From 0bb77c465f02e8281e24b9f02e7dc8a7e2b81ee2 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Mon, 3 Jan 2011 14:22:11 -0800 Subject: pstore: X86 platform interface using ACPI/APEI/ERST The 'error record serialization table' in ACPI provides a suitable amount of persistent storage for use by the pstore filesystem. Signed-off-by: Tony Luck --- drivers/acpi/apei/Kconfig | 1 + drivers/acpi/apei/erst.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index fca34ccfd294..e91680c7e047 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig @@ -1,5 +1,6 @@ config ACPI_APEI bool "ACPI Platform Error Interface (APEI)" + select PSTORE depends on X86 help APEI allows to report errors (for example from the chipset) diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 5850d320404c..22d70dbe75d1 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include "apei-internal.h" @@ -781,6 +782,128 @@ static int erst_check_table(struct acpi_table_erst *erst_tab) return 0; } +static size_t erst_reader(u64 *id, enum pstore_type_id *type, + struct timespec *time); +static u64 erst_writer(enum pstore_type_id type, size_t size); + +static struct pstore_info erst_info = { + .owner = THIS_MODULE, + .name = "erst", + .read = erst_reader, + .write = erst_writer, + .erase = erst_clear +}; + +#define CPER_CREATOR_PSTORE \ + UUID_LE(0x75a574e3, 0x5052, 0x4b29, 0x8a, 0x8e, 0xbe, 0x2c, \ + 0x64, 0x90, 0xb8, 0x9d) +#define CPER_SECTION_TYPE_DMESG \ + UUID_LE(0xc197e04e, 0xd545, 0x4a70, 0x9c, 0x17, 0xa5, 0x54, \ + 0x94, 0x19, 0xeb, 0x12) +#define CPER_SECTION_TYPE_MCE \ + UUID_LE(0xfe08ffbe, 0x95e4, 0x4be7, 0xbc, 0x73, 0x40, 0x96, \ + 0x04, 0x4a, 0x38, 0xfc) + +struct cper_pstore_record { + struct cper_record_header hdr; + struct cper_section_descriptor sec_hdr; + char data[]; +} __packed; + +static size_t erst_reader(u64 *id, enum pstore_type_id *type, + struct timespec *time) +{ + int rc; + ssize_t len; + unsigned long flags; + u64 record_id; + struct cper_pstore_record *rcd = (struct cper_pstore_record *) + (erst_info.buf - sizeof(*rcd)); + + if (erst_disable) + return -ENODEV; + + raw_spin_lock_irqsave(&erst_lock, flags); +skip: + rc = __erst_get_next_record_id(&record_id); + if (rc) { + raw_spin_unlock_irqrestore(&erst_lock, flags); + return rc; + } + /* no more record */ + if (record_id == APEI_ERST_INVALID_RECORD_ID) { + raw_spin_unlock_irqrestore(&erst_lock, flags); + return 0; + } + + len = __erst_read(record_id, &rcd->hdr, sizeof(*rcd) + + erst_erange.size); + if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0) + goto skip; + raw_spin_unlock_irqrestore(&erst_lock, flags); + + *id = record_id; + if (uuid_le_cmp(rcd->sec_hdr.section_type, + CPER_SECTION_TYPE_DMESG) == 0) + *type = PSTORE_TYPE_DMESG; + else if (uuid_le_cmp(rcd->sec_hdr.section_type, + CPER_SECTION_TYPE_MCE) == 0) + *type = PSTORE_TYPE_MCE; + else + *type = PSTORE_TYPE_UNKNOWN; + + if (rcd->hdr.validation_bits & CPER_VALID_TIMESTAMP) + time->tv_sec = rcd->hdr.timestamp; + else + time->tv_sec = 0; + time->tv_nsec = 0; + + return len - sizeof(*rcd); +} + +static u64 erst_writer(enum pstore_type_id type, size_t size) +{ + struct cper_pstore_record *rcd = (struct cper_pstore_record *) + (erst_info.buf - sizeof(*rcd)); + + memset(rcd, 0, sizeof(*rcd)); + memcpy(rcd->hdr.signature, CPER_SIG_RECORD, CPER_SIG_SIZE); + rcd->hdr.revision = CPER_RECORD_REV; + rcd->hdr.signature_end = CPER_SIG_END; + rcd->hdr.section_count = 1; + rcd->hdr.error_severity = CPER_SEV_FATAL; + /* timestamp valid. platform_id, partition_id are invalid */ + rcd->hdr.validation_bits = CPER_VALID_TIMESTAMP; + rcd->hdr.timestamp = get_seconds(); + rcd->hdr.record_length = sizeof(*rcd) + size; + rcd->hdr.creator_id = CPER_CREATOR_PSTORE; + rcd->hdr.notification_type = CPER_NOTIFY_MCE; + rcd->hdr.record_id = cper_next_record_id(); + rcd->hdr.flags = CPER_HW_ERROR_FLAGS_PREVERR; + + rcd->sec_hdr.section_offset = sizeof(*rcd); + rcd->sec_hdr.section_length = size; + rcd->sec_hdr.revision = CPER_SEC_REV; + /* fru_id and fru_text is invalid */ + rcd->sec_hdr.validation_bits = 0; + rcd->sec_hdr.flags = CPER_SEC_PRIMARY; + switch (type) { + case PSTORE_TYPE_DMESG: + rcd->sec_hdr.section_type = CPER_SECTION_TYPE_DMESG; + break; + case PSTORE_TYPE_MCE: + rcd->sec_hdr.section_type = CPER_SECTION_TYPE_MCE; + break; + default: + return -EINVAL; + } + rcd->sec_hdr.section_severity = CPER_SEV_FATAL; + + erst_write(&rcd->hdr); + + return rcd->hdr.record_id; +} + static int __init erst_init(void) { int rc = 0; @@ -788,6 +911,7 @@ static int __init erst_init(void) struct apei_exec_context ctx; struct apei_resources erst_resources; struct resource *r; + char *buf; if (acpi_disabled) goto err; @@ -854,6 +978,18 @@ static int __init erst_init(void) if (!erst_erange.vaddr) goto err_release_erange; + buf = kmalloc(erst_erange.size, GFP_KERNEL); + mutex_init(&erst_info.buf_mutex); + if (buf) { + erst_info.buf = buf + sizeof(struct cper_pstore_record); + erst_info.bufsize = erst_erange.size - + sizeof(struct cper_pstore_record); + if (pstore_register(&erst_info)) { + pr_info(ERST_PFX "Could not register with persistent store\n"); + kfree(buf); + } + } + pr_info(ERST_PFX "Error Record Serialization Table (ERST) support is initialized.\n"); -- cgit v1.2.3 From 252486a13a36e2846ff046c18aae67658692eced Mon Sep 17 00:00:00 2001 From: Nishant Sarmukadam Date: Thu, 30 Dec 2010 11:23:31 -0800 Subject: mwl8k: Modify add_dma_header to include pad parameters Add capability to add_dma_header to support padding at tail of the data packet to be transmitted when crypto is enabled. Padding is required for adding crypto information in data packets for supporting 802.11 security modes. Signed-off-by: Nishant Sarmukadam Signed-off-by: Pradeep Nemavat Signed-off-by: Thomas Pedersen Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 9ecf8407cb1b..1798b7e8283f 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -715,10 +715,12 @@ static inline void mwl8k_remove_dma_header(struct sk_buff *skb, __le16 qos) skb_pull(skb, sizeof(*tr) - hdrlen); } -static inline void mwl8k_add_dma_header(struct sk_buff *skb) +static void +mwl8k_add_dma_header(struct sk_buff *skb, int tail_pad) { struct ieee80211_hdr *wh; int hdrlen; + int reqd_hdrlen; struct mwl8k_dma_data *tr; /* @@ -730,11 +732,13 @@ static inline void mwl8k_add_dma_header(struct sk_buff *skb) wh = (struct ieee80211_hdr *)skb->data; hdrlen = ieee80211_hdrlen(wh->frame_control); - if (hdrlen != sizeof(*tr)) - skb_push(skb, sizeof(*tr) - hdrlen); + reqd_hdrlen = sizeof(*tr); + + if (hdrlen != reqd_hdrlen) + skb_push(skb, reqd_hdrlen - hdrlen); if (ieee80211_is_data_qos(wh->frame_control)) - hdrlen -= 2; + hdrlen -= IEEE80211_QOS_CTL_LEN; tr = (struct mwl8k_dma_data *)skb->data; if (wh != &tr->wh) @@ -747,7 +751,7 @@ static inline void mwl8k_add_dma_header(struct sk_buff *skb) * payload". That is, everything except for the 802.11 header. * This includes all crypto material including the MIC. */ - tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr)); + tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr) + tail_pad); } @@ -1443,7 +1447,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) else qos = 0; - mwl8k_add_dma_header(skb); + mwl8k_add_dma_header(skb, 0); wh = &((struct mwl8k_dma_data *)skb->data)->wh; tx_info = IEEE80211_SKB_CB(skb); -- cgit v1.2.3 From e53d9b964e2568172149d41b3157af9cde9accaf Mon Sep 17 00:00:00 2001 From: Nishant Sarmukadam Date: Thu, 30 Dec 2010 11:23:32 -0800 Subject: mwl8k: Add encapsulation of data packet for crypto Different tail pads will be needed for crypto depending on the crypto mode. Add support to encapsulate the packets with appropriate pad value. Signed-off-by: Nishant Sarmukadam Signed-off-by: Pradeep Nemavat Signed-off-by: Thomas Pedersen Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 54 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 1798b7e8283f..95bbdca0ba87 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -232,6 +232,9 @@ struct mwl8k_priv { struct completion firmware_loading_complete; }; +#define MAX_WEP_KEY_LEN 13 +#define NUM_WEP_KEYS 4 + /* Per interface specific private data */ struct mwl8k_vif { struct list_head list; @@ -242,6 +245,12 @@ struct mwl8k_vif { /* Non AMPDU sequence number assigned by driver. */ u16 seqno; + + /* Saved WEP keys */ + struct { + u8 enabled; + u8 key[sizeof(struct ieee80211_key_conf) + MAX_WEP_KEY_LEN]; + } wep_key_conf[NUM_WEP_KEYS]; }; #define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv)) @@ -754,6 +763,49 @@ mwl8k_add_dma_header(struct sk_buff *skb, int tail_pad) tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr) + tail_pad); } +static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb) +{ + struct ieee80211_hdr *wh; + struct ieee80211_tx_info *tx_info; + struct ieee80211_key_conf *key_conf; + int data_pad; + + wh = (struct ieee80211_hdr *)skb->data; + + tx_info = IEEE80211_SKB_CB(skb); + + key_conf = NULL; + if (ieee80211_is_data(wh->frame_control)) + key_conf = tx_info->control.hw_key; + + /* + * Make sure the packet header is in the DMA header format (4-address + * without QoS), the necessary crypto padding between the header and the + * payload has already been provided by mac80211, but it doesn't add tail + * padding when HW crypto is enabled. + * + * We have the following trailer padding requirements: + * - WEP: 4 trailer bytes (ICV) + * - TKIP: 12 trailer bytes (8 MIC + 4 ICV) + * - CCMP: 8 trailer bytes (MIC) + */ + data_pad = 0; + if (key_conf != NULL) { + switch (key_conf->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + data_pad = 4; + break; + case WLAN_CIPHER_SUITE_TKIP: + data_pad = 12; + break; + case WLAN_CIPHER_SUITE_CCMP: + data_pad = 8; + break; + } + } + mwl8k_add_dma_header(skb, data_pad); +} /* * Packet reception for 88w8366 AP firmware. @@ -1447,7 +1499,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) else qos = 0; - mwl8k_add_dma_header(skb, 0); + mwl8k_encapsulate_tx_frame(skb); wh = &((struct mwl8k_dma_data *)skb->data)->wh; tx_info = IEEE80211_SKB_CB(skb); -- cgit v1.2.3 From d9a07d4980514e701555c4f03b865a54c4c48b4a Mon Sep 17 00:00:00 2001 From: Nishant Sarmukadam Date: Thu, 30 Dec 2010 11:23:33 -0800 Subject: mwl8k: Set mac80211 rx status flags appropriately when hw crypto is enabled When hw crypto is enabled, set rx status flags appropriately depending on whether hw crypto is enabled for a particular bss. Also report MIC errors to mac80211, so that counter measures can be initiated Signed-off-by: Nishant Sarmukadam Signed-off-by: yogesh powar Signed-off-by: Thomas Pedersen Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 101 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 98 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 95bbdca0ba87..2b76bbc5e612 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -251,6 +251,12 @@ struct mwl8k_vif { u8 enabled; u8 key[sizeof(struct ieee80211_key_conf) + MAX_WEP_KEY_LEN]; } wep_key_conf[NUM_WEP_KEYS]; + + /* BSSID */ + u8 bssid[ETH_ALEN]; + + /* A flag to indicate is HW crypto is enabled for this bssid */ + bool is_hw_crypto_enabled; }; #define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv)) @@ -834,6 +840,13 @@ struct mwl8k_rxd_8366_ap { #define MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST 0x80 +/* 8366 AP rx_status bits */ +#define MWL8K_8366_AP_RXSTAT_DECRYPT_ERR_MASK 0x80 +#define MWL8K_8366_AP_RXSTAT_GENERAL_DECRYPT_ERR 0xFF +#define MWL8K_8366_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR 0x02 +#define MWL8K_8366_AP_RXSTAT_WEP_DECRYPT_ICV_ERR 0x04 +#define MWL8K_8366_AP_RXSTAT_TKIP_DECRYPT_ICV_ERR 0x08 + static void mwl8k_rxd_8366_ap_init(void *_rxd, dma_addr_t next_dma_addr) { struct mwl8k_rxd_8366_ap *rxd = _rxd; @@ -894,6 +907,11 @@ mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status, *qos = rxd->qos_control; + if ((rxd->rx_status != MWL8K_8366_AP_RXSTAT_GENERAL_DECRYPT_ERR) && + (rxd->rx_status & MWL8K_8366_AP_RXSTAT_DECRYPT_ERR_MASK) && + (rxd->rx_status & MWL8K_8366_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR)) + status->flag |= RX_FLAG_MMIC_ERROR; + return le16_to_cpu(rxd->pkt_len); } @@ -932,6 +950,11 @@ struct mwl8k_rxd_sta { #define MWL8K_STA_RATE_INFO_MCS_FORMAT 0x0001 #define MWL8K_STA_RX_CTRL_OWNED_BY_HOST 0x02 +#define MWL8K_STA_RX_CTRL_DECRYPT_ERROR 0x04 +/* ICV=0 or MIC=1 */ +#define MWL8K_STA_RX_CTRL_DEC_ERR_TYPE 0x08 +/* Key is uploaded only in failure case */ +#define MWL8K_STA_RX_CTRL_KEY_INDEX 0x30 static void mwl8k_rxd_sta_init(void *_rxd, dma_addr_t next_dma_addr) { @@ -990,6 +1013,9 @@ mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status, status->freq = ieee80211_channel_to_frequency(rxd->channel); *qos = rxd->qos_control; + if ((rxd->rx_ctrl & MWL8K_STA_RX_CTRL_DECRYPT_ERROR) && + (rxd->rx_ctrl & MWL8K_STA_RX_CTRL_DEC_ERR_TYPE)) + status->flag |= RX_FLAG_MMIC_ERROR; return le16_to_cpu(rxd->pkt_len); } @@ -1148,9 +1174,25 @@ static inline void mwl8k_save_beacon(struct ieee80211_hw *hw, ieee80211_queue_work(hw, &priv->finalize_join_worker); } +static inline struct mwl8k_vif *mwl8k_find_vif_bss(struct list_head *vif_list, + u8 *bssid) +{ + struct mwl8k_vif *mwl8k_vif; + + list_for_each_entry(mwl8k_vif, + vif_list, list) { + if (memcmp(bssid, mwl8k_vif->bssid, + ETH_ALEN) == 0) + return mwl8k_vif; + } + + return NULL; +} + static int rxq_process(struct ieee80211_hw *hw, int index, int limit) { struct mwl8k_priv *priv = hw->priv; + struct mwl8k_vif *mwl8k_vif = NULL; struct mwl8k_rx_queue *rxq = priv->rxq + index; int processed; @@ -1160,6 +1202,7 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit) void *rxd; int pkt_len; struct ieee80211_rx_status status; + struct ieee80211_hdr *wh; __le16 qos; skb = rxq->buf[rxq->head].skb; @@ -1186,8 +1229,7 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit) rxq->rxd_count--; - skb_put(skb, pkt_len); - mwl8k_remove_dma_header(skb, qos); + wh = &((struct mwl8k_dma_data *)skb->data)->wh; /* * Check for a pending join operation. Save a @@ -1197,6 +1239,46 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit) if (mwl8k_capture_bssid(priv, (void *)skb->data)) mwl8k_save_beacon(hw, skb); + if (ieee80211_has_protected(wh->frame_control)) { + + /* Check if hw crypto has been enabled for + * this bss. If yes, set the status flags + * accordingly + */ + mwl8k_vif = mwl8k_find_vif_bss(&priv->vif_list, + wh->addr1); + + if (mwl8k_vif != NULL && + mwl8k_vif->is_hw_crypto_enabled == true) { + /* + * When MMIC ERROR is encountered + * by the firmware, payload is + * dropped and only 32 bytes of + * mwl8k Firmware header is sent + * to the host. + * + * We need to add four bytes of + * key information. In it + * MAC80211 expects keyidx set to + * 0 for triggering Counter + * Measure of MMIC failure. + */ + if (status.flag & RX_FLAG_MMIC_ERROR) { + struct mwl8k_dma_data *tr; + tr = (struct mwl8k_dma_data *)skb->data; + memset((void *)&(tr->data), 0, 4); + pkt_len += 4; + } + + if (!ieee80211_is_auth(wh->frame_control)) + status.flag |= RX_FLAG_IV_STRIPPED | + RX_FLAG_DECRYPTED | + RX_FLAG_MMIC_STRIPPED; + } + } + + skb_put(skb, pkt_len); + mwl8k_remove_dma_header(skb, qos); memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); ieee80211_rx_irqsafe(hw, skb); @@ -1499,7 +1581,11 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) else qos = 0; - mwl8k_encapsulate_tx_frame(skb); + if (priv->ap_fw) + mwl8k_encapsulate_tx_frame(skb); + else + mwl8k_add_dma_header(skb, 0); + wh = &((struct mwl8k_dma_data *)skb->data)->wh; tx_info = IEEE80211_SKB_CB(skb); @@ -3525,6 +3611,8 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw, mwl8k_vif->vif = vif; mwl8k_vif->macid = macid; mwl8k_vif->seqno = 0; + memcpy(mwl8k_vif->bssid, vif->addr, ETH_ALEN); + mwl8k_vif->is_hw_crypto_enabled = false; /* Set the mac address. */ mwl8k_cmd_set_mac_addr(hw, vif, vif->addr); @@ -3930,9 +4018,16 @@ static int mwl8k_sta_add(struct ieee80211_hw *hw, return 0; } + } else { + ret = mwl8k_cmd_set_new_stn_add(hw, vif, sta); return ret; } + for (i = 0; i < NUM_WEP_KEYS; i++) { + key = IEEE80211_KEY_CONF(mwl8k_vif->wep_key_conf[i].key); + if (mwl8k_vif->wep_key_conf[i].enabled) + mwl8k_set_key(hw, SET_KEY, vif, sta, key); + } return mwl8k_cmd_set_new_stn_add(hw, vif, sta); } -- cgit v1.2.3 From fcdc403c31ed5bb5f3baf42f4e2b5e7198fef0c0 Mon Sep 17 00:00:00 2001 From: Nishant Sarmukadam Date: Thu, 30 Dec 2010 11:23:34 -0800 Subject: mwl8k: Enable HW encryption for AP mode set_key callback is defined for mac80211 to install keys for HW crypto in AP mode. Driver currently falls back to SW crypto in STA mode. Add support to configure the keys appropriately in the hardware after the set_key routine is called. Signed-off-by: Nishant Sarmukadam Signed-off-by: Pradeep Nemavat Signed-off-by: Thomas Pedersen Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 280 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 277 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 2b76bbc5e612..809f2bf27958 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -259,6 +259,7 @@ struct mwl8k_vif { bool is_hw_crypto_enabled; }; #define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv)) +#define IEEE80211_KEY_CONF(_u8) ((struct ieee80211_key_conf *)(_u8)) struct mwl8k_sta { /* Index into station database. Returned by UPDATE_STADB. */ @@ -352,6 +353,7 @@ static const struct ieee80211_rate mwl8k_rates_50[] = { #define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203 #define MWL8K_CMD_BSS_START 0x1100 /* per-vif */ #define MWL8K_CMD_SET_NEW_STN 0x1111 /* per-vif */ +#define MWL8K_CMD_UPDATE_ENCRYPTION 0x1122 /* per-vif */ #define MWL8K_CMD_UPDATE_STADB 0x1123 static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize) @@ -390,6 +392,7 @@ static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize) MWL8K_CMDNAME(SET_RATEADAPT_MODE); MWL8K_CMDNAME(BSS_START); MWL8K_CMDNAME(SET_NEW_STN); + MWL8K_CMDNAME(UPDATE_ENCRYPTION); MWL8K_CMDNAME(UPDATE_STADB); default: snprintf(buf, bufsize, "0x%x", cmd); @@ -3240,6 +3243,274 @@ static int mwl8k_cmd_set_new_stn_del(struct ieee80211_hw *hw, return rc; } +/* + * CMD_UPDATE_ENCRYPTION. + */ + +#define MAX_ENCR_KEY_LENGTH 16 +#define MIC_KEY_LENGTH 8 + +struct mwl8k_cmd_update_encryption { + struct mwl8k_cmd_pkt header; + + __le32 action; + __le32 reserved; + __u8 mac_addr[6]; + __u8 encr_type; + +} __attribute__((packed)); + +struct mwl8k_cmd_set_key { + struct mwl8k_cmd_pkt header; + + __le32 action; + __le32 reserved; + __le16 length; + __le16 key_type_id; + __le32 key_info; + __le32 key_id; + __le16 key_len; + __u8 key_material[MAX_ENCR_KEY_LENGTH]; + __u8 tkip_tx_mic_key[MIC_KEY_LENGTH]; + __u8 tkip_rx_mic_key[MIC_KEY_LENGTH]; + __le16 tkip_rsc_low; + __le32 tkip_rsc_high; + __le16 tkip_tsc_low; + __le32 tkip_tsc_high; + __u8 mac_addr[6]; +} __attribute__((packed)); + +enum { + MWL8K_ENCR_ENABLE, + MWL8K_ENCR_SET_KEY, + MWL8K_ENCR_REMOVE_KEY, + MWL8K_ENCR_SET_GROUP_KEY, +}; + +#define MWL8K_UPDATE_ENCRYPTION_TYPE_WEP 0 +#define MWL8K_UPDATE_ENCRYPTION_TYPE_DISABLE 1 +#define MWL8K_UPDATE_ENCRYPTION_TYPE_TKIP 4 +#define MWL8K_UPDATE_ENCRYPTION_TYPE_MIXED 7 +#define MWL8K_UPDATE_ENCRYPTION_TYPE_AES 8 + +enum { + MWL8K_ALG_WEP, + MWL8K_ALG_TKIP, + MWL8K_ALG_CCMP, +}; + +#define MWL8K_KEY_FLAG_TXGROUPKEY 0x00000004 +#define MWL8K_KEY_FLAG_PAIRWISE 0x00000008 +#define MWL8K_KEY_FLAG_TSC_VALID 0x00000040 +#define MWL8K_KEY_FLAG_WEP_TXKEY 0x01000000 +#define MWL8K_KEY_FLAG_MICKEY_VALID 0x02000000 + +static int mwl8k_cmd_update_encryption_enable(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u8 *addr, + u8 encr_type) +{ + struct mwl8k_cmd_update_encryption *cmd; + int rc; + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (cmd == NULL) + return -ENOMEM; + + cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_ENCRYPTION); + cmd->header.length = cpu_to_le16(sizeof(*cmd)); + cmd->action = cpu_to_le32(MWL8K_ENCR_ENABLE); + memcpy(cmd->mac_addr, addr, ETH_ALEN); + cmd->encr_type = encr_type; + + rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); + kfree(cmd); + + return rc; +} + +static int mwl8k_encryption_set_cmd_info(struct mwl8k_cmd_set_key *cmd, + u8 *addr, + struct ieee80211_key_conf *key) +{ + cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_ENCRYPTION); + cmd->header.length = cpu_to_le16(sizeof(*cmd)); + cmd->length = cpu_to_le16(sizeof(*cmd) - + offsetof(struct mwl8k_cmd_set_key, length)); + cmd->key_id = cpu_to_le32(key->keyidx); + cmd->key_len = cpu_to_le16(key->keylen); + memcpy(cmd->mac_addr, addr, ETH_ALEN); + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + cmd->key_type_id = cpu_to_le16(MWL8K_ALG_WEP); + if (key->keyidx == 0) + cmd->key_info = cpu_to_le32(MWL8K_KEY_FLAG_WEP_TXKEY); + + break; + case WLAN_CIPHER_SUITE_TKIP: + cmd->key_type_id = cpu_to_le16(MWL8K_ALG_TKIP); + cmd->key_info = (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) + ? cpu_to_le32(MWL8K_KEY_FLAG_PAIRWISE) + : cpu_to_le32(MWL8K_KEY_FLAG_TXGROUPKEY); + cmd->key_info |= cpu_to_le32(MWL8K_KEY_FLAG_MICKEY_VALID + | MWL8K_KEY_FLAG_TSC_VALID); + break; + case WLAN_CIPHER_SUITE_CCMP: + cmd->key_type_id = cpu_to_le16(MWL8K_ALG_CCMP); + cmd->key_info = (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) + ? cpu_to_le32(MWL8K_KEY_FLAG_PAIRWISE) + : cpu_to_le32(MWL8K_KEY_FLAG_TXGROUPKEY); + break; + default: + return -ENOTSUPP; + } + + return 0; +} + +static int mwl8k_cmd_encryption_set_key(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u8 *addr, + struct ieee80211_key_conf *key) +{ + struct mwl8k_cmd_set_key *cmd; + int rc; + int keymlen; + u32 action; + u8 idx; + struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (cmd == NULL) + return -ENOMEM; + + rc = mwl8k_encryption_set_cmd_info(cmd, addr, key); + if (rc < 0) + goto done; + + idx = key->keyidx; + + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) + action = MWL8K_ENCR_SET_KEY; + else + action = MWL8K_ENCR_SET_GROUP_KEY; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + if (!mwl8k_vif->wep_key_conf[idx].enabled) { + memcpy(mwl8k_vif->wep_key_conf[idx].key, key, + sizeof(*key) + key->keylen); + mwl8k_vif->wep_key_conf[idx].enabled = 1; + } + + keymlen = 0; + action = MWL8K_ENCR_SET_KEY; + break; + case WLAN_CIPHER_SUITE_TKIP: + keymlen = MAX_ENCR_KEY_LENGTH + 2 * MIC_KEY_LENGTH; + break; + case WLAN_CIPHER_SUITE_CCMP: + keymlen = key->keylen; + break; + default: + rc = -ENOTSUPP; + goto done; + } + + memcpy(cmd->key_material, key->key, keymlen); + cmd->action = cpu_to_le32(action); + + rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); +done: + kfree(cmd); + + return rc; +} + +static int mwl8k_cmd_encryption_remove_key(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u8 *addr, + struct ieee80211_key_conf *key) +{ + struct mwl8k_cmd_set_key *cmd; + int rc; + struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (cmd == NULL) + return -ENOMEM; + + rc = mwl8k_encryption_set_cmd_info(cmd, addr, key); + if (rc < 0) + goto done; + + if (key->cipher == WLAN_CIPHER_SUITE_WEP40 || + WLAN_CIPHER_SUITE_WEP104) + mwl8k_vif->wep_key_conf[key->keyidx].enabled = 0; + + cmd->action = cpu_to_le32(MWL8K_ENCR_REMOVE_KEY); + + rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); +done: + kfree(cmd); + + return rc; +} + +static int mwl8k_set_key(struct ieee80211_hw *hw, + enum set_key_cmd cmd_param, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + int rc = 0; + u8 encr_type; + u8 *addr; + struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif); + + if (vif->type == NL80211_IFTYPE_STATION) + return -EOPNOTSUPP; + + if (sta == NULL) + addr = hw->wiphy->perm_addr; + else + addr = sta->addr; + + if (cmd_param == SET_KEY) { + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + rc = mwl8k_cmd_encryption_set_key(hw, vif, addr, key); + if (rc) + goto out; + + if ((key->cipher == WLAN_CIPHER_SUITE_WEP40) + || (key->cipher == WLAN_CIPHER_SUITE_WEP104)) + encr_type = MWL8K_UPDATE_ENCRYPTION_TYPE_WEP; + else + encr_type = MWL8K_UPDATE_ENCRYPTION_TYPE_MIXED; + + rc = mwl8k_cmd_update_encryption_enable(hw, vif, addr, + encr_type); + if (rc) + goto out; + + mwl8k_vif->is_hw_crypto_enabled = true; + + } else { + rc = mwl8k_cmd_encryption_remove_key(hw, vif, addr, key); + + if (rc) + goto out; + + mwl8k_vif->is_hw_crypto_enabled = false; + + } +out: + return rc; +} + /* * CMD_UPDATE_STADB. */ @@ -4010,17 +4281,19 @@ static int mwl8k_sta_add(struct ieee80211_hw *hw, { struct mwl8k_priv *priv = hw->priv; int ret; + int i; + struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif); + struct ieee80211_key_conf *key; if (!priv->ap_fw) { ret = mwl8k_cmd_update_stadb_add(hw, vif, sta); if (ret >= 0) { MWL8K_STA(sta)->peer_id = ret; - return 0; + ret = 0; } } else { ret = mwl8k_cmd_set_new_stn_add(hw, vif, sta); - return ret; } for (i = 0; i < NUM_WEP_KEYS; i++) { @@ -4028,7 +4301,7 @@ static int mwl8k_sta_add(struct ieee80211_hw *hw, if (mwl8k_vif->wep_key_conf[i].enabled) mwl8k_set_key(hw, SET_KEY, vif, sta, key); } - return mwl8k_cmd_set_new_stn_add(hw, vif, sta); + return ret; } static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue, @@ -4106,6 +4379,7 @@ static const struct ieee80211_ops mwl8k_ops = { .bss_info_changed = mwl8k_bss_info_changed, .prepare_multicast = mwl8k_prepare_multicast, .configure_filter = mwl8k_configure_filter, + .set_key = mwl8k_set_key, .set_rts_threshold = mwl8k_set_rts_threshold, .sta_add = mwl8k_sta_add, .sta_remove = mwl8k_sta_remove, -- cgit v1.2.3 From 09a525d33870e8a16076ec0200cc5002f6bef35d Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 4 Jan 2011 13:17:18 +0530 Subject: ath9k_htc: Add multiple register read API This would decrease latency in reading bulk registers. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 2 ++ drivers/net/wireless/ath/ath9k/htc_drv_init.c | 29 +++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/hw.h | 3 +++ 3 files changed, 34 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index e43210c8585c..a6c6a466000f 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -108,12 +108,14 @@ enum ath_cipher { * struct ath_ops - Register read/write operations * * @read: Register read + * @multi_read: Multiple register read * @write: Register write * @enable_write_buffer: Enable multiple register writes * @write_flush: flush buffered register writes and disable buffering */ struct ath_ops { unsigned int (*read)(void *, u32 reg_offset); + void (*multi_read)(void *, u32 *addr, u32 *val, u16 count); void (*write)(void *, u32 val, u32 reg_offset); void (*enable_write_buffer)(void *); void (*write_flush) (void *); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 38433f9bfe59..8e04586c5256 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -297,6 +297,34 @@ static unsigned int ath9k_regread(void *hw_priv, u32 reg_offset) return be32_to_cpu(val); } +static void ath9k_multi_regread(void *hw_priv, u32 *addr, + u32 *val, u16 count) +{ + struct ath_hw *ah = (struct ath_hw *) hw_priv; + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; + __be32 tmpaddr[8]; + __be32 tmpval[8]; + int i, ret; + + for (i = 0; i < count; i++) { + tmpaddr[i] = cpu_to_be32(addr[i]); + } + + ret = ath9k_wmi_cmd(priv->wmi, WMI_REG_READ_CMDID, + (u8 *)tmpaddr , sizeof(u32) * count, + (u8 *)tmpval, sizeof(u32) * count, + 100); + if (unlikely(ret)) { + ath_dbg(common, ATH_DBG_WMI, + "Multiple REGISTER READ FAILED (count: %d)\n", count); + } + + for (i = 0; i < count; i++) { + val[i] = be32_to_cpu(tmpval[i]); + } +} + static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset) { struct ath_hw *ah = (struct ath_hw *) hw_priv; @@ -407,6 +435,7 @@ static void ath9k_regwrite_flush(void *hw_priv) static const struct ath_ops ath9k_common_ops = { .read = ath9k_regread, + .multi_read = ath9k_multi_regread, .write = ath9k_regwrite, .enable_write_buffer = ath9k_enable_regwrite_buffer, .write_flush = ath9k_regwrite_flush, diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 5a3dfec45e96..c2b3515deea1 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -70,6 +70,9 @@ #define REG_READ(_ah, _reg) \ ath9k_hw_common(_ah)->ops->read((_ah), (_reg)) +#define REG_READ_MULTI(_ah, _addr, _val, _cnt) \ + ath9k_hw_common(_ah)->ops->multi_read((_ah), (_addr), (_val), (_cnt)) + #define ENABLE_REGWRITE_BUFFER(_ah) \ do { \ if (ath9k_hw_common(_ah)->ops->enable_write_buffer) \ -- cgit v1.2.3 From 04cf53f465049c7c509aac7b776f75d38ef68e69 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 4 Jan 2011 13:17:28 +0530 Subject: ath9k_hw: Offload USB eeprom reading to target For USB devices, reading the EEPROM data can be offloaded to the target. Use multiple register reads to take advantage of this feature to reduce initialization time. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/eeprom.c | 32 ++++++++++++++++++++ drivers/net/wireless/ath/ath9k/eeprom.h | 2 ++ drivers/net/wireless/ath/ath9k/eeprom_4k.c | 41 ++++++++++++++++++------- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 45 ++++++++++++++++++---------- drivers/net/wireless/ath/ath9k/eeprom_def.c | 32 ++++++++++++++++++-- 5 files changed, 123 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index d05163159572..8c18bed3a558 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c @@ -89,6 +89,38 @@ bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize, return false; } +void ath9k_hw_usb_gen_fill_eeprom(struct ath_hw *ah, u16 *eep_data, + int eep_start_loc, int size) +{ + int i = 0, j, addr; + u32 addrdata[8]; + u32 data[8]; + + for (addr = 0; addr < size; addr++) { + addrdata[i] = AR5416_EEPROM_OFFSET + + ((addr + eep_start_loc) << AR5416_EEPROM_S); + i++; + if (i == 8) { + REG_READ_MULTI(ah, addrdata, data, i); + + for (j = 0; j < i; j++) { + *eep_data = data[j]; + eep_data++; + } + i = 0; + } + } + + if (i != 0) { + REG_READ_MULTI(ah, addrdata, data, i); + + for (j = 0; j < i; j++) { + *eep_data = data[j]; + eep_data++; + } + } +} + bool ath9k_hw_nvram_read(struct ath_common *common, u32 off, u16 *data) { return common->bus_ops->eeprom_read(common, off, data); diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 58e2ddc927a9..bd82447f5b78 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -665,6 +665,8 @@ int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight, bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize, u16 *indexL, u16 *indexR); bool ath9k_hw_nvram_read(struct ath_common *common, u32 off, u16 *data); +void ath9k_hw_usb_gen_fill_eeprom(struct ath_hw *ah, u16 *eep_data, + int eep_start_loc, int size); void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList, u8 *pVpdList, u16 numIntercepts, u8 *pRetVpdList); diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index fbdff7e47952..bc77a308c901 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -27,19 +27,13 @@ static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah) return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF); } -static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah) -{ #define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) + +static bool __ath9k_hw_4k_fill_eeprom(struct ath_hw *ah) +{ struct ath_common *common = ath9k_hw_common(ah); u16 *eep_data = (u16 *)&ah->eeprom.map4k; - int addr, eep_start_loc = 0; - - eep_start_loc = 64; - - if (!ath9k_hw_use_flash(ah)) { - ath_dbg(common, ATH_DBG_EEPROM, - "Reading from EEPROM, not flash\n"); - } + int addr, eep_start_loc = 64; for (addr = 0; addr < SIZE_EEPROM_4K; addr++) { if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) { @@ -51,9 +45,34 @@ static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah) } return true; -#undef SIZE_EEPROM_4K } +static bool __ath9k_hw_usb_4k_fill_eeprom(struct ath_hw *ah) +{ + u16 *eep_data = (u16 *)&ah->eeprom.map4k; + + ath9k_hw_usb_gen_fill_eeprom(ah, eep_data, 64, SIZE_EEPROM_4K); + + return true; +} + +static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah) +{ + struct ath_common *common = ath9k_hw_common(ah); + + if (!ath9k_hw_use_flash(ah)) { + ath_dbg(common, ATH_DBG_EEPROM, + "Reading from EEPROM, not flash\n"); + } + + if (common->bus_ops->ath_bus_type == ATH_USB) + return __ath9k_hw_usb_4k_fill_eeprom(ah); + else + return __ath9k_hw_4k_fill_eeprom(ah); +} + +#undef SIZE_EEPROM_4K + static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) { #define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 9b6bc8a953bc..8cd8333cc086 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -17,7 +17,7 @@ #include "hw.h" #include "ar9002_phy.h" -#define NUM_EEP_WORDS (sizeof(struct ar9287_eeprom) / sizeof(u16)) +#define SIZE_EEPROM_AR9287 (sizeof(struct ar9287_eeprom) / sizeof(u16)) static int ath9k_hw_ar9287_get_eeprom_ver(struct ath_hw *ah) { @@ -29,25 +29,15 @@ static int ath9k_hw_ar9287_get_eeprom_rev(struct ath_hw *ah) return (ah->eeprom.map9287.baseEepHeader.version) & 0xFFF; } -static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah) +static bool __ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah) { struct ar9287_eeprom *eep = &ah->eeprom.map9287; struct ath_common *common = ath9k_hw_common(ah); u16 *eep_data; - int addr, eep_start_loc; + int addr, eep_start_loc = AR9287_EEP_START_LOC; eep_data = (u16 *)eep; - if (common->bus_ops->ath_bus_type == ATH_USB) - eep_start_loc = AR9287_HTC_EEP_START_LOC; - else - eep_start_loc = AR9287_EEP_START_LOC; - - if (!ath9k_hw_use_flash(ah)) { - ath_dbg(common, ATH_DBG_EEPROM, - "Reading from EEPROM, not flash\n"); - } - - for (addr = 0; addr < NUM_EEP_WORDS; addr++) { + for (addr = 0; addr < SIZE_EEPROM_AR9287; addr++) { if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) { ath_dbg(common, ATH_DBG_EEPROM, @@ -60,6 +50,31 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah) return true; } +static bool __ath9k_hw_usb_ar9287_fill_eeprom(struct ath_hw *ah) +{ + u16 *eep_data = (u16 *)&ah->eeprom.map9287; + + ath9k_hw_usb_gen_fill_eeprom(ah, eep_data, + AR9287_HTC_EEP_START_LOC, + SIZE_EEPROM_AR9287); + return true; +} + +static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah) +{ + struct ath_common *common = ath9k_hw_common(ah); + + if (!ath9k_hw_use_flash(ah)) { + ath_dbg(common, ATH_DBG_EEPROM, + "Reading from EEPROM, not flash\n"); + } + + if (common->bus_ops->ath_bus_type == ATH_USB) + return __ath9k_hw_usb_ar9287_fill_eeprom(ah); + else + return __ath9k_hw_ar9287_fill_eeprom(ah); +} + static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah) { u32 sum = 0, el, integer; @@ -86,7 +101,7 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah) need_swap = true; eepdata = (u16 *)(&ah->eeprom); - for (addr = 0; addr < NUM_EEP_WORDS; addr++) { + for (addr = 0; addr < SIZE_EEPROM_AR9287; addr++) { temp = swab16(*eepdata); *eepdata = temp; eepdata++; diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 749a93608664..c9318ff40964 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -86,9 +86,10 @@ static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah) return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF); } -static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah) -{ #define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16)) + +static bool __ath9k_hw_def_fill_eeprom(struct ath_hw *ah) +{ struct ath_common *common = ath9k_hw_common(ah); u16 *eep_data = (u16 *)&ah->eeprom.def; int addr, ar5416_eep_start_loc = 0x100; @@ -103,9 +104,34 @@ static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah) eep_data++; } return true; -#undef SIZE_EEPROM_DEF } +static bool __ath9k_hw_usb_def_fill_eeprom(struct ath_hw *ah) +{ + u16 *eep_data = (u16 *)&ah->eeprom.def; + + ath9k_hw_usb_gen_fill_eeprom(ah, eep_data, + 0x100, SIZE_EEPROM_DEF); + return true; +} + +static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah) +{ + struct ath_common *common = ath9k_hw_common(ah); + + if (!ath9k_hw_use_flash(ah)) { + ath_dbg(common, ATH_DBG_EEPROM, + "Reading from EEPROM, not flash\n"); + } + + if (common->bus_ops->ath_bus_type == ATH_USB) + return __ath9k_hw_usb_def_fill_eeprom(ah); + else + return __ath9k_hw_def_fill_eeprom(ah); +} + +#undef SIZE_EEPROM_DEF + static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) { struct ar5416_eeprom_def *eep = -- cgit v1.2.3 From 7f6e144fb99a4a70d3c5ad5f074204c5b89a6f65 Mon Sep 17 00:00:00 2001 From: RA-Jay Hung Date: Mon, 10 Jan 2011 11:27:43 +0100 Subject: rt2x00: Fix radio off hang issue for PCIE interface PCI/PCIE radio off behavior is different from SOC/USB. They mainly use MCU command to disable DMA, TX/RX and enter power saving mode. Signed-off-by: RA-Jay Hung Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 6 ------ drivers/net/wireless/rt2x00/rt2800pci.c | 36 +++++++++------------------------ 2 files changed, 10 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 54917a281398..e2a528da3641 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2810,10 +2810,7 @@ void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev) rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0); rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); /* Wait for DMA, ignore error */ @@ -2823,9 +2820,6 @@ void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 0); rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); - - rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0); - rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); } EXPORT_SYMBOL_GPL(rt2800_disable_radio); diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index aa97971a38af..bfc2fc5c1c22 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -475,39 +475,23 @@ static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev) { - u32 reg; - - rt2800_disable_radio(rt2x00dev); - - rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001280); - - rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, ®); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, 1); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, 1); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, 1); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, 1); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX4, 1); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX5, 1); - rt2x00_set_field32(®, WPDMA_RST_IDX_DRX_IDX0, 1); - rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg); - - rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); - rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); + if (rt2x00_is_soc(rt2x00dev)) { + rt2800_disable_radio(rt2x00dev); + rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0); + rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); + } } static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) { - /* - * Always put the device to sleep (even when we intend to wakeup!) - * if the device is booting and wasn't asleep it will return - * failure when attempting to wakeup. - */ - rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0xff, 2); - if (state == STATE_AWAKE) { - rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0); + rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0x02); rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKUP); + } else if (state == STATE_SLEEP) { + rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, 0xffffffff); + rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, 0xffffffff); + rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0x01, 0xff, 0x01); } return 0; -- cgit v1.2.3 From 80d184e6cfb1ba7371152c4c91652d770c9caddb Mon Sep 17 00:00:00 2001 From: RA-Jay Hung Date: Mon, 10 Jan 2011 11:28:10 +0100 Subject: rt2x00: Fix and fine-tune rf registers for RT3070/RT3071/RT3090 Basically fix and fine-tune RT3070/RT3071/RT3090 chip RF initial value when call rt2800_init_rfcsr Signed-off-by: RA-Jay Hung Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 6 ++++++ drivers/net/wireless/rt2x00/rt2800lib.c | 25 +++++++++++++++++-------- 2 files changed, 23 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 4c55e8525cad..c7e615cebac1 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1804,6 +1804,12 @@ struct mac_iveiv_entry { */ #define RFCSR30_RF_CALIBRATION FIELD8(0x80) +/* + * RFCSR 31: + */ +#define RFCSR31_RX_AGC_FC FIELD8(0x1f) +#define RFCSR31_RX_H20M FIELD8(0x20) + /* * RF registers */ diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index e2a528da3641..a25be625ee90 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2436,6 +2436,10 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * bw40); rt2800_bbp_write(rt2x00dev, 4, bbp); + rt2800_rfcsr_read(rt2x00dev, 31, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR31_RX_H20M, bw40); + rt2800_rfcsr_write(rt2x00dev, 31, rfcsr); + rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 1); rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); @@ -2510,7 +2514,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 4, 0x40); rt2800_rfcsr_write(rt2x00dev, 5, 0x03); rt2800_rfcsr_write(rt2x00dev, 6, 0x02); - rt2800_rfcsr_write(rt2x00dev, 7, 0x70); + rt2800_rfcsr_write(rt2x00dev, 7, 0x60); rt2800_rfcsr_write(rt2x00dev, 9, 0x0f); rt2800_rfcsr_write(rt2x00dev, 10, 0x41); rt2800_rfcsr_write(rt2x00dev, 11, 0x21); @@ -2602,12 +2606,12 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_register_write(rt2x00dev, LDO_CFG0, reg); } else if (rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090)) { + rt2800_rfcsr_write(rt2x00dev, 31, 0x14); + rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1); rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); - rt2800_rfcsr_write(rt2x00dev, 31, 0x14); - rt2800_register_read(rt2x00dev, LDO_CFG0, ®); rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || @@ -2619,6 +2623,10 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0); } rt2800_register_write(rt2x00dev, LDO_CFG0, reg); + + rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®); + rt2x00_set_field32(®, GPIO_SWITCH_5, 0); + rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg); } else if (rt2x00_rt(rt2x00dev, RT3390)) { rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®); rt2x00_set_field32(®, GPIO_SWITCH_5, 0); @@ -2670,10 +2678,11 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0); - if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || + if (rt2x00_rt(rt2x00dev, RT3070) || + rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { - if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) + if (!test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); } rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom); @@ -2686,6 +2695,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) if (rt2x00_rt(rt2x00dev, RT3090)) { rt2800_bbp_read(rt2x00dev, 138, &bbp); + /* Turn off unused DAC1 and ADC1 to reduce power consumption */ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1) rt2x00_set_field8(&bbp, BBP138_RX_ADC1, 0); @@ -2719,10 +2729,9 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 21, rfcsr); } - if (rt2x00_rt(rt2x00dev, RT3070) || rt2x00_rt(rt2x00dev, RT3071)) { + if (rt2x00_rt(rt2x00dev, RT3070)) { rt2800_rfcsr_read(rt2x00dev, 27, &rfcsr); - if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) || - rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E)) + if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) rt2x00_set_field8(&rfcsr, RFCSR27_R1, 3); else rt2x00_set_field8(&rfcsr, RFCSR27_R1, 0); -- cgit v1.2.3 From a9e99a0cea3b6e27cca23ad2ef57331a25d886bb Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 10 Jan 2011 17:05:47 -0700 Subject: ath9k: fix bogus sequence number increases on aggregation tid flush When a tid pointer is passed to ath_tx_send_normal(), it increases the starting sequence number for the next AMPDU action frame, which should only be done if the sequence number assignment is fresh. In this case it is clearly not. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 332d1feb5c18..1adfebcd9b9a 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -169,7 +169,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) ath_tx_update_baw(sc, tid, fi->seqno); ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); } else { - ath_tx_send_normal(sc, txq, tid, &bf_head); + ath_tx_send_normal(sc, txq, NULL, &bf_head); } spin_lock_bh(&txq->axq_lock); } -- cgit v1.2.3 From 49447f2f9d47c4a57a76db702c9c1dab32fa7934 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 10 Jan 2011 17:05:48 -0700 Subject: ath9k: fix initial sequence number after starting an ampdu session txtid->seq_start may not always be up to date, when there is HT non-AMPDU traffic just before starting an AMPDU session. Relying on txtid->seq_next is better, since it is also used to generate the sequence numbers for all QoS data frames. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 1adfebcd9b9a..6ddba4b361fd 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -856,7 +856,7 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, txtid->state |= AGGR_ADDBA_PROGRESS; txtid->paused = true; - *ssn = txtid->seq_start; + *ssn = txtid->seq_start = txtid->seq_next; return 0; } -- cgit v1.2.3 From 2ed72229d60fc6f3ac9941b75d1e1522b08a975a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 10 Jan 2011 17:05:49 -0700 Subject: ath9k: reinitialize block ack window data when starting aggregation There might be some old stale data left, which could confuse tracking of pending tx frames. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 6ddba4b361fd..ab4f7b4f789f 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -858,6 +858,9 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, txtid->paused = true; *ssn = txtid->seq_start = txtid->seq_next; + memset(txtid->tx_buf, 0, sizeof(txtid->tx_buf)); + txtid->baw_head = txtid->baw_tail = 0; + return 0; } -- cgit v1.2.3 From 8b3f4616d40a2ad19dd14af40b73f56860c812ea Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 10 Jan 2011 17:05:50 -0700 Subject: ath9k: reduce the likelihood of baseband hang check false positives Since baseband hangs are rare, but the hang check function has a high false positive rate in some situations, we need to add more reliable indicators. In AP mode we can use blocked beacon transmissions as an indicator, they should be rare enough. In station mode, we can skip the hang check entirely, since a true hang will trigger beacon loss detection, and mac80211 will rescan, which leads to a hw reset that will bring the hardware back to life. To make this more reliable, we need to skip fast channel changes if the hardware appears to be stuck. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index f90a6ca94a76..c753ba413f60 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -251,6 +251,9 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, if (!ath_stoprecv(sc)) stopped = false; + if (!ath9k_hw_check_alive(ah)) + stopped = false; + /* XXX: do not flush receive queue here. We don't want * to flush data frames already in queue because of * changing channel. */ @@ -602,7 +605,15 @@ void ath9k_tasklet(unsigned long data) spin_lock(&sc->sc_pcu_lock); - if (!ath9k_hw_check_alive(ah)) + /* + * Only run the baseband hang check if beacons stop working in AP or + * IBSS mode, because it has a high false positive rate. For station + * mode it should not be necessary, since the upper layers will detect + * this through a beacon miss automatically and the following channel + * change will trigger a hardware reset anyway + */ + if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0 && + !ath9k_hw_check_alive(ah)) ieee80211_queue_work(sc->hw, &sc->hw_check_work); if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) -- cgit v1.2.3 From fda9b7afa70f9003853929821748aec98d567b1e Mon Sep 17 00:00:00 2001 From: Wojciech Dubowik Date: Tue, 11 Jan 2011 09:00:31 +0100 Subject: ath5k: Fix return codes for eeprom read functions. Eeprom read functions are of bool type and not int. Signed-off-by: Wojciech Dubowik Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ahb.c | 7 ++++--- drivers/net/wireless/ath/ath5k/eeprom.c | 24 ++++++++---------------- drivers/net/wireless/ath/ath5k/eeprom.h | 5 ++--- drivers/net/wireless/ath/ath5k/pci.c | 9 +++++---- 4 files changed, 19 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index 707cde149248..ae84b86c3bf2 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -31,7 +31,8 @@ static void ath5k_ahb_read_cachesize(struct ath_common *common, int *csz) *csz = L1_CACHE_BYTES >> 2; } -bool ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) +static bool +ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) { struct ath5k_softc *sc = common->priv; struct platform_device *pdev = to_platform_device(sc->dev); @@ -46,10 +47,10 @@ bool ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) eeprom += off; if (eeprom > eeprom_end) - return -EINVAL; + return false; *data = *eeprom; - return 0; + return true; } int ath5k_hw_read_srev(struct ath5k_hw *ah) diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 80e625608bac..b6561f785c6e 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -72,7 +72,6 @@ static int ath5k_eeprom_init_header(struct ath5k_hw *ah) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - int ret; u16 val; u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX; @@ -192,7 +191,7 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset, struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; u32 o = *offset; u16 val; - int ret, i = 0; + int i = 0; AR5K_EEPROM_READ(o++, val); ee->ee_switch_settling[mode] = (val >> 8) & 0x7f; @@ -252,7 +251,6 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; u32 o = *offset; u16 val; - int ret; ee->ee_n_piers[mode] = 0; AR5K_EEPROM_READ(o++, val); @@ -515,7 +513,6 @@ ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max, int o = *offset; int i = 0; u8 freq1, freq2; - int ret; u16 val; ee->ee_n_piers[mode] = 0; @@ -551,7 +548,7 @@ ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset) { struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a; - int i, ret; + int i; u16 val; u8 mask; @@ -970,7 +967,6 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode) u32 offset; u8 i, c; u16 val; - int ret; u8 pd_gains = 0; /* Count how many curves we have and @@ -1228,7 +1224,7 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode) struct ath5k_chan_pcal_info *chinfo; u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; u32 offset; - int idx, i, ret; + int idx, i; u16 val; u8 pd_gains = 0; @@ -1419,7 +1415,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode) u8 *rate_target_pwr_num; u32 offset; u16 val; - int ret, i; + int i; offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1); rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode]; @@ -1593,7 +1589,7 @@ ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) struct ath5k_edge_power *rep; unsigned int fmask, pmask; unsigned int ctl_mode; - int ret, i, j; + int i, j; u32 offset; u16 val; @@ -1733,16 +1729,12 @@ int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) u8 mac_d[ETH_ALEN] = {}; u32 total, offset; u16 data; - int octet, ret; + int octet; - ret = ath5k_hw_nvram_read(ah, 0x20, &data); - if (ret) - return ret; + AR5K_EEPROM_READ(0x20, data); for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { - ret = ath5k_hw_nvram_read(ah, offset, &data); - if (ret) - return ret; + AR5K_EEPROM_READ(offset, data); total += data; mac_d[octet + 1] = data & 0xff; diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h index 7c09e150dbdc..d46f1056f447 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.h +++ b/drivers/net/wireless/ath/ath5k/eeprom.h @@ -241,9 +241,8 @@ enum ath5k_eeprom_freq_bands{ #define AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz 6250 #define AR5K_EEPROM_READ(_o, _v) do { \ - ret = ath5k_hw_nvram_read(ah, (_o), &(_v)); \ - if (ret) \ - return ret; \ + if (!ath5k_hw_nvram_read(ah, (_o), &(_v))) \ + return -EIO; \ } while (0) #define AR5K_EEPROM_READ_HDR(_o, _v) \ diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c index 7f8c5b0e9d2a..66598a0d1df0 100644 --- a/drivers/net/wireless/ath/ath5k/pci.c +++ b/drivers/net/wireless/ath/ath5k/pci.c @@ -69,7 +69,8 @@ static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz) /* * Read from eeprom */ -bool ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data) +static bool +ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data) { struct ath5k_hw *ah = (struct ath5k_hw *) common->ah; u32 status, timeout; @@ -90,15 +91,15 @@ bool ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data) status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS); if (status & AR5K_EEPROM_STAT_RDDONE) { if (status & AR5K_EEPROM_STAT_RDERR) - return -EIO; + return false; *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) & 0xffff); - return 0; + return true; } udelay(15); } - return -ETIMEDOUT; + return false; } int ath5k_hw_read_srev(struct ath5k_hw *ah) -- cgit v1.2.3 From 115dad7a7f42e68840392767323ceb9306dbdb36 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 14 Jan 2011 00:06:27 +0100 Subject: ath9k_hw: partially revert "fix dma descriptor rx error bit parsing" The rx error bit parsing was changed to consider PHY errors and various decryption errors separately. While correct according to the documentation, this is causing spurious decryption error reports in some situations. Fix this by restoring the original order of the checks in those places, where the errors are meant to be mutually exclusive. If a CRC error is reported, then MIC failure and decryption errors are irrelevant, and a PHY error is unlikely. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 8 ++++---- drivers/net/wireless/ath/ath9k/mac.c | 14 ++++++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 4ceddbbdfcee..038a0cbfc6e7 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -615,7 +615,7 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, */ if (rxsp->status11 & AR_CRCErr) rxs->rs_status |= ATH9K_RXERR_CRC; - if (rxsp->status11 & AR_PHYErr) { + else if (rxsp->status11 & AR_PHYErr) { phyerr = MS(rxsp->status11, AR_PHYErrCode); /* * If we reach a point here where AR_PostDelimCRCErr is @@ -638,11 +638,11 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, rxs->rs_phyerr = phyerr; } - } - if (rxsp->status11 & AR_DecryptCRCErr) + } else if (rxsp->status11 & AR_DecryptCRCErr) rxs->rs_status |= ATH9K_RXERR_DECRYPT; - if (rxsp->status11 & AR_MichaelErr) + else if (rxsp->status11 & AR_MichaelErr) rxs->rs_status |= ATH9K_RXERR_MIC; + if (rxsp->status11 & AR_KeyMiss) rxs->rs_status |= ATH9K_RXERR_DECRYPT; } diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 180170d3ce25..c75d40fb86f1 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -690,17 +690,23 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, rs->rs_flags |= ATH9K_RX_DECRYPT_BUSY; if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) { + /* + * Treat these errors as mutually exclusive to avoid spurious + * extra error reports from the hardware. If a CRC error is + * reported, then decryption and MIC errors are irrelevant, + * the frame is going to be dropped either way + */ if (ads.ds_rxstatus8 & AR_CRCErr) rs->rs_status |= ATH9K_RXERR_CRC; - if (ads.ds_rxstatus8 & AR_PHYErr) { + else if (ads.ds_rxstatus8 & AR_PHYErr) { rs->rs_status |= ATH9K_RXERR_PHY; phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode); rs->rs_phyerr = phyerr; - } - if (ads.ds_rxstatus8 & AR_DecryptCRCErr) + } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) rs->rs_status |= ATH9K_RXERR_DECRYPT; - if (ads.ds_rxstatus8 & AR_MichaelErr) + else if (ads.ds_rxstatus8 & AR_MichaelErr) rs->rs_status |= ATH9K_RXERR_MIC; + if (ads.ds_rxstatus8 & AR_KeyMiss) rs->rs_status |= ATH9K_RXERR_DECRYPT; } -- cgit v1.2.3 From bdd196a3e00d2be8b50d8af0d8cf845884f4d59b Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Sat, 15 Jan 2011 01:01:22 +0530 Subject: ath9k: preserve caldata history buffer across scanning caldata's channel info is never filled with operating channel info which is causing the operating channel's noise floor history buffer is reset to default nf during channel change. Signed-off-by: Rajkumar Manoharan Acked-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/calib.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index b68a1acbddd0..b4a92a4313f6 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -382,9 +382,8 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, s16 default_nf; int i, j; - if (!ah->caldata) - return; - + ah->caldata->channel = chan->channel; + ah->caldata->channelFlags = chan->channelFlags & ~CHANNEL_CW_INT; h = ah->caldata->nfCalHist; default_nf = ath9k_hw_get_default_nf(ah, chan); for (i = 0; i < NUM_NF_READINGS; i++) { -- cgit v1.2.3 From 4e3ae3873858f1e64afb19975360000bee15b502 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Sat, 15 Jan 2011 01:33:28 +0530 Subject: ath9k_htc: keep calibrated noise floor value for oper channel The ath9k_hw assumes that caldata is valid only for oper channel. But with ath9k_htc case, the caldata is passed for all channels on hw_reset though we are not doing calibration on that channel. So the oper channel's nf history got cleared to default due to mismatch in channel flags. This patch also saves some space. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 1ce506f23110..c976600ba255 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -366,7 +366,7 @@ struct ath9k_htc_priv { u16 seq_no; u32 bmiss_cnt; - struct ath9k_hw_cal_data caldata[ATH9K_NUM_CHANNELS]; + struct ath9k_hw_cal_data caldata; spinlock_t beacon_lock; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index f4d576bc3ccd..187af5b4440d 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -121,7 +121,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) struct ath_hw *ah = priv->ah; struct ath_common *common = ath9k_hw_common(ah); struct ieee80211_channel *channel = priv->hw->conf.channel; - struct ath9k_hw_cal_data *caldata; + struct ath9k_hw_cal_data *caldata = NULL; enum htc_phymode mode; __be16 htc_mode; u8 cmd_rsp; @@ -139,7 +139,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); WMI_CMD(WMI_STOP_RECV_CMDID); - caldata = &priv->caldata[channel->hw_value]; + caldata = &priv->caldata; ret = ath9k_hw_reset(ah, ah->curchan, caldata, false); if (ret) { ath_err(common, @@ -202,7 +202,8 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf), fastcc); - caldata = &priv->caldata[channel->hw_value]; + if (!fastcc) + caldata = &priv->caldata; ret = ath9k_hw_reset(ah, hchan, caldata, fastcc); if (ret) { ath_err(common, -- cgit v1.2.3 From a4d6e17d3ee0f9d12474b1692f7a0574f1aab53c Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Sat, 15 Jan 2011 01:42:01 +0530 Subject: ath9k_hw: fix carrier leakage calibration for AR9271 AR9285 carrier leakage calibration related workaround on high temperature is not applicable for AR9271. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index ea2e7d714bda..14d7d2a68ec5 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -805,7 +805,10 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) { struct ath_common *common = ath9k_hw_common(ah); - if (AR_SREV_9271(ah) || AR_SREV_9285_12_OR_LATER(ah)) { + if (AR_SREV_9271(ah)) { + if (!ar9285_hw_cl_cal(ah, chan)) + return false; + } else if (AR_SREV_9285_12_OR_LATER(ah)) { if (!ar9285_hw_clc(ah, chan)) return false; } else { -- cgit v1.2.3 From 21f28e6f0061568b2347aa7517249fc034f949b5 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 15 Jan 2011 14:30:14 +0100 Subject: ath9k: try more than one tid when scheduling a new aggregate Sometimes the first TID in the first AC's list is not available for forming a new aggregate (the BAW might not allow it), however other TIDs may have data available for sending. Prevent a slowdown of other TIDs by going through multiple entries until we've either hit the last one or enough AMPDUs are pending in the hardware queue. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index ab4f7b4f789f..fffd13d204b5 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1224,12 +1224,14 @@ void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq) void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) { struct ath_atx_ac *ac; - struct ath_atx_tid *tid; + struct ath_atx_tid *tid, *last; - if (list_empty(&txq->axq_acq)) + if (list_empty(&txq->axq_acq) || + txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) return; ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list); + last = list_entry(ac->tid_q.prev, struct ath_atx_tid, list); list_del(&ac->list); ac->sched = false; @@ -1253,7 +1255,8 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) if (!list_empty(&tid->buf_q)) ath_tx_queue_tid(txq, tid); - break; + if (tid == last || txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) + break; } while (!list_empty(&ac->tid_q)); if (!list_empty(&ac->tid_q)) { -- cgit v1.2.3 From f0b8220c64242e19f41ad1b4eec3225d53715cbe Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 15 Jan 2011 14:30:15 +0100 Subject: ath9k: fix excessive BAR sending when a frame exceeds its retry limit Because the sendbar variable was not reset to zero, the stack would send Block ACK requests for all subframes following the one that failed, which could mess up the receiver side block ack window. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index fffd13d204b5..ad569e152d78 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -429,7 +429,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, ath_tx_count_frames(sc, bf, ts, txok, &nframes, &nbad); while (bf) { - txfail = txpending = 0; + txfail = txpending = sendbar = 0; bf_next = bf->bf_next; skb = bf->bf_mpdu; -- cgit v1.2.3 From 4801416c76a3a355076d6d371c00270dfe332e1c Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Sat, 15 Jan 2011 19:13:48 +0000 Subject: ath9k: Fix up hardware mode and beacons with multiple vifs. When using a mixture of AP and Station interfaces, the hardware mode was using the type of the last VIF registered. Instead, we should keep track of the number of different types of vifs and set the mode accordingly. In addtion, use the vif type instead of hardware opmode when dealing with beacons. Attempt to move some of the common setup code into smaller methods so we can re-use it when changing vif mode as well as adding/deleting vifs. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 23 ++- drivers/net/wireless/ath/ath9k/beacon.c | 14 +- drivers/net/wireless/ath/ath9k/main.c | 308 ++++++++++++++++++++++--------- drivers/net/wireless/ath/ath9k/recv.c | 16 +- drivers/net/wireless/ath/ath9k/virtual.c | 48 ----- 5 files changed, 263 insertions(+), 146 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 3681caf54282..6e22135a96ac 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -560,6 +560,20 @@ struct ath_ant_comb { struct ath_wiphy; struct ath_rate_table; +struct ath9k_vif_iter_data { + const u8 *hw_macaddr; /* phy's hardware address, set + * before starting iteration for + * valid bssid mask. + */ + u8 mask[ETH_ALEN]; /* bssid mask */ + int naps; /* number of AP vifs */ + int nmeshes; /* number of mesh vifs */ + int nstations; /* number of station vifs */ + int nwds; /* number of nwd vifs */ + int nadhocs; /* number of adhoc vifs */ + int nothers; /* number of vifs not specified above. */ +}; + struct ath_softc { struct ieee80211_hw *hw; struct device *dev; @@ -599,10 +613,10 @@ struct ath_softc { u32 sc_flags; /* SC_OP_* */ u16 ps_flags; /* PS_* */ u16 curtxpow; - u8 nbcnvifs; - u16 nvifs; bool ps_enabled; bool ps_idle; + short nbcnvifs; + short nvifs; unsigned long ps_usecount; struct ath_config config; @@ -683,6 +697,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw); void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode); +bool ath9k_uses_beacons(int type); #ifdef CONFIG_PCI int ath_pci_init(void); @@ -727,5 +742,9 @@ bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); void ath_start_rfkill_poll(struct ath_softc *sc); extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); +void ath9k_calculate_iter_data(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ath9k_vif_iter_data *iter_data); + #endif /* ATH9K_H */ diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 385ba03134ba..8de591e5b851 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -244,9 +244,7 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) struct ath_buf, list); list_del(&avp->av_bcbuf->list); - if (sc->sc_ah->opmode == NL80211_IFTYPE_AP || - sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC || - sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) { + if (ath9k_uses_beacons(vif->type)) { int slot; /* * Assign the vif to a beacon xmit slot. As @@ -282,7 +280,7 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) /* NB: the beacon data buffer must be 32-bit aligned. */ skb = ieee80211_beacon_get(sc->hw, vif); if (skb == NULL) { - ath_dbg(common, ATH_DBG_BEACON, "cannot get skb\n"); + ath_err(common, "ieee80211_beacon_get failed\n"); return -ENOMEM; } @@ -720,10 +718,10 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) iftype = sc->sc_ah->opmode; } - cur_conf->listen_interval = 1; - cur_conf->dtim_count = 1; - cur_conf->bmiss_timeout = - ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval; + cur_conf->listen_interval = 1; + cur_conf->dtim_count = 1; + cur_conf->bmiss_timeout = + ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval; /* * It looks like mac80211 may end up using beacon interval of zero in diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c753ba413f60..174c016ef89d 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1352,112 +1352,251 @@ static void ath9k_stop(struct ieee80211_hw *hw) ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n"); } -static int ath9k_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +bool ath9k_uses_beacons(int type) +{ + switch (type) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_MESH_POINT: + return true; + default: + return false; + } +} + +static void ath9k_reclaim_beacon(struct ath_softc *sc, + struct ieee80211_vif *vif) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; - struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); struct ath_vif *avp = (void *)vif->drv_priv; - enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED; - int ret = 0; - mutex_lock(&sc->mutex); + /* Disable SWBA interrupt */ + sc->sc_ah->imask &= ~ATH9K_INT_SWBA; + ath9k_ps_wakeup(sc); + ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); + ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); + tasklet_kill(&sc->bcon_tasklet); + ath9k_ps_restore(sc); + + ath_beacon_return(sc, avp); + sc->sc_flags &= ~SC_OP_BEACONS; + + if (sc->nbcnvifs > 0) { + /* Re-enable beaconing */ + sc->sc_ah->imask |= ATH9K_INT_SWBA; + ath9k_ps_wakeup(sc); + ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); + ath9k_ps_restore(sc); + } +} + +static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) +{ + struct ath9k_vif_iter_data *iter_data = data; + int i; + + if (iter_data->hw_macaddr) + for (i = 0; i < ETH_ALEN; i++) + iter_data->mask[i] &= + ~(iter_data->hw_macaddr[i] ^ mac[i]); switch (vif->type) { - case NL80211_IFTYPE_STATION: - ic_opmode = NL80211_IFTYPE_STATION; + case NL80211_IFTYPE_AP: + iter_data->naps++; break; - case NL80211_IFTYPE_WDS: - ic_opmode = NL80211_IFTYPE_WDS; + case NL80211_IFTYPE_STATION: + iter_data->nstations++; break; case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_AP: + iter_data->nadhocs++; + break; case NL80211_IFTYPE_MESH_POINT: - if (sc->nbcnvifs >= ATH_BCBUF) { - ret = -ENOBUFS; - goto out; - } - ic_opmode = vif->type; + iter_data->nmeshes++; + break; + case NL80211_IFTYPE_WDS: + iter_data->nwds++; break; default: - ath_err(common, "Interface type %d not yet supported\n", - vif->type); - ret = -EOPNOTSUPP; - goto out; + iter_data->nothers++; + break; } +} - ath_dbg(common, ATH_DBG_CONFIG, - "Attach a VIF of type: %d\n", ic_opmode); +/* Called with sc->mutex held. */ +void ath9k_calculate_iter_data(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ath9k_vif_iter_data *iter_data) +{ + struct ath_wiphy *aphy = hw->priv; + struct ath_softc *sc = aphy->sc; + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + int i; - /* Set the VIF opmode */ - avp->av_opmode = ic_opmode; - avp->av_bslot = -1; + /* + * Use the hardware MAC address as reference, the hardware uses it + * together with the BSSID mask when matching addresses. + */ + memset(iter_data, 0, sizeof(*iter_data)); + iter_data->hw_macaddr = common->macaddr; + memset(&iter_data->mask, 0xff, ETH_ALEN); - sc->nvifs++; + if (vif) + ath9k_vif_iter(iter_data, vif->addr, vif); + + /* Get list of all active MAC addresses */ + spin_lock_bh(&sc->wiphy_lock); + ieee80211_iterate_active_interfaces_atomic(sc->hw, ath9k_vif_iter, + iter_data); + for (i = 0; i < sc->num_sec_wiphy; i++) { + if (sc->sec_wiphy[i] == NULL) + continue; + ieee80211_iterate_active_interfaces_atomic( + sc->sec_wiphy[i]->hw, ath9k_vif_iter, iter_data); + } + spin_unlock_bh(&sc->wiphy_lock); +} + +/* Called with sc->mutex held. */ +static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct ath_wiphy *aphy = hw->priv; + struct ath_softc *sc = aphy->sc; + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_vif_iter_data iter_data; - ath9k_set_bssid_mask(hw, vif); + ath9k_calculate_iter_data(hw, vif, &iter_data); - if (sc->nvifs > 1) - goto out; /* skip global settings for secondary vif */ + /* Set BSSID mask. */ + memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); + ath_hw_setbssidmask(common); - if (ic_opmode == NL80211_IFTYPE_AP) { + /* Set op-mode & TSF */ + if (iter_data.naps > 0) { ath9k_hw_set_tsfadjust(ah, 1); sc->sc_flags |= SC_OP_TSF_RESET; - } + ah->opmode = NL80211_IFTYPE_AP; + } else { + ath9k_hw_set_tsfadjust(ah, 0); + sc->sc_flags &= ~SC_OP_TSF_RESET; - /* Set the device opmode */ - ah->opmode = ic_opmode; + if (iter_data.nwds + iter_data.nmeshes) + ah->opmode = NL80211_IFTYPE_AP; + else if (iter_data.nadhocs) + ah->opmode = NL80211_IFTYPE_ADHOC; + else + ah->opmode = NL80211_IFTYPE_STATION; + } /* * Enable MIB interrupts when there are hardware phy counters. - * Note we only do this (at the moment) for station mode. */ - if ((vif->type == NL80211_IFTYPE_STATION) || - (vif->type == NL80211_IFTYPE_ADHOC) || - (vif->type == NL80211_IFTYPE_MESH_POINT)) { + if ((iter_data.nstations + iter_data.nadhocs + iter_data.nmeshes) > 0) { if (ah->config.enable_ani) ah->imask |= ATH9K_INT_MIB; ah->imask |= ATH9K_INT_TSFOOR; + } else { + ah->imask &= ~ATH9K_INT_MIB; + ah->imask &= ~ATH9K_INT_TSFOOR; } ath9k_hw_set_interrupts(ah, ah->imask); - if (vif->type == NL80211_IFTYPE_AP || - vif->type == NL80211_IFTYPE_ADHOC) { + /* Set up ANI */ + if ((iter_data.naps + iter_data.nadhocs) > 0) { sc->sc_flags |= SC_OP_ANI_RUN; ath_start_ani(common); + } else { + sc->sc_flags &= ~SC_OP_ANI_RUN; + del_timer_sync(&common->ani.timer); } +} -out: - mutex_unlock(&sc->mutex); - return ret; +/* Called with sc->mutex held, vif counts set up properly. */ +static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct ath_wiphy *aphy = hw->priv; + struct ath_softc *sc = aphy->sc; + + ath9k_calculate_summary_state(hw, vif); + + if (ath9k_uses_beacons(vif->type)) { + int error; + ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); + /* This may fail because upper levels do not have beacons + * properly configured yet. That's OK, we assume it + * will be properly configured and then we will be notified + * in the info_changed method and set up beacons properly + * there. + */ + error = ath_beacon_alloc(aphy, vif); + if (error) + ath9k_reclaim_beacon(sc, vif); + else + ath_beacon_config(sc, vif); + } } -static void ath9k_reclaim_beacon(struct ath_softc *sc, - struct ieee80211_vif *vif) + +static int ath9k_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { + struct ath_wiphy *aphy = hw->priv; + struct ath_softc *sc = aphy->sc; + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); struct ath_vif *avp = (void *)vif->drv_priv; + int ret = 0; - /* Disable SWBA interrupt */ - sc->sc_ah->imask &= ~ATH9K_INT_SWBA; - ath9k_ps_wakeup(sc); - ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); - ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); - tasklet_kill(&sc->bcon_tasklet); - ath9k_ps_restore(sc); + mutex_lock(&sc->mutex); - ath_beacon_return(sc, avp); - sc->sc_flags &= ~SC_OP_BEACONS; + switch (vif->type) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_WDS: + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_MESH_POINT: + break; + default: + ath_err(common, "Interface type %d not yet supported\n", + vif->type); + ret = -EOPNOTSUPP; + goto out; + } - if (sc->nbcnvifs > 0) { - /* Re-enable beaconing */ - sc->sc_ah->imask |= ATH9K_INT_SWBA; - ath9k_ps_wakeup(sc); - ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); - ath9k_ps_restore(sc); + if (ath9k_uses_beacons(vif->type)) { + if (sc->nbcnvifs >= ATH_BCBUF) { + ath_err(common, "Not enough beacon buffers when adding" + " new interface of type: %i\n", + vif->type); + ret = -ENOBUFS; + goto out; + } + } + + if ((vif->type == NL80211_IFTYPE_ADHOC) && + sc->nvifs > 0) { + ath_err(common, "Cannot create ADHOC interface when other" + " interfaces already exist.\n"); + ret = -EINVAL; + goto out; } + + ath_dbg(common, ATH_DBG_CONFIG, + "Attach a VIF of type: %d\n", vif->type); + + /* Set the VIF opmode */ + avp->av_opmode = vif->type; + avp->av_bslot = -1; + + sc->nvifs++; + + ath9k_do_vif_add_setup(hw, vif); +out: + mutex_unlock(&sc->mutex); + return ret; } static int ath9k_change_interface(struct ieee80211_hw *hw, @@ -1473,32 +1612,33 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, ath_dbg(common, ATH_DBG_CONFIG, "Change Interface\n"); mutex_lock(&sc->mutex); - switch (new_type) { - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_ADHOC: + /* See if new interface type is valid. */ + if ((new_type == NL80211_IFTYPE_ADHOC) && + (sc->nvifs > 1)) { + ath_err(common, "When using ADHOC, it must be the only" + " interface.\n"); + ret = -EINVAL; + goto out; + } + + if (ath9k_uses_beacons(new_type) && + !ath9k_uses_beacons(vif->type)) { if (sc->nbcnvifs >= ATH_BCBUF) { ath_err(common, "No beacon slot available\n"); ret = -ENOBUFS; goto out; } - break; - case NL80211_IFTYPE_STATION: - /* Stop ANI */ - sc->sc_flags &= ~SC_OP_ANI_RUN; - del_timer_sync(&common->ani.timer); - if ((vif->type == NL80211_IFTYPE_AP) || - (vif->type == NL80211_IFTYPE_ADHOC)) - ath9k_reclaim_beacon(sc, vif); - break; - default: - ath_err(common, "Interface type %d not yet supported\n", - vif->type); - ret = -ENOTSUPP; - goto out; } + + /* Clean up old vif stuff */ + if (ath9k_uses_beacons(vif->type)) + ath9k_reclaim_beacon(sc, vif); + + /* Add new settings */ vif->type = new_type; vif->p2p = p2p; + ath9k_do_vif_add_setup(hw, vif); out: mutex_unlock(&sc->mutex); return ret; @@ -1515,17 +1655,13 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, mutex_lock(&sc->mutex); - /* Stop ANI */ - sc->sc_flags &= ~SC_OP_ANI_RUN; - del_timer_sync(&common->ani.timer); + sc->nvifs--; /* Reclaim beacon resources */ - if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || - (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || - (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) + if (ath9k_uses_beacons(vif->type)) ath9k_reclaim_beacon(sc, vif); - sc->nvifs--; + ath9k_calculate_summary_state(hw, NULL); mutex_unlock(&sc->mutex); } diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index b2497b8601e5..116f0582af24 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -588,8 +588,14 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) return; mgmt = (struct ieee80211_mgmt *)skb->data; - if (memcmp(common->curbssid, mgmt->bssid, ETH_ALEN) != 0) + if (memcmp(common->curbssid, mgmt->bssid, ETH_ALEN) != 0) { + /* TODO: This doesn't work well if you have stations + * associated to two different APs because curbssid + * is just the last AP that any of the stations associated + * with. + */ return; /* not from our current AP */ + } sc->ps_flags &= ~PS_WAIT_FOR_BEACON; @@ -984,8 +990,14 @@ static void ath9k_process_rssi(struct ath_common *common, fc = hdr->frame_control; if (!ieee80211_is_beacon(fc) || - compare_ether_addr(hdr->addr3, common->curbssid)) + compare_ether_addr(hdr->addr3, common->curbssid)) { + /* TODO: This doesn't work well if you have stations + * associated to two different APs because curbssid + * is just the last AP that any of the stations associated + * with. + */ return; + } if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && !rx_stats->rs_moreaggr) ATH_RSSI_LPF(aphy->last_rssi, rx_stats->rs_rssi); diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index 2dc7095e56d1..d205c66cd972 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c @@ -18,54 +18,6 @@ #include "ath9k.h" -struct ath9k_vif_iter_data { - const u8 *hw_macaddr; - u8 mask[ETH_ALEN]; -}; - -static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) -{ - struct ath9k_vif_iter_data *iter_data = data; - int i; - - for (i = 0; i < ETH_ALEN; i++) - iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]); -} - -void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -{ - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); - struct ath9k_vif_iter_data iter_data; - int i; - - /* - * Use the hardware MAC address as reference, the hardware uses it - * together with the BSSID mask when matching addresses. - */ - iter_data.hw_macaddr = common->macaddr; - memset(&iter_data.mask, 0xff, ETH_ALEN); - - if (vif) - ath9k_vif_iter(&iter_data, vif->addr, vif); - - /* Get list of all active MAC addresses */ - spin_lock_bh(&sc->wiphy_lock); - ieee80211_iterate_active_interfaces_atomic(sc->hw, ath9k_vif_iter, - &iter_data); - for (i = 0; i < sc->num_sec_wiphy; i++) { - if (sc->sec_wiphy[i] == NULL) - continue; - ieee80211_iterate_active_interfaces_atomic( - sc->sec_wiphy[i]->hw, ath9k_vif_iter, &iter_data); - } - spin_unlock_bh(&sc->wiphy_lock); - - memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); - ath_hw_setbssidmask(common); -} - int ath9k_wiphy_add(struct ath_softc *sc) { int i, error; -- cgit v1.2.3 From 0b01f030d38e00650e2db42da083d8647aad40a5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 18 Jan 2011 13:51:05 +0100 Subject: mac80211: track receiver's aggregation reorder buffer size The aggregation code currently doesn't implement the buffer size negotiation. It will always request a max buffer size (which is fine, if a little pointless, as the mac80211 code doesn't know and might just use 0 instead), but if the peer requests a smaller size it isn't possible to honour this request. In order to fix this, look at the buffer size in the addBA response frame, keep track of it and pass it to the driver in the ampdu_action callback when called with the IEEE80211_AMPDU_TX_OPERATIONAL action. That way the driver can limit the number of subframes in aggregates appropriately. Note that this doesn't fix any drivers apart from the addition of the new argument -- they all need to be updated separately to use this variable! Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ar9170/main.c | 3 ++- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 2 +- drivers/net/wireless/ath/ath9k/main.c | 2 +- drivers/net/wireless/ath/carl9170/main.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 ++- drivers/net/wireless/iwlwifi/iwl-agn.h | 3 ++- drivers/net/wireless/mac80211_hwsim.c | 3 ++- drivers/net/wireless/mwl8k.c | 3 ++- drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++- drivers/net/wireless/rt2x00/rt2800lib.h | 3 ++- drivers/net/wireless/rtlwifi/core.c | 3 ++- include/net/mac80211.h | 7 ++++++- net/mac80211/agg-rx.c | 4 ++-- net/mac80211/agg-tx.c | 20 +++++++++++++++++--- net/mac80211/driver-ops.h | 6 +++--- net/mac80211/driver-trace.h | 11 +++++++---- net/mac80211/sta_info.h | 2 ++ 17 files changed, 56 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index 32bf79e6a320..a9111e1161fd 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c @@ -1945,7 +1945,8 @@ static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, static int ar9170_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn) + struct ieee80211_sta *sta, u16 tid, u16 *ssn, + u8 buf_size) { switch (action) { case IEEE80211_AMPDU_RX_START: diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 187af5b4440d..f14f37d29f45 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1549,7 +1549,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, struct ieee80211_sta *sta, - u16 tid, u16 *ssn) + u16 tid, u16 *ssn, u8 buf_size) { struct ath9k_htc_priv *priv = hw->priv; struct ath9k_htc_sta *ista; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 174c016ef89d..c03184e7bffe 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2165,7 +2165,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, struct ieee80211_sta *sta, - u16 tid, u16 *ssn) + u16 tid, u16 *ssn, u8 buf_size) { struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 870df8c42622..ecfb80b059d1 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1279,7 +1279,7 @@ static int carl9170_op_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, struct ieee80211_sta *sta, - u16 tid, u16 *ssn) + u16 tid, u16 *ssn, u8 buf_size) { struct ar9170 *ar = hw->priv; struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 36335b1b54d4..8b045a401d62 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3393,7 +3393,8 @@ int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn) + struct ieee80211_sta *sta, u16 tid, u16 *ssn, + u8 buf_size) { struct iwl_priv *priv = hw->priv; int ret = -EINVAL; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index da303585f801..822221a97e80 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -349,7 +349,8 @@ void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn); + struct ieee80211_sta *sta, u16 tid, u16 *ssn, + u8 buf_size); int iwlagn_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 454f045ddff3..5d39b2840584 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -943,7 +943,8 @@ static int mac80211_hwsim_testmode_cmd(struct ieee80211_hw *hw, static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn) + struct ieee80211_sta *sta, u16 tid, u16 *ssn, + u8 buf_size) { switch (action) { case IEEE80211_AMPDU_TX_START: diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 809f2bf27958..106b427d0064 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -4356,7 +4356,8 @@ static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx, static int mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn) + struct ieee80211_sta *sta, u16 tid, u16 *ssn, + u8 buf_size) { switch (action) { case IEEE80211_AMPDU_RX_START: diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index a25be625ee90..f8ba01cbc6dd 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -3533,7 +3533,8 @@ EXPORT_SYMBOL_GPL(rt2800_get_tsf); int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn) + struct ieee80211_sta *sta, u16 tid, u16 *ssn, + u8 buf_size) { int ret = 0; diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index e3c995a9dec4..3efafb78ff77 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h @@ -198,7 +198,8 @@ int rt2800_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, u64 rt2800_get_tsf(struct ieee80211_hw *hw); int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn); + struct ieee80211_sta *sta, u16 tid, u16 *ssn, + u8 buf_size); int rt2800_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey); diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index d6a924a05654..25d2d667ffba 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -748,7 +748,8 @@ static void rtl_op_sta_notify(struct ieee80211_hw *hw, static int rtl_op_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 * ssn) + struct ieee80211_sta *sta, u16 tid, u16 *ssn, + u8 buf_size) { struct rtl_priv *rtlpriv = rtl_priv(hw); diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d024fc563e7b..5afe341b4010 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1731,6 +1731,10 @@ enum ieee80211_ampdu_mlme_action { * ieee80211_ampdu_mlme_action. Starting sequence number (@ssn) * is the first frame we expect to perform the action on. Notice * that TX/RX_STOP can pass NULL for this parameter. + * The @buf_size parameter is only valid when the action is set to + * %IEEE80211_AMPDU_TX_OPERATIONAL and indicates the peer's reorder + * buffer size (number of subframes) for this session -- aggregates + * containing more subframes than this may not be transmitted to the peer. * Returns a negative error code on failure. * The callback can sleep. * @@ -1833,7 +1837,8 @@ struct ieee80211_ops { int (*ampdu_action)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn); + struct ieee80211_sta *sta, u16 tid, u16 *ssn, + u8 buf_size); int (*get_survey)(struct ieee80211_hw *hw, int idx, struct survey_info *survey); void (*rfkill_poll)(struct ieee80211_hw *hw); diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 002db5e86eb6..1f51f4162426 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c @@ -76,7 +76,7 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, #endif /* CONFIG_MAC80211_HT_DEBUG */ if (drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_STOP, - &sta->sta, tid, NULL)) + &sta->sta, tid, NULL, 0)) printk(KERN_DEBUG "HW problem - can not stop rx " "aggregation for tid %d\n", tid); @@ -297,7 +297,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, } ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_START, - &sta->sta, tid, &start_seq_num); + &sta->sta, tid, &start_seq_num, 0); #ifdef CONFIG_MAC80211_HT_DEBUG printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret); #endif /* CONFIG_MAC80211_HT_DEBUG */ diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 9cc472c6a6a5..42f7c9007331 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -190,7 +190,7 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_TX_STOP, - &sta->sta, tid, NULL); + &sta->sta, tid, NULL, 0); /* HW shall not deny going back to legacy */ if (WARN_ON(ret)) { @@ -311,7 +311,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) start_seq_num = sta->tid_seq[tid] >> 4; ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START, - &sta->sta, tid, &start_seq_num); + &sta->sta, tid, &start_seq_num, 0); if (ret) { #ifdef CONFIG_MAC80211_HT_DEBUG printk(KERN_DEBUG "BA request denied - HW unavailable for" @@ -487,7 +487,8 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local, drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_TX_OPERATIONAL, - &sta->sta, tid, NULL); + &sta->sta, tid, NULL, + sta->ampdu_mlme.tid_tx[tid]->buf_size); /* * synchronize with TX path, while splicing the TX path @@ -742,9 +743,11 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, { struct tid_ampdu_tx *tid_tx; u16 capab, tid; + u8 buf_size; capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; + buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6; mutex_lock(&sta->ampdu_mlme.mtx); @@ -767,12 +770,23 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) == WLAN_STATUS_SUCCESS) { + /* + * IEEE 802.11-2007 7.3.1.14: + * In an ADDBA Response frame, when the Status Code field + * is set to 0, the Buffer Size subfield is set to a value + * of at least 1. + */ + if (!buf_size) + goto out; + if (test_and_set_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) { /* ignore duplicate response */ goto out; } + tid_tx->buf_size = buf_size; + if (test_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state)) ieee80211_agg_tx_operational(local, sta, tid); diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 98d589960a49..78af32d4bc58 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -382,17 +382,17 @@ static inline int drv_ampdu_action(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, enum ieee80211_ampdu_mlme_action action, struct ieee80211_sta *sta, u16 tid, - u16 *ssn) + u16 *ssn, u8 buf_size) { int ret = -EOPNOTSUPP; might_sleep(); - trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn); + trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size); if (local->ops->ampdu_action) ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action, - sta, tid, ssn); + sta, tid, ssn, buf_size); trace_drv_return_int(local, ret); diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 49c84218b2f4..fbabbc2f181a 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h @@ -784,9 +784,9 @@ TRACE_EVENT(drv_ampdu_action, struct ieee80211_sub_if_data *sdata, enum ieee80211_ampdu_mlme_action action, struct ieee80211_sta *sta, u16 tid, - u16 *ssn), + u16 *ssn, u8 buf_size), - TP_ARGS(local, sdata, action, sta, tid, ssn), + TP_ARGS(local, sdata, action, sta, tid, ssn, buf_size), TP_STRUCT__entry( LOCAL_ENTRY @@ -794,6 +794,7 @@ TRACE_EVENT(drv_ampdu_action, __field(u32, action) __field(u16, tid) __field(u16, ssn) + __field(u8, buf_size) VIF_ENTRY ), @@ -804,11 +805,13 @@ TRACE_EVENT(drv_ampdu_action, __entry->action = action; __entry->tid = tid; __entry->ssn = ssn ? *ssn : 0; + __entry->buf_size = buf_size; ), TP_printk( - LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " action:%d tid:%d", - LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->action, __entry->tid + LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " action:%d tid:%d buf:%d", + LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->action, + __entry->tid, __entry->buf_size ) ); diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index bbdd2a86a94b..ca0b69060ef7 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -82,6 +82,7 @@ enum ieee80211_sta_info_flags { * @state: session state (see above) * @stop_initiator: initiator of a session stop * @tx_stop: TX DelBA frame when stopping + * @buf_size: reorder buffer size at receiver * * This structure's lifetime is managed by RCU, assignments to * the array holding it must hold the aggregation mutex. @@ -101,6 +102,7 @@ struct tid_ampdu_tx { u8 dialog_token; u8 stop_initiator; bool tx_stop; + u8 buf_size; }; /** -- cgit v1.2.3 From 6cca200362b46a6845b3f07367f5068a427161e1 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Tue, 18 Jan 2011 15:02:19 +0000 Subject: vxge: cleanup probe error paths Reorder the commands to be in the inverse order of their allocations (instead of the random order they appear to be in), propagate return code on errors from pci_request_region and register_netdev, reduce the config_dev_cnt and total_dev_cnt counters on remove, and return the correct error code for vdev->vpaths kzalloc failures. Also, prevent leaking of vdev->vpaths memory and netdev in vxge_probe error path due to freeing for these not occurring in vxge_device_unregister. Signed-off-by: Jon Mason Signed-off-by: Sivakumar Subramani Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-main.c | 55 ++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index c81a6512c683..ecf9a8ee6838 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -3348,7 +3348,7 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev, vxge_debug_init(VXGE_ERR, "%s: vpath memory allocation failed", vdev->ndev->name); - ret = -ENODEV; + ret = -ENOMEM; goto _out1; } @@ -3369,11 +3369,11 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev, if (vdev->config.gro_enable) ndev->features |= NETIF_F_GRO; - if (register_netdev(ndev)) { + ret = register_netdev(ndev); + if (ret) { vxge_debug_init(vxge_hw_device_trace_level_get(hldev), "%s: %s : device registration failed!", ndev->name, __func__); - ret = -ENODEV; goto _out2; } @@ -3444,6 +3444,11 @@ static void vxge_device_unregister(struct __vxge_hw_device *hldev) /* in 2.6 will call stop() if device is up */ unregister_netdev(dev); + kfree(vdev->vpaths); + + /* we are safe to free it now */ + free_netdev(dev); + vxge_debug_init(vdev->level_trace, "%s: ethernet device unregistered", buf); vxge_debug_entryexit(vdev->level_trace, "%s: %s:%d Exiting...", buf, @@ -4335,10 +4340,10 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) goto _exit1; } - if (pci_request_region(pdev, 0, VXGE_DRIVER_NAME)) { + ret = pci_request_region(pdev, 0, VXGE_DRIVER_NAME); + if (ret) { vxge_debug_init(VXGE_ERR, "%s : request regions failed", __func__); - ret = -ENODEV; goto _exit1; } @@ -4643,8 +4648,9 @@ _exit6: _exit5: vxge_device_unregister(hldev); _exit4: - pci_disable_sriov(pdev); + pci_set_drvdata(pdev, NULL); vxge_hw_device_terminate(hldev); + pci_disable_sriov(pdev); _exit3: iounmap(attr.bar0); _exit2: @@ -4655,7 +4661,7 @@ _exit0: kfree(ll_config); kfree(device_config); driver_config->config_dev_cnt--; - pci_set_drvdata(pdev, NULL); + driver_config->total_dev_cnt--; return ret; } @@ -4668,45 +4674,34 @@ _exit0: static void __devexit vxge_remove(struct pci_dev *pdev) { struct __vxge_hw_device *hldev; - struct vxgedev *vdev = NULL; - struct net_device *dev; - int i = 0; + struct vxgedev *vdev; + int i; hldev = pci_get_drvdata(pdev); - if (hldev == NULL) return; - dev = hldev->ndev; - vdev = netdev_priv(dev); + vdev = netdev_priv(hldev->ndev); vxge_debug_entryexit(vdev->level_trace, "%s:%d", __func__, __LINE__); - vxge_debug_init(vdev->level_trace, "%s : removing PCI device...", __func__); - vxge_device_unregister(hldev); - for (i = 0; i < vdev->no_of_vpath; i++) { + for (i = 0; i < vdev->no_of_vpath; i++) vxge_free_mac_add_list(&vdev->vpaths[i]); - vdev->vpaths[i].mcast_addr_cnt = 0; - vdev->vpaths[i].mac_addr_cnt = 0; - } - - kfree(vdev->vpaths); + vxge_device_unregister(hldev); + pci_set_drvdata(pdev, NULL); + /* Do not call pci_disable_sriov here, as it will break child devices */ + vxge_hw_device_terminate(hldev); iounmap(vdev->bar0); - - /* we are safe to free it now */ - free_netdev(dev); + pci_release_region(pdev, 0); + pci_disable_device(pdev); + driver_config->config_dev_cnt--; + driver_config->total_dev_cnt--; vxge_debug_init(vdev->level_trace, "%s:%d Device unregistered", __func__, __LINE__); - - vxge_hw_device_terminate(hldev); - - pci_disable_device(pdev); - pci_release_region(pdev, 0); - pci_set_drvdata(pdev, NULL); vxge_debug_entryexit(vdev->level_trace, "%s:%d Exiting...", __func__, __LINE__); } -- cgit v1.2.3 From 1d15f81cda496f1c1d59af7458ea0bcdeeb726f3 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Tue, 18 Jan 2011 15:02:20 +0000 Subject: vxge: correct eprom version detection The firmware PXE EPROM version detection is failing due to passing the wrong parameter into firmware query function. Also, the version printing function has an extraneous newline. Signed-off-by: Jon Mason Signed-off-by: Sivakumar Subramani Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-config.c | 2 +- drivers/net/vxge/vxge-main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 01c05f53e2f9..da35562ba48c 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -387,8 +387,8 @@ vxge_hw_vpath_eprom_img_ver_get(struct __vxge_hw_device *hldev, data1 = steer_ctrl = 0; status = vxge_hw_vpath_fw_api(vpath, - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, VXGE_HW_FW_API_GET_EPROM_REV, + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, 0, &data0, &data1, &steer_ctrl); if (status != VXGE_HW_OK) break; diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index ecf9a8ee6838..0fcac099413a 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -4451,7 +4451,7 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) if (!img[i].is_valid) break; vxge_debug_init(VXGE_TRACE, "%s: EPROM %d, version " - "%d.%d.%d.%d\n", VXGE_DRIVER_NAME, i, + "%d.%d.%d.%d", VXGE_DRIVER_NAME, i, VXGE_EPROM_IMG_MAJOR(img[i].version), VXGE_EPROM_IMG_MINOR(img[i].version), VXGE_EPROM_IMG_FIX(img[i].version), -- cgit v1.2.3 From 16fded7da2cefc619ece0d44f8df76b533c43fd2 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Tue, 18 Jan 2011 15:02:21 +0000 Subject: vxge: MSIX one shot mode To reduce the possibility of losing an interrupt in the handler due to a race between an interrupt processing and disable/enable of interrupts, enable MSIX one shot. Also, add support for adaptive interrupt coalesing Signed-off-by: Jon Mason Signed-off-by: Masroor Vettuparambil Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-config.c | 30 +++----- drivers/net/vxge/vxge-config.h | 10 +++ drivers/net/vxge/vxge-main.c | 159 +++++++++++++++++++++++++++++++++++----- drivers/net/vxge/vxge-main.h | 23 +++++- drivers/net/vxge/vxge-traffic.c | 116 +++++++++++++++++++++++++++-- drivers/net/vxge/vxge-traffic.h | 14 +++- 6 files changed, 302 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index da35562ba48c..77097e383cf4 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -2868,6 +2868,8 @@ __vxge_hw_ring_create(struct __vxge_hw_vpath_handle *vp, ring->rxd_init = attr->rxd_init; ring->rxd_term = attr->rxd_term; ring->buffer_mode = config->buffer_mode; + ring->tim_rti_cfg1_saved = vp->vpath->tim_rti_cfg1_saved; + ring->tim_rti_cfg3_saved = vp->vpath->tim_rti_cfg3_saved; ring->rxds_limit = config->rxds_limit; ring->rxd_size = vxge_hw_ring_rxd_size_get(config->buffer_mode); @@ -3511,6 +3513,8 @@ __vxge_hw_fifo_create(struct __vxge_hw_vpath_handle *vp, /* apply "interrupts per txdl" attribute */ fifo->interrupt_type = VXGE_HW_FIFO_TXD_INT_TYPE_UTILZ; + fifo->tim_tti_cfg1_saved = vpath->tim_tti_cfg1_saved; + fifo->tim_tti_cfg3_saved = vpath->tim_tti_cfg3_saved; if (fifo->config->intr) fifo->interrupt_type = VXGE_HW_FIFO_TXD_INT_TYPE_PER_LIST; @@ -4377,6 +4381,8 @@ __vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id) } writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]); + vpath->tim_tti_cfg1_saved = val64; + val64 = readq(&vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_TX]); if (config->tti.uec_a != VXGE_HW_USE_FLASH_DEFAULT) { @@ -4433,6 +4439,7 @@ __vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id) } writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_TX]); + vpath->tim_tti_cfg3_saved = val64; } if (config->ring.enable == VXGE_HW_RING_ENABLE) { @@ -4481,6 +4488,8 @@ __vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id) } writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_RX]); + vpath->tim_rti_cfg1_saved = val64; + val64 = readq(&vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_RX]); if (config->rti.uec_a != VXGE_HW_USE_FLASH_DEFAULT) { @@ -4537,6 +4546,7 @@ __vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id) } writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_RX]); + vpath->tim_rti_cfg3_saved = val64; } val64 = 0; @@ -4555,26 +4565,6 @@ __vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id) return status; } -void vxge_hw_vpath_tti_ci_set(struct __vxge_hw_device *hldev, u32 vp_id) -{ - struct __vxge_hw_virtualpath *vpath; - struct vxge_hw_vpath_reg __iomem *vp_reg; - struct vxge_hw_vp_config *config; - u64 val64; - - vpath = &hldev->virtual_paths[vp_id]; - vp_reg = vpath->vp_reg; - config = vpath->vp_config; - - if (config->fifo.enable == VXGE_HW_FIFO_ENABLE && - config->tti.timer_ci_en != VXGE_HW_TIM_TIMER_CI_ENABLE) { - config->tti.timer_ci_en = VXGE_HW_TIM_TIMER_CI_ENABLE; - val64 = readq(&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]); - val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI; - writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]); - } -} - /* * __vxge_hw_vpath_initialize * This routine is the final phase of init which initializes the diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h index e249e288d160..3c53aa732c9d 100644 --- a/drivers/net/vxge/vxge-config.h +++ b/drivers/net/vxge/vxge-config.h @@ -682,6 +682,10 @@ struct __vxge_hw_virtualpath { u32 vsport_number; u32 max_kdfc_db; u32 max_nofl_db; + u64 tim_tti_cfg1_saved; + u64 tim_tti_cfg3_saved; + u64 tim_rti_cfg1_saved; + u64 tim_rti_cfg3_saved; struct __vxge_hw_ring *____cacheline_aligned ringh; struct __vxge_hw_fifo *____cacheline_aligned fifoh; @@ -921,6 +925,9 @@ struct __vxge_hw_ring { u32 doorbell_cnt; u32 total_db_cnt; u64 rxds_limit; + u32 rtimer; + u64 tim_rti_cfg1_saved; + u64 tim_rti_cfg3_saved; enum vxge_hw_status (*callback)( struct __vxge_hw_ring *ringh, @@ -1000,6 +1007,9 @@ struct __vxge_hw_fifo { u32 per_txdl_space; u32 vp_id; u32 tx_intr_num; + u32 rtimer; + u64 tim_tti_cfg1_saved; + u64 tim_tti_cfg3_saved; enum vxge_hw_status (*callback)( struct __vxge_hw_fifo *fifo_handle, diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 0fcac099413a..e40f619b62b1 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -371,9 +371,6 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr, struct vxge_hw_ring_rxd_info ext_info; vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d", ring->ndev->name, __func__, __LINE__); - ring->pkts_processed = 0; - - vxge_hw_ring_replenish(ringh); do { prefetch((char *)dtr + L1_CACHE_BYTES); @@ -1588,6 +1585,36 @@ static int vxge_reset_vpath(struct vxgedev *vdev, int vp_id) return ret; } +/* Configure CI */ +static void vxge_config_ci_for_tti_rti(struct vxgedev *vdev) +{ + int i = 0; + + /* Enable CI for RTI */ + if (vdev->config.intr_type == MSI_X) { + for (i = 0; i < vdev->no_of_vpath; i++) { + struct __vxge_hw_ring *hw_ring; + + hw_ring = vdev->vpaths[i].ring.handle; + vxge_hw_vpath_dynamic_rti_ci_set(hw_ring); + } + } + + /* Enable CI for TTI */ + for (i = 0; i < vdev->no_of_vpath; i++) { + struct __vxge_hw_fifo *hw_fifo = vdev->vpaths[i].fifo.handle; + vxge_hw_vpath_tti_ci_set(hw_fifo); + /* + * For Inta (with or without napi), Set CI ON for only one + * vpath. (Have only one free running timer). + */ + if ((vdev->config.intr_type == INTA) && (i == 0)) + break; + } + + return; +} + static int do_vxge_reset(struct vxgedev *vdev, int event) { enum vxge_hw_status status; @@ -1753,6 +1780,9 @@ static int do_vxge_reset(struct vxgedev *vdev, int event) netif_tx_wake_all_queues(vdev->ndev); } + /* configure CI */ + vxge_config_ci_for_tti_rti(vdev); + out: vxge_debug_entryexit(VXGE_TRACE, "%s:%d Exiting...", __func__, __LINE__); @@ -1793,22 +1823,29 @@ static void vxge_reset(struct work_struct *work) */ static int vxge_poll_msix(struct napi_struct *napi, int budget) { - struct vxge_ring *ring = - container_of(napi, struct vxge_ring, napi); + struct vxge_ring *ring = container_of(napi, struct vxge_ring, napi); + int pkts_processed; int budget_org = budget; - ring->budget = budget; + ring->budget = budget; + ring->pkts_processed = 0; vxge_hw_vpath_poll_rx(ring->handle); + pkts_processed = ring->pkts_processed; if (ring->pkts_processed < budget_org) { napi_complete(napi); + /* Re enable the Rx interrupts for the vpath */ vxge_hw_channel_msix_unmask( (struct __vxge_hw_channel *)ring->handle, ring->rx_vector_no); + mmiowb(); } - return ring->pkts_processed; + /* We are copying and returning the local variable, in case if after + * clearing the msix interrupt above, if the interrupt fires right + * away which can preempt this NAPI thread */ + return pkts_processed; } static int vxge_poll_inta(struct napi_struct *napi, int budget) @@ -1824,6 +1861,7 @@ static int vxge_poll_inta(struct napi_struct *napi, int budget) for (i = 0; i < vdev->no_of_vpath; i++) { ring = &vdev->vpaths[i].ring; ring->budget = budget; + ring->pkts_processed = 0; vxge_hw_vpath_poll_rx(ring->handle); pkts_processed += ring->pkts_processed; budget -= ring->pkts_processed; @@ -2054,6 +2092,7 @@ static int vxge_open_vpaths(struct vxgedev *vdev) netdev_get_tx_queue(vdev->ndev, 0); vpath->fifo.indicate_max_pkts = vdev->config.fifo_indicate_max_pkts; + vpath->fifo.tx_vector_no = 0; vpath->ring.rx_vector_no = 0; vpath->ring.rx_csum = vdev->rx_csum; vpath->ring.rx_hwts = vdev->rx_hwts; @@ -2079,6 +2118,61 @@ static int vxge_open_vpaths(struct vxgedev *vdev) return VXGE_HW_OK; } +/** + * adaptive_coalesce_tx_interrupts - Changes the interrupt coalescing + * if the interrupts are not within a range + * @fifo: pointer to transmit fifo structure + * Description: The function changes boundary timer and restriction timer + * value depends on the traffic + * Return Value: None + */ +static void adaptive_coalesce_tx_interrupts(struct vxge_fifo *fifo) +{ + fifo->interrupt_count++; + if (jiffies > fifo->jiffies + HZ / 100) { + struct __vxge_hw_fifo *hw_fifo = fifo->handle; + + fifo->jiffies = jiffies; + if (fifo->interrupt_count > VXGE_T1A_MAX_TX_INTERRUPT_COUNT && + hw_fifo->rtimer != VXGE_TTI_RTIMER_ADAPT_VAL) { + hw_fifo->rtimer = VXGE_TTI_RTIMER_ADAPT_VAL; + vxge_hw_vpath_dynamic_tti_rtimer_set(hw_fifo); + } else if (hw_fifo->rtimer != 0) { + hw_fifo->rtimer = 0; + vxge_hw_vpath_dynamic_tti_rtimer_set(hw_fifo); + } + fifo->interrupt_count = 0; + } +} + +/** + * adaptive_coalesce_rx_interrupts - Changes the interrupt coalescing + * if the interrupts are not within a range + * @ring: pointer to receive ring structure + * Description: The function increases of decreases the packet counts within + * the ranges of traffic utilization, if the interrupts due to this ring are + * not within a fixed range. + * Return Value: Nothing + */ +static void adaptive_coalesce_rx_interrupts(struct vxge_ring *ring) +{ + ring->interrupt_count++; + if (jiffies > ring->jiffies + HZ / 100) { + struct __vxge_hw_ring *hw_ring = ring->handle; + + ring->jiffies = jiffies; + if (ring->interrupt_count > VXGE_T1A_MAX_INTERRUPT_COUNT && + hw_ring->rtimer != VXGE_RTI_RTIMER_ADAPT_VAL) { + hw_ring->rtimer = VXGE_RTI_RTIMER_ADAPT_VAL; + vxge_hw_vpath_dynamic_rti_rtimer_set(hw_ring); + } else if (hw_ring->rtimer != 0) { + hw_ring->rtimer = 0; + vxge_hw_vpath_dynamic_rti_rtimer_set(hw_ring); + } + ring->interrupt_count = 0; + } +} + /* * vxge_isr_napi * @irq: the irq of the device. @@ -2139,24 +2233,39 @@ static irqreturn_t vxge_isr_napi(int irq, void *dev_id) #ifdef CONFIG_PCI_MSI -static irqreturn_t -vxge_tx_msix_handle(int irq, void *dev_id) +static irqreturn_t vxge_tx_msix_handle(int irq, void *dev_id) { struct vxge_fifo *fifo = (struct vxge_fifo *)dev_id; + adaptive_coalesce_tx_interrupts(fifo); + + vxge_hw_channel_msix_mask((struct __vxge_hw_channel *)fifo->handle, + fifo->tx_vector_no); + + vxge_hw_channel_msix_clear((struct __vxge_hw_channel *)fifo->handle, + fifo->tx_vector_no); + VXGE_COMPLETE_VPATH_TX(fifo); + vxge_hw_channel_msix_unmask((struct __vxge_hw_channel *)fifo->handle, + fifo->tx_vector_no); + + mmiowb(); + return IRQ_HANDLED; } -static irqreturn_t -vxge_rx_msix_napi_handle(int irq, void *dev_id) +static irqreturn_t vxge_rx_msix_napi_handle(int irq, void *dev_id) { struct vxge_ring *ring = (struct vxge_ring *)dev_id; - /* MSIX_IDX for Rx is 1 */ + adaptive_coalesce_rx_interrupts(ring); + vxge_hw_channel_msix_mask((struct __vxge_hw_channel *)ring->handle, - ring->rx_vector_no); + ring->rx_vector_no); + + vxge_hw_channel_msix_clear((struct __vxge_hw_channel *)ring->handle, + ring->rx_vector_no); napi_schedule(&ring->napi); return IRQ_HANDLED; @@ -2173,14 +2282,20 @@ vxge_alarm_msix_handle(int irq, void *dev_id) VXGE_HW_VPATH_MSIX_ACTIVE) + VXGE_ALARM_MSIX_ID; for (i = 0; i < vdev->no_of_vpath; i++) { + /* Reduce the chance of loosing alarm interrupts by masking + * the vector. A pending bit will be set if an alarm is + * generated and on unmask the interrupt will be fired. + */ vxge_hw_vpath_msix_mask(vdev->vpaths[i].handle, msix_id); + vxge_hw_vpath_msix_clear(vdev->vpaths[i].handle, msix_id); + mmiowb(); status = vxge_hw_vpath_alarm_process(vdev->vpaths[i].handle, vdev->exec_mode); if (status == VXGE_HW_OK) { - vxge_hw_vpath_msix_unmask(vdev->vpaths[i].handle, - msix_id); + msix_id); + mmiowb(); continue; } vxge_debug_intr(VXGE_ERR, @@ -2299,6 +2414,9 @@ static int vxge_enable_msix(struct vxgedev *vdev) vpath->ring.rx_vector_no = (vpath->device_id * VXGE_HW_VPATH_MSIX_ACTIVE) + 1; + vpath->fifo.tx_vector_no = (vpath->device_id * + VXGE_HW_VPATH_MSIX_ACTIVE); + vxge_hw_vpath_msix_set(vpath->handle, tim_msix_id, VXGE_ALARM_MSIX_ID); } @@ -2474,8 +2592,9 @@ INTA_MODE: "%s:vxge:INTA", vdev->ndev->name); vxge_hw_device_set_intr_type(vdev->devh, VXGE_HW_INTR_MODE_IRQLINE); - vxge_hw_vpath_tti_ci_set(vdev->devh, - vdev->vpaths[0].device_id); + + vxge_hw_vpath_tti_ci_set(vdev->vpaths[0].fifo.handle); + ret = request_irq((int) vdev->pdev->irq, vxge_isr_napi, IRQF_SHARED, vdev->desc[0], vdev); @@ -2745,6 +2864,10 @@ static int vxge_open(struct net_device *dev) } netif_tx_start_all_queues(vdev->ndev); + + /* configure CI */ + vxge_config_ci_for_tti_rti(vdev); + goto out0; out2: @@ -3804,7 +3927,7 @@ static void __devinit vxge_device_config_init( break; case MSI_X: - device_config->intr_mode = VXGE_HW_INTR_MODE_MSIX; + device_config->intr_mode = VXGE_HW_INTR_MODE_MSIX_ONE_SHOT; break; } diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h index 5746fedc356f..40474f0da576 100644 --- a/drivers/net/vxge/vxge-main.h +++ b/drivers/net/vxge/vxge-main.h @@ -59,11 +59,13 @@ #define VXGE_TTI_LTIMER_VAL 1000 #define VXGE_T1A_TTI_LTIMER_VAL 80 #define VXGE_TTI_RTIMER_VAL 0 +#define VXGE_TTI_RTIMER_ADAPT_VAL 10 #define VXGE_T1A_TTI_RTIMER_VAL 400 #define VXGE_RTI_BTIMER_VAL 250 #define VXGE_RTI_LTIMER_VAL 100 #define VXGE_RTI_RTIMER_VAL 0 -#define VXGE_FIFO_INDICATE_MAX_PKTS VXGE_DEF_FIFO_LENGTH +#define VXGE_RTI_RTIMER_ADAPT_VAL 15 +#define VXGE_FIFO_INDICATE_MAX_PKTS VXGE_DEF_FIFO_LENGTH #define VXGE_ISR_POLLING_CNT 8 #define VXGE_MAX_CONFIG_DEV 0xFF #define VXGE_EXEC_MODE_DISABLE 0 @@ -107,6 +109,14 @@ #define RTI_T1A_RX_UFC_C 50 #define RTI_T1A_RX_UFC_D 60 +/* + * The interrupt rate is maintained at 3k per second with the moderation + * parameters for most traffic but not all. This is the maximum interrupt + * count allowed per function with INTA or per vector in the case of + * MSI-X in a 10 millisecond time period. Enabled only for Titan 1A. + */ +#define VXGE_T1A_MAX_INTERRUPT_COUNT 100 +#define VXGE_T1A_MAX_TX_INTERRUPT_COUNT 200 /* Milli secs timer period */ #define VXGE_TIMER_DELAY 10000 @@ -247,6 +257,11 @@ struct vxge_fifo { int tx_steering_type; int indicate_max_pkts; + /* Adaptive interrupt moderation parameters used in T1A */ + unsigned long interrupt_count; + unsigned long jiffies; + + u32 tx_vector_no; /* Tx stats */ struct vxge_fifo_stats stats; } ____cacheline_aligned; @@ -271,6 +286,10 @@ struct vxge_ring { */ int driver_id; + /* Adaptive interrupt moderation parameters used in T1A */ + unsigned long interrupt_count; + unsigned long jiffies; + /* copy of the flag indicating whether rx_csum is to be used */ u32 rx_csum:1, rx_hwts:1; @@ -286,7 +305,7 @@ struct vxge_ring { int vlan_tag_strip; struct vlan_group *vlgrp; - int rx_vector_no; + u32 rx_vector_no; enum vxge_hw_status last_status; /* Rx stats */ diff --git a/drivers/net/vxge/vxge-traffic.c b/drivers/net/vxge/vxge-traffic.c index 4c10d6c4075f..8674f331311c 100644 --- a/drivers/net/vxge/vxge-traffic.c +++ b/drivers/net/vxge/vxge-traffic.c @@ -218,6 +218,68 @@ exit: return status; } +void vxge_hw_vpath_tti_ci_set(struct __vxge_hw_fifo *fifo) +{ + struct vxge_hw_vpath_reg __iomem *vp_reg; + struct vxge_hw_vp_config *config; + u64 val64; + + if (fifo->config->enable != VXGE_HW_FIFO_ENABLE) + return; + + vp_reg = fifo->vp_reg; + config = container_of(fifo->config, struct vxge_hw_vp_config, fifo); + + if (config->tti.timer_ci_en != VXGE_HW_TIM_TIMER_CI_ENABLE) { + config->tti.timer_ci_en = VXGE_HW_TIM_TIMER_CI_ENABLE; + val64 = readq(&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]); + val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI; + fifo->tim_tti_cfg1_saved = val64; + writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]); + } +} + +void vxge_hw_vpath_dynamic_rti_ci_set(struct __vxge_hw_ring *ring) +{ + u64 val64 = ring->tim_rti_cfg1_saved; + + val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI; + ring->tim_rti_cfg1_saved = val64; + writeq(val64, &ring->vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_RX]); +} + +void vxge_hw_vpath_dynamic_tti_rtimer_set(struct __vxge_hw_fifo *fifo) +{ + u64 val64 = fifo->tim_tti_cfg3_saved; + u64 timer = (fifo->rtimer * 1000) / 272; + + val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(0x3ffffff); + if (timer) + val64 |= VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(timer) | + VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_EVENT_SF(5); + + writeq(val64, &fifo->vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_TX]); + /* tti_cfg3_saved is not updated again because it is + * initialized at one place only - init time. + */ +} + +void vxge_hw_vpath_dynamic_rti_rtimer_set(struct __vxge_hw_ring *ring) +{ + u64 val64 = ring->tim_rti_cfg3_saved; + u64 timer = (ring->rtimer * 1000) / 272; + + val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(0x3ffffff); + if (timer) + val64 |= VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(timer) | + VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_EVENT_SF(4); + + writeq(val64, &ring->vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_RX]); + /* rti_cfg3_saved is not updated again because it is + * initialized at one place only - init time. + */ +} + /** * vxge_hw_channel_msix_mask - Mask MSIX Vector. * @channeh: Channel for rx or tx handle @@ -253,6 +315,23 @@ vxge_hw_channel_msix_unmask(struct __vxge_hw_channel *channel, int msix_id) &channel->common_reg->clear_msix_mask_vect[msix_id%4]); } +/** + * vxge_hw_channel_msix_clear - Unmask the MSIX Vector. + * @channel: Channel for rx or tx handle + * @msix_id: MSI ID + * + * The function unmasks the msix interrupt for the given msix_id + * if configured in MSIX oneshot mode + * + * Returns: 0 + */ +void vxge_hw_channel_msix_clear(struct __vxge_hw_channel *channel, int msix_id) +{ + __vxge_hw_pio_mem_write32_upper( + (u32) vxge_bVALn(vxge_mBIT(msix_id >> 2), 0, 32), + &channel->common_reg->clr_msix_one_shot_vec[msix_id % 4]); +} + /** * vxge_hw_device_set_intr_type - Updates the configuration * with new interrupt type. @@ -2190,20 +2269,15 @@ vxge_hw_vpath_msix_set(struct __vxge_hw_vpath_handle *vp, int *tim_msix_id, if (vpath->hldev->config.intr_mode == VXGE_HW_INTR_MODE_MSIX_ONE_SHOT) { + __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn( + VXGE_HW_ONE_SHOT_VECT0_EN_ONE_SHOT_VECT0_EN, + 0, 32), &vp_reg->one_shot_vect0_en); __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn( VXGE_HW_ONE_SHOT_VECT1_EN_ONE_SHOT_VECT1_EN, 0, 32), &vp_reg->one_shot_vect1_en); - } - - if (vpath->hldev->config.intr_mode == - VXGE_HW_INTR_MODE_MSIX_ONE_SHOT) { __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn( VXGE_HW_ONE_SHOT_VECT2_EN_ONE_SHOT_VECT2_EN, 0, 32), &vp_reg->one_shot_vect2_en); - - __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn( - VXGE_HW_ONE_SHOT_VECT3_EN_ONE_SHOT_VECT3_EN, - 0, 32), &vp_reg->one_shot_vect3_en); } } @@ -2228,6 +2302,32 @@ vxge_hw_vpath_msix_mask(struct __vxge_hw_vpath_handle *vp, int msix_id) &hldev->common_reg->set_msix_mask_vect[msix_id % 4]); } +/** + * vxge_hw_vpath_msix_clear - Clear MSIX Vector. + * @vp: Virtual Path handle. + * @msix_id: MSI ID + * + * The function clears the msix interrupt for the given msix_id + * + * Returns: 0, + * Otherwise, VXGE_HW_ERR_WRONG_IRQ if the msix index is out of range + * status. + * See also: + */ +void vxge_hw_vpath_msix_clear(struct __vxge_hw_vpath_handle *vp, int msix_id) +{ + struct __vxge_hw_device *hldev = vp->vpath->hldev; + + if ((hldev->config.intr_mode == VXGE_HW_INTR_MODE_MSIX_ONE_SHOT)) + __vxge_hw_pio_mem_write32_upper( + (u32) vxge_bVALn(vxge_mBIT((msix_id >> 2)), 0, 32), + &hldev->common_reg->clr_msix_one_shot_vec[msix_id % 4]); + else + __vxge_hw_pio_mem_write32_upper( + (u32) vxge_bVALn(vxge_mBIT((msix_id >> 2)), 0, 32), + &hldev->common_reg->clear_msix_mask_vect[msix_id % 4]); +} + /** * vxge_hw_vpath_msix_unmask - Unmask the MSIX Vector. * @vp: Virtual Path handle. diff --git a/drivers/net/vxge/vxge-traffic.h b/drivers/net/vxge/vxge-traffic.h index d48486d6afa1..9d9dfda4c7ab 100644 --- a/drivers/net/vxge/vxge-traffic.h +++ b/drivers/net/vxge/vxge-traffic.h @@ -2142,6 +2142,10 @@ void vxge_hw_device_clear_tx_rx( * Virtual Paths */ +void vxge_hw_vpath_dynamic_rti_rtimer_set(struct __vxge_hw_ring *ring); + +void vxge_hw_vpath_dynamic_tti_rtimer_set(struct __vxge_hw_fifo *fifo); + u32 vxge_hw_vpath_id( struct __vxge_hw_vpath_handle *vpath_handle); @@ -2245,6 +2249,8 @@ void vxge_hw_vpath_msix_mask(struct __vxge_hw_vpath_handle *vpath_handle, int msix_id); +void vxge_hw_vpath_msix_clear(struct __vxge_hw_vpath_handle *vp, int msix_id); + void vxge_hw_device_flush_io(struct __vxge_hw_device *devh); void @@ -2269,6 +2275,9 @@ vxge_hw_channel_msix_mask(struct __vxge_hw_channel *channelh, int msix_id); void vxge_hw_channel_msix_unmask(struct __vxge_hw_channel *channelh, int msix_id); +void +vxge_hw_channel_msix_clear(struct __vxge_hw_channel *channelh, int msix_id); + void vxge_hw_channel_dtr_try_complete(struct __vxge_hw_channel *channel, void **dtrh); @@ -2282,7 +2291,8 @@ vxge_hw_channel_dtr_free(struct __vxge_hw_channel *channel, void *dtrh); int vxge_hw_channel_dtr_count(struct __vxge_hw_channel *channel); -void -vxge_hw_vpath_tti_ci_set(struct __vxge_hw_device *hldev, u32 vp_id); +void vxge_hw_vpath_tti_ci_set(struct __vxge_hw_fifo *fifo); + +void vxge_hw_vpath_dynamic_rti_ci_set(struct __vxge_hw_ring *ring); #endif -- cgit v1.2.3 From 6997e618910b902081a5123f228aac620faa899b Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Tue, 18 Jan 2011 15:02:22 +0000 Subject: vxge: update driver version Update vxge driver version to 2.5.2 Signed-off-by: Jon Mason Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vxge/vxge-version.h b/drivers/net/vxge/vxge-version.h index ad2f99b9bcf3..581e21525e85 100644 --- a/drivers/net/vxge/vxge-version.h +++ b/drivers/net/vxge/vxge-version.h @@ -16,8 +16,8 @@ #define VXGE_VERSION_MAJOR "2" #define VXGE_VERSION_MINOR "5" -#define VXGE_VERSION_FIX "1" -#define VXGE_VERSION_BUILD "22082" +#define VXGE_VERSION_FIX "2" +#define VXGE_VERSION_BUILD "22259" #define VXGE_VERSION_FOR "k" #define VXGE_FW_VER(maj, min, bld) (((maj) << 16) + ((min) << 8) + (bld)) -- cgit v1.2.3 From 008c7891858498f6eea3802062f118922f46a527 Mon Sep 17 00:00:00 2001 From: Ky Srinivasan Date: Thu, 16 Dec 2010 18:38:28 -0700 Subject: Staging: hv: Rename hv_utils.c to hv_util.c The hv_utils module will be composed of more than one file; rename hv_utils.c to accommodate this without changing the module name. Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Makefile | 1 + drivers/staging/hv/hv_util.c | 315 ++++++++++++++++++++++++++++++++++++++++++ drivers/staging/hv/hv_utils.c | 315 ------------------------------------------ 3 files changed, 316 insertions(+), 315 deletions(-) create mode 100644 drivers/staging/hv/hv_util.c delete mode 100644 drivers/staging/hv/hv_utils.c (limited to 'drivers') diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index acd39bd75b1c..4c14138defb2 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -10,3 +10,4 @@ hv_vmbus-y := vmbus_drv.o osd.o \ hv_storvsc-y := storvsc_drv.o storvsc.o hv_blkvsc-y := blkvsc_drv.o blkvsc.o hv_netvsc-y := netvsc_drv.o netvsc.o rndis_filter.o +hv_utils-y := hv_util.o diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c new file mode 100644 index 000000000000..0074581f20e8 --- /dev/null +++ b/drivers/staging/hv/hv_util.c @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2010, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "logging.h" +#include "osd.h" +#include "vmbus.h" +#include "vmbus_packet_format.h" +#include "vmbus_channel_interface.h" +#include "version_info.h" +#include "channel.h" +#include "vmbus_private.h" +#include "vmbus_api.h" +#include "utils.h" + +static u8 *shut_txf_buf; +static u8 *time_txf_buf; +static u8 *hbeat_txf_buf; + +static void shutdown_onchannelcallback(void *context) +{ + struct vmbus_channel *channel = context; + u32 recvlen; + u64 requestid; + u8 execute_shutdown = false; + + struct shutdown_msg_data *shutdown_msg; + + struct icmsg_hdr *icmsghdrp; + struct icmsg_negotiate *negop = NULL; + + vmbus_recvpacket(channel, shut_txf_buf, + PAGE_SIZE, &recvlen, &requestid); + + if (recvlen > 0) { + DPRINT_DBG(VMBUS, "shutdown packet: len=%d, requestid=%lld", + recvlen, requestid); + + icmsghdrp = (struct icmsg_hdr *)&shut_txf_buf[ + sizeof(struct vmbuspipe_hdr)]; + + if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { + prep_negotiate_resp(icmsghdrp, negop, shut_txf_buf); + } else { + shutdown_msg = + (struct shutdown_msg_data *)&shut_txf_buf[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; + + switch (shutdown_msg->flags) { + case 0: + case 1: + icmsghdrp->status = HV_S_OK; + execute_shutdown = true; + + DPRINT_INFO(VMBUS, "Shutdown request received -" + " gracefull shutdown initiated"); + break; + default: + icmsghdrp->status = HV_E_FAIL; + execute_shutdown = false; + + DPRINT_INFO(VMBUS, "Shutdown request received -" + " Invalid request"); + break; + }; + } + + icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION + | ICMSGHDRFLAG_RESPONSE; + + vmbus_sendpacket(channel, shut_txf_buf, + recvlen, requestid, + VmbusPacketTypeDataInBand, 0); + } + + if (execute_shutdown == true) + orderly_poweroff(false); +} + +/* + * Set guest time to host UTC time. + */ +static inline void do_adj_guesttime(u64 hosttime) +{ + s64 host_tns; + struct timespec host_ts; + + host_tns = (hosttime - WLTIMEDELTA) * 100; + host_ts = ns_to_timespec(host_tns); + + do_settimeofday(&host_ts); +} + +/* + * Synchronize time with host after reboot, restore, etc. + * + * ICTIMESYNCFLAG_SYNC flag bit indicates reboot, restore events of the VM. + * After reboot the flag ICTIMESYNCFLAG_SYNC is included in the first time + * message after the timesync channel is opened. Since the hv_utils module is + * loaded after hv_vmbus, the first message is usually missed. The other + * thing is, systime is automatically set to emulated hardware clock which may + * not be UTC time or in the same time zone. So, to override these effects, we + * use the first 50 time samples for initial system time setting. + */ +static inline void adj_guesttime(u64 hosttime, u8 flags) +{ + static s32 scnt = 50; + + if ((flags & ICTIMESYNCFLAG_SYNC) != 0) { + do_adj_guesttime(hosttime); + return; + } + + if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && scnt > 0) { + scnt--; + do_adj_guesttime(hosttime); + } +} + +/* + * Time Sync Channel message handler. + */ +static void timesync_onchannelcallback(void *context) +{ + struct vmbus_channel *channel = context; + u32 recvlen; + u64 requestid; + struct icmsg_hdr *icmsghdrp; + struct ictimesync_data *timedatap; + + vmbus_recvpacket(channel, time_txf_buf, + PAGE_SIZE, &recvlen, &requestid); + + if (recvlen > 0) { + DPRINT_DBG(VMBUS, "timesync packet: recvlen=%d, requestid=%lld", + recvlen, requestid); + + icmsghdrp = (struct icmsg_hdr *)&time_txf_buf[ + sizeof(struct vmbuspipe_hdr)]; + + if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { + prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf); + } else { + timedatap = (struct ictimesync_data *)&time_txf_buf[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; + adj_guesttime(timedatap->parenttime, timedatap->flags); + } + + icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION + | ICMSGHDRFLAG_RESPONSE; + + vmbus_sendpacket(channel, time_txf_buf, + recvlen, requestid, + VmbusPacketTypeDataInBand, 0); + } +} + +/* + * Heartbeat functionality. + * Every two seconds, Hyper-V send us a heartbeat request message. + * we respond to this message, and Hyper-V knows we are alive. + */ +static void heartbeat_onchannelcallback(void *context) +{ + struct vmbus_channel *channel = context; + u32 recvlen; + u64 requestid; + struct icmsg_hdr *icmsghdrp; + struct heartbeat_msg_data *heartbeat_msg; + + vmbus_recvpacket(channel, hbeat_txf_buf, + PAGE_SIZE, &recvlen, &requestid); + + if (recvlen > 0) { + DPRINT_DBG(VMBUS, "heartbeat packet: len=%d, requestid=%lld", + recvlen, requestid); + + icmsghdrp = (struct icmsg_hdr *)&hbeat_txf_buf[ + sizeof(struct vmbuspipe_hdr)]; + + if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { + prep_negotiate_resp(icmsghdrp, NULL, hbeat_txf_buf); + } else { + heartbeat_msg = + (struct heartbeat_msg_data *)&hbeat_txf_buf[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; + + DPRINT_DBG(VMBUS, "heartbeat seq = %lld", + heartbeat_msg->seq_num); + + heartbeat_msg->seq_num += 1; + } + + icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION + | ICMSGHDRFLAG_RESPONSE; + + vmbus_sendpacket(channel, hbeat_txf_buf, + recvlen, requestid, + VmbusPacketTypeDataInBand, 0); + } +} + +static const struct pci_device_id __initconst +hv_utils_pci_table[] __maybe_unused = { + { PCI_DEVICE(0x1414, 0x5353) }, /* Hyper-V emulated VGA controller */ + { 0 } +}; +MODULE_DEVICE_TABLE(pci, hv_utils_pci_table); + + +static const struct dmi_system_id __initconst +hv_utils_dmi_table[] __maybe_unused = { + { + .ident = "Hyper-V", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), + DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"), + }, + }, + { }, +}; +MODULE_DEVICE_TABLE(dmi, hv_utils_dmi_table); + + +static int __init init_hyperv_utils(void) +{ + printk(KERN_INFO "Registering HyperV Utility Driver\n"); + + if (!dmi_check_system(hv_utils_dmi_table)) + return -ENODEV; + + shut_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + time_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + hbeat_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + + if (!shut_txf_buf || !time_txf_buf || !hbeat_txf_buf) { + printk(KERN_INFO + "Unable to allocate memory for receive buffer\n"); + kfree(shut_txf_buf); + kfree(time_txf_buf); + kfree(hbeat_txf_buf); + return -ENOMEM; + } + + hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback = + &shutdown_onchannelcallback; + hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback; + + hv_cb_utils[HV_TIMESYNC_MSG].channel->onchannel_callback = + ×ync_onchannelcallback; + hv_cb_utils[HV_TIMESYNC_MSG].callback = ×ync_onchannelcallback; + + hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback = + &heartbeat_onchannelcallback; + hv_cb_utils[HV_HEARTBEAT_MSG].callback = &heartbeat_onchannelcallback; + + return 0; +} + +static void exit_hyperv_utils(void) +{ + printk(KERN_INFO "De-Registered HyperV Utility Driver\n"); + + hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback = + &chn_cb_negotiate; + hv_cb_utils[HV_SHUTDOWN_MSG].callback = &chn_cb_negotiate; + + hv_cb_utils[HV_TIMESYNC_MSG].channel->onchannel_callback = + &chn_cb_negotiate; + hv_cb_utils[HV_TIMESYNC_MSG].callback = &chn_cb_negotiate; + + hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback = + &chn_cb_negotiate; + hv_cb_utils[HV_HEARTBEAT_MSG].callback = &chn_cb_negotiate; + + kfree(shut_txf_buf); + kfree(time_txf_buf); + kfree(hbeat_txf_buf); +} + +module_init(init_hyperv_utils); +module_exit(exit_hyperv_utils); + +MODULE_DESCRIPTION("Hyper-V Utilities"); +MODULE_VERSION(HV_DRV_VERSION); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/hv/hv_utils.c b/drivers/staging/hv/hv_utils.c deleted file mode 100644 index 0074581f20e8..000000000000 --- a/drivers/staging/hv/hv_utils.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright (c) 2010, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "logging.h" -#include "osd.h" -#include "vmbus.h" -#include "vmbus_packet_format.h" -#include "vmbus_channel_interface.h" -#include "version_info.h" -#include "channel.h" -#include "vmbus_private.h" -#include "vmbus_api.h" -#include "utils.h" - -static u8 *shut_txf_buf; -static u8 *time_txf_buf; -static u8 *hbeat_txf_buf; - -static void shutdown_onchannelcallback(void *context) -{ - struct vmbus_channel *channel = context; - u32 recvlen; - u64 requestid; - u8 execute_shutdown = false; - - struct shutdown_msg_data *shutdown_msg; - - struct icmsg_hdr *icmsghdrp; - struct icmsg_negotiate *negop = NULL; - - vmbus_recvpacket(channel, shut_txf_buf, - PAGE_SIZE, &recvlen, &requestid); - - if (recvlen > 0) { - DPRINT_DBG(VMBUS, "shutdown packet: len=%d, requestid=%lld", - recvlen, requestid); - - icmsghdrp = (struct icmsg_hdr *)&shut_txf_buf[ - sizeof(struct vmbuspipe_hdr)]; - - if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { - prep_negotiate_resp(icmsghdrp, negop, shut_txf_buf); - } else { - shutdown_msg = - (struct shutdown_msg_data *)&shut_txf_buf[ - sizeof(struct vmbuspipe_hdr) + - sizeof(struct icmsg_hdr)]; - - switch (shutdown_msg->flags) { - case 0: - case 1: - icmsghdrp->status = HV_S_OK; - execute_shutdown = true; - - DPRINT_INFO(VMBUS, "Shutdown request received -" - " gracefull shutdown initiated"); - break; - default: - icmsghdrp->status = HV_E_FAIL; - execute_shutdown = false; - - DPRINT_INFO(VMBUS, "Shutdown request received -" - " Invalid request"); - break; - }; - } - - icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION - | ICMSGHDRFLAG_RESPONSE; - - vmbus_sendpacket(channel, shut_txf_buf, - recvlen, requestid, - VmbusPacketTypeDataInBand, 0); - } - - if (execute_shutdown == true) - orderly_poweroff(false); -} - -/* - * Set guest time to host UTC time. - */ -static inline void do_adj_guesttime(u64 hosttime) -{ - s64 host_tns; - struct timespec host_ts; - - host_tns = (hosttime - WLTIMEDELTA) * 100; - host_ts = ns_to_timespec(host_tns); - - do_settimeofday(&host_ts); -} - -/* - * Synchronize time with host after reboot, restore, etc. - * - * ICTIMESYNCFLAG_SYNC flag bit indicates reboot, restore events of the VM. - * After reboot the flag ICTIMESYNCFLAG_SYNC is included in the first time - * message after the timesync channel is opened. Since the hv_utils module is - * loaded after hv_vmbus, the first message is usually missed. The other - * thing is, systime is automatically set to emulated hardware clock which may - * not be UTC time or in the same time zone. So, to override these effects, we - * use the first 50 time samples for initial system time setting. - */ -static inline void adj_guesttime(u64 hosttime, u8 flags) -{ - static s32 scnt = 50; - - if ((flags & ICTIMESYNCFLAG_SYNC) != 0) { - do_adj_guesttime(hosttime); - return; - } - - if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && scnt > 0) { - scnt--; - do_adj_guesttime(hosttime); - } -} - -/* - * Time Sync Channel message handler. - */ -static void timesync_onchannelcallback(void *context) -{ - struct vmbus_channel *channel = context; - u32 recvlen; - u64 requestid; - struct icmsg_hdr *icmsghdrp; - struct ictimesync_data *timedatap; - - vmbus_recvpacket(channel, time_txf_buf, - PAGE_SIZE, &recvlen, &requestid); - - if (recvlen > 0) { - DPRINT_DBG(VMBUS, "timesync packet: recvlen=%d, requestid=%lld", - recvlen, requestid); - - icmsghdrp = (struct icmsg_hdr *)&time_txf_buf[ - sizeof(struct vmbuspipe_hdr)]; - - if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { - prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf); - } else { - timedatap = (struct ictimesync_data *)&time_txf_buf[ - sizeof(struct vmbuspipe_hdr) + - sizeof(struct icmsg_hdr)]; - adj_guesttime(timedatap->parenttime, timedatap->flags); - } - - icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION - | ICMSGHDRFLAG_RESPONSE; - - vmbus_sendpacket(channel, time_txf_buf, - recvlen, requestid, - VmbusPacketTypeDataInBand, 0); - } -} - -/* - * Heartbeat functionality. - * Every two seconds, Hyper-V send us a heartbeat request message. - * we respond to this message, and Hyper-V knows we are alive. - */ -static void heartbeat_onchannelcallback(void *context) -{ - struct vmbus_channel *channel = context; - u32 recvlen; - u64 requestid; - struct icmsg_hdr *icmsghdrp; - struct heartbeat_msg_data *heartbeat_msg; - - vmbus_recvpacket(channel, hbeat_txf_buf, - PAGE_SIZE, &recvlen, &requestid); - - if (recvlen > 0) { - DPRINT_DBG(VMBUS, "heartbeat packet: len=%d, requestid=%lld", - recvlen, requestid); - - icmsghdrp = (struct icmsg_hdr *)&hbeat_txf_buf[ - sizeof(struct vmbuspipe_hdr)]; - - if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { - prep_negotiate_resp(icmsghdrp, NULL, hbeat_txf_buf); - } else { - heartbeat_msg = - (struct heartbeat_msg_data *)&hbeat_txf_buf[ - sizeof(struct vmbuspipe_hdr) + - sizeof(struct icmsg_hdr)]; - - DPRINT_DBG(VMBUS, "heartbeat seq = %lld", - heartbeat_msg->seq_num); - - heartbeat_msg->seq_num += 1; - } - - icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION - | ICMSGHDRFLAG_RESPONSE; - - vmbus_sendpacket(channel, hbeat_txf_buf, - recvlen, requestid, - VmbusPacketTypeDataInBand, 0); - } -} - -static const struct pci_device_id __initconst -hv_utils_pci_table[] __maybe_unused = { - { PCI_DEVICE(0x1414, 0x5353) }, /* Hyper-V emulated VGA controller */ - { 0 } -}; -MODULE_DEVICE_TABLE(pci, hv_utils_pci_table); - - -static const struct dmi_system_id __initconst -hv_utils_dmi_table[] __maybe_unused = { - { - .ident = "Hyper-V", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), - DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"), - }, - }, - { }, -}; -MODULE_DEVICE_TABLE(dmi, hv_utils_dmi_table); - - -static int __init init_hyperv_utils(void) -{ - printk(KERN_INFO "Registering HyperV Utility Driver\n"); - - if (!dmi_check_system(hv_utils_dmi_table)) - return -ENODEV; - - shut_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); - time_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); - hbeat_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); - - if (!shut_txf_buf || !time_txf_buf || !hbeat_txf_buf) { - printk(KERN_INFO - "Unable to allocate memory for receive buffer\n"); - kfree(shut_txf_buf); - kfree(time_txf_buf); - kfree(hbeat_txf_buf); - return -ENOMEM; - } - - hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback = - &shutdown_onchannelcallback; - hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback; - - hv_cb_utils[HV_TIMESYNC_MSG].channel->onchannel_callback = - ×ync_onchannelcallback; - hv_cb_utils[HV_TIMESYNC_MSG].callback = ×ync_onchannelcallback; - - hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback = - &heartbeat_onchannelcallback; - hv_cb_utils[HV_HEARTBEAT_MSG].callback = &heartbeat_onchannelcallback; - - return 0; -} - -static void exit_hyperv_utils(void) -{ - printk(KERN_INFO "De-Registered HyperV Utility Driver\n"); - - hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback = - &chn_cb_negotiate; - hv_cb_utils[HV_SHUTDOWN_MSG].callback = &chn_cb_negotiate; - - hv_cb_utils[HV_TIMESYNC_MSG].channel->onchannel_callback = - &chn_cb_negotiate; - hv_cb_utils[HV_TIMESYNC_MSG].callback = &chn_cb_negotiate; - - hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback = - &chn_cb_negotiate; - hv_cb_utils[HV_HEARTBEAT_MSG].callback = &chn_cb_negotiate; - - kfree(shut_txf_buf); - kfree(time_txf_buf); - kfree(hbeat_txf_buf); -} - -module_init(init_hyperv_utils); -module_exit(exit_hyperv_utils); - -MODULE_DESCRIPTION("Hyper-V Utilities"); -MODULE_VERSION(HV_DRV_VERSION); -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 245ba56a52a32536a751cc3e60e5602afcfc5fd9 Mon Sep 17 00:00:00 2001 From: Ky Srinivasan Date: Thu, 16 Dec 2010 18:54:16 -0700 Subject: Staging: hv: Implement key/value pair (KVP) This is an implementation of the key value/pair (KVP) functionality for Linux guests hosted on HyperV. This component communicates with the host to support the KVP functionality. Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Makefile | 2 +- drivers/staging/hv/channel_mgmt.c | 23 ++- drivers/staging/hv/hv_kvp.c | 346 ++++++++++++++++++++++++++++++++++++++ drivers/staging/hv/hv_kvp.h | 184 ++++++++++++++++++++ drivers/staging/hv/hv_util.c | 14 ++ drivers/staging/hv/utils.h | 1 + 6 files changed, 567 insertions(+), 3 deletions(-) create mode 100644 drivers/staging/hv/hv_kvp.c create mode 100644 drivers/staging/hv/hv_kvp.h (limited to 'drivers') diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index 4c14138defb2..606ce7daa4ee 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -10,4 +10,4 @@ hv_vmbus-y := vmbus_drv.o osd.o \ hv_storvsc-y := storvsc_drv.o storvsc.o hv_blkvsc-y := blkvsc_drv.o blkvsc.o hv_netvsc-y := netvsc_drv.o netvsc.o rndis_filter.o -hv_utils-y := hv_util.o +hv_utils-y := hv_util.o hv_kvp.o diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index d44d5c39f68b..fb71f88e697d 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -34,8 +34,8 @@ struct vmbus_channel_message_table_entry { void (*messageHandler)(struct vmbus_channel_message_header *msg); }; -#define MAX_MSG_TYPES 3 -#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 7 +#define MAX_MSG_TYPES 4 +#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 8 static const struct hv_guid gSupportedDeviceClasses[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = { @@ -98,6 +98,15 @@ static const struct hv_guid 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d } }, + /* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */ + /* KVP */ + { + .data = { + 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, + 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6 + } + }, + }; @@ -231,6 +240,16 @@ struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = { .callback = chn_cb_negotiate, .log_msg = "Heartbeat channel functionality initialized" }, + /* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */ + /* KVP */ + { + .data = { + 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, + 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6 + }, + .callback = chn_cb_negotiate, + .log_msg = "KVP channel functionality initialized" + }, }; EXPORT_SYMBOL(hv_cb_utils); diff --git a/drivers/staging/hv/hv_kvp.c b/drivers/staging/hv/hv_kvp.c new file mode 100644 index 000000000000..5458631b09cd --- /dev/null +++ b/drivers/staging/hv/hv_kvp.c @@ -0,0 +1,346 @@ +/* + * An implementation of key value pair (KVP) functionality for Linux. + * + * + * Copyright (C) 2010, Novell, Inc. + * Author : K. Y. Srinivasan + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + + +#include +#include +#include +#include + +#include "logging.h" +#include "osd.h" +#include "vmbus.h" +#include "vmbus_packet_format.h" +#include "vmbus_channel_interface.h" +#include "version_info.h" +#include "channel.h" +#include "vmbus_private.h" +#include "vmbus_api.h" +#include "utils.h" +#include "hv_kvp.h" + + + +/* + * Global state maintained for transaction that is being processed. + * Note that only one transaction can be active at any point in time. + * + * This state is set when we receive a request from the host; we + * cleanup this state when the transaction is completed - when we respond + * to the host with the key value. + */ + +static struct { + bool active; /* transaction status - active or not */ + int recv_len; /* number of bytes received. */ + struct vmbus_channel *recv_channel; /* chn we got the request */ + u64 recv_req_id; /* request ID. */ +} kvp_transaction; + +static int kvp_send_key(int index); + +static void kvp_respond_to_host(char *key, char *value, int error); +static void kvp_work_func(struct work_struct *dummy); +static void kvp_register(void); + +static DECLARE_DELAYED_WORK(kvp_work, kvp_work_func); + +static struct cb_id kvp_id = { CN_KVP_IDX, CN_KVP_VAL }; +static const char kvp_name[] = "kvp_kernel_module"; +static int timeout_fired; +static u8 *recv_buffer; +/* + * Register the kernel component with the user-level daemon. + * As part of this registration, pass the LIC version number. + */ + +static void +kvp_register(void) +{ + + struct cn_msg *msg; + + msg = kzalloc(sizeof(*msg) + strlen(HV_DRV_VERSION) + 1 , GFP_ATOMIC); + + if (msg) { + msg->id.idx = CN_KVP_IDX; + msg->id.val = CN_KVP_VAL; + msg->seq = KVP_REGISTER; + strcpy(msg->data, HV_DRV_VERSION); + msg->len = strlen(HV_DRV_VERSION) + 1; + cn_netlink_send(msg, 0, GFP_ATOMIC); + kfree(msg); + } +} +static void +kvp_work_func(struct work_struct *dummy) +{ + /* + * If the timer fires, the user-mode component has not responded; + * process the pending transaction. + */ + kvp_respond_to_host("Unknown key", "Guest timed out", timeout_fired); + timeout_fired = 1; +} + +/* + * Callback when data is received from user mode. + */ + +static void +kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) +{ + struct hv_ku_msg *message; + + message = (struct hv_ku_msg *)msg->data; + if (msg->seq == KVP_REGISTER) { + printk(KERN_INFO "KVP: user-mode registering done.\n"); + kvp_register(); + } + + if (msg->seq == KVP_USER_SET) { + /* + * Complete the transaction by forwarding the key value + * to the host. But first, cancel the timeout. + */ + if (cancel_delayed_work_sync(&kvp_work)) + kvp_respond_to_host(message->kvp_key, + message->kvp_value, + !strlen(message->kvp_key)); + } +} + +static int +kvp_send_key(int index) +{ + struct cn_msg *msg; + + msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg) , GFP_ATOMIC); + + if (msg) { + msg->id.idx = CN_KVP_IDX; + msg->id.val = CN_KVP_VAL; + msg->seq = KVP_KERNEL_GET; + ((struct hv_ku_msg *)msg->data)->kvp_index = index; + msg->len = sizeof(struct hv_ku_msg); + cn_netlink_send(msg, 0, GFP_ATOMIC); + kfree(msg); + return 0; + } + return 1; +} + +/* + * Send a response back to the host. + */ + +static void +kvp_respond_to_host(char *key, char *value, int error) +{ + struct hv_kvp_msg *kvp_msg; + struct hv_kvp_msg_enumerate *kvp_data; + char *key_name; + struct icmsg_hdr *icmsghdrp; + int keylen, valuelen; + u32 buf_len; + struct vmbus_channel *channel; + u64 req_id; + + /* + * If a transaction is not active; log and return. + */ + + if (!kvp_transaction.active) { + /* + * This is a spurious call! + */ + printk(KERN_WARNING "KVP: Transaction not active\n"); + return; + } + /* + * Copy the global state for completing the transaction. Note that + * only one transaction can be active at a time. + */ + + buf_len = kvp_transaction.recv_len; + channel = kvp_transaction.recv_channel; + req_id = kvp_transaction.recv_req_id; + + icmsghdrp = (struct icmsg_hdr *) + &recv_buffer[sizeof(struct vmbuspipe_hdr)]; + kvp_msg = (struct hv_kvp_msg *) + &recv_buffer[sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; + kvp_data = &kvp_msg->kvp_data; + key_name = key; + + /* + * If the error parameter is set, terminate the host's enumeration. + */ + if (error) { + /* + * We don't support this index or the we have timedout; + * terminate the host-side iteration by returning an error. + */ + icmsghdrp->status = HV_E_FAIL; + goto response_done; + } + + /* + * The windows host expects the key/value pair to be encoded + * in utf16. + */ + keylen = utf8s_to_utf16s(key_name, strlen(key_name), + (wchar_t *)kvp_data->data.key); + kvp_data->data.key_size = 2*(keylen + 1); /* utf16 encoding */ + valuelen = utf8s_to_utf16s(value, strlen(value), + (wchar_t *)kvp_data->data.value); + kvp_data->data.value_size = 2*(valuelen + 1); /* utf16 encoding */ + + kvp_data->data.value_type = REG_SZ; /* all our values are strings */ + icmsghdrp->status = HV_S_OK; + +response_done: + icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; + + vmbus_sendpacket(channel, recv_buffer, buf_len, req_id, + VmbusPacketTypeDataInBand, 0); + + kvp_transaction.active = false; +} + +/* + * This callback is invoked when we get a KVP message from the host. + * The host ensures that only one KVP transaction can be active at a time. + * KVP implementation in Linux needs to forward the key to a user-mde + * component to retrive the corresponding value. Consequently, we cannot + * respond to the host in the conext of this callback. Since the host + * guarantees that at most only one transaction can be active at a time, + * we stash away the transaction state in a set of global variables. + */ + +void hv_kvp_onchannelcallback(void *context) +{ + struct vmbus_channel *channel = context; + u32 recvlen; + u64 requestid; + + struct hv_kvp_msg *kvp_msg; + struct hv_kvp_msg_enumerate *kvp_data; + + struct icmsg_hdr *icmsghdrp; + struct icmsg_negotiate *negop = NULL; + + + if (kvp_transaction.active) + return; + + + vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE, &recvlen, &requestid); + + if (recvlen > 0) { + DPRINT_DBG(VMBUS, "KVP packet: len=%d, requestid=%lld", + recvlen, requestid); + + icmsghdrp = (struct icmsg_hdr *)&recv_buffer[ + sizeof(struct vmbuspipe_hdr)]; + + if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { + prep_negotiate_resp(icmsghdrp, negop, recv_buffer); + } else { + kvp_msg = (struct hv_kvp_msg *)&recv_buffer[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; + + kvp_data = &kvp_msg->kvp_data; + + /* + * We only support the "get" operation on + * "KVP_POOL_AUTO" pool. + */ + + if ((kvp_msg->kvp_hdr.pool != KVP_POOL_AUTO) || + (kvp_msg->kvp_hdr.operation != + KVP_OP_ENUMERATE)) { + icmsghdrp->status = HV_E_FAIL; + goto callback_done; + } + + /* + * Stash away this global state for completing the + * transaction; note transactions are serialized. + */ + kvp_transaction.recv_len = recvlen; + kvp_transaction.recv_channel = channel; + kvp_transaction.recv_req_id = requestid; + kvp_transaction.active = true; + + /* + * Get the information from the + * user-mode component. + * component. This transaction will be + * completed when we get the value from + * the user-mode component. + * Set a timeout to deal with + * user-mode not responding. + */ + kvp_send_key(kvp_data->index); + schedule_delayed_work(&kvp_work, 100); + + return; + + } + +callback_done: + + icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION + | ICMSGHDRFLAG_RESPONSE; + + vmbus_sendpacket(channel, recv_buffer, + recvlen, requestid, + VmbusPacketTypeDataInBand, 0); + } + +} + +int +hv_kvp_init(void) +{ + int err; + + err = cn_add_callback(&kvp_id, kvp_name, kvp_cn_callback); + if (err) + return err; + recv_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!recv_buffer) + return -ENOMEM; + + return 0; +} + +void hv_kvp_deinit(void) +{ + cn_del_callback(&kvp_id); + cancel_delayed_work_sync(&kvp_work); + kfree(recv_buffer); +} diff --git a/drivers/staging/hv/hv_kvp.h b/drivers/staging/hv/hv_kvp.h new file mode 100644 index 000000000000..e069f59b5135 --- /dev/null +++ b/drivers/staging/hv/hv_kvp.h @@ -0,0 +1,184 @@ +/* + * An implementation of HyperV key value pair (KVP) functionality for Linux. + * + * + * Copyright (C) 2010, Novell, Inc. + * Author : K. Y. Srinivasan + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#ifndef _KVP_H +#define _KVP_H_ + +/* + * Maximum value size - used for both key names and value data, and includes + * any applicable NULL terminators. + * + * Note: This limit is somewhat arbitrary, but falls easily within what is + * supported for all native guests (back to Win 2000) and what is reasonable + * for the IC KVP exchange functionality. Note that Windows Me/98/95 are + * limited to 255 character key names. + * + * MSDN recommends not storing data values larger than 2048 bytes in the + * registry. + * + * Note: This value is used in defining the KVP exchange message - this value + * cannot be modified without affecting the message size and compatability. + */ + +/* + * bytes, including any null terminators + */ +#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE (2048) + + +/* + * Maximum key size - the registry limit for the length of an entry name + * is 256 characters, including the null terminator + */ + +#define HV_KVP_EXCHANGE_MAX_KEY_SIZE (512) + +/* + * In Linux, we implement the KVP functionality in two components: + * 1) The kernel component which is packaged as part of the hv_utils driver + * is responsible for communicating with the host and responsible for + * implementing the host/guest protocol. 2) A user level daemon that is + * responsible for data gathering. + * + * Host/Guest Protocol: The host iterates over an index and expects the guest + * to assign a key name to the index and also return the value corresponding to + * the key. The host will have atmost one KVP transaction outstanding at any + * given point in time. The host side iteration stops when the guest returns + * an error. Microsoft has specified the following mapping of key names to + * host specified index: + * + * Index Key Name + * 0 FullyQualifiedDomainName + * 1 IntegrationServicesVersion + * 2 NetworkAddressIPv4 + * 3 NetworkAddressIPv6 + * 4 OSBuildNumber + * 5 OSName + * 6 OSMajorVersion + * 7 OSMinorVersion + * 8 OSVersion + * 9 ProcessorArchitecture + * + * The Windows host expects the Key Name and Key Value to be encoded in utf16. + * + * Guest Kernel/KVP Daemon Protocol: As noted earlier, we implement all of the + * data gathering functionality in a user mode daemon. The user level daemon + * is also responsible for binding the key name to the index as well. The + * kernel and user-level daemon communicate using a connector channel. + * + * The user mode component first registers with the + * the kernel component. Subsequently, the kernel component requests, data + * for the specified keys. In response to this message the user mode component + * fills in the value corresponding to the specified key. We overload the + * sequence field in the cn_msg header to define our KVP message types. + * + * + * The kernel component simply acts as a conduit for communication between the + * Windows host and the user-level daemon. The kernel component passes up the + * index received from the Host to the user-level daemon. If the index is + * valid (supported), the corresponding key as well as its + * value (both are strings) is returned. If the index is invalid + * (not supported), a NULL key string is returned. + */ + +/* + * + * The following definitions are shared with the user-mode component; do not + * change any of this without making the corresponding changes in + * the KVP user-mode component. + */ + +#define CN_KVP_VAL 0x1 /* This supports queries from the kernel */ +#define CN_KVP_USER_VAL 0x2 /* This supports queries from the user */ + +enum hv_ku_op { + KVP_REGISTER = 0, /* Register the user mode component */ + KVP_KERNEL_GET, /* Kernel is requesting the value */ + KVP_KERNEL_SET, /* Kernel is providing the value */ + KVP_USER_GET, /* User is requesting the value */ + KVP_USER_SET /* User is providing the value */ +}; + +struct hv_ku_msg { + __u32 kvp_index; /* Key index */ + __u8 kvp_key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; /* Key name */ + __u8 kvp_value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; /* Key value */ +}; + + + + +#ifdef __KERNEL__ + +/* + * Registry value types. + */ + +#define REG_SZ 1 + +enum hv_kvp_exchg_op { + KVP_OP_GET = 0, + KVP_OP_SET, + KVP_OP_DELETE, + KVP_OP_ENUMERATE, + KVP_OP_COUNT /* Number of operations, must be last. */ +}; + +enum hv_kvp_exchg_pool { + KVP_POOL_EXTERNAL = 0, + KVP_POOL_GUEST, + KVP_POOL_AUTO, + KVP_POOL_AUTO_EXTERNAL, + KVP_POOL_AUTO_INTERNAL, + KVP_POOL_COUNT /* Number of pools, must be last. */ +}; + +struct hv_kvp_hdr { + u8 operation; + u8 pool; +}; + +struct hv_kvp_exchg_msg_value { + u32 value_type; + u32 key_size; + u32 value_size; + u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; + u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; +}; + +struct hv_kvp_msg_enumerate { + u32 index; + struct hv_kvp_exchg_msg_value data; +}; + +struct hv_kvp_msg { + struct hv_kvp_hdr kvp_hdr; + struct hv_kvp_msg_enumerate kvp_data; +}; + +int hv_kvp_init(void); +void hv_kvp_deinit(void); +void hv_kvp_onchannelcallback(void *); + +#endif /* __KERNEL__ */ +#endif /* _KVP_H */ + diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c index 0074581f20e8..dea0513eef71 100644 --- a/drivers/staging/hv/hv_util.c +++ b/drivers/staging/hv/hv_util.c @@ -37,6 +37,7 @@ #include "vmbus_private.h" #include "vmbus_api.h" #include "utils.h" +#include "hv_kvp.h" static u8 *shut_txf_buf; static u8 *time_txf_buf; @@ -255,6 +256,10 @@ static int __init init_hyperv_utils(void) { printk(KERN_INFO "Registering HyperV Utility Driver\n"); + if (hv_kvp_init()) + return -ENODEV; + + if (!dmi_check_system(hv_utils_dmi_table)) return -ENODEV; @@ -283,6 +288,11 @@ static int __init init_hyperv_utils(void) &heartbeat_onchannelcallback; hv_cb_utils[HV_HEARTBEAT_MSG].callback = &heartbeat_onchannelcallback; + hv_cb_utils[HV_KVP_MSG].channel->onchannel_callback = + &hv_kvp_onchannelcallback; + + + return 0; } @@ -302,6 +312,10 @@ static void exit_hyperv_utils(void) &chn_cb_negotiate; hv_cb_utils[HV_HEARTBEAT_MSG].callback = &chn_cb_negotiate; + hv_cb_utils[HV_KVP_MSG].channel->onchannel_callback = + &chn_cb_negotiate; + hv_kvp_deinit(); + kfree(shut_txf_buf); kfree(time_txf_buf); kfree(hbeat_txf_buf); diff --git a/drivers/staging/hv/utils.h b/drivers/staging/hv/utils.h index 7c0749999a6f..6d27d15ab525 100644 --- a/drivers/staging/hv/utils.h +++ b/drivers/staging/hv/utils.h @@ -102,6 +102,7 @@ struct ictimesync_data{ #define HV_SHUTDOWN_MSG 0 #define HV_TIMESYNC_MSG 1 #define HV_HEARTBEAT_MSG 2 +#define HV_KVP_MSG 3 struct hyperv_service_callback { u8 msg_type; -- cgit v1.2.3 From cc04acf53fb1bba1e57b0d34a400ccaf498fc9be Mon Sep 17 00:00:00 2001 From: Ky Srinivasan Date: Thu, 16 Dec 2010 18:56:54 -0700 Subject: Staging: hv: Add a user-space daemon to support key/value pair (KVP) All guest specific data gathering is implemented in a user-mode daemon. The kernel component of KVP passes the "key" to this daemon and the daemon is responsible for passing back the corresponding value. This daemon communicates with the kernel component via a netlink channel. Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/tools/hv_kvp_daemon.c | 470 +++++++++++++++++++++++++++++++ 1 file changed, 470 insertions(+) create mode 100644 drivers/staging/hv/tools/hv_kvp_daemon.c (limited to 'drivers') diff --git a/drivers/staging/hv/tools/hv_kvp_daemon.c b/drivers/staging/hv/tools/hv_kvp_daemon.c new file mode 100644 index 000000000000..f5a2dd694611 --- /dev/null +++ b/drivers/staging/hv/tools/hv_kvp_daemon.c @@ -0,0 +1,470 @@ +/* + * An implementation of key value pair (KVP) functionality for Linux. + * + * + * Copyright (C) 2010, Novell, Inc. + * Author : K. Y. Srinivasan + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * KYS: TODO. Need to register these in the kernel. + * + * The following definitions are shared with the in-kernel component; do not + * change any of this without making the corresponding changes in + * the KVP kernel component. + */ +#define CN_KVP_IDX 0x9 /* MSFT KVP functionality */ +#define CN_KVP_VAL 0x1 /* This supports queries from the kernel */ +#define CN_KVP_USER_VAL 0x2 /* This supports queries from the user */ + +/* + * KVP protocol: The user mode component first registers with the + * the kernel component. Subsequently, the kernel component requests, data + * for the specified keys. In response to this message the user mode component + * fills in the value corresponding to the specified key. We overload the + * sequence field in the cn_msg header to define our KVP message types. + * + * We use this infrastructure for also supporting queries from user mode + * application for state that may be maintained in the KVP kernel component. + * + * XXXKYS: Have a shared header file between the user and kernel (TODO) + */ + +enum kvp_op { + KVP_REGISTER = 0, /* Register the user mode component*/ + KVP_KERNEL_GET, /*Kernel is requesting the value for the specified key*/ + KVP_KERNEL_SET, /*Kernel is providing the value for the specified key*/ + KVP_USER_GET, /*User is requesting the value for the specified key*/ + KVP_USER_SET /*User is providing the value for the specified key*/ +}; + +#define HV_KVP_EXCHANGE_MAX_KEY_SIZE 512 +#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE 2048 + +struct hv_ku_msg { + __u32 kvp_index; + __u8 kvp_key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; /* Key name */ + __u8 kvp_value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; /* Key value */ +}; + +enum key_index { + FullyQualifiedDomainName = 0, + IntegrationServicesVersion, /*This key is serviced in the kernel*/ + NetworkAddressIPv4, + NetworkAddressIPv6, + OSBuildNumber, + OSName, + OSMajorVersion, + OSMinorVersion, + OSVersion, + ProcessorArchitecture +}; + +/* + * End of shared definitions. + */ + +static char kvp_send_buffer[4096]; +static char kvp_recv_buffer[4096]; +static struct sockaddr_nl addr; + +static char os_name[100]; +static char os_major[50]; +static char os_minor[50]; +static char processor_arch[50]; +static char os_build[100]; +static char *lic_version; + +void kvp_get_os_info(void) +{ + FILE *file; + char *eol; + struct utsname buf; + + uname(&buf); + strcpy(os_build, buf.release); + strcpy(processor_arch, buf.machine); + + file = fopen("/etc/SuSE-release", "r"); + if (file != NULL) + goto kvp_osinfo_found; + file = fopen("/etc/redhat-release", "r"); + if (file != NULL) + goto kvp_osinfo_found; + /* + * Add code for other supported platforms. + */ + + /* + * We don't have information about the os. + */ + strcpy(os_name, "Linux"); + strcpy(os_major, "0"); + strcpy(os_minor, "0"); + return; + +kvp_osinfo_found: + fgets(os_name, 99, file); + eol = index(os_name, '\n'); + *eol = '\0'; + fgets(os_major, 49, file); + eol = index(os_major, '\n'); + *eol = '\0'; + fgets(os_minor, 49, file); + eol = index(os_minor, '\n'); + *eol = '\0'; + fclose(file); + return; +} + +static int +kvp_get_ip_address(int family, char *buffer, int length) +{ + struct ifaddrs *ifap; + struct ifaddrs *curp; + int ipv4_len = strlen("255.255.255.255") + 1; + int ipv6_len = strlen("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")+1; + int offset = 0; + const char *str; + char tmp[50]; + int error = 0; + + /* + * On entry into this function, the buffer is capable of holding the + * maximum key value (2048 bytes). + */ + + if (getifaddrs(&ifap)) { + strcpy(buffer, "getifaddrs failed\n"); + return 1; + } + + curp = ifap; + while (curp != NULL) { + if ((curp->ifa_addr != NULL) && + (curp->ifa_addr->sa_family == family)) { + if (family == AF_INET) { + struct sockaddr_in *addr = + (struct sockaddr_in *) curp->ifa_addr; + + str = inet_ntop(family, &addr->sin_addr, + tmp, 50); + if (str == NULL) { + strcpy(buffer, "inet_ntop failed\n"); + error = 1; + goto getaddr_done; + } + if (offset == 0) + strcpy(buffer, tmp); + else + strcat(buffer, tmp); + strcat(buffer, ";"); + + offset += strlen(str) + 1; + if ((length - offset) < (ipv4_len + 1)) + goto getaddr_done; + + } else { + + /* + * We only support AF_INET and AF_INET6 + * and the list of addresses is seperated by a ";". + */ + struct sockaddr_in6 *addr = + (struct sockaddr_in6 *) curp->ifa_addr; + + str = inet_ntop(family, + &addr->sin6_addr.s6_addr, + tmp, 50); + if (str == NULL) { + strcpy(buffer, "inet_ntop failed\n"); + error = 1; + goto getaddr_done; + } + if (offset == 0) + strcpy(buffer, tmp); + else + strcat(buffer, tmp); + strcat(buffer, ";"); + offset += strlen(str) + 1; + if ((length - offset) < (ipv6_len + 1)) + goto getaddr_done; + + } + + } + curp = curp->ifa_next; + } + +getaddr_done: + freeifaddrs(ifap); + return error; +} + + +static int +kvp_get_domain_name(char *buffer, int length) +{ + struct addrinfo hints, *info ; + gethostname(buffer, length); + int error = 0; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; /*Get only ipv4 addrinfo. */ + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_CANONNAME; + + error = getaddrinfo(buffer, "http", &hints, &info); + if (error != 0) { + strcpy(buffer, "getaddrinfo failed\n"); + error = 1; + goto get_domain_done; + } + strcpy(buffer, info->ai_canonname); +get_domain_done: + freeaddrinfo(info); + return error; +} + +static int +netlink_send(int fd, struct cn_msg *msg) +{ + struct nlmsghdr *nlh; + unsigned int size; + struct msghdr message; + char buffer[64]; + struct iovec iov[2]; + + size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len); + + nlh = (struct nlmsghdr *)buffer; + nlh->nlmsg_seq = 0; + nlh->nlmsg_pid = getpid(); + nlh->nlmsg_type = NLMSG_DONE; + nlh->nlmsg_len = NLMSG_LENGTH(size - sizeof(*nlh)); + nlh->nlmsg_flags = 0; + + iov[0].iov_base = nlh; + iov[0].iov_len = sizeof(*nlh); + + iov[1].iov_base = msg; + iov[1].iov_len = size; + + memset(&message, 0, sizeof(message)); + message.msg_name = &addr; + message.msg_namelen = sizeof(addr); + message.msg_iov = iov; + message.msg_iovlen = 2; + + return sendmsg(fd, &message, 0); +} + +main(void) +{ + int fd, len, sock_opt; + int error; + struct cn_msg *message; + struct pollfd pfd; + struct nlmsghdr *incoming_msg; + struct cn_msg *incoming_cn_msg; + char *key_value; + char *key_name; + int key_index; + + daemon(1, 0); + openlog("KVP", 0, LOG_USER); + syslog(LOG_INFO, "KVP starting; pid is:%d", getpid()); + /* + * Retrieve OS release information. + */ + kvp_get_os_info(); + + fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR); + if (fd < 0) { + syslog(LOG_ERR, "netlink socket creation failed; error:%d", fd); + exit(-1); + } + addr.nl_family = AF_NETLINK; + addr.nl_pad = 0; + addr.nl_pid = 0; + addr.nl_groups = CN_KVP_IDX; + + + error = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); + if (error < 0) { + syslog(LOG_ERR, "bind failed; error:%d", error); + close(fd); + exit(-1); + } + sock_opt = addr.nl_groups; + setsockopt(fd, 270, 1, &sock_opt, sizeof(sock_opt)); + /* + * Register ourselves with the kernel. + */ + message = (struct cn_msg *)kvp_send_buffer; + message->id.idx = CN_KVP_IDX; + message->id.val = CN_KVP_VAL; + message->seq = KVP_REGISTER; + message->ack = 0; + message->len = 0; + + len = netlink_send(fd, message); + if (len < 0) { + syslog(LOG_ERR, "netlink_send failed; error:%d", len); + close(fd); + exit(-1); + } + + pfd.fd = fd; + + while (1) { + pfd.events = POLLIN; + pfd.revents = 0; + poll(&pfd, 1, -1); + + len = recv(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0); + + if (len < 0) { + syslog(LOG_ERR, "recv failed; error:%d", len); + close(fd); + return -1; + } + + incoming_msg = (struct nlmsghdr *)kvp_recv_buffer; + incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg); + + switch (incoming_cn_msg->seq) { + case KVP_REGISTER: + /* + * Driver is registering with us; stash away the version + * information. + */ + lic_version = malloc(strlen(incoming_cn_msg->data) + 1); + if (lic_version) { + strcpy(lic_version, incoming_cn_msg->data); + syslog(LOG_INFO, "KVP LIC Version: %s", + lic_version); + } else { + syslog(LOG_ERR, "malloc failed"); + } + continue; + + case KVP_KERNEL_GET: + break; + default: + continue; + } + + key_index = + ((struct hv_ku_msg *)incoming_cn_msg->data)->kvp_index; + key_name = + ((struct hv_ku_msg *)incoming_cn_msg->data)->kvp_key; + key_value = + ((struct hv_ku_msg *)incoming_cn_msg->data)->kvp_value; + + switch (key_index) { + case FullyQualifiedDomainName: + kvp_get_domain_name(key_value, + HV_KVP_EXCHANGE_MAX_VALUE_SIZE); + strcpy(key_name, "FullyQualifiedDomainName"); + break; + case IntegrationServicesVersion: + strcpy(key_name, "IntegrationServicesVersion"); + strcpy(key_value, lic_version); + break; + case NetworkAddressIPv4: + kvp_get_ip_address(AF_INET, key_value, + HV_KVP_EXCHANGE_MAX_VALUE_SIZE); + strcpy(key_name, "NetworkAddressIPv4"); + break; + case NetworkAddressIPv6: + kvp_get_ip_address(AF_INET6, key_value, + HV_KVP_EXCHANGE_MAX_VALUE_SIZE); + strcpy(key_name, "NetworkAddressIPv6"); + break; + case OSBuildNumber: + strcpy(key_value, os_build); + strcpy(key_name, "OSBuildNumber"); + break; + case OSName: + strcpy(key_value, os_name); + strcpy(key_name, "OSName"); + break; + case OSMajorVersion: + strcpy(key_value, os_major); + strcpy(key_name, "OSMajorVersion"); + break; + case OSMinorVersion: + strcpy(key_value, os_minor); + strcpy(key_name, "OSMinorVersion"); + break; + case OSVersion: + strcpy(key_value, os_build); + strcpy(key_name, "OSVersion"); + break; + case ProcessorArchitecture: + strcpy(key_value, processor_arch); + strcpy(key_name, "ProcessorArchitecture"); + break; + default: + strcpy(key_value, "Unknown Key"); + /* + * We use a null key name to terminate enumeration. + */ + strcpy(key_name, ""); + break; + } + /* + * Send the value back to the kernel. The response is + * already in the receive buffer. Update the cn_msg header to + * reflect the key value that has been added to the message + */ + + incoming_cn_msg->id.idx = CN_KVP_IDX; + incoming_cn_msg->id.val = CN_KVP_VAL; + incoming_cn_msg->seq = KVP_USER_SET; + incoming_cn_msg->ack = 0; + incoming_cn_msg->len = sizeof(struct hv_ku_msg); + + len = netlink_send(fd, incoming_cn_msg); + if (len < 0) { + syslog(LOG_ERR, "net_link send failed; error:%d", len); + exit(-1); + } + } + +} -- cgit v1.2.3 From 7350968193f9b94c4a4b7d14d7a44333a322c5d7 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 20 Jan 2011 09:32:01 +0100 Subject: staging/hv/osd: don't reimplement ALIGN macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ALIGN_DOWN macro was only used in NUM_PAGES_SPANNED. So make the latter easier and get rid of the former. Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc.c | 2 +- drivers/staging/hv/channel.c | 6 +++--- drivers/staging/hv/hv.c | 4 ++-- drivers/staging/hv/osd.h | 10 +++------- drivers/staging/hv/storvsc.c | 6 +++--- drivers/staging/hv/storvsc_drv.c | 4 ++-- 6 files changed, 14 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/blkvsc.c b/drivers/staging/hv/blkvsc.c index bc16d9172eb2..11a2523a74e3 100644 --- a/drivers/staging/hv/blkvsc.c +++ b/drivers/staging/hv/blkvsc.c @@ -85,7 +85,7 @@ int blk_vsc_initialize(struct hv_driver *driver) */ stor_driver->max_outstanding_req_per_channel = ((stor_driver->ring_buffer_size - PAGE_SIZE) / - ALIGN_UP(MAX_MULTIPAGE_BUFFER_PACKET + + ALIGN(MAX_MULTIPAGE_BUFFER_PACKET + sizeof(struct vstor_packet) + sizeof(u64), sizeof(u64))); diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index 45a627d77b41..69e78568f359 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -726,7 +726,7 @@ int vmbus_sendpacket(struct vmbus_channel *channel, const void *buffer, { struct vmpacket_descriptor desc; u32 packetlen = sizeof(struct vmpacket_descriptor) + bufferlen; - u32 packetlen_aligned = ALIGN_UP(packetlen, sizeof(u64)); + u32 packetlen_aligned = ALIGN(packetlen, sizeof(u64)); struct scatterlist bufferlist[3]; u64 aligned_data = 0; int ret; @@ -793,7 +793,7 @@ int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel, ((MAX_PAGE_BUFFER_COUNT - pagecount) * sizeof(struct hv_page_buffer)); packetlen = descsize + bufferlen; - packetlen_aligned = ALIGN_UP(packetlen, sizeof(u64)); + packetlen_aligned = ALIGN(packetlen, sizeof(u64)); /* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */ @@ -862,7 +862,7 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, ((MAX_MULTIPAGE_BUFFER_COUNT - pfncount) * sizeof(u64)); packetlen = descsize + bufferlen; - packetlen_aligned = ALIGN_UP(packetlen, sizeof(u64)); + packetlen_aligned = ALIGN(packetlen, sizeof(u64)); /* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */ diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c index a34d713d9c57..021acbaae247 100644 --- a/drivers/staging/hv/hv.c +++ b/drivers/staging/hv/hv.c @@ -267,7 +267,7 @@ int hv_init(void) hv_context.signal_event_param = (struct hv_input_signal_event *) - (ALIGN_UP((unsigned long) + (ALIGN((unsigned long) hv_context.signal_event_buffer, HV_HYPERCALL_PARAM_ALIGN)); hv_context.signal_event_param->connectionid.asu32 = 0; @@ -338,7 +338,7 @@ u16 hv_post_message(union hv_connection_id connection_id, return -1; aligned_msg = (struct hv_input_post_message *) - (ALIGN_UP(addr, HV_HYPERCALL_PARAM_ALIGN)); + (ALIGN(addr, HV_HYPERCALL_PARAM_ALIGN)); aligned_msg->connectionid = connection_id; aligned_msg->message_type = message_type; diff --git a/drivers/staging/hv/osd.h b/drivers/staging/hv/osd.h index 870ef0768833..f7871614b983 100644 --- a/drivers/staging/hv/osd.h +++ b/drivers/staging/hv/osd.h @@ -25,16 +25,12 @@ #ifndef _OSD_H_ #define _OSD_H_ +#include #include /* Defines */ -#define ALIGN_UP(value, align) (((value) & (align-1)) ? \ - (((value) + (align-1)) & ~(align-1)) : \ - (value)) -#define ALIGN_DOWN(value, align) ((value) & ~(align-1)) -#define NUM_PAGES_SPANNED(addr, len) ((ALIGN_UP(addr+len, PAGE_SIZE) - \ - ALIGN_DOWN(addr, PAGE_SIZE)) >> \ - PAGE_SHIFT) +#define NUM_PAGES_SPANNED(addr, len) ((PAGE_ALIGN(addr + len) >> PAGE_SHIFT) - \ + (addr >> PAGE_SHIFT)) #define LOWORD(dw) ((unsigned short)(dw)) #define HIWORD(dw) ((unsigned short)(((unsigned int) (dw) >> 16) & 0xFFFF)) diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 9295113e09b9..5680fb06532d 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -437,7 +437,7 @@ static void stor_vsc_on_channel_callback(void *context) struct storvsc_device *stor_device; u32 bytes_recvd; u64 request_id; - unsigned char packet[ALIGN_UP(sizeof(struct vstor_packet), 8)]; + unsigned char packet[ALIGN(sizeof(struct vstor_packet), 8)]; struct storvsc_request_extension *request; int ret; @@ -452,7 +452,7 @@ static void stor_vsc_on_channel_callback(void *context) do { ret = vmbus_recvpacket(device->channel, packet, - ALIGN_UP(sizeof(struct vstor_packet), 8), + ALIGN(sizeof(struct vstor_packet), 8), &bytes_recvd, &request_id); if (ret == 0 && bytes_recvd > 0) { DPRINT_DBG(STORVSC, "receive %d bytes - tid %llx", @@ -802,7 +802,7 @@ int stor_vsc_initialize(struct hv_driver *driver) */ stor_driver->max_outstanding_req_per_channel = ((stor_driver->ring_buffer_size - PAGE_SIZE) / - ALIGN_UP(MAX_MULTIPAGE_BUFFER_PACKET + + ALIGN(MAX_MULTIPAGE_BUFFER_PACKET + sizeof(struct vstor_packet) + sizeof(u64), sizeof(u64))); diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 17f1b344fbc5..7651ca2accc7 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -434,7 +434,7 @@ static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl, struct scatterlist *bounce_sgl; struct page *page_buf; - num_pages = ALIGN_UP(len, PAGE_SIZE) >> PAGE_SHIFT; + num_pages = ALIGN(len, PAGE_SIZE) >> PAGE_SHIFT; bounce_sgl = kcalloc(num_pages, sizeof(struct scatterlist), GFP_ATOMIC); if (!bounce_sgl) @@ -720,7 +720,7 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, } cmd_request->bounce_sgl_count = - ALIGN_UP(scsi_bufflen(scmnd), PAGE_SIZE) >> + ALIGN(scsi_bufflen(scmnd), PAGE_SIZE) >> PAGE_SHIFT; /* -- cgit v1.2.3 From 541f05fea2a943b1ff02b98558498fc2ea2e0a91 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 22 Dec 2010 09:30:09 +0100 Subject: staging: brcm80211: remove usage of ETHER_MAX_LEN definition The linux include file if_ether.h already provides a definition ETH_FRAME_LEN although this is excluding checksum. So code uses ETH_FRAME_LEN+ETH_FCS_LEN now. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Reviewed-by: Dowan Kim Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/bcmcdc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/bcmcdc.h b/drivers/staging/brcm80211/include/bcmcdc.h index 10c1ddcd5e5a..ed1c424fbc63 100644 --- a/drivers/staging/brcm80211/include/bcmcdc.h +++ b/drivers/staging/brcm80211/include/bcmcdc.h @@ -24,7 +24,7 @@ typedef struct cdc_ioctl { } cdc_ioctl_t; /* Max valid buffer size that can be sent to the dongle */ -#define CDC_MAX_MSG_SIZE ETHER_MAX_LEN +#define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN) /* len field is divided into input and output buffer lengths */ #define CDCL_IOC_OUTLEN_MASK 0x0000FFFF /* maximum or expected -- cgit v1.2.3 From c09240ac4b9e2f7de91331dcbaa226424fe0eef4 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 22 Dec 2010 09:30:10 +0100 Subject: staging: brcm80211: move definition of ETHER_TYPE_BRCM to source file The ethertype BRCM is used in single source file and consequently move there. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Reviewed-by: Dowan Kim Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 5 +++-- drivers/staging/brcm80211/include/bcmcdc.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index db4508378775..5d5255fc62a6 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -45,7 +45,8 @@ #include -#define EPI_VERSION_STR "4.218.248.5" +#define EPI_VERSION_STR "4.218.248.5" +#define ETH_P_BRCM 0x886c #if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) #include @@ -1215,7 +1216,7 @@ void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf, skb_pull(skb, ETH_HLEN); /* Process special event packets and then discard them */ - if (ntoh16(skb->protocol) == ETHER_TYPE_BRCM) + if (ntoh16(skb->protocol) == ETH_P_BRCM) dhd_wl_host_event(dhd, &ifidx, skb_mac_header(skb), &event, &data); diff --git a/drivers/staging/brcm80211/include/bcmcdc.h b/drivers/staging/brcm80211/include/bcmcdc.h index ed1c424fbc63..ed4c4a517eca 100644 --- a/drivers/staging/brcm80211/include/bcmcdc.h +++ b/drivers/staging/brcm80211/include/bcmcdc.h @@ -13,7 +13,7 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#include typedef struct cdc_ioctl { u32 cmd; /* ioctl command value */ -- cgit v1.2.3 From e2582ad85a59bc758431db9648627c626ef2e2a7 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 22 Dec 2010 09:30:11 +0100 Subject: staging: brcm80211: remove usage of struct ether_header In linux the is already a structure defined for the ethernet header. Code now uses struct ethhdr instead. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Reviewed-by: Dowan Kim Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_common.c | 2 +- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 12 ++++++------ drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 1 - drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 1 - drivers/staging/brcm80211/brcmfmac/wl_iw.c | 2 -- drivers/staging/brcm80211/include/proto/bcmevent.h | 2 +- drivers/staging/brcm80211/sys/wlc_mac80211.c | 2 +- drivers/staging/brcm80211/util/bcmsrom.c | 1 + 8 files changed, 10 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index 3dbf72eebd4a..4eacdff7bff7 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -868,7 +868,7 @@ wl_host_event(struct dhd_info *dhd, int *ifidx, void *pktdata, if (ifevent->action == WLC_E_IF_ADD) dhd_add_if(dhd, ifevent->ifidx, NULL, event->ifname, - pvt_data->eth.ether_dhost, + pvt_data->eth.h_dest, ifevent->flags, ifevent->bssidx); else diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 5d5255fc62a6..4ef12426718a 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -1031,11 +1031,11 @@ int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf) /* Update multicast statistic */ if (pktbuf->len >= ETH_ALEN) { u8 *pktdata = (u8 *) (pktbuf->data); - struct ether_header *eh = (struct ether_header *)pktdata; + struct ethhdr *eh = (struct ethhdr *)pktdata; - if (is_multicast_ether_addr(eh->ether_dhost)) + if (is_multicast_ether_addr(eh->h_dest)) dhdp->tx_multicast++; - if (ntoh16(eh->ether_type) == ETH_P_PAE) + if (ntoh16(eh->h_proto) == ETH_P_PAE) atomic_inc(&dhd->pend_8021x_cnt); } @@ -1255,13 +1255,13 @@ void dhd_txcomplete(dhd_pub_t *dhdp, struct sk_buff *txp, bool success) { uint ifidx; dhd_info_t *dhd = (dhd_info_t *) (dhdp->info); - struct ether_header *eh; + struct ethhdr *eh; u16 type; dhd_prot_hdrpull(dhdp, &ifidx, txp); - eh = (struct ether_header *)(txp->data); - type = ntoh16(eh->ether_type); + eh = (struct ethhdr *)(txp->data); + type = ntoh16(eh->h_proto); if (type == ETH_P_PAE) atomic_dec(&dhd->pend_8021x_cnt); diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 3edce44978a1..383416d5a750 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -44,7 +44,6 @@ #include #include -#include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 991463f4a7f4..f857d381f5c4 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -20,7 +20,6 @@ #include #include -#include #include diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index db6e68eab290..00700c69a054 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -23,7 +23,6 @@ #include #include -#include #include #include @@ -35,7 +34,6 @@ typedef const struct si_pub si_t; #include -#include #include #include diff --git a/drivers/staging/brcm80211/include/proto/bcmevent.h b/drivers/staging/brcm80211/include/proto/bcmevent.h index 865d15767a00..5796f7563c68 100644 --- a/drivers/staging/brcm80211/include/proto/bcmevent.h +++ b/drivers/staging/brcm80211/include/proto/bcmevent.h @@ -40,7 +40,7 @@ typedef BWL_PRE_PACKED_STRUCT struct { #ifdef BRCM_FULLMAC typedef BWL_PRE_PACKED_STRUCT struct bcm_event { - struct ether_header eth; + struct ethhdr eth; bcmeth_hdr_t bcm_hdr; wl_event_msg_t event; } BWL_POST_PACKED_STRUCT bcm_event_t; diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 1d5d01ac0a9b..9c57573ceaa5 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -1729,7 +1729,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, /* some code depends on packed structures */ ASSERT(sizeof(struct ether_addr) == ETH_ALEN); - ASSERT(sizeof(struct ether_header) == ETH_HLEN); + ASSERT(sizeof(struct ethhdr) == ETH_HLEN); ASSERT(sizeof(d11regs_t) == SI_CORE_SIZE); ASSERT(sizeof(ofdm_phy_hdr_t) == D11_PHY_HDR_LEN); ASSERT(sizeof(cck_phy_hdr_t) == D11_PHY_HDR_LEN); diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index 19d45026a5ee..fc836ee38ed8 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -44,6 +44,7 @@ #include #endif +#include #include /* for sprom content groking */ #define BS_ERROR(args) -- cgit v1.2.3 From 7925465bc50116fd314e3fe7ec080294d187e97e Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 22 Dec 2010 09:30:12 +0100 Subject: staging: brcm80211: cleanup proto/ethernet.h include Most definitions have been removed. Last definitions and the file itself are going to be removed in a later stage. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Reviewed-by: Dowan Kim Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/proto/ethernet.h | 39 ---------------------- 1 file changed, 39 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/proto/ethernet.h b/drivers/staging/brcm80211/include/proto/ethernet.h index 567407de020e..520c4d267e92 100644 --- a/drivers/staging/brcm80211/include/proto/ethernet.h +++ b/drivers/staging/brcm80211/include/proto/ethernet.h @@ -21,52 +21,13 @@ #include -#define ETHER_TYPE_LEN 2 -#define ETHER_CRC_LEN 4 -#define ETHER_MIN_LEN 64 -#define ETHER_MIN_DATA 46 -#define ETHER_MAX_LEN 1518 -#define ETHER_MAX_DATA 1500 - -#define ETHER_TYPE_BRCM 0x886c - -#define ETHER_DEST_OFFSET (0 * ETH_ALEN) -#define ETHER_SRC_OFFSET (1 * ETH_ALEN) -#define ETHER_TYPE_OFFSET (2 * ETH_ALEN) - -#define ETHER_IS_VALID_LEN(foo) \ - ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN) - -#define ETHER_FILL_MCAST_ADDR_FROM_IP(ea, mgrp_ip) { \ - ((u8 *)ea)[0] = 0x01; \ - ((u8 *)ea)[1] = 0x00; \ - ((u8 *)ea)[2] = 0x5e; \ - ((u8 *)ea)[3] = ((mgrp_ip) >> 16) & 0x7f; \ - ((u8 *)ea)[4] = ((mgrp_ip) >> 8) & 0xff; \ - ((u8 *)ea)[5] = ((mgrp_ip) >> 0) & 0xff; \ -} - -BWL_PRE_PACKED_STRUCT struct ether_header { - u8 ether_dhost[ETH_ALEN]; - u8 ether_shost[ETH_ALEN]; - u16 ether_type; -} BWL_POST_PACKED_STRUCT; BWL_PRE_PACKED_STRUCT struct ether_addr { u8 octet[ETH_ALEN]; } BWL_POST_PACKED_STRUCT; -#define ETHER_SET_UNICAST(ea) (((u8 *)(ea))[0] = (((u8 *)(ea))[0] & ~1)) - static const struct ether_addr ether_bcast = { {255, 255, 255, 255, 255, 255} }; -#define ETHER_MOVE_HDR(d, s) \ -do { \ - struct ether_header t; \ - t = *(struct ether_header *)(s); \ - *(struct ether_header *)(d) = t; \ -} while (0) - #include #endif /* _NET_ETHERNET_H_ */ -- cgit v1.2.3 From 35af876454b35b9ed080569e430096d3175302c5 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 22 Dec 2010 09:30:13 +0100 Subject: staging: brcm80211: removed usage of proto/wpa.h file Definitions used either had linux equivalent or were only used in one source file. Changes were made accordingly and proto/wpa.h has been removed from the driver sources. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Reviewed-by: Dowan Kim Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 14 +++++----- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 16 ++++++------ drivers/staging/brcm80211/include/proto/802.11.h | 2 +- drivers/staging/brcm80211/include/proto/wpa.h | 33 ------------------------ drivers/staging/brcm80211/include/wlioctl.h | 3 ++- drivers/staging/brcm80211/sys/wlc_mac80211.c | 10 ++++++- 6 files changed, 27 insertions(+), 51 deletions(-) delete mode 100644 drivers/staging/brcm80211/include/proto/wpa.h (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index f857d381f5c4..e4670641b774 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -2004,8 +2004,8 @@ wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list, WL_DBG("No of elements %d\n", pmk_list->pmkids.npmkid); for (i = 0; i < pmk_list->pmkids.npmkid; i++) { WL_DBG("PMKID[%d]: %pM =\n", i, - &pmk_list->pmkids.pmkid[i].BSSID); - for (j = 0; j < WPA2_PMKID_LEN; j++) { + &pmk_list->pmkids.pmkid[i].BSSID); + for (j = 0; j < WLAN_PMKID_LEN; j++) { WL_DBG("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]); } } @@ -2034,7 +2034,7 @@ wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid, ETH_ALEN); memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid, - WPA2_PMKID_LEN); + WLAN_PMKID_LEN); if (i == wl->pmk_list->pmkids.npmkid) wl->pmk_list->pmkids.npmkid++; } else { @@ -2042,7 +2042,7 @@ wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, } WL_DBG("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n", &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID); - for (i = 0; i < WPA2_PMKID_LEN; i++) { + for (i = 0; i < WLAN_PMKID_LEN; i++) { WL_DBG("%02x\n", wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid]. PMKID[i]); @@ -2064,11 +2064,11 @@ wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, CHECK_SYS_UP(); memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN); - memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN); + memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN); WL_DBG("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n", &pmkid.pmkid[0].BSSID); - for (i = 0; i < WPA2_PMKID_LEN; i++) { + for (i = 0; i < WLAN_PMKID_LEN; i++) { WL_DBG("%02x\n", pmkid.pmkid[0].PMKID[i]); } @@ -2087,7 +2087,7 @@ wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, ETH_ALEN); memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, &wl->pmk_list->pmkids.pmkid[i + 1].PMKID, - WPA2_PMKID_LEN); + WLAN_PMKID_LEN); } wl->pmk_list->pmkids.npmkid--; } else { diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index 00700c69a054..92727cbf0a7c 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -2652,11 +2652,11 @@ wl_iw_set_pmksa(struct net_device *dev, bcopy(&iwpmksa->bssid.sa_data[0], &pmkidptr->pmkid[0].BSSID, ETH_ALEN); bcopy(&iwpmksa->pmkid[0], &pmkidptr->pmkid[0].PMKID, - WPA2_PMKID_LEN); + WLAN_PMKID_LEN); - WL_WSEC("wl_iw_set_pmksa:IW_PMKSA_REMOVE:PMKID: %pM = ", - &pmkidptr->pmkid[0].BSSID); - for (j = 0; j < WPA2_PMKID_LEN; j++) + WL_WSEC("wl_iw_set_pmksa:IW_PMKSA_REMOVE:PMKID: " + "%pM = ", &pmkidptr->pmkid[0].BSSID); + for (j = 0; j < WLAN_PMKID_LEN; j++) WL_WSEC("%02x ", pmkidptr->pmkid[0].PMKID[j]); WL_WSEC("\n"); } @@ -2676,7 +2676,7 @@ wl_iw_set_pmksa(struct net_device *dev, ETH_ALEN); bcopy(&pmkid_list.pmkids.pmkid[i + 1].PMKID, &pmkid_list.pmkids.pmkid[i].PMKID, - WPA2_PMKID_LEN); + WLAN_PMKID_LEN); } pmkid_list.pmkids.npmkid--; } else @@ -2695,7 +2695,7 @@ wl_iw_set_pmksa(struct net_device *dev, ETH_ALEN); bcopy(&iwpmksa->pmkid[0], &pmkid_list.pmkids.pmkid[i].PMKID, - WPA2_PMKID_LEN); + WLAN_PMKID_LEN); if (i == pmkid_list.pmkids.npmkid) pmkid_list.pmkids.npmkid++; } else @@ -2706,7 +2706,7 @@ wl_iw_set_pmksa(struct net_device *dev, k = pmkid_list.pmkids.npmkid; WL_WSEC("wl_iw_set_pmksa,IW_PMKSA_ADD - PMKID: %pM = ", &pmkid_list.pmkids.pmkid[k].BSSID); - for (j = 0; j < WPA2_PMKID_LEN; j++) + for (j = 0; j < WLAN_PMKID_LEN; j++) WL_WSEC("%02x ", pmkid_list.pmkids.pmkid[k].PMKID[j]); WL_WSEC("\n"); @@ -2718,7 +2718,7 @@ wl_iw_set_pmksa(struct net_device *dev, uint j; WL_WSEC("PMKID[%d]: %pM = ", i, &pmkid_list.pmkids.pmkid[i].BSSID); - for (j = 0; j < WPA2_PMKID_LEN; j++) + for (j = 0; j < WLAN_PMKID_LEN; j++) WL_WSEC("%02x ", pmkid_list.pmkids.pmkid[i].PMKID[j]); WL_WSEC("\n"); } diff --git a/drivers/staging/brcm80211/include/proto/802.11.h b/drivers/staging/brcm80211/include/proto/802.11.h index ffde19c5ac5c..d1ee416c1176 100644 --- a/drivers/staging/brcm80211/include/proto/802.11.h +++ b/drivers/staging/brcm80211/include/proto/802.11.h @@ -17,7 +17,7 @@ #ifndef _802_11_H_ #define _802_11_H_ -#include +#include #include #define DOT11_A3_HDR_LEN 24 diff --git a/drivers/staging/brcm80211/include/proto/wpa.h b/drivers/staging/brcm80211/include/proto/wpa.h deleted file mode 100644 index 10c2fb62df09..000000000000 --- a/drivers/staging/brcm80211/include/proto/wpa.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _proto_wpa_h_ -#define _proto_wpa_h_ - -#include - -#define WPA2_PMKID_LEN 16 -#define RSN_CAP_1_REPLAY_CNTR 0 -#define RSN_CAP_2_REPLAY_CNTRS 1 -#define RSN_CAP_4_REPLAY_CNTRS 2 -#define RSN_CAP_16_REPLAY_CNTRS 3 - -#define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS -#define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS -#define WPA_CAP_REPLAY_CNTR_SHIFT RSN_CAP_PTK_REPLAY_CNTR_SHIFT -#define WPA_CAP_REPLAY_CNTR_MASK RSN_CAP_PTK_REPLAY_CNTR_MASK - -#endif /* _proto_wpa_h_ */ diff --git a/drivers/staging/brcm80211/include/wlioctl.h b/drivers/staging/brcm80211/include/wlioctl.h index 9be793c5f10c..f909c12b8ac0 100644 --- a/drivers/staging/brcm80211/include/wlioctl.h +++ b/drivers/staging/brcm80211/include/wlioctl.h @@ -17,6 +17,7 @@ #ifndef _wlioctl_h_ #define _wlioctl_h_ +#include #include #ifdef BRCM_FULLMAC #include @@ -535,7 +536,7 @@ typedef struct { typedef struct _pmkid { struct ether_addr BSSID; - u8 PMKID[WPA2_PMKID_LEN]; + u8 PMKID[WLAN_PMKID_LEN]; } pmkid_t; typedef struct _pmkid_list { diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 9c57573ceaa5..43ee132e09dc 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -55,6 +54,15 @@ #include +/* + * WPA(2) definitions + */ +#define RSN_CAP_4_REPLAY_CNTRS 2 +#define RSN_CAP_16_REPLAY_CNTRS 3 + +#define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS +#define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS + /* * buffer length needed for wlc_format_ssid * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. -- cgit v1.2.3 From 1e6610862c96fbe84534507e58014b50e0a1df5b Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 22 Dec 2010 09:30:14 +0100 Subject: staging: brcm80211: remove usage of packet section macros Removed include construction used to solve compiler differences related to packed structure types. Now GNUC variant of packed structure is used explicitly. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Reviewed-by: Dowan Kim Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/d11.h | 34 +++++++++----------- drivers/staging/brcm80211/include/dhdioctl.h | 7 ----- drivers/staging/brcm80211/include/msgtrace.h | 10 ++---- .../staging/brcm80211/include/packed_section_end.h | 32 ------------------- .../brcm80211/include/packed_section_start.h | 36 ---------------------- drivers/staging/brcm80211/include/proto/802.11.h | 30 +++++++++--------- drivers/staging/brcm80211/include/proto/bcmeth.h | 8 ++--- drivers/staging/brcm80211/include/proto/bcmevent.h | 12 +++----- drivers/staging/brcm80211/include/proto/ethernet.h | 8 ++--- drivers/staging/brcm80211/include/sdiovar.h | 6 ---- drivers/staging/brcm80211/include/wlioctl.h | 7 ----- 11 files changed, 38 insertions(+), 152 deletions(-) delete mode 100644 drivers/staging/brcm80211/include/packed_section_end.h delete mode 100644 drivers/staging/brcm80211/include/packed_section_start.h (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/d11.h b/drivers/staging/brcm80211/include/d11.h index be2d4970407c..631bfe7d366b 100644 --- a/drivers/staging/brcm80211/include/d11.h +++ b/drivers/staging/brcm80211/include/d11.h @@ -17,9 +17,6 @@ #ifndef _D11_H #define _D11_H -/* This marks the start of a packed structure section. */ -#include - #ifndef WL_RSSI_ANT_MAX #define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */ #elif WL_RSSI_ANT_MAX != 4 @@ -625,11 +622,11 @@ typedef volatile struct _d11regs { /* 802.11a PLCP header def */ typedef struct ofdm_phy_hdr ofdm_phy_hdr_t; -BWL_PRE_PACKED_STRUCT struct ofdm_phy_hdr { +struct ofdm_phy_hdr { u8 rlpt[3]; /* rate, length, parity, tail */ u16 service; u8 pad; -} BWL_POST_PACKED_STRUCT; +} __attribute__((packed)); #define D11A_PHY_HDR_GRATE(phdr) ((phdr)->rlpt[0] & 0x0f) #define D11A_PHY_HDR_GRES(phdr) (((phdr)->rlpt[0] >> 4) & 0x01) @@ -660,12 +657,12 @@ BWL_PRE_PACKED_STRUCT struct ofdm_phy_hdr { /* 802.11b PLCP header def */ typedef struct cck_phy_hdr cck_phy_hdr_t; -BWL_PRE_PACKED_STRUCT struct cck_phy_hdr { +struct cck_phy_hdr { u8 signal; u8 service; u16 length; u16 crc; -} BWL_POST_PACKED_STRUCT; +} __attribute__((packed)); #define D11B_PHY_HDR_LEN 6 @@ -706,7 +703,7 @@ BWL_PRE_PACKED_STRUCT struct cck_phy_hdr { /* TX DMA buffer header */ typedef struct d11txh d11txh_t; -BWL_PRE_PACKED_STRUCT struct d11txh { +struct d11txh { u16 MacTxControlLow; /* 0x0 */ u16 MacTxControlHigh; /* 0x1 */ u16 MacFrameControl; /* 0x2 */ @@ -741,7 +738,7 @@ BWL_PRE_PACKED_STRUCT struct d11txh { u8 RTSPhyHeader[D11_PHY_HDR_LEN]; /* 0x2c - 0x2e */ struct dot11_rts_frame rts_frame; /* 0x2f - 0x36 */ u16 PAD; /* 0x37 */ -} BWL_POST_PACKED_STRUCT; +} __attribute__((packed)); #define D11_TXH_LEN 112 /* bytes */ @@ -850,7 +847,7 @@ BWL_PRE_PACKED_STRUCT struct d11txh { /* tx status packet */ typedef struct tx_status tx_status_t; -BWL_PRE_PACKED_STRUCT struct tx_status { +struct tx_status { u16 framelen; u16 PAD; u16 frameid; @@ -859,7 +856,7 @@ BWL_PRE_PACKED_STRUCT struct tx_status { u16 sequence; u16 phyerr; u16 ackphyrxsh; -} BWL_POST_PACKED_STRUCT; +} __attribute__((packed)); #define TXSTATUS_LEN 16 @@ -1243,7 +1240,7 @@ BWL_PRE_PACKED_STRUCT struct tx_status { #define MIMO_ANTSEL_OVERRIDE 0x8000 /* flag */ typedef struct shm_acparams shm_acparams_t; -BWL_PRE_PACKED_STRUCT struct shm_acparams { +struct shm_acparams { u16 txop; u16 cwmin; u16 cwmax; @@ -1253,7 +1250,7 @@ BWL_PRE_PACKED_STRUCT struct shm_acparams { u16 reggap; u16 status; u16 rsvd[8]; -} BWL_POST_PACKED_STRUCT; +} __attribute__((packed)); #define M_EDCF_QLEN (16 * 2) #define WME_STATUS_NEWAC (1 << 8) @@ -1302,7 +1299,7 @@ BWL_PRE_PACKED_STRUCT struct shm_acparams { /* Receive Frame Data Header for 802.11b DCF-only frames */ typedef struct d11rxhdr d11rxhdr_t; -BWL_PRE_PACKED_STRUCT struct d11rxhdr { +struct d11rxhdr { u16 RxFrameSize; /* Actual byte length of the frame data received */ u16 PAD; u16 PhyRxStatus_0; /* PhyRxStatus 15:0 */ @@ -1315,13 +1312,13 @@ BWL_PRE_PACKED_STRUCT struct d11rxhdr { u16 RxStatus2; /* extended MAC Rx status */ u16 RxTSFTime; /* RxTSFTime time of first MAC symbol + M_PHY_PLCPRX_DLY */ u16 RxChan; /* gain code, channel radio code, and phy type */ -} BWL_POST_PACKED_STRUCT; +} __attribute__((packed)); #define RXHDR_LEN 24 /* sizeof d11rxhdr_t */ #define FRAMELEN(h) ((h)->RxFrameSize) typedef struct wlc_d11rxhdr wlc_d11rxhdr_t; -BWL_PRE_PACKED_STRUCT struct wlc_d11rxhdr { +struct wlc_d11rxhdr { d11rxhdr_t rxhdr; u32 tsf_l; /* TSF_L reading */ s8 rssi; /* computed instanteneous rssi in BMAC */ @@ -1329,7 +1326,7 @@ BWL_PRE_PACKED_STRUCT struct wlc_d11rxhdr { s8 rxpwr1; /* obsoleted, place holder for legacy ROM code. use rxpwr[] */ s8 do_rssi_ma; /* do per-pkt sampling for per-antenna ma in HIGH */ s8 rxpwr[WL_RSSI_ANT_MAX]; /* rssi for supported antennas */ -} BWL_POST_PACKED_STRUCT; +} __attribute__((packed)); /* PhyRxStatus_0: */ #define PRXS0_FT_MASK 0x0003 /* NPHY only: CCK, OFDM, preN, N */ @@ -1762,9 +1759,6 @@ typedef struct macstat { #define TST_TXTEST_RATE_11MBPS 3 #define TST_TXTEST_RATE_SHIFT 3 -/* This marks the end of a packed structure section. */ -#include - #define SHM_BYT_CNT 0x2 /* IHR location */ #define MAX_BYT_CNT 0x600 /* Maximum frame len */ diff --git a/drivers/staging/brcm80211/include/dhdioctl.h b/drivers/staging/brcm80211/include/dhdioctl.h index 4d06e506f154..f0ba53558ccd 100644 --- a/drivers/staging/brcm80211/include/dhdioctl.h +++ b/drivers/staging/brcm80211/include/dhdioctl.h @@ -17,10 +17,6 @@ #ifndef _dhdioctl_h_ #define _dhdioctl_h_ -/* require default structure packing */ -#define BWL_DEFAULT_PACKING -#include - /* Linux network driver ioctl encoding */ typedef struct dhd_ioctl { uint cmd; /* common ioctl definition */ @@ -101,7 +97,4 @@ typedef struct dhd_pktgen { #define DHD_IDLE_STOP (-1) /* Request SD clock be stopped (and use SD1 mode) */ -/* require default structure packing */ -#include - #endif /* _dhdioctl_h_ */ diff --git a/drivers/staging/brcm80211/include/msgtrace.h b/drivers/staging/brcm80211/include/msgtrace.h index 9d9e53da088a..d654671a5a30 100644 --- a/drivers/staging/brcm80211/include/msgtrace.h +++ b/drivers/staging/brcm80211/include/msgtrace.h @@ -17,13 +17,10 @@ #ifndef _MSGTRACE_H #define _MSGTRACE_H -/* This marks the start of a packed structure section. */ -#include - #define MSGTRACE_VERSION 1 /* Message trace header */ -typedef BWL_PRE_PACKED_STRUCT struct msgtrace_hdr { +typedef struct msgtrace_hdr { u8 version; u8 spare; u16 len; /* Len of the trace */ @@ -36,7 +33,7 @@ typedef BWL_PRE_PACKED_STRUCT struct msgtrace_hdr { trace overflow */ u32 discarded_printf; /* Number of discarded printf because of trace overflow */ -} BWL_POST_PACKED_STRUCT msgtrace_hdr_t; +} __attribute__((packed)) msgtrace_hdr_t; #define MSGTRACE_HDRLEN sizeof(msgtrace_hdr_t) @@ -61,7 +58,4 @@ extern void msgtrace_put(char *buf, int count); extern void msgtrace_init(void *hdl1, void *hdl2, msgtrace_func_send_t func_send); -/* This marks the end of a packed structure section. */ -#include - #endif /* _MSGTRACE_H */ diff --git a/drivers/staging/brcm80211/include/packed_section_end.h b/drivers/staging/brcm80211/include/packed_section_end.h deleted file mode 100644 index 04c7d43e1286..000000000000 --- a/drivers/staging/brcm80211/include/packed_section_end.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* Error check - BWL_PACKED_SECTION is defined in packed_section_start.h - * and undefined in packed_section_end.h. If it is NOT defined at this - * point, then there is a missing include of packed_section_start.h. - */ -#ifdef BWL_PACKED_SECTION -#undef BWL_PACKED_SECTION -#else -#error "BWL_PACKED_SECTION is NOT defined!" -#endif - -/* Compiler-specific directives for structure packing are declared in - * packed_section_start.h. This marks the end of the structure packing section, - * so, undef them here. - */ -#undef BWL_PRE_PACKED_STRUCT -#undef BWL_POST_PACKED_STRUCT diff --git a/drivers/staging/brcm80211/include/packed_section_start.h b/drivers/staging/brcm80211/include/packed_section_start.h deleted file mode 100644 index 60e862a0c213..000000000000 --- a/drivers/staging/brcm80211/include/packed_section_start.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* Error check - BWL_PACKED_SECTION is defined in packed_section_start.h - * and undefined in packed_section_end.h. If it is already defined at this - * point, then there is a missing include of packed_section_end.h. - */ -#ifdef BWL_PACKED_SECTION -#error "BWL_PACKED_SECTION is already defined!" -#else -#define BWL_PACKED_SECTION -#endif - -/* Declare compiler-specific directives for structure packing. */ -#if defined(__GNUC__) -#define BWL_PRE_PACKED_STRUCT -#define BWL_POST_PACKED_STRUCT __attribute__((packed)) -#elif defined(__CC_ARM) -#define BWL_PRE_PACKED_STRUCT __packed -#define BWL_POST_PACKED_STRUCT -#else -#error "Unknown compiler!" -#endif diff --git a/drivers/staging/brcm80211/include/proto/802.11.h b/drivers/staging/brcm80211/include/proto/802.11.h index d1ee416c1176..57840a0750d2 100644 --- a/drivers/staging/brcm80211/include/proto/802.11.h +++ b/drivers/staging/brcm80211/include/proto/802.11.h @@ -18,7 +18,6 @@ #define _802_11_H_ #include -#include #define DOT11_A3_HDR_LEN 24 #define DOT11_A4_HDR_LEN 30 @@ -45,7 +44,7 @@ #define DOT11_OUI_LEN 3 -BWL_PRE_PACKED_STRUCT struct dot11_header { +struct dot11_header { u16 fc; u16 durid; struct ether_addr a1; @@ -53,14 +52,14 @@ BWL_PRE_PACKED_STRUCT struct dot11_header { struct ether_addr a3; u16 seq; struct ether_addr a4; -} BWL_POST_PACKED_STRUCT; +} __attribute__((packed)); -BWL_PRE_PACKED_STRUCT struct dot11_rts_frame { +struct dot11_rts_frame { u16 fc; u16 durid; struct ether_addr ra; struct ether_addr ta; -} BWL_POST_PACKED_STRUCT; +} __attribute__((packed)); #define DOT11_RTS_LEN 16 #define DOT11_CTS_LEN 10 @@ -69,21 +68,21 @@ BWL_PRE_PACKED_STRUCT struct dot11_rts_frame { #define DOT11_BA_BITMAP_LEN 128 #define DOT11_BA_LEN 4 -BWL_PRE_PACKED_STRUCT struct dot11_management_header { +struct dot11_management_header { u16 fc; u16 durid; struct ether_addr da; struct ether_addr sa; struct ether_addr bssid; u16 seq; -} BWL_POST_PACKED_STRUCT; +} __attribute__((packed)); #define DOT11_MGMT_HDR_LEN 24 -BWL_PRE_PACKED_STRUCT struct dot11_bcn_prb { +struct dot11_bcn_prb { u32 timestamp[2]; u16 beacon_interval; u16 capability; -} BWL_POST_PACKED_STRUCT; +} __attribute__((packed)); #define DOT11_BCN_PRB_LEN 12 #define WME_OUI "\x00\x50\xf2" @@ -102,14 +101,14 @@ typedef u8 ac_bitmap_t; #define AC_BITMAP_ALL 0xf #define AC_BITMAP_TST(ab, ac) (((ab) & (1 << (ac))) != 0) -BWL_PRE_PACKED_STRUCT struct edcf_acparam { +struct edcf_acparam { u8 ACI; u8 ECW; u16 TXOP; -} BWL_POST_PACKED_STRUCT; +} __attribute__((packed)); typedef struct edcf_acparam edcf_acparam_t; -BWL_PRE_PACKED_STRUCT struct wme_param_ie { +struct wme_param_ie { u8 oui[3]; u8 type; u8 subtype; @@ -117,7 +116,7 @@ BWL_PRE_PACKED_STRUCT struct wme_param_ie { u8 qosinfo; u8 rsvd; edcf_acparam_t acparam[AC_COUNT]; -} BWL_POST_PACKED_STRUCT; +} __attribute__((packed)); typedef struct wme_param_ie wme_param_ie_t; #define WME_PARAM_IE_LEN 24 @@ -253,14 +252,14 @@ typedef struct d11cnt { #define MCSSET_LEN 16 -BWL_PRE_PACKED_STRUCT struct ht_cap_ie { +struct ht_cap_ie { u16 cap; u8 params; u8 supp_mcs[MCSSET_LEN]; u16 ext_htcap; u32 txbf_cap; u8 as_cap; -} BWL_POST_PACKED_STRUCT; +} __attribute__((packed)); typedef struct ht_cap_ie ht_cap_ie_t; #define HT_CAP_IE_LEN 26 @@ -317,6 +316,5 @@ typedef struct ht_cap_ie ht_cap_ie_t; #define AES_KEY_SIZE 16 #define BRCM_OUI "\x00\x10\x18" -#include #endif /* _802_11_H_ */ diff --git a/drivers/staging/brcm80211/include/proto/bcmeth.h b/drivers/staging/brcm80211/include/proto/bcmeth.h index f7d3d8dfd3ae..e98ee654458d 100644 --- a/drivers/staging/brcm80211/include/proto/bcmeth.h +++ b/drivers/staging/brcm80211/include/proto/bcmeth.h @@ -17,8 +17,6 @@ #ifndef _BCMETH_H_ #define _BCMETH_H_ -#include - #define BCMILCP_SUBTYPE_RATE 1 #define BCMILCP_SUBTYPE_LINK 2 #define BCMILCP_SUBTYPE_CSA 3 @@ -35,14 +33,12 @@ #define BCMILCP_BCM_SUBTYPEHDR_MINLENGTH 8 #define BCMILCP_BCM_SUBTYPEHDR_VERSION 0 -typedef BWL_PRE_PACKED_STRUCT struct bcmeth_hdr { +typedef struct bcmeth_hdr { u16 subtype; u16 length; u8 version; u8 oui[3]; u16 usr_subtype; -} BWL_POST_PACKED_STRUCT bcmeth_hdr_t; - -#include +} __attribute__((packed)) bcmeth_hdr_t; #endif /* _BCMETH_H_ */ diff --git a/drivers/staging/brcm80211/include/proto/bcmevent.h b/drivers/staging/brcm80211/include/proto/bcmevent.h index 5796f7563c68..2f0d471dede0 100644 --- a/drivers/staging/brcm80211/include/proto/bcmevent.h +++ b/drivers/staging/brcm80211/include/proto/bcmevent.h @@ -17,8 +17,6 @@ #ifndef _BCMEVENT_H_ #define _BCMEVENT_H_ -#include - #define BCM_EVENT_MSG_VERSION 1 #define BCM_MSG_IFNAME_MAX 16 @@ -26,7 +24,7 @@ #define WLC_EVENT_MSG_FLUSHTXQ 0x02 #define WLC_EVENT_MSG_GROUP 0x04 -typedef BWL_PRE_PACKED_STRUCT struct { +typedef struct { u16 version; u16 flags; u32 event_type; @@ -36,14 +34,14 @@ typedef BWL_PRE_PACKED_STRUCT struct { u32 datalen; struct ether_addr addr; char ifname[BCM_MSG_IFNAME_MAX]; -} BWL_POST_PACKED_STRUCT wl_event_msg_t; +} __attribute__((packed)) wl_event_msg_t; #ifdef BRCM_FULLMAC -typedef BWL_PRE_PACKED_STRUCT struct bcm_event { +typedef struct bcm_event { struct ethhdr eth; bcmeth_hdr_t bcm_hdr; wl_event_msg_t event; -} BWL_POST_PACKED_STRUCT bcm_event_t; +} __attribute__((packed)) bcm_event_t; #endif #define BCM_MSG_LEN (sizeof(bcm_event_t) - sizeof(bcmeth_hdr_t) - \ sizeof(struct ether_header)) @@ -212,6 +210,4 @@ typedef struct wl_event_data_if { #define WLC_E_LINK_ASSOC_REC 3 #define WLC_E_LINK_BSSCFG_DIS 4 -#include - #endif /* _BCMEVENT_H_ */ diff --git a/drivers/staging/brcm80211/include/proto/ethernet.h b/drivers/staging/brcm80211/include/proto/ethernet.h index 520c4d267e92..0860219ed9dd 100644 --- a/drivers/staging/brcm80211/include/proto/ethernet.h +++ b/drivers/staging/brcm80211/include/proto/ethernet.h @@ -19,15 +19,11 @@ #include -#include - -BWL_PRE_PACKED_STRUCT struct ether_addr { +struct ether_addr { u8 octet[ETH_ALEN]; -} BWL_POST_PACKED_STRUCT; +} __attribute__((packed)); static const struct ether_addr ether_bcast = { {255, 255, 255, 255, 255, 255} }; -#include - #endif /* _NET_ETHERNET_H_ */ diff --git a/drivers/staging/brcm80211/include/sdiovar.h b/drivers/staging/brcm80211/include/sdiovar.h index 7686fde03960..d1cfa5f0a982 100644 --- a/drivers/staging/brcm80211/include/sdiovar.h +++ b/drivers/staging/brcm80211/include/sdiovar.h @@ -17,10 +17,6 @@ #ifndef _sdiovar_h_ #define _sdiovar_h_ -/* require default structure packing */ -#define BWL_DEFAULT_PACKING -#include - typedef struct sdreg { int func; int offset; @@ -39,6 +35,4 @@ typedef struct sdreg { #define NUM_PREV_TRANSACTIONS 16 -#include - #endif /* _sdiovar_h_ */ diff --git a/drivers/staging/brcm80211/include/wlioctl.h b/drivers/staging/brcm80211/include/wlioctl.h index f909c12b8ac0..69cb541534fb 100644 --- a/drivers/staging/brcm80211/include/wlioctl.h +++ b/drivers/staging/brcm80211/include/wlioctl.h @@ -30,10 +30,6 @@ #define INTF_NAME_SIZ 16 #endif -/* require default structure packing */ -#define BWL_DEFAULT_PACKING -#include - #ifdef BRCM_FULLMAC #define WL_BSS_INFO_VERSION 108 /* current ver of wl_bss_info struct */ @@ -1669,9 +1665,6 @@ typedef struct wl_pkt_filter_enable { #define WLC_RSSI_INVALID 0 /* invalid RSSI value */ -/* require default structure packing */ -#include - /* n-mode support capability */ /* 2x2 includes both 1x1 & 2x2 devices * reserved #define 2 for future when we want to separate 1x1 & 2x2 and -- cgit v1.2.3 From a44d42367fe73e7720d309c4bde5ac79a6cd64a7 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 22 Dec 2010 09:30:15 +0100 Subject: staging: brcm80211: last nail into proto/ethernet.h cleaned up last artifacts used from proto/ethernet.h and subsequently the file can be removed. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Reviewed-by: Dowan Kim Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd.h | 4 +- drivers/staging/brcm80211/brcmfmac/dhd_cdc.c | 2 +- drivers/staging/brcm80211/brcmfmac/dhd_common.c | 8 ++-- .../staging/brcm80211/brcmfmac/dhd_custom_gpio.c | 4 +- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 11 +++--- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 5 ++- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h | 3 +- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 11 ++++-- drivers/staging/brcm80211/brcmfmac/wl_iw.h | 3 +- drivers/staging/brcm80211/include/bcmutils.h | 9 +---- drivers/staging/brcm80211/include/proto/802.11.h | 20 +++++----- drivers/staging/brcm80211/include/proto/bcmevent.h | 4 +- drivers/staging/brcm80211/include/proto/ethernet.h | 29 -------------- drivers/staging/brcm80211/include/wlioctl.h | 23 ++++++----- drivers/staging/brcm80211/sys/wl_mac80211.c | 2 +- drivers/staging/brcm80211/sys/wlc_alloc.c | 4 +- drivers/staging/brcm80211/sys/wlc_ampdu.c | 2 +- drivers/staging/brcm80211/sys/wlc_bmac.c | 37 +++++++++--------- drivers/staging/brcm80211/sys/wlc_bmac.h | 8 ++-- drivers/staging/brcm80211/sys/wlc_bsscfg.h | 4 +- drivers/staging/brcm80211/sys/wlc_key.h | 2 +- drivers/staging/brcm80211/sys/wlc_mac80211.c | 44 +++++++++++----------- drivers/staging/brcm80211/sys/wlc_mac80211.h | 10 ++--- drivers/staging/brcm80211/sys/wlc_pub.h | 8 ++-- drivers/staging/brcm80211/sys/wlc_scb.h | 2 +- drivers/staging/brcm80211/util/bcmsrom.c | 17 ++++----- drivers/staging/brcm80211/util/bcmutils.c | 5 +-- 27 files changed, 122 insertions(+), 159 deletions(-) delete mode 100644 drivers/staging/brcm80211/include/proto/ethernet.h (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd.h b/drivers/staging/brcm80211/brcmfmac/dhd.h index 69c6a0272812..e5cdd619bdc1 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd.h @@ -95,8 +95,8 @@ typedef struct dhd_pub { /* Dongle media info */ bool iswl; /* Dongle-resident driver is wl */ unsigned long drv_version; /* Version of dongle-resident driver */ - struct ether_addr mac; /* MAC address obtained from dongle */ - dngl_stats_t dstats; /* Stats for dongle-based data */ + u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */ + dngl_stats_t dstats; /* Stats for dongle-based data */ /* Additional stats for the bus level */ unsigned long tx_packets; /* Data packets sent to dongle */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c index b7b527f5024c..e491da071a74 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c @@ -477,7 +477,7 @@ int dhd_prot_init(dhd_pub_t *dhd) dhd_os_proto_unblock(dhd); return ret; } - memcpy(dhd->mac.octet, buf, ETH_ALEN); + memcpy(dhd->mac, buf, ETH_ALEN); dhd_os_proto_unblock(dhd); diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index 4eacdff7bff7..1799ee68d097 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -599,7 +599,7 @@ static void wl_show_host_event(wl_event_msg_t *event, void *event_data) auth_type = ntoh32(event->auth_type); datalen = ntoh32(event->datalen); /* debug dump of event messages */ - sprintf(eabuf, "%pM", event->addr.octet); + sprintf(eabuf, "%pM", event->addr); event_name = "UNKNOWN"; for (i = 0; i < ARRAY_SIZE(event_names); i++) { @@ -1242,7 +1242,7 @@ int dhd_preinit_ioctls(dhd_pub_t *dhd) int scan_unassoc_time = 40; #ifdef GET_CUSTOM_MAC_ENABLE int ret = 0; - struct ether_addr ea_addr; + u8 ea_addr[ETH_ALEN]; #endif /* GET_CUSTOM_MAC_ENABLE */ dhd_os_proto_block(dhd); @@ -1254,9 +1254,9 @@ int dhd_preinit_ioctls(dhd_pub_t *dhd) ** firmware but unique per board mac address maybe provided by ** customer code */ - ret = dhd_custom_get_mac_address(ea_addr.octet); + ret = dhd_custom_get_mac_address(ea_addr); if (!ret) { - bcm_mkiovar("cur_etheraddr", (void *)&ea_addr, ETH_ALEN, + bcm_mkiovar("cur_etheraddr", (void *)ea_addr, ETH_ALEN, buf, sizeof(buf)); ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, sizeof(buf)); if (ret < 0) { diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c b/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c index c3f18bb3b27c..2cd80114d385 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c @@ -149,9 +149,9 @@ int dhd_custom_get_mac_address(unsigned char *buf) #ifdef EXAMPLE_GET_MAC /* EXAMPLE code */ { - struct ether_addr ea_example = { + u8 ea_example[ETH_ALEN] = { {0x00, 0x11, 0x22, 0x33, 0x44, 0xFF} }; - bcopy((char *)&ea_example, buf, sizeof(struct ether_addr)); + bcopy((char *)ea_example, buf, ETH_ALEN); } #endif /* EXAMPLE_GET_MAC */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 4ef12426718a..508daaa731ca 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -36,7 +36,6 @@ #include #include -#include #include #include #include @@ -248,7 +247,7 @@ typedef struct dhd_info { struct semaphore sysioc_sem; bool set_multicast; bool set_macaddress; - struct ether_addr macvalue; + u8 macvalue[ETH_ALEN]; wait_queue_head_t ctrl_wait; atomic_t pend_8021x_cnt; @@ -804,7 +803,7 @@ static void _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) } static int -_dhd_set_mac_address(dhd_info_t *dhd, int ifidx, struct ether_addr *addr) +_dhd_set_mac_address(dhd_info_t *dhd, int ifidx, u8 *addr) { char buf[32]; wl_ioctl_t ioc; @@ -977,7 +976,7 @@ static int _dhd_sysioc_thread(void *data) if (dhd->set_macaddress) { dhd->set_macaddress = false; _dhd_set_mac_address(dhd, i, - &dhd->macvalue); + dhd->macvalue); } } } @@ -1867,7 +1866,7 @@ static int dhd_open(struct net_device *net) } atomic_set(&dhd->pend_8021x_cnt, 0); - memcpy(net->dev_addr, dhd->pub.mac.octet, ETH_ALEN); + memcpy(net->dev_addr, dhd->pub.mac, ETH_ALEN); #ifdef TOE /* Get current TOE mode from dongle */ @@ -2300,7 +2299,7 @@ int dhd_net_attach(dhd_pub_t *dhdp, int ifidx) */ if (ifidx != 0) { /* for virtual interfaces use the primary MAC */ - memcpy(temp_addr, dhd->pub.mac.octet, ETH_ALEN); + memcpy(temp_addr, dhd->pub.mac, ETH_ALEN); } diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index e4670641b774..55b9ceee4200 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -43,6 +43,7 @@ static struct sdio_func *cfg80211_sdio_func; static struct wl_dev *wl_cfg80211_dev; +static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; u32 wl_dbg_level = WL_DBG_ERR | WL_DBG_INFO; @@ -647,7 +648,7 @@ wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid) { - memcpy(¶ms->bssid, ðer_bcast, ETH_ALEN); + memcpy(params->bssid, ether_bcast, ETH_ALEN); params->bss_type = DOT11_BSSTYPE_ANY; params->scan_type = 0; params->nprobes = -1; @@ -1372,7 +1373,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len); join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len); wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID); - memcpy(&join_params.params.bssid, ðer_bcast, ETH_ALEN); + memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN); wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size); WL_DBG("join_param_size %d\n", join_params_size); diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h index 482691be210a..b7e2e59b82df 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h @@ -20,7 +20,6 @@ #include #include #include -#include #include struct wl_conf; @@ -316,7 +315,7 @@ struct wl_priv { cfg80211 layer */ struct wl_ie ie; /* information element object for internal purpose */ - struct ether_addr bssid; /* bssid of currently engaged network */ + u8 bssid[ETH_ALEN]; /* bssid of currently engaged network */ struct semaphore event_sync; /* for synchronization of main event thread */ struct wl_profile *profile; /* holding dongle profile */ diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index 92727cbf0a7c..eed40fa36f81 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -135,6 +135,9 @@ typedef struct iscan_info { int iscan_ex_param_size; } iscan_info_t; iscan_info_t *g_iscan; + +static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; + static void wl_iw_timerfunc(unsigned long data); static void wl_iw_set_event_mask(struct net_device *dev); static int wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, u16 action); @@ -688,7 +691,7 @@ wl_iw_set_spy(struct net_device *dev, iw->spy_num = min_t(int, ARRAY_SIZE(iw->spy_addr), dwrq->length); for (i = 0; i < iw->spy_num; i++) - memcpy(&iw->spy_addr[i], addr[i].sa_data, ETH_ALEN); + memcpy(iw->spy_addr[i], addr[i].sa_data, ETH_ALEN); memset(iw->spy_qual, 0, sizeof(iw->spy_qual)); return 0; @@ -710,7 +713,7 @@ wl_iw_get_spy(struct net_device *dev, dwrq->length = iw->spy_num; for (i = 0; i < iw->spy_num; i++) { - memcpy(addr[i].sa_data, &iw->spy_addr[i], ETH_ALEN); + memcpy(addr[i].sa_data, iw->spy_addr[i], ETH_ALEN); addr[i].sa_family = AF_UNIX; memcpy(&qual[i], &iw->spy_qual[i], sizeof(struct iw_quality)); iw->spy_qual[i].updated = 0; @@ -1013,7 +1016,7 @@ static int wl_iw_iscan_prep(wl_scan_params_t *params, wlc_ssid_t *ssid) { int err = 0; - memcpy(¶ms->bssid, ðer_bcast, ETH_ALEN); + memcpy(params->bssid, ether_bcast, ETH_ALEN); params->bss_type = DOT11_BSSTYPE_ANY; params->scan_type = 0; params->nprobes = -1; @@ -1917,7 +1920,7 @@ wl_iw_set_essid(struct net_device *dev, memcpy(&join_params.ssid.SSID, g_ssid.SSID, g_ssid.SSID_len); join_params.ssid.SSID_len = htod32(g_ssid.SSID_len); - memcpy(&join_params.params.bssid, ðer_bcast, ETH_ALEN); + memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN); wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, &join_params, &join_params_size); diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.h b/drivers/staging/brcm80211/brcmfmac/wl_iw.h index c8637c50dc17..08e11fba5248 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.h +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.h @@ -19,7 +19,6 @@ #include -#include #include #define WL_SCAN_PARAMS_SSID_MAX 10 @@ -92,7 +91,7 @@ typedef struct wl_iw { u32 gwsec; bool privacy_invoked; - struct ether_addr spy_addr[IW_MAX_SPY]; + u8 spy_addr[IW_MAX_SPY][ETH_ALEN]; struct iw_quality spy_qual[IW_MAX_SPY]; void *wlinfo; dhd_pub_t *pub; diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h index a8f76d8199ff..a871acd2fd49 100644 --- a/drivers/staging/brcm80211/include/bcmutils.h +++ b/drivers/staging/brcm80211/include/bcmutils.h @@ -86,13 +86,6 @@ /* fn(pkt, arg). return true if pkt belongs to if */ typedef bool(*ifpkt_cb_t) (void *, int); -/* forward definition of ether_addr structure used by some function prototypes */ - - struct ether_addr; - - extern int ether_isbcast(const void *ea); - extern int ether_isnulladdr(const void *ea); - /* operations on a specific precedence in packet queue */ #define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max)) @@ -157,7 +150,7 @@ extern struct sk_buff *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); extern uint pkttotlen(struct osl_info *osh, struct sk_buff *p); /* ethernet address */ - extern int bcm_ether_atoe(char *p, struct ether_addr *ea); + extern int bcm_ether_atoe(char *p, u8 *ea); /* ip address */ struct ipv4_addr; diff --git a/drivers/staging/brcm80211/include/proto/802.11.h b/drivers/staging/brcm80211/include/proto/802.11.h index 57840a0750d2..7595bc7a1a7a 100644 --- a/drivers/staging/brcm80211/include/proto/802.11.h +++ b/drivers/staging/brcm80211/include/proto/802.11.h @@ -17,7 +17,7 @@ #ifndef _802_11_H_ #define _802_11_H_ -#include +#include #define DOT11_A3_HDR_LEN 24 #define DOT11_A4_HDR_LEN 30 @@ -47,18 +47,18 @@ struct dot11_header { u16 fc; u16 durid; - struct ether_addr a1; - struct ether_addr a2; - struct ether_addr a3; + u8 a1[ETH_ALEN]; + u8 a2[ETH_ALEN]; + u8 a3[ETH_ALEN]; u16 seq; - struct ether_addr a4; + u8 a4[ETH_ALEN]; } __attribute__((packed)); struct dot11_rts_frame { u16 fc; u16 durid; - struct ether_addr ra; - struct ether_addr ta; + u8 ra[ETH_ALEN]; + u8 ta[ETH_ALEN]; } __attribute__((packed)); #define DOT11_RTS_LEN 16 @@ -71,9 +71,9 @@ struct dot11_rts_frame { struct dot11_management_header { u16 fc; u16 durid; - struct ether_addr da; - struct ether_addr sa; - struct ether_addr bssid; + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u8 bssid[ETH_ALEN]; u16 seq; } __attribute__((packed)); #define DOT11_MGMT_HDR_LEN 24 diff --git a/drivers/staging/brcm80211/include/proto/bcmevent.h b/drivers/staging/brcm80211/include/proto/bcmevent.h index 2f0d471dede0..f020e3fbcb33 100644 --- a/drivers/staging/brcm80211/include/proto/bcmevent.h +++ b/drivers/staging/brcm80211/include/proto/bcmevent.h @@ -17,6 +17,8 @@ #ifndef _BCMEVENT_H_ #define _BCMEVENT_H_ +#include + #define BCM_EVENT_MSG_VERSION 1 #define BCM_MSG_IFNAME_MAX 16 @@ -32,7 +34,7 @@ typedef struct { u32 reason; u32 auth_type; u32 datalen; - struct ether_addr addr; + u8 addr[ETH_ALEN]; char ifname[BCM_MSG_IFNAME_MAX]; } __attribute__((packed)) wl_event_msg_t; diff --git a/drivers/staging/brcm80211/include/proto/ethernet.h b/drivers/staging/brcm80211/include/proto/ethernet.h deleted file mode 100644 index 0860219ed9dd..000000000000 --- a/drivers/staging/brcm80211/include/proto/ethernet.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _NET_ETHERNET_H_ -#define _NET_ETHERNET_H_ - -#include - - -struct ether_addr { - u8 octet[ETH_ALEN]; -} __attribute__((packed)); - -static const struct ether_addr ether_bcast = { {255, 255, 255, 255, 255, 255} }; - -#endif /* _NET_ETHERNET_H_ */ diff --git a/drivers/staging/brcm80211/include/wlioctl.h b/drivers/staging/brcm80211/include/wlioctl.h index 69cb541534fb..0f79863d08af 100644 --- a/drivers/staging/brcm80211/include/wlioctl.h +++ b/drivers/staging/brcm80211/include/wlioctl.h @@ -18,7 +18,6 @@ #define _wlioctl_h_ #include -#include #ifdef BRCM_FULLMAC #include #endif @@ -43,7 +42,7 @@ typedef struct wl_bss_info { u32 length; /* byte length of data in this record, * starting at version and including IEs */ - struct ether_addr BSSID; + u8 BSSID[ETH_ALEN]; u16 beacon_period; /* units are Kusec */ u16 capability; /* Capability information */ u8 SSID_len; @@ -125,7 +124,7 @@ typedef struct wl_extdscan_params { typedef struct wl_scan_params { wlc_ssid_t ssid; /* default: {0, ""} */ - struct ether_addr bssid; /* default: bcast */ + u8 bssid[ETH_ALEN]; /* default: bcast */ s8 bss_type; /* default: any, * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT */ @@ -231,8 +230,8 @@ typedef struct wl_iscan_results { typedef struct wl_probe_params { wlc_ssid_t ssid; - struct ether_addr bssid; - struct ether_addr mac; + u8 bssid[ETH_ALEN]; + u8 mac[ETH_ALEN]; } wl_probe_params_t; #endif /* BRCM_FULLMAC */ @@ -259,7 +258,7 @@ typedef struct wl_u32_list { /* used for association with a specific BSSID and chanspec list */ typedef struct wl_assoc_params { - struct ether_addr bssid; /* 00:00:00:00:00:00: broadcast scan */ + u8 bssid[ETH_ALEN]; /* 00:00:00:00:00:00: broadcast scan */ s32 chanspec_num; /* 0: all available channels, * otherwise count of chanspecs in chanspec_list */ @@ -489,7 +488,7 @@ typedef struct wl_wsec_key { u16 lo; /* lower 16 bits of IV */ } rxiv; u32 pad_5[2]; - struct ether_addr ea; /* per station */ + u8 ea[ETH_ALEN]; /* per station */ } wl_wsec_key_t; #define WSEC_MIN_PSK_LEN 8 @@ -531,7 +530,7 @@ typedef struct { #define MAXPMKID 16 typedef struct _pmkid { - struct ether_addr BSSID; + u8 BSSID[ETH_ALEN]; u8 PMKID[WLAN_PMKID_LEN]; } pmkid_t; @@ -541,7 +540,7 @@ typedef struct _pmkid_list { } pmkid_list_t; typedef struct _pmkid_cand { - struct ether_addr BSSID; + u8 BSSID[ETH_ALEN]; u8 preauth; } pmkid_cand_t; @@ -569,7 +568,7 @@ typedef struct { /* Used to get specific STA parameters */ typedef struct { u32 val; - struct ether_addr ea; + u8 ea[ETH_ALEN]; } scb_val_t; #endif /* BRCM_FULLMAC */ @@ -583,7 +582,7 @@ typedef struct channel_info { /* For ioctls that take a list of MAC addresses */ struct maclist { uint count; /* number of MAC addresses */ - struct ether_addr ea[1]; /* variable length array of MAC addresses */ + u8 ea[1][ETH_ALEN]; /* variable length array of MAC addresses */ }; /* get pkt count struct passed through ioctl */ @@ -1611,7 +1610,7 @@ struct ampdu_tid_control { /* structure for identifying ea/tid for sending addba/delba */ struct ampdu_ea_tid { - struct ether_addr ea; /* Station address */ + u8 ea[ETH_ALEN]; /* Station address */ u8 tid; /* tid */ }; /* structure for identifying retry/tid for retry_limit_tid/rr_retry_limit_tid */ diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index bdd629d72a75..6bc6207bab3e 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -396,7 +396,7 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, /* BSSID changed, for whatever reason (IBSS and managed mode) */ /* FIXME: need to store bssid in bsscfg */ wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, - (struct ether_addr *)info->bssid); + info->bssid); } if (changed & BSS_CHANGED_BEACON) { WL_ERROR("BSS_CHANGED_BEACON\n"); diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.c b/drivers/staging/brcm80211/sys/wlc_alloc.c index 746439e8fd57..02ae320d5f77 100644 --- a/drivers/staging/brcm80211/sys/wlc_alloc.c +++ b/drivers/staging/brcm80211/sys/wlc_alloc.c @@ -86,8 +86,8 @@ static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, /* need to init the tunables now */ wlc_tunables_init(pub->tunables, devid); - pub->multicast = (struct ether_addr *)wlc_calloc(osh, unit, - (sizeof(struct ether_addr) * MAXMULTILIST)); + pub->multicast = (u8 *)wlc_calloc(osh, unit, + (ETH_ALEN * MAXMULTILIST)); if (pub->multicast == NULL) { *err = 1003; goto fail; diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c index d749917f5912..3d7119536583 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.c +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c @@ -1329,7 +1329,7 @@ void wlc_ampdu_macaddr_upd(struct wlc_info *wlc) /* driver needs to write the ta in the template; ta is at offset 16 */ memset(template, 0, sizeof(template)); - bcopy((char *)wlc->pub->cur_etheraddr.octet, template, ETH_ALEN); + bcopy((char *)wlc->pub->cur_etheraddr, template, ETH_ALEN); wlc_write_template_ram(wlc, (T_BA_TPL_BASE + 16), (T_RAM_ACCESS_SZ * 2), template); } diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index 69f600affa46..e22ce1f79660 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -1032,9 +1032,9 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, err = 21; goto fail; } - bcm_ether_atoe(macaddr, &wlc_hw->etheraddr); - if (is_broadcast_ether_addr(wlc_hw->etheraddr.octet) || - is_zero_ether_addr(wlc_hw->etheraddr.octet)) { + bcm_ether_atoe(macaddr, wlc_hw->etheraddr); + if (is_broadcast_ether_addr(wlc_hw->etheraddr) || + is_zero_ether_addr(wlc_hw->etheraddr)) { WL_ERROR("wl%d: wlc_bmac_attach: bad macaddr %s\n", unit, macaddr); err = 22; @@ -1348,15 +1348,15 @@ void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw) ASSERT(wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) != DBGST_ASLEEP); } -void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, struct ether_addr *ea) +void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, u8 *ea) { - bcopy(&wlc_hw->etheraddr, ea, ETH_ALEN); + bcopy(wlc_hw->etheraddr, ea, ETH_ALEN); } void wlc_bmac_set_hw_etheraddr(struct wlc_hw_info *wlc_hw, - struct ether_addr *ea) + u8 *ea) { - bcopy(ea, &wlc_hw->etheraddr, ETH_ALEN); + bcopy(ea, wlc_hw->etheraddr, ETH_ALEN); } int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw) @@ -1721,7 +1721,7 @@ static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw) */ void wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, - const struct ether_addr *addr) + const u8 *addr) { d11regs_t *regs = wlc_hw->regs; volatile u16 *objdata16 = (volatile u16 *)®s->objdata; @@ -1734,10 +1734,9 @@ wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, ASSERT(wlc_hw->corerev > 4); mac_hm = - (addr->octet[3] << 24) | (addr->octet[2] << 16) | (addr-> - octet[1] << 8) | - addr->octet[0]; - mac_l = (addr->octet[5] << 8) | addr->octet[4]; + (addr[3] << 24) | (addr[2] << 16) | + (addr[1] << 8) | addr[0]; + mac_l = (addr[5] << 8) | addr[4]; osh = wlc_hw->osh; @@ -1754,7 +1753,7 @@ wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, */ void wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset, - const struct ether_addr *addr) + const u8 *addr) { d11regs_t *regs; u16 mac_l; @@ -1767,9 +1766,9 @@ wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset, ASSERT((match_reg_offset < RCM_SIZE) || (wlc_hw->corerev == 4)); regs = wlc_hw->regs; - mac_l = addr->octet[0] | (addr->octet[1] << 8); - mac_m = addr->octet[2] | (addr->octet[3] << 8); - mac_h = addr->octet[4] | (addr->octet[5] << 8); + mac_l = addr[0] | (addr[1] << 8); + mac_m = addr[2] | (addr[3] << 8); + mac_h = addr[4] | (addr[5] << 8); osh = wlc_hw->osh; @@ -3042,7 +3041,7 @@ void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask) void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool on, mbool flags) { - struct ether_addr null_ether_addr = { {0, 0, 0, 0, 0, 0} }; + u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; if (on) { /* suspend tx fifos */ @@ -3053,7 +3052,7 @@ void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool on, mbool flags) /* zero the address match register so we do not send ACKs */ wlc_bmac_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, - &null_ether_addr); + null_ether_addr); } else { /* resume tx fifos */ if (!wlc_hw->wlc->tx_suspended) { @@ -3065,7 +3064,7 @@ void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool on, mbool flags) /* Restore address */ wlc_bmac_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, - &wlc_hw->etheraddr); + wlc_hw->etheraddr); } wlc_phy_mute_upd(wlc_hw->band->pi, on, flags); diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.h b/drivers/staging/brcm80211/sys/wlc_bmac.h index 98150aaff3a3..03ce9521d652 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.h +++ b/drivers/staging/brcm80211/sys/wlc_bmac.h @@ -204,9 +204,9 @@ extern void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, extern void wlc_bmac_process_ps_switch(struct wlc_hw_info *wlc, struct ether_addr *ea, s8 ps_on); extern void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, - struct ether_addr *ea); + u8 *ea); extern void wlc_bmac_set_hw_etheraddr(struct wlc_hw_info *wlc_hw, - struct ether_addr *ea); + u8 *ea); extern bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw); extern bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw); @@ -227,10 +227,10 @@ extern void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw, u32 override_bit); extern void wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, - const struct ether_addr *addr); + const u8 *addr); extern void wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset, - const struct ether_addr *addr); + const u8 *addr); extern void wlc_bmac_write_hw_bcntemplates(struct wlc_hw_info *wlc_hw, void *bcn, int len, bool both); diff --git a/drivers/staging/brcm80211/sys/wlc_bsscfg.h b/drivers/staging/brcm80211/sys/wlc_bsscfg.h index d6a1971c69a0..901a0a3a67d6 100644 --- a/drivers/staging/brcm80211/sys/wlc_bsscfg.h +++ b/drivers/staging/brcm80211/sys/wlc_bsscfg.h @@ -93,8 +93,8 @@ struct wlc_bsscfg { u32 tk_cm_bt_tmstmp; /* Timestamp when TKIP BT is activated */ bool tk_cm_activate; /* activate countermeasures after EAPOL-Key sent */ - struct ether_addr BSSID; /* BSSID (associated) */ - struct ether_addr cur_etheraddr; /* h/w address */ + u8 BSSID[ETH_ALEN]; /* BSSID (associated) */ + u8 cur_etheraddr[ETH_ALEN]; /* h/w address */ u16 bcmc_fid; /* the last BCMC FID queued to TX_BCMC_FIFO */ u16 bcmc_fid_shm; /* the last BCMC FID written to shared mem */ diff --git a/drivers/staging/brcm80211/sys/wlc_key.h b/drivers/staging/brcm80211/sys/wlc_key.h index 6678c69f1e1c..3e23d5145919 100644 --- a/drivers/staging/brcm80211/sys/wlc_key.h +++ b/drivers/staging/brcm80211/sys/wlc_key.h @@ -87,7 +87,7 @@ typedef struct wsec_iv { #define WLC_NUMRXIVS 16 /* # rx IVs (one per 802.11e TID) */ typedef struct wsec_key { - struct ether_addr ea; /* per station */ + u8 ea[ETH_ALEN]; /* per station */ u8 idx; /* key index in wsec_keys array */ u8 id; /* key ID [0-3] */ u8 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 43ee132e09dc..11b267d0728f 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -308,7 +308,7 @@ static int _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, struct wlc_if *wlcif); #if defined(BCMDBG) -void wlc_get_rcmta(struct wlc_info *wlc, int idx, struct ether_addr *addr) +void wlc_get_rcmta(struct wlc_info *wlc, int idx, u8 *addr) { d11regs_t *regs = wlc->regs; u32 v32; @@ -323,15 +323,15 @@ void wlc_get_rcmta(struct wlc_info *wlc, int idx, struct ether_addr *addr) W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); (void)R_REG(osh, ®s->objaddr); v32 = R_REG(osh, ®s->objdata); - addr->octet[0] = (u8) v32; - addr->octet[1] = (u8) (v32 >> 8); - addr->octet[2] = (u8) (v32 >> 16); - addr->octet[3] = (u8) (v32 >> 24); + addr[0] = (u8) v32; + addr[1] = (u8) (v32 >> 8); + addr[2] = (u8) (v32 >> 16); + addr[3] = (u8) (v32 >> 24); W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1))); (void)R_REG(osh, ®s->objaddr); v32 = R_REG(osh, (volatile u16 *)®s->objdata); - addr->octet[4] = (u8) v32; - addr->octet[5] = (u8) (v32 >> 8); + addr[4] = (u8) v32; + addr[5] = (u8) (v32 >> 8); } #endif /* defined(BCMDBG) */ @@ -687,7 +687,7 @@ int wlc_set_mac(wlc_bsscfg_t *cfg) if (cfg == wlc->cfg) { /* enter the MAC addr into the RXE match registers */ - wlc_set_addrmatch(wlc, RCM_MAC_OFFSET, &cfg->cur_etheraddr); + wlc_set_addrmatch(wlc, RCM_MAC_OFFSET, cfg->cur_etheraddr); } wlc_ampdu_macaddr_upd(wlc); @@ -704,7 +704,7 @@ void wlc_set_bssid(wlc_bsscfg_t *cfg) /* if primary config, we need to update BSSID in RXE match registers */ if (cfg == wlc->cfg) { - wlc_set_addrmatch(wlc, RCM_BSSID_OFFSET, &cfg->BSSID); + wlc_set_addrmatch(wlc, RCM_BSSID_OFFSET, cfg->BSSID); } #ifdef SUPPORT_HWKEYS else if (BSSCFG_STA(cfg) && cfg->BSS) { @@ -1736,7 +1736,6 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, ASSERT(WSEC_MAX_DEFAULT_KEYS == WLC_DEFAULT_KEYS); /* some code depends on packed structures */ - ASSERT(sizeof(struct ether_addr) == ETH_ALEN); ASSERT(sizeof(struct ethhdr) == ETH_HLEN); ASSERT(sizeof(d11regs_t) == SI_CORE_SIZE); ASSERT(sizeof(ofdm_phy_hdr_t) == D11_PHY_HDR_LEN); @@ -1846,7 +1845,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, wlc->core->txavail[i] = wlc->hw->txavail[i]; } - wlc_bmac_hw_etheraddr(wlc->hw, &wlc->perm_etheraddr); + wlc_bmac_hw_etheraddr(wlc->hw, wlc->perm_etheraddr); bcopy((char *)&wlc->perm_etheraddr, (char *)&pub->cur_etheraddr, ETH_ALEN); @@ -3610,7 +3609,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, if (src_key->flags & WSEC_PRIMARY_KEY) key.flags |= WL_PRIMARY_KEY; - bcopy(src_key->ea.octet, key.ea.octet, + bcopy(src_key->ea, key.ea, ETH_ALEN); } @@ -3647,7 +3646,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, u32 hi; /* group keys in WPA-NONE (IBSS only, AES and TKIP) use a global TXIV */ if ((bsscfg->WPA_auth & WPA_AUTH_NONE) && - is_zero_ether_addr(key->ea.octet)) { + is_zero_ether_addr(key->ea)) { lo = bsscfg->wpa_none_txiv.lo; hi = bsscfg->wpa_none_txiv.hi; } else { @@ -5819,7 +5818,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, rspec[k] = WLC_RATE_1M; } else { if (WLANTSEL_ENAB(wlc) && - !is_multicast_ether_addr(h->a1.octet)) { + !is_multicast_ether_addr(h->a1)) { /* set tx antenna config */ wlc_antsel_antcfg_get(wlc->asi, false, false, 0, 0, &antcfg, &fbantcfg); @@ -5982,7 +5981,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* DUR field for main rate */ if ((fc != FC_PS_POLL) && - !is_multicast_ether_addr(h->a1.octet) && !use_rifs) { + !is_multicast_ether_addr(h->a1) && !use_rifs) { durid = wlc_compute_frame_dur(wlc, rspec[0], preamble_type[0], next_frag_len); @@ -6000,7 +5999,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* DUR field for fallback rate */ if (fc == FC_PS_POLL) txh->FragDurFallback = h->durid; - else if (is_multicast_ether_addr(h->a1.octet) || use_rifs) + else if (is_multicast_ether_addr(h->a1) || use_rifs) txh->FragDurFallback = 0; else { durid = wlc_compute_frame_dur(wlc, rspec[1], @@ -6012,7 +6011,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, if (frag == 0) mcl |= TXC_STARTMSDU; - if (!is_multicast_ether_addr(h->a1.octet)) + if (!is_multicast_ether_addr(h->a1)) mcl |= TXC_IMMEDACK; if (BAND_5G(wlc->band->bandtype)) @@ -6241,7 +6240,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, if (SCB_WME(scb) && qos && wlc->edcf_txop[ac]) { uint frag_dur, dur, dur_fallback; - ASSERT(!is_multicast_ether_addr(h->a1.octet)); + ASSERT(!is_multicast_ether_addr(h->a1)); /* WME: Update TXOP threshold */ if ((!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) && (frag == 0)) { @@ -7051,8 +7050,8 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) if (!is_amsdu) { /* CTS and ACK CTL frames are w/o a2 */ if (FC_TYPE(fc) == FC_TYPE_DATA || FC_TYPE(fc) == FC_TYPE_MNG) { - if ((is_zero_ether_addr(h->a2.octet) || - is_multicast_ether_addr(h->a2.octet))) { + if ((is_zero_ether_addr(h->a2) || + is_multicast_ether_addr(h->a2))) { WL_ERROR("wl%d: %s: dropping a frame with invalid src mac address, a2: %pM\n", wlc->pub->unit, __func__, &h->a2); WLCNTINCR(wlc->pub->_cnt->rxbadsrcmac); @@ -7622,6 +7621,7 @@ static void wlc_bcn_prb_template(struct wlc_info *wlc, uint type, ratespec_t bcn_rspec, wlc_bsscfg_t *cfg, u16 *buf, int *len) { + static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; cck_phy_hdr_t *plcp; struct dot11_management_header *h; int hdr_len, body_len; @@ -8232,12 +8232,12 @@ void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len, void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, - const struct ether_addr *addr) + const u8 *addr) { wlc_bmac_set_addrmatch(wlc->hw, match_reg_offset, addr); } -void wlc_set_rcmta(struct wlc_info *wlc, int idx, const struct ether_addr *addr) +void wlc_set_rcmta(struct wlc_info *wlc, int idx, const u8 *addr) { wlc_bmac_set_rcmta(wlc->hw, idx, addr); } diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index 5df996b78911..72e52bf561a4 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -470,7 +470,7 @@ struct wlc_hw_info { uint mac_suspend_depth; /* current depth of mac_suspend levels */ u32 wake_override; /* Various conditions to force MAC to WAKE mode */ u32 mute_override; /* Prevent ucode from sending beacons */ - struct ether_addr etheraddr; /* currently configured ethernet address */ + u8 etheraddr[ETH_ALEN]; /* currently configured ethernet address */ u32 led_gpio_mask; /* LED GPIO Mask */ bool noreset; /* true= do not reset hw, used by WLC_OUT */ bool forcefastclk; /* true if the h/w is forcing the use of fast clk */ @@ -566,7 +566,7 @@ struct wlc_info { u32 machwcap; /* MAC capabilities, BMAC shadow */ - struct ether_addr perm_etheraddr; /* original sprom local ethernet address */ + u8 perm_etheraddr[ETH_ALEN]; /* original sprom local ethernet address */ bool bandlocked; /* disable auto multi-band switching */ bool bandinit_pending; /* track band init in auto band */ @@ -836,12 +836,12 @@ extern void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len, bool both); #if defined(BCMDBG) extern void wlc_get_rcmta(struct wlc_info *wlc, int idx, - struct ether_addr *addr); + u8 *addr); #endif extern void wlc_set_rcmta(struct wlc_info *wlc, int idx, - const struct ether_addr *addr); + const u8 *addr); extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, - const struct ether_addr *addr); + const u8 *addr); extern void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, u32 *tsf_h_ptr); extern void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin); diff --git a/drivers/staging/brcm80211/sys/wlc_pub.h b/drivers/staging/brcm80211/sys/wlc_pub.h index 146a6904a39b..2ada3603cd65 100644 --- a/drivers/staging/brcm80211/sys/wlc_pub.h +++ b/drivers/staging/brcm80211/sys/wlc_pub.h @@ -165,7 +165,7 @@ typedef struct wlc_event { /* wlc internal bss_info, wl external one is in wlioctl.h */ typedef struct wlc_bss_info { - struct ether_addr BSSID; /* network BSSID */ + u8 BSSID[ETH_ALEN]; /* network BSSID */ u16 flags; /* flags for internal attributes */ u8 SSID_len; /* the length of SSID */ u8 SSID[32]; /* SSID string */ @@ -291,9 +291,9 @@ struct wlc_pub { s8 _coex; /* 20/40 MHz BSS Management AUTO, ENAB, DISABLE */ bool _priofc; /* Priority-based flowcontrol */ - struct ether_addr cur_etheraddr; /* our local ethernet address */ + u8 cur_etheraddr[ETH_ALEN]; /* our local ethernet address */ - struct ether_addr *multicast; /* ptr to list of multicast addresses */ + u8 *multicast; /* ptr to list of multicast addresses */ uint nmulticast; /* # enabled multicast addresses */ u32 wlfeatureflag; /* Flags to control sw features from registry */ @@ -524,7 +524,7 @@ extern void wlc_statsupd(struct wlc_info *wlc); extern int wlc_get_header_len(void); extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc); extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, - const struct ether_addr *addr); + const u8 *addr); extern void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend); diff --git a/drivers/staging/brcm80211/sys/wlc_scb.h b/drivers/staging/brcm80211/sys/wlc_scb.h index fe84e993b52a..142b75674444 100644 --- a/drivers/staging/brcm80211/sys/wlc_scb.h +++ b/drivers/staging/brcm80211/sys/wlc_scb.h @@ -58,7 +58,7 @@ struct scb { u32 flags; /* various bit flags as defined below */ u32 flags2; /* various bit flags2 as defined below */ u8 state; /* current state bitfield of auth/assoc process */ - struct ether_addr ea; /* station address */ + u8 ea[ETH_ALEN]; /* station address */ void *fragbuf[NUMPRIO]; /* defragmentation buffer per prio */ uint fragresid[NUMPRIO]; /* #bytes unused in frag buffer per prio */ diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index fc836ee38ed8..622cd309c6a7 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -45,7 +45,6 @@ #endif #include -#include /* for sprom content groking */ #define BS_ERROR(args) @@ -1726,16 +1725,16 @@ static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b) continue; if (flags & SRFL_ETHADDR) { - struct ether_addr ea; + u8 ea[ETH_ALEN]; - ea.octet[0] = (srom[srv->off - off] >> 8) & 0xff; - ea.octet[1] = srom[srv->off - off] & 0xff; - ea.octet[2] = (srom[srv->off + 1 - off] >> 8) & 0xff; - ea.octet[3] = srom[srv->off + 1 - off] & 0xff; - ea.octet[4] = (srom[srv->off + 2 - off] >> 8) & 0xff; - ea.octet[5] = srom[srv->off + 2 - off] & 0xff; + ea[0] = (srom[srv->off - off] >> 8) & 0xff; + ea[1] = srom[srv->off - off] & 0xff; + ea[2] = (srom[srv->off + 1 - off] >> 8) & 0xff; + ea[3] = srom[srv->off + 1 - off] & 0xff; + ea[4] = (srom[srv->off + 2 - off] >> 8) & 0xff; + ea[5] = srom[srv->off + 2 - off] & 0xff; - varbuf_append(b, "%s=%pM", name, ea.octet); + varbuf_append(b, "%s=%pM", name, ea); } else { ASSERT(mask_valid(srv->mask)); ASSERT(mask_width(srv->mask)); diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index fd30cc6fb7f8..258fd90d9152 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -348,12 +347,12 @@ struct sk_buff *BCMFASTPATH pktq_mdeq(struct pktq *pq, uint prec_bmp, } /* parse a xx:xx:xx:xx:xx:xx format ethernet address */ -int bcm_ether_atoe(char *p, struct ether_addr *ea) +int bcm_ether_atoe(char *p, u8 *ea) { int i = 0; for (;;) { - ea->octet[i++] = (char)simple_strtoul(p, &p, 16); + ea[i++] = (char)simple_strtoul(p, &p, 16); if (!*p++ || i == 6) break; } -- cgit v1.2.3 From 1b1d36b6e8df93b1ddba81c6b72f0c22be6ed4ef Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Fri, 24 Dec 2010 15:17:40 +0100 Subject: staging: brcm80211: replaced 2.4Ghz specific wf_channel2mhz() 2.4 Ghz code cleanup related. Replaced broadcom specific function with Linux function ieee80211_dsss_chan_to_freq(). Reviewed-by: Arend van Spriel Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 38 ++++++++++++++++------------ drivers/staging/brcm80211/sys/wlc_mac80211.c | 2 +- drivers/staging/brcm80211/util/bcmwifi.c | 5 +--- 3 files changed, 24 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index eed40fa36f81..ad16732b3461 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -30,7 +30,7 @@ #include #include #include - +#include typedef const struct si_pub si_t; #include @@ -529,12 +529,13 @@ wl_iw_get_range(struct net_device *dev, range->freq[i].i = dtoh32(list->element[i]); ch = dtoh32(list->element[i]); - if (ch <= CH_MAX_2G_CHANNEL) + if (ch <= CH_MAX_2G_CHANNEL) { sf = WF_CHAN_FACTOR_2_4_G; - else + range->freq[i].m = ieee80211_dsss_chan_to_freq(ch); + } else { sf = WF_CHAN_FACTOR_5_G; - - range->freq[i].m = wf_channel2mhz(ch, sf); + range->freq[i].m = wf_channel2mhz(ch, sf); + } range->freq[i].e = 6; } range->num_frequency = range->num_channels = i; @@ -1534,11 +1535,14 @@ wl_iw_get_scan_prep(wl_scan_results_t *list, } iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = wf_channel2mhz(CHSPEC_CHANNEL(bi->chanspec), - CHSPEC_CHANNEL(bi->chanspec) <= - CH_MAX_2G_CHANNEL ? - WF_CHAN_FACTOR_2_4_G : - WF_CHAN_FACTOR_5_G); + + if (CHSPEC_CHANNEL(bi->chanspec) <= CH_MAX_2G_CHANNEL) + iwe.u.freq.m = ieee80211_dsss_chan_to_freq( + CHSPEC_CHANNEL(bi->chanspec)); + else + iwe.u.freq.m = wf_channel2mhz( + CHSPEC_CHANNEL(bi->chanspec), + WF_CHAN_FACTOR_5_G); iwe.u.freq.e = 6; event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, @@ -1811,12 +1815,14 @@ wl_iw_iscan_get_scan(struct net_device *dev, channel = (bi->ctl_ch == 0) ? CHSPEC_CHANNEL(bi->chanspec) : bi->ctl_ch; - iwe.u.freq.m = - wf_channel2mhz(channel, - channel <= - CH_MAX_2G_CHANNEL ? - WF_CHAN_FACTOR_2_4_G : - WF_CHAN_FACTOR_5_G); + + if (channel <= CH_MAX_2G_CHANNEL) + iwe.u.freq.m = + ieee80211_dsss_chan_to_freq(channel); + else + iwe.u.freq.m = wf_channel2mhz(channel, + WF_CHAN_FACTOR_5_G); + iwe.u.freq.e = 6; event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 11b267d0728f..4853286c2916 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -6840,7 +6840,7 @@ prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, rx_status->freq = wf_channel2mhz(channel, WF_CHAN_FACTOR_5_G); } else { rx_status->band = IEEE80211_BAND_2GHZ; - rx_status->freq = wf_channel2mhz(channel, WF_CHAN_FACTOR_2_4_G); + rx_status->freq = ieee80211_dsss_chan_to_freq(channel); } rx_status->signal = wlc_rxh->rssi; /* signal */ diff --git a/drivers/staging/brcm80211/util/bcmwifi.c b/drivers/staging/brcm80211/util/bcmwifi.c index 81e54bd7a554..fbed6c0292bc 100644 --- a/drivers/staging/brcm80211/util/bcmwifi.c +++ b/drivers/staging/brcm80211/util/bcmwifi.c @@ -181,11 +181,8 @@ int wf_channel2mhz(uint ch, uint start_factor) { int freq; - if ((start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 14)) || - (ch > 200)) + if (ch > 200) freq = -1; - else if ((start_factor == WF_CHAN_FACTOR_2_4_G) && (ch == 14)) - freq = 2484; else freq = ch * 5 + start_factor / 2; -- cgit v1.2.3 From d69a135806136ef26298116cc3fa08d14bb1d7d6 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Fri, 24 Dec 2010 15:17:41 +0100 Subject: staging: brcm80211: replaced 5Ghz specific wf_channel2mhz() Code cleanup related. Replaced broadcom specific function with Linux function ieee80211_dsss_chan_to_freq(). Reviewed-by: Arend van Spriel Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 19 ++++++++++--------- drivers/staging/brcm80211/include/bcmwifi.h | 18 ------------------ drivers/staging/brcm80211/sys/wlc_mac80211.c | 4 +++- drivers/staging/brcm80211/util/bcmwifi.c | 27 --------------------------- 4 files changed, 13 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index ad16732b3461..9d5e2c5e3068 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -489,7 +489,7 @@ wl_iw_get_range(struct net_device *dev, wl_rateset_t rateset; s8 *channels; int error, i, k; - uint sf, ch; + uint ch; int phytype; int bw_cap = 0, sgi_tx = 0, nmode = 0; @@ -530,11 +530,10 @@ wl_iw_get_range(struct net_device *dev, ch = dtoh32(list->element[i]); if (ch <= CH_MAX_2G_CHANNEL) { - sf = WF_CHAN_FACTOR_2_4_G; range->freq[i].m = ieee80211_dsss_chan_to_freq(ch); } else { - sf = WF_CHAN_FACTOR_5_G; - range->freq[i].m = wf_channel2mhz(ch, sf); + range->freq[i].m = ieee80211_ofdm_chan_to_freq( + WF_CHAN_FACTOR_5_G/2, ch); } range->freq[i].e = 6; } @@ -1540,9 +1539,10 @@ wl_iw_get_scan_prep(wl_scan_results_t *list, iwe.u.freq.m = ieee80211_dsss_chan_to_freq( CHSPEC_CHANNEL(bi->chanspec)); else - iwe.u.freq.m = wf_channel2mhz( - CHSPEC_CHANNEL(bi->chanspec), - WF_CHAN_FACTOR_5_G); + iwe.u.freq.m = ieee80211_ofdm_chan_to_freq( + WF_CHAN_FACTOR_5_G/2, + CHSPEC_CHANNEL(bi->chanspec)); + iwe.u.freq.e = 6; event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, @@ -1820,8 +1820,9 @@ wl_iw_iscan_get_scan(struct net_device *dev, iwe.u.freq.m = ieee80211_dsss_chan_to_freq(channel); else - iwe.u.freq.m = wf_channel2mhz(channel, - WF_CHAN_FACTOR_5_G); + iwe.u.freq.m = ieee80211_ofdm_chan_to_freq( + WF_CHAN_FACTOR_5_G/2, + channel); iwe.u.freq.e = 6; event = diff --git a/drivers/staging/brcm80211/include/bcmwifi.h b/drivers/staging/brcm80211/include/bcmwifi.h index 4067fbaacb8f..4978df8660bb 100644 --- a/drivers/staging/brcm80211/include/bcmwifi.h +++ b/drivers/staging/brcm80211/include/bcmwifi.h @@ -171,22 +171,4 @@ extern chanspec_t wf_chspec_ctlchspec(chanspec_t chspec); */ extern int wf_mhz2channel(uint freq, uint start_factor); -/* - * Return the center frequency in MHz of the given channel and base frequency. - * The channel number is interpreted relative to the given base frequency. - * - * The valid channel range is [1, 14] in the 2.4 GHz band and [0, 200] otherwise. - * The base frequency is specified as (start_factor * 500 kHz). - * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for - * 2.4 GHz and 5 GHz bands. - * The channel range of [1, 14] is only checked for a start_factor of - * WF_CHAN_FACTOR_2_4_G (4814). - * Odd start_factors produce channels on .5 MHz boundaries, in which case - * the answer is rounded down to an integral MHz. - * -1 is returned for an out of range channel. - * - * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2 - */ -extern int wf_channel2mhz(uint channel, uint start_factor); - #endif /* _bcmwifi_h_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 4853286c2916..49894b6fdbfa 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -6837,7 +6837,9 @@ prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, /* XXX Channel/badn needs to be filtered against whether we are single/dual band card */ if (channel > 14) { rx_status->band = IEEE80211_BAND_5GHZ; - rx_status->freq = wf_channel2mhz(channel, WF_CHAN_FACTOR_5_G); + rx_status->freq = ieee80211_ofdm_chan_to_freq( + WF_CHAN_FACTOR_5_G/2, channel); + } else { rx_status->band = IEEE80211_BAND_2GHZ; rx_status->freq = ieee80211_dsss_chan_to_freq(channel); diff --git a/drivers/staging/brcm80211/util/bcmwifi.c b/drivers/staging/brcm80211/util/bcmwifi.c index fbed6c0292bc..cb6f21ae36cc 100644 --- a/drivers/staging/brcm80211/util/bcmwifi.c +++ b/drivers/staging/brcm80211/util/bcmwifi.c @@ -161,30 +161,3 @@ int wf_mhz2channel(uint freq, uint start_factor) return ch; } -/* - * Return the center frequency in MHz of the given channel and base frequency. - * The channel number is interpreted relative to the given base frequency. - * - * The valid channel range is [1, 14] in the 2.4 GHz band and [0, 200] otherwise. - * The base frequency is specified as (start_factor * 500 kHz). - * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_4_G, and WF_CHAN_FACTOR_5_G - * are defined for 2.4 GHz, 4 GHz, and 5 GHz bands. - * The channel range of [1, 14] is only checked for a start_factor of - * WF_CHAN_FACTOR_2_4_G (4814 = 2407 * 2). - * Odd start_factors produce channels on .5 MHz boundaries, in which case - * the answer is rounded down to an integral MHz. - * -1 is returned for an out of range channel. - * - * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2 - */ -int wf_channel2mhz(uint ch, uint start_factor) -{ - int freq; - - if (ch > 200) - freq = -1; - else - freq = ch * 5 + start_factor / 2; - - return freq; -} -- cgit v1.2.3 From f3dc3ea4bb06c966c2071e507df939ad95e3e32c Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Fri, 24 Dec 2010 15:17:42 +0100 Subject: staging: brcm80211: replaced struct dot11_rts_frame by struct ieee80211_rts Code cleanup. Replacing Broadcom specific definitions with Linux counterpart. Not tested yet. Reviewed-by: Arend van Spriel Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/d11.h | 2 +- drivers/staging/brcm80211/include/proto/802.11.h | 7 ------- drivers/staging/brcm80211/sys/wlc_ampdu.c | 12 ++++++------ drivers/staging/brcm80211/sys/wlc_mac80211.c | 18 +++++++++--------- 4 files changed, 16 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/d11.h b/drivers/staging/brcm80211/include/d11.h index 631bfe7d366b..50883af62496 100644 --- a/drivers/staging/brcm80211/include/d11.h +++ b/drivers/staging/brcm80211/include/d11.h @@ -736,7 +736,7 @@ struct d11txh { u16 MaxABytes_FBR; /* 0x2a corerev >=16 */ u16 MinMBytes; /* 0x2b corerev >=16 */ u8 RTSPhyHeader[D11_PHY_HDR_LEN]; /* 0x2c - 0x2e */ - struct dot11_rts_frame rts_frame; /* 0x2f - 0x36 */ + struct ieee80211_rts rts_frame; /* 0x2f - 0x36 */ u16 PAD; /* 0x37 */ } __attribute__((packed)); diff --git a/drivers/staging/brcm80211/include/proto/802.11.h b/drivers/staging/brcm80211/include/proto/802.11.h index 7595bc7a1a7a..0fc12d1844e4 100644 --- a/drivers/staging/brcm80211/include/proto/802.11.h +++ b/drivers/staging/brcm80211/include/proto/802.11.h @@ -54,13 +54,6 @@ struct dot11_header { u8 a4[ETH_ALEN]; } __attribute__((packed)); -struct dot11_rts_frame { - u16 fc; - u16 durid; - u8 ra[ETH_ALEN]; - u8 ta[ETH_ALEN]; -} __attribute__((packed)); - #define DOT11_RTS_LEN 16 #define DOT11_CTS_LEN 10 #define DOT11_ACK_LEN 10 diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c index 3d7119536583..3ce2b2f83fc2 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.c +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c @@ -519,7 +519,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, ratespec_t rspec = 0, rspec_fallback = 0; ratespec_t rts_rspec = 0, rts_rspec_fallback = 0; u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; - struct dot11_rts_frame *rts; + struct ieee80211_rts *rts; u8 rr_retry_limit; wlc_fifo_info_t *f; bool fbr_iscck; @@ -639,8 +639,8 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT); /* refill the bits since might be a retx mpdu */ mcl |= TXC_STARTMSDU; - rts = (struct dot11_rts_frame *)&txh->rts_frame; - fc = ltoh16(rts->fc); + rts = (struct ieee80211_rts *)&txh->rts_frame; + fc = ltoh16(rts->frame_control); if ((fc & FC_KIND_MASK) == FC_RTS) { mcl |= TXC_SENDRTS; use_rts = true; @@ -837,7 +837,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, /* update RTS dur fields */ if (use_rts || use_cts) { u16 durid; - rts = (struct dot11_rts_frame *)&txh->rts_frame; + rts = (struct ieee80211_rts *)&txh->rts_frame; if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) == TXC_PREAMBLE_RTS_MAIN_SHORT) rts_preamble_type = WLC_SHORT_PREAMBLE; @@ -851,7 +851,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, rspec, rts_preamble_type, preamble_type, ampdu_len, true); - rts->durid = htol16(durid); + rts->duration = htol16(durid); durid = wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec_fallback, rspec_fallback, @@ -860,7 +860,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, ampdu_len, true); txh->RTSDurFallback = htol16(durid); /* set TxFesTimeNormal */ - txh->TxFesTimeNormal = rts->durid; + txh->TxFesTimeNormal = rts->duration; /* set fallback rate version of TxFesTimeNormal */ txh->TxFesTimeFallback = txh->RTSDurFallback; } diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 49894b6fdbfa..1c68f4a1fff5 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -1743,7 +1743,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, ASSERT(sizeof(d11txh_t) == D11_TXH_LEN); ASSERT(sizeof(d11rxhdr_t) == RXHDR_LEN); ASSERT(sizeof(struct dot11_header) == DOT11_A4_HDR_LEN); - ASSERT(sizeof(struct dot11_rts_frame) == DOT11_RTS_LEN); + ASSERT(sizeof(struct ieee80211_rts) == DOT11_RTS_LEN); ASSERT(sizeof(struct dot11_management_header) == DOT11_MGMT_HDR_LEN); ASSERT(sizeof(struct dot11_bcn_prb) == DOT11_BCN_PRB_LEN); ASSERT(sizeof(tx_status_t) == TXSTATUS_LEN); @@ -4865,7 +4865,7 @@ void wlc_print_txdesc(d11txh_t *txh) u16 mmbyte = ltoh16(txh->MinMBytes); u8 *rtsph = txh->RTSPhyHeader; - struct dot11_rts_frame rts = txh->rts_frame; + struct ieee80211_rts rts = txh->rts_frame; char hexbuf[256]; /* add plcp header along with txh descriptor */ @@ -5674,7 +5674,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, u8 preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE }; u8 rts_preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE }; u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN]; - struct dot11_rts_frame *rts = NULL; + struct ieee80211_rts *rts = NULL; bool qos; uint ac; u32 rate_val[2]; @@ -6118,12 +6118,12 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, sizeof(txh->RTSPLCPFallback)); /* RTS frame fields... */ - rts = (struct dot11_rts_frame *)&txh->rts_frame; + rts = (struct ieee80211_rts *)&txh->rts_frame; durid = wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec[0], rspec[0], rts_preamble_type[0], preamble_type[0], phylen, false); - rts->durid = htol16(durid); + rts->duration = htol16(durid); /* fallback rate version of RTS DUR field */ durid = wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec[1], rspec[1], @@ -6132,10 +6132,10 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, txh->RTSDurFallback = htol16(durid); if (use_cts) { - rts->fc = htol16(FC_CTS); + rts->frame_control = htol16(FC_CTS); bcopy((char *)&h->a2, (char *)&rts->ra, ETH_ALEN); } else { - rts->fc = htol16((u16) FC_RTS); + rts->frame_control = htol16((u16) FC_RTS); bcopy((char *)&h->a1, (char *)&rts->ra, 2 * ETH_ALEN); } @@ -6150,7 +6150,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, } else { memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN); memset((char *)&txh->rts_frame, 0, - sizeof(struct dot11_rts_frame)); + sizeof(struct ieee80211_rts)); memset((char *)txh->RTSPLCPFallback, 0, sizeof(txh->RTSPLCPFallback)); txh->RTSDurFallback = 0; @@ -6257,7 +6257,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, wlc_calc_cts_time(wlc, rts_rspec[1], rts_preamble_type[1]); /* (SIFS + CTS) + SIFS + frame + SIFS + ACK */ - dur += ltoh16(rts->durid); + dur += ltoh16(rts->duration); dur_fallback += ltoh16(txh->RTSDurFallback); } else if (use_rifs) { dur = frag_dur; -- cgit v1.2.3 From 3e9796f9d4da939f7a67ba66790e9cfb9f9a316b Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Fri, 24 Dec 2010 15:17:43 +0100 Subject: staging: brcm80211: replaced struct dot11_header by struct ieee80211_hdr Code cleanup. Replaced Broadcom specific structure by its Linux equivalent. Reviewed-by: Arend van Spriel Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/proto/802.11.h | 10 ---- drivers/staging/brcm80211/sys/wlc_ampdu.c | 18 +++---- drivers/staging/brcm80211/sys/wlc_mac80211.c | 66 ++++++++++++------------ 3 files changed, 42 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/proto/802.11.h b/drivers/staging/brcm80211/include/proto/802.11.h index 0fc12d1844e4..bb3da205add7 100644 --- a/drivers/staging/brcm80211/include/proto/802.11.h +++ b/drivers/staging/brcm80211/include/proto/802.11.h @@ -44,16 +44,6 @@ #define DOT11_OUI_LEN 3 -struct dot11_header { - u16 fc; - u16 durid; - u8 a1[ETH_ALEN]; - u8 a2[ETH_ALEN]; - u8 a3[ETH_ALEN]; - u16 seq; - u8 a4[ETH_ALEN]; -} __attribute__((packed)); - #define DOT11_RTS_LEN 16 #define DOT11_CTS_LEN 10 #define DOT11_ACK_LEN 10 diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c index 3ce2b2f83fc2..d4c1ee58369d 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.c +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c @@ -154,10 +154,10 @@ static void wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, static inline u16 pkt_txh_seqnum(struct wlc_info *wlc, struct sk_buff *p) { d11txh_t *txh; - struct dot11_header *h; + struct ieee80211_hdr *h; txh = (d11txh_t *) p->data; - h = (struct dot11_header *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); - return ltoh16(h->seq) >> SEQNUM_SHIFT; + h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); + return ltoh16(h->seq_ctrl) >> SEQNUM_SHIFT; } struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc) @@ -510,7 +510,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, u32 ampdu_len, maxlen = 0; d11txh_t *txh = NULL; u8 *plcp; - struct dot11_header *h; + struct ieee80211_hdr *h; struct scb *scb; scb_ampdu_t *scb_ampdu; scb_ampdu_tid_ini_t *ini; @@ -596,8 +596,8 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); txh = (d11txh_t *) p->data; plcp = (u8 *) (txh + 1); - h = (struct dot11_header *)(plcp + D11_PHY_HDR_LEN); - seq = ltoh16(h->seq) >> SEQNUM_SHIFT; + h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); + seq = ltoh16(h->seq_ctrl) >> SEQNUM_SHIFT; index = TX_SEQ_TO_INDEX(seq); /* check mcl fields and test whether it can be agg'd */ @@ -968,7 +968,7 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, u8 bitmap[8], queue, tid; d11txh_t *txh; u8 *plcp; - struct dot11_header *h; + struct ieee80211_hdr *h; u16 seq, start_seq = 0, bindex, index, mcl; u8 mcs = 0; bool ba_recd = false, ack_recd = false; @@ -1089,8 +1089,8 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, txh = (d11txh_t *) p->data; mcl = ltoh16(txh->MacTxControlLow); plcp = (u8 *) (txh + 1); - h = (struct dot11_header *)(plcp + D11_PHY_HDR_LEN); - seq = ltoh16(h->seq) >> SEQNUM_SHIFT; + h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); + seq = ltoh16(h->seq_ctrl) >> SEQNUM_SHIFT; if (tot_mpdu == 0) { mcs = plcp[0] & MIMO_PLCP_MCS_MASK; diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 1c68f4a1fff5..f3b1b12b1900 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -1742,7 +1742,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, ASSERT(sizeof(cck_phy_hdr_t) == D11_PHY_HDR_LEN); ASSERT(sizeof(d11txh_t) == D11_TXH_LEN); ASSERT(sizeof(d11rxhdr_t) == RXHDR_LEN); - ASSERT(sizeof(struct dot11_header) == DOT11_A4_HDR_LEN); + ASSERT(sizeof(struct ieee80211_hdr) == DOT11_A4_HDR_LEN); ASSERT(sizeof(struct ieee80211_rts) == DOT11_RTS_LEN); ASSERT(sizeof(struct dot11_management_header) == DOT11_MGMT_HDR_LEN); ASSERT(sizeof(struct dot11_bcn_prb) == DOT11_BCN_PRB_LEN); @@ -5120,12 +5120,12 @@ wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, uint fifo; void *pkt; struct scb *scb = &global_scb; - struct dot11_header *d11_header = (struct dot11_header *)(sdu->data); + struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data); u16 type, fc; ASSERT(sdu); - fc = ltoh16(d11_header->fc); + fc = ltoh16(d11_header->frame_control); type = FC_TYPE(fc); /* 802.11 standard requires management traffic to go at highest priority */ @@ -5658,7 +5658,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, uint nfrags, uint queue, uint next_frag_len, wsec_key_t *key, ratespec_t rspec_override) { - struct dot11_header *h; + struct ieee80211_hdr *h; d11txh_t *txh; u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN]; struct osl_info *osh; @@ -5701,8 +5701,8 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, osh = wlc->osh; /* locate 802.11 MAC header */ - h = (struct dot11_header *)(p->data); - fc = ltoh16(h->fc); + h = (struct ieee80211_hdr *)(p->data); + fc = ltoh16(h->frame_control); type = FC_TYPE(fc); qos = (type == FC_TYPE_DATA && FC_SUBTYPE_ANY_QOS(FC_SUBTYPE(fc))); @@ -5748,7 +5748,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* extract fragment number from frame first */ seq = ltoh16(seq) & FRAGNUM_MASK; seq |= (SCB_SEQNUM(scb, p->priority) << SEQNUM_SHIFT); - h->seq = htol16(seq); + h->seq_ctrl = htol16(seq); frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) | (queue & TXFID_QUEUE_MASK); @@ -5818,7 +5818,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, rspec[k] = WLC_RATE_1M; } else { if (WLANTSEL_ENAB(wlc) && - !is_multicast_ether_addr(h->a1)) { + !is_multicast_ether_addr(h->addr1)) { /* set tx antenna config */ wlc_antsel_antcfg_get(wlc->asi, false, false, 0, 0, &antcfg, &fbantcfg); @@ -5981,11 +5981,11 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* DUR field for main rate */ if ((fc != FC_PS_POLL) && - !is_multicast_ether_addr(h->a1) && !use_rifs) { + !is_multicast_ether_addr(h->addr1) && !use_rifs) { durid = wlc_compute_frame_dur(wlc, rspec[0], preamble_type[0], next_frag_len); - h->durid = htol16(durid); + h->duration_id = htol16(durid); } else if (use_rifs) { /* NAV protect to end of next max packet size */ durid = @@ -5993,13 +5993,13 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, preamble_type[0], DOT11_MAX_FRAG_LEN); durid += RIFS_11N_TIME; - h->durid = htol16(durid); + h->duration_id = htol16(durid); } /* DUR field for fallback rate */ if (fc == FC_PS_POLL) - txh->FragDurFallback = h->durid; - else if (is_multicast_ether_addr(h->a1) || use_rifs) + txh->FragDurFallback = h->duration_id; + else if (is_multicast_ether_addr(h->addr1) || use_rifs) txh->FragDurFallback = 0; else { durid = wlc_compute_frame_dur(wlc, rspec[1], @@ -6011,7 +6011,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, if (frag == 0) mcl |= TXC_STARTMSDU; - if (!is_multicast_ether_addr(h->a1)) + if (!is_multicast_ether_addr(h->addr1)) mcl |= TXC_IMMEDACK; if (BAND_5G(wlc->band->bandtype)) @@ -6039,14 +6039,14 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, } /* MacFrameControl */ - bcopy((char *)&h->fc, (char *)&txh->MacFrameControl, sizeof(u16)); - + bcopy((char *)&h->frame_control, (char *)&txh->MacFrameControl, + sizeof(u16)); txh->TxFesTimeNormal = htol16(0); txh->TxFesTimeFallback = htol16(0); /* TxFrameRA */ - bcopy((char *)&h->a1, (char *)&txh->TxFrameRA, ETH_ALEN); + bcopy((char *)&h->addr1, (char *)&txh->TxFrameRA, ETH_ALEN); /* TxFrameID */ txh->TxFrameID = htol16(frameid); @@ -6133,10 +6133,10 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, if (use_cts) { rts->frame_control = htol16(FC_CTS); - bcopy((char *)&h->a2, (char *)&rts->ra, ETH_ALEN); + bcopy((char *)&h->addr2, (char *)&rts->ra, ETH_ALEN); } else { rts->frame_control = htol16((u16) FC_RTS); - bcopy((char *)&h->a1, (char *)&rts->ra, + bcopy((char *)&h->addr1, (char *)&rts->ra, 2 * ETH_ALEN); } @@ -6240,7 +6240,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, if (SCB_WME(scb) && qos && wlc->edcf_txop[ac]) { uint frag_dur, dur, dur_fallback; - ASSERT(!is_multicast_ether_addr(h->a1)); + ASSERT(!is_multicast_ether_addr(h->addr1)); /* WME: Update TXOP threshold */ if ((!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) && (frag == 0)) { @@ -6542,7 +6542,7 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) int tx_rts, tx_frame_count, tx_rts_count; uint totlen, supr_status; bool lastframe; - struct dot11_header *h; + struct ieee80211_hdr *h; u16 fc; u16 mcl; struct ieee80211_tx_info *tx_info; @@ -6598,8 +6598,8 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) goto fatal; tx_info = IEEE80211_SKB_CB(p); - h = (struct dot11_header *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); - fc = ltoh16(h->fc); + h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); + fc = ltoh16(h->frame_control); scb = (struct scb *)tx_info->control.sta->drv_priv; @@ -6995,7 +6995,7 @@ void wlc_bss_list_free(struct wlc_info *wlc, wlc_bss_list_t *bss_list) void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) { d11rxhdr_t *rxh; - struct dot11_header *h; + struct ieee80211_hdr *h; struct osl_info *osh; u16 fc; uint len; @@ -7025,7 +7025,7 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) skb_pull(p, 2); } - h = (struct dot11_header *)(p->data + D11_PHY_HDR_LEN); + h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN); len = p->len; if (rxh->RxStatus1 & RXS_FCSERR) { @@ -7039,8 +7039,8 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) } /* check received pkt has at least frame control field */ - if (len >= D11_PHY_HDR_LEN + sizeof(h->fc)) { - fc = ltoh16(h->fc); + if (len >= D11_PHY_HDR_LEN + sizeof(h->frame_control)) { + fc = ltoh16(h->frame_control); } else { WLCNTINCR(wlc->pub->_cnt->rxrunt); goto toss; @@ -7052,10 +7052,10 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) if (!is_amsdu) { /* CTS and ACK CTL frames are w/o a2 */ if (FC_TYPE(fc) == FC_TYPE_DATA || FC_TYPE(fc) == FC_TYPE_MNG) { - if ((is_zero_ether_addr(h->a2) || - is_multicast_ether_addr(h->a2))) { + if ((is_zero_ether_addr(h->addr2) || + is_multicast_ether_addr(h->addr2))) { WL_ERROR("wl%d: %s: dropping a frame with invalid src mac address, a2: %pM\n", - wlc->pub->unit, __func__, &h->a2); + wlc->pub->unit, __func__, &h->addr2); WLCNTINCR(wlc->pub->_cnt->rxbadsrcmac); goto toss; } @@ -7829,7 +7829,7 @@ int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) struct osl_info *osh; uint fifo; d11txh_t *txh; - struct dot11_header *h; + struct ieee80211_hdr *h; struct scb *scb; u16 fc; @@ -7838,9 +7838,9 @@ int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) ASSERT(pdu); txh = (d11txh_t *) (pdu->data); ASSERT(txh); - h = (struct dot11_header *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); + h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); ASSERT(h); - fc = ltoh16(h->fc); + fc = ltoh16(h->frame_control); /* get the pkt queue info. This was put at wlc_sendctl or wlc_send for PDU */ fifo = ltoh16(txh->TxFrameID) & TXFID_QUEUE_MASK; -- cgit v1.2.3 From 392308d00eb99bd92093fd8d6b7049d6745f150b Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Fri, 24 Dec 2010 15:17:44 +0100 Subject: staging: brcm80211: replaced struct dot11_management_header with ieee80211_mgmt Code cleanup. Reviewed-by: Arend van Spriel Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/proto/802.11.h | 8 -------- drivers/staging/brcm80211/sys/wlc_mac80211.c | 9 ++++----- 2 files changed, 4 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/proto/802.11.h b/drivers/staging/brcm80211/include/proto/802.11.h index bb3da205add7..5adabfb3e268 100644 --- a/drivers/staging/brcm80211/include/proto/802.11.h +++ b/drivers/staging/brcm80211/include/proto/802.11.h @@ -51,14 +51,6 @@ #define DOT11_BA_BITMAP_LEN 128 #define DOT11_BA_LEN 4 -struct dot11_management_header { - u16 fc; - u16 durid; - u8 da[ETH_ALEN]; - u8 sa[ETH_ALEN]; - u8 bssid[ETH_ALEN]; - u16 seq; -} __attribute__((packed)); #define DOT11_MGMT_HDR_LEN 24 struct dot11_bcn_prb { diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index f3b1b12b1900..755b73d604a1 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -1744,7 +1744,6 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, ASSERT(sizeof(d11rxhdr_t) == RXHDR_LEN); ASSERT(sizeof(struct ieee80211_hdr) == DOT11_A4_HDR_LEN); ASSERT(sizeof(struct ieee80211_rts) == DOT11_RTS_LEN); - ASSERT(sizeof(struct dot11_management_header) == DOT11_MGMT_HDR_LEN); ASSERT(sizeof(struct dot11_bcn_prb) == DOT11_BCN_PRB_LEN); ASSERT(sizeof(tx_status_t) == TXSTATUS_LEN); ASSERT(sizeof(ht_cap_ie_t) == HT_CAP_IE_LEN); @@ -7625,7 +7624,7 @@ wlc_bcn_prb_template(struct wlc_info *wlc, uint type, ratespec_t bcn_rspec, { static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; cck_phy_hdr_t *plcp; - struct dot11_management_header *h; + struct ieee80211_mgmt *h; int hdr_len, body_len; ASSERT(*len >= 142); @@ -7658,12 +7657,12 @@ wlc_bcn_prb_template(struct wlc_info *wlc, uint type, ratespec_t bcn_rspec, wlc_beacon_phytxctl_txant_upd(wlc, bcn_rspec); if (MBSS_BCN_ENAB(cfg) && type == FC_BEACON) - h = (struct dot11_management_header *)&plcp[0]; + h = (struct ieee80211_mgmt *)&plcp[0]; else - h = (struct dot11_management_header *)&plcp[1]; + h = (struct ieee80211_mgmt *)&plcp[1]; /* fill in 802.11 header */ - h->fc = htol16((u16) type); + h->frame_control = htol16((u16) type); /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */ /* A1 filled in by MAC for prb resp, broadcast for bcn */ -- cgit v1.2.3 From 3726ed4d55ec2b16a8b453b4025eff8ca41bd8a2 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Fri, 24 Dec 2010 15:17:45 +0100 Subject: staging: brcm80211: replaced some ieee80211 preprocessor constants part 1 Code cleanup. Reviewed-by: Arend van Spriel Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/proto/802.11.h | 10 +++----- drivers/staging/brcm80211/sys/wlc_ampdu.c | 3 ++- drivers/staging/brcm80211/sys/wlc_bsscfg.h | 2 +- drivers/staging/brcm80211/sys/wlc_mac80211.c | 30 ++++++++++++------------ drivers/staging/brcm80211/sys/wlc_pub.h | 2 +- 5 files changed, 22 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/proto/802.11.h b/drivers/staging/brcm80211/include/proto/802.11.h index 5adabfb3e268..9ddf42aa3669 100644 --- a/drivers/staging/brcm80211/include/proto/802.11.h +++ b/drivers/staging/brcm80211/include/proto/802.11.h @@ -22,14 +22,11 @@ #define DOT11_A3_HDR_LEN 24 #define DOT11_A4_HDR_LEN 30 #define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN -#define DOT11_FCS_LEN 4 #define DOT11_ICV_AES_LEN 8 #define DOT11_QOS_LEN 2 #define DOT11_IV_MAX_LEN 8 -#define DOT11_MAX_SSID_LEN 32 - #define DOT11_DEFAULT_RTS_LEN 2347 #define DOT11_MIN_FRAG_LEN 256 @@ -131,7 +128,6 @@ typedef struct wme_param_ie wme_param_ie_t; #define FC_TYPE_SHIFT 2 #define FC_SUBTYPE_MASK 0xF0 #define FC_SUBTYPE_SHIFT 4 -#define FC_MOREFRAG 0x400 #define SEQNUM_SHIFT 4 #define SEQNUM_MAX 0x1000 @@ -150,12 +146,12 @@ typedef struct wme_param_ie wme_param_ie_t; #define FC_SUBTYPE_ANY_QOS(s) (((s) & 8) != 0) -#define FC_KIND_MASK (FC_TYPE_MASK | FC_SUBTYPE_MASK) +#define FC_KIND_MASK (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE) #define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT)) -#define FC_SUBTYPE(fc) (((fc) & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT) -#define FC_TYPE(fc) (((fc) & FC_TYPE_MASK) >> FC_TYPE_SHIFT) +#define FC_SUBTYPE(fc) (((fc) & IEEE80211_FCTL_STYPE) >> FC_SUBTYPE_SHIFT) +#define FC_TYPE(fc) (((fc) & IEEE80211_FCTL_FTYPE) >> FC_TYPE_SHIFT) #define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ) #define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP) diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c index d4c1ee58369d..8e1011203481 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.c +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c @@ -67,7 +67,8 @@ #define TX_SEQ_TO_INDEX(seq) ((seq) % AMPDU_TX_BA_MAX_WSIZE) /* max possible overhead per mpdu in the ampdu; 3 is for roundup if needed */ -#define AMPDU_MAX_MPDU_OVERHEAD (DOT11_FCS_LEN + DOT11_ICV_AES_LEN + AMPDU_DELIMITER_LEN + 3 \ +#define AMPDU_MAX_MPDU_OVERHEAD (FCS_LEN + DOT11_ICV_AES_LEN +\ + AMPDU_DELIMITER_LEN + 3\ + DOT11_A4_HDR_LEN + DOT11_QOS_LEN + DOT11_IV_MAX_LEN) #ifdef BCMDBG diff --git a/drivers/staging/brcm80211/sys/wlc_bsscfg.h b/drivers/staging/brcm80211/sys/wlc_bsscfg.h index 901a0a3a67d6..0bb4a212dd71 100644 --- a/drivers/staging/brcm80211/sys/wlc_bsscfg.h +++ b/drivers/staging/brcm80211/sys/wlc_bsscfg.h @@ -63,7 +63,7 @@ struct wlc_bsscfg { bool sup_auth_pending; /* flag for auth timeout */ #endif u8 SSID_len; /* the length of SSID */ - u8 SSID[DOT11_MAX_SSID_LEN]; /* SSID string */ + u8 SSID[IEEE80211_MAX_SSID_LEN]; /* SSID string */ struct scb *bcmc_scb[MAXBANDS]; /* one bcmc_scb per band */ s8 _idx; /* the index of this bsscfg, * assigned at wlc_bsscfg_alloc() diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 755b73d604a1..b26fcf360783 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -67,7 +67,7 @@ * buffer length needed for wlc_format_ssid * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. */ -#define SSID_FMT_BUF_LEN ((4 * DOT11_MAX_SSID_LEN) + 1) +#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) #define TIMER_INTERVAL_WATCHDOG 1000 /* watchdog timer, in unit of ms */ #define TIMER_INTERVAL_RADIOCHK 800 /* radio monitor timer, in unit of ms */ @@ -4963,8 +4963,8 @@ int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len) char *p = buf; char *endp = buf + SSID_FMT_BUF_LEN; - if (ssid_len > DOT11_MAX_SSID_LEN) - ssid_len = DOT11_MAX_SSID_LEN; + if (ssid_len > IEEE80211_MAX_SSID_LEN) + ssid_len = IEEE80211_MAX_SSID_LEN; for (i = 0; i < ssid_len; i++) { c = (uint) ssid[i]; @@ -5708,7 +5708,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* compute length of frame in bytes for use in PLCP computations */ len = pkttotlen(osh, p); - phylen = len + DOT11_FCS_LEN; + phylen = len + FCS_LEN; /* If WEP enabled, add room in phylen for the additional bytes of * ICV which MAC generates. We do NOT add the additional bytes to @@ -6104,9 +6104,9 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, ASSERT(IS_ALIGNED((unsigned long)txh->RTSPhyHeader, sizeof(u16))); rts_plcp = txh->RTSPhyHeader; if (use_cts) - rts_phylen = DOT11_CTS_LEN + DOT11_FCS_LEN; + rts_phylen = DOT11_CTS_LEN + FCS_LEN; else - rts_phylen = DOT11_RTS_LEN + DOT11_FCS_LEN; + rts_phylen = DOT11_RTS_LEN + FCS_LEN; wlc_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp); @@ -6627,7 +6627,7 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) tx_rts_count = (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT; - lastframe = (fc & FC_MOREFRAG) == 0; + lastframe = (fc & IEEE80211_FCTL_MOREFRAGS) == 0; if (!lastframe) { WL_ERROR("Not last frame!\n"); @@ -6945,7 +6945,7 @@ wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, d11rxhdr_t *rxh, prep_mac80211_status(wlc, rxh, p, &rx_status); /* mac header+body length, exclude CRC and plcp header */ - len_mpdu = p->len - D11_PHY_HDR_LEN - DOT11_FCS_LEN; + len_mpdu = p->len - D11_PHY_HDR_LEN - FCS_LEN; skb_pull(p, D11_PHY_HDR_LEN); __skb_trim(p, len_mpdu); @@ -7259,7 +7259,7 @@ wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) /* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */ return wlc_calc_frame_time(wlc, rspec, preamble_type, (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN + - DOT11_FCS_LEN)); + FCS_LEN)); } static uint BCMFASTPATH @@ -7278,7 +7278,7 @@ wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) /* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */ dur = wlc_calc_frame_time(wlc, rspec, preamble_type, - (DOT11_ACK_LEN + DOT11_FCS_LEN)); + (DOT11_ACK_LEN + FCS_LEN)); return dur; } @@ -7647,7 +7647,7 @@ wlc_bcn_prb_template(struct wlc_info *wlc, uint type, ratespec_t bcn_rspec, if (type == FC_BEACON && !MBSS_BCN_ENAB(cfg)) { /* fill in PLCP */ wlc_compute_plcp(wlc, bcn_rspec, - (DOT11_MAC_HDR_LEN + body_len + DOT11_FCS_LEN), + (DOT11_MAC_HDR_LEN + body_len + FCS_LEN), (u8 *) plcp); } @@ -7757,13 +7757,13 @@ void wlc_shm_ssid_upd(struct wlc_info *wlc, wlc_bsscfg_t *cfg) { u8 *ssidptr = cfg->SSID; u16 base = M_SSID; - u8 ssidbuf[DOT11_MAX_SSID_LEN]; + u8 ssidbuf[IEEE80211_MAX_SSID_LEN]; /* padding the ssid with zero and copy it into shm */ - memset(ssidbuf, 0, DOT11_MAX_SSID_LEN); + memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN); bcopy(ssidptr, ssidbuf, cfg->SSID_len); - wlc_copyto_shm(wlc, base, ssidbuf, DOT11_MAX_SSID_LEN); + wlc_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN); if (!MBSS_BCN_ENAB(cfg)) wlc_write_shm(wlc, M_SSIDLEN, (u16) cfg->SSID_len); @@ -7812,7 +7812,7 @@ wlc_bss_update_probe_resp(struct wlc_info *wlc, wlc_bsscfg_t *cfg, bool suspend) * Use the actual frame length covered by the PLCP header for the call to * wlc_mod_prb_rsp_rate_table() by subtracting the PLCP len and adding the FCS. */ - len += (-D11_PHY_HDR_LEN + DOT11_FCS_LEN); + len += (-D11_PHY_HDR_LEN + FCS_LEN); wlc_mod_prb_rsp_rate_table(wlc, (u16) len); if (suspend) diff --git a/drivers/staging/brcm80211/sys/wlc_pub.h b/drivers/staging/brcm80211/sys/wlc_pub.h index 2ada3603cd65..549dd5f5d84a 100644 --- a/drivers/staging/brcm80211/sys/wlc_pub.h +++ b/drivers/staging/brcm80211/sys/wlc_pub.h @@ -134,7 +134,7 @@ struct rsn_parms { * buffer length needed for wlc_format_ssid * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. */ -#define SSID_FMT_BUF_LEN ((4 * DOT11_MAX_SSID_LEN) + 1) +#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) #define RSN_FLAGS_SUPPORTED 0x1 /* Flag for rsn_params */ #define RSN_FLAGS_PREAUTH 0x2 /* Flag for WPA2 rsn_params */ -- cgit v1.2.3 From 04795017b7da2bc1ee35dd671fc11018122a7905 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Fri, 24 Dec 2010 15:17:46 +0100 Subject: staging: brcm80211: replaced some ieee80211 preprocessor constants part 2 Code cleanup. Reviewed-by: Arend van Spriel Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 36 +++++++++++++----------- drivers/staging/brcm80211/include/proto/802.11.h | 20 ------------- drivers/staging/brcm80211/sys/wlc_mac80211.c | 31 +++++++++++--------- drivers/staging/brcm80211/sys/wlc_pub.h | 5 ++-- drivers/staging/brcm80211/sys/wlc_stf.c | 4 +-- 5 files changed, 41 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index 9d5e2c5e3068..c039ef18903f 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -607,14 +607,14 @@ wl_iw_get_range(struct net_device *dev, range->max_encoding_tokens = DOT11_MAX_DEFAULT_KEYS; range->num_encoding_sizes = 4; - range->encoding_size[0] = WEP1_KEY_SIZE; - range->encoding_size[1] = WEP128_KEY_SIZE; + range->encoding_size[0] = WLAN_KEY_LEN_WEP40; + range->encoding_size[1] = WLAN_KEY_LEN_WEP104; #if WIRELESS_EXT > 17 - range->encoding_size[2] = TKIP_KEY_SIZE; + range->encoding_size[2] = WLAN_KEY_LEN_TKIP; #else range->encoding_size[2] = 0; #endif - range->encoding_size[3] = AES_KEY_SIZE; + range->encoding_size[3] = WLAN_KEY_LEN_AES_CMAC; range->min_pmp = 0; range->max_pmp = 0; @@ -909,7 +909,7 @@ wl_iw_get_aplist(struct net_device *dev, ASSERT(((unsigned long)bi + dtoh32(bi->length)) <= ((unsigned long)list + buflen)); - if (!(dtoh16(bi->capability) & DOT11_CAP_ESS)) + if (!(dtoh16(bi->capability) & WLAN_CAPABILITY_ESS)) continue; memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETH_ALEN); @@ -981,7 +981,7 @@ wl_iw_iscan_get_aplist(struct net_device *dev, ASSERT(((unsigned long)bi + dtoh32(bi->length)) <= ((unsigned long)list + WLC_IW_ISCAN_MAXLEN)); - if (!(dtoh16(bi->capability) & DOT11_CAP_ESS)) + if (!(dtoh16(bi->capability) & WLAN_CAPABILITY_ESS)) continue; memcpy(addr[dwrq->length].sa_data, &bi->BSSID, @@ -1522,9 +1522,10 @@ wl_iw_get_scan_prep(wl_scan_results_t *list, iwe.u.data.flags = 1; event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID); - if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) { + if (dtoh16(bi->capability) & (WLAN_CAPABILITY_ESS | + WLAN_CAPABILITY_IBSS)) { iwe.cmd = SIOCGIWMODE; - if (dtoh16(bi->capability) & DOT11_CAP_ESS) + if (dtoh16(bi->capability) & WLAN_CAPABILITY_ESS) iwe.u.mode = IW_MODE_INFRA; else iwe.u.mode = IW_MODE_ADHOC; @@ -1559,7 +1560,7 @@ wl_iw_get_scan_prep(wl_scan_results_t *list, wl_iw_handle_scanresults_ies(&event, end, info, bi); iwe.cmd = SIOCGIWENCODE; - if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY) + if (dtoh16(bi->capability) & WLAN_CAPABILITY_PRIVACY) iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; else iwe.u.data.flags = IW_ENCODE_DISABLED; @@ -1800,9 +1801,10 @@ wl_iw_iscan_get_scan(struct net_device *dev, bi->SSID); if (dtoh16(bi->capability) & - (DOT11_CAP_ESS | DOT11_CAP_IBSS)) { + (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) { iwe.cmd = SIOCGIWMODE; - if (dtoh16(bi->capability) & DOT11_CAP_ESS) + if (dtoh16(bi->capability) & + WLAN_CAPABILITY_ESS) iwe.u.mode = IW_MODE_INFRA; else iwe.u.mode = IW_MODE_ADHOC; @@ -1840,7 +1842,7 @@ wl_iw_iscan_get_scan(struct net_device *dev, wl_iw_handle_scanresults_ies(&event, end, info, bi); iwe.cmd = SIOCGIWENCODE; - if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY) + if (dtoh16(bi->capability) & WLAN_CAPABILITY_PRIVACY) iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; else @@ -2361,16 +2363,16 @@ wl_iw_set_encode(struct net_device *dev, key.flags = WL_PRIMARY_KEY; switch (key.len) { - case WEP1_KEY_SIZE: + case WLAN_KEY_LEN_WEP40: key.algo = CRYPTO_ALGO_WEP1; break; - case WEP128_KEY_SIZE: + case WLAN_KEY_LEN_WEP104: key.algo = CRYPTO_ALGO_WEP128; break; - case TKIP_KEY_SIZE: + case WLAN_KEY_LEN_TKIP: key.algo = CRYPTO_ALGO_TKIP; break; - case AES_KEY_SIZE: + case WLAN_KEY_LEN_AES_CMAC: key.algo = CRYPTO_ALGO_AES_CCM; break; default: @@ -2602,7 +2604,7 @@ wl_iw_set_encodeext(struct net_device *dev, key.algo = CRYPTO_ALGO_OFF; break; case IW_ENCODE_ALG_WEP: - if (iwe->key_len == WEP1_KEY_SIZE) + if (iwe->key_len == WLAN_KEY_LEN_WEP40) key.algo = CRYPTO_ALGO_WEP1; else key.algo = CRYPTO_ALGO_WEP128; diff --git a/drivers/staging/brcm80211/include/proto/802.11.h b/drivers/staging/brcm80211/include/proto/802.11.h index 9ddf42aa3669..e559b2a50654 100644 --- a/drivers/staging/brcm80211/include/proto/802.11.h +++ b/drivers/staging/brcm80211/include/proto/802.11.h @@ -168,12 +168,6 @@ typedef struct wme_param_ie wme_param_ie_t; #define DOT11_MNG_WPA_ID 221 #define DOT11_MNG_VS_ID 221 -#define DOT11_CAP_ESS 0x0001 -#define DOT11_CAP_IBSS 0x0002 -#define DOT11_CAP_PRIVACY 0x0010 -#define DOT11_CAP_SHORT 0x0020 -#define DOT11_CAP_SHORTSLOT 0x0400 - #define DOT11_BSSTYPE_INFRASTRUCTURE 0 #define DOT11_BSSTYPE_ANY 2 #define DOT11_SCANTYPE_ACTIVE 0 @@ -235,21 +229,12 @@ typedef struct ht_cap_ie ht_cap_ie_t; #define HT_CAP_IE_LEN 26 -#define HT_CAP_LDPC_CODING 0x0001 -#define HT_CAP_40MHZ 0x0002 #define HT_CAP_MIMO_PS_MASK 0x000C -#define HT_CAP_MIMO_PS_SHIFT 0x0002 #define HT_CAP_MIMO_PS_OFF 0x0003 #define HT_CAP_MIMO_PS_ON 0x0000 -#define HT_CAP_GF 0x0010 -#define HT_CAP_SHORT_GI_20 0x0020 -#define HT_CAP_SHORT_GI_40 0x0040 -#define HT_CAP_TX_STBC 0x0080 #define HT_CAP_RX_STBC_MASK 0x0300 #define HT_CAP_RX_STBC_SHIFT 8 #define HT_CAP_MAX_AMSDU 0x0800 -#define HT_CAP_DSSS_CCK 0x1000 -#define HT_CAP_40MHZ_INTOLERANT 0x4000 #define HT_CAP_RX_STBC_NO 0x0 #define HT_CAP_RX_STBC_ONE_STREAM 0x1 @@ -281,11 +266,6 @@ typedef struct ht_cap_ie ht_cap_ie_t; #define DOT11_MAX_KEY_SIZE 32 #define DOT11_WPA_KEY_RSC_LEN 8 -#define WEP1_KEY_SIZE 5 -#define WEP128_KEY_SIZE 13 -#define TKIP_KEY_SIZE 32 -#define AES_KEY_SIZE 16 - #define BRCM_OUI "\x00\x10\x18" #endif /* _802_11_H_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index b26fcf360783..0cc79675eb4f 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -737,9 +737,11 @@ void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot) FOREACH_BSS(wlc, idx, cfg) { if (!cfg->associated) continue; - cfg->current_bss->capability &= ~DOT11_CAP_SHORTSLOT; + cfg->current_bss->capability &= + ~WLAN_CAPABILITY_SHORT_SLOT_TIME; if (wlc->shortslot) - cfg->current_bss->capability |= DOT11_CAP_SHORTSLOT; + cfg->current_bss->capability |= + WLAN_CAPABILITY_SHORT_SLOT_TIME; } wlc_bmac_set_shortslot(wlc->hw, shortslot); @@ -1178,9 +1180,9 @@ void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val) static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val) { - wlc->ht_cap.cap &= ~(HT_CAP_SHORT_GI_20 | HT_CAP_SHORT_GI_40); - wlc->ht_cap.cap |= (val & WLC_N_SGI_20) ? HT_CAP_SHORT_GI_20 : 0; - wlc->ht_cap.cap |= (val & WLC_N_SGI_40) ? HT_CAP_SHORT_GI_40 : 0; + wlc->ht_cap.cap &= ~(IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40); + wlc->ht_cap.cap |= (val & WLC_N_SGI_20) ? IEEE80211_HT_CAP_SGI_20 : 0; + wlc->ht_cap.cap |= (val & WLC_N_SGI_40) ? IEEE80211_HT_CAP_SGI_40 : 0; if (wlc->pub->up) { wlc_update_beacon(wlc); @@ -1192,9 +1194,9 @@ static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val) { wlc->stf->ldpc = val; - wlc->ht_cap.cap &= ~HT_CAP_LDPC_CODING; + wlc->ht_cap.cap &= ~IEEE80211_HT_CAP_LDPC_CODING; if (wlc->stf->ldpc != OFF) - wlc->ht_cap.cap |= HT_CAP_LDPC_CODING; + wlc->ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING; if (wlc->pub->up) { wlc_update_beacon(wlc); @@ -1987,14 +1989,14 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, if (n_disabled & WLFEATURE_DISABLE_11N_STBC_TX) { wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF; wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF; - wlc->ht_cap.cap &= ~HT_CAP_TX_STBC; + wlc->ht_cap.cap &= ~IEEE80211_HT_CAP_TX_STBC; } if (n_disabled & WLFEATURE_DISABLE_11N_STBC_RX) wlc_stf_stbc_rx_set(wlc, HT_CAP_RX_STBC_NO); /* apply the GF override from nvram conf */ if (n_disabled & WLFEATURE_DISABLE_11N_GF) - wlc->ht_cap.cap &= ~HT_CAP_GF; + wlc->ht_cap.cap &= ~IEEE80211_HT_CAP_GRN_FLD; /* initialize radio_mpc_disable according to wlc->mpc */ wlc_radio_mpc_upd(wlc); @@ -2872,16 +2874,17 @@ int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) if ((AP_ENAB(wlc->pub) && preamble != WLC_PLCP_LONG) || preamble == WLC_PLCP_SHORT) - wlc->default_bss->capability |= DOT11_CAP_SHORT; + wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE; else - wlc->default_bss->capability &= ~DOT11_CAP_SHORT; + wlc->default_bss->capability &= ~WLAN_CAPABILITY_SHORT_PREAMBLE; /* Update shortslot capability bit for AP and IBSS */ if ((AP_ENAB(wlc->pub) && shortslot == WLC_SHORTSLOT_AUTO) || shortslot == WLC_SHORTSLOT_ON) - wlc->default_bss->capability |= DOT11_CAP_SHORTSLOT; + wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_SLOT_TIME; else - wlc->default_bss->capability &= ~DOT11_CAP_SHORTSLOT; + wlc->default_bss->capability &= + ~WLAN_CAPABILITY_SHORT_SLOT_TIME; /* Use the default 11g rateset */ if (!rs.count) @@ -8280,7 +8283,7 @@ void wlc_reset_bmac_done(struct wlc_info *wlc) void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode) { wlc->ht_cap.cap &= ~HT_CAP_MIMO_PS_MASK; - wlc->ht_cap.cap |= (mimops_mode << HT_CAP_MIMO_PS_SHIFT); + wlc->ht_cap.cap |= (mimops_mode << IEEE80211_HT_CAP_SM_PS_SHIFT); if (AP_ENAB(wlc->pub) && wlc->clk) { wlc_update_beacon(wlc); diff --git a/drivers/staging/brcm80211/sys/wlc_pub.h b/drivers/staging/brcm80211/sys/wlc_pub.h index 549dd5f5d84a..ce211b9e7563 100644 --- a/drivers/staging/brcm80211/sys/wlc_pub.h +++ b/drivers/staging/brcm80211/sys/wlc_pub.h @@ -145,8 +145,9 @@ struct rsn_parms { #define AMPDU_DEF_MPDU_DENSITY 6 /* default mpdu density (110 ==> 4us) */ /* defaults for the HT (MIMO) bss */ -#define HT_CAP ((HT_CAP_MIMO_PS_OFF << HT_CAP_MIMO_PS_SHIFT) | HT_CAP_40MHZ | \ - HT_CAP_GF | HT_CAP_MAX_AMSDU | HT_CAP_DSSS_CCK) +#define HT_CAP ((HT_CAP_MIMO_PS_OFF << IEEE80211_HT_CAP_SM_PS_SHIFT) |\ + IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_GRN_FLD |\ + HT_CAP_MAX_AMSDU | IEEE80211_HT_CAP_DSSSCCK40) /* WLC packet type is a void * */ typedef void *wlc_pkt_t; diff --git a/drivers/staging/brcm80211/sys/wlc_stf.c b/drivers/staging/brcm80211/sys/wlc_stf.c index 8975b09a7438..42c7bd17d882 100644 --- a/drivers/staging/brcm80211/sys/wlc_stf.c +++ b/drivers/staging/brcm80211/sys/wlc_stf.c @@ -167,9 +167,9 @@ static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val) if ((int_val == OFF) || (wlc->stf->txstreams == 1) || !WLC_STBC_CAP_PHY(wlc)) - wlc->ht_cap.cap &= ~HT_CAP_TX_STBC; + wlc->ht_cap.cap &= ~IEEE80211_HT_CAP_TX_STBC; else - wlc->ht_cap.cap |= HT_CAP_TX_STBC; + wlc->ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC; wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = (s8) int_val; wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = (s8) int_val; -- cgit v1.2.3 From d83b2a8a89fd19f5c9bfefe5d90f30b4287c8568 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Fri, 24 Dec 2010 15:17:47 +0100 Subject: staging: brcm80211: cleaned up macros in 802.11.h Code cleanup. Cleaned up 802.11 type and subtype related macros by using Linux defines instead of Broadcom defined ones. Reviewed-by: Arend van Spriel Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/proto/802.11.h | 35 +++++------------------- drivers/staging/brcm80211/sys/wlc_mac80211.c | 22 +++++++++------ 2 files changed, 20 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/proto/802.11.h b/drivers/staging/brcm80211/include/proto/802.11.h index e559b2a50654..08aed61756c2 100644 --- a/drivers/staging/brcm80211/include/proto/802.11.h +++ b/drivers/staging/brcm80211/include/proto/802.11.h @@ -124,41 +124,20 @@ typedef struct wme_param_ie wme_param_ie_t; #define DOT11_OPEN_SYSTEM 0 #define DOT11_SHARED_KEY 1 -#define FC_TYPE_MASK 0xC -#define FC_TYPE_SHIFT 2 -#define FC_SUBTYPE_MASK 0xF0 -#define FC_SUBTYPE_SHIFT 4 - #define SEQNUM_SHIFT 4 #define SEQNUM_MAX 0x1000 #define FRAGNUM_MASK 0xF -#define FC_TYPE_MNG 0 -#define FC_TYPE_CTL 1 -#define FC_TYPE_DATA 2 - -#define FC_SUBTYPE_PROBE_REQ 4 -#define FC_SUBTYPE_PROBE_RESP 5 -#define FC_SUBTYPE_BEACON 8 -#define FC_SUBTYPE_PS_POLL 10 -#define FC_SUBTYPE_RTS 11 -#define FC_SUBTYPE_CTS 12 - -#define FC_SUBTYPE_ANY_QOS(s) (((s) & 8) != 0) +#define FC_SUBTYPE_ANY_QOS(s) ((((fc) & IEEE80211_FCTL_STYPE & (1<<7))) != 0) #define FC_KIND_MASK (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE) -#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT)) - -#define FC_SUBTYPE(fc) (((fc) & IEEE80211_FCTL_STYPE) >> FC_SUBTYPE_SHIFT) -#define FC_TYPE(fc) (((fc) & IEEE80211_FCTL_FTYPE) >> FC_TYPE_SHIFT) - -#define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ) -#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP) -#define FC_BEACON FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON) -#define FC_PS_POLL FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL) -#define FC_RTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS) -#define FC_CTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS) +#define FC_PROBE_REQ (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ) +#define FC_PROBE_RESP (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP) +#define FC_BEACON (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON) +#define FC_PS_POLL (IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL) +#define FC_RTS (IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS) +#define FC_CTS (IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS) #define TLV_LEN_OFF 1 #define TLV_HDR_LEN 2 diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 0cc79675eb4f..e454c2ecb9ec 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -5128,10 +5128,10 @@ wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, ASSERT(sdu); fc = ltoh16(d11_header->frame_control); - type = FC_TYPE(fc); + type = (fc & IEEE80211_FCTL_FTYPE); /* 802.11 standard requires management traffic to go at highest priority */ - prio = (type == FC_TYPE_DATA ? sdu->priority : MAXPRIO); + prio = (type == IEEE80211_FTYPE_DATA ? sdu->priority : MAXPRIO); fifo = prio2fifo[prio]; ASSERT((uint) skb_headroom(sdu) >= TXOFF); @@ -5705,9 +5705,10 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* locate 802.11 MAC header */ h = (struct ieee80211_hdr *)(p->data); fc = ltoh16(h->frame_control); - type = FC_TYPE(fc); + type = (fc & IEEE80211_FCTL_FTYPE); - qos = (type == FC_TYPE_DATA && FC_SUBTYPE_ANY_QOS(FC_SUBTYPE(fc))); + qos = (type == IEEE80211_FTYPE_DATA && + FC_SUBTYPE_ANY_QOS(fc)); /* compute length of frame in bytes for use in PLCP computations */ len = pkttotlen(osh, p); @@ -7053,11 +7054,13 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) /* explicitly test bad src address to avoid sending bad deauth */ if (!is_amsdu) { /* CTS and ACK CTL frames are w/o a2 */ - if (FC_TYPE(fc) == FC_TYPE_DATA || FC_TYPE(fc) == FC_TYPE_MNG) { + if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA || + (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { if ((is_zero_ether_addr(h->addr2) || is_multicast_ether_addr(h->addr2))) { - WL_ERROR("wl%d: %s: dropping a frame with invalid src mac address, a2: %pM\n", - wlc->pub->unit, __func__, &h->addr2); + WL_ERROR("wl%d: %s: dropping a frame with " + "invalid src mac address, a2: %pM\n", + wlc->pub->unit, __func__, h->addr2); WLCNTINCR(wlc->pub->_cnt->rxbadsrcmac); goto toss; } @@ -7066,7 +7069,7 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) } /* due to sheer numbers, toss out probe reqs for now */ - if (FC_TYPE(fc) == FC_TYPE_MNG) { + if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { if ((fc & FC_KIND_MASK) == FC_PROBE_REQ) goto toss; } @@ -7858,7 +7861,8 @@ int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) return BCME_BUSY; } - if (FC_TYPE(ltoh16(txh->MacFrameControl)) != FC_TYPE_DATA) + if ((ltoh16(txh->MacFrameControl) & IEEE80211_FCTL_FTYPE) != + IEEE80211_FTYPE_DATA) WLCNTINCR(wlc->pub->_cnt->txctl); return 0; -- cgit v1.2.3 From 0b8b430dda57de180bb0e83a9710c70ec5794432 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Fri, 24 Dec 2010 15:17:48 +0100 Subject: staging: brcm80211: deleted struct dot11_bcn_prb Code cleanup. This struct did nothing useful in the code. Instances of this struct and the code that read them were removed as well. Reviewed-by: Arend van Spriel Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/proto/802.11.h | 9 +-------- drivers/staging/brcm80211/sys/wlc_alloc.c | 2 -- drivers/staging/brcm80211/sys/wlc_mac80211.c | 4 ---- drivers/staging/brcm80211/sys/wlc_pub.h | 2 -- 4 files changed, 1 insertion(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/proto/802.11.h b/drivers/staging/brcm80211/include/proto/802.11.h index 08aed61756c2..c5e044a82899 100644 --- a/drivers/staging/brcm80211/include/proto/802.11.h +++ b/drivers/staging/brcm80211/include/proto/802.11.h @@ -48,14 +48,7 @@ #define DOT11_BA_BITMAP_LEN 128 #define DOT11_BA_LEN 4 -#define DOT11_MGMT_HDR_LEN 24 - -struct dot11_bcn_prb { - u32 timestamp[2]; - u16 beacon_interval; - u16 capability; -} __attribute__((packed)); -#define DOT11_BCN_PRB_LEN 12 +#define DOT11_MGMT_HDR_LEN 24 #define WME_OUI "\x00\x50\xf2" #define WME_VER 1 diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.c b/drivers/staging/brcm80211/sys/wlc_alloc.c index 02ae320d5f77..7a9fdbb5daee 100644 --- a/drivers/staging/brcm80211/sys/wlc_alloc.c +++ b/drivers/staging/brcm80211/sys/wlc_alloc.c @@ -147,8 +147,6 @@ void wlc_bsscfg_mfree(struct osl_info *osh, wlc_bsscfg_t *cfg) if (cfg->current_bss != NULL) { wlc_bss_info_t *current_bss = cfg->current_bss; - if (current_bss->bcn_prb != NULL) - kfree(current_bss->bcn_prb); kfree(current_bss); cfg->current_bss = NULL; } diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index e454c2ecb9ec..a5fbfc0f3aca 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -1746,7 +1746,6 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, ASSERT(sizeof(d11rxhdr_t) == RXHDR_LEN); ASSERT(sizeof(struct ieee80211_hdr) == DOT11_A4_HDR_LEN); ASSERT(sizeof(struct ieee80211_rts) == DOT11_RTS_LEN); - ASSERT(sizeof(struct dot11_bcn_prb) == DOT11_BCN_PRB_LEN); ASSERT(sizeof(tx_status_t) == TXSTATUS_LEN); ASSERT(sizeof(ht_cap_ie_t) == HT_CAP_IE_LEN); #ifdef BRCM_FULLMAC @@ -6979,9 +6978,6 @@ void wlc_bss_list_free(struct wlc_info *wlc, wlc_bss_list_t *bss_list) for (index = 0; index < bss_list->count; index++) { bi = bss_list->ptrs[index]; if (bi) { - if (bi->bcn_prb) { - kfree(bi->bcn_prb); - } kfree(bi); bss_list->ptrs[index] = NULL; } diff --git a/drivers/staging/brcm80211/sys/wlc_pub.h b/drivers/staging/brcm80211/sys/wlc_pub.h index ce211b9e7563..23e99685d548 100644 --- a/drivers/staging/brcm80211/sys/wlc_pub.h +++ b/drivers/staging/brcm80211/sys/wlc_pub.h @@ -180,8 +180,6 @@ typedef struct wlc_bss_info { u8 dtim_period; /* DTIM period */ s8 phy_noise; /* noise right after tx (in dBm) */ u16 capability; /* Capability information */ - struct dot11_bcn_prb *bcn_prb; /* beacon/probe response frame (ioctl na) */ - u16 bcn_prb_len; /* beacon/probe response frame length (ioctl na) */ u8 wme_qosinfo; /* QoS Info from WME IE; valid if WLC_BSS_WME flag set */ struct rsn_parms wpa; struct rsn_parms wpa2; -- cgit v1.2.3 From 651bd3a9ff2bd1c25998d5f66be3e2eb220c5910 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Fri, 24 Dec 2010 15:17:49 +0100 Subject: staging: brcm80211: replaced struct ht_cap_ie by struct ieee80211_ht_cap Code cleanup. Replaced broadcom specific type by Linux counterpart. Reviewed-by: Arend van Spriel Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/proto/802.11.h | 10 ---------- drivers/staging/brcm80211/sys/wlc_mac80211.c | 25 +++++++++++++----------- drivers/staging/brcm80211/sys/wlc_mac80211.h | 3 ++- drivers/staging/brcm80211/sys/wlc_stf.c | 11 ++++++----- 4 files changed, 22 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/proto/802.11.h b/drivers/staging/brcm80211/include/proto/802.11.h index c5e044a82899..8ca674e1a3d5 100644 --- a/drivers/staging/brcm80211/include/proto/802.11.h +++ b/drivers/staging/brcm80211/include/proto/802.11.h @@ -189,16 +189,6 @@ typedef struct d11cnt { #define MCSSET_LEN 16 -struct ht_cap_ie { - u16 cap; - u8 params; - u8 supp_mcs[MCSSET_LEN]; - u16 ext_htcap; - u32 txbf_cap; - u8 as_cap; -} __attribute__((packed)); -typedef struct ht_cap_ie ht_cap_ie_t; - #define HT_CAP_IE_LEN 26 #define HT_CAP_MIMO_PS_MASK 0x000C diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index a5fbfc0f3aca..5eb41d64bc23 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -1180,9 +1180,12 @@ void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val) static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val) { - wlc->ht_cap.cap &= ~(IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40); - wlc->ht_cap.cap |= (val & WLC_N_SGI_20) ? IEEE80211_HT_CAP_SGI_20 : 0; - wlc->ht_cap.cap |= (val & WLC_N_SGI_40) ? IEEE80211_HT_CAP_SGI_40 : 0; + wlc->ht_cap.cap_info &= ~(IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_SGI_40); + wlc->ht_cap.cap_info |= (val & WLC_N_SGI_20) ? + IEEE80211_HT_CAP_SGI_20 : 0; + wlc->ht_cap.cap_info |= (val & WLC_N_SGI_40) ? + IEEE80211_HT_CAP_SGI_40 : 0; if (wlc->pub->up) { wlc_update_beacon(wlc); @@ -1194,9 +1197,9 @@ static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val) { wlc->stf->ldpc = val; - wlc->ht_cap.cap &= ~IEEE80211_HT_CAP_LDPC_CODING; + wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_LDPC_CODING; if (wlc->stf->ldpc != OFF) - wlc->ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING; + wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_LDPC_CODING; if (wlc->pub->up) { wlc_update_beacon(wlc); @@ -1747,7 +1750,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, ASSERT(sizeof(struct ieee80211_hdr) == DOT11_A4_HDR_LEN); ASSERT(sizeof(struct ieee80211_rts) == DOT11_RTS_LEN); ASSERT(sizeof(tx_status_t) == TXSTATUS_LEN); - ASSERT(sizeof(ht_cap_ie_t) == HT_CAP_IE_LEN); + ASSERT(sizeof(struct ieee80211_ht_cap) == HT_CAP_IE_LEN); #ifdef BRCM_FULLMAC ASSERT(offsetof(wl_scan_params_t, channel_list) == WL_SCAN_PARAMS_FIXED_SIZE); @@ -1951,7 +1954,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, wlc_wme_initparams_sta(wlc, &wlc->wme_param_ie); wlc->mimoft = FT_HT; - wlc->ht_cap.cap = HT_CAP; + wlc->ht_cap.cap_info = HT_CAP; if (HT_ENAB(wlc->pub)) wlc->stf->ldpc = AUTO; @@ -1988,14 +1991,14 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, if (n_disabled & WLFEATURE_DISABLE_11N_STBC_TX) { wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF; wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF; - wlc->ht_cap.cap &= ~IEEE80211_HT_CAP_TX_STBC; + wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC; } if (n_disabled & WLFEATURE_DISABLE_11N_STBC_RX) wlc_stf_stbc_rx_set(wlc, HT_CAP_RX_STBC_NO); /* apply the GF override from nvram conf */ if (n_disabled & WLFEATURE_DISABLE_11N_GF) - wlc->ht_cap.cap &= ~IEEE80211_HT_CAP_GRN_FLD; + wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_GRN_FLD; /* initialize radio_mpc_disable according to wlc->mpc */ wlc_radio_mpc_upd(wlc); @@ -8282,8 +8285,8 @@ void wlc_reset_bmac_done(struct wlc_info *wlc) void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode) { - wlc->ht_cap.cap &= ~HT_CAP_MIMO_PS_MASK; - wlc->ht_cap.cap |= (mimops_mode << IEEE80211_HT_CAP_SM_PS_SHIFT); + wlc->ht_cap.cap_info &= ~HT_CAP_MIMO_PS_MASK; + wlc->ht_cap.cap_info |= (mimops_mode << IEEE80211_HT_CAP_SM_PS_SHIFT); if (AP_ENAB(wlc->pub) && wlc->clk) { wlc_update_beacon(wlc); diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index 72e52bf561a4..f56b58141c09 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -677,7 +677,8 @@ struct wlc_info { s8 cck_40txbw; /* 11N, cck tx b/w override when in 40MHZ mode */ s8 ofdm_40txbw; /* 11N, ofdm tx b/w override when in 40MHZ mode */ s8 mimo_40txbw; /* 11N, mimo tx b/w override when in 40MHZ mode */ - ht_cap_ie_t ht_cap; /* HT CAP IE being advertised by this node */ + /* HT CAP IE being advertised by this node: */ + struct ieee80211_ht_cap ht_cap; uint seckeys; /* 54 key table shm address */ uint tkmickeys; /* 12 TKIP MIC key table shm address */ diff --git a/drivers/staging/brcm80211/sys/wlc_stf.c b/drivers/staging/brcm80211/sys/wlc_stf.c index 42c7bd17d882..10c9f447cdf0 100644 --- a/drivers/staging/brcm80211/sys/wlc_stf.c +++ b/drivers/staging/brcm80211/sys/wlc_stf.c @@ -76,8 +76,8 @@ static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val) return; } - wlc->ht_cap.cap &= ~HT_CAP_RX_STBC_MASK; - wlc->ht_cap.cap |= (val << HT_CAP_RX_STBC_SHIFT); + wlc->ht_cap.cap_info &= ~HT_CAP_RX_STBC_MASK; + wlc->ht_cap.cap_info |= (val << HT_CAP_RX_STBC_SHIFT); if (wlc->pub->up) { wlc_update_beacon(wlc); @@ -153,7 +153,8 @@ wlc_stf_ss_algo_channel_get(struct wlc_info *wlc, u16 *ss_algo_channel, static s8 wlc_stf_stbc_rx_get(struct wlc_info *wlc) { - return (wlc->ht_cap.cap & HT_CAP_RX_STBC_MASK) >> HT_CAP_RX_STBC_SHIFT; + return (wlc->ht_cap.cap_info & HT_CAP_RX_STBC_MASK) + >> HT_CAP_RX_STBC_SHIFT; } static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val) @@ -167,9 +168,9 @@ static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val) if ((int_val == OFF) || (wlc->stf->txstreams == 1) || !WLC_STBC_CAP_PHY(wlc)) - wlc->ht_cap.cap &= ~IEEE80211_HT_CAP_TX_STBC; + wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC; else - wlc->ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC; + wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_TX_STBC; wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = (s8) int_val; wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = (s8) int_val; -- cgit v1.2.3 From 2ae44d64b770832451b112c6e3d4d5ab0aef66c2 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Wed, 19 Jan 2011 22:16:04 -0800 Subject: staging: brcm80211 dhd.h Remove CONFIG_HAS_WAKELOCK Note:not sure if there is already something like this submitted or not. The first two patches removes CONFIG_HAS_WAKELOCK since it is no longer in the kernel. Please let me know, if this is the proper way of doing this and/or more needs to be done.. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd.h | 41 -------------------------------- 1 file changed, 41 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd.h b/drivers/staging/brcm80211/brcmfmac/dhd.h index e5cdd619bdc1..5be2decca754 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd.h @@ -33,9 +33,6 @@ #include #include #include -#if defined(CONFIG_HAS_WAKELOCK) -#include -#endif /* defined (CONFIG_HAS_WAKELOCK) */ /* The kernel threading is sdio-specific */ #include @@ -145,9 +142,6 @@ typedef struct dhd_pub { u8 country_code[WLC_CNTRY_BUF_SZ]; char eventmask[WL_EVENTING_MASK_LEN]; -#if defined(CONFIG_HAS_WAKELOCK) - struct wake_lock wakelock[WAKE_LOCK_MAX]; -#endif /* defined (CONFIG_HAS_WAKELOCK) */ } dhd_pub_t; #if defined(CONFIG_PM_SLEEP) @@ -230,41 +224,6 @@ static inline void MUTEX_UNLOCK_WL_SCAN_SET(void) { } -static inline void WAKE_LOCK_INIT(dhd_pub_t *dhdp, int index, char *y) -{ -#if defined(CONFIG_HAS_WAKELOCK) - wake_lock_init(&dhdp->wakelock[index], WAKE_LOCK_SUSPEND, y); -#endif /* defined (CONFIG_HAS_WAKELOCK) */ -} - -static inline void WAKE_LOCK(dhd_pub_t *dhdp, int index) -{ -#if defined(CONFIG_HAS_WAKELOCK) - wake_lock(&dhdp->wakelock[index]); -#endif /* defined (CONFIG_HAS_WAKELOCK) */ -} - -static inline void WAKE_UNLOCK(dhd_pub_t *dhdp, int index) -{ -#if defined(CONFIG_HAS_WAKELOCK) - wake_unlock(&dhdp->wakelock[index]); -#endif /* defined (CONFIG_HAS_WAKELOCK) */ -} - -static inline void WAKE_LOCK_TIMEOUT(dhd_pub_t *dhdp, int index, long time) -{ -#if defined(CONFIG_HAS_WAKELOCK) - wake_lock_timeout(&dhdp->wakelock[index], time); -#endif /* defined (CONFIG_HAS_WAKELOCK) */ -} - -static inline void WAKE_LOCK_DESTROY(dhd_pub_t *dhdp, int index) -{ -#if defined(CONFIG_HAS_WAKELOCK) - wake_lock_destroy(&dhdp->wakelock[index]); -#endif /* defined (CONFIG_HAS_WAKELOCK) */ -} - typedef struct dhd_if_event { u8 ifidx; u8 action; -- cgit v1.2.3 From e6856764dc677aed6c1edb317f60b35194913b0d Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Wed, 19 Jan 2011 22:16:05 -0800 Subject: staging: ath6kl Remove CONFIG_HAS_WAKELOCK The patch below removes CONFIG_HAS_WAKELOCK since it is no longer in the kernel. Please let me know, if this is the proper way of doing this and/or more needs to be done.. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_android.c | 23 ------------------- drivers/staging/ath6kl/os/linux/ar6000_pm.c | 28 ------------------------ 2 files changed, 51 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/ar6000_android.c b/drivers/staging/ath6kl/os/linux/ar6000_android.c index a588825b9dab..dbde05f7ed14 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_android.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_android.c @@ -25,9 +25,6 @@ #include #include -#ifdef CONFIG_HAS_WAKELOCK -#include -#endif #ifdef CONFIG_HAS_EARLYSUSPEND #include #endif @@ -44,11 +41,6 @@ extern int bmienable; extern struct net_device *ar6000_devices[]; extern char ifname[]; -#ifdef CONFIG_HAS_WAKELOCK -extern struct wake_lock ar6k_wow_wake_lock; -struct wake_lock ar6k_init_wake_lock; -#endif - const char def_ifname[] = "wlan0"; module_param_string(fwpath, fwpath, sizeof(fwpath), 0644); module_param(enablelogcat, uint, 0644); @@ -280,14 +272,8 @@ void android_release_firmware(const struct firmware *firmware) static A_STATUS ar6000_android_avail_ev(void *context, void *hif_handle) { A_STATUS ret; -#ifdef CONFIG_HAS_WAKELOCK - wake_lock(&ar6k_init_wake_lock); -#endif ar6000_enable_mmchost_detect_change(0); ret = ar6000_avail_ev_p(context, hif_handle); -#ifdef CONFIG_HAS_WAKELOCK - wake_unlock(&ar6k_init_wake_lock); -#endif return ret; } @@ -328,9 +314,6 @@ void android_module_init(OSDRV_CALLBACKS *osdrvCallbacks) bmienable = 1; if (ifname[0] == '\0') strcpy(ifname, def_ifname); -#ifdef CONFIG_HAS_WAKELOCK - wake_lock_init(&ar6k_init_wake_lock, WAKE_LOCK_SUSPEND, "ar6k_init"); -#endif #ifdef CONFIG_HAS_EARLYSUSPEND ar6k_early_suspend.suspend = android_early_suspend; ar6k_early_suspend.resume = android_late_resume; @@ -348,9 +331,6 @@ void android_module_exit(void) { #ifdef CONFIG_HAS_EARLYSUSPEND unregister_early_suspend(&ar6k_early_suspend); -#endif -#ifdef CONFIG_HAS_WAKELOCK - wake_lock_destroy(&ar6k_init_wake_lock); #endif ar6000_enable_mmchost_detect_change(1); } @@ -395,9 +375,6 @@ void android_ar6k_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, A_BOOL i } if (needWake) { /* keep host wake up if there is any event and packate comming in*/ -#ifdef CONFIG_HAS_WAKELOCK - wake_lock_timeout(&ar6k_wow_wake_lock, 3*HZ); -#endif if (wowledon) { char buf[32]; int len = sprintf(buf, "on"); diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c index b937df9c0cb5..13195d4c7427 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_pm.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_pm.c @@ -30,23 +30,12 @@ #include #include "wlan_config.h" -#ifdef CONFIG_HAS_WAKELOCK -#include -#endif - #define WOW_ENABLE_MAX_INTERVAL 0 #define WOW_SET_SCAN_PARAMS 0 extern unsigned int wmitimeout; extern wait_queue_head_t arEvent; -#ifdef CONFIG_PM -#ifdef CONFIG_HAS_WAKELOCK -struct wake_lock ar6k_suspend_wake_lock; -struct wake_lock ar6k_wow_wake_lock; -#endif -#endif /* CONFIG_PM */ - #ifdef ANDROID_ENV extern void android_ar6k_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, A_BOOL isEvent); #endif @@ -89,9 +78,6 @@ static void ar6000_wow_resume(AR_SOFTC_T *ar) A_UINT16 bg_period = (ar->scParams.bg_period==0) ? 60 : ar->scParams.bg_period; WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {TRUE, FALSE}; ar->arWowState = WLAN_WOW_STATE_NONE; -#ifdef CONFIG_HAS_WAKELOCK - wake_lock_timeout(&ar6k_wow_wake_lock, 3*HZ); -#endif if (wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)!=A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup restore host awake\n")); } @@ -267,9 +253,6 @@ A_STATUS ar6000_resume_ev(void *context) AR_SOFTC_T *ar = (AR_SOFTC_T *)context; A_UINT16 powerState = ar->arWlanPowerState; -#ifdef CONFIG_HAS_WAKELOCK - wake_lock(&ar6k_suspend_wake_lock); -#endif AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: enter previous state %d wowState %d\n", __func__, powerState, ar->arWowState)); switch (powerState) { case WLAN_POWER_STATE_WOW: @@ -287,9 +270,6 @@ A_STATUS ar6000_resume_ev(void *context) AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange SDIO bus power mode!!\n")); break; } -#ifdef CONFIG_HAS_WAKELOCK - wake_unlock(&ar6k_suspend_wake_lock); -#endif return A_OK; } @@ -704,10 +684,6 @@ void ar6000_pm_init() { A_REGISTER_MODULE_DEBUG_INFO(pm); #ifdef CONFIG_PM -#ifdef CONFIG_HAS_WAKELOCK - wake_lock_init(&ar6k_suspend_wake_lock, WAKE_LOCK_SUSPEND, "ar6k_suspend"); - wake_lock_init(&ar6k_wow_wake_lock, WAKE_LOCK_SUSPEND, "ar6k_wow"); -#endif /* * Register ar6000_pm_device into system. * We should also add platform_device into the first item of array @@ -723,9 +699,5 @@ void ar6000_pm_exit() { #ifdef CONFIG_PM platform_driver_unregister(&ar6000_pm_device); -#ifdef CONFIG_HAS_WAKELOCK - wake_lock_destroy(&ar6k_suspend_wake_lock); - wake_lock_destroy(&ar6k_wow_wake_lock); -#endif #endif /* CONFIG_PM */ } -- cgit v1.2.3 From eee3a678835fbf8f8a5a243c7bf69d9f990a70fd Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Wed, 19 Jan 2011 22:16:06 -0800 Subject: staging: brcm80211 Remove WAKE_LOCK The patch below removes WAKE_LOCK since it is no longer in the kernel. Please let me know, if this is the proper way of doing this and/or more needs to be done.. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c | 2 -- drivers/staging/brcm80211/brcmfmac/dhd.h | 15 ----------- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 33 ----------------------- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 4 --- 4 files changed, 54 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c index d24b5e7d753c..143e8604a596 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c @@ -328,8 +328,6 @@ static irqreturn_t wlan_oob_irq(int irq, void *dev_id) return IRQ_HANDLED; } - WAKE_LOCK_TIMEOUT(dhdp, WAKE_LOCK_TMOUT, 25); - dhdsdio_isr((void *)dhdp->bus); return IRQ_HANDLED; diff --git a/drivers/staging/brcm80211/brcmfmac/dhd.h b/drivers/staging/brcm80211/brcmfmac/dhd.h index 5be2decca754..3be1bdb344ae 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd.h @@ -49,21 +49,6 @@ enum dhd_bus_state { DHD_BUS_DATA /* Ready for frame transfers */ }; -enum dhd_bus_wake_state { - WAKE_LOCK_OFF, - WAKE_LOCK_PRIV, - WAKE_LOCK_DPC, - WAKE_LOCK_IOCTL, - WAKE_LOCK_DOWNLOAD, - WAKE_LOCK_TMOUT, - WAKE_LOCK_WATCHDOG, - WAKE_LOCK_LINK_DOWN_TMOUT, - WAKE_LOCK_PNO_FIND_TMOUT, - WAKE_LOCK_SOFTAP_SET, - WAKE_LOCK_SOFTAP_STOP, - WAKE_LOCK_SOFTAP_START, - WAKE_LOCK_MAX -}; enum dhd_prealloc_index { DHD_PREALLOC_PROT = 0, DHD_PREALLOC_RXBUF, diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 508daaa731ca..28ddf1b69aac 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -1045,7 +1045,6 @@ int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf) #ifdef BCMDBUS ret = dbus_send_pkt(dhdp->dbus, pktbuf, NULL /* pktinfo */); #else - WAKE_LOCK_TIMEOUT(dhdp, WAKE_LOCK_TMOUT, 25); ret = dhd_bus_txdata(dhdp->bus, pktbuf); #endif /* BCMDBUS */ @@ -1304,7 +1303,6 @@ static struct net_device_stats *dhd_get_stats(struct net_device *net) static int dhd_watchdog_thread(void *data) { dhd_info_t *dhd = (dhd_info_t *) data; - WAKE_LOCK_INIT(&dhd->pub, WAKE_LOCK_WATCHDOG, "dhd_watchdog_thread"); /* This thread doesn't need any user-level access, * so get rid of all our resources @@ -1325,18 +1323,14 @@ static int dhd_watchdog_thread(void *data) break; if (down_interruptible(&dhd->watchdog_sem) == 0) { if (dhd->pub.dongle_reset == false) { - WAKE_LOCK(&dhd->pub, WAKE_LOCK_WATCHDOG); /* Call the bus module watchdog */ dhd_bus_watchdog(&dhd->pub); - WAKE_UNLOCK(&dhd->pub, WAKE_LOCK_WATCHDOG); } /* Count the tick for reference */ dhd->pub.tickcnt++; } else break; } - - WAKE_LOCK_DESTROY(&dhd->pub, WAKE_LOCK_WATCHDOG); return 0; } @@ -1370,7 +1364,6 @@ static int dhd_dpc_thread(void *data) { dhd_info_t *dhd = (dhd_info_t *) data; - WAKE_LOCK_INIT(&dhd->pub, WAKE_LOCK_DPC, "dhd_dpc_thread"); /* This thread doesn't need any user-level access, * so get rid of all our resources */ @@ -1393,21 +1386,15 @@ static int dhd_dpc_thread(void *data) /* Call bus dpc unless it indicated down (then clean stop) */ if (dhd->pub.busstate != DHD_BUS_DOWN) { - WAKE_LOCK(&dhd->pub, WAKE_LOCK_DPC); if (dhd_bus_dpc(dhd->pub.bus)) { up(&dhd->dpc_sem); - WAKE_LOCK_TIMEOUT(&dhd->pub, - WAKE_LOCK_TMOUT, 25); } - WAKE_UNLOCK(&dhd->pub, WAKE_LOCK_DPC); } else { dhd_bus_stop(dhd->pub.bus, true); } } else break; } - - WAKE_LOCK_DESTROY(&dhd->pub, WAKE_LOCK_DPC); return 0; } @@ -1797,14 +1784,9 @@ static int dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) if (is_set_key_cmd) dhd_wait_pend8021x(net); - WAKE_LOCK_INIT(&dhd->pub, WAKE_LOCK_IOCTL, "dhd_ioctl_entry"); - WAKE_LOCK(&dhd->pub, WAKE_LOCK_IOCTL); - bcmerror = dhd_prot_ioctl(&dhd->pub, ifidx, (wl_ioctl_t *)&ioc, buf, buflen); - WAKE_UNLOCK(&dhd->pub, WAKE_LOCK_IOCTL); - WAKE_LOCK_DESTROY(&dhd->pub, WAKE_LOCK_IOCTL); done: if (!bcmerror && buf && ioc.buf) { if (copy_to_user(ioc.buf, buf, buflen)) @@ -2115,11 +2097,6 @@ dhd_pub_t *dhd_attach(struct osl_info *osh, struct dhd_bus *bus, #endif /* defined(CONFIG_PM_SLEEP) */ /* && defined(DHD_GPL) */ /* Init lock suspend to prevent kernel going to suspend */ - WAKE_LOCK_INIT(&dhd->pub, WAKE_LOCK_TMOUT, "dhd_wake_lock"); - WAKE_LOCK_INIT(&dhd->pub, WAKE_LOCK_LINK_DOWN_TMOUT, - "dhd_wake_lock_link_dw_event"); - WAKE_LOCK_INIT(&dhd->pub, WAKE_LOCK_PNO_FIND_TMOUT, - "dhd_wake_lock_link_pno_find_event"); #ifdef CONFIG_HAS_EARLYSUSPEND dhd->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 20; dhd->early_suspend.suspend = dhd_early_suspend; @@ -2153,20 +2130,13 @@ int dhd_bus_start(dhd_pub_t *dhdp) /* try to download image and nvram to the dongle */ if (dhd->pub.busstate == DHD_BUS_DOWN) { - WAKE_LOCK_INIT(dhdp, WAKE_LOCK_DOWNLOAD, "dhd_bus_start"); - WAKE_LOCK(dhdp, WAKE_LOCK_DOWNLOAD); if (!(dhd_bus_download_firmware(dhd->pub.bus, dhd->pub.osh, fw_path, nv_path))) { DHD_ERROR(("%s: dhdsdio_probe_download failed. " "firmware = %s nvram = %s\n", __func__, fw_path, nv_path)); - WAKE_UNLOCK(dhdp, WAKE_LOCK_DOWNLOAD); - WAKE_LOCK_DESTROY(dhdp, WAKE_LOCK_DOWNLOAD); return -1; } - - WAKE_UNLOCK(dhdp, WAKE_LOCK_DOWNLOAD); - WAKE_LOCK_DESTROY(dhdp, WAKE_LOCK_DOWNLOAD); } /* Start the watchdog timer */ @@ -2432,9 +2402,6 @@ void dhd_detach(dhd_pub_t *dhdp) unregister_pm_notifier(&dhd_sleep_pm_notifier); #endif /* defined(CONFIG_PM_SLEEP) */ /* && defined(DHD_GPL) */ - WAKE_LOCK_DESTROY(dhdp, WAKE_LOCK_TMOUT); - WAKE_LOCK_DESTROY(dhdp, WAKE_LOCK_LINK_DOWN_TMOUT); - WAKE_LOCK_DESTROY(dhdp, WAKE_LOCK_PNO_FIND_TMOUT); free_netdev(ifp->net); kfree(ifp); kfree(dhd); diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index c039ef18903f..7167d4735e2a 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -3419,8 +3419,6 @@ void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) if (!(flags & WLC_EVENT_MSG_LINK)) { memset(wrqu.addr.sa_data, 0, ETH_ALEN); memset(&extra, 0, ETH_ALEN); - WAKE_LOCK_TIMEOUT(iw->pub, WAKE_LOCK_LINK_DOWN_TMOUT, - 20 * HZ); } else { memcpy(wrqu.addr.sa_data, &e->addr, ETH_ALEN); WL_TRACE("Link UP\n"); @@ -3533,8 +3531,6 @@ void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) WL_ERROR("%s Event WLC_E_PFN_NET_FOUND, send %s up : find %s len=%d\n", __func__, PNO_EVENT_UP, ssid->SSID, ssid->SSID_len); - WAKE_LOCK_TIMEOUT(iw->pub, WAKE_LOCK_PNO_FIND_TMOUT, - 20 * HZ); cmd = IWEVCUSTOM; memset(&wrqu, 0, sizeof(wrqu)); strcpy(extra, PNO_EVENT_UP); -- cgit v1.2.3 From 0bbfc0edb7a2606829dfcb5c6926f20adfc68d91 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 12 Jan 2011 13:21:19 -0800 Subject: staging: brcm80211: Remove unnecessary memset(,0,) kzalloc'd memory doesn't need a memset to 0. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 55b9ceee4200..6a552bd5c90b 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -703,7 +703,6 @@ wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action) params = kzalloc(params_size, GFP_KERNEL); if (unlikely(!params)) return -ENOMEM; - memset(params, 0, params_size); BUG_ON(unlikely(params_size >= WLC_IOCTL_SMLEN)); wl_iscan_prep(¶ms->params, ssid); -- cgit v1.2.3 From 628f34282db49359576dcb8cbaea65b4bf083ebd Mon Sep 17 00:00:00 2001 From: Christopher Brannon Date: Sun, 19 Dec 2010 22:50:24 +0000 Subject: staging: speakup: more fixes for init-failure handling. We still leaked many resources when Speakup failed to initialize. Examples of leaked resources include: /dev/synth, keyboard or VT notifiers, and heap-allocated st_spk_t structs. This is fixed. * We now use PTR_ERR to detect kthread_create failure (thank you Dan Carpenter). * The loop which frees members of the speakup_console array now iterates over the whole array, not stopping at the first NULL value. Fixes a possible memory leak. Safe because kfree(NULL) is a no-op. * The order of some initializations was changed. The safe ones, which will never fail, are performed first. Signed-off-by: Christopher Brannon Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/main.c | 127 ++++++++++++++++++++++++++++------------- 1 file changed, 88 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index 3cd00396a462..cd981a13c12d 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -1283,7 +1283,7 @@ static int edit_bits(struct vc_data *vc, u_char type, u_char ch, u_short key) } /* Allocation concurrency is protected by the console semaphore */ -void speakup_allocate(struct vc_data *vc) +int speakup_allocate(struct vc_data *vc) { int vc_num; @@ -1292,10 +1292,12 @@ void speakup_allocate(struct vc_data *vc) speakup_console[vc_num] = kzalloc(sizeof(*speakup_console[0]), GFP_ATOMIC); if (speakup_console[vc_num] == NULL) - return; + return -ENOMEM; speakup_date(vc); } else if (!spk_parked) speakup_date(vc); + + return 0; } void speakup_deallocate(struct vc_data *vc) @@ -2217,18 +2219,23 @@ static void __exit speakup_exit(void) { int i; - free_user_msgs(); unregister_keyboard_notifier(&keyboard_notifier_block); unregister_vt_notifier(&vt_notifier_block); speakup_unregister_devsynth(); del_timer(&cursor_timer); - kthread_stop(speakup_task); speakup_task = NULL; mutex_lock(&spk_mutex); synth_release(); mutex_unlock(&spk_mutex); + speakup_kobj_exit(); + + for (i = 0; i < MAX_NR_CONSOLES; i++) + kfree(speakup_console[i]); + + speakup_remove_virtual_keyboard(); + for (i = 0; i < MAXVARS; i++) speakup_unregister_var(i); @@ -2236,42 +2243,23 @@ static void __exit speakup_exit(void) if (characters[i] != default_chars[i]) kfree(characters[i]); } - for (i = 0; speakup_console[i]; i++) - kfree(speakup_console[i]); - speakup_kobj_exit(); - speakup_remove_virtual_keyboard(); + + free_user_msgs(); } /* call by: module_init() */ static int __init speakup_init(void) { int i; - int err; + long err = 0; struct st_spk_t *first_console; struct vc_data *vc = vc_cons[fg_console].d; struct var_t *var; - err = speakup_add_virtual_keyboard(); - if (err) - goto out; - + /* These first few initializations cannot fail. */ initialize_msgs(); /* Initialize arrays for i18n. */ - first_console = kzalloc(sizeof(*first_console), GFP_KERNEL); - if (!first_console) { - err = -ENOMEM; - goto err_cons; - } - err = speakup_kobj_init(); - if (err) - goto err_kobject; - reset_default_chars(); reset_default_chartab(); - - speakup_console[vc->vc_num] = first_console; - speakup_date(vc); - pr_info("speakup %s: initialized\n", SPEAKUP_VERSION); - strlwr(synth_name); spk_vars[0].u.n.high = vc->vc_cols; for (var = spk_vars; var->var_id != MAXVARS; var++) @@ -2286,31 +2274,92 @@ static int __init speakup_init(void) if (quiet_boot) spk_shut_up |= 0x01; + /* From here on out, initializations can fail. */ + err = speakup_add_virtual_keyboard(); + if (err) + goto error_virtkeyboard; + + first_console = kzalloc(sizeof(*first_console), GFP_KERNEL); + if (!first_console) { + err = -ENOMEM; + goto error_alloc; + } + + speakup_console[vc->vc_num] = first_console; + speakup_date(vc); + for (i = 0; i < MAX_NR_CONSOLES; i++) - if (vc_cons[i].d) - speakup_allocate(vc_cons[i].d); + if (vc_cons[i].d) { + err = speakup_allocate(vc_cons[i].d); + if (err) + goto error_kobjects; + } + + err = speakup_kobj_init(); + if (err) + goto error_kobjects; - pr_warn("synth name on entry is: %s\n", synth_name); synth_init(synth_name); speakup_register_devsynth(); + /* + * register_devsynth might fail, but this error is not fatal. + * /dev/synth is an extra feature; the rest of Speakup + * will work fine without it. + */ - register_keyboard_notifier(&keyboard_notifier_block); - register_vt_notifier(&vt_notifier_block); + err = register_keyboard_notifier(&keyboard_notifier_block); + if (err) + goto error_kbdnotifier; + err = register_vt_notifier(&vt_notifier_block); + if (err) + goto error_vtnotifier; speakup_task = kthread_create(speakup_thread, NULL, "speakup"); - set_user_nice(speakup_task, 10); + if (IS_ERR(speakup_task)) { - err = -ENOMEM; - goto err_kobject; + err = PTR_ERR(speakup_task); + goto error_task; } + + set_user_nice(speakup_task, 10); wake_up_process(speakup_task); + + pr_info("speakup %s: initialized\n", SPEAKUP_VERSION); + pr_info("synth name on entry is: %s\n", synth_name); goto out; -err_kobject: -speakup_kobj_exit(); - kfree(first_console); -err_cons: +error_task: + unregister_vt_notifier(&vt_notifier_block); + +error_vtnotifier: + unregister_keyboard_notifier(&keyboard_notifier_block); + del_timer(&cursor_timer); + +error_kbdnotifier: + speakup_unregister_devsynth(); + mutex_lock(&spk_mutex); + synth_release(); + mutex_unlock(&spk_mutex); + speakup_kobj_exit(); + +error_kobjects: + for (i = 0; i < MAX_NR_CONSOLES; i++) + kfree(speakup_console[i]); + +error_alloc: speakup_remove_virtual_keyboard(); + +error_virtkeyboard: + for (i = 0; i < MAXVARS; i++) + speakup_unregister_var(i); + + for (i = 0; i < 256; i++) { + if (characters[i] != default_chars[i]) + kfree(characters[i]); + } + + free_user_msgs(); + out: return err; } -- cgit v1.2.3 From 977016882d62ae5124a42bc9959d8785eb143655 Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Thu, 23 Dec 2010 01:23:56 -0600 Subject: drivers:staging: ti-st: add the v7 btwilink driver Add the btwilink driver which has undergone 7 revisions of review. Based on bluetooth maintainer comments, since there might be some re-work needed on underlying ST driver, park the driver here. Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ti-st/btwilink.c | 363 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 363 insertions(+) create mode 100644 drivers/staging/ti-st/btwilink.c (limited to 'drivers') diff --git a/drivers/staging/ti-st/btwilink.c b/drivers/staging/ti-st/btwilink.c new file mode 100644 index 000000000000..71e69f8394c9 --- /dev/null +++ b/drivers/staging/ti-st/btwilink.c @@ -0,0 +1,363 @@ +/* + * Texas Instrument's Bluetooth Driver For Shared Transport. + * + * Bluetooth Driver acts as interface between HCI core and + * TI Shared Transport Layer. + * + * Copyright (C) 2009-2010 Texas Instruments + * Author: Raja Mani + * Pavan Savoy + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include + +#include + +/* Bluetooth Driver Version */ +#define VERSION "1.0" + +/* Number of seconds to wait for registration completion + * when ST returns PENDING status. + */ +#define BT_REGISTER_TIMEOUT 6000 /* 6 sec */ + +/** + * struct ti_st - driver operation structure + * @hdev: hci device pointer which binds to bt driver + * @reg_status: ST registration callback status + * @st_write: write function provided by the ST driver + * to be used by the driver during send_frame. + * @wait_reg_completion - completion sync between ti_st_open + * and ti_st_registration_completion_cb. + */ +struct ti_st { + struct hci_dev *hdev; + char reg_status; + long (*st_write) (struct sk_buff *); + struct completion wait_reg_completion; +}; + +/* Increments HCI counters based on pocket ID (cmd,acl,sco) */ +static inline void ti_st_tx_complete(struct ti_st *hst, int pkt_type) +{ + struct hci_dev *hdev = hst->hdev; + + /* Update HCI stat counters */ + switch (pkt_type) { + case HCI_COMMAND_PKT: + hdev->stat.cmd_tx++; + break; + + case HCI_ACLDATA_PKT: + hdev->stat.acl_tx++; + break; + + case HCI_SCODATA_PKT: + hdev->stat.sco_tx++; + break; + } +} + +/* ------- Interfaces to Shared Transport ------ */ + +/* Called by ST layer to indicate protocol registration completion + * status.ti_st_open() function will wait for signal from this + * API when st_register() function returns ST_PENDING. + */ +static void st_registration_completion_cb(void *priv_data, char data) +{ + struct ti_st *lhst = priv_data; + + /* Save registration status for use in ti_st_open() */ + lhst->reg_status = data; + /* complete the wait in ti_st_open() */ + complete(&lhst->wait_reg_completion); +} + +/* Called by Shared Transport layer when receive data is + * available */ +static long st_receive(void *priv_data, struct sk_buff *skb) +{ + struct ti_st *lhst = priv_data; + int err; + + if (!skb) + return -EFAULT; + + if (!lhst) { + kfree_skb(skb); + return -EFAULT; + } + + skb->dev = (void *) lhst->hdev; + + /* Forward skb to HCI core layer */ + err = hci_recv_frame(skb); + if (err < 0) { + BT_ERR("Unable to push skb to HCI core(%d)", err); + return err; + } + + lhst->hdev->stat.byte_rx += skb->len; + + return 0; +} + +/* ------- Interfaces to HCI layer ------ */ +/* protocol structure registered with shared transport */ +static struct st_proto_s ti_st_proto = { + .type = ST_BT, + .recv = st_receive, + .reg_complete_cb = st_registration_completion_cb, +}; + +/* Called from HCI core to initialize the device */ +static int ti_st_open(struct hci_dev *hdev) +{ + unsigned long timeleft; + struct ti_st *hst; + int err; + + BT_DBG("%s %p", hdev->name, hdev); + if (test_and_set_bit(HCI_RUNNING, &hdev->flags)) { + BT_ERR("btwilink already opened"); + return -EBUSY; + } + + /* provide contexts for callbacks from ST */ + hst = hdev->driver_data; + ti_st_proto.priv_data = hst; + + err = st_register(&ti_st_proto); + if (err == -EINPROGRESS) { + /* ST is busy with either protocol registration or firmware + * download. + */ + /* Prepare wait-for-completion handler data structures. + */ + init_completion(&hst->wait_reg_completion); + + /* Reset ST registration callback status flag , this value + * will be updated in ti_st_registration_completion_cb() + * function whenever it called from ST driver. + */ + hst->reg_status = -EINPROGRESS; + + BT_DBG("waiting for registration completion signal from ST"); + timeleft = wait_for_completion_timeout + (&hst->wait_reg_completion, + msecs_to_jiffies(BT_REGISTER_TIMEOUT)); + if (!timeleft) { + clear_bit(HCI_RUNNING, &hdev->flags); + BT_ERR("Timeout(%d sec),didn't get reg " + "completion signal from ST", + BT_REGISTER_TIMEOUT / 1000); + return -ETIMEDOUT; + } + + /* Is ST registration callback called with ERROR status? */ + if (hst->reg_status != 0) { + clear_bit(HCI_RUNNING, &hdev->flags); + BT_ERR("ST registration completed with invalid " + "status %d", hst->reg_status); + return -EAGAIN; + } + err = 0; + } else if (err != 0) { + clear_bit(HCI_RUNNING, &hdev->flags); + BT_ERR("st_register failed %d", err); + return err; + } + + /* ti_st_proto.write is filled up by the underlying shared + * transport driver upon registration + */ + hst->st_write = ti_st_proto.write; + if (!hst->st_write) { + BT_ERR("undefined ST write function"); + clear_bit(HCI_RUNNING, &hdev->flags); + + /* Undo registration with ST */ + err = st_unregister(ST_BT); + if (err) + BT_ERR("st_unregister() failed with error %d", err); + + hst->st_write = NULL; + return err; + } + + return err; +} + +/* Close device */ +static int ti_st_close(struct hci_dev *hdev) +{ + int err; + struct ti_st *hst = hdev->driver_data; + + if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) + return 0; + + /* continue to unregister from transport */ + err = st_unregister(ST_BT); + if (err) + BT_ERR("st_unregister() failed with error %d", err); + + hst->st_write = NULL; + + return err; +} + +static int ti_st_send_frame(struct sk_buff *skb) +{ + struct hci_dev *hdev; + struct ti_st *hst; + long len; + + hdev = (struct hci_dev *)skb->dev; + + if (!test_bit(HCI_RUNNING, &hdev->flags)) + return -EBUSY; + + hst = hdev->driver_data; + + /* Prepend skb with frame type */ + memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); + + BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, + skb->len); + + /* Insert skb to shared transport layer's transmit queue. + * Freeing skb memory is taken care in shared transport layer, + * so don't free skb memory here. + */ + len = hst->st_write(skb); + if (len < 0) { + kfree_skb(skb); + BT_ERR("ST write failed (%ld)", len); + /* Try Again, would only fail if UART has gone bad */ + return -EAGAIN; + } + + /* ST accepted our skb. So, Go ahead and do rest */ + hdev->stat.byte_tx += len; + ti_st_tx_complete(hst, bt_cb(skb)->pkt_type); + + return 0; +} + +static void ti_st_destruct(struct hci_dev *hdev) +{ + BT_DBG("%s", hdev->name); + kfree(hdev->driver_data); +} + +static int bt_ti_probe(struct platform_device *pdev) +{ + static struct ti_st *hst; + struct hci_dev *hdev; + int err; + + hst = kzalloc(sizeof(struct ti_st), GFP_KERNEL); + if (!hst) + return -ENOMEM; + + /* Expose "hciX" device to user space */ + hdev = hci_alloc_dev(); + if (!hdev) { + kfree(hst); + return -ENOMEM; + } + + BT_DBG("hdev %p", hdev); + + hst->hdev = hdev; + hdev->bus = HCI_UART; + hdev->driver_data = hst; + hdev->open = ti_st_open; + hdev->close = ti_st_close; + hdev->flush = NULL; + hdev->send = ti_st_send_frame; + hdev->destruct = ti_st_destruct; + hdev->owner = THIS_MODULE; + + err = hci_register_dev(hdev); + if (err < 0) { + BT_ERR("Can't register HCI device error %d", err); + kfree(hst); + hci_free_dev(hdev); + return err; + } + + BT_DBG("HCI device registered (hdev %p)", hdev); + + dev_set_drvdata(&pdev->dev, hst); + return err; +} + +static int bt_ti_remove(struct platform_device *pdev) +{ + struct hci_dev *hdev; + struct ti_st *hst = dev_get_drvdata(&pdev->dev); + + if (!hst) + return -EFAULT; + + hdev = hst->hdev; + ti_st_close(hdev); + hci_unregister_dev(hdev); + + hci_free_dev(hdev); + kfree(hst); + + dev_set_drvdata(&pdev->dev, NULL); + return 0; +} + +static struct platform_driver btwilink_driver = { + .probe = bt_ti_probe, + .remove = bt_ti_remove, + .driver = { + .name = "btwilink", + .owner = THIS_MODULE, + }, +}; + +/* ------- Module Init/Exit interfaces ------ */ +static int __init btwilink_init(void) +{ + BT_INFO("Bluetooth Driver for TI WiLink - Version %s", VERSION); + + return platform_driver_register(&btwilink_driver); +} + +static void __exit btwilink_exit(void) +{ + platform_driver_unregister(&btwilink_driver); +} + +module_init(btwilink_init); +module_exit(btwilink_exit); + +/* ------ Module Info ------ */ + +MODULE_AUTHOR("Raja Mani "); +MODULE_DESCRIPTION("Bluetooth Driver for TI Shared Transport" VERSION); +MODULE_VERSION(VERSION); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 4a5200ac8bd0e1a85aacea7cf4ded6e597254be0 Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Thu, 23 Dec 2010 01:23:57 -0600 Subject: drivers:staging: ti-st: delete old bt_drv driver point the new v7 driver to build if ST_BT is selected in Makefile and delete the old bt_drv driver. Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ti-st/Makefile | 2 +- drivers/staging/ti-st/bt_drv.c | 509 ----------------------------------------- drivers/staging/ti-st/bt_drv.h | 61 ----- 3 files changed, 1 insertion(+), 571 deletions(-) delete mode 100644 drivers/staging/ti-st/bt_drv.c delete mode 100644 drivers/staging/ti-st/bt_drv.h (limited to 'drivers') diff --git a/drivers/staging/ti-st/Makefile b/drivers/staging/ti-st/Makefile index 5f11b82c016c..9125462807d4 100644 --- a/drivers/staging/ti-st/Makefile +++ b/drivers/staging/ti-st/Makefile @@ -2,4 +2,4 @@ # Makefile for TI's shared transport line discipline # and its protocol drivers (BT, FM, GPS) # -obj-$(CONFIG_ST_BT) += bt_drv.o +obj-$(CONFIG_ST_BT) += btwilink.o diff --git a/drivers/staging/ti-st/bt_drv.c b/drivers/staging/ti-st/bt_drv.c deleted file mode 100644 index 75065bf39e5c..000000000000 --- a/drivers/staging/ti-st/bt_drv.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Texas Instrument's Bluetooth Driver For Shared Transport. - * - * Bluetooth Driver acts as interface between HCI CORE and - * TI Shared Transport Layer. - * - * Copyright (C) 2009 Texas Instruments - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include - -#include -#include "bt_drv.h" - -/* Define this macro to get debug msg */ -#undef DEBUG - -#ifdef DEBUG -#define BT_DRV_DBG(fmt, arg...) printk(KERN_INFO "(btdrv):"fmt"\n" , ## arg) -#define BTDRV_API_START() printk(KERN_INFO "(btdrv): %s Start\n", \ - __func__) -#define BTDRV_API_EXIT(errno) printk(KERN_INFO "(btdrv): %s Exit(%d)\n", \ - __func__, errno) -#else -#define BT_DRV_DBG(fmt, arg...) -#define BTDRV_API_START() -#define BTDRV_API_EXIT(errno) -#endif - -#define BT_DRV_ERR(fmt, arg...) printk(KERN_ERR "(btdrv):"fmt"\n" , ## arg) - -static int reset; -static struct hci_st *hst; - -/* Increments HCI counters based on pocket ID (cmd,acl,sco) */ -static inline void hci_st_tx_complete(struct hci_st *hst, int pkt_type) -{ - struct hci_dev *hdev; - - BTDRV_API_START(); - - hdev = hst->hdev; - - /* Update HCI stat counters */ - switch (pkt_type) { - case HCI_COMMAND_PKT: - hdev->stat.cmd_tx++; - break; - - case HCI_ACLDATA_PKT: - hdev->stat.acl_tx++; - break; - - case HCI_SCODATA_PKT: - hdev->stat.cmd_tx++; - break; - } - - BTDRV_API_EXIT(0); -} - -/* ------- Interfaces to Shared Transport ------ */ - -/* Called by ST layer to indicate protocol registration completion - * status.hci_st_open() function will wait for signal from this - * API when st_register() function returns ST_PENDING. - */ -static void hci_st_registration_completion_cb(void *priv_data, char data) -{ - struct hci_st *lhst = (struct hci_st *)priv_data; - BTDRV_API_START(); - - /* hci_st_open() function needs value of 'data' to know - * the registration status(success/fail),So have a back - * up of it. - */ - lhst->streg_cbdata = data; - - /* Got a feedback from ST for BT driver registration - * request.Wackup hci_st_open() function to continue - * it's open operation. - */ - complete(&lhst->wait_for_btdrv_reg_completion); - - BTDRV_API_EXIT(0); -} - -/* Called by Shared Transport layer when receive data is - * available */ -static long hci_st_receive(void *priv_data, struct sk_buff *skb) -{ - int err; - int len; - struct hci_st *lhst = (struct hci_st *)priv_data; - - BTDRV_API_START(); - - err = 0; - len = 0; - - if (skb == NULL) { - BT_DRV_ERR("Invalid SKB received from ST"); - BTDRV_API_EXIT(-EFAULT); - return -EFAULT; - } - if (!lhst) { - kfree_skb(skb); - BT_DRV_ERR("Invalid hci_st memory,freeing SKB"); - BTDRV_API_EXIT(-EFAULT); - return -EFAULT; - } - if (!test_bit(BT_DRV_RUNNING, &lhst->flags)) { - kfree_skb(skb); - BT_DRV_ERR("Device is not running,freeing SKB"); - BTDRV_API_EXIT(-EINVAL); - return -EINVAL; - } - - len = skb->len; - skb->dev = (struct net_device *)lhst->hdev; - - /* Forward skb to HCI CORE layer */ - err = hci_recv_frame(skb); - if (err) { - kfree_skb(skb); - BT_DRV_ERR("Unable to push skb to HCI CORE(%d),freeing SKB", - err); - BTDRV_API_EXIT(err); - return err; - } - lhst->hdev->stat.byte_rx += len; - - BTDRV_API_EXIT(0); - return 0; -} - -/* ------- Interfaces to HCI layer ------ */ - -/* Called from HCI core to initialize the device */ -static int hci_st_open(struct hci_dev *hdev) -{ - static struct st_proto_s hci_st_proto; - unsigned long timeleft; - int err; - - BTDRV_API_START(); - - err = 0; - - BT_DRV_DBG("%s %p", hdev->name, hdev); - - /* Already registered with ST ? */ - if (test_bit(BT_ST_REGISTERED, &hst->flags)) { - BT_DRV_ERR("Registered with ST already,open called again?"); - BTDRV_API_EXIT(0); - return 0; - } - - /* Populate BT driver info required by ST */ - memset(&hci_st_proto, 0, sizeof(hci_st_proto)); - - /* BT driver ID */ - hci_st_proto.type = ST_BT; - - /* Receive function which called from ST */ - hci_st_proto.recv = hci_st_receive; - - /* Packet match function may used in future */ - hci_st_proto.match_packet = NULL; - - /* Callback to be called when registration is pending */ - hci_st_proto.reg_complete_cb = hci_st_registration_completion_cb; - - /* This is write function pointer of ST. BT driver will make use of this - * for sending any packets to chip. ST will assign and give to us, so - * make it as NULL */ - hci_st_proto.write = NULL; - - /* send in the hst to be received at registration complete callback - * and during st's receive - */ - hci_st_proto.priv_data = hst; - - /* Register with ST layer */ - err = st_register(&hci_st_proto); - if (err == -EINPROGRESS) { - /* Prepare wait-for-completion handler data structures. - * Needed to syncronize this and st_registration_completion_cb() - * functions. - */ - init_completion(&hst->wait_for_btdrv_reg_completion); - - /* Reset ST registration callback status flag , this value - * will be updated in hci_st_registration_completion_cb() - * function whenever it called from ST driver. - */ - hst->streg_cbdata = -EINPROGRESS; - - /* ST is busy with other protocol registration(may be busy with - * firmware download).So,Wait till the registration callback - * (passed as a argument to st_register() function) getting - * called from ST. - */ - BT_DRV_DBG(" %s waiting for reg completion signal from ST", - __func__); - - timeleft = - wait_for_completion_timeout - (&hst->wait_for_btdrv_reg_completion, - msecs_to_jiffies(BT_REGISTER_TIMEOUT)); - if (!timeleft) { - BT_DRV_ERR("Timeout(%ld sec),didn't get reg" - "completion signal from ST", - BT_REGISTER_TIMEOUT / 1000); - BTDRV_API_EXIT(-ETIMEDOUT); - return -ETIMEDOUT; - } - - /* Is ST registration callback called with ERROR value? */ - if (hst->streg_cbdata != 0) { - BT_DRV_ERR("ST reg completion CB called with invalid" - "status %d", hst->streg_cbdata); - BTDRV_API_EXIT(-EAGAIN); - return -EAGAIN; - } - err = 0; - } else if (err == -1) { - BT_DRV_ERR("st_register failed %d", err); - BTDRV_API_EXIT(-EAGAIN); - return -EAGAIN; - } - - /* Do we have proper ST write function? */ - if (hci_st_proto.write != NULL) { - /* We need this pointer for sending any Bluetooth pkts */ - hst->st_write = hci_st_proto.write; - } else { - BT_DRV_ERR("failed to get ST write func pointer"); - - /* Undo registration with ST */ - err = st_unregister(ST_BT); - if (err < 0) - BT_DRV_ERR("st_unregister failed %d", err); - - hst->st_write = NULL; - BTDRV_API_EXIT(-EAGAIN); - return -EAGAIN; - } - - /* Registration with ST layer is completed successfully, - * now chip is ready to accept commands from HCI CORE. - * Mark HCI Device flag as RUNNING - */ - set_bit(HCI_RUNNING, &hdev->flags); - - /* Registration with ST successful */ - set_bit(BT_ST_REGISTERED, &hst->flags); - - BTDRV_API_EXIT(err); - return err; -} - -/* Close device */ -static int hci_st_close(struct hci_dev *hdev) -{ - int err; - - BTDRV_API_START(); - - err = 0; - - /* Unregister from ST layer */ - if (test_and_clear_bit(BT_ST_REGISTERED, &hst->flags)) { - err = st_unregister(ST_BT); - if (err != 0) { - BT_DRV_ERR("st_unregister failed %d", err); - BTDRV_API_EXIT(-EBUSY); - return -EBUSY; - } - } - - hst->st_write = NULL; - - /* ST layer would have moved chip to inactive state. - * So,clear HCI device RUNNING flag. - */ - if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) { - BTDRV_API_EXIT(0); - return 0; - } - - BTDRV_API_EXIT(err); - return err; -} - -/* Called from HCI CORE , Sends frames to Shared Transport */ -static int hci_st_send_frame(struct sk_buff *skb) -{ - struct hci_dev *hdev; - struct hci_st *hst; - long len; - - BTDRV_API_START(); - - if (skb == NULL) { - BT_DRV_ERR("Invalid skb received from HCI CORE"); - BTDRV_API_EXIT(-ENOMEM); - return -ENOMEM; - } - hdev = (struct hci_dev *)skb->dev; - if (!hdev) { - BT_DRV_ERR("SKB received for invalid HCI Device (hdev=NULL)"); - BTDRV_API_EXIT(-ENODEV); - return -ENODEV; - } - if (!test_bit(HCI_RUNNING, &hdev->flags)) { - BT_DRV_ERR("Device is not running"); - BTDRV_API_EXIT(-EBUSY); - return -EBUSY; - } - - hst = (struct hci_st *)hdev->driver_data; - - /* Prepend skb with frame type */ - memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); - - BT_DRV_DBG(" %s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, - skb->len); - - /* Insert skb to shared transport layer's transmit queue. - * Freeing skb memory is taken care in shared transport layer, - * so don't free skb memory here. - */ - if (!hst->st_write) { - kfree_skb(skb); - BT_DRV_ERR(" Can't write to ST, st_write null?"); - BTDRV_API_EXIT(-EAGAIN); - return -EAGAIN; - } - len = hst->st_write(skb); - if (len < 0) { - /* Something went wrong in st write , free skb memory */ - kfree_skb(skb); - BT_DRV_ERR(" ST write failed (%ld)", len); - BTDRV_API_EXIT(-EAGAIN); - return -EAGAIN; - } - - /* ST accepted our skb. So, Go ahead and do rest */ - hdev->stat.byte_tx += len; - hci_st_tx_complete(hst, bt_cb(skb)->pkt_type); - - BTDRV_API_EXIT(0); - return 0; -} - -static void hci_st_destruct(struct hci_dev *hdev) -{ - BTDRV_API_START(); - - if (!hdev) { - BT_DRV_ERR("Destruct called with invalid HCI Device" - "(hdev=NULL)"); - BTDRV_API_EXIT(0); - return; - } - - BT_DRV_DBG("%s", hdev->name); - - /* free hci_st memory */ - if (hdev->driver_data != NULL) - kfree(hdev->driver_data); - - BTDRV_API_EXIT(0); - return; -} - -/* Creates new HCI device */ -static int hci_st_register_dev(struct hci_st *hst) -{ - struct hci_dev *hdev; - - BTDRV_API_START(); - - /* Initialize and register HCI device */ - hdev = hci_alloc_dev(); - if (!hdev) { - BT_DRV_ERR("Can't allocate HCI device"); - BTDRV_API_EXIT(-ENOMEM); - return -ENOMEM; - } - BT_DRV_DBG(" HCI device allocated. hdev= %p", hdev); - - hst->hdev = hdev; - hdev->bus = HCI_UART; - hdev->driver_data = hst; - hdev->open = hci_st_open; - hdev->close = hci_st_close; - hdev->flush = NULL; - hdev->send = hci_st_send_frame; - hdev->destruct = hci_st_destruct; - hdev->owner = THIS_MODULE; - - if (reset) - set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); - - if (hci_register_dev(hdev) < 0) { - BT_DRV_ERR("Can't register HCI device"); - hci_free_dev(hdev); - BTDRV_API_EXIT(-ENODEV); - return -ENODEV; - } - - BT_DRV_DBG(" HCI device registered. hdev= %p", hdev); - BTDRV_API_EXIT(0); - return 0; -} - -/* ------- Module Init interface ------ */ - -static int __init bt_drv_init(void) -{ - int err; - - BTDRV_API_START(); - - err = 0; - - BT_DRV_DBG(" Bluetooth Driver Version %s", VERSION); - - /* Allocate local resource memory */ - hst = kzalloc(sizeof(struct hci_st), GFP_KERNEL); - if (!hst) { - BT_DRV_ERR("Can't allocate control structure"); - BTDRV_API_EXIT(-ENFILE); - return -ENFILE; - } - - /* Expose "hciX" device to user space */ - err = hci_st_register_dev(hst); - if (err) { - /* Release local resource memory */ - kfree(hst); - - BT_DRV_ERR("Unable to expose hci0 device(%d)", err); - BTDRV_API_EXIT(err); - return err; - } - set_bit(BT_DRV_RUNNING, &hst->flags); - - BTDRV_API_EXIT(err); - return err; -} - -/* ------- Module Exit interface ------ */ - -static void __exit bt_drv_exit(void) -{ - BTDRV_API_START(); - - /* Deallocate local resource's memory */ - if (hst) { - struct hci_dev *hdev = hst->hdev; - - if (hdev == NULL) { - BT_DRV_ERR("Invalid hdev memory"); - kfree(hst); - } else { - hci_st_close(hdev); - if (test_and_clear_bit(BT_DRV_RUNNING, &hst->flags)) { - /* Remove HCI device (hciX) created - * in module init. - */ - hci_unregister_dev(hdev); - - /* Free HCI device memory */ - hci_free_dev(hdev); - } - } - } - BTDRV_API_EXIT(0); -} - -module_init(bt_drv_init); -module_exit(bt_drv_exit); - -/* ------ Module Info ------ */ - -module_param(reset, bool, 0644); -MODULE_PARM_DESC(reset, "Send HCI reset command on initialization"); -MODULE_AUTHOR("Raja Mani "); -MODULE_DESCRIPTION("Bluetooth Driver for TI Shared Transport" VERSION); -MODULE_VERSION(VERSION); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/ti-st/bt_drv.h b/drivers/staging/ti-st/bt_drv.h deleted file mode 100644 index a0beebec8465..000000000000 --- a/drivers/staging/ti-st/bt_drv.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Texas Instrument's Bluetooth Driver For Shared Transport. - * - * Bluetooth Driver acts as interface between HCI CORE and - * TI Shared Transport Layer. - * - * Copyright (C) 2009 Texas Instruments - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef _BT_DRV_H -#define _BT_DRV_H - -/* Bluetooth Driver Version */ -#define VERSION "1.0" - -/* Defines number of seconds to wait for reg completion - * callback getting called from ST (in case,registration - * with ST returns PENDING status) - */ -#define BT_REGISTER_TIMEOUT msecs_to_jiffies(6000) /* 6 sec */ - -/* BT driver's local status */ -#define BT_DRV_RUNNING 0 -#define BT_ST_REGISTERED 1 - -/* BT driver operation structure */ -struct hci_st { - - /* hci device pointer which binds to bt driver */ - struct hci_dev *hdev; - - /* used locally,to maintain various BT driver status */ - unsigned long flags; - - /* to hold ST registration callback status */ - char streg_cbdata; - - /* write function pointer of ST driver */ - long (*st_write) (struct sk_buff *); - - /* Wait on comepletion handler needed to synchronize - * hci_st_open() and hci_st_registration_completion_cb() - * functions.*/ - struct completion wait_for_btdrv_reg_completion; -}; - -#endif -- cgit v1.2.3 From 267024a9f6cc7f7e26ed57424d5d0c8558769b56 Mon Sep 17 00:00:00 2001 From: roel kluin Date: Sat, 1 Jan 2011 18:01:51 +0000 Subject: Staging: iio: --/++ confusion in build_channel_array() error cleanup Fix loop: it should decrement Signed-off-by: Roel Kluin Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/iio_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index 03724246b95a..4dc961ced35e 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -398,7 +398,7 @@ inline int build_channel_array(const char *device_dir, return 0; error_cleanup_array: - for (i = count - 1; i >= 0; i++) + for (i = count - 1; i >= 0; i--) free((*ci_array)[i].name); free(*ci_array); error_close_dir: -- cgit v1.2.3 From c331e766f9a3dd2d05f209a39859bb206f723fae Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Mon, 10 Jan 2011 13:14:28 +0100 Subject: staging: ft1000-pcmcia: Fix compilation errors. Following patch will fix all compilation errors. Main problems was with pcmcia API changes. Also remove BROKEN as now driver is properly build. Signed-off-by: Marek Belisko Signed-off-by: Stano Lanci Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/Kconfig | 2 +- drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c | 263 +++------------------ drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.h | 1 - drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c | 2 +- drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c | 34 +-- 5 files changed, 55 insertions(+), 247 deletions(-) delete mode 100644 drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.h (limited to 'drivers') diff --git a/drivers/staging/ft1000/Kconfig b/drivers/staging/ft1000/Kconfig index d6da1304b45f..c54b4e83d6e9 100644 --- a/drivers/staging/ft1000/Kconfig +++ b/drivers/staging/ft1000/Kconfig @@ -13,7 +13,7 @@ config FT1000_USB config FT1000_PCMCIA tristate "Driver for ft1000 pcmcia device." - depends on PCMCIA && BROKEN + depends on PCMCIA depends on NET help Say Y if you want to have support for Flarion card also called diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c index 2163eae295f7..874919cf5965 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c @@ -39,9 +39,6 @@ #include #include -//#include // Slavius 21.10.2009 removed from kernel -#include -#include #include #include #include @@ -51,8 +48,6 @@ #include #include -#include "ft1000_cs.h" // Slavius 21.10.2009 because CS_SUCCESS constant is missing due to removed pcmcia/version.h - /*====================================================================*/ /* Module parameters */ @@ -82,9 +77,8 @@ MODULE_LICENSE("GPL"); /*====================================================================*/ -struct net_device *init_ft1000_card(int, int, unsigned char *, - void *ft1000_reset, struct pcmcia_device * link, - struct device *fdev); +struct net_device *init_ft1000_card(struct pcmcia_device *link, + void *ft1000_reset); void stop_ft1000_card(struct net_device *); static int ft1000_config(struct pcmcia_device *link); @@ -111,73 +105,7 @@ typedef struct local_info_t { static void ft1000_reset(struct pcmcia_device * link) { - conf_reg_t reg; - - DEBUG(0, "ft1000_cs:ft1000_reset is called................\n"); - - /* Soft-Reset card */ - reg.Action = CS_WRITE; - reg.Offset = CISREG_COR; - reg.Value = COR_SOFT_RESET; - pcmcia_access_configuration_register(link, ®); - - /* Wait until the card has acknowledged our reset */ - udelay(2); - - /* Restore original COR configuration index */ - /* Need at least 2 write to respond */ - reg.Action = CS_WRITE; - reg.Offset = CISREG_COR; - reg.Value = COR_DEFAULT; - pcmcia_access_configuration_register(link, ®); - - /* Wait until the card has finished restarting */ - udelay(1); - - reg.Action = CS_WRITE; - reg.Offset = CISREG_COR; - reg.Value = COR_DEFAULT; - pcmcia_access_configuration_register(link, ®); - - /* Wait until the card has finished restarting */ - udelay(1); - - reg.Action = CS_WRITE; - reg.Offset = CISREG_COR; - reg.Value = COR_DEFAULT; - pcmcia_access_configuration_register(link, ®); - - /* Wait until the card has finished restarting */ - udelay(1); - -} - -/*====================================================================*/ - -static int get_tuple_first(struct pcmcia_device *link, tuple_t * tuple, - cisparse_t * parse) -{ - int i; - i = pcmcia_get_first_tuple(link, tuple); - if (i != CS_SUCCESS) - return i; - i = pcmcia_get_tuple_data(link, tuple); - if (i != CS_SUCCESS) - return i; - return pcmcia_parse_tuple(tuple, parse); // Slavius 21.10.2009 removed unused link parameter -} - -static int get_tuple_next(struct pcmcia_device *link, tuple_t * tuple, - cisparse_t * parse) -{ - int i; - i = pcmcia_get_next_tuple(link, tuple); - if (i != CS_SUCCESS) - return i; - i = pcmcia_get_tuple_data(link, tuple); - if (i != CS_SUCCESS) - return i; - return pcmcia_parse_tuple(tuple, parse); // Slavius 21.10.2009 removed unused link parameter + pcmcia_reset_card(link->socket); } /*====================================================================== @@ -202,13 +130,10 @@ static int ft1000_attach(struct pcmcia_device *link) link->priv = local; local->dev = NULL; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; - link->irq.IRQInfo1 = IRQ_LEVEL_ID; - link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.IntType = INT_MEMORY_AND_IO; - link->irq.Handler = NULL; + link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; return ft1000_config(link); + } /* ft1000_attach */ /*====================================================================== @@ -235,13 +160,24 @@ static void ft1000_detach(struct pcmcia_device *link) stop_ft1000_card(dev); } - ft1000_release(link); + pcmcia_disable_device(link); /* This points to the parent local_info_t struct */ free_netdev(dev); } /* ft1000_detach */ +/*====================================================================== + + Check if the io window is configured + +======================================================================*/ +int ft1000_confcheck(struct pcmcia_device *link, void *priv_data) +{ + + return pcmcia_request_io(link); +} /* ft1000_confcheck */ + /*====================================================================== ft1000_config() is scheduled to run after a CARD_INSERTION event @@ -250,160 +186,36 @@ static void ft1000_detach(struct pcmcia_device *link) ======================================================================*/ -#define CS_CHECK(fn, ret) \ - do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) - -#define CFG_CHECK(fn, ret) \ - last_fn = (fn); if ((last_ret = (ret)) != 0) goto next_entry - -static int ft1000_config(struct pcmcia_device * link) +static int ft1000_config(struct pcmcia_device *link) { - tuple_t tuple; - cisparse_t parse; - int last_fn, last_ret, i; - u_char buf[64]; - cistpl_lan_node_id_t *node_id; - cistpl_cftable_entry_t dflt = { 0 }; - cistpl_cftable_entry_t *cfg; - unsigned char mac_address[6]; + int ret; - DEBUG(0, "ft1000_cs: ft1000_config(0x%p)\n", link); - - /* - This reads the card's CONFIG tuple to find its configuration - registers. - */ -// tuple.DesiredTuple = CISTPL_CONFIG; -// tuple.Attributes = 0; - tuple.TupleData = buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; -// CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); -// CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); -// CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); -// link->conf.ConfigBase = parse.config.base; -// link->conf.Present = parse.config.rmask[0]; + dev_dbg(&link->dev, "ft1000_cs: ft1000_config(0x%p)\n", link); - /* - In this loop, we scan the CIS for configuration table entries, - each of which describes a valid card configuration, including - voltage, IO window, memory window, and interrupt settings. - - We make no assumptions about the card to be configured: we use - just the information available in the CIS. In an ideal world, - this would work for any PCMCIA card, but it requires a complete - and accurate CIS. In practice, a driver usually "knows" most of - these things without consulting the CIS, and most client drivers - will only use the CIS to fill in implementation-defined details. - */ - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - tuple.Attributes = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - while (1) { - cfg = &(parse.cftable_entry); - CFG_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CFG_CHECK(ParseTuple, - pcmcia_parse_tuple(&tuple, &parse)); // Slavius 21.10.2009 removed unused link parameter - - if (cfg->flags & CISTPL_CFTABLE_DEFAULT) - dflt = *cfg; - if (cfg->index == 0) - goto next_entry; - link->conf.ConfigIndex = cfg->index; - - /* Do we need to allocate an interrupt? */ - if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) - link->conf.Attributes |= CONF_ENABLE_IRQ; - - /* IO window settings */ - link->io.NumPorts1 = link->io.NumPorts2 = 0; - if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) { - DEBUG(0, "ft1000_cs: IO_DATA_PATH_WIDTH_16\n"); - link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - } - if (!(io->flags & CISTPL_IO_16BIT)) { - DEBUG(0, "ft1000_cs: IO_DATA_PATH_WIDTH_8\n"); - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - } - link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - link->io.BasePort1 = io->win[0].base; - link->io.NumPorts1 = io->win[0].len; - if (io->nwin > 1) { - link->io.Attributes2 = link->io.Attributes1; - link->io.BasePort2 = io->win[1].base; - link->io.NumPorts2 = io->win[1].len; - } - /* This reserves IO space but doesn't actually enable it */ - pcmcia_request_io(link, &link->io); - } - - break; - - next_entry: - last_ret = pcmcia_get_next_tuple(link, &tuple); - } - if (last_ret != CS_SUCCESS) { - cs_error(link, RequestIO, last_ret); - goto failed; + /* setup IO window */ + ret = pcmcia_loop_config(link, ft1000_confcheck, NULL); + if (ret) { + printk(KERN_INFO "ft1000: Could not configure pcmcia\n"); + return -ENODEV; } - /* - Allocate an interrupt line. Note that this does not assign a - handler to the interrupt, unless the 'Handler' member of the - irq structure is initialized. - */ - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); - - /* - This actually configures the PCMCIA socket -- setting up - the I/O windows and the interrupt mapping, and putting the - card and host interface into "Memory and IO" mode. - */ - CS_CHECK(RequestConfiguration, - pcmcia_request_configuration(link, &link->conf)); - - /* Get MAC address from tuples */ - - tuple.Attributes = tuple.TupleOffset = 0; - tuple.TupleData = buf; - tuple.TupleDataMax = sizeof(buf); - - /* Check for a LAN function extension tuple */ - tuple.DesiredTuple = CISTPL_FUNCE; - i = get_tuple_first(link, &tuple, &parse); - while (i == CS_SUCCESS) { - if (parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID) - break; - i = get_tuple_next(link, &tuple, &parse); + /* configure device */ + ret = pcmcia_enable_device(link); + if (ret) { + printk(KERN_INFO "ft1000: could not enable pcmcia\n"); + goto failed; } - if (i == CS_SUCCESS) { - node_id = (cistpl_lan_node_id_t *) parse.funce.data; - if (node_id->nb == 6) { - for (i = 0; i < 6; i++) - mac_address[i] = node_id->id[i]; - } + ((local_info_t *) link->priv)->dev = init_ft1000_card(link, + &ft1000_reset); + if (((local_info_t *) link->priv)->dev == NULL) { + printk(KERN_INFO "ft1000: Could not register as network device\n"); + goto failed; } - ((local_info_t *) link->priv)->dev = - init_ft1000_card(link->irq.AssignedIRQ, link->io.BasePort1, - &mac_address[0], ft1000_reset, link, - &handle_to_dev(link)); - - /* - At this point, the dev_node_t structure(s) need to be - initialized and arranged in a linked list at link->dev. - */ - /* Finally, report what we've done */ return 0; - -cs_failed: - cs_error(link, last_fn, last_ret); failed: ft1000_release(link); return -ENODEV; @@ -429,14 +241,11 @@ static void ft1000_release(struct pcmcia_device * link) no one will try to access the device or its data structures. */ - /* Unlink the device chain */ - link->dev_node = NULL; - /* In a normal driver, additional code may be needed to release other kernel data structures associated with this device. */ - + kfree((local_info_t *) link->priv); /* Don't bother checking to see if these succeed or not */ pcmcia_disable_device(link); diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.h b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.h deleted file mode 100644 index 2b5e383631fc..000000000000 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.h +++ /dev/null @@ -1 +0,0 @@ -#define CS_SUCCESS 0x00 diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c index 0bf398d570dc..c56f588a790b 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c @@ -310,7 +310,7 @@ USHORT hdr_checksum(PPSEUDO_HDR pHdr) return chksum; } -int card_download(struct net_device *dev, void *pFileStart, UINT FileLength) +int card_download(struct net_device *dev, const u8 *pFileStart, UINT FileLength) { FT1000_INFO *info = (PFT1000_INFO) netdev_priv(dev); int Status = SUCCESS; diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c index 588afd5a5ddb..5bc6811513df 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c @@ -43,6 +43,10 @@ #include #include +#include +#include +#include + #ifdef FT_DEBUG #define DEBUG(n, args...) printk(KERN_DEBUG args); #else @@ -53,7 +57,7 @@ #include "ft1000_dev.h" #include "ft1000.h" -int card_download(struct net_device *dev, void *pFileStart, UINT FileLength); +int card_download(struct net_device *dev, const u8 *pFileStart, UINT FileLength); void ft1000InitProc(struct net_device *dev); void ft1000CleanupProc(struct net_device *dev); @@ -2148,13 +2152,11 @@ static const struct ethtool_ops ops = { .get_link = ft1000_get_link }; -struct net_device *init_ft1000_card(unsigned short irq, int port, - unsigned char *mac_addr, void *ft1000_reset, - void *link, struct device *fdev) +struct net_device *init_ft1000_card(struct pcmcia_device *link, + void *ft1000_reset) { FT1000_INFO *info; struct net_device *dev; - int i; static const struct net_device_ops ft1000ops = // Slavius 21.10.2009 due to kernel changes { @@ -2165,8 +2167,8 @@ struct net_device *init_ft1000_card(unsigned short irq, int port, }; DEBUG(1, "ft1000_hw: init_ft1000_card()\n"); - DEBUG(1, "ft1000_hw: irq = %d\n", irq); - DEBUG(1, "ft1000_hw: port = 0x%04x\n", port); + DEBUG(1, "ft1000_hw: irq = %d\n", link->irq); + DEBUG(1, "ft1000_hw: port = 0x%04x\n", link->resource[0]->start); flarion_ft1000_cnt++; @@ -2184,7 +2186,7 @@ struct net_device *init_ft1000_card(unsigned short irq, int port, return NULL; } - SET_NETDEV_DEV(dev, fdev); + SET_NETDEV_DEV(dev, &link->dev); info = netdev_priv(dev); memset(info, 0, sizeof(FT1000_INFO)); @@ -2227,15 +2229,13 @@ struct net_device *init_ft1000_card(unsigned short irq, int port, DEBUG(0, "device name = %s\n", dev->name); - for (i = 0; i < 6; i++) { - dev->dev_addr[i] = mac_addr[i]; - DEBUG(1, "ft1000_hw: mac_addr %d = 0x%02x\n", i, mac_addr[i]); + dev->irq = link->irq; + dev->base_addr = link->resource[0]->start; + if (pcmcia_get_mac_from_cis(link, dev)) { + printk(KERN_ERR "ft1000: Could not read mac address\n"); + goto err_dev; } - netif_stop_queue(dev); - dev->irq = irq; - dev->base_addr = port; - if (request_irq(dev->irq, ft1000_interrupt, IRQF_SHARED, dev->name, dev)) { printk(KERN_ERR "ft1000: Could not request_irq\n"); goto err_dev; @@ -2254,13 +2254,13 @@ struct net_device *init_ft1000_card(unsigned short irq, int port, info->AsicID = ft1000_read_reg(dev, FT1000_REG_ASIC_ID); if (info->AsicID == ELECTRABUZZ_ID) { DEBUG(0, "ft1000_hw: ELECTRABUZZ ASIC\n"); - if (request_firmware(&fw_entry, "ft1000.img", fdev) != 0) { + if (request_firmware(&fw_entry, "ft1000.img", &link->dev) != 0) { printk(KERN_INFO "ft1000: Could not open ft1000.img\n"); goto err_unreg; } } else { DEBUG(0, "ft1000_hw: MAGNEMITE ASIC\n"); - if (request_firmware(&fw_entry, "ft2000.img", fdev) != 0) { + if (request_firmware(&fw_entry, "ft2000.img", &link->dev) != 0) { printk(KERN_INFO "ft1000: Could not open ft2000.img\n"); goto err_unreg; } -- cgit v1.2.3 From 98069c3f1cd353eda61d8e11ce40f83d5c5a99f3 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 13 Jan 2011 17:43:29 +0100 Subject: Staging: iio: Documented output / DAC interface Added documentation for: * /sys/bus/iio/devices/deviceX/outY_scale * /sys/bus/iio/devices/deviceX/outY_raw * /sys/bus/iio/devices/deviceX/outY&Z_raw Signed-off-by: Roland Stigge Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/sysfs-bus-iio | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio b/drivers/staging/iio/Documentation/sysfs-bus-iio index 2dde97de75f8..8e5d8d1f3b2f 100644 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio @@ -168,6 +168,7 @@ Description: What: /sys/bus/iio/devices/deviceX/inY_scale What: /sys/bus/iio/devices/deviceX/inY_supply_scale What: /sys/bus/iio/devices/deviceX/in_scale +What: /sys/bus/iio/devices/deviceX/outY_scale What: /sys/bus/iio/devices/deviceX/accel_scale What: /sys/bus/iio/devices/deviceX/accel_peak_scale What: /sys/bus/iio/devices/deviceX/gyro_scale @@ -222,6 +223,23 @@ Description: If a discrete set of scale values are available, they are listed in this attribute. +What: /sys/bus/iio/devices/deviceX/outY_raw +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Raw (unscaled, no bias etc.) output voltage for + channel Y. The number must always be specified and + unique if the output corresponds to a single channel. + +What: /sys/bus/iio/devices/deviceX/outY&Z_raw +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Raw (unscaled, no bias etc.) output voltage for an aggregate of + channel Y, channel Z, etc. This interface is available in cases + where a single output sets the value for multiple channels + simultaneously. + What: /sys/bus/iio/devices/deviceX/deviceX:eventY KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org -- cgit v1.2.3 From 2b152873469d2b0751e8b726df6415f05e37632e Mon Sep 17 00:00:00 2001 From: Jerome Marchand Date: Fri, 17 Dec 2010 16:59:33 +0100 Subject: Staging: zram: make ZRAM depends on SYSFS We can not configure zram device without sysfs anyway, so make zram depends on it. Signed-off-by: Jerome Marchand Acked-by: Jeff Moyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/Kconfig | 2 +- drivers/staging/zram/zram_drv.c | 4 ---- drivers/staging/zram/zram_sysfs.c | 4 ---- 3 files changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zram/Kconfig b/drivers/staging/zram/Kconfig index da079f8d6e3d..d3982e6fdb40 100644 --- a/drivers/staging/zram/Kconfig +++ b/drivers/staging/zram/Kconfig @@ -1,6 +1,6 @@ config ZRAM tristate "Compressed RAM block device support" - depends on BLOCK + depends on BLOCK && SYSFS select LZO_COMPRESS select LZO_DECOMPRESS default n diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 5415712f01f8..0ab931e9ee7e 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -626,14 +626,12 @@ static int create_device(struct zram *zram, int device_id) add_disk(zram->disk); -#ifdef CONFIG_SYSFS ret = sysfs_create_group(&disk_to_dev(zram->disk)->kobj, &zram_disk_attr_group); if (ret < 0) { pr_warning("Error creating sysfs group"); goto out; } -#endif zram->init_done = 0; @@ -643,10 +641,8 @@ out: static void destroy_device(struct zram *zram) { -#ifdef CONFIG_SYSFS sysfs_remove_group(&disk_to_dev(zram->disk)->kobj, &zram_disk_attr_group); -#endif if (zram->disk) { del_gendisk(zram->disk); diff --git a/drivers/staging/zram/zram_sysfs.c b/drivers/staging/zram/zram_sysfs.c index 6b3cf00b0ff4..ad62db221b6f 100644 --- a/drivers/staging/zram/zram_sysfs.c +++ b/drivers/staging/zram/zram_sysfs.c @@ -17,8 +17,6 @@ #include "zram_drv.h" -#ifdef CONFIG_SYSFS - static u64 zram_stat64_read(struct zram *zram, u64 *v) { u64 val; @@ -220,5 +218,3 @@ static struct attribute *zram_disk_attrs[] = { struct attribute_group zram_disk_attr_group = { .attrs = zram_disk_attrs, }; - -#endif /* CONFIG_SYSFS */ -- cgit v1.2.3 From f2da98739da4e20e907f8317d513868764002d31 Mon Sep 17 00:00:00 2001 From: Jerome Marchand Date: Fri, 17 Dec 2010 17:02:28 +0100 Subject: Staging: zram: round up the disk size provided by user Currently disksize_store() round down the disk size provided by user. This is probably not what one would expect, so round up instead. Signed-off-by: Jerome Marchand Acked-by: Jeff Moyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/zram_sysfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/zram/zram_sysfs.c b/drivers/staging/zram/zram_sysfs.c index ad62db221b6f..a70cc010d18d 100644 --- a/drivers/staging/zram/zram_sysfs.c +++ b/drivers/staging/zram/zram_sysfs.c @@ -14,6 +14,7 @@ #include #include +#include #include "zram_drv.h" @@ -65,7 +66,7 @@ static ssize_t disksize_store(struct device *dev, if (ret) return ret; - zram->disksize &= PAGE_MASK; + zram->disksize = PAGE_ALIGN(zram->disksize); set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT); return len; -- cgit v1.2.3 From 1aa326640d1e91d32179310441fa3030c501d0f3 Mon Sep 17 00:00:00 2001 From: Jerome Marchand Date: Fri, 17 Dec 2010 17:03:15 +0100 Subject: Staging: zram: make zram_read return a bio error if the device is not initialized Make zram_read() return a bio error if the device is not initialized instead of pretending nothing happened. Signed-off-by: Jerome Marchand Acked-by: Jeff Moyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/zram_drv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 0ab931e9ee7e..01d6dd952581 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -208,8 +208,7 @@ static int zram_read(struct zram *zram, struct bio *bio) struct bio_vec *bvec; if (unlikely(!zram->init_done)) { - set_bit(BIO_UPTODATE, &bio->bi_flags); - bio_endio(bio, 0); + bio_endio(bio, -ENXIO); return 0; } -- cgit v1.2.3 From c4586c16859861df6af51d0aab5c4738c0e4ac44 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 27 Dec 2010 22:22:31 -0800 Subject: staging:zram:xvmalloc.c Fix a typo. Not exactly sure if this is a typo or not, due to my search results comming up with not that many hits. Either its dereferenceable or dereferencable from the two I choose the later. if it's wrong let me know and I'll resend. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/xvmalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/zram/xvmalloc.c b/drivers/staging/zram/xvmalloc.c index b64406739d05..3ed744ba7ba0 100644 --- a/drivers/staging/zram/xvmalloc.c +++ b/drivers/staging/zram/xvmalloc.c @@ -46,7 +46,7 @@ static void clear_flag(struct block_header *block, enum blockflags flag) } /* - * Given pair, provide a derefrencable pointer. + * Given pair, provide a dereferencable pointer. * This is called from xv_malloc/xv_free path, so it * needs to be fast. */ -- cgit v1.2.3 From bf3c45f054506b8b7edc189b702b720a842e0764 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 27 Dec 2010 21:46:46 +0900 Subject: Staging: rtl8192e: Remove empty function rtl8192_try_wake_queue Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index fac4eee28e4e..6f591ab7122c 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -152,7 +152,6 @@ static void rtl8192_irq_rx_tasklet(struct r8192_priv *priv); static void rtl8192_irq_tx_tasklet(struct r8192_priv *priv); static void rtl8192_prepare_beacon(struct r8192_priv *priv); static irqreturn_t rtl8192_interrupt(int irq, void *netdev); -static void rtl8192_try_wake_queue(struct net_device *dev, int pri); static void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb); static void rtl8192_update_ratr_table(struct net_device* dev); static void rtl8192_restart(struct work_struct *work); @@ -6293,7 +6292,6 @@ static irqreturn_t rtl8192_interrupt(int irq, void *netdev) priv->stats.txbkokint++; priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; rtl8192_tx_isr(dev,BK_QUEUE); - rtl8192_try_wake_queue(dev, BK_QUEUE); } if(inta & IMR_BEDOK){ @@ -6301,7 +6299,6 @@ static irqreturn_t rtl8192_interrupt(int irq, void *netdev) priv->stats.txbeokint++; priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; rtl8192_tx_isr(dev,BE_QUEUE); - rtl8192_try_wake_queue(dev, BE_QUEUE); } if(inta & IMR_VIDOK){ @@ -6309,14 +6306,12 @@ static irqreturn_t rtl8192_interrupt(int irq, void *netdev) priv->stats.txviokint++; priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; rtl8192_tx_isr(dev,VI_QUEUE); - rtl8192_try_wake_queue(dev, VI_QUEUE); } if(inta & IMR_VODOK){ priv->stats.txvookint++; priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; rtl8192_tx_isr(dev,VO_QUEUE); - rtl8192_try_wake_queue(dev, VO_QUEUE); } spin_unlock_irqrestore(&priv->irq_th_lock,flags); @@ -6324,11 +6319,6 @@ static irqreturn_t rtl8192_interrupt(int irq, void *netdev) return IRQ_HANDLED; } -static void rtl8192_try_wake_queue(struct net_device *dev, int pri) -{ -} - - void EnableHWSecurityConfig8192(struct net_device *dev) { u8 SECR_value = 0x0; -- cgit v1.2.3 From b2cf8d4872a5c3f5e57010bcab9be45e8b27cb99 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 27 Dec 2010 21:47:02 +0900 Subject: Staging: rtl8192e: Clean up rtl8192_interrupt formatting Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 210 ++++++++++++++++----------------- 1 file changed, 100 insertions(+), 110 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 6f591ab7122c..f006f6700285 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -6179,144 +6179,134 @@ static void __exit rtl8192_pci_module_exit(void) ieee80211_rtl_exit(); } -//warning message WB static irqreturn_t rtl8192_interrupt(int irq, void *netdev) { - struct net_device *dev = (struct net_device *) netdev; - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - unsigned long flags; - u32 inta; - /* We should return IRQ_NONE, but for now let me keep this */ - if(priv->irq_enabled == 0){ - return IRQ_HANDLED; - } + struct net_device *dev = (struct net_device *) netdev; + struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + unsigned long flags; + u32 inta; - spin_lock_irqsave(&priv->irq_th_lock,flags); + /* We should return IRQ_NONE, but for now let me keep this */ + if (priv->irq_enabled == 0) + return IRQ_HANDLED; - //ISR: 4bytes + spin_lock_irqsave(&priv->irq_th_lock,flags); - inta = read_nic_dword(dev, ISR);// & priv->IntrMask; - write_nic_dword(dev,ISR,inta); // reset int situation + /* ISR: 4bytes */ - priv->stats.shints++; - //DMESG("Enter interrupt, ISR value = 0x%08x", inta); - if(!inta){ - spin_unlock_irqrestore(&priv->irq_th_lock,flags); - return IRQ_HANDLED; - /* - most probably we can safely return IRQ_NONE, - but for now is better to avoid problems - */ - } + inta = read_nic_dword(dev, ISR); /* & priv->IntrMask; */ + write_nic_dword(dev, ISR, inta); /* reset int situation */ - if(inta == 0xffff){ - /* HW disappared */ - spin_unlock_irqrestore(&priv->irq_th_lock,flags); - return IRQ_HANDLED; - } + priv->stats.shints++; + if (!inta) { + spin_unlock_irqrestore(&priv->irq_th_lock, flags); + return IRQ_HANDLED; + /* + * most probably we can safely return IRQ_NONE, + * but for now is better to avoid problems + */ + } - priv->stats.ints++; + if (inta == 0xffff) { + /* HW disappared */ + spin_unlock_irqrestore(&priv->irq_th_lock, flags); + return IRQ_HANDLED; + } + + priv->stats.ints++; #ifdef DEBUG_IRQ - DMESG("NIC irq %x",inta); + DMESG("NIC irq %x",inta); #endif - //priv->irqpending = inta; - - - if(!netif_running(dev)) { - spin_unlock_irqrestore(&priv->irq_th_lock,flags); - return IRQ_HANDLED; - } - - if(inta & IMR_TIMEOUT0){ - // write_nic_dword(dev, TimerInt, 0); - //DMESG("=================>waking up"); - // rtl8180_hw_wakeup(dev); - } - if(inta & IMR_TBDOK){ - RT_TRACE(COMP_INTR, "beacon ok interrupt!\n"); - rtl8192_tx_isr(dev, BEACON_QUEUE); - priv->stats.txbeaconokint++; - } + if (!netif_running(dev)) { + spin_unlock_irqrestore(&priv->irq_th_lock, flags); + return IRQ_HANDLED; + } - if(inta & IMR_TBDER){ - RT_TRACE(COMP_INTR, "beacon ok interrupt!\n"); - rtl8192_tx_isr(dev, BEACON_QUEUE); - priv->stats.txbeaconerr++; - } + if (inta & IMR_TBDOK) { + RT_TRACE(COMP_INTR, "beacon ok interrupt!\n"); + rtl8192_tx_isr(dev, BEACON_QUEUE); + priv->stats.txbeaconokint++; + } - if(inta & IMR_MGNTDOK ) { - RT_TRACE(COMP_INTR, "Manage ok interrupt!\n"); - priv->stats.txmanageokint++; - rtl8192_tx_isr(dev,MGNT_QUEUE); + if (inta & IMR_TBDER) { + RT_TRACE(COMP_INTR, "beacon ok interrupt!\n"); + rtl8192_tx_isr(dev, BEACON_QUEUE); + priv->stats.txbeaconerr++; + } - } + if (inta & IMR_MGNTDOK ) { + RT_TRACE(COMP_INTR, "Manage ok interrupt!\n"); + priv->stats.txmanageokint++; + rtl8192_tx_isr(dev,MGNT_QUEUE); + } - if(inta & IMR_COMDOK) - { - priv->stats.txcmdpktokint++; - rtl8192_tx_isr(dev,TXCMD_QUEUE); - } + if (inta & IMR_COMDOK) + { + priv->stats.txcmdpktokint++; + rtl8192_tx_isr(dev, TXCMD_QUEUE); + } - if(inta & IMR_ROK){ + if (inta & IMR_ROK) { #ifdef DEBUG_RX - DMESG("Frame arrived !"); + DMESG("Frame arrived !"); #endif - priv->stats.rxint++; - tasklet_schedule(&priv->irq_rx_tasklet); - } + priv->stats.rxint++; + tasklet_schedule(&priv->irq_rx_tasklet); + } - if(inta & IMR_BcnInt) { - RT_TRACE(COMP_INTR, "prepare beacon for interrupt!\n"); - tasklet_schedule(&priv->irq_prepare_beacon_tasklet); - } + if (inta & IMR_BcnInt) { + RT_TRACE(COMP_INTR, "prepare beacon for interrupt!\n"); + tasklet_schedule(&priv->irq_prepare_beacon_tasklet); + } - if(inta & IMR_RDU){ - RT_TRACE(COMP_INTR, "rx descriptor unavailable!\n"); - priv->stats.rxrdu++; - /* reset int situation */ - write_nic_dword(dev,INTA_MASK,read_nic_dword(dev, INTA_MASK) & ~IMR_RDU); - tasklet_schedule(&priv->irq_rx_tasklet); - } + if (inta & IMR_RDU) { + RT_TRACE(COMP_INTR, "rx descriptor unavailable!\n"); + priv->stats.rxrdu++; + /* reset int situation */ + write_nic_dword(dev, INTA_MASK, read_nic_dword(dev, INTA_MASK) & ~IMR_RDU); + tasklet_schedule(&priv->irq_rx_tasklet); + } - if(inta & IMR_RXFOVW){ - RT_TRACE(COMP_INTR, "rx overflow !\n"); - priv->stats.rxoverflow++; - tasklet_schedule(&priv->irq_rx_tasklet); - } + if (inta & IMR_RXFOVW) { + RT_TRACE(COMP_INTR, "rx overflow !\n"); + priv->stats.rxoverflow++; + tasklet_schedule(&priv->irq_rx_tasklet); + } - if(inta & IMR_TXFOVW) priv->stats.txoverflow++; + if (inta & IMR_TXFOVW) + priv->stats.txoverflow++; - if(inta & IMR_BKDOK){ - RT_TRACE(COMP_INTR, "BK Tx OK interrupt!\n"); - priv->stats.txbkokint++; - priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; - rtl8192_tx_isr(dev,BK_QUEUE); - } + if (inta & IMR_BKDOK) { + RT_TRACE(COMP_INTR, "BK Tx OK interrupt!\n"); + priv->stats.txbkokint++; + priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; + rtl8192_tx_isr(dev, BK_QUEUE); + } - if(inta & IMR_BEDOK){ - RT_TRACE(COMP_INTR, "BE TX OK interrupt!\n"); - priv->stats.txbeokint++; - priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; - rtl8192_tx_isr(dev,BE_QUEUE); - } + if (inta & IMR_BEDOK) { + RT_TRACE(COMP_INTR, "BE TX OK interrupt!\n"); + priv->stats.txbeokint++; + priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; + rtl8192_tx_isr(dev, BE_QUEUE); + } - if(inta & IMR_VIDOK){ - RT_TRACE(COMP_INTR, "VI TX OK interrupt!\n"); - priv->stats.txviokint++; - priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; - rtl8192_tx_isr(dev,VI_QUEUE); - } + if (inta & IMR_VIDOK) { + RT_TRACE(COMP_INTR, "VI TX OK interrupt!\n"); + priv->stats.txviokint++; + priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; + rtl8192_tx_isr(dev, VI_QUEUE); + } - if(inta & IMR_VODOK){ - priv->stats.txvookint++; - priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; - rtl8192_tx_isr(dev,VO_QUEUE); - } + if (inta & IMR_VODOK) { + priv->stats.txvookint++; + priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; + rtl8192_tx_isr(dev, VO_QUEUE); + } - spin_unlock_irqrestore(&priv->irq_th_lock,flags); + spin_unlock_irqrestore(&priv->irq_th_lock, flags); - return IRQ_HANDLED; + return IRQ_HANDLED; } void EnableHWSecurityConfig8192(struct net_device *dev) -- cgit v1.2.3 From f8129a95414931c0b8e333963181548bb0f6d670 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 27 Dec 2010 21:47:35 +0900 Subject: Staging: rtl8192e: Unlock spinlock in once place only Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index f006f6700285..075245b92a87 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -6185,12 +6185,13 @@ static irqreturn_t rtl8192_interrupt(int irq, void *netdev) struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); unsigned long flags; u32 inta; + irqreturn_t ret = IRQ_HANDLED; + + spin_lock_irqsave(&priv->irq_th_lock, flags); /* We should return IRQ_NONE, but for now let me keep this */ if (priv->irq_enabled == 0) - return IRQ_HANDLED; - - spin_lock_irqsave(&priv->irq_th_lock,flags); + goto out_unlock; /* ISR: 4bytes */ @@ -6199,18 +6200,16 @@ static irqreturn_t rtl8192_interrupt(int irq, void *netdev) priv->stats.shints++; if (!inta) { - spin_unlock_irqrestore(&priv->irq_th_lock, flags); - return IRQ_HANDLED; /* * most probably we can safely return IRQ_NONE, * but for now is better to avoid problems */ + goto out_unlock; } if (inta == 0xffff) { /* HW disappared */ - spin_unlock_irqrestore(&priv->irq_th_lock, flags); - return IRQ_HANDLED; + goto out_unlock; } priv->stats.ints++; @@ -6218,10 +6217,8 @@ static irqreturn_t rtl8192_interrupt(int irq, void *netdev) DMESG("NIC irq %x",inta); #endif - if (!netif_running(dev)) { - spin_unlock_irqrestore(&priv->irq_th_lock, flags); - return IRQ_HANDLED; - } + if (!netif_running(dev)) + goto out_unlock; if (inta & IMR_TBDOK) { RT_TRACE(COMP_INTR, "beacon ok interrupt!\n"); @@ -6304,9 +6301,10 @@ static irqreturn_t rtl8192_interrupt(int irq, void *netdev) rtl8192_tx_isr(dev, VO_QUEUE); } +out_unlock: spin_unlock_irqrestore(&priv->irq_th_lock, flags); - return IRQ_HANDLED; + return ret; } void EnableHWSecurityConfig8192(struct net_device *dev) -- cgit v1.2.3 From dbb6c03659cdb4c2073129cb9a9cdcbfafea0a27 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 27 Dec 2010 21:49:28 +0900 Subject: Staging: rtl8192e: Dump step we fail in init_firmware() Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r819xE_firmware.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r819xE_firmware.c b/drivers/staging/rtl8192e/r819xE_firmware.c index 5c3da468f0dc..e335b815ca00 100644 --- a/drivers/staging/rtl8192e/r819xE_firmware.c +++ b/drivers/staging/rtl8192e/r819xE_firmware.c @@ -345,7 +345,7 @@ bool init_firmware(struct net_device *dev) return rt_status; download_firmware_fail: - RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__); + RT_TRACE(COMP_ERR, "ERR in %s() step %d\n", __func__, init_step); rt_status = false; return rt_status; } -- cgit v1.2.3 From 03996954fd758c4f3b5de6528f77db16ef460eb3 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 27 Dec 2010 21:48:32 +0900 Subject: Staging: rtl8192e: Use compare_ether_addr instead of eqMacAddr Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/dot11d.h | 6 ------ drivers/staging/rtl8192e/r8192E_core.c | 6 +++--- 2 files changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/dot11d.h b/drivers/staging/rtl8192e/dot11d.h index 3bec1a40016d..86660833d110 100644 --- a/drivers/staging/rtl8192e/dot11d.h +++ b/drivers/staging/rtl8192e/dot11d.h @@ -41,12 +41,6 @@ typedef struct _RT_DOT11D_INFO { DOT11D_STATE State; } RT_DOT11D_INFO, *PRT_DOT11D_INFO; -static inline bool eqMacAddr(u8 *a, u8 *b) -{ - return a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && - a[3] == b[3] && a[4] == b[4] && a[5] == b[5]; -} - #define cpMacAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], \ (des)[2] = (src)[2], (des)[3] = (src)[3], \ (des)[4] = (src)[4], (des)[5] = (src)[5]) diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 075245b92a87..54853ee9e0ef 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -5571,9 +5571,9 @@ static void TranslateRxSignalStuff819xpci(struct net_device *dev, /* Check if the received packet is acceptabe. */ bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) && - (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3)) + (!compare_ether_addr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3)) && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV)); - bpacket_toself = bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr)); + bpacket_toself = bpacket_match_bssid & (!compare_ether_addr(praddr, priv->ieee80211->dev->dev_addr)); #if 1//cosa if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON) { @@ -5582,7 +5582,7 @@ static void TranslateRxSignalStuff819xpci(struct net_device *dev, } if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK) { - if((eqMacAddr(praddr,dev->dev_addr))) + if((!compare_ether_addr(praddr,dev->dev_addr))) bToSelfBA = true; //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf); } -- cgit v1.2.3 From dd1847332a5e5c6ac945ad12db0bc49871481d3a Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 27 Dec 2010 21:49:49 +0900 Subject: Staging: rtl8192e: Convert cpMacAddr macro to inline function Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/dot11d.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/dot11d.h b/drivers/staging/rtl8192e/dot11d.h index 86660833d110..106ebcfa7d7d 100644 --- a/drivers/staging/rtl8192e/dot11d.h +++ b/drivers/staging/rtl8192e/dot11d.h @@ -41,9 +41,10 @@ typedef struct _RT_DOT11D_INFO { DOT11D_STATE State; } RT_DOT11D_INFO, *PRT_DOT11D_INFO; -#define cpMacAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], \ - (des)[2] = (src)[2], (des)[3] = (src)[3], \ - (des)[4] = (src)[4], (des)[5] = (src)[5]) +static inline void cpMacAddr(unsigned char *des, unsigned char *src) +{ + memcpy(des, src, 6); +} #define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO) \ ((__pIeeeDev)->pDot11dInfo)) -- cgit v1.2.3 From 5d33549a525c737e9ad437638aa9bf812037bdf2 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 27 Dec 2010 21:50:14 +0900 Subject: Staging: rtl8192e: Remove assert macro Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 6 ------ drivers/staging/rtl8192e/r8192E_core.c | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 4a83958ac24d..853783762404 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -152,11 +152,6 @@ do { if(rt_global_debug_component & component) \ #define RTL819x_DEBUG #ifdef RTL819x_DEBUG -#define assert(expr) \ - if (!(expr)) { \ - printk( "Assertion failed! %s,%s,%s,line=%d\n", \ - #expr,__FILE__,__FUNCTION__,__LINE__); \ - } //wb added to debug out data buf //if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA #define RT_DEBUG_DATA(level, data, datalen) \ @@ -174,7 +169,6 @@ do { if(rt_global_debug_component & component) \ } \ } while (0) #else -#define assert(expr) do {} while (0) #define RT_DEBUG_DATA(level, data, datalen) do {} while(0) #endif /* RTL8169_DEBUG */ diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 54853ee9e0ef..bace6b346612 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -978,7 +978,7 @@ static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, u8 queue_index = tcb_desc->queue_index; /* shall not be referred by command packet */ - assert(queue_index != TXCMD_QUEUE); + BUG_ON(queue_index == TXCMD_QUEUE); if (priv->bHwRadioOff || (!priv->up)) { -- cgit v1.2.3 From 9bd931a8d470977a3658415105bedc39a63391b1 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 27 Dec 2010 21:50:33 +0900 Subject: Staging: rtl8192e: Remove unused RT_DEBUG_DATA macro Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 853783762404..aaf600d8fe22 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -150,28 +150,6 @@ do { if(rt_global_debug_component & component) \ #define COMP_ERR BIT31 // for error out, always on #endif -#define RTL819x_DEBUG -#ifdef RTL819x_DEBUG -//wb added to debug out data buf -//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA -#define RT_DEBUG_DATA(level, data, datalen) \ - do{ if ((rt_global_debug_component & (level)) == (level)) \ - { \ - int i; \ - u8* pdata = (u8*) data; \ - printk(KERN_DEBUG RTL819xE_MODULE_NAME ": %s()\n", __FUNCTION__); \ - for(i=0; i<(int)(datalen); i++) \ - { \ - printk("%2x ", pdata[i]); \ - if ((i+1)%16 == 0) printk("\n"); \ - } \ - printk("\n"); \ - } \ - } while (0) -#else -#define RT_DEBUG_DATA(level, data, datalen) do {} while(0) -#endif /* RTL8169_DEBUG */ - // // Queue Select Value in TxDesc -- cgit v1.2.3 From e9c0afc98b335a3358d57021243add3bc0495559 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 27 Dec 2010 21:50:47 +0900 Subject: Staging: rtl8192e: Remove commented debugging code Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index bace6b346612..cc391ee2bf22 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -4708,18 +4708,6 @@ static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } } } -#ifdef JOHN_DEBUG - //john's test 0711 - { - int i; - printk("@@ wrq->u pointer = "); - for(i=0;iu.data.length;i++){ - if(i%10==0) printk("\n"); - printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] ); - } - printk("\n"); - } -#endif /*JOHN_DEBUG*/ ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data); break; -- cgit v1.2.3 From 7bb5e8232b8d37cb1e2b5f80dff50b1a505c1066 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 27 Dec 2010 21:51:09 +0900 Subject: Staging: rtl8192e: Remove cast in request_irq Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index cc391ee2bf22..541d83d279e3 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -2913,11 +2913,7 @@ static short rtl8192_init(struct net_device *dev) init_timer(&priv->watch_dog_timer); priv->watch_dog_timer.data = (unsigned long)dev; priv->watch_dog_timer.function = watch_dog_timer_callback; -#if defined(IRQF_SHARED) - if(request_irq(dev->irq, (void*)rtl8192_interrupt, IRQF_SHARED, dev->name, dev)){ -#else - if(request_irq(dev->irq, (void *)rtl8192_interrupt, SA_SHIRQ, dev->name, dev)){ -#endif + if (request_irq(dev->irq, rtl8192_interrupt, IRQF_SHARED, dev->name, dev)) { printk("Error allocating IRQ %d",dev->irq); return -1; }else{ -- cgit v1.2.3 From 5506cf2eb994a9a8fb8a8449d1ca989f563acf82 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 27 Dec 2010 21:52:35 +0900 Subject: Staging: rtl8192e: Remove commented out printks Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/dot11d.c | 3 -- .../rtl8192e/ieee80211/ieee80211_crypt_ccmp.c | 6 ---- .../rtl8192e/ieee80211/ieee80211_crypt_tkip.c | 1 - drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c | 30 -------------------- .../staging/rtl8192e/ieee80211/ieee80211_softmac.c | 32 ---------------------- .../rtl8192e/ieee80211/ieee80211_softmac_wx.c | 2 -- drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c | 13 --------- .../staging/rtl8192e/ieee80211/rtl819x_HTProc.c | 3 -- .../staging/rtl8192e/ieee80211/rtl819x_TSProc.c | 1 - 9 files changed, 91 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/dot11d.c b/drivers/staging/rtl8192e/ieee80211/dot11d.c index 6bbf0919cdff..98e46487dc05 100644 --- a/drivers/staging/rtl8192e/ieee80211/dot11d.c +++ b/drivers/staging/rtl8192e/ieee80211/dot11d.c @@ -53,8 +53,6 @@ Dot11d_Reset(struct ieee80211_device *ieee) pDot11dInfo->State = DOT11D_STATE_NONE; pDot11dInfo->CountryIeLen = 0; RESET_CIE_WATCHDOG(ieee); - - //printk("Dot11d_Reset()\n"); } // @@ -109,7 +107,6 @@ Dot11d_UpdateCountryIe( pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3); } #if 1 - //printk("Dot11d_UpdateCountryIe(): Channel List:\n"); printk("Channel List:"); for(i=1; i<= MAX_CHANNEL_NUMBER; i++) if(pDot11dInfo->channel_map[i] > 0) diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c index a4e21cbcdf19..9b8533f2fcbb 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c @@ -319,11 +319,6 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) pos += 8; if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { - if (net_ratelimit()) { - //printk(KERN_DEBUG "CCMP: replay detected: STA=%pM" - // " previous PN %pm received PN %pm\n", - // hdr->addr2, key->rx_pn, pn); - } key->dot11RSNAStatsCCMPReplays++; return -4; } @@ -456,7 +451,6 @@ static char * ieee80211_ccmp_print_stats(char *p, void *priv) void ieee80211_ccmp_null(void) { -// printk("============>%s()\n", __FUNCTION__); return; } diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c index 14ca61087c01..2ad9501801b4 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c @@ -829,7 +829,6 @@ void ieee80211_crypto_tkip_exit(void) void ieee80211_tkip_null(void) { -// printk("============>%s()\n", __FUNCTION__); return; } diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c index 9318695042fb..4db6944cb6dc 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c @@ -511,19 +511,14 @@ static int is_duplicate_packet(struct ieee80211_device *ieee, return 0; } -// if(tid != 0) { -// printk(KERN_WARNING ":)))))))))))%x %x %x, fc(%x)\n", tid, *last_seq, seq, header->frame_ctl); -// } if ((*last_seq == seq) && time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) { if (*last_frag == frag){ - //printk(KERN_WARNING "[1] go drop!\n"); goto drop; } if (*last_frag + 1 != frag) /* out-of-order fragment */ - //printk(KERN_WARNING "[2] go drop!\n"); goto drop; } else *last_seq = seq; @@ -533,9 +528,6 @@ static int is_duplicate_packet(struct ieee80211_device *ieee, return 0; drop: -// BUG_ON(!(fc & IEEE80211_FCTL_RETRY)); -// printk("DUP\n"); - return 1; } bool @@ -607,14 +599,12 @@ void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_ /* Indicat the packets to upper layer */ if (sub_skb) { - //printk("0skb_len(%d)\n", skb->len); sub_skb->protocol = eth_type_trans(sub_skb, ieee->dev); memset(sub_skb->cb, 0, sizeof(sub_skb->cb)); sub_skb->dev = ieee->dev; sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */ //skb->ip_summed = CHECKSUM_UNNECESSARY; /* 802.11 crc not sufficient */ ieee->last_rx_ps_time = jiffies; - //printk("1skb_len(%d)\n", skb->len); netif_rx(sub_skb); } } @@ -693,7 +683,6 @@ void RxReorderIndicatePacket( struct ieee80211_device *ieee, IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Packets indication!! IndicateSeq: %d, NewSeq: %d\n",\ pTS->RxIndicateSeq, SeqNum); prxbIndicateArray[0] = prxb; -// printk("========================>%s(): SeqNum is %d\n",__FUNCTION__,SeqNum); index = 1; } else { /* Current packet is going to be inserted into pending list.*/ @@ -766,7 +755,6 @@ void RxReorderIndicatePacket( struct ieee80211_device *ieee, IEEE80211_DEBUG(IEEE80211_DL_REORDER,"Packets indication!! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum); prxbIndicateArray[index] = pReorderEntry->prxb; - // printk("========================>%s(): pReorderEntry->SeqNum is %d\n",__FUNCTION__,pReorderEntry->SeqNum); index++; list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List); @@ -841,7 +829,6 @@ u8 parse_subframe(struct ieee80211_device* ieee,struct sk_buff *skb, if(rx_stats->bContainHTC) { LLCOffset += sHTCLng; } - //printk("ChkLength = %d\n", LLCOffset); // Null packet, don't indicate it to upper layer ChkLength = LLCOffset;/* + (Frame_WEP(frame)!=0 ?Adapter->MgntInfo.SecurityInfo.EncryptionHeadOverhead:0);*/ @@ -925,9 +912,6 @@ u8 parse_subframe(struct ieee80211_device* ieee,struct sk_buff *skb, #ifdef JOHN_NOCPY dev_kfree_skb(skb); #endif - //{just for debug added by david - //printk("AMSDU::rxb->nr_subframes = %d\n",rxb->nr_subframes); - //} return rxb->nr_subframes; } } @@ -1472,13 +1456,11 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, } /* Indicat the packets to upper layer */ - //printk("0skb_len(%d)\n", skb->len); sub_skb->protocol = eth_type_trans(sub_skb, dev); memset(sub_skb->cb, 0, sizeof(sub_skb->cb)); sub_skb->dev = dev; sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */ //skb->ip_summed = CHECKSUM_UNNECESSARY; /* 802.11 crc not sufficient */ - //printk("1skb_len(%d)\n", skb->len); netif_rx(sub_skb); } } @@ -1898,8 +1880,6 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, offset = (info_element->data[2] >> 1)*2; - //printk("offset1:%x aid:%x\n",offset, ieee->assoc_id); - if(ieee->assoc_id < 8*offset || ieee->assoc_id > 8*(offset + info_element->len -3)) @@ -1910,7 +1890,6 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8))) network->dtim_data |= IEEE80211_DTIM_UCAST; - //IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: partially ignored\n"); break; case MFIE_TYPE_ERP: @@ -2073,7 +2052,6 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, info_element->data[1] == 0x13 && info_element->data[2] == 0x74)) { - //printk("========>%s(): athros AP is exist\n",__FUNCTION__); network->atheros_cap_exist = true; } else @@ -2085,7 +2063,6 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, info_element->data[2] == 0x43) ) { network->marvell_cap_exist = true; - //printk("========>%s(): marvel AP is exist\n",__FUNCTION__); } @@ -2231,7 +2208,6 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, case MFIE_TYPE_COUNTRY: IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n", info_element->len); - //printk("=====>Receive <%s> Country IE\n",network->ssid); ieee80211_extract_country_ie(ieee, info_element, network, network->bssid);//addr2 is same as addr3 when from an AP break; #endif @@ -2551,9 +2527,6 @@ static inline void update_network(struct ieee80211_network *dst, old_param = dst->qos_data.param_count; if(dst->flags & NETWORK_HAS_QOS_MASK){ //not update QOS paramter in beacon, as most AP will set all these parameter to 0.//WB - // printk("====>%s(), aifs:%x, %x\n", __FUNCTION__, dst->qos_data.parameters.aifs[0], src->qos_data.parameters.aifs[0]); - // memcpy(&dst->qos_data, &src->qos_data, - // sizeof(struct ieee80211_qos_data)); } else { dst->qos_data.supported = src->qos_data.supported; @@ -2806,8 +2779,6 @@ static inline void ieee80211_process_probe_response( //YJ,add,080819,for hidden ap if(is_beacon(beacon->header.frame_ctl) == 0) network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags); - //if(strncmp(network.ssid, "linksys-c",9) == 0) - // printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags); if(((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \ && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\ ||((ieee->current_network.ssid_len == network.ssid_len)&&(strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0)&&(ieee->state == IEEE80211_NOLINK)))) @@ -2852,7 +2823,6 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee, ieee80211_process_probe_response( ieee, (struct ieee80211_probe_response *)header, stats); - //printk("----------->%s()\n", __func__); if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED && ieee->iw_mode == IW_MODE_INFRA && ieee->state == IEEE80211_LINKED)) diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index 54c9c2471ec3..32e5d0aca6c4 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -280,10 +280,8 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee /* as for the completion function, it does not need * to check it any more. * */ - //printk("%s():insert to waitqueue!\n",__FUNCTION__); skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb); } else { - //printk("TX packet!\n"); ieee->softmac_hard_start_xmit(skb,ieee->dev); //dev_kfree_skb_any(skb);//edit by thomas } @@ -304,7 +302,6 @@ inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *i tcb_desc->RATRIndex = 7; tcb_desc->bTxDisableRateFallBack = 1; tcb_desc->bTxUseDriverAssingedRate = 1; - //printk("=============>%s()\n", __FUNCTION__); if(single){ header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); @@ -798,7 +795,6 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer); HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len); } -// printk("===============>tmp_ht_cap_len is %d,tmp_ht_info_len is %d, tmp_generic_ie_len is %d\n",tmp_ht_cap_len,tmp_ht_info_len,tmp_generic_ie_len); #endif beacon_size = sizeof(struct ieee80211_probe_response)+2+ ssid_len @@ -1344,8 +1340,6 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco memcpy(tag, realtek_ie_buf,realtek_ie_len -2 ); } } -// printk("<=====%s(), %p, %p\n", __FUNCTION__, ieee->dev, ieee->dev->dev_addr); -// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len); return skb; } @@ -1399,7 +1393,6 @@ void ieee80211_associate_step1(struct ieee80211_device *ieee) else{ ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ; IEEE80211_DEBUG_MGMT("Sending authentication request\n"); - //printk(KERN_WARNING "Sending authentication request\n"); softmac_mgmt_xmit(skb, ieee); //BUGON when you try to add_timer twice, using mod_timer may be better, john0709 if(!timer_pending(&ieee->associate_timer)){ @@ -1915,28 +1908,23 @@ short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *ti if(ieee->LPSDelayCnt) { - //printk("===============>Delay enter LPS for DHCP and ARP packets...\n"); ieee->LPSDelayCnt --; return 0; } dtim = ieee->current_network.dtim_data; -// printk("%s():DTIM:%d\n",__FUNCTION__,dtim); if(!(dtim & IEEE80211_DTIM_VALID)) return 0; timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval - //printk("VALID\n"); ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID; /* there's no need to nofity AP that I find you buffered with broadcast packet */ if(dtim & (IEEE80211_DTIM_UCAST & ieee->ps)) return 2; if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout))){ -// printk("%s():111Oh Oh ,it is not time out return 0\n",__FUNCTION__); return 0; } if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout))){ -// printk("%s():222Oh Oh ,it is not time out return 0\n",__FUNCTION__); return 0; } if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) && @@ -1976,7 +1964,6 @@ short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *ti else LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl;//ieee->current_network.tim.tim_count;//pPSC->LPSAwakeIntvl; } - //printk("=========>%s()assoc_id:%d(%#x),bAwakePktSent:%d,DTIM:%d, sleep interval:%d, LPSAwakeIntvl_tmp:%d, count:%d\n",__func__,ieee->assoc_id,cpu_to_le16(ieee->assoc_id),ieee->bAwakePktSent,ieee->current_network.dtim_period,pPSC->LPSAwakeIntvl,LPSAwakeIntvl_tmp,count); *time_l = ieee->current_network.last_dtim_sta_time[0] + MSECS(ieee->current_network.beacon_interval * LPSAwakeIntvl_tmp); @@ -2023,24 +2010,19 @@ inline void ieee80211_sta_ps(struct ieee80211_device *ieee) /* 2 wake, 1 sleep, 0 do nothing */ if(sleep == 0)//it is not time out or dtim is not valid { - //printk("===========>sleep is 0,do nothing\n"); goto out; } if(sleep == 1){ - //printk("===========>sleep is 1,to sleep\n"); if(ieee->sta_sleep == 1){ - //printk("%s(1): sta_sleep = 1, sleep again ++++++++++ \n", __func__); ieee->enter_sleep_state(ieee->dev,th,tl); } else if(ieee->sta_sleep == 0){ - // printk("send null 1\n"); spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); if(ieee->ps_is_queue_empty(ieee->dev)){ ieee->sta_sleep = 2; ieee->ack_tx_to_ieee = 1; - //printk("%s(2): sta_sleep = 0, notify AP we will sleeped ++++++++++ SendNullFunctionData\n", __func__); ieee80211_sta_ps_send_null_frame(ieee,1); ieee->ps_th = th; ieee->ps_tl = tl; @@ -2052,10 +2034,8 @@ inline void ieee80211_sta_ps(struct ieee80211_device *ieee) ieee->bAwakePktSent = false;//after null to power save we set it to false. not listen every beacon. }else if(sleep == 2){ - //printk("==========>sleep is 2,to wakeup\n"); spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); - //printk("%s(3): pkt buffered in ap will awake ++++++++++ ieee80211_sta_wakeup\n", __func__); ieee80211_sta_wakeup(ieee,1); spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); @@ -2072,15 +2052,12 @@ void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl) if(nl){ if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING) { - //printk("%s(1): notify AP we are awaked ++++++++++ SendNullFunctionData\n", __func__); - //printk("Warning: driver is probably failing to report TX ps error\n"); ieee->ack_tx_to_ieee = 1; ieee80211_sta_ps_send_null_frame(ieee, 0); } else { ieee->ack_tx_to_ieee = 1; - //printk("%s(2): notify AP we are awaked ++++++++++ Send PS-Poll\n", __func__); ieee80211_sta_ps_send_pspoll_frame(ieee); } } @@ -2094,8 +2071,6 @@ void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl) if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING) { - //printk("%s(3): notify AP we are awaked ++++++++++ SendNullFunctionData\n", __func__); - //printk("Warning: driver is probably failing to report TX ps error\n"); ieee->ack_tx_to_ieee = 1; ieee80211_sta_ps_send_null_frame(ieee, 0); } @@ -2103,7 +2078,6 @@ void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl) { ieee->ack_tx_to_ieee = 1; ieee->polling = true; - //printk("%s(4): notify AP we are awaked ++++++++++ Send PS-Poll\n", __func__); //ieee80211_sta_ps_send_null_frame(ieee, 0); ieee80211_sta_ps_send_pspoll_frame(ieee); } @@ -2124,7 +2098,6 @@ void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success) /* Null frame with PS bit set */ if(success){ ieee->sta_sleep = 1; - //printk("notify AP we will sleep and send null ok, so sleep now++++++++++ enter_sleep_state\n"); ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl); } } else {/* 21112005 - tx again null without PS bit if lost */ @@ -2134,12 +2107,10 @@ void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success) //ieee80211_sta_ps_send_null_frame(ieee, 0); if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING) { - //printk("notify AP we will sleep but send bull failed, so resend++++++++++ SendNullFunctionData\n"); ieee80211_sta_ps_send_null_frame(ieee, 0); } else { - //printk("notify AP we are awaked but send pspoll failed, so resend++++++++++ Send PS-Poll\n"); ieee80211_sta_ps_send_pspoll_frame(ieee); } spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); @@ -2431,7 +2402,6 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device * /* as for the completion function, it does not need * to check it any more. * */ - //printk("error:no descriptor left@queue_index %d\n", queue_index); //ieee80211_rtl_stop_queue(ieee); #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]); @@ -2937,8 +2907,6 @@ void ieee80211_start_protocol(struct ieee80211_device *ieee) if (ieee->current_network.beacon_interval == 0) ieee->current_network.beacon_interval = 100; -// printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel); -// ieee->set_chan(ieee->dev,ieee->current_network.channel); for(i = 0; i < 17; i++) { ieee->last_rxseq_num[i] = -1; diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c index d0a10807f7f6..5cc74be87463 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c @@ -538,8 +538,6 @@ int ieee80211_wx_set_power(struct ieee80211_device *ieee, (!ieee->enter_sleep_state) || (!ieee->ps_is_queue_empty)){ - // printk("ERROR. PS mode is tryied to be use but driver missed a callback\n\n"); - return -1; } #endif diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c index b74491c38ec5..368f669ded81 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c @@ -203,7 +203,6 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee, #if (WIRELESS_EXT < 18) if (ieee->wpa_enabled && network->wpa_ie_len){ char buf[MAX_WPA_IE_LEN * 2 + 30]; - // printk("WPA IE\n"); u8 *p = buf; p += sprintf(p, "wpa_ie="); for (i = 0; i < network->wpa_ie_len; i++) { @@ -552,7 +551,6 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, struct ieee80211_security sec = { .flags = 0, }; - //printk("======>encoding flag:%x,ext flag:%x, ext alg:%d\n", encoding->flags,ext->ext_flags, ext->alg); idx = encoding->flags & IW_ENCODE_INDEX; if (idx) { if (idx < 1 || idx > WEP_KEYS) @@ -568,7 +566,6 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, group_key = 1; } else { /* some Cisco APs use idx>0 for unicast in dynamic WEP */ - //printk("not group key, flags:%x, ext->alg:%d\n", ext->ext_flags, ext->alg); if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP) return -EINVAL; if (ieee->iw_mode == IW_MODE_INFRA) @@ -597,7 +594,6 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, sec.level = SEC_LEVEL_0; sec.flags |= SEC_LEVEL; } - //printk("disabled: flag:%x\n", encoding->flags); goto done; } @@ -674,8 +670,6 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, goto done; } #if 1 - //skip_host_crypt: - //printk("skip_host_crypt:ext_flags:%x\n", ext->ext_flags); if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { ieee->tx_keyidx = idx; sec.active_key = idx; @@ -795,7 +789,6 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee, switch (data->flags & IW_AUTH_INDEX) { case IW_AUTH_WPA_VERSION: /*need to support wpa2 here*/ - //printk("wpa version:%x\n", data->value); break; case IW_AUTH_CIPHER_PAIRWISE: case IW_AUTH_CIPHER_GROUP: @@ -813,8 +806,6 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee, break; case IW_AUTH_80211_AUTH_ALG: - //printk("======>%s():data->value is %d\n",__FUNCTION__,data->value); - // ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0; if(data->value & IW_AUTH_ALG_SHARED_KEY){ ieee->open_wep = 0; ieee->auth_mode = 1; @@ -826,17 +817,14 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee, else if(data->value & IW_AUTH_ALG_LEAP){ ieee->open_wep = 1; ieee->auth_mode = 2; - //printk("hahahaa:LEAP\n"); } else return -EINVAL; - //printk("open_wep:%d\n", ieee->open_wep); break; #if 1 case IW_AUTH_WPA_ENABLED: ieee->wpa_enabled = (data->value)?1:0; - //printk("enable wpa:%d\n", ieee->wpa_enabled); break; #endif @@ -859,7 +847,6 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len) if (len>MAX_WPA_IE_LEN || (len && ie == NULL)) { - // printk("return error out, len:%d\n", len); return -EINVAL; } diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c index b0c9c78eca4e..ebd1745cf524 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c @@ -55,10 +55,7 @@ static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4}; void HTUpdateDefaultSetting(struct ieee80211_device* ieee) { PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - //const typeof( ((struct ieee80211_device *)0)->pHTInfo ) *__mptr = &pHTInfo; - //printk("pHTinfo:%p, &pHTinfo:%p, mptr:%p, offsetof:%x\n", pHTInfo, &pHTInfo, __mptr, offsetof(struct ieee80211_device, pHTInfo)); - //printk("===>ieee:%p,\n", ieee); // ShortGI support pHTInfo->bRegShortGI20MHz= 1; pHTInfo->bRegShortGI40MHz= 1; diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c index 5876b4d53eb1..29eecf0ab769 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c @@ -293,7 +293,6 @@ PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee, u8* Addr, u8 if (pRet->TSpec.f.TSInfo.field.ucTSID == TID) if(pRet->TSpec.f.TSInfo.field.ucDirection == dir) { - // printk("Bingo! got it\n"); break; } -- cgit v1.2.3 From 7602032af1164d6b4aefc66b68cece776919dff8 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 27 Dec 2010 21:52:52 +0900 Subject: Staging: rtl8192e: Make arrays const Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8192e/ieee80211/rtl819x_HTProc.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c index ebd1745cf524..e031f42aea5c 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c @@ -29,18 +29,18 @@ u16 MCS_DATA_RATE[2][2][77] = 660, 450, 540, 630, 540, 630, 720, 810, 720, 810, 900, 900, 990} } // Short GI, 40MHz }; -static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf}; -static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70}; -static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e}; +static const u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf}; +static const u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70}; +static const u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e}; //static u8 NETGEAR834Bv2_BROADCOM[3] = {0x00, 0x1b, 0x2f}; -static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f}; //cosa 03202008 -static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf}; -static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc}; -static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e}; -static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02}; -static u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0}; -static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94}; -static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4}; +static const u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f}; +static const u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf}; +static const u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc}; +static const u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e}; +static const u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02}; +static const u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0}; +static const u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94}; +static const u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4}; // 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Should we put the // code in other place?? -- cgit v1.2.3 From 951fc8ed5cf346efb1fe18dabb739bcb9d3403c6 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 27 Dec 2010 21:53:05 +0900 Subject: Staging: rtl8192e: Fix typo in enum name Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 2 +- drivers/staging/rtl8192e/r8192E_core.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index dda6719234c9..933c800d6402 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -1919,7 +1919,7 @@ typedef enum _HW_VARIABLES{ HW_VAR_RATR_0, HW_VAR_RRSR, HW_VAR_CPU_RST, - HW_VAR_CECHK_BSSID, + HW_VAR_CHECK_BSSID, HW_VAR_LBK_MODE, // Set lookback mode, 2008.06.11. added by Roger. // Set HW related setting for 11N AES bug. HW_VAR_AES_11N_FIX, diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 541d83d279e3..044e226fe9ab 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -404,7 +404,7 @@ rtl8192e_SetHwReg(struct net_device *dev,u8 variable,u8* val) } break; - case HW_VAR_CECHK_BSSID: + case HW_VAR_CHECK_BSSID: { u32 RegRCR, Type; -- cgit v1.2.3 From a57d188daa8cd2867e6d8eca8d7cc7a8f5dcf628 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 27 Dec 2010 21:53:24 +0900 Subject: Staging: rtl8192e: Remove pointless returns Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c | 5 ----- drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c | 16 ---------------- 2 files changed, 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c index ae0e5b9e2183..389b9353690f 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c @@ -309,7 +309,6 @@ void ieee80211_send_ADDBAReq(struct ieee80211_device* ieee, u8* dst, PBA_RECORD { IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__); } - return; } /******************************************************************************************************************** @@ -333,9 +332,6 @@ void ieee80211_send_ADDBARsp(struct ieee80211_device* ieee, u8* dst, PBA_RECORD { IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__); } - - return; - } /******************************************************************************************************************** *function: send ADDBARSP frame out @@ -774,6 +770,5 @@ void RxBaInactTimeout(unsigned long data) &pRxTs->RxAdmittedBARecord, RX_DIR, DELBA_REASON_TIMEOUT); - return ; } diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c index e031f42aea5c..a4415972a60f 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c @@ -145,8 +145,6 @@ void HTDebugHTCapability(u8* CapIE, u8* TitleString ) IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMPDU Density = %d\n", pCapELE->MPDUDensity); IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMCS Rate Set = [%x][%x][%x][%x][%x]\n", pCapELE->MCS[0],\ pCapELE->MCS[1], pCapELE->MCS[2], pCapELE->MCS[3], pCapELE->MCS[4]); - return; - } /******************************************************************************************************************** *function: This function print out each field on HT Information IE mainly from (Beacon/ProbeRsp) @@ -211,7 +209,6 @@ void HTDebugHTInfo(u8* InfoIE, u8* TitleString) IEEE80211_DEBUG(IEEE80211_DL_HT, "\tBasic MCS Rate Set = [%x][%x][%x][%x][%x]\n", pHTInfoEle->BasicMSC[0],\ pHTInfoEle->BasicMSC[1], pHTInfoEle->BasicMSC[2], pHTInfoEle->BasicMSC[3], pHTInfoEle->BasicMSC[4]); - return; } /* @@ -729,15 +726,6 @@ void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u *len = 30 + 2; else *len = 26 + 2; - - - -// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_HT, posHTCap, *len -2); - - //Print each field in detail. Driver should not print out this message by default -// HTDebugHTCapability(posHTCap, (u8*)"HTConstructCapability()"); - return; - } /******************************************************************************************************************** *function: Construct Information Element in Beacon... if HTEnable is turned on @@ -789,9 +777,6 @@ void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* le //STA should not generate High Throughput Information Element *len = 0; } - //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_HT, posHTInfo, *len - 2); - //HTDebugHTInfo(posHTInfo, "HTConstructInforElement"); - return; } /* @@ -1648,7 +1633,6 @@ void HTUseDefaultSetting(struct ieee80211_device* ieee) { pHTInfo->bCurrentHTSupport = false; } - return; } /******************************************************************************************************************** *function: check whether HT control field exists -- cgit v1.2.3 From 34aac66cc2c32f6cd0bd08e0a0e6de851d261e36 Mon Sep 17 00:00:00 2001 From: françois romieu Date: Thu, 20 Jan 2011 04:59:06 +0000 Subject: atl1c: remove private #define. Either unused or duplicates from mii.h. Signed-off-by: Francois Romieu Cc: Jay Cliburn Cc: Chris Snook Cc: Jie Yang Signed-off-by: David S. Miller --- drivers/net/atl1c/atl1c_hw.c | 15 +++++++-------- drivers/net/atl1c/atl1c_hw.h | 43 ++----------------------------------------- 2 files changed, 9 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/net/atl1c/atl1c_hw.c b/drivers/net/atl1c/atl1c_hw.c index 1bf672009948..23f2ab0f2fa8 100644 --- a/drivers/net/atl1c/atl1c_hw.c +++ b/drivers/net/atl1c/atl1c_hw.c @@ -345,7 +345,7 @@ int atl1c_write_phy_reg(struct atl1c_hw *hw, u32 reg_addr, u16 phy_data) */ static int atl1c_phy_setup_adv(struct atl1c_hw *hw) { - u16 mii_adv_data = ADVERTISE_DEFAULT_CAP & ~ADVERTISE_SPEED_MASK; + u16 mii_adv_data = ADVERTISE_DEFAULT_CAP & ~ADVERTISE_ALL; u16 mii_giga_ctrl_data = GIGA_CR_1000T_DEFAULT_CAP & ~GIGA_CR_1000T_SPEED_MASK; @@ -373,7 +373,7 @@ static int atl1c_phy_setup_adv(struct atl1c_hw *hw) } if (atl1c_write_phy_reg(hw, MII_ADVERTISE, mii_adv_data) != 0 || - atl1c_write_phy_reg(hw, MII_GIGA_CR, mii_giga_ctrl_data) != 0) + atl1c_write_phy_reg(hw, MII_CTRL1000, mii_giga_ctrl_data) != 0) return -1; return 0; } @@ -517,19 +517,18 @@ int atl1c_phy_init(struct atl1c_hw *hw) "Error Setting up Auto-Negotiation\n"); return ret_val; } - mii_bmcr_data |= BMCR_AUTO_NEG_EN | BMCR_RESTART_AUTO_NEG; + mii_bmcr_data |= BMCR_ANENABLE | BMCR_ANRESTART; break; case MEDIA_TYPE_100M_FULL: - mii_bmcr_data |= BMCR_SPEED_100 | BMCR_FULL_DUPLEX; + mii_bmcr_data |= BMCR_SPEED100 | BMCR_FULLDPLX; break; case MEDIA_TYPE_100M_HALF: - mii_bmcr_data |= BMCR_SPEED_100; + mii_bmcr_data |= BMCR_SPEED100; break; case MEDIA_TYPE_10M_FULL: - mii_bmcr_data |= BMCR_SPEED_10 | BMCR_FULL_DUPLEX; + mii_bmcr_data |= BMCR_FULLDPLX; break; case MEDIA_TYPE_10M_HALF: - mii_bmcr_data |= BMCR_SPEED_10; break; default: if (netif_msg_link(adapter)) @@ -657,7 +656,7 @@ int atl1c_restart_autoneg(struct atl1c_hw *hw) err = atl1c_phy_setup_adv(hw); if (err) return err; - mii_bmcr_data |= BMCR_AUTO_NEG_EN | BMCR_RESTART_AUTO_NEG; + mii_bmcr_data |= BMCR_ANENABLE | BMCR_ANRESTART; return atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data); } diff --git a/drivers/net/atl1c/atl1c_hw.h b/drivers/net/atl1c/atl1c_hw.h index 3dd675979aa1..655fc6c4a8a4 100644 --- a/drivers/net/atl1c/atl1c_hw.h +++ b/drivers/net/atl1c/atl1c_hw.h @@ -736,55 +736,16 @@ int atl1c_phy_power_saving(struct atl1c_hw *hw); #define REG_DEBUG_DATA0 0x1900 #define REG_DEBUG_DATA1 0x1904 -/* PHY Control Register */ -#define MII_BMCR 0x00 -#define BMCR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */ -#define BMCR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */ -#define BMCR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ -#define BMCR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ -#define BMCR_ISOLATE 0x0400 /* Isolate PHY from MII */ -#define BMCR_POWER_DOWN 0x0800 /* Power down */ -#define BMCR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */ -#define BMCR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */ -#define BMCR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ -#define BMCR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ -#define BMCR_SPEED_MASK 0x2040 -#define BMCR_SPEED_1000 0x0040 -#define BMCR_SPEED_100 0x2000 -#define BMCR_SPEED_10 0x0000 - -/* PHY Status Register */ -#define MII_BMSR 0x01 -#define BMMSR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */ -#define BMSR_JABBER_DETECT 0x0002 /* Jabber Detected */ -#define BMSR_LINK_STATUS 0x0004 /* Link Status 1 = link */ -#define BMSR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */ -#define BMSR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */ -#define BMSR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ -#define BMSR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */ -#define BMSR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */ -#define BMSR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */ -#define BMSR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */ -#define BMSR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */ -#define BMSR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */ -#define BMSR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */ -#define BMMII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */ -#define BMMII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */ - -#define MII_PHYSID1 0x02 -#define MII_PHYSID2 0x03 #define L1D_MPW_PHYID1 0xD01C /* V7 */ #define L1D_MPW_PHYID2 0xD01D /* V1-V6 */ #define L1D_MPW_PHYID3 0xD01E /* V8 */ /* Autoneg Advertisement Register */ -#define MII_ADVERTISE 0x04 -#define ADVERTISE_SPEED_MASK 0x01E0 -#define ADVERTISE_DEFAULT_CAP 0x0DE0 +#define ADVERTISE_DEFAULT_CAP \ + (ADVERTISE_ALL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM) /* 1000BASE-T Control Register */ -#define MII_GIGA_CR 0x09 #define GIGA_CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port 0=DTE device */ #define GIGA_CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master 0=Configure PHY as Slave */ -- cgit v1.2.3 From ccd5c8ef24590bd0e1277ae6f6c0b7790afd371d Mon Sep 17 00:00:00 2001 From: françois romieu Date: Thu, 20 Jan 2011 04:59:23 +0000 Subject: atl1e: remove private #define. Either unused or duplicates from mii.h. Signed-off-by: Francois Romieu Cc: Jay Cliburn Cc: Chris Snook Cc: Jie Yang Signed-off-by: David S. Miller --- drivers/net/atl1e/atl1e_ethtool.c | 12 ++--- drivers/net/atl1e/atl1e_hw.c | 34 +++++------- drivers/net/atl1e/atl1e_hw.h | 111 ++------------------------------------ drivers/net/atl1e/atl1e_main.c | 4 +- 4 files changed, 25 insertions(+), 136 deletions(-) (limited to 'drivers') diff --git a/drivers/net/atl1e/atl1e_ethtool.c b/drivers/net/atl1e/atl1e_ethtool.c index 6943a6c3b948..1209297433b8 100644 --- a/drivers/net/atl1e/atl1e_ethtool.c +++ b/drivers/net/atl1e/atl1e_ethtool.c @@ -95,18 +95,18 @@ static int atl1e_set_settings(struct net_device *netdev, ecmd->advertising = hw->autoneg_advertised | ADVERTISED_TP | ADVERTISED_Autoneg; - adv4 = hw->mii_autoneg_adv_reg & ~MII_AR_SPEED_MASK; + adv4 = hw->mii_autoneg_adv_reg & ~ADVERTISE_ALL; adv9 = hw->mii_1000t_ctrl_reg & ~MII_AT001_CR_1000T_SPEED_MASK; if (hw->autoneg_advertised & ADVERTISE_10_HALF) - adv4 |= MII_AR_10T_HD_CAPS; + adv4 |= ADVERTISE_10HALF; if (hw->autoneg_advertised & ADVERTISE_10_FULL) - adv4 |= MII_AR_10T_FD_CAPS; + adv4 |= ADVERTISE_10FULL; if (hw->autoneg_advertised & ADVERTISE_100_HALF) - adv4 |= MII_AR_100TX_HD_CAPS; + adv4 |= ADVERTISE_100HALF; if (hw->autoneg_advertised & ADVERTISE_100_FULL) - adv4 |= MII_AR_100TX_FD_CAPS; + adv4 |= ADVERTISE_100FULL; if (hw->autoneg_advertised & ADVERTISE_1000_FULL) - adv9 |= MII_AT001_CR_1000T_FD_CAPS; + adv9 |= ADVERTISE_1000FULL; if (adv4 != hw->mii_autoneg_adv_reg || adv9 != hw->mii_1000t_ctrl_reg) { diff --git a/drivers/net/atl1e/atl1e_hw.c b/drivers/net/atl1e/atl1e_hw.c index 76cc043def8c..923063d2e5bb 100644 --- a/drivers/net/atl1e/atl1e_hw.c +++ b/drivers/net/atl1e/atl1e_hw.c @@ -318,7 +318,7 @@ static int atl1e_phy_setup_autoneg_adv(struct atl1e_hw *hw) * Advertisement Register (Address 4) and the 1000 mb speed bits in * the 1000Base-T control Register (Address 9). */ - mii_autoneg_adv_reg &= ~MII_AR_SPEED_MASK; + mii_autoneg_adv_reg &= ~ADVERTISE_ALL; mii_1000t_ctrl_reg &= ~MII_AT001_CR_1000T_SPEED_MASK; /* @@ -327,44 +327,37 @@ static int atl1e_phy_setup_autoneg_adv(struct atl1e_hw *hw) */ switch (hw->media_type) { case MEDIA_TYPE_AUTO_SENSOR: - mii_autoneg_adv_reg |= (MII_AR_10T_HD_CAPS | - MII_AR_10T_FD_CAPS | - MII_AR_100TX_HD_CAPS | - MII_AR_100TX_FD_CAPS); - hw->autoneg_advertised = ADVERTISE_10_HALF | - ADVERTISE_10_FULL | - ADVERTISE_100_HALF | - ADVERTISE_100_FULL; + mii_autoneg_adv_reg |= ADVERTISE_ALL; + hw->autoneg_advertised = ADVERTISE_ALL; if (hw->nic_type == athr_l1e) { - mii_1000t_ctrl_reg |= - MII_AT001_CR_1000T_FD_CAPS; + mii_1000t_ctrl_reg |= ADVERTISE_1000FULL; hw->autoneg_advertised |= ADVERTISE_1000_FULL; } break; case MEDIA_TYPE_100M_FULL: - mii_autoneg_adv_reg |= MII_AR_100TX_FD_CAPS; + mii_autoneg_adv_reg |= ADVERTISE_100FULL; hw->autoneg_advertised = ADVERTISE_100_FULL; break; case MEDIA_TYPE_100M_HALF: - mii_autoneg_adv_reg |= MII_AR_100TX_HD_CAPS; + mii_autoneg_adv_reg |= ADVERTISE_100_HALF; hw->autoneg_advertised = ADVERTISE_100_HALF; break; case MEDIA_TYPE_10M_FULL: - mii_autoneg_adv_reg |= MII_AR_10T_FD_CAPS; + mii_autoneg_adv_reg |= ADVERTISE_10_FULL; hw->autoneg_advertised = ADVERTISE_10_FULL; break; default: - mii_autoneg_adv_reg |= MII_AR_10T_HD_CAPS; + mii_autoneg_adv_reg |= ADVERTISE_10_HALF; hw->autoneg_advertised = ADVERTISE_10_HALF; break; } /* flow control fixed to enable all */ - mii_autoneg_adv_reg |= (MII_AR_ASM_DIR | MII_AR_PAUSE); + mii_autoneg_adv_reg |= (ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP); hw->mii_autoneg_adv_reg = mii_autoneg_adv_reg; hw->mii_1000t_ctrl_reg = mii_1000t_ctrl_reg; @@ -374,7 +367,7 @@ static int atl1e_phy_setup_autoneg_adv(struct atl1e_hw *hw) return ret_val; if (hw->nic_type == athr_l1e || hw->nic_type == athr_l2e_revA) { - ret_val = atl1e_write_phy_reg(hw, MII_AT001_CR, + ret_val = atl1e_write_phy_reg(hw, MII_CTRL1000, mii_1000t_ctrl_reg); if (ret_val) return ret_val; @@ -397,7 +390,7 @@ int atl1e_phy_commit(struct atl1e_hw *hw) int ret_val; u16 phy_data; - phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG; + phy_data = BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART; ret_val = atl1e_write_phy_reg(hw, MII_BMCR, phy_data); if (ret_val) { @@ -645,15 +638,14 @@ int atl1e_restart_autoneg(struct atl1e_hw *hw) return err; if (hw->nic_type == athr_l1e || hw->nic_type == athr_l2e_revA) { - err = atl1e_write_phy_reg(hw, MII_AT001_CR, + err = atl1e_write_phy_reg(hw, MII_CTRL1000, hw->mii_1000t_ctrl_reg); if (err) return err; } err = atl1e_write_phy_reg(hw, MII_BMCR, - MII_CR_RESET | MII_CR_AUTO_NEG_EN | - MII_CR_RESTART_AUTO_NEG); + BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART); return err; } diff --git a/drivers/net/atl1e/atl1e_hw.h b/drivers/net/atl1e/atl1e_hw.h index 5ea2f4d86cfa..74df16aef793 100644 --- a/drivers/net/atl1e/atl1e_hw.h +++ b/drivers/net/atl1e/atl1e_hw.h @@ -629,127 +629,24 @@ s32 atl1e_restart_autoneg(struct atl1e_hw *hw); /***************************** MII definition ***************************************/ /* PHY Common Register */ -#define MII_BMCR 0x00 -#define MII_BMSR 0x01 -#define MII_PHYSID1 0x02 -#define MII_PHYSID2 0x03 -#define MII_ADVERTISE 0x04 -#define MII_LPA 0x05 -#define MII_EXPANSION 0x06 -#define MII_AT001_CR 0x09 -#define MII_AT001_SR 0x0A -#define MII_AT001_ESR 0x0F #define MII_AT001_PSCR 0x10 #define MII_AT001_PSSR 0x11 #define MII_INT_CTRL 0x12 #define MII_INT_STATUS 0x13 #define MII_SMARTSPEED 0x14 -#define MII_RERRCOUNTER 0x15 -#define MII_SREVISION 0x16 -#define MII_RESV1 0x17 #define MII_LBRERROR 0x18 -#define MII_PHYADDR 0x19 #define MII_RESV2 0x1a -#define MII_TPISTATUS 0x1b -#define MII_NCONFIG 0x1c #define MII_DBG_ADDR 0x1D #define MII_DBG_DATA 0x1E - -/* PHY Control Register */ -#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */ -#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */ -#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ -#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ -#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */ -#define MII_CR_POWER_DOWN 0x0800 /* Power down */ -#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */ -#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */ -#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ -#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ -#define MII_CR_SPEED_MASK 0x2040 -#define MII_CR_SPEED_1000 0x0040 -#define MII_CR_SPEED_100 0x2000 -#define MII_CR_SPEED_10 0x0000 - - -/* PHY Status Register */ -#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */ -#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */ -#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */ -#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */ -#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */ -#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ -#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */ -#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */ -#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */ -#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */ -#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */ -#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */ -#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */ -#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */ -#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */ - -/* Link partner ability register. */ -#define MII_LPA_SLCT 0x001f /* Same as advertise selector */ -#define MII_LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */ -#define MII_LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */ -#define MII_LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */ -#define MII_LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */ -#define MII_LPA_100BASE4 0x0200 /* 100BASE-T4 */ -#define MII_LPA_PAUSE 0x0400 /* PAUSE */ -#define MII_LPA_ASYPAUSE 0x0800 /* Asymmetrical PAUSE */ -#define MII_LPA_RFAULT 0x2000 /* Link partner faulted */ -#define MII_LPA_LPACK 0x4000 /* Link partner acked us */ -#define MII_LPA_NPAGE 0x8000 /* Next page bit */ - /* Autoneg Advertisement Register */ -#define MII_AR_SELECTOR_FIELD 0x0001 /* indicates IEEE 802.3 CSMA/CD */ -#define MII_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */ -#define MII_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */ -#define MII_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */ -#define MII_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */ -#define MII_AR_100T4_CAPS 0x0200 /* 100T4 Capable */ -#define MII_AR_PAUSE 0x0400 /* Pause operation desired */ -#define MII_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */ -#define MII_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */ -#define MII_AR_NEXT_PAGE 0x8000 /* Next Page ability supported */ -#define MII_AR_SPEED_MASK 0x01E0 -#define MII_AR_DEFAULT_CAP_MASK 0x0DE0 +#define MII_AR_DEFAULT_CAP_MASK 0 /* 1000BASE-T Control Register */ -#define MII_AT001_CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */ -#define MII_AT001_CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */ -#define MII_AT001_CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port */ -/* 0=DTE device */ -#define MII_AT001_CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master */ -/* 0=Configure PHY as Slave */ -#define MII_AT001_CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value */ -/* 0=Automatic Master/Slave config */ -#define MII_AT001_CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */ -#define MII_AT001_CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */ -#define MII_AT001_CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */ -#define MII_AT001_CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */ -#define MII_AT001_CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */ -#define MII_AT001_CR_1000T_SPEED_MASK 0x0300 -#define MII_AT001_CR_1000T_DEFAULT_CAP_MASK 0x0300 - -/* 1000BASE-T Status Register */ -#define MII_AT001_SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */ -#define MII_AT001_SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */ -#define MII_AT001_SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */ -#define MII_AT001_SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */ -#define MII_AT001_SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local TX is Master, 0=Slave */ -#define MII_AT001_SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */ -#define MII_AT001_SR_1000T_REMOTE_RX_STATUS_SHIFT 12 -#define MII_AT001_SR_1000T_LOCAL_RX_STATUS_SHIFT 13 - -/* Extended Status Register */ -#define MII_AT001_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */ -#define MII_AT001_ESR_1000T_FD_CAPS 0x2000 /* 1000T FD capable */ -#define MII_AT001_ESR_1000X_HD_CAPS 0x4000 /* 1000X HD capable */ -#define MII_AT001_ESR_1000X_FD_CAPS 0x8000 /* 1000X FD capable */ +#define MII_AT001_CR_1000T_SPEED_MASK \ + (ADVERTISE_1000FULL | ADVERTISE_1000HALF) +#define MII_AT001_CR_1000T_DEFAULT_CAP_MASK MII_AT001_CR_1000T_SPEED_MASK /* AT001 PHY Specific Control Register */ #define MII_AT001_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Function disabled */ diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index e28f8baf394e..bf7500ccd73f 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -2051,9 +2051,9 @@ static int atl1e_suspend(struct pci_dev *pdev, pm_message_t state) atl1e_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data); atl1e_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data); - mii_advertise_data = MII_AR_10T_HD_CAPS; + mii_advertise_data = ADVERTISE_10HALF; - if ((atl1e_write_phy_reg(hw, MII_AT001_CR, 0) != 0) || + if ((atl1e_write_phy_reg(hw, MII_CTRL1000, 0) != 0) || (atl1e_write_phy_reg(hw, MII_ADVERTISE, mii_advertise_data) != 0) || (atl1e_phy_commit(hw)) != 0) { -- cgit v1.2.3 From 2ffa007eaa01cf5fedd6a71f7d43854339a831ee Mon Sep 17 00:00:00 2001 From: françois romieu Date: Thu, 20 Jan 2011 04:59:33 +0000 Subject: via-velocity: fix the WOL bug on 1000M full duplex forced mode. The VIA velocity card can't be waken up by WOL tool on 1000M full duplex forced mode. This patch fixes the bug. Signed-off-by: David Lv Acked-by: Francois Romieu Signed-off-by: David S. Miller --- drivers/net/via-velocity.c | 9 +++++++++ drivers/net/via-velocity.h | 8 ++++---- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 09cac704fdd7..0d6fec6b7d93 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -2923,6 +2923,7 @@ static u16 wol_calc_crc(int size, u8 *pattern, u8 *mask_pattern) static int velocity_set_wol(struct velocity_info *vptr) { struct mac_regs __iomem *regs = vptr->mac_regs; + enum speed_opt spd_dpx = vptr->options.spd_dpx; static u8 buf[256]; int i; @@ -2968,6 +2969,12 @@ static int velocity_set_wol(struct velocity_info *vptr) writew(0x0FFF, ®s->WOLSRClr); + if (spd_dpx == SPD_DPX_1000_FULL) + goto mac_done; + + if (spd_dpx != SPD_DPX_AUTO) + goto advertise_done; + if (vptr->mii_status & VELOCITY_AUTONEG_ENABLE) { if (PHYID_GET_PHY_ID(vptr->phy_id) == PHYID_CICADA_CS8201) MII_REG_BITS_ON(AUXCR_MDPPS, MII_NCONFIG, vptr->mac_regs); @@ -2978,6 +2985,7 @@ static int velocity_set_wol(struct velocity_info *vptr) if (vptr->mii_status & VELOCITY_SPEED_1000) MII_REG_BITS_ON(BMCR_ANRESTART, MII_BMCR, vptr->mac_regs); +advertise_done: BYTE_REG_BITS_ON(CHIPGCR_FCMODE, ®s->CHIPGCR); { @@ -2987,6 +2995,7 @@ static int velocity_set_wol(struct velocity_info *vptr) writeb(GCR, ®s->CHIPGCR); } +mac_done: BYTE_REG_BITS_OFF(ISR_PWEI, ®s->ISR); /* Turn on SWPTAG just before entering power mode */ BYTE_REG_BITS_ON(STICKHW_SWPTAG, ®s->STICKHW); diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h index aa2e69b9ff61..d7227539484e 100644 --- a/drivers/net/via-velocity.h +++ b/drivers/net/via-velocity.h @@ -361,7 +361,7 @@ enum velocity_owner { #define MAC_REG_CHIPGSR 0x9C #define MAC_REG_TESTCFG 0x9D #define MAC_REG_DEBUG 0x9E -#define MAC_REG_CHIPGCR 0x9F +#define MAC_REG_CHIPGCR 0x9F /* Chip Operation and Diagnostic Control */ #define MAC_REG_WOLCR0_SET 0xA0 #define MAC_REG_WOLCR1_SET 0xA1 #define MAC_REG_PWCFG_SET 0xA2 @@ -848,10 +848,10 @@ enum velocity_owner { * Bits in CHIPGCR register */ -#define CHIPGCR_FCGMII 0x80 /* enable GMII mode */ -#define CHIPGCR_FCFDX 0x40 +#define CHIPGCR_FCGMII 0x80 /* force GMII (else MII only) */ +#define CHIPGCR_FCFDX 0x40 /* force full duplex */ #define CHIPGCR_FCRESV 0x20 -#define CHIPGCR_FCMODE 0x10 +#define CHIPGCR_FCMODE 0x10 /* enable MAC forced mode */ #define CHIPGCR_LPSOPT 0x08 #define CHIPGCR_TM1US 0x04 #define CHIPGCR_TM0US 0x02 -- cgit v1.2.3 From 4dce2396b329ef6a14b40c5416d6f76005097b0d Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Thu, 20 Jan 2011 14:35:54 +0000 Subject: enic: Bug Fix: Dont reset ENIC_SET_APPLIED flag on port profile disassociate enic_get_vf_port returns port profile operation status only if ENIC_SET_APPLIED flag is set. A recent rework of enic_set_port_profile added code to reset this flag on disassociate. As a result of which a client calling enic_get_vf_port to get the status of port profile disassociate will always get a return value of ENODATA. This patch renames ENIC_SET_APPLIED to more appropriate ENIC_PORT_REQUEST_APPLIED and reverts back the recent change so that the flag is set both at associate and disassociate of a port profile. Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: Christian Benvenuti Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 6 +++--- drivers/net/enic/enic_main.c | 10 ++++++---- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index a937f49d9db7..ca3be4f15556 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,8 +32,8 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "1.4.1.10" -#define DRV_COPYRIGHT "Copyright 2008-2010 Cisco Systems, Inc" +#define DRV_VERSION "2.1.1.2" +#define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 @@ -49,7 +49,7 @@ struct enic_msix_entry { void *devid; }; -#define ENIC_SET_APPLIED (1 << 0) +#define ENIC_PORT_REQUEST_APPLIED (1 << 0) #define ENIC_SET_REQUEST (1 << 1) #define ENIC_SET_NAME (1 << 2) #define ENIC_SET_INSTANCE (1 << 3) diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index a0af48c51fb3..89664c670972 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1318,18 +1318,20 @@ static int enic_set_port_profile(struct enic *enic, u8 *mac) vic_provinfo_free(vp); if (err) return err; - - enic->pp.set |= ENIC_SET_APPLIED; break; case PORT_REQUEST_DISASSOCIATE: - enic->pp.set &= ~ENIC_SET_APPLIED; break; default: return -EINVAL; } + /* Set flag to indicate that the port assoc/disassoc + * request has been sent out to fw + */ + enic->pp.set |= ENIC_PORT_REQUEST_APPLIED; + return 0; } @@ -1411,7 +1413,7 @@ static int enic_get_vf_port(struct net_device *netdev, int vf, int err, error, done; u16 response = PORT_PROFILE_RESPONSE_SUCCESS; - if (!(enic->pp.set & ENIC_SET_APPLIED)) + if (!(enic->pp.set & ENIC_PORT_REQUEST_APPLIED)) return -ENODATA; err = enic_dev_init_done(enic, &done, &error); -- cgit v1.2.3 From b48f8c23c336d82c1af9a53187568bdb6e86b8a8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 20 Jan 2011 22:44:36 -0800 Subject: ppp: Clean up kernel log messages. Use netdev_*() and pr_*(). To preserve existing semantics in cases where KERN_DEBUG is indeed appropriate, use netdev_printk(KERN_DEBUG, ...) Convert PPPIOCDETACH to pr_warn() because an unexpected file count is a serious bug and should be logged with KERN_WARN. Signed-off-by: David S. Miller Signed-off-by: Paul Mackerras --- drivers/net/ppp_generic.c | 86 +++++++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index c7a6c4466978..3d7a38eeacda 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -592,8 +592,8 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ppp_release(NULL, file); err = 0; } else - printk(KERN_DEBUG "PPPIOCDETACH file->f_count=%ld\n", - atomic_long_read(&file->f_count)); + pr_warn("PPPIOCDETACH file->f_count=%ld\n", + atomic_long_read(&file->f_count)); mutex_unlock(&ppp_mutex); return err; } @@ -630,7 +630,7 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (pf->kind != INTERFACE) { /* can't happen */ - printk(KERN_ERR "PPP: not interface or channel??\n"); + pr_err("PPP: not interface or channel??\n"); return -EINVAL; } @@ -704,7 +704,8 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } vj = slhc_init(val2+1, val+1); if (!vj) { - printk(KERN_ERR "PPP: no memory (VJ compressor)\n"); + netdev_err(ppp->dev, + "PPP: no memory (VJ compressor)\n"); err = -ENOMEM; break; } @@ -898,17 +899,17 @@ static int __init ppp_init(void) { int err; - printk(KERN_INFO "PPP generic driver version " PPP_VERSION "\n"); + pr_info("PPP generic driver version " PPP_VERSION "\n"); err = register_pernet_device(&ppp_net_ops); if (err) { - printk(KERN_ERR "failed to register PPP pernet device (%d)\n", err); + pr_err("failed to register PPP pernet device (%d)\n", err); goto out; } err = register_chrdev(PPP_MAJOR, "ppp", &ppp_device_fops); if (err) { - printk(KERN_ERR "failed to register PPP device (%d)\n", err); + pr_err("failed to register PPP device (%d)\n", err); goto out_net; } @@ -1078,7 +1079,7 @@ pad_compress_skb(struct ppp *ppp, struct sk_buff *skb) new_skb = alloc_skb(new_skb_size, GFP_ATOMIC); if (!new_skb) { if (net_ratelimit()) - printk(KERN_ERR "PPP: no memory (comp pkt)\n"); + netdev_err(ppp->dev, "PPP: no memory (comp pkt)\n"); return NULL; } if (ppp->dev->hard_header_len > PPP_HDRLEN) @@ -1108,7 +1109,7 @@ pad_compress_skb(struct ppp *ppp, struct sk_buff *skb) * the same number. */ if (net_ratelimit()) - printk(KERN_ERR "ppp: compressor dropped pkt\n"); + netdev_err(ppp->dev, "ppp: compressor dropped pkt\n"); kfree_skb(skb); kfree_skb(new_skb); new_skb = NULL; @@ -1138,7 +1139,9 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) if (ppp->pass_filter && sk_run_filter(skb, ppp->pass_filter) == 0) { if (ppp->debug & 1) - printk(KERN_DEBUG "PPP: outbound frame not passed\n"); + netdev_printk(KERN_DEBUG, ppp->dev, + "PPP: outbound frame " + "not passed\n"); kfree_skb(skb); return; } @@ -1164,7 +1167,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) new_skb = alloc_skb(skb->len + ppp->dev->hard_header_len - 2, GFP_ATOMIC); if (!new_skb) { - printk(KERN_ERR "PPP: no memory (VJ comp pkt)\n"); + netdev_err(ppp->dev, "PPP: no memory (VJ comp pkt)\n"); goto drop; } skb_reserve(new_skb, ppp->dev->hard_header_len - 2); @@ -1202,7 +1205,9 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) proto != PPP_LCP && proto != PPP_CCP) { if (!(ppp->flags & SC_CCP_UP) && (ppp->flags & SC_MUST_COMP)) { if (net_ratelimit()) - printk(KERN_ERR "ppp: compression required but down - pkt dropped.\n"); + netdev_err(ppp->dev, + "ppp: compression required but " + "down - pkt dropped.\n"); goto drop; } skb = pad_compress_skb(ppp, skb); @@ -1505,7 +1510,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) noskb: spin_unlock_bh(&pch->downl); if (ppp->debug & 1) - printk(KERN_ERR "PPP: no memory (fragment)\n"); + netdev_err(ppp->dev, "PPP: no memory (fragment)\n"); ++ppp->dev->stats.tx_errors; ++ppp->nxseq; return 1; /* abandon the frame */ @@ -1686,7 +1691,8 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) /* copy to a new sk_buff with more tailroom */ ns = dev_alloc_skb(skb->len + 128); if (!ns) { - printk(KERN_ERR"PPP: no memory (VJ decomp)\n"); + netdev_err(ppp->dev, "PPP: no memory " + "(VJ decomp)\n"); goto err; } skb_reserve(ns, 2); @@ -1699,7 +1705,8 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) len = slhc_uncompress(ppp->vj, skb->data + 2, skb->len - 2); if (len <= 0) { - printk(KERN_DEBUG "PPP: VJ decompression error\n"); + netdev_printk(KERN_DEBUG, ppp->dev, + "PPP: VJ decompression error\n"); goto err; } len += 2; @@ -1721,7 +1728,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) goto err; if (slhc_remember(ppp->vj, skb->data + 2, skb->len - 2) <= 0) { - printk(KERN_ERR "PPP: VJ uncompressed error\n"); + netdev_err(ppp->dev, "PPP: VJ uncompressed error\n"); goto err; } proto = PPP_IP; @@ -1762,8 +1769,9 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) if (ppp->pass_filter && sk_run_filter(skb, ppp->pass_filter) == 0) { if (ppp->debug & 1) - printk(KERN_DEBUG "PPP: inbound frame " - "not passed\n"); + netdev_printk(KERN_DEBUG, ppp->dev, + "PPP: inbound frame " + "not passed\n"); kfree_skb(skb); return; } @@ -1821,7 +1829,8 @@ ppp_decompress_frame(struct ppp *ppp, struct sk_buff *skb) ns = dev_alloc_skb(obuff_size); if (!ns) { - printk(KERN_ERR "ppp_decompress_frame: no memory\n"); + netdev_err(ppp->dev, "ppp_decompress_frame: " + "no memory\n"); goto err; } /* the decompressor still expects the A/C bytes in the hdr */ @@ -2002,8 +2011,9 @@ ppp_mp_reconstruct(struct ppp *ppp) next = p->next; if (seq_before(PPP_MP_CB(p)->sequence, seq)) { /* this can't happen, anyway ignore the skb */ - printk(KERN_ERR "ppp_mp_reconstruct bad seq %u < %u\n", - PPP_MP_CB(p)->sequence, seq); + netdev_err(ppp->dev, "ppp_mp_reconstruct bad " + "seq %u < %u\n", + PPP_MP_CB(p)->sequence, seq); head = next; continue; } @@ -2042,8 +2052,9 @@ ppp_mp_reconstruct(struct ppp *ppp) (PPP_MP_CB(head)->BEbits & B)) { if (len > ppp->mrru + 2) { ++ppp->dev->stats.rx_length_errors; - printk(KERN_DEBUG "PPP: reconstructed packet" - " is too long (%d)\n", len); + netdev_printk(KERN_DEBUG, ppp->dev, + "PPP: reconstructed packet" + " is too long (%d)\n", len); } else if (p == head) { /* fragment is complete packet - reuse skb */ tail = p; @@ -2051,8 +2062,9 @@ ppp_mp_reconstruct(struct ppp *ppp) break; } else if ((skb = dev_alloc_skb(len)) == NULL) { ++ppp->dev->stats.rx_missed_errors; - printk(KERN_DEBUG "PPP: no memory for " - "reconstructed packet"); + netdev_printk(KERN_DEBUG, ppp->dev, + "PPP: no memory for " + "reconstructed packet"); } else { tail = p; break; @@ -2077,9 +2089,10 @@ ppp_mp_reconstruct(struct ppp *ppp) signal a receive error. */ if (PPP_MP_CB(head)->sequence != ppp->nextseq) { if (ppp->debug & 1) - printk(KERN_DEBUG " missed pkts %u..%u\n", - ppp->nextseq, - PPP_MP_CB(head)->sequence-1); + netdev_printk(KERN_DEBUG, ppp->dev, + " missed pkts %u..%u\n", + ppp->nextseq, + PPP_MP_CB(head)->sequence-1); ++ppp->dev->stats.rx_dropped; ppp_receive_error(ppp); } @@ -2617,8 +2630,8 @@ ppp_create_interface(struct net *net, int unit, int *retp) ret = register_netdev(dev); if (ret != 0) { unit_put(&pn->units_idr, unit); - printk(KERN_ERR "PPP: couldn't register device %s (%d)\n", - dev->name, ret); + netdev_err(ppp->dev, "PPP: couldn't register device %s (%d)\n", + dev->name, ret); goto out2; } @@ -2690,9 +2703,9 @@ static void ppp_destroy_interface(struct ppp *ppp) if (!ppp->file.dead || ppp->n_channels) { /* "can't happen" */ - printk(KERN_ERR "ppp: destroying ppp struct %p but dead=%d " - "n_channels=%d !\n", ppp, ppp->file.dead, - ppp->n_channels); + netdev_err(ppp->dev, "ppp: destroying ppp struct %p " + "but dead=%d n_channels=%d !\n", + ppp, ppp->file.dead, ppp->n_channels); return; } @@ -2834,8 +2847,7 @@ static void ppp_destroy_channel(struct channel *pch) if (!pch->file.dead) { /* "can't happen" */ - printk(KERN_ERR "ppp: destroying undead channel %p !\n", - pch); + pr_err("ppp: destroying undead channel %p !\n", pch); return; } skb_queue_purge(&pch->file.xq); @@ -2847,7 +2859,7 @@ static void __exit ppp_cleanup(void) { /* should never happen */ if (atomic_read(&ppp_unit_count) || atomic_read(&channel_count)) - printk(KERN_ERR "PPP: removing module but units remain!\n"); + pr_err("PPP: removing module but units remain!\n"); unregister_chrdev(PPP_MAJOR, "ppp"); device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0)); class_destroy(ppp_class); @@ -2865,7 +2877,7 @@ static int __unit_alloc(struct idr *p, void *ptr, int n) again: if (!idr_pre_get(p, GFP_KERNEL)) { - printk(KERN_ERR "PPP: No free memory for idr\n"); + pr_err("PPP: No free memory for idr\n"); return -ENOMEM; } -- cgit v1.2.3 From 212bfb9e94e86b40684076f642b089b0565455d2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 20 Jan 2011 22:46:07 -0800 Subject: ppp: Reconstruct fragmented packets using frag lists instead of copying. [paulus@samba.org: fixed a couple of bugs] Signed-off-by: David S. Miller Signed-off-by: Paul Mackerras --- drivers/net/ppp_generic.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 3d7a38eeacda..1d4fb348488f 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -2055,16 +2055,6 @@ ppp_mp_reconstruct(struct ppp *ppp) netdev_printk(KERN_DEBUG, ppp->dev, "PPP: reconstructed packet" " is too long (%d)\n", len); - } else if (p == head) { - /* fragment is complete packet - reuse skb */ - tail = p; - skb = skb_get(p); - break; - } else if ((skb = dev_alloc_skb(len)) == NULL) { - ++ppp->dev->stats.rx_missed_errors; - netdev_printk(KERN_DEBUG, ppp->dev, - "PPP: no memory for " - "reconstructed packet"); } else { tail = p; break; @@ -2097,16 +2087,33 @@ ppp_mp_reconstruct(struct ppp *ppp) ppp_receive_error(ppp); } - if (head != tail) - /* copy to a single skb */ - for (p = head; p != tail->next; p = p->next) - skb_copy_bits(p, 0, skb_put(skb, p->len), p->len); + skb = head; + if (head != tail) { + struct sk_buff **fragpp = &skb_shinfo(skb)->frag_list; + p = skb_queue_next(list, head); + __skb_unlink(skb, list); + skb_queue_walk_from_safe(list, p, tmp) { + __skb_unlink(p, list); + *fragpp = p; + p->next = NULL; + fragpp = &p->next; + + skb->len += p->len; + skb->data_len += p->len; + skb->truesize += p->len; + + if (p == tail) + break; + } + } else { + __skb_unlink(skb, list); + } + ppp->nextseq = PPP_MP_CB(tail)->sequence + 1; head = tail->next; } - /* Discard all the skbuffs that we have copied the data out of - or that we can't use. */ + /* Discard all the skbuffs that we can't use. */ while ((p = list->next) != head) { __skb_unlink(p, list); kfree_skb(p); -- cgit v1.2.3 From d52344a7ae8a3fb660636f7de4f1c542b0036cbb Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 20 Jan 2011 22:52:05 -0800 Subject: ppp: Use SKB queue abstraction interfaces in fragment processing. No more direct references to SKB queue and list implementation details. Signed-off-by: David S. Miller --- drivers/net/ppp_generic.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 1d4fb348488f..9f6d670748d1 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -1998,7 +1998,7 @@ ppp_mp_reconstruct(struct ppp *ppp) u32 seq = ppp->nextseq; u32 minseq = ppp->minseq; struct sk_buff_head *list = &ppp->mrq; - struct sk_buff *p, *next; + struct sk_buff *p, *tmp; struct sk_buff *head, *tail; struct sk_buff *skb = NULL; int lost = 0, len = 0; @@ -2007,14 +2007,15 @@ ppp_mp_reconstruct(struct ppp *ppp) return NULL; head = list->next; tail = NULL; - for (p = head; p != (struct sk_buff *) list; p = next) { - next = p->next; + skb_queue_walk_safe(list, p, tmp) { + again: if (seq_before(PPP_MP_CB(p)->sequence, seq)) { /* this can't happen, anyway ignore the skb */ netdev_err(ppp->dev, "ppp_mp_reconstruct bad " "seq %u < %u\n", PPP_MP_CB(p)->sequence, seq); - head = next; + __skb_unlink(p, list); + kfree_skb(p); continue; } if (PPP_MP_CB(p)->sequence != seq) { @@ -2026,8 +2027,7 @@ ppp_mp_reconstruct(struct ppp *ppp) lost = 1; seq = seq_before(minseq, PPP_MP_CB(p)->sequence)? minseq + 1: PPP_MP_CB(p)->sequence; - next = p; - continue; + goto again; } /* @@ -2067,9 +2067,17 @@ ppp_mp_reconstruct(struct ppp *ppp) * and we haven't found a complete valid packet yet, * we can discard up to and including this fragment. */ - if (PPP_MP_CB(p)->BEbits & E) - head = next; + if (PPP_MP_CB(p)->BEbits & E) { + struct sk_buff *tmp2; + skb_queue_reverse_walk_from_safe(list, p, tmp2) { + __skb_unlink(p, list); + kfree_skb(p); + } + head = skb_peek(list); + if (!head) + break; + } ++seq; } @@ -2110,13 +2118,6 @@ ppp_mp_reconstruct(struct ppp *ppp) } ppp->nextseq = PPP_MP_CB(tail)->sequence + 1; - head = tail->next; - } - - /* Discard all the skbuffs that we can't use. */ - while ((p = list->next) != head) { - __skb_unlink(p, list); - kfree_skb(p); } return skb; -- cgit v1.2.3 From c9e358dfc4a8cb2227172ef77908c2e0ee17bcb9 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 21 Jan 2011 09:24:48 -0700 Subject: driver-core: remove conditionals around devicetree pointers Having conditional around the of_match_table and the of_node pointers turns out to make driver code use ugly #ifdef blocks. Drop the conditionals and remove the #ifdef blocks from the affected drivers. Also tidy up minor whitespace issues within the same hunks. Signed-off-by: Grant Likely Acked-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-ocores.c | 14 +++----------- drivers/i2c/i2c-core.c | 2 -- drivers/mmc/host/mmc_spi.c | 4 ---- drivers/net/ethoc.c | 8 +------- drivers/spi/pxa2xx_spi.c | 2 -- drivers/spi/pxa2xx_spi_pci.c | 2 -- drivers/spi/xilinx_spi.c | 6 ------ include/linux/device.h | 7 ++----- include/linux/i2c.h | 2 -- include/linux/of.h | 4 ++-- 10 files changed, 8 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index ef3bcb1ce864..c2ef5ce1f1ff 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -330,9 +330,7 @@ static int __devinit ocores_i2c_probe(struct platform_device *pdev) i2c->adap = ocores_adapter; i2c_set_adapdata(&i2c->adap, i2c); i2c->adap.dev.parent = &pdev->dev; -#ifdef CONFIG_OF i2c->adap.dev.of_node = pdev->dev.of_node; -#endif /* add i2c adapter to i2c tree */ ret = i2c_add_adapter(&i2c->adap); @@ -390,15 +388,11 @@ static int ocores_i2c_resume(struct platform_device *pdev) #define ocores_i2c_resume NULL #endif -#ifdef CONFIG_OF static struct of_device_id ocores_i2c_match[] = { - { - .compatible = "opencores,i2c-ocores", - }, - {}, + { .compatible = "opencores,i2c-ocores", }, + {}, }; MODULE_DEVICE_TABLE(of, ocores_i2c_match); -#endif /* work with hotplug and coldplug */ MODULE_ALIAS("platform:ocores-i2c"); @@ -411,9 +405,7 @@ static struct platform_driver ocores_i2c_driver = { .driver = { .owner = THIS_MODULE, .name = "ocores-i2c", -#ifdef CONFIG_OF - .of_match_table = ocores_i2c_match, -#endif + .of_match_table = ocores_i2c_match, }, }; diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index f0bd5bcdf563..045ba6efea48 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -537,9 +537,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) client->dev.parent = &client->adapter->dev; client->dev.bus = &i2c_bus_type; client->dev.type = &i2c_client_type; -#ifdef CONFIG_OF client->dev.of_node = info->of_node; -#endif dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap), client->addr); diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index fd877f633dd2..2f7fc0c5146f 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -1516,21 +1516,17 @@ static int __devexit mmc_spi_remove(struct spi_device *spi) return 0; } -#if defined(CONFIG_OF) static struct of_device_id mmc_spi_of_match_table[] __devinitdata = { { .compatible = "mmc-spi-slot", }, {}, }; -#endif static struct spi_driver mmc_spi_driver = { .driver = { .name = "mmc_spi", .bus = &spi_bus_type, .owner = THIS_MODULE, -#if defined(CONFIG_OF) .of_match_table = mmc_spi_of_match_table, -#endif }, .probe = mmc_spi_probe, .remove = __devexit_p(mmc_spi_remove), diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index b79d7e1555d5..db0290f05bdf 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -1163,15 +1163,11 @@ static int ethoc_resume(struct platform_device *pdev) # define ethoc_resume NULL #endif -#ifdef CONFIG_OF static struct of_device_id ethoc_match[] = { - { - .compatible = "opencores,ethoc", - }, + { .compatible = "opencores,ethoc", }, {}, }; MODULE_DEVICE_TABLE(of, ethoc_match); -#endif static struct platform_driver ethoc_driver = { .probe = ethoc_probe, @@ -1181,9 +1177,7 @@ static struct platform_driver ethoc_driver = { .driver = { .name = "ethoc", .owner = THIS_MODULE, -#ifdef CONFIG_OF .of_match_table = ethoc_match, -#endif }, }; diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 95928833855b..a429b01d0285 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -1557,9 +1557,7 @@ static int __devinit pxa2xx_spi_probe(struct platform_device *pdev) drv_data->ssp = ssp; master->dev.parent = &pdev->dev; -#ifdef CONFIG_OF master->dev.of_node = pdev->dev.of_node; -#endif /* the spi->mode bits understood by this driver: */ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; diff --git a/drivers/spi/pxa2xx_spi_pci.c b/drivers/spi/pxa2xx_spi_pci.c index 351d8a375b57..b6589bb3a6c3 100644 --- a/drivers/spi/pxa2xx_spi_pci.c +++ b/drivers/spi/pxa2xx_spi_pci.c @@ -98,9 +98,7 @@ static int __devinit ce4100_spi_probe(struct pci_dev *dev, pdev->dev.parent = &dev->dev; pdev->dev.platform_data = &spi_info->spi_pdata; -#ifdef CONFIG_OF pdev->dev.of_node = dev->dev.of_node; -#endif pdev->dev.release = plat_dev_release; spi_pdata->num_chipselect = dev->devfn; diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index 7adaef62a991..4d2c75df886c 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c @@ -351,14 +351,12 @@ static irqreturn_t xilinx_spi_irq(int irq, void *dev_id) return IRQ_HANDLED; } -#ifdef CONFIG_OF static const struct of_device_id xilinx_spi_of_match[] = { { .compatible = "xlnx,xps-spi-2.00.a", }, { .compatible = "xlnx,xps-spi-2.00.b", }, {} }; MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); -#endif struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, u32 irq, s16 bus_num, int num_cs, int little_endian, int bits_per_word) @@ -394,9 +392,7 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, master->bus_num = bus_num; master->num_chipselect = num_cs; -#ifdef CONFIG_OF master->dev.of_node = dev->of_node; -#endif xspi->mem = *mem; xspi->irq = irq; @@ -539,9 +535,7 @@ static struct platform_driver xilinx_spi_driver = { .driver = { .name = XILINX_SPI_NAME, .owner = THIS_MODULE, -#ifdef CONFIG_OF .of_match_table = xilinx_spi_of_match, -#endif }, }; diff --git a/include/linux/device.h b/include/linux/device.h index 1bf5cf0b4513..ca5d25225aab 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -128,9 +128,7 @@ struct device_driver { bool suppress_bind_attrs; /* disables bind/unbind via sysfs */ -#if defined(CONFIG_OF) const struct of_device_id *of_match_table; -#endif int (*probe) (struct device *dev); int (*remove) (struct device *dev); @@ -441,9 +439,8 @@ struct device { override */ /* arch specific additions */ struct dev_archdata archdata; -#ifdef CONFIG_OF - struct device_node *of_node; -#endif + + struct device_node *of_node; /* associated device tree node */ dev_t devt; /* dev_t, creates the sysfs "dev" */ diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 903576df88dc..06a8d9c7de98 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -258,9 +258,7 @@ struct i2c_board_info { unsigned short addr; void *platform_data; struct dev_archdata *archdata; -#ifdef CONFIG_OF struct device_node *of_node; -#endif int irq; }; diff --git a/include/linux/of.h b/include/linux/of.h index cad7cf0ab278..d9dd664a6a9c 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -23,8 +23,6 @@ #include -#ifdef CONFIG_OF - typedef u32 phandle; typedef u32 ihandle; @@ -65,6 +63,8 @@ struct device_node { #endif }; +#ifdef CONFIG_OF + /* Pointer for first entry in chain of all nodes. */ extern struct device_node *allnodes; extern struct device_node *of_chosen; -- cgit v1.2.3 From f8559b6920b435028ec9aed62846906bb20e47d8 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 21 Jan 2011 10:54:48 +0100 Subject: staging: brcm80211: moved code around for cleanup Restructured code to have more consistent directory tree for the two drivers. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/Kconfig | 4 +- drivers/staging/brcm80211/Makefile | 61 +- drivers/staging/brcm80211/brcmfmac/Kconfig | 15 - drivers/staging/brcm80211/brcmfmac/Makefile | 24 +- drivers/staging/brcm80211/brcmsmac/Makefile | 67 + .../staging/brcm80211/brcmsmac/phy/phy_version.h | 36 + .../staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c | 3461 +++ .../staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h | 256 + .../staging/brcm80211/brcmsmac/phy/wlc_phy_int.h | 1229 + .../staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c | 5325 ++++ .../staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h | 119 + drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c | 29239 +++++++++++++++++++ .../staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h | 1533 + .../staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h | 167 + .../brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c | 3641 +++ .../brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h | 49 + .../staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c | 10634 +++++++ .../staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h | 39 + .../staging/brcm80211/brcmsmac/sys/d11ucode_ext.h | 35 + drivers/staging/brcm80211/brcmsmac/sys/wl_dbg.h | 102 + drivers/staging/brcm80211/brcmsmac/sys/wl_export.h | 63 + .../staging/brcm80211/brcmsmac/sys/wl_mac80211.c | 1846 ++ .../staging/brcm80211/brcmsmac/sys/wl_mac80211.h | 117 + drivers/staging/brcm80211/brcmsmac/sys/wl_ucode.h | 49 + .../brcm80211/brcmsmac/sys/wl_ucode_loader.c | 89 + drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.c | 371 + drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.h | 25 + drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.c | 1356 + drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.h | 36 + .../staging/brcm80211/brcmsmac/sys/wlc_antsel.c | 329 + .../staging/brcm80211/brcmsmac/sys/wlc_antsel.h | 30 + drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.c | 4235 +++ drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.h | 273 + .../staging/brcm80211/brcmsmac/sys/wlc_bsscfg.h | 153 + drivers/staging/brcm80211/brcmsmac/sys/wlc_cfg.h | 286 + .../staging/brcm80211/brcmsmac/sys/wlc_channel.c | 1609 + .../staging/brcm80211/brcmsmac/sys/wlc_channel.h | 159 + drivers/staging/brcm80211/brcmsmac/sys/wlc_event.c | 232 + drivers/staging/brcm80211/brcmsmac/sys/wlc_event.h | 52 + drivers/staging/brcm80211/brcmsmac/sys/wlc_key.h | 144 + .../staging/brcm80211/brcmsmac/sys/wlc_mac80211.c | 8479 ++++++ .../staging/brcm80211/brcmsmac/sys/wlc_mac80211.h | 989 + .../staging/brcm80211/brcmsmac/sys/wlc_phy_shim.c | 247 + .../staging/brcm80211/brcmsmac/sys/wlc_phy_shim.h | 112 + drivers/staging/brcm80211/brcmsmac/sys/wlc_pub.h | 624 + drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.c | 501 + drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.h | 170 + drivers/staging/brcm80211/brcmsmac/sys/wlc_scb.h | 84 + drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.c | 600 + drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.h | 43 + drivers/staging/brcm80211/brcmsmac/sys/wlc_types.h | 37 + drivers/staging/brcm80211/include/bcmsdh.h | 1 + drivers/staging/brcm80211/phy/phy_version.h | 36 - drivers/staging/brcm80211/phy/wlc_phy_cmn.c | 3461 --- drivers/staging/brcm80211/phy/wlc_phy_hal.h | 256 - drivers/staging/brcm80211/phy/wlc_phy_int.h | 1229 - drivers/staging/brcm80211/phy/wlc_phy_lcn.c | 5325 ---- drivers/staging/brcm80211/phy/wlc_phy_lcn.h | 119 - drivers/staging/brcm80211/phy/wlc_phy_n.c | 29239 ------------------- drivers/staging/brcm80211/phy/wlc_phy_radio.h | 1533 - drivers/staging/brcm80211/phy/wlc_phyreg_n.h | 167 - drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c | 3641 --- drivers/staging/brcm80211/phy/wlc_phytbl_lcn.h | 49 - drivers/staging/brcm80211/phy/wlc_phytbl_n.c | 10634 ------- drivers/staging/brcm80211/phy/wlc_phytbl_n.h | 39 - drivers/staging/brcm80211/sys/d11ucode_ext.h | 35 - drivers/staging/brcm80211/sys/wl_dbg.h | 102 - drivers/staging/brcm80211/sys/wl_export.h | 63 - drivers/staging/brcm80211/sys/wl_mac80211.c | 1846 -- drivers/staging/brcm80211/sys/wl_mac80211.h | 117 - drivers/staging/brcm80211/sys/wl_ucode.h | 49 - drivers/staging/brcm80211/sys/wl_ucode_loader.c | 89 - drivers/staging/brcm80211/sys/wlc_alloc.c | 371 - drivers/staging/brcm80211/sys/wlc_alloc.h | 25 - drivers/staging/brcm80211/sys/wlc_ampdu.c | 1356 - drivers/staging/brcm80211/sys/wlc_ampdu.h | 36 - drivers/staging/brcm80211/sys/wlc_antsel.c | 329 - drivers/staging/brcm80211/sys/wlc_antsel.h | 30 - drivers/staging/brcm80211/sys/wlc_bmac.c | 4235 --- drivers/staging/brcm80211/sys/wlc_bmac.h | 273 - drivers/staging/brcm80211/sys/wlc_bsscfg.h | 153 - drivers/staging/brcm80211/sys/wlc_cfg.h | 286 - drivers/staging/brcm80211/sys/wlc_channel.c | 1609 - drivers/staging/brcm80211/sys/wlc_channel.h | 159 - drivers/staging/brcm80211/sys/wlc_event.c | 232 - drivers/staging/brcm80211/sys/wlc_event.h | 52 - drivers/staging/brcm80211/sys/wlc_key.h | 144 - drivers/staging/brcm80211/sys/wlc_mac80211.c | 8479 ------ drivers/staging/brcm80211/sys/wlc_mac80211.h | 989 - drivers/staging/brcm80211/sys/wlc_phy_shim.c | 247 - drivers/staging/brcm80211/sys/wlc_phy_shim.h | 112 - drivers/staging/brcm80211/sys/wlc_pub.h | 624 - drivers/staging/brcm80211/sys/wlc_rate.c | 501 - drivers/staging/brcm80211/sys/wlc_rate.h | 170 - drivers/staging/brcm80211/sys/wlc_scb.h | 84 - drivers/staging/brcm80211/sys/wlc_stf.c | 600 - drivers/staging/brcm80211/sys/wlc_stf.h | 43 - drivers/staging/brcm80211/sys/wlc_types.h | 37 - drivers/staging/brcm80211/util/aiutils.c | 3 - drivers/staging/brcm80211/util/bcmwifi.c | 3 - drivers/staging/brcm80211/util/hndpmu.c | 3 - drivers/staging/brcm80211/util/siutils.c | 3 - 102 files changed, 79297 insertions(+), 79297 deletions(-) delete mode 100644 drivers/staging/brcm80211/brcmfmac/Kconfig create mode 100644 drivers/staging/brcm80211/brcmsmac/Makefile create mode 100644 drivers/staging/brcm80211/brcmsmac/phy/phy_version.h create mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c create mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h create mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h create mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c create mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h create mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c create mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h create mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h create mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c create mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h create mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c create mode 100644 drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/d11ucode_ext.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wl_dbg.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wl_export.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wl_mac80211.c create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wl_mac80211.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wl_ucode.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wl_ucode_loader.c create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.c create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.c create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_antsel.c create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_antsel.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.c create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_bsscfg.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_cfg.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_channel.c create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_channel.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_event.c create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_event.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_key.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_mac80211.c create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_mac80211.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_phy_shim.c create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_phy_shim.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_pub.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.c create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_scb.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.c create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_types.h delete mode 100644 drivers/staging/brcm80211/phy/phy_version.h delete mode 100644 drivers/staging/brcm80211/phy/wlc_phy_cmn.c delete mode 100644 drivers/staging/brcm80211/phy/wlc_phy_hal.h delete mode 100644 drivers/staging/brcm80211/phy/wlc_phy_int.h delete mode 100644 drivers/staging/brcm80211/phy/wlc_phy_lcn.c delete mode 100644 drivers/staging/brcm80211/phy/wlc_phy_lcn.h delete mode 100644 drivers/staging/brcm80211/phy/wlc_phy_n.c delete mode 100644 drivers/staging/brcm80211/phy/wlc_phy_radio.h delete mode 100644 drivers/staging/brcm80211/phy/wlc_phyreg_n.h delete mode 100644 drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c delete mode 100644 drivers/staging/brcm80211/phy/wlc_phytbl_lcn.h delete mode 100644 drivers/staging/brcm80211/phy/wlc_phytbl_n.c delete mode 100644 drivers/staging/brcm80211/phy/wlc_phytbl_n.h delete mode 100644 drivers/staging/brcm80211/sys/d11ucode_ext.h delete mode 100644 drivers/staging/brcm80211/sys/wl_dbg.h delete mode 100644 drivers/staging/brcm80211/sys/wl_export.h delete mode 100644 drivers/staging/brcm80211/sys/wl_mac80211.c delete mode 100644 drivers/staging/brcm80211/sys/wl_mac80211.h delete mode 100644 drivers/staging/brcm80211/sys/wl_ucode.h delete mode 100644 drivers/staging/brcm80211/sys/wl_ucode_loader.c delete mode 100644 drivers/staging/brcm80211/sys/wlc_alloc.c delete mode 100644 drivers/staging/brcm80211/sys/wlc_alloc.h delete mode 100644 drivers/staging/brcm80211/sys/wlc_ampdu.c delete mode 100644 drivers/staging/brcm80211/sys/wlc_ampdu.h delete mode 100644 drivers/staging/brcm80211/sys/wlc_antsel.c delete mode 100644 drivers/staging/brcm80211/sys/wlc_antsel.h delete mode 100644 drivers/staging/brcm80211/sys/wlc_bmac.c delete mode 100644 drivers/staging/brcm80211/sys/wlc_bmac.h delete mode 100644 drivers/staging/brcm80211/sys/wlc_bsscfg.h delete mode 100644 drivers/staging/brcm80211/sys/wlc_cfg.h delete mode 100644 drivers/staging/brcm80211/sys/wlc_channel.c delete mode 100644 drivers/staging/brcm80211/sys/wlc_channel.h delete mode 100644 drivers/staging/brcm80211/sys/wlc_event.c delete mode 100644 drivers/staging/brcm80211/sys/wlc_event.h delete mode 100644 drivers/staging/brcm80211/sys/wlc_key.h delete mode 100644 drivers/staging/brcm80211/sys/wlc_mac80211.c delete mode 100644 drivers/staging/brcm80211/sys/wlc_mac80211.h delete mode 100644 drivers/staging/brcm80211/sys/wlc_phy_shim.c delete mode 100644 drivers/staging/brcm80211/sys/wlc_phy_shim.h delete mode 100644 drivers/staging/brcm80211/sys/wlc_pub.h delete mode 100644 drivers/staging/brcm80211/sys/wlc_rate.c delete mode 100644 drivers/staging/brcm80211/sys/wlc_rate.h delete mode 100644 drivers/staging/brcm80211/sys/wlc_scb.h delete mode 100644 drivers/staging/brcm80211/sys/wlc_stf.c delete mode 100644 drivers/staging/brcm80211/sys/wlc_stf.h delete mode 100644 drivers/staging/brcm80211/sys/wlc_types.h (limited to 'drivers') diff --git a/drivers/staging/brcm80211/Kconfig b/drivers/staging/brcm80211/Kconfig index 57d2d1b782f1..3208352465af 100644 --- a/drivers/staging/brcm80211/Kconfig +++ b/drivers/staging/brcm80211/Kconfig @@ -8,7 +8,7 @@ choice help Select the appropriate driver style from the list below. -config BRCM80211_PCI +config BRCMSMAC bool "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver" depends on PCI depends on BRCM80211 && MAC80211 @@ -16,7 +16,7 @@ config BRCM80211_PCI ---help--- This module adds support for PCIe wireless adapters based on Broadcom IEEE802.11n SoftMAC chipsets. If you choose to build a module, it'll - be called brcm80211.ko. + be called brcmsmac.ko. config BRCMFMAC bool "Broadcom IEEE802.11n embedded FullMAC WLAN driver" diff --git a/drivers/staging/brcm80211/Makefile b/drivers/staging/brcm80211/Makefile index 1953ebe3d64b..a0695195614f 100644 --- a/drivers/staging/brcm80211/Makefile +++ b/drivers/staging/brcm80211/Makefile @@ -15,62 +15,5 @@ # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -ccflags-y := \ - -DBCMDBG \ - -DWLC_HIGH \ - -DSTA \ - -DWME \ - -DWL11N \ - -DDBAND \ - -DBCMDMA32 \ - -DBCMNVRAMR \ - -Idrivers/staging/brcm80211/sys \ - -Idrivers/staging/brcm80211/phy \ - -Idrivers/staging/brcm80211/util \ - -Idrivers/staging/brcm80211/include - -PCI_CFLAGS := -DWLC_LOW - -BRCM80211_OFILES := \ - util/siutils.o \ - util/aiutils.o \ - util/bcmotp.o \ - util/bcmsrom.o \ - util/bcmutils.o \ - util/bcmwifi.o \ - util/hndpmu.o \ - util/linux_osl.o \ - sys/wlc_alloc.o \ - sys/wlc_antsel.o \ - sys/wlc_channel.o \ - sys/wlc_event.o \ - sys/wlc_mac80211.o \ - sys/wlc_rate.o \ - sys/wlc_stf.o \ - sys/wl_mac80211.o \ - sys/wlc_ampdu.o - -PCIFILES := \ - phy/wlc_phy_cmn.o \ - phy/wlc_phy_lcn.o \ - phy/wlc_phy_n.o \ - phy/wlc_phytbl_lcn.o \ - phy/wlc_phytbl_n.o \ - sys/wlc_bmac.o \ - sys/wlc_phy_shim.o \ - sys/wl_ucode_loader.o \ - util/hnddma.o \ - util/nicpci.o \ - util/nvram/nvram_ro.o \ - util/qmath.o - -MODULEPFX := brcm80211 - -# PCI driver -ifeq ($(CONFIG_BRCM80211_PCI),y) -obj-m += $(MODULEPFX).o -ccflags-y += $(PCI_CFLAGS) -$(MODULEPFX)-objs = $(BRCM80211_OFILES) $(PCIFILES) -endif - -obj-$(CONFIG_BRCMFMAC) += brcmfmac/ +obj-$(CONFIG_BRCMFMAC) += brcmfmac/ +obj-$(CONFIG_BRCMSMAC) += brcmsmac/ diff --git a/drivers/staging/brcm80211/brcmfmac/Kconfig b/drivers/staging/brcm80211/brcmfmac/Kconfig deleted file mode 100644 index e9f3037b0876..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -menuconfig BRCMFMAC - tristate "Broadcom fullmac wireless cards support" - depends on MMC - depends on CFG80211 - select FW_LOADER - select WIRELESS_EXT - select WEXT_PRIV - ---help--- - This module adds support for wireless adapters based on - Broadcom fullmac chipsets. - This driver uses the kernel's wireless extensions subsystem. - If you choose to build a module, it'll be called brcmfmac.ko. Say M if - unsure. - - diff --git a/drivers/staging/brcm80211/brcmfmac/Makefile b/drivers/staging/brcm80211/brcmfmac/Makefile index 76f2d8b37e45..13df7c3c79d3 100644 --- a/drivers/staging/brcm80211/brcmfmac/Makefile +++ b/drivers/staging/brcm80211/brcmfmac/Makefile @@ -37,10 +37,26 @@ ccflags-y := \ -Idrivers/staging/brcm80211/include \ -Idrivers/staging/brcm80211/util -DHDOFILES = dhd_linux.o ../util/linux_osl.o ../util/bcmutils.o dhd_common.o dhd_custom_gpio.o \ - wl_iw.o wl_cfg80211.o ../util/siutils.o ../util/sbutils.o ../util/aiutils.o ../util/hndpmu.o ../util/bcmwifi.o dhd_sdio.o \ - dhd_linux_sched.o dhd_cdc.o bcmsdh_sdmmc.o bcmsdh.o bcmsdh_linux.o \ - bcmsdh_sdmmc_linux.o +DHDOFILES = \ + wl_cfg80211.o \ + wl_iw.o \ + dhd_cdc.o \ + dhd_common.o \ + dhd_custom_gpio.o \ + dhd_sdio.o \ + dhd_linux.o \ + dhd_linux_sched.o \ + bcmsdh.o \ + bcmsdh_linux.o \ + bcmsdh_sdmmc.o \ + bcmsdh_sdmmc_linux.o \ + ../util/linux_osl.o \ + ../util/aiutils.o \ + ../util/siutils.o \ + ../util/sbutils.o \ + ../util/bcmutils.o \ + ../util/bcmwifi.o \ + ../util/hndpmu.o obj-m += brcmfmac.o brcmfmac-objs += $(DHDOFILES) diff --git a/drivers/staging/brcm80211/brcmsmac/Makefile b/drivers/staging/brcm80211/brcmsmac/Makefile new file mode 100644 index 000000000000..910196a37353 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/Makefile @@ -0,0 +1,67 @@ +# +# Makefile fragment for Broadcom 802.11n Networking Device Driver +# +# Copyright (c) 2010 Broadcom Corporation +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +ccflags-y := \ + -DBCMDBG \ + -DWLC_HIGH \ + -DWLC_LOW \ + -DSTA \ + -DWME \ + -DWL11N \ + -DDBAND \ + -DBCMDMA32 \ + -DBCMNVRAMR \ + -Idrivers/staging/brcm80211/brcmsmac/sys \ + -Idrivers/staging/brcm80211/brcmsmac/phy \ + -Idrivers/staging/brcm80211/util \ + -Idrivers/staging/brcm80211/include + +BRCMSMAC_OFILES := \ + sys/wl_mac80211.o \ + sys/wl_ucode_loader.o \ + sys/wlc_alloc.o \ + sys/wlc_ampdu.o \ + sys/wlc_antsel.o \ + sys/wlc_bmac.o \ + sys/wlc_channel.o \ + sys/wlc_event.o \ + sys/wlc_mac80211.o \ + sys/wlc_phy_shim.o \ + sys/wlc_rate.o \ + sys/wlc_stf.o \ + phy/wlc_phy_cmn.o \ + phy/wlc_phy_lcn.o \ + phy/wlc_phy_n.o \ + phy/wlc_phytbl_lcn.o \ + phy/wlc_phytbl_n.o \ + ../util/linux_osl.o \ + ../util/aiutils.o \ + ../util/siutils.o \ + ../util/bcmutils.o \ + ../util/bcmwifi.o \ + ../util/bcmotp.o \ + ../util/bcmsrom.o \ + ../util/hnddma.o \ + ../util/hndpmu.o \ + ../util/nicpci.o \ + ../util/qmath.o \ + ../util/nvram/nvram_ro.o + +MODULEPFX := brcmsmac + +obj-m += $(MODULEPFX).o +$(MODULEPFX)-objs = $(BRCMSMAC_OFILES) diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_version.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_version.h new file mode 100644 index 000000000000..51a223880bcf --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_version.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef phy_version_h_ +#define phy_version_h_ + +#define PHY_MAJOR_VERSION 1 + +#define PHY_MINOR_VERSION 82 + +#define PHY_RC_NUMBER 8 + +#define PHY_INCREMENTAL_NUMBER 0 + +#define PHY_BUILD_NUMBER 0 + +#define PHY_VERSION { 1, 82, 8, 0 } + +#define PHY_VERSION_NUM 0x01520800 + +#define PHY_VERSION_STR "1.82.8.0" + +#endif /* phy_version_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c new file mode 100644 index 000000000000..3bed37cb59b8 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c @@ -0,0 +1,3461 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +u32 phyhal_msg_level = PHYHAL_ERROR; + +typedef struct _chan_info_basic { + u16 chan; + u16 freq; +} chan_info_basic_t; + +static chan_info_basic_t chan_info_all[] = { + + {1, 2412}, + {2, 2417}, + {3, 2422}, + {4, 2427}, + {5, 2432}, + {6, 2437}, + {7, 2442}, + {8, 2447}, + {9, 2452}, + {10, 2457}, + {11, 2462}, + {12, 2467}, + {13, 2472}, + {14, 2484}, + + {34, 5170}, + {38, 5190}, + {42, 5210}, + {46, 5230}, + + {36, 5180}, + {40, 5200}, + {44, 5220}, + {48, 5240}, + {52, 5260}, + {56, 5280}, + {60, 5300}, + {64, 5320}, + + {100, 5500}, + {104, 5520}, + {108, 5540}, + {112, 5560}, + {116, 5580}, + {120, 5600}, + {124, 5620}, + {128, 5640}, + {132, 5660}, + {136, 5680}, + {140, 5700}, + + {149, 5745}, + {153, 5765}, + {157, 5785}, + {161, 5805}, + {165, 5825}, + + {184, 4920}, + {188, 4940}, + {192, 4960}, + {196, 4980}, + {200, 5000}, + {204, 5020}, + {208, 5040}, + {212, 5060}, + {216, 50800} +}; + +u16 ltrn_list[PHY_LTRN_LIST_LEN] = { + 0x18f9, 0x0d01, 0x00e4, 0xdef4, 0x06f1, 0x0ffc, + 0xfa27, 0x1dff, 0x10f0, 0x0918, 0xf20a, 0xe010, + 0x1417, 0x1104, 0xf114, 0xf2fa, 0xf7db, 0xe2fc, + 0xe1fb, 0x13ee, 0xff0d, 0xe91c, 0x171a, 0x0318, + 0xda00, 0x03e8, 0x17e6, 0xe9e4, 0xfff3, 0x1312, + 0xe105, 0xe204, 0xf725, 0xf206, 0xf1ec, 0x11fc, + 0x14e9, 0xe0f0, 0xf2f6, 0x09e8, 0x1010, 0x1d01, + 0xfad9, 0x0f04, 0x060f, 0xde0c, 0x001c, 0x0dff, + 0x1807, 0xf61a, 0xe40e, 0x0f16, 0x05f9, 0x18ec, + 0x0a1b, 0xff1e, 0x2600, 0xffe2, 0x0ae5, 0x1814, + 0x0507, 0x0fea, 0xe4f2, 0xf6e6 +}; + +const u8 ofdm_rate_lookup[] = { + + WLC_RATE_48M, + WLC_RATE_24M, + WLC_RATE_12M, + WLC_RATE_6M, + WLC_RATE_54M, + WLC_RATE_36M, + WLC_RATE_18M, + WLC_RATE_9M +}; + +#define PHY_WREG_LIMIT 24 + +static void wlc_set_phy_uninitted(phy_info_t *pi); +static u32 wlc_phy_get_radio_ver(phy_info_t *pi); +static void wlc_phy_timercb_phycal(void *arg); + +static bool wlc_phy_noise_calc_phy(phy_info_t *pi, u32 *cmplx_pwr, + s8 *pwr_ant); + +static void wlc_phy_cal_perical_mphase_schedule(phy_info_t *pi, uint delay); +static void wlc_phy_noise_cb(phy_info_t *pi, u8 channel, s8 noise_dbm); +static void wlc_phy_noise_sample_request(wlc_phy_t *pih, u8 reason, + u8 ch); + +static void wlc_phy_txpower_reg_limit_calc(phy_info_t *pi, + struct txpwr_limits *tp, chanspec_t); +static bool wlc_phy_cal_txpower_recalc_sw(phy_info_t *pi); + +static s8 wlc_user_txpwr_antport_to_rfport(phy_info_t *pi, uint chan, + u32 band, u8 rate); +static void wlc_phy_upd_env_txpwr_rate_limits(phy_info_t *pi, u32 band); +static s8 wlc_phy_env_measure_vbat(phy_info_t *pi); +static s8 wlc_phy_env_measure_temperature(phy_info_t *pi); + +char *phy_getvar(phy_info_t *pi, const char *name) +{ + char *vars = pi->vars; + char *s; + int len; + + ASSERT(pi->vars != (char *)&pi->vars); + + if (!name) + return NULL; + + len = strlen(name); + if (len == 0) + return NULL; + + for (s = vars; s && *s;) { + if ((memcmp(s, name, len) == 0) && (s[len] == '=')) + return &s[len + 1]; + + while (*s++) + ; + } + + return nvram_get(name); +} + +int phy_getintvar(phy_info_t *pi, const char *name) +{ + char *val; + + val = PHY_GETVAR(pi, name); + if (val == NULL) + return 0; + + return simple_strtoul(val, NULL, 0); +} + +void wlc_phyreg_enter(wlc_phy_t *pih) +{ + phy_info_t *pi = (phy_info_t *) pih; + wlapi_bmac_ucode_wake_override_phyreg_set(pi->sh->physhim); +} + +void wlc_phyreg_exit(wlc_phy_t *pih) +{ + phy_info_t *pi = (phy_info_t *) pih; + wlapi_bmac_ucode_wake_override_phyreg_clear(pi->sh->physhim); +} + +void wlc_radioreg_enter(wlc_phy_t *pih) +{ + phy_info_t *pi = (phy_info_t *) pih; + wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, MCTL_LOCK_RADIO); + + udelay(10); +} + +void wlc_radioreg_exit(wlc_phy_t *pih) +{ + phy_info_t *pi = (phy_info_t *) pih; + volatile u16 dummy; + + dummy = R_REG(pi->sh->osh, &pi->regs->phyversion); + pi->phy_wreg = 0; + wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, 0); +} + +u16 read_radio_reg(phy_info_t *pi, u16 addr) +{ + u16 data; + + if ((addr == RADIO_IDCODE)) + return 0xffff; + + if (NORADIO_ENAB(pi->pubpi)) + return NORADIO_IDCODE & 0xffff; + + switch (pi->pubpi.phy_type) { + case PHY_TYPE_N: + CASECHECK(PHYTYPE, PHY_TYPE_N); + if (NREV_GE(pi->pubpi.phy_rev, 7)) + addr |= RADIO_2057_READ_OFF; + else + addr |= RADIO_2055_READ_OFF; + break; + + case PHY_TYPE_LCN: + CASECHECK(PHYTYPE, PHY_TYPE_LCN); + addr |= RADIO_2064_READ_OFF; + break; + + default: + ASSERT(VALID_PHYTYPE(pi->pubpi.phy_type)); + } + + if ((D11REV_GE(pi->sh->corerev, 24)) || + (D11REV_IS(pi->sh->corerev, 22) + && (pi->pubpi.phy_type != PHY_TYPE_SSN))) { + W_REG(pi->sh->osh, &pi->regs->radioregaddr, addr); +#ifdef __mips__ + (void)R_REG(pi->sh->osh, &pi->regs->radioregaddr); +#endif + data = R_REG(pi->sh->osh, &pi->regs->radioregdata); + } else { + W_REG(pi->sh->osh, &pi->regs->phy4waddr, addr); +#ifdef __mips__ + (void)R_REG(pi->sh->osh, &pi->regs->phy4waddr); +#endif + +#ifdef __ARM_ARCH_4T__ + __asm__(" .align 4 "); + __asm__(" nop "); + data = R_REG(pi->sh->osh, &pi->regs->phy4wdatalo); +#else + data = R_REG(pi->sh->osh, &pi->regs->phy4wdatalo); +#endif + + } + pi->phy_wreg = 0; + + return data; +} + +void write_radio_reg(phy_info_t *pi, u16 addr, u16 val) +{ + struct osl_info *osh; + + if (NORADIO_ENAB(pi->pubpi)) + return; + + osh = pi->sh->osh; + + if ((D11REV_GE(pi->sh->corerev, 24)) || + (D11REV_IS(pi->sh->corerev, 22) + && (pi->pubpi.phy_type != PHY_TYPE_SSN))) { + + W_REG(osh, &pi->regs->radioregaddr, addr); +#ifdef __mips__ + (void)R_REG(osh, &pi->regs->radioregaddr); +#endif + W_REG(osh, &pi->regs->radioregdata, val); + } else { + W_REG(osh, &pi->regs->phy4waddr, addr); +#ifdef __mips__ + (void)R_REG(osh, &pi->regs->phy4waddr); +#endif + W_REG(osh, &pi->regs->phy4wdatalo, val); + } + + if (pi->sh->bustype == PCI_BUS) { + if (++pi->phy_wreg >= pi->phy_wreg_limit) { + (void)R_REG(osh, &pi->regs->maccontrol); + pi->phy_wreg = 0; + } + } +} + +static u32 read_radio_id(phy_info_t *pi) +{ + u32 id; + + if (NORADIO_ENAB(pi->pubpi)) + return NORADIO_IDCODE; + + if (D11REV_GE(pi->sh->corerev, 24)) { + u32 b0, b1, b2; + + W_REG(pi->sh->osh, &pi->regs->radioregaddr, 0); +#ifdef __mips__ + (void)R_REG(pi->sh->osh, &pi->regs->radioregaddr); +#endif + b0 = (u32) R_REG(pi->sh->osh, &pi->regs->radioregdata); + W_REG(pi->sh->osh, &pi->regs->radioregaddr, 1); +#ifdef __mips__ + (void)R_REG(pi->sh->osh, &pi->regs->radioregaddr); +#endif + b1 = (u32) R_REG(pi->sh->osh, &pi->regs->radioregdata); + W_REG(pi->sh->osh, &pi->regs->radioregaddr, 2); +#ifdef __mips__ + (void)R_REG(pi->sh->osh, &pi->regs->radioregaddr); +#endif + b2 = (u32) R_REG(pi->sh->osh, &pi->regs->radioregdata); + + id = ((b0 & 0xf) << 28) | (((b2 << 8) | b1) << 12) | ((b0 >> 4) + & 0xf); + } else { + W_REG(pi->sh->osh, &pi->regs->phy4waddr, RADIO_IDCODE); +#ifdef __mips__ + (void)R_REG(pi->sh->osh, &pi->regs->phy4waddr); +#endif + id = (u32) R_REG(pi->sh->osh, &pi->regs->phy4wdatalo); + id |= (u32) R_REG(pi->sh->osh, &pi->regs->phy4wdatahi) << 16; + } + pi->phy_wreg = 0; + return id; +} + +void and_radio_reg(phy_info_t *pi, u16 addr, u16 val) +{ + u16 rval; + + if (NORADIO_ENAB(pi->pubpi)) + return; + + rval = read_radio_reg(pi, addr); + write_radio_reg(pi, addr, (rval & val)); +} + +void or_radio_reg(phy_info_t *pi, u16 addr, u16 val) +{ + u16 rval; + + if (NORADIO_ENAB(pi->pubpi)) + return; + + rval = read_radio_reg(pi, addr); + write_radio_reg(pi, addr, (rval | val)); +} + +void xor_radio_reg(phy_info_t *pi, u16 addr, u16 mask) +{ + u16 rval; + + if (NORADIO_ENAB(pi->pubpi)) + return; + + rval = read_radio_reg(pi, addr); + write_radio_reg(pi, addr, (rval ^ mask)); +} + +void mod_radio_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val) +{ + u16 rval; + + if (NORADIO_ENAB(pi->pubpi)) + return; + + rval = read_radio_reg(pi, addr); + write_radio_reg(pi, addr, (rval & ~mask) | (val & mask)); +} + +void write_phy_channel_reg(phy_info_t *pi, uint val) +{ + W_REG(pi->sh->osh, &pi->regs->phychannel, val); +} + +#if defined(BCMDBG) +static bool wlc_phy_war41476(phy_info_t *pi) +{ + u32 mc = R_REG(pi->sh->osh, &pi->regs->maccontrol); + + return ((mc & MCTL_EN_MAC) == 0) + || ((mc & MCTL_PHYLOCK) == MCTL_PHYLOCK); +} +#endif + +u16 read_phy_reg(phy_info_t *pi, u16 addr) +{ + struct osl_info *osh; + d11regs_t *regs; + + osh = pi->sh->osh; + regs = pi->regs; + + W_REG(osh, ®s->phyregaddr, addr); +#ifdef __mips__ + (void)R_REG(osh, ®s->phyregaddr); +#endif + + ASSERT(! + (D11REV_IS(pi->sh->corerev, 11) + || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi)); + + pi->phy_wreg = 0; + return R_REG(osh, ®s->phyregdata); +} + +void write_phy_reg(phy_info_t *pi, u16 addr, u16 val) +{ + struct osl_info *osh; + d11regs_t *regs; + + osh = pi->sh->osh; + regs = pi->regs; + +#ifdef __mips__ + W_REG(osh, ®s->phyregaddr, addr); + (void)R_REG(osh, ®s->phyregaddr); + W_REG(osh, ®s->phyregdata, val); + if (addr == 0x72) + (void)R_REG(osh, ®s->phyregdata); +#else + W_REG(osh, (volatile u32 *)(®s->phyregaddr), + addr | (val << 16)); + if (pi->sh->bustype == PCI_BUS) { + if (++pi->phy_wreg >= pi->phy_wreg_limit) { + pi->phy_wreg = 0; + (void)R_REG(osh, ®s->phyversion); + } + } +#endif +} + +void and_phy_reg(phy_info_t *pi, u16 addr, u16 val) +{ + struct osl_info *osh; + d11regs_t *regs; + + osh = pi->sh->osh; + regs = pi->regs; + + W_REG(osh, ®s->phyregaddr, addr); +#ifdef __mips__ + (void)R_REG(osh, ®s->phyregaddr); +#endif + + ASSERT(! + (D11REV_IS(pi->sh->corerev, 11) + || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi)); + + W_REG(osh, ®s->phyregdata, (R_REG(osh, ®s->phyregdata) & val)); + pi->phy_wreg = 0; +} + +void or_phy_reg(phy_info_t *pi, u16 addr, u16 val) +{ + struct osl_info *osh; + d11regs_t *regs; + + osh = pi->sh->osh; + regs = pi->regs; + + W_REG(osh, ®s->phyregaddr, addr); +#ifdef __mips__ + (void)R_REG(osh, ®s->phyregaddr); +#endif + + ASSERT(! + (D11REV_IS(pi->sh->corerev, 11) + || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi)); + + W_REG(osh, ®s->phyregdata, (R_REG(osh, ®s->phyregdata) | val)); + pi->phy_wreg = 0; +} + +void mod_phy_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val) +{ + struct osl_info *osh; + d11regs_t *regs; + + osh = pi->sh->osh; + regs = pi->regs; + + W_REG(osh, ®s->phyregaddr, addr); +#ifdef __mips__ + (void)R_REG(osh, ®s->phyregaddr); +#endif + + ASSERT(! + (D11REV_IS(pi->sh->corerev, 11) + || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi)); + + W_REG(osh, ®s->phyregdata, + ((R_REG(osh, ®s->phyregdata) & ~mask) | (val & mask))); + pi->phy_wreg = 0; +} + +static void WLBANDINITFN(wlc_set_phy_uninitted) (phy_info_t *pi) +{ + int i, j; + + pi->initialized = false; + + pi->tx_vos = 0xffff; + pi->nrssi_table_delta = 0x7fffffff; + pi->rc_cal = 0xffff; + pi->mintxbias = 0xffff; + pi->txpwridx = -1; + if (ISNPHY(pi)) { + pi->phy_spuravoid = SPURAVOID_DISABLE; + + if (NREV_GE(pi->pubpi.phy_rev, 3) + && NREV_LT(pi->pubpi.phy_rev, 7)) + pi->phy_spuravoid = SPURAVOID_AUTO; + + pi->nphy_papd_skip = 0; + pi->nphy_papd_epsilon_offset[0] = 0xf588; + pi->nphy_papd_epsilon_offset[1] = 0xf588; + pi->nphy_txpwr_idx[0] = 128; + pi->nphy_txpwr_idx[1] = 128; + pi->nphy_txpwrindex[0].index_internal = 40; + pi->nphy_txpwrindex[1].index_internal = 40; + pi->phy_pabias = 0; + } else { + pi->phy_spuravoid = SPURAVOID_AUTO; + } + pi->radiopwr = 0xffff; + for (i = 0; i < STATIC_NUM_RF; i++) { + for (j = 0; j < STATIC_NUM_BB; j++) { + pi->stats_11b_txpower[i][j] = -1; + } + } +} + +shared_phy_t *wlc_phy_shared_attach(shared_phy_params_t *shp) +{ + shared_phy_t *sh; + + sh = kzalloc(sizeof(shared_phy_t), GFP_ATOMIC); + if (sh == NULL) { + return NULL; + } + + sh->osh = shp->osh; + sh->sih = shp->sih; + sh->physhim = shp->physhim; + sh->unit = shp->unit; + sh->corerev = shp->corerev; + + sh->vid = shp->vid; + sh->did = shp->did; + sh->chip = shp->chip; + sh->chiprev = shp->chiprev; + sh->chippkg = shp->chippkg; + sh->sromrev = shp->sromrev; + sh->boardtype = shp->boardtype; + sh->boardrev = shp->boardrev; + sh->boardvendor = shp->boardvendor; + sh->boardflags = shp->boardflags; + sh->boardflags2 = shp->boardflags2; + sh->bustype = shp->bustype; + sh->buscorerev = shp->buscorerev; + + sh->fast_timer = PHY_SW_TIMER_FAST; + sh->slow_timer = PHY_SW_TIMER_SLOW; + sh->glacial_timer = PHY_SW_TIMER_GLACIAL; + + sh->rssi_mode = RSSI_ANT_MERGE_MAX; + + return sh; +} + +void wlc_phy_shared_detach(shared_phy_t *phy_sh) +{ + struct osl_info *osh; + + if (phy_sh) { + osh = phy_sh->osh; + + if (phy_sh->phy_head) { + ASSERT(!phy_sh->phy_head); + } + kfree(phy_sh); + } +} + +wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, char *vars) +{ + phy_info_t *pi; + u32 sflags = 0; + uint phyversion; + int i; + struct osl_info *osh; + + osh = sh->osh; + + if (D11REV_IS(sh->corerev, 4)) + sflags = SISF_2G_PHY | SISF_5G_PHY; + else + sflags = si_core_sflags(sh->sih, 0, 0); + + if (BAND_5G(bandtype)) { + if ((sflags & (SISF_5G_PHY | SISF_DB_PHY)) == 0) { + return NULL; + } + } + + pi = sh->phy_head; + if ((sflags & SISF_DB_PHY) && pi) { + + wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags); + pi->refcnt++; + return &pi->pubpi_ro; + } + + pi = kzalloc(sizeof(phy_info_t), GFP_ATOMIC); + if (pi == NULL) { + return NULL; + } + pi->regs = (d11regs_t *) regs; + pi->sh = sh; + pi->phy_init_por = true; + pi->phy_wreg_limit = PHY_WREG_LIMIT; + + pi->vars = vars; + + pi->txpwr_percent = 100; + + pi->do_initcal = true; + + pi->phycal_tempdelta = 0; + + if (BAND_2G(bandtype) && (sflags & SISF_2G_PHY)) { + + pi->pubpi.coreflags = SICF_GMODE; + } + + wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags); + phyversion = R_REG(osh, &pi->regs->phyversion); + + pi->pubpi.phy_type = PHY_TYPE(phyversion); + pi->pubpi.phy_rev = phyversion & PV_PV_MASK; + + if (pi->pubpi.phy_type == PHY_TYPE_LCNXN) { + pi->pubpi.phy_type = PHY_TYPE_N; + pi->pubpi.phy_rev += LCNXN_BASEREV; + } + pi->pubpi.phy_corenum = PHY_CORE_NUM_2; + pi->pubpi.ana_rev = (phyversion & PV_AV_MASK) >> PV_AV_SHIFT; + + if (!VALID_PHYTYPE(pi->pubpi.phy_type)) { + goto err; + } + if (BAND_5G(bandtype)) { + if (!ISNPHY(pi)) { + goto err; + } + } else { + if (!ISNPHY(pi) && !ISLCNPHY(pi)) { + goto err; + } + } + + if (ISSIM_ENAB(pi->sh->sih)) { + pi->pubpi.radioid = NORADIO_ID; + pi->pubpi.radiorev = 5; + } else { + u32 idcode; + + wlc_phy_anacore((wlc_phy_t *) pi, ON); + + idcode = wlc_phy_get_radio_ver(pi); + pi->pubpi.radioid = + (idcode & IDCODE_ID_MASK) >> IDCODE_ID_SHIFT; + pi->pubpi.radiorev = + (idcode & IDCODE_REV_MASK) >> IDCODE_REV_SHIFT; + pi->pubpi.radiover = + (idcode & IDCODE_VER_MASK) >> IDCODE_VER_SHIFT; + if (!VALID_RADIO(pi, pi->pubpi.radioid)) { + goto err; + } + + wlc_phy_switch_radio((wlc_phy_t *) pi, OFF); + } + + wlc_set_phy_uninitted(pi); + + pi->bw = WL_CHANSPEC_BW_20; + pi->radio_chanspec = + BAND_2G(bandtype) ? CH20MHZ_CHSPEC(1) : CH20MHZ_CHSPEC(36); + + pi->rxiq_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY; + pi->rxiq_antsel = ANT_RX_DIV_DEF; + + pi->watchdog_override = true; + + pi->cal_type_override = PHY_PERICAL_AUTO; + + pi->nphy_saved_noisevars.bufcount = 0; + + if (ISNPHY(pi)) + pi->min_txpower = PHY_TXPWR_MIN_NPHY; + else + pi->min_txpower = PHY_TXPWR_MIN; + + pi->sh->phyrxchain = 0x3; + + pi->rx2tx_biasentry = -1; + + pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP; + pi->phy_txcore_enable_temp = + PHY_CHAIN_TX_DISABLE_TEMP - PHY_HYSTERESIS_DELTATEMP; + pi->phy_tempsense_offset = 0; + pi->phy_txcore_heatedup = false; + + pi->nphy_lastcal_temp = -50; + + pi->phynoise_polling = true; + if (ISNPHY(pi) || ISLCNPHY(pi)) + pi->phynoise_polling = false; + + for (i = 0; i < TXP_NUM_RATES; i++) { + pi->txpwr_limit[i] = WLC_TXPWR_MAX; + pi->txpwr_env_limit[i] = WLC_TXPWR_MAX; + pi->tx_user_target[i] = WLC_TXPWR_MAX; + } + + pi->radiopwr_override = RADIOPWR_OVERRIDE_DEF; + + pi->user_txpwr_at_rfport = false; + + if (ISNPHY(pi)) { + + pi->phycal_timer = wlapi_init_timer(pi->sh->physhim, + wlc_phy_timercb_phycal, + pi, "phycal"); + if (!pi->phycal_timer) { + goto err; + } + + if (!wlc_phy_attach_nphy(pi)) + goto err; + + } else if (ISLCNPHY(pi)) { + if (!wlc_phy_attach_lcnphy(pi)) + goto err; + + } else { + + } + + pi->refcnt++; + pi->next = pi->sh->phy_head; + sh->phy_head = pi; + + pi->vars = (char *)&pi->vars; + + bcopy(&pi->pubpi, &pi->pubpi_ro, sizeof(wlc_phy_t)); + + return &pi->pubpi_ro; + + err: + if (pi) + kfree(pi); + return NULL; +} + +void wlc_phy_detach(wlc_phy_t *pih) +{ + phy_info_t *pi = (phy_info_t *) pih; + + if (pih) { + if (--pi->refcnt) { + return; + } + + if (pi->phycal_timer) { + wlapi_free_timer(pi->sh->physhim, pi->phycal_timer); + pi->phycal_timer = NULL; + } + + if (pi->sh->phy_head == pi) + pi->sh->phy_head = pi->next; + else if (pi->sh->phy_head->next == pi) + pi->sh->phy_head->next = NULL; + else + ASSERT(0); + + if (pi->pi_fptr.detach) + (pi->pi_fptr.detach) (pi); + + kfree(pi); + } +} + +bool +wlc_phy_get_phyversion(wlc_phy_t *pih, u16 *phytype, u16 *phyrev, + u16 *radioid, u16 *radiover) +{ + phy_info_t *pi = (phy_info_t *) pih; + *phytype = (u16) pi->pubpi.phy_type; + *phyrev = (u16) pi->pubpi.phy_rev; + *radioid = pi->pubpi.radioid; + *radiover = pi->pubpi.radiorev; + + return true; +} + +bool wlc_phy_get_encore(wlc_phy_t *pih) +{ + phy_info_t *pi = (phy_info_t *) pih; + return pi->pubpi.abgphy_encore; +} + +u32 wlc_phy_get_coreflags(wlc_phy_t *pih) +{ + phy_info_t *pi = (phy_info_t *) pih; + return pi->pubpi.coreflags; +} + +static void wlc_phy_timercb_phycal(void *arg) +{ + phy_info_t *pi = (phy_info_t *) arg; + uint delay = 5; + + if (PHY_PERICAL_MPHASE_PENDING(pi)) { + if (!pi->sh->up) { + wlc_phy_cal_perical_mphase_reset(pi); + return; + } + + if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)) { + + delay = 1000; + wlc_phy_cal_perical_mphase_restart(pi); + } else + wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_AUTO); + wlapi_add_timer(pi->sh->physhim, pi->phycal_timer, delay, 0); + return; + } + +} + +void wlc_phy_anacore(wlc_phy_t *pih, bool on) +{ + phy_info_t *pi = (phy_info_t *) pih; + + if (ISNPHY(pi)) { + if (on) { + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + write_phy_reg(pi, 0xa6, 0x0d); + write_phy_reg(pi, 0x8f, 0x0); + write_phy_reg(pi, 0xa7, 0x0d); + write_phy_reg(pi, 0xa5, 0x0); + } else { + write_phy_reg(pi, 0xa5, 0x0); + } + } else { + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + write_phy_reg(pi, 0x8f, 0x07ff); + write_phy_reg(pi, 0xa6, 0x0fd); + write_phy_reg(pi, 0xa5, 0x07ff); + write_phy_reg(pi, 0xa7, 0x0fd); + } else { + write_phy_reg(pi, 0xa5, 0x7fff); + } + } + } else if (ISLCNPHY(pi)) { + if (on) { + and_phy_reg(pi, 0x43b, + ~((0x1 << 0) | (0x1 << 1) | (0x1 << 2))); + } else { + or_phy_reg(pi, 0x43c, + (0x1 << 0) | (0x1 << 1) | (0x1 << 2)); + or_phy_reg(pi, 0x43b, + (0x1 << 0) | (0x1 << 1) | (0x1 << 2)); + } + } +} + +u32 wlc_phy_clk_bwbits(wlc_phy_t *pih) +{ + phy_info_t *pi = (phy_info_t *) pih; + + u32 phy_bw_clkbits = 0; + + if (pi && (ISNPHY(pi) || ISLCNPHY(pi))) { + switch (pi->bw) { + case WL_CHANSPEC_BW_10: + phy_bw_clkbits = SICF_BW10; + break; + case WL_CHANSPEC_BW_20: + phy_bw_clkbits = SICF_BW20; + break; + case WL_CHANSPEC_BW_40: + phy_bw_clkbits = SICF_BW40; + break; + default: + ASSERT(0); + break; + } + } + + return phy_bw_clkbits; +} + +void WLBANDINITFN(wlc_phy_por_inform) (wlc_phy_t *ppi) +{ + phy_info_t *pi = (phy_info_t *) ppi; + + pi->phy_init_por = true; +} + +void wlc_phy_edcrs_lock(wlc_phy_t *pih, bool lock) +{ + phy_info_t *pi = (phy_info_t *) pih; + + pi->edcrs_threshold_lock = lock; + + write_phy_reg(pi, 0x22c, 0x46b); + write_phy_reg(pi, 0x22d, 0x46b); + write_phy_reg(pi, 0x22e, 0x3c0); + write_phy_reg(pi, 0x22f, 0x3c0); +} + +void wlc_phy_initcal_enable(wlc_phy_t *pih, bool initcal) +{ + phy_info_t *pi = (phy_info_t *) pih; + + pi->do_initcal = initcal; +} + +void wlc_phy_hw_clk_state_upd(wlc_phy_t *pih, bool newstate) +{ + phy_info_t *pi = (phy_info_t *) pih; + + if (!pi || !pi->sh) + return; + + pi->sh->clk = newstate; +} + +void wlc_phy_hw_state_upd(wlc_phy_t *pih, bool newstate) +{ + phy_info_t *pi = (phy_info_t *) pih; + + if (!pi || !pi->sh) + return; + + pi->sh->up = newstate; +} + +void WLBANDINITFN(wlc_phy_init) (wlc_phy_t *pih, chanspec_t chanspec) +{ + u32 mc; + initfn_t phy_init = NULL; + phy_info_t *pi = (phy_info_t *) pih; + + if (pi->init_in_progress) + return; + + pi->init_in_progress = true; + + pi->radio_chanspec = chanspec; + + mc = R_REG(pi->sh->osh, &pi->regs->maccontrol); + if ((mc & MCTL_EN_MAC) != 0) { + ASSERT((const char *) + "wlc_phy_init: Called with the MAC running!" == NULL); + } + + ASSERT(pi != NULL); + + if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN)) { + pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC; + } + + if (D11REV_GE(pi->sh->corerev, 5)) + ASSERT(si_core_sflags(pi->sh->sih, 0, 0) & SISF_FCLKA); + + phy_init = pi->pi_fptr.init; + + if (phy_init == NULL) { + ASSERT(phy_init != NULL); + return; + } + + wlc_phy_anacore(pih, ON); + + if (CHSPEC_BW(pi->radio_chanspec) != pi->bw) + wlapi_bmac_bw_set(pi->sh->physhim, + CHSPEC_BW(pi->radio_chanspec)); + + pi->nphy_gain_boost = true; + + wlc_phy_switch_radio((wlc_phy_t *) pi, ON); + + (*phy_init) (pi); + + pi->phy_init_por = false; + + if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) + wlc_phy_do_dummy_tx(pi, true, OFF); + + if (!(ISNPHY(pi))) + wlc_phy_txpower_update_shm(pi); + + wlc_phy_ant_rxdiv_set((wlc_phy_t *) pi, pi->sh->rx_antdiv); + + pi->init_in_progress = false; +} + +void wlc_phy_cal_init(wlc_phy_t *pih) +{ + phy_info_t *pi = (phy_info_t *) pih; + initfn_t cal_init = NULL; + + ASSERT((R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC) == 0); + + if (!pi->initialized) { + cal_init = pi->pi_fptr.calinit; + if (cal_init) + (*cal_init) (pi); + + pi->initialized = true; + } +} + +int wlc_phy_down(wlc_phy_t *pih) +{ + phy_info_t *pi = (phy_info_t *) pih; + int callbacks = 0; + + ASSERT(pi->phytest_on == false); + + if (pi->phycal_timer + && !wlapi_del_timer(pi->sh->physhim, pi->phycal_timer)) + callbacks++; + + pi->nphy_iqcal_chanspec_2G = 0; + pi->nphy_iqcal_chanspec_5G = 0; + + return callbacks; +} + +static u32 wlc_phy_get_radio_ver(phy_info_t *pi) +{ + u32 ver; + + ver = read_radio_id(pi); + + return ver; +} + +void +wlc_phy_table_addr(phy_info_t *pi, uint tbl_id, uint tbl_offset, + u16 tblAddr, u16 tblDataHi, u16 tblDataLo) +{ + write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset); + + pi->tbl_data_hi = tblDataHi; + pi->tbl_data_lo = tblDataLo; + + if ((pi->sh->chip == BCM43224_CHIP_ID || + pi->sh->chip == BCM43421_CHIP_ID) && + (pi->sh->chiprev == 1)) { + pi->tbl_addr = tblAddr; + pi->tbl_save_id = tbl_id; + pi->tbl_save_offset = tbl_offset; + } +} + +void wlc_phy_table_data_write(phy_info_t *pi, uint width, u32 val) +{ + ASSERT((width == 8) || (width == 16) || (width == 32)); + + if ((pi->sh->chip == BCM43224_CHIP_ID || + pi->sh->chip == BCM43421_CHIP_ID) && + (pi->sh->chiprev == 1) && + (pi->tbl_save_id == NPHY_TBL_ID_ANTSWCTRLLUT)) { + read_phy_reg(pi, pi->tbl_data_lo); + + write_phy_reg(pi, pi->tbl_addr, + (pi->tbl_save_id << 10) | pi->tbl_save_offset); + pi->tbl_save_offset++; + } + + if (width == 32) { + + write_phy_reg(pi, pi->tbl_data_hi, (u16) (val >> 16)); + write_phy_reg(pi, pi->tbl_data_lo, (u16) val); + } else { + + write_phy_reg(pi, pi->tbl_data_lo, (u16) val); + } +} + +void +wlc_phy_write_table(phy_info_t *pi, const phytbl_info_t *ptbl_info, + u16 tblAddr, u16 tblDataHi, u16 tblDataLo) +{ + uint idx; + uint tbl_id = ptbl_info->tbl_id; + uint tbl_offset = ptbl_info->tbl_offset; + uint tbl_width = ptbl_info->tbl_width; + const u8 *ptbl_8b = (const u8 *)ptbl_info->tbl_ptr; + const u16 *ptbl_16b = (const u16 *)ptbl_info->tbl_ptr; + const u32 *ptbl_32b = (const u32 *)ptbl_info->tbl_ptr; + + ASSERT((tbl_width == 8) || (tbl_width == 16) || (tbl_width == 32)); + + write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset); + + for (idx = 0; idx < ptbl_info->tbl_len; idx++) { + + if ((pi->sh->chip == BCM43224_CHIP_ID || + pi->sh->chip == BCM43421_CHIP_ID) && + (pi->sh->chiprev == 1) && + (tbl_id == NPHY_TBL_ID_ANTSWCTRLLUT)) { + read_phy_reg(pi, tblDataLo); + + write_phy_reg(pi, tblAddr, + (tbl_id << 10) | (tbl_offset + idx)); + } + + if (tbl_width == 32) { + + write_phy_reg(pi, tblDataHi, + (u16) (ptbl_32b[idx] >> 16)); + write_phy_reg(pi, tblDataLo, (u16) ptbl_32b[idx]); + } else if (tbl_width == 16) { + + write_phy_reg(pi, tblDataLo, ptbl_16b[idx]); + } else { + + write_phy_reg(pi, tblDataLo, ptbl_8b[idx]); + } + } +} + +void +wlc_phy_read_table(phy_info_t *pi, const phytbl_info_t *ptbl_info, + u16 tblAddr, u16 tblDataHi, u16 tblDataLo) +{ + uint idx; + uint tbl_id = ptbl_info->tbl_id; + uint tbl_offset = ptbl_info->tbl_offset; + uint tbl_width = ptbl_info->tbl_width; + u8 *ptbl_8b = (u8 *)ptbl_info->tbl_ptr; + u16 *ptbl_16b = (u16 *)ptbl_info->tbl_ptr; + u32 *ptbl_32b = (u32 *)ptbl_info->tbl_ptr; + + ASSERT((tbl_width == 8) || (tbl_width == 16) || (tbl_width == 32)); + + write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset); + + for (idx = 0; idx < ptbl_info->tbl_len; idx++) { + + if ((pi->sh->chip == BCM43224_CHIP_ID || + pi->sh->chip == BCM43421_CHIP_ID) && + (pi->sh->chiprev == 1)) { + (void)read_phy_reg(pi, tblDataLo); + + write_phy_reg(pi, tblAddr, + (tbl_id << 10) | (tbl_offset + idx)); + } + + if (tbl_width == 32) { + + ptbl_32b[idx] = read_phy_reg(pi, tblDataLo); + ptbl_32b[idx] |= (read_phy_reg(pi, tblDataHi) << 16); + } else if (tbl_width == 16) { + + ptbl_16b[idx] = read_phy_reg(pi, tblDataLo); + } else { + + ptbl_8b[idx] = (u8) read_phy_reg(pi, tblDataLo); + } + } +} + +uint +wlc_phy_init_radio_regs_allbands(phy_info_t *pi, radio_20xx_regs_t *radioregs) +{ + uint i = 0; + + do { + if (radioregs[i].do_init) { + write_radio_reg(pi, radioregs[i].address, + (u16) radioregs[i].init); + } + + i++; + } while (radioregs[i].address != 0xffff); + + return i; +} + +uint +wlc_phy_init_radio_regs(phy_info_t *pi, radio_regs_t *radioregs, + u16 core_offset) +{ + uint i = 0; + uint count = 0; + + do { + if (CHSPEC_IS5G(pi->radio_chanspec)) { + if (radioregs[i].do_init_a) { + write_radio_reg(pi, + radioregs[i]. + address | core_offset, + (u16) radioregs[i].init_a); + if (ISNPHY(pi) && (++count % 4 == 0)) + WLC_PHY_WAR_PR51571(pi); + } + } else { + if (radioregs[i].do_init_g) { + write_radio_reg(pi, + radioregs[i]. + address | core_offset, + (u16) radioregs[i].init_g); + if (ISNPHY(pi) && (++count % 4 == 0)) + WLC_PHY_WAR_PR51571(pi); + } + } + + i++; + } while (radioregs[i].address != 0xffff); + + return i; +} + +void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on) +{ +#define DUMMY_PKT_LEN 20 + d11regs_t *regs = pi->regs; + int i, count; + u8 ofdmpkt[DUMMY_PKT_LEN] = { + 0xcc, 0x01, 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + u8 cckpkt[DUMMY_PKT_LEN] = { + 0x6e, 0x84, 0x0b, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 + }; + u32 *dummypkt; + + ASSERT((R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC) == 0); + + dummypkt = (u32 *) (ofdm ? ofdmpkt : cckpkt); + wlapi_bmac_write_template_ram(pi->sh->physhim, 0, DUMMY_PKT_LEN, + dummypkt); + + W_REG(pi->sh->osh, ®s->xmtsel, 0); + + if (D11REV_GE(pi->sh->corerev, 11)) + W_REG(pi->sh->osh, ®s->wepctl, 0x100); + else + W_REG(pi->sh->osh, ®s->wepctl, 0); + + W_REG(pi->sh->osh, ®s->txe_phyctl, (ofdm ? 1 : 0) | PHY_TXC_ANT_0); + if (ISNPHY(pi) || ISLCNPHY(pi)) { + ASSERT(ofdm); + W_REG(pi->sh->osh, ®s->txe_phyctl1, 0x1A02); + } + + W_REG(pi->sh->osh, ®s->txe_wm_0, 0); + W_REG(pi->sh->osh, ®s->txe_wm_1, 0); + + W_REG(pi->sh->osh, ®s->xmttplatetxptr, 0); + W_REG(pi->sh->osh, ®s->xmttxcnt, DUMMY_PKT_LEN); + + W_REG(pi->sh->osh, ®s->xmtsel, ((8 << 8) | (1 << 5) | (1 << 2) | 2)); + + W_REG(pi->sh->osh, ®s->txe_ctl, 0); + + if (!pa_on) { + if (ISNPHY(pi)) + wlc_phy_pa_override_nphy(pi, OFF); + } + + if (ISNPHY(pi) || ISLCNPHY(pi)) + W_REG(pi->sh->osh, ®s->txe_aux, 0xD0); + else + W_REG(pi->sh->osh, ®s->txe_aux, ((1 << 5) | (1 << 4))); + + (void)R_REG(pi->sh->osh, ®s->txe_aux); + + i = 0; + count = ofdm ? 30 : 250; + + if (ISSIM_ENAB(pi->sh->sih)) { + count *= 100; + } + + while ((i++ < count) + && (R_REG(pi->sh->osh, ®s->txe_status) & (1 << 7))) { + udelay(10); + } + + i = 0; + + while ((i++ < 10) + && ((R_REG(pi->sh->osh, ®s->txe_status) & (1 << 10)) == 0)) { + udelay(10); + } + + i = 0; + + while ((i++ < 10) && ((R_REG(pi->sh->osh, ®s->ifsstat) & (1 << 8)))) { + udelay(10); + } + if (!pa_on) { + if (ISNPHY(pi)) + wlc_phy_pa_override_nphy(pi, ON); + } +} + +void wlc_phy_hold_upd(wlc_phy_t *pih, mbool id, bool set) +{ + phy_info_t *pi = (phy_info_t *) pih; + ASSERT(id); + + if (set) { + mboolset(pi->measure_hold, id); + } else { + mboolclr(pi->measure_hold, id); + } + + return; +} + +void wlc_phy_mute_upd(wlc_phy_t *pih, bool mute, mbool flags) +{ + phy_info_t *pi = (phy_info_t *) pih; + + if (mute) { + mboolset(pi->measure_hold, PHY_HOLD_FOR_MUTE); + } else { + mboolclr(pi->measure_hold, PHY_HOLD_FOR_MUTE); + } + + if (!mute && (flags & PHY_MUTE_FOR_PREISM)) + pi->nphy_perical_last = pi->sh->now - pi->sh->glacial_timer; + return; +} + +void wlc_phy_clear_tssi(wlc_phy_t *pih) +{ + phy_info_t *pi = (phy_info_t *) pih; + + if (ISNPHY(pi)) { + return; + } else { + wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_0, NULL_TSSI_W); + wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_1, NULL_TSSI_W); + wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_0, NULL_TSSI_W); + wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_1, NULL_TSSI_W); + } +} + +static bool wlc_phy_cal_txpower_recalc_sw(phy_info_t *pi) +{ + return false; +} + +void wlc_phy_switch_radio(wlc_phy_t *pih, bool on) +{ + phy_info_t *pi = (phy_info_t *) pih; + + if (NORADIO_ENAB(pi->pubpi)) + return; + + { + uint mc; + + mc = R_REG(pi->sh->osh, &pi->regs->maccontrol); + } + + if (ISNPHY(pi)) { + wlc_phy_switch_radio_nphy(pi, on); + + } else if (ISLCNPHY(pi)) { + if (on) { + and_phy_reg(pi, 0x44c, + ~((0x1 << 8) | + (0x1 << 9) | + (0x1 << 10) | (0x1 << 11) | (0x1 << 12))); + and_phy_reg(pi, 0x4b0, ~((0x1 << 3) | (0x1 << 11))); + and_phy_reg(pi, 0x4f9, ~(0x1 << 3)); + } else { + and_phy_reg(pi, 0x44d, + ~((0x1 << 10) | + (0x1 << 11) | + (0x1 << 12) | (0x1 << 13) | (0x1 << 14))); + or_phy_reg(pi, 0x44c, + (0x1 << 8) | + (0x1 << 9) | + (0x1 << 10) | (0x1 << 11) | (0x1 << 12)); + + and_phy_reg(pi, 0x4b7, ~((0x7f << 8))); + and_phy_reg(pi, 0x4b1, ~((0x1 << 13))); + or_phy_reg(pi, 0x4b0, (0x1 << 3) | (0x1 << 11)); + and_phy_reg(pi, 0x4fa, ~((0x1 << 3))); + or_phy_reg(pi, 0x4f9, (0x1 << 3)); + } + } +} + +u16 wlc_phy_bw_state_get(wlc_phy_t *ppi) +{ + phy_info_t *pi = (phy_info_t *) ppi; + + return pi->bw; +} + +void wlc_phy_bw_state_set(wlc_phy_t *ppi, u16 bw) +{ + phy_info_t *pi = (phy_info_t *) ppi; + + pi->bw = bw; +} + +void wlc_phy_chanspec_radio_set(wlc_phy_t *ppi, chanspec_t newch) +{ + phy_info_t *pi = (phy_info_t *) ppi; + pi->radio_chanspec = newch; + +} + +chanspec_t wlc_phy_chanspec_get(wlc_phy_t *ppi) +{ + phy_info_t *pi = (phy_info_t *) ppi; + + return pi->radio_chanspec; +} + +void wlc_phy_chanspec_set(wlc_phy_t *ppi, chanspec_t chanspec) +{ + phy_info_t *pi = (phy_info_t *) ppi; + u16 m_cur_channel; + chansetfn_t chanspec_set = NULL; + + ASSERT(!wf_chspec_malformed(chanspec)); + + m_cur_channel = CHSPEC_CHANNEL(chanspec); + if (CHSPEC_IS5G(chanspec)) + m_cur_channel |= D11_CURCHANNEL_5G; + if (CHSPEC_IS40(chanspec)) + m_cur_channel |= D11_CURCHANNEL_40; + wlapi_bmac_write_shm(pi->sh->physhim, M_CURCHANNEL, m_cur_channel); + + chanspec_set = pi->pi_fptr.chanset; + if (chanspec_set) + (*chanspec_set) (pi, chanspec); + +} + +int wlc_phy_chanspec_freq2bandrange_lpssn(uint freq) +{ + int range = -1; + + if (freq < 2500) + range = WL_CHAN_FREQ_RANGE_2G; + else if (freq <= 5320) + range = WL_CHAN_FREQ_RANGE_5GL; + else if (freq <= 5700) + range = WL_CHAN_FREQ_RANGE_5GM; + else + range = WL_CHAN_FREQ_RANGE_5GH; + + return range; +} + +int wlc_phy_chanspec_bandrange_get(phy_info_t *pi, chanspec_t chanspec) +{ + int range = -1; + uint channel = CHSPEC_CHANNEL(chanspec); + uint freq = wlc_phy_channel2freq(channel); + + if (ISNPHY(pi)) { + range = wlc_phy_get_chan_freq_range_nphy(pi, channel); + } else if (ISLCNPHY(pi)) { + range = wlc_phy_chanspec_freq2bandrange_lpssn(freq); + } else + ASSERT(0); + + return range; +} + +void wlc_phy_chanspec_ch14_widefilter_set(wlc_phy_t *ppi, bool wide_filter) +{ + phy_info_t *pi = (phy_info_t *) ppi; + + pi->channel_14_wide_filter = wide_filter; + +} + +int wlc_phy_channel2freq(uint channel) +{ + uint i; + + for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) + if (chan_info_all[i].chan == channel) + return chan_info_all[i].freq; + return 0; +} + +void +wlc_phy_chanspec_band_validch(wlc_phy_t *ppi, uint band, chanvec_t *channels) +{ + phy_info_t *pi = (phy_info_t *) ppi; + uint i; + uint channel; + + ASSERT((band == WLC_BAND_2G) || (band == WLC_BAND_5G)); + + memset(channels, 0, sizeof(chanvec_t)); + + for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) { + channel = chan_info_all[i].chan; + + if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM) + && (channel <= LAST_REF5_CHANNUM)) + continue; + + if (((band == WLC_BAND_2G) && (channel <= CH_MAX_2G_CHANNEL)) || + ((band == WLC_BAND_5G) && (channel > CH_MAX_2G_CHANNEL))) + setbit(channels->vec, channel); + } +} + +chanspec_t wlc_phy_chanspec_band_firstch(wlc_phy_t *ppi, uint band) +{ + phy_info_t *pi = (phy_info_t *) ppi; + uint i; + uint channel; + chanspec_t chspec; + + ASSERT((band == WLC_BAND_2G) || (band == WLC_BAND_5G)); + + for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) { + channel = chan_info_all[i].chan; + + if (ISNPHY(pi) && IS40MHZ(pi)) { + uint j; + + for (j = 0; j < ARRAY_SIZE(chan_info_all); j++) { + if (chan_info_all[j].chan == + channel + CH_10MHZ_APART) + break; + } + + if (j == ARRAY_SIZE(chan_info_all)) + continue; + + channel = UPPER_20_SB(channel); + chspec = + channel | WL_CHANSPEC_BW_40 | + WL_CHANSPEC_CTL_SB_LOWER; + if (band == WLC_BAND_2G) + chspec |= WL_CHANSPEC_BAND_2G; + else + chspec |= WL_CHANSPEC_BAND_5G; + } else + chspec = CH20MHZ_CHSPEC(channel); + + if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM) + && (channel <= LAST_REF5_CHANNUM)) + continue; + + if (((band == WLC_BAND_2G) && (channel <= CH_MAX_2G_CHANNEL)) || + ((band == WLC_BAND_5G) && (channel > CH_MAX_2G_CHANNEL))) + return chspec; + } + + ASSERT(0); + + return (chanspec_t) INVCHANSPEC; +} + +int wlc_phy_txpower_get(wlc_phy_t *ppi, uint *qdbm, bool *override) +{ + phy_info_t *pi = (phy_info_t *) ppi; + + ASSERT(qdbm != NULL); + *qdbm = pi->tx_user_target[0]; + if (override != NULL) + *override = pi->txpwroverride; + return 0; +} + +void wlc_phy_txpower_target_set(wlc_phy_t *ppi, struct txpwr_limits *txpwr) +{ + bool mac_enabled = false; + phy_info_t *pi = (phy_info_t *) ppi; + + bcopy(&txpwr->cck[0], &pi->tx_user_target[TXP_FIRST_CCK], + WLC_NUM_RATES_CCK); + + bcopy(&txpwr->ofdm[0], &pi->tx_user_target[TXP_FIRST_OFDM], + WLC_NUM_RATES_OFDM); + bcopy(&txpwr->ofdm_cdd[0], &pi->tx_user_target[TXP_FIRST_OFDM_20_CDD], + WLC_NUM_RATES_OFDM); + + bcopy(&txpwr->ofdm_40_siso[0], + &pi->tx_user_target[TXP_FIRST_OFDM_40_SISO], WLC_NUM_RATES_OFDM); + bcopy(&txpwr->ofdm_40_cdd[0], + &pi->tx_user_target[TXP_FIRST_OFDM_40_CDD], WLC_NUM_RATES_OFDM); + + bcopy(&txpwr->mcs_20_siso[0], + &pi->tx_user_target[TXP_FIRST_MCS_20_SISO], + WLC_NUM_RATES_MCS_1_STREAM); + bcopy(&txpwr->mcs_20_cdd[0], &pi->tx_user_target[TXP_FIRST_MCS_20_CDD], + WLC_NUM_RATES_MCS_1_STREAM); + bcopy(&txpwr->mcs_20_stbc[0], + &pi->tx_user_target[TXP_FIRST_MCS_20_STBC], + WLC_NUM_RATES_MCS_1_STREAM); + bcopy(&txpwr->mcs_20_mimo[0], &pi->tx_user_target[TXP_FIRST_MCS_20_SDM], + WLC_NUM_RATES_MCS_2_STREAM); + + bcopy(&txpwr->mcs_40_siso[0], + &pi->tx_user_target[TXP_FIRST_MCS_40_SISO], + WLC_NUM_RATES_MCS_1_STREAM); + bcopy(&txpwr->mcs_40_cdd[0], &pi->tx_user_target[TXP_FIRST_MCS_40_CDD], + WLC_NUM_RATES_MCS_1_STREAM); + bcopy(&txpwr->mcs_40_stbc[0], + &pi->tx_user_target[TXP_FIRST_MCS_40_STBC], + WLC_NUM_RATES_MCS_1_STREAM); + bcopy(&txpwr->mcs_40_mimo[0], &pi->tx_user_target[TXP_FIRST_MCS_40_SDM], + WLC_NUM_RATES_MCS_2_STREAM); + + if (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC) + mac_enabled = true; + + if (mac_enabled) + wlapi_suspend_mac_and_wait(pi->sh->physhim); + + wlc_phy_txpower_recalc_target(pi); + wlc_phy_cal_txpower_recalc_sw(pi); + + if (mac_enabled) + wlapi_enable_mac(pi->sh->physhim); +} + +int wlc_phy_txpower_set(wlc_phy_t *ppi, uint qdbm, bool override) +{ + phy_info_t *pi = (phy_info_t *) ppi; + int i; + + if (qdbm > 127) + return 5; + + for (i = 0; i < TXP_NUM_RATES; i++) + pi->tx_user_target[i] = (u8) qdbm; + + pi->txpwroverride = false; + + if (pi->sh->up) { + if (!SCAN_INPROG_PHY(pi)) { + bool suspend; + + suspend = + (0 == + (R_REG(pi->sh->osh, &pi->regs->maccontrol) & + MCTL_EN_MAC)); + + if (!suspend) + wlapi_suspend_mac_and_wait(pi->sh->physhim); + + wlc_phy_txpower_recalc_target(pi); + wlc_phy_cal_txpower_recalc_sw(pi); + + if (!suspend) + wlapi_enable_mac(pi->sh->physhim); + } + } + return 0; +} + +void +wlc_phy_txpower_sromlimit(wlc_phy_t *ppi, uint channel, u8 *min_pwr, + u8 *max_pwr, int txp_rate_idx) +{ + phy_info_t *pi = (phy_info_t *) ppi; + uint i; + + *min_pwr = pi->min_txpower * WLC_TXPWR_DB_FACTOR; + + if (ISNPHY(pi)) { + if (txp_rate_idx < 0) + txp_rate_idx = TXP_FIRST_CCK; + wlc_phy_txpower_sromlimit_get_nphy(pi, channel, max_pwr, + (u8) txp_rate_idx); + + } else if ((channel <= CH_MAX_2G_CHANNEL)) { + if (txp_rate_idx < 0) + txp_rate_idx = TXP_FIRST_CCK; + *max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx]; + } else { + + *max_pwr = WLC_TXPWR_MAX; + + if (txp_rate_idx < 0) + txp_rate_idx = TXP_FIRST_OFDM; + + for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) { + if (channel == chan_info_all[i].chan) { + break; + } + } + ASSERT(i < ARRAY_SIZE(chan_info_all)); + + if (pi->hwtxpwr) { + *max_pwr = pi->hwtxpwr[i]; + } else { + + if ((i >= FIRST_MID_5G_CHAN) && (i <= LAST_MID_5G_CHAN)) + *max_pwr = + pi->tx_srom_max_rate_5g_mid[txp_rate_idx]; + if ((i >= FIRST_HIGH_5G_CHAN) + && (i <= LAST_HIGH_5G_CHAN)) + *max_pwr = + pi->tx_srom_max_rate_5g_hi[txp_rate_idx]; + if ((i >= FIRST_LOW_5G_CHAN) && (i <= LAST_LOW_5G_CHAN)) + *max_pwr = + pi->tx_srom_max_rate_5g_low[txp_rate_idx]; + } + } +} + +void +wlc_phy_txpower_sromlimit_max_get(wlc_phy_t *ppi, uint chan, u8 *max_txpwr, + u8 *min_txpwr) +{ + phy_info_t *pi = (phy_info_t *) ppi; + u8 tx_pwr_max = 0; + u8 tx_pwr_min = 255; + u8 max_num_rate; + u8 maxtxpwr, mintxpwr, rate, pactrl; + + pactrl = 0; + + max_num_rate = ISNPHY(pi) ? TXP_NUM_RATES : + ISLCNPHY(pi) ? (TXP_LAST_SISO_MCS_20 + 1) : (TXP_LAST_OFDM + 1); + + for (rate = 0; rate < max_num_rate; rate++) { + + wlc_phy_txpower_sromlimit(ppi, chan, &mintxpwr, &maxtxpwr, + rate); + + maxtxpwr = (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0; + + maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0; + + tx_pwr_max = max(tx_pwr_max, maxtxpwr); + tx_pwr_min = min(tx_pwr_min, maxtxpwr); + } + *max_txpwr = tx_pwr_max; + *min_txpwr = tx_pwr_min; +} + +void +wlc_phy_txpower_boardlimit_band(wlc_phy_t *ppi, uint bandunit, s32 *max_pwr, + s32 *min_pwr, u32 *step_pwr) +{ + return; +} + +u8 wlc_phy_txpower_get_target_min(wlc_phy_t *ppi) +{ + phy_info_t *pi = (phy_info_t *) ppi; + + return pi->tx_power_min; +} + +u8 wlc_phy_txpower_get_target_max(wlc_phy_t *ppi) +{ + phy_info_t *pi = (phy_info_t *) ppi; + + return pi->tx_power_max; +} + +void wlc_phy_txpower_recalc_target(phy_info_t *pi) +{ + u8 maxtxpwr, mintxpwr, rate, pactrl; + uint target_chan; + u8 tx_pwr_target[TXP_NUM_RATES]; + u8 tx_pwr_max = 0; + u8 tx_pwr_min = 255; + u8 tx_pwr_max_rate_ind = 0; + u8 max_num_rate; + u8 start_rate = 0; + chanspec_t chspec; + u32 band = CHSPEC2WLC_BAND(pi->radio_chanspec); + initfn_t txpwr_recalc_fn = NULL; + + chspec = pi->radio_chanspec; + if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) + target_chan = CHSPEC_CHANNEL(chspec); + else if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) + target_chan = UPPER_20_SB(CHSPEC_CHANNEL(chspec)); + else + target_chan = LOWER_20_SB(CHSPEC_CHANNEL(chspec)); + + pactrl = 0; + if (ISLCNPHY(pi)) { + u32 offset_mcs, i; + + if (CHSPEC_IS40(pi->radio_chanspec)) { + offset_mcs = pi->mcs40_po; + for (i = TXP_FIRST_SISO_MCS_20; + i <= TXP_LAST_SISO_MCS_20; i++) { + pi->tx_srom_max_rate_2g[i - 8] = + pi->tx_srom_max_2g - + ((offset_mcs & 0xf) * 2); + offset_mcs >>= 4; + } + } else { + offset_mcs = pi->mcs20_po; + for (i = TXP_FIRST_SISO_MCS_20; + i <= TXP_LAST_SISO_MCS_20; i++) { + pi->tx_srom_max_rate_2g[i - 8] = + pi->tx_srom_max_2g - + ((offset_mcs & 0xf) * 2); + offset_mcs >>= 4; + } + } + } +#if WL11N + max_num_rate = ((ISNPHY(pi)) ? (TXP_NUM_RATES) : + ((ISLCNPHY(pi)) ? + (TXP_LAST_SISO_MCS_20 + 1) : (TXP_LAST_OFDM + 1))); +#else + max_num_rate = ((ISNPHY(pi)) ? (TXP_NUM_RATES) : (TXP_LAST_OFDM + 1)); +#endif + + wlc_phy_upd_env_txpwr_rate_limits(pi, band); + + for (rate = start_rate; rate < max_num_rate; rate++) { + + tx_pwr_target[rate] = pi->tx_user_target[rate]; + + if (pi->user_txpwr_at_rfport) { + tx_pwr_target[rate] += + wlc_user_txpwr_antport_to_rfport(pi, target_chan, + band, rate); + } + + { + + wlc_phy_txpower_sromlimit((wlc_phy_t *) pi, target_chan, + &mintxpwr, &maxtxpwr, rate); + + maxtxpwr = min(maxtxpwr, pi->txpwr_limit[rate]); + + maxtxpwr = + (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0; + + maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0; + + maxtxpwr = min(maxtxpwr, tx_pwr_target[rate]); + + if (pi->txpwr_percent <= 100) + maxtxpwr = (maxtxpwr * pi->txpwr_percent) / 100; + + tx_pwr_target[rate] = max(maxtxpwr, mintxpwr); + } + + tx_pwr_target[rate] = + min(tx_pwr_target[rate], pi->txpwr_env_limit[rate]); + + if (tx_pwr_target[rate] > tx_pwr_max) + tx_pwr_max_rate_ind = rate; + + tx_pwr_max = max(tx_pwr_max, tx_pwr_target[rate]); + tx_pwr_min = min(tx_pwr_min, tx_pwr_target[rate]); + } + + memset(pi->tx_power_offset, 0, sizeof(pi->tx_power_offset)); + pi->tx_power_max = tx_pwr_max; + pi->tx_power_min = tx_pwr_min; + pi->tx_power_max_rate_ind = tx_pwr_max_rate_ind; + for (rate = 0; rate < max_num_rate; rate++) { + + pi->tx_power_target[rate] = tx_pwr_target[rate]; + + if (!pi->hwpwrctrl || ISNPHY(pi)) { + pi->tx_power_offset[rate] = + pi->tx_power_max - pi->tx_power_target[rate]; + } else { + pi->tx_power_offset[rate] = + pi->tx_power_target[rate] - pi->tx_power_min; + } + } + + txpwr_recalc_fn = pi->pi_fptr.txpwrrecalc; + if (txpwr_recalc_fn) + (*txpwr_recalc_fn) (pi); +} + +void +wlc_phy_txpower_reg_limit_calc(phy_info_t *pi, struct txpwr_limits *txpwr, + chanspec_t chanspec) +{ + u8 tmp_txpwr_limit[2 * WLC_NUM_RATES_OFDM]; + u8 *txpwr_ptr1 = NULL, *txpwr_ptr2 = NULL; + int rate_start_index = 0, rate1, rate2, k; + + for (rate1 = WL_TX_POWER_CCK_FIRST, rate2 = 0; + rate2 < WL_TX_POWER_CCK_NUM; rate1++, rate2++) + pi->txpwr_limit[rate1] = txpwr->cck[rate2]; + + for (rate1 = WL_TX_POWER_OFDM_FIRST, rate2 = 0; + rate2 < WL_TX_POWER_OFDM_NUM; rate1++, rate2++) + pi->txpwr_limit[rate1] = txpwr->ofdm[rate2]; + + if (ISNPHY(pi)) { + + for (k = 0; k < 4; k++) { + switch (k) { + case 0: + + txpwr_ptr1 = txpwr->mcs_20_siso; + txpwr_ptr2 = txpwr->ofdm; + rate_start_index = WL_TX_POWER_OFDM_FIRST; + break; + case 1: + + txpwr_ptr1 = txpwr->mcs_20_cdd; + txpwr_ptr2 = txpwr->ofdm_cdd; + rate_start_index = WL_TX_POWER_OFDM20_CDD_FIRST; + break; + case 2: + + txpwr_ptr1 = txpwr->mcs_40_siso; + txpwr_ptr2 = txpwr->ofdm_40_siso; + rate_start_index = + WL_TX_POWER_OFDM40_SISO_FIRST; + break; + case 3: + + txpwr_ptr1 = txpwr->mcs_40_cdd; + txpwr_ptr2 = txpwr->ofdm_40_cdd; + rate_start_index = WL_TX_POWER_OFDM40_CDD_FIRST; + break; + } + + for (rate2 = 0; rate2 < WLC_NUM_RATES_OFDM; rate2++) { + tmp_txpwr_limit[rate2] = 0; + tmp_txpwr_limit[WLC_NUM_RATES_OFDM + rate2] = + txpwr_ptr1[rate2]; + } + wlc_phy_mcs_to_ofdm_powers_nphy(tmp_txpwr_limit, 0, + WLC_NUM_RATES_OFDM - 1, + WLC_NUM_RATES_OFDM); + for (rate1 = rate_start_index, rate2 = 0; + rate2 < WLC_NUM_RATES_OFDM; rate1++, rate2++) + pi->txpwr_limit[rate1] = + min(txpwr_ptr2[rate2], + tmp_txpwr_limit[rate2]); + } + + for (k = 0; k < 4; k++) { + switch (k) { + case 0: + + txpwr_ptr1 = txpwr->ofdm; + txpwr_ptr2 = txpwr->mcs_20_siso; + rate_start_index = WL_TX_POWER_MCS20_SISO_FIRST; + break; + case 1: + + txpwr_ptr1 = txpwr->ofdm_cdd; + txpwr_ptr2 = txpwr->mcs_20_cdd; + rate_start_index = WL_TX_POWER_MCS20_CDD_FIRST; + break; + case 2: + + txpwr_ptr1 = txpwr->ofdm_40_siso; + txpwr_ptr2 = txpwr->mcs_40_siso; + rate_start_index = WL_TX_POWER_MCS40_SISO_FIRST; + break; + case 3: + + txpwr_ptr1 = txpwr->ofdm_40_cdd; + txpwr_ptr2 = txpwr->mcs_40_cdd; + rate_start_index = WL_TX_POWER_MCS40_CDD_FIRST; + break; + } + for (rate2 = 0; rate2 < WLC_NUM_RATES_OFDM; rate2++) { + tmp_txpwr_limit[rate2] = 0; + tmp_txpwr_limit[WLC_NUM_RATES_OFDM + rate2] = + txpwr_ptr1[rate2]; + } + wlc_phy_ofdm_to_mcs_powers_nphy(tmp_txpwr_limit, 0, + WLC_NUM_RATES_OFDM - 1, + WLC_NUM_RATES_OFDM); + for (rate1 = rate_start_index, rate2 = 0; + rate2 < WLC_NUM_RATES_MCS_1_STREAM; + rate1++, rate2++) + pi->txpwr_limit[rate1] = + min(txpwr_ptr2[rate2], + tmp_txpwr_limit[rate2]); + } + + for (k = 0; k < 2; k++) { + switch (k) { + case 0: + + rate_start_index = WL_TX_POWER_MCS20_STBC_FIRST; + txpwr_ptr1 = txpwr->mcs_20_stbc; + break; + case 1: + + rate_start_index = WL_TX_POWER_MCS40_STBC_FIRST; + txpwr_ptr1 = txpwr->mcs_40_stbc; + break; + } + for (rate1 = rate_start_index, rate2 = 0; + rate2 < WLC_NUM_RATES_MCS_1_STREAM; + rate1++, rate2++) + pi->txpwr_limit[rate1] = txpwr_ptr1[rate2]; + } + + for (k = 0; k < 2; k++) { + switch (k) { + case 0: + + rate_start_index = WL_TX_POWER_MCS20_SDM_FIRST; + txpwr_ptr1 = txpwr->mcs_20_mimo; + break; + case 1: + + rate_start_index = WL_TX_POWER_MCS40_SDM_FIRST; + txpwr_ptr1 = txpwr->mcs_40_mimo; + break; + } + for (rate1 = rate_start_index, rate2 = 0; + rate2 < WLC_NUM_RATES_MCS_2_STREAM; + rate1++, rate2++) + pi->txpwr_limit[rate1] = txpwr_ptr1[rate2]; + } + + pi->txpwr_limit[WL_TX_POWER_MCS_32] = txpwr->mcs32; + + pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST] = + min(pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST], + pi->txpwr_limit[WL_TX_POWER_MCS_32]); + pi->txpwr_limit[WL_TX_POWER_MCS_32] = + pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST]; + } +} + +void wlc_phy_txpwr_percent_set(wlc_phy_t *ppi, u8 txpwr_percent) +{ + phy_info_t *pi = (phy_info_t *) ppi; + + pi->txpwr_percent = txpwr_percent; +} + +void wlc_phy_machwcap_set(wlc_phy_t *ppi, u32 machwcap) +{ + phy_info_t *pi = (phy_info_t *) ppi; + + pi->sh->machwcap = machwcap; +} + +void wlc_phy_runbist_config(wlc_phy_t *ppi, bool start_end) +{ + phy_info_t *pi = (phy_info_t *) ppi; + u16 rxc; + rxc = 0; + + if (start_end == ON) { + if (!ISNPHY(pi)) + return; + + if (NREV_IS(pi->pubpi.phy_rev, 3) + || NREV_IS(pi->pubpi.phy_rev, 4)) { + W_REG(pi->sh->osh, &pi->regs->phyregaddr, 0xa0); + (void)R_REG(pi->sh->osh, &pi->regs->phyregaddr); + rxc = R_REG(pi->sh->osh, &pi->regs->phyregdata); + W_REG(pi->sh->osh, &pi->regs->phyregdata, + (0x1 << 15) | rxc); + } + } else { + if (NREV_IS(pi->pubpi.phy_rev, 3) + || NREV_IS(pi->pubpi.phy_rev, 4)) { + W_REG(pi->sh->osh, &pi->regs->phyregaddr, 0xa0); + (void)R_REG(pi->sh->osh, &pi->regs->phyregaddr); + W_REG(pi->sh->osh, &pi->regs->phyregdata, rxc); + } + + wlc_phy_por_inform(ppi); + } +} + +void +wlc_phy_txpower_limit_set(wlc_phy_t *ppi, struct txpwr_limits *txpwr, + chanspec_t chanspec) +{ + phy_info_t *pi = (phy_info_t *) ppi; + + wlc_phy_txpower_reg_limit_calc(pi, txpwr, chanspec); + + if (ISLCNPHY(pi)) { + int i, j; + for (i = TXP_FIRST_OFDM_20_CDD, j = 0; + j < WLC_NUM_RATES_MCS_1_STREAM; i++, j++) { + if (txpwr->mcs_20_siso[j]) + pi->txpwr_limit[i] = txpwr->mcs_20_siso[j]; + else + pi->txpwr_limit[i] = txpwr->ofdm[j]; + } + } + + wlapi_suspend_mac_and_wait(pi->sh->physhim); + + wlc_phy_txpower_recalc_target(pi); + wlc_phy_cal_txpower_recalc_sw(pi); + wlapi_enable_mac(pi->sh->physhim); +} + +void wlc_phy_ofdm_rateset_war(wlc_phy_t *pih, bool war) +{ + phy_info_t *pi = (phy_info_t *) pih; + + pi->ofdm_rateset_war = war; +} + +void wlc_phy_bf_preempt_enable(wlc_phy_t *pih, bool bf_preempt) +{ + phy_info_t *pi = (phy_info_t *) pih; + + pi->bf_preempt_4306 = bf_preempt; +} + +void wlc_phy_txpower_update_shm(phy_info_t *pi) +{ + int j; + if (ISNPHY(pi)) { + ASSERT(0); + return; + } + + if (!pi->sh->clk) + return; + + if (pi->hwpwrctrl) { + u16 offset; + + wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_MAX, 63); + wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_N, + 1 << NUM_TSSI_FRAMES); + + wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_TARGET, + pi->tx_power_min << NUM_TSSI_FRAMES); + + wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_CUR, + pi->hwpwr_txcur); + + for (j = TXP_FIRST_OFDM; j <= TXP_LAST_OFDM; j++) { + const u8 ucode_ofdm_rates[] = { + 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c + }; + offset = wlapi_bmac_rate_shm_offset(pi->sh->physhim, + ucode_ofdm_rates[j - + TXP_FIRST_OFDM]); + wlapi_bmac_write_shm(pi->sh->physhim, offset + 6, + pi->tx_power_offset[j]); + wlapi_bmac_write_shm(pi->sh->physhim, offset + 14, + -(pi->tx_power_offset[j] / 2)); + } + + wlapi_bmac_mhf(pi->sh->physhim, MHF2, MHF2_HWPWRCTL, + MHF2_HWPWRCTL, WLC_BAND_ALL); + } else { + int i; + + for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) + pi->tx_power_offset[i] = + (u8) roundup(pi->tx_power_offset[i], 8); + wlapi_bmac_write_shm(pi->sh->physhim, M_OFDM_OFFSET, + (u16) ((pi-> + tx_power_offset[TXP_FIRST_OFDM] + + 7) >> 3)); + } +} + +bool wlc_phy_txpower_hw_ctrl_get(wlc_phy_t *ppi) +{ + phy_info_t *pi = (phy_info_t *) ppi; + + if (ISNPHY(pi)) { + return pi->nphy_txpwrctrl; + } else { + return pi->hwpwrctrl; + } +} + +void wlc_phy_txpower_hw_ctrl_set(wlc_phy_t *ppi, bool hwpwrctrl) +{ + phy_info_t *pi = (phy_info_t *) ppi; + bool cur_hwpwrctrl = pi->hwpwrctrl; + bool suspend; + + if (!pi->hwpwrctrl_capable) { + return; + } + + pi->hwpwrctrl = hwpwrctrl; + pi->nphy_txpwrctrl = hwpwrctrl; + pi->txpwrctrl = hwpwrctrl; + + if (ISNPHY(pi)) { + suspend = + (0 == + (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + if (!suspend) + wlapi_suspend_mac_and_wait(pi->sh->physhim); + + wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl); + if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) { + wlc_phy_txpwr_fixpower_nphy(pi); + } else { + + mod_phy_reg(pi, 0x1e7, (0x7f << 0), + pi->saved_txpwr_idx); + } + + if (!suspend) + wlapi_enable_mac(pi->sh->physhim); + } else if (hwpwrctrl != cur_hwpwrctrl) { + + return; + } +} + +void wlc_phy_txpower_ipa_upd(phy_info_t *pi) +{ + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + pi->ipa2g_on = (pi->srom_fem2g.extpagain == 2); + pi->ipa5g_on = (pi->srom_fem5g.extpagain == 2); + } else { + pi->ipa2g_on = false; + pi->ipa5g_on = false; + } +} + +static u32 wlc_phy_txpower_est_power_nphy(phy_info_t *pi); + +static u32 wlc_phy_txpower_est_power_nphy(phy_info_t *pi) +{ + s16 tx0_status, tx1_status; + u16 estPower1, estPower2; + u8 pwr0, pwr1, adj_pwr0, adj_pwr1; + u32 est_pwr; + + estPower1 = read_phy_reg(pi, 0x118); + estPower2 = read_phy_reg(pi, 0x119); + + if ((estPower1 & (0x1 << 8)) + == (0x1 << 8)) { + pwr0 = (u8) (estPower1 & (0xff << 0)) + >> 0; + } else { + pwr0 = 0x80; + } + + if ((estPower2 & (0x1 << 8)) + == (0x1 << 8)) { + pwr1 = (u8) (estPower2 & (0xff << 0)) + >> 0; + } else { + pwr1 = 0x80; + } + + tx0_status = read_phy_reg(pi, 0x1ed); + tx1_status = read_phy_reg(pi, 0x1ee); + + if ((tx0_status & (0x1 << 15)) + == (0x1 << 15)) { + adj_pwr0 = (u8) (tx0_status & (0xff << 0)) + >> 0; + } else { + adj_pwr0 = 0x80; + } + if ((tx1_status & (0x1 << 15)) + == (0x1 << 15)) { + adj_pwr1 = (u8) (tx1_status & (0xff << 0)) + >> 0; + } else { + adj_pwr1 = 0x80; + } + + est_pwr = + (u32) ((pwr0 << 24) | (pwr1 << 16) | (adj_pwr0 << 8) | adj_pwr1); + return est_pwr; +} + +void +wlc_phy_txpower_get_current(wlc_phy_t *ppi, tx_power_t *power, uint channel) +{ + phy_info_t *pi = (phy_info_t *) ppi; + uint rate, num_rates; + u8 min_pwr, max_pwr; + +#if WL_TX_POWER_RATES != TXP_NUM_RATES +#error "tx_power_t struct out of sync with this fn" +#endif + + if (ISNPHY(pi)) { + power->rf_cores = 2; + power->flags |= (WL_TX_POWER_F_MIMO); + if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON) + power->flags |= + (WL_TX_POWER_F_ENABLED | WL_TX_POWER_F_HW); + } else if (ISLCNPHY(pi)) { + power->rf_cores = 1; + power->flags |= (WL_TX_POWER_F_SISO); + if (pi->radiopwr_override == RADIOPWR_OVERRIDE_DEF) + power->flags |= WL_TX_POWER_F_ENABLED; + if (pi->hwpwrctrl) + power->flags |= WL_TX_POWER_F_HW; + } + + num_rates = ((ISNPHY(pi)) ? (TXP_NUM_RATES) : + ((ISLCNPHY(pi)) ? + (TXP_LAST_OFDM_20_CDD + 1) : (TXP_LAST_OFDM + 1))); + + for (rate = 0; rate < num_rates; rate++) { + power->user_limit[rate] = pi->tx_user_target[rate]; + wlc_phy_txpower_sromlimit(ppi, channel, &min_pwr, &max_pwr, + rate); + power->board_limit[rate] = (u8) max_pwr; + power->target[rate] = pi->tx_power_target[rate]; + } + + if (ISNPHY(pi)) { + u32 est_pout; + + wlapi_suspend_mac_and_wait(pi->sh->physhim); + wlc_phyreg_enter((wlc_phy_t *) pi); + est_pout = wlc_phy_txpower_est_power_nphy(pi); + wlc_phyreg_exit((wlc_phy_t *) pi); + wlapi_enable_mac(pi->sh->physhim); + + power->est_Pout[0] = (est_pout >> 8) & 0xff; + power->est_Pout[1] = est_pout & 0xff; + + power->est_Pout_act[0] = est_pout >> 24; + power->est_Pout_act[1] = (est_pout >> 16) & 0xff; + + if (power->est_Pout[0] == 0x80) + power->est_Pout[0] = 0; + if (power->est_Pout[1] == 0x80) + power->est_Pout[1] = 0; + + if (power->est_Pout_act[0] == 0x80) + power->est_Pout_act[0] = 0; + if (power->est_Pout_act[1] == 0x80) + power->est_Pout_act[1] = 0; + + power->est_Pout_cck = 0; + + power->tx_power_max[0] = pi->tx_power_max; + power->tx_power_max[1] = pi->tx_power_max; + + power->tx_power_max_rate_ind[0] = pi->tx_power_max_rate_ind; + power->tx_power_max_rate_ind[1] = pi->tx_power_max_rate_ind; + } else if (!pi->hwpwrctrl) { + } else if (pi->sh->up) { + + wlc_phyreg_enter(ppi); + if (ISLCNPHY(pi)) { + + power->tx_power_max[0] = pi->tx_power_max; + power->tx_power_max[1] = pi->tx_power_max; + + power->tx_power_max_rate_ind[0] = + pi->tx_power_max_rate_ind; + power->tx_power_max_rate_ind[1] = + pi->tx_power_max_rate_ind; + + if (wlc_phy_tpc_isenabled_lcnphy(pi)) + power->flags |= + (WL_TX_POWER_F_HW | WL_TX_POWER_F_ENABLED); + else + power->flags &= + ~(WL_TX_POWER_F_HW | WL_TX_POWER_F_ENABLED); + + wlc_lcnphy_get_tssi(pi, (s8 *) &power->est_Pout[0], + (s8 *) &power->est_Pout_cck); + } + wlc_phyreg_exit(ppi); + } +} + +void wlc_phy_antsel_type_set(wlc_phy_t *ppi, u8 antsel_type) +{ + phy_info_t *pi = (phy_info_t *) ppi; + + pi->antsel_type = antsel_type; +} + +bool wlc_phy_test_ison(wlc_phy_t *ppi) +{ + phy_info_t *pi = (phy_info_t *) ppi; + + return pi->phytest_on; +} + +bool wlc_phy_ant_rxdiv_get(wlc_phy_t *ppi, u8 *pval) +{ + phy_info_t *pi = (phy_info_t *) ppi; + bool ret = true; + + wlc_phyreg_enter(ppi); + + if (ISNPHY(pi)) { + + ret = false; + } else if (ISLCNPHY(pi)) { + u16 crsctrl = read_phy_reg(pi, 0x410); + u16 div = crsctrl & (0x1 << 1); + *pval = (div | ((crsctrl & (0x1 << 0)) ^ (div >> 1))); + } + + wlc_phyreg_exit(ppi); + + return ret; +} + +void wlc_phy_ant_rxdiv_set(wlc_phy_t *ppi, u8 val) +{ + phy_info_t *pi = (phy_info_t *) ppi; + bool suspend; + + pi->sh->rx_antdiv = val; + + if (!(ISNPHY(pi) && D11REV_IS(pi->sh->corerev, 16))) { + if (val > ANT_RX_DIV_FORCE_1) + wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV, + MHF1_ANTDIV, WLC_BAND_ALL); + else + wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV, 0, + WLC_BAND_ALL); + } + + if (ISNPHY(pi)) { + + return; + } + + if (!pi->sh->clk) + return; + + suspend = + (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + if (!suspend) + wlapi_suspend_mac_and_wait(pi->sh->physhim); + + if (ISLCNPHY(pi)) { + if (val > ANT_RX_DIV_FORCE_1) { + mod_phy_reg(pi, 0x410, (0x1 << 1), 0x01 << 1); + mod_phy_reg(pi, 0x410, + (0x1 << 0), + ((ANT_RX_DIV_START_1 == val) ? 1 : 0) << 0); + } else { + mod_phy_reg(pi, 0x410, (0x1 << 1), 0x00 << 1); + mod_phy_reg(pi, 0x410, (0x1 << 0), (u16) val << 0); + } + } else { + ASSERT(0); + } + + if (!suspend) + wlapi_enable_mac(pi->sh->physhim); + + return; +} + +static bool +wlc_phy_noise_calc_phy(phy_info_t *pi, u32 *cmplx_pwr, s8 *pwr_ant) +{ + s8 cmplx_pwr_dbm[PHY_CORE_MAX]; + u8 i; + + memset((u8 *) cmplx_pwr_dbm, 0, sizeof(cmplx_pwr_dbm)); + ASSERT(pi->pubpi.phy_corenum <= PHY_CORE_MAX); + wlc_phy_compute_dB(cmplx_pwr, cmplx_pwr_dbm, pi->pubpi.phy_corenum); + + for (i = 0; i < pi->pubpi.phy_corenum; i++) { + if (NREV_GE(pi->pubpi.phy_rev, 3)) + cmplx_pwr_dbm[i] += (s8) PHY_NOISE_OFFSETFACT_4322; + else + + cmplx_pwr_dbm[i] += (s8) (16 - (15) * 3 - 70); + } + + for (i = 0; i < pi->pubpi.phy_corenum; i++) { + pi->nphy_noise_win[i][pi->nphy_noise_index] = cmplx_pwr_dbm[i]; + pwr_ant[i] = cmplx_pwr_dbm[i]; + } + pi->nphy_noise_index = + MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ); + return true; +} + +static void +wlc_phy_noise_sample_request(wlc_phy_t *pih, u8 reason, u8 ch) +{ + phy_info_t *pi = (phy_info_t *) pih; + s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; + bool sampling_in_progress = (pi->phynoise_state != 0); + bool wait_for_intr = true; + + if (NORADIO_ENAB(pi->pubpi)) { + return; + } + + switch (reason) { + case PHY_NOISE_SAMPLE_MON: + + pi->phynoise_chan_watchdog = ch; + pi->phynoise_state |= PHY_NOISE_STATE_MON; + + break; + + case PHY_NOISE_SAMPLE_EXTERNAL: + + pi->phynoise_state |= PHY_NOISE_STATE_EXTERNAL; + break; + + default: + ASSERT(0); + break; + } + + if (sampling_in_progress) + return; + + pi->phynoise_now = pi->sh->now; + + if (pi->phy_fixed_noise) { + if (ISNPHY(pi)) { + pi->nphy_noise_win[WL_ANT_IDX_1][pi->nphy_noise_index] = + PHY_NOISE_FIXED_VAL_NPHY; + pi->nphy_noise_win[WL_ANT_IDX_2][pi->nphy_noise_index] = + PHY_NOISE_FIXED_VAL_NPHY; + pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index, + PHY_NOISE_WINDOW_SZ); + + noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; + } else { + + noise_dbm = PHY_NOISE_FIXED_VAL; + } + + wait_for_intr = false; + goto done; + } + + if (ISLCNPHY(pi)) { + if (!pi->phynoise_polling + || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) { + wlapi_bmac_write_shm(pi->sh->physhim, M_JSSI_0, 0); + wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0); + wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0); + wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0); + wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0); + + OR_REG(pi->sh->osh, &pi->regs->maccommand, + MCMD_BG_NOISE); + } else { + wlapi_suspend_mac_and_wait(pi->sh->physhim); + wlc_lcnphy_deaf_mode(pi, (bool) 0); + noise_dbm = (s8) wlc_lcnphy_rx_signal_power(pi, 20); + wlc_lcnphy_deaf_mode(pi, (bool) 1); + wlapi_enable_mac(pi->sh->physhim); + wait_for_intr = false; + } + } else if (ISNPHY(pi)) { + if (!pi->phynoise_polling + || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) { + + wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0); + wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0); + wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0); + wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0); + + OR_REG(pi->sh->osh, &pi->regs->maccommand, + MCMD_BG_NOISE); + } else { + phy_iq_est_t est[PHY_CORE_MAX]; + u32 cmplx_pwr[PHY_CORE_MAX]; + s8 noise_dbm_ant[PHY_CORE_MAX]; + u16 log_num_samps, num_samps, classif_state = 0; + u8 wait_time = 32; + u8 wait_crs = 0; + u8 i; + + memset((u8 *) est, 0, sizeof(est)); + memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr)); + memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant)); + + log_num_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY; + num_samps = 1 << log_num_samps; + + wlapi_suspend_mac_and_wait(pi->sh->physhim); + classif_state = wlc_phy_classifier_nphy(pi, 0, 0); + wlc_phy_classifier_nphy(pi, 3, 0); + wlc_phy_rx_iq_est_nphy(pi, est, num_samps, wait_time, + wait_crs); + wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state); + wlapi_enable_mac(pi->sh->physhim); + + for (i = 0; i < pi->pubpi.phy_corenum; i++) + cmplx_pwr[i] = + (est[i].i_pwr + + est[i].q_pwr) >> log_num_samps; + + wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant); + + for (i = 0; i < pi->pubpi.phy_corenum; i++) { + pi->nphy_noise_win[i][pi->nphy_noise_index] = + noise_dbm_ant[i]; + + if (noise_dbm_ant[i] > noise_dbm) + noise_dbm = noise_dbm_ant[i]; + } + pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index, + PHY_NOISE_WINDOW_SZ); + + wait_for_intr = false; + } + } + + done: + + if (!wait_for_intr) + wlc_phy_noise_cb(pi, ch, noise_dbm); + +} + +void wlc_phy_noise_sample_request_external(wlc_phy_t *pih) +{ + u8 channel; + + channel = CHSPEC_CHANNEL(wlc_phy_chanspec_get(pih)); + + wlc_phy_noise_sample_request(pih, PHY_NOISE_SAMPLE_EXTERNAL, channel); +} + +static void wlc_phy_noise_cb(phy_info_t *pi, u8 channel, s8 noise_dbm) +{ + if (!pi->phynoise_state) + return; + + if (pi->phynoise_state & PHY_NOISE_STATE_MON) { + if (pi->phynoise_chan_watchdog == channel) { + pi->sh->phy_noise_window[pi->sh->phy_noise_index] = + noise_dbm; + pi->sh->phy_noise_index = + MODINC(pi->sh->phy_noise_index, MA_WINDOW_SZ); + } + pi->phynoise_state &= ~PHY_NOISE_STATE_MON; + } + + if (pi->phynoise_state & PHY_NOISE_STATE_EXTERNAL) { + pi->phynoise_state &= ~PHY_NOISE_STATE_EXTERNAL; + } + +} + +static s8 wlc_phy_noise_read_shmem(phy_info_t *pi) +{ + u32 cmplx_pwr[PHY_CORE_MAX]; + s8 noise_dbm_ant[PHY_CORE_MAX]; + u16 lo, hi; + u32 cmplx_pwr_tot = 0; + s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; + u8 idx, core; + + ASSERT(pi->pubpi.phy_corenum <= PHY_CORE_MAX); + memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr)); + memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant)); + + for (idx = 0, core = 0; core < pi->pubpi.phy_corenum; idx += 2, core++) { + lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP(idx)); + hi = wlapi_bmac_read_shm(pi->sh->physhim, + M_PWRIND_MAP(idx + 1)); + cmplx_pwr[core] = (hi << 16) + lo; + cmplx_pwr_tot += cmplx_pwr[core]; + if (cmplx_pwr[core] == 0) { + noise_dbm_ant[core] = PHY_NOISE_FIXED_VAL_NPHY; + } else + cmplx_pwr[core] >>= PHY_NOISE_SAMPLE_LOG_NUM_UCODE; + } + + if (cmplx_pwr_tot != 0) + wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant); + + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + pi->nphy_noise_win[core][pi->nphy_noise_index] = + noise_dbm_ant[core]; + + if (noise_dbm_ant[core] > noise_dbm) + noise_dbm = noise_dbm_ant[core]; + } + pi->nphy_noise_index = + MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ); + + return noise_dbm; + +} + +void wlc_phy_noise_sample_intr(wlc_phy_t *pih) +{ + phy_info_t *pi = (phy_info_t *) pih; + u16 jssi_aux; + u8 channel = 0; + s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; + + if (ISLCNPHY(pi)) { + u32 cmplx_pwr, cmplx_pwr0, cmplx_pwr1; + u16 lo, hi; + s32 pwr_offset_dB, gain_dB; + u16 status_0, status_1; + + jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX); + channel = jssi_aux & D11_CURCHANNEL_MAX; + + lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP0); + hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP1); + cmplx_pwr0 = (hi << 16) + lo; + + lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP2); + hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP3); + cmplx_pwr1 = (hi << 16) + lo; + cmplx_pwr = (cmplx_pwr0 + cmplx_pwr1) >> 6; + + status_0 = 0x44; + status_1 = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_0); + if ((cmplx_pwr > 0 && cmplx_pwr < 500) + && ((status_1 & 0xc000) == 0x4000)) { + + wlc_phy_compute_dB(&cmplx_pwr, &noise_dbm, + pi->pubpi.phy_corenum); + pwr_offset_dB = (read_phy_reg(pi, 0x434) & 0xFF); + if (pwr_offset_dB > 127) + pwr_offset_dB -= 256; + + noise_dbm += (s8) (pwr_offset_dB - 30); + + gain_dB = (status_0 & 0x1ff); + noise_dbm -= (s8) (gain_dB); + } else { + noise_dbm = PHY_NOISE_FIXED_VAL_LCNPHY; + } + } else if (ISNPHY(pi)) { + + jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX); + channel = jssi_aux & D11_CURCHANNEL_MAX; + + noise_dbm = wlc_phy_noise_read_shmem(pi); + } else { + ASSERT(0); + } + + wlc_phy_noise_cb(pi, channel, noise_dbm); + +} + +s8 lcnphy_gain_index_offset_for_pkt_rssi[] = { + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 9, + 10, + 8, + 8, + 7, + 7, + 1, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 1, + 1, + 0, + 0, + 0, + 0 +}; + +void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_cmplx_pwr_dB, u8 core) +{ + u8 shift_ct, lsb, msb, secondmsb, i; + u32 tmp; + + for (i = 0; i < core; i++) { + tmp = cmplx_pwr[i]; + shift_ct = msb = secondmsb = 0; + while (tmp != 0) { + tmp = tmp >> 1; + shift_ct++; + lsb = (u8) (tmp & 1); + if (lsb == 1) + msb = shift_ct; + } + secondmsb = (u8) ((cmplx_pwr[i] >> (msb - 1)) & 1); + p_cmplx_pwr_dB[i] = (s8) (3 * msb + 2 * secondmsb); + } +} + +void BCMFASTPATH wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx) +{ + wlc_d11rxhdr_t *wlc_rxhdr = (wlc_d11rxhdr_t *) ctx; + d11rxhdr_t *rxh = &wlc_rxhdr->rxhdr; + int rssi = ltoh16(rxh->PhyRxStatus_1) & PRXS1_JSSI_MASK; + uint radioid = pih->radioid; + phy_info_t *pi = (phy_info_t *) pih; + + if (NORADIO_ENAB(pi->pubpi)) { + rssi = WLC_RSSI_INVALID; + goto end; + } + + if ((pi->sh->corerev >= 11) + && !(ltoh16(rxh->RxStatus2) & RXS_PHYRXST_VALID)) { + rssi = WLC_RSSI_INVALID; + goto end; + } + + if (ISLCNPHY(pi)) { + u8 gidx = (ltoh16(rxh->PhyRxStatus_2) & 0xFC00) >> 10; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + if (rssi > 127) + rssi -= 256; + + rssi = rssi + lcnphy_gain_index_offset_for_pkt_rssi[gidx]; + if ((rssi > -46) && (gidx > 18)) + rssi = rssi + 7; + + rssi = rssi + pi_lcn->lcnphy_pkteng_rssi_slope; + + rssi = rssi + 2; + + } + + if (ISLCNPHY(pi)) { + + if (rssi > 127) + rssi -= 256; + } else if (radioid == BCM2055_ID || radioid == BCM2056_ID + || radioid == BCM2057_ID) { + ASSERT(ISNPHY(pi)); + rssi = wlc_phy_rssi_compute_nphy(pi, wlc_rxhdr); + } else { + ASSERT((const char *)"Unknown radio" == NULL); + } + + end: + wlc_rxhdr->rssi = (s8) rssi; +} + +void wlc_phy_freqtrack_start(wlc_phy_t *pih) +{ + return; +} + +void wlc_phy_freqtrack_end(wlc_phy_t *pih) +{ + return; +} + +void wlc_phy_set_deaf(wlc_phy_t *ppi, bool user_flag) +{ + phy_info_t *pi; + pi = (phy_info_t *) ppi; + + if (ISLCNPHY(pi)) + wlc_lcnphy_deaf_mode(pi, true); + else if (ISNPHY(pi)) + wlc_nphy_deaf_mode(pi, true); + else { + ASSERT(0); + } +} + +void wlc_phy_watchdog(wlc_phy_t *pih) +{ + phy_info_t *pi = (phy_info_t *) pih; + bool delay_phy_cal = false; + pi->sh->now++; + + if (!pi->watchdog_override) + return; + + if (!(SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi))) { + wlc_phy_noise_sample_request((wlc_phy_t *) pi, + PHY_NOISE_SAMPLE_MON, + CHSPEC_CHANNEL(pi-> + radio_chanspec)); + } + + if (pi->phynoise_state && (pi->sh->now - pi->phynoise_now) > 5) { + pi->phynoise_state = 0; + } + + if ((!pi->phycal_txpower) || + ((pi->sh->now - pi->phycal_txpower) >= pi->sh->fast_timer)) { + + if (!SCAN_INPROG_PHY(pi) && wlc_phy_cal_txpower_recalc_sw(pi)) { + pi->phycal_txpower = pi->sh->now; + } + } + + if (NORADIO_ENAB(pi->pubpi)) + return; + + if ((SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi) + || ASSOC_INPROG_PHY(pi))) + return; + + if (ISNPHY(pi) && !pi->disable_percal && !delay_phy_cal) { + + if ((pi->nphy_perical != PHY_PERICAL_DISABLE) && + (pi->nphy_perical != PHY_PERICAL_MANUAL) && + ((pi->sh->now - pi->nphy_perical_last) >= + pi->sh->glacial_timer)) + wlc_phy_cal_perical((wlc_phy_t *) pi, + PHY_PERICAL_WATCHDOG); + + wlc_phy_txpwr_papd_cal_nphy(pi); + } + + if (ISLCNPHY(pi)) { + if (pi->phy_forcecal || + ((pi->sh->now - pi->phy_lastcal) >= + pi->sh->glacial_timer)) { + if (!(SCAN_RM_IN_PROGRESS(pi) || ASSOC_INPROG_PHY(pi))) + wlc_lcnphy_calib_modes(pi, + LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL); + if (! + (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi) + || ASSOC_INPROG_PHY(pi) + || pi->carrier_suppr_disable + || pi->disable_percal)) + wlc_lcnphy_calib_modes(pi, + PHY_PERICAL_WATCHDOG); + } + } +} + +void wlc_phy_BSSinit(wlc_phy_t *pih, bool bonlyap, int rssi) +{ + phy_info_t *pi = (phy_info_t *) pih; + uint i; + uint k; + + for (i = 0; i < MA_WINDOW_SZ; i++) { + pi->sh->phy_noise_window[i] = (s8) (rssi & 0xff); + } + if (ISLCNPHY(pi)) { + for (i = 0; i < MA_WINDOW_SZ; i++) + pi->sh->phy_noise_window[i] = + PHY_NOISE_FIXED_VAL_LCNPHY; + } + pi->sh->phy_noise_index = 0; + + for (i = 0; i < PHY_NOISE_WINDOW_SZ; i++) { + for (k = WL_ANT_IDX_1; k < WL_ANT_RX_MAX; k++) + pi->nphy_noise_win[k][i] = PHY_NOISE_FIXED_VAL_NPHY; + } + pi->nphy_noise_index = 0; +} + +void +wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, s32 *eps_imag) +{ + *eps_imag = (epsilon >> 13); + if (*eps_imag > 0xfff) + *eps_imag -= 0x2000; + + *eps_real = (epsilon & 0x1fff); + if (*eps_real > 0xfff) + *eps_real -= 0x2000; +} + +static const fixed AtanTbl[] = { + 2949120, + 1740967, + 919879, + 466945, + 234379, + 117304, + 58666, + 29335, + 14668, + 7334, + 3667, + 1833, + 917, + 458, + 229, + 115, + 57, + 29 +}; + +void wlc_phy_cordic(fixed theta, cs32 *val) +{ + fixed angle, valtmp; + unsigned iter; + int signx = 1; + int signtheta; + + val[0].i = CORDIC_AG; + val[0].q = 0; + angle = 0; + + signtheta = (theta < 0) ? -1 : 1; + theta = + ((theta + FIXED(180) * signtheta) % FIXED(360)) - + FIXED(180) * signtheta; + + if (FLOAT(theta) > 90) { + theta -= FIXED(180); + signx = -1; + } else if (FLOAT(theta) < -90) { + theta += FIXED(180); + signx = -1; + } + + for (iter = 0; iter < CORDIC_NI; iter++) { + if (theta > angle) { + valtmp = val[0].i - (val[0].q >> iter); + val[0].q = (val[0].i >> iter) + val[0].q; + val[0].i = valtmp; + angle += AtanTbl[iter]; + } else { + valtmp = val[0].i + (val[0].q >> iter); + val[0].q = -(val[0].i >> iter) + val[0].q; + val[0].i = valtmp; + angle -= AtanTbl[iter]; + } + } + + val[0].i = val[0].i * signx; + val[0].q = val[0].q * signx; +} + +void wlc_phy_cal_perical_mphase_reset(phy_info_t *pi) +{ + wlapi_del_timer(pi->sh->physhim, pi->phycal_timer); + + pi->cal_type_override = PHY_PERICAL_AUTO; + pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE; + pi->mphase_txcal_cmdidx = 0; +} + +static void wlc_phy_cal_perical_mphase_schedule(phy_info_t *pi, uint delay) +{ + + if ((pi->nphy_perical != PHY_PERICAL_MPHASE) && + (pi->nphy_perical != PHY_PERICAL_MANUAL)) + return; + + wlapi_del_timer(pi->sh->physhim, pi->phycal_timer); + + pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT; + wlapi_add_timer(pi->sh->physhim, pi->phycal_timer, delay, 0); +} + +void wlc_phy_cal_perical(wlc_phy_t *pih, u8 reason) +{ + s16 nphy_currtemp = 0; + s16 delta_temp = 0; + bool do_periodic_cal = true; + phy_info_t *pi = (phy_info_t *) pih; + + if (!ISNPHY(pi)) + return; + + if ((pi->nphy_perical == PHY_PERICAL_DISABLE) || + (pi->nphy_perical == PHY_PERICAL_MANUAL)) + return; + + switch (reason) { + case PHY_PERICAL_DRIVERUP: + break; + + case PHY_PERICAL_PHYINIT: + if (pi->nphy_perical == PHY_PERICAL_MPHASE) { + if (PHY_PERICAL_MPHASE_PENDING(pi)) { + wlc_phy_cal_perical_mphase_reset(pi); + } + wlc_phy_cal_perical_mphase_schedule(pi, + PHY_PERICAL_INIT_DELAY); + } + break; + + case PHY_PERICAL_JOIN_BSS: + case PHY_PERICAL_START_IBSS: + case PHY_PERICAL_UP_BSS: + if ((pi->nphy_perical == PHY_PERICAL_MPHASE) && + PHY_PERICAL_MPHASE_PENDING(pi)) { + wlc_phy_cal_perical_mphase_reset(pi); + } + + pi->first_cal_after_assoc = true; + + pi->cal_type_override = PHY_PERICAL_FULL; + + if (pi->phycal_tempdelta) { + pi->nphy_lastcal_temp = wlc_phy_tempsense_nphy(pi); + } + wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_FULL); + break; + + case PHY_PERICAL_WATCHDOG: + if (pi->phycal_tempdelta) { + nphy_currtemp = wlc_phy_tempsense_nphy(pi); + delta_temp = + (nphy_currtemp > pi->nphy_lastcal_temp) ? + nphy_currtemp - pi->nphy_lastcal_temp : + pi->nphy_lastcal_temp - nphy_currtemp; + + if ((delta_temp < (s16) pi->phycal_tempdelta) && + (pi->nphy_txiqlocal_chanspec == + pi->radio_chanspec)) { + do_periodic_cal = false; + } else { + pi->nphy_lastcal_temp = nphy_currtemp; + } + } + + if (do_periodic_cal) { + + if (pi->nphy_perical == PHY_PERICAL_MPHASE) { + + if (!PHY_PERICAL_MPHASE_PENDING(pi)) + wlc_phy_cal_perical_mphase_schedule(pi, + PHY_PERICAL_WDOG_DELAY); + } else if (pi->nphy_perical == PHY_PERICAL_SPHASE) + wlc_phy_cal_perical_nphy_run(pi, + PHY_PERICAL_AUTO); + else { + ASSERT(0); + } + } + break; + default: + ASSERT(0); + break; + } +} + +void wlc_phy_cal_perical_mphase_restart(phy_info_t *pi) +{ + pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT; + pi->mphase_txcal_cmdidx = 0; +} + +u8 wlc_phy_nbits(s32 value) +{ + s32 abs_val; + u8 nbits = 0; + + abs_val = ABS(value); + while ((abs_val >> nbits) > 0) + nbits++; + + return nbits; +} + +u32 wlc_phy_sqrt_int(u32 value) +{ + u32 root = 0, shift = 0; + + for (shift = 0; shift < 32; shift += 2) { + if (((0x40000000 >> shift) + root) <= value) { + value -= ((0x40000000 >> shift) + root); + root = (root >> 1) | (0x40000000 >> shift); + } else { + root = root >> 1; + } + } + + if (root < value) + ++root; + + return root; +} + +void wlc_phy_stf_chain_init(wlc_phy_t *pih, u8 txchain, u8 rxchain) +{ + phy_info_t *pi = (phy_info_t *) pih; + + pi->sh->hw_phytxchain = txchain; + pi->sh->hw_phyrxchain = rxchain; + pi->sh->phytxchain = txchain; + pi->sh->phyrxchain = rxchain; + pi->pubpi.phy_corenum = (u8) PHY_BITSCNT(pi->sh->phyrxchain); +} + +void wlc_phy_stf_chain_set(wlc_phy_t *pih, u8 txchain, u8 rxchain) +{ + phy_info_t *pi = (phy_info_t *) pih; + + pi->sh->phytxchain = txchain; + + if (ISNPHY(pi)) { + wlc_phy_rxcore_setstate_nphy(pih, rxchain); + } + pi->pubpi.phy_corenum = (u8) PHY_BITSCNT(pi->sh->phyrxchain); +} + +void wlc_phy_stf_chain_get(wlc_phy_t *pih, u8 *txchain, u8 *rxchain) +{ + phy_info_t *pi = (phy_info_t *) pih; + + *txchain = pi->sh->phytxchain; + *rxchain = pi->sh->phyrxchain; +} + +u8 wlc_phy_stf_chain_active_get(wlc_phy_t *pih) +{ + s16 nphy_currtemp; + u8 active_bitmap; + phy_info_t *pi = (phy_info_t *) pih; + + active_bitmap = (pi->phy_txcore_heatedup) ? 0x31 : 0x33; + + if (!pi->watchdog_override) + return active_bitmap; + + if (NREV_GE(pi->pubpi.phy_rev, 6)) { + wlapi_suspend_mac_and_wait(pi->sh->physhim); + nphy_currtemp = wlc_phy_tempsense_nphy(pi); + wlapi_enable_mac(pi->sh->physhim); + + if (!pi->phy_txcore_heatedup) { + if (nphy_currtemp >= pi->phy_txcore_disable_temp) { + active_bitmap &= 0xFD; + pi->phy_txcore_heatedup = true; + } + } else { + if (nphy_currtemp <= pi->phy_txcore_enable_temp) { + active_bitmap |= 0x2; + pi->phy_txcore_heatedup = false; + } + } + } + + return active_bitmap; +} + +s8 wlc_phy_stf_ssmode_get(wlc_phy_t *pih, chanspec_t chanspec) +{ + phy_info_t *pi = (phy_info_t *) pih; + u8 siso_mcs_id, cdd_mcs_id; + + siso_mcs_id = + (CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_SISO : + TXP_FIRST_MCS_20_SISO; + cdd_mcs_id = + (CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_CDD : + TXP_FIRST_MCS_20_CDD; + + if (pi->tx_power_target[siso_mcs_id] > + (pi->tx_power_target[cdd_mcs_id] + 12)) + return PHY_TXC1_MODE_SISO; + else + return PHY_TXC1_MODE_CDD; +} + +const u8 *wlc_phy_get_ofdm_rate_lookup(void) +{ + return ofdm_rate_lookup; +} + +void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode) +{ + if ((pi->sh->chip == BCM4313_CHIP_ID) && + (pi->sh->boardflags & BFL_FEM)) { + if (mode) { + u16 txant = 0; + txant = wlapi_bmac_get_txant(pi->sh->physhim); + if (txant == 1) { + mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2); + + mod_phy_reg(pi, 0x44c, (0x1 << 2), (1) << 2); + + } + si_corereg(pi->sh->sih, SI_CC_IDX, + offsetof(chipcregs_t, gpiocontrol), ~0x0, + 0x0); + si_corereg(pi->sh->sih, SI_CC_IDX, + offsetof(chipcregs_t, gpioout), 0x40, 0x40); + si_corereg(pi->sh->sih, SI_CC_IDX, + offsetof(chipcregs_t, gpioouten), 0x40, + 0x40); + } else { + mod_phy_reg(pi, 0x44c, (0x1 << 2), (0) << 2); + + mod_phy_reg(pi, 0x44d, (0x1 << 2), (0) << 2); + + si_corereg(pi->sh->sih, SI_CC_IDX, + offsetof(chipcregs_t, gpioout), 0x40, 0x00); + si_corereg(pi->sh->sih, SI_CC_IDX, + offsetof(chipcregs_t, gpioouten), 0x40, 0x0); + si_corereg(pi->sh->sih, SI_CC_IDX, + offsetof(chipcregs_t, gpiocontrol), ~0x0, + 0x40); + } + } +} + +static s8 +wlc_user_txpwr_antport_to_rfport(phy_info_t *pi, uint chan, u32 band, + u8 rate) +{ + s8 offset = 0; + + if (!pi->user_txpwr_at_rfport) + return offset; + return offset; +} + +static s8 wlc_phy_env_measure_vbat(phy_info_t *pi) +{ + if (ISLCNPHY(pi)) + return wlc_lcnphy_vbatsense(pi, 0); + else + return 0; +} + +static s8 wlc_phy_env_measure_temperature(phy_info_t *pi) +{ + if (ISLCNPHY(pi)) + return wlc_lcnphy_tempsense_degree(pi, 0); + else + return 0; +} + +static void wlc_phy_upd_env_txpwr_rate_limits(phy_info_t *pi, u32 band) +{ + u8 i; + s8 temp, vbat; + + for (i = 0; i < TXP_NUM_RATES; i++) + pi->txpwr_env_limit[i] = WLC_TXPWR_MAX; + + vbat = wlc_phy_env_measure_vbat(pi); + temp = wlc_phy_env_measure_temperature(pi); + +} + +void wlc_phy_ldpc_override_set(wlc_phy_t *ppi, bool ldpc) +{ + return; +} + +void +wlc_phy_get_pwrdet_offsets(phy_info_t *pi, s8 *cckoffset, s8 *ofdmoffset) +{ + *cckoffset = 0; + *ofdmoffset = 0; +} + +u32 wlc_phy_qdiv_roundup(u32 dividend, u32 divisor, u8 precision) +{ + u32 quotient, remainder, roundup, rbit; + + ASSERT(divisor); + + quotient = dividend / divisor; + remainder = dividend % divisor; + rbit = divisor & 1; + roundup = (divisor >> 1) + rbit; + + while (precision--) { + quotient <<= 1; + if (remainder >= roundup) { + quotient++; + remainder = ((remainder - roundup) << 1) + rbit; + } else { + remainder <<= 1; + } + } + + if (remainder >= roundup) + quotient++; + + return quotient; +} + +s8 wlc_phy_upd_rssi_offset(phy_info_t *pi, s8 rssi, chanspec_t chanspec) +{ + + return rssi; +} + +bool wlc_phy_txpower_ipa_ison(wlc_phy_t *ppi) +{ + phy_info_t *pi = (phy_info_t *) ppi; + + if (ISNPHY(pi)) + return wlc_phy_n_txpower_ipa_ison(pi); + else + return 0; +} diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h new file mode 100644 index 000000000000..514e15e00283 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_phy_h_ +#define _wlc_phy_h_ + +#include +#include +#include +#include + +#define IDCODE_VER_MASK 0x0000000f +#define IDCODE_VER_SHIFT 0 +#define IDCODE_MFG_MASK 0x00000fff +#define IDCODE_MFG_SHIFT 0 +#define IDCODE_ID_MASK 0x0ffff000 +#define IDCODE_ID_SHIFT 12 +#define IDCODE_REV_MASK 0xf0000000 +#define IDCODE_REV_SHIFT 28 + +#define NORADIO_ID 0xe4f5 +#define NORADIO_IDCODE 0x4e4f5246 + +#define BCM2055_ID 0x2055 +#define BCM2055_IDCODE 0x02055000 +#define BCM2055A0_IDCODE 0x1205517f + +#define BCM2056_ID 0x2056 +#define BCM2056_IDCODE 0x02056000 +#define BCM2056A0_IDCODE 0x1205617f + +#define BCM2057_ID 0x2057 +#define BCM2057_IDCODE 0x02057000 +#define BCM2057A0_IDCODE 0x1205717f + +#define BCM2064_ID 0x2064 +#define BCM2064_IDCODE 0x02064000 +#define BCM2064A0_IDCODE 0x0206417f + +#define PHY_TPC_HW_OFF false +#define PHY_TPC_HW_ON true + +#define PHY_PERICAL_DRIVERUP 1 +#define PHY_PERICAL_WATCHDOG 2 +#define PHY_PERICAL_PHYINIT 3 +#define PHY_PERICAL_JOIN_BSS 4 +#define PHY_PERICAL_START_IBSS 5 +#define PHY_PERICAL_UP_BSS 6 +#define PHY_PERICAL_CHAN 7 +#define PHY_FULLCAL 8 + +#define PHY_PERICAL_DISABLE 0 +#define PHY_PERICAL_SPHASE 1 +#define PHY_PERICAL_MPHASE 2 +#define PHY_PERICAL_MANUAL 3 + +#define PHY_HOLD_FOR_ASSOC 1 +#define PHY_HOLD_FOR_SCAN 2 +#define PHY_HOLD_FOR_RM 4 +#define PHY_HOLD_FOR_PLT 8 +#define PHY_HOLD_FOR_MUTE 16 +#define PHY_HOLD_FOR_NOT_ASSOC 0x20 + +#define PHY_MUTE_FOR_PREISM 1 +#define PHY_MUTE_ALL 0xffffffff + +#define PHY_NOISE_FIXED_VAL (-95) +#define PHY_NOISE_FIXED_VAL_NPHY (-92) +#define PHY_NOISE_FIXED_VAL_LCNPHY (-92) + +#define PHY_MODE_CAL 0x0002 +#define PHY_MODE_NOISEM 0x0004 + +#define WLC_TXPWR_DB_FACTOR 4 + +#define WLC_NUM_RATES_CCK 4 +#define WLC_NUM_RATES_OFDM 8 +#define WLC_NUM_RATES_MCS_1_STREAM 8 +#define WLC_NUM_RATES_MCS_2_STREAM 8 +#define WLC_NUM_RATES_MCS_3_STREAM 8 +#define WLC_NUM_RATES_MCS_4_STREAM 8 +typedef struct txpwr_limits { + u8 cck[WLC_NUM_RATES_CCK]; + u8 ofdm[WLC_NUM_RATES_OFDM]; + + u8 ofdm_cdd[WLC_NUM_RATES_OFDM]; + + u8 ofdm_40_siso[WLC_NUM_RATES_OFDM]; + u8 ofdm_40_cdd[WLC_NUM_RATES_OFDM]; + + u8 mcs_20_siso[WLC_NUM_RATES_MCS_1_STREAM]; + u8 mcs_20_cdd[WLC_NUM_RATES_MCS_1_STREAM]; + u8 mcs_20_stbc[WLC_NUM_RATES_MCS_1_STREAM]; + u8 mcs_20_mimo[WLC_NUM_RATES_MCS_2_STREAM]; + + u8 mcs_40_siso[WLC_NUM_RATES_MCS_1_STREAM]; + u8 mcs_40_cdd[WLC_NUM_RATES_MCS_1_STREAM]; + u8 mcs_40_stbc[WLC_NUM_RATES_MCS_1_STREAM]; + u8 mcs_40_mimo[WLC_NUM_RATES_MCS_2_STREAM]; + u8 mcs32; +} txpwr_limits_t; + +typedef struct { + u8 vec[MAXCHANNEL / NBBY]; +} chanvec_t; + +struct rpc_info; +typedef struct shared_phy shared_phy_t; + +struct phy_pub; + +typedef struct phy_pub wlc_phy_t; + +typedef struct shared_phy_params { + void *osh; + si_t *sih; + void *physhim; + uint unit; + uint corerev; + uint bustype; + uint buscorerev; + char *vars; + u16 vid; + u16 did; + uint chip; + uint chiprev; + uint chippkg; + uint sromrev; + uint boardtype; + uint boardrev; + uint boardvendor; + u32 boardflags; + u32 boardflags2; +} shared_phy_params_t; + + +extern shared_phy_t *wlc_phy_shared_attach(shared_phy_params_t *shp); +extern void wlc_phy_shared_detach(shared_phy_t *phy_sh); +extern wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, + char *vars); +extern void wlc_phy_detach(wlc_phy_t *ppi); + +extern bool wlc_phy_get_phyversion(wlc_phy_t *pih, u16 *phytype, + u16 *phyrev, u16 *radioid, + u16 *radiover); +extern bool wlc_phy_get_encore(wlc_phy_t *pih); +extern u32 wlc_phy_get_coreflags(wlc_phy_t *pih); + +extern void wlc_phy_hw_clk_state_upd(wlc_phy_t *ppi, bool newstate); +extern void wlc_phy_hw_state_upd(wlc_phy_t *ppi, bool newstate); +extern void wlc_phy_init(wlc_phy_t *ppi, chanspec_t chanspec); +extern void wlc_phy_watchdog(wlc_phy_t *ppi); +extern int wlc_phy_down(wlc_phy_t *ppi); +extern u32 wlc_phy_clk_bwbits(wlc_phy_t *pih); +extern void wlc_phy_cal_init(wlc_phy_t *ppi); +extern void wlc_phy_antsel_init(wlc_phy_t *ppi, bool lut_init); + +extern void wlc_phy_chanspec_set(wlc_phy_t *ppi, chanspec_t chanspec); +extern chanspec_t wlc_phy_chanspec_get(wlc_phy_t *ppi); +extern void wlc_phy_chanspec_radio_set(wlc_phy_t *ppi, chanspec_t newch); +extern u16 wlc_phy_bw_state_get(wlc_phy_t *ppi); +extern void wlc_phy_bw_state_set(wlc_phy_t *ppi, u16 bw); + +extern void wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx); +extern void wlc_phy_por_inform(wlc_phy_t *ppi); +extern void wlc_phy_noise_sample_intr(wlc_phy_t *ppi); +extern bool wlc_phy_bist_check_phy(wlc_phy_t *ppi); + +extern void wlc_phy_set_deaf(wlc_phy_t *ppi, bool user_flag); + +extern void wlc_phy_switch_radio(wlc_phy_t *ppi, bool on); +extern void wlc_phy_anacore(wlc_phy_t *ppi, bool on); + + +extern void wlc_phy_BSSinit(wlc_phy_t *ppi, bool bonlyap, int rssi); + +extern void wlc_phy_chanspec_ch14_widefilter_set(wlc_phy_t *ppi, + bool wide_filter); +extern void wlc_phy_chanspec_band_validch(wlc_phy_t *ppi, uint band, + chanvec_t *channels); +extern chanspec_t wlc_phy_chanspec_band_firstch(wlc_phy_t *ppi, uint band); + +extern void wlc_phy_txpower_sromlimit(wlc_phy_t *ppi, uint chan, + u8 *_min_, u8 *_max_, int rate); +extern void wlc_phy_txpower_sromlimit_max_get(wlc_phy_t *ppi, uint chan, + u8 *_max_, u8 *_min_); +extern void wlc_phy_txpower_boardlimit_band(wlc_phy_t *ppi, uint band, s32 *, + s32 *, u32 *); +extern void wlc_phy_txpower_limit_set(wlc_phy_t *ppi, struct txpwr_limits *, + chanspec_t chanspec); +extern int wlc_phy_txpower_get(wlc_phy_t *ppi, uint *qdbm, bool *override); +extern int wlc_phy_txpower_set(wlc_phy_t *ppi, uint qdbm, bool override); +extern void wlc_phy_txpower_target_set(wlc_phy_t *ppi, struct txpwr_limits *); +extern bool wlc_phy_txpower_hw_ctrl_get(wlc_phy_t *ppi); +extern void wlc_phy_txpower_hw_ctrl_set(wlc_phy_t *ppi, bool hwpwrctrl); +extern u8 wlc_phy_txpower_get_target_min(wlc_phy_t *ppi); +extern u8 wlc_phy_txpower_get_target_max(wlc_phy_t *ppi); +extern bool wlc_phy_txpower_ipa_ison(wlc_phy_t *pih); + +extern void wlc_phy_stf_chain_init(wlc_phy_t *pih, u8 txchain, + u8 rxchain); +extern void wlc_phy_stf_chain_set(wlc_phy_t *pih, u8 txchain, + u8 rxchain); +extern void wlc_phy_stf_chain_get(wlc_phy_t *pih, u8 *txchain, + u8 *rxchain); +extern u8 wlc_phy_stf_chain_active_get(wlc_phy_t *pih); +extern s8 wlc_phy_stf_ssmode_get(wlc_phy_t *pih, chanspec_t chanspec); +extern void wlc_phy_ldpc_override_set(wlc_phy_t *ppi, bool val); + +extern void wlc_phy_cal_perical(wlc_phy_t *ppi, u8 reason); +extern void wlc_phy_noise_sample_request_external(wlc_phy_t *ppi); +extern void wlc_phy_edcrs_lock(wlc_phy_t *pih, bool lock); +extern void wlc_phy_cal_papd_recal(wlc_phy_t *ppi); + +extern void wlc_phy_ant_rxdiv_set(wlc_phy_t *ppi, u8 val); +extern bool wlc_phy_ant_rxdiv_get(wlc_phy_t *ppi, u8 *pval); +extern void wlc_phy_clear_tssi(wlc_phy_t *ppi); +extern void wlc_phy_hold_upd(wlc_phy_t *ppi, mbool id, bool val); +extern void wlc_phy_mute_upd(wlc_phy_t *ppi, bool val, mbool flags); + +extern void wlc_phy_antsel_type_set(wlc_phy_t *ppi, u8 antsel_type); + +extern void wlc_phy_txpower_get_current(wlc_phy_t *ppi, tx_power_t *power, + uint channel); + +extern void wlc_phy_initcal_enable(wlc_phy_t *pih, bool initcal); +extern bool wlc_phy_test_ison(wlc_phy_t *ppi); +extern void wlc_phy_txpwr_percent_set(wlc_phy_t *ppi, u8 txpwr_percent); +extern void wlc_phy_ofdm_rateset_war(wlc_phy_t *pih, bool war); +extern void wlc_phy_bf_preempt_enable(wlc_phy_t *pih, bool bf_preempt); +extern void wlc_phy_machwcap_set(wlc_phy_t *ppi, u32 machwcap); + +extern void wlc_phy_runbist_config(wlc_phy_t *ppi, bool start_end); + +extern void wlc_phy_freqtrack_start(wlc_phy_t *ppi); +extern void wlc_phy_freqtrack_end(wlc_phy_t *ppi); + +extern const u8 *wlc_phy_get_ofdm_rate_lookup(void); + +extern s8 wlc_phy_get_tx_power_offset_by_mcs(wlc_phy_t *ppi, + u8 mcs_offset); +extern s8 wlc_phy_get_tx_power_offset(wlc_phy_t *ppi, u8 tbl_offset); +#endif /* _wlc_phy_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h new file mode 100644 index 000000000000..72eee9120c2f --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h @@ -0,0 +1,1229 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_phy_int_h_ +#define _wlc_phy_int_h_ + +#include +#include +#include + +#include +#include + +#define PHYHAL_ERROR 0x0001 +#define PHYHAL_TRACE 0x0002 +#define PHYHAL_INFORM 0x0004 + +extern u32 phyhal_msg_level; + +#define PHY_INFORM_ON() (phyhal_msg_level & PHYHAL_INFORM) +#define PHY_THERMAL_ON() (phyhal_msg_level & PHYHAL_THERMAL) +#define PHY_CAL_ON() (phyhal_msg_level & PHYHAL_CAL) + +#ifdef BOARD_TYPE +#define BOARDTYPE(_type) BOARD_TYPE +#else +#define BOARDTYPE(_type) _type +#endif + +#define LCNXN_BASEREV 16 + +struct wlc_hw_info; +typedef struct phy_info phy_info_t; +typedef void (*initfn_t) (phy_info_t *); +typedef void (*chansetfn_t) (phy_info_t *, chanspec_t); +typedef int (*longtrnfn_t) (phy_info_t *, int); +typedef void (*txiqccgetfn_t) (phy_info_t *, u16 *, u16 *); +typedef void (*txiqccsetfn_t) (phy_info_t *, u16, u16); +typedef u16(*txloccgetfn_t) (phy_info_t *); +typedef void (*radioloftgetfn_t) (phy_info_t *, u8 *, u8 *, u8 *, + u8 *); +typedef s32(*rxsigpwrfn_t) (phy_info_t *, s32); +typedef void (*detachfn_t) (phy_info_t *); + +#undef ISNPHY +#undef ISLCNPHY +#define ISNPHY(pi) PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_N) +#define ISLCNPHY(pi) PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_LCN) + +#define ISPHY_11N_CAP(pi) (ISNPHY(pi) || ISLCNPHY(pi)) + +#define IS20MHZ(pi) ((pi)->bw == WL_CHANSPEC_BW_20) +#define IS40MHZ(pi) ((pi)->bw == WL_CHANSPEC_BW_40) + +#define PHY_GET_RFATTN(rfgain) ((rfgain) & 0x0f) +#define PHY_GET_PADMIX(rfgain) (((rfgain) & 0x10) >> 4) +#define PHY_GET_RFGAINID(rfattn, padmix, width) ((rfattn) + ((padmix)*(width))) +#define PHY_SAT(x, n) ((x) > ((1<<((n)-1))-1) ? ((1<<((n)-1))-1) : \ + ((x) < -(1<<((n)-1)) ? -(1<<((n)-1)) : (x))) +#define PHY_SHIFT_ROUND(x, n) ((x) >= 0 ? ((x)+(1<<((n)-1)))>>(n) : (x)>>(n)) +#define PHY_HW_ROUND(x, s) ((x >> s) + ((x >> (s-1)) & (s != 0))) + +#define CH_5G_GROUP 3 +#define A_LOW_CHANS 0 +#define A_MID_CHANS 1 +#define A_HIGH_CHANS 2 +#define CH_2G_GROUP 1 +#define G_ALL_CHANS 0 + +#define FIRST_REF5_CHANNUM 149 +#define LAST_REF5_CHANNUM 165 +#define FIRST_5G_CHAN 14 +#define LAST_5G_CHAN 50 +#define FIRST_MID_5G_CHAN 14 +#define LAST_MID_5G_CHAN 35 +#define FIRST_HIGH_5G_CHAN 36 +#define LAST_HIGH_5G_CHAN 41 +#define FIRST_LOW_5G_CHAN 42 +#define LAST_LOW_5G_CHAN 50 + +#define BASE_LOW_5G_CHAN 4900 +#define BASE_MID_5G_CHAN 5100 +#define BASE_HIGH_5G_CHAN 5500 + +#define CHAN5G_FREQ(chan) (5000 + chan*5) +#define CHAN2G_FREQ(chan) (2407 + chan*5) + +#define TXP_FIRST_CCK 0 +#define TXP_LAST_CCK 3 +#define TXP_FIRST_OFDM 4 +#define TXP_LAST_OFDM 11 +#define TXP_FIRST_OFDM_20_CDD 12 +#define TXP_LAST_OFDM_20_CDD 19 +#define TXP_FIRST_MCS_20_SISO 20 +#define TXP_LAST_MCS_20_SISO 27 +#define TXP_FIRST_MCS_20_CDD 28 +#define TXP_LAST_MCS_20_CDD 35 +#define TXP_FIRST_MCS_20_STBC 36 +#define TXP_LAST_MCS_20_STBC 43 +#define TXP_FIRST_MCS_20_SDM 44 +#define TXP_LAST_MCS_20_SDM 51 +#define TXP_FIRST_OFDM_40_SISO 52 +#define TXP_LAST_OFDM_40_SISO 59 +#define TXP_FIRST_OFDM_40_CDD 60 +#define TXP_LAST_OFDM_40_CDD 67 +#define TXP_FIRST_MCS_40_SISO 68 +#define TXP_LAST_MCS_40_SISO 75 +#define TXP_FIRST_MCS_40_CDD 76 +#define TXP_LAST_MCS_40_CDD 83 +#define TXP_FIRST_MCS_40_STBC 84 +#define TXP_LAST_MCS_40_STBC 91 +#define TXP_FIRST_MCS_40_SDM 92 +#define TXP_LAST_MCS_40_SDM 99 +#define TXP_MCS_32 100 +#define TXP_NUM_RATES 101 +#define ADJ_PWR_TBL_LEN 84 + +#define TXP_FIRST_SISO_MCS_20 20 +#define TXP_LAST_SISO_MCS_20 27 + +#define PHY_CORE_NUM_1 1 +#define PHY_CORE_NUM_2 2 +#define PHY_CORE_NUM_3 3 +#define PHY_CORE_NUM_4 4 +#define PHY_CORE_MAX PHY_CORE_NUM_4 +#define PHY_CORE_0 0 +#define PHY_CORE_1 1 +#define PHY_CORE_2 2 +#define PHY_CORE_3 3 + +#define MA_WINDOW_SZ 8 + +#define PHY_NOISE_SAMPLE_MON 1 +#define PHY_NOISE_SAMPLE_EXTERNAL 2 +#define PHY_NOISE_WINDOW_SZ 16 +#define PHY_NOISE_GLITCH_INIT_MA 10 +#define PHY_NOISE_GLITCH_INIT_MA_BADPlCP 10 +#define PHY_NOISE_STATE_MON 0x1 +#define PHY_NOISE_STATE_EXTERNAL 0x2 +#define PHY_NOISE_SAMPLE_LOG_NUM_NPHY 10 +#define PHY_NOISE_SAMPLE_LOG_NUM_UCODE 9 + +#define PHY_NOISE_OFFSETFACT_4322 (-103) +#define PHY_NOISE_MA_WINDOW_SZ 2 + +#define PHY_RSSI_TABLE_SIZE 64 +#define RSSI_ANT_MERGE_MAX 0 +#define RSSI_ANT_MERGE_MIN 1 +#define RSSI_ANT_MERGE_AVG 2 + +#define PHY_TSSI_TABLE_SIZE 64 +#define APHY_TSSI_TABLE_SIZE 256 +#define TX_GAIN_TABLE_LENGTH 64 +#define DEFAULT_11A_TXP_IDX 24 +#define NUM_TSSI_FRAMES 4 +#define NULL_TSSI 0x7f +#define NULL_TSSI_W 0x7f7f + +#define PHY_PAPD_EPS_TBL_SIZE_LCNPHY 64 + +#define LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL 9 + +#define PHY_TXPWR_MIN 10 +#define PHY_TXPWR_MIN_NPHY 8 +#define RADIOPWR_OVERRIDE_DEF (-1) + +#define PWRTBL_NUM_COEFF 3 + +#define SPURAVOID_DISABLE 0 +#define SPURAVOID_AUTO 1 +#define SPURAVOID_FORCEON 2 +#define SPURAVOID_FORCEON2 3 + +#define PHY_SW_TIMER_FAST 15 +#define PHY_SW_TIMER_SLOW 60 +#define PHY_SW_TIMER_GLACIAL 120 + +#define PHY_PERICAL_AUTO 0 +#define PHY_PERICAL_FULL 1 +#define PHY_PERICAL_PARTIAL 2 + +#define PHY_PERICAL_NODELAY 0 +#define PHY_PERICAL_INIT_DELAY 5 +#define PHY_PERICAL_ASSOC_DELAY 5 +#define PHY_PERICAL_WDOG_DELAY 5 + +#define MPHASE_TXCAL_NUMCMDS 2 +#define PHY_PERICAL_MPHASE_PENDING(pi) (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_IDLE) + +enum { + MPHASE_CAL_STATE_IDLE = 0, + MPHASE_CAL_STATE_INIT = 1, + MPHASE_CAL_STATE_TXPHASE0, + MPHASE_CAL_STATE_TXPHASE1, + MPHASE_CAL_STATE_TXPHASE2, + MPHASE_CAL_STATE_TXPHASE3, + MPHASE_CAL_STATE_TXPHASE4, + MPHASE_CAL_STATE_TXPHASE5, + MPHASE_CAL_STATE_PAPDCAL, + MPHASE_CAL_STATE_RXCAL, + MPHASE_CAL_STATE_RSSICAL, + MPHASE_CAL_STATE_IDLETSSI +}; + +typedef enum { + CAL_FULL, + CAL_RECAL, + CAL_CURRECAL, + CAL_DIGCAL, + CAL_GCTRL, + CAL_SOFT, + CAL_DIGLO +} phy_cal_mode_t; + +#define RDR_NTIERS 1 +#define RDR_TIER_SIZE 64 +#define RDR_LIST_SIZE (512/3) +#define RDR_EPOCH_SIZE 40 +#define RDR_NANTENNAS 2 +#define RDR_NTIER_SIZE RDR_LIST_SIZE +#define RDR_LP_BUFFER_SIZE 64 +#define LP_LEN_HIS_SIZE 10 + +#define STATIC_NUM_RF 32 +#define STATIC_NUM_BB 9 + +#define BB_MULT_MASK 0x0000ffff +#define BB_MULT_VALID_MASK 0x80000000 + +#define CORDIC_AG 39797 +#define CORDIC_NI 18 +#define FIXED(X) ((s32)((X) << 16)) +#define FLOAT(X) (((X) >= 0) ? ((((X) >> 15) + 1) >> 1) : -((((-(X)) >> 15) + 1) >> 1)) + +#define PHY_CHAIN_TX_DISABLE_TEMP 115 +#define PHY_HYSTERESIS_DELTATEMP 5 + +#define PHY_BITSCNT(x) bcm_bitcount((u8 *)&(x), sizeof(u8)) + +#define MOD_PHY_REG(pi, phy_type, reg_name, field, value) \ + mod_phy_reg(pi, phy_type##_##reg_name, phy_type##_##reg_name##_##field##_MASK, \ + (value) << phy_type##_##reg_name##_##field##_##SHIFT); +#define READ_PHY_REG(pi, phy_type, reg_name, field) \ + ((read_phy_reg(pi, phy_type##_##reg_name) & phy_type##_##reg_name##_##field##_##MASK)\ + >> phy_type##_##reg_name##_##field##_##SHIFT) + +#define VALID_PHYTYPE(phytype) (((uint)phytype == PHY_TYPE_N) || \ + ((uint)phytype == PHY_TYPE_LCN)) + +#define VALID_N_RADIO(radioid) ((radioid == BCM2055_ID) || (radioid == BCM2056_ID) || \ + (radioid == BCM2057_ID)) +#define VALID_LCN_RADIO(radioid) (radioid == BCM2064_ID) + +#define VALID_RADIO(pi, radioid) (\ + (ISNPHY(pi) ? VALID_N_RADIO(radioid) : false) || \ + (ISLCNPHY(pi) ? VALID_LCN_RADIO(radioid) : false)) + +#define SCAN_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN)) +#define RM_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_RM)) +#define PLT_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_PLT)) +#define ASSOC_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_ASSOC)) +#define SCAN_RM_IN_PROGRESS(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN | PHY_HOLD_FOR_RM)) +#define PHY_MUTED(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_MUTE)) +#define PUB_NOT_ASSOC(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_NOT_ASSOC)) + +#if defined(EXT_CBALL) +#define NORADIO_ENAB(pub) ((pub).radioid == NORADIO_ID) +#else +#define NORADIO_ENAB(pub) 0 +#endif + +#define PHY_LTRN_LIST_LEN 64 +extern u16 ltrn_list[PHY_LTRN_LIST_LEN]; + +typedef struct _phy_table_info { + uint table; + int q; + uint max; +} phy_table_info_t; + +typedef struct phytbl_info { + const void *tbl_ptr; + u32 tbl_len; + u32 tbl_id; + u32 tbl_offset; + u32 tbl_width; +} phytbl_info_t; + +typedef struct { + u8 curr_home_channel; + u16 crsminpwrthld_40_stored; + u16 crsminpwrthld_20L_stored; + u16 crsminpwrthld_20U_stored; + u16 init_gain_code_core1_stored; + u16 init_gain_code_core2_stored; + u16 init_gain_codeb_core1_stored; + u16 init_gain_codeb_core2_stored; + u16 init_gain_table_stored[4]; + + u16 clip1_hi_gain_code_core1_stored; + u16 clip1_hi_gain_code_core2_stored; + u16 clip1_hi_gain_codeb_core1_stored; + u16 clip1_hi_gain_codeb_core2_stored; + u16 nb_clip_thresh_core1_stored; + u16 nb_clip_thresh_core2_stored; + u16 init_ofdmlna2gainchange_stored[4]; + u16 init_ccklna2gainchange_stored[4]; + u16 clip1_lo_gain_code_core1_stored; + u16 clip1_lo_gain_code_core2_stored; + u16 clip1_lo_gain_codeb_core1_stored; + u16 clip1_lo_gain_codeb_core2_stored; + u16 w1_clip_thresh_core1_stored; + u16 w1_clip_thresh_core2_stored; + u16 radio_2056_core1_rssi_gain_stored; + u16 radio_2056_core2_rssi_gain_stored; + u16 energy_drop_timeout_len_stored; + + u16 ed_crs40_assertthld0_stored; + u16 ed_crs40_assertthld1_stored; + u16 ed_crs40_deassertthld0_stored; + u16 ed_crs40_deassertthld1_stored; + u16 ed_crs20L_assertthld0_stored; + u16 ed_crs20L_assertthld1_stored; + u16 ed_crs20L_deassertthld0_stored; + u16 ed_crs20L_deassertthld1_stored; + u16 ed_crs20U_assertthld0_stored; + u16 ed_crs20U_assertthld1_stored; + u16 ed_crs20U_deassertthld0_stored; + u16 ed_crs20U_deassertthld1_stored; + + u16 badplcp_ma; + u16 badplcp_ma_previous; + u16 badplcp_ma_total; + u16 badplcp_ma_list[MA_WINDOW_SZ]; + int badplcp_ma_index; + s16 pre_badplcp_cnt; + s16 bphy_pre_badplcp_cnt; + + u16 init_gain_core1; + u16 init_gain_core2; + u16 init_gainb_core1; + u16 init_gainb_core2; + u16 init_gain_rfseq[4]; + + u16 crsminpwr0; + u16 crsminpwrl0; + u16 crsminpwru0; + + s16 crsminpwr_index; + + u16 radio_2057_core1_rssi_wb1a_gc_stored; + u16 radio_2057_core2_rssi_wb1a_gc_stored; + u16 radio_2057_core1_rssi_wb1g_gc_stored; + u16 radio_2057_core2_rssi_wb1g_gc_stored; + u16 radio_2057_core1_rssi_wb2_gc_stored; + u16 radio_2057_core2_rssi_wb2_gc_stored; + u16 radio_2057_core1_rssi_nb_gc_stored; + u16 radio_2057_core2_rssi_nb_gc_stored; + +} interference_info_t; + +typedef struct { + u16 rc_cal_ovr; + u16 phycrsth1; + u16 phycrsth2; + u16 init_n1p1_gain; + u16 p1_p2_gain; + u16 n1_n2_gain; + u16 n1_p1_gain; + u16 div_search_gain; + u16 div_p1_p2_gain; + u16 div_search_gn_change; + u16 table_7_2; + u16 table_7_3; + u16 cckshbits_gnref; + u16 clip_thresh; + u16 clip2_thresh; + u16 clip3_thresh; + u16 clip_p2_thresh; + u16 clip_pwdn_thresh; + u16 clip_n1p1_thresh; + u16 clip_n1_pwdn_thresh; + u16 bbconfig; + u16 cthr_sthr_shdin; + u16 energy; + u16 clip_p1_p2_thresh; + u16 threshold; + u16 reg15; + u16 reg16; + u16 reg17; + u16 div_srch_idx; + u16 div_srch_p1_p2; + u16 div_srch_gn_back; + u16 ant_dwell; + u16 ant_wr_settle; +} aci_save_gphy_t; + +typedef struct _lo_complex_t { + s8 i; + s8 q; +} lo_complex_abgphy_info_t; + +typedef struct _nphy_iq_comp { + s16 a0; + s16 b0; + s16 a1; + s16 b1; +} nphy_iq_comp_t; + +typedef struct _nphy_txpwrindex { + s8 index; + s8 index_internal; + s8 index_internal_save; + u16 AfectrlOverride; + u16 AfeCtrlDacGain; + u16 rad_gain; + u8 bbmult; + u16 iqcomp_a; + u16 iqcomp_b; + u16 locomp; +} phy_txpwrindex_t; + +typedef struct { + + u16 txcal_coeffs_2G[8]; + u16 txcal_radio_regs_2G[8]; + nphy_iq_comp_t rxcal_coeffs_2G; + + u16 txcal_coeffs_5G[8]; + u16 txcal_radio_regs_5G[8]; + nphy_iq_comp_t rxcal_coeffs_5G; +} txiqcal_cache_t; + +typedef struct _nphy_pwrctrl { + s8 max_pwr_2g; + s8 idle_targ_2g; + s16 pwrdet_2g_a1; + s16 pwrdet_2g_b0; + s16 pwrdet_2g_b1; + s8 max_pwr_5gm; + s8 idle_targ_5gm; + s8 max_pwr_5gh; + s8 max_pwr_5gl; + s16 pwrdet_5gm_a1; + s16 pwrdet_5gm_b0; + s16 pwrdet_5gm_b1; + s16 pwrdet_5gl_a1; + s16 pwrdet_5gl_b0; + s16 pwrdet_5gl_b1; + s16 pwrdet_5gh_a1; + s16 pwrdet_5gh_b0; + s16 pwrdet_5gh_b1; + s8 idle_targ_5gl; + s8 idle_targ_5gh; + s8 idle_tssi_2g; + s8 idle_tssi_5g; + s8 idle_tssi; + s16 a1; + s16 b0; + s16 b1; +} phy_pwrctrl_t; + +typedef struct _nphy_txgains { + u16 txlpf[2]; + u16 txgm[2]; + u16 pga[2]; + u16 pad[2]; + u16 ipa[2]; +} nphy_txgains_t; + +#define PHY_NOISEVAR_BUFSIZE 10 + +typedef struct _nphy_noisevar_buf { + int bufcount; + int tone_id[PHY_NOISEVAR_BUFSIZE]; + u32 noise_vars[PHY_NOISEVAR_BUFSIZE]; + u32 min_noise_vars[PHY_NOISEVAR_BUFSIZE]; +} phy_noisevar_buf_t; + +typedef struct { + u16 rssical_radio_regs_2G[2]; + u16 rssical_phyregs_2G[12]; + + u16 rssical_radio_regs_5G[2]; + u16 rssical_phyregs_5G[12]; +} rssical_cache_t; + +typedef struct { + + u16 txiqlocal_a; + u16 txiqlocal_b; + u16 txiqlocal_didq; + u8 txiqlocal_ei0; + u8 txiqlocal_eq0; + u8 txiqlocal_fi0; + u8 txiqlocal_fq0; + + u16 txiqlocal_bestcoeffs[11]; + u16 txiqlocal_bestcoeffs_valid; + + u32 papd_eps_tbl[PHY_PAPD_EPS_TBL_SIZE_LCNPHY]; + u16 analog_gain_ref; + u16 lut_begin; + u16 lut_end; + u16 lut_step; + u16 rxcompdbm; + u16 papdctrl; + u16 sslpnCalibClkEnCtrl; + + u16 rxiqcal_coeff_a0; + u16 rxiqcal_coeff_b0; +} lcnphy_cal_results_t; + +struct shared_phy { + struct phy_info *phy_head; + uint unit; + struct osl_info *osh; + si_t *sih; + void *physhim; + uint corerev; + u32 machwcap; + bool up; + bool clk; + uint now; + u16 vid; + u16 did; + uint chip; + uint chiprev; + uint chippkg; + uint sromrev; + uint boardtype; + uint boardrev; + uint boardvendor; + u32 boardflags; + u32 boardflags2; + uint bustype; + uint buscorerev; + uint fast_timer; + uint slow_timer; + uint glacial_timer; + u8 rx_antdiv; + s8 phy_noise_window[MA_WINDOW_SZ]; + uint phy_noise_index; + u8 hw_phytxchain; + u8 hw_phyrxchain; + u8 phytxchain; + u8 phyrxchain; + u8 rssi_mode; + bool _rifs_phy; +}; + +struct phy_pub { + uint phy_type; + uint phy_rev; + u8 phy_corenum; + u16 radioid; + u8 radiorev; + u8 radiover; + + uint coreflags; + uint ana_rev; + bool abgphy_encore; +}; + +struct phy_info_nphy; +typedef struct phy_info_nphy phy_info_nphy_t; + +struct phy_info_lcnphy; +typedef struct phy_info_lcnphy phy_info_lcnphy_t; + +struct phy_func_ptr { + initfn_t init; + initfn_t calinit; + chansetfn_t chanset; + initfn_t txpwrrecalc; + longtrnfn_t longtrn; + txiqccgetfn_t txiqccget; + txiqccsetfn_t txiqccset; + txloccgetfn_t txloccget; + radioloftgetfn_t radioloftget; + initfn_t carrsuppr; + rxsigpwrfn_t rxsigpwr; + detachfn_t detach; +}; +typedef struct phy_func_ptr phy_func_ptr_t; + +struct phy_info { + wlc_phy_t pubpi_ro; + shared_phy_t *sh; + phy_func_ptr_t pi_fptr; + void *pi_ptr; + + union { + phy_info_lcnphy_t *pi_lcnphy; + } u; + bool user_txpwr_at_rfport; + + d11regs_t *regs; + struct phy_info *next; + char *vars; + wlc_phy_t pubpi; + + bool do_initcal; + bool phytest_on; + bool ofdm_rateset_war; + bool bf_preempt_4306; + chanspec_t radio_chanspec; + u8 antsel_type; + u16 bw; + u8 txpwr_percent; + bool phy_init_por; + + bool init_in_progress; + bool initialized; + bool sbtml_gm; + uint refcnt; + bool watchdog_override; + u8 phynoise_state; + uint phynoise_now; + int phynoise_chan_watchdog; + bool phynoise_polling; + bool disable_percal; + mbool measure_hold; + + s16 txpa_2g[PWRTBL_NUM_COEFF]; + s16 txpa_2g_low_temp[PWRTBL_NUM_COEFF]; + s16 txpa_2g_high_temp[PWRTBL_NUM_COEFF]; + s16 txpa_5g_low[PWRTBL_NUM_COEFF]; + s16 txpa_5g_mid[PWRTBL_NUM_COEFF]; + s16 txpa_5g_hi[PWRTBL_NUM_COEFF]; + + u8 tx_srom_max_2g; + u8 tx_srom_max_5g_low; + u8 tx_srom_max_5g_mid; + u8 tx_srom_max_5g_hi; + u8 tx_srom_max_rate_2g[TXP_NUM_RATES]; + u8 tx_srom_max_rate_5g_low[TXP_NUM_RATES]; + u8 tx_srom_max_rate_5g_mid[TXP_NUM_RATES]; + u8 tx_srom_max_rate_5g_hi[TXP_NUM_RATES]; + u8 tx_user_target[TXP_NUM_RATES]; + s8 tx_power_offset[TXP_NUM_RATES]; + u8 tx_power_target[TXP_NUM_RATES]; + + srom_fem_t srom_fem2g; + srom_fem_t srom_fem5g; + + u8 tx_power_max; + u8 tx_power_max_rate_ind; + bool hwpwrctrl; + u8 nphy_txpwrctrl; + s8 nphy_txrx_chain; + bool phy_5g_pwrgain; + + u16 phy_wreg; + u16 phy_wreg_limit; + + s8 n_preamble_override; + u8 antswitch; + u8 aa2g, aa5g; + + s8 idle_tssi[CH_5G_GROUP]; + s8 target_idle_tssi; + s8 txpwr_est_Pout; + u8 tx_power_min; + u8 txpwr_limit[TXP_NUM_RATES]; + u8 txpwr_env_limit[TXP_NUM_RATES]; + u8 adj_pwr_tbl_nphy[ADJ_PWR_TBL_LEN]; + + bool channel_14_wide_filter; + + bool txpwroverride; + bool txpwridx_override_aphy; + s16 radiopwr_override; + u16 hwpwr_txcur; + u8 saved_txpwr_idx; + + bool edcrs_threshold_lock; + + u32 tr_R_gain_val; + u32 tr_T_gain_val; + + s16 ofdm_analog_filt_bw_override; + s16 cck_analog_filt_bw_override; + s16 ofdm_rccal_override; + s16 cck_rccal_override; + u16 extlna_type; + + uint interference_mode_crs_time; + u16 crsglitch_prev; + bool interference_mode_crs; + + u32 phy_tx_tone_freq; + uint phy_lastcal; + bool phy_forcecal; + bool phy_fixed_noise; + u32 xtalfreq; + u8 pdiv; + s8 carrier_suppr_disable; + + bool phy_bphy_evm; + bool phy_bphy_rfcs; + s8 phy_scraminit; + u8 phy_gpiosel; + + s16 phy_txcore_disable_temp; + s16 phy_txcore_enable_temp; + s8 phy_tempsense_offset; + bool phy_txcore_heatedup; + + u16 radiopwr; + u16 bb_atten; + u16 txctl1; + + u16 mintxbias; + u16 mintxmag; + lo_complex_abgphy_info_t gphy_locomp_iq[STATIC_NUM_RF][STATIC_NUM_BB]; + s8 stats_11b_txpower[STATIC_NUM_RF][STATIC_NUM_BB]; + u16 gain_table[TX_GAIN_TABLE_LENGTH]; + bool loopback_gain; + s16 max_lpback_gain_hdB; + s16 trsw_rx_gain_hdB; + u8 power_vec[8]; + + u16 rc_cal; + int nrssi_table_delta; + int nrssi_slope_scale; + int nrssi_slope_offset; + int min_rssi; + int max_rssi; + + s8 txpwridx; + u8 min_txpower; + + u8 a_band_high_disable; + + u16 tx_vos; + u16 global_tx_bb_dc_bias_loft; + + int rf_max; + int bb_max; + int rf_list_size; + int bb_list_size; + u16 *rf_attn_list; + u16 *bb_attn_list; + u16 padmix_mask; + u16 padmix_reg; + u16 *txmag_list; + uint txmag_len; + bool txmag_enable; + + s8 *a_tssi_to_dbm; + s8 *m_tssi_to_dbm; + s8 *l_tssi_to_dbm; + s8 *h_tssi_to_dbm; + u8 *hwtxpwr; + + u16 freqtrack_saved_regs[2]; + int cur_interference_mode; + bool hwpwrctrl_capable; + bool temppwrctrl_capable; + + uint phycal_nslope; + uint phycal_noffset; + uint phycal_mlo; + uint phycal_txpower; + + u8 phy_aa2g; + + bool nphy_tableloaded; + s8 nphy_rssisel; + u32 nphy_bb_mult_save; + u16 nphy_txiqlocal_bestc[11]; + bool nphy_txiqlocal_coeffsvalid; + phy_txpwrindex_t nphy_txpwrindex[PHY_CORE_NUM_2]; + phy_pwrctrl_t nphy_pwrctrl_info[PHY_CORE_NUM_2]; + u16 cck2gpo; + u32 ofdm2gpo; + u32 ofdm5gpo; + u32 ofdm5glpo; + u32 ofdm5ghpo; + u8 bw402gpo; + u8 bw405gpo; + u8 bw405glpo; + u8 bw405ghpo; + u8 cdd2gpo; + u8 cdd5gpo; + u8 cdd5glpo; + u8 cdd5ghpo; + u8 stbc2gpo; + u8 stbc5gpo; + u8 stbc5glpo; + u8 stbc5ghpo; + u8 bwdup2gpo; + u8 bwdup5gpo; + u8 bwdup5glpo; + u8 bwdup5ghpo; + u16 mcs2gpo[8]; + u16 mcs5gpo[8]; + u16 mcs5glpo[8]; + u16 mcs5ghpo[8]; + u32 nphy_rxcalparams; + + u8 phy_spuravoid; + bool phy_isspuravoid; + + u8 phy_pabias; + u8 nphy_papd_skip; + u8 nphy_tssi_slope; + + s16 nphy_noise_win[PHY_CORE_MAX][PHY_NOISE_WINDOW_SZ]; + u8 nphy_noise_index; + + u8 nphy_txpid2g[PHY_CORE_NUM_2]; + u8 nphy_txpid5g[PHY_CORE_NUM_2]; + u8 nphy_txpid5gl[PHY_CORE_NUM_2]; + u8 nphy_txpid5gh[PHY_CORE_NUM_2]; + + bool nphy_gain_boost; + bool nphy_elna_gain_config; + u16 old_bphy_test; + u16 old_bphy_testcontrol; + + bool phyhang_avoid; + + bool rssical_nphy; + u8 nphy_perical; + uint nphy_perical_last; + u8 cal_type_override; + u8 mphase_cal_phase_id; + u8 mphase_txcal_cmdidx; + u8 mphase_txcal_numcmds; + u16 mphase_txcal_bestcoeffs[11]; + chanspec_t nphy_txiqlocal_chanspec; + chanspec_t nphy_iqcal_chanspec_2G; + chanspec_t nphy_iqcal_chanspec_5G; + chanspec_t nphy_rssical_chanspec_2G; + chanspec_t nphy_rssical_chanspec_5G; + struct wlapi_timer *phycal_timer; + bool use_int_tx_iqlo_cal_nphy; + bool internal_tx_iqlo_cal_tapoff_intpa_nphy; + s16 nphy_lastcal_temp; + + txiqcal_cache_t calibration_cache; + rssical_cache_t rssical_cache; + + u8 nphy_txpwr_idx[2]; + u8 nphy_papd_cal_type; + uint nphy_papd_last_cal; + u16 nphy_papd_tx_gain_at_last_cal[2]; + u8 nphy_papd_cal_gain_index[2]; + s16 nphy_papd_epsilon_offset[2]; + bool nphy_papd_recal_enable; + u32 nphy_papd_recal_counter; + bool nphy_force_papd_cal; + bool nphy_papdcomp; + bool ipa2g_on; + bool ipa5g_on; + + u16 classifier_state; + u16 clip_state[2]; + uint nphy_deaf_count; + u8 rxiq_samps; + u8 rxiq_antsel; + + u16 rfctrlIntc1_save; + u16 rfctrlIntc2_save; + bool first_cal_after_assoc; + u16 tx_rx_cal_radio_saveregs[22]; + u16 tx_rx_cal_phy_saveregs[15]; + + u8 nphy_cal_orig_pwr_idx[2]; + u8 nphy_txcal_pwr_idx[2]; + u8 nphy_rxcal_pwr_idx[2]; + u16 nphy_cal_orig_tx_gain[2]; + nphy_txgains_t nphy_cal_target_gain; + u16 nphy_txcal_bbmult; + u16 nphy_gmval; + + u16 nphy_saved_bbconf; + + bool nphy_gband_spurwar_en; + bool nphy_gband_spurwar2_en; + bool nphy_aband_spurwar_en; + u16 nphy_rccal_value; + u16 nphy_crsminpwr[3]; + phy_noisevar_buf_t nphy_saved_noisevars; + bool nphy_anarxlpf_adjusted; + bool nphy_crsminpwr_adjusted; + bool nphy_noisevars_adjusted; + + bool nphy_rxcal_active; + u16 radar_percal_mask; + bool dfs_lp_buffer_nphy; + + u16 nphy_fineclockgatecontrol; + + s8 rx2tx_biasentry; + + u16 crsminpwr0; + u16 crsminpwrl0; + u16 crsminpwru0; + s16 noise_crsminpwr_index; + u16 init_gain_core1; + u16 init_gain_core2; + u16 init_gainb_core1; + u16 init_gainb_core2; + u8 aci_noise_curr_channel; + u16 init_gain_rfseq[4]; + + bool radio_is_on; + + bool nphy_sample_play_lpf_bw_ctl_ovr; + + u16 tbl_data_hi; + u16 tbl_data_lo; + u16 tbl_addr; + + uint tbl_save_id; + uint tbl_save_offset; + + u8 txpwrctrl; + s8 txpwrindex[PHY_CORE_MAX]; + + u8 phycal_tempdelta; + u32 mcs20_po; + u32 mcs40_po; +}; + +typedef s32 fixed; + +typedef struct _cs32 { + fixed q; + fixed i; +} cs32; + +typedef struct radio_regs { + u16 address; + u32 init_a; + u32 init_g; + u8 do_init_a; + u8 do_init_g; +} radio_regs_t; + +typedef struct radio_20xx_regs { + u16 address; + u8 init; + u8 do_init; +} radio_20xx_regs_t; + +typedef struct lcnphy_radio_regs { + u16 address; + u8 init_a; + u8 init_g; + u8 do_init_a; + u8 do_init_g; +} lcnphy_radio_regs_t; + +extern lcnphy_radio_regs_t lcnphy_radio_regs_2064[]; +extern lcnphy_radio_regs_t lcnphy_radio_regs_2066[]; +extern radio_regs_t regs_2055[], regs_SYN_2056[], regs_TX_2056[], + regs_RX_2056[]; +extern radio_regs_t regs_SYN_2056_A1[], regs_TX_2056_A1[], regs_RX_2056_A1[]; +extern radio_regs_t regs_SYN_2056_rev5[], regs_TX_2056_rev5[], + regs_RX_2056_rev5[]; +extern radio_regs_t regs_SYN_2056_rev6[], regs_TX_2056_rev6[], + regs_RX_2056_rev6[]; +extern radio_regs_t regs_SYN_2056_rev7[], regs_TX_2056_rev7[], + regs_RX_2056_rev7[]; +extern radio_regs_t regs_SYN_2056_rev8[], regs_TX_2056_rev8[], + regs_RX_2056_rev8[]; +extern radio_20xx_regs_t regs_2057_rev4[], regs_2057_rev5[], regs_2057_rev5v1[]; +extern radio_20xx_regs_t regs_2057_rev7[], regs_2057_rev8[]; + +extern char *phy_getvar(phy_info_t *pi, const char *name); +extern int phy_getintvar(phy_info_t *pi, const char *name); +#define PHY_GETVAR(pi, name) phy_getvar(pi, name) +#define PHY_GETINTVAR(pi, name) phy_getintvar(pi, name) + +extern u16 read_phy_reg(phy_info_t *pi, u16 addr); +extern void write_phy_reg(phy_info_t *pi, u16 addr, u16 val); +extern void and_phy_reg(phy_info_t *pi, u16 addr, u16 val); +extern void or_phy_reg(phy_info_t *pi, u16 addr, u16 val); +extern void mod_phy_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val); + +extern u16 read_radio_reg(phy_info_t *pi, u16 addr); +extern void or_radio_reg(phy_info_t *pi, u16 addr, u16 val); +extern void and_radio_reg(phy_info_t *pi, u16 addr, u16 val); +extern void mod_radio_reg(phy_info_t *pi, u16 addr, u16 mask, + u16 val); +extern void xor_radio_reg(phy_info_t *pi, u16 addr, u16 mask); + +extern void write_radio_reg(phy_info_t *pi, u16 addr, u16 val); + +extern void wlc_phyreg_enter(wlc_phy_t *pih); +extern void wlc_phyreg_exit(wlc_phy_t *pih); +extern void wlc_radioreg_enter(wlc_phy_t *pih); +extern void wlc_radioreg_exit(wlc_phy_t *pih); + +extern void wlc_phy_read_table(phy_info_t *pi, const phytbl_info_t *ptbl_info, + u16 tblAddr, u16 tblDataHi, + u16 tblDatalo); +extern void wlc_phy_write_table(phy_info_t *pi, + const phytbl_info_t *ptbl_info, u16 tblAddr, + u16 tblDataHi, u16 tblDatalo); +extern void wlc_phy_table_addr(phy_info_t *pi, uint tbl_id, uint tbl_offset, + u16 tblAddr, u16 tblDataHi, + u16 tblDataLo); +extern void wlc_phy_table_data_write(phy_info_t *pi, uint width, u32 val); + +extern void write_phy_channel_reg(phy_info_t *pi, uint val); +extern void wlc_phy_txpower_update_shm(phy_info_t *pi); + +extern void wlc_phy_cordic(fixed theta, cs32 *val); +extern u8 wlc_phy_nbits(s32 value); +extern u32 wlc_phy_sqrt_int(u32 value); +extern void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_dB, u8 core); + +extern uint wlc_phy_init_radio_regs_allbands(phy_info_t *pi, + radio_20xx_regs_t *radioregs); +extern uint wlc_phy_init_radio_regs(phy_info_t *pi, radio_regs_t *radioregs, + u16 core_offset); + +extern void wlc_phy_txpower_ipa_upd(phy_info_t *pi); + +extern void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on); +extern void wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, + s32 *eps_imag); + +extern void wlc_phy_cal_perical_mphase_reset(phy_info_t *pi); +extern void wlc_phy_cal_perical_mphase_restart(phy_info_t *pi); + +extern bool wlc_phy_attach_nphy(phy_info_t *pi); +extern bool wlc_phy_attach_lcnphy(phy_info_t *pi); + +extern void wlc_phy_detach_lcnphy(phy_info_t *pi); + +extern void wlc_phy_init_nphy(phy_info_t *pi); +extern void wlc_phy_init_lcnphy(phy_info_t *pi); + +extern void wlc_phy_cal_init_nphy(phy_info_t *pi); +extern void wlc_phy_cal_init_lcnphy(phy_info_t *pi); + +extern void wlc_phy_chanspec_set_nphy(phy_info_t *pi, chanspec_t chanspec); +extern void wlc_phy_chanspec_set_lcnphy(phy_info_t *pi, chanspec_t chanspec); +extern void wlc_phy_chanspec_set_fixup_lcnphy(phy_info_t *pi, + chanspec_t chanspec); +extern int wlc_phy_channel2freq(uint channel); +extern int wlc_phy_chanspec_freq2bandrange_lpssn(uint); +extern int wlc_phy_chanspec_bandrange_get(phy_info_t *, chanspec_t); + +extern void wlc_lcnphy_set_tx_pwr_ctrl(phy_info_t *pi, u16 mode); +extern s8 wlc_lcnphy_get_current_tx_pwr_idx(phy_info_t *pi); + +extern void wlc_phy_txpower_recalc_target_nphy(phy_info_t *pi); +extern void wlc_lcnphy_txpower_recalc_target(phy_info_t *pi); +extern void wlc_phy_txpower_recalc_target_lcnphy(phy_info_t *pi); + +extern void wlc_lcnphy_set_tx_pwr_by_index(phy_info_t *pi, int index); +extern void wlc_lcnphy_tx_pu(phy_info_t *pi, bool bEnable); +extern void wlc_lcnphy_stop_tx_tone(phy_info_t *pi); +extern void wlc_lcnphy_start_tx_tone(phy_info_t *pi, s32 f_kHz, + u16 max_val, bool iqcalmode); + +extern void wlc_phy_txpower_sromlimit_get_nphy(phy_info_t *pi, uint chan, + u8 *max_pwr, u8 rate_id); +extern void wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start, + u8 rate_mcs_end, + u8 rate_ofdm_start); +extern void wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power, + u8 rate_ofdm_start, + u8 rate_ofdm_end, + u8 rate_mcs_start); + +extern u16 wlc_lcnphy_tempsense(phy_info_t *pi, bool mode); +extern s16 wlc_lcnphy_tempsense_new(phy_info_t *pi, bool mode); +extern s8 wlc_lcnphy_tempsense_degree(phy_info_t *pi, bool mode); +extern s8 wlc_lcnphy_vbatsense(phy_info_t *pi, bool mode); +extern void wlc_phy_carrier_suppress_lcnphy(phy_info_t *pi); +extern void wlc_lcnphy_crsuprs(phy_info_t *pi, int channel); +extern void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode); +extern void wlc_2064_vco_cal(phy_info_t *pi); + +extern void wlc_phy_txpower_recalc_target(phy_info_t *pi); +extern u32 wlc_phy_qdiv_roundup(u32 dividend, u32 divisor, + u8 precision); + +#define LCNPHY_TBL_ID_PAPDCOMPDELTATBL 0x18 +#define LCNPHY_TX_POWER_TABLE_SIZE 128 +#define LCNPHY_MAX_TX_POWER_INDEX (LCNPHY_TX_POWER_TABLE_SIZE - 1) +#define LCNPHY_TBL_ID_TXPWRCTL 0x07 +#define LCNPHY_TX_PWR_CTRL_OFF 0 +#define LCNPHY_TX_PWR_CTRL_SW (0x1 << 15) +#define LCNPHY_TX_PWR_CTRL_HW ((0x1 << 15) | \ + (0x1 << 14) | \ + (0x1 << 13)) + +#define LCNPHY_TX_PWR_CTRL_TEMPBASED 0xE001 + +extern void wlc_lcnphy_write_table(phy_info_t *pi, const phytbl_info_t *pti); +extern void wlc_lcnphy_read_table(phy_info_t *pi, phytbl_info_t *pti); +extern void wlc_lcnphy_set_tx_iqcc(phy_info_t *pi, u16 a, u16 b); +extern void wlc_lcnphy_set_tx_locc(phy_info_t *pi, u16 didq); +extern void wlc_lcnphy_get_tx_iqcc(phy_info_t *pi, u16 *a, u16 *b); +extern u16 wlc_lcnphy_get_tx_locc(phy_info_t *pi); +extern void wlc_lcnphy_get_radio_loft(phy_info_t *pi, u8 *ei0, + u8 *eq0, u8 *fi0, u8 *fq0); +extern void wlc_lcnphy_calib_modes(phy_info_t *pi, uint mode); +extern void wlc_lcnphy_deaf_mode(phy_info_t *pi, bool mode); +extern bool wlc_phy_tpc_isenabled_lcnphy(phy_info_t *pi); +extern void wlc_lcnphy_tx_pwr_update_npt(phy_info_t *pi); +extern s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1); +extern void wlc_lcnphy_get_tssi(phy_info_t *pi, s8 *ofdm_pwr, + s8 *cck_pwr); +extern void wlc_lcnphy_tx_power_adjustment(wlc_phy_t *ppi); + +extern s32 wlc_lcnphy_rx_signal_power(phy_info_t *pi, s32 gain_index); + +#define NPHY_MAX_HPVGA1_INDEX 10 +#define NPHY_DEF_HPVGA1_INDEXLIMIT 7 + +typedef struct _phy_iq_est { + s32 iq_prod; + u32 i_pwr; + u32 q_pwr; +} phy_iq_est_t; + +extern void wlc_phy_stay_in_carriersearch_nphy(phy_info_t *pi, bool enable); +extern void wlc_nphy_deaf_mode(phy_info_t *pi, bool mode); + +#define wlc_phy_write_table_nphy(pi, pti) wlc_phy_write_table(pi, pti, 0x72, \ + 0x74, 0x73) +#define wlc_phy_read_table_nphy(pi, pti) wlc_phy_read_table(pi, pti, 0x72, \ + 0x74, 0x73) +#define wlc_nphy_table_addr(pi, id, off) wlc_phy_table_addr((pi), (id), (off), \ + 0x72, 0x74, 0x73) +#define wlc_nphy_table_data_write(pi, w, v) wlc_phy_table_data_write((pi), (w), (v)) + +extern void wlc_phy_table_read_nphy(phy_info_t *pi, u32, u32 l, u32 o, + u32 w, void *d); +extern void wlc_phy_table_write_nphy(phy_info_t *pi, u32, u32, u32, + u32, const void *); + +#define PHY_IPA(pi) \ + ((pi->ipa2g_on && CHSPEC_IS2G(pi->radio_chanspec)) || \ + (pi->ipa5g_on && CHSPEC_IS5G(pi->radio_chanspec))) + +#define WLC_PHY_WAR_PR51571(pi) \ + if (((pi)->sh->bustype == PCI_BUS) && NREV_LT((pi)->pubpi.phy_rev, 3)) \ + (void)R_REG((pi)->sh->osh, &(pi)->regs->maccontrol) + +extern void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype); +extern void wlc_phy_aci_reset_nphy(phy_info_t *pi); +extern void wlc_phy_pa_override_nphy(phy_info_t *pi, bool en); + +extern u8 wlc_phy_get_chan_freq_range_nphy(phy_info_t *pi, uint chan); +extern void wlc_phy_switch_radio_nphy(phy_info_t *pi, bool on); + +extern void wlc_phy_stf_chain_upd_nphy(phy_info_t *pi); + +extern void wlc_phy_force_rfseq_nphy(phy_info_t *pi, u8 cmd); +extern s16 wlc_phy_tempsense_nphy(phy_info_t *pi); + +extern u16 wlc_phy_classifier_nphy(phy_info_t *pi, u16 mask, u16 val); + +extern void wlc_phy_rx_iq_est_nphy(phy_info_t *pi, phy_iq_est_t *est, + u16 num_samps, u8 wait_time, + u8 wait_for_crs); + +extern void wlc_phy_rx_iq_coeffs_nphy(phy_info_t *pi, u8 write, + nphy_iq_comp_t *comp); +extern void wlc_phy_aci_and_noise_reduction_nphy(phy_info_t *pi); + +extern void wlc_phy_rxcore_setstate_nphy(wlc_phy_t *pih, u8 rxcore_bitmask); +extern u8 wlc_phy_rxcore_getstate_nphy(wlc_phy_t *pih); + +extern void wlc_phy_txpwrctrl_enable_nphy(phy_info_t *pi, u8 ctrl_type); +extern void wlc_phy_txpwr_fixpower_nphy(phy_info_t *pi); +extern void wlc_phy_txpwr_apply_nphy(phy_info_t *pi); +extern void wlc_phy_txpwr_papd_cal_nphy(phy_info_t *pi); +extern u16 wlc_phy_txpwr_idx_get_nphy(phy_info_t *pi); + +extern nphy_txgains_t wlc_phy_get_tx_gain_nphy(phy_info_t *pi); +extern int wlc_phy_cal_txiqlo_nphy(phy_info_t *pi, nphy_txgains_t target_gain, + bool full, bool m); +extern int wlc_phy_cal_rxiq_nphy(phy_info_t *pi, nphy_txgains_t target_gain, + u8 type, bool d); +extern void wlc_phy_txpwr_index_nphy(phy_info_t *pi, u8 core_mask, + s8 txpwrindex, bool res); +extern void wlc_phy_rssisel_nphy(phy_info_t *pi, u8 core, u8 rssi_type); +extern int wlc_phy_poll_rssi_nphy(phy_info_t *pi, u8 rssi_type, + s32 *rssi_buf, u8 nsamps); +extern void wlc_phy_rssi_cal_nphy(phy_info_t *pi); +extern int wlc_phy_aci_scan_nphy(phy_info_t *pi); +extern void wlc_phy_cal_txgainctrl_nphy(phy_info_t *pi, s32 dBm_targetpower, + bool debug); +extern int wlc_phy_tx_tone_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val, + u8 mode, u8, bool); +extern void wlc_phy_stopplayback_nphy(phy_info_t *pi); +extern void wlc_phy_est_tonepwr_nphy(phy_info_t *pi, s32 *qdBm_pwrbuf, + u8 num_samps); +extern void wlc_phy_radio205x_vcocal_nphy(phy_info_t *pi); + +extern int wlc_phy_rssi_compute_nphy(phy_info_t *pi, wlc_d11rxhdr_t *wlc_rxh); + +#define NPHY_TESTPATTERN_BPHY_EVM 0 +#define NPHY_TESTPATTERN_BPHY_RFCS 1 + +extern void wlc_phy_nphy_tkip_rifs_war(phy_info_t *pi, u8 rifs); + +void wlc_phy_get_pwrdet_offsets(phy_info_t *pi, s8 *cckoffset, + s8 *ofdmoffset); +extern s8 wlc_phy_upd_rssi_offset(phy_info_t *pi, s8 rssi, + chanspec_t chanspec); + +extern bool wlc_phy_n_txpower_ipa_ison(phy_info_t *pih); +#endif /* _wlc_phy_int_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c new file mode 100644 index 000000000000..3ac2b49d9a9d --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c @@ -0,0 +1,5325 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#define PLL_2064_NDIV 90 +#define PLL_2064_LOW_END_VCO 3000 +#define PLL_2064_LOW_END_KVCO 27 +#define PLL_2064_HIGH_END_VCO 4200 +#define PLL_2064_HIGH_END_KVCO 68 +#define PLL_2064_LOOP_BW_DOUBLER 200 +#define PLL_2064_D30_DOUBLER 10500 +#define PLL_2064_LOOP_BW 260 +#define PLL_2064_D30 8000 +#define PLL_2064_CAL_REF_TO 8 +#define PLL_2064_MHZ 1000000 +#define PLL_2064_OPEN_LOOP_DELAY 5 + +#define TEMPSENSE 1 +#define VBATSENSE 2 + +#define NOISE_IF_UPD_CHK_INTERVAL 1 +#define NOISE_IF_UPD_RST_INTERVAL 60 +#define NOISE_IF_UPD_THRESHOLD_CNT 1 +#define NOISE_IF_UPD_TRHRESHOLD 50 +#define NOISE_IF_UPD_TIMEOUT 1000 +#define NOISE_IF_OFF 0 +#define NOISE_IF_CHK 1 +#define NOISE_IF_ON 2 + +#define PAPD_BLANKING_PROFILE 3 +#define PAPD2LUT 0 +#define PAPD_CORR_NORM 0 +#define PAPD_BLANKING_THRESHOLD 0 +#define PAPD_STOP_AFTER_LAST_UPDATE 0 + +#define LCN_TARGET_PWR 60 + +#define LCN_VBAT_OFFSET_433X 34649679 +#define LCN_VBAT_SLOPE_433X 8258032 + +#define LCN_VBAT_SCALE_NOM 53 +#define LCN_VBAT_SCALE_DEN 432 + +#define LCN_TEMPSENSE_OFFSET 80812 +#define LCN_TEMPSENSE_DEN 2647 + +#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT \ + (0 + 8) +#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK \ + (0x7f << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT) + +#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT \ + (0 + 8) +#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK \ + (0x7f << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT) + +#define wlc_lcnphy_enable_tx_gain_override(pi) \ + wlc_lcnphy_set_tx_gain_override(pi, true) +#define wlc_lcnphy_disable_tx_gain_override(pi) \ + wlc_lcnphy_set_tx_gain_override(pi, false) + +#define wlc_lcnphy_iqcal_active(pi) \ + (read_phy_reg((pi), 0x451) & \ + ((0x1 << 15) | (0x1 << 14))) + +#define txpwrctrl_off(pi) (0x7 != ((read_phy_reg(pi, 0x4a4) & 0xE000) >> 13)) +#define wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) \ + (pi->temppwrctrl_capable) +#define wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) \ + (pi->hwpwrctrl_capable) + +#define SWCTRL_BT_TX 0x18 +#define SWCTRL_OVR_DISABLE 0x40 + +#define AFE_CLK_INIT_MODE_TXRX2X 1 +#define AFE_CLK_INIT_MODE_PAPD 0 + +#define LCNPHY_TBL_ID_IQLOCAL 0x00 + +#define LCNPHY_TBL_ID_RFSEQ 0x08 +#define LCNPHY_TBL_ID_GAIN_IDX 0x0d +#define LCNPHY_TBL_ID_SW_CTRL 0x0f +#define LCNPHY_TBL_ID_GAIN_TBL 0x12 +#define LCNPHY_TBL_ID_SPUR 0x14 +#define LCNPHY_TBL_ID_SAMPLEPLAY 0x15 +#define LCNPHY_TBL_ID_SAMPLEPLAY1 0x16 + +#define LCNPHY_TX_PWR_CTRL_RATE_OFFSET 832 +#define LCNPHY_TX_PWR_CTRL_MAC_OFFSET 128 +#define LCNPHY_TX_PWR_CTRL_GAIN_OFFSET 192 +#define LCNPHY_TX_PWR_CTRL_IQ_OFFSET 320 +#define LCNPHY_TX_PWR_CTRL_LO_OFFSET 448 +#define LCNPHY_TX_PWR_CTRL_PWR_OFFSET 576 + +#define LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313 140 + +#define LCNPHY_TX_PWR_CTRL_START_NPT 1 +#define LCNPHY_TX_PWR_CTRL_MAX_NPT 7 + +#define LCNPHY_NOISE_SAMPLES_DEFAULT 5000 + +#define LCNPHY_ACI_DETECT_START 1 +#define LCNPHY_ACI_DETECT_PROGRESS 2 +#define LCNPHY_ACI_DETECT_STOP 3 + +#define LCNPHY_ACI_CRSHIFRMLO_TRSH 100 +#define LCNPHY_ACI_GLITCH_TRSH 2000 +#define LCNPHY_ACI_TMOUT 250 +#define LCNPHY_ACI_DETECT_TIMEOUT 2 +#define LCNPHY_ACI_START_DELAY 0 + +#define wlc_lcnphy_tx_gain_override_enabled(pi) \ + (0 != (read_phy_reg((pi), 0x43b) & (0x1 << 6))) + +#define wlc_lcnphy_total_tx_frames(pi) \ + wlapi_bmac_read_shm((pi)->sh->physhim, M_UCODE_MACSTAT + offsetof(macstat_t, txallfrm)) + +typedef struct { + u16 gm_gain; + u16 pga_gain; + u16 pad_gain; + u16 dac_gain; +} lcnphy_txgains_t; + +typedef enum { + LCNPHY_CAL_FULL, + LCNPHY_CAL_RECAL, + LCNPHY_CAL_CURRECAL, + LCNPHY_CAL_DIGCAL, + LCNPHY_CAL_GCTRL +} lcnphy_cal_mode_t; + +typedef struct { + lcnphy_txgains_t gains; + bool useindex; + u8 index; +} lcnphy_txcalgains_t; + +typedef struct { + u8 chan; + s16 a; + s16 b; +} lcnphy_rx_iqcomp_t; + +typedef struct { + s16 re; + s16 im; +} lcnphy_spb_tone_t; + +typedef struct { + u16 re; + u16 im; +} lcnphy_unsign16_struct; + +typedef struct { + u32 iq_prod; + u32 i_pwr; + u32 q_pwr; +} lcnphy_iq_est_t; + +typedef struct { + u16 ptcentreTs20; + u16 ptcentreFactor; +} lcnphy_sfo_cfg_t; + +typedef enum { + LCNPHY_PAPD_CAL_CW, + LCNPHY_PAPD_CAL_OFDM +} lcnphy_papd_cal_type_t; + +typedef u16 iqcal_gain_params_lcnphy[9]; + +static const iqcal_gain_params_lcnphy tbl_iqcal_gainparams_lcnphy_2G[] = { + {0, 0, 0, 0, 0, 0, 0, 0, 0}, +}; + +static const iqcal_gain_params_lcnphy *tbl_iqcal_gainparams_lcnphy[1] = { + tbl_iqcal_gainparams_lcnphy_2G, +}; + +static const u16 iqcal_gainparams_numgains_lcnphy[1] = { + sizeof(tbl_iqcal_gainparams_lcnphy_2G) / + sizeof(*tbl_iqcal_gainparams_lcnphy_2G), +}; + +static const lcnphy_sfo_cfg_t lcnphy_sfo_cfg[] = { + {965, 1087}, + {967, 1085}, + {969, 1082}, + {971, 1080}, + {973, 1078}, + {975, 1076}, + {977, 1073}, + {979, 1071}, + {981, 1069}, + {983, 1067}, + {985, 1065}, + {987, 1063}, + {989, 1060}, + {994, 1055} +}; + +static const +u16 lcnphy_iqcal_loft_gainladder[] = { + ((2 << 8) | 0), + ((3 << 8) | 0), + ((4 << 8) | 0), + ((6 << 8) | 0), + ((8 << 8) | 0), + ((11 << 8) | 0), + ((16 << 8) | 0), + ((16 << 8) | 1), + ((16 << 8) | 2), + ((16 << 8) | 3), + ((16 << 8) | 4), + ((16 << 8) | 5), + ((16 << 8) | 6), + ((16 << 8) | 7), + ((23 << 8) | 7), + ((32 << 8) | 7), + ((45 << 8) | 7), + ((64 << 8) | 7), + ((91 << 8) | 7), + ((128 << 8) | 7) +}; + +static const +u16 lcnphy_iqcal_ir_gainladder[] = { + ((1 << 8) | 0), + ((2 << 8) | 0), + ((4 << 8) | 0), + ((6 << 8) | 0), + ((8 << 8) | 0), + ((11 << 8) | 0), + ((16 << 8) | 0), + ((23 << 8) | 0), + ((32 << 8) | 0), + ((45 << 8) | 0), + ((64 << 8) | 0), + ((64 << 8) | 1), + ((64 << 8) | 2), + ((64 << 8) | 3), + ((64 << 8) | 4), + ((64 << 8) | 5), + ((64 << 8) | 6), + ((64 << 8) | 7), + ((91 << 8) | 7), + ((128 << 8) | 7) +}; + +static const +lcnphy_spb_tone_t lcnphy_spb_tone_3750[] = { + {88, 0}, + {73, 49}, + {34, 81}, + {-17, 86}, + {-62, 62}, + {-86, 17}, + {-81, -34}, + {-49, -73}, + {0, -88}, + {49, -73}, + {81, -34}, + {86, 17}, + {62, 62}, + {17, 86}, + {-34, 81}, + {-73, 49}, + {-88, 0}, + {-73, -49}, + {-34, -81}, + {17, -86}, + {62, -62}, + {86, -17}, + {81, 34}, + {49, 73}, + {0, 88}, + {-49, 73}, + {-81, 34}, + {-86, -17}, + {-62, -62}, + {-17, -86}, + {34, -81}, + {73, -49}, +}; + +static const +u16 iqlo_loopback_rf_regs[20] = { + RADIO_2064_REG036, + RADIO_2064_REG11A, + RADIO_2064_REG03A, + RADIO_2064_REG025, + RADIO_2064_REG028, + RADIO_2064_REG005, + RADIO_2064_REG112, + RADIO_2064_REG0FF, + RADIO_2064_REG11F, + RADIO_2064_REG00B, + RADIO_2064_REG113, + RADIO_2064_REG007, + RADIO_2064_REG0FC, + RADIO_2064_REG0FD, + RADIO_2064_REG012, + RADIO_2064_REG057, + RADIO_2064_REG059, + RADIO_2064_REG05C, + RADIO_2064_REG078, + RADIO_2064_REG092, +}; + +static const +u16 tempsense_phy_regs[14] = { + 0x503, + 0x4a4, + 0x4d0, + 0x4d9, + 0x4da, + 0x4a6, + 0x938, + 0x939, + 0x4d8, + 0x4d0, + 0x4d7, + 0x4a5, + 0x40d, + 0x4a2, +}; + +static const +u16 rxiq_cal_rf_reg[11] = { + RADIO_2064_REG098, + RADIO_2064_REG116, + RADIO_2064_REG12C, + RADIO_2064_REG06A, + RADIO_2064_REG00B, + RADIO_2064_REG01B, + RADIO_2064_REG113, + RADIO_2064_REG01D, + RADIO_2064_REG114, + RADIO_2064_REG02E, + RADIO_2064_REG12A, +}; + +static const +lcnphy_rx_iqcomp_t lcnphy_rx_iqcomp_table_rev0[] = { + {1, 0, 0}, + {2, 0, 0}, + {3, 0, 0}, + {4, 0, 0}, + {5, 0, 0}, + {6, 0, 0}, + {7, 0, 0}, + {8, 0, 0}, + {9, 0, 0}, + {10, 0, 0}, + {11, 0, 0}, + {12, 0, 0}, + {13, 0, 0}, + {14, 0, 0}, + {34, 0, 0}, + {38, 0, 0}, + {42, 0, 0}, + {46, 0, 0}, + {36, 0, 0}, + {40, 0, 0}, + {44, 0, 0}, + {48, 0, 0}, + {52, 0, 0}, + {56, 0, 0}, + {60, 0, 0}, + {64, 0, 0}, + {100, 0, 0}, + {104, 0, 0}, + {108, 0, 0}, + {112, 0, 0}, + {116, 0, 0}, + {120, 0, 0}, + {124, 0, 0}, + {128, 0, 0}, + {132, 0, 0}, + {136, 0, 0}, + {140, 0, 0}, + {149, 0, 0}, + {153, 0, 0}, + {157, 0, 0}, + {161, 0, 0}, + {165, 0, 0}, + {184, 0, 0}, + {188, 0, 0}, + {192, 0, 0}, + {196, 0, 0}, + {200, 0, 0}, + {204, 0, 0}, + {208, 0, 0}, + {212, 0, 0}, + {216, 0, 0}, +}; + +static const u32 lcnphy_23bitgaincode_table[] = { + 0x200100, + 0x200200, + 0x200004, + 0x200014, + 0x200024, + 0x200034, + 0x200134, + 0x200234, + 0x200334, + 0x200434, + 0x200037, + 0x200137, + 0x200237, + 0x200337, + 0x200437, + 0x000035, + 0x000135, + 0x000235, + 0x000037, + 0x000137, + 0x000237, + 0x000337, + 0x00013f, + 0x00023f, + 0x00033f, + 0x00034f, + 0x00044f, + 0x00144f, + 0x00244f, + 0x00254f, + 0x00354f, + 0x00454f, + 0x00464f, + 0x01464f, + 0x02464f, + 0x03464f, + 0x04464f, +}; + +static const s8 lcnphy_gain_table[] = { + -16, + -13, + 10, + 7, + 4, + 0, + 3, + 6, + 9, + 12, + 15, + 18, + 21, + 24, + 27, + 30, + 33, + 36, + 39, + 42, + 45, + 48, + 50, + 53, + 56, + 59, + 62, + 65, + 68, + 71, + 74, + 77, + 80, + 83, + 86, + 89, + 92, +}; + +static const s8 lcnphy_gain_index_offset_for_rssi[] = { + 7, + 7, + 7, + 7, + 7, + 7, + 7, + 8, + 7, + 7, + 6, + 7, + 7, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 3, + 3, + 3, + 3, + 3, + 3, + 4, + 2, + 2, + 2, + 2, + 2, + 2, + -1, + -2, + -2, + -2 +}; + +extern const u8 spur_tbl_rev0[]; +extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev1; +extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev1[]; +extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa; +extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250; + +typedef struct _chan_info_2064_lcnphy { + uint chan; + uint freq; + u8 logen_buftune; + u8 logen_rccr_tx; + u8 txrf_mix_tune_ctrl; + u8 pa_input_tune_g; + u8 logen_rccr_rx; + u8 pa_rxrf_lna1_freq_tune; + u8 pa_rxrf_lna2_freq_tune; + u8 rxrf_rxrf_spare1; +} chan_info_2064_lcnphy_t; + +static chan_info_2064_lcnphy_t chan_info_2064_lcnphy[] = { + {1, 2412, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, + {2, 2417, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, + {3, 2422, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, + {4, 2427, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, + {5, 2432, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, + {6, 2437, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, + {7, 2442, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, + {8, 2447, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, + {9, 2452, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, + {10, 2457, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, + {11, 2462, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, + {12, 2467, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, + {13, 2472, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, + {14, 2484, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, +}; + +lcnphy_radio_regs_t lcnphy_radio_regs_2064[] = { + {0x00, 0, 0, 0, 0}, + {0x01, 0x64, 0x64, 0, 0}, + {0x02, 0x20, 0x20, 0, 0}, + {0x03, 0x66, 0x66, 0, 0}, + {0x04, 0xf8, 0xf8, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0x10, 0x10, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0, 0, 0, 0}, + {0x0A, 0x37, 0x37, 0, 0}, + {0x0B, 0x6, 0x6, 0, 0}, + {0x0C, 0x55, 0x55, 0, 0}, + {0x0D, 0x8b, 0x8b, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0x5, 0x5, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0xe, 0xe, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0xb, 0xb, 0, 0}, + {0x14, 0x2, 0x2, 0, 0}, + {0x15, 0x12, 0x12, 0, 0}, + {0x16, 0x12, 0x12, 0, 0}, + {0x17, 0xc, 0xc, 0, 0}, + {0x18, 0xc, 0xc, 0, 0}, + {0x19, 0xc, 0xc, 0, 0}, + {0x1A, 0x8, 0x8, 0, 0}, + {0x1B, 0x2, 0x2, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0x1, 0x1, 0, 0}, + {0x1E, 0x12, 0x12, 0, 0}, + {0x1F, 0x6e, 0x6e, 0, 0}, + {0x20, 0x2, 0x2, 0, 0}, + {0x21, 0x23, 0x23, 0, 0}, + {0x22, 0x8, 0x8, 0, 0}, + {0x23, 0, 0, 0, 0}, + {0x24, 0, 0, 0, 0}, + {0x25, 0xc, 0xc, 0, 0}, + {0x26, 0x33, 0x33, 0, 0}, + {0x27, 0x55, 0x55, 0, 0}, + {0x28, 0, 0, 0, 0}, + {0x29, 0x30, 0x30, 0, 0}, + {0x2A, 0xb, 0xb, 0, 0}, + {0x2B, 0x1b, 0x1b, 0, 0}, + {0x2C, 0x3, 0x3, 0, 0}, + {0x2D, 0x1b, 0x1b, 0, 0}, + {0x2E, 0, 0, 0, 0}, + {0x2F, 0x20, 0x20, 0, 0}, + {0x30, 0xa, 0xa, 0, 0}, + {0x31, 0, 0, 0, 0}, + {0x32, 0x62, 0x62, 0, 0}, + {0x33, 0x19, 0x19, 0, 0}, + {0x34, 0x33, 0x33, 0, 0}, + {0x35, 0x77, 0x77, 0, 0}, + {0x36, 0, 0, 0, 0}, + {0x37, 0x70, 0x70, 0, 0}, + {0x38, 0x3, 0x3, 0, 0}, + {0x39, 0xf, 0xf, 0, 0}, + {0x3A, 0x6, 0x6, 0, 0}, + {0x3B, 0xcf, 0xcf, 0, 0}, + {0x3C, 0x1a, 0x1a, 0, 0}, + {0x3D, 0x6, 0x6, 0, 0}, + {0x3E, 0x42, 0x42, 0, 0}, + {0x3F, 0, 0, 0, 0}, + {0x40, 0xfb, 0xfb, 0, 0}, + {0x41, 0x9a, 0x9a, 0, 0}, + {0x42, 0x7a, 0x7a, 0, 0}, + {0x43, 0x29, 0x29, 0, 0}, + {0x44, 0, 0, 0, 0}, + {0x45, 0x8, 0x8, 0, 0}, + {0x46, 0xce, 0xce, 0, 0}, + {0x47, 0x27, 0x27, 0, 0}, + {0x48, 0x62, 0x62, 0, 0}, + {0x49, 0x6, 0x6, 0, 0}, + {0x4A, 0x58, 0x58, 0, 0}, + {0x4B, 0xf7, 0xf7, 0, 0}, + {0x4C, 0, 0, 0, 0}, + {0x4D, 0xb3, 0xb3, 0, 0}, + {0x4E, 0, 0, 0, 0}, + {0x4F, 0x2, 0x2, 0, 0}, + {0x50, 0, 0, 0, 0}, + {0x51, 0x9, 0x9, 0, 0}, + {0x52, 0x5, 0x5, 0, 0}, + {0x53, 0x17, 0x17, 0, 0}, + {0x54, 0x38, 0x38, 0, 0}, + {0x55, 0, 0, 0, 0}, + {0x56, 0, 0, 0, 0}, + {0x57, 0xb, 0xb, 0, 0}, + {0x58, 0, 0, 0, 0}, + {0x59, 0, 0, 0, 0}, + {0x5A, 0, 0, 0, 0}, + {0x5B, 0, 0, 0, 0}, + {0x5C, 0, 0, 0, 0}, + {0x5D, 0, 0, 0, 0}, + {0x5E, 0x88, 0x88, 0, 0}, + {0x5F, 0xcc, 0xcc, 0, 0}, + {0x60, 0x74, 0x74, 0, 0}, + {0x61, 0x74, 0x74, 0, 0}, + {0x62, 0x74, 0x74, 0, 0}, + {0x63, 0x44, 0x44, 0, 0}, + {0x64, 0x77, 0x77, 0, 0}, + {0x65, 0x44, 0x44, 0, 0}, + {0x66, 0x77, 0x77, 0, 0}, + {0x67, 0x55, 0x55, 0, 0}, + {0x68, 0x77, 0x77, 0, 0}, + {0x69, 0x77, 0x77, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0x7f, 0x7f, 0, 0}, + {0x6C, 0x8, 0x8, 0, 0}, + {0x6D, 0, 0, 0, 0}, + {0x6E, 0x88, 0x88, 0, 0}, + {0x6F, 0x66, 0x66, 0, 0}, + {0x70, 0x66, 0x66, 0, 0}, + {0x71, 0x28, 0x28, 0, 0}, + {0x72, 0x55, 0x55, 0, 0}, + {0x73, 0x4, 0x4, 0, 0}, + {0x74, 0, 0, 0, 0}, + {0x75, 0, 0, 0, 0}, + {0x76, 0, 0, 0, 0}, + {0x77, 0x1, 0x1, 0, 0}, + {0x78, 0xd6, 0xd6, 0, 0}, + {0x79, 0, 0, 0, 0}, + {0x7A, 0, 0, 0, 0}, + {0x7B, 0, 0, 0, 0}, + {0x7C, 0, 0, 0, 0}, + {0x7D, 0, 0, 0, 0}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0xb4, 0xb4, 0, 0}, + {0x84, 0x1, 0x1, 0, 0}, + {0x85, 0x20, 0x20, 0, 0}, + {0x86, 0x5, 0x5, 0, 0}, + {0x87, 0xff, 0xff, 0, 0}, + {0x88, 0x7, 0x7, 0, 0}, + {0x89, 0x77, 0x77, 0, 0}, + {0x8A, 0x77, 0x77, 0, 0}, + {0x8B, 0x77, 0x77, 0, 0}, + {0x8C, 0x77, 0x77, 0, 0}, + {0x8D, 0x8, 0x8, 0, 0}, + {0x8E, 0xa, 0xa, 0, 0}, + {0x8F, 0x8, 0x8, 0, 0}, + {0x90, 0x18, 0x18, 0, 0}, + {0x91, 0x5, 0x5, 0, 0}, + {0x92, 0x1f, 0x1f, 0, 0}, + {0x93, 0x10, 0x10, 0, 0}, + {0x94, 0x3, 0x3, 0, 0}, + {0x95, 0, 0, 0, 0}, + {0x96, 0, 0, 0, 0}, + {0x97, 0xaa, 0xaa, 0, 0}, + {0x98, 0, 0, 0, 0}, + {0x99, 0x23, 0x23, 0, 0}, + {0x9A, 0x7, 0x7, 0, 0}, + {0x9B, 0xf, 0xf, 0, 0}, + {0x9C, 0x10, 0x10, 0, 0}, + {0x9D, 0x3, 0x3, 0, 0}, + {0x9E, 0x4, 0x4, 0, 0}, + {0x9F, 0x20, 0x20, 0, 0}, + {0xA0, 0, 0, 0, 0}, + {0xA1, 0, 0, 0, 0}, + {0xA2, 0, 0, 0, 0}, + {0xA3, 0, 0, 0, 0}, + {0xA4, 0x1, 0x1, 0, 0}, + {0xA5, 0x77, 0x77, 0, 0}, + {0xA6, 0x77, 0x77, 0, 0}, + {0xA7, 0x77, 0x77, 0, 0}, + {0xA8, 0x77, 0x77, 0, 0}, + {0xA9, 0x8c, 0x8c, 0, 0}, + {0xAA, 0x88, 0x88, 0, 0}, + {0xAB, 0x78, 0x78, 0, 0}, + {0xAC, 0x57, 0x57, 0, 0}, + {0xAD, 0x88, 0x88, 0, 0}, + {0xAE, 0, 0, 0, 0}, + {0xAF, 0x8, 0x8, 0, 0}, + {0xB0, 0x88, 0x88, 0, 0}, + {0xB1, 0, 0, 0, 0}, + {0xB2, 0x1b, 0x1b, 0, 0}, + {0xB3, 0x3, 0x3, 0, 0}, + {0xB4, 0x24, 0x24, 0, 0}, + {0xB5, 0x3, 0x3, 0, 0}, + {0xB6, 0x1b, 0x1b, 0, 0}, + {0xB7, 0x24, 0x24, 0, 0}, + {0xB8, 0x3, 0x3, 0, 0}, + {0xB9, 0, 0, 0, 0}, + {0xBA, 0xaa, 0xaa, 0, 0}, + {0xBB, 0, 0, 0, 0}, + {0xBC, 0x4, 0x4, 0, 0}, + {0xBD, 0, 0, 0, 0}, + {0xBE, 0x8, 0x8, 0, 0}, + {0xBF, 0x11, 0x11, 0, 0}, + {0xC0, 0, 0, 0, 0}, + {0xC1, 0, 0, 0, 0}, + {0xC2, 0x62, 0x62, 0, 0}, + {0xC3, 0x1e, 0x1e, 0, 0}, + {0xC4, 0x33, 0x33, 0, 0}, + {0xC5, 0x37, 0x37, 0, 0}, + {0xC6, 0, 0, 0, 0}, + {0xC7, 0x70, 0x70, 0, 0}, + {0xC8, 0x1e, 0x1e, 0, 0}, + {0xC9, 0x6, 0x6, 0, 0}, + {0xCA, 0x4, 0x4, 0, 0}, + {0xCB, 0x2f, 0x2f, 0, 0}, + {0xCC, 0xf, 0xf, 0, 0}, + {0xCD, 0, 0, 0, 0}, + {0xCE, 0xff, 0xff, 0, 0}, + {0xCF, 0x8, 0x8, 0, 0}, + {0xD0, 0x3f, 0x3f, 0, 0}, + {0xD1, 0x3f, 0x3f, 0, 0}, + {0xD2, 0x3f, 0x3f, 0, 0}, + {0xD3, 0, 0, 0, 0}, + {0xD4, 0, 0, 0, 0}, + {0xD5, 0, 0, 0, 0}, + {0xD6, 0xcc, 0xcc, 0, 0}, + {0xD7, 0, 0, 0, 0}, + {0xD8, 0x8, 0x8, 0, 0}, + {0xD9, 0x8, 0x8, 0, 0}, + {0xDA, 0x8, 0x8, 0, 0}, + {0xDB, 0x11, 0x11, 0, 0}, + {0xDC, 0, 0, 0, 0}, + {0xDD, 0x87, 0x87, 0, 0}, + {0xDE, 0x88, 0x88, 0, 0}, + {0xDF, 0x8, 0x8, 0, 0}, + {0xE0, 0x8, 0x8, 0, 0}, + {0xE1, 0x8, 0x8, 0, 0}, + {0xE2, 0, 0, 0, 0}, + {0xE3, 0, 0, 0, 0}, + {0xE4, 0, 0, 0, 0}, + {0xE5, 0xf5, 0xf5, 0, 0}, + {0xE6, 0x30, 0x30, 0, 0}, + {0xE7, 0x1, 0x1, 0, 0}, + {0xE8, 0, 0, 0, 0}, + {0xE9, 0xff, 0xff, 0, 0}, + {0xEA, 0, 0, 0, 0}, + {0xEB, 0, 0, 0, 0}, + {0xEC, 0x22, 0x22, 0, 0}, + {0xED, 0, 0, 0, 0}, + {0xEE, 0, 0, 0, 0}, + {0xEF, 0, 0, 0, 0}, + {0xF0, 0x3, 0x3, 0, 0}, + {0xF1, 0x1, 0x1, 0, 0}, + {0xF2, 0, 0, 0, 0}, + {0xF3, 0, 0, 0, 0}, + {0xF4, 0, 0, 0, 0}, + {0xF5, 0, 0, 0, 0}, + {0xF6, 0, 0, 0, 0}, + {0xF7, 0x6, 0x6, 0, 0}, + {0xF8, 0, 0, 0, 0}, + {0xF9, 0, 0, 0, 0}, + {0xFA, 0x40, 0x40, 0, 0}, + {0xFB, 0, 0, 0, 0}, + {0xFC, 0x1, 0x1, 0, 0}, + {0xFD, 0x80, 0x80, 0, 0}, + {0xFE, 0x2, 0x2, 0, 0}, + {0xFF, 0x10, 0x10, 0, 0}, + {0x100, 0x2, 0x2, 0, 0}, + {0x101, 0x1e, 0x1e, 0, 0}, + {0x102, 0x1e, 0x1e, 0, 0}, + {0x103, 0, 0, 0, 0}, + {0x104, 0x1f, 0x1f, 0, 0}, + {0x105, 0, 0x8, 0, 1}, + {0x106, 0x2a, 0x2a, 0, 0}, + {0x107, 0xf, 0xf, 0, 0}, + {0x108, 0, 0, 0, 0}, + {0x109, 0, 0, 0, 0}, + {0x10A, 0, 0, 0, 0}, + {0x10B, 0, 0, 0, 0}, + {0x10C, 0, 0, 0, 0}, + {0x10D, 0, 0, 0, 0}, + {0x10E, 0, 0, 0, 0}, + {0x10F, 0, 0, 0, 0}, + {0x110, 0, 0, 0, 0}, + {0x111, 0, 0, 0, 0}, + {0x112, 0, 0, 0, 0}, + {0x113, 0, 0, 0, 0}, + {0x114, 0, 0, 0, 0}, + {0x115, 0, 0, 0, 0}, + {0x116, 0, 0, 0, 0}, + {0x117, 0, 0, 0, 0}, + {0x118, 0, 0, 0, 0}, + {0x119, 0, 0, 0, 0}, + {0x11A, 0, 0, 0, 0}, + {0x11B, 0, 0, 0, 0}, + {0x11C, 0x1, 0x1, 0, 0}, + {0x11D, 0, 0, 0, 0}, + {0x11E, 0, 0, 0, 0}, + {0x11F, 0, 0, 0, 0}, + {0x120, 0, 0, 0, 0}, + {0x121, 0, 0, 0, 0}, + {0x122, 0x80, 0x80, 0, 0}, + {0x123, 0, 0, 0, 0}, + {0x124, 0xf8, 0xf8, 0, 0}, + {0x125, 0, 0, 0, 0}, + {0x126, 0, 0, 0, 0}, + {0x127, 0, 0, 0, 0}, + {0x128, 0, 0, 0, 0}, + {0x129, 0, 0, 0, 0}, + {0x12A, 0, 0, 0, 0}, + {0x12B, 0, 0, 0, 0}, + {0x12C, 0, 0, 0, 0}, + {0x12D, 0, 0, 0, 0}, + {0x12E, 0, 0, 0, 0}, + {0x12F, 0, 0, 0, 0}, + {0x130, 0, 0, 0, 0}, + {0xFFFF, 0, 0, 0, 0} +}; + +#define LCNPHY_NUM_DIG_FILT_COEFFS 16 +#define LCNPHY_NUM_TX_DIG_FILTERS_CCK 13 + +u16 + LCNPHY_txdigfiltcoeffs_cck[LCNPHY_NUM_TX_DIG_FILTERS_CCK] + [LCNPHY_NUM_DIG_FILT_COEFFS + 1] = { + {0, 1, 415, 1874, 64, 128, 64, 792, 1656, 64, 128, 64, 778, 1582, 64, + 128, 64,}, + {1, 1, 402, 1847, 259, 59, 259, 671, 1794, 68, 54, 68, 608, 1863, 93, + 167, 93,}, + {2, 1, 415, 1874, 64, 128, 64, 792, 1656, 192, 384, 192, 778, 1582, 64, + 128, 64,}, + {3, 1, 302, 1841, 129, 258, 129, 658, 1720, 205, 410, 205, 754, 1760, + 170, 340, 170,}, + {20, 1, 360, 1884, 242, 1734, 242, 752, 1720, 205, 1845, 205, 767, 1760, + 256, 185, 256,}, + {21, 1, 360, 1884, 149, 1874, 149, 752, 1720, 205, 1883, 205, 767, 1760, + 256, 273, 256,}, + {22, 1, 360, 1884, 98, 1948, 98, 752, 1720, 205, 1924, 205, 767, 1760, + 256, 352, 256,}, + {23, 1, 350, 1884, 116, 1966, 116, 752, 1720, 205, 2008, 205, 767, 1760, + 128, 233, 128,}, + {24, 1, 325, 1884, 32, 40, 32, 756, 1720, 256, 471, 256, 766, 1760, 256, + 1881, 256,}, + {25, 1, 299, 1884, 51, 64, 51, 736, 1720, 256, 471, 256, 765, 1760, 256, + 1881, 256,}, + {26, 1, 277, 1943, 39, 117, 88, 637, 1838, 64, 192, 144, 614, 1864, 128, + 384, 288,}, + {27, 1, 245, 1943, 49, 147, 110, 626, 1838, 256, 768, 576, 613, 1864, + 128, 384, 288,}, + {30, 1, 302, 1841, 61, 122, 61, 658, 1720, 205, 410, 205, 754, 1760, + 170, 340, 170,}, +}; + +#define LCNPHY_NUM_TX_DIG_FILTERS_OFDM 3 +u16 + LCNPHY_txdigfiltcoeffs_ofdm[LCNPHY_NUM_TX_DIG_FILTERS_OFDM] + [LCNPHY_NUM_DIG_FILT_COEFFS + 1] = { + {0, 0, 0xa2, 0x0, 0x100, 0x100, 0x0, 0x0, 0x0, 0x100, 0x0, 0x0, + 0x278, 0xfea0, 0x80, 0x100, 0x80,}, + {1, 0, 374, 0xFF79, 16, 32, 16, 799, 0xFE74, 50, 32, 50, + 750, 0xFE2B, 212, 0xFFCE, 212,}, + {2, 0, 375, 0xFF16, 37, 76, 37, 799, 0xFE74, 32, 20, 32, 748, + 0xFEF2, 128, 0xFFE2, 128} +}; + +#define wlc_lcnphy_set_start_tx_pwr_idx(pi, idx) \ + mod_phy_reg(pi, 0x4a4, \ + (0x1ff << 0), \ + (u16)(idx) << 0) + +#define wlc_lcnphy_set_tx_pwr_npt(pi, npt) \ + mod_phy_reg(pi, 0x4a5, \ + (0x7 << 8), \ + (u16)(npt) << 8) + +#define wlc_lcnphy_get_tx_pwr_ctrl(pi) \ + (read_phy_reg((pi), 0x4a4) & \ + ((0x1 << 15) | \ + (0x1 << 14) | \ + (0x1 << 13))) + +#define wlc_lcnphy_get_tx_pwr_npt(pi) \ + ((read_phy_reg(pi, 0x4a5) & \ + (0x7 << 8)) >> \ + 8) + +#define wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(pi) \ + (read_phy_reg(pi, 0x473) & 0x1ff) + +#define wlc_lcnphy_get_target_tx_pwr(pi) \ + ((read_phy_reg(pi, 0x4a7) & \ + (0xff << 0)) >> \ + 0) + +#define wlc_lcnphy_set_target_tx_pwr(pi, target) \ + mod_phy_reg(pi, 0x4a7, \ + (0xff << 0), \ + (u16)(target) << 0) + +#define wlc_radio_2064_rcal_done(pi) (0 != (read_radio_reg(pi, RADIO_2064_REG05C) & 0x20)) +#define tempsense_done(pi) (0x8000 == (read_phy_reg(pi, 0x476) & 0x8000)) + +#define LCNPHY_IQLOCC_READ(val) ((u8)(-(s8)(((val) & 0xf0) >> 4) + (s8)((val) & 0x0f))) +#define FIXED_TXPWR 78 +#define LCNPHY_TEMPSENSE(val) ((s16)((val > 255) ? (val - 512) : val)) + +static u32 wlc_lcnphy_qdiv_roundup(u32 divident, u32 divisor, + u8 precision); +static void wlc_lcnphy_set_rx_gain_by_distribution(phy_info_t *pi, + u16 ext_lna, u16 trsw, + u16 biq2, u16 biq1, + u16 tia, u16 lna2, + u16 lna1); +static void wlc_lcnphy_clear_tx_power_offsets(phy_info_t *pi); +static void wlc_lcnphy_set_pa_gain(phy_info_t *pi, u16 gain); +static void wlc_lcnphy_set_trsw_override(phy_info_t *pi, bool tx, bool rx); +static void wlc_lcnphy_set_bbmult(phy_info_t *pi, u8 m0); +static u8 wlc_lcnphy_get_bbmult(phy_info_t *pi); +static void wlc_lcnphy_get_tx_gain(phy_info_t *pi, lcnphy_txgains_t *gains); +static void wlc_lcnphy_set_tx_gain_override(phy_info_t *pi, bool bEnable); +static void wlc_lcnphy_toggle_afe_pwdn(phy_info_t *pi); +static void wlc_lcnphy_rx_gain_override_enable(phy_info_t *pi, bool enable); +static void wlc_lcnphy_set_tx_gain(phy_info_t *pi, + lcnphy_txgains_t *target_gains); +static bool wlc_lcnphy_rx_iq_est(phy_info_t *pi, u16 num_samps, + u8 wait_time, lcnphy_iq_est_t *iq_est); +static bool wlc_lcnphy_calc_rx_iq_comp(phy_info_t *pi, u16 num_samps); +static u16 wlc_lcnphy_get_pa_gain(phy_info_t *pi); +static void wlc_lcnphy_afe_clk_init(phy_info_t *pi, u8 mode); +extern void wlc_lcnphy_tx_pwr_ctrl_init(wlc_phy_t *ppi); +static void wlc_lcnphy_radio_2064_channel_tune_4313(phy_info_t *pi, + u8 channel); + +static void wlc_lcnphy_load_tx_gain_table(phy_info_t *pi, + const lcnphy_tx_gain_tbl_entry *g); + +static void wlc_lcnphy_samp_cap(phy_info_t *pi, int clip_detect_algo, + u16 thresh, s16 *ptr, int mode); +static int wlc_lcnphy_calc_floor(s16 coeff, int type); +static void wlc_lcnphy_tx_iqlo_loopback(phy_info_t *pi, + u16 *values_to_save); +static void wlc_lcnphy_tx_iqlo_loopback_cleanup(phy_info_t *pi, + u16 *values_to_save); +static void wlc_lcnphy_set_cc(phy_info_t *pi, int cal_type, s16 coeff_x, + s16 coeff_y); +static lcnphy_unsign16_struct wlc_lcnphy_get_cc(phy_info_t *pi, int cal_type); +static void wlc_lcnphy_a1(phy_info_t *pi, int cal_type, + int num_levels, int step_size_lg2); +static void wlc_lcnphy_tx_iqlo_soft_cal_full(phy_info_t *pi); + +static void wlc_lcnphy_set_chanspec_tweaks(phy_info_t *pi, + chanspec_t chanspec); +static void wlc_lcnphy_agc_temp_init(phy_info_t *pi); +static void wlc_lcnphy_temp_adj(phy_info_t *pi); +static void wlc_lcnphy_clear_papd_comptable(phy_info_t *pi); +static void wlc_lcnphy_baseband_init(phy_info_t *pi); +static void wlc_lcnphy_radio_init(phy_info_t *pi); +static void wlc_lcnphy_rc_cal(phy_info_t *pi); +static void wlc_lcnphy_rcal(phy_info_t *pi); +static void wlc_lcnphy_txrx_spur_avoidance_mode(phy_info_t *pi, bool enable); +static int wlc_lcnphy_load_tx_iir_filter(phy_info_t *pi, bool is_ofdm, + s16 filt_type); +static void wlc_lcnphy_set_rx_iq_comp(phy_info_t *pi, u16 a, u16 b); + +void wlc_lcnphy_write_table(phy_info_t *pi, const phytbl_info_t *pti) +{ + wlc_phy_write_table(pi, pti, 0x455, 0x457, 0x456); +} + +void wlc_lcnphy_read_table(phy_info_t *pi, phytbl_info_t *pti) +{ + wlc_phy_read_table(pi, pti, 0x455, 0x457, 0x456); +} + +static void +wlc_lcnphy_common_read_table(phy_info_t *pi, u32 tbl_id, + const void *tbl_ptr, u32 tbl_len, + u32 tbl_width, u32 tbl_offset) +{ + phytbl_info_t tab; + tab.tbl_id = tbl_id; + tab.tbl_ptr = tbl_ptr; + tab.tbl_len = tbl_len; + tab.tbl_width = tbl_width; + tab.tbl_offset = tbl_offset; + wlc_lcnphy_read_table(pi, &tab); +} + +static void +wlc_lcnphy_common_write_table(phy_info_t *pi, u32 tbl_id, + const void *tbl_ptr, u32 tbl_len, + u32 tbl_width, u32 tbl_offset) +{ + + phytbl_info_t tab; + tab.tbl_id = tbl_id; + tab.tbl_ptr = tbl_ptr; + tab.tbl_len = tbl_len; + tab.tbl_width = tbl_width; + tab.tbl_offset = tbl_offset; + wlc_lcnphy_write_table(pi, &tab); +} + +static u32 +wlc_lcnphy_qdiv_roundup(u32 dividend, u32 divisor, u8 precision) +{ + u32 quotient, remainder, roundup, rbit; + + ASSERT(divisor); + + quotient = dividend / divisor; + remainder = dividend % divisor; + rbit = divisor & 1; + roundup = (divisor >> 1) + rbit; + + while (precision--) { + quotient <<= 1; + if (remainder >= roundup) { + quotient++; + remainder = ((remainder - roundup) << 1) + rbit; + } else { + remainder <<= 1; + } + } + + if (remainder >= roundup) + quotient++; + + return quotient; +} + +static int wlc_lcnphy_calc_floor(s16 coeff_x, int type) +{ + int k; + k = 0; + if (type == 0) { + if (coeff_x < 0) { + k = (coeff_x - 1) / 2; + } else { + k = coeff_x / 2; + } + } + if (type == 1) { + if ((coeff_x + 1) < 0) + k = (coeff_x) / 2; + else + k = (coeff_x + 1) / 2; + } + return k; +} + +s8 wlc_lcnphy_get_current_tx_pwr_idx(phy_info_t *pi) +{ + s8 index; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + if (txpwrctrl_off(pi)) + index = pi_lcn->lcnphy_current_index; + else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) + index = + (s8) (wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(pi) + / 2); + else + index = pi_lcn->lcnphy_current_index; + return index; +} + +static u32 wlc_lcnphy_measure_digital_power(phy_info_t *pi, u16 nsamples) +{ + lcnphy_iq_est_t iq_est = { 0, 0, 0 }; + + if (!wlc_lcnphy_rx_iq_est(pi, nsamples, 32, &iq_est)) + return 0; + return (iq_est.i_pwr + iq_est.q_pwr) / nsamples; +} + +void wlc_lcnphy_crsuprs(phy_info_t *pi, int channel) +{ + u16 afectrlovr, afectrlovrval; + afectrlovr = read_phy_reg(pi, 0x43b); + afectrlovrval = read_phy_reg(pi, 0x43c); + if (channel != 0) { + mod_phy_reg(pi, 0x43b, (0x1 << 1), (1) << 1); + + mod_phy_reg(pi, 0x43c, (0x1 << 1), (0) << 1); + + mod_phy_reg(pi, 0x43b, (0x1 << 4), (1) << 4); + + mod_phy_reg(pi, 0x43c, (0x1 << 6), (0) << 6); + + write_phy_reg(pi, 0x44b, 0xffff); + wlc_lcnphy_tx_pu(pi, 1); + + mod_phy_reg(pi, 0x634, (0xff << 8), (0) << 8); + + or_phy_reg(pi, 0x6da, 0x0080); + + or_phy_reg(pi, 0x00a, 0x228); + } else { + and_phy_reg(pi, 0x00a, ~(0x228)); + + and_phy_reg(pi, 0x6da, 0xFF7F); + write_phy_reg(pi, 0x43b, afectrlovr); + write_phy_reg(pi, 0x43c, afectrlovrval); + } +} + +static void wlc_lcnphy_toggle_afe_pwdn(phy_info_t *pi) +{ + u16 save_AfeCtrlOvrVal, save_AfeCtrlOvr; + + save_AfeCtrlOvrVal = read_phy_reg(pi, 0x43c); + save_AfeCtrlOvr = read_phy_reg(pi, 0x43b); + + write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal | 0x1); + write_phy_reg(pi, 0x43b, save_AfeCtrlOvr | 0x1); + + write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal & 0xfffe); + write_phy_reg(pi, 0x43b, save_AfeCtrlOvr & 0xfffe); + + write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal); + write_phy_reg(pi, 0x43b, save_AfeCtrlOvr); +} + +static void wlc_lcnphy_txrx_spur_avoidance_mode(phy_info_t *pi, bool enable) +{ + if (enable) { + write_phy_reg(pi, 0x942, 0x7); + write_phy_reg(pi, 0x93b, ((1 << 13) + 23)); + write_phy_reg(pi, 0x93c, ((1 << 13) + 1989)); + + write_phy_reg(pi, 0x44a, 0x084); + write_phy_reg(pi, 0x44a, 0x080); + write_phy_reg(pi, 0x6d3, 0x2222); + write_phy_reg(pi, 0x6d3, 0x2220); + } else { + write_phy_reg(pi, 0x942, 0x0); + write_phy_reg(pi, 0x93b, ((0 << 13) + 23)); + write_phy_reg(pi, 0x93c, ((0 << 13) + 1989)); + } + wlapi_switch_macfreq(pi->sh->physhim, enable); +} + +void wlc_phy_chanspec_set_lcnphy(phy_info_t *pi, chanspec_t chanspec) +{ + u8 channel = CHSPEC_CHANNEL(chanspec); + + wlc_phy_chanspec_radio_set((wlc_phy_t *) pi, chanspec); + + wlc_lcnphy_set_chanspec_tweaks(pi, pi->radio_chanspec); + + or_phy_reg(pi, 0x44a, 0x44); + write_phy_reg(pi, 0x44a, 0x80); + + if (!NORADIO_ENAB(pi->pubpi)) { + wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel); + udelay(1000); + } + + wlc_lcnphy_toggle_afe_pwdn(pi); + + write_phy_reg(pi, 0x657, lcnphy_sfo_cfg[channel - 1].ptcentreTs20); + write_phy_reg(pi, 0x658, lcnphy_sfo_cfg[channel - 1].ptcentreFactor); + + if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) { + mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8); + + wlc_lcnphy_load_tx_iir_filter(pi, false, 3); + } else { + mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8); + + wlc_lcnphy_load_tx_iir_filter(pi, false, 2); + } + + wlc_lcnphy_load_tx_iir_filter(pi, true, 0); + + mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3); + +} + +static void wlc_lcnphy_set_dac_gain(phy_info_t *pi, u16 dac_gain) +{ + u16 dac_ctrl; + + dac_ctrl = (read_phy_reg(pi, 0x439) >> 0); + dac_ctrl = dac_ctrl & 0xc7f; + dac_ctrl = dac_ctrl | (dac_gain << 7); + mod_phy_reg(pi, 0x439, (0xfff << 0), (dac_ctrl) << 0); + +} + +static void wlc_lcnphy_set_tx_gain_override(phy_info_t *pi, bool bEnable) +{ + u16 bit = bEnable ? 1 : 0; + + mod_phy_reg(pi, 0x4b0, (0x1 << 7), bit << 7); + + mod_phy_reg(pi, 0x4b0, (0x1 << 14), bit << 14); + + mod_phy_reg(pi, 0x43b, (0x1 << 6), bit << 6); +} + +static u16 wlc_lcnphy_get_pa_gain(phy_info_t *pi) +{ + u16 pa_gain; + + pa_gain = (read_phy_reg(pi, 0x4fb) & + LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK) >> + LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT; + + return pa_gain; +} + +static void +wlc_lcnphy_set_tx_gain(phy_info_t *pi, lcnphy_txgains_t *target_gains) +{ + u16 pa_gain = wlc_lcnphy_get_pa_gain(pi); + + mod_phy_reg(pi, 0x4b5, + (0xffff << 0), + ((target_gains->gm_gain) | (target_gains->pga_gain << 8)) << + 0); + mod_phy_reg(pi, 0x4fb, + (0x7fff << 0), + ((target_gains->pad_gain) | (pa_gain << 8)) << 0); + + mod_phy_reg(pi, 0x4fc, + (0xffff << 0), + ((target_gains->gm_gain) | (target_gains->pga_gain << 8)) << + 0); + mod_phy_reg(pi, 0x4fd, + (0x7fff << 0), + ((target_gains->pad_gain) | (pa_gain << 8)) << 0); + + wlc_lcnphy_set_dac_gain(pi, target_gains->dac_gain); + + wlc_lcnphy_enable_tx_gain_override(pi); +} + +static void wlc_lcnphy_set_bbmult(phy_info_t *pi, u8 m0) +{ + u16 m0m1 = (u16) m0 << 8; + phytbl_info_t tab; + + tab.tbl_ptr = &m0m1; + tab.tbl_len = 1; + tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL; + tab.tbl_offset = 87; + tab.tbl_width = 16; + wlc_lcnphy_write_table(pi, &tab); +} + +static void wlc_lcnphy_clear_tx_power_offsets(phy_info_t *pi) +{ + u32 data_buf[64]; + phytbl_info_t tab; + + memset(data_buf, 0, sizeof(data_buf)); + + tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; + tab.tbl_width = 32; + tab.tbl_ptr = data_buf; + + if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) { + + tab.tbl_len = 30; + tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET; + wlc_lcnphy_write_table(pi, &tab); + } + + tab.tbl_len = 64; + tab.tbl_offset = LCNPHY_TX_PWR_CTRL_MAC_OFFSET; + wlc_lcnphy_write_table(pi, &tab); +} + +typedef enum { + LCNPHY_TSSI_PRE_PA, + LCNPHY_TSSI_POST_PA, + LCNPHY_TSSI_EXT +} lcnphy_tssi_mode_t; + +static void wlc_lcnphy_set_tssi_mux(phy_info_t *pi, lcnphy_tssi_mode_t pos) +{ + mod_phy_reg(pi, 0x4d7, (0x1 << 0), (0x1) << 0); + + mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1) << 6); + + if (LCNPHY_TSSI_POST_PA == pos) { + mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0) << 2); + + mod_phy_reg(pi, 0x4d9, (0x1 << 3), (1) << 3); + + if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { + mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4); + } else { + mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1); + mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8); + } + } else { + mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2); + + mod_phy_reg(pi, 0x4d9, (0x1 << 3), (0) << 3); + + if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { + mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4); + } else { + mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0); + mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8); + } + } + mod_phy_reg(pi, 0x637, (0x3 << 14), (0) << 14); + + if (LCNPHY_TSSI_EXT == pos) { + write_radio_reg(pi, RADIO_2064_REG07F, 1); + mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 0x2); + mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 0x1 << 7); + mod_radio_reg(pi, RADIO_2064_REG028, 0x1f, 0x3); + } +} + +static u16 wlc_lcnphy_rfseq_tbl_adc_pwrup(phy_info_t *pi) +{ + u16 N1, N2, N3, N4, N5, N6, N; + N1 = ((read_phy_reg(pi, 0x4a5) & (0xff << 0)) + >> 0); + N2 = 1 << ((read_phy_reg(pi, 0x4a5) & (0x7 << 12)) + >> 12); + N3 = ((read_phy_reg(pi, 0x40d) & (0xff << 0)) + >> 0); + N4 = 1 << ((read_phy_reg(pi, 0x40d) & (0x7 << 8)) + >> 8); + N5 = ((read_phy_reg(pi, 0x4a2) & (0xff << 0)) + >> 0); + N6 = 1 << ((read_phy_reg(pi, 0x4a2) & (0x7 << 8)) + >> 8); + N = 2 * (N1 + N2 + N3 + N4 + 2 * (N5 + N6)) + 80; + if (N < 1600) + N = 1600; + return N; +} + +static void wlc_lcnphy_pwrctrl_rssiparams(phy_info_t *pi) +{ + u16 auxpga_vmid, auxpga_vmid_temp, auxpga_gain_temp; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + auxpga_vmid = + (2 << 8) | (pi_lcn->lcnphy_rssi_vc << 4) | pi_lcn->lcnphy_rssi_vf; + auxpga_vmid_temp = (2 << 8) | (8 << 4) | 4; + auxpga_gain_temp = 2; + + mod_phy_reg(pi, 0x4d8, (0x1 << 0), (0) << 0); + + mod_phy_reg(pi, 0x4d8, (0x1 << 1), (0) << 1); + + mod_phy_reg(pi, 0x4d7, (0x1 << 3), (0) << 3); + + mod_phy_reg(pi, 0x4db, + (0x3ff << 0) | + (0x7 << 12), + (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12)); + + mod_phy_reg(pi, 0x4dc, + (0x3ff << 0) | + (0x7 << 12), + (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12)); + + mod_phy_reg(pi, 0x40a, + (0x3ff << 0) | + (0x7 << 12), + (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12)); + + mod_phy_reg(pi, 0x40b, + (0x3ff << 0) | + (0x7 << 12), + (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12)); + + mod_phy_reg(pi, 0x40c, + (0x3ff << 0) | + (0x7 << 12), + (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12)); + + mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5)); +} + +static void wlc_lcnphy_tssi_setup(phy_info_t *pi) +{ + phytbl_info_t tab; + u32 rfseq, ind; + + tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; + tab.tbl_width = 32; + tab.tbl_ptr = &ind; + tab.tbl_len = 1; + tab.tbl_offset = 0; + for (ind = 0; ind < 128; ind++) { + wlc_lcnphy_write_table(pi, &tab); + tab.tbl_offset++; + } + tab.tbl_offset = 704; + for (ind = 0; ind < 128; ind++) { + wlc_lcnphy_write_table(pi, &tab); + tab.tbl_offset++; + } + mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0); + + mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2); + + mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4); + + wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT); + mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14); + + mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15); + + mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5); + + mod_phy_reg(pi, 0x4a4, (0x1ff << 0), (0) << 0); + + mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0); + + mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12); + + mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8); + + mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0); + + mod_phy_reg(pi, 0x40d, (0x7 << 8), (4) << 8); + + mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0); + + mod_phy_reg(pi, 0x4a2, (0x7 << 8), (4) << 8); + + mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (0) << 6); + + mod_phy_reg(pi, 0x4a8, (0xff << 0), (0x1) << 0); + + wlc_lcnphy_clear_tx_power_offsets(pi); + + mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15); + + mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (0xff) << 0); + + mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0); + + if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { + mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe); + mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4); + } else { + mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1); + mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3); + } + + write_radio_reg(pi, RADIO_2064_REG025, 0xc); + + if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { + mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1); + } else { + if (CHSPEC_IS2G(pi->radio_chanspec)) + mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1); + else + mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 0 << 1); + } + + if (LCNREV_IS(pi->pubpi.phy_rev, 2)) + mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1); + else + mod_radio_reg(pi, RADIO_2064_REG03A, 0x4, 1 << 2); + + mod_radio_reg(pi, RADIO_2064_REG11A, 0x1, 1 << 0); + + mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 1 << 3); + + if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) { + mod_phy_reg(pi, 0x4d7, + (0x1 << 3) | (0x7 << 12), 0 << 3 | 2 << 12); + } + + rfseq = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi); + tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; + tab.tbl_width = 16; + tab.tbl_ptr = &rfseq; + tab.tbl_len = 1; + tab.tbl_offset = 6; + wlc_lcnphy_write_table(pi, &tab); + + mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2); + + mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2); + + mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12); + + mod_phy_reg(pi, 0x4d7, (0x1 << 2), (1) << 2); + + mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8); + + wlc_lcnphy_pwrctrl_rssiparams(pi); +} + +void wlc_lcnphy_tx_pwr_update_npt(phy_info_t *pi) +{ + u16 tx_cnt, tx_total, npt; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + tx_total = wlc_lcnphy_total_tx_frames(pi); + tx_cnt = tx_total - pi_lcn->lcnphy_tssi_tx_cnt; + npt = wlc_lcnphy_get_tx_pwr_npt(pi); + + if (tx_cnt > (1 << npt)) { + + pi_lcn->lcnphy_tssi_tx_cnt = tx_total; + + pi_lcn->lcnphy_tssi_idx = wlc_lcnphy_get_current_tx_pwr_idx(pi); + pi_lcn->lcnphy_tssi_npt = npt; + + } +} + +s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1) +{ + s32 a, b, p; + + a = 32768 + (a1 * tssi); + b = (1024 * b0) + (64 * b1 * tssi); + p = ((2 * b) + a) / (2 * a); + + return p; +} + +static void wlc_lcnphy_txpower_reset_npt(phy_info_t *pi) +{ + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) + return; + + pi_lcn->lcnphy_tssi_idx = LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313; + pi_lcn->lcnphy_tssi_npt = LCNPHY_TX_PWR_CTRL_START_NPT; +} + +void wlc_lcnphy_txpower_recalc_target(phy_info_t *pi) +{ + phytbl_info_t tab; + u32 rate_table[WLC_NUM_RATES_CCK + WLC_NUM_RATES_OFDM + + WLC_NUM_RATES_MCS_1_STREAM]; + uint i, j; + if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) + return; + + for (i = 0, j = 0; i < ARRAY_SIZE(rate_table); i++, j++) { + + if (i == WLC_NUM_RATES_CCK + WLC_NUM_RATES_OFDM) + j = TXP_FIRST_MCS_20_SISO; + + rate_table[i] = (u32) ((s32) (-pi->tx_power_offset[j])); + } + + tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; + tab.tbl_width = 32; + tab.tbl_len = ARRAY_SIZE(rate_table); + tab.tbl_ptr = rate_table; + tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET; + wlc_lcnphy_write_table(pi, &tab); + + if (wlc_lcnphy_get_target_tx_pwr(pi) != pi->tx_power_min) { + wlc_lcnphy_set_target_tx_pwr(pi, pi->tx_power_min); + + wlc_lcnphy_txpower_reset_npt(pi); + } +} + +static void wlc_lcnphy_set_tx_pwr_soft_ctrl(phy_info_t *pi, s8 index) +{ + u32 cck_offset[4] = { 22, 22, 22, 22 }; + u32 ofdm_offset, reg_offset_cck; + int i; + u16 index2; + phytbl_info_t tab; + + if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) + return; + + mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14); + + mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x0) << 14); + + or_phy_reg(pi, 0x6da, 0x0040); + + reg_offset_cck = 0; + for (i = 0; i < 4; i++) + cck_offset[i] -= reg_offset_cck; + tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; + tab.tbl_width = 32; + tab.tbl_len = 4; + tab.tbl_ptr = cck_offset; + tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET; + wlc_lcnphy_write_table(pi, &tab); + ofdm_offset = 0; + tab.tbl_len = 1; + tab.tbl_ptr = &ofdm_offset; + for (i = 836; i < 862; i++) { + tab.tbl_offset = i; + wlc_lcnphy_write_table(pi, &tab); + } + + mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0x1) << 15); + + mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14); + + mod_phy_reg(pi, 0x4a4, (0x1 << 13), (0x1) << 13); + + mod_phy_reg(pi, 0x4b0, (0x1 << 7), (0) << 7); + + mod_phy_reg(pi, 0x43b, (0x1 << 6), (0) << 6); + + mod_phy_reg(pi, 0x4a9, (0x1 << 15), (1) << 15); + + index2 = (u16) (index * 2); + mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0); + + mod_phy_reg(pi, 0x6a3, (0x1 << 4), (0) << 4); + +} + +static s8 wlc_lcnphy_tempcompensated_txpwrctrl(phy_info_t *pi) +{ + s8 index, delta_brd, delta_temp, new_index, tempcorrx; + s16 manp, meas_temp, temp_diff; + bool neg = 0; + u16 temp; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) + return pi_lcn->lcnphy_current_index; + + index = FIXED_TXPWR; + + if (NORADIO_ENAB(pi->pubpi)) + return index; + + if (pi_lcn->lcnphy_tempsense_slope == 0) { + return index; + } + temp = (u16) wlc_lcnphy_tempsense(pi, 0); + meas_temp = LCNPHY_TEMPSENSE(temp); + + if (pi->tx_power_min != 0) { + delta_brd = (pi_lcn->lcnphy_measPower - pi->tx_power_min); + } else { + delta_brd = 0; + } + + manp = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_rawtempsense); + temp_diff = manp - meas_temp; + if (temp_diff < 0) { + + neg = 1; + + temp_diff = -temp_diff; + } + + delta_temp = (s8) wlc_lcnphy_qdiv_roundup((u32) (temp_diff * 192), + (u32) (pi_lcn-> + lcnphy_tempsense_slope + * 10), 0); + if (neg) + delta_temp = -delta_temp; + + if (pi_lcn->lcnphy_tempsense_option == 3 + && LCNREV_IS(pi->pubpi.phy_rev, 0)) + delta_temp = 0; + if (pi_lcn->lcnphy_tempcorrx > 31) + tempcorrx = (s8) (pi_lcn->lcnphy_tempcorrx - 64); + else + tempcorrx = (s8) pi_lcn->lcnphy_tempcorrx; + if (LCNREV_IS(pi->pubpi.phy_rev, 1)) + tempcorrx = 4; + new_index = + index + delta_brd + delta_temp - pi_lcn->lcnphy_bandedge_corr; + new_index += tempcorrx; + + if (LCNREV_IS(pi->pubpi.phy_rev, 1)) + index = 127; + if (new_index < 0 || new_index > 126) { + return index; + } + return new_index; +} + +static u16 wlc_lcnphy_set_tx_pwr_ctrl_mode(phy_info_t *pi, u16 mode) +{ + + u16 current_mode = mode; + if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) && + mode == LCNPHY_TX_PWR_CTRL_HW) + current_mode = LCNPHY_TX_PWR_CTRL_TEMPBASED; + if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) && + mode == LCNPHY_TX_PWR_CTRL_TEMPBASED) + current_mode = LCNPHY_TX_PWR_CTRL_HW; + return current_mode; +} + +void wlc_lcnphy_set_tx_pwr_ctrl(phy_info_t *pi, u16 mode) +{ + u16 old_mode = wlc_lcnphy_get_tx_pwr_ctrl(pi); + s8 index; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + ASSERT((LCNPHY_TX_PWR_CTRL_OFF == mode) || + (LCNPHY_TX_PWR_CTRL_SW == mode) || + (LCNPHY_TX_PWR_CTRL_HW == mode) || + (LCNPHY_TX_PWR_CTRL_TEMPBASED == mode)); + + mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, mode); + old_mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, old_mode); + + mod_phy_reg(pi, 0x6da, (0x1 << 6), + ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 1 : 0) << 6); + + mod_phy_reg(pi, 0x6a3, (0x1 << 4), + ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 0 : 1) << 4); + + if (old_mode != mode) { + if (LCNPHY_TX_PWR_CTRL_HW == old_mode) { + + wlc_lcnphy_tx_pwr_update_npt(pi); + + wlc_lcnphy_clear_tx_power_offsets(pi); + } + if (LCNPHY_TX_PWR_CTRL_HW == mode) { + + wlc_lcnphy_txpower_recalc_target(pi); + + wlc_lcnphy_set_start_tx_pwr_idx(pi, + pi_lcn-> + lcnphy_tssi_idx); + wlc_lcnphy_set_tx_pwr_npt(pi, pi_lcn->lcnphy_tssi_npt); + mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0); + + pi_lcn->lcnphy_tssi_tx_cnt = + wlc_lcnphy_total_tx_frames(pi); + + wlc_lcnphy_disable_tx_gain_override(pi); + pi_lcn->lcnphy_tx_power_idx_override = -1; + } else + wlc_lcnphy_enable_tx_gain_override(pi); + + mod_phy_reg(pi, 0x4a4, + ((0x1 << 15) | (0x1 << 14) | (0x1 << 13)), mode); + if (mode == LCNPHY_TX_PWR_CTRL_TEMPBASED) { + index = wlc_lcnphy_tempcompensated_txpwrctrl(pi); + wlc_lcnphy_set_tx_pwr_soft_ctrl(pi, index); + pi_lcn->lcnphy_current_index = (s8) + ((read_phy_reg(pi, 0x4a9) & 0xFF) / 2); + } + } +} + +static bool wlc_lcnphy_iqcal_wait(phy_info_t *pi) +{ + uint delay_count = 0; + + while (wlc_lcnphy_iqcal_active(pi)) { + udelay(100); + delay_count++; + + if (delay_count > (10 * 500)) + break; + } + + return (0 == wlc_lcnphy_iqcal_active(pi)); +} + +static void +wlc_lcnphy_tx_iqlo_cal(phy_info_t *pi, + lcnphy_txgains_t *target_gains, + lcnphy_cal_mode_t cal_mode, bool keep_tone) +{ + + lcnphy_txgains_t cal_gains, temp_gains; + u16 hash; + u8 band_idx; + int j; + u16 ncorr_override[5]; + u16 syst_coeffs[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 + }; + + u16 commands_fullcal[] = { + 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234 }; + + u16 commands_recal[] = { + 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234 }; + + u16 command_nums_fullcal[] = { + 0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97 }; + + u16 command_nums_recal[] = { + 0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97 }; + u16 *command_nums = command_nums_fullcal; + + u16 *start_coeffs = NULL, *cal_cmds = NULL, cal_type, diq_start; + u16 tx_pwr_ctrl_old, save_txpwrctrlrfctrl2; + u16 save_sslpnCalibClkEnCtrl, save_sslpnRxFeClkEnCtrl; + bool tx_gain_override_old; + lcnphy_txgains_t old_gains; + uint i, n_cal_cmds = 0, n_cal_start = 0; + u16 *values_to_save; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + if (NORADIO_ENAB(pi->pubpi)) + return; + + values_to_save = kmalloc(sizeof(u16) * 20, GFP_ATOMIC); + if (NULL == values_to_save) { + return; + } + + save_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db); + save_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); + + or_phy_reg(pi, 0x6da, 0x40); + or_phy_reg(pi, 0x6db, 0x3); + + switch (cal_mode) { + case LCNPHY_CAL_FULL: + start_coeffs = syst_coeffs; + cal_cmds = commands_fullcal; + n_cal_cmds = ARRAY_SIZE(commands_fullcal); + break; + + case LCNPHY_CAL_RECAL: + ASSERT(pi_lcn->lcnphy_cal_results.txiqlocal_bestcoeffs_valid); + + start_coeffs = syst_coeffs; + + cal_cmds = commands_recal; + n_cal_cmds = ARRAY_SIZE(commands_recal); + command_nums = command_nums_recal; + break; + default: + ASSERT(false); + } + + wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, + start_coeffs, 11, 16, 64); + + write_phy_reg(pi, 0x6da, 0xffff); + mod_phy_reg(pi, 0x503, (0x1 << 3), (1) << 3); + + tx_pwr_ctrl_old = wlc_lcnphy_get_tx_pwr_ctrl(pi); + + mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12); + + wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); + + save_txpwrctrlrfctrl2 = read_phy_reg(pi, 0x4db); + + mod_phy_reg(pi, 0x4db, (0x3ff << 0), (0x2a6) << 0); + + mod_phy_reg(pi, 0x4db, (0x7 << 12), (2) << 12); + + wlc_lcnphy_tx_iqlo_loopback(pi, values_to_save); + + tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi); + if (tx_gain_override_old) + wlc_lcnphy_get_tx_gain(pi, &old_gains); + + if (!target_gains) { + if (!tx_gain_override_old) + wlc_lcnphy_set_tx_pwr_by_index(pi, + pi_lcn->lcnphy_tssi_idx); + wlc_lcnphy_get_tx_gain(pi, &temp_gains); + target_gains = &temp_gains; + } + + hash = (target_gains->gm_gain << 8) | + (target_gains->pga_gain << 4) | (target_gains->pad_gain); + + band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0); + + cal_gains = *target_gains; + memset(ncorr_override, 0, sizeof(ncorr_override)); + for (j = 0; j < iqcal_gainparams_numgains_lcnphy[band_idx]; j++) { + if (hash == tbl_iqcal_gainparams_lcnphy[band_idx][j][0]) { + cal_gains.gm_gain = + tbl_iqcal_gainparams_lcnphy[band_idx][j][1]; + cal_gains.pga_gain = + tbl_iqcal_gainparams_lcnphy[band_idx][j][2]; + cal_gains.pad_gain = + tbl_iqcal_gainparams_lcnphy[band_idx][j][3]; + bcopy(&tbl_iqcal_gainparams_lcnphy[band_idx][j][3], + ncorr_override, sizeof(ncorr_override)); + break; + } + } + + wlc_lcnphy_set_tx_gain(pi, &cal_gains); + + write_phy_reg(pi, 0x453, 0xaa9); + write_phy_reg(pi, 0x93d, 0xc0); + + wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, + (const void *) + lcnphy_iqcal_loft_gainladder, + ARRAY_SIZE(lcnphy_iqcal_loft_gainladder), + 16, 0); + + wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, + (const void *)lcnphy_iqcal_ir_gainladder, + ARRAY_SIZE(lcnphy_iqcal_ir_gainladder), 16, + 32); + + if (pi->phy_tx_tone_freq) { + + wlc_lcnphy_stop_tx_tone(pi); + udelay(5); + wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1); + } else { + wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1); + } + + write_phy_reg(pi, 0x6da, 0xffff); + + for (i = n_cal_start; i < n_cal_cmds; i++) { + u16 zero_diq = 0; + u16 best_coeffs[11]; + u16 command_num; + + cal_type = (cal_cmds[i] & 0x0f00) >> 8; + + command_num = command_nums[i]; + if (ncorr_override[cal_type]) + command_num = + ncorr_override[cal_type] << 8 | (command_num & + 0xff); + + write_phy_reg(pi, 0x452, command_num); + + if ((cal_type == 3) || (cal_type == 4)) { + + wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL, + &diq_start, 1, 16, 69); + + wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, + &zero_diq, 1, 16, 69); + } + + write_phy_reg(pi, 0x451, cal_cmds[i]); + + if (!wlc_lcnphy_iqcal_wait(pi)) { + + goto cleanup; + } + + wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL, + best_coeffs, + ARRAY_SIZE(best_coeffs), 16, 96); + wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, + best_coeffs, + ARRAY_SIZE(best_coeffs), 16, 64); + + if ((cal_type == 3) || (cal_type == 4)) { + wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, + &diq_start, 1, 16, 69); + } + wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL, + pi_lcn->lcnphy_cal_results. + txiqlocal_bestcoeffs, + ARRAY_SIZE(pi_lcn-> + lcnphy_cal_results. + txiqlocal_bestcoeffs), + 16, 96); + } + + wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL, + pi_lcn->lcnphy_cal_results. + txiqlocal_bestcoeffs, + ARRAY_SIZE(pi_lcn->lcnphy_cal_results. + txiqlocal_bestcoeffs), 16, 96); + pi_lcn->lcnphy_cal_results.txiqlocal_bestcoeffs_valid = true; + + wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, + &pi_lcn->lcnphy_cal_results. + txiqlocal_bestcoeffs[0], 4, 16, 80); + + wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, + &pi_lcn->lcnphy_cal_results. + txiqlocal_bestcoeffs[5], 2, 16, 85); + + cleanup: + wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, values_to_save); + kfree(values_to_save); + + if (!keep_tone) + wlc_lcnphy_stop_tx_tone(pi); + + write_phy_reg(pi, 0x4db, save_txpwrctrlrfctrl2); + + write_phy_reg(pi, 0x453, 0); + + if (tx_gain_override_old) + wlc_lcnphy_set_tx_gain(pi, &old_gains); + wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl_old); + + write_phy_reg(pi, 0x6da, save_sslpnCalibClkEnCtrl); + write_phy_reg(pi, 0x6db, save_sslpnRxFeClkEnCtrl); + +} + +static void wlc_lcnphy_idle_tssi_est(wlc_phy_t *ppi) +{ + bool suspend, tx_gain_override_old; + lcnphy_txgains_t old_gains; + phy_info_t *pi = (phy_info_t *) ppi; + u16 idleTssi, idleTssi0_2C, idleTssi0_OB, idleTssi0_regvalue_OB, + idleTssi0_regvalue_2C; + u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); + u16 SAVE_lpfgain = read_radio_reg(pi, RADIO_2064_REG112); + u16 SAVE_jtag_bb_afe_switch = + read_radio_reg(pi, RADIO_2064_REG007) & 1; + u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10; + u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4; + idleTssi = read_phy_reg(pi, 0x4ab); + suspend = + (0 == + (R_REG(pi->sh->osh, &((phy_info_t *) pi)->regs->maccontrol) & + MCTL_EN_MAC)); + if (!suspend) + wlapi_suspend_mac_and_wait(pi->sh->physhim); + wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); + + tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi); + wlc_lcnphy_get_tx_gain(pi, &old_gains); + + wlc_lcnphy_enable_tx_gain_override(pi); + wlc_lcnphy_set_tx_pwr_by_index(pi, 127); + write_radio_reg(pi, RADIO_2064_REG112, 0x6); + mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 1); + mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4); + mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2); + wlc_lcnphy_tssi_setup(pi); + wlc_phy_do_dummy_tx(pi, true, OFF); + idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0)) + >> 0); + + idleTssi0_2C = ((read_phy_reg(pi, 0x63e) & (0x1ff << 0)) + >> 0); + + if (idleTssi0_2C >= 256) + idleTssi0_OB = idleTssi0_2C - 256; + else + idleTssi0_OB = idleTssi0_2C + 256; + + idleTssi0_regvalue_OB = idleTssi0_OB; + if (idleTssi0_regvalue_OB >= 256) + idleTssi0_regvalue_2C = idleTssi0_regvalue_OB - 256; + else + idleTssi0_regvalue_2C = idleTssi0_regvalue_OB + 256; + mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (idleTssi0_regvalue_2C) << 0); + + mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12); + + wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old); + wlc_lcnphy_set_tx_gain(pi, &old_gains); + wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl); + + write_radio_reg(pi, RADIO_2064_REG112, SAVE_lpfgain); + mod_radio_reg(pi, RADIO_2064_REG007, 0x1, SAVE_jtag_bb_afe_switch); + mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, SAVE_jtag_auxpga); + mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, SAVE_iqadc_aux_en); + mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1 << 7); + if (!suspend) + wlapi_enable_mac(pi->sh->physhim); +} + +static void wlc_lcnphy_vbat_temp_sense_setup(phy_info_t *pi, u8 mode) +{ + bool suspend; + u16 save_txpwrCtrlEn; + u8 auxpga_vmidcourse, auxpga_vmidfine, auxpga_gain; + u16 auxpga_vmid; + phytbl_info_t tab; + u32 val; + u8 save_reg007, save_reg0FF, save_reg11F, save_reg005, save_reg025, + save_reg112; + u16 values_to_save[14]; + s8 index; + int i; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + udelay(999); + + save_reg007 = (u8) read_radio_reg(pi, RADIO_2064_REG007); + save_reg0FF = (u8) read_radio_reg(pi, RADIO_2064_REG0FF); + save_reg11F = (u8) read_radio_reg(pi, RADIO_2064_REG11F); + save_reg005 = (u8) read_radio_reg(pi, RADIO_2064_REG005); + save_reg025 = (u8) read_radio_reg(pi, RADIO_2064_REG025); + save_reg112 = (u8) read_radio_reg(pi, RADIO_2064_REG112); + + for (i = 0; i < 14; i++) + values_to_save[i] = read_phy_reg(pi, tempsense_phy_regs[i]); + suspend = + (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + if (!suspend) + wlapi_suspend_mac_and_wait(pi->sh->physhim); + save_txpwrCtrlEn = read_radio_reg(pi, 0x4a4); + + wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); + index = pi_lcn->lcnphy_current_index; + wlc_lcnphy_set_tx_pwr_by_index(pi, 127); + mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 0x1); + mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 0x1 << 4); + mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0x1 << 2); + mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0); + + mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2); + + mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14); + + mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0) << 15); + + mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5); + + mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0); + + mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12); + + mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8); + + mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0); + + mod_phy_reg(pi, 0x40d, (0x7 << 8), (6) << 8); + + mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0); + + mod_phy_reg(pi, 0x4a2, (0x7 << 8), (6) << 8); + + mod_phy_reg(pi, 0x4d9, (0x7 << 4), (2) << 4); + + mod_phy_reg(pi, 0x4d9, (0x7 << 8), (3) << 8); + + mod_phy_reg(pi, 0x4d9, (0x7 << 12), (1) << 12); + + mod_phy_reg(pi, 0x4da, (0x1 << 12), (0) << 12); + + mod_phy_reg(pi, 0x4da, (0x1 << 13), (1) << 13); + + mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15); + + write_radio_reg(pi, RADIO_2064_REG025, 0xC); + + mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 0x1 << 3); + + mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2); + + mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2); + + mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12); + + val = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi); + tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; + tab.tbl_width = 16; + tab.tbl_len = 1; + tab.tbl_ptr = &val; + tab.tbl_offset = 6; + wlc_lcnphy_write_table(pi, &tab); + if (mode == TEMPSENSE) { + mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3); + + mod_phy_reg(pi, 0x4d7, (0x7 << 12), (1) << 12); + + auxpga_vmidcourse = 8; + auxpga_vmidfine = 0x4; + auxpga_gain = 2; + mod_radio_reg(pi, RADIO_2064_REG082, 0x20, 1 << 5); + } else { + mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3); + + mod_phy_reg(pi, 0x4d7, (0x7 << 12), (3) << 12); + + auxpga_vmidcourse = 7; + auxpga_vmidfine = 0xa; + auxpga_gain = 2; + } + auxpga_vmid = + (u16) ((2 << 8) | (auxpga_vmidcourse << 4) | auxpga_vmidfine); + mod_phy_reg(pi, 0x4d8, (0x1 << 0), (1) << 0); + + mod_phy_reg(pi, 0x4d8, (0x3ff << 2), (auxpga_vmid) << 2); + + mod_phy_reg(pi, 0x4d8, (0x1 << 1), (1) << 1); + + mod_phy_reg(pi, 0x4d8, (0x7 << 12), (auxpga_gain) << 12); + + mod_phy_reg(pi, 0x4d0, (0x1 << 5), (1) << 5); + + write_radio_reg(pi, RADIO_2064_REG112, 0x6); + + wlc_phy_do_dummy_tx(pi, true, OFF); + if (!tempsense_done(pi)) + udelay(10); + + write_radio_reg(pi, RADIO_2064_REG007, (u16) save_reg007); + write_radio_reg(pi, RADIO_2064_REG0FF, (u16) save_reg0FF); + write_radio_reg(pi, RADIO_2064_REG11F, (u16) save_reg11F); + write_radio_reg(pi, RADIO_2064_REG005, (u16) save_reg005); + write_radio_reg(pi, RADIO_2064_REG025, (u16) save_reg025); + write_radio_reg(pi, RADIO_2064_REG112, (u16) save_reg112); + for (i = 0; i < 14; i++) + write_phy_reg(pi, tempsense_phy_regs[i], values_to_save[i]); + wlc_lcnphy_set_tx_pwr_by_index(pi, (int)index); + + write_radio_reg(pi, 0x4a4, save_txpwrCtrlEn); + if (!suspend) + wlapi_enable_mac(pi->sh->physhim); + udelay(999); +} + +void WLBANDINITFN(wlc_lcnphy_tx_pwr_ctrl_init) (wlc_phy_t *ppi) +{ + lcnphy_txgains_t tx_gains; + u8 bbmult; + phytbl_info_t tab; + s32 a1, b0, b1; + s32 tssi, pwr, maxtargetpwr, mintargetpwr; + bool suspend; + phy_info_t *pi = (phy_info_t *) ppi; + + suspend = + (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + if (!suspend) + wlapi_suspend_mac_and_wait(pi->sh->physhim); + + if (NORADIO_ENAB(pi->pubpi)) { + wlc_lcnphy_set_bbmult(pi, 0x30); + if (!suspend) + wlapi_enable_mac(pi->sh->physhim); + return; + } + + if (!pi->hwpwrctrl_capable) { + if (CHSPEC_IS2G(pi->radio_chanspec)) { + tx_gains.gm_gain = 4; + tx_gains.pga_gain = 12; + tx_gains.pad_gain = 12; + tx_gains.dac_gain = 0; + + bbmult = 150; + } else { + tx_gains.gm_gain = 7; + tx_gains.pga_gain = 15; + tx_gains.pad_gain = 14; + tx_gains.dac_gain = 0; + + bbmult = 150; + } + wlc_lcnphy_set_tx_gain(pi, &tx_gains); + wlc_lcnphy_set_bbmult(pi, bbmult); + wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE); + } else { + + wlc_lcnphy_idle_tssi_est(ppi); + + wlc_lcnphy_clear_tx_power_offsets(pi); + + b0 = pi->txpa_2g[0]; + b1 = pi->txpa_2g[1]; + a1 = pi->txpa_2g[2]; + maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1); + mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1); + + tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; + tab.tbl_width = 32; + tab.tbl_ptr = &pwr; + tab.tbl_len = 1; + tab.tbl_offset = 0; + for (tssi = 0; tssi < 128; tssi++) { + pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1); + + pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr; + wlc_lcnphy_write_table(pi, &tab); + tab.tbl_offset++; + } + + mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7); + + write_phy_reg(pi, 0x4a8, 10); + + wlc_lcnphy_set_target_tx_pwr(pi, LCN_TARGET_PWR); + + wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW); + } + if (!suspend) + wlapi_enable_mac(pi->sh->physhim); +} + +static u8 wlc_lcnphy_get_bbmult(phy_info_t *pi) +{ + u16 m0m1; + phytbl_info_t tab; + + tab.tbl_ptr = &m0m1; + tab.tbl_len = 1; + tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL; + tab.tbl_offset = 87; + tab.tbl_width = 16; + wlc_lcnphy_read_table(pi, &tab); + + return (u8) ((m0m1 & 0xff00) >> 8); +} + +static void wlc_lcnphy_set_pa_gain(phy_info_t *pi, u16 gain) +{ + mod_phy_reg(pi, 0x4fb, + LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK, + gain << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT); + mod_phy_reg(pi, 0x4fd, + LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK, + gain << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT); +} + +void +wlc_lcnphy_get_radio_loft(phy_info_t *pi, + u8 *ei0, u8 *eq0, u8 *fi0, u8 *fq0) +{ + *ei0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG089)); + *eq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08A)); + *fi0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08B)); + *fq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08C)); +} + +static void wlc_lcnphy_get_tx_gain(phy_info_t *pi, lcnphy_txgains_t *gains) +{ + u16 dac_gain; + + dac_gain = read_phy_reg(pi, 0x439) >> 0; + gains->dac_gain = (dac_gain & 0x380) >> 7; + + { + u16 rfgain0, rfgain1; + + rfgain0 = (read_phy_reg(pi, 0x4b5) & (0xffff << 0)) >> 0; + rfgain1 = (read_phy_reg(pi, 0x4fb) & (0x7fff << 0)) >> 0; + + gains->gm_gain = rfgain0 & 0xff; + gains->pga_gain = (rfgain0 >> 8) & 0xff; + gains->pad_gain = rfgain1 & 0xff; + } +} + +void wlc_lcnphy_set_tx_iqcc(phy_info_t *pi, u16 a, u16 b) +{ + phytbl_info_t tab; + u16 iqcc[2]; + + iqcc[0] = a; + iqcc[1] = b; + + tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL; + tab.tbl_width = 16; + tab.tbl_ptr = iqcc; + tab.tbl_len = 2; + tab.tbl_offset = 80; + wlc_lcnphy_write_table(pi, &tab); +} + +void wlc_lcnphy_set_tx_locc(phy_info_t *pi, u16 didq) +{ + phytbl_info_t tab; + + tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL; + tab.tbl_width = 16; + tab.tbl_ptr = &didq; + tab.tbl_len = 1; + tab.tbl_offset = 85; + wlc_lcnphy_write_table(pi, &tab); +} + +void wlc_lcnphy_set_tx_pwr_by_index(phy_info_t *pi, int index) +{ + phytbl_info_t tab; + u16 a, b; + u8 bb_mult; + u32 bbmultiqcomp, txgain, locoeffs, rfpower; + lcnphy_txgains_t gains; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + ASSERT(index <= LCNPHY_MAX_TX_POWER_INDEX); + + pi_lcn->lcnphy_tx_power_idx_override = (s8) index; + pi_lcn->lcnphy_current_index = (u8) index; + + tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; + tab.tbl_width = 32; + tab.tbl_len = 1; + + wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); + + tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index; + tab.tbl_ptr = &bbmultiqcomp; + wlc_lcnphy_read_table(pi, &tab); + + tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index; + tab.tbl_width = 32; + tab.tbl_ptr = &txgain; + wlc_lcnphy_read_table(pi, &tab); + + gains.gm_gain = (u16) (txgain & 0xff); + gains.pga_gain = (u16) (txgain >> 8) & 0xff; + gains.pad_gain = (u16) (txgain >> 16) & 0xff; + gains.dac_gain = (u16) (bbmultiqcomp >> 28) & 0x07; + wlc_lcnphy_set_tx_gain(pi, &gains); + wlc_lcnphy_set_pa_gain(pi, (u16) (txgain >> 24) & 0x7f); + + bb_mult = (u8) ((bbmultiqcomp >> 20) & 0xff); + wlc_lcnphy_set_bbmult(pi, bb_mult); + + wlc_lcnphy_enable_tx_gain_override(pi); + + if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) { + + a = (u16) ((bbmultiqcomp >> 10) & 0x3ff); + b = (u16) (bbmultiqcomp & 0x3ff); + wlc_lcnphy_set_tx_iqcc(pi, a, b); + + tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + index; + tab.tbl_ptr = &locoeffs; + wlc_lcnphy_read_table(pi, &tab); + + wlc_lcnphy_set_tx_locc(pi, (u16) locoeffs); + + tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index; + tab.tbl_ptr = &rfpower; + wlc_lcnphy_read_table(pi, &tab); + mod_phy_reg(pi, 0x6a6, (0x1fff << 0), (rfpower * 8) << 0); + + } +} + +static void wlc_lcnphy_set_trsw_override(phy_info_t *pi, bool tx, bool rx) +{ + + mod_phy_reg(pi, 0x44d, + (0x1 << 1) | + (0x1 << 0), (tx ? (0x1 << 1) : 0) | (rx ? (0x1 << 0) : 0)); + + or_phy_reg(pi, 0x44c, (0x1 << 1) | (0x1 << 0)); +} + +static void wlc_lcnphy_clear_papd_comptable(phy_info_t *pi) +{ + u32 j; + phytbl_info_t tab; + u32 temp_offset[128]; + tab.tbl_ptr = temp_offset; + tab.tbl_len = 128; + tab.tbl_id = LCNPHY_TBL_ID_PAPDCOMPDELTATBL; + tab.tbl_width = 32; + tab.tbl_offset = 0; + + memset(temp_offset, 0, sizeof(temp_offset)); + for (j = 1; j < 128; j += 2) + temp_offset[j] = 0x80000; + + wlc_lcnphy_write_table(pi, &tab); + return; +} + +static void +wlc_lcnphy_set_rx_gain_by_distribution(phy_info_t *pi, + u16 trsw, + u16 ext_lna, + u16 biq2, + u16 biq1, + u16 tia, u16 lna2, u16 lna1) +{ + u16 gain0_15, gain16_19; + + gain16_19 = biq2 & 0xf; + gain0_15 = ((biq1 & 0xf) << 12) | + ((tia & 0xf) << 8) | + ((lna2 & 0x3) << 6) | + ((lna2 & 0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0); + + mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0); + mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0); + mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11); + + if (LCNREV_LT(pi->pubpi.phy_rev, 2)) { + mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9); + mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10); + } else { + mod_phy_reg(pi, 0x4b1, (0x1 << 10), 0 << 10); + + mod_phy_reg(pi, 0x4b1, (0x1 << 15), 0 << 15); + + mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9); + } + + mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0); + +} + +static void wlc_lcnphy_rx_gain_override_enable(phy_info_t *pi, bool enable) +{ + u16 ebit = enable ? 1 : 0; + + mod_phy_reg(pi, 0x4b0, (0x1 << 8), ebit << 8); + + mod_phy_reg(pi, 0x44c, (0x1 << 0), ebit << 0); + + if (LCNREV_LT(pi->pubpi.phy_rev, 2)) { + mod_phy_reg(pi, 0x44c, (0x1 << 4), ebit << 4); + mod_phy_reg(pi, 0x44c, (0x1 << 6), ebit << 6); + mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5); + mod_phy_reg(pi, 0x4b0, (0x1 << 6), ebit << 6); + } else { + mod_phy_reg(pi, 0x4b0, (0x1 << 12), ebit << 12); + mod_phy_reg(pi, 0x4b0, (0x1 << 13), ebit << 13); + mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5); + } + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + mod_phy_reg(pi, 0x4b0, (0x1 << 10), ebit << 10); + mod_phy_reg(pi, 0x4e5, (0x1 << 3), ebit << 3); + } +} + +void wlc_lcnphy_tx_pu(phy_info_t *pi, bool bEnable) +{ + if (!bEnable) { + + and_phy_reg(pi, 0x43b, ~(u16) ((0x1 << 1) | (0x1 << 4))); + + mod_phy_reg(pi, 0x43c, (0x1 << 1), 1 << 1); + + and_phy_reg(pi, 0x44c, + ~(u16) ((0x1 << 3) | + (0x1 << 5) | + (0x1 << 12) | + (0x1 << 0) | (0x1 << 1) | (0x1 << 2))); + + and_phy_reg(pi, 0x44d, + ~(u16) ((0x1 << 3) | (0x1 << 5) | (0x1 << 14))); + mod_phy_reg(pi, 0x44d, (0x1 << 2), 1 << 2); + + mod_phy_reg(pi, 0x44d, (0x1 << 1) | (0x1 << 0), (0x1 << 0)); + + and_phy_reg(pi, 0x4f9, + ~(u16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2))); + + and_phy_reg(pi, 0x4fa, + ~(u16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2))); + } else { + + mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); + + mod_phy_reg(pi, 0x43b, (0x1 << 4), 1 << 4); + mod_phy_reg(pi, 0x43c, (0x1 << 6), 0 << 6); + + mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12); + mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14); + + wlc_lcnphy_set_trsw_override(pi, true, false); + + mod_phy_reg(pi, 0x44d, (0x1 << 2), 0 << 2); + mod_phy_reg(pi, 0x44c, (0x1 << 2), 1 << 2); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + + mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3); + mod_phy_reg(pi, 0x44d, (0x1 << 3), 1 << 3); + + mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5); + mod_phy_reg(pi, 0x44d, (0x1 << 5), 0 << 5); + + mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x4fa, (0x1 << 1), 1 << 1); + + mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2); + mod_phy_reg(pi, 0x4fa, (0x1 << 2), 1 << 2); + + mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x4fa, (0x1 << 0), 1 << 0); + } else { + + mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3); + mod_phy_reg(pi, 0x44d, (0x1 << 3), 0 << 3); + + mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5); + mod_phy_reg(pi, 0x44d, (0x1 << 5), 1 << 5); + + mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x4fa, (0x1 << 1), 0 << 1); + + mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2); + mod_phy_reg(pi, 0x4fa, (0x1 << 2), 0 << 2); + + mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0); + } + } +} + +static void +wlc_lcnphy_run_samples(phy_info_t *pi, + u16 num_samps, + u16 num_loops, u16 wait, bool iqcalmode) +{ + + or_phy_reg(pi, 0x6da, 0x8080); + + mod_phy_reg(pi, 0x642, (0x7f << 0), (num_samps - 1) << 0); + if (num_loops != 0xffff) + num_loops--; + mod_phy_reg(pi, 0x640, (0xffff << 0), num_loops << 0); + + mod_phy_reg(pi, 0x641, (0xffff << 0), wait << 0); + + if (iqcalmode) { + + and_phy_reg(pi, 0x453, (u16) ~(0x1 << 15)); + or_phy_reg(pi, 0x453, (0x1 << 15)); + } else { + write_phy_reg(pi, 0x63f, 1); + wlc_lcnphy_tx_pu(pi, 1); + } + + or_radio_reg(pi, RADIO_2064_REG112, 0x6); +} + +void wlc_lcnphy_deaf_mode(phy_info_t *pi, bool mode) +{ + + u8 phybw40; + phybw40 = CHSPEC_IS40(pi->radio_chanspec); + + if (LCNREV_LT(pi->pubpi.phy_rev, 2)) { + mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5); + mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9); + } else { + mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5); + mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9); + } + + if (phybw40 == 0) { + mod_phy_reg((pi), 0x410, + (0x1 << 6) | + (0x1 << 5), + ((CHSPEC_IS2G(pi->radio_chanspec)) ? (!mode) : 0) << + 6 | (!mode) << 5); + mod_phy_reg(pi, 0x410, (0x1 << 7), (mode) << 7); + } +} + +void +wlc_lcnphy_start_tx_tone(phy_info_t *pi, s32 f_kHz, u16 max_val, + bool iqcalmode) +{ + u8 phy_bw; + u16 num_samps, t, k; + u32 bw; + fixed theta = 0, rot = 0; + cs32 tone_samp; + u32 data_buf[64]; + u16 i_samp, q_samp; + phytbl_info_t tab; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + pi->phy_tx_tone_freq = f_kHz; + + wlc_lcnphy_deaf_mode(pi, true); + + phy_bw = 40; + if (pi_lcn->lcnphy_spurmod) { + write_phy_reg(pi, 0x942, 0x2); + write_phy_reg(pi, 0x93b, 0x0); + write_phy_reg(pi, 0x93c, 0x0); + wlc_lcnphy_txrx_spur_avoidance_mode(pi, false); + } + + if (f_kHz) { + k = 1; + do { + bw = phy_bw * 1000 * k; + num_samps = bw / ABS(f_kHz); + ASSERT(num_samps <= ARRAY_SIZE(data_buf)); + k++; + } while ((num_samps * (u32) (ABS(f_kHz))) != bw); + } else + num_samps = 2; + + rot = FIXED((f_kHz * 36) / phy_bw) / 100; + theta = 0; + + for (t = 0; t < num_samps; t++) { + + wlc_phy_cordic(theta, &tone_samp); + + theta += rot; + + i_samp = (u16) (FLOAT(tone_samp.i * max_val) & 0x3ff); + q_samp = (u16) (FLOAT(tone_samp.q * max_val) & 0x3ff); + data_buf[t] = (i_samp << 10) | q_samp; + } + + mod_phy_reg(pi, 0x6d6, (0x3 << 0), 0 << 0); + + mod_phy_reg(pi, 0x6da, (0x1 << 3), 1 << 3); + + tab.tbl_ptr = data_buf; + tab.tbl_len = num_samps; + tab.tbl_id = LCNPHY_TBL_ID_SAMPLEPLAY; + tab.tbl_offset = 0; + tab.tbl_width = 32; + wlc_lcnphy_write_table(pi, &tab); + + wlc_lcnphy_run_samples(pi, num_samps, 0xffff, 0, iqcalmode); +} + +void wlc_lcnphy_stop_tx_tone(phy_info_t *pi) +{ + s16 playback_status; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + pi->phy_tx_tone_freq = 0; + if (pi_lcn->lcnphy_spurmod) { + write_phy_reg(pi, 0x942, 0x7); + write_phy_reg(pi, 0x93b, 0x2017); + write_phy_reg(pi, 0x93c, 0x27c5); + wlc_lcnphy_txrx_spur_avoidance_mode(pi, true); + } + + playback_status = read_phy_reg(pi, 0x644); + if (playback_status & (0x1 << 0)) { + wlc_lcnphy_tx_pu(pi, 0); + mod_phy_reg(pi, 0x63f, (0x1 << 1), 1 << 1); + } else if (playback_status & (0x1 << 1)) + mod_phy_reg(pi, 0x453, (0x1 << 15), 0 << 15); + + mod_phy_reg(pi, 0x6d6, (0x3 << 0), 1 << 0); + + mod_phy_reg(pi, 0x6da, (0x1 << 3), 0 << 3); + + mod_phy_reg(pi, 0x6da, (0x1 << 7), 0 << 7); + + and_radio_reg(pi, RADIO_2064_REG112, 0xFFF9); + + wlc_lcnphy_deaf_mode(pi, false); +} + +static void wlc_lcnphy_clear_trsw_override(phy_info_t *pi) +{ + + and_phy_reg(pi, 0x44c, (u16) ~((0x1 << 1) | (0x1 << 0))); +} + +void wlc_lcnphy_get_tx_iqcc(phy_info_t *pi, u16 *a, u16 *b) +{ + u16 iqcc[2]; + phytbl_info_t tab; + + tab.tbl_ptr = iqcc; + tab.tbl_len = 2; + tab.tbl_id = 0; + tab.tbl_offset = 80; + tab.tbl_width = 16; + wlc_lcnphy_read_table(pi, &tab); + + *a = iqcc[0]; + *b = iqcc[1]; +} + +u16 wlc_lcnphy_get_tx_locc(phy_info_t *pi) +{ + phytbl_info_t tab; + u16 didq; + + tab.tbl_id = 0; + tab.tbl_width = 16; + tab.tbl_ptr = &didq; + tab.tbl_len = 1; + tab.tbl_offset = 85; + wlc_lcnphy_read_table(pi, &tab); + + return didq; +} + +static void wlc_lcnphy_txpwrtbl_iqlo_cal(phy_info_t *pi) +{ + + lcnphy_txgains_t target_gains, old_gains; + u8 save_bb_mult; + u16 a, b, didq, save_pa_gain = 0; + uint idx, SAVE_txpwrindex = 0xFF; + u32 val; + u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); + phytbl_info_t tab; + u8 ei0, eq0, fi0, fq0; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + wlc_lcnphy_get_tx_gain(pi, &old_gains); + save_pa_gain = wlc_lcnphy_get_pa_gain(pi); + + save_bb_mult = wlc_lcnphy_get_bbmult(pi); + + if (SAVE_txpwrctrl == LCNPHY_TX_PWR_CTRL_OFF) + SAVE_txpwrindex = wlc_lcnphy_get_current_tx_pwr_idx(pi); + + wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); + + target_gains.gm_gain = 7; + target_gains.pga_gain = 0; + target_gains.pad_gain = 21; + target_gains.dac_gain = 0; + wlc_lcnphy_set_tx_gain(pi, &target_gains); + wlc_lcnphy_set_tx_pwr_by_index(pi, 16); + + if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) { + + wlc_lcnphy_set_tx_pwr_by_index(pi, 30); + + wlc_lcnphy_tx_iqlo_cal(pi, &target_gains, + (pi_lcn-> + lcnphy_recal ? LCNPHY_CAL_RECAL : + LCNPHY_CAL_FULL), false); + } else { + + wlc_lcnphy_tx_iqlo_soft_cal_full(pi); + } + + wlc_lcnphy_get_radio_loft(pi, &ei0, &eq0, &fi0, &fq0); + if ((ABS((s8) fi0) == 15) && (ABS((s8) fq0) == 15)) { + if (CHSPEC_IS5G(pi->radio_chanspec)) { + target_gains.gm_gain = 255; + target_gains.pga_gain = 255; + target_gains.pad_gain = 0xf0; + target_gains.dac_gain = 0; + } else { + target_gains.gm_gain = 7; + target_gains.pga_gain = 45; + target_gains.pad_gain = 186; + target_gains.dac_gain = 0; + } + + if (LCNREV_IS(pi->pubpi.phy_rev, 1) + || pi_lcn->lcnphy_hw_iqcal_en) { + + target_gains.pga_gain = 0; + target_gains.pad_gain = 30; + wlc_lcnphy_set_tx_pwr_by_index(pi, 16); + wlc_lcnphy_tx_iqlo_cal(pi, &target_gains, + LCNPHY_CAL_FULL, false); + } else { + + wlc_lcnphy_tx_iqlo_soft_cal_full(pi); + } + + } + + wlc_lcnphy_get_tx_iqcc(pi, &a, &b); + + didq = wlc_lcnphy_get_tx_locc(pi); + + tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; + tab.tbl_width = 32; + tab.tbl_ptr = &val; + + tab.tbl_len = 1; + tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET; + + for (idx = 0; idx < 128; idx++) { + tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + idx; + + wlc_lcnphy_read_table(pi, &tab); + val = (val & 0xfff00000) | + ((u32) (a & 0x3FF) << 10) | (b & 0x3ff); + wlc_lcnphy_write_table(pi, &tab); + + val = didq; + tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + idx; + wlc_lcnphy_write_table(pi, &tab); + } + + pi_lcn->lcnphy_cal_results.txiqlocal_a = a; + pi_lcn->lcnphy_cal_results.txiqlocal_b = b; + pi_lcn->lcnphy_cal_results.txiqlocal_didq = didq; + pi_lcn->lcnphy_cal_results.txiqlocal_ei0 = ei0; + pi_lcn->lcnphy_cal_results.txiqlocal_eq0 = eq0; + pi_lcn->lcnphy_cal_results.txiqlocal_fi0 = fi0; + pi_lcn->lcnphy_cal_results.txiqlocal_fq0 = fq0; + + wlc_lcnphy_set_bbmult(pi, save_bb_mult); + wlc_lcnphy_set_pa_gain(pi, save_pa_gain); + wlc_lcnphy_set_tx_gain(pi, &old_gains); + + if (SAVE_txpwrctrl != LCNPHY_TX_PWR_CTRL_OFF) + wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl); + else + wlc_lcnphy_set_tx_pwr_by_index(pi, SAVE_txpwrindex); +} + +s16 wlc_lcnphy_tempsense_new(phy_info_t *pi, bool mode) +{ + u16 tempsenseval1, tempsenseval2; + s16 avg = 0; + bool suspend = 0; + + if (NORADIO_ENAB(pi->pubpi)) + return -1; + + if (mode == 1) { + suspend = + (0 == + (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + if (!suspend) + wlapi_suspend_mac_and_wait(pi->sh->physhim); + wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE); + } + tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF; + tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF; + + if (tempsenseval1 > 255) + avg = (s16) (tempsenseval1 - 512); + else + avg = (s16) tempsenseval1; + + if (tempsenseval2 > 255) + avg += (s16) (tempsenseval2 - 512); + else + avg += (s16) tempsenseval2; + + avg /= 2; + + if (mode == 1) { + + mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14); + + udelay(100); + mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14); + + if (!suspend) + wlapi_enable_mac(pi->sh->physhim); + } + return avg; +} + +u16 wlc_lcnphy_tempsense(phy_info_t *pi, bool mode) +{ + u16 tempsenseval1, tempsenseval2; + s32 avg = 0; + bool suspend = 0; + u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + if (NORADIO_ENAB(pi->pubpi)) + return -1; + + if (mode == 1) { + suspend = + (0 == + (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + if (!suspend) + wlapi_suspend_mac_and_wait(pi->sh->physhim); + wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE); + } + tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF; + tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF; + + if (tempsenseval1 > 255) + avg = (int)(tempsenseval1 - 512); + else + avg = (int)tempsenseval1; + + if (pi_lcn->lcnphy_tempsense_option == 1 || pi->hwpwrctrl_capable) { + if (tempsenseval2 > 255) + avg = (int)(avg - tempsenseval2 + 512); + else + avg = (int)(avg - tempsenseval2); + } else { + if (tempsenseval2 > 255) + avg = (int)(avg + tempsenseval2 - 512); + else + avg = (int)(avg + tempsenseval2); + avg = avg / 2; + } + if (avg < 0) + avg = avg + 512; + + if (pi_lcn->lcnphy_tempsense_option == 2) + avg = tempsenseval1; + + if (mode) + wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl); + + if (mode == 1) { + + mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14); + + udelay(100); + mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14); + + if (!suspend) + wlapi_enable_mac(pi->sh->physhim); + } + return (u16) avg; +} + +s8 wlc_lcnphy_tempsense_degree(phy_info_t *pi, bool mode) +{ + s32 degree = wlc_lcnphy_tempsense_new(pi, mode); + degree = + ((degree << 10) + LCN_TEMPSENSE_OFFSET + (LCN_TEMPSENSE_DEN >> 1)) + / LCN_TEMPSENSE_DEN; + return (s8) degree; +} + +s8 wlc_lcnphy_vbatsense(phy_info_t *pi, bool mode) +{ + u16 vbatsenseval; + s32 avg = 0; + bool suspend = 0; + + if (NORADIO_ENAB(pi->pubpi)) + return -1; + + if (mode == 1) { + suspend = + (0 == + (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + if (!suspend) + wlapi_suspend_mac_and_wait(pi->sh->physhim); + wlc_lcnphy_vbat_temp_sense_setup(pi, VBATSENSE); + } + + vbatsenseval = read_phy_reg(pi, 0x475) & 0x1FF; + + if (vbatsenseval > 255) + avg = (s32) (vbatsenseval - 512); + else + avg = (s32) vbatsenseval; + + avg = + (avg * LCN_VBAT_SCALE_NOM + + (LCN_VBAT_SCALE_DEN >> 1)) / LCN_VBAT_SCALE_DEN; + + if (mode == 1) { + if (!suspend) + wlapi_enable_mac(pi->sh->physhim); + } + return (s8) avg; +} + +static void wlc_lcnphy_afe_clk_init(phy_info_t *pi, u8 mode) +{ + u8 phybw40; + phybw40 = CHSPEC_IS40(pi->radio_chanspec); + + mod_phy_reg(pi, 0x6d1, (0x1 << 7), (1) << 7); + + if (((mode == AFE_CLK_INIT_MODE_PAPD) && (phybw40 == 0)) || + (mode == AFE_CLK_INIT_MODE_TXRX2X)) + write_phy_reg(pi, 0x6d0, 0x7); + + wlc_lcnphy_toggle_afe_pwdn(pi); +} + +static bool +wlc_lcnphy_rx_iq_est(phy_info_t *pi, + u16 num_samps, + u8 wait_time, lcnphy_iq_est_t *iq_est) +{ + int wait_count = 0; + bool result = true; + u8 phybw40; + phybw40 = CHSPEC_IS40(pi->radio_chanspec); + + mod_phy_reg(pi, 0x6da, (0x1 << 5), (1) << 5); + + mod_phy_reg(pi, 0x410, (0x1 << 3), (0) << 3); + + mod_phy_reg(pi, 0x482, (0xffff << 0), (num_samps) << 0); + + mod_phy_reg(pi, 0x481, (0xff << 0), ((u16) wait_time) << 0); + + mod_phy_reg(pi, 0x481, (0x1 << 8), (0) << 8); + + mod_phy_reg(pi, 0x481, (0x1 << 9), (1) << 9); + + while (read_phy_reg(pi, 0x481) & (0x1 << 9)) { + + if (wait_count > (10 * 500)) { + result = false; + goto cleanup; + } + udelay(100); + wait_count++; + } + + iq_est->iq_prod = ((u32) read_phy_reg(pi, 0x483) << 16) | + (u32) read_phy_reg(pi, 0x484); + iq_est->i_pwr = ((u32) read_phy_reg(pi, 0x485) << 16) | + (u32) read_phy_reg(pi, 0x486); + iq_est->q_pwr = ((u32) read_phy_reg(pi, 0x487) << 16) | + (u32) read_phy_reg(pi, 0x488); + + cleanup: + mod_phy_reg(pi, 0x410, (0x1 << 3), (1) << 3); + + mod_phy_reg(pi, 0x6da, (0x1 << 5), (0) << 5); + + return result; +} + +static bool wlc_lcnphy_calc_rx_iq_comp(phy_info_t *pi, u16 num_samps) +{ +#define LCNPHY_MIN_RXIQ_PWR 2 + bool result; + u16 a0_new, b0_new; + lcnphy_iq_est_t iq_est = { 0, 0, 0 }; + s32 a, b, temp; + s16 iq_nbits, qq_nbits, arsh, brsh; + s32 iq; + u32 ii, qq; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + a0_new = ((read_phy_reg(pi, 0x645) & (0x3ff << 0)) >> 0); + b0_new = ((read_phy_reg(pi, 0x646) & (0x3ff << 0)) >> 0); + mod_phy_reg(pi, 0x6d1, (0x1 << 2), (0) << 2); + + mod_phy_reg(pi, 0x64b, (0x1 << 6), (1) << 6); + + wlc_lcnphy_set_rx_iq_comp(pi, 0, 0); + + result = wlc_lcnphy_rx_iq_est(pi, num_samps, 32, &iq_est); + if (!result) + goto cleanup; + + iq = (s32) iq_est.iq_prod; + ii = iq_est.i_pwr; + qq = iq_est.q_pwr; + + if ((ii + qq) < LCNPHY_MIN_RXIQ_PWR) { + result = false; + goto cleanup; + } + + iq_nbits = wlc_phy_nbits(iq); + qq_nbits = wlc_phy_nbits(qq); + + arsh = 10 - (30 - iq_nbits); + if (arsh >= 0) { + a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh))); + temp = (s32) (ii >> arsh); + if (temp == 0) { + return false; + } + } else { + a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh))); + temp = (s32) (ii << -arsh); + if (temp == 0) { + return false; + } + } + a /= temp; + brsh = qq_nbits - 31 + 20; + if (brsh >= 0) { + b = (qq << (31 - qq_nbits)); + temp = (s32) (ii >> brsh); + if (temp == 0) { + return false; + } + } else { + b = (qq << (31 - qq_nbits)); + temp = (s32) (ii << -brsh); + if (temp == 0) { + return false; + } + } + b /= temp; + b -= a * a; + b = (s32) wlc_phy_sqrt_int((u32) b); + b -= (1 << 10); + a0_new = (u16) (a & 0x3ff); + b0_new = (u16) (b & 0x3ff); + cleanup: + + wlc_lcnphy_set_rx_iq_comp(pi, a0_new, b0_new); + + mod_phy_reg(pi, 0x64b, (0x1 << 0), (1) << 0); + + mod_phy_reg(pi, 0x64b, (0x1 << 3), (1) << 3); + + pi_lcn->lcnphy_cal_results.rxiqcal_coeff_a0 = a0_new; + pi_lcn->lcnphy_cal_results.rxiqcal_coeff_b0 = b0_new; + + return result; +} + +static bool +wlc_lcnphy_rx_iq_cal(phy_info_t *pi, const lcnphy_rx_iqcomp_t *iqcomp, + int iqcomp_sz, bool tx_switch, bool rx_switch, int module, + int tx_gain_idx) +{ + lcnphy_txgains_t old_gains; + u16 tx_pwr_ctrl; + u8 tx_gain_index_old = 0; + bool result = false, tx_gain_override_old = false; + u16 i, Core1TxControl_old, RFOverride0_old, + RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old, + rfoverride3_old, rfoverride3val_old, rfoverride4_old, + rfoverride4val_old, afectrlovr_old, afectrlovrval_old; + int tia_gain; + u32 received_power, rx_pwr_threshold; + u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl; + u16 values_to_save[11]; + s16 *ptr; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC); + if (NULL == ptr) { + return false; + } + if (module == 2) { + ASSERT(iqcomp_sz); + + while (iqcomp_sz--) { + if (iqcomp[iqcomp_sz].chan == + CHSPEC_CHANNEL(pi->radio_chanspec)) { + + wlc_lcnphy_set_rx_iq_comp(pi, + (u16) + iqcomp[iqcomp_sz].a, + (u16) + iqcomp[iqcomp_sz].b); + result = true; + break; + } + } + ASSERT(result); + goto cal_done; + } + + if (module == 1) { + + tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); + wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); + + for (i = 0; i < 11; i++) { + values_to_save[i] = + read_radio_reg(pi, rxiq_cal_rf_reg[i]); + } + Core1TxControl_old = read_phy_reg(pi, 0x631); + + or_phy_reg(pi, 0x631, 0x0015); + + RFOverride0_old = read_phy_reg(pi, 0x44c); + RFOverrideVal0_old = read_phy_reg(pi, 0x44d); + rfoverride2_old = read_phy_reg(pi, 0x4b0); + rfoverride2val_old = read_phy_reg(pi, 0x4b1); + rfoverride3_old = read_phy_reg(pi, 0x4f9); + rfoverride3val_old = read_phy_reg(pi, 0x4fa); + rfoverride4_old = read_phy_reg(pi, 0x938); + rfoverride4val_old = read_phy_reg(pi, 0x939); + afectrlovr_old = read_phy_reg(pi, 0x43b); + afectrlovrval_old = read_phy_reg(pi, 0x43c); + old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); + old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db); + + tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi); + if (tx_gain_override_old) { + wlc_lcnphy_get_tx_gain(pi, &old_gains); + tx_gain_index_old = pi_lcn->lcnphy_current_index; + } + + wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx); + + mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0); + + mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); + + write_radio_reg(pi, RADIO_2064_REG116, 0x06); + write_radio_reg(pi, RADIO_2064_REG12C, 0x07); + write_radio_reg(pi, RADIO_2064_REG06A, 0xd3); + write_radio_reg(pi, RADIO_2064_REG098, 0x03); + write_radio_reg(pi, RADIO_2064_REG00B, 0x7); + mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4); + write_radio_reg(pi, RADIO_2064_REG01D, 0x01); + write_radio_reg(pi, RADIO_2064_REG114, 0x01); + write_radio_reg(pi, RADIO_2064_REG02E, 0x10); + write_radio_reg(pi, RADIO_2064_REG12A, 0x08); + + mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0); + mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2); + mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2); + mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3); + mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3); + mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5); + mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5); + + mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0); + + wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0); + write_phy_reg(pi, 0x6da, 0xffff); + or_phy_reg(pi, 0x6db, 0x3); + wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch); + wlc_lcnphy_rx_gain_override_enable(pi, true); + + tia_gain = 8; + rx_pwr_threshold = 950; + while (tia_gain > 0) { + tia_gain -= 1; + wlc_lcnphy_set_rx_gain_by_distribution(pi, + 0, 0, 2, 2, + (u16) + tia_gain, 1, 0); + udelay(500); + + received_power = + wlc_lcnphy_measure_digital_power(pi, 2000); + if (received_power < rx_pwr_threshold) + break; + } + result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff); + + wlc_lcnphy_stop_tx_tone(pi); + + write_phy_reg(pi, 0x631, Core1TxControl_old); + + write_phy_reg(pi, 0x44c, RFOverrideVal0_old); + write_phy_reg(pi, 0x44d, RFOverrideVal0_old); + write_phy_reg(pi, 0x4b0, rfoverride2_old); + write_phy_reg(pi, 0x4b1, rfoverride2val_old); + write_phy_reg(pi, 0x4f9, rfoverride3_old); + write_phy_reg(pi, 0x4fa, rfoverride3val_old); + write_phy_reg(pi, 0x938, rfoverride4_old); + write_phy_reg(pi, 0x939, rfoverride4val_old); + write_phy_reg(pi, 0x43b, afectrlovr_old); + write_phy_reg(pi, 0x43c, afectrlovrval_old); + write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl); + write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl); + + wlc_lcnphy_clear_trsw_override(pi); + + mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2); + + for (i = 0; i < 11; i++) { + write_radio_reg(pi, rxiq_cal_rf_reg[i], + values_to_save[i]); + } + + if (tx_gain_override_old) { + wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old); + } else + wlc_lcnphy_disable_tx_gain_override(pi); + wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl); + + wlc_lcnphy_rx_gain_override_enable(pi, false); + } + + cal_done: + kfree(ptr); + return result; +} + +static void wlc_lcnphy_temp_adj(phy_info_t *pi) +{ + if (NORADIO_ENAB(pi->pubpi)) + return; +} + +static void wlc_lcnphy_glacial_timer_based_cal(phy_info_t *pi) +{ + bool suspend; + s8 index; + u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + suspend = + (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + if (!suspend) + wlapi_suspend_mac_and_wait(pi->sh->physhim); + wlc_lcnphy_deaf_mode(pi, true); + pi->phy_lastcal = pi->sh->now; + pi->phy_forcecal = false; + index = pi_lcn->lcnphy_current_index; + + wlc_lcnphy_txpwrtbl_iqlo_cal(pi); + + wlc_lcnphy_set_tx_pwr_by_index(pi, index); + wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl); + wlc_lcnphy_deaf_mode(pi, false); + if (!suspend) + wlapi_enable_mac(pi->sh->physhim); + +} + +static void wlc_lcnphy_periodic_cal(phy_info_t *pi) +{ + bool suspend, full_cal; + const lcnphy_rx_iqcomp_t *rx_iqcomp; + int rx_iqcomp_sz; + u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); + s8 index; + phytbl_info_t tab; + s32 a1, b0, b1; + s32 tssi, pwr, maxtargetpwr, mintargetpwr; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + if (NORADIO_ENAB(pi->pubpi)) + return; + + pi->phy_lastcal = pi->sh->now; + pi->phy_forcecal = false; + full_cal = + (pi_lcn->lcnphy_full_cal_channel != + CHSPEC_CHANNEL(pi->radio_chanspec)); + pi_lcn->lcnphy_full_cal_channel = CHSPEC_CHANNEL(pi->radio_chanspec); + index = pi_lcn->lcnphy_current_index; + + suspend = + (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + if (!suspend) { + + wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000); + wlapi_suspend_mac_and_wait(pi->sh->physhim); + } + wlc_lcnphy_deaf_mode(pi, true); + + wlc_lcnphy_txpwrtbl_iqlo_cal(pi); + + rx_iqcomp = lcnphy_rx_iqcomp_table_rev0; + rx_iqcomp_sz = ARRAY_SIZE(lcnphy_rx_iqcomp_table_rev0); + + if (LCNREV_IS(pi->pubpi.phy_rev, 1)) + wlc_lcnphy_rx_iq_cal(pi, NULL, 0, true, false, 1, 40); + else + wlc_lcnphy_rx_iq_cal(pi, NULL, 0, true, false, 1, 127); + + if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) { + + wlc_lcnphy_idle_tssi_est((wlc_phy_t *) pi); + + b0 = pi->txpa_2g[0]; + b1 = pi->txpa_2g[1]; + a1 = pi->txpa_2g[2]; + maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1); + mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1); + + tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; + tab.tbl_width = 32; + tab.tbl_ptr = &pwr; + tab.tbl_len = 1; + tab.tbl_offset = 0; + for (tssi = 0; tssi < 128; tssi++) { + pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1); + pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr; + wlc_lcnphy_write_table(pi, &tab); + tab.tbl_offset++; + } + } + + wlc_lcnphy_set_tx_pwr_by_index(pi, index); + wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl); + wlc_lcnphy_deaf_mode(pi, false); + if (!suspend) + wlapi_enable_mac(pi->sh->physhim); +} + +void wlc_lcnphy_calib_modes(phy_info_t *pi, uint mode) +{ + u16 temp_new; + int temp1, temp2, temp_diff; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + switch (mode) { + case PHY_PERICAL_CHAN: + + break; + case PHY_FULLCAL: + wlc_lcnphy_periodic_cal(pi); + break; + case PHY_PERICAL_PHYINIT: + wlc_lcnphy_periodic_cal(pi); + break; + case PHY_PERICAL_WATCHDOG: + if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) { + temp_new = wlc_lcnphy_tempsense(pi, 0); + temp1 = LCNPHY_TEMPSENSE(temp_new); + temp2 = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_cal_temper); + temp_diff = temp1 - temp2; + if ((pi_lcn->lcnphy_cal_counter > 90) || + (temp_diff > 60) || (temp_diff < -60)) { + wlc_lcnphy_glacial_timer_based_cal(pi); + wlc_2064_vco_cal(pi); + pi_lcn->lcnphy_cal_temper = temp_new; + pi_lcn->lcnphy_cal_counter = 0; + } else + pi_lcn->lcnphy_cal_counter++; + } + break; + case LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL: + if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) + wlc_lcnphy_tx_power_adjustment((wlc_phy_t *) pi); + break; + default: + ASSERT(0); + break; + } +} + +void wlc_lcnphy_get_tssi(phy_info_t *pi, s8 *ofdm_pwr, s8 *cck_pwr) +{ + s8 cck_offset; + u16 status; + status = (read_phy_reg(pi, 0x4ab)); + if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) && + (status & (0x1 << 15))) { + *ofdm_pwr = (s8) (((read_phy_reg(pi, 0x4ab) & (0x1ff << 0)) + >> 0) >> 1); + + if (wlc_phy_tpc_isenabled_lcnphy(pi)) + cck_offset = pi->tx_power_offset[TXP_FIRST_CCK]; + else + cck_offset = 0; + + *cck_pwr = *ofdm_pwr + cck_offset; + } else { + *cck_pwr = 0; + *ofdm_pwr = 0; + } +} + +void WLBANDINITFN(wlc_phy_cal_init_lcnphy) (phy_info_t *pi) +{ + return; + +} + +static void wlc_lcnphy_set_chanspec_tweaks(phy_info_t *pi, chanspec_t chanspec) +{ + u8 channel = CHSPEC_CHANNEL(chanspec); + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + if (NORADIO_ENAB(pi->pubpi)) + return; + + if (channel == 14) { + mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8); + + } else { + mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8); + + } + pi_lcn->lcnphy_bandedge_corr = 2; + if (channel == 1) + pi_lcn->lcnphy_bandedge_corr = 4; + + if (channel == 1 || channel == 2 || channel == 3 || + channel == 4 || channel == 9 || + channel == 10 || channel == 11 || channel == 12) { + si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03000c04); + si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x0); + si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x200005c0); + + si_pmu_pllupd(pi->sh->sih); + write_phy_reg(pi, 0x942, 0); + wlc_lcnphy_txrx_spur_avoidance_mode(pi, false); + pi_lcn->lcnphy_spurmod = 0; + mod_phy_reg(pi, 0x424, (0xff << 8), (0x1b) << 8); + + write_phy_reg(pi, 0x425, 0x5907); + } else { + si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03140c04); + si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x333333); + si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x202c2820); + + si_pmu_pllupd(pi->sh->sih); + write_phy_reg(pi, 0x942, 0); + wlc_lcnphy_txrx_spur_avoidance_mode(pi, true); + + pi_lcn->lcnphy_spurmod = 0; + mod_phy_reg(pi, 0x424, (0xff << 8), (0x1f) << 8); + + write_phy_reg(pi, 0x425, 0x590a); + } + + or_phy_reg(pi, 0x44a, 0x44); + write_phy_reg(pi, 0x44a, 0x80); +} + +void wlc_lcnphy_tx_power_adjustment(wlc_phy_t *ppi) +{ + s8 index; + u16 index2; + phy_info_t *pi = (phy_info_t *) ppi; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); + if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) && SAVE_txpwrctrl) { + index = wlc_lcnphy_tempcompensated_txpwrctrl(pi); + index2 = (u16) (index * 2); + mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0); + + pi_lcn->lcnphy_current_index = (s8) + ((read_phy_reg(pi, 0x4a9) & 0xFF) / 2); + } +} + +static void wlc_lcnphy_set_rx_iq_comp(phy_info_t *pi, u16 a, u16 b) +{ + mod_phy_reg(pi, 0x645, (0x3ff << 0), (a) << 0); + + mod_phy_reg(pi, 0x646, (0x3ff << 0), (b) << 0); + + mod_phy_reg(pi, 0x647, (0x3ff << 0), (a) << 0); + + mod_phy_reg(pi, 0x648, (0x3ff << 0), (b) << 0); + + mod_phy_reg(pi, 0x649, (0x3ff << 0), (a) << 0); + + mod_phy_reg(pi, 0x64a, (0x3ff << 0), (b) << 0); + +} + +void WLBANDINITFN(wlc_phy_init_lcnphy) (phy_info_t *pi) +{ + u8 phybw40; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + phybw40 = CHSPEC_IS40(pi->radio_chanspec); + + pi_lcn->lcnphy_cal_counter = 0; + pi_lcn->lcnphy_cal_temper = pi_lcn->lcnphy_rawtempsense; + + or_phy_reg(pi, 0x44a, 0x80); + and_phy_reg(pi, 0x44a, 0x7f); + + wlc_lcnphy_afe_clk_init(pi, AFE_CLK_INIT_MODE_TXRX2X); + + write_phy_reg(pi, 0x60a, 160); + + write_phy_reg(pi, 0x46a, 25); + + wlc_lcnphy_baseband_init(pi); + + wlc_lcnphy_radio_init(pi); + + if (CHSPEC_IS2G(pi->radio_chanspec)) + wlc_lcnphy_tx_pwr_ctrl_init((wlc_phy_t *) pi); + + wlc_phy_chanspec_set((wlc_phy_t *) pi, pi->radio_chanspec); + + si_pmu_regcontrol(pi->sh->sih, 0, 0xf, 0x9); + + si_pmu_chipcontrol(pi->sh->sih, 0, 0xffffffff, 0x03CDDDDD); + + if ((pi->sh->boardflags & BFL_FEM) + && wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) + wlc_lcnphy_set_tx_pwr_by_index(pi, FIXED_TXPWR); + + wlc_lcnphy_agc_temp_init(pi); + + wlc_lcnphy_temp_adj(pi); + + mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14); + + udelay(100); + mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14); + + wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW); + pi_lcn->lcnphy_noise_samples = LCNPHY_NOISE_SAMPLES_DEFAULT; + wlc_lcnphy_calib_modes(pi, PHY_PERICAL_PHYINIT); +} + +static void +wlc_lcnphy_tx_iqlo_loopback(phy_info_t *pi, u16 *values_to_save) +{ + u16 vmid; + int i; + for (i = 0; i < 20; i++) { + values_to_save[i] = + read_radio_reg(pi, iqlo_loopback_rf_regs[i]); + } + + mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12); + mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14); + + mod_phy_reg(pi, 0x44c, (0x1 << 11), 1 << 11); + mod_phy_reg(pi, 0x44d, (0x1 << 13), 0 << 13); + + mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); + + mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0); + + if (LCNREV_IS(pi->pubpi.phy_rev, 2)) + and_radio_reg(pi, RADIO_2064_REG03A, 0xFD); + else + and_radio_reg(pi, RADIO_2064_REG03A, 0xF9); + or_radio_reg(pi, RADIO_2064_REG11A, 0x1); + + or_radio_reg(pi, RADIO_2064_REG036, 0x01); + or_radio_reg(pi, RADIO_2064_REG11A, 0x18); + udelay(20); + + if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { + if (CHSPEC_IS5G(pi->radio_chanspec)) + mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0); + else + or_radio_reg(pi, RADIO_2064_REG03A, 1); + } else { + if (CHSPEC_IS5G(pi->radio_chanspec)) + mod_radio_reg(pi, RADIO_2064_REG03A, 3, 1); + else + or_radio_reg(pi, RADIO_2064_REG03A, 0x3); + } + + udelay(20); + + write_radio_reg(pi, RADIO_2064_REG025, 0xF); + if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { + if (CHSPEC_IS5G(pi->radio_chanspec)) + mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x4); + else + mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x6); + } else { + if (CHSPEC_IS5G(pi->radio_chanspec)) + mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x4 << 1); + else + mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x6 << 1); + } + + udelay(20); + + write_radio_reg(pi, RADIO_2064_REG005, 0x8); + or_radio_reg(pi, RADIO_2064_REG112, 0x80); + udelay(20); + + or_radio_reg(pi, RADIO_2064_REG0FF, 0x10); + or_radio_reg(pi, RADIO_2064_REG11F, 0x44); + udelay(20); + + or_radio_reg(pi, RADIO_2064_REG00B, 0x7); + or_radio_reg(pi, RADIO_2064_REG113, 0x10); + udelay(20); + + write_radio_reg(pi, RADIO_2064_REG007, 0x1); + udelay(20); + + vmid = 0x2A6; + mod_radio_reg(pi, RADIO_2064_REG0FC, 0x3 << 0, (vmid >> 8) & 0x3); + write_radio_reg(pi, RADIO_2064_REG0FD, (vmid & 0xff)); + or_radio_reg(pi, RADIO_2064_REG11F, 0x44); + udelay(20); + + or_radio_reg(pi, RADIO_2064_REG0FF, 0x10); + udelay(20); + write_radio_reg(pi, RADIO_2064_REG012, 0x02); + or_radio_reg(pi, RADIO_2064_REG112, 0x06); + write_radio_reg(pi, RADIO_2064_REG036, 0x11); + write_radio_reg(pi, RADIO_2064_REG059, 0xcc); + write_radio_reg(pi, RADIO_2064_REG05C, 0x2e); + write_radio_reg(pi, RADIO_2064_REG078, 0xd7); + write_radio_reg(pi, RADIO_2064_REG092, 0x15); +} + +static void +wlc_lcnphy_samp_cap(phy_info_t *pi, int clip_detect_algo, u16 thresh, + s16 *ptr, int mode) +{ + u32 curval1, curval2, stpptr, curptr, strptr, val; + u16 sslpnCalibClkEnCtrl, timer; + u16 old_sslpnCalibClkEnCtrl; + s16 imag, real; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + timer = 0; + old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); + + curval1 = R_REG(pi->sh->osh, &pi->regs->psm_corectlsts); + ptr[130] = 0; + W_REG(pi->sh->osh, &pi->regs->psm_corectlsts, ((1 << 6) | curval1)); + + W_REG(pi->sh->osh, &pi->regs->smpl_clct_strptr, 0x7E00); + W_REG(pi->sh->osh, &pi->regs->smpl_clct_stpptr, 0x8000); + udelay(20); + curval2 = R_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param); + W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, curval2 | 0x30); + + write_phy_reg(pi, 0x555, 0x0); + write_phy_reg(pi, 0x5a6, 0x5); + + write_phy_reg(pi, 0x5a2, (u16) (mode | mode << 6)); + write_phy_reg(pi, 0x5cf, 3); + write_phy_reg(pi, 0x5a5, 0x3); + write_phy_reg(pi, 0x583, 0x0); + write_phy_reg(pi, 0x584, 0x0); + write_phy_reg(pi, 0x585, 0x0fff); + write_phy_reg(pi, 0x586, 0x0000); + + write_phy_reg(pi, 0x580, 0x4501); + + sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); + write_phy_reg(pi, 0x6da, (u32) (sslpnCalibClkEnCtrl | 0x2008)); + stpptr = R_REG(pi->sh->osh, &pi->regs->smpl_clct_stpptr); + curptr = R_REG(pi->sh->osh, &pi->regs->smpl_clct_curptr); + do { + udelay(10); + curptr = R_REG(pi->sh->osh, &pi->regs->smpl_clct_curptr); + timer++; + } while ((curptr != stpptr) && (timer < 500)); + + W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, 0x2); + strptr = 0x7E00; + W_REG(pi->sh->osh, &pi->regs->tplatewrptr, strptr); + while (strptr < 0x8000) { + val = R_REG(pi->sh->osh, &pi->regs->tplatewrdata); + imag = ((val >> 16) & 0x3ff); + real = ((val) & 0x3ff); + if (imag > 511) { + imag -= 1024; + } + if (real > 511) { + real -= 1024; + } + if (pi_lcn->lcnphy_iqcal_swp_dis) + ptr[(strptr - 0x7E00) / 4] = real; + else + ptr[(strptr - 0x7E00) / 4] = imag; + if (clip_detect_algo) { + if (imag > thresh || imag < -thresh) { + strptr = 0x8000; + ptr[130] = 1; + } + } + strptr += 4; + } + + write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl); + W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, curval2); + W_REG(pi->sh->osh, &pi->regs->psm_corectlsts, curval1); +} + +static void wlc_lcnphy_tx_iqlo_soft_cal_full(phy_info_t *pi) +{ + lcnphy_unsign16_struct iqcc0, locc2, locc3, locc4; + + wlc_lcnphy_set_cc(pi, 0, 0, 0); + wlc_lcnphy_set_cc(pi, 2, 0, 0); + wlc_lcnphy_set_cc(pi, 3, 0, 0); + wlc_lcnphy_set_cc(pi, 4, 0, 0); + + wlc_lcnphy_a1(pi, 4, 0, 0); + wlc_lcnphy_a1(pi, 3, 0, 0); + wlc_lcnphy_a1(pi, 2, 3, 2); + wlc_lcnphy_a1(pi, 0, 5, 8); + wlc_lcnphy_a1(pi, 2, 2, 1); + wlc_lcnphy_a1(pi, 0, 4, 3); + + iqcc0 = wlc_lcnphy_get_cc(pi, 0); + locc2 = wlc_lcnphy_get_cc(pi, 2); + locc3 = wlc_lcnphy_get_cc(pi, 3); + locc4 = wlc_lcnphy_get_cc(pi, 4); +} + +static void +wlc_lcnphy_set_cc(phy_info_t *pi, int cal_type, s16 coeff_x, s16 coeff_y) +{ + u16 di0dq0; + u16 x, y, data_rf; + int k; + switch (cal_type) { + case 0: + wlc_lcnphy_set_tx_iqcc(pi, coeff_x, coeff_y); + break; + case 2: + di0dq0 = (coeff_x & 0xff) << 8 | (coeff_y & 0xff); + wlc_lcnphy_set_tx_locc(pi, di0dq0); + break; + case 3: + k = wlc_lcnphy_calc_floor(coeff_x, 0); + y = 8 + k; + k = wlc_lcnphy_calc_floor(coeff_x, 1); + x = 8 - k; + data_rf = (x * 16 + y); + write_radio_reg(pi, RADIO_2064_REG089, data_rf); + k = wlc_lcnphy_calc_floor(coeff_y, 0); + y = 8 + k; + k = wlc_lcnphy_calc_floor(coeff_y, 1); + x = 8 - k; + data_rf = (x * 16 + y); + write_radio_reg(pi, RADIO_2064_REG08A, data_rf); + break; + case 4: + k = wlc_lcnphy_calc_floor(coeff_x, 0); + y = 8 + k; + k = wlc_lcnphy_calc_floor(coeff_x, 1); + x = 8 - k; + data_rf = (x * 16 + y); + write_radio_reg(pi, RADIO_2064_REG08B, data_rf); + k = wlc_lcnphy_calc_floor(coeff_y, 0); + y = 8 + k; + k = wlc_lcnphy_calc_floor(coeff_y, 1); + x = 8 - k; + data_rf = (x * 16 + y); + write_radio_reg(pi, RADIO_2064_REG08C, data_rf); + break; + } +} + +static lcnphy_unsign16_struct wlc_lcnphy_get_cc(phy_info_t *pi, int cal_type) +{ + u16 a, b, didq; + u8 di0, dq0, ei, eq, fi, fq; + lcnphy_unsign16_struct cc; + cc.re = 0; + cc.im = 0; + switch (cal_type) { + case 0: + wlc_lcnphy_get_tx_iqcc(pi, &a, &b); + cc.re = a; + cc.im = b; + break; + case 2: + didq = wlc_lcnphy_get_tx_locc(pi); + di0 = (((didq & 0xff00) << 16) >> 24); + dq0 = (((didq & 0x00ff) << 24) >> 24); + cc.re = (u16) di0; + cc.im = (u16) dq0; + break; + case 3: + wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq); + cc.re = (u16) ei; + cc.im = (u16) eq; + break; + case 4: + wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq); + cc.re = (u16) fi; + cc.im = (u16) fq; + break; + } + return cc; +} + +static void +wlc_lcnphy_a1(phy_info_t *pi, int cal_type, int num_levels, int step_size_lg2) +{ + const lcnphy_spb_tone_t *phy_c1; + lcnphy_spb_tone_t phy_c2; + lcnphy_unsign16_struct phy_c3; + int phy_c4, phy_c5, k, l, j, phy_c6; + u16 phy_c7, phy_c8, phy_c9; + s16 phy_c10, phy_c11, phy_c12, phy_c13, phy_c14, phy_c15, phy_c16; + s16 *ptr, phy_c17; + s32 phy_c18, phy_c19; + u32 phy_c20, phy_c21; + bool phy_c22, phy_c23, phy_c24, phy_c25; + u16 phy_c26, phy_c27; + u16 phy_c28, phy_c29, phy_c30; + u16 phy_c31; + u16 *phy_c32; + phy_c21 = 0; + phy_c10 = phy_c13 = phy_c14 = phy_c8 = 0; + ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC); + if (NULL == ptr) { + return; + } + + phy_c32 = kmalloc(sizeof(u16) * 20, GFP_ATOMIC); + if (NULL == phy_c32) { + return; + } + phy_c26 = read_phy_reg(pi, 0x6da); + phy_c27 = read_phy_reg(pi, 0x6db); + phy_c31 = read_radio_reg(pi, RADIO_2064_REG026); + write_phy_reg(pi, 0x93d, 0xC0); + + wlc_lcnphy_start_tx_tone(pi, 3750, 88, 0); + write_phy_reg(pi, 0x6da, 0xffff); + or_phy_reg(pi, 0x6db, 0x3); + + wlc_lcnphy_tx_iqlo_loopback(pi, phy_c32); + udelay(500); + phy_c28 = read_phy_reg(pi, 0x938); + phy_c29 = read_phy_reg(pi, 0x4d7); + phy_c30 = read_phy_reg(pi, 0x4d8); + or_phy_reg(pi, 0x938, 0x1 << 2); + or_phy_reg(pi, 0x4d7, 0x1 << 2); + or_phy_reg(pi, 0x4d7, 0x1 << 3); + mod_phy_reg(pi, 0x4d7, (0x7 << 12), 0x2 << 12); + or_phy_reg(pi, 0x4d8, 1 << 0); + or_phy_reg(pi, 0x4d8, 1 << 1); + mod_phy_reg(pi, 0x4d8, (0x3ff << 2), 0x23A << 2); + mod_phy_reg(pi, 0x4d8, (0x7 << 12), 0x7 << 12); + phy_c1 = &lcnphy_spb_tone_3750[0]; + phy_c4 = 32; + + if (num_levels == 0) { + if (cal_type != 0) { + num_levels = 4; + } else { + num_levels = 9; + } + } + if (step_size_lg2 == 0) { + if (cal_type != 0) { + step_size_lg2 = 3; + } else { + step_size_lg2 = 8; + } + } + + phy_c7 = (1 << step_size_lg2); + phy_c3 = wlc_lcnphy_get_cc(pi, cal_type); + phy_c15 = (s16) phy_c3.re; + phy_c16 = (s16) phy_c3.im; + if (cal_type == 2) { + if (phy_c3.re > 127) + phy_c15 = phy_c3.re - 256; + if (phy_c3.im > 127) + phy_c16 = phy_c3.im - 256; + } + wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16); + udelay(20); + for (phy_c8 = 0; phy_c7 != 0 && phy_c8 < num_levels; phy_c8++) { + phy_c23 = 1; + phy_c22 = 0; + switch (cal_type) { + case 0: + phy_c10 = 511; + break; + case 2: + phy_c10 = 127; + break; + case 3: + phy_c10 = 15; + break; + case 4: + phy_c10 = 15; + break; + } + + phy_c9 = read_phy_reg(pi, 0x93d); + phy_c9 = 2 * phy_c9; + phy_c24 = 0; + phy_c5 = 7; + phy_c25 = 1; + while (1) { + write_radio_reg(pi, RADIO_2064_REG026, + (phy_c5 & 0x7) | ((phy_c5 & 0x7) << 4)); + udelay(50); + phy_c22 = 0; + ptr[130] = 0; + wlc_lcnphy_samp_cap(pi, 1, phy_c9, &ptr[0], 2); + if (ptr[130] == 1) + phy_c22 = 1; + if (phy_c22) + phy_c5 -= 1; + if ((phy_c22 != phy_c24) && (!phy_c25)) + break; + if (!phy_c22) + phy_c5 += 1; + if (phy_c5 <= 0 || phy_c5 >= 7) + break; + phy_c24 = phy_c22; + phy_c25 = 0; + } + + if (phy_c5 < 0) + phy_c5 = 0; + else if (phy_c5 > 7) + phy_c5 = 7; + + for (k = -phy_c7; k <= phy_c7; k += phy_c7) { + for (l = -phy_c7; l <= phy_c7; l += phy_c7) { + phy_c11 = phy_c15 + k; + phy_c12 = phy_c16 + l; + + if (phy_c11 < -phy_c10) + phy_c11 = -phy_c10; + else if (phy_c11 > phy_c10) + phy_c11 = phy_c10; + if (phy_c12 < -phy_c10) + phy_c12 = -phy_c10; + else if (phy_c12 > phy_c10) + phy_c12 = phy_c10; + wlc_lcnphy_set_cc(pi, cal_type, phy_c11, + phy_c12); + udelay(20); + wlc_lcnphy_samp_cap(pi, 0, 0, ptr, 2); + + phy_c18 = 0; + phy_c19 = 0; + for (j = 0; j < 128; j++) { + if (cal_type != 0) { + phy_c6 = j % phy_c4; + } else { + phy_c6 = (2 * j) % phy_c4; + } + phy_c2.re = phy_c1[phy_c6].re; + phy_c2.im = phy_c1[phy_c6].im; + phy_c17 = ptr[j]; + phy_c18 = phy_c18 + phy_c17 * phy_c2.re; + phy_c19 = phy_c19 + phy_c17 * phy_c2.im; + } + + phy_c18 = phy_c18 >> 10; + phy_c19 = phy_c19 >> 10; + phy_c20 = + ((phy_c18 * phy_c18) + (phy_c19 * phy_c19)); + + if (phy_c23 || phy_c20 < phy_c21) { + phy_c21 = phy_c20; + phy_c13 = phy_c11; + phy_c14 = phy_c12; + } + phy_c23 = 0; + } + } + phy_c23 = 1; + phy_c15 = phy_c13; + phy_c16 = phy_c14; + phy_c7 = phy_c7 >> 1; + wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16); + udelay(20); + } + goto cleanup; + cleanup: + wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, phy_c32); + wlc_lcnphy_stop_tx_tone(pi); + write_phy_reg(pi, 0x6da, phy_c26); + write_phy_reg(pi, 0x6db, phy_c27); + write_phy_reg(pi, 0x938, phy_c28); + write_phy_reg(pi, 0x4d7, phy_c29); + write_phy_reg(pi, 0x4d8, phy_c30); + write_radio_reg(pi, RADIO_2064_REG026, phy_c31); + + kfree(phy_c32); + kfree(ptr); +} + +static void +wlc_lcnphy_tx_iqlo_loopback_cleanup(phy_info_t *pi, u16 *values_to_save) +{ + int i; + + and_phy_reg(pi, 0x44c, 0x0 >> 11); + + and_phy_reg(pi, 0x43b, 0xC); + + for (i = 0; i < 20; i++) { + write_radio_reg(pi, iqlo_loopback_rf_regs[i], + values_to_save[i]); + } +} + +static void +WLBANDINITFN(wlc_lcnphy_load_tx_gain_table) (phy_info_t *pi, + const lcnphy_tx_gain_tbl_entry * + gain_table) { + u32 j; + phytbl_info_t tab; + u32 val; + u16 pa_gain; + u16 gm_gain; + + if (CHSPEC_IS5G(pi->radio_chanspec)) + pa_gain = 0x70; + else + pa_gain = 0x70; + + if (pi->sh->boardflags & BFL_FEM) + pa_gain = 0x10; + tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; + tab.tbl_width = 32; + tab.tbl_len = 1; + tab.tbl_ptr = &val; + + for (j = 0; j < 128; j++) { + gm_gain = gain_table[j].gm; + val = (((u32) pa_gain << 24) | + (gain_table[j].pad << 16) | + (gain_table[j].pga << 8) | gm_gain); + + tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + j; + wlc_lcnphy_write_table(pi, &tab); + + val = (gain_table[j].dac << 28) | (gain_table[j].bb_mult << 20); + tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + j; + wlc_lcnphy_write_table(pi, &tab); + } +} + +static void wlc_lcnphy_load_rfpower(phy_info_t *pi) +{ + phytbl_info_t tab; + u32 val, bbmult, rfgain; + u8 index; + u8 scale_factor = 1; + s16 temp, temp1, temp2, qQ, qQ1, qQ2, shift; + + tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; + tab.tbl_width = 32; + tab.tbl_len = 1; + + for (index = 0; index < 128; index++) { + tab.tbl_ptr = &bbmult; + tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index; + wlc_lcnphy_read_table(pi, &tab); + bbmult = bbmult >> 20; + + tab.tbl_ptr = &rfgain; + tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index; + wlc_lcnphy_read_table(pi, &tab); + + qm_log10((s32) (bbmult), 0, &temp1, &qQ1); + qm_log10((s32) (1 << 6), 0, &temp2, &qQ2); + + if (qQ1 < qQ2) { + temp2 = qm_shr16(temp2, qQ2 - qQ1); + qQ = qQ1; + } else { + temp1 = qm_shr16(temp1, qQ1 - qQ2); + qQ = qQ2; + } + temp = qm_sub16(temp1, temp2); + + if (qQ >= 4) + shift = qQ - 4; + else + shift = 4 - qQ; + + val = (((index << shift) + (5 * temp) + + (1 << (scale_factor + shift - 3))) >> (scale_factor + + shift - 2)); + + tab.tbl_ptr = &val; + tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index; + wlc_lcnphy_write_table(pi, &tab); + } +} + +static void WLBANDINITFN(wlc_lcnphy_tbl_init) (phy_info_t *pi) +{ + uint idx; + u8 phybw40; + phytbl_info_t tab; + u32 val; + + phybw40 = CHSPEC_IS40(pi->radio_chanspec); + + for (idx = 0; idx < dot11lcnphytbl_info_sz_rev0; idx++) { + wlc_lcnphy_write_table(pi, &dot11lcnphytbl_info_rev0[idx]); + } + + if (pi->sh->boardflags & BFL_FEM_BT) { + tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; + tab.tbl_width = 16; + tab.tbl_ptr = &val; + tab.tbl_len = 1; + val = 100; + tab.tbl_offset = 4; + wlc_lcnphy_write_table(pi, &tab); + } + + tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; + tab.tbl_width = 16; + tab.tbl_ptr = &val; + tab.tbl_len = 1; + + val = 114; + tab.tbl_offset = 0; + wlc_lcnphy_write_table(pi, &tab); + + val = 130; + tab.tbl_offset = 1; + wlc_lcnphy_write_table(pi, &tab); + + val = 6; + tab.tbl_offset = 8; + wlc_lcnphy_write_table(pi, &tab); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (pi->sh->boardflags & BFL_FEM) + wlc_lcnphy_load_tx_gain_table(pi, + dot11lcnphy_2GHz_extPA_gaintable_rev0); + else + wlc_lcnphy_load_tx_gain_table(pi, + dot11lcnphy_2GHz_gaintable_rev0); + } + + if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { + if (CHSPEC_IS2G(pi->radio_chanspec)) { + for (idx = 0; + idx < dot11lcnphytbl_rx_gain_info_2G_rev2_sz; + idx++) + if (pi->sh->boardflags & BFL_EXTLNA) + wlc_lcnphy_write_table(pi, + &dot11lcnphytbl_rx_gain_info_extlna_2G_rev2 + [idx]); + else + wlc_lcnphy_write_table(pi, + &dot11lcnphytbl_rx_gain_info_2G_rev2 + [idx]); + } else { + for (idx = 0; + idx < dot11lcnphytbl_rx_gain_info_5G_rev2_sz; + idx++) + if (pi->sh->boardflags & BFL_EXTLNA_5GHz) + wlc_lcnphy_write_table(pi, + &dot11lcnphytbl_rx_gain_info_extlna_5G_rev2 + [idx]); + else + wlc_lcnphy_write_table(pi, + &dot11lcnphytbl_rx_gain_info_5G_rev2 + [idx]); + } + } + + if ((pi->sh->boardflags & BFL_FEM) + && !(pi->sh->boardflags & BFL_FEM_BT)) + wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313_epa); + else if (pi->sh->boardflags & BFL_FEM_BT) { + if (pi->sh->boardrev < 0x1250) + wlc_lcnphy_write_table(pi, + &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa); + else + wlc_lcnphy_write_table(pi, + &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250); + } else + wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313); + + wlc_lcnphy_load_rfpower(pi); + + wlc_lcnphy_clear_papd_comptable(pi); +} + +static void WLBANDINITFN(wlc_lcnphy_rev0_baseband_init) (phy_info_t *pi) +{ + u16 afectrl1; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + write_radio_reg(pi, RADIO_2064_REG11C, 0x0); + + write_phy_reg(pi, 0x43b, 0x0); + write_phy_reg(pi, 0x43c, 0x0); + write_phy_reg(pi, 0x44c, 0x0); + write_phy_reg(pi, 0x4e6, 0x0); + write_phy_reg(pi, 0x4f9, 0x0); + write_phy_reg(pi, 0x4b0, 0x0); + write_phy_reg(pi, 0x938, 0x0); + write_phy_reg(pi, 0x4b0, 0x0); + write_phy_reg(pi, 0x44e, 0); + + or_phy_reg(pi, 0x567, 0x03); + + or_phy_reg(pi, 0x44a, 0x44); + write_phy_reg(pi, 0x44a, 0x80); + + if (!(pi->sh->boardflags & BFL_FEM)) + wlc_lcnphy_set_tx_pwr_by_index(pi, 52); + + if (0) { + afectrl1 = 0; + afectrl1 = (u16) ((pi_lcn->lcnphy_rssi_vf) | + (pi_lcn->lcnphy_rssi_vc << 4) | (pi_lcn-> + lcnphy_rssi_gs + << 10)); + write_phy_reg(pi, 0x43e, afectrl1); + } + + mod_phy_reg(pi, 0x634, (0xff << 0), 0xC << 0); + if (pi->sh->boardflags & BFL_FEM) { + mod_phy_reg(pi, 0x634, (0xff << 0), 0xA << 0); + + write_phy_reg(pi, 0x910, 0x1); + } + + mod_phy_reg(pi, 0x448, (0x3 << 8), 1 << 8); + mod_phy_reg(pi, 0x608, (0xff << 0), 0x17 << 0); + mod_phy_reg(pi, 0x604, (0x7ff << 0), 0x3EA << 0); + +} + +static void WLBANDINITFN(wlc_lcnphy_rev2_baseband_init) (phy_info_t *pi) +{ + if (CHSPEC_IS5G(pi->radio_chanspec)) { + mod_phy_reg(pi, 0x416, (0xff << 0), 80 << 0); + + mod_phy_reg(pi, 0x416, (0xff << 8), 80 << 8); + } +} + +static void wlc_lcnphy_agc_temp_init(phy_info_t *pi) +{ + s16 temp; + phytbl_info_t tab; + u32 tableBuffer[2]; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + if (NORADIO_ENAB(pi->pubpi)) + return; + + temp = (s16) read_phy_reg(pi, 0x4df); + pi_lcn->lcnphy_ofdmgainidxtableoffset = (temp & (0xff << 0)) >> 0; + + if (pi_lcn->lcnphy_ofdmgainidxtableoffset > 127) + pi_lcn->lcnphy_ofdmgainidxtableoffset -= 256; + + pi_lcn->lcnphy_dsssgainidxtableoffset = (temp & (0xff << 8)) >> 8; + + if (pi_lcn->lcnphy_dsssgainidxtableoffset > 127) + pi_lcn->lcnphy_dsssgainidxtableoffset -= 256; + + tab.tbl_ptr = tableBuffer; + tab.tbl_len = 2; + tab.tbl_id = 17; + tab.tbl_offset = 59; + tab.tbl_width = 32; + wlc_lcnphy_read_table(pi, &tab); + + if (tableBuffer[0] > 63) + tableBuffer[0] -= 128; + pi_lcn->lcnphy_tr_R_gain_val = tableBuffer[0]; + + if (tableBuffer[1] > 63) + tableBuffer[1] -= 128; + pi_lcn->lcnphy_tr_T_gain_val = tableBuffer[1]; + + temp = (s16) (read_phy_reg(pi, 0x434) + & (0xff << 0)); + if (temp > 127) + temp -= 256; + pi_lcn->lcnphy_input_pwr_offset_db = (s8) temp; + + pi_lcn->lcnphy_Med_Low_Gain_db = (read_phy_reg(pi, 0x424) + & (0xff << 8)) + >> 8; + pi_lcn->lcnphy_Very_Low_Gain_db = (read_phy_reg(pi, 0x425) + & (0xff << 0)) + >> 0; + + tab.tbl_ptr = tableBuffer; + tab.tbl_len = 2; + tab.tbl_id = LCNPHY_TBL_ID_GAIN_IDX; + tab.tbl_offset = 28; + tab.tbl_width = 32; + wlc_lcnphy_read_table(pi, &tab); + + pi_lcn->lcnphy_gain_idx_14_lowword = tableBuffer[0]; + pi_lcn->lcnphy_gain_idx_14_hiword = tableBuffer[1]; + +} + +static void WLBANDINITFN(wlc_lcnphy_bu_tweaks) (phy_info_t *pi) +{ + if (NORADIO_ENAB(pi->pubpi)) + return; + + or_phy_reg(pi, 0x805, 0x1); + + mod_phy_reg(pi, 0x42f, (0x7 << 0), (0x3) << 0); + + mod_phy_reg(pi, 0x030, (0x7 << 0), (0x3) << 0); + + write_phy_reg(pi, 0x414, 0x1e10); + write_phy_reg(pi, 0x415, 0x0640); + + mod_phy_reg(pi, 0x4df, (0xff << 8), -9 << 8); + + or_phy_reg(pi, 0x44a, 0x44); + write_phy_reg(pi, 0x44a, 0x80); + mod_phy_reg(pi, 0x434, (0xff << 0), (0xFD) << 0); + + mod_phy_reg(pi, 0x420, (0xff << 0), (16) << 0); + + if (!(pi->sh->boardrev < 0x1204)) + mod_radio_reg(pi, RADIO_2064_REG09B, 0xF0, 0xF0); + + write_phy_reg(pi, 0x7d6, 0x0902); + mod_phy_reg(pi, 0x429, (0xf << 0), (0x9) << 0); + + mod_phy_reg(pi, 0x429, (0x3f << 4), (0xe) << 4); + + if (LCNREV_IS(pi->pubpi.phy_rev, 1)) { + mod_phy_reg(pi, 0x423, (0xff << 0), (0x46) << 0); + + mod_phy_reg(pi, 0x411, (0xff << 0), (1) << 0); + + mod_phy_reg(pi, 0x434, (0xff << 0), (0xFF) << 0); + + mod_phy_reg(pi, 0x656, (0xf << 0), (2) << 0); + + mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2); + + mod_radio_reg(pi, RADIO_2064_REG0F7, 0x4, 0x4); + mod_radio_reg(pi, RADIO_2064_REG0F1, 0x3, 0); + mod_radio_reg(pi, RADIO_2064_REG0F2, 0xF8, 0x90); + mod_radio_reg(pi, RADIO_2064_REG0F3, 0x3, 0x2); + mod_radio_reg(pi, RADIO_2064_REG0F3, 0xf0, 0xa0); + + mod_radio_reg(pi, RADIO_2064_REG11F, 0x2, 0x2); + + wlc_lcnphy_clear_tx_power_offsets(pi); + mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (10) << 6); + + } +} + +static void WLBANDINITFN(wlc_lcnphy_baseband_init) (phy_info_t *pi) +{ + + wlc_lcnphy_tbl_init(pi); + wlc_lcnphy_rev0_baseband_init(pi); + if (LCNREV_IS(pi->pubpi.phy_rev, 2)) + wlc_lcnphy_rev2_baseband_init(pi); + wlc_lcnphy_bu_tweaks(pi); +} + +static void WLBANDINITFN(wlc_radio_2064_init) (phy_info_t *pi) +{ + u32 i; + lcnphy_radio_regs_t *lcnphyregs = NULL; + + lcnphyregs = lcnphy_radio_regs_2064; + + for (i = 0; lcnphyregs[i].address != 0xffff; i++) + if (CHSPEC_IS5G(pi->radio_chanspec) && lcnphyregs[i].do_init_a) + write_radio_reg(pi, + ((lcnphyregs[i].address & 0x3fff) | + RADIO_DEFAULT_CORE), + (u16) lcnphyregs[i].init_a); + else if (lcnphyregs[i].do_init_g) + write_radio_reg(pi, + ((lcnphyregs[i].address & 0x3fff) | + RADIO_DEFAULT_CORE), + (u16) lcnphyregs[i].init_g); + + write_radio_reg(pi, RADIO_2064_REG032, 0x62); + write_radio_reg(pi, RADIO_2064_REG033, 0x19); + + write_radio_reg(pi, RADIO_2064_REG090, 0x10); + + write_radio_reg(pi, RADIO_2064_REG010, 0x00); + + if (LCNREV_IS(pi->pubpi.phy_rev, 1)) { + + write_radio_reg(pi, RADIO_2064_REG060, 0x7f); + write_radio_reg(pi, RADIO_2064_REG061, 0x72); + write_radio_reg(pi, RADIO_2064_REG062, 0x7f); + } + + write_radio_reg(pi, RADIO_2064_REG01D, 0x02); + write_radio_reg(pi, RADIO_2064_REG01E, 0x06); + + mod_phy_reg(pi, 0x4ea, (0x7 << 0), 0 << 0); + + mod_phy_reg(pi, 0x4ea, (0x7 << 3), 1 << 3); + + mod_phy_reg(pi, 0x4ea, (0x7 << 6), 2 << 6); + + mod_phy_reg(pi, 0x4ea, (0x7 << 9), 3 << 9); + + mod_phy_reg(pi, 0x4ea, (0x7 << 12), 4 << 12); + + write_phy_reg(pi, 0x4ea, 0x4688); + + mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0); + + mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6); + + mod_phy_reg(pi, 0x46a, (0xffff << 0), 25 << 0); + + wlc_lcnphy_set_tx_locc(pi, 0); + + wlc_lcnphy_rcal(pi); + + wlc_lcnphy_rc_cal(pi); +} + +static void WLBANDINITFN(wlc_lcnphy_radio_init) (phy_info_t *pi) +{ + if (NORADIO_ENAB(pi->pubpi)) + return; + + wlc_radio_2064_init(pi); +} + +static void wlc_lcnphy_rcal(phy_info_t *pi) +{ + u8 rcal_value; + + if (NORADIO_ENAB(pi->pubpi)) + return; + + and_radio_reg(pi, RADIO_2064_REG05B, 0xfD); + + or_radio_reg(pi, RADIO_2064_REG004, 0x40); + or_radio_reg(pi, RADIO_2064_REG120, 0x10); + + or_radio_reg(pi, RADIO_2064_REG078, 0x80); + or_radio_reg(pi, RADIO_2064_REG129, 0x02); + + or_radio_reg(pi, RADIO_2064_REG057, 0x01); + + or_radio_reg(pi, RADIO_2064_REG05B, 0x02); + mdelay(5); + SPINWAIT(!wlc_radio_2064_rcal_done(pi), 10 * 1000 * 1000); + + if (wlc_radio_2064_rcal_done(pi)) { + rcal_value = (u8) read_radio_reg(pi, RADIO_2064_REG05C); + rcal_value = rcal_value & 0x1f; + } + + and_radio_reg(pi, RADIO_2064_REG05B, 0xfD); + + and_radio_reg(pi, RADIO_2064_REG057, 0xFE); +} + +static void wlc_lcnphy_rc_cal(phy_info_t *pi) +{ + u8 dflt_rc_cal_val; + u16 flt_val; + + if (NORADIO_ENAB(pi->pubpi)) + return; + + dflt_rc_cal_val = 7; + if (LCNREV_IS(pi->pubpi.phy_rev, 1)) + dflt_rc_cal_val = 11; + flt_val = + (dflt_rc_cal_val << 10) | (dflt_rc_cal_val << 5) | + (dflt_rc_cal_val); + write_phy_reg(pi, 0x933, flt_val); + write_phy_reg(pi, 0x934, flt_val); + write_phy_reg(pi, 0x935, flt_val); + write_phy_reg(pi, 0x936, flt_val); + write_phy_reg(pi, 0x937, (flt_val & 0x1FF)); + + return; +} + +static bool wlc_phy_txpwr_srom_read_lcnphy(phy_info_t *pi) +{ + s8 txpwr = 0; + int i; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + u16 cckpo = 0; + u32 offset_ofdm, offset_mcs; + + pi_lcn->lcnphy_tr_isolation_mid = + (u8) PHY_GETINTVAR(pi, "triso2g"); + + pi_lcn->lcnphy_rx_power_offset = + (u8) PHY_GETINTVAR(pi, "rxpo2g"); + + pi->txpa_2g[0] = (s16) PHY_GETINTVAR(pi, "pa0b0"); + pi->txpa_2g[1] = (s16) PHY_GETINTVAR(pi, "pa0b1"); + pi->txpa_2g[2] = (s16) PHY_GETINTVAR(pi, "pa0b2"); + + pi_lcn->lcnphy_rssi_vf = (u8) PHY_GETINTVAR(pi, "rssismf2g"); + pi_lcn->lcnphy_rssi_vc = (u8) PHY_GETINTVAR(pi, "rssismc2g"); + pi_lcn->lcnphy_rssi_gs = (u8) PHY_GETINTVAR(pi, "rssisav2g"); + + { + pi_lcn->lcnphy_rssi_vf_lowtemp = pi_lcn->lcnphy_rssi_vf; + pi_lcn->lcnphy_rssi_vc_lowtemp = pi_lcn->lcnphy_rssi_vc; + pi_lcn->lcnphy_rssi_gs_lowtemp = pi_lcn->lcnphy_rssi_gs; + + pi_lcn->lcnphy_rssi_vf_hightemp = + pi_lcn->lcnphy_rssi_vf; + pi_lcn->lcnphy_rssi_vc_hightemp = + pi_lcn->lcnphy_rssi_vc; + pi_lcn->lcnphy_rssi_gs_hightemp = + pi_lcn->lcnphy_rssi_gs; + } + + txpwr = (s8) PHY_GETINTVAR(pi, "maxp2ga0"); + pi->tx_srom_max_2g = txpwr; + + for (i = 0; i < PWRTBL_NUM_COEFF; i++) { + pi->txpa_2g_low_temp[i] = pi->txpa_2g[i]; + pi->txpa_2g_high_temp[i] = pi->txpa_2g[i]; + } + + cckpo = (u16) PHY_GETINTVAR(pi, "cck2gpo"); + if (cckpo) { + uint max_pwr_chan = txpwr; + + for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) { + pi->tx_srom_max_rate_2g[i] = max_pwr_chan - + ((cckpo & 0xf) * 2); + cckpo >>= 4; + } + + offset_ofdm = (u32) PHY_GETINTVAR(pi, "ofdm2gpo"); + for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) { + pi->tx_srom_max_rate_2g[i] = max_pwr_chan - + ((offset_ofdm & 0xf) * 2); + offset_ofdm >>= 4; + } + } else { + u8 opo = 0; + + opo = (u8) PHY_GETINTVAR(pi, "opo"); + + for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) { + pi->tx_srom_max_rate_2g[i] = txpwr; + } + + offset_ofdm = (u32) PHY_GETINTVAR(pi, "ofdm2gpo"); + + for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) { + pi->tx_srom_max_rate_2g[i] = txpwr - + ((offset_ofdm & 0xf) * 2); + offset_ofdm >>= 4; + } + offset_mcs = + ((u16) PHY_GETINTVAR(pi, "mcs2gpo1") << 16) | + (u16) PHY_GETINTVAR(pi, "mcs2gpo0"); + pi_lcn->lcnphy_mcs20_po = offset_mcs; + for (i = TXP_FIRST_SISO_MCS_20; + i <= TXP_LAST_SISO_MCS_20; i++) { + pi->tx_srom_max_rate_2g[i] = + txpwr - ((offset_mcs & 0xf) * 2); + offset_mcs >>= 4; + } + } + + pi_lcn->lcnphy_rawtempsense = + (u16) PHY_GETINTVAR(pi, "rawtempsense"); + pi_lcn->lcnphy_measPower = + (u8) PHY_GETINTVAR(pi, "measpower"); + pi_lcn->lcnphy_tempsense_slope = + (u8) PHY_GETINTVAR(pi, "tempsense_slope"); + pi_lcn->lcnphy_hw_iqcal_en = + (bool) PHY_GETINTVAR(pi, "hw_iqcal_en"); + pi_lcn->lcnphy_iqcal_swp_dis = + (bool) PHY_GETINTVAR(pi, "iqcal_swp_dis"); + pi_lcn->lcnphy_tempcorrx = + (u8) PHY_GETINTVAR(pi, "tempcorrx"); + pi_lcn->lcnphy_tempsense_option = + (u8) PHY_GETINTVAR(pi, "tempsense_option"); + pi_lcn->lcnphy_freqoffset_corr = + (u8) PHY_GETINTVAR(pi, "freqoffset_corr"); + if ((u8) getintvar(pi->vars, "aa2g") > 1) + wlc_phy_ant_rxdiv_set((wlc_phy_t *) pi, + (u8) getintvar(pi->vars, + "aa2g")); + } + pi_lcn->lcnphy_cck_dig_filt_type = -1; + if (PHY_GETVAR(pi, "cckdigfilttype")) { + s16 temp; + temp = (s16) PHY_GETINTVAR(pi, "cckdigfilttype"); + if (temp >= 0) { + pi_lcn->lcnphy_cck_dig_filt_type = temp; + } + } + + return true; +} + +void wlc_2064_vco_cal(phy_info_t *pi) +{ + u8 calnrst; + + mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 1 << 3); + calnrst = (u8) read_radio_reg(pi, RADIO_2064_REG056) & 0xf8; + write_radio_reg(pi, RADIO_2064_REG056, calnrst); + udelay(1); + write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x03); + udelay(1); + write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x07); + udelay(300); + mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 0); +} + +static void +wlc_lcnphy_radio_2064_channel_tune_4313(phy_info_t *pi, u8 channel) +{ + uint i; + const chan_info_2064_lcnphy_t *ci; + u8 rfpll_doubler = 0; + u8 pll_pwrup, pll_pwrup_ovr; + fixed qFxtal, qFref, qFvco, qFcal; + u8 d15, d16, f16, e44, e45; + u32 div_int, div_frac, fvco3, fpfd, fref3, fcal_div; + u16 loop_bw, d30, setCount; + if (NORADIO_ENAB(pi->pubpi)) + return; + ci = &chan_info_2064_lcnphy[0]; + rfpll_doubler = 1; + + mod_radio_reg(pi, RADIO_2064_REG09D, 0x4, 0x1 << 2); + + write_radio_reg(pi, RADIO_2064_REG09E, 0xf); + if (!rfpll_doubler) { + loop_bw = PLL_2064_LOOP_BW; + d30 = PLL_2064_D30; + } else { + loop_bw = PLL_2064_LOOP_BW_DOUBLER; + d30 = PLL_2064_D30_DOUBLER; + } + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + for (i = 0; i < ARRAY_SIZE(chan_info_2064_lcnphy); i++) + if (chan_info_2064_lcnphy[i].chan == channel) + break; + + if (i >= ARRAY_SIZE(chan_info_2064_lcnphy)) { + return; + } + + ci = &chan_info_2064_lcnphy[i]; + } + + write_radio_reg(pi, RADIO_2064_REG02A, ci->logen_buftune); + + mod_radio_reg(pi, RADIO_2064_REG030, 0x3, ci->logen_rccr_tx); + + mod_radio_reg(pi, RADIO_2064_REG091, 0x3, ci->txrf_mix_tune_ctrl); + + mod_radio_reg(pi, RADIO_2064_REG038, 0xf, ci->pa_input_tune_g); + + mod_radio_reg(pi, RADIO_2064_REG030, 0x3 << 2, + (ci->logen_rccr_rx) << 2); + + mod_radio_reg(pi, RADIO_2064_REG05E, 0xf, ci->pa_rxrf_lna1_freq_tune); + + mod_radio_reg(pi, RADIO_2064_REG05E, (0xf) << 4, + (ci->pa_rxrf_lna2_freq_tune) << 4); + + write_radio_reg(pi, RADIO_2064_REG06C, ci->rxrf_rxrf_spare1); + + pll_pwrup = (u8) read_radio_reg(pi, RADIO_2064_REG044); + pll_pwrup_ovr = (u8) read_radio_reg(pi, RADIO_2064_REG12B); + + or_radio_reg(pi, RADIO_2064_REG044, 0x07); + + or_radio_reg(pi, RADIO_2064_REG12B, (0x07) << 1); + e44 = 0; + e45 = 0; + + fpfd = rfpll_doubler ? (pi->xtalfreq << 1) : (pi->xtalfreq); + if (pi->xtalfreq > 26000000) + e44 = 1; + if (pi->xtalfreq > 52000000) + e45 = 1; + if (e44 == 0) + fcal_div = 1; + else if (e45 == 0) + fcal_div = 2; + else + fcal_div = 4; + fvco3 = (ci->freq * 3); + fref3 = 2 * fpfd; + + qFxtal = wlc_lcnphy_qdiv_roundup(pi->xtalfreq, PLL_2064_MHZ, 16); + qFref = wlc_lcnphy_qdiv_roundup(fpfd, PLL_2064_MHZ, 16); + qFcal = pi->xtalfreq * fcal_div / PLL_2064_MHZ; + qFvco = wlc_lcnphy_qdiv_roundup(fvco3, 2, 16); + + write_radio_reg(pi, RADIO_2064_REG04F, 0x02); + + d15 = (pi->xtalfreq * fcal_div * 4 / 5) / PLL_2064_MHZ - 1; + write_radio_reg(pi, RADIO_2064_REG052, (0x07 & (d15 >> 2))); + write_radio_reg(pi, RADIO_2064_REG053, (d15 & 0x3) << 5); + + d16 = (qFcal * 8 / (d15 + 1)) - 1; + write_radio_reg(pi, RADIO_2064_REG051, d16); + + f16 = ((d16 + 1) * (d15 + 1)) / qFcal; + setCount = f16 * 3 * (ci->freq) / 32 - 1; + mod_radio_reg(pi, RADIO_2064_REG053, (0x0f << 0), + (u8) (setCount >> 8)); + + or_radio_reg(pi, RADIO_2064_REG053, 0x10); + write_radio_reg(pi, RADIO_2064_REG054, (u8) (setCount & 0xff)); + + div_int = ((fvco3 * (PLL_2064_MHZ >> 4)) / fref3) << 4; + + div_frac = ((fvco3 * (PLL_2064_MHZ >> 4)) % fref3) << 4; + while (div_frac >= fref3) { + div_int++; + div_frac -= fref3; + } + div_frac = wlc_lcnphy_qdiv_roundup(div_frac, fref3, 20); + + mod_radio_reg(pi, RADIO_2064_REG045, (0x1f << 0), + (u8) (div_int >> 4)); + mod_radio_reg(pi, RADIO_2064_REG046, (0x1f << 4), + (u8) (div_int << 4)); + mod_radio_reg(pi, RADIO_2064_REG046, (0x0f << 0), + (u8) (div_frac >> 16)); + write_radio_reg(pi, RADIO_2064_REG047, (u8) (div_frac >> 8) & 0xff); + write_radio_reg(pi, RADIO_2064_REG048, (u8) div_frac & 0xff); + + write_radio_reg(pi, RADIO_2064_REG040, 0xfb); + + write_radio_reg(pi, RADIO_2064_REG041, 0x9A); + write_radio_reg(pi, RADIO_2064_REG042, 0xA3); + write_radio_reg(pi, RADIO_2064_REG043, 0x0C); + + { + u8 h29, h23, c28, d29, h28_ten, e30, h30_ten, cp_current; + u16 c29, c38, c30, g30, d28; + c29 = loop_bw; + d29 = 200; + c38 = 1250; + h29 = d29 / c29; + h23 = 1; + c28 = 30; + d28 = (((PLL_2064_HIGH_END_KVCO - PLL_2064_LOW_END_KVCO) * + (fvco3 / 2 - PLL_2064_LOW_END_VCO)) / + (PLL_2064_HIGH_END_VCO - PLL_2064_LOW_END_VCO)) + + PLL_2064_LOW_END_KVCO; + h28_ten = (d28 * 10) / c28; + c30 = 2640; + e30 = (d30 - 680) / 490; + g30 = 680 + (e30 * 490); + h30_ten = (g30 * 10) / c30; + cp_current = ((c38 * h29 * h23 * 100) / h28_ten) / h30_ten; + mod_radio_reg(pi, RADIO_2064_REG03C, 0x3f, cp_current); + } + if (channel >= 1 && channel <= 5) + write_radio_reg(pi, RADIO_2064_REG03C, 0x8); + else + write_radio_reg(pi, RADIO_2064_REG03C, 0x7); + write_radio_reg(pi, RADIO_2064_REG03D, 0x3); + + mod_radio_reg(pi, RADIO_2064_REG044, 0x0c, 0x0c); + udelay(1); + + wlc_2064_vco_cal(pi); + + write_radio_reg(pi, RADIO_2064_REG044, pll_pwrup); + write_radio_reg(pi, RADIO_2064_REG12B, pll_pwrup_ovr); + if (LCNREV_IS(pi->pubpi.phy_rev, 1)) { + write_radio_reg(pi, RADIO_2064_REG038, 3); + write_radio_reg(pi, RADIO_2064_REG091, 7); + } +} + +bool wlc_phy_tpc_isenabled_lcnphy(phy_info_t *pi) +{ + if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) + return 0; + else + return (LCNPHY_TX_PWR_CTRL_HW == + wlc_lcnphy_get_tx_pwr_ctrl((pi))); +} + +void wlc_phy_txpower_recalc_target_lcnphy(phy_info_t *pi) +{ + u16 pwr_ctrl; + if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) { + wlc_lcnphy_calib_modes(pi, LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL); + } else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) { + + pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); + wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); + wlc_lcnphy_txpower_recalc_target(pi); + + wlc_lcnphy_set_tx_pwr_ctrl(pi, pwr_ctrl); + } else + return; +} + +void wlc_phy_detach_lcnphy(phy_info_t *pi) +{ + kfree(pi->u.pi_lcnphy); +} + +bool wlc_phy_attach_lcnphy(phy_info_t *pi) +{ + phy_info_lcnphy_t *pi_lcn; + + pi->u.pi_lcnphy = kzalloc(sizeof(phy_info_lcnphy_t), GFP_ATOMIC); + if (pi->u.pi_lcnphy == NULL) { + return false; + } + + pi_lcn = pi->u.pi_lcnphy; + + if ((0 == (pi->sh->boardflags & BFL_NOPA)) && !NORADIO_ENAB(pi->pubpi)) { + pi->hwpwrctrl = true; + pi->hwpwrctrl_capable = true; + } + + pi->xtalfreq = si_alp_clock(pi->sh->sih); + ASSERT(0 == (pi->xtalfreq % 1000)); + + pi_lcn->lcnphy_papd_rxGnCtrl_init = 0; + + pi->pi_fptr.init = wlc_phy_init_lcnphy; + pi->pi_fptr.calinit = wlc_phy_cal_init_lcnphy; + pi->pi_fptr.chanset = wlc_phy_chanspec_set_lcnphy; + pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_lcnphy; + pi->pi_fptr.txiqccget = wlc_lcnphy_get_tx_iqcc; + pi->pi_fptr.txiqccset = wlc_lcnphy_set_tx_iqcc; + pi->pi_fptr.txloccget = wlc_lcnphy_get_tx_locc; + pi->pi_fptr.radioloftget = wlc_lcnphy_get_radio_loft; + pi->pi_fptr.detach = wlc_phy_detach_lcnphy; + + if (!wlc_phy_txpwr_srom_read_lcnphy(pi)) + return false; + + if ((pi->sh->boardflags & BFL_FEM) && (LCNREV_IS(pi->pubpi.phy_rev, 1))) { + if (pi_lcn->lcnphy_tempsense_option == 3) { + pi->hwpwrctrl = true; + pi->hwpwrctrl_capable = true; + pi->temppwrctrl_capable = false; + } else { + pi->hwpwrctrl = false; + pi->hwpwrctrl_capable = false; + pi->temppwrctrl_capable = true; + } + } + + return true; +} + +static void wlc_lcnphy_set_rx_gain(phy_info_t *pi, u32 gain) +{ + u16 trsw, ext_lna, lna1, lna2, tia, biq0, biq1, gain0_15, gain16_19; + + trsw = (gain & ((u32) 1 << 28)) ? 0 : 1; + ext_lna = (u16) (gain >> 29) & 0x01; + lna1 = (u16) (gain >> 0) & 0x0f; + lna2 = (u16) (gain >> 4) & 0x0f; + tia = (u16) (gain >> 8) & 0xf; + biq0 = (u16) (gain >> 12) & 0xf; + biq1 = (u16) (gain >> 16) & 0xf; + + gain0_15 = (u16) ((lna1 & 0x3) | ((lna1 & 0x3) << 2) | + ((lna2 & 0x3) << 4) | ((lna2 & 0x3) << 6) | + ((tia & 0xf) << 8) | ((biq0 & 0xf) << 12)); + gain16_19 = biq1; + + mod_phy_reg(pi, 0x44d, (0x1 << 0), trsw << 0); + mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9); + mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10); + mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0); + mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11); + mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3); + } + wlc_lcnphy_rx_gain_override_enable(pi, true); +} + +static u32 wlc_lcnphy_get_receive_power(phy_info_t *pi, s32 *gain_index) +{ + u32 received_power = 0; + s32 max_index = 0; + u32 gain_code = 0; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + max_index = 36; + if (*gain_index >= 0) + gain_code = lcnphy_23bitgaincode_table[*gain_index]; + + if (-1 == *gain_index) { + *gain_index = 0; + while ((*gain_index <= (s32) max_index) + && (received_power < 700)) { + wlc_lcnphy_set_rx_gain(pi, + lcnphy_23bitgaincode_table + [*gain_index]); + received_power = + wlc_lcnphy_measure_digital_power(pi, + pi_lcn-> + lcnphy_noise_samples); + (*gain_index)++; + } + (*gain_index)--; + } else { + wlc_lcnphy_set_rx_gain(pi, gain_code); + received_power = + wlc_lcnphy_measure_digital_power(pi, + pi_lcn-> + lcnphy_noise_samples); + } + + return received_power; +} + +s32 wlc_lcnphy_rx_signal_power(phy_info_t *pi, s32 gain_index) +{ + s32 gain = 0; + s32 nominal_power_db; + s32 log_val, gain_mismatch, desired_gain, input_power_offset_db, + input_power_db; + s32 received_power, temperature; + uint freq; + phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + + received_power = wlc_lcnphy_get_receive_power(pi, &gain_index); + + gain = lcnphy_gain_table[gain_index]; + + nominal_power_db = read_phy_reg(pi, 0x425) >> 8; + + { + u32 power = (received_power * 16); + u32 msb1, msb2, val1, val2, diff1, diff2; + msb1 = ffs(power) - 1; + msb2 = msb1 + 1; + val1 = 1 << msb1; + val2 = 1 << msb2; + diff1 = (power - val1); + diff2 = (val2 - power); + if (diff1 < diff2) + log_val = msb1; + else + log_val = msb2; + } + + log_val = log_val * 3; + + gain_mismatch = (nominal_power_db / 2) - (log_val); + + desired_gain = gain + gain_mismatch; + + input_power_offset_db = read_phy_reg(pi, 0x434) & 0xFF; + + if (input_power_offset_db > 127) + input_power_offset_db -= 256; + + input_power_db = input_power_offset_db - desired_gain; + + input_power_db = + input_power_db + lcnphy_gain_index_offset_for_rssi[gain_index]; + + freq = wlc_phy_channel2freq(CHSPEC_CHANNEL(pi->radio_chanspec)); + if ((freq > 2427) && (freq <= 2467)) + input_power_db = input_power_db - 1; + + temperature = pi_lcn->lcnphy_lastsensed_temperature; + + if ((temperature - 15) < -30) { + input_power_db = + input_power_db + (((temperature - 10 - 25) * 286) >> 12) - + 7; + } else if ((temperature - 15) < 4) { + input_power_db = + input_power_db + (((temperature - 10 - 25) * 286) >> 12) - + 3; + } else { + input_power_db = + input_power_db + (((temperature - 10 - 25) * 286) >> 12); + } + + wlc_lcnphy_rx_gain_override_enable(pi, 0); + + return input_power_db; +} + +static int +wlc_lcnphy_load_tx_iir_filter(phy_info_t *pi, bool is_ofdm, s16 filt_type) +{ + s16 filt_index = -1; + int j; + + u16 addr[] = { + 0x910, + 0x91e, + 0x91f, + 0x924, + 0x925, + 0x926, + 0x920, + 0x921, + 0x927, + 0x928, + 0x929, + 0x922, + 0x923, + 0x930, + 0x931, + 0x932 + }; + + u16 addr_ofdm[] = { + 0x90f, + 0x900, + 0x901, + 0x906, + 0x907, + 0x908, + 0x902, + 0x903, + 0x909, + 0x90a, + 0x90b, + 0x904, + 0x905, + 0x90c, + 0x90d, + 0x90e + }; + + if (!is_ofdm) { + for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_CCK; j++) { + if (filt_type == LCNPHY_txdigfiltcoeffs_cck[j][0]) { + filt_index = (s16) j; + break; + } + } + + if (filt_index == -1) { + ASSERT(false); + } else { + for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) { + write_phy_reg(pi, addr[j], + LCNPHY_txdigfiltcoeffs_cck + [filt_index][j + 1]); + } + } + } else { + for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_OFDM; j++) { + if (filt_type == LCNPHY_txdigfiltcoeffs_ofdm[j][0]) { + filt_index = (s16) j; + break; + } + } + + if (filt_index == -1) { + ASSERT(false); + } else { + for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) { + write_phy_reg(pi, addr_ofdm[j], + LCNPHY_txdigfiltcoeffs_ofdm + [filt_index][j + 1]); + } + } + } + + return (filt_index != -1) ? 0 : -1; +} diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h new file mode 100644 index 000000000000..b7bfc7230dfc --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_phy_lcn_h_ +#define _wlc_phy_lcn_h_ + +struct phy_info_lcnphy { + int lcnphy_txrf_sp_9_override; + u8 lcnphy_full_cal_channel; + u8 lcnphy_cal_counter; + u16 lcnphy_cal_temper; + bool lcnphy_recal; + + u8 lcnphy_rc_cap; + u32 lcnphy_mcs20_po; + + u8 lcnphy_tr_isolation_mid; + u8 lcnphy_tr_isolation_low; + u8 lcnphy_tr_isolation_hi; + + u8 lcnphy_bx_arch; + u8 lcnphy_rx_power_offset; + u8 lcnphy_rssi_vf; + u8 lcnphy_rssi_vc; + u8 lcnphy_rssi_gs; + u8 lcnphy_tssi_val; + u8 lcnphy_rssi_vf_lowtemp; + u8 lcnphy_rssi_vc_lowtemp; + u8 lcnphy_rssi_gs_lowtemp; + + u8 lcnphy_rssi_vf_hightemp; + u8 lcnphy_rssi_vc_hightemp; + u8 lcnphy_rssi_gs_hightemp; + + s16 lcnphy_pa0b0; + s16 lcnphy_pa0b1; + s16 lcnphy_pa0b2; + + u16 lcnphy_rawtempsense; + u8 lcnphy_measPower; + u8 lcnphy_tempsense_slope; + u8 lcnphy_freqoffset_corr; + u8 lcnphy_tempsense_option; + u8 lcnphy_tempcorrx; + bool lcnphy_iqcal_swp_dis; + bool lcnphy_hw_iqcal_en; + uint lcnphy_bandedge_corr; + bool lcnphy_spurmod; + u16 lcnphy_tssi_tx_cnt; + u16 lcnphy_tssi_idx; + u16 lcnphy_tssi_npt; + + u16 lcnphy_target_tx_freq; + s8 lcnphy_tx_power_idx_override; + u16 lcnphy_noise_samples; + + u32 lcnphy_papdRxGnIdx; + u32 lcnphy_papd_rxGnCtrl_init; + + u32 lcnphy_gain_idx_14_lowword; + u32 lcnphy_gain_idx_14_hiword; + u32 lcnphy_gain_idx_27_lowword; + u32 lcnphy_gain_idx_27_hiword; + s16 lcnphy_ofdmgainidxtableoffset; + s16 lcnphy_dsssgainidxtableoffset; + u32 lcnphy_tr_R_gain_val; + u32 lcnphy_tr_T_gain_val; + s8 lcnphy_input_pwr_offset_db; + u16 lcnphy_Med_Low_Gain_db; + u16 lcnphy_Very_Low_Gain_db; + s8 lcnphy_lastsensed_temperature; + s8 lcnphy_pkteng_rssi_slope; + u8 lcnphy_saved_tx_user_target[TXP_NUM_RATES]; + u8 lcnphy_volt_winner; + u8 lcnphy_volt_low; + u8 lcnphy_54_48_36_24mbps_backoff; + u8 lcnphy_11n_backoff; + u8 lcnphy_lowerofdm; + u8 lcnphy_cck; + u8 lcnphy_psat_2pt3_detected; + s32 lcnphy_lowest_Re_div_Im; + s8 lcnphy_final_papd_cal_idx; + u16 lcnphy_extstxctrl4; + u16 lcnphy_extstxctrl0; + u16 lcnphy_extstxctrl1; + s16 lcnphy_cck_dig_filt_type; + s16 lcnphy_ofdm_dig_filt_type; + lcnphy_cal_results_t lcnphy_cal_results; + + u8 lcnphy_psat_pwr; + u8 lcnphy_psat_indx; + s32 lcnphy_min_phase; + u8 lcnphy_final_idx; + u8 lcnphy_start_idx; + u8 lcnphy_current_index; + u16 lcnphy_logen_buf_1; + u16 lcnphy_local_ovr_2; + u16 lcnphy_local_oval_6; + u16 lcnphy_local_oval_5; + u16 lcnphy_logen_mixer_1; + + u8 lcnphy_aci_stat; + uint lcnphy_aci_start_time; + s8 lcnphy_tx_power_offset[TXP_NUM_RATES]; +}; +#endif /* _wlc_phy_lcn_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c new file mode 100644 index 000000000000..c6cce8de1aee --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c @@ -0,0 +1,29239 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#define READ_RADIO_REG2(pi, radio_type, jspace, core, reg_name) \ + read_radio_reg(pi, radio_type##_##jspace##_##reg_name | \ + ((core == PHY_CORE_0) ? radio_type##_##jspace##0 : radio_type##_##jspace##1)) +#define WRITE_RADIO_REG2(pi, radio_type, jspace, core, reg_name, value) \ + write_radio_reg(pi, radio_type##_##jspace##_##reg_name | \ + ((core == PHY_CORE_0) ? radio_type##_##jspace##0 : radio_type##_##jspace##1), value); +#define WRITE_RADIO_SYN(pi, radio_type, reg_name, value) \ + write_radio_reg(pi, radio_type##_##SYN##_##reg_name, value); + +#define READ_RADIO_REG3(pi, radio_type, jspace, core, reg_name) \ + read_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##jspace##0##_##reg_name : \ + radio_type##_##jspace##1##_##reg_name)); +#define WRITE_RADIO_REG3(pi, radio_type, jspace, core, reg_name, value) \ + write_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##jspace##0##_##reg_name : \ + radio_type##_##jspace##1##_##reg_name), value); +#define READ_RADIO_REG4(pi, radio_type, jspace, core, reg_name) \ + read_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##reg_name##_##jspace##0 : \ + radio_type##_##reg_name##_##jspace##1)); +#define WRITE_RADIO_REG4(pi, radio_type, jspace, core, reg_name, value) \ + write_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##reg_name##_##jspace##0 : \ + radio_type##_##reg_name##_##jspace##1), value); + +#define NPHY_ACI_MAX_UNDETECT_WINDOW_SZ 40 +#define NPHY_ACI_CHANNEL_DELTA 5 +#define NPHY_ACI_CHANNEL_SKIP 4 +#define NPHY_ACI_40MHZ_CHANNEL_DELTA 6 +#define NPHY_ACI_40MHZ_CHANNEL_SKIP 5 +#define NPHY_ACI_40MHZ_CHANNEL_DELTA_GE_REV3 6 +#define NPHY_ACI_40MHZ_CHANNEL_SKIP_GE_REV3 5 +#define NPHY_ACI_CHANNEL_DELTA_GE_REV3 4 +#define NPHY_ACI_CHANNEL_SKIP_GE_REV3 3 + +#define NPHY_NOISE_NOASSOC_GLITCH_TH_UP 2 + +#define NPHY_NOISE_NOASSOC_GLITCH_TH_DN 8 + +#define NPHY_NOISE_ASSOC_GLITCH_TH_UP 2 + +#define NPHY_NOISE_ASSOC_GLITCH_TH_DN 8 + +#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_UP 2 + +#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_DN 8 + +#define NPHY_NOISE_NOASSOC_ENTER_TH 400 + +#define NPHY_NOISE_ASSOC_ENTER_TH 400 + +#define NPHY_NOISE_ASSOC_RX_GLITCH_BADPLCP_ENTER_TH 400 + +#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX 44 +#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX_REV_7 56 + +#define NPHY_NOISE_NOASSOC_CRSIDX_INCR 16 + +#define NPHY_NOISE_ASSOC_CRSIDX_INCR 8 + +#define NPHY_IS_SROM_REINTERPRET NREV_GE(pi->pubpi.phy_rev, 5) + +#define NPHY_RSSICAL_MAXREAD 31 + +#define NPHY_RSSICAL_NPOLL 8 +#define NPHY_RSSICAL_MAXD (1<<20) +#define NPHY_MIN_RXIQ_PWR 2 + +#define NPHY_RSSICAL_W1_TARGET 25 +#define NPHY_RSSICAL_W2_TARGET NPHY_RSSICAL_W1_TARGET +#define NPHY_RSSICAL_NB_TARGET 0 + +#define NPHY_RSSICAL_W1_TARGET_REV3 29 +#define NPHY_RSSICAL_W2_TARGET_REV3 NPHY_RSSICAL_W1_TARGET_REV3 + +#define NPHY_CALSANITY_RSSI_NB_MAX_POS 9 +#define NPHY_CALSANITY_RSSI_NB_MAX_NEG -9 +#define NPHY_CALSANITY_RSSI_W1_MAX_POS 12 +#define NPHY_CALSANITY_RSSI_W1_MAX_NEG (NPHY_RSSICAL_W1_TARGET - NPHY_RSSICAL_MAXREAD) +#define NPHY_CALSANITY_RSSI_W2_MAX_POS NPHY_CALSANITY_RSSI_W1_MAX_POS +#define NPHY_CALSANITY_RSSI_W2_MAX_NEG (NPHY_RSSICAL_W2_TARGET - NPHY_RSSICAL_MAXREAD) +#define NPHY_RSSI_SXT(x) ((s8) (-((x) & 0x20) + ((x) & 0x1f))) +#define NPHY_RSSI_NB_VIOL(x) (((x) > NPHY_CALSANITY_RSSI_NB_MAX_POS) || \ + ((x) < NPHY_CALSANITY_RSSI_NB_MAX_NEG)) +#define NPHY_RSSI_W1_VIOL(x) (((x) > NPHY_CALSANITY_RSSI_W1_MAX_POS) || \ + ((x) < NPHY_CALSANITY_RSSI_W1_MAX_NEG)) +#define NPHY_RSSI_W2_VIOL(x) (((x) > NPHY_CALSANITY_RSSI_W2_MAX_POS) || \ + ((x) < NPHY_CALSANITY_RSSI_W2_MAX_NEG)) + +#define NPHY_IQCAL_NUMGAINS 9 +#define NPHY_N_GCTL 0x66 + +#define NPHY_PAPD_EPS_TBL_SIZE 64 +#define NPHY_PAPD_SCL_TBL_SIZE 64 +#define NPHY_NUM_DIG_FILT_COEFFS 15 + +#define NPHY_PAPD_COMP_OFF 0 +#define NPHY_PAPD_COMP_ON 1 + +#define NPHY_SROM_TEMPSHIFT 32 +#define NPHY_SROM_MAXTEMPOFFSET 16 +#define NPHY_SROM_MINTEMPOFFSET -16 + +#define NPHY_CAL_MAXTEMPDELTA 64 + +#define NPHY_NOISEVAR_TBLLEN40 256 +#define NPHY_NOISEVAR_TBLLEN20 128 + +#define NPHY_ANARXLPFBW_REDUCTIONFACT 7 + +#define NPHY_ADJUSTED_MINCRSPOWER 0x1e + +typedef struct _nphy_iqcal_params { + u16 txlpf; + u16 txgm; + u16 pga; + u16 pad; + u16 ipa; + u16 cal_gain; + u16 ncorr[5]; +} nphy_iqcal_params_t; + +typedef struct _nphy_txiqcal_ladder { + u8 percent; + u8 g_env; +} nphy_txiqcal_ladder_t; + +typedef struct { + nphy_txgains_t gains; + bool useindex; + u8 index; +} nphy_ipa_txcalgains_t; + +typedef struct nphy_papd_restore_state_t { + u16 fbmix[2]; + u16 vga_master[2]; + u16 intpa_master[2]; + u16 afectrl[2]; + u16 afeoverride[2]; + u16 pwrup[2]; + u16 atten[2]; + u16 mm; +} nphy_papd_restore_state; + +typedef struct _nphy_ipa_txrxgain { + u16 hpvga; + u16 lpf_biq1; + u16 lpf_biq0; + u16 lna2; + u16 lna1; + s8 txpwrindex; +} nphy_ipa_txrxgain_t; + +#define NPHY_IPA_RXCAL_MAXGAININDEX (6 - 1) + +nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_5GHz[] = { {0, 0, 0, 0, 0, 100}, +{0, 0, 0, 0, 0, 50}, +{0, 0, 0, 0, 0, -1}, +{0, 0, 0, 3, 0, -1}, +{0, 0, 3, 3, 0, -1}, +{0, 2, 3, 3, 0, -1} +}; + +nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_2GHz[] = { {0, 0, 0, 0, 0, 128}, +{0, 0, 0, 0, 0, 70}, +{0, 0, 0, 0, 0, 20}, +{0, 0, 0, 3, 0, 20}, +{0, 0, 3, 3, 0, 20}, +{0, 2, 3, 3, 0, 20} +}; + +nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_5GHz_rev7[] = { {0, 0, 0, 0, 0, 100}, +{0, 0, 0, 0, 0, 50}, +{0, 0, 0, 0, 0, -1}, +{0, 0, 0, 3, 0, -1}, +{0, 0, 3, 3, 0, -1}, +{0, 0, 5, 3, 0, -1} +}; + +nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_2GHz_rev7[] = { {0, 0, 0, 0, 0, 10}, +{0, 0, 0, 1, 0, 10}, +{0, 0, 1, 2, 0, 10}, +{0, 0, 1, 3, 0, 10}, +{0, 0, 4, 3, 0, 10}, +{0, 0, 6, 3, 0, 10} +}; + +#define NPHY_RXCAL_TONEAMP 181 +#define NPHY_RXCAL_TONEFREQ_40MHz 4000 +#define NPHY_RXCAL_TONEFREQ_20MHz 2000 + +enum { + NPHY_RXCAL_GAIN_INIT = 0, + NPHY_RXCAL_GAIN_UP, + NPHY_RXCAL_GAIN_DOWN +}; + +#define wlc_phy_get_papd_nphy(pi) \ + (read_phy_reg((pi), 0x1e7) & \ + ((0x1 << 15) | \ + (0x1 << 14) | \ + (0x1 << 13))) + +#define TXFILT_SHAPING_OFDM20 0 +#define TXFILT_SHAPING_OFDM40 1 +#define TXFILT_SHAPING_CCK 2 +#define TXFILT_DEFAULT_OFDM20 3 +#define TXFILT_DEFAULT_OFDM40 4 + +u16 NPHY_IPA_REV4_txdigi_filtcoeffs[][NPHY_NUM_DIG_FILT_COEFFS] = { + {-377, 137, -407, 208, -1527, 956, 93, 186, 93, + 230, -44, 230, 201, -191, 201}, + {-77, 20, -98, 49, -93, 60, 56, 111, 56, 26, -5, + 26, 34, -32, 34}, + {-360, 164, -376, 164, -1533, 576, 308, -314, 308, + 121, -73, 121, 91, 124, 91}, + {-295, 200, -363, 142, -1391, 826, 151, 301, 151, + 151, 301, 151, 602, -752, 602}, + {-92, 58, -96, 49, -104, 44, 17, 35, 17, + 12, 25, 12, 13, 27, 13}, + {-375, 136, -399, 209, -1479, 949, 130, 260, 130, + 230, -44, 230, 201, -191, 201}, + {0xed9, 0xc8, 0xe95, 0x8e, 0xa91, 0x33a, 0x97, 0x12d, 0x97, + 0x97, 0x12d, 0x97, 0x25a, 0xd10, 0x25a} +}; + +typedef struct _chan_info_nphy_2055 { + u16 chan; + u16 freq; + uint unknown; + u8 RF_pll_ref; + u8 RF_rf_pll_mod1; + u8 RF_rf_pll_mod0; + u8 RF_vco_cap_tail; + u8 RF_vco_cal1; + u8 RF_vco_cal2; + u8 RF_pll_lf_c1; + u8 RF_pll_lf_r1; + u8 RF_pll_lf_c2; + u8 RF_lgbuf_cen_buf; + u8 RF_lgen_tune1; + u8 RF_lgen_tune2; + u8 RF_core1_lgbuf_a_tune; + u8 RF_core1_lgbuf_g_tune; + u8 RF_core1_rxrf_reg1; + u8 RF_core1_tx_pga_pad_tn; + u8 RF_core1_tx_mx_bgtrim; + u8 RF_core2_lgbuf_a_tune; + u8 RF_core2_lgbuf_g_tune; + u8 RF_core2_rxrf_reg1; + u8 RF_core2_tx_pga_pad_tn; + u8 RF_core2_tx_mx_bgtrim; + u16 PHY_BW1a; + u16 PHY_BW2; + u16 PHY_BW3; + u16 PHY_BW4; + u16 PHY_BW5; + u16 PHY_BW6; +} chan_info_nphy_2055_t; + +typedef struct _chan_info_nphy_radio205x { + u16 chan; + u16 freq; + u8 RF_SYN_pll_vcocal1; + u8 RF_SYN_pll_vcocal2; + u8 RF_SYN_pll_refdiv; + u8 RF_SYN_pll_mmd2; + u8 RF_SYN_pll_mmd1; + u8 RF_SYN_pll_loopfilter1; + u8 RF_SYN_pll_loopfilter2; + u8 RF_SYN_pll_loopfilter3; + u8 RF_SYN_pll_loopfilter4; + u8 RF_SYN_pll_loopfilter5; + u8 RF_SYN_reserved_addr27; + u8 RF_SYN_reserved_addr28; + u8 RF_SYN_reserved_addr29; + u8 RF_SYN_logen_VCOBUF1; + u8 RF_SYN_logen_MIXER2; + u8 RF_SYN_logen_BUF3; + u8 RF_SYN_logen_BUF4; + u8 RF_RX0_lnaa_tune; + u8 RF_RX0_lnag_tune; + u8 RF_TX0_intpaa_boost_tune; + u8 RF_TX0_intpag_boost_tune; + u8 RF_TX0_pada_boost_tune; + u8 RF_TX0_padg_boost_tune; + u8 RF_TX0_pgaa_boost_tune; + u8 RF_TX0_pgag_boost_tune; + u8 RF_TX0_mixa_boost_tune; + u8 RF_TX0_mixg_boost_tune; + u8 RF_RX1_lnaa_tune; + u8 RF_RX1_lnag_tune; + u8 RF_TX1_intpaa_boost_tune; + u8 RF_TX1_intpag_boost_tune; + u8 RF_TX1_pada_boost_tune; + u8 RF_TX1_padg_boost_tune; + u8 RF_TX1_pgaa_boost_tune; + u8 RF_TX1_pgag_boost_tune; + u8 RF_TX1_mixa_boost_tune; + u8 RF_TX1_mixg_boost_tune; + u16 PHY_BW1a; + u16 PHY_BW2; + u16 PHY_BW3; + u16 PHY_BW4; + u16 PHY_BW5; + u16 PHY_BW6; +} chan_info_nphy_radio205x_t; + +typedef struct _chan_info_nphy_radio2057 { + u16 chan; + u16 freq; + u8 RF_vcocal_countval0; + u8 RF_vcocal_countval1; + u8 RF_rfpll_refmaster_sparextalsize; + u8 RF_rfpll_loopfilter_r1; + u8 RF_rfpll_loopfilter_c2; + u8 RF_rfpll_loopfilter_c1; + u8 RF_cp_kpd_idac; + u8 RF_rfpll_mmd0; + u8 RF_rfpll_mmd1; + u8 RF_vcobuf_tune; + u8 RF_logen_mx2g_tune; + u8 RF_logen_mx5g_tune; + u8 RF_logen_indbuf2g_tune; + u8 RF_logen_indbuf5g_tune; + u8 RF_txmix2g_tune_boost_pu_core0; + u8 RF_pad2g_tune_pus_core0; + u8 RF_pga_boost_tune_core0; + u8 RF_txmix5g_boost_tune_core0; + u8 RF_pad5g_tune_misc_pus_core0; + u8 RF_lna2g_tune_core0; + u8 RF_lna5g_tune_core0; + u8 RF_txmix2g_tune_boost_pu_core1; + u8 RF_pad2g_tune_pus_core1; + u8 RF_pga_boost_tune_core1; + u8 RF_txmix5g_boost_tune_core1; + u8 RF_pad5g_tune_misc_pus_core1; + u8 RF_lna2g_tune_core1; + u8 RF_lna5g_tune_core1; + u16 PHY_BW1a; + u16 PHY_BW2; + u16 PHY_BW3; + u16 PHY_BW4; + u16 PHY_BW5; + u16 PHY_BW6; +} chan_info_nphy_radio2057_t; + +typedef struct _chan_info_nphy_radio2057_rev5 { + u16 chan; + u16 freq; + u8 RF_vcocal_countval0; + u8 RF_vcocal_countval1; + u8 RF_rfpll_refmaster_sparextalsize; + u8 RF_rfpll_loopfilter_r1; + u8 RF_rfpll_loopfilter_c2; + u8 RF_rfpll_loopfilter_c1; + u8 RF_cp_kpd_idac; + u8 RF_rfpll_mmd0; + u8 RF_rfpll_mmd1; + u8 RF_vcobuf_tune; + u8 RF_logen_mx2g_tune; + u8 RF_logen_indbuf2g_tune; + u8 RF_txmix2g_tune_boost_pu_core0; + u8 RF_pad2g_tune_pus_core0; + u8 RF_lna2g_tune_core0; + u8 RF_txmix2g_tune_boost_pu_core1; + u8 RF_pad2g_tune_pus_core1; + u8 RF_lna2g_tune_core1; + u16 PHY_BW1a; + u16 PHY_BW2; + u16 PHY_BW3; + u16 PHY_BW4; + u16 PHY_BW5; + u16 PHY_BW6; +} chan_info_nphy_radio2057_rev5_t; + +typedef struct nphy_sfo_cfg { + u16 PHY_BW1a; + u16 PHY_BW2; + u16 PHY_BW3; + u16 PHY_BW4; + u16 PHY_BW5; + u16 PHY_BW6; +} nphy_sfo_cfg_t; + +static chan_info_nphy_2055_t chan_info_nphy_2055[] = { + { + 184, 4920, 3280, 0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, + 0x0F, 0x8F, 0x7B4, 0x7B0, 0x7AC, 0x214, 0x215, 0x216}, + { + 186, 4930, 3287, 0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, + 0x0F, 0x8F, 0x7B8, 0x7B4, 0x7B0, 0x213, 0x214, 0x215}, + { + 188, 4940, 3293, 0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, + 0x0F, 0x8F, 0x7BC, 0x7B8, 0x7B4, 0x212, 0x213, 0x214}, + { + 190, 4950, 3300, 0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, + 0x0F, 0x8F, 0x7C0, 0x7BC, 0x7B8, 0x211, 0x212, 0x213}, + { + 192, 4960, 3307, 0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, + 0x0F, 0x8F, 0x7C4, 0x7C0, 0x7BC, 0x20F, 0x211, 0x212}, + { + 194, 4970, 3313, 0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, + 0x0F, 0x8F, 0x7C8, 0x7C4, 0x7C0, 0x20E, 0x20F, 0x211}, + { + 196, 4980, 3320, 0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, + 0x0F, 0x8F, 0x7CC, 0x7C8, 0x7C4, 0x20D, 0x20E, 0x20F}, + { + 198, 4990, 3327, 0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, + 0x0F, 0x8F, 0x7D0, 0x7CC, 0x7C8, 0x20C, 0x20D, 0x20E}, + { + 200, 5000, 3333, 0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, + 0x0F, 0x8F, 0x7D4, 0x7D0, 0x7CC, 0x20B, 0x20C, 0x20D}, + { + 202, 5010, 3340, 0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, + 0x0F, 0x8F, 0x7D8, 0x7D4, 0x7D0, 0x20A, 0x20B, 0x20C}, + { + 204, 5020, 3347, 0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, + 0x0F, 0x8F, 0x7DC, 0x7D8, 0x7D4, 0x209, 0x20A, 0x20B}, + { + 206, 5030, 3353, 0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, + 0x0F, 0x8F, 0x7E0, 0x7DC, 0x7D8, 0x208, 0x209, 0x20A}, + { + 208, 5040, 3360, 0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, + 0x0F, 0x8F, 0x7E4, 0x7E0, 0x7DC, 0x207, 0x208, 0x209}, + { + 210, 5050, 3367, 0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, + 0x0F, 0x8F, 0x7E8, 0x7E4, 0x7E0, 0x206, 0x207, 0x208}, + { + 212, 5060, 3373, 0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E, + 0x0F, 0x8E, 0x7EC, 0x7E8, 0x7E4, 0x205, 0x206, 0x207}, + { + 214, 5070, 3380, 0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E, + 0x0F, 0x8E, 0x7F0, 0x7EC, 0x7E8, 0x204, 0x205, 0x206}, + { + 216, 5080, 3387, 0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A, + 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E, + 0x0F, 0x8D, 0x7F4, 0x7F0, 0x7EC, 0x203, 0x204, 0x205}, + { + 218, 5090, 3393, 0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A, + 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E, + 0x0F, 0x8D, 0x7F8, 0x7F4, 0x7F0, 0x202, 0x203, 0x204}, + { + 220, 5100, 3400, 0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A, + 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D, + 0x0F, 0x8D, 0x7FC, 0x7F8, 0x7F4, 0x201, 0x202, 0x203}, + { + 222, 5110, 3407, 0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A, + 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D, + 0x0F, 0x8D, 0x800, 0x7FC, 0x7F8, 0x200, 0x201, 0x202}, + { + 224, 5120, 3413, 0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A, + 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D, + 0x0F, 0x8C, 0x804, 0x800, 0x7FC, 0x1FF, 0x200, 0x201}, + { + 226, 5130, 3420, 0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A, + 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D, + 0x0F, 0x8C, 0x808, 0x804, 0x800, 0x1FE, 0x1FF, 0x200}, + { + 228, 5140, 3427, 0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A, + 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E, 0x8B, 0xDD, 0x00, 0x0C, + 0x0E, 0x8B, 0x80C, 0x808, 0x804, 0x1FD, 0x1FE, 0x1FF}, + { + 32, 5160, 3440, 0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A, + 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B, + 0x0D, 0x8A, 0x814, 0x810, 0x80C, 0x1FB, 0x1FC, 0x1FD}, + { + 34, 5170, 3447, 0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A, + 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B, + 0x0D, 0x8A, 0x818, 0x814, 0x810, 0x1FA, 0x1FB, 0x1FC}, + { + 36, 5180, 3453, 0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A, + 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B, + 0x0C, 0x89, 0x81C, 0x818, 0x814, 0x1F9, 0x1FA, 0x1FB}, + { + 38, 5190, 3460, 0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A, + 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B, + 0x0C, 0x89, 0x820, 0x81C, 0x818, 0x1F8, 0x1F9, 0x1FA}, + { + 40, 5200, 3467, 0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A, + 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A, + 0x0B, 0x89, 0x824, 0x820, 0x81C, 0x1F7, 0x1F8, 0x1F9}, + { + 42, 5210, 3473, 0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A, + 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A, + 0x0B, 0x89, 0x828, 0x824, 0x820, 0x1F6, 0x1F7, 0x1F8}, + { + 44, 5220, 3480, 0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A, + 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09, + 0x0A, 0x88, 0x82C, 0x828, 0x824, 0x1F5, 0x1F6, 0x1F7}, + { + 46, 5230, 3487, 0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A, + 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09, + 0x0A, 0x88, 0x830, 0x82C, 0x828, 0x1F4, 0x1F5, 0x1F6}, + { + 48, 5240, 3493, 0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A, + 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09, + 0x0A, 0x87, 0x834, 0x830, 0x82C, 0x1F3, 0x1F4, 0x1F5}, + { + 50, 5250, 3500, 0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A, + 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09, + 0x0A, 0x87, 0x838, 0x834, 0x830, 0x1F2, 0x1F3, 0x1F4}, + { + 52, 5260, 3507, 0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A, + 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08, + 0x09, 0x87, 0x83C, 0x838, 0x834, 0x1F1, 0x1F2, 0x1F3}, + { + 54, 5270, 3513, 0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A, + 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08, + 0x09, 0x87, 0x840, 0x83C, 0x838, 0x1F0, 0x1F1, 0x1F2}, + { + 56, 5280, 3520, 0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A, + 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08, + 0x08, 0x86, 0x844, 0x840, 0x83C, 0x1F0, 0x1F0, 0x1F1}, + { + 58, 5290, 3527, 0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A, + 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08, + 0x08, 0x86, 0x848, 0x844, 0x840, 0x1EF, 0x1F0, 0x1F0}, + { + 60, 5300, 3533, 0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A, + 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08, + 0x07, 0x85, 0x84C, 0x848, 0x844, 0x1EE, 0x1EF, 0x1F0}, + { + 62, 5310, 3540, 0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A, + 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08, + 0x07, 0x85, 0x850, 0x84C, 0x848, 0x1ED, 0x1EE, 0x1EF}, + { + 64, 5320, 3547, 0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A, + 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07, + 0x07, 0x84, 0x854, 0x850, 0x84C, 0x1EC, 0x1ED, 0x1EE}, + { + 66, 5330, 3553, 0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A, + 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07, + 0x07, 0x84, 0x858, 0x854, 0x850, 0x1EB, 0x1EC, 0x1ED}, + { + 68, 5340, 3560, 0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A, + 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07, + 0x06, 0x84, 0x85C, 0x858, 0x854, 0x1EA, 0x1EB, 0x1EC}, + { + 70, 5350, 3567, 0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A, + 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07, + 0x06, 0x84, 0x860, 0x85C, 0x858, 0x1E9, 0x1EA, 0x1EB}, + { + 72, 5360, 3573, 0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A, + 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06, + 0x05, 0x83, 0x864, 0x860, 0x85C, 0x1E8, 0x1E9, 0x1EA}, + { + 74, 5370, 3580, 0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A, + 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06, + 0x05, 0x83, 0x868, 0x864, 0x860, 0x1E7, 0x1E8, 0x1E9}, + { + 76, 5380, 3587, 0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A, + 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06, + 0x04, 0x82, 0x86C, 0x868, 0x864, 0x1E6, 0x1E7, 0x1E8}, + { + 78, 5390, 3593, 0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A, + 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06, + 0x04, 0x82, 0x870, 0x86C, 0x868, 0x1E5, 0x1E6, 0x1E7}, + { + 80, 5400, 3600, 0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A, + 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05, + 0x04, 0x81, 0x874, 0x870, 0x86C, 0x1E5, 0x1E5, 0x1E6}, + { + 82, 5410, 3607, 0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A, + 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05, + 0x04, 0x81, 0x878, 0x874, 0x870, 0x1E4, 0x1E5, 0x1E5}, + { + 84, 5420, 3613, 0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A, + 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05, + 0x03, 0x80, 0x87C, 0x878, 0x874, 0x1E3, 0x1E4, 0x1E5}, + { + 86, 5430, 3620, 0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A, + 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05, + 0x03, 0x80, 0x880, 0x87C, 0x878, 0x1E2, 0x1E3, 0x1E4}, + { + 88, 5440, 3627, 0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A, + 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04, + 0x02, 0x80, 0x884, 0x880, 0x87C, 0x1E1, 0x1E2, 0x1E3}, + { + 90, 5450, 3633, 0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A, + 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04, + 0x02, 0x80, 0x888, 0x884, 0x880, 0x1E0, 0x1E1, 0x1E2}, + { + 92, 5460, 3640, 0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A, + 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04, + 0x01, 0x80, 0x88C, 0x888, 0x884, 0x1DF, 0x1E0, 0x1E1}, + { + 94, 5470, 3647, 0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A, + 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04, + 0x01, 0x80, 0x890, 0x88C, 0x888, 0x1DE, 0x1DF, 0x1E0}, + { + 96, 5480, 3653, 0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A, + 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03, + 0x00, 0x80, 0x894, 0x890, 0x88C, 0x1DD, 0x1DE, 0x1DF}, + { + 98, 5490, 3660, 0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A, + 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03, + 0x00, 0x80, 0x898, 0x894, 0x890, 0x1DD, 0x1DD, 0x1DE}, + { + 100, 5500, 3667, 0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A, + 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03, + 0x00, 0x80, 0x89C, 0x898, 0x894, 0x1DC, 0x1DD, 0x1DD}, + { + 102, 5510, 3673, 0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A, + 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03, + 0x00, 0x80, 0x8A0, 0x89C, 0x898, 0x1DB, 0x1DC, 0x1DD}, + { + 104, 5520, 3680, 0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A, + 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02, + 0x00, 0x80, 0x8A4, 0x8A0, 0x89C, 0x1DA, 0x1DB, 0x1DC}, + { + 106, 5530, 3687, 0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A, + 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02, + 0x00, 0x80, 0x8A8, 0x8A4, 0x8A0, 0x1D9, 0x1DA, 0x1DB}, + { + 108, 5540, 3693, 0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A, + 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02, + 0x00, 0x80, 0x8AC, 0x8A8, 0x8A4, 0x1D8, 0x1D9, 0x1DA}, + { + 110, 5550, 3700, 0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A, + 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02, + 0x00, 0x80, 0x8B0, 0x8AC, 0x8A8, 0x1D7, 0x1D8, 0x1D9}, + { + 112, 5560, 3707, 0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A, + 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01, + 0x00, 0x80, 0x8B4, 0x8B0, 0x8AC, 0x1D7, 0x1D7, 0x1D8}, + { + 114, 5570, 3713, 0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A, + 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01, + 0x00, 0x80, 0x8B8, 0x8B4, 0x8B0, 0x1D6, 0x1D7, 0x1D7}, + { + 116, 5580, 3720, 0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A, + 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01, + 0x00, 0x80, 0x8BC, 0x8B8, 0x8B4, 0x1D5, 0x1D6, 0x1D7}, + { + 118, 5590, 3727, 0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A, + 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01, + 0x00, 0x80, 0x8C0, 0x8BC, 0x8B8, 0x1D4, 0x1D5, 0x1D6}, + { + 120, 5600, 3733, 0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A, + 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01, + 0x00, 0x80, 0x8C4, 0x8C0, 0x8BC, 0x1D3, 0x1D4, 0x1D5}, + { + 122, 5610, 3740, 0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A, + 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01, + 0x00, 0x80, 0x8C8, 0x8C4, 0x8C0, 0x1D2, 0x1D3, 0x1D4}, + { + 124, 5620, 3747, 0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A, + 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, + 0x00, 0x80, 0x8CC, 0x8C8, 0x8C4, 0x1D2, 0x1D2, 0x1D3}, + { + 126, 5630, 3753, 0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A, + 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, + 0x00, 0x80, 0x8D0, 0x8CC, 0x8C8, 0x1D1, 0x1D2, 0x1D2}, + { + 128, 5640, 3760, 0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x8D4, 0x8D0, 0x8CC, 0x1D0, 0x1D1, 0x1D2}, + { + 130, 5650, 3767, 0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x8D8, 0x8D4, 0x8D0, 0x1CF, 0x1D0, 0x1D1}, + { + 132, 5660, 3773, 0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x8DC, 0x8D8, 0x8D4, 0x1CE, 0x1CF, 0x1D0}, + { + 134, 5670, 3780, 0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x8E0, 0x8DC, 0x8D8, 0x1CE, 0x1CE, 0x1CF}, + { + 136, 5680, 3787, 0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x8E4, 0x8E0, 0x8DC, 0x1CD, 0x1CE, 0x1CE}, + { + 138, 5690, 3793, 0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x8E8, 0x8E4, 0x8E0, 0x1CC, 0x1CD, 0x1CE}, + { + 140, 5700, 3800, 0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x8EC, 0x8E8, 0x8E4, 0x1CB, 0x1CC, 0x1CD}, + { + 142, 5710, 3807, 0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x8F0, 0x8EC, 0x8E8, 0x1CA, 0x1CB, 0x1CC}, + { + 144, 5720, 3813, 0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x8F4, 0x8F0, 0x8EC, 0x1C9, 0x1CA, 0x1CB}, + { + 145, 5725, 3817, 0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x8F6, 0x8F2, 0x8EE, 0x1C9, 0x1CA, 0x1CB}, + { + 146, 5730, 3820, 0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x8F8, 0x8F4, 0x8F0, 0x1C9, 0x1C9, 0x1CA}, + { + 147, 5735, 3823, 0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x8FA, 0x8F6, 0x8F2, 0x1C8, 0x1C9, 0x1CA}, + { + 148, 5740, 3827, 0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x8FC, 0x8F8, 0x8F4, 0x1C8, 0x1C9, 0x1C9}, + { + 149, 5745, 3830, 0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x8FE, 0x8FA, 0x8F6, 0x1C8, 0x1C8, 0x1C9}, + { + 150, 5750, 3833, 0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x900, 0x8FC, 0x8F8, 0x1C7, 0x1C8, 0x1C9}, + { + 151, 5755, 3837, 0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x902, 0x8FE, 0x8FA, 0x1C7, 0x1C8, 0x1C8}, + { + 152, 5760, 3840, 0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x904, 0x900, 0x8FC, 0x1C6, 0x1C7, 0x1C8}, + { + 153, 5765, 3843, 0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x906, 0x902, 0x8FE, 0x1C6, 0x1C7, 0x1C8}, + { + 154, 5770, 3847, 0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x908, 0x904, 0x900, 0x1C6, 0x1C6, 0x1C7}, + { + 155, 5775, 3850, 0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x90A, 0x906, 0x902, 0x1C5, 0x1C6, 0x1C7}, + { + 156, 5780, 3853, 0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x90C, 0x908, 0x904, 0x1C5, 0x1C6, 0x1C6}, + { + 157, 5785, 3857, 0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x90E, 0x90A, 0x906, 0x1C4, 0x1C5, 0x1C6}, + { + 158, 5790, 3860, 0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x910, 0x90C, 0x908, 0x1C4, 0x1C5, 0x1C6}, + { + 159, 5795, 3863, 0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x912, 0x90E, 0x90A, 0x1C4, 0x1C4, 0x1C5}, + { + 160, 5800, 3867, 0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x914, 0x910, 0x90C, 0x1C3, 0x1C4, 0x1C5}, + { + 161, 5805, 3870, 0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x916, 0x912, 0x90E, 0x1C3, 0x1C4, 0x1C4}, + { + 162, 5810, 3873, 0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x918, 0x914, 0x910, 0x1C2, 0x1C3, 0x1C4}, + { + 163, 5815, 3877, 0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x91A, 0x916, 0x912, 0x1C2, 0x1C3, 0x1C4}, + { + 164, 5820, 3880, 0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x91C, 0x918, 0x914, 0x1C2, 0x1C2, 0x1C3}, + { + 165, 5825, 3883, 0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x91E, 0x91A, 0x916, 0x1C1, 0x1C2, 0x1C3}, + { + 166, 5830, 3887, 0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x920, 0x91C, 0x918, 0x1C1, 0x1C2, 0x1C2}, + { + 168, 5840, 3893, 0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x924, 0x920, 0x91C, 0x1C0, 0x1C1, 0x1C2}, + { + 170, 5850, 3900, 0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x928, 0x924, 0x920, 0x1BF, 0x1C0, 0x1C1}, + { + 172, 5860, 3907, 0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x92C, 0x928, 0x924, 0x1BF, 0x1BF, 0x1C0}, + { + 174, 5870, 3913, 0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x930, 0x92C, 0x928, 0x1BE, 0x1BF, 0x1BF}, + { + 176, 5880, 3920, 0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x934, 0x930, 0x92C, 0x1BD, 0x1BE, 0x1BF}, + { + 178, 5890, 3927, 0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x938, 0x934, 0x930, 0x1BC, 0x1BD, 0x1BE}, + { + 180, 5900, 3933, 0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x93C, 0x938, 0x934, 0x1BC, 0x1BC, 0x1BD}, + { + 182, 5910, 3940, 0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x940, 0x93C, 0x938, 0x1BB, 0x1BC, 0x1BC}, + { + 1, 2412, 3216, 0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C, 0x80, 0xFF, 0x88, 0x0D, + 0x0C, 0x80, 0x3C9, 0x3C5, 0x3C1, 0x43A, 0x43F, 0x443}, + { + 2, 2417, 3223, 0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B, 0x80, 0xFF, 0x88, 0x0C, + 0x0B, 0x80, 0x3CB, 0x3C7, 0x3C3, 0x438, 0x43D, 0x441}, + { + 3, 2422, 3229, 0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C, + 0x0A, 0x80, 0x3CD, 0x3C9, 0x3C5, 0x436, 0x43A, 0x43F}, + { + 4, 2427, 3236, 0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C, + 0x0A, 0x80, 0x3CF, 0x3CB, 0x3C7, 0x434, 0x438, 0x43D}, + { + 5, 2432, 3243, 0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09, 0x80, 0xFF, 0x88, 0x0C, + 0x09, 0x80, 0x3D1, 0x3CD, 0x3C9, 0x431, 0x436, 0x43A}, + { + 6, 2437, 3249, 0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08, 0x80, 0xFF, 0x88, 0x0B, + 0x08, 0x80, 0x3D3, 0x3CF, 0x3CB, 0x42F, 0x434, 0x438}, + { + 7, 2442, 3256, 0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07, 0x80, 0xFF, 0x88, 0x0A, + 0x07, 0x80, 0x3D5, 0x3D1, 0x3CD, 0x42D, 0x431, 0x436}, + { + 8, 2447, 3263, 0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06, 0x80, 0xFF, 0x88, 0x0A, + 0x06, 0x80, 0x3D7, 0x3D3, 0x3CF, 0x42B, 0x42F, 0x434}, + { + 9, 2452, 3269, 0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06, 0x80, 0xFF, 0x88, 0x09, + 0x06, 0x80, 0x3D9, 0x3D5, 0x3D1, 0x429, 0x42D, 0x431}, + { + 10, 2457, 3276, 0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05, 0x80, 0xFF, 0x88, 0x08, + 0x05, 0x80, 0x3DB, 0x3D7, 0x3D3, 0x427, 0x42B, 0x42F}, + { + 11, 2462, 3283, 0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04, 0x80, 0xFF, 0x88, 0x08, + 0x04, 0x80, 0x3DD, 0x3D9, 0x3D5, 0x424, 0x429, 0x42D}, + { + 12, 2467, 3289, 0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03, 0x80, 0xFF, 0x88, 0x08, + 0x03, 0x80, 0x3DF, 0x3DB, 0x3D7, 0x422, 0x427, 0x42B}, + { + 13, 2472, 3296, 0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03, 0x80, 0xFF, 0x88, 0x07, + 0x03, 0x80, 0x3E1, 0x3DD, 0x3D9, 0x420, 0x424, 0x429}, + { + 14, 2484, 3312, 0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01, 0x80, 0xFF, 0x88, 0x07, + 0x01, 0x80, 0x3E6, 0x3E2, 0x3DE, 0x41B, 0x41F, 0x424} +}; + +static chan_info_nphy_radio205x_t chan_info_nphyrev3_2056[] = { + { + 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216}, + { + 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215}, + { + 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214}, + { + 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213}, + { + 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212}, + { + 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211}, + { + 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f}, + { + 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e}, + { + 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d}, + { + 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c}, + { + 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b}, + { + 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a}, + { + 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209}, + { + 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208}, + { + 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207}, + { + 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206}, + { + 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205}, + { + 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204}, + { + 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xff, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203}, + { + 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xfc, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202}, + { + 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xfc, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201}, + { + 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xfc, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200}, + { + 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xfc, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff}, + { + 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xfc, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd}, + { + 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xfc, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc}, + { + 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xfc, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb}, + { + 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xfc, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa}, + { + 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9}, + { + 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8}, + { + 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7}, + { + 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6}, + { + 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5}, + { + 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4}, + { + 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3}, + { + 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2}, + { + 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1}, + { + 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0}, + { + 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfc, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0}, + { + 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef}, + { + 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee}, + { + 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed}, + { + 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec}, + { + 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb}, + { + 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea}, + { + 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9}, + { + 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8}, + { + 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x05, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7}, + { + 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xfa, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6}, + { + 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xfa, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5}, + { + 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xfa, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5}, + { + 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xfa, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4}, + { + 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xfa, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3}, + { + 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xfa, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2}, + { + 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1}, + { + 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0}, + { + 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df}, + { + 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, + 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de}, + { + 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd}, + { + 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd}, + { + 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc}, + { + 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db}, + { + 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da}, + { + 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9}, + { + 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8}, + { + 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7}, + { + 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7}, + { + 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6}, + { + 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5}, + { + 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4}, + { + 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3}, + { + 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2}, + { + 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2}, + { + 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf8, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf8, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1}, + { + 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf6, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0}, + { + 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf6, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf}, + { + 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf6, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce}, + { + 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf6, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce}, + { + 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf6, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd}, + { + 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc}, + { + 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb}, + { + 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb}, + { + 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca}, + { + 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca}, + { + 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9}, + { + 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9}, + { + 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9}, + { + 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8}, + { + 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8}, + { + 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8}, + { + 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7}, + { + 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7}, + { + 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6}, + { + 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6}, + { + 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6}, + { + 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5}, + { + 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5}, + { + 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4}, + { + 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4}, + { + 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4}, + { + 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3}, + { + 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3}, + { + 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2}, + { + 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2}, + { + 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf4, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1}, + { + 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf2, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf2, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0}, + { + 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf2, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf}, + { + 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf2, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf}, + { + 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, + 0x00, 0xf2, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be}, + { + 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x05, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05, + 0x00, 0xf2, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd}, + { + 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x05, 0x00, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05, + 0x00, 0xf2, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc}, + { + 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0f, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443}, + { + 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0f, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441}, + { + 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0f, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f}, + { + 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfd, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0f, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d}, + { + 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfb, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0f, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a}, + { + 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0f, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438}, + { + 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0f, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436}, + { + 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf7, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0f, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434}, + { + 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf6, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0f, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431}, + { + 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf5, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0d, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f}, + { + 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0d, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d}, + { + 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf3, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0d, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b}, + { + 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0d, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429}, + { + 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x05, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf0, 0x00, 0x05, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0d, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} +}; + +static chan_info_nphy_radio205x_t chan_info_nphyrev4_2056_A1[] = { + { + 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216}, + { + 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215}, + { + 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214}, + { + 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213}, + { + 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212}, + { + 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211}, + { + 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f}, + { + 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e}, + { + 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d}, + { + 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c}, + { + 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b}, + { + 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a}, + { + 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209}, + { + 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208}, + { + 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207}, + { + 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206}, + { + 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205}, + { + 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204}, + { + 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfe, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203}, + { + 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfe, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202}, + { + 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfe, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201}, + { + 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfe, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200}, + { + 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfe, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff}, + { + 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfe, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd}, + { + 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfe, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc}, + { + 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfe, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb}, + { + 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfe, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa}, + { + 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9}, + { + 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8}, + { + 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7}, + { + 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6}, + { + 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5}, + { + 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4}, + { + 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3}, + { + 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2}, + { + 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1}, + { + 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0}, + { + 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0}, + { + 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef}, + { + 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee}, + { + 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed}, + { + 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec}, + { + 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb}, + { + 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea}, + { + 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9}, + { + 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8}, + { + 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x08, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7}, + { + 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6}, + { + 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5}, + { + 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5}, + { + 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4}, + { + 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3}, + { + 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2}, + { + 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1}, + { + 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0}, + { + 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df}, + { + 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x07, 0x00, 0x7f, + 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, + 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de}, + { + 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x5c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd}, + { + 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd}, + { + 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc}, + { + 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db}, + { + 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da}, + { + 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9}, + { + 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8}, + { + 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7}, + { + 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7}, + { + 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f, + 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, + 0x00, 0xf6, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6}, + { + 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x1a, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5}, + { + 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4}, + { + 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3}, + { + 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2}, + { + 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2}, + { + 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1}, + { + 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0}, + { + 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf}, + { + 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce}, + { + 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x04, 0x00, 0x7f, + 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, + 0x00, 0xf4, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce}, + { + 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd}, + { + 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc}, + { + 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb}, + { + 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb}, + { + 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca}, + { + 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca}, + { + 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9}, + { + 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9}, + { + 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9}, + { + 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8}, + { + 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8}, + { + 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8}, + { + 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7}, + { + 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7}, + { + 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6}, + { + 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6}, + { + 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6}, + { + 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f, + 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, + 0x00, 0xf2, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5}, + { + 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5}, + { + 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4}, + { + 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4}, + { + 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4}, + { + 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3}, + { + 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3}, + { + 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2}, + { + 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2}, + { + 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1}, + { + 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0}, + { + 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf}, + { + 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf}, + { + 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f, + 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, + 0x00, 0xf0, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be}, + { + 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf0, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd}, + { + 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x07, 0x00, 0xf0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07, + 0x00, 0xf0, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc}, + { + 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443}, + { + 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441}, + { + 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f}, + { + 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfd, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d}, + { + 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfb, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a}, + { + 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438}, + { + 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf8, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436}, + { + 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf7, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434}, + { + 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf6, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431}, + { + 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf5, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f}, + { + 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d}, + { + 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf3, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b}, + { + 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429}, + { + 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x04, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0e, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} +}; + +static chan_info_nphy_radio205x_t chan_info_nphyrev5_2056v5[] = { + { + 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, + 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216}, + { + 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, + 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215}, + { + 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, + 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214}, + { + 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, + 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213}, + { + 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212}, + { + 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211}, + { + 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f}, + { + 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e}, + { + 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d}, + { + 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c}, + { + 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b}, + { + 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a}, + { + 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209}, + { + 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208}, + { + 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207}, + { + 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206}, + { + 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205}, + { + 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204}, + { + 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203}, + { + 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202}, + { + 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201}, + { + 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200}, + { + 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, + 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff}, + { + 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd}, + { + 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc}, + { + 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb}, + { + 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa}, + { + 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9}, + { + 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8}, + { + 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7}, + { + 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xea, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08, + 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6}, + { + 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70, + 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08, + 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5}, + { + 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70, + 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08, + 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4}, + { + 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xd9, 0x00, 0x05, 0x00, 0x70, + 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08, + 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3}, + { + 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xd8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2}, + { + 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1}, + { + 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0}, + { + 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0}, + { + 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef}, + { + 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee}, + { + 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed}, + { + 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec}, + { + 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa7, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb}, + { + 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea}, + { + 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x5b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9}, + { + 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x96, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x5a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8}, + { + 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x95, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x5a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7}, + { + 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x5a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6}, + { + 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x5a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5}, + { + 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x5a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5}, + { + 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x85, 0x00, 0x02, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x59, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4}, + { + 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x59, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3}, + { + 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x59, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2}, + { + 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x69, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1}, + { + 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x74, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x69, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0}, + { + 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df}, + { + 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de}, + { + 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd}, + { + 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd}, + { + 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc}, + { + 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x63, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03, + 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db}, + { + 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, + 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da}, + { + 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, + 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9}, + { + 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, + 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8}, + { + 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7}, + { + 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x76, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7}, + { + 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x76, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6}, + { + 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x76, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5}, + { + 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x76, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4}, + { + 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x76, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3}, + { + 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x76, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2}, + { + 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x75, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2}, + { + 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x75, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1}, + { + 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x75, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0}, + { + 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x74, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf}, + { + 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x74, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce}, + { + 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x74, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce}, + { + 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x74, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd}, + { + 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x74, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc}, + { + 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x74, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb}, + { + 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x74, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb}, + { + 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x84, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca}, + { + 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x83, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca}, + { + 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x83, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9}, + { + 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x83, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9}, + { + 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x83, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9}, + { + 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x83, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8}, + { + 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x83, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8}, + { + 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x82, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8}, + { + 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x82, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7}, + { + 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x82, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7}, + { + 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x82, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6}, + { + 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x82, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6}, + { + 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x82, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6}, + { + 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x82, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5}, + { + 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x82, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5}, + { + 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x82, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4}, + { + 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x82, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4}, + { + 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x82, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4}, + { + 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x82, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3}, + { + 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x82, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3}, + { + 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x72, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2}, + { + 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x72, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2}, + { + 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x72, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1}, + { + 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x72, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0}, + { + 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x71, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf}, + { + 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x71, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf}, + { + 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x71, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be}, + { + 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x71, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd}, + { + 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x71, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc}, + { + 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443}, + { + 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441}, + { + 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f}, + { + 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d}, + { + 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a}, + { + 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438}, + { + 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436}, + { + 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x08, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434}, + { + 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x07, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431}, + { + 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x06, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f}, + { + 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x05, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d}, + { + 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b}, + { + 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x03, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429}, + { + 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} +}; + +static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v6[] = { + { + 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216}, + { + 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215}, + { + 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214}, + { + 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213}, + { + 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212}, + { + 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211}, + { + 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f}, + { + 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e}, + { + 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d}, + { + 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c}, + { + 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b}, + { + 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a}, + { + 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209}, + { + 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208}, + { + 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207}, + { + 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206}, + { + 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205}, + { + 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204}, + { + 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203}, + { + 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202}, + { + 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201}, + { + 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200}, + { + 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff}, + { + 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, + 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd}, + { + 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, + 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc}, + { + 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, + 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb}, + { + 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa}, + { + 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9}, + { + 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8}, + { + 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7}, + { + 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6}, + { + 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5}, + { + 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4}, + { + 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3}, + { + 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2}, + { + 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1}, + { + 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0}, + { + 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0}, + { + 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef}, + { + 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee}, + { + 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed}, + { + 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec}, + { + 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb}, + { + 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea}, + { + 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9}, + { + 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8}, + { + 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7}, + { + 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6}, + { + 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5}, + { + 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5}, + { + 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4}, + { + 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3}, + { + 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2}, + { + 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1}, + { + 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0}, + { + 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df}, + { + 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de}, + { + 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd}, + { + 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd}, + { + 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc}, + { + 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db}, + { + 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da}, + { + 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9}, + { + 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8}, + { + 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7}, + { + 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7}, + { + 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6}, + { + 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5}, + { + 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4}, + { + 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3}, + { + 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2}, + { + 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2}, + { + 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1}, + { + 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0}, + { + 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf}, + { + 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce}, + { + 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce}, + { + 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd}, + { + 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc}, + { + 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb}, + { + 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb}, + { + 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca}, + { + 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca}, + { + 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9}, + { + 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9}, + { + 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9}, + { + 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8}, + { + 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8}, + { + 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8}, + { + 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7}, + { + 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7}, + { + 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6}, + { + 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6}, + { + 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6}, + { + 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5}, + { + 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5}, + { + 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4}, + { + 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4}, + { + 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4}, + { + 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3}, + { + 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3}, + { + 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2}, + { + 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2}, + { + 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1}, + { + 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0}, + { + 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf}, + { + 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf}, + { + 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be}, + { + 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd}, + { + 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc}, + { + 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443}, + { + 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441}, + { + 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x67, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f}, + { + 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x57, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d}, + { + 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x56, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a}, + { + 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x46, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438}, + { + 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436}, + { + 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434}, + { + 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x23, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431}, + { + 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x12, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f}, + { + 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x02, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d}, + { + 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b}, + { + 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429}, + { + 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} +}; + +static chan_info_nphy_radio205x_t chan_info_nphyrev5n6_2056v7[] = { + { + 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, + 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216}, + { + 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, + 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215}, + { + 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, + 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214}, + { + 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, + 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213}, + { + 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212}, + { + 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211}, + { + 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f}, + { + 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e}, + { + 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d}, + { + 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c}, + { + 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b}, + { + 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a}, + { + 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209}, + { + 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208}, + { + 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70, + 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207}, + { + 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206}, + { + 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205}, + { + 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204}, + { + 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203}, + { + 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202}, + { + 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201}, + { + 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70, + 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200}, + { + 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, + 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff}, + { + 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd}, + { + 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc}, + { + 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb}, + { + 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa}, + { + 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9}, + { + 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8}, + { + 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xfa, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, + 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7}, + { + 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xea, 0x00, 0x06, 0x00, 0x70, + 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08, + 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6}, + { + 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xe9, 0x00, 0x05, 0x00, 0x70, + 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08, + 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5}, + { + 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xe9, 0x00, 0x05, 0x00, 0x70, + 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08, + 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4}, + { + 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xd9, 0x00, 0x05, 0x00, 0x70, + 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08, + 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3}, + { + 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xd8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2}, + { + 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1}, + { + 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0}, + { + 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0}, + { + 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef}, + { + 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb8, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee}, + { + 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xb7, 0x00, 0x04, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed}, + { + 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xb7, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07, + 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec}, + { + 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa7, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb}, + { + 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea}, + { + 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x7b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9}, + { + 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x96, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x7a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8}, + { + 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x7a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7}, + { + 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, + 0x00, 0x7a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6}, + { + 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x95, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x7a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5}, + { + 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x95, 0x00, 0x03, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x7a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5}, + { + 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x85, 0x00, 0x02, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x79, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4}, + { + 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x79, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3}, + { + 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70, + 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05, + 0x00, 0x79, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2}, + { + 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x79, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1}, + { + 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x74, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x79, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0}, + { + 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x78, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df}, + { + 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x78, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de}, + { + 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd}, + { + 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd}, + { + 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, + 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc}, + { + 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x63, 0x00, 0x01, 0x00, 0x70, + 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03, + 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db}, + { + 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x62, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, + 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da}, + { + 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, + 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9}, + { + 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, + 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8}, + { + 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x52, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7}, + { + 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x52, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x86, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7}, + { + 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x86, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6}, + { + 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x86, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5}, + { + 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x86, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4}, + { + 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x86, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3}, + { + 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x86, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2}, + { + 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x51, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, + 0x00, 0x85, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2}, + { + 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x85, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1}, + { + 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x85, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0}, + { + 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x84, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf}, + { + 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x84, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce}, + { + 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce}, + { + 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd}, + { + 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc}, + { + 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb}, + { + 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb}, + { + 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, + 0x00, 0x94, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca}, + { + 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x93, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca}, + { + 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x93, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9}, + { + 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x93, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9}, + { + 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x93, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9}, + { + 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x30, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x93, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8}, + { + 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x93, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8}, + { + 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8}, + { + 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7}, + { + 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7}, + { + 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6}, + { + 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6}, + { + 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6}, + { + 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5}, + { + 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5}, + { + 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4}, + { + 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4}, + { + 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4}, + { + 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3}, + { + 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3}, + { + 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2}, + { + 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2}, + { + 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1}, + { + 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x92, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0}, + { + 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x91, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf}, + { + 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x91, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf}, + { + 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x91, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be}, + { + 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x91, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd}, + { + 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x91, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc}, + { + 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443}, + { + 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441}, + { + 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f}, + { + 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d}, + { + 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a}, + { + 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x76, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438}, + { + 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x66, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436}, + { + 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x55, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434}, + { + 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431}, + { + 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f}, + { + 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d}, + { + 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x22, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b}, + { + 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429}, + { + 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} +}; + +static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v8[] = { + { + 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216}, + { + 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215}, + { + 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214}, + { + 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213}, + { + 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212}, + { + 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211}, + { + 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f}, + { + 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e}, + { + 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d}, + { + 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c}, + { + 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b}, + { + 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a}, + { + 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209}, + { + 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208}, + { + 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207}, + { + 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206}, + { + 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205}, + { + 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204}, + { + 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203}, + { + 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202}, + { + 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201}, + { + 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200}, + { + 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff}, + { + 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, + 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd}, + { + 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, + 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc}, + { + 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, + 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb}, + { + 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa}, + { + 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9}, + { + 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8}, + { + 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7}, + { + 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6}, + { + 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5}, + { + 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4}, + { + 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3}, + { + 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2}, + { + 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1}, + { + 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0}, + { + 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0}, + { + 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef}, + { + 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee}, + { + 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed}, + { + 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec}, + { + 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb}, + { + 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea}, + { + 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9}, + { + 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8}, + { + 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7}, + { + 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6}, + { + 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5}, + { + 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5}, + { + 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4}, + { + 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3}, + { + 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2}, + { + 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1}, + { + 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0}, + { + 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df}, + { + 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de}, + { + 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd}, + { + 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd}, + { + 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc}, + { + 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db}, + { + 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da}, + { + 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9}, + { + 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8}, + { + 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7}, + { + 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7}, + { + 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6}, + { + 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5}, + { + 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4}, + { + 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3}, + { + 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2}, + { + 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2}, + { + 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1}, + { + 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0}, + { + 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf}, + { + 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce}, + { + 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce}, + { + 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd}, + { + 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc}, + { + 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb}, + { + 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb}, + { + 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca}, + { + 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca}, + { + 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9}, + { + 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9}, + { + 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9}, + { + 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8}, + { + 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8}, + { + 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8}, + { + 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7}, + { + 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7}, + { + 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6}, + { + 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6}, + { + 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6}, + { + 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5}, + { + 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5}, + { + 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4}, + { + 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4}, + { + 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4}, + { + 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3}, + { + 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3}, + { + 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2}, + { + 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2}, + { + 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1}, + { + 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0}, + { + 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf}, + { + 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf}, + { + 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be}, + { + 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd}, + { + 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc}, + { + 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443}, + { + 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441}, + { + 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f}, + { + 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d}, + { + 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a}, + { + 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438}, + { + 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436}, + { + 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434}, + { + 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431}, + { + 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f}, + { + 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d}, + { + 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b}, + { + 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429}, + { + 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01, + 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} +}; + +static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v11[] = { + { + 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216}, + { + 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215}, + { + 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214}, + { + 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213}, + { + 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212}, + { + 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211}, + { + 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f}, + { + 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e}, + { + 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d}, + { + 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c}, + { + 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b}, + { + 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a}, + { + 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209}, + { + 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208}, + { + 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207}, + { + 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206}, + { + 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205}, + { + 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204}, + { + 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203}, + { + 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202}, + { + 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201}, + { + 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200}, + { + 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77, + 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, + 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff}, + { + 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, + 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd}, + { + 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, + 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc}, + { + 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, + 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e, + 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb}, + { + 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa}, + { + 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9}, + { + 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8}, + { + 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7}, + { + 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6}, + { + 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5}, + { + 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4}, + { + 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, + 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d, + 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3}, + { + 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2}, + { + 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1}, + { + 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0}, + { + 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0}, + { + 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef}, + { + 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, + 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee}, + { + 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed}, + { + 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec}, + { + 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, + 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb}, + { + 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea}, + { + 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9}, + { + 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8}, + { + 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7}, + { + 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6}, + { + 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5}, + { + 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5}, + { + 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, + 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4}, + { + 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3}, + { + 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2}, + { + 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1}, + { + 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0}, + { + 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df}, + { + 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de}, + { + 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd}, + { + 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd}, + { + 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc}, + { + 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db}, + { + 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da}, + { + 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9}, + { + 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8}, + { + 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, + 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7}, + { + 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7}, + { + 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6}, + { + 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5}, + { + 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, + 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4}, + { + 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3}, + { + 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2}, + { + 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2}, + { + 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, + 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1}, + { + 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0}, + { + 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf}, + { + 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce}, + { + 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce}, + { + 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd}, + { + 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc}, + { + 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb}, + { + 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x05, 0x05, 0x02, 0x15, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb}, + { + 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca}, + { + 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x05, 0x05, 0x02, 0x15, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca}, + { + 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9}, + { + 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x05, 0x05, 0x02, 0x15, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, + 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9}, + { + 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9}, + { + 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x05, 0x05, 0x02, 0x15, 0x01, + 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8}, + { + 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8}, + { + 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x05, 0x05, 0x02, 0x15, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8}, + { + 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7}, + { + 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x05, 0x05, 0x02, 0x15, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7}, + { + 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6}, + { + 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x05, 0x05, 0x02, 0x15, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6}, + { + 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6}, + { + 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x05, 0x05, 0x02, 0x15, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5}, + { + 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5}, + { + 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x05, 0x05, 0x02, 0x15, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4}, + { + 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4}, + { + 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x05, 0x05, 0x02, 0x15, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4}, + { + 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3}, + { + 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x05, 0x05, 0x02, 0x15, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3}, + { + 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, + 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2}, + { + 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2}, + { + 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1}, + { + 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0}, + { + 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf}, + { + 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf}, + { + 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be}, + { + 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd}, + { + 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x02, 0x0c, 0x01, + 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, + 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, + 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc}, + { + 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x06, 0x06, 0x04, 0x2b, 0x01, + 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443}, + { + 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x06, 0x06, 0x04, 0x2b, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441}, + { + 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x06, 0x06, 0x04, 0x2b, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f}, + { + 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x06, 0x06, 0x04, 0x2b, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d}, + { + 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x06, 0x06, 0x04, 0x2b, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a}, + { + 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x06, 0x06, 0x04, 0x2b, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438}, + { + 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x06, 0x06, 0x04, 0x2b, 0x01, + 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436}, + { + 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x06, 0x06, 0x04, 0x2b, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434}, + { + 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x06, 0x06, 0x04, 0x2b, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431}, + { + 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x06, 0x06, 0x04, 0x2b, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f}, + { + 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x06, 0x06, 0x04, 0x2b, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d}, + { + 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x06, 0x06, 0x04, 0x2b, 0x01, + 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b}, + { + 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x06, 0x06, 0x04, 0x2b, 0x01, + 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429}, + { + 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x06, 0x06, 0x04, 0x2b, 0x01, + 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00, + 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} +}; + +static chan_info_nphy_radio2057_t chan_info_nphyrev7_2057_rev4[] = { + { + 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, + 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b4, 0x07b0, 0x07ac, 0x0214, + 0x0215, + 0x0216, + }, + { + 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, + 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b8, 0x07b4, 0x07b0, 0x0213, + 0x0214, + 0x0215, + }, + { + 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, + 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07bc, 0x07b8, 0x07b4, 0x0212, + 0x0213, + 0x0214, + }, + { + 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, + 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c0, 0x07bc, 0x07b8, 0x0211, + 0x0212, + 0x0213, + }, + { + 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, + 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c4, 0x07c0, 0x07bc, 0x020f, + 0x0211, + 0x0212, + }, + { + 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, + 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c8, 0x07c4, 0x07c0, 0x020e, + 0x020f, + 0x0211, + }, + { + 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, + 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07cc, 0x07c8, 0x07c4, 0x020d, + 0x020e, + 0x020f, + }, + { + 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, + 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d0, 0x07cc, 0x07c8, 0x020c, + 0x020d, + 0x020e, + }, + { + 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, + 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d4, 0x07d0, 0x07cc, 0x020b, + 0x020c, + 0x020d, + }, + { + 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, + 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d8, 0x07d4, 0x07d0, 0x020a, + 0x020b, + 0x020c, + }, + { + 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, + 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07dc, 0x07d8, 0x07d4, 0x0209, + 0x020a, + 0x020b, + }, + { + 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, + 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e0, 0x07dc, 0x07d8, 0x0208, + 0x0209, + 0x020a, + }, + { + 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, + 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e4, 0x07e0, 0x07dc, 0x0207, + 0x0208, + 0x0209, + }, + { + 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, + 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e8, 0x07e4, 0x07e0, 0x0206, + 0x0207, + 0x0208, + }, + { + 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x00, + 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x07ec, 0x07e8, 0x07e4, 0x0205, + 0x0206, + 0x0207, + }, + { + 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00, + 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f0, 0x07ec, 0x07e8, 0x0204, + 0x0205, + 0x0206, + }, + { + 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00, + 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f4, 0x07f0, 0x07ec, 0x0203, + 0x0204, + 0x0205, + }, + { + 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00, + 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07f8, 0x07f4, 0x07f0, 0x0202, + 0x0203, + 0x0204, + }, + { + 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00, + 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07fc, 0x07f8, 0x07f4, 0x0201, + 0x0202, + 0x0203, + }, + { + 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00, + 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0800, 0x07fc, 0x07f8, 0x0200, + 0x0201, + 0x0202, + }, + { + 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00, + 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0804, 0x0800, 0x07fc, 0x01ff, + 0x0200, + 0x0201, + }, + { + 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00, + 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0808, 0x0804, 0x0800, 0x01fe, + 0x01ff, + 0x0200, + }, + { + 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x00, + 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x080c, 0x0808, 0x0804, 0x01fd, + 0x01fe, + 0x01ff, + }, + { + 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00, + 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0814, 0x0810, 0x080c, 0x01fb, + 0x01fc, + 0x01fd, + }, + { + 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00, + 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0818, 0x0814, 0x0810, 0x01fa, + 0x01fb, + 0x01fc, + }, + { + 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00, + 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x081c, 0x0818, 0x0814, 0x01f9, + 0x01fa, + 0x01fb, + }, + { + 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00, + 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0820, 0x081c, 0x0818, 0x01f8, + 0x01f9, + 0x01fa, + }, + { + 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00, + 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0824, 0x0820, 0x081c, 0x01f7, + 0x01f8, + 0x01f9, + }, + { + 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00, + 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0828, 0x0824, 0x0820, 0x01f6, + 0x01f7, + 0x01f8, + }, + { + 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00, + 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x082c, 0x0828, 0x0824, 0x01f5, + 0x01f6, + 0x01f7, + }, + { + 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00, + 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0830, 0x082c, 0x0828, 0x01f4, + 0x01f5, + 0x01f6, + }, + { + 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00, + 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0834, 0x0830, 0x082c, 0x01f3, + 0x01f4, + 0x01f5, + }, + { + 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00, + 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0838, 0x0834, 0x0830, 0x01f2, + 0x01f3, + 0x01f4, + }, + { + 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00, + 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x083c, 0x0838, 0x0834, 0x01f1, + 0x01f2, + 0x01f3, + }, + { + 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00, + 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x0840, 0x083c, 0x0838, 0x01f0, + 0x01f1, + 0x01f2, + }, + { + 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00, + 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0844, 0x0840, 0x083c, 0x01f0, + 0x01f0, + 0x01f1, + }, + { + 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00, + 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0848, 0x0844, 0x0840, 0x01ef, + 0x01f0, + 0x01f0, + }, + { + 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00, + 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x084c, 0x0848, 0x0844, 0x01ee, + 0x01ef, + 0x01f0, + }, + { + 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00, + 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0850, 0x084c, 0x0848, 0x01ed, + 0x01ee, + 0x01ef, + }, + { + 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00, + 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0854, 0x0850, 0x084c, 0x01ec, + 0x01ed, + 0x01ee, + }, + { + 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00, + 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0858, 0x0854, 0x0850, 0x01eb, + 0x01ec, + 0x01ed, + }, + { + 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x00, + 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x085c, 0x0858, 0x0854, 0x01ea, + 0x01eb, + 0x01ec, + }, + { + 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00, + 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0860, 0x085c, 0x0858, 0x01e9, + 0x01ea, + 0x01eb, + }, + { + 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00, + 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0864, 0x0860, 0x085c, 0x01e8, + 0x01e9, + 0x01ea, + }, + { + 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00, + 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0868, 0x0864, 0x0860, 0x01e7, + 0x01e8, + 0x01e9, + }, + { + 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00, + 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x086c, 0x0868, 0x0864, 0x01e6, + 0x01e7, + 0x01e8, + }, + { + 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x00, + 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x0870, 0x086c, 0x0868, 0x01e5, + 0x01e6, + 0x01e7, + }, + { + 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00, + 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0874, 0x0870, 0x086c, 0x01e5, + 0x01e5, + 0x01e6, + }, + { + 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00, + 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0878, 0x0874, 0x0870, 0x01e4, + 0x01e5, + 0x01e5, + }, + { + 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x00, + 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x087c, 0x0878, 0x0874, 0x01e3, + 0x01e4, + 0x01e5, + }, + { + 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00, + 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0880, 0x087c, 0x0878, 0x01e2, + 0x01e3, + 0x01e4, + }, + { + 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00, + 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0884, 0x0880, 0x087c, 0x01e1, + 0x01e2, + 0x01e3, + }, + { + 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00, + 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0888, 0x0884, 0x0880, 0x01e0, + 0x01e1, + 0x01e2, + }, + { + 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x00, + 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x088c, 0x0888, 0x0884, 0x01df, + 0x01e0, + 0x01e1, + }, + { + 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x00, + 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x0890, 0x088c, 0x0888, 0x01de, + 0x01df, + 0x01e0, + }, + { + 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00, + 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0894, 0x0890, 0x088c, 0x01dd, + 0x01de, + 0x01df, + }, + { + 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00, + 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0898, 0x0894, 0x0890, 0x01dd, + 0x01dd, + 0x01de, + }, + { + 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00, + 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x089c, 0x0898, 0x0894, 0x01dc, + 0x01dd, + 0x01dd, + }, + { + 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00, + 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x08a0, 0x089c, 0x0898, 0x01db, + 0x01dc, + 0x01dd, + }, + { + 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00, + 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a4, 0x08a0, 0x089c, 0x01da, + 0x01db, + 0x01dc, + }, + { + 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00, + 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a8, 0x08a4, 0x08a0, 0x01d9, + 0x01da, + 0x01db, + }, + { + 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00, + 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08ac, 0x08a8, 0x08a4, 0x01d8, + 0x01d9, + 0x01da, + }, + { + 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00, + 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b0, 0x08ac, 0x08a8, 0x01d7, + 0x01d8, + 0x01d9, + }, + { + 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00, + 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b4, 0x08b0, 0x08ac, 0x01d7, + 0x01d7, + 0x01d8, + }, + { + 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00, + 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b8, 0x08b4, 0x08b0, 0x01d6, + 0x01d7, + 0x01d7, + }, + { + 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x00, + 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x08bc, 0x08b8, 0x08b4, 0x01d5, + 0x01d6, + 0x01d7, + }, + { + 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x00, + 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x08c0, 0x08bc, 0x08b8, 0x01d4, + 0x01d5, + 0x01d6, + }, + { + 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x00, + 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x08c4, 0x08c0, 0x08bc, 0x01d3, + 0x01d4, + 0x01d5, + }, + { + 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00, + 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08c8, 0x08c4, 0x08c0, 0x01d2, + 0x01d3, + 0x01d4, + }, + { + 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00, + 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08cc, 0x08c8, 0x08c4, 0x01d2, + 0x01d2, + 0x01d3, + }, + { + 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00, + 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d0, 0x08cc, 0x08c8, 0x01d1, + 0x01d2, + 0x01d2, + }, + { + 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00, + 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d4, 0x08d0, 0x08cc, 0x01d0, + 0x01d1, + 0x01d2, + }, + { + 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00, + 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08d8, 0x08d4, 0x08d0, 0x01cf, + 0x01d0, + 0x01d1, + }, + { + 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00, + 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08dc, 0x08d8, 0x08d4, 0x01ce, + 0x01cf, + 0x01d0, + }, + { + 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, + 0x01ce, + 0x01cf, + }, + { + 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, + 0x01ce, + 0x01ce, + }, + { + 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, + 0x01cd, + 0x01ce, + }, + { + 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, + 0x01cc, + 0x01cd, + }, + { + 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, + 0x01cb, + 0x01cc, + }, + { + 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, + 0x01ca, + 0x01cb, + }, + { + 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, + 0x01ca, + 0x01cb, + }, + { + 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, + 0x01c9, + 0x01ca, + }, + { + 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, + 0x01c9, + 0x01ca, + }, + { + 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, + 0x01c9, + 0x01c9, + }, + { + 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, + 0x01c8, + 0x01c9, + }, + { + 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, + 0x01c8, + 0x01c9, + }, + { + 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, + 0x01c8, + 0x01c8, + }, + { + 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, + 0x01c7, + 0x01c8, + }, + { + 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, + 0x01c7, + 0x01c8, + }, + { + 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, + 0x01c6, + 0x01c7, + }, + { + 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, + 0x01c6, + 0x01c7, + }, + { + 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, + 0x01c6, + 0x01c6, + }, + { + 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, + 0x01c5, + 0x01c6, + }, + { + 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, + 0x01c5, + 0x01c6, + }, + { + 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, + 0x01c4, + 0x01c5, + }, + { + 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, + 0x01c4, + 0x01c5, + }, + { + 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, + 0x01c4, + 0x01c4, + }, + { + 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, + 0x01c3, + 0x01c4, + }, + { + 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, + 0x01c3, + 0x01c4, + }, + { + 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, + 0x01c2, + 0x01c3, + }, + { + 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, + 0x01c2, + 0x01c3, + }, + { + 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, + 0x01c2, + 0x01c2, + }, + { + 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, + 0x01c1, + 0x01c2, + }, + { + 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04, + 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, + 0x01c0, + 0x01c1, + }, + { + 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04, + 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, + 0x01bf, + 0x01c0, + }, + { + 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04, + 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, + 0x01bf, + 0x01bf, + }, + { + 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03, + 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, + 0x01be, + 0x01bf, + }, + { + 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03, + 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, + 0x01bd, + 0x01be, + }, + { + 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03, + 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, + 0x01bc, + 0x01bd, + }, + { + 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f, + 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71, + 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a, + 0x043f, + 0x0443, + }, + { + 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f, + 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71, + 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438, + 0x043d, + 0x0441, + }, + { + 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f, + 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71, + 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436, + 0x043a, + 0x043f, + }, + { + 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f, + 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71, + 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434, + 0x0438, + 0x043d, + }, + { + 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f, + 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51, + 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431, + 0x0436, + 0x043a, + }, + { + 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f, + 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51, + 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f, + 0x0434, + 0x0438, + }, + { + 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f, + 0x07, 0x00, 0x07, 0x00, 0x51, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d, + 0x0431, + 0x0436, + }, + { + 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f, + 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b, + 0x042f, + 0x0434, + }, + { + 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f, + 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429, + 0x042d, + 0x0431, + }, + { + 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f, + 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31, + 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427, + 0x042b, + 0x042f, + }, + { + 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f, + 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31, + 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424, + 0x0429, + 0x042d, + }, + { + 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f, + 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11, + 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422, + 0x0427, + 0x042b, + }, + { + 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f, + 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11, + 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420, + 0x0424, + 0x0429, + }, + { + 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f, + 0x04, 0x00, 0x04, 0x00, 0x11, 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x11, + 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b, + 0x041f, + 0x0424} +}; + +static chan_info_nphy_radio2057_rev5_t chan_info_nphyrev8_2057_rev5[] = { + { + 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d, + 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1, + 0x043a, 0x043f, 0x0443}, + { + 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d, + 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3, + 0x0438, 0x043d, 0x0441}, + { + 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d, + 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5, + 0x0436, 0x043a, 0x043f}, + { + 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c, + 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7, + 0x0434, 0x0438, 0x043d}, + { + 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c, + 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9, + 0x0431, 0x0436, 0x043a}, + { + 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c, + 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb, + 0x042f, 0x0434, 0x0438}, + { + 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b, + 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd, + 0x042d, 0x0431, 0x0436}, + { + 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b, + 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf, + 0x042b, 0x042f, 0x0434}, + { + 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b, + 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1, + 0x0429, 0x042d, 0x0431}, + { + 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b, + 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3, + 0x0427, 0x042b, 0x042f}, + { + 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b, + 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5, + 0x0424, 0x0429, 0x042d}, + { + 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b, + 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7, + 0x0422, 0x0427, 0x042b}, + { + 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a, + 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9, + 0x0420, 0x0424, 0x0429}, + { + 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a, + 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de, + 0x041b, 0x041f, 0x0424} +}; + +static chan_info_nphy_radio2057_rev5_t chan_info_nphyrev9_2057_rev5v1[] = { + { + 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d, + 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1, + 0x043a, 0x043f, 0x0443}, + { + 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d, + 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3, + 0x0438, 0x043d, 0x0441}, + { + 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d, + 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5, + 0x0436, 0x043a, 0x043f}, + { + 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c, + 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7, + 0x0434, 0x0438, 0x043d}, + { + 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c, + 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9, + 0x0431, 0x0436, 0x043a}, + { + 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c, + 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb, + 0x042f, 0x0434, 0x0438}, + { + 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b, + 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd, + 0x042d, 0x0431, 0x0436}, + { + 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b, + 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf, + 0x042b, 0x042f, 0x0434}, + { + 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b, + 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1, + 0x0429, 0x042d, 0x0431}, + { + 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b, + 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3, + 0x0427, 0x042b, 0x042f}, + { + 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b, + 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5, + 0x0424, 0x0429, 0x042d}, + { + 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b, + 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7, + 0x0422, 0x0427, 0x042b}, + { + 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a, + 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9, + 0x0420, 0x0424, 0x0429}, + { + 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a, + 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de, + 0x041b, 0x041f, 0x0424} +}; + +static chan_info_nphy_radio2057_t chan_info_nphyrev8_2057_rev7[] = { + { + 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b4, 0x07b0, 0x07ac, 0x0214, + 0x0215, + 0x0216}, + { + 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213, + 0x0214, + 0x0215}, + { + 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212, + 0x0213, + 0x0214}, + { + 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211, + 0x0212, + 0x0213}, + { + 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f, + 0x0211, + 0x0212}, + { + 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e, + 0x020f, + 0x0211}, + { + 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d, + 0x020e, + 0x020f}, + { + 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c, + 0x020d, + 0x020e}, + { + 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b, + 0x020c, + 0x020d}, + { + 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a, + 0x020b, + 0x020c}, + { + 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209, + 0x020a, + 0x020b}, + { + 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208, + 0x0209, + 0x020a}, + { + 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207, + 0x0208, + 0x0209}, + { + 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206, + 0x0207, + 0x0208}, + { + 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205, + 0x0206, + 0x0207}, + { + 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204, + 0x0205, + 0x0206}, + { + 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203, + 0x0204, + 0x0205}, + { + 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202, + 0x0203, + 0x0204}, + { + 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, + 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201, + 0x0202, + 0x0203}, + { + 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, + 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200, + 0x0201, + 0x0202}, + { + 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, + 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff, + 0x0200, + 0x0201}, + { + 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, + 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe, + 0x01ff, + 0x0200}, + { + 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, + 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd, + 0x01fe, + 0x01ff}, + { + 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, + 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb, + 0x01fc, + 0x01fd}, + { + 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, + 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa, + 0x01fb, + 0x01fc}, + { + 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, + 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9, + 0x01fa, + 0x01fb}, + { + 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, + 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8, + 0x01f9, + 0x01fa}, + { + 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7, + 0x01f8, + 0x01f9}, + { + 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6, + 0x01f7, + 0x01f8}, + { + 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5, + 0x01f6, + 0x01f7}, + { + 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4, + 0x01f5, + 0x01f6}, + { + 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3, + 0x01f4, + 0x01f5}, + { + 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2, + 0x01f3, + 0x01f4}, + { + 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1, + 0x01f2, + 0x01f3}, + { + 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0, + 0x01f1, + 0x01f2}, + { + 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0, + 0x01f0, + 0x01f1}, + { + 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef, + 0x01f0, + 0x01f0}, + { + 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee, + 0x01ef, + 0x01f0}, + { + 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed, + 0x01ee, + 0x01ef}, + { + 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec, + 0x01ed, + 0x01ee}, + { + 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb, + 0x01ec, + 0x01ed}, + { + 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea, + 0x01eb, + 0x01ec}, + { + 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9, + 0x01ea, + 0x01eb}, + { + 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8, + 0x01e9, + 0x01ea}, + { + 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7, + 0x01e8, + 0x01e9}, + { + 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6, + 0x01e7, + 0x01e8}, + { + 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5, + 0x01e6, + 0x01e7}, + { + 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5, + 0x01e5, + 0x01e6}, + { + 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4, + 0x01e5, + 0x01e5}, + { + 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3, + 0x01e4, + 0x01e5}, + { + 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2, + 0x01e3, + 0x01e4}, + { + 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1, + 0x01e2, + 0x01e3}, + { + 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0, + 0x01e1, + 0x01e2}, + { + 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df, + 0x01e0, + 0x01e1}, + { + 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de, + 0x01df, + 0x01e0}, + { + 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd, + 0x01de, + 0x01df}, + { + 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd, + 0x01dd, + 0x01de}, + { + 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc, + 0x01dd, + 0x01dd}, + { + 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db, + 0x01dc, + 0x01dd}, + { + 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da, + 0x01db, + 0x01dc}, + { + 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9, + 0x01da, + 0x01db}, + { + 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8, + 0x01d9, + 0x01da}, + { + 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7, + 0x01d8, + 0x01d9}, + { + 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7, + 0x01d7, + 0x01d8}, + { + 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6, + 0x01d7, + 0x01d7}, + { + 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5, + 0x01d6, + 0x01d7}, + { + 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4, + 0x01d5, + 0x01d6}, + { + 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3, + 0x01d4, + 0x01d5}, + { + 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2, + 0x01d3, + 0x01d4}, + { + 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2, + 0x01d2, + 0x01d3}, + { + 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1, + 0x01d2, + 0x01d2}, + { + 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0, + 0x01d1, + 0x01d2}, + { + 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf, + 0x01d0, + 0x01d1}, + { + 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce, + 0x01cf, + 0x01d0}, + { + 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce, + 0x01ce, + 0x01cf}, + { + 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd, + 0x01ce, + 0x01ce}, + { + 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc, + 0x01cd, + 0x01ce}, + { + 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb, + 0x01cc, + 0x01cd}, + { + 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca, + 0x01cb, + 0x01cc}, + { + 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9, + 0x01ca, + 0x01cb}, + { + 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9, + 0x01ca, + 0x01cb}, + { + 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9, + 0x01c9, + 0x01ca}, + { + 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8, + 0x01c9, + 0x01ca}, + { + 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8, + 0x01c9, + 0x01c9}, + { + 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8, + 0x01c8, + 0x01c9}, + { + 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, + 0x01c8, + 0x01c9}, + { + 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, + 0x01c8, + 0x01c8}, + { + 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, + 0x01c7, + 0x01c8}, + { + 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, + 0x01c7, + 0x01c8}, + { + 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, + 0x01c6, + 0x01c7}, + { + 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, + 0x01c6, + 0x01c7}, + { + 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, + 0x01c6, + 0x01c6}, + { + 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, + 0x01c5, + 0x01c6}, + { + 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, + 0x01c5, + 0x01c6}, + { + 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, + 0x01c4, + 0x01c5}, + { + 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, + 0x01c4, + 0x01c5}, + { + 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, + 0x01c4, + 0x01c4}, + { + 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, + 0x01c3, + 0x01c4}, + { + 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, + 0x01c3, + 0x01c4}, + { + 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, + 0x01c2, + 0x01c3}, + { + 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, + 0x01c2, + 0x01c3}, + { + 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, + 0x01c2, + 0x01c2}, + { + 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, + 0x01c1, + 0x01c2}, + { + 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04, + 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, + 0x01c0, + 0x01c1}, + { + 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04, + 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, + 0x01bf, + 0x01c0}, + { + 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04, + 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, + 0x01bf, + 0x01bf}, + { + 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03, + 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, + 0x01be, + 0x01bf}, + { + 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03, + 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, + 0x01bd, + 0x01be}, + { + 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03, + 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, + 0x01bc, + 0x01bd}, + { + 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f, + 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a, + 0x043f, + 0x0443}, + { + 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f, + 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438, + 0x043d, + 0x0441}, + { + 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f, + 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436, + 0x043a, + 0x043f}, + { + 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f, + 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434, + 0x0438, + 0x043d}, + { + 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f, + 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431, + 0x0436, + 0x043a}, + { + 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f, + 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f, + 0x0434, + 0x0438}, + { + 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f, + 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d, + 0x0431, + 0x0436}, + { + 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f, + 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b, + 0x042f, + 0x0434}, + { + 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f, + 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429, + 0x042d, + 0x0431}, + { + 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f, + 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427, + 0x042b, + 0x042f}, + { + 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f, + 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424, + 0x0429, + 0x042d}, + { + 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f, + 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422, + 0x0427, + 0x042b}, + { + 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f, + 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420, + 0x0424, + 0x0429}, + { + 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f, + 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b, + 0x041f, + 0x0424} +}; + +static chan_info_nphy_radio2057_t chan_info_nphyrev8_2057_rev8[] = { + { + 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213, + 0x0214, + 0x0215}, + { + 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212, + 0x0213, + 0x0214}, + { + 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211, + 0x0212, + 0x0213}, + { + 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f, + 0x0211, + 0x0212}, + { + 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e, + 0x020f, + 0x0211}, + { + 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d, + 0x020e, + 0x020f}, + { + 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c, + 0x020d, + 0x020e}, + { + 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b, + 0x020c, + 0x020d}, + { + 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f, + 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a, + 0x020b, + 0x020c}, + { + 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209, + 0x020a, + 0x020b}, + { + 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208, + 0x0209, + 0x020a}, + { + 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207, + 0x0208, + 0x0209}, + { + 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206, + 0x0207, + 0x0208}, + { + 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205, + 0x0206, + 0x0207}, + { + 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204, + 0x0205, + 0x0206}, + { + 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203, + 0x0204, + 0x0205}, + { + 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e, + 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, + 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202, + 0x0203, + 0x0204}, + { + 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, + 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201, + 0x0202, + 0x0203}, + { + 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, + 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200, + 0x0201, + 0x0202}, + { + 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, + 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff, + 0x0200, + 0x0201}, + { + 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, + 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe, + 0x01ff, + 0x0200}, + { + 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, + 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd, + 0x01fe, + 0x01ff}, + { + 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, + 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb, + 0x01fc, + 0x01fd}, + { + 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d, + 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, + 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa, + 0x01fb, + 0x01fc}, + { + 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, + 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9, + 0x01fa, + 0x01fb}, + { + 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, + 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8, + 0x01f9, + 0x01fa}, + { + 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7, + 0x01f8, + 0x01f9}, + { + 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6, + 0x01f7, + 0x01f8}, + { + 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5, + 0x01f6, + 0x01f7}, + { + 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4, + 0x01f5, + 0x01f6}, + { + 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3, + 0x01f4, + 0x01f5}, + { + 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c, + 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2, + 0x01f3, + 0x01f4}, + { + 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1, + 0x01f2, + 0x01f3}, + { + 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0, + 0x01f1, + 0x01f2}, + { + 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0, + 0x01f0, + 0x01f1}, + { + 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, + 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef, + 0x01f0, + 0x01f0}, + { + 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee, + 0x01ef, + 0x01f0}, + { + 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed, + 0x01ee, + 0x01ef}, + { + 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec, + 0x01ed, + 0x01ee}, + { + 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b, + 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb, + 0x01ec, + 0x01ed}, + { + 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea, + 0x01eb, + 0x01ec}, + { + 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9, + 0x01ea, + 0x01eb}, + { + 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8, + 0x01e9, + 0x01ea}, + { + 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7, + 0x01e8, + 0x01e9}, + { + 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6, + 0x01e7, + 0x01e8}, + { + 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, + 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5, + 0x01e6, + 0x01e7}, + { + 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5, + 0x01e5, + 0x01e6}, + { + 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a, + 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4, + 0x01e5, + 0x01e5}, + { + 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3, + 0x01e4, + 0x01e5}, + { + 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2, + 0x01e3, + 0x01e4}, + { + 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1, + 0x01e2, + 0x01e3}, + { + 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0, + 0x01e1, + 0x01e2}, + { + 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df, + 0x01e0, + 0x01e1}, + { + 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de, + 0x01df, + 0x01e0}, + { + 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd, + 0x01de, + 0x01df}, + { + 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, + 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd, + 0x01dd, + 0x01de}, + { + 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc, + 0x01dd, + 0x01dd}, + { + 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09, + 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db, + 0x01dc, + 0x01dd}, + { + 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da, + 0x01db, + 0x01dc}, + { + 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9, + 0x01da, + 0x01db}, + { + 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8, + 0x01d9, + 0x01da}, + { + 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7, + 0x01d8, + 0x01d9}, + { + 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7, + 0x01d7, + 0x01d8}, + { + 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6, + 0x01d7, + 0x01d7}, + { + 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5, + 0x01d6, + 0x01d7}, + { + 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, + 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4, + 0x01d5, + 0x01d6}, + { + 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3, + 0x01d4, + 0x01d5}, + { + 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2, + 0x01d3, + 0x01d4}, + { + 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2, + 0x01d2, + 0x01d3}, + { + 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1, + 0x01d2, + 0x01d2}, + { + 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0, + 0x01d1, + 0x01d2}, + { + 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf, + 0x01d0, + 0x01d1}, + { + 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce, + 0x01cf, + 0x01d0}, + { + 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce, + 0x01ce, + 0x01cf}, + { + 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd, + 0x01ce, + 0x01ce}, + { + 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00, + 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc, + 0x01cd, + 0x01ce}, + { + 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb, + 0x01cc, + 0x01cd}, + { + 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca, + 0x01cb, + 0x01cc}, + { + 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07, + 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9, + 0x01ca, + 0x01cb}, + { + 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9, + 0x01ca, + 0x01cb}, + { + 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9, + 0x01c9, + 0x01ca}, + { + 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8, + 0x01c9, + 0x01ca}, + { + 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8, + 0x01c9, + 0x01c9}, + { + 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8, + 0x01c8, + 0x01c9}, + { + 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, + 0x01c8, + 0x01c9}, + { + 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, + 0x01c8, + 0x01c8}, + { + 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, + 0x01c7, + 0x01c8}, + { + 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, + 0x01c7, + 0x01c8}, + { + 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, + 0x01c6, + 0x01c7}, + { + 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, + 0x01c6, + 0x01c7}, + { + 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06, + 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, + 0x01c6, + 0x01c6}, + { + 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, + 0x01c5, + 0x01c6}, + { + 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, + 0x01c5, + 0x01c6}, + { + 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, + 0x01c4, + 0x01c5}, + { + 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, + 0x01c4, + 0x01c5}, + { + 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, + 0x01c4, + 0x01c4}, + { + 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, + 0x01c3, + 0x01c4}, + { + 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, + 0x01c3, + 0x01c4}, + { + 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, + 0x01c2, + 0x01c3}, + { + 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, + 0x01c2, + 0x01c3}, + { + 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, + 0x01c2, + 0x01c2}, + { + 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05, + 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, + 0x01c1, + 0x01c2}, + { + 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04, + 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, + 0x01c0, + 0x01c1}, + { + 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04, + 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, + 0x01bf, + 0x01c0}, + { + 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04, + 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, + 0x01bf, + 0x01bf}, + { + 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03, + 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, + 0x01be, + 0x01bf}, + { + 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03, + 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, + 0x01bd, + 0x01be}, + { + 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03, + 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, + 0x01bc, + 0x01bd}, + { + 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f, + 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a, + 0x043f, + 0x0443}, + { + 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f, + 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438, + 0x043d, + 0x0441}, + { + 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f, + 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436, + 0x043a, + 0x043f}, + { + 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f, + 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434, + 0x0438, + 0x043d}, + { + 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f, + 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431, + 0x0436, + 0x043a}, + { + 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f, + 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f, + 0x0434, + 0x0438}, + { + 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f, + 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d, + 0x0431, + 0x0436}, + { + 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f, + 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b, + 0x042f, + 0x0434}, + { + 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f, + 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429, + 0x042d, + 0x0431}, + { + 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f, + 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427, + 0x042b, + 0x042f}, + { + 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f, + 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424, + 0x0429, + 0x042d}, + { + 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f, + 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422, + 0x0427, + 0x042b}, + { + 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f, + 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420, + 0x0424, + 0x0429}, + { + 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f, + 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61, + 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b, + 0x041f, + 0x0424} +}; + +radio_regs_t regs_2055[] = { + {0x02, 0x80, 0x80, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0x27, 0x27, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0x27, 0x27, 0, 0}, + {0x07, 0x7f, 0x7f, 1, 1}, + {0x08, 0x7, 0x7, 1, 1}, + {0x09, 0x7f, 0x7f, 1, 1}, + {0x0A, 0x7, 0x7, 1, 1}, + {0x0B, 0x15, 0x15, 0, 0}, + {0x0C, 0x15, 0x15, 0, 0}, + {0x0D, 0x4f, 0x4f, 1, 1}, + {0x0E, 0x5, 0x5, 1, 1}, + {0x0F, 0x4f, 0x4f, 1, 1}, + {0x10, 0x5, 0x5, 1, 1}, + {0x11, 0xd0, 0xd0, 0, 0}, + {0x12, 0x2, 0x2, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0x40, 0x40, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0xc0, 0xc0, 0, 0}, + {0x1E, 0xff, 0xff, 0, 0}, + {0x1F, 0xc0, 0xc0, 0, 0}, + {0x20, 0xff, 0xff, 0, 0}, + {0x21, 0xc0, 0xc0, 0, 0}, + {0x22, 0, 0, 0, 0}, + {0x23, 0x2c, 0x2c, 0, 0}, + {0x24, 0, 0, 0, 0}, + {0x25, 0, 0, 0, 0}, + {0x26, 0, 0, 0, 0}, + {0x27, 0, 0, 0, 0}, + {0x28, 0, 0, 0, 0}, + {0x29, 0, 0, 0, 0}, + {0x2A, 0, 0, 0, 0}, + {0x2B, 0, 0, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0xa4, 0xa4, 0, 0}, + {0x2E, 0x38, 0x38, 0, 0}, + {0x2F, 0, 0, 0, 0}, + {0x30, 0x4, 0x4, 1, 1}, + {0x31, 0, 0, 0, 0}, + {0x32, 0xa, 0xa, 0, 0}, + {0x33, 0x87, 0x87, 0, 0}, + {0x34, 0x9, 0x9, 0, 0}, + {0x35, 0x70, 0x70, 0, 0}, + {0x36, 0x11, 0x11, 0, 0}, + {0x37, 0x18, 0x18, 1, 1}, + {0x38, 0x6, 0x6, 0, 0}, + {0x39, 0x4, 0x4, 1, 1}, + {0x3A, 0x6, 0x6, 0, 0}, + {0x3B, 0x9e, 0x9e, 0, 0}, + {0x3C, 0x9, 0x9, 0, 0}, + {0x3D, 0xc8, 0xc8, 1, 1}, + {0x3E, 0x88, 0x88, 0, 0}, + {0x3F, 0, 0, 0, 0}, + {0x40, 0, 0, 0, 0}, + {0x41, 0, 0, 0, 0}, + {0x42, 0x1, 0x1, 0, 0}, + {0x43, 0x2, 0x2, 0, 0}, + {0x44, 0x96, 0x96, 0, 0}, + {0x45, 0x3e, 0x3e, 0, 0}, + {0x46, 0x3e, 0x3e, 0, 0}, + {0x47, 0x13, 0x13, 0, 0}, + {0x48, 0x2, 0x2, 0, 0}, + {0x49, 0x15, 0x15, 0, 0}, + {0x4A, 0x7, 0x7, 0, 0}, + {0x4B, 0, 0, 0, 0}, + {0x4C, 0, 0, 0, 0}, + {0x4D, 0, 0, 0, 0}, + {0x4E, 0, 0, 0, 0}, + {0x4F, 0, 0, 0, 0}, + {0x50, 0x8, 0x8, 0, 0}, + {0x51, 0x8, 0x8, 0, 0}, + {0x52, 0x6, 0x6, 0, 0}, + {0x53, 0x84, 0x84, 1, 1}, + {0x54, 0xc3, 0xc3, 0, 0}, + {0x55, 0x8f, 0x8f, 0, 0}, + {0x56, 0xff, 0xff, 0, 0}, + {0x57, 0xff, 0xff, 0, 0}, + {0x58, 0x88, 0x88, 0, 0}, + {0x59, 0x88, 0x88, 0, 0}, + {0x5A, 0, 0, 0, 0}, + {0x5B, 0xcc, 0xcc, 0, 0}, + {0x5C, 0x6, 0x6, 0, 0}, + {0x5D, 0x80, 0x80, 0, 0}, + {0x5E, 0x80, 0x80, 0, 0}, + {0x5F, 0xf8, 0xf8, 0, 0}, + {0x60, 0x88, 0x88, 0, 0}, + {0x61, 0x88, 0x88, 0, 0}, + {0x62, 0x88, 0x8, 1, 1}, + {0x63, 0x88, 0x88, 0, 0}, + {0x64, 0, 0, 0, 0}, + {0x65, 0x1, 0x1, 1, 1}, + {0x66, 0x8a, 0x8a, 0, 0}, + {0x67, 0x8, 0x8, 0, 0}, + {0x68, 0x83, 0x83, 0, 0}, + {0x69, 0x6, 0x6, 0, 0}, + {0x6A, 0xa0, 0xa0, 0, 0}, + {0x6B, 0xa, 0xa, 0, 0}, + {0x6C, 0x87, 0x87, 1, 1}, + {0x6D, 0x2a, 0x2a, 0, 0}, + {0x6E, 0x2a, 0x2a, 0, 0}, + {0x6F, 0x2a, 0x2a, 0, 0}, + {0x70, 0x2a, 0x2a, 0, 0}, + {0x71, 0x18, 0x18, 0, 0}, + {0x72, 0x6a, 0x6a, 1, 1}, + {0x73, 0xab, 0xab, 1, 1}, + {0x74, 0x13, 0x13, 1, 1}, + {0x75, 0xc1, 0xc1, 1, 1}, + {0x76, 0xaa, 0xaa, 1, 1}, + {0x77, 0x87, 0x87, 1, 1}, + {0x78, 0, 0, 0, 0}, + {0x79, 0x6, 0x6, 0, 0}, + {0x7A, 0x7, 0x7, 0, 0}, + {0x7B, 0x7, 0x7, 0, 0}, + {0x7C, 0x15, 0x15, 0, 0}, + {0x7D, 0x55, 0x55, 0, 0}, + {0x7E, 0x97, 0x97, 1, 1}, + {0x7F, 0x8, 0x8, 0, 0}, + {0x80, 0x14, 0x14, 1, 1}, + {0x81, 0x33, 0x33, 0, 0}, + {0x82, 0x88, 0x88, 0, 0}, + {0x83, 0x6, 0x6, 0, 0}, + {0x84, 0x3, 0x3, 1, 1}, + {0x85, 0xa, 0xa, 0, 0}, + {0x86, 0x3, 0x3, 1, 1}, + {0x87, 0x2a, 0x2a, 0, 0}, + {0x88, 0xa4, 0xa4, 0, 0}, + {0x89, 0x18, 0x18, 0, 0}, + {0x8A, 0x28, 0x28, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0x4a, 0x4a, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0xf8, 0xf8, 0, 0}, + {0x8F, 0x88, 0x88, 0, 0}, + {0x90, 0x88, 0x88, 0, 0}, + {0x91, 0x88, 0x8, 1, 1}, + {0x92, 0x88, 0x88, 0, 0}, + {0x93, 0, 0, 0, 0}, + {0x94, 0x1, 0x1, 1, 1}, + {0x95, 0x8a, 0x8a, 0, 0}, + {0x96, 0x8, 0x8, 0, 0}, + {0x97, 0x83, 0x83, 0, 0}, + {0x98, 0x6, 0x6, 0, 0}, + {0x99, 0xa0, 0xa0, 0, 0}, + {0x9A, 0xa, 0xa, 0, 0}, + {0x9B, 0x87, 0x87, 1, 1}, + {0x9C, 0x2a, 0x2a, 0, 0}, + {0x9D, 0x2a, 0x2a, 0, 0}, + {0x9E, 0x2a, 0x2a, 0, 0}, + {0x9F, 0x2a, 0x2a, 0, 0}, + {0xA0, 0x18, 0x18, 0, 0}, + {0xA1, 0x6a, 0x6a, 1, 1}, + {0xA2, 0xab, 0xab, 1, 1}, + {0xA3, 0x13, 0x13, 1, 1}, + {0xA4, 0xc1, 0xc1, 1, 1}, + {0xA5, 0xaa, 0xaa, 1, 1}, + {0xA6, 0x87, 0x87, 1, 1}, + {0xA7, 0, 0, 0, 0}, + {0xA8, 0x6, 0x6, 0, 0}, + {0xA9, 0x7, 0x7, 0, 0}, + {0xAA, 0x7, 0x7, 0, 0}, + {0xAB, 0x15, 0x15, 0, 0}, + {0xAC, 0x55, 0x55, 0, 0}, + {0xAD, 0x97, 0x97, 1, 1}, + {0xAE, 0x8, 0x8, 0, 0}, + {0xAF, 0x14, 0x14, 1, 1}, + {0xB0, 0x33, 0x33, 0, 0}, + {0xB1, 0x88, 0x88, 0, 0}, + {0xB2, 0x6, 0x6, 0, 0}, + {0xB3, 0x3, 0x3, 1, 1}, + {0xB4, 0xa, 0xa, 0, 0}, + {0xB5, 0x3, 0x3, 1, 1}, + {0xB6, 0x2a, 0x2a, 0, 0}, + {0xB7, 0xa4, 0xa4, 0, 0}, + {0xB8, 0x18, 0x18, 0, 0}, + {0xB9, 0x28, 0x28, 0, 0}, + {0xBA, 0, 0, 0, 0}, + {0xBB, 0x4a, 0x4a, 0, 0}, + {0xBC, 0, 0, 0, 0}, + {0xBD, 0x71, 0x71, 0, 0}, + {0xBE, 0x72, 0x72, 0, 0}, + {0xBF, 0x73, 0x73, 0, 0}, + {0xC0, 0x74, 0x74, 0, 0}, + {0xC1, 0x75, 0x75, 0, 0}, + {0xC2, 0x76, 0x76, 0, 0}, + {0xC3, 0x77, 0x77, 0, 0}, + {0xC4, 0x78, 0x78, 0, 0}, + {0xC5, 0x79, 0x79, 0, 0}, + {0xC6, 0x7a, 0x7a, 0, 0}, + {0xC7, 0, 0, 0, 0}, + {0xC8, 0, 0, 0, 0}, + {0xC9, 0, 0, 0, 0}, + {0xCA, 0, 0, 0, 0}, + {0xCB, 0, 0, 0, 0}, + {0xCC, 0, 0, 0, 0}, + {0xCD, 0, 0, 0, 0}, + {0xCE, 0x6, 0x6, 0, 0}, + {0xCF, 0, 0, 0, 0}, + {0xD0, 0, 0, 0, 0}, + {0xD1, 0x18, 0x18, 0, 0}, + {0xD2, 0x88, 0x88, 0, 0}, + {0xD3, 0, 0, 0, 0}, + {0xD4, 0, 0, 0, 0}, + {0xD5, 0, 0, 0, 0}, + {0xD6, 0, 0, 0, 0}, + {0xD7, 0, 0, 0, 0}, + {0xD8, 0, 0, 0, 0}, + {0xD9, 0, 0, 0, 0}, + {0xDA, 0x6, 0x6, 0, 0}, + {0xDB, 0, 0, 0, 0}, + {0xDC, 0, 0, 0, 0}, + {0xDD, 0x18, 0x18, 0, 0}, + {0xDE, 0x88, 0x88, 0, 0}, + {0xDF, 0, 0, 0, 0}, + {0xE0, 0, 0, 0, 0}, + {0xE1, 0, 0, 0, 0}, + {0xE2, 0, 0, 0, 0}, + {0xFFFF, 0, 0, 0, 0}, +}; + +radio_regs_t regs_SYN_2056[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0x1, 0x1, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0, 0, 0, 0}, + {0x21, 0, 0, 0, 0}, + {0x22, 0x60, 0x60, 0, 0}, + {0x23, 0x6, 0x6, 0, 0}, + {0x24, 0xc, 0xc, 0, 0}, + {0x25, 0, 0, 0, 0}, + {0x26, 0, 0, 0, 0}, + {0x27, 0, 0, 0, 0}, + {0x28, 0x1, 0x1, 0, 0}, + {0x29, 0, 0, 0, 0}, + {0x2A, 0, 0, 0, 0}, + {0x2B, 0, 0, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0, 0, 0, 0}, + {0x2E, 0xd, 0xd, 0, 0}, + {0x2F, 0x1f, 0x1f, 0, 0}, + {0x30, 0x15, 0x15, 0, 0}, + {0x31, 0xf, 0xf, 0, 0}, + {0x32, 0, 0, 0, 0}, + {0x33, 0, 0, 0, 0}, + {0x34, 0, 0, 0, 0}, + {0x35, 0, 0, 0, 0}, + {0x36, 0, 0, 0, 0}, + {0x37, 0, 0, 0, 0}, + {0x38, 0, 0, 0, 0}, + {0x39, 0, 0, 0, 0}, + {0x3A, 0, 0, 0, 0}, + {0x3B, 0, 0, 0, 0}, + {0x3C, 0x13, 0x13, 0, 0}, + {0x3D, 0xf, 0xf, 0, 0}, + {0x3E, 0x18, 0x18, 0, 0}, + {0x3F, 0, 0, 0, 0}, + {0x40, 0, 0, 0, 0}, + {0x41, 0x20, 0x20, 0, 0}, + {0x42, 0x20, 0x20, 0, 0}, + {0x43, 0, 0, 0, 0}, + {0x44, 0x77, 0x77, 0, 0}, + {0x45, 0x7, 0x7, 0, 0}, + {0x46, 0x1, 0x1, 0, 0}, + {0x47, 0x4, 0x4, 0, 0}, + {0x48, 0xf, 0xf, 0, 0}, + {0x49, 0x30, 0x30, 0, 0}, + {0x4A, 0x32, 0x32, 0, 0}, + {0x4B, 0xd, 0xd, 0, 0}, + {0x4C, 0xd, 0xd, 0, 0}, + {0x4D, 0x4, 0x4, 0, 0}, + {0x4E, 0x6, 0x6, 0, 0}, + {0x4F, 0x1, 0x1, 0, 0}, + {0x50, 0x1c, 0x1c, 0, 0}, + {0x51, 0x2, 0x2, 0, 0}, + {0x52, 0x2, 0x2, 0, 0}, + {0x53, 0xf7, 0xf7, 1, 1}, + {0x54, 0xb4, 0xb4, 0, 0}, + {0x55, 0xd2, 0xd2, 0, 0}, + {0x56, 0, 0, 0, 0}, + {0x57, 0, 0, 0, 0}, + {0x58, 0x4, 0x4, 0, 0}, + {0x59, 0x96, 0x96, 0, 0}, + {0x5A, 0x3e, 0x3e, 0, 0}, + {0x5B, 0x3e, 0x3e, 0, 0}, + {0x5C, 0x13, 0x13, 0, 0}, + {0x5D, 0x2, 0x2, 0, 0}, + {0x5E, 0, 0, 0, 0}, + {0x5F, 0x7, 0x7, 0, 0}, + {0x60, 0x7, 0x7, 1, 1}, + {0x61, 0x8, 0x8, 0, 0}, + {0x62, 0x3, 0x3, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0, 0, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0, 0, 0, 0}, + {0x68, 0x40, 0x40, 0, 0}, + {0x69, 0, 0, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0, 0, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0x1, 0x1, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0x60, 0x60, 0, 0}, + {0x71, 0x66, 0x66, 0, 0}, + {0x72, 0xc, 0xc, 0, 0}, + {0x73, 0x66, 0x66, 0, 0}, + {0x74, 0x8f, 0x8f, 1, 1}, + {0x75, 0, 0, 0, 0}, + {0x76, 0xcc, 0xcc, 0, 0}, + {0x77, 0x1, 0x1, 0, 0}, + {0x78, 0x66, 0x66, 0, 0}, + {0x79, 0x66, 0x66, 0, 0}, + {0x7A, 0, 0, 0, 0}, + {0x7B, 0, 0, 0, 0}, + {0x7C, 0, 0, 0, 0}, + {0x7D, 0, 0, 0, 0}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0xff, 0xff, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0x93, 0, 0, 0, 0}, + {0x94, 0, 0, 0, 0}, + {0x95, 0, 0, 0, 0}, + {0x96, 0, 0, 0, 0}, + {0x97, 0, 0, 0, 0}, + {0x98, 0, 0, 0, 0}, + {0x99, 0, 0, 0, 0}, + {0x9A, 0, 0, 0, 0}, + {0x9B, 0, 0, 0, 0}, + {0x9C, 0, 0, 0, 0}, + {0x9D, 0, 0, 0, 0}, + {0x9E, 0, 0, 0, 0}, + {0x9F, 0x6, 0x6, 0, 0}, + {0xA0, 0x66, 0x66, 0, 0}, + {0xA1, 0x66, 0x66, 0, 0}, + {0xA2, 0x66, 0x66, 0, 0}, + {0xA3, 0x66, 0x66, 0, 0}, + {0xA4, 0x66, 0x66, 0, 0}, + {0xA5, 0x66, 0x66, 0, 0}, + {0xA6, 0x66, 0x66, 0, 0}, + {0xA7, 0x66, 0x66, 0, 0}, + {0xA8, 0x66, 0x66, 0, 0}, + {0xA9, 0x66, 0x66, 0, 0}, + {0xAA, 0x66, 0x66, 0, 0}, + {0xAB, 0x66, 0x66, 0, 0}, + {0xAC, 0x66, 0x66, 0, 0}, + {0xAD, 0x66, 0x66, 0, 0}, + {0xAE, 0x66, 0x66, 0, 0}, + {0xAF, 0x66, 0x66, 0, 0}, + {0xB0, 0x66, 0x66, 0, 0}, + {0xB1, 0x66, 0x66, 0, 0}, + {0xB2, 0x66, 0x66, 0, 0}, + {0xB3, 0xa, 0xa, 0, 0}, + {0xB4, 0, 0, 0, 0}, + {0xB5, 0, 0, 0, 0}, + {0xB6, 0, 0, 0, 0}, + {0xFFFF, 0, 0, 0, 0} +}; + +radio_regs_t regs_TX_2056[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0, 0, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0, 0, 0, 0}, + {0x21, 0x88, 0x88, 0, 0}, + {0x22, 0x88, 0x88, 0, 0}, + {0x23, 0x88, 0x88, 0, 0}, + {0x24, 0x88, 0x88, 0, 0}, + {0x25, 0xc, 0xc, 0, 0}, + {0x26, 0, 0, 0, 0}, + {0x27, 0x3, 0x3, 0, 0}, + {0x28, 0, 0, 0, 0}, + {0x29, 0x3, 0x3, 0, 0}, + {0x2A, 0x37, 0x37, 0, 0}, + {0x2B, 0x3, 0x3, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0, 0, 0, 0}, + {0x2E, 0x1, 0x1, 0, 0}, + {0x2F, 0x1, 0x1, 0, 0}, + {0x30, 0, 0, 0, 0}, + {0x31, 0, 0, 0, 0}, + {0x32, 0, 0, 0, 0}, + {0x33, 0x11, 0x11, 0, 0}, + {0x34, 0x11, 0x11, 0, 0}, + {0x35, 0, 0, 0, 0}, + {0x36, 0, 0, 0, 0}, + {0x37, 0x3, 0x3, 0, 0}, + {0x38, 0xf, 0xf, 0, 0}, + {0x39, 0, 0, 0, 0}, + {0x3A, 0x2d, 0x2d, 0, 0}, + {0x3B, 0, 0, 0, 0}, + {0x3C, 0x6e, 0x6e, 0, 0}, + {0x3D, 0xf0, 0xf0, 1, 1}, + {0x3E, 0, 0, 0, 0}, + {0x3F, 0, 0, 0, 0}, + {0x40, 0, 0, 0, 0}, + {0x41, 0x3, 0x3, 0, 0}, + {0x42, 0x3, 0x3, 0, 0}, + {0x43, 0, 0, 0, 0}, + {0x44, 0x1e, 0x1e, 0, 0}, + {0x45, 0, 0, 0, 0}, + {0x46, 0x6e, 0x6e, 0, 0}, + {0x47, 0xf0, 0xf0, 1, 1}, + {0x48, 0, 0, 0, 0}, + {0x49, 0x2, 0x2, 0, 0}, + {0x4A, 0xff, 0xff, 1, 1}, + {0x4B, 0xc, 0xc, 0, 0}, + {0x4C, 0, 0, 0, 0}, + {0x4D, 0x38, 0x38, 0, 0}, + {0x4E, 0x70, 0x70, 1, 1}, + {0x4F, 0x2, 0x2, 0, 0}, + {0x50, 0x88, 0x88, 0, 0}, + {0x51, 0xc, 0xc, 0, 0}, + {0x52, 0, 0, 0, 0}, + {0x53, 0x8, 0x8, 0, 0}, + {0x54, 0x70, 0x70, 1, 1}, + {0x55, 0x2, 0x2, 0, 0}, + {0x56, 0xff, 0xff, 1, 1}, + {0x57, 0, 0, 0, 0}, + {0x58, 0x83, 0x83, 0, 0}, + {0x59, 0x77, 0x77, 1, 1}, + {0x5A, 0, 0, 0, 0}, + {0x5B, 0x2, 0x2, 0, 0}, + {0x5C, 0x88, 0x88, 0, 0}, + {0x5D, 0, 0, 0, 0}, + {0x5E, 0x8, 0x8, 0, 0}, + {0x5F, 0x77, 0x77, 1, 1}, + {0x60, 0x1, 0x1, 0, 0}, + {0x61, 0, 0, 0, 0}, + {0x62, 0x7, 0x7, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0x7, 0x7, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0x74, 0x74, 1, 1}, + {0x68, 0, 0, 0, 0}, + {0x69, 0xa, 0xa, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0, 0, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0, 0, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0, 0, 0, 0}, + {0x71, 0x2, 0x2, 0, 0}, + {0x72, 0, 0, 0, 0}, + {0x73, 0, 0, 0, 0}, + {0x74, 0xe, 0xe, 0, 0}, + {0x75, 0xe, 0xe, 0, 0}, + {0x76, 0xe, 0xe, 0, 0}, + {0x77, 0x13, 0x13, 0, 0}, + {0x78, 0x13, 0x13, 0, 0}, + {0x79, 0x1b, 0x1b, 0, 0}, + {0x7A, 0x1b, 0x1b, 0, 0}, + {0x7B, 0x55, 0x55, 0, 0}, + {0x7C, 0x5b, 0x5b, 0, 0}, + {0x7D, 0, 0, 0, 0}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0, 0, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0xFFFF, 0, 0, 0, 0} +}; + +radio_regs_t regs_RX_2056[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0, 0, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0x3, 0x3, 0, 0}, + {0x21, 0, 0, 0, 0}, + {0x22, 0, 0, 0, 0}, + {0x23, 0x90, 0x90, 0, 0}, + {0x24, 0x55, 0x55, 0, 0}, + {0x25, 0x15, 0x15, 0, 0}, + {0x26, 0x5, 0x5, 0, 0}, + {0x27, 0x15, 0x15, 0, 0}, + {0x28, 0x5, 0x5, 0, 0}, + {0x29, 0x20, 0x20, 0, 0}, + {0x2A, 0x11, 0x11, 0, 0}, + {0x2B, 0x90, 0x90, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0x88, 0x88, 0, 0}, + {0x2E, 0x32, 0x32, 0, 0}, + {0x2F, 0x77, 0x77, 0, 0}, + {0x30, 0x17, 0x17, 1, 1}, + {0x31, 0xff, 0xff, 1, 1}, + {0x32, 0x20, 0x20, 0, 0}, + {0x33, 0, 0, 0, 0}, + {0x34, 0x88, 0x88, 0, 0}, + {0x35, 0x32, 0x32, 0, 0}, + {0x36, 0x77, 0x77, 0, 0}, + {0x37, 0x17, 0x17, 1, 1}, + {0x38, 0xf0, 0xf0, 1, 1}, + {0x39, 0x20, 0x20, 0, 0}, + {0x3A, 0x8, 0x8, 0, 0}, + {0x3B, 0x99, 0x99, 0, 0}, + {0x3C, 0, 0, 0, 0}, + {0x3D, 0x44, 0x44, 1, 1}, + {0x3E, 0, 0, 0, 0}, + {0x3F, 0x44, 0x44, 0, 0}, + {0x40, 0xf, 0xf, 1, 1}, + {0x41, 0x6, 0x6, 0, 0}, + {0x42, 0x4, 0x4, 0, 0}, + {0x43, 0x50, 0x50, 1, 1}, + {0x44, 0x8, 0x8, 0, 0}, + {0x45, 0x99, 0x99, 0, 0}, + {0x46, 0, 0, 0, 0}, + {0x47, 0x11, 0x11, 0, 0}, + {0x48, 0, 0, 0, 0}, + {0x49, 0x44, 0x44, 0, 0}, + {0x4A, 0x7, 0x7, 0, 0}, + {0x4B, 0x6, 0x6, 0, 0}, + {0x4C, 0x4, 0x4, 0, 0}, + {0x4D, 0, 0, 0, 0}, + {0x4E, 0, 0, 0, 0}, + {0x4F, 0x66, 0x66, 0, 0}, + {0x50, 0x66, 0x66, 0, 0}, + {0x51, 0x57, 0x57, 0, 0}, + {0x52, 0x57, 0x57, 0, 0}, + {0x53, 0x44, 0x44, 0, 0}, + {0x54, 0, 0, 0, 0}, + {0x55, 0, 0, 0, 0}, + {0x56, 0x8, 0x8, 0, 0}, + {0x57, 0x8, 0x8, 0, 0}, + {0x58, 0x7, 0x7, 0, 0}, + {0x59, 0x22, 0x22, 0, 0}, + {0x5A, 0x22, 0x22, 0, 0}, + {0x5B, 0x2, 0x2, 0, 0}, + {0x5C, 0x23, 0x23, 0, 0}, + {0x5D, 0x7, 0x7, 0, 0}, + {0x5E, 0x55, 0x55, 0, 0}, + {0x5F, 0x23, 0x23, 0, 0}, + {0x60, 0x41, 0x41, 0, 0}, + {0x61, 0x1, 0x1, 0, 0}, + {0x62, 0xa, 0xa, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0, 0, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0, 0, 0, 0}, + {0x68, 0, 0, 0, 0}, + {0x69, 0, 0, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0xc, 0xc, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0, 0, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0, 0, 0, 0}, + {0x71, 0, 0, 0, 0}, + {0x72, 0x22, 0x22, 0, 0}, + {0x73, 0x22, 0x22, 0, 0}, + {0x74, 0x2, 0x2, 0, 0}, + {0x75, 0xa, 0xa, 0, 0}, + {0x76, 0x1, 0x1, 0, 0}, + {0x77, 0x22, 0x22, 0, 0}, + {0x78, 0x30, 0x30, 0, 0}, + {0x79, 0, 0, 0, 0}, + {0x7A, 0, 0, 0, 0}, + {0x7B, 0, 0, 0, 0}, + {0x7C, 0, 0, 0, 0}, + {0x7D, 0, 0, 0, 0}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0, 0, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0x93, 0, 0, 0, 0}, + {0x94, 0, 0, 0, 0}, + {0xFFFF, 0, 0, 0, 0} +}; + +radio_regs_t regs_SYN_2056_A1[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0x1, 0x1, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0, 0, 0, 0}, + {0x21, 0, 0, 0, 0}, + {0x22, 0x60, 0x60, 0, 0}, + {0x23, 0x6, 0x6, 0, 0}, + {0x24, 0xc, 0xc, 0, 0}, + {0x25, 0, 0, 0, 0}, + {0x26, 0, 0, 0, 0}, + {0x27, 0, 0, 0, 0}, + {0x28, 0x1, 0x1, 0, 0}, + {0x29, 0, 0, 0, 0}, + {0x2A, 0, 0, 0, 0}, + {0x2B, 0, 0, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0, 0, 0, 0}, + {0x2E, 0xd, 0xd, 0, 0}, + {0x2F, 0x1f, 0x1f, 0, 0}, + {0x30, 0x15, 0x15, 0, 0}, + {0x31, 0xf, 0xf, 0, 0}, + {0x32, 0, 0, 0, 0}, + {0x33, 0, 0, 0, 0}, + {0x34, 0, 0, 0, 0}, + {0x35, 0, 0, 0, 0}, + {0x36, 0, 0, 0, 0}, + {0x37, 0, 0, 0, 0}, + {0x38, 0, 0, 0, 0}, + {0x39, 0, 0, 0, 0}, + {0x3A, 0, 0, 0, 0}, + {0x3B, 0, 0, 0, 0}, + {0x3C, 0x13, 0x13, 0, 0}, + {0x3D, 0xf, 0xf, 0, 0}, + {0x3E, 0x18, 0x18, 0, 0}, + {0x3F, 0, 0, 0, 0}, + {0x40, 0, 0, 0, 0}, + {0x41, 0x20, 0x20, 0, 0}, + {0x42, 0x20, 0x20, 0, 0}, + {0x43, 0, 0, 0, 0}, + {0x44, 0x77, 0x77, 0, 0}, + {0x45, 0x7, 0x7, 0, 0}, + {0x46, 0x1, 0x1, 0, 0}, + {0x47, 0x4, 0x4, 0, 0}, + {0x48, 0xf, 0xf, 0, 0}, + {0x49, 0x30, 0x30, 0, 0}, + {0x4A, 0x32, 0x32, 0, 0}, + {0x4B, 0xd, 0xd, 0, 0}, + {0x4C, 0xd, 0xd, 0, 0}, + {0x4D, 0x4, 0x4, 0, 0}, + {0x4E, 0x6, 0x6, 0, 0}, + {0x4F, 0x1, 0x1, 0, 0}, + {0x50, 0x1c, 0x1c, 0, 0}, + {0x51, 0x2, 0x2, 0, 0}, + {0x52, 0x2, 0x2, 0, 0}, + {0x53, 0xf7, 0xf7, 1, 1}, + {0x54, 0xb4, 0xb4, 0, 0}, + {0x55, 0xd2, 0xd2, 0, 0}, + {0x56, 0, 0, 0, 0}, + {0x57, 0, 0, 0, 0}, + {0x58, 0x4, 0x4, 0, 0}, + {0x59, 0x96, 0x96, 0, 0}, + {0x5A, 0x3e, 0x3e, 0, 0}, + {0x5B, 0x3e, 0x3e, 0, 0}, + {0x5C, 0x13, 0x13, 0, 0}, + {0x5D, 0x2, 0x2, 0, 0}, + {0x5E, 0, 0, 0, 0}, + {0x5F, 0x7, 0x7, 0, 0}, + {0x60, 0x7, 0x7, 1, 1}, + {0x61, 0x8, 0x8, 0, 0}, + {0x62, 0x3, 0x3, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0, 0, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0, 0, 0, 0}, + {0x68, 0x40, 0x40, 0, 0}, + {0x69, 0, 0, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0, 0, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0x1, 0x1, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0x60, 0x60, 0, 0}, + {0x71, 0x66, 0x66, 0, 0}, + {0x72, 0xc, 0xc, 0, 0}, + {0x73, 0x66, 0x66, 0, 0}, + {0x74, 0x8f, 0x8f, 1, 1}, + {0x75, 0, 0, 0, 0}, + {0x76, 0xcc, 0xcc, 0, 0}, + {0x77, 0x1, 0x1, 0, 0}, + {0x78, 0x66, 0x66, 0, 0}, + {0x79, 0x66, 0x66, 0, 0}, + {0x7A, 0, 0, 0, 0}, + {0x7B, 0, 0, 0, 0}, + {0x7C, 0, 0, 0, 0}, + {0x7D, 0, 0, 0, 0}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0xff, 0xff, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0x93, 0, 0, 0, 0}, + {0x94, 0, 0, 0, 0}, + {0x95, 0, 0, 0, 0}, + {0x96, 0, 0, 0, 0}, + {0x97, 0, 0, 0, 0}, + {0x98, 0, 0, 0, 0}, + {0x99, 0, 0, 0, 0}, + {0x9A, 0, 0, 0, 0}, + {0x9B, 0, 0, 0, 0}, + {0x9C, 0, 0, 0, 0}, + {0x9D, 0, 0, 0, 0}, + {0x9E, 0, 0, 0, 0}, + {0x9F, 0x6, 0x6, 0, 0}, + {0xA0, 0x66, 0x66, 0, 0}, + {0xA1, 0x66, 0x66, 0, 0}, + {0xA2, 0x66, 0x66, 0, 0}, + {0xA3, 0x66, 0x66, 0, 0}, + {0xA4, 0x66, 0x66, 0, 0}, + {0xA5, 0x66, 0x66, 0, 0}, + {0xA6, 0x66, 0x66, 0, 0}, + {0xA7, 0x66, 0x66, 0, 0}, + {0xA8, 0x66, 0x66, 0, 0}, + {0xA9, 0x66, 0x66, 0, 0}, + {0xAA, 0x66, 0x66, 0, 0}, + {0xAB, 0x66, 0x66, 0, 0}, + {0xAC, 0x66, 0x66, 0, 0}, + {0xAD, 0x66, 0x66, 0, 0}, + {0xAE, 0x66, 0x66, 0, 0}, + {0xAF, 0x66, 0x66, 0, 0}, + {0xB0, 0x66, 0x66, 0, 0}, + {0xB1, 0x66, 0x66, 0, 0}, + {0xB2, 0x66, 0x66, 0, 0}, + {0xB3, 0xa, 0xa, 0, 0}, + {0xB4, 0, 0, 0, 0}, + {0xB5, 0, 0, 0, 0}, + {0xB6, 0, 0, 0, 0}, + {0xFFFF, 0, 0, 0, 0} +}; + +radio_regs_t regs_TX_2056_A1[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0, 0, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0, 0, 0, 0}, + {0x21, 0x88, 0x88, 0, 0}, + {0x22, 0x88, 0x88, 0, 0}, + {0x23, 0x88, 0x88, 0, 0}, + {0x24, 0x88, 0x88, 0, 0}, + {0x25, 0xc, 0xc, 0, 0}, + {0x26, 0, 0, 0, 0}, + {0x27, 0x3, 0x3, 0, 0}, + {0x28, 0, 0, 0, 0}, + {0x29, 0x3, 0x3, 0, 0}, + {0x2A, 0x37, 0x37, 0, 0}, + {0x2B, 0x3, 0x3, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0, 0, 0, 0}, + {0x2E, 0x1, 0x1, 0, 0}, + {0x2F, 0x1, 0x1, 0, 0}, + {0x30, 0, 0, 0, 0}, + {0x31, 0, 0, 0, 0}, + {0x32, 0, 0, 0, 0}, + {0x33, 0x11, 0x11, 0, 0}, + {0x34, 0x11, 0x11, 0, 0}, + {0x35, 0, 0, 0, 0}, + {0x36, 0, 0, 0, 0}, + {0x37, 0x3, 0x3, 0, 0}, + {0x38, 0xf, 0xf, 0, 0}, + {0x39, 0, 0, 0, 0}, + {0x3A, 0x2d, 0x2d, 0, 0}, + {0x3B, 0, 0, 0, 0}, + {0x3C, 0x6e, 0x6e, 0, 0}, + {0x3D, 0xf0, 0xf0, 1, 1}, + {0x3E, 0, 0, 0, 0}, + {0x3F, 0, 0, 0, 0}, + {0x40, 0, 0, 0, 0}, + {0x41, 0x3, 0x3, 0, 0}, + {0x42, 0x3, 0x3, 0, 0}, + {0x43, 0, 0, 0, 0}, + {0x44, 0x1e, 0x1e, 0, 0}, + {0x45, 0, 0, 0, 0}, + {0x46, 0x6e, 0x6e, 0, 0}, + {0x47, 0xf0, 0xf0, 1, 1}, + {0x48, 0, 0, 0, 0}, + {0x49, 0x2, 0x2, 0, 0}, + {0x4A, 0xff, 0xff, 1, 1}, + {0x4B, 0xc, 0xc, 0, 0}, + {0x4C, 0, 0, 0, 0}, + {0x4D, 0x38, 0x38, 0, 0}, + {0x4E, 0x70, 0x70, 1, 1}, + {0x4F, 0x2, 0x2, 0, 0}, + {0x50, 0x88, 0x88, 0, 0}, + {0x51, 0xc, 0xc, 0, 0}, + {0x52, 0, 0, 0, 0}, + {0x53, 0x8, 0x8, 0, 0}, + {0x54, 0x70, 0x70, 1, 1}, + {0x55, 0x2, 0x2, 0, 0}, + {0x56, 0xff, 0xff, 1, 1}, + {0x57, 0, 0, 0, 0}, + {0x58, 0x83, 0x83, 0, 0}, + {0x59, 0x77, 0x77, 1, 1}, + {0x5A, 0, 0, 0, 0}, + {0x5B, 0x2, 0x2, 0, 0}, + {0x5C, 0x88, 0x88, 0, 0}, + {0x5D, 0, 0, 0, 0}, + {0x5E, 0x8, 0x8, 0, 0}, + {0x5F, 0x77, 0x77, 1, 1}, + {0x60, 0x1, 0x1, 0, 0}, + {0x61, 0, 0, 0, 0}, + {0x62, 0x7, 0x7, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0x7, 0x7, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0x72, 0x72, 1, 1}, + {0x68, 0, 0, 0, 0}, + {0x69, 0xa, 0xa, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0, 0, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0, 0, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0, 0, 0, 0}, + {0x71, 0x2, 0x2, 0, 0}, + {0x72, 0, 0, 0, 0}, + {0x73, 0, 0, 0, 0}, + {0x74, 0xe, 0xe, 0, 0}, + {0x75, 0xe, 0xe, 0, 0}, + {0x76, 0xe, 0xe, 0, 0}, + {0x77, 0x13, 0x13, 0, 0}, + {0x78, 0x13, 0x13, 0, 0}, + {0x79, 0x1b, 0x1b, 0, 0}, + {0x7A, 0x1b, 0x1b, 0, 0}, + {0x7B, 0x55, 0x55, 0, 0}, + {0x7C, 0x5b, 0x5b, 0, 0}, + {0x7D, 0, 0, 0, 0}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0, 0, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0xFFFF, 0, 0, 0, 0} +}; + +radio_regs_t regs_RX_2056_A1[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0, 0, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0x3, 0x3, 0, 0}, + {0x21, 0, 0, 0, 0}, + {0x22, 0, 0, 0, 0}, + {0x23, 0x90, 0x90, 0, 0}, + {0x24, 0x55, 0x55, 0, 0}, + {0x25, 0x15, 0x15, 0, 0}, + {0x26, 0x5, 0x5, 0, 0}, + {0x27, 0x15, 0x15, 0, 0}, + {0x28, 0x5, 0x5, 0, 0}, + {0x29, 0x20, 0x20, 0, 0}, + {0x2A, 0x11, 0x11, 0, 0}, + {0x2B, 0x90, 0x90, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0x88, 0x88, 0, 0}, + {0x2E, 0x32, 0x32, 0, 0}, + {0x2F, 0x77, 0x77, 0, 0}, + {0x30, 0x17, 0x17, 1, 1}, + {0x31, 0xff, 0xff, 1, 1}, + {0x32, 0x20, 0x20, 0, 0}, + {0x33, 0, 0, 0, 0}, + {0x34, 0x88, 0x88, 0, 0}, + {0x35, 0x32, 0x32, 0, 0}, + {0x36, 0x77, 0x77, 0, 0}, + {0x37, 0x17, 0x17, 1, 1}, + {0x38, 0xf0, 0xf0, 1, 1}, + {0x39, 0x20, 0x20, 0, 0}, + {0x3A, 0x8, 0x8, 0, 0}, + {0x3B, 0x55, 0x55, 1, 1}, + {0x3C, 0, 0, 0, 0}, + {0x3D, 0x44, 0x44, 1, 1}, + {0x3E, 0, 0, 0, 0}, + {0x3F, 0x44, 0x44, 0, 0}, + {0x40, 0xf, 0xf, 1, 1}, + {0x41, 0x6, 0x6, 0, 0}, + {0x42, 0x4, 0x4, 0, 0}, + {0x43, 0x50, 0x50, 1, 1}, + {0x44, 0x8, 0x8, 0, 0}, + {0x45, 0x55, 0x55, 1, 1}, + {0x46, 0, 0, 0, 0}, + {0x47, 0x11, 0x11, 0, 0}, + {0x48, 0, 0, 0, 0}, + {0x49, 0x44, 0x44, 0, 0}, + {0x4A, 0x7, 0x7, 0, 0}, + {0x4B, 0x6, 0x6, 0, 0}, + {0x4C, 0x4, 0x4, 0, 0}, + {0x4D, 0, 0, 0, 0}, + {0x4E, 0, 0, 0, 0}, + {0x4F, 0x26, 0x26, 1, 1}, + {0x50, 0x26, 0x26, 1, 1}, + {0x51, 0xf, 0xf, 1, 1}, + {0x52, 0xf, 0xf, 1, 1}, + {0x53, 0x44, 0x44, 0, 0}, + {0x54, 0, 0, 0, 0}, + {0x55, 0, 0, 0, 0}, + {0x56, 0x8, 0x8, 0, 0}, + {0x57, 0x8, 0x8, 0, 0}, + {0x58, 0x7, 0x7, 0, 0}, + {0x59, 0x22, 0x22, 0, 0}, + {0x5A, 0x22, 0x22, 0, 0}, + {0x5B, 0x2, 0x2, 0, 0}, + {0x5C, 0x2f, 0x2f, 1, 1}, + {0x5D, 0x7, 0x7, 0, 0}, + {0x5E, 0x55, 0x55, 0, 0}, + {0x5F, 0x23, 0x23, 0, 0}, + {0x60, 0x41, 0x41, 0, 0}, + {0x61, 0x1, 0x1, 0, 0}, + {0x62, 0xa, 0xa, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0, 0, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0, 0, 0, 0}, + {0x68, 0, 0, 0, 0}, + {0x69, 0, 0, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0xc, 0xc, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0, 0, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0, 0, 0, 0}, + {0x71, 0, 0, 0, 0}, + {0x72, 0x22, 0x22, 0, 0}, + {0x73, 0x22, 0x22, 0, 0}, + {0x74, 0, 0, 1, 1}, + {0x75, 0xa, 0xa, 0, 0}, + {0x76, 0x1, 0x1, 0, 0}, + {0x77, 0x22, 0x22, 0, 0}, + {0x78, 0x30, 0x30, 0, 0}, + {0x79, 0, 0, 0, 0}, + {0x7A, 0, 0, 0, 0}, + {0x7B, 0, 0, 0, 0}, + {0x7C, 0, 0, 0, 0}, + {0x7D, 0, 0, 0, 0}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0, 0, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0x93, 0, 0, 0, 0}, + {0x94, 0, 0, 0, 0}, + {0xFFFF, 0, 0, 0, 0} +}; + +radio_regs_t regs_SYN_2056_rev5[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0x1, 0x1, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0, 0, 0, 0}, + {0x21, 0, 0, 0, 0}, + {0x22, 0x60, 0x60, 0, 0}, + {0x23, 0x6, 0x6, 0, 0}, + {0x24, 0xc, 0xc, 0, 0}, + {0x25, 0, 0, 0, 0}, + {0x26, 0, 0, 0, 0}, + {0x27, 0, 0, 0, 0}, + {0x28, 0x1, 0x1, 0, 0}, + {0x29, 0, 0, 0, 0}, + {0x2A, 0, 0, 0, 0}, + {0x2B, 0, 0, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0, 0, 0, 0}, + {0x2E, 0, 0, 0, 0}, + {0x2F, 0x1f, 0x1f, 0, 0}, + {0x30, 0x15, 0x15, 0, 0}, + {0x31, 0xf, 0xf, 0, 0}, + {0x32, 0, 0, 0, 0}, + {0x33, 0, 0, 0, 0}, + {0x34, 0, 0, 0, 0}, + {0x35, 0, 0, 0, 0}, + {0x36, 0, 0, 0, 0}, + {0x37, 0, 0, 0, 0}, + {0x38, 0, 0, 0, 0}, + {0x39, 0, 0, 0, 0}, + {0x3A, 0, 0, 0, 0}, + {0x3B, 0, 0, 0, 0}, + {0x3C, 0x13, 0x13, 0, 0}, + {0x3D, 0xf, 0xf, 0, 0}, + {0x3E, 0x18, 0x18, 0, 0}, + {0x3F, 0, 0, 0, 0}, + {0x40, 0, 0, 0, 0}, + {0x41, 0x20, 0x20, 0, 0}, + {0x42, 0x20, 0x20, 0, 0}, + {0x43, 0, 0, 0, 0}, + {0x44, 0x77, 0x77, 0, 0}, + {0x45, 0x7, 0x7, 0, 0}, + {0x46, 0x1, 0x1, 0, 0}, + {0x47, 0x4, 0x4, 0, 0}, + {0x48, 0xf, 0xf, 0, 0}, + {0x49, 0x30, 0x30, 0, 0}, + {0x4A, 0x32, 0x32, 0, 0}, + {0x4B, 0xd, 0xd, 0, 0}, + {0x4C, 0xd, 0xd, 0, 0}, + {0x4D, 0x4, 0x4, 0, 0}, + {0x4E, 0x6, 0x6, 0, 0}, + {0x4F, 0x1, 0x1, 0, 0}, + {0x50, 0x1c, 0x1c, 0, 0}, + {0x51, 0x2, 0x2, 0, 0}, + {0x52, 0x2, 0x2, 0, 0}, + {0x53, 0xf7, 0xf7, 1, 1}, + {0x54, 0xb4, 0xb4, 0, 0}, + {0x55, 0xd2, 0xd2, 0, 0}, + {0x56, 0, 0, 0, 0}, + {0x57, 0, 0, 0, 0}, + {0x58, 0x4, 0x4, 0, 0}, + {0x59, 0x96, 0x96, 0, 0}, + {0x5A, 0x3e, 0x3e, 0, 0}, + {0x5B, 0x3e, 0x3e, 0, 0}, + {0x5C, 0x13, 0x13, 0, 0}, + {0x5D, 0x2, 0x2, 0, 0}, + {0x5E, 0, 0, 0, 0}, + {0x5F, 0x7, 0x7, 0, 0}, + {0x60, 0x7, 0x7, 1, 1}, + {0x61, 0x8, 0x8, 0, 0}, + {0x62, 0x3, 0x3, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0, 0, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0, 0, 0, 0}, + {0x68, 0x40, 0x40, 0, 0}, + {0x69, 0, 0, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0, 0, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0x1, 0x1, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0x60, 0x60, 0, 0}, + {0x71, 0x66, 0x66, 0, 0}, + {0x72, 0xc, 0xc, 0, 0}, + {0x73, 0x66, 0x66, 0, 0}, + {0x74, 0x8f, 0x8f, 1, 1}, + {0x75, 0, 0, 0, 0}, + {0x76, 0xcc, 0xcc, 0, 0}, + {0x77, 0x1, 0x1, 0, 0}, + {0x78, 0x66, 0x66, 0, 0}, + {0x79, 0x66, 0x66, 0, 0}, + {0x7A, 0, 0, 0, 0}, + {0x7B, 0, 0, 0, 0}, + {0x7C, 0, 0, 0, 0}, + {0x7D, 0, 0, 0, 0}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0xff, 0xff, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0x93, 0, 0, 0, 0}, + {0x94, 0, 0, 0, 0}, + {0x95, 0, 0, 0, 0}, + {0x96, 0, 0, 0, 0}, + {0x97, 0, 0, 0, 0}, + {0x98, 0, 0, 0, 0}, + {0x99, 0, 0, 0, 0}, + {0x9A, 0, 0, 0, 0}, + {0x9B, 0, 0, 0, 0}, + {0x9C, 0, 0, 0, 0}, + {0x9D, 0, 0, 0, 0}, + {0x9E, 0, 0, 0, 0}, + {0x9F, 0x6, 0x6, 0, 0}, + {0xA0, 0x66, 0x66, 0, 0}, + {0xA1, 0x66, 0x66, 0, 0}, + {0xA2, 0x66, 0x66, 0, 0}, + {0xA3, 0x66, 0x66, 0, 0}, + {0xA4, 0x66, 0x66, 0, 0}, + {0xA5, 0x66, 0x66, 0, 0}, + {0xA6, 0x66, 0x66, 0, 0}, + {0xA7, 0x66, 0x66, 0, 0}, + {0xA8, 0x66, 0x66, 0, 0}, + {0xA9, 0x66, 0x66, 0, 0}, + {0xAA, 0x66, 0x66, 0, 0}, + {0xAB, 0x66, 0x66, 0, 0}, + {0xAC, 0x66, 0x66, 0, 0}, + {0xAD, 0x66, 0x66, 0, 0}, + {0xAE, 0x66, 0x66, 0, 0}, + {0xAF, 0x66, 0x66, 0, 0}, + {0xB0, 0x66, 0x66, 0, 0}, + {0xB1, 0x66, 0x66, 0, 0}, + {0xB2, 0x66, 0x66, 0, 0}, + {0xB3, 0xa, 0xa, 0, 0}, + {0xB4, 0, 0, 0, 0}, + {0xB5, 0, 0, 0, 0}, + {0xB6, 0, 0, 0, 0}, + {0xFFFF, 0, 0, 0, 0} +}; + +radio_regs_t regs_TX_2056_rev5[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0, 0, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0, 0, 0, 0}, + {0x21, 0x88, 0x88, 0, 0}, + {0x22, 0x88, 0x88, 0, 0}, + {0x23, 0x88, 0x88, 0, 0}, + {0x24, 0x88, 0x88, 0, 0}, + {0x25, 0xc, 0xc, 0, 0}, + {0x26, 0, 0, 0, 0}, + {0x27, 0x3, 0x3, 0, 0}, + {0x28, 0, 0, 0, 0}, + {0x29, 0x3, 0x3, 0, 0}, + {0x2A, 0x37, 0x37, 0, 0}, + {0x2B, 0x3, 0x3, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0, 0, 0, 0}, + {0x2E, 0x1, 0x1, 0, 0}, + {0x2F, 0x1, 0x1, 0, 0}, + {0x30, 0, 0, 0, 0}, + {0x31, 0, 0, 0, 0}, + {0x32, 0, 0, 0, 0}, + {0x33, 0x11, 0x11, 0, 0}, + {0x34, 0x11, 0x11, 0, 0}, + {0x35, 0, 0, 0, 0}, + {0x36, 0, 0, 0, 0}, + {0x37, 0x3, 0x3, 0, 0}, + {0x38, 0xf, 0xf, 0, 0}, + {0x39, 0, 0, 0, 0}, + {0x3A, 0x2d, 0x2d, 0, 0}, + {0x3B, 0, 0, 0, 0}, + {0x3C, 0x6e, 0x6e, 0, 0}, + {0x3D, 0xf0, 0xf0, 1, 1}, + {0x3E, 0, 0, 0, 0}, + {0x3F, 0, 0, 0, 0}, + {0x40, 0, 0, 0, 0}, + {0x41, 0x3, 0x3, 0, 0}, + {0x42, 0x3, 0x3, 0, 0}, + {0x43, 0, 0, 0, 0}, + {0x44, 0x1e, 0x1e, 0, 0}, + {0x45, 0, 0, 0, 0}, + {0x46, 0x6e, 0x6e, 0, 0}, + {0x47, 0xf0, 0xf0, 1, 1}, + {0x48, 0, 0, 0, 0}, + {0x49, 0x2, 0x2, 0, 0}, + {0x4A, 0xff, 0xff, 1, 1}, + {0x4B, 0xc, 0xc, 0, 0}, + {0x4C, 0, 0, 0, 0}, + {0x4D, 0x38, 0x38, 0, 0}, + {0x4E, 0x70, 0x70, 1, 1}, + {0x4F, 0x2, 0x2, 0, 0}, + {0x50, 0x88, 0x88, 0, 0}, + {0x51, 0xc, 0xc, 0, 0}, + {0x52, 0, 0, 0, 0}, + {0x53, 0x8, 0x8, 0, 0}, + {0x54, 0x70, 0x70, 1, 1}, + {0x55, 0x2, 0x2, 0, 0}, + {0x56, 0xff, 0xff, 1, 1}, + {0x57, 0, 0, 0, 0}, + {0x58, 0x83, 0x83, 0, 0}, + {0x59, 0x77, 0x77, 1, 1}, + {0x5A, 0, 0, 0, 0}, + {0x5B, 0x2, 0x2, 0, 0}, + {0x5C, 0x88, 0x88, 0, 0}, + {0x5D, 0, 0, 0, 0}, + {0x5E, 0x8, 0x8, 0, 0}, + {0x5F, 0x77, 0x77, 1, 1}, + {0x60, 0x1, 0x1, 0, 0}, + {0x61, 0, 0, 0, 0}, + {0x62, 0x7, 0x7, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0x7, 0x7, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0, 0, 1, 1}, + {0x68, 0, 0, 0, 0}, + {0x69, 0xa, 0xa, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0, 0, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0, 0, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0, 0, 0, 0}, + {0x71, 0x2, 0x2, 0, 0}, + {0x72, 0, 0, 0, 0}, + {0x73, 0, 0, 0, 0}, + {0x74, 0xe, 0xe, 0, 0}, + {0x75, 0xe, 0xe, 0, 0}, + {0x76, 0xe, 0xe, 0, 0}, + {0x77, 0x13, 0x13, 0, 0}, + {0x78, 0x13, 0x13, 0, 0}, + {0x79, 0x1b, 0x1b, 0, 0}, + {0x7A, 0x1b, 0x1b, 0, 0}, + {0x7B, 0x55, 0x55, 0, 0}, + {0x7C, 0x5b, 0x5b, 0, 0}, + {0x7D, 0, 0, 0, 0}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0, 0, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0x93, 0x70, 0x70, 0, 0}, + {0x94, 0x70, 0x70, 0, 0}, + {0x95, 0x71, 0x71, 1, 1}, + {0x96, 0x71, 0x71, 1, 1}, + {0x97, 0x72, 0x72, 1, 1}, + {0x98, 0x73, 0x73, 1, 1}, + {0x99, 0x74, 0x74, 1, 1}, + {0x9A, 0x75, 0x75, 1, 1}, + {0xFFFF, 0, 0, 0, 0} +}; + +radio_regs_t regs_RX_2056_rev5[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0, 0, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0x3, 0x3, 0, 0}, + {0x21, 0, 0, 0, 0}, + {0x22, 0, 0, 0, 0}, + {0x23, 0x90, 0x90, 0, 0}, + {0x24, 0x55, 0x55, 0, 0}, + {0x25, 0x15, 0x15, 0, 0}, + {0x26, 0x5, 0x5, 0, 0}, + {0x27, 0x15, 0x15, 0, 0}, + {0x28, 0x5, 0x5, 0, 0}, + {0x29, 0x20, 0x20, 0, 0}, + {0x2A, 0x11, 0x11, 0, 0}, + {0x2B, 0x90, 0x90, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0x88, 0x88, 0, 0}, + {0x2E, 0x32, 0x32, 0, 0}, + {0x2F, 0x77, 0x77, 0, 0}, + {0x30, 0x17, 0x17, 1, 1}, + {0x31, 0xff, 0xff, 1, 1}, + {0x32, 0x20, 0x20, 0, 0}, + {0x33, 0, 0, 0, 0}, + {0x34, 0x88, 0x88, 0, 0}, + {0x35, 0x32, 0x32, 0, 0}, + {0x36, 0x77, 0x77, 0, 0}, + {0x37, 0x17, 0x17, 1, 1}, + {0x38, 0xf0, 0xf0, 1, 1}, + {0x39, 0x20, 0x20, 0, 0}, + {0x3A, 0x8, 0x8, 0, 0}, + {0x3B, 0x55, 0x55, 1, 1}, + {0x3C, 0, 0, 0, 0}, + {0x3D, 0x88, 0x88, 1, 1}, + {0x3E, 0, 0, 0, 0}, + {0x3F, 0, 0, 1, 1}, + {0x40, 0x7, 0x7, 1, 1}, + {0x41, 0x6, 0x6, 0, 0}, + {0x42, 0x4, 0x4, 0, 0}, + {0x43, 0, 0, 0, 0}, + {0x44, 0x8, 0x8, 0, 0}, + {0x45, 0x55, 0x55, 1, 1}, + {0x46, 0, 0, 0, 0}, + {0x47, 0x11, 0x11, 0, 0}, + {0x48, 0, 0, 0, 0}, + {0x49, 0, 0, 1, 1}, + {0x4A, 0x7, 0x7, 0, 0}, + {0x4B, 0x6, 0x6, 0, 0}, + {0x4C, 0x4, 0x4, 0, 0}, + {0x4D, 0, 0, 0, 0}, + {0x4E, 0, 0, 0, 0}, + {0x4F, 0x26, 0x26, 1, 1}, + {0x50, 0x26, 0x26, 1, 1}, + {0x51, 0xf, 0xf, 1, 1}, + {0x52, 0xf, 0xf, 1, 1}, + {0x53, 0x44, 0x44, 0, 0}, + {0x54, 0, 0, 0, 0}, + {0x55, 0, 0, 0, 0}, + {0x56, 0x8, 0x8, 0, 0}, + {0x57, 0x8, 0x8, 0, 0}, + {0x58, 0x7, 0x7, 0, 0}, + {0x59, 0x22, 0x22, 0, 0}, + {0x5A, 0x22, 0x22, 0, 0}, + {0x5B, 0x2, 0x2, 0, 0}, + {0x5C, 0x4, 0x4, 1, 1}, + {0x5D, 0x7, 0x7, 0, 0}, + {0x5E, 0x55, 0x55, 0, 0}, + {0x5F, 0x23, 0x23, 0, 0}, + {0x60, 0x41, 0x41, 0, 0}, + {0x61, 0x1, 0x1, 0, 0}, + {0x62, 0xa, 0xa, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0, 0, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0, 0, 0, 0}, + {0x68, 0, 0, 0, 0}, + {0x69, 0, 0, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0xc, 0xc, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0, 0, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0, 0, 0, 0}, + {0x71, 0, 0, 0, 0}, + {0x72, 0x22, 0x22, 0, 0}, + {0x73, 0x22, 0x22, 0, 0}, + {0x74, 0, 0, 1, 1}, + {0x75, 0xa, 0xa, 0, 0}, + {0x76, 0x1, 0x1, 0, 0}, + {0x77, 0x22, 0x22, 0, 0}, + {0x78, 0x30, 0x30, 0, 0}, + {0x79, 0, 0, 0, 0}, + {0x7A, 0, 0, 0, 0}, + {0x7B, 0, 0, 0, 0}, + {0x7C, 0, 0, 0, 0}, + {0x7D, 0, 0, 0, 0}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0, 0, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0x93, 0, 0, 0, 0}, + {0x94, 0, 0, 0, 0}, + {0xFFFF, 0, 0, 0, 0} +}; + +radio_regs_t regs_SYN_2056_rev6[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0x1, 0x1, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0, 0, 0, 0}, + {0x21, 0, 0, 0, 0}, + {0x22, 0x60, 0x60, 0, 0}, + {0x23, 0x6, 0x6, 0, 0}, + {0x24, 0xc, 0xc, 0, 0}, + {0x25, 0, 0, 0, 0}, + {0x26, 0, 0, 0, 0}, + {0x27, 0, 0, 0, 0}, + {0x28, 0x1, 0x1, 0, 0}, + {0x29, 0, 0, 0, 0}, + {0x2A, 0, 0, 0, 0}, + {0x2B, 0, 0, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0, 0, 0, 0}, + {0x2E, 0, 0, 0, 0}, + {0x2F, 0x1f, 0x1f, 0, 0}, + {0x30, 0x15, 0x15, 0, 0}, + {0x31, 0xf, 0xf, 0, 0}, + {0x32, 0, 0, 0, 0}, + {0x33, 0, 0, 0, 0}, + {0x34, 0, 0, 0, 0}, + {0x35, 0, 0, 0, 0}, + {0x36, 0, 0, 0, 0}, + {0x37, 0, 0, 0, 0}, + {0x38, 0, 0, 0, 0}, + {0x39, 0, 0, 0, 0}, + {0x3A, 0, 0, 0, 0}, + {0x3B, 0, 0, 0, 0}, + {0x3C, 0x13, 0x13, 0, 0}, + {0x3D, 0xf, 0xf, 0, 0}, + {0x3E, 0x18, 0x18, 0, 0}, + {0x3F, 0, 0, 0, 0}, + {0x40, 0, 0, 0, 0}, + {0x41, 0x20, 0x20, 0, 0}, + {0x42, 0x20, 0x20, 0, 0}, + {0x43, 0, 0, 0, 0}, + {0x44, 0x77, 0x77, 0, 0}, + {0x45, 0x7, 0x7, 0, 0}, + {0x46, 0x1, 0x1, 0, 0}, + {0x47, 0x4, 0x4, 0, 0}, + {0x48, 0xf, 0xf, 0, 0}, + {0x49, 0x30, 0x30, 0, 0}, + {0x4A, 0x32, 0x32, 0, 0}, + {0x4B, 0xd, 0xd, 0, 0}, + {0x4C, 0xd, 0xd, 0, 0}, + {0x4D, 0x4, 0x4, 0, 0}, + {0x4E, 0x6, 0x6, 0, 0}, + {0x4F, 0x1, 0x1, 0, 0}, + {0x50, 0x1c, 0x1c, 0, 0}, + {0x51, 0x2, 0x2, 0, 0}, + {0x52, 0x2, 0x2, 0, 0}, + {0x53, 0xf7, 0xf7, 1, 1}, + {0x54, 0xb4, 0xb4, 0, 0}, + {0x55, 0xd2, 0xd2, 0, 0}, + {0x56, 0, 0, 0, 0}, + {0x57, 0, 0, 0, 0}, + {0x58, 0x4, 0x4, 0, 0}, + {0x59, 0x96, 0x96, 0, 0}, + {0x5A, 0x3e, 0x3e, 0, 0}, + {0x5B, 0x3e, 0x3e, 0, 0}, + {0x5C, 0x13, 0x13, 0, 0}, + {0x5D, 0x2, 0x2, 0, 0}, + {0x5E, 0, 0, 0, 0}, + {0x5F, 0x7, 0x7, 0, 0}, + {0x60, 0x7, 0x7, 1, 1}, + {0x61, 0x8, 0x8, 0, 0}, + {0x62, 0x3, 0x3, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0, 0, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0, 0, 0, 0}, + {0x68, 0x40, 0x40, 0, 0}, + {0x69, 0, 0, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0, 0, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0x1, 0x1, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0x60, 0x60, 0, 0}, + {0x71, 0x66, 0x66, 0, 0}, + {0x72, 0xc, 0xc, 0, 0}, + {0x73, 0x66, 0x66, 0, 0}, + {0x74, 0x8f, 0x8f, 1, 1}, + {0x75, 0, 0, 0, 0}, + {0x76, 0xcc, 0xcc, 0, 0}, + {0x77, 0x1, 0x1, 0, 0}, + {0x78, 0x66, 0x66, 0, 0}, + {0x79, 0x66, 0x66, 0, 0}, + {0x7A, 0, 0, 0, 0}, + {0x7B, 0, 0, 0, 0}, + {0x7C, 0, 0, 0, 0}, + {0x7D, 0, 0, 0, 0}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0xff, 0xff, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0x93, 0, 0, 0, 0}, + {0x94, 0, 0, 0, 0}, + {0x95, 0, 0, 0, 0}, + {0x96, 0, 0, 0, 0}, + {0x97, 0, 0, 0, 0}, + {0x98, 0, 0, 0, 0}, + {0x99, 0, 0, 0, 0}, + {0x9A, 0, 0, 0, 0}, + {0x9B, 0, 0, 0, 0}, + {0x9C, 0, 0, 0, 0}, + {0x9D, 0, 0, 0, 0}, + {0x9E, 0, 0, 0, 0}, + {0x9F, 0x6, 0x6, 0, 0}, + {0xA0, 0x66, 0x66, 0, 0}, + {0xA1, 0x66, 0x66, 0, 0}, + {0xA2, 0x66, 0x66, 0, 0}, + {0xA3, 0x66, 0x66, 0, 0}, + {0xA4, 0x66, 0x66, 0, 0}, + {0xA5, 0x66, 0x66, 0, 0}, + {0xA6, 0x66, 0x66, 0, 0}, + {0xA7, 0x66, 0x66, 0, 0}, + {0xA8, 0x66, 0x66, 0, 0}, + {0xA9, 0x66, 0x66, 0, 0}, + {0xAA, 0x66, 0x66, 0, 0}, + {0xAB, 0x66, 0x66, 0, 0}, + {0xAC, 0x66, 0x66, 0, 0}, + {0xAD, 0x66, 0x66, 0, 0}, + {0xAE, 0x66, 0x66, 0, 0}, + {0xAF, 0x66, 0x66, 0, 0}, + {0xB0, 0x66, 0x66, 0, 0}, + {0xB1, 0x66, 0x66, 0, 0}, + {0xB2, 0x66, 0x66, 0, 0}, + {0xB3, 0xa, 0xa, 0, 0}, + {0xB4, 0, 0, 0, 0}, + {0xB5, 0, 0, 0, 0}, + {0xB6, 0, 0, 0, 0}, + {0xFFFF, 0, 0, 0, 0} +}; + +radio_regs_t regs_TX_2056_rev6[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0, 0, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0, 0, 0, 0}, + {0x21, 0x88, 0x88, 0, 0}, + {0x22, 0x88, 0x88, 0, 0}, + {0x23, 0x88, 0x88, 0, 0}, + {0x24, 0x88, 0x88, 0, 0}, + {0x25, 0xc, 0xc, 0, 0}, + {0x26, 0, 0, 0, 0}, + {0x27, 0x3, 0x3, 0, 0}, + {0x28, 0, 0, 0, 0}, + {0x29, 0x3, 0x3, 0, 0}, + {0x2A, 0x37, 0x37, 0, 0}, + {0x2B, 0x3, 0x3, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0, 0, 0, 0}, + {0x2E, 0x1, 0x1, 0, 0}, + {0x2F, 0x1, 0x1, 0, 0}, + {0x30, 0, 0, 0, 0}, + {0x31, 0, 0, 0, 0}, + {0x32, 0, 0, 0, 0}, + {0x33, 0x11, 0x11, 0, 0}, + {0x34, 0xee, 0xee, 1, 1}, + {0x35, 0, 0, 0, 0}, + {0x36, 0, 0, 0, 0}, + {0x37, 0x3, 0x3, 0, 0}, + {0x38, 0x50, 0x50, 1, 1}, + {0x39, 0, 0, 0, 0}, + {0x3A, 0x50, 0x50, 1, 1}, + {0x3B, 0, 0, 0, 0}, + {0x3C, 0x6e, 0x6e, 0, 0}, + {0x3D, 0xf0, 0xf0, 1, 1}, + {0x3E, 0, 0, 0, 0}, + {0x3F, 0, 0, 0, 0}, + {0x40, 0, 0, 0, 0}, + {0x41, 0x3, 0x3, 0, 0}, + {0x42, 0x3, 0x3, 0, 0}, + {0x43, 0, 0, 0, 0}, + {0x44, 0x1e, 0x1e, 0, 0}, + {0x45, 0, 0, 0, 0}, + {0x46, 0x6e, 0x6e, 0, 0}, + {0x47, 0xf0, 0xf0, 1, 1}, + {0x48, 0, 0, 0, 0}, + {0x49, 0x2, 0x2, 0, 0}, + {0x4A, 0xff, 0xff, 1, 1}, + {0x4B, 0xc, 0xc, 0, 0}, + {0x4C, 0, 0, 0, 0}, + {0x4D, 0x38, 0x38, 0, 0}, + {0x4E, 0x70, 0x70, 1, 1}, + {0x4F, 0x2, 0x2, 0, 0}, + {0x50, 0x88, 0x88, 0, 0}, + {0x51, 0xc, 0xc, 0, 0}, + {0x52, 0, 0, 0, 0}, + {0x53, 0x8, 0x8, 0, 0}, + {0x54, 0x70, 0x70, 1, 1}, + {0x55, 0x2, 0x2, 0, 0}, + {0x56, 0xff, 0xff, 1, 1}, + {0x57, 0, 0, 0, 0}, + {0x58, 0x83, 0x83, 0, 0}, + {0x59, 0x77, 0x77, 1, 1}, + {0x5A, 0, 0, 0, 0}, + {0x5B, 0x2, 0x2, 0, 0}, + {0x5C, 0x88, 0x88, 0, 0}, + {0x5D, 0, 0, 0, 0}, + {0x5E, 0x8, 0x8, 0, 0}, + {0x5F, 0x77, 0x77, 1, 1}, + {0x60, 0x1, 0x1, 0, 0}, + {0x61, 0, 0, 0, 0}, + {0x62, 0x7, 0x7, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0x7, 0x7, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0, 0, 1, 1}, + {0x68, 0, 0, 0, 0}, + {0x69, 0xa, 0xa, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0, 0, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0, 0, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0, 0, 0, 0}, + {0x71, 0x2, 0x2, 0, 0}, + {0x72, 0, 0, 0, 0}, + {0x73, 0, 0, 0, 0}, + {0x74, 0xe, 0xe, 0, 0}, + {0x75, 0xe, 0xe, 0, 0}, + {0x76, 0xe, 0xe, 0, 0}, + {0x77, 0x13, 0x13, 0, 0}, + {0x78, 0x13, 0x13, 0, 0}, + {0x79, 0x1b, 0x1b, 0, 0}, + {0x7A, 0x1b, 0x1b, 0, 0}, + {0x7B, 0x55, 0x55, 0, 0}, + {0x7C, 0x5b, 0x5b, 0, 0}, + {0x7D, 0x30, 0x30, 1, 1}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0, 0, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0x93, 0x70, 0x70, 0, 0}, + {0x94, 0x70, 0x70, 0, 0}, + {0x95, 0x70, 0x70, 0, 0}, + {0x96, 0x70, 0x70, 0, 0}, + {0x97, 0x70, 0x70, 0, 0}, + {0x98, 0x70, 0x70, 0, 0}, + {0x99, 0x70, 0x70, 0, 0}, + {0x9A, 0x70, 0x70, 0, 0}, + {0xFFFF, 0, 0, 0, 0} +}; + +radio_regs_t regs_RX_2056_rev6[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0, 0, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0x3, 0x3, 0, 0}, + {0x21, 0, 0, 0, 0}, + {0x22, 0, 0, 0, 0}, + {0x23, 0x90, 0x90, 0, 0}, + {0x24, 0x55, 0x55, 0, 0}, + {0x25, 0x15, 0x15, 0, 0}, + {0x26, 0x5, 0x5, 0, 0}, + {0x27, 0x15, 0x15, 0, 0}, + {0x28, 0x5, 0x5, 0, 0}, + {0x29, 0x20, 0x20, 0, 0}, + {0x2A, 0x11, 0x11, 0, 0}, + {0x2B, 0x90, 0x90, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0x88, 0x88, 0, 0}, + {0x2E, 0x32, 0x32, 0, 0}, + {0x2F, 0x77, 0x77, 0, 0}, + {0x30, 0x17, 0x17, 1, 1}, + {0x31, 0xff, 0xff, 1, 1}, + {0x32, 0x20, 0x20, 0, 0}, + {0x33, 0, 0, 0, 0}, + {0x34, 0x88, 0x88, 0, 0}, + {0x35, 0x32, 0x32, 0, 0}, + {0x36, 0x77, 0x77, 0, 0}, + {0x37, 0x17, 0x17, 1, 1}, + {0x38, 0xf0, 0xf0, 1, 1}, + {0x39, 0x20, 0x20, 0, 0}, + {0x3A, 0x8, 0x8, 0, 0}, + {0x3B, 0x55, 0x55, 1, 1}, + {0x3C, 0, 0, 0, 0}, + {0x3D, 0x88, 0x88, 1, 1}, + {0x3E, 0, 0, 0, 0}, + {0x3F, 0x44, 0x44, 0, 0}, + {0x40, 0x7, 0x7, 1, 1}, + {0x41, 0x6, 0x6, 0, 0}, + {0x42, 0x4, 0x4, 0, 0}, + {0x43, 0, 0, 0, 0}, + {0x44, 0x8, 0x8, 0, 0}, + {0x45, 0x55, 0x55, 1, 1}, + {0x46, 0, 0, 0, 0}, + {0x47, 0x11, 0x11, 0, 0}, + {0x48, 0, 0, 0, 0}, + {0x49, 0x44, 0x44, 0, 0}, + {0x4A, 0x7, 0x7, 0, 0}, + {0x4B, 0x6, 0x6, 0, 0}, + {0x4C, 0x4, 0x4, 0, 0}, + {0x4D, 0, 0, 0, 0}, + {0x4E, 0, 0, 0, 0}, + {0x4F, 0x26, 0x26, 1, 1}, + {0x50, 0x26, 0x26, 1, 1}, + {0x51, 0xf, 0xf, 1, 1}, + {0x52, 0xf, 0xf, 1, 1}, + {0x53, 0x44, 0x44, 0, 0}, + {0x54, 0, 0, 0, 0}, + {0x55, 0, 0, 0, 0}, + {0x56, 0x8, 0x8, 0, 0}, + {0x57, 0x8, 0x8, 0, 0}, + {0x58, 0x7, 0x7, 0, 0}, + {0x59, 0x22, 0x22, 0, 0}, + {0x5A, 0x22, 0x22, 0, 0}, + {0x5B, 0x2, 0x2, 0, 0}, + {0x5C, 0x4, 0x4, 1, 1}, + {0x5D, 0x7, 0x7, 0, 0}, + {0x5E, 0x55, 0x55, 0, 0}, + {0x5F, 0x23, 0x23, 0, 0}, + {0x60, 0x41, 0x41, 0, 0}, + {0x61, 0x1, 0x1, 0, 0}, + {0x62, 0xa, 0xa, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0, 0, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0, 0, 0, 0}, + {0x68, 0, 0, 0, 0}, + {0x69, 0, 0, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0xc, 0xc, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0, 0, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0, 0, 0, 0}, + {0x71, 0, 0, 0, 0}, + {0x72, 0x22, 0x22, 0, 0}, + {0x73, 0x22, 0x22, 0, 0}, + {0x74, 0, 0, 1, 1}, + {0x75, 0xa, 0xa, 0, 0}, + {0x76, 0x1, 0x1, 0, 0}, + {0x77, 0x22, 0x22, 0, 0}, + {0x78, 0x30, 0x30, 0, 0}, + {0x79, 0, 0, 0, 0}, + {0x7A, 0, 0, 0, 0}, + {0x7B, 0, 0, 0, 0}, + {0x7C, 0, 0, 0, 0}, + {0x7D, 0x5, 0x5, 1, 1}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0, 0, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0x93, 0, 0, 0, 0}, + {0x94, 0, 0, 0, 0}, + {0xFFFF, 0, 0, 0, 0} +}; + +radio_regs_t regs_SYN_2056_rev7[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0x1, 0x1, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0, 0, 0, 0}, + {0x21, 0, 0, 0, 0}, + {0x22, 0x60, 0x60, 0, 0}, + {0x23, 0x6, 0x6, 0, 0}, + {0x24, 0xc, 0xc, 0, 0}, + {0x25, 0, 0, 0, 0}, + {0x26, 0, 0, 0, 0}, + {0x27, 0, 0, 0, 0}, + {0x28, 0x1, 0x1, 0, 0}, + {0x29, 0, 0, 0, 0}, + {0x2A, 0, 0, 0, 0}, + {0x2B, 0, 0, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0, 0, 0, 0}, + {0x2E, 0, 0, 0, 0}, + {0x2F, 0x1f, 0x1f, 0, 0}, + {0x30, 0x15, 0x15, 0, 0}, + {0x31, 0xf, 0xf, 0, 0}, + {0x32, 0, 0, 0, 0}, + {0x33, 0, 0, 0, 0}, + {0x34, 0, 0, 0, 0}, + {0x35, 0, 0, 0, 0}, + {0x36, 0, 0, 0, 0}, + {0x37, 0, 0, 0, 0}, + {0x38, 0, 0, 0, 0}, + {0x39, 0, 0, 0, 0}, + {0x3A, 0, 0, 0, 0}, + {0x3B, 0, 0, 0, 0}, + {0x3C, 0x13, 0x13, 0, 0}, + {0x3D, 0xf, 0xf, 0, 0}, + {0x3E, 0x18, 0x18, 0, 0}, + {0x3F, 0, 0, 0, 0}, + {0x40, 0, 0, 0, 0}, + {0x41, 0x20, 0x20, 0, 0}, + {0x42, 0x20, 0x20, 0, 0}, + {0x43, 0, 0, 0, 0}, + {0x44, 0x77, 0x77, 0, 0}, + {0x45, 0x7, 0x7, 0, 0}, + {0x46, 0x1, 0x1, 0, 0}, + {0x47, 0x4, 0x4, 0, 0}, + {0x48, 0xf, 0xf, 0, 0}, + {0x49, 0x30, 0x30, 0, 0}, + {0x4A, 0x32, 0x32, 0, 0}, + {0x4B, 0xd, 0xd, 0, 0}, + {0x4C, 0xd, 0xd, 0, 0}, + {0x4D, 0x4, 0x4, 0, 0}, + {0x4E, 0x6, 0x6, 0, 0}, + {0x4F, 0x1, 0x1, 0, 0}, + {0x50, 0x1c, 0x1c, 0, 0}, + {0x51, 0x2, 0x2, 0, 0}, + {0x52, 0x2, 0x2, 0, 0}, + {0x53, 0xf7, 0xf7, 1, 1}, + {0x54, 0xb4, 0xb4, 0, 0}, + {0x55, 0xd2, 0xd2, 0, 0}, + {0x56, 0, 0, 0, 0}, + {0x57, 0, 0, 0, 0}, + {0x58, 0x4, 0x4, 0, 0}, + {0x59, 0x96, 0x96, 0, 0}, + {0x5A, 0x3e, 0x3e, 0, 0}, + {0x5B, 0x3e, 0x3e, 0, 0}, + {0x5C, 0x13, 0x13, 0, 0}, + {0x5D, 0x2, 0x2, 0, 0}, + {0x5E, 0, 0, 0, 0}, + {0x5F, 0x7, 0x7, 0, 0}, + {0x60, 0x7, 0x7, 1, 1}, + {0x61, 0x8, 0x8, 0, 0}, + {0x62, 0x3, 0x3, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0, 0, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0, 0, 0, 0}, + {0x68, 0x40, 0x40, 0, 0}, + {0x69, 0, 0, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0, 0, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0x1, 0x1, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0x60, 0x60, 0, 0}, + {0x71, 0x66, 0x66, 0, 0}, + {0x72, 0xc, 0xc, 0, 0}, + {0x73, 0x66, 0x66, 0, 0}, + {0x74, 0x8f, 0x8f, 1, 1}, + {0x75, 0, 0, 0, 0}, + {0x76, 0xcc, 0xcc, 0, 0}, + {0x77, 0x1, 0x1, 0, 0}, + {0x78, 0x66, 0x66, 0, 0}, + {0x79, 0x66, 0x66, 0, 0}, + {0x7A, 0, 0, 0, 0}, + {0x7B, 0, 0, 0, 0}, + {0x7C, 0, 0, 0, 0}, + {0x7D, 0, 0, 0, 0}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0xff, 0xff, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0x93, 0, 0, 0, 0}, + {0x94, 0, 0, 0, 0}, + {0x95, 0, 0, 0, 0}, + {0x96, 0, 0, 0, 0}, + {0x97, 0, 0, 0, 0}, + {0x98, 0, 0, 0, 0}, + {0x99, 0, 0, 0, 0}, + {0x9A, 0, 0, 0, 0}, + {0x9B, 0, 0, 0, 0}, + {0x9C, 0, 0, 0, 0}, + {0x9D, 0, 0, 0, 0}, + {0x9E, 0, 0, 0, 0}, + {0x9F, 0x6, 0x6, 0, 0}, + {0xA0, 0x66, 0x66, 0, 0}, + {0xA1, 0x66, 0x66, 0, 0}, + {0xA2, 0x66, 0x66, 0, 0}, + {0xA3, 0x66, 0x66, 0, 0}, + {0xA4, 0x66, 0x66, 0, 0}, + {0xA5, 0x66, 0x66, 0, 0}, + {0xA6, 0x66, 0x66, 0, 0}, + {0xA7, 0x66, 0x66, 0, 0}, + {0xA8, 0x66, 0x66, 0, 0}, + {0xA9, 0x66, 0x66, 0, 0}, + {0xAA, 0x66, 0x66, 0, 0}, + {0xAB, 0x66, 0x66, 0, 0}, + {0xAC, 0x66, 0x66, 0, 0}, + {0xAD, 0x66, 0x66, 0, 0}, + {0xAE, 0x66, 0x66, 0, 0}, + {0xAF, 0x66, 0x66, 0, 0}, + {0xB0, 0x66, 0x66, 0, 0}, + {0xB1, 0x66, 0x66, 0, 0}, + {0xB2, 0x66, 0x66, 0, 0}, + {0xB3, 0xa, 0xa, 0, 0}, + {0xB4, 0, 0, 0, 0}, + {0xB5, 0, 0, 0, 0}, + {0xB6, 0, 0, 0, 0}, + {0xFFFF, 0, 0, 0, 0}, +}; + +radio_regs_t regs_TX_2056_rev7[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0, 0, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0, 0, 0, 0}, + {0x21, 0x88, 0x88, 0, 0}, + {0x22, 0x88, 0x88, 0, 0}, + {0x23, 0x88, 0x88, 0, 0}, + {0x24, 0x88, 0x88, 0, 0}, + {0x25, 0xc, 0xc, 0, 0}, + {0x26, 0, 0, 0, 0}, + {0x27, 0x3, 0x3, 0, 0}, + {0x28, 0, 0, 0, 0}, + {0x29, 0x3, 0x3, 0, 0}, + {0x2A, 0x37, 0x37, 0, 0}, + {0x2B, 0x3, 0x3, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0, 0, 0, 0}, + {0x2E, 0x1, 0x1, 0, 0}, + {0x2F, 0x1, 0x1, 0, 0}, + {0x30, 0, 0, 0, 0}, + {0x31, 0, 0, 0, 0}, + {0x32, 0, 0, 0, 0}, + {0x33, 0x11, 0x11, 0, 0}, + {0x34, 0xee, 0xee, 1, 1}, + {0x35, 0, 0, 0, 0}, + {0x36, 0, 0, 0, 0}, + {0x37, 0x3, 0x3, 0, 0}, + {0x38, 0x50, 0x50, 1, 1}, + {0x39, 0, 0, 0, 0}, + {0x3A, 0x50, 0x50, 1, 1}, + {0x3B, 0, 0, 0, 0}, + {0x3C, 0x6e, 0x6e, 0, 0}, + {0x3D, 0xf0, 0xf0, 1, 1}, + {0x3E, 0, 0, 0, 0}, + {0x3F, 0, 0, 0, 0}, + {0x40, 0, 0, 0, 0}, + {0x41, 0x3, 0x3, 0, 0}, + {0x42, 0x3, 0x3, 0, 0}, + {0x43, 0, 0, 0, 0}, + {0x44, 0x1e, 0x1e, 0, 0}, + {0x45, 0, 0, 0, 0}, + {0x46, 0x6e, 0x6e, 0, 0}, + {0x47, 0xf0, 0xf0, 1, 1}, + {0x48, 0, 0, 0, 0}, + {0x49, 0x2, 0x2, 0, 0}, + {0x4A, 0xff, 0xff, 1, 1}, + {0x4B, 0xc, 0xc, 0, 0}, + {0x4C, 0, 0, 0, 0}, + {0x4D, 0x38, 0x38, 0, 0}, + {0x4E, 0x70, 0x70, 1, 1}, + {0x4F, 0x2, 0x2, 0, 0}, + {0x50, 0x88, 0x88, 0, 0}, + {0x51, 0xc, 0xc, 0, 0}, + {0x52, 0, 0, 0, 0}, + {0x53, 0x8, 0x8, 0, 0}, + {0x54, 0x70, 0x70, 1, 1}, + {0x55, 0x2, 0x2, 0, 0}, + {0x56, 0xff, 0xff, 1, 1}, + {0x57, 0, 0, 0, 0}, + {0x58, 0x83, 0x83, 0, 0}, + {0x59, 0x77, 0x77, 1, 1}, + {0x5A, 0, 0, 0, 0}, + {0x5B, 0x2, 0x2, 0, 0}, + {0x5C, 0x88, 0x88, 0, 0}, + {0x5D, 0, 0, 0, 0}, + {0x5E, 0x8, 0x8, 0, 0}, + {0x5F, 0x77, 0x77, 1, 1}, + {0x60, 0x1, 0x1, 0, 0}, + {0x61, 0, 0, 0, 0}, + {0x62, 0x7, 0x7, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0x7, 0x7, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0, 0, 1, 1}, + {0x68, 0, 0, 0, 0}, + {0x69, 0xa, 0xa, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0, 0, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0, 0, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0, 0, 0, 0}, + {0x71, 0x2, 0x2, 0, 0}, + {0x72, 0, 0, 0, 0}, + {0x73, 0, 0, 0, 0}, + {0x74, 0xe, 0xe, 0, 0}, + {0x75, 0xe, 0xe, 0, 0}, + {0x76, 0xe, 0xe, 0, 0}, + {0x77, 0x13, 0x13, 0, 0}, + {0x78, 0x13, 0x13, 0, 0}, + {0x79, 0x1b, 0x1b, 0, 0}, + {0x7A, 0x1b, 0x1b, 0, 0}, + {0x7B, 0x55, 0x55, 0, 0}, + {0x7C, 0x5b, 0x5b, 0, 0}, + {0x7D, 0x30, 0x30, 1, 1}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0, 0, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0x93, 0x70, 0x70, 0, 0}, + {0x94, 0x70, 0x70, 0, 0}, + {0x95, 0x71, 0x71, 1, 1}, + {0x96, 0x71, 0x71, 1, 1}, + {0x97, 0x72, 0x72, 1, 1}, + {0x98, 0x73, 0x73, 1, 1}, + {0x99, 0x74, 0x74, 1, 1}, + {0x9A, 0x75, 0x75, 1, 1}, + {0xFFFF, 0, 0, 0, 0}, +}; + +radio_regs_t regs_RX_2056_rev7[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0, 0, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0x3, 0x3, 0, 0}, + {0x21, 0, 0, 0, 0}, + {0x22, 0, 0, 0, 0}, + {0x23, 0x90, 0x90, 0, 0}, + {0x24, 0x55, 0x55, 0, 0}, + {0x25, 0x15, 0x15, 0, 0}, + {0x26, 0x5, 0x5, 0, 0}, + {0x27, 0x15, 0x15, 0, 0}, + {0x28, 0x5, 0x5, 0, 0}, + {0x29, 0x20, 0x20, 0, 0}, + {0x2A, 0x11, 0x11, 0, 0}, + {0x2B, 0x90, 0x90, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0x88, 0x88, 0, 0}, + {0x2E, 0x32, 0x32, 0, 0}, + {0x2F, 0x77, 0x77, 0, 0}, + {0x30, 0x17, 0x17, 1, 1}, + {0x31, 0xff, 0xff, 1, 1}, + {0x32, 0x20, 0x20, 0, 0}, + {0x33, 0, 0, 0, 0}, + {0x34, 0x88, 0x88, 0, 0}, + {0x35, 0x32, 0x32, 0, 0}, + {0x36, 0x77, 0x77, 0, 0}, + {0x37, 0x17, 0x17, 1, 1}, + {0x38, 0xf0, 0xf0, 1, 1}, + {0x39, 0x20, 0x20, 0, 0}, + {0x3A, 0x8, 0x8, 0, 0}, + {0x3B, 0x55, 0x55, 1, 1}, + {0x3C, 0, 0, 0, 0}, + {0x3D, 0x88, 0x88, 1, 1}, + {0x3E, 0, 0, 0, 0}, + {0x3F, 0, 0, 1, 1}, + {0x40, 0x7, 0x7, 1, 1}, + {0x41, 0x6, 0x6, 0, 0}, + {0x42, 0x4, 0x4, 0, 0}, + {0x43, 0, 0, 0, 0}, + {0x44, 0x8, 0x8, 0, 0}, + {0x45, 0x55, 0x55, 1, 1}, + {0x46, 0, 0, 0, 0}, + {0x47, 0x11, 0x11, 0, 0}, + {0x48, 0, 0, 0, 0}, + {0x49, 0, 0, 1, 1}, + {0x4A, 0x7, 0x7, 0, 0}, + {0x4B, 0x6, 0x6, 0, 0}, + {0x4C, 0x4, 0x4, 0, 0}, + {0x4D, 0, 0, 0, 0}, + {0x4E, 0, 0, 0, 0}, + {0x4F, 0x26, 0x26, 1, 1}, + {0x50, 0x26, 0x26, 1, 1}, + {0x51, 0xf, 0xf, 1, 1}, + {0x52, 0xf, 0xf, 1, 1}, + {0x53, 0x44, 0x44, 0, 0}, + {0x54, 0, 0, 0, 0}, + {0x55, 0, 0, 0, 0}, + {0x56, 0x8, 0x8, 0, 0}, + {0x57, 0x8, 0x8, 0, 0}, + {0x58, 0x7, 0x7, 0, 0}, + {0x59, 0x22, 0x22, 0, 0}, + {0x5A, 0x22, 0x22, 0, 0}, + {0x5B, 0x2, 0x2, 0, 0}, + {0x5C, 0x4, 0x4, 1, 1}, + {0x5D, 0x7, 0x7, 0, 0}, + {0x5E, 0x55, 0x55, 0, 0}, + {0x5F, 0x23, 0x23, 0, 0}, + {0x60, 0x41, 0x41, 0, 0}, + {0x61, 0x1, 0x1, 0, 0}, + {0x62, 0xa, 0xa, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0, 0, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0, 0, 0, 0}, + {0x68, 0, 0, 0, 0}, + {0x69, 0, 0, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0xc, 0xc, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0, 0, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0, 0, 0, 0}, + {0x71, 0, 0, 0, 0}, + {0x72, 0x22, 0x22, 0, 0}, + {0x73, 0x22, 0x22, 0, 0}, + {0x74, 0, 0, 1, 1}, + {0x75, 0xa, 0xa, 0, 0}, + {0x76, 0x1, 0x1, 0, 0}, + {0x77, 0x22, 0x22, 0, 0}, + {0x78, 0x30, 0x30, 0, 0}, + {0x79, 0, 0, 0, 0}, + {0x7A, 0, 0, 0, 0}, + {0x7B, 0, 0, 0, 0}, + {0x7C, 0, 0, 0, 0}, + {0x7D, 0, 0, 0, 0}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0, 0, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0x93, 0, 0, 0, 0}, + {0x94, 0, 0, 0, 0}, + {0xFFFF, 0, 0, 0, 0}, +}; + +radio_regs_t regs_SYN_2056_rev8[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0x1, 0x1, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0, 0, 0, 0}, + {0x21, 0, 0, 0, 0}, + {0x22, 0x60, 0x60, 0, 0}, + {0x23, 0x6, 0x6, 0, 0}, + {0x24, 0xc, 0xc, 0, 0}, + {0x25, 0, 0, 0, 0}, + {0x26, 0, 0, 0, 0}, + {0x27, 0, 0, 0, 0}, + {0x28, 0x1, 0x1, 0, 0}, + {0x29, 0, 0, 0, 0}, + {0x2A, 0, 0, 0, 0}, + {0x2B, 0, 0, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0, 0, 0, 0}, + {0x2E, 0, 0, 0, 0}, + {0x2F, 0x1f, 0x1f, 0, 0}, + {0x30, 0x15, 0x15, 0, 0}, + {0x31, 0xf, 0xf, 0, 0}, + {0x32, 0, 0, 0, 0}, + {0x33, 0, 0, 0, 0}, + {0x34, 0, 0, 0, 0}, + {0x35, 0, 0, 0, 0}, + {0x36, 0, 0, 0, 0}, + {0x37, 0, 0, 0, 0}, + {0x38, 0, 0, 0, 0}, + {0x39, 0, 0, 0, 0}, + {0x3A, 0, 0, 0, 0}, + {0x3B, 0, 0, 0, 0}, + {0x3C, 0x13, 0x13, 0, 0}, + {0x3D, 0xf, 0xf, 0, 0}, + {0x3E, 0x18, 0x18, 0, 0}, + {0x3F, 0, 0, 0, 0}, + {0x40, 0, 0, 0, 0}, + {0x41, 0x20, 0x20, 0, 0}, + {0x42, 0x20, 0x20, 0, 0}, + {0x43, 0, 0, 0, 0}, + {0x44, 0x77, 0x77, 0, 0}, + {0x45, 0x7, 0x7, 0, 0}, + {0x46, 0x1, 0x1, 0, 0}, + {0x47, 0x4, 0x4, 0, 0}, + {0x48, 0xf, 0xf, 0, 0}, + {0x49, 0x30, 0x30, 0, 0}, + {0x4A, 0x32, 0x32, 0, 0}, + {0x4B, 0xd, 0xd, 0, 0}, + {0x4C, 0xd, 0xd, 0, 0}, + {0x4D, 0x4, 0x4, 0, 0}, + {0x4E, 0x6, 0x6, 0, 0}, + {0x4F, 0x1, 0x1, 0, 0}, + {0x50, 0x1c, 0x1c, 0, 0}, + {0x51, 0x2, 0x2, 0, 0}, + {0x52, 0x2, 0x2, 0, 0}, + {0x53, 0xf7, 0xf7, 1, 1}, + {0x54, 0xb4, 0xb4, 0, 0}, + {0x55, 0xd2, 0xd2, 0, 0}, + {0x56, 0, 0, 0, 0}, + {0x57, 0, 0, 0, 0}, + {0x58, 0x4, 0x4, 0, 0}, + {0x59, 0x96, 0x96, 0, 0}, + {0x5A, 0x3e, 0x3e, 0, 0}, + {0x5B, 0x3e, 0x3e, 0, 0}, + {0x5C, 0x13, 0x13, 0, 0}, + {0x5D, 0x2, 0x2, 0, 0}, + {0x5E, 0, 0, 0, 0}, + {0x5F, 0x7, 0x7, 0, 0}, + {0x60, 0x7, 0x7, 1, 1}, + {0x61, 0x8, 0x8, 0, 0}, + {0x62, 0x3, 0x3, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0, 0, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0, 0, 0, 0}, + {0x68, 0x40, 0x40, 0, 0}, + {0x69, 0, 0, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0, 0, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0x1, 0x1, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0x60, 0x60, 0, 0}, + {0x71, 0x66, 0x66, 0, 0}, + {0x72, 0xc, 0xc, 0, 0}, + {0x73, 0x66, 0x66, 0, 0}, + {0x74, 0x8f, 0x8f, 1, 1}, + {0x75, 0, 0, 0, 0}, + {0x76, 0xcc, 0xcc, 0, 0}, + {0x77, 0x1, 0x1, 0, 0}, + {0x78, 0x66, 0x66, 0, 0}, + {0x79, 0x66, 0x66, 0, 0}, + {0x7A, 0, 0, 0, 0}, + {0x7B, 0, 0, 0, 0}, + {0x7C, 0, 0, 0, 0}, + {0x7D, 0, 0, 0, 0}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0xff, 0xff, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0x93, 0, 0, 0, 0}, + {0x94, 0, 0, 0, 0}, + {0x95, 0, 0, 0, 0}, + {0x96, 0, 0, 0, 0}, + {0x97, 0, 0, 0, 0}, + {0x98, 0, 0, 0, 0}, + {0x99, 0, 0, 0, 0}, + {0x9A, 0, 0, 0, 0}, + {0x9B, 0, 0, 0, 0}, + {0x9C, 0, 0, 0, 0}, + {0x9D, 0, 0, 0, 0}, + {0x9E, 0, 0, 0, 0}, + {0x9F, 0x6, 0x6, 0, 0}, + {0xA0, 0x66, 0x66, 0, 0}, + {0xA1, 0x66, 0x66, 0, 0}, + {0xA2, 0x66, 0x66, 0, 0}, + {0xA3, 0x66, 0x66, 0, 0}, + {0xA4, 0x66, 0x66, 0, 0}, + {0xA5, 0x66, 0x66, 0, 0}, + {0xA6, 0x66, 0x66, 0, 0}, + {0xA7, 0x66, 0x66, 0, 0}, + {0xA8, 0x66, 0x66, 0, 0}, + {0xA9, 0x66, 0x66, 0, 0}, + {0xAA, 0x66, 0x66, 0, 0}, + {0xAB, 0x66, 0x66, 0, 0}, + {0xAC, 0x66, 0x66, 0, 0}, + {0xAD, 0x66, 0x66, 0, 0}, + {0xAE, 0x66, 0x66, 0, 0}, + {0xAF, 0x66, 0x66, 0, 0}, + {0xB0, 0x66, 0x66, 0, 0}, + {0xB1, 0x66, 0x66, 0, 0}, + {0xB2, 0x66, 0x66, 0, 0}, + {0xB3, 0xa, 0xa, 0, 0}, + {0xB4, 0, 0, 0, 0}, + {0xB5, 0, 0, 0, 0}, + {0xB6, 0, 0, 0, 0}, + {0xFFFF, 0, 0, 0, 0}, +}; + +radio_regs_t regs_TX_2056_rev8[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0, 0, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0, 0, 0, 0}, + {0x21, 0x88, 0x88, 0, 0}, + {0x22, 0x88, 0x88, 0, 0}, + {0x23, 0x88, 0x88, 0, 0}, + {0x24, 0x88, 0x88, 0, 0}, + {0x25, 0xc, 0xc, 0, 0}, + {0x26, 0, 0, 0, 0}, + {0x27, 0x3, 0x3, 0, 0}, + {0x28, 0, 0, 0, 0}, + {0x29, 0x3, 0x3, 0, 0}, + {0x2A, 0x37, 0x37, 0, 0}, + {0x2B, 0x3, 0x3, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0, 0, 0, 0}, + {0x2E, 0x1, 0x1, 0, 0}, + {0x2F, 0x1, 0x1, 0, 0}, + {0x30, 0, 0, 0, 0}, + {0x31, 0, 0, 0, 0}, + {0x32, 0, 0, 0, 0}, + {0x33, 0x11, 0x11, 0, 0}, + {0x34, 0xee, 0xee, 1, 1}, + {0x35, 0, 0, 0, 0}, + {0x36, 0, 0, 0, 0}, + {0x37, 0x3, 0x3, 0, 0}, + {0x38, 0x50, 0x50, 1, 1}, + {0x39, 0, 0, 0, 0}, + {0x3A, 0x50, 0x50, 1, 1}, + {0x3B, 0, 0, 0, 0}, + {0x3C, 0x6e, 0x6e, 0, 0}, + {0x3D, 0xf0, 0xf0, 1, 1}, + {0x3E, 0, 0, 0, 0}, + {0x3F, 0, 0, 0, 0}, + {0x40, 0, 0, 0, 0}, + {0x41, 0x3, 0x3, 0, 0}, + {0x42, 0x3, 0x3, 0, 0}, + {0x43, 0, 0, 0, 0}, + {0x44, 0x1e, 0x1e, 0, 0}, + {0x45, 0, 0, 0, 0}, + {0x46, 0x6e, 0x6e, 0, 0}, + {0x47, 0xf0, 0xf0, 1, 1}, + {0x48, 0, 0, 0, 0}, + {0x49, 0x2, 0x2, 0, 0}, + {0x4A, 0xff, 0xff, 1, 1}, + {0x4B, 0xc, 0xc, 0, 0}, + {0x4C, 0, 0, 0, 0}, + {0x4D, 0x38, 0x38, 0, 0}, + {0x4E, 0x70, 0x70, 1, 1}, + {0x4F, 0x2, 0x2, 0, 0}, + {0x50, 0x88, 0x88, 0, 0}, + {0x51, 0xc, 0xc, 0, 0}, + {0x52, 0, 0, 0, 0}, + {0x53, 0x8, 0x8, 0, 0}, + {0x54, 0x70, 0x70, 1, 1}, + {0x55, 0x2, 0x2, 0, 0}, + {0x56, 0xff, 0xff, 1, 1}, + {0x57, 0, 0, 0, 0}, + {0x58, 0x83, 0x83, 0, 0}, + {0x59, 0x77, 0x77, 1, 1}, + {0x5A, 0, 0, 0, 0}, + {0x5B, 0x2, 0x2, 0, 0}, + {0x5C, 0x88, 0x88, 0, 0}, + {0x5D, 0, 0, 0, 0}, + {0x5E, 0x8, 0x8, 0, 0}, + {0x5F, 0x77, 0x77, 1, 1}, + {0x60, 0x1, 0x1, 0, 0}, + {0x61, 0, 0, 0, 0}, + {0x62, 0x7, 0x7, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0x7, 0x7, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0, 0, 1, 1}, + {0x68, 0, 0, 0, 0}, + {0x69, 0xa, 0xa, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0, 0, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0, 0, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0, 0, 0, 0}, + {0x71, 0x2, 0x2, 0, 0}, + {0x72, 0, 0, 0, 0}, + {0x73, 0, 0, 0, 0}, + {0x74, 0xe, 0xe, 0, 0}, + {0x75, 0xe, 0xe, 0, 0}, + {0x76, 0xe, 0xe, 0, 0}, + {0x77, 0x13, 0x13, 0, 0}, + {0x78, 0x13, 0x13, 0, 0}, + {0x79, 0x1b, 0x1b, 0, 0}, + {0x7A, 0x1b, 0x1b, 0, 0}, + {0x7B, 0x55, 0x55, 0, 0}, + {0x7C, 0x5b, 0x5b, 0, 0}, + {0x7D, 0x30, 0x30, 1, 1}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0, 0, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0x93, 0x70, 0x70, 0, 0}, + {0x94, 0x70, 0x70, 0, 0}, + {0x95, 0x70, 0x70, 0, 0}, + {0x96, 0x70, 0x70, 0, 0}, + {0x97, 0x70, 0x70, 0, 0}, + {0x98, 0x70, 0x70, 0, 0}, + {0x99, 0x70, 0x70, 0, 0}, + {0x9A, 0x70, 0x70, 0, 0}, + {0xFFFF, 0, 0, 0, 0}, +}; + +radio_regs_t regs_RX_2056_rev8[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0, 0, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0x3, 0x3, 0, 0}, + {0x21, 0, 0, 0, 0}, + {0x22, 0, 0, 0, 0}, + {0x23, 0x90, 0x90, 0, 0}, + {0x24, 0x55, 0x55, 0, 0}, + {0x25, 0x15, 0x15, 0, 0}, + {0x26, 0x5, 0x5, 0, 0}, + {0x27, 0x15, 0x15, 0, 0}, + {0x28, 0x5, 0x5, 0, 0}, + {0x29, 0x20, 0x20, 0, 0}, + {0x2A, 0x11, 0x11, 0, 0}, + {0x2B, 0x90, 0x90, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0x88, 0x88, 0, 0}, + {0x2E, 0x32, 0x32, 0, 0}, + {0x2F, 0x77, 0x77, 0, 0}, + {0x30, 0x17, 0x17, 1, 1}, + {0x31, 0xff, 0xff, 1, 1}, + {0x32, 0x20, 0x20, 0, 0}, + {0x33, 0, 0, 0, 0}, + {0x34, 0x88, 0x88, 0, 0}, + {0x35, 0x32, 0x32, 0, 0}, + {0x36, 0x77, 0x77, 0, 0}, + {0x37, 0x17, 0x17, 1, 1}, + {0x38, 0xf0, 0xf0, 1, 1}, + {0x39, 0x20, 0x20, 0, 0}, + {0x3A, 0x8, 0x8, 0, 0}, + {0x3B, 0x55, 0x55, 1, 1}, + {0x3C, 0, 0, 0, 0}, + {0x3D, 0x88, 0x88, 1, 1}, + {0x3E, 0, 0, 0, 0}, + {0x3F, 0x44, 0x44, 0, 0}, + {0x40, 0x7, 0x7, 1, 1}, + {0x41, 0x6, 0x6, 0, 0}, + {0x42, 0x4, 0x4, 0, 0}, + {0x43, 0, 0, 0, 0}, + {0x44, 0x8, 0x8, 0, 0}, + {0x45, 0x55, 0x55, 1, 1}, + {0x46, 0, 0, 0, 0}, + {0x47, 0x11, 0x11, 0, 0}, + {0x48, 0, 0, 0, 0}, + {0x49, 0x44, 0x44, 0, 0}, + {0x4A, 0x7, 0x7, 0, 0}, + {0x4B, 0x6, 0x6, 0, 0}, + {0x4C, 0x4, 0x4, 0, 0}, + {0x4D, 0, 0, 0, 0}, + {0x4E, 0, 0, 0, 0}, + {0x4F, 0x26, 0x26, 1, 1}, + {0x50, 0x26, 0x26, 1, 1}, + {0x51, 0xf, 0xf, 1, 1}, + {0x52, 0xf, 0xf, 1, 1}, + {0x53, 0x44, 0x44, 0, 0}, + {0x54, 0, 0, 0, 0}, + {0x55, 0, 0, 0, 0}, + {0x56, 0x8, 0x8, 0, 0}, + {0x57, 0x8, 0x8, 0, 0}, + {0x58, 0x7, 0x7, 0, 0}, + {0x59, 0x22, 0x22, 0, 0}, + {0x5A, 0x22, 0x22, 0, 0}, + {0x5B, 0x2, 0x2, 0, 0}, + {0x5C, 0x4, 0x4, 1, 1}, + {0x5D, 0x7, 0x7, 0, 0}, + {0x5E, 0x55, 0x55, 0, 0}, + {0x5F, 0x23, 0x23, 0, 0}, + {0x60, 0x41, 0x41, 0, 0}, + {0x61, 0x1, 0x1, 0, 0}, + {0x62, 0xa, 0xa, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0, 0, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0, 0, 0, 0}, + {0x68, 0, 0, 0, 0}, + {0x69, 0, 0, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0xc, 0xc, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0, 0, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0, 0, 0, 0}, + {0x71, 0, 0, 0, 0}, + {0x72, 0x22, 0x22, 0, 0}, + {0x73, 0x22, 0x22, 0, 0}, + {0x74, 0, 0, 1, 1}, + {0x75, 0xa, 0xa, 0, 0}, + {0x76, 0x1, 0x1, 0, 0}, + {0x77, 0x22, 0x22, 0, 0}, + {0x78, 0x30, 0x30, 0, 0}, + {0x79, 0, 0, 0, 0}, + {0x7A, 0, 0, 0, 0}, + {0x7B, 0, 0, 0, 0}, + {0x7C, 0, 0, 0, 0}, + {0x7D, 0x5, 0x5, 1, 1}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0, 0, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0x93, 0, 0, 0, 0}, + {0x94, 0, 0, 0, 0}, + {0xFFFF, 0, 0, 0, 0}, +}; + +radio_regs_t regs_SYN_2056_rev11[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0x1, 0x1, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0, 0, 0, 0}, + {0x21, 0, 0, 0, 0}, + {0x22, 0x60, 0x60, 0, 0}, + {0x23, 0x6, 0x6, 0, 0}, + {0x24, 0xc, 0xc, 0, 0}, + {0x25, 0, 0, 0, 0}, + {0x26, 0, 0, 0, 0}, + {0x27, 0, 0, 0, 0}, + {0x28, 0x1, 0x1, 0, 0}, + {0x29, 0, 0, 0, 0}, + {0x2A, 0, 0, 0, 0}, + {0x2B, 0, 0, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0, 0, 0, 0}, + {0x2E, 0, 0, 0, 0}, + {0x2F, 0x1f, 0x1f, 0, 0}, + {0x30, 0x15, 0x15, 0, 0}, + {0x31, 0xf, 0xf, 0, 0}, + {0x32, 0, 0, 0, 0}, + {0x33, 0, 0, 0, 0}, + {0x34, 0, 0, 0, 0}, + {0x35, 0, 0, 0, 0}, + {0x36, 0, 0, 0, 0}, + {0x37, 0, 0, 0, 0}, + {0x38, 0, 0, 0, 0}, + {0x39, 0, 0, 0, 0}, + {0x3A, 0, 0, 0, 0}, + {0x3B, 0, 0, 0, 0}, + {0x3C, 0x13, 0x13, 0, 0}, + {0x3D, 0xf, 0xf, 0, 0}, + {0x3E, 0x18, 0x18, 0, 0}, + {0x3F, 0, 0, 0, 0}, + {0x40, 0, 0, 0, 0}, + {0x41, 0x20, 0x20, 0, 0}, + {0x42, 0x20, 0x20, 0, 0}, + {0x43, 0, 0, 0, 0}, + {0x44, 0x77, 0x77, 0, 0}, + {0x45, 0x7, 0x7, 0, 0}, + {0x46, 0x1, 0x1, 0, 0}, + {0x47, 0x6, 0x6, 1, 1}, + {0x48, 0xf, 0xf, 0, 0}, + {0x49, 0x3f, 0x3f, 1, 1}, + {0x4A, 0x32, 0x32, 0, 0}, + {0x4B, 0x6, 0x6, 1, 1}, + {0x4C, 0x6, 0x6, 1, 1}, + {0x4D, 0x4, 0x4, 0, 0}, + {0x4E, 0x2b, 0x2b, 1, 1}, + {0x4F, 0x1, 0x1, 0, 0}, + {0x50, 0x1c, 0x1c, 0, 0}, + {0x51, 0x2, 0x2, 0, 0}, + {0x52, 0x2, 0x2, 0, 0}, + {0x53, 0xf7, 0xf7, 1, 1}, + {0x54, 0xb4, 0xb4, 0, 0}, + {0x55, 0xd2, 0xd2, 0, 0}, + {0x56, 0, 0, 0, 0}, + {0x57, 0, 0, 0, 0}, + {0x58, 0x4, 0x4, 0, 0}, + {0x59, 0x96, 0x96, 0, 0}, + {0x5A, 0x3e, 0x3e, 0, 0}, + {0x5B, 0x3e, 0x3e, 0, 0}, + {0x5C, 0x13, 0x13, 0, 0}, + {0x5D, 0x2, 0x2, 0, 0}, + {0x5E, 0, 0, 0, 0}, + {0x5F, 0x7, 0x7, 0, 0}, + {0x60, 0x7, 0x7, 1, 1}, + {0x61, 0x8, 0x8, 0, 0}, + {0x62, 0x3, 0x3, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0, 0, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0, 0, 0, 0}, + {0x68, 0x40, 0x40, 0, 0}, + {0x69, 0, 0, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0, 0, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0x1, 0x1, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0x60, 0x60, 0, 0}, + {0x71, 0x66, 0x66, 0, 0}, + {0x72, 0xc, 0xc, 0, 0}, + {0x73, 0x66, 0x66, 0, 0}, + {0x74, 0x8f, 0x8f, 1, 1}, + {0x75, 0, 0, 0, 0}, + {0x76, 0xcc, 0xcc, 0, 0}, + {0x77, 0x1, 0x1, 0, 0}, + {0x78, 0x66, 0x66, 0, 0}, + {0x79, 0x66, 0x66, 0, 0}, + {0x7A, 0, 0, 0, 0}, + {0x7B, 0, 0, 0, 0}, + {0x7C, 0, 0, 0, 0}, + {0x7D, 0, 0, 0, 0}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0xff, 0xff, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0x93, 0, 0, 0, 0}, + {0x94, 0, 0, 0, 0}, + {0x95, 0, 0, 0, 0}, + {0x96, 0, 0, 0, 0}, + {0x97, 0, 0, 0, 0}, + {0x98, 0, 0, 0, 0}, + {0x99, 0, 0, 0, 0}, + {0x9A, 0, 0, 0, 0}, + {0x9B, 0, 0, 0, 0}, + {0x9C, 0, 0, 0, 0}, + {0x9D, 0, 0, 0, 0}, + {0x9E, 0, 0, 0, 0}, + {0x9F, 0x6, 0x6, 0, 0}, + {0xA0, 0x66, 0x66, 0, 0}, + {0xA1, 0x66, 0x66, 0, 0}, + {0xA2, 0x66, 0x66, 0, 0}, + {0xA3, 0x66, 0x66, 0, 0}, + {0xA4, 0x66, 0x66, 0, 0}, + {0xA5, 0x66, 0x66, 0, 0}, + {0xA6, 0x66, 0x66, 0, 0}, + {0xA7, 0x66, 0x66, 0, 0}, + {0xA8, 0x66, 0x66, 0, 0}, + {0xA9, 0x66, 0x66, 0, 0}, + {0xAA, 0x66, 0x66, 0, 0}, + {0xAB, 0x66, 0x66, 0, 0}, + {0xAC, 0x66, 0x66, 0, 0}, + {0xAD, 0x66, 0x66, 0, 0}, + {0xAE, 0x66, 0x66, 0, 0}, + {0xAF, 0x66, 0x66, 0, 0}, + {0xB0, 0x66, 0x66, 0, 0}, + {0xB1, 0x66, 0x66, 0, 0}, + {0xB2, 0x66, 0x66, 0, 0}, + {0xB3, 0xa, 0xa, 0, 0}, + {0xB4, 0, 0, 0, 0}, + {0xB5, 0, 0, 0, 0}, + {0xB6, 0, 0, 0, 0}, + {0xFFFF, 0, 0, 0, 0}, +}; + +radio_regs_t regs_TX_2056_rev11[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0, 0, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0, 0, 0, 0}, + {0x21, 0x88, 0x88, 0, 0}, + {0x22, 0x88, 0x88, 0, 0}, + {0x23, 0x88, 0x88, 0, 0}, + {0x24, 0x88, 0x88, 0, 0}, + {0x25, 0xc, 0xc, 0, 0}, + {0x26, 0, 0, 0, 0}, + {0x27, 0x3, 0x3, 0, 0}, + {0x28, 0, 0, 0, 0}, + {0x29, 0x3, 0x3, 0, 0}, + {0x2A, 0x37, 0x37, 0, 0}, + {0x2B, 0x3, 0x3, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0, 0, 0, 0}, + {0x2E, 0x1, 0x1, 0, 0}, + {0x2F, 0x1, 0x1, 0, 0}, + {0x30, 0, 0, 0, 0}, + {0x31, 0, 0, 0, 0}, + {0x32, 0, 0, 0, 0}, + {0x33, 0x11, 0x11, 0, 0}, + {0x34, 0xee, 0xee, 1, 1}, + {0x35, 0, 0, 0, 0}, + {0x36, 0, 0, 0, 0}, + {0x37, 0x3, 0x3, 0, 0}, + {0x38, 0x50, 0x50, 1, 1}, + {0x39, 0, 0, 0, 0}, + {0x3A, 0x50, 0x50, 1, 1}, + {0x3B, 0, 0, 0, 0}, + {0x3C, 0x6e, 0x6e, 0, 0}, + {0x3D, 0xf0, 0xf0, 1, 1}, + {0x3E, 0, 0, 0, 0}, + {0x3F, 0, 0, 0, 0}, + {0x40, 0, 0, 0, 0}, + {0x41, 0x3, 0x3, 0, 0}, + {0x42, 0x3, 0x3, 0, 0}, + {0x43, 0, 0, 0, 0}, + {0x44, 0x1e, 0x1e, 0, 0}, + {0x45, 0, 0, 0, 0}, + {0x46, 0x6e, 0x6e, 0, 0}, + {0x47, 0xf0, 0xf0, 1, 1}, + {0x48, 0, 0, 0, 0}, + {0x49, 0x2, 0x2, 0, 0}, + {0x4A, 0xff, 0xff, 1, 1}, + {0x4B, 0xc, 0xc, 0, 0}, + {0x4C, 0, 0, 0, 0}, + {0x4D, 0x38, 0x38, 0, 0}, + {0x4E, 0x70, 0x70, 1, 1}, + {0x4F, 0x2, 0x2, 0, 0}, + {0x50, 0x88, 0x88, 0, 0}, + {0x51, 0xc, 0xc, 0, 0}, + {0x52, 0, 0, 0, 0}, + {0x53, 0x8, 0x8, 0, 0}, + {0x54, 0x70, 0x70, 1, 1}, + {0x55, 0x2, 0x2, 0, 0}, + {0x56, 0xff, 0xff, 1, 1}, + {0x57, 0, 0, 0, 0}, + {0x58, 0x83, 0x83, 0, 0}, + {0x59, 0x77, 0x77, 1, 1}, + {0x5A, 0, 0, 0, 0}, + {0x5B, 0x2, 0x2, 0, 0}, + {0x5C, 0x88, 0x88, 0, 0}, + {0x5D, 0, 0, 0, 0}, + {0x5E, 0x8, 0x8, 0, 0}, + {0x5F, 0x77, 0x77, 1, 1}, + {0x60, 0x1, 0x1, 0, 0}, + {0x61, 0, 0, 0, 0}, + {0x62, 0x7, 0x7, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0x7, 0x7, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0, 0, 1, 1}, + {0x68, 0, 0, 0, 0}, + {0x69, 0xa, 0xa, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0, 0, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0, 0, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0, 0, 0, 0}, + {0x71, 0x2, 0x2, 0, 0}, + {0x72, 0, 0, 0, 0}, + {0x73, 0, 0, 0, 0}, + {0x74, 0xe, 0xe, 0, 0}, + {0x75, 0xe, 0xe, 0, 0}, + {0x76, 0xe, 0xe, 0, 0}, + {0x77, 0x13, 0x13, 0, 0}, + {0x78, 0x13, 0x13, 0, 0}, + {0x79, 0x1b, 0x1b, 0, 0}, + {0x7A, 0x1b, 0x1b, 0, 0}, + {0x7B, 0x55, 0x55, 0, 0}, + {0x7C, 0x5b, 0x5b, 0, 0}, + {0x7D, 0x30, 0x30, 1, 1}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0, 0, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0x93, 0x70, 0x70, 0, 0}, + {0x94, 0x70, 0x70, 0, 0}, + {0x95, 0x70, 0x70, 0, 0}, + {0x96, 0x70, 0x70, 0, 0}, + {0x97, 0x70, 0x70, 0, 0}, + {0x98, 0x70, 0x70, 0, 0}, + {0x99, 0x70, 0x70, 0, 0}, + {0x9A, 0x70, 0x70, 0, 0}, + {0xFFFF, 0, 0, 0, 0}, +}; + +radio_regs_t regs_RX_2056_rev11[] = { + {0x02, 0, 0, 0, 0}, + {0x03, 0, 0, 0, 0}, + {0x04, 0, 0, 0, 0}, + {0x05, 0, 0, 0, 0}, + {0x06, 0, 0, 0, 0}, + {0x07, 0, 0, 0, 0}, + {0x08, 0, 0, 0, 0}, + {0x09, 0, 0, 0, 0}, + {0x0A, 0, 0, 0, 0}, + {0x0B, 0, 0, 0, 0}, + {0x0C, 0, 0, 0, 0}, + {0x0D, 0, 0, 0, 0}, + {0x0E, 0, 0, 0, 0}, + {0x0F, 0, 0, 0, 0}, + {0x10, 0, 0, 0, 0}, + {0x11, 0, 0, 0, 0}, + {0x12, 0, 0, 0, 0}, + {0x13, 0, 0, 0, 0}, + {0x14, 0, 0, 0, 0}, + {0x15, 0, 0, 0, 0}, + {0x16, 0, 0, 0, 0}, + {0x17, 0, 0, 0, 0}, + {0x18, 0, 0, 0, 0}, + {0x19, 0, 0, 0, 0}, + {0x1A, 0, 0, 0, 0}, + {0x1B, 0, 0, 0, 0}, + {0x1C, 0, 0, 0, 0}, + {0x1D, 0, 0, 0, 0}, + {0x1E, 0, 0, 0, 0}, + {0x1F, 0, 0, 0, 0}, + {0x20, 0x3, 0x3, 0, 0}, + {0x21, 0, 0, 0, 0}, + {0x22, 0, 0, 0, 0}, + {0x23, 0x90, 0x90, 0, 0}, + {0x24, 0x55, 0x55, 0, 0}, + {0x25, 0x15, 0x15, 0, 0}, + {0x26, 0x5, 0x5, 0, 0}, + {0x27, 0x15, 0x15, 0, 0}, + {0x28, 0x5, 0x5, 0, 0}, + {0x29, 0x20, 0x20, 0, 0}, + {0x2A, 0x11, 0x11, 0, 0}, + {0x2B, 0x90, 0x90, 0, 0}, + {0x2C, 0, 0, 0, 0}, + {0x2D, 0x88, 0x88, 0, 0}, + {0x2E, 0x32, 0x32, 0, 0}, + {0x2F, 0x77, 0x77, 0, 0}, + {0x30, 0x17, 0x17, 1, 1}, + {0x31, 0xff, 0xff, 1, 1}, + {0x32, 0x20, 0x20, 0, 0}, + {0x33, 0, 0, 0, 0}, + {0x34, 0x88, 0x88, 0, 0}, + {0x35, 0x32, 0x32, 0, 0}, + {0x36, 0x77, 0x77, 0, 0}, + {0x37, 0x17, 0x17, 1, 1}, + {0x38, 0xf0, 0xf0, 1, 1}, + {0x39, 0x20, 0x20, 0, 0}, + {0x3A, 0x8, 0x8, 0, 0}, + {0x3B, 0x55, 0x55, 1, 1}, + {0x3C, 0, 0, 0, 0}, + {0x3D, 0x88, 0x88, 1, 1}, + {0x3E, 0, 0, 0, 0}, + {0x3F, 0x44, 0x44, 0, 0}, + {0x40, 0x7, 0x7, 1, 1}, + {0x41, 0x6, 0x6, 0, 0}, + {0x42, 0x4, 0x4, 0, 0}, + {0x43, 0, 0, 0, 0}, + {0x44, 0x8, 0x8, 0, 0}, + {0x45, 0x55, 0x55, 1, 1}, + {0x46, 0, 0, 0, 0}, + {0x47, 0x11, 0x11, 0, 0}, + {0x48, 0, 0, 0, 0}, + {0x49, 0x44, 0x44, 0, 0}, + {0x4A, 0x7, 0x7, 0, 0}, + {0x4B, 0x6, 0x6, 0, 0}, + {0x4C, 0x4, 0x4, 0, 0}, + {0x4D, 0, 0, 0, 0}, + {0x4E, 0, 0, 0, 0}, + {0x4F, 0x26, 0x26, 1, 1}, + {0x50, 0x26, 0x26, 1, 1}, + {0x51, 0xf, 0xf, 1, 1}, + {0x52, 0xf, 0xf, 1, 1}, + {0x53, 0x44, 0x44, 0, 0}, + {0x54, 0, 0, 0, 0}, + {0x55, 0, 0, 0, 0}, + {0x56, 0x8, 0x8, 0, 0}, + {0x57, 0x8, 0x8, 0, 0}, + {0x58, 0x7, 0x7, 0, 0}, + {0x59, 0x22, 0x22, 0, 0}, + {0x5A, 0x22, 0x22, 0, 0}, + {0x5B, 0x2, 0x2, 0, 0}, + {0x5C, 0x4, 0x4, 1, 1}, + {0x5D, 0x7, 0x7, 0, 0}, + {0x5E, 0x55, 0x55, 0, 0}, + {0x5F, 0x23, 0x23, 0, 0}, + {0x60, 0x41, 0x41, 0, 0}, + {0x61, 0x1, 0x1, 0, 0}, + {0x62, 0xa, 0xa, 0, 0}, + {0x63, 0, 0, 0, 0}, + {0x64, 0, 0, 0, 0}, + {0x65, 0, 0, 0, 0}, + {0x66, 0, 0, 0, 0}, + {0x67, 0, 0, 0, 0}, + {0x68, 0, 0, 0, 0}, + {0x69, 0, 0, 0, 0}, + {0x6A, 0, 0, 0, 0}, + {0x6B, 0xc, 0xc, 0, 0}, + {0x6C, 0, 0, 0, 0}, + {0x6D, 0, 0, 0, 0}, + {0x6E, 0, 0, 0, 0}, + {0x6F, 0, 0, 0, 0}, + {0x70, 0, 0, 0, 0}, + {0x71, 0, 0, 0, 0}, + {0x72, 0x22, 0x22, 0, 0}, + {0x73, 0x22, 0x22, 0, 0}, + {0x74, 0, 0, 1, 1}, + {0x75, 0xa, 0xa, 0, 0}, + {0x76, 0x1, 0x1, 0, 0}, + {0x77, 0x22, 0x22, 0, 0}, + {0x78, 0x30, 0x30, 0, 0}, + {0x79, 0, 0, 0, 0}, + {0x7A, 0, 0, 0, 0}, + {0x7B, 0, 0, 0, 0}, + {0x7C, 0, 0, 0, 0}, + {0x7D, 0x5, 0x5, 1, 1}, + {0x7E, 0, 0, 0, 0}, + {0x7F, 0, 0, 0, 0}, + {0x80, 0, 0, 0, 0}, + {0x81, 0, 0, 0, 0}, + {0x82, 0, 0, 0, 0}, + {0x83, 0, 0, 0, 0}, + {0x84, 0, 0, 0, 0}, + {0x85, 0, 0, 0, 0}, + {0x86, 0, 0, 0, 0}, + {0x87, 0, 0, 0, 0}, + {0x88, 0, 0, 0, 0}, + {0x89, 0, 0, 0, 0}, + {0x8A, 0, 0, 0, 0}, + {0x8B, 0, 0, 0, 0}, + {0x8C, 0, 0, 0, 0}, + {0x8D, 0, 0, 0, 0}, + {0x8E, 0, 0, 0, 0}, + {0x8F, 0, 0, 0, 0}, + {0x90, 0, 0, 0, 0}, + {0x91, 0, 0, 0, 0}, + {0x92, 0, 0, 0, 0}, + {0x93, 0, 0, 0, 0}, + {0x94, 0, 0, 0, 0}, + {0xFFFF, 0, 0, 0, 0}, +}; + +radio_20xx_regs_t regs_2057_rev4[] = { + {0x00, 0x84, 0}, + {0x01, 0, 0}, + {0x02, 0x60, 0}, + {0x03, 0x1f, 0}, + {0x04, 0x4, 0}, + {0x05, 0x2, 0}, + {0x06, 0x1, 0}, + {0x07, 0x1, 0}, + {0x08, 0x1, 0}, + {0x09, 0x69, 0}, + {0x0A, 0x66, 0}, + {0x0B, 0x6, 0}, + {0x0C, 0x18, 0}, + {0x0D, 0x3, 0}, + {0x0E, 0x20, 1}, + {0x0F, 0x20, 0}, + {0x10, 0, 0}, + {0x11, 0x7c, 0}, + {0x12, 0x42, 0}, + {0x13, 0xbd, 0}, + {0x14, 0x7, 0}, + {0x15, 0xf7, 0}, + {0x16, 0x8, 0}, + {0x17, 0x17, 0}, + {0x18, 0x7, 0}, + {0x19, 0, 0}, + {0x1A, 0x2, 0}, + {0x1B, 0x13, 0}, + {0x1C, 0x3e, 0}, + {0x1D, 0x3e, 0}, + {0x1E, 0x96, 0}, + {0x1F, 0x4, 0}, + {0x20, 0, 0}, + {0x21, 0, 0}, + {0x22, 0x17, 0}, + {0x23, 0x4, 0}, + {0x24, 0x1, 0}, + {0x25, 0x6, 0}, + {0x26, 0x4, 0}, + {0x27, 0xd, 0}, + {0x28, 0xd, 0}, + {0x29, 0x30, 0}, + {0x2A, 0x32, 0}, + {0x2B, 0x8, 0}, + {0x2C, 0x1c, 0}, + {0x2D, 0x2, 0}, + {0x2E, 0x4, 0}, + {0x2F, 0x7f, 0}, + {0x30, 0x27, 0}, + {0x31, 0, 1}, + {0x32, 0, 1}, + {0x33, 0, 1}, + {0x34, 0, 0}, + {0x35, 0x26, 1}, + {0x36, 0x18, 0}, + {0x37, 0x7, 0}, + {0x38, 0x66, 0}, + {0x39, 0x66, 0}, + {0x3A, 0x66, 0}, + {0x3B, 0x66, 0}, + {0x3C, 0xff, 1}, + {0x3D, 0xff, 1}, + {0x3E, 0xff, 1}, + {0x3F, 0xff, 1}, + {0x40, 0x16, 0}, + {0x41, 0x7, 0}, + {0x42, 0x19, 0}, + {0x43, 0x7, 0}, + {0x44, 0x6, 0}, + {0x45, 0x3, 0}, + {0x46, 0x1, 0}, + {0x47, 0x7, 0}, + {0x48, 0x33, 0}, + {0x49, 0x5, 0}, + {0x4A, 0x77, 0}, + {0x4B, 0x66, 0}, + {0x4C, 0x66, 0}, + {0x4D, 0, 0}, + {0x4E, 0x4, 0}, + {0x4F, 0xc, 0}, + {0x50, 0, 0}, + {0x51, 0x75, 0}, + {0x56, 0x7, 0}, + {0x57, 0, 0}, + {0x58, 0, 0}, + {0x59, 0xa8, 0}, + {0x5A, 0, 0}, + {0x5B, 0x1f, 0}, + {0x5C, 0x30, 0}, + {0x5D, 0x1, 0}, + {0x5E, 0x30, 0}, + {0x5F, 0x70, 0}, + {0x60, 0, 0}, + {0x61, 0, 0}, + {0x62, 0x33, 1}, + {0x63, 0x19, 0}, + {0x64, 0x62, 0}, + {0x65, 0, 0}, + {0x66, 0x11, 0}, + {0x69, 0, 0}, + {0x6A, 0x7e, 0}, + {0x6B, 0x3f, 0}, + {0x6C, 0x7f, 0}, + {0x6D, 0x78, 0}, + {0x6E, 0xc8, 0}, + {0x6F, 0x88, 0}, + {0x70, 0x8, 0}, + {0x71, 0xf, 0}, + {0x72, 0xbc, 0}, + {0x73, 0x8, 0}, + {0x74, 0x60, 0}, + {0x75, 0x1e, 0}, + {0x76, 0x70, 0}, + {0x77, 0, 0}, + {0x78, 0, 0}, + {0x79, 0, 0}, + {0x7A, 0x33, 0}, + {0x7B, 0x1e, 0}, + {0x7C, 0x62, 0}, + {0x7D, 0x11, 0}, + {0x80, 0x3c, 0}, + {0x81, 0x9c, 0}, + {0x82, 0xa, 0}, + {0x83, 0x9d, 0}, + {0x84, 0xa, 0}, + {0x85, 0, 0}, + {0x86, 0x40, 0}, + {0x87, 0x40, 0}, + {0x88, 0x88, 0}, + {0x89, 0x10, 0}, + {0x8A, 0xf0, 1}, + {0x8B, 0x10, 1}, + {0x8C, 0xf0, 1}, + {0x8D, 0, 0}, + {0x8E, 0, 0}, + {0x8F, 0x10, 0}, + {0x90, 0x55, 0}, + {0x91, 0x3f, 1}, + {0x92, 0x36, 1}, + {0x93, 0, 0}, + {0x94, 0, 0}, + {0x95, 0, 0}, + {0x96, 0x87, 0}, + {0x97, 0x11, 0}, + {0x98, 0, 0}, + {0x99, 0x33, 0}, + {0x9A, 0x88, 0}, + {0x9B, 0, 0}, + {0x9C, 0x87, 0}, + {0x9D, 0x11, 0}, + {0x9E, 0, 0}, + {0x9F, 0x33, 0}, + {0xA0, 0x88, 0}, + {0xA1, 0xe1, 0}, + {0xA2, 0x3f, 0}, + {0xA3, 0x44, 0}, + {0xA4, 0x8c, 1}, + {0xA5, 0x6d, 0}, + {0xA6, 0x22, 0}, + {0xA7, 0xbe, 0}, + {0xA8, 0x55, 1}, + {0xA9, 0xc, 0}, + {0xAA, 0xc, 0}, + {0xAB, 0xaa, 0}, + {0xAC, 0x2, 0}, + {0xAD, 0, 0}, + {0xAE, 0x10, 0}, + {0xAF, 0x1, 1}, + {0xB0, 0, 0}, + {0xB1, 0, 0}, + {0xB2, 0x80, 0}, + {0xB3, 0x60, 0}, + {0xB4, 0x44, 0}, + {0xB5, 0x55, 0}, + {0xB6, 0x1, 0}, + {0xB7, 0x55, 0}, + {0xB8, 0x1, 0}, + {0xB9, 0x5, 0}, + {0xBA, 0x55, 0}, + {0xBB, 0x55, 0}, + {0xC1, 0, 0}, + {0xC2, 0, 0}, + {0xC3, 0, 0}, + {0xC4, 0, 0}, + {0xC5, 0, 0}, + {0xC6, 0, 0}, + {0xC7, 0, 0}, + {0xC8, 0, 0}, + {0xC9, 0, 0}, + {0xCA, 0, 0}, + {0xCB, 0, 0}, + {0xCC, 0, 0}, + {0xCD, 0, 0}, + {0xCE, 0x5e, 0}, + {0xCF, 0xc, 0}, + {0xD0, 0xc, 0}, + {0xD1, 0xc, 0}, + {0xD2, 0, 0}, + {0xD3, 0x2b, 0}, + {0xD4, 0xc, 0}, + {0xD5, 0, 0}, + {0xD6, 0x75, 0}, + {0xDB, 0x7, 0}, + {0xDC, 0, 0}, + {0xDD, 0, 0}, + {0xDE, 0xa8, 0}, + {0xDF, 0, 0}, + {0xE0, 0x1f, 0}, + {0xE1, 0x30, 0}, + {0xE2, 0x1, 0}, + {0xE3, 0x30, 0}, + {0xE4, 0x70, 0}, + {0xE5, 0, 0}, + {0xE6, 0, 0}, + {0xE7, 0x33, 0}, + {0xE8, 0x19, 0}, + {0xE9, 0x62, 0}, + {0xEA, 0, 0}, + {0xEB, 0x11, 0}, + {0xEE, 0, 0}, + {0xEF, 0x7e, 0}, + {0xF0, 0x3f, 0}, + {0xF1, 0x7f, 0}, + {0xF2, 0x78, 0}, + {0xF3, 0xc8, 0}, + {0xF4, 0x88, 0}, + {0xF5, 0x8, 0}, + {0xF6, 0xf, 0}, + {0xF7, 0xbc, 0}, + {0xF8, 0x8, 0}, + {0xF9, 0x60, 0}, + {0xFA, 0x1e, 0}, + {0xFB, 0x70, 0}, + {0xFC, 0, 0}, + {0xFD, 0, 0}, + {0xFE, 0, 0}, + {0xFF, 0x33, 0}, + {0x100, 0x1e, 0}, + {0x101, 0x62, 0}, + {0x102, 0x11, 0}, + {0x105, 0x3c, 0}, + {0x106, 0x9c, 0}, + {0x107, 0xa, 0}, + {0x108, 0x9d, 0}, + {0x109, 0xa, 0}, + {0x10A, 0, 0}, + {0x10B, 0x40, 0}, + {0x10C, 0x40, 0}, + {0x10D, 0x88, 0}, + {0x10E, 0x10, 0}, + {0x10F, 0xf0, 1}, + {0x110, 0x10, 1}, + {0x111, 0xf0, 1}, + {0x112, 0, 0}, + {0x113, 0, 0}, + {0x114, 0x10, 0}, + {0x115, 0x55, 0}, + {0x116, 0x3f, 1}, + {0x117, 0x36, 1}, + {0x118, 0, 0}, + {0x119, 0, 0}, + {0x11A, 0, 0}, + {0x11B, 0x87, 0}, + {0x11C, 0x11, 0}, + {0x11D, 0, 0}, + {0x11E, 0x33, 0}, + {0x11F, 0x88, 0}, + {0x120, 0, 0}, + {0x121, 0x87, 0}, + {0x122, 0x11, 0}, + {0x123, 0, 0}, + {0x124, 0x33, 0}, + {0x125, 0x88, 0}, + {0x126, 0xe1, 0}, + {0x127, 0x3f, 0}, + {0x128, 0x44, 0}, + {0x129, 0x8c, 1}, + {0x12A, 0x6d, 0}, + {0x12B, 0x22, 0}, + {0x12C, 0xbe, 0}, + {0x12D, 0x55, 1}, + {0x12E, 0xc, 0}, + {0x12F, 0xc, 0}, + {0x130, 0xaa, 0}, + {0x131, 0x2, 0}, + {0x132, 0, 0}, + {0x133, 0x10, 0}, + {0x134, 0x1, 1}, + {0x135, 0, 0}, + {0x136, 0, 0}, + {0x137, 0x80, 0}, + {0x138, 0x60, 0}, + {0x139, 0x44, 0}, + {0x13A, 0x55, 0}, + {0x13B, 0x1, 0}, + {0x13C, 0x55, 0}, + {0x13D, 0x1, 0}, + {0x13E, 0x5, 0}, + {0x13F, 0x55, 0}, + {0x140, 0x55, 0}, + {0x146, 0, 0}, + {0x147, 0, 0}, + {0x148, 0, 0}, + {0x149, 0, 0}, + {0x14A, 0, 0}, + {0x14B, 0, 0}, + {0x14C, 0, 0}, + {0x14D, 0, 0}, + {0x14E, 0, 0}, + {0x14F, 0, 0}, + {0x150, 0, 0}, + {0x151, 0, 0}, + {0x152, 0, 0}, + {0x153, 0, 0}, + {0x154, 0xc, 0}, + {0x155, 0xc, 0}, + {0x156, 0xc, 0}, + {0x157, 0, 0}, + {0x158, 0x2b, 0}, + {0x159, 0x84, 0}, + {0x15A, 0x15, 0}, + {0x15B, 0xf, 0}, + {0x15C, 0, 0}, + {0x15D, 0, 0}, + {0x15E, 0, 1}, + {0x15F, 0, 1}, + {0x160, 0, 1}, + {0x161, 0, 1}, + {0x162, 0, 1}, + {0x163, 0, 1}, + {0x164, 0, 0}, + {0x165, 0, 0}, + {0x166, 0, 0}, + {0x167, 0, 0}, + {0x168, 0, 0}, + {0x169, 0x2, 1}, + {0x16A, 0, 1}, + {0x16B, 0, 1}, + {0x16C, 0, 1}, + {0x16D, 0, 0}, + {0x170, 0, 0}, + {0x171, 0x77, 0}, + {0x172, 0x77, 0}, + {0x173, 0x77, 0}, + {0x174, 0x77, 0}, + {0x175, 0, 0}, + {0x176, 0x3, 0}, + {0x177, 0x37, 0}, + {0x178, 0x3, 0}, + {0x179, 0, 0}, + {0x17A, 0x21, 0}, + {0x17B, 0x21, 0}, + {0x17C, 0, 0}, + {0x17D, 0xaa, 0}, + {0x17E, 0, 0}, + {0x17F, 0xaa, 0}, + {0x180, 0, 0}, + {0x190, 0, 0}, + {0x191, 0x77, 0}, + {0x192, 0x77, 0}, + {0x193, 0x77, 0}, + {0x194, 0x77, 0}, + {0x195, 0, 0}, + {0x196, 0x3, 0}, + {0x197, 0x37, 0}, + {0x198, 0x3, 0}, + {0x199, 0, 0}, + {0x19A, 0x21, 0}, + {0x19B, 0x21, 0}, + {0x19C, 0, 0}, + {0x19D, 0xaa, 0}, + {0x19E, 0, 0}, + {0x19F, 0xaa, 0}, + {0x1A0, 0, 0}, + {0x1A1, 0x2, 0}, + {0x1A2, 0xf, 0}, + {0x1A3, 0xf, 0}, + {0x1A4, 0, 1}, + {0x1A5, 0, 1}, + {0x1A6, 0, 1}, + {0x1A7, 0x2, 0}, + {0x1A8, 0xf, 0}, + {0x1A9, 0xf, 0}, + {0x1AA, 0, 1}, + {0x1AB, 0, 1}, + {0x1AC, 0, 1}, + {0xFFFF, 0, 0}, +}; + +radio_20xx_regs_t regs_2057_rev5[] = { + {0x00, 0, 1}, + {0x01, 0x57, 1}, + {0x02, 0x20, 1}, + {0x03, 0x1f, 0}, + {0x04, 0x4, 0}, + {0x05, 0x2, 0}, + {0x06, 0x1, 0}, + {0x07, 0x1, 0}, + {0x08, 0x1, 0}, + {0x09, 0x69, 0}, + {0x0A, 0x66, 0}, + {0x0B, 0x6, 0}, + {0x0C, 0x18, 0}, + {0x0D, 0x3, 0}, + {0x0E, 0x20, 0}, + {0x0F, 0x20, 0}, + {0x10, 0, 0}, + {0x11, 0x7c, 0}, + {0x12, 0x42, 0}, + {0x13, 0xbd, 0}, + {0x14, 0x7, 0}, + {0x15, 0x87, 0}, + {0x16, 0x8, 0}, + {0x17, 0x17, 0}, + {0x18, 0x7, 0}, + {0x19, 0, 0}, + {0x1A, 0x2, 0}, + {0x1B, 0x13, 0}, + {0x1C, 0x3e, 0}, + {0x1D, 0x3e, 0}, + {0x1E, 0x96, 0}, + {0x1F, 0x4, 0}, + {0x20, 0, 0}, + {0x21, 0, 0}, + {0x22, 0x17, 0}, + {0x23, 0x6, 1}, + {0x24, 0x1, 0}, + {0x25, 0x6, 0}, + {0x26, 0x4, 0}, + {0x27, 0xd, 0}, + {0x28, 0xd, 0}, + {0x29, 0x30, 0}, + {0x2A, 0x32, 0}, + {0x2B, 0x8, 0}, + {0x2C, 0x1c, 0}, + {0x2D, 0x2, 0}, + {0x2E, 0x4, 0}, + {0x2F, 0x7f, 0}, + {0x30, 0x27, 0}, + {0x31, 0, 1}, + {0x32, 0, 1}, + {0x33, 0, 1}, + {0x34, 0, 0}, + {0x35, 0x20, 0}, + {0x36, 0x18, 0}, + {0x37, 0x7, 0}, + {0x38, 0x66, 0}, + {0x39, 0x66, 0}, + {0x3C, 0xff, 0}, + {0x3D, 0xff, 0}, + {0x40, 0x16, 0}, + {0x41, 0x7, 0}, + {0x45, 0x3, 0}, + {0x46, 0x1, 0}, + {0x47, 0x7, 0}, + {0x4B, 0x66, 0}, + {0x4C, 0x66, 0}, + {0x4D, 0, 0}, + {0x4E, 0x4, 0}, + {0x4F, 0xc, 0}, + {0x50, 0, 0}, + {0x51, 0x70, 1}, + {0x56, 0x7, 0}, + {0x57, 0, 0}, + {0x58, 0, 0}, + {0x59, 0x88, 1}, + {0x5A, 0, 0}, + {0x5B, 0x1f, 0}, + {0x5C, 0x20, 1}, + {0x5D, 0x1, 0}, + {0x5E, 0x30, 0}, + {0x5F, 0x70, 0}, + {0x60, 0, 0}, + {0x61, 0, 0}, + {0x62, 0x33, 1}, + {0x63, 0xf, 1}, + {0x64, 0xf, 1}, + {0x65, 0, 0}, + {0x66, 0x11, 0}, + {0x80, 0x3c, 0}, + {0x81, 0x1, 1}, + {0x82, 0xa, 0}, + {0x85, 0, 0}, + {0x86, 0x40, 0}, + {0x87, 0x40, 0}, + {0x88, 0x88, 0}, + {0x89, 0x10, 0}, + {0x8A, 0xf0, 0}, + {0x8B, 0x10, 0}, + {0x8C, 0xf0, 0}, + {0x8F, 0x10, 0}, + {0x90, 0x55, 0}, + {0x91, 0x3f, 1}, + {0x92, 0x36, 1}, + {0x93, 0, 0}, + {0x94, 0, 0}, + {0x95, 0, 0}, + {0x96, 0x87, 0}, + {0x97, 0x11, 0}, + {0x98, 0, 0}, + {0x99, 0x33, 0}, + {0x9A, 0x88, 0}, + {0xA1, 0x20, 1}, + {0xA2, 0x3f, 0}, + {0xA3, 0x44, 0}, + {0xA4, 0x8c, 0}, + {0xA5, 0x6c, 0}, + {0xA6, 0x22, 0}, + {0xA7, 0xbe, 0}, + {0xA8, 0x55, 0}, + {0xAA, 0xc, 0}, + {0xAB, 0xaa, 0}, + {0xAC, 0x2, 0}, + {0xAD, 0, 0}, + {0xAE, 0x10, 0}, + {0xAF, 0x1, 0}, + {0xB0, 0, 0}, + {0xB1, 0, 0}, + {0xB2, 0x80, 0}, + {0xB3, 0x60, 0}, + {0xB4, 0x44, 0}, + {0xB5, 0x55, 0}, + {0xB6, 0x1, 0}, + {0xB7, 0x55, 0}, + {0xB8, 0x1, 0}, + {0xB9, 0x5, 0}, + {0xBA, 0x55, 0}, + {0xBB, 0x55, 0}, + {0xC3, 0, 0}, + {0xC4, 0, 0}, + {0xC5, 0, 0}, + {0xC6, 0, 0}, + {0xC7, 0, 0}, + {0xC8, 0, 0}, + {0xC9, 0, 0}, + {0xCA, 0, 0}, + {0xCB, 0, 0}, + {0xCD, 0, 0}, + {0xCE, 0x5e, 0}, + {0xCF, 0xc, 0}, + {0xD0, 0xc, 0}, + {0xD1, 0xc, 0}, + {0xD2, 0, 0}, + {0xD3, 0x2b, 0}, + {0xD4, 0xc, 0}, + {0xD5, 0, 0}, + {0xD6, 0x70, 1}, + {0xDB, 0x7, 0}, + {0xDC, 0, 0}, + {0xDD, 0, 0}, + {0xDE, 0x88, 1}, + {0xDF, 0, 0}, + {0xE0, 0x1f, 0}, + {0xE1, 0x20, 1}, + {0xE2, 0x1, 0}, + {0xE3, 0x30, 0}, + {0xE4, 0x70, 0}, + {0xE5, 0, 0}, + {0xE6, 0, 0}, + {0xE7, 0x33, 0}, + {0xE8, 0xf, 1}, + {0xE9, 0xf, 1}, + {0xEA, 0, 0}, + {0xEB, 0x11, 0}, + {0x105, 0x3c, 0}, + {0x106, 0x1, 1}, + {0x107, 0xa, 0}, + {0x10A, 0, 0}, + {0x10B, 0x40, 0}, + {0x10C, 0x40, 0}, + {0x10D, 0x88, 0}, + {0x10E, 0x10, 0}, + {0x10F, 0xf0, 0}, + {0x110, 0x10, 0}, + {0x111, 0xf0, 0}, + {0x114, 0x10, 0}, + {0x115, 0x55, 0}, + {0x116, 0x3f, 1}, + {0x117, 0x36, 1}, + {0x118, 0, 0}, + {0x119, 0, 0}, + {0x11A, 0, 0}, + {0x11B, 0x87, 0}, + {0x11C, 0x11, 0}, + {0x11D, 0, 0}, + {0x11E, 0x33, 0}, + {0x11F, 0x88, 0}, + {0x126, 0x20, 1}, + {0x127, 0x3f, 0}, + {0x128, 0x44, 0}, + {0x129, 0x8c, 0}, + {0x12A, 0x6c, 0}, + {0x12B, 0x22, 0}, + {0x12C, 0xbe, 0}, + {0x12D, 0x55, 0}, + {0x12F, 0xc, 0}, + {0x130, 0xaa, 0}, + {0x131, 0x2, 0}, + {0x132, 0, 0}, + {0x133, 0x10, 0}, + {0x134, 0x1, 0}, + {0x135, 0, 0}, + {0x136, 0, 0}, + {0x137, 0x80, 0}, + {0x138, 0x60, 0}, + {0x139, 0x44, 0}, + {0x13A, 0x55, 0}, + {0x13B, 0x1, 0}, + {0x13C, 0x55, 0}, + {0x13D, 0x1, 0}, + {0x13E, 0x5, 0}, + {0x13F, 0x55, 0}, + {0x140, 0x55, 0}, + {0x148, 0, 0}, + {0x149, 0, 0}, + {0x14A, 0, 0}, + {0x14B, 0, 0}, + {0x14C, 0, 0}, + {0x14D, 0, 0}, + {0x14E, 0, 0}, + {0x14F, 0, 0}, + {0x150, 0, 0}, + {0x154, 0xc, 0}, + {0x155, 0xc, 0}, + {0x156, 0xc, 0}, + {0x157, 0, 0}, + {0x158, 0x2b, 0}, + {0x159, 0x84, 0}, + {0x15A, 0x15, 0}, + {0x15B, 0xf, 0}, + {0x15C, 0, 0}, + {0x15D, 0, 0}, + {0x15E, 0, 1}, + {0x15F, 0, 1}, + {0x160, 0, 1}, + {0x161, 0, 1}, + {0x162, 0, 1}, + {0x163, 0, 1}, + {0x164, 0, 0}, + {0x165, 0, 0}, + {0x166, 0, 0}, + {0x167, 0, 0}, + {0x168, 0, 0}, + {0x169, 0, 0}, + {0x16A, 0, 1}, + {0x16B, 0, 1}, + {0x16C, 0, 1}, + {0x16D, 0, 0}, + {0x170, 0, 0}, + {0x171, 0x77, 0}, + {0x172, 0x77, 0}, + {0x173, 0x77, 0}, + {0x174, 0x77, 0}, + {0x175, 0, 0}, + {0x176, 0x3, 0}, + {0x177, 0x37, 0}, + {0x178, 0x3, 0}, + {0x179, 0, 0}, + {0x17B, 0x21, 0}, + {0x17C, 0, 0}, + {0x17D, 0xaa, 0}, + {0x17E, 0, 0}, + {0x190, 0, 0}, + {0x191, 0x77, 0}, + {0x192, 0x77, 0}, + {0x193, 0x77, 0}, + {0x194, 0x77, 0}, + {0x195, 0, 0}, + {0x196, 0x3, 0}, + {0x197, 0x37, 0}, + {0x198, 0x3, 0}, + {0x199, 0, 0}, + {0x19B, 0x21, 0}, + {0x19C, 0, 0}, + {0x19D, 0xaa, 0}, + {0x19E, 0, 0}, + {0x1A1, 0x2, 0}, + {0x1A2, 0xf, 0}, + {0x1A3, 0xf, 0}, + {0x1A4, 0, 1}, + {0x1A5, 0, 1}, + {0x1A6, 0, 1}, + {0x1A7, 0x2, 0}, + {0x1A8, 0xf, 0}, + {0x1A9, 0xf, 0}, + {0x1AA, 0, 1}, + {0x1AB, 0, 1}, + {0x1AC, 0, 1}, + {0x1AD, 0x84, 0}, + {0x1AE, 0x60, 0}, + {0x1AF, 0x47, 0}, + {0x1B0, 0x47, 0}, + {0x1B1, 0, 0}, + {0x1B2, 0, 0}, + {0x1B3, 0, 0}, + {0x1B4, 0, 0}, + {0x1B5, 0, 0}, + {0x1B6, 0, 0}, + {0x1B7, 0xc, 1}, + {0x1B8, 0, 0}, + {0x1B9, 0, 0}, + {0x1BA, 0, 0}, + {0x1BB, 0, 0}, + {0x1BC, 0, 0}, + {0x1BD, 0, 0}, + {0x1BE, 0, 0}, + {0x1BF, 0, 0}, + {0x1C0, 0, 0}, + {0x1C1, 0x1, 1}, + {0x1C2, 0x80, 1}, + {0x1C3, 0, 0}, + {0x1C4, 0, 0}, + {0x1C5, 0, 0}, + {0x1C6, 0, 0}, + {0x1C7, 0, 0}, + {0x1C8, 0, 0}, + {0x1C9, 0, 0}, + {0x1CA, 0, 0}, + {0xFFFF, 0, 0} +}; + +radio_20xx_regs_t regs_2057_rev5v1[] = { + {0x00, 0x15, 1}, + {0x01, 0x57, 1}, + {0x02, 0x20, 1}, + {0x03, 0x1f, 0}, + {0x04, 0x4, 0}, + {0x05, 0x2, 0}, + {0x06, 0x1, 0}, + {0x07, 0x1, 0}, + {0x08, 0x1, 0}, + {0x09, 0x69, 0}, + {0x0A, 0x66, 0}, + {0x0B, 0x6, 0}, + {0x0C, 0x18, 0}, + {0x0D, 0x3, 0}, + {0x0E, 0x20, 0}, + {0x0F, 0x20, 0}, + {0x10, 0, 0}, + {0x11, 0x7c, 0}, + {0x12, 0x42, 0}, + {0x13, 0xbd, 0}, + {0x14, 0x7, 0}, + {0x15, 0x87, 0}, + {0x16, 0x8, 0}, + {0x17, 0x17, 0}, + {0x18, 0x7, 0}, + {0x19, 0, 0}, + {0x1A, 0x2, 0}, + {0x1B, 0x13, 0}, + {0x1C, 0x3e, 0}, + {0x1D, 0x3e, 0}, + {0x1E, 0x96, 0}, + {0x1F, 0x4, 0}, + {0x20, 0, 0}, + {0x21, 0, 0}, + {0x22, 0x17, 0}, + {0x23, 0x6, 1}, + {0x24, 0x1, 0}, + {0x25, 0x6, 0}, + {0x26, 0x4, 0}, + {0x27, 0xd, 0}, + {0x28, 0xd, 0}, + {0x29, 0x30, 0}, + {0x2A, 0x32, 0}, + {0x2B, 0x8, 0}, + {0x2C, 0x1c, 0}, + {0x2D, 0x2, 0}, + {0x2E, 0x4, 0}, + {0x2F, 0x7f, 0}, + {0x30, 0x27, 0}, + {0x31, 0, 1}, + {0x32, 0, 1}, + {0x33, 0, 1}, + {0x34, 0, 0}, + {0x35, 0x20, 0}, + {0x36, 0x18, 0}, + {0x37, 0x7, 0}, + {0x38, 0x66, 0}, + {0x39, 0x66, 0}, + {0x3C, 0xff, 0}, + {0x3D, 0xff, 0}, + {0x40, 0x16, 0}, + {0x41, 0x7, 0}, + {0x45, 0x3, 0}, + {0x46, 0x1, 0}, + {0x47, 0x7, 0}, + {0x4B, 0x66, 0}, + {0x4C, 0x66, 0}, + {0x4D, 0, 0}, + {0x4E, 0x4, 0}, + {0x4F, 0xc, 0}, + {0x50, 0, 0}, + {0x51, 0x70, 1}, + {0x56, 0x7, 0}, + {0x57, 0, 0}, + {0x58, 0, 0}, + {0x59, 0x88, 1}, + {0x5A, 0, 0}, + {0x5B, 0x1f, 0}, + {0x5C, 0x20, 1}, + {0x5D, 0x1, 0}, + {0x5E, 0x30, 0}, + {0x5F, 0x70, 0}, + {0x60, 0, 0}, + {0x61, 0, 0}, + {0x62, 0x33, 1}, + {0x63, 0xf, 1}, + {0x64, 0xf, 1}, + {0x65, 0, 0}, + {0x66, 0x11, 0}, + {0x80, 0x3c, 0}, + {0x81, 0x1, 1}, + {0x82, 0xa, 0}, + {0x85, 0, 0}, + {0x86, 0x40, 0}, + {0x87, 0x40, 0}, + {0x88, 0x88, 0}, + {0x89, 0x10, 0}, + {0x8A, 0xf0, 0}, + {0x8B, 0x10, 0}, + {0x8C, 0xf0, 0}, + {0x8F, 0x10, 0}, + {0x90, 0x55, 0}, + {0x91, 0x3f, 1}, + {0x92, 0x36, 1}, + {0x93, 0, 0}, + {0x94, 0, 0}, + {0x95, 0, 0}, + {0x96, 0x87, 0}, + {0x97, 0x11, 0}, + {0x98, 0, 0}, + {0x99, 0x33, 0}, + {0x9A, 0x88, 0}, + {0xA1, 0x20, 1}, + {0xA2, 0x3f, 0}, + {0xA3, 0x44, 0}, + {0xA4, 0x8c, 0}, + {0xA5, 0x6c, 0}, + {0xA6, 0x22, 0}, + {0xA7, 0xbe, 0}, + {0xA8, 0x55, 0}, + {0xAA, 0xc, 0}, + {0xAB, 0xaa, 0}, + {0xAC, 0x2, 0}, + {0xAD, 0, 0}, + {0xAE, 0x10, 0}, + {0xAF, 0x1, 0}, + {0xB0, 0, 0}, + {0xB1, 0, 0}, + {0xB2, 0x80, 0}, + {0xB3, 0x60, 0}, + {0xB4, 0x44, 0}, + {0xB5, 0x55, 0}, + {0xB6, 0x1, 0}, + {0xB7, 0x55, 0}, + {0xB8, 0x1, 0}, + {0xB9, 0x5, 0}, + {0xBA, 0x55, 0}, + {0xBB, 0x55, 0}, + {0xC3, 0, 0}, + {0xC4, 0, 0}, + {0xC5, 0, 0}, + {0xC6, 0, 0}, + {0xC7, 0, 0}, + {0xC8, 0, 0}, + {0xC9, 0x1, 1}, + {0xCA, 0, 0}, + {0xCB, 0, 0}, + {0xCD, 0, 0}, + {0xCE, 0x5e, 0}, + {0xCF, 0xc, 0}, + {0xD0, 0xc, 0}, + {0xD1, 0xc, 0}, + {0xD2, 0, 0}, + {0xD3, 0x2b, 0}, + {0xD4, 0xc, 0}, + {0xD5, 0, 0}, + {0xD6, 0x70, 1}, + {0xDB, 0x7, 0}, + {0xDC, 0, 0}, + {0xDD, 0, 0}, + {0xDE, 0x88, 1}, + {0xDF, 0, 0}, + {0xE0, 0x1f, 0}, + {0xE1, 0x20, 1}, + {0xE2, 0x1, 0}, + {0xE3, 0x30, 0}, + {0xE4, 0x70, 0}, + {0xE5, 0, 0}, + {0xE6, 0, 0}, + {0xE7, 0x33, 0}, + {0xE8, 0xf, 1}, + {0xE9, 0xf, 1}, + {0xEA, 0, 0}, + {0xEB, 0x11, 0}, + {0x105, 0x3c, 0}, + {0x106, 0x1, 1}, + {0x107, 0xa, 0}, + {0x10A, 0, 0}, + {0x10B, 0x40, 0}, + {0x10C, 0x40, 0}, + {0x10D, 0x88, 0}, + {0x10E, 0x10, 0}, + {0x10F, 0xf0, 0}, + {0x110, 0x10, 0}, + {0x111, 0xf0, 0}, + {0x114, 0x10, 0}, + {0x115, 0x55, 0}, + {0x116, 0x3f, 1}, + {0x117, 0x36, 1}, + {0x118, 0, 0}, + {0x119, 0, 0}, + {0x11A, 0, 0}, + {0x11B, 0x87, 0}, + {0x11C, 0x11, 0}, + {0x11D, 0, 0}, + {0x11E, 0x33, 0}, + {0x11F, 0x88, 0}, + {0x126, 0x20, 1}, + {0x127, 0x3f, 0}, + {0x128, 0x44, 0}, + {0x129, 0x8c, 0}, + {0x12A, 0x6c, 0}, + {0x12B, 0x22, 0}, + {0x12C, 0xbe, 0}, + {0x12D, 0x55, 0}, + {0x12F, 0xc, 0}, + {0x130, 0xaa, 0}, + {0x131, 0x2, 0}, + {0x132, 0, 0}, + {0x133, 0x10, 0}, + {0x134, 0x1, 0}, + {0x135, 0, 0}, + {0x136, 0, 0}, + {0x137, 0x80, 0}, + {0x138, 0x60, 0}, + {0x139, 0x44, 0}, + {0x13A, 0x55, 0}, + {0x13B, 0x1, 0}, + {0x13C, 0x55, 0}, + {0x13D, 0x1, 0}, + {0x13E, 0x5, 0}, + {0x13F, 0x55, 0}, + {0x140, 0x55, 0}, + {0x148, 0, 0}, + {0x149, 0, 0}, + {0x14A, 0, 0}, + {0x14B, 0, 0}, + {0x14C, 0, 0}, + {0x14D, 0, 0}, + {0x14E, 0x1, 1}, + {0x14F, 0, 0}, + {0x150, 0, 0}, + {0x154, 0xc, 0}, + {0x155, 0xc, 0}, + {0x156, 0xc, 0}, + {0x157, 0, 0}, + {0x158, 0x2b, 0}, + {0x159, 0x84, 0}, + {0x15A, 0x15, 0}, + {0x15B, 0xf, 0}, + {0x15C, 0, 0}, + {0x15D, 0, 0}, + {0x15E, 0, 1}, + {0x15F, 0, 1}, + {0x160, 0, 1}, + {0x161, 0, 1}, + {0x162, 0, 1}, + {0x163, 0, 1}, + {0x164, 0, 0}, + {0x165, 0, 0}, + {0x166, 0, 0}, + {0x167, 0, 0}, + {0x168, 0, 0}, + {0x169, 0, 0}, + {0x16A, 0, 1}, + {0x16B, 0, 1}, + {0x16C, 0, 1}, + {0x16D, 0, 0}, + {0x170, 0, 0}, + {0x171, 0x77, 0}, + {0x172, 0x77, 0}, + {0x173, 0x77, 0}, + {0x174, 0x77, 0}, + {0x175, 0, 0}, + {0x176, 0x3, 0}, + {0x177, 0x37, 0}, + {0x178, 0x3, 0}, + {0x179, 0, 0}, + {0x17B, 0x21, 0}, + {0x17C, 0, 0}, + {0x17D, 0xaa, 0}, + {0x17E, 0, 0}, + {0x190, 0, 0}, + {0x191, 0x77, 0}, + {0x192, 0x77, 0}, + {0x193, 0x77, 0}, + {0x194, 0x77, 0}, + {0x195, 0, 0}, + {0x196, 0x3, 0}, + {0x197, 0x37, 0}, + {0x198, 0x3, 0}, + {0x199, 0, 0}, + {0x19B, 0x21, 0}, + {0x19C, 0, 0}, + {0x19D, 0xaa, 0}, + {0x19E, 0, 0}, + {0x1A1, 0x2, 0}, + {0x1A2, 0xf, 0}, + {0x1A3, 0xf, 0}, + {0x1A4, 0, 1}, + {0x1A5, 0, 1}, + {0x1A6, 0, 1}, + {0x1A7, 0x2, 0}, + {0x1A8, 0xf, 0}, + {0x1A9, 0xf, 0}, + {0x1AA, 0, 1}, + {0x1AB, 0, 1}, + {0x1AC, 0, 1}, + {0x1AD, 0x84, 0}, + {0x1AE, 0x60, 0}, + {0x1AF, 0x47, 0}, + {0x1B0, 0x47, 0}, + {0x1B1, 0, 0}, + {0x1B2, 0, 0}, + {0x1B3, 0, 0}, + {0x1B4, 0, 0}, + {0x1B5, 0, 0}, + {0x1B6, 0, 0}, + {0x1B7, 0xc, 1}, + {0x1B8, 0, 0}, + {0x1B9, 0, 0}, + {0x1BA, 0, 0}, + {0x1BB, 0, 0}, + {0x1BC, 0, 0}, + {0x1BD, 0, 0}, + {0x1BE, 0, 0}, + {0x1BF, 0, 0}, + {0x1C0, 0, 0}, + {0x1C1, 0x1, 1}, + {0x1C2, 0x80, 1}, + {0x1C3, 0, 0}, + {0x1C4, 0, 0}, + {0x1C5, 0, 0}, + {0x1C6, 0, 0}, + {0x1C7, 0, 0}, + {0x1C8, 0, 0}, + {0x1C9, 0, 0}, + {0x1CA, 0, 0}, + {0xFFFF, 0, 0} +}; + +radio_20xx_regs_t regs_2057_rev7[] = { + {0x00, 0, 1}, + {0x01, 0x57, 1}, + {0x02, 0x20, 1}, + {0x03, 0x1f, 0}, + {0x04, 0x4, 0}, + {0x05, 0x2, 0}, + {0x06, 0x1, 0}, + {0x07, 0x1, 0}, + {0x08, 0x1, 0}, + {0x09, 0x69, 0}, + {0x0A, 0x66, 0}, + {0x0B, 0x6, 0}, + {0x0C, 0x18, 0}, + {0x0D, 0x3, 0}, + {0x0E, 0x20, 0}, + {0x0F, 0x20, 0}, + {0x10, 0, 0}, + {0x11, 0x7c, 0}, + {0x12, 0x42, 0}, + {0x13, 0xbd, 0}, + {0x14, 0x7, 0}, + {0x15, 0x87, 0}, + {0x16, 0x8, 0}, + {0x17, 0x17, 0}, + {0x18, 0x7, 0}, + {0x19, 0, 0}, + {0x1A, 0x2, 0}, + {0x1B, 0x13, 0}, + {0x1C, 0x3e, 0}, + {0x1D, 0x3e, 0}, + {0x1E, 0x96, 0}, + {0x1F, 0x4, 0}, + {0x20, 0, 0}, + {0x21, 0, 0}, + {0x22, 0x17, 0}, + {0x23, 0x6, 0}, + {0x24, 0x1, 0}, + {0x25, 0x6, 0}, + {0x26, 0x4, 0}, + {0x27, 0xd, 0}, + {0x28, 0xd, 0}, + {0x29, 0x30, 0}, + {0x2A, 0x32, 0}, + {0x2B, 0x8, 0}, + {0x2C, 0x1c, 0}, + {0x2D, 0x2, 0}, + {0x2E, 0x4, 0}, + {0x2F, 0x7f, 0}, + {0x30, 0x27, 0}, + {0x31, 0, 1}, + {0x32, 0, 1}, + {0x33, 0, 1}, + {0x34, 0, 0}, + {0x35, 0x20, 0}, + {0x36, 0x18, 0}, + {0x37, 0x7, 0}, + {0x38, 0x66, 0}, + {0x39, 0x66, 0}, + {0x3A, 0x66, 0}, + {0x3B, 0x66, 0}, + {0x3C, 0xff, 0}, + {0x3D, 0xff, 0}, + {0x3E, 0xff, 0}, + {0x3F, 0xff, 0}, + {0x40, 0x16, 0}, + {0x41, 0x7, 0}, + {0x42, 0x19, 0}, + {0x43, 0x7, 0}, + {0x44, 0x6, 0}, + {0x45, 0x3, 0}, + {0x46, 0x1, 0}, + {0x47, 0x7, 0}, + {0x48, 0x33, 0}, + {0x49, 0x5, 0}, + {0x4A, 0x77, 0}, + {0x4B, 0x66, 0}, + {0x4C, 0x66, 0}, + {0x4D, 0, 0}, + {0x4E, 0x4, 0}, + {0x4F, 0xc, 0}, + {0x50, 0, 0}, + {0x51, 0x70, 1}, + {0x56, 0x7, 0}, + {0x57, 0, 0}, + {0x58, 0, 0}, + {0x59, 0x88, 1}, + {0x5A, 0, 0}, + {0x5B, 0x1f, 0}, + {0x5C, 0x20, 1}, + {0x5D, 0x1, 0}, + {0x5E, 0x30, 0}, + {0x5F, 0x70, 0}, + {0x60, 0, 0}, + {0x61, 0, 0}, + {0x62, 0x33, 1}, + {0x63, 0xf, 1}, + {0x64, 0x13, 1}, + {0x65, 0, 0}, + {0x66, 0xee, 1}, + {0x69, 0, 0}, + {0x6A, 0x7e, 0}, + {0x6B, 0x3f, 0}, + {0x6C, 0x7f, 0}, + {0x6D, 0x78, 0}, + {0x6E, 0x58, 1}, + {0x6F, 0x88, 0}, + {0x70, 0x8, 0}, + {0x71, 0xf, 0}, + {0x72, 0xbc, 0}, + {0x73, 0x8, 0}, + {0x74, 0x60, 0}, + {0x75, 0x13, 1}, + {0x76, 0x70, 0}, + {0x77, 0, 0}, + {0x78, 0, 0}, + {0x79, 0, 0}, + {0x7A, 0x33, 0}, + {0x7B, 0x13, 1}, + {0x7C, 0x14, 1}, + {0x7D, 0xee, 1}, + {0x80, 0x3c, 0}, + {0x81, 0x1, 1}, + {0x82, 0xa, 0}, + {0x83, 0x9d, 0}, + {0x84, 0xa, 0}, + {0x85, 0, 0}, + {0x86, 0x40, 0}, + {0x87, 0x40, 0}, + {0x88, 0x88, 0}, + {0x89, 0x10, 0}, + {0x8A, 0xf0, 0}, + {0x8B, 0x10, 0}, + {0x8C, 0xf0, 0}, + {0x8D, 0, 0}, + {0x8E, 0, 0}, + {0x8F, 0x10, 0}, + {0x90, 0x55, 0}, + {0x91, 0x3f, 1}, + {0x92, 0x36, 1}, + {0x93, 0, 0}, + {0x94, 0, 0}, + {0x95, 0, 0}, + {0x96, 0x87, 0}, + {0x97, 0x11, 0}, + {0x98, 0, 0}, + {0x99, 0x33, 0}, + {0x9A, 0x88, 0}, + {0x9B, 0, 0}, + {0x9C, 0x87, 0}, + {0x9D, 0x11, 0}, + {0x9E, 0, 0}, + {0x9F, 0x33, 0}, + {0xA0, 0x88, 0}, + {0xA1, 0x20, 1}, + {0xA2, 0x3f, 0}, + {0xA3, 0x44, 0}, + {0xA4, 0x8c, 0}, + {0xA5, 0x6c, 0}, + {0xA6, 0x22, 0}, + {0xA7, 0xbe, 0}, + {0xA8, 0x55, 0}, + {0xAA, 0xc, 0}, + {0xAB, 0xaa, 0}, + {0xAC, 0x2, 0}, + {0xAD, 0, 0}, + {0xAE, 0x10, 0}, + {0xAF, 0x1, 0}, + {0xB0, 0, 0}, + {0xB1, 0, 0}, + {0xB2, 0x80, 0}, + {0xB3, 0x60, 0}, + {0xB4, 0x44, 0}, + {0xB5, 0x55, 0}, + {0xB6, 0x1, 0}, + {0xB7, 0x55, 0}, + {0xB8, 0x1, 0}, + {0xB9, 0x5, 0}, + {0xBA, 0x55, 0}, + {0xBB, 0x55, 0}, + {0xC1, 0, 0}, + {0xC2, 0, 0}, + {0xC3, 0, 0}, + {0xC4, 0, 0}, + {0xC5, 0, 0}, + {0xC6, 0, 0}, + {0xC7, 0, 0}, + {0xC8, 0, 0}, + {0xC9, 0, 0}, + {0xCA, 0, 0}, + {0xCB, 0, 0}, + {0xCC, 0, 0}, + {0xCD, 0, 0}, + {0xCE, 0x5e, 0}, + {0xCF, 0xc, 0}, + {0xD0, 0xc, 0}, + {0xD1, 0xc, 0}, + {0xD2, 0, 0}, + {0xD3, 0x2b, 0}, + {0xD4, 0xc, 0}, + {0xD5, 0, 0}, + {0xD6, 0x70, 1}, + {0xDB, 0x7, 0}, + {0xDC, 0, 0}, + {0xDD, 0, 0}, + {0xDE, 0x88, 1}, + {0xDF, 0, 0}, + {0xE0, 0x1f, 0}, + {0xE1, 0x20, 1}, + {0xE2, 0x1, 0}, + {0xE3, 0x30, 0}, + {0xE4, 0x70, 0}, + {0xE5, 0, 0}, + {0xE6, 0, 0}, + {0xE7, 0x33, 0}, + {0xE8, 0xf, 1}, + {0xE9, 0x13, 1}, + {0xEA, 0, 0}, + {0xEB, 0xee, 1}, + {0xEE, 0, 0}, + {0xEF, 0x7e, 0}, + {0xF0, 0x3f, 0}, + {0xF1, 0x7f, 0}, + {0xF2, 0x78, 0}, + {0xF3, 0x58, 1}, + {0xF4, 0x88, 0}, + {0xF5, 0x8, 0}, + {0xF6, 0xf, 0}, + {0xF7, 0xbc, 0}, + {0xF8, 0x8, 0}, + {0xF9, 0x60, 0}, + {0xFA, 0x13, 1}, + {0xFB, 0x70, 0}, + {0xFC, 0, 0}, + {0xFD, 0, 0}, + {0xFE, 0, 0}, + {0xFF, 0x33, 0}, + {0x100, 0x13, 1}, + {0x101, 0x14, 1}, + {0x102, 0xee, 1}, + {0x105, 0x3c, 0}, + {0x106, 0x1, 1}, + {0x107, 0xa, 0}, + {0x108, 0x9d, 0}, + {0x109, 0xa, 0}, + {0x10A, 0, 0}, + {0x10B, 0x40, 0}, + {0x10C, 0x40, 0}, + {0x10D, 0x88, 0}, + {0x10E, 0x10, 0}, + {0x10F, 0xf0, 0}, + {0x110, 0x10, 0}, + {0x111, 0xf0, 0}, + {0x112, 0, 0}, + {0x113, 0, 0}, + {0x114, 0x10, 0}, + {0x115, 0x55, 0}, + {0x116, 0x3f, 1}, + {0x117, 0x36, 1}, + {0x118, 0, 0}, + {0x119, 0, 0}, + {0x11A, 0, 0}, + {0x11B, 0x87, 0}, + {0x11C, 0x11, 0}, + {0x11D, 0, 0}, + {0x11E, 0x33, 0}, + {0x11F, 0x88, 0}, + {0x120, 0, 0}, + {0x121, 0x87, 0}, + {0x122, 0x11, 0}, + {0x123, 0, 0}, + {0x124, 0x33, 0}, + {0x125, 0x88, 0}, + {0x126, 0x20, 1}, + {0x127, 0x3f, 0}, + {0x128, 0x44, 0}, + {0x129, 0x8c, 0}, + {0x12A, 0x6c, 0}, + {0x12B, 0x22, 0}, + {0x12C, 0xbe, 0}, + {0x12D, 0x55, 0}, + {0x12F, 0xc, 0}, + {0x130, 0xaa, 0}, + {0x131, 0x2, 0}, + {0x132, 0, 0}, + {0x133, 0x10, 0}, + {0x134, 0x1, 0}, + {0x135, 0, 0}, + {0x136, 0, 0}, + {0x137, 0x80, 0}, + {0x138, 0x60, 0}, + {0x139, 0x44, 0}, + {0x13A, 0x55, 0}, + {0x13B, 0x1, 0}, + {0x13C, 0x55, 0}, + {0x13D, 0x1, 0}, + {0x13E, 0x5, 0}, + {0x13F, 0x55, 0}, + {0x140, 0x55, 0}, + {0x146, 0, 0}, + {0x147, 0, 0}, + {0x148, 0, 0}, + {0x149, 0, 0}, + {0x14A, 0, 0}, + {0x14B, 0, 0}, + {0x14C, 0, 0}, + {0x14D, 0, 0}, + {0x14E, 0, 0}, + {0x14F, 0, 0}, + {0x150, 0, 0}, + {0x151, 0, 0}, + {0x154, 0xc, 0}, + {0x155, 0xc, 0}, + {0x156, 0xc, 0}, + {0x157, 0, 0}, + {0x158, 0x2b, 0}, + {0x159, 0x84, 0}, + {0x15A, 0x15, 0}, + {0x15B, 0xf, 0}, + {0x15C, 0, 0}, + {0x15D, 0, 0}, + {0x15E, 0, 1}, + {0x15F, 0, 1}, + {0x160, 0, 1}, + {0x161, 0, 1}, + {0x162, 0, 1}, + {0x163, 0, 1}, + {0x164, 0, 0}, + {0x165, 0, 0}, + {0x166, 0, 0}, + {0x167, 0, 0}, + {0x168, 0, 0}, + {0x169, 0, 0}, + {0x16A, 0, 1}, + {0x16B, 0, 1}, + {0x16C, 0, 1}, + {0x16D, 0, 0}, + {0x170, 0, 0}, + {0x171, 0x77, 0}, + {0x172, 0x77, 0}, + {0x173, 0x77, 0}, + {0x174, 0x77, 0}, + {0x175, 0, 0}, + {0x176, 0x3, 0}, + {0x177, 0x37, 0}, + {0x178, 0x3, 0}, + {0x179, 0, 0}, + {0x17A, 0x21, 0}, + {0x17B, 0x21, 0}, + {0x17C, 0, 0}, + {0x17D, 0xaa, 0}, + {0x17E, 0, 0}, + {0x17F, 0xaa, 0}, + {0x180, 0, 0}, + {0x190, 0, 0}, + {0x191, 0x77, 0}, + {0x192, 0x77, 0}, + {0x193, 0x77, 0}, + {0x194, 0x77, 0}, + {0x195, 0, 0}, + {0x196, 0x3, 0}, + {0x197, 0x37, 0}, + {0x198, 0x3, 0}, + {0x199, 0, 0}, + {0x19A, 0x21, 0}, + {0x19B, 0x21, 0}, + {0x19C, 0, 0}, + {0x19D, 0xaa, 0}, + {0x19E, 0, 0}, + {0x19F, 0xaa, 0}, + {0x1A0, 0, 0}, + {0x1A1, 0x2, 0}, + {0x1A2, 0xf, 0}, + {0x1A3, 0xf, 0}, + {0x1A4, 0, 1}, + {0x1A5, 0, 1}, + {0x1A6, 0, 1}, + {0x1A7, 0x2, 0}, + {0x1A8, 0xf, 0}, + {0x1A9, 0xf, 0}, + {0x1AA, 0, 1}, + {0x1AB, 0, 1}, + {0x1AC, 0, 1}, + {0x1AD, 0x84, 0}, + {0x1AE, 0x60, 0}, + {0x1AF, 0x47, 0}, + {0x1B0, 0x47, 0}, + {0x1B1, 0, 0}, + {0x1B2, 0, 0}, + {0x1B3, 0, 0}, + {0x1B4, 0, 0}, + {0x1B5, 0, 0}, + {0x1B6, 0, 0}, + {0x1B7, 0x5, 1}, + {0x1B8, 0, 0}, + {0x1B9, 0, 0}, + {0x1BA, 0, 0}, + {0x1BB, 0, 0}, + {0x1BC, 0, 0}, + {0x1BD, 0, 0}, + {0x1BE, 0, 0}, + {0x1BF, 0, 0}, + {0x1C0, 0, 0}, + {0x1C1, 0, 0}, + {0x1C2, 0xa0, 1}, + {0x1C3, 0, 0}, + {0x1C4, 0, 0}, + {0x1C5, 0, 0}, + {0x1C6, 0, 0}, + {0x1C7, 0, 0}, + {0x1C8, 0, 0}, + {0x1C9, 0, 0}, + {0x1CA, 0, 0}, + {0xFFFF, 0, 0} +}; + +radio_20xx_regs_t regs_2057_rev8[] = { + {0x00, 0x8, 1}, + {0x01, 0x57, 1}, + {0x02, 0x20, 1}, + {0x03, 0x1f, 0}, + {0x04, 0x4, 0}, + {0x05, 0x2, 0}, + {0x06, 0x1, 0}, + {0x07, 0x1, 0}, + {0x08, 0x1, 0}, + {0x09, 0x69, 0}, + {0x0A, 0x66, 0}, + {0x0B, 0x6, 0}, + {0x0C, 0x18, 0}, + {0x0D, 0x3, 0}, + {0x0E, 0x20, 0}, + {0x0F, 0x20, 0}, + {0x10, 0, 0}, + {0x11, 0x7c, 0}, + {0x12, 0x42, 0}, + {0x13, 0xbd, 0}, + {0x14, 0x7, 0}, + {0x15, 0x87, 0}, + {0x16, 0x8, 0}, + {0x17, 0x17, 0}, + {0x18, 0x7, 0}, + {0x19, 0, 0}, + {0x1A, 0x2, 0}, + {0x1B, 0x13, 0}, + {0x1C, 0x3e, 0}, + {0x1D, 0x3e, 0}, + {0x1E, 0x96, 0}, + {0x1F, 0x4, 0}, + {0x20, 0, 0}, + {0x21, 0, 0}, + {0x22, 0x17, 0}, + {0x23, 0x6, 0}, + {0x24, 0x1, 0}, + {0x25, 0x6, 0}, + {0x26, 0x4, 0}, + {0x27, 0xd, 0}, + {0x28, 0xd, 0}, + {0x29, 0x30, 0}, + {0x2A, 0x32, 0}, + {0x2B, 0x8, 0}, + {0x2C, 0x1c, 0}, + {0x2D, 0x2, 0}, + {0x2E, 0x4, 0}, + {0x2F, 0x7f, 0}, + {0x30, 0x27, 0}, + {0x31, 0, 1}, + {0x32, 0, 1}, + {0x33, 0, 1}, + {0x34, 0, 0}, + {0x35, 0x20, 0}, + {0x36, 0x18, 0}, + {0x37, 0x7, 0}, + {0x38, 0x66, 0}, + {0x39, 0x66, 0}, + {0x3A, 0x66, 0}, + {0x3B, 0x66, 0}, + {0x3C, 0xff, 0}, + {0x3D, 0xff, 0}, + {0x3E, 0xff, 0}, + {0x3F, 0xff, 0}, + {0x40, 0x16, 0}, + {0x41, 0x7, 0}, + {0x42, 0x19, 0}, + {0x43, 0x7, 0}, + {0x44, 0x6, 0}, + {0x45, 0x3, 0}, + {0x46, 0x1, 0}, + {0x47, 0x7, 0}, + {0x48, 0x33, 0}, + {0x49, 0x5, 0}, + {0x4A, 0x77, 0}, + {0x4B, 0x66, 0}, + {0x4C, 0x66, 0}, + {0x4D, 0, 0}, + {0x4E, 0x4, 0}, + {0x4F, 0xc, 0}, + {0x50, 0, 0}, + {0x51, 0x70, 1}, + {0x56, 0x7, 0}, + {0x57, 0, 0}, + {0x58, 0, 0}, + {0x59, 0x88, 1}, + {0x5A, 0, 0}, + {0x5B, 0x1f, 0}, + {0x5C, 0x20, 1}, + {0x5D, 0x1, 0}, + {0x5E, 0x30, 0}, + {0x5F, 0x70, 0}, + {0x60, 0, 0}, + {0x61, 0, 0}, + {0x62, 0x33, 1}, + {0x63, 0xf, 1}, + {0x64, 0xf, 1}, + {0x65, 0, 0}, + {0x66, 0x11, 0}, + {0x69, 0, 0}, + {0x6A, 0x7e, 0}, + {0x6B, 0x3f, 0}, + {0x6C, 0x7f, 0}, + {0x6D, 0x78, 0}, + {0x6E, 0x58, 1}, + {0x6F, 0x88, 0}, + {0x70, 0x8, 0}, + {0x71, 0xf, 0}, + {0x72, 0xbc, 0}, + {0x73, 0x8, 0}, + {0x74, 0x60, 0}, + {0x75, 0x13, 1}, + {0x76, 0x70, 0}, + {0x77, 0, 0}, + {0x78, 0, 0}, + {0x79, 0, 0}, + {0x7A, 0x33, 0}, + {0x7B, 0x13, 1}, + {0x7C, 0xf, 1}, + {0x7D, 0xee, 1}, + {0x80, 0x3c, 0}, + {0x81, 0x1, 1}, + {0x82, 0xa, 0}, + {0x83, 0x9d, 0}, + {0x84, 0xa, 0}, + {0x85, 0, 0}, + {0x86, 0x40, 0}, + {0x87, 0x40, 0}, + {0x88, 0x88, 0}, + {0x89, 0x10, 0}, + {0x8A, 0xf0, 0}, + {0x8B, 0x10, 0}, + {0x8C, 0xf0, 0}, + {0x8D, 0, 0}, + {0x8E, 0, 0}, + {0x8F, 0x10, 0}, + {0x90, 0x55, 0}, + {0x91, 0x3f, 1}, + {0x92, 0x36, 1}, + {0x93, 0, 0}, + {0x94, 0, 0}, + {0x95, 0, 0}, + {0x96, 0x87, 0}, + {0x97, 0x11, 0}, + {0x98, 0, 0}, + {0x99, 0x33, 0}, + {0x9A, 0x88, 0}, + {0x9B, 0, 0}, + {0x9C, 0x87, 0}, + {0x9D, 0x11, 0}, + {0x9E, 0, 0}, + {0x9F, 0x33, 0}, + {0xA0, 0x88, 0}, + {0xA1, 0x20, 1}, + {0xA2, 0x3f, 0}, + {0xA3, 0x44, 0}, + {0xA4, 0x8c, 0}, + {0xA5, 0x6c, 0}, + {0xA6, 0x22, 0}, + {0xA7, 0xbe, 0}, + {0xA8, 0x55, 0}, + {0xAA, 0xc, 0}, + {0xAB, 0xaa, 0}, + {0xAC, 0x2, 0}, + {0xAD, 0, 0}, + {0xAE, 0x10, 0}, + {0xAF, 0x1, 0}, + {0xB0, 0, 0}, + {0xB1, 0, 0}, + {0xB2, 0x80, 0}, + {0xB3, 0x60, 0}, + {0xB4, 0x44, 0}, + {0xB5, 0x55, 0}, + {0xB6, 0x1, 0}, + {0xB7, 0x55, 0}, + {0xB8, 0x1, 0}, + {0xB9, 0x5, 0}, + {0xBA, 0x55, 0}, + {0xBB, 0x55, 0}, + {0xC1, 0, 0}, + {0xC2, 0, 0}, + {0xC3, 0, 0}, + {0xC4, 0, 0}, + {0xC5, 0, 0}, + {0xC6, 0, 0}, + {0xC7, 0, 0}, + {0xC8, 0, 0}, + {0xC9, 0x1, 1}, + {0xCA, 0, 0}, + {0xCB, 0, 0}, + {0xCC, 0, 0}, + {0xCD, 0, 0}, + {0xCE, 0x5e, 0}, + {0xCF, 0xc, 0}, + {0xD0, 0xc, 0}, + {0xD1, 0xc, 0}, + {0xD2, 0, 0}, + {0xD3, 0x2b, 0}, + {0xD4, 0xc, 0}, + {0xD5, 0, 0}, + {0xD6, 0x70, 1}, + {0xDB, 0x7, 0}, + {0xDC, 0, 0}, + {0xDD, 0, 0}, + {0xDE, 0x88, 1}, + {0xDF, 0, 0}, + {0xE0, 0x1f, 0}, + {0xE1, 0x20, 1}, + {0xE2, 0x1, 0}, + {0xE3, 0x30, 0}, + {0xE4, 0x70, 0}, + {0xE5, 0, 0}, + {0xE6, 0, 0}, + {0xE7, 0x33, 0}, + {0xE8, 0xf, 1}, + {0xE9, 0xf, 1}, + {0xEA, 0, 0}, + {0xEB, 0x11, 0}, + {0xEE, 0, 0}, + {0xEF, 0x7e, 0}, + {0xF0, 0x3f, 0}, + {0xF1, 0x7f, 0}, + {0xF2, 0x78, 0}, + {0xF3, 0x58, 1}, + {0xF4, 0x88, 0}, + {0xF5, 0x8, 0}, + {0xF6, 0xf, 0}, + {0xF7, 0xbc, 0}, + {0xF8, 0x8, 0}, + {0xF9, 0x60, 0}, + {0xFA, 0x13, 1}, + {0xFB, 0x70, 0}, + {0xFC, 0, 0}, + {0xFD, 0, 0}, + {0xFE, 0, 0}, + {0xFF, 0x33, 0}, + {0x100, 0x13, 1}, + {0x101, 0xf, 1}, + {0x102, 0xee, 1}, + {0x105, 0x3c, 0}, + {0x106, 0x1, 1}, + {0x107, 0xa, 0}, + {0x108, 0x9d, 0}, + {0x109, 0xa, 0}, + {0x10A, 0, 0}, + {0x10B, 0x40, 0}, + {0x10C, 0x40, 0}, + {0x10D, 0x88, 0}, + {0x10E, 0x10, 0}, + {0x10F, 0xf0, 0}, + {0x110, 0x10, 0}, + {0x111, 0xf0, 0}, + {0x112, 0, 0}, + {0x113, 0, 0}, + {0x114, 0x10, 0}, + {0x115, 0x55, 0}, + {0x116, 0x3f, 1}, + {0x117, 0x36, 1}, + {0x118, 0, 0}, + {0x119, 0, 0}, + {0x11A, 0, 0}, + {0x11B, 0x87, 0}, + {0x11C, 0x11, 0}, + {0x11D, 0, 0}, + {0x11E, 0x33, 0}, + {0x11F, 0x88, 0}, + {0x120, 0, 0}, + {0x121, 0x87, 0}, + {0x122, 0x11, 0}, + {0x123, 0, 0}, + {0x124, 0x33, 0}, + {0x125, 0x88, 0}, + {0x126, 0x20, 1}, + {0x127, 0x3f, 0}, + {0x128, 0x44, 0}, + {0x129, 0x8c, 0}, + {0x12A, 0x6c, 0}, + {0x12B, 0x22, 0}, + {0x12C, 0xbe, 0}, + {0x12D, 0x55, 0}, + {0x12F, 0xc, 0}, + {0x130, 0xaa, 0}, + {0x131, 0x2, 0}, + {0x132, 0, 0}, + {0x133, 0x10, 0}, + {0x134, 0x1, 0}, + {0x135, 0, 0}, + {0x136, 0, 0}, + {0x137, 0x80, 0}, + {0x138, 0x60, 0}, + {0x139, 0x44, 0}, + {0x13A, 0x55, 0}, + {0x13B, 0x1, 0}, + {0x13C, 0x55, 0}, + {0x13D, 0x1, 0}, + {0x13E, 0x5, 0}, + {0x13F, 0x55, 0}, + {0x140, 0x55, 0}, + {0x146, 0, 0}, + {0x147, 0, 0}, + {0x148, 0, 0}, + {0x149, 0, 0}, + {0x14A, 0, 0}, + {0x14B, 0, 0}, + {0x14C, 0, 0}, + {0x14D, 0, 0}, + {0x14E, 0x1, 1}, + {0x14F, 0, 0}, + {0x150, 0, 0}, + {0x151, 0, 0}, + {0x154, 0xc, 0}, + {0x155, 0xc, 0}, + {0x156, 0xc, 0}, + {0x157, 0, 0}, + {0x158, 0x2b, 0}, + {0x159, 0x84, 0}, + {0x15A, 0x15, 0}, + {0x15B, 0xf, 0}, + {0x15C, 0, 0}, + {0x15D, 0, 0}, + {0x15E, 0, 1}, + {0x15F, 0, 1}, + {0x160, 0, 1}, + {0x161, 0, 1}, + {0x162, 0, 1}, + {0x163, 0, 1}, + {0x164, 0, 0}, + {0x165, 0, 0}, + {0x166, 0, 0}, + {0x167, 0, 0}, + {0x168, 0, 0}, + {0x169, 0, 0}, + {0x16A, 0, 1}, + {0x16B, 0, 1}, + {0x16C, 0, 1}, + {0x16D, 0, 0}, + {0x170, 0, 0}, + {0x171, 0x77, 0}, + {0x172, 0x77, 0}, + {0x173, 0x77, 0}, + {0x174, 0x77, 0}, + {0x175, 0, 0}, + {0x176, 0x3, 0}, + {0x177, 0x37, 0}, + {0x178, 0x3, 0}, + {0x179, 0, 0}, + {0x17A, 0x21, 0}, + {0x17B, 0x21, 0}, + {0x17C, 0, 0}, + {0x17D, 0xaa, 0}, + {0x17E, 0, 0}, + {0x17F, 0xaa, 0}, + {0x180, 0, 0}, + {0x190, 0, 0}, + {0x191, 0x77, 0}, + {0x192, 0x77, 0}, + {0x193, 0x77, 0}, + {0x194, 0x77, 0}, + {0x195, 0, 0}, + {0x196, 0x3, 0}, + {0x197, 0x37, 0}, + {0x198, 0x3, 0}, + {0x199, 0, 0}, + {0x19A, 0x21, 0}, + {0x19B, 0x21, 0}, + {0x19C, 0, 0}, + {0x19D, 0xaa, 0}, + {0x19E, 0, 0}, + {0x19F, 0xaa, 0}, + {0x1A0, 0, 0}, + {0x1A1, 0x2, 0}, + {0x1A2, 0xf, 0}, + {0x1A3, 0xf, 0}, + {0x1A4, 0, 1}, + {0x1A5, 0, 1}, + {0x1A6, 0, 1}, + {0x1A7, 0x2, 0}, + {0x1A8, 0xf, 0}, + {0x1A9, 0xf, 0}, + {0x1AA, 0, 1}, + {0x1AB, 0, 1}, + {0x1AC, 0, 1}, + {0x1AD, 0x84, 0}, + {0x1AE, 0x60, 0}, + {0x1AF, 0x47, 0}, + {0x1B0, 0x47, 0}, + {0x1B1, 0, 0}, + {0x1B2, 0, 0}, + {0x1B3, 0, 0}, + {0x1B4, 0, 0}, + {0x1B5, 0, 0}, + {0x1B6, 0, 0}, + {0x1B7, 0x5, 1}, + {0x1B8, 0, 0}, + {0x1B9, 0, 0}, + {0x1BA, 0, 0}, + {0x1BB, 0, 0}, + {0x1BC, 0, 0}, + {0x1BD, 0, 0}, + {0x1BE, 0, 0}, + {0x1BF, 0, 0}, + {0x1C0, 0, 0}, + {0x1C1, 0, 0}, + {0x1C2, 0xa0, 1}, + {0x1C3, 0, 0}, + {0x1C4, 0, 0}, + {0x1C5, 0, 0}, + {0x1C6, 0, 0}, + {0x1C7, 0, 0}, + {0x1C8, 0, 0}, + {0x1C9, 0, 0}, + {0x1CA, 0, 0}, + {0xFFFF, 0, 0} +}; + +static s16 nphy_def_lnagains[] = { -2, 10, 19, 25 }; + +static s32 nphy_lnagain_est0[] = { -315, 40370 }; +static s32 nphy_lnagain_est1[] = { -224, 23242 }; + +static const u16 tbl_iqcal_gainparams_nphy[2][NPHY_IQCAL_NUMGAINS][8] = { + { + {0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69}, + {0x700, 7, 0, 0, 0x69, 0x69, 0x69, 0x69}, + {0x710, 7, 1, 0, 0x68, 0x68, 0x68, 0x68}, + {0x720, 7, 2, 0, 0x67, 0x67, 0x67, 0x67}, + {0x730, 7, 3, 0, 0x66, 0x66, 0x66, 0x66}, + {0x740, 7, 4, 0, 0x65, 0x65, 0x65, 0x65}, + {0x741, 7, 4, 1, 0x65, 0x65, 0x65, 0x65}, + {0x742, 7, 4, 2, 0x65, 0x65, 0x65, 0x65}, + {0x743, 7, 4, 3, 0x65, 0x65, 0x65, 0x65} + }, + { + {0x000, 7, 0, 0, 0x79, 0x79, 0x79, 0x79}, + {0x700, 7, 0, 0, 0x79, 0x79, 0x79, 0x79}, + {0x710, 7, 1, 0, 0x79, 0x79, 0x79, 0x79}, + {0x720, 7, 2, 0, 0x78, 0x78, 0x78, 0x78}, + {0x730, 7, 3, 0, 0x78, 0x78, 0x78, 0x78}, + {0x740, 7, 4, 0, 0x78, 0x78, 0x78, 0x78}, + {0x741, 7, 4, 1, 0x78, 0x78, 0x78, 0x78}, + {0x742, 7, 4, 2, 0x78, 0x78, 0x78, 0x78}, + {0x743, 7, 4, 3, 0x78, 0x78, 0x78, 0x78} + } +}; + +static const u32 nphy_tpc_txgain[] = { + 0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42, + 0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44, + 0x03c82a42, 0x03c82944, 0x03c82942, 0x03c82844, + 0x03c82842, 0x03c42b44, 0x03c42b42, 0x03c42a44, + 0x03c42a42, 0x03c42944, 0x03c42942, 0x03c42844, + 0x03c42842, 0x03c42744, 0x03c42742, 0x03c42644, + 0x03c42642, 0x03c42544, 0x03c42542, 0x03c42444, + 0x03c42442, 0x03c02b44, 0x03c02b42, 0x03c02a44, + 0x03c02a42, 0x03c02944, 0x03c02942, 0x03c02844, + 0x03c02842, 0x03c02744, 0x03c02742, 0x03b02b44, + 0x03b02b42, 0x03b02a44, 0x03b02a42, 0x03b02944, + 0x03b02942, 0x03b02844, 0x03b02842, 0x03b02744, + 0x03b02742, 0x03b02644, 0x03b02642, 0x03b02544, + 0x03b02542, 0x03a02b44, 0x03a02b42, 0x03a02a44, + 0x03a02a42, 0x03a02944, 0x03a02942, 0x03a02844, + 0x03a02842, 0x03a02744, 0x03a02742, 0x03902b44, + 0x03902b42, 0x03902a44, 0x03902a42, 0x03902944, + 0x03902942, 0x03902844, 0x03902842, 0x03902744, + 0x03902742, 0x03902644, 0x03902642, 0x03902544, + 0x03902542, 0x03802b44, 0x03802b42, 0x03802a44, + 0x03802a42, 0x03802944, 0x03802942, 0x03802844, + 0x03802842, 0x03802744, 0x03802742, 0x03802644, + 0x03802642, 0x03802544, 0x03802542, 0x03802444, + 0x03802442, 0x03802344, 0x03802342, 0x03802244, + 0x03802242, 0x03802144, 0x03802142, 0x03802044, + 0x03802042, 0x03801f44, 0x03801f42, 0x03801e44, + 0x03801e42, 0x03801d44, 0x03801d42, 0x03801c44, + 0x03801c42, 0x03801b44, 0x03801b42, 0x03801a44, + 0x03801a42, 0x03801944, 0x03801942, 0x03801844, + 0x03801842, 0x03801744, 0x03801742, 0x03801644, + 0x03801642, 0x03801544, 0x03801542, 0x03801444, + 0x03801442, 0x03801344, 0x03801342, 0x00002b00 +}; + +static const u16 nphy_tpc_loscale[] = { + 256, 256, 271, 271, 287, 256, 256, 271, + 271, 287, 287, 304, 304, 256, 256, 271, + 271, 287, 287, 304, 304, 322, 322, 341, + 341, 362, 362, 383, 383, 256, 256, 271, + 271, 287, 287, 304, 304, 322, 322, 256, + 256, 271, 271, 287, 287, 304, 304, 322, + 322, 341, 341, 362, 362, 256, 256, 271, + 271, 287, 287, 304, 304, 322, 322, 256, + 256, 271, 271, 287, 287, 304, 304, 322, + 322, 341, 341, 362, 362, 256, 256, 271, + 271, 287, 287, 304, 304, 322, 322, 341, + 341, 362, 362, 383, 383, 406, 406, 430, + 430, 455, 455, 482, 482, 511, 511, 541, + 541, 573, 573, 607, 607, 643, 643, 681, + 681, 722, 722, 764, 764, 810, 810, 858, + 858, 908, 908, 962, 962, 1019, 1019, 256 +}; + +static u32 nphy_tpc_txgain_ipa[] = { + 0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029, + 0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025, + 0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029, + 0x5ef70028, 0x5ef70027, 0x5ef70026, 0x5ef70025, + 0x5df7002d, 0x5df7002b, 0x5df7002a, 0x5df70029, + 0x5df70028, 0x5df70027, 0x5df70026, 0x5df70025, + 0x5cf7002d, 0x5cf7002b, 0x5cf7002a, 0x5cf70029, + 0x5cf70028, 0x5cf70027, 0x5cf70026, 0x5cf70025, + 0x5bf7002d, 0x5bf7002b, 0x5bf7002a, 0x5bf70029, + 0x5bf70028, 0x5bf70027, 0x5bf70026, 0x5bf70025, + 0x5af7002d, 0x5af7002b, 0x5af7002a, 0x5af70029, + 0x5af70028, 0x5af70027, 0x5af70026, 0x5af70025, + 0x59f7002d, 0x59f7002b, 0x59f7002a, 0x59f70029, + 0x59f70028, 0x59f70027, 0x59f70026, 0x59f70025, + 0x58f7002d, 0x58f7002b, 0x58f7002a, 0x58f70029, + 0x58f70028, 0x58f70027, 0x58f70026, 0x58f70025, + 0x57f7002d, 0x57f7002b, 0x57f7002a, 0x57f70029, + 0x57f70028, 0x57f70027, 0x57f70026, 0x57f70025, + 0x56f7002d, 0x56f7002b, 0x56f7002a, 0x56f70029, + 0x56f70028, 0x56f70027, 0x56f70026, 0x56f70025, + 0x55f7002d, 0x55f7002b, 0x55f7002a, 0x55f70029, + 0x55f70028, 0x55f70027, 0x55f70026, 0x55f70025, + 0x54f7002d, 0x54f7002b, 0x54f7002a, 0x54f70029, + 0x54f70028, 0x54f70027, 0x54f70026, 0x54f70025, + 0x53f7002d, 0x53f7002b, 0x53f7002a, 0x53f70029, + 0x53f70028, 0x53f70027, 0x53f70026, 0x53f70025, + 0x52f7002d, 0x52f7002b, 0x52f7002a, 0x52f70029, + 0x52f70028, 0x52f70027, 0x52f70026, 0x52f70025, + 0x51f7002d, 0x51f7002b, 0x51f7002a, 0x51f70029, + 0x51f70028, 0x51f70027, 0x51f70026, 0x51f70025, + 0x50f7002d, 0x50f7002b, 0x50f7002a, 0x50f70029, + 0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025 +}; + +static u32 nphy_tpc_txgain_ipa_rev5[] = { + 0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029, + 0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025, + 0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029, + 0x1ef70028, 0x1ef70027, 0x1ef70026, 0x1ef70025, + 0x1df7002d, 0x1df7002b, 0x1df7002a, 0x1df70029, + 0x1df70028, 0x1df70027, 0x1df70026, 0x1df70025, + 0x1cf7002d, 0x1cf7002b, 0x1cf7002a, 0x1cf70029, + 0x1cf70028, 0x1cf70027, 0x1cf70026, 0x1cf70025, + 0x1bf7002d, 0x1bf7002b, 0x1bf7002a, 0x1bf70029, + 0x1bf70028, 0x1bf70027, 0x1bf70026, 0x1bf70025, + 0x1af7002d, 0x1af7002b, 0x1af7002a, 0x1af70029, + 0x1af70028, 0x1af70027, 0x1af70026, 0x1af70025, + 0x19f7002d, 0x19f7002b, 0x19f7002a, 0x19f70029, + 0x19f70028, 0x19f70027, 0x19f70026, 0x19f70025, + 0x18f7002d, 0x18f7002b, 0x18f7002a, 0x18f70029, + 0x18f70028, 0x18f70027, 0x18f70026, 0x18f70025, + 0x17f7002d, 0x17f7002b, 0x17f7002a, 0x17f70029, + 0x17f70028, 0x17f70027, 0x17f70026, 0x17f70025, + 0x16f7002d, 0x16f7002b, 0x16f7002a, 0x16f70029, + 0x16f70028, 0x16f70027, 0x16f70026, 0x16f70025, + 0x15f7002d, 0x15f7002b, 0x15f7002a, 0x15f70029, + 0x15f70028, 0x15f70027, 0x15f70026, 0x15f70025, + 0x14f7002d, 0x14f7002b, 0x14f7002a, 0x14f70029, + 0x14f70028, 0x14f70027, 0x14f70026, 0x14f70025, + 0x13f7002d, 0x13f7002b, 0x13f7002a, 0x13f70029, + 0x13f70028, 0x13f70027, 0x13f70026, 0x13f70025, + 0x12f7002d, 0x12f7002b, 0x12f7002a, 0x12f70029, + 0x12f70028, 0x12f70027, 0x12f70026, 0x12f70025, + 0x11f7002d, 0x11f7002b, 0x11f7002a, 0x11f70029, + 0x11f70028, 0x11f70027, 0x11f70026, 0x11f70025, + 0x10f7002d, 0x10f7002b, 0x10f7002a, 0x10f70029, + 0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025 +}; + +static u32 nphy_tpc_txgain_ipa_rev6[] = { + 0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029, + 0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025, + 0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029, + 0x0ef70028, 0x0ef70027, 0x0ef70026, 0x0ef70025, + 0x0df7002d, 0x0df7002b, 0x0df7002a, 0x0df70029, + 0x0df70028, 0x0df70027, 0x0df70026, 0x0df70025, + 0x0cf7002d, 0x0cf7002b, 0x0cf7002a, 0x0cf70029, + 0x0cf70028, 0x0cf70027, 0x0cf70026, 0x0cf70025, + 0x0bf7002d, 0x0bf7002b, 0x0bf7002a, 0x0bf70029, + 0x0bf70028, 0x0bf70027, 0x0bf70026, 0x0bf70025, + 0x0af7002d, 0x0af7002b, 0x0af7002a, 0x0af70029, + 0x0af70028, 0x0af70027, 0x0af70026, 0x0af70025, + 0x09f7002d, 0x09f7002b, 0x09f7002a, 0x09f70029, + 0x09f70028, 0x09f70027, 0x09f70026, 0x09f70025, + 0x08f7002d, 0x08f7002b, 0x08f7002a, 0x08f70029, + 0x08f70028, 0x08f70027, 0x08f70026, 0x08f70025, + 0x07f7002d, 0x07f7002b, 0x07f7002a, 0x07f70029, + 0x07f70028, 0x07f70027, 0x07f70026, 0x07f70025, + 0x06f7002d, 0x06f7002b, 0x06f7002a, 0x06f70029, + 0x06f70028, 0x06f70027, 0x06f70026, 0x06f70025, + 0x05f7002d, 0x05f7002b, 0x05f7002a, 0x05f70029, + 0x05f70028, 0x05f70027, 0x05f70026, 0x05f70025, + 0x04f7002d, 0x04f7002b, 0x04f7002a, 0x04f70029, + 0x04f70028, 0x04f70027, 0x04f70026, 0x04f70025, + 0x03f7002d, 0x03f7002b, 0x03f7002a, 0x03f70029, + 0x03f70028, 0x03f70027, 0x03f70026, 0x03f70025, + 0x02f7002d, 0x02f7002b, 0x02f7002a, 0x02f70029, + 0x02f70028, 0x02f70027, 0x02f70026, 0x02f70025, + 0x01f7002d, 0x01f7002b, 0x01f7002a, 0x01f70029, + 0x01f70028, 0x01f70027, 0x01f70026, 0x01f70025, + 0x00f7002d, 0x00f7002b, 0x00f7002a, 0x00f70029, + 0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025 +}; + +static u32 nphy_tpc_txgain_ipa_2g_2057rev3[] = { + 0x70ff0040, 0x70f7003e, 0x70ef003b, 0x70e70039, + 0x70df0037, 0x70d70036, 0x70cf0033, 0x70c70032, + 0x70bf0031, 0x70b7002f, 0x70af002e, 0x70a7002d, + 0x709f002d, 0x7097002c, 0x708f002c, 0x7087002c, + 0x707f002b, 0x7077002c, 0x706f002c, 0x7067002d, + 0x705f002e, 0x705f002b, 0x705f0029, 0x7057002a, + 0x70570028, 0x704f002a, 0x7047002c, 0x7047002a, + 0x70470028, 0x70470026, 0x70470024, 0x70470022, + 0x7047001f, 0x70370027, 0x70370024, 0x70370022, + 0x70370020, 0x7037001f, 0x7037001d, 0x7037001b, + 0x7037001a, 0x70370018, 0x70370017, 0x7027001e, + 0x7027001d, 0x7027001a, 0x701f0024, 0x701f0022, + 0x701f0020, 0x701f001f, 0x701f001d, 0x701f001b, + 0x701f001a, 0x701f0018, 0x701f0017, 0x701f0015, + 0x701f0014, 0x701f0013, 0x701f0012, 0x701f0011, + 0x70170019, 0x70170018, 0x70170016, 0x70170015, + 0x70170014, 0x70170013, 0x70170012, 0x70170010, + 0x70170010, 0x7017000f, 0x700f001d, 0x700f001b, + 0x700f001a, 0x700f0018, 0x700f0017, 0x700f0015, + 0x700f0015, 0x700f0013, 0x700f0013, 0x700f0011, + 0x700f0010, 0x700f0010, 0x700f000f, 0x700f000e, + 0x700f000d, 0x700f000c, 0x700f000b, 0x700f000b, + 0x700f000b, 0x700f000a, 0x700f0009, 0x700f0009, + 0x700f0009, 0x700f0008, 0x700f0007, 0x700f0007, + 0x700f0006, 0x700f0006, 0x700f0006, 0x700f0006, + 0x700f0005, 0x700f0005, 0x700f0005, 0x700f0004, + 0x700f0004, 0x700f0004, 0x700f0004, 0x700f0004, + 0x700f0004, 0x700f0003, 0x700f0003, 0x700f0003, + 0x700f0003, 0x700f0002, 0x700f0002, 0x700f0002, + 0x700f0002, 0x700f0002, 0x700f0002, 0x700f0001, + 0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001, + 0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001 +}; + +static u32 nphy_tpc_txgain_ipa_2g_2057rev4n6[] = { + 0xf0ff0040, 0xf0f7003e, 0xf0ef003b, 0xf0e70039, + 0xf0df0037, 0xf0d70036, 0xf0cf0033, 0xf0c70032, + 0xf0bf0031, 0xf0b7002f, 0xf0af002e, 0xf0a7002d, + 0xf09f002d, 0xf097002c, 0xf08f002c, 0xf087002c, + 0xf07f002b, 0xf077002c, 0xf06f002c, 0xf067002d, + 0xf05f002e, 0xf05f002b, 0xf05f0029, 0xf057002a, + 0xf0570028, 0xf04f002a, 0xf047002c, 0xf047002a, + 0xf0470028, 0xf0470026, 0xf0470024, 0xf0470022, + 0xf047001f, 0xf0370027, 0xf0370024, 0xf0370022, + 0xf0370020, 0xf037001f, 0xf037001d, 0xf037001b, + 0xf037001a, 0xf0370018, 0xf0370017, 0xf027001e, + 0xf027001d, 0xf027001a, 0xf01f0024, 0xf01f0022, + 0xf01f0020, 0xf01f001f, 0xf01f001d, 0xf01f001b, + 0xf01f001a, 0xf01f0018, 0xf01f0017, 0xf01f0015, + 0xf01f0014, 0xf01f0013, 0xf01f0012, 0xf01f0011, + 0xf0170019, 0xf0170018, 0xf0170016, 0xf0170015, + 0xf0170014, 0xf0170013, 0xf0170012, 0xf0170010, + 0xf0170010, 0xf017000f, 0xf00f001d, 0xf00f001b, + 0xf00f001a, 0xf00f0018, 0xf00f0017, 0xf00f0015, + 0xf00f0015, 0xf00f0013, 0xf00f0013, 0xf00f0011, + 0xf00f0010, 0xf00f0010, 0xf00f000f, 0xf00f000e, + 0xf00f000d, 0xf00f000c, 0xf00f000b, 0xf00f000b, + 0xf00f000b, 0xf00f000a, 0xf00f0009, 0xf00f0009, + 0xf00f0009, 0xf00f0008, 0xf00f0007, 0xf00f0007, + 0xf00f0006, 0xf00f0006, 0xf00f0006, 0xf00f0006, + 0xf00f0005, 0xf00f0005, 0xf00f0005, 0xf00f0004, + 0xf00f0004, 0xf00f0004, 0xf00f0004, 0xf00f0004, + 0xf00f0004, 0xf00f0003, 0xf00f0003, 0xf00f0003, + 0xf00f0003, 0xf00f0002, 0xf00f0002, 0xf00f0002, + 0xf00f0002, 0xf00f0002, 0xf00f0002, 0xf00f0001, + 0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001, + 0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001 +}; + +static u32 nphy_tpc_txgain_ipa_2g_2057rev5[] = { + 0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e, + 0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033, + 0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e, + 0x3067002e, 0x305f002f, 0x30570030, 0x3057002d, + 0x304f002e, 0x30470031, 0x3047002e, 0x3047002c, + 0x30470029, 0x303f002c, 0x303f0029, 0x3037002d, + 0x3037002a, 0x30370028, 0x302f002c, 0x302f002a, + 0x302f0028, 0x302f0026, 0x3027002c, 0x30270029, + 0x30270027, 0x30270025, 0x30270023, 0x301f002c, + 0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024, + 0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b, + 0x30170028, 0x30170026, 0x30170024, 0x30170022, + 0x30170020, 0x3017001e, 0x3017001d, 0x3017001b, + 0x3017001a, 0x30170018, 0x30170017, 0x30170015, + 0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024, + 0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d, + 0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017, + 0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215, + 0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715 +}; + +static u32 nphy_tpc_txgain_ipa_2g_2057rev7[] = { + 0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e, + 0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033, + 0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e, + 0x3067002e, 0x305f002f, 0x30570030, 0x3057002d, + 0x304f002e, 0x30470031, 0x3047002e, 0x3047002c, + 0x30470029, 0x303f002c, 0x303f0029, 0x3037002d, + 0x3037002a, 0x30370028, 0x302f002c, 0x302f002a, + 0x302f0028, 0x302f0026, 0x3027002c, 0x30270029, + 0x30270027, 0x30270025, 0x30270023, 0x301f002c, + 0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024, + 0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b, + 0x30170028, 0x30170026, 0x30170024, 0x30170022, + 0x30170020, 0x3017001e, 0x3017001d, 0x3017001b, + 0x3017001a, 0x30170018, 0x30170017, 0x30170015, + 0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024, + 0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d, + 0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017, + 0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215, + 0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715 +}; + +static u32 nphy_tpc_txgain_ipa_5g[] = { + 0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031, + 0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b, + 0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027, + 0x7ff70026, 0x7ff70024, 0x7ff70023, 0x7ff70022, + 0x7ef70028, 0x7ef70027, 0x7ef70026, 0x7ef70025, + 0x7ef70024, 0x7ef70023, 0x7df70028, 0x7df70027, + 0x7df70026, 0x7df70025, 0x7df70024, 0x7df70023, + 0x7df70022, 0x7cf70029, 0x7cf70028, 0x7cf70027, + 0x7cf70026, 0x7cf70025, 0x7cf70023, 0x7cf70022, + 0x7bf70029, 0x7bf70028, 0x7bf70026, 0x7bf70025, + 0x7bf70024, 0x7bf70023, 0x7bf70022, 0x7bf70021, + 0x7af70029, 0x7af70028, 0x7af70027, 0x7af70026, + 0x7af70025, 0x7af70024, 0x7af70023, 0x7af70022, + 0x79f70029, 0x79f70028, 0x79f70027, 0x79f70026, + 0x79f70025, 0x79f70024, 0x79f70023, 0x79f70022, + 0x78f70029, 0x78f70028, 0x78f70027, 0x78f70026, + 0x78f70025, 0x78f70024, 0x78f70023, 0x78f70022, + 0x77f70029, 0x77f70028, 0x77f70027, 0x77f70026, + 0x77f70025, 0x77f70024, 0x77f70023, 0x77f70022, + 0x76f70029, 0x76f70028, 0x76f70027, 0x76f70026, + 0x76f70024, 0x76f70023, 0x76f70022, 0x76f70021, + 0x75f70029, 0x75f70028, 0x75f70027, 0x75f70026, + 0x75f70025, 0x75f70024, 0x75f70023, 0x74f70029, + 0x74f70028, 0x74f70026, 0x74f70025, 0x74f70024, + 0x74f70023, 0x74f70022, 0x73f70029, 0x73f70027, + 0x73f70026, 0x73f70025, 0x73f70024, 0x73f70023, + 0x73f70022, 0x72f70028, 0x72f70027, 0x72f70026, + 0x72f70025, 0x72f70024, 0x72f70023, 0x72f70022, + 0x71f70028, 0x71f70027, 0x71f70026, 0x71f70025, + 0x71f70024, 0x71f70023, 0x70f70028, 0x70f70027, + 0x70f70026, 0x70f70024, 0x70f70023, 0x70f70022, + 0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f +}; + +static u32 nphy_tpc_txgain_ipa_5g_2057[] = { + 0x7f7f0044, 0x7f7f0040, 0x7f7f003c, 0x7f7f0039, + 0x7f7f0036, 0x7e7f003c, 0x7e7f0038, 0x7e7f0035, + 0x7d7f003c, 0x7d7f0039, 0x7d7f0036, 0x7d7f0033, + 0x7c7f003b, 0x7c7f0037, 0x7c7f0034, 0x7b7f003a, + 0x7b7f0036, 0x7b7f0033, 0x7a7f003c, 0x7a7f0039, + 0x7a7f0036, 0x7a7f0033, 0x797f003b, 0x797f0038, + 0x797f0035, 0x797f0032, 0x787f003b, 0x787f0038, + 0x787f0035, 0x787f0032, 0x777f003a, 0x777f0037, + 0x777f0034, 0x777f0031, 0x767f003a, 0x767f0036, + 0x767f0033, 0x767f0031, 0x757f003a, 0x757f0037, + 0x757f0034, 0x747f003c, 0x747f0039, 0x747f0036, + 0x747f0033, 0x737f003b, 0x737f0038, 0x737f0035, + 0x737f0032, 0x727f0039, 0x727f0036, 0x727f0033, + 0x727f0030, 0x717f003a, 0x717f0037, 0x717f0034, + 0x707f003b, 0x707f0038, 0x707f0035, 0x707f0032, + 0x707f002f, 0x707f002d, 0x707f002a, 0x707f0028, + 0x707f0025, 0x707f0023, 0x707f0021, 0x707f0020, + 0x707f001e, 0x707f001c, 0x707f001b, 0x707f0019, + 0x707f0018, 0x707f0016, 0x707f0015, 0x707f0014, + 0x707f0013, 0x707f0012, 0x707f0011, 0x707f0010, + 0x707f000f, 0x707f000e, 0x707f000d, 0x707f000d, + 0x707f000c, 0x707f000b, 0x707f000b, 0x707f000a, + 0x707f0009, 0x707f0009, 0x707f0008, 0x707f0008, + 0x707f0007, 0x707f0007, 0x707f0007, 0x707f0006, + 0x707f0006, 0x707f0006, 0x707f0005, 0x707f0005, + 0x707f0005, 0x707f0004, 0x707f0004, 0x707f0004, + 0x707f0004, 0x707f0004, 0x707f0003, 0x707f0003, + 0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003, + 0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002, + 0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002, + 0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001, + 0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001 +}; + +static u32 nphy_tpc_txgain_ipa_5g_2057rev7[] = { + 0x6f7f0031, 0x6f7f002e, 0x6f7f002c, 0x6f7f002a, + 0x6f7f0027, 0x6e7f002e, 0x6e7f002c, 0x6e7f002a, + 0x6d7f0030, 0x6d7f002d, 0x6d7f002a, 0x6d7f0028, + 0x6c7f0030, 0x6c7f002d, 0x6c7f002b, 0x6b7f002e, + 0x6b7f002c, 0x6b7f002a, 0x6b7f0027, 0x6a7f002e, + 0x6a7f002c, 0x6a7f002a, 0x697f0030, 0x697f002e, + 0x697f002b, 0x697f0029, 0x687f002f, 0x687f002d, + 0x687f002a, 0x687f0027, 0x677f002f, 0x677f002d, + 0x677f002a, 0x667f0031, 0x667f002e, 0x667f002c, + 0x667f002a, 0x657f0030, 0x657f002e, 0x657f002b, + 0x657f0029, 0x647f0030, 0x647f002d, 0x647f002b, + 0x647f0029, 0x637f002f, 0x637f002d, 0x637f002a, + 0x627f0030, 0x627f002d, 0x627f002b, 0x627f0029, + 0x617f0030, 0x617f002e, 0x617f002b, 0x617f0029, + 0x607f002f, 0x607f002d, 0x607f002a, 0x607f0027, + 0x607f0026, 0x607f0023, 0x607f0021, 0x607f0020, + 0x607f001e, 0x607f001c, 0x607f001a, 0x607f0019, + 0x607f0018, 0x607f0016, 0x607f0015, 0x607f0014, + 0x607f0012, 0x607f0012, 0x607f0011, 0x607f000f, + 0x607f000f, 0x607f000e, 0x607f000d, 0x607f000c, + 0x607f000c, 0x607f000b, 0x607f000b, 0x607f000a, + 0x607f0009, 0x607f0009, 0x607f0008, 0x607f0008, + 0x607f0008, 0x607f0007, 0x607f0007, 0x607f0006, + 0x607f0006, 0x607f0005, 0x607f0005, 0x607f0005, + 0x607f0005, 0x607f0005, 0x607f0004, 0x607f0004, + 0x607f0004, 0x607f0004, 0x607f0003, 0x607f0003, + 0x607f0003, 0x607f0003, 0x607f0002, 0x607f0002, + 0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002, + 0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002, + 0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002, + 0x607f0002, 0x607f0001, 0x607f0001, 0x607f0001, + 0x607f0001, 0x607f0001, 0x607f0001, 0x607f0001 +}; + +static s8 nphy_papd_pga_gain_delta_ipa_2g[] = { + -114, -108, -98, -91, -84, -78, -70, -62, + -54, -46, -39, -31, -23, -15, -8, 0 +}; + +static s8 nphy_papd_pga_gain_delta_ipa_5g[] = { + -100, -95, -89, -83, -77, -70, -63, -56, + -48, -41, -33, -25, -19, -12, -6, 0 +}; + +static s16 nphy_papd_padgain_dlt_2g_2057rev3n4[] = { + -159, -113, -86, -72, -62, -54, -48, -43, + -39, -35, -31, -28, -25, -23, -20, -18, + -17, -15, -13, -11, -10, -8, -7, -6, + -5, -4, -3, -3, -2, -1, -1, 0 +}; + +static s16 nphy_papd_padgain_dlt_2g_2057rev5[] = { + -109, -109, -82, -68, -58, -50, -44, -39, + -35, -31, -28, -26, -23, -21, -19, -17, + -16, -14, -13, -11, -10, -9, -8, -7, + -5, -5, -4, -3, -2, -1, -1, 0 +}; + +static s16 nphy_papd_padgain_dlt_2g_2057rev7[] = { + -122, -122, -95, -80, -69, -61, -54, -49, + -43, -39, -35, -32, -28, -26, -23, -21, + -18, -16, -15, -13, -11, -10, -8, -7, + -6, -5, -4, -3, -2, -1, -1, 0 +}; + +static s8 nphy_papd_pgagain_dlt_5g_2057[] = { + -107, -101, -92, -85, -78, -71, -62, -55, + -47, -39, -32, -24, -19, -12, -6, 0 +}; + +static s8 nphy_papd_pgagain_dlt_5g_2057rev7[] = { + -110, -104, -95, -88, -81, -74, -66, -58, + -50, -44, -36, -28, -23, -15, -8, 0 +}; + +static u8 pad_gain_codes_used_2057rev5[] = { + 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, + 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 +}; + +static u8 pad_gain_codes_used_2057rev7[] = { + 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, + 5, 4, 3, 2, 1 +}; + +static u8 pad_all_gain_codes_2057[] = { + 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, + 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, + 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, + 1, 0 +}; + +static u8 pga_all_gain_codes_2057[] = { + 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 +}; + +static u32 nphy_papd_scaltbl[] = { + 0x0ae2002f, 0x0a3b0032, 0x09a70035, 0x09220038, + 0x0887003c, 0x081f003f, 0x07a20043, 0x07340047, + 0x06d2004b, 0x067a004f, 0x06170054, 0x05bf0059, + 0x0571005e, 0x051e0064, 0x04d3006a, 0x04910070, + 0x044c0077, 0x040f007e, 0x03d90085, 0x03a1008d, + 0x036f0095, 0x033d009e, 0x030b00a8, 0x02e000b2, + 0x02b900bc, 0x029200c7, 0x026d00d3, 0x024900e0, + 0x022900ed, 0x020a00fb, 0x01ec010a, 0x01d0011a, + 0x01b7012a, 0x019e013c, 0x0187014f, 0x01720162, + 0x015d0177, 0x0149018e, 0x013701a5, 0x012601be, + 0x011501d9, 0x010501f5, 0x00f70212, 0x00e90232, + 0x00dc0253, 0x00d00276, 0x00c4029c, 0x00b902c3, + 0x00af02ed, 0x00a5031a, 0x009c0349, 0x0093037a, + 0x008b03af, 0x008303e7, 0x007c0422, 0x00750461, + 0x006e04a3, 0x006804ea, 0x00620534, 0x005d0583, + 0x005805d7, 0x0053062f, 0x004e068d, 0x004a06f1 +}; + +static u32 nphy_tpc_txgain_rev3[] = { + 0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e, + 0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037, + 0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e, + 0x1e41003c, 0x1e41003b, 0x1e410039, 0x1e410037, + 0x1d410044, 0x1d410042, 0x1d410040, 0x1d41003e, + 0x1d41003c, 0x1d41003b, 0x1d410039, 0x1d410037, + 0x1c410044, 0x1c410042, 0x1c410040, 0x1c41003e, + 0x1c41003c, 0x1c41003b, 0x1c410039, 0x1c410037, + 0x1b410044, 0x1b410042, 0x1b410040, 0x1b41003e, + 0x1b41003c, 0x1b41003b, 0x1b410039, 0x1b410037, + 0x1a410044, 0x1a410042, 0x1a410040, 0x1a41003e, + 0x1a41003c, 0x1a41003b, 0x1a410039, 0x1a410037, + 0x19410044, 0x19410042, 0x19410040, 0x1941003e, + 0x1941003c, 0x1941003b, 0x19410039, 0x19410037, + 0x18410044, 0x18410042, 0x18410040, 0x1841003e, + 0x1841003c, 0x1841003b, 0x18410039, 0x18410037, + 0x17410044, 0x17410042, 0x17410040, 0x1741003e, + 0x1741003c, 0x1741003b, 0x17410039, 0x17410037, + 0x16410044, 0x16410042, 0x16410040, 0x1641003e, + 0x1641003c, 0x1641003b, 0x16410039, 0x16410037, + 0x15410044, 0x15410042, 0x15410040, 0x1541003e, + 0x1541003c, 0x1541003b, 0x15410039, 0x15410037, + 0x14410044, 0x14410042, 0x14410040, 0x1441003e, + 0x1441003c, 0x1441003b, 0x14410039, 0x14410037, + 0x13410044, 0x13410042, 0x13410040, 0x1341003e, + 0x1341003c, 0x1341003b, 0x13410039, 0x13410037, + 0x12410044, 0x12410042, 0x12410040, 0x1241003e, + 0x1241003c, 0x1241003b, 0x12410039, 0x12410037, + 0x11410044, 0x11410042, 0x11410040, 0x1141003e, + 0x1141003c, 0x1141003b, 0x11410039, 0x11410037, + 0x10410044, 0x10410042, 0x10410040, 0x1041003e, + 0x1041003c, 0x1041003b, 0x10410039, 0x10410037 +}; + +static u32 nphy_tpc_txgain_HiPwrEPA[] = { + 0x0f410044, 0x0f410042, 0x0f410040, 0x0f41003e, + 0x0f41003c, 0x0f41003b, 0x0f410039, 0x0f410037, + 0x0e410044, 0x0e410042, 0x0e410040, 0x0e41003e, + 0x0e41003c, 0x0e41003b, 0x0e410039, 0x0e410037, + 0x0d410044, 0x0d410042, 0x0d410040, 0x0d41003e, + 0x0d41003c, 0x0d41003b, 0x0d410039, 0x0d410037, + 0x0c410044, 0x0c410042, 0x0c410040, 0x0c41003e, + 0x0c41003c, 0x0c41003b, 0x0c410039, 0x0c410037, + 0x0b410044, 0x0b410042, 0x0b410040, 0x0b41003e, + 0x0b41003c, 0x0b41003b, 0x0b410039, 0x0b410037, + 0x0a410044, 0x0a410042, 0x0a410040, 0x0a41003e, + 0x0a41003c, 0x0a41003b, 0x0a410039, 0x0a410037, + 0x09410044, 0x09410042, 0x09410040, 0x0941003e, + 0x0941003c, 0x0941003b, 0x09410039, 0x09410037, + 0x08410044, 0x08410042, 0x08410040, 0x0841003e, + 0x0841003c, 0x0841003b, 0x08410039, 0x08410037, + 0x07410044, 0x07410042, 0x07410040, 0x0741003e, + 0x0741003c, 0x0741003b, 0x07410039, 0x07410037, + 0x06410044, 0x06410042, 0x06410040, 0x0641003e, + 0x0641003c, 0x0641003b, 0x06410039, 0x06410037, + 0x05410044, 0x05410042, 0x05410040, 0x0541003e, + 0x0541003c, 0x0541003b, 0x05410039, 0x05410037, + 0x04410044, 0x04410042, 0x04410040, 0x0441003e, + 0x0441003c, 0x0441003b, 0x04410039, 0x04410037, + 0x03410044, 0x03410042, 0x03410040, 0x0341003e, + 0x0341003c, 0x0341003b, 0x03410039, 0x03410037, + 0x02410044, 0x02410042, 0x02410040, 0x0241003e, + 0x0241003c, 0x0241003b, 0x02410039, 0x02410037, + 0x01410044, 0x01410042, 0x01410040, 0x0141003e, + 0x0141003c, 0x0141003b, 0x01410039, 0x01410037, + 0x00410044, 0x00410042, 0x00410040, 0x0041003e, + 0x0041003c, 0x0041003b, 0x00410039, 0x00410037 +}; + +static u32 nphy_tpc_txgain_epa_2057rev3[] = { + 0x80f90040, 0x80e10040, 0x80e1003c, 0x80c9003d, + 0x80b9003c, 0x80a9003d, 0x80a1003c, 0x8099003b, + 0x8091003b, 0x8089003a, 0x8081003a, 0x80790039, + 0x80710039, 0x8069003a, 0x8061003b, 0x8059003d, + 0x8051003f, 0x80490042, 0x8049003e, 0x8049003b, + 0x8041003e, 0x8041003b, 0x8039003e, 0x8039003b, + 0x80390038, 0x80390035, 0x8031003a, 0x80310036, + 0x80310033, 0x8029003a, 0x80290037, 0x80290034, + 0x80290031, 0x80210039, 0x80210036, 0x80210033, + 0x80210030, 0x8019003c, 0x80190039, 0x80190036, + 0x80190033, 0x80190030, 0x8019002d, 0x8019002b, + 0x80190028, 0x8011003a, 0x80110036, 0x80110033, + 0x80110030, 0x8011002e, 0x8011002b, 0x80110029, + 0x80110027, 0x80110024, 0x80110022, 0x80110020, + 0x8011001f, 0x8011001d, 0x8009003a, 0x80090037, + 0x80090034, 0x80090031, 0x8009002e, 0x8009002c, + 0x80090029, 0x80090027, 0x80090025, 0x80090023, + 0x80090021, 0x8009001f, 0x8009001d, 0x8009011d, + 0x8009021d, 0x8009031d, 0x8009041d, 0x8009051d, + 0x8009061d, 0x8009071d, 0x8009071d, 0x8009071d, + 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, + 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, + 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, + 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, + 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, + 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, + 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, + 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, + 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, + 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, + 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, + 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d +}; + +static u32 nphy_tpc_txgain_epa_2057rev5[] = { + 0x10f90040, 0x10e10040, 0x10e1003c, 0x10c9003d, + 0x10b9003c, 0x10a9003d, 0x10a1003c, 0x1099003b, + 0x1091003b, 0x1089003a, 0x1081003a, 0x10790039, + 0x10710039, 0x1069003a, 0x1061003b, 0x1059003d, + 0x1051003f, 0x10490042, 0x1049003e, 0x1049003b, + 0x1041003e, 0x1041003b, 0x1039003e, 0x1039003b, + 0x10390038, 0x10390035, 0x1031003a, 0x10310036, + 0x10310033, 0x1029003a, 0x10290037, 0x10290034, + 0x10290031, 0x10210039, 0x10210036, 0x10210033, + 0x10210030, 0x1019003c, 0x10190039, 0x10190036, + 0x10190033, 0x10190030, 0x1019002d, 0x1019002b, + 0x10190028, 0x1011003a, 0x10110036, 0x10110033, + 0x10110030, 0x1011002e, 0x1011002b, 0x10110029, + 0x10110027, 0x10110024, 0x10110022, 0x10110020, + 0x1011001f, 0x1011001d, 0x1009003a, 0x10090037, + 0x10090034, 0x10090031, 0x1009002e, 0x1009002c, + 0x10090029, 0x10090027, 0x10090025, 0x10090023, + 0x10090021, 0x1009001f, 0x1009001d, 0x1009001b, + 0x1009001a, 0x10090018, 0x10090017, 0x10090016, + 0x10090015, 0x10090013, 0x10090012, 0x10090011, + 0x10090010, 0x1009000f, 0x1009000f, 0x1009000e, + 0x1009000d, 0x1009000c, 0x1009000c, 0x1009000b, + 0x1009000a, 0x1009000a, 0x10090009, 0x10090009, + 0x10090008, 0x10090008, 0x10090007, 0x10090007, + 0x10090007, 0x10090006, 0x10090006, 0x10090005, + 0x10090005, 0x10090005, 0x10090005, 0x10090004, + 0x10090004, 0x10090004, 0x10090004, 0x10090003, + 0x10090003, 0x10090003, 0x10090003, 0x10090003, + 0x10090003, 0x10090002, 0x10090002, 0x10090002, + 0x10090002, 0x10090002, 0x10090002, 0x10090002, + 0x10090002, 0x10090002, 0x10090001, 0x10090001, + 0x10090001, 0x10090001, 0x10090001, 0x10090001 +}; + +static u32 nphy_tpc_5GHz_txgain_rev3[] = { + 0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e, + 0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037, + 0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e, + 0xcef7003c, 0xcef7003b, 0xcef70039, 0xcef70037, + 0xcdf70044, 0xcdf70042, 0xcdf70040, 0xcdf7003e, + 0xcdf7003c, 0xcdf7003b, 0xcdf70039, 0xcdf70037, + 0xccf70044, 0xccf70042, 0xccf70040, 0xccf7003e, + 0xccf7003c, 0xccf7003b, 0xccf70039, 0xccf70037, + 0xcbf70044, 0xcbf70042, 0xcbf70040, 0xcbf7003e, + 0xcbf7003c, 0xcbf7003b, 0xcbf70039, 0xcbf70037, + 0xcaf70044, 0xcaf70042, 0xcaf70040, 0xcaf7003e, + 0xcaf7003c, 0xcaf7003b, 0xcaf70039, 0xcaf70037, + 0xc9f70044, 0xc9f70042, 0xc9f70040, 0xc9f7003e, + 0xc9f7003c, 0xc9f7003b, 0xc9f70039, 0xc9f70037, + 0xc8f70044, 0xc8f70042, 0xc8f70040, 0xc8f7003e, + 0xc8f7003c, 0xc8f7003b, 0xc8f70039, 0xc8f70037, + 0xc7f70044, 0xc7f70042, 0xc7f70040, 0xc7f7003e, + 0xc7f7003c, 0xc7f7003b, 0xc7f70039, 0xc7f70037, + 0xc6f70044, 0xc6f70042, 0xc6f70040, 0xc6f7003e, + 0xc6f7003c, 0xc6f7003b, 0xc6f70039, 0xc6f70037, + 0xc5f70044, 0xc5f70042, 0xc5f70040, 0xc5f7003e, + 0xc5f7003c, 0xc5f7003b, 0xc5f70039, 0xc5f70037, + 0xc4f70044, 0xc4f70042, 0xc4f70040, 0xc4f7003e, + 0xc4f7003c, 0xc4f7003b, 0xc4f70039, 0xc4f70037, + 0xc3f70044, 0xc3f70042, 0xc3f70040, 0xc3f7003e, + 0xc3f7003c, 0xc3f7003b, 0xc3f70039, 0xc3f70037, + 0xc2f70044, 0xc2f70042, 0xc2f70040, 0xc2f7003e, + 0xc2f7003c, 0xc2f7003b, 0xc2f70039, 0xc2f70037, + 0xc1f70044, 0xc1f70042, 0xc1f70040, 0xc1f7003e, + 0xc1f7003c, 0xc1f7003b, 0xc1f70039, 0xc1f70037, + 0xc0f70044, 0xc0f70042, 0xc0f70040, 0xc0f7003e, + 0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037 +}; + +static u32 nphy_tpc_5GHz_txgain_rev4[] = { + 0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e, + 0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037, + 0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e, + 0x2ef2003c, 0x2ef2003b, 0x2ef20039, 0x2ef20037, + 0x2df20044, 0x2df20042, 0x2df20040, 0x2df2003e, + 0x2df2003c, 0x2df2003b, 0x2df20039, 0x2df20037, + 0x2cf20044, 0x2cf20042, 0x2cf20040, 0x2cf2003e, + 0x2cf2003c, 0x2cf2003b, 0x2cf20039, 0x2cf20037, + 0x2bf20044, 0x2bf20042, 0x2bf20040, 0x2bf2003e, + 0x2bf2003c, 0x2bf2003b, 0x2bf20039, 0x2bf20037, + 0x2af20044, 0x2af20042, 0x2af20040, 0x2af2003e, + 0x2af2003c, 0x2af2003b, 0x2af20039, 0x2af20037, + 0x29f20044, 0x29f20042, 0x29f20040, 0x29f2003e, + 0x29f2003c, 0x29f2003b, 0x29f20039, 0x29f20037, + 0x28f20044, 0x28f20042, 0x28f20040, 0x28f2003e, + 0x28f2003c, 0x28f2003b, 0x28f20039, 0x28f20037, + 0x27f20044, 0x27f20042, 0x27f20040, 0x27f2003e, + 0x27f2003c, 0x27f2003b, 0x27f20039, 0x27f20037, + 0x26f20044, 0x26f20042, 0x26f20040, 0x26f2003e, + 0x26f2003c, 0x26f2003b, 0x26f20039, 0x26f20037, + 0x25f20044, 0x25f20042, 0x25f20040, 0x25f2003e, + 0x25f2003c, 0x25f2003b, 0x25f20039, 0x25f20037, + 0x24f20044, 0x24f20042, 0x24f20040, 0x24f2003e, + 0x24f2003c, 0x24f2003b, 0x24f20039, 0x24f20038, + 0x23f20041, 0x23f20040, 0x23f2003f, 0x23f2003e, + 0x23f2003c, 0x23f2003b, 0x23f20039, 0x23f20037, + 0x22f20044, 0x22f20042, 0x22f20040, 0x22f2003e, + 0x22f2003c, 0x22f2003b, 0x22f20039, 0x22f20037, + 0x21f20044, 0x21f20042, 0x21f20040, 0x21f2003e, + 0x21f2003c, 0x21f2003b, 0x21f20039, 0x21f20037, + 0x20d20043, 0x20d20041, 0x20d2003e, 0x20d2003c, + 0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034 +}; + +static u32 nphy_tpc_5GHz_txgain_rev5[] = { + 0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044, + 0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c, + 0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e, + 0x0e62003c, 0x0e62003d, 0x0e62003b, 0x0e62003a, + 0x0d620043, 0x0d620041, 0x0d620040, 0x0d62003e, + 0x0d62003d, 0x0d62003c, 0x0d62003b, 0x0d62003a, + 0x0c620041, 0x0c620040, 0x0c62003f, 0x0c62003e, + 0x0c62003c, 0x0c62003b, 0x0c620039, 0x0c620037, + 0x0b620046, 0x0b620044, 0x0b620042, 0x0b620040, + 0x0b62003e, 0x0b62003c, 0x0b62003b, 0x0b62003a, + 0x0a620041, 0x0a620040, 0x0a62003e, 0x0a62003c, + 0x0a62003b, 0x0a62003a, 0x0a620039, 0x0a620038, + 0x0962003e, 0x0962003d, 0x0962003c, 0x0962003b, + 0x09620039, 0x09620037, 0x09620035, 0x09620033, + 0x08620044, 0x08620042, 0x08620040, 0x0862003e, + 0x0862003c, 0x0862003b, 0x0862003a, 0x08620039, + 0x07620043, 0x07620042, 0x07620040, 0x0762003f, + 0x0762003d, 0x0762003b, 0x0762003a, 0x07620039, + 0x0662003e, 0x0662003d, 0x0662003c, 0x0662003b, + 0x06620039, 0x06620037, 0x06620035, 0x06620033, + 0x05620046, 0x05620044, 0x05620042, 0x05620040, + 0x0562003e, 0x0562003c, 0x0562003b, 0x05620039, + 0x04620044, 0x04620042, 0x04620040, 0x0462003e, + 0x0462003c, 0x0462003b, 0x04620039, 0x04620038, + 0x0362003c, 0x0362003b, 0x0362003a, 0x03620039, + 0x03620038, 0x03620037, 0x03620035, 0x03620033, + 0x0262004c, 0x0262004a, 0x02620048, 0x02620047, + 0x02620046, 0x02620044, 0x02620043, 0x02620042, + 0x0162004a, 0x01620048, 0x01620046, 0x01620044, + 0x01620043, 0x01620042, 0x01620041, 0x01620040, + 0x00620042, 0x00620040, 0x0062003e, 0x0062003c, + 0x0062003b, 0x00620039, 0x00620037, 0x00620035 +}; + +static u32 nphy_tpc_5GHz_txgain_HiPwrEPA[] = { + 0x2ff10044, 0x2ff10042, 0x2ff10040, 0x2ff1003e, + 0x2ff1003c, 0x2ff1003b, 0x2ff10039, 0x2ff10037, + 0x2ef10044, 0x2ef10042, 0x2ef10040, 0x2ef1003e, + 0x2ef1003c, 0x2ef1003b, 0x2ef10039, 0x2ef10037, + 0x2df10044, 0x2df10042, 0x2df10040, 0x2df1003e, + 0x2df1003c, 0x2df1003b, 0x2df10039, 0x2df10037, + 0x2cf10044, 0x2cf10042, 0x2cf10040, 0x2cf1003e, + 0x2cf1003c, 0x2cf1003b, 0x2cf10039, 0x2cf10037, + 0x2bf10044, 0x2bf10042, 0x2bf10040, 0x2bf1003e, + 0x2bf1003c, 0x2bf1003b, 0x2bf10039, 0x2bf10037, + 0x2af10044, 0x2af10042, 0x2af10040, 0x2af1003e, + 0x2af1003c, 0x2af1003b, 0x2af10039, 0x2af10037, + 0x29f10044, 0x29f10042, 0x29f10040, 0x29f1003e, + 0x29f1003c, 0x29f1003b, 0x29f10039, 0x29f10037, + 0x28f10044, 0x28f10042, 0x28f10040, 0x28f1003e, + 0x28f1003c, 0x28f1003b, 0x28f10039, 0x28f10037, + 0x27f10044, 0x27f10042, 0x27f10040, 0x27f1003e, + 0x27f1003c, 0x27f1003b, 0x27f10039, 0x27f10037, + 0x26f10044, 0x26f10042, 0x26f10040, 0x26f1003e, + 0x26f1003c, 0x26f1003b, 0x26f10039, 0x26f10037, + 0x25f10044, 0x25f10042, 0x25f10040, 0x25f1003e, + 0x25f1003c, 0x25f1003b, 0x25f10039, 0x25f10037, + 0x24f10044, 0x24f10042, 0x24f10040, 0x24f1003e, + 0x24f1003c, 0x24f1003b, 0x24f10039, 0x24f10038, + 0x23f10041, 0x23f10040, 0x23f1003f, 0x23f1003e, + 0x23f1003c, 0x23f1003b, 0x23f10039, 0x23f10037, + 0x22f10044, 0x22f10042, 0x22f10040, 0x22f1003e, + 0x22f1003c, 0x22f1003b, 0x22f10039, 0x22f10037, + 0x21f10044, 0x21f10042, 0x21f10040, 0x21f1003e, + 0x21f1003c, 0x21f1003b, 0x21f10039, 0x21f10037, + 0x20d10043, 0x20d10041, 0x20d1003e, 0x20d1003c, + 0x20d1003a, 0x20d10038, 0x20d10036, 0x20d10034 +}; + +static u8 ant_sw_ctrl_tbl_rev8_2o3[] = { 0x14, 0x18 }; +static u8 ant_sw_ctrl_tbl_rev8[] = { 0x4, 0x8, 0x4, 0x8, 0x11, 0x12 }; +static u8 ant_sw_ctrl_tbl_rev8_2057v7_core0[] = { + 0x09, 0x0a, 0x15, 0x16, 0x09, 0x0a }; +static u8 ant_sw_ctrl_tbl_rev8_2057v7_core1[] = { + 0x09, 0x0a, 0x09, 0x0a, 0x15, 0x16 }; + +static bool wlc_phy_chan2freq_nphy(phy_info_t *pi, uint channel, int *f, + chan_info_nphy_radio2057_t **t0, + chan_info_nphy_radio205x_t **t1, + chan_info_nphy_radio2057_rev5_t **t2, + chan_info_nphy_2055_t **t3); +static void wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chans, + const nphy_sfo_cfg_t *c); + +static void wlc_phy_adjust_rx_analpfbw_nphy(phy_info_t *pi, + u16 reduction_factr); +static void wlc_phy_adjust_min_noisevar_nphy(phy_info_t *pi, int ntones, int *, + u32 *buf); +static void wlc_phy_adjust_crsminpwr_nphy(phy_info_t *pi, u8 minpwr); +static void wlc_phy_txlpfbw_nphy(phy_info_t *pi); +static void wlc_phy_spurwar_nphy(phy_info_t *pi); + +static void wlc_phy_radio_preinit_2055(phy_info_t *pi); +static void wlc_phy_radio_init_2055(phy_info_t *pi); +static void wlc_phy_radio_postinit_2055(phy_info_t *pi); +static void wlc_phy_radio_preinit_205x(phy_info_t *pi); +static void wlc_phy_radio_init_2056(phy_info_t *pi); +static void wlc_phy_radio_postinit_2056(phy_info_t *pi); +static void wlc_phy_radio_init_2057(phy_info_t *pi); +static void wlc_phy_radio_postinit_2057(phy_info_t *pi); +static void wlc_phy_workarounds_nphy(phy_info_t *pi); +static void wlc_phy_workarounds_nphy_gainctrl(phy_info_t *pi); +static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(phy_info_t *pi); +static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(phy_info_t *pi); +static void wlc_phy_adjust_lnagaintbl_nphy(phy_info_t *pi); + +static void wlc_phy_restore_rssical_nphy(phy_info_t *pi); +static void wlc_phy_reapply_txcal_coeffs_nphy(phy_info_t *pi); +static void wlc_phy_tx_iq_war_nphy(phy_info_t *pi); +static int wlc_phy_cal_rxiq_nphy_rev3(phy_info_t *pi, nphy_txgains_t tg, + u8 type, bool d); +static void wlc_phy_rxcal_gainctrl_nphy_rev5(phy_info_t *pi, u8 rxcore, + u16 *rg, u8 type); +static void wlc_phy_update_mimoconfig_nphy(phy_info_t *pi, s32 preamble); +static void wlc_phy_savecal_nphy(phy_info_t *pi); +static void wlc_phy_restorecal_nphy(phy_info_t *pi); +static void wlc_phy_resetcca_nphy(phy_info_t *pi); + +static void wlc_phy_txpwrctrl_config_nphy(phy_info_t *pi); +static void wlc_phy_internal_cal_txgain_nphy(phy_info_t *pi); +static void wlc_phy_precal_txgain_nphy(phy_info_t *pi); +static void wlc_phy_update_txcal_ladder_nphy(phy_info_t *pi, u16 core); + +static void wlc_phy_extpa_set_tx_digi_filts_nphy(phy_info_t *pi); +static void wlc_phy_ipa_set_tx_digi_filts_nphy(phy_info_t *pi); +static void wlc_phy_ipa_restore_tx_digi_filts_nphy(phy_info_t *pi); +static u16 wlc_phy_ipa_get_bbmult_nphy(phy_info_t *pi); +static void wlc_phy_ipa_set_bbmult_nphy(phy_info_t *pi, u8 m0, u8 m1); +static u32 *wlc_phy_get_ipa_gaintbl_nphy(phy_info_t *pi); + +static void wlc_phy_a1_nphy(phy_info_t *pi, u8 core, u32 winsz, u32, + u32 e); +static u8 wlc_phy_a3_nphy(phy_info_t *pi, u8 start_gain, u8 core); +static void wlc_phy_a2_nphy(phy_info_t *pi, nphy_ipa_txcalgains_t *, + phy_cal_mode_t, u8); +static void wlc_phy_papd_cal_cleanup_nphy(phy_info_t *pi, + nphy_papd_restore_state *state); +static void wlc_phy_papd_cal_setup_nphy(phy_info_t *pi, + nphy_papd_restore_state *state, u8); + +static void wlc_phy_clip_det_nphy(phy_info_t *pi, u8 write, u16 *vals); + +static void wlc_phy_set_rfseq_nphy(phy_info_t *pi, u8 cmd, u8 *evts, + u8 *dlys, u8 len); + +static u16 wlc_phy_read_lpf_bw_ctl_nphy(phy_info_t *pi, u16 offset); + +static void +wlc_phy_rfctrl_override_nphy_rev7(phy_info_t *pi, u16 field, u16 value, + u8 core_mask, u8 off, + u8 override_id); + +static void wlc_phy_rssi_cal_nphy_rev2(phy_info_t *pi, u8 rssi_type); +static void wlc_phy_rssi_cal_nphy_rev3(phy_info_t *pi); + +static bool wlc_phy_txpwr_srom_read_nphy(phy_info_t *pi); +static void wlc_phy_txpwr_nphy_srom_convert(u8 *srom_max, + u16 *pwr_offset, + u8 tmp_max_pwr, u8 rate_start, + u8 rate_end); + +static void wlc_phy_txpwr_limit_to_tbl_nphy(phy_info_t *pi); +static void wlc_phy_txpwrctrl_coeff_setup_nphy(phy_info_t *pi); +static void wlc_phy_txpwrctrl_idle_tssi_nphy(phy_info_t *pi); +static void wlc_phy_txpwrctrl_pwr_setup_nphy(phy_info_t *pi); + +static bool wlc_phy_txpwr_ison_nphy(phy_info_t *pi); +static u8 wlc_phy_txpwr_idx_cur_get_nphy(phy_info_t *pi, u8 core); +static void wlc_phy_txpwr_idx_cur_set_nphy(phy_info_t *pi, u8 idx0, + u8 idx1); +static void wlc_phy_a4(phy_info_t *pi, bool full_cal); + +static u16 wlc_phy_radio205x_rcal(phy_info_t *pi); + +static u16 wlc_phy_radio2057_rccal(phy_info_t *pi); + +static u16 wlc_phy_gen_load_samples_nphy(phy_info_t *pi, u32 f_kHz, + u16 max_val, + u8 dac_test_mode); +static void wlc_phy_loadsampletable_nphy(phy_info_t *pi, cs32 *tone_buf, + u16 num_samps); +static void wlc_phy_runsamples_nphy(phy_info_t *pi, u16 n, u16 lps, + u16 wait, u8 iq, u8 dac_test_mode, + bool modify_bbmult); + +bool wlc_phy_bist_check_phy(wlc_phy_t *pih) +{ + phy_info_t *pi = (phy_info_t *) pih; + u32 phybist0, phybist1, phybist2, phybist3, phybist4; + + if (NREV_GE(pi->pubpi.phy_rev, 16)) + return true; + + phybist0 = read_phy_reg(pi, 0x0e); + phybist1 = read_phy_reg(pi, 0x0f); + phybist2 = read_phy_reg(pi, 0xea); + phybist3 = read_phy_reg(pi, 0xeb); + phybist4 = read_phy_reg(pi, 0x156); + + if ((phybist0 == 0) && (phybist1 == 0x4000) && (phybist2 == 0x1fe0) && + (phybist3 == 0) && (phybist4 == 0)) { + return true; + } + + return false; +} + +static void WLBANDINITFN(wlc_phy_bphy_init_nphy) (phy_info_t *pi) +{ + u16 addr, val; + + ASSERT(ISNPHY(pi)); + + val = 0x1e1f; + for (addr = (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT); + addr <= (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT_END); addr++) { + write_phy_reg(pi, addr, val); + if (addr == (NPHY_TO_BPHY_OFF + 0x97)) + val = 0x3e3f; + else + val -= 0x0202; + } + + if (NORADIO_ENAB(pi->pubpi)) { + + write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_PHYCRSTH, 0x3206); + + write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_RSSI_TRESH, 0x281e); + + or_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_LNA_GAIN_RANGE, 0x1a); + + } else { + + write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_STEP, 0x668); + } +} + +void +wlc_phy_table_write_nphy(phy_info_t *pi, u32 id, u32 len, u32 offset, + u32 width, const void *data) +{ + mimophytbl_info_t tbl; + + tbl.tbl_id = id; + tbl.tbl_len = len; + tbl.tbl_offset = offset; + tbl.tbl_width = width; + tbl.tbl_ptr = data; + wlc_phy_write_table_nphy(pi, &tbl); +} + +void +wlc_phy_table_read_nphy(phy_info_t *pi, u32 id, u32 len, u32 offset, + u32 width, void *data) +{ + mimophytbl_info_t tbl; + + tbl.tbl_id = id; + tbl.tbl_len = len; + tbl.tbl_offset = offset; + tbl.tbl_width = width; + tbl.tbl_ptr = data; + wlc_phy_read_table_nphy(pi, &tbl); +} + +static void WLBANDINITFN(wlc_phy_static_table_download_nphy) (phy_info_t *pi) +{ + uint idx; + + if (NREV_GE(pi->pubpi.phy_rev, 16)) { + for (idx = 0; idx < mimophytbl_info_sz_rev16; idx++) + wlc_phy_write_table_nphy(pi, + &mimophytbl_info_rev16[idx]); + } else if (NREV_GE(pi->pubpi.phy_rev, 7)) { + for (idx = 0; idx < mimophytbl_info_sz_rev7; idx++) + wlc_phy_write_table_nphy(pi, + &mimophytbl_info_rev7[idx]); + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + for (idx = 0; idx < mimophytbl_info_sz_rev3; idx++) + wlc_phy_write_table_nphy(pi, + &mimophytbl_info_rev3[idx]); + } else { + for (idx = 0; idx < mimophytbl_info_sz_rev0; idx++) + wlc_phy_write_table_nphy(pi, + &mimophytbl_info_rev0[idx]); + } +} + +static void WLBANDINITFN(wlc_phy_tbl_init_nphy) (phy_info_t *pi) +{ + uint idx = 0; + u8 antswctrllut; + + if (pi->phy_init_por) + wlc_phy_static_table_download_nphy(pi); + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + antswctrllut = CHSPEC_IS2G(pi->radio_chanspec) ? + pi->srom_fem2g.antswctrllut : pi->srom_fem5g.antswctrllut; + + switch (antswctrllut) { + case 0: + + break; + + case 1: + + if (pi->aa2g == 7) { + + wlc_phy_table_write_nphy(pi, + NPHY_TBL_ID_ANTSWCTRLLUT, + 2, 0x21, 8, + &ant_sw_ctrl_tbl_rev8_2o3 + [0]); + } else { + wlc_phy_table_write_nphy(pi, + NPHY_TBL_ID_ANTSWCTRLLUT, + 2, 0x21, 8, + &ant_sw_ctrl_tbl_rev8 + [0]); + } + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 2, 0x25, 8, + &ant_sw_ctrl_tbl_rev8[2]); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 2, 0x29, 8, + &ant_sw_ctrl_tbl_rev8[4]); + break; + + case 2: + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 2, 0x1, 8, + &ant_sw_ctrl_tbl_rev8_2057v7_core0 + [0]); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 2, 0x5, 8, + &ant_sw_ctrl_tbl_rev8_2057v7_core0 + [2]); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 2, 0x9, 8, + &ant_sw_ctrl_tbl_rev8_2057v7_core0 + [4]); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 2, 0x21, 8, + &ant_sw_ctrl_tbl_rev8_2057v7_core1 + [0]); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 2, 0x25, 8, + &ant_sw_ctrl_tbl_rev8_2057v7_core1 + [2]); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 2, 0x29, 8, + &ant_sw_ctrl_tbl_rev8_2057v7_core1 + [4]); + break; + + default: + + ASSERT(0); + break; + } + + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + for (idx = 0; idx < mimophytbl_info_sz_rev3_volatile; idx++) { + + if (idx == ANT_SWCTRL_TBL_REV3_IDX) { + antswctrllut = CHSPEC_IS2G(pi->radio_chanspec) ? + pi->srom_fem2g.antswctrllut : pi-> + srom_fem5g.antswctrllut; + switch (antswctrllut) { + case 0: + wlc_phy_write_table_nphy(pi, + &mimophytbl_info_rev3_volatile + [idx]); + break; + case 1: + wlc_phy_write_table_nphy(pi, + &mimophytbl_info_rev3_volatile1 + [idx]); + break; + case 2: + wlc_phy_write_table_nphy(pi, + &mimophytbl_info_rev3_volatile2 + [idx]); + break; + case 3: + wlc_phy_write_table_nphy(pi, + &mimophytbl_info_rev3_volatile3 + [idx]); + break; + default: + + ASSERT(0); + break; + } + } else { + wlc_phy_write_table_nphy(pi, + &mimophytbl_info_rev3_volatile + [idx]); + } + } + } else { + for (idx = 0; idx < mimophytbl_info_sz_rev0_volatile; idx++) { + wlc_phy_write_table_nphy(pi, + &mimophytbl_info_rev0_volatile + [idx]); + } + } +} + +static void +wlc_phy_write_txmacreg_nphy(phy_info_t *pi, u16 holdoff, u16 delay) +{ + write_phy_reg(pi, 0x77, holdoff); + write_phy_reg(pi, 0xb4, delay); +} + +void wlc_phy_nphy_tkip_rifs_war(phy_info_t *pi, u8 rifs) +{ + u16 holdoff, delay; + + if (rifs) { + + holdoff = 0x10; + delay = 0x258; + } else { + + holdoff = 0x15; + delay = 0x320; + } + + wlc_phy_write_txmacreg_nphy(pi, holdoff, delay); + + if (pi && pi->sh && (pi->sh->_rifs_phy != rifs)) { + pi->sh->_rifs_phy = rifs; + } +} + +bool wlc_phy_attach_nphy(phy_info_t *pi) +{ + uint i; + + if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 6)) { + pi->phyhang_avoid = true; + } + + if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) { + + pi->nphy_gband_spurwar_en = true; + + if (pi->sh->boardflags2 & BFL2_SPUR_WAR) { + pi->nphy_aband_spurwar_en = true; + } + } + if (NREV_GE(pi->pubpi.phy_rev, 6) && NREV_LT(pi->pubpi.phy_rev, 7)) { + + if (pi->sh->boardflags2 & BFL2_2G_SPUR_WAR) { + pi->nphy_gband_spurwar2_en = true; + } + } + + pi->n_preamble_override = AUTO; + if (NREV_IS(pi->pubpi.phy_rev, 3) || NREV_IS(pi->pubpi.phy_rev, 4)) + pi->n_preamble_override = WLC_N_PREAMBLE_MIXEDMODE; + + pi->nphy_txrx_chain = AUTO; + pi->phy_scraminit = AUTO; + + pi->nphy_rxcalparams = 0x010100B5; + + pi->nphy_perical = PHY_PERICAL_MPHASE; + pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE; + pi->mphase_txcal_numcmds = MPHASE_TXCAL_NUMCMDS; + + pi->nphy_gain_boost = true; + pi->nphy_elna_gain_config = false; + pi->radio_is_on = false; + + for (i = 0; i < pi->pubpi.phy_corenum; i++) { + pi->nphy_txpwrindex[i].index = AUTO; + } + + wlc_phy_txpwrctrl_config_nphy(pi); + if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON) + pi->hwpwrctrl_capable = true; + + pi->pi_fptr.init = wlc_phy_init_nphy; + pi->pi_fptr.calinit = wlc_phy_cal_init_nphy; + pi->pi_fptr.chanset = wlc_phy_chanspec_set_nphy; + pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_nphy; + + if (!wlc_phy_txpwr_srom_read_nphy(pi)) + return false; + + return true; +} + +static void wlc_phy_txpwrctrl_config_nphy(phy_info_t *pi) +{ + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + pi->nphy_txpwrctrl = PHY_TPC_HW_ON; + pi->phy_5g_pwrgain = true; + return; + } + + pi->nphy_txpwrctrl = PHY_TPC_HW_OFF; + pi->phy_5g_pwrgain = false; + + if ((pi->sh->boardflags2 & BFL2_TXPWRCTRL_EN) && + NREV_GE(pi->pubpi.phy_rev, 2) && (pi->sh->sromrev >= 4)) + pi->nphy_txpwrctrl = PHY_TPC_HW_ON; + else if ((pi->sh->sromrev >= 4) + && (pi->sh->boardflags2 & BFL2_5G_PWRGAIN)) + pi->phy_5g_pwrgain = true; +} + +void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi) +{ + u16 val; + u16 clip1_ths[2]; + nphy_txgains_t target_gain; + u8 tx_pwr_ctrl_state; + bool do_nphy_cal = false; + uint core; + uint origidx, intr_val; + d11regs_t *regs; + u32 d11_clk_ctl_st; + + core = 0; + + if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN)) { + pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC; + } + + if ((ISNPHY(pi)) && (NREV_GE(pi->pubpi.phy_rev, 5)) && + ((pi->sh->chippkg == BCM4717_PKG_ID) || + (pi->sh->chippkg == BCM4718_PKG_ID))) { + if ((pi->sh->boardflags & BFL_EXTLNA) && + (CHSPEC_IS2G(pi->radio_chanspec))) { + si_corereg(pi->sh->sih, SI_CC_IDX, + offsetof(chipcregs_t, chipcontrol), 0x40, + 0x40); + } + } + + if ((!PHY_IPA(pi)) && (pi->sh->chip == BCM5357_CHIP_ID)) { + si_pmu_chipcontrol(pi->sh->sih, 1, CCTRL5357_EXTPA, + CCTRL5357_EXTPA); + } + + if ((pi->nphy_gband_spurwar2_en) && CHSPEC_IS2G(pi->radio_chanspec) && + CHSPEC_IS40(pi->radio_chanspec)) { + + regs = (d11regs_t *) si_switch_core(pi->sh->sih, D11_CORE_ID, + &origidx, &intr_val); + ASSERT(regs != NULL); + + d11_clk_ctl_st = R_REG(pi->sh->osh, ®s->clk_ctl_st); + AND_REG(pi->sh->osh, ®s->clk_ctl_st, + ~(CCS_FORCEHT | CCS_HTAREQ)); + + W_REG(pi->sh->osh, ®s->clk_ctl_st, d11_clk_ctl_st); + + si_restore_core(pi->sh->sih, origidx, intr_val); + } + + pi->use_int_tx_iqlo_cal_nphy = + (PHY_IPA(pi) || + (NREV_GE(pi->pubpi.phy_rev, 7) || + (NREV_GE(pi->pubpi.phy_rev, 5) + && pi->sh->boardflags2 & BFL2_INTERNDET_TXIQCAL))); + + pi->internal_tx_iqlo_cal_tapoff_intpa_nphy = false; + + pi->nphy_deaf_count = 0; + + wlc_phy_tbl_init_nphy(pi); + + pi->nphy_crsminpwr_adjusted = false; + pi->nphy_noisevars_adjusted = false; + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + write_phy_reg(pi, 0xe7, 0); + write_phy_reg(pi, 0xec, 0); + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + write_phy_reg(pi, 0x342, 0); + write_phy_reg(pi, 0x343, 0); + write_phy_reg(pi, 0x346, 0); + write_phy_reg(pi, 0x347, 0); + } + write_phy_reg(pi, 0xe5, 0); + write_phy_reg(pi, 0xe6, 0); + } else { + write_phy_reg(pi, 0xec, 0); + } + + write_phy_reg(pi, 0x91, 0); + write_phy_reg(pi, 0x92, 0); + if (NREV_LT(pi->pubpi.phy_rev, 6)) { + write_phy_reg(pi, 0x93, 0); + write_phy_reg(pi, 0x94, 0); + } + + and_phy_reg(pi, 0xa1, ~3); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + write_phy_reg(pi, 0x8f, 0); + write_phy_reg(pi, 0xa5, 0); + } else { + write_phy_reg(pi, 0xa5, 0); + } + + if (NREV_IS(pi->pubpi.phy_rev, 2)) + mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b); + else if (NREV_LT(pi->pubpi.phy_rev, 2)) + mod_phy_reg(pi, 0xdc, 0x00ff, 0x40); + + write_phy_reg(pi, 0x203, 32); + write_phy_reg(pi, 0x201, 32); + + if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD) + write_phy_reg(pi, 0x20d, 160); + else + write_phy_reg(pi, 0x20d, 184); + + write_phy_reg(pi, 0x13a, 200); + + write_phy_reg(pi, 0x70, 80); + + write_phy_reg(pi, 0x1ff, 48); + + if (NREV_LT(pi->pubpi.phy_rev, 8)) { + wlc_phy_update_mimoconfig_nphy(pi, pi->n_preamble_override); + } + + wlc_phy_stf_chain_upd_nphy(pi); + + if (NREV_LT(pi->pubpi.phy_rev, 2)) { + write_phy_reg(pi, 0x180, 0xaa8); + write_phy_reg(pi, 0x181, 0x9a4); + } + + if (PHY_IPA(pi)) { + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (1) << 0); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x298 : + 0x29c, (0x1ff << 7), + (pi->nphy_papd_epsilon_offset[core]) << 7); + + } + + wlc_phy_ipa_set_tx_digi_filts_nphy(pi); + } else { + + if (NREV_GE(pi->pubpi.phy_rev, 5)) { + wlc_phy_extpa_set_tx_digi_filts_nphy(pi); + } + } + + wlc_phy_workarounds_nphy(pi); + + wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON); + + val = read_phy_reg(pi, 0x01); + write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA); + write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA)); + wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF); + + wlapi_bmac_macphyclk_set(pi->sh->physhim, ON); + + wlc_phy_pa_override_nphy(pi, OFF); + wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX); + wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); + wlc_phy_pa_override_nphy(pi, ON); + + wlc_phy_classifier_nphy(pi, 0, 0); + wlc_phy_clip_det_nphy(pi, 0, clip1_ths); + + if (CHSPEC_IS2G(pi->radio_chanspec)) + wlc_phy_bphy_init_nphy(pi); + + tx_pwr_ctrl_state = pi->nphy_txpwrctrl; + wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF); + + wlc_phy_txpwr_fixpower_nphy(pi); + + wlc_phy_txpwrctrl_idle_tssi_nphy(pi); + + wlc_phy_txpwrctrl_pwr_setup_nphy(pi); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + u32 *tx_pwrctrl_tbl = NULL; + u16 idx; + s16 pga_gn = 0; + s16 pad_gn = 0; + s32 rfpwr_offset = 0; + + if (PHY_IPA(pi)) { + tx_pwrctrl_tbl = wlc_phy_get_ipa_gaintbl_nphy(pi); + } else { + if (CHSPEC_IS5G(pi->radio_chanspec)) { + if NREV_IS + (pi->pubpi.phy_rev, 3) { + tx_pwrctrl_tbl = + nphy_tpc_5GHz_txgain_rev3; + } else if NREV_IS + (pi->pubpi.phy_rev, 4) { + tx_pwrctrl_tbl = + (pi->srom_fem5g.extpagain == 3) ? + nphy_tpc_5GHz_txgain_HiPwrEPA : + nphy_tpc_5GHz_txgain_rev4; + } else { + tx_pwrctrl_tbl = + nphy_tpc_5GHz_txgain_rev5; + } + + } else { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (pi->pubpi.radiorev == 5) { + tx_pwrctrl_tbl = + nphy_tpc_txgain_epa_2057rev5; + } else if (pi->pubpi.radiorev == 3) { + tx_pwrctrl_tbl = + nphy_tpc_txgain_epa_2057rev3; + } + + } else { + if (NREV_GE(pi->pubpi.phy_rev, 5) && + (pi->srom_fem2g.extpagain == 3)) { + tx_pwrctrl_tbl = + nphy_tpc_txgain_HiPwrEPA; + } else { + tx_pwrctrl_tbl = + nphy_tpc_txgain_rev3; + } + } + } + } + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128, + 192, 32, tx_pwrctrl_tbl); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128, + 192, 32, tx_pwrctrl_tbl); + + pi->nphy_gmval = (u16) ((*tx_pwrctrl_tbl >> 16) & 0x7000); + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + for (idx = 0; idx < 128; idx++) { + pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf; + pad_gn = (tx_pwrctrl_tbl[idx] >> 19) & 0x1f; + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if ((pi->pubpi.radiorev == 3) || + (pi->pubpi.radiorev == 4) || + (pi->pubpi.radiorev == 6)) { + rfpwr_offset = (s16) + nphy_papd_padgain_dlt_2g_2057rev3n4 + [pad_gn]; + } else if (pi->pubpi.radiorev == 5) { + rfpwr_offset = (s16) + nphy_papd_padgain_dlt_2g_2057rev5 + [pad_gn]; + } else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == + 8)) { + rfpwr_offset = (s16) + nphy_papd_padgain_dlt_2g_2057rev7 + [pad_gn]; + } else { + ASSERT(0); + } + + } else { + if ((pi->pubpi.radiorev == 3) || + (pi->pubpi.radiorev == 4) || + (pi->pubpi.radiorev == 6)) { + rfpwr_offset = (s16) + nphy_papd_pgagain_dlt_5g_2057 + [pga_gn]; + } else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == + 8)) { + rfpwr_offset = (s16) + nphy_papd_pgagain_dlt_5g_2057rev7 + [pga_gn]; + } else { + ASSERT(0); + } + } + wlc_phy_table_write_nphy(pi, + NPHY_TBL_ID_CORE1TXPWRCTL, + 1, 576 + idx, 32, + &rfpwr_offset); + wlc_phy_table_write_nphy(pi, + NPHY_TBL_ID_CORE2TXPWRCTL, + 1, 576 + idx, 32, + &rfpwr_offset); + } + } else { + + for (idx = 0; idx < 128; idx++) { + pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf; + if (CHSPEC_IS2G(pi->radio_chanspec)) { + rfpwr_offset = (s16) + nphy_papd_pga_gain_delta_ipa_2g + [pga_gn]; + } else { + rfpwr_offset = (s16) + nphy_papd_pga_gain_delta_ipa_5g + [pga_gn]; + } + + wlc_phy_table_write_nphy(pi, + NPHY_TBL_ID_CORE1TXPWRCTL, + 1, 576 + idx, 32, + &rfpwr_offset); + wlc_phy_table_write_nphy(pi, + NPHY_TBL_ID_CORE2TXPWRCTL, + 1, 576 + idx, 32, + &rfpwr_offset); + } + + } + } else { + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128, + 192, 32, nphy_tpc_txgain); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128, + 192, 32, nphy_tpc_txgain); + } + + if (pi->sh->phyrxchain != 0x3) { + wlc_phy_rxcore_setstate_nphy((wlc_phy_t *) pi, + pi->sh->phyrxchain); + } + + if (PHY_PERICAL_MPHASE_PENDING(pi)) { + wlc_phy_cal_perical_mphase_restart(pi); + } + + if (!NORADIO_ENAB(pi->pubpi)) { + bool do_rssi_cal = false; + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + do_rssi_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ? + (pi->nphy_rssical_chanspec_2G == 0) : + (pi->nphy_rssical_chanspec_5G == 0); + + if (do_rssi_cal) { + wlc_phy_rssi_cal_nphy(pi); + } else { + wlc_phy_restore_rssical_nphy(pi); + } + } else { + wlc_phy_rssi_cal_nphy(pi); + } + + if (!SCAN_RM_IN_PROGRESS(pi)) { + do_nphy_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ? + (pi->nphy_iqcal_chanspec_2G == 0) : + (pi->nphy_iqcal_chanspec_5G == 0); + } + + if (!pi->do_initcal) + do_nphy_cal = false; + + if (do_nphy_cal) { + + target_gain = wlc_phy_get_tx_gain_nphy(pi); + + if (pi->antsel_type == ANTSEL_2x3) + wlc_phy_antsel_init((wlc_phy_t *) pi, true); + + if (pi->nphy_perical != PHY_PERICAL_MPHASE) { + wlc_phy_rssi_cal_nphy(pi); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + pi->nphy_cal_orig_pwr_idx[0] = + pi->nphy_txpwrindex[PHY_CORE_0]. + index_internal; + pi->nphy_cal_orig_pwr_idx[1] = + pi->nphy_txpwrindex[PHY_CORE_1]. + index_internal; + + wlc_phy_precal_txgain_nphy(pi); + target_gain = + wlc_phy_get_tx_gain_nphy(pi); + } + + if (wlc_phy_cal_txiqlo_nphy + (pi, target_gain, true, false) == BCME_OK) { + if (wlc_phy_cal_rxiq_nphy + (pi, target_gain, 2, + false) == BCME_OK) { + wlc_phy_savecal_nphy(pi); + + } + } + } else if (pi->mphase_cal_phase_id == + MPHASE_CAL_STATE_IDLE) { + + wlc_phy_cal_perical((wlc_phy_t *) pi, + PHY_PERICAL_PHYINIT); + } + } else { + wlc_phy_restorecal_nphy(pi); + } + } + + wlc_phy_txpwrctrl_coeff_setup_nphy(pi); + + wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state); + + wlc_phy_nphy_tkip_rifs_war(pi, pi->sh->_rifs_phy); + + if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LE(pi->pubpi.phy_rev, 6)) + + write_phy_reg(pi, 0x70, 50); + + wlc_phy_txlpfbw_nphy(pi); + + wlc_phy_spurwar_nphy(pi); + +} + +static void wlc_phy_update_mimoconfig_nphy(phy_info_t *pi, s32 preamble) +{ + bool gf_preamble = false; + u16 val; + + if (preamble == WLC_N_PREAMBLE_GF) { + gf_preamble = true; + } + + val = read_phy_reg(pi, 0xed); + + val |= RX_GF_MM_AUTO; + val &= ~RX_GF_OR_MM; + if (gf_preamble) + val |= RX_GF_OR_MM; + + write_phy_reg(pi, 0xed, val); +} + +static void wlc_phy_resetcca_nphy(phy_info_t *pi) +{ + u16 val; + + ASSERT(0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + + wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON); + + val = read_phy_reg(pi, 0x01); + write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA); + udelay(1); + write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA)); + + wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF); + + wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); +} + +void wlc_phy_pa_override_nphy(phy_info_t *pi, bool en) +{ + u16 rfctrlintc_override_val; + + if (!en) { + + pi->rfctrlIntc1_save = read_phy_reg(pi, 0x91); + pi->rfctrlIntc2_save = read_phy_reg(pi, 0x92); + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + rfctrlintc_override_val = 0x1480; + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + rfctrlintc_override_val = + CHSPEC_IS5G(pi->radio_chanspec) ? 0x600 : 0x480; + } else { + rfctrlintc_override_val = + CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120; + } + + write_phy_reg(pi, 0x91, rfctrlintc_override_val); + write_phy_reg(pi, 0x92, rfctrlintc_override_val); + } else { + + write_phy_reg(pi, 0x91, pi->rfctrlIntc1_save); + write_phy_reg(pi, 0x92, pi->rfctrlIntc2_save); + } + +} + +void wlc_phy_stf_chain_upd_nphy(phy_info_t *pi) +{ + + u16 txrx_chain = + (NPHY_RfseqCoreActv_TxRxChain0 | NPHY_RfseqCoreActv_TxRxChain1); + bool CoreActv_override = false; + + if (pi->nphy_txrx_chain == WLC_N_TXRX_CHAIN0) { + txrx_chain = NPHY_RfseqCoreActv_TxRxChain0; + CoreActv_override = true; + + if (NREV_LE(pi->pubpi.phy_rev, 2)) { + and_phy_reg(pi, 0xa0, ~0x20); + } + } else if (pi->nphy_txrx_chain == WLC_N_TXRX_CHAIN1) { + txrx_chain = NPHY_RfseqCoreActv_TxRxChain1; + CoreActv_override = true; + + if (NREV_LE(pi->pubpi.phy_rev, 2)) { + or_phy_reg(pi, 0xa0, 0x20); + } + } + + mod_phy_reg(pi, 0xa2, ((0xf << 0) | (0xf << 4)), txrx_chain); + + if (CoreActv_override) { + + pi->nphy_perical = PHY_PERICAL_DISABLE; + or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override); + } else { + pi->nphy_perical = PHY_PERICAL_MPHASE; + and_phy_reg(pi, 0xa1, ~NPHY_RfseqMode_CoreActv_override); + } +} + +void wlc_phy_rxcore_setstate_nphy(wlc_phy_t *pih, u8 rxcore_bitmask) +{ + u16 regval; + u16 tbl_buf[16]; + uint i; + phy_info_t *pi = (phy_info_t *) pih; + u16 tbl_opcode; + bool suspend; + + pi->sh->phyrxchain = rxcore_bitmask; + + if (!pi->sh->clk) + return; + + suspend = + (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + if (!suspend) + wlapi_suspend_mac_and_wait(pi->sh->physhim); + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + regval = read_phy_reg(pi, 0xa2); + regval &= ~(0xf << 4); + regval |= ((u16) (rxcore_bitmask & 0x3)) << 4; + write_phy_reg(pi, 0xa2, regval); + + if ((rxcore_bitmask & 0x3) != 0x3) { + + write_phy_reg(pi, 0x20e, 1); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (pi->rx2tx_biasentry == -1) { + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, + ARRAY_SIZE(tbl_buf), 80, + 16, tbl_buf); + + for (i = 0; i < ARRAY_SIZE(tbl_buf); i++) { + if (tbl_buf[i] == + NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS) { + + pi->rx2tx_biasentry = (u8) i; + tbl_opcode = + NPHY_REV3_RFSEQ_CMD_NOP; + wlc_phy_table_write_nphy(pi, + NPHY_TBL_ID_RFSEQ, + 1, i, + 16, + &tbl_opcode); + break; + } else if (tbl_buf[i] == + NPHY_REV3_RFSEQ_CMD_END) { + break; + } + } + } + } + } else { + + write_phy_reg(pi, 0x20e, 30); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (pi->rx2tx_biasentry != -1) { + tbl_opcode = NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, + 1, pi->rx2tx_biasentry, + 16, &tbl_opcode); + pi->rx2tx_biasentry = -1; + } + } + } + + wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); + + if (!suspend) + wlapi_enable_mac(pi->sh->physhim); +} + +u8 wlc_phy_rxcore_getstate_nphy(wlc_phy_t *pih) +{ + u16 regval, rxen_bits; + phy_info_t *pi = (phy_info_t *) pih; + + regval = read_phy_reg(pi, 0xa2); + rxen_bits = (regval >> 4) & 0xf; + + return (u8) rxen_bits; +} + +bool wlc_phy_n_txpower_ipa_ison(phy_info_t *pi) +{ + return PHY_IPA(pi); +} + +static void wlc_phy_txpwr_limit_to_tbl_nphy(phy_info_t *pi) +{ + u8 idx, idx2, i, delta_ind; + + for (idx = TXP_FIRST_CCK; idx <= TXP_LAST_CCK; idx++) { + pi->adj_pwr_tbl_nphy[idx] = pi->tx_power_offset[idx]; + } + + for (i = 0; i < 4; i++) { + idx2 = 0; + + delta_ind = 0; + + switch (i) { + case 0: + + if (CHSPEC_IS40(pi->radio_chanspec) + && NPHY_IS_SROM_REINTERPRET) { + idx = TXP_FIRST_MCS_40_SISO; + } else { + idx = (CHSPEC_IS40(pi->radio_chanspec)) ? + TXP_FIRST_OFDM_40_SISO : TXP_FIRST_OFDM; + delta_ind = 1; + } + break; + + case 1: + + idx = (CHSPEC_IS40(pi->radio_chanspec)) ? + TXP_FIRST_MCS_40_CDD : TXP_FIRST_MCS_20_CDD; + break; + + case 2: + + idx = (CHSPEC_IS40(pi->radio_chanspec)) ? + TXP_FIRST_MCS_40_STBC : TXP_FIRST_MCS_20_STBC; + break; + + case 3: + + idx = (CHSPEC_IS40(pi->radio_chanspec)) ? + TXP_FIRST_MCS_40_SDM : TXP_FIRST_MCS_20_SDM; + break; + } + + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + idx = idx + delta_ind; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx++]; + + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx++]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx++]; + + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx++]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx++]; + + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx++]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + idx = idx + 1 - delta_ind; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + } +} + +void wlc_phy_cal_init_nphy(phy_info_t *pi) +{ +} + +static void wlc_phy_war_force_trsw_to_R_cliplo_nphy(phy_info_t *pi, u8 core) +{ + if (core == PHY_CORE_0) { + write_phy_reg(pi, 0x38, 0x4); + if (CHSPEC_IS2G(pi->radio_chanspec)) { + write_phy_reg(pi, 0x37, 0x0060); + } else { + write_phy_reg(pi, 0x37, 0x1080); + } + } else if (core == PHY_CORE_1) { + write_phy_reg(pi, 0x2ae, 0x4); + if (CHSPEC_IS2G(pi->radio_chanspec)) { + write_phy_reg(pi, 0x2ad, 0x0060); + } else { + write_phy_reg(pi, 0x2ad, 0x1080); + } + } +} + +static void wlc_phy_war_txchain_upd_nphy(phy_info_t *pi, u8 txchain) +{ + u8 txchain0, txchain1; + + txchain0 = txchain & 0x1; + txchain1 = (txchain & 0x2) >> 1; + if (!txchain0) { + wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0); + } + + if (!txchain1) { + wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1); + } +} + +static void wlc_phy_workarounds_nphy(phy_info_t *pi) +{ + u8 rfseq_rx2tx_events[] = { + NPHY_RFSEQ_CMD_NOP, + NPHY_RFSEQ_CMD_RXG_FBW, + NPHY_RFSEQ_CMD_TR_SWITCH, + NPHY_RFSEQ_CMD_CLR_HIQ_DIS, + NPHY_RFSEQ_CMD_RXPD_TXPD, + NPHY_RFSEQ_CMD_TX_GAIN, + NPHY_RFSEQ_CMD_EXT_PA + }; + u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 }; + u8 rfseq_tx2rx_events[] = { + NPHY_RFSEQ_CMD_NOP, + NPHY_RFSEQ_CMD_EXT_PA, + NPHY_RFSEQ_CMD_TX_GAIN, + NPHY_RFSEQ_CMD_RXPD_TXPD, + NPHY_RFSEQ_CMD_TR_SWITCH, + NPHY_RFSEQ_CMD_RXG_FBW, + NPHY_RFSEQ_CMD_CLR_HIQ_DIS + }; + u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 }; + u8 rfseq_tx2rx_events_rev3[] = { + NPHY_REV3_RFSEQ_CMD_EXT_PA, + NPHY_REV3_RFSEQ_CMD_INT_PA_PU, + NPHY_REV3_RFSEQ_CMD_TX_GAIN, + NPHY_REV3_RFSEQ_CMD_RXPD_TXPD, + NPHY_REV3_RFSEQ_CMD_TR_SWITCH, + NPHY_REV3_RFSEQ_CMD_RXG_FBW, + NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS, + NPHY_REV3_RFSEQ_CMD_END + }; + u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 }; + u8 rfseq_rx2tx_events_rev3[] = { + NPHY_REV3_RFSEQ_CMD_NOP, + NPHY_REV3_RFSEQ_CMD_RXG_FBW, + NPHY_REV3_RFSEQ_CMD_TR_SWITCH, + NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS, + NPHY_REV3_RFSEQ_CMD_RXPD_TXPD, + NPHY_REV3_RFSEQ_CMD_TX_GAIN, + NPHY_REV3_RFSEQ_CMD_INT_PA_PU, + NPHY_REV3_RFSEQ_CMD_EXT_PA, + NPHY_REV3_RFSEQ_CMD_END + }; + u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 }; + + u8 rfseq_rx2tx_events_rev3_ipa[] = { + NPHY_REV3_RFSEQ_CMD_NOP, + NPHY_REV3_RFSEQ_CMD_RXG_FBW, + NPHY_REV3_RFSEQ_CMD_TR_SWITCH, + NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS, + NPHY_REV3_RFSEQ_CMD_RXPD_TXPD, + NPHY_REV3_RFSEQ_CMD_TX_GAIN, + NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS, + NPHY_REV3_RFSEQ_CMD_INT_PA_PU, + NPHY_REV3_RFSEQ_CMD_END + }; + u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 }; + u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f }; + + s16 alpha0, alpha1, alpha2; + s16 beta0, beta1, beta2; + u32 leg_data_weights, ht_data_weights, nss1_data_weights, + stbc_data_weights; + u8 chan_freq_range = 0; + u16 dac_control = 0x0002; + u16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 }; + u16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 }; + u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 }; + u16 aux_adc_vmid_rev3[] = { 0xa2, 0xb4, 0xb4, 0x89 }; + u16 *aux_adc_vmid; + u16 aux_adc_gain_rev7[] = { 0x02, 0x02, 0x02, 0x02 }; + u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 }; + u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 }; + u16 *aux_adc_gain; + u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 }; + u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 }; + s32 min_nvar_val = 0x18d; + s32 min_nvar_offset_6mbps = 20; + u8 pdetrange; + u8 triso; + u16 regval; + u16 afectrl_adc_ctrl1_rev7 = 0x20; + u16 afectrl_adc_ctrl2_rev7 = 0x0; + u16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77; + u16 rfseq_tx2rx_lpf_h_hpc_rev7 = 0x77; + u16 rfseq_pktgn_lpf_h_hpc_rev7 = 0x77; + u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 }; + u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; + u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; + u16 ipalvlshift_3p3_war_en = 0; + u16 rccal_bcap_val, rccal_scap_val; + u16 rccal_tx20_11b_bcap = 0; + u16 rccal_tx20_11b_scap = 0; + u16 rccal_tx20_11n_bcap = 0; + u16 rccal_tx20_11n_scap = 0; + u16 rccal_tx40_11n_bcap = 0; + u16 rccal_tx40_11n_scap = 0; + u16 rx2tx_lpf_rc_lut_tx20_11b = 0; + u16 rx2tx_lpf_rc_lut_tx20_11n = 0; + u16 rx2tx_lpf_rc_lut_tx40_11n = 0; + u16 tx_lpf_bw_ofdm_20mhz = 0; + u16 tx_lpf_bw_ofdm_40mhz = 0; + u16 tx_lpf_bw_11b = 0; + u16 ipa2g_mainbias, ipa2g_casconv, ipa2g_biasfilt; + u16 txgm_idac_bleed = 0; + bool rccal_ovrd = false; + u16 freq; + int coreNum; + + if (CHSPEC_IS5G(pi->radio_chanspec)) { + wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 0); + } else { + wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 1); + } + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + if (!ISSIM_ENAB(pi->sh->sih)) { + or_phy_reg(pi, 0xb1, NPHY_IQFlip_ADC1 | NPHY_IQFlip_ADC2); + } + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + if (NREV_IS(pi->pubpi.phy_rev, 7)) { + mod_phy_reg(pi, 0x221, (0x1 << 4), (1 << 4)); + + mod_phy_reg(pi, 0x160, (0x7f << 0), (32 << 0)); + mod_phy_reg(pi, 0x160, (0x7f << 8), (39 << 8)); + mod_phy_reg(pi, 0x161, (0x7f << 0), (46 << 0)); + mod_phy_reg(pi, 0x161, (0x7f << 8), (51 << 8)); + mod_phy_reg(pi, 0x162, (0x7f << 0), (55 << 0)); + mod_phy_reg(pi, 0x162, (0x7f << 8), (58 << 8)); + mod_phy_reg(pi, 0x163, (0x7f << 0), (60 << 0)); + mod_phy_reg(pi, 0x163, (0x7f << 8), (62 << 8)); + mod_phy_reg(pi, 0x164, (0x7f << 0), (62 << 0)); + mod_phy_reg(pi, 0x164, (0x7f << 8), (63 << 8)); + mod_phy_reg(pi, 0x165, (0x7f << 0), (63 << 0)); + mod_phy_reg(pi, 0x165, (0x7f << 8), (64 << 8)); + mod_phy_reg(pi, 0x166, (0x7f << 0), (64 << 0)); + mod_phy_reg(pi, 0x166, (0x7f << 8), (64 << 8)); + mod_phy_reg(pi, 0x167, (0x7f << 0), (64 << 0)); + mod_phy_reg(pi, 0x167, (0x7f << 8), (64 << 8)); + } + + if (NREV_LE(pi->pubpi.phy_rev, 8)) { + write_phy_reg(pi, 0x23f, 0x1b0); + write_phy_reg(pi, 0x240, 0x1b0); + } + + if (NREV_GE(pi->pubpi.phy_rev, 8)) { + mod_phy_reg(pi, 0xbd, (0xff << 0), (114 << 0)); + } + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16, + &dac_control); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16, + &dac_control); + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL, + 1, 0, 32, &leg_data_weights); + leg_data_weights = leg_data_weights & 0xffffff; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL, + 1, 0, 32, &leg_data_weights); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, + 2, 0x15e, 16, + rfseq_rx2tx_dacbufpu_rev7); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x16e, 16, + rfseq_rx2tx_dacbufpu_rev7); + + if (PHY_IPA(pi)) { + wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, + rfseq_rx2tx_events_rev3_ipa, + rfseq_rx2tx_dlys_rev3_ipa, + sizeof + (rfseq_rx2tx_events_rev3_ipa) / + sizeof + (rfseq_rx2tx_events_rev3_ipa + [0])); + } + + mod_phy_reg(pi, 0x299, (0x3 << 14), (0x1 << 14)); + mod_phy_reg(pi, 0x29d, (0x3 << 14), (0x1 << 14)); + + tx_lpf_bw_ofdm_20mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x154); + tx_lpf_bw_ofdm_40mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x159); + tx_lpf_bw_11b = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x152); + + if (PHY_IPA(pi)) { + + if (((pi->pubpi.radiorev == 5) + && (CHSPEC_IS40(pi->radio_chanspec) == 1)) + || (pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) { + + rccal_bcap_val = + read_radio_reg(pi, + RADIO_2057_RCCAL_BCAP_VAL); + rccal_scap_val = + read_radio_reg(pi, + RADIO_2057_RCCAL_SCAP_VAL); + + rccal_tx20_11b_bcap = rccal_bcap_val; + rccal_tx20_11b_scap = rccal_scap_val; + + if ((pi->pubpi.radiorev == 5) && + (CHSPEC_IS40(pi->radio_chanspec) == 1)) { + + rccal_tx20_11n_bcap = rccal_bcap_val; + rccal_tx20_11n_scap = rccal_scap_val; + rccal_tx40_11n_bcap = 0xc; + rccal_tx40_11n_scap = 0xc; + + rccal_ovrd = true; + + } else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) { + + tx_lpf_bw_ofdm_20mhz = 4; + tx_lpf_bw_11b = 1; + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + rccal_tx20_11n_bcap = 0xc; + rccal_tx20_11n_scap = 0xc; + rccal_tx40_11n_bcap = 0xa; + rccal_tx40_11n_scap = 0xa; + } else { + rccal_tx20_11n_bcap = 0x14; + rccal_tx20_11n_scap = 0x14; + rccal_tx40_11n_bcap = 0xf; + rccal_tx40_11n_scap = 0xf; + } + + rccal_ovrd = true; + } + } + + } else { + + if (pi->pubpi.radiorev == 5) { + + tx_lpf_bw_ofdm_20mhz = 1; + tx_lpf_bw_ofdm_40mhz = 3; + + rccal_bcap_val = + read_radio_reg(pi, + RADIO_2057_RCCAL_BCAP_VAL); + rccal_scap_val = + read_radio_reg(pi, + RADIO_2057_RCCAL_SCAP_VAL); + + rccal_tx20_11b_bcap = rccal_bcap_val; + rccal_tx20_11b_scap = rccal_scap_val; + + rccal_tx20_11n_bcap = 0x13; + rccal_tx20_11n_scap = 0x11; + rccal_tx40_11n_bcap = 0x13; + rccal_tx40_11n_scap = 0x11; + + rccal_ovrd = true; + } + } + + if (rccal_ovrd) { + + rx2tx_lpf_rc_lut_tx20_11b = (rccal_tx20_11b_bcap << 8) | + (rccal_tx20_11b_scap << 3) | tx_lpf_bw_11b; + rx2tx_lpf_rc_lut_tx20_11n = (rccal_tx20_11n_bcap << 8) | + (rccal_tx20_11n_scap << 3) | tx_lpf_bw_ofdm_20mhz; + rx2tx_lpf_rc_lut_tx40_11n = (rccal_tx40_11n_bcap << 8) | + (rccal_tx40_11n_scap << 3) | tx_lpf_bw_ofdm_40mhz; + + for (coreNum = 0; coreNum <= 1; coreNum++) { + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, + 1, + 0x152 + coreNum * 0x10, + 16, + &rx2tx_lpf_rc_lut_tx20_11b); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, + 1, + 0x153 + coreNum * 0x10, + 16, + &rx2tx_lpf_rc_lut_tx20_11n); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, + 1, + 0x154 + coreNum * 0x10, + 16, + &rx2tx_lpf_rc_lut_tx20_11n); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, + 1, + 0x155 + coreNum * 0x10, + 16, + &rx2tx_lpf_rc_lut_tx40_11n); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, + 1, + 0x156 + coreNum * 0x10, + 16, + &rx2tx_lpf_rc_lut_tx40_11n); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, + 1, + 0x157 + coreNum * 0x10, + 16, + &rx2tx_lpf_rc_lut_tx40_11n); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, + 1, + 0x158 + coreNum * 0x10, + 16, + &rx2tx_lpf_rc_lut_tx40_11n); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, + 1, + 0x159 + coreNum * 0x10, + 16, + &rx2tx_lpf_rc_lut_tx40_11n); + } + + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), + 1, 0x3, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID2); + } + + if (!NORADIO_ENAB(pi->pubpi)) { + write_phy_reg(pi, 0x32f, 0x3); + } + + if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6)) { + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), + 1, 0x3, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + } + + if ((pi->pubpi.radiorev == 3) || (pi->pubpi.radiorev == 4) || + (pi->pubpi.radiorev == 6)) { + if ((pi->sh->sromrev >= 8) + && (pi->sh->boardflags2 & BFL2_IPALVLSHIFT_3P3)) + ipalvlshift_3p3_war_en = 1; + + if (ipalvlshift_3p3_war_en) { + write_radio_reg(pi, RADIO_2057_GPAIO_CONFIG, + 0x5); + write_radio_reg(pi, RADIO_2057_GPAIO_SEL1, + 0x30); + write_radio_reg(pi, RADIO_2057_GPAIO_SEL0, 0x0); + or_radio_reg(pi, + RADIO_2057_RXTXBIAS_CONFIG_CORE0, + 0x1); + or_radio_reg(pi, + RADIO_2057_RXTXBIAS_CONFIG_CORE1, + 0x1); + + ipa2g_mainbias = 0x1f; + + ipa2g_casconv = 0x6f; + + ipa2g_biasfilt = 0xaa; + } else { + + ipa2g_mainbias = 0x2b; + + ipa2g_casconv = 0x7f; + + ipa2g_biasfilt = 0xee; + } + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + for (coreNum = 0; coreNum <= 1; coreNum++) { + WRITE_RADIO_REG4(pi, RADIO_2057, CORE, + coreNum, IPA2G_IMAIN, + ipa2g_mainbias); + WRITE_RADIO_REG4(pi, RADIO_2057, CORE, + coreNum, IPA2G_CASCONV, + ipa2g_casconv); + WRITE_RADIO_REG4(pi, RADIO_2057, CORE, + coreNum, + IPA2G_BIAS_FILTER, + ipa2g_biasfilt); + } + } + } + + if (PHY_IPA(pi)) { + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if ((pi->pubpi.radiorev == 3) + || (pi->pubpi.radiorev == 4) + || (pi->pubpi.radiorev == 6)) { + + txgm_idac_bleed = 0x7f; + } + + for (coreNum = 0; coreNum <= 1; coreNum++) { + if (txgm_idac_bleed != 0) + WRITE_RADIO_REG4(pi, RADIO_2057, + CORE, coreNum, + TXGM_IDAC_BLEED, + txgm_idac_bleed); + } + + if (pi->pubpi.radiorev == 5) { + + for (coreNum = 0; coreNum <= 1; + coreNum++) { + WRITE_RADIO_REG4(pi, RADIO_2057, + CORE, coreNum, + IPA2G_CASCONV, + 0x13); + WRITE_RADIO_REG4(pi, RADIO_2057, + CORE, coreNum, + IPA2G_IMAIN, + 0x1f); + WRITE_RADIO_REG4(pi, RADIO_2057, + CORE, coreNum, + IPA2G_BIAS_FILTER, + 0xee); + WRITE_RADIO_REG4(pi, RADIO_2057, + CORE, coreNum, + PAD2G_IDACS, + 0x8a); + WRITE_RADIO_REG4(pi, RADIO_2057, + CORE, coreNum, + PAD_BIAS_FILTER_BWS, + 0x3e); + } + + } else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) { + + if (CHSPEC_IS40(pi->radio_chanspec) == + 0) { + WRITE_RADIO_REG4(pi, RADIO_2057, + CORE, 0, + IPA2G_IMAIN, + 0x14); + WRITE_RADIO_REG4(pi, RADIO_2057, + CORE, 1, + IPA2G_IMAIN, + 0x12); + } else { + WRITE_RADIO_REG4(pi, RADIO_2057, + CORE, 0, + IPA2G_IMAIN, + 0x16); + WRITE_RADIO_REG4(pi, RADIO_2057, + CORE, 1, + IPA2G_IMAIN, + 0x16); + } + } + + } else { + freq = + CHAN5G_FREQ(CHSPEC_CHANNEL + (pi->radio_chanspec)); + if (((freq >= 5180) && (freq <= 5230)) + || ((freq >= 5745) && (freq <= 5805))) { + WRITE_RADIO_REG4(pi, RADIO_2057, CORE, + 0, IPA5G_BIAS_FILTER, + 0xff); + WRITE_RADIO_REG4(pi, RADIO_2057, CORE, + 1, IPA5G_BIAS_FILTER, + 0xff); + } + } + } else { + + if (pi->pubpi.radiorev != 5) { + for (coreNum = 0; coreNum <= 1; coreNum++) { + WRITE_RADIO_REG4(pi, RADIO_2057, CORE, + coreNum, + TXMIX2G_TUNE_BOOST_PU, + 0x61); + WRITE_RADIO_REG4(pi, RADIO_2057, CORE, + coreNum, + TXGM_IDAC_BLEED, 0x70); + } + } + } + + if (pi->pubpi.radiorev == 4) { + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, + 0x05, 16, + &afectrl_adc_ctrl1_rev7); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, + 0x15, 16, + &afectrl_adc_ctrl1_rev7); + + for (coreNum = 0; coreNum <= 1; coreNum++) { + WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum, + AFE_VCM_CAL_MASTER, 0x0); + WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum, + AFE_SET_VCM_I, 0x3f); + WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum, + AFE_SET_VCM_Q, 0x3f); + } + } else { + mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2)); + mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2)); + mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2)); + mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2)); + + mod_phy_reg(pi, 0xa6, (0x1 << 0), 0); + mod_phy_reg(pi, 0x8f, (0x1 << 0), (0x1 << 0)); + mod_phy_reg(pi, 0xa7, (0x1 << 0), 0); + mod_phy_reg(pi, 0xa5, (0x1 << 0), (0x1 << 0)); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, + 0x05, 16, + &afectrl_adc_ctrl2_rev7); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, + 0x15, 16, + &afectrl_adc_ctrl2_rev7); + + mod_phy_reg(pi, 0xa6, (0x1 << 2), 0); + mod_phy_reg(pi, 0x8f, (0x1 << 2), 0); + mod_phy_reg(pi, 0xa7, (0x1 << 2), 0); + mod_phy_reg(pi, 0xa5, (0x1 << 2), 0); + } + + write_phy_reg(pi, 0x6a, 0x2); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 256, 32, + &min_nvar_offset_6mbps); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x138, 16, + &rfseq_pktgn_lpf_hpc_rev7); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x141, 16, + &rfseq_pktgn_lpf_h_hpc_rev7); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 3, 0x133, 16, + &rfseq_htpktgn_lpf_hpc_rev7); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x146, 16, + &rfseq_cckpktgn_lpf_hpc_rev7); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x123, 16, + &rfseq_tx2rx_lpf_h_hpc_rev7); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x12A, 16, + &rfseq_rx2tx_lpf_h_hpc_rev7); + + if (CHSPEC_IS40(pi->radio_chanspec) == 0) { + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3, + 32, &min_nvar_val); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, + 127, 32, &min_nvar_val); + } else { + min_nvar_val = noise_var_tbl_rev7[3]; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3, + 32, &min_nvar_val); + + min_nvar_val = noise_var_tbl_rev7[127]; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, + 127, 32, &min_nvar_val); + } + + wlc_phy_workarounds_nphy_gainctrl(pi); + + pdetrange = + (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g. + pdetrange : pi->srom_fem2g.pdetrange; + + if (pdetrange == 0) { + chan_freq_range = + wlc_phy_get_chan_freq_range_nphy(pi, 0); + if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) { + aux_adc_vmid_rev7_core0[3] = 0x70; + aux_adc_vmid_rev7_core1[3] = 0x70; + aux_adc_gain_rev7[3] = 2; + } else { + aux_adc_vmid_rev7_core0[3] = 0x80; + aux_adc_vmid_rev7_core1[3] = 0x80; + aux_adc_gain_rev7[3] = 3; + } + } else if (pdetrange == 1) { + if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) { + aux_adc_vmid_rev7_core0[3] = 0x7c; + aux_adc_vmid_rev7_core1[3] = 0x7c; + aux_adc_gain_rev7[3] = 2; + } else { + aux_adc_vmid_rev7_core0[3] = 0x8c; + aux_adc_vmid_rev7_core1[3] = 0x8c; + aux_adc_gain_rev7[3] = 1; + } + } else if (pdetrange == 2) { + if (pi->pubpi.radioid == BCM2057_ID) { + if ((pi->pubpi.radiorev == 5) + || (pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) { + if (chan_freq_range == + WL_CHAN_FREQ_RANGE_2G) { + aux_adc_vmid_rev7_core0[3] = + 0x8c; + aux_adc_vmid_rev7_core1[3] = + 0x8c; + aux_adc_gain_rev7[3] = 0; + } else { + aux_adc_vmid_rev7_core0[3] = + 0x96; + aux_adc_vmid_rev7_core1[3] = + 0x96; + aux_adc_gain_rev7[3] = 0; + } + } + } + + } else if (pdetrange == 3) { + if (chan_freq_range == WL_CHAN_FREQ_RANGE_2G) { + aux_adc_vmid_rev7_core0[3] = 0x89; + aux_adc_vmid_rev7_core1[3] = 0x89; + aux_adc_gain_rev7[3] = 0; + } + + } else if (pdetrange == 5) { + + if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) { + aux_adc_vmid_rev7_core0[3] = 0x80; + aux_adc_vmid_rev7_core1[3] = 0x80; + aux_adc_gain_rev7[3] = 3; + } else { + aux_adc_vmid_rev7_core0[3] = 0x70; + aux_adc_vmid_rev7_core1[3] = 0x70; + aux_adc_gain_rev7[3] = 2; + } + } + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x08, 16, + &aux_adc_vmid_rev7_core0); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x18, 16, + &aux_adc_vmid_rev7_core1); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x0c, 16, + &aux_adc_gain_rev7); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x1c, 16, + &aux_adc_gain_rev7); + + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + + write_phy_reg(pi, 0x23f, 0x1f8); + write_phy_reg(pi, 0x240, 0x1f8); + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL, + 1, 0, 32, &leg_data_weights); + leg_data_weights = leg_data_weights & 0xffffff; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL, + 1, 0, 32, &leg_data_weights); + + alpha0 = 293; + alpha1 = 435; + alpha2 = 261; + beta0 = 366; + beta1 = 205; + beta2 = 32; + write_phy_reg(pi, 0x145, alpha0); + write_phy_reg(pi, 0x146, alpha1); + write_phy_reg(pi, 0x147, alpha2); + write_phy_reg(pi, 0x148, beta0); + write_phy_reg(pi, 0x149, beta1); + write_phy_reg(pi, 0x14a, beta2); + + write_phy_reg(pi, 0x38, 0xC); + write_phy_reg(pi, 0x2ae, 0xC); + + wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX, + rfseq_tx2rx_events_rev3, + rfseq_tx2rx_dlys_rev3, + sizeof(rfseq_tx2rx_events_rev3) / + sizeof(rfseq_tx2rx_events_rev3[0])); + + if (PHY_IPA(pi)) { + wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, + rfseq_rx2tx_events_rev3_ipa, + rfseq_rx2tx_dlys_rev3_ipa, + sizeof + (rfseq_rx2tx_events_rev3_ipa) / + sizeof + (rfseq_rx2tx_events_rev3_ipa + [0])); + } + + if ((pi->sh->hw_phyrxchain != 0x3) && + (pi->sh->hw_phyrxchain != pi->sh->hw_phytxchain)) { + + if (PHY_IPA(pi)) { + rfseq_rx2tx_dlys_rev3[5] = 59; + rfseq_rx2tx_dlys_rev3[6] = 1; + rfseq_rx2tx_events_rev3[7] = + NPHY_REV3_RFSEQ_CMD_END; + } + + wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, + rfseq_rx2tx_events_rev3, + rfseq_rx2tx_dlys_rev3, + sizeof(rfseq_rx2tx_events_rev3) / + sizeof(rfseq_rx2tx_events_rev3 + [0])); + } + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + write_phy_reg(pi, 0x6a, 0x2); + } else { + write_phy_reg(pi, 0x6a, 0x9c40); + } + + mod_phy_reg(pi, 0x294, (0xf << 8), (7 << 8)); + + if (CHSPEC_IS40(pi->radio_chanspec) == 0) { + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3, + 32, &min_nvar_val); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, + 127, 32, &min_nvar_val); + } else { + min_nvar_val = noise_var_tbl_rev3[3]; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3, + 32, &min_nvar_val); + + min_nvar_val = noise_var_tbl_rev3[127]; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, + 127, 32, &min_nvar_val); + } + + wlc_phy_workarounds_nphy_gainctrl(pi); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16, + &dac_control); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16, + &dac_control); + + pdetrange = + (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g. + pdetrange : pi->srom_fem2g.pdetrange; + + if (pdetrange == 0) { + if (NREV_GE(pi->pubpi.phy_rev, 4)) { + aux_adc_vmid = aux_adc_vmid_rev4; + aux_adc_gain = aux_adc_gain_rev4; + } else { + aux_adc_vmid = aux_adc_vmid_rev3; + aux_adc_gain = aux_adc_gain_rev3; + } + chan_freq_range = + wlc_phy_get_chan_freq_range_nphy(pi, 0); + if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) { + switch (chan_freq_range) { + case WL_CHAN_FREQ_RANGE_5GL: + aux_adc_vmid[3] = 0x89; + aux_adc_gain[3] = 0; + break; + case WL_CHAN_FREQ_RANGE_5GM: + aux_adc_vmid[3] = 0x89; + aux_adc_gain[3] = 0; + break; + case WL_CHAN_FREQ_RANGE_5GH: + aux_adc_vmid[3] = 0x89; + aux_adc_gain[3] = 0; + break; + default: + break; + } + } + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, + 0x08, 16, aux_adc_vmid); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, + 0x18, 16, aux_adc_vmid); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, + 0x0c, 16, aux_adc_gain); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, + 0x1c, 16, aux_adc_gain); + } else if (pdetrange == 1) { + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, + 0x08, 16, sk_adc_vmid); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, + 0x18, 16, sk_adc_vmid); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, + 0x0c, 16, sk_adc_gain); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, + 0x1c, 16, sk_adc_gain); + } else if (pdetrange == 2) { + + u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x74 }; + u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x04 }; + + if (NREV_GE(pi->pubpi.phy_rev, 6)) { + chan_freq_range = + wlc_phy_get_chan_freq_range_nphy(pi, 0); + if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) { + bcm_adc_vmid[3] = 0x8e; + bcm_adc_gain[3] = 0x03; + } else { + bcm_adc_vmid[3] = 0x94; + bcm_adc_gain[3] = 0x03; + } + } else if (NREV_IS(pi->pubpi.phy_rev, 5)) { + bcm_adc_vmid[3] = 0x84; + bcm_adc_gain[3] = 0x02; + } + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, + 0x08, 16, bcm_adc_vmid); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, + 0x18, 16, bcm_adc_vmid); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, + 0x0c, 16, bcm_adc_gain); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, + 0x1c, 16, bcm_adc_gain); + } else if (pdetrange == 3) { + chan_freq_range = + wlc_phy_get_chan_freq_range_nphy(pi, 0); + if ((NREV_GE(pi->pubpi.phy_rev, 4)) + && (chan_freq_range == WL_CHAN_FREQ_RANGE_2G)) { + + u16 auxadc_vmid[] = { + 0xa2, 0xb4, 0xb4, 0x270 }; + u16 auxadc_gain[] = { + 0x02, 0x02, 0x02, 0x00 }; + + wlc_phy_table_write_nphy(pi, + NPHY_TBL_ID_AFECTRL, 4, + 0x08, 16, auxadc_vmid); + wlc_phy_table_write_nphy(pi, + NPHY_TBL_ID_AFECTRL, 4, + 0x18, 16, auxadc_vmid); + wlc_phy_table_write_nphy(pi, + NPHY_TBL_ID_AFECTRL, 4, + 0x0c, 16, auxadc_gain); + wlc_phy_table_write_nphy(pi, + NPHY_TBL_ID_AFECTRL, 4, + 0x1c, 16, auxadc_gain); + } + } else if ((pdetrange == 4) || (pdetrange == 5)) { + u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x0 }; + u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x0 }; + u16 Vmid[2], Av[2]; + + chan_freq_range = + wlc_phy_get_chan_freq_range_nphy(pi, 0); + if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) { + Vmid[0] = (pdetrange == 4) ? 0x8e : 0x89; + Vmid[1] = (pdetrange == 4) ? 0x96 : 0x89; + Av[0] = (pdetrange == 4) ? 2 : 0; + Av[1] = (pdetrange == 4) ? 2 : 0; + } else { + Vmid[0] = (pdetrange == 4) ? 0x89 : 0x74; + Vmid[1] = (pdetrange == 4) ? 0x8b : 0x70; + Av[0] = (pdetrange == 4) ? 2 : 0; + Av[1] = (pdetrange == 4) ? 2 : 0; + } + + bcm_adc_vmid[3] = Vmid[0]; + bcm_adc_gain[3] = Av[0]; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, + 0x08, 16, bcm_adc_vmid); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, + 0x0c, 16, bcm_adc_gain); + + bcm_adc_vmid[3] = Vmid[1]; + bcm_adc_gain[3] = Av[1]; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, + 0x18, 16, bcm_adc_vmid); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, + 0x1c, 16, bcm_adc_gain); + } else { + ASSERT(0); + } + + write_radio_reg(pi, + (RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX0), + 0x0); + write_radio_reg(pi, + (RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX1), + 0x0); + + write_radio_reg(pi, + (RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX0), + 0x6); + write_radio_reg(pi, + (RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX1), + 0x6); + + write_radio_reg(pi, + (RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX0), + 0x7); + write_radio_reg(pi, + (RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX1), + 0x7); + + write_radio_reg(pi, + (RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX0), + 0x88); + write_radio_reg(pi, + (RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX1), + 0x88); + + write_radio_reg(pi, + (RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX0), + 0x0); + write_radio_reg(pi, + (RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX1), + 0x0); + + write_radio_reg(pi, + (RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX0), + 0x0); + write_radio_reg(pi, + (RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX1), + 0x0); + + triso = + (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g. + triso : pi->srom_fem2g.triso; + if (triso == 7) { + wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0); + wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1); + } + + wlc_phy_war_txchain_upd_nphy(pi, pi->sh->hw_phytxchain); + + if (((pi->sh->boardflags2 & BFL2_APLL_WAR) && + (CHSPEC_IS5G(pi->radio_chanspec))) || + (((pi->sh->boardflags2 & BFL2_GPLL_WAR) || + (pi->sh->boardflags2 & BFL2_GPLL_WAR2)) && + (CHSPEC_IS2G(pi->radio_chanspec)))) { + nss1_data_weights = 0x00088888; + ht_data_weights = 0x00088888; + stbc_data_weights = 0x00088888; + } else { + nss1_data_weights = 0x88888888; + ht_data_weights = 0x88888888; + stbc_data_weights = 0x88888888; + } + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL, + 1, 1, 32, &nss1_data_weights); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL, + 1, 2, 32, &ht_data_weights); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL, + 1, 3, 32, &stbc_data_weights); + + if (NREV_IS(pi->pubpi.phy_rev, 4)) { + if (CHSPEC_IS5G(pi->radio_chanspec)) { + write_radio_reg(pi, + RADIO_2056_TX_GMBB_IDAC | + RADIO_2056_TX0, 0x70); + write_radio_reg(pi, + RADIO_2056_TX_GMBB_IDAC | + RADIO_2056_TX1, 0x70); + } + } + + if (!pi->edcrs_threshold_lock) { + write_phy_reg(pi, 0x224, 0x3eb); + write_phy_reg(pi, 0x225, 0x3eb); + write_phy_reg(pi, 0x226, 0x341); + write_phy_reg(pi, 0x227, 0x341); + write_phy_reg(pi, 0x228, 0x42b); + write_phy_reg(pi, 0x229, 0x42b); + write_phy_reg(pi, 0x22a, 0x381); + write_phy_reg(pi, 0x22b, 0x381); + write_phy_reg(pi, 0x22c, 0x42b); + write_phy_reg(pi, 0x22d, 0x42b); + write_phy_reg(pi, 0x22e, 0x381); + write_phy_reg(pi, 0x22f, 0x381); + } + + if (NREV_GE(pi->pubpi.phy_rev, 6)) { + + if (pi->sh->boardflags2 & BFL2_SINGLEANT_CCK) { + wlapi_bmac_mhf(pi->sh->physhim, MHF4, + MHF4_BPHY_TXCORE0, + MHF4_BPHY_TXCORE0, WLC_BAND_ALL); + } + } + } else { + + if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD || + (pi->sh->boardtype == 0x8b)) { + uint i; + u8 war_dlys[] = { 1, 6, 6, 2, 4, 20, 1 }; + for (i = 0; i < ARRAY_SIZE(rfseq_rx2tx_dlys); i++) + rfseq_rx2tx_dlys[i] = war_dlys[i]; + } + + if (CHSPEC_IS5G(pi->radio_chanspec) && pi->phy_5g_pwrgain) { + and_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0xf7); + and_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0xf7); + } else { + or_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0x8); + or_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0x8); + } + + regval = 0x000a; + wlc_phy_table_write_nphy(pi, 8, 1, 0, 16, ®val); + wlc_phy_table_write_nphy(pi, 8, 1, 0x10, 16, ®val); + + if (NREV_LT(pi->pubpi.phy_rev, 3)) { + regval = 0xcdaa; + wlc_phy_table_write_nphy(pi, 8, 1, 0x02, 16, ®val); + wlc_phy_table_write_nphy(pi, 8, 1, 0x12, 16, ®val); + } + + if (NREV_LT(pi->pubpi.phy_rev, 2)) { + regval = 0x0000; + wlc_phy_table_write_nphy(pi, 8, 1, 0x08, 16, ®val); + wlc_phy_table_write_nphy(pi, 8, 1, 0x18, 16, ®val); + + regval = 0x7aab; + wlc_phy_table_write_nphy(pi, 8, 1, 0x07, 16, ®val); + wlc_phy_table_write_nphy(pi, 8, 1, 0x17, 16, ®val); + + regval = 0x0800; + wlc_phy_table_write_nphy(pi, 8, 1, 0x06, 16, ®val); + wlc_phy_table_write_nphy(pi, 8, 1, 0x16, 16, ®val); + } + + write_phy_reg(pi, 0xf8, 0x02d8); + write_phy_reg(pi, 0xf9, 0x0301); + write_phy_reg(pi, 0xfa, 0x02d8); + write_phy_reg(pi, 0xfb, 0x0301); + + wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, rfseq_rx2tx_events, + rfseq_rx2tx_dlys, + sizeof(rfseq_rx2tx_events) / + sizeof(rfseq_rx2tx_events[0])); + + wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX, rfseq_tx2rx_events, + rfseq_tx2rx_dlys, + sizeof(rfseq_tx2rx_events) / + sizeof(rfseq_tx2rx_events[0])); + + wlc_phy_workarounds_nphy_gainctrl(pi); + + if (NREV_LT(pi->pubpi.phy_rev, 2)) { + + if (read_phy_reg(pi, 0xa0) & NPHY_MLenable) + wlapi_bmac_mhf(pi->sh->physhim, MHF3, + MHF3_NPHY_MLADV_WAR, + MHF3_NPHY_MLADV_WAR, + WLC_BAND_ALL); + + } else if (NREV_IS(pi->pubpi.phy_rev, 2)) { + write_phy_reg(pi, 0x1e3, 0x0); + write_phy_reg(pi, 0x1e4, 0x0); + } + + if (NREV_LT(pi->pubpi.phy_rev, 2)) + mod_phy_reg(pi, 0x90, (0x1 << 7), 0); + + alpha0 = 293; + alpha1 = 435; + alpha2 = 261; + beta0 = 366; + beta1 = 205; + beta2 = 32; + write_phy_reg(pi, 0x145, alpha0); + write_phy_reg(pi, 0x146, alpha1); + write_phy_reg(pi, 0x147, alpha2); + write_phy_reg(pi, 0x148, beta0); + write_phy_reg(pi, 0x149, beta1); + write_phy_reg(pi, 0x14a, beta2); + + if (NREV_LT(pi->pubpi.phy_rev, 3)) { + mod_phy_reg(pi, 0x142, (0xf << 12), 0); + + write_phy_reg(pi, 0x192, 0xb5); + write_phy_reg(pi, 0x193, 0xa4); + write_phy_reg(pi, 0x194, 0x0); + } + + if (NREV_IS(pi->pubpi.phy_rev, 2)) { + mod_phy_reg(pi, 0x221, + NPHY_FORCESIG_DECODEGATEDCLKS, + NPHY_FORCESIG_DECODEGATEDCLKS); + } + } + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); +} + +static void wlc_phy_workarounds_nphy_gainctrl(phy_info_t *pi) +{ + u16 w1th, hpf_code, currband; + int ctr; + u8 rfseq_updategainu_events[] = { + NPHY_RFSEQ_CMD_RX_GAIN, + NPHY_RFSEQ_CMD_CLR_HIQ_DIS, + NPHY_RFSEQ_CMD_SET_HPF_BW + }; + u8 rfseq_updategainu_dlys[] = { 10, 30, 1 }; + s8 lna1G_gain_db[] = { 7, 11, 16, 23 }; + s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 }; + s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 }; + s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 }; + s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 }; + s8 lna1A_gain_db[] = { 7, 11, 17, 23 }; + s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 }; + s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 }; + s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 }; + s8 *lna1_gain_db = NULL; + s8 lna2G_gain_db[] = { -5, 6, 10, 14 }; + s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 }; + s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 }; + s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 }; + s8 lna2A_gain_db[] = { -6, 2, 6, 10 }; + s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 }; + s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 }; + s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 }; + s8 *lna2_gain_db = NULL; + s8 tiaG_gain_db[] = { + 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A }; + s8 tiaA_gain_db[] = { + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 }; + s8 tiaA_gain_db_rev4[] = { + 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; + s8 tiaA_gain_db_rev5[] = { + 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; + s8 tiaA_gain_db_rev6[] = { + 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; + s8 *tia_gain_db; + s8 tiaG_gainbits[] = { + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 }; + s8 tiaA_gainbits[] = { + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 }; + s8 tiaA_gainbits_rev4[] = { + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; + s8 tiaA_gainbits_rev5[] = { + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; + s8 tiaA_gainbits_rev6[] = { + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; + s8 *tia_gainbits; + s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 }; + s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 }; + u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f }; + u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f }; + u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f }; + u16 rfseqG_init_gain_rev5_elna[] = { + 0x013f, 0x013f, 0x013f, 0x013f }; + u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f }; + u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f }; + u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f }; + u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f }; + u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f }; + u16 rfseqA_init_gain_rev4_elna[] = { + 0x314f, 0x314f, 0x314f, 0x314f }; + u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f }; + u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f }; + u16 *rfseq_init_gain; + u16 initG_gaincode = 0x627e; + u16 initG_gaincode_rev4 = 0x527e; + u16 initG_gaincode_rev5 = 0x427e; + u16 initG_gaincode_rev5_elna = 0x027e; + u16 initG_gaincode_rev6 = 0x527e; + u16 initG_gaincode_rev6_224B0 = 0x427e; + u16 initG_gaincode_rev6_elna = 0x127e; + u16 initA_gaincode = 0x52de; + u16 initA_gaincode_rev4 = 0x629e; + u16 initA_gaincode_rev4_elna = 0x329e; + u16 initA_gaincode_rev5 = 0x729e; + u16 initA_gaincode_rev6 = 0x729e; + u16 init_gaincode; + u16 clip1hiG_gaincode = 0x107e; + u16 clip1hiG_gaincode_rev4 = 0x007e; + u16 clip1hiG_gaincode_rev5 = 0x1076; + u16 clip1hiG_gaincode_rev6 = 0x007e; + u16 clip1hiA_gaincode = 0x00de; + u16 clip1hiA_gaincode_rev4 = 0x029e; + u16 clip1hiA_gaincode_rev5 = 0x029e; + u16 clip1hiA_gaincode_rev6 = 0x029e; + u16 clip1hi_gaincode; + u16 clip1mdG_gaincode = 0x0066; + u16 clip1mdA_gaincode = 0x00ca; + u16 clip1mdA_gaincode_rev4 = 0x1084; + u16 clip1mdA_gaincode_rev5 = 0x2084; + u16 clip1mdA_gaincode_rev6 = 0x2084; + u16 clip1md_gaincode = 0; + u16 clip1loG_gaincode = 0x0074; + u16 clip1loG_gaincode_rev5[] = { + 0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c + }; + u16 clip1loG_gaincode_rev6[] = { + 0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e + }; + u16 clip1loG_gaincode_rev6_224B0 = 0x1074; + u16 clip1loA_gaincode = 0x00cc; + u16 clip1loA_gaincode_rev4 = 0x0086; + u16 clip1loA_gaincode_rev5 = 0x2086; + u16 clip1loA_gaincode_rev6 = 0x2086; + u16 clip1lo_gaincode; + u8 crsminG_th = 0x18; + u8 crsminG_th_rev5 = 0x18; + u8 crsminG_th_rev6 = 0x18; + u8 crsminA_th = 0x1e; + u8 crsminA_th_rev4 = 0x24; + u8 crsminA_th_rev5 = 0x24; + u8 crsminA_th_rev6 = 0x24; + u8 crsmin_th; + u8 crsminlG_th = 0x18; + u8 crsminlG_th_rev5 = 0x18; + u8 crsminlG_th_rev6 = 0x18; + u8 crsminlA_th = 0x1e; + u8 crsminlA_th_rev4 = 0x24; + u8 crsminlA_th_rev5 = 0x24; + u8 crsminlA_th_rev6 = 0x24; + u8 crsminl_th = 0; + u8 crsminuG_th = 0x18; + u8 crsminuG_th_rev5 = 0x18; + u8 crsminuG_th_rev6 = 0x18; + u8 crsminuA_th = 0x1e; + u8 crsminuA_th_rev4 = 0x24; + u8 crsminuA_th_rev5 = 0x24; + u8 crsminuA_th_rev6 = 0x24; + u8 crsminuA_th_rev6_224B0 = 0x2d; + u8 crsminu_th; + u16 nbclipG_th = 0x20d; + u16 nbclipG_th_rev4 = 0x1a1; + u16 nbclipG_th_rev5 = 0x1d0; + u16 nbclipG_th_rev6 = 0x1d0; + u16 nbclipA_th = 0x1a1; + u16 nbclipA_th_rev4 = 0x107; + u16 nbclipA_th_rev5 = 0x0a9; + u16 nbclipA_th_rev6 = 0x0f0; + u16 nbclip_th = 0; + u8 w1clipG_th = 5; + u8 w1clipG_th_rev5 = 9; + u8 w1clipG_th_rev6 = 5; + u8 w1clipA_th = 25, w1clip_th; + u8 rssi_gain_default = 0x50; + u8 rssiG_gain_rev6_224B0 = 0x50; + u8 rssiA_gain_rev5 = 0x90; + u8 rssiA_gain_rev6 = 0x90; + u8 rssi_gain; + u16 regval[21]; + u8 triso; + + triso = (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.triso : + pi->srom_fem2g.triso; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (pi->pubpi.radiorev == 5) { + + wlc_phy_workarounds_nphy_gainctrl_2057_rev5(pi); + } else if (pi->pubpi.radiorev == 7) { + wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi); + + mod_phy_reg(pi, 0x283, (0xff << 0), (0x44 << 0)); + mod_phy_reg(pi, 0x280, (0xff << 0), (0x44 << 0)); + + } else if ((pi->pubpi.radiorev == 3) + || (pi->pubpi.radiorev == 8)) { + wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi); + + if (pi->pubpi.radiorev == 8) { + mod_phy_reg(pi, 0x283, + (0xff << 0), (0x44 << 0)); + mod_phy_reg(pi, 0x280, + (0xff << 0), (0x44 << 0)); + } + } else { + wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi); + } + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + + mod_phy_reg(pi, 0xa0, (0x1 << 6), (1 << 6)); + + mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13)); + mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13)); + + currband = + read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand; + if (currband == 0) { + if (NREV_GE(pi->pubpi.phy_rev, 6)) { + if (pi->pubpi.radiorev == 11) { + lna1_gain_db = lna1G_gain_db_rev6_224B0; + lna2_gain_db = lna2G_gain_db_rev6_224B0; + rfseq_init_gain = + rfseqG_init_gain_rev6_224B0; + init_gaincode = + initG_gaincode_rev6_224B0; + clip1hi_gaincode = + clip1hiG_gaincode_rev6; + clip1lo_gaincode = + clip1loG_gaincode_rev6_224B0; + nbclip_th = nbclipG_th_rev6; + w1clip_th = w1clipG_th_rev6; + crsmin_th = crsminG_th_rev6; + crsminl_th = crsminlG_th_rev6; + crsminu_th = crsminuG_th_rev6; + rssi_gain = rssiG_gain_rev6_224B0; + } else { + lna1_gain_db = lna1G_gain_db_rev6; + lna2_gain_db = lna2G_gain_db_rev6; + if (pi->sh->boardflags & BFL_EXTLNA) { + + rfseq_init_gain = + rfseqG_init_gain_rev6_elna; + init_gaincode = + initG_gaincode_rev6_elna; + } else { + rfseq_init_gain = + rfseqG_init_gain_rev6; + init_gaincode = + initG_gaincode_rev6; + } + clip1hi_gaincode = + clip1hiG_gaincode_rev6; + switch (triso) { + case 0: + clip1lo_gaincode = + clip1loG_gaincode_rev6[0]; + break; + case 1: + clip1lo_gaincode = + clip1loG_gaincode_rev6[1]; + break; + case 2: + clip1lo_gaincode = + clip1loG_gaincode_rev6[2]; + break; + case 3: + default: + + clip1lo_gaincode = + clip1loG_gaincode_rev6[3]; + break; + case 4: + clip1lo_gaincode = + clip1loG_gaincode_rev6[4]; + break; + case 5: + clip1lo_gaincode = + clip1loG_gaincode_rev6[5]; + break; + case 6: + clip1lo_gaincode = + clip1loG_gaincode_rev6[6]; + break; + case 7: + clip1lo_gaincode = + clip1loG_gaincode_rev6[7]; + break; + } + nbclip_th = nbclipG_th_rev6; + w1clip_th = w1clipG_th_rev6; + crsmin_th = crsminG_th_rev6; + crsminl_th = crsminlG_th_rev6; + crsminu_th = crsminuG_th_rev6; + rssi_gain = rssi_gain_default; + } + } else if (NREV_IS(pi->pubpi.phy_rev, 5)) { + lna1_gain_db = lna1G_gain_db_rev5; + lna2_gain_db = lna2G_gain_db_rev5; + if (pi->sh->boardflags & BFL_EXTLNA) { + + rfseq_init_gain = + rfseqG_init_gain_rev5_elna; + init_gaincode = + initG_gaincode_rev5_elna; + } else { + rfseq_init_gain = rfseqG_init_gain_rev5; + init_gaincode = initG_gaincode_rev5; + } + clip1hi_gaincode = clip1hiG_gaincode_rev5; + switch (triso) { + case 0: + clip1lo_gaincode = + clip1loG_gaincode_rev5[0]; + break; + case 1: + clip1lo_gaincode = + clip1loG_gaincode_rev5[1]; + break; + case 2: + clip1lo_gaincode = + clip1loG_gaincode_rev5[2]; + break; + case 3: + + clip1lo_gaincode = + clip1loG_gaincode_rev5[3]; + break; + case 4: + clip1lo_gaincode = + clip1loG_gaincode_rev5[4]; + break; + case 5: + clip1lo_gaincode = + clip1loG_gaincode_rev5[5]; + break; + case 6: + clip1lo_gaincode = + clip1loG_gaincode_rev5[6]; + break; + case 7: + clip1lo_gaincode = + clip1loG_gaincode_rev5[7]; + break; + default: + clip1lo_gaincode = + clip1loG_gaincode_rev5[3]; + break; + } + nbclip_th = nbclipG_th_rev5; + w1clip_th = w1clipG_th_rev5; + crsmin_th = crsminG_th_rev5; + crsminl_th = crsminlG_th_rev5; + crsminu_th = crsminuG_th_rev5; + rssi_gain = rssi_gain_default; + } else if (NREV_IS(pi->pubpi.phy_rev, 4)) { + lna1_gain_db = lna1G_gain_db_rev4; + lna2_gain_db = lna2G_gain_db; + rfseq_init_gain = rfseqG_init_gain_rev4; + init_gaincode = initG_gaincode_rev4; + clip1hi_gaincode = clip1hiG_gaincode_rev4; + clip1lo_gaincode = clip1loG_gaincode; + nbclip_th = nbclipG_th_rev4; + w1clip_th = w1clipG_th; + crsmin_th = crsminG_th; + crsminl_th = crsminlG_th; + crsminu_th = crsminuG_th; + rssi_gain = rssi_gain_default; + } else { + lna1_gain_db = lna1G_gain_db; + lna2_gain_db = lna2G_gain_db; + rfseq_init_gain = rfseqG_init_gain; + init_gaincode = initG_gaincode; + clip1hi_gaincode = clip1hiG_gaincode; + clip1lo_gaincode = clip1loG_gaincode; + nbclip_th = nbclipG_th; + w1clip_th = w1clipG_th; + crsmin_th = crsminG_th; + crsminl_th = crsminlG_th; + crsminu_th = crsminuG_th; + rssi_gain = rssi_gain_default; + } + tia_gain_db = tiaG_gain_db; + tia_gainbits = tiaG_gainbits; + clip1md_gaincode = clip1mdG_gaincode; + } else { + if (NREV_GE(pi->pubpi.phy_rev, 6)) { + lna1_gain_db = lna1A_gain_db_rev6; + lna2_gain_db = lna2A_gain_db_rev6; + tia_gain_db = tiaA_gain_db_rev6; + tia_gainbits = tiaA_gainbits_rev6; + rfseq_init_gain = rfseqA_init_gain_rev6; + init_gaincode = initA_gaincode_rev6; + clip1hi_gaincode = clip1hiA_gaincode_rev6; + clip1md_gaincode = clip1mdA_gaincode_rev6; + clip1lo_gaincode = clip1loA_gaincode_rev6; + crsmin_th = crsminA_th_rev6; + crsminl_th = crsminlA_th_rev6; + if ((pi->pubpi.radiorev == 11) && + (CHSPEC_IS40(pi->radio_chanspec) == 0)) { + crsminu_th = crsminuA_th_rev6_224B0; + } else { + crsminu_th = crsminuA_th_rev6; + } + nbclip_th = nbclipA_th_rev6; + rssi_gain = rssiA_gain_rev6; + } else if (NREV_IS(pi->pubpi.phy_rev, 5)) { + lna1_gain_db = lna1A_gain_db_rev5; + lna2_gain_db = lna2A_gain_db_rev5; + tia_gain_db = tiaA_gain_db_rev5; + tia_gainbits = tiaA_gainbits_rev5; + rfseq_init_gain = rfseqA_init_gain_rev5; + init_gaincode = initA_gaincode_rev5; + clip1hi_gaincode = clip1hiA_gaincode_rev5; + clip1md_gaincode = clip1mdA_gaincode_rev5; + clip1lo_gaincode = clip1loA_gaincode_rev5; + crsmin_th = crsminA_th_rev5; + crsminl_th = crsminlA_th_rev5; + crsminu_th = crsminuA_th_rev5; + nbclip_th = nbclipA_th_rev5; + rssi_gain = rssiA_gain_rev5; + } else if (NREV_IS(pi->pubpi.phy_rev, 4)) { + lna1_gain_db = lna1A_gain_db_rev4; + lna2_gain_db = lna2A_gain_db_rev4; + tia_gain_db = tiaA_gain_db_rev4; + tia_gainbits = tiaA_gainbits_rev4; + if (pi->sh->boardflags & BFL_EXTLNA_5GHz) { + + rfseq_init_gain = + rfseqA_init_gain_rev4_elna; + init_gaincode = + initA_gaincode_rev4_elna; + } else { + rfseq_init_gain = rfseqA_init_gain_rev4; + init_gaincode = initA_gaincode_rev4; + } + clip1hi_gaincode = clip1hiA_gaincode_rev4; + clip1md_gaincode = clip1mdA_gaincode_rev4; + clip1lo_gaincode = clip1loA_gaincode_rev4; + crsmin_th = crsminA_th_rev4; + crsminl_th = crsminlA_th_rev4; + crsminu_th = crsminuA_th_rev4; + nbclip_th = nbclipA_th_rev4; + rssi_gain = rssi_gain_default; + } else { + lna1_gain_db = lna1A_gain_db; + lna2_gain_db = lna2A_gain_db; + tia_gain_db = tiaA_gain_db; + tia_gainbits = tiaA_gainbits; + rfseq_init_gain = rfseqA_init_gain; + init_gaincode = initA_gaincode; + clip1hi_gaincode = clip1hiA_gaincode; + clip1md_gaincode = clip1mdA_gaincode; + clip1lo_gaincode = clip1loA_gaincode; + crsmin_th = crsminA_th; + crsminl_th = crsminlA_th; + crsminu_th = crsminuA_th; + nbclip_th = nbclipA_th; + rssi_gain = rssi_gain_default; + } + w1clip_th = w1clipA_th; + } + + write_radio_reg(pi, + (RADIO_2056_RX_BIASPOLE_LNAG1_IDAC | + RADIO_2056_RX0), 0x17); + write_radio_reg(pi, + (RADIO_2056_RX_BIASPOLE_LNAG1_IDAC | + RADIO_2056_RX1), 0x17); + + write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX0), + 0xf0); + write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX1), + 0xf0); + + write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX0), + 0x0); + write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX1), + 0x0); + + write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX0), + rssi_gain); + write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX1), + rssi_gain); + + write_radio_reg(pi, + (RADIO_2056_RX_BIASPOLE_LNAA1_IDAC | + RADIO_2056_RX0), 0x17); + write_radio_reg(pi, + (RADIO_2056_RX_BIASPOLE_LNAA1_IDAC | + RADIO_2056_RX1), 0x17); + + write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX0), + 0xFF); + write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX1), + 0xFF); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, + 8, lna1_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, + 8, lna1_gain_db); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, + 8, lna2_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, + 8, lna2_gain_db); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, + 8, tia_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, + 8, tia_gain_db); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, + 8, tia_gainbits); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, + 8, tia_gainbits); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 6, 0x40, + 8, &lpf_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 6, 0x40, + 8, &lpf_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 6, 0x40, + 8, &lpf_gainbits); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 6, 0x40, + 8, &lpf_gainbits); + + write_phy_reg(pi, 0x20, init_gaincode); + write_phy_reg(pi, 0x2a7, init_gaincode); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, + pi->pubpi.phy_corenum, 0x106, 16, + rfseq_init_gain); + + write_phy_reg(pi, 0x22, clip1hi_gaincode); + write_phy_reg(pi, 0x2a9, clip1hi_gaincode); + + write_phy_reg(pi, 0x24, clip1md_gaincode); + write_phy_reg(pi, 0x2ab, clip1md_gaincode); + + write_phy_reg(pi, 0x37, clip1lo_gaincode); + write_phy_reg(pi, 0x2ad, clip1lo_gaincode); + + mod_phy_reg(pi, 0x27d, (0xff << 0), (crsmin_th << 0)); + mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0)); + mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0)); + + write_phy_reg(pi, 0x2b, nbclip_th); + write_phy_reg(pi, 0x41, nbclip_th); + + mod_phy_reg(pi, 0x27, (0x3f << 0), (w1clip_th << 0)); + mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1clip_th << 0)); + + write_phy_reg(pi, 0x150, 0x809c); + + } else { + + mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13)); + mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13)); + + write_phy_reg(pi, 0x2b, 0x84); + write_phy_reg(pi, 0x41, 0x84); + + if (CHSPEC_IS20(pi->radio_chanspec)) { + write_phy_reg(pi, 0x6b, 0x2b); + write_phy_reg(pi, 0x6c, 0x2b); + write_phy_reg(pi, 0x6d, 0x9); + write_phy_reg(pi, 0x6e, 0x9); + } + + w1th = NPHY_RSSICAL_W1_TARGET - 4; + mod_phy_reg(pi, 0x27, (0x3f << 0), (w1th << 0)); + mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1th << 0)); + + if (CHSPEC_IS20(pi->radio_chanspec)) { + mod_phy_reg(pi, 0x1c, (0x1f << 0), (0x1 << 0)); + mod_phy_reg(pi, 0x32, (0x1f << 0), (0x1 << 0)); + + mod_phy_reg(pi, 0x1d, (0x1f << 0), (0x1 << 0)); + mod_phy_reg(pi, 0x33, (0x1f << 0), (0x1 << 0)); + } + + write_phy_reg(pi, 0x150, 0x809c); + + if (pi->nphy_gain_boost) + if ((CHSPEC_IS2G(pi->radio_chanspec)) && + (CHSPEC_IS40(pi->radio_chanspec))) + hpf_code = 4; + else + hpf_code = 5; + else if (CHSPEC_IS40(pi->radio_chanspec)) + hpf_code = 6; + else + hpf_code = 7; + + mod_phy_reg(pi, 0x20, (0x1f << 7), (hpf_code << 7)); + mod_phy_reg(pi, 0x36, (0x1f << 7), (hpf_code << 7)); + + for (ctr = 0; ctr < 4; ctr++) { + regval[ctr] = (hpf_code << 8) | 0x7c; + } + wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval); + + wlc_phy_adjust_lnagaintbl_nphy(pi); + + if (pi->nphy_elna_gain_config) { + regval[0] = 0; + regval[1] = 1; + regval[2] = 1; + regval[3] = 1; + wlc_phy_table_write_nphy(pi, 2, 4, 8, 16, regval); + wlc_phy_table_write_nphy(pi, 3, 4, 8, 16, regval); + + for (ctr = 0; ctr < 4; ctr++) { + regval[ctr] = (hpf_code << 8) | 0x74; + } + wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval); + } + + if (NREV_IS(pi->pubpi.phy_rev, 2)) { + for (ctr = 0; ctr < 21; ctr++) { + regval[ctr] = 3 * ctr; + } + wlc_phy_table_write_nphy(pi, 0, 21, 32, 16, regval); + wlc_phy_table_write_nphy(pi, 1, 21, 32, 16, regval); + + for (ctr = 0; ctr < 21; ctr++) { + regval[ctr] = (u16) ctr; + } + wlc_phy_table_write_nphy(pi, 2, 21, 32, 16, regval); + wlc_phy_table_write_nphy(pi, 3, 21, 32, 16, regval); + } + + wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_UPDATEGAINU, + rfseq_updategainu_events, + rfseq_updategainu_dlys, + sizeof(rfseq_updategainu_events) / + sizeof(rfseq_updategainu_events[0])); + + mod_phy_reg(pi, 0x153, (0xff << 8), (90 << 8)); + + if (CHSPEC_IS2G(pi->radio_chanspec)) + mod_phy_reg(pi, + (NPHY_TO_BPHY_OFF + BPHY_OPTIONAL_MODES), + 0x7f, 0x4); + } +} + +static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(phy_info_t *pi) +{ + s8 lna1_gain_db[] = { 8, 13, 17, 22 }; + s8 lna2_gain_db[] = { -2, 7, 11, 15 }; + s8 tia_gain_db[] = { -4, -1, 2, 5, 5, 5, 5, 5, 5, 5 }; + s8 tia_gainbits[] = { + 0x0, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 }; + + mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13)); + mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13)); + + mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0)); + + mod_phy_reg(pi, 0x283, (0xff << 0), (0x3c << 0)); + mod_phy_reg(pi, 0x280, (0xff << 0), (0x3c << 0)); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x8, 8, + lna1_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x8, 8, + lna1_gain_db); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, 8, + lna2_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, 8, + lna2_gain_db); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8, + tia_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8, + tia_gain_db); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8, + tia_gainbits); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8, + tia_gainbits); + + write_phy_reg(pi, 0x37, 0x74); + write_phy_reg(pi, 0x2ad, 0x74); + write_phy_reg(pi, 0x38, 0x18); + write_phy_reg(pi, 0x2ae, 0x18); + + write_phy_reg(pi, 0x2b, 0xe8); + write_phy_reg(pi, 0x41, 0xe8); + + if (CHSPEC_IS20(pi->radio_chanspec)) { + + mod_phy_reg(pi, 0x300, (0x3f << 0), (0x12 << 0)); + mod_phy_reg(pi, 0x301, (0x3f << 0), (0x12 << 0)); + } else { + + mod_phy_reg(pi, 0x300, (0x3f << 0), (0x10 << 0)); + mod_phy_reg(pi, 0x301, (0x3f << 0), (0x10 << 0)); + } +} + +static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(phy_info_t *pi) +{ + u16 currband; + s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 }; + s8 *lna1_gain_db = NULL; + s8 *lna1_gain_db_2 = NULL; + s8 *lna2_gain_db = NULL; + s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 }; + s8 *tia_gain_db; + s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 }; + s8 *tia_gainbits; + u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f }; + u16 *rfseq_init_gain; + u16 init_gaincode; + u16 clip1hi_gaincode; + u16 clip1md_gaincode = 0; + u16 clip1md_gaincode_B; + u16 clip1lo_gaincode; + u16 clip1lo_gaincode_B; + u8 crsminl_th = 0; + u8 crsminu_th; + u16 nbclip_th = 0; + u8 w1clip_th; + u16 freq; + s8 nvar_baseline_offset0 = 0, nvar_baseline_offset1 = 0; + u8 chg_nbclip_th = 0; + + mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13)); + mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13)); + + currband = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand; + if (currband == 0) { + + lna1_gain_db = lna1G_gain_db_rev7; + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8, + lna1_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8, + lna1_gain_db); + + mod_phy_reg(pi, 0x283, (0xff << 0), (0x40 << 0)); + + if (CHSPEC_IS40(pi->radio_chanspec)) { + mod_phy_reg(pi, 0x280, (0xff << 0), (0x3e << 0)); + mod_phy_reg(pi, 0x283, (0xff << 0), (0x3e << 0)); + } + + mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0)); + + if (CHSPEC_IS20(pi->radio_chanspec)) { + mod_phy_reg(pi, 0x300, (0x3f << 0), (13 << 0)); + mod_phy_reg(pi, 0x301, (0x3f << 0), (13 << 0)); + } + } else { + + init_gaincode = 0x9e; + clip1hi_gaincode = 0x9e; + clip1md_gaincode_B = 0x24; + clip1lo_gaincode = 0x8a; + clip1lo_gaincode_B = 8; + rfseq_init_gain = rfseqA_init_gain_rev7; + + tia_gain_db = tiaA_gain_db_rev7; + tia_gainbits = tiaA_gainbits_rev7; + + freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec)); + if (CHSPEC_IS20(pi->radio_chanspec)) { + + w1clip_th = 25; + clip1md_gaincode = 0x82; + + if ((freq <= 5080) || (freq == 5825)) { + + s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 }; + s8 lna1A_gain_db_2_rev7[] = { + 11, 17, 22, 25 }; + s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; + + crsminu_th = 0x3e; + lna1_gain_db = lna1A_gain_db_rev7; + lna1_gain_db_2 = lna1A_gain_db_2_rev7; + lna2_gain_db = lna2A_gain_db_rev7; + } else if ((freq >= 5500) && (freq <= 5700)) { + + s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 }; + s8 lna1A_gain_db_2_rev7[] = { + 12, 18, 22, 26 }; + s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 }; + + crsminu_th = 0x45; + clip1md_gaincode_B = 0x14; + nbclip_th = 0xff; + chg_nbclip_th = 1; + lna1_gain_db = lna1A_gain_db_rev7; + lna1_gain_db_2 = lna1A_gain_db_2_rev7; + lna2_gain_db = lna2A_gain_db_rev7; + } else { + + s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 }; + s8 lna1A_gain_db_2_rev7[] = { + 12, 18, 22, 26 }; + s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; + + crsminu_th = 0x41; + lna1_gain_db = lna1A_gain_db_rev7; + lna1_gain_db_2 = lna1A_gain_db_2_rev7; + lna2_gain_db = lna2A_gain_db_rev7; + } + + if (freq <= 4920) { + nvar_baseline_offset0 = 5; + nvar_baseline_offset1 = 5; + } else if ((freq > 4920) && (freq <= 5320)) { + nvar_baseline_offset0 = 3; + nvar_baseline_offset1 = 5; + } else if ((freq > 5320) && (freq <= 5700)) { + nvar_baseline_offset0 = 3; + nvar_baseline_offset1 = 2; + } else { + nvar_baseline_offset0 = 4; + nvar_baseline_offset1 = 0; + } + } else { + + crsminu_th = 0x3a; + crsminl_th = 0x3a; + w1clip_th = 20; + + if ((freq >= 4920) && (freq <= 5320)) { + nvar_baseline_offset0 = 4; + nvar_baseline_offset1 = 5; + } else if ((freq > 5320) && (freq <= 5550)) { + nvar_baseline_offset0 = 4; + nvar_baseline_offset1 = 2; + } else { + nvar_baseline_offset0 = 5; + nvar_baseline_offset1 = 3; + } + } + + write_phy_reg(pi, 0x20, init_gaincode); + write_phy_reg(pi, 0x2a7, init_gaincode); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, + pi->pubpi.phy_corenum, 0x106, 16, + rfseq_init_gain); + + write_phy_reg(pi, 0x22, clip1hi_gaincode); + write_phy_reg(pi, 0x2a9, clip1hi_gaincode); + + write_phy_reg(pi, 0x36, clip1md_gaincode_B); + write_phy_reg(pi, 0x2ac, clip1md_gaincode_B); + + write_phy_reg(pi, 0x37, clip1lo_gaincode); + write_phy_reg(pi, 0x2ad, clip1lo_gaincode); + write_phy_reg(pi, 0x38, clip1lo_gaincode_B); + write_phy_reg(pi, 0x2ae, clip1lo_gaincode_B); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8, + tia_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8, + tia_gain_db); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8, + tia_gainbits); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8, + tia_gainbits); + + mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0)); + + if (chg_nbclip_th == 1) { + write_phy_reg(pi, 0x2b, nbclip_th); + write_phy_reg(pi, 0x41, nbclip_th); + } + + mod_phy_reg(pi, 0x300, (0x3f << 0), (w1clip_th << 0)); + mod_phy_reg(pi, 0x301, (0x3f << 0), (w1clip_th << 0)); + + mod_phy_reg(pi, 0x2e4, + (0x3f << 0), (nvar_baseline_offset0 << 0)); + + mod_phy_reg(pi, 0x2e4, + (0x3f << 6), (nvar_baseline_offset1 << 6)); + + if (CHSPEC_IS20(pi->radio_chanspec)) { + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8, + lna1_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8, + lna1_gain_db_2); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, + 8, lna2_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, + 8, lna2_gain_db); + + write_phy_reg(pi, 0x24, clip1md_gaincode); + write_phy_reg(pi, 0x2ab, clip1md_gaincode); + } else { + mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0)); + } + + } + +} + +static void wlc_phy_adjust_lnagaintbl_nphy(phy_info_t *pi) +{ + uint core; + int ctr; + s16 gain_delta[2]; + u8 curr_channel; + u16 minmax_gain[2]; + u16 regval[4]; + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + if (pi->nphy_gain_boost) { + if ((CHSPEC_IS2G(pi->radio_chanspec))) { + + gain_delta[0] = 6; + gain_delta[1] = 6; + } else { + + curr_channel = CHSPEC_CHANNEL(pi->radio_chanspec); + gain_delta[0] = + (s16) + PHY_HW_ROUND(((nphy_lnagain_est0[0] * + curr_channel) + + nphy_lnagain_est0[1]), 13); + gain_delta[1] = + (s16) + PHY_HW_ROUND(((nphy_lnagain_est1[0] * + curr_channel) + + nphy_lnagain_est1[1]), 13); + } + } else { + + gain_delta[0] = 0; + gain_delta[1] = 0; + } + + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + if (pi->nphy_elna_gain_config) { + + regval[0] = nphy_def_lnagains[2] + gain_delta[core]; + regval[1] = nphy_def_lnagains[3] + gain_delta[core]; + regval[2] = nphy_def_lnagains[3] + gain_delta[core]; + regval[3] = nphy_def_lnagains[3] + gain_delta[core]; + } else { + for (ctr = 0; ctr < 4; ctr++) { + regval[ctr] = + nphy_def_lnagains[ctr] + gain_delta[core]; + } + } + wlc_phy_table_write_nphy(pi, core, 4, 8, 16, regval); + + minmax_gain[core] = + (u16) (nphy_def_lnagains[2] + gain_delta[core] + 4); + } + + mod_phy_reg(pi, 0x1e, (0xff << 0), (minmax_gain[0] << 0)); + mod_phy_reg(pi, 0x34, (0xff << 0), (minmax_gain[1] << 0)); + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); +} + +void wlc_phy_switch_radio_nphy(phy_info_t *pi, bool on) +{ + if (on) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (!pi->radio_is_on) { + wlc_phy_radio_preinit_205x(pi); + wlc_phy_radio_init_2057(pi); + wlc_phy_radio_postinit_2057(pi); + } + + wlc_phy_chanspec_set((wlc_phy_t *) pi, + pi->radio_chanspec); + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + wlc_phy_radio_preinit_205x(pi); + wlc_phy_radio_init_2056(pi); + wlc_phy_radio_postinit_2056(pi); + + wlc_phy_chanspec_set((wlc_phy_t *) pi, + pi->radio_chanspec); + } else { + wlc_phy_radio_preinit_2055(pi); + wlc_phy_radio_init_2055(pi); + wlc_phy_radio_postinit_2055(pi); + } + + pi->radio_is_on = true; + + } else { + + if (NREV_GE(pi->pubpi.phy_rev, 3) + && NREV_LT(pi->pubpi.phy_rev, 7)) { + and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU); + mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x0); + + write_radio_reg(pi, + RADIO_2056_TX_PADA_BOOST_TUNE | + RADIO_2056_TX0, 0); + write_radio_reg(pi, + RADIO_2056_TX_PADG_BOOST_TUNE | + RADIO_2056_TX0, 0); + write_radio_reg(pi, + RADIO_2056_TX_PGAA_BOOST_TUNE | + RADIO_2056_TX0, 0); + write_radio_reg(pi, + RADIO_2056_TX_PGAG_BOOST_TUNE | + RADIO_2056_TX0, 0); + mod_radio_reg(pi, + RADIO_2056_TX_MIXA_BOOST_TUNE | + RADIO_2056_TX0, 0xf0, 0); + write_radio_reg(pi, + RADIO_2056_TX_MIXG_BOOST_TUNE | + RADIO_2056_TX0, 0); + + write_radio_reg(pi, + RADIO_2056_TX_PADA_BOOST_TUNE | + RADIO_2056_TX1, 0); + write_radio_reg(pi, + RADIO_2056_TX_PADG_BOOST_TUNE | + RADIO_2056_TX1, 0); + write_radio_reg(pi, + RADIO_2056_TX_PGAA_BOOST_TUNE | + RADIO_2056_TX1, 0); + write_radio_reg(pi, + RADIO_2056_TX_PGAG_BOOST_TUNE | + RADIO_2056_TX1, 0); + mod_radio_reg(pi, + RADIO_2056_TX_MIXA_BOOST_TUNE | + RADIO_2056_TX1, 0xf0, 0); + write_radio_reg(pi, + RADIO_2056_TX_MIXG_BOOST_TUNE | + RADIO_2056_TX1, 0); + + pi->radio_is_on = false; + } + + if (NREV_GE(pi->pubpi.phy_rev, 8)) { + and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU); + pi->radio_is_on = false; + } + + } +} + +static void wlc_phy_radio_preinit_2055(phy_info_t *pi) +{ + + and_phy_reg(pi, 0x78, ~RFCC_POR_FORCE); + or_phy_reg(pi, 0x78, RFCC_CHIP0_PU | RFCC_OE_POR_FORCE); + + or_phy_reg(pi, 0x78, RFCC_POR_FORCE); +} + +static void wlc_phy_radio_init_2055(phy_info_t *pi) +{ + wlc_phy_init_radio_regs(pi, regs_2055, RADIO_DEFAULT_CORE); +} + +static void wlc_phy_radio_postinit_2055(phy_info_t *pi) +{ + + and_radio_reg(pi, RADIO_2055_MASTER_CNTRL1, + ~(RADIO_2055_JTAGCTRL_MASK | RADIO_2055_JTAGSYNC_MASK)); + + if (((pi->sh->sromrev >= 4) + && !(pi->sh->boardflags2 & BFL2_RXBB_INT_REG_DIS)) + || ((pi->sh->sromrev < 4))) { + and_radio_reg(pi, RADIO_2055_CORE1_RXBB_REGULATOR, 0x7F); + and_radio_reg(pi, RADIO_2055_CORE2_RXBB_REGULATOR, 0x7F); + } + + mod_radio_reg(pi, RADIO_2055_RRCCAL_N_OPT_SEL, 0x3F, 0x2C); + write_radio_reg(pi, RADIO_2055_CAL_MISC, 0x3C); + + and_radio_reg(pi, RADIO_2055_CAL_MISC, + ~(RADIO_2055_RRCAL_START | RADIO_2055_RRCAL_RST_N)); + + or_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL, RADIO_2055_CAL_LPO_ENABLE); + + or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_RST_N); + + udelay(1000); + + or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_START); + + SPINWAIT(((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) & + RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE), 2000); + + ASSERT((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) & + RADIO_2055_RCAL_DONE) == RADIO_2055_RCAL_DONE); + + and_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL, + ~(RADIO_2055_CAL_LPO_ENABLE)); + + wlc_phy_chanspec_set((wlc_phy_t *) pi, pi->radio_chanspec); + + write_radio_reg(pi, RADIO_2055_CORE1_RXBB_LPF, 9); + write_radio_reg(pi, RADIO_2055_CORE2_RXBB_LPF, 9); + + write_radio_reg(pi, RADIO_2055_CORE1_RXBB_MIDAC_HIPAS, 0x83); + write_radio_reg(pi, RADIO_2055_CORE2_RXBB_MIDAC_HIPAS, 0x83); + + mod_radio_reg(pi, RADIO_2055_CORE1_LNA_GAINBST, + RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE); + mod_radio_reg(pi, RADIO_2055_CORE2_LNA_GAINBST, + RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE); + if (pi->nphy_gain_boost) { + and_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1, + ~(RADIO_2055_GAINBST_DISABLE)); + and_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1, + ~(RADIO_2055_GAINBST_DISABLE)); + } else { + or_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1, + RADIO_2055_GAINBST_DISABLE); + or_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1, + RADIO_2055_GAINBST_DISABLE); + } + + udelay(2); +} + +static void wlc_phy_radio_preinit_205x(phy_info_t *pi) +{ + + and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU); + and_phy_reg(pi, 0x78, RFCC_OE_POR_FORCE); + + or_phy_reg(pi, 0x78, ~RFCC_OE_POR_FORCE); + or_phy_reg(pi, 0x78, RFCC_CHIP0_PU); + +} + +static void wlc_phy_radio_init_2056(phy_info_t *pi) +{ + radio_regs_t *regs_SYN_2056_ptr = NULL; + radio_regs_t *regs_TX_2056_ptr = NULL; + radio_regs_t *regs_RX_2056_ptr = NULL; + + if (NREV_IS(pi->pubpi.phy_rev, 3)) { + regs_SYN_2056_ptr = regs_SYN_2056; + regs_TX_2056_ptr = regs_TX_2056; + regs_RX_2056_ptr = regs_RX_2056; + } else if (NREV_IS(pi->pubpi.phy_rev, 4)) { + regs_SYN_2056_ptr = regs_SYN_2056_A1; + regs_TX_2056_ptr = regs_TX_2056_A1; + regs_RX_2056_ptr = regs_RX_2056_A1; + } else { + switch (pi->pubpi.radiorev) { + case 5: + regs_SYN_2056_ptr = regs_SYN_2056_rev5; + regs_TX_2056_ptr = regs_TX_2056_rev5; + regs_RX_2056_ptr = regs_RX_2056_rev5; + break; + + case 6: + regs_SYN_2056_ptr = regs_SYN_2056_rev6; + regs_TX_2056_ptr = regs_TX_2056_rev6; + regs_RX_2056_ptr = regs_RX_2056_rev6; + break; + + case 7: + case 9: + regs_SYN_2056_ptr = regs_SYN_2056_rev7; + regs_TX_2056_ptr = regs_TX_2056_rev7; + regs_RX_2056_ptr = regs_RX_2056_rev7; + break; + + case 8: + regs_SYN_2056_ptr = regs_SYN_2056_rev8; + regs_TX_2056_ptr = regs_TX_2056_rev8; + regs_RX_2056_ptr = regs_RX_2056_rev8; + break; + + case 11: + regs_SYN_2056_ptr = regs_SYN_2056_rev11; + regs_TX_2056_ptr = regs_TX_2056_rev11; + regs_RX_2056_ptr = regs_RX_2056_rev11; + break; + + default: + ASSERT(0); + break; + } + } + + wlc_phy_init_radio_regs(pi, regs_SYN_2056_ptr, (u16) RADIO_2056_SYN); + + wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX0); + + wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX1); + + wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX0); + + wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX1); +} + +static void wlc_phy_radio_postinit_2056(phy_info_t *pi) +{ + mod_radio_reg(pi, RADIO_2056_SYN_COM_CTRL, 0xb, 0xb); + + mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x2); + mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x2); + udelay(1000); + mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x0); + + if ((pi->sh->boardflags2 & BFL2_LEGACY) + || (pi->sh->boardflags2 & BFL2_XTALBUFOUTEN)) { + + mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xf4, 0x0); + } else { + + mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xfc, 0x0); + } + + mod_radio_reg(pi, RADIO_2056_SYN_RCCAL_CTRL0, 0x1, 0x0); + + if (pi->phy_init_por) { + wlc_phy_radio205x_rcal(pi); + } +} + +static void wlc_phy_radio_init_2057(phy_info_t *pi) +{ + radio_20xx_regs_t *regs_2057_ptr = NULL; + + if (NREV_IS(pi->pubpi.phy_rev, 7)) { + + regs_2057_ptr = regs_2057_rev4; + } else if (NREV_IS(pi->pubpi.phy_rev, 8) + || NREV_IS(pi->pubpi.phy_rev, 9)) { + switch (pi->pubpi.radiorev) { + case 5: + + if (pi->pubpi.radiover == 0x0) { + + regs_2057_ptr = regs_2057_rev5; + + } else if (pi->pubpi.radiover == 0x1) { + + regs_2057_ptr = regs_2057_rev5v1; + } else { + ASSERT(0); + break; + } + + case 7: + + regs_2057_ptr = regs_2057_rev7; + break; + + case 8: + + regs_2057_ptr = regs_2057_rev8; + break; + + default: + ASSERT(0); + break; + } + } else { + ASSERT(0); + } + + wlc_phy_init_radio_regs_allbands(pi, regs_2057_ptr); +} + +static void wlc_phy_radio_postinit_2057(phy_info_t *pi) +{ + + mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x1, 0x1); + + if (pi->sh->chip == !BCM6362_CHIP_ID) { + + mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x2, 0x2); + } + + mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x78); + mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x80); + mdelay(2); + mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x0); + mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x0); + + if (pi->phy_init_por) { + wlc_phy_radio205x_rcal(pi); + wlc_phy_radio2057_rccal(pi); + } + + mod_radio_reg(pi, RADIO_2057_RFPLL_MASTER, 0x8, 0x0); +} + +static bool +wlc_phy_chan2freq_nphy(phy_info_t *pi, uint channel, int *f, + chan_info_nphy_radio2057_t **t0, + chan_info_nphy_radio205x_t **t1, + chan_info_nphy_radio2057_rev5_t **t2, + chan_info_nphy_2055_t **t3) +{ + uint i; + chan_info_nphy_radio2057_t *chan_info_tbl_p_0 = NULL; + chan_info_nphy_radio205x_t *chan_info_tbl_p_1 = NULL; + chan_info_nphy_radio2057_rev5_t *chan_info_tbl_p_2 = NULL; + u32 tbl_len = 0; + + int freq = 0; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + if (NREV_IS(pi->pubpi.phy_rev, 7)) { + + chan_info_tbl_p_0 = chan_info_nphyrev7_2057_rev4; + tbl_len = ARRAY_SIZE(chan_info_nphyrev7_2057_rev4); + + } else if (NREV_IS(pi->pubpi.phy_rev, 8) + || NREV_IS(pi->pubpi.phy_rev, 9)) { + switch (pi->pubpi.radiorev) { + + case 5: + + if (pi->pubpi.radiover == 0x0) { + + chan_info_tbl_p_2 = + chan_info_nphyrev8_2057_rev5; + tbl_len = + ARRAY_SIZE + (chan_info_nphyrev8_2057_rev5); + + } else if (pi->pubpi.radiover == 0x1) { + + chan_info_tbl_p_2 = + chan_info_nphyrev9_2057_rev5v1; + tbl_len = + ARRAY_SIZE + (chan_info_nphyrev9_2057_rev5v1); + + } + break; + + case 7: + chan_info_tbl_p_0 = + chan_info_nphyrev8_2057_rev7; + tbl_len = + ARRAY_SIZE(chan_info_nphyrev8_2057_rev7); + break; + + case 8: + chan_info_tbl_p_0 = + chan_info_nphyrev8_2057_rev8; + tbl_len = + ARRAY_SIZE(chan_info_nphyrev8_2057_rev8); + break; + + default: + if (NORADIO_ENAB(pi->pubpi)) { + goto fail; + } + break; + } + } else if (NREV_IS(pi->pubpi.phy_rev, 16)) { + + chan_info_tbl_p_0 = chan_info_nphyrev8_2057_rev8; + tbl_len = ARRAY_SIZE(chan_info_nphyrev8_2057_rev8); + } else { + goto fail; + } + + for (i = 0; i < tbl_len; i++) { + if (pi->pubpi.radiorev == 5) { + + if (chan_info_tbl_p_2[i].chan == channel) + break; + } else { + + if (chan_info_tbl_p_0[i].chan == channel) + break; + } + } + + if (i >= tbl_len) { + ASSERT(i < tbl_len); + goto fail; + } + if (pi->pubpi.radiorev == 5) { + *t2 = &chan_info_tbl_p_2[i]; + freq = chan_info_tbl_p_2[i].freq; + } else { + *t0 = &chan_info_tbl_p_0[i]; + freq = chan_info_tbl_p_0[i].freq; + } + + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (NREV_IS(pi->pubpi.phy_rev, 3)) { + chan_info_tbl_p_1 = chan_info_nphyrev3_2056; + tbl_len = ARRAY_SIZE(chan_info_nphyrev3_2056); + } else if (NREV_IS(pi->pubpi.phy_rev, 4)) { + chan_info_tbl_p_1 = chan_info_nphyrev4_2056_A1; + tbl_len = ARRAY_SIZE(chan_info_nphyrev4_2056_A1); + } else if (NREV_IS(pi->pubpi.phy_rev, 5) + || NREV_IS(pi->pubpi.phy_rev, 6)) { + switch (pi->pubpi.radiorev) { + case 5: + chan_info_tbl_p_1 = chan_info_nphyrev5_2056v5; + tbl_len = ARRAY_SIZE(chan_info_nphyrev5_2056v5); + break; + case 6: + chan_info_tbl_p_1 = chan_info_nphyrev6_2056v6; + tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v6); + break; + case 7: + case 9: + chan_info_tbl_p_1 = chan_info_nphyrev5n6_2056v7; + tbl_len = + ARRAY_SIZE(chan_info_nphyrev5n6_2056v7); + break; + case 8: + chan_info_tbl_p_1 = chan_info_nphyrev6_2056v8; + tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v8); + break; + case 11: + chan_info_tbl_p_1 = chan_info_nphyrev6_2056v11; + tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v11); + break; + default: + if (NORADIO_ENAB(pi->pubpi)) { + goto fail; + } + break; + } + } + + for (i = 0; i < tbl_len; i++) { + if (chan_info_tbl_p_1[i].chan == channel) + break; + } + + if (i >= tbl_len) { + ASSERT(i < tbl_len); + goto fail; + } + *t1 = &chan_info_tbl_p_1[i]; + freq = chan_info_tbl_p_1[i].freq; + + } else { + for (i = 0; i < ARRAY_SIZE(chan_info_nphy_2055); i++) + if (chan_info_nphy_2055[i].chan == channel) + break; + + if (i >= ARRAY_SIZE(chan_info_nphy_2055)) { + ASSERT(i < ARRAY_SIZE(chan_info_nphy_2055)); + goto fail; + } + *t3 = &chan_info_nphy_2055[i]; + freq = chan_info_nphy_2055[i].freq; + } + + *f = freq; + return true; + + fail: + *f = WL_CHAN_FREQ_RANGE_2G; + return false; +} + +u8 wlc_phy_get_chan_freq_range_nphy(phy_info_t *pi, uint channel) +{ + int freq; + chan_info_nphy_radio2057_t *t0 = NULL; + chan_info_nphy_radio205x_t *t1 = NULL; + chan_info_nphy_radio2057_rev5_t *t2 = NULL; + chan_info_nphy_2055_t *t3 = NULL; + + if (NORADIO_ENAB(pi->pubpi)) + return WL_CHAN_FREQ_RANGE_2G; + + if (channel == 0) + channel = CHSPEC_CHANNEL(pi->radio_chanspec); + + wlc_phy_chan2freq_nphy(pi, channel, &freq, &t0, &t1, &t2, &t3); + + if (CHSPEC_IS2G(pi->radio_chanspec)) + return WL_CHAN_FREQ_RANGE_2G; + + if ((freq >= BASE_LOW_5G_CHAN) && (freq < BASE_MID_5G_CHAN)) { + return WL_CHAN_FREQ_RANGE_5GL; + } else if ((freq >= BASE_MID_5G_CHAN) && (freq < BASE_HIGH_5G_CHAN)) { + return WL_CHAN_FREQ_RANGE_5GM; + } else { + return WL_CHAN_FREQ_RANGE_5GH; + } +} + +static void +wlc_phy_chanspec_radio2055_setup(phy_info_t *pi, chan_info_nphy_2055_t *ci) +{ + + write_radio_reg(pi, RADIO_2055_PLL_REF, ci->RF_pll_ref); + write_radio_reg(pi, RADIO_2055_RF_PLL_MOD0, ci->RF_rf_pll_mod0); + write_radio_reg(pi, RADIO_2055_RF_PLL_MOD1, ci->RF_rf_pll_mod1); + write_radio_reg(pi, RADIO_2055_VCO_CAP_TAIL, ci->RF_vco_cap_tail); + + WLC_PHY_WAR_PR51571(pi); + + write_radio_reg(pi, RADIO_2055_VCO_CAL1, ci->RF_vco_cal1); + write_radio_reg(pi, RADIO_2055_VCO_CAL2, ci->RF_vco_cal2); + write_radio_reg(pi, RADIO_2055_PLL_LF_C1, ci->RF_pll_lf_c1); + write_radio_reg(pi, RADIO_2055_PLL_LF_R1, ci->RF_pll_lf_r1); + + WLC_PHY_WAR_PR51571(pi); + + write_radio_reg(pi, RADIO_2055_PLL_LF_C2, ci->RF_pll_lf_c2); + write_radio_reg(pi, RADIO_2055_LGBUF_CEN_BUF, ci->RF_lgbuf_cen_buf); + write_radio_reg(pi, RADIO_2055_LGEN_TUNE1, ci->RF_lgen_tune1); + write_radio_reg(pi, RADIO_2055_LGEN_TUNE2, ci->RF_lgen_tune2); + + WLC_PHY_WAR_PR51571(pi); + + write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_A_TUNE, + ci->RF_core1_lgbuf_a_tune); + write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_G_TUNE, + ci->RF_core1_lgbuf_g_tune); + write_radio_reg(pi, RADIO_2055_CORE1_RXRF_REG1, ci->RF_core1_rxrf_reg1); + write_radio_reg(pi, RADIO_2055_CORE1_TX_PGA_PAD_TN, + ci->RF_core1_tx_pga_pad_tn); + + WLC_PHY_WAR_PR51571(pi); + + write_radio_reg(pi, RADIO_2055_CORE1_TX_MX_BGTRIM, + ci->RF_core1_tx_mx_bgtrim); + write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_A_TUNE, + ci->RF_core2_lgbuf_a_tune); + write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_G_TUNE, + ci->RF_core2_lgbuf_g_tune); + write_radio_reg(pi, RADIO_2055_CORE2_RXRF_REG1, ci->RF_core2_rxrf_reg1); + + WLC_PHY_WAR_PR51571(pi); + + write_radio_reg(pi, RADIO_2055_CORE2_TX_PGA_PAD_TN, + ci->RF_core2_tx_pga_pad_tn); + write_radio_reg(pi, RADIO_2055_CORE2_TX_MX_BGTRIM, + ci->RF_core2_tx_mx_bgtrim); + + udelay(50); + + write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x05); + write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x45); + + WLC_PHY_WAR_PR51571(pi); + + write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x65); + + udelay(300); +} + +static void +wlc_phy_chanspec_radio2056_setup(phy_info_t *pi, + const chan_info_nphy_radio205x_t *ci) +{ + radio_regs_t *regs_SYN_2056_ptr = NULL; + + write_radio_reg(pi, + RADIO_2056_SYN_PLL_VCOCAL1 | RADIO_2056_SYN, + ci->RF_SYN_pll_vcocal1); + write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL2 | RADIO_2056_SYN, + ci->RF_SYN_pll_vcocal2); + write_radio_reg(pi, RADIO_2056_SYN_PLL_REFDIV | RADIO_2056_SYN, + ci->RF_SYN_pll_refdiv); + write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD2 | RADIO_2056_SYN, + ci->RF_SYN_pll_mmd2); + write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD1 | RADIO_2056_SYN, + ci->RF_SYN_pll_mmd1); + write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN, + ci->RF_SYN_pll_loopfilter1); + write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN, + ci->RF_SYN_pll_loopfilter2); + write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER3 | RADIO_2056_SYN, + ci->RF_SYN_pll_loopfilter3); + write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN, + ci->RF_SYN_pll_loopfilter4); + write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER5 | RADIO_2056_SYN, + ci->RF_SYN_pll_loopfilter5); + write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR27 | RADIO_2056_SYN, + ci->RF_SYN_reserved_addr27); + write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR28 | RADIO_2056_SYN, + ci->RF_SYN_reserved_addr28); + write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR29 | RADIO_2056_SYN, + ci->RF_SYN_reserved_addr29); + write_radio_reg(pi, RADIO_2056_SYN_LOGEN_VCOBUF1 | RADIO_2056_SYN, + ci->RF_SYN_logen_VCOBUF1); + write_radio_reg(pi, RADIO_2056_SYN_LOGEN_MIXER2 | RADIO_2056_SYN, + ci->RF_SYN_logen_MIXER2); + write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF3 | RADIO_2056_SYN, + ci->RF_SYN_logen_BUF3); + write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF4 | RADIO_2056_SYN, + ci->RF_SYN_logen_BUF4); + + write_radio_reg(pi, + RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX0, + ci->RF_RX0_lnaa_tune); + write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX0, + ci->RF_RX0_lnag_tune); + write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX0, + ci->RF_TX0_intpaa_boost_tune); + write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX0, + ci->RF_TX0_intpag_boost_tune); + write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX0, + ci->RF_TX0_pada_boost_tune); + write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX0, + ci->RF_TX0_padg_boost_tune); + write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX0, + ci->RF_TX0_pgaa_boost_tune); + write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX0, + ci->RF_TX0_pgag_boost_tune); + write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX0, + ci->RF_TX0_mixa_boost_tune); + write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX0, + ci->RF_TX0_mixg_boost_tune); + + write_radio_reg(pi, + RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX1, + ci->RF_RX1_lnaa_tune); + write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX1, + ci->RF_RX1_lnag_tune); + write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX1, + ci->RF_TX1_intpaa_boost_tune); + write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX1, + ci->RF_TX1_intpag_boost_tune); + write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX1, + ci->RF_TX1_pada_boost_tune); + write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX1, + ci->RF_TX1_padg_boost_tune); + write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX1, + ci->RF_TX1_pgaa_boost_tune); + write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX1, + ci->RF_TX1_pgag_boost_tune); + write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX1, + ci->RF_TX1_mixa_boost_tune); + write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX1, + ci->RF_TX1_mixg_boost_tune); + + if (NREV_IS(pi->pubpi.phy_rev, 3)) + regs_SYN_2056_ptr = regs_SYN_2056; + else if (NREV_IS(pi->pubpi.phy_rev, 4)) + regs_SYN_2056_ptr = regs_SYN_2056_A1; + else { + switch (pi->pubpi.radiorev) { + case 5: + regs_SYN_2056_ptr = regs_SYN_2056_rev5; + break; + case 6: + regs_SYN_2056_ptr = regs_SYN_2056_rev6; + break; + case 7: + case 9: + regs_SYN_2056_ptr = regs_SYN_2056_rev7; + break; + case 8: + regs_SYN_2056_ptr = regs_SYN_2056_rev8; + break; + case 11: + regs_SYN_2056_ptr = regs_SYN_2056_rev11; + break; + } + } + if (CHSPEC_IS2G(pi->radio_chanspec)) { + write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 | + RADIO_2056_SYN, + (u16) regs_SYN_2056_ptr[0x49 - 2].init_g); + } else { + write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 | + RADIO_2056_SYN, + (u16) regs_SYN_2056_ptr[0x49 - 2].init_a); + } + + if (pi->sh->boardflags2 & BFL2_GPLL_WAR) { + if (CHSPEC_IS2G(pi->radio_chanspec)) { + write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 | + RADIO_2056_SYN, 0x1f); + write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 | + RADIO_2056_SYN, 0x1f); + + if ((pi->sh->chip == BCM4716_CHIP_ID) || + (pi->sh->chip == BCM47162_CHIP_ID)) { + + write_radio_reg(pi, + RADIO_2056_SYN_PLL_LOOPFILTER4 | + RADIO_2056_SYN, 0x14); + write_radio_reg(pi, + RADIO_2056_SYN_PLL_CP2 | + RADIO_2056_SYN, 0x00); + } else { + write_radio_reg(pi, + RADIO_2056_SYN_PLL_LOOPFILTER4 | + RADIO_2056_SYN, 0xb); + write_radio_reg(pi, + RADIO_2056_SYN_PLL_CP2 | + RADIO_2056_SYN, 0x14); + } + } + } + + if ((pi->sh->boardflags2 & BFL2_GPLL_WAR2) && + (CHSPEC_IS2G(pi->radio_chanspec))) { + write_radio_reg(pi, + RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN, + 0x1f); + write_radio_reg(pi, + RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN, + 0x1f); + write_radio_reg(pi, + RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN, + 0xb); + write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 | RADIO_2056_SYN, + 0x20); + } + + if (pi->sh->boardflags2 & BFL2_APLL_WAR) { + if (CHSPEC_IS5G(pi->radio_chanspec)) { + write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 | + RADIO_2056_SYN, 0x1f); + write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 | + RADIO_2056_SYN, 0x1f); + write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 | + RADIO_2056_SYN, 0x5); + write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 | + RADIO_2056_SYN, 0xc); + } + } + + if (PHY_IPA(pi) && CHSPEC_IS2G(pi->radio_chanspec)) { + u16 pag_boost_tune; + u16 padg_boost_tune; + u16 pgag_boost_tune; + u16 mixg_boost_tune; + u16 bias, cascbias; + uint core; + + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + + if (NREV_GE(pi->pubpi.phy_rev, 5)) { + + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + PADG_IDAC, 0xcc); + + if ((pi->sh->chip == BCM4716_CHIP_ID) || + (pi->sh->chip == + BCM47162_CHIP_ID)) { + bias = 0x40; + cascbias = 0x45; + pag_boost_tune = 0x5; + pgag_boost_tune = 0x33; + padg_boost_tune = 0x77; + mixg_boost_tune = 0x55; + } else { + bias = 0x25; + cascbias = 0x20; + + if ((pi->sh->chip == + BCM43224_CHIP_ID) + || (pi->sh->chip == + BCM43225_CHIP_ID) + || (pi->sh->chip == + BCM43421_CHIP_ID)) { + if (pi->sh->chippkg == + BCM43224_FAB_SMIC) { + bias = 0x2a; + cascbias = 0x38; + } + } + + pag_boost_tune = 0x4; + pgag_boost_tune = 0x03; + padg_boost_tune = 0x77; + mixg_boost_tune = 0x65; + } + + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAG_IMAIN_STAT, bias); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAG_IAUX_STAT, bias); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAG_CASCBIAS, cascbias); + + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAG_BOOST_TUNE, + pag_boost_tune); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + PGAG_BOOST_TUNE, + pgag_boost_tune); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + PADG_BOOST_TUNE, + padg_boost_tune); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + MIXG_BOOST_TUNE, + mixg_boost_tune); + } else { + + bias = IS40MHZ(pi) ? 0x40 : 0x20; + + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAG_IMAIN_STAT, bias); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAG_IAUX_STAT, bias); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAG_CASCBIAS, 0x30); + } + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, PA_SPARE1, + 0xee); + } + } + + if (PHY_IPA(pi) && NREV_IS(pi->pubpi.phy_rev, 6) + && CHSPEC_IS5G(pi->radio_chanspec)) { + u16 paa_boost_tune; + u16 pada_boost_tune; + u16 pgaa_boost_tune; + u16 mixa_boost_tune; + u16 freq, pabias, cascbias; + uint core; + + freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec)); + + if (freq < 5150) { + + paa_boost_tune = 0xa; + pada_boost_tune = 0x77; + pgaa_boost_tune = 0xf; + mixa_boost_tune = 0xf; + } else if (freq < 5340) { + + paa_boost_tune = 0x8; + pada_boost_tune = 0x77; + pgaa_boost_tune = 0xfb; + mixa_boost_tune = 0xf; + } else if (freq < 5650) { + + paa_boost_tune = 0x0; + pada_boost_tune = 0x77; + pgaa_boost_tune = 0xb; + mixa_boost_tune = 0xf; + } else { + + paa_boost_tune = 0x0; + pada_boost_tune = 0x77; + if (freq != 5825) { + pgaa_boost_tune = -(int)(freq - 18) / 36 + 168; + } else { + pgaa_boost_tune = 6; + } + mixa_boost_tune = 0xf; + } + + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAA_BOOST_TUNE, paa_boost_tune); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + PADA_BOOST_TUNE, pada_boost_tune); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + PGAA_BOOST_TUNE, pgaa_boost_tune); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + MIXA_BOOST_TUNE, mixa_boost_tune); + + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + TXSPARE1, 0x30); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + PA_SPARE2, 0xee); + + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + PADA_CASCBIAS, 0x3); + + cascbias = 0x30; + + if ((pi->sh->chip == BCM43224_CHIP_ID) || + (pi->sh->chip == BCM43225_CHIP_ID) || + (pi->sh->chip == BCM43421_CHIP_ID)) { + if (pi->sh->chippkg == BCM43224_FAB_SMIC) { + cascbias = 0x35; + } + } + + pabias = (pi->phy_pabias == 0) ? 0x30 : pi->phy_pabias; + + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAA_IAUX_STAT, pabias); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAA_IMAIN_STAT, pabias); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAA_CASCBIAS, cascbias); + } + } + + udelay(50); + + wlc_phy_radio205x_vcocal_nphy(pi); +} + +void wlc_phy_radio205x_vcocal_nphy(phy_info_t *pi) +{ + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x0); + mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04, 0x0); + mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04, + (1 << 2)); + mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x01); + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL12, 0x0); + write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38); + write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x18); + write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38); + write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x39); + } + + udelay(300); +} + +#define MAX_205x_RCAL_WAITLOOPS 10000 + +static u16 wlc_phy_radio205x_rcal(phy_info_t *pi) +{ + u16 rcal_reg = 0; + int i; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + if (pi->pubpi.radiorev == 5) { + + and_phy_reg(pi, 0x342, ~(0x1 << 1)); + + udelay(10); + + mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x1); + mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2, + 0x1); + } + mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x1); + + udelay(10); + + mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x3, 0x3); + + for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { + rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS); + if (rcal_reg & 0x1) { + break; + } + udelay(100); + } + + ASSERT(i < MAX_205x_RCAL_WAITLOOPS); + + mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x2, 0x0); + + rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS) & 0x3e; + + mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x0); + if (pi->pubpi.radiorev == 5) { + + mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x0); + mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2, + 0x0); + } + + if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) { + + mod_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x3c, + rcal_reg); + mod_radio_reg(pi, RADIO_2057_BANDGAP_RCAL_TRIM, 0xf0, + rcal_reg << 2); + } + + } else if (NREV_IS(pi->pubpi.phy_rev, 3)) { + u16 savereg; + + savereg = + read_radio_reg(pi, + RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN); + write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN, + savereg | 0x7); + udelay(10); + + write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN, + 0x1); + udelay(10); + + write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN, + 0x9); + + for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { + rcal_reg = read_radio_reg(pi, + RADIO_2056_SYN_RCAL_CODE_OUT | + RADIO_2056_SYN); + if (rcal_reg & 0x80) { + break; + } + udelay(100); + } + + ASSERT(i < MAX_205x_RCAL_WAITLOOPS); + + write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN, + 0x1); + + rcal_reg = + read_radio_reg(pi, + RADIO_2056_SYN_RCAL_CODE_OUT | + RADIO_2056_SYN); + + write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN, + 0x0); + + write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN, + savereg); + + return rcal_reg & 0x1f; + } + return rcal_reg & 0x3e; +} + +static void +wlc_phy_chanspec_radio2057_setup(phy_info_t *pi, + const chan_info_nphy_radio2057_t *ci, + const chan_info_nphy_radio2057_rev5_t *ci2) +{ + int coreNum; + u16 txmix2g_tune_boost_pu = 0; + u16 pad2g_tune_pus = 0; + + if (pi->pubpi.radiorev == 5) { + + write_radio_reg(pi, + RADIO_2057_VCOCAL_COUNTVAL0, + ci2->RF_vcocal_countval0); + write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1, + ci2->RF_vcocal_countval1); + write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE, + ci2->RF_rfpll_refmaster_sparextalsize); + write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1, + ci2->RF_rfpll_loopfilter_r1); + write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2, + ci2->RF_rfpll_loopfilter_c2); + write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1, + ci2->RF_rfpll_loopfilter_c1); + write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, + ci2->RF_cp_kpd_idac); + write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci2->RF_rfpll_mmd0); + write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci2->RF_rfpll_mmd1); + write_radio_reg(pi, + RADIO_2057_VCOBUF_TUNE, ci2->RF_vcobuf_tune); + write_radio_reg(pi, + RADIO_2057_LOGEN_MX2G_TUNE, + ci2->RF_logen_mx2g_tune); + write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE, + ci2->RF_logen_indbuf2g_tune); + + write_radio_reg(pi, + RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0, + ci2->RF_txmix2g_tune_boost_pu_core0); + write_radio_reg(pi, + RADIO_2057_PAD2G_TUNE_PUS_CORE0, + ci2->RF_pad2g_tune_pus_core0); + write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0, + ci2->RF_lna2g_tune_core0); + + write_radio_reg(pi, + RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1, + ci2->RF_txmix2g_tune_boost_pu_core1); + write_radio_reg(pi, + RADIO_2057_PAD2G_TUNE_PUS_CORE1, + ci2->RF_pad2g_tune_pus_core1); + write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1, + ci2->RF_lna2g_tune_core1); + + } else { + + write_radio_reg(pi, + RADIO_2057_VCOCAL_COUNTVAL0, + ci->RF_vcocal_countval0); + write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1, + ci->RF_vcocal_countval1); + write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE, + ci->RF_rfpll_refmaster_sparextalsize); + write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1, + ci->RF_rfpll_loopfilter_r1); + write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2, + ci->RF_rfpll_loopfilter_c2); + write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1, + ci->RF_rfpll_loopfilter_c1); + write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, ci->RF_cp_kpd_idac); + write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci->RF_rfpll_mmd0); + write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci->RF_rfpll_mmd1); + write_radio_reg(pi, RADIO_2057_VCOBUF_TUNE, ci->RF_vcobuf_tune); + write_radio_reg(pi, + RADIO_2057_LOGEN_MX2G_TUNE, + ci->RF_logen_mx2g_tune); + write_radio_reg(pi, RADIO_2057_LOGEN_MX5G_TUNE, + ci->RF_logen_mx5g_tune); + write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE, + ci->RF_logen_indbuf2g_tune); + write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF5G_TUNE, + ci->RF_logen_indbuf5g_tune); + + write_radio_reg(pi, + RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0, + ci->RF_txmix2g_tune_boost_pu_core0); + write_radio_reg(pi, + RADIO_2057_PAD2G_TUNE_PUS_CORE0, + ci->RF_pad2g_tune_pus_core0); + write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE0, + ci->RF_pga_boost_tune_core0); + write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0, + ci->RF_txmix5g_boost_tune_core0); + write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0, + ci->RF_pad5g_tune_misc_pus_core0); + write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0, + ci->RF_lna2g_tune_core0); + write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE0, + ci->RF_lna5g_tune_core0); + + write_radio_reg(pi, + RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1, + ci->RF_txmix2g_tune_boost_pu_core1); + write_radio_reg(pi, + RADIO_2057_PAD2G_TUNE_PUS_CORE1, + ci->RF_pad2g_tune_pus_core1); + write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE1, + ci->RF_pga_boost_tune_core1); + write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1, + ci->RF_txmix5g_boost_tune_core1); + write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1, + ci->RF_pad5g_tune_misc_pus_core1); + write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1, + ci->RF_lna2g_tune_core1); + write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE1, + ci->RF_lna5g_tune_core1); + } + + if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) { + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1, + 0x3f); + write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f); + write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1, + 0x8); + write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2, + 0x8); + } else { + write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1, + 0x1f); + write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f); + write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1, + 0x8); + write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2, + 0x8); + } + } else if ((pi->pubpi.radiorev == 5) || (pi->pubpi.radiorev == 7) || + (pi->pubpi.radiorev == 8)) { + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1, + 0x1b); + write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x30); + write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1, + 0xa); + write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2, + 0xa); + } else { + write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1, + 0x1f); + write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f); + write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1, + 0x8); + write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2, + 0x8); + } + + } + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (PHY_IPA(pi)) { + if (pi->pubpi.radiorev == 3) { + txmix2g_tune_boost_pu = 0x6b; + } + + if (pi->pubpi.radiorev == 5) + pad2g_tune_pus = 0x73; + + } else { + if (pi->pubpi.radiorev != 5) { + pad2g_tune_pus = 0x3; + + txmix2g_tune_boost_pu = 0x61; + } + } + + for (coreNum = 0; coreNum <= 1; coreNum++) { + + if (txmix2g_tune_boost_pu != 0) + WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum, + TXMIX2G_TUNE_BOOST_PU, + txmix2g_tune_boost_pu); + + if (pad2g_tune_pus != 0) + WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum, + PAD2G_TUNE_PUS, + pad2g_tune_pus); + } + } + + udelay(50); + + wlc_phy_radio205x_vcocal_nphy(pi); +} + +static u16 wlc_phy_radio2057_rccal(phy_info_t *pi) +{ + u16 rccal_valid; + int i; + bool chip43226_6362A0; + + chip43226_6362A0 = ((pi->pubpi.radiorev == 3) + || (pi->pubpi.radiorev == 4) + || (pi->pubpi.radiorev == 6)); + + rccal_valid = 0; + if (chip43226_6362A0) { + write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x61); + write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xc0); + } else { + write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x61); + + write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xe9); + } + write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e); + write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55); + + for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { + rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP); + if (rccal_valid & 0x2) { + break; + } + udelay(500); + } + + ASSERT(rccal_valid & 0x2); + + write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15); + + rccal_valid = 0; + if (chip43226_6362A0) { + write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x69); + write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0); + } else { + write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x69); + + write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xd5); + } + write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e); + write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55); + + for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { + rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP); + if (rccal_valid & 0x2) { + break; + } + udelay(500); + } + + ASSERT(rccal_valid & 0x2); + + write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15); + + rccal_valid = 0; + if (chip43226_6362A0) { + write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x73); + + write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x28); + write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0); + } else { + write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x73); + write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e); + write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0x99); + } + write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55); + + for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { + rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP); + if (rccal_valid & 0x2) { + break; + } + udelay(500); + } + + ASSERT(rccal_valid & 0x2); + + write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15); + + return rccal_valid; +} + +static void +wlc_phy_adjust_rx_analpfbw_nphy(phy_info_t *pi, u16 reduction_factr) +{ + if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) { + if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) && + CHSPEC_IS40(pi->radio_chanspec)) { + if (!pi->nphy_anarxlpf_adjusted) { + write_radio_reg(pi, + (RADIO_2056_RX_RXLPF_RCCAL_LPC | + RADIO_2056_RX0), + ((pi->nphy_rccal_value + + reduction_factr) | 0x80)); + + pi->nphy_anarxlpf_adjusted = true; + } + } else { + if (pi->nphy_anarxlpf_adjusted) { + write_radio_reg(pi, + (RADIO_2056_RX_RXLPF_RCCAL_LPC | + RADIO_2056_RX0), + (pi->nphy_rccal_value | 0x80)); + + pi->nphy_anarxlpf_adjusted = false; + } + } + } +} + +static void +wlc_phy_adjust_min_noisevar_nphy(phy_info_t *pi, int ntones, int *tone_id_buf, + u32 *noise_var_buf) +{ + int i; + u32 offset; + int tone_id; + int tbllen = + CHSPEC_IS40(pi-> + radio_chanspec) ? NPHY_NOISEVAR_TBLLEN40 : + NPHY_NOISEVAR_TBLLEN20; + + if (pi->nphy_noisevars_adjusted) { + for (i = 0; i < pi->nphy_saved_noisevars.bufcount; i++) { + tone_id = pi->nphy_saved_noisevars.tone_id[i]; + offset = (tone_id >= 0) ? + ((tone_id * 2) + 1) : (tbllen + (tone_id * 2) + 1); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, + offset, 32, + (void *)&pi-> + nphy_saved_noisevars. + min_noise_vars[i]); + } + + pi->nphy_saved_noisevars.bufcount = 0; + pi->nphy_noisevars_adjusted = false; + } + + if ((noise_var_buf != NULL) && (tone_id_buf != NULL)) { + pi->nphy_saved_noisevars.bufcount = 0; + + for (i = 0; i < ntones; i++) { + tone_id = tone_id_buf[i]; + offset = (tone_id >= 0) ? + ((tone_id * 2) + 1) : (tbllen + (tone_id * 2) + 1); + pi->nphy_saved_noisevars.tone_id[i] = tone_id; + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, + offset, 32, + &pi->nphy_saved_noisevars. + min_noise_vars[i]); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, + offset, 32, + (void *)&noise_var_buf[i]); + pi->nphy_saved_noisevars.bufcount++; + } + + pi->nphy_noisevars_adjusted = true; + } +} + +static void wlc_phy_adjust_crsminpwr_nphy(phy_info_t *pi, u8 minpwr) +{ + u16 regval; + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) && + CHSPEC_IS40(pi->radio_chanspec)) { + if (!pi->nphy_crsminpwr_adjusted) { + regval = read_phy_reg(pi, 0x27d); + pi->nphy_crsminpwr[0] = regval & 0xff; + regval &= 0xff00; + regval |= (u16) minpwr; + write_phy_reg(pi, 0x27d, regval); + + regval = read_phy_reg(pi, 0x280); + pi->nphy_crsminpwr[1] = regval & 0xff; + regval &= 0xff00; + regval |= (u16) minpwr; + write_phy_reg(pi, 0x280, regval); + + regval = read_phy_reg(pi, 0x283); + pi->nphy_crsminpwr[2] = regval & 0xff; + regval &= 0xff00; + regval |= (u16) minpwr; + write_phy_reg(pi, 0x283, regval); + + pi->nphy_crsminpwr_adjusted = true; + } + } else { + if (pi->nphy_crsminpwr_adjusted) { + regval = read_phy_reg(pi, 0x27d); + regval &= 0xff00; + regval |= pi->nphy_crsminpwr[0]; + write_phy_reg(pi, 0x27d, regval); + + regval = read_phy_reg(pi, 0x280); + regval &= 0xff00; + regval |= pi->nphy_crsminpwr[1]; + write_phy_reg(pi, 0x280, regval); + + regval = read_phy_reg(pi, 0x283); + regval &= 0xff00; + regval |= pi->nphy_crsminpwr[2]; + write_phy_reg(pi, 0x283, regval); + + pi->nphy_crsminpwr_adjusted = false; + } + } + } +} + +static void wlc_phy_txlpfbw_nphy(phy_info_t *pi) +{ + u8 tx_lpf_bw = 0; + + if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) { + if (CHSPEC_IS40(pi->radio_chanspec)) { + tx_lpf_bw = 3; + } else { + tx_lpf_bw = 1; + } + + if (PHY_IPA(pi)) { + if (CHSPEC_IS40(pi->radio_chanspec)) { + tx_lpf_bw = 5; + } else { + tx_lpf_bw = 4; + } + } + write_phy_reg(pi, 0xe8, + (tx_lpf_bw << 0) | + (tx_lpf_bw << 3) | + (tx_lpf_bw << 6) | (tx_lpf_bw << 9)); + + if (PHY_IPA(pi)) { + + if (CHSPEC_IS40(pi->radio_chanspec)) { + tx_lpf_bw = 4; + } else { + tx_lpf_bw = 1; + } + + write_phy_reg(pi, 0xe9, + (tx_lpf_bw << 0) | + (tx_lpf_bw << 3) | + (tx_lpf_bw << 6) | (tx_lpf_bw << 9)); + } + } +} + +static void wlc_phy_spurwar_nphy(phy_info_t *pi) +{ + u16 cur_channel = 0; + int nphy_adj_tone_id_buf[] = { 57, 58 }; + u32 nphy_adj_noise_var_buf[] = { 0x3ff, 0x3ff }; + bool isAdjustNoiseVar = false; + uint numTonesAdjust = 0; + u32 tempval = 0; + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + cur_channel = CHSPEC_CHANNEL(pi->radio_chanspec); + + if (pi->nphy_gband_spurwar_en) { + + wlc_phy_adjust_rx_analpfbw_nphy(pi, + NPHY_ANARXLPFBW_REDUCTIONFACT); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if ((cur_channel == 11) + && CHSPEC_IS40(pi->radio_chanspec)) { + + wlc_phy_adjust_min_noisevar_nphy(pi, 2, + nphy_adj_tone_id_buf, + nphy_adj_noise_var_buf); + } else { + + wlc_phy_adjust_min_noisevar_nphy(pi, 0, + NULL, + NULL); + } + } + wlc_phy_adjust_crsminpwr_nphy(pi, + NPHY_ADJUSTED_MINCRSPOWER); + } + + if ((pi->nphy_gband_spurwar2_en) + && CHSPEC_IS2G(pi->radio_chanspec)) { + + if (CHSPEC_IS40(pi->radio_chanspec)) { + switch (cur_channel) { + case 3: + nphy_adj_tone_id_buf[0] = 57; + nphy_adj_tone_id_buf[1] = 58; + nphy_adj_noise_var_buf[0] = 0x22f; + nphy_adj_noise_var_buf[1] = 0x25f; + isAdjustNoiseVar = true; + break; + case 4: + nphy_adj_tone_id_buf[0] = 41; + nphy_adj_tone_id_buf[1] = 42; + nphy_adj_noise_var_buf[0] = 0x22f; + nphy_adj_noise_var_buf[1] = 0x25f; + isAdjustNoiseVar = true; + break; + case 5: + nphy_adj_tone_id_buf[0] = 25; + nphy_adj_tone_id_buf[1] = 26; + nphy_adj_noise_var_buf[0] = 0x24f; + nphy_adj_noise_var_buf[1] = 0x25f; + isAdjustNoiseVar = true; + break; + case 6: + nphy_adj_tone_id_buf[0] = 9; + nphy_adj_tone_id_buf[1] = 10; + nphy_adj_noise_var_buf[0] = 0x22f; + nphy_adj_noise_var_buf[1] = 0x24f; + isAdjustNoiseVar = true; + break; + case 7: + nphy_adj_tone_id_buf[0] = 121; + nphy_adj_tone_id_buf[1] = 122; + nphy_adj_noise_var_buf[0] = 0x18f; + nphy_adj_noise_var_buf[1] = 0x24f; + isAdjustNoiseVar = true; + break; + case 8: + nphy_adj_tone_id_buf[0] = 105; + nphy_adj_tone_id_buf[1] = 106; + nphy_adj_noise_var_buf[0] = 0x22f; + nphy_adj_noise_var_buf[1] = 0x25f; + isAdjustNoiseVar = true; + break; + case 9: + nphy_adj_tone_id_buf[0] = 89; + nphy_adj_tone_id_buf[1] = 90; + nphy_adj_noise_var_buf[0] = 0x22f; + nphy_adj_noise_var_buf[1] = 0x24f; + isAdjustNoiseVar = true; + break; + case 10: + nphy_adj_tone_id_buf[0] = 73; + nphy_adj_tone_id_buf[1] = 74; + nphy_adj_noise_var_buf[0] = 0x22f; + nphy_adj_noise_var_buf[1] = 0x24f; + isAdjustNoiseVar = true; + break; + default: + isAdjustNoiseVar = false; + break; + } + } + + if (isAdjustNoiseVar) { + numTonesAdjust = sizeof(nphy_adj_tone_id_buf) / + sizeof(nphy_adj_tone_id_buf[0]); + + wlc_phy_adjust_min_noisevar_nphy(pi, + numTonesAdjust, + nphy_adj_tone_id_buf, + nphy_adj_noise_var_buf); + + tempval = 0; + + } else { + + wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL, + NULL); + } + } + + if ((pi->nphy_aband_spurwar_en) && + (CHSPEC_IS5G(pi->radio_chanspec))) { + switch (cur_channel) { + case 54: + nphy_adj_tone_id_buf[0] = 32; + nphy_adj_noise_var_buf[0] = 0x25f; + break; + case 38: + case 102: + case 118: + if ((pi->sh->chip == BCM4716_CHIP_ID) && + (pi->sh->chippkg == BCM4717_PKG_ID)) { + nphy_adj_tone_id_buf[0] = 32; + nphy_adj_noise_var_buf[0] = 0x21f; + } else { + nphy_adj_tone_id_buf[0] = 0; + nphy_adj_noise_var_buf[0] = 0x0; + } + break; + case 134: + nphy_adj_tone_id_buf[0] = 32; + nphy_adj_noise_var_buf[0] = 0x21f; + break; + case 151: + nphy_adj_tone_id_buf[0] = 16; + nphy_adj_noise_var_buf[0] = 0x23f; + break; + case 153: + case 161: + nphy_adj_tone_id_buf[0] = 48; + nphy_adj_noise_var_buf[0] = 0x23f; + break; + default: + nphy_adj_tone_id_buf[0] = 0; + nphy_adj_noise_var_buf[0] = 0x0; + break; + } + + if (nphy_adj_tone_id_buf[0] + && nphy_adj_noise_var_buf[0]) { + wlc_phy_adjust_min_noisevar_nphy(pi, 1, + nphy_adj_tone_id_buf, + nphy_adj_noise_var_buf); + } else { + wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL, + NULL); + } + } + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); + } +} + +static void +wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chanspec, + const nphy_sfo_cfg_t *ci) +{ + u16 val; + + val = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand; + if (CHSPEC_IS5G(chanspec) && !val) { + + val = R_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param); + W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, + (val | MAC_PHY_FORCE_CLK)); + + or_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG), + (BBCFG_RESETCCA | BBCFG_RESETRX)); + + W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, val); + + or_phy_reg(pi, 0x09, NPHY_BandControl_currentBand); + } else if (!CHSPEC_IS5G(chanspec) && val) { + + and_phy_reg(pi, 0x09, ~NPHY_BandControl_currentBand); + + val = R_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param); + W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, + (val | MAC_PHY_FORCE_CLK)); + + and_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG), + (u16) (~(BBCFG_RESETCCA | BBCFG_RESETRX))); + + W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, val); + } + + write_phy_reg(pi, 0x1ce, ci->PHY_BW1a); + write_phy_reg(pi, 0x1cf, ci->PHY_BW2); + write_phy_reg(pi, 0x1d0, ci->PHY_BW3); + + write_phy_reg(pi, 0x1d1, ci->PHY_BW4); + write_phy_reg(pi, 0x1d2, ci->PHY_BW5); + write_phy_reg(pi, 0x1d3, ci->PHY_BW6); + + if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) { + wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en, 0); + + or_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, 0x800); + } else { + wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en, + NPHY_ClassifierCtrl_ofdm_en); + + if (CHSPEC_IS2G(chanspec)) + and_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, ~0x840); + } + + if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) { + wlc_phy_txpwr_fixpower_nphy(pi); + } + + if (NREV_LT(pi->pubpi.phy_rev, 3)) { + + wlc_phy_adjust_lnagaintbl_nphy(pi); + } + + wlc_phy_txlpfbw_nphy(pi); + + if (NREV_GE(pi->pubpi.phy_rev, 3) + && (pi->phy_spuravoid != SPURAVOID_DISABLE)) { + u8 spuravoid = 0; + + val = CHSPEC_CHANNEL(chanspec); + if (!CHSPEC_IS40(pi->radio_chanspec)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if ((val == 13) || (val == 14) || (val == 153)) { + spuravoid = 1; + } + } else { + + if (((val >= 5) && (val <= 8)) || (val == 13) + || (val == 14)) { + spuravoid = 1; + } + } + } else { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (val == 54) { + spuravoid = 1; + } + } else { + + if (pi->nphy_aband_spurwar_en && + ((val == 38) || (val == 102) + || (val == 118))) { + if ((pi->sh->chip == + BCM4716_CHIP_ID) + && (pi->sh->chippkg == + BCM4717_PKG_ID)) { + spuravoid = 0; + } else { + spuravoid = 1; + } + } + } + } + + if (pi->phy_spuravoid == SPURAVOID_FORCEON) + spuravoid = 1; + + if ((pi->sh->chip == BCM4716_CHIP_ID) || + (pi->sh->chip == BCM47162_CHIP_ID)) { + si_pmu_spuravoid(pi->sh->sih, pi->sh->osh, spuravoid); + } else { + wlapi_bmac_core_phypll_ctl(pi->sh->physhim, false); + si_pmu_spuravoid(pi->sh->sih, pi->sh->osh, spuravoid); + wlapi_bmac_core_phypll_ctl(pi->sh->physhim, true); + } + + if ((pi->sh->chip == BCM43224_CHIP_ID) || + (pi->sh->chip == BCM43225_CHIP_ID) || + (pi->sh->chip == BCM43421_CHIP_ID)) { + + if (spuravoid == 1) { + + W_REG(pi->sh->osh, &pi->regs->tsf_clk_frac_l, + 0x5341); + W_REG(pi->sh->osh, &pi->regs->tsf_clk_frac_h, + 0x8); + } else { + + W_REG(pi->sh->osh, &pi->regs->tsf_clk_frac_l, + 0x8889); + W_REG(pi->sh->osh, &pi->regs->tsf_clk_frac_h, + 0x8); + } + } + + if (!((pi->sh->chip == BCM4716_CHIP_ID) || + (pi->sh->chip == BCM47162_CHIP_ID))) { + wlapi_bmac_core_phypll_reset(pi->sh->physhim); + } + + mod_phy_reg(pi, 0x01, (0x1 << 15), + ((spuravoid > 0) ? (0x1 << 15) : 0)); + + wlc_phy_resetcca_nphy(pi); + + pi->phy_isspuravoid = (spuravoid > 0); + } + + if (NREV_LT(pi->pubpi.phy_rev, 7)) + write_phy_reg(pi, 0x17e, 0x3830); + + wlc_phy_spurwar_nphy(pi); +} + +void wlc_phy_chanspec_set_nphy(phy_info_t *pi, chanspec_t chanspec) +{ + int freq; + chan_info_nphy_radio2057_t *t0 = NULL; + chan_info_nphy_radio205x_t *t1 = NULL; + chan_info_nphy_radio2057_rev5_t *t2 = NULL; + chan_info_nphy_2055_t *t3 = NULL; + + if (NORADIO_ENAB(pi->pubpi)) { + return; + } + + if (!wlc_phy_chan2freq_nphy + (pi, CHSPEC_CHANNEL(chanspec), &freq, &t0, &t1, &t2, &t3)) + return; + + wlc_phy_chanspec_radio_set((wlc_phy_t *) pi, chanspec); + + if (CHSPEC_BW(chanspec) != pi->bw) + wlapi_bmac_bw_set(pi->sh->physhim, CHSPEC_BW(chanspec)); + + if (CHSPEC_IS40(chanspec)) { + if (CHSPEC_SB_UPPER(chanspec)) { + or_phy_reg(pi, 0xa0, BPHY_BAND_SEL_UP20); + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + or_phy_reg(pi, 0x310, PRIM_SEL_UP20); + } + } else { + and_phy_reg(pi, 0xa0, ~BPHY_BAND_SEL_UP20); + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + and_phy_reg(pi, 0x310, + (~PRIM_SEL_UP20 & 0xffff)); + } + } + } + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + if ((pi->pubpi.radiorev <= 4) + || (pi->pubpi.radiorev == 6)) { + mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE0, + 0x2, + (CHSPEC_IS5G(chanspec) ? (1 << 1) + : 0)); + mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE1, + 0x2, + (CHSPEC_IS5G(chanspec) ? (1 << 1) + : 0)); + } + + wlc_phy_chanspec_radio2057_setup(pi, t0, t2); + wlc_phy_chanspec_nphy_setup(pi, chanspec, + (pi->pubpi.radiorev == + 5) ? (const nphy_sfo_cfg_t + *)&(t2-> + PHY_BW1a) + : (const nphy_sfo_cfg_t *) + &(t0->PHY_BW1a)); + + } else { + + mod_radio_reg(pi, + RADIO_2056_SYN_COM_CTRL | RADIO_2056_SYN, + 0x4, + (CHSPEC_IS5G(chanspec) ? (0x1 << 2) : 0)); + wlc_phy_chanspec_radio2056_setup(pi, t1); + + wlc_phy_chanspec_nphy_setup(pi, chanspec, + (const nphy_sfo_cfg_t *) + &(t1->PHY_BW1a)); + } + + } else { + + mod_radio_reg(pi, RADIO_2055_MASTER_CNTRL1, 0x70, + (CHSPEC_IS5G(chanspec) ? (0x02 << 4) + : (0x05 << 4))); + + wlc_phy_chanspec_radio2055_setup(pi, t3); + wlc_phy_chanspec_nphy_setup(pi, chanspec, + (const nphy_sfo_cfg_t *)&(t3-> + PHY_BW1a)); + } + +} + +static void wlc_phy_savecal_nphy(phy_info_t *pi) +{ + void *tbl_ptr; + int coreNum; + u16 *txcal_radio_regs = NULL; + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + + wlc_phy_rx_iq_coeffs_nphy(pi, 0, + &pi->calibration_cache. + rxcal_coeffs_2G); + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + txcal_radio_regs = + pi->calibration_cache.txcal_radio_regs_2G; + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + + pi->calibration_cache.txcal_radio_regs_2G[0] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_I | + RADIO_2056_TX0); + pi->calibration_cache.txcal_radio_regs_2G[1] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_Q | + RADIO_2056_TX0); + pi->calibration_cache.txcal_radio_regs_2G[2] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_I | + RADIO_2056_TX1); + pi->calibration_cache.txcal_radio_regs_2G[3] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_Q | + RADIO_2056_TX1); + + pi->calibration_cache.txcal_radio_regs_2G[4] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_I | + RADIO_2056_TX0); + pi->calibration_cache.txcal_radio_regs_2G[5] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_Q | + RADIO_2056_TX0); + pi->calibration_cache.txcal_radio_regs_2G[6] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_I | + RADIO_2056_TX1); + pi->calibration_cache.txcal_radio_regs_2G[7] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_Q | + RADIO_2056_TX1); + } else { + pi->calibration_cache.txcal_radio_regs_2G[0] = + read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL); + pi->calibration_cache.txcal_radio_regs_2G[1] = + read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL); + pi->calibration_cache.txcal_radio_regs_2G[2] = + read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM); + pi->calibration_cache.txcal_radio_regs_2G[3] = + read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM); + } + + pi->nphy_iqcal_chanspec_2G = pi->radio_chanspec; + tbl_ptr = pi->calibration_cache.txcal_coeffs_2G; + } else { + + wlc_phy_rx_iq_coeffs_nphy(pi, 0, + &pi->calibration_cache. + rxcal_coeffs_5G); + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + txcal_radio_regs = + pi->calibration_cache.txcal_radio_regs_5G; + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + + pi->calibration_cache.txcal_radio_regs_5G[0] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_I | + RADIO_2056_TX0); + pi->calibration_cache.txcal_radio_regs_5G[1] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_Q | + RADIO_2056_TX0); + pi->calibration_cache.txcal_radio_regs_5G[2] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_I | + RADIO_2056_TX1); + pi->calibration_cache.txcal_radio_regs_5G[3] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_Q | + RADIO_2056_TX1); + + pi->calibration_cache.txcal_radio_regs_5G[4] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_I | + RADIO_2056_TX0); + pi->calibration_cache.txcal_radio_regs_5G[5] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_Q | + RADIO_2056_TX0); + pi->calibration_cache.txcal_radio_regs_5G[6] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_I | + RADIO_2056_TX1); + pi->calibration_cache.txcal_radio_regs_5G[7] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_Q | + RADIO_2056_TX1); + } else { + pi->calibration_cache.txcal_radio_regs_5G[0] = + read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL); + pi->calibration_cache.txcal_radio_regs_5G[1] = + read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL); + pi->calibration_cache.txcal_radio_regs_5G[2] = + read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM); + pi->calibration_cache.txcal_radio_regs_5G[3] = + read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM); + } + + pi->nphy_iqcal_chanspec_5G = pi->radio_chanspec; + tbl_ptr = pi->calibration_cache.txcal_coeffs_5G; + } + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + for (coreNum = 0; coreNum <= 1; coreNum++) { + + txcal_radio_regs[2 * coreNum] = + READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum, + LOFT_FINE_I); + txcal_radio_regs[2 * coreNum + 1] = + READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum, + LOFT_FINE_Q); + + txcal_radio_regs[2 * coreNum + 4] = + READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum, + LOFT_COARSE_I); + txcal_radio_regs[2 * coreNum + 5] = + READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum, + LOFT_COARSE_Q); + } + } + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 8, 80, 16, tbl_ptr); + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); +} + +static void wlc_phy_restorecal_nphy(phy_info_t *pi) +{ + u16 *loft_comp; + u16 txcal_coeffs_bphy[4]; + u16 *tbl_ptr; + int coreNum; + u16 *txcal_radio_regs = NULL; + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (pi->nphy_iqcal_chanspec_2G == 0) + return; + + tbl_ptr = pi->calibration_cache.txcal_coeffs_2G; + loft_comp = &pi->calibration_cache.txcal_coeffs_2G[5]; + } else { + if (pi->nphy_iqcal_chanspec_5G == 0) + return; + + tbl_ptr = pi->calibration_cache.txcal_coeffs_5G; + loft_comp = &pi->calibration_cache.txcal_coeffs_5G[5]; + } + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80, 16, + (void *)tbl_ptr); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + txcal_coeffs_bphy[0] = tbl_ptr[0]; + txcal_coeffs_bphy[1] = tbl_ptr[1]; + txcal_coeffs_bphy[2] = tbl_ptr[2]; + txcal_coeffs_bphy[3] = tbl_ptr[3]; + } else { + txcal_coeffs_bphy[0] = 0; + txcal_coeffs_bphy[1] = 0; + txcal_coeffs_bphy[2] = 0; + txcal_coeffs_bphy[3] = 0; + } + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88, 16, + txcal_coeffs_bphy); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85, 16, loft_comp); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93, 16, loft_comp); + + if (NREV_LT(pi->pubpi.phy_rev, 2)) + wlc_phy_tx_iq_war_nphy(pi); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + txcal_radio_regs = + pi->calibration_cache.txcal_radio_regs_2G; + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + + write_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_I | + RADIO_2056_TX0, + pi->calibration_cache. + txcal_radio_regs_2G[0]); + write_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_Q | + RADIO_2056_TX0, + pi->calibration_cache. + txcal_radio_regs_2G[1]); + write_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_I | + RADIO_2056_TX1, + pi->calibration_cache. + txcal_radio_regs_2G[2]); + write_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_Q | + RADIO_2056_TX1, + pi->calibration_cache. + txcal_radio_regs_2G[3]); + + write_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_I | + RADIO_2056_TX0, + pi->calibration_cache. + txcal_radio_regs_2G[4]); + write_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_Q | + RADIO_2056_TX0, + pi->calibration_cache. + txcal_radio_regs_2G[5]); + write_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_I | + RADIO_2056_TX1, + pi->calibration_cache. + txcal_radio_regs_2G[6]); + write_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_Q | + RADIO_2056_TX1, + pi->calibration_cache. + txcal_radio_regs_2G[7]); + } else { + write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL, + pi->calibration_cache. + txcal_radio_regs_2G[0]); + write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL, + pi->calibration_cache. + txcal_radio_regs_2G[1]); + write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, + pi->calibration_cache. + txcal_radio_regs_2G[2]); + write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, + pi->calibration_cache. + txcal_radio_regs_2G[3]); + } + + wlc_phy_rx_iq_coeffs_nphy(pi, 1, + &pi->calibration_cache. + rxcal_coeffs_2G); + } else { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + txcal_radio_regs = + pi->calibration_cache.txcal_radio_regs_5G; + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + + write_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_I | + RADIO_2056_TX0, + pi->calibration_cache. + txcal_radio_regs_5G[0]); + write_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_Q | + RADIO_2056_TX0, + pi->calibration_cache. + txcal_radio_regs_5G[1]); + write_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_I | + RADIO_2056_TX1, + pi->calibration_cache. + txcal_radio_regs_5G[2]); + write_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_Q | + RADIO_2056_TX1, + pi->calibration_cache. + txcal_radio_regs_5G[3]); + + write_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_I | + RADIO_2056_TX0, + pi->calibration_cache. + txcal_radio_regs_5G[4]); + write_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_Q | + RADIO_2056_TX0, + pi->calibration_cache. + txcal_radio_regs_5G[5]); + write_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_I | + RADIO_2056_TX1, + pi->calibration_cache. + txcal_radio_regs_5G[6]); + write_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_Q | + RADIO_2056_TX1, + pi->calibration_cache. + txcal_radio_regs_5G[7]); + } else { + write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL, + pi->calibration_cache. + txcal_radio_regs_5G[0]); + write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL, + pi->calibration_cache. + txcal_radio_regs_5G[1]); + write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, + pi->calibration_cache. + txcal_radio_regs_5G[2]); + write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, + pi->calibration_cache. + txcal_radio_regs_5G[3]); + } + + wlc_phy_rx_iq_coeffs_nphy(pi, 1, + &pi->calibration_cache. + rxcal_coeffs_5G); + } + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + for (coreNum = 0; coreNum <= 1; coreNum++) { + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum, + LOFT_FINE_I, + txcal_radio_regs[2 * coreNum]); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum, + LOFT_FINE_Q, + txcal_radio_regs[2 * coreNum + 1]); + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum, + LOFT_COARSE_I, + txcal_radio_regs[2 * coreNum + 4]); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum, + LOFT_COARSE_Q, + txcal_radio_regs[2 * coreNum + 5]); + } + } +} + +void wlc_phy_antsel_init(wlc_phy_t *ppi, bool lut_init) +{ + phy_info_t *pi = (phy_info_t *) ppi; + u16 mask = 0xfc00; + u32 mc = 0; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) + return; + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + u16 v0 = 0x211, v1 = 0x222, v2 = 0x144, v3 = 0x188; + + if (lut_init == false) + return; + + if (pi->srom_fem2g.antswctrllut == 0) { + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 1, 0x02, 16, &v0); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 1, 0x03, 16, &v1); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 1, 0x08, 16, &v2); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 1, 0x0C, 16, &v3); + } else { + ASSERT(0); + } + + if (pi->srom_fem5g.antswctrllut == 0) { + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 1, 0x12, 16, &v0); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 1, 0x13, 16, &v1); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 1, 0x18, 16, &v2); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 1, 0x1C, 16, &v3); + } else { + ASSERT(0); + } + } else { + + write_phy_reg(pi, 0xc8, 0x0); + write_phy_reg(pi, 0xc9, 0x0); + + si_gpiocontrol(pi->sh->sih, mask, mask, GPIO_DRV_PRIORITY); + + mc = R_REG(pi->sh->osh, &pi->regs->maccontrol); + mc &= ~MCTL_GPOUT_SEL_MASK; + W_REG(pi->sh->osh, &pi->regs->maccontrol, mc); + + OR_REG(pi->sh->osh, &pi->regs->psm_gpio_oe, mask); + + AND_REG(pi->sh->osh, &pi->regs->psm_gpio_out, ~mask); + + if (lut_init) { + write_phy_reg(pi, 0xf8, 0x02d8); + write_phy_reg(pi, 0xf9, 0x0301); + write_phy_reg(pi, 0xfa, 0x02d8); + write_phy_reg(pi, 0xfb, 0x0301); + } + } +} + +u16 wlc_phy_classifier_nphy(phy_info_t *pi, u16 mask, u16 val) +{ + u16 curr_ctl, new_ctl; + bool suspended = false; + + if (D11REV_IS(pi->sh->corerev, 16)) { + suspended = + (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC) ? + false : true; + if (!suspended) + wlapi_suspend_mac_and_wait(pi->sh->physhim); + } + + curr_ctl = read_phy_reg(pi, 0xb0) & (0x7 << 0); + + new_ctl = (curr_ctl & (~mask)) | (val & mask); + + mod_phy_reg(pi, 0xb0, (0x7 << 0), new_ctl); + + if (D11REV_IS(pi->sh->corerev, 16) && !suspended) + wlapi_enable_mac(pi->sh->physhim); + + return new_ctl; +} + +static void wlc_phy_clip_det_nphy(phy_info_t *pi, u8 write, u16 *vals) +{ + + if (write == 0) { + vals[0] = read_phy_reg(pi, 0x2c); + vals[1] = read_phy_reg(pi, 0x42); + } else { + write_phy_reg(pi, 0x2c, vals[0]); + write_phy_reg(pi, 0x42, vals[1]); + } +} + +void wlc_phy_force_rfseq_nphy(phy_info_t *pi, u8 cmd) +{ + u16 trigger_mask, status_mask; + u16 orig_RfseqCoreActv; + + switch (cmd) { + case NPHY_RFSEQ_RX2TX: + trigger_mask = NPHY_RfseqTrigger_rx2tx; + status_mask = NPHY_RfseqStatus_rx2tx; + break; + case NPHY_RFSEQ_TX2RX: + trigger_mask = NPHY_RfseqTrigger_tx2rx; + status_mask = NPHY_RfseqStatus_tx2rx; + break; + case NPHY_RFSEQ_RESET2RX: + trigger_mask = NPHY_RfseqTrigger_reset2rx; + status_mask = NPHY_RfseqStatus_reset2rx; + break; + case NPHY_RFSEQ_UPDATEGAINH: + trigger_mask = NPHY_RfseqTrigger_updategainh; + status_mask = NPHY_RfseqStatus_updategainh; + break; + case NPHY_RFSEQ_UPDATEGAINL: + trigger_mask = NPHY_RfseqTrigger_updategainl; + status_mask = NPHY_RfseqStatus_updategainl; + break; + case NPHY_RFSEQ_UPDATEGAINU: + trigger_mask = NPHY_RfseqTrigger_updategainu; + status_mask = NPHY_RfseqStatus_updategainu; + break; + default: + return; + } + + orig_RfseqCoreActv = read_phy_reg(pi, 0xa1); + or_phy_reg(pi, 0xa1, + (NPHY_RfseqMode_CoreActv_override | + NPHY_RfseqMode_Trigger_override)); + or_phy_reg(pi, 0xa3, trigger_mask); + SPINWAIT((read_phy_reg(pi, 0xa4) & status_mask), 200000); + write_phy_reg(pi, 0xa1, orig_RfseqCoreActv); + + ASSERT((read_phy_reg(pi, 0xa4) & status_mask) == 0); +} + +static void +wlc_phy_set_rfseq_nphy(phy_info_t *pi, u8 cmd, u8 *events, u8 *dlys, + u8 len) +{ + u32 t1_offset, t2_offset; + u8 ctr; + u8 end_event = + NREV_GE(pi->pubpi.phy_rev, + 3) ? NPHY_REV3_RFSEQ_CMD_END : NPHY_RFSEQ_CMD_END; + u8 end_dly = 1; + + ASSERT(len <= 16); + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + t1_offset = cmd << 4; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t1_offset, 8, + events); + t2_offset = t1_offset + 0x080; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t2_offset, 8, + dlys); + + for (ctr = len; ctr < 16; ctr++) { + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, + t1_offset + ctr, 8, &end_event); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, + t2_offset + ctr, 8, &end_dly); + } + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); +} + +static u16 wlc_phy_read_lpf_bw_ctl_nphy(phy_info_t *pi, u16 offset) +{ + u16 lpf_bw_ctl_val = 0; + u16 rx2tx_lpf_rc_lut_offset = 0; + + if (offset == 0) { + if (CHSPEC_IS40(pi->radio_chanspec)) { + rx2tx_lpf_rc_lut_offset = 0x159; + } else { + rx2tx_lpf_rc_lut_offset = 0x154; + } + } else { + rx2tx_lpf_rc_lut_offset = offset; + } + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, + (u32) rx2tx_lpf_rc_lut_offset, 16, + &lpf_bw_ctl_val); + + lpf_bw_ctl_val = lpf_bw_ctl_val & 0x7; + + return lpf_bw_ctl_val; +} + +static void +wlc_phy_rfctrl_override_nphy_rev7(phy_info_t *pi, u16 field, u16 value, + u8 core_mask, u8 off, u8 override_id) +{ + u8 core_num; + u16 addr = 0, en_addr = 0, val_addr = 0, en_mask = 0, val_mask = 0; + u8 val_shift = 0; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + en_mask = field; + for (core_num = 0; core_num < 2; core_num++) { + if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID0) { + + switch (field) { + case (0x1 << 2): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : + 0x7d; + val_mask = (0x1 << 1); + val_shift = 1; + break; + case (0x1 << 3): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : + 0x7d; + val_mask = (0x1 << 2); + val_shift = 2; + break; + case (0x1 << 4): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : + 0x7d; + val_mask = (0x1 << 4); + val_shift = 4; + break; + case (0x1 << 5): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : + 0x7d; + val_mask = (0x1 << 5); + val_shift = 5; + break; + case (0x1 << 6): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : + 0x7d; + val_mask = (0x1 << 6); + val_shift = 6; + break; + case (0x1 << 7): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : + 0x7d; + val_mask = (0x1 << 7); + val_shift = 7; + break; + case (0x1 << 10): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0xf8 : + 0xfa; + val_mask = (0x7 << 4); + val_shift = 4; + break; + case (0x1 << 11): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7b : + 0x7e; + val_mask = (0xffff << 0); + val_shift = 0; + break; + case (0x1 << 12): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7c : + 0x7f; + val_mask = (0xffff << 0); + val_shift = 0; + break; + case (0x3 << 13): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x348 : + 0x349; + val_mask = (0xff << 0); + val_shift = 0; + break; + case (0x1 << 13): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x348 : + 0x349; + val_mask = (0xf << 0); + val_shift = 0; + break; + default: + addr = 0xffff; + break; + } + } else if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID1) { + + switch (field) { + case (0x1 << 1): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 1); + val_shift = 1; + break; + case (0x1 << 3): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 3); + val_shift = 3; + break; + case (0x1 << 5): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 5); + val_shift = 5; + break; + case (0x1 << 4): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 4); + val_shift = 4; + break; + case (0x1 << 2): + + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 2); + val_shift = 2; + break; + case (0x1 << 7): + + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x7 << 8); + val_shift = 8; + break; + case (0x1 << 11): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 14); + val_shift = 14; + break; + case (0x1 << 10): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 13); + val_shift = 13; + break; + case (0x1 << 9): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 12); + val_shift = 12; + break; + case (0x1 << 8): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 11); + val_shift = 11; + break; + case (0x1 << 6): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 6); + val_shift = 6; + break; + case (0x1 << 0): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 0); + val_shift = 0; + break; + default: + addr = 0xffff; + break; + } + } else if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID2) { + + switch (field) { + case (0x1 << 3): + en_addr = (core_num == 0) ? 0x346 : + 0x347; + val_addr = (core_num == 0) ? 0x344 : + 0x345; + val_mask = (0x1 << 3); + val_shift = 3; + break; + case (0x1 << 1): + en_addr = (core_num == 0) ? 0x346 : + 0x347; + val_addr = (core_num == 0) ? 0x344 : + 0x345; + val_mask = (0x1 << 1); + val_shift = 1; + break; + case (0x1 << 0): + en_addr = (core_num == 0) ? 0x346 : + 0x347; + val_addr = (core_num == 0) ? 0x344 : + 0x345; + val_mask = (0x1 << 0); + val_shift = 0; + break; + case (0x1 << 2): + en_addr = (core_num == 0) ? 0x346 : + 0x347; + val_addr = (core_num == 0) ? 0x344 : + 0x345; + val_mask = (0x1 << 2); + val_shift = 2; + break; + case (0x1 << 4): + en_addr = (core_num == 0) ? 0x346 : + 0x347; + val_addr = (core_num == 0) ? 0x344 : + 0x345; + val_mask = (0x1 << 4); + val_shift = 4; + break; + default: + addr = 0xffff; + break; + } + } + + if (off) { + and_phy_reg(pi, en_addr, ~en_mask); + and_phy_reg(pi, val_addr, ~val_mask); + } else { + + if ((core_mask == 0) + || (core_mask & (1 << core_num))) { + or_phy_reg(pi, en_addr, en_mask); + + if (addr != 0xffff) { + mod_phy_reg(pi, val_addr, + val_mask, + (value << + val_shift)); + } + } + } + } + } +} + +static void +wlc_phy_rfctrl_override_nphy(phy_info_t *pi, u16 field, u16 value, + u8 core_mask, u8 off) +{ + u8 core_num; + u16 addr = 0, mask = 0, en_addr = 0, val_addr = 0, en_mask = + 0, val_mask = 0; + u8 shift = 0, val_shift = 0; + + if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) { + + en_mask = field; + for (core_num = 0; core_num < 2; core_num++) { + + switch (field) { + case (0x1 << 1): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : 0x7d; + val_mask = (0x1 << 0); + val_shift = 0; + break; + case (0x1 << 2): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : 0x7d; + val_mask = (0x1 << 1); + val_shift = 1; + break; + case (0x1 << 3): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : 0x7d; + val_mask = (0x1 << 2); + val_shift = 2; + break; + case (0x1 << 4): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : 0x7d; + val_mask = (0x1 << 4); + val_shift = 4; + break; + case (0x1 << 5): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : 0x7d; + val_mask = (0x1 << 5); + val_shift = 5; + break; + case (0x1 << 6): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : 0x7d; + val_mask = (0x1 << 6); + val_shift = 6; + break; + case (0x1 << 7): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : 0x7d; + val_mask = (0x1 << 7); + val_shift = 7; + break; + case (0x1 << 8): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : 0x7d; + val_mask = (0x7 << 8); + val_shift = 8; + break; + case (0x1 << 11): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : 0x7d; + val_mask = (0x7 << 13); + val_shift = 13; + break; + + case (0x1 << 9): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0xf8 : 0xfa; + val_mask = (0x7 << 0); + val_shift = 0; + break; + + case (0x1 << 10): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0xf8 : 0xfa; + val_mask = (0x7 << 4); + val_shift = 4; + break; + + case (0x1 << 12): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7b : 0x7e; + val_mask = (0xffff << 0); + val_shift = 0; + break; + case (0x1 << 13): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7c : 0x7f; + val_mask = (0xffff << 0); + val_shift = 0; + break; + case (0x1 << 14): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0xf9 : 0xfb; + val_mask = (0x3 << 6); + val_shift = 6; + break; + case (0x1 << 0): + en_addr = (core_num == 0) ? 0xe5 : 0xe6; + val_addr = (core_num == 0) ? 0xf9 : 0xfb; + val_mask = (0x1 << 15); + val_shift = 15; + break; + default: + addr = 0xffff; + break; + } + + if (off) { + and_phy_reg(pi, en_addr, ~en_mask); + and_phy_reg(pi, val_addr, ~val_mask); + } else { + + if ((core_mask == 0) + || (core_mask & (1 << core_num))) { + or_phy_reg(pi, en_addr, en_mask); + + if (addr != 0xffff) { + mod_phy_reg(pi, val_addr, + val_mask, + (value << + val_shift)); + } + } + } + } + } else { + + if (off) { + and_phy_reg(pi, 0xec, ~field); + value = 0x0; + } else { + or_phy_reg(pi, 0xec, field); + } + + for (core_num = 0; core_num < 2; core_num++) { + + switch (field) { + case (0x1 << 1): + case (0x1 << 9): + case (0x1 << 12): + case (0x1 << 13): + case (0x1 << 14): + addr = 0x78; + + core_mask = 0x1; + break; + case (0x1 << 2): + case (0x1 << 3): + case (0x1 << 4): + case (0x1 << 5): + case (0x1 << 6): + case (0x1 << 7): + case (0x1 << 8): + addr = (core_num == 0) ? 0x7a : 0x7d; + break; + case (0x1 << 10): + addr = (core_num == 0) ? 0x7b : 0x7e; + break; + case (0x1 << 11): + addr = (core_num == 0) ? 0x7c : 0x7f; + break; + default: + addr = 0xffff; + } + + switch (field) { + case (0x1 << 1): + mask = (0x7 << 3); + shift = 3; + break; + case (0x1 << 9): + mask = (0x1 << 2); + shift = 2; + break; + case (0x1 << 12): + mask = (0x1 << 8); + shift = 8; + break; + case (0x1 << 13): + mask = (0x1 << 9); + shift = 9; + break; + case (0x1 << 14): + mask = (0xf << 12); + shift = 12; + break; + case (0x1 << 2): + mask = (0x1 << 0); + shift = 0; + break; + case (0x1 << 3): + mask = (0x1 << 1); + shift = 1; + break; + case (0x1 << 4): + mask = (0x1 << 2); + shift = 2; + break; + case (0x1 << 5): + mask = (0x3 << 4); + shift = 4; + break; + case (0x1 << 6): + mask = (0x3 << 6); + shift = 6; + break; + case (0x1 << 7): + mask = (0x1 << 8); + shift = 8; + break; + case (0x1 << 8): + mask = (0x1 << 9); + shift = 9; + break; + case (0x1 << 10): + mask = 0x1fff; + shift = 0x0; + break; + case (0x1 << 11): + mask = 0x1fff; + shift = 0x0; + break; + default: + mask = 0x0; + shift = 0x0; + break; + } + + if ((addr != 0xffff) && (core_mask & (1 << core_num))) { + mod_phy_reg(pi, addr, mask, (value << shift)); + } + } + + or_phy_reg(pi, 0xec, (0x1 << 0)); + or_phy_reg(pi, 0x78, (0x1 << 0)); + udelay(1); + and_phy_reg(pi, 0xec, ~(0x1 << 0)); + } +} + +static void +wlc_phy_rfctrl_override_1tomany_nphy(phy_info_t *pi, u16 cmd, u16 value, + u8 core_mask, u8 off) +{ + u16 rfmxgain = 0, lpfgain = 0; + u16 tgain = 0; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + switch (cmd) { + case NPHY_REV7_RfctrlOverride_cmd_rxrf_pu: + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), + value, core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), value, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), value, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + break; + case NPHY_REV7_RfctrlOverride_cmd_rx_pu: + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), + value, core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), value, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID2); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + break; + case NPHY_REV7_RfctrlOverride_cmd_tx_pu: + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), + value, core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), value, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID2); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), value, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID2); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 1, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + break; + case NPHY_REV7_RfctrlOverride_cmd_rxgain: + rfmxgain = value & 0x000ff; + lpfgain = value & 0x0ff00; + lpfgain = lpfgain >> 8; + + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), + rfmxgain, core_mask, + off, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x3 << 13), + lpfgain, core_mask, + off, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + break; + case NPHY_REV7_RfctrlOverride_cmd_txgain: + tgain = value & 0x7fff; + lpfgain = value & 0x8000; + lpfgain = lpfgain >> 14; + + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), + tgain, core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 13), + lpfgain, core_mask, + off, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + break; + } + } +} + +static void +wlc_phy_scale_offset_rssi_nphy(phy_info_t *pi, u16 scale, s8 offset, + u8 coresel, u8 rail, u8 rssi_type) +{ + u16 valuetostuff; + + offset = (offset > NPHY_RSSICAL_MAXREAD) ? + NPHY_RSSICAL_MAXREAD : offset; + offset = (offset < (-NPHY_RSSICAL_MAXREAD - 1)) ? + -NPHY_RSSICAL_MAXREAD - 1 : offset; + + valuetostuff = ((scale & 0x3f) << 8) | (offset & 0x3f); + + if (((coresel == RADIO_MIMO_CORESEL_CORE1) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB)) { + write_phy_reg(pi, 0x1a6, valuetostuff); + } + if (((coresel == RADIO_MIMO_CORESEL_CORE1) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB)) { + write_phy_reg(pi, 0x1ac, valuetostuff); + } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB)) { + write_phy_reg(pi, 0x1b2, valuetostuff); + } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB)) { + write_phy_reg(pi, 0x1b8, valuetostuff); + } + + if (((coresel == RADIO_MIMO_CORESEL_CORE1) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1)) { + write_phy_reg(pi, 0x1a4, valuetostuff); + } + if (((coresel == RADIO_MIMO_CORESEL_CORE1) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1)) { + write_phy_reg(pi, 0x1aa, valuetostuff); + } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1)) { + write_phy_reg(pi, 0x1b0, valuetostuff); + } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1)) { + write_phy_reg(pi, 0x1b6, valuetostuff); + } + + if (((coresel == RADIO_MIMO_CORESEL_CORE1) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2)) { + write_phy_reg(pi, 0x1a5, valuetostuff); + } + if (((coresel == RADIO_MIMO_CORESEL_CORE1) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2)) { + write_phy_reg(pi, 0x1ab, valuetostuff); + } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2)) { + write_phy_reg(pi, 0x1b1, valuetostuff); + } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2)) { + write_phy_reg(pi, 0x1b7, valuetostuff); + } + + if (((coresel == RADIO_MIMO_CORESEL_CORE1) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD)) { + write_phy_reg(pi, 0x1a7, valuetostuff); + } + if (((coresel == RADIO_MIMO_CORESEL_CORE1) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD)) { + write_phy_reg(pi, 0x1ad, valuetostuff); + } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD)) { + write_phy_reg(pi, 0x1b3, valuetostuff); + } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD)) { + write_phy_reg(pi, 0x1b9, valuetostuff); + } + + if (((coresel == RADIO_MIMO_CORESEL_CORE1) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ)) { + write_phy_reg(pi, 0x1a8, valuetostuff); + } + if (((coresel == RADIO_MIMO_CORESEL_CORE1) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ)) { + write_phy_reg(pi, 0x1ae, valuetostuff); + } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ)) { + write_phy_reg(pi, 0x1b4, valuetostuff); + } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ)) { + write_phy_reg(pi, 0x1ba, valuetostuff); + } + + if (((coresel == RADIO_MIMO_CORESEL_CORE1) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rssi_type == NPHY_RSSI_SEL_TSSI_2G)) { + write_phy_reg(pi, 0x1a9, valuetostuff); + } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rssi_type == NPHY_RSSI_SEL_TSSI_2G)) { + write_phy_reg(pi, 0x1b5, valuetostuff); + } + + if (((coresel == RADIO_MIMO_CORESEL_CORE1) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rssi_type == NPHY_RSSI_SEL_TSSI_5G)) { + write_phy_reg(pi, 0x1af, valuetostuff); + } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || + (coresel == RADIO_MIMO_CORESEL_ALLRX)) && + (rssi_type == NPHY_RSSI_SEL_TSSI_5G)) { + write_phy_reg(pi, 0x1bb, valuetostuff); + } +} + +void wlc_phy_rssisel_nphy(phy_info_t *pi, u8 core_code, u8 rssi_type) +{ + u16 mask, val; + u16 afectrlovr_rssi_val, rfctrlcmd_rxen_val, rfctrlcmd_coresel_val, + startseq; + u16 rfctrlovr_rssi_val, rfctrlovr_rxen_val, rfctrlovr_coresel_val, + rfctrlovr_trigger_val; + u16 afectrlovr_rssi_mask, rfctrlcmd_mask, rfctrlovr_mask; + u16 rfctrlcmd_val, rfctrlovr_val; + u8 core; + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (core_code == RADIO_MIMO_CORESEL_OFF) { + mod_phy_reg(pi, 0x8f, (0x1 << 9), 0); + mod_phy_reg(pi, 0xa5, (0x1 << 9), 0); + + mod_phy_reg(pi, 0xa6, (0x3 << 8), 0); + mod_phy_reg(pi, 0xa7, (0x3 << 8), 0); + + mod_phy_reg(pi, 0xe5, (0x1 << 5), 0); + mod_phy_reg(pi, 0xe6, (0x1 << 5), 0); + + mask = (0x1 << 2) | + (0x1 << 3) | (0x1 << 4) | (0x1 << 5); + mod_phy_reg(pi, 0xf9, mask, 0); + mod_phy_reg(pi, 0xfb, mask, 0); + + } else { + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + if (core_code == RADIO_MIMO_CORESEL_CORE1 + && core == PHY_CORE_1) + continue; + else if (core_code == RADIO_MIMO_CORESEL_CORE2 + && core == PHY_CORE_0) + continue; + + mod_phy_reg(pi, (core == PHY_CORE_0) ? + 0x8f : 0xa5, (0x1 << 9), 1 << 9); + + if (rssi_type == NPHY_RSSI_SEL_W1 || + rssi_type == NPHY_RSSI_SEL_W2 || + rssi_type == NPHY_RSSI_SEL_NB) { + + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0xa6 : 0xa7, + (0x3 << 8), 0); + + mask = (0x1 << 2) | + (0x1 << 3) | + (0x1 << 4) | (0x1 << 5); + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0xf9 : 0xfb, + mask, 0); + + if (rssi_type == NPHY_RSSI_SEL_W1) { + if (CHSPEC_IS5G + (pi->radio_chanspec)) { + mask = (0x1 << 2); + val = 1 << 2; + } else { + mask = (0x1 << 3); + val = 1 << 3; + } + } else if (rssi_type == + NPHY_RSSI_SEL_W2) { + mask = (0x1 << 4); + val = 1 << 4; + } else { + mask = (0x1 << 5); + val = 1 << 5; + } + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0xf9 : 0xfb, + mask, val); + + mask = (0x1 << 5); + val = 1 << 5; + mod_phy_reg(pi, (core == PHY_CORE_0) ? + 0xe5 : 0xe6, mask, val); + } else { + if (rssi_type == NPHY_RSSI_SEL_TBD) { + + mask = (0x3 << 8); + val = 1 << 8; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0xa6 + : 0xa7, mask, val); + mask = (0x3 << 10); + val = 1 << 10; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0xa6 + : 0xa7, mask, val); + } else if (rssi_type == + NPHY_RSSI_SEL_IQ) { + + mask = (0x3 << 8); + val = 2 << 8; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0xa6 + : 0xa7, mask, val); + mask = (0x3 << 10); + val = 2 << 10; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0xa6 + : 0xa7, mask, val); + } else { + + mask = (0x3 << 8); + val = 3 << 8; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0xa6 + : 0xa7, mask, val); + mask = (0x3 << 10); + val = 3 << 10; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0xa6 + : 0xa7, mask, val); + + if (PHY_IPA(pi)) { + if (NREV_GE + (pi->pubpi.phy_rev, + 7)) { + + write_radio_reg + (pi, + ((core == + PHY_CORE_0) + ? + RADIO_2057_TX0_TX_SSI_MUX + : + RADIO_2057_TX1_TX_SSI_MUX), + (CHSPEC_IS5G + (pi-> + radio_chanspec) + ? 0xc : + 0xe)); + } else { + write_radio_reg + (pi, + RADIO_2056_TX_TX_SSI_MUX + | + ((core == + PHY_CORE_0) + ? + RADIO_2056_TX0 + : + RADIO_2056_TX1), + (CHSPEC_IS5G + (pi-> + radio_chanspec) + ? 0xc : + 0xe)); + } + } else { + + if (NREV_GE + (pi->pubpi.phy_rev, + 7)) { + write_radio_reg + (pi, + ((core == + PHY_CORE_0) + ? + RADIO_2057_TX0_TX_SSI_MUX + : + RADIO_2057_TX1_TX_SSI_MUX), + 0x11); + + if (pi->pubpi. + radioid == + BCM2057_ID) + write_radio_reg + (pi, + RADIO_2057_IQTEST_SEL_PU, + 0x1); + + } else { + write_radio_reg + (pi, + RADIO_2056_TX_TX_SSI_MUX + | + ((core == + PHY_CORE_0) + ? + RADIO_2056_TX0 + : + RADIO_2056_TX1), + 0x11); + } + } + + afectrlovr_rssi_val = 1 << 9; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x8f + : 0xa5, (0x1 << 9), + afectrlovr_rssi_val); + } + } + } + } + } else { + + if ((rssi_type == NPHY_RSSI_SEL_W1) || + (rssi_type == NPHY_RSSI_SEL_W2) || + (rssi_type == NPHY_RSSI_SEL_NB)) { + + val = 0x0; + } else if (rssi_type == NPHY_RSSI_SEL_TBD) { + + val = 0x1; + } else if (rssi_type == NPHY_RSSI_SEL_IQ) { + + val = 0x2; + } else { + + val = 0x3; + } + mask = ((0x3 << 12) | (0x3 << 14)); + val = (val << 12) | (val << 14); + mod_phy_reg(pi, 0xa6, mask, val); + mod_phy_reg(pi, 0xa7, mask, val); + + if ((rssi_type == NPHY_RSSI_SEL_W1) || + (rssi_type == NPHY_RSSI_SEL_W2) || + (rssi_type == NPHY_RSSI_SEL_NB)) { + if (rssi_type == NPHY_RSSI_SEL_W1) { + val = 0x1; + } + if (rssi_type == NPHY_RSSI_SEL_W2) { + val = 0x2; + } + if (rssi_type == NPHY_RSSI_SEL_NB) { + val = 0x3; + } + mask = (0x3 << 4); + val = (val << 4); + mod_phy_reg(pi, 0x7a, mask, val); + mod_phy_reg(pi, 0x7d, mask, val); + } + + if (core_code == RADIO_MIMO_CORESEL_OFF) { + afectrlovr_rssi_val = 0; + rfctrlcmd_rxen_val = 0; + rfctrlcmd_coresel_val = 0; + rfctrlovr_rssi_val = 0; + rfctrlovr_rxen_val = 0; + rfctrlovr_coresel_val = 0; + rfctrlovr_trigger_val = 0; + startseq = 0; + } else { + afectrlovr_rssi_val = 1; + rfctrlcmd_rxen_val = 1; + rfctrlcmd_coresel_val = core_code; + rfctrlovr_rssi_val = 1; + rfctrlovr_rxen_val = 1; + rfctrlovr_coresel_val = 1; + rfctrlovr_trigger_val = 1; + startseq = 1; + } + + afectrlovr_rssi_mask = ((0x1 << 12) | (0x1 << 13)); + afectrlovr_rssi_val = (afectrlovr_rssi_val << + 12) | (afectrlovr_rssi_val << 13); + mod_phy_reg(pi, 0xa5, afectrlovr_rssi_mask, + afectrlovr_rssi_val); + + if ((rssi_type == NPHY_RSSI_SEL_W1) || + (rssi_type == NPHY_RSSI_SEL_W2) || + (rssi_type == NPHY_RSSI_SEL_NB)) { + rfctrlcmd_mask = ((0x1 << 8) | (0x7 << 3)); + rfctrlcmd_val = (rfctrlcmd_rxen_val << 8) | + (rfctrlcmd_coresel_val << 3); + + rfctrlovr_mask = ((0x1 << 5) | + (0x1 << 12) | + (0x1 << 1) | (0x1 << 0)); + rfctrlovr_val = (rfctrlovr_rssi_val << + 5) | + (rfctrlovr_rxen_val << 12) | + (rfctrlovr_coresel_val << 1) | + (rfctrlovr_trigger_val << 0); + + mod_phy_reg(pi, 0x78, rfctrlcmd_mask, rfctrlcmd_val); + mod_phy_reg(pi, 0xec, rfctrlovr_mask, rfctrlovr_val); + + mod_phy_reg(pi, 0x78, (0x1 << 0), (startseq << 0)); + udelay(20); + + mod_phy_reg(pi, 0xec, (0x1 << 0), 0); + } + } +} + +int +wlc_phy_poll_rssi_nphy(phy_info_t *pi, u8 rssi_type, s32 *rssi_buf, + u8 nsamps) +{ + s16 rssi0, rssi1; + u16 afectrlCore1_save = 0; + u16 afectrlCore2_save = 0; + u16 afectrlOverride1_save = 0; + u16 afectrlOverride2_save = 0; + u16 rfctrlOverrideAux0_save = 0; + u16 rfctrlOverrideAux1_save = 0; + u16 rfctrlMiscReg1_save = 0; + u16 rfctrlMiscReg2_save = 0; + u16 rfctrlcmd_save = 0; + u16 rfctrloverride_save = 0; + u16 rfctrlrssiothers1_save = 0; + u16 rfctrlrssiothers2_save = 0; + s8 tmp_buf[4]; + u8 ctr = 0, samp = 0; + s32 rssi_out_val; + u16 gpiosel_orig; + + afectrlCore1_save = read_phy_reg(pi, 0xa6); + afectrlCore2_save = read_phy_reg(pi, 0xa7); + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + rfctrlMiscReg1_save = read_phy_reg(pi, 0xf9); + rfctrlMiscReg2_save = read_phy_reg(pi, 0xfb); + afectrlOverride1_save = read_phy_reg(pi, 0x8f); + afectrlOverride2_save = read_phy_reg(pi, 0xa5); + rfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5); + rfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6); + } else { + afectrlOverride1_save = read_phy_reg(pi, 0xa5); + rfctrlcmd_save = read_phy_reg(pi, 0x78); + rfctrloverride_save = read_phy_reg(pi, 0xec); + rfctrlrssiothers1_save = read_phy_reg(pi, 0x7a); + rfctrlrssiothers2_save = read_phy_reg(pi, 0x7d); + } + + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type); + + gpiosel_orig = read_phy_reg(pi, 0xca); + if (NREV_LT(pi->pubpi.phy_rev, 2)) { + write_phy_reg(pi, 0xca, 5); + } + + for (ctr = 0; ctr < 4; ctr++) { + rssi_buf[ctr] = 0; + } + + for (samp = 0; samp < nsamps; samp++) { + if (NREV_LT(pi->pubpi.phy_rev, 2)) { + rssi0 = read_phy_reg(pi, 0x1c9); + rssi1 = read_phy_reg(pi, 0x1ca); + } else { + rssi0 = read_phy_reg(pi, 0x219); + rssi1 = read_phy_reg(pi, 0x21a); + } + + ctr = 0; + tmp_buf[ctr++] = ((s8) ((rssi0 & 0x3f) << 2)) >> 2; + tmp_buf[ctr++] = ((s8) (((rssi0 >> 8) & 0x3f) << 2)) >> 2; + tmp_buf[ctr++] = ((s8) ((rssi1 & 0x3f) << 2)) >> 2; + tmp_buf[ctr++] = ((s8) (((rssi1 >> 8) & 0x3f) << 2)) >> 2; + + for (ctr = 0; ctr < 4; ctr++) { + rssi_buf[ctr] += tmp_buf[ctr]; + } + + } + + rssi_out_val = rssi_buf[3] & 0xff; + rssi_out_val |= (rssi_buf[2] & 0xff) << 8; + rssi_out_val |= (rssi_buf[1] & 0xff) << 16; + rssi_out_val |= (rssi_buf[0] & 0xff) << 24; + + if (NREV_LT(pi->pubpi.phy_rev, 2)) { + write_phy_reg(pi, 0xca, gpiosel_orig); + } + + write_phy_reg(pi, 0xa6, afectrlCore1_save); + write_phy_reg(pi, 0xa7, afectrlCore2_save); + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + write_phy_reg(pi, 0xf9, rfctrlMiscReg1_save); + write_phy_reg(pi, 0xfb, rfctrlMiscReg2_save); + write_phy_reg(pi, 0x8f, afectrlOverride1_save); + write_phy_reg(pi, 0xa5, afectrlOverride2_save); + write_phy_reg(pi, 0xe5, rfctrlOverrideAux0_save); + write_phy_reg(pi, 0xe6, rfctrlOverrideAux1_save); + } else { + write_phy_reg(pi, 0xa5, afectrlOverride1_save); + write_phy_reg(pi, 0x78, rfctrlcmd_save); + write_phy_reg(pi, 0xec, rfctrloverride_save); + write_phy_reg(pi, 0x7a, rfctrlrssiothers1_save); + write_phy_reg(pi, 0x7d, rfctrlrssiothers2_save); + } + + return rssi_out_val; +} + +s16 wlc_phy_tempsense_nphy(phy_info_t *pi) +{ + u16 core1_txrf_iqcal1_save, core1_txrf_iqcal2_save; + u16 core2_txrf_iqcal1_save, core2_txrf_iqcal2_save; + u16 pwrdet_rxtx_core1_save; + u16 pwrdet_rxtx_core2_save; + u16 afectrlCore1_save; + u16 afectrlCore2_save; + u16 afectrlOverride_save; + u16 afectrlOverride2_save; + u16 pd_pll_ts_save; + u16 gpioSel_save; + s32 radio_temp[4]; + s32 radio_temp2[4]; + u16 syn_tempprocsense_save; + s16 offset = 0; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + u16 auxADC_Vmid, auxADC_Av, auxADC_Vmid_save, auxADC_Av_save; + u16 auxADC_rssi_ctrlL_save, auxADC_rssi_ctrlH_save; + u16 auxADC_rssi_ctrlL, auxADC_rssi_ctrlH; + s32 auxADC_Vl; + u16 RfctrlOverride5_save, RfctrlOverride6_save; + u16 RfctrlMiscReg5_save, RfctrlMiscReg6_save; + u16 RSSIMultCoef0QPowerDet_save; + u16 tempsense_Rcal; + + syn_tempprocsense_save = + read_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG); + + afectrlCore1_save = read_phy_reg(pi, 0xa6); + afectrlCore2_save = read_phy_reg(pi, 0xa7); + afectrlOverride_save = read_phy_reg(pi, 0x8f); + afectrlOverride2_save = read_phy_reg(pi, 0xa5); + RSSIMultCoef0QPowerDet_save = read_phy_reg(pi, 0x1ae); + RfctrlOverride5_save = read_phy_reg(pi, 0x346); + RfctrlOverride6_save = read_phy_reg(pi, 0x347); + RfctrlMiscReg5_save = read_phy_reg(pi, 0x344); + RfctrlMiscReg6_save = read_phy_reg(pi, 0x345); + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16, + &auxADC_Vmid_save); + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16, + &auxADC_Av_save); + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16, + &auxADC_rssi_ctrlL_save); + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16, + &auxADC_rssi_ctrlH_save); + + write_phy_reg(pi, 0x1ae, 0x0); + + auxADC_rssi_ctrlL = 0x0; + auxADC_rssi_ctrlH = 0x20; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16, + &auxADC_rssi_ctrlL); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16, + &auxADC_rssi_ctrlH); + + tempsense_Rcal = syn_tempprocsense_save & 0x1c; + + write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, + tempsense_Rcal | 0x01); + + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), + 1, 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID2); + mod_phy_reg(pi, 0xa6, (0x1 << 7), 0); + mod_phy_reg(pi, 0xa7, (0x1 << 7), 0); + mod_phy_reg(pi, 0x8f, (0x1 << 7), (0x1 << 7)); + mod_phy_reg(pi, 0xa5, (0x1 << 7), (0x1 << 7)); + + mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2)); + mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2)); + mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2)); + mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2)); + udelay(5); + mod_phy_reg(pi, 0xa6, (0x1 << 2), 0); + mod_phy_reg(pi, 0xa7, (0x1 << 2), 0); + mod_phy_reg(pi, 0xa6, (0x1 << 3), 0); + mod_phy_reg(pi, 0xa7, (0x1 << 3), 0); + mod_phy_reg(pi, 0x8f, (0x1 << 3), (0x1 << 3)); + mod_phy_reg(pi, 0xa5, (0x1 << 3), (0x1 << 3)); + mod_phy_reg(pi, 0xa6, (0x1 << 6), 0); + mod_phy_reg(pi, 0xa7, (0x1 << 6), 0); + mod_phy_reg(pi, 0x8f, (0x1 << 6), (0x1 << 6)); + mod_phy_reg(pi, 0xa5, (0x1 << 6), (0x1 << 6)); + + auxADC_Vmid = 0xA3; + auxADC_Av = 0x0; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16, + &auxADC_Vmid); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16, + &auxADC_Av); + + udelay(3); + + wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1); + write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, + tempsense_Rcal | 0x03); + + udelay(5); + wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1); + + auxADC_Av = 0x7; + if (radio_temp[1] + radio_temp2[1] < -30) { + auxADC_Vmid = 0x45; + auxADC_Vl = 263; + } else if (radio_temp[1] + radio_temp2[1] < -9) { + auxADC_Vmid = 0x200; + auxADC_Vl = 467; + } else if (radio_temp[1] + radio_temp2[1] < 11) { + auxADC_Vmid = 0x266; + auxADC_Vl = 634; + } else { + auxADC_Vmid = 0x2D5; + auxADC_Vl = 816; + } + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16, + &auxADC_Vmid); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16, + &auxADC_Av); + + udelay(3); + + wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1); + write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, + tempsense_Rcal | 0x01); + + udelay(5); + wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1); + + write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, + syn_tempprocsense_save); + + write_phy_reg(pi, 0xa6, afectrlCore1_save); + write_phy_reg(pi, 0xa7, afectrlCore2_save); + write_phy_reg(pi, 0x8f, afectrlOverride_save); + write_phy_reg(pi, 0xa5, afectrlOverride2_save); + write_phy_reg(pi, 0x1ae, RSSIMultCoef0QPowerDet_save); + write_phy_reg(pi, 0x346, RfctrlOverride5_save); + write_phy_reg(pi, 0x347, RfctrlOverride6_save); + write_phy_reg(pi, 0x344, RfctrlMiscReg5_save); + write_phy_reg(pi, 0x345, RfctrlMiscReg5_save); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16, + &auxADC_Vmid_save); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16, + &auxADC_Av_save); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16, + &auxADC_rssi_ctrlL_save); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16, + &auxADC_rssi_ctrlH_save); + + if (pi->sh->chip == BCM5357_CHIP_ID) { + radio_temp[0] = (193 * (radio_temp[1] + radio_temp2[1]) + + 88 * (auxADC_Vl) - 27111 + + 128) / 256; + } else if (pi->sh->chip == BCM43236_CHIP_ID) { + radio_temp[0] = (198 * (radio_temp[1] + radio_temp2[1]) + + 91 * (auxADC_Vl) - 27243 + + 128) / 256; + } else { + radio_temp[0] = (179 * (radio_temp[1] + radio_temp2[1]) + + 82 * (auxADC_Vl) - 28861 + + 128) / 256; + } + + offset = (s16) pi->phy_tempsense_offset; + + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + syn_tempprocsense_save = + read_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE); + + afectrlCore1_save = read_phy_reg(pi, 0xa6); + afectrlCore2_save = read_phy_reg(pi, 0xa7); + afectrlOverride_save = read_phy_reg(pi, 0x8f); + afectrlOverride2_save = read_phy_reg(pi, 0xa5); + gpioSel_save = read_phy_reg(pi, 0xca); + + write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01); + + wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1); + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + } else { + write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x05); + } + + wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1); + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x01); + } else { + write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01); + } + + radio_temp[0] = + (126 * (radio_temp[1] + radio_temp2[1]) + 3987) / 64; + + write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, + syn_tempprocsense_save); + + write_phy_reg(pi, 0xca, gpioSel_save); + write_phy_reg(pi, 0xa6, afectrlCore1_save); + write_phy_reg(pi, 0xa7, afectrlCore2_save); + write_phy_reg(pi, 0x8f, afectrlOverride_save); + write_phy_reg(pi, 0xa5, afectrlOverride2_save); + + offset = (s16) pi->phy_tempsense_offset; + } else { + + pwrdet_rxtx_core1_save = + read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1); + pwrdet_rxtx_core2_save = + read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2); + core1_txrf_iqcal1_save = + read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1); + core1_txrf_iqcal2_save = + read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2); + core2_txrf_iqcal1_save = + read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1); + core2_txrf_iqcal2_save = + read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2); + pd_pll_ts_save = read_radio_reg(pi, RADIO_2055_PD_PLL_TS); + + afectrlCore1_save = read_phy_reg(pi, 0xa6); + afectrlCore2_save = read_phy_reg(pi, 0xa7); + afectrlOverride_save = read_phy_reg(pi, 0xa5); + gpioSel_save = read_phy_reg(pi, 0xca); + + write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x01); + write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x01); + write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x08); + write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x08); + write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04); + write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04); + write_radio_reg(pi, RADIO_2055_PD_PLL_TS, 0x00); + + wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1); + xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80); + + wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1); + xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80); + + wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1); + xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80); + + radio_temp[0] = (radio_temp[0] + radio_temp2[0]); + radio_temp[1] = (radio_temp[1] + radio_temp2[1]); + radio_temp[2] = (radio_temp[2] + radio_temp2[2]); + radio_temp[3] = (radio_temp[3] + radio_temp2[3]); + + radio_temp[0] = + (radio_temp[0] + radio_temp[1] + radio_temp[2] + + radio_temp[3]); + + radio_temp[0] = + (radio_temp[0] + (8 * 32)) * (950 - 350) / 63 + (350 * 8); + + radio_temp[0] = (radio_temp[0] - (8 * 420)) / 38; + + write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, + pwrdet_rxtx_core1_save); + write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, + pwrdet_rxtx_core2_save); + write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, + core1_txrf_iqcal1_save); + write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, + core2_txrf_iqcal1_save); + write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, + core1_txrf_iqcal2_save); + write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, + core2_txrf_iqcal2_save); + write_radio_reg(pi, RADIO_2055_PD_PLL_TS, pd_pll_ts_save); + + write_phy_reg(pi, 0xca, gpioSel_save); + write_phy_reg(pi, 0xa6, afectrlCore1_save); + write_phy_reg(pi, 0xa7, afectrlCore2_save); + write_phy_reg(pi, 0xa5, afectrlOverride_save); + } + + return (s16) radio_temp[0] + offset; +} + +static void +wlc_phy_set_rssi_2055_vcm(phy_info_t *pi, u8 rssi_type, u8 *vcm_buf) +{ + u8 core; + + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + if (rssi_type == NPHY_RSSI_SEL_NB) { + if (core == PHY_CORE_0) { + mod_radio_reg(pi, + RADIO_2055_CORE1_B0_NBRSSI_VCM, + RADIO_2055_NBRSSI_VCM_I_MASK, + vcm_buf[2 * + core] << + RADIO_2055_NBRSSI_VCM_I_SHIFT); + mod_radio_reg(pi, + RADIO_2055_CORE1_RXBB_RSSI_CTRL5, + RADIO_2055_NBRSSI_VCM_Q_MASK, + vcm_buf[2 * core + + 1] << + RADIO_2055_NBRSSI_VCM_Q_SHIFT); + } else { + mod_radio_reg(pi, + RADIO_2055_CORE2_B0_NBRSSI_VCM, + RADIO_2055_NBRSSI_VCM_I_MASK, + vcm_buf[2 * + core] << + RADIO_2055_NBRSSI_VCM_I_SHIFT); + mod_radio_reg(pi, + RADIO_2055_CORE2_RXBB_RSSI_CTRL5, + RADIO_2055_NBRSSI_VCM_Q_MASK, + vcm_buf[2 * core + + 1] << + RADIO_2055_NBRSSI_VCM_Q_SHIFT); + } + } else { + + if (core == PHY_CORE_0) { + mod_radio_reg(pi, + RADIO_2055_CORE1_RXBB_RSSI_CTRL5, + RADIO_2055_WBRSSI_VCM_IQ_MASK, + vcm_buf[2 * + core] << + RADIO_2055_WBRSSI_VCM_IQ_SHIFT); + } else { + mod_radio_reg(pi, + RADIO_2055_CORE2_RXBB_RSSI_CTRL5, + RADIO_2055_WBRSSI_VCM_IQ_MASK, + vcm_buf[2 * + core] << + RADIO_2055_WBRSSI_VCM_IQ_SHIFT); + } + } + } +} + +void wlc_phy_rssi_cal_nphy(phy_info_t *pi) +{ + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + + wlc_phy_rssi_cal_nphy_rev3(pi); + } else { + wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_NB); + wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W1); + wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W2); + } +} + +static void wlc_phy_rssi_cal_nphy_rev2(phy_info_t *pi, u8 rssi_type) +{ + s32 target_code; + u16 classif_state; + u16 clip_state[2]; + u16 rssi_ctrl_state[2], pd_state[2]; + u16 rfctrlintc_state[2], rfpdcorerxtx_state[2]; + u16 rfctrlintc_override_val; + u16 clip_off[] = { 0xffff, 0xffff }; + u16 rf_pd_val, pd_mask, rssi_ctrl_mask; + u8 vcm, min_vcm, vcm_tmp[4]; + u8 vcm_final[4] = { 0, 0, 0, 0 }; + u8 result_idx, ctr; + s32 poll_results[4][4] = { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} + }; + s32 poll_miniq[4][2] = { + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0} + }; + s32 min_d, curr_d; + s32 fine_digital_offset[4]; + s32 poll_results_min[4] = { 0, 0, 0, 0 }; + s32 min_poll; + + switch (rssi_type) { + case NPHY_RSSI_SEL_NB: + target_code = NPHY_RSSICAL_NB_TARGET; + break; + case NPHY_RSSI_SEL_W1: + target_code = NPHY_RSSICAL_W1_TARGET; + break; + case NPHY_RSSI_SEL_W2: + target_code = NPHY_RSSICAL_W2_TARGET; + break; + default: + return; + break; + } + + classif_state = wlc_phy_classifier_nphy(pi, 0, 0); + wlc_phy_classifier_nphy(pi, (0x7 << 0), 4); + wlc_phy_clip_det_nphy(pi, 0, clip_state); + wlc_phy_clip_det_nphy(pi, 1, clip_off); + + rf_pd_val = (rssi_type == NPHY_RSSI_SEL_NB) ? 0x6 : 0x4; + rfctrlintc_override_val = + CHSPEC_IS5G(pi->radio_chanspec) ? 0x140 : 0x110; + + rfctrlintc_state[0] = read_phy_reg(pi, 0x91); + rfpdcorerxtx_state[0] = read_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX); + write_phy_reg(pi, 0x91, rfctrlintc_override_val); + write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rf_pd_val); + + rfctrlintc_state[1] = read_phy_reg(pi, 0x92); + rfpdcorerxtx_state[1] = read_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX); + write_phy_reg(pi, 0x92, rfctrlintc_override_val); + write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rf_pd_val); + + pd_mask = RADIO_2055_NBRSSI_PD | RADIO_2055_WBRSSI_G1_PD | + RADIO_2055_WBRSSI_G2_PD; + pd_state[0] = + read_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC) & pd_mask; + pd_state[1] = + read_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC) & pd_mask; + mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, 0); + mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, 0); + rssi_ctrl_mask = RADIO_2055_NBRSSI_SEL | RADIO_2055_WBRSSI_G1_SEL | + RADIO_2055_WBRSSI_G2_SEL; + rssi_ctrl_state[0] = + read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE1) & rssi_ctrl_mask; + rssi_ctrl_state[1] = + read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE2) & rssi_ctrl_mask; + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type); + + wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX, + NPHY_RAIL_I, rssi_type); + wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX, + NPHY_RAIL_Q, rssi_type); + + for (vcm = 0; vcm < 4; vcm++) { + + vcm_tmp[0] = vcm_tmp[1] = vcm_tmp[2] = vcm_tmp[3] = vcm; + if (rssi_type != NPHY_RSSI_SEL_W2) { + wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_tmp); + } + + wlc_phy_poll_rssi_nphy(pi, rssi_type, &poll_results[vcm][0], + NPHY_RSSICAL_NPOLL); + + if ((rssi_type == NPHY_RSSI_SEL_W1) + || (rssi_type == NPHY_RSSI_SEL_W2)) { + for (ctr = 0; ctr < 2; ctr++) { + poll_miniq[vcm][ctr] = + min(poll_results[vcm][ctr * 2 + 0], + poll_results[vcm][ctr * 2 + 1]); + } + } + } + + for (result_idx = 0; result_idx < 4; result_idx++) { + min_d = NPHY_RSSICAL_MAXD; + min_vcm = 0; + min_poll = NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL + 1; + for (vcm = 0; vcm < 4; vcm++) { + curr_d = ABS(((rssi_type == NPHY_RSSI_SEL_NB) ? + poll_results[vcm][result_idx] : + poll_miniq[vcm][result_idx / 2]) - + (target_code * NPHY_RSSICAL_NPOLL)); + if (curr_d < min_d) { + min_d = curr_d; + min_vcm = vcm; + } + if (poll_results[vcm][result_idx] < min_poll) { + min_poll = poll_results[vcm][result_idx]; + } + } + vcm_final[result_idx] = min_vcm; + poll_results_min[result_idx] = min_poll; + } + + if (rssi_type != NPHY_RSSI_SEL_W2) { + wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_final); + } + + for (result_idx = 0; result_idx < 4; result_idx++) { + fine_digital_offset[result_idx] = + (target_code * NPHY_RSSICAL_NPOLL) - + poll_results[vcm_final[result_idx]][result_idx]; + if (fine_digital_offset[result_idx] < 0) { + fine_digital_offset[result_idx] = + ABS(fine_digital_offset[result_idx]); + fine_digital_offset[result_idx] += + (NPHY_RSSICAL_NPOLL / 2); + fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL; + fine_digital_offset[result_idx] = + -fine_digital_offset[result_idx]; + } else { + fine_digital_offset[result_idx] += + (NPHY_RSSICAL_NPOLL / 2); + fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL; + } + + if (poll_results_min[result_idx] == + NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL) { + fine_digital_offset[result_idx] = + (target_code - NPHY_RSSICAL_MAXREAD - 1); + } + + wlc_phy_scale_offset_rssi_nphy(pi, 0x0, + (s8) + fine_digital_offset[result_idx], + (result_idx / 2 == + 0) ? RADIO_MIMO_CORESEL_CORE1 : + RADIO_MIMO_CORESEL_CORE2, + (result_idx % 2 == + 0) ? NPHY_RAIL_I : NPHY_RAIL_Q, + rssi_type); + } + + mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, pd_state[0]); + mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, pd_state[1]); + if (rssi_ctrl_state[0] == RADIO_2055_NBRSSI_SEL) { + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, + NPHY_RSSI_SEL_NB); + } else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G1_SEL) { + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, + NPHY_RSSI_SEL_W1); + } else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G2_SEL) { + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, + NPHY_RSSI_SEL_W2); + } else { + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, + NPHY_RSSI_SEL_W2); + } + if (rssi_ctrl_state[1] == RADIO_2055_NBRSSI_SEL) { + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, + NPHY_RSSI_SEL_NB); + } else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G1_SEL) { + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, + NPHY_RSSI_SEL_W1); + } else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G2_SEL) { + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, + NPHY_RSSI_SEL_W2); + } else { + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, + NPHY_RSSI_SEL_W2); + } + + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, rssi_type); + + write_phy_reg(pi, 0x91, rfctrlintc_state[0]); + write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rfpdcorerxtx_state[0]); + write_phy_reg(pi, 0x92, rfctrlintc_state[1]); + write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rfpdcorerxtx_state[1]); + + wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state); + wlc_phy_clip_det_nphy(pi, 1, clip_state); + + wlc_phy_resetcca_nphy(pi); +} + +int BCMFASTPATH +wlc_phy_rssi_compute_nphy(phy_info_t *pi, wlc_d11rxhdr_t *wlc_rxh) +{ + d11rxhdr_t *rxh = &wlc_rxh->rxhdr; + s16 rxpwr, rxpwr0, rxpwr1; + s16 phyRx0_l, phyRx2_l; + + rxpwr = 0; + rxpwr0 = ltoh16(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR0_MASK; + rxpwr1 = (ltoh16(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR1_MASK) >> 8; + + if (rxpwr0 > 127) + rxpwr0 -= 256; + if (rxpwr1 > 127) + rxpwr1 -= 256; + + phyRx0_l = ltoh16(rxh->PhyRxStatus_0) & 0x00ff; + phyRx2_l = ltoh16(rxh->PhyRxStatus_2) & 0x00ff; + if (phyRx2_l > 127) + phyRx2_l -= 256; + + if (((rxpwr0 == 16) || (rxpwr0 == 32))) { + rxpwr0 = rxpwr1; + rxpwr1 = phyRx2_l; + } + + wlc_rxh->rxpwr[0] = (s8) rxpwr0; + wlc_rxh->rxpwr[1] = (s8) rxpwr1; + wlc_rxh->do_rssi_ma = 0; + + if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MAX) + rxpwr = (rxpwr0 > rxpwr1) ? rxpwr0 : rxpwr1; + else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MIN) + rxpwr = (rxpwr0 < rxpwr1) ? rxpwr0 : rxpwr1; + else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_AVG) + rxpwr = (rxpwr0 + rxpwr1) >> 1; + else + ASSERT(0); + + return rxpwr; +} + +static void +wlc_phy_rfctrlintc_override_nphy(phy_info_t *pi, u8 field, u16 value, + u8 core_code) +{ + u16 mask; + u16 val; + u8 core; + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + if (core_code == RADIO_MIMO_CORESEL_CORE1 + && core == PHY_CORE_1) + continue; + else if (core_code == RADIO_MIMO_CORESEL_CORE2 + && core == PHY_CORE_0) + continue; + + if (NREV_LT(pi->pubpi.phy_rev, 7)) { + + mask = (0x1 << 10); + val = 1 << 10; + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 : + 0x92, mask, val); + } + + if (field == NPHY_RfctrlIntc_override_OFF) { + + write_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 : + 0x92, 0); + + wlc_phy_force_rfseq_nphy(pi, + NPHY_RFSEQ_RESET2RX); + } else if (field == NPHY_RfctrlIntc_override_TRSW) { + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + mask = (0x1 << 6) | (0x1 << 7); + + val = value << 6; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + mask, val); + + or_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + (0x1 << 10)); + + and_phy_reg(pi, 0x2ff, (u16) + ~(0x3 << 14)); + or_phy_reg(pi, 0x2ff, (0x1 << 13)); + or_phy_reg(pi, 0x2ff, (0x1 << 0)); + } else { + + mask = (0x1 << 6) | + (0x1 << 7) | + (0x1 << 8) | (0x1 << 9); + val = value << 6; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + mask, val); + + mask = (0x1 << 0); + val = 1 << 0; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0xe7 : 0xec, + mask, val); + + mask = (core == PHY_CORE_0) ? (0x1 << 0) + : (0x1 << 1); + val = 1 << ((core == PHY_CORE_0) ? + 0 : 1); + mod_phy_reg(pi, 0x78, mask, val); + + SPINWAIT(((read_phy_reg(pi, 0x78) & val) + != 0), 10000); + ASSERT((read_phy_reg(pi, 0x78) & val) == + 0); + + mask = (0x1 << 0); + val = 0 << 0; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0xe7 : 0xec, + mask, val); + } + } else if (field == NPHY_RfctrlIntc_override_PA) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + mask = (0x1 << 4) | (0x1 << 5); + + if (CHSPEC_IS5G(pi->radio_chanspec)) { + val = value << 5; + } else { + val = value << 4; + } + + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + mask, val); + + or_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + (0x1 << 12)); + } else { + + if (CHSPEC_IS5G(pi->radio_chanspec)) { + mask = (0x1 << 5); + val = value << 5; + } else { + mask = (0x1 << 4); + val = value << 4; + } + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + mask, val); + } + } else if (field == NPHY_RfctrlIntc_override_EXT_LNA_PU) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (CHSPEC_IS5G(pi->radio_chanspec)) { + + mask = (0x1 << 0); + val = value << 0; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 + : 0x92, mask, val); + + mask = (0x1 << 2); + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 + : 0x92, mask, 0); + } else { + + mask = (0x1 << 2); + val = value << 2; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 + : 0x92, mask, val); + + mask = (0x1 << 0); + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 + : 0x92, mask, 0); + } + + mask = (0x1 << 11); + val = 1 << 11; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + mask, val); + } else { + + if (CHSPEC_IS5G(pi->radio_chanspec)) { + mask = (0x1 << 0); + val = value << 0; + } else { + mask = (0x1 << 2); + val = value << 2; + } + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + mask, val); + } + } else if (field == + NPHY_RfctrlIntc_override_EXT_LNA_GAIN) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (CHSPEC_IS5G(pi->radio_chanspec)) { + + mask = (0x1 << 1); + val = value << 1; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 + : 0x92, mask, val); + + mask = (0x1 << 3); + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 + : 0x92, mask, 0); + } else { + + mask = (0x1 << 3); + val = value << 3; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 + : 0x92, mask, val); + + mask = (0x1 << 1); + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 + : 0x92, mask, 0); + } + + mask = (0x1 << 11); + val = 1 << 11; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + mask, val); + } else { + + if (CHSPEC_IS5G(pi->radio_chanspec)) { + mask = (0x1 << 1); + val = value << 1; + } else { + mask = (0x1 << 3); + val = value << 3; + } + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + mask, val); + } + } + } + } else { + return; + } +} + +static void wlc_phy_rssi_cal_nphy_rev3(phy_info_t *pi) +{ + u16 classif_state; + u16 clip_state[2]; + u16 clip_off[] = { 0xffff, 0xffff }; + s32 target_code; + u8 vcm, min_vcm; + u8 vcm_final = 0; + u8 result_idx; + s32 poll_results[8][4] = { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} + }; + s32 poll_result_core[4] = { 0, 0, 0, 0 }; + s32 min_d = NPHY_RSSICAL_MAXD, curr_d; + s32 fine_digital_offset[4]; + s32 poll_results_min[4] = { 0, 0, 0, 0 }; + s32 min_poll; + u8 vcm_level_max; + u8 core; + u8 wb_cnt; + u8 rssi_type; + u16 NPHY_Rfctrlintc1_save, NPHY_Rfctrlintc2_save; + u16 NPHY_AfectrlOverride1_save, NPHY_AfectrlOverride2_save; + u16 NPHY_AfectrlCore1_save, NPHY_AfectrlCore2_save; + u16 NPHY_RfctrlOverride0_save, NPHY_RfctrlOverride1_save; + u16 NPHY_RfctrlOverrideAux0_save, NPHY_RfctrlOverrideAux1_save; + u16 NPHY_RfctrlCmd_save; + u16 NPHY_RfctrlMiscReg1_save, NPHY_RfctrlMiscReg2_save; + u16 NPHY_RfctrlRSSIOTHERS1_save, NPHY_RfctrlRSSIOTHERS2_save; + u8 rxcore_state; + u16 NPHY_REV7_RfctrlOverride3_save, NPHY_REV7_RfctrlOverride4_save; + u16 NPHY_REV7_RfctrlOverride5_save, NPHY_REV7_RfctrlOverride6_save; + u16 NPHY_REV7_RfctrlMiscReg3_save, NPHY_REV7_RfctrlMiscReg4_save; + u16 NPHY_REV7_RfctrlMiscReg5_save, NPHY_REV7_RfctrlMiscReg6_save; + + NPHY_REV7_RfctrlOverride3_save = NPHY_REV7_RfctrlOverride4_save = + NPHY_REV7_RfctrlOverride5_save = NPHY_REV7_RfctrlOverride6_save = + NPHY_REV7_RfctrlMiscReg3_save = NPHY_REV7_RfctrlMiscReg4_save = + NPHY_REV7_RfctrlMiscReg5_save = NPHY_REV7_RfctrlMiscReg6_save = 0; + + classif_state = wlc_phy_classifier_nphy(pi, 0, 0); + wlc_phy_classifier_nphy(pi, (0x7 << 0), 4); + wlc_phy_clip_det_nphy(pi, 0, clip_state); + wlc_phy_clip_det_nphy(pi, 1, clip_off); + + NPHY_Rfctrlintc1_save = read_phy_reg(pi, 0x91); + NPHY_Rfctrlintc2_save = read_phy_reg(pi, 0x92); + NPHY_AfectrlOverride1_save = read_phy_reg(pi, 0x8f); + NPHY_AfectrlOverride2_save = read_phy_reg(pi, 0xa5); + NPHY_AfectrlCore1_save = read_phy_reg(pi, 0xa6); + NPHY_AfectrlCore2_save = read_phy_reg(pi, 0xa7); + NPHY_RfctrlOverride0_save = read_phy_reg(pi, 0xe7); + NPHY_RfctrlOverride1_save = read_phy_reg(pi, 0xec); + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + NPHY_REV7_RfctrlOverride3_save = read_phy_reg(pi, 0x342); + NPHY_REV7_RfctrlOverride4_save = read_phy_reg(pi, 0x343); + NPHY_REV7_RfctrlOverride5_save = read_phy_reg(pi, 0x346); + NPHY_REV7_RfctrlOverride6_save = read_phy_reg(pi, 0x347); + } + NPHY_RfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5); + NPHY_RfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6); + NPHY_RfctrlCmd_save = read_phy_reg(pi, 0x78); + NPHY_RfctrlMiscReg1_save = read_phy_reg(pi, 0xf9); + NPHY_RfctrlMiscReg2_save = read_phy_reg(pi, 0xfb); + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + NPHY_REV7_RfctrlMiscReg3_save = read_phy_reg(pi, 0x340); + NPHY_REV7_RfctrlMiscReg4_save = read_phy_reg(pi, 0x341); + NPHY_REV7_RfctrlMiscReg5_save = read_phy_reg(pi, 0x344); + NPHY_REV7_RfctrlMiscReg6_save = read_phy_reg(pi, 0x345); + } + NPHY_RfctrlRSSIOTHERS1_save = read_phy_reg(pi, 0x7a); + NPHY_RfctrlRSSIOTHERS2_save = read_phy_reg(pi, 0x7d); + + wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_OFF, 0, + RADIO_MIMO_CORESEL_ALLRXTX); + wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_TRSW, 1, + RADIO_MIMO_CORESEL_ALLRXTX); + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + wlc_phy_rfctrl_override_1tomany_nphy(pi, + NPHY_REV7_RfctrlOverride_cmd_rxrf_pu, + 0, 0, 0); + } else { + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0, 0); + } + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + wlc_phy_rfctrl_override_1tomany_nphy(pi, + NPHY_REV7_RfctrlOverride_cmd_rx_pu, + 1, 0, 0); + } else { + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0, 0); + } + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), + 1, 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 6), 1, 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + } else { + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 7), 1, 0, 0); + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 6), 1, 0, 0); + } + + if (CHSPEC_IS5G(pi->radio_chanspec)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), + 0, 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 1, 0, + 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + } else { + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 0, 0, 0); + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 1, 0, 0); + } + + } else { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), + 0, 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 1, 0, + 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + } else { + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 0, 0, 0); + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 1, 0, 0); + } + } + + rxcore_state = wlc_phy_rxcore_getstate_nphy((wlc_phy_t *) pi); + + vcm_level_max = 8; + + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + + if ((rxcore_state & (1 << core)) == 0) + continue; + + wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, + core == + PHY_CORE_0 ? + RADIO_MIMO_CORESEL_CORE1 : + RADIO_MIMO_CORESEL_CORE2, + NPHY_RAIL_I, NPHY_RSSI_SEL_NB); + wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, + core == + PHY_CORE_0 ? + RADIO_MIMO_CORESEL_CORE1 : + RADIO_MIMO_CORESEL_CORE2, + NPHY_RAIL_Q, NPHY_RSSI_SEL_NB); + + for (vcm = 0; vcm < vcm_level_max; vcm++) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + mod_radio_reg(pi, (core == PHY_CORE_0) ? + RADIO_2057_NB_MASTER_CORE0 : + RADIO_2057_NB_MASTER_CORE1, + RADIO_2057_VCM_MASK, vcm); + } else { + + mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC | + ((core == + PHY_CORE_0) ? RADIO_2056_RX0 : + RADIO_2056_RX1), + RADIO_2056_VCM_MASK, + vcm << RADIO_2056_RSSI_VCM_SHIFT); + } + + wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_NB, + &poll_results[vcm][0], + NPHY_RSSICAL_NPOLL); + } + + for (result_idx = 0; result_idx < 4; result_idx++) { + if ((core == result_idx / 2) && (result_idx % 2 == 0)) { + + min_d = NPHY_RSSICAL_MAXD; + min_vcm = 0; + min_poll = + NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL + + 1; + for (vcm = 0; vcm < vcm_level_max; vcm++) { + curr_d = poll_results[vcm][result_idx] * + poll_results[vcm][result_idx] + + poll_results[vcm][result_idx + 1] * + poll_results[vcm][result_idx + 1]; + if (curr_d < min_d) { + min_d = curr_d; + min_vcm = vcm; + } + if (poll_results[vcm][result_idx] < + min_poll) { + min_poll = + poll_results[vcm] + [result_idx]; + } + } + vcm_final = min_vcm; + poll_results_min[result_idx] = min_poll; + } + } + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + mod_radio_reg(pi, (core == PHY_CORE_0) ? + RADIO_2057_NB_MASTER_CORE0 : + RADIO_2057_NB_MASTER_CORE1, + RADIO_2057_VCM_MASK, vcm_final); + } else { + mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC | + ((core == + PHY_CORE_0) ? RADIO_2056_RX0 : + RADIO_2056_RX1), RADIO_2056_VCM_MASK, + vcm_final << RADIO_2056_RSSI_VCM_SHIFT); + } + + for (result_idx = 0; result_idx < 4; result_idx++) { + if (core == result_idx / 2) { + fine_digital_offset[result_idx] = + (NPHY_RSSICAL_NB_TARGET * + NPHY_RSSICAL_NPOLL) - + poll_results[vcm_final][result_idx]; + if (fine_digital_offset[result_idx] < 0) { + fine_digital_offset[result_idx] = + ABS(fine_digital_offset + [result_idx]); + fine_digital_offset[result_idx] += + (NPHY_RSSICAL_NPOLL / 2); + fine_digital_offset[result_idx] /= + NPHY_RSSICAL_NPOLL; + fine_digital_offset[result_idx] = + -fine_digital_offset[result_idx]; + } else { + fine_digital_offset[result_idx] += + (NPHY_RSSICAL_NPOLL / 2); + fine_digital_offset[result_idx] /= + NPHY_RSSICAL_NPOLL; + } + + if (poll_results_min[result_idx] == + NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL) { + fine_digital_offset[result_idx] = + (NPHY_RSSICAL_NB_TARGET - + NPHY_RSSICAL_MAXREAD - 1); + } + + wlc_phy_scale_offset_rssi_nphy(pi, 0x0, + (s8) + fine_digital_offset + [result_idx], + (result_idx / + 2 == + 0) ? + RADIO_MIMO_CORESEL_CORE1 + : + RADIO_MIMO_CORESEL_CORE2, + (result_idx % + 2 == + 0) ? NPHY_RAIL_I + : NPHY_RAIL_Q, + NPHY_RSSI_SEL_NB); + } + } + + } + + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + + if ((rxcore_state & (1 << core)) == 0) + continue; + + for (wb_cnt = 0; wb_cnt < 2; wb_cnt++) { + if (wb_cnt == 0) { + rssi_type = NPHY_RSSI_SEL_W1; + target_code = NPHY_RSSICAL_W1_TARGET_REV3; + } else { + rssi_type = NPHY_RSSI_SEL_W2; + target_code = NPHY_RSSICAL_W2_TARGET_REV3; + } + + wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, + core == + PHY_CORE_0 ? + RADIO_MIMO_CORESEL_CORE1 + : + RADIO_MIMO_CORESEL_CORE2, + NPHY_RAIL_I, rssi_type); + wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, + core == + PHY_CORE_0 ? + RADIO_MIMO_CORESEL_CORE1 + : + RADIO_MIMO_CORESEL_CORE2, + NPHY_RAIL_Q, rssi_type); + + wlc_phy_poll_rssi_nphy(pi, rssi_type, poll_result_core, + NPHY_RSSICAL_NPOLL); + + for (result_idx = 0; result_idx < 4; result_idx++) { + if (core == result_idx / 2) { + fine_digital_offset[result_idx] = + (target_code * NPHY_RSSICAL_NPOLL) - + poll_result_core[result_idx]; + if (fine_digital_offset[result_idx] < 0) { + fine_digital_offset[result_idx] + = + ABS(fine_digital_offset + [result_idx]); + fine_digital_offset[result_idx] + += (NPHY_RSSICAL_NPOLL / 2); + fine_digital_offset[result_idx] + /= NPHY_RSSICAL_NPOLL; + fine_digital_offset[result_idx] + = + -fine_digital_offset + [result_idx]; + } else { + fine_digital_offset[result_idx] + += (NPHY_RSSICAL_NPOLL / 2); + fine_digital_offset[result_idx] + /= NPHY_RSSICAL_NPOLL; + } + + wlc_phy_scale_offset_rssi_nphy(pi, 0x0, + (s8) + fine_digital_offset + [core * + 2], + (core == + PHY_CORE_0) + ? + RADIO_MIMO_CORESEL_CORE1 + : + RADIO_MIMO_CORESEL_CORE2, + (result_idx + % 2 == + 0) ? + NPHY_RAIL_I + : + NPHY_RAIL_Q, + rssi_type); + } + } + + } + } + + write_phy_reg(pi, 0x91, NPHY_Rfctrlintc1_save); + write_phy_reg(pi, 0x92, NPHY_Rfctrlintc2_save); + + wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); + + mod_phy_reg(pi, 0xe7, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x78, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0xe7, (0x1 << 0), 0); + + mod_phy_reg(pi, 0xec, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x78, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0xec, (0x1 << 0), 0); + + write_phy_reg(pi, 0x8f, NPHY_AfectrlOverride1_save); + write_phy_reg(pi, 0xa5, NPHY_AfectrlOverride2_save); + write_phy_reg(pi, 0xa6, NPHY_AfectrlCore1_save); + write_phy_reg(pi, 0xa7, NPHY_AfectrlCore2_save); + write_phy_reg(pi, 0xe7, NPHY_RfctrlOverride0_save); + write_phy_reg(pi, 0xec, NPHY_RfctrlOverride1_save); + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + write_phy_reg(pi, 0x342, NPHY_REV7_RfctrlOverride3_save); + write_phy_reg(pi, 0x343, NPHY_REV7_RfctrlOverride4_save); + write_phy_reg(pi, 0x346, NPHY_REV7_RfctrlOverride5_save); + write_phy_reg(pi, 0x347, NPHY_REV7_RfctrlOverride6_save); + } + write_phy_reg(pi, 0xe5, NPHY_RfctrlOverrideAux0_save); + write_phy_reg(pi, 0xe6, NPHY_RfctrlOverrideAux1_save); + write_phy_reg(pi, 0x78, NPHY_RfctrlCmd_save); + write_phy_reg(pi, 0xf9, NPHY_RfctrlMiscReg1_save); + write_phy_reg(pi, 0xfb, NPHY_RfctrlMiscReg2_save); + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + write_phy_reg(pi, 0x340, NPHY_REV7_RfctrlMiscReg3_save); + write_phy_reg(pi, 0x341, NPHY_REV7_RfctrlMiscReg4_save); + write_phy_reg(pi, 0x344, NPHY_REV7_RfctrlMiscReg5_save); + write_phy_reg(pi, 0x345, NPHY_REV7_RfctrlMiscReg6_save); + } + write_phy_reg(pi, 0x7a, NPHY_RfctrlRSSIOTHERS1_save); + write_phy_reg(pi, 0x7d, NPHY_RfctrlRSSIOTHERS2_save); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + pi->rssical_cache.rssical_radio_regs_2G[0] = + read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0); + pi->rssical_cache.rssical_radio_regs_2G[1] = + read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1); + } else { + pi->rssical_cache.rssical_radio_regs_2G[0] = + read_radio_reg(pi, + RADIO_2056_RX_RSSI_MISC | + RADIO_2056_RX0); + pi->rssical_cache.rssical_radio_regs_2G[1] = + read_radio_reg(pi, + RADIO_2056_RX_RSSI_MISC | + RADIO_2056_RX1); + } + + pi->rssical_cache.rssical_phyregs_2G[0] = + read_phy_reg(pi, 0x1a6); + pi->rssical_cache.rssical_phyregs_2G[1] = + read_phy_reg(pi, 0x1ac); + pi->rssical_cache.rssical_phyregs_2G[2] = + read_phy_reg(pi, 0x1b2); + pi->rssical_cache.rssical_phyregs_2G[3] = + read_phy_reg(pi, 0x1b8); + pi->rssical_cache.rssical_phyregs_2G[4] = + read_phy_reg(pi, 0x1a4); + pi->rssical_cache.rssical_phyregs_2G[5] = + read_phy_reg(pi, 0x1aa); + pi->rssical_cache.rssical_phyregs_2G[6] = + read_phy_reg(pi, 0x1b0); + pi->rssical_cache.rssical_phyregs_2G[7] = + read_phy_reg(pi, 0x1b6); + pi->rssical_cache.rssical_phyregs_2G[8] = + read_phy_reg(pi, 0x1a5); + pi->rssical_cache.rssical_phyregs_2G[9] = + read_phy_reg(pi, 0x1ab); + pi->rssical_cache.rssical_phyregs_2G[10] = + read_phy_reg(pi, 0x1b1); + pi->rssical_cache.rssical_phyregs_2G[11] = + read_phy_reg(pi, 0x1b7); + + pi->nphy_rssical_chanspec_2G = pi->radio_chanspec; + } else { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + pi->rssical_cache.rssical_radio_regs_5G[0] = + read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0); + pi->rssical_cache.rssical_radio_regs_5G[1] = + read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1); + } else { + pi->rssical_cache.rssical_radio_regs_5G[0] = + read_radio_reg(pi, + RADIO_2056_RX_RSSI_MISC | + RADIO_2056_RX0); + pi->rssical_cache.rssical_radio_regs_5G[1] = + read_radio_reg(pi, + RADIO_2056_RX_RSSI_MISC | + RADIO_2056_RX1); + } + + pi->rssical_cache.rssical_phyregs_5G[0] = + read_phy_reg(pi, 0x1a6); + pi->rssical_cache.rssical_phyregs_5G[1] = + read_phy_reg(pi, 0x1ac); + pi->rssical_cache.rssical_phyregs_5G[2] = + read_phy_reg(pi, 0x1b2); + pi->rssical_cache.rssical_phyregs_5G[3] = + read_phy_reg(pi, 0x1b8); + pi->rssical_cache.rssical_phyregs_5G[4] = + read_phy_reg(pi, 0x1a4); + pi->rssical_cache.rssical_phyregs_5G[5] = + read_phy_reg(pi, 0x1aa); + pi->rssical_cache.rssical_phyregs_5G[6] = + read_phy_reg(pi, 0x1b0); + pi->rssical_cache.rssical_phyregs_5G[7] = + read_phy_reg(pi, 0x1b6); + pi->rssical_cache.rssical_phyregs_5G[8] = + read_phy_reg(pi, 0x1a5); + pi->rssical_cache.rssical_phyregs_5G[9] = + read_phy_reg(pi, 0x1ab); + pi->rssical_cache.rssical_phyregs_5G[10] = + read_phy_reg(pi, 0x1b1); + pi->rssical_cache.rssical_phyregs_5G[11] = + read_phy_reg(pi, 0x1b7); + + pi->nphy_rssical_chanspec_5G = pi->radio_chanspec; + } + + wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state); + wlc_phy_clip_det_nphy(pi, 1, clip_state); +} + +static void wlc_phy_restore_rssical_nphy(phy_info_t *pi) +{ + ASSERT(NREV_GE(pi->pubpi.phy_rev, 3)); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (pi->nphy_rssical_chanspec_2G == 0) + return; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0, + RADIO_2057_VCM_MASK, + pi->rssical_cache. + rssical_radio_regs_2G[0]); + mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1, + RADIO_2057_VCM_MASK, + pi->rssical_cache. + rssical_radio_regs_2G[1]); + } else { + mod_radio_reg(pi, + RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0, + RADIO_2056_VCM_MASK, + pi->rssical_cache. + rssical_radio_regs_2G[0]); + mod_radio_reg(pi, + RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1, + RADIO_2056_VCM_MASK, + pi->rssical_cache. + rssical_radio_regs_2G[1]); + } + + write_phy_reg(pi, 0x1a6, + pi->rssical_cache.rssical_phyregs_2G[0]); + write_phy_reg(pi, 0x1ac, + pi->rssical_cache.rssical_phyregs_2G[1]); + write_phy_reg(pi, 0x1b2, + pi->rssical_cache.rssical_phyregs_2G[2]); + write_phy_reg(pi, 0x1b8, + pi->rssical_cache.rssical_phyregs_2G[3]); + write_phy_reg(pi, 0x1a4, + pi->rssical_cache.rssical_phyregs_2G[4]); + write_phy_reg(pi, 0x1aa, + pi->rssical_cache.rssical_phyregs_2G[5]); + write_phy_reg(pi, 0x1b0, + pi->rssical_cache.rssical_phyregs_2G[6]); + write_phy_reg(pi, 0x1b6, + pi->rssical_cache.rssical_phyregs_2G[7]); + write_phy_reg(pi, 0x1a5, + pi->rssical_cache.rssical_phyregs_2G[8]); + write_phy_reg(pi, 0x1ab, + pi->rssical_cache.rssical_phyregs_2G[9]); + write_phy_reg(pi, 0x1b1, + pi->rssical_cache.rssical_phyregs_2G[10]); + write_phy_reg(pi, 0x1b7, + pi->rssical_cache.rssical_phyregs_2G[11]); + + } else { + if (pi->nphy_rssical_chanspec_5G == 0) + return; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0, + RADIO_2057_VCM_MASK, + pi->rssical_cache. + rssical_radio_regs_5G[0]); + mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1, + RADIO_2057_VCM_MASK, + pi->rssical_cache. + rssical_radio_regs_5G[1]); + } else { + mod_radio_reg(pi, + RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0, + RADIO_2056_VCM_MASK, + pi->rssical_cache. + rssical_radio_regs_5G[0]); + mod_radio_reg(pi, + RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1, + RADIO_2056_VCM_MASK, + pi->rssical_cache. + rssical_radio_regs_5G[1]); + } + + write_phy_reg(pi, 0x1a6, + pi->rssical_cache.rssical_phyregs_5G[0]); + write_phy_reg(pi, 0x1ac, + pi->rssical_cache.rssical_phyregs_5G[1]); + write_phy_reg(pi, 0x1b2, + pi->rssical_cache.rssical_phyregs_5G[2]); + write_phy_reg(pi, 0x1b8, + pi->rssical_cache.rssical_phyregs_5G[3]); + write_phy_reg(pi, 0x1a4, + pi->rssical_cache.rssical_phyregs_5G[4]); + write_phy_reg(pi, 0x1aa, + pi->rssical_cache.rssical_phyregs_5G[5]); + write_phy_reg(pi, 0x1b0, + pi->rssical_cache.rssical_phyregs_5G[6]); + write_phy_reg(pi, 0x1b6, + pi->rssical_cache.rssical_phyregs_5G[7]); + write_phy_reg(pi, 0x1a5, + pi->rssical_cache.rssical_phyregs_5G[8]); + write_phy_reg(pi, 0x1ab, + pi->rssical_cache.rssical_phyregs_5G[9]); + write_phy_reg(pi, 0x1b1, + pi->rssical_cache.rssical_phyregs_5G[10]); + write_phy_reg(pi, 0x1b7, + pi->rssical_cache.rssical_phyregs_5G[11]); + } +} + +static u16 +wlc_phy_gen_load_samples_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val, + u8 dac_test_mode) +{ + u8 phy_bw, is_phybw40; + u16 num_samps, t, spur; + fixed theta = 0, rot = 0; + u32 tbl_len; + cs32 *tone_buf = NULL; + + is_phybw40 = CHSPEC_IS40(pi->radio_chanspec); + phy_bw = (is_phybw40 == 1) ? 40 : 20; + tbl_len = (phy_bw << 3); + + if (dac_test_mode == 1) { + spur = read_phy_reg(pi, 0x01); + spur = (spur >> 15) & 1; + phy_bw = (spur == 1) ? 82 : 80; + phy_bw = (is_phybw40 == 1) ? (phy_bw << 1) : phy_bw; + + tbl_len = (phy_bw << 1); + } + + tone_buf = kmalloc(sizeof(cs32) * tbl_len, GFP_ATOMIC); + if (tone_buf == NULL) { + return 0; + } + + num_samps = (u16) tbl_len; + rot = FIXED((f_kHz * 36) / phy_bw) / 100; + theta = 0; + + for (t = 0; t < num_samps; t++) { + + wlc_phy_cordic(theta, &tone_buf[t]); + + theta += rot; + + tone_buf[t].q = (s32) FLOAT(tone_buf[t].q * max_val); + tone_buf[t].i = (s32) FLOAT(tone_buf[t].i * max_val); + } + + wlc_phy_loadsampletable_nphy(pi, tone_buf, num_samps); + + if (tone_buf != NULL) + kfree(tone_buf); + + return num_samps; +} + +int +wlc_phy_tx_tone_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val, + u8 iqmode, u8 dac_test_mode, bool modify_bbmult) +{ + u16 num_samps; + u16 loops = 0xffff; + u16 wait = 0; + + num_samps = + wlc_phy_gen_load_samples_nphy(pi, f_kHz, max_val, dac_test_mode); + if (num_samps == 0) { + return BCME_ERROR; + } + + wlc_phy_runsamples_nphy(pi, num_samps, loops, wait, iqmode, + dac_test_mode, modify_bbmult); + + return BCME_OK; +} + +static void +wlc_phy_loadsampletable_nphy(phy_info_t *pi, cs32 *tone_buf, + u16 num_samps) +{ + u16 t; + u32 *data_buf = NULL; + + data_buf = kmalloc(sizeof(u32) * num_samps, GFP_ATOMIC); + if (data_buf == NULL) { + return; + } + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + for (t = 0; t < num_samps; t++) { + data_buf[t] = ((((unsigned int)tone_buf[t].i) & 0x3ff) << 10) | + (((unsigned int)tone_buf[t].q) & 0x3ff); + } + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SAMPLEPLAY, num_samps, 0, 32, + data_buf); + + if (data_buf != NULL) + kfree(data_buf); + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); +} + +static void +wlc_phy_runsamples_nphy(phy_info_t *pi, u16 num_samps, u16 loops, + u16 wait, u8 iqmode, u8 dac_test_mode, + bool modify_bbmult) +{ + u16 bb_mult; + u8 phy_bw, sample_cmd; + u16 orig_RfseqCoreActv; + u16 lpf_bw_ctl_override3, lpf_bw_ctl_override4, lpf_bw_ctl_miscreg3, + lpf_bw_ctl_miscreg4; + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + phy_bw = 20; + if (CHSPEC_IS40(pi->radio_chanspec)) + phy_bw = 40; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + lpf_bw_ctl_override3 = read_phy_reg(pi, 0x342) & (0x1 << 7); + lpf_bw_ctl_override4 = read_phy_reg(pi, 0x343) & (0x1 << 7); + if (lpf_bw_ctl_override3 | lpf_bw_ctl_override4) { + lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) & + (0x7 << 8); + lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) & + (0x7 << 8); + } else { + wlc_phy_rfctrl_override_nphy_rev7(pi, + (0x1 << 7), + wlc_phy_read_lpf_bw_ctl_nphy + (pi, 0), 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + + pi->nphy_sample_play_lpf_bw_ctl_ovr = true; + + lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) & + (0x7 << 8); + lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) & + (0x7 << 8); + } + } + + if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) == 0) { + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16, + &bb_mult); + pi->nphy_bb_mult_save = + BB_MULT_VALID_MASK | (bb_mult & BB_MULT_MASK); + } + + if (modify_bbmult) { + bb_mult = (phy_bw == 20) ? 100 : 71; + bb_mult = (bb_mult << 8) + bb_mult; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16, + &bb_mult); + } + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); + + write_phy_reg(pi, 0xc6, num_samps - 1); + + if (loops != 0xffff) { + write_phy_reg(pi, 0xc4, loops - 1); + } else { + write_phy_reg(pi, 0xc4, loops); + } + write_phy_reg(pi, 0xc5, wait); + + orig_RfseqCoreActv = read_phy_reg(pi, 0xa1); + or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override); + if (iqmode) { + + and_phy_reg(pi, 0xc2, 0x7FFF); + + or_phy_reg(pi, 0xc2, 0x8000); + } else { + + sample_cmd = (dac_test_mode == 1) ? 0x5 : 0x1; + write_phy_reg(pi, 0xc3, sample_cmd); + } + + SPINWAIT(((read_phy_reg(pi, 0xa4) & 0x1) == 1), 1000); + + write_phy_reg(pi, 0xa1, orig_RfseqCoreActv); +} + +void wlc_phy_stopplayback_nphy(phy_info_t *pi) +{ + u16 playback_status; + u16 bb_mult; + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + playback_status = read_phy_reg(pi, 0xc7); + if (playback_status & 0x1) { + or_phy_reg(pi, 0xc3, NPHY_sampleCmd_STOP); + } else if (playback_status & 0x2) { + + and_phy_reg(pi, 0xc2, + (u16) ~NPHY_iqloCalCmdGctl_IQLO_CAL_EN); + } + + and_phy_reg(pi, 0xc3, (u16) ~(0x1 << 2)); + + if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) != 0) { + + bb_mult = pi->nphy_bb_mult_save & BB_MULT_MASK; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16, + &bb_mult); + + pi->nphy_bb_mult_save = 0; + } + + if (NREV_IS(pi->pubpi.phy_rev, 7) || NREV_GE(pi->pubpi.phy_rev, 8)) { + if (pi->nphy_sample_play_lpf_bw_ctl_ovr) { + wlc_phy_rfctrl_override_nphy_rev7(pi, + (0x1 << 7), + 0, 0, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + pi->nphy_sample_play_lpf_bw_ctl_ovr = false; + } + } + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); +} + +nphy_txgains_t wlc_phy_get_tx_gain_nphy(phy_info_t *pi) +{ + u16 base_idx[2], curr_gain[2]; + u8 core_no; + nphy_txgains_t target_gain; + u32 *tx_pwrctrl_tbl = NULL; + + if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) { + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, + curr_gain); + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); + + for (core_no = 0; core_no < 2; core_no++) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + target_gain.ipa[core_no] = + curr_gain[core_no] & 0x0007; + target_gain.pad[core_no] = + ((curr_gain[core_no] & 0x00F8) >> 3); + target_gain.pga[core_no] = + ((curr_gain[core_no] & 0x0F00) >> 8); + target_gain.txgm[core_no] = + ((curr_gain[core_no] & 0x7000) >> 12); + target_gain.txlpf[core_no] = + ((curr_gain[core_no] & 0x8000) >> 15); + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + target_gain.ipa[core_no] = + curr_gain[core_no] & 0x000F; + target_gain.pad[core_no] = + ((curr_gain[core_no] & 0x00F0) >> 4); + target_gain.pga[core_no] = + ((curr_gain[core_no] & 0x0F00) >> 8); + target_gain.txgm[core_no] = + ((curr_gain[core_no] & 0x7000) >> 12); + } else { + target_gain.ipa[core_no] = + curr_gain[core_no] & 0x0003; + target_gain.pad[core_no] = + ((curr_gain[core_no] & 0x000C) >> 2); + target_gain.pga[core_no] = + ((curr_gain[core_no] & 0x0070) >> 4); + target_gain.txgm[core_no] = + ((curr_gain[core_no] & 0x0380) >> 7); + } + } + } else { + base_idx[0] = (read_phy_reg(pi, 0x1ed) >> 8) & 0x7f; + base_idx[1] = (read_phy_reg(pi, 0x1ee) >> 8) & 0x7f; + for (core_no = 0; core_no < 2; core_no++) { + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (PHY_IPA(pi)) { + tx_pwrctrl_tbl = + wlc_phy_get_ipa_gaintbl_nphy(pi); + } else { + if (CHSPEC_IS5G(pi->radio_chanspec)) { + if NREV_IS + (pi->pubpi.phy_rev, 3) { + tx_pwrctrl_tbl = + nphy_tpc_5GHz_txgain_rev3; + } else if NREV_IS + (pi->pubpi.phy_rev, 4) { + tx_pwrctrl_tbl = + (pi->srom_fem5g. + extpagain == + 3) ? + nphy_tpc_5GHz_txgain_HiPwrEPA + : + nphy_tpc_5GHz_txgain_rev4; + } else { + tx_pwrctrl_tbl = + nphy_tpc_5GHz_txgain_rev5; + } + } else { + if (NREV_GE + (pi->pubpi.phy_rev, 7)) { + if (pi->pubpi. + radiorev == 3) { + tx_pwrctrl_tbl = + nphy_tpc_txgain_epa_2057rev3; + } else if (pi->pubpi. + radiorev == + 5) { + tx_pwrctrl_tbl = + nphy_tpc_txgain_epa_2057rev5; + } + + } else { + if (NREV_GE + (pi->pubpi.phy_rev, + 5) + && (pi->srom_fem2g. + extpagain == + 3)) { + tx_pwrctrl_tbl = + nphy_tpc_txgain_HiPwrEPA; + } else { + tx_pwrctrl_tbl = + nphy_tpc_txgain_rev3; + } + } + } + } + if NREV_GE + (pi->pubpi.phy_rev, 7) { + target_gain.ipa[core_no] = + (tx_pwrctrl_tbl[base_idx[core_no]] + >> 16) & 0x7; + target_gain.pad[core_no] = + (tx_pwrctrl_tbl[base_idx[core_no]] + >> 19) & 0x1f; + target_gain.pga[core_no] = + (tx_pwrctrl_tbl[base_idx[core_no]] + >> 24) & 0xf; + target_gain.txgm[core_no] = + (tx_pwrctrl_tbl[base_idx[core_no]] + >> 28) & 0x7; + target_gain.txlpf[core_no] = + (tx_pwrctrl_tbl[base_idx[core_no]] + >> 31) & 0x1; + } else { + target_gain.ipa[core_no] = + (tx_pwrctrl_tbl[base_idx[core_no]] + >> 16) & 0xf; + target_gain.pad[core_no] = + (tx_pwrctrl_tbl[base_idx[core_no]] + >> 20) & 0xf; + target_gain.pga[core_no] = + (tx_pwrctrl_tbl[base_idx[core_no]] + >> 24) & 0xf; + target_gain.txgm[core_no] = + (tx_pwrctrl_tbl[base_idx[core_no]] + >> 28) & 0x7; + } + } else { + target_gain.ipa[core_no] = + (nphy_tpc_txgain[base_idx[core_no]] >> 16) & + 0x3; + target_gain.pad[core_no] = + (nphy_tpc_txgain[base_idx[core_no]] >> 18) & + 0x3; + target_gain.pga[core_no] = + (nphy_tpc_txgain[base_idx[core_no]] >> 20) & + 0x7; + target_gain.txgm[core_no] = + (nphy_tpc_txgain[base_idx[core_no]] >> 23) & + 0x7; + } + } + } + + return target_gain; +} + +static void +wlc_phy_iqcal_gainparams_nphy(phy_info_t *pi, u16 core_no, + nphy_txgains_t target_gain, + nphy_iqcal_params_t *params) +{ + u8 k; + int idx; + u16 gain_index; + u8 band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + params->txlpf = target_gain.txlpf[core_no]; + } + params->txgm = target_gain.txgm[core_no]; + params->pga = target_gain.pga[core_no]; + params->pad = target_gain.pad[core_no]; + params->ipa = target_gain.ipa[core_no]; + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + params->cal_gain = + ((params->txlpf << 15) | (params-> + txgm << 12) | (params-> + pga << 8) | + (params->pad << 3) | (params->ipa)); + } else { + params->cal_gain = + ((params->txgm << 12) | (params-> + pga << 8) | (params-> + pad << 4) | + (params->ipa)); + } + params->ncorr[0] = 0x79; + params->ncorr[1] = 0x79; + params->ncorr[2] = 0x79; + params->ncorr[3] = 0x79; + params->ncorr[4] = 0x79; + } else { + + gain_index = ((target_gain.pad[core_no] << 0) | + (target_gain.pga[core_no] << 4) | (target_gain. + txgm[core_no] + << 8)); + + idx = -1; + for (k = 0; k < NPHY_IQCAL_NUMGAINS; k++) { + if (tbl_iqcal_gainparams_nphy[band_idx][k][0] == + gain_index) { + idx = k; + break; + } + } + + ASSERT(idx != -1); + + params->txgm = tbl_iqcal_gainparams_nphy[band_idx][k][1]; + params->pga = tbl_iqcal_gainparams_nphy[band_idx][k][2]; + params->pad = tbl_iqcal_gainparams_nphy[band_idx][k][3]; + params->cal_gain = ((params->txgm << 7) | (params->pga << 4) | + (params->pad << 2)); + params->ncorr[0] = tbl_iqcal_gainparams_nphy[band_idx][k][4]; + params->ncorr[1] = tbl_iqcal_gainparams_nphy[band_idx][k][5]; + params->ncorr[2] = tbl_iqcal_gainparams_nphy[band_idx][k][6]; + params->ncorr[3] = tbl_iqcal_gainparams_nphy[band_idx][k][7]; + } +} + +static void wlc_phy_txcal_radio_setup_nphy(phy_info_t *pi) +{ + u16 jtag_core, core; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + for (core = 0; core <= 1; core++) { + + pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] = + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + TX_SSI_MASTER); + + pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] = + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + IQCAL_VCM_HG); + + pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] = + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + IQCAL_IDAC); + + pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] = + READ_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM); + + pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] = 0; + + pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] = + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + TX_SSI_MUX); + + if (pi->pubpi.radiorev != 5) + pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] = + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + TSSIA); + + pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] = + READ_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG); + + pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] = + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + TSSI_MISC1); + + if (CHSPEC_IS5G(pi->radio_chanspec)) { + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TX_SSI_MASTER, 0x0a); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + IQCAL_VCM_HG, 0x43); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + IQCAL_IDAC, 0x55); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TSSI_VCM, 0x00); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TSSIG, 0x00); + if (pi->use_int_tx_iqlo_cal_nphy) { + WRITE_RADIO_REG3(pi, RADIO_2057, TX, + core, TX_SSI_MUX, 0x4); + if (! + (pi-> + internal_tx_iqlo_cal_tapoff_intpa_nphy)) { + + WRITE_RADIO_REG3(pi, RADIO_2057, + TX, core, + TSSIA, 0x31); + } else { + + WRITE_RADIO_REG3(pi, RADIO_2057, + TX, core, + TSSIA, 0x21); + } + } + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TSSI_MISC1, 0x00); + } else { + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TX_SSI_MASTER, 0x06); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + IQCAL_VCM_HG, 0x43); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + IQCAL_IDAC, 0x55); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TSSI_VCM, 0x00); + + if (pi->pubpi.radiorev != 5) + WRITE_RADIO_REG3(pi, RADIO_2057, TX, + core, TSSIA, 0x00); + if (pi->use_int_tx_iqlo_cal_nphy) { + WRITE_RADIO_REG3(pi, RADIO_2057, TX, + core, TX_SSI_MUX, + 0x06); + if (! + (pi-> + internal_tx_iqlo_cal_tapoff_intpa_nphy)) { + + WRITE_RADIO_REG3(pi, RADIO_2057, + TX, core, + TSSIG, 0x31); + } else { + + WRITE_RADIO_REG3(pi, RADIO_2057, + TX, core, + TSSIG, 0x21); + } + } + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TSSI_MISC1, 0x00); + } + } + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + + for (core = 0; core <= 1; core++) { + jtag_core = + (core == + PHY_CORE_0) ? RADIO_2056_TX0 : RADIO_2056_TX1; + + pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] = + read_radio_reg(pi, + RADIO_2056_TX_TX_SSI_MASTER | + jtag_core); + + pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] = + read_radio_reg(pi, + RADIO_2056_TX_IQCAL_VCM_HG | + jtag_core); + + pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] = + read_radio_reg(pi, + RADIO_2056_TX_IQCAL_IDAC | + jtag_core); + + pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] = + read_radio_reg(pi, + RADIO_2056_TX_TSSI_VCM | jtag_core); + + pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] = + read_radio_reg(pi, + RADIO_2056_TX_TX_AMP_DET | + jtag_core); + + pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] = + read_radio_reg(pi, + RADIO_2056_TX_TX_SSI_MUX | + jtag_core); + + pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] = + read_radio_reg(pi, RADIO_2056_TX_TSSIA | jtag_core); + + pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] = + read_radio_reg(pi, RADIO_2056_TX_TSSIG | jtag_core); + + pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] = + read_radio_reg(pi, + RADIO_2056_TX_TSSI_MISC1 | + jtag_core); + + pi->tx_rx_cal_radio_saveregs[(core * 11) + 9] = + read_radio_reg(pi, + RADIO_2056_TX_TSSI_MISC2 | + jtag_core); + + pi->tx_rx_cal_radio_saveregs[(core * 11) + 10] = + read_radio_reg(pi, + RADIO_2056_TX_TSSI_MISC3 | + jtag_core); + + if (CHSPEC_IS5G(pi->radio_chanspec)) { + write_radio_reg(pi, + RADIO_2056_TX_TX_SSI_MASTER | + jtag_core, 0x0a); + write_radio_reg(pi, + RADIO_2056_TX_IQCAL_VCM_HG | + jtag_core, 0x40); + write_radio_reg(pi, + RADIO_2056_TX_IQCAL_IDAC | + jtag_core, 0x55); + write_radio_reg(pi, + RADIO_2056_TX_TSSI_VCM | + jtag_core, 0x00); + write_radio_reg(pi, + RADIO_2056_TX_TX_AMP_DET | + jtag_core, 0x00); + + if (PHY_IPA(pi)) { + write_radio_reg(pi, + RADIO_2056_TX_TX_SSI_MUX + | jtag_core, 0x4); + write_radio_reg(pi, + RADIO_2056_TX_TSSIA | + jtag_core, 0x1); + } else { + write_radio_reg(pi, + RADIO_2056_TX_TX_SSI_MUX + | jtag_core, 0x00); + write_radio_reg(pi, + RADIO_2056_TX_TSSIA | + jtag_core, 0x2f); + } + write_radio_reg(pi, + RADIO_2056_TX_TSSIG | jtag_core, + 0x00); + write_radio_reg(pi, + RADIO_2056_TX_TSSI_MISC1 | + jtag_core, 0x00); + + write_radio_reg(pi, + RADIO_2056_TX_TSSI_MISC2 | + jtag_core, 0x00); + write_radio_reg(pi, + RADIO_2056_TX_TSSI_MISC3 | + jtag_core, 0x00); + } else { + write_radio_reg(pi, + RADIO_2056_TX_TX_SSI_MASTER | + jtag_core, 0x06); + write_radio_reg(pi, + RADIO_2056_TX_IQCAL_VCM_HG | + jtag_core, 0x40); + write_radio_reg(pi, + RADIO_2056_TX_IQCAL_IDAC | + jtag_core, 0x55); + write_radio_reg(pi, + RADIO_2056_TX_TSSI_VCM | + jtag_core, 0x00); + write_radio_reg(pi, + RADIO_2056_TX_TX_AMP_DET | + jtag_core, 0x00); + write_radio_reg(pi, + RADIO_2056_TX_TSSIA | jtag_core, + 0x00); + + if (PHY_IPA(pi)) { + + write_radio_reg(pi, + RADIO_2056_TX_TX_SSI_MUX + | jtag_core, 0x06); + if (NREV_LT(pi->pubpi.phy_rev, 5)) { + + write_radio_reg(pi, + RADIO_2056_TX_TSSIG + | jtag_core, + 0x11); + } else { + + write_radio_reg(pi, + RADIO_2056_TX_TSSIG + | jtag_core, + 0x1); + } + } else { + write_radio_reg(pi, + RADIO_2056_TX_TX_SSI_MUX + | jtag_core, 0x00); + write_radio_reg(pi, + RADIO_2056_TX_TSSIG | + jtag_core, 0x20); + } + + write_radio_reg(pi, + RADIO_2056_TX_TSSI_MISC1 | + jtag_core, 0x00); + write_radio_reg(pi, + RADIO_2056_TX_TSSI_MISC2 | + jtag_core, 0x00); + write_radio_reg(pi, + RADIO_2056_TX_TSSI_MISC3 | + jtag_core, 0x00); + } + } + } else { + + pi->tx_rx_cal_radio_saveregs[0] = + read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1); + write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x29); + pi->tx_rx_cal_radio_saveregs[1] = + read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2); + write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x54); + + pi->tx_rx_cal_radio_saveregs[2] = + read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1); + write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x29); + pi->tx_rx_cal_radio_saveregs[3] = + read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2); + write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x54); + + pi->tx_rx_cal_radio_saveregs[4] = + read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1); + pi->tx_rx_cal_radio_saveregs[5] = + read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2); + + if ((read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand) == + 0) { + + write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04); + write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04); + } else { + + write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x20); + write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x20); + } + + if (NREV_LT(pi->pubpi.phy_rev, 2)) { + + or_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0x20); + or_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0x20); + } else { + + and_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0xdf); + and_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0xdf); + } + } +} + +static void wlc_phy_txcal_radio_cleanup_nphy(phy_info_t *pi) +{ + u16 jtag_core, core; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + for (core = 0; core <= 1; core++) { + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TX_SSI_MASTER, + pi-> + tx_rx_cal_radio_saveregs[(core * 11) + + 0]); + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG, + pi-> + tx_rx_cal_radio_saveregs[(core * 11) + + 1]); + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC, + pi-> + tx_rx_cal_radio_saveregs[(core * 11) + + 2]); + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM, + pi-> + tx_rx_cal_radio_saveregs[(core * 11) + + 3]); + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TX_SSI_MUX, + pi-> + tx_rx_cal_radio_saveregs[(core * 11) + + 5]); + + if (pi->pubpi.radiorev != 5) + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TSSIA, + pi-> + tx_rx_cal_radio_saveregs[(core + * + 11) + + 6]); + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG, + pi-> + tx_rx_cal_radio_saveregs[(core * 11) + + 7]); + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1, + pi-> + tx_rx_cal_radio_saveregs[(core * 11) + + 8]); + } + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + for (core = 0; core <= 1; core++) { + jtag_core = + (core == + PHY_CORE_0) ? RADIO_2056_TX0 : RADIO_2056_TX1; + + write_radio_reg(pi, + RADIO_2056_TX_TX_SSI_MASTER | jtag_core, + pi-> + tx_rx_cal_radio_saveregs[(core * 11) + + 0]); + + write_radio_reg(pi, + RADIO_2056_TX_IQCAL_VCM_HG | jtag_core, + pi-> + tx_rx_cal_radio_saveregs[(core * 11) + + 1]); + + write_radio_reg(pi, + RADIO_2056_TX_IQCAL_IDAC | jtag_core, + pi-> + tx_rx_cal_radio_saveregs[(core * 11) + + 2]); + + write_radio_reg(pi, RADIO_2056_TX_TSSI_VCM | jtag_core, + pi-> + tx_rx_cal_radio_saveregs[(core * 11) + + 3]); + + write_radio_reg(pi, + RADIO_2056_TX_TX_AMP_DET | jtag_core, + pi-> + tx_rx_cal_radio_saveregs[(core * 11) + + 4]); + + write_radio_reg(pi, + RADIO_2056_TX_TX_SSI_MUX | jtag_core, + pi-> + tx_rx_cal_radio_saveregs[(core * 11) + + 5]); + + write_radio_reg(pi, RADIO_2056_TX_TSSIA | jtag_core, + pi-> + tx_rx_cal_radio_saveregs[(core * 11) + + 6]); + + write_radio_reg(pi, RADIO_2056_TX_TSSIG | jtag_core, + pi-> + tx_rx_cal_radio_saveregs[(core * 11) + + 7]); + + write_radio_reg(pi, + RADIO_2056_TX_TSSI_MISC1 | jtag_core, + pi-> + tx_rx_cal_radio_saveregs[(core * 11) + + 8]); + + write_radio_reg(pi, + RADIO_2056_TX_TSSI_MISC2 | jtag_core, + pi-> + tx_rx_cal_radio_saveregs[(core * 11) + + 9]); + + write_radio_reg(pi, + RADIO_2056_TX_TSSI_MISC3 | jtag_core, + pi-> + tx_rx_cal_radio_saveregs[(core * 11) + + 10]); + } + } else { + + write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, + pi->tx_rx_cal_radio_saveregs[0]); + write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, + pi->tx_rx_cal_radio_saveregs[1]); + write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, + pi->tx_rx_cal_radio_saveregs[2]); + write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, + pi->tx_rx_cal_radio_saveregs[3]); + write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, + pi->tx_rx_cal_radio_saveregs[4]); + write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, + pi->tx_rx_cal_radio_saveregs[5]); + } +} + +static void wlc_phy_txcal_physetup_nphy(phy_info_t *pi) +{ + u16 val, mask; + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6); + pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7); + + mask = ((0x3 << 8) | (0x3 << 10)); + val = (0x2 << 8); + val |= (0x2 << 10); + mod_phy_reg(pi, 0xa6, mask, val); + mod_phy_reg(pi, 0xa7, mask, val); + + val = read_phy_reg(pi, 0x8f); + pi->tx_rx_cal_phy_saveregs[2] = val; + val |= ((0x1 << 9) | (0x1 << 10)); + write_phy_reg(pi, 0x8f, val); + + val = read_phy_reg(pi, 0xa5); + pi->tx_rx_cal_phy_saveregs[3] = val; + val |= ((0x1 << 9) | (0x1 << 10)); + write_phy_reg(pi, 0xa5, val); + + pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x01); + mod_phy_reg(pi, 0x01, (0x1 << 15), 0); + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16, + &val); + pi->tx_rx_cal_phy_saveregs[5] = val; + val = 0; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16, + &val); + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16, + &val); + pi->tx_rx_cal_phy_saveregs[6] = val; + val = 0; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16, + &val); + + pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0x91); + pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0x92); + + if (!(pi->use_int_tx_iqlo_cal_nphy)) { + + wlc_phy_rfctrlintc_override_nphy(pi, + NPHY_RfctrlIntc_override_PA, + 1, + RADIO_MIMO_CORESEL_CORE1 + | + RADIO_MIMO_CORESEL_CORE2); + } else { + + wlc_phy_rfctrlintc_override_nphy(pi, + NPHY_RfctrlIntc_override_PA, + 0, + RADIO_MIMO_CORESEL_CORE1 + | + RADIO_MIMO_CORESEL_CORE2); + } + + wlc_phy_rfctrlintc_override_nphy(pi, + NPHY_RfctrlIntc_override_TRSW, + 0x2, RADIO_MIMO_CORESEL_CORE1); + wlc_phy_rfctrlintc_override_nphy(pi, + NPHY_RfctrlIntc_override_TRSW, + 0x8, RADIO_MIMO_CORESEL_CORE2); + + pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297); + pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b); + mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (0) << 0); + + mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (0) << 0); + + if (NREV_IS(pi->pubpi.phy_rev, 7) + || NREV_GE(pi->pubpi.phy_rev, 8)) { + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), + wlc_phy_read_lpf_bw_ctl_nphy + (pi, 0), 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + } + + if (pi->use_int_tx_iqlo_cal_nphy + && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) { + + if (NREV_IS(pi->pubpi.phy_rev, 7)) { + + mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4, + 1 << 4); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + mod_radio_reg(pi, + RADIO_2057_PAD2G_TUNE_PUS_CORE0, + 1, 0); + mod_radio_reg(pi, + RADIO_2057_PAD2G_TUNE_PUS_CORE1, + 1, 0); + } else { + mod_radio_reg(pi, + RADIO_2057_IPA5G_CASCOFFV_PU_CORE0, + 1, 0); + mod_radio_reg(pi, + RADIO_2057_IPA5G_CASCOFFV_PU_CORE1, + 1, 0); + } + } else if (NREV_GE(pi->pubpi.phy_rev, 8)) { + wlc_phy_rfctrl_override_nphy_rev7(pi, + (0x1 << 3), 0, + 0x3, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + } + } + } else { + pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6); + pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7); + + mask = ((0x3 << 12) | (0x3 << 14)); + val = (0x2 << 12); + val |= (0x2 << 14); + mod_phy_reg(pi, 0xa6, mask, val); + mod_phy_reg(pi, 0xa7, mask, val); + + val = read_phy_reg(pi, 0xa5); + pi->tx_rx_cal_phy_saveregs[2] = val; + val |= ((0x1 << 12) | (0x1 << 13)); + write_phy_reg(pi, 0xa5, val); + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16, + &val); + pi->tx_rx_cal_phy_saveregs[3] = val; + val |= 0x2000; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16, + &val); + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16, + &val); + pi->tx_rx_cal_phy_saveregs[4] = val; + val |= 0x2000; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16, + &val); + + pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x91); + pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x92); + val = CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120; + write_phy_reg(pi, 0x91, val); + write_phy_reg(pi, 0x92, val); + } +} + +static void wlc_phy_txcal_phycleanup_nphy(phy_info_t *pi) +{ + u16 mask; + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + write_phy_reg(pi, 0xa6, pi->tx_rx_cal_phy_saveregs[0]); + write_phy_reg(pi, 0xa7, pi->tx_rx_cal_phy_saveregs[1]); + write_phy_reg(pi, 0x8f, pi->tx_rx_cal_phy_saveregs[2]); + write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[3]); + write_phy_reg(pi, 0x01, pi->tx_rx_cal_phy_saveregs[4]); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16, + &pi->tx_rx_cal_phy_saveregs[5]); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16, + &pi->tx_rx_cal_phy_saveregs[6]); + + write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[7]); + write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[8]); + + write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]); + write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]); + + if (NREV_IS(pi->pubpi.phy_rev, 7) + || NREV_GE(pi->pubpi.phy_rev, 8)) { + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), 0, 0, + 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + } + + wlc_phy_resetcca_nphy(pi); + + if (pi->use_int_tx_iqlo_cal_nphy + && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) { + + if (NREV_IS(pi->pubpi.phy_rev, 7)) { + if (CHSPEC_IS2G(pi->radio_chanspec)) { + mod_radio_reg(pi, + RADIO_2057_PAD2G_TUNE_PUS_CORE0, + 1, 1); + mod_radio_reg(pi, + RADIO_2057_PAD2G_TUNE_PUS_CORE1, + 1, 1); + } else { + mod_radio_reg(pi, + RADIO_2057_IPA5G_CASCOFFV_PU_CORE0, + 1, 1); + mod_radio_reg(pi, + RADIO_2057_IPA5G_CASCOFFV_PU_CORE1, + 1, 1); + } + + mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4, + 0); + } else if (NREV_GE(pi->pubpi.phy_rev, 8)) { + wlc_phy_rfctrl_override_nphy_rev7(pi, + (0x1 << 3), 0, + 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + } + } + } else { + mask = ((0x3 << 12) | (0x3 << 14)); + mod_phy_reg(pi, 0xa6, mask, pi->tx_rx_cal_phy_saveregs[0]); + mod_phy_reg(pi, 0xa7, mask, pi->tx_rx_cal_phy_saveregs[1]); + write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[2]); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16, + &pi->tx_rx_cal_phy_saveregs[3]); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16, + &pi->tx_rx_cal_phy_saveregs[4]); + + write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[5]); + write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[6]); + } +} + +#define NPHY_CAL_TSSISAMPS 64 +#define NPHY_TEST_TONE_FREQ_40MHz 4000 +#define NPHY_TEST_TONE_FREQ_20MHz 2500 + +void +wlc_phy_est_tonepwr_nphy(phy_info_t *pi, s32 *qdBm_pwrbuf, u8 num_samps) +{ + u16 tssi_reg; + s32 temp, pwrindex[2]; + s32 idle_tssi[2]; + s32 rssi_buf[4]; + s32 tssival[2]; + u8 tssi_type; + + tssi_reg = read_phy_reg(pi, 0x1e9); + + temp = (s32) (tssi_reg & 0x3f); + idle_tssi[0] = (temp <= 31) ? temp : (temp - 64); + + temp = (s32) ((tssi_reg >> 8) & 0x3f); + idle_tssi[1] = (temp <= 31) ? temp : (temp - 64); + + tssi_type = + CHSPEC_IS5G(pi->radio_chanspec) ? + (u8)NPHY_RSSI_SEL_TSSI_5G:(u8)NPHY_RSSI_SEL_TSSI_2G; + + wlc_phy_poll_rssi_nphy(pi, tssi_type, rssi_buf, num_samps); + + tssival[0] = rssi_buf[0] / ((s32) num_samps); + tssival[1] = rssi_buf[2] / ((s32) num_samps); + + pwrindex[0] = idle_tssi[0] - tssival[0] + 64; + pwrindex[1] = idle_tssi[1] - tssival[1] + 64; + + if (pwrindex[0] < 0) { + pwrindex[0] = 0; + } else if (pwrindex[0] > 63) { + pwrindex[0] = 63; + } + + if (pwrindex[1] < 0) { + pwrindex[1] = 0; + } else if (pwrindex[1] > 63) { + pwrindex[1] = 63; + } + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 1, + (u32) pwrindex[0], 32, &qdBm_pwrbuf[0]); + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 1, + (u32) pwrindex[1], 32, &qdBm_pwrbuf[1]); +} + +static void wlc_phy_internal_cal_txgain_nphy(phy_info_t *pi) +{ + u16 txcal_gain[2]; + + pi->nphy_txcal_pwr_idx[0] = pi->nphy_cal_orig_pwr_idx[0]; + pi->nphy_txcal_pwr_idx[1] = pi->nphy_cal_orig_pwr_idx[0]; + wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true); + wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true); + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, + txcal_gain); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F40; + txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F40; + } else { + txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F60; + txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F60; + } + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, + txcal_gain); +} + +static void wlc_phy_precal_txgain_nphy(phy_info_t *pi) +{ + bool save_bbmult = false; + u8 txcal_index_2057_rev5n7 = 0; + u8 txcal_index_2057_rev3n4n6 = 10; + + if (pi->use_int_tx_iqlo_cal_nphy) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if ((pi->pubpi.radiorev == 3) || + (pi->pubpi.radiorev == 4) || + (pi->pubpi.radiorev == 6)) { + + pi->nphy_txcal_pwr_idx[0] = + txcal_index_2057_rev3n4n6; + pi->nphy_txcal_pwr_idx[1] = + txcal_index_2057_rev3n4n6; + wlc_phy_txpwr_index_nphy(pi, 3, + txcal_index_2057_rev3n4n6, + false); + } else { + + pi->nphy_txcal_pwr_idx[0] = + txcal_index_2057_rev5n7; + pi->nphy_txcal_pwr_idx[1] = + txcal_index_2057_rev5n7; + wlc_phy_txpwr_index_nphy(pi, 3, + txcal_index_2057_rev5n7, + false); + } + save_bbmult = true; + + } else if (NREV_LT(pi->pubpi.phy_rev, 5)) { + wlc_phy_cal_txgainctrl_nphy(pi, 11, false); + if (pi->sh->hw_phytxchain != 3) { + pi->nphy_txcal_pwr_idx[1] = + pi->nphy_txcal_pwr_idx[0]; + wlc_phy_txpwr_index_nphy(pi, 3, + pi-> + nphy_txcal_pwr_idx[0], + true); + save_bbmult = true; + } + + } else if (NREV_IS(pi->pubpi.phy_rev, 5)) { + if (PHY_IPA(pi)) { + if (CHSPEC_IS2G(pi->radio_chanspec)) { + wlc_phy_cal_txgainctrl_nphy(pi, 12, + false); + } else { + pi->nphy_txcal_pwr_idx[0] = 80; + pi->nphy_txcal_pwr_idx[1] = 80; + wlc_phy_txpwr_index_nphy(pi, 3, 80, + false); + save_bbmult = true; + } + } else { + + wlc_phy_internal_cal_txgain_nphy(pi); + save_bbmult = true; + } + + } else if (NREV_IS(pi->pubpi.phy_rev, 6)) { + if (PHY_IPA(pi)) { + if (CHSPEC_IS2G(pi->radio_chanspec)) { + wlc_phy_cal_txgainctrl_nphy(pi, 12, + false); + } else { + wlc_phy_cal_txgainctrl_nphy(pi, 14, + false); + } + } else { + + wlc_phy_internal_cal_txgain_nphy(pi); + save_bbmult = true; + } + } + + } else { + wlc_phy_cal_txgainctrl_nphy(pi, 10, false); + } + + if (save_bbmult) { + wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, + &pi->nphy_txcal_bbmult); + } +} + +void +wlc_phy_cal_txgainctrl_nphy(phy_info_t *pi, s32 dBm_targetpower, bool debug) +{ + int gainctrl_loopidx; + uint core; + u16 m0m1, curr_m0m1; + s32 delta_power; + s32 txpwrindex; + s32 qdBm_power[2]; + u16 orig_BBConfig; + u16 phy_saveregs[4]; + u32 freq_test; + u16 ampl_test = 250; + uint stepsize; + bool phyhang_avoid_state = false; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + stepsize = 2; + } else { + + stepsize = 1; + } + + if (CHSPEC_IS40(pi->radio_chanspec)) { + freq_test = 5000; + } else { + freq_test = 2500; + } + + wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true); + wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true); + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + phyhang_avoid_state = pi->phyhang_avoid; + pi->phyhang_avoid = false; + + phy_saveregs[0] = read_phy_reg(pi, 0x91); + phy_saveregs[1] = read_phy_reg(pi, 0x92); + phy_saveregs[2] = read_phy_reg(pi, 0xe7); + phy_saveregs[3] = read_phy_reg(pi, 0xec); + wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 1, + RADIO_MIMO_CORESEL_CORE1 | + RADIO_MIMO_CORESEL_CORE2); + + if (!debug) { + wlc_phy_rfctrlintc_override_nphy(pi, + NPHY_RfctrlIntc_override_TRSW, + 0x2, RADIO_MIMO_CORESEL_CORE1); + wlc_phy_rfctrlintc_override_nphy(pi, + NPHY_RfctrlIntc_override_TRSW, + 0x8, RADIO_MIMO_CORESEL_CORE2); + } else { + wlc_phy_rfctrlintc_override_nphy(pi, + NPHY_RfctrlIntc_override_TRSW, + 0x1, RADIO_MIMO_CORESEL_CORE1); + wlc_phy_rfctrlintc_override_nphy(pi, + NPHY_RfctrlIntc_override_TRSW, + 0x7, RADIO_MIMO_CORESEL_CORE2); + } + + orig_BBConfig = read_phy_reg(pi, 0x01); + mod_phy_reg(pi, 0x01, (0x1 << 15), 0); + + wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1); + + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + txpwrindex = (s32) pi->nphy_cal_orig_pwr_idx[core]; + + for (gainctrl_loopidx = 0; gainctrl_loopidx < 2; + gainctrl_loopidx++) { + wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0, + false); + + if (core == PHY_CORE_0) { + curr_m0m1 = m0m1 & 0xff00; + } else { + curr_m0m1 = m0m1 & 0x00ff; + } + + wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &curr_m0m1); + wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &curr_m0m1); + + udelay(50); + + wlc_phy_est_tonepwr_nphy(pi, qdBm_power, + NPHY_CAL_TSSISAMPS); + + pi->nphy_bb_mult_save = 0; + wlc_phy_stopplayback_nphy(pi); + + delta_power = (dBm_targetpower * 4) - qdBm_power[core]; + + txpwrindex -= stepsize * delta_power; + if (txpwrindex < 0) { + txpwrindex = 0; + } else if (txpwrindex > 127) { + txpwrindex = 127; + } + + if (CHSPEC_IS5G(pi->radio_chanspec)) { + if (NREV_IS(pi->pubpi.phy_rev, 4) && + (pi->srom_fem5g.extpagain == 3)) { + if (txpwrindex < 30) { + txpwrindex = 30; + } + } + } else { + if (NREV_GE(pi->pubpi.phy_rev, 5) && + (pi->srom_fem2g.extpagain == 3)) { + if (txpwrindex < 50) { + txpwrindex = 50; + } + } + } + + wlc_phy_txpwr_index_nphy(pi, (1 << core), + (u8) txpwrindex, true); + } + + pi->nphy_txcal_pwr_idx[core] = (u8) txpwrindex; + + if (debug) { + u16 radio_gain; + u16 dbg_m0m1; + + wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &dbg_m0m1); + + wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0, + false); + + wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &dbg_m0m1); + wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &dbg_m0m1); + + udelay(100); + + wlc_phy_est_tonepwr_nphy(pi, qdBm_power, + NPHY_CAL_TSSISAMPS); + + wlc_phy_table_read_nphy(pi, 7, 1, (0x110 + core), 16, + &radio_gain); + + mdelay(4000); + pi->nphy_bb_mult_save = 0; + wlc_phy_stopplayback_nphy(pi); + } + } + + wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_txcal_pwr_idx[0], true); + wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_txcal_pwr_idx[1], true); + + wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &pi->nphy_txcal_bbmult); + + write_phy_reg(pi, 0x01, orig_BBConfig); + + write_phy_reg(pi, 0x91, phy_saveregs[0]); + write_phy_reg(pi, 0x92, phy_saveregs[1]); + write_phy_reg(pi, 0xe7, phy_saveregs[2]); + write_phy_reg(pi, 0xec, phy_saveregs[3]); + + pi->phyhang_avoid = phyhang_avoid_state; + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); +} + +static void wlc_phy_update_txcal_ladder_nphy(phy_info_t *pi, u16 core) +{ + int index; + u32 bbmult_scale; + u16 bbmult; + u16 tblentry; + + nphy_txiqcal_ladder_t ladder_lo[] = { + {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0}, + {25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5}, + {25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7} + }; + + nphy_txiqcal_ladder_t ladder_iq[] = { + {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0}, + {25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1}, + {100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7} + }; + + bbmult = (core == PHY_CORE_0) ? + ((pi->nphy_txcal_bbmult >> 8) & 0xff) : (pi-> + nphy_txcal_bbmult & 0xff); + + for (index = 0; index < 18; index++) { + bbmult_scale = ladder_lo[index].percent * bbmult; + bbmult_scale /= 100; + + tblentry = + ((bbmult_scale & 0xff) << 8) | ladder_lo[index].g_env; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index, 16, + &tblentry); + + bbmult_scale = ladder_iq[index].percent * bbmult; + bbmult_scale /= 100; + + tblentry = + ((bbmult_scale & 0xff) << 8) | ladder_iq[index].g_env; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index + 32, + 16, &tblentry); + } +} + +void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype) +{ + nphy_txgains_t target_gain; + u8 tx_pwr_ctrl_state; + bool fullcal = true; + bool restore_tx_gain = false; + bool mphase; + + if (NORADIO_ENAB(pi->pubpi)) { + wlc_phy_cal_perical_mphase_reset(pi); + return; + } + + if (PHY_MUTED(pi)) + return; + + ASSERT(pi->nphy_perical != PHY_PERICAL_DISABLE); + + if (caltype == PHY_PERICAL_AUTO) + fullcal = (pi->radio_chanspec != pi->nphy_txiqlocal_chanspec); + else if (caltype == PHY_PERICAL_PARTIAL) + fullcal = false; + + if (pi->cal_type_override != PHY_PERICAL_AUTO) { + fullcal = + (pi->cal_type_override == PHY_PERICAL_FULL) ? true : false; + } + + if ((pi->mphase_cal_phase_id > MPHASE_CAL_STATE_INIT)) { + if (pi->nphy_txiqlocal_chanspec != pi->radio_chanspec) + wlc_phy_cal_perical_mphase_restart(pi); + } + + if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_RXCAL)) { + wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000); + } + + wlapi_suspend_mac_and_wait(pi->sh->physhim); + + wlc_phyreg_enter((wlc_phy_t *) pi); + + if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_IDLE) || + (pi->mphase_cal_phase_id == MPHASE_CAL_STATE_INIT)) { + pi->nphy_cal_orig_pwr_idx[0] = + (u8) ((read_phy_reg(pi, 0x1ed) >> 8) & 0x7f); + pi->nphy_cal_orig_pwr_idx[1] = + (u8) ((read_phy_reg(pi, 0x1ee) >> 8) & 0x7f); + + if (pi->nphy_txpwrctrl != PHY_TPC_HW_OFF) { + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, + 0x110, 16, + pi->nphy_cal_orig_tx_gain); + } else { + pi->nphy_cal_orig_tx_gain[0] = 0; + pi->nphy_cal_orig_tx_gain[1] = 0; + } + } + target_gain = wlc_phy_get_tx_gain_nphy(pi); + tx_pwr_ctrl_state = pi->nphy_txpwrctrl; + wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF); + + if (pi->antsel_type == ANTSEL_2x3) + wlc_phy_antsel_init((wlc_phy_t *) pi, true); + + mphase = (pi->mphase_cal_phase_id != MPHASE_CAL_STATE_IDLE); + if (!mphase) { + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + wlc_phy_precal_txgain_nphy(pi); + pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi); + restore_tx_gain = true; + + target_gain = pi->nphy_cal_target_gain; + } + if (BCME_OK == + wlc_phy_cal_txiqlo_nphy(pi, target_gain, fullcal, mphase)) { + if (PHY_IPA(pi)) + wlc_phy_a4(pi, true); + + wlc_phyreg_exit((wlc_phy_t *) pi); + wlapi_enable_mac(pi->sh->physhim); + wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, + 10000); + wlapi_suspend_mac_and_wait(pi->sh->physhim); + wlc_phyreg_enter((wlc_phy_t *) pi); + + if (BCME_OK == wlc_phy_cal_rxiq_nphy(pi, target_gain, + (pi-> + first_cal_after_assoc + || (pi-> + cal_type_override + == + PHY_PERICAL_FULL)) + ? 2 : 0, false)) { + wlc_phy_savecal_nphy(pi); + + wlc_phy_txpwrctrl_coeff_setup_nphy(pi); + + pi->nphy_perical_last = pi->sh->now; + } + } + if (caltype != PHY_PERICAL_AUTO) { + wlc_phy_rssi_cal_nphy(pi); + } + + if (pi->first_cal_after_assoc + || (pi->cal_type_override == PHY_PERICAL_FULL)) { + pi->first_cal_after_assoc = false; + wlc_phy_txpwrctrl_idle_tssi_nphy(pi); + wlc_phy_txpwrctrl_pwr_setup_nphy(pi); + } + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + wlc_phy_radio205x_vcocal_nphy(pi); + } + } else { + ASSERT(pi->nphy_perical >= PHY_PERICAL_MPHASE); + + switch (pi->mphase_cal_phase_id) { + case MPHASE_CAL_STATE_INIT: + pi->nphy_perical_last = pi->sh->now; + pi->nphy_txiqlocal_chanspec = pi->radio_chanspec; + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + wlc_phy_precal_txgain_nphy(pi); + } + pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi); + pi->mphase_cal_phase_id++; + break; + + case MPHASE_CAL_STATE_TXPHASE0: + case MPHASE_CAL_STATE_TXPHASE1: + case MPHASE_CAL_STATE_TXPHASE2: + case MPHASE_CAL_STATE_TXPHASE3: + case MPHASE_CAL_STATE_TXPHASE4: + case MPHASE_CAL_STATE_TXPHASE5: + if ((pi->radar_percal_mask & 0x10) != 0) + pi->nphy_rxcal_active = true; + + if (wlc_phy_cal_txiqlo_nphy + (pi, pi->nphy_cal_target_gain, fullcal, + true) != BCME_OK) { + + wlc_phy_cal_perical_mphase_reset(pi); + break; + } + + if (NREV_LE(pi->pubpi.phy_rev, 2) && + (pi->mphase_cal_phase_id == + MPHASE_CAL_STATE_TXPHASE4)) { + pi->mphase_cal_phase_id += 2; + } else { + pi->mphase_cal_phase_id++; + } + break; + + case MPHASE_CAL_STATE_PAPDCAL: + if ((pi->radar_percal_mask & 0x2) != 0) + pi->nphy_rxcal_active = true; + + if (PHY_IPA(pi)) { + wlc_phy_a4(pi, true); + } + pi->mphase_cal_phase_id++; + break; + + case MPHASE_CAL_STATE_RXCAL: + if ((pi->radar_percal_mask & 0x1) != 0) + pi->nphy_rxcal_active = true; + if (wlc_phy_cal_rxiq_nphy(pi, target_gain, + (pi->first_cal_after_assoc || + (pi->cal_type_override == + PHY_PERICAL_FULL)) ? 2 : 0, + false) == BCME_OK) { + wlc_phy_savecal_nphy(pi); + } + + pi->mphase_cal_phase_id++; + break; + + case MPHASE_CAL_STATE_RSSICAL: + if ((pi->radar_percal_mask & 0x4) != 0) + pi->nphy_rxcal_active = true; + wlc_phy_txpwrctrl_coeff_setup_nphy(pi); + wlc_phy_rssi_cal_nphy(pi); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + wlc_phy_radio205x_vcocal_nphy(pi); + } + restore_tx_gain = true; + + if (pi->first_cal_after_assoc) { + pi->mphase_cal_phase_id++; + } else { + wlc_phy_cal_perical_mphase_reset(pi); + } + + break; + + case MPHASE_CAL_STATE_IDLETSSI: + if ((pi->radar_percal_mask & 0x8) != 0) + pi->nphy_rxcal_active = true; + + if (pi->first_cal_after_assoc) { + pi->first_cal_after_assoc = false; + wlc_phy_txpwrctrl_idle_tssi_nphy(pi); + wlc_phy_txpwrctrl_pwr_setup_nphy(pi); + } + + wlc_phy_cal_perical_mphase_reset(pi); + break; + + default: + ASSERT(0); + wlc_phy_cal_perical_mphase_reset(pi); + break; + } + } + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (restore_tx_gain) { + if (tx_pwr_ctrl_state != PHY_TPC_HW_OFF) { + + wlc_phy_txpwr_index_nphy(pi, 1, + pi-> + nphy_cal_orig_pwr_idx + [0], false); + wlc_phy_txpwr_index_nphy(pi, 2, + pi-> + nphy_cal_orig_pwr_idx + [1], false); + + pi->nphy_txpwrindex[0].index = -1; + pi->nphy_txpwrindex[1].index = -1; + } else { + wlc_phy_txpwr_index_nphy(pi, (1 << 0), + (s8) (pi-> + nphy_txpwrindex + [0]. + index_internal), + false); + wlc_phy_txpwr_index_nphy(pi, (1 << 1), + (s8) (pi-> + nphy_txpwrindex + [1]. + index_internal), + false); + } + } + } + + wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state); + wlc_phyreg_exit((wlc_phy_t *) pi); + wlapi_enable_mac(pi->sh->physhim); +} + +int +wlc_phy_cal_txiqlo_nphy(phy_info_t *pi, nphy_txgains_t target_gain, + bool fullcal, bool mphase) +{ + u16 val; + u16 tbl_buf[11]; + u8 cal_cnt; + u16 cal_cmd; + u8 num_cals, max_cal_cmds; + u16 core_no, cal_type; + u16 diq_start = 0; + u8 phy_bw; + u16 max_val; + u16 tone_freq; + u16 gain_save[2]; + u16 cal_gain[2]; + nphy_iqcal_params_t cal_params[2]; + u32 tbl_len; + void *tbl_ptr; + bool ladder_updated[2]; + u8 mphase_cal_lastphase = 0; + int bcmerror = BCME_OK; + bool phyhang_avoid_state = false; + + u16 tbl_tx_iqlo_cal_loft_ladder_20[] = { + 0x0300, 0x0500, 0x0700, 0x0900, 0x0d00, 0x1100, 0x1900, 0x1901, + 0x1902, + 0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x2407, 0x3207, 0x4607, + 0x6407 + }; + + u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = { + 0x0200, 0x0300, 0x0600, 0x0900, 0x0d00, 0x1100, 0x1900, 0x2400, + 0x3200, + 0x4600, 0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406, + 0x6407 + }; + + u16 tbl_tx_iqlo_cal_loft_ladder_40[] = { + 0x0200, 0x0300, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1201, + 0x1202, + 0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1907, 0x2307, 0x3207, + 0x4707 + }; + + u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = { + 0x0100, 0x0200, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1900, + 0x2300, + 0x3200, 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706, + 0x4707 + }; + + u16 tbl_tx_iqlo_cal_startcoefs[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000 + }; + + u16 tbl_tx_iqlo_cal_cmds_fullcal[] = { + 0x8123, 0x8264, 0x8086, 0x8245, 0x8056, + 0x9123, 0x9264, 0x9086, 0x9245, 0x9056 + }; + + u16 tbl_tx_iqlo_cal_cmds_recal[] = { + 0x8101, 0x8253, 0x8053, 0x8234, 0x8034, + 0x9101, 0x9253, 0x9053, 0x9234, 0x9034 + }; + + u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000 + }; + + u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = { + 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234, + 0x9434, 0x9334, 0x9084, 0x9267, 0x9056, 0x9234 + }; + + u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = { + 0x8423, 0x8323, 0x8073, 0x8256, 0x8045, 0x8223, + 0x9423, 0x9323, 0x9073, 0x9256, 0x9045, 0x9223 + }; + + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + if (NREV_GE(pi->pubpi.phy_rev, 4)) { + phyhang_avoid_state = pi->phyhang_avoid; + pi->phyhang_avoid = false; + } + + if (CHSPEC_IS40(pi->radio_chanspec)) { + phy_bw = 40; + } else { + phy_bw = 20; + } + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save); + + for (core_no = 0; core_no <= 1; core_no++) { + wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain, + &cal_params[core_no]); + cal_gain[core_no] = cal_params[core_no].cal_gain; + } + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain); + + wlc_phy_txcal_radio_setup_nphy(pi); + + wlc_phy_txcal_physetup_nphy(pi); + + ladder_updated[0] = ladder_updated[1] = false; + if (!(NREV_GE(pi->pubpi.phy_rev, 6) || + (NREV_IS(pi->pubpi.phy_rev, 5) && PHY_IPA(pi) + && (CHSPEC_IS2G(pi->radio_chanspec))))) { + + if (phy_bw == 40) { + tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_40; + tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_loft_ladder_40); + } else { + tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_20; + tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_loft_ladder_20); + } + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 0, + 16, tbl_ptr); + + if (phy_bw == 40) { + tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_40; + tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_iqimb_ladder_40); + } else { + tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_20; + tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_iqimb_ladder_20); + } + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 32, + 16, tbl_ptr); + } + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + write_phy_reg(pi, 0xc2, 0x8ad9); + } else { + write_phy_reg(pi, 0xc2, 0x8aa9); + } + + max_val = 250; + tone_freq = (phy_bw == 20) ? 2500 : 5000; + + if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) { + wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff, 0, 1, 0, false); + bcmerror = BCME_OK; + } else { + bcmerror = + wlc_phy_tx_tone_nphy(pi, tone_freq, max_val, 1, 0, false); + } + + if (bcmerror == BCME_OK) { + + if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) { + tbl_ptr = pi->mphase_txcal_bestcoeffs; + tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs); + if (NREV_LT(pi->pubpi.phy_rev, 3)) { + + tbl_len -= 2; + } + } else { + if ((!fullcal) && (pi->nphy_txiqlocal_coeffsvalid)) { + + tbl_ptr = pi->nphy_txiqlocal_bestc; + tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc); + if (NREV_LT(pi->pubpi.phy_rev, 3)) { + + tbl_len -= 2; + } + } else { + + fullcal = true; + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + tbl_ptr = + tbl_tx_iqlo_cal_startcoefs_nphyrev3; + tbl_len = + ARRAY_SIZE + (tbl_tx_iqlo_cal_startcoefs_nphyrev3); + } else { + tbl_ptr = tbl_tx_iqlo_cal_startcoefs; + tbl_len = + ARRAY_SIZE + (tbl_tx_iqlo_cal_startcoefs); + } + } + } + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 64, + 16, tbl_ptr); + + if (fullcal) { + max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ? + ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3) : + ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_fullcal); + } else { + max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ? + ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_recal_nphyrev3) : + ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_recal); + } + + if (mphase) { + cal_cnt = pi->mphase_txcal_cmdidx; + if ((cal_cnt + pi->mphase_txcal_numcmds) < max_cal_cmds) { + num_cals = cal_cnt + pi->mphase_txcal_numcmds; + } else { + num_cals = max_cal_cmds; + } + } else { + cal_cnt = 0; + num_cals = max_cal_cmds; + } + + for (; cal_cnt < num_cals; cal_cnt++) { + + if (fullcal) { + cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ? + tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3 + [cal_cnt] : + tbl_tx_iqlo_cal_cmds_fullcal[cal_cnt]; + } else { + cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ? + tbl_tx_iqlo_cal_cmds_recal_nphyrev3[cal_cnt] + : tbl_tx_iqlo_cal_cmds_recal[cal_cnt]; + } + + core_no = ((cal_cmd & 0x3000) >> 12); + cal_type = ((cal_cmd & 0x0F00) >> 8); + + if (NREV_GE(pi->pubpi.phy_rev, 6) || + (NREV_IS(pi->pubpi.phy_rev, 5) && + PHY_IPA(pi) + && (CHSPEC_IS2G(pi->radio_chanspec)))) { + if (!ladder_updated[core_no]) { + wlc_phy_update_txcal_ladder_nphy(pi, + core_no); + ladder_updated[core_no] = true; + } + } + + val = + (cal_params[core_no]. + ncorr[cal_type] << 8) | NPHY_N_GCTL; + write_phy_reg(pi, 0xc1, val); + + if ((cal_type == 1) || (cal_type == 3) + || (cal_type == 4)) { + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, + 1, 69 + core_no, 16, + tbl_buf); + + diq_start = tbl_buf[0]; + + tbl_buf[0] = 0; + wlc_phy_table_write_nphy(pi, + NPHY_TBL_ID_IQLOCAL, 1, + 69 + core_no, 16, + tbl_buf); + } + + write_phy_reg(pi, 0xc0, cal_cmd); + + SPINWAIT(((read_phy_reg(pi, 0xc0) & 0xc000) != 0), + 20000); + ASSERT((read_phy_reg(pi, 0xc0) & 0xc000) == 0); + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, + tbl_len, 96, 16, tbl_buf); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, + tbl_len, 64, 16, tbl_buf); + + if ((cal_type == 1) || (cal_type == 3) + || (cal_type == 4)) { + + tbl_buf[0] = diq_start; + + } + + } + + if (mphase) { + pi->mphase_txcal_cmdidx = num_cals; + if (pi->mphase_txcal_cmdidx >= max_cal_cmds) + pi->mphase_txcal_cmdidx = 0; + } + + mphase_cal_lastphase = + (NREV_LE(pi->pubpi.phy_rev, 2)) ? + MPHASE_CAL_STATE_TXPHASE4 : MPHASE_CAL_STATE_TXPHASE5; + + if (!mphase + || (pi->mphase_cal_phase_id == mphase_cal_lastphase)) { + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 96, + 16, tbl_buf); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80, + 16, tbl_buf); + + if (NREV_LT(pi->pubpi.phy_rev, 2)) { + + tbl_buf[0] = 0; + tbl_buf[1] = 0; + tbl_buf[2] = 0; + tbl_buf[3] = 0; + + } + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88, + 16, tbl_buf); + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 101, + 16, tbl_buf); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85, + 16, tbl_buf); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93, + 16, tbl_buf); + + tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc); + if (NREV_LT(pi->pubpi.phy_rev, 3)) { + + tbl_len -= 2; + } + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, + tbl_len, 96, 16, + pi->nphy_txiqlocal_bestc); + + pi->nphy_txiqlocal_coeffsvalid = true; + pi->nphy_txiqlocal_chanspec = pi->radio_chanspec; + } else { + tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs); + if (NREV_LT(pi->pubpi.phy_rev, 3)) { + + tbl_len -= 2; + } + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, + tbl_len, 96, 16, + pi->mphase_txcal_bestcoeffs); + } + + wlc_phy_stopplayback_nphy(pi); + + write_phy_reg(pi, 0xc2, 0x0000); + + } + + wlc_phy_txcal_phycleanup_nphy(pi); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, + gain_save); + + wlc_phy_txcal_radio_cleanup_nphy(pi); + + if (NREV_LT(pi->pubpi.phy_rev, 2)) { + if (!mphase + || (pi->mphase_cal_phase_id == mphase_cal_lastphase)) + wlc_phy_tx_iq_war_nphy(pi); + } + + if (NREV_GE(pi->pubpi.phy_rev, 4)) { + pi->phyhang_avoid = phyhang_avoid_state; + } + + wlc_phy_stay_in_carriersearch_nphy(pi, false); + + return bcmerror; +} + +static void wlc_phy_reapply_txcal_coeffs_nphy(phy_info_t *pi) +{ + u16 tbl_buf[7]; + + ASSERT(NREV_LT(pi->pubpi.phy_rev, 2)); + + if ((pi->nphy_txiqlocal_chanspec == pi->radio_chanspec) && + (pi->nphy_txiqlocal_coeffsvalid)) { + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, + ARRAY_SIZE(tbl_buf), 80, 16, tbl_buf); + + if ((pi->nphy_txiqlocal_bestc[0] != tbl_buf[0]) || + (pi->nphy_txiqlocal_bestc[1] != tbl_buf[1]) || + (pi->nphy_txiqlocal_bestc[2] != tbl_buf[2]) || + (pi->nphy_txiqlocal_bestc[3] != tbl_buf[3])) { + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80, + 16, pi->nphy_txiqlocal_bestc); + + tbl_buf[0] = 0; + tbl_buf[1] = 0; + tbl_buf[2] = 0; + tbl_buf[3] = 0; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88, + 16, tbl_buf); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85, + 16, + &pi->nphy_txiqlocal_bestc[5]); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93, + 16, + &pi->nphy_txiqlocal_bestc[5]); + } + } +} + +static void wlc_phy_tx_iq_war_nphy(phy_info_t *pi) +{ + nphy_iq_comp_t tx_comp; + + wlc_phy_table_read_nphy(pi, 15, 4, 0x50, 16, (void *)&tx_comp); + + wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ, tx_comp.a0); + wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 2, tx_comp.b0); + wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 4, tx_comp.a1); + wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 6, tx_comp.b1); +} + +void +wlc_phy_rx_iq_coeffs_nphy(phy_info_t *pi, u8 write, nphy_iq_comp_t *pcomp) +{ + if (write) { + write_phy_reg(pi, 0x9a, pcomp->a0); + write_phy_reg(pi, 0x9b, pcomp->b0); + write_phy_reg(pi, 0x9c, pcomp->a1); + write_phy_reg(pi, 0x9d, pcomp->b1); + } else { + pcomp->a0 = read_phy_reg(pi, 0x9a); + pcomp->b0 = read_phy_reg(pi, 0x9b); + pcomp->a1 = read_phy_reg(pi, 0x9c); + pcomp->b1 = read_phy_reg(pi, 0x9d); + } +} + +void +wlc_phy_rx_iq_est_nphy(phy_info_t *pi, phy_iq_est_t *est, u16 num_samps, + u8 wait_time, u8 wait_for_crs) +{ + u8 core; + + write_phy_reg(pi, 0x12b, num_samps); + mod_phy_reg(pi, 0x12a, (0xff << 0), (wait_time << 0)); + mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqMode, + (wait_for_crs) ? NPHY_IqestCmd_iqMode : 0); + + mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqstart, NPHY_IqestCmd_iqstart); + + SPINWAIT(((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) != 0), + 10000); + ASSERT((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) == 0); + + if ((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) == 0) { + ASSERT(pi->pubpi.phy_corenum <= PHY_CORE_MAX); + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + est[core].i_pwr = + (read_phy_reg(pi, NPHY_IqestipwrAccHi(core)) << 16) + | read_phy_reg(pi, NPHY_IqestipwrAccLo(core)); + est[core].q_pwr = + (read_phy_reg(pi, NPHY_IqestqpwrAccHi(core)) << 16) + | read_phy_reg(pi, NPHY_IqestqpwrAccLo(core)); + est[core].iq_prod = + (read_phy_reg(pi, NPHY_IqestIqAccHi(core)) << 16) | + read_phy_reg(pi, NPHY_IqestIqAccLo(core)); + } + } +} + +#define CAL_RETRY_CNT 2 +static void wlc_phy_calc_rx_iq_comp_nphy(phy_info_t *pi, u8 core_mask) +{ + u8 curr_core; + phy_iq_est_t est[PHY_CORE_MAX]; + nphy_iq_comp_t old_comp, new_comp; + s32 iq = 0; + u32 ii = 0, qq = 0; + s16 iq_nbits, qq_nbits, brsh, arsh; + s32 a, b, temp; + int bcmerror = BCME_OK; + uint cal_retry = 0; + + if (core_mask == 0x0) + return; + + wlc_phy_rx_iq_coeffs_nphy(pi, 0, &old_comp); + new_comp.a0 = new_comp.b0 = new_comp.a1 = new_comp.b1 = 0x0; + wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp); + + cal_try: + wlc_phy_rx_iq_est_nphy(pi, est, 0x4000, 32, 0); + + new_comp = old_comp; + + for (curr_core = 0; curr_core < pi->pubpi.phy_corenum; curr_core++) { + + if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) { + iq = est[curr_core].iq_prod; + ii = est[curr_core].i_pwr; + qq = est[curr_core].q_pwr; + } else if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) { + iq = est[curr_core].iq_prod; + ii = est[curr_core].i_pwr; + qq = est[curr_core].q_pwr; + } else { + continue; + } + + if ((ii + qq) < NPHY_MIN_RXIQ_PWR) { + bcmerror = BCME_ERROR; + break; + } + + iq_nbits = wlc_phy_nbits(iq); + qq_nbits = wlc_phy_nbits(qq); + + arsh = 10 - (30 - iq_nbits); + if (arsh >= 0) { + a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh))); + temp = (s32) (ii >> arsh); + if (temp == 0) { + bcmerror = BCME_ERROR; + break; + } + } else { + a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh))); + temp = (s32) (ii << -arsh); + if (temp == 0) { + bcmerror = BCME_ERROR; + break; + } + } + + a /= temp; + + brsh = qq_nbits - 31 + 20; + if (brsh >= 0) { + b = (qq << (31 - qq_nbits)); + temp = (s32) (ii >> brsh); + if (temp == 0) { + bcmerror = BCME_ERROR; + break; + } + } else { + b = (qq << (31 - qq_nbits)); + temp = (s32) (ii << -brsh); + if (temp == 0) { + bcmerror = BCME_ERROR; + break; + } + } + b /= temp; + b -= a * a; + b = (s32) wlc_phy_sqrt_int((u32) b); + b -= (1 << 10); + + if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) { + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + new_comp.a0 = (s16) a & 0x3ff; + new_comp.b0 = (s16) b & 0x3ff; + } else { + + new_comp.a0 = (s16) b & 0x3ff; + new_comp.b0 = (s16) a & 0x3ff; + } + } + if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) { + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + new_comp.a1 = (s16) a & 0x3ff; + new_comp.b1 = (s16) b & 0x3ff; + } else { + + new_comp.a1 = (s16) b & 0x3ff; + new_comp.b1 = (s16) a & 0x3ff; + } + } + } + + if (bcmerror != BCME_OK) { + printk("%s: Failed, cnt = %d\n", __func__, cal_retry); + + if (cal_retry < CAL_RETRY_CNT) { + cal_retry++; + goto cal_try; + } + + new_comp = old_comp; + } else if (cal_retry > 0) { + } + + wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp); +} + +static void wlc_phy_rxcal_radio_setup_nphy(phy_info_t *pi, u8 rx_core) +{ + u16 offtune_val; + u16 bias_g = 0; + u16 bias_a = 0; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (rx_core == PHY_CORE_0) { + if (CHSPEC_IS5G(pi->radio_chanspec)) { + pi->tx_rx_cal_radio_saveregs[0] = + read_radio_reg(pi, + RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP); + pi->tx_rx_cal_radio_saveregs[1] = + read_radio_reg(pi, + RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN); + + write_radio_reg(pi, + RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP, + 0x3); + write_radio_reg(pi, + RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN, + 0xaf); + + } else { + pi->tx_rx_cal_radio_saveregs[0] = + read_radio_reg(pi, + RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP); + pi->tx_rx_cal_radio_saveregs[1] = + read_radio_reg(pi, + RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN); + + write_radio_reg(pi, + RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP, + 0x3); + write_radio_reg(pi, + RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN, + 0x7f); + } + + } else { + if (CHSPEC_IS5G(pi->radio_chanspec)) { + pi->tx_rx_cal_radio_saveregs[0] = + read_radio_reg(pi, + RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP); + pi->tx_rx_cal_radio_saveregs[1] = + read_radio_reg(pi, + RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN); + + write_radio_reg(pi, + RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP, + 0x3); + write_radio_reg(pi, + RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN, + 0xaf); + + } else { + pi->tx_rx_cal_radio_saveregs[0] = + read_radio_reg(pi, + RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP); + pi->tx_rx_cal_radio_saveregs[1] = + read_radio_reg(pi, + RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN); + + write_radio_reg(pi, + RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP, + 0x3); + write_radio_reg(pi, + RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN, + 0x7f); + } + } + + } else { + if (rx_core == PHY_CORE_0) { + pi->tx_rx_cal_radio_saveregs[0] = + read_radio_reg(pi, + RADIO_2056_TX_RXIQCAL_TXMUX | + RADIO_2056_TX1); + pi->tx_rx_cal_radio_saveregs[1] = + read_radio_reg(pi, + RADIO_2056_RX_RXIQCAL_RXMUX | + RADIO_2056_RX0); + + if (pi->pubpi.radiorev >= 5) { + pi->tx_rx_cal_radio_saveregs[2] = + read_radio_reg(pi, + RADIO_2056_RX_RXSPARE2 | + RADIO_2056_RX0); + pi->tx_rx_cal_radio_saveregs[3] = + read_radio_reg(pi, + RADIO_2056_TX_TXSPARE2 | + RADIO_2056_TX1); + } + + if (CHSPEC_IS5G(pi->radio_chanspec)) { + + if (pi->pubpi.radiorev >= 5) { + pi->tx_rx_cal_radio_saveregs[4] = + read_radio_reg(pi, + RADIO_2056_RX_LNAA_MASTER + | RADIO_2056_RX0); + + write_radio_reg(pi, + RADIO_2056_RX_LNAA_MASTER + | RADIO_2056_RX0, 0x40); + + write_radio_reg(pi, + RADIO_2056_TX_TXSPARE2 | + RADIO_2056_TX1, bias_a); + + write_radio_reg(pi, + RADIO_2056_RX_RXSPARE2 | + RADIO_2056_RX0, bias_a); + } else { + pi->tx_rx_cal_radio_saveregs[4] = + read_radio_reg(pi, + RADIO_2056_RX_LNAA_TUNE + | RADIO_2056_RX0); + + offtune_val = + (pi-> + tx_rx_cal_radio_saveregs[2] & 0xF0) + >> 8; + offtune_val = + (offtune_val <= 0x7) ? 0xF : 0; + + mod_radio_reg(pi, + RADIO_2056_RX_LNAA_TUNE | + RADIO_2056_RX0, 0xF0, + (offtune_val << 8)); + } + + write_radio_reg(pi, + RADIO_2056_TX_RXIQCAL_TXMUX | + RADIO_2056_TX1, 0x9); + write_radio_reg(pi, + RADIO_2056_RX_RXIQCAL_RXMUX | + RADIO_2056_RX0, 0x9); + } else { + if (pi->pubpi.radiorev >= 5) { + pi->tx_rx_cal_radio_saveregs[4] = + read_radio_reg(pi, + RADIO_2056_RX_LNAG_MASTER + | RADIO_2056_RX0); + + write_radio_reg(pi, + RADIO_2056_RX_LNAG_MASTER + | RADIO_2056_RX0, 0x40); + + write_radio_reg(pi, + RADIO_2056_TX_TXSPARE2 | + RADIO_2056_TX1, bias_g); + + write_radio_reg(pi, + RADIO_2056_RX_RXSPARE2 | + RADIO_2056_RX0, bias_g); + + } else { + pi->tx_rx_cal_radio_saveregs[4] = + read_radio_reg(pi, + RADIO_2056_RX_LNAG_TUNE + | RADIO_2056_RX0); + + offtune_val = + (pi-> + tx_rx_cal_radio_saveregs[2] & 0xF0) + >> 8; + offtune_val = + (offtune_val <= 0x7) ? 0xF : 0; + + mod_radio_reg(pi, + RADIO_2056_RX_LNAG_TUNE | + RADIO_2056_RX0, 0xF0, + (offtune_val << 8)); + } + + write_radio_reg(pi, + RADIO_2056_TX_RXIQCAL_TXMUX | + RADIO_2056_TX1, 0x6); + write_radio_reg(pi, + RADIO_2056_RX_RXIQCAL_RXMUX | + RADIO_2056_RX0, 0x6); + } + + } else { + pi->tx_rx_cal_radio_saveregs[0] = + read_radio_reg(pi, + RADIO_2056_TX_RXIQCAL_TXMUX | + RADIO_2056_TX0); + pi->tx_rx_cal_radio_saveregs[1] = + read_radio_reg(pi, + RADIO_2056_RX_RXIQCAL_RXMUX | + RADIO_2056_RX1); + + if (pi->pubpi.radiorev >= 5) { + pi->tx_rx_cal_radio_saveregs[2] = + read_radio_reg(pi, + RADIO_2056_RX_RXSPARE2 | + RADIO_2056_RX1); + pi->tx_rx_cal_radio_saveregs[3] = + read_radio_reg(pi, + RADIO_2056_TX_TXSPARE2 | + RADIO_2056_TX0); + } + + if (CHSPEC_IS5G(pi->radio_chanspec)) { + + if (pi->pubpi.radiorev >= 5) { + pi->tx_rx_cal_radio_saveregs[4] = + read_radio_reg(pi, + RADIO_2056_RX_LNAA_MASTER + | RADIO_2056_RX1); + + write_radio_reg(pi, + RADIO_2056_RX_LNAA_MASTER + | RADIO_2056_RX1, 0x40); + + write_radio_reg(pi, + RADIO_2056_TX_TXSPARE2 | + RADIO_2056_TX0, bias_a); + + write_radio_reg(pi, + RADIO_2056_RX_RXSPARE2 | + RADIO_2056_RX1, bias_a); + } else { + pi->tx_rx_cal_radio_saveregs[4] = + read_radio_reg(pi, + RADIO_2056_RX_LNAA_TUNE + | RADIO_2056_RX1); + + offtune_val = + (pi-> + tx_rx_cal_radio_saveregs[2] & 0xF0) + >> 8; + offtune_val = + (offtune_val <= 0x7) ? 0xF : 0; + + mod_radio_reg(pi, + RADIO_2056_RX_LNAA_TUNE | + RADIO_2056_RX1, 0xF0, + (offtune_val << 8)); + } + + write_radio_reg(pi, + RADIO_2056_TX_RXIQCAL_TXMUX | + RADIO_2056_TX0, 0x9); + write_radio_reg(pi, + RADIO_2056_RX_RXIQCAL_RXMUX | + RADIO_2056_RX1, 0x9); + } else { + if (pi->pubpi.radiorev >= 5) { + pi->tx_rx_cal_radio_saveregs[4] = + read_radio_reg(pi, + RADIO_2056_RX_LNAG_MASTER + | RADIO_2056_RX1); + + write_radio_reg(pi, + RADIO_2056_RX_LNAG_MASTER + | RADIO_2056_RX1, 0x40); + + write_radio_reg(pi, + RADIO_2056_TX_TXSPARE2 | + RADIO_2056_TX0, bias_g); + + write_radio_reg(pi, + RADIO_2056_RX_RXSPARE2 | + RADIO_2056_RX1, bias_g); + } else { + pi->tx_rx_cal_radio_saveregs[4] = + read_radio_reg(pi, + RADIO_2056_RX_LNAG_TUNE + | RADIO_2056_RX1); + + offtune_val = + (pi-> + tx_rx_cal_radio_saveregs[2] & 0xF0) + >> 8; + offtune_val = + (offtune_val <= 0x7) ? 0xF : 0; + + mod_radio_reg(pi, + RADIO_2056_RX_LNAG_TUNE | + RADIO_2056_RX1, 0xF0, + (offtune_val << 8)); + } + + write_radio_reg(pi, + RADIO_2056_TX_RXIQCAL_TXMUX | + RADIO_2056_TX0, 0x6); + write_radio_reg(pi, + RADIO_2056_RX_RXIQCAL_RXMUX | + RADIO_2056_RX1, 0x6); + } + } + } +} + +static void wlc_phy_rxcal_radio_cleanup_nphy(phy_info_t *pi, u8 rx_core) +{ + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (rx_core == PHY_CORE_0) { + if (CHSPEC_IS5G(pi->radio_chanspec)) { + write_radio_reg(pi, + RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP, + pi-> + tx_rx_cal_radio_saveregs[0]); + write_radio_reg(pi, + RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN, + pi-> + tx_rx_cal_radio_saveregs[1]); + + } else { + write_radio_reg(pi, + RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP, + pi-> + tx_rx_cal_radio_saveregs[0]); + write_radio_reg(pi, + RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN, + pi-> + tx_rx_cal_radio_saveregs[1]); + } + + } else { + if (CHSPEC_IS5G(pi->radio_chanspec)) { + write_radio_reg(pi, + RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP, + pi-> + tx_rx_cal_radio_saveregs[0]); + write_radio_reg(pi, + RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN, + pi-> + tx_rx_cal_radio_saveregs[1]); + + } else { + write_radio_reg(pi, + RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP, + pi-> + tx_rx_cal_radio_saveregs[0]); + write_radio_reg(pi, + RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN, + pi-> + tx_rx_cal_radio_saveregs[1]); + } + } + + } else { + if (rx_core == PHY_CORE_0) { + write_radio_reg(pi, + RADIO_2056_TX_RXIQCAL_TXMUX | + RADIO_2056_TX1, + pi->tx_rx_cal_radio_saveregs[0]); + + write_radio_reg(pi, + RADIO_2056_RX_RXIQCAL_RXMUX | + RADIO_2056_RX0, + pi->tx_rx_cal_radio_saveregs[1]); + + if (pi->pubpi.radiorev >= 5) { + write_radio_reg(pi, + RADIO_2056_RX_RXSPARE2 | + RADIO_2056_RX0, + pi-> + tx_rx_cal_radio_saveregs[2]); + + write_radio_reg(pi, + RADIO_2056_TX_TXSPARE2 | + RADIO_2056_TX1, + pi-> + tx_rx_cal_radio_saveregs[3]); + } + + if (CHSPEC_IS5G(pi->radio_chanspec)) { + if (pi->pubpi.radiorev >= 5) { + write_radio_reg(pi, + RADIO_2056_RX_LNAA_MASTER + | RADIO_2056_RX0, + pi-> + tx_rx_cal_radio_saveregs + [4]); + } else { + write_radio_reg(pi, + RADIO_2056_RX_LNAA_TUNE + | RADIO_2056_RX0, + pi-> + tx_rx_cal_radio_saveregs + [4]); + } + } else { + if (pi->pubpi.radiorev >= 5) { + write_radio_reg(pi, + RADIO_2056_RX_LNAG_MASTER + | RADIO_2056_RX0, + pi-> + tx_rx_cal_radio_saveregs + [4]); + } else { + write_radio_reg(pi, + RADIO_2056_RX_LNAG_TUNE + | RADIO_2056_RX0, + pi-> + tx_rx_cal_radio_saveregs + [4]); + } + } + + } else { + write_radio_reg(pi, + RADIO_2056_TX_RXIQCAL_TXMUX | + RADIO_2056_TX0, + pi->tx_rx_cal_radio_saveregs[0]); + + write_radio_reg(pi, + RADIO_2056_RX_RXIQCAL_RXMUX | + RADIO_2056_RX1, + pi->tx_rx_cal_radio_saveregs[1]); + + if (pi->pubpi.radiorev >= 5) { + write_radio_reg(pi, + RADIO_2056_RX_RXSPARE2 | + RADIO_2056_RX1, + pi-> + tx_rx_cal_radio_saveregs[2]); + + write_radio_reg(pi, + RADIO_2056_TX_TXSPARE2 | + RADIO_2056_TX0, + pi-> + tx_rx_cal_radio_saveregs[3]); + } + + if (CHSPEC_IS5G(pi->radio_chanspec)) { + if (pi->pubpi.radiorev >= 5) { + write_radio_reg(pi, + RADIO_2056_RX_LNAA_MASTER + | RADIO_2056_RX1, + pi-> + tx_rx_cal_radio_saveregs + [4]); + } else { + write_radio_reg(pi, + RADIO_2056_RX_LNAA_TUNE + | RADIO_2056_RX1, + pi-> + tx_rx_cal_radio_saveregs + [4]); + } + } else { + if (pi->pubpi.radiorev >= 5) { + write_radio_reg(pi, + RADIO_2056_RX_LNAG_MASTER + | RADIO_2056_RX1, + pi-> + tx_rx_cal_radio_saveregs + [4]); + } else { + write_radio_reg(pi, + RADIO_2056_RX_LNAG_TUNE + | RADIO_2056_RX1, + pi-> + tx_rx_cal_radio_saveregs + [4]); + } + } + } + } +} + +static void wlc_phy_rxcal_physetup_nphy(phy_info_t *pi, u8 rx_core) +{ + u8 tx_core; + u16 rx_antval, tx_antval; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + tx_core = rx_core; + } else { + tx_core = (rx_core == PHY_CORE_0) ? 1 : 0; + } + + pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa2); + pi->tx_rx_cal_phy_saveregs[1] = + read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7); + pi->tx_rx_cal_phy_saveregs[2] = + read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5); + pi->tx_rx_cal_phy_saveregs[3] = read_phy_reg(pi, 0x91); + pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x92); + pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x7a); + pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x7d); + pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0xe7); + pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0xec); + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + pi->tx_rx_cal_phy_saveregs[11] = read_phy_reg(pi, 0x342); + pi->tx_rx_cal_phy_saveregs[12] = read_phy_reg(pi, 0x343); + pi->tx_rx_cal_phy_saveregs[13] = read_phy_reg(pi, 0x346); + pi->tx_rx_cal_phy_saveregs[14] = read_phy_reg(pi, 0x347); + } + + pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297); + pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b); + mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (0) << 0); + + mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (0) << 0); + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0); + + mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << (1 - rx_core)) << 12); + + } else { + + mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12); + mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0); + mod_phy_reg(pi, 0xa2, (0xf << 4), (1 << rx_core) << 4); + mod_phy_reg(pi, 0xa2, (0xf << 8), (1 << rx_core) << 8); + } + + mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7), (0x1 << 2), 0); + mod_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5, + (0x1 << 2), (0x1 << 2)); + if (NREV_LT(pi->pubpi.phy_rev, 7)) { + mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7), + (0x1 << 0) | (0x1 << 1), 0); + mod_phy_reg(pi, (rx_core == PHY_CORE_0) ? + 0x8f : 0xa5, + (0x1 << 0) | (0x1 << 1), (0x1 << 0) | (0x1 << 1)); + } + + wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 0, + RADIO_MIMO_CORESEL_CORE1 | + RADIO_MIMO_CORESEL_CORE2); + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), + 0, 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 0, 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 1, 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 1, 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID2); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + if (CHSPEC_IS40(pi->radio_chanspec)) { + wlc_phy_rfctrl_override_nphy_rev7(pi, + (0x1 << 7), + 2, 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + } else { + wlc_phy_rfctrl_override_nphy_rev7(pi, + (0x1 << 7), + 0, 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + } + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), + 0, 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + } else { + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 3, 0); + } + + wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX); + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + wlc_phy_rfctrlintc_override_nphy(pi, + NPHY_RfctrlIntc_override_TRSW, + 0x1, rx_core + 1); + } else { + + if (rx_core == PHY_CORE_0) { + rx_antval = 0x1; + tx_antval = 0x8; + } else { + rx_antval = 0x4; + tx_antval = 0x2; + } + + wlc_phy_rfctrlintc_override_nphy(pi, + NPHY_RfctrlIntc_override_TRSW, + rx_antval, rx_core + 1); + wlc_phy_rfctrlintc_override_nphy(pi, + NPHY_RfctrlIntc_override_TRSW, + tx_antval, tx_core + 1); + } +} + +static void wlc_phy_rxcal_phycleanup_nphy(phy_info_t *pi, u8 rx_core) +{ + + write_phy_reg(pi, 0xa2, pi->tx_rx_cal_phy_saveregs[0]); + write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7, + pi->tx_rx_cal_phy_saveregs[1]); + write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5, + pi->tx_rx_cal_phy_saveregs[2]); + write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[3]); + write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[4]); + + write_phy_reg(pi, 0x7a, pi->tx_rx_cal_phy_saveregs[5]); + write_phy_reg(pi, 0x7d, pi->tx_rx_cal_phy_saveregs[6]); + write_phy_reg(pi, 0xe7, pi->tx_rx_cal_phy_saveregs[7]); + write_phy_reg(pi, 0xec, pi->tx_rx_cal_phy_saveregs[8]); + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + write_phy_reg(pi, 0x342, pi->tx_rx_cal_phy_saveregs[11]); + write_phy_reg(pi, 0x343, pi->tx_rx_cal_phy_saveregs[12]); + write_phy_reg(pi, 0x346, pi->tx_rx_cal_phy_saveregs[13]); + write_phy_reg(pi, 0x347, pi->tx_rx_cal_phy_saveregs[14]); + } + + write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]); + write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]); +} + +static void +wlc_phy_rxcal_gainctrl_nphy_rev5(phy_info_t *pi, u8 rx_core, + u16 *rxgain, u8 cal_type) +{ + + u16 num_samps; + phy_iq_est_t est[PHY_CORE_MAX]; + u8 tx_core; + nphy_iq_comp_t save_comp, zero_comp; + u32 i_pwr, q_pwr, curr_pwr, optim_pwr = 0, prev_pwr = 0, thresh_pwr = + 10000; + s16 desired_log2_pwr, actual_log2_pwr, delta_pwr; + bool gainctrl_done = false; + u8 mix_tia_gain = 3; + s8 optim_gaintbl_index = 0, prev_gaintbl_index = 0; + s8 curr_gaintbl_index = 3; + u8 gainctrl_dirn = NPHY_RXCAL_GAIN_INIT; + nphy_ipa_txrxgain_t *nphy_rxcal_gaintbl; + u16 hpvga, lpf_biq1, lpf_biq0, lna2, lna1; + int fine_gain_idx; + s8 txpwrindex; + u16 nphy_rxcal_txgain[2]; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + tx_core = rx_core; + } else { + tx_core = 1 - rx_core; + } + + num_samps = 1024; + desired_log2_pwr = (cal_type == 0) ? 13 : 13; + + wlc_phy_rx_iq_coeffs_nphy(pi, 0, &save_comp); + zero_comp.a0 = zero_comp.b0 = zero_comp.a1 = zero_comp.b1 = 0x0; + wlc_phy_rx_iq_coeffs_nphy(pi, 1, &zero_comp); + + if (CHSPEC_IS5G(pi->radio_chanspec)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + mix_tia_gain = 3; + } else if (NREV_GE(pi->pubpi.phy_rev, 4)) { + mix_tia_gain = 4; + } else { + mix_tia_gain = 6; + } + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz_rev7; + } else { + nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz; + } + } else { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz_rev7; + } else { + nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz; + } + } + + do { + + hpvga = (NREV_GE(pi->pubpi.phy_rev, 7)) ? + 0 : nphy_rxcal_gaintbl[curr_gaintbl_index].hpvga; + lpf_biq1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq1; + lpf_biq0 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq0; + lna2 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna2; + lna1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna1; + txpwrindex = nphy_rxcal_gaintbl[curr_gaintbl_index].txpwrindex; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + wlc_phy_rfctrl_override_1tomany_nphy(pi, + NPHY_REV7_RfctrlOverride_cmd_rxgain, + ((lpf_biq1 << 12) | + (lpf_biq0 << 8) | + (mix_tia_gain << + 4) | (lna2 << 2) + | lna1), 0x3, 0); + } else { + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), + ((hpvga << 12) | + (lpf_biq1 << 10) | + (lpf_biq0 << 8) | + (mix_tia_gain << 4) | + (lna2 << 2) | lna1), 0x3, + 0); + } + + pi->nphy_rxcal_pwr_idx[tx_core] = txpwrindex; + + if (txpwrindex == -1) { + nphy_rxcal_txgain[0] = 0x8ff0 | pi->nphy_gmval; + nphy_rxcal_txgain[1] = 0x8ff0 | pi->nphy_gmval; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, + 2, 0x110, 16, + nphy_rxcal_txgain); + } else { + wlc_phy_txpwr_index_nphy(pi, tx_core + 1, txpwrindex, + false); + } + + wlc_phy_tx_tone_nphy(pi, (CHSPEC_IS40(pi->radio_chanspec)) ? + NPHY_RXCAL_TONEFREQ_40MHz : + NPHY_RXCAL_TONEFREQ_20MHz, + NPHY_RXCAL_TONEAMP, 0, cal_type, false); + + wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0); + i_pwr = (est[rx_core].i_pwr + num_samps / 2) / num_samps; + q_pwr = (est[rx_core].q_pwr + num_samps / 2) / num_samps; + curr_pwr = i_pwr + q_pwr; + + switch (gainctrl_dirn) { + case NPHY_RXCAL_GAIN_INIT: + if (curr_pwr > thresh_pwr) { + gainctrl_dirn = NPHY_RXCAL_GAIN_DOWN; + prev_gaintbl_index = curr_gaintbl_index; + curr_gaintbl_index--; + } else { + gainctrl_dirn = NPHY_RXCAL_GAIN_UP; + prev_gaintbl_index = curr_gaintbl_index; + curr_gaintbl_index++; + } + break; + + case NPHY_RXCAL_GAIN_UP: + if (curr_pwr > thresh_pwr) { + gainctrl_done = true; + optim_pwr = prev_pwr; + optim_gaintbl_index = prev_gaintbl_index; + } else { + prev_gaintbl_index = curr_gaintbl_index; + curr_gaintbl_index++; + } + break; + + case NPHY_RXCAL_GAIN_DOWN: + if (curr_pwr > thresh_pwr) { + prev_gaintbl_index = curr_gaintbl_index; + curr_gaintbl_index--; + } else { + gainctrl_done = true; + optim_pwr = curr_pwr; + optim_gaintbl_index = curr_gaintbl_index; + } + break; + + default: + ASSERT(0); + } + + if ((curr_gaintbl_index < 0) || + (curr_gaintbl_index > NPHY_IPA_RXCAL_MAXGAININDEX)) { + gainctrl_done = true; + optim_pwr = curr_pwr; + optim_gaintbl_index = prev_gaintbl_index; + } else { + prev_pwr = curr_pwr; + } + + wlc_phy_stopplayback_nphy(pi); + } while (!gainctrl_done); + + hpvga = nphy_rxcal_gaintbl[optim_gaintbl_index].hpvga; + lpf_biq1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq1; + lpf_biq0 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq0; + lna2 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna2; + lna1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna1; + txpwrindex = nphy_rxcal_gaintbl[optim_gaintbl_index].txpwrindex; + + actual_log2_pwr = wlc_phy_nbits(optim_pwr); + delta_pwr = desired_log2_pwr - actual_log2_pwr; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + fine_gain_idx = (int)lpf_biq1 + delta_pwr; + + if (fine_gain_idx + (int)lpf_biq0 > 10) { + lpf_biq1 = 10 - lpf_biq0; + } else { + lpf_biq1 = (u16) max(fine_gain_idx, 0); + } + wlc_phy_rfctrl_override_1tomany_nphy(pi, + NPHY_REV7_RfctrlOverride_cmd_rxgain, + ((lpf_biq1 << 12) | + (lpf_biq0 << 8) | + (mix_tia_gain << 4) | + (lna2 << 2) | lna1), 0x3, + 0); + } else { + hpvga = (u16) max(min(((int)hpvga) + delta_pwr, 10), 0); + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), + ((hpvga << 12) | (lpf_biq1 << 10) | + (lpf_biq0 << 8) | (mix_tia_gain << + 4) | (lna2 << + 2) | + lna1), 0x3, 0); + + } + + if (rxgain != NULL) { + *rxgain++ = lna1; + *rxgain++ = lna2; + *rxgain++ = mix_tia_gain; + *rxgain++ = lpf_biq0; + *rxgain++ = lpf_biq1; + *rxgain = hpvga; + } + + wlc_phy_rx_iq_coeffs_nphy(pi, 1, &save_comp); +} + +static void +wlc_phy_rxcal_gainctrl_nphy(phy_info_t *pi, u8 rx_core, u16 *rxgain, + u8 cal_type) +{ + wlc_phy_rxcal_gainctrl_nphy_rev5(pi, rx_core, rxgain, cal_type); +} + +static u8 +wlc_phy_rc_sweep_nphy(phy_info_t *pi, u8 core_idx, u8 loopback_type) +{ + u32 target_bws[2] = { 9500, 21000 }; + u32 ref_tones[2] = { 3000, 6000 }; + u32 target_bw, ref_tone; + + u32 target_pwr_ratios[2] = { 28606, 18468 }; + u32 target_pwr_ratio, pwr_ratio, last_pwr_ratio = 0; + + u16 start_rccal_ovr_val = 128; + u16 txlpf_rccal_lpc_ovr_val = 128; + u16 rxlpf_rccal_hpc_ovr_val = 159; + + u16 orig_txlpf_rccal_lpc_ovr_val; + u16 orig_rxlpf_rccal_hpc_ovr_val; + u16 radio_addr_offset_rx; + u16 radio_addr_offset_tx; + u16 orig_dcBypass; + u16 orig_RxStrnFilt40Num[6]; + u16 orig_RxStrnFilt40Den[4]; + u16 orig_rfctrloverride[2]; + u16 orig_rfctrlauxreg[2]; + u16 orig_rfctrlrssiothers; + u16 tx_lpf_bw = 4; + + u16 rx_lpf_bw, rx_lpf_bws[2] = { 2, 4 }; + u16 lpf_hpc = 7, hpvga_hpc = 7; + + s8 rccal_stepsize; + u16 rccal_val, last_rccal_val = 0, best_rccal_val = 0; + u32 ref_iq_vals = 0, target_iq_vals = 0; + u16 num_samps, log_num_samps = 10; + phy_iq_est_t est[PHY_CORE_MAX]; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + return 0; + } + + num_samps = (1 << log_num_samps); + + if (CHSPEC_IS40(pi->radio_chanspec)) { + target_bw = target_bws[1]; + target_pwr_ratio = target_pwr_ratios[1]; + ref_tone = ref_tones[1]; + rx_lpf_bw = rx_lpf_bws[1]; + } else { + target_bw = target_bws[0]; + target_pwr_ratio = target_pwr_ratios[0]; + ref_tone = ref_tones[0]; + rx_lpf_bw = rx_lpf_bws[0]; + } + + if (core_idx == 0) { + radio_addr_offset_rx = RADIO_2056_RX0; + radio_addr_offset_tx = + (loopback_type == 0) ? RADIO_2056_TX0 : RADIO_2056_TX1; + } else { + radio_addr_offset_rx = RADIO_2056_RX1; + radio_addr_offset_tx = + (loopback_type == 0) ? RADIO_2056_TX1 : RADIO_2056_TX0; + } + + orig_txlpf_rccal_lpc_ovr_val = + read_radio_reg(pi, + (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx)); + orig_rxlpf_rccal_hpc_ovr_val = + read_radio_reg(pi, + (RADIO_2056_RX_RXLPF_RCCAL_HPC | + radio_addr_offset_rx)); + + orig_dcBypass = ((read_phy_reg(pi, 0x48) >> 8) & 1); + + orig_RxStrnFilt40Num[0] = read_phy_reg(pi, 0x267); + orig_RxStrnFilt40Num[1] = read_phy_reg(pi, 0x268); + orig_RxStrnFilt40Num[2] = read_phy_reg(pi, 0x269); + orig_RxStrnFilt40Den[0] = read_phy_reg(pi, 0x26a); + orig_RxStrnFilt40Den[1] = read_phy_reg(pi, 0x26b); + orig_RxStrnFilt40Num[3] = read_phy_reg(pi, 0x26c); + orig_RxStrnFilt40Num[4] = read_phy_reg(pi, 0x26d); + orig_RxStrnFilt40Num[5] = read_phy_reg(pi, 0x26e); + orig_RxStrnFilt40Den[2] = read_phy_reg(pi, 0x26f); + orig_RxStrnFilt40Den[3] = read_phy_reg(pi, 0x270); + + orig_rfctrloverride[0] = read_phy_reg(pi, 0xe7); + orig_rfctrloverride[1] = read_phy_reg(pi, 0xec); + orig_rfctrlauxreg[0] = read_phy_reg(pi, 0xf8); + orig_rfctrlauxreg[1] = read_phy_reg(pi, 0xfa); + orig_rfctrlrssiothers = read_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d); + + write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx), + txlpf_rccal_lpc_ovr_val); + + write_radio_reg(pi, + (RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx), + rxlpf_rccal_hpc_ovr_val); + + mod_phy_reg(pi, 0x48, (0x1 << 8), (0x1 << 8)); + + write_phy_reg(pi, 0x267, 0x02d4); + write_phy_reg(pi, 0x268, 0x0000); + write_phy_reg(pi, 0x269, 0x0000); + write_phy_reg(pi, 0x26a, 0x0000); + write_phy_reg(pi, 0x26b, 0x0000); + write_phy_reg(pi, 0x26c, 0x02d4); + write_phy_reg(pi, 0x26d, 0x0000); + write_phy_reg(pi, 0x26e, 0x0000); + write_phy_reg(pi, 0x26f, 0x0000); + write_phy_reg(pi, 0x270, 0x0000); + + or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 8)); + or_phy_reg(pi, (core_idx == 0) ? 0xec : 0xe7, (0x1 << 15)); + or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 9)); + or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 10)); + + mod_phy_reg(pi, (core_idx == 0) ? 0xfa : 0xf8, + (0x7 << 10), (tx_lpf_bw << 10)); + mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa, + (0x7 << 0), (hpvga_hpc << 0)); + mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa, + (0x7 << 4), (lpf_hpc << 4)); + mod_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d, + (0x7 << 8), (rx_lpf_bw << 8)); + + rccal_stepsize = 16; + rccal_val = start_rccal_ovr_val + rccal_stepsize; + + while (rccal_stepsize >= 0) { + write_radio_reg(pi, + (RADIO_2056_RX_RXLPF_RCCAL_LPC | + radio_addr_offset_rx), rccal_val); + + if (rccal_stepsize == 16) { + + wlc_phy_tx_tone_nphy(pi, ref_tone, NPHY_RXCAL_TONEAMP, + 0, 1, false); + udelay(2); + + wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0); + + if (core_idx == 0) { + ref_iq_vals = + max_t(u32, (est[0].i_pwr + + est[0].q_pwr) >> (log_num_samps + 1), + 1); + } else { + ref_iq_vals = + max_t(u32, (est[1].i_pwr + + est[1].q_pwr) >> (log_num_samps + 1), + 1); + } + + wlc_phy_tx_tone_nphy(pi, target_bw, NPHY_RXCAL_TONEAMP, + 0, 1, false); + udelay(2); + } + + wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0); + + if (core_idx == 0) { + target_iq_vals = + (est[0].i_pwr + est[0].q_pwr) >> (log_num_samps + + 1); + } else { + target_iq_vals = + (est[1].i_pwr + est[1].q_pwr) >> (log_num_samps + + 1); + } + pwr_ratio = (uint) ((target_iq_vals << 16) / ref_iq_vals); + + if (rccal_stepsize == 0) { + rccal_stepsize--; + } else if (rccal_stepsize == 1) { + last_rccal_val = rccal_val; + rccal_val += (pwr_ratio > target_pwr_ratio) ? 1 : -1; + last_pwr_ratio = pwr_ratio; + rccal_stepsize--; + } else { + rccal_stepsize = (rccal_stepsize >> 1); + rccal_val += ((pwr_ratio > target_pwr_ratio) ? + rccal_stepsize : (-rccal_stepsize)); + } + + if (rccal_stepsize == -1) { + best_rccal_val = + (ABS((int)last_pwr_ratio - (int)target_pwr_ratio) < + ABS((int)pwr_ratio - + (int)target_pwr_ratio)) ? last_rccal_val : + rccal_val; + + if (CHSPEC_IS40(pi->radio_chanspec)) { + if ((best_rccal_val > 140) + || (best_rccal_val < 135)) { + best_rccal_val = 138; + } + } else { + if ((best_rccal_val > 142) + || (best_rccal_val < 137)) { + best_rccal_val = 140; + } + } + + write_radio_reg(pi, + (RADIO_2056_RX_RXLPF_RCCAL_LPC | + radio_addr_offset_rx), best_rccal_val); + } + } + + wlc_phy_stopplayback_nphy(pi); + + write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx), + orig_txlpf_rccal_lpc_ovr_val); + write_radio_reg(pi, + (RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx), + orig_rxlpf_rccal_hpc_ovr_val); + + mod_phy_reg(pi, 0x48, (0x1 << 8), (orig_dcBypass << 8)); + + write_phy_reg(pi, 0x267, orig_RxStrnFilt40Num[0]); + write_phy_reg(pi, 0x268, orig_RxStrnFilt40Num[1]); + write_phy_reg(pi, 0x269, orig_RxStrnFilt40Num[2]); + write_phy_reg(pi, 0x26a, orig_RxStrnFilt40Den[0]); + write_phy_reg(pi, 0x26b, orig_RxStrnFilt40Den[1]); + write_phy_reg(pi, 0x26c, orig_RxStrnFilt40Num[3]); + write_phy_reg(pi, 0x26d, orig_RxStrnFilt40Num[4]); + write_phy_reg(pi, 0x26e, orig_RxStrnFilt40Num[5]); + write_phy_reg(pi, 0x26f, orig_RxStrnFilt40Den[2]); + write_phy_reg(pi, 0x270, orig_RxStrnFilt40Den[3]); + + write_phy_reg(pi, 0xe7, orig_rfctrloverride[0]); + write_phy_reg(pi, 0xec, orig_rfctrloverride[1]); + write_phy_reg(pi, 0xf8, orig_rfctrlauxreg[0]); + write_phy_reg(pi, 0xfa, orig_rfctrlauxreg[1]); + write_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d, orig_rfctrlrssiothers); + + pi->nphy_anarxlpf_adjusted = false; + + return best_rccal_val - 0x80; +} + +#define WAIT_FOR_SCOPE 4000 +static int +wlc_phy_cal_rxiq_nphy_rev3(phy_info_t *pi, nphy_txgains_t target_gain, + u8 cal_type, bool debug) +{ + u16 orig_BBConfig; + u8 core_no, rx_core; + u8 best_rccal[2]; + u16 gain_save[2]; + u16 cal_gain[2]; + nphy_iqcal_params_t cal_params[2]; + u8 rxcore_state; + s8 rxlpf_rccal_hpc, txlpf_rccal_lpc; + s8 txlpf_idac; + bool phyhang_avoid_state = false; + bool skip_rxiqcal = false; + + orig_BBConfig = read_phy_reg(pi, 0x01); + mod_phy_reg(pi, 0x01, (0x1 << 15), 0); + + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + if (NREV_GE(pi->pubpi.phy_rev, 4)) { + phyhang_avoid_state = pi->phyhang_avoid; + pi->phyhang_avoid = false; + } + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save); + + for (core_no = 0; core_no <= 1; core_no++) { + wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain, + &cal_params[core_no]); + cal_gain[core_no] = cal_params[core_no].cal_gain; + } + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain); + + rxcore_state = wlc_phy_rxcore_getstate_nphy((wlc_phy_t *) pi); + + for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) { + + skip_rxiqcal = + ((rxcore_state & (1 << rx_core)) == 0) ? true : false; + + wlc_phy_rxcal_physetup_nphy(pi, rx_core); + + wlc_phy_rxcal_radio_setup_nphy(pi, rx_core); + + if ((!skip_rxiqcal) && ((cal_type == 0) || (cal_type == 2))) { + + wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL, 0); + + wlc_phy_tx_tone_nphy(pi, + (CHSPEC_IS40(pi->radio_chanspec)) ? + NPHY_RXCAL_TONEFREQ_40MHz : + NPHY_RXCAL_TONEFREQ_20MHz, + NPHY_RXCAL_TONEAMP, 0, cal_type, + false); + + if (debug) + mdelay(WAIT_FOR_SCOPE); + + wlc_phy_calc_rx_iq_comp_nphy(pi, rx_core + 1); + wlc_phy_stopplayback_nphy(pi); + } + + if (((cal_type == 1) || (cal_type == 2)) + && NREV_LT(pi->pubpi.phy_rev, 7)) { + + if (rx_core == PHY_CORE_1) { + + if (rxcore_state == 1) { + wlc_phy_rxcore_setstate_nphy((wlc_phy_t + *) pi, 3); + } + + wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL, + 1); + + best_rccal[rx_core] = + wlc_phy_rc_sweep_nphy(pi, rx_core, 1); + pi->nphy_rccal_value = best_rccal[rx_core]; + + if (rxcore_state == 1) { + wlc_phy_rxcore_setstate_nphy((wlc_phy_t + *) pi, + rxcore_state); + } + } + } + + wlc_phy_rxcal_radio_cleanup_nphy(pi, rx_core); + + wlc_phy_rxcal_phycleanup_nphy(pi, rx_core); + wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); + } + + if ((cal_type == 1) || (cal_type == 2)) { + + best_rccal[0] = best_rccal[1]; + write_radio_reg(pi, + (RADIO_2056_RX_RXLPF_RCCAL_LPC | + RADIO_2056_RX0), (best_rccal[0] | 0x80)); + + for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) { + rxlpf_rccal_hpc = + (((int)best_rccal[rx_core] - 12) >> 1) + 10; + txlpf_rccal_lpc = ((int)best_rccal[rx_core] - 12) + 10; + + if (PHY_IPA(pi)) { + txlpf_rccal_lpc += IS40MHZ(pi) ? 24 : 12; + txlpf_idac = IS40MHZ(pi) ? 0x0e : 0x13; + WRITE_RADIO_REG2(pi, RADIO_2056, TX, rx_core, + TXLPF_IDAC_4, txlpf_idac); + } + + rxlpf_rccal_hpc = max(min_t(u8, rxlpf_rccal_hpc, 31), 0); + txlpf_rccal_lpc = max(min_t(u8, txlpf_rccal_lpc, 31), 0); + + write_radio_reg(pi, (RADIO_2056_RX_RXLPF_RCCAL_HPC | + ((rx_core == + PHY_CORE_0) ? RADIO_2056_RX0 : + RADIO_2056_RX1)), + (rxlpf_rccal_hpc | 0x80)); + + write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | + ((rx_core == + PHY_CORE_0) ? RADIO_2056_TX0 : + RADIO_2056_TX1)), + (txlpf_rccal_lpc | 0x80)); + } + } + + write_phy_reg(pi, 0x01, orig_BBConfig); + + wlc_phy_resetcca_nphy(pi); + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + wlc_phy_rfctrl_override_1tomany_nphy(pi, + NPHY_REV7_RfctrlOverride_cmd_rxgain, + 0, 0x3, 1); + } else { + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1); + } + wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, + gain_save); + + if (NREV_GE(pi->pubpi.phy_rev, 4)) { + pi->phyhang_avoid = phyhang_avoid_state; + } + + wlc_phy_stay_in_carriersearch_nphy(pi, false); + + return BCME_OK; +} + +static int +wlc_phy_cal_rxiq_nphy_rev2(phy_info_t *pi, nphy_txgains_t target_gain, + bool debug) +{ + phy_iq_est_t est[PHY_CORE_MAX]; + u8 core_num, rx_core, tx_core; + u16 lna_vals[] = { 0x3, 0x3, 0x1 }; + u16 hpf1_vals[] = { 0x7, 0x2, 0x0 }; + u16 hpf2_vals[] = { 0x2, 0x0, 0x0 }; + s16 curr_hpf1, curr_hpf2, curr_hpf, curr_lna; + s16 desired_log2_pwr, actual_log2_pwr, hpf_change; + u16 orig_RfseqCoreActv, orig_AfectrlCore, orig_AfectrlOverride; + u16 orig_RfctrlIntcRx, orig_RfctrlIntcTx; + u16 num_samps; + u32 i_pwr, q_pwr, tot_pwr[3]; + u8 gain_pass, use_hpf_num; + u16 mask, val1, val2; + u16 core_no; + u16 gain_save[2]; + u16 cal_gain[2]; + nphy_iqcal_params_t cal_params[2]; + u8 phy_bw; + int bcmerror = BCME_OK; + bool first_playtone = true; + + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + if (NREV_LT(pi->pubpi.phy_rev, 2)) { + + wlc_phy_reapply_txcal_coeffs_nphy(pi); + } + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save); + + for (core_no = 0; core_no <= 1; core_no++) { + wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain, + &cal_params[core_no]); + cal_gain[core_no] = cal_params[core_no].cal_gain; + } + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain); + + num_samps = 1024; + desired_log2_pwr = 13; + + for (core_num = 0; core_num < 2; core_num++) { + + rx_core = core_num; + tx_core = 1 - core_num; + + orig_RfseqCoreActv = read_phy_reg(pi, 0xa2); + orig_AfectrlCore = read_phy_reg(pi, (rx_core == PHY_CORE_0) ? + 0xa6 : 0xa7); + orig_AfectrlOverride = read_phy_reg(pi, 0xa5); + orig_RfctrlIntcRx = read_phy_reg(pi, (rx_core == PHY_CORE_0) ? + 0x91 : 0x92); + orig_RfctrlIntcTx = read_phy_reg(pi, (tx_core == PHY_CORE_0) ? + 0x91 : 0x92); + + mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12); + mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0); + + or_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7), + ((0x1 << 1) | (0x1 << 2))); + or_phy_reg(pi, 0xa5, ((0x1 << 1) | (0x1 << 2))); + + if (((pi->nphy_rxcalparams) & 0xff000000)) { + + write_phy_reg(pi, + (rx_core == PHY_CORE_0) ? 0x91 : 0x92, + (CHSPEC_IS5G(pi->radio_chanspec) ? 0x140 : + 0x110)); + } else { + + write_phy_reg(pi, + (rx_core == PHY_CORE_0) ? 0x91 : 0x92, + (CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : + 0x120)); + } + + write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 : 0x92, + (CHSPEC_IS5G(pi->radio_chanspec) ? 0x148 : + 0x114)); + + mask = RADIO_2055_COUPLE_RX_MASK | RADIO_2055_COUPLE_TX_MASK; + if (rx_core == PHY_CORE_0) { + val1 = RADIO_2055_COUPLE_RX_MASK; + val2 = RADIO_2055_COUPLE_TX_MASK; + } else { + val1 = RADIO_2055_COUPLE_TX_MASK; + val2 = RADIO_2055_COUPLE_RX_MASK; + } + + if ((pi->nphy_rxcalparams & 0x10000)) { + mod_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, mask, + val1); + mod_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, mask, + val2); + } + + for (gain_pass = 0; gain_pass < 4; gain_pass++) { + + if (debug) + mdelay(WAIT_FOR_SCOPE); + + if (gain_pass < 3) { + curr_lna = lna_vals[gain_pass]; + curr_hpf1 = hpf1_vals[gain_pass]; + curr_hpf2 = hpf2_vals[gain_pass]; + } else { + + if (tot_pwr[1] > 10000) { + curr_lna = lna_vals[2]; + curr_hpf1 = hpf1_vals[2]; + curr_hpf2 = hpf2_vals[2]; + use_hpf_num = 1; + curr_hpf = curr_hpf1; + actual_log2_pwr = + wlc_phy_nbits(tot_pwr[2]); + } else { + if (tot_pwr[0] > 10000) { + curr_lna = lna_vals[1]; + curr_hpf1 = hpf1_vals[1]; + curr_hpf2 = hpf2_vals[1]; + use_hpf_num = 1; + curr_hpf = curr_hpf1; + actual_log2_pwr = + wlc_phy_nbits(tot_pwr[1]); + } else { + curr_lna = lna_vals[0]; + curr_hpf1 = hpf1_vals[0]; + curr_hpf2 = hpf2_vals[0]; + use_hpf_num = 2; + curr_hpf = curr_hpf2; + actual_log2_pwr = + wlc_phy_nbits(tot_pwr[0]); + } + } + + hpf_change = desired_log2_pwr - actual_log2_pwr; + curr_hpf += hpf_change; + curr_hpf = max(min_t(u16, curr_hpf, 10), 0); + if (use_hpf_num == 1) { + curr_hpf1 = curr_hpf; + } else { + curr_hpf2 = curr_hpf; + } + } + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10), + ((curr_hpf2 << 8) | + (curr_hpf1 << 4) | + (curr_lna << 2)), 0x3, 0); + wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); + + wlc_phy_stopplayback_nphy(pi); + + if (first_playtone) { + bcmerror = wlc_phy_tx_tone_nphy(pi, 4000, + (u16) (pi-> + nphy_rxcalparams + & + 0xffff), + 0, 0, true); + first_playtone = false; + } else { + phy_bw = + (CHSPEC_IS40(pi->radio_chanspec)) ? 40 : 20; + wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff, + 0, 0, 0, true); + } + + if (bcmerror == BCME_OK) { + if (gain_pass < 3) { + + wlc_phy_rx_iq_est_nphy(pi, est, + num_samps, 32, + 0); + i_pwr = + (est[rx_core].i_pwr + + num_samps / 2) / num_samps; + q_pwr = + (est[rx_core].q_pwr + + num_samps / 2) / num_samps; + tot_pwr[gain_pass] = i_pwr + q_pwr; + } else { + + wlc_phy_calc_rx_iq_comp_nphy(pi, + (1 << + rx_core)); + } + + wlc_phy_stopplayback_nphy(pi); + } + + if (bcmerror != BCME_OK) + break; + } + + and_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, ~mask); + and_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, ~mask); + + write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 : + 0x92, orig_RfctrlIntcTx); + write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x91 : + 0x92, orig_RfctrlIntcRx); + write_phy_reg(pi, 0xa5, orig_AfectrlOverride); + write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : + 0xa7, orig_AfectrlCore); + write_phy_reg(pi, 0xa2, orig_RfseqCoreActv); + + if (bcmerror != BCME_OK) + break; + } + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10), 0, 0x3, 1); + wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, + gain_save); + + wlc_phy_stay_in_carriersearch_nphy(pi, false); + + return bcmerror; +} + +int +wlc_phy_cal_rxiq_nphy(phy_info_t *pi, nphy_txgains_t target_gain, + u8 cal_type, bool debug) +{ + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + cal_type = 0; + } + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + return wlc_phy_cal_rxiq_nphy_rev3(pi, target_gain, cal_type, + debug); + } else { + return wlc_phy_cal_rxiq_nphy_rev2(pi, target_gain, debug); + } +} + +static void wlc_phy_extpa_set_tx_digi_filts_nphy(phy_info_t *pi) +{ + int j, type = 2; + u16 addr_offset = 0x2c5; + + for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { + write_phy_reg(pi, addr_offset + j, + NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]); + } +} + +static void wlc_phy_ipa_set_tx_digi_filts_nphy(phy_info_t *pi) +{ + int j, type; + u16 addr_offset[] = { 0x186, 0x195, + 0x2c5 + }; + + for (type = 0; type < 3; type++) { + for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { + write_phy_reg(pi, addr_offset[type] + j, + NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]); + } + } + + if (IS40MHZ(pi)) { + for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { + write_phy_reg(pi, 0x186 + j, + NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]); + } + } else { + if (CHSPEC_IS5G(pi->radio_chanspec)) { + for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { + write_phy_reg(pi, 0x186 + j, + NPHY_IPA_REV4_txdigi_filtcoeffs[5] + [j]); + } + } + + if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) { + for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { + write_phy_reg(pi, 0x2c5 + j, + NPHY_IPA_REV4_txdigi_filtcoeffs[6] + [j]); + } + } + } +} + +static void wlc_phy_ipa_restore_tx_digi_filts_nphy(phy_info_t *pi) +{ + int j; + + if (IS40MHZ(pi)) { + for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { + write_phy_reg(pi, 0x195 + j, + NPHY_IPA_REV4_txdigi_filtcoeffs[4][j]); + } + } else { + for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { + write_phy_reg(pi, 0x186 + j, + NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]); + } + } +} + +static u16 wlc_phy_ipa_get_bbmult_nphy(phy_info_t *pi) +{ + u16 m0m1; + + wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1); + + return m0m1; +} + +static void wlc_phy_ipa_set_bbmult_nphy(phy_info_t *pi, u8 m0, u8 m1) +{ + u16 m0m1 = (u16) ((m0 << 8) | m1); + + wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m0m1); + wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &m0m1); +} + +static u32 *wlc_phy_get_ipa_gaintbl_nphy(phy_info_t *pi) +{ + u32 *tx_pwrctrl_tbl = NULL; + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + if ((pi->pubpi.radiorev == 4) + || (pi->pubpi.radiorev == 6)) { + + tx_pwrctrl_tbl = + nphy_tpc_txgain_ipa_2g_2057rev4n6; + } else if (pi->pubpi.radiorev == 3) { + + tx_pwrctrl_tbl = + nphy_tpc_txgain_ipa_2g_2057rev3; + } else if (pi->pubpi.radiorev == 5) { + + tx_pwrctrl_tbl = + nphy_tpc_txgain_ipa_2g_2057rev5; + } else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) { + + tx_pwrctrl_tbl = + nphy_tpc_txgain_ipa_2g_2057rev7; + } else { + ASSERT(0); + } + + } else if (NREV_IS(pi->pubpi.phy_rev, 6)) { + + tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev6; + if (pi->sh->chip == BCM47162_CHIP_ID) { + + tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5; + } + + } else if (NREV_IS(pi->pubpi.phy_rev, 5)) { + + tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5; + } else { + + tx_pwrctrl_tbl = nphy_tpc_txgain_ipa; + } + + } else { + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if ((pi->pubpi.radiorev == 3) || + (pi->pubpi.radiorev == 4) || + (pi->pubpi.radiorev == 6)) { + + tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g_2057; + } else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) { + + tx_pwrctrl_tbl = + nphy_tpc_txgain_ipa_5g_2057rev7; + } else { + ASSERT(0); + } + + } else { + tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g; + } + } + + return tx_pwrctrl_tbl; +} + +static void +wlc_phy_papd_cal_setup_nphy(phy_info_t *pi, nphy_papd_restore_state *state, + u8 core) +{ + s32 tone_freq; + u8 off_core; + u16 mixgain = 0; + + off_core = core ^ 0x1; + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + if (NREV_IS(pi->pubpi.phy_rev, 7) + || NREV_GE(pi->pubpi.phy_rev, 8)) { + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), + wlc_phy_read_lpf_bw_ctl_nphy + (pi, 0), 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + } + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (pi->pubpi.radiorev == 5) { + mixgain = (core == 0) ? 0x20 : 0x00; + + } else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) { + + mixgain = 0x00; + + } else if ((pi->pubpi.radiorev <= 4) + || (pi->pubpi.radiorev == 6)) { + + mixgain = 0x00; + } else { + ASSERT(0); + } + + } else { + if ((pi->pubpi.radiorev == 4) || + (pi->pubpi.radiorev == 6)) { + + mixgain = 0x50; + } else if ((pi->pubpi.radiorev == 3) + || (pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) { + + mixgain = 0x0; + } else { + ASSERT(0); + } + } + + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), + mixgain, (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + + wlc_phy_rfctrl_override_1tomany_nphy(pi, + NPHY_REV7_RfctrlOverride_cmd_tx_pu, + 1, (1 << core), 0); + wlc_phy_rfctrl_override_1tomany_nphy(pi, + NPHY_REV7_RfctrlOverride_cmd_tx_pu, + 0, (1 << off_core), 0); + + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), + 0, 0x3, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1, + (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, + (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, + (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID2); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0, + (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1, + (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0, + (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1, + (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), + 0, (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0, + (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + + state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ? + 0xa6 : 0xa7); + state->afeoverride[core] = + read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5); + state->afectrl[off_core] = + read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa7 : 0xa6); + state->afeoverride[off_core] = + read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa5 : 0x8f); + + mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7), + (0x1 << 2), 0); + mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f : + 0xa5), (0x1 << 2), (0x1 << 2)); + + mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa7 : 0xa6), + (0x1 << 2), (0x1 << 2)); + mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa5 : + 0x8f), (0x1 << 2), (0x1 << 2)); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + state->pwrup[core] = + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_2G_PWRUP); + state->atten[core] = + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_2G_ATTEN); + state->pwrup[off_core] = + READ_RADIO_REG3(pi, RADIO_2057, TX, off_core, + TXRXCOUPLE_2G_PWRUP); + state->atten[off_core] = + READ_RADIO_REG3(pi, RADIO_2057, TX, off_core, + TXRXCOUPLE_2G_ATTEN); + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_2G_PWRUP, 0xc); + + if ((pi->pubpi.radiorev == 3) || + (pi->pubpi.radiorev == 4) || + (pi->pubpi.radiorev == 6)) { + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_2G_ATTEN, 0xf0); + + } else if (pi->pubpi.radiorev == 5) { + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_2G_ATTEN, + (core == 0) ? 0xf7 : 0xf2); + + } else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) { + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_2G_ATTEN, 0xf0); + + } else { + ASSERT(0); + } + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core, + TXRXCOUPLE_2G_PWRUP, 0x0); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core, + TXRXCOUPLE_2G_ATTEN, 0xff); + + } else { + state->pwrup[core] = + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_5G_PWRUP); + state->atten[core] = + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_5G_ATTEN); + state->pwrup[off_core] = + READ_RADIO_REG3(pi, RADIO_2057, TX, off_core, + TXRXCOUPLE_5G_PWRUP); + state->atten[off_core] = + READ_RADIO_REG3(pi, RADIO_2057, TX, off_core, + TXRXCOUPLE_5G_ATTEN); + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_5G_PWRUP, 0xc); + + if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) { + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_5G_ATTEN, 0xf4); + + } else { + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_5G_ATTEN, 0xf0); + } + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core, + TXRXCOUPLE_5G_PWRUP, 0x0); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core, + TXRXCOUPLE_5G_ATTEN, 0xff); + } + + tone_freq = 4000; + + wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 13), (1) << 13); + + mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_OFF) << 0); + + mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 13), (0) << 13); + + } else { + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 0); + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0, 0); + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 0); + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 1, 0x3, 0); + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0x3, 0); + + state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ? + 0xa6 : 0xa7); + state->afeoverride[core] = + read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5); + + mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7), + (0x1 << 0) | (0x1 << 1) | (0x1 << 2), 0); + mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f : + 0xa5), + (0x1 << 0) | + (0x1 << 1) | + (0x1 << 2), (0x1 << 0) | (0x1 << 1) | (0x1 << 2)); + + state->vga_master[core] = + READ_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER); + WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER, 0x2b); + if (CHSPEC_IS2G(pi->radio_chanspec)) { + state->fbmix[core] = + READ_RADIO_REG2(pi, RADIO_2056, RX, core, + TXFBMIX_G); + state->intpa_master[core] = + READ_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAG_MASTER); + + WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_G, + 0x03); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAG_MASTER, 0x04); + } else { + state->fbmix[core] = + READ_RADIO_REG2(pi, RADIO_2056, RX, core, + TXFBMIX_A); + state->intpa_master[core] = + READ_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAA_MASTER); + + WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_A, + 0x03); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAA_MASTER, 0x04); + + } + + tone_freq = 4000; + + wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (1) << 0); + + mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (0) << 0); + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0); + } +} + +static void +wlc_phy_papd_cal_cleanup_nphy(phy_info_t *pi, nphy_papd_restore_state *state) +{ + u8 core; + + wlc_phy_stopplayback_nphy(pi); + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_2G_PWRUP, 0); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_2G_ATTEN, + state->atten[core]); + } else { + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_5G_PWRUP, 0); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_5G_ATTEN, + state->atten[core]); + } + } + + if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6)) { + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), + 1, 0x3, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + } else { + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), + 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + } + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), + 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID2); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID2); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 1, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID2); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + + write_phy_reg(pi, (core == PHY_CORE_0) ? + 0xa6 : 0xa7, state->afectrl[core]); + write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : + 0xa5, state->afeoverride[core]); + } + + wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff, + (state->mm & 0xff)); + + if (NREV_IS(pi->pubpi.phy_rev, 7) + || NREV_GE(pi->pubpi.phy_rev, 8)) { + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), 0, 0, + 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + } + } else { + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1); + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 0x3, 1); + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 1); + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 0, 0x3, 1); + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 0, 0x3, 1); + + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + + WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER, + state->vga_master[core]); + if (CHSPEC_IS2G(pi->radio_chanspec)) { + WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, + TXFBMIX_G, state->fbmix[core]); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAG_MASTER, + state->intpa_master[core]); + } else { + WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, + TXFBMIX_A, state->fbmix[core]); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAA_MASTER, + state->intpa_master[core]); + } + + write_phy_reg(pi, (core == PHY_CORE_0) ? + 0xa6 : 0xa7, state->afectrl[core]); + write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : + 0xa5, state->afeoverride[core]); + } + + wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff, + (state->mm & 0xff)); + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 1); + } +} + +static void +wlc_phy_a1_nphy(phy_info_t *pi, u8 core, u32 winsz, u32 start, + u32 end) +{ + u32 *buf, *src, *dst, sz; + + sz = end - start + 1; + ASSERT(end > start); + ASSERT(end < NPHY_PAPD_EPS_TBL_SIZE); + + buf = kmalloc(2 * sizeof(u32) * NPHY_PAPD_EPS_TBL_SIZE, GFP_ATOMIC); + if (NULL == buf) { + return; + } + + src = buf; + dst = buf + NPHY_PAPD_EPS_TBL_SIZE; + + wlc_phy_table_read_nphy(pi, + (core == + PHY_CORE_0 ? NPHY_TBL_ID_EPSILONTBL0 : + NPHY_TBL_ID_EPSILONTBL1), + NPHY_PAPD_EPS_TBL_SIZE, 0, 32, src); + + do { + u32 phy_a1, phy_a2; + s32 phy_a3, phy_a4, phy_a5, phy_a6, phy_a7; + + phy_a1 = end - min(end, (winsz >> 1)); + phy_a2 = min_t(u32, NPHY_PAPD_EPS_TBL_SIZE - 1, end + (winsz >> 1)); + phy_a3 = phy_a2 - phy_a1 + 1; + phy_a6 = 0; + phy_a7 = 0; + + do { + wlc_phy_papd_decode_epsilon(src[phy_a2], &phy_a4, + &phy_a5); + phy_a6 += phy_a4; + phy_a7 += phy_a5; + } while (phy_a2-- != phy_a1); + + phy_a6 /= phy_a3; + phy_a7 /= phy_a3; + dst[end] = ((u32) phy_a7 << 13) | ((u32) phy_a6 & 0x1fff); + } while (end-- != start); + + wlc_phy_table_write_nphy(pi, + (core == + PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 : + NPHY_TBL_ID_EPSILONTBL1, sz, start, 32, dst); + + kfree(buf); +} + +static void +wlc_phy_a2_nphy(phy_info_t *pi, nphy_ipa_txcalgains_t *txgains, + phy_cal_mode_t cal_mode, u8 core) +{ + u16 phy_a1, phy_a2, phy_a3; + u16 phy_a4, phy_a5; + bool phy_a6; + u8 phy_a7, m[2]; + u32 phy_a8 = 0; + nphy_txgains_t phy_a9; + + if (NREV_LT(pi->pubpi.phy_rev, 3)) + return; + + phy_a7 = (core == PHY_CORE_0) ? 1 : 0; + + ASSERT((cal_mode == CAL_FULL) || (cal_mode == CAL_GCTRL) + || (cal_mode == CAL_SOFT)); + phy_a6 = ((cal_mode == CAL_GCTRL) + || (cal_mode == CAL_SOFT)) ? true : false; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + phy_a9 = wlc_phy_get_tx_gain_nphy(pi); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + phy_a5 = ((phy_a9.txlpf[core] << 15) | + (phy_a9.txgm[core] << 12) | + (phy_a9.pga[core] << 8) | + (txgains->gains.pad[core] << 3) | + (phy_a9.ipa[core])); + } else { + phy_a5 = ((phy_a9.txlpf[core] << 15) | + (phy_a9.txgm[core] << 12) | + (txgains->gains.pga[core] << 8) | + (phy_a9.pad[core] << 3) | (phy_a9.ipa[core])); + } + + wlc_phy_rfctrl_override_1tomany_nphy(pi, + NPHY_REV7_RfctrlOverride_cmd_txgain, + phy_a5, (1 << core), 0); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if ((pi->pubpi.radiorev <= 4) + || (pi->pubpi.radiorev == 6)) { + + m[core] = IS40MHZ(pi) ? 60 : 79; + } else { + + m[core] = IS40MHZ(pi) ? 45 : 64; + } + + } else { + m[core] = IS40MHZ(pi) ? 75 : 107; + } + + m[phy_a7] = 0; + wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]); + + phy_a2 = 63; + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (pi->sh->chip == BCM6362_CHIP_ID) { + phy_a1 = 35; + phy_a3 = 35; + } else if ((pi->pubpi.radiorev == 4) + || (pi->pubpi.radiorev == 6)) { + phy_a1 = 30; + phy_a3 = 30; + } else { + phy_a1 = 25; + phy_a3 = 25; + } + } else { + if ((pi->pubpi.radiorev == 5) + || (pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) { + phy_a1 = 25; + phy_a3 = 25; + } else { + phy_a1 = 35; + phy_a3 = 35; + } + } + + if (cal_mode == CAL_GCTRL) { + if ((pi->pubpi.radiorev == 5) + && (CHSPEC_IS2G(pi->radio_chanspec))) { + phy_a1 = 55; + } else if (((pi->pubpi.radiorev == 7) && + (CHSPEC_IS2G(pi->radio_chanspec))) || + ((pi->pubpi.radiorev == 8) && + (CHSPEC_IS2G(pi->radio_chanspec)))) { + phy_a1 = 60; + } else { + phy_a1 = 63; + } + + } else if ((cal_mode != CAL_FULL) && (cal_mode != CAL_SOFT)) { + + phy_a1 = 35; + phy_a3 = 35; + } + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (1) << 0); + + mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (0) << 0); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 13), (1) << 13); + + mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 13), (0) << 13); + + write_phy_reg(pi, 0x2a1, 0x80); + write_phy_reg(pi, 0x2a2, 0x100); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x7 << 4), (11) << 4); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x7 << 8), (11) << 8); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x7 << 0), (0x3) << 0); + + write_phy_reg(pi, 0x2e5, 0x20); + + mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0); + + mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0); + + mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8); + + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), + 1, ((core == 0) ? 1 : 2), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), + 0, ((core == 0) ? 2 : 1), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + + write_phy_reg(pi, 0x2be, 1); + SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000); + + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), + 0, 0x3, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + + wlc_phy_table_write_nphy(pi, + (core == + PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 + : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3, + 32, &phy_a8); + + if (cal_mode != CAL_GCTRL) { + if (CHSPEC_IS5G(pi->radio_chanspec)) { + wlc_phy_a1_nphy(pi, core, 5, 0, 35); + } + } + + wlc_phy_rfctrl_override_1tomany_nphy(pi, + NPHY_REV7_RfctrlOverride_cmd_txgain, + phy_a5, (1 << core), 1); + + } else { + + if (txgains) { + if (txgains->useindex) { + phy_a4 = 15 - ((txgains->index) >> 3); + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (NREV_GE(pi->pubpi.phy_rev, 6)) { + phy_a5 = 0x00f7 | (phy_a4 << 8); + + if (pi->sh->chip == + BCM47162_CHIP_ID) { + phy_a5 = + 0x10f7 | (phy_a4 << + 8); + } + } else + if (NREV_IS(pi->pubpi.phy_rev, 5)) + phy_a5 = 0x10f7 | (phy_a4 << 8); + else + phy_a5 = 0x50f7 | (phy_a4 << 8); + } else { + phy_a5 = 0x70f7 | (phy_a4 << 8); + } + wlc_phy_rfctrl_override_nphy(pi, + (0x1 << 13), + phy_a5, + (1 << core), 0); + } else { + wlc_phy_rfctrl_override_nphy(pi, + (0x1 << 13), + 0x5bf7, + (1 << core), 0); + } + } + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + m[core] = IS40MHZ(pi) ? 45 : 64; + } else { + m[core] = IS40MHZ(pi) ? 75 : 107; + } + + m[phy_a7] = 0; + wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]); + + phy_a2 = 63; + + if (cal_mode == CAL_FULL) { + phy_a1 = 25; + phy_a3 = 25; + } else if (cal_mode == CAL_SOFT) { + phy_a1 = 25; + phy_a3 = 25; + } else if (cal_mode == CAL_GCTRL) { + phy_a1 = 63; + phy_a3 = 25; + } else { + + phy_a1 = 25; + phy_a3 = 25; + } + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (1) << 0); + + mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (0) << 0); + + if (NREV_GE(pi->pubpi.phy_rev, 6)) { + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 13), (1) << 13); + + mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 13), (0) << 13); + + write_phy_reg(pi, 0x2a1, 0x20); + write_phy_reg(pi, 0x2a2, 0x60); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0xf << 4), (9) << 4); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0xf << 8), (9) << 8); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0xf << 0), (0x2) << 0); + + write_phy_reg(pi, 0x2e5, 0x20); + } else { + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 11), (1) << 11); + + mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 11), (0) << 11); + + write_phy_reg(pi, 0x2a1, 0x80); + write_phy_reg(pi, 0x2a2, 0x600); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x7 << 4), (0) << 4); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x7 << 8), (0) << 8); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x7 << 0), (0x3) << 0); + + mod_phy_reg(pi, 0x2a0, (0x3f << 8), (0x20) << 8); + + } + + mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0); + + mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0); + + mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8); + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0x3, 0); + + write_phy_reg(pi, 0x2be, 1); + SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000); + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0); + + wlc_phy_table_write_nphy(pi, + (core == + PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 + : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3, + 32, &phy_a8); + + if (cal_mode != CAL_GCTRL) { + wlc_phy_a1_nphy(pi, core, 5, 0, 40); + } + } +} + +static u8 wlc_phy_a3_nphy(phy_info_t *pi, u8 start_gain, u8 core) +{ + int phy_a1; + int phy_a2; + bool phy_a3; + nphy_ipa_txcalgains_t phy_a4; + bool phy_a5 = false; + bool phy_a6 = true; + s32 phy_a7, phy_a8; + u32 phy_a9; + int phy_a10; + bool phy_a11 = false; + int phy_a12; + u8 phy_a13 = 0; + u8 phy_a14; + u8 *phy_a15 = NULL; + + phy_a4.useindex = true; + phy_a12 = start_gain; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + phy_a2 = 20; + phy_a1 = 1; + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (pi->pubpi.radiorev == 5) { + + phy_a15 = pad_gain_codes_used_2057rev5; + phy_a13 = sizeof(pad_gain_codes_used_2057rev5) / + sizeof(pad_gain_codes_used_2057rev5[0]) - 1; + + } else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) { + + phy_a15 = pad_gain_codes_used_2057rev7; + phy_a13 = sizeof(pad_gain_codes_used_2057rev7) / + sizeof(pad_gain_codes_used_2057rev7[0]) - 1; + + } else { + + phy_a15 = pad_all_gain_codes_2057; + phy_a13 = sizeof(pad_all_gain_codes_2057) / + sizeof(pad_all_gain_codes_2057[0]) - 1; + } + + } else { + + phy_a15 = pga_all_gain_codes_2057; + phy_a13 = sizeof(pga_all_gain_codes_2057) / + sizeof(pga_all_gain_codes_2057[0]) - 1; + } + + phy_a14 = 0; + + for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) { + if (CHSPEC_IS2G(pi->radio_chanspec)) { + phy_a4.gains.pad[core] = + (u16) phy_a15[phy_a12]; + } else { + phy_a4.gains.pga[core] = + (u16) phy_a15[phy_a12]; + } + + wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core); + + wlc_phy_table_read_nphy(pi, + (core == + PHY_CORE_0 ? + NPHY_TBL_ID_EPSILONTBL0 : + NPHY_TBL_ID_EPSILONTBL1), 1, + 63, 32, &phy_a9); + + wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8); + + phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) || + (phy_a8 == 4095) || (phy_a8 == -4096)); + + if (!phy_a6 && (phy_a3 != phy_a5)) { + if (!phy_a3) { + phy_a12 -= (u8) phy_a1; + } + phy_a11 = true; + break; + } + + if (phy_a3) + phy_a12 += (u8) phy_a1; + else + phy_a12 -= (u8) phy_a1; + + if ((phy_a12 < phy_a14) || (phy_a12 > phy_a13)) { + if (phy_a12 < phy_a14) { + phy_a12 = phy_a14; + } else { + phy_a12 = phy_a13; + } + phy_a11 = true; + break; + } + + phy_a6 = false; + phy_a5 = phy_a3; + } + + } else { + phy_a2 = 10; + phy_a1 = 8; + for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) { + phy_a4.index = (u8) phy_a12; + wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core); + + wlc_phy_table_read_nphy(pi, + (core == + PHY_CORE_0 ? + NPHY_TBL_ID_EPSILONTBL0 : + NPHY_TBL_ID_EPSILONTBL1), 1, + 63, 32, &phy_a9); + + wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8); + + phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) || + (phy_a8 == 4095) || (phy_a8 == -4096)); + + if (!phy_a6 && (phy_a3 != phy_a5)) { + if (!phy_a3) { + phy_a12 -= (u8) phy_a1; + } + phy_a11 = true; + break; + } + + if (phy_a3) + phy_a12 += (u8) phy_a1; + else + phy_a12 -= (u8) phy_a1; + + if ((phy_a12 < 0) || (phy_a12 > 127)) { + if (phy_a12 < 0) { + phy_a12 = 0; + } else { + phy_a12 = 127; + } + phy_a11 = true; + break; + } + + phy_a6 = false; + phy_a5 = phy_a3; + } + + } + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + return (u8) phy_a15[phy_a12]; + } else { + return (u8) phy_a12; + } + +} + +static void wlc_phy_a4(phy_info_t *pi, bool full_cal) +{ + nphy_ipa_txcalgains_t phy_b1[2]; + nphy_papd_restore_state phy_b2; + bool phy_b3; + u8 phy_b4; + u8 phy_b5; + s16 phy_b6, phy_b7, phy_b8; + u16 phy_b9; + s16 phy_b10, phy_b11, phy_b12; + + phy_b11 = 0; + phy_b12 = 0; + phy_b7 = 0; + phy_b8 = 0; + phy_b6 = 0; + + if (pi->nphy_papd_skip == 1) + return; + + phy_b3 = + (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + if (!phy_b3) { + wlapi_suspend_mac_and_wait(pi->sh->physhim); + } + + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + pi->nphy_force_papd_cal = false; + + for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) + pi->nphy_papd_tx_gain_at_last_cal[phy_b5] = + wlc_phy_txpwr_idx_cur_get_nphy(pi, phy_b5); + + pi->nphy_papd_last_cal = pi->sh->now; + pi->nphy_papd_recal_counter++; + + if (NORADIO_ENAB(pi->pubpi)) + return; + + phy_b4 = pi->nphy_txpwrctrl; + wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL0, 64, 0, 32, + nphy_papd_scaltbl); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL1, 64, 0, 32, + nphy_papd_scaltbl); + + phy_b9 = read_phy_reg(pi, 0x01); + mod_phy_reg(pi, 0x01, (0x1 << 15), 0); + + for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) { + s32 i, val = 0; + for (i = 0; i < 64; i++) { + wlc_phy_table_write_nphy(pi, + ((phy_b5 == + PHY_CORE_0) ? + NPHY_TBL_ID_EPSILONTBL0 : + NPHY_TBL_ID_EPSILONTBL1), 1, + i, 32, &val); + } + } + + wlc_phy_ipa_restore_tx_digi_filts_nphy(pi); + + phy_b2.mm = wlc_phy_ipa_get_bbmult_nphy(pi); + for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) { + wlc_phy_papd_cal_setup_nphy(pi, &phy_b2, phy_b5); + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (CHSPEC_IS2G(pi->radio_chanspec)) { + + if ((pi->pubpi.radiorev == 3) + || (pi->pubpi.radiorev == 4) + || (pi->pubpi.radiorev == 6)) { + + pi->nphy_papd_cal_gain_index[phy_b5] = + 23; + + } else if (pi->pubpi.radiorev == 5) { + + pi->nphy_papd_cal_gain_index[phy_b5] = + 0; + pi->nphy_papd_cal_gain_index[phy_b5] = + wlc_phy_a3_nphy(pi, + pi-> + nphy_papd_cal_gain_index + [phy_b5], phy_b5); + + } else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) { + + pi->nphy_papd_cal_gain_index[phy_b5] = + 0; + pi->nphy_papd_cal_gain_index[phy_b5] = + wlc_phy_a3_nphy(pi, + pi-> + nphy_papd_cal_gain_index + [phy_b5], phy_b5); + + } else { + ASSERT(0); + } + + phy_b1[phy_b5].gains.pad[phy_b5] = + pi->nphy_papd_cal_gain_index[phy_b5]; + + } else { + pi->nphy_papd_cal_gain_index[phy_b5] = 0; + pi->nphy_papd_cal_gain_index[phy_b5] = + wlc_phy_a3_nphy(pi, + pi-> + nphy_papd_cal_gain_index + [phy_b5], phy_b5); + phy_b1[phy_b5].gains.pga[phy_b5] = + pi->nphy_papd_cal_gain_index[phy_b5]; + } + } else { + phy_b1[phy_b5].useindex = true; + phy_b1[phy_b5].index = 16; + phy_b1[phy_b5].index = + wlc_phy_a3_nphy(pi, phy_b1[phy_b5].index, phy_b5); + + pi->nphy_papd_cal_gain_index[phy_b5] = + 15 - ((phy_b1[phy_b5].index) >> 3); + } + + switch (pi->nphy_papd_cal_type) { + case 0: + wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_FULL, phy_b5); + break; + case 1: + wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_SOFT, phy_b5); + break; + } + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2); + } + } + + if (NREV_LT(pi->pubpi.phy_rev, 7)) { + wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2); + } + + for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) { + int eps_offset = 0; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (pi->pubpi.radiorev == 3) { + eps_offset = -2; + } else if (pi->pubpi.radiorev == 5) { + eps_offset = 3; + } else { + eps_offset = -1; + } + } else { + eps_offset = 2; + } + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + phy_b8 = phy_b1[phy_b5].gains.pad[phy_b5]; + phy_b10 = 0; + if ((pi->pubpi.radiorev == 3) || + (pi->pubpi.radiorev == 4) || + (pi->pubpi.radiorev == 6)) { + phy_b12 = + - + (nphy_papd_padgain_dlt_2g_2057rev3n4 + [phy_b8] + + 1) / 2; + phy_b10 = -1; + } else if (pi->pubpi.radiorev == 5) { + phy_b12 = + -(nphy_papd_padgain_dlt_2g_2057rev5 + [phy_b8] + + 1) / 2; + } else if ((pi->pubpi.radiorev == 7) || + (pi->pubpi.radiorev == 8)) { + phy_b12 = + -(nphy_papd_padgain_dlt_2g_2057rev7 + [phy_b8] + + 1) / 2; + } else { + ASSERT(0); + } + } else { + phy_b7 = phy_b1[phy_b5].gains.pga[phy_b5]; + if ((pi->pubpi.radiorev == 3) || + (pi->pubpi.radiorev == 4) || + (pi->pubpi.radiorev == 6)) { + phy_b11 = + -(nphy_papd_pgagain_dlt_5g_2057 + [phy_b7] + + 1) / 2; + } else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) { + phy_b11 = + -(nphy_papd_pgagain_dlt_5g_2057rev7 + [phy_b7] + + 1) / 2; + } else { + ASSERT(0); + } + + phy_b10 = -9; + } + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + phy_b6 = + -60 + 27 + eps_offset + phy_b12 + phy_b10; + } else { + phy_b6 = + -60 + 27 + eps_offset + phy_b11 + phy_b10; + } + + mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 : + 0x29c, (0x1ff << 7), (phy_b6) << 7); + + pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6; + } else { + if (NREV_LT(pi->pubpi.phy_rev, 5)) { + eps_offset = 4; + } else { + eps_offset = 2; + } + + phy_b7 = 15 - ((phy_b1[phy_b5].index) >> 3); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + phy_b11 = + -(nphy_papd_pga_gain_delta_ipa_2g[phy_b7] + + 1) / 2; + phy_b10 = 0; + } else { + phy_b11 = + -(nphy_papd_pga_gain_delta_ipa_5g[phy_b7] + + 1) / 2; + phy_b10 = -9; + } + + phy_b6 = -60 + 27 + eps_offset + phy_b11 + phy_b10; + + mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 : + 0x29c, (0x1ff << 7), (phy_b6) << 7); + + pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6; + } + } + + mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0); + + mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0); + + if (NREV_GE(pi->pubpi.phy_rev, 6)) { + mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 13), (0) << 13); + + mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 13), (0) << 13); + + } else { + mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 11), (0) << 11); + + mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 11), (0) << 11); + + } + pi->nphy_papdcomp = NPHY_PAPD_COMP_ON; + + write_phy_reg(pi, 0x01, phy_b9); + + wlc_phy_ipa_set_tx_digi_filts_nphy(pi); + + wlc_phy_txpwrctrl_enable_nphy(pi, phy_b4); + if (phy_b4 == PHY_TPC_HW_OFF) { + wlc_phy_txpwr_index_nphy(pi, (1 << 0), + (s8) (pi->nphy_txpwrindex[0]. + index_internal), false); + wlc_phy_txpwr_index_nphy(pi, (1 << 1), + (s8) (pi->nphy_txpwrindex[1]. + index_internal), false); + } + + wlc_phy_stay_in_carriersearch_nphy(pi, false); + + if (!phy_b3) { + wlapi_enable_mac(pi->sh->physhim); + } +} + +void wlc_phy_txpwr_fixpower_nphy(phy_info_t *pi) +{ + uint core; + u32 txgain; + u16 rad_gain, dac_gain, bbmult, m1m2; + u8 txpi[2], chan_freq_range; + s32 rfpwr_offset; + + ASSERT(pi->nphy_txpwrctrl == PHY_TPC_HW_OFF); + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + if (pi->sh->sromrev < 4) { + txpi[0] = txpi[1] = 72; + } else { + + chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0); + switch (chan_freq_range) { + case WL_CHAN_FREQ_RANGE_2G: + txpi[0] = pi->nphy_txpid2g[0]; + txpi[1] = pi->nphy_txpid2g[1]; + break; + case WL_CHAN_FREQ_RANGE_5GL: + txpi[0] = pi->nphy_txpid5gl[0]; + txpi[1] = pi->nphy_txpid5gl[1]; + break; + case WL_CHAN_FREQ_RANGE_5GM: + txpi[0] = pi->nphy_txpid5g[0]; + txpi[1] = pi->nphy_txpid5g[1]; + break; + case WL_CHAN_FREQ_RANGE_5GH: + txpi[0] = pi->nphy_txpid5gh[0]; + txpi[1] = pi->nphy_txpid5gh[1]; + break; + default: + txpi[0] = txpi[1] = 91; + break; + } + } + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + txpi[0] = txpi[1] = 30; + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + txpi[0] = txpi[1] = 40; + } + + if (NREV_LT(pi->pubpi.phy_rev, 7)) { + + if ((txpi[0] < 40) || (txpi[0] > 100) || + (txpi[1] < 40) || (txpi[1] > 100)) + txpi[0] = txpi[1] = 91; + } + + pi->nphy_txpwrindex[PHY_CORE_0].index_internal = txpi[0]; + pi->nphy_txpwrindex[PHY_CORE_1].index_internal = txpi[1]; + pi->nphy_txpwrindex[PHY_CORE_0].index_internal_save = txpi[0]; + pi->nphy_txpwrindex[PHY_CORE_1].index_internal_save = txpi[1]; + + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (PHY_IPA(pi)) { + u32 *tx_gaintbl = + wlc_phy_get_ipa_gaintbl_nphy(pi); + txgain = tx_gaintbl[txpi[core]]; + } else { + if (CHSPEC_IS5G(pi->radio_chanspec)) { + if NREV_IS + (pi->pubpi.phy_rev, 3) { + txgain = + nphy_tpc_5GHz_txgain_rev3 + [txpi[core]]; + } else if NREV_IS + (pi->pubpi.phy_rev, 4) { + txgain = + (pi->srom_fem5g.extpagain == + 3) ? + nphy_tpc_5GHz_txgain_HiPwrEPA + [txpi[core]] : + nphy_tpc_5GHz_txgain_rev4 + [txpi[core]]; + } else { + txgain = + nphy_tpc_5GHz_txgain_rev5 + [txpi[core]]; + } + } else { + if (NREV_GE(pi->pubpi.phy_rev, 5) && + (pi->srom_fem2g.extpagain == 3)) { + txgain = + nphy_tpc_txgain_HiPwrEPA + [txpi[core]]; + } else { + txgain = + nphy_tpc_txgain_rev3[txpi + [core]]; + } + } + } + } else { + txgain = nphy_tpc_txgain[txpi[core]]; + } + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + rad_gain = (txgain >> 16) & ((1 << (32 - 16 + 1)) - 1); + } else { + rad_gain = (txgain >> 16) & ((1 << (28 - 16 + 1)) - 1); + } + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + dac_gain = (txgain >> 8) & ((1 << (10 - 8 + 1)) - 1); + } else { + dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1); + } + bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f : + 0xa5), (0x1 << 8), (0x1 << 8)); + } else { + mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14)); + } + write_phy_reg(pi, (core == PHY_CORE_0) ? 0xaa : 0xab, dac_gain); + + wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16, + &rad_gain); + + wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2); + m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00); + m1m2 |= ((core == PHY_CORE_0) ? (bbmult << 8) : (bbmult << 0)); + wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2); + + if (PHY_IPA(pi)) { + wlc_phy_table_read_nphy(pi, + (core == + PHY_CORE_0 ? + NPHY_TBL_ID_CORE1TXPWRCTL : + NPHY_TBL_ID_CORE2TXPWRCTL), 1, + 576 + txpi[core], 32, + &rfpwr_offset); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1ff << 4), + ((s16) rfpwr_offset) << 4); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 2), (1) << 2); + + } + } + + and_phy_reg(pi, 0xbf, (u16) (~(0x1f << 0))); + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); +} + +static void +wlc_phy_txpwr_nphy_srom_convert(u8 *srom_max, u16 *pwr_offset, + u8 tmp_max_pwr, u8 rate_start, + u8 rate_end) +{ + u8 rate; + u8 word_num, nibble_num; + u8 tmp_nibble; + + for (rate = rate_start; rate <= rate_end; rate++) { + word_num = (rate - rate_start) >> 2; + nibble_num = (rate - rate_start) & 0x3; + tmp_nibble = (pwr_offset[word_num] >> 4 * nibble_num) & 0xf; + + srom_max[rate] = tmp_max_pwr - 2 * tmp_nibble; + } +} + +static void +wlc_phy_txpwr_nphy_po_apply(u8 *srom_max, u8 pwr_offset, + u8 rate_start, u8 rate_end) +{ + u8 rate; + + for (rate = rate_start; rate <= rate_end; rate++) { + srom_max[rate] -= 2 * pwr_offset; + } +} + +void +wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start, + u8 rate_mcs_end, u8 rate_ofdm_start) +{ + u8 rate1, rate2; + + rate2 = rate_ofdm_start; + for (rate1 = rate_mcs_start; rate1 <= rate_mcs_end - 1; rate1++) { + power[rate1] = power[rate2]; + rate2 += (rate1 == rate_mcs_start) ? 2 : 1; + } + power[rate_mcs_end] = power[rate_mcs_end - 1]; +} + +void +wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power, u8 rate_ofdm_start, + u8 rate_ofdm_end, u8 rate_mcs_start) +{ + u8 rate1, rate2; + + for (rate1 = rate_ofdm_start, rate2 = rate_mcs_start; + rate1 <= rate_ofdm_end; rate1++, rate2++) { + power[rate1] = power[rate2]; + if (rate1 == rate_ofdm_start) + power[++rate1] = power[rate2]; + } +} + +void wlc_phy_txpwr_apply_nphy(phy_info_t *pi) +{ + uint rate1, rate2, band_num; + u8 tmp_bw40po = 0, tmp_cddpo = 0, tmp_stbcpo = 0; + u8 tmp_max_pwr = 0; + u16 pwr_offsets1[2], *pwr_offsets2 = NULL; + u8 *tx_srom_max_rate = NULL; + + for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP); band_num++) { + switch (band_num) { + case 0: + + tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_2g, + pi->nphy_pwrctrl_info[1].max_pwr_2g); + + pwr_offsets1[0] = pi->cck2gpo; + wlc_phy_txpwr_nphy_srom_convert(pi->tx_srom_max_rate_2g, + pwr_offsets1, + tmp_max_pwr, + TXP_FIRST_CCK, + TXP_LAST_CCK); + + pwr_offsets1[0] = (u16) (pi->ofdm2gpo & 0xffff); + pwr_offsets1[1] = + (u16) (pi->ofdm2gpo >> 16) & 0xffff; + + pwr_offsets2 = pi->mcs2gpo; + + tmp_cddpo = pi->cdd2gpo; + tmp_stbcpo = pi->stbc2gpo; + tmp_bw40po = pi->bw402gpo; + + tx_srom_max_rate = pi->tx_srom_max_rate_2g; + break; + case 1: + + tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gm, + pi->nphy_pwrctrl_info[1].max_pwr_5gm); + + pwr_offsets1[0] = (u16) (pi->ofdm5gpo & 0xffff); + pwr_offsets1[1] = + (u16) (pi->ofdm5gpo >> 16) & 0xffff; + + pwr_offsets2 = pi->mcs5gpo; + + tmp_cddpo = pi->cdd5gpo; + tmp_stbcpo = pi->stbc5gpo; + tmp_bw40po = pi->bw405gpo; + + tx_srom_max_rate = pi->tx_srom_max_rate_5g_mid; + break; + case 2: + + tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gl, + pi->nphy_pwrctrl_info[1].max_pwr_5gl); + + pwr_offsets1[0] = (u16) (pi->ofdm5glpo & 0xffff); + pwr_offsets1[1] = + (u16) (pi->ofdm5glpo >> 16) & 0xffff; + + pwr_offsets2 = pi->mcs5glpo; + + tmp_cddpo = pi->cdd5glpo; + tmp_stbcpo = pi->stbc5glpo; + tmp_bw40po = pi->bw405glpo; + + tx_srom_max_rate = pi->tx_srom_max_rate_5g_low; + break; + case 3: + + tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gh, + pi->nphy_pwrctrl_info[1].max_pwr_5gh); + + pwr_offsets1[0] = (u16) (pi->ofdm5ghpo & 0xffff); + pwr_offsets1[1] = + (u16) (pi->ofdm5ghpo >> 16) & 0xffff; + + pwr_offsets2 = pi->mcs5ghpo; + + tmp_cddpo = pi->cdd5ghpo; + tmp_stbcpo = pi->stbc5ghpo; + tmp_bw40po = pi->bw405ghpo; + + tx_srom_max_rate = pi->tx_srom_max_rate_5g_hi; + break; + } + + wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets1, + tmp_max_pwr, TXP_FIRST_OFDM, + TXP_LAST_OFDM); + + wlc_phy_ofdm_to_mcs_powers_nphy(tx_srom_max_rate, + TXP_FIRST_MCS_20_SISO, + TXP_LAST_MCS_20_SISO, + TXP_FIRST_OFDM); + + wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2, + tmp_max_pwr, + TXP_FIRST_MCS_20_CDD, + TXP_LAST_MCS_20_CDD); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + + wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo, + TXP_FIRST_MCS_20_CDD, + TXP_LAST_MCS_20_CDD); + } + + wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate, + TXP_FIRST_OFDM_20_CDD, + TXP_LAST_OFDM_20_CDD, + TXP_FIRST_MCS_20_CDD); + + wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2, + tmp_max_pwr, + TXP_FIRST_MCS_20_STBC, + TXP_LAST_MCS_20_STBC); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + + wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, + tmp_stbcpo, + TXP_FIRST_MCS_20_STBC, + TXP_LAST_MCS_20_STBC); + } + + wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, + &pwr_offsets2[2], tmp_max_pwr, + TXP_FIRST_MCS_20_SDM, + TXP_LAST_MCS_20_SDM); + + if (NPHY_IS_SROM_REINTERPRET) { + + wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, + &pwr_offsets2[4], + tmp_max_pwr, + TXP_FIRST_MCS_40_SISO, + TXP_LAST_MCS_40_SISO); + + wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate, + TXP_FIRST_OFDM_40_SISO, + TXP_LAST_OFDM_40_SISO, + TXP_FIRST_MCS_40_SISO); + + wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, + &pwr_offsets2[4], + tmp_max_pwr, + TXP_FIRST_MCS_40_CDD, + TXP_LAST_MCS_40_CDD); + + wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo, + TXP_FIRST_MCS_40_CDD, + TXP_LAST_MCS_40_CDD); + + wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate, + TXP_FIRST_OFDM_40_CDD, + TXP_LAST_OFDM_40_CDD, + TXP_FIRST_MCS_40_CDD); + + wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, + &pwr_offsets2[4], + tmp_max_pwr, + TXP_FIRST_MCS_40_STBC, + TXP_LAST_MCS_40_STBC); + + wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, + tmp_stbcpo, + TXP_FIRST_MCS_40_STBC, + TXP_LAST_MCS_40_STBC); + + wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, + &pwr_offsets2[6], + tmp_max_pwr, + TXP_FIRST_MCS_40_SDM, + TXP_LAST_MCS_40_SDM); + } else { + + for (rate1 = TXP_FIRST_OFDM_40_SISO, rate2 = + TXP_FIRST_OFDM; rate1 <= TXP_LAST_MCS_40_SDM; + rate1++, rate2++) + tx_srom_max_rate[rate1] = + tx_srom_max_rate[rate2]; + } + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, + tmp_bw40po, + TXP_FIRST_OFDM_40_SISO, + TXP_LAST_MCS_40_SDM); + } + + tx_srom_max_rate[TXP_MCS_32] = + tx_srom_max_rate[TXP_FIRST_MCS_40_CDD]; + } + + return; +} + +static void wlc_phy_txpwr_srom_read_ppr_nphy(phy_info_t *pi) +{ + u16 bw40po, cddpo, stbcpo, bwduppo; + uint band_num; + + if (pi->sh->sromrev >= 9) { + + return; + } + + bw40po = (u16) PHY_GETINTVAR(pi, "bw40po"); + pi->bw402gpo = bw40po & 0xf; + pi->bw405gpo = (bw40po & 0xf0) >> 4; + pi->bw405glpo = (bw40po & 0xf00) >> 8; + pi->bw405ghpo = (bw40po & 0xf000) >> 12; + + cddpo = (u16) PHY_GETINTVAR(pi, "cddpo"); + pi->cdd2gpo = cddpo & 0xf; + pi->cdd5gpo = (cddpo & 0xf0) >> 4; + pi->cdd5glpo = (cddpo & 0xf00) >> 8; + pi->cdd5ghpo = (cddpo & 0xf000) >> 12; + + stbcpo = (u16) PHY_GETINTVAR(pi, "stbcpo"); + pi->stbc2gpo = stbcpo & 0xf; + pi->stbc5gpo = (stbcpo & 0xf0) >> 4; + pi->stbc5glpo = (stbcpo & 0xf00) >> 8; + pi->stbc5ghpo = (stbcpo & 0xf000) >> 12; + + bwduppo = (u16) PHY_GETINTVAR(pi, "bwduppo"); + pi->bwdup2gpo = bwduppo & 0xf; + pi->bwdup5gpo = (bwduppo & 0xf0) >> 4; + pi->bwdup5glpo = (bwduppo & 0xf00) >> 8; + pi->bwdup5ghpo = (bwduppo & 0xf000) >> 12; + + for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP); band_num++) { + switch (band_num) { + case 0: + + pi->nphy_txpid2g[PHY_CORE_0] = + (u8) PHY_GETINTVAR(pi, "txpid2ga0"); + pi->nphy_txpid2g[PHY_CORE_1] = + (u8) PHY_GETINTVAR(pi, "txpid2ga1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g = + (s8) PHY_GETINTVAR(pi, "maxp2ga0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_2g = + (s8) PHY_GETINTVAR(pi, "maxp2ga1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_a1 = + (s16) PHY_GETINTVAR(pi, "pa2gw0a0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_a1 = + (s16) PHY_GETINTVAR(pi, "pa2gw0a1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b0 = + (s16) PHY_GETINTVAR(pi, "pa2gw1a0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b0 = + (s16) PHY_GETINTVAR(pi, "pa2gw1a1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b1 = + (s16) PHY_GETINTVAR(pi, "pa2gw2a0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b1 = + (s16) PHY_GETINTVAR(pi, "pa2gw2a1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_2g = + (s8) PHY_GETINTVAR(pi, "itt2ga0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_2g = + (s8) PHY_GETINTVAR(pi, "itt2ga1"); + + pi->cck2gpo = (u16) PHY_GETINTVAR(pi, "cck2gpo"); + + pi->ofdm2gpo = (u32) PHY_GETINTVAR(pi, "ofdm2gpo"); + + pi->mcs2gpo[0] = (u16) PHY_GETINTVAR(pi, "mcs2gpo0"); + pi->mcs2gpo[1] = (u16) PHY_GETINTVAR(pi, "mcs2gpo1"); + pi->mcs2gpo[2] = (u16) PHY_GETINTVAR(pi, "mcs2gpo2"); + pi->mcs2gpo[3] = (u16) PHY_GETINTVAR(pi, "mcs2gpo3"); + pi->mcs2gpo[4] = (u16) PHY_GETINTVAR(pi, "mcs2gpo4"); + pi->mcs2gpo[5] = (u16) PHY_GETINTVAR(pi, "mcs2gpo5"); + pi->mcs2gpo[6] = (u16) PHY_GETINTVAR(pi, "mcs2gpo6"); + pi->mcs2gpo[7] = (u16) PHY_GETINTVAR(pi, "mcs2gpo7"); + break; + case 1: + + pi->nphy_txpid5g[PHY_CORE_0] = + (u8) PHY_GETINTVAR(pi, "txpid5ga0"); + pi->nphy_txpid5g[PHY_CORE_1] = + (u8) PHY_GETINTVAR(pi, "txpid5ga1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm = + (s8) PHY_GETINTVAR(pi, "maxp5ga0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm = + (s8) PHY_GETINTVAR(pi, "maxp5ga1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_a1 = + (s16) PHY_GETINTVAR(pi, "pa5gw0a0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_a1 = + (s16) PHY_GETINTVAR(pi, "pa5gw0a1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b0 = + (s16) PHY_GETINTVAR(pi, "pa5gw1a0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b0 = + (s16) PHY_GETINTVAR(pi, "pa5gw1a1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b1 = + (s16) PHY_GETINTVAR(pi, "pa5gw2a0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b1 = + (s16) PHY_GETINTVAR(pi, "pa5gw2a1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_5gm = + (s8) PHY_GETINTVAR(pi, "itt5ga0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_5gm = + (s8) PHY_GETINTVAR(pi, "itt5ga1"); + + pi->ofdm5gpo = (u32) PHY_GETINTVAR(pi, "ofdm5gpo"); + + pi->mcs5gpo[0] = (u16) PHY_GETINTVAR(pi, "mcs5gpo0"); + pi->mcs5gpo[1] = (u16) PHY_GETINTVAR(pi, "mcs5gpo1"); + pi->mcs5gpo[2] = (u16) PHY_GETINTVAR(pi, "mcs5gpo2"); + pi->mcs5gpo[3] = (u16) PHY_GETINTVAR(pi, "mcs5gpo3"); + pi->mcs5gpo[4] = (u16) PHY_GETINTVAR(pi, "mcs5gpo4"); + pi->mcs5gpo[5] = (u16) PHY_GETINTVAR(pi, "mcs5gpo5"); + pi->mcs5gpo[6] = (u16) PHY_GETINTVAR(pi, "mcs5gpo6"); + pi->mcs5gpo[7] = (u16) PHY_GETINTVAR(pi, "mcs5gpo7"); + break; + case 2: + + pi->nphy_txpid5gl[0] = + (u8) PHY_GETINTVAR(pi, "txpid5gla0"); + pi->nphy_txpid5gl[1] = + (u8) PHY_GETINTVAR(pi, "txpid5gla1"); + pi->nphy_pwrctrl_info[0].max_pwr_5gl = + (s8) PHY_GETINTVAR(pi, "maxp5gla0"); + pi->nphy_pwrctrl_info[1].max_pwr_5gl = + (s8) PHY_GETINTVAR(pi, "maxp5gla1"); + pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1 = + (s16) PHY_GETINTVAR(pi, "pa5glw0a0"); + pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1 = + (s16) PHY_GETINTVAR(pi, "pa5glw0a1"); + pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0 = + (s16) PHY_GETINTVAR(pi, "pa5glw1a0"); + pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0 = + (s16) PHY_GETINTVAR(pi, "pa5glw1a1"); + pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1 = + (s16) PHY_GETINTVAR(pi, "pa5glw2a0"); + pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1 = + (s16) PHY_GETINTVAR(pi, "pa5glw2a1"); + pi->nphy_pwrctrl_info[0].idle_targ_5gl = 0; + pi->nphy_pwrctrl_info[1].idle_targ_5gl = 0; + + pi->ofdm5glpo = (u32) PHY_GETINTVAR(pi, "ofdm5glpo"); + + pi->mcs5glpo[0] = + (u16) PHY_GETINTVAR(pi, "mcs5glpo0"); + pi->mcs5glpo[1] = + (u16) PHY_GETINTVAR(pi, "mcs5glpo1"); + pi->mcs5glpo[2] = + (u16) PHY_GETINTVAR(pi, "mcs5glpo2"); + pi->mcs5glpo[3] = + (u16) PHY_GETINTVAR(pi, "mcs5glpo3"); + pi->mcs5glpo[4] = + (u16) PHY_GETINTVAR(pi, "mcs5glpo4"); + pi->mcs5glpo[5] = + (u16) PHY_GETINTVAR(pi, "mcs5glpo5"); + pi->mcs5glpo[6] = + (u16) PHY_GETINTVAR(pi, "mcs5glpo6"); + pi->mcs5glpo[7] = + (u16) PHY_GETINTVAR(pi, "mcs5glpo7"); + break; + case 3: + + pi->nphy_txpid5gh[0] = + (u8) PHY_GETINTVAR(pi, "txpid5gha0"); + pi->nphy_txpid5gh[1] = + (u8) PHY_GETINTVAR(pi, "txpid5gha1"); + pi->nphy_pwrctrl_info[0].max_pwr_5gh = + (s8) PHY_GETINTVAR(pi, "maxp5gha0"); + pi->nphy_pwrctrl_info[1].max_pwr_5gh = + (s8) PHY_GETINTVAR(pi, "maxp5gha1"); + pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1 = + (s16) PHY_GETINTVAR(pi, "pa5ghw0a0"); + pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1 = + (s16) PHY_GETINTVAR(pi, "pa5ghw0a1"); + pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0 = + (s16) PHY_GETINTVAR(pi, "pa5ghw1a0"); + pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0 = + (s16) PHY_GETINTVAR(pi, "pa5ghw1a1"); + pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1 = + (s16) PHY_GETINTVAR(pi, "pa5ghw2a0"); + pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1 = + (s16) PHY_GETINTVAR(pi, "pa5ghw2a1"); + pi->nphy_pwrctrl_info[0].idle_targ_5gh = 0; + pi->nphy_pwrctrl_info[1].idle_targ_5gh = 0; + + pi->ofdm5ghpo = (u32) PHY_GETINTVAR(pi, "ofdm5ghpo"); + + pi->mcs5ghpo[0] = + (u16) PHY_GETINTVAR(pi, "mcs5ghpo0"); + pi->mcs5ghpo[1] = + (u16) PHY_GETINTVAR(pi, "mcs5ghpo1"); + pi->mcs5ghpo[2] = + (u16) PHY_GETINTVAR(pi, "mcs5ghpo2"); + pi->mcs5ghpo[3] = + (u16) PHY_GETINTVAR(pi, "mcs5ghpo3"); + pi->mcs5ghpo[4] = + (u16) PHY_GETINTVAR(pi, "mcs5ghpo4"); + pi->mcs5ghpo[5] = + (u16) PHY_GETINTVAR(pi, "mcs5ghpo5"); + pi->mcs5ghpo[6] = + (u16) PHY_GETINTVAR(pi, "mcs5ghpo6"); + pi->mcs5ghpo[7] = + (u16) PHY_GETINTVAR(pi, "mcs5ghpo7"); + break; + } + } + + wlc_phy_txpwr_apply_nphy(pi); +} + +static bool wlc_phy_txpwr_srom_read_nphy(phy_info_t *pi) +{ + + pi->antswitch = (u8) PHY_GETINTVAR(pi, "antswitch"); + pi->aa2g = (u8) PHY_GETINTVAR(pi, "aa2g"); + pi->aa5g = (u8) PHY_GETINTVAR(pi, "aa5g"); + + pi->srom_fem2g.tssipos = (u8) PHY_GETINTVAR(pi, "tssipos2g"); + pi->srom_fem2g.extpagain = (u8) PHY_GETINTVAR(pi, "extpagain2g"); + pi->srom_fem2g.pdetrange = (u8) PHY_GETINTVAR(pi, "pdetrange2g"); + pi->srom_fem2g.triso = (u8) PHY_GETINTVAR(pi, "triso2g"); + pi->srom_fem2g.antswctrllut = (u8) PHY_GETINTVAR(pi, "antswctl2g"); + + pi->srom_fem5g.tssipos = (u8) PHY_GETINTVAR(pi, "tssipos5g"); + pi->srom_fem5g.extpagain = (u8) PHY_GETINTVAR(pi, "extpagain5g"); + pi->srom_fem5g.pdetrange = (u8) PHY_GETINTVAR(pi, "pdetrange5g"); + pi->srom_fem5g.triso = (u8) PHY_GETINTVAR(pi, "triso5g"); + if (PHY_GETVAR(pi, "antswctl5g")) { + + pi->srom_fem5g.antswctrllut = + (u8) PHY_GETINTVAR(pi, "antswctl5g"); + } else { + + pi->srom_fem5g.antswctrllut = + (u8) PHY_GETINTVAR(pi, "antswctl2g"); + } + + wlc_phy_txpower_ipa_upd(pi); + + pi->phy_txcore_disable_temp = (s16) PHY_GETINTVAR(pi, "tempthresh"); + if (pi->phy_txcore_disable_temp == 0) { + pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP; + } + + pi->phy_tempsense_offset = (s8) PHY_GETINTVAR(pi, "tempoffset"); + if (pi->phy_tempsense_offset != 0) { + if (pi->phy_tempsense_offset > + (NPHY_SROM_TEMPSHIFT + NPHY_SROM_MAXTEMPOFFSET)) { + pi->phy_tempsense_offset = NPHY_SROM_MAXTEMPOFFSET; + } else if (pi->phy_tempsense_offset < (NPHY_SROM_TEMPSHIFT + + NPHY_SROM_MINTEMPOFFSET)) { + pi->phy_tempsense_offset = NPHY_SROM_MINTEMPOFFSET; + } else { + pi->phy_tempsense_offset -= NPHY_SROM_TEMPSHIFT; + } + } + + pi->phy_txcore_enable_temp = + pi->phy_txcore_disable_temp - PHY_HYSTERESIS_DELTATEMP; + + pi->phycal_tempdelta = (u8) PHY_GETINTVAR(pi, "phycal_tempdelta"); + if (pi->phycal_tempdelta > NPHY_CAL_MAXTEMPDELTA) { + pi->phycal_tempdelta = 0; + } + + wlc_phy_txpwr_srom_read_ppr_nphy(pi); + + return true; +} + +void wlc_phy_txpower_recalc_target_nphy(phy_info_t *pi) +{ + u8 tx_pwr_ctrl_state; + wlc_phy_txpwr_limit_to_tbl_nphy(pi); + wlc_phy_txpwrctrl_pwr_setup_nphy(pi); + + tx_pwr_ctrl_state = pi->nphy_txpwrctrl; + + if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) { + wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK); + (void)R_REG(pi->sh->osh, &pi->regs->maccontrol); + udelay(1); + } + + wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state); + + if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) + wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0); +} + +static void wlc_phy_txpwrctrl_coeff_setup_nphy(phy_info_t *pi) +{ + u32 idx; + u16 iqloCalbuf[7]; + u32 iqcomp, locomp, curr_locomp; + s8 locomp_i, locomp_q; + s8 curr_locomp_i, curr_locomp_q; + u32 tbl_id, tbl_len, tbl_offset; + u32 regval[128]; + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + wlc_phy_table_read_nphy(pi, 15, 7, 80, 16, iqloCalbuf); + + tbl_len = 128; + tbl_offset = 320; + for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL; + tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) { + iqcomp = + (tbl_id == + 26) ? (((u32) (iqloCalbuf[0] & 0x3ff)) << 10) | + (iqloCalbuf[1] & 0x3ff) + : (((u32) (iqloCalbuf[2] & 0x3ff)) << 10) | + (iqloCalbuf[3] & 0x3ff); + + for (idx = 0; idx < tbl_len; idx++) { + regval[idx] = iqcomp; + } + wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32, + regval); + } + + tbl_offset = 448; + for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL; + tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) { + + locomp = + (u32) ((tbl_id == 26) ? iqloCalbuf[5] : iqloCalbuf[6]); + locomp_i = (s8) ((locomp >> 8) & 0xff); + locomp_q = (s8) ((locomp) & 0xff); + for (idx = 0; idx < tbl_len; idx++) { + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + curr_locomp_i = locomp_i; + curr_locomp_q = locomp_q; + } else { + curr_locomp_i = (s8) ((locomp_i * + nphy_tpc_loscale[idx] + + 128) >> 8); + curr_locomp_q = + (s8) ((locomp_q * nphy_tpc_loscale[idx] + + 128) >> 8); + } + curr_locomp = (u32) ((curr_locomp_i & 0xff) << 8); + curr_locomp |= (u32) (curr_locomp_q & 0xff); + regval[idx] = curr_locomp; + } + wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32, + regval); + } + + if (NREV_LT(pi->pubpi.phy_rev, 2)) { + + wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX1, 0xFFFF); + wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX2, 0xFFFF); + } + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); +} + +static void wlc_phy_ipa_internal_tssi_setup_nphy(phy_info_t *pi) +{ + u8 core; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + if (CHSPEC_IS2G(pi->radio_chanspec)) { + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TX_SSI_MASTER, 0x5); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TX_SSI_MUX, 0xe); + + if (pi->pubpi.radiorev != 5) + WRITE_RADIO_REG3(pi, RADIO_2057, TX, + core, TSSIA, 0); + + if (!NREV_IS(pi->pubpi.phy_rev, 7)) { + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, + core, TSSIG, 0x1); + } else { + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, + core, TSSIG, 0x31); + } + } else { + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TX_SSI_MASTER, 0x9); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TX_SSI_MUX, 0xc); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TSSIG, 0); + + if (pi->pubpi.radiorev != 5) { + if (!NREV_IS(pi->pubpi.phy_rev, 7)) { + + WRITE_RADIO_REG3(pi, RADIO_2057, + TX, core, + TSSIA, 0x1); + } else { + + WRITE_RADIO_REG3(pi, RADIO_2057, + TX, core, + TSSIA, 0x31); + } + } + } + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG, + 0); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC, + 0); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM, + 0x3); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1, + 0x0); + } + } else { + WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR31, + (CHSPEC_IS2G(pi->radio_chanspec)) ? 0x128 : + 0x80); + WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR30, 0x0); + WRITE_RADIO_SYN(pi, RADIO_2056, GPIO_MASTER1, 0x29); + + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_VCM_HG, + 0x0); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_IDAC, + 0x0); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_VCM, + 0x3); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TX_AMP_DET, + 0x0); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC1, + 0x8); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC2, + 0x0); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC3, + 0x0); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + TX_SSI_MASTER, 0x5); + + if (pi->pubpi.radiorev != 5) + WRITE_RADIO_REG2(pi, RADIO_2056, TX, + core, TSSIA, 0x0); + if (NREV_GE(pi->pubpi.phy_rev, 5)) { + + WRITE_RADIO_REG2(pi, RADIO_2056, TX, + core, TSSIG, 0x31); + } else { + WRITE_RADIO_REG2(pi, RADIO_2056, TX, + core, TSSIG, 0x11); + } + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + TX_SSI_MUX, 0xe); + } else { + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + TX_SSI_MASTER, 0x9); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + TSSIA, 0x31); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + TSSIG, 0x0); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + TX_SSI_MUX, 0xc); + } + } + } +} + +static void wlc_phy_txpwrctrl_idle_tssi_nphy(phy_info_t *pi) +{ + s32 rssi_buf[4]; + s32 int_val; + + if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi) || PHY_MUTED(pi)) + + return; + + if (PHY_IPA(pi)) { + wlc_phy_ipa_internal_tssi_setup_nphy(pi); + } + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), + 0, 0x3, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 0); + } + + wlc_phy_stopplayback_nphy(pi); + + wlc_phy_tx_tone_nphy(pi, 4000, 0, 0, 0, false); + + udelay(20); + int_val = + wlc_phy_poll_rssi_nphy(pi, (u8) NPHY_RSSI_SEL_TSSI_2G, rssi_buf, + 1); + wlc_phy_stopplayback_nphy(pi); + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, 0); + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), + 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 1); + } + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + + pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g = + (u8) ((int_val >> 24) & 0xff); + pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g = + (u8) ((int_val >> 24) & 0xff); + + pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g = + (u8) ((int_val >> 8) & 0xff); + pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g = + (u8) ((int_val >> 8) & 0xff); + } else { + pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g = + (u8) ((int_val >> 24) & 0xff); + + pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g = + (u8) ((int_val >> 8) & 0xff); + + pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g = + (u8) ((int_val >> 16) & 0xff); + pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g = + (u8) ((int_val) & 0xff); + } + +} + +static void wlc_phy_txpwrctrl_pwr_setup_nphy(phy_info_t *pi) +{ + u32 idx; + s16 a1[2], b0[2], b1[2]; + s8 target_pwr_qtrdbm[2]; + s32 num, den, pwr_est; + u8 chan_freq_range; + u8 idle_tssi[2]; + u32 tbl_id, tbl_len, tbl_offset; + u32 regval[64]; + u8 core; + + if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) { + wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK); + (void)R_REG(pi->sh->osh, &pi->regs->maccontrol); + udelay(1); + } + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + or_phy_reg(pi, 0x122, (0x1 << 0)); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + and_phy_reg(pi, 0x1e7, (u16) (~(0x1 << 15))); + } else { + + or_phy_reg(pi, 0x1e7, (0x1 << 15)); + } + + if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) + wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0); + + if (pi->sh->sromrev < 4) { + idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g; + idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g; + target_pwr_qtrdbm[0] = 13 * 4; + target_pwr_qtrdbm[1] = 13 * 4; + a1[0] = -424; + a1[1] = -424; + b0[0] = 5612; + b0[1] = 5612; + b1[1] = -1393; + b1[0] = -1393; + } else { + + chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0); + switch (chan_freq_range) { + case WL_CHAN_FREQ_RANGE_2G: + idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g; + idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g; + target_pwr_qtrdbm[0] = + pi->nphy_pwrctrl_info[0].max_pwr_2g; + target_pwr_qtrdbm[1] = + pi->nphy_pwrctrl_info[1].max_pwr_2g; + a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_a1; + a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_a1; + b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b0; + b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b0; + b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b1; + b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b1; + break; + case WL_CHAN_FREQ_RANGE_5GL: + idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g; + idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g; + target_pwr_qtrdbm[0] = + pi->nphy_pwrctrl_info[0].max_pwr_5gl; + target_pwr_qtrdbm[1] = + pi->nphy_pwrctrl_info[1].max_pwr_5gl; + a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1; + a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1; + b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0; + b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0; + b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1; + b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1; + break; + case WL_CHAN_FREQ_RANGE_5GM: + idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g; + idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g; + target_pwr_qtrdbm[0] = + pi->nphy_pwrctrl_info[0].max_pwr_5gm; + target_pwr_qtrdbm[1] = + pi->nphy_pwrctrl_info[1].max_pwr_5gm; + a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_a1; + a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_a1; + b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b0; + b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b0; + b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b1; + b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b1; + break; + case WL_CHAN_FREQ_RANGE_5GH: + idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g; + idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g; + target_pwr_qtrdbm[0] = + pi->nphy_pwrctrl_info[0].max_pwr_5gh; + target_pwr_qtrdbm[1] = + pi->nphy_pwrctrl_info[1].max_pwr_5gh; + a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1; + a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1; + b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0; + b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0; + b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1; + b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1; + break; + default: + idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g; + idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g; + target_pwr_qtrdbm[0] = 13 * 4; + target_pwr_qtrdbm[1] = 13 * 4; + a1[0] = -424; + a1[1] = -424; + b0[0] = 5612; + b0[1] = 5612; + b1[1] = -1393; + b1[0] = -1393; + break; + } + } + + target_pwr_qtrdbm[0] = (s8) pi->tx_power_max; + target_pwr_qtrdbm[1] = (s8) pi->tx_power_max; + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (pi->srom_fem2g.tssipos) { + or_phy_reg(pi, 0x1e9, (0x1 << 14)); + } + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + for (core = 0; core <= 1; core++) { + if (PHY_IPA(pi)) { + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + WRITE_RADIO_REG3(pi, RADIO_2057, + TX, core, + TX_SSI_MUX, + 0xe); + } else { + WRITE_RADIO_REG3(pi, RADIO_2057, + TX, core, + TX_SSI_MUX, + 0xc); + } + } else { + } + } + } else { + if (PHY_IPA(pi)) { + + write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX | + RADIO_2056_TX0, + (CHSPEC_IS5G + (pi-> + radio_chanspec)) ? 0xc : 0xe); + write_radio_reg(pi, + RADIO_2056_TX_TX_SSI_MUX | + RADIO_2056_TX1, + (CHSPEC_IS5G + (pi-> + radio_chanspec)) ? 0xc : 0xe); + } else { + + write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX | + RADIO_2056_TX0, 0x11); + write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX | + RADIO_2056_TX1, 0x11); + } + } + } + + if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) { + wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK); + (void)R_REG(pi->sh->osh, &pi->regs->maccontrol); + udelay(1); + } + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + mod_phy_reg(pi, 0x1e7, (0x7f << 0), + (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0)); + } else { + mod_phy_reg(pi, 0x1e7, (0x7f << 0), + (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0)); + } + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + mod_phy_reg(pi, 0x222, (0xff << 0), + (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0)); + } else if (NREV_GT(pi->pubpi.phy_rev, 1)) { + mod_phy_reg(pi, 0x222, (0xff << 0), + (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0)); + } + + if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) + wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0); + + write_phy_reg(pi, 0x1e8, (0x3 << 8) | (240 << 0)); + + write_phy_reg(pi, 0x1e9, + (1 << 15) | (idle_tssi[0] << 0) | (idle_tssi[1] << 8)); + + write_phy_reg(pi, 0x1ea, + (target_pwr_qtrdbm[0] << 0) | + (target_pwr_qtrdbm[1] << 8)); + + tbl_len = 64; + tbl_offset = 0; + for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL; + tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) { + + for (idx = 0; idx < tbl_len; idx++) { + num = + 8 * (16 * b0[tbl_id - 26] + b1[tbl_id - 26] * idx); + den = 32768 + a1[tbl_id - 26] * idx; + pwr_est = max(((4 * num + den / 2) / den), -8); + if (NREV_LT(pi->pubpi.phy_rev, 3)) { + if (idx <= + (uint) (31 - idle_tssi[tbl_id - 26] + 1)) + pwr_est = + max(pwr_est, + target_pwr_qtrdbm[tbl_id - 26] + + 1); + } + regval[idx] = (u32) pwr_est; + } + wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32, + regval); + } + + wlc_phy_txpwr_limit_to_tbl_nphy(pi); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64, 8, + pi->adj_pwr_tbl_nphy); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64, 8, + pi->adj_pwr_tbl_nphy); + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); +} + +static bool wlc_phy_txpwr_ison_nphy(phy_info_t *pi) +{ + return read_phy_reg((pi), 0x1e7) & ((0x1 << 15) | + (0x1 << 14) | (0x1 << 13)); +} + +static u8 wlc_phy_txpwr_idx_cur_get_nphy(phy_info_t *pi, u8 core) +{ + u16 tmp; + tmp = read_phy_reg(pi, ((core == PHY_CORE_0) ? 0x1ed : 0x1ee)); + + tmp = (tmp & (0x7f << 8)) >> 8; + return (u8) tmp; +} + +static void +wlc_phy_txpwr_idx_cur_set_nphy(phy_info_t *pi, u8 idx0, u8 idx1) +{ + mod_phy_reg(pi, 0x1e7, (0x7f << 0), idx0); + + if (NREV_GT(pi->pubpi.phy_rev, 1)) + mod_phy_reg(pi, 0x222, (0xff << 0), idx1); +} + +u16 wlc_phy_txpwr_idx_get_nphy(phy_info_t *pi) +{ + u16 tmp; + u16 pwr_idx[2]; + + if (wlc_phy_txpwr_ison_nphy(pi)) { + pwr_idx[0] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_0); + pwr_idx[1] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_1); + + tmp = (pwr_idx[0] << 8) | pwr_idx[1]; + } else { + tmp = + ((pi->nphy_txpwrindex[PHY_CORE_0]. + index_internal & 0xff) << 8) | (pi-> + nphy_txpwrindex + [PHY_CORE_1]. + index_internal & 0xff); + } + + return tmp; +} + +void wlc_phy_txpwr_papd_cal_nphy(phy_info_t *pi) +{ + if (PHY_IPA(pi) + && (pi->nphy_force_papd_cal + || (wlc_phy_txpwr_ison_nphy(pi) + && + (((u32) + ABS(wlc_phy_txpwr_idx_cur_get_nphy(pi, 0) - + pi->nphy_papd_tx_gain_at_last_cal[0]) >= 4) + || ((u32) + ABS(wlc_phy_txpwr_idx_cur_get_nphy(pi, 1) - + pi->nphy_papd_tx_gain_at_last_cal[1]) >= 4))))) { + wlc_phy_a4(pi, true); + } +} + +void wlc_phy_txpwrctrl_enable_nphy(phy_info_t *pi, u8 ctrl_type) +{ + u16 mask = 0, val = 0, ishw = 0; + u8 ctr; + uint core; + u32 tbl_offset; + u32 tbl_len; + u16 regval[84]; + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + switch (ctrl_type) { + case PHY_TPC_HW_OFF: + case PHY_TPC_HW_ON: + pi->nphy_txpwrctrl = ctrl_type; + break; + default: + break; + } + + if (ctrl_type == PHY_TPC_HW_OFF) { + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + + if (wlc_phy_txpwr_ison_nphy(pi)) { + for (core = 0; core < pi->pubpi.phy_corenum; + core++) + pi->nphy_txpwr_idx[core] = + wlc_phy_txpwr_idx_cur_get_nphy(pi, + (u8) + core); + } + + } + + tbl_len = 84; + tbl_offset = 64; + for (ctr = 0; ctr < tbl_len; ctr++) { + regval[ctr] = 0; + } + wlc_phy_table_write_nphy(pi, 26, tbl_len, tbl_offset, 16, + regval); + wlc_phy_table_write_nphy(pi, 27, tbl_len, tbl_offset, 16, + regval); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + + and_phy_reg(pi, 0x1e7, + (u16) (~((0x1 << 15) | + (0x1 << 14) | (0x1 << 13)))); + } else { + and_phy_reg(pi, 0x1e7, + (u16) (~((0x1 << 14) | (0x1 << 13)))); + } + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + or_phy_reg(pi, 0x8f, (0x1 << 8)); + or_phy_reg(pi, 0xa5, (0x1 << 8)); + } else { + or_phy_reg(pi, 0xa5, (0x1 << 14)); + } + + if (NREV_IS(pi->pubpi.phy_rev, 2)) + mod_phy_reg(pi, 0xdc, 0x00ff, 0x53); + else if (NREV_LT(pi->pubpi.phy_rev, 2)) + mod_phy_reg(pi, 0xdc, 0x00ff, 0x5a); + + if (NREV_LT(pi->pubpi.phy_rev, 2) && IS40MHZ(pi)) + wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR, + MHF1_IQSWAP_WAR, WLC_BAND_ALL); + + } else { + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64, + 8, pi->adj_pwr_tbl_nphy); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64, + 8, pi->adj_pwr_tbl_nphy); + + ishw = (ctrl_type == PHY_TPC_HW_ON) ? 0x1 : 0x0; + mask = (0x1 << 14) | (0x1 << 13); + val = (ishw << 14) | (ishw << 13); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + mask |= (0x1 << 15); + val |= (ishw << 15); + } + + mod_phy_reg(pi, 0x1e7, mask, val); + + if (CHSPEC_IS5G(pi->radio_chanspec)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x32); + mod_phy_reg(pi, 0x222, (0xff << 0), 0x32); + } else { + mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x64); + if (NREV_GT(pi->pubpi.phy_rev, 1)) + mod_phy_reg(pi, 0x222, + (0xff << 0), 0x64); + } + } + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if ((pi->nphy_txpwr_idx[0] != 128) + && (pi->nphy_txpwr_idx[1] != 128)) { + wlc_phy_txpwr_idx_cur_set_nphy(pi, + pi-> + nphy_txpwr_idx + [0], + pi-> + nphy_txpwr_idx + [1]); + } + } + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + and_phy_reg(pi, 0x8f, ~(0x1 << 8)); + and_phy_reg(pi, 0xa5, ~(0x1 << 8)); + } else { + and_phy_reg(pi, 0xa5, ~(0x1 << 14)); + } + + if (NREV_IS(pi->pubpi.phy_rev, 2)) + mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b); + else if (NREV_LT(pi->pubpi.phy_rev, 2)) + mod_phy_reg(pi, 0xdc, 0x00ff, 0x40); + + if (NREV_LT(pi->pubpi.phy_rev, 2) && IS40MHZ(pi)) + wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR, + 0x0, WLC_BAND_ALL); + + if (PHY_IPA(pi)) { + mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 2), (0) << 2); + + mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 2), (0) << 2); + + } + + } + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); +} + +void +wlc_phy_txpwr_index_nphy(phy_info_t *pi, u8 core_mask, s8 txpwrindex, + bool restore_cals) +{ + u8 core, txpwrctl_tbl; + u16 tx_ind0, iq_ind0, lo_ind0; + u16 m1m2; + u32 txgain; + u16 rad_gain, dac_gain; + u8 bbmult; + u32 iqcomp; + u16 iqcomp_a, iqcomp_b; + u32 locomp; + u16 tmpval; + u8 tx_pwr_ctrl_state; + s32 rfpwr_offset; + u16 regval[2]; + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + tx_ind0 = 192; + iq_ind0 = 320; + lo_ind0 = 448; + + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + + if ((core_mask & (1 << core)) == 0) { + continue; + } + + txpwrctl_tbl = (core == PHY_CORE_0) ? 26 : 27; + + if (txpwrindex < 0) { + if (pi->nphy_txpwrindex[core].index < 0) { + + continue; + } + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + mod_phy_reg(pi, 0x8f, + (0x1 << 8), + pi->nphy_txpwrindex[core]. + AfectrlOverride); + mod_phy_reg(pi, 0xa5, (0x1 << 8), + pi->nphy_txpwrindex[core]. + AfectrlOverride); + } else { + mod_phy_reg(pi, 0xa5, + (0x1 << 14), + pi->nphy_txpwrindex[core]. + AfectrlOverride); + } + + write_phy_reg(pi, (core == PHY_CORE_0) ? + 0xaa : 0xab, + pi->nphy_txpwrindex[core].AfeCtrlDacGain); + + wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16, + &pi->nphy_txpwrindex[core]. + rad_gain); + + wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2); + m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00); + m1m2 |= ((core == PHY_CORE_0) ? + (pi->nphy_txpwrindex[core].bbmult << 8) : + (pi->nphy_txpwrindex[core].bbmult << 0)); + wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2); + + if (restore_cals) { + + wlc_phy_table_write_nphy(pi, 15, 2, + (80 + 2 * core), 16, + (void *)&pi-> + nphy_txpwrindex[core]. + iqcomp_a); + + wlc_phy_table_write_nphy(pi, 15, 1, (85 + core), + 16, + &pi-> + nphy_txpwrindex[core]. + locomp); + wlc_phy_table_write_nphy(pi, 15, 1, (93 + core), + 16, + (void *)&pi-> + nphy_txpwrindex[core]. + locomp); + } + + wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl); + + pi->nphy_txpwrindex[core].index_internal = + pi->nphy_txpwrindex[core].index_internal_save; + } else { + + if (pi->nphy_txpwrindex[core].index < 0) { + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + mod_phy_reg(pi, 0x8f, + (0x1 << 8), + pi->nphy_txpwrindex[core]. + AfectrlOverride); + mod_phy_reg(pi, 0xa5, (0x1 << 8), + pi->nphy_txpwrindex[core]. + AfectrlOverride); + } else { + pi->nphy_txpwrindex[core]. + AfectrlOverride = + read_phy_reg(pi, 0xa5); + } + + pi->nphy_txpwrindex[core].AfeCtrlDacGain = + read_phy_reg(pi, + (core == + PHY_CORE_0) ? 0xaa : 0xab); + + wlc_phy_table_read_nphy(pi, 7, 1, + (0x110 + core), 16, + &pi-> + nphy_txpwrindex[core]. + rad_gain); + + wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, + &tmpval); + tmpval >>= ((core == PHY_CORE_0) ? 8 : 0); + tmpval &= 0xff; + pi->nphy_txpwrindex[core].bbmult = + (u8) tmpval; + + wlc_phy_table_read_nphy(pi, 15, 2, + (80 + 2 * core), 16, + (void *)&pi-> + nphy_txpwrindex[core]. + iqcomp_a); + + wlc_phy_table_read_nphy(pi, 15, 1, (85 + core), + 16, + (void *)&pi-> + nphy_txpwrindex[core]. + locomp); + + pi->nphy_txpwrindex[core].index_internal_save = + pi->nphy_txpwrindex[core].index_internal; + } + + tx_pwr_ctrl_state = pi->nphy_txpwrctrl; + wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF); + + if (NREV_IS(pi->pubpi.phy_rev, 1)) + wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON); + + wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1, + (tx_ind0 + txpwrindex), 32, + &txgain); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + rad_gain = + (txgain >> 16) & ((1 << (32 - 16 + 1)) - 1); + } else { + rad_gain = + (txgain >> 16) & ((1 << (28 - 16 + 1)) - 1); + } + dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1); + bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f : + 0xa5), (0x1 << 8), (0x1 << 8)); + } else { + mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14)); + } + write_phy_reg(pi, (core == PHY_CORE_0) ? + 0xaa : 0xab, dac_gain); + + wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16, + &rad_gain); + + wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2); + m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00); + m1m2 |= + ((core == + PHY_CORE_0) ? (bbmult << 8) : (bbmult << 0)); + + wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2); + + wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1, + (iq_ind0 + txpwrindex), 32, + &iqcomp); + iqcomp_a = (iqcomp >> 10) & ((1 << (19 - 10 + 1)) - 1); + iqcomp_b = (iqcomp >> 0) & ((1 << (9 - 0 + 1)) - 1); + + if (restore_cals) { + regval[0] = (u16) iqcomp_a; + regval[1] = (u16) iqcomp_b; + wlc_phy_table_write_nphy(pi, 15, 2, + (80 + 2 * core), 16, + regval); + } + + wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1, + (lo_ind0 + txpwrindex), 32, + &locomp); + if (restore_cals) { + wlc_phy_table_write_nphy(pi, 15, 1, (85 + core), + 16, &locomp); + } + + if (NREV_IS(pi->pubpi.phy_rev, 1)) + wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF); + + if (PHY_IPA(pi)) { + wlc_phy_table_read_nphy(pi, + (core == + PHY_CORE_0 ? + NPHY_TBL_ID_CORE1TXPWRCTL + : + NPHY_TBL_ID_CORE2TXPWRCTL), + 1, 576 + txpwrindex, 32, + &rfpwr_offset); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1ff << 4), + ((s16) rfpwr_offset) << 4); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 2), (1) << 2); + + } + + wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state); + } + + pi->nphy_txpwrindex[core].index = txpwrindex; + } + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); +} + +void +wlc_phy_txpower_sromlimit_get_nphy(phy_info_t *pi, uint chan, u8 *max_pwr, + u8 txp_rate_idx) +{ + u8 chan_freq_range; + + chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, chan); + switch (chan_freq_range) { + case WL_CHAN_FREQ_RANGE_2G: + *max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx]; + break; + case WL_CHAN_FREQ_RANGE_5GM: + *max_pwr = pi->tx_srom_max_rate_5g_mid[txp_rate_idx]; + break; + case WL_CHAN_FREQ_RANGE_5GL: + *max_pwr = pi->tx_srom_max_rate_5g_low[txp_rate_idx]; + break; + case WL_CHAN_FREQ_RANGE_5GH: + *max_pwr = pi->tx_srom_max_rate_5g_hi[txp_rate_idx]; + break; + default: + ASSERT(0); + *max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx]; + break; + } + + return; +} + +void wlc_phy_stay_in_carriersearch_nphy(phy_info_t *pi, bool enable) +{ + u16 clip_off[] = { 0xffff, 0xffff }; + + ASSERT(0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + + if (enable) { + if (pi->nphy_deaf_count == 0) { + pi->classifier_state = + wlc_phy_classifier_nphy(pi, 0, 0); + wlc_phy_classifier_nphy(pi, (0x7 << 0), 4); + wlc_phy_clip_det_nphy(pi, 0, pi->clip_state); + wlc_phy_clip_det_nphy(pi, 1, clip_off); + } + + pi->nphy_deaf_count++; + + wlc_phy_resetcca_nphy(pi); + + } else { + ASSERT(pi->nphy_deaf_count > 0); + + pi->nphy_deaf_count--; + + if (pi->nphy_deaf_count == 0) { + wlc_phy_classifier_nphy(pi, (0x7 << 0), + pi->classifier_state); + wlc_phy_clip_det_nphy(pi, 1, pi->clip_state); + } + } +} + +void wlc_nphy_deaf_mode(phy_info_t *pi, bool mode) +{ + wlapi_suspend_mac_and_wait(pi->sh->physhim); + + if (mode) { + if (pi->nphy_deaf_count == 0) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + } else { + if (pi->nphy_deaf_count > 0) + wlc_phy_stay_in_carriersearch_nphy(pi, false); + } + wlapi_enable_mac(pi->sh->physhim); +} diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h new file mode 100644 index 000000000000..72176ae2882c --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h @@ -0,0 +1,1533 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _BCM20XX_H +#define _BCM20XX_H + +#define RADIO_IDCODE 0x01 + +#define RADIO_DEFAULT_CORE 0 + +#define RXC0_RSSI_RST 0x80 +#define RXC0_MODE_RSSI 0x40 +#define RXC0_MODE_OFF 0x20 +#define RXC0_MODE_CM 0x10 +#define RXC0_LAN_LOAD 0x08 +#define RXC0_OFF_ADJ_MASK 0x07 + +#define TXC0_MODE_TXLPF 0x04 +#define TXC0_PA_TSSI_EN 0x02 +#define TXC0_TSSI_EN 0x01 + +#define TXC1_PA_GAIN_MASK 0x60 +#define TXC1_PA_GAIN_3DB 0x40 +#define TXC1_PA_GAIN_2DB 0x20 +#define TXC1_TX_MIX_GAIN 0x10 +#define TXC1_OFF_I_MASK 0x0c +#define TXC1_OFF_Q_MASK 0x03 + +#define RADIO_2055_READ_OFF 0x100 +#define RADIO_2057_READ_OFF 0x200 + +#define RADIO_2055_GEN_SPARE 0x00 +#define RADIO_2055_SP_PIN_PD 0x02 +#define RADIO_2055_SP_RSSI_CORE1 0x03 +#define RADIO_2055_SP_PD_MISC_CORE1 0x04 +#define RADIO_2055_SP_RSSI_CORE2 0x05 +#define RADIO_2055_SP_PD_MISC_CORE2 0x06 +#define RADIO_2055_SP_RX_GC1_CORE1 0x07 +#define RADIO_2055_SP_RX_GC2_CORE1 0x08 +#define RADIO_2055_SP_RX_GC1_CORE2 0x09 +#define RADIO_2055_SP_RX_GC2_CORE2 0x0a +#define RADIO_2055_SP_LPF_BW_SELECT_CORE1 0x0b +#define RADIO_2055_SP_LPF_BW_SELECT_CORE2 0x0c +#define RADIO_2055_SP_TX_GC1_CORE1 0x0d +#define RADIO_2055_SP_TX_GC2_CORE1 0x0e +#define RADIO_2055_SP_TX_GC1_CORE2 0x0f +#define RADIO_2055_SP_TX_GC2_CORE2 0x10 +#define RADIO_2055_MASTER_CNTRL1 0x11 +#define RADIO_2055_MASTER_CNTRL2 0x12 +#define RADIO_2055_PD_LGEN 0x13 +#define RADIO_2055_PD_PLL_TS 0x14 +#define RADIO_2055_PD_CORE1_LGBUF 0x15 +#define RADIO_2055_PD_CORE1_TX 0x16 +#define RADIO_2055_PD_CORE1_RXTX 0x17 +#define RADIO_2055_PD_CORE1_RSSI_MISC 0x18 +#define RADIO_2055_PD_CORE2_LGBUF 0x19 +#define RADIO_2055_PD_CORE2_TX 0x1a +#define RADIO_2055_PD_CORE2_RXTX 0x1b +#define RADIO_2055_PD_CORE2_RSSI_MISC 0x1c +#define RADIO_2055_PWRDET_LGEN 0x1d +#define RADIO_2055_PWRDET_LGBUF_CORE1 0x1e +#define RADIO_2055_PWRDET_RXTX_CORE1 0x1f +#define RADIO_2055_PWRDET_LGBUF_CORE2 0x20 +#define RADIO_2055_PWRDET_RXTX_CORE2 0x21 +#define RADIO_2055_RRCCAL_CNTRL_SPARE 0x22 +#define RADIO_2055_RRCCAL_N_OPT_SEL 0x23 +#define RADIO_2055_CAL_MISC 0x24 +#define RADIO_2055_CAL_COUNTER_OUT 0x25 +#define RADIO_2055_CAL_COUNTER_OUT2 0x26 +#define RADIO_2055_CAL_CVAR_CNTRL 0x27 +#define RADIO_2055_CAL_RVAR_CNTRL 0x28 +#define RADIO_2055_CAL_LPO_CNTRL 0x29 +#define RADIO_2055_CAL_TS 0x2a +#define RADIO_2055_CAL_RCCAL_READ_TS 0x2b +#define RADIO_2055_CAL_RCAL_READ_TS 0x2c +#define RADIO_2055_PAD_DRIVER 0x2d +#define RADIO_2055_XO_CNTRL1 0x2e +#define RADIO_2055_XO_CNTRL2 0x2f +#define RADIO_2055_XO_REGULATOR 0x30 +#define RADIO_2055_XO_MISC 0x31 +#define RADIO_2055_PLL_LF_C1 0x32 +#define RADIO_2055_PLL_CAL_VTH 0x33 +#define RADIO_2055_PLL_LF_C2 0x34 +#define RADIO_2055_PLL_REF 0x35 +#define RADIO_2055_PLL_LF_R1 0x36 +#define RADIO_2055_PLL_PFD_CP 0x37 +#define RADIO_2055_PLL_IDAC_CPOPAMP 0x38 +#define RADIO_2055_PLL_CP_REGULATOR 0x39 +#define RADIO_2055_PLL_RCAL 0x3a +#define RADIO_2055_RF_PLL_MOD0 0x3b +#define RADIO_2055_RF_PLL_MOD1 0x3c +#define RADIO_2055_RF_MMD_IDAC1 0x3d +#define RADIO_2055_RF_MMD_IDAC0 0x3e +#define RADIO_2055_RF_MMD_SPARE 0x3f +#define RADIO_2055_VCO_CAL1 0x40 +#define RADIO_2055_VCO_CAL2 0x41 +#define RADIO_2055_VCO_CAL3 0x42 +#define RADIO_2055_VCO_CAL4 0x43 +#define RADIO_2055_VCO_CAL5 0x44 +#define RADIO_2055_VCO_CAL6 0x45 +#define RADIO_2055_VCO_CAL7 0x46 +#define RADIO_2055_VCO_CAL8 0x47 +#define RADIO_2055_VCO_CAL9 0x48 +#define RADIO_2055_VCO_CAL10 0x49 +#define RADIO_2055_VCO_CAL11 0x4a +#define RADIO_2055_VCO_CAL12 0x4b +#define RADIO_2055_VCO_CAL13 0x4c +#define RADIO_2055_VCO_CAL14 0x4d +#define RADIO_2055_VCO_CAL15 0x4e +#define RADIO_2055_VCO_CAL16 0x4f +#define RADIO_2055_VCO_KVCO 0x50 +#define RADIO_2055_VCO_CAP_TAIL 0x51 +#define RADIO_2055_VCO_IDAC_VCO 0x52 +#define RADIO_2055_VCO_REGULATOR 0x53 +#define RADIO_2055_PLL_RF_VTH 0x54 +#define RADIO_2055_LGBUF_CEN_BUF 0x55 +#define RADIO_2055_LGEN_TUNE1 0x56 +#define RADIO_2055_LGEN_TUNE2 0x57 +#define RADIO_2055_LGEN_IDAC1 0x58 +#define RADIO_2055_LGEN_IDAC2 0x59 +#define RADIO_2055_LGEN_BIAS_CNT 0x5a +#define RADIO_2055_LGEN_BIAS_IDAC 0x5b +#define RADIO_2055_LGEN_RCAL 0x5c +#define RADIO_2055_LGEN_DIV 0x5d +#define RADIO_2055_LGEN_SPARE2 0x5e +#define RADIO_2055_CORE1_LGBUF_A_TUNE 0x5f +#define RADIO_2055_CORE1_LGBUF_G_TUNE 0x60 +#define RADIO_2055_CORE1_LGBUF_DIV 0x61 +#define RADIO_2055_CORE1_LGBUF_A_IDAC 0x62 +#define RADIO_2055_CORE1_LGBUF_G_IDAC 0x63 +#define RADIO_2055_CORE1_LGBUF_IDACFIL_OVR 0x64 +#define RADIO_2055_CORE1_LGBUF_SPARE 0x65 +#define RADIO_2055_CORE1_RXRF_SPC1 0x66 +#define RADIO_2055_CORE1_RXRF_REG1 0x67 +#define RADIO_2055_CORE1_RXRF_REG2 0x68 +#define RADIO_2055_CORE1_RXRF_RCAL 0x69 +#define RADIO_2055_CORE1_RXBB_BUFI_LPFCMP 0x6a +#define RADIO_2055_CORE1_RXBB_LPF 0x6b +#define RADIO_2055_CORE1_RXBB_MIDAC_HIPAS 0x6c +#define RADIO_2055_CORE1_RXBB_VGA1_IDAC 0x6d +#define RADIO_2055_CORE1_RXBB_VGA2_IDAC 0x6e +#define RADIO_2055_CORE1_RXBB_VGA3_IDAC 0x6f +#define RADIO_2055_CORE1_RXBB_BUFO_CTRL 0x70 +#define RADIO_2055_CORE1_RXBB_RCCAL_CTRL 0x71 +#define RADIO_2055_CORE1_RXBB_RSSI_CTRL1 0x72 +#define RADIO_2055_CORE1_RXBB_RSSI_CTRL2 0x73 +#define RADIO_2055_CORE1_RXBB_RSSI_CTRL3 0x74 +#define RADIO_2055_CORE1_RXBB_RSSI_CTRL4 0x75 +#define RADIO_2055_CORE1_RXBB_RSSI_CTRL5 0x76 +#define RADIO_2055_CORE1_RXBB_REGULATOR 0x77 +#define RADIO_2055_CORE1_RXBB_SPARE1 0x78 +#define RADIO_2055_CORE1_RXTXBB_RCAL 0x79 +#define RADIO_2055_CORE1_TXRF_SGM_PGA 0x7a +#define RADIO_2055_CORE1_TXRF_SGM_PAD 0x7b +#define RADIO_2055_CORE1_TXRF_CNTR_PGA1 0x7c +#define RADIO_2055_CORE1_TXRF_CNTR_PAD1 0x7d +#define RADIO_2055_CORE1_TX_RFPGA_IDAC 0x7e +#define RADIO_2055_CORE1_TX_PGA_PAD_TN 0x7f +#define RADIO_2055_CORE1_TX_PAD_IDAC1 0x80 +#define RADIO_2055_CORE1_TX_PAD_IDAC2 0x81 +#define RADIO_2055_CORE1_TX_MX_BGTRIM 0x82 +#define RADIO_2055_CORE1_TXRF_RCAL 0x83 +#define RADIO_2055_CORE1_TXRF_PAD_TSSI1 0x84 +#define RADIO_2055_CORE1_TXRF_PAD_TSSI2 0x85 +#define RADIO_2055_CORE1_TX_RF_SPARE 0x86 +#define RADIO_2055_CORE1_TXRF_IQCAL1 0x87 +#define RADIO_2055_CORE1_TXRF_IQCAL2 0x88 +#define RADIO_2055_CORE1_TXBB_RCCAL_CTRL 0x89 +#define RADIO_2055_CORE1_TXBB_LPF1 0x8a +#define RADIO_2055_CORE1_TX_VOS_CNCL 0x8b +#define RADIO_2055_CORE1_TX_LPF_MXGM_IDAC 0x8c +#define RADIO_2055_CORE1_TX_BB_MXGM 0x8d +#define RADIO_2055_CORE2_LGBUF_A_TUNE 0x8e +#define RADIO_2055_CORE2_LGBUF_G_TUNE 0x8f +#define RADIO_2055_CORE2_LGBUF_DIV 0x90 +#define RADIO_2055_CORE2_LGBUF_A_IDAC 0x91 +#define RADIO_2055_CORE2_LGBUF_G_IDAC 0x92 +#define RADIO_2055_CORE2_LGBUF_IDACFIL_OVR 0x93 +#define RADIO_2055_CORE2_LGBUF_SPARE 0x94 +#define RADIO_2055_CORE2_RXRF_SPC1 0x95 +#define RADIO_2055_CORE2_RXRF_REG1 0x96 +#define RADIO_2055_CORE2_RXRF_REG2 0x97 +#define RADIO_2055_CORE2_RXRF_RCAL 0x98 +#define RADIO_2055_CORE2_RXBB_BUFI_LPFCMP 0x99 +#define RADIO_2055_CORE2_RXBB_LPF 0x9a +#define RADIO_2055_CORE2_RXBB_MIDAC_HIPAS 0x9b +#define RADIO_2055_CORE2_RXBB_VGA1_IDAC 0x9c +#define RADIO_2055_CORE2_RXBB_VGA2_IDAC 0x9d +#define RADIO_2055_CORE2_RXBB_VGA3_IDAC 0x9e +#define RADIO_2055_CORE2_RXBB_BUFO_CTRL 0x9f +#define RADIO_2055_CORE2_RXBB_RCCAL_CTRL 0xa0 +#define RADIO_2055_CORE2_RXBB_RSSI_CTRL1 0xa1 +#define RADIO_2055_CORE2_RXBB_RSSI_CTRL2 0xa2 +#define RADIO_2055_CORE2_RXBB_RSSI_CTRL3 0xa3 +#define RADIO_2055_CORE2_RXBB_RSSI_CTRL4 0xa4 +#define RADIO_2055_CORE2_RXBB_RSSI_CTRL5 0xa5 +#define RADIO_2055_CORE2_RXBB_REGULATOR 0xa6 +#define RADIO_2055_CORE2_RXBB_SPARE1 0xa7 +#define RADIO_2055_CORE2_RXTXBB_RCAL 0xa8 +#define RADIO_2055_CORE2_TXRF_SGM_PGA 0xa9 +#define RADIO_2055_CORE2_TXRF_SGM_PAD 0xaa +#define RADIO_2055_CORE2_TXRF_CNTR_PGA1 0xab +#define RADIO_2055_CORE2_TXRF_CNTR_PAD1 0xac +#define RADIO_2055_CORE2_TX_RFPGA_IDAC 0xad +#define RADIO_2055_CORE2_TX_PGA_PAD_TN 0xae +#define RADIO_2055_CORE2_TX_PAD_IDAC1 0xaf +#define RADIO_2055_CORE2_TX_PAD_IDAC2 0xb0 +#define RADIO_2055_CORE2_TX_MX_BGTRIM 0xb1 +#define RADIO_2055_CORE2_TXRF_RCAL 0xb2 +#define RADIO_2055_CORE2_TXRF_PAD_TSSI1 0xb3 +#define RADIO_2055_CORE2_TXRF_PAD_TSSI2 0xb4 +#define RADIO_2055_CORE2_TX_RF_SPARE 0xb5 +#define RADIO_2055_CORE2_TXRF_IQCAL1 0xb6 +#define RADIO_2055_CORE2_TXRF_IQCAL2 0xb7 +#define RADIO_2055_CORE2_TXBB_RCCAL_CTRL 0xb8 +#define RADIO_2055_CORE2_TXBB_LPF1 0xb9 +#define RADIO_2055_CORE2_TX_VOS_CNCL 0xba +#define RADIO_2055_CORE2_TX_LPF_MXGM_IDAC 0xbb +#define RADIO_2055_CORE2_TX_BB_MXGM 0xbc +#define RADIO_2055_PRG_GC_HPVGA23_21 0xbd +#define RADIO_2055_PRG_GC_HPVGA23_22 0xbe +#define RADIO_2055_PRG_GC_HPVGA23_23 0xbf +#define RADIO_2055_PRG_GC_HPVGA23_24 0xc0 +#define RADIO_2055_PRG_GC_HPVGA23_25 0xc1 +#define RADIO_2055_PRG_GC_HPVGA23_26 0xc2 +#define RADIO_2055_PRG_GC_HPVGA23_27 0xc3 +#define RADIO_2055_PRG_GC_HPVGA23_28 0xc4 +#define RADIO_2055_PRG_GC_HPVGA23_29 0xc5 +#define RADIO_2055_PRG_GC_HPVGA23_30 0xc6 +#define RADIO_2055_CORE1_LNA_GAINBST 0xcd +#define RADIO_2055_CORE1_B0_NBRSSI_VCM 0xd2 +#define RADIO_2055_CORE1_GEN_SPARE2 0xd6 +#define RADIO_2055_CORE2_LNA_GAINBST 0xd9 +#define RADIO_2055_CORE2_B0_NBRSSI_VCM 0xde +#define RADIO_2055_CORE2_GEN_SPARE2 0xe2 + +#define RADIO_2055_GAINBST_GAIN_DB 6 +#define RADIO_2055_GAINBST_CODE 0x6 + +#define RADIO_2055_JTAGCTRL_MASK 0x04 +#define RADIO_2055_JTAGSYNC_MASK 0x08 +#define RADIO_2055_RRCAL_START 0x40 +#define RADIO_2055_RRCAL_RST_N 0x01 +#define RADIO_2055_CAL_LPO_ENABLE 0x80 +#define RADIO_2055_RCAL_DONE 0x80 +#define RADIO_2055_NBRSSI_VCM_I_MASK 0x03 +#define RADIO_2055_NBRSSI_VCM_I_SHIFT 0x00 +#define RADIO_2055_NBRSSI_VCM_Q_MASK 0x03 +#define RADIO_2055_NBRSSI_VCM_Q_SHIFT 0x00 +#define RADIO_2055_WBRSSI_VCM_IQ_MASK 0x0c +#define RADIO_2055_WBRSSI_VCM_IQ_SHIFT 0x02 +#define RADIO_2055_NBRSSI_PD 0x01 +#define RADIO_2055_WBRSSI_G1_PD 0x04 +#define RADIO_2055_WBRSSI_G2_PD 0x02 +#define RADIO_2055_NBRSSI_SEL 0x01 +#define RADIO_2055_WBRSSI_G1_SEL 0x04 +#define RADIO_2055_WBRSSI_G2_SEL 0x02 +#define RADIO_2055_COUPLE_RX_MASK 0x01 +#define RADIO_2055_COUPLE_TX_MASK 0x02 +#define RADIO_2055_GAINBST_DISABLE 0x02 +#define RADIO_2055_GAINBST_VAL_MASK 0x07 +#define RADIO_2055_RXMX_GC_MASK 0x0c + +#define RADIO_MIMO_CORESEL_OFF 0x0 +#define RADIO_MIMO_CORESEL_CORE1 0x1 +#define RADIO_MIMO_CORESEL_CORE2 0x2 +#define RADIO_MIMO_CORESEL_CORE3 0x3 +#define RADIO_MIMO_CORESEL_CORE4 0x4 +#define RADIO_MIMO_CORESEL_ALLRX 0x5 +#define RADIO_MIMO_CORESEL_ALLTX 0x6 +#define RADIO_MIMO_CORESEL_ALLRXTX 0x7 + +#define RADIO_2064_READ_OFF 0x200 + +#define RADIO_2064_REG000 0x0 +#define RADIO_2064_REG001 0x1 +#define RADIO_2064_REG002 0x2 +#define RADIO_2064_REG003 0x3 +#define RADIO_2064_REG004 0x4 +#define RADIO_2064_REG005 0x5 +#define RADIO_2064_REG006 0x6 +#define RADIO_2064_REG007 0x7 +#define RADIO_2064_REG008 0x8 +#define RADIO_2064_REG009 0x9 +#define RADIO_2064_REG00A 0xa +#define RADIO_2064_REG00B 0xb +#define RADIO_2064_REG00C 0xc +#define RADIO_2064_REG00D 0xd +#define RADIO_2064_REG00E 0xe +#define RADIO_2064_REG00F 0xf +#define RADIO_2064_REG010 0x10 +#define RADIO_2064_REG011 0x11 +#define RADIO_2064_REG012 0x12 +#define RADIO_2064_REG013 0x13 +#define RADIO_2064_REG014 0x14 +#define RADIO_2064_REG015 0x15 +#define RADIO_2064_REG016 0x16 +#define RADIO_2064_REG017 0x17 +#define RADIO_2064_REG018 0x18 +#define RADIO_2064_REG019 0x19 +#define RADIO_2064_REG01A 0x1a +#define RADIO_2064_REG01B 0x1b +#define RADIO_2064_REG01C 0x1c +#define RADIO_2064_REG01D 0x1d +#define RADIO_2064_REG01E 0x1e +#define RADIO_2064_REG01F 0x1f +#define RADIO_2064_REG020 0x20 +#define RADIO_2064_REG021 0x21 +#define RADIO_2064_REG022 0x22 +#define RADIO_2064_REG023 0x23 +#define RADIO_2064_REG024 0x24 +#define RADIO_2064_REG025 0x25 +#define RADIO_2064_REG026 0x26 +#define RADIO_2064_REG027 0x27 +#define RADIO_2064_REG028 0x28 +#define RADIO_2064_REG029 0x29 +#define RADIO_2064_REG02A 0x2a +#define RADIO_2064_REG02B 0x2b +#define RADIO_2064_REG02C 0x2c +#define RADIO_2064_REG02D 0x2d +#define RADIO_2064_REG02E 0x2e +#define RADIO_2064_REG02F 0x2f +#define RADIO_2064_REG030 0x30 +#define RADIO_2064_REG031 0x31 +#define RADIO_2064_REG032 0x32 +#define RADIO_2064_REG033 0x33 +#define RADIO_2064_REG034 0x34 +#define RADIO_2064_REG035 0x35 +#define RADIO_2064_REG036 0x36 +#define RADIO_2064_REG037 0x37 +#define RADIO_2064_REG038 0x38 +#define RADIO_2064_REG039 0x39 +#define RADIO_2064_REG03A 0x3a +#define RADIO_2064_REG03B 0x3b +#define RADIO_2064_REG03C 0x3c +#define RADIO_2064_REG03D 0x3d +#define RADIO_2064_REG03E 0x3e +#define RADIO_2064_REG03F 0x3f +#define RADIO_2064_REG040 0x40 +#define RADIO_2064_REG041 0x41 +#define RADIO_2064_REG042 0x42 +#define RADIO_2064_REG043 0x43 +#define RADIO_2064_REG044 0x44 +#define RADIO_2064_REG045 0x45 +#define RADIO_2064_REG046 0x46 +#define RADIO_2064_REG047 0x47 +#define RADIO_2064_REG048 0x48 +#define RADIO_2064_REG049 0x49 +#define RADIO_2064_REG04A 0x4a +#define RADIO_2064_REG04B 0x4b +#define RADIO_2064_REG04C 0x4c +#define RADIO_2064_REG04D 0x4d +#define RADIO_2064_REG04E 0x4e +#define RADIO_2064_REG04F 0x4f +#define RADIO_2064_REG050 0x50 +#define RADIO_2064_REG051 0x51 +#define RADIO_2064_REG052 0x52 +#define RADIO_2064_REG053 0x53 +#define RADIO_2064_REG054 0x54 +#define RADIO_2064_REG055 0x55 +#define RADIO_2064_REG056 0x56 +#define RADIO_2064_REG057 0x57 +#define RADIO_2064_REG058 0x58 +#define RADIO_2064_REG059 0x59 +#define RADIO_2064_REG05A 0x5a +#define RADIO_2064_REG05B 0x5b +#define RADIO_2064_REG05C 0x5c +#define RADIO_2064_REG05D 0x5d +#define RADIO_2064_REG05E 0x5e +#define RADIO_2064_REG05F 0x5f +#define RADIO_2064_REG060 0x60 +#define RADIO_2064_REG061 0x61 +#define RADIO_2064_REG062 0x62 +#define RADIO_2064_REG063 0x63 +#define RADIO_2064_REG064 0x64 +#define RADIO_2064_REG065 0x65 +#define RADIO_2064_REG066 0x66 +#define RADIO_2064_REG067 0x67 +#define RADIO_2064_REG068 0x68 +#define RADIO_2064_REG069 0x69 +#define RADIO_2064_REG06A 0x6a +#define RADIO_2064_REG06B 0x6b +#define RADIO_2064_REG06C 0x6c +#define RADIO_2064_REG06D 0x6d +#define RADIO_2064_REG06E 0x6e +#define RADIO_2064_REG06F 0x6f +#define RADIO_2064_REG070 0x70 +#define RADIO_2064_REG071 0x71 +#define RADIO_2064_REG072 0x72 +#define RADIO_2064_REG073 0x73 +#define RADIO_2064_REG074 0x74 +#define RADIO_2064_REG075 0x75 +#define RADIO_2064_REG076 0x76 +#define RADIO_2064_REG077 0x77 +#define RADIO_2064_REG078 0x78 +#define RADIO_2064_REG079 0x79 +#define RADIO_2064_REG07A 0x7a +#define RADIO_2064_REG07B 0x7b +#define RADIO_2064_REG07C 0x7c +#define RADIO_2064_REG07D 0x7d +#define RADIO_2064_REG07E 0x7e +#define RADIO_2064_REG07F 0x7f +#define RADIO_2064_REG080 0x80 +#define RADIO_2064_REG081 0x81 +#define RADIO_2064_REG082 0x82 +#define RADIO_2064_REG083 0x83 +#define RADIO_2064_REG084 0x84 +#define RADIO_2064_REG085 0x85 +#define RADIO_2064_REG086 0x86 +#define RADIO_2064_REG087 0x87 +#define RADIO_2064_REG088 0x88 +#define RADIO_2064_REG089 0x89 +#define RADIO_2064_REG08A 0x8a +#define RADIO_2064_REG08B 0x8b +#define RADIO_2064_REG08C 0x8c +#define RADIO_2064_REG08D 0x8d +#define RADIO_2064_REG08E 0x8e +#define RADIO_2064_REG08F 0x8f +#define RADIO_2064_REG090 0x90 +#define RADIO_2064_REG091 0x91 +#define RADIO_2064_REG092 0x92 +#define RADIO_2064_REG093 0x93 +#define RADIO_2064_REG094 0x94 +#define RADIO_2064_REG095 0x95 +#define RADIO_2064_REG096 0x96 +#define RADIO_2064_REG097 0x97 +#define RADIO_2064_REG098 0x98 +#define RADIO_2064_REG099 0x99 +#define RADIO_2064_REG09A 0x9a +#define RADIO_2064_REG09B 0x9b +#define RADIO_2064_REG09C 0x9c +#define RADIO_2064_REG09D 0x9d +#define RADIO_2064_REG09E 0x9e +#define RADIO_2064_REG09F 0x9f +#define RADIO_2064_REG0A0 0xa0 +#define RADIO_2064_REG0A1 0xa1 +#define RADIO_2064_REG0A2 0xa2 +#define RADIO_2064_REG0A3 0xa3 +#define RADIO_2064_REG0A4 0xa4 +#define RADIO_2064_REG0A5 0xa5 +#define RADIO_2064_REG0A6 0xa6 +#define RADIO_2064_REG0A7 0xa7 +#define RADIO_2064_REG0A8 0xa8 +#define RADIO_2064_REG0A9 0xa9 +#define RADIO_2064_REG0AA 0xaa +#define RADIO_2064_REG0AB 0xab +#define RADIO_2064_REG0AC 0xac +#define RADIO_2064_REG0AD 0xad +#define RADIO_2064_REG0AE 0xae +#define RADIO_2064_REG0AF 0xaf +#define RADIO_2064_REG0B0 0xb0 +#define RADIO_2064_REG0B1 0xb1 +#define RADIO_2064_REG0B2 0xb2 +#define RADIO_2064_REG0B3 0xb3 +#define RADIO_2064_REG0B4 0xb4 +#define RADIO_2064_REG0B5 0xb5 +#define RADIO_2064_REG0B6 0xb6 +#define RADIO_2064_REG0B7 0xb7 +#define RADIO_2064_REG0B8 0xb8 +#define RADIO_2064_REG0B9 0xb9 +#define RADIO_2064_REG0BA 0xba +#define RADIO_2064_REG0BB 0xbb +#define RADIO_2064_REG0BC 0xbc +#define RADIO_2064_REG0BD 0xbd +#define RADIO_2064_REG0BE 0xbe +#define RADIO_2064_REG0BF 0xbf +#define RADIO_2064_REG0C0 0xc0 +#define RADIO_2064_REG0C1 0xc1 +#define RADIO_2064_REG0C2 0xc2 +#define RADIO_2064_REG0C3 0xc3 +#define RADIO_2064_REG0C4 0xc4 +#define RADIO_2064_REG0C5 0xc5 +#define RADIO_2064_REG0C6 0xc6 +#define RADIO_2064_REG0C7 0xc7 +#define RADIO_2064_REG0C8 0xc8 +#define RADIO_2064_REG0C9 0xc9 +#define RADIO_2064_REG0CA 0xca +#define RADIO_2064_REG0CB 0xcb +#define RADIO_2064_REG0CC 0xcc +#define RADIO_2064_REG0CD 0xcd +#define RADIO_2064_REG0CE 0xce +#define RADIO_2064_REG0CF 0xcf +#define RADIO_2064_REG0D0 0xd0 +#define RADIO_2064_REG0D1 0xd1 +#define RADIO_2064_REG0D2 0xd2 +#define RADIO_2064_REG0D3 0xd3 +#define RADIO_2064_REG0D4 0xd4 +#define RADIO_2064_REG0D5 0xd5 +#define RADIO_2064_REG0D6 0xd6 +#define RADIO_2064_REG0D7 0xd7 +#define RADIO_2064_REG0D8 0xd8 +#define RADIO_2064_REG0D9 0xd9 +#define RADIO_2064_REG0DA 0xda +#define RADIO_2064_REG0DB 0xdb +#define RADIO_2064_REG0DC 0xdc +#define RADIO_2064_REG0DD 0xdd +#define RADIO_2064_REG0DE 0xde +#define RADIO_2064_REG0DF 0xdf +#define RADIO_2064_REG0E0 0xe0 +#define RADIO_2064_REG0E1 0xe1 +#define RADIO_2064_REG0E2 0xe2 +#define RADIO_2064_REG0E3 0xe3 +#define RADIO_2064_REG0E4 0xe4 +#define RADIO_2064_REG0E5 0xe5 +#define RADIO_2064_REG0E6 0xe6 +#define RADIO_2064_REG0E7 0xe7 +#define RADIO_2064_REG0E8 0xe8 +#define RADIO_2064_REG0E9 0xe9 +#define RADIO_2064_REG0EA 0xea +#define RADIO_2064_REG0EB 0xeb +#define RADIO_2064_REG0EC 0xec +#define RADIO_2064_REG0ED 0xed +#define RADIO_2064_REG0EE 0xee +#define RADIO_2064_REG0EF 0xef +#define RADIO_2064_REG0F0 0xf0 +#define RADIO_2064_REG0F1 0xf1 +#define RADIO_2064_REG0F2 0xf2 +#define RADIO_2064_REG0F3 0xf3 +#define RADIO_2064_REG0F4 0xf4 +#define RADIO_2064_REG0F5 0xf5 +#define RADIO_2064_REG0F6 0xf6 +#define RADIO_2064_REG0F7 0xf7 +#define RADIO_2064_REG0F8 0xf8 +#define RADIO_2064_REG0F9 0xf9 +#define RADIO_2064_REG0FA 0xfa +#define RADIO_2064_REG0FB 0xfb +#define RADIO_2064_REG0FC 0xfc +#define RADIO_2064_REG0FD 0xfd +#define RADIO_2064_REG0FE 0xfe +#define RADIO_2064_REG0FF 0xff +#define RADIO_2064_REG100 0x100 +#define RADIO_2064_REG101 0x101 +#define RADIO_2064_REG102 0x102 +#define RADIO_2064_REG103 0x103 +#define RADIO_2064_REG104 0x104 +#define RADIO_2064_REG105 0x105 +#define RADIO_2064_REG106 0x106 +#define RADIO_2064_REG107 0x107 +#define RADIO_2064_REG108 0x108 +#define RADIO_2064_REG109 0x109 +#define RADIO_2064_REG10A 0x10a +#define RADIO_2064_REG10B 0x10b +#define RADIO_2064_REG10C 0x10c +#define RADIO_2064_REG10D 0x10d +#define RADIO_2064_REG10E 0x10e +#define RADIO_2064_REG10F 0x10f +#define RADIO_2064_REG110 0x110 +#define RADIO_2064_REG111 0x111 +#define RADIO_2064_REG112 0x112 +#define RADIO_2064_REG113 0x113 +#define RADIO_2064_REG114 0x114 +#define RADIO_2064_REG115 0x115 +#define RADIO_2064_REG116 0x116 +#define RADIO_2064_REG117 0x117 +#define RADIO_2064_REG118 0x118 +#define RADIO_2064_REG119 0x119 +#define RADIO_2064_REG11A 0x11a +#define RADIO_2064_REG11B 0x11b +#define RADIO_2064_REG11C 0x11c +#define RADIO_2064_REG11D 0x11d +#define RADIO_2064_REG11E 0x11e +#define RADIO_2064_REG11F 0x11f +#define RADIO_2064_REG120 0x120 +#define RADIO_2064_REG121 0x121 +#define RADIO_2064_REG122 0x122 +#define RADIO_2064_REG123 0x123 +#define RADIO_2064_REG124 0x124 +#define RADIO_2064_REG125 0x125 +#define RADIO_2064_REG126 0x126 +#define RADIO_2064_REG127 0x127 +#define RADIO_2064_REG128 0x128 +#define RADIO_2064_REG129 0x129 +#define RADIO_2064_REG12A 0x12a +#define RADIO_2064_REG12B 0x12b +#define RADIO_2064_REG12C 0x12c +#define RADIO_2064_REG12D 0x12d +#define RADIO_2064_REG12E 0x12e +#define RADIO_2064_REG12F 0x12f +#define RADIO_2064_REG130 0x130 + +#define RADIO_2056_SYN (0x0 << 12) +#define RADIO_2056_TX0 (0x2 << 12) +#define RADIO_2056_TX1 (0x3 << 12) +#define RADIO_2056_RX0 (0x6 << 12) +#define RADIO_2056_RX1 (0x7 << 12) +#define RADIO_2056_ALLTX (0xe << 12) +#define RADIO_2056_ALLRX (0xf << 12) + +#define RADIO_2056_SYN_RESERVED_ADDR0 0x0 +#define RADIO_2056_SYN_IDCODE 0x1 +#define RADIO_2056_SYN_RESERVED_ADDR2 0x2 +#define RADIO_2056_SYN_RESERVED_ADDR3 0x3 +#define RADIO_2056_SYN_RESERVED_ADDR4 0x4 +#define RADIO_2056_SYN_RESERVED_ADDR5 0x5 +#define RADIO_2056_SYN_RESERVED_ADDR6 0x6 +#define RADIO_2056_SYN_RESERVED_ADDR7 0x7 +#define RADIO_2056_SYN_COM_CTRL 0x8 +#define RADIO_2056_SYN_COM_PU 0x9 +#define RADIO_2056_SYN_COM_OVR 0xa +#define RADIO_2056_SYN_COM_RESET 0xb +#define RADIO_2056_SYN_COM_RCAL 0xc +#define RADIO_2056_SYN_COM_RC_RXLPF 0xd +#define RADIO_2056_SYN_COM_RC_TXLPF 0xe +#define RADIO_2056_SYN_COM_RC_RXHPF 0xf +#define RADIO_2056_SYN_RESERVED_ADDR16 0x10 +#define RADIO_2056_SYN_RESERVED_ADDR17 0x11 +#define RADIO_2056_SYN_RESERVED_ADDR18 0x12 +#define RADIO_2056_SYN_RESERVED_ADDR19 0x13 +#define RADIO_2056_SYN_RESERVED_ADDR20 0x14 +#define RADIO_2056_SYN_RESERVED_ADDR21 0x15 +#define RADIO_2056_SYN_RESERVED_ADDR22 0x16 +#define RADIO_2056_SYN_RESERVED_ADDR23 0x17 +#define RADIO_2056_SYN_RESERVED_ADDR24 0x18 +#define RADIO_2056_SYN_RESERVED_ADDR25 0x19 +#define RADIO_2056_SYN_RESERVED_ADDR26 0x1a +#define RADIO_2056_SYN_RESERVED_ADDR27 0x1b +#define RADIO_2056_SYN_RESERVED_ADDR28 0x1c +#define RADIO_2056_SYN_RESERVED_ADDR29 0x1d +#define RADIO_2056_SYN_RESERVED_ADDR30 0x1e +#define RADIO_2056_SYN_RESERVED_ADDR31 0x1f +#define RADIO_2056_SYN_GPIO_MASTER1 0x20 +#define RADIO_2056_SYN_GPIO_MASTER2 0x21 +#define RADIO_2056_SYN_TOPBIAS_MASTER 0x22 +#define RADIO_2056_SYN_TOPBIAS_RCAL 0x23 +#define RADIO_2056_SYN_AFEREG 0x24 +#define RADIO_2056_SYN_TEMPPROCSENSE 0x25 +#define RADIO_2056_SYN_TEMPPROCSENSEIDAC 0x26 +#define RADIO_2056_SYN_TEMPPROCSENSERCAL 0x27 +#define RADIO_2056_SYN_LPO 0x28 +#define RADIO_2056_SYN_VDDCAL_MASTER 0x29 +#define RADIO_2056_SYN_VDDCAL_IDAC 0x2a +#define RADIO_2056_SYN_VDDCAL_STATUS 0x2b +#define RADIO_2056_SYN_RCAL_MASTER 0x2c +#define RADIO_2056_SYN_RCAL_CODE_OUT 0x2d +#define RADIO_2056_SYN_RCCAL_CTRL0 0x2e +#define RADIO_2056_SYN_RCCAL_CTRL1 0x2f +#define RADIO_2056_SYN_RCCAL_CTRL2 0x30 +#define RADIO_2056_SYN_RCCAL_CTRL3 0x31 +#define RADIO_2056_SYN_RCCAL_CTRL4 0x32 +#define RADIO_2056_SYN_RCCAL_CTRL5 0x33 +#define RADIO_2056_SYN_RCCAL_CTRL6 0x34 +#define RADIO_2056_SYN_RCCAL_CTRL7 0x35 +#define RADIO_2056_SYN_RCCAL_CTRL8 0x36 +#define RADIO_2056_SYN_RCCAL_CTRL9 0x37 +#define RADIO_2056_SYN_RCCAL_CTRL10 0x38 +#define RADIO_2056_SYN_RCCAL_CTRL11 0x39 +#define RADIO_2056_SYN_ZCAL_SPARE1 0x3a +#define RADIO_2056_SYN_ZCAL_SPARE2 0x3b +#define RADIO_2056_SYN_PLL_MAST1 0x3c +#define RADIO_2056_SYN_PLL_MAST2 0x3d +#define RADIO_2056_SYN_PLL_MAST3 0x3e +#define RADIO_2056_SYN_PLL_BIAS_RESET 0x3f +#define RADIO_2056_SYN_PLL_XTAL0 0x40 +#define RADIO_2056_SYN_PLL_XTAL1 0x41 +#define RADIO_2056_SYN_PLL_XTAL3 0x42 +#define RADIO_2056_SYN_PLL_XTAL4 0x43 +#define RADIO_2056_SYN_PLL_XTAL5 0x44 +#define RADIO_2056_SYN_PLL_XTAL6 0x45 +#define RADIO_2056_SYN_PLL_REFDIV 0x46 +#define RADIO_2056_SYN_PLL_PFD 0x47 +#define RADIO_2056_SYN_PLL_CP1 0x48 +#define RADIO_2056_SYN_PLL_CP2 0x49 +#define RADIO_2056_SYN_PLL_CP3 0x4a +#define RADIO_2056_SYN_PLL_LOOPFILTER1 0x4b +#define RADIO_2056_SYN_PLL_LOOPFILTER2 0x4c +#define RADIO_2056_SYN_PLL_LOOPFILTER3 0x4d +#define RADIO_2056_SYN_PLL_LOOPFILTER4 0x4e +#define RADIO_2056_SYN_PLL_LOOPFILTER5 0x4f +#define RADIO_2056_SYN_PLL_MMD1 0x50 +#define RADIO_2056_SYN_PLL_MMD2 0x51 +#define RADIO_2056_SYN_PLL_VCO1 0x52 +#define RADIO_2056_SYN_PLL_VCO2 0x53 +#define RADIO_2056_SYN_PLL_MONITOR1 0x54 +#define RADIO_2056_SYN_PLL_MONITOR2 0x55 +#define RADIO_2056_SYN_PLL_VCOCAL1 0x56 +#define RADIO_2056_SYN_PLL_VCOCAL2 0x57 +#define RADIO_2056_SYN_PLL_VCOCAL4 0x58 +#define RADIO_2056_SYN_PLL_VCOCAL5 0x59 +#define RADIO_2056_SYN_PLL_VCOCAL6 0x5a +#define RADIO_2056_SYN_PLL_VCOCAL7 0x5b +#define RADIO_2056_SYN_PLL_VCOCAL8 0x5c +#define RADIO_2056_SYN_PLL_VCOCAL9 0x5d +#define RADIO_2056_SYN_PLL_VCOCAL10 0x5e +#define RADIO_2056_SYN_PLL_VCOCAL11 0x5f +#define RADIO_2056_SYN_PLL_VCOCAL12 0x60 +#define RADIO_2056_SYN_PLL_VCOCAL13 0x61 +#define RADIO_2056_SYN_PLL_VREG 0x62 +#define RADIO_2056_SYN_PLL_STATUS1 0x63 +#define RADIO_2056_SYN_PLL_STATUS2 0x64 +#define RADIO_2056_SYN_PLL_STATUS3 0x65 +#define RADIO_2056_SYN_LOGEN_PU0 0x66 +#define RADIO_2056_SYN_LOGEN_PU1 0x67 +#define RADIO_2056_SYN_LOGEN_PU2 0x68 +#define RADIO_2056_SYN_LOGEN_PU3 0x69 +#define RADIO_2056_SYN_LOGEN_PU5 0x6a +#define RADIO_2056_SYN_LOGEN_PU6 0x6b +#define RADIO_2056_SYN_LOGEN_PU7 0x6c +#define RADIO_2056_SYN_LOGEN_PU8 0x6d +#define RADIO_2056_SYN_LOGEN_BIAS_RESET 0x6e +#define RADIO_2056_SYN_LOGEN_RCCR1 0x6f +#define RADIO_2056_SYN_LOGEN_VCOBUF1 0x70 +#define RADIO_2056_SYN_LOGEN_MIXER1 0x71 +#define RADIO_2056_SYN_LOGEN_MIXER2 0x72 +#define RADIO_2056_SYN_LOGEN_BUF1 0x73 +#define RADIO_2056_SYN_LOGENBUF2 0x74 +#define RADIO_2056_SYN_LOGEN_BUF3 0x75 +#define RADIO_2056_SYN_LOGEN_BUF4 0x76 +#define RADIO_2056_SYN_LOGEN_DIV1 0x77 +#define RADIO_2056_SYN_LOGEN_DIV2 0x78 +#define RADIO_2056_SYN_LOGEN_DIV3 0x79 +#define RADIO_2056_SYN_LOGEN_ACL1 0x7a +#define RADIO_2056_SYN_LOGEN_ACL2 0x7b +#define RADIO_2056_SYN_LOGEN_ACL3 0x7c +#define RADIO_2056_SYN_LOGEN_ACL4 0x7d +#define RADIO_2056_SYN_LOGEN_ACL5 0x7e +#define RADIO_2056_SYN_LOGEN_ACL6 0x7f +#define RADIO_2056_SYN_LOGEN_ACLOUT 0x80 +#define RADIO_2056_SYN_LOGEN_ACLCAL1 0x81 +#define RADIO_2056_SYN_LOGEN_ACLCAL2 0x82 +#define RADIO_2056_SYN_LOGEN_ACLCAL3 0x83 +#define RADIO_2056_SYN_CALEN 0x84 +#define RADIO_2056_SYN_LOGEN_PEAKDET1 0x85 +#define RADIO_2056_SYN_LOGEN_CORE_ACL_OVR 0x86 +#define RADIO_2056_SYN_LOGEN_RX_DIFF_ACL_OVR 0x87 +#define RADIO_2056_SYN_LOGEN_TX_DIFF_ACL_OVR 0x88 +#define RADIO_2056_SYN_LOGEN_RX_CMOS_ACL_OVR 0x89 +#define RADIO_2056_SYN_LOGEN_TX_CMOS_ACL_OVR 0x8a +#define RADIO_2056_SYN_LOGEN_VCOBUF2 0x8b +#define RADIO_2056_SYN_LOGEN_MIXER3 0x8c +#define RADIO_2056_SYN_LOGEN_BUF5 0x8d +#define RADIO_2056_SYN_LOGEN_BUF6 0x8e +#define RADIO_2056_SYN_LOGEN_CBUFRX1 0x8f +#define RADIO_2056_SYN_LOGEN_CBUFRX2 0x90 +#define RADIO_2056_SYN_LOGEN_CBUFRX3 0x91 +#define RADIO_2056_SYN_LOGEN_CBUFRX4 0x92 +#define RADIO_2056_SYN_LOGEN_CBUFTX1 0x93 +#define RADIO_2056_SYN_LOGEN_CBUFTX2 0x94 +#define RADIO_2056_SYN_LOGEN_CBUFTX3 0x95 +#define RADIO_2056_SYN_LOGEN_CBUFTX4 0x96 +#define RADIO_2056_SYN_LOGEN_CMOSRX1 0x97 +#define RADIO_2056_SYN_LOGEN_CMOSRX2 0x98 +#define RADIO_2056_SYN_LOGEN_CMOSRX3 0x99 +#define RADIO_2056_SYN_LOGEN_CMOSRX4 0x9a +#define RADIO_2056_SYN_LOGEN_CMOSTX1 0x9b +#define RADIO_2056_SYN_LOGEN_CMOSTX2 0x9c +#define RADIO_2056_SYN_LOGEN_CMOSTX3 0x9d +#define RADIO_2056_SYN_LOGEN_CMOSTX4 0x9e +#define RADIO_2056_SYN_LOGEN_VCOBUF2_OVRVAL 0x9f +#define RADIO_2056_SYN_LOGEN_MIXER3_OVRVAL 0xa0 +#define RADIO_2056_SYN_LOGEN_BUF5_OVRVAL 0xa1 +#define RADIO_2056_SYN_LOGEN_BUF6_OVRVAL 0xa2 +#define RADIO_2056_SYN_LOGEN_CBUFRX1_OVRVAL 0xa3 +#define RADIO_2056_SYN_LOGEN_CBUFRX2_OVRVAL 0xa4 +#define RADIO_2056_SYN_LOGEN_CBUFRX3_OVRVAL 0xa5 +#define RADIO_2056_SYN_LOGEN_CBUFRX4_OVRVAL 0xa6 +#define RADIO_2056_SYN_LOGEN_CBUFTX1_OVRVAL 0xa7 +#define RADIO_2056_SYN_LOGEN_CBUFTX2_OVRVAL 0xa8 +#define RADIO_2056_SYN_LOGEN_CBUFTX3_OVRVAL 0xa9 +#define RADIO_2056_SYN_LOGEN_CBUFTX4_OVRVAL 0xaa +#define RADIO_2056_SYN_LOGEN_CMOSRX1_OVRVAL 0xab +#define RADIO_2056_SYN_LOGEN_CMOSRX2_OVRVAL 0xac +#define RADIO_2056_SYN_LOGEN_CMOSRX3_OVRVAL 0xad +#define RADIO_2056_SYN_LOGEN_CMOSRX4_OVRVAL 0xae +#define RADIO_2056_SYN_LOGEN_CMOSTX1_OVRVAL 0xaf +#define RADIO_2056_SYN_LOGEN_CMOSTX2_OVRVAL 0xb0 +#define RADIO_2056_SYN_LOGEN_CMOSTX3_OVRVAL 0xb1 +#define RADIO_2056_SYN_LOGEN_CMOSTX4_OVRVAL 0xb2 +#define RADIO_2056_SYN_LOGEN_ACL_WAITCNT 0xb3 +#define RADIO_2056_SYN_LOGEN_CORE_CALVALID 0xb4 +#define RADIO_2056_SYN_LOGEN_RX_CMOS_CALVALID 0xb5 +#define RADIO_2056_SYN_LOGEN_TX_CMOS_VALID 0xb6 + +#define RADIO_2056_TX_RESERVED_ADDR0 0x0 +#define RADIO_2056_TX_IDCODE 0x1 +#define RADIO_2056_TX_RESERVED_ADDR2 0x2 +#define RADIO_2056_TX_RESERVED_ADDR3 0x3 +#define RADIO_2056_TX_RESERVED_ADDR4 0x4 +#define RADIO_2056_TX_RESERVED_ADDR5 0x5 +#define RADIO_2056_TX_RESERVED_ADDR6 0x6 +#define RADIO_2056_TX_RESERVED_ADDR7 0x7 +#define RADIO_2056_TX_COM_CTRL 0x8 +#define RADIO_2056_TX_COM_PU 0x9 +#define RADIO_2056_TX_COM_OVR 0xa +#define RADIO_2056_TX_COM_RESET 0xb +#define RADIO_2056_TX_COM_RCAL 0xc +#define RADIO_2056_TX_COM_RC_RXLPF 0xd +#define RADIO_2056_TX_COM_RC_TXLPF 0xe +#define RADIO_2056_TX_COM_RC_RXHPF 0xf +#define RADIO_2056_TX_RESERVED_ADDR16 0x10 +#define RADIO_2056_TX_RESERVED_ADDR17 0x11 +#define RADIO_2056_TX_RESERVED_ADDR18 0x12 +#define RADIO_2056_TX_RESERVED_ADDR19 0x13 +#define RADIO_2056_TX_RESERVED_ADDR20 0x14 +#define RADIO_2056_TX_RESERVED_ADDR21 0x15 +#define RADIO_2056_TX_RESERVED_ADDR22 0x16 +#define RADIO_2056_TX_RESERVED_ADDR23 0x17 +#define RADIO_2056_TX_RESERVED_ADDR24 0x18 +#define RADIO_2056_TX_RESERVED_ADDR25 0x19 +#define RADIO_2056_TX_RESERVED_ADDR26 0x1a +#define RADIO_2056_TX_RESERVED_ADDR27 0x1b +#define RADIO_2056_TX_RESERVED_ADDR28 0x1c +#define RADIO_2056_TX_RESERVED_ADDR29 0x1d +#define RADIO_2056_TX_RESERVED_ADDR30 0x1e +#define RADIO_2056_TX_RESERVED_ADDR31 0x1f +#define RADIO_2056_TX_IQCAL_GAIN_BW 0x20 +#define RADIO_2056_TX_LOFT_FINE_I 0x21 +#define RADIO_2056_TX_LOFT_FINE_Q 0x22 +#define RADIO_2056_TX_LOFT_COARSE_I 0x23 +#define RADIO_2056_TX_LOFT_COARSE_Q 0x24 +#define RADIO_2056_TX_TX_COM_MASTER1 0x25 +#define RADIO_2056_TX_TX_COM_MASTER2 0x26 +#define RADIO_2056_TX_RXIQCAL_TXMUX 0x27 +#define RADIO_2056_TX_TX_SSI_MASTER 0x28 +#define RADIO_2056_TX_IQCAL_VCM_HG 0x29 +#define RADIO_2056_TX_IQCAL_IDAC 0x2a +#define RADIO_2056_TX_TSSI_VCM 0x2b +#define RADIO_2056_TX_TX_AMP_DET 0x2c +#define RADIO_2056_TX_TX_SSI_MUX 0x2d +#define RADIO_2056_TX_TSSIA 0x2e +#define RADIO_2056_TX_TSSIG 0x2f +#define RADIO_2056_TX_TSSI_MISC1 0x30 +#define RADIO_2056_TX_TSSI_MISC2 0x31 +#define RADIO_2056_TX_TSSI_MISC3 0x32 +#define RADIO_2056_TX_PA_SPARE1 0x33 +#define RADIO_2056_TX_PA_SPARE2 0x34 +#define RADIO_2056_TX_INTPAA_MASTER 0x35 +#define RADIO_2056_TX_INTPAA_GAIN 0x36 +#define RADIO_2056_TX_INTPAA_BOOST_TUNE 0x37 +#define RADIO_2056_TX_INTPAA_IAUX_STAT 0x38 +#define RADIO_2056_TX_INTPAA_IAUX_DYN 0x39 +#define RADIO_2056_TX_INTPAA_IMAIN_STAT 0x3a +#define RADIO_2056_TX_INTPAA_IMAIN_DYN 0x3b +#define RADIO_2056_TX_INTPAA_CASCBIAS 0x3c +#define RADIO_2056_TX_INTPAA_PASLOPE 0x3d +#define RADIO_2056_TX_INTPAA_PA_MISC 0x3e +#define RADIO_2056_TX_INTPAG_MASTER 0x3f +#define RADIO_2056_TX_INTPAG_GAIN 0x40 +#define RADIO_2056_TX_INTPAG_BOOST_TUNE 0x41 +#define RADIO_2056_TX_INTPAG_IAUX_STAT 0x42 +#define RADIO_2056_TX_INTPAG_IAUX_DYN 0x43 +#define RADIO_2056_TX_INTPAG_IMAIN_STAT 0x44 +#define RADIO_2056_TX_INTPAG_IMAIN_DYN 0x45 +#define RADIO_2056_TX_INTPAG_CASCBIAS 0x46 +#define RADIO_2056_TX_INTPAG_PASLOPE 0x47 +#define RADIO_2056_TX_INTPAG_PA_MISC 0x48 +#define RADIO_2056_TX_PADA_MASTER 0x49 +#define RADIO_2056_TX_PADA_IDAC 0x4a +#define RADIO_2056_TX_PADA_CASCBIAS 0x4b +#define RADIO_2056_TX_PADA_GAIN 0x4c +#define RADIO_2056_TX_PADA_BOOST_TUNE 0x4d +#define RADIO_2056_TX_PADA_SLOPE 0x4e +#define RADIO_2056_TX_PADG_MASTER 0x4f +#define RADIO_2056_TX_PADG_IDAC 0x50 +#define RADIO_2056_TX_PADG_CASCBIAS 0x51 +#define RADIO_2056_TX_PADG_GAIN 0x52 +#define RADIO_2056_TX_PADG_BOOST_TUNE 0x53 +#define RADIO_2056_TX_PADG_SLOPE 0x54 +#define RADIO_2056_TX_PGAA_MASTER 0x55 +#define RADIO_2056_TX_PGAA_IDAC 0x56 +#define RADIO_2056_TX_PGAA_GAIN 0x57 +#define RADIO_2056_TX_PGAA_BOOST_TUNE 0x58 +#define RADIO_2056_TX_PGAA_SLOPE 0x59 +#define RADIO_2056_TX_PGAA_MISC 0x5a +#define RADIO_2056_TX_PGAG_MASTER 0x5b +#define RADIO_2056_TX_PGAG_IDAC 0x5c +#define RADIO_2056_TX_PGAG_GAIN 0x5d +#define RADIO_2056_TX_PGAG_BOOST_TUNE 0x5e +#define RADIO_2056_TX_PGAG_SLOPE 0x5f +#define RADIO_2056_TX_PGAG_MISC 0x60 +#define RADIO_2056_TX_MIXA_MASTER 0x61 +#define RADIO_2056_TX_MIXA_BOOST_TUNE 0x62 +#define RADIO_2056_TX_MIXG 0x63 +#define RADIO_2056_TX_MIXG_BOOST_TUNE 0x64 +#define RADIO_2056_TX_BB_GM_MASTER 0x65 +#define RADIO_2056_TX_GMBB_GM 0x66 +#define RADIO_2056_TX_GMBB_IDAC 0x67 +#define RADIO_2056_TX_TXLPF_MASTER 0x68 +#define RADIO_2056_TX_TXLPF_RCCAL 0x69 +#define RADIO_2056_TX_TXLPF_RCCAL_OFF0 0x6a +#define RADIO_2056_TX_TXLPF_RCCAL_OFF1 0x6b +#define RADIO_2056_TX_TXLPF_RCCAL_OFF2 0x6c +#define RADIO_2056_TX_TXLPF_RCCAL_OFF3 0x6d +#define RADIO_2056_TX_TXLPF_RCCAL_OFF4 0x6e +#define RADIO_2056_TX_TXLPF_RCCAL_OFF5 0x6f +#define RADIO_2056_TX_TXLPF_RCCAL_OFF6 0x70 +#define RADIO_2056_TX_TXLPF_BW 0x71 +#define RADIO_2056_TX_TXLPF_GAIN 0x72 +#define RADIO_2056_TX_TXLPF_IDAC 0x73 +#define RADIO_2056_TX_TXLPF_IDAC_0 0x74 +#define RADIO_2056_TX_TXLPF_IDAC_1 0x75 +#define RADIO_2056_TX_TXLPF_IDAC_2 0x76 +#define RADIO_2056_TX_TXLPF_IDAC_3 0x77 +#define RADIO_2056_TX_TXLPF_IDAC_4 0x78 +#define RADIO_2056_TX_TXLPF_IDAC_5 0x79 +#define RADIO_2056_TX_TXLPF_IDAC_6 0x7a +#define RADIO_2056_TX_TXLPF_OPAMP_IDAC 0x7b +#define RADIO_2056_TX_TXLPF_MISC 0x7c +#define RADIO_2056_TX_TXSPARE1 0x7d +#define RADIO_2056_TX_TXSPARE2 0x7e +#define RADIO_2056_TX_TXSPARE3 0x7f +#define RADIO_2056_TX_TXSPARE4 0x80 +#define RADIO_2056_TX_TXSPARE5 0x81 +#define RADIO_2056_TX_TXSPARE6 0x82 +#define RADIO_2056_TX_TXSPARE7 0x83 +#define RADIO_2056_TX_TXSPARE8 0x84 +#define RADIO_2056_TX_TXSPARE9 0x85 +#define RADIO_2056_TX_TXSPARE10 0x86 +#define RADIO_2056_TX_TXSPARE11 0x87 +#define RADIO_2056_TX_TXSPARE12 0x88 +#define RADIO_2056_TX_TXSPARE13 0x89 +#define RADIO_2056_TX_TXSPARE14 0x8a +#define RADIO_2056_TX_TXSPARE15 0x8b +#define RADIO_2056_TX_TXSPARE16 0x8c +#define RADIO_2056_TX_STATUS_INTPA_GAIN 0x8d +#define RADIO_2056_TX_STATUS_PAD_GAIN 0x8e +#define RADIO_2056_TX_STATUS_PGA_GAIN 0x8f +#define RADIO_2056_TX_STATUS_GM_TXLPF_GAIN 0x90 +#define RADIO_2056_TX_STATUS_TXLPF_BW 0x91 +#define RADIO_2056_TX_STATUS_TXLPF_RC 0x92 +#define RADIO_2056_TX_GMBB_IDAC0 0x93 +#define RADIO_2056_TX_GMBB_IDAC1 0x94 +#define RADIO_2056_TX_GMBB_IDAC2 0x95 +#define RADIO_2056_TX_GMBB_IDAC3 0x96 +#define RADIO_2056_TX_GMBB_IDAC4 0x97 +#define RADIO_2056_TX_GMBB_IDAC5 0x98 +#define RADIO_2056_TX_GMBB_IDAC6 0x99 +#define RADIO_2056_TX_GMBB_IDAC7 0x9a + +#define RADIO_2056_RX_RESERVED_ADDR0 0x0 +#define RADIO_2056_RX_IDCODE 0x1 +#define RADIO_2056_RX_RESERVED_ADDR2 0x2 +#define RADIO_2056_RX_RESERVED_ADDR3 0x3 +#define RADIO_2056_RX_RESERVED_ADDR4 0x4 +#define RADIO_2056_RX_RESERVED_ADDR5 0x5 +#define RADIO_2056_RX_RESERVED_ADDR6 0x6 +#define RADIO_2056_RX_RESERVED_ADDR7 0x7 +#define RADIO_2056_RX_COM_CTRL 0x8 +#define RADIO_2056_RX_COM_PU 0x9 +#define RADIO_2056_RX_COM_OVR 0xa +#define RADIO_2056_RX_COM_RESET 0xb +#define RADIO_2056_RX_COM_RCAL 0xc +#define RADIO_2056_RX_COM_RC_RXLPF 0xd +#define RADIO_2056_RX_COM_RC_TXLPF 0xe +#define RADIO_2056_RX_COM_RC_RXHPF 0xf +#define RADIO_2056_RX_RESERVED_ADDR16 0x10 +#define RADIO_2056_RX_RESERVED_ADDR17 0x11 +#define RADIO_2056_RX_RESERVED_ADDR18 0x12 +#define RADIO_2056_RX_RESERVED_ADDR19 0x13 +#define RADIO_2056_RX_RESERVED_ADDR20 0x14 +#define RADIO_2056_RX_RESERVED_ADDR21 0x15 +#define RADIO_2056_RX_RESERVED_ADDR22 0x16 +#define RADIO_2056_RX_RESERVED_ADDR23 0x17 +#define RADIO_2056_RX_RESERVED_ADDR24 0x18 +#define RADIO_2056_RX_RESERVED_ADDR25 0x19 +#define RADIO_2056_RX_RESERVED_ADDR26 0x1a +#define RADIO_2056_RX_RESERVED_ADDR27 0x1b +#define RADIO_2056_RX_RESERVED_ADDR28 0x1c +#define RADIO_2056_RX_RESERVED_ADDR29 0x1d +#define RADIO_2056_RX_RESERVED_ADDR30 0x1e +#define RADIO_2056_RX_RESERVED_ADDR31 0x1f +#define RADIO_2056_RX_RXIQCAL_RXMUX 0x20 +#define RADIO_2056_RX_RSSI_PU 0x21 +#define RADIO_2056_RX_RSSI_SEL 0x22 +#define RADIO_2056_RX_RSSI_GAIN 0x23 +#define RADIO_2056_RX_RSSI_NB_IDAC 0x24 +#define RADIO_2056_RX_RSSI_WB2I_IDAC_1 0x25 +#define RADIO_2056_RX_RSSI_WB2I_IDAC_2 0x26 +#define RADIO_2056_RX_RSSI_WB2Q_IDAC_1 0x27 +#define RADIO_2056_RX_RSSI_WB2Q_IDAC_2 0x28 +#define RADIO_2056_RX_RSSI_POLE 0x29 +#define RADIO_2056_RX_RSSI_WB1_IDAC 0x2a +#define RADIO_2056_RX_RSSI_MISC 0x2b +#define RADIO_2056_RX_LNAA_MASTER 0x2c +#define RADIO_2056_RX_LNAA_TUNE 0x2d +#define RADIO_2056_RX_LNAA_GAIN 0x2e +#define RADIO_2056_RX_LNA_A_SLOPE 0x2f +#define RADIO_2056_RX_BIASPOLE_LNAA1_IDAC 0x30 +#define RADIO_2056_RX_LNAA2_IDAC 0x31 +#define RADIO_2056_RX_LNA1A_MISC 0x32 +#define RADIO_2056_RX_LNAG_MASTER 0x33 +#define RADIO_2056_RX_LNAG_TUNE 0x34 +#define RADIO_2056_RX_LNAG_GAIN 0x35 +#define RADIO_2056_RX_LNA_G_SLOPE 0x36 +#define RADIO_2056_RX_BIASPOLE_LNAG1_IDAC 0x37 +#define RADIO_2056_RX_LNAG2_IDAC 0x38 +#define RADIO_2056_RX_LNA1G_MISC 0x39 +#define RADIO_2056_RX_MIXA_MASTER 0x3a +#define RADIO_2056_RX_MIXA_VCM 0x3b +#define RADIO_2056_RX_MIXA_CTRLPTAT 0x3c +#define RADIO_2056_RX_MIXA_LOB_BIAS 0x3d +#define RADIO_2056_RX_MIXA_CORE_IDAC 0x3e +#define RADIO_2056_RX_MIXA_CMFB_IDAC 0x3f +#define RADIO_2056_RX_MIXA_BIAS_AUX 0x40 +#define RADIO_2056_RX_MIXA_BIAS_MAIN 0x41 +#define RADIO_2056_RX_MIXA_BIAS_MISC 0x42 +#define RADIO_2056_RX_MIXA_MAST_BIAS 0x43 +#define RADIO_2056_RX_MIXG_MASTER 0x44 +#define RADIO_2056_RX_MIXG_VCM 0x45 +#define RADIO_2056_RX_MIXG_CTRLPTAT 0x46 +#define RADIO_2056_RX_MIXG_LOB_BIAS 0x47 +#define RADIO_2056_RX_MIXG_CORE_IDAC 0x48 +#define RADIO_2056_RX_MIXG_CMFB_IDAC 0x49 +#define RADIO_2056_RX_MIXG_BIAS_AUX 0x4a +#define RADIO_2056_RX_MIXG_BIAS_MAIN 0x4b +#define RADIO_2056_RX_MIXG_BIAS_MISC 0x4c +#define RADIO_2056_RX_MIXG_MAST_BIAS 0x4d +#define RADIO_2056_RX_TIA_MASTER 0x4e +#define RADIO_2056_RX_TIA_IOPAMP 0x4f +#define RADIO_2056_RX_TIA_QOPAMP 0x50 +#define RADIO_2056_RX_TIA_IMISC 0x51 +#define RADIO_2056_RX_TIA_QMISC 0x52 +#define RADIO_2056_RX_TIA_GAIN 0x53 +#define RADIO_2056_RX_TIA_SPARE1 0x54 +#define RADIO_2056_RX_TIA_SPARE2 0x55 +#define RADIO_2056_RX_BB_LPF_MASTER 0x56 +#define RADIO_2056_RX_AACI_MASTER 0x57 +#define RADIO_2056_RX_RXLPF_IDAC 0x58 +#define RADIO_2056_RX_RXLPF_OPAMPBIAS_LOWQ 0x59 +#define RADIO_2056_RX_RXLPF_OPAMPBIAS_HIGHQ 0x5a +#define RADIO_2056_RX_RXLPF_BIAS_DCCANCEL 0x5b +#define RADIO_2056_RX_RXLPF_OUTVCM 0x5c +#define RADIO_2056_RX_RXLPF_INVCM_BODY 0x5d +#define RADIO_2056_RX_RXLPF_CC_OP 0x5e +#define RADIO_2056_RX_RXLPF_GAIN 0x5f +#define RADIO_2056_RX_RXLPF_Q_BW 0x60 +#define RADIO_2056_RX_RXLPF_HP_CORNER_BW 0x61 +#define RADIO_2056_RX_RXLPF_RCCAL_HPC 0x62 +#define RADIO_2056_RX_RXHPF_OFF0 0x63 +#define RADIO_2056_RX_RXHPF_OFF1 0x64 +#define RADIO_2056_RX_RXHPF_OFF2 0x65 +#define RADIO_2056_RX_RXHPF_OFF3 0x66 +#define RADIO_2056_RX_RXHPF_OFF4 0x67 +#define RADIO_2056_RX_RXHPF_OFF5 0x68 +#define RADIO_2056_RX_RXHPF_OFF6 0x69 +#define RADIO_2056_RX_RXHPF_OFF7 0x6a +#define RADIO_2056_RX_RXLPF_RCCAL_LPC 0x6b +#define RADIO_2056_RX_RXLPF_OFF_0 0x6c +#define RADIO_2056_RX_RXLPF_OFF_1 0x6d +#define RADIO_2056_RX_RXLPF_OFF_2 0x6e +#define RADIO_2056_RX_RXLPF_OFF_3 0x6f +#define RADIO_2056_RX_RXLPF_OFF_4 0x70 +#define RADIO_2056_RX_UNUSED 0x71 +#define RADIO_2056_RX_VGA_MASTER 0x72 +#define RADIO_2056_RX_VGA_BIAS 0x73 +#define RADIO_2056_RX_VGA_BIAS_DCCANCEL 0x74 +#define RADIO_2056_RX_VGA_GAIN 0x75 +#define RADIO_2056_RX_VGA_HP_CORNER_BW 0x76 +#define RADIO_2056_RX_VGABUF_BIAS 0x77 +#define RADIO_2056_RX_VGABUF_GAIN_BW 0x78 +#define RADIO_2056_RX_TXFBMIX_A 0x79 +#define RADIO_2056_RX_TXFBMIX_G 0x7a +#define RADIO_2056_RX_RXSPARE1 0x7b +#define RADIO_2056_RX_RXSPARE2 0x7c +#define RADIO_2056_RX_RXSPARE3 0x7d +#define RADIO_2056_RX_RXSPARE4 0x7e +#define RADIO_2056_RX_RXSPARE5 0x7f +#define RADIO_2056_RX_RXSPARE6 0x80 +#define RADIO_2056_RX_RXSPARE7 0x81 +#define RADIO_2056_RX_RXSPARE8 0x82 +#define RADIO_2056_RX_RXSPARE9 0x83 +#define RADIO_2056_RX_RXSPARE10 0x84 +#define RADIO_2056_RX_RXSPARE11 0x85 +#define RADIO_2056_RX_RXSPARE12 0x86 +#define RADIO_2056_RX_RXSPARE13 0x87 +#define RADIO_2056_RX_RXSPARE14 0x88 +#define RADIO_2056_RX_RXSPARE15 0x89 +#define RADIO_2056_RX_RXSPARE16 0x8a +#define RADIO_2056_RX_STATUS_LNAA_GAIN 0x8b +#define RADIO_2056_RX_STATUS_LNAG_GAIN 0x8c +#define RADIO_2056_RX_STATUS_MIXTIA_GAIN 0x8d +#define RADIO_2056_RX_STATUS_RXLPF_GAIN 0x8e +#define RADIO_2056_RX_STATUS_VGA_BUF_GAIN 0x8f +#define RADIO_2056_RX_STATUS_RXLPF_Q 0x90 +#define RADIO_2056_RX_STATUS_RXLPF_BUF_BW 0x91 +#define RADIO_2056_RX_STATUS_RXLPF_VGA_HPC 0x92 +#define RADIO_2056_RX_STATUS_RXLPF_RC 0x93 +#define RADIO_2056_RX_STATUS_HPC_RC 0x94 + +#define RADIO_2056_LNA1_A_PU 0x01 +#define RADIO_2056_LNA2_A_PU 0x02 +#define RADIO_2056_LNA1_G_PU 0x01 +#define RADIO_2056_LNA2_G_PU 0x02 +#define RADIO_2056_MIXA_PU_I 0x01 +#define RADIO_2056_MIXA_PU_Q 0x02 +#define RADIO_2056_MIXA_PU_GM 0x10 +#define RADIO_2056_MIXG_PU_I 0x01 +#define RADIO_2056_MIXG_PU_Q 0x02 +#define RADIO_2056_MIXG_PU_GM 0x10 +#define RADIO_2056_TIA_PU 0x01 +#define RADIO_2056_BB_LPF_PU 0x20 +#define RADIO_2056_W1_PU 0x02 +#define RADIO_2056_W2_PU 0x04 +#define RADIO_2056_NB_PU 0x08 +#define RADIO_2056_RSSI_W1_SEL 0x02 +#define RADIO_2056_RSSI_W2_SEL 0x04 +#define RADIO_2056_RSSI_NB_SEL 0x08 +#define RADIO_2056_VCM_MASK 0x1c +#define RADIO_2056_RSSI_VCM_SHIFT 0x02 + +#define RADIO_2057_DACBUF_VINCM_CORE0 0x0 +#define RADIO_2057_IDCODE 0x1 +#define RADIO_2057_RCCAL_MASTER 0x2 +#define RADIO_2057_RCCAL_CAP_SIZE 0x3 +#define RADIO_2057_RCAL_CONFIG 0x4 +#define RADIO_2057_GPAIO_CONFIG 0x5 +#define RADIO_2057_GPAIO_SEL1 0x6 +#define RADIO_2057_GPAIO_SEL0 0x7 +#define RADIO_2057_CLPO_CONFIG 0x8 +#define RADIO_2057_BANDGAP_CONFIG 0x9 +#define RADIO_2057_BANDGAP_RCAL_TRIM 0xa +#define RADIO_2057_AFEREG_CONFIG 0xb +#define RADIO_2057_TEMPSENSE_CONFIG 0xc +#define RADIO_2057_XTAL_CONFIG1 0xd +#define RADIO_2057_XTAL_ICORE_SIZE 0xe +#define RADIO_2057_XTAL_BUF_SIZE 0xf +#define RADIO_2057_XTAL_PULLCAP_SIZE 0x10 +#define RADIO_2057_RFPLL_MASTER 0x11 +#define RADIO_2057_VCOMONITOR_VTH_L 0x12 +#define RADIO_2057_VCOMONITOR_VTH_H 0x13 +#define RADIO_2057_VCOCAL_BIASRESET_RFPLLREG_VOUT 0x14 +#define RADIO_2057_VCO_VARCSIZE_IDAC 0x15 +#define RADIO_2057_VCOCAL_COUNTVAL0 0x16 +#define RADIO_2057_VCOCAL_COUNTVAL1 0x17 +#define RADIO_2057_VCOCAL_INTCLK_COUNT 0x18 +#define RADIO_2057_VCOCAL_MASTER 0x19 +#define RADIO_2057_VCOCAL_NUMCAPCHANGE 0x1a +#define RADIO_2057_VCOCAL_WINSIZE 0x1b +#define RADIO_2057_VCOCAL_DELAY_AFTER_REFRESH 0x1c +#define RADIO_2057_VCOCAL_DELAY_AFTER_CLOSELOOP 0x1d +#define RADIO_2057_VCOCAL_DELAY_AFTER_OPENLOOP 0x1e +#define RADIO_2057_VCOCAL_DELAY_BEFORE_OPENLOOP 0x1f +#define RADIO_2057_VCO_FORCECAPEN_FORCECAP1 0x20 +#define RADIO_2057_VCO_FORCECAP0 0x21 +#define RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE 0x22 +#define RADIO_2057_RFPLL_PFD_RESET_PW 0x23 +#define RADIO_2057_RFPLL_LOOPFILTER_R2 0x24 +#define RADIO_2057_RFPLL_LOOPFILTER_R1 0x25 +#define RADIO_2057_RFPLL_LOOPFILTER_C3 0x26 +#define RADIO_2057_RFPLL_LOOPFILTER_C2 0x27 +#define RADIO_2057_RFPLL_LOOPFILTER_C1 0x28 +#define RADIO_2057_CP_KPD_IDAC 0x29 +#define RADIO_2057_RFPLL_IDACS 0x2a +#define RADIO_2057_RFPLL_MISC_EN 0x2b +#define RADIO_2057_RFPLL_MMD0 0x2c +#define RADIO_2057_RFPLL_MMD1 0x2d +#define RADIO_2057_RFPLL_MISC_CAL_RESETN 0x2e +#define RADIO_2057_JTAGXTAL_SIZE_CPBIAS_FILTRES 0x2f +#define RADIO_2057_VCO_ALCREF_BBPLLXTAL_SIZE 0x30 +#define RADIO_2057_VCOCAL_READCAP0 0x31 +#define RADIO_2057_VCOCAL_READCAP1 0x32 +#define RADIO_2057_VCOCAL_STATUS 0x33 +#define RADIO_2057_LOGEN_PUS 0x34 +#define RADIO_2057_LOGEN_PTAT_RESETS 0x35 +#define RADIO_2057_VCOBUF_IDACS 0x36 +#define RADIO_2057_VCOBUF_TUNE 0x37 +#define RADIO_2057_CMOSBUF_TX2GQ_IDACS 0x38 +#define RADIO_2057_CMOSBUF_TX2GI_IDACS 0x39 +#define RADIO_2057_CMOSBUF_TX5GQ_IDACS 0x3a +#define RADIO_2057_CMOSBUF_TX5GI_IDACS 0x3b +#define RADIO_2057_CMOSBUF_RX2GQ_IDACS 0x3c +#define RADIO_2057_CMOSBUF_RX2GI_IDACS 0x3d +#define RADIO_2057_CMOSBUF_RX5GQ_IDACS 0x3e +#define RADIO_2057_CMOSBUF_RX5GI_IDACS 0x3f +#define RADIO_2057_LOGEN_MX2G_IDACS 0x40 +#define RADIO_2057_LOGEN_MX2G_TUNE 0x41 +#define RADIO_2057_LOGEN_MX5G_IDACS 0x42 +#define RADIO_2057_LOGEN_MX5G_TUNE 0x43 +#define RADIO_2057_LOGEN_MX5G_RCCR 0x44 +#define RADIO_2057_LOGEN_INDBUF2G_IDAC 0x45 +#define RADIO_2057_LOGEN_INDBUF2G_IBOOST 0x46 +#define RADIO_2057_LOGEN_INDBUF2G_TUNE 0x47 +#define RADIO_2057_LOGEN_INDBUF5G_IDAC 0x48 +#define RADIO_2057_LOGEN_INDBUF5G_IBOOST 0x49 +#define RADIO_2057_LOGEN_INDBUF5G_TUNE 0x4a +#define RADIO_2057_CMOSBUF_TX_RCCR 0x4b +#define RADIO_2057_CMOSBUF_RX_RCCR 0x4c +#define RADIO_2057_LOGEN_SEL_PKDET 0x4d +#define RADIO_2057_CMOSBUF_SHAREIQ_PTAT 0x4e +#define RADIO_2057_RXTXBIAS_CONFIG_CORE0 0x4f +#define RADIO_2057_TXGM_TXRF_PUS_CORE0 0x50 +#define RADIO_2057_TXGM_IDAC_BLEED_CORE0 0x51 +#define RADIO_2057_TXGM_GAIN_CORE0 0x56 +#define RADIO_2057_TXGM2G_PKDET_PUS_CORE0 0x57 +#define RADIO_2057_PAD2G_PTATS_CORE0 0x58 +#define RADIO_2057_PAD2G_IDACS_CORE0 0x59 +#define RADIO_2057_PAD2G_BOOST_PU_CORE0 0x5a +#define RADIO_2057_PAD2G_CASCV_GAIN_CORE0 0x5b +#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0 0x5c +#define RADIO_2057_TXMIX2G_LODC_CORE0 0x5d +#define RADIO_2057_PAD2G_TUNE_PUS_CORE0 0x5e +#define RADIO_2057_IPA2G_GAIN_CORE0 0x5f +#define RADIO_2057_TSSI2G_SPARE1_CORE0 0x60 +#define RADIO_2057_TSSI2G_SPARE2_CORE0 0x61 +#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE0 0x62 +#define RADIO_2057_IPA2G_IMAIN_CORE0 0x63 +#define RADIO_2057_IPA2G_CASCONV_CORE0 0x64 +#define RADIO_2057_IPA2G_CASCOFFV_CORE0 0x65 +#define RADIO_2057_IPA2G_BIAS_FILTER_CORE0 0x66 +#define RADIO_2057_TX5G_PKDET_CORE0 0x69 +#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE0 0x6a +#define RADIO_2057_PAD5G_PTATS1_CORE0 0x6b +#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE0 0x6c +#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE0 0x6d +#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE0 0x6e +#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE0 0x6f +#define RADIO_2057_PGA_BOOST_TUNE_CORE0 0x70 +#define RADIO_2057_PGA_GAIN_CORE0 0x71 +#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE0 0x72 +#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0 0x73 +#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0 0x74 +#define RADIO_2057_IPA5G_IAUX_CORE0 0x75 +#define RADIO_2057_IPA5G_GAIN_CORE0 0x76 +#define RADIO_2057_TSSI5G_SPARE1_CORE0 0x77 +#define RADIO_2057_TSSI5G_SPARE2_CORE0 0x78 +#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE0 0x79 +#define RADIO_2057_IPA5G_PTAT_CORE0 0x7a +#define RADIO_2057_IPA5G_IMAIN_CORE0 0x7b +#define RADIO_2057_IPA5G_CASCONV_CORE0 0x7c +#define RADIO_2057_IPA5G_BIAS_FILTER_CORE0 0x7d +#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE0 0x80 +#define RADIO_2057_TR2G_CONFIG1_CORE0_NU 0x81 +#define RADIO_2057_TR2G_CONFIG2_CORE0_NU 0x82 +#define RADIO_2057_LNA5G_RFEN_CORE0 0x83 +#define RADIO_2057_TR5G_CONFIG2_CORE0_NU 0x84 +#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE0 0x85 +#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE0 0x86 +#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE0 0x87 +#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE0 0x88 +#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE0 0x89 +#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE0 0x8a +#define RADIO_2057_LNA2_IAUX_PTAT_CORE0 0x8b +#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE0 0x8c +#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE0 0x8d +#define RADIO_2057_RXRFBIAS_BANDSEL_CORE0 0x8e +#define RADIO_2057_TIA_CONFIG_CORE0 0x8f +#define RADIO_2057_TIA_IQGAIN_CORE0 0x90 +#define RADIO_2057_TIA_IBIAS2_CORE0 0x91 +#define RADIO_2057_TIA_IBIAS1_CORE0 0x92 +#define RADIO_2057_TIA_SPARE_Q_CORE0 0x93 +#define RADIO_2057_TIA_SPARE_I_CORE0 0x94 +#define RADIO_2057_RXMIX2G_PUS_CORE0 0x95 +#define RADIO_2057_RXMIX2G_VCMREFS_CORE0 0x96 +#define RADIO_2057_RXMIX2G_LODC_QI_CORE0 0x97 +#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE0 0x98 +#define RADIO_2057_LNA2G_GAIN_CORE0 0x99 +#define RADIO_2057_LNA2G_TUNE_CORE0 0x9a +#define RADIO_2057_RXMIX5G_PUS_CORE0 0x9b +#define RADIO_2057_RXMIX5G_VCMREFS_CORE0 0x9c +#define RADIO_2057_RXMIX5G_LODC_QI_CORE0 0x9d +#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE0 0x9e +#define RADIO_2057_LNA5G_GAIN_CORE0 0x9f +#define RADIO_2057_LNA5G_TUNE_CORE0 0xa0 +#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE0 0xa1 +#define RADIO_2057_RXBB_BIAS_MASTER_CORE0 0xa2 +#define RADIO_2057_RXBB_VGABUF_IDACS_CORE0 0xa3 +#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE0 0xa4 +#define RADIO_2057_TXBUF_VINCM_CORE0 0xa5 +#define RADIO_2057_TXBUF_IDACS_CORE0 0xa6 +#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE0 0xa7 +#define RADIO_2057_RXBB_CC_CORE0 0xa8 +#define RADIO_2057_RXBB_SPARE3_CORE0 0xa9 +#define RADIO_2057_RXBB_RCCAL_HPC_CORE0 0xaa +#define RADIO_2057_LPF_IDACS_CORE0 0xab +#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE0 0xac +#define RADIO_2057_TXBUF_GAIN_CORE0 0xad +#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE0 0xae +#define RADIO_2057_RXBUF_DEGEN_CORE0 0xaf +#define RADIO_2057_RXBB_SPARE2_CORE0 0xb0 +#define RADIO_2057_RXBB_SPARE1_CORE0 0xb1 +#define RADIO_2057_RSSI_MASTER_CORE0 0xb2 +#define RADIO_2057_W2_MASTER_CORE0 0xb3 +#define RADIO_2057_NB_MASTER_CORE0 0xb4 +#define RADIO_2057_W2_IDACS0_Q_CORE0 0xb5 +#define RADIO_2057_W2_IDACS1_Q_CORE0 0xb6 +#define RADIO_2057_W2_IDACS0_I_CORE0 0xb7 +#define RADIO_2057_W2_IDACS1_I_CORE0 0xb8 +#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE0 0xb9 +#define RADIO_2057_NB_IDACS_Q_CORE0 0xba +#define RADIO_2057_NB_IDACS_I_CORE0 0xbb +#define RADIO_2057_BACKUP4_CORE0 0xc1 +#define RADIO_2057_BACKUP3_CORE0 0xc2 +#define RADIO_2057_BACKUP2_CORE0 0xc3 +#define RADIO_2057_BACKUP1_CORE0 0xc4 +#define RADIO_2057_SPARE16_CORE0 0xc5 +#define RADIO_2057_SPARE15_CORE0 0xc6 +#define RADIO_2057_SPARE14_CORE0 0xc7 +#define RADIO_2057_SPARE13_CORE0 0xc8 +#define RADIO_2057_SPARE12_CORE0 0xc9 +#define RADIO_2057_SPARE11_CORE0 0xca +#define RADIO_2057_TX2G_BIAS_RESETS_CORE0 0xcb +#define RADIO_2057_TX5G_BIAS_RESETS_CORE0 0xcc +#define RADIO_2057_IQTEST_SEL_PU 0xcd +#define RADIO_2057_XTAL_CONFIG2 0xce +#define RADIO_2057_BUFS_MISC_LPFBW_CORE0 0xcf +#define RADIO_2057_TXLPF_RCCAL_CORE0 0xd0 +#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE0 0xd1 +#define RADIO_2057_LPF_GAIN_CORE0 0xd2 +#define RADIO_2057_DACBUF_IDACS_BW_CORE0 0xd3 +#define RADIO_2057_RXTXBIAS_CONFIG_CORE1 0xd4 +#define RADIO_2057_TXGM_TXRF_PUS_CORE1 0xd5 +#define RADIO_2057_TXGM_IDAC_BLEED_CORE1 0xd6 +#define RADIO_2057_TXGM_GAIN_CORE1 0xdb +#define RADIO_2057_TXGM2G_PKDET_PUS_CORE1 0xdc +#define RADIO_2057_PAD2G_PTATS_CORE1 0xdd +#define RADIO_2057_PAD2G_IDACS_CORE1 0xde +#define RADIO_2057_PAD2G_BOOST_PU_CORE1 0xdf +#define RADIO_2057_PAD2G_CASCV_GAIN_CORE1 0xe0 +#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1 0xe1 +#define RADIO_2057_TXMIX2G_LODC_CORE1 0xe2 +#define RADIO_2057_PAD2G_TUNE_PUS_CORE1 0xe3 +#define RADIO_2057_IPA2G_GAIN_CORE1 0xe4 +#define RADIO_2057_TSSI2G_SPARE1_CORE1 0xe5 +#define RADIO_2057_TSSI2G_SPARE2_CORE1 0xe6 +#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE1 0xe7 +#define RADIO_2057_IPA2G_IMAIN_CORE1 0xe8 +#define RADIO_2057_IPA2G_CASCONV_CORE1 0xe9 +#define RADIO_2057_IPA2G_CASCOFFV_CORE1 0xea +#define RADIO_2057_IPA2G_BIAS_FILTER_CORE1 0xeb +#define RADIO_2057_TX5G_PKDET_CORE1 0xee +#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE1 0xef +#define RADIO_2057_PAD5G_PTATS1_CORE1 0xf0 +#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE1 0xf1 +#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE1 0xf2 +#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE1 0xf3 +#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE1 0xf4 +#define RADIO_2057_PGA_BOOST_TUNE_CORE1 0xf5 +#define RADIO_2057_PGA_GAIN_CORE1 0xf6 +#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE1 0xf7 +#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1 0xf8 +#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1 0xf9 +#define RADIO_2057_IPA5G_IAUX_CORE1 0xfa +#define RADIO_2057_IPA5G_GAIN_CORE1 0xfb +#define RADIO_2057_TSSI5G_SPARE1_CORE1 0xfc +#define RADIO_2057_TSSI5G_SPARE2_CORE1 0xfd +#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE1 0xfe +#define RADIO_2057_IPA5G_PTAT_CORE1 0xff +#define RADIO_2057_IPA5G_IMAIN_CORE1 0x100 +#define RADIO_2057_IPA5G_CASCONV_CORE1 0x101 +#define RADIO_2057_IPA5G_BIAS_FILTER_CORE1 0x102 +#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE1 0x105 +#define RADIO_2057_TR2G_CONFIG1_CORE1_NU 0x106 +#define RADIO_2057_TR2G_CONFIG2_CORE1_NU 0x107 +#define RADIO_2057_LNA5G_RFEN_CORE1 0x108 +#define RADIO_2057_TR5G_CONFIG2_CORE1_NU 0x109 +#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE1 0x10a +#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE1 0x10b +#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE1 0x10c +#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE1 0x10d +#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE1 0x10e +#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE1 0x10f +#define RADIO_2057_LNA2_IAUX_PTAT_CORE1 0x110 +#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE1 0x111 +#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE1 0x112 +#define RADIO_2057_RXRFBIAS_BANDSEL_CORE1 0x113 +#define RADIO_2057_TIA_CONFIG_CORE1 0x114 +#define RADIO_2057_TIA_IQGAIN_CORE1 0x115 +#define RADIO_2057_TIA_IBIAS2_CORE1 0x116 +#define RADIO_2057_TIA_IBIAS1_CORE1 0x117 +#define RADIO_2057_TIA_SPARE_Q_CORE1 0x118 +#define RADIO_2057_TIA_SPARE_I_CORE1 0x119 +#define RADIO_2057_RXMIX2G_PUS_CORE1 0x11a +#define RADIO_2057_RXMIX2G_VCMREFS_CORE1 0x11b +#define RADIO_2057_RXMIX2G_LODC_QI_CORE1 0x11c +#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE1 0x11d +#define RADIO_2057_LNA2G_GAIN_CORE1 0x11e +#define RADIO_2057_LNA2G_TUNE_CORE1 0x11f +#define RADIO_2057_RXMIX5G_PUS_CORE1 0x120 +#define RADIO_2057_RXMIX5G_VCMREFS_CORE1 0x121 +#define RADIO_2057_RXMIX5G_LODC_QI_CORE1 0x122 +#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE1 0x123 +#define RADIO_2057_LNA5G_GAIN_CORE1 0x124 +#define RADIO_2057_LNA5G_TUNE_CORE1 0x125 +#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE1 0x126 +#define RADIO_2057_RXBB_BIAS_MASTER_CORE1 0x127 +#define RADIO_2057_RXBB_VGABUF_IDACS_CORE1 0x128 +#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE1 0x129 +#define RADIO_2057_TXBUF_VINCM_CORE1 0x12a +#define RADIO_2057_TXBUF_IDACS_CORE1 0x12b +#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE1 0x12c +#define RADIO_2057_RXBB_CC_CORE1 0x12d +#define RADIO_2057_RXBB_SPARE3_CORE1 0x12e +#define RADIO_2057_RXBB_RCCAL_HPC_CORE1 0x12f +#define RADIO_2057_LPF_IDACS_CORE1 0x130 +#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE1 0x131 +#define RADIO_2057_TXBUF_GAIN_CORE1 0x132 +#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE1 0x133 +#define RADIO_2057_RXBUF_DEGEN_CORE1 0x134 +#define RADIO_2057_RXBB_SPARE2_CORE1 0x135 +#define RADIO_2057_RXBB_SPARE1_CORE1 0x136 +#define RADIO_2057_RSSI_MASTER_CORE1 0x137 +#define RADIO_2057_W2_MASTER_CORE1 0x138 +#define RADIO_2057_NB_MASTER_CORE1 0x139 +#define RADIO_2057_W2_IDACS0_Q_CORE1 0x13a +#define RADIO_2057_W2_IDACS1_Q_CORE1 0x13b +#define RADIO_2057_W2_IDACS0_I_CORE1 0x13c +#define RADIO_2057_W2_IDACS1_I_CORE1 0x13d +#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE1 0x13e +#define RADIO_2057_NB_IDACS_Q_CORE1 0x13f +#define RADIO_2057_NB_IDACS_I_CORE1 0x140 +#define RADIO_2057_BACKUP4_CORE1 0x146 +#define RADIO_2057_BACKUP3_CORE1 0x147 +#define RADIO_2057_BACKUP2_CORE1 0x148 +#define RADIO_2057_BACKUP1_CORE1 0x149 +#define RADIO_2057_SPARE16_CORE1 0x14a +#define RADIO_2057_SPARE15_CORE1 0x14b +#define RADIO_2057_SPARE14_CORE1 0x14c +#define RADIO_2057_SPARE13_CORE1 0x14d +#define RADIO_2057_SPARE12_CORE1 0x14e +#define RADIO_2057_SPARE11_CORE1 0x14f +#define RADIO_2057_TX2G_BIAS_RESETS_CORE1 0x150 +#define RADIO_2057_TX5G_BIAS_RESETS_CORE1 0x151 +#define RADIO_2057_SPARE8_CORE1 0x152 +#define RADIO_2057_SPARE7_CORE1 0x153 +#define RADIO_2057_BUFS_MISC_LPFBW_CORE1 0x154 +#define RADIO_2057_TXLPF_RCCAL_CORE1 0x155 +#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE1 0x156 +#define RADIO_2057_LPF_GAIN_CORE1 0x157 +#define RADIO_2057_DACBUF_IDACS_BW_CORE1 0x158 +#define RADIO_2057_DACBUF_VINCM_CORE1 0x159 +#define RADIO_2057_RCCAL_START_R1_Q1_P1 0x15a +#define RADIO_2057_RCCAL_X1 0x15b +#define RADIO_2057_RCCAL_TRC0 0x15c +#define RADIO_2057_RCCAL_TRC1 0x15d +#define RADIO_2057_RCCAL_DONE_OSCCAP 0x15e +#define RADIO_2057_RCCAL_N0_0 0x15f +#define RADIO_2057_RCCAL_N0_1 0x160 +#define RADIO_2057_RCCAL_N1_0 0x161 +#define RADIO_2057_RCCAL_N1_1 0x162 +#define RADIO_2057_RCAL_STATUS 0x163 +#define RADIO_2057_XTALPUOVR_PINCTRL 0x164 +#define RADIO_2057_OVR_REG0 0x165 +#define RADIO_2057_OVR_REG1 0x166 +#define RADIO_2057_OVR_REG2 0x167 +#define RADIO_2057_OVR_REG3 0x168 +#define RADIO_2057_OVR_REG4 0x169 +#define RADIO_2057_RCCAL_SCAP_VAL 0x16a +#define RADIO_2057_RCCAL_BCAP_VAL 0x16b +#define RADIO_2057_RCCAL_HPC_VAL 0x16c +#define RADIO_2057_RCCAL_OVERRIDES 0x16d +#define RADIO_2057_TX0_IQCAL_GAIN_BW 0x170 +#define RADIO_2057_TX0_LOFT_FINE_I 0x171 +#define RADIO_2057_TX0_LOFT_FINE_Q 0x172 +#define RADIO_2057_TX0_LOFT_COARSE_I 0x173 +#define RADIO_2057_TX0_LOFT_COARSE_Q 0x174 +#define RADIO_2057_TX0_TX_SSI_MASTER 0x175 +#define RADIO_2057_TX0_IQCAL_VCM_HG 0x176 +#define RADIO_2057_TX0_IQCAL_IDAC 0x177 +#define RADIO_2057_TX0_TSSI_VCM 0x178 +#define RADIO_2057_TX0_TX_SSI_MUX 0x179 +#define RADIO_2057_TX0_TSSIA 0x17a +#define RADIO_2057_TX0_TSSIG 0x17b +#define RADIO_2057_TX0_TSSI_MISC1 0x17c +#define RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN 0x17d +#define RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP 0x17e +#define RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN 0x17f +#define RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP 0x180 +#define RADIO_2057_TX1_IQCAL_GAIN_BW 0x190 +#define RADIO_2057_TX1_LOFT_FINE_I 0x191 +#define RADIO_2057_TX1_LOFT_FINE_Q 0x192 +#define RADIO_2057_TX1_LOFT_COARSE_I 0x193 +#define RADIO_2057_TX1_LOFT_COARSE_Q 0x194 +#define RADIO_2057_TX1_TX_SSI_MASTER 0x195 +#define RADIO_2057_TX1_IQCAL_VCM_HG 0x196 +#define RADIO_2057_TX1_IQCAL_IDAC 0x197 +#define RADIO_2057_TX1_TSSI_VCM 0x198 +#define RADIO_2057_TX1_TX_SSI_MUX 0x199 +#define RADIO_2057_TX1_TSSIA 0x19a +#define RADIO_2057_TX1_TSSIG 0x19b +#define RADIO_2057_TX1_TSSI_MISC1 0x19c +#define RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN 0x19d +#define RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP 0x19e +#define RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN 0x19f +#define RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP 0x1a0 +#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE0 0x1a1 +#define RADIO_2057_AFE_SET_VCM_I_CORE0 0x1a2 +#define RADIO_2057_AFE_SET_VCM_Q_CORE0 0x1a3 +#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE0 0x1a4 +#define RADIO_2057_AFE_STATUS_VCM_I_CORE0 0x1a5 +#define RADIO_2057_AFE_STATUS_VCM_Q_CORE0 0x1a6 +#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE1 0x1a7 +#define RADIO_2057_AFE_SET_VCM_I_CORE1 0x1a8 +#define RADIO_2057_AFE_SET_VCM_Q_CORE1 0x1a9 +#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE1 0x1aa +#define RADIO_2057_AFE_STATUS_VCM_I_CORE1 0x1ab +#define RADIO_2057_AFE_STATUS_VCM_Q_CORE1 0x1ac + +#define RADIO_2057v7_DACBUF_VINCM_CORE0 0x1ad +#define RADIO_2057v7_RCCAL_MASTER 0x1ae +#define RADIO_2057v7_TR2G_CONFIG3_CORE0_NU 0x1af +#define RADIO_2057v7_TR2G_CONFIG3_CORE1_NU 0x1b0 +#define RADIO_2057v7_LOGEN_PUS1 0x1b1 +#define RADIO_2057v7_OVR_REG5 0x1b2 +#define RADIO_2057v7_OVR_REG6 0x1b3 +#define RADIO_2057v7_OVR_REG7 0x1b4 +#define RADIO_2057v7_OVR_REG8 0x1b5 +#define RADIO_2057v7_OVR_REG9 0x1b6 +#define RADIO_2057v7_OVR_REG10 0x1b7 +#define RADIO_2057v7_OVR_REG11 0x1b8 +#define RADIO_2057v7_OVR_REG12 0x1b9 +#define RADIO_2057v7_OVR_REG13 0x1ba +#define RADIO_2057v7_OVR_REG14 0x1bb +#define RADIO_2057v7_OVR_REG15 0x1bc +#define RADIO_2057v7_OVR_REG16 0x1bd +#define RADIO_2057v7_OVR_REG1 0x1be +#define RADIO_2057v7_OVR_REG18 0x1bf +#define RADIO_2057v7_OVR_REG19 0x1c0 +#define RADIO_2057v7_OVR_REG20 0x1c1 +#define RADIO_2057v7_OVR_REG21 0x1c2 +#define RADIO_2057v7_OVR_REG2 0x1c3 +#define RADIO_2057v7_OVR_REG23 0x1c4 +#define RADIO_2057v7_OVR_REG24 0x1c5 +#define RADIO_2057v7_OVR_REG25 0x1c6 +#define RADIO_2057v7_OVR_REG26 0x1c7 +#define RADIO_2057v7_OVR_REG27 0x1c8 +#define RADIO_2057v7_OVR_REG28 0x1c9 +#define RADIO_2057v7_IQTEST_SEL_PU2 0x1ca + +#define RADIO_2057_VCM_MASK 0x7 + +#endif /* _BCM20XX_H */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h new file mode 100644 index 000000000000..211bc3a842af --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define NPHY_TBL_ID_GAIN1 0 +#define NPHY_TBL_ID_GAIN2 1 +#define NPHY_TBL_ID_GAINBITS1 2 +#define NPHY_TBL_ID_GAINBITS2 3 +#define NPHY_TBL_ID_GAINLIMIT 4 +#define NPHY_TBL_ID_WRSSIGainLimit 5 +#define NPHY_TBL_ID_RFSEQ 7 +#define NPHY_TBL_ID_AFECTRL 8 +#define NPHY_TBL_ID_ANTSWCTRLLUT 9 +#define NPHY_TBL_ID_IQLOCAL 15 +#define NPHY_TBL_ID_NOISEVAR 16 +#define NPHY_TBL_ID_SAMPLEPLAY 17 +#define NPHY_TBL_ID_CORE1TXPWRCTL 26 +#define NPHY_TBL_ID_CORE2TXPWRCTL 27 +#define NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL 30 + +#define NPHY_TBL_ID_EPSILONTBL0 31 +#define NPHY_TBL_ID_SCALARTBL0 32 +#define NPHY_TBL_ID_EPSILONTBL1 33 +#define NPHY_TBL_ID_SCALARTBL1 34 + +#define NPHY_TO_BPHY_OFF 0xc00 + +#define NPHY_BandControl_currentBand 0x0001 +#define RFCC_CHIP0_PU 0x0400 +#define RFCC_POR_FORCE 0x0040 +#define RFCC_OE_POR_FORCE 0x0080 +#define NPHY_RfctrlIntc_override_OFF 0 +#define NPHY_RfctrlIntc_override_TRSW 1 +#define NPHY_RfctrlIntc_override_PA 2 +#define NPHY_RfctrlIntc_override_EXT_LNA_PU 3 +#define NPHY_RfctrlIntc_override_EXT_LNA_GAIN 4 +#define RIFS_ENABLE 0x80 +#define BPHY_BAND_SEL_UP20 0x10 +#define NPHY_MLenable 0x02 + +#define NPHY_RfseqMode_CoreActv_override 0x0001 +#define NPHY_RfseqMode_Trigger_override 0x0002 +#define NPHY_RfseqCoreActv_TxRxChain0 (0x11) +#define NPHY_RfseqCoreActv_TxRxChain1 (0x22) + +#define NPHY_RfseqTrigger_rx2tx 0x0001 +#define NPHY_RfseqTrigger_tx2rx 0x0002 +#define NPHY_RfseqTrigger_updategainh 0x0004 +#define NPHY_RfseqTrigger_updategainl 0x0008 +#define NPHY_RfseqTrigger_updategainu 0x0010 +#define NPHY_RfseqTrigger_reset2rx 0x0020 +#define NPHY_RfseqStatus_rx2tx 0x0001 +#define NPHY_RfseqStatus_tx2rx 0x0002 +#define NPHY_RfseqStatus_updategainh 0x0004 +#define NPHY_RfseqStatus_updategainl 0x0008 +#define NPHY_RfseqStatus_updategainu 0x0010 +#define NPHY_RfseqStatus_reset2rx 0x0020 +#define NPHY_ClassifierCtrl_cck_en 0x1 +#define NPHY_ClassifierCtrl_ofdm_en 0x2 +#define NPHY_ClassifierCtrl_waited_en 0x4 +#define NPHY_IQFlip_ADC1 0x0001 +#define NPHY_IQFlip_ADC2 0x0010 +#define NPHY_sampleCmd_STOP 0x0002 + +#define RX_GF_OR_MM 0x0004 +#define RX_GF_MM_AUTO 0x0100 + +#define NPHY_iqloCalCmdGctl_IQLO_CAL_EN 0x8000 + +#define NPHY_IqestCmd_iqstart 0x1 +#define NPHY_IqestCmd_iqMode 0x2 + +#define NPHY_TxPwrCtrlCmd_pwrIndex_init 0x40 +#define NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 0x19 + +#define PRIM_SEL_UP20 0x8000 + +#define NPHY_RFSEQ_RX2TX 0x0 +#define NPHY_RFSEQ_TX2RX 0x1 +#define NPHY_RFSEQ_RESET2RX 0x2 +#define NPHY_RFSEQ_UPDATEGAINH 0x3 +#define NPHY_RFSEQ_UPDATEGAINL 0x4 +#define NPHY_RFSEQ_UPDATEGAINU 0x5 + +#define NPHY_RFSEQ_CMD_NOP 0x0 +#define NPHY_RFSEQ_CMD_RXG_FBW 0x1 +#define NPHY_RFSEQ_CMD_TR_SWITCH 0x2 +#define NPHY_RFSEQ_CMD_EXT_PA 0x3 +#define NPHY_RFSEQ_CMD_RXPD_TXPD 0x4 +#define NPHY_RFSEQ_CMD_TX_GAIN 0x5 +#define NPHY_RFSEQ_CMD_RX_GAIN 0x6 +#define NPHY_RFSEQ_CMD_SET_HPF_BW 0x7 +#define NPHY_RFSEQ_CMD_CLR_HIQ_DIS 0x8 +#define NPHY_RFSEQ_CMD_END 0xf + +#define NPHY_REV3_RFSEQ_CMD_NOP 0x0 +#define NPHY_REV3_RFSEQ_CMD_RXG_FBW 0x1 +#define NPHY_REV3_RFSEQ_CMD_TR_SWITCH 0x2 +#define NPHY_REV3_RFSEQ_CMD_INT_PA_PU 0x3 +#define NPHY_REV3_RFSEQ_CMD_EXT_PA 0x4 +#define NPHY_REV3_RFSEQ_CMD_RXPD_TXPD 0x5 +#define NPHY_REV3_RFSEQ_CMD_TX_GAIN 0x6 +#define NPHY_REV3_RFSEQ_CMD_RX_GAIN 0x7 +#define NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS 0x8 +#define NPHY_REV3_RFSEQ_CMD_SET_HPF_H_HPC 0x9 +#define NPHY_REV3_RFSEQ_CMD_SET_LPF_H_HPC 0xa +#define NPHY_REV3_RFSEQ_CMD_SET_HPF_M_HPC 0xb +#define NPHY_REV3_RFSEQ_CMD_SET_LPF_M_HPC 0xc +#define NPHY_REV3_RFSEQ_CMD_SET_HPF_L_HPC 0xd +#define NPHY_REV3_RFSEQ_CMD_SET_LPF_L_HPC 0xe +#define NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS 0xf +#define NPHY_REV3_RFSEQ_CMD_END 0x1f + +#define NPHY_RSSI_SEL_W1 0x0 +#define NPHY_RSSI_SEL_W2 0x1 +#define NPHY_RSSI_SEL_NB 0x2 +#define NPHY_RSSI_SEL_IQ 0x3 +#define NPHY_RSSI_SEL_TSSI_2G 0x4 +#define NPHY_RSSI_SEL_TSSI_5G 0x5 +#define NPHY_RSSI_SEL_TBD 0x6 + +#define NPHY_RAIL_I 0x0 +#define NPHY_RAIL_Q 0x1 + +#define NPHY_FORCESIG_DECODEGATEDCLKS 0x8 + +#define NPHY_REV7_RfctrlOverride_cmd_rxrf_pu 0x0 +#define NPHY_REV7_RfctrlOverride_cmd_rx_pu 0x1 +#define NPHY_REV7_RfctrlOverride_cmd_tx_pu 0x2 +#define NPHY_REV7_RfctrlOverride_cmd_rxgain 0x3 +#define NPHY_REV7_RfctrlOverride_cmd_txgain 0x4 + +#define NPHY_REV7_RXGAINCODE_RFMXGAIN_MASK 0x000ff +#define NPHY_REV7_RXGAINCODE_LPFGAIN_MASK 0x0ff00 +#define NPHY_REV7_RXGAINCODE_DVGAGAIN_MASK 0xf0000 + +#define NPHY_REV7_TXGAINCODE_TGAIN_MASK 0x7fff +#define NPHY_REV7_TXGAINCODE_LPFGAIN_MASK 0x8000 +#define NPHY_REV7_TXGAINCODE_BIQ0GAIN_SHIFT 14 + +#define NPHY_REV7_RFCTRLOVERRIDE_ID0 0x0 +#define NPHY_REV7_RFCTRLOVERRIDE_ID1 0x1 +#define NPHY_REV7_RFCTRLOVERRIDE_ID2 0x2 + +#define NPHY_IqestIqAccLo(core) ((core == 0) ? 0x12c : 0x134) + +#define NPHY_IqestIqAccHi(core) ((core == 0) ? 0x12d : 0x135) + +#define NPHY_IqestipwrAccLo(core) ((core == 0) ? 0x12e : 0x136) + +#define NPHY_IqestipwrAccHi(core) ((core == 0) ? 0x12f : 0x137) + +#define NPHY_IqestqpwrAccLo(core) ((core == 0) ? 0x130 : 0x138) + +#define NPHY_IqestqpwrAccHi(core) ((core == 0) ? 0x131 : 0x139) diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c new file mode 100644 index 000000000000..330b88152b65 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c @@ -0,0 +1,3641 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +const u32 dot11lcn_gain_tbl_rev0[] = { + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000004, + 0x00000000, + 0x00000004, + 0x00000008, + 0x00000001, + 0x00000005, + 0x00000009, + 0x0000000d, + 0x0000004d, + 0x0000008d, + 0x0000000d, + 0x0000004d, + 0x0000008d, + 0x000000cd, + 0x0000004f, + 0x0000008f, + 0x000000cf, + 0x000000d3, + 0x00000113, + 0x00000513, + 0x00000913, + 0x00000953, + 0x00000d53, + 0x00001153, + 0x00001193, + 0x00005193, + 0x00009193, + 0x0000d193, + 0x00011193, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000004, + 0x00000000, + 0x00000004, + 0x00000008, + 0x00000001, + 0x00000005, + 0x00000009, + 0x0000000d, + 0x0000004d, + 0x0000008d, + 0x0000000d, + 0x0000004d, + 0x0000008d, + 0x000000cd, + 0x0000004f, + 0x0000008f, + 0x000000cf, + 0x000000d3, + 0x00000113, + 0x00000513, + 0x00000913, + 0x00000953, + 0x00000d53, + 0x00001153, + 0x00005153, + 0x00009153, + 0x0000d153, + 0x00011153, + 0x00015153, + 0x00019153, + 0x0001d153, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; + +const u32 dot11lcn_gain_tbl_rev1[] = { + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000008, + 0x00000004, + 0x00000008, + 0x00000001, + 0x00000005, + 0x00000009, + 0x0000000D, + 0x00000011, + 0x00000051, + 0x00000091, + 0x00000011, + 0x00000051, + 0x00000091, + 0x000000d1, + 0x00000053, + 0x00000093, + 0x000000d3, + 0x000000d7, + 0x00000117, + 0x00000517, + 0x00000917, + 0x00000957, + 0x00000d57, + 0x00001157, + 0x00001197, + 0x00005197, + 0x00009197, + 0x0000d197, + 0x00011197, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000008, + 0x00000004, + 0x00000008, + 0x00000001, + 0x00000005, + 0x00000009, + 0x0000000D, + 0x00000011, + 0x00000051, + 0x00000091, + 0x00000011, + 0x00000051, + 0x00000091, + 0x000000d1, + 0x00000053, + 0x00000093, + 0x000000d3, + 0x000000d7, + 0x00000117, + 0x00000517, + 0x00000917, + 0x00000957, + 0x00000d57, + 0x00001157, + 0x00005157, + 0x00009157, + 0x0000d157, + 0x00011157, + 0x00015157, + 0x00019157, + 0x0001d157, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; + +const u16 dot11lcn_aux_gain_idx_tbl_rev0[] = { + 0x0401, + 0x0402, + 0x0403, + 0x0404, + 0x0405, + 0x0406, + 0x0407, + 0x0408, + 0x0409, + 0x040a, + 0x058b, + 0x058c, + 0x058d, + 0x058e, + 0x058f, + 0x0090, + 0x0091, + 0x0092, + 0x0193, + 0x0194, + 0x0195, + 0x0196, + 0x0197, + 0x0198, + 0x0199, + 0x019a, + 0x019b, + 0x019c, + 0x019d, + 0x019e, + 0x019f, + 0x01a0, + 0x01a1, + 0x01a2, + 0x01a3, + 0x01a4, + 0x01a5, + 0x0000, +}; + +const u32 dot11lcn_gain_idx_tbl_rev0[] = { + 0x00000000, + 0x00000000, + 0x10000000, + 0x00000000, + 0x20000000, + 0x00000000, + 0x30000000, + 0x00000000, + 0x40000000, + 0x00000000, + 0x50000000, + 0x00000000, + 0x60000000, + 0x00000000, + 0x70000000, + 0x00000000, + 0x80000000, + 0x00000000, + 0x90000000, + 0x00000008, + 0xa0000000, + 0x00000008, + 0xb0000000, + 0x00000008, + 0xc0000000, + 0x00000008, + 0xd0000000, + 0x00000008, + 0xe0000000, + 0x00000008, + 0xf0000000, + 0x00000008, + 0x00000000, + 0x00000009, + 0x10000000, + 0x00000009, + 0x20000000, + 0x00000019, + 0x30000000, + 0x00000019, + 0x40000000, + 0x00000019, + 0x50000000, + 0x00000019, + 0x60000000, + 0x00000019, + 0x70000000, + 0x00000019, + 0x80000000, + 0x00000019, + 0x90000000, + 0x00000019, + 0xa0000000, + 0x00000019, + 0xb0000000, + 0x00000019, + 0xc0000000, + 0x00000019, + 0xd0000000, + 0x00000019, + 0xe0000000, + 0x00000019, + 0xf0000000, + 0x00000019, + 0x00000000, + 0x0000001a, + 0x10000000, + 0x0000001a, + 0x20000000, + 0x0000001a, + 0x30000000, + 0x0000001a, + 0x40000000, + 0x0000001a, + 0x50000000, + 0x00000002, + 0x60000000, + 0x00000002, + 0x70000000, + 0x00000002, + 0x80000000, + 0x00000002, + 0x90000000, + 0x00000002, + 0xa0000000, + 0x00000002, + 0xb0000000, + 0x00000002, + 0xc0000000, + 0x0000000a, + 0xd0000000, + 0x0000000a, + 0xe0000000, + 0x0000000a, + 0xf0000000, + 0x0000000a, + 0x00000000, + 0x0000000b, + 0x10000000, + 0x0000000b, + 0x20000000, + 0x0000000b, + 0x30000000, + 0x0000000b, + 0x40000000, + 0x0000000b, + 0x50000000, + 0x0000001b, + 0x60000000, + 0x0000001b, + 0x70000000, + 0x0000001b, + 0x80000000, + 0x0000001b, + 0x90000000, + 0x0000001b, + 0xa0000000, + 0x0000001b, + 0xb0000000, + 0x0000001b, + 0xc0000000, + 0x0000001b, + 0xd0000000, + 0x0000001b, + 0xe0000000, + 0x0000001b, + 0xf0000000, + 0x0000001b, + 0x00000000, + 0x0000001c, + 0x10000000, + 0x0000001c, + 0x20000000, + 0x0000001c, + 0x30000000, + 0x0000001c, + 0x40000000, + 0x0000001c, + 0x50000000, + 0x0000001c, + 0x60000000, + 0x0000001c, + 0x70000000, + 0x0000001c, + 0x80000000, + 0x0000001c, + 0x90000000, + 0x0000001c, +}; + +const u16 dot11lcn_aux_gain_idx_tbl_2G[] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0001, + 0x0080, + 0x0081, + 0x0100, + 0x0101, + 0x0180, + 0x0181, + 0x0182, + 0x0183, + 0x0184, + 0x0185, + 0x0186, + 0x0187, + 0x0188, + 0x0285, + 0x0289, + 0x028a, + 0x028b, + 0x028c, + 0x028d, + 0x028e, + 0x028f, + 0x0290, + 0x0291, + 0x0292, + 0x0293, + 0x0294, + 0x0295, + 0x0296, + 0x0297, + 0x0298, + 0x0299, + 0x029a, + 0x0000 +}; + +const u8 dot11lcn_gain_val_tbl_2G[] = { + 0xfc, + 0x02, + 0x08, + 0x0e, + 0x13, + 0x1b, + 0xfc, + 0x02, + 0x08, + 0x0e, + 0x13, + 0x1b, + 0xfc, + 0x00, + 0x0c, + 0x03, + 0xeb, + 0xfe, + 0x07, + 0x0b, + 0x0f, + 0xfb, + 0xfe, + 0x01, + 0x05, + 0x08, + 0x0b, + 0x0e, + 0x11, + 0x14, + 0x17, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x03, + 0x06, + 0x09, + 0x0c, + 0x0f, + 0x12, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x03, + 0x06, + 0x09, + 0x0c, + 0x0f, + 0x12, + 0x15, + 0x18, + 0x1b, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 +}; + +const u32 dot11lcn_gain_idx_tbl_2G[] = { + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x10000000, + 0x00000000, + 0x00000000, + 0x00000008, + 0x10000000, + 0x00000008, + 0x00000000, + 0x00000010, + 0x10000000, + 0x00000010, + 0x00000000, + 0x00000018, + 0x10000000, + 0x00000018, + 0x20000000, + 0x00000018, + 0x30000000, + 0x00000018, + 0x40000000, + 0x00000018, + 0x50000000, + 0x00000018, + 0x60000000, + 0x00000018, + 0x70000000, + 0x00000018, + 0x80000000, + 0x00000018, + 0x50000000, + 0x00000028, + 0x90000000, + 0x00000028, + 0xa0000000, + 0x00000028, + 0xb0000000, + 0x00000028, + 0xc0000000, + 0x00000028, + 0xd0000000, + 0x00000028, + 0xe0000000, + 0x00000028, + 0xf0000000, + 0x00000028, + 0x00000000, + 0x00000029, + 0x10000000, + 0x00000029, + 0x20000000, + 0x00000029, + 0x30000000, + 0x00000029, + 0x40000000, + 0x00000029, + 0x50000000, + 0x00000029, + 0x60000000, + 0x00000029, + 0x70000000, + 0x00000029, + 0x80000000, + 0x00000029, + 0x90000000, + 0x00000029, + 0xa0000000, + 0x00000029, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x10000000, + 0x00000000, + 0x00000000, + 0x00000008, + 0x10000000, + 0x00000008, + 0x00000000, + 0x00000010, + 0x10000000, + 0x00000010, + 0x00000000, + 0x00000018, + 0x10000000, + 0x00000018, + 0x20000000, + 0x00000018, + 0x30000000, + 0x00000018, + 0x40000000, + 0x00000018, + 0x50000000, + 0x00000018, + 0x60000000, + 0x00000018, + 0x70000000, + 0x00000018, + 0x80000000, + 0x00000018, + 0x50000000, + 0x00000028, + 0x90000000, + 0x00000028, + 0xa0000000, + 0x00000028, + 0xb0000000, + 0x00000028, + 0xc0000000, + 0x00000028, + 0xd0000000, + 0x00000028, + 0xe0000000, + 0x00000028, + 0xf0000000, + 0x00000028, + 0x00000000, + 0x00000029, + 0x10000000, + 0x00000029, + 0x20000000, + 0x00000029, + 0x30000000, + 0x00000029, + 0x40000000, + 0x00000029, + 0x50000000, + 0x00000029, + 0x60000000, + 0x00000029, + 0x70000000, + 0x00000029, + 0x80000000, + 0x00000029, + 0x90000000, + 0x00000029, + 0xa0000000, + 0x00000029, + 0xb0000000, + 0x00000029, + 0xc0000000, + 0x00000029, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 +}; + +const u32 dot11lcn_gain_tbl_2G[] = { + 0x00000000, + 0x00000004, + 0x00000008, + 0x00000001, + 0x00000005, + 0x00000009, + 0x0000000d, + 0x0000004d, + 0x0000008d, + 0x00000049, + 0x00000089, + 0x000000c9, + 0x0000004b, + 0x0000008b, + 0x000000cb, + 0x000000cf, + 0x0000010f, + 0x0000050f, + 0x0000090f, + 0x0000094f, + 0x00000d4f, + 0x0000114f, + 0x0000118f, + 0x0000518f, + 0x0000918f, + 0x0000d18f, + 0x0001118f, + 0x0001518f, + 0x0001918f, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 +}; + +const u32 dot11lcn_gain_tbl_extlna_2G[] = { + 0x00000000, + 0x00000004, + 0x00000008, + 0x00000001, + 0x00000005, + 0x00000009, + 0x0000000d, + 0x00000003, + 0x00000007, + 0x0000000b, + 0x0000000f, + 0x0000004f, + 0x0000008f, + 0x000000cf, + 0x0000010f, + 0x0000014f, + 0x0000018f, + 0x0000058f, + 0x0000098f, + 0x00000d8f, + 0x00008000, + 0x00008004, + 0x00008008, + 0x00008001, + 0x00008005, + 0x00008009, + 0x0000800d, + 0x00008003, + 0x00008007, + 0x0000800b, + 0x0000800f, + 0x0000804f, + 0x0000808f, + 0x000080cf, + 0x0000810f, + 0x0000814f, + 0x0000818f, + 0x0000858f, + 0x0000898f, + 0x00008d8f, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 +}; + +const u16 dot11lcn_aux_gain_idx_tbl_extlna_2G[] = { + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0401, + 0x0402, + 0x0403, + 0x0404, + 0x0483, + 0x0484, + 0x0485, + 0x0486, + 0x0583, + 0x0584, + 0x0585, + 0x0587, + 0x0588, + 0x0589, + 0x058a, + 0x0687, + 0x0688, + 0x0689, + 0x068a, + 0x068b, + 0x068c, + 0x068d, + 0x068e, + 0x068f, + 0x0690, + 0x0691, + 0x0692, + 0x0693, + 0x0000 +}; + +const u8 dot11lcn_gain_val_tbl_extlna_2G[] = { + 0xfc, + 0x02, + 0x08, + 0x0e, + 0x13, + 0x1b, + 0xfc, + 0x02, + 0x08, + 0x0e, + 0x13, + 0x1b, + 0xfc, + 0x00, + 0x0f, + 0x03, + 0xeb, + 0xfe, + 0x07, + 0x0b, + 0x0f, + 0xfb, + 0xfe, + 0x01, + 0x05, + 0x08, + 0x0b, + 0x0e, + 0x11, + 0x14, + 0x17, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x03, + 0x06, + 0x09, + 0x0c, + 0x0f, + 0x12, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x03, + 0x06, + 0x09, + 0x0c, + 0x0f, + 0x12, + 0x15, + 0x18, + 0x1b, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 +}; + +const u32 dot11lcn_gain_idx_tbl_extlna_2G[] = { + 0x00000000, + 0x00000040, + 0x00000000, + 0x00000040, + 0x00000000, + 0x00000040, + 0x00000000, + 0x00000040, + 0x00000000, + 0x00000040, + 0x00000000, + 0x00000040, + 0x00000000, + 0x00000040, + 0x00000000, + 0x00000040, + 0x00000000, + 0x00000040, + 0x10000000, + 0x00000040, + 0x20000000, + 0x00000040, + 0x30000000, + 0x00000040, + 0x40000000, + 0x00000040, + 0x30000000, + 0x00000048, + 0x40000000, + 0x00000048, + 0x50000000, + 0x00000048, + 0x60000000, + 0x00000048, + 0x30000000, + 0x00000058, + 0x40000000, + 0x00000058, + 0x50000000, + 0x00000058, + 0x70000000, + 0x00000058, + 0x80000000, + 0x00000058, + 0x90000000, + 0x00000058, + 0xa0000000, + 0x00000058, + 0x70000000, + 0x00000068, + 0x80000000, + 0x00000068, + 0x90000000, + 0x00000068, + 0xa0000000, + 0x00000068, + 0xb0000000, + 0x00000068, + 0xc0000000, + 0x00000068, + 0xd0000000, + 0x00000068, + 0xe0000000, + 0x00000068, + 0xf0000000, + 0x00000068, + 0x00000000, + 0x00000069, + 0x10000000, + 0x00000069, + 0x20000000, + 0x00000069, + 0x30000000, + 0x00000069, + 0x40000000, + 0x00000041, + 0x40000000, + 0x00000041, + 0x40000000, + 0x00000041, + 0x40000000, + 0x00000041, + 0x40000000, + 0x00000041, + 0x40000000, + 0x00000041, + 0x40000000, + 0x00000041, + 0x40000000, + 0x00000041, + 0x40000000, + 0x00000041, + 0x50000000, + 0x00000041, + 0x60000000, + 0x00000041, + 0x70000000, + 0x00000041, + 0x80000000, + 0x00000041, + 0x70000000, + 0x00000049, + 0x80000000, + 0x00000049, + 0x90000000, + 0x00000049, + 0xa0000000, + 0x00000049, + 0x70000000, + 0x00000059, + 0x80000000, + 0x00000059, + 0x90000000, + 0x00000059, + 0xb0000000, + 0x00000059, + 0xc0000000, + 0x00000059, + 0xd0000000, + 0x00000059, + 0xe0000000, + 0x00000059, + 0xb0000000, + 0x00000069, + 0xc0000000, + 0x00000069, + 0xd0000000, + 0x00000069, + 0xe0000000, + 0x00000069, + 0xf0000000, + 0x00000069, + 0x00000000, + 0x0000006a, + 0x10000000, + 0x0000006a, + 0x20000000, + 0x0000006a, + 0x30000000, + 0x0000006a, + 0x40000000, + 0x0000006a, + 0x50000000, + 0x0000006a, + 0x60000000, + 0x0000006a, + 0x70000000, + 0x0000006a, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 +}; + +const u32 dot11lcn_aux_gain_idx_tbl_5G[] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0001, + 0x0002, + 0x0003, + 0x0004, + 0x0083, + 0x0084, + 0x0085, + 0x0086, + 0x0087, + 0x0186, + 0x0187, + 0x0188, + 0x0189, + 0x018a, + 0x018b, + 0x018c, + 0x018d, + 0x018e, + 0x018f, + 0x0190, + 0x0191, + 0x0192, + 0x0193, + 0x0194, + 0x0195, + 0x0196, + 0x0197, + 0x0198, + 0x0199, + 0x019a, + 0x019b, + 0x019c, + 0x019d, + 0x0000 +}; + +const u32 dot11lcn_gain_val_tbl_5G[] = { + 0xf7, + 0xfd, + 0x00, + 0x04, + 0x04, + 0x04, + 0xf7, + 0xfd, + 0x00, + 0x04, + 0x04, + 0x04, + 0xf6, + 0x00, + 0x0c, + 0x03, + 0xeb, + 0xfe, + 0x06, + 0x0a, + 0x10, + 0x00, + 0x03, + 0x06, + 0x09, + 0x0c, + 0x0f, + 0x12, + 0x15, + 0x18, + 0x1b, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x03, + 0x06, + 0x09, + 0x0c, + 0x0f, + 0x12, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x03, + 0x06, + 0x09, + 0x0c, + 0x0f, + 0x12, + 0x15, + 0x18, + 0x1b, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 +}; + +const u32 dot11lcn_gain_idx_tbl_5G[] = { + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x10000000, + 0x00000000, + 0x20000000, + 0x00000000, + 0x30000000, + 0x00000000, + 0x40000000, + 0x00000000, + 0x30000000, + 0x00000008, + 0x40000000, + 0x00000008, + 0x50000000, + 0x00000008, + 0x60000000, + 0x00000008, + 0x70000000, + 0x00000008, + 0x60000000, + 0x00000018, + 0x70000000, + 0x00000018, + 0x80000000, + 0x00000018, + 0x90000000, + 0x00000018, + 0xa0000000, + 0x00000018, + 0xb0000000, + 0x00000018, + 0xc0000000, + 0x00000018, + 0xd0000000, + 0x00000018, + 0xe0000000, + 0x00000018, + 0xf0000000, + 0x00000018, + 0x00000000, + 0x00000019, + 0x10000000, + 0x00000019, + 0x20000000, + 0x00000019, + 0x30000000, + 0x00000019, + 0x40000000, + 0x00000019, + 0x50000000, + 0x00000019, + 0x60000000, + 0x00000019, + 0x70000000, + 0x00000019, + 0x80000000, + 0x00000019, + 0x90000000, + 0x00000019, + 0xa0000000, + 0x00000019, + 0xb0000000, + 0x00000019, + 0xc0000000, + 0x00000019, + 0xd0000000, + 0x00000019, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 +}; + +const u32 dot11lcn_gain_tbl_5G[] = { + 0x00000000, + 0x00000040, + 0x00000080, + 0x00000001, + 0x00000005, + 0x00000009, + 0x0000000d, + 0x00000011, + 0x00000015, + 0x00000055, + 0x00000095, + 0x00000017, + 0x0000001b, + 0x0000005b, + 0x0000009b, + 0x000000db, + 0x0000011b, + 0x0000015b, + 0x0000019b, + 0x0000059b, + 0x0000099b, + 0x00000d9b, + 0x0000119b, + 0x0000519b, + 0x0000919b, + 0x0000d19b, + 0x0001119b, + 0x0001519b, + 0x0001919b, + 0x0001d19b, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 +}; + +const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev0[] = { + {&dot11lcn_gain_tbl_rev0, + sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18, + 0, 32} + , + {&dot11lcn_aux_gain_idx_tbl_rev0, + sizeof(dot11lcn_aux_gain_idx_tbl_rev0) / + sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16} + , + {&dot11lcn_gain_idx_tbl_rev0, + sizeof(dot11lcn_gain_idx_tbl_rev0) / + sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32} + , +}; + +const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev1[] = { + {&dot11lcn_gain_tbl_rev1, + sizeof(dot11lcn_gain_tbl_rev1) / sizeof(dot11lcn_gain_tbl_rev1[0]), 18, + 0, 32} + , + {&dot11lcn_aux_gain_idx_tbl_rev0, + sizeof(dot11lcn_aux_gain_idx_tbl_rev0) / + sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16} + , + {&dot11lcn_gain_idx_tbl_rev0, + sizeof(dot11lcn_gain_idx_tbl_rev0) / + sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32} + , +}; + +const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_2G_rev2[] = { + {&dot11lcn_gain_tbl_2G, + sizeof(dot11lcn_gain_tbl_2G) / sizeof(dot11lcn_gain_tbl_2G[0]), 18, 0, + 32} + , + {&dot11lcn_aux_gain_idx_tbl_2G, + sizeof(dot11lcn_aux_gain_idx_tbl_2G) / + sizeof(dot11lcn_aux_gain_idx_tbl_2G[0]), 14, 0, 16} + , + {&dot11lcn_gain_idx_tbl_2G, + sizeof(dot11lcn_gain_idx_tbl_2G) / sizeof(dot11lcn_gain_idx_tbl_2G[0]), + 13, 0, 32} + , + {&dot11lcn_gain_val_tbl_2G, + sizeof(dot11lcn_gain_val_tbl_2G) / sizeof(dot11lcn_gain_val_tbl_2G[0]), + 17, 0, 8} +}; + +const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_5G_rev2[] = { + {&dot11lcn_gain_tbl_5G, + sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0, + 32} + , + {&dot11lcn_aux_gain_idx_tbl_5G, + sizeof(dot11lcn_aux_gain_idx_tbl_5G) / + sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16} + , + {&dot11lcn_gain_idx_tbl_5G, + sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]), + 13, 0, 32} + , + {&dot11lcn_gain_val_tbl_5G, + sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]), + 17, 0, 8} +}; + +const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[] = { + {&dot11lcn_gain_tbl_extlna_2G, + sizeof(dot11lcn_gain_tbl_extlna_2G) / + sizeof(dot11lcn_gain_tbl_extlna_2G[0]), 18, 0, 32} + , + {&dot11lcn_aux_gain_idx_tbl_extlna_2G, + sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G) / + sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G[0]), 14, 0, 16} + , + {&dot11lcn_gain_idx_tbl_extlna_2G, + sizeof(dot11lcn_gain_idx_tbl_extlna_2G) / + sizeof(dot11lcn_gain_idx_tbl_extlna_2G[0]), 13, 0, 32} + , + {&dot11lcn_gain_val_tbl_extlna_2G, + sizeof(dot11lcn_gain_val_tbl_extlna_2G) / + sizeof(dot11lcn_gain_val_tbl_extlna_2G[0]), 17, 0, 8} +}; + +const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[] = { + {&dot11lcn_gain_tbl_5G, + sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0, + 32} + , + {&dot11lcn_aux_gain_idx_tbl_5G, + sizeof(dot11lcn_aux_gain_idx_tbl_5G) / + sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16} + , + {&dot11lcn_gain_idx_tbl_5G, + sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]), + 13, 0, 32} + , + {&dot11lcn_gain_val_tbl_5G, + sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]), + 17, 0, 8} +}; + +const u32 dot11lcnphytbl_rx_gain_info_sz_rev0 = + sizeof(dot11lcnphytbl_rx_gain_info_rev0) / + sizeof(dot11lcnphytbl_rx_gain_info_rev0[0]); + +const u32 dot11lcnphytbl_rx_gain_info_sz_rev1 = + sizeof(dot11lcnphytbl_rx_gain_info_rev1) / + sizeof(dot11lcnphytbl_rx_gain_info_rev1[0]); + +const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz = + sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2) / + sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2[0]); + +const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz = + sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2) / + sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2[0]); + +const u16 dot11lcn_min_sig_sq_tbl_rev0[] = { + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, + 0x014d, +}; + +const u16 dot11lcn_noise_scale_tbl_rev0[] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}; + +const u32 dot11lcn_fltr_ctrl_tbl_rev0[] = { + 0x000141f8, + 0x000021f8, + 0x000021fb, + 0x000041fb, + 0x0001fe4b, + 0x0000217b, + 0x00002133, + 0x000040eb, + 0x0001fea3, + 0x0000024b, +}; + +const u32 dot11lcn_ps_ctrl_tbl_rev0[] = { + 0x00100001, + 0x00200010, + 0x00300001, + 0x00400010, + 0x00500022, + 0x00600122, + 0x00700222, + 0x00800322, + 0x00900422, + 0x00a00522, + 0x00b00622, + 0x00c00722, + 0x00d00822, + 0x00f00922, + 0x00100a22, + 0x00200b22, + 0x00300c22, + 0x00400d22, + 0x00500e22, + 0x00600f22, +}; + +const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[] = { + 0x0007, + 0x0005, + 0x0006, + 0x0004, + 0x0007, + 0x0005, + 0x0006, + 0x0004, + 0x0007, + 0x0005, + 0x0006, + 0x0004, + 0x0007, + 0x0005, + 0x0006, + 0x0004, + 0x000b, + 0x000b, + 0x000a, + 0x000a, + 0x000b, + 0x000b, + 0x000a, + 0x000a, + 0x000b, + 0x000b, + 0x000a, + 0x000a, + 0x000b, + 0x000b, + 0x000a, + 0x000a, + 0x0007, + 0x0005, + 0x0006, + 0x0004, + 0x0007, + 0x0005, + 0x0006, + 0x0004, + 0x0007, + 0x0005, + 0x0006, + 0x0004, + 0x0007, + 0x0005, + 0x0006, + 0x0004, + 0x000b, + 0x000b, + 0x000a, + 0x000a, + 0x000b, + 0x000b, + 0x000a, + 0x000a, + 0x000b, + 0x000b, + 0x000a, + 0x000a, + 0x000b, + 0x000b, + 0x000a, + 0x000a, + +}; + +const u16 dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[] = { + 0x0007, + 0x0005, + 0x0002, + 0x0000, + 0x0007, + 0x0005, + 0x0002, + 0x0000, + 0x0007, + 0x0005, + 0x0002, + 0x0000, + 0x0007, + 0x0005, + 0x0002, + 0x0000, + 0x0007, + 0x0007, + 0x0002, + 0x0002, + 0x0007, + 0x0007, + 0x0002, + 0x0002, + 0x0007, + 0x0007, + 0x0002, + 0x0002, + 0x0007, + 0x0007, + 0x0002, + 0x0002, + 0x0007, + 0x0005, + 0x0002, + 0x0000, + 0x0007, + 0x0005, + 0x0002, + 0x0000, + 0x0007, + 0x0005, + 0x0002, + 0x0000, + 0x0007, + 0x0005, + 0x0002, + 0x0000, + 0x0007, + 0x0007, + 0x0002, + 0x0002, + 0x0007, + 0x0007, + 0x0002, + 0x0002, + 0x0007, + 0x0007, + 0x0002, + 0x0002, + 0x0007, + 0x0007, + 0x0002, + 0x0002, +}; + +const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = { + 0x0002, + 0x0008, + 0x0004, + 0x0001, + 0x0002, + 0x0008, + 0x0004, + 0x0001, + 0x0002, + 0x0008, + 0x0004, + 0x0001, + 0x0002, + 0x0008, + 0x0004, + 0x0001, + 0x0002, + 0x0008, + 0x0004, + 0x0001, + 0x0002, + 0x0008, + 0x0004, + 0x0001, + 0x0002, + 0x0008, + 0x0004, + 0x0001, + 0x0002, + 0x0008, + 0x0004, + 0x0001, + 0x0002, + 0x0008, + 0x0004, + 0x0001, + 0x0002, + 0x0008, + 0x0004, + 0x0001, + 0x0002, + 0x0008, + 0x0004, + 0x0001, + 0x0002, + 0x0008, + 0x0004, + 0x0001, + 0x0002, + 0x0008, + 0x0004, + 0x0001, + 0x0002, + 0x0008, + 0x0004, + 0x0001, + 0x0002, + 0x0008, + 0x0004, + 0x0001, + 0x0002, + 0x0008, + 0x0004, + 0x0001, +}; + +const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = { + 0x000a, + 0x0009, + 0x0006, + 0x0005, + 0x000a, + 0x0009, + 0x0006, + 0x0005, + 0x000a, + 0x0009, + 0x0006, + 0x0005, + 0x000a, + 0x0009, + 0x0006, + 0x0005, + 0x000a, + 0x0009, + 0x0006, + 0x0005, + 0x000a, + 0x0009, + 0x0006, + 0x0005, + 0x000a, + 0x0009, + 0x0006, + 0x0005, + 0x000a, + 0x0009, + 0x0006, + 0x0005, + 0x000a, + 0x0009, + 0x0006, + 0x0005, + 0x000a, + 0x0009, + 0x0006, + 0x0005, + 0x000a, + 0x0009, + 0x0006, + 0x0005, + 0x000a, + 0x0009, + 0x0006, + 0x0005, + 0x000a, + 0x0009, + 0x0006, + 0x0005, + 0x000a, + 0x0009, + 0x0006, + 0x0005, + 0x000a, + 0x0009, + 0x0006, + 0x0005, + 0x000a, + 0x0009, + 0x0006, + 0x0005, +}; + +const u16 dot11lcn_sw_ctrl_tbl_rev0[] = { + 0x0004, + 0x0004, + 0x0002, + 0x0002, + 0x0004, + 0x0004, + 0x0002, + 0x0002, + 0x0004, + 0x0004, + 0x0002, + 0x0002, + 0x0004, + 0x0004, + 0x0002, + 0x0002, + 0x0004, + 0x0004, + 0x0002, + 0x0002, + 0x0004, + 0x0004, + 0x0002, + 0x0002, + 0x0004, + 0x0004, + 0x0002, + 0x0002, + 0x0004, + 0x0004, + 0x0002, + 0x0002, + 0x0004, + 0x0004, + 0x0002, + 0x0002, + 0x0004, + 0x0004, + 0x0002, + 0x0002, + 0x0004, + 0x0004, + 0x0002, + 0x0002, + 0x0004, + 0x0004, + 0x0002, + 0x0002, + 0x0004, + 0x0004, + 0x0002, + 0x0002, + 0x0004, + 0x0004, + 0x0002, + 0x0002, + 0x0004, + 0x0004, + 0x0002, + 0x0002, + 0x0004, + 0x0004, + 0x0002, + 0x0002, +}; + +const u8 dot11lcn_nf_table_rev0[] = { + 0x5f, + 0x36, + 0x29, + 0x1f, + 0x5f, + 0x36, + 0x29, + 0x1f, + 0x5f, + 0x36, + 0x29, + 0x1f, + 0x5f, + 0x36, + 0x29, + 0x1f, +}; + +const u8 dot11lcn_gain_val_tbl_rev0[] = { + 0x09, + 0x0f, + 0x14, + 0x18, + 0xfe, + 0x07, + 0x0b, + 0x0f, + 0xfb, + 0xfe, + 0x01, + 0x05, + 0x08, + 0x0b, + 0x0e, + 0x11, + 0x14, + 0x17, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x03, + 0x06, + 0x09, + 0x0c, + 0x0f, + 0x12, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x03, + 0x06, + 0x09, + 0x0c, + 0x0f, + 0x12, + 0x15, + 0x18, + 0x1b, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x03, + 0xeb, + 0x00, + 0x00, +}; + +const u8 dot11lcn_spur_tbl_rev0[] = { + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x02, + 0x03, + 0x01, + 0x03, + 0x02, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x02, + 0x03, + 0x01, + 0x03, + 0x02, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, +}; + +const u16 dot11lcn_unsup_mcs_tbl_rev0[] = { + 0x001a, + 0x0034, + 0x004e, + 0x0068, + 0x009c, + 0x00d0, + 0x00ea, + 0x0104, + 0x0034, + 0x0068, + 0x009c, + 0x00d0, + 0x0138, + 0x01a0, + 0x01d4, + 0x0208, + 0x004e, + 0x009c, + 0x00ea, + 0x0138, + 0x01d4, + 0x0270, + 0x02be, + 0x030c, + 0x0068, + 0x00d0, + 0x0138, + 0x01a0, + 0x0270, + 0x0340, + 0x03a8, + 0x0410, + 0x0018, + 0x009c, + 0x00d0, + 0x0104, + 0x00ea, + 0x0138, + 0x0186, + 0x00d0, + 0x0104, + 0x0104, + 0x0138, + 0x016c, + 0x016c, + 0x01a0, + 0x0138, + 0x0186, + 0x0186, + 0x01d4, + 0x0222, + 0x0222, + 0x0270, + 0x0104, + 0x0138, + 0x016c, + 0x0138, + 0x016c, + 0x01a0, + 0x01d4, + 0x01a0, + 0x01d4, + 0x0208, + 0x0208, + 0x023c, + 0x0186, + 0x01d4, + 0x0222, + 0x01d4, + 0x0222, + 0x0270, + 0x02be, + 0x0270, + 0x02be, + 0x030c, + 0x030c, + 0x035a, + 0x0036, + 0x006c, + 0x00a2, + 0x00d8, + 0x0144, + 0x01b0, + 0x01e6, + 0x021c, + 0x006c, + 0x00d8, + 0x0144, + 0x01b0, + 0x0288, + 0x0360, + 0x03cc, + 0x0438, + 0x00a2, + 0x0144, + 0x01e6, + 0x0288, + 0x03cc, + 0x0510, + 0x05b2, + 0x0654, + 0x00d8, + 0x01b0, + 0x0288, + 0x0360, + 0x0510, + 0x06c0, + 0x0798, + 0x0870, + 0x0018, + 0x0144, + 0x01b0, + 0x021c, + 0x01e6, + 0x0288, + 0x032a, + 0x01b0, + 0x021c, + 0x021c, + 0x0288, + 0x02f4, + 0x02f4, + 0x0360, + 0x0288, + 0x032a, + 0x032a, + 0x03cc, + 0x046e, + 0x046e, + 0x0510, + 0x021c, + 0x0288, + 0x02f4, + 0x0288, + 0x02f4, + 0x0360, + 0x03cc, + 0x0360, + 0x03cc, + 0x0438, + 0x0438, + 0x04a4, + 0x032a, + 0x03cc, + 0x046e, + 0x03cc, + 0x046e, + 0x0510, + 0x05b2, + 0x0510, + 0x05b2, + 0x0654, + 0x0654, + 0x06f6, +}; + +const u16 dot11lcn_iq_local_tbl_rev0[] = { + 0x0200, + 0x0300, + 0x0400, + 0x0600, + 0x0800, + 0x0b00, + 0x1000, + 0x1001, + 0x1002, + 0x1003, + 0x1004, + 0x1005, + 0x1006, + 0x1007, + 0x1707, + 0x2007, + 0x2d07, + 0x4007, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0200, + 0x0300, + 0x0400, + 0x0600, + 0x0800, + 0x0b00, + 0x1000, + 0x1001, + 0x1002, + 0x1003, + 0x1004, + 0x1005, + 0x1006, + 0x1007, + 0x1707, + 0x2007, + 0x2d07, + 0x4007, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x4000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}; + +const u32 dot11lcn_papd_compdelta_tbl_rev0[] = { + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, + 0x00080000, +}; + +const dot11lcnphytbl_info_t dot11lcnphytbl_info_rev0[] = { + {&dot11lcn_min_sig_sq_tbl_rev0, + sizeof(dot11lcn_min_sig_sq_tbl_rev0) / + sizeof(dot11lcn_min_sig_sq_tbl_rev0[0]), 2, 0, 16} + , + {&dot11lcn_noise_scale_tbl_rev0, + sizeof(dot11lcn_noise_scale_tbl_rev0) / + sizeof(dot11lcn_noise_scale_tbl_rev0[0]), 1, 0, 16} + , + {&dot11lcn_fltr_ctrl_tbl_rev0, + sizeof(dot11lcn_fltr_ctrl_tbl_rev0) / + sizeof(dot11lcn_fltr_ctrl_tbl_rev0[0]), 11, 0, 32} + , + {&dot11lcn_ps_ctrl_tbl_rev0, + sizeof(dot11lcn_ps_ctrl_tbl_rev0) / + sizeof(dot11lcn_ps_ctrl_tbl_rev0[0]), 12, 0, 32} + , + {&dot11lcn_gain_idx_tbl_rev0, + sizeof(dot11lcn_gain_idx_tbl_rev0) / + sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32} + , + {&dot11lcn_aux_gain_idx_tbl_rev0, + sizeof(dot11lcn_aux_gain_idx_tbl_rev0) / + sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16} + , + {&dot11lcn_sw_ctrl_tbl_rev0, + sizeof(dot11lcn_sw_ctrl_tbl_rev0) / + sizeof(dot11lcn_sw_ctrl_tbl_rev0[0]), 15, 0, 16} + , + {&dot11lcn_nf_table_rev0, + sizeof(dot11lcn_nf_table_rev0) / sizeof(dot11lcn_nf_table_rev0[0]), 16, + 0, 8} + , + {&dot11lcn_gain_val_tbl_rev0, + sizeof(dot11lcn_gain_val_tbl_rev0) / + sizeof(dot11lcn_gain_val_tbl_rev0[0]), 17, 0, 8} + , + {&dot11lcn_gain_tbl_rev0, + sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18, + 0, 32} + , + {&dot11lcn_spur_tbl_rev0, + sizeof(dot11lcn_spur_tbl_rev0) / sizeof(dot11lcn_spur_tbl_rev0[0]), 20, + 0, 8} + , + {&dot11lcn_unsup_mcs_tbl_rev0, + sizeof(dot11lcn_unsup_mcs_tbl_rev0) / + sizeof(dot11lcn_unsup_mcs_tbl_rev0[0]), 23, 0, 16} + , + {&dot11lcn_iq_local_tbl_rev0, + sizeof(dot11lcn_iq_local_tbl_rev0) / + sizeof(dot11lcn_iq_local_tbl_rev0[0]), 0, 0, 16} + , + {&dot11lcn_papd_compdelta_tbl_rev0, + sizeof(dot11lcn_papd_compdelta_tbl_rev0) / + sizeof(dot11lcn_papd_compdelta_tbl_rev0[0]), 24, 0, 32} + , +}; + +const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313 = { + &dot11lcn_sw_ctrl_tbl_4313_rev0, + sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0) / + sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0[0]), 15, 0, 16 +}; + +const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_epa = { + &dot11lcn_sw_ctrl_tbl_4313_epa_rev0, + sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0) / + sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0[0]), 15, 0, 16 +}; + +const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa = { + &dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo, + sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo) / + sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[0]), 15, 0, 16 +}; + +const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250 = { + &dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0, + sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0) / + sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[0]), 15, 0, 16 +}; + +const u32 dot11lcnphytbl_info_sz_rev0 = + sizeof(dot11lcnphytbl_info_rev0) / sizeof(dot11lcnphytbl_info_rev0[0]); + +const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[128] = { + {3, 0, 31, 0, 72,} + , + {3, 0, 31, 0, 70,} + , + {3, 0, 31, 0, 68,} + , + {3, 0, 30, 0, 67,} + , + {3, 0, 29, 0, 68,} + , + {3, 0, 28, 0, 68,} + , + {3, 0, 27, 0, 69,} + , + {3, 0, 26, 0, 70,} + , + {3, 0, 25, 0, 70,} + , + {3, 0, 24, 0, 71,} + , + {3, 0, 23, 0, 72,} + , + {3, 0, 23, 0, 70,} + , + {3, 0, 22, 0, 71,} + , + {3, 0, 21, 0, 72,} + , + {3, 0, 21, 0, 70,} + , + {3, 0, 21, 0, 68,} + , + {3, 0, 21, 0, 66,} + , + {3, 0, 21, 0, 64,} + , + {3, 0, 21, 0, 63,} + , + {3, 0, 20, 0, 64,} + , + {3, 0, 19, 0, 65,} + , + {3, 0, 19, 0, 64,} + , + {3, 0, 18, 0, 65,} + , + {3, 0, 18, 0, 64,} + , + {3, 0, 17, 0, 65,} + , + {3, 0, 17, 0, 64,} + , + {3, 0, 16, 0, 65,} + , + {3, 0, 16, 0, 64,} + , + {3, 0, 16, 0, 62,} + , + {3, 0, 16, 0, 60,} + , + {3, 0, 16, 0, 58,} + , + {3, 0, 15, 0, 61,} + , + {3, 0, 15, 0, 59,} + , + {3, 0, 14, 0, 61,} + , + {3, 0, 14, 0, 60,} + , + {3, 0, 14, 0, 58,} + , + {3, 0, 13, 0, 60,} + , + {3, 0, 13, 0, 59,} + , + {3, 0, 12, 0, 62,} + , + {3, 0, 12, 0, 60,} + , + {3, 0, 12, 0, 58,} + , + {3, 0, 11, 0, 62,} + , + {3, 0, 11, 0, 60,} + , + {3, 0, 11, 0, 59,} + , + {3, 0, 11, 0, 57,} + , + {3, 0, 10, 0, 61,} + , + {3, 0, 10, 0, 59,} + , + {3, 0, 10, 0, 57,} + , + {3, 0, 9, 0, 62,} + , + {3, 0, 9, 0, 60,} + , + {3, 0, 9, 0, 58,} + , + {3, 0, 9, 0, 57,} + , + {3, 0, 8, 0, 62,} + , + {3, 0, 8, 0, 60,} + , + {3, 0, 8, 0, 58,} + , + {3, 0, 8, 0, 57,} + , + {3, 0, 8, 0, 55,} + , + {3, 0, 7, 0, 61,} + , + {3, 0, 7, 0, 60,} + , + {3, 0, 7, 0, 58,} + , + {3, 0, 7, 0, 56,} + , + {3, 0, 7, 0, 55,} + , + {3, 0, 6, 0, 62,} + , + {3, 0, 6, 0, 60,} + , + {3, 0, 6, 0, 58,} + , + {3, 0, 6, 0, 57,} + , + {3, 0, 6, 0, 55,} + , + {3, 0, 6, 0, 54,} + , + {3, 0, 6, 0, 52,} + , + {3, 0, 5, 0, 61,} + , + {3, 0, 5, 0, 59,} + , + {3, 0, 5, 0, 57,} + , + {3, 0, 5, 0, 56,} + , + {3, 0, 5, 0, 54,} + , + {3, 0, 5, 0, 53,} + , + {3, 0, 5, 0, 51,} + , + {3, 0, 4, 0, 62,} + , + {3, 0, 4, 0, 60,} + , + {3, 0, 4, 0, 58,} + , + {3, 0, 4, 0, 57,} + , + {3, 0, 4, 0, 55,} + , + {3, 0, 4, 0, 54,} + , + {3, 0, 4, 0, 52,} + , + {3, 0, 4, 0, 51,} + , + {3, 0, 4, 0, 49,} + , + {3, 0, 4, 0, 48,} + , + {3, 0, 4, 0, 46,} + , + {3, 0, 3, 0, 60,} + , + {3, 0, 3, 0, 58,} + , + {3, 0, 3, 0, 57,} + , + {3, 0, 3, 0, 55,} + , + {3, 0, 3, 0, 54,} + , + {3, 0, 3, 0, 52,} + , + {3, 0, 3, 0, 51,} + , + {3, 0, 3, 0, 49,} + , + {3, 0, 3, 0, 48,} + , + {3, 0, 3, 0, 46,} + , + {3, 0, 3, 0, 45,} + , + {3, 0, 3, 0, 44,} + , + {3, 0, 3, 0, 43,} + , + {3, 0, 3, 0, 41,} + , + {3, 0, 2, 0, 61,} + , + {3, 0, 2, 0, 59,} + , + {3, 0, 2, 0, 57,} + , + {3, 0, 2, 0, 56,} + , + {3, 0, 2, 0, 54,} + , + {3, 0, 2, 0, 53,} + , + {3, 0, 2, 0, 51,} + , + {3, 0, 2, 0, 50,} + , + {3, 0, 2, 0, 48,} + , + {3, 0, 2, 0, 47,} + , + {3, 0, 2, 0, 46,} + , + {3, 0, 2, 0, 44,} + , + {3, 0, 2, 0, 43,} + , + {3, 0, 2, 0, 42,} + , + {3, 0, 2, 0, 41,} + , + {3, 0, 2, 0, 39,} + , + {3, 0, 2, 0, 38,} + , + {3, 0, 2, 0, 37,} + , + {3, 0, 2, 0, 36,} + , + {3, 0, 2, 0, 35,} + , + {3, 0, 2, 0, 34,} + , + {3, 0, 2, 0, 33,} + , + {3, 0, 2, 0, 32,} + , + {3, 0, 1, 0, 63,} + , + {3, 0, 1, 0, 61,} + , + {3, 0, 1, 0, 59,} + , + {3, 0, 1, 0, 57,} + , +}; + +const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[128] = { + {7, 0, 31, 0, 72,} + , + {7, 0, 31, 0, 70,} + , + {7, 0, 31, 0, 68,} + , + {7, 0, 30, 0, 67,} + , + {7, 0, 29, 0, 68,} + , + {7, 0, 28, 0, 68,} + , + {7, 0, 27, 0, 69,} + , + {7, 0, 26, 0, 70,} + , + {7, 0, 25, 0, 70,} + , + {7, 0, 24, 0, 71,} + , + {7, 0, 23, 0, 72,} + , + {7, 0, 23, 0, 70,} + , + {7, 0, 22, 0, 71,} + , + {7, 0, 21, 0, 72,} + , + {7, 0, 21, 0, 70,} + , + {7, 0, 21, 0, 68,} + , + {7, 0, 21, 0, 66,} + , + {7, 0, 21, 0, 64,} + , + {7, 0, 21, 0, 63,} + , + {7, 0, 20, 0, 64,} + , + {7, 0, 19, 0, 65,} + , + {7, 0, 19, 0, 64,} + , + {7, 0, 18, 0, 65,} + , + {7, 0, 18, 0, 64,} + , + {7, 0, 17, 0, 65,} + , + {7, 0, 17, 0, 64,} + , + {7, 0, 16, 0, 65,} + , + {7, 0, 16, 0, 64,} + , + {7, 0, 16, 0, 62,} + , + {7, 0, 16, 0, 60,} + , + {7, 0, 16, 0, 58,} + , + {7, 0, 15, 0, 61,} + , + {7, 0, 15, 0, 59,} + , + {7, 0, 14, 0, 61,} + , + {7, 0, 14, 0, 60,} + , + {7, 0, 14, 0, 58,} + , + {7, 0, 13, 0, 60,} + , + {7, 0, 13, 0, 59,} + , + {7, 0, 12, 0, 62,} + , + {7, 0, 12, 0, 60,} + , + {7, 0, 12, 0, 58,} + , + {7, 0, 11, 0, 62,} + , + {7, 0, 11, 0, 60,} + , + {7, 0, 11, 0, 59,} + , + {7, 0, 11, 0, 57,} + , + {7, 0, 10, 0, 61,} + , + {7, 0, 10, 0, 59,} + , + {7, 0, 10, 0, 57,} + , + {7, 0, 9, 0, 62,} + , + {7, 0, 9, 0, 60,} + , + {7, 0, 9, 0, 58,} + , + {7, 0, 9, 0, 57,} + , + {7, 0, 8, 0, 62,} + , + {7, 0, 8, 0, 60,} + , + {7, 0, 8, 0, 58,} + , + {7, 0, 8, 0, 57,} + , + {7, 0, 8, 0, 55,} + , + {7, 0, 7, 0, 61,} + , + {7, 0, 7, 0, 60,} + , + {7, 0, 7, 0, 58,} + , + {7, 0, 7, 0, 56,} + , + {7, 0, 7, 0, 55,} + , + {7, 0, 6, 0, 62,} + , + {7, 0, 6, 0, 60,} + , + {7, 0, 6, 0, 58,} + , + {7, 0, 6, 0, 57,} + , + {7, 0, 6, 0, 55,} + , + {7, 0, 6, 0, 54,} + , + {7, 0, 6, 0, 52,} + , + {7, 0, 5, 0, 61,} + , + {7, 0, 5, 0, 59,} + , + {7, 0, 5, 0, 57,} + , + {7, 0, 5, 0, 56,} + , + {7, 0, 5, 0, 54,} + , + {7, 0, 5, 0, 53,} + , + {7, 0, 5, 0, 51,} + , + {7, 0, 4, 0, 62,} + , + {7, 0, 4, 0, 60,} + , + {7, 0, 4, 0, 58,} + , + {7, 0, 4, 0, 57,} + , + {7, 0, 4, 0, 55,} + , + {7, 0, 4, 0, 54,} + , + {7, 0, 4, 0, 52,} + , + {7, 0, 4, 0, 51,} + , + {7, 0, 4, 0, 49,} + , + {7, 0, 4, 0, 48,} + , + {7, 0, 4, 0, 46,} + , + {7, 0, 3, 0, 60,} + , + {7, 0, 3, 0, 58,} + , + {7, 0, 3, 0, 57,} + , + {7, 0, 3, 0, 55,} + , + {7, 0, 3, 0, 54,} + , + {7, 0, 3, 0, 52,} + , + {7, 0, 3, 0, 51,} + , + {7, 0, 3, 0, 49,} + , + {7, 0, 3, 0, 48,} + , + {7, 0, 3, 0, 46,} + , + {7, 0, 3, 0, 45,} + , + {7, 0, 3, 0, 44,} + , + {7, 0, 3, 0, 43,} + , + {7, 0, 3, 0, 41,} + , + {7, 0, 2, 0, 61,} + , + {7, 0, 2, 0, 59,} + , + {7, 0, 2, 0, 57,} + , + {7, 0, 2, 0, 56,} + , + {7, 0, 2, 0, 54,} + , + {7, 0, 2, 0, 53,} + , + {7, 0, 2, 0, 51,} + , + {7, 0, 2, 0, 50,} + , + {7, 0, 2, 0, 48,} + , + {7, 0, 2, 0, 47,} + , + {7, 0, 2, 0, 46,} + , + {7, 0, 2, 0, 44,} + , + {7, 0, 2, 0, 43,} + , + {7, 0, 2, 0, 42,} + , + {7, 0, 2, 0, 41,} + , + {7, 0, 2, 0, 39,} + , + {7, 0, 2, 0, 38,} + , + {7, 0, 2, 0, 37,} + , + {7, 0, 2, 0, 36,} + , + {7, 0, 2, 0, 35,} + , + {7, 0, 2, 0, 34,} + , + {7, 0, 2, 0, 33,} + , + {7, 0, 2, 0, 32,} + , + {7, 0, 1, 0, 63,} + , + {7, 0, 1, 0, 61,} + , + {7, 0, 1, 0, 59,} + , + {7, 0, 1, 0, 57,} + , +}; + +const lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[128] = { + {255, 255, 0xf0, 0, 152,} + , + {255, 255, 0xf0, 0, 147,} + , + {255, 255, 0xf0, 0, 143,} + , + {255, 255, 0xf0, 0, 139,} + , + {255, 255, 0xf0, 0, 135,} + , + {255, 255, 0xf0, 0, 131,} + , + {255, 255, 0xf0, 0, 128,} + , + {255, 255, 0xf0, 0, 124,} + , + {255, 255, 0xf0, 0, 121,} + , + {255, 255, 0xf0, 0, 117,} + , + {255, 255, 0xf0, 0, 114,} + , + {255, 255, 0xf0, 0, 111,} + , + {255, 255, 0xf0, 0, 107,} + , + {255, 255, 0xf0, 0, 104,} + , + {255, 255, 0xf0, 0, 101,} + , + {255, 255, 0xf0, 0, 99,} + , + {255, 255, 0xf0, 0, 96,} + , + {255, 255, 0xf0, 0, 93,} + , + {255, 255, 0xf0, 0, 90,} + , + {255, 255, 0xf0, 0, 88,} + , + {255, 255, 0xf0, 0, 85,} + , + {255, 255, 0xf0, 0, 83,} + , + {255, 255, 0xf0, 0, 81,} + , + {255, 255, 0xf0, 0, 78,} + , + {255, 255, 0xf0, 0, 76,} + , + {255, 255, 0xf0, 0, 74,} + , + {255, 255, 0xf0, 0, 72,} + , + {255, 255, 0xf0, 0, 70,} + , + {255, 255, 0xf0, 0, 68,} + , + {255, 255, 0xf0, 0, 66,} + , + {255, 255, 0xf0, 0, 64,} + , + {255, 248, 0xf0, 0, 64,} + , + {255, 241, 0xf0, 0, 64,} + , + {255, 251, 0xe0, 0, 64,} + , + {255, 244, 0xe0, 0, 64,} + , + {255, 254, 0xd0, 0, 64,} + , + {255, 246, 0xd0, 0, 64,} + , + {255, 239, 0xd0, 0, 64,} + , + {255, 249, 0xc0, 0, 64,} + , + {255, 242, 0xc0, 0, 64,} + , + {255, 255, 0xb0, 0, 64,} + , + {255, 248, 0xb0, 0, 64,} + , + {255, 241, 0xb0, 0, 64,} + , + {255, 254, 0xa0, 0, 64,} + , + {255, 246, 0xa0, 0, 64,} + , + {255, 239, 0xa0, 0, 64,} + , + {255, 255, 0x90, 0, 64,} + , + {255, 248, 0x90, 0, 64,} + , + {255, 241, 0x90, 0, 64,} + , + {255, 234, 0x90, 0, 64,} + , + {255, 255, 0x80, 0, 64,} + , + {255, 248, 0x80, 0, 64,} + , + {255, 241, 0x80, 0, 64,} + , + {255, 234, 0x80, 0, 64,} + , + {255, 255, 0x70, 0, 64,} + , + {255, 248, 0x70, 0, 64,} + , + {255, 241, 0x70, 0, 64,} + , + {255, 234, 0x70, 0, 64,} + , + {255, 227, 0x70, 0, 64,} + , + {255, 221, 0x70, 0, 64,} + , + {255, 215, 0x70, 0, 64,} + , + {255, 208, 0x70, 0, 64,} + , + {255, 203, 0x70, 0, 64,} + , + {255, 197, 0x70, 0, 64,} + , + {255, 255, 0x60, 0, 64,} + , + {255, 248, 0x60, 0, 64,} + , + {255, 241, 0x60, 0, 64,} + , + {255, 234, 0x60, 0, 64,} + , + {255, 227, 0x60, 0, 64,} + , + {255, 221, 0x60, 0, 64,} + , + {255, 255, 0x50, 0, 64,} + , + {255, 248, 0x50, 0, 64,} + , + {255, 241, 0x50, 0, 64,} + , + {255, 234, 0x50, 0, 64,} + , + {255, 227, 0x50, 0, 64,} + , + {255, 221, 0x50, 0, 64,} + , + {255, 215, 0x50, 0, 64,} + , + {255, 208, 0x50, 0, 64,} + , + {255, 255, 0x40, 0, 64,} + , + {255, 248, 0x40, 0, 64,} + , + {255, 241, 0x40, 0, 64,} + , + {255, 234, 0x40, 0, 64,} + , + {255, 227, 0x40, 0, 64,} + , + {255, 221, 0x40, 0, 64,} + , + {255, 215, 0x40, 0, 64,} + , + {255, 208, 0x40, 0, 64,} + , + {255, 203, 0x40, 0, 64,} + , + {255, 197, 0x40, 0, 64,} + , + {255, 255, 0x30, 0, 64,} + , + {255, 248, 0x30, 0, 64,} + , + {255, 241, 0x30, 0, 64,} + , + {255, 234, 0x30, 0, 64,} + , + {255, 227, 0x30, 0, 64,} + , + {255, 221, 0x30, 0, 64,} + , + {255, 215, 0x30, 0, 64,} + , + {255, 208, 0x30, 0, 64,} + , + {255, 203, 0x30, 0, 64,} + , + {255, 197, 0x30, 0, 64,} + , + {255, 191, 0x30, 0, 64,} + , + {255, 186, 0x30, 0, 64,} + , + {255, 181, 0x30, 0, 64,} + , + {255, 175, 0x30, 0, 64,} + , + {255, 255, 0x20, 0, 64,} + , + {255, 248, 0x20, 0, 64,} + , + {255, 241, 0x20, 0, 64,} + , + {255, 234, 0x20, 0, 64,} + , + {255, 227, 0x20, 0, 64,} + , + {255, 221, 0x20, 0, 64,} + , + {255, 215, 0x20, 0, 64,} + , + {255, 208, 0x20, 0, 64,} + , + {255, 203, 0x20, 0, 64,} + , + {255, 197, 0x20, 0, 64,} + , + {255, 191, 0x20, 0, 64,} + , + {255, 186, 0x20, 0, 64,} + , + {255, 181, 0x20, 0, 64,} + , + {255, 175, 0x20, 0, 64,} + , + {255, 170, 0x20, 0, 64,} + , + {255, 166, 0x20, 0, 64,} + , + {255, 161, 0x20, 0, 64,} + , + {255, 156, 0x20, 0, 64,} + , + {255, 152, 0x20, 0, 64,} + , + {255, 148, 0x20, 0, 64,} + , + {255, 143, 0x20, 0, 64,} + , + {255, 139, 0x20, 0, 64,} + , + {255, 135, 0x20, 0, 64,} + , + {255, 132, 0x20, 0, 64,} + , + {255, 255, 0x10, 0, 64,} + , + {255, 248, 0x10, 0, 64,} + , +}; diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h new file mode 100644 index 000000000000..5a64a988d107 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +typedef phytbl_info_t dot11lcnphytbl_info_t; + +extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev0[]; +extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev0; +extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313; +extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_epa; +extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_epa_combo; + +extern const dot11lcnphytbl_info_t dot11lcnphytbl_info_rev0[]; +extern const u32 dot11lcnphytbl_info_sz_rev0; + +extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_2G_rev2[]; +extern const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz; + +extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_5G_rev2[]; +extern const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz; + +extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[]; + +extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[]; + +typedef struct { + unsigned char gm; + unsigned char pga; + unsigned char pad; + unsigned char dac; + unsigned char bb_mult; +} lcnphy_tx_gain_tbl_entry; + +extern const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[]; +extern const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[]; + +extern const lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[]; diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c new file mode 100644 index 000000000000..a9fc193721ef --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c @@ -0,0 +1,10634 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#include +#include + +const u32 frame_struct_rev0[] = { + 0x08004a04, + 0x00100000, + 0x01000a05, + 0x00100020, + 0x09804506, + 0x00100030, + 0x09804507, + 0x00100030, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x08004a0c, + 0x00100004, + 0x01000a0d, + 0x00100024, + 0x0980450e, + 0x00100034, + 0x0980450f, + 0x00100034, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000a04, + 0x00100000, + 0x11008a05, + 0x00100020, + 0x1980c506, + 0x00100030, + 0x21810506, + 0x00100030, + 0x21810506, + 0x00100030, + 0x01800504, + 0x00100030, + 0x11808505, + 0x00100030, + 0x29814507, + 0x01100030, + 0x00000a04, + 0x00100000, + 0x11008a05, + 0x00100020, + 0x21810506, + 0x00100030, + 0x21810506, + 0x00100030, + 0x29814507, + 0x01100030, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000a0c, + 0x00100008, + 0x11008a0d, + 0x00100028, + 0x1980c50e, + 0x00100038, + 0x2181050e, + 0x00100038, + 0x2181050e, + 0x00100038, + 0x0180050c, + 0x00100038, + 0x1180850d, + 0x00100038, + 0x2981450f, + 0x01100038, + 0x00000a0c, + 0x00100008, + 0x11008a0d, + 0x00100028, + 0x2181050e, + 0x00100038, + 0x2181050e, + 0x00100038, + 0x2981450f, + 0x01100038, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x08004a04, + 0x00100000, + 0x01000a05, + 0x00100020, + 0x1980c506, + 0x00100030, + 0x1980c506, + 0x00100030, + 0x11808504, + 0x00100030, + 0x3981ca05, + 0x00100030, + 0x29814507, + 0x01100030, + 0x00000000, + 0x00000000, + 0x10008a04, + 0x00100000, + 0x3981ca05, + 0x00100030, + 0x1980c506, + 0x00100030, + 0x29814507, + 0x01100030, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x08004a0c, + 0x00100008, + 0x01000a0d, + 0x00100028, + 0x1980c50e, + 0x00100038, + 0x1980c50e, + 0x00100038, + 0x1180850c, + 0x00100038, + 0x3981ca0d, + 0x00100038, + 0x2981450f, + 0x01100038, + 0x00000000, + 0x00000000, + 0x10008a0c, + 0x00100008, + 0x3981ca0d, + 0x00100038, + 0x1980c50e, + 0x00100038, + 0x2981450f, + 0x01100038, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x40021404, + 0x00100000, + 0x02001405, + 0x00100040, + 0x0b004a06, + 0x01900060, + 0x13008a06, + 0x01900060, + 0x13008a06, + 0x01900060, + 0x43020a04, + 0x00100060, + 0x1b00ca05, + 0x00100060, + 0x23010a07, + 0x01500060, + 0x40021404, + 0x00100000, + 0x1a00d405, + 0x00100040, + 0x13008a06, + 0x01900060, + 0x13008a06, + 0x01900060, + 0x23010a07, + 0x01500060, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x4002140c, + 0x00100010, + 0x0200140d, + 0x00100050, + 0x0b004a0e, + 0x01900070, + 0x13008a0e, + 0x01900070, + 0x13008a0e, + 0x01900070, + 0x43020a0c, + 0x00100070, + 0x1b00ca0d, + 0x00100070, + 0x23010a0f, + 0x01500070, + 0x4002140c, + 0x00100010, + 0x1a00d40d, + 0x00100050, + 0x13008a0e, + 0x01900070, + 0x13008a0e, + 0x01900070, + 0x23010a0f, + 0x01500070, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x50029404, + 0x00100000, + 0x32019405, + 0x00100040, + 0x0b004a06, + 0x01900060, + 0x0b004a06, + 0x01900060, + 0x5b02ca04, + 0x00100060, + 0x3b01d405, + 0x00100060, + 0x23010a07, + 0x01500060, + 0x00000000, + 0x00000000, + 0x5802d404, + 0x00100000, + 0x3b01d405, + 0x00100060, + 0x0b004a06, + 0x01900060, + 0x23010a07, + 0x01500060, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x5002940c, + 0x00100010, + 0x3201940d, + 0x00100050, + 0x0b004a0e, + 0x01900070, + 0x0b004a0e, + 0x01900070, + 0x5b02ca0c, + 0x00100070, + 0x3b01d40d, + 0x00100070, + 0x23010a0f, + 0x01500070, + 0x00000000, + 0x00000000, + 0x5802d40c, + 0x00100010, + 0x3b01d40d, + 0x00100070, + 0x0b004a0e, + 0x01900070, + 0x23010a0f, + 0x01500070, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x40021404, + 0x000f4800, + 0x62031405, + 0x00100040, + 0x53028a06, + 0x01900060, + 0x53028a07, + 0x01900060, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x4002140c, + 0x000f4808, + 0x6203140d, + 0x00100048, + 0x53028a0e, + 0x01900068, + 0x53028a0f, + 0x01900068, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000a0c, + 0x00100004, + 0x11008a0d, + 0x00100024, + 0x1980c50e, + 0x00100034, + 0x2181050e, + 0x00100034, + 0x2181050e, + 0x00100034, + 0x0180050c, + 0x00100038, + 0x1180850d, + 0x00100038, + 0x1181850d, + 0x00100038, + 0x2981450f, + 0x01100038, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000a0c, + 0x00100008, + 0x11008a0d, + 0x00100028, + 0x2181050e, + 0x00100038, + 0x2181050e, + 0x00100038, + 0x1181850d, + 0x00100038, + 0x2981450f, + 0x01100038, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x08004a04, + 0x00100000, + 0x01000a05, + 0x00100020, + 0x0180c506, + 0x00100030, + 0x0180c506, + 0x00100030, + 0x2180c50c, + 0x00100030, + 0x49820a0d, + 0x0016a130, + 0x41824a0d, + 0x0016a130, + 0x2981450f, + 0x01100030, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x2000ca0c, + 0x00100000, + 0x49820a0d, + 0x0016a130, + 0x1980c50e, + 0x00100030, + 0x41824a0d, + 0x0016a130, + 0x2981450f, + 0x01100030, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x4002140c, + 0x00100008, + 0x0200140d, + 0x00100048, + 0x0b004a0e, + 0x01900068, + 0x13008a0e, + 0x01900068, + 0x13008a0e, + 0x01900068, + 0x43020a0c, + 0x00100070, + 0x1b00ca0d, + 0x00100070, + 0x1b014a0d, + 0x00100070, + 0x23010a0f, + 0x01500070, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x4002140c, + 0x00100010, + 0x1a00d40d, + 0x00100050, + 0x13008a0e, + 0x01900070, + 0x13008a0e, + 0x01900070, + 0x1b014a0d, + 0x00100070, + 0x23010a0f, + 0x01500070, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x50029404, + 0x00100000, + 0x32019405, + 0x00100040, + 0x03004a06, + 0x01900060, + 0x03004a06, + 0x01900060, + 0x6b030a0c, + 0x00100060, + 0x4b02140d, + 0x0016a160, + 0x4302540d, + 0x0016a160, + 0x23010a0f, + 0x01500060, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x6b03140c, + 0x00100060, + 0x4b02140d, + 0x0016a160, + 0x0b004a0e, + 0x01900060, + 0x4302540d, + 0x0016a160, + 0x23010a0f, + 0x01500060, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x40021404, + 0x00100000, + 0x1a00d405, + 0x00100040, + 0x53028a06, + 0x01900060, + 0x5b02ca06, + 0x01900060, + 0x5b02ca06, + 0x01900060, + 0x43020a04, + 0x00100060, + 0x1b00ca05, + 0x00100060, + 0x53028a07, + 0x0190c060, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x4002140c, + 0x00100010, + 0x1a00d40d, + 0x00100050, + 0x53028a0e, + 0x01900070, + 0x5b02ca0e, + 0x01900070, + 0x5b02ca0e, + 0x01900070, + 0x43020a0c, + 0x00100070, + 0x1b00ca0d, + 0x00100070, + 0x53028a0f, + 0x0190c070, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x40021404, + 0x00100000, + 0x1a00d405, + 0x00100040, + 0x5b02ca06, + 0x01900060, + 0x5b02ca06, + 0x01900060, + 0x53028a07, + 0x0190c060, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x4002140c, + 0x00100010, + 0x1a00d40d, + 0x00100050, + 0x5b02ca0e, + 0x01900070, + 0x5b02ca0e, + 0x01900070, + 0x53028a0f, + 0x0190c070, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; + +const u8 frame_lut_rev0[] = { + 0x02, + 0x04, + 0x14, + 0x14, + 0x03, + 0x05, + 0x16, + 0x16, + 0x0a, + 0x0c, + 0x1c, + 0x1c, + 0x0b, + 0x0d, + 0x1e, + 0x1e, + 0x06, + 0x08, + 0x18, + 0x18, + 0x07, + 0x09, + 0x1a, + 0x1a, + 0x0e, + 0x10, + 0x20, + 0x28, + 0x0f, + 0x11, + 0x22, + 0x2a, +}; + +const u32 tmap_tbl_rev0[] = { + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0xf1111110, + 0x11111111, + 0x11f11111, + 0x00000111, + 0x11000000, + 0x1111f111, + 0x11111111, + 0x111111f1, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x000aa888, + 0x88880000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0xa1111110, + 0x11111111, + 0x11c11111, + 0x00000111, + 0x11000000, + 0x1111a111, + 0x11111111, + 0x111111a1, + 0xa2222220, + 0x22222222, + 0x22c22222, + 0x00000222, + 0x22000000, + 0x2222a222, + 0x22222222, + 0x222222a2, + 0xf1111110, + 0x11111111, + 0x11f11111, + 0x00011111, + 0x11110000, + 0x1111f111, + 0x11111111, + 0x111111f1, + 0xa8aa88a0, + 0xa88888a8, + 0xa8a8a88a, + 0x00088aaa, + 0xaaaa0000, + 0xa8a8aa88, + 0xa88aaaaa, + 0xaaaa8a8a, + 0xaaa8aaa0, + 0x8aaa8aaa, + 0xaa8a8a8a, + 0x000aaa88, + 0x8aaa0000, + 0xaaa8a888, + 0x8aa88a8a, + 0x8a88a888, + 0x08080a00, + 0x0a08080a, + 0x080a0a08, + 0x00080808, + 0x080a0000, + 0x080a0808, + 0x080a0808, + 0x0a0a0a08, + 0xa0a0a0a0, + 0x80a0a080, + 0x8080a0a0, + 0x00008080, + 0x80a00000, + 0x80a080a0, + 0xa080a0a0, + 0x8080a0a0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x99999000, + 0x9b9b99bb, + 0x9bb99999, + 0x9999b9b9, + 0x9b99bb90, + 0x9bbbbb9b, + 0x9b9b9bb9, + 0x00000999, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00aaa888, + 0x22000000, + 0x2222b222, + 0x22222222, + 0x222222b2, + 0xb2222220, + 0x22222222, + 0x22d22222, + 0x00000222, + 0x11000000, + 0x1111a111, + 0x11111111, + 0x111111a1, + 0xa1111110, + 0x11111111, + 0x11c11111, + 0x00000111, + 0x33000000, + 0x3333b333, + 0x33333333, + 0x333333b3, + 0xb3333330, + 0x33333333, + 0x33d33333, + 0x00000333, + 0x22000000, + 0x2222a222, + 0x22222222, + 0x222222a2, + 0xa2222220, + 0x22222222, + 0x22c22222, + 0x00000222, + 0x99b99b00, + 0x9b9b99bb, + 0x9bb99999, + 0x9999b9b9, + 0x9b99bb99, + 0x9bbbbb9b, + 0x9b9b9bb9, + 0x00000999, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa88, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x08aaa888, + 0x22222200, + 0x2222f222, + 0x22222222, + 0x222222f2, + 0x22222222, + 0x22222222, + 0x22f22222, + 0x00000222, + 0x11000000, + 0x1111f111, + 0x11111111, + 0x11111111, + 0xf1111111, + 0x11111111, + 0x11f11111, + 0x01111111, + 0xbb9bb900, + 0xb9b9bb99, + 0xb99bbbbb, + 0xbbbb9b9b, + 0xb9bb99bb, + 0xb99999b9, + 0xb9b9b99b, + 0x00000bbb, + 0xaa000000, + 0xa8a8aa88, + 0xa88aaaaa, + 0xaaaa8a8a, + 0xa8aa88aa, + 0xa88888a8, + 0xa8a8a88a, + 0x0a888aaa, + 0xaa000000, + 0xa8a8aa88, + 0xa88aaaaa, + 0xaaaa8a8a, + 0xa8aa88a0, + 0xa88888a8, + 0xa8a8a88a, + 0x00000aaa, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0xbbbbbb00, + 0x999bbbbb, + 0x9bb99b9b, + 0xb9b9b9bb, + 0xb9b99bbb, + 0xb9b9b9bb, + 0xb9bb9b99, + 0x00000999, + 0x8a000000, + 0xaa88a888, + 0xa88888aa, + 0xa88a8a88, + 0xa88aa88a, + 0x88a8aaaa, + 0xa8aa8aaa, + 0x0888a88a, + 0x0b0b0b00, + 0x090b0b0b, + 0x0b090b0b, + 0x0909090b, + 0x09090b0b, + 0x09090b0b, + 0x09090b09, + 0x00000909, + 0x0a000000, + 0x0a080808, + 0x080a080a, + 0x080a0a08, + 0x080a080a, + 0x0808080a, + 0x0a0a0a08, + 0x0808080a, + 0xb0b0b000, + 0x9090b0b0, + 0x90b09090, + 0xb0b0b090, + 0xb0b090b0, + 0x90b0b0b0, + 0xb0b09090, + 0x00000090, + 0x80000000, + 0xa080a080, + 0xa08080a0, + 0xa0808080, + 0xa080a080, + 0x80a0a0a0, + 0xa0a080a0, + 0x00a0a0a0, + 0x22000000, + 0x2222f222, + 0x22222222, + 0x222222f2, + 0xf2222220, + 0x22222222, + 0x22f22222, + 0x00000222, + 0x11000000, + 0x1111f111, + 0x11111111, + 0x111111f1, + 0xf1111110, + 0x11111111, + 0x11f11111, + 0x00000111, + 0x33000000, + 0x3333f333, + 0x33333333, + 0x333333f3, + 0xf3333330, + 0x33333333, + 0x33f33333, + 0x00000333, + 0x22000000, + 0x2222f222, + 0x22222222, + 0x222222f2, + 0xf2222220, + 0x22222222, + 0x22f22222, + 0x00000222, + 0x99000000, + 0x9b9b99bb, + 0x9bb99999, + 0x9999b9b9, + 0x9b99bb90, + 0x9bbbbb9b, + 0x9b9b9bb9, + 0x00000999, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0x88888000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00aaa888, + 0x88a88a00, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa88, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa88, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x08aaa888, + 0x11000000, + 0x1111a111, + 0x11111111, + 0x111111a1, + 0xa1111110, + 0x11111111, + 0x11c11111, + 0x00000111, + 0x11000000, + 0x1111a111, + 0x11111111, + 0x111111a1, + 0xa1111110, + 0x11111111, + 0x11c11111, + 0x00000111, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; + +const u32 tdtrn_tbl_rev0[] = { + 0x061c061c, + 0x0050ee68, + 0xf592fe36, + 0xfe5212f6, + 0x00000c38, + 0xfe5212f6, + 0xf592fe36, + 0x0050ee68, + 0x061c061c, + 0xee680050, + 0xfe36f592, + 0x12f6fe52, + 0x0c380000, + 0x12f6fe52, + 0xfe36f592, + 0xee680050, + 0x061c061c, + 0x0050ee68, + 0xf592fe36, + 0xfe5212f6, + 0x00000c38, + 0xfe5212f6, + 0xf592fe36, + 0x0050ee68, + 0x061c061c, + 0xee680050, + 0xfe36f592, + 0x12f6fe52, + 0x0c380000, + 0x12f6fe52, + 0xfe36f592, + 0xee680050, + 0x05e305e3, + 0x004def0c, + 0xf5f3fe47, + 0xfe611246, + 0x00000bc7, + 0xfe611246, + 0xf5f3fe47, + 0x004def0c, + 0x05e305e3, + 0xef0c004d, + 0xfe47f5f3, + 0x1246fe61, + 0x0bc70000, + 0x1246fe61, + 0xfe47f5f3, + 0xef0c004d, + 0x05e305e3, + 0x004def0c, + 0xf5f3fe47, + 0xfe611246, + 0x00000bc7, + 0xfe611246, + 0xf5f3fe47, + 0x004def0c, + 0x05e305e3, + 0xef0c004d, + 0xfe47f5f3, + 0x1246fe61, + 0x0bc70000, + 0x1246fe61, + 0xfe47f5f3, + 0xef0c004d, + 0xfa58fa58, + 0xf895043b, + 0xff4c09c0, + 0xfbc6ffa8, + 0xfb84f384, + 0x0798f6f9, + 0x05760122, + 0x058409f6, + 0x0b500000, + 0x05b7f542, + 0x08860432, + 0x06ddfee7, + 0xfb84f384, + 0xf9d90664, + 0xf7e8025c, + 0x00fff7bd, + 0x05a805a8, + 0xf7bd00ff, + 0x025cf7e8, + 0x0664f9d9, + 0xf384fb84, + 0xfee706dd, + 0x04320886, + 0xf54205b7, + 0x00000b50, + 0x09f60584, + 0x01220576, + 0xf6f90798, + 0xf384fb84, + 0xffa8fbc6, + 0x09c0ff4c, + 0x043bf895, + 0x02d402d4, + 0x07de0270, + 0xfc96079c, + 0xf90afe94, + 0xfe00ff2c, + 0x02d4065d, + 0x092a0096, + 0x0014fbb8, + 0xfd2cfd2c, + 0x076afb3c, + 0x0096f752, + 0xf991fd87, + 0xfb2c0200, + 0xfeb8f960, + 0x08e0fc96, + 0x049802a8, + 0xfd2cfd2c, + 0x02a80498, + 0xfc9608e0, + 0xf960feb8, + 0x0200fb2c, + 0xfd87f991, + 0xf7520096, + 0xfb3c076a, + 0xfd2cfd2c, + 0xfbb80014, + 0x0096092a, + 0x065d02d4, + 0xff2cfe00, + 0xfe94f90a, + 0x079cfc96, + 0x027007de, + 0x02d402d4, + 0x027007de, + 0x079cfc96, + 0xfe94f90a, + 0xff2cfe00, + 0x065d02d4, + 0x0096092a, + 0xfbb80014, + 0xfd2cfd2c, + 0xfb3c076a, + 0xf7520096, + 0xfd87f991, + 0x0200fb2c, + 0xf960feb8, + 0xfc9608e0, + 0x02a80498, + 0xfd2cfd2c, + 0x049802a8, + 0x08e0fc96, + 0xfeb8f960, + 0xfb2c0200, + 0xf991fd87, + 0x0096f752, + 0x076afb3c, + 0xfd2cfd2c, + 0x0014fbb8, + 0x092a0096, + 0x02d4065d, + 0xfe00ff2c, + 0xf90afe94, + 0xfc96079c, + 0x07de0270, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x062a0000, + 0xfefa0759, + 0x08b80908, + 0xf396fc2d, + 0xf9d6045c, + 0xfc4ef608, + 0xf748f596, + 0x07b207bf, + 0x062a062a, + 0xf84ef841, + 0xf748f596, + 0x03b209f8, + 0xf9d6045c, + 0x0c6a03d3, + 0x08b80908, + 0x0106f8a7, + 0x062a0000, + 0xfefaf8a7, + 0x08b8f6f8, + 0xf39603d3, + 0xf9d6fba4, + 0xfc4e09f8, + 0xf7480a6a, + 0x07b2f841, + 0x062af9d6, + 0xf84e07bf, + 0xf7480a6a, + 0x03b2f608, + 0xf9d6fba4, + 0x0c6afc2d, + 0x08b8f6f8, + 0x01060759, + 0x062a0000, + 0xfefa0759, + 0x08b80908, + 0xf396fc2d, + 0xf9d6045c, + 0xfc4ef608, + 0xf748f596, + 0x07b207bf, + 0x062a062a, + 0xf84ef841, + 0xf748f596, + 0x03b209f8, + 0xf9d6045c, + 0x0c6a03d3, + 0x08b80908, + 0x0106f8a7, + 0x062a0000, + 0xfefaf8a7, + 0x08b8f6f8, + 0xf39603d3, + 0xf9d6fba4, + 0xfc4e09f8, + 0xf7480a6a, + 0x07b2f841, + 0x062af9d6, + 0xf84e07bf, + 0xf7480a6a, + 0x03b2f608, + 0xf9d6fba4, + 0x0c6afc2d, + 0x08b8f6f8, + 0x01060759, + 0x061c061c, + 0xff30009d, + 0xffb21141, + 0xfd87fb54, + 0xf65dfe59, + 0x02eef99e, + 0x0166f03c, + 0xfff809b6, + 0x000008a4, + 0x000af42b, + 0x00eff577, + 0xfa840bf2, + 0xfc02ff51, + 0x08260f67, + 0xfff0036f, + 0x0842f9c3, + 0x00000000, + 0x063df7be, + 0xfc910010, + 0xf099f7da, + 0x00af03fe, + 0xf40e057c, + 0x0a89ff11, + 0x0bd5fff6, + 0xf75c0000, + 0xf64a0008, + 0x0fc4fe9a, + 0x0662fd12, + 0x01a709a3, + 0x04ac0279, + 0xeebf004e, + 0xff6300d0, + 0xf9e4f9e4, + 0x00d0ff63, + 0x004eeebf, + 0x027904ac, + 0x09a301a7, + 0xfd120662, + 0xfe9a0fc4, + 0x0008f64a, + 0x0000f75c, + 0xfff60bd5, + 0xff110a89, + 0x057cf40e, + 0x03fe00af, + 0xf7daf099, + 0x0010fc91, + 0xf7be063d, + 0x00000000, + 0xf9c30842, + 0x036ffff0, + 0x0f670826, + 0xff51fc02, + 0x0bf2fa84, + 0xf57700ef, + 0xf42b000a, + 0x08a40000, + 0x09b6fff8, + 0xf03c0166, + 0xf99e02ee, + 0xfe59f65d, + 0xfb54fd87, + 0x1141ffb2, + 0x009dff30, + 0x05e30000, + 0xff060705, + 0x085408a0, + 0xf425fc59, + 0xfa1d042a, + 0xfc78f67a, + 0xf7acf60e, + 0x075a0766, + 0x05e305e3, + 0xf8a6f89a, + 0xf7acf60e, + 0x03880986, + 0xfa1d042a, + 0x0bdb03a7, + 0x085408a0, + 0x00faf8fb, + 0x05e30000, + 0xff06f8fb, + 0x0854f760, + 0xf42503a7, + 0xfa1dfbd6, + 0xfc780986, + 0xf7ac09f2, + 0x075af89a, + 0x05e3fa1d, + 0xf8a60766, + 0xf7ac09f2, + 0x0388f67a, + 0xfa1dfbd6, + 0x0bdbfc59, + 0x0854f760, + 0x00fa0705, + 0x05e30000, + 0xff060705, + 0x085408a0, + 0xf425fc59, + 0xfa1d042a, + 0xfc78f67a, + 0xf7acf60e, + 0x075a0766, + 0x05e305e3, + 0xf8a6f89a, + 0xf7acf60e, + 0x03880986, + 0xfa1d042a, + 0x0bdb03a7, + 0x085408a0, + 0x00faf8fb, + 0x05e30000, + 0xff06f8fb, + 0x0854f760, + 0xf42503a7, + 0xfa1dfbd6, + 0xfc780986, + 0xf7ac09f2, + 0x075af89a, + 0x05e3fa1d, + 0xf8a60766, + 0xf7ac09f2, + 0x0388f67a, + 0xfa1dfbd6, + 0x0bdbfc59, + 0x0854f760, + 0x00fa0705, + 0xfa58fa58, + 0xf8f0fe00, + 0x0448073d, + 0xfdc9fe46, + 0xf9910258, + 0x089d0407, + 0xfd5cf71a, + 0x02affde0, + 0x083e0496, + 0xff5a0740, + 0xff7afd97, + 0x00fe01f1, + 0x0009082e, + 0xfa94ff75, + 0xfecdf8ea, + 0xffb0f693, + 0xfd2cfa58, + 0x0433ff16, + 0xfba405dd, + 0xfa610341, + 0x06a606cb, + 0x0039fd2d, + 0x0677fa97, + 0x01fa05e0, + 0xf896003e, + 0x075a068b, + 0x012cfc3e, + 0xfa23f98d, + 0xfc7cfd43, + 0xff90fc0d, + 0x01c10982, + 0x00c601d6, + 0xfd2cfd2c, + 0x01d600c6, + 0x098201c1, + 0xfc0dff90, + 0xfd43fc7c, + 0xf98dfa23, + 0xfc3e012c, + 0x068b075a, + 0x003ef896, + 0x05e001fa, + 0xfa970677, + 0xfd2d0039, + 0x06cb06a6, + 0x0341fa61, + 0x05ddfba4, + 0xff160433, + 0xfa58fd2c, + 0xf693ffb0, + 0xf8eafecd, + 0xff75fa94, + 0x082e0009, + 0x01f100fe, + 0xfd97ff7a, + 0x0740ff5a, + 0x0496083e, + 0xfde002af, + 0xf71afd5c, + 0x0407089d, + 0x0258f991, + 0xfe46fdc9, + 0x073d0448, + 0xfe00f8f0, + 0xfd2cfd2c, + 0xfce00500, + 0xfc09fddc, + 0xfe680157, + 0x04c70571, + 0xfc3aff21, + 0xfcd70228, + 0x056d0277, + 0x0200fe00, + 0x0022f927, + 0xfe3c032b, + 0xfc44ff3c, + 0x03e9fbdb, + 0x04570313, + 0x04c9ff5c, + 0x000d03b8, + 0xfa580000, + 0xfbe900d2, + 0xf9d0fe0b, + 0x0125fdf9, + 0x042501bf, + 0x0328fa2b, + 0xffa902f0, + 0xfa250157, + 0x0200fe00, + 0x03740438, + 0xff0405fd, + 0x030cfe52, + 0x0037fb39, + 0xff6904c5, + 0x04f8fd23, + 0xfd31fc1b, + 0xfd2cfd2c, + 0xfc1bfd31, + 0xfd2304f8, + 0x04c5ff69, + 0xfb390037, + 0xfe52030c, + 0x05fdff04, + 0x04380374, + 0xfe000200, + 0x0157fa25, + 0x02f0ffa9, + 0xfa2b0328, + 0x01bf0425, + 0xfdf90125, + 0xfe0bf9d0, + 0x00d2fbe9, + 0x0000fa58, + 0x03b8000d, + 0xff5c04c9, + 0x03130457, + 0xfbdb03e9, + 0xff3cfc44, + 0x032bfe3c, + 0xf9270022, + 0xfe000200, + 0x0277056d, + 0x0228fcd7, + 0xff21fc3a, + 0x057104c7, + 0x0157fe68, + 0xfddcfc09, + 0x0500fce0, + 0xfd2cfd2c, + 0x0500fce0, + 0xfddcfc09, + 0x0157fe68, + 0x057104c7, + 0xff21fc3a, + 0x0228fcd7, + 0x0277056d, + 0xfe000200, + 0xf9270022, + 0x032bfe3c, + 0xff3cfc44, + 0xfbdb03e9, + 0x03130457, + 0xff5c04c9, + 0x03b8000d, + 0x0000fa58, + 0x00d2fbe9, + 0xfe0bf9d0, + 0xfdf90125, + 0x01bf0425, + 0xfa2b0328, + 0x02f0ffa9, + 0x0157fa25, + 0xfe000200, + 0x04380374, + 0x05fdff04, + 0xfe52030c, + 0xfb390037, + 0x04c5ff69, + 0xfd2304f8, + 0xfc1bfd31, + 0xfd2cfd2c, + 0xfd31fc1b, + 0x04f8fd23, + 0xff6904c5, + 0x0037fb39, + 0x030cfe52, + 0xff0405fd, + 0x03740438, + 0x0200fe00, + 0xfa250157, + 0xffa902f0, + 0x0328fa2b, + 0x042501bf, + 0x0125fdf9, + 0xf9d0fe0b, + 0xfbe900d2, + 0xfa580000, + 0x000d03b8, + 0x04c9ff5c, + 0x04570313, + 0x03e9fbdb, + 0xfc44ff3c, + 0xfe3c032b, + 0x0022f927, + 0x0200fe00, + 0x056d0277, + 0xfcd70228, + 0xfc3aff21, + 0x04c70571, + 0xfe680157, + 0xfc09fddc, + 0xfce00500, + 0x05a80000, + 0xff1006be, + 0x0800084a, + 0xf49cfc7e, + 0xfa580400, + 0xfc9cf6da, + 0xf800f672, + 0x0710071c, + 0x05a805a8, + 0xf8f0f8e4, + 0xf800f672, + 0x03640926, + 0xfa580400, + 0x0b640382, + 0x0800084a, + 0x00f0f942, + 0x05a80000, + 0xff10f942, + 0x0800f7b6, + 0xf49c0382, + 0xfa58fc00, + 0xfc9c0926, + 0xf800098e, + 0x0710f8e4, + 0x05a8fa58, + 0xf8f0071c, + 0xf800098e, + 0x0364f6da, + 0xfa58fc00, + 0x0b64fc7e, + 0x0800f7b6, + 0x00f006be, + 0x05a80000, + 0xff1006be, + 0x0800084a, + 0xf49cfc7e, + 0xfa580400, + 0xfc9cf6da, + 0xf800f672, + 0x0710071c, + 0x05a805a8, + 0xf8f0f8e4, + 0xf800f672, + 0x03640926, + 0xfa580400, + 0x0b640382, + 0x0800084a, + 0x00f0f942, + 0x05a80000, + 0xff10f942, + 0x0800f7b6, + 0xf49c0382, + 0xfa58fc00, + 0xfc9c0926, + 0xf800098e, + 0x0710f8e4, + 0x05a8fa58, + 0xf8f0071c, + 0xf800098e, + 0x0364f6da, + 0xfa58fc00, + 0x0b64fc7e, + 0x0800f7b6, + 0x00f006be, +}; + +const u32 intlv_tbl_rev0[] = { + 0x00802070, + 0x0671188d, + 0x0a60192c, + 0x0a300e46, + 0x00c1188d, + 0x080024d2, + 0x00000070, +}; + +const u16 pilot_tbl_rev0[] = { + 0xff08, + 0xff08, + 0xff08, + 0xff08, + 0xff08, + 0xff08, + 0xff08, + 0xff08, + 0x80d5, + 0x80d5, + 0x80d5, + 0x80d5, + 0x80d5, + 0x80d5, + 0x80d5, + 0x80d5, + 0xff0a, + 0xff82, + 0xffa0, + 0xff28, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xff82, + 0xffa0, + 0xff28, + 0xff0a, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xf83f, + 0xfa1f, + 0xfa97, + 0xfab5, + 0xf2bd, + 0xf0bf, + 0xffff, + 0xffff, + 0xf017, + 0xf815, + 0xf215, + 0xf095, + 0xf035, + 0xf01d, + 0xffff, + 0xffff, + 0xff08, + 0xff02, + 0xff80, + 0xff20, + 0xff08, + 0xff02, + 0xff80, + 0xff20, + 0xf01f, + 0xf817, + 0xfa15, + 0xf295, + 0xf0b5, + 0xf03d, + 0xffff, + 0xffff, + 0xf82a, + 0xfa0a, + 0xfa82, + 0xfaa0, + 0xf2a8, + 0xf0aa, + 0xffff, + 0xffff, + 0xf002, + 0xf800, + 0xf200, + 0xf080, + 0xf020, + 0xf008, + 0xffff, + 0xffff, + 0xf00a, + 0xf802, + 0xfa00, + 0xf280, + 0xf0a0, + 0xf028, + 0xffff, + 0xffff, +}; + +const u32 pltlut_tbl_rev0[] = { + 0x76540123, + 0x62407351, + 0x76543201, + 0x76540213, + 0x76540123, + 0x76430521, +}; + +const u32 tdi_tbl20_ant0_rev0[] = { + 0x00091226, + 0x000a1429, + 0x000b56ad, + 0x000c58b0, + 0x000d5ab3, + 0x000e9cb6, + 0x000f9eba, + 0x0000c13d, + 0x00020301, + 0x00030504, + 0x00040708, + 0x0005090b, + 0x00064b8e, + 0x00095291, + 0x000a5494, + 0x000b9718, + 0x000c9927, + 0x000d9b2a, + 0x000edd2e, + 0x000fdf31, + 0x000101b4, + 0x000243b7, + 0x000345bb, + 0x000447be, + 0x00058982, + 0x00068c05, + 0x00099309, + 0x000a950c, + 0x000bd78f, + 0x000cd992, + 0x000ddb96, + 0x000f1d99, + 0x00005fa8, + 0x0001422c, + 0x0002842f, + 0x00038632, + 0x00048835, + 0x0005ca38, + 0x0006ccbc, + 0x0009d3bf, + 0x000b1603, + 0x000c1806, + 0x000d1a0a, + 0x000e1c0d, + 0x000f5e10, + 0x00008093, + 0x00018297, + 0x0002c49a, + 0x0003c680, + 0x0004c880, + 0x00060b00, + 0x00070d00, + 0x00000000, + 0x00000000, + 0x00000000, +}; + +const u32 tdi_tbl20_ant1_rev0[] = { + 0x00014b26, + 0x00028d29, + 0x000393ad, + 0x00049630, + 0x0005d833, + 0x0006da36, + 0x00099c3a, + 0x000a9e3d, + 0x000bc081, + 0x000cc284, + 0x000dc488, + 0x000f068b, + 0x0000488e, + 0x00018b91, + 0x0002d214, + 0x0003d418, + 0x0004d6a7, + 0x000618aa, + 0x00071aae, + 0x0009dcb1, + 0x000b1eb4, + 0x000c0137, + 0x000d033b, + 0x000e053e, + 0x000f4702, + 0x00008905, + 0x00020c09, + 0x0003128c, + 0x0004148f, + 0x00051712, + 0x00065916, + 0x00091b19, + 0x000a1d28, + 0x000b5f2c, + 0x000c41af, + 0x000d43b2, + 0x000e85b5, + 0x000f87b8, + 0x0000c9bc, + 0x00024cbf, + 0x00035303, + 0x00045506, + 0x0005978a, + 0x0006998d, + 0x00095b90, + 0x000a5d93, + 0x000b9f97, + 0x000c821a, + 0x000d8400, + 0x000ec600, + 0x000fc800, + 0x00010a00, + 0x00000000, + 0x00000000, + 0x00000000, +}; + +const u32 tdi_tbl40_ant0_rev0[] = { + 0x0011a346, + 0x00136ccf, + 0x0014f5d9, + 0x001641e2, + 0x0017cb6b, + 0x00195475, + 0x001b2383, + 0x001cad0c, + 0x001e7616, + 0x0000821f, + 0x00020ba8, + 0x0003d4b2, + 0x00056447, + 0x00072dd0, + 0x0008b6da, + 0x000a02e3, + 0x000b8c6c, + 0x000d15f6, + 0x0011e484, + 0x0013ae0d, + 0x00153717, + 0x00168320, + 0x00180ca9, + 0x00199633, + 0x001b6548, + 0x001ceed1, + 0x001eb7db, + 0x0000c3e4, + 0x00024d6d, + 0x000416f7, + 0x0005a585, + 0x00076f0f, + 0x0008f818, + 0x000a4421, + 0x000bcdab, + 0x000d9734, + 0x00122649, + 0x0013efd2, + 0x001578dc, + 0x0016c4e5, + 0x00184e6e, + 0x001a17f8, + 0x001ba686, + 0x001d3010, + 0x001ef999, + 0x00010522, + 0x00028eac, + 0x00045835, + 0x0005e74a, + 0x0007b0d3, + 0x00093a5d, + 0x000a85e6, + 0x000c0f6f, + 0x000dd8f9, + 0x00126787, + 0x00143111, + 0x0015ba9a, + 0x00170623, + 0x00188fad, + 0x001a5936, + 0x001be84b, + 0x001db1d4, + 0x001f3b5e, + 0x000146e7, + 0x00031070, + 0x000499fa, + 0x00062888, + 0x0007f212, + 0x00097b9b, + 0x000ac7a4, + 0x000c50ae, + 0x000e1a37, + 0x0012a94c, + 0x001472d5, + 0x0015fc5f, + 0x00174868, + 0x0018d171, + 0x001a9afb, + 0x001c2989, + 0x001df313, + 0x001f7c9c, + 0x000188a5, + 0x000351af, + 0x0004db38, + 0x0006aa4d, + 0x000833d7, + 0x0009bd60, + 0x000b0969, + 0x000c9273, + 0x000e5bfc, + 0x00132a8a, + 0x0014b414, + 0x00163d9d, + 0x001789a6, + 0x001912b0, + 0x001adc39, + 0x001c6bce, + 0x001e34d8, + 0x001fbe61, + 0x0001ca6a, + 0x00039374, + 0x00051cfd, + 0x0006ec0b, + 0x00087515, + 0x0009fe9e, + 0x000b4aa7, + 0x000cd3b1, + 0x000e9d3a, + 0x00000000, + 0x00000000, +}; + +const u32 tdi_tbl40_ant1_rev0[] = { + 0x001edb36, + 0x000129ca, + 0x0002b353, + 0x00047cdd, + 0x0005c8e6, + 0x000791ef, + 0x00091bf9, + 0x000aaa07, + 0x000c3391, + 0x000dfd1a, + 0x00120923, + 0x0013d22d, + 0x00155c37, + 0x0016eacb, + 0x00187454, + 0x001a3dde, + 0x001b89e7, + 0x001d12f0, + 0x001f1cfa, + 0x00016b88, + 0x00033492, + 0x0004be1b, + 0x00060a24, + 0x0007d32e, + 0x00095d38, + 0x000aec4c, + 0x000c7555, + 0x000e3edf, + 0x00124ae8, + 0x001413f1, + 0x0015a37b, + 0x00172c89, + 0x0018b593, + 0x001a419c, + 0x001bcb25, + 0x001d942f, + 0x001f63b9, + 0x0001ad4d, + 0x00037657, + 0x0004c260, + 0x00068be9, + 0x000814f3, + 0x0009a47c, + 0x000b2d8a, + 0x000cb694, + 0x000e429d, + 0x00128c26, + 0x001455b0, + 0x0015e4ba, + 0x00176e4e, + 0x0018f758, + 0x001a8361, + 0x001c0cea, + 0x001dd674, + 0x001fa57d, + 0x0001ee8b, + 0x0003b795, + 0x0005039e, + 0x0006cd27, + 0x000856b1, + 0x0009e5c6, + 0x000b6f4f, + 0x000cf859, + 0x000e8462, + 0x00130deb, + 0x00149775, + 0x00162603, + 0x0017af8c, + 0x00193896, + 0x001ac49f, + 0x001c4e28, + 0x001e17b2, + 0x0000a6c7, + 0x00023050, + 0x0003f9da, + 0x00054563, + 0x00070eec, + 0x00089876, + 0x000a2704, + 0x000bb08d, + 0x000d3a17, + 0x001185a0, + 0x00134f29, + 0x0014d8b3, + 0x001667c8, + 0x0017f151, + 0x00197adb, + 0x001b0664, + 0x001c8fed, + 0x001e5977, + 0x0000e805, + 0x0002718f, + 0x00043b18, + 0x000586a1, + 0x0007502b, + 0x0008d9b4, + 0x000a68c9, + 0x000bf252, + 0x000dbbdc, + 0x0011c7e5, + 0x001390ee, + 0x00151a78, + 0x0016a906, + 0x00183290, + 0x0019bc19, + 0x001b4822, + 0x001cd12c, + 0x001e9ab5, + 0x00000000, + 0x00000000, +}; + +const u16 bdi_tbl_rev0[] = { + 0x0070, + 0x0126, + 0x012c, + 0x0246, + 0x048d, + 0x04d2, +}; + +const u32 chanest_tbl_rev0[] = { + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, +}; + +const u8 mcs_tbl_rev0[] = { + 0x00, + 0x08, + 0x0a, + 0x10, + 0x12, + 0x19, + 0x1a, + 0x1c, + 0x40, + 0x48, + 0x4a, + 0x50, + 0x52, + 0x59, + 0x5a, + 0x5c, + 0x80, + 0x88, + 0x8a, + 0x90, + 0x92, + 0x99, + 0x9a, + 0x9c, + 0xc0, + 0xc8, + 0xca, + 0xd0, + 0xd2, + 0xd9, + 0xda, + 0xdc, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x02, + 0x04, + 0x08, + 0x09, + 0x0a, + 0x0c, + 0x10, + 0x11, + 0x12, + 0x14, + 0x18, + 0x19, + 0x1a, + 0x1c, + 0x20, + 0x21, + 0x22, + 0x24, + 0x40, + 0x41, + 0x42, + 0x44, + 0x48, + 0x49, + 0x4a, + 0x4c, + 0x50, + 0x51, + 0x52, + 0x54, + 0x58, + 0x59, + 0x5a, + 0x5c, + 0x60, + 0x61, + 0x62, + 0x64, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, +}; + +const u32 noise_var_tbl0_rev0[] = { + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, +}; + +const u32 noise_var_tbl1_rev0[] = { + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, +}; + +const u8 est_pwr_lut_core0_rev0[] = { + 0x50, + 0x4f, + 0x4e, + 0x4d, + 0x4c, + 0x4b, + 0x4a, + 0x49, + 0x48, + 0x47, + 0x46, + 0x45, + 0x44, + 0x43, + 0x42, + 0x41, + 0x40, + 0x3f, + 0x3e, + 0x3d, + 0x3c, + 0x3b, + 0x3a, + 0x39, + 0x38, + 0x37, + 0x36, + 0x35, + 0x34, + 0x33, + 0x32, + 0x31, + 0x30, + 0x2f, + 0x2e, + 0x2d, + 0x2c, + 0x2b, + 0x2a, + 0x29, + 0x28, + 0x27, + 0x26, + 0x25, + 0x24, + 0x23, + 0x22, + 0x21, + 0x20, + 0x1f, + 0x1e, + 0x1d, + 0x1c, + 0x1b, + 0x1a, + 0x19, + 0x18, + 0x17, + 0x16, + 0x15, + 0x14, + 0x13, + 0x12, + 0x11, +}; + +const u8 est_pwr_lut_core1_rev0[] = { + 0x50, + 0x4f, + 0x4e, + 0x4d, + 0x4c, + 0x4b, + 0x4a, + 0x49, + 0x48, + 0x47, + 0x46, + 0x45, + 0x44, + 0x43, + 0x42, + 0x41, + 0x40, + 0x3f, + 0x3e, + 0x3d, + 0x3c, + 0x3b, + 0x3a, + 0x39, + 0x38, + 0x37, + 0x36, + 0x35, + 0x34, + 0x33, + 0x32, + 0x31, + 0x30, + 0x2f, + 0x2e, + 0x2d, + 0x2c, + 0x2b, + 0x2a, + 0x29, + 0x28, + 0x27, + 0x26, + 0x25, + 0x24, + 0x23, + 0x22, + 0x21, + 0x20, + 0x1f, + 0x1e, + 0x1d, + 0x1c, + 0x1b, + 0x1a, + 0x19, + 0x18, + 0x17, + 0x16, + 0x15, + 0x14, + 0x13, + 0x12, + 0x11, +}; + +const u8 adj_pwr_lut_core0_rev0[] = { + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, +}; + +const u8 adj_pwr_lut_core1_rev0[] = { + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, +}; + +const u32 gainctrl_lut_core0_rev0[] = { + 0x03cc2b44, + 0x03cc2b42, + 0x03cc2b40, + 0x03cc2b3e, + 0x03cc2b3d, + 0x03cc2b3b, + 0x03c82b44, + 0x03c82b42, + 0x03c82b40, + 0x03c82b3e, + 0x03c82b3d, + 0x03c82b3b, + 0x03c82b39, + 0x03c82b38, + 0x03c82b36, + 0x03c82b34, + 0x03c42b44, + 0x03c42b42, + 0x03c42b40, + 0x03c42b3e, + 0x03c42b3d, + 0x03c42b3b, + 0x03c42b39, + 0x03c42b38, + 0x03c42b36, + 0x03c42b34, + 0x03c42b33, + 0x03c42b32, + 0x03c42b30, + 0x03c42b2f, + 0x03c42b2d, + 0x03c02b44, + 0x03c02b42, + 0x03c02b40, + 0x03c02b3e, + 0x03c02b3d, + 0x03c02b3b, + 0x03c02b39, + 0x03c02b38, + 0x03c02b36, + 0x03c02b34, + 0x03b02b44, + 0x03b02b42, + 0x03b02b40, + 0x03b02b3e, + 0x03b02b3d, + 0x03b02b3b, + 0x03b02b39, + 0x03b02b38, + 0x03b02b36, + 0x03b02b34, + 0x03b02b33, + 0x03b02b32, + 0x03b02b30, + 0x03b02b2f, + 0x03b02b2d, + 0x03a02b44, + 0x03a02b42, + 0x03a02b40, + 0x03a02b3e, + 0x03a02b3d, + 0x03a02b3b, + 0x03a02b39, + 0x03a02b38, + 0x03a02b36, + 0x03a02b34, + 0x03902b44, + 0x03902b42, + 0x03902b40, + 0x03902b3e, + 0x03902b3d, + 0x03902b3b, + 0x03902b39, + 0x03902b38, + 0x03902b36, + 0x03902b34, + 0x03902b33, + 0x03902b32, + 0x03902b30, + 0x03802b44, + 0x03802b42, + 0x03802b40, + 0x03802b3e, + 0x03802b3d, + 0x03802b3b, + 0x03802b39, + 0x03802b38, + 0x03802b36, + 0x03802b34, + 0x03802b33, + 0x03802b32, + 0x03802b30, + 0x03802b2f, + 0x03802b2d, + 0x03802b2c, + 0x03802b2b, + 0x03802b2a, + 0x03802b29, + 0x03802b27, + 0x03802b26, + 0x03802b25, + 0x03802b24, + 0x03802b23, + 0x03802b22, + 0x03802b21, + 0x03802b20, + 0x03802b1f, + 0x03802b1e, + 0x03802b1e, + 0x03802b1d, + 0x03802b1c, + 0x03802b1b, + 0x03802b1a, + 0x03802b1a, + 0x03802b19, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x00002b00, +}; + +const u32 gainctrl_lut_core1_rev0[] = { + 0x03cc2b44, + 0x03cc2b42, + 0x03cc2b40, + 0x03cc2b3e, + 0x03cc2b3d, + 0x03cc2b3b, + 0x03c82b44, + 0x03c82b42, + 0x03c82b40, + 0x03c82b3e, + 0x03c82b3d, + 0x03c82b3b, + 0x03c82b39, + 0x03c82b38, + 0x03c82b36, + 0x03c82b34, + 0x03c42b44, + 0x03c42b42, + 0x03c42b40, + 0x03c42b3e, + 0x03c42b3d, + 0x03c42b3b, + 0x03c42b39, + 0x03c42b38, + 0x03c42b36, + 0x03c42b34, + 0x03c42b33, + 0x03c42b32, + 0x03c42b30, + 0x03c42b2f, + 0x03c42b2d, + 0x03c02b44, + 0x03c02b42, + 0x03c02b40, + 0x03c02b3e, + 0x03c02b3d, + 0x03c02b3b, + 0x03c02b39, + 0x03c02b38, + 0x03c02b36, + 0x03c02b34, + 0x03b02b44, + 0x03b02b42, + 0x03b02b40, + 0x03b02b3e, + 0x03b02b3d, + 0x03b02b3b, + 0x03b02b39, + 0x03b02b38, + 0x03b02b36, + 0x03b02b34, + 0x03b02b33, + 0x03b02b32, + 0x03b02b30, + 0x03b02b2f, + 0x03b02b2d, + 0x03a02b44, + 0x03a02b42, + 0x03a02b40, + 0x03a02b3e, + 0x03a02b3d, + 0x03a02b3b, + 0x03a02b39, + 0x03a02b38, + 0x03a02b36, + 0x03a02b34, + 0x03902b44, + 0x03902b42, + 0x03902b40, + 0x03902b3e, + 0x03902b3d, + 0x03902b3b, + 0x03902b39, + 0x03902b38, + 0x03902b36, + 0x03902b34, + 0x03902b33, + 0x03902b32, + 0x03902b30, + 0x03802b44, + 0x03802b42, + 0x03802b40, + 0x03802b3e, + 0x03802b3d, + 0x03802b3b, + 0x03802b39, + 0x03802b38, + 0x03802b36, + 0x03802b34, + 0x03802b33, + 0x03802b32, + 0x03802b30, + 0x03802b2f, + 0x03802b2d, + 0x03802b2c, + 0x03802b2b, + 0x03802b2a, + 0x03802b29, + 0x03802b27, + 0x03802b26, + 0x03802b25, + 0x03802b24, + 0x03802b23, + 0x03802b22, + 0x03802b21, + 0x03802b20, + 0x03802b1f, + 0x03802b1e, + 0x03802b1e, + 0x03802b1d, + 0x03802b1c, + 0x03802b1b, + 0x03802b1a, + 0x03802b1a, + 0x03802b19, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x03802b18, + 0x00002b00, +}; + +const u32 iq_lut_core0_rev0[] = { + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, +}; + +const u32 iq_lut_core1_rev0[] = { + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, + 0x0000007f, +}; + +const u16 loft_lut_core0_rev0[] = { + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, +}; + +const u16 loft_lut_core1_rev0[] = { + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, + 0x0000, + 0x0101, + 0x0002, + 0x0103, +}; + +const mimophytbl_info_t mimophytbl_info_rev0_volatile[] = { + {&bdi_tbl_rev0, sizeof(bdi_tbl_rev0) / sizeof(bdi_tbl_rev0[0]), 21, 0, + 16} + , + {&pltlut_tbl_rev0, sizeof(pltlut_tbl_rev0) / sizeof(pltlut_tbl_rev0[0]), + 20, 0, 32} + , + {&gainctrl_lut_core0_rev0, + sizeof(gainctrl_lut_core0_rev0) / sizeof(gainctrl_lut_core0_rev0[0]), + 26, 192, 32} + , + {&gainctrl_lut_core1_rev0, + sizeof(gainctrl_lut_core1_rev0) / sizeof(gainctrl_lut_core1_rev0[0]), + 27, 192, 32} + , + + {&est_pwr_lut_core0_rev0, + sizeof(est_pwr_lut_core0_rev0) / sizeof(est_pwr_lut_core0_rev0[0]), 26, + 0, 8} + , + {&est_pwr_lut_core1_rev0, + sizeof(est_pwr_lut_core1_rev0) / sizeof(est_pwr_lut_core1_rev0[0]), 27, + 0, 8} + , + {&adj_pwr_lut_core0_rev0, + sizeof(adj_pwr_lut_core0_rev0) / sizeof(adj_pwr_lut_core0_rev0[0]), 26, + 64, 8} + , + {&adj_pwr_lut_core1_rev0, + sizeof(adj_pwr_lut_core1_rev0) / sizeof(adj_pwr_lut_core1_rev0[0]), 27, + 64, 8} + , + {&iq_lut_core0_rev0, + sizeof(iq_lut_core0_rev0) / sizeof(iq_lut_core0_rev0[0]), 26, 320, 32} + , + {&iq_lut_core1_rev0, + sizeof(iq_lut_core1_rev0) / sizeof(iq_lut_core1_rev0[0]), 27, 320, 32} + , + {&loft_lut_core0_rev0, + sizeof(loft_lut_core0_rev0) / sizeof(loft_lut_core0_rev0[0]), 26, 448, + 16} + , + {&loft_lut_core1_rev0, + sizeof(loft_lut_core1_rev0) / sizeof(loft_lut_core1_rev0[0]), 27, 448, + 16} + , +}; + +const mimophytbl_info_t mimophytbl_info_rev0[] = { + {&frame_struct_rev0, + sizeof(frame_struct_rev0) / sizeof(frame_struct_rev0[0]), 10, 0, 32} + , + {&frame_lut_rev0, sizeof(frame_lut_rev0) / sizeof(frame_lut_rev0[0]), + 24, 0, 8} + , + {&tmap_tbl_rev0, sizeof(tmap_tbl_rev0) / sizeof(tmap_tbl_rev0[0]), 12, + 0, 32} + , + {&tdtrn_tbl_rev0, sizeof(tdtrn_tbl_rev0) / sizeof(tdtrn_tbl_rev0[0]), + 14, 0, 32} + , + {&intlv_tbl_rev0, sizeof(intlv_tbl_rev0) / sizeof(intlv_tbl_rev0[0]), + 13, 0, 32} + , + {&pilot_tbl_rev0, sizeof(pilot_tbl_rev0) / sizeof(pilot_tbl_rev0[0]), + 11, 0, 16} + , + {&tdi_tbl20_ant0_rev0, + sizeof(tdi_tbl20_ant0_rev0) / sizeof(tdi_tbl20_ant0_rev0[0]), 19, 128, + 32} + , + {&tdi_tbl20_ant1_rev0, + sizeof(tdi_tbl20_ant1_rev0) / sizeof(tdi_tbl20_ant1_rev0[0]), 19, 256, + 32} + , + {&tdi_tbl40_ant0_rev0, + sizeof(tdi_tbl40_ant0_rev0) / sizeof(tdi_tbl40_ant0_rev0[0]), 19, 640, + 32} + , + {&tdi_tbl40_ant1_rev0, + sizeof(tdi_tbl40_ant1_rev0) / sizeof(tdi_tbl40_ant1_rev0[0]), 19, 768, + 32} + , + {&chanest_tbl_rev0, + sizeof(chanest_tbl_rev0) / sizeof(chanest_tbl_rev0[0]), 22, 0, 32} + , + {&mcs_tbl_rev0, sizeof(mcs_tbl_rev0) / sizeof(mcs_tbl_rev0[0]), 18, 0, 8} + , + {&noise_var_tbl0_rev0, + sizeof(noise_var_tbl0_rev0) / sizeof(noise_var_tbl0_rev0[0]), 16, 0, + 32} + , + {&noise_var_tbl1_rev0, + sizeof(noise_var_tbl1_rev0) / sizeof(noise_var_tbl1_rev0[0]), 16, 128, + 32} + , +}; + +const u32 mimophytbl_info_sz_rev0 = + sizeof(mimophytbl_info_rev0) / sizeof(mimophytbl_info_rev0[0]); +const u32 mimophytbl_info_sz_rev0_volatile = + sizeof(mimophytbl_info_rev0_volatile) / + sizeof(mimophytbl_info_rev0_volatile[0]); + +const u16 ant_swctrl_tbl_rev3[] = { + 0x0082, + 0x0082, + 0x0211, + 0x0222, + 0x0328, + 0x0000, + 0x0000, + 0x0000, + 0x0144, + 0x0000, + 0x0000, + 0x0000, + 0x0188, + 0x0000, + 0x0000, + 0x0000, + 0x0082, + 0x0082, + 0x0211, + 0x0222, + 0x0328, + 0x0000, + 0x0000, + 0x0000, + 0x0144, + 0x0000, + 0x0000, + 0x0000, + 0x0188, + 0x0000, + 0x0000, + 0x0000, +}; + +const u16 ant_swctrl_tbl_rev3_1[] = { + 0x0022, + 0x0022, + 0x0011, + 0x0022, + 0x0022, + 0x0000, + 0x0000, + 0x0000, + 0x0011, + 0x0000, + 0x0000, + 0x0000, + 0x0022, + 0x0000, + 0x0000, + 0x0000, + 0x0022, + 0x0022, + 0x0011, + 0x0022, + 0x0022, + 0x0000, + 0x0000, + 0x0000, + 0x0011, + 0x0000, + 0x0000, + 0x0000, + 0x0022, + 0x0000, + 0x0000, + 0x0000, +}; + +const u16 ant_swctrl_tbl_rev3_2[] = { + 0x0088, + 0x0088, + 0x0044, + 0x0088, + 0x0088, + 0x0000, + 0x0000, + 0x0000, + 0x0044, + 0x0000, + 0x0000, + 0x0000, + 0x0088, + 0x0000, + 0x0000, + 0x0000, + 0x0088, + 0x0088, + 0x0044, + 0x0088, + 0x0088, + 0x0000, + 0x0000, + 0x0000, + 0x0044, + 0x0000, + 0x0000, + 0x0000, + 0x0088, + 0x0000, + 0x0000, + 0x0000, +}; + +const u16 ant_swctrl_tbl_rev3_3[] = { + 0x022, + 0x022, + 0x011, + 0x022, + 0x000, + 0x000, + 0x000, + 0x000, + 0x011, + 0x000, + 0x000, + 0x000, + 0x022, + 0x000, + 0x000, + 0x3cc, + 0x022, + 0x022, + 0x011, + 0x022, + 0x000, + 0x000, + 0x000, + 0x000, + 0x011, + 0x000, + 0x000, + 0x000, + 0x022, + 0x000, + 0x000, + 0x3cc +}; + +const u32 frame_struct_rev3[] = { + 0x08004a04, + 0x00100000, + 0x01000a05, + 0x00100020, + 0x09804506, + 0x00100030, + 0x09804507, + 0x00100030, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x08004a0c, + 0x00100004, + 0x01000a0d, + 0x00100024, + 0x0980450e, + 0x00100034, + 0x0980450f, + 0x00100034, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000a04, + 0x00100000, + 0x11008a05, + 0x00100020, + 0x1980c506, + 0x00100030, + 0x21810506, + 0x00100030, + 0x21810506, + 0x00100030, + 0x01800504, + 0x00100030, + 0x11808505, + 0x00100030, + 0x29814507, + 0x01100030, + 0x00000a04, + 0x00100000, + 0x11008a05, + 0x00100020, + 0x21810506, + 0x00100030, + 0x21810506, + 0x00100030, + 0x29814507, + 0x01100030, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000a0c, + 0x00100008, + 0x11008a0d, + 0x00100028, + 0x1980c50e, + 0x00100038, + 0x2181050e, + 0x00100038, + 0x2181050e, + 0x00100038, + 0x0180050c, + 0x00100038, + 0x1180850d, + 0x00100038, + 0x2981450f, + 0x01100038, + 0x00000a0c, + 0x00100008, + 0x11008a0d, + 0x00100028, + 0x2181050e, + 0x00100038, + 0x2181050e, + 0x00100038, + 0x2981450f, + 0x01100038, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x08004a04, + 0x00100000, + 0x01000a05, + 0x00100020, + 0x1980c506, + 0x00100030, + 0x1980c506, + 0x00100030, + 0x11808504, + 0x00100030, + 0x3981ca05, + 0x00100030, + 0x29814507, + 0x01100030, + 0x00000000, + 0x00000000, + 0x10008a04, + 0x00100000, + 0x3981ca05, + 0x00100030, + 0x1980c506, + 0x00100030, + 0x29814507, + 0x01100030, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x08004a0c, + 0x00100008, + 0x01000a0d, + 0x00100028, + 0x1980c50e, + 0x00100038, + 0x1980c50e, + 0x00100038, + 0x1180850c, + 0x00100038, + 0x3981ca0d, + 0x00100038, + 0x2981450f, + 0x01100038, + 0x00000000, + 0x00000000, + 0x10008a0c, + 0x00100008, + 0x3981ca0d, + 0x00100038, + 0x1980c50e, + 0x00100038, + 0x2981450f, + 0x01100038, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x40021404, + 0x00100000, + 0x02001405, + 0x00100040, + 0x0b004a06, + 0x01900060, + 0x13008a06, + 0x01900060, + 0x13008a06, + 0x01900060, + 0x43020a04, + 0x00100060, + 0x1b00ca05, + 0x00100060, + 0x23010a07, + 0x01500060, + 0x40021404, + 0x00100000, + 0x1a00d405, + 0x00100040, + 0x13008a06, + 0x01900060, + 0x13008a06, + 0x01900060, + 0x23010a07, + 0x01500060, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x4002140c, + 0x00100010, + 0x0200140d, + 0x00100050, + 0x0b004a0e, + 0x01900070, + 0x13008a0e, + 0x01900070, + 0x13008a0e, + 0x01900070, + 0x43020a0c, + 0x00100070, + 0x1b00ca0d, + 0x00100070, + 0x23010a0f, + 0x01500070, + 0x4002140c, + 0x00100010, + 0x1a00d40d, + 0x00100050, + 0x13008a0e, + 0x01900070, + 0x13008a0e, + 0x01900070, + 0x23010a0f, + 0x01500070, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x50029404, + 0x00100000, + 0x32019405, + 0x00100040, + 0x0b004a06, + 0x01900060, + 0x0b004a06, + 0x01900060, + 0x5b02ca04, + 0x00100060, + 0x3b01d405, + 0x00100060, + 0x23010a07, + 0x01500060, + 0x00000000, + 0x00000000, + 0x5802d404, + 0x00100000, + 0x3b01d405, + 0x00100060, + 0x0b004a06, + 0x01900060, + 0x23010a07, + 0x01500060, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x5002940c, + 0x00100010, + 0x3201940d, + 0x00100050, + 0x0b004a0e, + 0x01900070, + 0x0b004a0e, + 0x01900070, + 0x5b02ca0c, + 0x00100070, + 0x3b01d40d, + 0x00100070, + 0x23010a0f, + 0x01500070, + 0x00000000, + 0x00000000, + 0x5802d40c, + 0x00100010, + 0x3b01d40d, + 0x00100070, + 0x0b004a0e, + 0x01900070, + 0x23010a0f, + 0x01500070, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x40021404, + 0x000f4800, + 0x62031405, + 0x00100040, + 0x53028a06, + 0x01900060, + 0x53028a07, + 0x01900060, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x4002140c, + 0x000f4808, + 0x6203140d, + 0x00100048, + 0x53028a0e, + 0x01900068, + 0x53028a0f, + 0x01900068, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000a0c, + 0x00100004, + 0x11008a0d, + 0x00100024, + 0x1980c50e, + 0x00100034, + 0x2181050e, + 0x00100034, + 0x2181050e, + 0x00100034, + 0x0180050c, + 0x00100038, + 0x1180850d, + 0x00100038, + 0x1181850d, + 0x00100038, + 0x2981450f, + 0x01100038, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000a0c, + 0x00100008, + 0x11008a0d, + 0x00100028, + 0x2181050e, + 0x00100038, + 0x2181050e, + 0x00100038, + 0x1181850d, + 0x00100038, + 0x2981450f, + 0x01100038, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x08004a04, + 0x00100000, + 0x01000a05, + 0x00100020, + 0x0180c506, + 0x00100030, + 0x0180c506, + 0x00100030, + 0x2180c50c, + 0x00100030, + 0x49820a0d, + 0x0016a130, + 0x41824a0d, + 0x0016a130, + 0x2981450f, + 0x01100030, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x2000ca0c, + 0x00100000, + 0x49820a0d, + 0x0016a130, + 0x1980c50e, + 0x00100030, + 0x41824a0d, + 0x0016a130, + 0x2981450f, + 0x01100030, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x4002140c, + 0x00100008, + 0x0200140d, + 0x00100048, + 0x0b004a0e, + 0x01900068, + 0x13008a0e, + 0x01900068, + 0x13008a0e, + 0x01900068, + 0x43020a0c, + 0x00100070, + 0x1b00ca0d, + 0x00100070, + 0x1b014a0d, + 0x00100070, + 0x23010a0f, + 0x01500070, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x4002140c, + 0x00100010, + 0x1a00d40d, + 0x00100050, + 0x13008a0e, + 0x01900070, + 0x13008a0e, + 0x01900070, + 0x1b014a0d, + 0x00100070, + 0x23010a0f, + 0x01500070, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x50029404, + 0x00100000, + 0x32019405, + 0x00100040, + 0x03004a06, + 0x01900060, + 0x03004a06, + 0x01900060, + 0x6b030a0c, + 0x00100060, + 0x4b02140d, + 0x0016a160, + 0x4302540d, + 0x0016a160, + 0x23010a0f, + 0x01500060, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x6b03140c, + 0x00100060, + 0x4b02140d, + 0x0016a160, + 0x0b004a0e, + 0x01900060, + 0x4302540d, + 0x0016a160, + 0x23010a0f, + 0x01500060, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x40021404, + 0x00100000, + 0x1a00d405, + 0x00100040, + 0x53028a06, + 0x01900060, + 0x5b02ca06, + 0x01900060, + 0x5b02ca06, + 0x01900060, + 0x43020a04, + 0x00100060, + 0x1b00ca05, + 0x00100060, + 0x53028a07, + 0x0190c060, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x4002140c, + 0x00100010, + 0x1a00d40d, + 0x00100050, + 0x53028a0e, + 0x01900070, + 0x5b02ca0e, + 0x01900070, + 0x5b02ca0e, + 0x01900070, + 0x43020a0c, + 0x00100070, + 0x1b00ca0d, + 0x00100070, + 0x53028a0f, + 0x0190c070, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x40021404, + 0x00100000, + 0x1a00d405, + 0x00100040, + 0x5b02ca06, + 0x01900060, + 0x5b02ca06, + 0x01900060, + 0x53028a07, + 0x0190c060, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x4002140c, + 0x00100010, + 0x1a00d40d, + 0x00100050, + 0x5b02ca0e, + 0x01900070, + 0x5b02ca0e, + 0x01900070, + 0x53028a0f, + 0x0190c070, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; + +const u16 pilot_tbl_rev3[] = { + 0xff08, + 0xff08, + 0xff08, + 0xff08, + 0xff08, + 0xff08, + 0xff08, + 0xff08, + 0x80d5, + 0x80d5, + 0x80d5, + 0x80d5, + 0x80d5, + 0x80d5, + 0x80d5, + 0x80d5, + 0xff0a, + 0xff82, + 0xffa0, + 0xff28, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xff82, + 0xffa0, + 0xff28, + 0xff0a, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xf83f, + 0xfa1f, + 0xfa97, + 0xfab5, + 0xf2bd, + 0xf0bf, + 0xffff, + 0xffff, + 0xf017, + 0xf815, + 0xf215, + 0xf095, + 0xf035, + 0xf01d, + 0xffff, + 0xffff, + 0xff08, + 0xff02, + 0xff80, + 0xff20, + 0xff08, + 0xff02, + 0xff80, + 0xff20, + 0xf01f, + 0xf817, + 0xfa15, + 0xf295, + 0xf0b5, + 0xf03d, + 0xffff, + 0xffff, + 0xf82a, + 0xfa0a, + 0xfa82, + 0xfaa0, + 0xf2a8, + 0xf0aa, + 0xffff, + 0xffff, + 0xf002, + 0xf800, + 0xf200, + 0xf080, + 0xf020, + 0xf008, + 0xffff, + 0xffff, + 0xf00a, + 0xf802, + 0xfa00, + 0xf280, + 0xf0a0, + 0xf028, + 0xffff, + 0xffff, +}; + +const u32 tmap_tbl_rev3[] = { + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0xf1111110, + 0x11111111, + 0x11f11111, + 0x00000111, + 0x11000000, + 0x1111f111, + 0x11111111, + 0x111111f1, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x000aa888, + 0x88880000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0xa1111110, + 0x11111111, + 0x11c11111, + 0x00000111, + 0x11000000, + 0x1111a111, + 0x11111111, + 0x111111a1, + 0xa2222220, + 0x22222222, + 0x22c22222, + 0x00000222, + 0x22000000, + 0x2222a222, + 0x22222222, + 0x222222a2, + 0xf1111110, + 0x11111111, + 0x11f11111, + 0x00011111, + 0x11110000, + 0x1111f111, + 0x11111111, + 0x111111f1, + 0xa8aa88a0, + 0xa88888a8, + 0xa8a8a88a, + 0x00088aaa, + 0xaaaa0000, + 0xa8a8aa88, + 0xa88aaaaa, + 0xaaaa8a8a, + 0xaaa8aaa0, + 0x8aaa8aaa, + 0xaa8a8a8a, + 0x000aaa88, + 0x8aaa0000, + 0xaaa8a888, + 0x8aa88a8a, + 0x8a88a888, + 0x08080a00, + 0x0a08080a, + 0x080a0a08, + 0x00080808, + 0x080a0000, + 0x080a0808, + 0x080a0808, + 0x0a0a0a08, + 0xa0a0a0a0, + 0x80a0a080, + 0x8080a0a0, + 0x00008080, + 0x80a00000, + 0x80a080a0, + 0xa080a0a0, + 0x8080a0a0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x99999000, + 0x9b9b99bb, + 0x9bb99999, + 0x9999b9b9, + 0x9b99bb90, + 0x9bbbbb9b, + 0x9b9b9bb9, + 0x00000999, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00aaa888, + 0x22000000, + 0x2222b222, + 0x22222222, + 0x222222b2, + 0xb2222220, + 0x22222222, + 0x22d22222, + 0x00000222, + 0x11000000, + 0x1111a111, + 0x11111111, + 0x111111a1, + 0xa1111110, + 0x11111111, + 0x11c11111, + 0x00000111, + 0x33000000, + 0x3333b333, + 0x33333333, + 0x333333b3, + 0xb3333330, + 0x33333333, + 0x33d33333, + 0x00000333, + 0x22000000, + 0x2222a222, + 0x22222222, + 0x222222a2, + 0xa2222220, + 0x22222222, + 0x22c22222, + 0x00000222, + 0x99b99b00, + 0x9b9b99bb, + 0x9bb99999, + 0x9999b9b9, + 0x9b99bb99, + 0x9bbbbb9b, + 0x9b9b9bb9, + 0x00000999, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa88, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x08aaa888, + 0x22222200, + 0x2222f222, + 0x22222222, + 0x222222f2, + 0x22222222, + 0x22222222, + 0x22f22222, + 0x00000222, + 0x11000000, + 0x1111f111, + 0x11111111, + 0x11111111, + 0xf1111111, + 0x11111111, + 0x11f11111, + 0x01111111, + 0xbb9bb900, + 0xb9b9bb99, + 0xb99bbbbb, + 0xbbbb9b9b, + 0xb9bb99bb, + 0xb99999b9, + 0xb9b9b99b, + 0x00000bbb, + 0xaa000000, + 0xa8a8aa88, + 0xa88aaaaa, + 0xaaaa8a8a, + 0xa8aa88aa, + 0xa88888a8, + 0xa8a8a88a, + 0x0a888aaa, + 0xaa000000, + 0xa8a8aa88, + 0xa88aaaaa, + 0xaaaa8a8a, + 0xa8aa88a0, + 0xa88888a8, + 0xa8a8a88a, + 0x00000aaa, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0xbbbbbb00, + 0x999bbbbb, + 0x9bb99b9b, + 0xb9b9b9bb, + 0xb9b99bbb, + 0xb9b9b9bb, + 0xb9bb9b99, + 0x00000999, + 0x8a000000, + 0xaa88a888, + 0xa88888aa, + 0xa88a8a88, + 0xa88aa88a, + 0x88a8aaaa, + 0xa8aa8aaa, + 0x0888a88a, + 0x0b0b0b00, + 0x090b0b0b, + 0x0b090b0b, + 0x0909090b, + 0x09090b0b, + 0x09090b0b, + 0x09090b09, + 0x00000909, + 0x0a000000, + 0x0a080808, + 0x080a080a, + 0x080a0a08, + 0x080a080a, + 0x0808080a, + 0x0a0a0a08, + 0x0808080a, + 0xb0b0b000, + 0x9090b0b0, + 0x90b09090, + 0xb0b0b090, + 0xb0b090b0, + 0x90b0b0b0, + 0xb0b09090, + 0x00000090, + 0x80000000, + 0xa080a080, + 0xa08080a0, + 0xa0808080, + 0xa080a080, + 0x80a0a0a0, + 0xa0a080a0, + 0x00a0a0a0, + 0x22000000, + 0x2222f222, + 0x22222222, + 0x222222f2, + 0xf2222220, + 0x22222222, + 0x22f22222, + 0x00000222, + 0x11000000, + 0x1111f111, + 0x11111111, + 0x111111f1, + 0xf1111110, + 0x11111111, + 0x11f11111, + 0x00000111, + 0x33000000, + 0x3333f333, + 0x33333333, + 0x333333f3, + 0xf3333330, + 0x33333333, + 0x33f33333, + 0x00000333, + 0x22000000, + 0x2222f222, + 0x22222222, + 0x222222f2, + 0xf2222220, + 0x22222222, + 0x22f22222, + 0x00000222, + 0x99000000, + 0x9b9b99bb, + 0x9bb99999, + 0x9999b9b9, + 0x9b99bb90, + 0x9bbbbb9b, + 0x9b9b9bb9, + 0x00000999, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0x88888000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00aaa888, + 0x88a88a00, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa88, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa88, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x08aaa888, + 0x11000000, + 0x1111a111, + 0x11111111, + 0x111111a1, + 0xa1111110, + 0x11111111, + 0x11c11111, + 0x00000111, + 0x11000000, + 0x1111a111, + 0x11111111, + 0x111111a1, + 0xa1111110, + 0x11111111, + 0x11c11111, + 0x00000111, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; + +const u32 intlv_tbl_rev3[] = { + 0x00802070, + 0x0671188d, + 0x0a60192c, + 0x0a300e46, + 0x00c1188d, + 0x080024d2, + 0x00000070, +}; + +const u32 tdtrn_tbl_rev3[] = { + 0x061c061c, + 0x0050ee68, + 0xf592fe36, + 0xfe5212f6, + 0x00000c38, + 0xfe5212f6, + 0xf592fe36, + 0x0050ee68, + 0x061c061c, + 0xee680050, + 0xfe36f592, + 0x12f6fe52, + 0x0c380000, + 0x12f6fe52, + 0xfe36f592, + 0xee680050, + 0x061c061c, + 0x0050ee68, + 0xf592fe36, + 0xfe5212f6, + 0x00000c38, + 0xfe5212f6, + 0xf592fe36, + 0x0050ee68, + 0x061c061c, + 0xee680050, + 0xfe36f592, + 0x12f6fe52, + 0x0c380000, + 0x12f6fe52, + 0xfe36f592, + 0xee680050, + 0x05e305e3, + 0x004def0c, + 0xf5f3fe47, + 0xfe611246, + 0x00000bc7, + 0xfe611246, + 0xf5f3fe47, + 0x004def0c, + 0x05e305e3, + 0xef0c004d, + 0xfe47f5f3, + 0x1246fe61, + 0x0bc70000, + 0x1246fe61, + 0xfe47f5f3, + 0xef0c004d, + 0x05e305e3, + 0x004def0c, + 0xf5f3fe47, + 0xfe611246, + 0x00000bc7, + 0xfe611246, + 0xf5f3fe47, + 0x004def0c, + 0x05e305e3, + 0xef0c004d, + 0xfe47f5f3, + 0x1246fe61, + 0x0bc70000, + 0x1246fe61, + 0xfe47f5f3, + 0xef0c004d, + 0xfa58fa58, + 0xf895043b, + 0xff4c09c0, + 0xfbc6ffa8, + 0xfb84f384, + 0x0798f6f9, + 0x05760122, + 0x058409f6, + 0x0b500000, + 0x05b7f542, + 0x08860432, + 0x06ddfee7, + 0xfb84f384, + 0xf9d90664, + 0xf7e8025c, + 0x00fff7bd, + 0x05a805a8, + 0xf7bd00ff, + 0x025cf7e8, + 0x0664f9d9, + 0xf384fb84, + 0xfee706dd, + 0x04320886, + 0xf54205b7, + 0x00000b50, + 0x09f60584, + 0x01220576, + 0xf6f90798, + 0xf384fb84, + 0xffa8fbc6, + 0x09c0ff4c, + 0x043bf895, + 0x02d402d4, + 0x07de0270, + 0xfc96079c, + 0xf90afe94, + 0xfe00ff2c, + 0x02d4065d, + 0x092a0096, + 0x0014fbb8, + 0xfd2cfd2c, + 0x076afb3c, + 0x0096f752, + 0xf991fd87, + 0xfb2c0200, + 0xfeb8f960, + 0x08e0fc96, + 0x049802a8, + 0xfd2cfd2c, + 0x02a80498, + 0xfc9608e0, + 0xf960feb8, + 0x0200fb2c, + 0xfd87f991, + 0xf7520096, + 0xfb3c076a, + 0xfd2cfd2c, + 0xfbb80014, + 0x0096092a, + 0x065d02d4, + 0xff2cfe00, + 0xfe94f90a, + 0x079cfc96, + 0x027007de, + 0x02d402d4, + 0x027007de, + 0x079cfc96, + 0xfe94f90a, + 0xff2cfe00, + 0x065d02d4, + 0x0096092a, + 0xfbb80014, + 0xfd2cfd2c, + 0xfb3c076a, + 0xf7520096, + 0xfd87f991, + 0x0200fb2c, + 0xf960feb8, + 0xfc9608e0, + 0x02a80498, + 0xfd2cfd2c, + 0x049802a8, + 0x08e0fc96, + 0xfeb8f960, + 0xfb2c0200, + 0xf991fd87, + 0x0096f752, + 0x076afb3c, + 0xfd2cfd2c, + 0x0014fbb8, + 0x092a0096, + 0x02d4065d, + 0xfe00ff2c, + 0xf90afe94, + 0xfc96079c, + 0x07de0270, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x062a0000, + 0xfefa0759, + 0x08b80908, + 0xf396fc2d, + 0xf9d6045c, + 0xfc4ef608, + 0xf748f596, + 0x07b207bf, + 0x062a062a, + 0xf84ef841, + 0xf748f596, + 0x03b209f8, + 0xf9d6045c, + 0x0c6a03d3, + 0x08b80908, + 0x0106f8a7, + 0x062a0000, + 0xfefaf8a7, + 0x08b8f6f8, + 0xf39603d3, + 0xf9d6fba4, + 0xfc4e09f8, + 0xf7480a6a, + 0x07b2f841, + 0x062af9d6, + 0xf84e07bf, + 0xf7480a6a, + 0x03b2f608, + 0xf9d6fba4, + 0x0c6afc2d, + 0x08b8f6f8, + 0x01060759, + 0x062a0000, + 0xfefa0759, + 0x08b80908, + 0xf396fc2d, + 0xf9d6045c, + 0xfc4ef608, + 0xf748f596, + 0x07b207bf, + 0x062a062a, + 0xf84ef841, + 0xf748f596, + 0x03b209f8, + 0xf9d6045c, + 0x0c6a03d3, + 0x08b80908, + 0x0106f8a7, + 0x062a0000, + 0xfefaf8a7, + 0x08b8f6f8, + 0xf39603d3, + 0xf9d6fba4, + 0xfc4e09f8, + 0xf7480a6a, + 0x07b2f841, + 0x062af9d6, + 0xf84e07bf, + 0xf7480a6a, + 0x03b2f608, + 0xf9d6fba4, + 0x0c6afc2d, + 0x08b8f6f8, + 0x01060759, + 0x061c061c, + 0xff30009d, + 0xffb21141, + 0xfd87fb54, + 0xf65dfe59, + 0x02eef99e, + 0x0166f03c, + 0xfff809b6, + 0x000008a4, + 0x000af42b, + 0x00eff577, + 0xfa840bf2, + 0xfc02ff51, + 0x08260f67, + 0xfff0036f, + 0x0842f9c3, + 0x00000000, + 0x063df7be, + 0xfc910010, + 0xf099f7da, + 0x00af03fe, + 0xf40e057c, + 0x0a89ff11, + 0x0bd5fff6, + 0xf75c0000, + 0xf64a0008, + 0x0fc4fe9a, + 0x0662fd12, + 0x01a709a3, + 0x04ac0279, + 0xeebf004e, + 0xff6300d0, + 0xf9e4f9e4, + 0x00d0ff63, + 0x004eeebf, + 0x027904ac, + 0x09a301a7, + 0xfd120662, + 0xfe9a0fc4, + 0x0008f64a, + 0x0000f75c, + 0xfff60bd5, + 0xff110a89, + 0x057cf40e, + 0x03fe00af, + 0xf7daf099, + 0x0010fc91, + 0xf7be063d, + 0x00000000, + 0xf9c30842, + 0x036ffff0, + 0x0f670826, + 0xff51fc02, + 0x0bf2fa84, + 0xf57700ef, + 0xf42b000a, + 0x08a40000, + 0x09b6fff8, + 0xf03c0166, + 0xf99e02ee, + 0xfe59f65d, + 0xfb54fd87, + 0x1141ffb2, + 0x009dff30, + 0x05e30000, + 0xff060705, + 0x085408a0, + 0xf425fc59, + 0xfa1d042a, + 0xfc78f67a, + 0xf7acf60e, + 0x075a0766, + 0x05e305e3, + 0xf8a6f89a, + 0xf7acf60e, + 0x03880986, + 0xfa1d042a, + 0x0bdb03a7, + 0x085408a0, + 0x00faf8fb, + 0x05e30000, + 0xff06f8fb, + 0x0854f760, + 0xf42503a7, + 0xfa1dfbd6, + 0xfc780986, + 0xf7ac09f2, + 0x075af89a, + 0x05e3fa1d, + 0xf8a60766, + 0xf7ac09f2, + 0x0388f67a, + 0xfa1dfbd6, + 0x0bdbfc59, + 0x0854f760, + 0x00fa0705, + 0x05e30000, + 0xff060705, + 0x085408a0, + 0xf425fc59, + 0xfa1d042a, + 0xfc78f67a, + 0xf7acf60e, + 0x075a0766, + 0x05e305e3, + 0xf8a6f89a, + 0xf7acf60e, + 0x03880986, + 0xfa1d042a, + 0x0bdb03a7, + 0x085408a0, + 0x00faf8fb, + 0x05e30000, + 0xff06f8fb, + 0x0854f760, + 0xf42503a7, + 0xfa1dfbd6, + 0xfc780986, + 0xf7ac09f2, + 0x075af89a, + 0x05e3fa1d, + 0xf8a60766, + 0xf7ac09f2, + 0x0388f67a, + 0xfa1dfbd6, + 0x0bdbfc59, + 0x0854f760, + 0x00fa0705, + 0xfa58fa58, + 0xf8f0fe00, + 0x0448073d, + 0xfdc9fe46, + 0xf9910258, + 0x089d0407, + 0xfd5cf71a, + 0x02affde0, + 0x083e0496, + 0xff5a0740, + 0xff7afd97, + 0x00fe01f1, + 0x0009082e, + 0xfa94ff75, + 0xfecdf8ea, + 0xffb0f693, + 0xfd2cfa58, + 0x0433ff16, + 0xfba405dd, + 0xfa610341, + 0x06a606cb, + 0x0039fd2d, + 0x0677fa97, + 0x01fa05e0, + 0xf896003e, + 0x075a068b, + 0x012cfc3e, + 0xfa23f98d, + 0xfc7cfd43, + 0xff90fc0d, + 0x01c10982, + 0x00c601d6, + 0xfd2cfd2c, + 0x01d600c6, + 0x098201c1, + 0xfc0dff90, + 0xfd43fc7c, + 0xf98dfa23, + 0xfc3e012c, + 0x068b075a, + 0x003ef896, + 0x05e001fa, + 0xfa970677, + 0xfd2d0039, + 0x06cb06a6, + 0x0341fa61, + 0x05ddfba4, + 0xff160433, + 0xfa58fd2c, + 0xf693ffb0, + 0xf8eafecd, + 0xff75fa94, + 0x082e0009, + 0x01f100fe, + 0xfd97ff7a, + 0x0740ff5a, + 0x0496083e, + 0xfde002af, + 0xf71afd5c, + 0x0407089d, + 0x0258f991, + 0xfe46fdc9, + 0x073d0448, + 0xfe00f8f0, + 0xfd2cfd2c, + 0xfce00500, + 0xfc09fddc, + 0xfe680157, + 0x04c70571, + 0xfc3aff21, + 0xfcd70228, + 0x056d0277, + 0x0200fe00, + 0x0022f927, + 0xfe3c032b, + 0xfc44ff3c, + 0x03e9fbdb, + 0x04570313, + 0x04c9ff5c, + 0x000d03b8, + 0xfa580000, + 0xfbe900d2, + 0xf9d0fe0b, + 0x0125fdf9, + 0x042501bf, + 0x0328fa2b, + 0xffa902f0, + 0xfa250157, + 0x0200fe00, + 0x03740438, + 0xff0405fd, + 0x030cfe52, + 0x0037fb39, + 0xff6904c5, + 0x04f8fd23, + 0xfd31fc1b, + 0xfd2cfd2c, + 0xfc1bfd31, + 0xfd2304f8, + 0x04c5ff69, + 0xfb390037, + 0xfe52030c, + 0x05fdff04, + 0x04380374, + 0xfe000200, + 0x0157fa25, + 0x02f0ffa9, + 0xfa2b0328, + 0x01bf0425, + 0xfdf90125, + 0xfe0bf9d0, + 0x00d2fbe9, + 0x0000fa58, + 0x03b8000d, + 0xff5c04c9, + 0x03130457, + 0xfbdb03e9, + 0xff3cfc44, + 0x032bfe3c, + 0xf9270022, + 0xfe000200, + 0x0277056d, + 0x0228fcd7, + 0xff21fc3a, + 0x057104c7, + 0x0157fe68, + 0xfddcfc09, + 0x0500fce0, + 0xfd2cfd2c, + 0x0500fce0, + 0xfddcfc09, + 0x0157fe68, + 0x057104c7, + 0xff21fc3a, + 0x0228fcd7, + 0x0277056d, + 0xfe000200, + 0xf9270022, + 0x032bfe3c, + 0xff3cfc44, + 0xfbdb03e9, + 0x03130457, + 0xff5c04c9, + 0x03b8000d, + 0x0000fa58, + 0x00d2fbe9, + 0xfe0bf9d0, + 0xfdf90125, + 0x01bf0425, + 0xfa2b0328, + 0x02f0ffa9, + 0x0157fa25, + 0xfe000200, + 0x04380374, + 0x05fdff04, + 0xfe52030c, + 0xfb390037, + 0x04c5ff69, + 0xfd2304f8, + 0xfc1bfd31, + 0xfd2cfd2c, + 0xfd31fc1b, + 0x04f8fd23, + 0xff6904c5, + 0x0037fb39, + 0x030cfe52, + 0xff0405fd, + 0x03740438, + 0x0200fe00, + 0xfa250157, + 0xffa902f0, + 0x0328fa2b, + 0x042501bf, + 0x0125fdf9, + 0xf9d0fe0b, + 0xfbe900d2, + 0xfa580000, + 0x000d03b8, + 0x04c9ff5c, + 0x04570313, + 0x03e9fbdb, + 0xfc44ff3c, + 0xfe3c032b, + 0x0022f927, + 0x0200fe00, + 0x056d0277, + 0xfcd70228, + 0xfc3aff21, + 0x04c70571, + 0xfe680157, + 0xfc09fddc, + 0xfce00500, + 0x05a80000, + 0xff1006be, + 0x0800084a, + 0xf49cfc7e, + 0xfa580400, + 0xfc9cf6da, + 0xf800f672, + 0x0710071c, + 0x05a805a8, + 0xf8f0f8e4, + 0xf800f672, + 0x03640926, + 0xfa580400, + 0x0b640382, + 0x0800084a, + 0x00f0f942, + 0x05a80000, + 0xff10f942, + 0x0800f7b6, + 0xf49c0382, + 0xfa58fc00, + 0xfc9c0926, + 0xf800098e, + 0x0710f8e4, + 0x05a8fa58, + 0xf8f0071c, + 0xf800098e, + 0x0364f6da, + 0xfa58fc00, + 0x0b64fc7e, + 0x0800f7b6, + 0x00f006be, + 0x05a80000, + 0xff1006be, + 0x0800084a, + 0xf49cfc7e, + 0xfa580400, + 0xfc9cf6da, + 0xf800f672, + 0x0710071c, + 0x05a805a8, + 0xf8f0f8e4, + 0xf800f672, + 0x03640926, + 0xfa580400, + 0x0b640382, + 0x0800084a, + 0x00f0f942, + 0x05a80000, + 0xff10f942, + 0x0800f7b6, + 0xf49c0382, + 0xfa58fc00, + 0xfc9c0926, + 0xf800098e, + 0x0710f8e4, + 0x05a8fa58, + 0xf8f0071c, + 0xf800098e, + 0x0364f6da, + 0xfa58fc00, + 0x0b64fc7e, + 0x0800f7b6, + 0x00f006be, +}; + +const u32 noise_var_tbl_rev3[] = { + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, + 0x02110211, + 0x0000014d, +}; + +const u16 mcs_tbl_rev3[] = { + 0x0000, + 0x0008, + 0x000a, + 0x0010, + 0x0012, + 0x0019, + 0x001a, + 0x001c, + 0x0080, + 0x0088, + 0x008a, + 0x0090, + 0x0092, + 0x0099, + 0x009a, + 0x009c, + 0x0100, + 0x0108, + 0x010a, + 0x0110, + 0x0112, + 0x0119, + 0x011a, + 0x011c, + 0x0180, + 0x0188, + 0x018a, + 0x0190, + 0x0192, + 0x0199, + 0x019a, + 0x019c, + 0x0000, + 0x0098, + 0x00a0, + 0x00a8, + 0x009a, + 0x00a2, + 0x00aa, + 0x0120, + 0x0128, + 0x0128, + 0x0130, + 0x0138, + 0x0138, + 0x0140, + 0x0122, + 0x012a, + 0x012a, + 0x0132, + 0x013a, + 0x013a, + 0x0142, + 0x01a8, + 0x01b0, + 0x01b8, + 0x01b0, + 0x01b8, + 0x01c0, + 0x01c8, + 0x01c0, + 0x01c8, + 0x01d0, + 0x01d0, + 0x01d8, + 0x01aa, + 0x01b2, + 0x01ba, + 0x01b2, + 0x01ba, + 0x01c2, + 0x01ca, + 0x01c2, + 0x01ca, + 0x01d2, + 0x01d2, + 0x01da, + 0x0001, + 0x0002, + 0x0004, + 0x0009, + 0x000c, + 0x0011, + 0x0014, + 0x0018, + 0x0020, + 0x0021, + 0x0022, + 0x0024, + 0x0081, + 0x0082, + 0x0084, + 0x0089, + 0x008c, + 0x0091, + 0x0094, + 0x0098, + 0x00a0, + 0x00a1, + 0x00a2, + 0x00a4, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, + 0x0007, +}; + +const u32 tdi_tbl20_ant0_rev3[] = { + 0x00091226, + 0x000a1429, + 0x000b56ad, + 0x000c58b0, + 0x000d5ab3, + 0x000e9cb6, + 0x000f9eba, + 0x0000c13d, + 0x00020301, + 0x00030504, + 0x00040708, + 0x0005090b, + 0x00064b8e, + 0x00095291, + 0x000a5494, + 0x000b9718, + 0x000c9927, + 0x000d9b2a, + 0x000edd2e, + 0x000fdf31, + 0x000101b4, + 0x000243b7, + 0x000345bb, + 0x000447be, + 0x00058982, + 0x00068c05, + 0x00099309, + 0x000a950c, + 0x000bd78f, + 0x000cd992, + 0x000ddb96, + 0x000f1d99, + 0x00005fa8, + 0x0001422c, + 0x0002842f, + 0x00038632, + 0x00048835, + 0x0005ca38, + 0x0006ccbc, + 0x0009d3bf, + 0x000b1603, + 0x000c1806, + 0x000d1a0a, + 0x000e1c0d, + 0x000f5e10, + 0x00008093, + 0x00018297, + 0x0002c49a, + 0x0003c680, + 0x0004c880, + 0x00060b00, + 0x00070d00, + 0x00000000, + 0x00000000, + 0x00000000, +}; + +const u32 tdi_tbl20_ant1_rev3[] = { + 0x00014b26, + 0x00028d29, + 0x000393ad, + 0x00049630, + 0x0005d833, + 0x0006da36, + 0x00099c3a, + 0x000a9e3d, + 0x000bc081, + 0x000cc284, + 0x000dc488, + 0x000f068b, + 0x0000488e, + 0x00018b91, + 0x0002d214, + 0x0003d418, + 0x0004d6a7, + 0x000618aa, + 0x00071aae, + 0x0009dcb1, + 0x000b1eb4, + 0x000c0137, + 0x000d033b, + 0x000e053e, + 0x000f4702, + 0x00008905, + 0x00020c09, + 0x0003128c, + 0x0004148f, + 0x00051712, + 0x00065916, + 0x00091b19, + 0x000a1d28, + 0x000b5f2c, + 0x000c41af, + 0x000d43b2, + 0x000e85b5, + 0x000f87b8, + 0x0000c9bc, + 0x00024cbf, + 0x00035303, + 0x00045506, + 0x0005978a, + 0x0006998d, + 0x00095b90, + 0x000a5d93, + 0x000b9f97, + 0x000c821a, + 0x000d8400, + 0x000ec600, + 0x000fc800, + 0x00010a00, + 0x00000000, + 0x00000000, + 0x00000000, +}; + +const u32 tdi_tbl40_ant0_rev3[] = { + 0x0011a346, + 0x00136ccf, + 0x0014f5d9, + 0x001641e2, + 0x0017cb6b, + 0x00195475, + 0x001b2383, + 0x001cad0c, + 0x001e7616, + 0x0000821f, + 0x00020ba8, + 0x0003d4b2, + 0x00056447, + 0x00072dd0, + 0x0008b6da, + 0x000a02e3, + 0x000b8c6c, + 0x000d15f6, + 0x0011e484, + 0x0013ae0d, + 0x00153717, + 0x00168320, + 0x00180ca9, + 0x00199633, + 0x001b6548, + 0x001ceed1, + 0x001eb7db, + 0x0000c3e4, + 0x00024d6d, + 0x000416f7, + 0x0005a585, + 0x00076f0f, + 0x0008f818, + 0x000a4421, + 0x000bcdab, + 0x000d9734, + 0x00122649, + 0x0013efd2, + 0x001578dc, + 0x0016c4e5, + 0x00184e6e, + 0x001a17f8, + 0x001ba686, + 0x001d3010, + 0x001ef999, + 0x00010522, + 0x00028eac, + 0x00045835, + 0x0005e74a, + 0x0007b0d3, + 0x00093a5d, + 0x000a85e6, + 0x000c0f6f, + 0x000dd8f9, + 0x00126787, + 0x00143111, + 0x0015ba9a, + 0x00170623, + 0x00188fad, + 0x001a5936, + 0x001be84b, + 0x001db1d4, + 0x001f3b5e, + 0x000146e7, + 0x00031070, + 0x000499fa, + 0x00062888, + 0x0007f212, + 0x00097b9b, + 0x000ac7a4, + 0x000c50ae, + 0x000e1a37, + 0x0012a94c, + 0x001472d5, + 0x0015fc5f, + 0x00174868, + 0x0018d171, + 0x001a9afb, + 0x001c2989, + 0x001df313, + 0x001f7c9c, + 0x000188a5, + 0x000351af, + 0x0004db38, + 0x0006aa4d, + 0x000833d7, + 0x0009bd60, + 0x000b0969, + 0x000c9273, + 0x000e5bfc, + 0x00132a8a, + 0x0014b414, + 0x00163d9d, + 0x001789a6, + 0x001912b0, + 0x001adc39, + 0x001c6bce, + 0x001e34d8, + 0x001fbe61, + 0x0001ca6a, + 0x00039374, + 0x00051cfd, + 0x0006ec0b, + 0x00087515, + 0x0009fe9e, + 0x000b4aa7, + 0x000cd3b1, + 0x000e9d3a, + 0x00000000, + 0x00000000, +}; + +const u32 tdi_tbl40_ant1_rev3[] = { + 0x001edb36, + 0x000129ca, + 0x0002b353, + 0x00047cdd, + 0x0005c8e6, + 0x000791ef, + 0x00091bf9, + 0x000aaa07, + 0x000c3391, + 0x000dfd1a, + 0x00120923, + 0x0013d22d, + 0x00155c37, + 0x0016eacb, + 0x00187454, + 0x001a3dde, + 0x001b89e7, + 0x001d12f0, + 0x001f1cfa, + 0x00016b88, + 0x00033492, + 0x0004be1b, + 0x00060a24, + 0x0007d32e, + 0x00095d38, + 0x000aec4c, + 0x000c7555, + 0x000e3edf, + 0x00124ae8, + 0x001413f1, + 0x0015a37b, + 0x00172c89, + 0x0018b593, + 0x001a419c, + 0x001bcb25, + 0x001d942f, + 0x001f63b9, + 0x0001ad4d, + 0x00037657, + 0x0004c260, + 0x00068be9, + 0x000814f3, + 0x0009a47c, + 0x000b2d8a, + 0x000cb694, + 0x000e429d, + 0x00128c26, + 0x001455b0, + 0x0015e4ba, + 0x00176e4e, + 0x0018f758, + 0x001a8361, + 0x001c0cea, + 0x001dd674, + 0x001fa57d, + 0x0001ee8b, + 0x0003b795, + 0x0005039e, + 0x0006cd27, + 0x000856b1, + 0x0009e5c6, + 0x000b6f4f, + 0x000cf859, + 0x000e8462, + 0x00130deb, + 0x00149775, + 0x00162603, + 0x0017af8c, + 0x00193896, + 0x001ac49f, + 0x001c4e28, + 0x001e17b2, + 0x0000a6c7, + 0x00023050, + 0x0003f9da, + 0x00054563, + 0x00070eec, + 0x00089876, + 0x000a2704, + 0x000bb08d, + 0x000d3a17, + 0x001185a0, + 0x00134f29, + 0x0014d8b3, + 0x001667c8, + 0x0017f151, + 0x00197adb, + 0x001b0664, + 0x001c8fed, + 0x001e5977, + 0x0000e805, + 0x0002718f, + 0x00043b18, + 0x000586a1, + 0x0007502b, + 0x0008d9b4, + 0x000a68c9, + 0x000bf252, + 0x000dbbdc, + 0x0011c7e5, + 0x001390ee, + 0x00151a78, + 0x0016a906, + 0x00183290, + 0x0019bc19, + 0x001b4822, + 0x001cd12c, + 0x001e9ab5, + 0x00000000, + 0x00000000, +}; + +const u32 pltlut_tbl_rev3[] = { + 0x76540213, + 0x62407351, + 0x76543210, + 0x76540213, + 0x76540213, + 0x76430521, +}; + +const u32 chanest_tbl_rev3[] = { + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x44444444, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, + 0x10101010, +}; + +const u8 frame_lut_rev3[] = { + 0x02, + 0x04, + 0x14, + 0x14, + 0x03, + 0x05, + 0x16, + 0x16, + 0x0a, + 0x0c, + 0x1c, + 0x1c, + 0x0b, + 0x0d, + 0x1e, + 0x1e, + 0x06, + 0x08, + 0x18, + 0x18, + 0x07, + 0x09, + 0x1a, + 0x1a, + 0x0e, + 0x10, + 0x20, + 0x28, + 0x0f, + 0x11, + 0x22, + 0x2a, +}; + +const u8 est_pwr_lut_core0_rev3[] = { + 0x55, + 0x54, + 0x54, + 0x53, + 0x52, + 0x52, + 0x51, + 0x51, + 0x50, + 0x4f, + 0x4f, + 0x4e, + 0x4e, + 0x4d, + 0x4c, + 0x4c, + 0x4b, + 0x4a, + 0x49, + 0x49, + 0x48, + 0x47, + 0x46, + 0x46, + 0x45, + 0x44, + 0x43, + 0x42, + 0x41, + 0x40, + 0x40, + 0x3f, + 0x3e, + 0x3d, + 0x3c, + 0x3a, + 0x39, + 0x38, + 0x37, + 0x36, + 0x35, + 0x33, + 0x32, + 0x31, + 0x2f, + 0x2e, + 0x2c, + 0x2b, + 0x29, + 0x27, + 0x25, + 0x23, + 0x21, + 0x1f, + 0x1d, + 0x1a, + 0x18, + 0x15, + 0x12, + 0x0e, + 0x0b, + 0x07, + 0x02, + 0xfd, +}; + +const u8 est_pwr_lut_core1_rev3[] = { + 0x55, + 0x54, + 0x54, + 0x53, + 0x52, + 0x52, + 0x51, + 0x51, + 0x50, + 0x4f, + 0x4f, + 0x4e, + 0x4e, + 0x4d, + 0x4c, + 0x4c, + 0x4b, + 0x4a, + 0x49, + 0x49, + 0x48, + 0x47, + 0x46, + 0x46, + 0x45, + 0x44, + 0x43, + 0x42, + 0x41, + 0x40, + 0x40, + 0x3f, + 0x3e, + 0x3d, + 0x3c, + 0x3a, + 0x39, + 0x38, + 0x37, + 0x36, + 0x35, + 0x33, + 0x32, + 0x31, + 0x2f, + 0x2e, + 0x2c, + 0x2b, + 0x29, + 0x27, + 0x25, + 0x23, + 0x21, + 0x1f, + 0x1d, + 0x1a, + 0x18, + 0x15, + 0x12, + 0x0e, + 0x0b, + 0x07, + 0x02, + 0xfd, +}; + +const u8 adj_pwr_lut_core0_rev3[] = { + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, +}; + +const u8 adj_pwr_lut_core1_rev3[] = { + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, +}; + +const u32 gainctrl_lut_core0_rev3[] = { + 0x5bf70044, + 0x5bf70042, + 0x5bf70040, + 0x5bf7003e, + 0x5bf7003c, + 0x5bf7003b, + 0x5bf70039, + 0x5bf70037, + 0x5bf70036, + 0x5bf70034, + 0x5bf70033, + 0x5bf70031, + 0x5bf70030, + 0x5ba70044, + 0x5ba70042, + 0x5ba70040, + 0x5ba7003e, + 0x5ba7003c, + 0x5ba7003b, + 0x5ba70039, + 0x5ba70037, + 0x5ba70036, + 0x5ba70034, + 0x5ba70033, + 0x5b770044, + 0x5b770042, + 0x5b770040, + 0x5b77003e, + 0x5b77003c, + 0x5b77003b, + 0x5b770039, + 0x5b770037, + 0x5b770036, + 0x5b770034, + 0x5b770033, + 0x5b770031, + 0x5b770030, + 0x5b77002f, + 0x5b77002d, + 0x5b77002c, + 0x5b470044, + 0x5b470042, + 0x5b470040, + 0x5b47003e, + 0x5b47003c, + 0x5b47003b, + 0x5b470039, + 0x5b470037, + 0x5b470036, + 0x5b470034, + 0x5b470033, + 0x5b470031, + 0x5b470030, + 0x5b47002f, + 0x5b47002d, + 0x5b47002c, + 0x5b47002b, + 0x5b47002a, + 0x5b270044, + 0x5b270042, + 0x5b270040, + 0x5b27003e, + 0x5b27003c, + 0x5b27003b, + 0x5b270039, + 0x5b270037, + 0x5b270036, + 0x5b270034, + 0x5b270033, + 0x5b270031, + 0x5b270030, + 0x5b27002f, + 0x5b170044, + 0x5b170042, + 0x5b170040, + 0x5b17003e, + 0x5b17003c, + 0x5b17003b, + 0x5b170039, + 0x5b170037, + 0x5b170036, + 0x5b170034, + 0x5b170033, + 0x5b170031, + 0x5b170030, + 0x5b17002f, + 0x5b17002d, + 0x5b17002c, + 0x5b17002b, + 0x5b17002a, + 0x5b170028, + 0x5b170027, + 0x5b170026, + 0x5b170025, + 0x5b170024, + 0x5b170023, + 0x5b070044, + 0x5b070042, + 0x5b070040, + 0x5b07003e, + 0x5b07003c, + 0x5b07003b, + 0x5b070039, + 0x5b070037, + 0x5b070036, + 0x5b070034, + 0x5b070033, + 0x5b070031, + 0x5b070030, + 0x5b07002f, + 0x5b07002d, + 0x5b07002c, + 0x5b07002b, + 0x5b07002a, + 0x5b070028, + 0x5b070027, + 0x5b070026, + 0x5b070025, + 0x5b070024, + 0x5b070023, + 0x5b070022, + 0x5b070021, + 0x5b070020, + 0x5b07001f, + 0x5b07001e, + 0x5b07001d, + 0x5b07001d, + 0x5b07001c, +}; + +const u32 gainctrl_lut_core1_rev3[] = { + 0x5bf70044, + 0x5bf70042, + 0x5bf70040, + 0x5bf7003e, + 0x5bf7003c, + 0x5bf7003b, + 0x5bf70039, + 0x5bf70037, + 0x5bf70036, + 0x5bf70034, + 0x5bf70033, + 0x5bf70031, + 0x5bf70030, + 0x5ba70044, + 0x5ba70042, + 0x5ba70040, + 0x5ba7003e, + 0x5ba7003c, + 0x5ba7003b, + 0x5ba70039, + 0x5ba70037, + 0x5ba70036, + 0x5ba70034, + 0x5ba70033, + 0x5b770044, + 0x5b770042, + 0x5b770040, + 0x5b77003e, + 0x5b77003c, + 0x5b77003b, + 0x5b770039, + 0x5b770037, + 0x5b770036, + 0x5b770034, + 0x5b770033, + 0x5b770031, + 0x5b770030, + 0x5b77002f, + 0x5b77002d, + 0x5b77002c, + 0x5b470044, + 0x5b470042, + 0x5b470040, + 0x5b47003e, + 0x5b47003c, + 0x5b47003b, + 0x5b470039, + 0x5b470037, + 0x5b470036, + 0x5b470034, + 0x5b470033, + 0x5b470031, + 0x5b470030, + 0x5b47002f, + 0x5b47002d, + 0x5b47002c, + 0x5b47002b, + 0x5b47002a, + 0x5b270044, + 0x5b270042, + 0x5b270040, + 0x5b27003e, + 0x5b27003c, + 0x5b27003b, + 0x5b270039, + 0x5b270037, + 0x5b270036, + 0x5b270034, + 0x5b270033, + 0x5b270031, + 0x5b270030, + 0x5b27002f, + 0x5b170044, + 0x5b170042, + 0x5b170040, + 0x5b17003e, + 0x5b17003c, + 0x5b17003b, + 0x5b170039, + 0x5b170037, + 0x5b170036, + 0x5b170034, + 0x5b170033, + 0x5b170031, + 0x5b170030, + 0x5b17002f, + 0x5b17002d, + 0x5b17002c, + 0x5b17002b, + 0x5b17002a, + 0x5b170028, + 0x5b170027, + 0x5b170026, + 0x5b170025, + 0x5b170024, + 0x5b170023, + 0x5b070044, + 0x5b070042, + 0x5b070040, + 0x5b07003e, + 0x5b07003c, + 0x5b07003b, + 0x5b070039, + 0x5b070037, + 0x5b070036, + 0x5b070034, + 0x5b070033, + 0x5b070031, + 0x5b070030, + 0x5b07002f, + 0x5b07002d, + 0x5b07002c, + 0x5b07002b, + 0x5b07002a, + 0x5b070028, + 0x5b070027, + 0x5b070026, + 0x5b070025, + 0x5b070024, + 0x5b070023, + 0x5b070022, + 0x5b070021, + 0x5b070020, + 0x5b07001f, + 0x5b07001e, + 0x5b07001d, + 0x5b07001d, + 0x5b07001c, +}; + +const u32 iq_lut_core0_rev3[] = { + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; + +const u32 iq_lut_core1_rev3[] = { + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; + +const u16 loft_lut_core0_rev3[] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}; + +const u16 loft_lut_core1_rev3[] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}; + +const u16 papd_comp_rfpwr_tbl_core0_rev3[] = { + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x002a, + 0x002a, + 0x002a, + 0x002a, + 0x002a, + 0x002a, + 0x002a, + 0x002a, + 0x002a, + 0x002a, + 0x002a, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, +}; + +const u16 papd_comp_rfpwr_tbl_core1_rev3[] = { + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x0036, + 0x002a, + 0x002a, + 0x002a, + 0x002a, + 0x002a, + 0x002a, + 0x002a, + 0x002a, + 0x002a, + 0x002a, + 0x002a, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x001e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x000e, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01fc, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01ee, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, + 0x01d6, +}; + +const u32 papd_comp_epsilon_tbl_core0_rev3[] = { + 0x00000000, + 0x00001fa0, + 0x00019f78, + 0x0001df7e, + 0x03fa9f86, + 0x03fd1f90, + 0x03fe5f8a, + 0x03fb1f94, + 0x03fd9fa0, + 0x00009f98, + 0x03fd1fac, + 0x03ff9fa2, + 0x03fe9fae, + 0x00001fae, + 0x03fddfb4, + 0x03ff1fb8, + 0x03ff9fbc, + 0x03ffdfbe, + 0x03fe9fc2, + 0x03fedfc6, + 0x03fedfc6, + 0x03ff9fc8, + 0x03ff5fc6, + 0x03fedfc2, + 0x03ff9fc0, + 0x03ff5fac, + 0x03ff5fac, + 0x03ff9fa2, + 0x03ff9fa6, + 0x03ff9faa, + 0x03ff5fb0, + 0x03ff5fb4, + 0x03ff1fca, + 0x03ff5fce, + 0x03fcdfdc, + 0x03fb4006, + 0x00000030, + 0x03ff808a, + 0x03ff80da, + 0x0000016c, + 0x03ff8318, + 0x03ff063a, + 0x03fd8bd6, + 0x00014ffe, + 0x00034ffe, + 0x00034ffe, + 0x0003cffe, + 0x00040ffe, + 0x00040ffe, + 0x0003cffe, + 0x0003cffe, + 0x00020ffe, + 0x03fe0ffe, + 0x03fdcffe, + 0x03f94ffe, + 0x03f54ffe, + 0x03f44ffe, + 0x03ef8ffe, + 0x03ee0ffe, + 0x03ebcffe, + 0x03e8cffe, + 0x03e74ffe, + 0x03e4cffe, + 0x03e38ffe, +}; + +const u32 papd_cal_scalars_tbl_core0_rev3[] = { + 0x05af005a, + 0x0571005e, + 0x05040066, + 0x04bd006c, + 0x047d0072, + 0x04430078, + 0x03f70081, + 0x03cb0087, + 0x03870091, + 0x035e0098, + 0x032e00a1, + 0x030300aa, + 0x02d800b4, + 0x02ae00bf, + 0x028900ca, + 0x026400d6, + 0x024100e3, + 0x022200f0, + 0x020200ff, + 0x01e5010e, + 0x01ca011e, + 0x01b0012f, + 0x01990140, + 0x01830153, + 0x016c0168, + 0x0158017d, + 0x01450193, + 0x013301ab, + 0x012101c5, + 0x011101e0, + 0x010201fc, + 0x00f4021a, + 0x00e6011d, + 0x00d9012e, + 0x00cd0140, + 0x00c20153, + 0x00b70167, + 0x00ac017c, + 0x00a30193, + 0x009a01ab, + 0x009101c4, + 0x008901df, + 0x008101fb, + 0x007a0219, + 0x00730239, + 0x006d025b, + 0x0067027e, + 0x006102a4, + 0x005c02cc, + 0x005602f6, + 0x00520323, + 0x004d0353, + 0x00490385, + 0x004503bb, + 0x004103f3, + 0x003d042f, + 0x003a046f, + 0x003704b2, + 0x003404f9, + 0x00310545, + 0x002e0596, + 0x002b05f5, + 0x00290640, + 0x002606a4, +}; + +const u32 papd_comp_epsilon_tbl_core1_rev3[] = { + 0x00000000, + 0x00001fa0, + 0x00019f78, + 0x0001df7e, + 0x03fa9f86, + 0x03fd1f90, + 0x03fe5f8a, + 0x03fb1f94, + 0x03fd9fa0, + 0x00009f98, + 0x03fd1fac, + 0x03ff9fa2, + 0x03fe9fae, + 0x00001fae, + 0x03fddfb4, + 0x03ff1fb8, + 0x03ff9fbc, + 0x03ffdfbe, + 0x03fe9fc2, + 0x03fedfc6, + 0x03fedfc6, + 0x03ff9fc8, + 0x03ff5fc6, + 0x03fedfc2, + 0x03ff9fc0, + 0x03ff5fac, + 0x03ff5fac, + 0x03ff9fa2, + 0x03ff9fa6, + 0x03ff9faa, + 0x03ff5fb0, + 0x03ff5fb4, + 0x03ff1fca, + 0x03ff5fce, + 0x03fcdfdc, + 0x03fb4006, + 0x00000030, + 0x03ff808a, + 0x03ff80da, + 0x0000016c, + 0x03ff8318, + 0x03ff063a, + 0x03fd8bd6, + 0x00014ffe, + 0x00034ffe, + 0x00034ffe, + 0x0003cffe, + 0x00040ffe, + 0x00040ffe, + 0x0003cffe, + 0x0003cffe, + 0x00020ffe, + 0x03fe0ffe, + 0x03fdcffe, + 0x03f94ffe, + 0x03f54ffe, + 0x03f44ffe, + 0x03ef8ffe, + 0x03ee0ffe, + 0x03ebcffe, + 0x03e8cffe, + 0x03e74ffe, + 0x03e4cffe, + 0x03e38ffe, +}; + +const u32 papd_cal_scalars_tbl_core1_rev3[] = { + 0x05af005a, + 0x0571005e, + 0x05040066, + 0x04bd006c, + 0x047d0072, + 0x04430078, + 0x03f70081, + 0x03cb0087, + 0x03870091, + 0x035e0098, + 0x032e00a1, + 0x030300aa, + 0x02d800b4, + 0x02ae00bf, + 0x028900ca, + 0x026400d6, + 0x024100e3, + 0x022200f0, + 0x020200ff, + 0x01e5010e, + 0x01ca011e, + 0x01b0012f, + 0x01990140, + 0x01830153, + 0x016c0168, + 0x0158017d, + 0x01450193, + 0x013301ab, + 0x012101c5, + 0x011101e0, + 0x010201fc, + 0x00f4021a, + 0x00e6011d, + 0x00d9012e, + 0x00cd0140, + 0x00c20153, + 0x00b70167, + 0x00ac017c, + 0x00a30193, + 0x009a01ab, + 0x009101c4, + 0x008901df, + 0x008101fb, + 0x007a0219, + 0x00730239, + 0x006d025b, + 0x0067027e, + 0x006102a4, + 0x005c02cc, + 0x005602f6, + 0x00520323, + 0x004d0353, + 0x00490385, + 0x004503bb, + 0x004103f3, + 0x003d042f, + 0x003a046f, + 0x003704b2, + 0x003404f9, + 0x00310545, + 0x002e0596, + 0x002b05f5, + 0x00290640, + 0x002606a4, +}; + +const mimophytbl_info_t mimophytbl_info_rev3_volatile[] = { + {&ant_swctrl_tbl_rev3, + sizeof(ant_swctrl_tbl_rev3) / sizeof(ant_swctrl_tbl_rev3[0]), 9, 0, 16} + , +}; + +const mimophytbl_info_t mimophytbl_info_rev3_volatile1[] = { + {&ant_swctrl_tbl_rev3_1, + sizeof(ant_swctrl_tbl_rev3_1) / sizeof(ant_swctrl_tbl_rev3_1[0]), 9, 0, + 16} + , +}; + +const mimophytbl_info_t mimophytbl_info_rev3_volatile2[] = { + {&ant_swctrl_tbl_rev3_2, + sizeof(ant_swctrl_tbl_rev3_2) / sizeof(ant_swctrl_tbl_rev3_2[0]), 9, 0, + 16} + , +}; + +const mimophytbl_info_t mimophytbl_info_rev3_volatile3[] = { + {&ant_swctrl_tbl_rev3_3, + sizeof(ant_swctrl_tbl_rev3_3) / sizeof(ant_swctrl_tbl_rev3_3[0]), 9, 0, + 16} + , +}; + +const mimophytbl_info_t mimophytbl_info_rev3[] = { + {&frame_struct_rev3, + sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32} + , + {&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]), + 11, 0, 16} + , + {&tmap_tbl_rev3, sizeof(tmap_tbl_rev3) / sizeof(tmap_tbl_rev3[0]), 12, + 0, 32} + , + {&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]), + 13, 0, 32} + , + {&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]), + 14, 0, 32} + , + {&noise_var_tbl_rev3, + sizeof(noise_var_tbl_rev3) / sizeof(noise_var_tbl_rev3[0]), 16, 0, 32} + , + {&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0, + 16} + , + {&tdi_tbl20_ant0_rev3, + sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128, + 32} + , + {&tdi_tbl20_ant1_rev3, + sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256, + 32} + , + {&tdi_tbl40_ant0_rev3, + sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640, + 32} + , + {&tdi_tbl40_ant1_rev3, + sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768, + 32} + , + {&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]), + 20, 0, 32} + , + {&chanest_tbl_rev3, + sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32} + , + {&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]), + 24, 0, 8} + , + {&est_pwr_lut_core0_rev3, + sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26, + 0, 8} + , + {&est_pwr_lut_core1_rev3, + sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27, + 0, 8} + , + {&adj_pwr_lut_core0_rev3, + sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26, + 64, 8} + , + {&adj_pwr_lut_core1_rev3, + sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27, + 64, 8} + , + {&gainctrl_lut_core0_rev3, + sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]), + 26, 192, 32} + , + {&gainctrl_lut_core1_rev3, + sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]), + 27, 192, 32} + , + {&iq_lut_core0_rev3, + sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32} + , + {&iq_lut_core1_rev3, + sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32} + , + {&loft_lut_core0_rev3, + sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448, + 16} + , + {&loft_lut_core1_rev3, + sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448, + 16} +}; + +const u32 mimophytbl_info_sz_rev3 = + sizeof(mimophytbl_info_rev3) / sizeof(mimophytbl_info_rev3[0]); +const u32 mimophytbl_info_sz_rev3_volatile = + sizeof(mimophytbl_info_rev3_volatile) / + sizeof(mimophytbl_info_rev3_volatile[0]); +const u32 mimophytbl_info_sz_rev3_volatile1 = + sizeof(mimophytbl_info_rev3_volatile1) / + sizeof(mimophytbl_info_rev3_volatile1[0]); +const u32 mimophytbl_info_sz_rev3_volatile2 = + sizeof(mimophytbl_info_rev3_volatile2) / + sizeof(mimophytbl_info_rev3_volatile2[0]); +const u32 mimophytbl_info_sz_rev3_volatile3 = + sizeof(mimophytbl_info_rev3_volatile3) / + sizeof(mimophytbl_info_rev3_volatile3[0]); + +const u32 tmap_tbl_rev7[] = { + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0xf1111110, + 0x11111111, + 0x11f11111, + 0x00000111, + 0x11000000, + 0x1111f111, + 0x11111111, + 0x111111f1, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x000aa888, + 0x88880000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0xa1111110, + 0x11111111, + 0x11c11111, + 0x00000111, + 0x11000000, + 0x1111a111, + 0x11111111, + 0x111111a1, + 0xa2222220, + 0x22222222, + 0x22c22222, + 0x00000222, + 0x22000000, + 0x2222a222, + 0x22222222, + 0x222222a2, + 0xf1111110, + 0x11111111, + 0x11f11111, + 0x00011111, + 0x11110000, + 0x1111f111, + 0x11111111, + 0x111111f1, + 0xa8aa88a0, + 0xa88888a8, + 0xa8a8a88a, + 0x00088aaa, + 0xaaaa0000, + 0xa8a8aa88, + 0xa88aaaaa, + 0xaaaa8a8a, + 0xaaa8aaa0, + 0x8aaa8aaa, + 0xaa8a8a8a, + 0x000aaa88, + 0x8aaa0000, + 0xaaa8a888, + 0x8aa88a8a, + 0x8a88a888, + 0x08080a00, + 0x0a08080a, + 0x080a0a08, + 0x00080808, + 0x080a0000, + 0x080a0808, + 0x080a0808, + 0x0a0a0a08, + 0xa0a0a0a0, + 0x80a0a080, + 0x8080a0a0, + 0x00008080, + 0x80a00000, + 0x80a080a0, + 0xa080a0a0, + 0x8080a0a0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x99999000, + 0x9b9b99bb, + 0x9bb99999, + 0x9999b9b9, + 0x9b99bb90, + 0x9bbbbb9b, + 0x9b9b9bb9, + 0x00000999, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00aaa888, + 0x22000000, + 0x2222b222, + 0x22222222, + 0x222222b2, + 0xb2222220, + 0x22222222, + 0x22d22222, + 0x00000222, + 0x11000000, + 0x1111a111, + 0x11111111, + 0x111111a1, + 0xa1111110, + 0x11111111, + 0x11c11111, + 0x00000111, + 0x33000000, + 0x3333b333, + 0x33333333, + 0x333333b3, + 0xb3333330, + 0x33333333, + 0x33d33333, + 0x00000333, + 0x22000000, + 0x2222a222, + 0x22222222, + 0x222222a2, + 0xa2222220, + 0x22222222, + 0x22c22222, + 0x00000222, + 0x99b99b00, + 0x9b9b99bb, + 0x9bb99999, + 0x9999b9b9, + 0x9b99bb99, + 0x9bbbbb9b, + 0x9b9b9bb9, + 0x00000999, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa88, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x08aaa888, + 0x22222200, + 0x2222f222, + 0x22222222, + 0x222222f2, + 0x22222222, + 0x22222222, + 0x22f22222, + 0x00000222, + 0x11000000, + 0x1111f111, + 0x11111111, + 0x11111111, + 0xf1111111, + 0x11111111, + 0x11f11111, + 0x01111111, + 0xbb9bb900, + 0xb9b9bb99, + 0xb99bbbbb, + 0xbbbb9b9b, + 0xb9bb99bb, + 0xb99999b9, + 0xb9b9b99b, + 0x00000bbb, + 0xaa000000, + 0xa8a8aa88, + 0xa88aaaaa, + 0xaaaa8a8a, + 0xa8aa88aa, + 0xa88888a8, + 0xa8a8a88a, + 0x0a888aaa, + 0xaa000000, + 0xa8a8aa88, + 0xa88aaaaa, + 0xaaaa8a8a, + 0xa8aa88a0, + 0xa88888a8, + 0xa8a8a88a, + 0x00000aaa, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0xbbbbbb00, + 0x999bbbbb, + 0x9bb99b9b, + 0xb9b9b9bb, + 0xb9b99bbb, + 0xb9b9b9bb, + 0xb9bb9b99, + 0x00000999, + 0x8a000000, + 0xaa88a888, + 0xa88888aa, + 0xa88a8a88, + 0xa88aa88a, + 0x88a8aaaa, + 0xa8aa8aaa, + 0x0888a88a, + 0x0b0b0b00, + 0x090b0b0b, + 0x0b090b0b, + 0x0909090b, + 0x09090b0b, + 0x09090b0b, + 0x09090b09, + 0x00000909, + 0x0a000000, + 0x0a080808, + 0x080a080a, + 0x080a0a08, + 0x080a080a, + 0x0808080a, + 0x0a0a0a08, + 0x0808080a, + 0xb0b0b000, + 0x9090b0b0, + 0x90b09090, + 0xb0b0b090, + 0xb0b090b0, + 0x90b0b0b0, + 0xb0b09090, + 0x00000090, + 0x80000000, + 0xa080a080, + 0xa08080a0, + 0xa0808080, + 0xa080a080, + 0x80a0a0a0, + 0xa0a080a0, + 0x00a0a0a0, + 0x22000000, + 0x2222f222, + 0x22222222, + 0x222222f2, + 0xf2222220, + 0x22222222, + 0x22f22222, + 0x00000222, + 0x11000000, + 0x1111f111, + 0x11111111, + 0x111111f1, + 0xf1111110, + 0x11111111, + 0x11f11111, + 0x00000111, + 0x33000000, + 0x3333f333, + 0x33333333, + 0x333333f3, + 0xf3333330, + 0x33333333, + 0x33f33333, + 0x00000333, + 0x22000000, + 0x2222f222, + 0x22222222, + 0x222222f2, + 0xf2222220, + 0x22222222, + 0x22f22222, + 0x00000222, + 0x99000000, + 0x9b9b99bb, + 0x9bb99999, + 0x9999b9b9, + 0x9b99bb90, + 0x9bbbbb9b, + 0x9b9b9bb9, + 0x00000999, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0x88888000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00aaa888, + 0x88a88a00, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa88, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x000aa888, + 0x88880000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa88, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x08aaa888, + 0x11000000, + 0x1111a111, + 0x11111111, + 0x111111a1, + 0xa1111110, + 0x11111111, + 0x11c11111, + 0x00000111, + 0x11000000, + 0x1111a111, + 0x11111111, + 0x111111a1, + 0xa1111110, + 0x11111111, + 0x11c11111, + 0x00000111, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0x88000000, + 0x8a8a88aa, + 0x8aa88888, + 0x8888a8a8, + 0x8a88aa80, + 0x8aaaaa8a, + 0x8a8a8aa8, + 0x00000888, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; + +const u32 noise_var_tbl_rev7[] = { + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, + 0x020c020c, + 0x0000014d, +}; + +const u32 papd_comp_epsilon_tbl_core0_rev7[] = { + 0x00000000, + 0x00000000, + 0x00016023, + 0x00006028, + 0x00034036, + 0x0003402e, + 0x0007203c, + 0x0006e037, + 0x00070030, + 0x0009401f, + 0x0009a00f, + 0x000b600d, + 0x000c8007, + 0x000ce007, + 0x00101fff, + 0x00121ff9, + 0x0012e004, + 0x0014dffc, + 0x0016dff6, + 0x0018dfe9, + 0x001b3fe5, + 0x001c5fd0, + 0x001ddfc2, + 0x001f1fb6, + 0x00207fa4, + 0x00219f8f, + 0x0022ff7d, + 0x00247f6c, + 0x0024df5b, + 0x00267f4b, + 0x0027df3b, + 0x0029bf3b, + 0x002b5f2f, + 0x002d3f2e, + 0x002f5f2a, + 0x002fff15, + 0x00315f0b, + 0x0032defa, + 0x0033beeb, + 0x0034fed9, + 0x00353ec5, + 0x00361eb0, + 0x00363e9b, + 0x0036be87, + 0x0036be70, + 0x0038fe67, + 0x0044beb2, + 0x00513ef3, + 0x00595f11, + 0x00669f3d, + 0x0078dfdf, + 0x00a143aa, + 0x01642fff, + 0x0162afff, + 0x01620fff, + 0x0160cfff, + 0x015f0fff, + 0x015dafff, + 0x015bcfff, + 0x015bcfff, + 0x015b4fff, + 0x015acfff, + 0x01590fff, + 0x0156cfff, +}; + +const u32 papd_cal_scalars_tbl_core0_rev7[] = { + 0x0b5e002d, + 0x0ae2002f, + 0x0a3b0032, + 0x09a70035, + 0x09220038, + 0x08ab003b, + 0x081f003f, + 0x07a20043, + 0x07340047, + 0x06d2004b, + 0x067a004f, + 0x06170054, + 0x05bf0059, + 0x0571005e, + 0x051e0064, + 0x04d3006a, + 0x04910070, + 0x044c0077, + 0x040f007e, + 0x03d90085, + 0x03a1008d, + 0x036f0095, + 0x033d009e, + 0x030b00a8, + 0x02e000b2, + 0x02b900bc, + 0x029200c7, + 0x026d00d3, + 0x024900e0, + 0x022900ed, + 0x020a00fb, + 0x01ec010a, + 0x01d20119, + 0x01b7012a, + 0x019e013c, + 0x0188014e, + 0x01720162, + 0x015d0177, + 0x0149018e, + 0x013701a5, + 0x012601be, + 0x011501d8, + 0x010601f4, + 0x00f70212, + 0x00e90231, + 0x00dc0253, + 0x00d00276, + 0x00c4029b, + 0x00b902c3, + 0x00af02ed, + 0x00a50319, + 0x009c0348, + 0x0093037a, + 0x008b03af, + 0x008303e6, + 0x007c0422, + 0x00750460, + 0x006e04a3, + 0x006804e9, + 0x00620533, + 0x005d0582, + 0x005805d6, + 0x0053062e, + 0x004e068c, +}; + +const u32 papd_comp_epsilon_tbl_core1_rev7[] = { + 0x00000000, + 0x00000000, + 0x00016023, + 0x00006028, + 0x00034036, + 0x0003402e, + 0x0007203c, + 0x0006e037, + 0x00070030, + 0x0009401f, + 0x0009a00f, + 0x000b600d, + 0x000c8007, + 0x000ce007, + 0x00101fff, + 0x00121ff9, + 0x0012e004, + 0x0014dffc, + 0x0016dff6, + 0x0018dfe9, + 0x001b3fe5, + 0x001c5fd0, + 0x001ddfc2, + 0x001f1fb6, + 0x00207fa4, + 0x00219f8f, + 0x0022ff7d, + 0x00247f6c, + 0x0024df5b, + 0x00267f4b, + 0x0027df3b, + 0x0029bf3b, + 0x002b5f2f, + 0x002d3f2e, + 0x002f5f2a, + 0x002fff15, + 0x00315f0b, + 0x0032defa, + 0x0033beeb, + 0x0034fed9, + 0x00353ec5, + 0x00361eb0, + 0x00363e9b, + 0x0036be87, + 0x0036be70, + 0x0038fe67, + 0x0044beb2, + 0x00513ef3, + 0x00595f11, + 0x00669f3d, + 0x0078dfdf, + 0x00a143aa, + 0x01642fff, + 0x0162afff, + 0x01620fff, + 0x0160cfff, + 0x015f0fff, + 0x015dafff, + 0x015bcfff, + 0x015bcfff, + 0x015b4fff, + 0x015acfff, + 0x01590fff, + 0x0156cfff, +}; + +const u32 papd_cal_scalars_tbl_core1_rev7[] = { + 0x0b5e002d, + 0x0ae2002f, + 0x0a3b0032, + 0x09a70035, + 0x09220038, + 0x08ab003b, + 0x081f003f, + 0x07a20043, + 0x07340047, + 0x06d2004b, + 0x067a004f, + 0x06170054, + 0x05bf0059, + 0x0571005e, + 0x051e0064, + 0x04d3006a, + 0x04910070, + 0x044c0077, + 0x040f007e, + 0x03d90085, + 0x03a1008d, + 0x036f0095, + 0x033d009e, + 0x030b00a8, + 0x02e000b2, + 0x02b900bc, + 0x029200c7, + 0x026d00d3, + 0x024900e0, + 0x022900ed, + 0x020a00fb, + 0x01ec010a, + 0x01d20119, + 0x01b7012a, + 0x019e013c, + 0x0188014e, + 0x01720162, + 0x015d0177, + 0x0149018e, + 0x013701a5, + 0x012601be, + 0x011501d8, + 0x010601f4, + 0x00f70212, + 0x00e90231, + 0x00dc0253, + 0x00d00276, + 0x00c4029b, + 0x00b902c3, + 0x00af02ed, + 0x00a50319, + 0x009c0348, + 0x0093037a, + 0x008b03af, + 0x008303e6, + 0x007c0422, + 0x00750460, + 0x006e04a3, + 0x006804e9, + 0x00620533, + 0x005d0582, + 0x005805d6, + 0x0053062e, + 0x004e068c, +}; + +const mimophytbl_info_t mimophytbl_info_rev7[] = { + {&frame_struct_rev3, + sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32} + , + {&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]), + 11, 0, 16} + , + {&tmap_tbl_rev7, sizeof(tmap_tbl_rev7) / sizeof(tmap_tbl_rev7[0]), 12, + 0, 32} + , + {&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]), + 13, 0, 32} + , + {&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]), + 14, 0, 32} + , + {&noise_var_tbl_rev7, + sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32} + , + {&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0, + 16} + , + {&tdi_tbl20_ant0_rev3, + sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128, + 32} + , + {&tdi_tbl20_ant1_rev3, + sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256, + 32} + , + {&tdi_tbl40_ant0_rev3, + sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640, + 32} + , + {&tdi_tbl40_ant1_rev3, + sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768, + 32} + , + {&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]), + 20, 0, 32} + , + {&chanest_tbl_rev3, + sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32} + , + {&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]), + 24, 0, 8} + , + {&est_pwr_lut_core0_rev3, + sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26, + 0, 8} + , + {&est_pwr_lut_core1_rev3, + sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27, + 0, 8} + , + {&adj_pwr_lut_core0_rev3, + sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26, + 64, 8} + , + {&adj_pwr_lut_core1_rev3, + sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27, + 64, 8} + , + {&gainctrl_lut_core0_rev3, + sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]), + 26, 192, 32} + , + {&gainctrl_lut_core1_rev3, + sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]), + 27, 192, 32} + , + {&iq_lut_core0_rev3, + sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32} + , + {&iq_lut_core1_rev3, + sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32} + , + {&loft_lut_core0_rev3, + sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448, + 16} + , + {&loft_lut_core1_rev3, + sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448, + 16} + , + {&papd_comp_rfpwr_tbl_core0_rev3, + sizeof(papd_comp_rfpwr_tbl_core0_rev3) / + sizeof(papd_comp_rfpwr_tbl_core0_rev3[0]), 26, 576, 16} + , + {&papd_comp_rfpwr_tbl_core1_rev3, + sizeof(papd_comp_rfpwr_tbl_core1_rev3) / + sizeof(papd_comp_rfpwr_tbl_core1_rev3[0]), 27, 576, 16} + , + {&papd_comp_epsilon_tbl_core0_rev7, + sizeof(papd_comp_epsilon_tbl_core0_rev7) / + sizeof(papd_comp_epsilon_tbl_core0_rev7[0]), 31, 0, 32} + , + {&papd_cal_scalars_tbl_core0_rev7, + sizeof(papd_cal_scalars_tbl_core0_rev7) / + sizeof(papd_cal_scalars_tbl_core0_rev7[0]), 32, 0, 32} + , + {&papd_comp_epsilon_tbl_core1_rev7, + sizeof(papd_comp_epsilon_tbl_core1_rev7) / + sizeof(papd_comp_epsilon_tbl_core1_rev7[0]), 33, 0, 32} + , + {&papd_cal_scalars_tbl_core1_rev7, + sizeof(papd_cal_scalars_tbl_core1_rev7) / + sizeof(papd_cal_scalars_tbl_core1_rev7[0]), 34, 0, 32} + , +}; + +const u32 mimophytbl_info_sz_rev7 = + sizeof(mimophytbl_info_rev7) / sizeof(mimophytbl_info_rev7[0]); + +const mimophytbl_info_t mimophytbl_info_rev16[] = { + {&noise_var_tbl_rev7, + sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32} + , + {&est_pwr_lut_core0_rev3, + sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26, + 0, 8} + , + {&est_pwr_lut_core1_rev3, + sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27, + 0, 8} + , + {&adj_pwr_lut_core0_rev3, + sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26, + 64, 8} + , + {&adj_pwr_lut_core1_rev3, + sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27, + 64, 8} + , + {&gainctrl_lut_core0_rev3, + sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]), + 26, 192, 32} + , + {&gainctrl_lut_core1_rev3, + sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]), + 27, 192, 32} + , + {&iq_lut_core0_rev3, + sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32} + , + {&iq_lut_core1_rev3, + sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32} + , + {&loft_lut_core0_rev3, + sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448, + 16} + , + {&loft_lut_core1_rev3, + sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448, + 16} + , +}; + +const u32 mimophytbl_info_sz_rev16 = + sizeof(mimophytbl_info_rev16) / sizeof(mimophytbl_info_rev16[0]); diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h new file mode 100644 index 000000000000..396122f5e50b --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define ANT_SWCTRL_TBL_REV3_IDX (0) + +typedef phytbl_info_t mimophytbl_info_t; + +extern const mimophytbl_info_t mimophytbl_info_rev0[], + mimophytbl_info_rev0_volatile[]; +extern const u32 mimophytbl_info_sz_rev0, mimophytbl_info_sz_rev0_volatile; + +extern const mimophytbl_info_t mimophytbl_info_rev3[], + mimophytbl_info_rev3_volatile[], mimophytbl_info_rev3_volatile1[], + mimophytbl_info_rev3_volatile2[], mimophytbl_info_rev3_volatile3[]; +extern const u32 mimophytbl_info_sz_rev3, mimophytbl_info_sz_rev3_volatile, + mimophytbl_info_sz_rev3_volatile1, mimophytbl_info_sz_rev3_volatile2, + mimophytbl_info_sz_rev3_volatile3; + +extern const u32 noise_var_tbl_rev3[]; + +extern const mimophytbl_info_t mimophytbl_info_rev7[]; +extern const u32 mimophytbl_info_sz_rev7; +extern const u32 noise_var_tbl_rev7[]; + +extern const mimophytbl_info_t mimophytbl_info_rev16[]; +extern const u32 mimophytbl_info_sz_rev16; diff --git a/drivers/staging/brcm80211/brcmsmac/sys/d11ucode_ext.h b/drivers/staging/brcm80211/brcmsmac/sys/d11ucode_ext.h new file mode 100644 index 000000000000..c0c0d661e00e --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/d11ucode_ext.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +enum { + D11UCODE_NAMETAG_START = 0, + D11LCN0BSINITVALS24, + D11LCN0INITVALS24, + D11LCN1BSINITVALS24, + D11LCN1INITVALS24, + D11LCN2BSINITVALS24, + D11LCN2INITVALS24, + D11N0ABSINITVALS16, + D11N0BSINITVALS16, + D11N0INITVALS16, + D11UCODE_OVERSIGHT16_MIMO, + D11UCODE_OVERSIGHT16_MIMOSZ, + D11UCODE_OVERSIGHT24_LCN, + D11UCODE_OVERSIGHT24_LCNSZ, + D11UCODE_OVERSIGHT_BOMMAJOR, + D11UCODE_OVERSIGHT_BOMMINOR +}; +#define UCODE_LOADER_API_VER 0 diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wl_dbg.h b/drivers/staging/brcm80211/brcmsmac/sys/wl_dbg.h new file mode 100644 index 000000000000..54af257598c2 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wl_dbg.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wl_dbg_h_ +#define _wl_dbg_h_ + +/* wl_msg_level is a bit vector with defs in wlioctl.h */ +extern u32 wl_msg_level; + +#define WL_NONE(fmt, args...) no_printk(fmt, ##args) + +#define WL_PRINT(level, fmt, args...) \ +do { \ + if (wl_msg_level & level) \ + printk(fmt, ##args); \ +} while (0) + +#ifdef BCMDBG + +#define WL_ERROR(fmt, args...) WL_PRINT(WL_ERROR_VAL, fmt, ##args) +#define WL_TRACE(fmt, args...) WL_PRINT(WL_TRACE_VAL, fmt, ##args) +#define WL_AMPDU(fmt, args...) WL_PRINT(WL_AMPDU_VAL, fmt, ##args) +#define WL_FFPLD(fmt, args...) WL_PRINT(WL_FFPLD_VAL, fmt, ##args) + +#define WL_ERROR_ON() (wl_msg_level & WL_ERROR_VAL) + +/* Extra message control for AMPDU debugging */ +#define WL_AMPDU_UPDN_VAL 0x00000001 /* Config up/down related */ +#define WL_AMPDU_ERR_VAL 0x00000002 /* Calls to beaocn update */ +#define WL_AMPDU_TX_VAL 0x00000004 /* Transmit data path */ +#define WL_AMPDU_RX_VAL 0x00000008 /* Receive data path */ +#define WL_AMPDU_CTL_VAL 0x00000010 /* TSF-related items */ +#define WL_AMPDU_HW_VAL 0x00000020 /* AMPDU_HW */ +#define WL_AMPDU_HWTXS_VAL 0x00000040 /* AMPDU_HWTXS */ +#define WL_AMPDU_HWDBG_VAL 0x00000080 /* AMPDU_DBG */ + +extern u32 wl_ampdu_dbg; + +#define WL_AMPDU_PRINT(level, fmt, args...) \ +do { \ + if (wl_ampdu_dbg & level) { \ + WL_AMPDU(fmt, ##args); \ + } \ +} while (0) + +#define WL_AMPDU_UPDN(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_UPDN_VAL, fmt, ##args) +#define WL_AMPDU_RX(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_RX_VAL, fmt, ##args) +#define WL_AMPDU_ERR(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_ERR_VAL, fmt, ##args) +#define WL_AMPDU_TX(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_TX_VAL, fmt, ##args) +#define WL_AMPDU_CTL(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_CTL_VAL, fmt, ##args) +#define WL_AMPDU_HW(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_HW_VAL, fmt, ##args) +#define WL_AMPDU_HWTXS(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_HWTXS_VAL, fmt, ##args) +#define WL_AMPDU_HWDBG(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_HWDBG_VAL, fmt, ##args) +#define WL_AMPDU_ERR_ON() (wl_ampdu_dbg & WL_AMPDU_ERR_VAL) +#define WL_AMPDU_HW_ON() (wl_ampdu_dbg & WL_AMPDU_HW_VAL) +#define WL_AMPDU_HWTXS_ON() (wl_ampdu_dbg & WL_AMPDU_HWTXS_VAL) + +#else /* BCMDBG */ + +#define WL_ERROR(fmt, args...) no_printk(fmt, ##args) +#define WL_TRACE(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU(fmt, args...) no_printk(fmt, ##args) +#define WL_FFPLD(fmt, args...) no_printk(fmt, ##args) + +#define WL_ERROR_ON() 0 + +#define WL_AMPDU_UPDN(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_RX(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_ERR(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_TX(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_CTL(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_HW(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_HWTXS(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_HWDBG(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_ERR_ON() 0 +#define WL_AMPDU_HW_ON() 0 +#define WL_AMPDU_HWTXS_ON() 0 + +#endif /* BCMDBG */ + +#endif /* _wl_dbg_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wl_export.h b/drivers/staging/brcm80211/brcmsmac/sys/wl_export.h new file mode 100644 index 000000000000..aa8b5a3ed633 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wl_export.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wl_export_h_ +#define _wl_export_h_ + +/* misc callbacks */ +struct wl_info; +struct wl_if; +struct wlc_if; +extern void wl_init(struct wl_info *wl); +extern uint wl_reset(struct wl_info *wl); +extern void wl_intrson(struct wl_info *wl); +extern u32 wl_intrsoff(struct wl_info *wl); +extern void wl_intrsrestore(struct wl_info *wl, u32 macintmask); +extern void wl_event(struct wl_info *wl, char *ifname, wlc_event_t *e); +extern void wl_event_sendup(struct wl_info *wl, const wlc_event_t *e, + u8 *data, u32 len); +extern int wl_up(struct wl_info *wl); +extern void wl_down(struct wl_info *wl); +extern void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, + int prio); +extern bool wl_alloc_dma_resources(struct wl_info *wl, uint dmaddrwidth); + +/* timer functions */ +struct wl_timer; +extern struct wl_timer *wl_init_timer(struct wl_info *wl, + void (*fn) (void *arg), void *arg, + const char *name); +extern void wl_free_timer(struct wl_info *wl, struct wl_timer *timer); +extern void wl_add_timer(struct wl_info *wl, struct wl_timer *timer, uint ms, + int periodic); +extern bool wl_del_timer(struct wl_info *wl, struct wl_timer *timer); + +extern uint wl_buf_to_pktcopy(struct osl_info *osh, void *p, unsigned char *buf, + int len, uint offset); +extern void *wl_get_pktbuffer(struct osl_info *osh, int len); +extern int wl_set_pktlen(struct osl_info *osh, void *p, int len); + +#define wl_sort_bsslist(a, b) false + +extern int wl_tkip_miccheck(struct wl_info *wl, void *p, int hdr_len, + bool group_key, int id); +extern int wl_tkip_micadd(struct wl_info *wl, void *p, int hdr_len); +extern int wl_tkip_encrypt(struct wl_info *wl, void *p, int hdr_len); +extern int wl_tkip_decrypt(struct wl_info *wl, void *p, int hdr_len, + bool group_key); +extern void wl_tkip_printstats(struct wl_info *wl, bool group_key); +extern int wl_tkip_keyset(struct wl_info *wl, wsec_key_t *key); +#endif /* _wl_export_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/sys/wl_mac80211.c new file mode 100644 index 000000000000..6bc6207bab3e --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wl_mac80211.c @@ -0,0 +1,1846 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define __UNDEF_NO_VERSION__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define WLC_MAXBSSCFG 1 /* single BSS configs */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +static void wl_timer(unsigned long data); +static void _wl_timer(wl_timer_t *t); + + +static int ieee_hw_init(struct ieee80211_hw *hw); +static int ieee_hw_rate_init(struct ieee80211_hw *hw); + +static int wl_linux_watchdog(void *ctx); + +/* Flags we support */ +#define MAC_FILTERS (FIF_PROMISC_IN_BSS | \ + FIF_ALLMULTI | \ + FIF_FCSFAIL | \ + FIF_PLCPFAIL | \ + FIF_CONTROL | \ + FIF_OTHER_BSS | \ + FIF_BCN_PRBRESP_PROMISC) + +static int wl_found; + +struct ieee80211_tkip_data { +#define TKIP_KEY_LEN 32 + u8 key[TKIP_KEY_LEN]; + int key_set; + + u32 tx_iv32; + u16 tx_iv16; + u16 tx_ttak[5]; + int tx_phase1_done; + + u32 rx_iv32; + u16 rx_iv16; + u16 rx_ttak[5]; + int rx_phase1_done; + u32 rx_iv32_new; + u16 rx_iv16_new; + + u32 dot11RSNAStatsTKIPReplays; + u32 dot11RSNAStatsTKIPICVErrors; + u32 dot11RSNAStatsTKIPLocalMICFailures; + + int key_idx; + + struct crypto_tfm *tfm_arc4; + struct crypto_tfm *tfm_michael; + + /* scratch buffers for virt_to_page() (crypto API) */ + u8 rx_hdr[16], tx_hdr[16]; +}; + +#define WL_DEV_IF(dev) ((struct wl_if *)netdev_priv(dev)) +#define WL_INFO(dev) ((struct wl_info *)(WL_DEV_IF(dev)->wl)) +static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev); +static void wl_release_fw(struct wl_info *wl); + +/* local prototypes */ +static int wl_start(struct sk_buff *skb, struct wl_info *wl); +static int wl_start_int(struct wl_info *wl, struct ieee80211_hw *hw, + struct sk_buff *skb); +static void wl_dpc(unsigned long data); + +MODULE_AUTHOR("Broadcom Corporation"); +MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver."); +MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards"); +MODULE_LICENSE("Dual BSD/GPL"); + +/* recognized PCI IDs */ +static struct pci_device_id wl_id_table[] = { + {PCI_VENDOR_ID_BROADCOM, 0x4357, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43225 2G */ + {PCI_VENDOR_ID_BROADCOM, 0x4353, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43224 DUAL */ + {PCI_VENDOR_ID_BROADCOM, 0x4727, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 4313 DUAL */ + {0} +}; + +MODULE_DEVICE_TABLE(pci, wl_id_table); +static void wl_remove(struct pci_dev *pdev); + + +#ifdef BCMDBG +static int msglevel = 0xdeadbeef; +module_param(msglevel, int, 0); +static int phymsglevel = 0xdeadbeef; +module_param(phymsglevel, int, 0); +#endif /* BCMDBG */ + +#define HW_TO_WL(hw) (hw->priv) +#define WL_TO_HW(wl) (wl->pub->ieee_hw) +static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb); +static int wl_ops_start(struct ieee80211_hw *hw); +static void wl_ops_stop(struct ieee80211_hw *hw); +static int wl_ops_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +static void wl_ops_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +static int wl_ops_config(struct ieee80211_hw *hw, u32 changed); +static void wl_ops_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, + u32 changed); +static void wl_ops_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, u64 multicast); +static int wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, + bool set); +static void wl_ops_sw_scan_start(struct ieee80211_hw *hw); +static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw); +static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf); +static int wl_ops_get_stats(struct ieee80211_hw *hw, + struct ieee80211_low_level_stats *stats); +static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value); +static void wl_ops_sta_notify(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum sta_notify_cmd cmd, + struct ieee80211_sta *sta); +static int wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, + const struct ieee80211_tx_queue_params *params); +static u64 wl_ops_get_tsf(struct ieee80211_hw *hw); +static int wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +static int wl_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +static int wl_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + enum ieee80211_ampdu_mlme_action action, + struct ieee80211_sta *sta, u16 tid, u16 *ssn); + +static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + int status; + struct wl_info *wl = hw->priv; + WL_LOCK(wl); + if (!wl->pub->up) { + WL_ERROR("ops->tx called while down\n"); + status = -ENETDOWN; + goto done; + } + status = wl_start(skb, wl); + done: + WL_UNLOCK(wl); + return status; +} + +static int wl_ops_start(struct ieee80211_hw *hw) +{ + struct wl_info *wl = hw->priv; + /* + struct ieee80211_channel *curchan = hw->conf.channel; + WL_NONE("%s : Initial channel: %d\n", __func__, curchan->hw_value); + */ + + WL_LOCK(wl); + ieee80211_wake_queues(hw); + WL_UNLOCK(wl); + + return 0; +} + +static void wl_ops_stop(struct ieee80211_hw *hw) +{ + struct wl_info *wl = hw->priv; + ASSERT(wl); + WL_LOCK(wl); + wl_down(wl); + ieee80211_stop_queues(hw); + WL_UNLOCK(wl); + + return; +} + +static int +wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct wl_info *wl; + int err; + + /* Just STA for now */ + if (vif->type != NL80211_IFTYPE_AP && + vif->type != NL80211_IFTYPE_MESH_POINT && + vif->type != NL80211_IFTYPE_STATION && + vif->type != NL80211_IFTYPE_WDS && + vif->type != NL80211_IFTYPE_ADHOC) { + WL_ERROR("%s: Attempt to add type %d, only STA for now\n", + __func__, vif->type); + return -EOPNOTSUPP; + } + + wl = HW_TO_WL(hw); + WL_LOCK(wl); + err = wl_up(wl); + WL_UNLOCK(wl); + + if (err != 0) + WL_ERROR("%s: wl_up() returned %d\n", __func__, err); + return err; +} + +static void +wl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + return; +} + +static int +ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan, + enum nl80211_channel_type type) +{ + struct wl_info *wl = HW_TO_WL(hw); + int err = 0; + + switch (type) { + case NL80211_CHAN_HT20: + case NL80211_CHAN_NO_HT: + WL_LOCK(wl); + err = wlc_set(wl->wlc, WLC_SET_CHANNEL, chan->hw_value); + WL_UNLOCK(wl); + break; + case NL80211_CHAN_HT40MINUS: + case NL80211_CHAN_HT40PLUS: + WL_ERROR("%s: Need to implement 40 Mhz Channels!\n", __func__); + break; + } + + if (err) + return -EIO; + return err; +} + +static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) +{ + struct ieee80211_conf *conf = &hw->conf; + struct wl_info *wl = HW_TO_WL(hw); + int err = 0; + int new_int; + + if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { + WL_NONE("%s: Setting listen interval to %d\n", + __func__, conf->listen_interval); + if (wlc_iovar_setint + (wl->wlc, "bcn_li_bcn", conf->listen_interval)) { + WL_ERROR("%s: Error setting listen_interval\n", + __func__); + err = -EIO; + goto config_out; + } + wlc_iovar_getint(wl->wlc, "bcn_li_bcn", &new_int); + ASSERT(new_int == conf->listen_interval); + } + if (changed & IEEE80211_CONF_CHANGE_MONITOR) + WL_NONE("Need to set monitor mode\n"); + if (changed & IEEE80211_CONF_CHANGE_PS) + WL_NONE("Need to set Power-save mode\n"); + + if (changed & IEEE80211_CONF_CHANGE_POWER) { + WL_NONE("%s: Setting tx power to %d dbm\n", + __func__, conf->power_level); + if (wlc_iovar_setint + (wl->wlc, "qtxpower", conf->power_level * 4)) { + WL_ERROR("%s: Error setting power_level\n", __func__); + err = -EIO; + goto config_out; + } + wlc_iovar_getint(wl->wlc, "qtxpower", &new_int); + if (new_int != (conf->power_level * 4)) + WL_ERROR("%s: Power level req != actual, %d %d\n", + __func__, conf->power_level * 4, new_int); + } + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + err = ieee_set_channel(hw, conf->channel, conf->channel_type); + } + if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { + WL_NONE("%s: srl %d, lrl %d\n", + __func__, + conf->short_frame_max_tx_count, + conf->long_frame_max_tx_count); + if (wlc_set + (wl->wlc, WLC_SET_SRL, + conf->short_frame_max_tx_count) < 0) { + WL_ERROR("%s: Error setting srl\n", __func__); + err = -EIO; + goto config_out; + } + if (wlc_set(wl->wlc, WLC_SET_LRL, conf->long_frame_max_tx_count) + < 0) { + WL_ERROR("%s: Error setting lrl\n", __func__); + err = -EIO; + goto config_out; + } + } + + config_out: + return err; +} + +static void +wl_ops_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, u32 changed) +{ + struct wl_info *wl = HW_TO_WL(hw); + int val; + + + if (changed & BSS_CHANGED_ASSOC) { + WL_ERROR("Associated:\t%s\n", info->assoc ? "True" : "False"); + /* association status changed (associated/disassociated) + * also implies a change in the AID. + */ + } + if (changed & BSS_CHANGED_ERP_CTS_PROT) { + WL_NONE("Use_cts_prot:\t%s Implement me\n", + info->use_cts_prot ? "True" : "False"); + /* CTS protection changed */ + } + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + WL_NONE("Short preamble:\t%s Implement me\n", + info->use_short_preamble ? "True" : "False"); + /* preamble changed */ + } + if (changed & BSS_CHANGED_ERP_SLOT) { + WL_NONE("Changing short slot:\t%s\n", + info->use_short_slot ? "True" : "False"); + if (info->use_short_slot) + val = 1; + else + val = 0; + wlc_set(wl->wlc, WLC_SET_SHORTSLOT_OVERRIDE, val); + /* slot timing changed */ + } + + if (changed & BSS_CHANGED_HT) { + WL_NONE("%s: HT mode - Implement me\n", __func__); + /* 802.11n parameters changed */ + } + if (changed & BSS_CHANGED_BASIC_RATES) { + WL_NONE("Need to change Basic Rates:\t0x%x! Implement me\n", + (u32) info->basic_rates); + /* Basic rateset changed */ + } + if (changed & BSS_CHANGED_BEACON_INT) { + WL_NONE("Beacon Interval:\t%d Implement me\n", + info->beacon_int); + /* Beacon interval changed */ + } + if (changed & BSS_CHANGED_BSSID) { + WL_NONE("new BSSID:\taid %d bss:%pM\n", + info->aid, info->bssid); + /* BSSID changed, for whatever reason (IBSS and managed mode) */ + /* FIXME: need to store bssid in bsscfg */ + wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, + info->bssid); + } + if (changed & BSS_CHANGED_BEACON) { + WL_ERROR("BSS_CHANGED_BEACON\n"); + /* Beacon data changed, retrieve new beacon (beaconing modes) */ + } + if (changed & BSS_CHANGED_BEACON_ENABLED) { + WL_ERROR("Beacon enabled:\t%s\n", + info->enable_beacon ? "True" : "False"); + /* Beaconing should be enabled/disabled (beaconing modes) */ + } + return; +} + +static void +wl_ops_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, u64 multicast) +{ + struct wl_info *wl = hw->priv; + + changed_flags &= MAC_FILTERS; + *total_flags &= MAC_FILTERS; + if (changed_flags & FIF_PROMISC_IN_BSS) + WL_ERROR("FIF_PROMISC_IN_BSS\n"); + if (changed_flags & FIF_ALLMULTI) + WL_ERROR("FIF_ALLMULTI\n"); + if (changed_flags & FIF_FCSFAIL) + WL_ERROR("FIF_FCSFAIL\n"); + if (changed_flags & FIF_PLCPFAIL) + WL_ERROR("FIF_PLCPFAIL\n"); + if (changed_flags & FIF_CONTROL) + WL_ERROR("FIF_CONTROL\n"); + if (changed_flags & FIF_OTHER_BSS) + WL_ERROR("FIF_OTHER_BSS\n"); + if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { + WL_NONE("FIF_BCN_PRBRESP_PROMISC\n"); + WL_LOCK(wl); + if (*total_flags & FIF_BCN_PRBRESP_PROMISC) { + wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS; + wlc_mac_bcn_promisc_change(wl->wlc, 1); + } else { + wlc_mac_bcn_promisc_change(wl->wlc, 0); + wl->pub->mac80211_state &= ~MAC80211_PROMISC_BCNS; + } + WL_UNLOCK(wl); + } + return; +} + +static int +wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) +{ + WL_ERROR("%s: Enter\n", __func__); + return 0; +} + +static void wl_ops_sw_scan_start(struct ieee80211_hw *hw) +{ + WL_NONE("Scan Start\n"); + return; +} + +static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw) +{ + WL_NONE("Scan Complete\n"); + return; +} + +static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf) +{ + WL_ERROR("%s: Enter\n", __func__); + return; +} + +static int +wl_ops_get_stats(struct ieee80211_hw *hw, + struct ieee80211_low_level_stats *stats) +{ + WL_ERROR("%s: Enter\n", __func__); + return 0; +} + +static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value) +{ + WL_ERROR("%s: Enter\n", __func__); + return 0; +} + +static void +wl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + enum sta_notify_cmd cmd, struct ieee80211_sta *sta) +{ + WL_NONE("%s: Enter\n", __func__); + switch (cmd) { + default: + WL_ERROR("%s: Unknown cmd = %d\n", __func__, cmd); + break; + } + return; +} + +static int +wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, + const struct ieee80211_tx_queue_params *params) +{ + struct wl_info *wl = hw->priv; + + WL_NONE("%s: Enter (WME config)\n", __func__); + WL_NONE("queue %d, txop %d, cwmin %d, cwmax %d, aifs %d\n", queue, + params->txop, params->cw_min, params->cw_max, params->aifs); + + WL_LOCK(wl); + wlc_wme_setparams(wl->wlc, queue, (void *)params, true); + WL_UNLOCK(wl); + + return 0; +} + +static u64 wl_ops_get_tsf(struct ieee80211_hw *hw) +{ + WL_ERROR("%s: Enter\n", __func__); + return 0; +} + +static int +wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct scb *scb; + + int i; + struct wl_info *wl = hw->priv; + + /* Init the scb */ + scb = (struct scb *)sta->drv_priv; + memset(scb, 0, sizeof(struct scb)); + for (i = 0; i < NUMPRIO; i++) + scb->seqctl[i] = 0xFFFF; + scb->seqctl_nonqos = 0xFFFF; + scb->magic = SCB_MAGIC; + + wl->pub->global_scb = scb; + wl->pub->global_ampdu = &(scb->scb_ampdu); + wl->pub->global_ampdu->scb = scb; + wl->pub->global_ampdu->max_pdu = 16; + pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID, + AMPDU_MAX_SCB_TID * PKTQ_LEN_DEFAULT); + + sta->ht_cap.ht_supported = true; + sta->ht_cap.ampdu_factor = AMPDU_RX_FACTOR_64K; + sta->ht_cap.ampdu_density = AMPDU_DEF_MPDU_DENSITY; + sta->ht_cap.cap = IEEE80211_HT_CAP_GRN_FLD | + IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT; + + /* minstrel_ht initiates addBA on our behalf by calling ieee80211_start_tx_ba_session() */ + return 0; +} + +static int +wl_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + WL_NONE("%s: Enter\n", __func__); + return 0; +} + +static int +wl_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum ieee80211_ampdu_mlme_action action, + struct ieee80211_sta *sta, u16 tid, u16 *ssn) +{ +#if defined(BCMDBG) + struct scb *scb = (struct scb *)sta->drv_priv; +#endif + struct wl_info *wl = hw->priv; + + ASSERT(scb->magic == SCB_MAGIC); + switch (action) { + case IEEE80211_AMPDU_RX_START: + WL_NONE("%s: action = IEEE80211_AMPDU_RX_START\n", __func__); + break; + case IEEE80211_AMPDU_RX_STOP: + WL_NONE("%s: action = IEEE80211_AMPDU_RX_STOP\n", __func__); + break; + case IEEE80211_AMPDU_TX_START: + if (!wlc_aggregatable(wl->wlc, tid)) { + /* WL_ERROR("START: tid %d is not agg' able, return FAILURE to stack\n", tid); */ + return -1; + } + /* XXX: Use the starting sequence number provided ... */ + *ssn = 0; + ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + break; + + case IEEE80211_AMPDU_TX_STOP: + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + break; + case IEEE80211_AMPDU_TX_OPERATIONAL: + /* Not sure what to do here */ + /* Power save wakeup */ + WL_NONE("%s: action = IEEE80211_AMPDU_TX_OPERATIONAL\n", + __func__); + break; + default: + WL_ERROR("%s: Invalid command, ignoring\n", __func__); + } + + return 0; +} + +static const struct ieee80211_ops wl_ops = { + .tx = wl_ops_tx, + .start = wl_ops_start, + .stop = wl_ops_stop, + .add_interface = wl_ops_add_interface, + .remove_interface = wl_ops_remove_interface, + .config = wl_ops_config, + .bss_info_changed = wl_ops_bss_info_changed, + .configure_filter = wl_ops_configure_filter, + .set_tim = wl_ops_set_tim, + .sw_scan_start = wl_ops_sw_scan_start, + .sw_scan_complete = wl_ops_sw_scan_complete, + .set_tsf = wl_ops_set_tsf, + .get_stats = wl_ops_get_stats, + .set_rts_threshold = wl_ops_set_rts_threshold, + .sta_notify = wl_ops_sta_notify, + .conf_tx = wl_ops_conf_tx, + .get_tsf = wl_ops_get_tsf, + .sta_add = wl_sta_add, + .sta_remove = wl_sta_remove, + .ampdu_action = wl_ampdu_action, +}; + +static int wl_set_hint(struct wl_info *wl, char *abbrev) +{ + WL_ERROR("%s: Sending country code %c%c to MAC80211\n", + __func__, abbrev[0], abbrev[1]); + return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev); +} + +/** + * attach to the WL device. + * + * Attach to the WL device identified by vendor and device parameters. + * regs is a host accessible memory address pointing to WL device registers. + * + * wl_attach is not defined as static because in the case where no bus + * is defined, wl_attach will never be called, and thus, gcc will issue + * a warning that this function is defined but not used if we declare + * it as static. + */ +static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, + uint bustype, void *btparam, uint irq) +{ + struct wl_info *wl; + struct osl_info *osh; + int unit, err; + + unsigned long base_addr; + struct ieee80211_hw *hw; + u8 perm[ETH_ALEN]; + + unit = wl_found; + err = 0; + + if (unit < 0) { + WL_ERROR("wl%d: unit number overflow, exiting\n", unit); + return NULL; + } + + osh = osl_attach(btparam, bustype); + ASSERT(osh); + + /* allocate private info */ + hw = pci_get_drvdata(btparam); /* btparam == pdev */ + wl = hw->priv; + ASSERT(wl); + + wl->osh = osh; + atomic_set(&wl->callbacks, 0); + + /* setup the bottom half handler */ + tasklet_init(&wl->tasklet, wl_dpc, (unsigned long) wl); + + + + base_addr = regs; + + if (bustype == PCI_BUS) { + wl->piomode = false; + } else if (bustype == RPC_BUS) { + /* Do nothing */ + } else { + bustype = PCI_BUS; + WL_TRACE("force to PCI\n"); + } + wl->bcm_bustype = bustype; + + wl->regsva = ioremap_nocache(base_addr, PCI_BAR0_WINSZ); + if (wl->regsva == NULL) { + WL_ERROR("wl%d: ioremap() failed\n", unit); + goto fail; + } + spin_lock_init(&wl->lock); + spin_lock_init(&wl->isr_lock); + + /* prepare ucode */ + if (wl_request_fw(wl, (struct pci_dev *)btparam)) { + printf("%s: Failed to find firmware usually in %s\n", + KBUILD_MODNAME, "/lib/firmware/brcm"); + wl_release_fw(wl); + wl_remove((struct pci_dev *)btparam); + goto fail1; + } + + /* common load-time initialization */ + wl->wlc = wlc_attach((void *)wl, vendor, device, unit, wl->piomode, osh, + wl->regsva, wl->bcm_bustype, btparam, &err); + wl_release_fw(wl); + if (!wl->wlc) { + printf("%s: wlc_attach() failed with code %d\n", + KBUILD_MODNAME, err); + goto fail; + } + wl->pub = wlc_pub(wl->wlc); + + wl->pub->ieee_hw = hw; + ASSERT(wl->pub->ieee_hw); + ASSERT(wl->pub->ieee_hw->priv == wl); + + + if (wlc_iovar_setint(wl->wlc, "mpc", 0)) { + WL_ERROR("wl%d: Error setting MPC variable to 0\n", unit); + } + + /* register our interrupt handler */ + if (request_irq(irq, wl_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { + WL_ERROR("wl%d: request_irq() failed\n", unit); + goto fail; + } + wl->irq = irq; + + /* register module */ + wlc_module_register(wl->pub, NULL, "linux", wl, NULL, wl_linux_watchdog, + NULL); + + if (ieee_hw_init(hw)) { + WL_ERROR("wl%d: %s: ieee_hw_init failed!\n", unit, __func__); + goto fail; + } + + bcopy(&wl->pub->cur_etheraddr, perm, ETH_ALEN); + ASSERT(is_valid_ether_addr(perm)); + SET_IEEE80211_PERM_ADDR(hw, perm); + + err = ieee80211_register_hw(hw); + if (err) { + WL_ERROR("%s: ieee80211_register_hw failed, status %d\n", + __func__, err); + } + + if (wl->pub->srom_ccode[0]) + err = wl_set_hint(wl, wl->pub->srom_ccode); + else + err = wl_set_hint(wl, "US"); + if (err) { + WL_ERROR("%s: regulatory_hint failed, status %d\n", + __func__, err); + } + WL_ERROR("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver (" PHY_VERSION_STR ")", + unit); + +#ifdef BCMDBG + printf(" (Compiled at " __TIME__ " on " __DATE__ ")"); +#endif /* BCMDBG */ + printf("\n"); + + wl_found++; + return wl; + + fail: + wl_free(wl); +fail1: + return NULL; +} + + + +#define CHAN2GHZ(channel, freqency, chflags) { \ + .band = IEEE80211_BAND_2GHZ, \ + .center_freq = (freqency), \ + .hw_value = (channel), \ + .flags = chflags, \ + .max_antenna_gain = 0, \ + .max_power = 19, \ +} + +static struct ieee80211_channel wl_2ghz_chantable[] = { + CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS), + CHAN2GHZ(2, 2417, IEEE80211_CHAN_NO_HT40MINUS), + CHAN2GHZ(3, 2422, IEEE80211_CHAN_NO_HT40MINUS), + CHAN2GHZ(4, 2427, IEEE80211_CHAN_NO_HT40MINUS), + CHAN2GHZ(5, 2432, 0), + CHAN2GHZ(6, 2437, 0), + CHAN2GHZ(7, 2442, 0), + CHAN2GHZ(8, 2447, IEEE80211_CHAN_NO_HT40PLUS), + CHAN2GHZ(9, 2452, IEEE80211_CHAN_NO_HT40PLUS), + CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS), + CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS), + CHAN2GHZ(12, 2467, + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_NO_HT40PLUS), + CHAN2GHZ(13, 2472, + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_NO_HT40PLUS), + CHAN2GHZ(14, 2484, + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS) +}; + +#define CHAN5GHZ(channel, chflags) { \ + .band = IEEE80211_BAND_5GHZ, \ + .center_freq = 5000 + 5*(channel), \ + .hw_value = (channel), \ + .flags = chflags, \ + .max_antenna_gain = 0, \ + .max_power = 21, \ +} + +static struct ieee80211_channel wl_5ghz_nphy_chantable[] = { + /* UNII-1 */ + CHAN5GHZ(36, IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(40, IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(44, IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS), + /* UNII-2 */ + CHAN5GHZ(52, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(56, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(60, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(64, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), + /* MID */ + CHAN5GHZ(100, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(104, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(108, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(112, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(116, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(120, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(124, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(128, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(132, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(136, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(140, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS | + IEEE80211_CHAN_NO_HT40MINUS), + /* UNII-3 */ + CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(153, IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(157, IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(161, IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(165, IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS) +}; + +#define RATE(rate100m, _flags) { \ + .bitrate = (rate100m), \ + .flags = (_flags), \ + .hw_value = (rate100m / 5), \ +} + +static struct ieee80211_rate wl_legacy_ratetable[] = { + RATE(10, 0), + RATE(20, IEEE80211_RATE_SHORT_PREAMBLE), + RATE(55, IEEE80211_RATE_SHORT_PREAMBLE), + RATE(110, IEEE80211_RATE_SHORT_PREAMBLE), + RATE(60, 0), + RATE(90, 0), + RATE(120, 0), + RATE(180, 0), + RATE(240, 0), + RATE(360, 0), + RATE(480, 0), + RATE(540, 0), +}; + +static struct ieee80211_supported_band wl_band_2GHz_nphy = { + .band = IEEE80211_BAND_2GHZ, + .channels = wl_2ghz_chantable, + .n_channels = ARRAY_SIZE(wl_2ghz_chantable), + .bitrates = wl_legacy_ratetable, + .n_bitrates = ARRAY_SIZE(wl_legacy_ratetable), + .ht_cap = { + /* from include/linux/ieee80211.h */ + .cap = IEEE80211_HT_CAP_GRN_FLD | + IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, + .ht_supported = true, + .ampdu_factor = AMPDU_RX_FACTOR_64K, + .ampdu_density = AMPDU_DEF_MPDU_DENSITY, + .mcs = { + /* placeholders for now */ + .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0}, + .rx_highest = 500, + .tx_params = IEEE80211_HT_MCS_TX_DEFINED} + } +}; + +static struct ieee80211_supported_band wl_band_5GHz_nphy = { + .band = IEEE80211_BAND_5GHZ, + .channels = wl_5ghz_nphy_chantable, + .n_channels = ARRAY_SIZE(wl_5ghz_nphy_chantable), + .bitrates = wl_legacy_ratetable + 4, + .n_bitrates = ARRAY_SIZE(wl_legacy_ratetable) - 4, + .ht_cap = { + /* use IEEE80211_HT_CAP_* from include/linux/ieee80211.h */ + .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, /* No 40 mhz yet */ + .ht_supported = true, + .ampdu_factor = AMPDU_RX_FACTOR_64K, + .ampdu_density = AMPDU_DEF_MPDU_DENSITY, + .mcs = { + /* placeholders for now */ + .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0}, + .rx_highest = 500, + .tx_params = IEEE80211_HT_MCS_TX_DEFINED} + } +}; + +static int ieee_hw_rate_init(struct ieee80211_hw *hw) +{ + struct wl_info *wl = HW_TO_WL(hw); + int has_5g; + char phy_list[4]; + + has_5g = 0; + + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL; + hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; + + if (wlc_get(wl->wlc, WLC_GET_PHYLIST, (int *)&phy_list) < 0) { + WL_ERROR("Phy list failed\n"); + } + WL_NONE("%s: phylist = %c\n", __func__, phy_list[0]); + + if (phy_list[0] == 'n' || phy_list[0] == 'c') { + if (phy_list[0] == 'c') { + /* Single stream */ + wl_band_2GHz_nphy.ht_cap.mcs.rx_mask[1] = 0; + wl_band_2GHz_nphy.ht_cap.mcs.rx_highest = 72; + } + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl_band_2GHz_nphy; + } else { + BUG(); + return -1; + } + + /* Assume all bands use the same phy. True for 11n devices. */ + if (NBANDS_PUB(wl->pub) > 1) { + has_5g++; + if (phy_list[0] == 'n' || phy_list[0] == 'c') { + hw->wiphy->bands[IEEE80211_BAND_5GHZ] = + &wl_band_5GHz_nphy; + } else { + return -1; + } + } + + WL_NONE("%s: 2ghz = %d, 5ghz = %d\n", __func__, 1, has_5g); + + return 0; +} + +static int ieee_hw_init(struct ieee80211_hw *hw) +{ + hw->flags = IEEE80211_HW_SIGNAL_DBM + /* | IEEE80211_HW_CONNECTION_MONITOR What is this? */ + | IEEE80211_HW_REPORTS_TX_ACK_STATUS + | IEEE80211_HW_AMPDU_AGGREGATION; + + hw->extra_tx_headroom = wlc_get_header_len(); + /* FIXME: should get this from wlc->machwcap */ + hw->queues = 4; + /* FIXME: this doesn't seem to be used properly in minstrel_ht. + * mac80211/status.c:ieee80211_tx_status() checks this value, + * but mac80211/rc80211_minstrel_ht.c:minstrel_ht_get_rate() + * appears to always set 3 rates + */ + hw->max_rates = 2; /* Primary rate and 1 fallback rate */ + + hw->channel_change_time = 7 * 1000; /* channel change time is dependant on chip and band */ + hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + + hw->rate_control_algorithm = "minstrel_ht"; + + hw->sta_data_size = sizeof(struct scb); + return ieee_hw_rate_init(hw); +} + +/** + * determines if a device is a WL device, and if so, attaches it. + * + * This function determines if a device pointed to by pdev is a WL device, + * and if so, performs a wl_attach() on it. + * + */ +int __devinit +wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int rc; + struct wl_info *wl; + struct ieee80211_hw *hw; + u32 val; + + ASSERT(pdev); + + WL_TRACE("%s: bus %d slot %d func %d irq %d\n", + __func__, pdev->bus->number, PCI_SLOT(pdev->devfn), + PCI_FUNC(pdev->devfn), pdev->irq); + + if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) || + (((pdev->device & 0xff00) != 0x4300) && + ((pdev->device & 0xff00) != 0x4700) && + ((pdev->device < 43000) || (pdev->device > 43999)))) + return -ENODEV; + + rc = pci_enable_device(pdev); + if (rc) { + WL_ERROR("%s: Cannot enable device %d-%d_%d\n", + __func__, pdev->bus->number, PCI_SLOT(pdev->devfn), + PCI_FUNC(pdev->devfn)); + return -ENODEV; + } + pci_set_master(pdev); + + pci_read_config_dword(pdev, 0x40, &val); + if ((val & 0x0000ff00) != 0) + pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); + + hw = ieee80211_alloc_hw(sizeof(struct wl_info), &wl_ops); + if (!hw) { + WL_ERROR("%s: ieee80211_alloc_hw failed\n", __func__); + rc = -ENOMEM; + goto err_1; + } + + SET_IEEE80211_DEV(hw, &pdev->dev); + + pci_set_drvdata(pdev, hw); + + memset(hw->priv, 0, sizeof(*wl)); + + wl = wl_attach(pdev->vendor, pdev->device, pci_resource_start(pdev, 0), + PCI_BUS, pdev, pdev->irq); + + if (!wl) { + WL_ERROR("%s: %s: wl_attach failed!\n", + KBUILD_MODNAME, __func__); + return -ENODEV; + } + return 0; + err_1: + WL_ERROR("%s: err_1: Major hoarkage\n", __func__); + return 0; +} + +#ifdef LINUXSTA_PS +static int wl_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct wl_info *wl; + struct ieee80211_hw *hw; + + WL_TRACE("wl: wl_suspend\n"); + + hw = pci_get_drvdata(pdev); + wl = HW_TO_WL(hw); + if (!wl) { + WL_ERROR("wl: wl_suspend: pci_get_drvdata failed\n"); + return -ENODEV; + } + + WL_LOCK(wl); + wl_down(wl); + wl->pub->hw_up = false; + WL_UNLOCK(wl); + pci_save_state(pdev, wl->pci_psstate); + pci_disable_device(pdev); + return pci_set_power_state(pdev, PCI_D3hot); +} + +static int wl_resume(struct pci_dev *pdev) +{ + struct wl_info *wl; + struct ieee80211_hw *hw; + int err = 0; + u32 val; + + WL_TRACE("wl: wl_resume\n"); + hw = pci_get_drvdata(pdev); + wl = HW_TO_WL(hw); + if (!wl) { + WL_ERROR("wl: wl_resume: pci_get_drvdata failed\n"); + return -ENODEV; + } + + err = pci_set_power_state(pdev, PCI_D0); + if (err) + return err; + + pci_restore_state(pdev, wl->pci_psstate); + + err = pci_enable_device(pdev); + if (err) + return err; + + pci_set_master(pdev); + + pci_read_config_dword(pdev, 0x40, &val); + if ((val & 0x0000ff00) != 0) + pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); + + WL_LOCK(wl); + err = wl_up(wl); + WL_UNLOCK(wl); + + return err; +} +#endif /* LINUXSTA_PS */ + +static void wl_remove(struct pci_dev *pdev) +{ + struct wl_info *wl; + struct ieee80211_hw *hw; + + hw = pci_get_drvdata(pdev); + wl = HW_TO_WL(hw); + if (!wl) { + WL_ERROR("wl: wl_remove: pci_get_drvdata failed\n"); + return; + } + if (!wlc_chipmatch(pdev->vendor, pdev->device)) { + WL_ERROR("wl: wl_remove: wlc_chipmatch failed\n"); + return; + } + if (wl->wlc) { + ieee80211_unregister_hw(hw); + WL_LOCK(wl); + wl_down(wl); + WL_UNLOCK(wl); + WL_NONE("%s: Down\n", __func__); + } + pci_disable_device(pdev); + + wl_free(wl); + + pci_set_drvdata(pdev, NULL); + ieee80211_free_hw(hw); +} + +static struct pci_driver wl_pci_driver = { + .name = "brcm80211", + .probe = wl_pci_probe, +#ifdef LINUXSTA_PS + .suspend = wl_suspend, + .resume = wl_resume, +#endif /* LINUXSTA_PS */ + .remove = __devexit_p(wl_remove), + .id_table = wl_id_table, +}; + +/** + * This is the main entry point for the WL driver. + * + * This function determines if a device pointed to by pdev is a WL device, + * and if so, performs a wl_attach() on it. + * + */ +static int __init wl_module_init(void) +{ + int error = -ENODEV; + +#ifdef BCMDBG + if (msglevel != 0xdeadbeef) + wl_msg_level = msglevel; + else { + char *var = getvar(NULL, "wl_msglevel"); + if (var) + wl_msg_level = simple_strtoul(var, NULL, 0); + } + { + extern u32 phyhal_msg_level; + + if (phymsglevel != 0xdeadbeef) + phyhal_msg_level = phymsglevel; + else { + char *var = getvar(NULL, "phy_msglevel"); + if (var) + phyhal_msg_level = simple_strtoul(var, NULL, 0); + } + } +#endif /* BCMDBG */ + + error = pci_register_driver(&wl_pci_driver); + if (!error) + return 0; + + + + return error; +} + +/** + * This function unloads the WL driver from the system. + * + * This function unconditionally unloads the WL driver module from the + * system. + * + */ +static void __exit wl_module_exit(void) +{ + pci_unregister_driver(&wl_pci_driver); + +} + +module_init(wl_module_init); +module_exit(wl_module_exit); + +/** + * This function frees the WL per-device resources. + * + * This function frees resources owned by the WL device pointed to + * by the wl parameter. + * + */ +void wl_free(struct wl_info *wl) +{ + wl_timer_t *t, *next; + struct osl_info *osh; + + ASSERT(wl); + /* free ucode data */ + if (wl->fw.fw_cnt) + wl_ucode_data_free(); + if (wl->irq) + free_irq(wl->irq, wl); + + /* kill dpc */ + tasklet_kill(&wl->tasklet); + + if (wl->pub) { + wlc_module_unregister(wl->pub, "linux", wl); + } + + /* free common resources */ + if (wl->wlc) { + wlc_detach(wl->wlc); + wl->wlc = NULL; + wl->pub = NULL; + } + + /* virtual interface deletion is deferred so we cannot spinwait */ + + /* wait for all pending callbacks to complete */ + while (atomic_read(&wl->callbacks) > 0) + schedule(); + + /* free timers */ + for (t = wl->timers; t; t = next) { + next = t->next; +#ifdef BCMDBG + if (t->name) + kfree(t->name); +#endif + kfree(t); + } + + osh = wl->osh; + + /* + * unregister_netdev() calls get_stats() which may read chip registers + * so we cannot unmap the chip registers until after calling unregister_netdev() . + */ + if (wl->regsva && wl->bcm_bustype != SDIO_BUS && + wl->bcm_bustype != JTAG_BUS) { + iounmap((void *)wl->regsva); + } + wl->regsva = NULL; + + + osl_detach(osh); +} + +/* transmit a packet */ +static int BCMFASTPATH wl_start(struct sk_buff *skb, struct wl_info *wl) +{ + if (!wl) + return -ENETDOWN; + + return wl_start_int(wl, WL_TO_HW(wl), skb); +} + +static int BCMFASTPATH +wl_start_int(struct wl_info *wl, struct ieee80211_hw *hw, struct sk_buff *skb) +{ + wlc_sendpkt_mac80211(wl->wlc, skb, hw); + return NETDEV_TX_OK; +} + +void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, + int prio) +{ + WL_ERROR("Shouldn't be here %s\n", __func__); +} + +void wl_init(struct wl_info *wl) +{ + WL_TRACE("wl%d: wl_init\n", wl->pub->unit); + + wl_reset(wl); + + wlc_init(wl->wlc); +} + +uint wl_reset(struct wl_info *wl) +{ + WL_TRACE("wl%d: wl_reset\n", wl->pub->unit); + + wlc_reset(wl->wlc); + + /* dpc will not be rescheduled */ + wl->resched = 0; + + return 0; +} + +/* + * These are interrupt on/off entry points. Disable interrupts + * during interrupt state transition. + */ +void BCMFASTPATH wl_intrson(struct wl_info *wl) +{ + unsigned long flags; + + INT_LOCK(wl, flags); + wlc_intrson(wl->wlc); + INT_UNLOCK(wl, flags); +} + +bool wl_alloc_dma_resources(struct wl_info *wl, uint addrwidth) +{ + return true; +} + +u32 BCMFASTPATH wl_intrsoff(struct wl_info *wl) +{ + unsigned long flags; + u32 status; + + INT_LOCK(wl, flags); + status = wlc_intrsoff(wl->wlc); + INT_UNLOCK(wl, flags); + return status; +} + +void wl_intrsrestore(struct wl_info *wl, u32 macintmask) +{ + unsigned long flags; + + INT_LOCK(wl, flags); + wlc_intrsrestore(wl->wlc, macintmask); + INT_UNLOCK(wl, flags); +} + +int wl_up(struct wl_info *wl) +{ + int error = 0; + + if (wl->pub->up) + return 0; + + error = wlc_up(wl->wlc); + + return error; +} + +void wl_down(struct wl_info *wl) +{ + uint callbacks, ret_val = 0; + + /* call common down function */ + ret_val = wlc_down(wl->wlc); + callbacks = atomic_read(&wl->callbacks) - ret_val; + + /* wait for down callbacks to complete */ + WL_UNLOCK(wl); + + /* For HIGH_only driver, it's important to actually schedule other work, + * not just spin wait since everything runs at schedule level + */ + SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000); + + WL_LOCK(wl); +} + +irqreturn_t BCMFASTPATH wl_isr(int irq, void *dev_id) +{ + struct wl_info *wl; + bool ours, wantdpc; + unsigned long flags; + + wl = (struct wl_info *) dev_id; + + WL_ISRLOCK(wl, flags); + + /* call common first level interrupt handler */ + ours = wlc_isr(wl->wlc, &wantdpc); + if (ours) { + /* if more to do... */ + if (wantdpc) { + + /* ...and call the second level interrupt handler */ + /* schedule dpc */ + ASSERT(wl->resched == false); + tasklet_schedule(&wl->tasklet); + } + } + + WL_ISRUNLOCK(wl, flags); + + return IRQ_RETVAL(ours); +} + +static void BCMFASTPATH wl_dpc(unsigned long data) +{ + struct wl_info *wl; + + wl = (struct wl_info *) data; + + WL_LOCK(wl); + + /* call the common second level interrupt handler */ + if (wl->pub->up) { + if (wl->resched) { + unsigned long flags; + + INT_LOCK(wl, flags); + wlc_intrsupd(wl->wlc); + INT_UNLOCK(wl, flags); + } + + wl->resched = wlc_dpc(wl->wlc, true); + } + + /* wlc_dpc() may bring the driver down */ + if (!wl->pub->up) + goto done; + + /* re-schedule dpc */ + if (wl->resched) + tasklet_schedule(&wl->tasklet); + else { + /* re-enable interrupts */ + wl_intrson(wl); + } + + done: + WL_UNLOCK(wl); +} + +static void wl_link_up(struct wl_info *wl, char *ifname) +{ + WL_ERROR("wl%d: link up (%s)\n", wl->pub->unit, ifname); +} + +static void wl_link_down(struct wl_info *wl, char *ifname) +{ + WL_ERROR("wl%d: link down (%s)\n", wl->pub->unit, ifname); +} + +void wl_event(struct wl_info *wl, char *ifname, wlc_event_t *e) +{ + + switch (e->event.event_type) { + case WLC_E_LINK: + case WLC_E_NDIS_LINK: + if (e->event.flags & WLC_EVENT_MSG_LINK) + wl_link_up(wl, ifname); + else + wl_link_down(wl, ifname); + break; + case WLC_E_RADIO: + break; + } +} + +static void wl_timer(unsigned long data) +{ + _wl_timer((wl_timer_t *) data); +} + +static void _wl_timer(wl_timer_t *t) +{ + WL_LOCK(t->wl); + + if (t->set) { + if (t->periodic) { + t->timer.expires = jiffies + t->ms * HZ / 1000; + atomic_inc(&t->wl->callbacks); + add_timer(&t->timer); + t->set = true; + } else + t->set = false; + + t->fn(t->arg); + } + + atomic_dec(&t->wl->callbacks); + + WL_UNLOCK(t->wl); +} + +wl_timer_t *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg), void *arg, + const char *name) +{ + wl_timer_t *t; + + t = kmalloc(sizeof(wl_timer_t), GFP_ATOMIC); + if (!t) { + WL_ERROR("wl%d: wl_init_timer: out of memory\n", wl->pub->unit); + return 0; + } + + memset(t, 0, sizeof(wl_timer_t)); + + init_timer(&t->timer); + t->timer.data = (unsigned long) t; + t->timer.function = wl_timer; + t->wl = wl; + t->fn = fn; + t->arg = arg; + t->next = wl->timers; + wl->timers = t; + +#ifdef BCMDBG + t->name = kmalloc(strlen(name) + 1, GFP_ATOMIC); + if (t->name) + strcpy(t->name, name); +#endif + + return t; +} + +/* BMAC_NOTE: Add timer adds only the kernel timer since it's going to be more accurate + * as well as it's easier to make it periodic + */ +void wl_add_timer(struct wl_info *wl, wl_timer_t *t, uint ms, int periodic) +{ +#ifdef BCMDBG + if (t->set) { + WL_ERROR("%s: Already set. Name: %s, per %d\n", + __func__, t->name, periodic); + } +#endif + ASSERT(!t->set); + + t->ms = ms; + t->periodic = (bool) periodic; + t->set = true; + t->timer.expires = jiffies + ms * HZ / 1000; + + atomic_inc(&wl->callbacks); + add_timer(&t->timer); +} + +/* return true if timer successfully deleted, false if still pending */ +bool wl_del_timer(struct wl_info *wl, wl_timer_t *t) +{ + if (t->set) { + t->set = false; + if (!del_timer(&t->timer)) { + return false; + } + atomic_dec(&wl->callbacks); + } + + return true; +} + +void wl_free_timer(struct wl_info *wl, wl_timer_t *t) +{ + wl_timer_t *tmp; + + /* delete the timer in case it is active */ + wl_del_timer(wl, t); + + if (wl->timers == t) { + wl->timers = wl->timers->next; +#ifdef BCMDBG + if (t->name) + kfree(t->name); +#endif + kfree(t); + return; + + } + + tmp = wl->timers; + while (tmp) { + if (tmp->next == t) { + tmp->next = t->next; +#ifdef BCMDBG + if (t->name) + kfree(t->name); +#endif + kfree(t); + return; + } + tmp = tmp->next; + } + +} + +static int wl_linux_watchdog(void *ctx) +{ + struct wl_info *wl = (struct wl_info *) ctx; + struct net_device_stats *stats = NULL; + uint id; + /* refresh stats */ + if (wl->pub->up) { + ASSERT(wl->stats_id < 2); + + id = 1 - wl->stats_id; + + stats = &wl->stats_watchdog[id]; + stats->rx_packets = WLCNTVAL(wl->pub->_cnt->rxframe); + stats->tx_packets = WLCNTVAL(wl->pub->_cnt->txframe); + stats->rx_bytes = WLCNTVAL(wl->pub->_cnt->rxbyte); + stats->tx_bytes = WLCNTVAL(wl->pub->_cnt->txbyte); + stats->rx_errors = WLCNTVAL(wl->pub->_cnt->rxerror); + stats->tx_errors = WLCNTVAL(wl->pub->_cnt->txerror); + stats->collisions = 0; + + stats->rx_length_errors = 0; + stats->rx_over_errors = WLCNTVAL(wl->pub->_cnt->rxoflo); + stats->rx_crc_errors = WLCNTVAL(wl->pub->_cnt->rxcrc); + stats->rx_frame_errors = 0; + stats->rx_fifo_errors = WLCNTVAL(wl->pub->_cnt->rxoflo); + stats->rx_missed_errors = 0; + + stats->tx_fifo_errors = WLCNTVAL(wl->pub->_cnt->txuflo); + + wl->stats_id = id; + + } + + return 0; +} + +struct wl_fw_hdr { + u32 offset; + u32 len; + u32 idx; +}; + +char *wl_firmwares[WL_MAX_FW] = { + "brcm/bcm43xx", + NULL +}; + +int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx) +{ + int i, entry; + const u8 *pdata; + struct wl_fw_hdr *hdr; + for (i = 0; i < wl->fw.fw_cnt; i++) { + hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data; + for (entry = 0; entry < wl->fw.hdr_num_entries[i]; + entry++, hdr++) { + if (hdr->idx == idx) { + pdata = wl->fw.fw_bin[i]->data + hdr->offset; + *pbuf = kmalloc(hdr->len, GFP_ATOMIC); + if (*pbuf == NULL) { + printf("fail to alloc %d bytes\n", + hdr->len); + } + bcopy(pdata, *pbuf, hdr->len); + return 0; + } + } + } + printf("ERROR: ucode buf tag:%d can not be found!\n", idx); + *pbuf = NULL; + return -1; +} + +int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx) +{ + int i, entry; + const u8 *pdata; + struct wl_fw_hdr *hdr; + for (i = 0; i < wl->fw.fw_cnt; i++) { + hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data; + for (entry = 0; entry < wl->fw.hdr_num_entries[i]; + entry++, hdr++) { + if (hdr->idx == idx) { + pdata = wl->fw.fw_bin[i]->data + hdr->offset; + ASSERT(hdr->len == 4); + *data = *((u32 *) pdata); + return 0; + } + } + } + printf("ERROR: ucode tag:%d can not be found!\n", idx); + return -1; +} + +static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) +{ + int status; + struct device *device = &pdev->dev; + char fw_name[100]; + int i; + + memset((void *)&wl->fw, 0, sizeof(struct wl_firmware)); + for (i = 0; i < WL_MAX_FW; i++) { + if (wl_firmwares[i] == NULL) + break; + sprintf(fw_name, "%s-%d.fw", wl_firmwares[i], + UCODE_LOADER_API_VER); + WL_NONE("request fw %s\n", fw_name); + status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); + if (status) { + printf("%s: fail to load firmware %s\n", + KBUILD_MODNAME, fw_name); + wl_release_fw(wl); + return status; + } + WL_NONE("request fw %s\n", fw_name); + sprintf(fw_name, "%s_hdr-%d.fw", wl_firmwares[i], + UCODE_LOADER_API_VER); + status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); + if (status) { + printf("%s: fail to load firmware %s\n", + KBUILD_MODNAME, fw_name); + wl_release_fw(wl); + return status; + } + wl->fw.hdr_num_entries[i] = + wl->fw.fw_hdr[i]->size / (sizeof(struct wl_fw_hdr)); + WL_NONE("request fw %s find: %d entries\n", + fw_name, wl->fw.hdr_num_entries[i]); + } + wl->fw.fw_cnt = i; + return wl_ucode_data_init(wl); +} + +void wl_ucode_free_buf(void *p) +{ + kfree(p); +} + +static void wl_release_fw(struct wl_info *wl) +{ + int i; + for (i = 0; i < WL_MAX_FW; i++) { + release_firmware(wl->fw.fw_bin[i]); + release_firmware(wl->fw.fw_hdr[i]); + } +} + + +/* + * checks validity of all firmware images loaded from user space + */ +int wl_check_firmwares(struct wl_info *wl) +{ + int i; + int entry; + int rc = 0; + const struct firmware *fw; + const struct firmware *fw_hdr; + struct wl_fw_hdr *ucode_hdr; + for (i = 0; i < WL_MAX_FW && rc == 0; i++) { + fw = wl->fw.fw_bin[i]; + fw_hdr = wl->fw.fw_hdr[i]; + if (fw == NULL && fw_hdr == NULL) { + break; + } else if (fw == NULL || fw_hdr == NULL) { + WL_ERROR("%s: invalid bin/hdr fw\n", __func__); + rc = -EBADF; + } else if (fw_hdr->size % sizeof(struct wl_fw_hdr)) { + WL_ERROR("%s: non integral fw hdr file size %d/%zu\n", + __func__, fw_hdr->size, + sizeof(struct wl_fw_hdr)); + rc = -EBADF; + } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) { + WL_ERROR("%s: out of bounds fw file size %d\n", + __func__, fw->size); + rc = -EBADF; + } else { + /* check if ucode section overruns firmware image */ + ucode_hdr = (struct wl_fw_hdr *)fw_hdr->data; + for (entry = 0; entry < wl->fw.hdr_num_entries[i] && rc; + entry++, ucode_hdr++) { + if (ucode_hdr->offset + ucode_hdr->len > + fw->size) { + WL_ERROR("%s: conflicting bin/hdr\n", + __func__); + rc = -EBADF; + } + } + } + } + if (rc == 0 && wl->fw.fw_cnt != i) { + WL_ERROR("%s: invalid fw_cnt=%d\n", __func__, wl->fw.fw_cnt); + rc = -EBADF; + } + return rc; +} + diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wl_mac80211.h b/drivers/staging/brcm80211/brcmsmac/sys/wl_mac80211.h new file mode 100644 index 000000000000..bb39b7705947 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wl_mac80211.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wl_mac80211_h_ +#define _wl_mac80211_h_ + +#include + +/* BMAC Note: High-only driver is no longer working in softirq context as it needs to block and + * sleep so perimeter lock has to be a semaphore instead of spinlock. This requires timers to be + * submitted to workqueue instead of being on kernel timer + */ +typedef struct wl_timer { + struct timer_list timer; + struct wl_info *wl; + void (*fn) (void *); + void *arg; /* argument to fn */ + uint ms; + bool periodic; + bool set; + struct wl_timer *next; +#ifdef BCMDBG + char *name; /* Description of the timer */ +#endif +} wl_timer_t; + +/* contortion to call functions at safe time */ +/* In 2.6.20 kernels work functions get passed a pointer to the struct work, so things + * will continue to work as long as the work structure is the first component of the task structure. + */ +typedef struct wl_task { + struct work_struct work; + void *context; +} wl_task_t; + +struct wl_if { + uint subunit; /* WDS/BSS unit */ + struct pci_dev *pci_dev; +}; + +#define WL_MAX_FW 4 +struct wl_firmware { + u32 fw_cnt; + const struct firmware *fw_bin[WL_MAX_FW]; + const struct firmware *fw_hdr[WL_MAX_FW]; + u32 hdr_num_entries[WL_MAX_FW]; +}; + +struct wl_info { + struct wlc_pub *pub; /* pointer to public wlc state */ + void *wlc; /* pointer to private common os-independent data */ + struct osl_info *osh; /* pointer to os handler */ + u32 magic; + + int irq; + + spinlock_t lock; /* per-device perimeter lock */ + spinlock_t isr_lock; /* per-device ISR synchronization lock */ + uint bcm_bustype; /* bus type */ + bool piomode; /* set from insmod argument */ + void *regsva; /* opaque chip registers virtual address */ + atomic_t callbacks; /* # outstanding callback functions */ + struct wl_timer *timers; /* timer cleanup queue */ + struct tasklet_struct tasklet; /* dpc tasklet */ + bool resched; /* dpc needs to be and is rescheduled */ +#ifdef LINUXSTA_PS + u32 pci_psstate[16]; /* pci ps-state save/restore */ +#endif + /* RPC, handle, lock, txq, workitem */ + uint stats_id; /* the current set of stats */ + /* ping-pong stats counters updated by Linux watchdog */ + struct net_device_stats stats_watchdog[2]; + struct wl_firmware fw; +}; + +#define WL_LOCK(wl) spin_lock_bh(&(wl)->lock) +#define WL_UNLOCK(wl) spin_unlock_bh(&(wl)->lock) + +/* locking from inside wl_isr */ +#define WL_ISRLOCK(wl, flags) do {spin_lock(&(wl)->isr_lock); (void)(flags); } while (0) +#define WL_ISRUNLOCK(wl, flags) do {spin_unlock(&(wl)->isr_lock); (void)(flags); } while (0) + +/* locking under WL_LOCK() to synchronize with wl_isr */ +#define INT_LOCK(wl, flags) spin_lock_irqsave(&(wl)->isr_lock, flags) +#define INT_UNLOCK(wl, flags) spin_unlock_irqrestore(&(wl)->isr_lock, flags) + +#ifndef PCI_D0 +#define PCI_D0 0 +#endif + +#ifndef PCI_D3hot +#define PCI_D3hot 3 +#endif + +/* exported functions */ + +extern irqreturn_t wl_isr(int irq, void *dev_id); + +extern int __devinit wl_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent); +extern void wl_free(struct wl_info *wl); +extern int wl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); + +#endif /* _wl_mac80211_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wl_ucode.h b/drivers/staging/brcm80211/brcmsmac/sys/wl_ucode.h new file mode 100644 index 000000000000..2a0f4028f6f3 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wl_ucode.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define MIN_FW_SIZE 40000 /* minimum firmware file size in bytes */ +#define MAX_FW_SIZE 150000 + +typedef struct d11init { + u16 addr; + u16 size; + u32 value; +} d11init_t; + +extern d11init_t *d11lcn0bsinitvals24; +extern d11init_t *d11lcn0initvals24; +extern d11init_t *d11lcn1bsinitvals24; +extern d11init_t *d11lcn1initvals24; +extern d11init_t *d11lcn2bsinitvals24; +extern d11init_t *d11lcn2initvals24; +extern d11init_t *d11n0absinitvals16; +extern d11init_t *d11n0bsinitvals16; +extern d11init_t *d11n0initvals16; +extern u32 *bcm43xx_16_mimo; +extern u32 bcm43xx_16_mimosz; +extern u32 *bcm43xx_24_lcn; +extern u32 bcm43xx_24_lcnsz; +extern u32 *bcm43xx_bommajor; +extern u32 *bcm43xx_bomminor; + +extern int wl_ucode_data_init(struct wl_info *wl); +extern void wl_ucode_data_free(void); + +extern int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, unsigned int idx); +extern int wl_ucode_init_uint(struct wl_info *wl, unsigned *data, + unsigned int idx); +extern void wl_ucode_free_buf(void *); +extern int wl_check_firmwares(struct wl_info *wl); diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wl_ucode_loader.c b/drivers/staging/brcm80211/brcmsmac/sys/wl_ucode_loader.c new file mode 100644 index 000000000000..23e10f3dec0d --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wl_ucode_loader.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + + + +d11init_t *d11lcn0bsinitvals24; +d11init_t *d11lcn0initvals24; +d11init_t *d11lcn1bsinitvals24; +d11init_t *d11lcn1initvals24; +d11init_t *d11lcn2bsinitvals24; +d11init_t *d11lcn2initvals24; +d11init_t *d11n0absinitvals16; +d11init_t *d11n0bsinitvals16; +d11init_t *d11n0initvals16; +u32 *bcm43xx_16_mimo; +u32 bcm43xx_16_mimosz; +u32 *bcm43xx_24_lcn; +u32 bcm43xx_24_lcnsz; +u32 *bcm43xx_bommajor; +u32 *bcm43xx_bomminor; + +int wl_ucode_data_init(struct wl_info *wl) +{ + int rc; + rc = wl_check_firmwares(wl); + if (rc < 0) + return rc; + wl_ucode_init_buf(wl, (void **)&d11lcn0bsinitvals24, + D11LCN0BSINITVALS24); + wl_ucode_init_buf(wl, (void **)&d11lcn0initvals24, D11LCN0INITVALS24); + wl_ucode_init_buf(wl, (void **)&d11lcn1bsinitvals24, + D11LCN1BSINITVALS24); + wl_ucode_init_buf(wl, (void **)&d11lcn1initvals24, D11LCN1INITVALS24); + wl_ucode_init_buf(wl, (void **)&d11lcn2bsinitvals24, + D11LCN2BSINITVALS24); + wl_ucode_init_buf(wl, (void **)&d11lcn2initvals24, D11LCN2INITVALS24); + wl_ucode_init_buf(wl, (void **)&d11n0absinitvals16, D11N0ABSINITVALS16); + wl_ucode_init_buf(wl, (void **)&d11n0bsinitvals16, D11N0BSINITVALS16); + wl_ucode_init_buf(wl, (void **)&d11n0initvals16, D11N0INITVALS16); + wl_ucode_init_buf(wl, (void **)&bcm43xx_16_mimo, + D11UCODE_OVERSIGHT16_MIMO); + wl_ucode_init_uint(wl, &bcm43xx_16_mimosz, D11UCODE_OVERSIGHT16_MIMOSZ); + wl_ucode_init_buf(wl, (void **)&bcm43xx_24_lcn, + D11UCODE_OVERSIGHT24_LCN); + wl_ucode_init_uint(wl, &bcm43xx_24_lcnsz, D11UCODE_OVERSIGHT24_LCNSZ); + wl_ucode_init_buf(wl, (void **)&bcm43xx_bommajor, + D11UCODE_OVERSIGHT_BOMMAJOR); + wl_ucode_init_buf(wl, (void **)&bcm43xx_bomminor, + D11UCODE_OVERSIGHT_BOMMINOR); + + return 0; +} + +void wl_ucode_data_free(void) +{ + wl_ucode_free_buf((void *)d11lcn0bsinitvals24); + wl_ucode_free_buf((void *)d11lcn0initvals24); + wl_ucode_free_buf((void *)d11lcn1bsinitvals24); + wl_ucode_free_buf((void *)d11lcn1initvals24); + wl_ucode_free_buf((void *)d11lcn2bsinitvals24); + wl_ucode_free_buf((void *)d11lcn2initvals24); + wl_ucode_free_buf((void *)d11n0absinitvals16); + wl_ucode_free_buf((void *)d11n0bsinitvals16); + wl_ucode_free_buf((void *)d11n0initvals16); + wl_ucode_free_buf((void *)bcm43xx_16_mimo); + wl_ucode_free_buf((void *)bcm43xx_24_lcn); + wl_ucode_free_buf((void *)bcm43xx_bommajor); + wl_ucode_free_buf((void *)bcm43xx_bomminor); + + return; +} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.c new file mode 100644 index 000000000000..7a9fdbb5daee --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.c @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, + uint *err, uint devid); +static void wlc_pub_mfree(struct osl_info *osh, struct wlc_pub *pub); +static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid); + +void *wlc_calloc(struct osl_info *osh, uint unit, uint size) +{ + void *item; + + item = kzalloc(size, GFP_ATOMIC); + if (item == NULL) + WL_ERROR("wl%d: %s: out of memory\n", unit, __func__); + return item; +} + +void wlc_tunables_init(wlc_tunables_t *tunables, uint devid) +{ + tunables->ntxd = NTXD; + tunables->nrxd = NRXD; + tunables->rxbufsz = RXBUFSZ; + tunables->nrxbufpost = NRXBUFPOST; + tunables->maxscb = MAXSCB; + tunables->ampdunummpdu = AMPDU_NUM_MPDU; + tunables->maxpktcb = MAXPKTCB; + tunables->maxucodebss = WLC_MAX_UCODE_BSS; + tunables->maxucodebss4 = WLC_MAX_UCODE_BSS4; + tunables->maxbss = MAXBSS; + tunables->datahiwat = WLC_DATAHIWAT; + tunables->ampdudatahiwat = WLC_AMPDUDATAHIWAT; + tunables->rxbnd = RXBND; + tunables->txsbnd = TXSBND; +} + +static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, + uint *err, uint devid) +{ + struct wlc_pub *pub; + + pub = (struct wlc_pub *) wlc_calloc(osh, unit, sizeof(struct wlc_pub)); + if (pub == NULL) { + *err = 1001; + goto fail; + } + + pub->tunables = (wlc_tunables_t *)wlc_calloc(osh, unit, + sizeof(wlc_tunables_t)); + if (pub->tunables == NULL) { + *err = 1028; + goto fail; + } + + /* need to init the tunables now */ + wlc_tunables_init(pub->tunables, devid); + + pub->multicast = (u8 *)wlc_calloc(osh, unit, + (ETH_ALEN * MAXMULTILIST)); + if (pub->multicast == NULL) { + *err = 1003; + goto fail; + } + + return pub; + + fail: + wlc_pub_mfree(osh, pub); + return NULL; +} + +static void wlc_pub_mfree(struct osl_info *osh, struct wlc_pub *pub) +{ + if (pub == NULL) + return; + + if (pub->multicast) + kfree(pub->multicast); + if (pub->tunables) { + kfree(pub->tunables); + pub->tunables = NULL; + } + + kfree(pub); +} + +wlc_bsscfg_t *wlc_bsscfg_malloc(struct osl_info *osh, uint unit) +{ + wlc_bsscfg_t *cfg; + + cfg = (wlc_bsscfg_t *) wlc_calloc(osh, unit, sizeof(wlc_bsscfg_t)); + if (cfg == NULL) + goto fail; + + cfg->current_bss = (wlc_bss_info_t *)wlc_calloc(osh, unit, + sizeof(wlc_bss_info_t)); + if (cfg->current_bss == NULL) + goto fail; + + return cfg; + + fail: + wlc_bsscfg_mfree(osh, cfg); + return NULL; +} + +void wlc_bsscfg_mfree(struct osl_info *osh, wlc_bsscfg_t *cfg) +{ + if (cfg == NULL) + return; + + if (cfg->maclist) { + kfree(cfg->maclist); + cfg->maclist = NULL; + } + + if (cfg->current_bss != NULL) { + wlc_bss_info_t *current_bss = cfg->current_bss; + kfree(current_bss); + cfg->current_bss = NULL; + } + + kfree(cfg); +} + +void wlc_bsscfg_ID_assign(struct wlc_info *wlc, wlc_bsscfg_t *bsscfg) +{ + bsscfg->ID = wlc->next_bsscfg_ID; + wlc->next_bsscfg_ID++; +} + +/* + * The common driver entry routine. Error codes should be unique + */ +struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, + uint devid) +{ + struct wlc_info *wlc; + + wlc = (struct wlc_info *) wlc_calloc(osh, unit, + sizeof(struct wlc_info)); + if (wlc == NULL) { + *err = 1002; + goto fail; + } + + wlc->hwrxoff = WL_HWRXOFF; + + /* allocate struct wlc_pub state structure */ + wlc->pub = wlc_pub_malloc(osh, unit, err, devid); + if (wlc->pub == NULL) { + *err = 1003; + goto fail; + } + wlc->pub->wlc = wlc; + + /* allocate struct wlc_hw_info state structure */ + + wlc->hw = (struct wlc_hw_info *)wlc_calloc(osh, unit, + sizeof(struct wlc_hw_info)); + if (wlc->hw == NULL) { + *err = 1005; + goto fail; + } + wlc->hw->wlc = wlc; + + wlc->hw->bandstate[0] = (wlc_hwband_t *)wlc_calloc(osh, unit, + (sizeof(wlc_hwband_t) * MAXBANDS)); + if (wlc->hw->bandstate[0] == NULL) { + *err = 1006; + goto fail; + } else { + int i; + + for (i = 1; i < MAXBANDS; i++) { + wlc->hw->bandstate[i] = (wlc_hwband_t *) + ((unsigned long)wlc->hw->bandstate[0] + + (sizeof(wlc_hwband_t) * i)); + } + } + + wlc->modulecb = (modulecb_t *)wlc_calloc(osh, unit, + sizeof(modulecb_t) * WLC_MAXMODULES); + if (wlc->modulecb == NULL) { + *err = 1009; + goto fail; + } + + wlc->default_bss = (wlc_bss_info_t *)wlc_calloc(osh, unit, + sizeof(wlc_bss_info_t)); + if (wlc->default_bss == NULL) { + *err = 1010; + goto fail; + } + + wlc->cfg = wlc_bsscfg_malloc(osh, unit); + if (wlc->cfg == NULL) { + *err = 1011; + goto fail; + } + wlc_bsscfg_ID_assign(wlc, wlc->cfg); + + wlc->pkt_callback = (pkt_cb_t *)wlc_calloc(osh, unit, + (sizeof(pkt_cb_t) * (wlc->pub->tunables->maxpktcb + 1))); + if (wlc->pkt_callback == NULL) { + *err = 1013; + goto fail; + } + + wlc->wsec_def_keys[0] = (wsec_key_t *)wlc_calloc(osh, unit, + (sizeof(wsec_key_t) * WLC_DEFAULT_KEYS)); + if (wlc->wsec_def_keys[0] == NULL) { + *err = 1015; + goto fail; + } else { + int i; + for (i = 1; i < WLC_DEFAULT_KEYS; i++) { + wlc->wsec_def_keys[i] = (wsec_key_t *) + ((unsigned long)wlc->wsec_def_keys[0] + + (sizeof(wsec_key_t) * i)); + } + } + + wlc->protection = (wlc_protection_t *)wlc_calloc(osh, unit, + sizeof(wlc_protection_t)); + if (wlc->protection == NULL) { + *err = 1016; + goto fail; + } + + wlc->stf = (wlc_stf_t *)wlc_calloc(osh, unit, sizeof(wlc_stf_t)); + if (wlc->stf == NULL) { + *err = 1017; + goto fail; + } + + wlc->bandstate[0] = (struct wlcband *)wlc_calloc(osh, unit, + (sizeof(struct wlcband)*MAXBANDS)); + if (wlc->bandstate[0] == NULL) { + *err = 1025; + goto fail; + } else { + int i; + + for (i = 1; i < MAXBANDS; i++) { + wlc->bandstate[i] = + (struct wlcband *) ((unsigned long)wlc->bandstate[0] + + (sizeof(struct wlcband)*i)); + } + } + + wlc->corestate = (struct wlccore *)wlc_calloc(osh, unit, + sizeof(struct wlccore)); + if (wlc->corestate == NULL) { + *err = 1026; + goto fail; + } + + wlc->corestate->macstat_snapshot = + (macstat_t *)wlc_calloc(osh, unit, sizeof(macstat_t)); + if (wlc->corestate->macstat_snapshot == NULL) { + *err = 1027; + goto fail; + } + + return wlc; + + fail: + wlc_detach_mfree(wlc, osh); + return NULL; +} + +void wlc_detach_mfree(struct wlc_info *wlc, struct osl_info *osh) +{ + if (wlc == NULL) + return; + + if (wlc->modulecb) { + kfree(wlc->modulecb); + wlc->modulecb = NULL; + } + + if (wlc->default_bss) { + kfree(wlc->default_bss); + wlc->default_bss = NULL; + } + if (wlc->cfg) { + wlc_bsscfg_mfree(osh, wlc->cfg); + wlc->cfg = NULL; + } + + if (wlc->pkt_callback && wlc->pub && wlc->pub->tunables) { + kfree(wlc->pkt_callback); + wlc->pkt_callback = NULL; + } + + if (wlc->wsec_def_keys[0]) + kfree(wlc->wsec_def_keys[0]); + if (wlc->protection) { + kfree(wlc->protection); + wlc->protection = NULL; + } + + if (wlc->stf) { + kfree(wlc->stf); + wlc->stf = NULL; + } + + if (wlc->bandstate[0]) + kfree(wlc->bandstate[0]); + + if (wlc->corestate) { + if (wlc->corestate->macstat_snapshot) { + kfree(wlc->corestate->macstat_snapshot); wlc->corestate->macstat_snapshot = NULL; + } + kfree(wlc->corestate); + wlc->corestate = NULL; + } + + if (wlc->pub) { + /* free pub struct */ + wlc_pub_mfree(osh, wlc->pub); + wlc->pub = NULL; + } + + if (wlc->hw) { + if (wlc->hw->bandstate[0]) { + kfree(wlc->hw->bandstate[0]); + wlc->hw->bandstate[0] = NULL; + } + + /* free hw struct */ + kfree(wlc->hw); + wlc->hw = NULL; + } + + /* free the wlc */ + kfree(wlc); + wlc = NULL; +} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.h new file mode 100644 index 000000000000..ac34f782b400 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +extern void *wlc_calloc(struct osl_info *osh, uint unit, uint size); + +extern struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, + uint *err, uint devid); +extern void wlc_detach_mfree(struct wlc_info *wlc, struct osl_info *osh); + +struct wlc_bsscfg; +extern struct wlc_bsscfg *wlc_bsscfg_malloc(struct osl_info *osh, uint unit); +extern void wlc_bsscfg_mfree(struct osl_info *osh, struct wlc_bsscfg *cfg); diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.c new file mode 100644 index 000000000000..8e1011203481 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.c @@ -0,0 +1,1356 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define AMPDU_MAX_MPDU 32 /* max number of mpdus in an ampdu */ +#define AMPDU_NUM_MPDU_LEGACY 16 /* max number of mpdus in an ampdu to a legacy */ +#define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */ +#define AMPDU_TX_BA_DEF_WSIZE 64 /* default Tx ba window size (in pdu) */ +#define AMPDU_RX_BA_DEF_WSIZE 64 /* max Rx ba window size (in pdu) */ +#define AMPDU_RX_BA_MAX_WSIZE 64 /* default Rx ba window size (in pdu) */ +#define AMPDU_MAX_DUR 5 /* max dur of tx ampdu (in msec) */ +#define AMPDU_DEF_RETRY_LIMIT 5 /* default tx retry limit */ +#define AMPDU_DEF_RR_RETRY_LIMIT 2 /* default tx retry limit at reg rate */ +#define AMPDU_DEF_TXPKT_WEIGHT 2 /* default weight of ampdu in txfifo */ +#define AMPDU_DEF_FFPLD_RSVD 2048 /* default ffpld reserved bytes */ +#define AMPDU_INI_FREE 10 /* # of inis to be freed on detach */ +#define AMPDU_SCB_MAX_RELEASE 20 /* max # of mpdus released at a time */ + +#define NUM_FFPLD_FIFO 4 /* number of fifo concerned by pre-loading */ +#define FFPLD_TX_MAX_UNFL 200 /* default value of the average number of ampdu + * without underflows + */ +#define FFPLD_MPDU_SIZE 1800 /* estimate of maximum mpdu size */ +#define FFPLD_MAX_MCS 23 /* we don't deal with mcs 32 */ +#define FFPLD_PLD_INCR 1000 /* increments in bytes */ +#define FFPLD_MAX_AMPDU_CNT 5000 /* maximum number of ampdu we + * accumulate between resets. + */ + +#define TX_SEQ_TO_INDEX(seq) ((seq) % AMPDU_TX_BA_MAX_WSIZE) + +/* max possible overhead per mpdu in the ampdu; 3 is for roundup if needed */ +#define AMPDU_MAX_MPDU_OVERHEAD (FCS_LEN + DOT11_ICV_AES_LEN +\ + AMPDU_DELIMITER_LEN + 3\ + + DOT11_A4_HDR_LEN + DOT11_QOS_LEN + DOT11_IV_MAX_LEN) + +#ifdef BCMDBG +u32 wl_ampdu_dbg = + WL_AMPDU_UPDN_VAL | + WL_AMPDU_ERR_VAL | + WL_AMPDU_TX_VAL | + WL_AMPDU_RX_VAL | + WL_AMPDU_CTL_VAL | + WL_AMPDU_HW_VAL | WL_AMPDU_HWTXS_VAL | WL_AMPDU_HWDBG_VAL; +#endif + +/* structure to hold tx fifo information and pre-loading state + * counters specific to tx underflows of ampdus + * some counters might be redundant with the ones in wlc or ampdu structures. + * This allows to maintain a specific state independantly of + * how often and/or when the wlc counters are updated. + */ +typedef struct wlc_fifo_info { + u16 ampdu_pld_size; /* number of bytes to be pre-loaded */ + u8 mcs2ampdu_table[FFPLD_MAX_MCS + 1]; /* per-mcs max # of mpdus in an ampdu */ + u16 prev_txfunfl; /* num of underflows last read from the HW macstats counter */ + u32 accum_txfunfl; /* num of underflows since we modified pld params */ + u32 accum_txampdu; /* num of tx ampdu since we modified pld params */ + u32 prev_txampdu; /* previous reading of tx ampdu */ + u32 dmaxferrate; /* estimated dma avg xfer rate in kbits/sec */ +} wlc_fifo_info_t; + +/* AMPDU module specific state */ +struct ampdu_info { + struct wlc_info *wlc; /* pointer to main wlc structure */ + int scb_handle; /* scb cubby handle to retrieve data from scb */ + u8 ini_enable[AMPDU_MAX_SCB_TID]; /* per-tid initiator enable/disable of ampdu */ + u8 ba_tx_wsize; /* Tx ba window size (in pdu) */ + u8 ba_rx_wsize; /* Rx ba window size (in pdu) */ + u8 retry_limit; /* mpdu transmit retry limit */ + u8 rr_retry_limit; /* mpdu transmit retry limit at regular rate */ + u8 retry_limit_tid[AMPDU_MAX_SCB_TID]; /* per-tid mpdu transmit retry limit */ + /* per-tid mpdu transmit retry limit at regular rate */ + u8 rr_retry_limit_tid[AMPDU_MAX_SCB_TID]; + u8 mpdu_density; /* min mpdu spacing (0-7) ==> 2^(x-1)/8 usec */ + s8 max_pdu; /* max pdus allowed in ampdu */ + u8 dur; /* max duration of an ampdu (in msec) */ + u8 txpkt_weight; /* weight of ampdu in txfifo; reduces rate lag */ + u8 rx_factor; /* maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes */ + u32 ffpld_rsvd; /* number of bytes to reserve for preload */ + u32 max_txlen[MCS_TABLE_SIZE][2][2]; /* max size of ampdu per mcs, bw and sgi */ + void *ini_free[AMPDU_INI_FREE]; /* array of ini's to be freed on detach */ + bool mfbr; /* enable multiple fallback rate */ + u32 tx_max_funl; /* underflows should be kept such that + * (tx_max_funfl*underflows) < tx frames + */ + wlc_fifo_info_t fifo_tb[NUM_FFPLD_FIFO]; /* table of fifo infos */ + +}; + +#define AMPDU_CLEANUPFLAG_RX (0x1) +#define AMPDU_CLEANUPFLAG_TX (0x2) + +#define SCB_AMPDU_CUBBY(ampdu, scb) (&(scb->scb_ampdu)) +#define SCB_AMPDU_INI(scb_ampdu, tid) (&(scb_ampdu->ini[tid])) + +static void wlc_ffpld_init(struct ampdu_info *ampdu); +static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int f); +static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f); + +static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu, + scb_ampdu_t *scb_ampdu, + u8 tid, bool override); +static void ampdu_cleanup_tid_ini(struct ampdu_info *ampdu, + scb_ampdu_t *scb_ampdu, + u8 tid, bool force); +static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur); +static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb); +static void scb_ampdu_update_config_all(struct ampdu_info *ampdu); + +#define wlc_ampdu_txflowcontrol(a, b, c) do {} while (0) + +static void wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, + struct scb *scb, + struct sk_buff *p, tx_status_t *txs, + u32 frmtxstatus, u32 frmtxstatus2); + +static inline u16 pkt_txh_seqnum(struct wlc_info *wlc, struct sk_buff *p) +{ + d11txh_t *txh; + struct ieee80211_hdr *h; + txh = (d11txh_t *) p->data; + h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); + return ltoh16(h->seq_ctrl) >> SEQNUM_SHIFT; +} + +struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc) +{ + struct ampdu_info *ampdu; + int i; + + /* some code depends on packed structures */ + ASSERT(DOT11_MAXNUMFRAGS == NBITS(u16)); + ASSERT(ISPOWEROF2(AMPDU_TX_BA_MAX_WSIZE)); + ASSERT(ISPOWEROF2(AMPDU_RX_BA_MAX_WSIZE)); + ASSERT(wlc->pub->tunables->ampdunummpdu <= AMPDU_MAX_MPDU); + ASSERT(wlc->pub->tunables->ampdunummpdu > 0); + + ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC); + if (!ampdu) { + WL_ERROR("wl%d: wlc_ampdu_attach: out of mem\n", + wlc->pub->unit); + return NULL; + } + ampdu->wlc = wlc; + + for (i = 0; i < AMPDU_MAX_SCB_TID; i++) + ampdu->ini_enable[i] = true; + /* Disable ampdu for VO by default */ + ampdu->ini_enable[PRIO_8021D_VO] = false; + ampdu->ini_enable[PRIO_8021D_NC] = false; + + /* Disable ampdu for BK by default since not enough fifo space */ + ampdu->ini_enable[PRIO_8021D_NONE] = false; + ampdu->ini_enable[PRIO_8021D_BK] = false; + + ampdu->ba_tx_wsize = AMPDU_TX_BA_DEF_WSIZE; + ampdu->ba_rx_wsize = AMPDU_RX_BA_DEF_WSIZE; + ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY; + ampdu->max_pdu = AUTO; + ampdu->dur = AMPDU_MAX_DUR; + ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT; + + ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD; + /* bump max ampdu rcv size to 64k for all 11n devices except 4321A0 and 4321A1 */ + if (WLCISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2)) + ampdu->rx_factor = AMPDU_RX_FACTOR_32K; + else + ampdu->rx_factor = AMPDU_RX_FACTOR_64K; + ampdu->retry_limit = AMPDU_DEF_RETRY_LIMIT; + ampdu->rr_retry_limit = AMPDU_DEF_RR_RETRY_LIMIT; + + for (i = 0; i < AMPDU_MAX_SCB_TID; i++) { + ampdu->retry_limit_tid[i] = ampdu->retry_limit; + ampdu->rr_retry_limit_tid[i] = ampdu->rr_retry_limit; + } + + ampdu_update_max_txlen(ampdu, ampdu->dur); + ampdu->mfbr = false; + /* try to set ampdu to the default value */ + wlc_ampdu_set(ampdu, wlc->pub->_ampdu); + + ampdu->tx_max_funl = FFPLD_TX_MAX_UNFL; + wlc_ffpld_init(ampdu); + + return ampdu; +} + +void wlc_ampdu_detach(struct ampdu_info *ampdu) +{ + int i; + + if (!ampdu) + return; + + /* free all ini's which were to be freed on callbacks which were never called */ + for (i = 0; i < AMPDU_INI_FREE; i++) { + if (ampdu->ini_free[i]) { + kfree(ampdu->ini_free[i]); + } + } + + wlc_module_unregister(ampdu->wlc->pub, "ampdu", ampdu); + kfree(ampdu); +} + +void scb_ampdu_cleanup(struct ampdu_info *ampdu, struct scb *scb) +{ + scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); + u8 tid; + + WL_AMPDU_UPDN("scb_ampdu_cleanup: enter\n"); + ASSERT(scb_ampdu); + + for (tid = 0; tid < AMPDU_MAX_SCB_TID; tid++) { + ampdu_cleanup_tid_ini(ampdu, scb_ampdu, tid, false); + } +} + +/* reset the ampdu state machine so that it can gracefully handle packets that were + * freed from the dma and tx queues during reinit + */ +void wlc_ampdu_reset(struct ampdu_info *ampdu) +{ + WL_NONE("%s: Entering\n", __func__); +} + +static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb) +{ + scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); + int i; + + scb_ampdu->max_pdu = (u8) ampdu->wlc->pub->tunables->ampdunummpdu; + + /* go back to legacy size if some preloading is occuring */ + for (i = 0; i < NUM_FFPLD_FIFO; i++) { + if (ampdu->fifo_tb[i].ampdu_pld_size > FFPLD_PLD_INCR) + scb_ampdu->max_pdu = AMPDU_NUM_MPDU_LEGACY; + } + + /* apply user override */ + if (ampdu->max_pdu != AUTO) + scb_ampdu->max_pdu = (u8) ampdu->max_pdu; + + scb_ampdu->release = min_t(u8, scb_ampdu->max_pdu, AMPDU_SCB_MAX_RELEASE); + + if (scb_ampdu->max_rxlen) + scb_ampdu->release = + min_t(u8, scb_ampdu->release, scb_ampdu->max_rxlen / 1600); + + scb_ampdu->release = min(scb_ampdu->release, + ampdu->fifo_tb[TX_AC_BE_FIFO]. + mcs2ampdu_table[FFPLD_MAX_MCS]); + + ASSERT(scb_ampdu->release); +} + +void scb_ampdu_update_config_all(struct ampdu_info *ampdu) +{ + scb_ampdu_update_config(ampdu, ampdu->wlc->pub->global_scb); +} + +static void wlc_ffpld_init(struct ampdu_info *ampdu) +{ + int i, j; + wlc_fifo_info_t *fifo; + + for (j = 0; j < NUM_FFPLD_FIFO; j++) { + fifo = (ampdu->fifo_tb + j); + fifo->ampdu_pld_size = 0; + for (i = 0; i <= FFPLD_MAX_MCS; i++) + fifo->mcs2ampdu_table[i] = 255; + fifo->dmaxferrate = 0; + fifo->accum_txampdu = 0; + fifo->prev_txfunfl = 0; + fifo->accum_txfunfl = 0; + + } +} + +/* evaluate the dma transfer rate using the tx underflows as feedback. + * If necessary, increase tx fifo preloading. If not enough, + * decrease maximum ampdu size for each mcs till underflows stop + * Return 1 if pre-loading not active, -1 if not an underflow event, + * 0 if pre-loading module took care of the event. + */ +static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) +{ + struct ampdu_info *ampdu = wlc->ampdu; + u32 phy_rate = MCS_RATE(FFPLD_MAX_MCS, true, false); + u32 txunfl_ratio; + u8 max_mpdu; + u32 current_ampdu_cnt = 0; + u16 max_pld_size; + u32 new_txunfl; + wlc_fifo_info_t *fifo = (ampdu->fifo_tb + fid); + uint xmtfifo_sz; + u16 cur_txunfl; + + /* return if we got here for a different reason than underflows */ + cur_txunfl = + wlc_read_shm(wlc, + M_UCODE_MACSTAT + offsetof(macstat_t, txfunfl[fid])); + new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl); + if (new_txunfl == 0) { + WL_FFPLD("check_txunfl : TX status FRAG set but no tx underflows\n"); + return -1; + } + fifo->prev_txfunfl = cur_txunfl; + + if (!ampdu->tx_max_funl) + return 1; + + /* check if fifo is big enough */ + if (wlc_xmtfifo_sz_get(wlc, fid, &xmtfifo_sz)) { + WL_FFPLD("check_txunfl : get xmtfifo_sz failed\n"); + return -1; + } + + if ((TXFIFO_SIZE_UNIT * (u32) xmtfifo_sz) <= ampdu->ffpld_rsvd) + return 1; + + max_pld_size = TXFIFO_SIZE_UNIT * xmtfifo_sz - ampdu->ffpld_rsvd; + fifo->accum_txfunfl += new_txunfl; + + /* we need to wait for at least 10 underflows */ + if (fifo->accum_txfunfl < 10) + return 0; + + WL_FFPLD("ampdu_count %d tx_underflows %d\n", + current_ampdu_cnt, fifo->accum_txfunfl); + + /* + compute the current ratio of tx unfl per ampdu. + When the current ampdu count becomes too + big while the ratio remains small, we reset + the current count in order to not + introduce too big of a latency in detecting a + large amount of tx underflows later. + */ + + txunfl_ratio = current_ampdu_cnt / fifo->accum_txfunfl; + + if (txunfl_ratio > ampdu->tx_max_funl) { + if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT) { + fifo->accum_txfunfl = 0; + } + return 0; + } + max_mpdu = + min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY); + + /* In case max value max_pdu is already lower than + the fifo depth, there is nothing more we can do. + */ + + if (fifo->ampdu_pld_size >= max_mpdu * FFPLD_MPDU_SIZE) { + WL_FFPLD(("tx fifo pld : max ampdu fits in fifo\n)")); + fifo->accum_txfunfl = 0; + return 0; + } + + if (fifo->ampdu_pld_size < max_pld_size) { + + /* increment by TX_FIFO_PLD_INC bytes */ + fifo->ampdu_pld_size += FFPLD_PLD_INCR; + if (fifo->ampdu_pld_size > max_pld_size) + fifo->ampdu_pld_size = max_pld_size; + + /* update scb release size */ + scb_ampdu_update_config_all(ampdu); + + /* + compute a new dma xfer rate for max_mpdu @ max mcs. + This is the minimum dma rate that + can acheive no unferflow condition for the current mpdu size. + */ + /* note : we divide/multiply by 100 to avoid integer overflows */ + fifo->dmaxferrate = + (((phy_rate / 100) * + (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size)) + / (max_mpdu * FFPLD_MPDU_SIZE)) * 100; + + WL_FFPLD("DMA estimated transfer rate %d; pre-load size %d\n", + fifo->dmaxferrate, fifo->ampdu_pld_size); + } else { + + /* decrease ampdu size */ + if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] > 1) { + if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] == 255) + fifo->mcs2ampdu_table[FFPLD_MAX_MCS] = + AMPDU_NUM_MPDU_LEGACY - 1; + else + fifo->mcs2ampdu_table[FFPLD_MAX_MCS] -= 1; + + /* recompute the table */ + wlc_ffpld_calc_mcs2ampdu_table(ampdu, fid); + + /* update scb release size */ + scb_ampdu_update_config_all(ampdu); + } + } + fifo->accum_txfunfl = 0; + return 0; +} + +static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f) +{ + int i; + u32 phy_rate, dma_rate, tmp; + u8 max_mpdu; + wlc_fifo_info_t *fifo = (ampdu->fifo_tb + f); + + /* recompute the dma rate */ + /* note : we divide/multiply by 100 to avoid integer overflows */ + max_mpdu = + min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY); + phy_rate = MCS_RATE(FFPLD_MAX_MCS, true, false); + dma_rate = + (((phy_rate / 100) * + (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size)) + / (max_mpdu * FFPLD_MPDU_SIZE)) * 100; + fifo->dmaxferrate = dma_rate; + + /* fill up the mcs2ampdu table; do not recalc the last mcs */ + dma_rate = dma_rate >> 7; + for (i = 0; i < FFPLD_MAX_MCS; i++) { + /* shifting to keep it within integer range */ + phy_rate = MCS_RATE(i, true, false) >> 7; + if (phy_rate > dma_rate) { + tmp = ((fifo->ampdu_pld_size * phy_rate) / + ((phy_rate - dma_rate) * FFPLD_MPDU_SIZE)) + 1; + tmp = min_t(u32, tmp, 255); + fifo->mcs2ampdu_table[i] = (u8) tmp; + } + } +} + +static void BCMFASTPATH +wlc_ampdu_agg(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p, + uint prec) +{ + scb_ampdu_t *scb_ampdu; + scb_ampdu_tid_ini_t *ini; + u8 tid = (u8) (p->priority); + + scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); + + /* initialize initiator on first packet; sends addba req */ + ini = SCB_AMPDU_INI(scb_ampdu, tid); + if (ini->magic != INI_MAGIC) { + ini = wlc_ampdu_init_tid_ini(ampdu, scb_ampdu, tid, false); + } + return; +} + +int BCMFASTPATH +wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, + struct sk_buff **pdu, int prec) +{ + struct wlc_info *wlc; + struct osl_info *osh; + struct sk_buff *p, *pkt[AMPDU_MAX_MPDU]; + u8 tid, ndelim; + int err = 0; + u8 preamble_type = WLC_GF_PREAMBLE; + u8 fbr_preamble_type = WLC_GF_PREAMBLE; + u8 rts_preamble_type = WLC_LONG_PREAMBLE; + u8 rts_fbr_preamble_type = WLC_LONG_PREAMBLE; + + bool rr = true, fbr = false; + uint i, count = 0, fifo, seg_cnt = 0; + u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0; + u32 ampdu_len, maxlen = 0; + d11txh_t *txh = NULL; + u8 *plcp; + struct ieee80211_hdr *h; + struct scb *scb; + scb_ampdu_t *scb_ampdu; + scb_ampdu_tid_ini_t *ini; + u8 mcs = 0; + bool use_rts = false, use_cts = false; + ratespec_t rspec = 0, rspec_fallback = 0; + ratespec_t rts_rspec = 0, rts_rspec_fallback = 0; + u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; + struct ieee80211_rts *rts; + u8 rr_retry_limit; + wlc_fifo_info_t *f; + bool fbr_iscck; + struct ieee80211_tx_info *tx_info; + u16 qlen; + + wlc = ampdu->wlc; + osh = wlc->osh; + p = *pdu; + + ASSERT(p); + + tid = (u8) (p->priority); + ASSERT(tid < AMPDU_MAX_SCB_TID); + + f = ampdu->fifo_tb + prio2fifo[tid]; + + scb = wlc->pub->global_scb; + ASSERT(scb->magic == SCB_MAGIC); + + scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); + ASSERT(scb_ampdu); + ini = &scb_ampdu->ini[tid]; + + /* Let pressure continue to build ... */ + qlen = pktq_plen(&qi->q, prec); + if (ini->tx_in_transit > 0 && qlen < scb_ampdu->max_pdu) { + return BCME_BUSY; + } + + wlc_ampdu_agg(ampdu, scb, p, tid); + + if (wlc->block_datafifo) { + WL_ERROR("%s: Fifo blocked\n", __func__); + return BCME_BUSY; + } + rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; + ampdu_len = 0; + dma_len = 0; + while (p) { + struct ieee80211_tx_rate *txrate; + + tx_info = IEEE80211_SKB_CB(p); + txrate = tx_info->status.rates; + + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { + err = wlc_prep_pdu(wlc, p, &fifo); + } else { + WL_ERROR("%s: AMPDU flag is off!\n", __func__); + *pdu = NULL; + err = 0; + break; + } + + if (err) { + if (err == BCME_BUSY) { + WL_ERROR("wl%d: wlc_sendampdu: prep_xdu retry; seq 0x%x\n", + wlc->pub->unit, seq); + WLCNTINCR(ampdu->cnt->sduretry); + *pdu = p; + break; + } + + /* error in the packet; reject it */ + WL_AMPDU_ERR("wl%d: wlc_sendampdu: prep_xdu rejected; seq 0x%x\n", + wlc->pub->unit, seq); + WLCNTINCR(ampdu->cnt->sdurejected); + + *pdu = NULL; + break; + } + + /* pkt is good to be aggregated */ + ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); + txh = (d11txh_t *) p->data; + plcp = (u8 *) (txh + 1); + h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); + seq = ltoh16(h->seq_ctrl) >> SEQNUM_SHIFT; + index = TX_SEQ_TO_INDEX(seq); + + /* check mcl fields and test whether it can be agg'd */ + mcl = ltoh16(txh->MacTxControlLow); + mcl &= ~TXC_AMPDU_MASK; + fbr_iscck = !(ltoh16(txh->XtraFrameTypes) & 0x3); + ASSERT(!fbr_iscck); + txh->PreloadSize = 0; /* always default to 0 */ + + /* Handle retry limits */ + if (txrate[0].count <= rr_retry_limit) { + txrate[0].count++; + rr = true; + fbr = false; + ASSERT(!fbr); + } else { + fbr = true; + rr = false; + txrate[1].count++; + } + + /* extract the length info */ + len = fbr_iscck ? WLC_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) + : WLC_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); + + /* retrieve null delimiter count */ + ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; + seg_cnt += 1; + + WL_AMPDU_TX("wl%d: wlc_sendampdu: mpdu %d plcp_len %d\n", + wlc->pub->unit, count, len); + + /* + * aggregateable mpdu. For ucode/hw agg, + * test whether need to break or change the epoch + */ + if (count == 0) { + u16 fc; + mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT); + /* refill the bits since might be a retx mpdu */ + mcl |= TXC_STARTMSDU; + rts = (struct ieee80211_rts *)&txh->rts_frame; + fc = ltoh16(rts->frame_control); + if ((fc & FC_KIND_MASK) == FC_RTS) { + mcl |= TXC_SENDRTS; + use_rts = true; + } + if ((fc & FC_KIND_MASK) == FC_CTS) { + mcl |= TXC_SENDCTS; + use_cts = true; + } + } else { + mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT); + mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS); + } + + len = roundup(len, 4); + ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN); + + dma_len += (u16) pkttotlen(osh, p); + + WL_AMPDU_TX("wl%d: wlc_sendampdu: ampdu_len %d seg_cnt %d null delim %d\n", + wlc->pub->unit, ampdu_len, seg_cnt, ndelim); + + txh->MacTxControlLow = htol16(mcl); + + /* this packet is added */ + pkt[count++] = p; + + /* patch the first MPDU */ + if (count == 1) { + u8 plcp0, plcp3, is40, sgi; + struct ieee80211_sta *sta; + + sta = tx_info->control.sta; + + if (rr) { + plcp0 = plcp[0]; + plcp3 = plcp[3]; + } else { + plcp0 = txh->FragPLCPFallback[0]; + plcp3 = txh->FragPLCPFallback[3]; + + } + is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; + sgi = PLCP3_ISSGI(plcp3) ? 1 : 0; + mcs = plcp0 & ~MIMO_PLCP_40MHZ; + ASSERT(mcs < MCS_TABLE_SIZE); + maxlen = + min(scb_ampdu->max_rxlen, + ampdu->max_txlen[mcs][is40][sgi]); + + WL_NONE("sendampdu: sgi %d, is40 %d, mcs %d\n", + sgi, is40, mcs); + + maxlen = 64 * 1024; /* XXX Fix me to honor real max_rxlen */ + + if (is40) + mimo_ctlchbw = + CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC) + ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; + + /* rebuild the rspec and rspec_fallback */ + rspec = RSPEC_MIMORATE; + rspec |= plcp[0] & ~MIMO_PLCP_40MHZ; + if (plcp[0] & MIMO_PLCP_40MHZ) + rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT); + + if (fbr_iscck) /* CCK */ + rspec_fallback = + CCK_RSPEC(CCK_PHY2MAC_RATE + (txh->FragPLCPFallback[0])); + else { /* MIMO */ + rspec_fallback = RSPEC_MIMORATE; + rspec_fallback |= + txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ; + if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ) + rspec_fallback |= + (PHY_TXC1_BW_40MHZ << + RSPEC_BW_SHIFT); + } + + if (use_rts || use_cts) { + rts_rspec = + wlc_rspec_to_rts_rspec(wlc, rspec, false, + mimo_ctlchbw); + rts_rspec_fallback = + wlc_rspec_to_rts_rspec(wlc, rspec_fallback, + false, mimo_ctlchbw); + } + } + + /* if (first mpdu for host agg) */ + /* test whether to add more */ + if ((MCS_RATE(mcs, true, false) >= f->dmaxferrate) && + (count == f->mcs2ampdu_table[mcs])) { + WL_AMPDU_ERR("wl%d: PR 37644: stopping ampdu at %d for mcs %d\n", + wlc->pub->unit, count, mcs); + break; + } + + if (count == scb_ampdu->max_pdu) { + WL_NONE("Stop taking from q, reached %d deep\n", + scb_ampdu->max_pdu); + break; + } + + /* check to see if the next pkt is a candidate for aggregation */ + p = pktq_ppeek(&qi->q, prec); + tx_info = IEEE80211_SKB_CB(p); /* tx_info must be checked with current p */ + + if (p) { + if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && + ((u8) (p->priority) == tid)) { + + plen = + pkttotlen(osh, p) + AMPDU_MAX_MPDU_OVERHEAD; + plen = max(scb_ampdu->min_len, plen); + + if ((plen + ampdu_len) > maxlen) { + p = NULL; + WL_ERROR("%s: Bogus plen #1\n", + __func__); + ASSERT(3 == 4); + continue; + } + + /* check if there are enough descriptors available */ + if (TXAVAIL(wlc, fifo) <= (seg_cnt + 1)) { + WL_ERROR("%s: No fifo space !!!!!!\n", + __func__); + p = NULL; + continue; + } + p = pktq_pdeq(&qi->q, prec); + ASSERT(p); + } else { + p = NULL; + } + } + } /* end while(p) */ + + ini->tx_in_transit += count; + + if (count) { + WLCNTADD(ampdu->cnt->txmpdu, count); + + /* patch up the last txh */ + txh = (d11txh_t *) pkt[count - 1]->data; + mcl = ltoh16(txh->MacTxControlLow); + mcl &= ~TXC_AMPDU_MASK; + mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT); + txh->MacTxControlLow = htol16(mcl); + + /* remove the null delimiter after last mpdu */ + ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; + txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0; + ampdu_len -= ndelim * AMPDU_DELIMITER_LEN; + + /* remove the pad len from last mpdu */ + fbr_iscck = ((ltoh16(txh->XtraFrameTypes) & 0x3) == 0); + len = fbr_iscck ? WLC_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) + : WLC_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); + ampdu_len -= roundup(len, 4) - len; + + /* patch up the first txh & plcp */ + txh = (d11txh_t *) pkt[0]->data; + plcp = (u8 *) (txh + 1); + + WLC_SET_MIMO_PLCP_LEN(plcp, ampdu_len); + /* mark plcp to indicate ampdu */ + WLC_SET_MIMO_PLCP_AMPDU(plcp); + + /* reset the mixed mode header durations */ + if (txh->MModeLen) { + u16 mmodelen = + wlc_calc_lsig_len(wlc, rspec, ampdu_len); + txh->MModeLen = htol16(mmodelen); + preamble_type = WLC_MM_PREAMBLE; + } + if (txh->MModeFbrLen) { + u16 mmfbrlen = + wlc_calc_lsig_len(wlc, rspec_fallback, ampdu_len); + txh->MModeFbrLen = htol16(mmfbrlen); + fbr_preamble_type = WLC_MM_PREAMBLE; + } + + /* set the preload length */ + if (MCS_RATE(mcs, true, false) >= f->dmaxferrate) { + dma_len = min(dma_len, f->ampdu_pld_size); + txh->PreloadSize = htol16(dma_len); + } else + txh->PreloadSize = 0; + + mch = ltoh16(txh->MacTxControlHigh); + + /* update RTS dur fields */ + if (use_rts || use_cts) { + u16 durid; + rts = (struct ieee80211_rts *)&txh->rts_frame; + if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) == + TXC_PREAMBLE_RTS_MAIN_SHORT) + rts_preamble_type = WLC_SHORT_PREAMBLE; + + if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) == + TXC_PREAMBLE_RTS_FB_SHORT) + rts_fbr_preamble_type = WLC_SHORT_PREAMBLE; + + durid = + wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec, + rspec, rts_preamble_type, + preamble_type, ampdu_len, + true); + rts->duration = htol16(durid); + durid = wlc_compute_rtscts_dur(wlc, use_cts, + rts_rspec_fallback, + rspec_fallback, + rts_fbr_preamble_type, + fbr_preamble_type, + ampdu_len, true); + txh->RTSDurFallback = htol16(durid); + /* set TxFesTimeNormal */ + txh->TxFesTimeNormal = rts->duration; + /* set fallback rate version of TxFesTimeNormal */ + txh->TxFesTimeFallback = txh->RTSDurFallback; + } + + /* set flag and plcp for fallback rate */ + if (fbr) { + WLCNTADD(ampdu->cnt->txfbr_mpdu, count); + WLCNTINCR(ampdu->cnt->txfbr_ampdu); + mch |= TXC_AMPDU_FBR; + txh->MacTxControlHigh = htol16(mch); + WLC_SET_MIMO_PLCP_AMPDU(plcp); + WLC_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback); + } + + WL_AMPDU_TX("wl%d: wlc_sendampdu: count %d ampdu_len %d\n", + wlc->pub->unit, count, ampdu_len); + + /* inform rate_sel if it this is a rate probe pkt */ + frameid = ltoh16(txh->TxFrameID); + if (frameid & TXFID_RATE_PROBE_MASK) { + WL_ERROR("%s: XXX what to do with TXFID_RATE_PROBE_MASK!?\n", + __func__); + } + for (i = 0; i < count; i++) + wlc_txfifo(wlc, fifo, pkt[i], i == (count - 1), + ampdu->txpkt_weight); + + } + /* endif (count) */ + return err; +} + +void BCMFASTPATH +wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, + struct sk_buff *p, tx_status_t *txs) +{ + scb_ampdu_t *scb_ampdu; + struct wlc_info *wlc = ampdu->wlc; + scb_ampdu_tid_ini_t *ini; + u32 s1 = 0, s2 = 0; + struct ieee80211_tx_info *tx_info; + + tx_info = IEEE80211_SKB_CB(p); + ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); + ASSERT(scb); + ASSERT(scb->magic == SCB_MAGIC); + ASSERT(txs->status & TX_STATUS_AMPDU); + scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); + ASSERT(scb_ampdu); + ini = SCB_AMPDU_INI(scb_ampdu, p->priority); + ASSERT(ini->scb == scb); + + /* BMAC_NOTE: For the split driver, second level txstatus comes later + * So if the ACK was received then wait for the second level else just + * call the first one + */ + if (txs->status & TX_STATUS_ACK_RCV) { + u8 status_delay = 0; + + /* wait till the next 8 bytes of txstatus is available */ + while (((s1 = + R_REG(wlc->osh, + &wlc->regs->frmtxstatus)) & TXS_V) == 0) { + udelay(1); + status_delay++; + if (status_delay > 10) { + ASSERT(status_delay <= 10); + return; + } + } + + ASSERT(!(s1 & TX_STATUS_INTERMEDIATE)); + ASSERT(s1 & TX_STATUS_AMPDU); + s2 = R_REG(wlc->osh, &wlc->regs->frmtxstatus2); + } + + wlc_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2); + wlc_ampdu_txflowcontrol(wlc, scb_ampdu, ini); +} + +void +rate_status(struct wlc_info *wlc, struct ieee80211_tx_info *tx_info, + tx_status_t *txs, u8 mcs) +{ + struct ieee80211_tx_rate *txrate = tx_info->status.rates; + int i; + + /* clear the rest of the rates */ + for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) { + txrate[i].idx = -1; + txrate[i].count = 0; + } +} + +#define SHORTNAME "AMPDU status" + +static void BCMFASTPATH +wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, + struct sk_buff *p, tx_status_t *txs, + u32 s1, u32 s2) +{ + scb_ampdu_t *scb_ampdu; + struct wlc_info *wlc = ampdu->wlc; + scb_ampdu_tid_ini_t *ini; + u8 bitmap[8], queue, tid; + d11txh_t *txh; + u8 *plcp; + struct ieee80211_hdr *h; + u16 seq, start_seq = 0, bindex, index, mcl; + u8 mcs = 0; + bool ba_recd = false, ack_recd = false; + u8 suc_mpdu = 0, tot_mpdu = 0; + uint supr_status; + bool update_rate = true, retry = true, tx_error = false; + u16 mimoantsel = 0; + u8 antselid = 0; + u8 retry_limit, rr_retry_limit; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); + +#ifdef BCMDBG + u8 hole[AMPDU_MAX_MPDU]; + memset(hole, 0, sizeof(hole)); +#endif + + ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); + ASSERT(txs->status & TX_STATUS_AMPDU); + + scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); + ASSERT(scb_ampdu); + + tid = (u8) (p->priority); + + ini = SCB_AMPDU_INI(scb_ampdu, tid); + retry_limit = ampdu->retry_limit_tid[tid]; + rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; + + ASSERT(ini->scb == scb); + + memset(bitmap, 0, sizeof(bitmap)); + queue = txs->frameid & TXFID_QUEUE_MASK; + ASSERT(queue < AC_COUNT); + + supr_status = txs->status & TX_STATUS_SUPR_MASK; + + if (txs->status & TX_STATUS_ACK_RCV) { + if (TX_STATUS_SUPR_UF == supr_status) { + update_rate = false; + } + + ASSERT(txs->status & TX_STATUS_INTERMEDIATE); + start_seq = txs->sequence >> SEQNUM_SHIFT; + bitmap[0] = (txs->status & TX_STATUS_BA_BMAP03_MASK) >> + TX_STATUS_BA_BMAP03_SHIFT; + + ASSERT(!(s1 & TX_STATUS_INTERMEDIATE)); + ASSERT(s1 & TX_STATUS_AMPDU); + + bitmap[0] |= + (s1 & TX_STATUS_BA_BMAP47_MASK) << + TX_STATUS_BA_BMAP47_SHIFT; + bitmap[1] = (s1 >> 8) & 0xff; + bitmap[2] = (s1 >> 16) & 0xff; + bitmap[3] = (s1 >> 24) & 0xff; + + bitmap[4] = s2 & 0xff; + bitmap[5] = (s2 >> 8) & 0xff; + bitmap[6] = (s2 >> 16) & 0xff; + bitmap[7] = (s2 >> 24) & 0xff; + + ba_recd = true; + } else { + WLCNTINCR(ampdu->cnt->noba); + if (supr_status) { + update_rate = false; + if (supr_status == TX_STATUS_SUPR_BADCH) { + WL_ERROR("%s: Pkt tx suppressed, illegal channel possibly %d\n", + __func__, + CHSPEC_CHANNEL(wlc->default_bss->chanspec)); + } else { + if (supr_status == TX_STATUS_SUPR_FRAG) + WL_NONE("%s: AMPDU frag err\n", + __func__); + else + WL_ERROR("%s: wlc_ampdu_dotxstatus: supr_status 0x%x\n", + __func__, supr_status); + } + /* no need to retry for badch; will fail again */ + if (supr_status == TX_STATUS_SUPR_BADCH || + supr_status == TX_STATUS_SUPR_EXPTIME) { + retry = false; + WLCNTINCR(wlc->pub->_cnt->txchanrej); + } else if (supr_status == TX_STATUS_SUPR_EXPTIME) { + + WLCNTINCR(wlc->pub->_cnt->txexptime); + + /* TX underflow : try tuning pre-loading or ampdu size */ + } else if (supr_status == TX_STATUS_SUPR_FRAG) { + /* if there were underflows, but pre-loading is not active, + notify rate adaptation. + */ + if (wlc_ffpld_check_txfunfl(wlc, prio2fifo[tid]) + > 0) { + tx_error = true; + } + } + } else if (txs->phyerr) { + update_rate = false; + WLCNTINCR(wlc->pub->_cnt->txphyerr); + WL_ERROR("wl%d: wlc_ampdu_dotxstatus: tx phy error (0x%x)\n", + wlc->pub->unit, txs->phyerr); + +#ifdef BCMDBG + if (WL_ERROR_ON()) { + prpkt("txpkt (AMPDU)", wlc->osh, p); + wlc_print_txdesc((d11txh_t *) p->data); + wlc_print_txstatus(txs); + } +#endif /* BCMDBG */ + } + } + + /* loop through all pkts and retry if not acked */ + while (p) { + tx_info = IEEE80211_SKB_CB(p); + ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); + txh = (d11txh_t *) p->data; + mcl = ltoh16(txh->MacTxControlLow); + plcp = (u8 *) (txh + 1); + h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); + seq = ltoh16(h->seq_ctrl) >> SEQNUM_SHIFT; + + if (tot_mpdu == 0) { + mcs = plcp[0] & MIMO_PLCP_MCS_MASK; + mimoantsel = ltoh16(txh->ABI_MimoAntSel); + } + + index = TX_SEQ_TO_INDEX(seq); + ack_recd = false; + if (ba_recd) { + bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); + + WL_AMPDU_TX("%s: tid %d seq is %d, start_seq is %d, bindex is %d set %d, index %d\n", + __func__, tid, seq, start_seq, bindex, + isset(bitmap, bindex), index); + + /* if acked then clear bit and free packet */ + if ((bindex < AMPDU_TX_BA_MAX_WSIZE) + && isset(bitmap, bindex)) { + ini->tx_in_transit--; + ini->txretry[index] = 0; + + /* ampdu_ack_len: number of acked aggregated frames */ + /* ampdu_ack_map: block ack bit map for the aggregation */ + /* ampdu_len: number of aggregated frames */ + rate_status(wlc, tx_info, txs, mcs); + tx_info->flags |= IEEE80211_TX_STAT_ACK; + tx_info->flags |= IEEE80211_TX_STAT_AMPDU; + + /* XXX TODO: Make these accurate. */ + tx_info->status.ampdu_ack_len = + (txs-> + status & TX_STATUS_FRM_RTX_MASK) >> + TX_STATUS_FRM_RTX_SHIFT; + tx_info->status.ampdu_len = + (txs-> + status & TX_STATUS_FRM_RTX_MASK) >> + TX_STATUS_FRM_RTX_SHIFT; + + skb_pull(p, D11_PHY_HDR_LEN); + skb_pull(p, D11_TXH_LEN); + + ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, + p); + ack_recd = true; + suc_mpdu++; + } + } + /* either retransmit or send bar if ack not recd */ + if (!ack_recd) { + struct ieee80211_tx_rate *txrate = + tx_info->status.rates; + if (retry && (txrate[0].count < (int)retry_limit)) { + ini->txretry[index]++; + ini->tx_in_transit--; + /* Use high prededence for retransmit to give some punch */ + /* wlc_txq_enq(wlc, scb, p, WLC_PRIO_TO_PREC(tid)); */ + wlc_txq_enq(wlc, scb, p, + WLC_PRIO_TO_HI_PREC(tid)); + } else { + /* Retry timeout */ + ini->tx_in_transit--; + ieee80211_tx_info_clear_status(tx_info); + tx_info->flags |= + IEEE80211_TX_STAT_AMPDU_NO_BACK; + skb_pull(p, D11_PHY_HDR_LEN); + skb_pull(p, D11_TXH_LEN); + WL_ERROR("%s: BA Timeout, seq %d, in_transit %d\n", + SHORTNAME, seq, ini->tx_in_transit); + ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, + p); + } + } + tot_mpdu++; + + /* break out if last packet of ampdu */ + if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) == + TXC_AMPDU_LAST) + break; + + p = GETNEXTTXP(wlc, queue); + if (p == NULL) { + ASSERT(p); + break; + } + } + wlc_send_q(wlc, wlc->active_queue); + + /* update rate state */ + if (WLANTSEL_ENAB(wlc)) + antselid = wlc_antsel_antsel2id(wlc->asi, mimoantsel); + + wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight); +} + +static void +ampdu_cleanup_tid_ini(struct ampdu_info *ampdu, scb_ampdu_t *scb_ampdu, u8 tid, + bool force) +{ + scb_ampdu_tid_ini_t *ini; + ini = SCB_AMPDU_INI(scb_ampdu, tid); + if (!ini) + return; + + WL_AMPDU_CTL("wl%d: ampdu_cleanup_tid_ini: tid %d\n", + ampdu->wlc->pub->unit, tid); + + if (ini->tx_in_transit && !force) + return; + + scb_ampdu = SCB_AMPDU_CUBBY(ampdu, ini->scb); + ASSERT(ini == &scb_ampdu->ini[ini->tid]); + + /* free all buffered tx packets */ + pktq_pflush(ampdu->wlc->osh, &scb_ampdu->txq, ini->tid, true, NULL, 0); +} + +/* initialize the initiator code for tid */ +static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu, + scb_ampdu_t *scb_ampdu, + u8 tid, bool override) +{ + scb_ampdu_tid_ini_t *ini; + + ASSERT(scb_ampdu); + ASSERT(scb_ampdu->scb); + ASSERT(SCB_AMPDU(scb_ampdu->scb)); + ASSERT(tid < AMPDU_MAX_SCB_TID); + + /* check for per-tid control of ampdu */ + if (!ampdu->ini_enable[tid]) { + WL_ERROR("%s: Rejecting tid %d\n", __func__, tid); + return NULL; + } + + ini = SCB_AMPDU_INI(scb_ampdu, tid); + ini->tid = tid; + ini->scb = scb_ampdu->scb; + ini->magic = INI_MAGIC; + WLCNTINCR(ampdu->cnt->txaddbareq); + + return ini; +} + +int wlc_ampdu_set(struct ampdu_info *ampdu, bool on) +{ + struct wlc_info *wlc = ampdu->wlc; + + wlc->pub->_ampdu = false; + + if (on) { + if (!N_ENAB(wlc->pub)) { + WL_AMPDU_ERR("wl%d: driver not nmode enabled\n", + wlc->pub->unit); + return BCME_UNSUPPORTED; + } + if (!wlc_ampdu_cap(ampdu)) { + WL_AMPDU_ERR("wl%d: device not ampdu capable\n", + wlc->pub->unit); + return BCME_UNSUPPORTED; + } + wlc->pub->_ampdu = on; + } + + return 0; +} + +bool wlc_ampdu_cap(struct ampdu_info *ampdu) +{ + if (WLC_PHY_11N_CAP(ampdu->wlc->band)) + return true; + else + return false; +} + +static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur) +{ + u32 rate, mcs; + + for (mcs = 0; mcs < MCS_TABLE_SIZE; mcs++) { + /* rate is in Kbps; dur is in msec ==> len = (rate * dur) / 8 */ + /* 20MHz, No SGI */ + rate = MCS_RATE(mcs, false, false); + ampdu->max_txlen[mcs][0][0] = (rate * dur) >> 3; + /* 40 MHz, No SGI */ + rate = MCS_RATE(mcs, true, false); + ampdu->max_txlen[mcs][1][0] = (rate * dur) >> 3; + /* 20MHz, SGI */ + rate = MCS_RATE(mcs, false, true); + ampdu->max_txlen[mcs][0][1] = (rate * dur) >> 3; + /* 40 MHz, SGI */ + rate = MCS_RATE(mcs, true, true); + ampdu->max_txlen[mcs][1][1] = (rate * dur) >> 3; + } +} + +u8 BCMFASTPATH +wlc_ampdu_null_delim_cnt(struct ampdu_info *ampdu, struct scb *scb, + ratespec_t rspec, int phylen) +{ + scb_ampdu_t *scb_ampdu; + int bytes, cnt, tmp; + u8 tx_density; + + ASSERT(scb); + ASSERT(SCB_AMPDU(scb)); + + scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); + ASSERT(scb_ampdu); + + if (scb_ampdu->mpdu_density == 0) + return 0; + + /* RSPEC2RATE is in kbps units ==> ~RSPEC2RATE/2^13 is in bytes/usec + density x is in 2^(x-4) usec + ==> # of bytes needed for req density = rate/2^(17-x) + ==> # of null delimiters = ceil(ceil(rate/2^(17-x)) - phylen)/4) + */ + + tx_density = scb_ampdu->mpdu_density; + + ASSERT(tx_density <= AMPDU_MAX_MPDU_DENSITY); + tmp = 1 << (17 - tx_density); + bytes = CEIL(RSPEC2RATE(rspec), tmp); + + if (bytes > phylen) { + cnt = CEIL(bytes - phylen, AMPDU_DELIMITER_LEN); + ASSERT(cnt <= 255); + return (u8) cnt; + } else + return 0; +} + +void wlc_ampdu_macaddr_upd(struct wlc_info *wlc) +{ + char template[T_RAM_ACCESS_SZ * 2]; + + /* driver needs to write the ta in the template; ta is at offset 16 */ + memset(template, 0, sizeof(template)); + bcopy((char *)wlc->pub->cur_etheraddr, template, ETH_ALEN); + wlc_write_template_ram(wlc, (T_BA_TPL_BASE + 16), (T_RAM_ACCESS_SZ * 2), + template); +} + +bool wlc_aggregatable(struct wlc_info *wlc, u8 tid) +{ + return wlc->ampdu->ini_enable[tid]; +} + +void wlc_ampdu_shm_upd(struct ampdu_info *ampdu) +{ + struct wlc_info *wlc = ampdu->wlc; + + /* Extend ucode internal watchdog timer to match larger received frames */ + if ((ampdu->rx_factor & HT_PARAMS_RX_FACTOR_MASK) == + AMPDU_RX_FACTOR_64K) { + wlc_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX); + wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX); + } else { + wlc_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_DEF); + wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF); + } +} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.h new file mode 100644 index 000000000000..03457f63f2ab --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_ampdu_h_ +#define _wlc_ampdu_h_ + +extern struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc); +extern void wlc_ampdu_detach(struct ampdu_info *ampdu); +extern bool wlc_ampdu_cap(struct ampdu_info *ampdu); +extern int wlc_ampdu_set(struct ampdu_info *ampdu, bool on); +extern int wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, + struct sk_buff **aggp, int prec); +extern void wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, + struct sk_buff *p, tx_status_t *txs); +extern void wlc_ampdu_reset(struct ampdu_info *ampdu); +extern void wlc_ampdu_macaddr_upd(struct wlc_info *wlc); +extern void wlc_ampdu_shm_upd(struct ampdu_info *ampdu); + +extern u8 wlc_ampdu_null_delim_cnt(struct ampdu_info *ampdu, struct scb *scb, + ratespec_t rspec, int phylen); +extern void scb_ampdu_cleanup(struct ampdu_info *ampdu, struct scb *scb); + +#endif /* _wlc_ampdu_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_antsel.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_antsel.c new file mode 100644 index 000000000000..402ddf8f3371 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_antsel.c @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#ifdef WLANTSEL + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* useful macros */ +#define WLC_ANTSEL_11N_0(ant) ((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf) +#define WLC_ANTSEL_11N_1(ant) (((ant) & ANT_SELCFG_MASK) & 0xf) +#define WLC_ANTIDX_11N(ant) (((WLC_ANTSEL_11N_0(ant)) << 2) + (WLC_ANTSEL_11N_1(ant))) +#define WLC_ANT_ISAUTO_11N(ant) (((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) +#define WLC_ANTSEL_11N(ant) ((ant) & ANT_SELCFG_MASK) + +/* antenna switch */ +/* defines for no boardlevel antenna diversity */ +#define ANT_SELCFG_DEF_2x2 0x01 /* default antenna configuration */ + +/* 2x3 antdiv defines and tables for GPIO communication */ +#define ANT_SELCFG_NUM_2x3 3 +#define ANT_SELCFG_DEF_2x3 0x01 /* default antenna configuration */ + +/* 2x4 antdiv rev4 defines and tables for GPIO communication */ +#define ANT_SELCFG_NUM_2x4 4 +#define ANT_SELCFG_DEF_2x4 0x02 /* default antenna configuration */ + +/* static functions */ +static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel); +static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id); +static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg); +static void wlc_antsel_init_cfg(struct antsel_info *asi, + wlc_antselcfg_t *antsel, + bool auto_sel); + +const u16 mimo_2x4_div_antselpat_tbl[] = { + 0, 0, 0x9, 0xa, /* ant0: 0 ant1: 2,3 */ + 0, 0, 0x5, 0x6, /* ant0: 1 ant1: 2,3 */ + 0, 0, 0, 0, /* n.a. */ + 0, 0, 0, 0 /* n.a. */ +}; + +const u8 mimo_2x4_div_antselid_tbl[16] = { + 0, 0, 0, 0, 0, 2, 3, 0, + 0, 0, 1, 0, 0, 0, 0, 0 /* pat to antselid */ +}; + +const u16 mimo_2x3_div_antselpat_tbl[] = { + 16, 0, 1, 16, /* ant0: 0 ant1: 1,2 */ + 16, 16, 16, 16, /* n.a. */ + 16, 2, 16, 16, /* ant0: 2 ant1: 1 */ + 16, 16, 16, 16 /* n.a. */ +}; + +const u8 mimo_2x3_div_antselid_tbl[16] = { + 0, 1, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 /* pat to antselid */ +}; + +struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc, + struct osl_info *osh, + struct wlc_pub *pub, + struct wlc_hw_info *wlc_hw) { + struct antsel_info *asi; + + asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC); + if (!asi) { + WL_ERROR("wl%d: wlc_antsel_attach: out of mem\n", pub->unit); + return NULL; + } + + asi->wlc = wlc; + asi->pub = pub; + asi->antsel_type = ANTSEL_NA; + asi->antsel_avail = false; + asi->antsel_antswitch = (u8) getintvar(asi->pub->vars, "antswitch"); + + if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) { + switch (asi->antsel_antswitch) { + case ANTSWITCH_TYPE_1: + case ANTSWITCH_TYPE_2: + case ANTSWITCH_TYPE_3: + /* 4321/2 board with 2x3 switch logic */ + asi->antsel_type = ANTSEL_2x3; + /* Antenna selection availability */ + if (((u16) getintvar(asi->pub->vars, "aa2g") == 7) || + ((u16) getintvar(asi->pub->vars, "aa5g") == 7)) { + asi->antsel_avail = true; + } else + if (((u16) getintvar(asi->pub->vars, "aa2g") == + 3) + || ((u16) getintvar(asi->pub->vars, "aa5g") + == 3)) { + asi->antsel_avail = false; + } else { + asi->antsel_avail = false; + WL_ERROR("wlc_antsel_attach: 2o3 board cfg invalid\n"); + ASSERT(0); + } + break; + default: + break; + } + } else if ((asi->pub->sromrev == 4) && + ((u16) getintvar(asi->pub->vars, "aa2g") == 7) && + ((u16) getintvar(asi->pub->vars, "aa5g") == 0)) { + /* hack to match old 4321CB2 cards with 2of3 antenna switch */ + asi->antsel_type = ANTSEL_2x3; + asi->antsel_avail = true; + } else if (asi->pub->boardflags2 & BFL2_2X4_DIV) { + asi->antsel_type = ANTSEL_2x4; + asi->antsel_avail = true; + } + + /* Set the antenna selection type for the low driver */ + wlc_bmac_antsel_type_set(wlc_hw, asi->antsel_type); + + /* Init (auto/manual) antenna selection */ + wlc_antsel_init_cfg(asi, &asi->antcfg_11n, true); + wlc_antsel_init_cfg(asi, &asi->antcfg_cur, true); + + return asi; +} + +void wlc_antsel_detach(struct antsel_info *asi) +{ + if (!asi) + return; + + kfree(asi); +} + +void wlc_antsel_init(struct antsel_info *asi) +{ + if ((asi->antsel_type == ANTSEL_2x3) || + (asi->antsel_type == ANTSEL_2x4)) + wlc_antsel_cfgupd(asi, &asi->antcfg_11n); +} + +/* boardlevel antenna selection: init antenna selection structure */ +static void +wlc_antsel_init_cfg(struct antsel_info *asi, wlc_antselcfg_t *antsel, + bool auto_sel) +{ + if (asi->antsel_type == ANTSEL_2x3) { + u8 antcfg_def = ANT_SELCFG_DEF_2x3 | + ((asi->antsel_avail && auto_sel) ? ANT_SELCFG_AUTO : 0); + antsel->ant_config[ANT_SELCFG_TX_DEF] = antcfg_def; + antsel->ant_config[ANT_SELCFG_TX_UNICAST] = antcfg_def; + antsel->ant_config[ANT_SELCFG_RX_DEF] = antcfg_def; + antsel->ant_config[ANT_SELCFG_RX_UNICAST] = antcfg_def; + antsel->num_antcfg = ANT_SELCFG_NUM_2x3; + + } else if (asi->antsel_type == ANTSEL_2x4) { + + antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x4; + antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x4; + antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x4; + antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x4; + antsel->num_antcfg = ANT_SELCFG_NUM_2x4; + + } else { /* no antenna selection available */ + + antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x2; + antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x2; + antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x2; + antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x2; + antsel->num_antcfg = 0; + } +} + +void BCMFASTPATH +wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel, + u8 antselid, u8 fbantselid, u8 *antcfg, + u8 *fbantcfg) +{ + u8 ant; + + /* if use default, assign it and return */ + if (usedef) { + *antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_DEF]; + *fbantcfg = *antcfg; + return; + } + + if (!sel) { + *antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST]; + *fbantcfg = *antcfg; + + } else { + ant = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST]; + if ((ant & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) { + *antcfg = wlc_antsel_id2antcfg(asi, antselid); + *fbantcfg = wlc_antsel_id2antcfg(asi, fbantselid); + } else { + *antcfg = + asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST]; + *fbantcfg = *antcfg; + } + } + return; +} + +/* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */ +u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel) +{ + u8 antselid = 0; + + if (asi->antsel_type == ANTSEL_2x4) { + /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */ + antselid = mimo_2x4_div_antselid_tbl[(antsel & 0xf)]; + return antselid; + + } else if (asi->antsel_type == ANTSEL_2x3) { + /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */ + antselid = mimo_2x3_div_antselid_tbl[(antsel & 0xf)]; + return antselid; + } + + return antselid; +} + +/* boardlevel antenna selection: convert id to ant_cfg */ +static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id) +{ + u8 antcfg = ANT_SELCFG_DEF_2x2; + + if (asi->antsel_type == ANTSEL_2x4) { + /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */ + antcfg = (((id & 0x2) << 3) | ((id & 0x1) + 2)); + return antcfg; + + } else if (asi->antsel_type == ANTSEL_2x3) { + /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */ + antcfg = (((id & 0x02) << 4) | ((id & 0x1) + 1)); + return antcfg; + } + + return antcfg; +} + +/* boardlevel antenna selection: convert ant_cfg to mimo_antsel (ucode interface) */ +static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg) +{ + u8 idx = WLC_ANTIDX_11N(WLC_ANTSEL_11N(ant_cfg)); + u16 mimo_antsel = 0; + + if (asi->antsel_type == ANTSEL_2x4) { + /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */ + mimo_antsel = (mimo_2x4_div_antselpat_tbl[idx] & 0xf); + return mimo_antsel; + + } else if (asi->antsel_type == ANTSEL_2x3) { + /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */ + mimo_antsel = (mimo_2x3_div_antselpat_tbl[idx] & 0xf); + return mimo_antsel; + } + + return mimo_antsel; +} + +/* boardlevel antenna selection: ucode interface control */ +static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel) +{ + struct wlc_info *wlc = asi->wlc; + u8 ant_cfg; + u16 mimo_antsel; + + ASSERT(asi->antsel_type != ANTSEL_NA); + + /* 1) Update TX antconfig for all frames that are not unicast data + * (aka default TX) + */ + ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF]; + mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg); + wlc_write_shm(wlc, M_MIMO_ANTSEL_TXDFLT, mimo_antsel); + /* Update driver stats for currently selected default tx/rx antenna config */ + asi->antcfg_cur.ant_config[ANT_SELCFG_TX_DEF] = ant_cfg; + + /* 2) Update RX antconfig for all frames that are not unicast data + * (aka default RX) + */ + ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF]; + mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg); + wlc_write_shm(wlc, M_MIMO_ANTSEL_RXDFLT, mimo_antsel); + /* Update driver stats for currently selected default tx/rx antenna config */ + asi->antcfg_cur.ant_config[ANT_SELCFG_RX_DEF] = ant_cfg; + + return 0; +} + +#endif /* WLANTSEL */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_antsel.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_antsel.h new file mode 100644 index 000000000000..8875b5848665 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_antsel.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_antsel_h_ +#define _wlc_antsel_h_ +extern struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc, + struct osl_info *osh, + struct wlc_pub *pub, + struct wlc_hw_info *wlc_hw); +extern void wlc_antsel_detach(struct antsel_info *asi); +extern void wlc_antsel_init(struct antsel_info *asi); +extern void wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, + bool sel, + u8 id, u8 fbid, u8 *antcfg, + u8 *fbantcfg); +extern u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel); +#endif /* _wlc_antsel_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.c new file mode 100644 index 000000000000..e22ce1f79660 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.c @@ -0,0 +1,4235 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* BMAC_NOTE: a WLC_HIGH compile include of wlc.h adds in more structures and type + * dependencies. Need to include these to files to allow a clean include of wlc.h + * with WLC_HIGH defined. + * At some point we may be able to skip the include of wlc.h and instead just + * define a stub wlc_info and band struct to allow rpc calls to get the rpc handle. + */ +#include +#include +#include +#include +#include +#include +#include "wl_ucode.h" +#include "d11ucode_ext.h" +#include + +/* BMAC_NOTE: With WLC_HIGH defined, some fns in this file make calls to high level + * functions defined in the headers below. We should be eliminating those calls and + * will be able to delete these include lines. + */ +#include + +#include + +#include +#include + +#define TIMER_INTERVAL_WATCHDOG_BMAC 1000 /* watchdog timer, in unit of ms */ + +#define SYNTHPU_DLY_APHY_US 3700 /* a phy synthpu_dly time in us */ +#define SYNTHPU_DLY_BPHY_US 1050 /* b/g phy synthpu_dly time in us, default */ +#define SYNTHPU_DLY_NPHY_US 2048 /* n phy REV3 synthpu_dly time in us, default */ +#define SYNTHPU_DLY_LPPHY_US 300 /* lpphy synthpu_dly time in us */ + +#define SYNTHPU_DLY_PHY_US_QT 100 /* QT synthpu_dly time in us */ + +#ifndef BMAC_DUP_TO_REMOVE +#define WLC_RM_WAIT_TX_SUSPEND 4 /* Wait Tx Suspend */ + +#define ANTCNT 10 /* vanilla M_MAX_ANTCNT value */ + +#endif /* BMAC_DUP_TO_REMOVE */ + +#define DMAREG(wlc_hw, direction, fifonum) (D11REV_LT(wlc_hw->corerev, 11) ? \ + ((direction == DMA_TX) ? \ + (void *)&(wlc_hw->regs->fifo.f32regs.dmaregs[fifonum].xmt) : \ + (void *)&(wlc_hw->regs->fifo.f32regs.dmaregs[fifonum].rcv)) : \ + ((direction == DMA_TX) ? \ + (void *)&(wlc_hw->regs->fifo.f64regs[fifonum].dmaxmt) : \ + (void *)&(wlc_hw->regs->fifo.f64regs[fifonum].dmarcv))) + +/* + * The following table lists the buffer memory allocated to xmt fifos in HW. + * the size is in units of 256bytes(one block), total size is HW dependent + * ucode has default fifo partition, sw can overwrite if necessary + * + * This is documented in twiki under the topic UcodeTxFifo. Please ensure + * the twiki is updated before making changes. + */ + +#define XMTFIFOTBL_STARTREV 20 /* Starting corerev for the fifo size table */ + +static u16 xmtfifo_sz[][NFIFO] = { + {20, 192, 192, 21, 17, 5}, /* corerev 20: 5120, 49152, 49152, 5376, 4352, 1280 */ + {9, 58, 22, 14, 14, 5}, /* corerev 21: 2304, 14848, 5632, 3584, 3584, 1280 */ + {20, 192, 192, 21, 17, 5}, /* corerev 22: 5120, 49152, 49152, 5376, 4352, 1280 */ + {20, 192, 192, 21, 17, 5}, /* corerev 23: 5120, 49152, 49152, 5376, 4352, 1280 */ + {9, 58, 22, 14, 14, 5}, /* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */ +}; + +static void wlc_clkctl_clk(struct wlc_hw_info *wlc, uint mode); +static void wlc_coreinit(struct wlc_info *wlc); + +/* used by wlc_wakeucode_init() */ +static void wlc_write_inits(struct wlc_hw_info *wlc_hw, const d11init_t *inits); +static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[], + const uint nbytes); +static void wlc_ucode_download(struct wlc_hw_info *wlc); +static void wlc_ucode_txant_set(struct wlc_hw_info *wlc_hw); + +/* used by wlc_dpc() */ +static bool wlc_bmac_dotxstatus(struct wlc_hw_info *wlc, tx_status_t *txs, + u32 s2); +static bool wlc_bmac_txstatus_corerev4(struct wlc_hw_info *wlc); +static bool wlc_bmac_txstatus(struct wlc_hw_info *wlc, bool bound, bool *fatal); +static bool wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound); + +/* used by wlc_down() */ +static void wlc_flushqueues(struct wlc_info *wlc); + +static void wlc_write_mhf(struct wlc_hw_info *wlc_hw, u16 *mhfs); +static void wlc_mctrl_reset(struct wlc_hw_info *wlc_hw); +static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw); + +/* Low Level Prototypes */ +static u16 wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, + u32 sel); +static void wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset, + u16 v, u32 sel); +static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme); +static void wlc_bmac_detach_dmapio(struct wlc_hw_info *wlc_hw); +static void wlc_ucode_bsinit(struct wlc_hw_info *wlc_hw); +static bool wlc_validboardtype(struct wlc_hw_info *wlc); +static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw); +static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw); +static void wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init); +static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw); +static void wlc_ucode_mute_override_set(struct wlc_hw_info *wlc_hw); +static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw); +static u32 wlc_wlintrsoff(struct wlc_info *wlc); +static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask); +static void wlc_gpio_init(struct wlc_info *wlc); +static void wlc_write_hw_bcntemplate0(struct wlc_hw_info *wlc_hw, void *bcn, + int len); +static void wlc_write_hw_bcntemplate1(struct wlc_hw_info *wlc_hw, void *bcn, + int len); +static void wlc_bmac_bsinit(struct wlc_info *wlc, chanspec_t chanspec); +static u32 wlc_setband_inact(struct wlc_info *wlc, uint bandunit); +static void wlc_bmac_setband(struct wlc_hw_info *wlc_hw, uint bandunit, + chanspec_t chanspec); +static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw, + bool shortslot); +static void wlc_upd_ofdm_pctl1_table(struct wlc_hw_info *wlc_hw); +static u16 wlc_bmac_ofdm_ratetable_offset(struct wlc_hw_info *wlc_hw, + u8 rate); + +/* === Low Level functions === */ + +void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot) +{ + wlc_hw->shortslot = shortslot; + + if (BAND_2G(wlc_hw->band->bandtype) && wlc_hw->up) { + wlc_suspend_mac_and_wait(wlc_hw->wlc); + wlc_bmac_update_slot_timing(wlc_hw, shortslot); + wlc_enable_mac(wlc_hw->wlc); + } +} + +/* + * Update the slot timing for standard 11b/g (20us slots) + * or shortslot 11g (9us slots) + * The PSM needs to be suspended for this call. + */ +static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw, + bool shortslot) +{ + struct osl_info *osh; + d11regs_t *regs; + + osh = wlc_hw->osh; + regs = wlc_hw->regs; + + if (shortslot) { + /* 11g short slot: 11a timing */ + W_REG(osh, ®s->ifs_slot, 0x0207); /* APHY_SLOT_TIME */ + wlc_bmac_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME); + } else { + /* 11g long slot: 11b timing */ + W_REG(osh, ®s->ifs_slot, 0x0212); /* BPHY_SLOT_TIME */ + wlc_bmac_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME); + } +} + +static void WLBANDINITFN(wlc_ucode_bsinit) (struct wlc_hw_info *wlc_hw) +{ + /* init microcode host flags */ + wlc_write_mhf(wlc_hw, wlc_hw->band->mhfs); + + /* do band-specific ucode IHR, SHM, and SCR inits */ + if (D11REV_IS(wlc_hw->corerev, 23)) { + if (WLCISNPHY(wlc_hw->band)) { + wlc_write_inits(wlc_hw, d11n0bsinitvals16); + } else { + WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); + } + } else { + if (D11REV_IS(wlc_hw->corerev, 24)) { + if (WLCISLCNPHY(wlc_hw->band)) { + wlc_write_inits(wlc_hw, d11lcn0bsinitvals24); + } else + WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", + __func__, wlc_hw->unit, + wlc_hw->corerev); + } else { + WL_ERROR("%s: wl%d: unsupported corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); + } + } +} + +/* switch to new band but leave it inactive */ +static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + u32 macintmask; + u32 tmp; + + WL_TRACE("wl%d: wlc_setband_inact\n", wlc_hw->unit); + + ASSERT(bandunit != wlc_hw->band->bandunit); + ASSERT(si_iscoreup(wlc_hw->sih)); + ASSERT((R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol) & MCTL_EN_MAC) == + 0); + + /* disable interrupts */ + macintmask = wl_intrsoff(wlc->wl); + + /* radio off */ + wlc_phy_switch_radio(wlc_hw->band->pi, OFF); + + ASSERT(wlc_hw->clk); + + if (D11REV_LT(wlc_hw->corerev, 17)) + tmp = R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol); + + wlc_bmac_core_phy_clk(wlc_hw, OFF); + + wlc_setxband(wlc_hw, bandunit); + + return macintmask; +} + +/* Process received frames */ +/* + * Return true if more frames need to be processed. false otherwise. + * Param 'bound' indicates max. # frames to process before break out. + */ +static bool BCMFASTPATH +wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound) +{ + struct sk_buff *p; + struct sk_buff *head = NULL; + struct sk_buff *tail = NULL; + uint n = 0; + uint bound_limit = bound ? wlc_hw->wlc->pub->tunables->rxbnd : -1; + u32 tsf_h, tsf_l; + wlc_d11rxhdr_t *wlc_rxhdr = NULL; + + WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); + /* gather received frames */ + while ((p = dma_rx(wlc_hw->di[fifo]))) { + + if (!tail) + head = tail = p; + else { + tail->prev = p; + tail = p; + } + + /* !give others some time to run! */ + if (++n >= bound_limit) + break; + } + + /* get the TSF REG reading */ + wlc_bmac_read_tsf(wlc_hw, &tsf_l, &tsf_h); + + /* post more rbufs */ + dma_rxfill(wlc_hw->di[fifo]); + + /* process each frame */ + while ((p = head) != NULL) { + head = head->prev; + p->prev = NULL; + + /* record the tsf_l in wlc_rxd11hdr */ + wlc_rxhdr = (wlc_d11rxhdr_t *) p->data; + wlc_rxhdr->tsf_l = htol32(tsf_l); + + /* compute the RSSI from d11rxhdr and record it in wlc_rxd11hr */ + wlc_phy_rssi_compute(wlc_hw->band->pi, wlc_rxhdr); + + wlc_recv(wlc_hw->wlc, p); + } + + return n >= bound_limit; +} + +/* second-level interrupt processing + * Return true if another dpc needs to be re-scheduled. false otherwise. + * Param 'bounded' indicates if applicable loops should be bounded. + */ +bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) +{ + u32 macintstatus; + struct wlc_hw_info *wlc_hw = wlc->hw; + d11regs_t *regs = wlc_hw->regs; + bool fatal = false; + + if (DEVICEREMOVED(wlc)) { + WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); + wl_down(wlc->wl); + return false; + } + + /* grab and clear the saved software intstatus bits */ + macintstatus = wlc->macintstatus; + wlc->macintstatus = 0; + + WL_TRACE("wl%d: wlc_dpc: macintstatus 0x%x\n", + wlc_hw->unit, macintstatus); + + if (macintstatus & MI_PRQ) { + /* Process probe request FIFO */ + ASSERT(0 && "PRQ Interrupt in non-MBSS"); + } + + /* BCN template is available */ + /* ZZZ: Use AP_ACTIVE ? */ + if (AP_ENAB(wlc->pub) && (!APSTA_ENAB(wlc->pub) || wlc->aps_associated) + && (macintstatus & MI_BCNTPL)) { + wlc_update_beacon(wlc); + } + + /* PMQ entry addition */ + if (macintstatus & MI_PMQ) { + } + + /* tx status */ + if (macintstatus & MI_TFS) { + if (wlc_bmac_txstatus(wlc->hw, bounded, &fatal)) + wlc->macintstatus |= MI_TFS; + if (fatal) { + WL_ERROR("MI_TFS: fatal\n"); + goto fatal; + } + } + + if (macintstatus & (MI_TBTT | MI_DTIM_TBTT)) + wlc_tbtt(wlc, regs); + + /* ATIM window end */ + if (macintstatus & MI_ATIMWINEND) { + WL_TRACE("wlc_isr: end of ATIM window\n"); + + OR_REG(wlc_hw->osh, ®s->maccommand, wlc->qvalid); + wlc->qvalid = 0; + } + + /* phy tx error */ + if (macintstatus & MI_PHYTXERR) { + WLCNTINCR(wlc->pub->_cnt->txphyerr); + } + + /* received data or control frame, MI_DMAINT is indication of RX_FIFO interrupt */ + if (macintstatus & MI_DMAINT) { + if (wlc_bmac_recv(wlc_hw, RX_FIFO, bounded)) { + wlc->macintstatus |= MI_DMAINT; + } + } + + /* TX FIFO suspend/flush completion */ + if (macintstatus & MI_TXSTOP) { + if (wlc_bmac_tx_fifo_suspended(wlc_hw, TX_DATA_FIFO)) { + /* WL_ERROR("dpc: fifo_suspend_comlete\n"); */ + } + } + + /* noise sample collected */ + if (macintstatus & MI_BG_NOISE) { + wlc_phy_noise_sample_intr(wlc_hw->band->pi); + } + + if (macintstatus & MI_GP0) { + WL_ERROR("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", + wlc_hw->unit, wlc_hw->now); + + printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", + __func__, wlc_hw->sih->chip, + wlc_hw->sih->chiprev); + + WLCNTINCR(wlc->pub->_cnt->psmwds); + + /* big hammer */ + wl_init(wlc->wl); + } + + /* gptimer timeout */ + if (macintstatus & MI_TO) { + W_REG(wlc_hw->osh, ®s->gptimer, 0); + } + + if (macintstatus & MI_RFDISABLE) { +#if defined(BCMDBG) + u32 rfd = R_REG(wlc_hw->osh, ®s->phydebug) & PDBG_RFD; +#endif + + WL_ERROR("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n", + wlc_hw->unit, rfd); + + WLCNTINCR(wlc->pub->_cnt->rfdisable); + } + + /* send any enq'd tx packets. Just makes sure to jump start tx */ + if (!pktq_empty(&wlc->active_queue->q)) + wlc_send_q(wlc, wlc->active_queue); + + ASSERT(wlc_ps_check(wlc)); + + /* make sure the bound indication and the implementation are in sync */ + ASSERT(bounded == true || wlc->macintstatus == 0); + + /* it isn't done and needs to be resched if macintstatus is non-zero */ + return wlc->macintstatus != 0; + + fatal: + wl_init(wlc->wl); + return wlc->macintstatus != 0; +} + +/* common low-level watchdog code */ +void wlc_bmac_watchdog(void *arg) +{ + struct wlc_info *wlc = (struct wlc_info *) arg; + struct wlc_hw_info *wlc_hw = wlc->hw; + + WL_TRACE("wl%d: wlc_bmac_watchdog\n", wlc_hw->unit); + + if (!wlc_hw->up) + return; + + /* increment second count */ + wlc_hw->now++; + + /* Check for FIFO error interrupts */ + wlc_bmac_fifoerrors(wlc_hw); + + /* make sure RX dma has buffers */ + dma_rxfill(wlc->hw->di[RX_FIFO]); + if (D11REV_IS(wlc_hw->corerev, 4)) { + dma_rxfill(wlc->hw->di[RX_TXSTATUS_FIFO]); + } + + wlc_phy_watchdog(wlc_hw->band->pi); +} + +void +wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, + bool mute, struct txpwr_limits *txpwr) +{ + uint bandunit; + + WL_TRACE("wl%d: wlc_bmac_set_chanspec 0x%x\n", + wlc_hw->unit, chanspec); + + wlc_hw->chanspec = chanspec; + + /* Switch bands if necessary */ + if (NBANDS_HW(wlc_hw) > 1) { + bandunit = CHSPEC_WLCBANDUNIT(chanspec); + if (wlc_hw->band->bandunit != bandunit) { + /* wlc_bmac_setband disables other bandunit, + * use light band switch if not up yet + */ + if (wlc_hw->up) { + wlc_phy_chanspec_radio_set(wlc_hw-> + bandstate[bandunit]-> + pi, chanspec); + wlc_bmac_setband(wlc_hw, bandunit, chanspec); + } else { + wlc_setxband(wlc_hw, bandunit); + } + } + } + + wlc_phy_initcal_enable(wlc_hw->band->pi, !mute); + + if (!wlc_hw->up) { + if (wlc_hw->clk) + wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, + chanspec); + wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec); + } else { + wlc_phy_chanspec_set(wlc_hw->band->pi, chanspec); + wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec); + + /* Update muting of the channel */ + wlc_bmac_mute(wlc_hw, mute, 0); + } +} + +int wlc_bmac_revinfo_get(struct wlc_hw_info *wlc_hw, + wlc_bmac_revinfo_t *revinfo) +{ + si_t *sih = wlc_hw->sih; + uint idx; + + revinfo->vendorid = wlc_hw->vendorid; + revinfo->deviceid = wlc_hw->deviceid; + + revinfo->boardrev = wlc_hw->boardrev; + revinfo->corerev = wlc_hw->corerev; + revinfo->sromrev = wlc_hw->sromrev; + revinfo->chiprev = sih->chiprev; + revinfo->chip = sih->chip; + revinfo->chippkg = sih->chippkg; + revinfo->boardtype = sih->boardtype; + revinfo->boardvendor = sih->boardvendor; + revinfo->bustype = sih->bustype; + revinfo->buscoretype = sih->buscoretype; + revinfo->buscorerev = sih->buscorerev; + revinfo->issim = sih->issim; + + revinfo->nbands = NBANDS_HW(wlc_hw); + + for (idx = 0; idx < NBANDS_HW(wlc_hw); idx++) { + wlc_hwband_t *band = wlc_hw->bandstate[idx]; + revinfo->band[idx].bandunit = band->bandunit; + revinfo->band[idx].bandtype = band->bandtype; + revinfo->band[idx].phytype = band->phytype; + revinfo->band[idx].phyrev = band->phyrev; + revinfo->band[idx].radioid = band->radioid; + revinfo->band[idx].radiorev = band->radiorev; + revinfo->band[idx].abgphy_encore = band->abgphy_encore; + revinfo->band[idx].anarev = 0; + + } + return 0; +} + +int wlc_bmac_state_get(struct wlc_hw_info *wlc_hw, wlc_bmac_state_t *state) +{ + state->machwcap = wlc_hw->machwcap; + + return 0; +} + +static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) +{ + uint i; + char name[8]; + /* ucode host flag 2 needed for pio mode, independent of band and fifo */ + u16 pio_mhf2 = 0; + struct wlc_hw_info *wlc_hw = wlc->hw; + uint unit = wlc_hw->unit; + wlc_tunables_t *tune = wlc->pub->tunables; + + /* name and offsets for dma_attach */ + snprintf(name, sizeof(name), "wl%d", unit); + + if (wlc_hw->di[0] == 0) { /* Init FIFOs */ + uint addrwidth; + int dma_attach_err = 0; + struct osl_info *osh = wlc_hw->osh; + + /* Find out the DMA addressing capability and let OS know + * All the channels within one DMA core have 'common-minimum' same + * capability + */ + addrwidth = + dma_addrwidth(wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 0)); + + if (!wl_alloc_dma_resources(wlc_hw->wlc->wl, addrwidth)) { + WL_ERROR("wl%d: wlc_attach: alloc_dma_resources failed\n", + unit); + return false; + } + + /* + * FIFO 0 + * TX: TX_AC_BK_FIFO (TX AC Background data packets) + * RX: RX_FIFO (RX data packets) + */ + ASSERT(TX_AC_BK_FIFO == 0); + ASSERT(RX_FIFO == 0); + wlc_hw->di[0] = dma_attach(osh, name, wlc_hw->sih, + (wme ? DMAREG(wlc_hw, DMA_TX, 0) : + NULL), DMAREG(wlc_hw, DMA_RX, 0), + (wme ? tune->ntxd : 0), tune->nrxd, + tune->rxbufsz, -1, tune->nrxbufpost, + WL_HWRXOFF, &wl_msg_level); + dma_attach_err |= (NULL == wlc_hw->di[0]); + + /* + * FIFO 1 + * TX: TX_AC_BE_FIFO (TX AC Best-Effort data packets) + * (legacy) TX_DATA_FIFO (TX data packets) + * RX: UNUSED + */ + ASSERT(TX_AC_BE_FIFO == 1); + ASSERT(TX_DATA_FIFO == 1); + wlc_hw->di[1] = dma_attach(osh, name, wlc_hw->sih, + DMAREG(wlc_hw, DMA_TX, 1), NULL, + tune->ntxd, 0, 0, -1, 0, 0, + &wl_msg_level); + dma_attach_err |= (NULL == wlc_hw->di[1]); + + /* + * FIFO 2 + * TX: TX_AC_VI_FIFO (TX AC Video data packets) + * RX: UNUSED + */ + ASSERT(TX_AC_VI_FIFO == 2); + wlc_hw->di[2] = dma_attach(osh, name, wlc_hw->sih, + DMAREG(wlc_hw, DMA_TX, 2), NULL, + tune->ntxd, 0, 0, -1, 0, 0, + &wl_msg_level); + dma_attach_err |= (NULL == wlc_hw->di[2]); + /* + * FIFO 3 + * TX: TX_AC_VO_FIFO (TX AC Voice data packets) + * (legacy) TX_CTL_FIFO (TX control & mgmt packets) + * RX: RX_TXSTATUS_FIFO (transmit-status packets) + * for corerev < 5 only + */ + ASSERT(TX_AC_VO_FIFO == 3); + ASSERT(TX_CTL_FIFO == 3); + if (D11REV_IS(wlc_hw->corerev, 4)) { + ASSERT(RX_TXSTATUS_FIFO == 3); + wlc_hw->di[3] = dma_attach(osh, name, wlc_hw->sih, + DMAREG(wlc_hw, DMA_TX, 3), + DMAREG(wlc_hw, DMA_RX, 3), + tune->ntxd, tune->nrxd, + sizeof(tx_status_t), -1, + tune->nrxbufpost, 0, + &wl_msg_level); + dma_attach_err |= (NULL == wlc_hw->di[3]); + } else { + wlc_hw->di[3] = dma_attach(osh, name, wlc_hw->sih, + DMAREG(wlc_hw, DMA_TX, 3), + NULL, tune->ntxd, 0, 0, -1, + 0, 0, &wl_msg_level); + dma_attach_err |= (NULL == wlc_hw->di[3]); + } +/* Cleaner to leave this as if with AP defined */ + + if (dma_attach_err) { + WL_ERROR("wl%d: wlc_attach: dma_attach failed\n", unit); + return false; + } + + /* get pointer to dma engine tx flow control variable */ + for (i = 0; i < NFIFO; i++) + if (wlc_hw->di[i]) + wlc_hw->txavail[i] = + (uint *) dma_getvar(wlc_hw->di[i], + "&txavail"); + } + + /* initial ucode host flags */ + wlc_mhfdef(wlc, wlc_hw->band->mhfs, pio_mhf2); + + return true; +} + +static void wlc_bmac_detach_dmapio(struct wlc_hw_info *wlc_hw) +{ + uint j; + + for (j = 0; j < NFIFO; j++) { + if (wlc_hw->di[j]) { + dma_detach(wlc_hw->di[j]); + wlc_hw->di[j] = NULL; + } + } +} + +/* low level attach + * run backplane attach, init nvram + * run phy attach + * initialize software state for each core and band + * put the whole chip in reset(driver down state), no clock + */ +int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, + bool piomode, struct osl_info *osh, void *regsva, + uint bustype, void *btparam) +{ + struct wlc_hw_info *wlc_hw; + d11regs_t *regs; + char *macaddr = NULL; + char *vars; + uint err = 0; + uint j; + bool wme = false; + shared_phy_params_t sha_params; + + WL_TRACE("wl%d: wlc_bmac_attach: vendor 0x%x device 0x%x\n", + unit, vendor, device); + + ASSERT(sizeof(wlc_d11rxhdr_t) <= WL_HWRXOFF); + + wme = true; + + wlc_hw = wlc->hw; + wlc_hw->wlc = wlc; + wlc_hw->unit = unit; + wlc_hw->osh = osh; + wlc_hw->band = wlc_hw->bandstate[0]; + wlc_hw->_piomode = piomode; + + /* populate struct wlc_hw_info with default values */ + wlc_bmac_info_init(wlc_hw); + + /* + * Do the hardware portion of the attach. + * Also initialize software state that depends on the particular hardware + * we are running. + */ + wlc_hw->sih = si_attach((uint) device, osh, regsva, bustype, btparam, + &wlc_hw->vars, &wlc_hw->vars_size); + if (wlc_hw->sih == NULL) { + WL_ERROR("wl%d: wlc_bmac_attach: si_attach failed\n", unit); + err = 11; + goto fail; + } + vars = wlc_hw->vars; + + /* + * Get vendid/devid nvram overwrites, which could be different + * than those the BIOS recognizes for devices on PCMCIA_BUS, + * SDIO_BUS, and SROMless devices on PCI_BUS. + */ +#ifdef BCMBUSTYPE + bustype = BCMBUSTYPE; +#endif + if (bustype != SI_BUS) { + char *var; + + var = getvar(vars, "vendid"); + if (var) { + vendor = (u16) simple_strtoul(var, NULL, 0); + WL_ERROR("Overriding vendor id = 0x%x\n", vendor); + } + var = getvar(vars, "devid"); + if (var) { + u16 devid = (u16) simple_strtoul(var, NULL, 0); + if (devid != 0xffff) { + device = devid; + WL_ERROR("Overriding device id = 0x%x\n", + device); + } + } + + /* verify again the device is supported */ + if (!wlc_chipmatch(vendor, device)) { + WL_ERROR("wl%d: wlc_bmac_attach: Unsupported vendor/device (0x%x/0x%x)\n", + unit, vendor, device); + err = 12; + goto fail; + } + } + + wlc_hw->vendorid = vendor; + wlc_hw->deviceid = device; + + /* set bar0 window to point at D11 core */ + wlc_hw->regs = (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, 0); + wlc_hw->corerev = si_corerev(wlc_hw->sih); + + regs = wlc_hw->regs; + + wlc->regs = wlc_hw->regs; + + /* validate chip, chiprev and corerev */ + if (!wlc_isgoodchip(wlc_hw)) { + err = 13; + goto fail; + } + + /* initialize power control registers */ + si_clkctl_init(wlc_hw->sih); + + /* request fastclock and force fastclock for the rest of attach + * bring the d11 core out of reset. + * For PMU chips, the first wlc_clkctl_clk is no-op since core-clk is still false; + * But it will be called again inside wlc_corereset, after d11 is out of reset. + */ + wlc_clkctl_clk(wlc_hw, CLK_FAST); + wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); + + if (!wlc_bmac_validate_chip_access(wlc_hw)) { + WL_ERROR("wl%d: wlc_bmac_attach: validate_chip_access failed\n", + unit); + err = 14; + goto fail; + } + + /* get the board rev, used just below */ + j = getintvar(vars, "boardrev"); + /* promote srom boardrev of 0xFF to 1 */ + if (j == BOARDREV_PROMOTABLE) + j = BOARDREV_PROMOTED; + wlc_hw->boardrev = (u16) j; + if (!wlc_validboardtype(wlc_hw)) { + WL_ERROR("wl%d: wlc_bmac_attach: Unsupported Broadcom board type (0x%x)" " or revision level (0x%x)\n", + unit, wlc_hw->sih->boardtype, wlc_hw->boardrev); + err = 15; + goto fail; + } + wlc_hw->sromrev = (u8) getintvar(vars, "sromrev"); + wlc_hw->boardflags = (u32) getintvar(vars, "boardflags"); + wlc_hw->boardflags2 = (u32) getintvar(vars, "boardflags2"); + + if (D11REV_LE(wlc_hw->corerev, 4) + || (wlc_hw->boardflags & BFL_NOPLLDOWN)) + wlc_bmac_pllreq(wlc_hw, true, WLC_PLLREQ_SHARED); + + if ((wlc_hw->sih->bustype == PCI_BUS) + && (si_pci_war16165(wlc_hw->sih))) + wlc->war16165 = true; + + /* check device id(srom, nvram etc.) to set bands */ + if (wlc_hw->deviceid == BCM43224_D11N_ID) { + /* Dualband boards */ + wlc_hw->_nbands = 2; + } else + wlc_hw->_nbands = 1; + + if ((wlc_hw->sih->chip == BCM43225_CHIP_ID)) + wlc_hw->_nbands = 1; + + /* BMAC_NOTE: remove init of pub values when wlc_attach() unconditionally does the + * init of these values + */ + wlc->vendorid = wlc_hw->vendorid; + wlc->deviceid = wlc_hw->deviceid; + wlc->pub->sih = wlc_hw->sih; + wlc->pub->corerev = wlc_hw->corerev; + wlc->pub->sromrev = wlc_hw->sromrev; + wlc->pub->boardrev = wlc_hw->boardrev; + wlc->pub->boardflags = wlc_hw->boardflags; + wlc->pub->boardflags2 = wlc_hw->boardflags2; + wlc->pub->_nbands = wlc_hw->_nbands; + + wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc); + + if (wlc_hw->physhim == NULL) { + WL_ERROR("wl%d: wlc_bmac_attach: wlc_phy_shim_attach failed\n", + unit); + err = 25; + goto fail; + } + + /* pass all the parameters to wlc_phy_shared_attach in one struct */ + sha_params.osh = osh; + sha_params.sih = wlc_hw->sih; + sha_params.physhim = wlc_hw->physhim; + sha_params.unit = unit; + sha_params.corerev = wlc_hw->corerev; + sha_params.vars = vars; + sha_params.vid = wlc_hw->vendorid; + sha_params.did = wlc_hw->deviceid; + sha_params.chip = wlc_hw->sih->chip; + sha_params.chiprev = wlc_hw->sih->chiprev; + sha_params.chippkg = wlc_hw->sih->chippkg; + sha_params.sromrev = wlc_hw->sromrev; + sha_params.boardtype = wlc_hw->sih->boardtype; + sha_params.boardrev = wlc_hw->boardrev; + sha_params.boardvendor = wlc_hw->sih->boardvendor; + sha_params.boardflags = wlc_hw->boardflags; + sha_params.boardflags2 = wlc_hw->boardflags2; + sha_params.bustype = wlc_hw->sih->bustype; + sha_params.buscorerev = wlc_hw->sih->buscorerev; + + /* alloc and save pointer to shared phy state area */ + wlc_hw->phy_sh = wlc_phy_shared_attach(&sha_params); + if (!wlc_hw->phy_sh) { + err = 16; + goto fail; + } + + /* initialize software state for each core and band */ + for (j = 0; j < NBANDS_HW(wlc_hw); j++) { + /* + * band0 is always 2.4Ghz + * band1, if present, is 5Ghz + */ + + /* So if this is a single band 11a card, use band 1 */ + if (IS_SINGLEBAND_5G(wlc_hw->deviceid)) + j = BAND_5G_INDEX; + + wlc_setxband(wlc_hw, j); + + wlc_hw->band->bandunit = j; + wlc_hw->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G; + wlc->band->bandunit = j; + wlc->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G; + wlc->core->coreidx = si_coreidx(wlc_hw->sih); + + if (D11REV_GE(wlc_hw->corerev, 13)) { + wlc_hw->machwcap = R_REG(wlc_hw->osh, ®s->machwcap); + wlc_hw->machwcap_backup = wlc_hw->machwcap; + } + + /* init tx fifo size */ + ASSERT((wlc_hw->corerev - XMTFIFOTBL_STARTREV) < + ARRAY_SIZE(xmtfifo_sz)); + wlc_hw->xmtfifo_sz = + xmtfifo_sz[(wlc_hw->corerev - XMTFIFOTBL_STARTREV)]; + + /* Get a phy for this band */ + wlc_hw->band->pi = wlc_phy_attach(wlc_hw->phy_sh, + (void *)regs, wlc_hw->band->bandtype, vars); + if (wlc_hw->band->pi == NULL) { + WL_ERROR("wl%d: wlc_bmac_attach: wlc_phy_attach failed\n", + unit); + err = 17; + goto fail; + } + + wlc_phy_machwcap_set(wlc_hw->band->pi, wlc_hw->machwcap); + + wlc_phy_get_phyversion(wlc_hw->band->pi, &wlc_hw->band->phytype, + &wlc_hw->band->phyrev, + &wlc_hw->band->radioid, + &wlc_hw->band->radiorev); + wlc_hw->band->abgphy_encore = + wlc_phy_get_encore(wlc_hw->band->pi); + wlc->band->abgphy_encore = wlc_phy_get_encore(wlc_hw->band->pi); + wlc_hw->band->core_flags = + wlc_phy_get_coreflags(wlc_hw->band->pi); + + /* verify good phy_type & supported phy revision */ + if (WLCISNPHY(wlc_hw->band)) { + if (NCONF_HAS(wlc_hw->band->phyrev)) + goto good_phy; + else + goto bad_phy; + } else if (WLCISLCNPHY(wlc_hw->band)) { + if (LCNCONF_HAS(wlc_hw->band->phyrev)) + goto good_phy; + else + goto bad_phy; + } else { + bad_phy: + WL_ERROR("wl%d: wlc_bmac_attach: unsupported phy type/rev (%d/%d)\n", + unit, + wlc_hw->band->phytype, wlc_hw->band->phyrev); + err = 18; + goto fail; + } + + good_phy: + /* BMAC_NOTE: wlc->band->pi should not be set below and should be done in the + * high level attach. However we can not make that change until all low level access + * is changed to wlc_hw->band->pi. Instead do the wlc->band->pi init below, keeping + * wlc_hw->band->pi as well for incremental update of low level fns, and cut over + * low only init when all fns updated. + */ + wlc->band->pi = wlc_hw->band->pi; + wlc->band->phytype = wlc_hw->band->phytype; + wlc->band->phyrev = wlc_hw->band->phyrev; + wlc->band->radioid = wlc_hw->band->radioid; + wlc->band->radiorev = wlc_hw->band->radiorev; + + /* default contention windows size limits */ + wlc_hw->band->CWmin = APHY_CWMIN; + wlc_hw->band->CWmax = PHY_CWMAX; + + if (!wlc_bmac_attach_dmapio(wlc, j, wme)) { + err = 19; + goto fail; + } + } + + /* disable core to match driver "down" state */ + wlc_coredisable(wlc_hw); + + /* Match driver "down" state */ + if (wlc_hw->sih->bustype == PCI_BUS) + si_pci_down(wlc_hw->sih); + + /* register sb interrupt callback functions */ + si_register_intr_callback(wlc_hw->sih, (void *)wlc_wlintrsoff, + (void *)wlc_wlintrsrestore, NULL, wlc); + + /* turn off pll and xtal to match driver "down" state */ + wlc_bmac_xtal(wlc_hw, OFF); + + /* ********************************************************************* + * The hardware is in the DOWN state at this point. D11 core + * or cores are in reset with clocks off, and the board PLLs + * are off if possible. + * + * Beyond this point, wlc->sbclk == false and chip registers + * should not be touched. + ********************************************************************* + */ + + /* init etheraddr state variables */ + macaddr = wlc_get_macaddr(wlc_hw); + if (macaddr == NULL) { + WL_ERROR("wl%d: wlc_bmac_attach: macaddr not found\n", unit); + err = 21; + goto fail; + } + bcm_ether_atoe(macaddr, wlc_hw->etheraddr); + if (is_broadcast_ether_addr(wlc_hw->etheraddr) || + is_zero_ether_addr(wlc_hw->etheraddr)) { + WL_ERROR("wl%d: wlc_bmac_attach: bad macaddr %s\n", + unit, macaddr); + err = 22; + goto fail; + } + + WL_ERROR("%s:: deviceid 0x%x nbands %d board 0x%x macaddr: %s\n", + __func__, wlc_hw->deviceid, wlc_hw->_nbands, + wlc_hw->sih->boardtype, macaddr); + + return err; + + fail: + WL_ERROR("wl%d: wlc_bmac_attach: failed with err %d\n", unit, err); + return err; +} + +/* + * Initialize wlc_info default values ... + * may get overrides later in this function + * BMAC_NOTES, move low out and resolve the dangling ones + */ +void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw) +{ + struct wlc_info *wlc = wlc_hw->wlc; + + /* set default sw macintmask value */ + wlc->defmacintmask = DEF_MACINTMASK; + + /* various 802.11g modes */ + wlc_hw->shortslot = false; + + wlc_hw->SFBL = RETRY_SHORT_FB; + wlc_hw->LFBL = RETRY_LONG_FB; + + /* default mac retry limits */ + wlc_hw->SRL = RETRY_SHORT_DEF; + wlc_hw->LRL = RETRY_LONG_DEF; + wlc_hw->chanspec = CH20MHZ_CHSPEC(1); +} + +/* + * low level detach + */ +int wlc_bmac_detach(struct wlc_info *wlc) +{ + uint i; + wlc_hwband_t *band; + struct wlc_hw_info *wlc_hw = wlc->hw; + int callbacks; + + callbacks = 0; + + if (wlc_hw->sih) { + /* detach interrupt sync mechanism since interrupt is disabled and per-port + * interrupt object may has been freed. this must be done before sb core switch + */ + si_deregister_intr_callback(wlc_hw->sih); + + if (wlc_hw->sih->bustype == PCI_BUS) + si_pci_sleep(wlc_hw->sih); + } + + wlc_bmac_detach_dmapio(wlc_hw); + + band = wlc_hw->band; + for (i = 0; i < NBANDS_HW(wlc_hw); i++) { + if (band->pi) { + /* Detach this band's phy */ + wlc_phy_detach(band->pi); + band->pi = NULL; + } + band = wlc_hw->bandstate[OTHERBANDUNIT(wlc)]; + } + + /* Free shared phy state */ + wlc_phy_shared_detach(wlc_hw->phy_sh); + + wlc_phy_shim_detach(wlc_hw->physhim); + + /* free vars */ + if (wlc_hw->vars) { + kfree(wlc_hw->vars); + wlc_hw->vars = NULL; + } + + if (wlc_hw->sih) { + si_detach(wlc_hw->sih); + wlc_hw->sih = NULL; + } + + return callbacks; + +} + +void wlc_bmac_reset(struct wlc_hw_info *wlc_hw) +{ + WL_TRACE("wl%d: wlc_bmac_reset\n", wlc_hw->unit); + + WLCNTINCR(wlc_hw->wlc->pub->_cnt->reset); + + /* reset the core */ + if (!DEVICEREMOVED(wlc_hw->wlc)) + wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); + + /* purge the dma rings */ + wlc_flushqueues(wlc_hw->wlc); + + wlc_reset_bmac_done(wlc_hw->wlc); +} + +void +wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, + bool mute) { + u32 macintmask; + bool fastclk; + struct wlc_info *wlc = wlc_hw->wlc; + + WL_TRACE("wl%d: wlc_bmac_init\n", wlc_hw->unit); + + /* request FAST clock if not on */ + fastclk = wlc_hw->forcefastclk; + if (!fastclk) + wlc_clkctl_clk(wlc_hw, CLK_FAST); + + /* disable interrupts */ + macintmask = wl_intrsoff(wlc->wl); + + /* set up the specified band and chanspec */ + wlc_setxband(wlc_hw, CHSPEC_WLCBANDUNIT(chanspec)); + wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec); + + /* do one-time phy inits and calibration */ + wlc_phy_cal_init(wlc_hw->band->pi); + + /* core-specific initialization */ + wlc_coreinit(wlc); + + /* suspend the tx fifos and mute the phy for preism cac time */ + if (mute) + wlc_bmac_mute(wlc_hw, ON, PHY_MUTE_FOR_PREISM); + + /* band-specific inits */ + wlc_bmac_bsinit(wlc, chanspec); + + /* restore macintmask */ + wl_intrsrestore(wlc->wl, macintmask); + + /* seed wake_override with WLC_WAKE_OVERRIDE_MACSUSPEND since the mac is suspended + * and wlc_enable_mac() will clear this override bit. + */ + mboolset(wlc_hw->wake_override, WLC_WAKE_OVERRIDE_MACSUSPEND); + + /* + * initialize mac_suspend_depth to 1 to match ucode initial suspended state + */ + wlc_hw->mac_suspend_depth = 1; + + /* restore the clk */ + if (!fastclk) + wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); +} + +int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw) +{ + uint coremask; + + WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); + + ASSERT(wlc_hw->wlc->pub->hw_up && wlc_hw->wlc->macintmask == 0); + + /* + * Enable pll and xtal, initialize the power control registers, + * and force fastclock for the remainder of wlc_up(). + */ + wlc_bmac_xtal(wlc_hw, ON); + si_clkctl_init(wlc_hw->sih); + wlc_clkctl_clk(wlc_hw, CLK_FAST); + + /* + * Configure pci/pcmcia here instead of in wlc_attach() + * to allow mfg hotswap: down, hotswap (chip power cycle), up. + */ + coremask = (1 << wlc_hw->wlc->core->coreidx); + + if (wlc_hw->sih->bustype == PCI_BUS) + si_pci_setup(wlc_hw->sih, coremask); + + ASSERT(si_coreid(wlc_hw->sih) == D11_CORE_ID); + + /* + * Need to read the hwradio status here to cover the case where the system + * is loaded with the hw radio disabled. We do not want to bring the driver up in this case. + */ + if (wlc_bmac_radio_read_hwdisabled(wlc_hw)) { + /* put SB PCI in down state again */ + if (wlc_hw->sih->bustype == PCI_BUS) + si_pci_down(wlc_hw->sih); + wlc_bmac_xtal(wlc_hw, OFF); + return BCME_RADIOOFF; + } + + if (wlc_hw->sih->bustype == PCI_BUS) + si_pci_up(wlc_hw->sih); + + /* reset the d11 core */ + wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); + + return 0; +} + +int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw) +{ + WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); + + wlc_hw->up = true; + wlc_phy_hw_state_upd(wlc_hw->band->pi, true); + + /* FULLY enable dynamic power control and d11 core interrupt */ + wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); + ASSERT(wlc_hw->wlc->macintmask == 0); + wl_intrson(wlc_hw->wlc->wl); + return 0; +} + +int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw) +{ + bool dev_gone; + uint callbacks = 0; + + WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); + + if (!wlc_hw->up) + return callbacks; + + dev_gone = DEVICEREMOVED(wlc_hw->wlc); + + /* disable interrupts */ + if (dev_gone) + wlc_hw->wlc->macintmask = 0; + else { + /* now disable interrupts */ + wl_intrsoff(wlc_hw->wlc->wl); + + /* ensure we're running on the pll clock again */ + wlc_clkctl_clk(wlc_hw, CLK_FAST); + } + /* down phy at the last of this stage */ + callbacks += wlc_phy_down(wlc_hw->band->pi); + + return callbacks; +} + +int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw) +{ + uint callbacks = 0; + bool dev_gone; + + WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); + + if (!wlc_hw->up) + return callbacks; + + wlc_hw->up = false; + wlc_phy_hw_state_upd(wlc_hw->band->pi, false); + + dev_gone = DEVICEREMOVED(wlc_hw->wlc); + + if (dev_gone) { + wlc_hw->sbclk = false; + wlc_hw->clk = false; + wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); + + /* reclaim any posted packets */ + wlc_flushqueues(wlc_hw->wlc); + } else { + + /* Reset and disable the core */ + if (si_iscoreup(wlc_hw->sih)) { + if (R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol) & + MCTL_EN_MAC) + wlc_suspend_mac_and_wait(wlc_hw->wlc); + callbacks += wl_reset(wlc_hw->wlc->wl); + wlc_coredisable(wlc_hw); + } + + /* turn off primary xtal and pll */ + if (!wlc_hw->noreset) { + if (wlc_hw->sih->bustype == PCI_BUS) + si_pci_down(wlc_hw->sih); + wlc_bmac_xtal(wlc_hw, OFF); + } + } + + return callbacks; +} + +void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw) +{ + if (D11REV_IS(wlc_hw->corerev, 4)) /* no slowclock */ + udelay(5); + else { + /* delay before first read of ucode state */ + udelay(40); + + /* wait until ucode is no longer asleep */ + SPINWAIT((wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) == + DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly); + } + + ASSERT(wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) != DBGST_ASLEEP); +} + +void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, u8 *ea) +{ + bcopy(wlc_hw->etheraddr, ea, ETH_ALEN); +} + +void wlc_bmac_set_hw_etheraddr(struct wlc_hw_info *wlc_hw, + u8 *ea) +{ + bcopy(ea, wlc_hw->etheraddr, ETH_ALEN); +} + +int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw) +{ + return wlc_hw->band->bandtype; +} + +void *wlc_cur_phy(struct wlc_info *wlc) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + return (void *)wlc_hw->band->pi; +} + +/* control chip clock to save power, enable dynamic clock or force fast clock */ +static void wlc_clkctl_clk(struct wlc_hw_info *wlc_hw, uint mode) +{ + if (PMUCTL_ENAB(wlc_hw->sih)) { + /* new chips with PMU, CCS_FORCEHT will distribute the HT clock on backplane, + * but mac core will still run on ALP(not HT) when it enters powersave mode, + * which means the FCA bit may not be set. + * should wakeup mac if driver wants it to run on HT. + */ + + if (wlc_hw->clk) { + if (mode == CLK_FAST) { + OR_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, + CCS_FORCEHT); + + udelay(64); + + SPINWAIT(((R_REG + (wlc_hw->osh, + &wlc_hw->regs-> + clk_ctl_st) & CCS_HTAVAIL) == 0), + PMU_MAX_TRANSITION_DLY); + ASSERT(R_REG + (wlc_hw->osh, + &wlc_hw->regs-> + clk_ctl_st) & CCS_HTAVAIL); + } else { + if ((wlc_hw->sih->pmurev == 0) && + (R_REG + (wlc_hw->osh, + &wlc_hw->regs-> + clk_ctl_st) & (CCS_FORCEHT | CCS_HTAREQ))) + SPINWAIT(((R_REG + (wlc_hw->osh, + &wlc_hw->regs-> + clk_ctl_st) & CCS_HTAVAIL) + == 0), + PMU_MAX_TRANSITION_DLY); + AND_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, + ~CCS_FORCEHT); + } + } + wlc_hw->forcefastclk = (mode == CLK_FAST); + } else { + bool wakeup_ucode; + + /* old chips w/o PMU, force HT through cc, + * then use FCA to verify mac is running fast clock + */ + + wakeup_ucode = D11REV_LT(wlc_hw->corerev, 9); + + if (wlc_hw->up && wakeup_ucode) + wlc_ucode_wake_override_set(wlc_hw, + WLC_WAKE_OVERRIDE_CLKCTL); + + wlc_hw->forcefastclk = si_clkctl_cc(wlc_hw->sih, mode); + + if (D11REV_LT(wlc_hw->corerev, 11)) { + /* ucode WAR for old chips */ + if (wlc_hw->forcefastclk) + wlc_bmac_mhf(wlc_hw, MHF1, MHF1_FORCEFASTCLK, + MHF1_FORCEFASTCLK, WLC_BAND_ALL); + else + wlc_bmac_mhf(wlc_hw, MHF1, MHF1_FORCEFASTCLK, 0, + WLC_BAND_ALL); + } + + /* check fast clock is available (if core is not in reset) */ + if (D11REV_GT(wlc_hw->corerev, 4) && wlc_hw->forcefastclk + && wlc_hw->clk) + ASSERT(si_core_sflags(wlc_hw->sih, 0, 0) & SISF_FCLKA); + + /* keep the ucode wake bit on if forcefastclk is on + * since we do not want ucode to put us back to slow clock + * when it dozes for PM mode. + * Code below matches the wake override bit with current forcefastclk state + * Only setting bit in wake_override instead of waking ucode immediately + * since old code (wlc.c 1.4499) had this behavior. Older code set + * wlc->forcefastclk but only had the wake happen if the wakup_ucode work + * (protected by an up check) was executed just below. + */ + if (wlc_hw->forcefastclk) + mboolset(wlc_hw->wake_override, + WLC_WAKE_OVERRIDE_FORCEFAST); + else + mboolclr(wlc_hw->wake_override, + WLC_WAKE_OVERRIDE_FORCEFAST); + + /* ok to clear the wakeup now */ + if (wlc_hw->up && wakeup_ucode) + wlc_ucode_wake_override_clear(wlc_hw, + WLC_WAKE_OVERRIDE_CLKCTL); + } +} + +/* set initial host flags value */ +static void +wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + + memset(mhfs, 0, MHFMAX * sizeof(u16)); + + mhfs[MHF2] |= mhf2_init; + + /* prohibit use of slowclock on multifunction boards */ + if (wlc_hw->boardflags & BFL_NOPLLDOWN) + mhfs[MHF1] |= MHF1_FORCEFASTCLK; + + if (WLCISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 2)) { + mhfs[MHF2] |= MHF2_NPHY40MHZ_WAR; + mhfs[MHF1] |= MHF1_IQSWAP_WAR; + } +} + +/* set or clear ucode host flag bits + * it has an optimization for no-change write + * it only writes through shared memory when the core has clock; + * pre-CLK changes should use wlc_write_mhf to get around the optimization + * + * + * bands values are: WLC_BAND_AUTO <--- Current band only + * WLC_BAND_5G <--- 5G band only + * WLC_BAND_2G <--- 2G band only + * WLC_BAND_ALL <--- All bands + */ +void +wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, u16 val, + int bands) +{ + u16 save; + u16 addr[MHFMAX] = { + M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4, + M_HOST_FLAGS5 + }; + wlc_hwband_t *band; + + ASSERT((val & ~mask) == 0); + ASSERT(idx < MHFMAX); + ASSERT(ARRAY_SIZE(addr) == MHFMAX); + + switch (bands) { + /* Current band only or all bands, + * then set the band to current band + */ + case WLC_BAND_AUTO: + case WLC_BAND_ALL: + band = wlc_hw->band; + break; + case WLC_BAND_5G: + band = wlc_hw->bandstate[BAND_5G_INDEX]; + break; + case WLC_BAND_2G: + band = wlc_hw->bandstate[BAND_2G_INDEX]; + break; + default: + ASSERT(0); + band = NULL; + } + + if (band) { + save = band->mhfs[idx]; + band->mhfs[idx] = (band->mhfs[idx] & ~mask) | val; + + /* optimization: only write through if changed, and + * changed band is the current band + */ + if (wlc_hw->clk && (band->mhfs[idx] != save) + && (band == wlc_hw->band)) + wlc_bmac_write_shm(wlc_hw, addr[idx], + (u16) band->mhfs[idx]); + } + + if (bands == WLC_BAND_ALL) { + wlc_hw->bandstate[0]->mhfs[idx] = + (wlc_hw->bandstate[0]->mhfs[idx] & ~mask) | val; + wlc_hw->bandstate[1]->mhfs[idx] = + (wlc_hw->bandstate[1]->mhfs[idx] & ~mask) | val; + } +} + +u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands) +{ + wlc_hwband_t *band; + ASSERT(idx < MHFMAX); + + switch (bands) { + case WLC_BAND_AUTO: + band = wlc_hw->band; + break; + case WLC_BAND_5G: + band = wlc_hw->bandstate[BAND_5G_INDEX]; + break; + case WLC_BAND_2G: + band = wlc_hw->bandstate[BAND_2G_INDEX]; + break; + default: + ASSERT(0); + band = NULL; + } + + if (!band) + return 0; + + return band->mhfs[idx]; +} + +static void wlc_write_mhf(struct wlc_hw_info *wlc_hw, u16 *mhfs) +{ + u8 idx; + u16 addr[] = { + M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4, + M_HOST_FLAGS5 + }; + + ASSERT(ARRAY_SIZE(addr) == MHFMAX); + + for (idx = 0; idx < MHFMAX; idx++) { + wlc_bmac_write_shm(wlc_hw, addr[idx], mhfs[idx]); + } +} + +/* set the maccontrol register to desired reset state and + * initialize the sw cache of the register + */ +static void wlc_mctrl_reset(struct wlc_hw_info *wlc_hw) +{ + /* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */ + wlc_hw->maccontrol = 0; + wlc_hw->suspended_fifos = 0; + wlc_hw->wake_override = 0; + wlc_hw->mute_override = 0; + wlc_bmac_mctrl(wlc_hw, ~0, MCTL_IHR_EN | MCTL_WAKE); +} + +/* set or clear maccontrol bits */ +void wlc_bmac_mctrl(struct wlc_hw_info *wlc_hw, u32 mask, u32 val) +{ + u32 maccontrol; + u32 new_maccontrol; + + ASSERT((val & ~mask) == 0); + + maccontrol = wlc_hw->maccontrol; + new_maccontrol = (maccontrol & ~mask) | val; + + /* if the new maccontrol value is the same as the old, nothing to do */ + if (new_maccontrol == maccontrol) + return; + + /* something changed, cache the new value */ + wlc_hw->maccontrol = new_maccontrol; + + /* write the new values with overrides applied */ + wlc_mctrl_write(wlc_hw); +} + +/* write the software state of maccontrol and overrides to the maccontrol register */ +static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw) +{ + u32 maccontrol = wlc_hw->maccontrol; + + /* OR in the wake bit if overridden */ + if (wlc_hw->wake_override) + maccontrol |= MCTL_WAKE; + + /* set AP and INFRA bits for mute if needed */ + if (wlc_hw->mute_override) { + maccontrol &= ~(MCTL_AP); + maccontrol |= MCTL_INFRA; + } + + W_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol, maccontrol); +} + +void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, u32 override_bit) +{ + ASSERT((wlc_hw->wake_override & override_bit) == 0); + + if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) { + mboolset(wlc_hw->wake_override, override_bit); + return; + } + + mboolset(wlc_hw->wake_override, override_bit); + + wlc_mctrl_write(wlc_hw); + wlc_bmac_wait_for_wake(wlc_hw); + + return; +} + +void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw, u32 override_bit) +{ + ASSERT(wlc_hw->wake_override & override_bit); + + mboolclr(wlc_hw->wake_override, override_bit); + + if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) + return; + + wlc_mctrl_write(wlc_hw); + + return; +} + +/* When driver needs ucode to stop beaconing, it has to make sure that + * MCTL_AP is clear and MCTL_INFRA is set + * Mode MCTL_AP MCTL_INFRA + * AP 1 1 + * STA 0 1 <--- This will ensure no beacons + * IBSS 0 0 + */ +static void wlc_ucode_mute_override_set(struct wlc_hw_info *wlc_hw) +{ + wlc_hw->mute_override = 1; + + /* if maccontrol already has AP == 0 and INFRA == 1 without this + * override, then there is no change to write + */ + if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA) + return; + + wlc_mctrl_write(wlc_hw); + + return; +} + +/* Clear the override on AP and INFRA bits */ +static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw) +{ + if (wlc_hw->mute_override == 0) + return; + + wlc_hw->mute_override = 0; + + /* if maccontrol already has AP == 0 and INFRA == 1 without this + * override, then there is no change to write + */ + if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA) + return; + + wlc_mctrl_write(wlc_hw); +} + +/* + * Write a MAC address to the rcmta structure + */ +void +wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, + const u8 *addr) +{ + d11regs_t *regs = wlc_hw->regs; + volatile u16 *objdata16 = (volatile u16 *)®s->objdata; + u32 mac_hm; + u16 mac_l; + struct osl_info *osh; + + WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); + + ASSERT(wlc_hw->corerev > 4); + + mac_hm = + (addr[3] << 24) | (addr[2] << 16) | + (addr[1] << 8) | addr[0]; + mac_l = (addr[5] << 8) | addr[4]; + + osh = wlc_hw->osh; + + W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); + (void)R_REG(osh, ®s->objaddr); + W_REG(osh, ®s->objdata, mac_hm); + W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1))); + (void)R_REG(osh, ®s->objaddr); + W_REG(osh, objdata16, mac_l); +} + +/* + * Write a MAC address to the given match reg offset in the RXE match engine. + */ +void +wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset, + const u8 *addr) +{ + d11regs_t *regs; + u16 mac_l; + u16 mac_m; + u16 mac_h; + struct osl_info *osh; + + WL_TRACE("wl%d: wlc_bmac_set_addrmatch\n", wlc_hw->unit); + + ASSERT((match_reg_offset < RCM_SIZE) || (wlc_hw->corerev == 4)); + + regs = wlc_hw->regs; + mac_l = addr[0] | (addr[1] << 8); + mac_m = addr[2] | (addr[3] << 8); + mac_h = addr[4] | (addr[5] << 8); + + osh = wlc_hw->osh; + + /* enter the MAC addr into the RXE match registers */ + W_REG(osh, ®s->rcm_ctl, RCM_INC_DATA | match_reg_offset); + W_REG(osh, ®s->rcm_mat_data, mac_l); + W_REG(osh, ®s->rcm_mat_data, mac_m); + W_REG(osh, ®s->rcm_mat_data, mac_h); + +} + +void +wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, int len, + void *buf) +{ + d11regs_t *regs; + u32 word; + bool be_bit; +#ifdef IL_BIGENDIAN + volatile u16 *dptr = NULL; +#endif /* IL_BIGENDIAN */ + struct osl_info *osh; + + WL_TRACE("wl%d: wlc_bmac_write_template_ram\n", wlc_hw->unit); + + regs = wlc_hw->regs; + osh = wlc_hw->osh; + + ASSERT(IS_ALIGNED(offset, sizeof(u32))); + ASSERT(IS_ALIGNED(len, sizeof(u32))); + ASSERT((offset & ~0xffff) == 0); + + W_REG(osh, ®s->tplatewrptr, offset); + + /* if MCTL_BIGEND bit set in mac control register, + * the chip swaps data in fifo, as well as data in + * template ram + */ + be_bit = (R_REG(osh, ®s->maccontrol) & MCTL_BIGEND) != 0; + + while (len > 0) { + bcopy((u8 *) buf, &word, sizeof(u32)); + + if (be_bit) + word = hton32(word); + else + word = htol32(word); + + W_REG(osh, ®s->tplatewrdata, word); + + buf = (u8 *) buf + sizeof(u32); + len -= sizeof(u32); + } +} + +void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin) +{ + struct osl_info *osh; + + osh = wlc_hw->osh; + wlc_hw->band->CWmin = newmin; + + W_REG(osh, &wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMIN); + (void)R_REG(osh, &wlc_hw->regs->objaddr); + W_REG(osh, &wlc_hw->regs->objdata, newmin); +} + +void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax) +{ + struct osl_info *osh; + + osh = wlc_hw->osh; + wlc_hw->band->CWmax = newmax; + + W_REG(osh, &wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMAX); + (void)R_REG(osh, &wlc_hw->regs->objaddr); + W_REG(osh, &wlc_hw->regs->objdata, newmax); +} + +void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw) +{ + bool fastclk; + u32 tmp; + + /* request FAST clock if not on */ + fastclk = wlc_hw->forcefastclk; + if (!fastclk) + wlc_clkctl_clk(wlc_hw, CLK_FAST); + + wlc_phy_bw_state_set(wlc_hw->band->pi, bw); + + ASSERT(wlc_hw->clk); + if (D11REV_LT(wlc_hw->corerev, 17)) + tmp = R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol); + + wlc_bmac_phy_reset(wlc_hw); + wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi)); + + /* restore the clk */ + if (!fastclk) + wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); +} + +static void +wlc_write_hw_bcntemplate0(struct wlc_hw_info *wlc_hw, void *bcn, int len) +{ + d11regs_t *regs = wlc_hw->regs; + + wlc_bmac_write_template_ram(wlc_hw, T_BCN0_TPL_BASE, (len + 3) & ~3, + bcn); + /* write beacon length to SCR */ + ASSERT(len < 65536); + wlc_bmac_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len); + /* mark beacon0 valid */ + OR_REG(wlc_hw->osh, ®s->maccommand, MCMD_BCN0VLD); +} + +static void +wlc_write_hw_bcntemplate1(struct wlc_hw_info *wlc_hw, void *bcn, int len) +{ + d11regs_t *regs = wlc_hw->regs; + + wlc_bmac_write_template_ram(wlc_hw, T_BCN1_TPL_BASE, (len + 3) & ~3, + bcn); + /* write beacon length to SCR */ + ASSERT(len < 65536); + wlc_bmac_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len); + /* mark beacon1 valid */ + OR_REG(wlc_hw->osh, ®s->maccommand, MCMD_BCN1VLD); +} + +/* mac is assumed to be suspended at this point */ +void +wlc_bmac_write_hw_bcntemplates(struct wlc_hw_info *wlc_hw, void *bcn, int len, + bool both) +{ + d11regs_t *regs = wlc_hw->regs; + + if (both) { + wlc_write_hw_bcntemplate0(wlc_hw, bcn, len); + wlc_write_hw_bcntemplate1(wlc_hw, bcn, len); + } else { + /* bcn 0 */ + if (!(R_REG(wlc_hw->osh, ®s->maccommand) & MCMD_BCN0VLD)) + wlc_write_hw_bcntemplate0(wlc_hw, bcn, len); + /* bcn 1 */ + else if (! + (R_REG(wlc_hw->osh, ®s->maccommand) & MCMD_BCN1VLD)) + wlc_write_hw_bcntemplate1(wlc_hw, bcn, len); + else /* one template should always have been available */ + ASSERT(0); + } +} + +static void WLBANDINITFN(wlc_bmac_upd_synthpu) (struct wlc_hw_info *wlc_hw) +{ + u16 v; + struct wlc_info *wlc = wlc_hw->wlc; + /* update SYNTHPU_DLY */ + + if (WLCISLCNPHY(wlc->band)) { + v = SYNTHPU_DLY_LPPHY_US; + } else if (WLCISNPHY(wlc->band) && (NREV_GE(wlc->band->phyrev, 3))) { + v = SYNTHPU_DLY_NPHY_US; + } else { + v = SYNTHPU_DLY_BPHY_US; + } + + wlc_bmac_write_shm(wlc_hw, M_SYNTHPU_DLY, v); +} + +/* band-specific init */ +static void +WLBANDINITFN(wlc_bmac_bsinit) (struct wlc_info *wlc, chanspec_t chanspec) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + + WL_TRACE("wl%d: wlc_bmac_bsinit: bandunit %d\n", + wlc_hw->unit, wlc_hw->band->bandunit); + + /* sanity check */ + if (PHY_TYPE(R_REG(wlc_hw->osh, &wlc_hw->regs->phyversion)) != + PHY_TYPE_LCNXN) + ASSERT((uint) + PHY_TYPE(R_REG(wlc_hw->osh, &wlc_hw->regs->phyversion)) + == wlc_hw->band->phytype); + + wlc_ucode_bsinit(wlc_hw); + + wlc_phy_init(wlc_hw->band->pi, chanspec); + + wlc_ucode_txant_set(wlc_hw); + + /* cwmin is band-specific, update hardware with value for current band */ + wlc_bmac_set_cwmin(wlc_hw, wlc_hw->band->CWmin); + wlc_bmac_set_cwmax(wlc_hw, wlc_hw->band->CWmax); + + wlc_bmac_update_slot_timing(wlc_hw, + BAND_5G(wlc_hw->band-> + bandtype) ? true : wlc_hw-> + shortslot); + + /* write phytype and phyvers */ + wlc_bmac_write_shm(wlc_hw, M_PHYTYPE, (u16) wlc_hw->band->phytype); + wlc_bmac_write_shm(wlc_hw, M_PHYVER, (u16) wlc_hw->band->phyrev); + + /* initialize the txphyctl1 rate table since shmem is shared between bands */ + wlc_upd_ofdm_pctl1_table(wlc_hw); + + wlc_bmac_upd_synthpu(wlc_hw); +} + +void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk) +{ + WL_TRACE("wl%d: wlc_bmac_core_phy_clk: clk %d\n", wlc_hw->unit, clk); + + wlc_hw->phyclk = clk; + + if (OFF == clk) { /* clear gmode bit, put phy into reset */ + + si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC | SICF_GMODE), + (SICF_PRST | SICF_FGC)); + udelay(1); + si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_PRST); + udelay(1); + + } else { /* take phy out of reset */ + + si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_FGC); + udelay(1); + si_core_cflags(wlc_hw->sih, (SICF_FGC), 0); + udelay(1); + + } +} + +/* Perform a soft reset of the PHY PLL */ +void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw) +{ + WL_TRACE("wl%d: wlc_bmac_core_phypll_reset\n", wlc_hw->unit); + + si_corereg(wlc_hw->sih, SI_CC_IDX, + offsetof(chipcregs_t, chipcontrol_addr), ~0, 0); + udelay(1); + si_corereg(wlc_hw->sih, SI_CC_IDX, + offsetof(chipcregs_t, chipcontrol_data), 0x4, 0); + udelay(1); + si_corereg(wlc_hw->sih, SI_CC_IDX, + offsetof(chipcregs_t, chipcontrol_data), 0x4, 4); + udelay(1); + si_corereg(wlc_hw->sih, SI_CC_IDX, + offsetof(chipcregs_t, chipcontrol_data), 0x4, 0); + udelay(1); +} + +/* light way to turn on phy clock without reset for NPHY only + * refer to wlc_bmac_core_phy_clk for full version + */ +void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk) +{ + /* support(necessary for NPHY and HYPHY) only */ + if (!WLCISNPHY(wlc_hw->band)) + return; + + if (ON == clk) + si_core_cflags(wlc_hw->sih, SICF_FGC, SICF_FGC); + else + si_core_cflags(wlc_hw->sih, SICF_FGC, 0); + +} + +void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk) +{ + if (ON == clk) + si_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE); + else + si_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0); +} + +void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw) +{ + wlc_phy_t *pih = wlc_hw->band->pi; + u32 phy_bw_clkbits; + bool phy_in_reset = false; + + WL_TRACE("wl%d: wlc_bmac_phy_reset\n", wlc_hw->unit); + + if (pih == NULL) + return; + + phy_bw_clkbits = wlc_phy_clk_bwbits(wlc_hw->band->pi); + + /* Specfic reset sequence required for NPHY rev 3 and 4 */ + if (WLCISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) && + NREV_LE(wlc_hw->band->phyrev, 4)) { + /* Set the PHY bandwidth */ + si_core_cflags(wlc_hw->sih, SICF_BWMASK, phy_bw_clkbits); + + udelay(1); + + /* Perform a soft reset of the PHY PLL */ + wlc_bmac_core_phypll_reset(wlc_hw); + + /* reset the PHY */ + si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE), + (SICF_PRST | SICF_PCLKE)); + phy_in_reset = true; + } else { + + si_core_cflags(wlc_hw->sih, + (SICF_PRST | SICF_PCLKE | SICF_BWMASK), + (SICF_PRST | SICF_PCLKE | phy_bw_clkbits)); + } + + udelay(2); + wlc_bmac_core_phy_clk(wlc_hw, ON); + + if (pih) + wlc_phy_anacore(pih, ON); +} + +/* switch to and initialize new band */ +static void +WLBANDINITFN(wlc_bmac_setband) (struct wlc_hw_info *wlc_hw, uint bandunit, + chanspec_t chanspec) { + struct wlc_info *wlc = wlc_hw->wlc; + u32 macintmask; + + ASSERT(NBANDS_HW(wlc_hw) > 1); + ASSERT(bandunit != wlc_hw->band->bandunit); + + /* Enable the d11 core before accessing it */ + if (!si_iscoreup(wlc_hw->sih)) { + si_core_reset(wlc_hw->sih, 0, 0); + ASSERT(si_iscoreup(wlc_hw->sih)); + wlc_mctrl_reset(wlc_hw); + } + + macintmask = wlc_setband_inact(wlc, bandunit); + + if (!wlc_hw->up) + return; + + wlc_bmac_core_phy_clk(wlc_hw, ON); + + /* band-specific initializations */ + wlc_bmac_bsinit(wlc, chanspec); + + /* + * If there are any pending software interrupt bits, + * then replace these with a harmless nonzero value + * so wlc_dpc() will re-enable interrupts when done. + */ + if (wlc->macintstatus) + wlc->macintstatus = MI_DMAINT; + + /* restore macintmask */ + wl_intrsrestore(wlc->wl, macintmask); + + /* ucode should still be suspended.. */ + ASSERT((R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol) & MCTL_EN_MAC) == + 0); +} + +/* low-level band switch utility routine */ +void WLBANDINITFN(wlc_setxband) (struct wlc_hw_info *wlc_hw, uint bandunit) +{ + WL_TRACE("wl%d: wlc_setxband: bandunit %d\n", wlc_hw->unit, bandunit); + + wlc_hw->band = wlc_hw->bandstate[bandunit]; + + /* BMAC_NOTE: until we eliminate need for wlc->band refs in low level code */ + wlc_hw->wlc->band = wlc_hw->wlc->bandstate[bandunit]; + + /* set gmode core flag */ + if (wlc_hw->sbclk && !wlc_hw->noreset) { + si_core_cflags(wlc_hw->sih, SICF_GMODE, + ((bandunit == 0) ? SICF_GMODE : 0)); + } +} + +static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw) +{ + + /* reject unsupported corerev */ + if (!VALID_COREREV(wlc_hw->corerev)) { + WL_ERROR("unsupported core rev %d\n", wlc_hw->corerev); + return false; + } + + return true; +} + +static bool wlc_validboardtype(struct wlc_hw_info *wlc_hw) +{ + bool goodboard = true; + uint boardrev = wlc_hw->boardrev; + + if (boardrev == 0) + goodboard = false; + else if (boardrev > 0xff) { + uint brt = (boardrev & 0xf000) >> 12; + uint b0 = (boardrev & 0xf00) >> 8; + uint b1 = (boardrev & 0xf0) >> 4; + uint b2 = boardrev & 0xf; + + if ((brt > 2) || (brt == 0) || (b0 > 9) || (b0 == 0) || (b1 > 9) + || (b2 > 9)) + goodboard = false; + } + + if (wlc_hw->sih->boardvendor != VENDOR_BROADCOM) + return goodboard; + + return goodboard; +} + +static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw) +{ + const char *varname = "macaddr"; + char *macaddr; + + /* If macaddr exists, use it (Sromrev4, CIS, ...). */ + macaddr = getvar(wlc_hw->vars, varname); + if (macaddr != NULL) + return macaddr; + + if (NBANDS_HW(wlc_hw) > 1) + varname = "et1macaddr"; + else + varname = "il0macaddr"; + + macaddr = getvar(wlc_hw->vars, varname); + if (macaddr == NULL) { + WL_ERROR("wl%d: wlc_get_macaddr: macaddr getvar(%s) not found\n", + wlc_hw->unit, varname); + } + + return macaddr; +} + +/* + * Return true if radio is disabled, otherwise false. + * hw radio disable signal is an external pin, users activate it asynchronously + * this function could be called when driver is down and w/o clock + * it operates on different registers depending on corerev and boardflag. + */ +bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw) +{ + bool v, clk, xtal; + u32 resetbits = 0, flags = 0; + + xtal = wlc_hw->sbclk; + if (!xtal) + wlc_bmac_xtal(wlc_hw, ON); + + /* may need to take core out of reset first */ + clk = wlc_hw->clk; + if (!clk) { + if (D11REV_LE(wlc_hw->corerev, 11)) + resetbits |= SICF_PCLKE; + + /* + * corerev >= 18, mac no longer enables phyclk automatically when driver accesses + * phyreg throughput mac. This can be skipped since only mac reg is accessed below + */ + if (D11REV_GE(wlc_hw->corerev, 18)) + flags |= SICF_PCLKE; + + /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */ + if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || + (wlc_hw->sih->chip == BCM43225_CHIP_ID) || + (wlc_hw->sih->chip == BCM43421_CHIP_ID)) + wlc_hw->regs = + (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, + 0); + si_core_reset(wlc_hw->sih, flags, resetbits); + wlc_mctrl_reset(wlc_hw); + } + + v = ((R_REG(wlc_hw->osh, &wlc_hw->regs->phydebug) & PDBG_RFD) != 0); + + /* put core back into reset */ + if (!clk) + si_core_disable(wlc_hw->sih, 0); + + if (!xtal) + wlc_bmac_xtal(wlc_hw, OFF); + + return v; +} + +/* Initialize just the hardware when coming out of POR or S3/S5 system states */ +void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw) +{ + if (wlc_hw->wlc->pub->hw_up) + return; + + WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); + + /* + * Enable pll and xtal, initialize the power control registers, + * and force fastclock for the remainder of wlc_up(). + */ + wlc_bmac_xtal(wlc_hw, ON); + si_clkctl_init(wlc_hw->sih); + wlc_clkctl_clk(wlc_hw, CLK_FAST); + + if (wlc_hw->sih->bustype == PCI_BUS) { + si_pci_fixcfg(wlc_hw->sih); + + /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */ + if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || + (wlc_hw->sih->chip == BCM43225_CHIP_ID) || + (wlc_hw->sih->chip == BCM43421_CHIP_ID)) + wlc_hw->regs = + (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, + 0); + } + + /* Inform phy that a POR reset has occurred so it does a complete phy init */ + wlc_phy_por_inform(wlc_hw->band->pi); + + wlc_hw->ucode_loaded = false; + wlc_hw->wlc->pub->hw_up = true; + + if ((wlc_hw->boardflags & BFL_FEM) + && (wlc_hw->sih->chip == BCM4313_CHIP_ID)) { + if (! + (wlc_hw->boardrev >= 0x1250 + && (wlc_hw->boardflags & BFL_FEM_BT))) + si_epa_4313war(wlc_hw->sih); + } +} + +static bool wlc_dma_rxreset(struct wlc_hw_info *wlc_hw, uint fifo) +{ + struct hnddma_pub *di = wlc_hw->di[fifo]; + struct osl_info *osh; + + if (D11REV_LT(wlc_hw->corerev, 12)) { + bool rxidle = true; + u16 rcv_frm_cnt = 0; + + osh = wlc_hw->osh; + + W_REG(osh, &wlc_hw->regs->rcv_fifo_ctl, fifo << 8); + SPINWAIT((!(rxidle = dma_rxidle(di))) && + ((rcv_frm_cnt = + R_REG(osh, &wlc_hw->regs->rcv_frm_cnt)) != 0), + 50000); + + if (!rxidle && (rcv_frm_cnt != 0)) + WL_ERROR("wl%d: %s: rxdma[%d] not idle && rcv_frm_cnt(%d) not zero\n", + wlc_hw->unit, __func__, fifo, rcv_frm_cnt); + mdelay(2); + } + + return dma_rxreset(di); +} + +/* d11 core reset + * ensure fask clock during reset + * reset dma + * reset d11(out of reset) + * reset phy(out of reset) + * clear software macintstatus for fresh new start + * one testing hack wlc_hw->noreset will bypass the d11/phy reset + */ +void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags) +{ + d11regs_t *regs; + uint i; + bool fastclk; + u32 resetbits = 0; + + if (flags == WLC_USE_COREFLAGS) + flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0); + + WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); + + regs = wlc_hw->regs; + + /* request FAST clock if not on */ + fastclk = wlc_hw->forcefastclk; + if (!fastclk) + wlc_clkctl_clk(wlc_hw, CLK_FAST); + + /* reset the dma engines except first time thru */ + if (si_iscoreup(wlc_hw->sih)) { + for (i = 0; i < NFIFO; i++) + if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) { + WL_ERROR("wl%d: %s: dma_txreset[%d]: cannot stop dma\n", + wlc_hw->unit, __func__, i); + } + + if ((wlc_hw->di[RX_FIFO]) + && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) { + WL_ERROR("wl%d: %s: dma_rxreset[%d]: cannot stop dma\n", + wlc_hw->unit, __func__, RX_FIFO); + } + if (D11REV_IS(wlc_hw->corerev, 4) + && wlc_hw->di[RX_TXSTATUS_FIFO] + && (!wlc_dma_rxreset(wlc_hw, RX_TXSTATUS_FIFO))) { + WL_ERROR("wl%d: %s: dma_rxreset[%d]: cannot stop dma\n", + wlc_hw->unit, __func__, RX_TXSTATUS_FIFO); + } + } + /* if noreset, just stop the psm and return */ + if (wlc_hw->noreset) { + wlc_hw->wlc->macintstatus = 0; /* skip wl_dpc after down */ + wlc_bmac_mctrl(wlc_hw, MCTL_PSM_RUN | MCTL_EN_MAC, 0); + return; + } + + if (D11REV_LE(wlc_hw->corerev, 11)) + resetbits |= SICF_PCLKE; + + /* + * corerev >= 18, mac no longer enables phyclk automatically when driver accesses phyreg + * throughput mac, AND phy_reset is skipped at early stage when band->pi is invalid + * need to enable PHY CLK + */ + if (D11REV_GE(wlc_hw->corerev, 18)) + flags |= SICF_PCLKE; + + /* reset the core + * In chips with PMU, the fastclk request goes through d11 core reg 0x1e0, which + * is cleared by the core_reset. have to re-request it. + * This adds some delay and we can optimize it by also requesting fastclk through + * chipcommon during this period if necessary. But that has to work coordinate + * with other driver like mips/arm since they may touch chipcommon as well. + */ + wlc_hw->clk = false; + si_core_reset(wlc_hw->sih, flags, resetbits); + wlc_hw->clk = true; + if (wlc_hw->band && wlc_hw->band->pi) + wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true); + + wlc_mctrl_reset(wlc_hw); + + if (PMUCTL_ENAB(wlc_hw->sih)) + wlc_clkctl_clk(wlc_hw, CLK_FAST); + + wlc_bmac_phy_reset(wlc_hw); + + /* turn on PHY_PLL */ + wlc_bmac_core_phypll_ctl(wlc_hw, true); + + /* clear sw intstatus */ + wlc_hw->wlc->macintstatus = 0; + + /* restore the clk setting */ + if (!fastclk) + wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); +} + +/* If the ucode that supports corerev 5 is used for corerev 9 and above, + * txfifo sizes needs to be modified(increased) since the newer cores + * have more memory. + */ +static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw) +{ + d11regs_t *regs = wlc_hw->regs; + u16 fifo_nu; + u16 txfifo_startblk = TXFIFO_START_BLK, txfifo_endblk; + u16 txfifo_def, txfifo_def1; + u16 txfifo_cmd; + struct osl_info *osh; + + if (D11REV_LT(wlc_hw->corerev, 9)) + goto exit; + + /* tx fifos start at TXFIFO_START_BLK from the Base address */ + txfifo_startblk = TXFIFO_START_BLK; + + osh = wlc_hw->osh; + + /* sequence of operations: reset fifo, set fifo size, reset fifo */ + for (fifo_nu = 0; fifo_nu < NFIFO; fifo_nu++) { + + txfifo_endblk = txfifo_startblk + wlc_hw->xmtfifo_sz[fifo_nu]; + txfifo_def = (txfifo_startblk & 0xff) | + (((txfifo_endblk - 1) & 0xff) << TXFIFO_FIFOTOP_SHIFT); + txfifo_def1 = ((txfifo_startblk >> 8) & 0x1) | + ((((txfifo_endblk - + 1) >> 8) & 0x1) << TXFIFO_FIFOTOP_SHIFT); + txfifo_cmd = + TXFIFOCMD_RESET_MASK | (fifo_nu << TXFIFOCMD_FIFOSEL_SHIFT); + + W_REG(osh, ®s->xmtfifocmd, txfifo_cmd); + W_REG(osh, ®s->xmtfifodef, txfifo_def); + if (D11REV_GE(wlc_hw->corerev, 16)) + W_REG(osh, ®s->xmtfifodef1, txfifo_def1); + + W_REG(osh, ®s->xmtfifocmd, txfifo_cmd); + + txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu]; + } + exit: + /* need to propagate to shm location to be in sync since ucode/hw won't do this */ + wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE0, + wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]); + wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE1, + wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]); + wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE2, + ((wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO] << 8) | wlc_hw-> + xmtfifo_sz[TX_AC_BK_FIFO])); + wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE3, + ((wlc_hw->xmtfifo_sz[TX_ATIM_FIFO] << 8) | wlc_hw-> + xmtfifo_sz[TX_BCMC_FIFO])); +} + +/* d11 core init + * reset PSM + * download ucode/PCM + * let ucode run to suspended + * download ucode inits + * config other core registers + * init dma + */ +static void wlc_coreinit(struct wlc_info *wlc) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + d11regs_t *regs; + u32 sflags; + uint bcnint_us; + uint i = 0; + bool fifosz_fixup = false; + struct osl_info *osh; + int err = 0; + u16 buf[NFIFO]; + + regs = wlc_hw->regs; + osh = wlc_hw->osh; + + WL_TRACE("wl%d: wlc_coreinit\n", wlc_hw->unit); + + /* reset PSM */ + wlc_bmac_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE)); + + wlc_ucode_download(wlc_hw); + /* + * FIFOSZ fixup + * 1) core5-9 use ucode 5 to save space since the PSM is the same + * 2) newer chips, driver wants to controls the fifo allocation + */ + if (D11REV_GE(wlc_hw->corerev, 4)) + fifosz_fixup = true; + + /* let the PSM run to the suspended state, set mode to BSS STA */ + W_REG(osh, ®s->macintstatus, -1); + wlc_bmac_mctrl(wlc_hw, ~0, + (MCTL_IHR_EN | MCTL_INFRA | MCTL_PSM_RUN | MCTL_WAKE)); + + /* wait for ucode to self-suspend after auto-init */ + SPINWAIT(((R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD) == 0), + 1000 * 1000); + if ((R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD) == 0) + WL_ERROR("wl%d: wlc_coreinit: ucode did not self-suspend!\n", + wlc_hw->unit); + + wlc_gpio_init(wlc); + + sflags = si_core_sflags(wlc_hw->sih, 0, 0); + + if (D11REV_IS(wlc_hw->corerev, 23)) { + if (WLCISNPHY(wlc_hw->band)) + wlc_write_inits(wlc_hw, d11n0initvals16); + else + WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); + } else if (D11REV_IS(wlc_hw->corerev, 24)) { + if (WLCISLCNPHY(wlc_hw->band)) { + wlc_write_inits(wlc_hw, d11lcn0initvals24); + } else { + WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); + } + } else { + WL_ERROR("%s: wl%d: unsupported corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); + } + + /* For old ucode, txfifo sizes needs to be modified(increased) for Corerev >= 9 */ + if (fifosz_fixup == true) { + wlc_corerev_fifofixup(wlc_hw); + } + + /* check txfifo allocations match between ucode and driver */ + buf[TX_AC_BE_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE0); + if (buf[TX_AC_BE_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]) { + i = TX_AC_BE_FIFO; + err = -1; + } + buf[TX_AC_VI_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE1); + if (buf[TX_AC_VI_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]) { + i = TX_AC_VI_FIFO; + err = -1; + } + buf[TX_AC_BK_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE2); + buf[TX_AC_VO_FIFO] = (buf[TX_AC_BK_FIFO] >> 8) & 0xff; + buf[TX_AC_BK_FIFO] &= 0xff; + if (buf[TX_AC_BK_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BK_FIFO]) { + i = TX_AC_BK_FIFO; + err = -1; + } + if (buf[TX_AC_VO_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO]) { + i = TX_AC_VO_FIFO; + err = -1; + } + buf[TX_BCMC_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE3); + buf[TX_ATIM_FIFO] = (buf[TX_BCMC_FIFO] >> 8) & 0xff; + buf[TX_BCMC_FIFO] &= 0xff; + if (buf[TX_BCMC_FIFO] != wlc_hw->xmtfifo_sz[TX_BCMC_FIFO]) { + i = TX_BCMC_FIFO; + err = -1; + } + if (buf[TX_ATIM_FIFO] != wlc_hw->xmtfifo_sz[TX_ATIM_FIFO]) { + i = TX_ATIM_FIFO; + err = -1; + } + if (err != 0) { + WL_ERROR("wlc_coreinit: txfifo mismatch: ucode size %d driver size %d index %d\n", + buf[i], wlc_hw->xmtfifo_sz[i], i); + /* DO NOT ASSERT corerev < 4 even there is a mismatch + * shmem, since driver don't overwrite those chip and + * ucode initialize data will be used. + */ + if (D11REV_GE(wlc_hw->corerev, 4)) + ASSERT(0); + } + + /* make sure we can still talk to the mac */ + ASSERT(R_REG(osh, ®s->maccontrol) != 0xffffffff); + + /* band-specific inits done by wlc_bsinit() */ + + /* Set up frame burst size and antenna swap threshold init values */ + wlc_bmac_write_shm(wlc_hw, M_MBURST_SIZE, MAXTXFRAMEBURST); + wlc_bmac_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT); + + /* enable one rx interrupt per received frame */ + W_REG(osh, ®s->intrcvlazy[0], (1 << IRL_FC_SHIFT)); + if (D11REV_IS(wlc_hw->corerev, 4)) + W_REG(osh, ®s->intrcvlazy[3], (1 << IRL_FC_SHIFT)); + + /* set the station mode (BSS STA) */ + wlc_bmac_mctrl(wlc_hw, + (MCTL_INFRA | MCTL_DISCARD_PMQ | MCTL_AP), + (MCTL_INFRA | MCTL_DISCARD_PMQ)); + + /* set up Beacon interval */ + bcnint_us = 0x8000 << 10; + W_REG(osh, ®s->tsf_cfprep, (bcnint_us << CFPREP_CBI_SHIFT)); + W_REG(osh, ®s->tsf_cfpstart, bcnint_us); + W_REG(osh, ®s->macintstatus, MI_GP1); + + /* write interrupt mask */ + W_REG(osh, ®s->intctrlregs[RX_FIFO].intmask, DEF_RXINTMASK); + if (D11REV_IS(wlc_hw->corerev, 4)) + W_REG(osh, ®s->intctrlregs[RX_TXSTATUS_FIFO].intmask, + DEF_RXINTMASK); + + /* allow the MAC to control the PHY clock (dynamic on/off) */ + wlc_bmac_macphyclk_set(wlc_hw, ON); + + /* program dynamic clock control fast powerup delay register */ + if (D11REV_GT(wlc_hw->corerev, 4)) { + wlc->fastpwrup_dly = si_clkctl_fast_pwrup_delay(wlc_hw->sih); + W_REG(osh, ®s->scc_fastpwrup_dly, wlc->fastpwrup_dly); + } + + /* tell the ucode the corerev */ + wlc_bmac_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev); + + /* tell the ucode MAC capabilities */ + if (D11REV_GE(wlc_hw->corerev, 13)) { + wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_L, + (u16) (wlc_hw->machwcap & 0xffff)); + wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_H, + (u16) ((wlc_hw-> + machwcap >> 16) & 0xffff)); + } + + /* write retry limits to SCR, this done after PSM init */ + W_REG(osh, ®s->objaddr, OBJADDR_SCR_SEL | S_DOT11_SRC_LMT); + (void)R_REG(osh, ®s->objaddr); + W_REG(osh, ®s->objdata, wlc_hw->SRL); + W_REG(osh, ®s->objaddr, OBJADDR_SCR_SEL | S_DOT11_LRC_LMT); + (void)R_REG(osh, ®s->objaddr); + W_REG(osh, ®s->objdata, wlc_hw->LRL); + + /* write rate fallback retry limits */ + wlc_bmac_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL); + wlc_bmac_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL); + + if (D11REV_GE(wlc_hw->corerev, 16)) { + AND_REG(osh, ®s->ifs_ctl, 0x0FFF); + W_REG(osh, ®s->ifs_aifsn, EDCF_AIFSN_MIN); + } + + /* dma initializations */ + wlc->txpend16165war = 0; + + /* init the tx dma engines */ + for (i = 0; i < NFIFO; i++) { + if (wlc_hw->di[i]) + dma_txinit(wlc_hw->di[i]); + } + + /* init the rx dma engine(s) and post receive buffers */ + dma_rxinit(wlc_hw->di[RX_FIFO]); + dma_rxfill(wlc_hw->di[RX_FIFO]); + if (D11REV_IS(wlc_hw->corerev, 4)) { + dma_rxinit(wlc_hw->di[RX_TXSTATUS_FIFO]); + dma_rxfill(wlc_hw->di[RX_TXSTATUS_FIFO]); + } +} + +/* This function is used for changing the tsf frac register + * If spur avoidance mode is off, the mac freq will be 80/120/160Mhz + * If spur avoidance mode is on1, the mac freq will be 82/123/164Mhz + * If spur avoidance mode is on2, the mac freq will be 84/126/168Mhz + * HTPHY Formula is 2^26/freq(MHz) e.g. + * For spuron2 - 126MHz -> 2^26/126 = 532610.0 + * - 532610 = 0x82082 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x2082 + * For spuron: 123MHz -> 2^26/123 = 545600.5 + * - 545601 = 0x85341 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x5341 + * For spur off: 120MHz -> 2^26/120 = 559240.5 + * - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889 + */ + +void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode) +{ + d11regs_t *regs; + struct osl_info *osh; + regs = wlc_hw->regs; + osh = wlc_hw->osh; + + if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || + (wlc_hw->sih->chip == BCM43225_CHIP_ID)) { + if (spurmode == WL_SPURAVOID_ON2) { /* 126Mhz */ + W_REG(osh, ®s->tsf_clk_frac_l, 0x2082); + W_REG(osh, ®s->tsf_clk_frac_h, 0x8); + } else if (spurmode == WL_SPURAVOID_ON1) { /* 123Mhz */ + W_REG(osh, ®s->tsf_clk_frac_l, 0x5341); + W_REG(osh, ®s->tsf_clk_frac_h, 0x8); + } else { /* 120Mhz */ + W_REG(osh, ®s->tsf_clk_frac_l, 0x8889); + W_REG(osh, ®s->tsf_clk_frac_h, 0x8); + } + } else if (WLCISLCNPHY(wlc_hw->band)) { + if (spurmode == WL_SPURAVOID_ON1) { /* 82Mhz */ + W_REG(osh, ®s->tsf_clk_frac_l, 0x7CE0); + W_REG(osh, ®s->tsf_clk_frac_h, 0xC); + } else { /* 80Mhz */ + W_REG(osh, ®s->tsf_clk_frac_l, 0xCCCD); + W_REG(osh, ®s->tsf_clk_frac_h, 0xC); + } + } +} + +/* Initialize GPIOs that are controlled by D11 core */ +static void wlc_gpio_init(struct wlc_info *wlc) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + d11regs_t *regs; + u32 gc, gm; + struct osl_info *osh; + + regs = wlc_hw->regs; + osh = wlc_hw->osh; + + /* use GPIO select 0 to get all gpio signals from the gpio out reg */ + wlc_bmac_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0); + + /* + * Common GPIO setup: + * G0 = LED 0 = WLAN Activity + * G1 = LED 1 = WLAN 2.4 GHz Radio State + * G2 = LED 2 = WLAN 5 GHz Radio State + * G4 = radio disable input (HI enabled, LO disabled) + */ + + gc = gm = 0; + + /* Allocate GPIOs for mimo antenna diversity feature */ + if (WLANTSEL_ENAB(wlc)) { + if (wlc_hw->antsel_type == ANTSEL_2x3) { + /* Enable antenna diversity, use 2x3 mode */ + wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, + MHF3_ANTSEL_EN, WLC_BAND_ALL); + wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, + MHF3_ANTSEL_MODE, WLC_BAND_ALL); + + /* init superswitch control */ + wlc_phy_antsel_init(wlc_hw->band->pi, false); + + } else if (wlc_hw->antsel_type == ANTSEL_2x4) { + ASSERT((gm & BOARD_GPIO_12) == 0); + gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13); + /* The board itself is powered by these GPIOs (when not sending pattern) + * So set them high + */ + OR_REG(osh, ®s->psm_gpio_oe, + (BOARD_GPIO_12 | BOARD_GPIO_13)); + OR_REG(osh, ®s->psm_gpio_out, + (BOARD_GPIO_12 | BOARD_GPIO_13)); + + /* Enable antenna diversity, use 2x4 mode */ + wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, + MHF3_ANTSEL_EN, WLC_BAND_ALL); + wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0, + WLC_BAND_ALL); + + /* Configure the desired clock to be 4Mhz */ + wlc_bmac_write_shm(wlc_hw, M_ANTSEL_CLKDIV, + ANTSEL_CLKDIV_4MHZ); + } + } + /* gpio 9 controls the PA. ucode is responsible for wiggling out and oe */ + if (wlc_hw->boardflags & BFL_PACTRL) + gm |= gc |= BOARD_GPIO_PACTRL; + + /* apply to gpiocontrol register */ + si_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY); +} + +static void wlc_ucode_download(struct wlc_hw_info *wlc_hw) +{ + struct wlc_info *wlc; + wlc = wlc_hw->wlc; + + if (wlc_hw->ucode_loaded) + return; + + if (D11REV_IS(wlc_hw->corerev, 23)) { + if (WLCISNPHY(wlc_hw->band)) { + wlc_ucode_write(wlc_hw, bcm43xx_16_mimo, + bcm43xx_16_mimosz); + wlc_hw->ucode_loaded = true; + } else + WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); + } else if (D11REV_IS(wlc_hw->corerev, 24)) { + if (WLCISLCNPHY(wlc_hw->band)) { + wlc_ucode_write(wlc_hw, bcm43xx_24_lcn, + bcm43xx_24_lcnsz); + wlc_hw->ucode_loaded = true; + } else { + WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); + } + } +} + +static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[], + const uint nbytes) { + struct osl_info *osh; + d11regs_t *regs = wlc_hw->regs; + uint i; + uint count; + + osh = wlc_hw->osh; + + WL_TRACE("wl%d: wlc_ucode_write\n", wlc_hw->unit); + + ASSERT(IS_ALIGNED(nbytes, sizeof(u32))); + + count = (nbytes / sizeof(u32)); + + W_REG(osh, ®s->objaddr, (OBJADDR_AUTO_INC | OBJADDR_UCM_SEL)); + (void)R_REG(osh, ®s->objaddr); + for (i = 0; i < count; i++) + W_REG(osh, ®s->objdata, ucode[i]); +} + +static void wlc_write_inits(struct wlc_hw_info *wlc_hw, const d11init_t *inits) +{ + int i; + struct osl_info *osh; + volatile u8 *base; + + WL_TRACE("wl%d: wlc_write_inits\n", wlc_hw->unit); + + osh = wlc_hw->osh; + base = (volatile u8 *)wlc_hw->regs; + + for (i = 0; inits[i].addr != 0xffff; i++) { + ASSERT((inits[i].size == 2) || (inits[i].size == 4)); + + if (inits[i].size == 2) + W_REG(osh, (u16 *)(base + inits[i].addr), + inits[i].value); + else if (inits[i].size == 4) + W_REG(osh, (u32 *)(base + inits[i].addr), + inits[i].value); + } +} + +static void wlc_ucode_txant_set(struct wlc_hw_info *wlc_hw) +{ + u16 phyctl; + u16 phytxant = wlc_hw->bmac_phytxant; + u16 mask = PHY_TXC_ANT_MASK; + + /* set the Probe Response frame phy control word */ + phyctl = wlc_bmac_read_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS); + phyctl = (phyctl & ~mask) | phytxant; + wlc_bmac_write_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS, phyctl); + + /* set the Response (ACK/CTS) frame phy control word */ + phyctl = wlc_bmac_read_shm(wlc_hw, M_RSP_PCTLWD); + phyctl = (phyctl & ~mask) | phytxant; + wlc_bmac_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl); +} + +void wlc_bmac_txant_set(struct wlc_hw_info *wlc_hw, u16 phytxant) +{ + /* update sw state */ + wlc_hw->bmac_phytxant = phytxant; + + /* push to ucode if up */ + if (!wlc_hw->up) + return; + wlc_ucode_txant_set(wlc_hw); + +} + +u16 wlc_bmac_get_txant(struct wlc_hw_info *wlc_hw) +{ + return (u16) wlc_hw->wlc->stf->txant; +} + +void wlc_bmac_antsel_type_set(struct wlc_hw_info *wlc_hw, u8 antsel_type) +{ + wlc_hw->antsel_type = antsel_type; + + /* Update the antsel type for phy module to use */ + wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type); +} + +void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw) +{ + bool fatal = false; + uint unit; + uint intstatus, idx; + d11regs_t *regs = wlc_hw->regs; + + unit = wlc_hw->unit; + + for (idx = 0; idx < NFIFO; idx++) { + /* read intstatus register and ignore any non-error bits */ + intstatus = + R_REG(wlc_hw->osh, + ®s->intctrlregs[idx].intstatus) & I_ERRORS; + if (!intstatus) + continue; + + WL_TRACE("wl%d: wlc_bmac_fifoerrors: intstatus%d 0x%x\n", + unit, idx, intstatus); + + if (intstatus & I_RO) { + WL_ERROR("wl%d: fifo %d: receive fifo overflow\n", + unit, idx); + WLCNTINCR(wlc_hw->wlc->pub->_cnt->rxoflo); + fatal = true; + } + + if (intstatus & I_PC) { + WL_ERROR("wl%d: fifo %d: descriptor error\n", + unit, idx); + WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmade); + fatal = true; + } + + if (intstatus & I_PD) { + WL_ERROR("wl%d: fifo %d: data error\n", unit, idx); + WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmada); + fatal = true; + } + + if (intstatus & I_DE) { + WL_ERROR("wl%d: fifo %d: descriptor protocol error\n", + unit, idx); + WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmape); + fatal = true; + } + + if (intstatus & I_RU) { + WL_ERROR("wl%d: fifo %d: receive descriptor underflow\n", + idx, unit); + WLCNTINCR(wlc_hw->wlc->pub->_cnt->rxuflo[idx]); + } + + if (intstatus & I_XU) { + WL_ERROR("wl%d: fifo %d: transmit fifo underflow\n", + idx, unit); + WLCNTINCR(wlc_hw->wlc->pub->_cnt->txuflo); + fatal = true; + } + + if (fatal) { + wlc_fatal_error(wlc_hw->wlc); /* big hammer */ + break; + } else + W_REG(wlc_hw->osh, ®s->intctrlregs[idx].intstatus, + intstatus); + } +} + +void wlc_intrson(struct wlc_info *wlc) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + ASSERT(wlc->defmacintmask); + wlc->macintmask = wlc->defmacintmask; + W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, wlc->macintmask); +} + +/* callback for siutils.c, which has only wlc handler, no wl + * they both check up, not only because there is no need to off/restore d11 interrupt + * but also because per-port code may require sync with valid interrupt. + */ + +static u32 wlc_wlintrsoff(struct wlc_info *wlc) +{ + if (!wlc->hw->up) + return 0; + + return wl_intrsoff(wlc->wl); +} + +static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask) +{ + if (!wlc->hw->up) + return; + + wl_intrsrestore(wlc->wl, macintmask); +} + +u32 wlc_intrsoff(struct wlc_info *wlc) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + u32 macintmask; + + if (!wlc_hw->clk) + return 0; + + macintmask = wlc->macintmask; /* isr can still happen */ + + W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, 0); + (void)R_REG(wlc_hw->osh, &wlc_hw->regs->macintmask); /* sync readback */ + udelay(1); /* ensure int line is no longer driven */ + wlc->macintmask = 0; + + /* return previous macintmask; resolve race between us and our isr */ + return wlc->macintstatus ? 0 : macintmask; +} + +void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + if (!wlc_hw->clk) + return; + + wlc->macintmask = macintmask; + W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, wlc->macintmask); +} + +void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool on, mbool flags) +{ + u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; + + if (on) { + /* suspend tx fifos */ + wlc_bmac_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO); + wlc_bmac_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO); + wlc_bmac_tx_fifo_suspend(wlc_hw, TX_AC_BK_FIFO); + wlc_bmac_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO); + + /* zero the address match register so we do not send ACKs */ + wlc_bmac_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, + null_ether_addr); + } else { + /* resume tx fifos */ + if (!wlc_hw->wlc->tx_suspended) { + wlc_bmac_tx_fifo_resume(wlc_hw, TX_DATA_FIFO); + } + wlc_bmac_tx_fifo_resume(wlc_hw, TX_CTL_FIFO); + wlc_bmac_tx_fifo_resume(wlc_hw, TX_AC_BK_FIFO); + wlc_bmac_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO); + + /* Restore address */ + wlc_bmac_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, + wlc_hw->etheraddr); + } + + wlc_phy_mute_upd(wlc_hw->band->pi, on, flags); + + if (on) + wlc_ucode_mute_override_set(wlc_hw); + else + wlc_ucode_mute_override_clear(wlc_hw); +} + +void wlc_bmac_set_deaf(struct wlc_hw_info *wlc_hw, bool user_flag) +{ + wlc_phy_set_deaf(wlc_hw->band->pi, user_flag); +} + +int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, uint *blocks) +{ + if (fifo >= NFIFO) + return BCME_RANGE; + + *blocks = wlc_hw->xmtfifo_sz[fifo]; + + return 0; +} + +int wlc_bmac_xmtfifo_sz_set(struct wlc_hw_info *wlc_hw, uint fifo, uint blocks) +{ + if (fifo >= NFIFO || blocks > 299) + return BCME_RANGE; + + /* BMAC_NOTE, change blocks to u16 */ + wlc_hw->xmtfifo_sz[fifo] = (u16) blocks; + + return 0; +} + +/* wlc_bmac_tx_fifo_suspended: + * Check the MAC's tx suspend status for a tx fifo. + * + * When the MAC acknowledges a tx suspend, it indicates that no more + * packets will be transmitted out the radio. This is independent of + * DMA channel suspension---the DMA may have finished suspending, or may still + * be pulling data into a tx fifo, by the time the MAC acks the suspend + * request. + */ +bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, uint tx_fifo) +{ + /* check that a suspend has been requested and is no longer pending */ + + /* + * for DMA mode, the suspend request is set in xmtcontrol of the DMA engine, + * and the tx fifo suspend at the lower end of the MAC is acknowledged in the + * chnstatus register. + * The tx fifo suspend completion is independent of the DMA suspend completion and + * may be acked before or after the DMA is suspended. + */ + if (dma_txsuspended(wlc_hw->di[tx_fifo]) && + (R_REG(wlc_hw->osh, &wlc_hw->regs->chnstatus) & + (1 << tx_fifo)) == 0) + return true; + + return false; +} + +void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo) +{ + u8 fifo = 1 << tx_fifo; + + /* Two clients of this code, 11h Quiet period and scanning. */ + + /* only suspend if not already suspended */ + if ((wlc_hw->suspended_fifos & fifo) == fifo) + return; + + /* force the core awake only if not already */ + if (wlc_hw->suspended_fifos == 0) + wlc_ucode_wake_override_set(wlc_hw, WLC_WAKE_OVERRIDE_TXFIFO); + + wlc_hw->suspended_fifos |= fifo; + + if (wlc_hw->di[tx_fifo]) { + /* Suspending AMPDU transmissions in the middle can cause underflow + * which may result in mismatch between ucode and driver + * so suspend the mac before suspending the FIFO + */ + if (WLC_PHY_11N_CAP(wlc_hw->band)) + wlc_suspend_mac_and_wait(wlc_hw->wlc); + + dma_txsuspend(wlc_hw->di[tx_fifo]); + + if (WLC_PHY_11N_CAP(wlc_hw->band)) + wlc_enable_mac(wlc_hw->wlc); + } +} + +void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo) +{ + /* BMAC_NOTE: WLC_TX_FIFO_ENAB is done in wlc_dpc() for DMA case but need to be done + * here for PIO otherwise the watchdog will catch the inconsistency and fire + */ + /* Two clients of this code, 11h Quiet period and scanning. */ + if (wlc_hw->di[tx_fifo]) + dma_txresume(wlc_hw->di[tx_fifo]); + + /* allow core to sleep again */ + if (wlc_hw->suspended_fifos == 0) + return; + else { + wlc_hw->suspended_fifos &= ~(1 << tx_fifo); + if (wlc_hw->suspended_fifos == 0) + wlc_ucode_wake_override_clear(wlc_hw, + WLC_WAKE_OVERRIDE_TXFIFO); + } +} + +/* + * Read and clear macintmask and macintstatus and intstatus registers. + * This routine should be called with interrupts off + * Return: + * -1 if DEVICEREMOVED(wlc) evaluates to true; + * 0 if the interrupt is not for us, or we are in some special cases; + * device interrupt status bits otherwise. + */ +static inline u32 wlc_intstatus(struct wlc_info *wlc, bool in_isr) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + d11regs_t *regs = wlc_hw->regs; + u32 macintstatus; + u32 intstatus_rxfifo, intstatus_txsfifo; + struct osl_info *osh; + + osh = wlc_hw->osh; + + /* macintstatus includes a DMA interrupt summary bit */ + macintstatus = R_REG(osh, ®s->macintstatus); + + WL_TRACE("wl%d: macintstatus: 0x%x\n", wlc_hw->unit, macintstatus); + + /* detect cardbus removed, in power down(suspend) and in reset */ + if (DEVICEREMOVED(wlc)) + return -1; + + /* DEVICEREMOVED succeeds even when the core is still resetting, + * handle that case here. + */ + if (macintstatus == 0xffffffff) + return 0; + + /* defer unsolicited interrupts */ + macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask); + + /* if not for us */ + if (macintstatus == 0) + return 0; + + /* interrupts are already turned off for CFE build + * Caution: For CFE Turning off the interrupts again has some undesired + * consequences + */ + /* turn off the interrupts */ + W_REG(osh, ®s->macintmask, 0); + (void)R_REG(osh, ®s->macintmask); /* sync readback */ + wlc->macintmask = 0; + + /* clear device interrupts */ + W_REG(osh, ®s->macintstatus, macintstatus); + + /* MI_DMAINT is indication of non-zero intstatus */ + if (macintstatus & MI_DMAINT) { + if (D11REV_IS(wlc_hw->corerev, 4)) { + intstatus_rxfifo = + R_REG(osh, ®s->intctrlregs[RX_FIFO].intstatus); + intstatus_txsfifo = + R_REG(osh, + ®s->intctrlregs[RX_TXSTATUS_FIFO]. + intstatus); + WL_TRACE("wl%d: intstatus_rxfifo 0x%x, intstatus_txsfifo 0x%x\n", + wlc_hw->unit, + intstatus_rxfifo, intstatus_txsfifo); + + /* defer unsolicited interrupt hints */ + intstatus_rxfifo &= DEF_RXINTMASK; + intstatus_txsfifo &= DEF_RXINTMASK; + + /* MI_DMAINT bit in macintstatus is indication of RX_FIFO interrupt */ + /* clear interrupt hints */ + if (intstatus_rxfifo) + W_REG(osh, + ®s->intctrlregs[RX_FIFO].intstatus, + intstatus_rxfifo); + else + macintstatus &= ~MI_DMAINT; + + /* MI_TFS bit in macintstatus is encoding of RX_TXSTATUS_FIFO interrupt */ + if (intstatus_txsfifo) { + W_REG(osh, + ®s->intctrlregs[RX_TXSTATUS_FIFO]. + intstatus, intstatus_txsfifo); + macintstatus |= MI_TFS; + } + } else { + /* + * For corerevs >= 5, only fifo interrupt enabled is I_RI in RX_FIFO. + * If MI_DMAINT is set, assume it is set and clear the interrupt. + */ + W_REG(osh, ®s->intctrlregs[RX_FIFO].intstatus, + DEF_RXINTMASK); + } + } + + return macintstatus; +} + +/* Update wlc->macintstatus and wlc->intstatus[]. */ +/* Return true if they are updated successfully. false otherwise */ +bool wlc_intrsupd(struct wlc_info *wlc) +{ + u32 macintstatus; + + ASSERT(wlc->macintstatus != 0); + + /* read and clear macintstatus and intstatus registers */ + macintstatus = wlc_intstatus(wlc, false); + + /* device is removed */ + if (macintstatus == 0xffffffff) + return false; + + /* update interrupt status in software */ + wlc->macintstatus |= macintstatus; + + return true; +} + +/* + * First-level interrupt processing. + * Return true if this was our interrupt, false otherwise. + * *wantdpc will be set to true if further wlc_dpc() processing is required, + * false otherwise. + */ +bool BCMFASTPATH wlc_isr(struct wlc_info *wlc, bool *wantdpc) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + u32 macintstatus; + + *wantdpc = false; + + if (!wlc_hw->up || !wlc->macintmask) + return false; + + /* read and clear macintstatus and intstatus registers */ + macintstatus = wlc_intstatus(wlc, true); + + if (macintstatus == 0xffffffff) + WL_ERROR("DEVICEREMOVED detected in the ISR code path\n"); + + /* it is not for us */ + if (macintstatus == 0) + return false; + + *wantdpc = true; + + /* save interrupt status bits */ + ASSERT(wlc->macintstatus == 0); + wlc->macintstatus = macintstatus; + + return true; + +} + +/* process tx completion events for corerev < 5 */ +static bool wlc_bmac_txstatus_corerev4(struct wlc_hw_info *wlc_hw) +{ + struct sk_buff *status_p; + tx_status_t *txs; + struct osl_info *osh; + bool fatal = false; + + WL_TRACE("wl%d: wlc_txstatusrecv\n", wlc_hw->unit); + + osh = wlc_hw->osh; + + while (!fatal && (status_p = dma_rx(wlc_hw->di[RX_TXSTATUS_FIFO]))) { + + txs = (tx_status_t *) status_p->data; + /* MAC uses little endian only */ + ltoh16_buf((void *)txs, sizeof(tx_status_t)); + + /* shift low bits for tx_status_t status compatibility */ + txs->status = (txs->status & ~TXS_COMPAT_MASK) + | (((txs->status & TXS_COMPAT_MASK) << TXS_COMPAT_SHIFT)); + + fatal = wlc_bmac_dotxstatus(wlc_hw, txs, 0); + + pkt_buf_free_skb(osh, status_p, false); + } + + if (fatal) + return true; + + /* post more rbufs */ + dma_rxfill(wlc_hw->di[RX_TXSTATUS_FIFO]); + + return false; +} + +static bool BCMFASTPATH +wlc_bmac_dotxstatus(struct wlc_hw_info *wlc_hw, tx_status_t *txs, u32 s2) +{ + /* discard intermediate indications for ucode with one legitimate case: + * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent + * tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts + * transmission count) + */ + if (!(txs->status & TX_STATUS_AMPDU) + && (txs->status & TX_STATUS_INTERMEDIATE)) { + return false; + } + + return wlc_dotxstatus(wlc_hw->wlc, txs, s2); +} + +/* process tx completion events in BMAC + * Return true if more tx status need to be processed. false otherwise. + */ +static bool BCMFASTPATH +wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal) +{ + bool morepending = false; + struct wlc_info *wlc = wlc_hw->wlc; + + WL_TRACE("wl%d: wlc_bmac_txstatus\n", wlc_hw->unit); + + if (D11REV_IS(wlc_hw->corerev, 4)) { + /* to retire soon */ + *fatal = wlc_bmac_txstatus_corerev4(wlc->hw); + + if (*fatal) + return 0; + } else { + /* corerev >= 5 */ + d11regs_t *regs; + struct osl_info *osh; + tx_status_t txstatus, *txs; + u32 s1, s2; + uint n = 0; + /* Param 'max_tx_num' indicates max. # tx status to process before break out. */ + uint max_tx_num = bound ? wlc->pub->tunables->txsbnd : -1; + + txs = &txstatus; + regs = wlc_hw->regs; + osh = wlc_hw->osh; + while (!(*fatal) + && (s1 = R_REG(osh, ®s->frmtxstatus)) & TXS_V) { + + if (s1 == 0xffffffff) { + WL_ERROR("wl%d: %s: dead chip\n", + wlc_hw->unit, __func__); + ASSERT(s1 != 0xffffffff); + return morepending; + } + + s2 = R_REG(osh, ®s->frmtxstatus2); + + txs->status = s1 & TXS_STATUS_MASK; + txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT; + txs->sequence = s2 & TXS_SEQ_MASK; + txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT; + txs->lasttxtime = 0; + + *fatal = wlc_bmac_dotxstatus(wlc_hw, txs, s2); + + /* !give others some time to run! */ + if (++n >= max_tx_num) + break; + } + + if (*fatal) + return 0; + + if (n >= max_tx_num) + morepending = true; + } + + if (!pktq_empty(&wlc->active_queue->q)) + wlc_send_q(wlc, wlc->active_queue); + + return morepending; +} + +void wlc_suspend_mac_and_wait(struct wlc_info *wlc) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + d11regs_t *regs = wlc_hw->regs; + u32 mc, mi; + struct osl_info *osh; + + WL_TRACE("wl%d: wlc_suspend_mac_and_wait: bandunit %d\n", + wlc_hw->unit, wlc_hw->band->bandunit); + + /* + * Track overlapping suspend requests + */ + wlc_hw->mac_suspend_depth++; + if (wlc_hw->mac_suspend_depth > 1) + return; + + osh = wlc_hw->osh; + + /* force the core awake */ + wlc_ucode_wake_override_set(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND); + + mc = R_REG(osh, ®s->maccontrol); + + if (mc == 0xffffffff) { + WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); + wl_down(wlc->wl); + return; + } + ASSERT(!(mc & MCTL_PSM_JMP_0)); + ASSERT(mc & MCTL_PSM_RUN); + ASSERT(mc & MCTL_EN_MAC); + + mi = R_REG(osh, ®s->macintstatus); + if (mi == 0xffffffff) { + WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); + wl_down(wlc->wl); + return; + } + ASSERT(!(mi & MI_MACSSPNDD)); + + wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, 0); + + SPINWAIT(!(R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD), + WLC_MAX_MAC_SUSPEND); + + if (!(R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD)) { + WL_ERROR("wl%d: wlc_suspend_mac_and_wait: waited %d uS and MI_MACSSPNDD is still not on.\n", + wlc_hw->unit, WLC_MAX_MAC_SUSPEND); + WL_ERROR("wl%d: psmdebug 0x%08x, phydebug 0x%08x, psm_brc 0x%04x\n", + wlc_hw->unit, + R_REG(osh, ®s->psmdebug), + R_REG(osh, ®s->phydebug), + R_REG(osh, ®s->psm_brc)); + } + + mc = R_REG(osh, ®s->maccontrol); + if (mc == 0xffffffff) { + WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); + wl_down(wlc->wl); + return; + } + ASSERT(!(mc & MCTL_PSM_JMP_0)); + ASSERT(mc & MCTL_PSM_RUN); + ASSERT(!(mc & MCTL_EN_MAC)); +} + +void wlc_enable_mac(struct wlc_info *wlc) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + d11regs_t *regs = wlc_hw->regs; + u32 mc, mi; + struct osl_info *osh; + + WL_TRACE("wl%d: wlc_enable_mac: bandunit %d\n", + wlc_hw->unit, wlc->band->bandunit); + + /* + * Track overlapping suspend requests + */ + ASSERT(wlc_hw->mac_suspend_depth > 0); + wlc_hw->mac_suspend_depth--; + if (wlc_hw->mac_suspend_depth > 0) + return; + + osh = wlc_hw->osh; + + mc = R_REG(osh, ®s->maccontrol); + ASSERT(!(mc & MCTL_PSM_JMP_0)); + ASSERT(!(mc & MCTL_EN_MAC)); + ASSERT(mc & MCTL_PSM_RUN); + + wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC); + W_REG(osh, ®s->macintstatus, MI_MACSSPNDD); + + mc = R_REG(osh, ®s->maccontrol); + ASSERT(!(mc & MCTL_PSM_JMP_0)); + ASSERT(mc & MCTL_EN_MAC); + ASSERT(mc & MCTL_PSM_RUN); + + mi = R_REG(osh, ®s->macintstatus); + ASSERT(!(mi & MI_MACSSPNDD)); + + wlc_ucode_wake_override_clear(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND); +} + +void wlc_bmac_ifsctl_edcrs_set(struct wlc_hw_info *wlc_hw, bool abie, bool isht) +{ + if (!(WLCISNPHY(wlc_hw->band) && (D11REV_GE(wlc_hw->corerev, 16)))) + return; + + if (isht) { + if (WLCISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 3)) { + AND_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, + ~IFS_CTL1_EDCRS); + } + } else { + /* enable EDCRS for non-11n association */ + OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, IFS_CTL1_EDCRS); + } + + if (WLCISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3)) { + if (CHSPEC_IS20(wlc_hw->chanspec)) { + /* 20 mhz, use 20U ED only */ + OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, + IFS_CTL1_EDCRS); + AND_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, + ~IFS_CTL1_EDCRS_20L); + AND_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, + ~IFS_CTL1_EDCRS_40); + } else { + /* 40 mhz, use 20U 20L and 40 ED */ + OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, + IFS_CTL1_EDCRS); + OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, + IFS_CTL1_EDCRS_20L); + OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, + IFS_CTL1_EDCRS_40); + } + } +} + +static void wlc_upd_ofdm_pctl1_table(struct wlc_hw_info *wlc_hw) +{ + u8 rate; + u8 rates[8] = { + WLC_RATE_6M, WLC_RATE_9M, WLC_RATE_12M, WLC_RATE_18M, + WLC_RATE_24M, WLC_RATE_36M, WLC_RATE_48M, WLC_RATE_54M + }; + u16 entry_ptr; + u16 pctl1; + uint i; + + if (!WLC_PHY_11N_CAP(wlc_hw->band)) + return; + + /* walk the phy rate table and update the entries */ + for (i = 0; i < ARRAY_SIZE(rates); i++) { + rate = rates[i]; + + entry_ptr = wlc_bmac_ofdm_ratetable_offset(wlc_hw, rate); + + /* read the SHM Rate Table entry OFDM PCTL1 values */ + pctl1 = + wlc_bmac_read_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS); + + /* modify the value */ + pctl1 &= ~PHY_TXC1_MODE_MASK; + pctl1 |= (wlc_hw->hw_stf_ss_opmode << PHY_TXC1_MODE_SHIFT); + + /* Update the SHM Rate Table entry OFDM PCTL1 values */ + wlc_bmac_write_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS, + pctl1); + } +} + +static u16 wlc_bmac_ofdm_ratetable_offset(struct wlc_hw_info *wlc_hw, u8 rate) +{ + uint i; + u8 plcp_rate = 0; + struct plcp_signal_rate_lookup { + u8 rate; + u8 signal_rate; + }; + /* OFDM RATE sub-field of PLCP SIGNAL field, per 802.11 sec 17.3.4.1 */ + const struct plcp_signal_rate_lookup rate_lookup[] = { + {WLC_RATE_6M, 0xB}, + {WLC_RATE_9M, 0xF}, + {WLC_RATE_12M, 0xA}, + {WLC_RATE_18M, 0xE}, + {WLC_RATE_24M, 0x9}, + {WLC_RATE_36M, 0xD}, + {WLC_RATE_48M, 0x8}, + {WLC_RATE_54M, 0xC} + }; + + for (i = 0; i < ARRAY_SIZE(rate_lookup); i++) { + if (rate == rate_lookup[i].rate) { + plcp_rate = rate_lookup[i].signal_rate; + break; + } + } + + /* Find the SHM pointer to the rate table entry by looking in the + * Direct-map Table + */ + return 2 * wlc_bmac_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2)); +} + +void wlc_bmac_band_stf_ss_set(struct wlc_hw_info *wlc_hw, u8 stf_mode) +{ + wlc_hw->hw_stf_ss_opmode = stf_mode; + + if (wlc_hw->clk) + wlc_upd_ofdm_pctl1_table(wlc_hw); +} + +void BCMFASTPATH +wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr, + u32 *tsf_h_ptr) +{ + d11regs_t *regs = wlc_hw->regs; + + /* read the tsf timer low, then high to get an atomic read */ + *tsf_l_ptr = R_REG(wlc_hw->osh, ®s->tsf_timerlow); + *tsf_h_ptr = R_REG(wlc_hw->osh, ®s->tsf_timerhigh); + + return; +} + +bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) +{ + d11regs_t *regs; + u32 w, val; + volatile u16 *reg16; + struct osl_info *osh; + + WL_TRACE("wl%d: validate_chip_access\n", wlc_hw->unit); + + regs = wlc_hw->regs; + osh = wlc_hw->osh; + + /* Validate dchip register access */ + + W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(osh, ®s->objaddr); + w = R_REG(osh, ®s->objdata); + + /* Can we write and read back a 32bit register? */ + W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(osh, ®s->objaddr); + W_REG(osh, ®s->objdata, (u32) 0xaa5555aa); + + W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(osh, ®s->objaddr); + val = R_REG(osh, ®s->objdata); + if (val != (u32) 0xaa5555aa) { + WL_ERROR("wl%d: validate_chip_access: SHM = 0x%x, expected 0xaa5555aa\n", + wlc_hw->unit, val); + return false; + } + + W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(osh, ®s->objaddr); + W_REG(osh, ®s->objdata, (u32) 0x55aaaa55); + + W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(osh, ®s->objaddr); + val = R_REG(osh, ®s->objdata); + if (val != (u32) 0x55aaaa55) { + WL_ERROR("wl%d: validate_chip_access: SHM = 0x%x, expected 0x55aaaa55\n", + wlc_hw->unit, val); + return false; + } + + W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(osh, ®s->objaddr); + W_REG(osh, ®s->objdata, w); + + if (D11REV_LT(wlc_hw->corerev, 11)) { + /* if 32 bit writes are split into 16 bit writes, are they in the correct order + * for our interface, low to high + */ + reg16 = (volatile u16 *)®s->tsf_cfpstart; + + /* write the CFPStart register low half explicitly, starting a buffered write */ + W_REG(osh, reg16, 0xAAAA); + + /* Write a 32 bit value to CFPStart to test the 16 bit split order. + * If the low 16 bits are written first, followed by the high 16 bits then the + * 32 bit value 0xCCCCBBBB should end up in the register. + * If the order is reversed, then the write to the high half will trigger a buffered + * write of 0xCCCCAAAA. + * If the bus is 32 bits, then this is not much of a test, and the reg should + * have the correct value 0xCCCCBBBB. + */ + W_REG(osh, ®s->tsf_cfpstart, 0xCCCCBBBB); + + /* verify with the 16 bit registers that have no side effects */ + val = R_REG(osh, ®s->tsf_cfpstrt_l); + if (val != (uint) 0xBBBB) { + WL_ERROR("wl%d: validate_chip_access: tsf_cfpstrt_l = 0x%x, expected 0x%x\n", + wlc_hw->unit, val, 0xBBBB); + return false; + } + val = R_REG(osh, ®s->tsf_cfpstrt_h); + if (val != (uint) 0xCCCC) { + WL_ERROR("wl%d: validate_chip_access: tsf_cfpstrt_h = 0x%x, expected 0x%x\n", + wlc_hw->unit, val, 0xCCCC); + return false; + } + + } + + /* clear CFPStart */ + W_REG(osh, ®s->tsf_cfpstart, 0); + + w = R_REG(osh, ®s->maccontrol); + if ((w != (MCTL_IHR_EN | MCTL_WAKE)) && + (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) { + WL_ERROR("wl%d: validate_chip_access: maccontrol = 0x%x, expected 0x%x or 0x%x\n", + wlc_hw->unit, w, + (MCTL_IHR_EN | MCTL_WAKE), + (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE)); + return false; + } + + return true; +} + +#define PHYPLL_WAIT_US 100000 + +void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on) +{ + d11regs_t *regs; + struct osl_info *osh; + u32 tmp; + + WL_TRACE("wl%d: wlc_bmac_core_phypll_ctl\n", wlc_hw->unit); + + tmp = 0; + regs = wlc_hw->regs; + osh = wlc_hw->osh; + + if (D11REV_LE(wlc_hw->corerev, 16) || D11REV_IS(wlc_hw->corerev, 20)) + return; + + if (on) { + if ((wlc_hw->sih->chip == BCM4313_CHIP_ID)) { + OR_REG(osh, ®s->clk_ctl_st, + (CCS_ERSRC_REQ_HT | CCS_ERSRC_REQ_D11PLL | + CCS_ERSRC_REQ_PHYPLL)); + SPINWAIT((R_REG(osh, ®s->clk_ctl_st) & + (CCS_ERSRC_AVAIL_HT)) != (CCS_ERSRC_AVAIL_HT), + PHYPLL_WAIT_US); + + tmp = R_REG(osh, ®s->clk_ctl_st); + if ((tmp & (CCS_ERSRC_AVAIL_HT)) != + (CCS_ERSRC_AVAIL_HT)) { + WL_ERROR("%s: turn on PHY PLL failed\n", + __func__); + ASSERT(0); + } + } else { + OR_REG(osh, ®s->clk_ctl_st, + (CCS_ERSRC_REQ_D11PLL | CCS_ERSRC_REQ_PHYPLL)); + SPINWAIT((R_REG(osh, ®s->clk_ctl_st) & + (CCS_ERSRC_AVAIL_D11PLL | + CCS_ERSRC_AVAIL_PHYPLL)) != + (CCS_ERSRC_AVAIL_D11PLL | + CCS_ERSRC_AVAIL_PHYPLL), PHYPLL_WAIT_US); + + tmp = R_REG(osh, ®s->clk_ctl_st); + if ((tmp & + (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) + != + (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) { + WL_ERROR("%s: turn on PHY PLL failed\n", + __func__); + ASSERT(0); + } + } + } else { + /* Since the PLL may be shared, other cores can still be requesting it; + * so we'll deassert the request but not wait for status to comply. + */ + AND_REG(osh, ®s->clk_ctl_st, ~CCS_ERSRC_REQ_PHYPLL); + tmp = R_REG(osh, ®s->clk_ctl_st); + } +} + +void wlc_coredisable(struct wlc_hw_info *wlc_hw) +{ + bool dev_gone; + + WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); + + ASSERT(!wlc_hw->up); + + dev_gone = DEVICEREMOVED(wlc_hw->wlc); + + if (dev_gone) + return; + + if (wlc_hw->noreset) + return; + + /* radio off */ + wlc_phy_switch_radio(wlc_hw->band->pi, OFF); + + /* turn off analog core */ + wlc_phy_anacore(wlc_hw->band->pi, OFF); + + /* turn off PHYPLL to save power */ + wlc_bmac_core_phypll_ctl(wlc_hw, false); + + /* No need to set wlc->pub->radio_active = OFF + * because this function needs down capability and + * radio_active is designed for BCMNODOWN. + */ + + /* remove gpio controls */ + if (wlc_hw->ucode_dbgsel) + si_gpiocontrol(wlc_hw->sih, ~0, 0, GPIO_DRV_PRIORITY); + + wlc_hw->clk = false; + si_core_disable(wlc_hw->sih, 0); + wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); +} + +/* power both the pll and external oscillator on/off */ +void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want) +{ + WL_TRACE("wl%d: wlc_bmac_xtal: want %d\n", wlc_hw->unit, want); + + /* dont power down if plldown is false or we must poll hw radio disable */ + if (!want && wlc_hw->pllreq) + return; + + if (wlc_hw->sih) + si_clkctl_xtal(wlc_hw->sih, XTAL | PLL, want); + + wlc_hw->sbclk = want; + if (!wlc_hw->sbclk) { + wlc_hw->clk = false; + if (wlc_hw->band && wlc_hw->band->pi) + wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); + } +} + +static void wlc_flushqueues(struct wlc_info *wlc) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + uint i; + + wlc->txpend16165war = 0; + + /* free any posted tx packets */ + for (i = 0; i < NFIFO; i++) + if (wlc_hw->di[i]) { + dma_txreclaim(wlc_hw->di[i], HNDDMA_RANGE_ALL); + TXPKTPENDCLR(wlc, i); + WL_TRACE("wlc_flushqueues: pktpend fifo %d cleared\n", + i); + } + + /* free any posted rx packets */ + dma_rxreclaim(wlc_hw->di[RX_FIFO]); + if (D11REV_IS(wlc_hw->corerev, 4)) + dma_rxreclaim(wlc_hw->di[RX_TXSTATUS_FIFO]); +} + +u16 wlc_bmac_read_shm(struct wlc_hw_info *wlc_hw, uint offset) +{ + return wlc_bmac_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL); +} + +void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v) +{ + wlc_bmac_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL); +} + +/* Set a range of shared memory to a value. + * SHM 'offset' needs to be an even address and + * Buffer length 'len' must be an even number of bytes + */ +void wlc_bmac_set_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v, int len) +{ + int i; + + /* offset and len need to be even */ + ASSERT((offset & 1) == 0); + ASSERT((len & 1) == 0); + + if (len <= 0) + return; + + for (i = 0; i < len; i += 2) { + wlc_bmac_write_objmem(wlc_hw, offset + i, v, OBJADDR_SHM_SEL); + } +} + +static u16 +wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, u32 sel) +{ + d11regs_t *regs = wlc_hw->regs; + volatile u16 *objdata_lo = (volatile u16 *)®s->objdata; + volatile u16 *objdata_hi = objdata_lo + 1; + u16 v; + + ASSERT((offset & 1) == 0); + + W_REG(wlc_hw->osh, ®s->objaddr, sel | (offset >> 2)); + (void)R_REG(wlc_hw->osh, ®s->objaddr); + if (offset & 2) { + v = R_REG(wlc_hw->osh, objdata_hi); + } else { + v = R_REG(wlc_hw->osh, objdata_lo); + } + + return v; +} + +static void +wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset, u16 v, u32 sel) +{ + d11regs_t *regs = wlc_hw->regs; + volatile u16 *objdata_lo = (volatile u16 *)®s->objdata; + volatile u16 *objdata_hi = objdata_lo + 1; + + ASSERT((offset & 1) == 0); + + W_REG(wlc_hw->osh, ®s->objaddr, sel | (offset >> 2)); + (void)R_REG(wlc_hw->osh, ®s->objaddr); + if (offset & 2) { + W_REG(wlc_hw->osh, objdata_hi, v); + } else { + W_REG(wlc_hw->osh, objdata_lo, v); + } +} + +/* Copy a buffer to shared memory of specified type . + * SHM 'offset' needs to be an even address and + * Buffer length 'len' must be an even number of bytes + * 'sel' selects the type of memory + */ +void +wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw, uint offset, const void *buf, + int len, u32 sel) +{ + u16 v; + const u8 *p = (const u8 *)buf; + int i; + + /* offset and len need to be even */ + ASSERT((offset & 1) == 0); + ASSERT((len & 1) == 0); + + if (len <= 0) + return; + + for (i = 0; i < len; i += 2) { + v = p[i] | (p[i + 1] << 8); + wlc_bmac_write_objmem(wlc_hw, offset + i, v, sel); + } +} + +/* Copy a piece of shared memory of specified type to a buffer . + * SHM 'offset' needs to be an even address and + * Buffer length 'len' must be an even number of bytes + * 'sel' selects the type of memory + */ +void +wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset, void *buf, + int len, u32 sel) +{ + u16 v; + u8 *p = (u8 *) buf; + int i; + + /* offset and len need to be even */ + ASSERT((offset & 1) == 0); + ASSERT((len & 1) == 0); + + if (len <= 0) + return; + + for (i = 0; i < len; i += 2) { + v = wlc_bmac_read_objmem(wlc_hw, offset + i, sel); + p[i] = v & 0xFF; + p[i + 1] = (v >> 8) & 0xFF; + } +} + +void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, uint *len) +{ + WL_TRACE("wlc_bmac_copyfrom_vars, nvram vars totlen=%d\n", + wlc_hw->vars_size); + + *buf = wlc_hw->vars; + *len = wlc_hw->vars_size; +} + +void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL, u16 LRL) +{ + wlc_hw->SRL = SRL; + wlc_hw->LRL = LRL; + + /* write retry limit to SCR, shouldn't need to suspend */ + if (wlc_hw->up) { + W_REG(wlc_hw->osh, &wlc_hw->regs->objaddr, + OBJADDR_SCR_SEL | S_DOT11_SRC_LMT); + (void)R_REG(wlc_hw->osh, &wlc_hw->regs->objaddr); + W_REG(wlc_hw->osh, &wlc_hw->regs->objdata, wlc_hw->SRL); + W_REG(wlc_hw->osh, &wlc_hw->regs->objaddr, + OBJADDR_SCR_SEL | S_DOT11_LRC_LMT); + (void)R_REG(wlc_hw->osh, &wlc_hw->regs->objaddr); + W_REG(wlc_hw->osh, &wlc_hw->regs->objdata, wlc_hw->LRL); + } +} + +void wlc_bmac_set_noreset(struct wlc_hw_info *wlc_hw, bool noreset_flag) +{ + wlc_hw->noreset = noreset_flag; +} + +void wlc_bmac_set_ucode_loaded(struct wlc_hw_info *wlc_hw, bool ucode_loaded) +{ + wlc_hw->ucode_loaded = ucode_loaded; +} + +void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, mbool req_bit) +{ + ASSERT(req_bit); + + if (set) { + if (mboolisset(wlc_hw->pllreq, req_bit)) + return; + + mboolset(wlc_hw->pllreq, req_bit); + + if (mboolisset(wlc_hw->pllreq, WLC_PLLREQ_FLIP)) { + if (!wlc_hw->sbclk) { + wlc_bmac_xtal(wlc_hw, ON); + } + } + } else { + if (!mboolisset(wlc_hw->pllreq, req_bit)) + return; + + mboolclr(wlc_hw->pllreq, req_bit); + + if (mboolisset(wlc_hw->pllreq, WLC_PLLREQ_FLIP)) { + if (wlc_hw->sbclk) { + wlc_bmac_xtal(wlc_hw, OFF); + } + } + } + + return; +} + +void wlc_bmac_set_clk(struct wlc_hw_info *wlc_hw, bool on) +{ + if (on) { + /* power up pll and oscillator */ + wlc_bmac_xtal(wlc_hw, ON); + + /* enable core(s), ignore bandlocked + * Leave with the same band selected as we entered + */ + wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); + } else { + /* if already down, must skip the core disable */ + if (wlc_hw->clk) { + /* disable core(s), ignore bandlocked */ + wlc_coredisable(wlc_hw); + } + /* power down pll and oscillator */ + wlc_bmac_xtal(wlc_hw, OFF); + } +} + +/* this will be true for all ai chips */ +bool wlc_bmac_taclear(struct wlc_hw_info *wlc_hw, bool ta_ok) +{ + return true; +} + +/* Lower down relevant GPIOs like LED when going down w/o + * doing PCI config cycles or touching interrupts + */ +void wlc_gpio_fast_deinit(struct wlc_hw_info *wlc_hw) +{ + if ((wlc_hw == NULL) || (wlc_hw->sih == NULL)) + return; + + /* Only chips with internal bus or PCIE cores or certain PCI cores + * are able to switch cores w/o disabling interrupts + */ + if (!((wlc_hw->sih->bustype == SI_BUS) || + ((wlc_hw->sih->bustype == PCI_BUS) && + ((wlc_hw->sih->buscoretype == PCIE_CORE_ID) || + (wlc_hw->sih->buscorerev >= 13))))) + return; + + WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); + return; +} + +bool wlc_bmac_radio_hw(struct wlc_hw_info *wlc_hw, bool enable) +{ + /* Do not access Phy registers if core is not up */ + if (si_iscoreup(wlc_hw->sih) == false) + return false; + + if (enable) { + if (PMUCTL_ENAB(wlc_hw->sih)) { + AND_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, + ~CCS_FORCEHWREQOFF); + si_pmu_radio_enable(wlc_hw->sih, true); + } + + wlc_phy_anacore(wlc_hw->band->pi, ON); + wlc_phy_switch_radio(wlc_hw->band->pi, ON); + + /* resume d11 core */ + wlc_enable_mac(wlc_hw->wlc); + } else { + /* suspend d11 core */ + wlc_suspend_mac_and_wait(wlc_hw->wlc); + + wlc_phy_switch_radio(wlc_hw->band->pi, OFF); + wlc_phy_anacore(wlc_hw->band->pi, OFF); + + if (PMUCTL_ENAB(wlc_hw->sih)) { + si_pmu_radio_enable(wlc_hw->sih, false); + OR_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, + CCS_FORCEHWREQOFF); + } + } + + return true; +} + +u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate) +{ + u16 table_ptr; + u8 phy_rate, index; + + /* get the phy specific rate encoding for the PLCP SIGNAL field */ + /* XXX4321 fixup needed ? */ + if (IS_OFDM(rate)) + table_ptr = M_RT_DIRMAP_A; + else + table_ptr = M_RT_DIRMAP_B; + + /* for a given rate, the LS-nibble of the PLCP SIGNAL field is + * the index into the rate table. + */ + phy_rate = rate_info[rate] & RATE_MASK; + index = phy_rate & 0xf; + + /* Find the SHM pointer to the rate table entry by looking in the + * Direct-map Table + */ + return 2 * wlc_bmac_read_shm(wlc_hw, table_ptr + (index * 2)); +} + +void wlc_bmac_set_txpwr_percent(struct wlc_hw_info *wlc_hw, u8 val) +{ + wlc_phy_txpwr_percent_set(wlc_hw->band->pi, val); +} + +void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail) +{ + wlc_hw->antsel_avail = antsel_avail; +} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.h new file mode 100644 index 000000000000..03ce9521d652 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.h @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* XXXXX this interface is under wlc.c by design + * http://hwnbu-twiki.broadcom.com/bin/view/Mwgroup/WlBmacDesign + * + * high driver files(e.g. wlc_ampdu.c etc) + * wlc.h/wlc.c + * wlc_bmac.h/wlc_bmac.c + * + * So don't include this in files other than wlc.c, wlc_bmac* wl_rte.c(dongle port) and wl_phy.c + * create wrappers in wlc.c if needed + */ + +/* Revision and other info required from BMAC driver for functioning of high ONLY driver */ +typedef struct wlc_bmac_revinfo { + uint vendorid; /* PCI vendor id */ + uint deviceid; /* device id of chip */ + + uint boardrev; /* version # of particular board */ + uint corerev; /* core revision */ + uint sromrev; /* srom revision */ + uint chiprev; /* chip revision */ + uint chip; /* chip number */ + uint chippkg; /* chip package */ + uint boardtype; /* board type */ + uint boardvendor; /* board vendor */ + uint bustype; /* SB_BUS, PCI_BUS */ + uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */ + uint buscorerev; /* buscore rev */ + u32 issim; /* chip is in simulation or emulation */ + + uint nbands; + + struct band_info { + uint bandunit; /* To match on both sides */ + uint bandtype; /* To match on both sides */ + uint radiorev; + uint phytype; + uint phyrev; + uint anarev; + uint radioid; + bool abgphy_encore; + } band[MAXBANDS]; +} wlc_bmac_revinfo_t; + +/* dup state between BMAC(struct wlc_hw_info) and HIGH(struct wlc_info) + driver */ +typedef struct wlc_bmac_state { + u32 machwcap; /* mac hw capibility */ + u32 preamble_ovr; /* preamble override */ +} wlc_bmac_state_t; + +enum { + IOV_BMAC_DIAG, + IOV_BMAC_SBGPIOTIMERVAL, + IOV_BMAC_SBGPIOOUT, + IOV_BMAC_CCGPIOCTRL, /* CC GPIOCTRL REG */ + IOV_BMAC_CCGPIOOUT, /* CC GPIOOUT REG */ + IOV_BMAC_CCGPIOOUTEN, /* CC GPIOOUTEN REG */ + IOV_BMAC_CCGPIOIN, /* CC GPIOIN REG */ + IOV_BMAC_WPSGPIO, /* WPS push button GPIO pin */ + IOV_BMAC_OTPDUMP, + IOV_BMAC_OTPSTAT, + IOV_BMAC_PCIEASPM, /* obfuscation clkreq/aspm control */ + IOV_BMAC_PCIEADVCORRMASK, /* advanced correctable error mask */ + IOV_BMAC_PCIECLKREQ, /* PCIE 1.1 clockreq enab support */ + IOV_BMAC_PCIELCREG, /* PCIE LCREG */ + IOV_BMAC_SBGPIOTIMERMASK, + IOV_BMAC_RFDISABLEDLY, + IOV_BMAC_PCIEREG, /* PCIE REG */ + IOV_BMAC_PCICFGREG, /* PCI Config register */ + IOV_BMAC_PCIESERDESREG, /* PCIE SERDES REG (dev, 0}offset) */ + IOV_BMAC_PCIEGPIOOUT, /* PCIEOUT REG */ + IOV_BMAC_PCIEGPIOOUTEN, /* PCIEOUTEN REG */ + IOV_BMAC_PCIECLKREQENCTRL, /* clkreqenctrl REG (PCIE REV > 6.0 */ + IOV_BMAC_DMALPBK, + IOV_BMAC_CCREG, + IOV_BMAC_COREREG, + IOV_BMAC_SDCIS, + IOV_BMAC_SDIO_DRIVE, + IOV_BMAC_OTPW, + IOV_BMAC_NVOTPW, + IOV_BMAC_SROM, + IOV_BMAC_SRCRC, + IOV_BMAC_CIS_SOURCE, + IOV_BMAC_CISVAR, + IOV_BMAC_OTPLOCK, + IOV_BMAC_OTP_CHIPID, + IOV_BMAC_CUSTOMVAR1, + IOV_BMAC_BOARDFLAGS, + IOV_BMAC_BOARDFLAGS2, + IOV_BMAC_WPSLED, + IOV_BMAC_NVRAM_SOURCE, + IOV_BMAC_OTP_RAW_READ, + IOV_BMAC_LAST +}; + +typedef enum { + BMAC_DUMP_GPIO_ID, + BMAC_DUMP_SI_ID, + BMAC_DUMP_SIREG_ID, + BMAC_DUMP_SICLK_ID, + BMAC_DUMP_CCREG_ID, + BMAC_DUMP_PCIEREG_ID, + BMAC_DUMP_PHYREG_ID, + BMAC_DUMP_PHYTBL_ID, + BMAC_DUMP_PHYTBL2_ID, + BMAC_DUMP_PHY_RADIOREG_ID, + BMAC_DUMP_LAST +} wlc_bmac_dump_id_t; + +typedef enum { + WLCHW_STATE_ATTACH, + WLCHW_STATE_CLK, + WLCHW_STATE_UP, + WLCHW_STATE_ASSOC, + WLCHW_STATE_LAST +} wlc_bmac_state_id_t; + +extern int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, + uint unit, bool piomode, struct osl_info *osh, + void *regsva, uint bustype, void *btparam); +extern int wlc_bmac_detach(struct wlc_info *wlc); +extern void wlc_bmac_watchdog(void *arg); +extern void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw); + +/* up/down, reset, clk */ +extern void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want); + +extern void wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw, + uint offset, const void *buf, int len, + u32 sel); +extern void wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset, + void *buf, int len, u32 sel); +#define wlc_bmac_copyfrom_shm(wlc_hw, offset, buf, len) \ + wlc_bmac_copyfrom_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL) +#define wlc_bmac_copyto_shm(wlc_hw, offset, buf, len) \ + wlc_bmac_copyto_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL) + +extern void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk); +extern void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on); +extern void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk); +extern void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk); +extern void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags); +extern void wlc_bmac_reset(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, + bool mute); +extern int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw); +extern int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw); +extern int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw); +extern int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags); +extern void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode); + +/* chanspec, ucode interface */ +extern int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, + chanspec_t chanspec, + bool mute, struct txpwr_limits *txpwr); + +extern void wlc_bmac_txfifo(struct wlc_hw_info *wlc_hw, uint fifo, void *p, + bool commit, u16 frameid, u8 txpktpend); +extern int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, + uint *blocks); +extern void wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, + u16 val, int bands); +extern void wlc_bmac_mctrl(struct wlc_hw_info *wlc_hw, u32 mask, u32 val); +extern u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands); +extern int wlc_bmac_xmtfifo_sz_set(struct wlc_hw_info *wlc_hw, uint fifo, + uint blocks); +extern void wlc_bmac_txant_set(struct wlc_hw_info *wlc_hw, u16 phytxant); +extern u16 wlc_bmac_get_txant(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_antsel_type_set(struct wlc_hw_info *wlc_hw, + u8 antsel_type); +extern int wlc_bmac_revinfo_get(struct wlc_hw_info *wlc_hw, + wlc_bmac_revinfo_t *revinfo); +extern int wlc_bmac_state_get(struct wlc_hw_info *wlc_hw, + wlc_bmac_state_t *state); +extern void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v); +extern u16 wlc_bmac_read_shm(struct wlc_hw_info *wlc_hw, uint offset); +extern void wlc_bmac_set_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v, + int len); +extern void wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, + int len, void *buf); +extern void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, + uint *len); + +extern void wlc_bmac_process_ps_switch(struct wlc_hw_info *wlc, + struct ether_addr *ea, s8 ps_on); +extern void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, + u8 *ea); +extern void wlc_bmac_set_hw_etheraddr(struct wlc_hw_info *wlc_hw, + u8 *ea); +extern bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw); + +extern bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot); +extern void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool want, mbool flags); +extern void wlc_bmac_set_deaf(struct wlc_hw_info *wlc_hw, bool user_flag); +extern void wlc_bmac_band_stf_ss_set(struct wlc_hw_info *wlc_hw, u8 stf_mode); + +extern void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw); +extern bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, + uint tx_fifo); +extern void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo); +extern void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo); + +extern void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, + u32 override_bit); +extern void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw, + u32 override_bit); + +extern void wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, + const u8 *addr); +extern void wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, + int match_reg_offset, + const u8 *addr); +extern void wlc_bmac_write_hw_bcntemplates(struct wlc_hw_info *wlc_hw, + void *bcn, int len, bool both); + +extern void wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr, + u32 *tsf_h_ptr); +extern void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin); +extern void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax); +extern void wlc_bmac_set_noreset(struct wlc_hw_info *wlc, bool noreset_flag); +extern void wlc_bmac_set_ucode_loaded(struct wlc_hw_info *wlc, + bool ucode_loaded); + +extern void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL, + u16 LRL); + +extern void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw); + + +/* API for BMAC driver (e.g. wlc_phy.c etc) */ + +extern void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw); +extern void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, + mbool req_bit); +extern void wlc_bmac_set_clk(struct wlc_hw_info *wlc_hw, bool on); +extern bool wlc_bmac_taclear(struct wlc_hw_info *wlc_hw, bool ta_ok); +extern void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw); + +extern void wlc_bmac_dump(struct wlc_hw_info *wlc_hw, struct bcmstrbuf *b, + wlc_bmac_dump_id_t dump_id); +extern void wlc_gpio_fast_deinit(struct wlc_hw_info *wlc_hw); + +extern bool wlc_bmac_radio_hw(struct wlc_hw_info *wlc_hw, bool enable); +extern u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate); + +extern void wlc_bmac_assert_type_set(struct wlc_hw_info *wlc_hw, u32 type); +extern void wlc_bmac_set_txpwr_percent(struct wlc_hw_info *wlc_hw, u8 val); +extern void wlc_bmac_blink_sync(struct wlc_hw_info *wlc_hw, u32 led_pins); +extern void wlc_bmac_ifsctl_edcrs_set(struct wlc_hw_info *wlc_hw, bool abie, + bool isht); + +extern void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail); diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_bsscfg.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_bsscfg.h new file mode 100644 index 000000000000..0bb4a212dd71 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_bsscfg.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _WLC_BSSCFG_H_ +#define _WLC_BSSCFG_H_ + +#include + +/* Check if a particular BSS config is AP or STA */ +#define BSSCFG_AP(cfg) (0) +#define BSSCFG_STA(cfg) (1) + +#define BSSCFG_IBSS(cfg) (!(cfg)->BSS) + +/* forward declarations */ +typedef struct wlc_bsscfg wlc_bsscfg_t; + +#include + +#define NTXRATE 64 /* # tx MPDUs rate is reported for */ +#define MAXMACLIST 64 /* max # source MAC matches */ +#define BCN_TEMPLATE_COUNT 2 + +/* Iterator for "associated" STA bss configs: + (struct wlc_info *wlc, int idx, wlc_bsscfg_t *cfg) */ +#define FOREACH_AS_STA(wlc, idx, cfg) \ + for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \ + if ((cfg = (wlc)->bsscfg[idx]) && BSSCFG_STA(cfg) && cfg->associated) + +/* As above for all non-NULL BSS configs */ +#define FOREACH_BSS(wlc, idx, cfg) \ + for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \ + if ((cfg = (wlc)->bsscfg[idx])) + +/* BSS configuration state */ +struct wlc_bsscfg { + struct wlc_info *wlc; /* wlc to which this bsscfg belongs to. */ + bool up; /* is this configuration up operational */ + bool enable; /* is this configuration enabled */ + bool associated; /* is BSS in ASSOCIATED state */ + bool BSS; /* infraustructure or adhac */ + bool dtim_programmed; +#ifdef LATER + bool _ap; /* is this configuration an AP */ + struct wlc_if *wlcif; /* virtual interface, NULL for primary bsscfg */ + void *sup; /* pointer to supplicant state */ + s8 sup_type; /* type of supplicant */ + bool sup_enable_wpa; /* supplicant WPA on/off */ + void *authenticator; /* pointer to authenticator state */ + bool sup_auth_pending; /* flag for auth timeout */ +#endif + u8 SSID_len; /* the length of SSID */ + u8 SSID[IEEE80211_MAX_SSID_LEN]; /* SSID string */ + struct scb *bcmc_scb[MAXBANDS]; /* one bcmc_scb per band */ + s8 _idx; /* the index of this bsscfg, + * assigned at wlc_bsscfg_alloc() + */ + /* MAC filter */ + uint nmac; /* # of entries on maclist array */ + int macmode; /* allow/deny stations on maclist array */ + struct ether_addr *maclist; /* list of source MAC addrs to match */ + + /* security */ + u32 wsec; /* wireless security bitvec */ + s16 auth; /* 802.11 authentication: Open, Shared Key, WPA */ + s16 openshared; /* try Open auth first, then Shared Key */ + bool wsec_restrict; /* drop unencrypted packets if wsec is enabled */ + bool eap_restrict; /* restrict data until 802.1X auth succeeds */ + u16 WPA_auth; /* WPA: authenticated key management */ + bool wpa2_preauth; /* default is true, wpa_cap sets value */ + bool wsec_portopen; /* indicates keys are plumbed */ + wsec_iv_t wpa_none_txiv; /* global txiv for WPA_NONE, tkip and aes */ + int wsec_index; /* 0-3: default tx key, -1: not set */ + wsec_key_t *bss_def_keys[WLC_DEFAULT_KEYS]; /* default key storage */ + + /* TKIP countermeasures */ + bool tkip_countermeasures; /* flags TKIP no-assoc period */ + u32 tk_cm_dt; /* detect timer */ + u32 tk_cm_bt; /* blocking timer */ + u32 tk_cm_bt_tmstmp; /* Timestamp when TKIP BT is activated */ + bool tk_cm_activate; /* activate countermeasures after EAPOL-Key sent */ + + u8 BSSID[ETH_ALEN]; /* BSSID (associated) */ + u8 cur_etheraddr[ETH_ALEN]; /* h/w address */ + u16 bcmc_fid; /* the last BCMC FID queued to TX_BCMC_FIFO */ + u16 bcmc_fid_shm; /* the last BCMC FID written to shared mem */ + + u32 flags; /* WLC_BSSCFG flags; see below */ + + u8 *bcn; /* AP beacon */ + uint bcn_len; /* AP beacon length */ + bool ar_disassoc; /* disassociated in associated recreation */ + + int auth_atmptd; /* auth type (open/shared) attempted */ + + pmkid_cand_t pmkid_cand[MAXPMKID]; /* PMKID candidate list */ + uint npmkid_cand; /* num PMKID candidates */ + pmkid_t pmkid[MAXPMKID]; /* PMKID cache */ + uint npmkid; /* num cached PMKIDs */ + + wlc_bss_info_t *target_bss; /* BSS parms during tran. to ASSOCIATED state */ + wlc_bss_info_t *current_bss; /* BSS parms in ASSOCIATED state */ + + /* PM states */ + bool PMawakebcn; /* bcn recvd during current waking state */ + bool PMpending; /* waiting for tx status with PM indicated set */ + bool priorPMstate; /* Detecting PM state transitions */ + bool PSpoll; /* whether there is an outstanding PS-Poll frame */ + + /* BSSID entry in RCMTA, use the wsec key management infrastructure to + * manage the RCMTA entries. + */ + wsec_key_t *rcmta; + + /* 'unique' ID of this bsscfg, assigned at bsscfg allocation */ + u16 ID; + + uint txrspecidx; /* index into tx rate circular buffer */ + ratespec_t txrspec[NTXRATE][2]; /* circular buffer of prev MPDUs tx rates */ +}; + +#define WLC_BSSCFG_11N_DISABLE 0x1000 /* Do not advertise .11n IEs for this BSS */ +#define WLC_BSSCFG_HW_BCN 0x20 /* The BSS is generating beacons in HW */ + +#define HWBCN_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_BCN) != 0) +#define HWPRB_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_PRB) != 0) + +extern void wlc_bsscfg_ID_assign(struct wlc_info *wlc, wlc_bsscfg_t * bsscfg); + +/* Extend N_ENAB to per-BSS */ +#define BSS_N_ENAB(wlc, cfg) \ + (N_ENAB((wlc)->pub) && !((cfg)->flags & WLC_BSSCFG_11N_DISABLE)) + +#define MBSS_BCN_ENAB(cfg) 0 +#define MBSS_PRB_ENAB(cfg) 0 +#define SOFTBCN_ENAB(pub) (0) +#define SOFTPRB_ENAB(pub) (0) +#define wlc_bsscfg_tx_check(a) do { } while (0); + +#endif /* _WLC_BSSCFG_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_cfg.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_cfg.h new file mode 100644 index 000000000000..3decb7d1a5e5 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_cfg.h @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_cfg_h_ +#define _wlc_cfg_h_ + +#define NBANDS(wlc) ((wlc)->pub->_nbands) +#define NBANDS_PUB(pub) ((pub)->_nbands) +#define NBANDS_HW(hw) ((hw)->_nbands) + +#define IS_SINGLEBAND_5G(device) 0 + +/* **** Core type/rev defaults **** */ +#define D11_DEFAULT 0x0fffffb0 /* Supported D11 revs: 4, 5, 7-27 + * also need to update wlc.h MAXCOREREV + */ + +#define NPHY_DEFAULT 0x000001ff /* Supported nphy revs: + * 0 4321a0 + * 1 4321a1 + * 2 4321b0/b1/c0/c1 + * 3 4322a0 + * 4 4322a1 + * 5 4716a0 + * 6 43222a0, 43224a0 + * 7 43226a0 + * 8 5357a0, 43236a0 + */ + +#define LCNPHY_DEFAULT 0x00000007 /* Supported lcnphy revs: + * 0 4313a0, 4336a0, 4330a0 + * 1 + * 2 4330a0 + */ + +#define SSLPNPHY_DEFAULT 0x0000000f /* Supported sslpnphy revs: + * 0 4329a0/k0 + * 1 4329b0/4329C0 + * 2 4319a0 + * 3 5356a0 + */ + + +/* For undefined values, use defaults */ +#ifndef D11CONF +#define D11CONF D11_DEFAULT +#endif +#ifndef NCONF +#define NCONF NPHY_DEFAULT +#endif +#ifndef LCNCONF +#define LCNCONF LCNPHY_DEFAULT +#endif + +#ifndef SSLPNCONF +#define SSLPNCONF SSLPNPHY_DEFAULT +#endif + +#define BAND2G +#define BAND5G +#define WLANTSEL 1 + +/******************************************************************** + * Phy/Core Configuration. Defines macros to to check core phy/rev * + * compile-time configuration. Defines default core support. * + * ****************************************************************** + */ + +/* Basic macros to check a configuration bitmask */ + +#define CONF_HAS(config, val) ((config) & (1 << (val))) +#define CONF_MSK(config, mask) ((config) & (mask)) +#define MSK_RANGE(low, hi) ((1 << ((hi)+1)) - (1 << (low))) +#define CONF_RANGE(config, low, hi) (CONF_MSK(config, MSK_RANGE(low, high))) + +#define CONF_IS(config, val) ((config) == (1 << (val))) +#define CONF_GE(config, val) ((config) & (0-(1 << (val)))) +#define CONF_GT(config, val) ((config) & (0-2*(1 << (val)))) +#define CONF_LT(config, val) ((config) & ((1 << (val))-1)) +#define CONF_LE(config, val) ((config) & (2*(1 << (val))-1)) + +/* Wrappers for some of the above, specific to config constants */ + +#define NCONF_HAS(val) CONF_HAS(NCONF, val) +#define NCONF_MSK(mask) CONF_MSK(NCONF, mask) +#define NCONF_IS(val) CONF_IS(NCONF, val) +#define NCONF_GE(val) CONF_GE(NCONF, val) +#define NCONF_GT(val) CONF_GT(NCONF, val) +#define NCONF_LT(val) CONF_LT(NCONF, val) +#define NCONF_LE(val) CONF_LE(NCONF, val) + +#define LCNCONF_HAS(val) CONF_HAS(LCNCONF, val) +#define LCNCONF_MSK(mask) CONF_MSK(LCNCONF, mask) +#define LCNCONF_IS(val) CONF_IS(LCNCONF, val) +#define LCNCONF_GE(val) CONF_GE(LCNCONF, val) +#define LCNCONF_GT(val) CONF_GT(LCNCONF, val) +#define LCNCONF_LT(val) CONF_LT(LCNCONF, val) +#define LCNCONF_LE(val) CONF_LE(LCNCONF, val) + +#define D11CONF_HAS(val) CONF_HAS(D11CONF, val) +#define D11CONF_MSK(mask) CONF_MSK(D11CONF, mask) +#define D11CONF_IS(val) CONF_IS(D11CONF, val) +#define D11CONF_GE(val) CONF_GE(D11CONF, val) +#define D11CONF_GT(val) CONF_GT(D11CONF, val) +#define D11CONF_LT(val) CONF_LT(D11CONF, val) +#define D11CONF_LE(val) CONF_LE(D11CONF, val) + +#define PHYCONF_HAS(val) CONF_HAS(PHYTYPE, val) +#define PHYCONF_IS(val) CONF_IS(PHYTYPE, val) + +#define NREV_IS(var, val) (NCONF_HAS(val) && (NCONF_IS(val) || ((var) == (val)))) +#define NREV_GE(var, val) (NCONF_GE(val) && (!NCONF_LT(val) || ((var) >= (val)))) +#define NREV_GT(var, val) (NCONF_GT(val) && (!NCONF_LE(val) || ((var) > (val)))) +#define NREV_LT(var, val) (NCONF_LT(val) && (!NCONF_GE(val) || ((var) < (val)))) +#define NREV_LE(var, val) (NCONF_LE(val) && (!NCONF_GT(val) || ((var) <= (val)))) + +#define LCNREV_IS(var, val) (LCNCONF_HAS(val) && (LCNCONF_IS(val) || ((var) == (val)))) +#define LCNREV_GE(var, val) (LCNCONF_GE(val) && (!LCNCONF_LT(val) || ((var) >= (val)))) +#define LCNREV_GT(var, val) (LCNCONF_GT(val) && (!LCNCONF_LE(val) || ((var) > (val)))) +#define LCNREV_LT(var, val) (LCNCONF_LT(val) && (!LCNCONF_GE(val) || ((var) < (val)))) +#define LCNREV_LE(var, val) (LCNCONF_LE(val) && (!LCNCONF_GT(val) || ((var) <= (val)))) + +#define D11REV_IS(var, val) (D11CONF_HAS(val) && (D11CONF_IS(val) || ((var) == (val)))) +#define D11REV_GE(var, val) (D11CONF_GE(val) && (!D11CONF_LT(val) || ((var) >= (val)))) +#define D11REV_GT(var, val) (D11CONF_GT(val) && (!D11CONF_LE(val) || ((var) > (val)))) +#define D11REV_LT(var, val) (D11CONF_LT(val) && (!D11CONF_GE(val) || ((var) < (val)))) +#define D11REV_LE(var, val) (D11CONF_LE(val) && (!D11CONF_GT(val) || ((var) <= (val)))) + +#define PHYTYPE_IS(var, val) (PHYCONF_HAS(val) && (PHYCONF_IS(val) || ((var) == (val)))) + +/* Finally, early-exit from switch case if anyone wants it... */ + +#define CASECHECK(config, val) if (!(CONF_HAS(config, val))) break +#define CASEMSK(config, mask) if (!(CONF_MSK(config, mask))) break + +#if (D11CONF ^ (D11CONF & D11_DEFAULT)) +#error "Unsupported MAC revision configured" +#endif +#if (NCONF ^ (NCONF & NPHY_DEFAULT)) +#error "Unsupported NPHY revision configured" +#endif +#if (LCNCONF ^ (LCNCONF & LCNPHY_DEFAULT)) +#error "Unsupported LPPHY revision configured" +#endif + +/* *** Consistency checks *** */ +#if !D11CONF +#error "No MAC revisions configured!" +#endif + +#if !NCONF && !LCNCONF && !SSLPNCONF +#error "No PHY configured!" +#endif + +/* Set up PHYTYPE automatically: (depends on PHY_TYPE_X, from d11.h) */ + +#define _PHYCONF_N (1 << PHY_TYPE_N) + +#if LCNCONF +#define _PHYCONF_LCN (1 << PHY_TYPE_LCN) +#else +#define _PHYCONF_LCN 0 +#endif /* LCNCONF */ + +#if SSLPNCONF +#define _PHYCONF_SSLPN (1 << PHY_TYPE_SSN) +#else +#define _PHYCONF_SSLPN 0 +#endif /* SSLPNCONF */ + +#define PHYTYPE (_PHYCONF_N | _PHYCONF_LCN | _PHYCONF_SSLPN) + +/* Utility macro to identify 802.11n (HT) capable PHYs */ +#define PHYTYPE_11N_CAP(phytype) \ + (PHYTYPE_IS(phytype, PHY_TYPE_N) || \ + PHYTYPE_IS(phytype, PHY_TYPE_LCN) || \ + PHYTYPE_IS(phytype, PHY_TYPE_SSN)) + +/* Last but not least: shorter wlc-specific var checks */ +#define WLCISNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_N) +#define WLCISLCNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_LCN) +#define WLCISSSLPNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_SSN) + +#define WLC_PHY_11N_CAP(band) PHYTYPE_11N_CAP((band)->phytype) + +/********************************************************************** + * ------------- End of Core phy/rev configuration. ----------------- * + * ******************************************************************** + */ + +/************************************************* + * Defaults for tunables (e.g. sizing constants) + * + * For each new tunable, add a member to the end + * of wlc_tunables_t in wlc_pub.h to enable + * runtime checks of tunable values. (Directly + * using the macros in code invalidates ROM code) + * + * *********************************************** + */ +#ifndef NTXD +#define NTXD 256 /* Max # of entries in Tx FIFO based on 4kb page size */ +#endif /* NTXD */ +#ifndef NRXD +#define NRXD 256 /* Max # of entries in Rx FIFO based on 4kb page size */ +#endif /* NRXD */ + +#ifndef NRXBUFPOST +#define NRXBUFPOST 32 /* try to keep this # rbufs posted to the chip */ +#endif /* NRXBUFPOST */ + +#ifndef MAXSCB /* station control blocks in cache */ +#define MAXSCB 32 /* Maximum SCBs in cache for STA */ +#endif /* MAXSCB */ + +#ifndef AMPDU_NUM_MPDU +#define AMPDU_NUM_MPDU 16 /* max allowed number of mpdus in an ampdu (2 streams) */ +#endif /* AMPDU_NUM_MPDU */ + +#ifndef AMPDU_NUM_MPDU_3STREAMS +#define AMPDU_NUM_MPDU_3STREAMS 32 /* max allowed number of mpdus in an ampdu for 3+ streams */ +#endif /* AMPDU_NUM_MPDU_3STREAMS */ + +/* Count of packet callback structures. either of following + * 1. Set to the number of SCBs since a STA + * can queue up a rate callback for each IBSS STA it knows about, and an AP can + * queue up an "are you there?" Null Data callback for each associated STA + * 2. controlled by tunable config file + */ +#ifndef MAXPKTCB +#define MAXPKTCB MAXSCB /* Max number of packet callbacks */ +#endif /* MAXPKTCB */ + +#ifndef CTFPOOLSZ +#define CTFPOOLSZ 128 +#endif /* CTFPOOLSZ */ + +/* NetBSD also needs to keep track of this */ +#define WLC_MAX_UCODE_BSS (16) /* Number of BSS handled in ucode bcn/prb */ +#define WLC_MAX_UCODE_BSS4 (4) /* Number of BSS handled in sw bcn/prb */ +#ifndef WLC_MAXBSSCFG +#define WLC_MAXBSSCFG (1) /* max # BSS configs */ +#endif /* WLC_MAXBSSCFG */ + +#ifndef MAXBSS +#define MAXBSS 64 /* max # available networks */ +#endif /* MAXBSS */ + +#ifndef WLC_DATAHIWAT +#define WLC_DATAHIWAT 50 /* data msg txq hiwat mark */ +#endif /* WLC_DATAHIWAT */ + +#ifndef WLC_AMPDUDATAHIWAT +#define WLC_AMPDUDATAHIWAT 255 +#endif /* WLC_AMPDUDATAHIWAT */ + +/* bounded rx loops */ +#ifndef RXBND +#define RXBND 8 /* max # frames to process in wlc_recv() */ +#endif /* RXBND */ +#ifndef TXSBND +#define TXSBND 8 /* max # tx status to process in wlc_txstatus() */ +#endif /* TXSBND */ + +#define BAND_5G(bt) ((bt) == WLC_BAND_5G) +#define BAND_2G(bt) ((bt) == WLC_BAND_2G) + +#define WLBANDINITDATA(_data) _data +#define WLBANDINITFN(_fn) _fn + +#define WLANTSEL_ENAB(wlc) 1 + +#endif /* _wlc_cfg_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_channel.c new file mode 100644 index 000000000000..a35c15214880 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_channel.c @@ -0,0 +1,1609 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct wlc_cm_band { + u8 locale_flags; /* locale_info_t flags */ + chanvec_t valid_channels; /* List of valid channels in the country */ + const chanvec_t *restricted_channels; /* List of restricted use channels */ + const chanvec_t *radar_channels; /* List of radar sensitive channels */ + u8 PAD[8]; +} wlc_cm_band_t; + +struct wlc_cm_info { + struct wlc_pub *pub; + struct wlc_info *wlc; + char srom_ccode[WLC_CNTRY_BUF_SZ]; /* Country Code in SROM */ + uint srom_regrev; /* Regulatory Rev for the SROM ccode */ + const country_info_t *country; /* current country def */ + char ccode[WLC_CNTRY_BUF_SZ]; /* current internal Country Code */ + uint regrev; /* current Regulatory Revision */ + char country_abbrev[WLC_CNTRY_BUF_SZ]; /* current advertised ccode */ + wlc_cm_band_t bandstate[MAXBANDS]; /* per-band state (one per phy/radio) */ + /* quiet channels currently for radar sensitivity or 11h support */ + chanvec_t quiet_channels; /* channels on which we cannot transmit */ +}; + +static int wlc_channels_init(wlc_cm_info_t *wlc_cm, + const country_info_t *country); +static void wlc_set_country_common(wlc_cm_info_t *wlc_cm, + const char *country_abbrev, + const char *ccode, uint regrev, + const country_info_t *country); +static int wlc_country_aggregate_map(wlc_cm_info_t *wlc_cm, const char *ccode, + char *mapped_ccode, uint *mapped_regrev); +static const country_info_t *wlc_country_lookup_direct(const char *ccode, + uint regrev); +static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm, + const char *ccode, + char *mapped_ccode, + uint *mapped_regrev); +static void wlc_channels_commit(wlc_cm_info_t *wlc_cm); +static bool wlc_japan_ccode(const char *ccode); +static void wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t * + wlc_cm, + struct + txpwr_limits + *txpwr, + u8 + local_constraint_qdbm); +void wlc_locale_add_channels(chanvec_t *target, const chanvec_t *channels); +static const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx); +static const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx); + +/* QDB() macro takes a dB value and converts to a quarter dB value */ +#ifdef QDB +#undef QDB +#endif +#define QDB(n) ((n) * WLC_TXPWR_DB_FACTOR) + +/* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */ + +/* + * Some common channel sets + */ + +/* No channels */ +static const chanvec_t chanvec_none = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* All 2.4 GHz HW channels */ +const chanvec_t chanvec_all_2G = { + {0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* All 5 GHz HW channels */ +const chanvec_t chanvec_all_5G = { + {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x11, 0x11, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x20, 0x22, 0x22, 0x00, 0x00, 0x11, + 0x11, 0x11, 0x11, 0x01} +}; + +/* + * Radar channel sets + */ + +/* No radar */ +#define radar_set_none chanvec_none + +static const chanvec_t radar_set1 = { /* Channels 52 - 64, 100 - 140 */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, /* 52 - 60 */ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, /* 64, 100 - 124 */ + 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 128 - 140 */ + 0x00, 0x00, 0x00, 0x00} +}; + +/* + * Restricted channel sets + */ + +#define restricted_set_none chanvec_none + +/* Channels 34, 38, 42, 46 */ +static const chanvec_t restricted_set_japan_legacy = { + {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* Channels 12, 13 */ +static const chanvec_t restricted_set_2g_short = { + {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* Channel 165 */ +static const chanvec_t restricted_chan_165 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* Channels 36 - 48 & 149 - 165 */ +static const chanvec_t restricted_low_hi = { + {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x22, 0x22, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* Channels 12 - 14 */ +static const chanvec_t restricted_set_12_13_14 = { + {0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +#define LOCALE_CHAN_01_11 (1<<0) +#define LOCALE_CHAN_12_13 (1<<1) +#define LOCALE_CHAN_14 (1<<2) +#define LOCALE_SET_5G_LOW_JP1 (1<<3) /* 34-48, step 2 */ +#define LOCALE_SET_5G_LOW_JP2 (1<<4) /* 34-46, step 4 */ +#define LOCALE_SET_5G_LOW1 (1<<5) /* 36-48, step 4 */ +#define LOCALE_SET_5G_LOW2 (1<<6) /* 52 */ +#define LOCALE_SET_5G_LOW3 (1<<7) /* 56-64, step 4 */ +#define LOCALE_SET_5G_MID1 (1<<8) /* 100-116, step 4 */ +#define LOCALE_SET_5G_MID2 (1<<9) /* 120-124, step 4 */ +#define LOCALE_SET_5G_MID3 (1<<10) /* 128 */ +#define LOCALE_SET_5G_HIGH1 (1<<11) /* 132-140, step 4 */ +#define LOCALE_SET_5G_HIGH2 (1<<12) /* 149-161, step 4 */ +#define LOCALE_SET_5G_HIGH3 (1<<13) /* 165 */ +#define LOCALE_CHAN_52_140_ALL (1<<14) +#define LOCALE_SET_5G_HIGH4 (1<<15) /* 184-216 */ + +#define LOCALE_CHAN_36_64 (LOCALE_SET_5G_LOW1 | LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3) +#define LOCALE_CHAN_52_64 (LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3) +#define LOCALE_CHAN_100_124 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2) +#define LOCALE_CHAN_100_140 \ + (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1) +#define LOCALE_CHAN_149_165 (LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3) +#define LOCALE_CHAN_184_216 LOCALE_SET_5G_HIGH4 + +#define LOCALE_CHAN_01_14 (LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13 | LOCALE_CHAN_14) + +#define LOCALE_RADAR_SET_NONE 0 +#define LOCALE_RADAR_SET_1 1 + +#define LOCALE_RESTRICTED_NONE 0 +#define LOCALE_RESTRICTED_SET_2G_SHORT 1 +#define LOCALE_RESTRICTED_CHAN_165 2 +#define LOCALE_CHAN_ALL_5G 3 +#define LOCALE_RESTRICTED_JAPAN_LEGACY 4 +#define LOCALE_RESTRICTED_11D_2G 5 +#define LOCALE_RESTRICTED_11D_5G 6 +#define LOCALE_RESTRICTED_LOW_HI 7 +#define LOCALE_RESTRICTED_12_13_14 8 + +/* global memory to provide working buffer for expanded locale */ + +static const chanvec_t *g_table_radar_set[] = { + &chanvec_none, + &radar_set1 +}; + +static const chanvec_t *g_table_restricted_chan[] = { + &chanvec_none, /* restricted_set_none */ + &restricted_set_2g_short, + &restricted_chan_165, + &chanvec_all_5G, + &restricted_set_japan_legacy, + &chanvec_all_2G, /* restricted_set_11d_2G */ + &chanvec_all_5G, /* restricted_set_11d_5G */ + &restricted_low_hi, + &restricted_set_12_13_14 +}; + +static const chanvec_t locale_2g_01_11 = { + {0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_2g_12_13 = { + {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_2g_14 = { + {0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_LOW_JP1 = { + {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_LOW_JP2 = { + {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_LOW1 = { + {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_LOW2 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_LOW3 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_MID1 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_MID2 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_MID3 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_HIGH1 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_HIGH2 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x22, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_HIGH3 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_52_140_ALL = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_HIGH4 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x11, 0x11, 0x11, 0x11} +}; + +static const chanvec_t *g_table_locale_base[] = { + &locale_2g_01_11, + &locale_2g_12_13, + &locale_2g_14, + &locale_5g_LOW_JP1, + &locale_5g_LOW_JP2, + &locale_5g_LOW1, + &locale_5g_LOW2, + &locale_5g_LOW3, + &locale_5g_MID1, + &locale_5g_MID2, + &locale_5g_MID3, + &locale_5g_HIGH1, + &locale_5g_HIGH2, + &locale_5g_HIGH3, + &locale_5g_52_140_ALL, + &locale_5g_HIGH4 +}; + +void wlc_locale_add_channels(chanvec_t *target, const chanvec_t *channels) +{ + u8 i; + for (i = 0; i < sizeof(chanvec_t); i++) { + target->vec[i] |= channels->vec[i]; + } +} + +void wlc_locale_get_channels(const locale_info_t *locale, chanvec_t *channels) +{ + u8 i; + + memset(channels, 0, sizeof(chanvec_t)); + + for (i = 0; i < ARRAY_SIZE(g_table_locale_base); i++) { + if (locale->valid_channels & (1 << i)) { + wlc_locale_add_channels(channels, + g_table_locale_base[i]); + } + } +} + +/* + * Locale Definitions - 2.4 GHz + */ +static const locale_info_t locale_i = { /* locale i. channel 1 - 13 */ + LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13, + LOCALE_RADAR_SET_NONE, + LOCALE_RESTRICTED_SET_2G_SHORT, + {QDB(19), QDB(19), QDB(19), + QDB(19), QDB(19), QDB(19)}, + {20, 20, 20, 0}, + WLC_EIRP +}; + +/* + * Locale Definitions - 5 GHz + */ +static const locale_info_t locale_11 = { + /* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */ + LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165, + LOCALE_RADAR_SET_1, + LOCALE_RESTRICTED_NONE, + {QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)}, + {23, 23, 23, 30, 30}, + WLC_EIRP | WLC_DFS_EU +}; + +#define LOCALE_2G_IDX_i 0 +static const locale_info_t *g_locale_2g_table[] = { + &locale_i +}; + +#define LOCALE_5G_IDX_11 0 +static const locale_info_t *g_locale_5g_table[] = { + &locale_11 +}; + +/* + * MIMO Locale Definitions - 2.4 GHz + */ +static const locale_mimo_info_t locale_bn = { + {QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), + QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), + QDB(13), QDB(13), QDB(13)}, + {0, 0, QDB(13), QDB(13), QDB(13), + QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), + QDB(13), 0, 0}, + 0 +}; + +/* locale mimo 2g indexes */ +#define LOCALE_MIMO_IDX_bn 0 + +static const locale_mimo_info_t *g_mimo_2g_table[] = { + &locale_bn +}; + +/* + * MIMO Locale Definitions - 5 GHz + */ +static const locale_mimo_info_t locale_11n = { + { /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)}, + {QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)}, + 0 +}; + +#define LOCALE_MIMO_IDX_11n 0 +static const locale_mimo_info_t *g_mimo_5g_table[] = { + &locale_11n +}; + +#ifdef LC +#undef LC +#endif +#define LC(id) LOCALE_MIMO_IDX_ ## id + +#ifdef LC_2G +#undef LC_2G +#endif +#define LC_2G(id) LOCALE_2G_IDX_ ## id + +#ifdef LC_5G +#undef LC_5G +#endif +#define LC_5G(id) LOCALE_5G_IDX_ ## id + +#define LOCALES(band2, band5, mimo2, mimo5) {LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)} + +static const struct { + char abbrev[WLC_CNTRY_BUF_SZ]; /* country abbreviation */ + country_info_t country; +} cntry_locales[] = { + { + "X2", LOCALES(i, 11, bn, 11n)}, /* Worldwide RoW 2 */ +}; + +#ifdef SUPPORT_40MHZ +/* 20MHz channel info for 40MHz pairing support */ +struct chan20_info { + u8 sb; + u8 adj_sbs; +}; + +/* indicates adjacent channels that are allowed for a 40 Mhz channel and + * those that permitted by the HT + */ +struct chan20_info chan20_info[] = { + /* 11b/11g */ +/* 0 */ {1, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 1 */ {2, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 2 */ {3, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 3 */ {4, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 4 */ {5, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, +/* 5 */ {6, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, +/* 6 */ {7, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, +/* 7 */ {8, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, +/* 8 */ {9, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, +/* 9 */ {10, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 10 */ {11, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 11 */ {12, (CH_LOWER_SB)}, +/* 12 */ {13, (CH_LOWER_SB)}, +/* 13 */ {14, (CH_LOWER_SB)}, + +/* 11a japan high */ +/* 14 */ {34, (CH_UPPER_SB)}, +/* 15 */ {38, (CH_LOWER_SB)}, +/* 16 */ {42, (CH_LOWER_SB)}, +/* 17 */ {46, (CH_LOWER_SB)}, + +/* 11a usa low */ +/* 18 */ {36, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 19 */ {40, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 20 */ {44, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 21 */ {48, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 22 */ {52, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 23 */ {56, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 24 */ {60, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 25 */ {64, (CH_LOWER_SB | CH_EWA_VALID)}, + +/* 11a Europe */ +/* 26 */ {100, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 27 */ {104, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 28 */ {108, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 29 */ {112, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 30 */ {116, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 31 */ {120, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 32 */ {124, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 33 */ {128, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 34 */ {132, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 35 */ {136, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 36 */ {140, (CH_LOWER_SB)}, + +/* 11a usa high, ref5 only */ +/* The 0x80 bit in pdiv means these are REF5, other entries are REF20 */ +/* 37 */ {149, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 38 */ {153, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 39 */ {157, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 40 */ {161, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 41 */ {165, (CH_LOWER_SB)}, + +/* 11a japan */ +/* 42 */ {184, (CH_UPPER_SB)}, +/* 43 */ {188, (CH_LOWER_SB)}, +/* 44 */ {192, (CH_UPPER_SB)}, +/* 45 */ {196, (CH_LOWER_SB)}, +/* 46 */ {200, (CH_UPPER_SB)}, +/* 47 */ {204, (CH_LOWER_SB)}, +/* 48 */ {208, (CH_UPPER_SB)}, +/* 49 */ {212, (CH_LOWER_SB)}, +/* 50 */ {216, (CH_LOWER_SB)} +}; +#endif /* SUPPORT_40MHZ */ + +const locale_info_t *wlc_get_locale_2g(u8 locale_idx) +{ + if (locale_idx >= ARRAY_SIZE(g_locale_2g_table)) { + WL_ERROR("%s: locale 2g index size out of range %d\n", + __func__, locale_idx); + ASSERT(locale_idx < ARRAY_SIZE(g_locale_2g_table)); + return NULL; + } + return g_locale_2g_table[locale_idx]; +} + +const locale_info_t *wlc_get_locale_5g(u8 locale_idx) +{ + if (locale_idx >= ARRAY_SIZE(g_locale_5g_table)) { + WL_ERROR("%s: locale 5g index size out of range %d\n", + __func__, locale_idx); + ASSERT(locale_idx < ARRAY_SIZE(g_locale_5g_table)); + return NULL; + } + return g_locale_5g_table[locale_idx]; +} + +const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx) +{ + if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table)) { + WL_ERROR("%s: mimo 2g index size out of range %d\n", + __func__, locale_idx); + return NULL; + } + return g_mimo_2g_table[locale_idx]; +} + +const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx) +{ + if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table)) { + WL_ERROR("%s: mimo 5g index size out of range %d\n", + __func__, locale_idx); + return NULL; + } + return g_mimo_5g_table[locale_idx]; +} + +wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc) +{ + wlc_cm_info_t *wlc_cm; + char country_abbrev[WLC_CNTRY_BUF_SZ]; + const country_info_t *country; + struct wlc_pub *pub = wlc->pub; + char *ccode; + + WL_TRACE("wl%d: wlc_channel_mgr_attach\n", wlc->pub->unit); + + wlc_cm = kzalloc(sizeof(wlc_cm_info_t), GFP_ATOMIC); + if (wlc_cm == NULL) { + WL_ERROR("wl%d: %s: out of memory", pub->unit, __func__); + return NULL; + } + wlc_cm->pub = pub; + wlc_cm->wlc = wlc; + wlc->cmi = wlc_cm; + + /* store the country code for passing up as a regulatory hint */ + ccode = getvar(wlc->pub->vars, "ccode"); + if (ccode) { + strncpy(wlc->pub->srom_ccode, ccode, WLC_CNTRY_BUF_SZ - 1); + WL_NONE("%s: SROM country code is %c%c\n", + __func__, + wlc->pub->srom_ccode[0], wlc->pub->srom_ccode[1]); + } + + /* internal country information which must match regulatory constraints in firmware */ + memset(country_abbrev, 0, WLC_CNTRY_BUF_SZ); + strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1); + country = wlc_country_lookup(wlc, country_abbrev); + + ASSERT(country != NULL); + + /* save default country for exiting 11d regulatory mode */ + strncpy(wlc->country_default, country_abbrev, WLC_CNTRY_BUF_SZ - 1); + + /* initialize autocountry_default to driver default */ + strncpy(wlc->autocountry_default, "X2", WLC_CNTRY_BUF_SZ - 1); + + wlc_set_countrycode(wlc_cm, country_abbrev); + + return wlc_cm; +} + +void wlc_channel_mgr_detach(wlc_cm_info_t *wlc_cm) +{ + if (wlc_cm) + kfree(wlc_cm); +} + +const char *wlc_channel_country_abbrev(wlc_cm_info_t *wlc_cm) +{ + return wlc_cm->country_abbrev; +} + +u8 wlc_channel_locale_flags(wlc_cm_info_t *wlc_cm) +{ + struct wlc_info *wlc = wlc_cm->wlc; + + return wlc_cm->bandstate[wlc->band->bandunit].locale_flags; +} + +u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, uint bandunit) +{ + return wlc_cm->bandstate[bandunit].locale_flags; +} + +/* return chanvec for a given country code and band */ +bool +wlc_channel_get_chanvec(struct wlc_info *wlc, const char *country_abbrev, + int bandtype, chanvec_t *channels) +{ + const country_info_t *country; + const locale_info_t *locale = NULL; + + country = wlc_country_lookup(wlc, country_abbrev); + if (country == NULL) + return false; + + if (bandtype == WLC_BAND_2G) + locale = wlc_get_locale_2g(country->locale_2G); + else if (bandtype == WLC_BAND_5G) + locale = wlc_get_locale_5g(country->locale_5G); + if (locale == NULL) + return false; + + wlc_locale_get_channels(locale, channels); + return true; +} + +/* set the driver's current country and regulatory information using a country code + * as the source. Lookup built in country information found with the country code. + */ +int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode) +{ + char country_abbrev[WLC_CNTRY_BUF_SZ]; + strncpy(country_abbrev, ccode, WLC_CNTRY_BUF_SZ); + return wlc_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1); +} + +int +wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, + const char *country_abbrev, + const char *ccode, int regrev) +{ + const country_info_t *country; + char mapped_ccode[WLC_CNTRY_BUF_SZ]; + uint mapped_regrev; + + WL_NONE("%s: (country_abbrev \"%s\", ccode \"%s\", regrev %d) SPROM \"%s\"/%u\n", + __func__, country_abbrev, ccode, regrev, + wlc_cm->srom_ccode, wlc_cm->srom_regrev); + + /* if regrev is -1, lookup the mapped country code, + * otherwise use the ccode and regrev directly + */ + if (regrev == -1) { + /* map the country code to a built-in country code, regrev, and country_info */ + country = + wlc_countrycode_map(wlc_cm, ccode, mapped_ccode, + &mapped_regrev); + } else { + /* find the matching built-in country definition */ + ASSERT(0); + country = wlc_country_lookup_direct(ccode, regrev); + strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ); + mapped_regrev = regrev; + } + + if (country == NULL) + return BCME_BADARG; + + /* set the driver state for the country */ + wlc_set_country_common(wlc_cm, country_abbrev, mapped_ccode, + mapped_regrev, country); + + return 0; +} + +/* set the driver's current country and regulatory information using a country code + * as the source. Look up built in country information found with the country code. + */ +static void +wlc_set_country_common(wlc_cm_info_t *wlc_cm, + const char *country_abbrev, + const char *ccode, uint regrev, + const country_info_t *country) +{ + const locale_mimo_info_t *li_mimo; + const locale_info_t *locale; + struct wlc_info *wlc = wlc_cm->wlc; + char prev_country_abbrev[WLC_CNTRY_BUF_SZ]; + + ASSERT(country != NULL); + + /* save current country state */ + wlc_cm->country = country; + + memset(&prev_country_abbrev, 0, WLC_CNTRY_BUF_SZ); + strncpy(prev_country_abbrev, wlc_cm->country_abbrev, + WLC_CNTRY_BUF_SZ - 1); + + strncpy(wlc_cm->country_abbrev, country_abbrev, WLC_CNTRY_BUF_SZ - 1); + strncpy(wlc_cm->ccode, ccode, WLC_CNTRY_BUF_SZ - 1); + wlc_cm->regrev = regrev; + + /* disable/restore nmode based on country regulations */ + li_mimo = wlc_get_mimo_2g(country->locale_mimo_2G); + if (li_mimo && (li_mimo->flags & WLC_NO_MIMO)) { + wlc_set_nmode(wlc, OFF); + wlc->stf->no_cddstbc = true; + } else { + wlc->stf->no_cddstbc = false; + if (N_ENAB(wlc->pub) != wlc->protection->nmode_user) + wlc_set_nmode(wlc, wlc->protection->nmode_user); + } + + wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); + wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); + /* set or restore gmode as required by regulatory */ + locale = wlc_get_locale_2g(country->locale_2G); + if (locale && (locale->flags & WLC_NO_OFDM)) { + wlc_set_gmode(wlc, GMODE_LEGACY_B, false); + } else { + wlc_set_gmode(wlc, wlc->protection->gmode_user, false); + } + + wlc_channels_init(wlc_cm, country); + + return; +} + +/* Lookup a country info structure from a null terminated country code + * The lookup is case sensitive. + */ +const country_info_t *wlc_country_lookup(struct wlc_info *wlc, + const char *ccode) +{ + const country_info_t *country; + char mapped_ccode[WLC_CNTRY_BUF_SZ]; + uint mapped_regrev; + + /* map the country code to a built-in country code, regrev, and country_info struct */ + country = + wlc_countrycode_map(wlc->cmi, ccode, mapped_ccode, &mapped_regrev); + + return country; +} + +static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm, + const char *ccode, + char *mapped_ccode, + uint *mapped_regrev) +{ + struct wlc_info *wlc = wlc_cm->wlc; + const country_info_t *country; + uint srom_regrev = wlc_cm->srom_regrev; + const char *srom_ccode = wlc_cm->srom_ccode; + int mapped; + + /* check for currently supported ccode size */ + if (strlen(ccode) > (WLC_CNTRY_BUF_SZ - 1)) { + WL_ERROR("wl%d: %s: ccode \"%s\" too long for match\n", + wlc->pub->unit, __func__, ccode); + return NULL; + } + + /* default mapping is the given ccode and regrev 0 */ + strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ); + *mapped_regrev = 0; + + /* If the desired country code matches the srom country code, + * then the mapped country is the srom regulatory rev. + * Otherwise look for an aggregate mapping. + */ + if (!strcmp(srom_ccode, ccode)) { + *mapped_regrev = srom_regrev; + mapped = 0; + WL_ERROR("srom_code == ccode %s\n", __func__); + ASSERT(0); + } else { + mapped = + wlc_country_aggregate_map(wlc_cm, ccode, mapped_ccode, + mapped_regrev); + } + + /* find the matching built-in country definition */ + country = wlc_country_lookup_direct(mapped_ccode, *mapped_regrev); + + /* if there is not an exact rev match, default to rev zero */ + if (country == NULL && *mapped_regrev != 0) { + *mapped_regrev = 0; + ASSERT(0); + country = + wlc_country_lookup_direct(mapped_ccode, *mapped_regrev); + } + + return country; +} + +static int +wlc_country_aggregate_map(wlc_cm_info_t *wlc_cm, const char *ccode, + char *mapped_ccode, uint *mapped_regrev) +{ + return false; +} + +/* Lookup a country info structure from a null terminated country + * abbreviation and regrev directly with no translation. + */ +static const country_info_t *wlc_country_lookup_direct(const char *ccode, + uint regrev) +{ + uint size, i; + + /* Should just return 0 for single locale driver. */ + /* Keep it this way in case we add more locales. (for now anyway) */ + + /* all other country def arrays are for regrev == 0, so if regrev is non-zero, fail */ + if (regrev > 0) + return NULL; + + /* find matched table entry from country code */ + size = ARRAY_SIZE(cntry_locales); + for (i = 0; i < size; i++) { + if (strcmp(ccode, cntry_locales[i].abbrev) == 0) { + return &cntry_locales[i].country; + } + } + + WL_ERROR("%s: Returning NULL\n", __func__); + ASSERT(0); + return NULL; +} + +static int +wlc_channels_init(wlc_cm_info_t *wlc_cm, const country_info_t *country) +{ + struct wlc_info *wlc = wlc_cm->wlc; + uint i, j; + struct wlcband *band; + const locale_info_t *li; + chanvec_t sup_chan; + const locale_mimo_info_t *li_mimo; + + band = wlc->band; + for (i = 0; i < NBANDS(wlc); + i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { + + li = BAND_5G(band->bandtype) ? + wlc_get_locale_5g(country->locale_5G) : + wlc_get_locale_2g(country->locale_2G); + ASSERT(li); + wlc_cm->bandstate[band->bandunit].locale_flags = li->flags; + li_mimo = BAND_5G(band->bandtype) ? + wlc_get_mimo_5g(country->locale_mimo_5G) : + wlc_get_mimo_2g(country->locale_mimo_2G); + ASSERT(li_mimo); + + /* merge the mimo non-mimo locale flags */ + wlc_cm->bandstate[band->bandunit].locale_flags |= + li_mimo->flags; + + wlc_cm->bandstate[band->bandunit].restricted_channels = + g_table_restricted_chan[li->restricted_channels]; + wlc_cm->bandstate[band->bandunit].radar_channels = + g_table_radar_set[li->radar_channels]; + + /* set the channel availability, + * masking out the channels that may not be supported on this phy + */ + wlc_phy_chanspec_band_validch(band->pi, band->bandtype, + &sup_chan); + wlc_locale_get_channels(li, + &wlc_cm->bandstate[band->bandunit]. + valid_channels); + for (j = 0; j < sizeof(chanvec_t); j++) + wlc_cm->bandstate[band->bandunit].valid_channels. + vec[j] &= sup_chan.vec[j]; + } + + wlc_quiet_channels_reset(wlc_cm); + wlc_channels_commit(wlc_cm); + + return 0; +} + +/* Update the radio state (enable/disable) and tx power targets + * based on a new set of channel/regulatory information + */ +static void wlc_channels_commit(wlc_cm_info_t *wlc_cm) +{ + struct wlc_info *wlc = wlc_cm->wlc; + uint chan; + struct txpwr_limits txpwr; + + /* search for the existence of any valid channel */ + for (chan = 0; chan < MAXCHANNEL; chan++) { + if (VALID_CHANNEL20_DB(wlc, chan)) { + break; + } + } + if (chan == MAXCHANNEL) + chan = INVCHANNEL; + + /* based on the channel search above, set or clear WL_RADIO_COUNTRY_DISABLE */ + if (chan == INVCHANNEL) { + /* country/locale with no valid channels, set the radio disable bit */ + mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); + WL_ERROR("wl%d: %s: no valid channel for \"%s\" nbands %d bandlocked %d\n", + wlc->pub->unit, __func__, + wlc_cm->country_abbrev, NBANDS(wlc), wlc->bandlocked); + } else + if (mboolisset(wlc->pub->radio_disabled, + WL_RADIO_COUNTRY_DISABLE)) { + /* country/locale with valid channel, clear the radio disable bit */ + mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); + } + + /* Now that the country abbreviation is set, if the radio supports 2G, then + * set channel 14 restrictions based on the new locale. + */ + if (NBANDS(wlc) > 1 || BAND_2G(wlc->band->bandtype)) { + wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi, + wlc_japan(wlc) ? true : + false); + } + + if (wlc->pub->up && chan != INVCHANNEL) { + wlc_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr); + wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, + &txpwr, + WLC_TXPWR_MAX); + wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec); + } +} + +/* reset the quiet channels vector to the union of the restricted and radar channel sets */ +void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm) +{ + struct wlc_info *wlc = wlc_cm->wlc; + uint i, j; + struct wlcband *band; + const chanvec_t *chanvec; + + memset(&wlc_cm->quiet_channels, 0, sizeof(chanvec_t)); + + band = wlc->band; + for (i = 0; i < NBANDS(wlc); + i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { + + /* initialize quiet channels for restricted channels */ + chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels; + for (j = 0; j < sizeof(chanvec_t); j++) + wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j]; + + } +} + +bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec) +{ + return N_ENAB(wlc_cm->wlc->pub) && CHSPEC_IS40(chspec) ? + (isset + (wlc_cm->quiet_channels.vec, + LOWER_20_SB(CHSPEC_CHANNEL(chspec))) + || isset(wlc_cm->quiet_channels.vec, + UPPER_20_SB(CHSPEC_CHANNEL(chspec)))) : isset(wlc_cm-> + quiet_channels. + vec, + CHSPEC_CHANNEL + (chspec)); +} + +/* Is the channel valid for the current locale? (but don't consider channels not + * available due to bandlocking) + */ +bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val) +{ + struct wlc_info *wlc = wlc_cm->wlc; + + return VALID_CHANNEL20(wlc, val) || + (!wlc->bandlocked + && VALID_CHANNEL20_IN_BAND(wlc, OTHERBANDUNIT(wlc), val)); +} + +/* Is the channel valid for the current locale and specified band? */ +bool +wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, uint val) +{ + return ((val < MAXCHANNEL) + && isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val)); +} + +/* Is the channel valid for the current locale and current band? */ +bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val) +{ + struct wlc_info *wlc = wlc_cm->wlc; + + return ((val < MAXCHANNEL) && + isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec, + val)); +} + +/* Is the 40 MHz allowed for the current locale and specified band? */ +bool wlc_valid_40chanspec_in_band(wlc_cm_info_t *wlc_cm, uint bandunit) +{ + struct wlc_info *wlc = wlc_cm->wlc; + + return (((wlc_cm->bandstate[bandunit]. + locale_flags & (WLC_NO_MIMO | WLC_NO_40MHZ)) == 0) + && wlc->bandstate[bandunit]->mimo_cap_40); +} + +static void +wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t *wlc_cm, + struct txpwr_limits *txpwr, + u8 + local_constraint_qdbm) +{ + int j; + + /* CCK Rates */ + for (j = 0; j < WL_TX_POWER_CCK_NUM; j++) { + txpwr->cck[j] = min(txpwr->cck[j], local_constraint_qdbm); + } + + /* 20 MHz Legacy OFDM SISO */ + for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++) { + txpwr->ofdm[j] = min(txpwr->ofdm[j], local_constraint_qdbm); + } + + /* 20 MHz Legacy OFDM CDD */ + for (j = 0; j < WLC_NUM_RATES_OFDM; j++) { + txpwr->ofdm_cdd[j] = + min(txpwr->ofdm_cdd[j], local_constraint_qdbm); + } + + /* 40 MHz Legacy OFDM SISO */ + for (j = 0; j < WLC_NUM_RATES_OFDM; j++) { + txpwr->ofdm_40_siso[j] = + min(txpwr->ofdm_40_siso[j], local_constraint_qdbm); + } + + /* 40 MHz Legacy OFDM CDD */ + for (j = 0; j < WLC_NUM_RATES_OFDM; j++) { + txpwr->ofdm_40_cdd[j] = + min(txpwr->ofdm_40_cdd[j], local_constraint_qdbm); + } + + /* 20MHz MCS 0-7 SISO */ + for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { + txpwr->mcs_20_siso[j] = + min(txpwr->mcs_20_siso[j], local_constraint_qdbm); + } + + /* 20MHz MCS 0-7 CDD */ + for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { + txpwr->mcs_20_cdd[j] = + min(txpwr->mcs_20_cdd[j], local_constraint_qdbm); + } + + /* 20MHz MCS 0-7 STBC */ + for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { + txpwr->mcs_20_stbc[j] = + min(txpwr->mcs_20_stbc[j], local_constraint_qdbm); + } + + /* 20MHz MCS 8-15 MIMO */ + for (j = 0; j < WLC_NUM_RATES_MCS_2_STREAM; j++) + txpwr->mcs_20_mimo[j] = + min(txpwr->mcs_20_mimo[j], local_constraint_qdbm); + + /* 40MHz MCS 0-7 SISO */ + for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { + txpwr->mcs_40_siso[j] = + min(txpwr->mcs_40_siso[j], local_constraint_qdbm); + } + + /* 40MHz MCS 0-7 CDD */ + for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { + txpwr->mcs_40_cdd[j] = + min(txpwr->mcs_40_cdd[j], local_constraint_qdbm); + } + + /* 40MHz MCS 0-7 STBC */ + for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { + txpwr->mcs_40_stbc[j] = + min(txpwr->mcs_40_stbc[j], local_constraint_qdbm); + } + + /* 40MHz MCS 8-15 MIMO */ + for (j = 0; j < WLC_NUM_RATES_MCS_2_STREAM; j++) + txpwr->mcs_40_mimo[j] = + min(txpwr->mcs_40_mimo[j], local_constraint_qdbm); + + /* 40MHz MCS 32 */ + txpwr->mcs32 = min(txpwr->mcs32, local_constraint_qdbm); + +} + +void +wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, + u8 local_constraint_qdbm) +{ + struct wlc_info *wlc = wlc_cm->wlc; + struct txpwr_limits txpwr; + + wlc_channel_reg_limits(wlc_cm, chanspec, &txpwr); + + wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr, + local_constraint_qdbm); + + wlc_bmac_set_chanspec(wlc->hw, chanspec, + (wlc_quiet_chanspec(wlc_cm, chanspec) != 0), + &txpwr); +} + +int +wlc_channel_set_txpower_limit(wlc_cm_info_t *wlc_cm, + u8 local_constraint_qdbm) +{ + struct wlc_info *wlc = wlc_cm->wlc; + struct txpwr_limits txpwr; + + wlc_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr); + + wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr, + local_constraint_qdbm); + + wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec); + + return 0; +} + +#ifdef POWER_DBG +static void wlc_phy_txpower_limits_dump(txpwr_limits_t *txpwr) +{ + int i; + char fraction[4][4] = { " ", ".25", ".5 ", ".75" }; + + printf("CCK "); + for (i = 0; i < WLC_NUM_RATES_CCK; i++) { + printf(" %2d%s", txpwr->cck[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->cck[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("20 MHz OFDM SISO "); + for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { + printf(" %2d%s", txpwr->ofdm[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->ofdm[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("20 MHz OFDM CDD "); + for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { + printf(" %2d%s", txpwr->ofdm_cdd[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->ofdm_cdd[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("40 MHz OFDM SISO "); + for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { + printf(" %2d%s", txpwr->ofdm_40_siso[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->ofdm_40_siso[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("40 MHz OFDM CDD "); + for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { + printf(" %2d%s", txpwr->ofdm_40_cdd[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->ofdm_40_cdd[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("20 MHz MCS0-7 SISO "); + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + printf(" %2d%s", txpwr->mcs_20_siso[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_20_siso[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("20 MHz MCS0-7 CDD "); + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + printf(" %2d%s", txpwr->mcs_20_cdd[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_20_cdd[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("20 MHz MCS0-7 STBC "); + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + printf(" %2d%s", txpwr->mcs_20_stbc[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_20_stbc[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("20 MHz MCS8-15 SDM "); + for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) { + printf(" %2d%s", txpwr->mcs_20_mimo[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_20_mimo[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("40 MHz MCS0-7 SISO "); + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + printf(" %2d%s", txpwr->mcs_40_siso[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_40_siso[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("40 MHz MCS0-7 CDD "); + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + printf(" %2d%s", txpwr->mcs_40_cdd[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_40_cdd[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("40 MHz MCS0-7 STBC "); + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + printf(" %2d%s", txpwr->mcs_40_stbc[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_40_stbc[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("40 MHz MCS8-15 SDM "); + for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) { + printf(" %2d%s", txpwr->mcs_40_mimo[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_40_mimo[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("MCS32 %2d%s\n", + txpwr->mcs32 / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs32 % WLC_TXPWR_DB_FACTOR]); +} +#endif /* POWER_DBG */ + +void +wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, + txpwr_limits_t *txpwr) +{ + struct wlc_info *wlc = wlc_cm->wlc; + uint i; + uint chan; + int maxpwr; + int delta; + const country_info_t *country; + struct wlcband *band; + const locale_info_t *li; + int conducted_max; + int conducted_ofdm_max; + const locale_mimo_info_t *li_mimo; + int maxpwr20, maxpwr40; + int maxpwr_idx; + uint j; + + memset(txpwr, 0, sizeof(txpwr_limits_t)); + + if (!wlc_valid_chanspec_db(wlc_cm, chanspec)) { + country = wlc_country_lookup(wlc, wlc->autocountry_default); + if (country == NULL) + return; + } else { + country = wlc_cm->country; + } + + chan = CHSPEC_CHANNEL(chanspec); + band = wlc->bandstate[CHSPEC_WLCBANDUNIT(chanspec)]; + li = BAND_5G(band->bandtype) ? + wlc_get_locale_5g(country->locale_5G) : + wlc_get_locale_2g(country->locale_2G); + + li_mimo = BAND_5G(band->bandtype) ? + wlc_get_mimo_5g(country->locale_mimo_5G) : + wlc_get_mimo_2g(country->locale_mimo_2G); + + if (li->flags & WLC_EIRP) { + delta = band->antgain; + } else { + delta = 0; + if (band->antgain > QDB(6)) + delta = band->antgain - QDB(6); /* Excess over 6 dB */ + } + + if (li == &locale_i) { + conducted_max = QDB(22); + conducted_ofdm_max = QDB(22); + } + + /* CCK txpwr limits for 2.4G band */ + if (BAND_2G(band->bandtype)) { + maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_CCK(chan)]; + + maxpwr = maxpwr - delta; + maxpwr = max(maxpwr, 0); + maxpwr = min(maxpwr, conducted_max); + + for (i = 0; i < WLC_NUM_RATES_CCK; i++) + txpwr->cck[i] = (u8) maxpwr; + } + + /* OFDM txpwr limits for 2.4G or 5G bands */ + if (BAND_2G(band->bandtype)) { + maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_OFDM(chan)]; + + } else { + maxpwr = li->maxpwr[CHANNEL_POWER_IDX_5G(chan)]; + } + + maxpwr = maxpwr - delta; + maxpwr = max(maxpwr, 0); + maxpwr = min(maxpwr, conducted_ofdm_max); + + /* Keep OFDM lmit below CCK limit */ + if (BAND_2G(band->bandtype)) + maxpwr = min_t(int, maxpwr, txpwr->cck[0]); + + for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { + txpwr->ofdm[i] = (u8) maxpwr; + } + + for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { + /* OFDM 40 MHz SISO has the same power as the corresponding MCS0-7 rate unless + * overriden by the locale specific code. We set this value to 0 as a + * flag (presumably 0 dBm isn't a possibility) and then copy the MCS0-7 value + * to the 40 MHz value if it wasn't explicitly set. + */ + txpwr->ofdm_40_siso[i] = 0; + + txpwr->ofdm_cdd[i] = (u8) maxpwr; + + txpwr->ofdm_40_cdd[i] = 0; + } + + /* MIMO/HT specific limits */ + if (li_mimo->flags & WLC_EIRP) { + delta = band->antgain; + } else { + delta = 0; + if (band->antgain > QDB(6)) + delta = band->antgain - QDB(6); /* Excess over 6 dB */ + } + + if (BAND_2G(band->bandtype)) + maxpwr_idx = (chan - 1); + else + maxpwr_idx = CHANNEL_POWER_IDX_5G(chan); + + maxpwr20 = li_mimo->maxpwr20[maxpwr_idx]; + maxpwr40 = li_mimo->maxpwr40[maxpwr_idx]; + + maxpwr20 = maxpwr20 - delta; + maxpwr20 = max(maxpwr20, 0); + maxpwr40 = maxpwr40 - delta; + maxpwr40 = max(maxpwr40, 0); + + /* Fill in the MCS 0-7 (SISO) rates */ + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + + /* 20 MHz has the same power as the corresponding OFDM rate unless + * overriden by the locale specific code. + */ + txpwr->mcs_20_siso[i] = txpwr->ofdm[i]; + txpwr->mcs_40_siso[i] = 0; + } + + /* Fill in the MCS 0-7 CDD rates */ + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + txpwr->mcs_20_cdd[i] = (u8) maxpwr20; + txpwr->mcs_40_cdd[i] = (u8) maxpwr40; + } + + /* These locales have SISO expressed in the table and override CDD later */ + if (li_mimo == &locale_bn) { + if (li_mimo == &locale_bn) { + maxpwr20 = QDB(16); + maxpwr40 = 0; + + if (chan >= 3 && chan <= 11) { + maxpwr40 = QDB(16); + } + } + + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + txpwr->mcs_20_siso[i] = (u8) maxpwr20; + txpwr->mcs_40_siso[i] = (u8) maxpwr40; + } + } + + /* Fill in the MCS 0-7 STBC rates */ + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + txpwr->mcs_20_stbc[i] = 0; + txpwr->mcs_40_stbc[i] = 0; + } + + /* Fill in the MCS 8-15 SDM rates */ + for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) { + txpwr->mcs_20_mimo[i] = (u8) maxpwr20; + txpwr->mcs_40_mimo[i] = (u8) maxpwr40; + } + + /* Fill in MCS32 */ + txpwr->mcs32 = (u8) maxpwr40; + + for (i = 0, j = 0; i < WLC_NUM_RATES_OFDM; i++, j++) { + if (txpwr->ofdm_40_cdd[i] == 0) + txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j]; + if (i == 0) { + i = i + 1; + if (txpwr->ofdm_40_cdd[i] == 0) + txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j]; + } + } + + /* Copy the 40 MHZ MCS 0-7 CDD value to the 40 MHZ MCS 0-7 SISO value if it wasn't + * provided explicitly. + */ + + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + if (txpwr->mcs_40_siso[i] == 0) + txpwr->mcs_40_siso[i] = txpwr->mcs_40_cdd[i]; + } + + for (i = 0, j = 0; i < WLC_NUM_RATES_OFDM; i++, j++) { + if (txpwr->ofdm_40_siso[i] == 0) + txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j]; + if (i == 0) { + i = i + 1; + if (txpwr->ofdm_40_siso[i] == 0) + txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j]; + } + } + + /* Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding STBC values if they weren't + * provided explicitly. + */ + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + if (txpwr->mcs_20_stbc[i] == 0) + txpwr->mcs_20_stbc[i] = txpwr->mcs_20_cdd[i]; + + if (txpwr->mcs_40_stbc[i] == 0) + txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i]; + } + +#ifdef POWER_DBG + wlc_phy_txpower_limits_dump(txpwr); +#endif + return; +} + +/* Returns true if currently set country is Japan or variant */ +bool wlc_japan(struct wlc_info *wlc) +{ + return wlc_japan_ccode(wlc->cmi->country_abbrev); +} + +/* JP, J1 - J10 are Japan ccodes */ +static bool wlc_japan_ccode(const char *ccode) +{ + return (ccode[0] == 'J' && + (ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9'))); +} + +/* + * Validate the chanspec for this locale, for 40MHZ we need to also check that the sidebands + * are valid 20MZH channels in this locale and they are also a legal HT combination + */ +static bool +wlc_valid_chanspec_ext(wlc_cm_info_t *wlc_cm, chanspec_t chspec, bool dualband) +{ + struct wlc_info *wlc = wlc_cm->wlc; + u8 channel = CHSPEC_CHANNEL(chspec); + + /* check the chanspec */ + if (wf_chspec_malformed(chspec)) { + WL_ERROR("wl%d: malformed chanspec 0x%x\n", + wlc->pub->unit, chspec); + ASSERT(0); + return false; + } + + if (CHANNEL_BANDUNIT(wlc_cm->wlc, channel) != + CHSPEC_WLCBANDUNIT(chspec)) + return false; + + /* Check a 20Mhz channel */ + if (CHSPEC_IS20(chspec)) { + if (dualband) + return VALID_CHANNEL20_DB(wlc_cm->wlc, channel); + else + return VALID_CHANNEL20(wlc_cm->wlc, channel); + } +#ifdef SUPPORT_40MHZ + /* We know we are now checking a 40MHZ channel, so we should only be here + * for NPHYS + */ + if (WLCISNPHY(wlc->band) || WLCISSSLPNPHY(wlc->band)) { + u8 upper_sideband = 0, idx; + u8 num_ch20_entries = + sizeof(chan20_info) / sizeof(struct chan20_info); + + if (!VALID_40CHANSPEC_IN_BAND(wlc, CHSPEC_WLCBANDUNIT(chspec))) + return false; + + if (dualband) { + if (!VALID_CHANNEL20_DB(wlc, LOWER_20_SB(channel)) || + !VALID_CHANNEL20_DB(wlc, UPPER_20_SB(channel))) + return false; + } else { + if (!VALID_CHANNEL20(wlc, LOWER_20_SB(channel)) || + !VALID_CHANNEL20(wlc, UPPER_20_SB(channel))) + return false; + } + + /* find the lower sideband info in the sideband array */ + for (idx = 0; idx < num_ch20_entries; idx++) { + if (chan20_info[idx].sb == LOWER_20_SB(channel)) + upper_sideband = chan20_info[idx].adj_sbs; + } + /* check that the lower sideband allows an upper sideband */ + if ((upper_sideband & (CH_UPPER_SB | CH_EWA_VALID)) == + (CH_UPPER_SB | CH_EWA_VALID)) + return true; + return false; + } +#endif /* 40 MHZ */ + + return false; +} + +bool wlc_valid_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec) +{ + return wlc_valid_chanspec_ext(wlc_cm, chspec, false); +} + +bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec) +{ + return wlc_valid_chanspec_ext(wlc_cm, chspec, true); +} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_channel.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_channel.h new file mode 100644 index 000000000000..1f170aff68fd --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_channel.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _WLC_CHANNEL_H_ +#define _WLC_CHANNEL_H_ + +#include + +#define WLC_TXPWR_DB_FACTOR 4 /* conversion for phy txpwr cacluations that use .25 dB units */ + +struct wlc_info; + +/* maxpwr mapping to 5GHz band channels: + * maxpwr[0] - channels [34-48] + * maxpwr[1] - channels [52-60] + * maxpwr[2] - channels [62-64] + * maxpwr[3] - channels [100-140] + * maxpwr[4] - channels [149-165] + */ +#define BAND_5G_PWR_LVLS 5 /* 5 power levels for 5G */ + +/* power level in group of 2.4GHz band channels: + * maxpwr[0] - CCK channels [1] + * maxpwr[1] - CCK channels [2-10] + * maxpwr[2] - CCK channels [11-14] + * maxpwr[3] - OFDM channels [1] + * maxpwr[4] - OFDM channels [2-10] + * maxpwr[5] - OFDM channels [11-14] + */ + +/* macro to get 2.4 GHz channel group index for tx power */ +#define CHANNEL_POWER_IDX_2G_CCK(c) (((c) < 2) ? 0 : (((c) < 11) ? 1 : 2)) /* cck index */ +#define CHANNEL_POWER_IDX_2G_OFDM(c) (((c) < 2) ? 3 : (((c) < 11) ? 4 : 5)) /* ofdm index */ + +/* macro to get 5 GHz channel group index for tx power */ +#define CHANNEL_POWER_IDX_5G(c) \ + (((c) < 52) ? 0 : (((c) < 62) ? 1 : (((c) < 100) ? 2 : (((c) < 149) ? 3 : 4)))) + +#define WLC_MAXPWR_TBL_SIZE 6 /* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */ +#define WLC_MAXPWR_MIMO_TBL_SIZE 14 /* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */ + +/* locale channel and power info. */ +typedef struct { + u32 valid_channels; + u8 radar_channels; /* List of radar sensitive channels */ + u8 restricted_channels; /* List of channels used only if APs are detected */ + s8 maxpwr[WLC_MAXPWR_TBL_SIZE]; /* Max tx pwr in qdBm for each sub-band */ + s8 pub_maxpwr[BAND_5G_PWR_LVLS]; /* Country IE advertised max tx pwr in dBm + * per sub-band + */ + u8 flags; +} locale_info_t; + +/* bits for locale_info flags */ +#define WLC_PEAK_CONDUCTED 0x00 /* Peak for locals */ +#define WLC_EIRP 0x01 /* Flag for EIRP */ +#define WLC_DFS_TPC 0x02 /* Flag for DFS TPC */ +#define WLC_NO_OFDM 0x04 /* Flag for No OFDM */ +#define WLC_NO_40MHZ 0x08 /* Flag for No MIMO 40MHz */ +#define WLC_NO_MIMO 0x10 /* Flag for No MIMO, 20 or 40 MHz */ +#define WLC_RADAR_TYPE_EU 0x20 /* Flag for EU */ +#define WLC_DFS_FCC WLC_DFS_TPC /* Flag for DFS FCC */ +#define WLC_DFS_EU (WLC_DFS_TPC | WLC_RADAR_TYPE_EU) /* Flag for DFS EU */ + +#define ISDFS_EU(fl) (((fl) & WLC_DFS_EU) == WLC_DFS_EU) + +/* locale per-channel tx power limits for MIMO frames + * maxpwr arrays are index by channel for 2.4 GHz limits, and + * by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel) + */ +typedef struct { + s8 maxpwr20[WLC_MAXPWR_MIMO_TBL_SIZE]; /* tx 20 MHz power limits, qdBm units */ + s8 maxpwr40[WLC_MAXPWR_MIMO_TBL_SIZE]; /* tx 40 MHz power limits, qdBm units */ + u8 flags; +} locale_mimo_info_t; + +extern const chanvec_t chanvec_all_2G; +extern const chanvec_t chanvec_all_5G; + +/* + * Country names and abbreviations with locale defined from ISO 3166 + */ +struct country_info { + const u8 locale_2G; /* 2.4G band locale */ + const u8 locale_5G; /* 5G band locale */ + const u8 locale_mimo_2G; /* 2.4G mimo info */ + const u8 locale_mimo_5G; /* 5G mimo info */ +}; + +typedef struct country_info country_info_t; + +typedef struct wlc_cm_info wlc_cm_info_t; + +extern wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc); +extern void wlc_channel_mgr_detach(wlc_cm_info_t *wlc_cm); + +extern int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode); +extern int wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, + const char *country_abbrev, + const char *ccode, int regrev); + +extern const char *wlc_channel_country_abbrev(wlc_cm_info_t *wlc_cm); +extern u8 wlc_channel_locale_flags(wlc_cm_info_t *wlc_cm); +extern u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, + uint bandunit); + +extern void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm); +extern bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec); + +#define VALID_CHANNEL20_DB(wlc, val) wlc_valid_channel20_db((wlc)->cmi, val) +#define VALID_CHANNEL20_IN_BAND(wlc, bandunit, val) \ + wlc_valid_channel20_in_band((wlc)->cmi, bandunit, val) +#define VALID_CHANNEL20(wlc, val) wlc_valid_channel20((wlc)->cmi, val) +#define VALID_40CHANSPEC_IN_BAND(wlc, bandunit) wlc_valid_40chanspec_in_band((wlc)->cmi, bandunit) + +extern bool wlc_valid_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec); +extern bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec); +extern bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val); +extern bool wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, + uint val); +extern bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val); +extern bool wlc_valid_40chanspec_in_band(wlc_cm_info_t *wlc_cm, uint bandunit); + +extern void wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, + chanspec_t chanspec, + struct txpwr_limits *txpwr); +extern void wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm, + chanspec_t chanspec, + u8 local_constraint_qdbm); +extern int wlc_channel_set_txpower_limit(wlc_cm_info_t *wlc_cm, + u8 local_constraint_qdbm); + +extern const country_info_t *wlc_country_lookup(struct wlc_info *wlc, + const char *ccode); +extern void wlc_locale_get_channels(const locale_info_t *locale, + chanvec_t *valid_channels); +extern const locale_info_t *wlc_get_locale_2g(u8 locale_idx); +extern const locale_info_t *wlc_get_locale_5g(u8 locale_idx); +extern bool wlc_japan(struct wlc_info *wlc); + +extern u8 wlc_get_regclass(wlc_cm_info_t *wlc_cm, chanspec_t chanspec); +extern bool wlc_channel_get_chanvec(struct wlc_info *wlc, + const char *country_abbrev, int bandtype, + chanvec_t *channels); + +#endif /* _WLC_CHANNEL_H */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_event.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_event.c new file mode 100644 index 000000000000..dabd7094cd73 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_event.c @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#ifdef MSGTRACE +#include +#endif +#include + +/* Local prototypes */ +static void wlc_timer_cb(void *arg); + +/* Private data structures */ +struct wlc_eventq { + wlc_event_t *head; + wlc_event_t *tail; + struct wlc_info *wlc; + void *wl; + struct wlc_pub *pub; + bool tpending; + bool workpending; + struct wl_timer *timer; + wlc_eventq_cb_t cb; + u8 event_inds_mask[broken_roundup(WLC_E_LAST, NBBY) / NBBY]; +}; + +/* + * Export functions + */ +wlc_eventq_t *wlc_eventq_attach(struct wlc_pub *pub, struct wlc_info *wlc, + void *wl, + wlc_eventq_cb_t cb) +{ + wlc_eventq_t *eq; + + eq = kzalloc(sizeof(wlc_eventq_t), GFP_ATOMIC); + if (eq == NULL) + return NULL; + + eq->cb = cb; + eq->wlc = wlc; + eq->wl = wl; + eq->pub = pub; + + eq->timer = wl_init_timer(eq->wl, wlc_timer_cb, eq, "eventq"); + if (!eq->timer) { + WL_ERROR("wl%d: wlc_eventq_attach: timer failed\n", + pub->unit); + kfree(eq); + return NULL; + } + + return eq; +} + +int wlc_eventq_detach(wlc_eventq_t *eq) +{ + /* Clean up pending events */ + wlc_eventq_down(eq); + + if (eq->timer) { + if (eq->tpending) { + wl_del_timer(eq->wl, eq->timer); + eq->tpending = false; + } + wl_free_timer(eq->wl, eq->timer); + eq->timer = NULL; + } + + ASSERT(wlc_eventq_avail(eq) == false); + kfree(eq); + return 0; +} + +int wlc_eventq_down(wlc_eventq_t *eq) +{ + int callbacks = 0; + if (eq->tpending && !eq->workpending) { + if (!wl_del_timer(eq->wl, eq->timer)) + callbacks++; + + ASSERT(wlc_eventq_avail(eq) == true); + ASSERT(eq->workpending == false); + eq->workpending = true; + if (eq->cb) + eq->cb(eq->wlc); + + ASSERT(eq->workpending == true); + eq->workpending = false; + eq->tpending = false; + } else { + ASSERT(eq->workpending || wlc_eventq_avail(eq) == false); + } + return callbacks; +} + +wlc_event_t *wlc_event_alloc(wlc_eventq_t *eq) +{ + wlc_event_t *e; + + e = kzalloc(sizeof(wlc_event_t), GFP_ATOMIC); + + if (e == NULL) + return NULL; + + return e; +} + +void wlc_event_free(wlc_eventq_t *eq, wlc_event_t *e) +{ + ASSERT(e->data == NULL); + ASSERT(e->next == NULL); + kfree(e); +} + +void wlc_eventq_enq(wlc_eventq_t *eq, wlc_event_t *e) +{ + ASSERT(e->next == NULL); + e->next = NULL; + + if (eq->tail) { + eq->tail->next = e; + eq->tail = e; + } else + eq->head = eq->tail = e; + + if (!eq->tpending) { + eq->tpending = true; + /* Use a zero-delay timer to trigger + * delayed processing of the event. + */ + wl_add_timer(eq->wl, eq->timer, 0, 0); + } +} + +wlc_event_t *wlc_eventq_deq(wlc_eventq_t *eq) +{ + wlc_event_t *e; + + e = eq->head; + if (e) { + eq->head = e->next; + e->next = NULL; + + if (eq->head == NULL) + eq->tail = eq->head; + } + return e; +} + +wlc_event_t *wlc_eventq_next(wlc_eventq_t *eq, wlc_event_t *e) +{ +#ifdef BCMDBG + wlc_event_t *etmp; + + for (etmp = eq->head; etmp; etmp = etmp->next) { + if (etmp == e) + break; + } + ASSERT(etmp != NULL); +#endif + + return e->next; +} + +int wlc_eventq_cnt(wlc_eventq_t *eq) +{ + wlc_event_t *etmp; + int cnt = 0; + + for (etmp = eq->head; etmp; etmp = etmp->next) + cnt++; + + return cnt; +} + +bool wlc_eventq_avail(wlc_eventq_t *eq) +{ + return (eq->head != NULL); +} + +/* + * Local Functions + */ +static void wlc_timer_cb(void *arg) +{ + struct wlc_eventq *eq = (struct wlc_eventq *)arg; + + ASSERT(eq->tpending == true); + ASSERT(wlc_eventq_avail(eq) == true); + ASSERT(eq->workpending == false); + eq->workpending = true; + + if (eq->cb) + eq->cb(eq->wlc); + + ASSERT(wlc_eventq_avail(eq) == false); + ASSERT(eq->tpending == true); + eq->workpending = false; + eq->tpending = false; +} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_event.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_event.h new file mode 100644 index 000000000000..e75582dcdd93 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_event.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _WLC_EVENT_H_ +#define _WLC_EVENT_H_ + +typedef struct wlc_eventq wlc_eventq_t; + +typedef void (*wlc_eventq_cb_t) (void *arg); + +extern wlc_eventq_t *wlc_eventq_attach(struct wlc_pub *pub, + struct wlc_info *wlc, + void *wl, wlc_eventq_cb_t cb); +extern int wlc_eventq_detach(wlc_eventq_t *eq); +extern int wlc_eventq_down(wlc_eventq_t *eq); +extern void wlc_event_free(wlc_eventq_t *eq, wlc_event_t *e); +extern wlc_event_t *wlc_eventq_next(wlc_eventq_t *eq, wlc_event_t *e); +extern int wlc_eventq_cnt(wlc_eventq_t *eq); +extern bool wlc_eventq_avail(wlc_eventq_t *eq); +extern wlc_event_t *wlc_eventq_deq(wlc_eventq_t *eq); +extern void wlc_eventq_enq(wlc_eventq_t *eq, wlc_event_t *e); +extern wlc_event_t *wlc_event_alloc(wlc_eventq_t *eq); + +extern int wlc_eventq_register_ind(wlc_eventq_t *eq, void *bitvect); +extern int wlc_eventq_query_ind(wlc_eventq_t *eq, void *bitvect); +extern int wlc_eventq_test_ind(wlc_eventq_t *eq, int et); +extern int wlc_eventq_set_ind(wlc_eventq_t *eq, uint et, bool on); +extern void wlc_eventq_flush(wlc_eventq_t *eq); +extern void wlc_assign_event_msg(struct wlc_info *wlc, wl_event_msg_t *msg, + const wlc_event_t *e, u8 *data, + u32 len); + +#ifdef MSGTRACE +extern void wlc_event_sendup_trace(struct wlc_info *wlc, hndrte_dev_t *bus, + u8 *hdr, u16 hdrlen, u8 *buf, + u16 buflen); +#endif + +#endif /* _WLC_EVENT_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_key.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_key.h new file mode 100644 index 000000000000..3e23d5145919 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_key.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_key_h_ +#define _wlc_key_h_ + +struct scb; +struct wlc_info; +struct wlc_bsscfg; +/* Maximum # of keys that wl driver supports in S/W. + * Keys supported in H/W is less than or equal to WSEC_MAX_KEYS. + */ +#define WSEC_MAX_KEYS 54 /* Max # of keys (50 + 4 default keys) */ +#define WLC_DEFAULT_KEYS 4 /* Default # of keys */ + +#define WSEC_MAX_WOWL_KEYS 5 /* Max keys in WOWL mode (1 + 4 default keys) */ + +#define WPA2_GTK_MAX 3 + +/* +* Max # of keys currently supported: +* +* s/w keys if WSEC_SW(wlc->wsec). +* h/w keys otherwise. +*/ +#define WLC_MAX_WSEC_KEYS(wlc) WSEC_MAX_KEYS + +/* number of 802.11 default (non-paired, group keys) */ +#define WSEC_MAX_DEFAULT_KEYS 4 /* # of default keys */ + +/* Max # of hardware keys supported */ +#define WLC_MAX_WSEC_HW_KEYS(wlc) WSEC_MAX_RCMTA_KEYS + +/* Max # of hardware TKIP MIC keys supported */ +#define WLC_MAX_TKMIC_HW_KEYS(wlc) ((D11REV_GE((wlc)->pub->corerev, 13)) ? \ + WSEC_MAX_TKMIC_ENGINE_KEYS : 0) + +#define WSEC_HW_TKMIC_KEY(wlc, key, bsscfg) \ + (((D11REV_GE((wlc)->pub->corerev, 13)) && ((wlc)->machwcap & MCAP_TKIPMIC)) && \ + (key) && ((key)->algo == CRYPTO_ALGO_TKIP) && \ + !WSEC_SOFTKEY(wlc, key, bsscfg) && \ + WSEC_KEY_INDEX(wlc, key) >= WLC_DEFAULT_KEYS && \ + (WSEC_KEY_INDEX(wlc, key) < WSEC_MAX_TKMIC_ENGINE_KEYS)) + +/* index of key in key table */ +#define WSEC_KEY_INDEX(wlc, key) ((key)->idx) + +#define WSEC_SOFTKEY(wlc, key, bsscfg) (WLC_SW_KEYS(wlc, bsscfg) || \ + WSEC_KEY_INDEX(wlc, key) >= WLC_MAX_WSEC_HW_KEYS(wlc)) + +/* get a key, non-NULL only if key allocated and not clear */ +#define WSEC_KEY(wlc, i) (((wlc)->wsec_keys[i] && (wlc)->wsec_keys[i]->len) ? \ + (wlc)->wsec_keys[i] : NULL) + +#define WSEC_SCB_KEY_VALID(scb) (((scb)->key && (scb)->key->len) ? true : false) + +/* default key */ +#define WSEC_BSS_DEFAULT_KEY(bsscfg) (((bsscfg)->wsec_index == -1) ? \ + (struct wsec_key *)NULL:(bsscfg)->bss_def_keys[(bsscfg)->wsec_index]) + +/* Macros for key management in IBSS mode */ +#define WSEC_IBSS_MAX_PEERS 16 /* Max # of IBSS Peers */ +#define WSEC_IBSS_RCMTA_INDEX(idx) \ + (((idx - WSEC_MAX_DEFAULT_KEYS) % WSEC_IBSS_MAX_PEERS) + WSEC_MAX_DEFAULT_KEYS) + +/* contiguous # key slots for infrastructure mode STA */ +#define WSEC_BSS_STA_KEY_GROUP_SIZE 5 + +typedef struct wsec_iv { + u32 hi; /* upper 32 bits of IV */ + u16 lo; /* lower 16 bits of IV */ +} wsec_iv_t; + +#define WLC_NUMRXIVS 16 /* # rx IVs (one per 802.11e TID) */ + +typedef struct wsec_key { + u8 ea[ETH_ALEN]; /* per station */ + u8 idx; /* key index in wsec_keys array */ + u8 id; /* key ID [0-3] */ + u8 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ + u8 rcmta; /* rcmta entry index, same as idx by default */ + u16 flags; /* misc flags */ + u8 algo_hw; /* cache for hw register */ + u8 aes_mode; /* cache for hw register */ + s8 iv_len; /* IV length */ + s8 icv_len; /* ICV length */ + u32 len; /* key length..don't move this var */ + /* data is 4byte aligned */ + u8 data[DOT11_MAX_KEY_SIZE]; /* key data */ + wsec_iv_t rxiv[WLC_NUMRXIVS]; /* Rx IV (one per TID) */ + wsec_iv_t txiv; /* Tx IV */ + +} wsec_key_t; + +#define broken_roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) +typedef struct { + u8 vec[broken_roundup(WSEC_MAX_KEYS, NBBY) / NBBY]; /* bitvec of wsec_key indexes */ +} wsec_key_vec_t; + +/* For use with wsec_key_t.flags */ + +#define WSEC_BS_UPDATE (1 << 0) /* Indicates hw needs key update on BS switch */ +#define WSEC_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */ +#define WSEC_TKIP_ERROR (1 << 2) /* Provoke deliberate MIC error */ +#define WSEC_REPLAY_ERROR (1 << 3) /* Provoke deliberate replay */ +#define WSEC_IBSS_PEER_GROUP_KEY (1 << 7) /* Flag: group key for a IBSS PEER */ +#define WSEC_ICV_ERROR (1 << 8) /* Provoke deliberate ICV error */ + +#define wlc_key_insert(a, b, c, d, e, f, g, h, i, j) (BCME_ERROR) +#define wlc_key_update(a, b, c) do {} while (0) +#define wlc_key_remove(a, b, c) do {} while (0) +#define wlc_key_remove_all(a, b) do {} while (0) +#define wlc_key_delete(a, b, c) do {} while (0) +#define wlc_scb_key_delete(a, b) do {} while (0) +#define wlc_key_lookup(a, b, c, d, e) (NULL) +#define wlc_key_hw_init_all(a) do {} while (0) +#define wlc_key_hw_init(a, b, c) do {} while (0) +#define wlc_key_hw_wowl_init(a, b, c, d) do {} while (0) +#define wlc_key_sw_wowl_update(a, b, c, d, e) do {} while (0) +#define wlc_key_sw_wowl_create(a, b, c) (BCME_ERROR) +#define wlc_key_iv_update(a, b, c, d, e) do {(void)e; } while (0) +#define wlc_key_iv_init(a, b, c) do {} while (0) +#define wlc_key_set_error(a, b, c) (BCME_ERROR) +#define wlc_key_dump_hw(a, b) (BCME_ERROR) +#define wlc_key_dump_sw(a, b) (BCME_ERROR) +#define wlc_key_defkeyflag(a) (0) +#define wlc_rcmta_add_bssid(a, b) do {} while (0) +#define wlc_rcmta_del_bssid(a, b) do {} while (0) +#define wlc_key_scb_delete(a, b) do {} while (0) + +#endif /* _wlc_key_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_mac80211.c new file mode 100644 index 000000000000..5eb41d64bc23 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_mac80211.c @@ -0,0 +1,8479 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "d11ucode_ext.h" +#include +#include +#include + + +/* + * WPA(2) definitions + */ +#define RSN_CAP_4_REPLAY_CNTRS 2 +#define RSN_CAP_16_REPLAY_CNTRS 3 + +#define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS +#define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS + +/* + * buffer length needed for wlc_format_ssid + * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. + */ +#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) + +#define TIMER_INTERVAL_WATCHDOG 1000 /* watchdog timer, in unit of ms */ +#define TIMER_INTERVAL_RADIOCHK 800 /* radio monitor timer, in unit of ms */ + +#ifndef WLC_MPC_MAX_DELAYCNT +#define WLC_MPC_MAX_DELAYCNT 10 /* Max MPC timeout, in unit of watchdog */ +#endif +#define WLC_MPC_MIN_DELAYCNT 1 /* Min MPC timeout, in unit of watchdog */ +#define WLC_MPC_THRESHOLD 3 /* MPC count threshold level */ + +#define BEACON_INTERVAL_DEFAULT 100 /* beacon interval, in unit of 1024TU */ +#define DTIM_INTERVAL_DEFAULT 3 /* DTIM interval, in unit of beacon interval */ + +/* Scale down delays to accommodate QT slow speed */ +#define BEACON_INTERVAL_DEF_QT 20 /* beacon interval, in unit of 1024TU */ +#define DTIM_INTERVAL_DEF_QT 1 /* DTIM interval, in unit of beacon interval */ + +#define TBTT_ALIGN_LEEWAY_US 100 /* min leeway before first TBTT in us */ + +/* + * driver maintains internal 'tick'(wlc->pub->now) which increments in 1s OS timer(soft + * watchdog) it is not a wall clock and won't increment when driver is in "down" state + * this low resolution driver tick can be used for maintenance tasks such as phy + * calibration and scb update + */ + +/* watchdog trigger mode: OSL timer or TBTT */ +#define WLC_WATCHDOG_TBTT(wlc) \ + (wlc->stas_associated > 0 && wlc->PM != PM_OFF && wlc->pub->align_wd_tbtt) + +/* To inform the ucode of the last mcast frame posted so that it can clear moredata bit */ +#define BCMCFID(wlc, fid) wlc_bmac_write_shm((wlc)->hw, M_BCMC_FID, (fid)) + +#define WLC_WAR16165(wlc) (wlc->pub->sih->bustype == PCI_BUS && \ + (!AP_ENAB(wlc->pub)) && (wlc->war16165)) + +/* debug/trace */ +uint wl_msg_level = +#if defined(BCMDBG) + WL_ERROR_VAL; +#else + 0; +#endif /* BCMDBG */ + +/* Find basic rate for a given rate */ +#define WLC_BASIC_RATE(wlc, rspec) (IS_MCS(rspec) ? \ + (wlc)->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK].leg_ofdm] : \ + (wlc)->band->basic_rate[rspec & RSPEC_RATE_MASK]) + +#define FRAMETYPE(r, mimoframe) (IS_MCS(r) ? mimoframe : (IS_CCK(r) ? FT_CCK : FT_OFDM)) + +#define RFDISABLE_DEFAULT 10000000 /* rfdisable delay timer 500 ms, runs of ALP clock */ + +#define WLC_TEMPSENSE_PERIOD 10 /* 10 second timeout */ + +#define SCAN_IN_PROGRESS(x) 0 + +#define EPI_VERSION_NUM 0x054b0b00 + +#ifdef BCMDBG +/* pointer to most recently allocated wl/wlc */ +static struct wlc_info *wlc_info_dbg = (struct wlc_info *) (NULL); +#endif + +/* IOVar table */ + +/* Parameter IDs, for use only internally to wlc -- in the wlc_iovars + * table and by the wlc_doiovar() function. No ordering is imposed: + * the table is keyed by name, and the function uses a switch. + */ +enum { + IOV_MPC = 1, + IOV_QTXPOWER, + IOV_BCN_LI_BCN, /* Beacon listen interval in # of beacons */ + IOV_LAST /* In case of a need to check max ID number */ +}; + +const bcm_iovar_t wlc_iovars[] = { + {"mpc", IOV_MPC, (IOVF_OPEN_ALLOW), IOVT_BOOL, 0}, + {"qtxpower", IOV_QTXPOWER, (IOVF_WHL | IOVF_OPEN_ALLOW), IOVT_UINT32, + 0}, + {"bcn_li_bcn", IOV_BCN_LI_BCN, 0, IOVT_UINT8, 0}, + {NULL, 0, 0, 0, 0} +}; + +const u8 prio2fifo[NUMPRIO] = { + TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */ + TX_AC_BK_FIFO, /* 1 BK AC_BK Background */ + TX_AC_BK_FIFO, /* 2 -- AC_BK Background */ + TX_AC_BE_FIFO, /* 3 EE AC_BE Best Effort */ + TX_AC_VI_FIFO, /* 4 CL AC_VI Video */ + TX_AC_VI_FIFO, /* 5 VI AC_VI Video */ + TX_AC_VO_FIFO, /* 6 VO AC_VO Voice */ + TX_AC_VO_FIFO /* 7 NC AC_VO Voice */ +}; + +/* precedences numbers for wlc queues. These are twice as may levels as + * 802.1D priorities. + * Odd numbers are used for HI priority traffic at same precedence levels + * These constants are used ONLY by wlc_prio2prec_map. Do not use them elsewhere. + */ +#define _WLC_PREC_NONE 0 /* None = - */ +#define _WLC_PREC_BK 2 /* BK - Background */ +#define _WLC_PREC_BE 4 /* BE - Best-effort */ +#define _WLC_PREC_EE 6 /* EE - Excellent-effort */ +#define _WLC_PREC_CL 8 /* CL - Controlled Load */ +#define _WLC_PREC_VI 10 /* Vi - Video */ +#define _WLC_PREC_VO 12 /* Vo - Voice */ +#define _WLC_PREC_NC 14 /* NC - Network Control */ + +/* 802.1D Priority to precedence queue mapping */ +const u8 wlc_prio2prec_map[] = { + _WLC_PREC_BE, /* 0 BE - Best-effort */ + _WLC_PREC_BK, /* 1 BK - Background */ + _WLC_PREC_NONE, /* 2 None = - */ + _WLC_PREC_EE, /* 3 EE - Excellent-effort */ + _WLC_PREC_CL, /* 4 CL - Controlled Load */ + _WLC_PREC_VI, /* 5 Vi - Video */ + _WLC_PREC_VO, /* 6 Vo - Voice */ + _WLC_PREC_NC, /* 7 NC - Network Control */ +}; + +/* Sanity check for tx_prec_map and fifo synchup + * Either there are some packets pending for the fifo, else if fifo is empty then + * all the corresponding precmap bits should be set + */ +#define WLC_TX_FIFO_CHECK(wlc, fifo) (TXPKTPENDGET((wlc), (fifo)) || \ + (TXPKTPENDGET((wlc), (fifo)) == 0 && \ + ((wlc)->tx_prec_map & (wlc)->fifo2prec_map[(fifo)]) == \ + (wlc)->fifo2prec_map[(fifo)])) + +/* TX FIFO number to WME/802.1E Access Category */ +const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE }; + +/* WME/802.1E Access Category to TX FIFO number */ +static const u8 wme_ac2fifo[] = { 1, 0, 2, 3 }; + +static bool in_send_q = false; + +/* Shared memory location index for various AC params */ +#define wme_shmemacindex(ac) wme_ac2fifo[ac] + +#ifdef BCMDBG +static const char *fifo_names[] = { + "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; +const char *aci_names[] = { "AC_BE", "AC_BK", "AC_VI", "AC_VO" }; +#endif + +static const u8 acbitmap2maxprio[] = { + PRIO_8021D_BE, PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_BK, + PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, + PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, + PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO +}; + +/* currently the best mechanism for determining SIFS is the band in use */ +#define SIFS(band) ((band)->bandtype == WLC_BAND_5G ? APHY_SIFS_TIME : BPHY_SIFS_TIME); + +/* value for # replay counters currently supported */ +#define WLC_REPLAY_CNTRS_VALUE WPA_CAP_16_REPLAY_CNTRS + +/* local prototypes */ +static u16 BCMFASTPATH wlc_d11hdrs_mac80211(struct wlc_info *wlc, + struct ieee80211_hw *hw, + struct sk_buff *p, + struct scb *scb, uint frag, + uint nfrags, uint queue, + uint next_frag_len, + wsec_key_t *key, + ratespec_t rspec_override); + +static void wlc_bss_default_init(struct wlc_info *wlc); +static void wlc_ucode_mac_upd(struct wlc_info *wlc); +static ratespec_t mac80211_wlc_set_nrate(struct wlc_info *wlc, + struct wlcband *cur_band, u32 int_val); +static void wlc_tx_prec_map_init(struct wlc_info *wlc); +static void wlc_watchdog(void *arg); +static void wlc_watchdog_by_timer(void *arg); +static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg); +static int wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, + const bcm_iovar_t *vi); +static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc); + +/* send and receive */ +static wlc_txq_info_t *wlc_txq_alloc(struct wlc_info *wlc, + struct osl_info *osh); +static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh, + wlc_txq_info_t *qi); +static void wlc_txflowcontrol_signal(struct wlc_info *wlc, wlc_txq_info_t *qi, + bool on, int prio); +static void wlc_txflowcontrol_reset(struct wlc_info *wlc); +static u16 wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, + uint length); +static void wlc_compute_cck_plcp(ratespec_t rate, uint length, u8 *plcp); +static void wlc_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp); +static void wlc_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp); +static u16 wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, + u8 preamble_type, uint next_frag_len); +static void wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, + d11rxhdr_t *rxh, struct sk_buff *p); +static uint wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t rate, + u8 preamble_type, uint dur); +static uint wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rate, + u8 preamble_type); +static uint wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rate, + u8 preamble_type); +/* interrupt, up/down, band */ +static void wlc_setband(struct wlc_info *wlc, uint bandunit); +static chanspec_t wlc_init_chanspec(struct wlc_info *wlc); +static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec); +static void wlc_bsinit(struct wlc_info *wlc); +static int wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, + bool writeToShm); +static void wlc_radio_hwdisable_upd(struct wlc_info *wlc); +static bool wlc_radio_monitor_start(struct wlc_info *wlc); +static void wlc_radio_timer(void *arg); +static void wlc_radio_enable(struct wlc_info *wlc); +static void wlc_radio_upd(struct wlc_info *wlc); + +/* scan, association, BSS */ +static uint wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rate, + u8 preamble_type); +static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap); +static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val); +static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val); +static void wlc_war16165(struct wlc_info *wlc, bool tx); + +static void wlc_process_eventq(void *arg); +static void wlc_wme_retries_write(struct wlc_info *wlc); +static bool wlc_attach_stf_ant_init(struct wlc_info *wlc); +static uint wlc_attach_module(struct wlc_info *wlc); +static void wlc_detach_module(struct wlc_info *wlc); +static void wlc_timers_deinit(struct wlc_info *wlc); +static void wlc_down_led_upd(struct wlc_info *wlc); +static uint wlc_down_del_timer(struct wlc_info *wlc); +static void wlc_ofdm_rateset_war(struct wlc_info *wlc); +static int _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, + struct wlc_if *wlcif); + +#if defined(BCMDBG) +void wlc_get_rcmta(struct wlc_info *wlc, int idx, u8 *addr) +{ + d11regs_t *regs = wlc->regs; + u32 v32; + struct osl_info *osh; + + WL_TRACE("wl%d: %s\n", WLCWLUNIT(wlc), __func__); + + ASSERT(wlc->pub->corerev > 4); + + osh = wlc->osh; + + W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); + (void)R_REG(osh, ®s->objaddr); + v32 = R_REG(osh, ®s->objdata); + addr[0] = (u8) v32; + addr[1] = (u8) (v32 >> 8); + addr[2] = (u8) (v32 >> 16); + addr[3] = (u8) (v32 >> 24); + W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1))); + (void)R_REG(osh, ®s->objaddr); + v32 = R_REG(osh, (volatile u16 *)®s->objdata); + addr[4] = (u8) v32; + addr[5] = (u8) (v32 >> 8); +} +#endif /* defined(BCMDBG) */ + +/* keep the chip awake if needed */ +bool wlc_stay_awake(struct wlc_info *wlc) +{ + return true; +} + +/* conditions under which the PM bit should be set in outgoing frames and STAY_AWAKE is meaningful + */ +bool wlc_ps_allowed(struct wlc_info *wlc) +{ + int idx; + wlc_bsscfg_t *cfg; + + /* disallow PS when one of the following global conditions meets */ + if (!wlc->pub->associated || !wlc->PMenabled || wlc->PM_override) + return false; + + /* disallow PS when one of these meets when not scanning */ + if (!wlc->PMblocked) { + if (AP_ACTIVE(wlc) || wlc->monitor) + return false; + } + + FOREACH_AS_STA(wlc, idx, cfg) { + /* disallow PS when one of the following bsscfg specific conditions meets */ + if (!cfg->BSS || !WLC_PORTOPEN(cfg)) + return false; + + if (!cfg->dtim_programmed) + return false; + } + + return true; +} + +void wlc_reset(struct wlc_info *wlc) +{ + WL_TRACE("wl%d: wlc_reset\n", wlc->pub->unit); + + wlc->check_for_unaligned_tbtt = false; + + /* slurp up hw mac counters before core reset */ + if (WLC_UPDATE_STATS(wlc)) { + wlc_statsupd(wlc); + + /* reset our snapshot of macstat counters */ + memset((char *)wlc->core->macstat_snapshot, 0, + sizeof(macstat_t)); + } + + wlc_bmac_reset(wlc->hw); + wlc_ampdu_reset(wlc->ampdu); + wlc->txretried = 0; + +} + +void wlc_fatal_error(struct wlc_info *wlc) +{ + WL_ERROR("wl%d: fatal error, reinitializing\n", wlc->pub->unit); + wl_init(wlc->wl); +} + +/* Return the channel the driver should initialize during wlc_init. + * the channel may have to be changed from the currently configured channel + * if other configurations are in conflict (bandlocked, 11n mode disabled, + * invalid channel for current country, etc.) + */ +static chanspec_t wlc_init_chanspec(struct wlc_info *wlc) +{ + chanspec_t chanspec = + 1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE | + WL_CHANSPEC_BAND_2G; + + /* make sure the channel is on the supported band if we are band-restricted */ + if (wlc->bandlocked || NBANDS(wlc) == 1) { + ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit); + } + ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec)); + return chanspec; +} + +struct scb global_scb; + +static void wlc_init_scb(struct wlc_info *wlc, struct scb *scb) +{ + int i; + scb->flags = SCB_WMECAP | SCB_HTCAP; + for (i = 0; i < NUMPRIO; i++) + scb->seqnum[i] = 0; +} + +void wlc_init(struct wlc_info *wlc) +{ + d11regs_t *regs; + chanspec_t chanspec; + int i; + wlc_bsscfg_t *bsscfg; + bool mute = false; + + WL_TRACE("wl%d: wlc_init\n", wlc->pub->unit); + + regs = wlc->regs; + + /* This will happen if a big-hammer was executed. In that case, we want to go back + * to the channel that we were on and not new channel + */ + if (wlc->pub->associated) + chanspec = wlc->home_chanspec; + else + chanspec = wlc_init_chanspec(wlc); + + wlc_bmac_init(wlc->hw, chanspec, mute); + + wlc->seckeys = wlc_bmac_read_shm(wlc->hw, M_SECRXKEYS_PTR) * 2; + if (D11REV_GE(wlc->pub->corerev, 15) && (wlc->machwcap & MCAP_TKIPMIC)) + wlc->tkmickeys = + wlc_bmac_read_shm(wlc->hw, M_TKMICKEYS_PTR) * 2; + + /* update beacon listen interval */ + wlc_bcn_li_upd(wlc); + wlc->bcn_wait_prd = + (u8) (wlc_bmac_read_shm(wlc->hw, M_NOSLPZNATDTIM) >> 10); + ASSERT(wlc->bcn_wait_prd > 0); + + /* the world is new again, so is our reported rate */ + wlc_reprate_init(wlc); + + /* write ethernet address to core */ + FOREACH_BSS(wlc, i, bsscfg) { + wlc_set_mac(bsscfg); + wlc_set_bssid(bsscfg); + } + + /* Update tsf_cfprep if associated and up */ + if (wlc->pub->associated) { + FOREACH_BSS(wlc, i, bsscfg) { + if (bsscfg->up) { + u32 bi; + + /* get beacon period from bsscfg and convert to uS */ + bi = bsscfg->current_bss->beacon_period << 10; + /* update the tsf_cfprep register */ + /* since init path would reset to default value */ + W_REG(wlc->osh, ®s->tsf_cfprep, + (bi << CFPREP_CBI_SHIFT)); + + /* Update maccontrol PM related bits */ + wlc_set_ps_ctrl(wlc); + + break; + } + } + } + + wlc_key_hw_init_all(wlc); + + wlc_bandinit_ordered(wlc, chanspec); + + wlc_init_scb(wlc, &global_scb); + + /* init probe response timeout */ + wlc_write_shm(wlc, M_PRS_MAXTIME, wlc->prb_resp_timeout); + + /* init max burst txop (framebursting) */ + wlc_write_shm(wlc, M_MBURST_TXOP, + (wlc-> + _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP)); + + /* initialize maximum allowed duty cycle */ + wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true); + wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true); + + /* Update some shared memory locations related to max AMPDU size allowed to received */ + wlc_ampdu_shm_upd(wlc->ampdu); + + /* band-specific inits */ + wlc_bsinit(wlc); + + /* Enable EDCF mode (while the MAC is suspended) */ + if (EDCF_ENAB(wlc->pub)) { + OR_REG(wlc->osh, ®s->ifs_ctl, IFS_USEEDCF); + wlc_edcf_setparams(wlc->cfg, false); + } + + /* Init precedence maps for empty FIFOs */ + wlc_tx_prec_map_init(wlc); + + /* read the ucode version if we have not yet done so */ + if (wlc->ucode_rev == 0) { + wlc->ucode_rev = + wlc_read_shm(wlc, M_BOM_REV_MAJOR) << NBITS(u16); + wlc->ucode_rev |= wlc_read_shm(wlc, M_BOM_REV_MINOR); + } + + /* ..now really unleash hell (allow the MAC out of suspend) */ + wlc_enable_mac(wlc); + + /* clear tx flow control */ + wlc_txflowcontrol_reset(wlc); + + /* clear tx data fifo suspends */ + wlc->tx_suspended = false; + + /* enable the RF Disable Delay timer */ + if (D11REV_GE(wlc->pub->corerev, 10)) + W_REG(wlc->osh, &wlc->regs->rfdisabledly, RFDISABLE_DEFAULT); + + /* initialize mpc delay */ + wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; + + /* + * Initialize WME parameters; if they haven't been set by some other + * mechanism (IOVar, etc) then read them from the hardware. + */ + if (WLC_WME_RETRY_SHORT_GET(wlc, 0) == 0) { /* Unintialized; read from HW */ + int ac; + + ASSERT(wlc->clk); + for (ac = 0; ac < AC_COUNT; ac++) { + wlc->wme_retries[ac] = + wlc_read_shm(wlc, M_AC_TXLMT_ADDR(ac)); + } + } +} + +void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc) +{ + wlc->bcnmisc_monitor = promisc; + wlc_mac_bcn_promisc(wlc); +} + +void wlc_mac_bcn_promisc(struct wlc_info *wlc) +{ + if ((AP_ENAB(wlc->pub) && (N_ENAB(wlc->pub) || wlc->band->gmode)) || + wlc->bcnmisc_ibss || wlc->bcnmisc_scan || wlc->bcnmisc_monitor) + wlc_mctrl(wlc, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC); + else + wlc_mctrl(wlc, MCTL_BCNS_PROMISC, 0); +} + +/* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */ +void wlc_mac_promisc(struct wlc_info *wlc) +{ + u32 promisc_bits = 0; + + /* promiscuous mode just sets MCTL_PROMISC + * Note: APs get all BSS traffic without the need to set the MCTL_PROMISC bit + * since all BSS data traffic is directed at the AP + */ + if (PROMISC_ENAB(wlc->pub) && !AP_ENAB(wlc->pub) && !wlc->wet) + promisc_bits |= MCTL_PROMISC; + + /* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL + * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is + * handled in wlc_mac_bcn_promisc() + */ + if (MONITOR_ENAB(wlc)) + promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL; + + wlc_mctrl(wlc, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits); +} + +/* check if hps and wake states of sw and hw are in sync */ +bool wlc_ps_check(struct wlc_info *wlc) +{ + bool res = true; + bool hps, wake; + bool wake_ok; + + if (!AP_ACTIVE(wlc)) { + volatile u32 tmp; + tmp = R_REG(wlc->osh, &wlc->regs->maccontrol); + + /* If deviceremoved is detected, then don't take any action as this can be called + * in any context. Assume that caller will take care of the condition. This is just + * to avoid assert + */ + if (tmp == 0xffffffff) { + WL_ERROR("wl%d: %s: dead chip\n", + wlc->pub->unit, __func__); + return DEVICEREMOVED(wlc); + } + + hps = PS_ALLOWED(wlc); + + if (hps != ((tmp & MCTL_HPS) != 0)) { + int idx; + wlc_bsscfg_t *cfg; + WL_ERROR("wl%d: hps not sync, sw %d, maccontrol 0x%x\n", + wlc->pub->unit, hps, tmp); + FOREACH_BSS(wlc, idx, cfg) { + if (!BSSCFG_STA(cfg)) + continue; + } + + res = false; + } + /* For a monolithic build the wake check can be exact since it looks at wake + * override bits. The MCTL_WAKE bit should match the 'wake' value. + */ + wake = STAY_AWAKE(wlc) || wlc->hw->wake_override; + wake_ok = (wake == ((tmp & MCTL_WAKE) != 0)); + if (hps && !wake_ok) { + WL_ERROR("wl%d: wake not sync, sw %d maccontrol 0x%x\n", + wlc->pub->unit, wake, tmp); + res = false; + } + } + ASSERT(res); + return res; +} + +/* push sw hps and wake state through hardware */ +void wlc_set_ps_ctrl(struct wlc_info *wlc) +{ + u32 v1, v2; + bool hps, wake; + bool awake_before; + + hps = PS_ALLOWED(wlc); + wake = hps ? (STAY_AWAKE(wlc)) : true; + + WL_TRACE("wl%d: wlc_set_ps_ctrl: hps %d wake %d\n", + wlc->pub->unit, hps, wake); + + v1 = R_REG(wlc->osh, &wlc->regs->maccontrol); + v2 = 0; + if (hps) + v2 |= MCTL_HPS; + if (wake) + v2 |= MCTL_WAKE; + + wlc_mctrl(wlc, MCTL_WAKE | MCTL_HPS, v2); + + awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0)); + + if (wake && !awake_before) + wlc_bmac_wait_for_wake(wlc->hw); + +} + +/* + * Write this BSS config's MAC address to core. + * Updates RXE match engine. + */ +int wlc_set_mac(wlc_bsscfg_t *cfg) +{ + int err = 0; + struct wlc_info *wlc = cfg->wlc; + + if (cfg == wlc->cfg) { + /* enter the MAC addr into the RXE match registers */ + wlc_set_addrmatch(wlc, RCM_MAC_OFFSET, cfg->cur_etheraddr); + } + + wlc_ampdu_macaddr_upd(wlc); + + return err; +} + +/* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl). + * Updates RXE match engine. + */ +void wlc_set_bssid(wlc_bsscfg_t *cfg) +{ + struct wlc_info *wlc = cfg->wlc; + + /* if primary config, we need to update BSSID in RXE match registers */ + if (cfg == wlc->cfg) { + wlc_set_addrmatch(wlc, RCM_BSSID_OFFSET, cfg->BSSID); + } +#ifdef SUPPORT_HWKEYS + else if (BSSCFG_STA(cfg) && cfg->BSS) { + wlc_rcmta_add_bssid(wlc, cfg); + } +#endif +} + +/* + * Suspend the the MAC and update the slot timing + * for standard 11b/g (20us slots) or shortslot 11g (9us slots). + */ +void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot) +{ + int idx; + wlc_bsscfg_t *cfg; + + ASSERT(wlc->band->gmode); + + /* use the override if it is set */ + if (wlc->shortslot_override != WLC_SHORTSLOT_AUTO) + shortslot = (wlc->shortslot_override == WLC_SHORTSLOT_ON); + + if (wlc->shortslot == shortslot) + return; + + wlc->shortslot = shortslot; + + /* update the capability based on current shortslot mode */ + FOREACH_BSS(wlc, idx, cfg) { + if (!cfg->associated) + continue; + cfg->current_bss->capability &= + ~WLAN_CAPABILITY_SHORT_SLOT_TIME; + if (wlc->shortslot) + cfg->current_bss->capability |= + WLAN_CAPABILITY_SHORT_SLOT_TIME; + } + + wlc_bmac_set_shortslot(wlc->hw, shortslot); +} + +static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc) +{ + u8 local; + s16 local_max; + + local = WLC_TXPWR_MAX; + if (wlc->pub->associated && + (wf_chspec_ctlchan(wlc->chanspec) == + wf_chspec_ctlchan(wlc->home_chanspec))) { + + /* get the local power constraint if we are on the AP's + * channel [802.11h, 7.3.2.13] + */ + /* Clamp the value between 0 and WLC_TXPWR_MAX w/o overflowing the target */ + local_max = + (wlc->txpwr_local_max - + wlc->txpwr_local_constraint) * WLC_TXPWR_DB_FACTOR; + if (local_max > 0 && local_max < WLC_TXPWR_MAX) + return (u8) local_max; + if (local_max < 0) + return 0; + } + + return local; +} + +/* propagate home chanspec to all bsscfgs in case bsscfg->current_bss->chanspec is referenced */ +void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec) +{ + if (wlc->home_chanspec != chanspec) { + int idx; + wlc_bsscfg_t *cfg; + + wlc->home_chanspec = chanspec; + + FOREACH_BSS(wlc, idx, cfg) { + if (!cfg->associated) + continue; + cfg->target_bss->chanspec = chanspec; + cfg->current_bss->chanspec = chanspec; + } + + } +} + +static void wlc_set_phy_chanspec(struct wlc_info *wlc, chanspec_t chanspec) +{ + /* Save our copy of the chanspec */ + wlc->chanspec = chanspec; + + /* Set the chanspec and power limits for this locale after computing + * any 11h local tx power constraints. + */ + wlc_channel_set_chanspec(wlc->cmi, chanspec, + wlc_local_constraint_qdbm(wlc)); + + if (wlc->stf->ss_algosel_auto) + wlc_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel, + chanspec); + + wlc_stf_ss_update(wlc, wlc->band); + +} + +void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec) +{ + uint bandunit; + bool switchband = false; + chanspec_t old_chanspec = wlc->chanspec; + + if (!wlc_valid_chanspec_db(wlc->cmi, chanspec)) { + WL_ERROR("wl%d: %s: Bad channel %d\n", + wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); + ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec)); + return; + } + + /* Switch bands if necessary */ + if (NBANDS(wlc) > 1) { + bandunit = CHSPEC_WLCBANDUNIT(chanspec); + if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) { + switchband = true; + if (wlc->bandlocked) { + WL_ERROR("wl%d: %s: chspec %d band is locked!\n", + wlc->pub->unit, __func__, + CHSPEC_CHANNEL(chanspec)); + return; + } + /* BMAC_NOTE: should the setband call come after the wlc_bmac_chanspec() ? + * if the setband updates (wlc_bsinit) use low level calls to inspect and + * set state, the state inspected may be from the wrong band, or the + * following wlc_bmac_set_chanspec() may undo the work. + */ + wlc_setband(wlc, bandunit); + } + } + + ASSERT(N_ENAB(wlc->pub) || !CHSPEC_IS40(chanspec)); + + /* sync up phy/radio chanspec */ + wlc_set_phy_chanspec(wlc, chanspec); + + /* init antenna selection */ + if (CHSPEC_WLC_BW(old_chanspec) != CHSPEC_WLC_BW(chanspec)) { + if (WLANTSEL_ENAB(wlc)) + wlc_antsel_init(wlc->asi); + + /* Fix the hardware rateset based on bw. + * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz + */ + wlc_rateset_bw_mcs_filter(&wlc->band->hw_rateset, + wlc->band-> + mimo_cap_40 ? CHSPEC_WLC_BW(chanspec) + : 0); + } + + /* update some mac configuration since chanspec changed */ + wlc_ucode_mac_upd(wlc); +} + +#if defined(BCMDBG) +static int wlc_get_current_txpwr(struct wlc_info *wlc, void *pwr, uint len) +{ + txpwr_limits_t txpwr; + tx_power_t power; + tx_power_legacy_t *old_power = NULL; + int r, c; + uint qdbm; + bool override; + + if (len == sizeof(tx_power_legacy_t)) + old_power = (tx_power_legacy_t *) pwr; + else if (len < sizeof(tx_power_t)) + return BCME_BUFTOOSHORT; + + memset(&power, 0, sizeof(tx_power_t)); + + power.chanspec = WLC_BAND_PI_RADIO_CHANSPEC; + if (wlc->pub->associated) + power.local_chanspec = wlc->home_chanspec; + + /* Return the user target tx power limits for the various rates. Note wlc_phy.c's + * public interface only implements getting and setting a single value for all of + * rates, so we need to fill the array ourselves. + */ + wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override); + for (r = 0; r < WL_TX_POWER_RATES; r++) { + power.user_limit[r] = (u8) qdbm; + } + + power.local_max = wlc->txpwr_local_max * WLC_TXPWR_DB_FACTOR; + power.local_constraint = + wlc->txpwr_local_constraint * WLC_TXPWR_DB_FACTOR; + + power.antgain[0] = wlc->bandstate[BAND_2G_INDEX]->antgain; + power.antgain[1] = wlc->bandstate[BAND_5G_INDEX]->antgain; + + wlc_channel_reg_limits(wlc->cmi, power.chanspec, &txpwr); + +#if WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK +#error "WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK" +#endif + + /* CCK tx power limits */ + for (c = 0, r = WL_TX_POWER_CCK_FIRST; c < WL_TX_POWER_CCK_NUM; + c++, r++) + power.reg_limit[r] = txpwr.cck[c]; + +#if WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM +#error "WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM" +#endif + + /* 20 MHz OFDM SISO tx power limits */ + for (c = 0, r = WL_TX_POWER_OFDM_FIRST; c < WL_TX_POWER_OFDM_NUM; + c++, r++) + power.reg_limit[r] = txpwr.ofdm[c]; + + if (WLC_PHY_11N_CAP(wlc->band)) { + + /* 20 MHz OFDM CDD tx power limits */ + for (c = 0, r = WL_TX_POWER_OFDM20_CDD_FIRST; + c < WL_TX_POWER_OFDM_NUM; c++, r++) + power.reg_limit[r] = txpwr.ofdm_cdd[c]; + + /* 40 MHz OFDM SISO tx power limits */ + for (c = 0, r = WL_TX_POWER_OFDM40_SISO_FIRST; + c < WL_TX_POWER_OFDM_NUM; c++, r++) + power.reg_limit[r] = txpwr.ofdm_40_siso[c]; + + /* 40 MHz OFDM CDD tx power limits */ + for (c = 0, r = WL_TX_POWER_OFDM40_CDD_FIRST; + c < WL_TX_POWER_OFDM_NUM; c++, r++) + power.reg_limit[r] = txpwr.ofdm_40_cdd[c]; + +#if WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM +#error "WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM" +#endif + + /* 20MHz MCS0-7 SISO tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS20_SISO_FIRST; + c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_20_siso[c]; + + /* 20MHz MCS0-7 CDD tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS20_CDD_FIRST; + c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_20_cdd[c]; + + /* 20MHz MCS0-7 STBC tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS20_STBC_FIRST; + c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_20_stbc[c]; + + /* 40MHz MCS0-7 SISO tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS40_SISO_FIRST; + c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_40_siso[c]; + + /* 40MHz MCS0-7 CDD tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS40_CDD_FIRST; + c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_40_cdd[c]; + + /* 40MHz MCS0-7 STBC tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS40_STBC_FIRST; + c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_40_stbc[c]; + +#if WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM +#error "WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM" +#endif + + /* 20MHz MCS8-15 SDM tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS20_SDM_FIRST; + c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_20_mimo[c]; + + /* 40MHz MCS8-15 SDM tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS40_SDM_FIRST; + c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_40_mimo[c]; + + /* MCS 32 */ + power.reg_limit[WL_TX_POWER_MCS_32] = txpwr.mcs32; + } + + wlc_phy_txpower_get_current(wlc->band->pi, &power, + CHSPEC_CHANNEL(power.chanspec)); + + /* copy the tx_power_t struct to the return buffer, + * or convert to a tx_power_legacy_t struct + */ + if (!old_power) { + bcopy(&power, pwr, sizeof(tx_power_t)); + } else { + int band_idx = CHSPEC_IS2G(power.chanspec) ? 0 : 1; + + memset(old_power, 0, sizeof(tx_power_legacy_t)); + + old_power->txpwr_local_max = power.local_max; + old_power->txpwr_local_constraint = power.local_constraint; + if (CHSPEC_IS2G(power.chanspec)) { + old_power->txpwr_chan_reg_max = txpwr.cck[0]; + old_power->txpwr_est_Pout[band_idx] = + power.est_Pout_cck; + old_power->txpwr_est_Pout_gofdm = power.est_Pout[0]; + } else { + old_power->txpwr_chan_reg_max = txpwr.ofdm[0]; + old_power->txpwr_est_Pout[band_idx] = power.est_Pout[0]; + } + old_power->txpwr_antgain[0] = power.antgain[0]; + old_power->txpwr_antgain[1] = power.antgain[1]; + + for (r = 0; r < NUM_PWRCTRL_RATES; r++) { + old_power->txpwr_band_max[r] = power.user_limit[r]; + old_power->txpwr_limit[r] = power.reg_limit[r]; + old_power->txpwr_target[band_idx][r] = power.target[r]; + if (CHSPEC_IS2G(power.chanspec)) + old_power->txpwr_bphy_cck_max[r] = + power.board_limit[r]; + else + old_power->txpwr_aphy_max[r] = + power.board_limit[r]; + } + } + + return 0; +} +#endif /* defined(BCMDBG) */ + +static u32 wlc_watchdog_backup_bi(struct wlc_info *wlc) +{ + u32 bi; + bi = 2 * wlc->cfg->current_bss->dtim_period * + wlc->cfg->current_bss->beacon_period; + if (wlc->bcn_li_dtim) + bi *= wlc->bcn_li_dtim; + else if (wlc->bcn_li_bcn) + /* recalculate bi based on bcn_li_bcn */ + bi = 2 * wlc->bcn_li_bcn * wlc->cfg->current_bss->beacon_period; + + if (bi < 2 * TIMER_INTERVAL_WATCHDOG) + bi = 2 * TIMER_INTERVAL_WATCHDOG; + return bi; +} + +/* Change to run the watchdog either from a periodic timer or from tbtt handler. + * Call watchdog from tbtt handler if tbtt is true, watchdog timer otherwise. + */ +void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt) +{ + /* make sure changing watchdog driver is allowed */ + if (!wlc->pub->up || !wlc->pub->align_wd_tbtt) + return; + if (!tbtt && wlc->WDarmed) { + wl_del_timer(wlc->wl, wlc->wdtimer); + wlc->WDarmed = false; + } + + /* stop watchdog timer and use tbtt interrupt to drive watchdog */ + if (tbtt && wlc->WDarmed) { + wl_del_timer(wlc->wl, wlc->wdtimer); + wlc->WDarmed = false; + wlc->WDlast = OSL_SYSUPTIME(); + } + /* arm watchdog timer and drive the watchdog there */ + else if (!tbtt && !wlc->WDarmed) { + wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, + true); + wlc->WDarmed = true; + } + if (tbtt && !wlc->WDarmed) { + wl_add_timer(wlc->wl, wlc->wdtimer, wlc_watchdog_backup_bi(wlc), + true); + wlc->WDarmed = true; + } +} + +ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, wlc_rateset_t *rs) +{ + ratespec_t lowest_basic_rspec; + uint i; + + /* Use the lowest basic rate */ + lowest_basic_rspec = rs->rates[0] & RATE_MASK; + for (i = 0; i < rs->count; i++) { + if (rs->rates[i] & WLC_RATE_FLAG) { + lowest_basic_rspec = rs->rates[i] & RATE_MASK; + break; + } + } +#if NCONF + /* pick siso/cdd as default for OFDM (note no basic rate MCSs are supported yet) */ + if (IS_OFDM(lowest_basic_rspec)) { + lowest_basic_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT); + } +#endif + + return lowest_basic_rspec; +} + +/* This function changes the phytxctl for beacon based on current beacon ratespec AND txant + * setting as per this table: + * ratespec CCK ant = wlc->stf->txant + * OFDM ant = 3 + */ +void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, ratespec_t bcn_rspec) +{ + u16 phyctl; + u16 phytxant = wlc->stf->phytxant; + u16 mask = PHY_TXC_ANT_MASK; + + /* for non-siso rates or default setting, use the available chains */ + if (WLC_PHY_11N_CAP(wlc->band)) { + phytxant = wlc_stf_phytxchain_sel(wlc, bcn_rspec); + } + + phyctl = wlc_read_shm(wlc, M_BCN_PCTLWD); + phyctl = (phyctl & ~mask) | phytxant; + wlc_write_shm(wlc, M_BCN_PCTLWD, phyctl); +} + +/* centralized protection config change function to simplify debugging, no consistency checking + * this should be called only on changes to avoid overhead in periodic function +*/ +void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val) +{ + WL_TRACE("wlc_protection_upd: idx %d, val %d\n", idx, val); + + switch (idx) { + case WLC_PROT_G_SPEC: + wlc->protection->_g = (bool) val; + break; + case WLC_PROT_G_OVR: + wlc->protection->g_override = (s8) val; + break; + case WLC_PROT_G_USER: + wlc->protection->gmode_user = (u8) val; + break; + case WLC_PROT_OVERLAP: + wlc->protection->overlap = (s8) val; + break; + case WLC_PROT_N_USER: + wlc->protection->nmode_user = (s8) val; + break; + case WLC_PROT_N_CFG: + wlc->protection->n_cfg = (s8) val; + break; + case WLC_PROT_N_CFG_OVR: + wlc->protection->n_cfg_override = (s8) val; + break; + case WLC_PROT_N_NONGF: + wlc->protection->nongf = (bool) val; + break; + case WLC_PROT_N_NONGF_OVR: + wlc->protection->nongf_override = (s8) val; + break; + case WLC_PROT_N_PAM_OVR: + wlc->protection->n_pam_override = (s8) val; + break; + case WLC_PROT_N_OBSS: + wlc->protection->n_obss = (bool) val; + break; + + default: + ASSERT(0); + break; + } + +} + +static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val) +{ + wlc->ht_cap.cap_info &= ~(IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_SGI_40); + wlc->ht_cap.cap_info |= (val & WLC_N_SGI_20) ? + IEEE80211_HT_CAP_SGI_20 : 0; + wlc->ht_cap.cap_info |= (val & WLC_N_SGI_40) ? + IEEE80211_HT_CAP_SGI_40 : 0; + + if (wlc->pub->up) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, true); + } +} + +static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val) +{ + wlc->stf->ldpc = val; + + wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_LDPC_CODING; + if (wlc->stf->ldpc != OFF) + wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_LDPC_CODING; + + if (wlc->pub->up) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, true); + wlc_phy_ldpc_override_set(wlc->band->pi, (val ? true : false)); + } +} + +/* + * ucode, hwmac update + * Channel dependent updates for ucode and hw + */ +static void wlc_ucode_mac_upd(struct wlc_info *wlc) +{ + /* enable or disable any active IBSSs depending on whether or not + * we are on the home channel + */ + if (wlc->home_chanspec == WLC_BAND_PI_RADIO_CHANSPEC) { + if (wlc->pub->associated) { + /* BMAC_NOTE: This is something that should be fixed in ucode inits. + * I think that the ucode inits set up the bcn templates and shm values + * with a bogus beacon. This should not be done in the inits. If ucode needs + * to set up a beacon for testing, the test routines should write it down, + * not expect the inits to populate a bogus beacon. + */ + if (WLC_PHY_11N_CAP(wlc->band)) { + wlc_write_shm(wlc, M_BCN_TXTSF_OFFSET, + wlc->band->bcntsfoff); + } + } + } else { + /* disable an active IBSS if we are not on the home channel */ + } + + /* update the various promisc bits */ + wlc_mac_bcn_promisc(wlc); + wlc_mac_promisc(wlc); +} + +static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec) +{ + wlc_rateset_t default_rateset; + uint parkband; + uint i, band_order[2]; + + WL_TRACE("wl%d: wlc_bandinit_ordered\n", wlc->pub->unit); + /* + * We might have been bandlocked during down and the chip power-cycled (hibernate). + * figure out the right band to park on + */ + if (wlc->bandlocked || NBANDS(wlc) == 1) { + ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit); + + parkband = wlc->band->bandunit; /* updated in wlc_bandlock() */ + band_order[0] = band_order[1] = parkband; + } else { + /* park on the band of the specified chanspec */ + parkband = CHSPEC_WLCBANDUNIT(chanspec); + + /* order so that parkband initialize last */ + band_order[0] = parkband ^ 1; + band_order[1] = parkband; + } + + /* make each band operational, software state init */ + for (i = 0; i < NBANDS(wlc); i++) { + uint j = band_order[i]; + + wlc->band = wlc->bandstate[j]; + + wlc_default_rateset(wlc, &default_rateset); + + /* fill in hw_rate */ + wlc_rateset_filter(&default_rateset, &wlc->band->hw_rateset, + false, WLC_RATES_CCK_OFDM, RATE_MASK, + (bool) N_ENAB(wlc->pub)); + + /* init basic rate lookup */ + wlc_rate_lookup_init(wlc, &default_rateset); + } + + /* sync up phy/radio chanspec */ + wlc_set_phy_chanspec(wlc, chanspec); +} + +/* band-specific init */ +static void WLBANDINITFN(wlc_bsinit) (struct wlc_info *wlc) +{ + WL_TRACE("wl%d: wlc_bsinit: bandunit %d\n", + wlc->pub->unit, wlc->band->bandunit); + + /* write ucode ACK/CTS rate table */ + wlc_set_ratetable(wlc); + + /* update some band specific mac configuration */ + wlc_ucode_mac_upd(wlc); + + /* init antenna selection */ + if (WLANTSEL_ENAB(wlc)) + wlc_antsel_init(wlc->asi); + +} + +/* switch to and initialize new band */ +static void WLBANDINITFN(wlc_setband) (struct wlc_info *wlc, uint bandunit) +{ + int idx; + wlc_bsscfg_t *cfg; + + ASSERT(NBANDS(wlc) > 1); + ASSERT(!wlc->bandlocked); + ASSERT(bandunit != wlc->band->bandunit || wlc->bandinit_pending); + + wlc->band = wlc->bandstate[bandunit]; + + if (!wlc->pub->up) + return; + + /* wait for at least one beacon before entering sleeping state */ + wlc->PMawakebcn = true; + FOREACH_AS_STA(wlc, idx, cfg) + cfg->PMawakebcn = true; + wlc_set_ps_ctrl(wlc); + + /* band-specific initializations */ + wlc_bsinit(wlc); +} + +/* Initialize a WME Parameter Info Element with default STA parameters from WMM Spec, Table 12 */ +void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe) +{ + static const wme_param_ie_t stadef = { + WME_OUI, + WME_TYPE, + WME_SUBTYPE_PARAM_IE, + WME_VER, + 0, + 0, + { + {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA, + HTOL16(EDCF_AC_BE_TXOP_STA)}, + {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA, + HTOL16(EDCF_AC_BK_TXOP_STA)}, + {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA, + HTOL16(EDCF_AC_VI_TXOP_STA)}, + {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA, + HTOL16(EDCF_AC_VO_TXOP_STA)} + } + }; + + ASSERT(sizeof(*pe) == WME_PARAM_IE_LEN); + memcpy(pe, &stadef, sizeof(*pe)); +} + +void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend) +{ + int i; + shm_acparams_t acp_shm; + u16 *shm_entry; + struct ieee80211_tx_queue_params *params = arg; + + ASSERT(wlc); + + /* Only apply params if the core is out of reset and has clocks */ + if (!wlc->clk) { + WL_ERROR("wl%d: %s : no-clock\n", wlc->pub->unit, __func__); + return; + } + + /* + * AP uses AC params from wme_param_ie_ap. + * AP advertises AC params from wme_param_ie. + * STA uses AC params from wme_param_ie. + */ + + wlc->wme_admctl = 0; + + do { + memset((char *)&acp_shm, 0, sizeof(shm_acparams_t)); + /* find out which ac this set of params applies to */ + ASSERT(aci < AC_COUNT); + /* set the admission control policy for this AC */ + /* wlc->wme_admctl |= 1 << aci; *//* should be set ?? seems like off by default */ + + /* fill in shm ac params struct */ + acp_shm.txop = ltoh16(params->txop); + /* convert from units of 32us to us for ucode */ + wlc->edcf_txop[aci & 0x3] = acp_shm.txop = + EDCF_TXOP2USEC(acp_shm.txop); + acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK); + + if (aci == AC_VI && acp_shm.txop == 0 + && acp_shm.aifs < EDCF_AIFSN_MAX) + acp_shm.aifs++; + + if (acp_shm.aifs < EDCF_AIFSN_MIN + || acp_shm.aifs > EDCF_AIFSN_MAX) { + WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n", + wlc->pub->unit, acp_shm.aifs); + continue; + } + + acp_shm.cwmin = params->cw_min; + acp_shm.cwmax = params->cw_max; + acp_shm.cwcur = acp_shm.cwmin; + acp_shm.bslots = + R_REG(wlc->osh, &wlc->regs->tsf_random) & acp_shm.cwcur; + acp_shm.reggap = acp_shm.bslots + acp_shm.aifs; + /* Indicate the new params to the ucode */ + acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO + + wme_shmemacindex(aci) * + M_EDCF_QLEN + + M_EDCF_STATUS_OFF)); + acp_shm.status |= WME_STATUS_NEWAC; + + /* Fill in shm acparam table */ + shm_entry = (u16 *) &acp_shm; + for (i = 0; i < (int)sizeof(shm_acparams_t); i += 2) + wlc_write_shm(wlc, + M_EDCF_QINFO + + wme_shmemacindex(aci) * M_EDCF_QLEN + i, + *shm_entry++); + + } while (0); + + if (suspend) + wlc_suspend_mac_and_wait(wlc); + + if (suspend) + wlc_enable_mac(wlc); + +} + +void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend) +{ + struct wlc_info *wlc = cfg->wlc; + uint aci, i, j; + edcf_acparam_t *edcf_acp; + shm_acparams_t acp_shm; + u16 *shm_entry; + + ASSERT(cfg); + ASSERT(wlc); + + /* Only apply params if the core is out of reset and has clocks */ + if (!wlc->clk) + return; + + /* + * AP uses AC params from wme_param_ie_ap. + * AP advertises AC params from wme_param_ie. + * STA uses AC params from wme_param_ie. + */ + + edcf_acp = (edcf_acparam_t *) &wlc->wme_param_ie.acparam[0]; + + wlc->wme_admctl = 0; + + for (i = 0; i < AC_COUNT; i++, edcf_acp++) { + memset((char *)&acp_shm, 0, sizeof(shm_acparams_t)); + /* find out which ac this set of params applies to */ + aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT; + ASSERT(aci < AC_COUNT); + /* set the admission control policy for this AC */ + if (edcf_acp->ACI & EDCF_ACM_MASK) { + wlc->wme_admctl |= 1 << aci; + } + + /* fill in shm ac params struct */ + acp_shm.txop = ltoh16(edcf_acp->TXOP); + /* convert from units of 32us to us for ucode */ + wlc->edcf_txop[aci] = acp_shm.txop = + EDCF_TXOP2USEC(acp_shm.txop); + acp_shm.aifs = (edcf_acp->ACI & EDCF_AIFSN_MASK); + + if (aci == AC_VI && acp_shm.txop == 0 + && acp_shm.aifs < EDCF_AIFSN_MAX) + acp_shm.aifs++; + + if (acp_shm.aifs < EDCF_AIFSN_MIN + || acp_shm.aifs > EDCF_AIFSN_MAX) { + WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n", + wlc->pub->unit, acp_shm.aifs); + continue; + } + + /* CWmin = 2^(ECWmin) - 1 */ + acp_shm.cwmin = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK); + /* CWmax = 2^(ECWmax) - 1 */ + acp_shm.cwmax = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK) + >> EDCF_ECWMAX_SHIFT); + acp_shm.cwcur = acp_shm.cwmin; + acp_shm.bslots = + R_REG(wlc->osh, &wlc->regs->tsf_random) & acp_shm.cwcur; + acp_shm.reggap = acp_shm.bslots + acp_shm.aifs; + /* Indicate the new params to the ucode */ + acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO + + wme_shmemacindex(aci) * + M_EDCF_QLEN + + M_EDCF_STATUS_OFF)); + acp_shm.status |= WME_STATUS_NEWAC; + + /* Fill in shm acparam table */ + shm_entry = (u16 *) &acp_shm; + for (j = 0; j < (int)sizeof(shm_acparams_t); j += 2) + wlc_write_shm(wlc, + M_EDCF_QINFO + + wme_shmemacindex(aci) * M_EDCF_QLEN + j, + *shm_entry++); + } + + if (suspend) + wlc_suspend_mac_and_wait(wlc); + + if (AP_ENAB(wlc->pub) && WME_ENAB(wlc->pub)) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, false); + } + + if (suspend) + wlc_enable_mac(wlc); + +} + +bool wlc_timers_init(struct wlc_info *wlc, int unit) +{ + wlc->wdtimer = wl_init_timer(wlc->wl, wlc_watchdog_by_timer, + wlc, "watchdog"); + if (!wlc->wdtimer) { + WL_ERROR("wl%d: wl_init_timer for wdtimer failed\n", unit); + goto fail; + } + + wlc->radio_timer = wl_init_timer(wlc->wl, wlc_radio_timer, + wlc, "radio"); + if (!wlc->radio_timer) { + WL_ERROR("wl%d: wl_init_timer for radio_timer failed\n", unit); + goto fail; + } + + return true; + + fail: + return false; +} + +/* + * Initialize wlc_info default values ... + * may get overrides later in this function + */ +void wlc_info_init(struct wlc_info *wlc, int unit) +{ + int i; + /* Assume the device is there until proven otherwise */ + wlc->device_present = true; + + /* set default power output percentage to 100 percent */ + wlc->txpwr_percent = 100; + + /* Save our copy of the chanspec */ + wlc->chanspec = CH20MHZ_CHSPEC(1); + + /* initialize CCK preamble mode to unassociated state */ + wlc->shortpreamble = false; + + wlc->legacy_probe = true; + + /* various 802.11g modes */ + wlc->shortslot = false; + wlc->shortslot_override = WLC_SHORTSLOT_AUTO; + + wlc->barker_overlap_control = true; + wlc->barker_preamble = WLC_BARKER_SHORT_ALLOWED; + wlc->txburst_limit_override = AUTO; + + wlc_protection_upd(wlc, WLC_PROT_G_OVR, WLC_PROTECTION_AUTO); + wlc_protection_upd(wlc, WLC_PROT_G_SPEC, false); + + wlc_protection_upd(wlc, WLC_PROT_N_CFG_OVR, WLC_PROTECTION_AUTO); + wlc_protection_upd(wlc, WLC_PROT_N_CFG, WLC_N_PROTECTION_OFF); + wlc_protection_upd(wlc, WLC_PROT_N_NONGF_OVR, WLC_PROTECTION_AUTO); + wlc_protection_upd(wlc, WLC_PROT_N_NONGF, false); + wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR, AUTO); + + wlc_protection_upd(wlc, WLC_PROT_OVERLAP, WLC_PROTECTION_CTL_OVERLAP); + + /* 802.11g draft 4.0 NonERP elt advertisement */ + wlc->include_legacy_erp = true; + + wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF; + wlc->stf->txant = ANT_TX_DEF; + + wlc->prb_resp_timeout = WLC_PRB_RESP_TIMEOUT; + + wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN; + for (i = 0; i < NFIFO; i++) + wlc->fragthresh[i] = DOT11_DEFAULT_FRAG_LEN; + wlc->RTSThresh = DOT11_DEFAULT_RTS_LEN; + + /* default rate fallback retry limits */ + wlc->SFBL = RETRY_SHORT_FB; + wlc->LFBL = RETRY_LONG_FB; + + /* default mac retry limits */ + wlc->SRL = RETRY_SHORT_DEF; + wlc->LRL = RETRY_LONG_DEF; + + /* init PM state */ + wlc->PM = PM_OFF; /* User's setting of PM mode through IOCTL */ + wlc->PM_override = false; /* Prevents from going to PM if our AP is 'ill' */ + wlc->PMenabled = false; /* Current PM state */ + wlc->PMpending = false; /* Tracks whether STA indicated PM in the last attempt */ + wlc->PMblocked = false; /* To allow blocking going into PM during RM and scans */ + + /* In WMM Auto mode, PM is allowed if association is a UAPSD association */ + wlc->WME_PM_blocked = false; + + /* Init wme queuing method */ + wlc->wme_prec_queuing = false; + + /* Overrides for the core to stay awake under zillion conditions Look for STAY_AWAKE */ + wlc->wake = false; + /* Are we waiting for a response to PS-Poll that we sent */ + wlc->PSpoll = false; + + /* APSD defaults */ + wlc->wme_apsd = true; + wlc->apsd_sta_usp = false; + wlc->apsd_trigger_timeout = 0; /* disable the trigger timer */ + wlc->apsd_trigger_ac = AC_BITMAP_ALL; + + /* Set flag to indicate that hw keys should be used when available. */ + wlc->wsec_swkeys = false; + + /* init the 4 static WEP default keys */ + for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) { + wlc->wsec_keys[i] = wlc->wsec_def_keys[i]; + wlc->wsec_keys[i]->idx = (u8) i; + } + + wlc->_regulatory_domain = false; /* 802.11d */ + + /* WME QoS mode is Auto by default */ + wlc->pub->_wme = AUTO; + +#ifdef BCMSDIODEV_ENABLED + wlc->pub->_priofc = true; /* enable priority flow control for sdio dongle */ +#endif + + wlc->pub->_ampdu = AMPDU_AGG_HOST; + wlc->pub->bcmerror = 0; + wlc->ibss_allowed = true; + wlc->ibss_coalesce_allowed = true; + wlc->pub->_coex = ON; + + /* intialize mpc delay */ + wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; + + wlc->pr80838_war = true; +} + +static bool wlc_state_bmac_sync(struct wlc_info *wlc) +{ + wlc_bmac_state_t state_bmac; + + if (wlc_bmac_state_get(wlc->hw, &state_bmac) != 0) + return false; + + wlc->machwcap = state_bmac.machwcap; + wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR, + (s8) state_bmac.preamble_ovr); + + return true; +} + +static uint wlc_attach_module(struct wlc_info *wlc) +{ + uint err = 0; + uint unit; + unit = wlc->pub->unit; + + wlc->asi = wlc_antsel_attach(wlc, wlc->osh, wlc->pub, wlc->hw); + if (wlc->asi == NULL) { + WL_ERROR("wl%d: wlc_attach: wlc_antsel_attach failed\n", unit); + err = 44; + goto fail; + } + + wlc->ampdu = wlc_ampdu_attach(wlc); + if (wlc->ampdu == NULL) { + WL_ERROR("wl%d: wlc_attach: wlc_ampdu_attach failed\n", unit); + err = 50; + goto fail; + } + + /* Initialize event queue; needed before following calls */ + wlc->eventq = + wlc_eventq_attach(wlc->pub, wlc, wlc->wl, wlc_process_eventq); + if (wlc->eventq == NULL) { + WL_ERROR("wl%d: wlc_attach: wlc_eventq_attachfailed\n", unit); + err = 57; + goto fail; + } + + if ((wlc_stf_attach(wlc) != 0)) { + WL_ERROR("wl%d: wlc_attach: wlc_stf_attach failed\n", unit); + err = 68; + goto fail; + } + fail: + return err; +} + +struct wlc_pub *wlc_pub(void *wlc) +{ + return ((struct wlc_info *) wlc)->pub; +} + +#define CHIP_SUPPORTS_11N(wlc) 1 + +/* + * The common driver entry routine. Error codes should be unique + */ +void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, + struct osl_info *osh, void *regsva, uint bustype, + void *btparam, uint *perr) +{ + struct wlc_info *wlc; + uint err = 0; + uint j; + struct wlc_pub *pub; + wlc_txq_info_t *qi; + uint n_disabled; + + WL_NONE("wl%d: %s: vendor 0x%x device 0x%x\n", + unit, __func__, vendor, device); + + ASSERT(WSEC_MAX_RCMTA_KEYS <= WSEC_MAX_KEYS); + ASSERT(WSEC_MAX_DEFAULT_KEYS == WLC_DEFAULT_KEYS); + + /* some code depends on packed structures */ + ASSERT(sizeof(struct ethhdr) == ETH_HLEN); + ASSERT(sizeof(d11regs_t) == SI_CORE_SIZE); + ASSERT(sizeof(ofdm_phy_hdr_t) == D11_PHY_HDR_LEN); + ASSERT(sizeof(cck_phy_hdr_t) == D11_PHY_HDR_LEN); + ASSERT(sizeof(d11txh_t) == D11_TXH_LEN); + ASSERT(sizeof(d11rxhdr_t) == RXHDR_LEN); + ASSERT(sizeof(struct ieee80211_hdr) == DOT11_A4_HDR_LEN); + ASSERT(sizeof(struct ieee80211_rts) == DOT11_RTS_LEN); + ASSERT(sizeof(tx_status_t) == TXSTATUS_LEN); + ASSERT(sizeof(struct ieee80211_ht_cap) == HT_CAP_IE_LEN); +#ifdef BRCM_FULLMAC + ASSERT(offsetof(wl_scan_params_t, channel_list) == + WL_SCAN_PARAMS_FIXED_SIZE); +#endif + ASSERT(IS_ALIGNED(offsetof(wsec_key_t, data), sizeof(u32))); + ASSERT(ISPOWEROF2(MA_WINDOW_SZ)); + + ASSERT(sizeof(wlc_d11rxhdr_t) <= WL_HWRXOFF); + + /* + * Number of replay counters value used in WPA IE must match # rxivs + * supported in wsec_key_t struct. See 802.11i/D3.0 sect. 7.3.2.17 + * 'RSN Information Element' figure 8 for this mapping. + */ + ASSERT((WPA_CAP_16_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE + && 16 == WLC_NUMRXIVS) + || (WPA_CAP_4_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE + && 4 == WLC_NUMRXIVS)); + + /* allocate struct wlc_info state and its substructures */ + wlc = (struct wlc_info *) wlc_attach_malloc(osh, unit, &err, device); + if (wlc == NULL) + goto fail; + wlc->osh = osh; + pub = wlc->pub; + +#if defined(BCMDBG) + wlc_info_dbg = wlc; +#endif + + wlc->band = wlc->bandstate[0]; + wlc->core = wlc->corestate; + wlc->wl = wl; + pub->unit = unit; + pub->osh = osh; + wlc->btparam = btparam; + pub->_piomode = piomode; + wlc->bandinit_pending = false; + /* By default restrict TKIP associations from 11n STA's */ + wlc->ht_wsec_restriction = WLC_HT_TKIP_RESTRICT; + + /* populate struct wlc_info with default values */ + wlc_info_init(wlc, unit); + + /* update sta/ap related parameters */ + wlc_ap_upd(wlc); + + /* 11n_disable nvram */ + n_disabled = getintvar(pub->vars, "11n_disable"); + + /* register a module (to handle iovars) */ + wlc_module_register(wlc->pub, wlc_iovars, "wlc_iovars", wlc, + wlc_doiovar, NULL, NULL); + + /* low level attach steps(all hw accesses go inside, no more in rest of the attach) */ + err = wlc_bmac_attach(wlc, vendor, device, unit, piomode, osh, regsva, + bustype, btparam); + if (err) + goto fail; + + /* for some states, due to different info pointer(e,g, wlc, wlc_hw) or master/slave split, + * HIGH driver(both monolithic and HIGH_ONLY) needs to sync states FROM BMAC portion driver + */ + if (!wlc_state_bmac_sync(wlc)) { + err = 20; + goto fail; + } + + pub->phy_11ncapable = WLC_PHY_11N_CAP(wlc->band); + + /* propagate *vars* from BMAC driver to high driver */ + wlc_bmac_copyfrom_vars(wlc->hw, &pub->vars, &wlc->vars_size); + + + /* set maximum allowed duty cycle */ + wlc->tx_duty_cycle_ofdm = + (u16) getintvar(pub->vars, "tx_duty_cycle_ofdm"); + wlc->tx_duty_cycle_cck = + (u16) getintvar(pub->vars, "tx_duty_cycle_cck"); + + wlc_stf_phy_chain_calc(wlc); + + /* txchain 1: txant 0, txchain 2: txant 1 */ + if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1)) + wlc->stf->txant = wlc->stf->hw_txchain - 1; + + /* push to BMAC driver */ + wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain, + wlc->stf->hw_rxchain); + + /* pull up some info resulting from the low attach */ + { + int i; + for (i = 0; i < NFIFO; i++) + wlc->core->txavail[i] = wlc->hw->txavail[i]; + } + + wlc_bmac_hw_etheraddr(wlc->hw, wlc->perm_etheraddr); + + bcopy((char *)&wlc->perm_etheraddr, (char *)&pub->cur_etheraddr, + ETH_ALEN); + + for (j = 0; j < NBANDS(wlc); j++) { + /* Use band 1 for single band 11a */ + if (IS_SINGLEBAND_5G(wlc->deviceid)) + j = BAND_5G_INDEX; + + wlc->band = wlc->bandstate[j]; + + if (!wlc_attach_stf_ant_init(wlc)) { + err = 24; + goto fail; + } + + /* default contention windows size limits */ + wlc->band->CWmin = APHY_CWMIN; + wlc->band->CWmax = PHY_CWMAX; + + /* init gmode value */ + if (BAND_2G(wlc->band->bandtype)) { + wlc->band->gmode = GMODE_AUTO; + wlc_protection_upd(wlc, WLC_PROT_G_USER, + wlc->band->gmode); + } + + /* init _n_enab supported mode */ + if (WLC_PHY_11N_CAP(wlc->band) && CHIP_SUPPORTS_11N(wlc)) { + if (n_disabled & WLFEATURE_DISABLE_11N) { + pub->_n_enab = OFF; + wlc_protection_upd(wlc, WLC_PROT_N_USER, OFF); + } else { + pub->_n_enab = SUPPORT_11N; + wlc_protection_upd(wlc, WLC_PROT_N_USER, + ((pub->_n_enab == + SUPPORT_11N) ? WL_11N_2x2 : + WL_11N_3x3)); + } + } + + /* init per-band default rateset, depend on band->gmode */ + wlc_default_rateset(wlc, &wlc->band->defrateset); + + /* fill in hw_rateset (used early by WLC_SET_RATESET) */ + wlc_rateset_filter(&wlc->band->defrateset, + &wlc->band->hw_rateset, false, + WLC_RATES_CCK_OFDM, RATE_MASK, + (bool) N_ENAB(wlc->pub)); + } + + /* update antenna config due to wlc->stf->txant/txchain/ant_rx_ovr change */ + wlc_stf_phy_txant_upd(wlc); + + /* attach each modules */ + err = wlc_attach_module(wlc); + if (err != 0) + goto fail; + + if (!wlc_timers_init(wlc, unit)) { + WL_ERROR("wl%d: %s: wlc_init_timer failed\n", unit, __func__); + err = 32; + goto fail; + } + + /* depend on rateset, gmode */ + wlc->cmi = wlc_channel_mgr_attach(wlc); + if (!wlc->cmi) { + WL_ERROR("wl%d: %s: wlc_channel_mgr_attach failed\n", + unit, __func__); + err = 33; + goto fail; + } + + /* init default when all parameters are ready, i.e. ->rateset */ + wlc_bss_default_init(wlc); + + /* + * Complete the wlc default state initializations.. + */ + + /* allocate our initial queue */ + qi = wlc_txq_alloc(wlc, osh); + if (qi == NULL) { + WL_ERROR("wl%d: %s: failed to malloc tx queue\n", + unit, __func__); + err = 100; + goto fail; + } + wlc->active_queue = qi; + + wlc->bsscfg[0] = wlc->cfg; + wlc->cfg->_idx = 0; + wlc->cfg->wlc = wlc; + pub->txmaxpkts = MAXTXPKTS; + + WLCNTSET(pub->_cnt->version, WL_CNT_T_VERSION); + WLCNTSET(pub->_cnt->length, sizeof(wl_cnt_t)); + + WLCNTSET(pub->_wme_cnt->version, WL_WME_CNT_VERSION); + WLCNTSET(pub->_wme_cnt->length, sizeof(wl_wme_cnt_t)); + + wlc_wme_initparams_sta(wlc, &wlc->wme_param_ie); + + wlc->mimoft = FT_HT; + wlc->ht_cap.cap_info = HT_CAP; + if (HT_ENAB(wlc->pub)) + wlc->stf->ldpc = AUTO; + + wlc->mimo_40txbw = AUTO; + wlc->ofdm_40txbw = AUTO; + wlc->cck_40txbw = AUTO; + wlc_update_mimo_band_bwcap(wlc, WLC_N_BW_20IN2G_40IN5G); + + /* Enable setting the RIFS Mode bit by default in HT Info IE */ + wlc->rifs_advert = AUTO; + + /* Set default values of SGI */ + if (WLC_SGI_CAP_PHY(wlc)) { + wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40)); + wlc->sgi_tx = AUTO; + } else if (WLCISSSLPNPHY(wlc->band)) { + wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40)); + wlc->sgi_tx = AUTO; + } else { + wlc_ht_update_sgi_rx(wlc, 0); + wlc->sgi_tx = OFF; + } + + /* *******nvram 11n config overrides Start ********* */ + + /* apply the sgi override from nvram conf */ + if (n_disabled & WLFEATURE_DISABLE_11N_SGI_TX) + wlc->sgi_tx = OFF; + + if (n_disabled & WLFEATURE_DISABLE_11N_SGI_RX) + wlc_ht_update_sgi_rx(wlc, 0); + + /* apply the stbc override from nvram conf */ + if (n_disabled & WLFEATURE_DISABLE_11N_STBC_TX) { + wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF; + wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF; + wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC; + } + if (n_disabled & WLFEATURE_DISABLE_11N_STBC_RX) + wlc_stf_stbc_rx_set(wlc, HT_CAP_RX_STBC_NO); + + /* apply the GF override from nvram conf */ + if (n_disabled & WLFEATURE_DISABLE_11N_GF) + wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_GRN_FLD; + + /* initialize radio_mpc_disable according to wlc->mpc */ + wlc_radio_mpc_upd(wlc); + + if (WLANTSEL_ENAB(wlc)) { + if ((wlc->pub->sih->chip) == BCM43235_CHIP_ID) { + if ((getintvar(wlc->pub->vars, "aa2g") == 7) || + (getintvar(wlc->pub->vars, "aa5g") == 7)) { + wlc_bmac_antsel_set(wlc->hw, 1); + } + } else { + wlc_bmac_antsel_set(wlc->hw, wlc->asi->antsel_avail); + } + } + + if (perr) + *perr = 0; + + return (void *)wlc; + + fail: + WL_ERROR("wl%d: %s: failed with err %d\n", unit, __func__, err); + if (wlc) + wlc_detach(wlc); + + if (perr) + *perr = err; + return NULL; +} + +static void wlc_attach_antgain_init(struct wlc_info *wlc) +{ + uint unit; + unit = wlc->pub->unit; + + if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) { + /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */ + wlc->band->antgain = 8; + } else if (wlc->band->antgain == -1) { + WL_ERROR("wl%d: %s: Invalid antennas available in srom, using 2dB\n", + unit, __func__); + wlc->band->antgain = 8; + } else { + s8 gain, fract; + /* Older sroms specified gain in whole dbm only. In order + * be able to specify qdbm granularity and remain backward compatible + * the whole dbms are now encoded in only low 6 bits and remaining qdbms + * are encoded in the hi 2 bits. 6 bit signed number ranges from + * -32 - 31. Examples: 0x1 = 1 db, + * 0xc1 = 1.75 db (1 + 3 quarters), + * 0x3f = -1 (-1 + 0 quarters), + * 0x7f = -.75 (-1 in low 6 bits + 1 quarters in hi 2 bits) = -3 qdbm. + * 0xbf = -.50 (-1 in low 6 bits + 2 quarters in hi 2 bits) = -2 qdbm. + */ + gain = wlc->band->antgain & 0x3f; + gain <<= 2; /* Sign extend */ + gain >>= 2; + fract = (wlc->band->antgain & 0xc0) >> 6; + wlc->band->antgain = 4 * gain + fract; + } +} + +static bool wlc_attach_stf_ant_init(struct wlc_info *wlc) +{ + int aa; + uint unit; + char *vars; + int bandtype; + + unit = wlc->pub->unit; + vars = wlc->pub->vars; + bandtype = wlc->band->bandtype; + + /* get antennas available */ + aa = (s8) getintvar(vars, (BAND_5G(bandtype) ? "aa5g" : "aa2g")); + if (aa == 0) + aa = (s8) getintvar(vars, + (BAND_5G(bandtype) ? "aa1" : "aa0")); + if ((aa < 1) || (aa > 15)) { + WL_ERROR("wl%d: %s: Invalid antennas available in srom (0x%x), using 3\n", + unit, __func__, aa); + aa = 3; + } + + /* reset the defaults if we have a single antenna */ + if (aa == 1) { + wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_0; + wlc->stf->txant = ANT_TX_FORCE_0; + } else if (aa == 2) { + wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_1; + wlc->stf->txant = ANT_TX_FORCE_1; + } else { + } + + /* Compute Antenna Gain */ + wlc->band->antgain = + (s8) getintvar(vars, (BAND_5G(bandtype) ? "ag1" : "ag0")); + wlc_attach_antgain_init(wlc); + + return true; +} + + +static void wlc_timers_deinit(struct wlc_info *wlc) +{ + /* free timer state */ + if (wlc->wdtimer) { + wl_free_timer(wlc->wl, wlc->wdtimer); + wlc->wdtimer = NULL; + } + if (wlc->radio_timer) { + wl_free_timer(wlc->wl, wlc->radio_timer); + wlc->radio_timer = NULL; + } +} + +static void wlc_detach_module(struct wlc_info *wlc) +{ + if (wlc->asi) { + wlc_antsel_detach(wlc->asi); + wlc->asi = NULL; + } + + if (wlc->ampdu) { + wlc_ampdu_detach(wlc->ampdu); + wlc->ampdu = NULL; + } + + wlc_stf_detach(wlc); +} + +/* + * Return a count of the number of driver callbacks still pending. + * + * General policy is that wlc_detach can only dealloc/free software states. It can NOT + * touch hardware registers since the d11core may be in reset and clock may not be available. + * One exception is sb register access, which is possible if crystal is turned on + * After "down" state, driver should avoid software timer with the exception of radio_monitor. + */ +uint wlc_detach(struct wlc_info *wlc) +{ + uint i; + uint callbacks = 0; + + if (wlc == NULL) + return 0; + + WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__); + + ASSERT(!wlc->pub->up); + + callbacks += wlc_bmac_detach(wlc); + + /* delete software timers */ + if (!wlc_radio_monitor_stop(wlc)) + callbacks++; + + if (wlc->eventq) { + wlc_eventq_detach(wlc->eventq); + wlc->eventq = NULL; + } + + wlc_channel_mgr_detach(wlc->cmi); + + wlc_timers_deinit(wlc); + + wlc_detach_module(wlc); + + /* free other state */ + + +#ifdef BCMDBG + if (wlc->country_ie_override) { + kfree(wlc->country_ie_override); + wlc->country_ie_override = NULL; + } +#endif /* BCMDBG */ + + { + /* free dumpcb list */ + dumpcb_t *prev, *ptr; + prev = ptr = wlc->dumpcb_head; + while (ptr) { + ptr = prev->next; + kfree(prev); + prev = ptr; + } + wlc->dumpcb_head = NULL; + } + + /* Detach from iovar manager */ + wlc_module_unregister(wlc->pub, "wlc_iovars", wlc); + + while (wlc->tx_queues != NULL) { + wlc_txq_free(wlc, wlc->osh, wlc->tx_queues); + } + + /* + * consistency check: wlc_module_register/wlc_module_unregister calls + * should match therefore nothing should be left here. + */ + for (i = 0; i < WLC_MAXMODULES; i++) + ASSERT(wlc->modulecb[i].name[0] == '\0'); + + wlc_detach_mfree(wlc, wlc->osh); + return callbacks; +} + +/* update state that depends on the current value of "ap" */ +void wlc_ap_upd(struct wlc_info *wlc) +{ + if (AP_ENAB(wlc->pub)) + wlc->PLCPHdr_override = WLC_PLCP_AUTO; /* AP: short not allowed, but not enforced */ + else + wlc->PLCPHdr_override = WLC_PLCP_SHORT; /* STA-BSS; short capable */ + + /* disable vlan_mode on AP since some legacy STAs cannot rx tagged pkts */ + wlc->vlan_mode = AP_ENAB(wlc->pub) ? OFF : AUTO; + + /* fixup mpc */ + wlc->mpc = true; +} + +/* read hwdisable state and propagate to wlc flag */ +static void wlc_radio_hwdisable_upd(struct wlc_info *wlc) +{ + if (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO || wlc->pub->hw_off) + return; + + if (wlc_bmac_radio_read_hwdisabled(wlc->hw)) { + mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); + } else { + mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); + } +} + +/* return true if Minimum Power Consumption should be entered, false otherwise */ +bool wlc_is_non_delay_mpc(struct wlc_info *wlc) +{ + return false; +} + +bool wlc_ismpc(struct wlc_info *wlc) +{ + return (wlc->mpc_delay_off == 0) && (wlc_is_non_delay_mpc(wlc)); +} + +void wlc_radio_mpc_upd(struct wlc_info *wlc) +{ + bool mpc_radio, radio_state; + + /* + * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled + * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio + * monitor also when WL_RADIO_MPC_DISABLE is the only reason that + * the radio is going down. + */ + if (!wlc->mpc) { + if (!wlc->pub->radio_disabled) + return; + mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); + wlc_radio_upd(wlc); + if (!wlc->pub->radio_disabled) + wlc_radio_monitor_stop(wlc); + return; + } + + /* + * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in wlc->pub->radio_disabled + * to go ON, always call radio_upd synchronously + * to go OFF, postpone radio_upd to later when context is safe(e.g. watchdog) + */ + radio_state = + (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF : + ON); + mpc_radio = (wlc_ismpc(wlc) == true) ? OFF : ON; + + if (radio_state == ON && mpc_radio == OFF) + wlc->mpc_delay_off = wlc->mpc_dlycnt; + else if (radio_state == OFF && mpc_radio == ON) { + mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); + wlc_radio_upd(wlc); + if (wlc->mpc_offcnt < WLC_MPC_THRESHOLD) { + wlc->mpc_dlycnt = WLC_MPC_MAX_DELAYCNT; + } else + wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; + wlc->mpc_dur += OSL_SYSUPTIME() - wlc->mpc_laston_ts; + } + /* Below logic is meant to capture the transition from mpc off to mpc on for reasons + * other than wlc->mpc_delay_off keeping the mpc off. In that case reset + * wlc->mpc_delay_off to wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off + */ + if ((wlc->prev_non_delay_mpc == false) && + (wlc_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off) { + wlc->mpc_delay_off = wlc->mpc_dlycnt; + } + wlc->prev_non_delay_mpc = wlc_is_non_delay_mpc(wlc); +} + +/* + * centralized radio disable/enable function, + * invoke radio enable/disable after updating hwradio status + */ +static void wlc_radio_upd(struct wlc_info *wlc) +{ + if (wlc->pub->radio_disabled) + wlc_radio_disable(wlc); + else + wlc_radio_enable(wlc); +} + +/* maintain LED behavior in down state */ +static void wlc_down_led_upd(struct wlc_info *wlc) +{ + ASSERT(!wlc->pub->up); + + /* maintain LEDs while in down state, turn on sbclk if not available yet */ + /* turn on sbclk if necessary */ + if (!AP_ENAB(wlc->pub)) { + wlc_pllreq(wlc, true, WLC_PLLREQ_FLIP); + + wlc_pllreq(wlc, false, WLC_PLLREQ_FLIP); + } +} + +void wlc_radio_disable(struct wlc_info *wlc) +{ + if (!wlc->pub->up) { + wlc_down_led_upd(wlc); + return; + } + + wlc_radio_monitor_start(wlc); + wl_down(wlc->wl); +} + +static void wlc_radio_enable(struct wlc_info *wlc) +{ + if (wlc->pub->up) + return; + + if (DEVICEREMOVED(wlc)) + return; + + if (!wlc->down_override) { /* imposed by wl down/out ioctl */ + wl_up(wlc->wl); + } +} + +/* periodical query hw radio button while driver is "down" */ +static void wlc_radio_timer(void *arg) +{ + struct wlc_info *wlc = (struct wlc_info *) arg; + + if (DEVICEREMOVED(wlc)) { + WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); + wl_down(wlc->wl); + return; + } + + /* cap mpc off count */ + if (wlc->mpc_offcnt < WLC_MPC_MAX_DELAYCNT) + wlc->mpc_offcnt++; + + /* validate all the reasons driver could be down and running this radio_timer */ + ASSERT(wlc->pub->radio_disabled || wlc->down_override); + wlc_radio_hwdisable_upd(wlc); + wlc_radio_upd(wlc); +} + +static bool wlc_radio_monitor_start(struct wlc_info *wlc) +{ + /* Don't start the timer if HWRADIO feature is disabled */ + if (wlc->radio_monitor || (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO)) + return true; + + wlc->radio_monitor = true; + wlc_pllreq(wlc, true, WLC_PLLREQ_RADIO_MON); + wl_add_timer(wlc->wl, wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true); + return true; +} + +bool wlc_radio_monitor_stop(struct wlc_info *wlc) +{ + if (!wlc->radio_monitor) + return true; + + ASSERT((wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO) != + WL_SWFL_NOHWRADIO); + + wlc->radio_monitor = false; + wlc_pllreq(wlc, false, WLC_PLLREQ_RADIO_MON); + return wl_del_timer(wlc->wl, wlc->radio_timer); +} + +/* bring the driver down, but don't reset hardware */ +void wlc_out(struct wlc_info *wlc) +{ + wlc_bmac_set_noreset(wlc->hw, true); + wlc_radio_upd(wlc); + wl_down(wlc->wl); + wlc_bmac_set_noreset(wlc->hw, false); + + /* core clk is true in BMAC driver due to noreset, need to mirror it in HIGH */ + wlc->clk = true; + + /* This will make sure that when 'up' is done + * after 'out' it'll restore hardware (especially gpios) + */ + wlc->pub->hw_up = false; +} + +#if defined(BCMDBG) +/* Verify the sanity of wlc->tx_prec_map. This can be done only by making sure that + * if there is no packet pending for the FIFO, then the corresponding prec bits should be set + * in prec_map. Of course, ignore this rule when block_datafifo is set + */ +static bool wlc_tx_prec_map_verify(struct wlc_info *wlc) +{ + /* For non-WME, both fifos have overlapping prec_map. So it's an error only if both + * fail the check. + */ + if (!EDCF_ENAB(wlc->pub)) { + if (!(WLC_TX_FIFO_CHECK(wlc, TX_DATA_FIFO) || + WLC_TX_FIFO_CHECK(wlc, TX_CTL_FIFO))) + return false; + else + return true; + } + + return WLC_TX_FIFO_CHECK(wlc, TX_AC_BK_FIFO) + && WLC_TX_FIFO_CHECK(wlc, TX_AC_BE_FIFO) + && WLC_TX_FIFO_CHECK(wlc, TX_AC_VI_FIFO) + && WLC_TX_FIFO_CHECK(wlc, TX_AC_VO_FIFO); +} +#endif /* BCMDBG */ + +static void wlc_watchdog_by_timer(void *arg) +{ + struct wlc_info *wlc = (struct wlc_info *) arg; + wlc_watchdog(arg); + if (WLC_WATCHDOG_TBTT(wlc)) { + /* set to normal osl watchdog period */ + wl_del_timer(wlc->wl, wlc->wdtimer); + wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, + true); + } +} + +/* common watchdog code */ +static void wlc_watchdog(void *arg) +{ + struct wlc_info *wlc = (struct wlc_info *) arg; + int i; + wlc_bsscfg_t *cfg; + + WL_TRACE("wl%d: wlc_watchdog\n", wlc->pub->unit); + + if (!wlc->pub->up) + return; + + if (DEVICEREMOVED(wlc)) { + WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); + wl_down(wlc->wl); + return; + } + + /* increment second count */ + wlc->pub->now++; + + /* delay radio disable */ + if (wlc->mpc_delay_off) { + if (--wlc->mpc_delay_off == 0) { + mboolset(wlc->pub->radio_disabled, + WL_RADIO_MPC_DISABLE); + if (wlc->mpc && wlc_ismpc(wlc)) + wlc->mpc_offcnt = 0; + wlc->mpc_laston_ts = OSL_SYSUPTIME(); + } + } + + /* mpc sync */ + wlc_radio_mpc_upd(wlc); + /* radio sync: sw/hw/mpc --> radio_disable/radio_enable */ + wlc_radio_hwdisable_upd(wlc); + wlc_radio_upd(wlc); + /* if ismpc, driver should be in down state if up/down is allowed */ + if (wlc->mpc && wlc_ismpc(wlc)) + ASSERT(!wlc->pub->up); + /* if radio is disable, driver may be down, quit here */ + if (wlc->pub->radio_disabled) + return; + + wlc_bmac_watchdog(wlc); + + /* occasionally sample mac stat counters to detect 16-bit counter wrap */ + if ((WLC_UPDATE_STATS(wlc)) + && (!(wlc->pub->now % SW_TIMER_MAC_STAT_UPD))) + wlc_statsupd(wlc); + + /* Manage TKIP countermeasures timers */ + FOREACH_BSS(wlc, i, cfg) { + if (cfg->tk_cm_dt) { + cfg->tk_cm_dt--; + } + if (cfg->tk_cm_bt) { + cfg->tk_cm_bt--; + } + } + + /* Call any registered watchdog handlers */ + for (i = 0; i < WLC_MAXMODULES; i++) { + if (wlc->modulecb[i].watchdog_fn) + wlc->modulecb[i].watchdog_fn(wlc->modulecb[i].hdl); + } + + if (WLCISNPHY(wlc->band) && !wlc->pub->tempsense_disable && + ((wlc->pub->now - wlc->tempsense_lasttime) >= + WLC_TEMPSENSE_PERIOD)) { + wlc->tempsense_lasttime = wlc->pub->now; + wlc_tempsense_upd(wlc); + } + /* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */ + ASSERT(wlc_bmac_taclear(wlc->hw, true)); + + /* Verify that tx_prec_map and fifos are in sync to avoid lock ups */ + ASSERT(wlc_tx_prec_map_verify(wlc)); + + ASSERT(wlc_ps_check(wlc)); +} + +/* make interface operational */ +int wlc_up(struct wlc_info *wlc) +{ + WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__); + + /* HW is turned off so don't try to access it */ + if (wlc->pub->hw_off || DEVICEREMOVED(wlc)) + return BCME_RADIOOFF; + + if (!wlc->pub->hw_up) { + wlc_bmac_hw_up(wlc->hw); + wlc->pub->hw_up = true; + } + + if ((wlc->pub->boardflags & BFL_FEM) + && (wlc->pub->sih->chip == BCM4313_CHIP_ID)) { + if (wlc->pub->boardrev >= 0x1250 + && (wlc->pub->boardflags & BFL_FEM_BT)) { + wlc_mhf(wlc, MHF5, MHF5_4313_GPIOCTRL, + MHF5_4313_GPIOCTRL, WLC_BAND_ALL); + } else { + wlc_mhf(wlc, MHF4, MHF4_EXTPA_ENABLE, MHF4_EXTPA_ENABLE, + WLC_BAND_ALL); + } + } + + /* + * Need to read the hwradio status here to cover the case where the system + * is loaded with the hw radio disabled. We do not want to bring the driver up in this case. + * if radio is disabled, abort up, lower power, start radio timer and return 0(for NDIS) + * don't call radio_update to avoid looping wlc_up. + * + * wlc_bmac_up_prep() returns either 0 or BCME_RADIOOFF only + */ + if (!wlc->pub->radio_disabled) { + int status = wlc_bmac_up_prep(wlc->hw); + if (status == BCME_RADIOOFF) { + if (!mboolisset + (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) { + int idx; + wlc_bsscfg_t *bsscfg; + mboolset(wlc->pub->radio_disabled, + WL_RADIO_HW_DISABLE); + + FOREACH_BSS(wlc, idx, bsscfg) { + if (!BSSCFG_STA(bsscfg) + || !bsscfg->enable || !bsscfg->BSS) + continue; + WL_ERROR("wl%d.%d: wlc_up: rfdisable -> " "wlc_bsscfg_disable()\n", + wlc->pub->unit, idx); + } + } + } else + ASSERT(!status); + } + + if (wlc->pub->radio_disabled) { + wlc_radio_monitor_start(wlc); + return 0; + } + + /* wlc_bmac_up_prep has done wlc_corereset(). so clk is on, set it */ + wlc->clk = true; + + wlc_radio_monitor_stop(wlc); + + /* Set EDCF hostflags */ + if (EDCF_ENAB(wlc->pub)) { + wlc_mhf(wlc, MHF1, MHF1_EDCF, MHF1_EDCF, WLC_BAND_ALL); + } else { + wlc_mhf(wlc, MHF1, MHF1_EDCF, 0, WLC_BAND_ALL); + } + + if (WLC_WAR16165(wlc)) + wlc_mhf(wlc, MHF2, MHF2_PCISLOWCLKWAR, MHF2_PCISLOWCLKWAR, + WLC_BAND_ALL); + + wl_init(wlc->wl); + wlc->pub->up = true; + + if (wlc->bandinit_pending) { + wlc_suspend_mac_and_wait(wlc); + wlc_set_chanspec(wlc, wlc->default_bss->chanspec); + wlc->bandinit_pending = false; + wlc_enable_mac(wlc); + } + + wlc_bmac_up_finish(wlc->hw); + + /* other software states up after ISR is running */ + /* start APs that were to be brought up but are not up yet */ + /* if (AP_ENAB(wlc->pub)) wlc_restart_ap(wlc->ap); */ + + /* Program the TX wme params with the current settings */ + wlc_wme_retries_write(wlc); + + /* start one second watchdog timer */ + ASSERT(!wlc->WDarmed); + wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true); + wlc->WDarmed = true; + + /* ensure antenna config is up to date */ + wlc_stf_phy_txant_upd(wlc); + /* ensure LDPC config is in sync */ + wlc_ht_update_ldpc(wlc, wlc->stf->ldpc); + + return 0; +} + +/* Initialize the base precedence map for dequeueing from txq based on WME settings */ +static void wlc_tx_prec_map_init(struct wlc_info *wlc) +{ + wlc->tx_prec_map = WLC_PREC_BMP_ALL; + memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16)); + + /* For non-WME, both fifos have overlapping MAXPRIO. So just disable all precedences + * if either is full. + */ + if (!EDCF_ENAB(wlc->pub)) { + wlc->fifo2prec_map[TX_DATA_FIFO] = WLC_PREC_BMP_ALL; + wlc->fifo2prec_map[TX_CTL_FIFO] = WLC_PREC_BMP_ALL; + } else { + wlc->fifo2prec_map[TX_AC_BK_FIFO] = WLC_PREC_BMP_AC_BK; + wlc->fifo2prec_map[TX_AC_BE_FIFO] = WLC_PREC_BMP_AC_BE; + wlc->fifo2prec_map[TX_AC_VI_FIFO] = WLC_PREC_BMP_AC_VI; + wlc->fifo2prec_map[TX_AC_VO_FIFO] = WLC_PREC_BMP_AC_VO; + } +} + +static uint wlc_down_del_timer(struct wlc_info *wlc) +{ + uint callbacks = 0; + + return callbacks; +} + +/* + * Mark the interface nonoperational, stop the software mechanisms, + * disable the hardware, free any transient buffer state. + * Return a count of the number of driver callbacks still pending. + */ +uint wlc_down(struct wlc_info *wlc) +{ + + uint callbacks = 0; + int i; + bool dev_gone = false; + wlc_txq_info_t *qi; + + WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__); + + /* check if we are already in the going down path */ + if (wlc->going_down) { + WL_ERROR("wl%d: %s: Driver going down so return\n", + wlc->pub->unit, __func__); + return 0; + } + if (!wlc->pub->up) + return callbacks; + + /* in between, mpc could try to bring down again.. */ + wlc->going_down = true; + + callbacks += wlc_bmac_down_prep(wlc->hw); + + dev_gone = DEVICEREMOVED(wlc); + + /* Call any registered down handlers */ + for (i = 0; i < WLC_MAXMODULES; i++) { + if (wlc->modulecb[i].down_fn) + callbacks += + wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl); + } + + /* cancel the watchdog timer */ + if (wlc->WDarmed) { + if (!wl_del_timer(wlc->wl, wlc->wdtimer)) + callbacks++; + wlc->WDarmed = false; + } + /* cancel all other timers */ + callbacks += wlc_down_del_timer(wlc); + + /* interrupt must have been blocked */ + ASSERT((wlc->macintmask == 0) || !wlc->pub->up); + + wlc->pub->up = false; + + wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL); + + /* clear txq flow control */ + wlc_txflowcontrol_reset(wlc); + + /* flush tx queues */ + for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { + pktq_flush(wlc->osh, &qi->q, true, NULL, 0); + ASSERT(pktq_empty(&qi->q)); + } + + /* flush event queue. + * Should be the last thing done after all the events are generated + * Just delivers the events synchronously instead of waiting for a timer + */ + callbacks += wlc_eventq_down(wlc->eventq); + + callbacks += wlc_bmac_down_finish(wlc->hw); + + /* wlc_bmac_down_finish has done wlc_coredisable(). so clk is off */ + wlc->clk = false; + + + /* Verify all packets are flushed from the driver */ + if (wlc->osh->pktalloced != 0) { + WL_ERROR("%d packets not freed at wlc_down!!!!!!\n", + wlc->osh->pktalloced); + } +#ifdef BCMDBG + /* Since all the packets should have been freed, + * all callbacks should have been called + */ + for (i = 1; i <= wlc->pub->tunables->maxpktcb; i++) + ASSERT(wlc->pkt_callback[i].fn == NULL); +#endif + wlc->going_down = false; + return callbacks; +} + +/* Set the current gmode configuration */ +int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) +{ + int ret = 0; + uint i; + wlc_rateset_t rs; + /* Default to 54g Auto */ + s8 shortslot = WLC_SHORTSLOT_AUTO; /* Advertise and use shortslot (-1/0/1 Auto/Off/On) */ + bool shortslot_restrict = false; /* Restrict association to stations that support shortslot + */ + bool ignore_bcns = true; /* Ignore legacy beacons on the same channel */ + bool ofdm_basic = false; /* Make 6, 12, and 24 basic rates */ + int preamble = WLC_PLCP_LONG; /* Advertise and use short preambles (-1/0/1 Auto/Off/On) */ + bool preamble_restrict = false; /* Restrict association to stations that support short + * preambles + */ + struct wlcband *band; + + /* if N-support is enabled, allow Gmode set as long as requested + * Gmode is not GMODE_LEGACY_B + */ + if (N_ENAB(wlc->pub) && gmode == GMODE_LEGACY_B) + return BCME_UNSUPPORTED; + + /* verify that we are dealing with 2G band and grab the band pointer */ + if (wlc->band->bandtype == WLC_BAND_2G) + band = wlc->band; + else if ((NBANDS(wlc) > 1) && + (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == WLC_BAND_2G)) + band = wlc->bandstate[OTHERBANDUNIT(wlc)]; + else + return BCME_BADBAND; + + /* Legacy or bust when no OFDM is supported by regulatory */ + if ((wlc_channel_locale_flags_in_band(wlc->cmi, band->bandunit) & + WLC_NO_OFDM) && (gmode != GMODE_LEGACY_B)) + return BCME_RANGE; + + /* update configuration value */ + if (config == true) + wlc_protection_upd(wlc, WLC_PROT_G_USER, gmode); + + /* Clear supported rates filter */ + memset(&wlc->sup_rates_override, 0, sizeof(wlc_rateset_t)); + + /* Clear rateset override */ + memset(&rs, 0, sizeof(wlc_rateset_t)); + + switch (gmode) { + case GMODE_LEGACY_B: + shortslot = WLC_SHORTSLOT_OFF; + wlc_rateset_copy(&gphy_legacy_rates, &rs); + + break; + + case GMODE_LRS: + if (AP_ENAB(wlc->pub)) + wlc_rateset_copy(&cck_rates, &wlc->sup_rates_override); + break; + + case GMODE_AUTO: + /* Accept defaults */ + break; + + case GMODE_ONLY: + ofdm_basic = true; + preamble = WLC_PLCP_SHORT; + preamble_restrict = true; + break; + + case GMODE_PERFORMANCE: + if (AP_ENAB(wlc->pub)) /* Put all rates into the Supported Rates element */ + wlc_rateset_copy(&cck_ofdm_rates, + &wlc->sup_rates_override); + + shortslot = WLC_SHORTSLOT_ON; + shortslot_restrict = true; + ofdm_basic = true; + preamble = WLC_PLCP_SHORT; + preamble_restrict = true; + break; + + default: + /* Error */ + WL_ERROR("wl%d: %s: invalid gmode %d\n", + wlc->pub->unit, __func__, gmode); + return BCME_UNSUPPORTED; + } + + /* + * If we are switching to gmode == GMODE_LEGACY_B, + * clean up rate info that may refer to OFDM rates. + */ + if ((gmode == GMODE_LEGACY_B) && (band->gmode != GMODE_LEGACY_B)) { + band->gmode = gmode; + if (band->rspec_override && !IS_CCK(band->rspec_override)) { + band->rspec_override = 0; + wlc_reprate_init(wlc); + } + if (band->mrspec_override && !IS_CCK(band->mrspec_override)) { + band->mrspec_override = 0; + } + } + + band->gmode = gmode; + + wlc->ignore_bcns = ignore_bcns; + + wlc->shortslot_override = shortslot; + + if (AP_ENAB(wlc->pub)) { + /* wlc->ap->shortslot_restrict = shortslot_restrict; */ + wlc->PLCPHdr_override = + (preamble != + WLC_PLCP_LONG) ? WLC_PLCP_SHORT : WLC_PLCP_AUTO; + } + + if ((AP_ENAB(wlc->pub) && preamble != WLC_PLCP_LONG) + || preamble == WLC_PLCP_SHORT) + wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE; + else + wlc->default_bss->capability &= ~WLAN_CAPABILITY_SHORT_PREAMBLE; + + /* Update shortslot capability bit for AP and IBSS */ + if ((AP_ENAB(wlc->pub) && shortslot == WLC_SHORTSLOT_AUTO) || + shortslot == WLC_SHORTSLOT_ON) + wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_SLOT_TIME; + else + wlc->default_bss->capability &= + ~WLAN_CAPABILITY_SHORT_SLOT_TIME; + + /* Use the default 11g rateset */ + if (!rs.count) + wlc_rateset_copy(&cck_ofdm_rates, &rs); + + if (ofdm_basic) { + for (i = 0; i < rs.count; i++) { + if (rs.rates[i] == WLC_RATE_6M + || rs.rates[i] == WLC_RATE_12M + || rs.rates[i] == WLC_RATE_24M) + rs.rates[i] |= WLC_RATE_FLAG; + } + } + + /* Set default bss rateset */ + wlc->default_bss->rateset.count = rs.count; + bcopy((char *)rs.rates, (char *)wlc->default_bss->rateset.rates, + sizeof(wlc->default_bss->rateset.rates)); + + return ret; +} + +static int wlc_nmode_validate(struct wlc_info *wlc, s32 nmode) +{ + int err = 0; + + switch (nmode) { + + case OFF: + break; + + case AUTO: + case WL_11N_2x2: + case WL_11N_3x3: + if (!(WLC_PHY_11N_CAP(wlc->band))) + err = BCME_BADBAND; + break; + + default: + err = BCME_RANGE; + break; + } + + return err; +} + +int wlc_set_nmode(struct wlc_info *wlc, s32 nmode) +{ + uint i; + int err; + + err = wlc_nmode_validate(wlc, nmode); + ASSERT(err == 0); + if (err) + return err; + + switch (nmode) { + case OFF: + wlc->pub->_n_enab = OFF; + wlc->default_bss->flags &= ~WLC_BSS_HT; + /* delete the mcs rates from the default and hw ratesets */ + wlc_rateset_mcs_clear(&wlc->default_bss->rateset); + for (i = 0; i < NBANDS(wlc); i++) { + memset(wlc->bandstate[i]->hw_rateset.mcs, 0, + MCSSET_LEN); + if (IS_MCS(wlc->band->rspec_override)) { + wlc->bandstate[i]->rspec_override = 0; + wlc_reprate_init(wlc); + } + if (IS_MCS(wlc->band->mrspec_override)) + wlc->bandstate[i]->mrspec_override = 0; + } + break; + + case AUTO: + if (wlc->stf->txstreams == WL_11N_3x3) + nmode = WL_11N_3x3; + else + nmode = WL_11N_2x2; + case WL_11N_2x2: + case WL_11N_3x3: + ASSERT(WLC_PHY_11N_CAP(wlc->band)); + /* force GMODE_AUTO if NMODE is ON */ + wlc_set_gmode(wlc, GMODE_AUTO, true); + if (nmode == WL_11N_3x3) + wlc->pub->_n_enab = SUPPORT_HT; + else + wlc->pub->_n_enab = SUPPORT_11N; + wlc->default_bss->flags |= WLC_BSS_HT; + /* add the mcs rates to the default and hw ratesets */ + wlc_rateset_mcs_build(&wlc->default_bss->rateset, + wlc->stf->txstreams); + for (i = 0; i < NBANDS(wlc); i++) + memcpy(wlc->bandstate[i]->hw_rateset.mcs, + wlc->default_bss->rateset.mcs, MCSSET_LEN); + break; + + default: + ASSERT(0); + break; + } + + return err; +} + +static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg) +{ + wlc_rateset_t rs, new; + uint bandunit; + + bcopy((char *)rs_arg, (char *)&rs, sizeof(wlc_rateset_t)); + + /* check for bad count value */ + if ((rs.count == 0) || (rs.count > WLC_NUMRATES)) + return BCME_BADRATESET; + + /* try the current band */ + bandunit = wlc->band->bandunit; + bcopy((char *)&rs, (char *)&new, sizeof(wlc_rateset_t)); + if (wlc_rate_hwrs_filter_sort_validate + (&new, &wlc->bandstate[bandunit]->hw_rateset, true, + wlc->stf->txstreams)) + goto good; + + /* try the other band */ + if (IS_MBAND_UNLOCKED(wlc)) { + bandunit = OTHERBANDUNIT(wlc); + bcopy((char *)&rs, (char *)&new, sizeof(wlc_rateset_t)); + if (wlc_rate_hwrs_filter_sort_validate(&new, + &wlc-> + bandstate[bandunit]-> + hw_rateset, true, + wlc->stf->txstreams)) + goto good; + } + + return BCME_ERROR; + + good: + /* apply new rateset */ + bcopy((char *)&new, (char *)&wlc->default_bss->rateset, + sizeof(wlc_rateset_t)); + bcopy((char *)&new, (char *)&wlc->bandstate[bandunit]->defrateset, + sizeof(wlc_rateset_t)); + return 0; +} + +/* simplified integer set interface for common ioctl handler */ +int wlc_set(struct wlc_info *wlc, int cmd, int arg) +{ + return wlc_ioctl(wlc, cmd, (void *)&arg, sizeof(arg), NULL); +} + +/* simplified integer get interface for common ioctl handler */ +int wlc_get(struct wlc_info *wlc, int cmd, int *arg) +{ + return wlc_ioctl(wlc, cmd, arg, sizeof(int), NULL); +} + +static void wlc_ofdm_rateset_war(struct wlc_info *wlc) +{ + u8 r; + bool war = false; + + if (wlc->cfg->associated) + r = wlc->cfg->current_bss->rateset.rates[0]; + else + r = wlc->default_bss->rateset.rates[0]; + + wlc_phy_ofdm_rateset_war(wlc->band->pi, war); + + return; +} + +int +wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, + struct wlc_if *wlcif) +{ + return _wlc_ioctl(wlc, cmd, arg, len, wlcif); +} + +/* common ioctl handler. return: 0=ok, -1=error, positive=particular error */ +static int +_wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, + struct wlc_if *wlcif) +{ + int val, *pval; + bool bool_val; + int bcmerror; + d11regs_t *regs; + uint i; + struct scb *nextscb; + bool ta_ok; + uint band; + rw_reg_t *r; + wlc_bsscfg_t *bsscfg; + struct osl_info *osh; + wlc_bss_info_t *current_bss; + + /* update bsscfg pointer */ + bsscfg = NULL; /* XXX: Hack bsscfg to be size one and use this globally */ + current_bss = NULL; + + /* initialize the following to get rid of compiler warning */ + nextscb = NULL; + ta_ok = false; + band = 0; + r = NULL; + + /* If the device is turned off, then it's not "removed" */ + if (!wlc->pub->hw_off && DEVICEREMOVED(wlc)) { + WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); + wl_down(wlc->wl); + return BCME_ERROR; + } + + ASSERT(!(wlc->pub->hw_off && wlc->pub->up)); + + /* default argument is generic integer */ + pval = arg ? (int *)arg:NULL; + + /* This will prevent the misaligned access */ + if (pval && (u32) len >= sizeof(val)) + bcopy(pval, &val, sizeof(val)); + else + val = 0; + + /* bool conversion to avoid duplication below */ + bool_val = val != 0; + + if (cmd != WLC_SET_CHANNEL) + WL_NONE("WLC_IOCTL: cmd %d val 0x%x (%d) len %d\n", + cmd, (uint)val, val, len); + + bcmerror = 0; + regs = wlc->regs; + osh = wlc->osh; + + /* A few commands don't need any arguments; all the others do. */ + switch (cmd) { + case WLC_UP: + case WLC_OUT: + case WLC_DOWN: + case WLC_DISASSOC: + case WLC_RESTART: + case WLC_REBOOT: + case WLC_START_CHANNEL_QA: + case WLC_INIT: + break; + + default: + if ((arg == NULL) || (len <= 0)) { + WL_ERROR("wl%d: %s: Command %d needs arguments\n", + wlc->pub->unit, __func__, cmd); + bcmerror = BCME_BADARG; + goto done; + } + } + + switch (cmd) { + +#if defined(BCMDBG) + case WLC_GET_MSGLEVEL: + *pval = wl_msg_level; + break; + + case WLC_SET_MSGLEVEL: + wl_msg_level = val; + break; +#endif + + case WLC_GET_INSTANCE: + *pval = wlc->pub->unit; + break; + + case WLC_GET_CHANNEL:{ + channel_info_t *ci = (channel_info_t *) arg; + + ASSERT(len > (int)sizeof(ci)); + + ci->hw_channel = + CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC); + ci->target_channel = + CHSPEC_CHANNEL(wlc->default_bss->chanspec); + ci->scan_channel = 0; + + break; + } + + case WLC_SET_CHANNEL:{ + chanspec_t chspec = CH20MHZ_CHSPEC(val); + + if (val < 0 || val > MAXCHANNEL) { + bcmerror = BCME_OUTOFRANGECHAN; + break; + } + + if (!wlc_valid_chanspec_db(wlc->cmi, chspec)) { + bcmerror = BCME_BADCHAN; + break; + } + + if (!wlc->pub->up && IS_MBAND_UNLOCKED(wlc)) { + if (wlc->band->bandunit != + CHSPEC_WLCBANDUNIT(chspec)) + wlc->bandinit_pending = true; + else + wlc->bandinit_pending = false; + } + + wlc->default_bss->chanspec = chspec; + /* wlc_BSSinit() will sanitize the rateset before using it.. */ + if (wlc->pub->up && !wlc->pub->associated && + (WLC_BAND_PI_RADIO_CHANSPEC != chspec)) { + wlc_set_home_chanspec(wlc, chspec); + wlc_suspend_mac_and_wait(wlc); + wlc_set_chanspec(wlc, chspec); + wlc_enable_mac(wlc); + } + break; + } + +#if defined(BCMDBG) + case WLC_GET_UCFLAGS: + if (!wlc->pub->up) { + bcmerror = BCME_NOTUP; + break; + } + + /* optional band is stored in the second integer of incoming buffer */ + band = + (len < + (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; + + /* bcmerror checking */ + bcmerror = wlc_iocregchk(wlc, band); + if (bcmerror) + break; + + if (val >= MHFMAX) { + bcmerror = BCME_RANGE; + break; + } + + *pval = wlc_bmac_mhf_get(wlc->hw, (u8) val, WLC_BAND_AUTO); + break; + + case WLC_SET_UCFLAGS: + if (!wlc->pub->up) { + bcmerror = BCME_NOTUP; + break; + } + + /* optional band is stored in the second integer of incoming buffer */ + band = + (len < + (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; + + /* bcmerror checking */ + bcmerror = wlc_iocregchk(wlc, band); + if (bcmerror) + break; + + i = (u16) val; + if (i >= MHFMAX) { + bcmerror = BCME_RANGE; + break; + } + + wlc_mhf(wlc, (u8) i, 0xffff, (u16) (val >> NBITS(u16)), + WLC_BAND_AUTO); + break; + + case WLC_GET_SHMEM: + ta_ok = true; + + /* optional band is stored in the second integer of incoming buffer */ + band = + (len < + (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; + + /* bcmerror checking */ + bcmerror = wlc_iocregchk(wlc, band); + if (bcmerror) + break; + + if (val & 1) { + bcmerror = BCME_BADADDR; + break; + } + + *pval = wlc_read_shm(wlc, (u16) val); + break; + + case WLC_SET_SHMEM: + ta_ok = true; + + /* optional band is stored in the second integer of incoming buffer */ + band = + (len < + (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; + + /* bcmerror checking */ + bcmerror = wlc_iocregchk(wlc, band); + if (bcmerror) + break; + + if (val & 1) { + bcmerror = BCME_BADADDR; + break; + } + + wlc_write_shm(wlc, (u16) val, + (u16) (val >> NBITS(u16))); + break; + + case WLC_R_REG: /* MAC registers */ + ta_ok = true; + r = (rw_reg_t *) arg; + band = WLC_BAND_AUTO; + + if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + if (len >= (int)sizeof(rw_reg_t)) + band = r->band; + + /* bcmerror checking */ + bcmerror = wlc_iocregchk(wlc, band); + if (bcmerror) + break; + + if ((r->byteoff + r->size) > sizeof(d11regs_t)) { + bcmerror = BCME_BADADDR; + break; + } + if (r->size == sizeof(u32)) + r->val = + R_REG(osh, + (u32 *)((unsigned char *)(unsigned long)regs + + r->byteoff)); + else if (r->size == sizeof(u16)) + r->val = + R_REG(osh, + (u16 *)((unsigned char *)(unsigned long)regs + + r->byteoff)); + else + bcmerror = BCME_BADADDR; + break; + + case WLC_W_REG: + ta_ok = true; + r = (rw_reg_t *) arg; + band = WLC_BAND_AUTO; + + if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + if (len >= (int)sizeof(rw_reg_t)) + band = r->band; + + /* bcmerror checking */ + bcmerror = wlc_iocregchk(wlc, band); + if (bcmerror) + break; + + if (r->byteoff + r->size > sizeof(d11regs_t)) { + bcmerror = BCME_BADADDR; + break; + } + if (r->size == sizeof(u32)) + W_REG(osh, + (u32 *)((unsigned char *)(unsigned long) regs + + r->byteoff), r->val); + else if (r->size == sizeof(u16)) + W_REG(osh, + (u16 *)((unsigned char *)(unsigned long) regs + + r->byteoff), r->val); + else + bcmerror = BCME_BADADDR; + break; +#endif /* BCMDBG */ + + case WLC_GET_TXANT: + *pval = wlc->stf->txant; + break; + + case WLC_SET_TXANT: + bcmerror = wlc_stf_ant_txant_validate(wlc, (s8) val); + if (bcmerror < 0) + break; + + wlc->stf->txant = (s8) val; + + /* if down, we are done */ + if (!wlc->pub->up) + break; + + wlc_suspend_mac_and_wait(wlc); + + wlc_stf_phy_txant_upd(wlc); + wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec); + + wlc_enable_mac(wlc); + + break; + + case WLC_GET_ANTDIV:{ + u8 phy_antdiv; + + /* return configured value if core is down */ + if (!wlc->pub->up) { + *pval = wlc->stf->ant_rx_ovr; + + } else { + if (wlc_phy_ant_rxdiv_get + (wlc->band->pi, &phy_antdiv)) + *pval = (int)phy_antdiv; + else + *pval = (int)wlc->stf->ant_rx_ovr; + } + + break; + } + case WLC_SET_ANTDIV: + /* values are -1=driver default, 0=force0, 1=force1, 2=start1, 3=start0 */ + if ((val < -1) || (val > 3)) { + bcmerror = BCME_RANGE; + break; + } + + if (val == -1) + val = ANT_RX_DIV_DEF; + + wlc->stf->ant_rx_ovr = (u8) val; + wlc_phy_ant_rxdiv_set(wlc->band->pi, (u8) val); + break; + + case WLC_GET_RX_ANT:{ /* get latest used rx antenna */ + u16 rxstatus; + + if (!wlc->pub->up) { + bcmerror = BCME_NOTUP; + break; + } + + rxstatus = R_REG(wlc->osh, &wlc->regs->phyrxstatus0); + if (rxstatus == 0xdead || rxstatus == (u16) -1) { + bcmerror = BCME_ERROR; + break; + } + *pval = (rxstatus & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; + break; + } + +#if defined(BCMDBG) + case WLC_GET_UCANTDIV: + if (!wlc->clk) { + bcmerror = BCME_NOCLK; + break; + } + + *pval = + (wlc_bmac_mhf_get(wlc->hw, MHF1, WLC_BAND_AUTO) & + MHF1_ANTDIV); + break; + + case WLC_SET_UCANTDIV:{ + if (!wlc->pub->up) { + bcmerror = BCME_NOTUP; + break; + } + + /* if multiband, band must be locked */ + if (IS_MBAND_UNLOCKED(wlc)) { + bcmerror = BCME_NOTBANDLOCKED; + break; + } + + /* 4322 supports antdiv in phy, no need to set it to ucode */ + if (WLCISNPHY(wlc->band) + && D11REV_IS(wlc->pub->corerev, 16)) { + WL_ERROR("wl%d: can't set ucantdiv for 4322\n", + wlc->pub->unit); + bcmerror = BCME_UNSUPPORTED; + } else + wlc_mhf(wlc, MHF1, MHF1_ANTDIV, + (val ? MHF1_ANTDIV : 0), WLC_BAND_AUTO); + break; + } +#endif /* defined(BCMDBG) */ + + case WLC_GET_SRL: + *pval = wlc->SRL; + break; + + case WLC_SET_SRL: + if (val >= 1 && val <= RETRY_SHORT_MAX) { + int ac; + wlc->SRL = (u16) val; + + wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); + + for (ac = 0; ac < AC_COUNT; ac++) { + WLC_WME_RETRY_SHORT_SET(wlc, ac, wlc->SRL); + } + wlc_wme_retries_write(wlc); + } else + bcmerror = BCME_RANGE; + break; + + case WLC_GET_LRL: + *pval = wlc->LRL; + break; + + case WLC_SET_LRL: + if (val >= 1 && val <= 255) { + int ac; + wlc->LRL = (u16) val; + + wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); + + for (ac = 0; ac < AC_COUNT; ac++) { + WLC_WME_RETRY_LONG_SET(wlc, ac, wlc->LRL); + } + wlc_wme_retries_write(wlc); + } else + bcmerror = BCME_RANGE; + break; + + case WLC_GET_CWMIN: + *pval = wlc->band->CWmin; + break; + + case WLC_SET_CWMIN: + if (!wlc->clk) { + bcmerror = BCME_NOCLK; + break; + } + + if (val >= 1 && val <= 255) { + wlc_set_cwmin(wlc, (u16) val); + } else + bcmerror = BCME_RANGE; + break; + + case WLC_GET_CWMAX: + *pval = wlc->band->CWmax; + break; + + case WLC_SET_CWMAX: + if (!wlc->clk) { + bcmerror = BCME_NOCLK; + break; + } + + if (val >= 255 && val <= 2047) { + wlc_set_cwmax(wlc, (u16) val); + } else + bcmerror = BCME_RANGE; + break; + + case WLC_GET_RADIO: /* use mask if don't want to expose some internal bits */ + *pval = wlc->pub->radio_disabled; + break; + + case WLC_SET_RADIO:{ /* 32 bits input, higher 16 bits are mask, lower 16 bits are value to + * set + */ + u16 radiomask, radioval; + uint validbits = + WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE; + mbool new = 0; + + radiomask = (val & 0xffff0000) >> 16; + radioval = val & 0x0000ffff; + + if ((radiomask == 0) || (radiomask & ~validbits) + || (radioval & ~validbits) + || ((radioval & ~radiomask) != 0)) { + WL_ERROR("SET_RADIO with wrong bits 0x%x\n", + val); + bcmerror = BCME_RANGE; + break; + } + + new = + (wlc->pub->radio_disabled & ~radiomask) | radioval; + wlc->pub->radio_disabled = new; + + wlc_radio_hwdisable_upd(wlc); + wlc_radio_upd(wlc); + break; + } + + case WLC_GET_PHYTYPE: + *pval = WLC_PHYTYPE(wlc->band->phytype); + break; + +#if defined(BCMDBG) + case WLC_GET_KEY: + if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc))) { + wl_wsec_key_t key; + + wsec_key_t *src_key = wlc->wsec_keys[val]; + + if (len < (int)sizeof(key)) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + memset((char *)&key, 0, sizeof(key)); + if (src_key) { + key.index = src_key->id; + key.len = src_key->len; + bcopy(src_key->data, key.data, key.len); + key.algo = src_key->algo; + if (WSEC_SOFTKEY(wlc, src_key, bsscfg)) + key.flags |= WL_SOFT_KEY; + if (src_key->flags & WSEC_PRIMARY_KEY) + key.flags |= WL_PRIMARY_KEY; + + bcopy(src_key->ea, key.ea, + ETH_ALEN); + } + + bcopy((char *)&key, arg, sizeof(key)); + } else + bcmerror = BCME_BADKEYIDX; + break; +#endif /* defined(BCMDBG) */ + + case WLC_SET_KEY: + bcmerror = + wlc_iovar_op(wlc, "wsec_key", NULL, 0, arg, len, IOV_SET, + wlcif); + break; + + case WLC_GET_KEY_SEQ:{ + wsec_key_t *key; + + if (len < DOT11_WPA_KEY_RSC_LEN) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + /* Return the key's tx iv as an EAPOL sequence counter. + * This will be used to supply the RSC value to a supplicant. + * The format is 8 bytes, with least significant in seq[0]. + */ + + key = WSEC_KEY(wlc, val); + if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc)) && + (key != NULL)) { + u8 seq[DOT11_WPA_KEY_RSC_LEN]; + u16 lo; + u32 hi; + /* group keys in WPA-NONE (IBSS only, AES and TKIP) use a global TXIV */ + if ((bsscfg->WPA_auth & WPA_AUTH_NONE) && + is_zero_ether_addr(key->ea)) { + lo = bsscfg->wpa_none_txiv.lo; + hi = bsscfg->wpa_none_txiv.hi; + } else { + lo = key->txiv.lo; + hi = key->txiv.hi; + } + + /* format the buffer, low to high */ + seq[0] = lo & 0xff; + seq[1] = (lo >> 8) & 0xff; + seq[2] = hi & 0xff; + seq[3] = (hi >> 8) & 0xff; + seq[4] = (hi >> 16) & 0xff; + seq[5] = (hi >> 24) & 0xff; + seq[6] = 0; + seq[7] = 0; + + bcopy((char *)seq, arg, sizeof(seq)); + } else { + bcmerror = BCME_BADKEYIDX; + } + break; + } + + case WLC_GET_CURR_RATESET:{ + wl_rateset_t *ret_rs = (wl_rateset_t *) arg; + wlc_rateset_t *rs; + + if (bsscfg->associated) + rs = ¤t_bss->rateset; + else + rs = &wlc->default_bss->rateset; + + if (len < (int)(rs->count + sizeof(rs->count))) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + /* Copy only legacy rateset section */ + ret_rs->count = rs->count; + bcopy(&rs->rates, &ret_rs->rates, rs->count); + break; + } + + case WLC_GET_RATESET:{ + wlc_rateset_t rs; + wl_rateset_t *ret_rs = (wl_rateset_t *) arg; + + memset(&rs, 0, sizeof(wlc_rateset_t)); + wlc_default_rateset(wlc, (wlc_rateset_t *) &rs); + + if (len < (int)(rs.count + sizeof(rs.count))) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + /* Copy only legacy rateset section */ + ret_rs->count = rs.count; + bcopy(&rs.rates, &ret_rs->rates, rs.count); + break; + } + + case WLC_SET_RATESET:{ + wlc_rateset_t rs; + wl_rateset_t *in_rs = (wl_rateset_t *) arg; + + if (len < (int)(in_rs->count + sizeof(in_rs->count))) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + if (in_rs->count > WLC_NUMRATES) { + bcmerror = BCME_BUFTOOLONG; + break; + } + + memset(&rs, 0, sizeof(wlc_rateset_t)); + + /* Copy only legacy rateset section */ + rs.count = in_rs->count; + bcopy(&in_rs->rates, &rs.rates, rs.count); + + /* merge rateset coming in with the current mcsset */ + if (N_ENAB(wlc->pub)) { + if (bsscfg->associated) + bcopy(¤t_bss->rateset.mcs[0], + rs.mcs, MCSSET_LEN); + else + bcopy(&wlc->default_bss->rateset.mcs[0], + rs.mcs, MCSSET_LEN); + } + + bcmerror = wlc_set_rateset(wlc, &rs); + + if (!bcmerror) + wlc_ofdm_rateset_war(wlc); + + break; + } + + case WLC_GET_BCNPRD: + if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated) + *pval = current_bss->beacon_period; + else + *pval = wlc->default_bss->beacon_period; + break; + + case WLC_SET_BCNPRD: + /* range [1, 0xffff] */ + if (val >= DOT11_MIN_BEACON_PERIOD + && val <= DOT11_MAX_BEACON_PERIOD) { + wlc->default_bss->beacon_period = (u16) val; + } else + bcmerror = BCME_RANGE; + break; + + case WLC_GET_DTIMPRD: + if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated) + *pval = current_bss->dtim_period; + else + *pval = wlc->default_bss->dtim_period; + break; + + case WLC_SET_DTIMPRD: + /* range [1, 0xff] */ + if (val >= DOT11_MIN_DTIM_PERIOD + && val <= DOT11_MAX_DTIM_PERIOD) { + wlc->default_bss->dtim_period = (u8) val; + } else + bcmerror = BCME_RANGE; + break; + +#ifdef SUPPORT_PS + case WLC_GET_PM: + *pval = wlc->PM; + break; + + case WLC_SET_PM: + if ((val >= PM_OFF) && (val <= PM_MAX)) { + wlc->PM = (u8) val; + if (wlc->pub->up) { + } + /* Change watchdog driver to align watchdog with tbtt if possible */ + wlc_watchdog_upd(wlc, PS_ALLOWED(wlc)); + } else + bcmerror = BCME_ERROR; + break; +#endif /* SUPPORT_PS */ + +#ifdef SUPPORT_PS +#ifdef BCMDBG + case WLC_GET_WAKE: + if (AP_ENAB(wlc->pub)) { + bcmerror = BCME_NOTSTA; + break; + } + *pval = wlc->wake; + break; + + case WLC_SET_WAKE: + if (AP_ENAB(wlc->pub)) { + bcmerror = BCME_NOTSTA; + break; + } + + wlc->wake = val ? true : false; + + /* if down, we're done */ + if (!wlc->pub->up) + break; + + /* apply to the mac */ + wlc_set_ps_ctrl(wlc); + break; +#endif /* BCMDBG */ +#endif /* SUPPORT_PS */ + + case WLC_GET_REVINFO: + bcmerror = wlc_get_revision_info(wlc, arg, (uint) len); + break; + + case WLC_GET_AP: + *pval = (int)AP_ENAB(wlc->pub); + break; + + case WLC_GET_ATIM: + if (bsscfg->associated) + *pval = (int)current_bss->atim_window; + else + *pval = (int)wlc->default_bss->atim_window; + break; + + case WLC_SET_ATIM: + wlc->default_bss->atim_window = (u32) val; + break; + + case WLC_GET_PKTCNTS:{ + get_pktcnt_t *pktcnt = (get_pktcnt_t *) pval; + if (WLC_UPDATE_STATS(wlc)) + wlc_statsupd(wlc); + pktcnt->rx_good_pkt = WLCNTVAL(wlc->pub->_cnt->rxframe); + pktcnt->rx_bad_pkt = WLCNTVAL(wlc->pub->_cnt->rxerror); + pktcnt->tx_good_pkt = + WLCNTVAL(wlc->pub->_cnt->txfrmsnt); + pktcnt->tx_bad_pkt = + WLCNTVAL(wlc->pub->_cnt->txerror) + + WLCNTVAL(wlc->pub->_cnt->txfail); + if (len >= (int)sizeof(get_pktcnt_t)) { + /* Be backward compatible - only if buffer is large enough */ + pktcnt->rx_ocast_good_pkt = + WLCNTVAL(wlc->pub->_cnt->rxmfrmocast); + } + break; + } + +#ifdef SUPPORT_HWKEY + case WLC_GET_WSEC: + bcmerror = + wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_GET, + wlcif); + break; + + case WLC_SET_WSEC: + bcmerror = + wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_SET, + wlcif); + break; + + case WLC_GET_WPA_AUTH: + *pval = (int)bsscfg->WPA_auth; + break; + + case WLC_SET_WPA_AUTH: + /* change of WPA_Auth modifies the PS_ALLOWED state */ + if (BSSCFG_STA(bsscfg)) { + bsscfg->WPA_auth = (u16) val; + } else + bsscfg->WPA_auth = (u16) val; + break; +#endif /* SUPPORT_HWKEY */ + + case WLC_GET_BANDLIST: + /* count of number of bands, followed by each band type */ + *pval++ = NBANDS(wlc); + *pval++ = wlc->band->bandtype; + if (NBANDS(wlc) > 1) + *pval++ = wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype; + break; + + case WLC_GET_BAND: + *pval = wlc->bandlocked ? wlc->band->bandtype : WLC_BAND_AUTO; + break; + + case WLC_GET_PHYLIST: + { + unsigned char *cp = arg; + if (len < 3) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + if (WLCISNPHY(wlc->band)) { + *cp++ = 'n'; + } else if (WLCISLCNPHY(wlc->band)) { + *cp++ = 'c'; + } else if (WLCISSSLPNPHY(wlc->band)) { + *cp++ = 's'; + } + *cp = '\0'; + break; + } + + case WLC_GET_SHORTSLOT: + *pval = wlc->shortslot; + break; + + case WLC_GET_SHORTSLOT_OVERRIDE: + *pval = wlc->shortslot_override; + break; + + case WLC_SET_SHORTSLOT_OVERRIDE: + if ((val != WLC_SHORTSLOT_AUTO) && + (val != WLC_SHORTSLOT_OFF) && (val != WLC_SHORTSLOT_ON)) { + bcmerror = BCME_RANGE; + break; + } + + wlc->shortslot_override = (s8) val; + + /* shortslot is an 11g feature, so no more work if we are + * currently on the 5G band + */ + if (BAND_5G(wlc->band->bandtype)) + break; + + if (wlc->pub->up && wlc->pub->associated) { + /* let watchdog or beacon processing update shortslot */ + } else if (wlc->pub->up) { + /* unassociated shortslot is off */ + wlc_switch_shortslot(wlc, false); + } else { + /* driver is down, so just update the wlc_info value */ + if (wlc->shortslot_override == WLC_SHORTSLOT_AUTO) { + wlc->shortslot = false; + } else { + wlc->shortslot = + (wlc->shortslot_override == + WLC_SHORTSLOT_ON); + } + } + + break; + + case WLC_GET_LEGACY_ERP: + *pval = wlc->include_legacy_erp; + break; + + case WLC_SET_LEGACY_ERP: + if (wlc->include_legacy_erp == bool_val) + break; + + wlc->include_legacy_erp = bool_val; + + if (AP_ENAB(wlc->pub) && wlc->clk) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, true); + } + break; + + case WLC_GET_GMODE: + if (wlc->band->bandtype == WLC_BAND_2G) + *pval = wlc->band->gmode; + else if (NBANDS(wlc) > 1) + *pval = wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode; + break; + + case WLC_SET_GMODE: + if (!wlc->pub->associated) + bcmerror = wlc_set_gmode(wlc, (u8) val, true); + else { + bcmerror = BCME_ASSOCIATED; + break; + } + break; + + case WLC_GET_GMODE_PROTECTION: + *pval = wlc->protection->_g; + break; + + case WLC_GET_PROTECTION_CONTROL: + *pval = wlc->protection->overlap; + break; + + case WLC_SET_PROTECTION_CONTROL: + if ((val != WLC_PROTECTION_CTL_OFF) && + (val != WLC_PROTECTION_CTL_LOCAL) && + (val != WLC_PROTECTION_CTL_OVERLAP)) { + bcmerror = BCME_RANGE; + break; + } + + wlc_protection_upd(wlc, WLC_PROT_OVERLAP, (s8) val); + + /* Current g_protection will sync up to the specified control alg in watchdog + * if the driver is up and associated. + * If the driver is down or not associated, the control setting has no effect. + */ + break; + + case WLC_GET_GMODE_PROTECTION_OVERRIDE: + *pval = wlc->protection->g_override; + break; + + case WLC_SET_GMODE_PROTECTION_OVERRIDE: + if ((val != WLC_PROTECTION_AUTO) && + (val != WLC_PROTECTION_OFF) && (val != WLC_PROTECTION_ON)) { + bcmerror = BCME_RANGE; + break; + } + + wlc_protection_upd(wlc, WLC_PROT_G_OVR, (s8) val); + + break; + + case WLC_SET_SUP_RATESET_OVERRIDE:{ + wlc_rateset_t rs, new; + + /* copyin */ + if (len < (int)sizeof(wlc_rateset_t)) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + bcopy((char *)arg, (char *)&rs, sizeof(wlc_rateset_t)); + + /* check for bad count value */ + if (rs.count > WLC_NUMRATES) { + bcmerror = BCME_BADRATESET; /* invalid rateset */ + break; + } + + /* this command is only appropriate for gmode operation */ + if (!(wlc->band->gmode || + ((NBANDS(wlc) > 1) + && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) { + bcmerror = BCME_BADBAND; /* gmode only command when not in gmode */ + break; + } + + /* check for an empty rateset to clear the override */ + if (rs.count == 0) { + memset(&wlc->sup_rates_override, 0, + sizeof(wlc_rateset_t)); + break; + } + + /* validate rateset by comparing pre and post sorted against 11g hw rates */ + wlc_rateset_filter(&rs, &new, false, WLC_RATES_CCK_OFDM, + RATE_MASK, BSS_N_ENAB(wlc, bsscfg)); + wlc_rate_hwrs_filter_sort_validate(&new, + &cck_ofdm_rates, + false, + wlc->stf->txstreams); + if (rs.count != new.count) { + bcmerror = BCME_BADRATESET; /* invalid rateset */ + break; + } + + /* apply new rateset to the override */ + bcopy((char *)&new, (char *)&wlc->sup_rates_override, + sizeof(wlc_rateset_t)); + + /* update bcn and probe resp if needed */ + if (wlc->pub->up && AP_ENAB(wlc->pub) + && wlc->pub->associated) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, true); + } + break; + } + + case WLC_GET_SUP_RATESET_OVERRIDE: + /* this command is only appropriate for gmode operation */ + if (!(wlc->band->gmode || + ((NBANDS(wlc) > 1) + && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) { + bcmerror = BCME_BADBAND; /* gmode only command when not in gmode */ + break; + } + if (len < (int)sizeof(wlc_rateset_t)) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + bcopy((char *)&wlc->sup_rates_override, (char *)arg, + sizeof(wlc_rateset_t)); + + break; + + case WLC_GET_PRB_RESP_TIMEOUT: + *pval = wlc->prb_resp_timeout; + break; + + case WLC_SET_PRB_RESP_TIMEOUT: + if (wlc->pub->up) { + bcmerror = BCME_NOTDOWN; + break; + } + if (val < 0 || val >= 0xFFFF) { + bcmerror = BCME_RANGE; /* bad value */ + break; + } + wlc->prb_resp_timeout = (u16) val; + break; + + case WLC_GET_KEY_PRIMARY:{ + wsec_key_t *key; + + /* treat the 'val' parm as the key id */ + key = WSEC_BSS_DEFAULT_KEY(bsscfg); + if (key != NULL) { + *pval = key->id == val ? true : false; + } else { + bcmerror = BCME_BADKEYIDX; + } + break; + } + + case WLC_SET_KEY_PRIMARY:{ + wsec_key_t *key, *old_key; + + bcmerror = BCME_BADKEYIDX; + + /* treat the 'val' parm as the key id */ + for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) { + key = bsscfg->bss_def_keys[i]; + if (key != NULL && key->id == val) { + old_key = WSEC_BSS_DEFAULT_KEY(bsscfg); + if (old_key != NULL) + old_key->flags &= + ~WSEC_PRIMARY_KEY; + key->flags |= WSEC_PRIMARY_KEY; + bsscfg->wsec_index = i; + bcmerror = BCME_OK; + } + } + break; + } + +#ifdef BCMDBG + case WLC_INIT: + wl_init(wlc->wl); + break; +#endif + + case WLC_SET_VAR: + case WLC_GET_VAR:{ + char *name; + /* validate the name value */ + name = (char *)arg; + for (i = 0; i < (uint) len && *name != '\0'; + i++, name++) + ; + + if (i == (uint) len) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + i++; /* include the null in the string length */ + + if (cmd == WLC_GET_VAR) { + bcmerror = + wlc_iovar_op(wlc, arg, + (void *)((s8 *) arg + i), + len - i, arg, len, IOV_GET, + wlcif); + } else + bcmerror = + wlc_iovar_op(wlc, arg, NULL, 0, + (void *)((s8 *) arg + i), + len - i, IOV_SET, wlcif); + + break; + } + + case WLC_SET_WSEC_PMK: + bcmerror = BCME_UNSUPPORTED; + break; + +#if defined(BCMDBG) + case WLC_CURRENT_PWR: + if (!wlc->pub->up) + bcmerror = BCME_NOTUP; + else + bcmerror = wlc_get_current_txpwr(wlc, arg, len); + break; +#endif + + case WLC_LAST: + WL_ERROR("%s: WLC_LAST\n", __func__); + } + done: + + if (bcmerror) { + if (VALID_BCMERROR(bcmerror)) + wlc->pub->bcmerror = bcmerror; + else { + bcmerror = 0; + } + + } + /* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */ + /* In hw_off condition, IOCTLs that reach here are deemed safe but taclear would + * certainly result in getting -1 for register reads. So skip ta_clear altogether + */ + if (!(wlc->pub->hw_off)) + ASSERT(wlc_bmac_taclear(wlc->hw, ta_ok) || !ta_ok); + + return bcmerror; +} + +#if defined(BCMDBG) +/* consolidated register access ioctl error checking */ +int wlc_iocregchk(struct wlc_info *wlc, uint band) +{ + /* if band is specified, it must be the current band */ + if ((band != WLC_BAND_AUTO) && (band != (uint) wlc->band->bandtype)) + return BCME_BADBAND; + + /* if multiband and band is not specified, band must be locked */ + if ((band == WLC_BAND_AUTO) && IS_MBAND_UNLOCKED(wlc)) + return BCME_NOTBANDLOCKED; + + /* must have core clocks */ + if (!wlc->clk) + return BCME_NOCLK; + + return 0; +} +#endif /* defined(BCMDBG) */ + +#if defined(BCMDBG) +/* For some ioctls, make sure that the pi pointer matches the current phy */ +int wlc_iocpichk(struct wlc_info *wlc, uint phytype) +{ + if (wlc->band->phytype != phytype) + return BCME_BADBAND; + return 0; +} +#endif + +/* Look up the given var name in the given table */ +static const bcm_iovar_t *wlc_iovar_lookup(const bcm_iovar_t *table, + const char *name) +{ + const bcm_iovar_t *vi; + const char *lookup_name; + + /* skip any ':' delimited option prefixes */ + lookup_name = strrchr(name, ':'); + if (lookup_name != NULL) + lookup_name++; + else + lookup_name = name; + + ASSERT(table != NULL); + + for (vi = table; vi->name; vi++) { + if (!strcmp(vi->name, lookup_name)) + return vi; + } + /* ran to end of table */ + + return NULL; /* var name not found */ +} + +/* simplified integer get interface for common WLC_GET_VAR ioctl handler */ +int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg) +{ + return wlc_iovar_op(wlc, name, NULL, 0, arg, sizeof(s32), IOV_GET, + NULL); +} + +/* simplified integer set interface for common WLC_SET_VAR ioctl handler */ +int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg) +{ + return wlc_iovar_op(wlc, name, NULL, 0, (void *)&arg, sizeof(arg), + IOV_SET, NULL); +} + +/* simplified s8 get interface for common WLC_GET_VAR ioctl handler */ +int wlc_iovar_gets8(struct wlc_info *wlc, const char *name, s8 *arg) +{ + int iovar_int; + int err; + + err = + wlc_iovar_op(wlc, name, NULL, 0, &iovar_int, sizeof(iovar_int), + IOV_GET, NULL); + if (!err) + *arg = (s8) iovar_int; + + return err; +} + +/* + * register iovar table, watchdog and down handlers. + * calling function must keep 'iovars' until wlc_module_unregister is called. + * 'iovar' must have the last entry's name field being NULL as terminator. + */ +int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, + const char *name, void *hdl, iovar_fn_t i_fn, + watchdog_fn_t w_fn, down_fn_t d_fn) +{ + struct wlc_info *wlc = (struct wlc_info *) pub->wlc; + int i; + + ASSERT(name != NULL); + ASSERT(i_fn != NULL || w_fn != NULL || d_fn != NULL); + + /* find an empty entry and just add, no duplication check! */ + for (i = 0; i < WLC_MAXMODULES; i++) { + if (wlc->modulecb[i].name[0] == '\0') { + strncpy(wlc->modulecb[i].name, name, + sizeof(wlc->modulecb[i].name) - 1); + wlc->modulecb[i].iovars = iovars; + wlc->modulecb[i].hdl = hdl; + wlc->modulecb[i].iovar_fn = i_fn; + wlc->modulecb[i].watchdog_fn = w_fn; + wlc->modulecb[i].down_fn = d_fn; + return 0; + } + } + + /* it is time to increase the capacity */ + ASSERT(i < WLC_MAXMODULES); + return BCME_NORESOURCE; +} + +/* unregister module callbacks */ +int wlc_module_unregister(struct wlc_pub *pub, const char *name, void *hdl) +{ + struct wlc_info *wlc = (struct wlc_info *) pub->wlc; + int i; + + if (wlc == NULL) + return BCME_NOTFOUND; + + ASSERT(name != NULL); + + for (i = 0; i < WLC_MAXMODULES; i++) { + if (!strcmp(wlc->modulecb[i].name, name) && + (wlc->modulecb[i].hdl == hdl)) { + memset(&wlc->modulecb[i], 0, sizeof(modulecb_t)); + return 0; + } + } + + /* table not found! */ + return BCME_NOTFOUND; +} + +/* Write WME tunable parameters for retransmit/max rate from wlc struct to ucode */ +static void wlc_wme_retries_write(struct wlc_info *wlc) +{ + int ac; + + /* Need clock to do this */ + if (!wlc->clk) + return; + + for (ac = 0; ac < AC_COUNT; ac++) { + wlc_write_shm(wlc, M_AC_TXLMT_ADDR(ac), wlc->wme_retries[ac]); + } +} + +/* Get or set an iovar. The params/p_len pair specifies any additional + * qualifying parameters (e.g. an "element index") for a get, while the + * arg/len pair is the buffer for the value to be set or retrieved. + * Operation (get/set) is specified by the last argument. + * interface context provided by wlcif + * + * All pointers may point into the same buffer. + */ +int +wlc_iovar_op(struct wlc_info *wlc, const char *name, + void *params, int p_len, void *arg, int len, + bool set, struct wlc_if *wlcif) +{ + int err = 0; + int val_size; + const bcm_iovar_t *vi = NULL; + u32 actionid; + int i; + + ASSERT(name != NULL); + + ASSERT(len >= 0); + + /* Get MUST have return space */ + ASSERT(set || (arg && len)); + + ASSERT(!(wlc->pub->hw_off && wlc->pub->up)); + + /* Set does NOT take qualifiers */ + ASSERT(!set || (!params && !p_len)); + + if (!set && (len == sizeof(int)) && + !(IS_ALIGNED((unsigned long)(arg), (uint) sizeof(int)))) { + WL_ERROR("wl%d: %s unaligned get ptr for %s\n", + wlc->pub->unit, __func__, name); + ASSERT(0); + } + + /* find the given iovar name */ + for (i = 0; i < WLC_MAXMODULES; i++) { + if (!wlc->modulecb[i].iovars) + continue; + vi = wlc_iovar_lookup(wlc->modulecb[i].iovars, name); + if (vi) + break; + } + /* iovar name not found */ + if (i >= WLC_MAXMODULES) { + err = BCME_UNSUPPORTED; + goto exit; + } + + /* set up 'params' pointer in case this is a set command so that + * the convenience int and bool code can be common to set and get + */ + if (params == NULL) { + params = arg; + p_len = len; + } + + if (vi->type == IOVT_VOID) + val_size = 0; + else if (vi->type == IOVT_BUFFER) + val_size = len; + else + /* all other types are integer sized */ + val_size = sizeof(int); + + actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); + + /* Do the actual parameter implementation */ + err = wlc->modulecb[i].iovar_fn(wlc->modulecb[i].hdl, vi, actionid, + name, params, p_len, arg, len, val_size, + wlcif); + + exit: + return err; +} + +int +wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, void *arg, int len, + bool set) +{ + struct wlc_info *wlc = (struct wlc_info *) pub->wlc; + int err = 0; + s32 int_val = 0; + + /* check generic condition flags */ + if (set) { + if (((vi->flags & IOVF_SET_DOWN) && wlc->pub->up) || + ((vi->flags & IOVF_SET_UP) && !wlc->pub->up)) { + err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP); + } else if ((vi->flags & IOVF_SET_BAND) + && IS_MBAND_UNLOCKED(wlc)) { + err = BCME_NOTBANDLOCKED; + } else if ((vi->flags & IOVF_SET_CLK) && !wlc->clk) { + err = BCME_NOCLK; + } + } else { + if (((vi->flags & IOVF_GET_DOWN) && wlc->pub->up) || + ((vi->flags & IOVF_GET_UP) && !wlc->pub->up)) { + err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP); + } else if ((vi->flags & IOVF_GET_BAND) + && IS_MBAND_UNLOCKED(wlc)) { + err = BCME_NOTBANDLOCKED; + } else if ((vi->flags & IOVF_GET_CLK) && !wlc->clk) { + err = BCME_NOCLK; + } + } + + if (err) + goto exit; + + /* length check on io buf */ + err = bcm_iovar_lencheck(vi, arg, len, set); + if (err) + goto exit; + + /* On set, check value ranges for integer types */ + if (set) { + switch (vi->type) { + case IOVT_BOOL: + case IOVT_INT8: + case IOVT_INT16: + case IOVT_INT32: + case IOVT_UINT8: + case IOVT_UINT16: + case IOVT_UINT32: + bcopy(arg, &int_val, sizeof(int)); + err = wlc_iovar_rangecheck(wlc, int_val, vi); + break; + } + } + exit: + return err; +} + +/* handler for iovar table wlc_iovars */ +/* + * IMPLEMENTATION NOTE: In order to avoid checking for get/set in each + * iovar case, the switch statement maps the iovar id into separate get + * and set values. If you add a new iovar to the switch you MUST use + * IOV_GVAL and/or IOV_SVAL in the case labels to avoid conflict with + * another case. + * Please use params for additional qualifying parameters. + */ +int +wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, + const char *name, void *params, uint p_len, void *arg, int len, + int val_size, struct wlc_if *wlcif) +{ + struct wlc_info *wlc = hdl; + wlc_bsscfg_t *bsscfg; + int err = 0; + s32 int_val = 0; + s32 int_val2 = 0; + s32 *ret_int_ptr; + bool bool_val; + bool bool_val2; + wlc_bss_info_t *current_bss; + + WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__); + + bsscfg = NULL; + current_bss = NULL; + + err = wlc_iovar_check(wlc->pub, vi, arg, len, IOV_ISSET(actionid)); + if (err != 0) + return err; + + /* convenience int and bool vals for first 8 bytes of buffer */ + if (p_len >= (int)sizeof(int_val)) + bcopy(params, &int_val, sizeof(int_val)); + + if (p_len >= (int)sizeof(int_val) * 2) + bcopy((void *)((unsigned long)params + sizeof(int_val)), &int_val2, + sizeof(int_val)); + + /* convenience int ptr for 4-byte gets (requires int aligned arg) */ + ret_int_ptr = (s32 *) arg; + + bool_val = (int_val != 0) ? true : false; + bool_val2 = (int_val2 != 0) ? true : false; + + WL_TRACE("wl%d: %s: id %d\n", + wlc->pub->unit, __func__, IOV_ID(actionid)); + /* Do the actual parameter implementation */ + switch (actionid) { + + case IOV_GVAL(IOV_QTXPOWER):{ + uint qdbm; + bool override; + + err = wlc_phy_txpower_get(wlc->band->pi, &qdbm, + &override); + if (err != BCME_OK) + return err; + + /* Return qdbm units */ + *ret_int_ptr = + qdbm | (override ? WL_TXPWR_OVERRIDE : 0); + break; + } + + /* As long as override is false, this only sets the *user* targets. + User can twiddle this all he wants with no harm. + wlc_phy_txpower_set() explicitly sets override to false if + not internal or test. + */ + case IOV_SVAL(IOV_QTXPOWER):{ + u8 qdbm; + bool override; + + /* Remove override bit and clip to max qdbm value */ + qdbm = (u8)min_t(u32, (int_val & ~WL_TXPWR_OVERRIDE), 0xff); + /* Extract override setting */ + override = (int_val & WL_TXPWR_OVERRIDE) ? true : false; + err = + wlc_phy_txpower_set(wlc->band->pi, qdbm, override); + break; + } + + case IOV_GVAL(IOV_MPC): + *ret_int_ptr = (s32) wlc->mpc; + break; + + case IOV_SVAL(IOV_MPC): + wlc->mpc = bool_val; + wlc_radio_mpc_upd(wlc); + + break; + + case IOV_GVAL(IOV_BCN_LI_BCN): + *ret_int_ptr = wlc->bcn_li_bcn; + break; + + case IOV_SVAL(IOV_BCN_LI_BCN): + wlc->bcn_li_bcn = (u8) int_val; + if (wlc->pub->up) + wlc_bcn_li_upd(wlc); + break; + + default: + WL_ERROR("wl%d: %s: unsupported\n", wlc->pub->unit, __func__); + err = BCME_UNSUPPORTED; + break; + } + + goto exit; /* avoid unused label warning */ + + exit: + return err; +} + +static int +wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, const bcm_iovar_t *vi) +{ + int err = 0; + u32 min_val = 0; + u32 max_val = 0; + + /* Only ranged integers are checked */ + switch (vi->type) { + case IOVT_INT32: + max_val |= 0x7fffffff; + /* fall through */ + case IOVT_INT16: + max_val |= 0x00007fff; + /* fall through */ + case IOVT_INT8: + max_val |= 0x0000007f; + min_val = ~max_val; + if (vi->flags & IOVF_NTRL) + min_val = 1; + else if (vi->flags & IOVF_WHL) + min_val = 0; + /* Signed values are checked against max_val and min_val */ + if ((s32) val < (s32) min_val + || (s32) val > (s32) max_val) + err = BCME_RANGE; + break; + + case IOVT_UINT32: + max_val |= 0xffffffff; + /* fall through */ + case IOVT_UINT16: + max_val |= 0x0000ffff; + /* fall through */ + case IOVT_UINT8: + max_val |= 0x000000ff; + if (vi->flags & IOVF_NTRL) + min_val = 1; + if ((val < min_val) || (val > max_val)) + err = BCME_RANGE; + break; + } + + return err; +} + +#ifdef BCMDBG +static const char *supr_reason[] = { + "None", "PMQ Entry", "Flush request", + "Previous frag failure", "Channel mismatch", + "Lifetime Expiry", "Underflow" +}; + +static void wlc_print_txs_status(u16 s) +{ + printf("[15:12] %d frame attempts\n", (s & TX_STATUS_FRM_RTX_MASK) >> + TX_STATUS_FRM_RTX_SHIFT); + printf(" [11:8] %d rts attempts\n", (s & TX_STATUS_RTS_RTX_MASK) >> + TX_STATUS_RTS_RTX_SHIFT); + printf(" [7] %d PM mode indicated\n", + ((s & TX_STATUS_PMINDCTD) ? 1 : 0)); + printf(" [6] %d intermediate status\n", + ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0)); + printf(" [5] %d AMPDU\n", (s & TX_STATUS_AMPDU) ? 1 : 0); + printf(" [4:2] %d Frame Suppressed Reason (%s)\n", + ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT), + supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]); + printf(" [1] %d acked\n", ((s & TX_STATUS_ACK_RCV) ? 1 : 0)); +} +#endif /* BCMDBG */ + +void wlc_print_txstatus(tx_status_t *txs) +{ +#if defined(BCMDBG) + u16 s = txs->status; + u16 ackphyrxsh = txs->ackphyrxsh; + + printf("\ntxpkt (MPDU) Complete\n"); + + printf("FrameID: %04x ", txs->frameid); + printf("TxStatus: %04x", s); + printf("\n"); +#ifdef BCMDBG + wlc_print_txs_status(s); +#endif + printf("LastTxTime: %04x ", txs->lasttxtime); + printf("Seq: %04x ", txs->sequence); + printf("PHYTxStatus: %04x ", txs->phyerr); + printf("RxAckRSSI: %04x ", + (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT); + printf("RxAckSQ: %04x", (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); + printf("\n"); +#endif /* defined(BCMDBG) */ +} + +#define MACSTATUPD(name) \ + wlc_ctrupd_cache(macstats.name, &wlc->core->macstat_snapshot->name, &wlc->pub->_cnt->name) + +void wlc_statsupd(struct wlc_info *wlc) +{ + int i; +#ifdef BCMDBG + u16 delta; + u16 rxf0ovfl; + u16 txfunfl[NFIFO]; +#endif /* BCMDBG */ + + /* if driver down, make no sense to update stats */ + if (!wlc->pub->up) + return; + +#ifdef BCMDBG + /* save last rx fifo 0 overflow count */ + rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl; + + /* save last tx fifo underflow count */ + for (i = 0; i < NFIFO; i++) + txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i]; +#endif /* BCMDBG */ + +#ifdef BCMDBG + /* check for rx fifo 0 overflow */ + delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); + if (delta) + WL_ERROR("wl%d: %u rx fifo 0 overflows!\n", + wlc->pub->unit, delta); + + /* check for tx fifo underflows */ + for (i = 0; i < NFIFO; i++) { + delta = + (u16) (wlc->core->macstat_snapshot->txfunfl[i] - + txfunfl[i]); + if (delta) + WL_ERROR("wl%d: %u tx fifo %d underflows!\n", + wlc->pub->unit, delta, i); + } +#endif /* BCMDBG */ + + /* dot11 counter update */ + + WLCNTSET(wlc->pub->_cnt->txrts, + (wlc->pub->_cnt->rxctsucast - + wlc->pub->_cnt->d11cnt_txrts_off)); + WLCNTSET(wlc->pub->_cnt->rxcrc, + (wlc->pub->_cnt->rxbadfcs - wlc->pub->_cnt->d11cnt_rxcrc_off)); + WLCNTSET(wlc->pub->_cnt->txnocts, + ((wlc->pub->_cnt->txrtsfrm - wlc->pub->_cnt->rxctsucast) - + wlc->pub->_cnt->d11cnt_txnocts_off)); + + /* merge counters from dma module */ + for (i = 0; i < NFIFO; i++) { + if (wlc->hw->di[i]) { + WLCNTADD(wlc->pub->_cnt->txnobuf, + (wlc->hw->di[i])->txnobuf); + WLCNTADD(wlc->pub->_cnt->rxnobuf, + (wlc->hw->di[i])->rxnobuf); + WLCNTADD(wlc->pub->_cnt->rxgiant, + (wlc->hw->di[i])->rxgiants); + dma_counterreset(wlc->hw->di[i]); + } + } + + /* + * Aggregate transmit and receive errors that probably resulted + * in the loss of a frame are computed on the fly. + */ + WLCNTSET(wlc->pub->_cnt->txerror, + wlc->pub->_cnt->txnobuf + wlc->pub->_cnt->txnoassoc + + wlc->pub->_cnt->txuflo + wlc->pub->_cnt->txrunt + + wlc->pub->_cnt->dmade + wlc->pub->_cnt->dmada + + wlc->pub->_cnt->dmape); + WLCNTSET(wlc->pub->_cnt->rxerror, + wlc->pub->_cnt->rxoflo + wlc->pub->_cnt->rxnobuf + + wlc->pub->_cnt->rxfragerr + wlc->pub->_cnt->rxrunt + + wlc->pub->_cnt->rxgiant + wlc->pub->_cnt->rxnoscb + + wlc->pub->_cnt->rxbadsrcmac); + for (i = 0; i < NFIFO; i++) + WLCNTADD(wlc->pub->_cnt->rxerror, wlc->pub->_cnt->rxuflo[i]); +} + +bool wlc_chipmatch(u16 vendor, u16 device) +{ + if (vendor != VENDOR_BROADCOM) { + WL_ERROR("wlc_chipmatch: unknown vendor id %04x\n", vendor); + return false; + } + + if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID)) + return true; + + if (device == BCM4313_D11N2G_ID) + return true; + if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID)) + return true; + + WL_ERROR("wlc_chipmatch: unknown device id %04x\n", device); + return false; +} + +#if defined(BCMDBG) +void wlc_print_txdesc(d11txh_t *txh) +{ + u16 mtcl = ltoh16(txh->MacTxControlLow); + u16 mtch = ltoh16(txh->MacTxControlHigh); + u16 mfc = ltoh16(txh->MacFrameControl); + u16 tfest = ltoh16(txh->TxFesTimeNormal); + u16 ptcw = ltoh16(txh->PhyTxControlWord); + u16 ptcw_1 = ltoh16(txh->PhyTxControlWord_1); + u16 ptcw_1_Fbr = ltoh16(txh->PhyTxControlWord_1_Fbr); + u16 ptcw_1_Rts = ltoh16(txh->PhyTxControlWord_1_Rts); + u16 ptcw_1_FbrRts = ltoh16(txh->PhyTxControlWord_1_FbrRts); + u16 mainrates = ltoh16(txh->MainRates); + u16 xtraft = ltoh16(txh->XtraFrameTypes); + u8 *iv = txh->IV; + u8 *ra = txh->TxFrameRA; + u16 tfestfb = ltoh16(txh->TxFesTimeFallback); + u8 *rtspfb = txh->RTSPLCPFallback; + u16 rtsdfb = ltoh16(txh->RTSDurFallback); + u8 *fragpfb = txh->FragPLCPFallback; + u16 fragdfb = ltoh16(txh->FragDurFallback); + u16 mmodelen = ltoh16(txh->MModeLen); + u16 mmodefbrlen = ltoh16(txh->MModeFbrLen); + u16 tfid = ltoh16(txh->TxFrameID); + u16 txs = ltoh16(txh->TxStatus); + u16 mnmpdu = ltoh16(txh->MaxNMpdus); + u16 mabyte = ltoh16(txh->MaxABytes_MRT); + u16 mabyte_f = ltoh16(txh->MaxABytes_FBR); + u16 mmbyte = ltoh16(txh->MinMBytes); + + u8 *rtsph = txh->RTSPhyHeader; + struct ieee80211_rts rts = txh->rts_frame; + char hexbuf[256]; + + /* add plcp header along with txh descriptor */ + prhex("Raw TxDesc + plcp header", (unsigned char *) txh, sizeof(d11txh_t) + 48); + + printf("TxCtlLow: %04x ", mtcl); + printf("TxCtlHigh: %04x ", mtch); + printf("FC: %04x ", mfc); + printf("FES Time: %04x\n", tfest); + printf("PhyCtl: %04x%s ", ptcw, + (ptcw & PHY_TXC_SHORT_HDR) ? " short" : ""); + printf("PhyCtl_1: %04x ", ptcw_1); + printf("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr); + printf("PhyCtl_1_Rts: %04x ", ptcw_1_Rts); + printf("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts); + printf("MainRates: %04x ", mainrates); + printf("XtraFrameTypes: %04x ", xtraft); + printf("\n"); + + bcm_format_hex(hexbuf, iv, sizeof(txh->IV)); + printf("SecIV: %s\n", hexbuf); + bcm_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA)); + printf("RA: %s\n", hexbuf); + + printf("Fb FES Time: %04x ", tfestfb); + bcm_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback)); + printf("RTS PLCP: %s ", hexbuf); + printf("RTS DUR: %04x ", rtsdfb); + bcm_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback)); + printf("PLCP: %s ", hexbuf); + printf("DUR: %04x", fragdfb); + printf("\n"); + + printf("MModeLen: %04x ", mmodelen); + printf("MModeFbrLen: %04x\n", mmodefbrlen); + + printf("FrameID: %04x\n", tfid); + printf("TxStatus: %04x\n", txs); + + printf("MaxNumMpdu: %04x\n", mnmpdu); + printf("MaxAggbyte: %04x\n", mabyte); + printf("MaxAggbyte_fb: %04x\n", mabyte_f); + printf("MinByte: %04x\n", mmbyte); + + bcm_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader)); + printf("RTS PLCP: %s ", hexbuf); + bcm_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame)); + printf("RTS Frame: %s", hexbuf); + printf("\n"); + +} +#endif /* defined(BCMDBG) */ + +#if defined(BCMDBG) +void wlc_print_rxh(d11rxhdr_t *rxh) +{ + u16 len = rxh->RxFrameSize; + u16 phystatus_0 = rxh->PhyRxStatus_0; + u16 phystatus_1 = rxh->PhyRxStatus_1; + u16 phystatus_2 = rxh->PhyRxStatus_2; + u16 phystatus_3 = rxh->PhyRxStatus_3; + u16 macstatus1 = rxh->RxStatus1; + u16 macstatus2 = rxh->RxStatus2; + char flagstr[64]; + char lenbuf[20]; + static const bcm_bit_desc_t macstat_flags[] = { + {RXS_FCSERR, "FCSErr"}, + {RXS_RESPFRAMETX, "Reply"}, + {RXS_PBPRES, "PADDING"}, + {RXS_DECATMPT, "DeCr"}, + {RXS_DECERR, "DeCrErr"}, + {RXS_BCNSENT, "Bcn"}, + {0, NULL} + }; + + prhex("Raw RxDesc", (unsigned char *) rxh, sizeof(d11rxhdr_t)); + + bcm_format_flags(macstat_flags, macstatus1, flagstr, 64); + + snprintf(lenbuf, sizeof(lenbuf), "0x%x", len); + + printf("RxFrameSize: %6s (%d)%s\n", lenbuf, len, + (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : ""); + printf("RxPHYStatus: %04x %04x %04x %04x\n", + phystatus_0, phystatus_1, phystatus_2, phystatus_3); + printf("RxMACStatus: %x %s\n", macstatus1, flagstr); + printf("RXMACaggtype: %x\n", (macstatus2 & RXS_AGGTYPE_MASK)); + printf("RxTSFTime: %04x\n", rxh->RxTSFTime); +} +#endif /* defined(BCMDBG) */ + +#if defined(BCMDBG) +int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len) +{ + uint i, c; + char *p = buf; + char *endp = buf + SSID_FMT_BUF_LEN; + + if (ssid_len > IEEE80211_MAX_SSID_LEN) + ssid_len = IEEE80211_MAX_SSID_LEN; + + for (i = 0; i < ssid_len; i++) { + c = (uint) ssid[i]; + if (c == '\\') { + *p++ = '\\'; + *p++ = '\\'; + } else if (isprint((unsigned char) c)) { + *p++ = (char)c; + } else { + p += snprintf(p, (endp - p), "\\x%02X", c); + } + } + *p = '\0'; + ASSERT(p < endp); + + return (int)(p - buf); +} +#endif /* defined(BCMDBG) */ + +u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate) +{ + return wlc_bmac_rate_shm_offset(wlc->hw, rate); +} + +/* Callback for device removed */ + +/* + * Attempts to queue a packet onto a multiple-precedence queue, + * if necessary evicting a lower precedence packet from the queue. + * + * 'prec' is the precedence number that has already been mapped + * from the packet priority. + * + * Returns true if packet consumed (queued), false if not. + */ +bool BCMFASTPATH +wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, int prec) +{ + return wlc_prec_enq_head(wlc, q, pkt, prec, false); +} + +bool BCMFASTPATH +wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, + int prec, bool head) +{ + struct sk_buff *p; + int eprec = -1; /* precedence to evict from */ + + /* Determine precedence from which to evict packet, if any */ + if (pktq_pfull(q, prec)) + eprec = prec; + else if (pktq_full(q)) { + p = pktq_peek_tail(q, &eprec); + ASSERT(p != NULL); + if (eprec > prec) { + WL_ERROR("%s: Failing: eprec %d > prec %d\n", + __func__, eprec, prec); + return false; + } + } + + /* Evict if needed */ + if (eprec >= 0) { + bool discard_oldest; + + /* Detect queueing to unconfigured precedence */ + ASSERT(!pktq_pempty(q, eprec)); + + discard_oldest = AC_BITMAP_TST(wlc->wme_dp, eprec); + + /* Refuse newer packet unless configured to discard oldest */ + if (eprec == prec && !discard_oldest) { + WL_ERROR("%s: No where to go, prec == %d\n", + __func__, prec); + return false; + } + + /* Evict packet according to discard policy */ + p = discard_oldest ? pktq_pdeq(q, eprec) : pktq_pdeq_tail(q, + eprec); + ASSERT(p != NULL); + + /* Increment wme stats */ + if (WME_ENAB(wlc->pub)) { + WLCNTINCR(wlc->pub->_wme_cnt-> + tx_failed[WME_PRIO2AC(p->priority)].packets); + WLCNTADD(wlc->pub->_wme_cnt-> + tx_failed[WME_PRIO2AC(p->priority)].bytes, + pkttotlen(wlc->osh, p)); + } + + ASSERT(0); + pkt_buf_free_skb(wlc->osh, p, true); + WLCNTINCR(wlc->pub->_cnt->txnobuf); + } + + /* Enqueue */ + if (head) + p = pktq_penq_head(q, prec, pkt); + else + p = pktq_penq(q, prec, pkt); + ASSERT(p != NULL); + + return true; +} + +void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, + uint prec) +{ + struct wlc_info *wlc = (struct wlc_info *) ctx; + wlc_txq_info_t *qi = wlc->active_queue; /* Check me */ + struct pktq *q = &qi->q; + int prio; + + prio = sdu->priority; + + ASSERT(pktq_max(q) >= wlc->pub->tunables->datahiwat); + + if (!wlc_prec_enq(wlc, q, sdu, prec)) { + if (!EDCF_ENAB(wlc->pub) + || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) + WL_ERROR("wl%d: wlc_txq_enq: txq overflow\n", + wlc->pub->unit); + + /* ASSERT(9 == 8); *//* XXX we might hit this condtion in case packet flooding from mac80211 stack */ + pkt_buf_free_skb(wlc->osh, sdu, true); + WLCNTINCR(wlc->pub->_cnt->txnobuf); + } + + /* Check if flow control needs to be turned on after enqueuing the packet + * Don't turn on flow control if EDCF is enabled. Driver would make the decision on what + * to drop instead of relying on stack to make the right decision + */ + if (!EDCF_ENAB(wlc->pub) + || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) { + if (pktq_len(q) >= wlc->pub->tunables->datahiwat) { + wlc_txflowcontrol(wlc, qi, ON, ALLPRIO); + } + } else if (wlc->pub->_priofc) { + if (pktq_plen(q, wlc_prio2prec_map[prio]) >= + wlc->pub->tunables->datahiwat) { + wlc_txflowcontrol(wlc, qi, ON, prio); + } + } +} + +bool BCMFASTPATH +wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, + struct ieee80211_hw *hw) +{ + u8 prio; + uint fifo; + void *pkt; + struct scb *scb = &global_scb; + struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data); + u16 type, fc; + + ASSERT(sdu); + + fc = ltoh16(d11_header->frame_control); + type = (fc & IEEE80211_FCTL_FTYPE); + + /* 802.11 standard requires management traffic to go at highest priority */ + prio = (type == IEEE80211_FTYPE_DATA ? sdu->priority : MAXPRIO); + fifo = prio2fifo[prio]; + + ASSERT((uint) skb_headroom(sdu) >= TXOFF); + ASSERT(!(sdu->cloned)); + ASSERT(!(sdu->next)); + ASSERT(!(sdu->prev)); + ASSERT(fifo < NFIFO); + + pkt = sdu; + if (unlikely + (wlc_d11hdrs_mac80211(wlc, hw, pkt, scb, 0, 1, fifo, 0, NULL, 0))) + return -EINVAL; + wlc_txq_enq(wlc, scb, pkt, WLC_PRIO_TO_PREC(prio)); + wlc_send_q(wlc, wlc->active_queue); + + WLCNTINCR(wlc->pub->_cnt->ieee_tx); + return 0; +} + +void BCMFASTPATH wlc_send_q(struct wlc_info *wlc, wlc_txq_info_t *qi) +{ + struct sk_buff *pkt[DOT11_MAXNUMFRAGS]; + int prec; + u16 prec_map; + int err = 0, i, count; + uint fifo; + struct pktq *q = &qi->q; + struct ieee80211_tx_info *tx_info; + + /* only do work for the active queue */ + if (qi != wlc->active_queue) + return; + + if (in_send_q) + return; + else + in_send_q = true; + + prec_map = wlc->tx_prec_map; + + /* Send all the enq'd pkts that we can. + * Dequeue packets with precedence with empty HW fifo only + */ + while (prec_map && (pkt[0] = pktq_mdeq(q, prec_map, &prec))) { + tx_info = IEEE80211_SKB_CB(pkt[0]); + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { + err = wlc_sendampdu(wlc->ampdu, qi, pkt, prec); + } else { + count = 1; + err = wlc_prep_pdu(wlc, pkt[0], &fifo); + if (!err) { + for (i = 0; i < count; i++) { + wlc_txfifo(wlc, fifo, pkt[i], true, 1); + } + } + } + + if (err == BCME_BUSY) { + pktq_penq_head(q, prec, pkt[0]); + /* If send failed due to any other reason than a change in + * HW FIFO condition, quit. Otherwise, read the new prec_map! + */ + if (prec_map == wlc->tx_prec_map) + break; + prec_map = wlc->tx_prec_map; + } + } + + /* Check if flow control needs to be turned off after sending the packet */ + if (!EDCF_ENAB(wlc->pub) + || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) { + if (wlc_txflowcontrol_prio_isset(wlc, qi, ALLPRIO) + && (pktq_len(q) < wlc->pub->tunables->datahiwat / 2)) { + wlc_txflowcontrol(wlc, qi, OFF, ALLPRIO); + } + } else if (wlc->pub->_priofc) { + int prio; + for (prio = MAXPRIO; prio >= 0; prio--) { + if (wlc_txflowcontrol_prio_isset(wlc, qi, prio) && + (pktq_plen(q, wlc_prio2prec_map[prio]) < + wlc->pub->tunables->datahiwat / 2)) { + wlc_txflowcontrol(wlc, qi, OFF, prio); + } + } + } + in_send_q = false; +} + +/* + * bcmc_fid_generate: + * Generate frame ID for a BCMC packet. The frag field is not used + * for MC frames so is used as part of the sequence number. + */ +static inline u16 +bcmc_fid_generate(struct wlc_info *wlc, wlc_bsscfg_t *bsscfg, d11txh_t *txh) +{ + u16 frameid; + + frameid = ltoh16(txh->TxFrameID) & ~(TXFID_SEQ_MASK | TXFID_QUEUE_MASK); + frameid |= + (((wlc-> + mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) | + TX_BCMC_FIFO; + + return frameid; +} + +void BCMFASTPATH +wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit, + s8 txpktpend) +{ + u16 frameid = INVALIDFID; + d11txh_t *txh; + + ASSERT(fifo < NFIFO); + txh = (d11txh_t *) (p->data); + + /* When a BC/MC frame is being committed to the BCMC fifo via DMA (NOT PIO), update + * ucode or BSS info as appropriate. + */ + if (fifo == TX_BCMC_FIFO) { + frameid = ltoh16(txh->TxFrameID); + + } + + if (WLC_WAR16165(wlc)) + wlc_war16165(wlc, true); + + + /* Bump up pending count for if not using rpc. If rpc is used, this will be handled + * in wlc_bmac_txfifo() + */ + if (commit) { + TXPKTPENDINC(wlc, fifo, txpktpend); + WL_TRACE("wlc_txfifo, pktpend inc %d to %d\n", + txpktpend, TXPKTPENDGET(wlc, fifo)); + } + + /* Commit BCMC sequence number in the SHM frame ID location */ + if (frameid != INVALIDFID) + BCMCFID(wlc, frameid); + + if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) { + WL_ERROR("wlc_txfifo: fatal, toss frames !!!\n"); + } +} + +static u16 +wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, uint length) +{ + u16 usec = 0; + uint mac_rate = RSPEC2RATE(rspec); + uint nsyms; + + if (IS_MCS(rspec)) { + /* not supported yet */ + ASSERT(0); + } else if (IS_OFDM(rspec)) { + /* nsyms = Ceiling(Nbits / (Nbits/sym)) + * + * Nbits = length * 8 + * Nbits/sym = Mbps * 4 = mac_rate * 2 + */ + nsyms = CEIL((length * 8), (mac_rate * 2)); + + /* usec = symbols * usec/symbol */ + usec = (u16) (nsyms * APHY_SYMBOL_TIME); + return usec; + } else { + switch (mac_rate) { + case WLC_RATE_1M: + usec = length << 3; + break; + case WLC_RATE_2M: + usec = length << 2; + break; + case WLC_RATE_5M5: + usec = (length << 4) / 11; + break; + case WLC_RATE_11M: + usec = (length << 3) / 11; + break; + default: + WL_ERROR("wl%d: wlc_compute_airtime: unsupported rspec 0x%x\n", + wlc->pub->unit, rspec); + ASSERT((const char *)"Bad phy_rate" == NULL); + break; + } + } + + return usec; +} + +void BCMFASTPATH +wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rspec, uint length, u8 *plcp) +{ + if (IS_MCS(rspec)) { + wlc_compute_mimo_plcp(rspec, length, plcp); + } else if (IS_OFDM(rspec)) { + wlc_compute_ofdm_plcp(rspec, length, plcp); + } else { + wlc_compute_cck_plcp(rspec, length, plcp); + } + return; +} + +/* Rate: 802.11 rate code, length: PSDU length in octets */ +static void wlc_compute_mimo_plcp(ratespec_t rspec, uint length, u8 *plcp) +{ + u8 mcs = (u8) (rspec & RSPEC_RATE_MASK); + ASSERT(IS_MCS(rspec)); + plcp[0] = mcs; + if (RSPEC_IS40MHZ(rspec) || (mcs == 32)) + plcp[0] |= MIMO_PLCP_40MHZ; + WLC_SET_MIMO_PLCP_LEN(plcp, length); + plcp[3] = RSPEC_MIMOPLCP3(rspec); /* rspec already holds this byte */ + plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */ + plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */ + plcp[5] = 0; +} + +/* Rate: 802.11 rate code, length: PSDU length in octets */ +static void BCMFASTPATH +wlc_compute_ofdm_plcp(ratespec_t rspec, u32 length, u8 *plcp) +{ + u8 rate_signal; + u32 tmp = 0; + int rate = RSPEC2RATE(rspec); + + ASSERT(IS_OFDM(rspec)); + + /* encode rate per 802.11a-1999 sec 17.3.4.1, with lsb transmitted first */ + rate_signal = rate_info[rate] & RATE_MASK; + ASSERT(rate_signal != 0); + + memset(plcp, 0, D11_PHY_HDR_LEN); + D11A_PHY_HDR_SRATE((ofdm_phy_hdr_t *) plcp, rate_signal); + + tmp = (length & 0xfff) << 5; + plcp[2] |= (tmp >> 16) & 0xff; + plcp[1] |= (tmp >> 8) & 0xff; + plcp[0] |= tmp & 0xff; + + return; +} + +/* + * Compute PLCP, but only requires actual rate and length of pkt. + * Rate is given in the driver standard multiple of 500 kbps. + * le is set for 11 Mbps rate if necessary. + * Broken out for PRQ. + */ + +static void wlc_cck_plcp_set(int rate_500, uint length, u8 *plcp) +{ + u16 usec = 0; + u8 le = 0; + + switch (rate_500) { + case WLC_RATE_1M: + usec = length << 3; + break; + case WLC_RATE_2M: + usec = length << 2; + break; + case WLC_RATE_5M5: + usec = (length << 4) / 11; + if ((length << 4) - (usec * 11) > 0) + usec++; + break; + case WLC_RATE_11M: + usec = (length << 3) / 11; + if ((length << 3) - (usec * 11) > 0) { + usec++; + if ((usec * 11) - (length << 3) >= 8) + le = D11B_PLCP_SIGNAL_LE; + } + break; + + default: + WL_ERROR("wlc_cck_plcp_set: unsupported rate %d\n", rate_500); + rate_500 = WLC_RATE_1M; + usec = length << 3; + break; + } + /* PLCP signal byte */ + plcp[0] = rate_500 * 5; /* r (500kbps) * 5 == r (100kbps) */ + /* PLCP service byte */ + plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED); + /* PLCP length u16, little endian */ + plcp[2] = usec & 0xff; + plcp[3] = (usec >> 8) & 0xff; + /* PLCP CRC16 */ + plcp[4] = 0; + plcp[5] = 0; +} + +/* Rate: 802.11 rate code, length: PSDU length in octets */ +static void wlc_compute_cck_plcp(ratespec_t rspec, uint length, u8 *plcp) +{ + int rate = RSPEC2RATE(rspec); + + ASSERT(IS_CCK(rspec)); + + wlc_cck_plcp_set(rate, length, plcp); +} + +/* wlc_compute_frame_dur() + * + * Calculate the 802.11 MAC header DUR field for MPDU + * DUR for a single frame = 1 SIFS + 1 ACK + * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time + * + * rate MPDU rate in unit of 500kbps + * next_frag_len next MPDU length in bytes + * preamble_type use short/GF or long/MM PLCP header + */ +static u16 BCMFASTPATH +wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type, + uint next_frag_len) +{ + u16 dur, sifs; + + sifs = SIFS(wlc->band); + + dur = sifs; + dur += (u16) wlc_calc_ack_time(wlc, rate, preamble_type); + + if (next_frag_len) { + /* Double the current DUR to get 2 SIFS + 2 ACKs */ + dur *= 2; + /* add another SIFS and the frag time */ + dur += sifs; + dur += + (u16) wlc_calc_frame_time(wlc, rate, preamble_type, + next_frag_len); + } + return dur; +} + +/* wlc_compute_rtscts_dur() + * + * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame + * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK + * DUR for CTS-TO-SELF w/ frame = 2 SIFS + next frame time + 1 ACK + * + * cts cts-to-self or rts/cts + * rts_rate rts or cts rate in unit of 500kbps + * rate next MPDU rate in unit of 500kbps + * frame_len next MPDU frame length in bytes + */ +u16 BCMFASTPATH +wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, ratespec_t rts_rate, + ratespec_t frame_rate, u8 rts_preamble_type, + u8 frame_preamble_type, uint frame_len, bool ba) +{ + u16 dur, sifs; + + sifs = SIFS(wlc->band); + + if (!cts_only) { /* RTS/CTS */ + dur = 3 * sifs; + dur += + (u16) wlc_calc_cts_time(wlc, rts_rate, + rts_preamble_type); + } else { /* CTS-TO-SELF */ + dur = 2 * sifs; + } + + dur += + (u16) wlc_calc_frame_time(wlc, frame_rate, frame_preamble_type, + frame_len); + if (ba) + dur += + (u16) wlc_calc_ba_time(wlc, frame_rate, + WLC_SHORT_PREAMBLE); + else + dur += + (u16) wlc_calc_ack_time(wlc, frame_rate, + frame_preamble_type); + return dur; +} + +static bool wlc_phy_rspec_check(struct wlc_info *wlc, u16 bw, ratespec_t rspec) +{ + if (IS_MCS(rspec)) { + uint mcs = rspec & RSPEC_RATE_MASK; + + if (mcs < 8) { + ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM); + } else if ((mcs >= 8) && (mcs <= 23)) { + ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SDM); + } else if (mcs == 32) { + ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM); + ASSERT(bw == PHY_TXC1_BW_40MHZ_DUP); + } + } else if (IS_OFDM(rspec)) { + ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_STBC); + } else { + ASSERT(IS_CCK(rspec)); + + ASSERT((bw == PHY_TXC1_BW_20MHZ) + || (bw == PHY_TXC1_BW_20MHZ_UP)); + ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SISO); + } + + return true; +} + +u16 BCMFASTPATH wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec) +{ + u16 phyctl1 = 0; + u16 bw; + + if (WLCISLCNPHY(wlc->band)) { + bw = PHY_TXC1_BW_20MHZ; + } else { + bw = RSPEC_GET_BW(rspec); + /* 10Mhz is not supported yet */ + if (bw < PHY_TXC1_BW_20MHZ) { + WL_ERROR("wlc_phytxctl1_calc: bw %d is not supported yet, set to 20L\n", + bw); + bw = PHY_TXC1_BW_20MHZ; + } + + wlc_phy_rspec_check(wlc, bw, rspec); + } + + if (IS_MCS(rspec)) { + uint mcs = rspec & RSPEC_RATE_MASK; + + /* bw, stf, coding-type is part of RSPEC_PHYTXBYTE2 returns */ + phyctl1 = RSPEC_PHYTXBYTE2(rspec); + /* set the upper byte of phyctl1 */ + phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8); + } else if (IS_CCK(rspec) && !WLCISLCNPHY(wlc->band) + && !WLCISSSLPNPHY(wlc->band)) { + /* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */ + /* Eventually MIMOPHY would also be converted to this format */ + /* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */ + phyctl1 = (bw | (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT)); + } else { /* legacy OFDM/CCK */ + s16 phycfg; + /* get the phyctl byte from rate phycfg table */ + phycfg = wlc_rate_legacy_phyctl(RSPEC2RATE(rspec)); + if (phycfg == -1) { + WL_ERROR("wlc_phytxctl1_calc: wrong legacy OFDM/CCK rate\n"); + ASSERT(0); + phycfg = 0; + } + /* set the upper byte of phyctl1 */ + phyctl1 = + (bw | (phycfg << 8) | + (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT)); + } + +#ifdef BCMDBG + /* phy clock must support 40Mhz if tx descriptor uses it */ + if ((phyctl1 & PHY_TXC1_BW_MASK) >= PHY_TXC1_BW_40MHZ) { + ASSERT(CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ); + ASSERT(wlc->chanspec == wlc_phy_chanspec_get(wlc->band->pi)); + } +#endif /* BCMDBG */ + return phyctl1; +} + +ratespec_t BCMFASTPATH +wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, bool use_rspec, + u16 mimo_ctlchbw) +{ + ratespec_t rts_rspec = 0; + + if (use_rspec) { + /* use frame rate as rts rate */ + rts_rspec = rspec; + + } else if (wlc->band->gmode && wlc->protection->_g && !IS_CCK(rspec)) { + /* Use 11Mbps as the g protection RTS target rate and fallback. + * Use the WLC_BASIC_RATE() lookup to find the best basic rate under the + * target in case 11 Mbps is not Basic. + * 6 and 9 Mbps are not usually selected by rate selection, but even + * if the OFDM rate we are protecting is 6 or 9 Mbps, 11 is more robust. + */ + rts_rspec = WLC_BASIC_RATE(wlc, WLC_RATE_11M); + } else { + /* calculate RTS rate and fallback rate based on the frame rate + * RTS must be sent at a basic rate since it is a + * control frame, sec 9.6 of 802.11 spec + */ + rts_rspec = WLC_BASIC_RATE(wlc, rspec); + } + + if (WLC_PHY_11N_CAP(wlc->band)) { + /* set rts txbw to correct side band */ + rts_rspec &= ~RSPEC_BW_MASK; + + /* if rspec/rspec_fallback is 40MHz, then send RTS on both 20MHz channel + * (DUP), otherwise send RTS on control channel + */ + if (RSPEC_IS40MHZ(rspec) && !IS_CCK(rts_rspec)) + rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT); + else + rts_rspec |= (mimo_ctlchbw << RSPEC_BW_SHIFT); + + /* pick siso/cdd as default for ofdm */ + if (IS_OFDM(rts_rspec)) { + rts_rspec &= ~RSPEC_STF_MASK; + rts_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT); + } + } + return rts_rspec; +} + +/* + * Add d11txh_t, cck_phy_hdr_t. + * + * 'p' data must start with 802.11 MAC header + * 'p' must allow enough bytes of local headers to be "pushed" onto the packet + * + * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes) + * + */ +static u16 BCMFASTPATH +wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, + struct sk_buff *p, struct scb *scb, uint frag, + uint nfrags, uint queue, uint next_frag_len, + wsec_key_t *key, ratespec_t rspec_override) +{ + struct ieee80211_hdr *h; + d11txh_t *txh; + u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN]; + struct osl_info *osh; + int len, phylen, rts_phylen; + u16 fc, type, frameid, mch, phyctl, xfts, mainrates; + u16 seq = 0, mcl = 0, status = 0; + ratespec_t rspec[2] = { WLC_RATE_1M, WLC_RATE_1M }, rts_rspec[2] = { + WLC_RATE_1M, WLC_RATE_1M}; + bool use_rts = false; + bool use_cts = false; + bool use_rifs = false; + bool short_preamble[2] = { false, false }; + u8 preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE }; + u8 rts_preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE }; + u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN]; + struct ieee80211_rts *rts = NULL; + bool qos; + uint ac; + u32 rate_val[2]; + bool hwtkmic = false; + u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; +#ifdef WLANTSEL +#define ANTCFG_NONE 0xFF + u8 antcfg = ANTCFG_NONE; + u8 fbantcfg = ANTCFG_NONE; +#endif + uint phyctl1_stf = 0; + u16 durid = 0; + struct ieee80211_tx_rate *txrate[2]; + int k; + struct ieee80211_tx_info *tx_info; + bool is_mcs[2]; + u16 mimo_txbw; + u8 mimo_preamble_type; + + frameid = 0; + + ASSERT(queue < NFIFO); + + osh = wlc->osh; + + /* locate 802.11 MAC header */ + h = (struct ieee80211_hdr *)(p->data); + fc = ltoh16(h->frame_control); + type = (fc & IEEE80211_FCTL_FTYPE); + + qos = (type == IEEE80211_FTYPE_DATA && + FC_SUBTYPE_ANY_QOS(fc)); + + /* compute length of frame in bytes for use in PLCP computations */ + len = pkttotlen(osh, p); + phylen = len + FCS_LEN; + + /* If WEP enabled, add room in phylen for the additional bytes of + * ICV which MAC generates. We do NOT add the additional bytes to + * the packet itself, thus phylen = packet length + ICV_LEN + FCS_LEN + * in this case + */ + if (key) { + phylen += key->icv_len; + } + + /* Get tx_info */ + tx_info = IEEE80211_SKB_CB(p); + ASSERT(tx_info); + + /* add PLCP */ + plcp = skb_push(p, D11_PHY_HDR_LEN); + + /* add Broadcom tx descriptor header */ + txh = (d11txh_t *) skb_push(p, D11_TXH_LEN); + memset((char *)txh, 0, D11_TXH_LEN); + + /* setup frameid */ + if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { + /* non-AP STA should never use BCMC queue */ + ASSERT(queue != TX_BCMC_FIFO); + if (queue == TX_BCMC_FIFO) { + WL_ERROR("wl%d: %s: ASSERT queue == TX_BCMC!\n", + WLCWLUNIT(wlc), __func__); + frameid = bcmc_fid_generate(wlc, NULL, txh); + } else { + /* Increment the counter for first fragment */ + if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) { + SCB_SEQNUM(scb, p->priority)++; + } + + /* extract fragment number from frame first */ + seq = ltoh16(seq) & FRAGNUM_MASK; + seq |= (SCB_SEQNUM(scb, p->priority) << SEQNUM_SHIFT); + h->seq_ctrl = htol16(seq); + + frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) | + (queue & TXFID_QUEUE_MASK); + } + } + frameid |= queue & TXFID_QUEUE_MASK; + + /* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */ + if (SCB_PS(scb) || ((fc & FC_KIND_MASK) == FC_BEACON)) + mcl |= TXC_IGNOREPMQ; + + ASSERT(hw->max_rates <= IEEE80211_TX_MAX_RATES); + ASSERT(hw->max_rates == 2); + + txrate[0] = tx_info->control.rates; + txrate[1] = txrate[0] + 1; + + ASSERT(txrate[0]->idx >= 0); + /* if rate control algorithm didn't give us a fallback rate, use the primary rate */ + if (txrate[1]->idx < 0) { + txrate[1] = txrate[0]; + } + + for (k = 0; k < hw->max_rates; k++) { + is_mcs[k] = + txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false; + if (!is_mcs[k]) { + ASSERT(!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)); + if ((txrate[k]->idx >= 0) + && (txrate[k]->idx < + hw->wiphy->bands[tx_info->band]->n_bitrates)) { + rate_val[k] = + hw->wiphy->bands[tx_info->band]-> + bitrates[txrate[k]->idx].hw_value; + short_preamble[k] = + txrate[k]-> + flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ? + true : false; + } else { + ASSERT((txrate[k]->idx >= 0) && + (txrate[k]->idx < + hw->wiphy->bands[tx_info->band]-> + n_bitrates)); + rate_val[k] = WLC_RATE_1M; + } + } else { + rate_val[k] = txrate[k]->idx; + } + /* Currently only support same setting for primay and fallback rates. + * Unify flags for each rate into a single value for the frame + */ + use_rts |= + txrate[k]-> + flags & IEEE80211_TX_RC_USE_RTS_CTS ? true : false; + use_cts |= + txrate[k]-> + flags & IEEE80211_TX_RC_USE_CTS_PROTECT ? true : false; + + if (is_mcs[k]) + rate_val[k] |= NRATE_MCS_INUSE; + + rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band, rate_val[k]); + + /* (1) RATE: determine and validate primary rate and fallback rates */ + if (!RSPEC_ACTIVE(rspec[k])) { + ASSERT(RSPEC_ACTIVE(rspec[k])); + rspec[k] = WLC_RATE_1M; + } else { + if (WLANTSEL_ENAB(wlc) && + !is_multicast_ether_addr(h->addr1)) { + /* set tx antenna config */ + wlc_antsel_antcfg_get(wlc->asi, false, false, 0, + 0, &antcfg, &fbantcfg); + } + } + } + + phyctl1_stf = wlc->stf->ss_opmode; + + if (N_ENAB(wlc->pub)) { + for (k = 0; k < hw->max_rates; k++) { + /* apply siso/cdd to single stream mcs's or ofdm if rspec is auto selected */ + if (((IS_MCS(rspec[k]) && + IS_SINGLE_STREAM(rspec[k] & RSPEC_RATE_MASK)) || + IS_OFDM(rspec[k])) + && ((rspec[k] & RSPEC_OVERRIDE_MCS_ONLY) + || !(rspec[k] & RSPEC_OVERRIDE))) { + rspec[k] &= ~(RSPEC_STF_MASK | RSPEC_STC_MASK); + + /* For SISO MCS use STBC if possible */ + if (IS_MCS(rspec[k]) + && WLC_STF_SS_STBC_TX(wlc, scb)) { + u8 stc; + + ASSERT(WLC_STBC_CAP_PHY(wlc)); + stc = 1; /* Nss for single stream is always 1 */ + rspec[k] |= + (PHY_TXC1_MODE_STBC << + RSPEC_STF_SHIFT) | (stc << + RSPEC_STC_SHIFT); + } else + rspec[k] |= + (phyctl1_stf << RSPEC_STF_SHIFT); + } + + /* Is the phy configured to use 40MHZ frames? If so then pick the desired txbw */ + if (CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ) { + /* default txbw is 20in40 SB */ + mimo_ctlchbw = mimo_txbw = + CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC) + ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; + + if (IS_MCS(rspec[k])) { + /* mcs 32 must be 40b/w DUP */ + if ((rspec[k] & RSPEC_RATE_MASK) == 32) { + mimo_txbw = + PHY_TXC1_BW_40MHZ_DUP; + /* use override */ + } else if (wlc->mimo_40txbw != AUTO) + mimo_txbw = wlc->mimo_40txbw; + /* else check if dst is using 40 Mhz */ + else if (scb->flags & SCB_IS40) + mimo_txbw = PHY_TXC1_BW_40MHZ; + } else if (IS_OFDM(rspec[k])) { + if (wlc->ofdm_40txbw != AUTO) + mimo_txbw = wlc->ofdm_40txbw; + } else { + ASSERT(IS_CCK(rspec[k])); + if (wlc->cck_40txbw != AUTO) + mimo_txbw = wlc->cck_40txbw; + } + } else { + /* mcs32 is 40 b/w only. + * This is possible for probe packets on a STA during SCAN + */ + if ((rspec[k] & RSPEC_RATE_MASK) == 32) { + /* mcs 0 */ + rspec[k] = RSPEC_MIMORATE; + } + mimo_txbw = PHY_TXC1_BW_20MHZ; + } + + /* Set channel width */ + rspec[k] &= ~RSPEC_BW_MASK; + if ((k == 0) || ((k > 0) && IS_MCS(rspec[k]))) + rspec[k] |= (mimo_txbw << RSPEC_BW_SHIFT); + else + rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT); + + /* Set Short GI */ +#ifdef NOSGIYET + if (IS_MCS(rspec[k]) + && (txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI)) + rspec[k] |= RSPEC_SHORT_GI; + else if (!(txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI)) + rspec[k] &= ~RSPEC_SHORT_GI; +#else + rspec[k] &= ~RSPEC_SHORT_GI; +#endif + + mimo_preamble_type = WLC_MM_PREAMBLE; + if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD) + mimo_preamble_type = WLC_GF_PREAMBLE; + + if ((txrate[k]->flags & IEEE80211_TX_RC_MCS) + && (!IS_MCS(rspec[k]))) { + WL_ERROR("wl%d: %s: IEEE80211_TX_RC_MCS != IS_MCS(rspec)\n", + WLCWLUNIT(wlc), __func__); + ASSERT(0 && "Rate mismatch"); + } + + if (IS_MCS(rspec[k])) { + preamble_type[k] = mimo_preamble_type; + + /* if SGI is selected, then forced mm for single stream */ + if ((rspec[k] & RSPEC_SHORT_GI) + && IS_SINGLE_STREAM(rspec[k] & + RSPEC_RATE_MASK)) { + preamble_type[k] = WLC_MM_PREAMBLE; + } + } + + /* mimo bw field MUST now be valid in the rspec (it affects duration calculations) */ + ASSERT(VALID_RATE_DBG(wlc, rspec[0])); + + /* should be better conditionalized */ + if (!IS_MCS(rspec[0]) + && (tx_info->control.rates[0]. + flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)) + preamble_type[k] = WLC_SHORT_PREAMBLE; + + ASSERT(!IS_MCS(rspec[0]) + || WLC_IS_MIMO_PREAMBLE(preamble_type[k])); + } + } else { + for (k = 0; k < hw->max_rates; k++) { + /* Set ctrlchbw as 20Mhz */ + ASSERT(!IS_MCS(rspec[k])); + rspec[k] &= ~RSPEC_BW_MASK; + rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT); + + /* for nphy, stf of ofdm frames must follow policies */ + if (WLCISNPHY(wlc->band) && IS_OFDM(rspec[k])) { + rspec[k] &= ~RSPEC_STF_MASK; + rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT; + } + } + } + + /* Reset these for use with AMPDU's */ + txrate[0]->count = 0; + txrate[1]->count = 0; + + /* (3) PLCP: determine PLCP header and MAC duration, fill d11txh_t */ + wlc_compute_plcp(wlc, rspec[0], phylen, plcp); + wlc_compute_plcp(wlc, rspec[1], phylen, plcp_fallback); + bcopy(plcp_fallback, (char *)&txh->FragPLCPFallback, + sizeof(txh->FragPLCPFallback)); + + /* Length field now put in CCK FBR CRC field */ + if (IS_CCK(rspec[1])) { + txh->FragPLCPFallback[4] = phylen & 0xff; + txh->FragPLCPFallback[5] = (phylen & 0xff00) >> 8; + } + + /* MIMO-RATE: need validation ?? */ + mainrates = + IS_OFDM(rspec[0]) ? D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) plcp) : + plcp[0]; + + /* DUR field for main rate */ + if ((fc != FC_PS_POLL) && + !is_multicast_ether_addr(h->addr1) && !use_rifs) { + durid = + wlc_compute_frame_dur(wlc, rspec[0], preamble_type[0], + next_frag_len); + h->duration_id = htol16(durid); + } else if (use_rifs) { + /* NAV protect to end of next max packet size */ + durid = + (u16) wlc_calc_frame_time(wlc, rspec[0], + preamble_type[0], + DOT11_MAX_FRAG_LEN); + durid += RIFS_11N_TIME; + h->duration_id = htol16(durid); + } + + /* DUR field for fallback rate */ + if (fc == FC_PS_POLL) + txh->FragDurFallback = h->duration_id; + else if (is_multicast_ether_addr(h->addr1) || use_rifs) + txh->FragDurFallback = 0; + else { + durid = wlc_compute_frame_dur(wlc, rspec[1], + preamble_type[1], next_frag_len); + txh->FragDurFallback = htol16(durid); + } + + /* (4) MAC-HDR: MacTxControlLow */ + if (frag == 0) + mcl |= TXC_STARTMSDU; + + if (!is_multicast_ether_addr(h->addr1)) + mcl |= TXC_IMMEDACK; + + if (BAND_5G(wlc->band->bandtype)) + mcl |= TXC_FREQBAND_5G; + + if (CHSPEC_IS40(WLC_BAND_PI_RADIO_CHANSPEC)) + mcl |= TXC_BW_40; + + /* set AMIC bit if using hardware TKIP MIC */ + if (hwtkmic) + mcl |= TXC_AMIC; + + txh->MacTxControlLow = htol16(mcl); + + /* MacTxControlHigh */ + mch = 0; + + /* Set fallback rate preamble type */ + if ((preamble_type[1] == WLC_SHORT_PREAMBLE) || + (preamble_type[1] == WLC_GF_PREAMBLE)) { + ASSERT((preamble_type[1] == WLC_GF_PREAMBLE) || + (!IS_MCS(rspec[1]))); + if (RSPEC2RATE(rspec[1]) != WLC_RATE_1M) + mch |= TXC_PREAMBLE_DATA_FB_SHORT; + } + + /* MacFrameControl */ + bcopy((char *)&h->frame_control, (char *)&txh->MacFrameControl, + sizeof(u16)); + txh->TxFesTimeNormal = htol16(0); + + txh->TxFesTimeFallback = htol16(0); + + /* TxFrameRA */ + bcopy((char *)&h->addr1, (char *)&txh->TxFrameRA, ETH_ALEN); + + /* TxFrameID */ + txh->TxFrameID = htol16(frameid); + + /* TxStatus, Note the case of recreating the first frag of a suppressed frame + * then we may need to reset the retry cnt's via the status reg + */ + txh->TxStatus = htol16(status); + + if (D11REV_GE(wlc->pub->corerev, 16)) { + /* extra fields for ucode AMPDU aggregation, the new fields are added to + * the END of previous structure so that it's compatible in driver. + * In old rev ucode, these fields should be ignored + */ + txh->MaxNMpdus = htol16(0); + txh->MaxABytes_MRT = htol16(0); + txh->MaxABytes_FBR = htol16(0); + txh->MinMBytes = htol16(0); + } + + /* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration, furnish d11txh_t */ + /* RTS PLCP header and RTS frame */ + if (use_rts || use_cts) { + if (use_rts && use_cts) + use_cts = false; + + for (k = 0; k < 2; k++) { + rts_rspec[k] = wlc_rspec_to_rts_rspec(wlc, rspec[k], + false, + mimo_ctlchbw); + } + + if (!IS_OFDM(rts_rspec[0]) && + !((RSPEC2RATE(rts_rspec[0]) == WLC_RATE_1M) || + (wlc->PLCPHdr_override == WLC_PLCP_LONG))) { + rts_preamble_type[0] = WLC_SHORT_PREAMBLE; + mch |= TXC_PREAMBLE_RTS_MAIN_SHORT; + } + + if (!IS_OFDM(rts_rspec[1]) && + !((RSPEC2RATE(rts_rspec[1]) == WLC_RATE_1M) || + (wlc->PLCPHdr_override == WLC_PLCP_LONG))) { + rts_preamble_type[1] = WLC_SHORT_PREAMBLE; + mch |= TXC_PREAMBLE_RTS_FB_SHORT; + } + + /* RTS/CTS additions to MacTxControlLow */ + if (use_cts) { + txh->MacTxControlLow |= htol16(TXC_SENDCTS); + } else { + txh->MacTxControlLow |= htol16(TXC_SENDRTS); + txh->MacTxControlLow |= htol16(TXC_LONGFRAME); + } + + /* RTS PLCP header */ + ASSERT(IS_ALIGNED((unsigned long)txh->RTSPhyHeader, sizeof(u16))); + rts_plcp = txh->RTSPhyHeader; + if (use_cts) + rts_phylen = DOT11_CTS_LEN + FCS_LEN; + else + rts_phylen = DOT11_RTS_LEN + FCS_LEN; + + wlc_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp); + + /* fallback rate version of RTS PLCP header */ + wlc_compute_plcp(wlc, rts_rspec[1], rts_phylen, + rts_plcp_fallback); + bcopy(rts_plcp_fallback, (char *)&txh->RTSPLCPFallback, + sizeof(txh->RTSPLCPFallback)); + + /* RTS frame fields... */ + rts = (struct ieee80211_rts *)&txh->rts_frame; + + durid = wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec[0], + rspec[0], rts_preamble_type[0], + preamble_type[0], phylen, false); + rts->duration = htol16(durid); + /* fallback rate version of RTS DUR field */ + durid = wlc_compute_rtscts_dur(wlc, use_cts, + rts_rspec[1], rspec[1], + rts_preamble_type[1], + preamble_type[1], phylen, false); + txh->RTSDurFallback = htol16(durid); + + if (use_cts) { + rts->frame_control = htol16(FC_CTS); + bcopy((char *)&h->addr2, (char *)&rts->ra, ETH_ALEN); + } else { + rts->frame_control = htol16((u16) FC_RTS); + bcopy((char *)&h->addr1, (char *)&rts->ra, + 2 * ETH_ALEN); + } + + /* mainrate + * low 8 bits: main frag rate/mcs, + * high 8 bits: rts/cts rate/mcs + */ + mainrates |= (IS_OFDM(rts_rspec[0]) ? + D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) rts_plcp) : + rts_plcp[0]) << 8; + } else { + memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN); + memset((char *)&txh->rts_frame, 0, + sizeof(struct ieee80211_rts)); + memset((char *)txh->RTSPLCPFallback, 0, + sizeof(txh->RTSPLCPFallback)); + txh->RTSDurFallback = 0; + } + +#ifdef SUPPORT_40MHZ + /* add null delimiter count */ + if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && IS_MCS(rspec)) { + txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = + wlc_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen); + } +#endif + + /* Now that RTS/RTS FB preamble types are updated, write the final value */ + txh->MacTxControlHigh = htol16(mch); + + /* MainRates (both the rts and frag plcp rates have been calculated now) */ + txh->MainRates = htol16(mainrates); + + /* XtraFrameTypes */ + xfts = FRAMETYPE(rspec[1], wlc->mimoft); + xfts |= (FRAMETYPE(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT); + xfts |= (FRAMETYPE(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT); + xfts |= + CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC) << XFTS_CHANNEL_SHIFT; + txh->XtraFrameTypes = htol16(xfts); + + /* PhyTxControlWord */ + phyctl = FRAMETYPE(rspec[0], wlc->mimoft); + if ((preamble_type[0] == WLC_SHORT_PREAMBLE) || + (preamble_type[0] == WLC_GF_PREAMBLE)) { + ASSERT((preamble_type[0] == WLC_GF_PREAMBLE) + || !IS_MCS(rspec[0])); + if (RSPEC2RATE(rspec[0]) != WLC_RATE_1M) + phyctl |= PHY_TXC_SHORT_HDR; + WLCNTINCR(wlc->pub->_cnt->txprshort); + } + + /* phytxant is properly bit shifted */ + phyctl |= wlc_stf_d11hdrs_phyctl_txant(wlc, rspec[0]); + txh->PhyTxControlWord = htol16(phyctl); + + /* PhyTxControlWord_1 */ + if (WLC_PHY_11N_CAP(wlc->band)) { + u16 phyctl1 = 0; + + phyctl1 = wlc_phytxctl1_calc(wlc, rspec[0]); + txh->PhyTxControlWord_1 = htol16(phyctl1); + phyctl1 = wlc_phytxctl1_calc(wlc, rspec[1]); + txh->PhyTxControlWord_1_Fbr = htol16(phyctl1); + + if (use_rts || use_cts) { + phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[0]); + txh->PhyTxControlWord_1_Rts = htol16(phyctl1); + phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[1]); + txh->PhyTxControlWord_1_FbrRts = htol16(phyctl1); + } + + /* + * For mcs frames, if mixedmode(overloaded with long preamble) is going to be set, + * fill in non-zero MModeLen and/or MModeFbrLen + * it will be unnecessary if they are separated + */ + if (IS_MCS(rspec[0]) && (preamble_type[0] == WLC_MM_PREAMBLE)) { + u16 mmodelen = + wlc_calc_lsig_len(wlc, rspec[0], phylen); + txh->MModeLen = htol16(mmodelen); + } + + if (IS_MCS(rspec[1]) && (preamble_type[1] == WLC_MM_PREAMBLE)) { + u16 mmodefbrlen = + wlc_calc_lsig_len(wlc, rspec[1], phylen); + txh->MModeFbrLen = htol16(mmodefbrlen); + } + } + + if (IS_MCS(rspec[0])) + ASSERT(IS_MCS(rspec[1])); + + ASSERT(!IS_MCS(rspec[0]) || + ((preamble_type[0] == WLC_MM_PREAMBLE) == (txh->MModeLen != 0))); + ASSERT(!IS_MCS(rspec[1]) || + ((preamble_type[1] == WLC_MM_PREAMBLE) == + (txh->MModeFbrLen != 0))); + + ac = wme_fifo2ac[queue]; + if (SCB_WME(scb) && qos && wlc->edcf_txop[ac]) { + uint frag_dur, dur, dur_fallback; + + ASSERT(!is_multicast_ether_addr(h->addr1)); + + /* WME: Update TXOP threshold */ + if ((!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) && (frag == 0)) { + frag_dur = + wlc_calc_frame_time(wlc, rspec[0], preamble_type[0], + phylen); + + if (rts) { + /* 1 RTS or CTS-to-self frame */ + dur = + wlc_calc_cts_time(wlc, rts_rspec[0], + rts_preamble_type[0]); + dur_fallback = + wlc_calc_cts_time(wlc, rts_rspec[1], + rts_preamble_type[1]); + /* (SIFS + CTS) + SIFS + frame + SIFS + ACK */ + dur += ltoh16(rts->duration); + dur_fallback += ltoh16(txh->RTSDurFallback); + } else if (use_rifs) { + dur = frag_dur; + dur_fallback = 0; + } else { + /* frame + SIFS + ACK */ + dur = frag_dur; + dur += + wlc_compute_frame_dur(wlc, rspec[0], + preamble_type[0], 0); + + dur_fallback = + wlc_calc_frame_time(wlc, rspec[1], + preamble_type[1], + phylen); + dur_fallback += + wlc_compute_frame_dur(wlc, rspec[1], + preamble_type[1], 0); + } + /* NEED to set TxFesTimeNormal (hard) */ + txh->TxFesTimeNormal = htol16((u16) dur); + /* NEED to set fallback rate version of TxFesTimeNormal (hard) */ + txh->TxFesTimeFallback = htol16((u16) dur_fallback); + + /* update txop byte threshold (txop minus intraframe overhead) */ + if (wlc->edcf_txop[ac] >= (dur - frag_dur)) { + { + uint newfragthresh; + + newfragthresh = + wlc_calc_frame_len(wlc, rspec[0], + preamble_type[0], + (wlc-> + edcf_txop[ac] - + (dur - + frag_dur))); + /* range bound the fragthreshold */ + if (newfragthresh < DOT11_MIN_FRAG_LEN) + newfragthresh = + DOT11_MIN_FRAG_LEN; + else if (newfragthresh > + wlc->usr_fragthresh) + newfragthresh = + wlc->usr_fragthresh; + /* update the fragthresh and do txc update */ + if (wlc->fragthresh[queue] != + (u16) newfragthresh) { + wlc->fragthresh[queue] = + (u16) newfragthresh; + } + } + } else + WL_ERROR("wl%d: %s txop invalid for rate %d\n", + wlc->pub->unit, fifo_names[queue], + RSPEC2RATE(rspec[0])); + + if (dur > wlc->edcf_txop[ac]) + WL_ERROR("wl%d: %s: %s txop exceeded phylen %d/%d dur %d/%d\n", + wlc->pub->unit, __func__, + fifo_names[queue], + phylen, wlc->fragthresh[queue], + dur, wlc->edcf_txop[ac]); + } + } + + return 0; +} + +void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs) +{ + wlc_bsscfg_t *cfg = wlc->cfg; + + WLCNTINCR(wlc->pub->_cnt->tbtt); + + if (BSSCFG_STA(cfg)) { + /* run watchdog here if the watchdog timer is not armed */ + if (WLC_WATCHDOG_TBTT(wlc)) { + u32 cur, delta; + if (wlc->WDarmed) { + wl_del_timer(wlc->wl, wlc->wdtimer); + wlc->WDarmed = false; + } + + cur = OSL_SYSUPTIME(); + delta = cur > wlc->WDlast ? cur - wlc->WDlast : + (u32) ~0 - wlc->WDlast + cur + 1; + if (delta >= TIMER_INTERVAL_WATCHDOG) { + wlc_watchdog((void *)wlc); + wlc->WDlast = cur; + } + + wl_add_timer(wlc->wl, wlc->wdtimer, + wlc_watchdog_backup_bi(wlc), true); + wlc->WDarmed = true; + } + } + + if (!cfg->BSS) { + /* DirFrmQ is now valid...defer setting until end of ATIM window */ + wlc->qvalid |= MCMD_DIRFRMQVAL; + } +} + +/* GP timer is a freerunning 32 bit counter, decrements at 1 us rate */ +void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us) +{ + ASSERT(wlc->pub->corerev >= 3); /* no gptimer in earlier revs */ + W_REG(wlc->osh, &wlc->regs->gptimer, us); +} + +void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc) +{ + ASSERT(wlc->pub->corerev >= 3); + W_REG(wlc->osh, &wlc->regs->gptimer, 0); +} + +static void wlc_hwtimer_gptimer_cb(struct wlc_info *wlc) +{ + /* when interrupt is generated, the counter is loaded with last value + * written and continue to decrement. So it has to be cleaned first + */ + W_REG(wlc->osh, &wlc->regs->gptimer, 0); +} + +/* + * This fn has all the high level dpc processing from wlc_dpc. + * POLICY: no macinstatus change, no bounding loop. + * All dpc bounding should be handled in BMAC dpc, like txstatus and rxint + */ +void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus) +{ + d11regs_t *regs = wlc->regs; +#ifdef BCMDBG + char flagstr[128]; + static const bcm_bit_desc_t int_flags[] = { + {MI_MACSSPNDD, "MACSSPNDD"}, + {MI_BCNTPL, "BCNTPL"}, + {MI_TBTT, "TBTT"}, + {MI_BCNSUCCESS, "BCNSUCCESS"}, + {MI_BCNCANCLD, "BCNCANCLD"}, + {MI_ATIMWINEND, "ATIMWINEND"}, + {MI_PMQ, "PMQ"}, + {MI_NSPECGEN_0, "NSPECGEN_0"}, + {MI_NSPECGEN_1, "NSPECGEN_1"}, + {MI_MACTXERR, "MACTXERR"}, + {MI_NSPECGEN_3, "NSPECGEN_3"}, + {MI_PHYTXERR, "PHYTXERR"}, + {MI_PME, "PME"}, + {MI_GP0, "GP0"}, + {MI_GP1, "GP1"}, + {MI_DMAINT, "DMAINT"}, + {MI_TXSTOP, "TXSTOP"}, + {MI_CCA, "CCA"}, + {MI_BG_NOISE, "BG_NOISE"}, + {MI_DTIM_TBTT, "DTIM_TBTT"}, + {MI_PRQ, "PRQ"}, + {MI_PWRUP, "PWRUP"}, + {MI_RFDISABLE, "RFDISABLE"}, + {MI_TFS, "TFS"}, + {MI_PHYCHANGED, "PHYCHANGED"}, + {MI_TO, "TO"}, + {0, NULL} + }; + + if (macintstatus & ~(MI_TBTT | MI_TXSTOP)) { + bcm_format_flags(int_flags, macintstatus, flagstr, + sizeof(flagstr)); + WL_TRACE("wl%d: macintstatus 0x%x %s\n", + wlc->pub->unit, macintstatus, flagstr); + } +#endif /* BCMDBG */ + + if (macintstatus & MI_PRQ) { + /* Process probe request FIFO */ + ASSERT(0 && "PRQ Interrupt in non-MBSS"); + } + + /* TBTT indication */ + /* ucode only gives either TBTT or DTIM_TBTT, not both */ + if (macintstatus & (MI_TBTT | MI_DTIM_TBTT)) + wlc_tbtt(wlc, regs); + + if (macintstatus & MI_GP0) { + WL_ERROR("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", + wlc->pub->unit, wlc->pub->now); + + printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", + __func__, wlc->pub->sih->chip, + wlc->pub->sih->chiprev); + + WLCNTINCR(wlc->pub->_cnt->psmwds); + + /* big hammer */ + wl_init(wlc->wl); + } + + /* gptimer timeout */ + if (macintstatus & MI_TO) { + wlc_hwtimer_gptimer_cb(wlc); + } + + if (macintstatus & MI_RFDISABLE) { + WL_ERROR("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n", + wlc->pub->unit, + R_REG(wlc->osh, ®s->phydebug) & PDBG_RFD); + /* delay the cleanup to wl_down in IBSS case */ + if ((R_REG(wlc->osh, ®s->phydebug) & PDBG_RFD)) { + int idx; + wlc_bsscfg_t *bsscfg; + FOREACH_BSS(wlc, idx, bsscfg) { + if (!BSSCFG_STA(bsscfg) || !bsscfg->enable + || !bsscfg->BSS) + continue; + WL_ERROR("wl%d: wlc_dpc: rfdisable -> wlc_bsscfg_disable()\n", + wlc->pub->unit); + } + } + } + + /* send any enq'd tx packets. Just makes sure to jump start tx */ + if (!pktq_empty(&wlc->active_queue->q)) + wlc_send_q(wlc, wlc->active_queue); + + ASSERT(wlc_ps_check(wlc)); +} + +static void *wlc_15420war(struct wlc_info *wlc, uint queue) +{ + struct hnddma_pub *di; + void *p; + + ASSERT(queue < NFIFO); + + if ((D11REV_IS(wlc->pub->corerev, 4)) + || (D11REV_GT(wlc->pub->corerev, 6))) + return NULL; + + di = wlc->hw->di[queue]; + ASSERT(di != NULL); + + /* get next packet, ignoring XmtStatus.Curr */ + p = dma_getnexttxp(di, HNDDMA_RANGE_ALL); + + /* sw block tx dma */ + dma_txblock(di); + + /* if tx ring is now empty, reset and re-init the tx dma channel */ + if (dma_txactive(wlc->hw->di[queue]) == 0) { + WLCNTINCR(wlc->pub->_cnt->txdmawar); + if (!dma_txreset(di)) + WL_ERROR("wl%d: %s: dma_txreset[%d]: cannot stop dma\n", + wlc->pub->unit, __func__, queue); + dma_txinit(di); + } + return p; +} + +static void wlc_war16165(struct wlc_info *wlc, bool tx) +{ + if (tx) { + /* the post-increment is used in STAY_AWAKE macro */ + if (wlc->txpend16165war++ == 0) + wlc_set_ps_ctrl(wlc); + } else { + wlc->txpend16165war--; + if (wlc->txpend16165war == 0) + wlc_set_ps_ctrl(wlc); + } +} + +/* process an individual tx_status_t */ +/* WLC_HIGH_API */ +bool BCMFASTPATH +wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) +{ + struct sk_buff *p; + uint queue; + d11txh_t *txh; + struct scb *scb = NULL; + bool free_pdu; + struct osl_info *osh; + int tx_rts, tx_frame_count, tx_rts_count; + uint totlen, supr_status; + bool lastframe; + struct ieee80211_hdr *h; + u16 fc; + u16 mcl; + struct ieee80211_tx_info *tx_info; + struct ieee80211_tx_rate *txrate; + int i; + + (void)(frm_tx2); /* Compiler reference to avoid unused variable warning */ + + /* discard intermediate indications for ucode with one legitimate case: + * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent + * tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts + * transmission count) + */ + if (!(txs->status & TX_STATUS_AMPDU) + && (txs->status & TX_STATUS_INTERMEDIATE)) { + WLCNTADD(wlc->pub->_cnt->txnoack, + ((txs-> + status & TX_STATUS_FRM_RTX_MASK) >> + TX_STATUS_FRM_RTX_SHIFT)); + WL_ERROR("%s: INTERMEDIATE but not AMPDU\n", __func__); + return false; + } + + osh = wlc->osh; + queue = txs->frameid & TXFID_QUEUE_MASK; + ASSERT(queue < NFIFO); + if (queue >= NFIFO) { + p = NULL; + goto fatal; + } + + p = GETNEXTTXP(wlc, queue); + if (WLC_WAR16165(wlc)) + wlc_war16165(wlc, false); + if (p == NULL) + p = wlc_15420war(wlc, queue); + ASSERT(p != NULL); + if (p == NULL) + goto fatal; + + txh = (d11txh_t *) (p->data); + mcl = ltoh16(txh->MacTxControlLow); + + if (txs->phyerr) { + WL_ERROR("phyerr 0x%x, rate 0x%x\n", + txs->phyerr, txh->MainRates); + wlc_print_txdesc(txh); + wlc_print_txstatus(txs); + } + + ASSERT(txs->frameid == htol16(txh->TxFrameID)); + if (txs->frameid != htol16(txh->TxFrameID)) + goto fatal; + + tx_info = IEEE80211_SKB_CB(p); + h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); + fc = ltoh16(h->frame_control); + + scb = (struct scb *)tx_info->control.sta->drv_priv; + + if (N_ENAB(wlc->pub)) { + u8 *plcp = (u8 *) (txh + 1); + if (PLCP3_ISSGI(plcp[3])) + WLCNTINCR(wlc->pub->_cnt->txmpdu_sgi); + if (PLCP3_ISSTBC(plcp[3])) + WLCNTINCR(wlc->pub->_cnt->txmpdu_stbc); + } + + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { + ASSERT((mcl & TXC_AMPDU_MASK) != TXC_AMPDU_NONE); + wlc_ampdu_dotxstatus(wlc->ampdu, scb, p, txs); + return false; + } + + supr_status = txs->status & TX_STATUS_SUPR_MASK; + if (supr_status == TX_STATUS_SUPR_BADCH) + WL_NONE("%s: Pkt tx suppressed, possibly channel %d\n", + __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec)); + + tx_rts = htol16(txh->MacTxControlLow) & TXC_SENDRTS; + tx_frame_count = + (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT; + tx_rts_count = + (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT; + + lastframe = (fc & IEEE80211_FCTL_MOREFRAGS) == 0; + + if (!lastframe) { + WL_ERROR("Not last frame!\n"); + } else { + u16 sfbl, lfbl; + ieee80211_tx_info_clear_status(tx_info); + if (queue < AC_COUNT) { + sfbl = WLC_WME_RETRY_SFB_GET(wlc, wme_fifo2ac[queue]); + lfbl = WLC_WME_RETRY_LFB_GET(wlc, wme_fifo2ac[queue]); + } else { + sfbl = wlc->SFBL; + lfbl = wlc->LFBL; + } + + txrate = tx_info->status.rates; + /* FIXME: this should use a combination of sfbl, lfbl depending on frame length and RTS setting */ + if ((tx_frame_count > sfbl) && (txrate[1].idx >= 0)) { + /* rate selection requested a fallback rate and we used it */ + txrate->count = lfbl; + txrate[1].count = tx_frame_count - lfbl; + } else { + /* rate selection did not request fallback rate, or we didn't need it */ + txrate->count = tx_frame_count; + /* rc80211_minstrel.c:minstrel_tx_status() expects unused rates to be marked with idx = -1 */ + txrate[1].idx = -1; + txrate[1].count = 0; + } + + /* clear the rest of the rates */ + for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) { + txrate[i].idx = -1; + txrate[i].count = 0; + } + + if (txs->status & TX_STATUS_ACK_RCV) + tx_info->flags |= IEEE80211_TX_STAT_ACK; + } + + totlen = pkttotlen(osh, p); + free_pdu = true; + + wlc_txfifo_complete(wlc, queue, 1); + + if (lastframe) { + p->next = NULL; + p->prev = NULL; + wlc->txretried = 0; + /* remove PLCP & Broadcom tx descriptor header */ + skb_pull(p, D11_PHY_HDR_LEN); + skb_pull(p, D11_TXH_LEN); + ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); + WLCNTINCR(wlc->pub->_cnt->ieee_tx_status); + } else { + WL_ERROR("%s: Not last frame => not calling tx_status\n", + __func__); + } + + return false; + + fatal: + ASSERT(0); + if (p) + pkt_buf_free_skb(osh, p, true); + + return true; + +} + +void BCMFASTPATH +wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend) +{ + TXPKTPENDDEC(wlc, fifo, txpktpend); + WL_TRACE("wlc_txfifo_complete, pktpend dec %d to %d\n", + txpktpend, TXPKTPENDGET(wlc, fifo)); + + /* There is more room; mark precedences related to this FIFO sendable */ + WLC_TX_FIFO_ENAB(wlc, fifo); + ASSERT(TXPKTPENDGET(wlc, fifo) >= 0); + + if (!TXPKTPENDTOT(wlc)) { + if (wlc->block_datafifo & DATA_BLOCK_TX_SUPR) + wlc_bsscfg_tx_check(wlc); + } + + /* Clear MHF2_TXBCMC_NOW flag if BCMC fifo has drained */ + if (AP_ENAB(wlc->pub) && + wlc->bcmcfifo_drain && !TXPKTPENDGET(wlc, TX_BCMC_FIFO)) { + wlc->bcmcfifo_drain = false; + wlc_mhf(wlc, MHF2, MHF2_TXBCMC_NOW, 0, WLC_BAND_AUTO); + } + + /* figure out which bsscfg is being worked on... */ +} + +/* Given the beacon interval in kus, and a 64 bit TSF in us, + * return the offset (in us) of the TSF from the last TBTT + */ +u32 wlc_calc_tbtt_offset(u32 bp, u32 tsf_h, u32 tsf_l) +{ + u32 k, btklo, btkhi, offset; + + /* TBTT is always an even multiple of the beacon_interval, + * so the TBTT less than or equal to the beacon timestamp is + * the beacon timestamp minus the beacon timestamp modulo + * the beacon interval. + * + * TBTT = BT - (BT % BIu) + * = (BTk - (BTk % BP)) * 2^10 + * + * BT = beacon timestamp (usec, 64bits) + * BTk = beacon timestamp (Kusec, 54bits) + * BP = beacon interval (Kusec, 16bits) + * BIu = BP * 2^10 = beacon interval (usec, 26bits) + * + * To keep the calculations in u32s, the modulo operation + * on the high part of BT needs to be done in parts using the + * relations: + * X*Y mod Z = ((X mod Z) * (Y mod Z)) mod Z + * and + * (X + Y) mod Z = ((X mod Z) + (Y mod Z)) mod Z + * + * So, if BTk[n] = u16 n [0,3] of BTk. + * BTk % BP = SUM((BTk[n] * 2^16n) % BP , 0<=n<4) % BP + * and the SUM term can be broken down: + * (BTk[n] * 2^16n) % BP + * (BTk[n] * (2^16n % BP)) % BP + * + * Create a set of power of 2 mod BP constants: + * K[n] = 2^(16n) % BP + * = (K[n-1] * 2^16) % BP + * K[2] = 2^32 % BP = ((2^16 % BP) * 2^16) % BP + * + * BTk % BP = BTk[0-1] % BP + + * (BTk[2] * K[2]) % BP + + * (BTk[3] * K[3]) % BP + * + * Since K[n] < 2^16 and BTk[n] is < 2^16, then BTk[n] * K[n] < 2^32 + */ + + /* BTk = BT >> 10, btklo = BTk[0-3], bkthi = BTk[4-6] */ + btklo = (tsf_h << 22) | (tsf_l >> 10); + btkhi = tsf_h >> 10; + + /* offset = BTk % BP */ + offset = btklo % bp; + + /* K[2] = ((2^16 % BP) * 2^16) % BP */ + k = (u32) (1 << 16) % bp; + k = (u32) (k * 1 << 16) % (u32) bp; + + /* offset += (BTk[2] * K[2]) % BP */ + offset += ((btkhi & 0xffff) * k) % bp; + + /* BTk[3] */ + btkhi = btkhi >> 16; + + /* k[3] = (K[2] * 2^16) % BP */ + k = (k << 16) % bp; + + /* offset += (BTk[3] * K[3]) % BP */ + offset += ((btkhi & 0xffff) * k) % bp; + + offset = offset % bp; + + /* convert offset from kus to us by shifting up 10 bits and + * add in the low 10 bits of tsf that we ignored + */ + offset = (offset << 10) + (tsf_l & 0x3FF); + + return offset; +} + +/* Update beacon listen interval in shared memory */ +void wlc_bcn_li_upd(struct wlc_info *wlc) +{ + if (AP_ENAB(wlc->pub)) + return; + + /* wake up every DTIM is the default */ + if (wlc->bcn_li_dtim == 1) + wlc_write_shm(wlc, M_BCN_LI, 0); + else + wlc_write_shm(wlc, M_BCN_LI, + (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn); +} + +static void +prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, + struct ieee80211_rx_status *rx_status) +{ + u32 tsf_l, tsf_h; + wlc_d11rxhdr_t *wlc_rxh = (wlc_d11rxhdr_t *) rxh; + int preamble; + int channel; + ratespec_t rspec; + unsigned char *plcp; + + wlc_read_tsf(wlc, &tsf_l, &tsf_h); /* mactime */ + rx_status->mactime = tsf_h; + rx_status->mactime <<= 32; + rx_status->mactime |= tsf_l; + rx_status->flag |= RX_FLAG_TSFT; + + channel = WLC_CHAN_CHANNEL(rxh->RxChan); + + /* XXX Channel/badn needs to be filtered against whether we are single/dual band card */ + if (channel > 14) { + rx_status->band = IEEE80211_BAND_5GHZ; + rx_status->freq = ieee80211_ofdm_chan_to_freq( + WF_CHAN_FACTOR_5_G/2, channel); + + } else { + rx_status->band = IEEE80211_BAND_2GHZ; + rx_status->freq = ieee80211_dsss_chan_to_freq(channel); + } + + rx_status->signal = wlc_rxh->rssi; /* signal */ + + /* noise */ + /* qual */ + rx_status->antenna = (rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; /* ant */ + + plcp = p->data; + + rspec = wlc_compute_rspec(rxh, plcp); + if (IS_MCS(rspec)) { + rx_status->rate_idx = rspec & RSPEC_RATE_MASK; + rx_status->flag |= RX_FLAG_HT; + if (RSPEC_IS40MHZ(rspec)) + rx_status->flag |= RX_FLAG_40MHZ; + } else { + switch (RSPEC2RATE(rspec)) { + case WLC_RATE_1M: + rx_status->rate_idx = 0; + break; + case WLC_RATE_2M: + rx_status->rate_idx = 1; + break; + case WLC_RATE_5M5: + rx_status->rate_idx = 2; + break; + case WLC_RATE_11M: + rx_status->rate_idx = 3; + break; + case WLC_RATE_6M: + rx_status->rate_idx = 4; + break; + case WLC_RATE_9M: + rx_status->rate_idx = 5; + break; + case WLC_RATE_12M: + rx_status->rate_idx = 6; + break; + case WLC_RATE_18M: + rx_status->rate_idx = 7; + break; + case WLC_RATE_24M: + rx_status->rate_idx = 8; + break; + case WLC_RATE_36M: + rx_status->rate_idx = 9; + break; + case WLC_RATE_48M: + rx_status->rate_idx = 10; + break; + case WLC_RATE_54M: + rx_status->rate_idx = 11; + break; + default: + WL_ERROR("%s: Unknown rate\n", __func__); + } + + /* Determine short preamble and rate_idx */ + preamble = 0; + if (IS_CCK(rspec)) { + if (rxh->PhyRxStatus_0 & PRXS0_SHORTH) + WL_ERROR("Short CCK\n"); + rx_status->flag |= RX_FLAG_SHORTPRE; + } else if (IS_OFDM(rspec)) { + rx_status->flag |= RX_FLAG_SHORTPRE; + } else { + WL_ERROR("%s: Unknown modulation\n", __func__); + } + } + + if (PLCP3_ISSGI(plcp[3])) + rx_status->flag |= RX_FLAG_SHORT_GI; + + if (rxh->RxStatus1 & RXS_DECERR) { + rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC; + WL_ERROR("%s: RX_FLAG_FAILED_PLCP_CRC\n", __func__); + } + if (rxh->RxStatus1 & RXS_FCSERR) { + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + WL_ERROR("%s: RX_FLAG_FAILED_FCS_CRC\n", __func__); + } +} + +static void +wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, d11rxhdr_t *rxh, + struct sk_buff *p) +{ + int len_mpdu; + struct ieee80211_rx_status rx_status; +#if defined(BCMDBG) + struct sk_buff *skb = p; +#endif /* BCMDBG */ + /* Todo: + * Cache plcp for first MPDU of AMPD and use chacched version for INTERMEDIATE. + * Test for INTERMEDIATE like so: + * if (!(plcp[0] | plcp[1] | plcp[2])) + */ + + memset(&rx_status, 0, sizeof(rx_status)); + prep_mac80211_status(wlc, rxh, p, &rx_status); + + /* mac header+body length, exclude CRC and plcp header */ + len_mpdu = p->len - D11_PHY_HDR_LEN - FCS_LEN; + skb_pull(p, D11_PHY_HDR_LEN); + __skb_trim(p, len_mpdu); + + ASSERT(!(p->next)); + ASSERT(!(p->prev)); + + ASSERT(IS_ALIGNED((unsigned long)skb->data, 2)); + + memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status)); + ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p); + + WLCNTINCR(wlc->pub->_cnt->ieee_rx); + osh->pktalloced--; + return; +} + +void wlc_bss_list_free(struct wlc_info *wlc, wlc_bss_list_t *bss_list) +{ + uint index; + wlc_bss_info_t *bi; + + if (!bss_list) { + WL_ERROR("%s: Attempting to free NULL list\n", __func__); + return; + } + /* inspect all BSS descriptor */ + for (index = 0; index < bss_list->count; index++) { + bi = bss_list->ptrs[index]; + if (bi) { + kfree(bi); + bss_list->ptrs[index] = NULL; + } + } + bss_list->count = 0; +} + +/* Process received frames */ +/* + * Return true if more frames need to be processed. false otherwise. + * Param 'bound' indicates max. # frames to process before break out. + */ +/* WLC_HIGH_API */ +void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) +{ + d11rxhdr_t *rxh; + struct ieee80211_hdr *h; + struct osl_info *osh; + u16 fc; + uint len; + bool is_amsdu; + + WL_TRACE("wl%d: wlc_recv\n", wlc->pub->unit); + + osh = wlc->osh; + + /* frame starts with rxhdr */ + rxh = (d11rxhdr_t *) (p->data); + + /* strip off rxhdr */ + skb_pull(p, wlc->hwrxoff); + + /* fixup rx header endianness */ + ltoh16_buf((void *)rxh, sizeof(d11rxhdr_t)); + + /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ + if (rxh->RxStatus1 & RXS_PBPRES) { + if (p->len < 2) { + WLCNTINCR(wlc->pub->_cnt->rxrunt); + WL_ERROR("wl%d: wlc_recv: rcvd runt of len %d\n", + wlc->pub->unit, p->len); + goto toss; + } + skb_pull(p, 2); + } + + h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN); + len = p->len; + + if (rxh->RxStatus1 & RXS_FCSERR) { + if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) { + WL_ERROR("FCSERR while scanning******* - tossing\n"); + goto toss; + } else { + WL_ERROR("RCSERR!!!\n"); + goto toss; + } + } + + /* check received pkt has at least frame control field */ + if (len >= D11_PHY_HDR_LEN + sizeof(h->frame_control)) { + fc = ltoh16(h->frame_control); + } else { + WLCNTINCR(wlc->pub->_cnt->rxrunt); + goto toss; + } + + is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK; + + /* explicitly test bad src address to avoid sending bad deauth */ + if (!is_amsdu) { + /* CTS and ACK CTL frames are w/o a2 */ + if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA || + (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { + if ((is_zero_ether_addr(h->addr2) || + is_multicast_ether_addr(h->addr2))) { + WL_ERROR("wl%d: %s: dropping a frame with " + "invalid src mac address, a2: %pM\n", + wlc->pub->unit, __func__, h->addr2); + WLCNTINCR(wlc->pub->_cnt->rxbadsrcmac); + goto toss; + } + WLCNTINCR(wlc->pub->_cnt->rxfrag); + } + } + + /* due to sheer numbers, toss out probe reqs for now */ + if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { + if ((fc & FC_KIND_MASK) == FC_PROBE_REQ) + goto toss; + } + + if (is_amsdu) { + WL_ERROR("%s: is_amsdu causing toss\n", __func__); + goto toss; + } + + wlc_recvctl(wlc, osh, rxh, p); + return; + + toss: + pkt_buf_free_skb(osh, p, false); +} + +/* calculate frame duration for Mixed-mode L-SIG spoofing, return + * number of bytes goes in the length field + * + * Formula given by HT PHY Spec v 1.13 + * len = 3(nsyms + nstream + 3) - 3 + */ +u16 BCMFASTPATH +wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, uint mac_len) +{ + uint nsyms, len = 0, kNdps; + + WL_TRACE("wl%d: wlc_calc_lsig_len: rate %d, len%d\n", + wlc->pub->unit, RSPEC2RATE(ratespec), mac_len); + + if (IS_MCS(ratespec)) { + uint mcs = ratespec & RSPEC_RATE_MASK; + /* MCS_TXS(mcs) returns num tx streams - 1 */ + int tot_streams = (MCS_TXS(mcs) + 1) + RSPEC_STC(ratespec); + + ASSERT(WLC_PHY_11N_CAP(wlc->band)); + /* the payload duration calculation matches that of regular ofdm */ + /* 1000Ndbps = kbps * 4 */ + kNdps = + MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec), + RSPEC_ISSGI(ratespec)) * 4; + + if (RSPEC_STC(ratespec) == 0) + /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ + nsyms = + CEIL((APHY_SERVICE_NBITS + 8 * mac_len + + APHY_TAIL_NBITS) * 1000, kNdps); + else + /* STBC needs to have even number of symbols */ + nsyms = + 2 * + CEIL((APHY_SERVICE_NBITS + 8 * mac_len + + APHY_TAIL_NBITS) * 1000, 2 * kNdps); + + nsyms += (tot_streams + 3); /* (+3) account for HT-SIG(2) and HT-STF(1) */ + /* 3 bytes/symbol @ legacy 6Mbps rate */ + len = (3 * nsyms) - 3; /* (-3) excluding service bits and tail bits */ + } + + return (u16) len; +} + +/* calculate frame duration of a given rate and length, return time in usec unit */ +uint BCMFASTPATH +wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, + uint mac_len) +{ + uint nsyms, dur = 0, Ndps, kNdps; + uint rate = RSPEC2RATE(ratespec); + + if (rate == 0) { + ASSERT(0); + WL_ERROR("wl%d: WAR: using rate of 1 mbps\n", wlc->pub->unit); + rate = WLC_RATE_1M; + } + + WL_TRACE("wl%d: wlc_calc_frame_time: rspec 0x%x, preamble_type %d, len%d\n", + wlc->pub->unit, ratespec, preamble_type, mac_len); + + if (IS_MCS(ratespec)) { + uint mcs = ratespec & RSPEC_RATE_MASK; + int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec); + ASSERT(WLC_PHY_11N_CAP(wlc->band)); + ASSERT(WLC_IS_MIMO_PREAMBLE(preamble_type)); + + dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT); + if (preamble_type == WLC_MM_PREAMBLE) + dur += PREN_MM_EXT; + /* 1000Ndbps = kbps * 4 */ + kNdps = + MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec), + RSPEC_ISSGI(ratespec)) * 4; + + if (RSPEC_STC(ratespec) == 0) + /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ + nsyms = + CEIL((APHY_SERVICE_NBITS + 8 * mac_len + + APHY_TAIL_NBITS) * 1000, kNdps); + else + /* STBC needs to have even number of symbols */ + nsyms = + 2 * + CEIL((APHY_SERVICE_NBITS + 8 * mac_len + + APHY_TAIL_NBITS) * 1000, 2 * kNdps); + + dur += APHY_SYMBOL_TIME * nsyms; + if (BAND_2G(wlc->band->bandtype)) + dur += DOT11_OFDM_SIGNAL_EXTENSION; + } else if (IS_OFDM(rate)) { + dur = APHY_PREAMBLE_TIME; + dur += APHY_SIGNAL_TIME; + /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */ + Ndps = rate * 2; + /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ + nsyms = + CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS), + Ndps); + dur += APHY_SYMBOL_TIME * nsyms; + if (BAND_2G(wlc->band->bandtype)) + dur += DOT11_OFDM_SIGNAL_EXTENSION; + } else { + /* calc # bits * 2 so factor of 2 in rate (1/2 mbps) will divide out */ + mac_len = mac_len * 8 * 2; + /* calc ceiling of bits/rate = microseconds of air time */ + dur = (mac_len + rate - 1) / rate; + if (preamble_type & WLC_SHORT_PREAMBLE) + dur += BPHY_PLCP_SHORT_TIME; + else + dur += BPHY_PLCP_TIME; + } + return dur; +} + +/* The opposite of wlc_calc_frame_time */ +static uint +wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, + uint dur) +{ + uint nsyms, mac_len, Ndps, kNdps; + uint rate = RSPEC2RATE(ratespec); + + WL_TRACE("wl%d: wlc_calc_frame_len: rspec 0x%x, preamble_type %d, dur %d\n", + wlc->pub->unit, ratespec, preamble_type, dur); + + if (IS_MCS(ratespec)) { + uint mcs = ratespec & RSPEC_RATE_MASK; + int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec); + ASSERT(WLC_PHY_11N_CAP(wlc->band)); + dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT); + /* payload calculation matches that of regular ofdm */ + if (BAND_2G(wlc->band->bandtype)) + dur -= DOT11_OFDM_SIGNAL_EXTENSION; + /* kNdbps = kbps * 4 */ + kNdps = + MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec), + RSPEC_ISSGI(ratespec)) * 4; + nsyms = dur / APHY_SYMBOL_TIME; + mac_len = + ((nsyms * kNdps) - + ((APHY_SERVICE_NBITS + APHY_TAIL_NBITS) * 1000)) / 8000; + } else if (IS_OFDM(ratespec)) { + dur -= APHY_PREAMBLE_TIME; + dur -= APHY_SIGNAL_TIME; + /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */ + Ndps = rate * 2; + nsyms = dur / APHY_SYMBOL_TIME; + mac_len = + ((nsyms * Ndps) - + (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8; + } else { + if (preamble_type & WLC_SHORT_PREAMBLE) + dur -= BPHY_PLCP_SHORT_TIME; + else + dur -= BPHY_PLCP_TIME; + mac_len = dur * rate; + /* divide out factor of 2 in rate (1/2 mbps) */ + mac_len = mac_len / 8 / 2; + } + return mac_len; +} + +static uint +wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) +{ + WL_TRACE("wl%d: wlc_calc_ba_time: rspec 0x%x, preamble_type %d\n", + wlc->pub->unit, rspec, preamble_type); + /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than + * or equal to the rate of the immediately previous frame in the FES + */ + rspec = WLC_BASIC_RATE(wlc, rspec); + ASSERT(VALID_RATE_DBG(wlc, rspec)); + + /* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */ + return wlc_calc_frame_time(wlc, rspec, preamble_type, + (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN + + FCS_LEN)); +} + +static uint BCMFASTPATH +wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) +{ + uint dur = 0; + + WL_TRACE("wl%d: wlc_calc_ack_time: rspec 0x%x, preamble_type %d\n", + wlc->pub->unit, rspec, preamble_type); + /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than + * or equal to the rate of the immediately previous frame in the FES + */ + rspec = WLC_BASIC_RATE(wlc, rspec); + ASSERT(VALID_RATE_DBG(wlc, rspec)); + + /* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */ + dur = + wlc_calc_frame_time(wlc, rspec, preamble_type, + (DOT11_ACK_LEN + FCS_LEN)); + return dur; +} + +static uint +wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) +{ + WL_TRACE("wl%d: wlc_calc_cts_time: ratespec 0x%x, preamble_type %d\n", + wlc->pub->unit, rspec, preamble_type); + return wlc_calc_ack_time(wlc, rspec, preamble_type); +} + +/* derive wlc->band->basic_rate[] table from 'rateset' */ +void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset) +{ + u8 rate; + u8 mandatory; + u8 cck_basic = 0; + u8 ofdm_basic = 0; + u8 *br = wlc->band->basic_rate; + uint i; + + /* incoming rates are in 500kbps units as in 802.11 Supported Rates */ + memset(br, 0, WLC_MAXRATE + 1); + + /* For each basic rate in the rates list, make an entry in the + * best basic lookup. + */ + for (i = 0; i < rateset->count; i++) { + /* only make an entry for a basic rate */ + if (!(rateset->rates[i] & WLC_RATE_FLAG)) + continue; + + /* mask off basic bit */ + rate = (rateset->rates[i] & RATE_MASK); + + if (rate > WLC_MAXRATE) { + WL_ERROR("wlc_rate_lookup_init: invalid rate 0x%X in rate set\n", + rateset->rates[i]); + continue; + } + + br[rate] = rate; + } + + /* The rate lookup table now has non-zero entries for each + * basic rate, equal to the basic rate: br[basicN] = basicN + * + * To look up the best basic rate corresponding to any + * particular rate, code can use the basic_rate table + * like this + * + * basic_rate = wlc->band->basic_rate[tx_rate] + * + * Make sure there is a best basic rate entry for + * every rate by walking up the table from low rates + * to high, filling in holes in the lookup table + */ + + for (i = 0; i < wlc->band->hw_rateset.count; i++) { + rate = wlc->band->hw_rateset.rates[i]; + ASSERT(rate <= WLC_MAXRATE); + + if (br[rate] != 0) { + /* This rate is a basic rate. + * Keep track of the best basic rate so far by + * modulation type. + */ + if (IS_OFDM(rate)) + ofdm_basic = rate; + else + cck_basic = rate; + + continue; + } + + /* This rate is not a basic rate so figure out the + * best basic rate less than this rate and fill in + * the hole in the table + */ + + br[rate] = IS_OFDM(rate) ? ofdm_basic : cck_basic; + + if (br[rate] != 0) + continue; + + if (IS_OFDM(rate)) { + /* In 11g and 11a, the OFDM mandatory rates are 6, 12, and 24 Mbps */ + if (rate >= WLC_RATE_24M) + mandatory = WLC_RATE_24M; + else if (rate >= WLC_RATE_12M) + mandatory = WLC_RATE_12M; + else + mandatory = WLC_RATE_6M; + } else { + /* In 11b, all the CCK rates are mandatory 1 - 11 Mbps */ + mandatory = rate; + } + + br[rate] = mandatory; + } +} + +static void wlc_write_rate_shm(struct wlc_info *wlc, u8 rate, u8 basic_rate) +{ + u8 phy_rate, index; + u8 basic_phy_rate, basic_index; + u16 dir_table, basic_table; + u16 basic_ptr; + + /* Shared memory address for the table we are reading */ + dir_table = IS_OFDM(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B; + + /* Shared memory address for the table we are writing */ + basic_table = IS_OFDM(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B; + + /* + * for a given rate, the LS-nibble of the PLCP SIGNAL field is + * the index into the rate table. + */ + phy_rate = rate_info[rate] & RATE_MASK; + basic_phy_rate = rate_info[basic_rate] & RATE_MASK; + index = phy_rate & 0xf; + basic_index = basic_phy_rate & 0xf; + + /* Find the SHM pointer to the ACK rate entry by looking in the + * Direct-map Table + */ + basic_ptr = wlc_read_shm(wlc, (dir_table + basic_index * 2)); + + /* Update the SHM BSS-basic-rate-set mapping table with the pointer + * to the correct basic rate for the given incoming rate + */ + wlc_write_shm(wlc, (basic_table + index * 2), basic_ptr); +} + +static const wlc_rateset_t *wlc_rateset_get_hwrs(struct wlc_info *wlc) +{ + const wlc_rateset_t *rs_dflt; + + if (WLC_PHY_11N_CAP(wlc->band)) { + if (BAND_5G(wlc->band->bandtype)) + rs_dflt = &ofdm_mimo_rates; + else + rs_dflt = &cck_ofdm_mimo_rates; + } else if (wlc->band->gmode) + rs_dflt = &cck_ofdm_rates; + else + rs_dflt = &cck_rates; + + return rs_dflt; +} + +void wlc_set_ratetable(struct wlc_info *wlc) +{ + const wlc_rateset_t *rs_dflt; + wlc_rateset_t rs; + u8 rate, basic_rate; + uint i; + + rs_dflt = wlc_rateset_get_hwrs(wlc); + ASSERT(rs_dflt != NULL); + + wlc_rateset_copy(rs_dflt, &rs); + wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams); + + /* walk the phy rate table and update SHM basic rate lookup table */ + for (i = 0; i < rs.count; i++) { + rate = rs.rates[i] & RATE_MASK; + + /* for a given rate WLC_BASIC_RATE returns the rate at + * which a response ACK/CTS should be sent. + */ + basic_rate = WLC_BASIC_RATE(wlc, rate); + if (basic_rate == 0) { + /* This should only happen if we are using a + * restricted rateset. + */ + basic_rate = rs.rates[0] & RATE_MASK; + } + + wlc_write_rate_shm(wlc, rate, basic_rate); + } +} + +/* + * Return true if the specified rate is supported by the specified band. + * WLC_BAND_AUTO indicates the current band. + */ +bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rspec, int band, + bool verbose) +{ + wlc_rateset_t *hw_rateset; + uint i; + + if ((band == WLC_BAND_AUTO) || (band == wlc->band->bandtype)) { + hw_rateset = &wlc->band->hw_rateset; + } else if (NBANDS(wlc) > 1) { + hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset; + } else { + /* other band specified and we are a single band device */ + return false; + } + + /* check if this is a mimo rate */ + if (IS_MCS(rspec)) { + if (!VALID_MCS((rspec & RSPEC_RATE_MASK))) + goto error; + + return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK)); + } + + for (i = 0; i < hw_rateset->count; i++) + if (hw_rateset->rates[i] == RSPEC2RATE(rspec)) + return true; + error: + if (verbose) { + WL_ERROR("wl%d: wlc_valid_rate: rate spec 0x%x not in hw_rateset\n", + wlc->pub->unit, rspec); + } + + return false; +} + +static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap) +{ + uint i; + struct wlcband *band; + + for (i = 0; i < NBANDS(wlc); i++) { + if (IS_SINGLEBAND_5G(wlc->deviceid)) + i = BAND_5G_INDEX; + band = wlc->bandstate[i]; + if (band->bandtype == WLC_BAND_5G) { + if ((bwcap == WLC_N_BW_40ALL) + || (bwcap == WLC_N_BW_20IN2G_40IN5G)) + band->mimo_cap_40 = true; + else + band->mimo_cap_40 = false; + } else { + ASSERT(band->bandtype == WLC_BAND_2G); + if (bwcap == WLC_N_BW_40ALL) + band->mimo_cap_40 = true; + else + band->mimo_cap_40 = false; + } + } + + wlc->mimo_band_bwcap = bwcap; +} + +void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len) +{ + const wlc_rateset_t *rs_dflt; + wlc_rateset_t rs; + u8 rate; + u16 entry_ptr; + u8 plcp[D11_PHY_HDR_LEN]; + u16 dur, sifs; + uint i; + + sifs = SIFS(wlc->band); + + rs_dflt = wlc_rateset_get_hwrs(wlc); + ASSERT(rs_dflt != NULL); + + wlc_rateset_copy(rs_dflt, &rs); + wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams); + + /* walk the phy rate table and update MAC core SHM basic rate table entries */ + for (i = 0; i < rs.count; i++) { + rate = rs.rates[i] & RATE_MASK; + + entry_ptr = wlc_rate_shm_offset(wlc, rate); + + /* Calculate the Probe Response PLCP for the given rate */ + wlc_compute_plcp(wlc, rate, frame_len, plcp); + + /* Calculate the duration of the Probe Response frame plus SIFS for the MAC */ + dur = + (u16) wlc_calc_frame_time(wlc, rate, WLC_LONG_PREAMBLE, + frame_len); + dur += sifs; + + /* Update the SHM Rate Table entry Probe Response values */ + wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS, + (u16) (plcp[0] + (plcp[1] << 8))); + wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS + 2, + (u16) (plcp[2] + (plcp[3] << 8))); + wlc_write_shm(wlc, entry_ptr + M_RT_PRS_DUR_POS, dur); + } +} + +u16 +wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec, + bool short_preamble, bool phydelay) +{ + uint bcntsfoff = 0; + + if (IS_MCS(rspec)) { + WL_ERROR("wl%d: recd beacon with mcs rate; rspec 0x%x\n", + wlc->pub->unit, rspec); + } else if (IS_OFDM(rspec)) { + /* tx delay from MAC through phy to air (2.1 usec) + + * phy header time (preamble + PLCP SIGNAL == 20 usec) + + * PLCP SERVICE + MAC header time (SERVICE + FC + DUR + A1 + A2 + A3 + SEQ == 26 + * bytes at beacon rate) + */ + bcntsfoff += phydelay ? D11A_PHY_TX_DELAY : 0; + bcntsfoff += APHY_PREAMBLE_TIME + APHY_SIGNAL_TIME; + bcntsfoff += + wlc_compute_airtime(wlc, rspec, + APHY_SERVICE_NBITS / 8 + + DOT11_MAC_HDR_LEN); + } else { + /* tx delay from MAC through phy to air (3.4 usec) + + * phy header time (long preamble + PLCP == 192 usec) + + * MAC header time (FC + DUR + A1 + A2 + A3 + SEQ == 24 bytes at beacon rate) + */ + bcntsfoff += phydelay ? D11B_PHY_TX_DELAY : 0; + bcntsfoff += + short_preamble ? D11B_PHY_SPREHDR_TIME : + D11B_PHY_LPREHDR_TIME; + bcntsfoff += wlc_compute_airtime(wlc, rspec, DOT11_MAC_HDR_LEN); + } + return (u16) (bcntsfoff); +} + +/* Max buffering needed for beacon template/prb resp template is 142 bytes. + * + * PLCP header is 6 bytes. + * 802.11 A3 header is 24 bytes. + * Max beacon frame body template length is 112 bytes. + * Max probe resp frame body template length is 110 bytes. + * + * *len on input contains the max length of the packet available. + * + * The *len value is set to the number of bytes in buf used, and starts with the PLCP + * and included up to, but not including, the 4 byte FCS. + */ +static void +wlc_bcn_prb_template(struct wlc_info *wlc, uint type, ratespec_t bcn_rspec, + wlc_bsscfg_t *cfg, u16 *buf, int *len) +{ + static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; + cck_phy_hdr_t *plcp; + struct ieee80211_mgmt *h; + int hdr_len, body_len; + + ASSERT(*len >= 142); + ASSERT(type == FC_BEACON || type == FC_PROBE_RESP); + + if (MBSS_BCN_ENAB(cfg) && type == FC_BEACON) + hdr_len = DOT11_MAC_HDR_LEN; + else + hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN; + body_len = *len - hdr_len; /* calc buffer size provided for frame body */ + + *len = hdr_len + body_len; /* return actual size */ + + /* format PHY and MAC headers */ + memset((char *)buf, 0, hdr_len); + + plcp = (cck_phy_hdr_t *) buf; + + /* PLCP for Probe Response frames are filled in from core's rate table */ + if (type == FC_BEACON && !MBSS_BCN_ENAB(cfg)) { + /* fill in PLCP */ + wlc_compute_plcp(wlc, bcn_rspec, + (DOT11_MAC_HDR_LEN + body_len + FCS_LEN), + (u8 *) plcp); + + } + /* "Regular" and 16 MBSS but not for 4 MBSS */ + /* Update the phytxctl for the beacon based on the rspec */ + if (!SOFTBCN_ENAB(cfg)) + wlc_beacon_phytxctl_txant_upd(wlc, bcn_rspec); + + if (MBSS_BCN_ENAB(cfg) && type == FC_BEACON) + h = (struct ieee80211_mgmt *)&plcp[0]; + else + h = (struct ieee80211_mgmt *)&plcp[1]; + + /* fill in 802.11 header */ + h->frame_control = htol16((u16) type); + + /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */ + /* A1 filled in by MAC for prb resp, broadcast for bcn */ + if (type == FC_BEACON) + bcopy((const char *)ðer_bcast, (char *)&h->da, + ETH_ALEN); + bcopy((char *)&cfg->cur_etheraddr, (char *)&h->sa, ETH_ALEN); + bcopy((char *)&cfg->BSSID, (char *)&h->bssid, ETH_ALEN); + + /* SEQ filled in by MAC */ + + return; +} + +int wlc_get_header_len() +{ + return TXOFF; +} + +/* Update a beacon for a particular BSS + * For MBSS, this updates the software template and sets "latest" to the index of the + * template updated. + * Otherwise, it updates the hardware template. + */ +void wlc_bss_update_beacon(struct wlc_info *wlc, wlc_bsscfg_t *cfg) +{ + int len = BCN_TMPL_LEN; + + /* Clear the soft intmask */ + wlc->defmacintmask &= ~MI_BCNTPL; + + if (!cfg->up) { /* Only allow updates on an UP bss */ + return; + } + + if (MBSS_BCN_ENAB(cfg)) { /* Optimize: Some of if/else could be combined */ + } else if (HWBCN_ENAB(cfg)) { /* Hardware beaconing for this config */ + u16 bcn[BCN_TMPL_LEN / 2]; + u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD; + d11regs_t *regs = wlc->regs; + struct osl_info *osh = NULL; + + osh = wlc->osh; + + /* Check if both templates are in use, if so sched. an interrupt + * that will call back into this routine + */ + if ((R_REG(osh, ®s->maccommand) & both_valid) == both_valid) { + /* clear any previous status */ + W_REG(osh, ®s->macintstatus, MI_BCNTPL); + } + /* Check that after scheduling the interrupt both of the + * templates are still busy. if not clear the int. & remask + */ + if ((R_REG(osh, ®s->maccommand) & both_valid) == both_valid) { + wlc->defmacintmask |= MI_BCNTPL; + return; + } + + wlc->bcn_rspec = + wlc_lowest_basic_rspec(wlc, &cfg->current_bss->rateset); + ASSERT(wlc_valid_rate + (wlc, wlc->bcn_rspec, + CHSPEC_IS2G(cfg->current_bss-> + chanspec) ? WLC_BAND_2G : WLC_BAND_5G, + true)); + + /* update the template and ucode shm */ + wlc_bcn_prb_template(wlc, FC_BEACON, wlc->bcn_rspec, cfg, bcn, + &len); + wlc_write_hw_bcntemplates(wlc, bcn, len, false); + } +} + +/* + * Update all beacons for the system. + */ +void wlc_update_beacon(struct wlc_info *wlc) +{ + int idx; + wlc_bsscfg_t *bsscfg; + + /* update AP or IBSS beacons */ + FOREACH_BSS(wlc, idx, bsscfg) { + if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS)) + wlc_bss_update_beacon(wlc, bsscfg); + } +} + +/* Write ssid into shared memory */ +void wlc_shm_ssid_upd(struct wlc_info *wlc, wlc_bsscfg_t *cfg) +{ + u8 *ssidptr = cfg->SSID; + u16 base = M_SSID; + u8 ssidbuf[IEEE80211_MAX_SSID_LEN]; + + /* padding the ssid with zero and copy it into shm */ + memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN); + bcopy(ssidptr, ssidbuf, cfg->SSID_len); + + wlc_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN); + + if (!MBSS_BCN_ENAB(cfg)) + wlc_write_shm(wlc, M_SSIDLEN, (u16) cfg->SSID_len); +} + +void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend) +{ + int idx; + wlc_bsscfg_t *bsscfg; + + /* update AP or IBSS probe responses */ + FOREACH_BSS(wlc, idx, bsscfg) { + if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS)) + wlc_bss_update_probe_resp(wlc, bsscfg, suspend); + } +} + +void +wlc_bss_update_probe_resp(struct wlc_info *wlc, wlc_bsscfg_t *cfg, bool suspend) +{ + u16 prb_resp[BCN_TMPL_LEN / 2]; + int len = BCN_TMPL_LEN; + + /* write the probe response to hardware, or save in the config structure */ + if (!MBSS_PRB_ENAB(cfg)) { + + /* create the probe response template */ + wlc_bcn_prb_template(wlc, FC_PROBE_RESP, 0, cfg, prb_resp, + &len); + + if (suspend) + wlc_suspend_mac_and_wait(wlc); + + /* write the probe response into the template region */ + wlc_bmac_write_template_ram(wlc->hw, T_PRS_TPL_BASE, + (len + 3) & ~3, prb_resp); + + /* write the length of the probe response frame (+PLCP/-FCS) */ + wlc_write_shm(wlc, M_PRB_RESP_FRM_LEN, (u16) len); + + /* write the SSID and SSID length */ + wlc_shm_ssid_upd(wlc, cfg); + + /* + * Write PLCP headers and durations for probe response frames at all rates. + * Use the actual frame length covered by the PLCP header for the call to + * wlc_mod_prb_rsp_rate_table() by subtracting the PLCP len and adding the FCS. + */ + len += (-D11_PHY_HDR_LEN + FCS_LEN); + wlc_mod_prb_rsp_rate_table(wlc, (u16) len); + + if (suspend) + wlc_enable_mac(wlc); + } else { /* Generating probe resp in sw; update local template */ + ASSERT(0 && "No software probe response support without MBSS"); + } +} + +/* prepares pdu for transmission. returns BCM error codes */ +int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) +{ + struct osl_info *osh; + uint fifo; + d11txh_t *txh; + struct ieee80211_hdr *h; + struct scb *scb; + u16 fc; + + osh = wlc->osh; + + ASSERT(pdu); + txh = (d11txh_t *) (pdu->data); + ASSERT(txh); + h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); + ASSERT(h); + fc = ltoh16(h->frame_control); + + /* get the pkt queue info. This was put at wlc_sendctl or wlc_send for PDU */ + fifo = ltoh16(txh->TxFrameID) & TXFID_QUEUE_MASK; + + scb = NULL; + + *fifop = fifo; + + /* return if insufficient dma resources */ + if (TXAVAIL(wlc, fifo) < MAX_DMA_SEGS) { + /* Mark precedences related to this FIFO, unsendable */ + WLC_TX_FIFO_CLEAR(wlc, fifo); + return BCME_BUSY; + } + + if ((ltoh16(txh->MacFrameControl) & IEEE80211_FCTL_FTYPE) != + IEEE80211_FTYPE_DATA) + WLCNTINCR(wlc->pub->_cnt->txctl); + + return 0; +} + +/* init tx reported rate mechanism */ +void wlc_reprate_init(struct wlc_info *wlc) +{ + int i; + wlc_bsscfg_t *bsscfg; + + FOREACH_BSS(wlc, i, bsscfg) { + wlc_bsscfg_reprate_init(bsscfg); + } +} + +/* per bsscfg init tx reported rate mechanism */ +void wlc_bsscfg_reprate_init(wlc_bsscfg_t *bsscfg) +{ + bsscfg->txrspecidx = 0; + memset((char *)bsscfg->txrspec, 0, sizeof(bsscfg->txrspec)); +} + +/* Retrieve a consolidated set of revision information, + * typically for the WLC_GET_REVINFO ioctl + */ +int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len) +{ + wlc_rev_info_t *rinfo = (wlc_rev_info_t *) buf; + + if (len < WL_REV_INFO_LEGACY_LENGTH) + return BCME_BUFTOOSHORT; + + rinfo->vendorid = wlc->vendorid; + rinfo->deviceid = wlc->deviceid; + rinfo->radiorev = (wlc->band->radiorev << IDCODE_REV_SHIFT) | + (wlc->band->radioid << IDCODE_ID_SHIFT); + rinfo->chiprev = wlc->pub->sih->chiprev; + rinfo->corerev = wlc->pub->corerev; + rinfo->boardid = wlc->pub->sih->boardtype; + rinfo->boardvendor = wlc->pub->sih->boardvendor; + rinfo->boardrev = wlc->pub->boardrev; + rinfo->ucoderev = wlc->ucode_rev; + rinfo->driverrev = EPI_VERSION_NUM; + rinfo->bus = wlc->pub->sih->bustype; + rinfo->chipnum = wlc->pub->sih->chip; + + if (len >= (offsetof(wlc_rev_info_t, chippkg))) { + rinfo->phytype = wlc->band->phytype; + rinfo->phyrev = wlc->band->phyrev; + rinfo->anarev = 0; /* obsolete stuff, suppress */ + } + + if (len >= sizeof(*rinfo)) { + rinfo->chippkg = wlc->pub->sih->chippkg; + } + + return BCME_OK; +} + +void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs) +{ + wlc_rateset_default(rs, NULL, wlc->band->phytype, wlc->band->bandtype, + false, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub), + CHSPEC_WLC_BW(wlc->default_bss->chanspec), + wlc->stf->txstreams); +} + +static void wlc_bss_default_init(struct wlc_info *wlc) +{ + chanspec_t chanspec; + struct wlcband *band; + wlc_bss_info_t *bi = wlc->default_bss; + + /* init default and target BSS with some sane initial values */ + memset((char *)(bi), 0, sizeof(wlc_bss_info_t)); + bi->beacon_period = ISSIM_ENAB(wlc->pub->sih) ? BEACON_INTERVAL_DEF_QT : + BEACON_INTERVAL_DEFAULT; + bi->dtim_period = ISSIM_ENAB(wlc->pub->sih) ? DTIM_INTERVAL_DEF_QT : + DTIM_INTERVAL_DEFAULT; + + /* fill the default channel as the first valid channel + * starting from the 2G channels + */ + chanspec = CH20MHZ_CHSPEC(1); + ASSERT(chanspec != INVCHANSPEC); + + wlc->home_chanspec = bi->chanspec = chanspec; + + /* find the band of our default channel */ + band = wlc->band; + if (NBANDS(wlc) > 1 && band->bandunit != CHSPEC_WLCBANDUNIT(chanspec)) + band = wlc->bandstate[OTHERBANDUNIT(wlc)]; + + /* init bss rates to the band specific default rate set */ + wlc_rateset_default(&bi->rateset, NULL, band->phytype, band->bandtype, + false, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub), + CHSPEC_WLC_BW(chanspec), wlc->stf->txstreams); + + if (N_ENAB(wlc->pub)) + bi->flags |= WLC_BSS_HT; +} + +/* Deferred event processing */ +static void wlc_process_eventq(void *arg) +{ + struct wlc_info *wlc = (struct wlc_info *) arg; + wlc_event_t *etmp; + + while ((etmp = wlc_eventq_deq(wlc->eventq))) { + /* Perform OS specific event processing */ + wl_event(wlc->wl, etmp->event.ifname, etmp); + if (etmp->data) { + kfree(etmp->data); + etmp->data = NULL; + } + wlc_event_free(wlc->eventq, etmp); + } +} + +void +wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, u32 b_low) +{ + if (b_low > *a_low) { + /* low half needs a carry */ + b_high += 1; + } + *a_low -= b_low; + *a_high -= b_high; +} + +static ratespec_t +mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, + u32 int_val) +{ + u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT; + u8 rate = int_val & NRATE_RATE_MASK; + ratespec_t rspec; + bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE); + bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT); + bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY) + == NRATE_OVERRIDE_MCS_ONLY); + int bcmerror = 0; + + if (!ismcs) { + return (ratespec_t) rate; + } + + /* validate the combination of rate/mcs/stf is allowed */ + if (N_ENAB(wlc->pub) && ismcs) { + /* mcs only allowed when nmode */ + if (stf > PHY_TXC1_MODE_SDM) { + WL_ERROR("wl%d: %s: Invalid stf\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + + /* mcs 32 is a special case, DUP mode 40 only */ + if (rate == 32) { + if (!CHSPEC_IS40(wlc->home_chanspec) || + ((stf != PHY_TXC1_MODE_SISO) + && (stf != PHY_TXC1_MODE_CDD))) { + WL_ERROR("wl%d: %s: Invalid mcs 32\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + /* mcs > 7 must use stf SDM */ + } else if (rate > HIGHEST_SINGLE_STREAM_MCS) { + /* mcs > 7 must use stf SDM */ + if (stf != PHY_TXC1_MODE_SDM) { + WL_TRACE("wl%d: %s: enabling SDM mode for mcs %d\n", + WLCWLUNIT(wlc), __func__, rate); + stf = PHY_TXC1_MODE_SDM; + } + } else { + /* MCS 0-7 may use SISO, CDD, and for phy_rev >= 3 STBC */ + if ((stf > PHY_TXC1_MODE_STBC) || + (!WLC_STBC_CAP_PHY(wlc) + && (stf == PHY_TXC1_MODE_STBC))) { + WL_ERROR("wl%d: %s: Invalid STBC\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + } + } else if (IS_OFDM(rate)) { + if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) { + WL_ERROR("wl%d: %s: Invalid OFDM\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + } else if (IS_CCK(rate)) { + if ((cur_band->bandtype != WLC_BAND_2G) + || (stf != PHY_TXC1_MODE_SISO)) { + WL_ERROR("wl%d: %s: Invalid CCK\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + } else { + WL_ERROR("wl%d: %s: Unknown rate type\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + /* make sure multiple antennae are available for non-siso rates */ + if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) { + WL_ERROR("wl%d: %s: SISO antenna but !SISO request\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + + rspec = rate; + if (ismcs) { + rspec |= RSPEC_MIMORATE; + /* For STBC populate the STC field of the ratespec */ + if (stf == PHY_TXC1_MODE_STBC) { + u8 stc; + stc = 1; /* Nss for single stream is always 1 */ + rspec |= (stc << RSPEC_STC_SHIFT); + } + } + + rspec |= (stf << RSPEC_STF_SHIFT); + + if (override_mcs_only) + rspec |= RSPEC_OVERRIDE_MCS_ONLY; + + if (issgi) + rspec |= RSPEC_SHORT_GI; + + if ((rate != 0) + && !wlc_valid_rate(wlc, rspec, cur_band->bandtype, true)) { + return rate; + } + + return rspec; + done: + WL_ERROR("Hoark\n"); + return rate; +} + +/* formula: IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */ +static int +wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, + bool writeToShm) +{ + int idle_busy_ratio_x_16 = 0; + uint offset = + isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM : + M_TX_IDLE_BUSY_RATIO_X_16_CCK; + if (duty_cycle > 100 || duty_cycle < 0) { + WL_ERROR("wl%d: duty cycle value off limit\n", wlc->pub->unit); + return BCME_RANGE; + } + if (duty_cycle) + idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle; + /* Only write to shared memory when wl is up */ + if (writeToShm) + wlc_write_shm(wlc, offset, (u16) idle_busy_ratio_x_16); + + if (isOFDM) + wlc->tx_duty_cycle_ofdm = (u16) duty_cycle; + else + wlc->tx_duty_cycle_cck = (u16) duty_cycle; + + return BCME_OK; +} + +/* Read a single u16 from shared memory. + * SHM 'offset' needs to be an even address + */ +u16 wlc_read_shm(struct wlc_info *wlc, uint offset) +{ + return wlc_bmac_read_shm(wlc->hw, offset); +} + +/* Write a single u16 to shared memory. + * SHM 'offset' needs to be an even address + */ +void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v) +{ + wlc_bmac_write_shm(wlc->hw, offset, v); +} + +/* Set a range of shared memory to a value. + * SHM 'offset' needs to be an even address and + * Range length 'len' must be an even number of bytes + */ +void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len) +{ + /* offset and len need to be even */ + ASSERT((offset & 1) == 0); + ASSERT((len & 1) == 0); + + if (len <= 0) + return; + + wlc_bmac_set_shm(wlc->hw, offset, v, len); +} + +/* Copy a buffer to shared memory. + * SHM 'offset' needs to be an even address and + * Buffer length 'len' must be an even number of bytes + */ +void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, int len) +{ + /* offset and len need to be even */ + ASSERT((offset & 1) == 0); + ASSERT((len & 1) == 0); + + if (len <= 0) + return; + wlc_bmac_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL); + +} + +/* Copy from shared memory to a buffer. + * SHM 'offset' needs to be an even address and + * Buffer length 'len' must be an even number of bytes + */ +void wlc_copyfrom_shm(struct wlc_info *wlc, uint offset, void *buf, int len) +{ + /* offset and len need to be even */ + ASSERT((offset & 1) == 0); + ASSERT((len & 1) == 0); + + if (len <= 0) + return; + + wlc_bmac_copyfrom_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL); +} + +/* wrapper BMAC functions to for HIGH driver access */ +void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val) +{ + wlc_bmac_mctrl(wlc->hw, mask, val); +} + +void wlc_corereset(struct wlc_info *wlc, u32 flags) +{ + wlc_bmac_corereset(wlc->hw, flags); +} + +void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val, int bands) +{ + wlc_bmac_mhf(wlc->hw, idx, mask, val, bands); +} + +u16 wlc_mhf_get(struct wlc_info *wlc, u8 idx, int bands) +{ + return wlc_bmac_mhf_get(wlc->hw, idx, bands); +} + +int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks) +{ + return wlc_bmac_xmtfifo_sz_get(wlc->hw, fifo, blocks); +} + +void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len, + void *buf) +{ + wlc_bmac_write_template_ram(wlc->hw, offset, len, buf); +} + +void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len, + bool both) +{ + wlc_bmac_write_hw_bcntemplates(wlc->hw, bcn, len, both); +} + +void +wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, + const u8 *addr) +{ + wlc_bmac_set_addrmatch(wlc->hw, match_reg_offset, addr); +} + +void wlc_set_rcmta(struct wlc_info *wlc, int idx, const u8 *addr) +{ + wlc_bmac_set_rcmta(wlc->hw, idx, addr); +} + +void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, u32 *tsf_h_ptr) +{ + wlc_bmac_read_tsf(wlc->hw, tsf_l_ptr, tsf_h_ptr); +} + +void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin) +{ + wlc->band->CWmin = newmin; + wlc_bmac_set_cwmin(wlc->hw, newmin); +} + +void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax) +{ + wlc->band->CWmax = newmax; + wlc_bmac_set_cwmax(wlc->hw, newmax); +} + +void wlc_fifoerrors(struct wlc_info *wlc) +{ + + wlc_bmac_fifoerrors(wlc->hw); +} + +/* Search mem rw utilities */ + +void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit) +{ + wlc_bmac_pllreq(wlc->hw, set, req_bit); +} + +void wlc_reset_bmac_done(struct wlc_info *wlc) +{ +} + +void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode) +{ + wlc->ht_cap.cap_info &= ~HT_CAP_MIMO_PS_MASK; + wlc->ht_cap.cap_info |= (mimops_mode << IEEE80211_HT_CAP_SM_PS_SHIFT); + + if (AP_ENAB(wlc->pub) && wlc->clk) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, true); + } +} + +/* check for the particular priority flow control bit being set */ +bool +wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, wlc_txq_info_t *q, int prio) +{ + uint prio_mask; + + if (prio == ALLPRIO) { + prio_mask = TXQ_STOP_FOR_PRIOFC_MASK; + } else { + ASSERT(prio >= 0 && prio <= MAXPRIO); + prio_mask = NBITVAL(prio); + } + + return (q->stopped & prio_mask) == prio_mask; +} + +/* propogate the flow control to all interfaces using the given tx queue */ +void wlc_txflowcontrol(struct wlc_info *wlc, wlc_txq_info_t *qi, + bool on, int prio) +{ + uint prio_bits; + uint cur_bits; + + WL_ERROR("%s: flow control kicks in\n", __func__); + + if (prio == ALLPRIO) { + prio_bits = TXQ_STOP_FOR_PRIOFC_MASK; + } else { + ASSERT(prio >= 0 && prio <= MAXPRIO); + prio_bits = NBITVAL(prio); + } + + cur_bits = qi->stopped & prio_bits; + + /* Check for the case of no change and return early + * Otherwise update the bit and continue + */ + if (on) { + if (cur_bits == prio_bits) { + return; + } + mboolset(qi->stopped, prio_bits); + } else { + if (cur_bits == 0) { + return; + } + mboolclr(qi->stopped, prio_bits); + } + + /* If there is a flow control override we will not change the external + * flow control state. + */ + if (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK) { + return; + } + + wlc_txflowcontrol_signal(wlc, qi, on, prio); +} + +void +wlc_txflowcontrol_override(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, + uint override) +{ + uint prev_override; + + ASSERT(override != 0); + ASSERT((override & TXQ_STOP_FOR_PRIOFC_MASK) == 0); + + prev_override = (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK); + + /* Update the flow control bits and do an early return if there is + * no change in the external flow control state. + */ + if (on) { + mboolset(qi->stopped, override); + /* if there was a previous override bit on, then setting this + * makes no difference. + */ + if (prev_override) { + return; + } + + wlc_txflowcontrol_signal(wlc, qi, ON, ALLPRIO); + } else { + mboolclr(qi->stopped, override); + /* clearing an override bit will only make a difference for + * flow control if it was the only bit set. For any other + * override setting, just return + */ + if (prev_override != override) { + return; + } + + if (qi->stopped == 0) { + wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); + } else { + int prio; + + for (prio = MAXPRIO; prio >= 0; prio--) { + if (!mboolisset(qi->stopped, NBITVAL(prio))) + wlc_txflowcontrol_signal(wlc, qi, OFF, + prio); + } + } + } +} + +static void wlc_txflowcontrol_reset(struct wlc_info *wlc) +{ + wlc_txq_info_t *qi; + + for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { + if (qi->stopped) { + wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); + qi->stopped = 0; + } + } +} + +static void +wlc_txflowcontrol_signal(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, + int prio) +{ + struct wlc_if *wlcif; + + for (wlcif = wlc->wlcif_list; wlcif != NULL; wlcif = wlcif->next) { + if (wlcif->qi == qi && wlcif->flags & WLC_IF_LINKED) + wl_txflowcontrol(wlc->wl, wlcif->wlif, on, prio); + } +} + +static wlc_txq_info_t *wlc_txq_alloc(struct wlc_info *wlc, struct osl_info *osh) +{ + wlc_txq_info_t *qi, *p; + + qi = (wlc_txq_info_t *) wlc_calloc(osh, wlc->pub->unit, + sizeof(wlc_txq_info_t)); + if (qi == NULL) { + return NULL; + } + + /* Have enough room for control packets along with HI watermark */ + /* Also, add room to txq for total psq packets if all the SCBs leave PS mode */ + /* The watermark for flowcontrol to OS packets will remain the same */ + pktq_init(&qi->q, WLC_PREC_COUNT, + (2 * wlc->pub->tunables->datahiwat) + PKTQ_LEN_DEFAULT + + wlc->pub->psq_pkts_total); + + /* add this queue to the the global list */ + p = wlc->tx_queues; + if (p == NULL) { + wlc->tx_queues = qi; + } else { + while (p->next != NULL) + p = p->next; + p->next = qi; + } + + return qi; +} + +static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh, + wlc_txq_info_t *qi) +{ + wlc_txq_info_t *p; + + if (qi == NULL) + return; + + /* remove the queue from the linked list */ + p = wlc->tx_queues; + if (p == qi) + wlc->tx_queues = p->next; + else { + while (p != NULL && p->next != qi) + p = p->next; + ASSERT(p->next == qi); + if (p != NULL) + p->next = p->next->next; + } + + kfree(qi); +} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_mac80211.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_mac80211.h new file mode 100644 index 000000000000..f56b58141c09 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_mac80211.h @@ -0,0 +1,989 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_h_ +#define _wlc_h_ + +#include +#include +#include +#include +#include + +#define MA_WINDOW_SZ 8 /* moving average window size */ +#define WL_HWRXOFF 38 /* chip rx buffer offset */ +#define INVCHANNEL 255 /* invalid channel */ +#define MAXCOREREV 28 /* max # supported core revisions (0 .. MAXCOREREV - 1) */ +#define WLC_MAXMODULES 22 /* max # wlc_module_register() calls */ + +/* network protection config */ +#define WLC_PROT_G_SPEC 1 /* SPEC g protection */ +#define WLC_PROT_G_OVR 2 /* SPEC g prot override */ +#define WLC_PROT_G_USER 3 /* gmode specified by user */ +#define WLC_PROT_OVERLAP 4 /* overlap */ +#define WLC_PROT_N_USER 10 /* nmode specified by user */ +#define WLC_PROT_N_CFG 11 /* n protection */ +#define WLC_PROT_N_CFG_OVR 12 /* n protection override */ +#define WLC_PROT_N_NONGF 13 /* non-GF protection */ +#define WLC_PROT_N_NONGF_OVR 14 /* non-GF protection override */ +#define WLC_PROT_N_PAM_OVR 15 /* n preamble override */ +#define WLC_PROT_N_OBSS 16 /* non-HT OBSS present */ + +#define WLC_BITSCNT(x) bcm_bitcount((u8 *)&(x), sizeof(u8)) + +/* Maximum wait time for a MAC suspend */ +#define WLC_MAX_MAC_SUSPEND 83000 /* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */ + +/* Probe Response timeout - responses for probe requests older that this are tossed, zero to disable + */ +#define WLC_PRB_RESP_TIMEOUT 0 /* Disable probe response timeout */ + +/* transmit buffer max headroom for protocol headers */ +#define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN) + +/* For managing scan result lists */ +typedef struct wlc_bss_list { + uint count; + bool beacon; /* set for beacon, cleared for probe response */ + wlc_bss_info_t *ptrs[MAXBSS]; +} wlc_bss_list_t; + +#define SW_TIMER_MAC_STAT_UPD 30 /* periodic MAC stats update */ + +/* Double check that unsupported cores are not enabled */ +#if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV) +#error "Configuration for D11CONF includes unsupported versions." +#endif /* Bad versions */ + +#define VALID_COREREV(corerev) CONF_HAS(D11CONF, corerev) + +/* values for shortslot_override */ +#define WLC_SHORTSLOT_AUTO -1 /* Driver will manage Shortslot setting */ +#define WLC_SHORTSLOT_OFF 0 /* Turn off short slot */ +#define WLC_SHORTSLOT_ON 1 /* Turn on short slot */ + +/* value for short/long and mixmode/greenfield preamble */ + +#define WLC_LONG_PREAMBLE (0) +#define WLC_SHORT_PREAMBLE (1 << 0) +#define WLC_GF_PREAMBLE (1 << 1) +#define WLC_MM_PREAMBLE (1 << 2) +#define WLC_IS_MIMO_PREAMBLE(_pre) (((_pre) == WLC_GF_PREAMBLE) || ((_pre) == WLC_MM_PREAMBLE)) + +/* values for barker_preamble */ +#define WLC_BARKER_SHORT_ALLOWED 0 /* Short pre-amble allowed */ + +/* A fifo is full. Clear precedences related to that FIFO */ +#define WLC_TX_FIFO_CLEAR(wlc, fifo) ((wlc)->tx_prec_map &= ~(wlc)->fifo2prec_map[fifo]) + +/* Fifo is NOT full. Enable precedences for that FIFO */ +#define WLC_TX_FIFO_ENAB(wlc, fifo) ((wlc)->tx_prec_map |= (wlc)->fifo2prec_map[fifo]) + +/* TxFrameID */ +/* seq and frag bits: SEQNUM_SHIFT, FRAGNUM_MASK (802.11.h) */ +/* rate epoch bits: TXFID_RATE_SHIFT, TXFID_RATE_MASK ((wlc_rate.c) */ +#define TXFID_QUEUE_MASK 0x0007 /* Bits 0-2 */ +#define TXFID_SEQ_MASK 0x7FE0 /* Bits 5-15 */ +#define TXFID_SEQ_SHIFT 5 /* Number of bit shifts */ +#define TXFID_RATE_PROBE_MASK 0x8000 /* Bit 15 for rate probe */ +#define TXFID_RATE_MASK 0x0018 /* Mask for bits 3 and 4 */ +#define TXFID_RATE_SHIFT 3 /* Shift 3 bits for rate mask */ + +/* promote boardrev */ +#define BOARDREV_PROMOTABLE 0xFF /* from */ +#define BOARDREV_PROMOTED 1 /* to */ + +/* if wpa is in use then portopen is true when the group key is plumbed otherwise it is always true + */ +#define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) +#define WLC_SW_KEYS(wlc, bsscfg) ((((wlc)->wsec_swkeys) || \ + ((bsscfg)->wsec & WSEC_SWFLAG))) + +#define WLC_PORTOPEN(cfg) \ + (((cfg)->WPA_auth != WPA_AUTH_DISABLED && WSEC_ENABLED((cfg)->wsec)) ? \ + (cfg)->wsec_portopen : true) + +#define PS_ALLOWED(wlc) wlc_ps_allowed(wlc) +#define STAY_AWAKE(wlc) wlc_stay_awake(wlc) + +#define DATA_BLOCK_TX_SUPR (1 << 4) + +/* 802.1D Priority to TX FIFO number for wme */ +extern const u8 prio2fifo[]; + +/* Ucode MCTL_WAKE override bits */ +#define WLC_WAKE_OVERRIDE_CLKCTL 0x01 +#define WLC_WAKE_OVERRIDE_PHYREG 0x02 +#define WLC_WAKE_OVERRIDE_MACSUSPEND 0x04 +#define WLC_WAKE_OVERRIDE_TXFIFO 0x08 +#define WLC_WAKE_OVERRIDE_FORCEFAST 0x10 + +/* stuff pulled in from wlc.c */ + +/* Interrupt bit error summary. Don't include I_RU: we refill DMA at other + * times; and if we run out, constant I_RU interrupts may cause lockup. We + * will still get error counts from rx0ovfl. + */ +#define I_ERRORS (I_PC | I_PD | I_DE | I_RO | I_XU) +/* default software intmasks */ +#define DEF_RXINTMASK (I_RI) /* enable rx int on rxfifo only */ +#define DEF_MACINTMASK (MI_TXSTOP | MI_TBTT | MI_ATIMWINEND | MI_PMQ | \ + MI_PHYTXERR | MI_DMAINT | MI_TFS | MI_BG_NOISE | \ + MI_CCA | MI_TO | MI_GP0 | MI_RFDISABLE | MI_PWRUP) + +#define RETRY_SHORT_DEF 7 /* Default Short retry Limit */ +#define RETRY_SHORT_MAX 255 /* Maximum Short retry Limit */ +#define RETRY_LONG_DEF 4 /* Default Long retry count */ +#define RETRY_SHORT_FB 3 /* Short retry count for fallback rate */ +#define RETRY_LONG_FB 2 /* Long retry count for fallback rate */ + +#define MAXTXPKTS 6 /* max # pkts pending */ + +/* frameburst */ +#define MAXTXFRAMEBURST 8 /* vanilla xpress mode: max frames/burst */ +#define MAXFRAMEBURST_TXOP 10000 /* Frameburst TXOP in usec */ + +/* Per-AC retry limit register definitions; uses bcmdefs.h bitfield macros */ +#define EDCF_SHORT_S 0 +#define EDCF_SFB_S 4 +#define EDCF_LONG_S 8 +#define EDCF_LFB_S 12 +#define EDCF_SHORT_M BITFIELD_MASK(4) +#define EDCF_SFB_M BITFIELD_MASK(4) +#define EDCF_LONG_M BITFIELD_MASK(4) +#define EDCF_LFB_M BITFIELD_MASK(4) + +#define WLC_WME_RETRY_SHORT_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_SHORT) +#define WLC_WME_RETRY_SFB_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_SFB) +#define WLC_WME_RETRY_LONG_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_LONG) +#define WLC_WME_RETRY_LFB_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_LFB) + +#define WLC_WME_RETRY_SHORT_SET(wlc, ac, val) \ + (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SHORT, val)) +#define WLC_WME_RETRY_SFB_SET(wlc, ac, val) \ + (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SFB, val)) +#define WLC_WME_RETRY_LONG_SET(wlc, ac, val) \ + (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LONG, val)) +#define WLC_WME_RETRY_LFB_SET(wlc, ac, val) \ + (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LFB, val)) + +/* PLL requests */ +#define WLC_PLLREQ_SHARED 0x1 /* pll is shared on old chips */ +#define WLC_PLLREQ_RADIO_MON 0x2 /* hold pll for radio monitor register checking */ +#define WLC_PLLREQ_FLIP 0x4 /* hold/release pll for some short operation */ + +/* Do we support this rate? */ +#define VALID_RATE_DBG(wlc, rspec) wlc_valid_rate(wlc, rspec, WLC_BAND_AUTO, true) + +/* + * Macros to check if AP or STA is active. + * AP Active means more than just configured: driver and BSS are "up"; + * that is, we are beaconing/responding as an AP (aps_associated). + * STA Active similarly means the driver is up and a configured STA BSS + * is up: either associated (stas_associated) or trying. + * + * Macro definitions vary as per AP/STA ifdefs, allowing references to + * ifdef'd structure fields and constant values (0) for optimization. + * Make sure to enclose blocks of code such that any routines they + * reference can also be unused and optimized out by the linker. + */ +/* NOTE: References structure fields defined in wlc.h */ +#define AP_ACTIVE(wlc) (0) + +/* + * Detect Card removed. + * Even checking an sbconfig register read will not false trigger when the core is in reset. + * it breaks CF address mechanism. Accessing gphy phyversion will cause SB error if aphy + * is in reset on 4306B0-DB. Need a simple accessible reg with fixed 0/1 pattern + * (some platforms return all 0). + * If clocks are present, call the sb routine which will figure out if the device is removed. + */ +#define DEVICEREMOVED(wlc) \ + ((wlc->hw->clk) ? \ + ((R_REG(wlc->hw->osh, &wlc->hw->regs->maccontrol) & \ + (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN) : \ + (si_deviceremoved(wlc->hw->sih))) + +#define WLCWLUNIT(wlc) ((wlc)->pub->unit) + +typedef struct wlc_protection { + bool _g; /* use g spec protection, driver internal */ + s8 g_override; /* override for use of g spec protection */ + u8 gmode_user; /* user config gmode, operating band->gmode is different */ + s8 overlap; /* Overlap BSS/IBSS protection for both 11g and 11n */ + s8 nmode_user; /* user config nmode, operating pub->nmode is different */ + s8 n_cfg; /* use OFDM protection on MIMO frames */ + s8 n_cfg_override; /* override for use of N protection */ + bool nongf; /* non-GF present protection */ + s8 nongf_override; /* override for use of GF protection */ + s8 n_pam_override; /* override for preamble: MM or GF */ + bool n_obss; /* indicated OBSS Non-HT STA present */ + + uint longpre_detect_timeout; /* #sec until long preamble bcns gone */ + uint barker_detect_timeout; /* #sec until bcns signaling Barker long preamble */ + /* only is gone */ + uint ofdm_ibss_timeout; /* #sec until ofdm IBSS beacons gone */ + uint ofdm_ovlp_timeout; /* #sec until ofdm overlapping BSS bcns gone */ + uint nonerp_ibss_timeout; /* #sec until nonerp IBSS beacons gone */ + uint nonerp_ovlp_timeout; /* #sec until nonerp overlapping BSS bcns gone */ + uint g_ibss_timeout; /* #sec until bcns signaling Use_Protection gone */ + uint n_ibss_timeout; /* #sec until bcns signaling Use_OFDM_Protection gone */ + uint ht20in40_ovlp_timeout; /* #sec until 20MHz overlapping OPMODE gone */ + uint ht20in40_ibss_timeout; /* #sec until 20MHz-only HT station bcns gone */ + uint non_gf_ibss_timeout; /* #sec until non-GF bcns gone */ +} wlc_protection_t; + +/* anything affects the single/dual streams/antenna operation */ +typedef struct wlc_stf { + u8 hw_txchain; /* HW txchain bitmap cfg */ + u8 txchain; /* txchain bitmap being used */ + u8 txstreams; /* number of txchains being used */ + + u8 hw_rxchain; /* HW rxchain bitmap cfg */ + u8 rxchain; /* rxchain bitmap being used */ + u8 rxstreams; /* number of rxchains being used */ + + u8 ant_rx_ovr; /* rx antenna override */ + s8 txant; /* userTx antenna setting */ + u16 phytxant; /* phyTx antenna setting in txheader */ + + u8 ss_opmode; /* singlestream Operational mode, 0:siso; 1:cdd */ + bool ss_algosel_auto; /* if true, use wlc->stf->ss_algo_channel; */ + /* else use wlc->band->stf->ss_mode_band; */ + u16 ss_algo_channel; /* ss based on per-channel algo: 0: SISO, 1: CDD 2: STBC */ + u8 no_cddstbc; /* stf override, 1: no CDD (or STBC) allowed */ + + u8 rxchain_restore_delay; /* delay time to restore default rxchain */ + + s8 ldpc; /* AUTO/ON/OFF ldpc cap supported */ + u8 txcore[MAX_STREAMS_SUPPORTED + 1]; /* bitmap of selected core for each Nsts */ + s8 spatial_policy; +} wlc_stf_t; + +#define WLC_STF_SS_STBC_TX(wlc, scb) \ + (((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) || \ + (SCB_STBC_CAP((scb)) && \ + (wlc)->band->band_stf_stbc_tx == AUTO && \ + isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC)))) + +#define WLC_STBC_CAP_PHY(wlc) (WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3)) + +#define WLC_SGI_CAP_PHY(wlc) ((WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3)) || \ + WLCISLCNPHY(wlc->band)) + +#define WLC_CHAN_PHYTYPE(x) (((x) & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT) +#define WLC_CHAN_CHANNEL(x) (((x) & RXS_CHAN_ID_MASK) >> RXS_CHAN_ID_SHIFT) +#define WLC_RX_CHANNEL(rxh) (WLC_CHAN_CHANNEL((rxh)->RxChan)) + +/* wlc_bss_info flag bit values */ +#define WLC_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */ + +/* Flags used in wlc_txq_info.stopped */ +#define TXQ_STOP_FOR_PRIOFC_MASK 0x000000FF /* per prio flow control bits */ +#define TXQ_STOP_FOR_PKT_DRAIN 0x00000100 /* stop txq enqueue for packet drain */ +#define TXQ_STOP_FOR_AMPDU_FLOW_CNTRL 0x00000200 /* stop txq enqueue for ampdu flow control */ + +#define WLC_HT_WEP_RESTRICT 0x01 /* restrict HT with WEP */ +#define WLC_HT_TKIP_RESTRICT 0x02 /* restrict HT with TKIP */ + +/* + * core state (mac) + */ +struct wlccore { + uint coreidx; /* # sb enumerated core */ + + /* fifo */ + uint *txavail[NFIFO]; /* # tx descriptors available */ + s16 txpktpend[NFIFO]; /* tx admission control */ + + macstat_t *macstat_snapshot; /* mac hw prev read values */ +}; + +/* + * band state (phy+ana+radio) + */ +struct wlcband { + int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */ + uint bandunit; /* bandstate[] index */ + + u16 phytype; /* phytype */ + u16 phyrev; + u16 radioid; + u16 radiorev; + wlc_phy_t *pi; /* pointer to phy specific information */ + bool abgphy_encore; + + u8 gmode; /* currently active gmode (see wlioctl.h) */ + + struct scb *hwrs_scb; /* permanent scb for hw rateset */ + + wlc_rateset_t defrateset; /* band-specific copy of default_bss.rateset */ + + ratespec_t rspec_override; /* 802.11 rate override */ + ratespec_t mrspec_override; /* multicast rate override */ + u8 band_stf_ss_mode; /* Configured STF type, 0:siso; 1:cdd */ + s8 band_stf_stbc_tx; /* STBC TX 0:off; 1:force on; -1:auto */ + wlc_rateset_t hw_rateset; /* rates supported by chip (phy-specific) */ + u8 basic_rate[WLC_MAXRATE + 1]; /* basic rates indexed by rate */ + bool mimo_cap_40; /* 40 MHz cap enabled on this band */ + s8 antgain; /* antenna gain from srom */ + + u16 CWmin; /* The minimum size of contention window, in unit of aSlotTime */ + u16 CWmax; /* The maximum size of contention window, in unit of aSlotTime */ + u16 bcntsfoff; /* beacon tsf offset */ +}; + +/* generic function callback takes just one arg */ +typedef void (*cb_fn_t) (void *); + +/* tx completion callback takes 3 args */ +typedef void (*pkcb_fn_t) (struct wlc_info *wlc, uint txstatus, void *arg); + +typedef struct pkt_cb { + pkcb_fn_t fn; /* function to call when tx frame completes */ + void *arg; /* void arg for fn */ + u8 nextidx; /* index of next call back if threading */ + bool entered; /* recursion check */ +} pkt_cb_t; + + /* module control blocks */ +typedef struct modulecb { + char name[32]; /* module name : NULL indicates empty array member */ + const bcm_iovar_t *iovars; /* iovar table */ + void *hdl; /* handle passed when handler 'doiovar' is called */ + watchdog_fn_t watchdog_fn; /* watchdog handler */ + iovar_fn_t iovar_fn; /* iovar handler */ + down_fn_t down_fn; /* down handler. Note: the int returned + * by the down function is a count of the + * number of timers that could not be + * freed. + */ +} modulecb_t; + + /* dump control blocks */ +typedef struct dumpcb_s { + const char *name; /* dump name */ + dump_fn_t dump_fn; /* 'wl dump' handler */ + void *dump_fn_arg; + struct dumpcb_s *next; +} dumpcb_t; + +/* virtual interface */ +struct wlc_if { + struct wlc_if *next; + u8 type; /* WLC_IFTYPE_BSS or WLC_IFTYPE_WDS */ + u8 index; /* assigned in wl_add_if(), index of the wlif if any, + * not necessarily corresponding to bsscfg._idx or + * AID2PVBMAP(scb). + */ + u8 flags; /* flags for the interface */ + struct wl_if *wlif; /* pointer to wlif */ + struct wlc_txq_info *qi; /* pointer to associated tx queue */ + union { + struct scb *scb; /* pointer to scb if WLC_IFTYPE_WDS */ + struct wlc_bsscfg *bsscfg; /* pointer to bsscfg if WLC_IFTYPE_BSS */ + } u; +}; + +/* flags for the interface */ +#define WLC_IF_LINKED 0x02 /* this interface is linked to a wl_if */ + +typedef struct wlc_hwband { + int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */ + uint bandunit; /* bandstate[] index */ + u16 mhfs[MHFMAX]; /* MHF array shadow */ + u8 bandhw_stf_ss_mode; /* HW configured STF type, 0:siso; 1:cdd */ + u16 CWmin; + u16 CWmax; + u32 core_flags; + + u16 phytype; /* phytype */ + u16 phyrev; + u16 radioid; + u16 radiorev; + wlc_phy_t *pi; /* pointer to phy specific information */ + bool abgphy_encore; +} wlc_hwband_t; + +struct wlc_hw_info { + struct osl_info *osh; /* pointer to os handle */ + bool _piomode; /* true if pio mode */ + struct wlc_info *wlc; + + /* fifo */ + struct hnddma_pub *di[NFIFO]; /* hnddma handles, per fifo */ + + uint unit; /* device instance number */ + + /* version info */ + u16 vendorid; /* PCI vendor id */ + u16 deviceid; /* PCI device id */ + uint corerev; /* core revision */ + u8 sromrev; /* version # of the srom */ + u16 boardrev; /* version # of particular board */ + u32 boardflags; /* Board specific flags from srom */ + u32 boardflags2; /* More board flags if sromrev >= 4 */ + u32 machwcap; /* MAC capabilities (corerev >= 13) */ + u32 machwcap_backup; /* backup of machwcap (corerev >= 13) */ + u16 ucode_dbgsel; /* dbgsel for ucode debug(config gpio) */ + + si_t *sih; /* SB handle (cookie for siutils calls) */ + char *vars; /* "environment" name=value */ + uint vars_size; /* size of vars, free vars on detach */ + d11regs_t *regs; /* pointer to device registers */ + void *physhim; /* phy shim layer handler */ + void *phy_sh; /* pointer to shared phy state */ + wlc_hwband_t *band; /* pointer to active per-band state */ + wlc_hwband_t *bandstate[MAXBANDS]; /* per-band state (one per phy/radio) */ + u16 bmac_phytxant; /* cache of high phytxant state */ + bool shortslot; /* currently using 11g ShortSlot timing */ + u16 SRL; /* 802.11 dot11ShortRetryLimit */ + u16 LRL; /* 802.11 dot11LongRetryLimit */ + u16 SFBL; /* Short Frame Rate Fallback Limit */ + u16 LFBL; /* Long Frame Rate Fallback Limit */ + + bool up; /* d11 hardware up and running */ + uint now; /* # elapsed seconds */ + uint _nbands; /* # bands supported */ + chanspec_t chanspec; /* bmac chanspec shadow */ + + uint *txavail[NFIFO]; /* # tx descriptors available */ + u16 *xmtfifo_sz; /* fifo size in 256B for each xmt fifo */ + + mbool pllreq; /* pll requests to keep PLL on */ + + u8 suspended_fifos; /* Which TX fifo to remain awake for */ + u32 maccontrol; /* Cached value of maccontrol */ + uint mac_suspend_depth; /* current depth of mac_suspend levels */ + u32 wake_override; /* Various conditions to force MAC to WAKE mode */ + u32 mute_override; /* Prevent ucode from sending beacons */ + u8 etheraddr[ETH_ALEN]; /* currently configured ethernet address */ + u32 led_gpio_mask; /* LED GPIO Mask */ + bool noreset; /* true= do not reset hw, used by WLC_OUT */ + bool forcefastclk; /* true if the h/w is forcing the use of fast clk */ + bool clk; /* core is out of reset and has clock */ + bool sbclk; /* sb has clock */ + struct bmac_pmq *bmac_pmq; /* bmac PM states derived from ucode PMQ */ + bool phyclk; /* phy is out of reset and has clock */ + bool dma_lpbk; /* core is in DMA loopback */ + + bool ucode_loaded; /* true after ucode downloaded */ + + + u8 hw_stf_ss_opmode; /* STF single stream operation mode */ + u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic + * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board + */ + u32 antsel_avail; /* + * put struct antsel_info here if more info is + * needed + */ +}; + +/* TX Queue information + * + * Each flow of traffic out of the device has a TX Queue with independent + * flow control. Several interfaces may be associated with a single TX Queue + * if they belong to the same flow of traffic from the device. For multi-channel + * operation there are independent TX Queues for each channel. + */ +typedef struct wlc_txq_info { + struct wlc_txq_info *next; + struct pktq q; + uint stopped; /* tx flow control bits */ +} wlc_txq_info_t; + +/* + * Principal common (os-independent) software data structure. + */ +struct wlc_info { + struct wlc_pub *pub; /* pointer to wlc public state */ + struct osl_info *osh; /* pointer to os handle */ + struct wl_info *wl; /* pointer to os-specific private state */ + d11regs_t *regs; /* pointer to device registers */ + + struct wlc_hw_info *hw; /* HW related state used primarily by BMAC */ + + /* clock */ + int clkreq_override; /* setting for clkreq for PCIE : Auto, 0, 1 */ + u16 fastpwrup_dly; /* time in us needed to bring up d11 fast clock */ + + /* interrupt */ + u32 macintstatus; /* bit channel between isr and dpc */ + u32 macintmask; /* sw runtime master macintmask value */ + u32 defmacintmask; /* default "on" macintmask value */ + + /* up and down */ + bool device_present; /* (removable) device is present */ + + bool clk; /* core is out of reset and has clock */ + + /* multiband */ + struct wlccore *core; /* pointer to active io core */ + struct wlcband *band; /* pointer to active per-band state */ + struct wlccore *corestate; /* per-core state (one per hw core) */ + /* per-band state (one per phy/radio): */ + struct wlcband *bandstate[MAXBANDS]; + + bool war16165; /* PCI slow clock 16165 war flag */ + + bool tx_suspended; /* data fifos need to remain suspended */ + + uint txpend16165war; + + /* packet queue */ + uint qvalid; /* DirFrmQValid and BcMcFrmQValid */ + + /* Regulatory power limits */ + s8 txpwr_local_max; /* regulatory local txpwr max */ + u8 txpwr_local_constraint; /* local power contraint in dB */ + + + struct ampdu_info *ampdu; /* ampdu module handler */ + struct antsel_info *asi; /* antsel module handler */ + wlc_cm_info_t *cmi; /* channel manager module handler */ + + void *btparam; /* bus type specific cookie */ + + uint vars_size; /* size of vars, free vars on detach */ + + u16 vendorid; /* PCI vendor id */ + u16 deviceid; /* PCI device id */ + uint ucode_rev; /* microcode revision */ + + u32 machwcap; /* MAC capabilities, BMAC shadow */ + + u8 perm_etheraddr[ETH_ALEN]; /* original sprom local ethernet address */ + + bool bandlocked; /* disable auto multi-band switching */ + bool bandinit_pending; /* track band init in auto band */ + + bool radio_monitor; /* radio timer is running */ + bool down_override; /* true=down */ + bool going_down; /* down path intermediate variable */ + + bool mpc; /* enable minimum power consumption */ + u8 mpc_dlycnt; /* # of watchdog cnt before turn disable radio */ + u8 mpc_offcnt; /* # of watchdog cnt that radio is disabled */ + u8 mpc_delay_off; /* delay radio disable by # of watchdog cnt */ + u8 prev_non_delay_mpc; /* prev state wlc_is_non_delay_mpc */ + + /* timer */ + struct wl_timer *wdtimer; /* timer for watchdog routine */ + uint fast_timer; /* Periodic timeout for 'fast' timer */ + uint slow_timer; /* Periodic timeout for 'slow' timer */ + uint glacial_timer; /* Periodic timeout for 'glacial' timer */ + uint phycal_mlo; /* last time measurelow calibration was done */ + uint phycal_txpower; /* last time txpower calibration was done */ + + struct wl_timer *radio_timer; /* timer for hw radio button monitor routine */ + struct wl_timer *pspoll_timer; /* periodic pspoll timer */ + + /* promiscuous */ + bool monitor; /* monitor (MPDU sniffing) mode */ + bool bcnmisc_ibss; /* bcns promisc mode override for IBSS */ + bool bcnmisc_scan; /* bcns promisc mode override for scan */ + bool bcnmisc_monitor; /* bcns promisc mode override for monitor */ + + u8 bcn_wait_prd; /* max waiting period (for beacon) in 1024TU */ + + /* driver feature */ + bool _rifs; /* enable per-packet rifs */ + s32 rifs_advert; /* RIFS mode advertisement */ + s8 sgi_tx; /* sgi tx */ + bool wet; /* true if wireless ethernet bridging mode */ + + /* AP-STA synchronization, power save */ + bool check_for_unaligned_tbtt; /* check unaligned tbtt flag */ + bool PM_override; /* no power-save flag, override PM(user input) */ + bool PMenabled; /* current power-management state (CAM or PS) */ + bool PMpending; /* waiting for tx status with PM indicated set */ + bool PMblocked; /* block any PSPolling in PS mode, used to buffer + * AP traffic, also used to indicate in progress + * of scan, rm, etc. off home channel activity. + */ + bool PSpoll; /* whether there is an outstanding PS-Poll frame */ + u8 PM; /* power-management mode (CAM, PS or FASTPS) */ + bool PMawakebcn; /* bcn recvd during current waking state */ + + bool WME_PM_blocked; /* Can STA go to PM when in WME Auto mode */ + bool wake; /* host-specified PS-mode sleep state */ + u8 pspoll_prd; /* pspoll interval in milliseconds */ + u8 bcn_li_bcn; /* beacon listen interval in # beacons */ + u8 bcn_li_dtim; /* beacon listen interval in # dtims */ + + bool WDarmed; /* watchdog timer is armed */ + u32 WDlast; /* last time wlc_watchdog() was called */ + + /* WME */ + ac_bitmap_t wme_dp; /* Discard (oldest first) policy per AC */ + bool wme_apsd; /* enable Advanced Power Save Delivery */ + ac_bitmap_t wme_admctl; /* bit i set if AC i under admission control */ + u16 edcf_txop[AC_COUNT]; /* current txop for each ac */ + wme_param_ie_t wme_param_ie; /* WME parameter info element, which on STA + * contains parameters in use locally, and on + * AP contains parameters advertised to STA + * in beacons and assoc responses. + */ + bool wme_prec_queuing; /* enable/disable non-wme STA prec queuing */ + u16 wme_retries[AC_COUNT]; /* per-AC retry limits */ + + int vlan_mode; /* OK to use 802.1Q Tags (ON, OFF, AUTO) */ + u16 tx_prec_map; /* Precedence map based on HW FIFO space */ + u16 fifo2prec_map[NFIFO]; /* pointer to fifo2_prec map based on WME */ + + /* BSS Configurations */ + wlc_bsscfg_t *bsscfg[WLC_MAXBSSCFG]; /* set of BSS configurations, idx 0 is default and + * always valid + */ + wlc_bsscfg_t *cfg; /* the primary bsscfg (can be AP or STA) */ + u8 stas_associated; /* count of ASSOCIATED STA bsscfgs */ + u8 aps_associated; /* count of UP AP bsscfgs */ + u8 block_datafifo; /* prohibit posting frames to data fifos */ + bool bcmcfifo_drain; /* TX_BCMC_FIFO is set to drain */ + + /* tx queue */ + wlc_txq_info_t *tx_queues; /* common TX Queue list */ + + /* event */ + wlc_eventq_t *eventq; /* event queue for deferred processing */ + + /* security */ + wsec_key_t *wsec_keys[WSEC_MAX_KEYS]; /* dynamic key storage */ + wsec_key_t *wsec_def_keys[WLC_DEFAULT_KEYS]; /* default key storage */ + bool wsec_swkeys; /* indicates that all keys should be + * treated as sw keys (used for debugging) + */ + modulecb_t *modulecb; + dumpcb_t *dumpcb_head; + + u8 mimoft; /* SIGN or 11N */ + u8 mimo_band_bwcap; /* bw cap per band type */ + s8 txburst_limit_override; /* tx burst limit override */ + u16 txburst_limit; /* tx burst limit value */ + s8 cck_40txbw; /* 11N, cck tx b/w override when in 40MHZ mode */ + s8 ofdm_40txbw; /* 11N, ofdm tx b/w override when in 40MHZ mode */ + s8 mimo_40txbw; /* 11N, mimo tx b/w override when in 40MHZ mode */ + /* HT CAP IE being advertised by this node: */ + struct ieee80211_ht_cap ht_cap; + + uint seckeys; /* 54 key table shm address */ + uint tkmickeys; /* 12 TKIP MIC key table shm address */ + + wlc_bss_info_t *default_bss; /* configured BSS parameters */ + + u16 AID; /* association ID */ + u16 counter; /* per-sdu monotonically increasing counter */ + u16 mc_fid_counter; /* BC/MC FIFO frame ID counter */ + + bool ibss_allowed; /* false, all IBSS will be ignored during a scan + * and the driver will not allow the creation of + * an IBSS network + */ + bool ibss_coalesce_allowed; + + char country_default[WLC_CNTRY_BUF_SZ]; /* saved country for leaving 802.11d + * auto-country mode + */ + char autocountry_default[WLC_CNTRY_BUF_SZ]; /* initial country for 802.11d + * auto-country mode + */ +#ifdef BCMDBG + bcm_tlv_t *country_ie_override; /* debug override of announced Country IE */ +#endif + + u16 prb_resp_timeout; /* do not send prb resp if request older than this, + * 0 = disable + */ + + wlc_rateset_t sup_rates_override; /* use only these rates in 11g supported rates if + * specifed + */ + + chanspec_t home_chanspec; /* shared home chanspec */ + + /* PHY parameters */ + chanspec_t chanspec; /* target operational channel */ + u16 usr_fragthresh; /* user configured fragmentation threshold */ + u16 fragthresh[NFIFO]; /* per-fifo fragmentation thresholds */ + u16 RTSThresh; /* 802.11 dot11RTSThreshold */ + u16 SRL; /* 802.11 dot11ShortRetryLimit */ + u16 LRL; /* 802.11 dot11LongRetryLimit */ + u16 SFBL; /* Short Frame Rate Fallback Limit */ + u16 LFBL; /* Long Frame Rate Fallback Limit */ + + /* network config */ + bool shortpreamble; /* currently operating with CCK ShortPreambles */ + bool shortslot; /* currently using 11g ShortSlot timing */ + s8 barker_preamble; /* current Barker Preamble Mode */ + s8 shortslot_override; /* 11g ShortSlot override */ + bool include_legacy_erp; /* include Legacy ERP info elt ID 47 as well as g ID 42 */ + bool barker_overlap_control; /* true: be aware of overlapping BSSs for barker */ + bool ignore_bcns; /* override: ignore non shortslot bcns in a 11g network */ + bool legacy_probe; /* restricts probe requests to CCK rates */ + + wlc_protection_t *protection; + s8 PLCPHdr_override; /* 802.11b Preamble Type override */ + + wlc_stf_t *stf; + + pkt_cb_t *pkt_callback; /* tx completion callback handlers */ + + u32 txretried; /* tx retried number in one msdu */ + + ratespec_t bcn_rspec; /* save bcn ratespec purpose */ + + bool apsd_sta_usp; /* Unscheduled Service Period in progress on STA */ + struct wl_timer *apsd_trigger_timer; /* timer for wme apsd trigger frames */ + u32 apsd_trigger_timeout; /* timeout value for apsd_trigger_timer (in ms) + * 0 == disable + */ + ac_bitmap_t apsd_trigger_ac; /* Permissible Acess Category in which APSD Null + * Trigger frames can be send + */ + u8 htphy_membership; /* HT PHY membership */ + + bool _regulatory_domain; /* 802.11d enabled? */ + + u8 mimops_PM; + + u8 txpwr_percent; /* power output percentage */ + + u8 ht_wsec_restriction; /* the restriction of HT with TKIP or WEP */ + + uint tempsense_lasttime; + + u16 tx_duty_cycle_ofdm; /* maximum allowed duty cycle for OFDM */ + u16 tx_duty_cycle_cck; /* maximum allowed duty cycle for CCK */ + + u16 next_bsscfg_ID; + + struct wlc_if *wlcif_list; /* linked list of wlc_if structs */ + wlc_txq_info_t *active_queue; /* txq for the currently active transmit context */ + u32 mpc_dur; /* total time (ms) in mpc mode except for the + * portion since radio is turned off last time + */ + u32 mpc_laston_ts; /* timestamp (ms) when radio is turned off last + * time + */ + bool pr80838_war; + uint hwrxoff; +}; + +/* antsel module specific state */ +struct antsel_info { + struct wlc_info *wlc; /* pointer to main wlc structure */ + struct wlc_pub *pub; /* pointer to public fn */ + u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic + * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board + */ + u8 antsel_antswitch; /* board level antenna switch type */ + bool antsel_avail; /* Ant selection availability (SROM based) */ + wlc_antselcfg_t antcfg_11n; /* antenna configuration */ + wlc_antselcfg_t antcfg_cur; /* current antenna config (auto) */ +}; + +#define CHANNEL_BANDUNIT(wlc, ch) (((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX) +#define OTHERBANDUNIT(wlc) ((uint)((wlc)->band->bandunit ? BAND_2G_INDEX : BAND_5G_INDEX)) + +#define IS_MBAND_UNLOCKED(wlc) \ + ((NBANDS(wlc) > 1) && !(wlc)->bandlocked) + +#define WLC_BAND_PI_RADIO_CHANSPEC wlc_phy_chanspec_get(wlc->band->pi) + +/* sum the individual fifo tx pending packet counts */ +#define TXPKTPENDTOT(wlc) ((wlc)->core->txpktpend[0] + (wlc)->core->txpktpend[1] + \ + (wlc)->core->txpktpend[2] + (wlc)->core->txpktpend[3]) +#define TXPKTPENDGET(wlc, fifo) ((wlc)->core->txpktpend[(fifo)]) +#define TXPKTPENDINC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] += (val)) +#define TXPKTPENDDEC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] -= (val)) +#define TXPKTPENDCLR(wlc, fifo) ((wlc)->core->txpktpend[(fifo)] = 0) +#define TXAVAIL(wlc, fifo) (*(wlc)->core->txavail[(fifo)]) +#define GETNEXTTXP(wlc, _queue) \ + dma_getnexttxp((wlc)->hw->di[(_queue)], HNDDMA_RANGE_TRANSMITTED) + +#define WLC_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \ + ((len1 == len2) && !memcmp(ssid1, ssid2, len1)) + +extern void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus); +extern void wlc_fatal_error(struct wlc_info *wlc); +extern void wlc_bmac_rpc_watchdog(struct wlc_info *wlc); +extern void wlc_recv(struct wlc_info *wlc, struct sk_buff *p); +extern bool wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2); +extern void wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, + bool commit, s8 txpktpend); +extern void wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend); +extern void wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, + uint prec); +extern void wlc_info_init(struct wlc_info *wlc, int unit); +extern void wlc_print_txstatus(tx_status_t *txs); +extern int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks); +extern void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len, + void *buf); +extern void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len, + bool both); +#if defined(BCMDBG) +extern void wlc_get_rcmta(struct wlc_info *wlc, int idx, + u8 *addr); +#endif +extern void wlc_set_rcmta(struct wlc_info *wlc, int idx, + const u8 *addr); +extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, + const u8 *addr); +extern void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, + u32 *tsf_h_ptr); +extern void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin); +extern void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax); +extern void wlc_fifoerrors(struct wlc_info *wlc); +extern void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit); +extern void wlc_reset_bmac_done(struct wlc_info *wlc); +extern void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val); +extern void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us); +extern void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc); + +#if defined(BCMDBG) +extern void wlc_print_rxh(d11rxhdr_t *rxh); +extern void wlc_print_hdrs(struct wlc_info *wlc, const char *prefix, u8 *frame, + d11txh_t *txh, d11rxhdr_t *rxh, uint len); +extern void wlc_print_txdesc(d11txh_t *txh); +#endif +#if defined(BCMDBG) +extern void wlc_print_dot11_mac_hdr(u8 *buf, int len); +#endif + +extern void wlc_setxband(struct wlc_hw_info *wlc_hw, uint bandunit); +extern void wlc_coredisable(struct wlc_hw_info *wlc_hw); + +extern bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rate, int band, + bool verbose); +extern void wlc_ap_upd(struct wlc_info *wlc); + +/* helper functions */ +extern void wlc_shm_ssid_upd(struct wlc_info *wlc, wlc_bsscfg_t *cfg); +extern int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config); + +extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc); +extern void wlc_mac_bcn_promisc(struct wlc_info *wlc); +extern void wlc_mac_promisc(struct wlc_info *wlc); +extern void wlc_txflowcontrol(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, + int prio); +extern void wlc_txflowcontrol_override(struct wlc_info *wlc, wlc_txq_info_t *qi, + bool on, uint override); +extern bool wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, + wlc_txq_info_t *qi, int prio); +extern void wlc_send_q(struct wlc_info *wlc, wlc_txq_info_t *qi); +extern int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifo); + +extern u16 wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, + uint mac_len); +extern ratespec_t wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, + bool use_rspec, u16 mimo_ctlchbw); +extern u16 wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, + ratespec_t rts_rate, ratespec_t frame_rate, + u8 rts_preamble_type, + u8 frame_preamble_type, uint frame_len, + bool ba); + +extern void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs); + +#if defined(BCMDBG) +extern void wlc_dump_ie(struct wlc_info *wlc, bcm_tlv_t *ie, + struct bcmstrbuf *b); +#endif + +extern bool wlc_ps_check(struct wlc_info *wlc); +extern void wlc_reprate_init(struct wlc_info *wlc); +extern void wlc_bsscfg_reprate_init(wlc_bsscfg_t *bsscfg); +extern void wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, + u32 b_low); +extern u32 wlc_calc_tbtt_offset(u32 bi, u32 tsf_h, u32 tsf_l); + +/* Shared memory access */ +extern void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v); +extern u16 wlc_read_shm(struct wlc_info *wlc, uint offset); +extern void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len); +extern void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, + int len); +extern void wlc_copyfrom_shm(struct wlc_info *wlc, uint offset, void *buf, + int len); + +extern void wlc_update_beacon(struct wlc_info *wlc); +extern void wlc_bss_update_beacon(struct wlc_info *wlc, + struct wlc_bsscfg *bsscfg); + +extern void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend); +extern void wlc_bss_update_probe_resp(struct wlc_info *wlc, wlc_bsscfg_t *cfg, + bool suspend); + +extern bool wlc_ismpc(struct wlc_info *wlc); +extern bool wlc_is_non_delay_mpc(struct wlc_info *wlc); +extern void wlc_radio_mpc_upd(struct wlc_info *wlc); +extern bool wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, + int prec); +extern bool wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, + struct sk_buff *pkt, int prec, bool head); +extern u16 wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec); +extern void wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rate, uint length, + u8 *plcp); +extern uint wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, + u8 preamble_type, uint mac_len); + +extern void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec); + +extern bool wlc_timers_init(struct wlc_info *wlc, int unit); + +extern const bcm_iovar_t wlc_iovars[]; + +extern int wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, + const char *name, void *params, uint p_len, void *arg, + int len, int val_size, struct wlc_if *wlcif); + +#if defined(BCMDBG) +extern void wlc_print_ies(struct wlc_info *wlc, u8 *ies, uint ies_len); +#endif + +extern int wlc_set_nmode(struct wlc_info *wlc, s32 nmode); +extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode); +extern void wlc_mimops_action_ht_send(struct wlc_info *wlc, + wlc_bsscfg_t *bsscfg, u8 mimops_mode); + +extern void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot); +extern void wlc_set_bssid(wlc_bsscfg_t *cfg); +extern void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend); + +extern void wlc_set_ratetable(struct wlc_info *wlc); +extern int wlc_set_mac(wlc_bsscfg_t *cfg); +extern void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, + ratespec_t bcn_rate); +extern void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len); +extern ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, + wlc_rateset_t *rs); +extern u16 wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec, + bool short_preamble, bool phydelay); +extern void wlc_radio_disable(struct wlc_info *wlc); +extern void wlc_bcn_li_upd(struct wlc_info *wlc); + +extern int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len); +extern void wlc_out(struct wlc_info *wlc); +extern void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec); +extern void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt); +extern bool wlc_ps_allowed(struct wlc_info *wlc); +extern bool wlc_stay_awake(struct wlc_info *wlc); +extern void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe); + +extern void wlc_bss_list_free(struct wlc_info *wlc, wlc_bss_list_t *bss_list); +extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode); +#endif /* _wlc_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_phy_shim.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_phy_shim.c new file mode 100644 index 000000000000..8bd4ede4c92a --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_phy_shim.c @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This is "two-way" interface, acting as the SHIM layer between WL and PHY layer. + * WL driver can optinally call this translation layer to do some preprocessing, then reach PHY. + * On the PHY->WL driver direction, all calls go through this layer since PHY doesn't have the + * access to wlc_hw pointer. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +/* PHY SHIM module specific state */ +struct wlc_phy_shim_info { + struct wlc_hw_info *wlc_hw; /* pointer to main wlc_hw structure */ + void *wlc; /* pointer to main wlc structure */ + void *wl; /* pointer to os-specific private state */ +}; + +wlc_phy_shim_info_t *wlc_phy_shim_attach(struct wlc_hw_info *wlc_hw, + void *wl, void *wlc) { + wlc_phy_shim_info_t *physhim = NULL; + + physhim = kzalloc(sizeof(wlc_phy_shim_info_t), GFP_ATOMIC); + if (!physhim) { + WL_ERROR("wl%d: wlc_phy_shim_attach: out of mem\n", + wlc_hw->unit); + return NULL; + } + physhim->wlc_hw = wlc_hw; + physhim->wlc = wlc; + physhim->wl = wl; + + return physhim; +} + +void wlc_phy_shim_detach(wlc_phy_shim_info_t *physhim) +{ + if (!physhim) + return; + + kfree(physhim); +} + +struct wlapi_timer *wlapi_init_timer(wlc_phy_shim_info_t *physhim, + void (*fn) (void *arg), void *arg, + const char *name) +{ + return (struct wlapi_timer *)wl_init_timer(physhim->wl, fn, arg, name); +} + +void wlapi_free_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t) +{ + wl_free_timer(physhim->wl, (struct wl_timer *)t); +} + +void +wlapi_add_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t, uint ms, + int periodic) +{ + wl_add_timer(physhim->wl, (struct wl_timer *)t, ms, periodic); +} + +bool wlapi_del_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t) +{ + return wl_del_timer(physhim->wl, (struct wl_timer *)t); +} + +void wlapi_intrson(wlc_phy_shim_info_t *physhim) +{ + wl_intrson(physhim->wl); +} + +u32 wlapi_intrsoff(wlc_phy_shim_info_t *physhim) +{ + return wl_intrsoff(physhim->wl); +} + +void wlapi_intrsrestore(wlc_phy_shim_info_t *physhim, u32 macintmask) +{ + wl_intrsrestore(physhim->wl, macintmask); +} + +void wlapi_bmac_write_shm(wlc_phy_shim_info_t *physhim, uint offset, u16 v) +{ + wlc_bmac_write_shm(physhim->wlc_hw, offset, v); +} + +u16 wlapi_bmac_read_shm(wlc_phy_shim_info_t *physhim, uint offset) +{ + return wlc_bmac_read_shm(physhim->wlc_hw, offset); +} + +void +wlapi_bmac_mhf(wlc_phy_shim_info_t *physhim, u8 idx, u16 mask, + u16 val, int bands) +{ + wlc_bmac_mhf(physhim->wlc_hw, idx, mask, val, bands); +} + +void wlapi_bmac_corereset(wlc_phy_shim_info_t *physhim, u32 flags) +{ + wlc_bmac_corereset(physhim->wlc_hw, flags); +} + +void wlapi_suspend_mac_and_wait(wlc_phy_shim_info_t *physhim) +{ + wlc_suspend_mac_and_wait(physhim->wlc); +} + +void wlapi_switch_macfreq(wlc_phy_shim_info_t *physhim, u8 spurmode) +{ + wlc_bmac_switch_macfreq(physhim->wlc_hw, spurmode); +} + +void wlapi_enable_mac(wlc_phy_shim_info_t *physhim) +{ + wlc_enable_mac(physhim->wlc); +} + +void wlapi_bmac_mctrl(wlc_phy_shim_info_t *physhim, u32 mask, u32 val) +{ + wlc_bmac_mctrl(physhim->wlc_hw, mask, val); +} + +void wlapi_bmac_phy_reset(wlc_phy_shim_info_t *physhim) +{ + wlc_bmac_phy_reset(physhim->wlc_hw); +} + +void wlapi_bmac_bw_set(wlc_phy_shim_info_t *physhim, u16 bw) +{ + wlc_bmac_bw_set(physhim->wlc_hw, bw); +} + +u16 wlapi_bmac_get_txant(wlc_phy_shim_info_t *physhim) +{ + return wlc_bmac_get_txant(physhim->wlc_hw); +} + +void wlapi_bmac_phyclk_fgc(wlc_phy_shim_info_t *physhim, bool clk) +{ + wlc_bmac_phyclk_fgc(physhim->wlc_hw, clk); +} + +void wlapi_bmac_macphyclk_set(wlc_phy_shim_info_t *physhim, bool clk) +{ + wlc_bmac_macphyclk_set(physhim->wlc_hw, clk); +} + +void wlapi_bmac_core_phypll_ctl(wlc_phy_shim_info_t *physhim, bool on) +{ + wlc_bmac_core_phypll_ctl(physhim->wlc_hw, on); +} + +void wlapi_bmac_core_phypll_reset(wlc_phy_shim_info_t *physhim) +{ + wlc_bmac_core_phypll_reset(physhim->wlc_hw); +} + +void wlapi_bmac_ucode_wake_override_phyreg_set(wlc_phy_shim_info_t *physhim) +{ + wlc_ucode_wake_override_set(physhim->wlc_hw, WLC_WAKE_OVERRIDE_PHYREG); +} + +void wlapi_bmac_ucode_wake_override_phyreg_clear(wlc_phy_shim_info_t *physhim) +{ + wlc_ucode_wake_override_clear(physhim->wlc_hw, + WLC_WAKE_OVERRIDE_PHYREG); +} + +void +wlapi_bmac_write_template_ram(wlc_phy_shim_info_t *physhim, int offset, + int len, void *buf) +{ + wlc_bmac_write_template_ram(physhim->wlc_hw, offset, len, buf); +} + +u16 wlapi_bmac_rate_shm_offset(wlc_phy_shim_info_t *physhim, u8 rate) +{ + return wlc_bmac_rate_shm_offset(physhim->wlc_hw, rate); +} + +void wlapi_ucode_sample_init(wlc_phy_shim_info_t *physhim) +{ +} + +void +wlapi_copyfrom_objmem(wlc_phy_shim_info_t *physhim, uint offset, void *buf, + int len, u32 sel) +{ + wlc_bmac_copyfrom_objmem(physhim->wlc_hw, offset, buf, len, sel); +} + +void +wlapi_copyto_objmem(wlc_phy_shim_info_t *physhim, uint offset, const void *buf, + int l, u32 sel) +{ + wlc_bmac_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel); +} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_phy_shim.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_phy_shim.h new file mode 100644 index 000000000000..c151a5d8c693 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_phy_shim.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_phy_shim_h_ +#define _wlc_phy_shim_h_ + +#define RADAR_TYPE_NONE 0 /* Radar type None */ +#define RADAR_TYPE_ETSI_1 1 /* ETSI 1 Radar type */ +#define RADAR_TYPE_ETSI_2 2 /* ETSI 2 Radar type */ +#define RADAR_TYPE_ETSI_3 3 /* ETSI 3 Radar type */ +#define RADAR_TYPE_ITU_E 4 /* ITU E Radar type */ +#define RADAR_TYPE_ITU_K 5 /* ITU K Radar type */ +#define RADAR_TYPE_UNCLASSIFIED 6 /* Unclassified Radar type */ +#define RADAR_TYPE_BIN5 7 /* long pulse radar type */ +#define RADAR_TYPE_STG2 8 /* staggered-2 radar */ +#define RADAR_TYPE_STG3 9 /* staggered-3 radar */ +#define RADAR_TYPE_FRA 10 /* French radar */ + +/* French radar pulse widths */ +#define FRA_T1_20MHZ 52770 +#define FRA_T2_20MHZ 61538 +#define FRA_T3_20MHZ 66002 +#define FRA_T1_40MHZ 105541 +#define FRA_T2_40MHZ 123077 +#define FRA_T3_40MHZ 132004 +#define FRA_ERR_20MHZ 60 +#define FRA_ERR_40MHZ 120 + +#define ANTSEL_NA 0 /* No boardlevel selection available */ +#define ANTSEL_2x4 1 /* 2x4 boardlevel selection available */ +#define ANTSEL_2x3 2 /* 2x3 CB2 boardlevel selection available */ + +/* Rx Antenna diversity control values */ +#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */ +#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */ +#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */ +#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */ +#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */ +#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */ + +/* Forward declarations */ +struct wlc_hw_info; +typedef struct wlc_phy_shim_info wlc_phy_shim_info_t; + +extern wlc_phy_shim_info_t *wlc_phy_shim_attach(struct wlc_hw_info *wlc_hw, + void *wl, void *wlc); +extern void wlc_phy_shim_detach(wlc_phy_shim_info_t *physhim); + +/* PHY to WL utility functions */ +struct wlapi_timer; +extern struct wlapi_timer *wlapi_init_timer(wlc_phy_shim_info_t *physhim, + void (*fn) (void *arg), void *arg, + const char *name); +extern void wlapi_free_timer(wlc_phy_shim_info_t *physhim, + struct wlapi_timer *t); +extern void wlapi_add_timer(wlc_phy_shim_info_t *physhim, + struct wlapi_timer *t, uint ms, int periodic); +extern bool wlapi_del_timer(wlc_phy_shim_info_t *physhim, + struct wlapi_timer *t); +extern void wlapi_intrson(wlc_phy_shim_info_t *physhim); +extern u32 wlapi_intrsoff(wlc_phy_shim_info_t *physhim); +extern void wlapi_intrsrestore(wlc_phy_shim_info_t *physhim, + u32 macintmask); + +extern void wlapi_bmac_write_shm(wlc_phy_shim_info_t *physhim, uint offset, + u16 v); +extern u16 wlapi_bmac_read_shm(wlc_phy_shim_info_t *physhim, uint offset); +extern void wlapi_bmac_mhf(wlc_phy_shim_info_t *physhim, u8 idx, + u16 mask, u16 val, int bands); +extern void wlapi_bmac_corereset(wlc_phy_shim_info_t *physhim, u32 flags); +extern void wlapi_suspend_mac_and_wait(wlc_phy_shim_info_t *physhim); +extern void wlapi_switch_macfreq(wlc_phy_shim_info_t *physhim, u8 spurmode); +extern void wlapi_enable_mac(wlc_phy_shim_info_t *physhim); +extern void wlapi_bmac_mctrl(wlc_phy_shim_info_t *physhim, u32 mask, + u32 val); +extern void wlapi_bmac_phy_reset(wlc_phy_shim_info_t *physhim); +extern void wlapi_bmac_bw_set(wlc_phy_shim_info_t *physhim, u16 bw); +extern void wlapi_bmac_phyclk_fgc(wlc_phy_shim_info_t *physhim, bool clk); +extern void wlapi_bmac_macphyclk_set(wlc_phy_shim_info_t *physhim, bool clk); +extern void wlapi_bmac_core_phypll_ctl(wlc_phy_shim_info_t *physhim, bool on); +extern void wlapi_bmac_core_phypll_reset(wlc_phy_shim_info_t *physhim); +extern void wlapi_bmac_ucode_wake_override_phyreg_set(wlc_phy_shim_info_t * + physhim); +extern void wlapi_bmac_ucode_wake_override_phyreg_clear(wlc_phy_shim_info_t * + physhim); +extern void wlapi_bmac_write_template_ram(wlc_phy_shim_info_t *physhim, int o, + int len, void *buf); +extern u16 wlapi_bmac_rate_shm_offset(wlc_phy_shim_info_t *physhim, + u8 rate); +extern void wlapi_ucode_sample_init(wlc_phy_shim_info_t *physhim); +extern void wlapi_copyfrom_objmem(wlc_phy_shim_info_t *physhim, uint, + void *buf, int, u32 sel); +extern void wlapi_copyto_objmem(wlc_phy_shim_info_t *physhim, uint, + const void *buf, int, u32); + +extern void wlapi_high_update_phy_mode(wlc_phy_shim_info_t *physhim, + u32 phy_mode); +extern u16 wlapi_bmac_get_txant(wlc_phy_shim_info_t *physhim); +#endif /* _wlc_phy_shim_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_pub.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_pub.h new file mode 100644 index 000000000000..23e99685d548 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_pub.h @@ -0,0 +1,624 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_pub_h_ +#define _wlc_pub_h_ + +#include +#include + +#define WLC_NUMRATES 16 /* max # of rates in a rateset */ +#define MAXMULTILIST 32 /* max # multicast addresses */ +#define D11_PHY_HDR_LEN 6 /* Phy header length - 6 bytes */ + +/* phy types */ +#define PHY_TYPE_A 0 /* Phy type A */ +#define PHY_TYPE_G 2 /* Phy type G */ +#define PHY_TYPE_N 4 /* Phy type N */ +#define PHY_TYPE_LP 5 /* Phy type Low Power A/B/G */ +#define PHY_TYPE_SSN 6 /* Phy type Single Stream N */ +#define PHY_TYPE_LCN 8 /* Phy type Single Stream N */ +#define PHY_TYPE_LCNXN 9 /* Phy type 2-stream N */ +#define PHY_TYPE_HT 7 /* Phy type 3-Stream N */ + +/* bw */ +#define WLC_10_MHZ 10 /* 10Mhz nphy channel bandwidth */ +#define WLC_20_MHZ 20 /* 20Mhz nphy channel bandwidth */ +#define WLC_40_MHZ 40 /* 40Mhz nphy channel bandwidth */ + +#define CHSPEC_WLC_BW(chanspec) (CHSPEC_IS40(chanspec) ? WLC_40_MHZ : \ + CHSPEC_IS20(chanspec) ? WLC_20_MHZ : \ + WLC_10_MHZ) + +#define WLC_RSSI_MINVAL -200 /* Low value, e.g. for forcing roam */ +#define WLC_RSSI_NO_SIGNAL -91 /* NDIS RSSI link quality cutoffs */ +#define WLC_RSSI_VERY_LOW -80 /* Very low quality cutoffs */ +#define WLC_RSSI_LOW -70 /* Low quality cutoffs */ +#define WLC_RSSI_GOOD -68 /* Good quality cutoffs */ +#define WLC_RSSI_VERY_GOOD -58 /* Very good quality cutoffs */ +#define WLC_RSSI_EXCELLENT -57 /* Excellent quality cutoffs */ + +#define WLC_PHYTYPE(_x) (_x) /* macro to perform WLC PHY -> D11 PHY TYPE, currently 1:1 */ + +#define MA_WINDOW_SZ 8 /* moving average window size */ + +#define WLC_SNR_INVALID 0 /* invalid SNR value */ + +/* a large TX Power as an init value to factor out of min() calculations, + * keep low enough to fit in an s8, units are .25 dBm + */ +#define WLC_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */ + +/* legacy rx Antenna diversity for SISO rates */ +#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */ +#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */ +#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */ +#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */ +#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */ +#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */ + +/* legacy rx Antenna diversity for SISO rates */ +#define ANT_TX_FORCE_0 0 /* Tx on antenna 0, "legacy term Main" */ +#define ANT_TX_FORCE_1 1 /* Tx on antenna 1, "legacy term Aux" */ +#define ANT_TX_LAST_RX 3 /* Tx on phy's last good Rx antenna */ +#define ANT_TX_DEF 3 /* driver's default tx antenna setting */ + +#define TXCORE_POLICY_ALL 0x1 /* use all available core for transmit */ + +/* Tx Chain values */ +#define TXCHAIN_DEF 0x1 /* def bitmap of txchain */ +#define TXCHAIN_DEF_NPHY 0x3 /* default bitmap of tx chains for nphy */ +#define TXCHAIN_DEF_HTPHY 0x7 /* default bitmap of tx chains for nphy */ +#define RXCHAIN_DEF 0x1 /* def bitmap of rxchain */ +#define RXCHAIN_DEF_NPHY 0x3 /* default bitmap of rx chains for nphy */ +#define RXCHAIN_DEF_HTPHY 0x7 /* default bitmap of rx chains for nphy */ +#define ANTSWITCH_NONE 0 /* no antenna switch */ +#define ANTSWITCH_TYPE_1 1 /* antenna switch on 4321CB2, 2of3 */ +#define ANTSWITCH_TYPE_2 2 /* antenna switch on 4321MPCI, 2of3 */ +#define ANTSWITCH_TYPE_3 3 /* antenna switch on 4322, 2of3 */ + +#define RXBUFSZ PKTBUFSZ +#ifndef AIDMAPSZ +#define AIDMAPSZ (roundup(MAXSCB, NBBY)/NBBY) /* aid bitmap size in bytes */ +#endif /* AIDMAPSZ */ + +typedef struct wlc_tunables { + int ntxd; /* size of tx descriptor table */ + int nrxd; /* size of rx descriptor table */ + int rxbufsz; /* size of rx buffers to post */ + int nrxbufpost; /* # of rx buffers to post */ + int maxscb; /* # of SCBs supported */ + int ampdunummpdu; /* max number of mpdu in an ampdu */ + int maxpktcb; /* max # of packet callbacks */ + int maxucodebss; /* max # of BSS handled in ucode bcn/prb */ + int maxucodebss4; /* max # of BSS handled in sw bcn/prb */ + int maxbss; /* max # of bss info elements in scan list */ + int datahiwat; /* data msg txq hiwat mark */ + int ampdudatahiwat; /* AMPDU msg txq hiwat mark */ + int rxbnd; /* max # of rx bufs to process before deferring to dpc */ + int txsbnd; /* max # tx status to process in wlc_txstatus() */ + int memreserved; /* memory reserved for BMAC's USB dma rx */ +} wlc_tunables_t; + +typedef struct wlc_rateset { + uint count; /* number of rates in rates[] */ + u8 rates[WLC_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */ + u8 htphy_membership; /* HT PHY Membership */ + u8 mcs[MCSSET_LEN]; /* supported mcs index bit map */ +} wlc_rateset_t; + +struct rsn_parms { + u8 flags; /* misc booleans (e.g., supported) */ + u8 multicast; /* multicast cipher */ + u8 ucount; /* count of unicast ciphers */ + u8 unicast[4]; /* unicast ciphers */ + u8 acount; /* count of auth modes */ + u8 auth[4]; /* Authentication modes */ + u8 PAD[4]; /* padding for future growth */ +}; + +/* + * buffer length needed for wlc_format_ssid + * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. + */ +#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) + +#define RSN_FLAGS_SUPPORTED 0x1 /* Flag for rsn_params */ +#define RSN_FLAGS_PREAUTH 0x2 /* Flag for WPA2 rsn_params */ + +/* All the HT-specific default advertised capabilities (including AMPDU) + * should be grouped here at one place + */ +#define AMPDU_DEF_MPDU_DENSITY 6 /* default mpdu density (110 ==> 4us) */ + +/* defaults for the HT (MIMO) bss */ +#define HT_CAP ((HT_CAP_MIMO_PS_OFF << IEEE80211_HT_CAP_SM_PS_SHIFT) |\ + IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_GRN_FLD |\ + HT_CAP_MAX_AMSDU | IEEE80211_HT_CAP_DSSSCCK40) + +/* WLC packet type is a void * */ +typedef void *wlc_pkt_t; + +/* Event data type */ +typedef struct wlc_event { + wl_event_msg_t event; /* encapsulated event */ + struct ether_addr *addr; /* used to keep a trace of the potential present of + * an address in wlc_event_msg_t + */ + int bsscfgidx; /* BSS config when needed */ + struct wl_if *wlif; /* pointer to wlif */ + void *data; /* used to hang additional data on an event */ + struct wlc_event *next; /* enables ordered list of pending events */ +} wlc_event_t; + +/* wlc internal bss_info, wl external one is in wlioctl.h */ +typedef struct wlc_bss_info { + u8 BSSID[ETH_ALEN]; /* network BSSID */ + u16 flags; /* flags for internal attributes */ + u8 SSID_len; /* the length of SSID */ + u8 SSID[32]; /* SSID string */ + s16 RSSI; /* receive signal strength (in dBm) */ + s16 SNR; /* receive signal SNR in dB */ + u16 beacon_period; /* units are Kusec */ + u16 atim_window; /* units are Kusec */ + chanspec_t chanspec; /* Channel num, bw, ctrl_sb and band */ + s8 infra; /* 0=IBSS, 1=infrastructure, 2=unknown */ + wlc_rateset_t rateset; /* supported rates */ + u8 dtim_period; /* DTIM period */ + s8 phy_noise; /* noise right after tx (in dBm) */ + u16 capability; /* Capability information */ + u8 wme_qosinfo; /* QoS Info from WME IE; valid if WLC_BSS_WME flag set */ + struct rsn_parms wpa; + struct rsn_parms wpa2; + u16 qbss_load_aac; /* qbss load available admission capacity */ + /* qbss_load_chan_free <- (0xff - channel_utilization of qbss_load_ie_t) */ + u8 qbss_load_chan_free; /* indicates how free the channel is */ + u8 mcipher; /* multicast cipher */ + u8 wpacfg; /* wpa config index */ +} wlc_bss_info_t; + +/* forward declarations */ +struct wlc_if; + +/* wlc_ioctl error codes */ +#define WLC_ENOIOCTL 1 /* No such Ioctl */ +#define WLC_EINVAL 2 /* Invalid value */ +#define WLC_ETOOSMALL 3 /* Value too small */ +#define WLC_ETOOBIG 4 /* Value too big */ +#define WLC_ERANGE 5 /* Out of range */ +#define WLC_EDOWN 6 /* Down */ +#define WLC_EUP 7 /* Up */ +#define WLC_ENOMEM 8 /* No Memory */ +#define WLC_EBUSY 9 /* Busy */ + +/* IOVar flags for common error checks */ +#define IOVF_MFG (1<<3) /* flag for mfgtest iovars */ +#define IOVF_WHL (1<<4) /* value must be whole (0-max) */ +#define IOVF_NTRL (1<<5) /* value must be natural (1-max) */ + +#define IOVF_SET_UP (1<<6) /* set requires driver be up */ +#define IOVF_SET_DOWN (1<<7) /* set requires driver be down */ +#define IOVF_SET_CLK (1<<8) /* set requires core clock */ +#define IOVF_SET_BAND (1<<9) /* set requires fixed band */ + +#define IOVF_GET_UP (1<<10) /* get requires driver be up */ +#define IOVF_GET_DOWN (1<<11) /* get requires driver be down */ +#define IOVF_GET_CLK (1<<12) /* get requires core clock */ +#define IOVF_GET_BAND (1<<13) /* get requires fixed band */ +#define IOVF_OPEN_ALLOW (1<<14) /* set allowed iovar for opensrc */ + +/* watchdog down and dump callback function proto's */ +typedef int (*watchdog_fn_t) (void *handle); +typedef int (*down_fn_t) (void *handle); +typedef int (*dump_fn_t) (void *handle, struct bcmstrbuf *b); + +/* IOVar handler + * + * handle - a pointer value registered with the function + * vi - iovar_info that was looked up + * actionid - action ID, calculated by IOV_GVAL() and IOV_SVAL() based on varid. + * name - the actual iovar name + * params/plen - parameters and length for a get, input only. + * arg/len - buffer and length for value to be set or retrieved, input or output. + * vsize - value size, valid for integer type only. + * wlcif - interface context (wlc_if pointer) + * + * All pointers may point into the same buffer. + */ +typedef int (*iovar_fn_t) (void *handle, const bcm_iovar_t *vi, + u32 actionid, const char *name, void *params, + uint plen, void *arg, int alen, int vsize, + struct wlc_if *wlcif); + +#define MAC80211_PROMISC_BCNS (1 << 0) +#define MAC80211_SCAN (1 << 1) + +/* + * Public portion of "common" os-independent state structure. + * The wlc handle points at this. + */ +struct wlc_pub { + void *wlc; + + struct ieee80211_hw *ieee_hw; + struct scb *global_scb; + scb_ampdu_t *global_ampdu; + uint mac80211_state; + uint unit; /* device instance number */ + uint corerev; /* core revision */ + struct osl_info *osh; /* pointer to os handle */ + si_t *sih; /* SB handle (cookie for siutils calls) */ + char *vars; /* "environment" name=value */ + bool up; /* interface up and running */ + bool hw_off; /* HW is off */ + wlc_tunables_t *tunables; /* tunables: ntxd, nrxd, maxscb, etc. */ + bool hw_up; /* one time hw up/down(from boot or hibernation) */ + bool _piomode; /* true if pio mode *//* BMAC_NOTE: NEED In both */ + uint _nbands; /* # bands supported */ + uint now; /* # elapsed seconds */ + + bool promisc; /* promiscuous destination address */ + bool delayed_down; /* down delayed */ + bool _ap; /* AP mode enabled */ + bool _apsta; /* simultaneous AP/STA mode enabled */ + bool _assoc_recreate; /* association recreation on up transitions */ + int _wme; /* WME QoS mode */ + u8 _mbss; /* MBSS mode on */ + bool allmulti; /* enable all multicasts */ + bool associated; /* true:part of [I]BSS, false: not */ + /* (union of stas_associated, aps_associated) */ + bool phytest_on; /* whether a PHY test is running */ + bool bf_preempt_4306; /* True to enable 'darwin' mode */ + bool _ampdu; /* ampdu enabled or not */ + bool _cac; /* 802.11e CAC enabled */ + u8 _n_enab; /* bitmap of 11N + HT support */ + bool _n_reqd; /* N support required for clients */ + + s8 _coex; /* 20/40 MHz BSS Management AUTO, ENAB, DISABLE */ + bool _priofc; /* Priority-based flowcontrol */ + + u8 cur_etheraddr[ETH_ALEN]; /* our local ethernet address */ + + u8 *multicast; /* ptr to list of multicast addresses */ + uint nmulticast; /* # enabled multicast addresses */ + + u32 wlfeatureflag; /* Flags to control sw features from registry */ + int psq_pkts_total; /* total num of ps pkts */ + + u16 txmaxpkts; /* max number of large pkts allowed to be pending */ + + /* s/w decryption counters */ + u32 swdecrypt; /* s/w decrypt attempts */ + + int bcmerror; /* last bcm error */ + + mbool radio_disabled; /* bit vector for radio disabled reasons */ + bool radio_active; /* radio on/off state */ + u16 roam_time_thresh; /* Max. # secs. of not hearing beacons + * before roaming. + */ + bool align_wd_tbtt; /* Align watchdog with tbtt indication + * handling. This flag is cleared by default + * and is set by per port code explicitly and + * you need to make sure the OSL_SYSUPTIME() + * is implemented properly in osl of that port + * when it enables this Power Save feature. + */ + + u16 boardrev; /* version # of particular board */ + u8 sromrev; /* version # of the srom */ + char srom_ccode[WLC_CNTRY_BUF_SZ]; /* Country Code in SROM */ + u32 boardflags; /* Board specific flags from srom */ + u32 boardflags2; /* More board flags if sromrev >= 4 */ + bool tempsense_disable; /* disable periodic tempsense check */ + + bool _lmac; /* lmac module included and enabled */ + bool _lmacproto; /* lmac protocol module included and enabled */ + bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */ + bool _ampdumac; /* mac assist ampdu enabled or not */ +}; + +/* wl_monitor rx status per packet */ +typedef struct wl_rxsts { + uint pkterror; /* error flags per pkt */ + uint phytype; /* 802.11 A/B/G ... */ + uint channel; /* channel */ + uint datarate; /* rate in 500kbps */ + uint antenna; /* antenna pkts received on */ + uint pktlength; /* pkt length minus bcm phy hdr */ + u32 mactime; /* time stamp from mac, count per 1us */ + uint sq; /* signal quality */ + s32 signal; /* in dbm */ + s32 noise; /* in dbm */ + uint preamble; /* Unknown, short, long */ + uint encoding; /* Unknown, CCK, PBCC, OFDM */ + uint nfrmtype; /* special 802.11n frames(AMPDU, AMSDU) */ + struct wl_if *wlif; /* wl interface */ +} wl_rxsts_t; + +/* status per error RX pkt */ +#define WL_RXS_CRC_ERROR 0x00000001 /* CRC Error in packet */ +#define WL_RXS_RUNT_ERROR 0x00000002 /* Runt packet */ +#define WL_RXS_ALIGN_ERROR 0x00000004 /* Misaligned packet */ +#define WL_RXS_OVERSIZE_ERROR 0x00000008 /* packet bigger than RX_LENGTH (usually 1518) */ +#define WL_RXS_WEP_ICV_ERROR 0x00000010 /* Integrity Check Value error */ +#define WL_RXS_WEP_ENCRYPTED 0x00000020 /* Encrypted with WEP */ +#define WL_RXS_PLCP_SHORT 0x00000040 /* Short PLCP error */ +#define WL_RXS_DECRYPT_ERR 0x00000080 /* Decryption error */ +#define WL_RXS_OTHER_ERR 0x80000000 /* Other errors */ + +/* phy type */ +#define WL_RXS_PHY_A 0x00000000 /* A phy type */ +#define WL_RXS_PHY_B 0x00000001 /* B phy type */ +#define WL_RXS_PHY_G 0x00000002 /* G phy type */ +#define WL_RXS_PHY_N 0x00000004 /* N phy type */ + +/* encoding */ +#define WL_RXS_ENCODING_CCK 0x00000000 /* CCK encoding */ +#define WL_RXS_ENCODING_OFDM 0x00000001 /* OFDM encoding */ + +/* preamble */ +#define WL_RXS_UNUSED_STUB 0x0 /* stub to match with wlc_ethereal.h */ +#define WL_RXS_PREAMBLE_SHORT 0x00000001 /* Short preamble */ +#define WL_RXS_PREAMBLE_LONG 0x00000002 /* Long preamble */ +#define WL_RXS_PREAMBLE_MIMO_MM 0x00000003 /* MIMO mixed mode preamble */ +#define WL_RXS_PREAMBLE_MIMO_GF 0x00000004 /* MIMO green field preamble */ + +#define WL_RXS_NFRM_AMPDU_FIRST 0x00000001 /* first MPDU in A-MPDU */ +#define WL_RXS_NFRM_AMPDU_SUB 0x00000002 /* subsequent MPDU(s) in A-MPDU */ +#define WL_RXS_NFRM_AMSDU_FIRST 0x00000004 /* first MSDU in A-MSDU */ +#define WL_RXS_NFRM_AMSDU_SUB 0x00000008 /* subsequent MSDU(s) in A-MSDU */ + +/* forward declare and use the struct notation so we don't have to + * have it defined if not necessary. + */ +struct wlc_info; +struct wlc_hw_info; +struct wlc_bsscfg; +struct wlc_if; + +/*********************************************** + * Feature-related macros to optimize out code * + * ********************************************* + */ + +/* AP Support (versus STA) */ +#define AP_ENAB(pub) (0) + +/* Macro to check if APSTA mode enabled */ +#define APSTA_ENAB(pub) (0) + +/* Some useful combinations */ +#define STA_ONLY(pub) (!AP_ENAB(pub)) +#define AP_ONLY(pub) (AP_ENAB(pub) && !APSTA_ENAB(pub)) + +#define ENAB_1x1 0x01 +#define ENAB_2x2 0x02 +#define ENAB_3x3 0x04 +#define ENAB_4x4 0x08 +#define SUPPORT_11N (ENAB_1x1|ENAB_2x2) +#define SUPPORT_HT (ENAB_1x1|ENAB_2x2|ENAB_3x3) +/* WL11N Support */ +#if ((defined(NCONF) && (NCONF != 0)) || (defined(LCNCONF) && (LCNCONF != 0)) || \ + (defined(HTCONF) && (HTCONF != 0)) || (defined(SSLPNCONF) && (SSLPNCONF != 0))) +#define N_ENAB(pub) ((pub)->_n_enab & SUPPORT_11N) +#define N_REQD(pub) ((pub)->_n_reqd) +#else +#define N_ENAB(pub) 0 +#define N_REQD(pub) 0 +#endif + +#if (defined(HTCONF) && (HTCONF != 0)) +#define HT_ENAB(pub) (((pub)->_n_enab & SUPPORT_HT) == SUPPORT_HT) +#else +#define HT_ENAB(pub) 0 +#endif + +#define AMPDU_AGG_HOST 1 +#define AMPDU_ENAB(pub) ((pub)->_ampdu) + +#define EDCF_ENAB(pub) (WME_ENAB(pub)) +#define QOS_ENAB(pub) (WME_ENAB(pub) || N_ENAB(pub)) + +#define MONITOR_ENAB(wlc) ((wlc)->monitor) + +#define PROMISC_ENAB(wlc) ((wlc)->promisc) + +#define WLC_PREC_COUNT 16 /* Max precedence level implemented */ + +/* pri is priority encoded in the packet. This maps the Packet priority to + * enqueue precedence as defined in wlc_prec_map + */ +extern const u8 wlc_prio2prec_map[]; +#define WLC_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7] + +/* This maps priority to one precedence higher - Used by PS-Poll response packets to + * simulate enqueue-at-head operation, but still maintain the order on the queue + */ +#define WLC_PRIO_TO_HI_PREC(pri) min(WLC_PRIO_TO_PREC(pri) + 1, WLC_PREC_COUNT - 1) + +extern const u8 wme_fifo2ac[]; +#define WME_PRIO2AC(prio) wme_fifo2ac[prio2fifo[(prio)]] + +/* Mask to describe all precedence levels */ +#define WLC_PREC_BMP_ALL MAXBITVAL(WLC_PREC_COUNT) + +/* Define a bitmap of precedences comprised by each AC */ +#define WLC_PREC_BMP_AC_BE (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BE)) | \ + NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BE)) | \ + NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_EE)) | \ + NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_EE))) +#define WLC_PREC_BMP_AC_BK (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BK)) | \ + NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BK)) | \ + NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NONE)) | \ + NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NONE))) +#define WLC_PREC_BMP_AC_VI (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_CL)) | \ + NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_CL)) | \ + NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VI)) | \ + NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VI))) +#define WLC_PREC_BMP_AC_VO (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VO)) | \ + NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VO)) | \ + NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NC)) | \ + NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NC))) + +/* WME Support */ +#define WME_ENAB(pub) ((pub)->_wme != OFF) +#define WME_AUTO(wlc) ((wlc)->pub->_wme == AUTO) + +#define WLC_USE_COREFLAGS 0xffffffff /* invalid core flags, use the saved coreflags */ + +#define WLC_UPDATE_STATS(wlc) 0 /* No stats support */ +#define WLCNTINCR(a) /* No stats support */ +#define WLCNTDECR(a) /* No stats support */ +#define WLCNTADD(a, delta) /* No stats support */ +#define WLCNTSET(a, value) /* No stats support */ +#define WLCNTVAL(a) 0 /* No stats support */ + +/* common functions for every port */ +extern void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, + bool piomode, struct osl_info *osh, void *regsva, + uint bustype, void *btparam, uint *perr); +extern uint wlc_detach(struct wlc_info *wlc); +extern int wlc_up(struct wlc_info *wlc); +extern uint wlc_down(struct wlc_info *wlc); + +extern int wlc_set(struct wlc_info *wlc, int cmd, int arg); +extern int wlc_get(struct wlc_info *wlc, int cmd, int *arg); +extern int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg); +extern int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg); +extern bool wlc_chipmatch(u16 vendor, u16 device); +extern void wlc_init(struct wlc_info *wlc); +extern void wlc_reset(struct wlc_info *wlc); + +extern void wlc_intrson(struct wlc_info *wlc); +extern u32 wlc_intrsoff(struct wlc_info *wlc); +extern void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask); +extern bool wlc_intrsupd(struct wlc_info *wlc); +extern bool wlc_isr(struct wlc_info *wlc, bool *wantdpc); +extern bool wlc_dpc(struct wlc_info *wlc, bool bounded); +extern bool wlc_send80211_raw(struct wlc_info *wlc, struct wlc_if *wlcif, + void *p, uint ac); +extern bool wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, + struct ieee80211_hw *hw); +extern int wlc_iovar_op(struct wlc_info *wlc, const char *name, void *params, + int p_len, void *arg, int len, bool set, + struct wlc_if *wlcif); +extern int wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, + struct wlc_if *wlcif); +/* helper functions */ +extern void wlc_statsupd(struct wlc_info *wlc); +extern int wlc_get_header_len(void); +extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc); +extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, + const u8 *addr); +extern void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, + bool suspend); + +extern struct wlc_pub *wlc_pub(void *wlc); + +/* common functions for every port */ +extern int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw); +extern int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw); +extern int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw); +extern int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw); + +extern u32 wlc_reg_read(struct wlc_info *wlc, void *r, uint size); +extern void wlc_reg_write(struct wlc_info *wlc, void *r, u32 v, uint size); +extern void wlc_corereset(struct wlc_info *wlc, u32 flags); +extern void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val, + int bands); +extern u16 wlc_mhf_get(struct wlc_info *wlc, u8 idx, int bands); +extern u32 wlc_delta_txfunfl(struct wlc_info *wlc, int fifo); +extern void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset); +extern void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs); + +/* wlc_phy.c helper functions */ +extern void wlc_set_ps_ctrl(struct wlc_info *wlc); +extern void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val); +extern void wlc_scb_ratesel_init_all(struct wlc_info *wlc); + +/* ioctl */ +extern int wlc_iovar_gets8(struct wlc_info *wlc, const char *name, + s8 *arg); +extern int wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, + void *arg, + int len, bool set); + +extern int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, + const char *name, void *hdl, iovar_fn_t iovar_fn, + watchdog_fn_t watchdog_fn, down_fn_t down_fn); +extern int wlc_module_unregister(struct wlc_pub *pub, const char *name, + void *hdl); +extern void wlc_event_if(struct wlc_info *wlc, struct wlc_bsscfg *cfg, + wlc_event_t *e, const struct ether_addr *addr); +extern void wlc_suspend_mac_and_wait(struct wlc_info *wlc); +extern void wlc_enable_mac(struct wlc_info *wlc); +extern u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate); +extern u32 wlc_get_rspec_history(struct wlc_bsscfg *cfg); +extern u32 wlc_get_current_highest_rate(struct wlc_bsscfg *cfg); + +static inline int wlc_iovar_getuint(struct wlc_info *wlc, const char *name, + uint *arg) +{ + return wlc_iovar_getint(wlc, name, (int *)arg); +} + +static inline int wlc_iovar_getu8(struct wlc_info *wlc, const char *name, + u8 *arg) +{ + return wlc_iovar_gets8(wlc, name, (s8 *) arg); +} + +static inline int wlc_iovar_setuint(struct wlc_info *wlc, const char *name, + uint arg) +{ + return wlc_iovar_setint(wlc, name, (int)arg); +} + +#if defined(BCMDBG) +extern int wlc_iocregchk(struct wlc_info *wlc, uint band); +#endif +#if defined(BCMDBG) +extern int wlc_iocpichk(struct wlc_info *wlc, uint phytype); +#endif + +/* helper functions */ +extern void wlc_getrand(struct wlc_info *wlc, u8 *buf, int len); + +struct scb; +extern void wlc_ps_on(struct wlc_info *wlc, struct scb *scb); +extern void wlc_ps_off(struct wlc_info *wlc, struct scb *scb, bool discard); +extern bool wlc_radio_monitor_stop(struct wlc_info *wlc); + +#if defined(BCMDBG) +extern int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len); +#endif + +extern void wlc_pmkid_build_cand_list(struct wlc_bsscfg *cfg, bool check_SSID); +extern void wlc_pmkid_event(struct wlc_bsscfg *cfg); + +#define MAXBANDS 2 /* Maximum #of bands */ +/* bandstate array indices */ +#define BAND_2G_INDEX 0 /* wlc->bandstate[x] index */ +#define BAND_5G_INDEX 1 /* wlc->bandstate[x] index */ + +#define BAND_2G_NAME "2.4G" +#define BAND_5G_NAME "5G" + +/* BMAC RPC: 7 u32 params: pkttotlen, fifo, commit, fid, txpktpend, pktflag, rpc_id */ +#define WLC_RPCTX_PARAMS 32 + +#endif /* _wlc_pub_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.c new file mode 100644 index 000000000000..ab7d0bed3c0a --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.c @@ -0,0 +1,501 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Rate info per rate: It tells whether a rate is ofdm or not and its phy_rate value */ +const u8 rate_info[WLC_MAXRATE + 1] = { + /* 0 1 2 3 4 5 6 7 8 9 */ +/* 0 */ 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, +/* 10 */ 0x00, 0x37, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00, +/* 20 */ 0x00, 0x00, 0x6e, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, +/* 30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, +/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, +/* 50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* 60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* 70 */ 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, +/* 100 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c +}; + +/* rates are in units of Kbps */ +const mcs_info_t mcs_table[MCS_TABLE_SIZE] = { + /* MCS 0: SS 1, MOD: BPSK, CR 1/2 */ + {6500, 13500, CEIL(6500 * 10, 9), CEIL(13500 * 10, 9), 0x00, + WLC_RATE_6M}, + /* MCS 1: SS 1, MOD: QPSK, CR 1/2 */ + {13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x08, + WLC_RATE_12M}, + /* MCS 2: SS 1, MOD: QPSK, CR 3/4 */ + {19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x0A, + WLC_RATE_18M}, + /* MCS 3: SS 1, MOD: 16QAM, CR 1/2 */ + {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x10, + WLC_RATE_24M}, + /* MCS 4: SS 1, MOD: 16QAM, CR 3/4 */ + {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x12, + WLC_RATE_36M}, + /* MCS 5: SS 1, MOD: 64QAM, CR 2/3 */ + {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x19, + WLC_RATE_48M}, + /* MCS 6: SS 1, MOD: 64QAM, CR 3/4 */ + {58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x1A, + WLC_RATE_54M}, + /* MCS 7: SS 1, MOD: 64QAM, CR 5/6 */ + {65000, 135000, CEIL(65000 * 10, 9), CEIL(135000 * 10, 9), 0x1C, + WLC_RATE_54M}, + /* MCS 8: SS 2, MOD: BPSK, CR 1/2 */ + {13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x40, + WLC_RATE_6M}, + /* MCS 9: SS 2, MOD: QPSK, CR 1/2 */ + {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x48, + WLC_RATE_12M}, + /* MCS 10: SS 2, MOD: QPSK, CR 3/4 */ + {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x4A, + WLC_RATE_18M}, + /* MCS 11: SS 2, MOD: 16QAM, CR 1/2 */ + {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x50, + WLC_RATE_24M}, + /* MCS 12: SS 2, MOD: 16QAM, CR 3/4 */ + {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x52, + WLC_RATE_36M}, + /* MCS 13: SS 2, MOD: 64QAM, CR 2/3 */ + {104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0x59, + WLC_RATE_48M}, + /* MCS 14: SS 2, MOD: 64QAM, CR 3/4 */ + {117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x5A, + WLC_RATE_54M}, + /* MCS 15: SS 2, MOD: 64QAM, CR 5/6 */ + {130000, 270000, CEIL(130000 * 10, 9), CEIL(270000 * 10, 9), 0x5C, + WLC_RATE_54M}, + /* MCS 16: SS 3, MOD: BPSK, CR 1/2 */ + {19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x80, + WLC_RATE_6M}, + /* MCS 17: SS 3, MOD: QPSK, CR 1/2 */ + {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x88, + WLC_RATE_12M}, + /* MCS 18: SS 3, MOD: QPSK, CR 3/4 */ + {58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x8A, + WLC_RATE_18M}, + /* MCS 19: SS 3, MOD: 16QAM, CR 1/2 */ + {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x90, + WLC_RATE_24M}, + /* MCS 20: SS 3, MOD: 16QAM, CR 3/4 */ + {117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x92, + WLC_RATE_36M}, + /* MCS 21: SS 3, MOD: 64QAM, CR 2/3 */ + {156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0x99, + WLC_RATE_48M}, + /* MCS 22: SS 3, MOD: 64QAM, CR 3/4 */ + {175500, 364500, CEIL(175500 * 10, 9), CEIL(364500 * 10, 9), 0x9A, + WLC_RATE_54M}, + /* MCS 23: SS 3, MOD: 64QAM, CR 5/6 */ + {195000, 405000, CEIL(195000 * 10, 9), CEIL(405000 * 10, 9), 0x9B, + WLC_RATE_54M}, + /* MCS 24: SS 4, MOD: BPSK, CR 1/2 */ + {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0xC0, + WLC_RATE_6M}, + /* MCS 25: SS 4, MOD: QPSK, CR 1/2 */ + {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0xC8, + WLC_RATE_12M}, + /* MCS 26: SS 4, MOD: QPSK, CR 3/4 */ + {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0xCA, + WLC_RATE_18M}, + /* MCS 27: SS 4, MOD: 16QAM, CR 1/2 */ + {104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0xD0, + WLC_RATE_24M}, + /* MCS 28: SS 4, MOD: 16QAM, CR 3/4 */ + {156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0xD2, + WLC_RATE_36M}, + /* MCS 29: SS 4, MOD: 64QAM, CR 2/3 */ + {208000, 432000, CEIL(208000 * 10, 9), CEIL(432000 * 10, 9), 0xD9, + WLC_RATE_48M}, + /* MCS 30: SS 4, MOD: 64QAM, CR 3/4 */ + {234000, 486000, CEIL(234000 * 10, 9), CEIL(486000 * 10, 9), 0xDA, + WLC_RATE_54M}, + /* MCS 31: SS 4, MOD: 64QAM, CR 5/6 */ + {260000, 540000, CEIL(260000 * 10, 9), CEIL(540000 * 10, 9), 0xDB, + WLC_RATE_54M}, + /* MCS 32: SS 1, MOD: BPSK, CR 1/2 */ + {0, 6000, 0, CEIL(6000 * 10, 9), 0x00, WLC_RATE_6M}, +}; + +/* phycfg for legacy OFDM frames: code rate, modulation scheme, spatial streams + * Number of spatial streams: always 1 + * other fields: refer to table 78 of section 17.3.2.2 of the original .11a standard + */ +typedef struct legacy_phycfg { + u32 rate_ofdm; /* ofdm mac rate */ + u8 tx_phy_ctl3; /* phy ctl byte 3, code rate, modulation type, # of streams */ +} legacy_phycfg_t; + +#define LEGACY_PHYCFG_TABLE_SIZE 12 /* Number of legacy_rate_cfg entries in the table */ + +/* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */ +/* Eventually MIMOPHY would also be converted to this format */ +/* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */ +static const legacy_phycfg_t legacy_phycfg_table[LEGACY_PHYCFG_TABLE_SIZE] = { + {WLC_RATE_1M, 0x00}, /* CCK 1Mbps, data rate 0 */ + {WLC_RATE_2M, 0x08}, /* CCK 2Mbps, data rate 1 */ + {WLC_RATE_5M5, 0x10}, /* CCK 5.5Mbps, data rate 2 */ + {WLC_RATE_11M, 0x18}, /* CCK 11Mbps, data rate 3 */ + {WLC_RATE_6M, 0x00}, /* OFDM 6Mbps, code rate 1/2, BPSK, 1 spatial stream */ + {WLC_RATE_9M, 0x02}, /* OFDM 9Mbps, code rate 3/4, BPSK, 1 spatial stream */ + {WLC_RATE_12M, 0x08}, /* OFDM 12Mbps, code rate 1/2, QPSK, 1 spatial stream */ + {WLC_RATE_18M, 0x0A}, /* OFDM 18Mbps, code rate 3/4, QPSK, 1 spatial stream */ + {WLC_RATE_24M, 0x10}, /* OFDM 24Mbps, code rate 1/2, 16-QAM, 1 spatial stream */ + {WLC_RATE_36M, 0x12}, /* OFDM 36Mbps, code rate 3/4, 16-QAM, 1 spatial stream */ + {WLC_RATE_48M, 0x19}, /* OFDM 48Mbps, code rate 2/3, 64-QAM, 1 spatial stream */ + {WLC_RATE_54M, 0x1A}, /* OFDM 54Mbps, code rate 3/4, 64-QAM, 1 spatial stream */ +}; + +/* Hardware rates (also encodes default basic rates) */ + +const wlc_rateset_t cck_ofdm_mimo_rates = { + 12, + { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */ + 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60, + 0x6c}, + 0x00, + {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +const wlc_rateset_t ofdm_mimo_rates = { + 8, + { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */ + 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c}, + 0x00, + {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* Default ratesets that include MCS32 for 40BW channels */ +const wlc_rateset_t cck_ofdm_40bw_mimo_rates = { + 12, + { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */ + 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60, + 0x6c}, + 0x00, + {0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +const wlc_rateset_t ofdm_40bw_mimo_rates = { + 8, + { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */ + 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c}, + 0x00, + {0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +const wlc_rateset_t cck_ofdm_rates = { + 12, + { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */ + 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60, + 0x6c}, + 0x00, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +const wlc_rateset_t gphy_legacy_rates = { + 4, + { /* 1b, 2b, 5.5b, 11b Mbps */ + 0x82, 0x84, 0x8b, 0x96}, + 0x00, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +const wlc_rateset_t ofdm_rates = { + 8, + { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */ + 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c}, + 0x00, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +const wlc_rateset_t cck_rates = { + 4, + { /* 1b, 2b, 5.5, 11 Mbps */ + 0x82, 0x84, 0x0b, 0x16}, + 0x00, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static bool wlc_rateset_valid(wlc_rateset_t *rs, bool check_brate); + +/* check if rateset is valid. + * if check_brate is true, rateset without a basic rate is considered NOT valid. + */ +static bool wlc_rateset_valid(wlc_rateset_t *rs, bool check_brate) +{ + uint idx; + + if (!rs->count) + return false; + + if (!check_brate) + return true; + + /* error if no basic rates */ + for (idx = 0; idx < rs->count; idx++) { + if (rs->rates[idx] & WLC_RATE_FLAG) + return true; + } + return false; +} + +void wlc_rateset_mcs_upd(wlc_rateset_t *rs, u8 txstreams) +{ + int i; + for (i = txstreams; i < MAX_STREAMS_SUPPORTED; i++) + rs->mcs[i] = 0; +} + +/* filter based on hardware rateset, and sort filtered rateset with basic bit(s) preserved, + * and check if resulting rateset is valid. +*/ +bool +wlc_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs, + const wlc_rateset_t *hw_rs, + bool check_brate, u8 txstreams) +{ + u8 rateset[WLC_MAXRATE + 1]; + u8 r; + uint count; + uint i; + + memset(rateset, 0, sizeof(rateset)); + count = rs->count; + + for (i = 0; i < count; i++) { + /* mask off "basic rate" bit, WLC_RATE_FLAG */ + r = (int)rs->rates[i] & RATE_MASK; + if ((r > WLC_MAXRATE) || (rate_info[r] == 0)) { + continue; + } + rateset[r] = rs->rates[i]; /* preserve basic bit! */ + } + + /* fill out the rates in order, looking at only supported rates */ + count = 0; + for (i = 0; i < hw_rs->count; i++) { + r = hw_rs->rates[i] & RATE_MASK; + ASSERT(r <= WLC_MAXRATE); + if (rateset[r]) + rs->rates[count++] = rateset[r]; + } + + rs->count = count; + + /* only set the mcs rate bit if the equivalent hw mcs bit is set */ + for (i = 0; i < MCSSET_LEN; i++) + rs->mcs[i] = (rs->mcs[i] & hw_rs->mcs[i]); + + if (wlc_rateset_valid(rs, check_brate)) + return true; + else + return false; +} + +/* caluclate the rate of a rx'd frame and return it as a ratespec */ +ratespec_t BCMFASTPATH wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp) +{ + int phy_type; + ratespec_t rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT; + + phy_type = + ((rxh->RxChan & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT); + + if ((phy_type == PHY_TYPE_N) || (phy_type == PHY_TYPE_SSN) || + (phy_type == PHY_TYPE_LCN) || (phy_type == PHY_TYPE_HT)) { + switch (rxh->PhyRxStatus_0 & PRXS0_FT_MASK) { + case PRXS0_CCK: + rspec = + CCK_PHY2MAC_RATE(((cck_phy_hdr_t *) plcp)->signal); + break; + case PRXS0_OFDM: + rspec = + OFDM_PHY2MAC_RATE(((ofdm_phy_hdr_t *) plcp)-> + rlpt[0]); + break; + case PRXS0_PREN: + rspec = (plcp[0] & MIMO_PLCP_MCS_MASK) | RSPEC_MIMORATE; + if (plcp[0] & MIMO_PLCP_40MHZ) { + /* indicate rspec is for 40 MHz mode */ + rspec &= ~RSPEC_BW_MASK; + rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT); + } + break; + case PRXS0_STDN: + /* fallthru */ + default: + /* not supported */ + ASSERT(0); + break; + } + if (PLCP3_ISSGI(plcp[3])) + rspec |= RSPEC_SHORT_GI; + } else + if ((phy_type == PHY_TYPE_A) || (rxh->PhyRxStatus_0 & PRXS0_OFDM)) + rspec = OFDM_PHY2MAC_RATE(((ofdm_phy_hdr_t *) plcp)->rlpt[0]); + else + rspec = CCK_PHY2MAC_RATE(((cck_phy_hdr_t *) plcp)->signal); + + return rspec; +} + +/* copy rateset src to dst as-is (no masking or sorting) */ +void wlc_rateset_copy(const wlc_rateset_t *src, wlc_rateset_t *dst) +{ + bcopy(src, dst, sizeof(wlc_rateset_t)); +} + +/* + * Copy and selectively filter one rateset to another. + * 'basic_only' means only copy basic rates. + * 'rates' indicates cck (11b) and ofdm rates combinations. + * - 0: cck and ofdm + * - 1: cck only + * - 2: ofdm only + * 'xmask' is the copy mask (typically 0x7f or 0xff). + */ +void +wlc_rateset_filter(wlc_rateset_t *src, wlc_rateset_t *dst, bool basic_only, + u8 rates, uint xmask, bool mcsallow) +{ + uint i; + uint r; + uint count; + + count = 0; + for (i = 0; i < src->count; i++) { + r = src->rates[i]; + if (basic_only && !(r & WLC_RATE_FLAG)) + continue; + if ((rates == WLC_RATES_CCK) && IS_OFDM((r & RATE_MASK))) + continue; + if ((rates == WLC_RATES_OFDM) && IS_CCK((r & RATE_MASK))) + continue; + dst->rates[count++] = r & xmask; + } + dst->count = count; + dst->htphy_membership = src->htphy_membership; + + if (mcsallow && rates != WLC_RATES_CCK) + bcopy(&src->mcs[0], &dst->mcs[0], MCSSET_LEN); + else + wlc_rateset_mcs_clear(dst); +} + +/* select rateset for a given phy_type and bandtype and filter it, sort it + * and fill rs_tgt with result + */ +void +wlc_rateset_default(wlc_rateset_t *rs_tgt, const wlc_rateset_t *rs_hw, + uint phy_type, int bandtype, bool cck_only, uint rate_mask, + bool mcsallow, u8 bw, u8 txstreams) +{ + const wlc_rateset_t *rs_dflt; + wlc_rateset_t rs_sel; + if ((PHYTYPE_IS(phy_type, PHY_TYPE_HT)) || + (PHYTYPE_IS(phy_type, PHY_TYPE_N)) || + (PHYTYPE_IS(phy_type, PHY_TYPE_LCN)) || + (PHYTYPE_IS(phy_type, PHY_TYPE_SSN))) { + if (BAND_5G(bandtype)) { + rs_dflt = (bw == WLC_20_MHZ ? + &ofdm_mimo_rates : &ofdm_40bw_mimo_rates); + } else { + rs_dflt = (bw == WLC_20_MHZ ? + &cck_ofdm_mimo_rates : + &cck_ofdm_40bw_mimo_rates); + } + } else if (PHYTYPE_IS(phy_type, PHY_TYPE_LP)) { + rs_dflt = (BAND_5G(bandtype)) ? &ofdm_rates : &cck_ofdm_rates; + } else if (PHYTYPE_IS(phy_type, PHY_TYPE_A)) { + rs_dflt = &ofdm_rates; + } else if (PHYTYPE_IS(phy_type, PHY_TYPE_G)) { + rs_dflt = &cck_ofdm_rates; + } else { + ASSERT(0); /* should not happen */ + rs_dflt = &cck_rates; /* force cck */ + } + + /* if hw rateset is not supplied, assign selected rateset to it */ + if (!rs_hw) + rs_hw = rs_dflt; + + wlc_rateset_copy(rs_dflt, &rs_sel); + wlc_rateset_mcs_upd(&rs_sel, txstreams); + wlc_rateset_filter(&rs_sel, rs_tgt, false, + cck_only ? WLC_RATES_CCK : WLC_RATES_CCK_OFDM, + rate_mask, mcsallow); + wlc_rate_hwrs_filter_sort_validate(rs_tgt, rs_hw, false, + mcsallow ? txstreams : 1); +} + +s16 BCMFASTPATH wlc_rate_legacy_phyctl(uint rate) +{ + uint i; + for (i = 0; i < LEGACY_PHYCFG_TABLE_SIZE; i++) + if (rate == legacy_phycfg_table[i].rate_ofdm) + return legacy_phycfg_table[i].tx_phy_ctl3; + + return -1; +} + +void wlc_rateset_mcs_clear(wlc_rateset_t *rateset) +{ + uint i; + for (i = 0; i < MCSSET_LEN; i++) + rateset->mcs[i] = 0; +} + +void wlc_rateset_mcs_build(wlc_rateset_t *rateset, u8 txstreams) +{ + bcopy(&cck_ofdm_mimo_rates.mcs[0], &rateset->mcs[0], MCSSET_LEN); + wlc_rateset_mcs_upd(rateset, txstreams); +} + +/* Based on bandwidth passed, allow/disallow MCS 32 in the rateset */ +void wlc_rateset_bw_mcs_filter(wlc_rateset_t *rateset, u8 bw) +{ + if (bw == WLC_40_MHZ) + setbit(rateset->mcs, 32); + else + clrbit(rateset->mcs, 32); +} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.h new file mode 100644 index 000000000000..25ba2a423639 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.h @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _WLC_RATE_H_ +#define _WLC_RATE_H_ + +extern const u8 rate_info[]; +extern const struct wlc_rateset cck_ofdm_mimo_rates; +extern const struct wlc_rateset ofdm_mimo_rates; +extern const struct wlc_rateset cck_ofdm_rates; +extern const struct wlc_rateset ofdm_rates; +extern const struct wlc_rateset cck_rates; +extern const struct wlc_rateset gphy_legacy_rates; +extern const struct wlc_rateset wlc_lrs_rates; +extern const struct wlc_rateset rate_limit_1_2; + +typedef struct mcs_info { + u32 phy_rate_20; /* phy rate in kbps [20Mhz] */ + u32 phy_rate_40; /* phy rate in kbps [40Mhz] */ + u32 phy_rate_20_sgi; /* phy rate in kbps [20Mhz] with SGI */ + u32 phy_rate_40_sgi; /* phy rate in kbps [40Mhz] with SGI */ + u8 tx_phy_ctl3; /* phy ctl byte 3, code rate, modulation type, # of streams */ + u8 leg_ofdm; /* matching legacy ofdm rate in 500bkps */ +} mcs_info_t; + +#define WLC_MAXMCS 32 /* max valid mcs index */ +#define MCS_TABLE_SIZE 33 /* Number of mcs entries in the table */ +extern const mcs_info_t mcs_table[]; + +#define MCS_INVALID 0xFF +#define MCS_CR_MASK 0x07 /* Code Rate bit mask */ +#define MCS_MOD_MASK 0x38 /* Modulation bit shift */ +#define MCS_MOD_SHIFT 3 /* MOdulation bit shift */ +#define MCS_TXS_MASK 0xc0 /* num tx streams - 1 bit mask */ +#define MCS_TXS_SHIFT 6 /* num tx streams - 1 bit shift */ +#define MCS_CR(_mcs) (mcs_table[_mcs].tx_phy_ctl3 & MCS_CR_MASK) +#define MCS_MOD(_mcs) ((mcs_table[_mcs].tx_phy_ctl3 & MCS_MOD_MASK) >> MCS_MOD_SHIFT) +#define MCS_TXS(_mcs) ((mcs_table[_mcs].tx_phy_ctl3 & MCS_TXS_MASK) >> MCS_TXS_SHIFT) +#define MCS_RATE(_mcs, _is40, _sgi) (_sgi ? \ + (_is40 ? mcs_table[_mcs].phy_rate_40_sgi : mcs_table[_mcs].phy_rate_20_sgi) : \ + (_is40 ? mcs_table[_mcs].phy_rate_40 : mcs_table[_mcs].phy_rate_20)) +#define VALID_MCS(_mcs) ((_mcs < MCS_TABLE_SIZE)) + +#define WLC_RATE_FLAG 0x80 /* Rate flag: basic or ofdm */ + +/* Macros to use the rate_info table */ +#define RATE_MASK 0x7f /* Rate value mask w/o basic rate flag */ +#define RATE_MASK_FULL 0xff /* Rate value mask with basic rate flag */ + +#define WLC_RATE_500K_TO_BPS(rate) ((rate) * 500000) /* convert 500kbps to bps */ + +/* rate spec : holds rate and mode specific information required to generate a tx frame. */ +/* Legacy CCK and OFDM information is held in the same manner as was done in the past */ +/* (in the lower byte) the upper 3 bytes primarily hold MIMO specific information */ +typedef u32 ratespec_t; + +/* rate spec bit fields */ +#define RSPEC_RATE_MASK 0x0000007F /* Either 500Kbps units or MIMO MCS idx */ +#define RSPEC_MIMORATE 0x08000000 /* mimo MCS is stored in RSPEC_RATE_MASK */ +#define RSPEC_BW_MASK 0x00000700 /* mimo bw mask */ +#define RSPEC_BW_SHIFT 8 /* mimo bw shift */ +#define RSPEC_STF_MASK 0x00003800 /* mimo Space/Time/Frequency mode mask */ +#define RSPEC_STF_SHIFT 11 /* mimo Space/Time/Frequency mode shift */ +#define RSPEC_CT_MASK 0x0000C000 /* mimo coding type mask */ +#define RSPEC_CT_SHIFT 14 /* mimo coding type shift */ +#define RSPEC_STC_MASK 0x00300000 /* mimo num STC streams per PLCP defn. */ +#define RSPEC_STC_SHIFT 20 /* mimo num STC streams per PLCP defn. */ +#define RSPEC_LDPC_CODING 0x00400000 /* mimo bit indicates adv coding in use */ +#define RSPEC_SHORT_GI 0x00800000 /* mimo bit indicates short GI in use */ +#define RSPEC_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */ +#define RSPEC_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicates override rate only */ + +#define WLC_HTPHY 127 /* HT PHY Membership */ + +#define RSPEC_ACTIVE(rspec) (rspec & (RSPEC_RATE_MASK | RSPEC_MIMORATE)) +#define RSPEC2RATE(rspec) ((rspec & RSPEC_MIMORATE) ? \ + MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec)) : \ + (rspec & RSPEC_RATE_MASK)) +/* return rate in unit of 500Kbps -- for internal use in wlc_rate_sel.c */ +#define RSPEC2RATE500K(rspec) ((rspec & RSPEC_MIMORATE) ? \ + MCS_RATE((rspec & RSPEC_RATE_MASK), state->is40bw, RSPEC_ISSGI(rspec))/500 : \ + (rspec & RSPEC_RATE_MASK)) +#define CRSPEC2RATE500K(rspec) ((rspec & RSPEC_MIMORATE) ? \ + MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec))/500 :\ + (rspec & RSPEC_RATE_MASK)) + +#define RSPEC2KBPS(rspec) (IS_MCS(rspec) ? RSPEC2RATE(rspec) : RSPEC2RATE(rspec)*500) +#define RSPEC_PHYTXBYTE2(rspec) ((rspec & 0xff00) >> 8) +#define RSPEC_GET_BW(rspec) ((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT) +#define RSPEC_IS40MHZ(rspec) ((((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT) == \ + PHY_TXC1_BW_40MHZ) || (((rspec & RSPEC_BW_MASK) >> \ + RSPEC_BW_SHIFT) == PHY_TXC1_BW_40MHZ_DUP)) +#define RSPEC_ISSGI(rspec) ((rspec & RSPEC_SHORT_GI) == RSPEC_SHORT_GI) +#define RSPEC_MIMOPLCP3(rspec) ((rspec & 0xf00000) >> 16) +#define PLCP3_ISSGI(plcp) (plcp & (RSPEC_SHORT_GI >> 16)) +#define RSPEC_STC(rspec) ((rspec & RSPEC_STC_MASK) >> RSPEC_STC_SHIFT) +#define RSPEC_STF(rspec) ((rspec & RSPEC_STF_MASK) >> RSPEC_STF_SHIFT) +#define PLCP3_ISSTBC(plcp) ((plcp & (RSPEC_STC_MASK) >> 16) == 0x10) +#define PLCP3_STC_MASK 0x30 +#define PLCP3_STC_SHIFT 4 + +/* Rate info table; takes a legacy rate or ratespec_t */ +#define IS_MCS(r) (r & RSPEC_MIMORATE) +#define IS_OFDM(r) (!IS_MCS(r) && (rate_info[(r) & RSPEC_RATE_MASK] & WLC_RATE_FLAG)) +#define IS_CCK(r) (!IS_MCS(r) && (((r) & RATE_MASK) == WLC_RATE_1M || \ + ((r) & RATE_MASK) == WLC_RATE_2M || \ + ((r) & RATE_MASK) == WLC_RATE_5M5 || ((r) & RATE_MASK) == WLC_RATE_11M)) +#define IS_SINGLE_STREAM(mcs) (((mcs) <= HIGHEST_SINGLE_STREAM_MCS) || ((mcs) == 32)) +#define CCK_RSPEC(cck) ((cck) & RSPEC_RATE_MASK) +#define OFDM_RSPEC(ofdm) (((ofdm) & RSPEC_RATE_MASK) |\ + (PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT)) +#define LEGACY_RSPEC(rate) (IS_CCK(rate) ? CCK_RSPEC(rate) : OFDM_RSPEC(rate)) + +#define MCS_RSPEC(mcs) (((mcs) & RSPEC_RATE_MASK) | RSPEC_MIMORATE | \ + (IS_SINGLE_STREAM(mcs) ? (PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT) : \ + (PHY_TXC1_MODE_SDM << RSPEC_STF_SHIFT))) + +/* Convert encoded rate value in plcp header to numerical rates in 500 KHz increments */ +extern const u8 ofdm_rate_lookup[]; +#define OFDM_PHY2MAC_RATE(rlpt) (ofdm_rate_lookup[rlpt & 0x7]) +#define CCK_PHY2MAC_RATE(signal) (signal/5) + +/* Rates specified in wlc_rateset_filter() */ +#define WLC_RATES_CCK_OFDM 0 +#define WLC_RATES_CCK 1 +#define WLC_RATES_OFDM 2 + +/* use the stuct form instead of typedef to fix dependency problems */ +struct wlc_rateset; + +/* sanitize, and sort a rateset with the basic bit(s) preserved, validate rateset */ +extern bool wlc_rate_hwrs_filter_sort_validate(struct wlc_rateset *rs, + const struct wlc_rateset *hw_rs, + bool check_brate, + u8 txstreams); +/* copy rateset src to dst as-is (no masking or sorting) */ +extern void wlc_rateset_copy(const struct wlc_rateset *src, + struct wlc_rateset *dst); + +/* would be nice to have these documented ... */ +extern ratespec_t wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp); + +extern void wlc_rateset_filter(struct wlc_rateset *src, struct wlc_rateset *dst, + bool basic_only, u8 rates, uint xmask, + bool mcsallow); +extern void wlc_rateset_default(struct wlc_rateset *rs_tgt, + const struct wlc_rateset *rs_hw, uint phy_type, + int bandtype, bool cck_only, uint rate_mask, + bool mcsallow, u8 bw, u8 txstreams); +extern s16 wlc_rate_legacy_phyctl(uint rate); + +extern void wlc_rateset_mcs_upd(struct wlc_rateset *rs, u8 txstreams); +extern void wlc_rateset_mcs_clear(struct wlc_rateset *rateset); +extern void wlc_rateset_mcs_build(struct wlc_rateset *rateset, u8 txstreams); +extern void wlc_rateset_bw_mcs_filter(struct wlc_rateset *rateset, u8 bw); + +#endif /* _WLC_RATE_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_scb.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_scb.h new file mode 100644 index 000000000000..142b75674444 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_scb.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_scb_h_ +#define _wlc_scb_h_ + +#include + +extern bool wlc_aggregatable(struct wlc_info *wlc, u8 tid); + +#define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */ +/* structure to store per-tid state for the ampdu initiator */ +typedef struct scb_ampdu_tid_ini { + u32 magic; + u8 tx_in_transit; /* number of pending mpdus in transit in driver */ + u8 tid; /* initiator tid for easy lookup */ + u8 txretry[AMPDU_TX_BA_MAX_WSIZE]; /* tx retry count; indexed by seq modulo */ + struct scb *scb; /* backptr for easy lookup */ +} scb_ampdu_tid_ini_t; + +#define AMPDU_MAX_SCB_TID NUMPRIO + +typedef struct scb_ampdu { + struct scb *scb; /* back pointer for easy reference */ + u8 mpdu_density; /* mpdu density */ + u8 max_pdu; /* max pdus allowed in ampdu */ + u8 release; /* # of mpdus released at a time */ + u16 min_len; /* min mpdu len to support the density */ + u32 max_rxlen; /* max ampdu rcv length; 8k, 16k, 32k, 64k */ + struct pktq txq; /* sdu transmit queue pending aggregation */ + + /* This could easily be a ini[] pointer and we keep this info in wl itself instead + * of having mac80211 hold it for us. Also could be made dynamic per tid instead of + * static. + */ + scb_ampdu_tid_ini_t ini[AMPDU_MAX_SCB_TID]; /* initiator info - per tid (NUMPRIO) */ +} scb_ampdu_t; + +#define SCB_MAGIC 0xbeefcafe +#define INI_MAGIC 0xabcd1234 + +/* station control block - one per remote MAC address */ +struct scb { + u32 magic; + u32 flags; /* various bit flags as defined below */ + u32 flags2; /* various bit flags2 as defined below */ + u8 state; /* current state bitfield of auth/assoc process */ + u8 ea[ETH_ALEN]; /* station address */ + void *fragbuf[NUMPRIO]; /* defragmentation buffer per prio */ + uint fragresid[NUMPRIO]; /* #bytes unused in frag buffer per prio */ + + u16 seqctl[NUMPRIO]; /* seqctl of last received frame (for dups) */ + u16 seqctl_nonqos; /* seqctl of last received frame (for dups) for + * non-QoS data and management + */ + u16 seqnum[NUMPRIO]; /* WME: driver maintained sw seqnum per priority */ + + scb_ampdu_t scb_ampdu; /* AMPDU state including per tid info */ +}; + +/* scb flags */ +#define SCB_WMECAP 0x0040 /* may ONLY be set if WME_ENAB(wlc) */ +#define SCB_HTCAP 0x10000 /* HT (MIMO) capable device */ +#define SCB_IS40 0x80000 /* 40MHz capable */ +#define SCB_STBCCAP 0x40000000 /* STBC Capable */ +#define SCB_WME(a) ((a)->flags & SCB_WMECAP)/* implies WME_ENAB */ +#define SCB_SEQNUM(scb, prio) ((scb)->seqnum[(prio)]) +#define SCB_PS(a) NULL +#define SCB_STBC_CAP(a) ((a)->flags & SCB_STBCCAP) +#define SCB_AMPDU(a) true +#endif /* _wlc_scb_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.c new file mode 100644 index 000000000000..10c9f447cdf0 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.c @@ -0,0 +1,600 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WLC_STF_SS_STBC_RX(wlc) (WLCISNPHY(wlc->band) && \ + NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6)) + +static s8 wlc_stf_stbc_rx_get(struct wlc_info *wlc); +static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val); +static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 val); +static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val); +static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val); + +static void _wlc_stf_phy_txant_upd(struct wlc_info *wlc); +static u16 _wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec); + +#define NSTS_1 1 +#define NSTS_2 2 +#define NSTS_3 3 +#define NSTS_4 4 +const u8 txcore_default[5] = { + (0), /* bitmap of the core enabled */ + (0x01), /* For Nsts = 1, enable core 1 */ + (0x03), /* For Nsts = 2, enable core 1 & 2 */ + (0x07), /* For Nsts = 3, enable core 1, 2 & 3 */ + (0x0f) /* For Nsts = 4, enable all cores */ +}; + +static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val) +{ + ASSERT((val == HT_CAP_RX_STBC_NO) + || (val == HT_CAP_RX_STBC_ONE_STREAM)); + + /* MIMOPHYs rev3-6 cannot receive STBC with only one rx core active */ + if (WLC_STF_SS_STBC_RX(wlc)) { + if ((wlc->stf->rxstreams == 1) && (val != HT_CAP_RX_STBC_NO)) + return; + } + + wlc->ht_cap.cap_info &= ~HT_CAP_RX_STBC_MASK; + wlc->ht_cap.cap_info |= (val << HT_CAP_RX_STBC_SHIFT); + + if (wlc->pub->up) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, true); + } +} + +/* every WLC_TEMPSENSE_PERIOD seconds temperature check to decide whether to turn on/off txchain */ +void wlc_tempsense_upd(struct wlc_info *wlc) +{ + wlc_phy_t *pi = wlc->band->pi; + uint active_chains, txchain; + + /* Check if the chip is too hot. Disable one Tx chain, if it is */ + /* high 4 bits are for Rx chain, low 4 bits are for Tx chain */ + active_chains = wlc_phy_stf_chain_active_get(pi); + txchain = active_chains & 0xf; + + if (wlc->stf->txchain == wlc->stf->hw_txchain) { + if (txchain && (txchain < wlc->stf->hw_txchain)) { + /* turn off 1 tx chain */ + wlc_stf_txchain_set(wlc, txchain, true); + } + } else if (wlc->stf->txchain < wlc->stf->hw_txchain) { + if (txchain == wlc->stf->hw_txchain) { + /* turn back on txchain */ + wlc_stf_txchain_set(wlc, txchain, true); + } + } +} + +void +wlc_stf_ss_algo_channel_get(struct wlc_info *wlc, u16 *ss_algo_channel, + chanspec_t chanspec) +{ + tx_power_t power; + u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id; + + /* Clear previous settings */ + *ss_algo_channel = 0; + + if (!wlc->pub->up) { + *ss_algo_channel = (u16) -1; + return; + } + + wlc_phy_txpower_get_current(wlc->band->pi, &power, + CHSPEC_CHANNEL(chanspec)); + + siso_mcs_id = (CHSPEC_IS40(chanspec)) ? + WL_TX_POWER_MCS40_SISO_FIRST : WL_TX_POWER_MCS20_SISO_FIRST; + cdd_mcs_id = (CHSPEC_IS40(chanspec)) ? + WL_TX_POWER_MCS40_CDD_FIRST : WL_TX_POWER_MCS20_CDD_FIRST; + stbc_mcs_id = (CHSPEC_IS40(chanspec)) ? + WL_TX_POWER_MCS40_STBC_FIRST : WL_TX_POWER_MCS20_STBC_FIRST; + + /* criteria to choose stf mode */ + + /* the "+3dbm (12 0.25db units)" is to account for the fact that with CDD, tx occurs + * on both chains + */ + if (power.target[siso_mcs_id] > (power.target[cdd_mcs_id] + 12)) + setbit(ss_algo_channel, PHY_TXC1_MODE_SISO); + else + setbit(ss_algo_channel, PHY_TXC1_MODE_CDD); + + /* STBC is ORed into to algo channel as STBC requires per-packet SCB capability check + * so cannot be default mode of operation. One of SISO, CDD have to be set + */ + if (power.target[siso_mcs_id] <= (power.target[stbc_mcs_id] + 12)) + setbit(ss_algo_channel, PHY_TXC1_MODE_STBC); +} + +static s8 wlc_stf_stbc_rx_get(struct wlc_info *wlc) +{ + return (wlc->ht_cap.cap_info & HT_CAP_RX_STBC_MASK) + >> HT_CAP_RX_STBC_SHIFT; +} + +static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val) +{ + if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON)) { + return false; + } + + if ((int_val == ON) && (wlc->stf->txstreams == 1)) + return false; + + if ((int_val == OFF) || (wlc->stf->txstreams == 1) + || !WLC_STBC_CAP_PHY(wlc)) + wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC; + else + wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_TX_STBC; + + wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = (s8) int_val; + wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = (s8) int_val; + + return true; +} + +bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val) +{ + if ((int_val != HT_CAP_RX_STBC_NO) + && (int_val != HT_CAP_RX_STBC_ONE_STREAM)) { + return false; + } + + if (WLC_STF_SS_STBC_RX(wlc)) { + if ((int_val != HT_CAP_RX_STBC_NO) + && (wlc->stf->rxstreams == 1)) + return false; + } + + wlc_stf_stbc_rx_ht_update(wlc, int_val); + return true; +} + +static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 core_mask) +{ + WL_TRACE("wl%d: %s: Nsts %d core_mask %x\n", + wlc->pub->unit, __func__, Nsts, core_mask); + + ASSERT((Nsts > 0) && (Nsts <= MAX_STREAMS_SUPPORTED)); + + if (WLC_BITSCNT(core_mask) > wlc->stf->txstreams) { + core_mask = 0; + } + + if ((WLC_BITSCNT(core_mask) == wlc->stf->txstreams) && + ((core_mask & ~wlc->stf->txchain) + || !(core_mask & wlc->stf->txchain))) { + core_mask = wlc->stf->txchain; + } + + ASSERT(!core_mask || Nsts <= WLC_BITSCNT(core_mask)); + + wlc->stf->txcore[Nsts] = core_mask; + /* Nsts = 1..4, txcore index = 1..4 */ + if (Nsts == 1) { + /* Needs to update beacon and ucode generated response + * frames when 1 stream core map changed + */ + wlc->stf->phytxant = core_mask << PHY_TXC_ANT_SHIFT; + wlc_bmac_txant_set(wlc->hw, wlc->stf->phytxant); + if (wlc->clk) { + wlc_suspend_mac_and_wait(wlc); + wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec); + wlc_enable_mac(wlc); + } + } + + return BCME_OK; +} + +static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val) +{ + int i; + u8 core_mask = 0; + + WL_TRACE("wl%d: %s: val %x\n", wlc->pub->unit, __func__, val); + + wlc->stf->spatial_policy = (s8) val; + for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) { + core_mask = (val == MAX_SPATIAL_EXPANSION) ? + wlc->stf->txchain : txcore_default[i]; + wlc_stf_txcore_set(wlc, (u8) i, core_mask); + } + return BCME_OK; +} + +int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force) +{ + u8 txchain = (u8) int_val; + u8 txstreams; + uint i; + + if (wlc->stf->txchain == txchain) + return BCME_OK; + + if ((txchain & ~wlc->stf->hw_txchain) + || !(txchain & wlc->stf->hw_txchain)) + return BCME_RANGE; + + /* if nrate override is configured to be non-SISO STF mode, reject reducing txchain to 1 */ + txstreams = (u8) WLC_BITSCNT(txchain); + if (txstreams > MAX_STREAMS_SUPPORTED) + return BCME_RANGE; + + if (txstreams == 1) { + for (i = 0; i < NBANDS(wlc); i++) + if ((RSPEC_STF(wlc->bandstate[i]->rspec_override) != + PHY_TXC1_MODE_SISO) + || (RSPEC_STF(wlc->bandstate[i]->mrspec_override) != + PHY_TXC1_MODE_SISO)) { + if (!force) + return BCME_ERROR; + + /* over-write the override rspec */ + if (RSPEC_STF(wlc->bandstate[i]->rspec_override) + != PHY_TXC1_MODE_SISO) { + wlc->bandstate[i]->rspec_override = 0; + WL_ERROR("%s(): temp sense override non-SISO rspec_override\n", + __func__); + } + if (RSPEC_STF + (wlc->bandstate[i]->mrspec_override) != + PHY_TXC1_MODE_SISO) { + wlc->bandstate[i]->mrspec_override = 0; + WL_ERROR("%s(): temp sense override non-SISO mrspec_override\n", + __func__); + } + } + } + + wlc->stf->txchain = txchain; + wlc->stf->txstreams = txstreams; + wlc_stf_stbc_tx_set(wlc, wlc->band->band_stf_stbc_tx); + wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); + wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); + wlc->stf->txant = + (wlc->stf->txstreams == 1) ? ANT_TX_FORCE_0 : ANT_TX_DEF; + _wlc_stf_phy_txant_upd(wlc); + + wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, + wlc->stf->rxchain); + + for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) + wlc_stf_txcore_set(wlc, (u8) i, txcore_default[i]); + + return BCME_OK; +} + +int wlc_stf_rxchain_set(struct wlc_info *wlc, s32 int_val) +{ + u8 rxchain_cnt; + u8 rxchain = (u8) int_val; + u8 mimops_mode; + u8 old_rxchain, old_rxchain_cnt; + + if (wlc->stf->rxchain == rxchain) + return BCME_OK; + + if ((rxchain & ~wlc->stf->hw_rxchain) + || !(rxchain & wlc->stf->hw_rxchain)) + return BCME_RANGE; + + rxchain_cnt = (u8) WLC_BITSCNT(rxchain); + if (WLC_STF_SS_STBC_RX(wlc)) { + if ((rxchain_cnt == 1) + && (wlc_stf_stbc_rx_get(wlc) != HT_CAP_RX_STBC_NO)) + return BCME_RANGE; + } + + if (APSTA_ENAB(wlc->pub) && (wlc->pub->associated)) + return BCME_ASSOCIATED; + + old_rxchain = wlc->stf->rxchain; + old_rxchain_cnt = wlc->stf->rxstreams; + + wlc->stf->rxchain = rxchain; + wlc->stf->rxstreams = rxchain_cnt; + + if (rxchain_cnt != old_rxchain_cnt) { + mimops_mode = + (rxchain_cnt == 1) ? HT_CAP_MIMO_PS_ON : HT_CAP_MIMO_PS_OFF; + wlc->mimops_PM = mimops_mode; + if (AP_ENAB(wlc->pub)) { + wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, + wlc->stf->rxchain); + wlc_ht_mimops_cap_update(wlc, mimops_mode); + if (wlc->pub->associated) + wlc_mimops_action_ht_send(wlc, wlc->cfg, + mimops_mode); + return BCME_OK; + } + if (wlc->pub->associated) { + if (mimops_mode == HT_CAP_MIMO_PS_OFF) { + /* if mimops is off, turn on the Rx chain first */ + wlc_phy_stf_chain_set(wlc->band->pi, + wlc->stf->txchain, + wlc->stf->rxchain); + wlc_ht_mimops_cap_update(wlc, mimops_mode); + } + } else { + wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, + wlc->stf->rxchain); + wlc_ht_mimops_cap_update(wlc, mimops_mode); + } + } else if (old_rxchain != rxchain) + wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, + wlc->stf->rxchain); + + return BCME_OK; +} + +/* update wlc->stf->ss_opmode which represents the operational stf_ss mode we're using */ +int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band) +{ + int ret_code = 0; + u8 prev_stf_ss; + u8 upd_stf_ss; + + prev_stf_ss = wlc->stf->ss_opmode; + + /* NOTE: opmode can only be SISO or CDD as STBC is decided on a per-packet basis */ + if (WLC_STBC_CAP_PHY(wlc) && + wlc->stf->ss_algosel_auto + && (wlc->stf->ss_algo_channel != (u16) -1)) { + ASSERT(isset(&wlc->stf->ss_algo_channel, PHY_TXC1_MODE_CDD) + || isset(&wlc->stf->ss_algo_channel, + PHY_TXC1_MODE_SISO)); + upd_stf_ss = (wlc->stf->no_cddstbc || (wlc->stf->txstreams == 1) + || isset(&wlc->stf->ss_algo_channel, + PHY_TXC1_MODE_SISO)) ? PHY_TXC1_MODE_SISO + : PHY_TXC1_MODE_CDD; + } else { + if (wlc->band != band) + return ret_code; + upd_stf_ss = (wlc->stf->no_cddstbc + || (wlc->stf->txstreams == + 1)) ? PHY_TXC1_MODE_SISO : band-> + band_stf_ss_mode; + } + if (prev_stf_ss != upd_stf_ss) { + wlc->stf->ss_opmode = upd_stf_ss; + wlc_bmac_band_stf_ss_set(wlc->hw, upd_stf_ss); + } + + return ret_code; +} + +int wlc_stf_attach(struct wlc_info *wlc) +{ + wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_SISO; + wlc->bandstate[BAND_5G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_CDD; + + if (WLCISNPHY(wlc->band) && + (wlc_phy_txpower_hw_ctrl_get(wlc->band->pi) != PHY_TPC_HW_ON)) + wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = + PHY_TXC1_MODE_CDD; + wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); + wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); + + wlc_stf_stbc_rx_ht_update(wlc, HT_CAP_RX_STBC_NO); + wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF; + wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF; + + if (WLC_STBC_CAP_PHY(wlc)) { + wlc->stf->ss_algosel_auto = true; + wlc->stf->ss_algo_channel = (u16) -1; /* Init the default value */ + } + return 0; +} + +void wlc_stf_detach(struct wlc_info *wlc) +{ +} + +int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val) +{ + int bcmerror = BCME_OK; + + /* when there is only 1 tx_streams, don't allow to change the txant */ + if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1)) + return ((val == wlc->stf->txant) ? bcmerror : BCME_RANGE); + + switch (val) { + case -1: + val = ANT_TX_DEF; + break; + case 0: + val = ANT_TX_FORCE_0; + break; + case 1: + val = ANT_TX_FORCE_1; + break; + case 3: + val = ANT_TX_LAST_RX; + break; + default: + bcmerror = BCME_RANGE; + break; + } + + if (bcmerror == BCME_OK) + wlc->stf->txant = (s8) val; + + return bcmerror; + +} + +/* + * Centralized txant update function. call it whenever wlc->stf->txant and/or wlc->stf->txchain + * change + * + * Antennas are controlled by ucode indirectly, which drives PHY or GPIO to + * achieve various tx/rx antenna selection schemes + * + * legacy phy, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means auto(last rx) + * for NREV<3, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means last rx and + * do tx-antenna selection for SISO transmissions + * for NREV=3, bit 6 and bit _8_ means antenna 0 and 1 respectively, bit6+bit7 means last rx and + * do tx-antenna selection for SISO transmissions + * for NREV>=7, bit 6 and bit 7 mean antenna 0 and 1 respectively, nit6+bit7 means both cores active +*/ +static void _wlc_stf_phy_txant_upd(struct wlc_info *wlc) +{ + s8 txant; + + txant = (s8) wlc->stf->txant; + ASSERT(txant == ANT_TX_FORCE_0 || txant == ANT_TX_FORCE_1 + || txant == ANT_TX_LAST_RX); + + if (WLC_PHY_11N_CAP(wlc->band)) { + if (txant == ANT_TX_FORCE_0) { + wlc->stf->phytxant = PHY_TXC_ANT_0; + } else if (txant == ANT_TX_FORCE_1) { + wlc->stf->phytxant = PHY_TXC_ANT_1; + + if (WLCISNPHY(wlc->band) && + NREV_GE(wlc->band->phyrev, 3) + && NREV_LT(wlc->band->phyrev, 7)) { + wlc->stf->phytxant = PHY_TXC_ANT_2; + } + } else { + if (WLCISLCNPHY(wlc->band) || WLCISSSLPNPHY(wlc->band)) + wlc->stf->phytxant = PHY_TXC_LCNPHY_ANT_LAST; + else { + /* keep this assert to catch out of sync wlc->stf->txcore */ + ASSERT(wlc->stf->txchain > 0); + wlc->stf->phytxant = + wlc->stf->txchain << PHY_TXC_ANT_SHIFT; + } + } + } else { + if (txant == ANT_TX_FORCE_0) + wlc->stf->phytxant = PHY_TXC_OLD_ANT_0; + else if (txant == ANT_TX_FORCE_1) + wlc->stf->phytxant = PHY_TXC_OLD_ANT_1; + else + wlc->stf->phytxant = PHY_TXC_OLD_ANT_LAST; + } + + wlc_bmac_txant_set(wlc->hw, wlc->stf->phytxant); +} + +void wlc_stf_phy_txant_upd(struct wlc_info *wlc) +{ + _wlc_stf_phy_txant_upd(wlc); +} + +void wlc_stf_phy_chain_calc(struct wlc_info *wlc) +{ + /* get available rx/tx chains */ + wlc->stf->hw_txchain = (u8) getintvar(wlc->pub->vars, "txchain"); + wlc->stf->hw_rxchain = (u8) getintvar(wlc->pub->vars, "rxchain"); + + /* these parameter are intended to be used for all PHY types */ + if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) { + if (WLCISNPHY(wlc->band)) { + wlc->stf->hw_txchain = TXCHAIN_DEF_NPHY; + } else { + wlc->stf->hw_txchain = TXCHAIN_DEF; + } + } + + wlc->stf->txchain = wlc->stf->hw_txchain; + wlc->stf->txstreams = (u8) WLC_BITSCNT(wlc->stf->hw_txchain); + + if (wlc->stf->hw_rxchain == 0 || wlc->stf->hw_rxchain == 0xf) { + if (WLCISNPHY(wlc->band)) { + wlc->stf->hw_rxchain = RXCHAIN_DEF_NPHY; + } else { + wlc->stf->hw_rxchain = RXCHAIN_DEF; + } + } + + wlc->stf->rxchain = wlc->stf->hw_rxchain; + wlc->stf->rxstreams = (u8) WLC_BITSCNT(wlc->stf->hw_rxchain); + + /* initialize the txcore table */ + bcopy(txcore_default, wlc->stf->txcore, sizeof(wlc->stf->txcore)); + + /* default spatial_policy */ + wlc->stf->spatial_policy = MIN_SPATIAL_EXPANSION; + wlc_stf_spatial_policy_set(wlc, MIN_SPATIAL_EXPANSION); +} + +static u16 _wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec) +{ + u16 phytxant = wlc->stf->phytxant; + + if (RSPEC_STF(rspec) != PHY_TXC1_MODE_SISO) { + ASSERT(wlc->stf->txstreams > 1); + phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT; + } else if (wlc->stf->txant == ANT_TX_DEF) + phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT; + phytxant &= PHY_TXC_ANT_MASK; + return phytxant; +} + +u16 wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec) +{ + return _wlc_stf_phytxchain_sel(wlc, rspec); +} + +u16 wlc_stf_d11hdrs_phyctl_txant(struct wlc_info *wlc, ratespec_t rspec) +{ + u16 phytxant = wlc->stf->phytxant; + u16 mask = PHY_TXC_ANT_MASK; + + /* for non-siso rates or default setting, use the available chains */ + if (WLCISNPHY(wlc->band)) { + ASSERT(wlc->stf->txchain != 0); + phytxant = _wlc_stf_phytxchain_sel(wlc, rspec); + mask = PHY_TXC_HTANT_MASK; + } + phytxant |= phytxant & mask; + return phytxant; +} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.h new file mode 100644 index 000000000000..8de6382e620d --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_stf_h_ +#define _wlc_stf_h_ + +#define MIN_SPATIAL_EXPANSION 0 +#define MAX_SPATIAL_EXPANSION 1 + +extern int wlc_stf_attach(struct wlc_info *wlc); +extern void wlc_stf_detach(struct wlc_info *wlc); + +extern void wlc_tempsense_upd(struct wlc_info *wlc); +extern void wlc_stf_ss_algo_channel_get(struct wlc_info *wlc, + u16 *ss_algo_channel, + chanspec_t chanspec); +extern int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band); +extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc); +extern int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force); +extern int wlc_stf_rxchain_set(struct wlc_info *wlc, s32 int_val); +extern bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val); + +extern int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val); +extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc); +extern void wlc_stf_phy_chain_calc(struct wlc_info *wlc); +extern u16 wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec); +extern u16 wlc_stf_d11hdrs_phyctl_txant(struct wlc_info *wlc, ratespec_t rspec); +extern u16 wlc_stf_spatial_expansion_get(struct wlc_info *wlc, + ratespec_t rspec); +#endif /* _wlc_stf_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_types.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_types.h new file mode 100644 index 000000000000..df6e04c6ac58 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_types.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_types_h_ +#define _wlc_types_h_ + +/* forward declarations */ + +struct wlc_info; +struct wlc_hw_info; +struct wlc_if; +struct wl_if; +struct ampdu_info; +struct antsel_info; +struct bmac_pmq; + +struct d11init; + +#ifndef _hnddma_pub_ +#define _hnddma_pub_ +struct hnddma_pub; +#endif /* _hnddma_pub_ */ + +#endif /* _wlc_types_h_ */ diff --git a/drivers/staging/brcm80211/include/bcmsdh.h b/drivers/staging/brcm80211/include/bcmsdh.h index 0e1f79919c9c..90a600de7a3a 100644 --- a/drivers/staging/brcm80211/include/bcmsdh.h +++ b/drivers/staging/brcm80211/include/bcmsdh.h @@ -17,6 +17,7 @@ #ifndef _bcmsdh_h_ #define _bcmsdh_h_ +#include #define BCMSDH_ERROR_VAL 0x0001 /* Error */ #define BCMSDH_INFO_VAL 0x0002 /* Info */ extern const uint bcmsdh_msglevel; diff --git a/drivers/staging/brcm80211/phy/phy_version.h b/drivers/staging/brcm80211/phy/phy_version.h deleted file mode 100644 index 51a223880bcf..000000000000 --- a/drivers/staging/brcm80211/phy/phy_version.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef phy_version_h_ -#define phy_version_h_ - -#define PHY_MAJOR_VERSION 1 - -#define PHY_MINOR_VERSION 82 - -#define PHY_RC_NUMBER 8 - -#define PHY_INCREMENTAL_NUMBER 0 - -#define PHY_BUILD_NUMBER 0 - -#define PHY_VERSION { 1, 82, 8, 0 } - -#define PHY_VERSION_NUM 0x01520800 - -#define PHY_VERSION_STR "1.82.8.0" - -#endif /* phy_version_h_ */ diff --git a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c deleted file mode 100644 index 3bed37cb59b8..000000000000 --- a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c +++ /dev/null @@ -1,3461 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -u32 phyhal_msg_level = PHYHAL_ERROR; - -typedef struct _chan_info_basic { - u16 chan; - u16 freq; -} chan_info_basic_t; - -static chan_info_basic_t chan_info_all[] = { - - {1, 2412}, - {2, 2417}, - {3, 2422}, - {4, 2427}, - {5, 2432}, - {6, 2437}, - {7, 2442}, - {8, 2447}, - {9, 2452}, - {10, 2457}, - {11, 2462}, - {12, 2467}, - {13, 2472}, - {14, 2484}, - - {34, 5170}, - {38, 5190}, - {42, 5210}, - {46, 5230}, - - {36, 5180}, - {40, 5200}, - {44, 5220}, - {48, 5240}, - {52, 5260}, - {56, 5280}, - {60, 5300}, - {64, 5320}, - - {100, 5500}, - {104, 5520}, - {108, 5540}, - {112, 5560}, - {116, 5580}, - {120, 5600}, - {124, 5620}, - {128, 5640}, - {132, 5660}, - {136, 5680}, - {140, 5700}, - - {149, 5745}, - {153, 5765}, - {157, 5785}, - {161, 5805}, - {165, 5825}, - - {184, 4920}, - {188, 4940}, - {192, 4960}, - {196, 4980}, - {200, 5000}, - {204, 5020}, - {208, 5040}, - {212, 5060}, - {216, 50800} -}; - -u16 ltrn_list[PHY_LTRN_LIST_LEN] = { - 0x18f9, 0x0d01, 0x00e4, 0xdef4, 0x06f1, 0x0ffc, - 0xfa27, 0x1dff, 0x10f0, 0x0918, 0xf20a, 0xe010, - 0x1417, 0x1104, 0xf114, 0xf2fa, 0xf7db, 0xe2fc, - 0xe1fb, 0x13ee, 0xff0d, 0xe91c, 0x171a, 0x0318, - 0xda00, 0x03e8, 0x17e6, 0xe9e4, 0xfff3, 0x1312, - 0xe105, 0xe204, 0xf725, 0xf206, 0xf1ec, 0x11fc, - 0x14e9, 0xe0f0, 0xf2f6, 0x09e8, 0x1010, 0x1d01, - 0xfad9, 0x0f04, 0x060f, 0xde0c, 0x001c, 0x0dff, - 0x1807, 0xf61a, 0xe40e, 0x0f16, 0x05f9, 0x18ec, - 0x0a1b, 0xff1e, 0x2600, 0xffe2, 0x0ae5, 0x1814, - 0x0507, 0x0fea, 0xe4f2, 0xf6e6 -}; - -const u8 ofdm_rate_lookup[] = { - - WLC_RATE_48M, - WLC_RATE_24M, - WLC_RATE_12M, - WLC_RATE_6M, - WLC_RATE_54M, - WLC_RATE_36M, - WLC_RATE_18M, - WLC_RATE_9M -}; - -#define PHY_WREG_LIMIT 24 - -static void wlc_set_phy_uninitted(phy_info_t *pi); -static u32 wlc_phy_get_radio_ver(phy_info_t *pi); -static void wlc_phy_timercb_phycal(void *arg); - -static bool wlc_phy_noise_calc_phy(phy_info_t *pi, u32 *cmplx_pwr, - s8 *pwr_ant); - -static void wlc_phy_cal_perical_mphase_schedule(phy_info_t *pi, uint delay); -static void wlc_phy_noise_cb(phy_info_t *pi, u8 channel, s8 noise_dbm); -static void wlc_phy_noise_sample_request(wlc_phy_t *pih, u8 reason, - u8 ch); - -static void wlc_phy_txpower_reg_limit_calc(phy_info_t *pi, - struct txpwr_limits *tp, chanspec_t); -static bool wlc_phy_cal_txpower_recalc_sw(phy_info_t *pi); - -static s8 wlc_user_txpwr_antport_to_rfport(phy_info_t *pi, uint chan, - u32 band, u8 rate); -static void wlc_phy_upd_env_txpwr_rate_limits(phy_info_t *pi, u32 band); -static s8 wlc_phy_env_measure_vbat(phy_info_t *pi); -static s8 wlc_phy_env_measure_temperature(phy_info_t *pi); - -char *phy_getvar(phy_info_t *pi, const char *name) -{ - char *vars = pi->vars; - char *s; - int len; - - ASSERT(pi->vars != (char *)&pi->vars); - - if (!name) - return NULL; - - len = strlen(name); - if (len == 0) - return NULL; - - for (s = vars; s && *s;) { - if ((memcmp(s, name, len) == 0) && (s[len] == '=')) - return &s[len + 1]; - - while (*s++) - ; - } - - return nvram_get(name); -} - -int phy_getintvar(phy_info_t *pi, const char *name) -{ - char *val; - - val = PHY_GETVAR(pi, name); - if (val == NULL) - return 0; - - return simple_strtoul(val, NULL, 0); -} - -void wlc_phyreg_enter(wlc_phy_t *pih) -{ - phy_info_t *pi = (phy_info_t *) pih; - wlapi_bmac_ucode_wake_override_phyreg_set(pi->sh->physhim); -} - -void wlc_phyreg_exit(wlc_phy_t *pih) -{ - phy_info_t *pi = (phy_info_t *) pih; - wlapi_bmac_ucode_wake_override_phyreg_clear(pi->sh->physhim); -} - -void wlc_radioreg_enter(wlc_phy_t *pih) -{ - phy_info_t *pi = (phy_info_t *) pih; - wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, MCTL_LOCK_RADIO); - - udelay(10); -} - -void wlc_radioreg_exit(wlc_phy_t *pih) -{ - phy_info_t *pi = (phy_info_t *) pih; - volatile u16 dummy; - - dummy = R_REG(pi->sh->osh, &pi->regs->phyversion); - pi->phy_wreg = 0; - wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, 0); -} - -u16 read_radio_reg(phy_info_t *pi, u16 addr) -{ - u16 data; - - if ((addr == RADIO_IDCODE)) - return 0xffff; - - if (NORADIO_ENAB(pi->pubpi)) - return NORADIO_IDCODE & 0xffff; - - switch (pi->pubpi.phy_type) { - case PHY_TYPE_N: - CASECHECK(PHYTYPE, PHY_TYPE_N); - if (NREV_GE(pi->pubpi.phy_rev, 7)) - addr |= RADIO_2057_READ_OFF; - else - addr |= RADIO_2055_READ_OFF; - break; - - case PHY_TYPE_LCN: - CASECHECK(PHYTYPE, PHY_TYPE_LCN); - addr |= RADIO_2064_READ_OFF; - break; - - default: - ASSERT(VALID_PHYTYPE(pi->pubpi.phy_type)); - } - - if ((D11REV_GE(pi->sh->corerev, 24)) || - (D11REV_IS(pi->sh->corerev, 22) - && (pi->pubpi.phy_type != PHY_TYPE_SSN))) { - W_REG(pi->sh->osh, &pi->regs->radioregaddr, addr); -#ifdef __mips__ - (void)R_REG(pi->sh->osh, &pi->regs->radioregaddr); -#endif - data = R_REG(pi->sh->osh, &pi->regs->radioregdata); - } else { - W_REG(pi->sh->osh, &pi->regs->phy4waddr, addr); -#ifdef __mips__ - (void)R_REG(pi->sh->osh, &pi->regs->phy4waddr); -#endif - -#ifdef __ARM_ARCH_4T__ - __asm__(" .align 4 "); - __asm__(" nop "); - data = R_REG(pi->sh->osh, &pi->regs->phy4wdatalo); -#else - data = R_REG(pi->sh->osh, &pi->regs->phy4wdatalo); -#endif - - } - pi->phy_wreg = 0; - - return data; -} - -void write_radio_reg(phy_info_t *pi, u16 addr, u16 val) -{ - struct osl_info *osh; - - if (NORADIO_ENAB(pi->pubpi)) - return; - - osh = pi->sh->osh; - - if ((D11REV_GE(pi->sh->corerev, 24)) || - (D11REV_IS(pi->sh->corerev, 22) - && (pi->pubpi.phy_type != PHY_TYPE_SSN))) { - - W_REG(osh, &pi->regs->radioregaddr, addr); -#ifdef __mips__ - (void)R_REG(osh, &pi->regs->radioregaddr); -#endif - W_REG(osh, &pi->regs->radioregdata, val); - } else { - W_REG(osh, &pi->regs->phy4waddr, addr); -#ifdef __mips__ - (void)R_REG(osh, &pi->regs->phy4waddr); -#endif - W_REG(osh, &pi->regs->phy4wdatalo, val); - } - - if (pi->sh->bustype == PCI_BUS) { - if (++pi->phy_wreg >= pi->phy_wreg_limit) { - (void)R_REG(osh, &pi->regs->maccontrol); - pi->phy_wreg = 0; - } - } -} - -static u32 read_radio_id(phy_info_t *pi) -{ - u32 id; - - if (NORADIO_ENAB(pi->pubpi)) - return NORADIO_IDCODE; - - if (D11REV_GE(pi->sh->corerev, 24)) { - u32 b0, b1, b2; - - W_REG(pi->sh->osh, &pi->regs->radioregaddr, 0); -#ifdef __mips__ - (void)R_REG(pi->sh->osh, &pi->regs->radioregaddr); -#endif - b0 = (u32) R_REG(pi->sh->osh, &pi->regs->radioregdata); - W_REG(pi->sh->osh, &pi->regs->radioregaddr, 1); -#ifdef __mips__ - (void)R_REG(pi->sh->osh, &pi->regs->radioregaddr); -#endif - b1 = (u32) R_REG(pi->sh->osh, &pi->regs->radioregdata); - W_REG(pi->sh->osh, &pi->regs->radioregaddr, 2); -#ifdef __mips__ - (void)R_REG(pi->sh->osh, &pi->regs->radioregaddr); -#endif - b2 = (u32) R_REG(pi->sh->osh, &pi->regs->radioregdata); - - id = ((b0 & 0xf) << 28) | (((b2 << 8) | b1) << 12) | ((b0 >> 4) - & 0xf); - } else { - W_REG(pi->sh->osh, &pi->regs->phy4waddr, RADIO_IDCODE); -#ifdef __mips__ - (void)R_REG(pi->sh->osh, &pi->regs->phy4waddr); -#endif - id = (u32) R_REG(pi->sh->osh, &pi->regs->phy4wdatalo); - id |= (u32) R_REG(pi->sh->osh, &pi->regs->phy4wdatahi) << 16; - } - pi->phy_wreg = 0; - return id; -} - -void and_radio_reg(phy_info_t *pi, u16 addr, u16 val) -{ - u16 rval; - - if (NORADIO_ENAB(pi->pubpi)) - return; - - rval = read_radio_reg(pi, addr); - write_radio_reg(pi, addr, (rval & val)); -} - -void or_radio_reg(phy_info_t *pi, u16 addr, u16 val) -{ - u16 rval; - - if (NORADIO_ENAB(pi->pubpi)) - return; - - rval = read_radio_reg(pi, addr); - write_radio_reg(pi, addr, (rval | val)); -} - -void xor_radio_reg(phy_info_t *pi, u16 addr, u16 mask) -{ - u16 rval; - - if (NORADIO_ENAB(pi->pubpi)) - return; - - rval = read_radio_reg(pi, addr); - write_radio_reg(pi, addr, (rval ^ mask)); -} - -void mod_radio_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val) -{ - u16 rval; - - if (NORADIO_ENAB(pi->pubpi)) - return; - - rval = read_radio_reg(pi, addr); - write_radio_reg(pi, addr, (rval & ~mask) | (val & mask)); -} - -void write_phy_channel_reg(phy_info_t *pi, uint val) -{ - W_REG(pi->sh->osh, &pi->regs->phychannel, val); -} - -#if defined(BCMDBG) -static bool wlc_phy_war41476(phy_info_t *pi) -{ - u32 mc = R_REG(pi->sh->osh, &pi->regs->maccontrol); - - return ((mc & MCTL_EN_MAC) == 0) - || ((mc & MCTL_PHYLOCK) == MCTL_PHYLOCK); -} -#endif - -u16 read_phy_reg(phy_info_t *pi, u16 addr) -{ - struct osl_info *osh; - d11regs_t *regs; - - osh = pi->sh->osh; - regs = pi->regs; - - W_REG(osh, ®s->phyregaddr, addr); -#ifdef __mips__ - (void)R_REG(osh, ®s->phyregaddr); -#endif - - ASSERT(! - (D11REV_IS(pi->sh->corerev, 11) - || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi)); - - pi->phy_wreg = 0; - return R_REG(osh, ®s->phyregdata); -} - -void write_phy_reg(phy_info_t *pi, u16 addr, u16 val) -{ - struct osl_info *osh; - d11regs_t *regs; - - osh = pi->sh->osh; - regs = pi->regs; - -#ifdef __mips__ - W_REG(osh, ®s->phyregaddr, addr); - (void)R_REG(osh, ®s->phyregaddr); - W_REG(osh, ®s->phyregdata, val); - if (addr == 0x72) - (void)R_REG(osh, ®s->phyregdata); -#else - W_REG(osh, (volatile u32 *)(®s->phyregaddr), - addr | (val << 16)); - if (pi->sh->bustype == PCI_BUS) { - if (++pi->phy_wreg >= pi->phy_wreg_limit) { - pi->phy_wreg = 0; - (void)R_REG(osh, ®s->phyversion); - } - } -#endif -} - -void and_phy_reg(phy_info_t *pi, u16 addr, u16 val) -{ - struct osl_info *osh; - d11regs_t *regs; - - osh = pi->sh->osh; - regs = pi->regs; - - W_REG(osh, ®s->phyregaddr, addr); -#ifdef __mips__ - (void)R_REG(osh, ®s->phyregaddr); -#endif - - ASSERT(! - (D11REV_IS(pi->sh->corerev, 11) - || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi)); - - W_REG(osh, ®s->phyregdata, (R_REG(osh, ®s->phyregdata) & val)); - pi->phy_wreg = 0; -} - -void or_phy_reg(phy_info_t *pi, u16 addr, u16 val) -{ - struct osl_info *osh; - d11regs_t *regs; - - osh = pi->sh->osh; - regs = pi->regs; - - W_REG(osh, ®s->phyregaddr, addr); -#ifdef __mips__ - (void)R_REG(osh, ®s->phyregaddr); -#endif - - ASSERT(! - (D11REV_IS(pi->sh->corerev, 11) - || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi)); - - W_REG(osh, ®s->phyregdata, (R_REG(osh, ®s->phyregdata) | val)); - pi->phy_wreg = 0; -} - -void mod_phy_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val) -{ - struct osl_info *osh; - d11regs_t *regs; - - osh = pi->sh->osh; - regs = pi->regs; - - W_REG(osh, ®s->phyregaddr, addr); -#ifdef __mips__ - (void)R_REG(osh, ®s->phyregaddr); -#endif - - ASSERT(! - (D11REV_IS(pi->sh->corerev, 11) - || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi)); - - W_REG(osh, ®s->phyregdata, - ((R_REG(osh, ®s->phyregdata) & ~mask) | (val & mask))); - pi->phy_wreg = 0; -} - -static void WLBANDINITFN(wlc_set_phy_uninitted) (phy_info_t *pi) -{ - int i, j; - - pi->initialized = false; - - pi->tx_vos = 0xffff; - pi->nrssi_table_delta = 0x7fffffff; - pi->rc_cal = 0xffff; - pi->mintxbias = 0xffff; - pi->txpwridx = -1; - if (ISNPHY(pi)) { - pi->phy_spuravoid = SPURAVOID_DISABLE; - - if (NREV_GE(pi->pubpi.phy_rev, 3) - && NREV_LT(pi->pubpi.phy_rev, 7)) - pi->phy_spuravoid = SPURAVOID_AUTO; - - pi->nphy_papd_skip = 0; - pi->nphy_papd_epsilon_offset[0] = 0xf588; - pi->nphy_papd_epsilon_offset[1] = 0xf588; - pi->nphy_txpwr_idx[0] = 128; - pi->nphy_txpwr_idx[1] = 128; - pi->nphy_txpwrindex[0].index_internal = 40; - pi->nphy_txpwrindex[1].index_internal = 40; - pi->phy_pabias = 0; - } else { - pi->phy_spuravoid = SPURAVOID_AUTO; - } - pi->radiopwr = 0xffff; - for (i = 0; i < STATIC_NUM_RF; i++) { - for (j = 0; j < STATIC_NUM_BB; j++) { - pi->stats_11b_txpower[i][j] = -1; - } - } -} - -shared_phy_t *wlc_phy_shared_attach(shared_phy_params_t *shp) -{ - shared_phy_t *sh; - - sh = kzalloc(sizeof(shared_phy_t), GFP_ATOMIC); - if (sh == NULL) { - return NULL; - } - - sh->osh = shp->osh; - sh->sih = shp->sih; - sh->physhim = shp->physhim; - sh->unit = shp->unit; - sh->corerev = shp->corerev; - - sh->vid = shp->vid; - sh->did = shp->did; - sh->chip = shp->chip; - sh->chiprev = shp->chiprev; - sh->chippkg = shp->chippkg; - sh->sromrev = shp->sromrev; - sh->boardtype = shp->boardtype; - sh->boardrev = shp->boardrev; - sh->boardvendor = shp->boardvendor; - sh->boardflags = shp->boardflags; - sh->boardflags2 = shp->boardflags2; - sh->bustype = shp->bustype; - sh->buscorerev = shp->buscorerev; - - sh->fast_timer = PHY_SW_TIMER_FAST; - sh->slow_timer = PHY_SW_TIMER_SLOW; - sh->glacial_timer = PHY_SW_TIMER_GLACIAL; - - sh->rssi_mode = RSSI_ANT_MERGE_MAX; - - return sh; -} - -void wlc_phy_shared_detach(shared_phy_t *phy_sh) -{ - struct osl_info *osh; - - if (phy_sh) { - osh = phy_sh->osh; - - if (phy_sh->phy_head) { - ASSERT(!phy_sh->phy_head); - } - kfree(phy_sh); - } -} - -wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, char *vars) -{ - phy_info_t *pi; - u32 sflags = 0; - uint phyversion; - int i; - struct osl_info *osh; - - osh = sh->osh; - - if (D11REV_IS(sh->corerev, 4)) - sflags = SISF_2G_PHY | SISF_5G_PHY; - else - sflags = si_core_sflags(sh->sih, 0, 0); - - if (BAND_5G(bandtype)) { - if ((sflags & (SISF_5G_PHY | SISF_DB_PHY)) == 0) { - return NULL; - } - } - - pi = sh->phy_head; - if ((sflags & SISF_DB_PHY) && pi) { - - wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags); - pi->refcnt++; - return &pi->pubpi_ro; - } - - pi = kzalloc(sizeof(phy_info_t), GFP_ATOMIC); - if (pi == NULL) { - return NULL; - } - pi->regs = (d11regs_t *) regs; - pi->sh = sh; - pi->phy_init_por = true; - pi->phy_wreg_limit = PHY_WREG_LIMIT; - - pi->vars = vars; - - pi->txpwr_percent = 100; - - pi->do_initcal = true; - - pi->phycal_tempdelta = 0; - - if (BAND_2G(bandtype) && (sflags & SISF_2G_PHY)) { - - pi->pubpi.coreflags = SICF_GMODE; - } - - wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags); - phyversion = R_REG(osh, &pi->regs->phyversion); - - pi->pubpi.phy_type = PHY_TYPE(phyversion); - pi->pubpi.phy_rev = phyversion & PV_PV_MASK; - - if (pi->pubpi.phy_type == PHY_TYPE_LCNXN) { - pi->pubpi.phy_type = PHY_TYPE_N; - pi->pubpi.phy_rev += LCNXN_BASEREV; - } - pi->pubpi.phy_corenum = PHY_CORE_NUM_2; - pi->pubpi.ana_rev = (phyversion & PV_AV_MASK) >> PV_AV_SHIFT; - - if (!VALID_PHYTYPE(pi->pubpi.phy_type)) { - goto err; - } - if (BAND_5G(bandtype)) { - if (!ISNPHY(pi)) { - goto err; - } - } else { - if (!ISNPHY(pi) && !ISLCNPHY(pi)) { - goto err; - } - } - - if (ISSIM_ENAB(pi->sh->sih)) { - pi->pubpi.radioid = NORADIO_ID; - pi->pubpi.radiorev = 5; - } else { - u32 idcode; - - wlc_phy_anacore((wlc_phy_t *) pi, ON); - - idcode = wlc_phy_get_radio_ver(pi); - pi->pubpi.radioid = - (idcode & IDCODE_ID_MASK) >> IDCODE_ID_SHIFT; - pi->pubpi.radiorev = - (idcode & IDCODE_REV_MASK) >> IDCODE_REV_SHIFT; - pi->pubpi.radiover = - (idcode & IDCODE_VER_MASK) >> IDCODE_VER_SHIFT; - if (!VALID_RADIO(pi, pi->pubpi.radioid)) { - goto err; - } - - wlc_phy_switch_radio((wlc_phy_t *) pi, OFF); - } - - wlc_set_phy_uninitted(pi); - - pi->bw = WL_CHANSPEC_BW_20; - pi->radio_chanspec = - BAND_2G(bandtype) ? CH20MHZ_CHSPEC(1) : CH20MHZ_CHSPEC(36); - - pi->rxiq_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY; - pi->rxiq_antsel = ANT_RX_DIV_DEF; - - pi->watchdog_override = true; - - pi->cal_type_override = PHY_PERICAL_AUTO; - - pi->nphy_saved_noisevars.bufcount = 0; - - if (ISNPHY(pi)) - pi->min_txpower = PHY_TXPWR_MIN_NPHY; - else - pi->min_txpower = PHY_TXPWR_MIN; - - pi->sh->phyrxchain = 0x3; - - pi->rx2tx_biasentry = -1; - - pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP; - pi->phy_txcore_enable_temp = - PHY_CHAIN_TX_DISABLE_TEMP - PHY_HYSTERESIS_DELTATEMP; - pi->phy_tempsense_offset = 0; - pi->phy_txcore_heatedup = false; - - pi->nphy_lastcal_temp = -50; - - pi->phynoise_polling = true; - if (ISNPHY(pi) || ISLCNPHY(pi)) - pi->phynoise_polling = false; - - for (i = 0; i < TXP_NUM_RATES; i++) { - pi->txpwr_limit[i] = WLC_TXPWR_MAX; - pi->txpwr_env_limit[i] = WLC_TXPWR_MAX; - pi->tx_user_target[i] = WLC_TXPWR_MAX; - } - - pi->radiopwr_override = RADIOPWR_OVERRIDE_DEF; - - pi->user_txpwr_at_rfport = false; - - if (ISNPHY(pi)) { - - pi->phycal_timer = wlapi_init_timer(pi->sh->physhim, - wlc_phy_timercb_phycal, - pi, "phycal"); - if (!pi->phycal_timer) { - goto err; - } - - if (!wlc_phy_attach_nphy(pi)) - goto err; - - } else if (ISLCNPHY(pi)) { - if (!wlc_phy_attach_lcnphy(pi)) - goto err; - - } else { - - } - - pi->refcnt++; - pi->next = pi->sh->phy_head; - sh->phy_head = pi; - - pi->vars = (char *)&pi->vars; - - bcopy(&pi->pubpi, &pi->pubpi_ro, sizeof(wlc_phy_t)); - - return &pi->pubpi_ro; - - err: - if (pi) - kfree(pi); - return NULL; -} - -void wlc_phy_detach(wlc_phy_t *pih) -{ - phy_info_t *pi = (phy_info_t *) pih; - - if (pih) { - if (--pi->refcnt) { - return; - } - - if (pi->phycal_timer) { - wlapi_free_timer(pi->sh->physhim, pi->phycal_timer); - pi->phycal_timer = NULL; - } - - if (pi->sh->phy_head == pi) - pi->sh->phy_head = pi->next; - else if (pi->sh->phy_head->next == pi) - pi->sh->phy_head->next = NULL; - else - ASSERT(0); - - if (pi->pi_fptr.detach) - (pi->pi_fptr.detach) (pi); - - kfree(pi); - } -} - -bool -wlc_phy_get_phyversion(wlc_phy_t *pih, u16 *phytype, u16 *phyrev, - u16 *radioid, u16 *radiover) -{ - phy_info_t *pi = (phy_info_t *) pih; - *phytype = (u16) pi->pubpi.phy_type; - *phyrev = (u16) pi->pubpi.phy_rev; - *radioid = pi->pubpi.radioid; - *radiover = pi->pubpi.radiorev; - - return true; -} - -bool wlc_phy_get_encore(wlc_phy_t *pih) -{ - phy_info_t *pi = (phy_info_t *) pih; - return pi->pubpi.abgphy_encore; -} - -u32 wlc_phy_get_coreflags(wlc_phy_t *pih) -{ - phy_info_t *pi = (phy_info_t *) pih; - return pi->pubpi.coreflags; -} - -static void wlc_phy_timercb_phycal(void *arg) -{ - phy_info_t *pi = (phy_info_t *) arg; - uint delay = 5; - - if (PHY_PERICAL_MPHASE_PENDING(pi)) { - if (!pi->sh->up) { - wlc_phy_cal_perical_mphase_reset(pi); - return; - } - - if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)) { - - delay = 1000; - wlc_phy_cal_perical_mphase_restart(pi); - } else - wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_AUTO); - wlapi_add_timer(pi->sh->physhim, pi->phycal_timer, delay, 0); - return; - } - -} - -void wlc_phy_anacore(wlc_phy_t *pih, bool on) -{ - phy_info_t *pi = (phy_info_t *) pih; - - if (ISNPHY(pi)) { - if (on) { - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - write_phy_reg(pi, 0xa6, 0x0d); - write_phy_reg(pi, 0x8f, 0x0); - write_phy_reg(pi, 0xa7, 0x0d); - write_phy_reg(pi, 0xa5, 0x0); - } else { - write_phy_reg(pi, 0xa5, 0x0); - } - } else { - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - write_phy_reg(pi, 0x8f, 0x07ff); - write_phy_reg(pi, 0xa6, 0x0fd); - write_phy_reg(pi, 0xa5, 0x07ff); - write_phy_reg(pi, 0xa7, 0x0fd); - } else { - write_phy_reg(pi, 0xa5, 0x7fff); - } - } - } else if (ISLCNPHY(pi)) { - if (on) { - and_phy_reg(pi, 0x43b, - ~((0x1 << 0) | (0x1 << 1) | (0x1 << 2))); - } else { - or_phy_reg(pi, 0x43c, - (0x1 << 0) | (0x1 << 1) | (0x1 << 2)); - or_phy_reg(pi, 0x43b, - (0x1 << 0) | (0x1 << 1) | (0x1 << 2)); - } - } -} - -u32 wlc_phy_clk_bwbits(wlc_phy_t *pih) -{ - phy_info_t *pi = (phy_info_t *) pih; - - u32 phy_bw_clkbits = 0; - - if (pi && (ISNPHY(pi) || ISLCNPHY(pi))) { - switch (pi->bw) { - case WL_CHANSPEC_BW_10: - phy_bw_clkbits = SICF_BW10; - break; - case WL_CHANSPEC_BW_20: - phy_bw_clkbits = SICF_BW20; - break; - case WL_CHANSPEC_BW_40: - phy_bw_clkbits = SICF_BW40; - break; - default: - ASSERT(0); - break; - } - } - - return phy_bw_clkbits; -} - -void WLBANDINITFN(wlc_phy_por_inform) (wlc_phy_t *ppi) -{ - phy_info_t *pi = (phy_info_t *) ppi; - - pi->phy_init_por = true; -} - -void wlc_phy_edcrs_lock(wlc_phy_t *pih, bool lock) -{ - phy_info_t *pi = (phy_info_t *) pih; - - pi->edcrs_threshold_lock = lock; - - write_phy_reg(pi, 0x22c, 0x46b); - write_phy_reg(pi, 0x22d, 0x46b); - write_phy_reg(pi, 0x22e, 0x3c0); - write_phy_reg(pi, 0x22f, 0x3c0); -} - -void wlc_phy_initcal_enable(wlc_phy_t *pih, bool initcal) -{ - phy_info_t *pi = (phy_info_t *) pih; - - pi->do_initcal = initcal; -} - -void wlc_phy_hw_clk_state_upd(wlc_phy_t *pih, bool newstate) -{ - phy_info_t *pi = (phy_info_t *) pih; - - if (!pi || !pi->sh) - return; - - pi->sh->clk = newstate; -} - -void wlc_phy_hw_state_upd(wlc_phy_t *pih, bool newstate) -{ - phy_info_t *pi = (phy_info_t *) pih; - - if (!pi || !pi->sh) - return; - - pi->sh->up = newstate; -} - -void WLBANDINITFN(wlc_phy_init) (wlc_phy_t *pih, chanspec_t chanspec) -{ - u32 mc; - initfn_t phy_init = NULL; - phy_info_t *pi = (phy_info_t *) pih; - - if (pi->init_in_progress) - return; - - pi->init_in_progress = true; - - pi->radio_chanspec = chanspec; - - mc = R_REG(pi->sh->osh, &pi->regs->maccontrol); - if ((mc & MCTL_EN_MAC) != 0) { - ASSERT((const char *) - "wlc_phy_init: Called with the MAC running!" == NULL); - } - - ASSERT(pi != NULL); - - if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN)) { - pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC; - } - - if (D11REV_GE(pi->sh->corerev, 5)) - ASSERT(si_core_sflags(pi->sh->sih, 0, 0) & SISF_FCLKA); - - phy_init = pi->pi_fptr.init; - - if (phy_init == NULL) { - ASSERT(phy_init != NULL); - return; - } - - wlc_phy_anacore(pih, ON); - - if (CHSPEC_BW(pi->radio_chanspec) != pi->bw) - wlapi_bmac_bw_set(pi->sh->physhim, - CHSPEC_BW(pi->radio_chanspec)); - - pi->nphy_gain_boost = true; - - wlc_phy_switch_radio((wlc_phy_t *) pi, ON); - - (*phy_init) (pi); - - pi->phy_init_por = false; - - if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) - wlc_phy_do_dummy_tx(pi, true, OFF); - - if (!(ISNPHY(pi))) - wlc_phy_txpower_update_shm(pi); - - wlc_phy_ant_rxdiv_set((wlc_phy_t *) pi, pi->sh->rx_antdiv); - - pi->init_in_progress = false; -} - -void wlc_phy_cal_init(wlc_phy_t *pih) -{ - phy_info_t *pi = (phy_info_t *) pih; - initfn_t cal_init = NULL; - - ASSERT((R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC) == 0); - - if (!pi->initialized) { - cal_init = pi->pi_fptr.calinit; - if (cal_init) - (*cal_init) (pi); - - pi->initialized = true; - } -} - -int wlc_phy_down(wlc_phy_t *pih) -{ - phy_info_t *pi = (phy_info_t *) pih; - int callbacks = 0; - - ASSERT(pi->phytest_on == false); - - if (pi->phycal_timer - && !wlapi_del_timer(pi->sh->physhim, pi->phycal_timer)) - callbacks++; - - pi->nphy_iqcal_chanspec_2G = 0; - pi->nphy_iqcal_chanspec_5G = 0; - - return callbacks; -} - -static u32 wlc_phy_get_radio_ver(phy_info_t *pi) -{ - u32 ver; - - ver = read_radio_id(pi); - - return ver; -} - -void -wlc_phy_table_addr(phy_info_t *pi, uint tbl_id, uint tbl_offset, - u16 tblAddr, u16 tblDataHi, u16 tblDataLo) -{ - write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset); - - pi->tbl_data_hi = tblDataHi; - pi->tbl_data_lo = tblDataLo; - - if ((pi->sh->chip == BCM43224_CHIP_ID || - pi->sh->chip == BCM43421_CHIP_ID) && - (pi->sh->chiprev == 1)) { - pi->tbl_addr = tblAddr; - pi->tbl_save_id = tbl_id; - pi->tbl_save_offset = tbl_offset; - } -} - -void wlc_phy_table_data_write(phy_info_t *pi, uint width, u32 val) -{ - ASSERT((width == 8) || (width == 16) || (width == 32)); - - if ((pi->sh->chip == BCM43224_CHIP_ID || - pi->sh->chip == BCM43421_CHIP_ID) && - (pi->sh->chiprev == 1) && - (pi->tbl_save_id == NPHY_TBL_ID_ANTSWCTRLLUT)) { - read_phy_reg(pi, pi->tbl_data_lo); - - write_phy_reg(pi, pi->tbl_addr, - (pi->tbl_save_id << 10) | pi->tbl_save_offset); - pi->tbl_save_offset++; - } - - if (width == 32) { - - write_phy_reg(pi, pi->tbl_data_hi, (u16) (val >> 16)); - write_phy_reg(pi, pi->tbl_data_lo, (u16) val); - } else { - - write_phy_reg(pi, pi->tbl_data_lo, (u16) val); - } -} - -void -wlc_phy_write_table(phy_info_t *pi, const phytbl_info_t *ptbl_info, - u16 tblAddr, u16 tblDataHi, u16 tblDataLo) -{ - uint idx; - uint tbl_id = ptbl_info->tbl_id; - uint tbl_offset = ptbl_info->tbl_offset; - uint tbl_width = ptbl_info->tbl_width; - const u8 *ptbl_8b = (const u8 *)ptbl_info->tbl_ptr; - const u16 *ptbl_16b = (const u16 *)ptbl_info->tbl_ptr; - const u32 *ptbl_32b = (const u32 *)ptbl_info->tbl_ptr; - - ASSERT((tbl_width == 8) || (tbl_width == 16) || (tbl_width == 32)); - - write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset); - - for (idx = 0; idx < ptbl_info->tbl_len; idx++) { - - if ((pi->sh->chip == BCM43224_CHIP_ID || - pi->sh->chip == BCM43421_CHIP_ID) && - (pi->sh->chiprev == 1) && - (tbl_id == NPHY_TBL_ID_ANTSWCTRLLUT)) { - read_phy_reg(pi, tblDataLo); - - write_phy_reg(pi, tblAddr, - (tbl_id << 10) | (tbl_offset + idx)); - } - - if (tbl_width == 32) { - - write_phy_reg(pi, tblDataHi, - (u16) (ptbl_32b[idx] >> 16)); - write_phy_reg(pi, tblDataLo, (u16) ptbl_32b[idx]); - } else if (tbl_width == 16) { - - write_phy_reg(pi, tblDataLo, ptbl_16b[idx]); - } else { - - write_phy_reg(pi, tblDataLo, ptbl_8b[idx]); - } - } -} - -void -wlc_phy_read_table(phy_info_t *pi, const phytbl_info_t *ptbl_info, - u16 tblAddr, u16 tblDataHi, u16 tblDataLo) -{ - uint idx; - uint tbl_id = ptbl_info->tbl_id; - uint tbl_offset = ptbl_info->tbl_offset; - uint tbl_width = ptbl_info->tbl_width; - u8 *ptbl_8b = (u8 *)ptbl_info->tbl_ptr; - u16 *ptbl_16b = (u16 *)ptbl_info->tbl_ptr; - u32 *ptbl_32b = (u32 *)ptbl_info->tbl_ptr; - - ASSERT((tbl_width == 8) || (tbl_width == 16) || (tbl_width == 32)); - - write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset); - - for (idx = 0; idx < ptbl_info->tbl_len; idx++) { - - if ((pi->sh->chip == BCM43224_CHIP_ID || - pi->sh->chip == BCM43421_CHIP_ID) && - (pi->sh->chiprev == 1)) { - (void)read_phy_reg(pi, tblDataLo); - - write_phy_reg(pi, tblAddr, - (tbl_id << 10) | (tbl_offset + idx)); - } - - if (tbl_width == 32) { - - ptbl_32b[idx] = read_phy_reg(pi, tblDataLo); - ptbl_32b[idx] |= (read_phy_reg(pi, tblDataHi) << 16); - } else if (tbl_width == 16) { - - ptbl_16b[idx] = read_phy_reg(pi, tblDataLo); - } else { - - ptbl_8b[idx] = (u8) read_phy_reg(pi, tblDataLo); - } - } -} - -uint -wlc_phy_init_radio_regs_allbands(phy_info_t *pi, radio_20xx_regs_t *radioregs) -{ - uint i = 0; - - do { - if (radioregs[i].do_init) { - write_radio_reg(pi, radioregs[i].address, - (u16) radioregs[i].init); - } - - i++; - } while (radioregs[i].address != 0xffff); - - return i; -} - -uint -wlc_phy_init_radio_regs(phy_info_t *pi, radio_regs_t *radioregs, - u16 core_offset) -{ - uint i = 0; - uint count = 0; - - do { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - if (radioregs[i].do_init_a) { - write_radio_reg(pi, - radioregs[i]. - address | core_offset, - (u16) radioregs[i].init_a); - if (ISNPHY(pi) && (++count % 4 == 0)) - WLC_PHY_WAR_PR51571(pi); - } - } else { - if (radioregs[i].do_init_g) { - write_radio_reg(pi, - radioregs[i]. - address | core_offset, - (u16) radioregs[i].init_g); - if (ISNPHY(pi) && (++count % 4 == 0)) - WLC_PHY_WAR_PR51571(pi); - } - } - - i++; - } while (radioregs[i].address != 0xffff); - - return i; -} - -void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on) -{ -#define DUMMY_PKT_LEN 20 - d11regs_t *regs = pi->regs; - int i, count; - u8 ofdmpkt[DUMMY_PKT_LEN] = { - 0xcc, 0x01, 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 - }; - u8 cckpkt[DUMMY_PKT_LEN] = { - 0x6e, 0x84, 0x0b, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 - }; - u32 *dummypkt; - - ASSERT((R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC) == 0); - - dummypkt = (u32 *) (ofdm ? ofdmpkt : cckpkt); - wlapi_bmac_write_template_ram(pi->sh->physhim, 0, DUMMY_PKT_LEN, - dummypkt); - - W_REG(pi->sh->osh, ®s->xmtsel, 0); - - if (D11REV_GE(pi->sh->corerev, 11)) - W_REG(pi->sh->osh, ®s->wepctl, 0x100); - else - W_REG(pi->sh->osh, ®s->wepctl, 0); - - W_REG(pi->sh->osh, ®s->txe_phyctl, (ofdm ? 1 : 0) | PHY_TXC_ANT_0); - if (ISNPHY(pi) || ISLCNPHY(pi)) { - ASSERT(ofdm); - W_REG(pi->sh->osh, ®s->txe_phyctl1, 0x1A02); - } - - W_REG(pi->sh->osh, ®s->txe_wm_0, 0); - W_REG(pi->sh->osh, ®s->txe_wm_1, 0); - - W_REG(pi->sh->osh, ®s->xmttplatetxptr, 0); - W_REG(pi->sh->osh, ®s->xmttxcnt, DUMMY_PKT_LEN); - - W_REG(pi->sh->osh, ®s->xmtsel, ((8 << 8) | (1 << 5) | (1 << 2) | 2)); - - W_REG(pi->sh->osh, ®s->txe_ctl, 0); - - if (!pa_on) { - if (ISNPHY(pi)) - wlc_phy_pa_override_nphy(pi, OFF); - } - - if (ISNPHY(pi) || ISLCNPHY(pi)) - W_REG(pi->sh->osh, ®s->txe_aux, 0xD0); - else - W_REG(pi->sh->osh, ®s->txe_aux, ((1 << 5) | (1 << 4))); - - (void)R_REG(pi->sh->osh, ®s->txe_aux); - - i = 0; - count = ofdm ? 30 : 250; - - if (ISSIM_ENAB(pi->sh->sih)) { - count *= 100; - } - - while ((i++ < count) - && (R_REG(pi->sh->osh, ®s->txe_status) & (1 << 7))) { - udelay(10); - } - - i = 0; - - while ((i++ < 10) - && ((R_REG(pi->sh->osh, ®s->txe_status) & (1 << 10)) == 0)) { - udelay(10); - } - - i = 0; - - while ((i++ < 10) && ((R_REG(pi->sh->osh, ®s->ifsstat) & (1 << 8)))) { - udelay(10); - } - if (!pa_on) { - if (ISNPHY(pi)) - wlc_phy_pa_override_nphy(pi, ON); - } -} - -void wlc_phy_hold_upd(wlc_phy_t *pih, mbool id, bool set) -{ - phy_info_t *pi = (phy_info_t *) pih; - ASSERT(id); - - if (set) { - mboolset(pi->measure_hold, id); - } else { - mboolclr(pi->measure_hold, id); - } - - return; -} - -void wlc_phy_mute_upd(wlc_phy_t *pih, bool mute, mbool flags) -{ - phy_info_t *pi = (phy_info_t *) pih; - - if (mute) { - mboolset(pi->measure_hold, PHY_HOLD_FOR_MUTE); - } else { - mboolclr(pi->measure_hold, PHY_HOLD_FOR_MUTE); - } - - if (!mute && (flags & PHY_MUTE_FOR_PREISM)) - pi->nphy_perical_last = pi->sh->now - pi->sh->glacial_timer; - return; -} - -void wlc_phy_clear_tssi(wlc_phy_t *pih) -{ - phy_info_t *pi = (phy_info_t *) pih; - - if (ISNPHY(pi)) { - return; - } else { - wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_0, NULL_TSSI_W); - wlapi_bmac_write_shm(pi->sh->physhim, M_B_TSSI_1, NULL_TSSI_W); - wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_0, NULL_TSSI_W); - wlapi_bmac_write_shm(pi->sh->physhim, M_G_TSSI_1, NULL_TSSI_W); - } -} - -static bool wlc_phy_cal_txpower_recalc_sw(phy_info_t *pi) -{ - return false; -} - -void wlc_phy_switch_radio(wlc_phy_t *pih, bool on) -{ - phy_info_t *pi = (phy_info_t *) pih; - - if (NORADIO_ENAB(pi->pubpi)) - return; - - { - uint mc; - - mc = R_REG(pi->sh->osh, &pi->regs->maccontrol); - } - - if (ISNPHY(pi)) { - wlc_phy_switch_radio_nphy(pi, on); - - } else if (ISLCNPHY(pi)) { - if (on) { - and_phy_reg(pi, 0x44c, - ~((0x1 << 8) | - (0x1 << 9) | - (0x1 << 10) | (0x1 << 11) | (0x1 << 12))); - and_phy_reg(pi, 0x4b0, ~((0x1 << 3) | (0x1 << 11))); - and_phy_reg(pi, 0x4f9, ~(0x1 << 3)); - } else { - and_phy_reg(pi, 0x44d, - ~((0x1 << 10) | - (0x1 << 11) | - (0x1 << 12) | (0x1 << 13) | (0x1 << 14))); - or_phy_reg(pi, 0x44c, - (0x1 << 8) | - (0x1 << 9) | - (0x1 << 10) | (0x1 << 11) | (0x1 << 12)); - - and_phy_reg(pi, 0x4b7, ~((0x7f << 8))); - and_phy_reg(pi, 0x4b1, ~((0x1 << 13))); - or_phy_reg(pi, 0x4b0, (0x1 << 3) | (0x1 << 11)); - and_phy_reg(pi, 0x4fa, ~((0x1 << 3))); - or_phy_reg(pi, 0x4f9, (0x1 << 3)); - } - } -} - -u16 wlc_phy_bw_state_get(wlc_phy_t *ppi) -{ - phy_info_t *pi = (phy_info_t *) ppi; - - return pi->bw; -} - -void wlc_phy_bw_state_set(wlc_phy_t *ppi, u16 bw) -{ - phy_info_t *pi = (phy_info_t *) ppi; - - pi->bw = bw; -} - -void wlc_phy_chanspec_radio_set(wlc_phy_t *ppi, chanspec_t newch) -{ - phy_info_t *pi = (phy_info_t *) ppi; - pi->radio_chanspec = newch; - -} - -chanspec_t wlc_phy_chanspec_get(wlc_phy_t *ppi) -{ - phy_info_t *pi = (phy_info_t *) ppi; - - return pi->radio_chanspec; -} - -void wlc_phy_chanspec_set(wlc_phy_t *ppi, chanspec_t chanspec) -{ - phy_info_t *pi = (phy_info_t *) ppi; - u16 m_cur_channel; - chansetfn_t chanspec_set = NULL; - - ASSERT(!wf_chspec_malformed(chanspec)); - - m_cur_channel = CHSPEC_CHANNEL(chanspec); - if (CHSPEC_IS5G(chanspec)) - m_cur_channel |= D11_CURCHANNEL_5G; - if (CHSPEC_IS40(chanspec)) - m_cur_channel |= D11_CURCHANNEL_40; - wlapi_bmac_write_shm(pi->sh->physhim, M_CURCHANNEL, m_cur_channel); - - chanspec_set = pi->pi_fptr.chanset; - if (chanspec_set) - (*chanspec_set) (pi, chanspec); - -} - -int wlc_phy_chanspec_freq2bandrange_lpssn(uint freq) -{ - int range = -1; - - if (freq < 2500) - range = WL_CHAN_FREQ_RANGE_2G; - else if (freq <= 5320) - range = WL_CHAN_FREQ_RANGE_5GL; - else if (freq <= 5700) - range = WL_CHAN_FREQ_RANGE_5GM; - else - range = WL_CHAN_FREQ_RANGE_5GH; - - return range; -} - -int wlc_phy_chanspec_bandrange_get(phy_info_t *pi, chanspec_t chanspec) -{ - int range = -1; - uint channel = CHSPEC_CHANNEL(chanspec); - uint freq = wlc_phy_channel2freq(channel); - - if (ISNPHY(pi)) { - range = wlc_phy_get_chan_freq_range_nphy(pi, channel); - } else if (ISLCNPHY(pi)) { - range = wlc_phy_chanspec_freq2bandrange_lpssn(freq); - } else - ASSERT(0); - - return range; -} - -void wlc_phy_chanspec_ch14_widefilter_set(wlc_phy_t *ppi, bool wide_filter) -{ - phy_info_t *pi = (phy_info_t *) ppi; - - pi->channel_14_wide_filter = wide_filter; - -} - -int wlc_phy_channel2freq(uint channel) -{ - uint i; - - for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) - if (chan_info_all[i].chan == channel) - return chan_info_all[i].freq; - return 0; -} - -void -wlc_phy_chanspec_band_validch(wlc_phy_t *ppi, uint band, chanvec_t *channels) -{ - phy_info_t *pi = (phy_info_t *) ppi; - uint i; - uint channel; - - ASSERT((band == WLC_BAND_2G) || (band == WLC_BAND_5G)); - - memset(channels, 0, sizeof(chanvec_t)); - - for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) { - channel = chan_info_all[i].chan; - - if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM) - && (channel <= LAST_REF5_CHANNUM)) - continue; - - if (((band == WLC_BAND_2G) && (channel <= CH_MAX_2G_CHANNEL)) || - ((band == WLC_BAND_5G) && (channel > CH_MAX_2G_CHANNEL))) - setbit(channels->vec, channel); - } -} - -chanspec_t wlc_phy_chanspec_band_firstch(wlc_phy_t *ppi, uint band) -{ - phy_info_t *pi = (phy_info_t *) ppi; - uint i; - uint channel; - chanspec_t chspec; - - ASSERT((band == WLC_BAND_2G) || (band == WLC_BAND_5G)); - - for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) { - channel = chan_info_all[i].chan; - - if (ISNPHY(pi) && IS40MHZ(pi)) { - uint j; - - for (j = 0; j < ARRAY_SIZE(chan_info_all); j++) { - if (chan_info_all[j].chan == - channel + CH_10MHZ_APART) - break; - } - - if (j == ARRAY_SIZE(chan_info_all)) - continue; - - channel = UPPER_20_SB(channel); - chspec = - channel | WL_CHANSPEC_BW_40 | - WL_CHANSPEC_CTL_SB_LOWER; - if (band == WLC_BAND_2G) - chspec |= WL_CHANSPEC_BAND_2G; - else - chspec |= WL_CHANSPEC_BAND_5G; - } else - chspec = CH20MHZ_CHSPEC(channel); - - if ((pi->a_band_high_disable) && (channel >= FIRST_REF5_CHANNUM) - && (channel <= LAST_REF5_CHANNUM)) - continue; - - if (((band == WLC_BAND_2G) && (channel <= CH_MAX_2G_CHANNEL)) || - ((band == WLC_BAND_5G) && (channel > CH_MAX_2G_CHANNEL))) - return chspec; - } - - ASSERT(0); - - return (chanspec_t) INVCHANSPEC; -} - -int wlc_phy_txpower_get(wlc_phy_t *ppi, uint *qdbm, bool *override) -{ - phy_info_t *pi = (phy_info_t *) ppi; - - ASSERT(qdbm != NULL); - *qdbm = pi->tx_user_target[0]; - if (override != NULL) - *override = pi->txpwroverride; - return 0; -} - -void wlc_phy_txpower_target_set(wlc_phy_t *ppi, struct txpwr_limits *txpwr) -{ - bool mac_enabled = false; - phy_info_t *pi = (phy_info_t *) ppi; - - bcopy(&txpwr->cck[0], &pi->tx_user_target[TXP_FIRST_CCK], - WLC_NUM_RATES_CCK); - - bcopy(&txpwr->ofdm[0], &pi->tx_user_target[TXP_FIRST_OFDM], - WLC_NUM_RATES_OFDM); - bcopy(&txpwr->ofdm_cdd[0], &pi->tx_user_target[TXP_FIRST_OFDM_20_CDD], - WLC_NUM_RATES_OFDM); - - bcopy(&txpwr->ofdm_40_siso[0], - &pi->tx_user_target[TXP_FIRST_OFDM_40_SISO], WLC_NUM_RATES_OFDM); - bcopy(&txpwr->ofdm_40_cdd[0], - &pi->tx_user_target[TXP_FIRST_OFDM_40_CDD], WLC_NUM_RATES_OFDM); - - bcopy(&txpwr->mcs_20_siso[0], - &pi->tx_user_target[TXP_FIRST_MCS_20_SISO], - WLC_NUM_RATES_MCS_1_STREAM); - bcopy(&txpwr->mcs_20_cdd[0], &pi->tx_user_target[TXP_FIRST_MCS_20_CDD], - WLC_NUM_RATES_MCS_1_STREAM); - bcopy(&txpwr->mcs_20_stbc[0], - &pi->tx_user_target[TXP_FIRST_MCS_20_STBC], - WLC_NUM_RATES_MCS_1_STREAM); - bcopy(&txpwr->mcs_20_mimo[0], &pi->tx_user_target[TXP_FIRST_MCS_20_SDM], - WLC_NUM_RATES_MCS_2_STREAM); - - bcopy(&txpwr->mcs_40_siso[0], - &pi->tx_user_target[TXP_FIRST_MCS_40_SISO], - WLC_NUM_RATES_MCS_1_STREAM); - bcopy(&txpwr->mcs_40_cdd[0], &pi->tx_user_target[TXP_FIRST_MCS_40_CDD], - WLC_NUM_RATES_MCS_1_STREAM); - bcopy(&txpwr->mcs_40_stbc[0], - &pi->tx_user_target[TXP_FIRST_MCS_40_STBC], - WLC_NUM_RATES_MCS_1_STREAM); - bcopy(&txpwr->mcs_40_mimo[0], &pi->tx_user_target[TXP_FIRST_MCS_40_SDM], - WLC_NUM_RATES_MCS_2_STREAM); - - if (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC) - mac_enabled = true; - - if (mac_enabled) - wlapi_suspend_mac_and_wait(pi->sh->physhim); - - wlc_phy_txpower_recalc_target(pi); - wlc_phy_cal_txpower_recalc_sw(pi); - - if (mac_enabled) - wlapi_enable_mac(pi->sh->physhim); -} - -int wlc_phy_txpower_set(wlc_phy_t *ppi, uint qdbm, bool override) -{ - phy_info_t *pi = (phy_info_t *) ppi; - int i; - - if (qdbm > 127) - return 5; - - for (i = 0; i < TXP_NUM_RATES; i++) - pi->tx_user_target[i] = (u8) qdbm; - - pi->txpwroverride = false; - - if (pi->sh->up) { - if (!SCAN_INPROG_PHY(pi)) { - bool suspend; - - suspend = - (0 == - (R_REG(pi->sh->osh, &pi->regs->maccontrol) & - MCTL_EN_MAC)); - - if (!suspend) - wlapi_suspend_mac_and_wait(pi->sh->physhim); - - wlc_phy_txpower_recalc_target(pi); - wlc_phy_cal_txpower_recalc_sw(pi); - - if (!suspend) - wlapi_enable_mac(pi->sh->physhim); - } - } - return 0; -} - -void -wlc_phy_txpower_sromlimit(wlc_phy_t *ppi, uint channel, u8 *min_pwr, - u8 *max_pwr, int txp_rate_idx) -{ - phy_info_t *pi = (phy_info_t *) ppi; - uint i; - - *min_pwr = pi->min_txpower * WLC_TXPWR_DB_FACTOR; - - if (ISNPHY(pi)) { - if (txp_rate_idx < 0) - txp_rate_idx = TXP_FIRST_CCK; - wlc_phy_txpower_sromlimit_get_nphy(pi, channel, max_pwr, - (u8) txp_rate_idx); - - } else if ((channel <= CH_MAX_2G_CHANNEL)) { - if (txp_rate_idx < 0) - txp_rate_idx = TXP_FIRST_CCK; - *max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx]; - } else { - - *max_pwr = WLC_TXPWR_MAX; - - if (txp_rate_idx < 0) - txp_rate_idx = TXP_FIRST_OFDM; - - for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) { - if (channel == chan_info_all[i].chan) { - break; - } - } - ASSERT(i < ARRAY_SIZE(chan_info_all)); - - if (pi->hwtxpwr) { - *max_pwr = pi->hwtxpwr[i]; - } else { - - if ((i >= FIRST_MID_5G_CHAN) && (i <= LAST_MID_5G_CHAN)) - *max_pwr = - pi->tx_srom_max_rate_5g_mid[txp_rate_idx]; - if ((i >= FIRST_HIGH_5G_CHAN) - && (i <= LAST_HIGH_5G_CHAN)) - *max_pwr = - pi->tx_srom_max_rate_5g_hi[txp_rate_idx]; - if ((i >= FIRST_LOW_5G_CHAN) && (i <= LAST_LOW_5G_CHAN)) - *max_pwr = - pi->tx_srom_max_rate_5g_low[txp_rate_idx]; - } - } -} - -void -wlc_phy_txpower_sromlimit_max_get(wlc_phy_t *ppi, uint chan, u8 *max_txpwr, - u8 *min_txpwr) -{ - phy_info_t *pi = (phy_info_t *) ppi; - u8 tx_pwr_max = 0; - u8 tx_pwr_min = 255; - u8 max_num_rate; - u8 maxtxpwr, mintxpwr, rate, pactrl; - - pactrl = 0; - - max_num_rate = ISNPHY(pi) ? TXP_NUM_RATES : - ISLCNPHY(pi) ? (TXP_LAST_SISO_MCS_20 + 1) : (TXP_LAST_OFDM + 1); - - for (rate = 0; rate < max_num_rate; rate++) { - - wlc_phy_txpower_sromlimit(ppi, chan, &mintxpwr, &maxtxpwr, - rate); - - maxtxpwr = (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0; - - maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0; - - tx_pwr_max = max(tx_pwr_max, maxtxpwr); - tx_pwr_min = min(tx_pwr_min, maxtxpwr); - } - *max_txpwr = tx_pwr_max; - *min_txpwr = tx_pwr_min; -} - -void -wlc_phy_txpower_boardlimit_band(wlc_phy_t *ppi, uint bandunit, s32 *max_pwr, - s32 *min_pwr, u32 *step_pwr) -{ - return; -} - -u8 wlc_phy_txpower_get_target_min(wlc_phy_t *ppi) -{ - phy_info_t *pi = (phy_info_t *) ppi; - - return pi->tx_power_min; -} - -u8 wlc_phy_txpower_get_target_max(wlc_phy_t *ppi) -{ - phy_info_t *pi = (phy_info_t *) ppi; - - return pi->tx_power_max; -} - -void wlc_phy_txpower_recalc_target(phy_info_t *pi) -{ - u8 maxtxpwr, mintxpwr, rate, pactrl; - uint target_chan; - u8 tx_pwr_target[TXP_NUM_RATES]; - u8 tx_pwr_max = 0; - u8 tx_pwr_min = 255; - u8 tx_pwr_max_rate_ind = 0; - u8 max_num_rate; - u8 start_rate = 0; - chanspec_t chspec; - u32 band = CHSPEC2WLC_BAND(pi->radio_chanspec); - initfn_t txpwr_recalc_fn = NULL; - - chspec = pi->radio_chanspec; - if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) - target_chan = CHSPEC_CHANNEL(chspec); - else if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) - target_chan = UPPER_20_SB(CHSPEC_CHANNEL(chspec)); - else - target_chan = LOWER_20_SB(CHSPEC_CHANNEL(chspec)); - - pactrl = 0; - if (ISLCNPHY(pi)) { - u32 offset_mcs, i; - - if (CHSPEC_IS40(pi->radio_chanspec)) { - offset_mcs = pi->mcs40_po; - for (i = TXP_FIRST_SISO_MCS_20; - i <= TXP_LAST_SISO_MCS_20; i++) { - pi->tx_srom_max_rate_2g[i - 8] = - pi->tx_srom_max_2g - - ((offset_mcs & 0xf) * 2); - offset_mcs >>= 4; - } - } else { - offset_mcs = pi->mcs20_po; - for (i = TXP_FIRST_SISO_MCS_20; - i <= TXP_LAST_SISO_MCS_20; i++) { - pi->tx_srom_max_rate_2g[i - 8] = - pi->tx_srom_max_2g - - ((offset_mcs & 0xf) * 2); - offset_mcs >>= 4; - } - } - } -#if WL11N - max_num_rate = ((ISNPHY(pi)) ? (TXP_NUM_RATES) : - ((ISLCNPHY(pi)) ? - (TXP_LAST_SISO_MCS_20 + 1) : (TXP_LAST_OFDM + 1))); -#else - max_num_rate = ((ISNPHY(pi)) ? (TXP_NUM_RATES) : (TXP_LAST_OFDM + 1)); -#endif - - wlc_phy_upd_env_txpwr_rate_limits(pi, band); - - for (rate = start_rate; rate < max_num_rate; rate++) { - - tx_pwr_target[rate] = pi->tx_user_target[rate]; - - if (pi->user_txpwr_at_rfport) { - tx_pwr_target[rate] += - wlc_user_txpwr_antport_to_rfport(pi, target_chan, - band, rate); - } - - { - - wlc_phy_txpower_sromlimit((wlc_phy_t *) pi, target_chan, - &mintxpwr, &maxtxpwr, rate); - - maxtxpwr = min(maxtxpwr, pi->txpwr_limit[rate]); - - maxtxpwr = - (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0; - - maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0; - - maxtxpwr = min(maxtxpwr, tx_pwr_target[rate]); - - if (pi->txpwr_percent <= 100) - maxtxpwr = (maxtxpwr * pi->txpwr_percent) / 100; - - tx_pwr_target[rate] = max(maxtxpwr, mintxpwr); - } - - tx_pwr_target[rate] = - min(tx_pwr_target[rate], pi->txpwr_env_limit[rate]); - - if (tx_pwr_target[rate] > tx_pwr_max) - tx_pwr_max_rate_ind = rate; - - tx_pwr_max = max(tx_pwr_max, tx_pwr_target[rate]); - tx_pwr_min = min(tx_pwr_min, tx_pwr_target[rate]); - } - - memset(pi->tx_power_offset, 0, sizeof(pi->tx_power_offset)); - pi->tx_power_max = tx_pwr_max; - pi->tx_power_min = tx_pwr_min; - pi->tx_power_max_rate_ind = tx_pwr_max_rate_ind; - for (rate = 0; rate < max_num_rate; rate++) { - - pi->tx_power_target[rate] = tx_pwr_target[rate]; - - if (!pi->hwpwrctrl || ISNPHY(pi)) { - pi->tx_power_offset[rate] = - pi->tx_power_max - pi->tx_power_target[rate]; - } else { - pi->tx_power_offset[rate] = - pi->tx_power_target[rate] - pi->tx_power_min; - } - } - - txpwr_recalc_fn = pi->pi_fptr.txpwrrecalc; - if (txpwr_recalc_fn) - (*txpwr_recalc_fn) (pi); -} - -void -wlc_phy_txpower_reg_limit_calc(phy_info_t *pi, struct txpwr_limits *txpwr, - chanspec_t chanspec) -{ - u8 tmp_txpwr_limit[2 * WLC_NUM_RATES_OFDM]; - u8 *txpwr_ptr1 = NULL, *txpwr_ptr2 = NULL; - int rate_start_index = 0, rate1, rate2, k; - - for (rate1 = WL_TX_POWER_CCK_FIRST, rate2 = 0; - rate2 < WL_TX_POWER_CCK_NUM; rate1++, rate2++) - pi->txpwr_limit[rate1] = txpwr->cck[rate2]; - - for (rate1 = WL_TX_POWER_OFDM_FIRST, rate2 = 0; - rate2 < WL_TX_POWER_OFDM_NUM; rate1++, rate2++) - pi->txpwr_limit[rate1] = txpwr->ofdm[rate2]; - - if (ISNPHY(pi)) { - - for (k = 0; k < 4; k++) { - switch (k) { - case 0: - - txpwr_ptr1 = txpwr->mcs_20_siso; - txpwr_ptr2 = txpwr->ofdm; - rate_start_index = WL_TX_POWER_OFDM_FIRST; - break; - case 1: - - txpwr_ptr1 = txpwr->mcs_20_cdd; - txpwr_ptr2 = txpwr->ofdm_cdd; - rate_start_index = WL_TX_POWER_OFDM20_CDD_FIRST; - break; - case 2: - - txpwr_ptr1 = txpwr->mcs_40_siso; - txpwr_ptr2 = txpwr->ofdm_40_siso; - rate_start_index = - WL_TX_POWER_OFDM40_SISO_FIRST; - break; - case 3: - - txpwr_ptr1 = txpwr->mcs_40_cdd; - txpwr_ptr2 = txpwr->ofdm_40_cdd; - rate_start_index = WL_TX_POWER_OFDM40_CDD_FIRST; - break; - } - - for (rate2 = 0; rate2 < WLC_NUM_RATES_OFDM; rate2++) { - tmp_txpwr_limit[rate2] = 0; - tmp_txpwr_limit[WLC_NUM_RATES_OFDM + rate2] = - txpwr_ptr1[rate2]; - } - wlc_phy_mcs_to_ofdm_powers_nphy(tmp_txpwr_limit, 0, - WLC_NUM_RATES_OFDM - 1, - WLC_NUM_RATES_OFDM); - for (rate1 = rate_start_index, rate2 = 0; - rate2 < WLC_NUM_RATES_OFDM; rate1++, rate2++) - pi->txpwr_limit[rate1] = - min(txpwr_ptr2[rate2], - tmp_txpwr_limit[rate2]); - } - - for (k = 0; k < 4; k++) { - switch (k) { - case 0: - - txpwr_ptr1 = txpwr->ofdm; - txpwr_ptr2 = txpwr->mcs_20_siso; - rate_start_index = WL_TX_POWER_MCS20_SISO_FIRST; - break; - case 1: - - txpwr_ptr1 = txpwr->ofdm_cdd; - txpwr_ptr2 = txpwr->mcs_20_cdd; - rate_start_index = WL_TX_POWER_MCS20_CDD_FIRST; - break; - case 2: - - txpwr_ptr1 = txpwr->ofdm_40_siso; - txpwr_ptr2 = txpwr->mcs_40_siso; - rate_start_index = WL_TX_POWER_MCS40_SISO_FIRST; - break; - case 3: - - txpwr_ptr1 = txpwr->ofdm_40_cdd; - txpwr_ptr2 = txpwr->mcs_40_cdd; - rate_start_index = WL_TX_POWER_MCS40_CDD_FIRST; - break; - } - for (rate2 = 0; rate2 < WLC_NUM_RATES_OFDM; rate2++) { - tmp_txpwr_limit[rate2] = 0; - tmp_txpwr_limit[WLC_NUM_RATES_OFDM + rate2] = - txpwr_ptr1[rate2]; - } - wlc_phy_ofdm_to_mcs_powers_nphy(tmp_txpwr_limit, 0, - WLC_NUM_RATES_OFDM - 1, - WLC_NUM_RATES_OFDM); - for (rate1 = rate_start_index, rate2 = 0; - rate2 < WLC_NUM_RATES_MCS_1_STREAM; - rate1++, rate2++) - pi->txpwr_limit[rate1] = - min(txpwr_ptr2[rate2], - tmp_txpwr_limit[rate2]); - } - - for (k = 0; k < 2; k++) { - switch (k) { - case 0: - - rate_start_index = WL_TX_POWER_MCS20_STBC_FIRST; - txpwr_ptr1 = txpwr->mcs_20_stbc; - break; - case 1: - - rate_start_index = WL_TX_POWER_MCS40_STBC_FIRST; - txpwr_ptr1 = txpwr->mcs_40_stbc; - break; - } - for (rate1 = rate_start_index, rate2 = 0; - rate2 < WLC_NUM_RATES_MCS_1_STREAM; - rate1++, rate2++) - pi->txpwr_limit[rate1] = txpwr_ptr1[rate2]; - } - - for (k = 0; k < 2; k++) { - switch (k) { - case 0: - - rate_start_index = WL_TX_POWER_MCS20_SDM_FIRST; - txpwr_ptr1 = txpwr->mcs_20_mimo; - break; - case 1: - - rate_start_index = WL_TX_POWER_MCS40_SDM_FIRST; - txpwr_ptr1 = txpwr->mcs_40_mimo; - break; - } - for (rate1 = rate_start_index, rate2 = 0; - rate2 < WLC_NUM_RATES_MCS_2_STREAM; - rate1++, rate2++) - pi->txpwr_limit[rate1] = txpwr_ptr1[rate2]; - } - - pi->txpwr_limit[WL_TX_POWER_MCS_32] = txpwr->mcs32; - - pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST] = - min(pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST], - pi->txpwr_limit[WL_TX_POWER_MCS_32]); - pi->txpwr_limit[WL_TX_POWER_MCS_32] = - pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST]; - } -} - -void wlc_phy_txpwr_percent_set(wlc_phy_t *ppi, u8 txpwr_percent) -{ - phy_info_t *pi = (phy_info_t *) ppi; - - pi->txpwr_percent = txpwr_percent; -} - -void wlc_phy_machwcap_set(wlc_phy_t *ppi, u32 machwcap) -{ - phy_info_t *pi = (phy_info_t *) ppi; - - pi->sh->machwcap = machwcap; -} - -void wlc_phy_runbist_config(wlc_phy_t *ppi, bool start_end) -{ - phy_info_t *pi = (phy_info_t *) ppi; - u16 rxc; - rxc = 0; - - if (start_end == ON) { - if (!ISNPHY(pi)) - return; - - if (NREV_IS(pi->pubpi.phy_rev, 3) - || NREV_IS(pi->pubpi.phy_rev, 4)) { - W_REG(pi->sh->osh, &pi->regs->phyregaddr, 0xa0); - (void)R_REG(pi->sh->osh, &pi->regs->phyregaddr); - rxc = R_REG(pi->sh->osh, &pi->regs->phyregdata); - W_REG(pi->sh->osh, &pi->regs->phyregdata, - (0x1 << 15) | rxc); - } - } else { - if (NREV_IS(pi->pubpi.phy_rev, 3) - || NREV_IS(pi->pubpi.phy_rev, 4)) { - W_REG(pi->sh->osh, &pi->regs->phyregaddr, 0xa0); - (void)R_REG(pi->sh->osh, &pi->regs->phyregaddr); - W_REG(pi->sh->osh, &pi->regs->phyregdata, rxc); - } - - wlc_phy_por_inform(ppi); - } -} - -void -wlc_phy_txpower_limit_set(wlc_phy_t *ppi, struct txpwr_limits *txpwr, - chanspec_t chanspec) -{ - phy_info_t *pi = (phy_info_t *) ppi; - - wlc_phy_txpower_reg_limit_calc(pi, txpwr, chanspec); - - if (ISLCNPHY(pi)) { - int i, j; - for (i = TXP_FIRST_OFDM_20_CDD, j = 0; - j < WLC_NUM_RATES_MCS_1_STREAM; i++, j++) { - if (txpwr->mcs_20_siso[j]) - pi->txpwr_limit[i] = txpwr->mcs_20_siso[j]; - else - pi->txpwr_limit[i] = txpwr->ofdm[j]; - } - } - - wlapi_suspend_mac_and_wait(pi->sh->physhim); - - wlc_phy_txpower_recalc_target(pi); - wlc_phy_cal_txpower_recalc_sw(pi); - wlapi_enable_mac(pi->sh->physhim); -} - -void wlc_phy_ofdm_rateset_war(wlc_phy_t *pih, bool war) -{ - phy_info_t *pi = (phy_info_t *) pih; - - pi->ofdm_rateset_war = war; -} - -void wlc_phy_bf_preempt_enable(wlc_phy_t *pih, bool bf_preempt) -{ - phy_info_t *pi = (phy_info_t *) pih; - - pi->bf_preempt_4306 = bf_preempt; -} - -void wlc_phy_txpower_update_shm(phy_info_t *pi) -{ - int j; - if (ISNPHY(pi)) { - ASSERT(0); - return; - } - - if (!pi->sh->clk) - return; - - if (pi->hwpwrctrl) { - u16 offset; - - wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_MAX, 63); - wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_N, - 1 << NUM_TSSI_FRAMES); - - wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_TARGET, - pi->tx_power_min << NUM_TSSI_FRAMES); - - wlapi_bmac_write_shm(pi->sh->physhim, M_TXPWR_CUR, - pi->hwpwr_txcur); - - for (j = TXP_FIRST_OFDM; j <= TXP_LAST_OFDM; j++) { - const u8 ucode_ofdm_rates[] = { - 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c - }; - offset = wlapi_bmac_rate_shm_offset(pi->sh->physhim, - ucode_ofdm_rates[j - - TXP_FIRST_OFDM]); - wlapi_bmac_write_shm(pi->sh->physhim, offset + 6, - pi->tx_power_offset[j]); - wlapi_bmac_write_shm(pi->sh->physhim, offset + 14, - -(pi->tx_power_offset[j] / 2)); - } - - wlapi_bmac_mhf(pi->sh->physhim, MHF2, MHF2_HWPWRCTL, - MHF2_HWPWRCTL, WLC_BAND_ALL); - } else { - int i; - - for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) - pi->tx_power_offset[i] = - (u8) roundup(pi->tx_power_offset[i], 8); - wlapi_bmac_write_shm(pi->sh->physhim, M_OFDM_OFFSET, - (u16) ((pi-> - tx_power_offset[TXP_FIRST_OFDM] - + 7) >> 3)); - } -} - -bool wlc_phy_txpower_hw_ctrl_get(wlc_phy_t *ppi) -{ - phy_info_t *pi = (phy_info_t *) ppi; - - if (ISNPHY(pi)) { - return pi->nphy_txpwrctrl; - } else { - return pi->hwpwrctrl; - } -} - -void wlc_phy_txpower_hw_ctrl_set(wlc_phy_t *ppi, bool hwpwrctrl) -{ - phy_info_t *pi = (phy_info_t *) ppi; - bool cur_hwpwrctrl = pi->hwpwrctrl; - bool suspend; - - if (!pi->hwpwrctrl_capable) { - return; - } - - pi->hwpwrctrl = hwpwrctrl; - pi->nphy_txpwrctrl = hwpwrctrl; - pi->txpwrctrl = hwpwrctrl; - - if (ISNPHY(pi)) { - suspend = - (0 == - (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); - if (!suspend) - wlapi_suspend_mac_and_wait(pi->sh->physhim); - - wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl); - if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) { - wlc_phy_txpwr_fixpower_nphy(pi); - } else { - - mod_phy_reg(pi, 0x1e7, (0x7f << 0), - pi->saved_txpwr_idx); - } - - if (!suspend) - wlapi_enable_mac(pi->sh->physhim); - } else if (hwpwrctrl != cur_hwpwrctrl) { - - return; - } -} - -void wlc_phy_txpower_ipa_upd(phy_info_t *pi) -{ - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - pi->ipa2g_on = (pi->srom_fem2g.extpagain == 2); - pi->ipa5g_on = (pi->srom_fem5g.extpagain == 2); - } else { - pi->ipa2g_on = false; - pi->ipa5g_on = false; - } -} - -static u32 wlc_phy_txpower_est_power_nphy(phy_info_t *pi); - -static u32 wlc_phy_txpower_est_power_nphy(phy_info_t *pi) -{ - s16 tx0_status, tx1_status; - u16 estPower1, estPower2; - u8 pwr0, pwr1, adj_pwr0, adj_pwr1; - u32 est_pwr; - - estPower1 = read_phy_reg(pi, 0x118); - estPower2 = read_phy_reg(pi, 0x119); - - if ((estPower1 & (0x1 << 8)) - == (0x1 << 8)) { - pwr0 = (u8) (estPower1 & (0xff << 0)) - >> 0; - } else { - pwr0 = 0x80; - } - - if ((estPower2 & (0x1 << 8)) - == (0x1 << 8)) { - pwr1 = (u8) (estPower2 & (0xff << 0)) - >> 0; - } else { - pwr1 = 0x80; - } - - tx0_status = read_phy_reg(pi, 0x1ed); - tx1_status = read_phy_reg(pi, 0x1ee); - - if ((tx0_status & (0x1 << 15)) - == (0x1 << 15)) { - adj_pwr0 = (u8) (tx0_status & (0xff << 0)) - >> 0; - } else { - adj_pwr0 = 0x80; - } - if ((tx1_status & (0x1 << 15)) - == (0x1 << 15)) { - adj_pwr1 = (u8) (tx1_status & (0xff << 0)) - >> 0; - } else { - adj_pwr1 = 0x80; - } - - est_pwr = - (u32) ((pwr0 << 24) | (pwr1 << 16) | (adj_pwr0 << 8) | adj_pwr1); - return est_pwr; -} - -void -wlc_phy_txpower_get_current(wlc_phy_t *ppi, tx_power_t *power, uint channel) -{ - phy_info_t *pi = (phy_info_t *) ppi; - uint rate, num_rates; - u8 min_pwr, max_pwr; - -#if WL_TX_POWER_RATES != TXP_NUM_RATES -#error "tx_power_t struct out of sync with this fn" -#endif - - if (ISNPHY(pi)) { - power->rf_cores = 2; - power->flags |= (WL_TX_POWER_F_MIMO); - if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON) - power->flags |= - (WL_TX_POWER_F_ENABLED | WL_TX_POWER_F_HW); - } else if (ISLCNPHY(pi)) { - power->rf_cores = 1; - power->flags |= (WL_TX_POWER_F_SISO); - if (pi->radiopwr_override == RADIOPWR_OVERRIDE_DEF) - power->flags |= WL_TX_POWER_F_ENABLED; - if (pi->hwpwrctrl) - power->flags |= WL_TX_POWER_F_HW; - } - - num_rates = ((ISNPHY(pi)) ? (TXP_NUM_RATES) : - ((ISLCNPHY(pi)) ? - (TXP_LAST_OFDM_20_CDD + 1) : (TXP_LAST_OFDM + 1))); - - for (rate = 0; rate < num_rates; rate++) { - power->user_limit[rate] = pi->tx_user_target[rate]; - wlc_phy_txpower_sromlimit(ppi, channel, &min_pwr, &max_pwr, - rate); - power->board_limit[rate] = (u8) max_pwr; - power->target[rate] = pi->tx_power_target[rate]; - } - - if (ISNPHY(pi)) { - u32 est_pout; - - wlapi_suspend_mac_and_wait(pi->sh->physhim); - wlc_phyreg_enter((wlc_phy_t *) pi); - est_pout = wlc_phy_txpower_est_power_nphy(pi); - wlc_phyreg_exit((wlc_phy_t *) pi); - wlapi_enable_mac(pi->sh->physhim); - - power->est_Pout[0] = (est_pout >> 8) & 0xff; - power->est_Pout[1] = est_pout & 0xff; - - power->est_Pout_act[0] = est_pout >> 24; - power->est_Pout_act[1] = (est_pout >> 16) & 0xff; - - if (power->est_Pout[0] == 0x80) - power->est_Pout[0] = 0; - if (power->est_Pout[1] == 0x80) - power->est_Pout[1] = 0; - - if (power->est_Pout_act[0] == 0x80) - power->est_Pout_act[0] = 0; - if (power->est_Pout_act[1] == 0x80) - power->est_Pout_act[1] = 0; - - power->est_Pout_cck = 0; - - power->tx_power_max[0] = pi->tx_power_max; - power->tx_power_max[1] = pi->tx_power_max; - - power->tx_power_max_rate_ind[0] = pi->tx_power_max_rate_ind; - power->tx_power_max_rate_ind[1] = pi->tx_power_max_rate_ind; - } else if (!pi->hwpwrctrl) { - } else if (pi->sh->up) { - - wlc_phyreg_enter(ppi); - if (ISLCNPHY(pi)) { - - power->tx_power_max[0] = pi->tx_power_max; - power->tx_power_max[1] = pi->tx_power_max; - - power->tx_power_max_rate_ind[0] = - pi->tx_power_max_rate_ind; - power->tx_power_max_rate_ind[1] = - pi->tx_power_max_rate_ind; - - if (wlc_phy_tpc_isenabled_lcnphy(pi)) - power->flags |= - (WL_TX_POWER_F_HW | WL_TX_POWER_F_ENABLED); - else - power->flags &= - ~(WL_TX_POWER_F_HW | WL_TX_POWER_F_ENABLED); - - wlc_lcnphy_get_tssi(pi, (s8 *) &power->est_Pout[0], - (s8 *) &power->est_Pout_cck); - } - wlc_phyreg_exit(ppi); - } -} - -void wlc_phy_antsel_type_set(wlc_phy_t *ppi, u8 antsel_type) -{ - phy_info_t *pi = (phy_info_t *) ppi; - - pi->antsel_type = antsel_type; -} - -bool wlc_phy_test_ison(wlc_phy_t *ppi) -{ - phy_info_t *pi = (phy_info_t *) ppi; - - return pi->phytest_on; -} - -bool wlc_phy_ant_rxdiv_get(wlc_phy_t *ppi, u8 *pval) -{ - phy_info_t *pi = (phy_info_t *) ppi; - bool ret = true; - - wlc_phyreg_enter(ppi); - - if (ISNPHY(pi)) { - - ret = false; - } else if (ISLCNPHY(pi)) { - u16 crsctrl = read_phy_reg(pi, 0x410); - u16 div = crsctrl & (0x1 << 1); - *pval = (div | ((crsctrl & (0x1 << 0)) ^ (div >> 1))); - } - - wlc_phyreg_exit(ppi); - - return ret; -} - -void wlc_phy_ant_rxdiv_set(wlc_phy_t *ppi, u8 val) -{ - phy_info_t *pi = (phy_info_t *) ppi; - bool suspend; - - pi->sh->rx_antdiv = val; - - if (!(ISNPHY(pi) && D11REV_IS(pi->sh->corerev, 16))) { - if (val > ANT_RX_DIV_FORCE_1) - wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV, - MHF1_ANTDIV, WLC_BAND_ALL); - else - wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV, 0, - WLC_BAND_ALL); - } - - if (ISNPHY(pi)) { - - return; - } - - if (!pi->sh->clk) - return; - - suspend = - (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); - if (!suspend) - wlapi_suspend_mac_and_wait(pi->sh->physhim); - - if (ISLCNPHY(pi)) { - if (val > ANT_RX_DIV_FORCE_1) { - mod_phy_reg(pi, 0x410, (0x1 << 1), 0x01 << 1); - mod_phy_reg(pi, 0x410, - (0x1 << 0), - ((ANT_RX_DIV_START_1 == val) ? 1 : 0) << 0); - } else { - mod_phy_reg(pi, 0x410, (0x1 << 1), 0x00 << 1); - mod_phy_reg(pi, 0x410, (0x1 << 0), (u16) val << 0); - } - } else { - ASSERT(0); - } - - if (!suspend) - wlapi_enable_mac(pi->sh->physhim); - - return; -} - -static bool -wlc_phy_noise_calc_phy(phy_info_t *pi, u32 *cmplx_pwr, s8 *pwr_ant) -{ - s8 cmplx_pwr_dbm[PHY_CORE_MAX]; - u8 i; - - memset((u8 *) cmplx_pwr_dbm, 0, sizeof(cmplx_pwr_dbm)); - ASSERT(pi->pubpi.phy_corenum <= PHY_CORE_MAX); - wlc_phy_compute_dB(cmplx_pwr, cmplx_pwr_dbm, pi->pubpi.phy_corenum); - - for (i = 0; i < pi->pubpi.phy_corenum; i++) { - if (NREV_GE(pi->pubpi.phy_rev, 3)) - cmplx_pwr_dbm[i] += (s8) PHY_NOISE_OFFSETFACT_4322; - else - - cmplx_pwr_dbm[i] += (s8) (16 - (15) * 3 - 70); - } - - for (i = 0; i < pi->pubpi.phy_corenum; i++) { - pi->nphy_noise_win[i][pi->nphy_noise_index] = cmplx_pwr_dbm[i]; - pwr_ant[i] = cmplx_pwr_dbm[i]; - } - pi->nphy_noise_index = - MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ); - return true; -} - -static void -wlc_phy_noise_sample_request(wlc_phy_t *pih, u8 reason, u8 ch) -{ - phy_info_t *pi = (phy_info_t *) pih; - s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; - bool sampling_in_progress = (pi->phynoise_state != 0); - bool wait_for_intr = true; - - if (NORADIO_ENAB(pi->pubpi)) { - return; - } - - switch (reason) { - case PHY_NOISE_SAMPLE_MON: - - pi->phynoise_chan_watchdog = ch; - pi->phynoise_state |= PHY_NOISE_STATE_MON; - - break; - - case PHY_NOISE_SAMPLE_EXTERNAL: - - pi->phynoise_state |= PHY_NOISE_STATE_EXTERNAL; - break; - - default: - ASSERT(0); - break; - } - - if (sampling_in_progress) - return; - - pi->phynoise_now = pi->sh->now; - - if (pi->phy_fixed_noise) { - if (ISNPHY(pi)) { - pi->nphy_noise_win[WL_ANT_IDX_1][pi->nphy_noise_index] = - PHY_NOISE_FIXED_VAL_NPHY; - pi->nphy_noise_win[WL_ANT_IDX_2][pi->nphy_noise_index] = - PHY_NOISE_FIXED_VAL_NPHY; - pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index, - PHY_NOISE_WINDOW_SZ); - - noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; - } else { - - noise_dbm = PHY_NOISE_FIXED_VAL; - } - - wait_for_intr = false; - goto done; - } - - if (ISLCNPHY(pi)) { - if (!pi->phynoise_polling - || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) { - wlapi_bmac_write_shm(pi->sh->physhim, M_JSSI_0, 0); - wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0); - wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0); - wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0); - wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0); - - OR_REG(pi->sh->osh, &pi->regs->maccommand, - MCMD_BG_NOISE); - } else { - wlapi_suspend_mac_and_wait(pi->sh->physhim); - wlc_lcnphy_deaf_mode(pi, (bool) 0); - noise_dbm = (s8) wlc_lcnphy_rx_signal_power(pi, 20); - wlc_lcnphy_deaf_mode(pi, (bool) 1); - wlapi_enable_mac(pi->sh->physhim); - wait_for_intr = false; - } - } else if (ISNPHY(pi)) { - if (!pi->phynoise_polling - || (reason == PHY_NOISE_SAMPLE_EXTERNAL)) { - - wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP0, 0); - wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP1, 0); - wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0); - wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0); - - OR_REG(pi->sh->osh, &pi->regs->maccommand, - MCMD_BG_NOISE); - } else { - phy_iq_est_t est[PHY_CORE_MAX]; - u32 cmplx_pwr[PHY_CORE_MAX]; - s8 noise_dbm_ant[PHY_CORE_MAX]; - u16 log_num_samps, num_samps, classif_state = 0; - u8 wait_time = 32; - u8 wait_crs = 0; - u8 i; - - memset((u8 *) est, 0, sizeof(est)); - memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr)); - memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant)); - - log_num_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY; - num_samps = 1 << log_num_samps; - - wlapi_suspend_mac_and_wait(pi->sh->physhim); - classif_state = wlc_phy_classifier_nphy(pi, 0, 0); - wlc_phy_classifier_nphy(pi, 3, 0); - wlc_phy_rx_iq_est_nphy(pi, est, num_samps, wait_time, - wait_crs); - wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state); - wlapi_enable_mac(pi->sh->physhim); - - for (i = 0; i < pi->pubpi.phy_corenum; i++) - cmplx_pwr[i] = - (est[i].i_pwr + - est[i].q_pwr) >> log_num_samps; - - wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant); - - for (i = 0; i < pi->pubpi.phy_corenum; i++) { - pi->nphy_noise_win[i][pi->nphy_noise_index] = - noise_dbm_ant[i]; - - if (noise_dbm_ant[i] > noise_dbm) - noise_dbm = noise_dbm_ant[i]; - } - pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index, - PHY_NOISE_WINDOW_SZ); - - wait_for_intr = false; - } - } - - done: - - if (!wait_for_intr) - wlc_phy_noise_cb(pi, ch, noise_dbm); - -} - -void wlc_phy_noise_sample_request_external(wlc_phy_t *pih) -{ - u8 channel; - - channel = CHSPEC_CHANNEL(wlc_phy_chanspec_get(pih)); - - wlc_phy_noise_sample_request(pih, PHY_NOISE_SAMPLE_EXTERNAL, channel); -} - -static void wlc_phy_noise_cb(phy_info_t *pi, u8 channel, s8 noise_dbm) -{ - if (!pi->phynoise_state) - return; - - if (pi->phynoise_state & PHY_NOISE_STATE_MON) { - if (pi->phynoise_chan_watchdog == channel) { - pi->sh->phy_noise_window[pi->sh->phy_noise_index] = - noise_dbm; - pi->sh->phy_noise_index = - MODINC(pi->sh->phy_noise_index, MA_WINDOW_SZ); - } - pi->phynoise_state &= ~PHY_NOISE_STATE_MON; - } - - if (pi->phynoise_state & PHY_NOISE_STATE_EXTERNAL) { - pi->phynoise_state &= ~PHY_NOISE_STATE_EXTERNAL; - } - -} - -static s8 wlc_phy_noise_read_shmem(phy_info_t *pi) -{ - u32 cmplx_pwr[PHY_CORE_MAX]; - s8 noise_dbm_ant[PHY_CORE_MAX]; - u16 lo, hi; - u32 cmplx_pwr_tot = 0; - s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; - u8 idx, core; - - ASSERT(pi->pubpi.phy_corenum <= PHY_CORE_MAX); - memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr)); - memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant)); - - for (idx = 0, core = 0; core < pi->pubpi.phy_corenum; idx += 2, core++) { - lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP(idx)); - hi = wlapi_bmac_read_shm(pi->sh->physhim, - M_PWRIND_MAP(idx + 1)); - cmplx_pwr[core] = (hi << 16) + lo; - cmplx_pwr_tot += cmplx_pwr[core]; - if (cmplx_pwr[core] == 0) { - noise_dbm_ant[core] = PHY_NOISE_FIXED_VAL_NPHY; - } else - cmplx_pwr[core] >>= PHY_NOISE_SAMPLE_LOG_NUM_UCODE; - } - - if (cmplx_pwr_tot != 0) - wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant); - - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - pi->nphy_noise_win[core][pi->nphy_noise_index] = - noise_dbm_ant[core]; - - if (noise_dbm_ant[core] > noise_dbm) - noise_dbm = noise_dbm_ant[core]; - } - pi->nphy_noise_index = - MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ); - - return noise_dbm; - -} - -void wlc_phy_noise_sample_intr(wlc_phy_t *pih) -{ - phy_info_t *pi = (phy_info_t *) pih; - u16 jssi_aux; - u8 channel = 0; - s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; - - if (ISLCNPHY(pi)) { - u32 cmplx_pwr, cmplx_pwr0, cmplx_pwr1; - u16 lo, hi; - s32 pwr_offset_dB, gain_dB; - u16 status_0, status_1; - - jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX); - channel = jssi_aux & D11_CURCHANNEL_MAX; - - lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP0); - hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP1); - cmplx_pwr0 = (hi << 16) + lo; - - lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP2); - hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP3); - cmplx_pwr1 = (hi << 16) + lo; - cmplx_pwr = (cmplx_pwr0 + cmplx_pwr1) >> 6; - - status_0 = 0x44; - status_1 = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_0); - if ((cmplx_pwr > 0 && cmplx_pwr < 500) - && ((status_1 & 0xc000) == 0x4000)) { - - wlc_phy_compute_dB(&cmplx_pwr, &noise_dbm, - pi->pubpi.phy_corenum); - pwr_offset_dB = (read_phy_reg(pi, 0x434) & 0xFF); - if (pwr_offset_dB > 127) - pwr_offset_dB -= 256; - - noise_dbm += (s8) (pwr_offset_dB - 30); - - gain_dB = (status_0 & 0x1ff); - noise_dbm -= (s8) (gain_dB); - } else { - noise_dbm = PHY_NOISE_FIXED_VAL_LCNPHY; - } - } else if (ISNPHY(pi)) { - - jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX); - channel = jssi_aux & D11_CURCHANNEL_MAX; - - noise_dbm = wlc_phy_noise_read_shmem(pi); - } else { - ASSERT(0); - } - - wlc_phy_noise_cb(pi, channel, noise_dbm); - -} - -s8 lcnphy_gain_index_offset_for_pkt_rssi[] = { - 8, - 8, - 8, - 8, - 8, - 8, - 8, - 9, - 10, - 8, - 8, - 7, - 7, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 1, - 1, - 0, - 0, - 0, - 0 -}; - -void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_cmplx_pwr_dB, u8 core) -{ - u8 shift_ct, lsb, msb, secondmsb, i; - u32 tmp; - - for (i = 0; i < core; i++) { - tmp = cmplx_pwr[i]; - shift_ct = msb = secondmsb = 0; - while (tmp != 0) { - tmp = tmp >> 1; - shift_ct++; - lsb = (u8) (tmp & 1); - if (lsb == 1) - msb = shift_ct; - } - secondmsb = (u8) ((cmplx_pwr[i] >> (msb - 1)) & 1); - p_cmplx_pwr_dB[i] = (s8) (3 * msb + 2 * secondmsb); - } -} - -void BCMFASTPATH wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx) -{ - wlc_d11rxhdr_t *wlc_rxhdr = (wlc_d11rxhdr_t *) ctx; - d11rxhdr_t *rxh = &wlc_rxhdr->rxhdr; - int rssi = ltoh16(rxh->PhyRxStatus_1) & PRXS1_JSSI_MASK; - uint radioid = pih->radioid; - phy_info_t *pi = (phy_info_t *) pih; - - if (NORADIO_ENAB(pi->pubpi)) { - rssi = WLC_RSSI_INVALID; - goto end; - } - - if ((pi->sh->corerev >= 11) - && !(ltoh16(rxh->RxStatus2) & RXS_PHYRXST_VALID)) { - rssi = WLC_RSSI_INVALID; - goto end; - } - - if (ISLCNPHY(pi)) { - u8 gidx = (ltoh16(rxh->PhyRxStatus_2) & 0xFC00) >> 10; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - if (rssi > 127) - rssi -= 256; - - rssi = rssi + lcnphy_gain_index_offset_for_pkt_rssi[gidx]; - if ((rssi > -46) && (gidx > 18)) - rssi = rssi + 7; - - rssi = rssi + pi_lcn->lcnphy_pkteng_rssi_slope; - - rssi = rssi + 2; - - } - - if (ISLCNPHY(pi)) { - - if (rssi > 127) - rssi -= 256; - } else if (radioid == BCM2055_ID || radioid == BCM2056_ID - || radioid == BCM2057_ID) { - ASSERT(ISNPHY(pi)); - rssi = wlc_phy_rssi_compute_nphy(pi, wlc_rxhdr); - } else { - ASSERT((const char *)"Unknown radio" == NULL); - } - - end: - wlc_rxhdr->rssi = (s8) rssi; -} - -void wlc_phy_freqtrack_start(wlc_phy_t *pih) -{ - return; -} - -void wlc_phy_freqtrack_end(wlc_phy_t *pih) -{ - return; -} - -void wlc_phy_set_deaf(wlc_phy_t *ppi, bool user_flag) -{ - phy_info_t *pi; - pi = (phy_info_t *) ppi; - - if (ISLCNPHY(pi)) - wlc_lcnphy_deaf_mode(pi, true); - else if (ISNPHY(pi)) - wlc_nphy_deaf_mode(pi, true); - else { - ASSERT(0); - } -} - -void wlc_phy_watchdog(wlc_phy_t *pih) -{ - phy_info_t *pi = (phy_info_t *) pih; - bool delay_phy_cal = false; - pi->sh->now++; - - if (!pi->watchdog_override) - return; - - if (!(SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi))) { - wlc_phy_noise_sample_request((wlc_phy_t *) pi, - PHY_NOISE_SAMPLE_MON, - CHSPEC_CHANNEL(pi-> - radio_chanspec)); - } - - if (pi->phynoise_state && (pi->sh->now - pi->phynoise_now) > 5) { - pi->phynoise_state = 0; - } - - if ((!pi->phycal_txpower) || - ((pi->sh->now - pi->phycal_txpower) >= pi->sh->fast_timer)) { - - if (!SCAN_INPROG_PHY(pi) && wlc_phy_cal_txpower_recalc_sw(pi)) { - pi->phycal_txpower = pi->sh->now; - } - } - - if (NORADIO_ENAB(pi->pubpi)) - return; - - if ((SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi) - || ASSOC_INPROG_PHY(pi))) - return; - - if (ISNPHY(pi) && !pi->disable_percal && !delay_phy_cal) { - - if ((pi->nphy_perical != PHY_PERICAL_DISABLE) && - (pi->nphy_perical != PHY_PERICAL_MANUAL) && - ((pi->sh->now - pi->nphy_perical_last) >= - pi->sh->glacial_timer)) - wlc_phy_cal_perical((wlc_phy_t *) pi, - PHY_PERICAL_WATCHDOG); - - wlc_phy_txpwr_papd_cal_nphy(pi); - } - - if (ISLCNPHY(pi)) { - if (pi->phy_forcecal || - ((pi->sh->now - pi->phy_lastcal) >= - pi->sh->glacial_timer)) { - if (!(SCAN_RM_IN_PROGRESS(pi) || ASSOC_INPROG_PHY(pi))) - wlc_lcnphy_calib_modes(pi, - LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL); - if (! - (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi) - || ASSOC_INPROG_PHY(pi) - || pi->carrier_suppr_disable - || pi->disable_percal)) - wlc_lcnphy_calib_modes(pi, - PHY_PERICAL_WATCHDOG); - } - } -} - -void wlc_phy_BSSinit(wlc_phy_t *pih, bool bonlyap, int rssi) -{ - phy_info_t *pi = (phy_info_t *) pih; - uint i; - uint k; - - for (i = 0; i < MA_WINDOW_SZ; i++) { - pi->sh->phy_noise_window[i] = (s8) (rssi & 0xff); - } - if (ISLCNPHY(pi)) { - for (i = 0; i < MA_WINDOW_SZ; i++) - pi->sh->phy_noise_window[i] = - PHY_NOISE_FIXED_VAL_LCNPHY; - } - pi->sh->phy_noise_index = 0; - - for (i = 0; i < PHY_NOISE_WINDOW_SZ; i++) { - for (k = WL_ANT_IDX_1; k < WL_ANT_RX_MAX; k++) - pi->nphy_noise_win[k][i] = PHY_NOISE_FIXED_VAL_NPHY; - } - pi->nphy_noise_index = 0; -} - -void -wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, s32 *eps_imag) -{ - *eps_imag = (epsilon >> 13); - if (*eps_imag > 0xfff) - *eps_imag -= 0x2000; - - *eps_real = (epsilon & 0x1fff); - if (*eps_real > 0xfff) - *eps_real -= 0x2000; -} - -static const fixed AtanTbl[] = { - 2949120, - 1740967, - 919879, - 466945, - 234379, - 117304, - 58666, - 29335, - 14668, - 7334, - 3667, - 1833, - 917, - 458, - 229, - 115, - 57, - 29 -}; - -void wlc_phy_cordic(fixed theta, cs32 *val) -{ - fixed angle, valtmp; - unsigned iter; - int signx = 1; - int signtheta; - - val[0].i = CORDIC_AG; - val[0].q = 0; - angle = 0; - - signtheta = (theta < 0) ? -1 : 1; - theta = - ((theta + FIXED(180) * signtheta) % FIXED(360)) - - FIXED(180) * signtheta; - - if (FLOAT(theta) > 90) { - theta -= FIXED(180); - signx = -1; - } else if (FLOAT(theta) < -90) { - theta += FIXED(180); - signx = -1; - } - - for (iter = 0; iter < CORDIC_NI; iter++) { - if (theta > angle) { - valtmp = val[0].i - (val[0].q >> iter); - val[0].q = (val[0].i >> iter) + val[0].q; - val[0].i = valtmp; - angle += AtanTbl[iter]; - } else { - valtmp = val[0].i + (val[0].q >> iter); - val[0].q = -(val[0].i >> iter) + val[0].q; - val[0].i = valtmp; - angle -= AtanTbl[iter]; - } - } - - val[0].i = val[0].i * signx; - val[0].q = val[0].q * signx; -} - -void wlc_phy_cal_perical_mphase_reset(phy_info_t *pi) -{ - wlapi_del_timer(pi->sh->physhim, pi->phycal_timer); - - pi->cal_type_override = PHY_PERICAL_AUTO; - pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE; - pi->mphase_txcal_cmdidx = 0; -} - -static void wlc_phy_cal_perical_mphase_schedule(phy_info_t *pi, uint delay) -{ - - if ((pi->nphy_perical != PHY_PERICAL_MPHASE) && - (pi->nphy_perical != PHY_PERICAL_MANUAL)) - return; - - wlapi_del_timer(pi->sh->physhim, pi->phycal_timer); - - pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT; - wlapi_add_timer(pi->sh->physhim, pi->phycal_timer, delay, 0); -} - -void wlc_phy_cal_perical(wlc_phy_t *pih, u8 reason) -{ - s16 nphy_currtemp = 0; - s16 delta_temp = 0; - bool do_periodic_cal = true; - phy_info_t *pi = (phy_info_t *) pih; - - if (!ISNPHY(pi)) - return; - - if ((pi->nphy_perical == PHY_PERICAL_DISABLE) || - (pi->nphy_perical == PHY_PERICAL_MANUAL)) - return; - - switch (reason) { - case PHY_PERICAL_DRIVERUP: - break; - - case PHY_PERICAL_PHYINIT: - if (pi->nphy_perical == PHY_PERICAL_MPHASE) { - if (PHY_PERICAL_MPHASE_PENDING(pi)) { - wlc_phy_cal_perical_mphase_reset(pi); - } - wlc_phy_cal_perical_mphase_schedule(pi, - PHY_PERICAL_INIT_DELAY); - } - break; - - case PHY_PERICAL_JOIN_BSS: - case PHY_PERICAL_START_IBSS: - case PHY_PERICAL_UP_BSS: - if ((pi->nphy_perical == PHY_PERICAL_MPHASE) && - PHY_PERICAL_MPHASE_PENDING(pi)) { - wlc_phy_cal_perical_mphase_reset(pi); - } - - pi->first_cal_after_assoc = true; - - pi->cal_type_override = PHY_PERICAL_FULL; - - if (pi->phycal_tempdelta) { - pi->nphy_lastcal_temp = wlc_phy_tempsense_nphy(pi); - } - wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_FULL); - break; - - case PHY_PERICAL_WATCHDOG: - if (pi->phycal_tempdelta) { - nphy_currtemp = wlc_phy_tempsense_nphy(pi); - delta_temp = - (nphy_currtemp > pi->nphy_lastcal_temp) ? - nphy_currtemp - pi->nphy_lastcal_temp : - pi->nphy_lastcal_temp - nphy_currtemp; - - if ((delta_temp < (s16) pi->phycal_tempdelta) && - (pi->nphy_txiqlocal_chanspec == - pi->radio_chanspec)) { - do_periodic_cal = false; - } else { - pi->nphy_lastcal_temp = nphy_currtemp; - } - } - - if (do_periodic_cal) { - - if (pi->nphy_perical == PHY_PERICAL_MPHASE) { - - if (!PHY_PERICAL_MPHASE_PENDING(pi)) - wlc_phy_cal_perical_mphase_schedule(pi, - PHY_PERICAL_WDOG_DELAY); - } else if (pi->nphy_perical == PHY_PERICAL_SPHASE) - wlc_phy_cal_perical_nphy_run(pi, - PHY_PERICAL_AUTO); - else { - ASSERT(0); - } - } - break; - default: - ASSERT(0); - break; - } -} - -void wlc_phy_cal_perical_mphase_restart(phy_info_t *pi) -{ - pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT; - pi->mphase_txcal_cmdidx = 0; -} - -u8 wlc_phy_nbits(s32 value) -{ - s32 abs_val; - u8 nbits = 0; - - abs_val = ABS(value); - while ((abs_val >> nbits) > 0) - nbits++; - - return nbits; -} - -u32 wlc_phy_sqrt_int(u32 value) -{ - u32 root = 0, shift = 0; - - for (shift = 0; shift < 32; shift += 2) { - if (((0x40000000 >> shift) + root) <= value) { - value -= ((0x40000000 >> shift) + root); - root = (root >> 1) | (0x40000000 >> shift); - } else { - root = root >> 1; - } - } - - if (root < value) - ++root; - - return root; -} - -void wlc_phy_stf_chain_init(wlc_phy_t *pih, u8 txchain, u8 rxchain) -{ - phy_info_t *pi = (phy_info_t *) pih; - - pi->sh->hw_phytxchain = txchain; - pi->sh->hw_phyrxchain = rxchain; - pi->sh->phytxchain = txchain; - pi->sh->phyrxchain = rxchain; - pi->pubpi.phy_corenum = (u8) PHY_BITSCNT(pi->sh->phyrxchain); -} - -void wlc_phy_stf_chain_set(wlc_phy_t *pih, u8 txchain, u8 rxchain) -{ - phy_info_t *pi = (phy_info_t *) pih; - - pi->sh->phytxchain = txchain; - - if (ISNPHY(pi)) { - wlc_phy_rxcore_setstate_nphy(pih, rxchain); - } - pi->pubpi.phy_corenum = (u8) PHY_BITSCNT(pi->sh->phyrxchain); -} - -void wlc_phy_stf_chain_get(wlc_phy_t *pih, u8 *txchain, u8 *rxchain) -{ - phy_info_t *pi = (phy_info_t *) pih; - - *txchain = pi->sh->phytxchain; - *rxchain = pi->sh->phyrxchain; -} - -u8 wlc_phy_stf_chain_active_get(wlc_phy_t *pih) -{ - s16 nphy_currtemp; - u8 active_bitmap; - phy_info_t *pi = (phy_info_t *) pih; - - active_bitmap = (pi->phy_txcore_heatedup) ? 0x31 : 0x33; - - if (!pi->watchdog_override) - return active_bitmap; - - if (NREV_GE(pi->pubpi.phy_rev, 6)) { - wlapi_suspend_mac_and_wait(pi->sh->physhim); - nphy_currtemp = wlc_phy_tempsense_nphy(pi); - wlapi_enable_mac(pi->sh->physhim); - - if (!pi->phy_txcore_heatedup) { - if (nphy_currtemp >= pi->phy_txcore_disable_temp) { - active_bitmap &= 0xFD; - pi->phy_txcore_heatedup = true; - } - } else { - if (nphy_currtemp <= pi->phy_txcore_enable_temp) { - active_bitmap |= 0x2; - pi->phy_txcore_heatedup = false; - } - } - } - - return active_bitmap; -} - -s8 wlc_phy_stf_ssmode_get(wlc_phy_t *pih, chanspec_t chanspec) -{ - phy_info_t *pi = (phy_info_t *) pih; - u8 siso_mcs_id, cdd_mcs_id; - - siso_mcs_id = - (CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_SISO : - TXP_FIRST_MCS_20_SISO; - cdd_mcs_id = - (CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_CDD : - TXP_FIRST_MCS_20_CDD; - - if (pi->tx_power_target[siso_mcs_id] > - (pi->tx_power_target[cdd_mcs_id] + 12)) - return PHY_TXC1_MODE_SISO; - else - return PHY_TXC1_MODE_CDD; -} - -const u8 *wlc_phy_get_ofdm_rate_lookup(void) -{ - return ofdm_rate_lookup; -} - -void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode) -{ - if ((pi->sh->chip == BCM4313_CHIP_ID) && - (pi->sh->boardflags & BFL_FEM)) { - if (mode) { - u16 txant = 0; - txant = wlapi_bmac_get_txant(pi->sh->physhim); - if (txant == 1) { - mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2); - - mod_phy_reg(pi, 0x44c, (0x1 << 2), (1) << 2); - - } - si_corereg(pi->sh->sih, SI_CC_IDX, - offsetof(chipcregs_t, gpiocontrol), ~0x0, - 0x0); - si_corereg(pi->sh->sih, SI_CC_IDX, - offsetof(chipcregs_t, gpioout), 0x40, 0x40); - si_corereg(pi->sh->sih, SI_CC_IDX, - offsetof(chipcregs_t, gpioouten), 0x40, - 0x40); - } else { - mod_phy_reg(pi, 0x44c, (0x1 << 2), (0) << 2); - - mod_phy_reg(pi, 0x44d, (0x1 << 2), (0) << 2); - - si_corereg(pi->sh->sih, SI_CC_IDX, - offsetof(chipcregs_t, gpioout), 0x40, 0x00); - si_corereg(pi->sh->sih, SI_CC_IDX, - offsetof(chipcregs_t, gpioouten), 0x40, 0x0); - si_corereg(pi->sh->sih, SI_CC_IDX, - offsetof(chipcregs_t, gpiocontrol), ~0x0, - 0x40); - } - } -} - -static s8 -wlc_user_txpwr_antport_to_rfport(phy_info_t *pi, uint chan, u32 band, - u8 rate) -{ - s8 offset = 0; - - if (!pi->user_txpwr_at_rfport) - return offset; - return offset; -} - -static s8 wlc_phy_env_measure_vbat(phy_info_t *pi) -{ - if (ISLCNPHY(pi)) - return wlc_lcnphy_vbatsense(pi, 0); - else - return 0; -} - -static s8 wlc_phy_env_measure_temperature(phy_info_t *pi) -{ - if (ISLCNPHY(pi)) - return wlc_lcnphy_tempsense_degree(pi, 0); - else - return 0; -} - -static void wlc_phy_upd_env_txpwr_rate_limits(phy_info_t *pi, u32 band) -{ - u8 i; - s8 temp, vbat; - - for (i = 0; i < TXP_NUM_RATES; i++) - pi->txpwr_env_limit[i] = WLC_TXPWR_MAX; - - vbat = wlc_phy_env_measure_vbat(pi); - temp = wlc_phy_env_measure_temperature(pi); - -} - -void wlc_phy_ldpc_override_set(wlc_phy_t *ppi, bool ldpc) -{ - return; -} - -void -wlc_phy_get_pwrdet_offsets(phy_info_t *pi, s8 *cckoffset, s8 *ofdmoffset) -{ - *cckoffset = 0; - *ofdmoffset = 0; -} - -u32 wlc_phy_qdiv_roundup(u32 dividend, u32 divisor, u8 precision) -{ - u32 quotient, remainder, roundup, rbit; - - ASSERT(divisor); - - quotient = dividend / divisor; - remainder = dividend % divisor; - rbit = divisor & 1; - roundup = (divisor >> 1) + rbit; - - while (precision--) { - quotient <<= 1; - if (remainder >= roundup) { - quotient++; - remainder = ((remainder - roundup) << 1) + rbit; - } else { - remainder <<= 1; - } - } - - if (remainder >= roundup) - quotient++; - - return quotient; -} - -s8 wlc_phy_upd_rssi_offset(phy_info_t *pi, s8 rssi, chanspec_t chanspec) -{ - - return rssi; -} - -bool wlc_phy_txpower_ipa_ison(wlc_phy_t *ppi) -{ - phy_info_t *pi = (phy_info_t *) ppi; - - if (ISNPHY(pi)) - return wlc_phy_n_txpower_ipa_ison(pi); - else - return 0; -} diff --git a/drivers/staging/brcm80211/phy/wlc_phy_hal.h b/drivers/staging/brcm80211/phy/wlc_phy_hal.h deleted file mode 100644 index 514e15e00283..000000000000 --- a/drivers/staging/brcm80211/phy/wlc_phy_hal.h +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_phy_h_ -#define _wlc_phy_h_ - -#include -#include -#include -#include - -#define IDCODE_VER_MASK 0x0000000f -#define IDCODE_VER_SHIFT 0 -#define IDCODE_MFG_MASK 0x00000fff -#define IDCODE_MFG_SHIFT 0 -#define IDCODE_ID_MASK 0x0ffff000 -#define IDCODE_ID_SHIFT 12 -#define IDCODE_REV_MASK 0xf0000000 -#define IDCODE_REV_SHIFT 28 - -#define NORADIO_ID 0xe4f5 -#define NORADIO_IDCODE 0x4e4f5246 - -#define BCM2055_ID 0x2055 -#define BCM2055_IDCODE 0x02055000 -#define BCM2055A0_IDCODE 0x1205517f - -#define BCM2056_ID 0x2056 -#define BCM2056_IDCODE 0x02056000 -#define BCM2056A0_IDCODE 0x1205617f - -#define BCM2057_ID 0x2057 -#define BCM2057_IDCODE 0x02057000 -#define BCM2057A0_IDCODE 0x1205717f - -#define BCM2064_ID 0x2064 -#define BCM2064_IDCODE 0x02064000 -#define BCM2064A0_IDCODE 0x0206417f - -#define PHY_TPC_HW_OFF false -#define PHY_TPC_HW_ON true - -#define PHY_PERICAL_DRIVERUP 1 -#define PHY_PERICAL_WATCHDOG 2 -#define PHY_PERICAL_PHYINIT 3 -#define PHY_PERICAL_JOIN_BSS 4 -#define PHY_PERICAL_START_IBSS 5 -#define PHY_PERICAL_UP_BSS 6 -#define PHY_PERICAL_CHAN 7 -#define PHY_FULLCAL 8 - -#define PHY_PERICAL_DISABLE 0 -#define PHY_PERICAL_SPHASE 1 -#define PHY_PERICAL_MPHASE 2 -#define PHY_PERICAL_MANUAL 3 - -#define PHY_HOLD_FOR_ASSOC 1 -#define PHY_HOLD_FOR_SCAN 2 -#define PHY_HOLD_FOR_RM 4 -#define PHY_HOLD_FOR_PLT 8 -#define PHY_HOLD_FOR_MUTE 16 -#define PHY_HOLD_FOR_NOT_ASSOC 0x20 - -#define PHY_MUTE_FOR_PREISM 1 -#define PHY_MUTE_ALL 0xffffffff - -#define PHY_NOISE_FIXED_VAL (-95) -#define PHY_NOISE_FIXED_VAL_NPHY (-92) -#define PHY_NOISE_FIXED_VAL_LCNPHY (-92) - -#define PHY_MODE_CAL 0x0002 -#define PHY_MODE_NOISEM 0x0004 - -#define WLC_TXPWR_DB_FACTOR 4 - -#define WLC_NUM_RATES_CCK 4 -#define WLC_NUM_RATES_OFDM 8 -#define WLC_NUM_RATES_MCS_1_STREAM 8 -#define WLC_NUM_RATES_MCS_2_STREAM 8 -#define WLC_NUM_RATES_MCS_3_STREAM 8 -#define WLC_NUM_RATES_MCS_4_STREAM 8 -typedef struct txpwr_limits { - u8 cck[WLC_NUM_RATES_CCK]; - u8 ofdm[WLC_NUM_RATES_OFDM]; - - u8 ofdm_cdd[WLC_NUM_RATES_OFDM]; - - u8 ofdm_40_siso[WLC_NUM_RATES_OFDM]; - u8 ofdm_40_cdd[WLC_NUM_RATES_OFDM]; - - u8 mcs_20_siso[WLC_NUM_RATES_MCS_1_STREAM]; - u8 mcs_20_cdd[WLC_NUM_RATES_MCS_1_STREAM]; - u8 mcs_20_stbc[WLC_NUM_RATES_MCS_1_STREAM]; - u8 mcs_20_mimo[WLC_NUM_RATES_MCS_2_STREAM]; - - u8 mcs_40_siso[WLC_NUM_RATES_MCS_1_STREAM]; - u8 mcs_40_cdd[WLC_NUM_RATES_MCS_1_STREAM]; - u8 mcs_40_stbc[WLC_NUM_RATES_MCS_1_STREAM]; - u8 mcs_40_mimo[WLC_NUM_RATES_MCS_2_STREAM]; - u8 mcs32; -} txpwr_limits_t; - -typedef struct { - u8 vec[MAXCHANNEL / NBBY]; -} chanvec_t; - -struct rpc_info; -typedef struct shared_phy shared_phy_t; - -struct phy_pub; - -typedef struct phy_pub wlc_phy_t; - -typedef struct shared_phy_params { - void *osh; - si_t *sih; - void *physhim; - uint unit; - uint corerev; - uint bustype; - uint buscorerev; - char *vars; - u16 vid; - u16 did; - uint chip; - uint chiprev; - uint chippkg; - uint sromrev; - uint boardtype; - uint boardrev; - uint boardvendor; - u32 boardflags; - u32 boardflags2; -} shared_phy_params_t; - - -extern shared_phy_t *wlc_phy_shared_attach(shared_phy_params_t *shp); -extern void wlc_phy_shared_detach(shared_phy_t *phy_sh); -extern wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, - char *vars); -extern void wlc_phy_detach(wlc_phy_t *ppi); - -extern bool wlc_phy_get_phyversion(wlc_phy_t *pih, u16 *phytype, - u16 *phyrev, u16 *radioid, - u16 *radiover); -extern bool wlc_phy_get_encore(wlc_phy_t *pih); -extern u32 wlc_phy_get_coreflags(wlc_phy_t *pih); - -extern void wlc_phy_hw_clk_state_upd(wlc_phy_t *ppi, bool newstate); -extern void wlc_phy_hw_state_upd(wlc_phy_t *ppi, bool newstate); -extern void wlc_phy_init(wlc_phy_t *ppi, chanspec_t chanspec); -extern void wlc_phy_watchdog(wlc_phy_t *ppi); -extern int wlc_phy_down(wlc_phy_t *ppi); -extern u32 wlc_phy_clk_bwbits(wlc_phy_t *pih); -extern void wlc_phy_cal_init(wlc_phy_t *ppi); -extern void wlc_phy_antsel_init(wlc_phy_t *ppi, bool lut_init); - -extern void wlc_phy_chanspec_set(wlc_phy_t *ppi, chanspec_t chanspec); -extern chanspec_t wlc_phy_chanspec_get(wlc_phy_t *ppi); -extern void wlc_phy_chanspec_radio_set(wlc_phy_t *ppi, chanspec_t newch); -extern u16 wlc_phy_bw_state_get(wlc_phy_t *ppi); -extern void wlc_phy_bw_state_set(wlc_phy_t *ppi, u16 bw); - -extern void wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx); -extern void wlc_phy_por_inform(wlc_phy_t *ppi); -extern void wlc_phy_noise_sample_intr(wlc_phy_t *ppi); -extern bool wlc_phy_bist_check_phy(wlc_phy_t *ppi); - -extern void wlc_phy_set_deaf(wlc_phy_t *ppi, bool user_flag); - -extern void wlc_phy_switch_radio(wlc_phy_t *ppi, bool on); -extern void wlc_phy_anacore(wlc_phy_t *ppi, bool on); - - -extern void wlc_phy_BSSinit(wlc_phy_t *ppi, bool bonlyap, int rssi); - -extern void wlc_phy_chanspec_ch14_widefilter_set(wlc_phy_t *ppi, - bool wide_filter); -extern void wlc_phy_chanspec_band_validch(wlc_phy_t *ppi, uint band, - chanvec_t *channels); -extern chanspec_t wlc_phy_chanspec_band_firstch(wlc_phy_t *ppi, uint band); - -extern void wlc_phy_txpower_sromlimit(wlc_phy_t *ppi, uint chan, - u8 *_min_, u8 *_max_, int rate); -extern void wlc_phy_txpower_sromlimit_max_get(wlc_phy_t *ppi, uint chan, - u8 *_max_, u8 *_min_); -extern void wlc_phy_txpower_boardlimit_band(wlc_phy_t *ppi, uint band, s32 *, - s32 *, u32 *); -extern void wlc_phy_txpower_limit_set(wlc_phy_t *ppi, struct txpwr_limits *, - chanspec_t chanspec); -extern int wlc_phy_txpower_get(wlc_phy_t *ppi, uint *qdbm, bool *override); -extern int wlc_phy_txpower_set(wlc_phy_t *ppi, uint qdbm, bool override); -extern void wlc_phy_txpower_target_set(wlc_phy_t *ppi, struct txpwr_limits *); -extern bool wlc_phy_txpower_hw_ctrl_get(wlc_phy_t *ppi); -extern void wlc_phy_txpower_hw_ctrl_set(wlc_phy_t *ppi, bool hwpwrctrl); -extern u8 wlc_phy_txpower_get_target_min(wlc_phy_t *ppi); -extern u8 wlc_phy_txpower_get_target_max(wlc_phy_t *ppi); -extern bool wlc_phy_txpower_ipa_ison(wlc_phy_t *pih); - -extern void wlc_phy_stf_chain_init(wlc_phy_t *pih, u8 txchain, - u8 rxchain); -extern void wlc_phy_stf_chain_set(wlc_phy_t *pih, u8 txchain, - u8 rxchain); -extern void wlc_phy_stf_chain_get(wlc_phy_t *pih, u8 *txchain, - u8 *rxchain); -extern u8 wlc_phy_stf_chain_active_get(wlc_phy_t *pih); -extern s8 wlc_phy_stf_ssmode_get(wlc_phy_t *pih, chanspec_t chanspec); -extern void wlc_phy_ldpc_override_set(wlc_phy_t *ppi, bool val); - -extern void wlc_phy_cal_perical(wlc_phy_t *ppi, u8 reason); -extern void wlc_phy_noise_sample_request_external(wlc_phy_t *ppi); -extern void wlc_phy_edcrs_lock(wlc_phy_t *pih, bool lock); -extern void wlc_phy_cal_papd_recal(wlc_phy_t *ppi); - -extern void wlc_phy_ant_rxdiv_set(wlc_phy_t *ppi, u8 val); -extern bool wlc_phy_ant_rxdiv_get(wlc_phy_t *ppi, u8 *pval); -extern void wlc_phy_clear_tssi(wlc_phy_t *ppi); -extern void wlc_phy_hold_upd(wlc_phy_t *ppi, mbool id, bool val); -extern void wlc_phy_mute_upd(wlc_phy_t *ppi, bool val, mbool flags); - -extern void wlc_phy_antsel_type_set(wlc_phy_t *ppi, u8 antsel_type); - -extern void wlc_phy_txpower_get_current(wlc_phy_t *ppi, tx_power_t *power, - uint channel); - -extern void wlc_phy_initcal_enable(wlc_phy_t *pih, bool initcal); -extern bool wlc_phy_test_ison(wlc_phy_t *ppi); -extern void wlc_phy_txpwr_percent_set(wlc_phy_t *ppi, u8 txpwr_percent); -extern void wlc_phy_ofdm_rateset_war(wlc_phy_t *pih, bool war); -extern void wlc_phy_bf_preempt_enable(wlc_phy_t *pih, bool bf_preempt); -extern void wlc_phy_machwcap_set(wlc_phy_t *ppi, u32 machwcap); - -extern void wlc_phy_runbist_config(wlc_phy_t *ppi, bool start_end); - -extern void wlc_phy_freqtrack_start(wlc_phy_t *ppi); -extern void wlc_phy_freqtrack_end(wlc_phy_t *ppi); - -extern const u8 *wlc_phy_get_ofdm_rate_lookup(void); - -extern s8 wlc_phy_get_tx_power_offset_by_mcs(wlc_phy_t *ppi, - u8 mcs_offset); -extern s8 wlc_phy_get_tx_power_offset(wlc_phy_t *ppi, u8 tbl_offset); -#endif /* _wlc_phy_h_ */ diff --git a/drivers/staging/brcm80211/phy/wlc_phy_int.h b/drivers/staging/brcm80211/phy/wlc_phy_int.h deleted file mode 100644 index 72eee9120c2f..000000000000 --- a/drivers/staging/brcm80211/phy/wlc_phy_int.h +++ /dev/null @@ -1,1229 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_phy_int_h_ -#define _wlc_phy_int_h_ - -#include -#include -#include - -#include -#include - -#define PHYHAL_ERROR 0x0001 -#define PHYHAL_TRACE 0x0002 -#define PHYHAL_INFORM 0x0004 - -extern u32 phyhal_msg_level; - -#define PHY_INFORM_ON() (phyhal_msg_level & PHYHAL_INFORM) -#define PHY_THERMAL_ON() (phyhal_msg_level & PHYHAL_THERMAL) -#define PHY_CAL_ON() (phyhal_msg_level & PHYHAL_CAL) - -#ifdef BOARD_TYPE -#define BOARDTYPE(_type) BOARD_TYPE -#else -#define BOARDTYPE(_type) _type -#endif - -#define LCNXN_BASEREV 16 - -struct wlc_hw_info; -typedef struct phy_info phy_info_t; -typedef void (*initfn_t) (phy_info_t *); -typedef void (*chansetfn_t) (phy_info_t *, chanspec_t); -typedef int (*longtrnfn_t) (phy_info_t *, int); -typedef void (*txiqccgetfn_t) (phy_info_t *, u16 *, u16 *); -typedef void (*txiqccsetfn_t) (phy_info_t *, u16, u16); -typedef u16(*txloccgetfn_t) (phy_info_t *); -typedef void (*radioloftgetfn_t) (phy_info_t *, u8 *, u8 *, u8 *, - u8 *); -typedef s32(*rxsigpwrfn_t) (phy_info_t *, s32); -typedef void (*detachfn_t) (phy_info_t *); - -#undef ISNPHY -#undef ISLCNPHY -#define ISNPHY(pi) PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_N) -#define ISLCNPHY(pi) PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_LCN) - -#define ISPHY_11N_CAP(pi) (ISNPHY(pi) || ISLCNPHY(pi)) - -#define IS20MHZ(pi) ((pi)->bw == WL_CHANSPEC_BW_20) -#define IS40MHZ(pi) ((pi)->bw == WL_CHANSPEC_BW_40) - -#define PHY_GET_RFATTN(rfgain) ((rfgain) & 0x0f) -#define PHY_GET_PADMIX(rfgain) (((rfgain) & 0x10) >> 4) -#define PHY_GET_RFGAINID(rfattn, padmix, width) ((rfattn) + ((padmix)*(width))) -#define PHY_SAT(x, n) ((x) > ((1<<((n)-1))-1) ? ((1<<((n)-1))-1) : \ - ((x) < -(1<<((n)-1)) ? -(1<<((n)-1)) : (x))) -#define PHY_SHIFT_ROUND(x, n) ((x) >= 0 ? ((x)+(1<<((n)-1)))>>(n) : (x)>>(n)) -#define PHY_HW_ROUND(x, s) ((x >> s) + ((x >> (s-1)) & (s != 0))) - -#define CH_5G_GROUP 3 -#define A_LOW_CHANS 0 -#define A_MID_CHANS 1 -#define A_HIGH_CHANS 2 -#define CH_2G_GROUP 1 -#define G_ALL_CHANS 0 - -#define FIRST_REF5_CHANNUM 149 -#define LAST_REF5_CHANNUM 165 -#define FIRST_5G_CHAN 14 -#define LAST_5G_CHAN 50 -#define FIRST_MID_5G_CHAN 14 -#define LAST_MID_5G_CHAN 35 -#define FIRST_HIGH_5G_CHAN 36 -#define LAST_HIGH_5G_CHAN 41 -#define FIRST_LOW_5G_CHAN 42 -#define LAST_LOW_5G_CHAN 50 - -#define BASE_LOW_5G_CHAN 4900 -#define BASE_MID_5G_CHAN 5100 -#define BASE_HIGH_5G_CHAN 5500 - -#define CHAN5G_FREQ(chan) (5000 + chan*5) -#define CHAN2G_FREQ(chan) (2407 + chan*5) - -#define TXP_FIRST_CCK 0 -#define TXP_LAST_CCK 3 -#define TXP_FIRST_OFDM 4 -#define TXP_LAST_OFDM 11 -#define TXP_FIRST_OFDM_20_CDD 12 -#define TXP_LAST_OFDM_20_CDD 19 -#define TXP_FIRST_MCS_20_SISO 20 -#define TXP_LAST_MCS_20_SISO 27 -#define TXP_FIRST_MCS_20_CDD 28 -#define TXP_LAST_MCS_20_CDD 35 -#define TXP_FIRST_MCS_20_STBC 36 -#define TXP_LAST_MCS_20_STBC 43 -#define TXP_FIRST_MCS_20_SDM 44 -#define TXP_LAST_MCS_20_SDM 51 -#define TXP_FIRST_OFDM_40_SISO 52 -#define TXP_LAST_OFDM_40_SISO 59 -#define TXP_FIRST_OFDM_40_CDD 60 -#define TXP_LAST_OFDM_40_CDD 67 -#define TXP_FIRST_MCS_40_SISO 68 -#define TXP_LAST_MCS_40_SISO 75 -#define TXP_FIRST_MCS_40_CDD 76 -#define TXP_LAST_MCS_40_CDD 83 -#define TXP_FIRST_MCS_40_STBC 84 -#define TXP_LAST_MCS_40_STBC 91 -#define TXP_FIRST_MCS_40_SDM 92 -#define TXP_LAST_MCS_40_SDM 99 -#define TXP_MCS_32 100 -#define TXP_NUM_RATES 101 -#define ADJ_PWR_TBL_LEN 84 - -#define TXP_FIRST_SISO_MCS_20 20 -#define TXP_LAST_SISO_MCS_20 27 - -#define PHY_CORE_NUM_1 1 -#define PHY_CORE_NUM_2 2 -#define PHY_CORE_NUM_3 3 -#define PHY_CORE_NUM_4 4 -#define PHY_CORE_MAX PHY_CORE_NUM_4 -#define PHY_CORE_0 0 -#define PHY_CORE_1 1 -#define PHY_CORE_2 2 -#define PHY_CORE_3 3 - -#define MA_WINDOW_SZ 8 - -#define PHY_NOISE_SAMPLE_MON 1 -#define PHY_NOISE_SAMPLE_EXTERNAL 2 -#define PHY_NOISE_WINDOW_SZ 16 -#define PHY_NOISE_GLITCH_INIT_MA 10 -#define PHY_NOISE_GLITCH_INIT_MA_BADPlCP 10 -#define PHY_NOISE_STATE_MON 0x1 -#define PHY_NOISE_STATE_EXTERNAL 0x2 -#define PHY_NOISE_SAMPLE_LOG_NUM_NPHY 10 -#define PHY_NOISE_SAMPLE_LOG_NUM_UCODE 9 - -#define PHY_NOISE_OFFSETFACT_4322 (-103) -#define PHY_NOISE_MA_WINDOW_SZ 2 - -#define PHY_RSSI_TABLE_SIZE 64 -#define RSSI_ANT_MERGE_MAX 0 -#define RSSI_ANT_MERGE_MIN 1 -#define RSSI_ANT_MERGE_AVG 2 - -#define PHY_TSSI_TABLE_SIZE 64 -#define APHY_TSSI_TABLE_SIZE 256 -#define TX_GAIN_TABLE_LENGTH 64 -#define DEFAULT_11A_TXP_IDX 24 -#define NUM_TSSI_FRAMES 4 -#define NULL_TSSI 0x7f -#define NULL_TSSI_W 0x7f7f - -#define PHY_PAPD_EPS_TBL_SIZE_LCNPHY 64 - -#define LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL 9 - -#define PHY_TXPWR_MIN 10 -#define PHY_TXPWR_MIN_NPHY 8 -#define RADIOPWR_OVERRIDE_DEF (-1) - -#define PWRTBL_NUM_COEFF 3 - -#define SPURAVOID_DISABLE 0 -#define SPURAVOID_AUTO 1 -#define SPURAVOID_FORCEON 2 -#define SPURAVOID_FORCEON2 3 - -#define PHY_SW_TIMER_FAST 15 -#define PHY_SW_TIMER_SLOW 60 -#define PHY_SW_TIMER_GLACIAL 120 - -#define PHY_PERICAL_AUTO 0 -#define PHY_PERICAL_FULL 1 -#define PHY_PERICAL_PARTIAL 2 - -#define PHY_PERICAL_NODELAY 0 -#define PHY_PERICAL_INIT_DELAY 5 -#define PHY_PERICAL_ASSOC_DELAY 5 -#define PHY_PERICAL_WDOG_DELAY 5 - -#define MPHASE_TXCAL_NUMCMDS 2 -#define PHY_PERICAL_MPHASE_PENDING(pi) (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_IDLE) - -enum { - MPHASE_CAL_STATE_IDLE = 0, - MPHASE_CAL_STATE_INIT = 1, - MPHASE_CAL_STATE_TXPHASE0, - MPHASE_CAL_STATE_TXPHASE1, - MPHASE_CAL_STATE_TXPHASE2, - MPHASE_CAL_STATE_TXPHASE3, - MPHASE_CAL_STATE_TXPHASE4, - MPHASE_CAL_STATE_TXPHASE5, - MPHASE_CAL_STATE_PAPDCAL, - MPHASE_CAL_STATE_RXCAL, - MPHASE_CAL_STATE_RSSICAL, - MPHASE_CAL_STATE_IDLETSSI -}; - -typedef enum { - CAL_FULL, - CAL_RECAL, - CAL_CURRECAL, - CAL_DIGCAL, - CAL_GCTRL, - CAL_SOFT, - CAL_DIGLO -} phy_cal_mode_t; - -#define RDR_NTIERS 1 -#define RDR_TIER_SIZE 64 -#define RDR_LIST_SIZE (512/3) -#define RDR_EPOCH_SIZE 40 -#define RDR_NANTENNAS 2 -#define RDR_NTIER_SIZE RDR_LIST_SIZE -#define RDR_LP_BUFFER_SIZE 64 -#define LP_LEN_HIS_SIZE 10 - -#define STATIC_NUM_RF 32 -#define STATIC_NUM_BB 9 - -#define BB_MULT_MASK 0x0000ffff -#define BB_MULT_VALID_MASK 0x80000000 - -#define CORDIC_AG 39797 -#define CORDIC_NI 18 -#define FIXED(X) ((s32)((X) << 16)) -#define FLOAT(X) (((X) >= 0) ? ((((X) >> 15) + 1) >> 1) : -((((-(X)) >> 15) + 1) >> 1)) - -#define PHY_CHAIN_TX_DISABLE_TEMP 115 -#define PHY_HYSTERESIS_DELTATEMP 5 - -#define PHY_BITSCNT(x) bcm_bitcount((u8 *)&(x), sizeof(u8)) - -#define MOD_PHY_REG(pi, phy_type, reg_name, field, value) \ - mod_phy_reg(pi, phy_type##_##reg_name, phy_type##_##reg_name##_##field##_MASK, \ - (value) << phy_type##_##reg_name##_##field##_##SHIFT); -#define READ_PHY_REG(pi, phy_type, reg_name, field) \ - ((read_phy_reg(pi, phy_type##_##reg_name) & phy_type##_##reg_name##_##field##_##MASK)\ - >> phy_type##_##reg_name##_##field##_##SHIFT) - -#define VALID_PHYTYPE(phytype) (((uint)phytype == PHY_TYPE_N) || \ - ((uint)phytype == PHY_TYPE_LCN)) - -#define VALID_N_RADIO(radioid) ((radioid == BCM2055_ID) || (radioid == BCM2056_ID) || \ - (radioid == BCM2057_ID)) -#define VALID_LCN_RADIO(radioid) (radioid == BCM2064_ID) - -#define VALID_RADIO(pi, radioid) (\ - (ISNPHY(pi) ? VALID_N_RADIO(radioid) : false) || \ - (ISLCNPHY(pi) ? VALID_LCN_RADIO(radioid) : false)) - -#define SCAN_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN)) -#define RM_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_RM)) -#define PLT_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_PLT)) -#define ASSOC_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_ASSOC)) -#define SCAN_RM_IN_PROGRESS(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN | PHY_HOLD_FOR_RM)) -#define PHY_MUTED(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_MUTE)) -#define PUB_NOT_ASSOC(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_NOT_ASSOC)) - -#if defined(EXT_CBALL) -#define NORADIO_ENAB(pub) ((pub).radioid == NORADIO_ID) -#else -#define NORADIO_ENAB(pub) 0 -#endif - -#define PHY_LTRN_LIST_LEN 64 -extern u16 ltrn_list[PHY_LTRN_LIST_LEN]; - -typedef struct _phy_table_info { - uint table; - int q; - uint max; -} phy_table_info_t; - -typedef struct phytbl_info { - const void *tbl_ptr; - u32 tbl_len; - u32 tbl_id; - u32 tbl_offset; - u32 tbl_width; -} phytbl_info_t; - -typedef struct { - u8 curr_home_channel; - u16 crsminpwrthld_40_stored; - u16 crsminpwrthld_20L_stored; - u16 crsminpwrthld_20U_stored; - u16 init_gain_code_core1_stored; - u16 init_gain_code_core2_stored; - u16 init_gain_codeb_core1_stored; - u16 init_gain_codeb_core2_stored; - u16 init_gain_table_stored[4]; - - u16 clip1_hi_gain_code_core1_stored; - u16 clip1_hi_gain_code_core2_stored; - u16 clip1_hi_gain_codeb_core1_stored; - u16 clip1_hi_gain_codeb_core2_stored; - u16 nb_clip_thresh_core1_stored; - u16 nb_clip_thresh_core2_stored; - u16 init_ofdmlna2gainchange_stored[4]; - u16 init_ccklna2gainchange_stored[4]; - u16 clip1_lo_gain_code_core1_stored; - u16 clip1_lo_gain_code_core2_stored; - u16 clip1_lo_gain_codeb_core1_stored; - u16 clip1_lo_gain_codeb_core2_stored; - u16 w1_clip_thresh_core1_stored; - u16 w1_clip_thresh_core2_stored; - u16 radio_2056_core1_rssi_gain_stored; - u16 radio_2056_core2_rssi_gain_stored; - u16 energy_drop_timeout_len_stored; - - u16 ed_crs40_assertthld0_stored; - u16 ed_crs40_assertthld1_stored; - u16 ed_crs40_deassertthld0_stored; - u16 ed_crs40_deassertthld1_stored; - u16 ed_crs20L_assertthld0_stored; - u16 ed_crs20L_assertthld1_stored; - u16 ed_crs20L_deassertthld0_stored; - u16 ed_crs20L_deassertthld1_stored; - u16 ed_crs20U_assertthld0_stored; - u16 ed_crs20U_assertthld1_stored; - u16 ed_crs20U_deassertthld0_stored; - u16 ed_crs20U_deassertthld1_stored; - - u16 badplcp_ma; - u16 badplcp_ma_previous; - u16 badplcp_ma_total; - u16 badplcp_ma_list[MA_WINDOW_SZ]; - int badplcp_ma_index; - s16 pre_badplcp_cnt; - s16 bphy_pre_badplcp_cnt; - - u16 init_gain_core1; - u16 init_gain_core2; - u16 init_gainb_core1; - u16 init_gainb_core2; - u16 init_gain_rfseq[4]; - - u16 crsminpwr0; - u16 crsminpwrl0; - u16 crsminpwru0; - - s16 crsminpwr_index; - - u16 radio_2057_core1_rssi_wb1a_gc_stored; - u16 radio_2057_core2_rssi_wb1a_gc_stored; - u16 radio_2057_core1_rssi_wb1g_gc_stored; - u16 radio_2057_core2_rssi_wb1g_gc_stored; - u16 radio_2057_core1_rssi_wb2_gc_stored; - u16 radio_2057_core2_rssi_wb2_gc_stored; - u16 radio_2057_core1_rssi_nb_gc_stored; - u16 radio_2057_core2_rssi_nb_gc_stored; - -} interference_info_t; - -typedef struct { - u16 rc_cal_ovr; - u16 phycrsth1; - u16 phycrsth2; - u16 init_n1p1_gain; - u16 p1_p2_gain; - u16 n1_n2_gain; - u16 n1_p1_gain; - u16 div_search_gain; - u16 div_p1_p2_gain; - u16 div_search_gn_change; - u16 table_7_2; - u16 table_7_3; - u16 cckshbits_gnref; - u16 clip_thresh; - u16 clip2_thresh; - u16 clip3_thresh; - u16 clip_p2_thresh; - u16 clip_pwdn_thresh; - u16 clip_n1p1_thresh; - u16 clip_n1_pwdn_thresh; - u16 bbconfig; - u16 cthr_sthr_shdin; - u16 energy; - u16 clip_p1_p2_thresh; - u16 threshold; - u16 reg15; - u16 reg16; - u16 reg17; - u16 div_srch_idx; - u16 div_srch_p1_p2; - u16 div_srch_gn_back; - u16 ant_dwell; - u16 ant_wr_settle; -} aci_save_gphy_t; - -typedef struct _lo_complex_t { - s8 i; - s8 q; -} lo_complex_abgphy_info_t; - -typedef struct _nphy_iq_comp { - s16 a0; - s16 b0; - s16 a1; - s16 b1; -} nphy_iq_comp_t; - -typedef struct _nphy_txpwrindex { - s8 index; - s8 index_internal; - s8 index_internal_save; - u16 AfectrlOverride; - u16 AfeCtrlDacGain; - u16 rad_gain; - u8 bbmult; - u16 iqcomp_a; - u16 iqcomp_b; - u16 locomp; -} phy_txpwrindex_t; - -typedef struct { - - u16 txcal_coeffs_2G[8]; - u16 txcal_radio_regs_2G[8]; - nphy_iq_comp_t rxcal_coeffs_2G; - - u16 txcal_coeffs_5G[8]; - u16 txcal_radio_regs_5G[8]; - nphy_iq_comp_t rxcal_coeffs_5G; -} txiqcal_cache_t; - -typedef struct _nphy_pwrctrl { - s8 max_pwr_2g; - s8 idle_targ_2g; - s16 pwrdet_2g_a1; - s16 pwrdet_2g_b0; - s16 pwrdet_2g_b1; - s8 max_pwr_5gm; - s8 idle_targ_5gm; - s8 max_pwr_5gh; - s8 max_pwr_5gl; - s16 pwrdet_5gm_a1; - s16 pwrdet_5gm_b0; - s16 pwrdet_5gm_b1; - s16 pwrdet_5gl_a1; - s16 pwrdet_5gl_b0; - s16 pwrdet_5gl_b1; - s16 pwrdet_5gh_a1; - s16 pwrdet_5gh_b0; - s16 pwrdet_5gh_b1; - s8 idle_targ_5gl; - s8 idle_targ_5gh; - s8 idle_tssi_2g; - s8 idle_tssi_5g; - s8 idle_tssi; - s16 a1; - s16 b0; - s16 b1; -} phy_pwrctrl_t; - -typedef struct _nphy_txgains { - u16 txlpf[2]; - u16 txgm[2]; - u16 pga[2]; - u16 pad[2]; - u16 ipa[2]; -} nphy_txgains_t; - -#define PHY_NOISEVAR_BUFSIZE 10 - -typedef struct _nphy_noisevar_buf { - int bufcount; - int tone_id[PHY_NOISEVAR_BUFSIZE]; - u32 noise_vars[PHY_NOISEVAR_BUFSIZE]; - u32 min_noise_vars[PHY_NOISEVAR_BUFSIZE]; -} phy_noisevar_buf_t; - -typedef struct { - u16 rssical_radio_regs_2G[2]; - u16 rssical_phyregs_2G[12]; - - u16 rssical_radio_regs_5G[2]; - u16 rssical_phyregs_5G[12]; -} rssical_cache_t; - -typedef struct { - - u16 txiqlocal_a; - u16 txiqlocal_b; - u16 txiqlocal_didq; - u8 txiqlocal_ei0; - u8 txiqlocal_eq0; - u8 txiqlocal_fi0; - u8 txiqlocal_fq0; - - u16 txiqlocal_bestcoeffs[11]; - u16 txiqlocal_bestcoeffs_valid; - - u32 papd_eps_tbl[PHY_PAPD_EPS_TBL_SIZE_LCNPHY]; - u16 analog_gain_ref; - u16 lut_begin; - u16 lut_end; - u16 lut_step; - u16 rxcompdbm; - u16 papdctrl; - u16 sslpnCalibClkEnCtrl; - - u16 rxiqcal_coeff_a0; - u16 rxiqcal_coeff_b0; -} lcnphy_cal_results_t; - -struct shared_phy { - struct phy_info *phy_head; - uint unit; - struct osl_info *osh; - si_t *sih; - void *physhim; - uint corerev; - u32 machwcap; - bool up; - bool clk; - uint now; - u16 vid; - u16 did; - uint chip; - uint chiprev; - uint chippkg; - uint sromrev; - uint boardtype; - uint boardrev; - uint boardvendor; - u32 boardflags; - u32 boardflags2; - uint bustype; - uint buscorerev; - uint fast_timer; - uint slow_timer; - uint glacial_timer; - u8 rx_antdiv; - s8 phy_noise_window[MA_WINDOW_SZ]; - uint phy_noise_index; - u8 hw_phytxchain; - u8 hw_phyrxchain; - u8 phytxchain; - u8 phyrxchain; - u8 rssi_mode; - bool _rifs_phy; -}; - -struct phy_pub { - uint phy_type; - uint phy_rev; - u8 phy_corenum; - u16 radioid; - u8 radiorev; - u8 radiover; - - uint coreflags; - uint ana_rev; - bool abgphy_encore; -}; - -struct phy_info_nphy; -typedef struct phy_info_nphy phy_info_nphy_t; - -struct phy_info_lcnphy; -typedef struct phy_info_lcnphy phy_info_lcnphy_t; - -struct phy_func_ptr { - initfn_t init; - initfn_t calinit; - chansetfn_t chanset; - initfn_t txpwrrecalc; - longtrnfn_t longtrn; - txiqccgetfn_t txiqccget; - txiqccsetfn_t txiqccset; - txloccgetfn_t txloccget; - radioloftgetfn_t radioloftget; - initfn_t carrsuppr; - rxsigpwrfn_t rxsigpwr; - detachfn_t detach; -}; -typedef struct phy_func_ptr phy_func_ptr_t; - -struct phy_info { - wlc_phy_t pubpi_ro; - shared_phy_t *sh; - phy_func_ptr_t pi_fptr; - void *pi_ptr; - - union { - phy_info_lcnphy_t *pi_lcnphy; - } u; - bool user_txpwr_at_rfport; - - d11regs_t *regs; - struct phy_info *next; - char *vars; - wlc_phy_t pubpi; - - bool do_initcal; - bool phytest_on; - bool ofdm_rateset_war; - bool bf_preempt_4306; - chanspec_t radio_chanspec; - u8 antsel_type; - u16 bw; - u8 txpwr_percent; - bool phy_init_por; - - bool init_in_progress; - bool initialized; - bool sbtml_gm; - uint refcnt; - bool watchdog_override; - u8 phynoise_state; - uint phynoise_now; - int phynoise_chan_watchdog; - bool phynoise_polling; - bool disable_percal; - mbool measure_hold; - - s16 txpa_2g[PWRTBL_NUM_COEFF]; - s16 txpa_2g_low_temp[PWRTBL_NUM_COEFF]; - s16 txpa_2g_high_temp[PWRTBL_NUM_COEFF]; - s16 txpa_5g_low[PWRTBL_NUM_COEFF]; - s16 txpa_5g_mid[PWRTBL_NUM_COEFF]; - s16 txpa_5g_hi[PWRTBL_NUM_COEFF]; - - u8 tx_srom_max_2g; - u8 tx_srom_max_5g_low; - u8 tx_srom_max_5g_mid; - u8 tx_srom_max_5g_hi; - u8 tx_srom_max_rate_2g[TXP_NUM_RATES]; - u8 tx_srom_max_rate_5g_low[TXP_NUM_RATES]; - u8 tx_srom_max_rate_5g_mid[TXP_NUM_RATES]; - u8 tx_srom_max_rate_5g_hi[TXP_NUM_RATES]; - u8 tx_user_target[TXP_NUM_RATES]; - s8 tx_power_offset[TXP_NUM_RATES]; - u8 tx_power_target[TXP_NUM_RATES]; - - srom_fem_t srom_fem2g; - srom_fem_t srom_fem5g; - - u8 tx_power_max; - u8 tx_power_max_rate_ind; - bool hwpwrctrl; - u8 nphy_txpwrctrl; - s8 nphy_txrx_chain; - bool phy_5g_pwrgain; - - u16 phy_wreg; - u16 phy_wreg_limit; - - s8 n_preamble_override; - u8 antswitch; - u8 aa2g, aa5g; - - s8 idle_tssi[CH_5G_GROUP]; - s8 target_idle_tssi; - s8 txpwr_est_Pout; - u8 tx_power_min; - u8 txpwr_limit[TXP_NUM_RATES]; - u8 txpwr_env_limit[TXP_NUM_RATES]; - u8 adj_pwr_tbl_nphy[ADJ_PWR_TBL_LEN]; - - bool channel_14_wide_filter; - - bool txpwroverride; - bool txpwridx_override_aphy; - s16 radiopwr_override; - u16 hwpwr_txcur; - u8 saved_txpwr_idx; - - bool edcrs_threshold_lock; - - u32 tr_R_gain_val; - u32 tr_T_gain_val; - - s16 ofdm_analog_filt_bw_override; - s16 cck_analog_filt_bw_override; - s16 ofdm_rccal_override; - s16 cck_rccal_override; - u16 extlna_type; - - uint interference_mode_crs_time; - u16 crsglitch_prev; - bool interference_mode_crs; - - u32 phy_tx_tone_freq; - uint phy_lastcal; - bool phy_forcecal; - bool phy_fixed_noise; - u32 xtalfreq; - u8 pdiv; - s8 carrier_suppr_disable; - - bool phy_bphy_evm; - bool phy_bphy_rfcs; - s8 phy_scraminit; - u8 phy_gpiosel; - - s16 phy_txcore_disable_temp; - s16 phy_txcore_enable_temp; - s8 phy_tempsense_offset; - bool phy_txcore_heatedup; - - u16 radiopwr; - u16 bb_atten; - u16 txctl1; - - u16 mintxbias; - u16 mintxmag; - lo_complex_abgphy_info_t gphy_locomp_iq[STATIC_NUM_RF][STATIC_NUM_BB]; - s8 stats_11b_txpower[STATIC_NUM_RF][STATIC_NUM_BB]; - u16 gain_table[TX_GAIN_TABLE_LENGTH]; - bool loopback_gain; - s16 max_lpback_gain_hdB; - s16 trsw_rx_gain_hdB; - u8 power_vec[8]; - - u16 rc_cal; - int nrssi_table_delta; - int nrssi_slope_scale; - int nrssi_slope_offset; - int min_rssi; - int max_rssi; - - s8 txpwridx; - u8 min_txpower; - - u8 a_band_high_disable; - - u16 tx_vos; - u16 global_tx_bb_dc_bias_loft; - - int rf_max; - int bb_max; - int rf_list_size; - int bb_list_size; - u16 *rf_attn_list; - u16 *bb_attn_list; - u16 padmix_mask; - u16 padmix_reg; - u16 *txmag_list; - uint txmag_len; - bool txmag_enable; - - s8 *a_tssi_to_dbm; - s8 *m_tssi_to_dbm; - s8 *l_tssi_to_dbm; - s8 *h_tssi_to_dbm; - u8 *hwtxpwr; - - u16 freqtrack_saved_regs[2]; - int cur_interference_mode; - bool hwpwrctrl_capable; - bool temppwrctrl_capable; - - uint phycal_nslope; - uint phycal_noffset; - uint phycal_mlo; - uint phycal_txpower; - - u8 phy_aa2g; - - bool nphy_tableloaded; - s8 nphy_rssisel; - u32 nphy_bb_mult_save; - u16 nphy_txiqlocal_bestc[11]; - bool nphy_txiqlocal_coeffsvalid; - phy_txpwrindex_t nphy_txpwrindex[PHY_CORE_NUM_2]; - phy_pwrctrl_t nphy_pwrctrl_info[PHY_CORE_NUM_2]; - u16 cck2gpo; - u32 ofdm2gpo; - u32 ofdm5gpo; - u32 ofdm5glpo; - u32 ofdm5ghpo; - u8 bw402gpo; - u8 bw405gpo; - u8 bw405glpo; - u8 bw405ghpo; - u8 cdd2gpo; - u8 cdd5gpo; - u8 cdd5glpo; - u8 cdd5ghpo; - u8 stbc2gpo; - u8 stbc5gpo; - u8 stbc5glpo; - u8 stbc5ghpo; - u8 bwdup2gpo; - u8 bwdup5gpo; - u8 bwdup5glpo; - u8 bwdup5ghpo; - u16 mcs2gpo[8]; - u16 mcs5gpo[8]; - u16 mcs5glpo[8]; - u16 mcs5ghpo[8]; - u32 nphy_rxcalparams; - - u8 phy_spuravoid; - bool phy_isspuravoid; - - u8 phy_pabias; - u8 nphy_papd_skip; - u8 nphy_tssi_slope; - - s16 nphy_noise_win[PHY_CORE_MAX][PHY_NOISE_WINDOW_SZ]; - u8 nphy_noise_index; - - u8 nphy_txpid2g[PHY_CORE_NUM_2]; - u8 nphy_txpid5g[PHY_CORE_NUM_2]; - u8 nphy_txpid5gl[PHY_CORE_NUM_2]; - u8 nphy_txpid5gh[PHY_CORE_NUM_2]; - - bool nphy_gain_boost; - bool nphy_elna_gain_config; - u16 old_bphy_test; - u16 old_bphy_testcontrol; - - bool phyhang_avoid; - - bool rssical_nphy; - u8 nphy_perical; - uint nphy_perical_last; - u8 cal_type_override; - u8 mphase_cal_phase_id; - u8 mphase_txcal_cmdidx; - u8 mphase_txcal_numcmds; - u16 mphase_txcal_bestcoeffs[11]; - chanspec_t nphy_txiqlocal_chanspec; - chanspec_t nphy_iqcal_chanspec_2G; - chanspec_t nphy_iqcal_chanspec_5G; - chanspec_t nphy_rssical_chanspec_2G; - chanspec_t nphy_rssical_chanspec_5G; - struct wlapi_timer *phycal_timer; - bool use_int_tx_iqlo_cal_nphy; - bool internal_tx_iqlo_cal_tapoff_intpa_nphy; - s16 nphy_lastcal_temp; - - txiqcal_cache_t calibration_cache; - rssical_cache_t rssical_cache; - - u8 nphy_txpwr_idx[2]; - u8 nphy_papd_cal_type; - uint nphy_papd_last_cal; - u16 nphy_papd_tx_gain_at_last_cal[2]; - u8 nphy_papd_cal_gain_index[2]; - s16 nphy_papd_epsilon_offset[2]; - bool nphy_papd_recal_enable; - u32 nphy_papd_recal_counter; - bool nphy_force_papd_cal; - bool nphy_papdcomp; - bool ipa2g_on; - bool ipa5g_on; - - u16 classifier_state; - u16 clip_state[2]; - uint nphy_deaf_count; - u8 rxiq_samps; - u8 rxiq_antsel; - - u16 rfctrlIntc1_save; - u16 rfctrlIntc2_save; - bool first_cal_after_assoc; - u16 tx_rx_cal_radio_saveregs[22]; - u16 tx_rx_cal_phy_saveregs[15]; - - u8 nphy_cal_orig_pwr_idx[2]; - u8 nphy_txcal_pwr_idx[2]; - u8 nphy_rxcal_pwr_idx[2]; - u16 nphy_cal_orig_tx_gain[2]; - nphy_txgains_t nphy_cal_target_gain; - u16 nphy_txcal_bbmult; - u16 nphy_gmval; - - u16 nphy_saved_bbconf; - - bool nphy_gband_spurwar_en; - bool nphy_gband_spurwar2_en; - bool nphy_aband_spurwar_en; - u16 nphy_rccal_value; - u16 nphy_crsminpwr[3]; - phy_noisevar_buf_t nphy_saved_noisevars; - bool nphy_anarxlpf_adjusted; - bool nphy_crsminpwr_adjusted; - bool nphy_noisevars_adjusted; - - bool nphy_rxcal_active; - u16 radar_percal_mask; - bool dfs_lp_buffer_nphy; - - u16 nphy_fineclockgatecontrol; - - s8 rx2tx_biasentry; - - u16 crsminpwr0; - u16 crsminpwrl0; - u16 crsminpwru0; - s16 noise_crsminpwr_index; - u16 init_gain_core1; - u16 init_gain_core2; - u16 init_gainb_core1; - u16 init_gainb_core2; - u8 aci_noise_curr_channel; - u16 init_gain_rfseq[4]; - - bool radio_is_on; - - bool nphy_sample_play_lpf_bw_ctl_ovr; - - u16 tbl_data_hi; - u16 tbl_data_lo; - u16 tbl_addr; - - uint tbl_save_id; - uint tbl_save_offset; - - u8 txpwrctrl; - s8 txpwrindex[PHY_CORE_MAX]; - - u8 phycal_tempdelta; - u32 mcs20_po; - u32 mcs40_po; -}; - -typedef s32 fixed; - -typedef struct _cs32 { - fixed q; - fixed i; -} cs32; - -typedef struct radio_regs { - u16 address; - u32 init_a; - u32 init_g; - u8 do_init_a; - u8 do_init_g; -} radio_regs_t; - -typedef struct radio_20xx_regs { - u16 address; - u8 init; - u8 do_init; -} radio_20xx_regs_t; - -typedef struct lcnphy_radio_regs { - u16 address; - u8 init_a; - u8 init_g; - u8 do_init_a; - u8 do_init_g; -} lcnphy_radio_regs_t; - -extern lcnphy_radio_regs_t lcnphy_radio_regs_2064[]; -extern lcnphy_radio_regs_t lcnphy_radio_regs_2066[]; -extern radio_regs_t regs_2055[], regs_SYN_2056[], regs_TX_2056[], - regs_RX_2056[]; -extern radio_regs_t regs_SYN_2056_A1[], regs_TX_2056_A1[], regs_RX_2056_A1[]; -extern radio_regs_t regs_SYN_2056_rev5[], regs_TX_2056_rev5[], - regs_RX_2056_rev5[]; -extern radio_regs_t regs_SYN_2056_rev6[], regs_TX_2056_rev6[], - regs_RX_2056_rev6[]; -extern radio_regs_t regs_SYN_2056_rev7[], regs_TX_2056_rev7[], - regs_RX_2056_rev7[]; -extern radio_regs_t regs_SYN_2056_rev8[], regs_TX_2056_rev8[], - regs_RX_2056_rev8[]; -extern radio_20xx_regs_t regs_2057_rev4[], regs_2057_rev5[], regs_2057_rev5v1[]; -extern radio_20xx_regs_t regs_2057_rev7[], regs_2057_rev8[]; - -extern char *phy_getvar(phy_info_t *pi, const char *name); -extern int phy_getintvar(phy_info_t *pi, const char *name); -#define PHY_GETVAR(pi, name) phy_getvar(pi, name) -#define PHY_GETINTVAR(pi, name) phy_getintvar(pi, name) - -extern u16 read_phy_reg(phy_info_t *pi, u16 addr); -extern void write_phy_reg(phy_info_t *pi, u16 addr, u16 val); -extern void and_phy_reg(phy_info_t *pi, u16 addr, u16 val); -extern void or_phy_reg(phy_info_t *pi, u16 addr, u16 val); -extern void mod_phy_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val); - -extern u16 read_radio_reg(phy_info_t *pi, u16 addr); -extern void or_radio_reg(phy_info_t *pi, u16 addr, u16 val); -extern void and_radio_reg(phy_info_t *pi, u16 addr, u16 val); -extern void mod_radio_reg(phy_info_t *pi, u16 addr, u16 mask, - u16 val); -extern void xor_radio_reg(phy_info_t *pi, u16 addr, u16 mask); - -extern void write_radio_reg(phy_info_t *pi, u16 addr, u16 val); - -extern void wlc_phyreg_enter(wlc_phy_t *pih); -extern void wlc_phyreg_exit(wlc_phy_t *pih); -extern void wlc_radioreg_enter(wlc_phy_t *pih); -extern void wlc_radioreg_exit(wlc_phy_t *pih); - -extern void wlc_phy_read_table(phy_info_t *pi, const phytbl_info_t *ptbl_info, - u16 tblAddr, u16 tblDataHi, - u16 tblDatalo); -extern void wlc_phy_write_table(phy_info_t *pi, - const phytbl_info_t *ptbl_info, u16 tblAddr, - u16 tblDataHi, u16 tblDatalo); -extern void wlc_phy_table_addr(phy_info_t *pi, uint tbl_id, uint tbl_offset, - u16 tblAddr, u16 tblDataHi, - u16 tblDataLo); -extern void wlc_phy_table_data_write(phy_info_t *pi, uint width, u32 val); - -extern void write_phy_channel_reg(phy_info_t *pi, uint val); -extern void wlc_phy_txpower_update_shm(phy_info_t *pi); - -extern void wlc_phy_cordic(fixed theta, cs32 *val); -extern u8 wlc_phy_nbits(s32 value); -extern u32 wlc_phy_sqrt_int(u32 value); -extern void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_dB, u8 core); - -extern uint wlc_phy_init_radio_regs_allbands(phy_info_t *pi, - radio_20xx_regs_t *radioregs); -extern uint wlc_phy_init_radio_regs(phy_info_t *pi, radio_regs_t *radioregs, - u16 core_offset); - -extern void wlc_phy_txpower_ipa_upd(phy_info_t *pi); - -extern void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on); -extern void wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, - s32 *eps_imag); - -extern void wlc_phy_cal_perical_mphase_reset(phy_info_t *pi); -extern void wlc_phy_cal_perical_mphase_restart(phy_info_t *pi); - -extern bool wlc_phy_attach_nphy(phy_info_t *pi); -extern bool wlc_phy_attach_lcnphy(phy_info_t *pi); - -extern void wlc_phy_detach_lcnphy(phy_info_t *pi); - -extern void wlc_phy_init_nphy(phy_info_t *pi); -extern void wlc_phy_init_lcnphy(phy_info_t *pi); - -extern void wlc_phy_cal_init_nphy(phy_info_t *pi); -extern void wlc_phy_cal_init_lcnphy(phy_info_t *pi); - -extern void wlc_phy_chanspec_set_nphy(phy_info_t *pi, chanspec_t chanspec); -extern void wlc_phy_chanspec_set_lcnphy(phy_info_t *pi, chanspec_t chanspec); -extern void wlc_phy_chanspec_set_fixup_lcnphy(phy_info_t *pi, - chanspec_t chanspec); -extern int wlc_phy_channel2freq(uint channel); -extern int wlc_phy_chanspec_freq2bandrange_lpssn(uint); -extern int wlc_phy_chanspec_bandrange_get(phy_info_t *, chanspec_t); - -extern void wlc_lcnphy_set_tx_pwr_ctrl(phy_info_t *pi, u16 mode); -extern s8 wlc_lcnphy_get_current_tx_pwr_idx(phy_info_t *pi); - -extern void wlc_phy_txpower_recalc_target_nphy(phy_info_t *pi); -extern void wlc_lcnphy_txpower_recalc_target(phy_info_t *pi); -extern void wlc_phy_txpower_recalc_target_lcnphy(phy_info_t *pi); - -extern void wlc_lcnphy_set_tx_pwr_by_index(phy_info_t *pi, int index); -extern void wlc_lcnphy_tx_pu(phy_info_t *pi, bool bEnable); -extern void wlc_lcnphy_stop_tx_tone(phy_info_t *pi); -extern void wlc_lcnphy_start_tx_tone(phy_info_t *pi, s32 f_kHz, - u16 max_val, bool iqcalmode); - -extern void wlc_phy_txpower_sromlimit_get_nphy(phy_info_t *pi, uint chan, - u8 *max_pwr, u8 rate_id); -extern void wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start, - u8 rate_mcs_end, - u8 rate_ofdm_start); -extern void wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power, - u8 rate_ofdm_start, - u8 rate_ofdm_end, - u8 rate_mcs_start); - -extern u16 wlc_lcnphy_tempsense(phy_info_t *pi, bool mode); -extern s16 wlc_lcnphy_tempsense_new(phy_info_t *pi, bool mode); -extern s8 wlc_lcnphy_tempsense_degree(phy_info_t *pi, bool mode); -extern s8 wlc_lcnphy_vbatsense(phy_info_t *pi, bool mode); -extern void wlc_phy_carrier_suppress_lcnphy(phy_info_t *pi); -extern void wlc_lcnphy_crsuprs(phy_info_t *pi, int channel); -extern void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode); -extern void wlc_2064_vco_cal(phy_info_t *pi); - -extern void wlc_phy_txpower_recalc_target(phy_info_t *pi); -extern u32 wlc_phy_qdiv_roundup(u32 dividend, u32 divisor, - u8 precision); - -#define LCNPHY_TBL_ID_PAPDCOMPDELTATBL 0x18 -#define LCNPHY_TX_POWER_TABLE_SIZE 128 -#define LCNPHY_MAX_TX_POWER_INDEX (LCNPHY_TX_POWER_TABLE_SIZE - 1) -#define LCNPHY_TBL_ID_TXPWRCTL 0x07 -#define LCNPHY_TX_PWR_CTRL_OFF 0 -#define LCNPHY_TX_PWR_CTRL_SW (0x1 << 15) -#define LCNPHY_TX_PWR_CTRL_HW ((0x1 << 15) | \ - (0x1 << 14) | \ - (0x1 << 13)) - -#define LCNPHY_TX_PWR_CTRL_TEMPBASED 0xE001 - -extern void wlc_lcnphy_write_table(phy_info_t *pi, const phytbl_info_t *pti); -extern void wlc_lcnphy_read_table(phy_info_t *pi, phytbl_info_t *pti); -extern void wlc_lcnphy_set_tx_iqcc(phy_info_t *pi, u16 a, u16 b); -extern void wlc_lcnphy_set_tx_locc(phy_info_t *pi, u16 didq); -extern void wlc_lcnphy_get_tx_iqcc(phy_info_t *pi, u16 *a, u16 *b); -extern u16 wlc_lcnphy_get_tx_locc(phy_info_t *pi); -extern void wlc_lcnphy_get_radio_loft(phy_info_t *pi, u8 *ei0, - u8 *eq0, u8 *fi0, u8 *fq0); -extern void wlc_lcnphy_calib_modes(phy_info_t *pi, uint mode); -extern void wlc_lcnphy_deaf_mode(phy_info_t *pi, bool mode); -extern bool wlc_phy_tpc_isenabled_lcnphy(phy_info_t *pi); -extern void wlc_lcnphy_tx_pwr_update_npt(phy_info_t *pi); -extern s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1); -extern void wlc_lcnphy_get_tssi(phy_info_t *pi, s8 *ofdm_pwr, - s8 *cck_pwr); -extern void wlc_lcnphy_tx_power_adjustment(wlc_phy_t *ppi); - -extern s32 wlc_lcnphy_rx_signal_power(phy_info_t *pi, s32 gain_index); - -#define NPHY_MAX_HPVGA1_INDEX 10 -#define NPHY_DEF_HPVGA1_INDEXLIMIT 7 - -typedef struct _phy_iq_est { - s32 iq_prod; - u32 i_pwr; - u32 q_pwr; -} phy_iq_est_t; - -extern void wlc_phy_stay_in_carriersearch_nphy(phy_info_t *pi, bool enable); -extern void wlc_nphy_deaf_mode(phy_info_t *pi, bool mode); - -#define wlc_phy_write_table_nphy(pi, pti) wlc_phy_write_table(pi, pti, 0x72, \ - 0x74, 0x73) -#define wlc_phy_read_table_nphy(pi, pti) wlc_phy_read_table(pi, pti, 0x72, \ - 0x74, 0x73) -#define wlc_nphy_table_addr(pi, id, off) wlc_phy_table_addr((pi), (id), (off), \ - 0x72, 0x74, 0x73) -#define wlc_nphy_table_data_write(pi, w, v) wlc_phy_table_data_write((pi), (w), (v)) - -extern void wlc_phy_table_read_nphy(phy_info_t *pi, u32, u32 l, u32 o, - u32 w, void *d); -extern void wlc_phy_table_write_nphy(phy_info_t *pi, u32, u32, u32, - u32, const void *); - -#define PHY_IPA(pi) \ - ((pi->ipa2g_on && CHSPEC_IS2G(pi->radio_chanspec)) || \ - (pi->ipa5g_on && CHSPEC_IS5G(pi->radio_chanspec))) - -#define WLC_PHY_WAR_PR51571(pi) \ - if (((pi)->sh->bustype == PCI_BUS) && NREV_LT((pi)->pubpi.phy_rev, 3)) \ - (void)R_REG((pi)->sh->osh, &(pi)->regs->maccontrol) - -extern void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype); -extern void wlc_phy_aci_reset_nphy(phy_info_t *pi); -extern void wlc_phy_pa_override_nphy(phy_info_t *pi, bool en); - -extern u8 wlc_phy_get_chan_freq_range_nphy(phy_info_t *pi, uint chan); -extern void wlc_phy_switch_radio_nphy(phy_info_t *pi, bool on); - -extern void wlc_phy_stf_chain_upd_nphy(phy_info_t *pi); - -extern void wlc_phy_force_rfseq_nphy(phy_info_t *pi, u8 cmd); -extern s16 wlc_phy_tempsense_nphy(phy_info_t *pi); - -extern u16 wlc_phy_classifier_nphy(phy_info_t *pi, u16 mask, u16 val); - -extern void wlc_phy_rx_iq_est_nphy(phy_info_t *pi, phy_iq_est_t *est, - u16 num_samps, u8 wait_time, - u8 wait_for_crs); - -extern void wlc_phy_rx_iq_coeffs_nphy(phy_info_t *pi, u8 write, - nphy_iq_comp_t *comp); -extern void wlc_phy_aci_and_noise_reduction_nphy(phy_info_t *pi); - -extern void wlc_phy_rxcore_setstate_nphy(wlc_phy_t *pih, u8 rxcore_bitmask); -extern u8 wlc_phy_rxcore_getstate_nphy(wlc_phy_t *pih); - -extern void wlc_phy_txpwrctrl_enable_nphy(phy_info_t *pi, u8 ctrl_type); -extern void wlc_phy_txpwr_fixpower_nphy(phy_info_t *pi); -extern void wlc_phy_txpwr_apply_nphy(phy_info_t *pi); -extern void wlc_phy_txpwr_papd_cal_nphy(phy_info_t *pi); -extern u16 wlc_phy_txpwr_idx_get_nphy(phy_info_t *pi); - -extern nphy_txgains_t wlc_phy_get_tx_gain_nphy(phy_info_t *pi); -extern int wlc_phy_cal_txiqlo_nphy(phy_info_t *pi, nphy_txgains_t target_gain, - bool full, bool m); -extern int wlc_phy_cal_rxiq_nphy(phy_info_t *pi, nphy_txgains_t target_gain, - u8 type, bool d); -extern void wlc_phy_txpwr_index_nphy(phy_info_t *pi, u8 core_mask, - s8 txpwrindex, bool res); -extern void wlc_phy_rssisel_nphy(phy_info_t *pi, u8 core, u8 rssi_type); -extern int wlc_phy_poll_rssi_nphy(phy_info_t *pi, u8 rssi_type, - s32 *rssi_buf, u8 nsamps); -extern void wlc_phy_rssi_cal_nphy(phy_info_t *pi); -extern int wlc_phy_aci_scan_nphy(phy_info_t *pi); -extern void wlc_phy_cal_txgainctrl_nphy(phy_info_t *pi, s32 dBm_targetpower, - bool debug); -extern int wlc_phy_tx_tone_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val, - u8 mode, u8, bool); -extern void wlc_phy_stopplayback_nphy(phy_info_t *pi); -extern void wlc_phy_est_tonepwr_nphy(phy_info_t *pi, s32 *qdBm_pwrbuf, - u8 num_samps); -extern void wlc_phy_radio205x_vcocal_nphy(phy_info_t *pi); - -extern int wlc_phy_rssi_compute_nphy(phy_info_t *pi, wlc_d11rxhdr_t *wlc_rxh); - -#define NPHY_TESTPATTERN_BPHY_EVM 0 -#define NPHY_TESTPATTERN_BPHY_RFCS 1 - -extern void wlc_phy_nphy_tkip_rifs_war(phy_info_t *pi, u8 rifs); - -void wlc_phy_get_pwrdet_offsets(phy_info_t *pi, s8 *cckoffset, - s8 *ofdmoffset); -extern s8 wlc_phy_upd_rssi_offset(phy_info_t *pi, s8 rssi, - chanspec_t chanspec); - -extern bool wlc_phy_n_txpower_ipa_ison(phy_info_t *pih); -#endif /* _wlc_phy_int_h_ */ diff --git a/drivers/staging/brcm80211/phy/wlc_phy_lcn.c b/drivers/staging/brcm80211/phy/wlc_phy_lcn.c deleted file mode 100644 index 3ac2b49d9a9d..000000000000 --- a/drivers/staging/brcm80211/phy/wlc_phy_lcn.c +++ /dev/null @@ -1,5325 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#define PLL_2064_NDIV 90 -#define PLL_2064_LOW_END_VCO 3000 -#define PLL_2064_LOW_END_KVCO 27 -#define PLL_2064_HIGH_END_VCO 4200 -#define PLL_2064_HIGH_END_KVCO 68 -#define PLL_2064_LOOP_BW_DOUBLER 200 -#define PLL_2064_D30_DOUBLER 10500 -#define PLL_2064_LOOP_BW 260 -#define PLL_2064_D30 8000 -#define PLL_2064_CAL_REF_TO 8 -#define PLL_2064_MHZ 1000000 -#define PLL_2064_OPEN_LOOP_DELAY 5 - -#define TEMPSENSE 1 -#define VBATSENSE 2 - -#define NOISE_IF_UPD_CHK_INTERVAL 1 -#define NOISE_IF_UPD_RST_INTERVAL 60 -#define NOISE_IF_UPD_THRESHOLD_CNT 1 -#define NOISE_IF_UPD_TRHRESHOLD 50 -#define NOISE_IF_UPD_TIMEOUT 1000 -#define NOISE_IF_OFF 0 -#define NOISE_IF_CHK 1 -#define NOISE_IF_ON 2 - -#define PAPD_BLANKING_PROFILE 3 -#define PAPD2LUT 0 -#define PAPD_CORR_NORM 0 -#define PAPD_BLANKING_THRESHOLD 0 -#define PAPD_STOP_AFTER_LAST_UPDATE 0 - -#define LCN_TARGET_PWR 60 - -#define LCN_VBAT_OFFSET_433X 34649679 -#define LCN_VBAT_SLOPE_433X 8258032 - -#define LCN_VBAT_SCALE_NOM 53 -#define LCN_VBAT_SCALE_DEN 432 - -#define LCN_TEMPSENSE_OFFSET 80812 -#define LCN_TEMPSENSE_DEN 2647 - -#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT \ - (0 + 8) -#define LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK \ - (0x7f << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT) - -#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT \ - (0 + 8) -#define LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK \ - (0x7f << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT) - -#define wlc_lcnphy_enable_tx_gain_override(pi) \ - wlc_lcnphy_set_tx_gain_override(pi, true) -#define wlc_lcnphy_disable_tx_gain_override(pi) \ - wlc_lcnphy_set_tx_gain_override(pi, false) - -#define wlc_lcnphy_iqcal_active(pi) \ - (read_phy_reg((pi), 0x451) & \ - ((0x1 << 15) | (0x1 << 14))) - -#define txpwrctrl_off(pi) (0x7 != ((read_phy_reg(pi, 0x4a4) & 0xE000) >> 13)) -#define wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) \ - (pi->temppwrctrl_capable) -#define wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) \ - (pi->hwpwrctrl_capable) - -#define SWCTRL_BT_TX 0x18 -#define SWCTRL_OVR_DISABLE 0x40 - -#define AFE_CLK_INIT_MODE_TXRX2X 1 -#define AFE_CLK_INIT_MODE_PAPD 0 - -#define LCNPHY_TBL_ID_IQLOCAL 0x00 - -#define LCNPHY_TBL_ID_RFSEQ 0x08 -#define LCNPHY_TBL_ID_GAIN_IDX 0x0d -#define LCNPHY_TBL_ID_SW_CTRL 0x0f -#define LCNPHY_TBL_ID_GAIN_TBL 0x12 -#define LCNPHY_TBL_ID_SPUR 0x14 -#define LCNPHY_TBL_ID_SAMPLEPLAY 0x15 -#define LCNPHY_TBL_ID_SAMPLEPLAY1 0x16 - -#define LCNPHY_TX_PWR_CTRL_RATE_OFFSET 832 -#define LCNPHY_TX_PWR_CTRL_MAC_OFFSET 128 -#define LCNPHY_TX_PWR_CTRL_GAIN_OFFSET 192 -#define LCNPHY_TX_PWR_CTRL_IQ_OFFSET 320 -#define LCNPHY_TX_PWR_CTRL_LO_OFFSET 448 -#define LCNPHY_TX_PWR_CTRL_PWR_OFFSET 576 - -#define LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313 140 - -#define LCNPHY_TX_PWR_CTRL_START_NPT 1 -#define LCNPHY_TX_PWR_CTRL_MAX_NPT 7 - -#define LCNPHY_NOISE_SAMPLES_DEFAULT 5000 - -#define LCNPHY_ACI_DETECT_START 1 -#define LCNPHY_ACI_DETECT_PROGRESS 2 -#define LCNPHY_ACI_DETECT_STOP 3 - -#define LCNPHY_ACI_CRSHIFRMLO_TRSH 100 -#define LCNPHY_ACI_GLITCH_TRSH 2000 -#define LCNPHY_ACI_TMOUT 250 -#define LCNPHY_ACI_DETECT_TIMEOUT 2 -#define LCNPHY_ACI_START_DELAY 0 - -#define wlc_lcnphy_tx_gain_override_enabled(pi) \ - (0 != (read_phy_reg((pi), 0x43b) & (0x1 << 6))) - -#define wlc_lcnphy_total_tx_frames(pi) \ - wlapi_bmac_read_shm((pi)->sh->physhim, M_UCODE_MACSTAT + offsetof(macstat_t, txallfrm)) - -typedef struct { - u16 gm_gain; - u16 pga_gain; - u16 pad_gain; - u16 dac_gain; -} lcnphy_txgains_t; - -typedef enum { - LCNPHY_CAL_FULL, - LCNPHY_CAL_RECAL, - LCNPHY_CAL_CURRECAL, - LCNPHY_CAL_DIGCAL, - LCNPHY_CAL_GCTRL -} lcnphy_cal_mode_t; - -typedef struct { - lcnphy_txgains_t gains; - bool useindex; - u8 index; -} lcnphy_txcalgains_t; - -typedef struct { - u8 chan; - s16 a; - s16 b; -} lcnphy_rx_iqcomp_t; - -typedef struct { - s16 re; - s16 im; -} lcnphy_spb_tone_t; - -typedef struct { - u16 re; - u16 im; -} lcnphy_unsign16_struct; - -typedef struct { - u32 iq_prod; - u32 i_pwr; - u32 q_pwr; -} lcnphy_iq_est_t; - -typedef struct { - u16 ptcentreTs20; - u16 ptcentreFactor; -} lcnphy_sfo_cfg_t; - -typedef enum { - LCNPHY_PAPD_CAL_CW, - LCNPHY_PAPD_CAL_OFDM -} lcnphy_papd_cal_type_t; - -typedef u16 iqcal_gain_params_lcnphy[9]; - -static const iqcal_gain_params_lcnphy tbl_iqcal_gainparams_lcnphy_2G[] = { - {0, 0, 0, 0, 0, 0, 0, 0, 0}, -}; - -static const iqcal_gain_params_lcnphy *tbl_iqcal_gainparams_lcnphy[1] = { - tbl_iqcal_gainparams_lcnphy_2G, -}; - -static const u16 iqcal_gainparams_numgains_lcnphy[1] = { - sizeof(tbl_iqcal_gainparams_lcnphy_2G) / - sizeof(*tbl_iqcal_gainparams_lcnphy_2G), -}; - -static const lcnphy_sfo_cfg_t lcnphy_sfo_cfg[] = { - {965, 1087}, - {967, 1085}, - {969, 1082}, - {971, 1080}, - {973, 1078}, - {975, 1076}, - {977, 1073}, - {979, 1071}, - {981, 1069}, - {983, 1067}, - {985, 1065}, - {987, 1063}, - {989, 1060}, - {994, 1055} -}; - -static const -u16 lcnphy_iqcal_loft_gainladder[] = { - ((2 << 8) | 0), - ((3 << 8) | 0), - ((4 << 8) | 0), - ((6 << 8) | 0), - ((8 << 8) | 0), - ((11 << 8) | 0), - ((16 << 8) | 0), - ((16 << 8) | 1), - ((16 << 8) | 2), - ((16 << 8) | 3), - ((16 << 8) | 4), - ((16 << 8) | 5), - ((16 << 8) | 6), - ((16 << 8) | 7), - ((23 << 8) | 7), - ((32 << 8) | 7), - ((45 << 8) | 7), - ((64 << 8) | 7), - ((91 << 8) | 7), - ((128 << 8) | 7) -}; - -static const -u16 lcnphy_iqcal_ir_gainladder[] = { - ((1 << 8) | 0), - ((2 << 8) | 0), - ((4 << 8) | 0), - ((6 << 8) | 0), - ((8 << 8) | 0), - ((11 << 8) | 0), - ((16 << 8) | 0), - ((23 << 8) | 0), - ((32 << 8) | 0), - ((45 << 8) | 0), - ((64 << 8) | 0), - ((64 << 8) | 1), - ((64 << 8) | 2), - ((64 << 8) | 3), - ((64 << 8) | 4), - ((64 << 8) | 5), - ((64 << 8) | 6), - ((64 << 8) | 7), - ((91 << 8) | 7), - ((128 << 8) | 7) -}; - -static const -lcnphy_spb_tone_t lcnphy_spb_tone_3750[] = { - {88, 0}, - {73, 49}, - {34, 81}, - {-17, 86}, - {-62, 62}, - {-86, 17}, - {-81, -34}, - {-49, -73}, - {0, -88}, - {49, -73}, - {81, -34}, - {86, 17}, - {62, 62}, - {17, 86}, - {-34, 81}, - {-73, 49}, - {-88, 0}, - {-73, -49}, - {-34, -81}, - {17, -86}, - {62, -62}, - {86, -17}, - {81, 34}, - {49, 73}, - {0, 88}, - {-49, 73}, - {-81, 34}, - {-86, -17}, - {-62, -62}, - {-17, -86}, - {34, -81}, - {73, -49}, -}; - -static const -u16 iqlo_loopback_rf_regs[20] = { - RADIO_2064_REG036, - RADIO_2064_REG11A, - RADIO_2064_REG03A, - RADIO_2064_REG025, - RADIO_2064_REG028, - RADIO_2064_REG005, - RADIO_2064_REG112, - RADIO_2064_REG0FF, - RADIO_2064_REG11F, - RADIO_2064_REG00B, - RADIO_2064_REG113, - RADIO_2064_REG007, - RADIO_2064_REG0FC, - RADIO_2064_REG0FD, - RADIO_2064_REG012, - RADIO_2064_REG057, - RADIO_2064_REG059, - RADIO_2064_REG05C, - RADIO_2064_REG078, - RADIO_2064_REG092, -}; - -static const -u16 tempsense_phy_regs[14] = { - 0x503, - 0x4a4, - 0x4d0, - 0x4d9, - 0x4da, - 0x4a6, - 0x938, - 0x939, - 0x4d8, - 0x4d0, - 0x4d7, - 0x4a5, - 0x40d, - 0x4a2, -}; - -static const -u16 rxiq_cal_rf_reg[11] = { - RADIO_2064_REG098, - RADIO_2064_REG116, - RADIO_2064_REG12C, - RADIO_2064_REG06A, - RADIO_2064_REG00B, - RADIO_2064_REG01B, - RADIO_2064_REG113, - RADIO_2064_REG01D, - RADIO_2064_REG114, - RADIO_2064_REG02E, - RADIO_2064_REG12A, -}; - -static const -lcnphy_rx_iqcomp_t lcnphy_rx_iqcomp_table_rev0[] = { - {1, 0, 0}, - {2, 0, 0}, - {3, 0, 0}, - {4, 0, 0}, - {5, 0, 0}, - {6, 0, 0}, - {7, 0, 0}, - {8, 0, 0}, - {9, 0, 0}, - {10, 0, 0}, - {11, 0, 0}, - {12, 0, 0}, - {13, 0, 0}, - {14, 0, 0}, - {34, 0, 0}, - {38, 0, 0}, - {42, 0, 0}, - {46, 0, 0}, - {36, 0, 0}, - {40, 0, 0}, - {44, 0, 0}, - {48, 0, 0}, - {52, 0, 0}, - {56, 0, 0}, - {60, 0, 0}, - {64, 0, 0}, - {100, 0, 0}, - {104, 0, 0}, - {108, 0, 0}, - {112, 0, 0}, - {116, 0, 0}, - {120, 0, 0}, - {124, 0, 0}, - {128, 0, 0}, - {132, 0, 0}, - {136, 0, 0}, - {140, 0, 0}, - {149, 0, 0}, - {153, 0, 0}, - {157, 0, 0}, - {161, 0, 0}, - {165, 0, 0}, - {184, 0, 0}, - {188, 0, 0}, - {192, 0, 0}, - {196, 0, 0}, - {200, 0, 0}, - {204, 0, 0}, - {208, 0, 0}, - {212, 0, 0}, - {216, 0, 0}, -}; - -static const u32 lcnphy_23bitgaincode_table[] = { - 0x200100, - 0x200200, - 0x200004, - 0x200014, - 0x200024, - 0x200034, - 0x200134, - 0x200234, - 0x200334, - 0x200434, - 0x200037, - 0x200137, - 0x200237, - 0x200337, - 0x200437, - 0x000035, - 0x000135, - 0x000235, - 0x000037, - 0x000137, - 0x000237, - 0x000337, - 0x00013f, - 0x00023f, - 0x00033f, - 0x00034f, - 0x00044f, - 0x00144f, - 0x00244f, - 0x00254f, - 0x00354f, - 0x00454f, - 0x00464f, - 0x01464f, - 0x02464f, - 0x03464f, - 0x04464f, -}; - -static const s8 lcnphy_gain_table[] = { - -16, - -13, - 10, - 7, - 4, - 0, - 3, - 6, - 9, - 12, - 15, - 18, - 21, - 24, - 27, - 30, - 33, - 36, - 39, - 42, - 45, - 48, - 50, - 53, - 56, - 59, - 62, - 65, - 68, - 71, - 74, - 77, - 80, - 83, - 86, - 89, - 92, -}; - -static const s8 lcnphy_gain_index_offset_for_rssi[] = { - 7, - 7, - 7, - 7, - 7, - 7, - 7, - 8, - 7, - 7, - 6, - 7, - 7, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 3, - 3, - 3, - 3, - 3, - 3, - 4, - 2, - 2, - 2, - 2, - 2, - 2, - -1, - -2, - -2, - -2 -}; - -extern const u8 spur_tbl_rev0[]; -extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev1; -extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev1[]; -extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa; -extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250; - -typedef struct _chan_info_2064_lcnphy { - uint chan; - uint freq; - u8 logen_buftune; - u8 logen_rccr_tx; - u8 txrf_mix_tune_ctrl; - u8 pa_input_tune_g; - u8 logen_rccr_rx; - u8 pa_rxrf_lna1_freq_tune; - u8 pa_rxrf_lna2_freq_tune; - u8 rxrf_rxrf_spare1; -} chan_info_2064_lcnphy_t; - -static chan_info_2064_lcnphy_t chan_info_2064_lcnphy[] = { - {1, 2412, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, - {2, 2417, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, - {3, 2422, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, - {4, 2427, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, - {5, 2432, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, - {6, 2437, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, - {7, 2442, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, - {8, 2447, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, - {9, 2452, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, - {10, 2457, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, - {11, 2462, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, - {12, 2467, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, - {13, 2472, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, - {14, 2484, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, -}; - -lcnphy_radio_regs_t lcnphy_radio_regs_2064[] = { - {0x00, 0, 0, 0, 0}, - {0x01, 0x64, 0x64, 0, 0}, - {0x02, 0x20, 0x20, 0, 0}, - {0x03, 0x66, 0x66, 0, 0}, - {0x04, 0xf8, 0xf8, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0x10, 0x10, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0, 0, 0, 0}, - {0x0A, 0x37, 0x37, 0, 0}, - {0x0B, 0x6, 0x6, 0, 0}, - {0x0C, 0x55, 0x55, 0, 0}, - {0x0D, 0x8b, 0x8b, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0x5, 0x5, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0xe, 0xe, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0xb, 0xb, 0, 0}, - {0x14, 0x2, 0x2, 0, 0}, - {0x15, 0x12, 0x12, 0, 0}, - {0x16, 0x12, 0x12, 0, 0}, - {0x17, 0xc, 0xc, 0, 0}, - {0x18, 0xc, 0xc, 0, 0}, - {0x19, 0xc, 0xc, 0, 0}, - {0x1A, 0x8, 0x8, 0, 0}, - {0x1B, 0x2, 0x2, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0x1, 0x1, 0, 0}, - {0x1E, 0x12, 0x12, 0, 0}, - {0x1F, 0x6e, 0x6e, 0, 0}, - {0x20, 0x2, 0x2, 0, 0}, - {0x21, 0x23, 0x23, 0, 0}, - {0x22, 0x8, 0x8, 0, 0}, - {0x23, 0, 0, 0, 0}, - {0x24, 0, 0, 0, 0}, - {0x25, 0xc, 0xc, 0, 0}, - {0x26, 0x33, 0x33, 0, 0}, - {0x27, 0x55, 0x55, 0, 0}, - {0x28, 0, 0, 0, 0}, - {0x29, 0x30, 0x30, 0, 0}, - {0x2A, 0xb, 0xb, 0, 0}, - {0x2B, 0x1b, 0x1b, 0, 0}, - {0x2C, 0x3, 0x3, 0, 0}, - {0x2D, 0x1b, 0x1b, 0, 0}, - {0x2E, 0, 0, 0, 0}, - {0x2F, 0x20, 0x20, 0, 0}, - {0x30, 0xa, 0xa, 0, 0}, - {0x31, 0, 0, 0, 0}, - {0x32, 0x62, 0x62, 0, 0}, - {0x33, 0x19, 0x19, 0, 0}, - {0x34, 0x33, 0x33, 0, 0}, - {0x35, 0x77, 0x77, 0, 0}, - {0x36, 0, 0, 0, 0}, - {0x37, 0x70, 0x70, 0, 0}, - {0x38, 0x3, 0x3, 0, 0}, - {0x39, 0xf, 0xf, 0, 0}, - {0x3A, 0x6, 0x6, 0, 0}, - {0x3B, 0xcf, 0xcf, 0, 0}, - {0x3C, 0x1a, 0x1a, 0, 0}, - {0x3D, 0x6, 0x6, 0, 0}, - {0x3E, 0x42, 0x42, 0, 0}, - {0x3F, 0, 0, 0, 0}, - {0x40, 0xfb, 0xfb, 0, 0}, - {0x41, 0x9a, 0x9a, 0, 0}, - {0x42, 0x7a, 0x7a, 0, 0}, - {0x43, 0x29, 0x29, 0, 0}, - {0x44, 0, 0, 0, 0}, - {0x45, 0x8, 0x8, 0, 0}, - {0x46, 0xce, 0xce, 0, 0}, - {0x47, 0x27, 0x27, 0, 0}, - {0x48, 0x62, 0x62, 0, 0}, - {0x49, 0x6, 0x6, 0, 0}, - {0x4A, 0x58, 0x58, 0, 0}, - {0x4B, 0xf7, 0xf7, 0, 0}, - {0x4C, 0, 0, 0, 0}, - {0x4D, 0xb3, 0xb3, 0, 0}, - {0x4E, 0, 0, 0, 0}, - {0x4F, 0x2, 0x2, 0, 0}, - {0x50, 0, 0, 0, 0}, - {0x51, 0x9, 0x9, 0, 0}, - {0x52, 0x5, 0x5, 0, 0}, - {0x53, 0x17, 0x17, 0, 0}, - {0x54, 0x38, 0x38, 0, 0}, - {0x55, 0, 0, 0, 0}, - {0x56, 0, 0, 0, 0}, - {0x57, 0xb, 0xb, 0, 0}, - {0x58, 0, 0, 0, 0}, - {0x59, 0, 0, 0, 0}, - {0x5A, 0, 0, 0, 0}, - {0x5B, 0, 0, 0, 0}, - {0x5C, 0, 0, 0, 0}, - {0x5D, 0, 0, 0, 0}, - {0x5E, 0x88, 0x88, 0, 0}, - {0x5F, 0xcc, 0xcc, 0, 0}, - {0x60, 0x74, 0x74, 0, 0}, - {0x61, 0x74, 0x74, 0, 0}, - {0x62, 0x74, 0x74, 0, 0}, - {0x63, 0x44, 0x44, 0, 0}, - {0x64, 0x77, 0x77, 0, 0}, - {0x65, 0x44, 0x44, 0, 0}, - {0x66, 0x77, 0x77, 0, 0}, - {0x67, 0x55, 0x55, 0, 0}, - {0x68, 0x77, 0x77, 0, 0}, - {0x69, 0x77, 0x77, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0x7f, 0x7f, 0, 0}, - {0x6C, 0x8, 0x8, 0, 0}, - {0x6D, 0, 0, 0, 0}, - {0x6E, 0x88, 0x88, 0, 0}, - {0x6F, 0x66, 0x66, 0, 0}, - {0x70, 0x66, 0x66, 0, 0}, - {0x71, 0x28, 0x28, 0, 0}, - {0x72, 0x55, 0x55, 0, 0}, - {0x73, 0x4, 0x4, 0, 0}, - {0x74, 0, 0, 0, 0}, - {0x75, 0, 0, 0, 0}, - {0x76, 0, 0, 0, 0}, - {0x77, 0x1, 0x1, 0, 0}, - {0x78, 0xd6, 0xd6, 0, 0}, - {0x79, 0, 0, 0, 0}, - {0x7A, 0, 0, 0, 0}, - {0x7B, 0, 0, 0, 0}, - {0x7C, 0, 0, 0, 0}, - {0x7D, 0, 0, 0, 0}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0xb4, 0xb4, 0, 0}, - {0x84, 0x1, 0x1, 0, 0}, - {0x85, 0x20, 0x20, 0, 0}, - {0x86, 0x5, 0x5, 0, 0}, - {0x87, 0xff, 0xff, 0, 0}, - {0x88, 0x7, 0x7, 0, 0}, - {0x89, 0x77, 0x77, 0, 0}, - {0x8A, 0x77, 0x77, 0, 0}, - {0x8B, 0x77, 0x77, 0, 0}, - {0x8C, 0x77, 0x77, 0, 0}, - {0x8D, 0x8, 0x8, 0, 0}, - {0x8E, 0xa, 0xa, 0, 0}, - {0x8F, 0x8, 0x8, 0, 0}, - {0x90, 0x18, 0x18, 0, 0}, - {0x91, 0x5, 0x5, 0, 0}, - {0x92, 0x1f, 0x1f, 0, 0}, - {0x93, 0x10, 0x10, 0, 0}, - {0x94, 0x3, 0x3, 0, 0}, - {0x95, 0, 0, 0, 0}, - {0x96, 0, 0, 0, 0}, - {0x97, 0xaa, 0xaa, 0, 0}, - {0x98, 0, 0, 0, 0}, - {0x99, 0x23, 0x23, 0, 0}, - {0x9A, 0x7, 0x7, 0, 0}, - {0x9B, 0xf, 0xf, 0, 0}, - {0x9C, 0x10, 0x10, 0, 0}, - {0x9D, 0x3, 0x3, 0, 0}, - {0x9E, 0x4, 0x4, 0, 0}, - {0x9F, 0x20, 0x20, 0, 0}, - {0xA0, 0, 0, 0, 0}, - {0xA1, 0, 0, 0, 0}, - {0xA2, 0, 0, 0, 0}, - {0xA3, 0, 0, 0, 0}, - {0xA4, 0x1, 0x1, 0, 0}, - {0xA5, 0x77, 0x77, 0, 0}, - {0xA6, 0x77, 0x77, 0, 0}, - {0xA7, 0x77, 0x77, 0, 0}, - {0xA8, 0x77, 0x77, 0, 0}, - {0xA9, 0x8c, 0x8c, 0, 0}, - {0xAA, 0x88, 0x88, 0, 0}, - {0xAB, 0x78, 0x78, 0, 0}, - {0xAC, 0x57, 0x57, 0, 0}, - {0xAD, 0x88, 0x88, 0, 0}, - {0xAE, 0, 0, 0, 0}, - {0xAF, 0x8, 0x8, 0, 0}, - {0xB0, 0x88, 0x88, 0, 0}, - {0xB1, 0, 0, 0, 0}, - {0xB2, 0x1b, 0x1b, 0, 0}, - {0xB3, 0x3, 0x3, 0, 0}, - {0xB4, 0x24, 0x24, 0, 0}, - {0xB5, 0x3, 0x3, 0, 0}, - {0xB6, 0x1b, 0x1b, 0, 0}, - {0xB7, 0x24, 0x24, 0, 0}, - {0xB8, 0x3, 0x3, 0, 0}, - {0xB9, 0, 0, 0, 0}, - {0xBA, 0xaa, 0xaa, 0, 0}, - {0xBB, 0, 0, 0, 0}, - {0xBC, 0x4, 0x4, 0, 0}, - {0xBD, 0, 0, 0, 0}, - {0xBE, 0x8, 0x8, 0, 0}, - {0xBF, 0x11, 0x11, 0, 0}, - {0xC0, 0, 0, 0, 0}, - {0xC1, 0, 0, 0, 0}, - {0xC2, 0x62, 0x62, 0, 0}, - {0xC3, 0x1e, 0x1e, 0, 0}, - {0xC4, 0x33, 0x33, 0, 0}, - {0xC5, 0x37, 0x37, 0, 0}, - {0xC6, 0, 0, 0, 0}, - {0xC7, 0x70, 0x70, 0, 0}, - {0xC8, 0x1e, 0x1e, 0, 0}, - {0xC9, 0x6, 0x6, 0, 0}, - {0xCA, 0x4, 0x4, 0, 0}, - {0xCB, 0x2f, 0x2f, 0, 0}, - {0xCC, 0xf, 0xf, 0, 0}, - {0xCD, 0, 0, 0, 0}, - {0xCE, 0xff, 0xff, 0, 0}, - {0xCF, 0x8, 0x8, 0, 0}, - {0xD0, 0x3f, 0x3f, 0, 0}, - {0xD1, 0x3f, 0x3f, 0, 0}, - {0xD2, 0x3f, 0x3f, 0, 0}, - {0xD3, 0, 0, 0, 0}, - {0xD4, 0, 0, 0, 0}, - {0xD5, 0, 0, 0, 0}, - {0xD6, 0xcc, 0xcc, 0, 0}, - {0xD7, 0, 0, 0, 0}, - {0xD8, 0x8, 0x8, 0, 0}, - {0xD9, 0x8, 0x8, 0, 0}, - {0xDA, 0x8, 0x8, 0, 0}, - {0xDB, 0x11, 0x11, 0, 0}, - {0xDC, 0, 0, 0, 0}, - {0xDD, 0x87, 0x87, 0, 0}, - {0xDE, 0x88, 0x88, 0, 0}, - {0xDF, 0x8, 0x8, 0, 0}, - {0xE0, 0x8, 0x8, 0, 0}, - {0xE1, 0x8, 0x8, 0, 0}, - {0xE2, 0, 0, 0, 0}, - {0xE3, 0, 0, 0, 0}, - {0xE4, 0, 0, 0, 0}, - {0xE5, 0xf5, 0xf5, 0, 0}, - {0xE6, 0x30, 0x30, 0, 0}, - {0xE7, 0x1, 0x1, 0, 0}, - {0xE8, 0, 0, 0, 0}, - {0xE9, 0xff, 0xff, 0, 0}, - {0xEA, 0, 0, 0, 0}, - {0xEB, 0, 0, 0, 0}, - {0xEC, 0x22, 0x22, 0, 0}, - {0xED, 0, 0, 0, 0}, - {0xEE, 0, 0, 0, 0}, - {0xEF, 0, 0, 0, 0}, - {0xF0, 0x3, 0x3, 0, 0}, - {0xF1, 0x1, 0x1, 0, 0}, - {0xF2, 0, 0, 0, 0}, - {0xF3, 0, 0, 0, 0}, - {0xF4, 0, 0, 0, 0}, - {0xF5, 0, 0, 0, 0}, - {0xF6, 0, 0, 0, 0}, - {0xF7, 0x6, 0x6, 0, 0}, - {0xF8, 0, 0, 0, 0}, - {0xF9, 0, 0, 0, 0}, - {0xFA, 0x40, 0x40, 0, 0}, - {0xFB, 0, 0, 0, 0}, - {0xFC, 0x1, 0x1, 0, 0}, - {0xFD, 0x80, 0x80, 0, 0}, - {0xFE, 0x2, 0x2, 0, 0}, - {0xFF, 0x10, 0x10, 0, 0}, - {0x100, 0x2, 0x2, 0, 0}, - {0x101, 0x1e, 0x1e, 0, 0}, - {0x102, 0x1e, 0x1e, 0, 0}, - {0x103, 0, 0, 0, 0}, - {0x104, 0x1f, 0x1f, 0, 0}, - {0x105, 0, 0x8, 0, 1}, - {0x106, 0x2a, 0x2a, 0, 0}, - {0x107, 0xf, 0xf, 0, 0}, - {0x108, 0, 0, 0, 0}, - {0x109, 0, 0, 0, 0}, - {0x10A, 0, 0, 0, 0}, - {0x10B, 0, 0, 0, 0}, - {0x10C, 0, 0, 0, 0}, - {0x10D, 0, 0, 0, 0}, - {0x10E, 0, 0, 0, 0}, - {0x10F, 0, 0, 0, 0}, - {0x110, 0, 0, 0, 0}, - {0x111, 0, 0, 0, 0}, - {0x112, 0, 0, 0, 0}, - {0x113, 0, 0, 0, 0}, - {0x114, 0, 0, 0, 0}, - {0x115, 0, 0, 0, 0}, - {0x116, 0, 0, 0, 0}, - {0x117, 0, 0, 0, 0}, - {0x118, 0, 0, 0, 0}, - {0x119, 0, 0, 0, 0}, - {0x11A, 0, 0, 0, 0}, - {0x11B, 0, 0, 0, 0}, - {0x11C, 0x1, 0x1, 0, 0}, - {0x11D, 0, 0, 0, 0}, - {0x11E, 0, 0, 0, 0}, - {0x11F, 0, 0, 0, 0}, - {0x120, 0, 0, 0, 0}, - {0x121, 0, 0, 0, 0}, - {0x122, 0x80, 0x80, 0, 0}, - {0x123, 0, 0, 0, 0}, - {0x124, 0xf8, 0xf8, 0, 0}, - {0x125, 0, 0, 0, 0}, - {0x126, 0, 0, 0, 0}, - {0x127, 0, 0, 0, 0}, - {0x128, 0, 0, 0, 0}, - {0x129, 0, 0, 0, 0}, - {0x12A, 0, 0, 0, 0}, - {0x12B, 0, 0, 0, 0}, - {0x12C, 0, 0, 0, 0}, - {0x12D, 0, 0, 0, 0}, - {0x12E, 0, 0, 0, 0}, - {0x12F, 0, 0, 0, 0}, - {0x130, 0, 0, 0, 0}, - {0xFFFF, 0, 0, 0, 0} -}; - -#define LCNPHY_NUM_DIG_FILT_COEFFS 16 -#define LCNPHY_NUM_TX_DIG_FILTERS_CCK 13 - -u16 - LCNPHY_txdigfiltcoeffs_cck[LCNPHY_NUM_TX_DIG_FILTERS_CCK] - [LCNPHY_NUM_DIG_FILT_COEFFS + 1] = { - {0, 1, 415, 1874, 64, 128, 64, 792, 1656, 64, 128, 64, 778, 1582, 64, - 128, 64,}, - {1, 1, 402, 1847, 259, 59, 259, 671, 1794, 68, 54, 68, 608, 1863, 93, - 167, 93,}, - {2, 1, 415, 1874, 64, 128, 64, 792, 1656, 192, 384, 192, 778, 1582, 64, - 128, 64,}, - {3, 1, 302, 1841, 129, 258, 129, 658, 1720, 205, 410, 205, 754, 1760, - 170, 340, 170,}, - {20, 1, 360, 1884, 242, 1734, 242, 752, 1720, 205, 1845, 205, 767, 1760, - 256, 185, 256,}, - {21, 1, 360, 1884, 149, 1874, 149, 752, 1720, 205, 1883, 205, 767, 1760, - 256, 273, 256,}, - {22, 1, 360, 1884, 98, 1948, 98, 752, 1720, 205, 1924, 205, 767, 1760, - 256, 352, 256,}, - {23, 1, 350, 1884, 116, 1966, 116, 752, 1720, 205, 2008, 205, 767, 1760, - 128, 233, 128,}, - {24, 1, 325, 1884, 32, 40, 32, 756, 1720, 256, 471, 256, 766, 1760, 256, - 1881, 256,}, - {25, 1, 299, 1884, 51, 64, 51, 736, 1720, 256, 471, 256, 765, 1760, 256, - 1881, 256,}, - {26, 1, 277, 1943, 39, 117, 88, 637, 1838, 64, 192, 144, 614, 1864, 128, - 384, 288,}, - {27, 1, 245, 1943, 49, 147, 110, 626, 1838, 256, 768, 576, 613, 1864, - 128, 384, 288,}, - {30, 1, 302, 1841, 61, 122, 61, 658, 1720, 205, 410, 205, 754, 1760, - 170, 340, 170,}, -}; - -#define LCNPHY_NUM_TX_DIG_FILTERS_OFDM 3 -u16 - LCNPHY_txdigfiltcoeffs_ofdm[LCNPHY_NUM_TX_DIG_FILTERS_OFDM] - [LCNPHY_NUM_DIG_FILT_COEFFS + 1] = { - {0, 0, 0xa2, 0x0, 0x100, 0x100, 0x0, 0x0, 0x0, 0x100, 0x0, 0x0, - 0x278, 0xfea0, 0x80, 0x100, 0x80,}, - {1, 0, 374, 0xFF79, 16, 32, 16, 799, 0xFE74, 50, 32, 50, - 750, 0xFE2B, 212, 0xFFCE, 212,}, - {2, 0, 375, 0xFF16, 37, 76, 37, 799, 0xFE74, 32, 20, 32, 748, - 0xFEF2, 128, 0xFFE2, 128} -}; - -#define wlc_lcnphy_set_start_tx_pwr_idx(pi, idx) \ - mod_phy_reg(pi, 0x4a4, \ - (0x1ff << 0), \ - (u16)(idx) << 0) - -#define wlc_lcnphy_set_tx_pwr_npt(pi, npt) \ - mod_phy_reg(pi, 0x4a5, \ - (0x7 << 8), \ - (u16)(npt) << 8) - -#define wlc_lcnphy_get_tx_pwr_ctrl(pi) \ - (read_phy_reg((pi), 0x4a4) & \ - ((0x1 << 15) | \ - (0x1 << 14) | \ - (0x1 << 13))) - -#define wlc_lcnphy_get_tx_pwr_npt(pi) \ - ((read_phy_reg(pi, 0x4a5) & \ - (0x7 << 8)) >> \ - 8) - -#define wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(pi) \ - (read_phy_reg(pi, 0x473) & 0x1ff) - -#define wlc_lcnphy_get_target_tx_pwr(pi) \ - ((read_phy_reg(pi, 0x4a7) & \ - (0xff << 0)) >> \ - 0) - -#define wlc_lcnphy_set_target_tx_pwr(pi, target) \ - mod_phy_reg(pi, 0x4a7, \ - (0xff << 0), \ - (u16)(target) << 0) - -#define wlc_radio_2064_rcal_done(pi) (0 != (read_radio_reg(pi, RADIO_2064_REG05C) & 0x20)) -#define tempsense_done(pi) (0x8000 == (read_phy_reg(pi, 0x476) & 0x8000)) - -#define LCNPHY_IQLOCC_READ(val) ((u8)(-(s8)(((val) & 0xf0) >> 4) + (s8)((val) & 0x0f))) -#define FIXED_TXPWR 78 -#define LCNPHY_TEMPSENSE(val) ((s16)((val > 255) ? (val - 512) : val)) - -static u32 wlc_lcnphy_qdiv_roundup(u32 divident, u32 divisor, - u8 precision); -static void wlc_lcnphy_set_rx_gain_by_distribution(phy_info_t *pi, - u16 ext_lna, u16 trsw, - u16 biq2, u16 biq1, - u16 tia, u16 lna2, - u16 lna1); -static void wlc_lcnphy_clear_tx_power_offsets(phy_info_t *pi); -static void wlc_lcnphy_set_pa_gain(phy_info_t *pi, u16 gain); -static void wlc_lcnphy_set_trsw_override(phy_info_t *pi, bool tx, bool rx); -static void wlc_lcnphy_set_bbmult(phy_info_t *pi, u8 m0); -static u8 wlc_lcnphy_get_bbmult(phy_info_t *pi); -static void wlc_lcnphy_get_tx_gain(phy_info_t *pi, lcnphy_txgains_t *gains); -static void wlc_lcnphy_set_tx_gain_override(phy_info_t *pi, bool bEnable); -static void wlc_lcnphy_toggle_afe_pwdn(phy_info_t *pi); -static void wlc_lcnphy_rx_gain_override_enable(phy_info_t *pi, bool enable); -static void wlc_lcnphy_set_tx_gain(phy_info_t *pi, - lcnphy_txgains_t *target_gains); -static bool wlc_lcnphy_rx_iq_est(phy_info_t *pi, u16 num_samps, - u8 wait_time, lcnphy_iq_est_t *iq_est); -static bool wlc_lcnphy_calc_rx_iq_comp(phy_info_t *pi, u16 num_samps); -static u16 wlc_lcnphy_get_pa_gain(phy_info_t *pi); -static void wlc_lcnphy_afe_clk_init(phy_info_t *pi, u8 mode); -extern void wlc_lcnphy_tx_pwr_ctrl_init(wlc_phy_t *ppi); -static void wlc_lcnphy_radio_2064_channel_tune_4313(phy_info_t *pi, - u8 channel); - -static void wlc_lcnphy_load_tx_gain_table(phy_info_t *pi, - const lcnphy_tx_gain_tbl_entry *g); - -static void wlc_lcnphy_samp_cap(phy_info_t *pi, int clip_detect_algo, - u16 thresh, s16 *ptr, int mode); -static int wlc_lcnphy_calc_floor(s16 coeff, int type); -static void wlc_lcnphy_tx_iqlo_loopback(phy_info_t *pi, - u16 *values_to_save); -static void wlc_lcnphy_tx_iqlo_loopback_cleanup(phy_info_t *pi, - u16 *values_to_save); -static void wlc_lcnphy_set_cc(phy_info_t *pi, int cal_type, s16 coeff_x, - s16 coeff_y); -static lcnphy_unsign16_struct wlc_lcnphy_get_cc(phy_info_t *pi, int cal_type); -static void wlc_lcnphy_a1(phy_info_t *pi, int cal_type, - int num_levels, int step_size_lg2); -static void wlc_lcnphy_tx_iqlo_soft_cal_full(phy_info_t *pi); - -static void wlc_lcnphy_set_chanspec_tweaks(phy_info_t *pi, - chanspec_t chanspec); -static void wlc_lcnphy_agc_temp_init(phy_info_t *pi); -static void wlc_lcnphy_temp_adj(phy_info_t *pi); -static void wlc_lcnphy_clear_papd_comptable(phy_info_t *pi); -static void wlc_lcnphy_baseband_init(phy_info_t *pi); -static void wlc_lcnphy_radio_init(phy_info_t *pi); -static void wlc_lcnphy_rc_cal(phy_info_t *pi); -static void wlc_lcnphy_rcal(phy_info_t *pi); -static void wlc_lcnphy_txrx_spur_avoidance_mode(phy_info_t *pi, bool enable); -static int wlc_lcnphy_load_tx_iir_filter(phy_info_t *pi, bool is_ofdm, - s16 filt_type); -static void wlc_lcnphy_set_rx_iq_comp(phy_info_t *pi, u16 a, u16 b); - -void wlc_lcnphy_write_table(phy_info_t *pi, const phytbl_info_t *pti) -{ - wlc_phy_write_table(pi, pti, 0x455, 0x457, 0x456); -} - -void wlc_lcnphy_read_table(phy_info_t *pi, phytbl_info_t *pti) -{ - wlc_phy_read_table(pi, pti, 0x455, 0x457, 0x456); -} - -static void -wlc_lcnphy_common_read_table(phy_info_t *pi, u32 tbl_id, - const void *tbl_ptr, u32 tbl_len, - u32 tbl_width, u32 tbl_offset) -{ - phytbl_info_t tab; - tab.tbl_id = tbl_id; - tab.tbl_ptr = tbl_ptr; - tab.tbl_len = tbl_len; - tab.tbl_width = tbl_width; - tab.tbl_offset = tbl_offset; - wlc_lcnphy_read_table(pi, &tab); -} - -static void -wlc_lcnphy_common_write_table(phy_info_t *pi, u32 tbl_id, - const void *tbl_ptr, u32 tbl_len, - u32 tbl_width, u32 tbl_offset) -{ - - phytbl_info_t tab; - tab.tbl_id = tbl_id; - tab.tbl_ptr = tbl_ptr; - tab.tbl_len = tbl_len; - tab.tbl_width = tbl_width; - tab.tbl_offset = tbl_offset; - wlc_lcnphy_write_table(pi, &tab); -} - -static u32 -wlc_lcnphy_qdiv_roundup(u32 dividend, u32 divisor, u8 precision) -{ - u32 quotient, remainder, roundup, rbit; - - ASSERT(divisor); - - quotient = dividend / divisor; - remainder = dividend % divisor; - rbit = divisor & 1; - roundup = (divisor >> 1) + rbit; - - while (precision--) { - quotient <<= 1; - if (remainder >= roundup) { - quotient++; - remainder = ((remainder - roundup) << 1) + rbit; - } else { - remainder <<= 1; - } - } - - if (remainder >= roundup) - quotient++; - - return quotient; -} - -static int wlc_lcnphy_calc_floor(s16 coeff_x, int type) -{ - int k; - k = 0; - if (type == 0) { - if (coeff_x < 0) { - k = (coeff_x - 1) / 2; - } else { - k = coeff_x / 2; - } - } - if (type == 1) { - if ((coeff_x + 1) < 0) - k = (coeff_x) / 2; - else - k = (coeff_x + 1) / 2; - } - return k; -} - -s8 wlc_lcnphy_get_current_tx_pwr_idx(phy_info_t *pi) -{ - s8 index; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - if (txpwrctrl_off(pi)) - index = pi_lcn->lcnphy_current_index; - else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) - index = - (s8) (wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(pi) - / 2); - else - index = pi_lcn->lcnphy_current_index; - return index; -} - -static u32 wlc_lcnphy_measure_digital_power(phy_info_t *pi, u16 nsamples) -{ - lcnphy_iq_est_t iq_est = { 0, 0, 0 }; - - if (!wlc_lcnphy_rx_iq_est(pi, nsamples, 32, &iq_est)) - return 0; - return (iq_est.i_pwr + iq_est.q_pwr) / nsamples; -} - -void wlc_lcnphy_crsuprs(phy_info_t *pi, int channel) -{ - u16 afectrlovr, afectrlovrval; - afectrlovr = read_phy_reg(pi, 0x43b); - afectrlovrval = read_phy_reg(pi, 0x43c); - if (channel != 0) { - mod_phy_reg(pi, 0x43b, (0x1 << 1), (1) << 1); - - mod_phy_reg(pi, 0x43c, (0x1 << 1), (0) << 1); - - mod_phy_reg(pi, 0x43b, (0x1 << 4), (1) << 4); - - mod_phy_reg(pi, 0x43c, (0x1 << 6), (0) << 6); - - write_phy_reg(pi, 0x44b, 0xffff); - wlc_lcnphy_tx_pu(pi, 1); - - mod_phy_reg(pi, 0x634, (0xff << 8), (0) << 8); - - or_phy_reg(pi, 0x6da, 0x0080); - - or_phy_reg(pi, 0x00a, 0x228); - } else { - and_phy_reg(pi, 0x00a, ~(0x228)); - - and_phy_reg(pi, 0x6da, 0xFF7F); - write_phy_reg(pi, 0x43b, afectrlovr); - write_phy_reg(pi, 0x43c, afectrlovrval); - } -} - -static void wlc_lcnphy_toggle_afe_pwdn(phy_info_t *pi) -{ - u16 save_AfeCtrlOvrVal, save_AfeCtrlOvr; - - save_AfeCtrlOvrVal = read_phy_reg(pi, 0x43c); - save_AfeCtrlOvr = read_phy_reg(pi, 0x43b); - - write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal | 0x1); - write_phy_reg(pi, 0x43b, save_AfeCtrlOvr | 0x1); - - write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal & 0xfffe); - write_phy_reg(pi, 0x43b, save_AfeCtrlOvr & 0xfffe); - - write_phy_reg(pi, 0x43c, save_AfeCtrlOvrVal); - write_phy_reg(pi, 0x43b, save_AfeCtrlOvr); -} - -static void wlc_lcnphy_txrx_spur_avoidance_mode(phy_info_t *pi, bool enable) -{ - if (enable) { - write_phy_reg(pi, 0x942, 0x7); - write_phy_reg(pi, 0x93b, ((1 << 13) + 23)); - write_phy_reg(pi, 0x93c, ((1 << 13) + 1989)); - - write_phy_reg(pi, 0x44a, 0x084); - write_phy_reg(pi, 0x44a, 0x080); - write_phy_reg(pi, 0x6d3, 0x2222); - write_phy_reg(pi, 0x6d3, 0x2220); - } else { - write_phy_reg(pi, 0x942, 0x0); - write_phy_reg(pi, 0x93b, ((0 << 13) + 23)); - write_phy_reg(pi, 0x93c, ((0 << 13) + 1989)); - } - wlapi_switch_macfreq(pi->sh->physhim, enable); -} - -void wlc_phy_chanspec_set_lcnphy(phy_info_t *pi, chanspec_t chanspec) -{ - u8 channel = CHSPEC_CHANNEL(chanspec); - - wlc_phy_chanspec_radio_set((wlc_phy_t *) pi, chanspec); - - wlc_lcnphy_set_chanspec_tweaks(pi, pi->radio_chanspec); - - or_phy_reg(pi, 0x44a, 0x44); - write_phy_reg(pi, 0x44a, 0x80); - - if (!NORADIO_ENAB(pi->pubpi)) { - wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel); - udelay(1000); - } - - wlc_lcnphy_toggle_afe_pwdn(pi); - - write_phy_reg(pi, 0x657, lcnphy_sfo_cfg[channel - 1].ptcentreTs20); - write_phy_reg(pi, 0x658, lcnphy_sfo_cfg[channel - 1].ptcentreFactor); - - if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) { - mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8); - - wlc_lcnphy_load_tx_iir_filter(pi, false, 3); - } else { - mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8); - - wlc_lcnphy_load_tx_iir_filter(pi, false, 2); - } - - wlc_lcnphy_load_tx_iir_filter(pi, true, 0); - - mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3); - -} - -static void wlc_lcnphy_set_dac_gain(phy_info_t *pi, u16 dac_gain) -{ - u16 dac_ctrl; - - dac_ctrl = (read_phy_reg(pi, 0x439) >> 0); - dac_ctrl = dac_ctrl & 0xc7f; - dac_ctrl = dac_ctrl | (dac_gain << 7); - mod_phy_reg(pi, 0x439, (0xfff << 0), (dac_ctrl) << 0); - -} - -static void wlc_lcnphy_set_tx_gain_override(phy_info_t *pi, bool bEnable) -{ - u16 bit = bEnable ? 1 : 0; - - mod_phy_reg(pi, 0x4b0, (0x1 << 7), bit << 7); - - mod_phy_reg(pi, 0x4b0, (0x1 << 14), bit << 14); - - mod_phy_reg(pi, 0x43b, (0x1 << 6), bit << 6); -} - -static u16 wlc_lcnphy_get_pa_gain(phy_info_t *pi) -{ - u16 pa_gain; - - pa_gain = (read_phy_reg(pi, 0x4fb) & - LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK) >> - LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT; - - return pa_gain; -} - -static void -wlc_lcnphy_set_tx_gain(phy_info_t *pi, lcnphy_txgains_t *target_gains) -{ - u16 pa_gain = wlc_lcnphy_get_pa_gain(pi); - - mod_phy_reg(pi, 0x4b5, - (0xffff << 0), - ((target_gains->gm_gain) | (target_gains->pga_gain << 8)) << - 0); - mod_phy_reg(pi, 0x4fb, - (0x7fff << 0), - ((target_gains->pad_gain) | (pa_gain << 8)) << 0); - - mod_phy_reg(pi, 0x4fc, - (0xffff << 0), - ((target_gains->gm_gain) | (target_gains->pga_gain << 8)) << - 0); - mod_phy_reg(pi, 0x4fd, - (0x7fff << 0), - ((target_gains->pad_gain) | (pa_gain << 8)) << 0); - - wlc_lcnphy_set_dac_gain(pi, target_gains->dac_gain); - - wlc_lcnphy_enable_tx_gain_override(pi); -} - -static void wlc_lcnphy_set_bbmult(phy_info_t *pi, u8 m0) -{ - u16 m0m1 = (u16) m0 << 8; - phytbl_info_t tab; - - tab.tbl_ptr = &m0m1; - tab.tbl_len = 1; - tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL; - tab.tbl_offset = 87; - tab.tbl_width = 16; - wlc_lcnphy_write_table(pi, &tab); -} - -static void wlc_lcnphy_clear_tx_power_offsets(phy_info_t *pi) -{ - u32 data_buf[64]; - phytbl_info_t tab; - - memset(data_buf, 0, sizeof(data_buf)); - - tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; - tab.tbl_width = 32; - tab.tbl_ptr = data_buf; - - if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) { - - tab.tbl_len = 30; - tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET; - wlc_lcnphy_write_table(pi, &tab); - } - - tab.tbl_len = 64; - tab.tbl_offset = LCNPHY_TX_PWR_CTRL_MAC_OFFSET; - wlc_lcnphy_write_table(pi, &tab); -} - -typedef enum { - LCNPHY_TSSI_PRE_PA, - LCNPHY_TSSI_POST_PA, - LCNPHY_TSSI_EXT -} lcnphy_tssi_mode_t; - -static void wlc_lcnphy_set_tssi_mux(phy_info_t *pi, lcnphy_tssi_mode_t pos) -{ - mod_phy_reg(pi, 0x4d7, (0x1 << 0), (0x1) << 0); - - mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1) << 6); - - if (LCNPHY_TSSI_POST_PA == pos) { - mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0) << 2); - - mod_phy_reg(pi, 0x4d9, (0x1 << 3), (1) << 3); - - if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { - mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4); - } else { - mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1); - mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8); - } - } else { - mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2); - - mod_phy_reg(pi, 0x4d9, (0x1 << 3), (0) << 3); - - if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { - mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4); - } else { - mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0); - mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8); - } - } - mod_phy_reg(pi, 0x637, (0x3 << 14), (0) << 14); - - if (LCNPHY_TSSI_EXT == pos) { - write_radio_reg(pi, RADIO_2064_REG07F, 1); - mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 0x2); - mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 0x1 << 7); - mod_radio_reg(pi, RADIO_2064_REG028, 0x1f, 0x3); - } -} - -static u16 wlc_lcnphy_rfseq_tbl_adc_pwrup(phy_info_t *pi) -{ - u16 N1, N2, N3, N4, N5, N6, N; - N1 = ((read_phy_reg(pi, 0x4a5) & (0xff << 0)) - >> 0); - N2 = 1 << ((read_phy_reg(pi, 0x4a5) & (0x7 << 12)) - >> 12); - N3 = ((read_phy_reg(pi, 0x40d) & (0xff << 0)) - >> 0); - N4 = 1 << ((read_phy_reg(pi, 0x40d) & (0x7 << 8)) - >> 8); - N5 = ((read_phy_reg(pi, 0x4a2) & (0xff << 0)) - >> 0); - N6 = 1 << ((read_phy_reg(pi, 0x4a2) & (0x7 << 8)) - >> 8); - N = 2 * (N1 + N2 + N3 + N4 + 2 * (N5 + N6)) + 80; - if (N < 1600) - N = 1600; - return N; -} - -static void wlc_lcnphy_pwrctrl_rssiparams(phy_info_t *pi) -{ - u16 auxpga_vmid, auxpga_vmid_temp, auxpga_gain_temp; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - auxpga_vmid = - (2 << 8) | (pi_lcn->lcnphy_rssi_vc << 4) | pi_lcn->lcnphy_rssi_vf; - auxpga_vmid_temp = (2 << 8) | (8 << 4) | 4; - auxpga_gain_temp = 2; - - mod_phy_reg(pi, 0x4d8, (0x1 << 0), (0) << 0); - - mod_phy_reg(pi, 0x4d8, (0x1 << 1), (0) << 1); - - mod_phy_reg(pi, 0x4d7, (0x1 << 3), (0) << 3); - - mod_phy_reg(pi, 0x4db, - (0x3ff << 0) | - (0x7 << 12), - (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12)); - - mod_phy_reg(pi, 0x4dc, - (0x3ff << 0) | - (0x7 << 12), - (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12)); - - mod_phy_reg(pi, 0x40a, - (0x3ff << 0) | - (0x7 << 12), - (auxpga_vmid << 0) | (pi_lcn->lcnphy_rssi_gs << 12)); - - mod_phy_reg(pi, 0x40b, - (0x3ff << 0) | - (0x7 << 12), - (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12)); - - mod_phy_reg(pi, 0x40c, - (0x3ff << 0) | - (0x7 << 12), - (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12)); - - mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5)); -} - -static void wlc_lcnphy_tssi_setup(phy_info_t *pi) -{ - phytbl_info_t tab; - u32 rfseq, ind; - - tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; - tab.tbl_width = 32; - tab.tbl_ptr = &ind; - tab.tbl_len = 1; - tab.tbl_offset = 0; - for (ind = 0; ind < 128; ind++) { - wlc_lcnphy_write_table(pi, &tab); - tab.tbl_offset++; - } - tab.tbl_offset = 704; - for (ind = 0; ind < 128; ind++) { - wlc_lcnphy_write_table(pi, &tab); - tab.tbl_offset++; - } - mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0); - - mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2); - - mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4); - - wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT); - mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14); - - mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15); - - mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5); - - mod_phy_reg(pi, 0x4a4, (0x1ff << 0), (0) << 0); - - mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0); - - mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12); - - mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8); - - mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0); - - mod_phy_reg(pi, 0x40d, (0x7 << 8), (4) << 8); - - mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0); - - mod_phy_reg(pi, 0x4a2, (0x7 << 8), (4) << 8); - - mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (0) << 6); - - mod_phy_reg(pi, 0x4a8, (0xff << 0), (0x1) << 0); - - wlc_lcnphy_clear_tx_power_offsets(pi); - - mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15); - - mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (0xff) << 0); - - mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0); - - if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { - mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe); - mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4); - } else { - mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1); - mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3); - } - - write_radio_reg(pi, RADIO_2064_REG025, 0xc); - - if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { - mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1); - } else { - if (CHSPEC_IS2G(pi->radio_chanspec)) - mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1); - else - mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 0 << 1); - } - - if (LCNREV_IS(pi->pubpi.phy_rev, 2)) - mod_radio_reg(pi, RADIO_2064_REG03A, 0x2, 1 << 1); - else - mod_radio_reg(pi, RADIO_2064_REG03A, 0x4, 1 << 2); - - mod_radio_reg(pi, RADIO_2064_REG11A, 0x1, 1 << 0); - - mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 1 << 3); - - if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) { - mod_phy_reg(pi, 0x4d7, - (0x1 << 3) | (0x7 << 12), 0 << 3 | 2 << 12); - } - - rfseq = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi); - tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; - tab.tbl_width = 16; - tab.tbl_ptr = &rfseq; - tab.tbl_len = 1; - tab.tbl_offset = 6; - wlc_lcnphy_write_table(pi, &tab); - - mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2); - - mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2); - - mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12); - - mod_phy_reg(pi, 0x4d7, (0x1 << 2), (1) << 2); - - mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8); - - wlc_lcnphy_pwrctrl_rssiparams(pi); -} - -void wlc_lcnphy_tx_pwr_update_npt(phy_info_t *pi) -{ - u16 tx_cnt, tx_total, npt; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - tx_total = wlc_lcnphy_total_tx_frames(pi); - tx_cnt = tx_total - pi_lcn->lcnphy_tssi_tx_cnt; - npt = wlc_lcnphy_get_tx_pwr_npt(pi); - - if (tx_cnt > (1 << npt)) { - - pi_lcn->lcnphy_tssi_tx_cnt = tx_total; - - pi_lcn->lcnphy_tssi_idx = wlc_lcnphy_get_current_tx_pwr_idx(pi); - pi_lcn->lcnphy_tssi_npt = npt; - - } -} - -s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1) -{ - s32 a, b, p; - - a = 32768 + (a1 * tssi); - b = (1024 * b0) + (64 * b1 * tssi); - p = ((2 * b) + a) / (2 * a); - - return p; -} - -static void wlc_lcnphy_txpower_reset_npt(phy_info_t *pi) -{ - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) - return; - - pi_lcn->lcnphy_tssi_idx = LCNPHY_TX_PWR_CTRL_START_INDEX_2G_4313; - pi_lcn->lcnphy_tssi_npt = LCNPHY_TX_PWR_CTRL_START_NPT; -} - -void wlc_lcnphy_txpower_recalc_target(phy_info_t *pi) -{ - phytbl_info_t tab; - u32 rate_table[WLC_NUM_RATES_CCK + WLC_NUM_RATES_OFDM + - WLC_NUM_RATES_MCS_1_STREAM]; - uint i, j; - if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) - return; - - for (i = 0, j = 0; i < ARRAY_SIZE(rate_table); i++, j++) { - - if (i == WLC_NUM_RATES_CCK + WLC_NUM_RATES_OFDM) - j = TXP_FIRST_MCS_20_SISO; - - rate_table[i] = (u32) ((s32) (-pi->tx_power_offset[j])); - } - - tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; - tab.tbl_width = 32; - tab.tbl_len = ARRAY_SIZE(rate_table); - tab.tbl_ptr = rate_table; - tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET; - wlc_lcnphy_write_table(pi, &tab); - - if (wlc_lcnphy_get_target_tx_pwr(pi) != pi->tx_power_min) { - wlc_lcnphy_set_target_tx_pwr(pi, pi->tx_power_min); - - wlc_lcnphy_txpower_reset_npt(pi); - } -} - -static void wlc_lcnphy_set_tx_pwr_soft_ctrl(phy_info_t *pi, s8 index) -{ - u32 cck_offset[4] = { 22, 22, 22, 22 }; - u32 ofdm_offset, reg_offset_cck; - int i; - u16 index2; - phytbl_info_t tab; - - if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) - return; - - mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14); - - mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x0) << 14); - - or_phy_reg(pi, 0x6da, 0x0040); - - reg_offset_cck = 0; - for (i = 0; i < 4; i++) - cck_offset[i] -= reg_offset_cck; - tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; - tab.tbl_width = 32; - tab.tbl_len = 4; - tab.tbl_ptr = cck_offset; - tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET; - wlc_lcnphy_write_table(pi, &tab); - ofdm_offset = 0; - tab.tbl_len = 1; - tab.tbl_ptr = &ofdm_offset; - for (i = 836; i < 862; i++) { - tab.tbl_offset = i; - wlc_lcnphy_write_table(pi, &tab); - } - - mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0x1) << 15); - - mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0x1) << 14); - - mod_phy_reg(pi, 0x4a4, (0x1 << 13), (0x1) << 13); - - mod_phy_reg(pi, 0x4b0, (0x1 << 7), (0) << 7); - - mod_phy_reg(pi, 0x43b, (0x1 << 6), (0) << 6); - - mod_phy_reg(pi, 0x4a9, (0x1 << 15), (1) << 15); - - index2 = (u16) (index * 2); - mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0); - - mod_phy_reg(pi, 0x6a3, (0x1 << 4), (0) << 4); - -} - -static s8 wlc_lcnphy_tempcompensated_txpwrctrl(phy_info_t *pi) -{ - s8 index, delta_brd, delta_temp, new_index, tempcorrx; - s16 manp, meas_temp, temp_diff; - bool neg = 0; - u16 temp; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) - return pi_lcn->lcnphy_current_index; - - index = FIXED_TXPWR; - - if (NORADIO_ENAB(pi->pubpi)) - return index; - - if (pi_lcn->lcnphy_tempsense_slope == 0) { - return index; - } - temp = (u16) wlc_lcnphy_tempsense(pi, 0); - meas_temp = LCNPHY_TEMPSENSE(temp); - - if (pi->tx_power_min != 0) { - delta_brd = (pi_lcn->lcnphy_measPower - pi->tx_power_min); - } else { - delta_brd = 0; - } - - manp = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_rawtempsense); - temp_diff = manp - meas_temp; - if (temp_diff < 0) { - - neg = 1; - - temp_diff = -temp_diff; - } - - delta_temp = (s8) wlc_lcnphy_qdiv_roundup((u32) (temp_diff * 192), - (u32) (pi_lcn-> - lcnphy_tempsense_slope - * 10), 0); - if (neg) - delta_temp = -delta_temp; - - if (pi_lcn->lcnphy_tempsense_option == 3 - && LCNREV_IS(pi->pubpi.phy_rev, 0)) - delta_temp = 0; - if (pi_lcn->lcnphy_tempcorrx > 31) - tempcorrx = (s8) (pi_lcn->lcnphy_tempcorrx - 64); - else - tempcorrx = (s8) pi_lcn->lcnphy_tempcorrx; - if (LCNREV_IS(pi->pubpi.phy_rev, 1)) - tempcorrx = 4; - new_index = - index + delta_brd + delta_temp - pi_lcn->lcnphy_bandedge_corr; - new_index += tempcorrx; - - if (LCNREV_IS(pi->pubpi.phy_rev, 1)) - index = 127; - if (new_index < 0 || new_index > 126) { - return index; - } - return new_index; -} - -static u16 wlc_lcnphy_set_tx_pwr_ctrl_mode(phy_info_t *pi, u16 mode) -{ - - u16 current_mode = mode; - if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) && - mode == LCNPHY_TX_PWR_CTRL_HW) - current_mode = LCNPHY_TX_PWR_CTRL_TEMPBASED; - if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) && - mode == LCNPHY_TX_PWR_CTRL_TEMPBASED) - current_mode = LCNPHY_TX_PWR_CTRL_HW; - return current_mode; -} - -void wlc_lcnphy_set_tx_pwr_ctrl(phy_info_t *pi, u16 mode) -{ - u16 old_mode = wlc_lcnphy_get_tx_pwr_ctrl(pi); - s8 index; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - ASSERT((LCNPHY_TX_PWR_CTRL_OFF == mode) || - (LCNPHY_TX_PWR_CTRL_SW == mode) || - (LCNPHY_TX_PWR_CTRL_HW == mode) || - (LCNPHY_TX_PWR_CTRL_TEMPBASED == mode)); - - mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, mode); - old_mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, old_mode); - - mod_phy_reg(pi, 0x6da, (0x1 << 6), - ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 1 : 0) << 6); - - mod_phy_reg(pi, 0x6a3, (0x1 << 4), - ((LCNPHY_TX_PWR_CTRL_HW == mode) ? 0 : 1) << 4); - - if (old_mode != mode) { - if (LCNPHY_TX_PWR_CTRL_HW == old_mode) { - - wlc_lcnphy_tx_pwr_update_npt(pi); - - wlc_lcnphy_clear_tx_power_offsets(pi); - } - if (LCNPHY_TX_PWR_CTRL_HW == mode) { - - wlc_lcnphy_txpower_recalc_target(pi); - - wlc_lcnphy_set_start_tx_pwr_idx(pi, - pi_lcn-> - lcnphy_tssi_idx); - wlc_lcnphy_set_tx_pwr_npt(pi, pi_lcn->lcnphy_tssi_npt); - mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0); - - pi_lcn->lcnphy_tssi_tx_cnt = - wlc_lcnphy_total_tx_frames(pi); - - wlc_lcnphy_disable_tx_gain_override(pi); - pi_lcn->lcnphy_tx_power_idx_override = -1; - } else - wlc_lcnphy_enable_tx_gain_override(pi); - - mod_phy_reg(pi, 0x4a4, - ((0x1 << 15) | (0x1 << 14) | (0x1 << 13)), mode); - if (mode == LCNPHY_TX_PWR_CTRL_TEMPBASED) { - index = wlc_lcnphy_tempcompensated_txpwrctrl(pi); - wlc_lcnphy_set_tx_pwr_soft_ctrl(pi, index); - pi_lcn->lcnphy_current_index = (s8) - ((read_phy_reg(pi, 0x4a9) & 0xFF) / 2); - } - } -} - -static bool wlc_lcnphy_iqcal_wait(phy_info_t *pi) -{ - uint delay_count = 0; - - while (wlc_lcnphy_iqcal_active(pi)) { - udelay(100); - delay_count++; - - if (delay_count > (10 * 500)) - break; - } - - return (0 == wlc_lcnphy_iqcal_active(pi)); -} - -static void -wlc_lcnphy_tx_iqlo_cal(phy_info_t *pi, - lcnphy_txgains_t *target_gains, - lcnphy_cal_mode_t cal_mode, bool keep_tone) -{ - - lcnphy_txgains_t cal_gains, temp_gains; - u16 hash; - u8 band_idx; - int j; - u16 ncorr_override[5]; - u16 syst_coeffs[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 - }; - - u16 commands_fullcal[] = { - 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234 }; - - u16 commands_recal[] = { - 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234 }; - - u16 command_nums_fullcal[] = { - 0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97 }; - - u16 command_nums_recal[] = { - 0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97 }; - u16 *command_nums = command_nums_fullcal; - - u16 *start_coeffs = NULL, *cal_cmds = NULL, cal_type, diq_start; - u16 tx_pwr_ctrl_old, save_txpwrctrlrfctrl2; - u16 save_sslpnCalibClkEnCtrl, save_sslpnRxFeClkEnCtrl; - bool tx_gain_override_old; - lcnphy_txgains_t old_gains; - uint i, n_cal_cmds = 0, n_cal_start = 0; - u16 *values_to_save; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - if (NORADIO_ENAB(pi->pubpi)) - return; - - values_to_save = kmalloc(sizeof(u16) * 20, GFP_ATOMIC); - if (NULL == values_to_save) { - return; - } - - save_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db); - save_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); - - or_phy_reg(pi, 0x6da, 0x40); - or_phy_reg(pi, 0x6db, 0x3); - - switch (cal_mode) { - case LCNPHY_CAL_FULL: - start_coeffs = syst_coeffs; - cal_cmds = commands_fullcal; - n_cal_cmds = ARRAY_SIZE(commands_fullcal); - break; - - case LCNPHY_CAL_RECAL: - ASSERT(pi_lcn->lcnphy_cal_results.txiqlocal_bestcoeffs_valid); - - start_coeffs = syst_coeffs; - - cal_cmds = commands_recal; - n_cal_cmds = ARRAY_SIZE(commands_recal); - command_nums = command_nums_recal; - break; - default: - ASSERT(false); - } - - wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, - start_coeffs, 11, 16, 64); - - write_phy_reg(pi, 0x6da, 0xffff); - mod_phy_reg(pi, 0x503, (0x1 << 3), (1) << 3); - - tx_pwr_ctrl_old = wlc_lcnphy_get_tx_pwr_ctrl(pi); - - mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12); - - wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); - - save_txpwrctrlrfctrl2 = read_phy_reg(pi, 0x4db); - - mod_phy_reg(pi, 0x4db, (0x3ff << 0), (0x2a6) << 0); - - mod_phy_reg(pi, 0x4db, (0x7 << 12), (2) << 12); - - wlc_lcnphy_tx_iqlo_loopback(pi, values_to_save); - - tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi); - if (tx_gain_override_old) - wlc_lcnphy_get_tx_gain(pi, &old_gains); - - if (!target_gains) { - if (!tx_gain_override_old) - wlc_lcnphy_set_tx_pwr_by_index(pi, - pi_lcn->lcnphy_tssi_idx); - wlc_lcnphy_get_tx_gain(pi, &temp_gains); - target_gains = &temp_gains; - } - - hash = (target_gains->gm_gain << 8) | - (target_gains->pga_gain << 4) | (target_gains->pad_gain); - - band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0); - - cal_gains = *target_gains; - memset(ncorr_override, 0, sizeof(ncorr_override)); - for (j = 0; j < iqcal_gainparams_numgains_lcnphy[band_idx]; j++) { - if (hash == tbl_iqcal_gainparams_lcnphy[band_idx][j][0]) { - cal_gains.gm_gain = - tbl_iqcal_gainparams_lcnphy[band_idx][j][1]; - cal_gains.pga_gain = - tbl_iqcal_gainparams_lcnphy[band_idx][j][2]; - cal_gains.pad_gain = - tbl_iqcal_gainparams_lcnphy[band_idx][j][3]; - bcopy(&tbl_iqcal_gainparams_lcnphy[band_idx][j][3], - ncorr_override, sizeof(ncorr_override)); - break; - } - } - - wlc_lcnphy_set_tx_gain(pi, &cal_gains); - - write_phy_reg(pi, 0x453, 0xaa9); - write_phy_reg(pi, 0x93d, 0xc0); - - wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, - (const void *) - lcnphy_iqcal_loft_gainladder, - ARRAY_SIZE(lcnphy_iqcal_loft_gainladder), - 16, 0); - - wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, - (const void *)lcnphy_iqcal_ir_gainladder, - ARRAY_SIZE(lcnphy_iqcal_ir_gainladder), 16, - 32); - - if (pi->phy_tx_tone_freq) { - - wlc_lcnphy_stop_tx_tone(pi); - udelay(5); - wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1); - } else { - wlc_lcnphy_start_tx_tone(pi, 3750, 88, 1); - } - - write_phy_reg(pi, 0x6da, 0xffff); - - for (i = n_cal_start; i < n_cal_cmds; i++) { - u16 zero_diq = 0; - u16 best_coeffs[11]; - u16 command_num; - - cal_type = (cal_cmds[i] & 0x0f00) >> 8; - - command_num = command_nums[i]; - if (ncorr_override[cal_type]) - command_num = - ncorr_override[cal_type] << 8 | (command_num & - 0xff); - - write_phy_reg(pi, 0x452, command_num); - - if ((cal_type == 3) || (cal_type == 4)) { - - wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL, - &diq_start, 1, 16, 69); - - wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, - &zero_diq, 1, 16, 69); - } - - write_phy_reg(pi, 0x451, cal_cmds[i]); - - if (!wlc_lcnphy_iqcal_wait(pi)) { - - goto cleanup; - } - - wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL, - best_coeffs, - ARRAY_SIZE(best_coeffs), 16, 96); - wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, - best_coeffs, - ARRAY_SIZE(best_coeffs), 16, 64); - - if ((cal_type == 3) || (cal_type == 4)) { - wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, - &diq_start, 1, 16, 69); - } - wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL, - pi_lcn->lcnphy_cal_results. - txiqlocal_bestcoeffs, - ARRAY_SIZE(pi_lcn-> - lcnphy_cal_results. - txiqlocal_bestcoeffs), - 16, 96); - } - - wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL, - pi_lcn->lcnphy_cal_results. - txiqlocal_bestcoeffs, - ARRAY_SIZE(pi_lcn->lcnphy_cal_results. - txiqlocal_bestcoeffs), 16, 96); - pi_lcn->lcnphy_cal_results.txiqlocal_bestcoeffs_valid = true; - - wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, - &pi_lcn->lcnphy_cal_results. - txiqlocal_bestcoeffs[0], 4, 16, 80); - - wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, - &pi_lcn->lcnphy_cal_results. - txiqlocal_bestcoeffs[5], 2, 16, 85); - - cleanup: - wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, values_to_save); - kfree(values_to_save); - - if (!keep_tone) - wlc_lcnphy_stop_tx_tone(pi); - - write_phy_reg(pi, 0x4db, save_txpwrctrlrfctrl2); - - write_phy_reg(pi, 0x453, 0); - - if (tx_gain_override_old) - wlc_lcnphy_set_tx_gain(pi, &old_gains); - wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl_old); - - write_phy_reg(pi, 0x6da, save_sslpnCalibClkEnCtrl); - write_phy_reg(pi, 0x6db, save_sslpnRxFeClkEnCtrl); - -} - -static void wlc_lcnphy_idle_tssi_est(wlc_phy_t *ppi) -{ - bool suspend, tx_gain_override_old; - lcnphy_txgains_t old_gains; - phy_info_t *pi = (phy_info_t *) ppi; - u16 idleTssi, idleTssi0_2C, idleTssi0_OB, idleTssi0_regvalue_OB, - idleTssi0_regvalue_2C; - u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); - u16 SAVE_lpfgain = read_radio_reg(pi, RADIO_2064_REG112); - u16 SAVE_jtag_bb_afe_switch = - read_radio_reg(pi, RADIO_2064_REG007) & 1; - u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10; - u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4; - idleTssi = read_phy_reg(pi, 0x4ab); - suspend = - (0 == - (R_REG(pi->sh->osh, &((phy_info_t *) pi)->regs->maccontrol) & - MCTL_EN_MAC)); - if (!suspend) - wlapi_suspend_mac_and_wait(pi->sh->physhim); - wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); - - tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi); - wlc_lcnphy_get_tx_gain(pi, &old_gains); - - wlc_lcnphy_enable_tx_gain_override(pi); - wlc_lcnphy_set_tx_pwr_by_index(pi, 127); - write_radio_reg(pi, RADIO_2064_REG112, 0x6); - mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 1); - mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4); - mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2); - wlc_lcnphy_tssi_setup(pi); - wlc_phy_do_dummy_tx(pi, true, OFF); - idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0)) - >> 0); - - idleTssi0_2C = ((read_phy_reg(pi, 0x63e) & (0x1ff << 0)) - >> 0); - - if (idleTssi0_2C >= 256) - idleTssi0_OB = idleTssi0_2C - 256; - else - idleTssi0_OB = idleTssi0_2C + 256; - - idleTssi0_regvalue_OB = idleTssi0_OB; - if (idleTssi0_regvalue_OB >= 256) - idleTssi0_regvalue_2C = idleTssi0_regvalue_OB - 256; - else - idleTssi0_regvalue_2C = idleTssi0_regvalue_OB + 256; - mod_phy_reg(pi, 0x4a6, (0x1ff << 0), (idleTssi0_regvalue_2C) << 0); - - mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12); - - wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old); - wlc_lcnphy_set_tx_gain(pi, &old_gains); - wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl); - - write_radio_reg(pi, RADIO_2064_REG112, SAVE_lpfgain); - mod_radio_reg(pi, RADIO_2064_REG007, 0x1, SAVE_jtag_bb_afe_switch); - mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, SAVE_jtag_auxpga); - mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, SAVE_iqadc_aux_en); - mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1 << 7); - if (!suspend) - wlapi_enable_mac(pi->sh->physhim); -} - -static void wlc_lcnphy_vbat_temp_sense_setup(phy_info_t *pi, u8 mode) -{ - bool suspend; - u16 save_txpwrCtrlEn; - u8 auxpga_vmidcourse, auxpga_vmidfine, auxpga_gain; - u16 auxpga_vmid; - phytbl_info_t tab; - u32 val; - u8 save_reg007, save_reg0FF, save_reg11F, save_reg005, save_reg025, - save_reg112; - u16 values_to_save[14]; - s8 index; - int i; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - udelay(999); - - save_reg007 = (u8) read_radio_reg(pi, RADIO_2064_REG007); - save_reg0FF = (u8) read_radio_reg(pi, RADIO_2064_REG0FF); - save_reg11F = (u8) read_radio_reg(pi, RADIO_2064_REG11F); - save_reg005 = (u8) read_radio_reg(pi, RADIO_2064_REG005); - save_reg025 = (u8) read_radio_reg(pi, RADIO_2064_REG025); - save_reg112 = (u8) read_radio_reg(pi, RADIO_2064_REG112); - - for (i = 0; i < 14; i++) - values_to_save[i] = read_phy_reg(pi, tempsense_phy_regs[i]); - suspend = - (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); - if (!suspend) - wlapi_suspend_mac_and_wait(pi->sh->physhim); - save_txpwrCtrlEn = read_radio_reg(pi, 0x4a4); - - wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); - index = pi_lcn->lcnphy_current_index; - wlc_lcnphy_set_tx_pwr_by_index(pi, 127); - mod_radio_reg(pi, RADIO_2064_REG007, 0x1, 0x1); - mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 0x1 << 4); - mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0x1 << 2); - mod_phy_reg(pi, 0x503, (0x1 << 0), (0) << 0); - - mod_phy_reg(pi, 0x503, (0x1 << 2), (0) << 2); - - mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14); - - mod_phy_reg(pi, 0x4a4, (0x1 << 15), (0) << 15); - - mod_phy_reg(pi, 0x4d0, (0x1 << 5), (0) << 5); - - mod_phy_reg(pi, 0x4a5, (0xff << 0), (255) << 0); - - mod_phy_reg(pi, 0x4a5, (0x7 << 12), (5) << 12); - - mod_phy_reg(pi, 0x4a5, (0x7 << 8), (0) << 8); - - mod_phy_reg(pi, 0x40d, (0xff << 0), (64) << 0); - - mod_phy_reg(pi, 0x40d, (0x7 << 8), (6) << 8); - - mod_phy_reg(pi, 0x4a2, (0xff << 0), (64) << 0); - - mod_phy_reg(pi, 0x4a2, (0x7 << 8), (6) << 8); - - mod_phy_reg(pi, 0x4d9, (0x7 << 4), (2) << 4); - - mod_phy_reg(pi, 0x4d9, (0x7 << 8), (3) << 8); - - mod_phy_reg(pi, 0x4d9, (0x7 << 12), (1) << 12); - - mod_phy_reg(pi, 0x4da, (0x1 << 12), (0) << 12); - - mod_phy_reg(pi, 0x4da, (0x1 << 13), (1) << 13); - - mod_phy_reg(pi, 0x4a6, (0x1 << 15), (1) << 15); - - write_radio_reg(pi, RADIO_2064_REG025, 0xC); - - mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 0x1 << 3); - - mod_phy_reg(pi, 0x938, (0x1 << 2), (1) << 2); - - mod_phy_reg(pi, 0x939, (0x1 << 2), (1) << 2); - - mod_phy_reg(pi, 0x4a4, (0x1 << 12), (1) << 12); - - val = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi); - tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; - tab.tbl_width = 16; - tab.tbl_len = 1; - tab.tbl_ptr = &val; - tab.tbl_offset = 6; - wlc_lcnphy_write_table(pi, &tab); - if (mode == TEMPSENSE) { - mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3); - - mod_phy_reg(pi, 0x4d7, (0x7 << 12), (1) << 12); - - auxpga_vmidcourse = 8; - auxpga_vmidfine = 0x4; - auxpga_gain = 2; - mod_radio_reg(pi, RADIO_2064_REG082, 0x20, 1 << 5); - } else { - mod_phy_reg(pi, 0x4d7, (0x1 << 3), (1) << 3); - - mod_phy_reg(pi, 0x4d7, (0x7 << 12), (3) << 12); - - auxpga_vmidcourse = 7; - auxpga_vmidfine = 0xa; - auxpga_gain = 2; - } - auxpga_vmid = - (u16) ((2 << 8) | (auxpga_vmidcourse << 4) | auxpga_vmidfine); - mod_phy_reg(pi, 0x4d8, (0x1 << 0), (1) << 0); - - mod_phy_reg(pi, 0x4d8, (0x3ff << 2), (auxpga_vmid) << 2); - - mod_phy_reg(pi, 0x4d8, (0x1 << 1), (1) << 1); - - mod_phy_reg(pi, 0x4d8, (0x7 << 12), (auxpga_gain) << 12); - - mod_phy_reg(pi, 0x4d0, (0x1 << 5), (1) << 5); - - write_radio_reg(pi, RADIO_2064_REG112, 0x6); - - wlc_phy_do_dummy_tx(pi, true, OFF); - if (!tempsense_done(pi)) - udelay(10); - - write_radio_reg(pi, RADIO_2064_REG007, (u16) save_reg007); - write_radio_reg(pi, RADIO_2064_REG0FF, (u16) save_reg0FF); - write_radio_reg(pi, RADIO_2064_REG11F, (u16) save_reg11F); - write_radio_reg(pi, RADIO_2064_REG005, (u16) save_reg005); - write_radio_reg(pi, RADIO_2064_REG025, (u16) save_reg025); - write_radio_reg(pi, RADIO_2064_REG112, (u16) save_reg112); - for (i = 0; i < 14; i++) - write_phy_reg(pi, tempsense_phy_regs[i], values_to_save[i]); - wlc_lcnphy_set_tx_pwr_by_index(pi, (int)index); - - write_radio_reg(pi, 0x4a4, save_txpwrCtrlEn); - if (!suspend) - wlapi_enable_mac(pi->sh->physhim); - udelay(999); -} - -void WLBANDINITFN(wlc_lcnphy_tx_pwr_ctrl_init) (wlc_phy_t *ppi) -{ - lcnphy_txgains_t tx_gains; - u8 bbmult; - phytbl_info_t tab; - s32 a1, b0, b1; - s32 tssi, pwr, maxtargetpwr, mintargetpwr; - bool suspend; - phy_info_t *pi = (phy_info_t *) ppi; - - suspend = - (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); - if (!suspend) - wlapi_suspend_mac_and_wait(pi->sh->physhim); - - if (NORADIO_ENAB(pi->pubpi)) { - wlc_lcnphy_set_bbmult(pi, 0x30); - if (!suspend) - wlapi_enable_mac(pi->sh->physhim); - return; - } - - if (!pi->hwpwrctrl_capable) { - if (CHSPEC_IS2G(pi->radio_chanspec)) { - tx_gains.gm_gain = 4; - tx_gains.pga_gain = 12; - tx_gains.pad_gain = 12; - tx_gains.dac_gain = 0; - - bbmult = 150; - } else { - tx_gains.gm_gain = 7; - tx_gains.pga_gain = 15; - tx_gains.pad_gain = 14; - tx_gains.dac_gain = 0; - - bbmult = 150; - } - wlc_lcnphy_set_tx_gain(pi, &tx_gains); - wlc_lcnphy_set_bbmult(pi, bbmult); - wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE); - } else { - - wlc_lcnphy_idle_tssi_est(ppi); - - wlc_lcnphy_clear_tx_power_offsets(pi); - - b0 = pi->txpa_2g[0]; - b1 = pi->txpa_2g[1]; - a1 = pi->txpa_2g[2]; - maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1); - mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1); - - tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; - tab.tbl_width = 32; - tab.tbl_ptr = &pwr; - tab.tbl_len = 1; - tab.tbl_offset = 0; - for (tssi = 0; tssi < 128; tssi++) { - pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1); - - pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr; - wlc_lcnphy_write_table(pi, &tab); - tab.tbl_offset++; - } - - mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7); - - write_phy_reg(pi, 0x4a8, 10); - - wlc_lcnphy_set_target_tx_pwr(pi, LCN_TARGET_PWR); - - wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW); - } - if (!suspend) - wlapi_enable_mac(pi->sh->physhim); -} - -static u8 wlc_lcnphy_get_bbmult(phy_info_t *pi) -{ - u16 m0m1; - phytbl_info_t tab; - - tab.tbl_ptr = &m0m1; - tab.tbl_len = 1; - tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL; - tab.tbl_offset = 87; - tab.tbl_width = 16; - wlc_lcnphy_read_table(pi, &tab); - - return (u8) ((m0m1 & 0xff00) >> 8); -} - -static void wlc_lcnphy_set_pa_gain(phy_info_t *pi, u16 gain) -{ - mod_phy_reg(pi, 0x4fb, - LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK, - gain << LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT); - mod_phy_reg(pi, 0x4fd, - LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_MASK, - gain << LCNPHY_stxtxgainctrlovrval1_pagain_ovr_val1_SHIFT); -} - -void -wlc_lcnphy_get_radio_loft(phy_info_t *pi, - u8 *ei0, u8 *eq0, u8 *fi0, u8 *fq0) -{ - *ei0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG089)); - *eq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08A)); - *fi0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08B)); - *fq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08C)); -} - -static void wlc_lcnphy_get_tx_gain(phy_info_t *pi, lcnphy_txgains_t *gains) -{ - u16 dac_gain; - - dac_gain = read_phy_reg(pi, 0x439) >> 0; - gains->dac_gain = (dac_gain & 0x380) >> 7; - - { - u16 rfgain0, rfgain1; - - rfgain0 = (read_phy_reg(pi, 0x4b5) & (0xffff << 0)) >> 0; - rfgain1 = (read_phy_reg(pi, 0x4fb) & (0x7fff << 0)) >> 0; - - gains->gm_gain = rfgain0 & 0xff; - gains->pga_gain = (rfgain0 >> 8) & 0xff; - gains->pad_gain = rfgain1 & 0xff; - } -} - -void wlc_lcnphy_set_tx_iqcc(phy_info_t *pi, u16 a, u16 b) -{ - phytbl_info_t tab; - u16 iqcc[2]; - - iqcc[0] = a; - iqcc[1] = b; - - tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL; - tab.tbl_width = 16; - tab.tbl_ptr = iqcc; - tab.tbl_len = 2; - tab.tbl_offset = 80; - wlc_lcnphy_write_table(pi, &tab); -} - -void wlc_lcnphy_set_tx_locc(phy_info_t *pi, u16 didq) -{ - phytbl_info_t tab; - - tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL; - tab.tbl_width = 16; - tab.tbl_ptr = &didq; - tab.tbl_len = 1; - tab.tbl_offset = 85; - wlc_lcnphy_write_table(pi, &tab); -} - -void wlc_lcnphy_set_tx_pwr_by_index(phy_info_t *pi, int index) -{ - phytbl_info_t tab; - u16 a, b; - u8 bb_mult; - u32 bbmultiqcomp, txgain, locoeffs, rfpower; - lcnphy_txgains_t gains; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - ASSERT(index <= LCNPHY_MAX_TX_POWER_INDEX); - - pi_lcn->lcnphy_tx_power_idx_override = (s8) index; - pi_lcn->lcnphy_current_index = (u8) index; - - tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; - tab.tbl_width = 32; - tab.tbl_len = 1; - - wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); - - tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index; - tab.tbl_ptr = &bbmultiqcomp; - wlc_lcnphy_read_table(pi, &tab); - - tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index; - tab.tbl_width = 32; - tab.tbl_ptr = &txgain; - wlc_lcnphy_read_table(pi, &tab); - - gains.gm_gain = (u16) (txgain & 0xff); - gains.pga_gain = (u16) (txgain >> 8) & 0xff; - gains.pad_gain = (u16) (txgain >> 16) & 0xff; - gains.dac_gain = (u16) (bbmultiqcomp >> 28) & 0x07; - wlc_lcnphy_set_tx_gain(pi, &gains); - wlc_lcnphy_set_pa_gain(pi, (u16) (txgain >> 24) & 0x7f); - - bb_mult = (u8) ((bbmultiqcomp >> 20) & 0xff); - wlc_lcnphy_set_bbmult(pi, bb_mult); - - wlc_lcnphy_enable_tx_gain_override(pi); - - if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) { - - a = (u16) ((bbmultiqcomp >> 10) & 0x3ff); - b = (u16) (bbmultiqcomp & 0x3ff); - wlc_lcnphy_set_tx_iqcc(pi, a, b); - - tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + index; - tab.tbl_ptr = &locoeffs; - wlc_lcnphy_read_table(pi, &tab); - - wlc_lcnphy_set_tx_locc(pi, (u16) locoeffs); - - tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index; - tab.tbl_ptr = &rfpower; - wlc_lcnphy_read_table(pi, &tab); - mod_phy_reg(pi, 0x6a6, (0x1fff << 0), (rfpower * 8) << 0); - - } -} - -static void wlc_lcnphy_set_trsw_override(phy_info_t *pi, bool tx, bool rx) -{ - - mod_phy_reg(pi, 0x44d, - (0x1 << 1) | - (0x1 << 0), (tx ? (0x1 << 1) : 0) | (rx ? (0x1 << 0) : 0)); - - or_phy_reg(pi, 0x44c, (0x1 << 1) | (0x1 << 0)); -} - -static void wlc_lcnphy_clear_papd_comptable(phy_info_t *pi) -{ - u32 j; - phytbl_info_t tab; - u32 temp_offset[128]; - tab.tbl_ptr = temp_offset; - tab.tbl_len = 128; - tab.tbl_id = LCNPHY_TBL_ID_PAPDCOMPDELTATBL; - tab.tbl_width = 32; - tab.tbl_offset = 0; - - memset(temp_offset, 0, sizeof(temp_offset)); - for (j = 1; j < 128; j += 2) - temp_offset[j] = 0x80000; - - wlc_lcnphy_write_table(pi, &tab); - return; -} - -static void -wlc_lcnphy_set_rx_gain_by_distribution(phy_info_t *pi, - u16 trsw, - u16 ext_lna, - u16 biq2, - u16 biq1, - u16 tia, u16 lna2, u16 lna1) -{ - u16 gain0_15, gain16_19; - - gain16_19 = biq2 & 0xf; - gain0_15 = ((biq1 & 0xf) << 12) | - ((tia & 0xf) << 8) | - ((lna2 & 0x3) << 6) | - ((lna2 & 0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0); - - mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0); - mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0); - mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11); - - if (LCNREV_LT(pi->pubpi.phy_rev, 2)) { - mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9); - mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10); - } else { - mod_phy_reg(pi, 0x4b1, (0x1 << 10), 0 << 10); - - mod_phy_reg(pi, 0x4b1, (0x1 << 15), 0 << 15); - - mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9); - } - - mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0); - -} - -static void wlc_lcnphy_rx_gain_override_enable(phy_info_t *pi, bool enable) -{ - u16 ebit = enable ? 1 : 0; - - mod_phy_reg(pi, 0x4b0, (0x1 << 8), ebit << 8); - - mod_phy_reg(pi, 0x44c, (0x1 << 0), ebit << 0); - - if (LCNREV_LT(pi->pubpi.phy_rev, 2)) { - mod_phy_reg(pi, 0x44c, (0x1 << 4), ebit << 4); - mod_phy_reg(pi, 0x44c, (0x1 << 6), ebit << 6); - mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5); - mod_phy_reg(pi, 0x4b0, (0x1 << 6), ebit << 6); - } else { - mod_phy_reg(pi, 0x4b0, (0x1 << 12), ebit << 12); - mod_phy_reg(pi, 0x4b0, (0x1 << 13), ebit << 13); - mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5); - } - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - mod_phy_reg(pi, 0x4b0, (0x1 << 10), ebit << 10); - mod_phy_reg(pi, 0x4e5, (0x1 << 3), ebit << 3); - } -} - -void wlc_lcnphy_tx_pu(phy_info_t *pi, bool bEnable) -{ - if (!bEnable) { - - and_phy_reg(pi, 0x43b, ~(u16) ((0x1 << 1) | (0x1 << 4))); - - mod_phy_reg(pi, 0x43c, (0x1 << 1), 1 << 1); - - and_phy_reg(pi, 0x44c, - ~(u16) ((0x1 << 3) | - (0x1 << 5) | - (0x1 << 12) | - (0x1 << 0) | (0x1 << 1) | (0x1 << 2))); - - and_phy_reg(pi, 0x44d, - ~(u16) ((0x1 << 3) | (0x1 << 5) | (0x1 << 14))); - mod_phy_reg(pi, 0x44d, (0x1 << 2), 1 << 2); - - mod_phy_reg(pi, 0x44d, (0x1 << 1) | (0x1 << 0), (0x1 << 0)); - - and_phy_reg(pi, 0x4f9, - ~(u16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2))); - - and_phy_reg(pi, 0x4fa, - ~(u16) ((0x1 << 0) | (0x1 << 1) | (0x1 << 2))); - } else { - - mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); - - mod_phy_reg(pi, 0x43b, (0x1 << 4), 1 << 4); - mod_phy_reg(pi, 0x43c, (0x1 << 6), 0 << 6); - - mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12); - mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14); - - wlc_lcnphy_set_trsw_override(pi, true, false); - - mod_phy_reg(pi, 0x44d, (0x1 << 2), 0 << 2); - mod_phy_reg(pi, 0x44c, (0x1 << 2), 1 << 2); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - - mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3); - mod_phy_reg(pi, 0x44d, (0x1 << 3), 1 << 3); - - mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5); - mod_phy_reg(pi, 0x44d, (0x1 << 5), 0 << 5); - - mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x4fa, (0x1 << 1), 1 << 1); - - mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2); - mod_phy_reg(pi, 0x4fa, (0x1 << 2), 1 << 2); - - mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x4fa, (0x1 << 0), 1 << 0); - } else { - - mod_phy_reg(pi, 0x44c, (0x1 << 3), 1 << 3); - mod_phy_reg(pi, 0x44d, (0x1 << 3), 0 << 3); - - mod_phy_reg(pi, 0x44c, (0x1 << 5), 1 << 5); - mod_phy_reg(pi, 0x44d, (0x1 << 5), 1 << 5); - - mod_phy_reg(pi, 0x4f9, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x4fa, (0x1 << 1), 0 << 1); - - mod_phy_reg(pi, 0x4f9, (0x1 << 2), 1 << 2); - mod_phy_reg(pi, 0x4fa, (0x1 << 2), 0 << 2); - - mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0); - } - } -} - -static void -wlc_lcnphy_run_samples(phy_info_t *pi, - u16 num_samps, - u16 num_loops, u16 wait, bool iqcalmode) -{ - - or_phy_reg(pi, 0x6da, 0x8080); - - mod_phy_reg(pi, 0x642, (0x7f << 0), (num_samps - 1) << 0); - if (num_loops != 0xffff) - num_loops--; - mod_phy_reg(pi, 0x640, (0xffff << 0), num_loops << 0); - - mod_phy_reg(pi, 0x641, (0xffff << 0), wait << 0); - - if (iqcalmode) { - - and_phy_reg(pi, 0x453, (u16) ~(0x1 << 15)); - or_phy_reg(pi, 0x453, (0x1 << 15)); - } else { - write_phy_reg(pi, 0x63f, 1); - wlc_lcnphy_tx_pu(pi, 1); - } - - or_radio_reg(pi, RADIO_2064_REG112, 0x6); -} - -void wlc_lcnphy_deaf_mode(phy_info_t *pi, bool mode) -{ - - u8 phybw40; - phybw40 = CHSPEC_IS40(pi->radio_chanspec); - - if (LCNREV_LT(pi->pubpi.phy_rev, 2)) { - mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5); - mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9); - } else { - mod_phy_reg(pi, 0x4b0, (0x1 << 5), (mode) << 5); - mod_phy_reg(pi, 0x4b1, (0x1 << 9), 0 << 9); - } - - if (phybw40 == 0) { - mod_phy_reg((pi), 0x410, - (0x1 << 6) | - (0x1 << 5), - ((CHSPEC_IS2G(pi->radio_chanspec)) ? (!mode) : 0) << - 6 | (!mode) << 5); - mod_phy_reg(pi, 0x410, (0x1 << 7), (mode) << 7); - } -} - -void -wlc_lcnphy_start_tx_tone(phy_info_t *pi, s32 f_kHz, u16 max_val, - bool iqcalmode) -{ - u8 phy_bw; - u16 num_samps, t, k; - u32 bw; - fixed theta = 0, rot = 0; - cs32 tone_samp; - u32 data_buf[64]; - u16 i_samp, q_samp; - phytbl_info_t tab; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - pi->phy_tx_tone_freq = f_kHz; - - wlc_lcnphy_deaf_mode(pi, true); - - phy_bw = 40; - if (pi_lcn->lcnphy_spurmod) { - write_phy_reg(pi, 0x942, 0x2); - write_phy_reg(pi, 0x93b, 0x0); - write_phy_reg(pi, 0x93c, 0x0); - wlc_lcnphy_txrx_spur_avoidance_mode(pi, false); - } - - if (f_kHz) { - k = 1; - do { - bw = phy_bw * 1000 * k; - num_samps = bw / ABS(f_kHz); - ASSERT(num_samps <= ARRAY_SIZE(data_buf)); - k++; - } while ((num_samps * (u32) (ABS(f_kHz))) != bw); - } else - num_samps = 2; - - rot = FIXED((f_kHz * 36) / phy_bw) / 100; - theta = 0; - - for (t = 0; t < num_samps; t++) { - - wlc_phy_cordic(theta, &tone_samp); - - theta += rot; - - i_samp = (u16) (FLOAT(tone_samp.i * max_val) & 0x3ff); - q_samp = (u16) (FLOAT(tone_samp.q * max_val) & 0x3ff); - data_buf[t] = (i_samp << 10) | q_samp; - } - - mod_phy_reg(pi, 0x6d6, (0x3 << 0), 0 << 0); - - mod_phy_reg(pi, 0x6da, (0x1 << 3), 1 << 3); - - tab.tbl_ptr = data_buf; - tab.tbl_len = num_samps; - tab.tbl_id = LCNPHY_TBL_ID_SAMPLEPLAY; - tab.tbl_offset = 0; - tab.tbl_width = 32; - wlc_lcnphy_write_table(pi, &tab); - - wlc_lcnphy_run_samples(pi, num_samps, 0xffff, 0, iqcalmode); -} - -void wlc_lcnphy_stop_tx_tone(phy_info_t *pi) -{ - s16 playback_status; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - pi->phy_tx_tone_freq = 0; - if (pi_lcn->lcnphy_spurmod) { - write_phy_reg(pi, 0x942, 0x7); - write_phy_reg(pi, 0x93b, 0x2017); - write_phy_reg(pi, 0x93c, 0x27c5); - wlc_lcnphy_txrx_spur_avoidance_mode(pi, true); - } - - playback_status = read_phy_reg(pi, 0x644); - if (playback_status & (0x1 << 0)) { - wlc_lcnphy_tx_pu(pi, 0); - mod_phy_reg(pi, 0x63f, (0x1 << 1), 1 << 1); - } else if (playback_status & (0x1 << 1)) - mod_phy_reg(pi, 0x453, (0x1 << 15), 0 << 15); - - mod_phy_reg(pi, 0x6d6, (0x3 << 0), 1 << 0); - - mod_phy_reg(pi, 0x6da, (0x1 << 3), 0 << 3); - - mod_phy_reg(pi, 0x6da, (0x1 << 7), 0 << 7); - - and_radio_reg(pi, RADIO_2064_REG112, 0xFFF9); - - wlc_lcnphy_deaf_mode(pi, false); -} - -static void wlc_lcnphy_clear_trsw_override(phy_info_t *pi) -{ - - and_phy_reg(pi, 0x44c, (u16) ~((0x1 << 1) | (0x1 << 0))); -} - -void wlc_lcnphy_get_tx_iqcc(phy_info_t *pi, u16 *a, u16 *b) -{ - u16 iqcc[2]; - phytbl_info_t tab; - - tab.tbl_ptr = iqcc; - tab.tbl_len = 2; - tab.tbl_id = 0; - tab.tbl_offset = 80; - tab.tbl_width = 16; - wlc_lcnphy_read_table(pi, &tab); - - *a = iqcc[0]; - *b = iqcc[1]; -} - -u16 wlc_lcnphy_get_tx_locc(phy_info_t *pi) -{ - phytbl_info_t tab; - u16 didq; - - tab.tbl_id = 0; - tab.tbl_width = 16; - tab.tbl_ptr = &didq; - tab.tbl_len = 1; - tab.tbl_offset = 85; - wlc_lcnphy_read_table(pi, &tab); - - return didq; -} - -static void wlc_lcnphy_txpwrtbl_iqlo_cal(phy_info_t *pi) -{ - - lcnphy_txgains_t target_gains, old_gains; - u8 save_bb_mult; - u16 a, b, didq, save_pa_gain = 0; - uint idx, SAVE_txpwrindex = 0xFF; - u32 val; - u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); - phytbl_info_t tab; - u8 ei0, eq0, fi0, fq0; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - wlc_lcnphy_get_tx_gain(pi, &old_gains); - save_pa_gain = wlc_lcnphy_get_pa_gain(pi); - - save_bb_mult = wlc_lcnphy_get_bbmult(pi); - - if (SAVE_txpwrctrl == LCNPHY_TX_PWR_CTRL_OFF) - SAVE_txpwrindex = wlc_lcnphy_get_current_tx_pwr_idx(pi); - - wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); - - target_gains.gm_gain = 7; - target_gains.pga_gain = 0; - target_gains.pad_gain = 21; - target_gains.dac_gain = 0; - wlc_lcnphy_set_tx_gain(pi, &target_gains); - wlc_lcnphy_set_tx_pwr_by_index(pi, 16); - - if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) { - - wlc_lcnphy_set_tx_pwr_by_index(pi, 30); - - wlc_lcnphy_tx_iqlo_cal(pi, &target_gains, - (pi_lcn-> - lcnphy_recal ? LCNPHY_CAL_RECAL : - LCNPHY_CAL_FULL), false); - } else { - - wlc_lcnphy_tx_iqlo_soft_cal_full(pi); - } - - wlc_lcnphy_get_radio_loft(pi, &ei0, &eq0, &fi0, &fq0); - if ((ABS((s8) fi0) == 15) && (ABS((s8) fq0) == 15)) { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - target_gains.gm_gain = 255; - target_gains.pga_gain = 255; - target_gains.pad_gain = 0xf0; - target_gains.dac_gain = 0; - } else { - target_gains.gm_gain = 7; - target_gains.pga_gain = 45; - target_gains.pad_gain = 186; - target_gains.dac_gain = 0; - } - - if (LCNREV_IS(pi->pubpi.phy_rev, 1) - || pi_lcn->lcnphy_hw_iqcal_en) { - - target_gains.pga_gain = 0; - target_gains.pad_gain = 30; - wlc_lcnphy_set_tx_pwr_by_index(pi, 16); - wlc_lcnphy_tx_iqlo_cal(pi, &target_gains, - LCNPHY_CAL_FULL, false); - } else { - - wlc_lcnphy_tx_iqlo_soft_cal_full(pi); - } - - } - - wlc_lcnphy_get_tx_iqcc(pi, &a, &b); - - didq = wlc_lcnphy_get_tx_locc(pi); - - tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; - tab.tbl_width = 32; - tab.tbl_ptr = &val; - - tab.tbl_len = 1; - tab.tbl_offset = LCNPHY_TX_PWR_CTRL_RATE_OFFSET; - - for (idx = 0; idx < 128; idx++) { - tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + idx; - - wlc_lcnphy_read_table(pi, &tab); - val = (val & 0xfff00000) | - ((u32) (a & 0x3FF) << 10) | (b & 0x3ff); - wlc_lcnphy_write_table(pi, &tab); - - val = didq; - tab.tbl_offset = LCNPHY_TX_PWR_CTRL_LO_OFFSET + idx; - wlc_lcnphy_write_table(pi, &tab); - } - - pi_lcn->lcnphy_cal_results.txiqlocal_a = a; - pi_lcn->lcnphy_cal_results.txiqlocal_b = b; - pi_lcn->lcnphy_cal_results.txiqlocal_didq = didq; - pi_lcn->lcnphy_cal_results.txiqlocal_ei0 = ei0; - pi_lcn->lcnphy_cal_results.txiqlocal_eq0 = eq0; - pi_lcn->lcnphy_cal_results.txiqlocal_fi0 = fi0; - pi_lcn->lcnphy_cal_results.txiqlocal_fq0 = fq0; - - wlc_lcnphy_set_bbmult(pi, save_bb_mult); - wlc_lcnphy_set_pa_gain(pi, save_pa_gain); - wlc_lcnphy_set_tx_gain(pi, &old_gains); - - if (SAVE_txpwrctrl != LCNPHY_TX_PWR_CTRL_OFF) - wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl); - else - wlc_lcnphy_set_tx_pwr_by_index(pi, SAVE_txpwrindex); -} - -s16 wlc_lcnphy_tempsense_new(phy_info_t *pi, bool mode) -{ - u16 tempsenseval1, tempsenseval2; - s16 avg = 0; - bool suspend = 0; - - if (NORADIO_ENAB(pi->pubpi)) - return -1; - - if (mode == 1) { - suspend = - (0 == - (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); - if (!suspend) - wlapi_suspend_mac_and_wait(pi->sh->physhim); - wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE); - } - tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF; - tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF; - - if (tempsenseval1 > 255) - avg = (s16) (tempsenseval1 - 512); - else - avg = (s16) tempsenseval1; - - if (tempsenseval2 > 255) - avg += (s16) (tempsenseval2 - 512); - else - avg += (s16) tempsenseval2; - - avg /= 2; - - if (mode == 1) { - - mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14); - - udelay(100); - mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14); - - if (!suspend) - wlapi_enable_mac(pi->sh->physhim); - } - return avg; -} - -u16 wlc_lcnphy_tempsense(phy_info_t *pi, bool mode) -{ - u16 tempsenseval1, tempsenseval2; - s32 avg = 0; - bool suspend = 0; - u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - if (NORADIO_ENAB(pi->pubpi)) - return -1; - - if (mode == 1) { - suspend = - (0 == - (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); - if (!suspend) - wlapi_suspend_mac_and_wait(pi->sh->physhim); - wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE); - } - tempsenseval1 = read_phy_reg(pi, 0x476) & 0x1FF; - tempsenseval2 = read_phy_reg(pi, 0x477) & 0x1FF; - - if (tempsenseval1 > 255) - avg = (int)(tempsenseval1 - 512); - else - avg = (int)tempsenseval1; - - if (pi_lcn->lcnphy_tempsense_option == 1 || pi->hwpwrctrl_capable) { - if (tempsenseval2 > 255) - avg = (int)(avg - tempsenseval2 + 512); - else - avg = (int)(avg - tempsenseval2); - } else { - if (tempsenseval2 > 255) - avg = (int)(avg + tempsenseval2 - 512); - else - avg = (int)(avg + tempsenseval2); - avg = avg / 2; - } - if (avg < 0) - avg = avg + 512; - - if (pi_lcn->lcnphy_tempsense_option == 2) - avg = tempsenseval1; - - if (mode) - wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl); - - if (mode == 1) { - - mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14); - - udelay(100); - mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14); - - if (!suspend) - wlapi_enable_mac(pi->sh->physhim); - } - return (u16) avg; -} - -s8 wlc_lcnphy_tempsense_degree(phy_info_t *pi, bool mode) -{ - s32 degree = wlc_lcnphy_tempsense_new(pi, mode); - degree = - ((degree << 10) + LCN_TEMPSENSE_OFFSET + (LCN_TEMPSENSE_DEN >> 1)) - / LCN_TEMPSENSE_DEN; - return (s8) degree; -} - -s8 wlc_lcnphy_vbatsense(phy_info_t *pi, bool mode) -{ - u16 vbatsenseval; - s32 avg = 0; - bool suspend = 0; - - if (NORADIO_ENAB(pi->pubpi)) - return -1; - - if (mode == 1) { - suspend = - (0 == - (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); - if (!suspend) - wlapi_suspend_mac_and_wait(pi->sh->physhim); - wlc_lcnphy_vbat_temp_sense_setup(pi, VBATSENSE); - } - - vbatsenseval = read_phy_reg(pi, 0x475) & 0x1FF; - - if (vbatsenseval > 255) - avg = (s32) (vbatsenseval - 512); - else - avg = (s32) vbatsenseval; - - avg = - (avg * LCN_VBAT_SCALE_NOM + - (LCN_VBAT_SCALE_DEN >> 1)) / LCN_VBAT_SCALE_DEN; - - if (mode == 1) { - if (!suspend) - wlapi_enable_mac(pi->sh->physhim); - } - return (s8) avg; -} - -static void wlc_lcnphy_afe_clk_init(phy_info_t *pi, u8 mode) -{ - u8 phybw40; - phybw40 = CHSPEC_IS40(pi->radio_chanspec); - - mod_phy_reg(pi, 0x6d1, (0x1 << 7), (1) << 7); - - if (((mode == AFE_CLK_INIT_MODE_PAPD) && (phybw40 == 0)) || - (mode == AFE_CLK_INIT_MODE_TXRX2X)) - write_phy_reg(pi, 0x6d0, 0x7); - - wlc_lcnphy_toggle_afe_pwdn(pi); -} - -static bool -wlc_lcnphy_rx_iq_est(phy_info_t *pi, - u16 num_samps, - u8 wait_time, lcnphy_iq_est_t *iq_est) -{ - int wait_count = 0; - bool result = true; - u8 phybw40; - phybw40 = CHSPEC_IS40(pi->radio_chanspec); - - mod_phy_reg(pi, 0x6da, (0x1 << 5), (1) << 5); - - mod_phy_reg(pi, 0x410, (0x1 << 3), (0) << 3); - - mod_phy_reg(pi, 0x482, (0xffff << 0), (num_samps) << 0); - - mod_phy_reg(pi, 0x481, (0xff << 0), ((u16) wait_time) << 0); - - mod_phy_reg(pi, 0x481, (0x1 << 8), (0) << 8); - - mod_phy_reg(pi, 0x481, (0x1 << 9), (1) << 9); - - while (read_phy_reg(pi, 0x481) & (0x1 << 9)) { - - if (wait_count > (10 * 500)) { - result = false; - goto cleanup; - } - udelay(100); - wait_count++; - } - - iq_est->iq_prod = ((u32) read_phy_reg(pi, 0x483) << 16) | - (u32) read_phy_reg(pi, 0x484); - iq_est->i_pwr = ((u32) read_phy_reg(pi, 0x485) << 16) | - (u32) read_phy_reg(pi, 0x486); - iq_est->q_pwr = ((u32) read_phy_reg(pi, 0x487) << 16) | - (u32) read_phy_reg(pi, 0x488); - - cleanup: - mod_phy_reg(pi, 0x410, (0x1 << 3), (1) << 3); - - mod_phy_reg(pi, 0x6da, (0x1 << 5), (0) << 5); - - return result; -} - -static bool wlc_lcnphy_calc_rx_iq_comp(phy_info_t *pi, u16 num_samps) -{ -#define LCNPHY_MIN_RXIQ_PWR 2 - bool result; - u16 a0_new, b0_new; - lcnphy_iq_est_t iq_est = { 0, 0, 0 }; - s32 a, b, temp; - s16 iq_nbits, qq_nbits, arsh, brsh; - s32 iq; - u32 ii, qq; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - a0_new = ((read_phy_reg(pi, 0x645) & (0x3ff << 0)) >> 0); - b0_new = ((read_phy_reg(pi, 0x646) & (0x3ff << 0)) >> 0); - mod_phy_reg(pi, 0x6d1, (0x1 << 2), (0) << 2); - - mod_phy_reg(pi, 0x64b, (0x1 << 6), (1) << 6); - - wlc_lcnphy_set_rx_iq_comp(pi, 0, 0); - - result = wlc_lcnphy_rx_iq_est(pi, num_samps, 32, &iq_est); - if (!result) - goto cleanup; - - iq = (s32) iq_est.iq_prod; - ii = iq_est.i_pwr; - qq = iq_est.q_pwr; - - if ((ii + qq) < LCNPHY_MIN_RXIQ_PWR) { - result = false; - goto cleanup; - } - - iq_nbits = wlc_phy_nbits(iq); - qq_nbits = wlc_phy_nbits(qq); - - arsh = 10 - (30 - iq_nbits); - if (arsh >= 0) { - a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh))); - temp = (s32) (ii >> arsh); - if (temp == 0) { - return false; - } - } else { - a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh))); - temp = (s32) (ii << -arsh); - if (temp == 0) { - return false; - } - } - a /= temp; - brsh = qq_nbits - 31 + 20; - if (brsh >= 0) { - b = (qq << (31 - qq_nbits)); - temp = (s32) (ii >> brsh); - if (temp == 0) { - return false; - } - } else { - b = (qq << (31 - qq_nbits)); - temp = (s32) (ii << -brsh); - if (temp == 0) { - return false; - } - } - b /= temp; - b -= a * a; - b = (s32) wlc_phy_sqrt_int((u32) b); - b -= (1 << 10); - a0_new = (u16) (a & 0x3ff); - b0_new = (u16) (b & 0x3ff); - cleanup: - - wlc_lcnphy_set_rx_iq_comp(pi, a0_new, b0_new); - - mod_phy_reg(pi, 0x64b, (0x1 << 0), (1) << 0); - - mod_phy_reg(pi, 0x64b, (0x1 << 3), (1) << 3); - - pi_lcn->lcnphy_cal_results.rxiqcal_coeff_a0 = a0_new; - pi_lcn->lcnphy_cal_results.rxiqcal_coeff_b0 = b0_new; - - return result; -} - -static bool -wlc_lcnphy_rx_iq_cal(phy_info_t *pi, const lcnphy_rx_iqcomp_t *iqcomp, - int iqcomp_sz, bool tx_switch, bool rx_switch, int module, - int tx_gain_idx) -{ - lcnphy_txgains_t old_gains; - u16 tx_pwr_ctrl; - u8 tx_gain_index_old = 0; - bool result = false, tx_gain_override_old = false; - u16 i, Core1TxControl_old, RFOverride0_old, - RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old, - rfoverride3_old, rfoverride3val_old, rfoverride4_old, - rfoverride4val_old, afectrlovr_old, afectrlovrval_old; - int tia_gain; - u32 received_power, rx_pwr_threshold; - u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl; - u16 values_to_save[11]; - s16 *ptr; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC); - if (NULL == ptr) { - return false; - } - if (module == 2) { - ASSERT(iqcomp_sz); - - while (iqcomp_sz--) { - if (iqcomp[iqcomp_sz].chan == - CHSPEC_CHANNEL(pi->radio_chanspec)) { - - wlc_lcnphy_set_rx_iq_comp(pi, - (u16) - iqcomp[iqcomp_sz].a, - (u16) - iqcomp[iqcomp_sz].b); - result = true; - break; - } - } - ASSERT(result); - goto cal_done; - } - - if (module == 1) { - - tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); - wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); - - for (i = 0; i < 11; i++) { - values_to_save[i] = - read_radio_reg(pi, rxiq_cal_rf_reg[i]); - } - Core1TxControl_old = read_phy_reg(pi, 0x631); - - or_phy_reg(pi, 0x631, 0x0015); - - RFOverride0_old = read_phy_reg(pi, 0x44c); - RFOverrideVal0_old = read_phy_reg(pi, 0x44d); - rfoverride2_old = read_phy_reg(pi, 0x4b0); - rfoverride2val_old = read_phy_reg(pi, 0x4b1); - rfoverride3_old = read_phy_reg(pi, 0x4f9); - rfoverride3val_old = read_phy_reg(pi, 0x4fa); - rfoverride4_old = read_phy_reg(pi, 0x938); - rfoverride4val_old = read_phy_reg(pi, 0x939); - afectrlovr_old = read_phy_reg(pi, 0x43b); - afectrlovrval_old = read_phy_reg(pi, 0x43c); - old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); - old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db); - - tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi); - if (tx_gain_override_old) { - wlc_lcnphy_get_tx_gain(pi, &old_gains); - tx_gain_index_old = pi_lcn->lcnphy_current_index; - } - - wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx); - - mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0); - - mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); - - write_radio_reg(pi, RADIO_2064_REG116, 0x06); - write_radio_reg(pi, RADIO_2064_REG12C, 0x07); - write_radio_reg(pi, RADIO_2064_REG06A, 0xd3); - write_radio_reg(pi, RADIO_2064_REG098, 0x03); - write_radio_reg(pi, RADIO_2064_REG00B, 0x7); - mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4); - write_radio_reg(pi, RADIO_2064_REG01D, 0x01); - write_radio_reg(pi, RADIO_2064_REG114, 0x01); - write_radio_reg(pi, RADIO_2064_REG02E, 0x10); - write_radio_reg(pi, RADIO_2064_REG12A, 0x08); - - mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0); - mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2); - mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2); - mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3); - mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3); - mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5); - mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5); - - mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0); - - wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0); - write_phy_reg(pi, 0x6da, 0xffff); - or_phy_reg(pi, 0x6db, 0x3); - wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch); - wlc_lcnphy_rx_gain_override_enable(pi, true); - - tia_gain = 8; - rx_pwr_threshold = 950; - while (tia_gain > 0) { - tia_gain -= 1; - wlc_lcnphy_set_rx_gain_by_distribution(pi, - 0, 0, 2, 2, - (u16) - tia_gain, 1, 0); - udelay(500); - - received_power = - wlc_lcnphy_measure_digital_power(pi, 2000); - if (received_power < rx_pwr_threshold) - break; - } - result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff); - - wlc_lcnphy_stop_tx_tone(pi); - - write_phy_reg(pi, 0x631, Core1TxControl_old); - - write_phy_reg(pi, 0x44c, RFOverrideVal0_old); - write_phy_reg(pi, 0x44d, RFOverrideVal0_old); - write_phy_reg(pi, 0x4b0, rfoverride2_old); - write_phy_reg(pi, 0x4b1, rfoverride2val_old); - write_phy_reg(pi, 0x4f9, rfoverride3_old); - write_phy_reg(pi, 0x4fa, rfoverride3val_old); - write_phy_reg(pi, 0x938, rfoverride4_old); - write_phy_reg(pi, 0x939, rfoverride4val_old); - write_phy_reg(pi, 0x43b, afectrlovr_old); - write_phy_reg(pi, 0x43c, afectrlovrval_old); - write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl); - write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl); - - wlc_lcnphy_clear_trsw_override(pi); - - mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2); - - for (i = 0; i < 11; i++) { - write_radio_reg(pi, rxiq_cal_rf_reg[i], - values_to_save[i]); - } - - if (tx_gain_override_old) { - wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old); - } else - wlc_lcnphy_disable_tx_gain_override(pi); - wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl); - - wlc_lcnphy_rx_gain_override_enable(pi, false); - } - - cal_done: - kfree(ptr); - return result; -} - -static void wlc_lcnphy_temp_adj(phy_info_t *pi) -{ - if (NORADIO_ENAB(pi->pubpi)) - return; -} - -static void wlc_lcnphy_glacial_timer_based_cal(phy_info_t *pi) -{ - bool suspend; - s8 index; - u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - suspend = - (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); - if (!suspend) - wlapi_suspend_mac_and_wait(pi->sh->physhim); - wlc_lcnphy_deaf_mode(pi, true); - pi->phy_lastcal = pi->sh->now; - pi->phy_forcecal = false; - index = pi_lcn->lcnphy_current_index; - - wlc_lcnphy_txpwrtbl_iqlo_cal(pi); - - wlc_lcnphy_set_tx_pwr_by_index(pi, index); - wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl); - wlc_lcnphy_deaf_mode(pi, false); - if (!suspend) - wlapi_enable_mac(pi->sh->physhim); - -} - -static void wlc_lcnphy_periodic_cal(phy_info_t *pi) -{ - bool suspend, full_cal; - const lcnphy_rx_iqcomp_t *rx_iqcomp; - int rx_iqcomp_sz; - u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); - s8 index; - phytbl_info_t tab; - s32 a1, b0, b1; - s32 tssi, pwr, maxtargetpwr, mintargetpwr; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - if (NORADIO_ENAB(pi->pubpi)) - return; - - pi->phy_lastcal = pi->sh->now; - pi->phy_forcecal = false; - full_cal = - (pi_lcn->lcnphy_full_cal_channel != - CHSPEC_CHANNEL(pi->radio_chanspec)); - pi_lcn->lcnphy_full_cal_channel = CHSPEC_CHANNEL(pi->radio_chanspec); - index = pi_lcn->lcnphy_current_index; - - suspend = - (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); - if (!suspend) { - - wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000); - wlapi_suspend_mac_and_wait(pi->sh->physhim); - } - wlc_lcnphy_deaf_mode(pi, true); - - wlc_lcnphy_txpwrtbl_iqlo_cal(pi); - - rx_iqcomp = lcnphy_rx_iqcomp_table_rev0; - rx_iqcomp_sz = ARRAY_SIZE(lcnphy_rx_iqcomp_table_rev0); - - if (LCNREV_IS(pi->pubpi.phy_rev, 1)) - wlc_lcnphy_rx_iq_cal(pi, NULL, 0, true, false, 1, 40); - else - wlc_lcnphy_rx_iq_cal(pi, NULL, 0, true, false, 1, 127); - - if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) { - - wlc_lcnphy_idle_tssi_est((wlc_phy_t *) pi); - - b0 = pi->txpa_2g[0]; - b1 = pi->txpa_2g[1]; - a1 = pi->txpa_2g[2]; - maxtargetpwr = wlc_lcnphy_tssi2dbm(10, a1, b0, b1); - mintargetpwr = wlc_lcnphy_tssi2dbm(125, a1, b0, b1); - - tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; - tab.tbl_width = 32; - tab.tbl_ptr = &pwr; - tab.tbl_len = 1; - tab.tbl_offset = 0; - for (tssi = 0; tssi < 128; tssi++) { - pwr = wlc_lcnphy_tssi2dbm(tssi, a1, b0, b1); - pwr = (pwr < mintargetpwr) ? mintargetpwr : pwr; - wlc_lcnphy_write_table(pi, &tab); - tab.tbl_offset++; - } - } - - wlc_lcnphy_set_tx_pwr_by_index(pi, index); - wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_pwrctrl); - wlc_lcnphy_deaf_mode(pi, false); - if (!suspend) - wlapi_enable_mac(pi->sh->physhim); -} - -void wlc_lcnphy_calib_modes(phy_info_t *pi, uint mode) -{ - u16 temp_new; - int temp1, temp2, temp_diff; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - switch (mode) { - case PHY_PERICAL_CHAN: - - break; - case PHY_FULLCAL: - wlc_lcnphy_periodic_cal(pi); - break; - case PHY_PERICAL_PHYINIT: - wlc_lcnphy_periodic_cal(pi); - break; - case PHY_PERICAL_WATCHDOG: - if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) { - temp_new = wlc_lcnphy_tempsense(pi, 0); - temp1 = LCNPHY_TEMPSENSE(temp_new); - temp2 = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_cal_temper); - temp_diff = temp1 - temp2; - if ((pi_lcn->lcnphy_cal_counter > 90) || - (temp_diff > 60) || (temp_diff < -60)) { - wlc_lcnphy_glacial_timer_based_cal(pi); - wlc_2064_vco_cal(pi); - pi_lcn->lcnphy_cal_temper = temp_new; - pi_lcn->lcnphy_cal_counter = 0; - } else - pi_lcn->lcnphy_cal_counter++; - } - break; - case LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL: - if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) - wlc_lcnphy_tx_power_adjustment((wlc_phy_t *) pi); - break; - default: - ASSERT(0); - break; - } -} - -void wlc_lcnphy_get_tssi(phy_info_t *pi, s8 *ofdm_pwr, s8 *cck_pwr) -{ - s8 cck_offset; - u16 status; - status = (read_phy_reg(pi, 0x4ab)); - if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) && - (status & (0x1 << 15))) { - *ofdm_pwr = (s8) (((read_phy_reg(pi, 0x4ab) & (0x1ff << 0)) - >> 0) >> 1); - - if (wlc_phy_tpc_isenabled_lcnphy(pi)) - cck_offset = pi->tx_power_offset[TXP_FIRST_CCK]; - else - cck_offset = 0; - - *cck_pwr = *ofdm_pwr + cck_offset; - } else { - *cck_pwr = 0; - *ofdm_pwr = 0; - } -} - -void WLBANDINITFN(wlc_phy_cal_init_lcnphy) (phy_info_t *pi) -{ - return; - -} - -static void wlc_lcnphy_set_chanspec_tweaks(phy_info_t *pi, chanspec_t chanspec) -{ - u8 channel = CHSPEC_CHANNEL(chanspec); - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - if (NORADIO_ENAB(pi->pubpi)) - return; - - if (channel == 14) { - mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8); - - } else { - mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8); - - } - pi_lcn->lcnphy_bandedge_corr = 2; - if (channel == 1) - pi_lcn->lcnphy_bandedge_corr = 4; - - if (channel == 1 || channel == 2 || channel == 3 || - channel == 4 || channel == 9 || - channel == 10 || channel == 11 || channel == 12) { - si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03000c04); - si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x0); - si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x200005c0); - - si_pmu_pllupd(pi->sh->sih); - write_phy_reg(pi, 0x942, 0); - wlc_lcnphy_txrx_spur_avoidance_mode(pi, false); - pi_lcn->lcnphy_spurmod = 0; - mod_phy_reg(pi, 0x424, (0xff << 8), (0x1b) << 8); - - write_phy_reg(pi, 0x425, 0x5907); - } else { - si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03140c04); - si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x333333); - si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x202c2820); - - si_pmu_pllupd(pi->sh->sih); - write_phy_reg(pi, 0x942, 0); - wlc_lcnphy_txrx_spur_avoidance_mode(pi, true); - - pi_lcn->lcnphy_spurmod = 0; - mod_phy_reg(pi, 0x424, (0xff << 8), (0x1f) << 8); - - write_phy_reg(pi, 0x425, 0x590a); - } - - or_phy_reg(pi, 0x44a, 0x44); - write_phy_reg(pi, 0x44a, 0x80); -} - -void wlc_lcnphy_tx_power_adjustment(wlc_phy_t *ppi) -{ - s8 index; - u16 index2; - phy_info_t *pi = (phy_info_t *) ppi; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); - if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) && SAVE_txpwrctrl) { - index = wlc_lcnphy_tempcompensated_txpwrctrl(pi); - index2 = (u16) (index * 2); - mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0); - - pi_lcn->lcnphy_current_index = (s8) - ((read_phy_reg(pi, 0x4a9) & 0xFF) / 2); - } -} - -static void wlc_lcnphy_set_rx_iq_comp(phy_info_t *pi, u16 a, u16 b) -{ - mod_phy_reg(pi, 0x645, (0x3ff << 0), (a) << 0); - - mod_phy_reg(pi, 0x646, (0x3ff << 0), (b) << 0); - - mod_phy_reg(pi, 0x647, (0x3ff << 0), (a) << 0); - - mod_phy_reg(pi, 0x648, (0x3ff << 0), (b) << 0); - - mod_phy_reg(pi, 0x649, (0x3ff << 0), (a) << 0); - - mod_phy_reg(pi, 0x64a, (0x3ff << 0), (b) << 0); - -} - -void WLBANDINITFN(wlc_phy_init_lcnphy) (phy_info_t *pi) -{ - u8 phybw40; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - phybw40 = CHSPEC_IS40(pi->radio_chanspec); - - pi_lcn->lcnphy_cal_counter = 0; - pi_lcn->lcnphy_cal_temper = pi_lcn->lcnphy_rawtempsense; - - or_phy_reg(pi, 0x44a, 0x80); - and_phy_reg(pi, 0x44a, 0x7f); - - wlc_lcnphy_afe_clk_init(pi, AFE_CLK_INIT_MODE_TXRX2X); - - write_phy_reg(pi, 0x60a, 160); - - write_phy_reg(pi, 0x46a, 25); - - wlc_lcnphy_baseband_init(pi); - - wlc_lcnphy_radio_init(pi); - - if (CHSPEC_IS2G(pi->radio_chanspec)) - wlc_lcnphy_tx_pwr_ctrl_init((wlc_phy_t *) pi); - - wlc_phy_chanspec_set((wlc_phy_t *) pi, pi->radio_chanspec); - - si_pmu_regcontrol(pi->sh->sih, 0, 0xf, 0x9); - - si_pmu_chipcontrol(pi->sh->sih, 0, 0xffffffff, 0x03CDDDDD); - - if ((pi->sh->boardflags & BFL_FEM) - && wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) - wlc_lcnphy_set_tx_pwr_by_index(pi, FIXED_TXPWR); - - wlc_lcnphy_agc_temp_init(pi); - - wlc_lcnphy_temp_adj(pi); - - mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14); - - udelay(100); - mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14); - - wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW); - pi_lcn->lcnphy_noise_samples = LCNPHY_NOISE_SAMPLES_DEFAULT; - wlc_lcnphy_calib_modes(pi, PHY_PERICAL_PHYINIT); -} - -static void -wlc_lcnphy_tx_iqlo_loopback(phy_info_t *pi, u16 *values_to_save) -{ - u16 vmid; - int i; - for (i = 0; i < 20; i++) { - values_to_save[i] = - read_radio_reg(pi, iqlo_loopback_rf_regs[i]); - } - - mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12); - mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14); - - mod_phy_reg(pi, 0x44c, (0x1 << 11), 1 << 11); - mod_phy_reg(pi, 0x44d, (0x1 << 13), 0 << 13); - - mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); - - mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0); - - if (LCNREV_IS(pi->pubpi.phy_rev, 2)) - and_radio_reg(pi, RADIO_2064_REG03A, 0xFD); - else - and_radio_reg(pi, RADIO_2064_REG03A, 0xF9); - or_radio_reg(pi, RADIO_2064_REG11A, 0x1); - - or_radio_reg(pi, RADIO_2064_REG036, 0x01); - or_radio_reg(pi, RADIO_2064_REG11A, 0x18); - udelay(20); - - if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { - if (CHSPEC_IS5G(pi->radio_chanspec)) - mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0); - else - or_radio_reg(pi, RADIO_2064_REG03A, 1); - } else { - if (CHSPEC_IS5G(pi->radio_chanspec)) - mod_radio_reg(pi, RADIO_2064_REG03A, 3, 1); - else - or_radio_reg(pi, RADIO_2064_REG03A, 0x3); - } - - udelay(20); - - write_radio_reg(pi, RADIO_2064_REG025, 0xF); - if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { - if (CHSPEC_IS5G(pi->radio_chanspec)) - mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x4); - else - mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x6); - } else { - if (CHSPEC_IS5G(pi->radio_chanspec)) - mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x4 << 1); - else - mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x6 << 1); - } - - udelay(20); - - write_radio_reg(pi, RADIO_2064_REG005, 0x8); - or_radio_reg(pi, RADIO_2064_REG112, 0x80); - udelay(20); - - or_radio_reg(pi, RADIO_2064_REG0FF, 0x10); - or_radio_reg(pi, RADIO_2064_REG11F, 0x44); - udelay(20); - - or_radio_reg(pi, RADIO_2064_REG00B, 0x7); - or_radio_reg(pi, RADIO_2064_REG113, 0x10); - udelay(20); - - write_radio_reg(pi, RADIO_2064_REG007, 0x1); - udelay(20); - - vmid = 0x2A6; - mod_radio_reg(pi, RADIO_2064_REG0FC, 0x3 << 0, (vmid >> 8) & 0x3); - write_radio_reg(pi, RADIO_2064_REG0FD, (vmid & 0xff)); - or_radio_reg(pi, RADIO_2064_REG11F, 0x44); - udelay(20); - - or_radio_reg(pi, RADIO_2064_REG0FF, 0x10); - udelay(20); - write_radio_reg(pi, RADIO_2064_REG012, 0x02); - or_radio_reg(pi, RADIO_2064_REG112, 0x06); - write_radio_reg(pi, RADIO_2064_REG036, 0x11); - write_radio_reg(pi, RADIO_2064_REG059, 0xcc); - write_radio_reg(pi, RADIO_2064_REG05C, 0x2e); - write_radio_reg(pi, RADIO_2064_REG078, 0xd7); - write_radio_reg(pi, RADIO_2064_REG092, 0x15); -} - -static void -wlc_lcnphy_samp_cap(phy_info_t *pi, int clip_detect_algo, u16 thresh, - s16 *ptr, int mode) -{ - u32 curval1, curval2, stpptr, curptr, strptr, val; - u16 sslpnCalibClkEnCtrl, timer; - u16 old_sslpnCalibClkEnCtrl; - s16 imag, real; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - timer = 0; - old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); - - curval1 = R_REG(pi->sh->osh, &pi->regs->psm_corectlsts); - ptr[130] = 0; - W_REG(pi->sh->osh, &pi->regs->psm_corectlsts, ((1 << 6) | curval1)); - - W_REG(pi->sh->osh, &pi->regs->smpl_clct_strptr, 0x7E00); - W_REG(pi->sh->osh, &pi->regs->smpl_clct_stpptr, 0x8000); - udelay(20); - curval2 = R_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param); - W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, curval2 | 0x30); - - write_phy_reg(pi, 0x555, 0x0); - write_phy_reg(pi, 0x5a6, 0x5); - - write_phy_reg(pi, 0x5a2, (u16) (mode | mode << 6)); - write_phy_reg(pi, 0x5cf, 3); - write_phy_reg(pi, 0x5a5, 0x3); - write_phy_reg(pi, 0x583, 0x0); - write_phy_reg(pi, 0x584, 0x0); - write_phy_reg(pi, 0x585, 0x0fff); - write_phy_reg(pi, 0x586, 0x0000); - - write_phy_reg(pi, 0x580, 0x4501); - - sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); - write_phy_reg(pi, 0x6da, (u32) (sslpnCalibClkEnCtrl | 0x2008)); - stpptr = R_REG(pi->sh->osh, &pi->regs->smpl_clct_stpptr); - curptr = R_REG(pi->sh->osh, &pi->regs->smpl_clct_curptr); - do { - udelay(10); - curptr = R_REG(pi->sh->osh, &pi->regs->smpl_clct_curptr); - timer++; - } while ((curptr != stpptr) && (timer < 500)); - - W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, 0x2); - strptr = 0x7E00; - W_REG(pi->sh->osh, &pi->regs->tplatewrptr, strptr); - while (strptr < 0x8000) { - val = R_REG(pi->sh->osh, &pi->regs->tplatewrdata); - imag = ((val >> 16) & 0x3ff); - real = ((val) & 0x3ff); - if (imag > 511) { - imag -= 1024; - } - if (real > 511) { - real -= 1024; - } - if (pi_lcn->lcnphy_iqcal_swp_dis) - ptr[(strptr - 0x7E00) / 4] = real; - else - ptr[(strptr - 0x7E00) / 4] = imag; - if (clip_detect_algo) { - if (imag > thresh || imag < -thresh) { - strptr = 0x8000; - ptr[130] = 1; - } - } - strptr += 4; - } - - write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl); - W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, curval2); - W_REG(pi->sh->osh, &pi->regs->psm_corectlsts, curval1); -} - -static void wlc_lcnphy_tx_iqlo_soft_cal_full(phy_info_t *pi) -{ - lcnphy_unsign16_struct iqcc0, locc2, locc3, locc4; - - wlc_lcnphy_set_cc(pi, 0, 0, 0); - wlc_lcnphy_set_cc(pi, 2, 0, 0); - wlc_lcnphy_set_cc(pi, 3, 0, 0); - wlc_lcnphy_set_cc(pi, 4, 0, 0); - - wlc_lcnphy_a1(pi, 4, 0, 0); - wlc_lcnphy_a1(pi, 3, 0, 0); - wlc_lcnphy_a1(pi, 2, 3, 2); - wlc_lcnphy_a1(pi, 0, 5, 8); - wlc_lcnphy_a1(pi, 2, 2, 1); - wlc_lcnphy_a1(pi, 0, 4, 3); - - iqcc0 = wlc_lcnphy_get_cc(pi, 0); - locc2 = wlc_lcnphy_get_cc(pi, 2); - locc3 = wlc_lcnphy_get_cc(pi, 3); - locc4 = wlc_lcnphy_get_cc(pi, 4); -} - -static void -wlc_lcnphy_set_cc(phy_info_t *pi, int cal_type, s16 coeff_x, s16 coeff_y) -{ - u16 di0dq0; - u16 x, y, data_rf; - int k; - switch (cal_type) { - case 0: - wlc_lcnphy_set_tx_iqcc(pi, coeff_x, coeff_y); - break; - case 2: - di0dq0 = (coeff_x & 0xff) << 8 | (coeff_y & 0xff); - wlc_lcnphy_set_tx_locc(pi, di0dq0); - break; - case 3: - k = wlc_lcnphy_calc_floor(coeff_x, 0); - y = 8 + k; - k = wlc_lcnphy_calc_floor(coeff_x, 1); - x = 8 - k; - data_rf = (x * 16 + y); - write_radio_reg(pi, RADIO_2064_REG089, data_rf); - k = wlc_lcnphy_calc_floor(coeff_y, 0); - y = 8 + k; - k = wlc_lcnphy_calc_floor(coeff_y, 1); - x = 8 - k; - data_rf = (x * 16 + y); - write_radio_reg(pi, RADIO_2064_REG08A, data_rf); - break; - case 4: - k = wlc_lcnphy_calc_floor(coeff_x, 0); - y = 8 + k; - k = wlc_lcnphy_calc_floor(coeff_x, 1); - x = 8 - k; - data_rf = (x * 16 + y); - write_radio_reg(pi, RADIO_2064_REG08B, data_rf); - k = wlc_lcnphy_calc_floor(coeff_y, 0); - y = 8 + k; - k = wlc_lcnphy_calc_floor(coeff_y, 1); - x = 8 - k; - data_rf = (x * 16 + y); - write_radio_reg(pi, RADIO_2064_REG08C, data_rf); - break; - } -} - -static lcnphy_unsign16_struct wlc_lcnphy_get_cc(phy_info_t *pi, int cal_type) -{ - u16 a, b, didq; - u8 di0, dq0, ei, eq, fi, fq; - lcnphy_unsign16_struct cc; - cc.re = 0; - cc.im = 0; - switch (cal_type) { - case 0: - wlc_lcnphy_get_tx_iqcc(pi, &a, &b); - cc.re = a; - cc.im = b; - break; - case 2: - didq = wlc_lcnphy_get_tx_locc(pi); - di0 = (((didq & 0xff00) << 16) >> 24); - dq0 = (((didq & 0x00ff) << 24) >> 24); - cc.re = (u16) di0; - cc.im = (u16) dq0; - break; - case 3: - wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq); - cc.re = (u16) ei; - cc.im = (u16) eq; - break; - case 4: - wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq); - cc.re = (u16) fi; - cc.im = (u16) fq; - break; - } - return cc; -} - -static void -wlc_lcnphy_a1(phy_info_t *pi, int cal_type, int num_levels, int step_size_lg2) -{ - const lcnphy_spb_tone_t *phy_c1; - lcnphy_spb_tone_t phy_c2; - lcnphy_unsign16_struct phy_c3; - int phy_c4, phy_c5, k, l, j, phy_c6; - u16 phy_c7, phy_c8, phy_c9; - s16 phy_c10, phy_c11, phy_c12, phy_c13, phy_c14, phy_c15, phy_c16; - s16 *ptr, phy_c17; - s32 phy_c18, phy_c19; - u32 phy_c20, phy_c21; - bool phy_c22, phy_c23, phy_c24, phy_c25; - u16 phy_c26, phy_c27; - u16 phy_c28, phy_c29, phy_c30; - u16 phy_c31; - u16 *phy_c32; - phy_c21 = 0; - phy_c10 = phy_c13 = phy_c14 = phy_c8 = 0; - ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC); - if (NULL == ptr) { - return; - } - - phy_c32 = kmalloc(sizeof(u16) * 20, GFP_ATOMIC); - if (NULL == phy_c32) { - return; - } - phy_c26 = read_phy_reg(pi, 0x6da); - phy_c27 = read_phy_reg(pi, 0x6db); - phy_c31 = read_radio_reg(pi, RADIO_2064_REG026); - write_phy_reg(pi, 0x93d, 0xC0); - - wlc_lcnphy_start_tx_tone(pi, 3750, 88, 0); - write_phy_reg(pi, 0x6da, 0xffff); - or_phy_reg(pi, 0x6db, 0x3); - - wlc_lcnphy_tx_iqlo_loopback(pi, phy_c32); - udelay(500); - phy_c28 = read_phy_reg(pi, 0x938); - phy_c29 = read_phy_reg(pi, 0x4d7); - phy_c30 = read_phy_reg(pi, 0x4d8); - or_phy_reg(pi, 0x938, 0x1 << 2); - or_phy_reg(pi, 0x4d7, 0x1 << 2); - or_phy_reg(pi, 0x4d7, 0x1 << 3); - mod_phy_reg(pi, 0x4d7, (0x7 << 12), 0x2 << 12); - or_phy_reg(pi, 0x4d8, 1 << 0); - or_phy_reg(pi, 0x4d8, 1 << 1); - mod_phy_reg(pi, 0x4d8, (0x3ff << 2), 0x23A << 2); - mod_phy_reg(pi, 0x4d8, (0x7 << 12), 0x7 << 12); - phy_c1 = &lcnphy_spb_tone_3750[0]; - phy_c4 = 32; - - if (num_levels == 0) { - if (cal_type != 0) { - num_levels = 4; - } else { - num_levels = 9; - } - } - if (step_size_lg2 == 0) { - if (cal_type != 0) { - step_size_lg2 = 3; - } else { - step_size_lg2 = 8; - } - } - - phy_c7 = (1 << step_size_lg2); - phy_c3 = wlc_lcnphy_get_cc(pi, cal_type); - phy_c15 = (s16) phy_c3.re; - phy_c16 = (s16) phy_c3.im; - if (cal_type == 2) { - if (phy_c3.re > 127) - phy_c15 = phy_c3.re - 256; - if (phy_c3.im > 127) - phy_c16 = phy_c3.im - 256; - } - wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16); - udelay(20); - for (phy_c8 = 0; phy_c7 != 0 && phy_c8 < num_levels; phy_c8++) { - phy_c23 = 1; - phy_c22 = 0; - switch (cal_type) { - case 0: - phy_c10 = 511; - break; - case 2: - phy_c10 = 127; - break; - case 3: - phy_c10 = 15; - break; - case 4: - phy_c10 = 15; - break; - } - - phy_c9 = read_phy_reg(pi, 0x93d); - phy_c9 = 2 * phy_c9; - phy_c24 = 0; - phy_c5 = 7; - phy_c25 = 1; - while (1) { - write_radio_reg(pi, RADIO_2064_REG026, - (phy_c5 & 0x7) | ((phy_c5 & 0x7) << 4)); - udelay(50); - phy_c22 = 0; - ptr[130] = 0; - wlc_lcnphy_samp_cap(pi, 1, phy_c9, &ptr[0], 2); - if (ptr[130] == 1) - phy_c22 = 1; - if (phy_c22) - phy_c5 -= 1; - if ((phy_c22 != phy_c24) && (!phy_c25)) - break; - if (!phy_c22) - phy_c5 += 1; - if (phy_c5 <= 0 || phy_c5 >= 7) - break; - phy_c24 = phy_c22; - phy_c25 = 0; - } - - if (phy_c5 < 0) - phy_c5 = 0; - else if (phy_c5 > 7) - phy_c5 = 7; - - for (k = -phy_c7; k <= phy_c7; k += phy_c7) { - for (l = -phy_c7; l <= phy_c7; l += phy_c7) { - phy_c11 = phy_c15 + k; - phy_c12 = phy_c16 + l; - - if (phy_c11 < -phy_c10) - phy_c11 = -phy_c10; - else if (phy_c11 > phy_c10) - phy_c11 = phy_c10; - if (phy_c12 < -phy_c10) - phy_c12 = -phy_c10; - else if (phy_c12 > phy_c10) - phy_c12 = phy_c10; - wlc_lcnphy_set_cc(pi, cal_type, phy_c11, - phy_c12); - udelay(20); - wlc_lcnphy_samp_cap(pi, 0, 0, ptr, 2); - - phy_c18 = 0; - phy_c19 = 0; - for (j = 0; j < 128; j++) { - if (cal_type != 0) { - phy_c6 = j % phy_c4; - } else { - phy_c6 = (2 * j) % phy_c4; - } - phy_c2.re = phy_c1[phy_c6].re; - phy_c2.im = phy_c1[phy_c6].im; - phy_c17 = ptr[j]; - phy_c18 = phy_c18 + phy_c17 * phy_c2.re; - phy_c19 = phy_c19 + phy_c17 * phy_c2.im; - } - - phy_c18 = phy_c18 >> 10; - phy_c19 = phy_c19 >> 10; - phy_c20 = - ((phy_c18 * phy_c18) + (phy_c19 * phy_c19)); - - if (phy_c23 || phy_c20 < phy_c21) { - phy_c21 = phy_c20; - phy_c13 = phy_c11; - phy_c14 = phy_c12; - } - phy_c23 = 0; - } - } - phy_c23 = 1; - phy_c15 = phy_c13; - phy_c16 = phy_c14; - phy_c7 = phy_c7 >> 1; - wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16); - udelay(20); - } - goto cleanup; - cleanup: - wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, phy_c32); - wlc_lcnphy_stop_tx_tone(pi); - write_phy_reg(pi, 0x6da, phy_c26); - write_phy_reg(pi, 0x6db, phy_c27); - write_phy_reg(pi, 0x938, phy_c28); - write_phy_reg(pi, 0x4d7, phy_c29); - write_phy_reg(pi, 0x4d8, phy_c30); - write_radio_reg(pi, RADIO_2064_REG026, phy_c31); - - kfree(phy_c32); - kfree(ptr); -} - -static void -wlc_lcnphy_tx_iqlo_loopback_cleanup(phy_info_t *pi, u16 *values_to_save) -{ - int i; - - and_phy_reg(pi, 0x44c, 0x0 >> 11); - - and_phy_reg(pi, 0x43b, 0xC); - - for (i = 0; i < 20; i++) { - write_radio_reg(pi, iqlo_loopback_rf_regs[i], - values_to_save[i]); - } -} - -static void -WLBANDINITFN(wlc_lcnphy_load_tx_gain_table) (phy_info_t *pi, - const lcnphy_tx_gain_tbl_entry * - gain_table) { - u32 j; - phytbl_info_t tab; - u32 val; - u16 pa_gain; - u16 gm_gain; - - if (CHSPEC_IS5G(pi->radio_chanspec)) - pa_gain = 0x70; - else - pa_gain = 0x70; - - if (pi->sh->boardflags & BFL_FEM) - pa_gain = 0x10; - tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; - tab.tbl_width = 32; - tab.tbl_len = 1; - tab.tbl_ptr = &val; - - for (j = 0; j < 128; j++) { - gm_gain = gain_table[j].gm; - val = (((u32) pa_gain << 24) | - (gain_table[j].pad << 16) | - (gain_table[j].pga << 8) | gm_gain); - - tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + j; - wlc_lcnphy_write_table(pi, &tab); - - val = (gain_table[j].dac << 28) | (gain_table[j].bb_mult << 20); - tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + j; - wlc_lcnphy_write_table(pi, &tab); - } -} - -static void wlc_lcnphy_load_rfpower(phy_info_t *pi) -{ - phytbl_info_t tab; - u32 val, bbmult, rfgain; - u8 index; - u8 scale_factor = 1; - s16 temp, temp1, temp2, qQ, qQ1, qQ2, shift; - - tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; - tab.tbl_width = 32; - tab.tbl_len = 1; - - for (index = 0; index < 128; index++) { - tab.tbl_ptr = &bbmult; - tab.tbl_offset = LCNPHY_TX_PWR_CTRL_IQ_OFFSET + index; - wlc_lcnphy_read_table(pi, &tab); - bbmult = bbmult >> 20; - - tab.tbl_ptr = &rfgain; - tab.tbl_offset = LCNPHY_TX_PWR_CTRL_GAIN_OFFSET + index; - wlc_lcnphy_read_table(pi, &tab); - - qm_log10((s32) (bbmult), 0, &temp1, &qQ1); - qm_log10((s32) (1 << 6), 0, &temp2, &qQ2); - - if (qQ1 < qQ2) { - temp2 = qm_shr16(temp2, qQ2 - qQ1); - qQ = qQ1; - } else { - temp1 = qm_shr16(temp1, qQ1 - qQ2); - qQ = qQ2; - } - temp = qm_sub16(temp1, temp2); - - if (qQ >= 4) - shift = qQ - 4; - else - shift = 4 - qQ; - - val = (((index << shift) + (5 * temp) + - (1 << (scale_factor + shift - 3))) >> (scale_factor + - shift - 2)); - - tab.tbl_ptr = &val; - tab.tbl_offset = LCNPHY_TX_PWR_CTRL_PWR_OFFSET + index; - wlc_lcnphy_write_table(pi, &tab); - } -} - -static void WLBANDINITFN(wlc_lcnphy_tbl_init) (phy_info_t *pi) -{ - uint idx; - u8 phybw40; - phytbl_info_t tab; - u32 val; - - phybw40 = CHSPEC_IS40(pi->radio_chanspec); - - for (idx = 0; idx < dot11lcnphytbl_info_sz_rev0; idx++) { - wlc_lcnphy_write_table(pi, &dot11lcnphytbl_info_rev0[idx]); - } - - if (pi->sh->boardflags & BFL_FEM_BT) { - tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; - tab.tbl_width = 16; - tab.tbl_ptr = &val; - tab.tbl_len = 1; - val = 100; - tab.tbl_offset = 4; - wlc_lcnphy_write_table(pi, &tab); - } - - tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; - tab.tbl_width = 16; - tab.tbl_ptr = &val; - tab.tbl_len = 1; - - val = 114; - tab.tbl_offset = 0; - wlc_lcnphy_write_table(pi, &tab); - - val = 130; - tab.tbl_offset = 1; - wlc_lcnphy_write_table(pi, &tab); - - val = 6; - tab.tbl_offset = 8; - wlc_lcnphy_write_table(pi, &tab); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (pi->sh->boardflags & BFL_FEM) - wlc_lcnphy_load_tx_gain_table(pi, - dot11lcnphy_2GHz_extPA_gaintable_rev0); - else - wlc_lcnphy_load_tx_gain_table(pi, - dot11lcnphy_2GHz_gaintable_rev0); - } - - if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { - if (CHSPEC_IS2G(pi->radio_chanspec)) { - for (idx = 0; - idx < dot11lcnphytbl_rx_gain_info_2G_rev2_sz; - idx++) - if (pi->sh->boardflags & BFL_EXTLNA) - wlc_lcnphy_write_table(pi, - &dot11lcnphytbl_rx_gain_info_extlna_2G_rev2 - [idx]); - else - wlc_lcnphy_write_table(pi, - &dot11lcnphytbl_rx_gain_info_2G_rev2 - [idx]); - } else { - for (idx = 0; - idx < dot11lcnphytbl_rx_gain_info_5G_rev2_sz; - idx++) - if (pi->sh->boardflags & BFL_EXTLNA_5GHz) - wlc_lcnphy_write_table(pi, - &dot11lcnphytbl_rx_gain_info_extlna_5G_rev2 - [idx]); - else - wlc_lcnphy_write_table(pi, - &dot11lcnphytbl_rx_gain_info_5G_rev2 - [idx]); - } - } - - if ((pi->sh->boardflags & BFL_FEM) - && !(pi->sh->boardflags & BFL_FEM_BT)) - wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313_epa); - else if (pi->sh->boardflags & BFL_FEM_BT) { - if (pi->sh->boardrev < 0x1250) - wlc_lcnphy_write_table(pi, - &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa); - else - wlc_lcnphy_write_table(pi, - &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250); - } else - wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313); - - wlc_lcnphy_load_rfpower(pi); - - wlc_lcnphy_clear_papd_comptable(pi); -} - -static void WLBANDINITFN(wlc_lcnphy_rev0_baseband_init) (phy_info_t *pi) -{ - u16 afectrl1; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - write_radio_reg(pi, RADIO_2064_REG11C, 0x0); - - write_phy_reg(pi, 0x43b, 0x0); - write_phy_reg(pi, 0x43c, 0x0); - write_phy_reg(pi, 0x44c, 0x0); - write_phy_reg(pi, 0x4e6, 0x0); - write_phy_reg(pi, 0x4f9, 0x0); - write_phy_reg(pi, 0x4b0, 0x0); - write_phy_reg(pi, 0x938, 0x0); - write_phy_reg(pi, 0x4b0, 0x0); - write_phy_reg(pi, 0x44e, 0); - - or_phy_reg(pi, 0x567, 0x03); - - or_phy_reg(pi, 0x44a, 0x44); - write_phy_reg(pi, 0x44a, 0x80); - - if (!(pi->sh->boardflags & BFL_FEM)) - wlc_lcnphy_set_tx_pwr_by_index(pi, 52); - - if (0) { - afectrl1 = 0; - afectrl1 = (u16) ((pi_lcn->lcnphy_rssi_vf) | - (pi_lcn->lcnphy_rssi_vc << 4) | (pi_lcn-> - lcnphy_rssi_gs - << 10)); - write_phy_reg(pi, 0x43e, afectrl1); - } - - mod_phy_reg(pi, 0x634, (0xff << 0), 0xC << 0); - if (pi->sh->boardflags & BFL_FEM) { - mod_phy_reg(pi, 0x634, (0xff << 0), 0xA << 0); - - write_phy_reg(pi, 0x910, 0x1); - } - - mod_phy_reg(pi, 0x448, (0x3 << 8), 1 << 8); - mod_phy_reg(pi, 0x608, (0xff << 0), 0x17 << 0); - mod_phy_reg(pi, 0x604, (0x7ff << 0), 0x3EA << 0); - -} - -static void WLBANDINITFN(wlc_lcnphy_rev2_baseband_init) (phy_info_t *pi) -{ - if (CHSPEC_IS5G(pi->radio_chanspec)) { - mod_phy_reg(pi, 0x416, (0xff << 0), 80 << 0); - - mod_phy_reg(pi, 0x416, (0xff << 8), 80 << 8); - } -} - -static void wlc_lcnphy_agc_temp_init(phy_info_t *pi) -{ - s16 temp; - phytbl_info_t tab; - u32 tableBuffer[2]; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - if (NORADIO_ENAB(pi->pubpi)) - return; - - temp = (s16) read_phy_reg(pi, 0x4df); - pi_lcn->lcnphy_ofdmgainidxtableoffset = (temp & (0xff << 0)) >> 0; - - if (pi_lcn->lcnphy_ofdmgainidxtableoffset > 127) - pi_lcn->lcnphy_ofdmgainidxtableoffset -= 256; - - pi_lcn->lcnphy_dsssgainidxtableoffset = (temp & (0xff << 8)) >> 8; - - if (pi_lcn->lcnphy_dsssgainidxtableoffset > 127) - pi_lcn->lcnphy_dsssgainidxtableoffset -= 256; - - tab.tbl_ptr = tableBuffer; - tab.tbl_len = 2; - tab.tbl_id = 17; - tab.tbl_offset = 59; - tab.tbl_width = 32; - wlc_lcnphy_read_table(pi, &tab); - - if (tableBuffer[0] > 63) - tableBuffer[0] -= 128; - pi_lcn->lcnphy_tr_R_gain_val = tableBuffer[0]; - - if (tableBuffer[1] > 63) - tableBuffer[1] -= 128; - pi_lcn->lcnphy_tr_T_gain_val = tableBuffer[1]; - - temp = (s16) (read_phy_reg(pi, 0x434) - & (0xff << 0)); - if (temp > 127) - temp -= 256; - pi_lcn->lcnphy_input_pwr_offset_db = (s8) temp; - - pi_lcn->lcnphy_Med_Low_Gain_db = (read_phy_reg(pi, 0x424) - & (0xff << 8)) - >> 8; - pi_lcn->lcnphy_Very_Low_Gain_db = (read_phy_reg(pi, 0x425) - & (0xff << 0)) - >> 0; - - tab.tbl_ptr = tableBuffer; - tab.tbl_len = 2; - tab.tbl_id = LCNPHY_TBL_ID_GAIN_IDX; - tab.tbl_offset = 28; - tab.tbl_width = 32; - wlc_lcnphy_read_table(pi, &tab); - - pi_lcn->lcnphy_gain_idx_14_lowword = tableBuffer[0]; - pi_lcn->lcnphy_gain_idx_14_hiword = tableBuffer[1]; - -} - -static void WLBANDINITFN(wlc_lcnphy_bu_tweaks) (phy_info_t *pi) -{ - if (NORADIO_ENAB(pi->pubpi)) - return; - - or_phy_reg(pi, 0x805, 0x1); - - mod_phy_reg(pi, 0x42f, (0x7 << 0), (0x3) << 0); - - mod_phy_reg(pi, 0x030, (0x7 << 0), (0x3) << 0); - - write_phy_reg(pi, 0x414, 0x1e10); - write_phy_reg(pi, 0x415, 0x0640); - - mod_phy_reg(pi, 0x4df, (0xff << 8), -9 << 8); - - or_phy_reg(pi, 0x44a, 0x44); - write_phy_reg(pi, 0x44a, 0x80); - mod_phy_reg(pi, 0x434, (0xff << 0), (0xFD) << 0); - - mod_phy_reg(pi, 0x420, (0xff << 0), (16) << 0); - - if (!(pi->sh->boardrev < 0x1204)) - mod_radio_reg(pi, RADIO_2064_REG09B, 0xF0, 0xF0); - - write_phy_reg(pi, 0x7d6, 0x0902); - mod_phy_reg(pi, 0x429, (0xf << 0), (0x9) << 0); - - mod_phy_reg(pi, 0x429, (0x3f << 4), (0xe) << 4); - - if (LCNREV_IS(pi->pubpi.phy_rev, 1)) { - mod_phy_reg(pi, 0x423, (0xff << 0), (0x46) << 0); - - mod_phy_reg(pi, 0x411, (0xff << 0), (1) << 0); - - mod_phy_reg(pi, 0x434, (0xff << 0), (0xFF) << 0); - - mod_phy_reg(pi, 0x656, (0xf << 0), (2) << 0); - - mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2); - - mod_radio_reg(pi, RADIO_2064_REG0F7, 0x4, 0x4); - mod_radio_reg(pi, RADIO_2064_REG0F1, 0x3, 0); - mod_radio_reg(pi, RADIO_2064_REG0F2, 0xF8, 0x90); - mod_radio_reg(pi, RADIO_2064_REG0F3, 0x3, 0x2); - mod_radio_reg(pi, RADIO_2064_REG0F3, 0xf0, 0xa0); - - mod_radio_reg(pi, RADIO_2064_REG11F, 0x2, 0x2); - - wlc_lcnphy_clear_tx_power_offsets(pi); - mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (10) << 6); - - } -} - -static void WLBANDINITFN(wlc_lcnphy_baseband_init) (phy_info_t *pi) -{ - - wlc_lcnphy_tbl_init(pi); - wlc_lcnphy_rev0_baseband_init(pi); - if (LCNREV_IS(pi->pubpi.phy_rev, 2)) - wlc_lcnphy_rev2_baseband_init(pi); - wlc_lcnphy_bu_tweaks(pi); -} - -static void WLBANDINITFN(wlc_radio_2064_init) (phy_info_t *pi) -{ - u32 i; - lcnphy_radio_regs_t *lcnphyregs = NULL; - - lcnphyregs = lcnphy_radio_regs_2064; - - for (i = 0; lcnphyregs[i].address != 0xffff; i++) - if (CHSPEC_IS5G(pi->radio_chanspec) && lcnphyregs[i].do_init_a) - write_radio_reg(pi, - ((lcnphyregs[i].address & 0x3fff) | - RADIO_DEFAULT_CORE), - (u16) lcnphyregs[i].init_a); - else if (lcnphyregs[i].do_init_g) - write_radio_reg(pi, - ((lcnphyregs[i].address & 0x3fff) | - RADIO_DEFAULT_CORE), - (u16) lcnphyregs[i].init_g); - - write_radio_reg(pi, RADIO_2064_REG032, 0x62); - write_radio_reg(pi, RADIO_2064_REG033, 0x19); - - write_radio_reg(pi, RADIO_2064_REG090, 0x10); - - write_radio_reg(pi, RADIO_2064_REG010, 0x00); - - if (LCNREV_IS(pi->pubpi.phy_rev, 1)) { - - write_radio_reg(pi, RADIO_2064_REG060, 0x7f); - write_radio_reg(pi, RADIO_2064_REG061, 0x72); - write_radio_reg(pi, RADIO_2064_REG062, 0x7f); - } - - write_radio_reg(pi, RADIO_2064_REG01D, 0x02); - write_radio_reg(pi, RADIO_2064_REG01E, 0x06); - - mod_phy_reg(pi, 0x4ea, (0x7 << 0), 0 << 0); - - mod_phy_reg(pi, 0x4ea, (0x7 << 3), 1 << 3); - - mod_phy_reg(pi, 0x4ea, (0x7 << 6), 2 << 6); - - mod_phy_reg(pi, 0x4ea, (0x7 << 9), 3 << 9); - - mod_phy_reg(pi, 0x4ea, (0x7 << 12), 4 << 12); - - write_phy_reg(pi, 0x4ea, 0x4688); - - mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0); - - mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6); - - mod_phy_reg(pi, 0x46a, (0xffff << 0), 25 << 0); - - wlc_lcnphy_set_tx_locc(pi, 0); - - wlc_lcnphy_rcal(pi); - - wlc_lcnphy_rc_cal(pi); -} - -static void WLBANDINITFN(wlc_lcnphy_radio_init) (phy_info_t *pi) -{ - if (NORADIO_ENAB(pi->pubpi)) - return; - - wlc_radio_2064_init(pi); -} - -static void wlc_lcnphy_rcal(phy_info_t *pi) -{ - u8 rcal_value; - - if (NORADIO_ENAB(pi->pubpi)) - return; - - and_radio_reg(pi, RADIO_2064_REG05B, 0xfD); - - or_radio_reg(pi, RADIO_2064_REG004, 0x40); - or_radio_reg(pi, RADIO_2064_REG120, 0x10); - - or_radio_reg(pi, RADIO_2064_REG078, 0x80); - or_radio_reg(pi, RADIO_2064_REG129, 0x02); - - or_radio_reg(pi, RADIO_2064_REG057, 0x01); - - or_radio_reg(pi, RADIO_2064_REG05B, 0x02); - mdelay(5); - SPINWAIT(!wlc_radio_2064_rcal_done(pi), 10 * 1000 * 1000); - - if (wlc_radio_2064_rcal_done(pi)) { - rcal_value = (u8) read_radio_reg(pi, RADIO_2064_REG05C); - rcal_value = rcal_value & 0x1f; - } - - and_radio_reg(pi, RADIO_2064_REG05B, 0xfD); - - and_radio_reg(pi, RADIO_2064_REG057, 0xFE); -} - -static void wlc_lcnphy_rc_cal(phy_info_t *pi) -{ - u8 dflt_rc_cal_val; - u16 flt_val; - - if (NORADIO_ENAB(pi->pubpi)) - return; - - dflt_rc_cal_val = 7; - if (LCNREV_IS(pi->pubpi.phy_rev, 1)) - dflt_rc_cal_val = 11; - flt_val = - (dflt_rc_cal_val << 10) | (dflt_rc_cal_val << 5) | - (dflt_rc_cal_val); - write_phy_reg(pi, 0x933, flt_val); - write_phy_reg(pi, 0x934, flt_val); - write_phy_reg(pi, 0x935, flt_val); - write_phy_reg(pi, 0x936, flt_val); - write_phy_reg(pi, 0x937, (flt_val & 0x1FF)); - - return; -} - -static bool wlc_phy_txpwr_srom_read_lcnphy(phy_info_t *pi) -{ - s8 txpwr = 0; - int i; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - u16 cckpo = 0; - u32 offset_ofdm, offset_mcs; - - pi_lcn->lcnphy_tr_isolation_mid = - (u8) PHY_GETINTVAR(pi, "triso2g"); - - pi_lcn->lcnphy_rx_power_offset = - (u8) PHY_GETINTVAR(pi, "rxpo2g"); - - pi->txpa_2g[0] = (s16) PHY_GETINTVAR(pi, "pa0b0"); - pi->txpa_2g[1] = (s16) PHY_GETINTVAR(pi, "pa0b1"); - pi->txpa_2g[2] = (s16) PHY_GETINTVAR(pi, "pa0b2"); - - pi_lcn->lcnphy_rssi_vf = (u8) PHY_GETINTVAR(pi, "rssismf2g"); - pi_lcn->lcnphy_rssi_vc = (u8) PHY_GETINTVAR(pi, "rssismc2g"); - pi_lcn->lcnphy_rssi_gs = (u8) PHY_GETINTVAR(pi, "rssisav2g"); - - { - pi_lcn->lcnphy_rssi_vf_lowtemp = pi_lcn->lcnphy_rssi_vf; - pi_lcn->lcnphy_rssi_vc_lowtemp = pi_lcn->lcnphy_rssi_vc; - pi_lcn->lcnphy_rssi_gs_lowtemp = pi_lcn->lcnphy_rssi_gs; - - pi_lcn->lcnphy_rssi_vf_hightemp = - pi_lcn->lcnphy_rssi_vf; - pi_lcn->lcnphy_rssi_vc_hightemp = - pi_lcn->lcnphy_rssi_vc; - pi_lcn->lcnphy_rssi_gs_hightemp = - pi_lcn->lcnphy_rssi_gs; - } - - txpwr = (s8) PHY_GETINTVAR(pi, "maxp2ga0"); - pi->tx_srom_max_2g = txpwr; - - for (i = 0; i < PWRTBL_NUM_COEFF; i++) { - pi->txpa_2g_low_temp[i] = pi->txpa_2g[i]; - pi->txpa_2g_high_temp[i] = pi->txpa_2g[i]; - } - - cckpo = (u16) PHY_GETINTVAR(pi, "cck2gpo"); - if (cckpo) { - uint max_pwr_chan = txpwr; - - for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) { - pi->tx_srom_max_rate_2g[i] = max_pwr_chan - - ((cckpo & 0xf) * 2); - cckpo >>= 4; - } - - offset_ofdm = (u32) PHY_GETINTVAR(pi, "ofdm2gpo"); - for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) { - pi->tx_srom_max_rate_2g[i] = max_pwr_chan - - ((offset_ofdm & 0xf) * 2); - offset_ofdm >>= 4; - } - } else { - u8 opo = 0; - - opo = (u8) PHY_GETINTVAR(pi, "opo"); - - for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) { - pi->tx_srom_max_rate_2g[i] = txpwr; - } - - offset_ofdm = (u32) PHY_GETINTVAR(pi, "ofdm2gpo"); - - for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) { - pi->tx_srom_max_rate_2g[i] = txpwr - - ((offset_ofdm & 0xf) * 2); - offset_ofdm >>= 4; - } - offset_mcs = - ((u16) PHY_GETINTVAR(pi, "mcs2gpo1") << 16) | - (u16) PHY_GETINTVAR(pi, "mcs2gpo0"); - pi_lcn->lcnphy_mcs20_po = offset_mcs; - for (i = TXP_FIRST_SISO_MCS_20; - i <= TXP_LAST_SISO_MCS_20; i++) { - pi->tx_srom_max_rate_2g[i] = - txpwr - ((offset_mcs & 0xf) * 2); - offset_mcs >>= 4; - } - } - - pi_lcn->lcnphy_rawtempsense = - (u16) PHY_GETINTVAR(pi, "rawtempsense"); - pi_lcn->lcnphy_measPower = - (u8) PHY_GETINTVAR(pi, "measpower"); - pi_lcn->lcnphy_tempsense_slope = - (u8) PHY_GETINTVAR(pi, "tempsense_slope"); - pi_lcn->lcnphy_hw_iqcal_en = - (bool) PHY_GETINTVAR(pi, "hw_iqcal_en"); - pi_lcn->lcnphy_iqcal_swp_dis = - (bool) PHY_GETINTVAR(pi, "iqcal_swp_dis"); - pi_lcn->lcnphy_tempcorrx = - (u8) PHY_GETINTVAR(pi, "tempcorrx"); - pi_lcn->lcnphy_tempsense_option = - (u8) PHY_GETINTVAR(pi, "tempsense_option"); - pi_lcn->lcnphy_freqoffset_corr = - (u8) PHY_GETINTVAR(pi, "freqoffset_corr"); - if ((u8) getintvar(pi->vars, "aa2g") > 1) - wlc_phy_ant_rxdiv_set((wlc_phy_t *) pi, - (u8) getintvar(pi->vars, - "aa2g")); - } - pi_lcn->lcnphy_cck_dig_filt_type = -1; - if (PHY_GETVAR(pi, "cckdigfilttype")) { - s16 temp; - temp = (s16) PHY_GETINTVAR(pi, "cckdigfilttype"); - if (temp >= 0) { - pi_lcn->lcnphy_cck_dig_filt_type = temp; - } - } - - return true; -} - -void wlc_2064_vco_cal(phy_info_t *pi) -{ - u8 calnrst; - - mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 1 << 3); - calnrst = (u8) read_radio_reg(pi, RADIO_2064_REG056) & 0xf8; - write_radio_reg(pi, RADIO_2064_REG056, calnrst); - udelay(1); - write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x03); - udelay(1); - write_radio_reg(pi, RADIO_2064_REG056, calnrst | 0x07); - udelay(300); - mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 0); -} - -static void -wlc_lcnphy_radio_2064_channel_tune_4313(phy_info_t *pi, u8 channel) -{ - uint i; - const chan_info_2064_lcnphy_t *ci; - u8 rfpll_doubler = 0; - u8 pll_pwrup, pll_pwrup_ovr; - fixed qFxtal, qFref, qFvco, qFcal; - u8 d15, d16, f16, e44, e45; - u32 div_int, div_frac, fvco3, fpfd, fref3, fcal_div; - u16 loop_bw, d30, setCount; - if (NORADIO_ENAB(pi->pubpi)) - return; - ci = &chan_info_2064_lcnphy[0]; - rfpll_doubler = 1; - - mod_radio_reg(pi, RADIO_2064_REG09D, 0x4, 0x1 << 2); - - write_radio_reg(pi, RADIO_2064_REG09E, 0xf); - if (!rfpll_doubler) { - loop_bw = PLL_2064_LOOP_BW; - d30 = PLL_2064_D30; - } else { - loop_bw = PLL_2064_LOOP_BW_DOUBLER; - d30 = PLL_2064_D30_DOUBLER; - } - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - for (i = 0; i < ARRAY_SIZE(chan_info_2064_lcnphy); i++) - if (chan_info_2064_lcnphy[i].chan == channel) - break; - - if (i >= ARRAY_SIZE(chan_info_2064_lcnphy)) { - return; - } - - ci = &chan_info_2064_lcnphy[i]; - } - - write_radio_reg(pi, RADIO_2064_REG02A, ci->logen_buftune); - - mod_radio_reg(pi, RADIO_2064_REG030, 0x3, ci->logen_rccr_tx); - - mod_radio_reg(pi, RADIO_2064_REG091, 0x3, ci->txrf_mix_tune_ctrl); - - mod_radio_reg(pi, RADIO_2064_REG038, 0xf, ci->pa_input_tune_g); - - mod_radio_reg(pi, RADIO_2064_REG030, 0x3 << 2, - (ci->logen_rccr_rx) << 2); - - mod_radio_reg(pi, RADIO_2064_REG05E, 0xf, ci->pa_rxrf_lna1_freq_tune); - - mod_radio_reg(pi, RADIO_2064_REG05E, (0xf) << 4, - (ci->pa_rxrf_lna2_freq_tune) << 4); - - write_radio_reg(pi, RADIO_2064_REG06C, ci->rxrf_rxrf_spare1); - - pll_pwrup = (u8) read_radio_reg(pi, RADIO_2064_REG044); - pll_pwrup_ovr = (u8) read_radio_reg(pi, RADIO_2064_REG12B); - - or_radio_reg(pi, RADIO_2064_REG044, 0x07); - - or_radio_reg(pi, RADIO_2064_REG12B, (0x07) << 1); - e44 = 0; - e45 = 0; - - fpfd = rfpll_doubler ? (pi->xtalfreq << 1) : (pi->xtalfreq); - if (pi->xtalfreq > 26000000) - e44 = 1; - if (pi->xtalfreq > 52000000) - e45 = 1; - if (e44 == 0) - fcal_div = 1; - else if (e45 == 0) - fcal_div = 2; - else - fcal_div = 4; - fvco3 = (ci->freq * 3); - fref3 = 2 * fpfd; - - qFxtal = wlc_lcnphy_qdiv_roundup(pi->xtalfreq, PLL_2064_MHZ, 16); - qFref = wlc_lcnphy_qdiv_roundup(fpfd, PLL_2064_MHZ, 16); - qFcal = pi->xtalfreq * fcal_div / PLL_2064_MHZ; - qFvco = wlc_lcnphy_qdiv_roundup(fvco3, 2, 16); - - write_radio_reg(pi, RADIO_2064_REG04F, 0x02); - - d15 = (pi->xtalfreq * fcal_div * 4 / 5) / PLL_2064_MHZ - 1; - write_radio_reg(pi, RADIO_2064_REG052, (0x07 & (d15 >> 2))); - write_radio_reg(pi, RADIO_2064_REG053, (d15 & 0x3) << 5); - - d16 = (qFcal * 8 / (d15 + 1)) - 1; - write_radio_reg(pi, RADIO_2064_REG051, d16); - - f16 = ((d16 + 1) * (d15 + 1)) / qFcal; - setCount = f16 * 3 * (ci->freq) / 32 - 1; - mod_radio_reg(pi, RADIO_2064_REG053, (0x0f << 0), - (u8) (setCount >> 8)); - - or_radio_reg(pi, RADIO_2064_REG053, 0x10); - write_radio_reg(pi, RADIO_2064_REG054, (u8) (setCount & 0xff)); - - div_int = ((fvco3 * (PLL_2064_MHZ >> 4)) / fref3) << 4; - - div_frac = ((fvco3 * (PLL_2064_MHZ >> 4)) % fref3) << 4; - while (div_frac >= fref3) { - div_int++; - div_frac -= fref3; - } - div_frac = wlc_lcnphy_qdiv_roundup(div_frac, fref3, 20); - - mod_radio_reg(pi, RADIO_2064_REG045, (0x1f << 0), - (u8) (div_int >> 4)); - mod_radio_reg(pi, RADIO_2064_REG046, (0x1f << 4), - (u8) (div_int << 4)); - mod_radio_reg(pi, RADIO_2064_REG046, (0x0f << 0), - (u8) (div_frac >> 16)); - write_radio_reg(pi, RADIO_2064_REG047, (u8) (div_frac >> 8) & 0xff); - write_radio_reg(pi, RADIO_2064_REG048, (u8) div_frac & 0xff); - - write_radio_reg(pi, RADIO_2064_REG040, 0xfb); - - write_radio_reg(pi, RADIO_2064_REG041, 0x9A); - write_radio_reg(pi, RADIO_2064_REG042, 0xA3); - write_radio_reg(pi, RADIO_2064_REG043, 0x0C); - - { - u8 h29, h23, c28, d29, h28_ten, e30, h30_ten, cp_current; - u16 c29, c38, c30, g30, d28; - c29 = loop_bw; - d29 = 200; - c38 = 1250; - h29 = d29 / c29; - h23 = 1; - c28 = 30; - d28 = (((PLL_2064_HIGH_END_KVCO - PLL_2064_LOW_END_KVCO) * - (fvco3 / 2 - PLL_2064_LOW_END_VCO)) / - (PLL_2064_HIGH_END_VCO - PLL_2064_LOW_END_VCO)) - + PLL_2064_LOW_END_KVCO; - h28_ten = (d28 * 10) / c28; - c30 = 2640; - e30 = (d30 - 680) / 490; - g30 = 680 + (e30 * 490); - h30_ten = (g30 * 10) / c30; - cp_current = ((c38 * h29 * h23 * 100) / h28_ten) / h30_ten; - mod_radio_reg(pi, RADIO_2064_REG03C, 0x3f, cp_current); - } - if (channel >= 1 && channel <= 5) - write_radio_reg(pi, RADIO_2064_REG03C, 0x8); - else - write_radio_reg(pi, RADIO_2064_REG03C, 0x7); - write_radio_reg(pi, RADIO_2064_REG03D, 0x3); - - mod_radio_reg(pi, RADIO_2064_REG044, 0x0c, 0x0c); - udelay(1); - - wlc_2064_vco_cal(pi); - - write_radio_reg(pi, RADIO_2064_REG044, pll_pwrup); - write_radio_reg(pi, RADIO_2064_REG12B, pll_pwrup_ovr); - if (LCNREV_IS(pi->pubpi.phy_rev, 1)) { - write_radio_reg(pi, RADIO_2064_REG038, 3); - write_radio_reg(pi, RADIO_2064_REG091, 7); - } -} - -bool wlc_phy_tpc_isenabled_lcnphy(phy_info_t *pi) -{ - if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) - return 0; - else - return (LCNPHY_TX_PWR_CTRL_HW == - wlc_lcnphy_get_tx_pwr_ctrl((pi))); -} - -void wlc_phy_txpower_recalc_target_lcnphy(phy_info_t *pi) -{ - u16 pwr_ctrl; - if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) { - wlc_lcnphy_calib_modes(pi, LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL); - } else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) { - - pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); - wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); - wlc_lcnphy_txpower_recalc_target(pi); - - wlc_lcnphy_set_tx_pwr_ctrl(pi, pwr_ctrl); - } else - return; -} - -void wlc_phy_detach_lcnphy(phy_info_t *pi) -{ - kfree(pi->u.pi_lcnphy); -} - -bool wlc_phy_attach_lcnphy(phy_info_t *pi) -{ - phy_info_lcnphy_t *pi_lcn; - - pi->u.pi_lcnphy = kzalloc(sizeof(phy_info_lcnphy_t), GFP_ATOMIC); - if (pi->u.pi_lcnphy == NULL) { - return false; - } - - pi_lcn = pi->u.pi_lcnphy; - - if ((0 == (pi->sh->boardflags & BFL_NOPA)) && !NORADIO_ENAB(pi->pubpi)) { - pi->hwpwrctrl = true; - pi->hwpwrctrl_capable = true; - } - - pi->xtalfreq = si_alp_clock(pi->sh->sih); - ASSERT(0 == (pi->xtalfreq % 1000)); - - pi_lcn->lcnphy_papd_rxGnCtrl_init = 0; - - pi->pi_fptr.init = wlc_phy_init_lcnphy; - pi->pi_fptr.calinit = wlc_phy_cal_init_lcnphy; - pi->pi_fptr.chanset = wlc_phy_chanspec_set_lcnphy; - pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_lcnphy; - pi->pi_fptr.txiqccget = wlc_lcnphy_get_tx_iqcc; - pi->pi_fptr.txiqccset = wlc_lcnphy_set_tx_iqcc; - pi->pi_fptr.txloccget = wlc_lcnphy_get_tx_locc; - pi->pi_fptr.radioloftget = wlc_lcnphy_get_radio_loft; - pi->pi_fptr.detach = wlc_phy_detach_lcnphy; - - if (!wlc_phy_txpwr_srom_read_lcnphy(pi)) - return false; - - if ((pi->sh->boardflags & BFL_FEM) && (LCNREV_IS(pi->pubpi.phy_rev, 1))) { - if (pi_lcn->lcnphy_tempsense_option == 3) { - pi->hwpwrctrl = true; - pi->hwpwrctrl_capable = true; - pi->temppwrctrl_capable = false; - } else { - pi->hwpwrctrl = false; - pi->hwpwrctrl_capable = false; - pi->temppwrctrl_capable = true; - } - } - - return true; -} - -static void wlc_lcnphy_set_rx_gain(phy_info_t *pi, u32 gain) -{ - u16 trsw, ext_lna, lna1, lna2, tia, biq0, biq1, gain0_15, gain16_19; - - trsw = (gain & ((u32) 1 << 28)) ? 0 : 1; - ext_lna = (u16) (gain >> 29) & 0x01; - lna1 = (u16) (gain >> 0) & 0x0f; - lna2 = (u16) (gain >> 4) & 0x0f; - tia = (u16) (gain >> 8) & 0xf; - biq0 = (u16) (gain >> 12) & 0xf; - biq1 = (u16) (gain >> 16) & 0xf; - - gain0_15 = (u16) ((lna1 & 0x3) | ((lna1 & 0x3) << 2) | - ((lna2 & 0x3) << 4) | ((lna2 & 0x3) << 6) | - ((tia & 0xf) << 8) | ((biq0 & 0xf) << 12)); - gain16_19 = biq1; - - mod_phy_reg(pi, 0x44d, (0x1 << 0), trsw << 0); - mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9); - mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10); - mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0); - mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11); - mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3); - } - wlc_lcnphy_rx_gain_override_enable(pi, true); -} - -static u32 wlc_lcnphy_get_receive_power(phy_info_t *pi, s32 *gain_index) -{ - u32 received_power = 0; - s32 max_index = 0; - u32 gain_code = 0; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - max_index = 36; - if (*gain_index >= 0) - gain_code = lcnphy_23bitgaincode_table[*gain_index]; - - if (-1 == *gain_index) { - *gain_index = 0; - while ((*gain_index <= (s32) max_index) - && (received_power < 700)) { - wlc_lcnphy_set_rx_gain(pi, - lcnphy_23bitgaincode_table - [*gain_index]); - received_power = - wlc_lcnphy_measure_digital_power(pi, - pi_lcn-> - lcnphy_noise_samples); - (*gain_index)++; - } - (*gain_index)--; - } else { - wlc_lcnphy_set_rx_gain(pi, gain_code); - received_power = - wlc_lcnphy_measure_digital_power(pi, - pi_lcn-> - lcnphy_noise_samples); - } - - return received_power; -} - -s32 wlc_lcnphy_rx_signal_power(phy_info_t *pi, s32 gain_index) -{ - s32 gain = 0; - s32 nominal_power_db; - s32 log_val, gain_mismatch, desired_gain, input_power_offset_db, - input_power_db; - s32 received_power, temperature; - uint freq; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; - - received_power = wlc_lcnphy_get_receive_power(pi, &gain_index); - - gain = lcnphy_gain_table[gain_index]; - - nominal_power_db = read_phy_reg(pi, 0x425) >> 8; - - { - u32 power = (received_power * 16); - u32 msb1, msb2, val1, val2, diff1, diff2; - msb1 = ffs(power) - 1; - msb2 = msb1 + 1; - val1 = 1 << msb1; - val2 = 1 << msb2; - diff1 = (power - val1); - diff2 = (val2 - power); - if (diff1 < diff2) - log_val = msb1; - else - log_val = msb2; - } - - log_val = log_val * 3; - - gain_mismatch = (nominal_power_db / 2) - (log_val); - - desired_gain = gain + gain_mismatch; - - input_power_offset_db = read_phy_reg(pi, 0x434) & 0xFF; - - if (input_power_offset_db > 127) - input_power_offset_db -= 256; - - input_power_db = input_power_offset_db - desired_gain; - - input_power_db = - input_power_db + lcnphy_gain_index_offset_for_rssi[gain_index]; - - freq = wlc_phy_channel2freq(CHSPEC_CHANNEL(pi->radio_chanspec)); - if ((freq > 2427) && (freq <= 2467)) - input_power_db = input_power_db - 1; - - temperature = pi_lcn->lcnphy_lastsensed_temperature; - - if ((temperature - 15) < -30) { - input_power_db = - input_power_db + (((temperature - 10 - 25) * 286) >> 12) - - 7; - } else if ((temperature - 15) < 4) { - input_power_db = - input_power_db + (((temperature - 10 - 25) * 286) >> 12) - - 3; - } else { - input_power_db = - input_power_db + (((temperature - 10 - 25) * 286) >> 12); - } - - wlc_lcnphy_rx_gain_override_enable(pi, 0); - - return input_power_db; -} - -static int -wlc_lcnphy_load_tx_iir_filter(phy_info_t *pi, bool is_ofdm, s16 filt_type) -{ - s16 filt_index = -1; - int j; - - u16 addr[] = { - 0x910, - 0x91e, - 0x91f, - 0x924, - 0x925, - 0x926, - 0x920, - 0x921, - 0x927, - 0x928, - 0x929, - 0x922, - 0x923, - 0x930, - 0x931, - 0x932 - }; - - u16 addr_ofdm[] = { - 0x90f, - 0x900, - 0x901, - 0x906, - 0x907, - 0x908, - 0x902, - 0x903, - 0x909, - 0x90a, - 0x90b, - 0x904, - 0x905, - 0x90c, - 0x90d, - 0x90e - }; - - if (!is_ofdm) { - for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_CCK; j++) { - if (filt_type == LCNPHY_txdigfiltcoeffs_cck[j][0]) { - filt_index = (s16) j; - break; - } - } - - if (filt_index == -1) { - ASSERT(false); - } else { - for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) { - write_phy_reg(pi, addr[j], - LCNPHY_txdigfiltcoeffs_cck - [filt_index][j + 1]); - } - } - } else { - for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_OFDM; j++) { - if (filt_type == LCNPHY_txdigfiltcoeffs_ofdm[j][0]) { - filt_index = (s16) j; - break; - } - } - - if (filt_index == -1) { - ASSERT(false); - } else { - for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) { - write_phy_reg(pi, addr_ofdm[j], - LCNPHY_txdigfiltcoeffs_ofdm - [filt_index][j + 1]); - } - } - } - - return (filt_index != -1) ? 0 : -1; -} diff --git a/drivers/staging/brcm80211/phy/wlc_phy_lcn.h b/drivers/staging/brcm80211/phy/wlc_phy_lcn.h deleted file mode 100644 index b7bfc7230dfc..000000000000 --- a/drivers/staging/brcm80211/phy/wlc_phy_lcn.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_phy_lcn_h_ -#define _wlc_phy_lcn_h_ - -struct phy_info_lcnphy { - int lcnphy_txrf_sp_9_override; - u8 lcnphy_full_cal_channel; - u8 lcnphy_cal_counter; - u16 lcnphy_cal_temper; - bool lcnphy_recal; - - u8 lcnphy_rc_cap; - u32 lcnphy_mcs20_po; - - u8 lcnphy_tr_isolation_mid; - u8 lcnphy_tr_isolation_low; - u8 lcnphy_tr_isolation_hi; - - u8 lcnphy_bx_arch; - u8 lcnphy_rx_power_offset; - u8 lcnphy_rssi_vf; - u8 lcnphy_rssi_vc; - u8 lcnphy_rssi_gs; - u8 lcnphy_tssi_val; - u8 lcnphy_rssi_vf_lowtemp; - u8 lcnphy_rssi_vc_lowtemp; - u8 lcnphy_rssi_gs_lowtemp; - - u8 lcnphy_rssi_vf_hightemp; - u8 lcnphy_rssi_vc_hightemp; - u8 lcnphy_rssi_gs_hightemp; - - s16 lcnphy_pa0b0; - s16 lcnphy_pa0b1; - s16 lcnphy_pa0b2; - - u16 lcnphy_rawtempsense; - u8 lcnphy_measPower; - u8 lcnphy_tempsense_slope; - u8 lcnphy_freqoffset_corr; - u8 lcnphy_tempsense_option; - u8 lcnphy_tempcorrx; - bool lcnphy_iqcal_swp_dis; - bool lcnphy_hw_iqcal_en; - uint lcnphy_bandedge_corr; - bool lcnphy_spurmod; - u16 lcnphy_tssi_tx_cnt; - u16 lcnphy_tssi_idx; - u16 lcnphy_tssi_npt; - - u16 lcnphy_target_tx_freq; - s8 lcnphy_tx_power_idx_override; - u16 lcnphy_noise_samples; - - u32 lcnphy_papdRxGnIdx; - u32 lcnphy_papd_rxGnCtrl_init; - - u32 lcnphy_gain_idx_14_lowword; - u32 lcnphy_gain_idx_14_hiword; - u32 lcnphy_gain_idx_27_lowword; - u32 lcnphy_gain_idx_27_hiword; - s16 lcnphy_ofdmgainidxtableoffset; - s16 lcnphy_dsssgainidxtableoffset; - u32 lcnphy_tr_R_gain_val; - u32 lcnphy_tr_T_gain_val; - s8 lcnphy_input_pwr_offset_db; - u16 lcnphy_Med_Low_Gain_db; - u16 lcnphy_Very_Low_Gain_db; - s8 lcnphy_lastsensed_temperature; - s8 lcnphy_pkteng_rssi_slope; - u8 lcnphy_saved_tx_user_target[TXP_NUM_RATES]; - u8 lcnphy_volt_winner; - u8 lcnphy_volt_low; - u8 lcnphy_54_48_36_24mbps_backoff; - u8 lcnphy_11n_backoff; - u8 lcnphy_lowerofdm; - u8 lcnphy_cck; - u8 lcnphy_psat_2pt3_detected; - s32 lcnphy_lowest_Re_div_Im; - s8 lcnphy_final_papd_cal_idx; - u16 lcnphy_extstxctrl4; - u16 lcnphy_extstxctrl0; - u16 lcnphy_extstxctrl1; - s16 lcnphy_cck_dig_filt_type; - s16 lcnphy_ofdm_dig_filt_type; - lcnphy_cal_results_t lcnphy_cal_results; - - u8 lcnphy_psat_pwr; - u8 lcnphy_psat_indx; - s32 lcnphy_min_phase; - u8 lcnphy_final_idx; - u8 lcnphy_start_idx; - u8 lcnphy_current_index; - u16 lcnphy_logen_buf_1; - u16 lcnphy_local_ovr_2; - u16 lcnphy_local_oval_6; - u16 lcnphy_local_oval_5; - u16 lcnphy_logen_mixer_1; - - u8 lcnphy_aci_stat; - uint lcnphy_aci_start_time; - s8 lcnphy_tx_power_offset[TXP_NUM_RATES]; -}; -#endif /* _wlc_phy_lcn_h_ */ diff --git a/drivers/staging/brcm80211/phy/wlc_phy_n.c b/drivers/staging/brcm80211/phy/wlc_phy_n.c deleted file mode 100644 index c6cce8de1aee..000000000000 --- a/drivers/staging/brcm80211/phy/wlc_phy_n.c +++ /dev/null @@ -1,29239 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#define READ_RADIO_REG2(pi, radio_type, jspace, core, reg_name) \ - read_radio_reg(pi, radio_type##_##jspace##_##reg_name | \ - ((core == PHY_CORE_0) ? radio_type##_##jspace##0 : radio_type##_##jspace##1)) -#define WRITE_RADIO_REG2(pi, radio_type, jspace, core, reg_name, value) \ - write_radio_reg(pi, radio_type##_##jspace##_##reg_name | \ - ((core == PHY_CORE_0) ? radio_type##_##jspace##0 : radio_type##_##jspace##1), value); -#define WRITE_RADIO_SYN(pi, radio_type, reg_name, value) \ - write_radio_reg(pi, radio_type##_##SYN##_##reg_name, value); - -#define READ_RADIO_REG3(pi, radio_type, jspace, core, reg_name) \ - read_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##jspace##0##_##reg_name : \ - radio_type##_##jspace##1##_##reg_name)); -#define WRITE_RADIO_REG3(pi, radio_type, jspace, core, reg_name, value) \ - write_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##jspace##0##_##reg_name : \ - radio_type##_##jspace##1##_##reg_name), value); -#define READ_RADIO_REG4(pi, radio_type, jspace, core, reg_name) \ - read_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##reg_name##_##jspace##0 : \ - radio_type##_##reg_name##_##jspace##1)); -#define WRITE_RADIO_REG4(pi, radio_type, jspace, core, reg_name, value) \ - write_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##reg_name##_##jspace##0 : \ - radio_type##_##reg_name##_##jspace##1), value); - -#define NPHY_ACI_MAX_UNDETECT_WINDOW_SZ 40 -#define NPHY_ACI_CHANNEL_DELTA 5 -#define NPHY_ACI_CHANNEL_SKIP 4 -#define NPHY_ACI_40MHZ_CHANNEL_DELTA 6 -#define NPHY_ACI_40MHZ_CHANNEL_SKIP 5 -#define NPHY_ACI_40MHZ_CHANNEL_DELTA_GE_REV3 6 -#define NPHY_ACI_40MHZ_CHANNEL_SKIP_GE_REV3 5 -#define NPHY_ACI_CHANNEL_DELTA_GE_REV3 4 -#define NPHY_ACI_CHANNEL_SKIP_GE_REV3 3 - -#define NPHY_NOISE_NOASSOC_GLITCH_TH_UP 2 - -#define NPHY_NOISE_NOASSOC_GLITCH_TH_DN 8 - -#define NPHY_NOISE_ASSOC_GLITCH_TH_UP 2 - -#define NPHY_NOISE_ASSOC_GLITCH_TH_DN 8 - -#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_UP 2 - -#define NPHY_NOISE_ASSOC_ACI_GLITCH_TH_DN 8 - -#define NPHY_NOISE_NOASSOC_ENTER_TH 400 - -#define NPHY_NOISE_ASSOC_ENTER_TH 400 - -#define NPHY_NOISE_ASSOC_RX_GLITCH_BADPLCP_ENTER_TH 400 - -#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX 44 -#define NPHY_NOISE_CRSMINPWR_ARRAY_MAX_INDEX_REV_7 56 - -#define NPHY_NOISE_NOASSOC_CRSIDX_INCR 16 - -#define NPHY_NOISE_ASSOC_CRSIDX_INCR 8 - -#define NPHY_IS_SROM_REINTERPRET NREV_GE(pi->pubpi.phy_rev, 5) - -#define NPHY_RSSICAL_MAXREAD 31 - -#define NPHY_RSSICAL_NPOLL 8 -#define NPHY_RSSICAL_MAXD (1<<20) -#define NPHY_MIN_RXIQ_PWR 2 - -#define NPHY_RSSICAL_W1_TARGET 25 -#define NPHY_RSSICAL_W2_TARGET NPHY_RSSICAL_W1_TARGET -#define NPHY_RSSICAL_NB_TARGET 0 - -#define NPHY_RSSICAL_W1_TARGET_REV3 29 -#define NPHY_RSSICAL_W2_TARGET_REV3 NPHY_RSSICAL_W1_TARGET_REV3 - -#define NPHY_CALSANITY_RSSI_NB_MAX_POS 9 -#define NPHY_CALSANITY_RSSI_NB_MAX_NEG -9 -#define NPHY_CALSANITY_RSSI_W1_MAX_POS 12 -#define NPHY_CALSANITY_RSSI_W1_MAX_NEG (NPHY_RSSICAL_W1_TARGET - NPHY_RSSICAL_MAXREAD) -#define NPHY_CALSANITY_RSSI_W2_MAX_POS NPHY_CALSANITY_RSSI_W1_MAX_POS -#define NPHY_CALSANITY_RSSI_W2_MAX_NEG (NPHY_RSSICAL_W2_TARGET - NPHY_RSSICAL_MAXREAD) -#define NPHY_RSSI_SXT(x) ((s8) (-((x) & 0x20) + ((x) & 0x1f))) -#define NPHY_RSSI_NB_VIOL(x) (((x) > NPHY_CALSANITY_RSSI_NB_MAX_POS) || \ - ((x) < NPHY_CALSANITY_RSSI_NB_MAX_NEG)) -#define NPHY_RSSI_W1_VIOL(x) (((x) > NPHY_CALSANITY_RSSI_W1_MAX_POS) || \ - ((x) < NPHY_CALSANITY_RSSI_W1_MAX_NEG)) -#define NPHY_RSSI_W2_VIOL(x) (((x) > NPHY_CALSANITY_RSSI_W2_MAX_POS) || \ - ((x) < NPHY_CALSANITY_RSSI_W2_MAX_NEG)) - -#define NPHY_IQCAL_NUMGAINS 9 -#define NPHY_N_GCTL 0x66 - -#define NPHY_PAPD_EPS_TBL_SIZE 64 -#define NPHY_PAPD_SCL_TBL_SIZE 64 -#define NPHY_NUM_DIG_FILT_COEFFS 15 - -#define NPHY_PAPD_COMP_OFF 0 -#define NPHY_PAPD_COMP_ON 1 - -#define NPHY_SROM_TEMPSHIFT 32 -#define NPHY_SROM_MAXTEMPOFFSET 16 -#define NPHY_SROM_MINTEMPOFFSET -16 - -#define NPHY_CAL_MAXTEMPDELTA 64 - -#define NPHY_NOISEVAR_TBLLEN40 256 -#define NPHY_NOISEVAR_TBLLEN20 128 - -#define NPHY_ANARXLPFBW_REDUCTIONFACT 7 - -#define NPHY_ADJUSTED_MINCRSPOWER 0x1e - -typedef struct _nphy_iqcal_params { - u16 txlpf; - u16 txgm; - u16 pga; - u16 pad; - u16 ipa; - u16 cal_gain; - u16 ncorr[5]; -} nphy_iqcal_params_t; - -typedef struct _nphy_txiqcal_ladder { - u8 percent; - u8 g_env; -} nphy_txiqcal_ladder_t; - -typedef struct { - nphy_txgains_t gains; - bool useindex; - u8 index; -} nphy_ipa_txcalgains_t; - -typedef struct nphy_papd_restore_state_t { - u16 fbmix[2]; - u16 vga_master[2]; - u16 intpa_master[2]; - u16 afectrl[2]; - u16 afeoverride[2]; - u16 pwrup[2]; - u16 atten[2]; - u16 mm; -} nphy_papd_restore_state; - -typedef struct _nphy_ipa_txrxgain { - u16 hpvga; - u16 lpf_biq1; - u16 lpf_biq0; - u16 lna2; - u16 lna1; - s8 txpwrindex; -} nphy_ipa_txrxgain_t; - -#define NPHY_IPA_RXCAL_MAXGAININDEX (6 - 1) - -nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_5GHz[] = { {0, 0, 0, 0, 0, 100}, -{0, 0, 0, 0, 0, 50}, -{0, 0, 0, 0, 0, -1}, -{0, 0, 0, 3, 0, -1}, -{0, 0, 3, 3, 0, -1}, -{0, 2, 3, 3, 0, -1} -}; - -nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_2GHz[] = { {0, 0, 0, 0, 0, 128}, -{0, 0, 0, 0, 0, 70}, -{0, 0, 0, 0, 0, 20}, -{0, 0, 0, 3, 0, 20}, -{0, 0, 3, 3, 0, 20}, -{0, 2, 3, 3, 0, 20} -}; - -nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_5GHz_rev7[] = { {0, 0, 0, 0, 0, 100}, -{0, 0, 0, 0, 0, 50}, -{0, 0, 0, 0, 0, -1}, -{0, 0, 0, 3, 0, -1}, -{0, 0, 3, 3, 0, -1}, -{0, 0, 5, 3, 0, -1} -}; - -nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_2GHz_rev7[] = { {0, 0, 0, 0, 0, 10}, -{0, 0, 0, 1, 0, 10}, -{0, 0, 1, 2, 0, 10}, -{0, 0, 1, 3, 0, 10}, -{0, 0, 4, 3, 0, 10}, -{0, 0, 6, 3, 0, 10} -}; - -#define NPHY_RXCAL_TONEAMP 181 -#define NPHY_RXCAL_TONEFREQ_40MHz 4000 -#define NPHY_RXCAL_TONEFREQ_20MHz 2000 - -enum { - NPHY_RXCAL_GAIN_INIT = 0, - NPHY_RXCAL_GAIN_UP, - NPHY_RXCAL_GAIN_DOWN -}; - -#define wlc_phy_get_papd_nphy(pi) \ - (read_phy_reg((pi), 0x1e7) & \ - ((0x1 << 15) | \ - (0x1 << 14) | \ - (0x1 << 13))) - -#define TXFILT_SHAPING_OFDM20 0 -#define TXFILT_SHAPING_OFDM40 1 -#define TXFILT_SHAPING_CCK 2 -#define TXFILT_DEFAULT_OFDM20 3 -#define TXFILT_DEFAULT_OFDM40 4 - -u16 NPHY_IPA_REV4_txdigi_filtcoeffs[][NPHY_NUM_DIG_FILT_COEFFS] = { - {-377, 137, -407, 208, -1527, 956, 93, 186, 93, - 230, -44, 230, 201, -191, 201}, - {-77, 20, -98, 49, -93, 60, 56, 111, 56, 26, -5, - 26, 34, -32, 34}, - {-360, 164, -376, 164, -1533, 576, 308, -314, 308, - 121, -73, 121, 91, 124, 91}, - {-295, 200, -363, 142, -1391, 826, 151, 301, 151, - 151, 301, 151, 602, -752, 602}, - {-92, 58, -96, 49, -104, 44, 17, 35, 17, - 12, 25, 12, 13, 27, 13}, - {-375, 136, -399, 209, -1479, 949, 130, 260, 130, - 230, -44, 230, 201, -191, 201}, - {0xed9, 0xc8, 0xe95, 0x8e, 0xa91, 0x33a, 0x97, 0x12d, 0x97, - 0x97, 0x12d, 0x97, 0x25a, 0xd10, 0x25a} -}; - -typedef struct _chan_info_nphy_2055 { - u16 chan; - u16 freq; - uint unknown; - u8 RF_pll_ref; - u8 RF_rf_pll_mod1; - u8 RF_rf_pll_mod0; - u8 RF_vco_cap_tail; - u8 RF_vco_cal1; - u8 RF_vco_cal2; - u8 RF_pll_lf_c1; - u8 RF_pll_lf_r1; - u8 RF_pll_lf_c2; - u8 RF_lgbuf_cen_buf; - u8 RF_lgen_tune1; - u8 RF_lgen_tune2; - u8 RF_core1_lgbuf_a_tune; - u8 RF_core1_lgbuf_g_tune; - u8 RF_core1_rxrf_reg1; - u8 RF_core1_tx_pga_pad_tn; - u8 RF_core1_tx_mx_bgtrim; - u8 RF_core2_lgbuf_a_tune; - u8 RF_core2_lgbuf_g_tune; - u8 RF_core2_rxrf_reg1; - u8 RF_core2_tx_pga_pad_tn; - u8 RF_core2_tx_mx_bgtrim; - u16 PHY_BW1a; - u16 PHY_BW2; - u16 PHY_BW3; - u16 PHY_BW4; - u16 PHY_BW5; - u16 PHY_BW6; -} chan_info_nphy_2055_t; - -typedef struct _chan_info_nphy_radio205x { - u16 chan; - u16 freq; - u8 RF_SYN_pll_vcocal1; - u8 RF_SYN_pll_vcocal2; - u8 RF_SYN_pll_refdiv; - u8 RF_SYN_pll_mmd2; - u8 RF_SYN_pll_mmd1; - u8 RF_SYN_pll_loopfilter1; - u8 RF_SYN_pll_loopfilter2; - u8 RF_SYN_pll_loopfilter3; - u8 RF_SYN_pll_loopfilter4; - u8 RF_SYN_pll_loopfilter5; - u8 RF_SYN_reserved_addr27; - u8 RF_SYN_reserved_addr28; - u8 RF_SYN_reserved_addr29; - u8 RF_SYN_logen_VCOBUF1; - u8 RF_SYN_logen_MIXER2; - u8 RF_SYN_logen_BUF3; - u8 RF_SYN_logen_BUF4; - u8 RF_RX0_lnaa_tune; - u8 RF_RX0_lnag_tune; - u8 RF_TX0_intpaa_boost_tune; - u8 RF_TX0_intpag_boost_tune; - u8 RF_TX0_pada_boost_tune; - u8 RF_TX0_padg_boost_tune; - u8 RF_TX0_pgaa_boost_tune; - u8 RF_TX0_pgag_boost_tune; - u8 RF_TX0_mixa_boost_tune; - u8 RF_TX0_mixg_boost_tune; - u8 RF_RX1_lnaa_tune; - u8 RF_RX1_lnag_tune; - u8 RF_TX1_intpaa_boost_tune; - u8 RF_TX1_intpag_boost_tune; - u8 RF_TX1_pada_boost_tune; - u8 RF_TX1_padg_boost_tune; - u8 RF_TX1_pgaa_boost_tune; - u8 RF_TX1_pgag_boost_tune; - u8 RF_TX1_mixa_boost_tune; - u8 RF_TX1_mixg_boost_tune; - u16 PHY_BW1a; - u16 PHY_BW2; - u16 PHY_BW3; - u16 PHY_BW4; - u16 PHY_BW5; - u16 PHY_BW6; -} chan_info_nphy_radio205x_t; - -typedef struct _chan_info_nphy_radio2057 { - u16 chan; - u16 freq; - u8 RF_vcocal_countval0; - u8 RF_vcocal_countval1; - u8 RF_rfpll_refmaster_sparextalsize; - u8 RF_rfpll_loopfilter_r1; - u8 RF_rfpll_loopfilter_c2; - u8 RF_rfpll_loopfilter_c1; - u8 RF_cp_kpd_idac; - u8 RF_rfpll_mmd0; - u8 RF_rfpll_mmd1; - u8 RF_vcobuf_tune; - u8 RF_logen_mx2g_tune; - u8 RF_logen_mx5g_tune; - u8 RF_logen_indbuf2g_tune; - u8 RF_logen_indbuf5g_tune; - u8 RF_txmix2g_tune_boost_pu_core0; - u8 RF_pad2g_tune_pus_core0; - u8 RF_pga_boost_tune_core0; - u8 RF_txmix5g_boost_tune_core0; - u8 RF_pad5g_tune_misc_pus_core0; - u8 RF_lna2g_tune_core0; - u8 RF_lna5g_tune_core0; - u8 RF_txmix2g_tune_boost_pu_core1; - u8 RF_pad2g_tune_pus_core1; - u8 RF_pga_boost_tune_core1; - u8 RF_txmix5g_boost_tune_core1; - u8 RF_pad5g_tune_misc_pus_core1; - u8 RF_lna2g_tune_core1; - u8 RF_lna5g_tune_core1; - u16 PHY_BW1a; - u16 PHY_BW2; - u16 PHY_BW3; - u16 PHY_BW4; - u16 PHY_BW5; - u16 PHY_BW6; -} chan_info_nphy_radio2057_t; - -typedef struct _chan_info_nphy_radio2057_rev5 { - u16 chan; - u16 freq; - u8 RF_vcocal_countval0; - u8 RF_vcocal_countval1; - u8 RF_rfpll_refmaster_sparextalsize; - u8 RF_rfpll_loopfilter_r1; - u8 RF_rfpll_loopfilter_c2; - u8 RF_rfpll_loopfilter_c1; - u8 RF_cp_kpd_idac; - u8 RF_rfpll_mmd0; - u8 RF_rfpll_mmd1; - u8 RF_vcobuf_tune; - u8 RF_logen_mx2g_tune; - u8 RF_logen_indbuf2g_tune; - u8 RF_txmix2g_tune_boost_pu_core0; - u8 RF_pad2g_tune_pus_core0; - u8 RF_lna2g_tune_core0; - u8 RF_txmix2g_tune_boost_pu_core1; - u8 RF_pad2g_tune_pus_core1; - u8 RF_lna2g_tune_core1; - u16 PHY_BW1a; - u16 PHY_BW2; - u16 PHY_BW3; - u16 PHY_BW4; - u16 PHY_BW5; - u16 PHY_BW6; -} chan_info_nphy_radio2057_rev5_t; - -typedef struct nphy_sfo_cfg { - u16 PHY_BW1a; - u16 PHY_BW2; - u16 PHY_BW3; - u16 PHY_BW4; - u16 PHY_BW5; - u16 PHY_BW6; -} nphy_sfo_cfg_t; - -static chan_info_nphy_2055_t chan_info_nphy_2055[] = { - { - 184, 4920, 3280, 0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, - 0x0F, 0x8F, 0x7B4, 0x7B0, 0x7AC, 0x214, 0x215, 0x216}, - { - 186, 4930, 3287, 0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, - 0x0F, 0x8F, 0x7B8, 0x7B4, 0x7B0, 0x213, 0x214, 0x215}, - { - 188, 4940, 3293, 0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, - 0x0F, 0x8F, 0x7BC, 0x7B8, 0x7B4, 0x212, 0x213, 0x214}, - { - 190, 4950, 3300, 0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, - 0x0F, 0x8F, 0x7C0, 0x7BC, 0x7B8, 0x211, 0x212, 0x213}, - { - 192, 4960, 3307, 0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, - 0x0F, 0x8F, 0x7C4, 0x7C0, 0x7BC, 0x20F, 0x211, 0x212}, - { - 194, 4970, 3313, 0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, - 0x0F, 0x8F, 0x7C8, 0x7C4, 0x7C0, 0x20E, 0x20F, 0x211}, - { - 196, 4980, 3320, 0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, - 0x0F, 0x8F, 0x7CC, 0x7C8, 0x7C4, 0x20D, 0x20E, 0x20F}, - { - 198, 4990, 3327, 0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, - 0x0F, 0x8F, 0x7D0, 0x7CC, 0x7C8, 0x20C, 0x20D, 0x20E}, - { - 200, 5000, 3333, 0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, - 0x0F, 0x8F, 0x7D4, 0x7D0, 0x7CC, 0x20B, 0x20C, 0x20D}, - { - 202, 5010, 3340, 0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, - 0x0F, 0x8F, 0x7D8, 0x7D4, 0x7D0, 0x20A, 0x20B, 0x20C}, - { - 204, 5020, 3347, 0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, - 0x0F, 0x8F, 0x7DC, 0x7D8, 0x7D4, 0x209, 0x20A, 0x20B}, - { - 206, 5030, 3353, 0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, - 0x0F, 0x8F, 0x7E0, 0x7DC, 0x7D8, 0x208, 0x209, 0x20A}, - { - 208, 5040, 3360, 0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, - 0x0F, 0x8F, 0x7E4, 0x7E0, 0x7DC, 0x207, 0x208, 0x209}, - { - 210, 5050, 3367, 0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, - 0x0F, 0x8F, 0x7E8, 0x7E4, 0x7E0, 0x206, 0x207, 0x208}, - { - 212, 5060, 3373, 0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E, - 0x0F, 0x8E, 0x7EC, 0x7E8, 0x7E4, 0x205, 0x206, 0x207}, - { - 214, 5070, 3380, 0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, 0x8E, 0xFF, 0x00, 0x0E, - 0x0F, 0x8E, 0x7F0, 0x7EC, 0x7E8, 0x204, 0x205, 0x206}, - { - 216, 5080, 3387, 0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A, - 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E, - 0x0F, 0x8D, 0x7F4, 0x7F0, 0x7EC, 0x203, 0x204, 0x205}, - { - 218, 5090, 3393, 0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A, - 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, 0x8D, 0xEE, 0x00, 0x0E, - 0x0F, 0x8D, 0x7F8, 0x7F4, 0x7F0, 0x202, 0x203, 0x204}, - { - 220, 5100, 3400, 0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A, - 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D, - 0x0F, 0x8D, 0x7FC, 0x7F8, 0x7F4, 0x201, 0x202, 0x203}, - { - 222, 5110, 3407, 0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A, - 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, 0x8D, 0xEE, 0x00, 0x0D, - 0x0F, 0x8D, 0x800, 0x7FC, 0x7F8, 0x200, 0x201, 0x202}, - { - 224, 5120, 3413, 0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A, - 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D, - 0x0F, 0x8C, 0x804, 0x800, 0x7FC, 0x1FF, 0x200, 0x201}, - { - 226, 5130, 3420, 0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A, - 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, 0x8C, 0xDD, 0x00, 0x0D, - 0x0F, 0x8C, 0x808, 0x804, 0x800, 0x1FE, 0x1FF, 0x200}, - { - 228, 5140, 3427, 0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A, - 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E, 0x8B, 0xDD, 0x00, 0x0C, - 0x0E, 0x8B, 0x80C, 0x808, 0x804, 0x1FD, 0x1FE, 0x1FF}, - { - 32, 5160, 3440, 0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A, - 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B, - 0x0D, 0x8A, 0x814, 0x810, 0x80C, 0x1FB, 0x1FC, 0x1FD}, - { - 34, 5170, 3447, 0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A, - 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, 0x8A, 0xCC, 0x00, 0x0B, - 0x0D, 0x8A, 0x818, 0x814, 0x810, 0x1FA, 0x1FB, 0x1FC}, - { - 36, 5180, 3453, 0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A, - 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B, - 0x0C, 0x89, 0x81C, 0x818, 0x814, 0x1F9, 0x1FA, 0x1FB}, - { - 38, 5190, 3460, 0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A, - 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, 0x89, 0xCC, 0x00, 0x0B, - 0x0C, 0x89, 0x820, 0x81C, 0x818, 0x1F8, 0x1F9, 0x1FA}, - { - 40, 5200, 3467, 0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A, - 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A, - 0x0B, 0x89, 0x824, 0x820, 0x81C, 0x1F7, 0x1F8, 0x1F9}, - { - 42, 5210, 3473, 0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A, - 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, 0x89, 0xBB, 0x00, 0x0A, - 0x0B, 0x89, 0x828, 0x824, 0x820, 0x1F6, 0x1F7, 0x1F8}, - { - 44, 5220, 3480, 0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A, - 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09, - 0x0A, 0x88, 0x82C, 0x828, 0x824, 0x1F5, 0x1F6, 0x1F7}, - { - 46, 5230, 3487, 0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A, - 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, 0x88, 0xBB, 0x00, 0x09, - 0x0A, 0x88, 0x830, 0x82C, 0x828, 0x1F4, 0x1F5, 0x1F6}, - { - 48, 5240, 3493, 0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A, - 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09, - 0x0A, 0x87, 0x834, 0x830, 0x82C, 0x1F3, 0x1F4, 0x1F5}, - { - 50, 5250, 3500, 0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A, - 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, 0x87, 0xAA, 0x00, 0x09, - 0x0A, 0x87, 0x838, 0x834, 0x830, 0x1F2, 0x1F3, 0x1F4}, - { - 52, 5260, 3507, 0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A, - 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08, - 0x09, 0x87, 0x83C, 0x838, 0x834, 0x1F1, 0x1F2, 0x1F3}, - { - 54, 5270, 3513, 0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A, - 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, 0x87, 0xAA, 0x00, 0x08, - 0x09, 0x87, 0x840, 0x83C, 0x838, 0x1F0, 0x1F1, 0x1F2}, - { - 56, 5280, 3520, 0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A, - 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08, - 0x08, 0x86, 0x844, 0x840, 0x83C, 0x1F0, 0x1F0, 0x1F1}, - { - 58, 5290, 3527, 0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A, - 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, 0x86, 0x99, 0x00, 0x08, - 0x08, 0x86, 0x848, 0x844, 0x840, 0x1EF, 0x1F0, 0x1F0}, - { - 60, 5300, 3533, 0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A, - 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08, - 0x07, 0x85, 0x84C, 0x848, 0x844, 0x1EE, 0x1EF, 0x1F0}, - { - 62, 5310, 3540, 0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A, - 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, 0x85, 0x99, 0x00, 0x08, - 0x07, 0x85, 0x850, 0x84C, 0x848, 0x1ED, 0x1EE, 0x1EF}, - { - 64, 5320, 3547, 0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A, - 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07, - 0x07, 0x84, 0x854, 0x850, 0x84C, 0x1EC, 0x1ED, 0x1EE}, - { - 66, 5330, 3553, 0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A, - 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, 0x84, 0x88, 0x00, 0x07, - 0x07, 0x84, 0x858, 0x854, 0x850, 0x1EB, 0x1EC, 0x1ED}, - { - 68, 5340, 3560, 0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A, - 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07, - 0x06, 0x84, 0x85C, 0x858, 0x854, 0x1EA, 0x1EB, 0x1EC}, - { - 70, 5350, 3567, 0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A, - 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, 0x84, 0x88, 0x00, 0x07, - 0x06, 0x84, 0x860, 0x85C, 0x858, 0x1E9, 0x1EA, 0x1EB}, - { - 72, 5360, 3573, 0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A, - 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06, - 0x05, 0x83, 0x864, 0x860, 0x85C, 0x1E8, 0x1E9, 0x1EA}, - { - 74, 5370, 3580, 0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A, - 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, 0x83, 0x77, 0x00, 0x06, - 0x05, 0x83, 0x868, 0x864, 0x860, 0x1E7, 0x1E8, 0x1E9}, - { - 76, 5380, 3587, 0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A, - 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06, - 0x04, 0x82, 0x86C, 0x868, 0x864, 0x1E6, 0x1E7, 0x1E8}, - { - 78, 5390, 3593, 0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A, - 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, 0x82, 0x77, 0x00, 0x06, - 0x04, 0x82, 0x870, 0x86C, 0x868, 0x1E5, 0x1E6, 0x1E7}, - { - 80, 5400, 3600, 0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A, - 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05, - 0x04, 0x81, 0x874, 0x870, 0x86C, 0x1E5, 0x1E5, 0x1E6}, - { - 82, 5410, 3607, 0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A, - 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, 0x81, 0x66, 0x00, 0x05, - 0x04, 0x81, 0x878, 0x874, 0x870, 0x1E4, 0x1E5, 0x1E5}, - { - 84, 5420, 3613, 0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A, - 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05, - 0x03, 0x80, 0x87C, 0x878, 0x874, 0x1E3, 0x1E4, 0x1E5}, - { - 86, 5430, 3620, 0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A, - 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, 0x80, 0x66, 0x00, 0x05, - 0x03, 0x80, 0x880, 0x87C, 0x878, 0x1E2, 0x1E3, 0x1E4}, - { - 88, 5440, 3627, 0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A, - 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04, - 0x02, 0x80, 0x884, 0x880, 0x87C, 0x1E1, 0x1E2, 0x1E3}, - { - 90, 5450, 3633, 0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A, - 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, 0x80, 0x55, 0x00, 0x04, - 0x02, 0x80, 0x888, 0x884, 0x880, 0x1E0, 0x1E1, 0x1E2}, - { - 92, 5460, 3640, 0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A, - 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04, - 0x01, 0x80, 0x88C, 0x888, 0x884, 0x1DF, 0x1E0, 0x1E1}, - { - 94, 5470, 3647, 0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A, - 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, 0x80, 0x55, 0x00, 0x04, - 0x01, 0x80, 0x890, 0x88C, 0x888, 0x1DE, 0x1DF, 0x1E0}, - { - 96, 5480, 3653, 0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A, - 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03, - 0x00, 0x80, 0x894, 0x890, 0x88C, 0x1DD, 0x1DE, 0x1DF}, - { - 98, 5490, 3660, 0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A, - 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03, - 0x00, 0x80, 0x898, 0x894, 0x890, 0x1DD, 0x1DD, 0x1DE}, - { - 100, 5500, 3667, 0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A, - 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03, - 0x00, 0x80, 0x89C, 0x898, 0x894, 0x1DC, 0x1DD, 0x1DD}, - { - 102, 5510, 3673, 0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A, - 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x44, 0x00, 0x03, - 0x00, 0x80, 0x8A0, 0x89C, 0x898, 0x1DB, 0x1DC, 0x1DD}, - { - 104, 5520, 3680, 0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A, - 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02, - 0x00, 0x80, 0x8A4, 0x8A0, 0x89C, 0x1DA, 0x1DB, 0x1DC}, - { - 106, 5530, 3687, 0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A, - 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02, - 0x00, 0x80, 0x8A8, 0x8A4, 0x8A0, 0x1D9, 0x1DA, 0x1DB}, - { - 108, 5540, 3693, 0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A, - 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02, - 0x00, 0x80, 0x8AC, 0x8A8, 0x8A4, 0x1D8, 0x1D9, 0x1DA}, - { - 110, 5550, 3700, 0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A, - 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, 0x80, 0x33, 0x00, 0x02, - 0x00, 0x80, 0x8B0, 0x8AC, 0x8A8, 0x1D7, 0x1D8, 0x1D9}, - { - 112, 5560, 3707, 0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A, - 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01, - 0x00, 0x80, 0x8B4, 0x8B0, 0x8AC, 0x1D7, 0x1D7, 0x1D8}, - { - 114, 5570, 3713, 0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A, - 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01, - 0x00, 0x80, 0x8B8, 0x8B4, 0x8B0, 0x1D6, 0x1D7, 0x1D7}, - { - 116, 5580, 3720, 0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A, - 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01, - 0x00, 0x80, 0x8BC, 0x8B8, 0x8B4, 0x1D5, 0x1D6, 0x1D7}, - { - 118, 5590, 3727, 0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A, - 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, 0x80, 0x22, 0x00, 0x01, - 0x00, 0x80, 0x8C0, 0x8BC, 0x8B8, 0x1D4, 0x1D5, 0x1D6}, - { - 120, 5600, 3733, 0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A, - 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01, - 0x00, 0x80, 0x8C4, 0x8C0, 0x8BC, 0x1D3, 0x1D4, 0x1D5}, - { - 122, 5610, 3740, 0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A, - 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x80, 0x11, 0x00, 0x01, - 0x00, 0x80, 0x8C8, 0x8C4, 0x8C0, 0x1D2, 0x1D3, 0x1D4}, - { - 124, 5620, 3747, 0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A, - 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, - 0x00, 0x80, 0x8CC, 0x8C8, 0x8C4, 0x1D2, 0x1D2, 0x1D3}, - { - 126, 5630, 3753, 0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A, - 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, - 0x00, 0x80, 0x8D0, 0x8CC, 0x8C8, 0x1D1, 0x1D2, 0x1D2}, - { - 128, 5640, 3760, 0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x8D4, 0x8D0, 0x8CC, 0x1D0, 0x1D1, 0x1D2}, - { - 130, 5650, 3767, 0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x8D8, 0x8D4, 0x8D0, 0x1CF, 0x1D0, 0x1D1}, - { - 132, 5660, 3773, 0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x8DC, 0x8D8, 0x8D4, 0x1CE, 0x1CF, 0x1D0}, - { - 134, 5670, 3780, 0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x8E0, 0x8DC, 0x8D8, 0x1CE, 0x1CE, 0x1CF}, - { - 136, 5680, 3787, 0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x8E4, 0x8E0, 0x8DC, 0x1CD, 0x1CE, 0x1CE}, - { - 138, 5690, 3793, 0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x8E8, 0x8E4, 0x8E0, 0x1CC, 0x1CD, 0x1CE}, - { - 140, 5700, 3800, 0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x8EC, 0x8E8, 0x8E4, 0x1CB, 0x1CC, 0x1CD}, - { - 142, 5710, 3807, 0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x8F0, 0x8EC, 0x8E8, 0x1CA, 0x1CB, 0x1CC}, - { - 144, 5720, 3813, 0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x8F4, 0x8F0, 0x8EC, 0x1C9, 0x1CA, 0x1CB}, - { - 145, 5725, 3817, 0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x8F6, 0x8F2, 0x8EE, 0x1C9, 0x1CA, 0x1CB}, - { - 146, 5730, 3820, 0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x8F8, 0x8F4, 0x8F0, 0x1C9, 0x1C9, 0x1CA}, - { - 147, 5735, 3823, 0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x8FA, 0x8F6, 0x8F2, 0x1C8, 0x1C9, 0x1CA}, - { - 148, 5740, 3827, 0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x8FC, 0x8F8, 0x8F4, 0x1C8, 0x1C9, 0x1C9}, - { - 149, 5745, 3830, 0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x8FE, 0x8FA, 0x8F6, 0x1C8, 0x1C8, 0x1C9}, - { - 150, 5750, 3833, 0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x900, 0x8FC, 0x8F8, 0x1C7, 0x1C8, 0x1C9}, - { - 151, 5755, 3837, 0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x902, 0x8FE, 0x8FA, 0x1C7, 0x1C8, 0x1C8}, - { - 152, 5760, 3840, 0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x904, 0x900, 0x8FC, 0x1C6, 0x1C7, 0x1C8}, - { - 153, 5765, 3843, 0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x906, 0x902, 0x8FE, 0x1C6, 0x1C7, 0x1C8}, - { - 154, 5770, 3847, 0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x908, 0x904, 0x900, 0x1C6, 0x1C6, 0x1C7}, - { - 155, 5775, 3850, 0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x90A, 0x906, 0x902, 0x1C5, 0x1C6, 0x1C7}, - { - 156, 5780, 3853, 0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x90C, 0x908, 0x904, 0x1C5, 0x1C6, 0x1C6}, - { - 157, 5785, 3857, 0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x90E, 0x90A, 0x906, 0x1C4, 0x1C5, 0x1C6}, - { - 158, 5790, 3860, 0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x910, 0x90C, 0x908, 0x1C4, 0x1C5, 0x1C6}, - { - 159, 5795, 3863, 0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x912, 0x90E, 0x90A, 0x1C4, 0x1C4, 0x1C5}, - { - 160, 5800, 3867, 0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x914, 0x910, 0x90C, 0x1C3, 0x1C4, 0x1C5}, - { - 161, 5805, 3870, 0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x916, 0x912, 0x90E, 0x1C3, 0x1C4, 0x1C4}, - { - 162, 5810, 3873, 0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x918, 0x914, 0x910, 0x1C2, 0x1C3, 0x1C4}, - { - 163, 5815, 3877, 0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x91A, 0x916, 0x912, 0x1C2, 0x1C3, 0x1C4}, - { - 164, 5820, 3880, 0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x91C, 0x918, 0x914, 0x1C2, 0x1C2, 0x1C3}, - { - 165, 5825, 3883, 0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x91E, 0x91A, 0x916, 0x1C1, 0x1C2, 0x1C3}, - { - 166, 5830, 3887, 0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x920, 0x91C, 0x918, 0x1C1, 0x1C2, 0x1C2}, - { - 168, 5840, 3893, 0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x924, 0x920, 0x91C, 0x1C0, 0x1C1, 0x1C2}, - { - 170, 5850, 3900, 0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x928, 0x924, 0x920, 0x1BF, 0x1C0, 0x1C1}, - { - 172, 5860, 3907, 0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x92C, 0x928, 0x924, 0x1BF, 0x1BF, 0x1C0}, - { - 174, 5870, 3913, 0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x930, 0x92C, 0x928, 0x1BE, 0x1BF, 0x1BF}, - { - 176, 5880, 3920, 0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x934, 0x930, 0x92C, 0x1BD, 0x1BE, 0x1BF}, - { - 178, 5890, 3927, 0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x938, 0x934, 0x930, 0x1BC, 0x1BD, 0x1BE}, - { - 180, 5900, 3933, 0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x93C, 0x938, 0x934, 0x1BC, 0x1BC, 0x1BD}, - { - 182, 5910, 3940, 0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x940, 0x93C, 0x938, 0x1BB, 0x1BC, 0x1BC}, - { - 1, 2412, 3216, 0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C, 0x80, 0xFF, 0x88, 0x0D, - 0x0C, 0x80, 0x3C9, 0x3C5, 0x3C1, 0x43A, 0x43F, 0x443}, - { - 2, 2417, 3223, 0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B, 0x80, 0xFF, 0x88, 0x0C, - 0x0B, 0x80, 0x3CB, 0x3C7, 0x3C3, 0x438, 0x43D, 0x441}, - { - 3, 2422, 3229, 0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C, - 0x0A, 0x80, 0x3CD, 0x3C9, 0x3C5, 0x436, 0x43A, 0x43F}, - { - 4, 2427, 3236, 0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, 0x80, 0xFF, 0x88, 0x0C, - 0x0A, 0x80, 0x3CF, 0x3CB, 0x3C7, 0x434, 0x438, 0x43D}, - { - 5, 2432, 3243, 0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09, 0x80, 0xFF, 0x88, 0x0C, - 0x09, 0x80, 0x3D1, 0x3CD, 0x3C9, 0x431, 0x436, 0x43A}, - { - 6, 2437, 3249, 0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08, 0x80, 0xFF, 0x88, 0x0B, - 0x08, 0x80, 0x3D3, 0x3CF, 0x3CB, 0x42F, 0x434, 0x438}, - { - 7, 2442, 3256, 0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07, 0x80, 0xFF, 0x88, 0x0A, - 0x07, 0x80, 0x3D5, 0x3D1, 0x3CD, 0x42D, 0x431, 0x436}, - { - 8, 2447, 3263, 0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06, 0x80, 0xFF, 0x88, 0x0A, - 0x06, 0x80, 0x3D7, 0x3D3, 0x3CF, 0x42B, 0x42F, 0x434}, - { - 9, 2452, 3269, 0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06, 0x80, 0xFF, 0x88, 0x09, - 0x06, 0x80, 0x3D9, 0x3D5, 0x3D1, 0x429, 0x42D, 0x431}, - { - 10, 2457, 3276, 0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05, 0x80, 0xFF, 0x88, 0x08, - 0x05, 0x80, 0x3DB, 0x3D7, 0x3D3, 0x427, 0x42B, 0x42F}, - { - 11, 2462, 3283, 0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04, 0x80, 0xFF, 0x88, 0x08, - 0x04, 0x80, 0x3DD, 0x3D9, 0x3D5, 0x424, 0x429, 0x42D}, - { - 12, 2467, 3289, 0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03, 0x80, 0xFF, 0x88, 0x08, - 0x03, 0x80, 0x3DF, 0x3DB, 0x3D7, 0x422, 0x427, 0x42B}, - { - 13, 2472, 3296, 0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03, 0x80, 0xFF, 0x88, 0x07, - 0x03, 0x80, 0x3E1, 0x3DD, 0x3D9, 0x420, 0x424, 0x429}, - { - 14, 2484, 3312, 0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01, 0x80, 0xFF, 0x88, 0x07, - 0x01, 0x80, 0x3E6, 0x3E2, 0x3DE, 0x41B, 0x41F, 0x424} -}; - -static chan_info_nphy_radio205x_t chan_info_nphyrev3_2056[] = { - { - 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216}, - { - 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215}, - { - 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214}, - { - 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213}, - { - 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212}, - { - 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211}, - { - 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f}, - { - 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e}, - { - 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d}, - { - 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c}, - { - 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b}, - { - 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a}, - { - 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209}, - { - 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208}, - { - 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207}, - { - 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206}, - { - 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205}, - { - 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204}, - { - 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xff, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xff, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203}, - { - 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xfc, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202}, - { - 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xfc, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201}, - { - 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xfc, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200}, - { - 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xfc, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff}, - { - 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xfc, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd}, - { - 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xfc, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc}, - { - 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xfc, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb}, - { - 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xfc, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa}, - { - 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9}, - { - 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8}, - { - 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7}, - { - 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6}, - { - 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5}, - { - 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4}, - { - 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3}, - { - 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2}, - { - 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1}, - { - 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0}, - { - 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xfc, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0}, - { - 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef}, - { - 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x05, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee}, - { - 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed}, - { - 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x05, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec}, - { - 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb}, - { - 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea}, - { - 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9}, - { - 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x05, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8}, - { - 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x05, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x05, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7}, - { - 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, - 0x00, 0xfa, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6}, - { - 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, - 0x00, 0xfa, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5}, - { - 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, - 0x00, 0xfa, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5}, - { - 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x08, 0x00, 0xfa, 0x00, 0x8e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, - 0x00, 0xfa, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4}, - { - 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7e, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, - 0x00, 0xfa, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3}, - { - 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x08, 0x00, 0xfa, 0x00, 0x7d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, - 0x00, 0xfa, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2}, - { - 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, - 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1}, - { - 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x08, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, - 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0}, - { - 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, - 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df}, - { - 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x08, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x08, - 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de}, - { - 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf8, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd}, - { - 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf8, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd}, - { - 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf8, 0x00, 0x4c, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf8, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc}, - { - 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf8, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db}, - { - 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf8, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da}, - { - 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf8, 0x00, 0x3b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf8, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9}, - { - 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2b, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf8, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8}, - { - 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf8, 0x00, 0x2a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf8, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7}, - { - 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf8, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7}, - { - 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf8, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6}, - { - 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf8, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf8, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5}, - { - 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf8, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4}, - { - 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf8, 0x00, 0x19, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf8, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3}, - { - 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf8, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2}, - { - 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf8, 0x00, 0x09, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf8, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2}, - { - 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf8, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf8, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1}, - { - 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf6, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0}, - { - 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf6, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf}, - { - 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf6, 0x00, 0x08, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf6, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce}, - { - 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf6, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce}, - { - 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf6, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf6, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd}, - { - 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc}, - { - 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb}, - { - 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb}, - { - 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca}, - { - 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca}, - { - 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9}, - { - 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9}, - { - 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x06, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9}, - { - 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8}, - { - 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8}, - { - 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8}, - { - 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7}, - { - 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7}, - { - 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6}, - { - 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6}, - { - 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6}, - { - 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5}, - { - 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5}, - { - 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4}, - { - 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4}, - { - 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4}, - { - 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3}, - { - 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3}, - { - 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2}, - { - 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2}, - { - 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf4, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf4, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1}, - { - 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf2, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf2, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0}, - { - 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf2, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf}, - { - 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf2, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf}, - { - 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x06, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x06, - 0x00, 0xf2, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be}, - { - 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x05, 0x00, 0xf2, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05, - 0x00, 0xf2, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd}, - { - 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x05, 0x00, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x05, - 0x00, 0xf2, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc}, - { - 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0f, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443}, - { - 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0f, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441}, - { - 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x05, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0f, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f}, - { - 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x05, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfd, 0x00, 0x05, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0f, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d}, - { - 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x05, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfb, 0x00, 0x05, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0f, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a}, - { - 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x05, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x05, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0f, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438}, - { - 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x05, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x05, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0f, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436}, - { - 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x05, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf7, 0x00, 0x05, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0f, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434}, - { - 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x05, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf6, 0x00, 0x05, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0f, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431}, - { - 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x05, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf5, 0x00, 0x05, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0d, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f}, - { - 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x05, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf4, 0x00, 0x05, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0d, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d}, - { - 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x05, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf3, 0x00, 0x05, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0d, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b}, - { - 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x05, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0d, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429}, - { - 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x05, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0xf0, 0x00, 0x05, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0d, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} -}; - -static chan_info_nphy_radio205x_t chan_info_nphyrev4_2056_A1[] = { - { - 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xff, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216}, - { - 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xff, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215}, - { - 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xff, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214}, - { - 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xff, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213}, - { - 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xff, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212}, - { - 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xff, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211}, - { - 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xff, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f}, - { - 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0e, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xff, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e}, - { - 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xff, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d}, - { - 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xff, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c}, - { - 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xff, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b}, - { - 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xff, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a}, - { - 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xff, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209}, - { - 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xff, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208}, - { - 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xff, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207}, - { - 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xff, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206}, - { - 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xff, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205}, - { - 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0d, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xff, 0x00, 0x0d, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xff, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204}, - { - 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfe, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203}, - { - 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfe, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202}, - { - 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfe, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201}, - { - 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfe, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200}, - { - 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfe, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff}, - { - 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfe, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd}, - { - 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfe, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc}, - { - 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfe, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb}, - { - 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0c, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfe, 0x00, 0xef, 0x00, 0x0c, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfe, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa}, - { - 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xef, 0x00, 0x0a, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xef, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfc, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9}, - { - 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfc, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8}, - { - 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfc, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7}, - { - 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xdf, 0x00, 0x0a, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xdf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfc, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6}, - { - 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfc, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5}, - { - 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfc, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4}, - { - 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfc, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3}, - { - 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xcf, 0x00, 0x0a, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xcf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfc, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2}, - { - 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfc, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1}, - { - 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xbf, 0x00, 0x0a, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfc, 0x00, 0xbf, 0x00, 0x0a, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfc, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0}, - { - 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfa, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0}, - { - 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfa, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef}, - { - 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xbf, 0x00, 0x08, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xbf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfa, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee}, - { - 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfa, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed}, - { - 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xaf, 0x00, 0x08, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfa, 0x00, 0xaf, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfa, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec}, - { - 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfa, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb}, - { - 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfa, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea}, - { - 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfa, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9}, - { - 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x9f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfa, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8}, - { - 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x8f, 0x00, 0x08, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xfa, 0x00, 0x8f, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xfa, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7}, - { - 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xf8, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6}, - { - 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8f, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8f, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xf8, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5}, - { - 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xf8, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5}, - { - 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x8e, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x8e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xf8, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4}, - { - 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7e, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7e, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xf8, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3}, - { - 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x7d, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x7d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xf8, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2}, - { - 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xf8, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1}, - { - 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x6d, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x6d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xf8, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0}, - { - 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5d, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5d, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xf8, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df}, - { - 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x5c, 0x00, 0x07, 0x00, 0x7f, - 0x00, 0x0f, 0x00, 0xf8, 0x00, 0x5c, 0x00, 0x07, 0x00, 0x7f, 0x00, 0x0f, - 0x00, 0xf8, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de}, - { - 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x5c, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x5c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, - 0x00, 0xf6, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd}, - { - 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, - 0x00, 0xf6, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd}, - { - 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x4c, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x4c, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, - 0x00, 0xf6, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc}, - { - 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, - 0x00, 0xf6, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db}, - { - 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, - 0x00, 0xf6, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da}, - { - 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x3b, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, - 0x00, 0xf6, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9}, - { - 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2b, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2b, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, - 0x00, 0xf6, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8}, - { - 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x2a, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x2a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, - 0x00, 0xf6, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7}, - { - 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, - 0x00, 0xf6, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7}, - { - 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x1a, 0x00, 0x06, 0x00, 0x7f, - 0x00, 0x0d, 0x00, 0xf6, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x7f, 0x00, 0x0d, - 0x00, 0xf6, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6}, - { - 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x1a, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x1a, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xf4, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5}, - { - 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xf4, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4}, - { - 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x19, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x19, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xf4, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3}, - { - 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xf4, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2}, - { - 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x09, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x09, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xf4, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2}, - { - 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xf4, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1}, - { - 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xf4, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0}, - { - 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xf4, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf}, - { - 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x08, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x08, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xf4, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce}, - { - 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x07, 0x00, 0x04, 0x00, 0x7f, - 0x00, 0x0b, 0x00, 0xf4, 0x00, 0x07, 0x00, 0x04, 0x00, 0x7f, 0x00, 0x0b, - 0x00, 0xf4, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce}, - { - 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xf2, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd}, - { - 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xf2, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc}, - { - 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x07, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x07, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xf2, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb}, - { - 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xf2, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb}, - { - 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xf2, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca}, - { - 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xf2, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca}, - { - 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xf2, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9}, - { - 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xf2, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9}, - { - 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x06, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x06, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xf2, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9}, - { - 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xf2, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8}, - { - 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xf2, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8}, - { - 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xf2, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8}, - { - 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xf2, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7}, - { - 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xf2, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7}, - { - 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x05, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xf2, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6}, - { - 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xf2, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6}, - { - 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xf2, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6}, - { - 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x04, 0x00, 0x03, 0x00, 0x7f, - 0x00, 0x0a, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x03, 0x00, 0x7f, 0x00, 0x0a, - 0x00, 0xf2, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5}, - { - 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xf0, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5}, - { - 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xf0, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4}, - { - 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xf0, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4}, - { - 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xf0, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4}, - { - 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xf0, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3}, - { - 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xf0, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3}, - { - 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xf0, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2}, - { - 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xf0, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2}, - { - 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xf0, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1}, - { - 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x03, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xf0, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0}, - { - 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xf0, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf}, - { - 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xf0, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf}, - { - 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x02, 0x00, 0x02, 0x00, 0x7f, - 0x00, 0x09, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x09, - 0x00, 0xf0, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be}, - { - 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf0, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd}, - { - 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x07, 0x00, 0xf0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x07, - 0x00, 0xf0, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc}, - { - 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0e, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443}, - { - 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0e, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441}, - { - 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x04, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xff, 0x00, 0x04, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0e, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f}, - { - 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x04, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfd, 0x00, 0x04, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0e, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d}, - { - 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x04, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfb, 0x00, 0x04, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0e, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a}, - { - 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0e, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438}, - { - 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x04, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf8, 0x00, 0x04, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0e, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436}, - { - 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x04, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf7, 0x00, 0x04, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0e, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434}, - { - 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf6, 0x00, 0x04, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0e, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431}, - { - 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x04, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf5, 0x00, 0x04, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0e, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f}, - { - 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x04, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf4, 0x00, 0x04, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0e, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d}, - { - 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x04, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf3, 0x00, 0x04, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0e, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b}, - { - 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x04, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf2, 0x00, 0x04, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0e, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429}, - { - 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x04, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0xf0, 0x00, 0x04, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0e, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} -}; - -static chan_info_nphy_radio205x_t chan_info_nphyrev5_2056v5[] = { - { - 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, - 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216}, - { - 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, - 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e, - 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215}, - { - 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, - 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e, - 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214}, - { - 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, - 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e, - 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213}, - { - 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, - 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e, - 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212}, - { - 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, - 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211}, - { - 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, - 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f}, - { - 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, - 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e}, - { - 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, - 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d}, - { - 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, - 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c}, - { - 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, - 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b}, - { - 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, - 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a}, - { - 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, - 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209}, - { - 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, - 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208}, - { - 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70, - 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207}, - { - 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70, - 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206}, - { - 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, - 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205}, - { - 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, - 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204}, - { - 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, - 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203}, - { - 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, - 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202}, - { - 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, - 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201}, - { - 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70, - 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200}, - { - 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, - 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff}, - { - 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, - 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09, - 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd}, - { - 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70, - 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, - 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc}, - { - 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, - 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, - 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb}, - { - 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, - 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, - 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa}, - { - 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, - 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, - 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9}, - { - 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, - 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, - 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8}, - { - 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, - 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, - 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7}, - { - 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xea, 0x00, 0x06, 0x00, 0x70, - 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08, - 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6}, - { - 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70, - 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08, - 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5}, - { - 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xe9, 0x00, 0x05, 0x00, 0x70, - 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08, - 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4}, - { - 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xd9, 0x00, 0x05, 0x00, 0x70, - 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08, - 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3}, - { - 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xd8, 0x00, 0x04, 0x00, 0x70, - 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, - 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2}, - { - 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, - 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, - 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1}, - { - 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0f, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, - 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, - 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0}, - { - 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, - 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, - 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0}, - { - 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xc8, 0x00, 0x04, 0x00, 0x70, - 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, - 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef}, - { - 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb8, 0x00, 0x04, 0x00, 0x70, - 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, - 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee}, - { - 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x04, 0x00, 0x70, - 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, - 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed}, - { - 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xb7, 0x00, 0x03, 0x00, 0x70, - 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07, - 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec}, - { - 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa7, 0x00, 0x03, 0x00, 0x70, - 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, - 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb}, - { - 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70, - 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, - 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea}, - { - 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x70, - 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, - 0x00, 0x5b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9}, - { - 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x96, 0x00, 0x03, 0x00, 0x70, - 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, - 0x00, 0x5a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8}, - { - 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8f, 0x0e, 0x00, 0xff, 0x95, 0x00, 0x03, 0x00, 0x70, - 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, - 0x00, 0x5a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7}, - { - 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70, - 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, - 0x00, 0x5a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6}, - { - 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70, - 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05, - 0x00, 0x5a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5}, - { - 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x95, 0x00, 0x03, 0x00, 0x70, - 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05, - 0x00, 0x5a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5}, - { - 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xc8, 0x85, 0x00, 0x02, 0x00, 0x70, - 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05, - 0x00, 0x59, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4}, - { - 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70, - 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05, - 0x00, 0x59, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3}, - { - 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70, - 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05, - 0x00, 0x59, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2}, - { - 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x84, 0x00, 0x02, 0x00, 0x70, - 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04, - 0x00, 0x69, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1}, - { - 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x74, 0x00, 0x01, 0x00, 0x70, - 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, - 0x00, 0x69, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0}, - { - 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70, - 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, - 0x00, 0x68, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df}, - { - 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0d, 0x00, 0xc8, 0x73, 0x00, 0x01, 0x00, 0x70, - 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, - 0x00, 0x68, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de}, - { - 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, - 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, - 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd}, - { - 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, - 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, - 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd}, - { - 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, - 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, - 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc}, - { - 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x63, 0x00, 0x01, 0x00, 0x70, - 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03, - 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db}, - { - 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, - 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da}, - { - 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, - 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9}, - { - 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x62, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, - 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8}, - { - 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, - 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7}, - { - 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x52, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, - 0x00, 0x76, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7}, - { - 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8d, 0x0b, 0x00, 0x84, 0x51, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, - 0x00, 0x76, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6}, - { - 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, - 0x00, 0x76, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5}, - { - 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, - 0x00, 0x76, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4}, - { - 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, - 0x00, 0x76, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3}, - { - 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, - 0x00, 0x76, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2}, - { - 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x51, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, - 0x00, 0x75, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2}, - { - 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x75, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1}, - { - 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x50, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x75, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0}, - { - 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x74, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf}, - { - 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x74, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce}, - { - 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8b, 0x09, 0x00, 0x70, 0x40, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x74, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce}, - { - 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x74, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd}, - { - 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x74, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc}, - { - 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x74, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb}, - { - 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x74, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb}, - { - 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x84, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca}, - { - 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x83, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca}, - { - 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x83, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9}, - { - 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x83, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9}, - { - 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x83, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9}, - { - 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x83, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8}, - { - 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x83, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8}, - { - 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x82, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8}, - { - 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x82, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7}, - { - 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x82, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7}, - { - 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x82, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6}, - { - 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x82, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6}, - { - 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x82, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6}, - { - 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x8a, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x82, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5}, - { - 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x82, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5}, - { - 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x82, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4}, - { - 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x82, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4}, - { - 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x82, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4}, - { - 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x82, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3}, - { - 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x82, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3}, - { - 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x72, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2}, - { - 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x72, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2}, - { - 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x72, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1}, - { - 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x72, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0}, - { - 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x71, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf}, - { - 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x71, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf}, - { - 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x88, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x71, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be}, - { - 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x71, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd}, - { - 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x87, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x71, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc}, - { - 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443}, - { - 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441}, - { - 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f}, - { - 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d}, - { - 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a}, - { - 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438}, - { - 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x09, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436}, - { - 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x08, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434}, - { - 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x07, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431}, - { - 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x06, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f}, - { - 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x05, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d}, - { - 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b}, - { - 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x03, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429}, - { - 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} -}; - -static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v6[] = { - { - 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216}, - { - 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215}, - { - 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214}, - { - 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213}, - { - 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212}, - { - 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211}, - { - 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f}, - { - 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e}, - { - 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d}, - { - 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c}, - { - 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b}, - { - 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a}, - { - 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209}, - { - 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208}, - { - 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207}, - { - 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206}, - { - 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205}, - { - 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204}, - { - 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203}, - { - 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202}, - { - 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201}, - { - 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200}, - { - 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff}, - { - 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, - 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e, - 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd}, - { - 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, - 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e, - 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc}, - { - 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, - 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e, - 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb}, - { - 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa}, - { - 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9}, - { - 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8}, - { - 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7}, - { - 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6}, - { - 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5}, - { - 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4}, - { - 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3}, - { - 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, - 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2}, - { - 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1}, - { - 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0}, - { - 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0}, - { - 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef}, - { - 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee}, - { - 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed}, - { - 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec}, - { - 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb}, - { - 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea}, - { - 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9}, - { - 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8}, - { - 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7}, - { - 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6}, - { - 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5}, - { - 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5}, - { - 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4}, - { - 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3}, - { - 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2}, - { - 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1}, - { - 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0}, - { - 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df}, - { - 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de}, - { - 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd}, - { - 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd}, - { - 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc}, - { - 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db}, - { - 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da}, - { - 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9}, - { - 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8}, - { - 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7}, - { - 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, - 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7}, - { - 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, - 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6}, - { - 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, - 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5}, - { - 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, - 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4}, - { - 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, - 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3}, - { - 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, - 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2}, - { - 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, - 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2}, - { - 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, - 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1}, - { - 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0}, - { - 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf}, - { - 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce}, - { - 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce}, - { - 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd}, - { - 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc}, - { - 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb}, - { - 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb}, - { - 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca}, - { - 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca}, - { - 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9}, - { - 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9}, - { - 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9}, - { - 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8}, - { - 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8}, - { - 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8}, - { - 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7}, - { - 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7}, - { - 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6}, - { - 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6}, - { - 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6}, - { - 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5}, - { - 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5}, - { - 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4}, - { - 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4}, - { - 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4}, - { - 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3}, - { - 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3}, - { - 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2}, - { - 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2}, - { - 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1}, - { - 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0}, - { - 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf}, - { - 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf}, - { - 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be}, - { - 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd}, - { - 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc}, - { - 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443}, - { - 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441}, - { - 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x67, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f}, - { - 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x57, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d}, - { - 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x56, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a}, - { - 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x46, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438}, - { - 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436}, - { - 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434}, - { - 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x23, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431}, - { - 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x12, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f}, - { - 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x02, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d}, - { - 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b}, - { - 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429}, - { - 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} -}; - -static chan_info_nphy_radio205x_t chan_info_nphyrev5n6_2056v7[] = { - { - 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, - 0x00, 0x0f, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216}, - { - 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, - 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e, - 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215}, - { - 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, - 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e, - 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214}, - { - 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, - 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0b, 0x00, 0x70, 0x00, 0x0e, - 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213}, - { - 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, - 0x00, 0x0e, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0e, - 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212}, - { - 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, - 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211}, - { - 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, - 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f}, - { - 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, - 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e}, - { - 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, - 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d}, - { - 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x70, - 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x0a, 0x00, 0x70, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c}, - { - 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, - 0x00, 0x0d, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b}, - { - 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x09, 0x00, 0x70, - 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xff, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a}, - { - 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, - 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209}, - { - 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x70, - 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208}, - { - 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x70, - 0x00, 0x0c, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x70, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207}, - { - 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x70, - 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206}, - { - 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, - 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205}, - { - 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, - 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204}, - { - 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, - 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203}, - { - 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, - 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202}, - { - 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x70, - 0x00, 0x0b, 0x00, 0x9f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201}, - { - 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x70, - 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x70, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200}, - { - 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, - 0x00, 0x0a, 0x00, 0x9f, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff}, - { - 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x07, 0x00, 0x70, - 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x07, 0x00, 0x70, 0x00, 0x09, - 0x00, 0x6e, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd}, - { - 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x06, 0x00, 0x70, - 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfb, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, - 0x00, 0x6e, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc}, - { - 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, - 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, - 0x00, 0x6e, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb}, - { - 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, - 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, - 0x00, 0x6e, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa}, - { - 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, - 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, - 0x00, 0x6e, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9}, - { - 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x06, 0x00, 0x70, - 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, - 0x00, 0x6e, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8}, - { - 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xfa, 0x00, 0x06, 0x00, 0x70, - 0x00, 0x09, 0x00, 0x9e, 0x00, 0xfa, 0x00, 0x06, 0x00, 0x70, 0x00, 0x09, - 0x00, 0x6e, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7}, - { - 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xea, 0x00, 0x06, 0x00, 0x70, - 0x00, 0x08, 0x00, 0x9e, 0x00, 0xea, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08, - 0x00, 0x6e, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6}, - { - 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xe9, 0x00, 0x05, 0x00, 0x70, - 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08, - 0x00, 0x6d, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5}, - { - 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xe9, 0x00, 0x05, 0x00, 0x70, - 0x00, 0x08, 0x00, 0x9d, 0x00, 0xe9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08, - 0x00, 0x6d, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4}, - { - 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xd9, 0x00, 0x05, 0x00, 0x70, - 0x00, 0x08, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0x05, 0x00, 0x70, 0x00, 0x08, - 0x00, 0x6d, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3}, - { - 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xd8, 0x00, 0x04, 0x00, 0x70, - 0x00, 0x07, 0x00, 0x9c, 0x00, 0xd8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, - 0x00, 0x6c, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2}, - { - 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, - 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, - 0x00, 0x6c, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1}, - { - 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, - 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, - 0x00, 0x6c, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0}, - { - 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, - 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, - 0x00, 0x6c, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0}, - { - 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xc8, 0x00, 0x04, 0x00, 0x70, - 0x00, 0x07, 0x00, 0x9c, 0x00, 0xc8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, - 0x00, 0x6c, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef}, - { - 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb8, 0x00, 0x04, 0x00, 0x70, - 0x00, 0x07, 0x00, 0x9c, 0x00, 0xb8, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, - 0x00, 0x6c, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee}, - { - 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xb7, 0x00, 0x04, 0x00, 0x70, - 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, - 0x00, 0x6b, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed}, - { - 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xb7, 0x00, 0x03, 0x00, 0x70, - 0x00, 0x07, 0x00, 0x9b, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x07, - 0x00, 0x6b, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec}, - { - 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa7, 0x00, 0x03, 0x00, 0x70, - 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, - 0x00, 0x6b, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb}, - { - 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70, - 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, - 0x00, 0x6b, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea}, - { - 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0xa6, 0x00, 0x03, 0x00, 0x70, - 0x00, 0x06, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, - 0x00, 0x7b, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9}, - { - 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x96, 0x00, 0x03, 0x00, 0x70, - 0x00, 0x06, 0x00, 0x9a, 0x00, 0x96, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, - 0x00, 0x7a, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8}, - { - 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70, - 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, - 0x00, 0x7a, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7}, - { - 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x70, - 0x00, 0x06, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x06, - 0x00, 0x7a, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6}, - { - 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x95, 0x00, 0x03, 0x00, 0x70, - 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05, - 0x00, 0x7a, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5}, - { - 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x95, 0x00, 0x03, 0x00, 0x70, - 0x00, 0x05, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x03, 0x00, 0x70, 0x00, 0x05, - 0x00, 0x7a, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5}, - { - 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x85, 0x00, 0x02, 0x00, 0x70, - 0x00, 0x05, 0x00, 0x99, 0x00, 0x85, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05, - 0x00, 0x79, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4}, - { - 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x70, - 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05, - 0x00, 0x79, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3}, - { - 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70, - 0x00, 0x05, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x05, - 0x00, 0x79, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2}, - { - 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x02, 0x00, 0x70, - 0x00, 0x04, 0x00, 0x99, 0x00, 0x84, 0x00, 0x02, 0x00, 0x70, 0x00, 0x04, - 0x00, 0x79, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1}, - { - 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x74, 0x00, 0x01, 0x00, 0x70, - 0x00, 0x04, 0x00, 0x99, 0x00, 0x74, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, - 0x00, 0x79, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0}, - { - 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x01, 0x00, 0x70, - 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, - 0x00, 0x78, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df}, - { - 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x01, 0x00, 0x70, - 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, - 0x00, 0x78, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de}, - { - 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70, - 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, - 0x00, 0x78, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd}, - { - 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x01, 0x00, 0x70, - 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, - 0x00, 0x78, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd}, - { - 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x01, 0x00, 0x70, - 0x00, 0x04, 0x00, 0x98, 0x00, 0x73, 0x00, 0x01, 0x00, 0x70, 0x00, 0x04, - 0x00, 0x78, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc}, - { - 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x63, 0x00, 0x01, 0x00, 0x70, - 0x00, 0x03, 0x00, 0x98, 0x00, 0x63, 0x00, 0x01, 0x00, 0x70, 0x00, 0x03, - 0x00, 0x78, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db}, - { - 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x62, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, - 0x00, 0x77, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da}, - { - 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, - 0x00, 0x77, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9}, - { - 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x03, 0x00, 0x97, 0x00, 0x62, 0x00, 0x00, 0x00, 0x70, 0x00, 0x03, - 0x00, 0x77, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8}, - { - 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x52, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, - 0x00, 0x76, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7}, - { - 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x52, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x02, 0x00, 0x96, 0x00, 0x52, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, - 0x00, 0x86, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7}, - { - 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, - 0x00, 0x86, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6}, - { - 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, - 0x00, 0x86, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5}, - { - 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, - 0x00, 0x86, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4}, - { - 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, - 0x00, 0x86, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3}, - { - 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x02, 0x00, 0x96, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, - 0x00, 0x86, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2}, - { - 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x51, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x02, 0x00, 0x95, 0x00, 0x51, 0x00, 0x00, 0x00, 0x70, 0x00, 0x02, - 0x00, 0x85, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2}, - { - 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x85, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1}, - { - 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x95, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x85, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0}, - { - 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x84, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf}, - { - 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x84, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce}, - { - 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x94, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce}, - { - 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x94, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd}, - { - 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x94, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc}, - { - 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x94, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb}, - { - 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x94, 0x00, 0x40, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x94, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb}, - { - 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x01, 0x00, 0x94, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x01, - 0x00, 0x94, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca}, - { - 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x93, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca}, - { - 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x93, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9}, - { - 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x93, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9}, - { - 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x93, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9}, - { - 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x30, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x93, 0x00, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x93, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8}, - { - 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x93, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8}, - { - 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x92, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8}, - { - 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x92, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7}, - { - 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x92, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7}, - { - 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x92, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6}, - { - 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x92, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6}, - { - 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x92, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6}, - { - 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x92, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5}, - { - 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x92, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5}, - { - 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x92, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4}, - { - 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x92, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4}, - { - 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x92, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4}, - { - 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x92, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3}, - { - 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x92, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3}, - { - 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x92, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2}, - { - 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x92, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2}, - { - 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x92, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1}, - { - 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x92, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0}, - { - 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x91, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf}, - { - 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x91, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf}, - { - 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x91, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be}, - { - 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x91, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd}, - { - 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, - 0x00, 0x91, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc}, - { - 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0b, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443}, - { - 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441}, - { - 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x89, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0f, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f}, - { - 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0e, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d}, - { - 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0e, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a}, - { - 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x76, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0e, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438}, - { - 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x66, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0e, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436}, - { - 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x55, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0e, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434}, - { - 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0e, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431}, - { - 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0d, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f}, - { - 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0d, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d}, - { - 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x22, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0d, 0x00, 0x08, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b}, - { - 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0d, 0x00, 0x08, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429}, - { - 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} -}; - -static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v8[] = { - { - 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216}, - { - 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215}, - { - 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214}, - { - 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213}, - { - 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212}, - { - 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211}, - { - 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f}, - { - 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e}, - { - 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d}, - { - 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c}, - { - 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b}, - { - 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a}, - { - 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209}, - { - 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208}, - { - 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207}, - { - 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206}, - { - 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205}, - { - 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204}, - { - 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203}, - { - 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202}, - { - 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201}, - { - 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200}, - { - 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff}, - { - 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, - 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e, - 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd}, - { - 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, - 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e, - 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc}, - { - 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, - 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e, - 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb}, - { - 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa}, - { - 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9}, - { - 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8}, - { - 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7}, - { - 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6}, - { - 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5}, - { - 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4}, - { - 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3}, - { - 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, - 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2}, - { - 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1}, - { - 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0}, - { - 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0}, - { - 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef}, - { - 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee}, - { - 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed}, - { - 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec}, - { - 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb}, - { - 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea}, - { - 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9}, - { - 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8}, - { - 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7}, - { - 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6}, - { - 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5}, - { - 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5}, - { - 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4}, - { - 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3}, - { - 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2}, - { - 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1}, - { - 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0}, - { - 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df}, - { - 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de}, - { - 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd}, - { - 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd}, - { - 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc}, - { - 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db}, - { - 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da}, - { - 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9}, - { - 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8}, - { - 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7}, - { - 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, - 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7}, - { - 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, - 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6}, - { - 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, - 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5}, - { - 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, - 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4}, - { - 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, - 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3}, - { - 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, - 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2}, - { - 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, - 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2}, - { - 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, - 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1}, - { - 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0}, - { - 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf}, - { - 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce}, - { - 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce}, - { - 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd}, - { - 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc}, - { - 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb}, - { - 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb}, - { - 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca}, - { - 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca}, - { - 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9}, - { - 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9}, - { - 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9}, - { - 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8}, - { - 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8}, - { - 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8}, - { - 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7}, - { - 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7}, - { - 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6}, - { - 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6}, - { - 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6}, - { - 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5}, - { - 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5}, - { - 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4}, - { - 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4}, - { - 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4}, - { - 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3}, - { - 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x07, 0x07, 0x04, 0x10, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3}, - { - 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2}, - { - 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2}, - { - 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1}, - { - 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0}, - { - 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf}, - { - 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf}, - { - 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be}, - { - 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd}, - { - 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x04, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc}, - { - 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443}, - { - 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441}, - { - 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f}, - { - 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d}, - { - 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a}, - { - 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438}, - { - 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436}, - { - 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434}, - { - 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431}, - { - 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f}, - { - 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d}, - { - 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b}, - { - 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429}, - { - 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x08, 0x08, 0x04, 0x16, 0x01, - 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} -}; - -static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v11[] = { - { - 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07b4, 0x07b0, 0x07ac, 0x0214, 0x0215, 0x0216}, - { - 186, 4930, 0xff, 0x01, 0x01, 0x01, 0xed, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07b8, 0x07b4, 0x07b0, 0x0213, 0x0214, 0x0215}, - { - 188, 4940, 0xff, 0x01, 0x01, 0x01, 0xee, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07bc, 0x07b8, 0x07b4, 0x0212, 0x0213, 0x0214}, - { - 190, 4950, 0xff, 0x01, 0x01, 0x01, 0xef, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07c0, 0x07bc, 0x07b8, 0x0211, 0x0212, 0x0213}, - { - 192, 4960, 0xff, 0x01, 0x01, 0x01, 0xf0, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07c4, 0x07c0, 0x07bc, 0x020f, 0x0211, 0x0212}, - { - 194, 4970, 0xff, 0x01, 0x01, 0x01, 0xf1, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07c8, 0x07c4, 0x07c0, 0x020e, 0x020f, 0x0211}, - { - 196, 4980, 0xff, 0x01, 0x01, 0x01, 0xf2, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07cc, 0x07c8, 0x07c4, 0x020d, 0x020e, 0x020f}, - { - 198, 4990, 0xff, 0x01, 0x01, 0x01, 0xf3, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07d0, 0x07cc, 0x07c8, 0x020c, 0x020d, 0x020e}, - { - 200, 5000, 0xff, 0x01, 0x01, 0x01, 0xf4, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07d4, 0x07d0, 0x07cc, 0x020b, 0x020c, 0x020d}, - { - 202, 5010, 0xff, 0x01, 0x01, 0x01, 0xf5, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07d8, 0x07d4, 0x07d0, 0x020a, 0x020b, 0x020c}, - { - 204, 5020, 0xf7, 0x01, 0x01, 0x01, 0xf6, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07dc, 0x07d8, 0x07d4, 0x0209, 0x020a, 0x020b}, - { - 206, 5030, 0xf7, 0x01, 0x01, 0x01, 0xf7, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07e0, 0x07dc, 0x07d8, 0x0208, 0x0209, 0x020a}, - { - 208, 5040, 0xef, 0x01, 0x01, 0x01, 0xf8, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07e4, 0x07e0, 0x07dc, 0x0207, 0x0208, 0x0209}, - { - 210, 5050, 0xef, 0x01, 0x01, 0x01, 0xf9, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07e8, 0x07e4, 0x07e0, 0x0206, 0x0207, 0x0208}, - { - 212, 5060, 0xe6, 0x01, 0x01, 0x01, 0xfa, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfe, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07ec, 0x07e8, 0x07e4, 0x0205, 0x0206, 0x0207}, - { - 214, 5070, 0xe6, 0x01, 0x01, 0x01, 0xfb, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07f0, 0x07ec, 0x07e8, 0x0204, 0x0205, 0x0206}, - { - 216, 5080, 0xde, 0x01, 0x01, 0x01, 0xfc, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07f4, 0x07f0, 0x07ec, 0x0203, 0x0204, 0x0205}, - { - 218, 5090, 0xde, 0x01, 0x01, 0x01, 0xfd, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x01, 0x01, 0x01, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x09, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x09, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07f8, 0x07f4, 0x07f0, 0x0202, 0x0203, 0x0204}, - { - 220, 5100, 0xd6, 0x01, 0x01, 0x01, 0xfe, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfd, 0x00, 0x08, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfd, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x07fc, 0x07f8, 0x07f4, 0x0201, 0x0202, 0x0203}, - { - 222, 5110, 0xd6, 0x01, 0x01, 0x01, 0xff, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x0800, 0x07fc, 0x07f8, 0x0200, 0x0201, 0x0202}, - { - 224, 5120, 0xce, 0x01, 0x01, 0x02, 0x00, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x0804, 0x0800, 0x07fc, 0x01ff, 0x0200, 0x0201}, - { - 226, 5130, 0xce, 0x01, 0x01, 0x02, 0x01, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfc, 0x00, 0x08, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfc, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x0808, 0x0804, 0x0800, 0x01fe, 0x01ff, 0x0200}, - { - 228, 5140, 0xc6, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfb, 0x00, 0x08, 0x00, 0x77, - 0x00, 0x0f, 0x00, 0x6f, 0x00, 0xfb, 0x00, 0x08, 0x00, 0x77, 0x00, 0x0f, - 0x00, 0x6f, 0x00, 0x080c, 0x0808, 0x0804, 0x01fd, 0x01fe, 0x01ff}, - { - 32, 5160, 0xbe, 0x01, 0x01, 0x02, 0x04, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, - 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e, - 0x00, 0x6f, 0x00, 0x0814, 0x0810, 0x080c, 0x01fb, 0x01fc, 0x01fd}, - { - 34, 5170, 0xbe, 0x01, 0x01, 0x02, 0x05, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xfa, 0x00, 0x07, 0x00, 0x77, - 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xfa, 0x00, 0x07, 0x00, 0x77, 0x00, 0x0e, - 0x00, 0x6f, 0x00, 0x0818, 0x0814, 0x0810, 0x01fa, 0x01fb, 0x01fc}, - { - 36, 5180, 0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, - 0x00, 0x0e, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e, - 0x00, 0x6f, 0x00, 0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb}, - { - 38, 5190, 0xb6, 0x01, 0x01, 0x02, 0x07, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x0820, 0x081c, 0x0818, 0x01f8, 0x01f9, 0x01fa}, - { - 40, 5200, 0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9}, - { - 42, 5210, 0xaf, 0x01, 0x01, 0x02, 0x09, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00, 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x0828, 0x0824, 0x0820, 0x01f6, 0x01f7, 0x01f8}, - { - 44, 5220, 0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7}, - { - 46, 5230, 0xa7, 0x01, 0x01, 0x02, 0x0b, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xd8, 0x00, 0x05, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x0830, 0x082c, 0x0828, 0x01f4, 0x01f5, 0x01f6}, - { - 48, 5240, 0xa0, 0x01, 0x01, 0x02, 0x0c, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xee, 0xc8, 0x00, 0x05, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5}, - { - 50, 5250, 0xa0, 0x01, 0x01, 0x02, 0x0d, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00, 0xed, 0xc7, 0x00, 0x05, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x0838, 0x0834, 0x0830, 0x01f2, 0x01f3, 0x01f4}, - { - 52, 5260, 0x98, 0x01, 0x01, 0x02, 0x0e, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x02, 0x02, 0x02, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, - 0x00, 0x0d, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0d, - 0x00, 0x6f, 0x00, 0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3}, - { - 54, 5270, 0x98, 0x01, 0x01, 0x02, 0x0f, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8e, 0x0e, 0x00, 0xed, 0xc7, 0x00, 0x04, 0x00, 0x77, - 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xc7, 0x00, 0x04, 0x00, 0x77, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x0840, 0x083c, 0x0838, 0x01f0, 0x01f1, 0x01f2}, - { - 56, 5280, 0x91, 0x01, 0x01, 0x02, 0x10, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1}, - { - 58, 5290, 0x91, 0x01, 0x01, 0x02, 0x11, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x0848, 0x0844, 0x0840, 0x01ef, 0x01f0, 0x01f0}, - { - 60, 5300, 0x8a, 0x01, 0x01, 0x02, 0x12, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0}, - { - 62, 5310, 0x8a, 0x01, 0x01, 0x02, 0x13, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdc, 0xb7, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x0850, 0x084c, 0x0848, 0x01ed, 0x01ee, 0x01ef}, - { - 64, 5320, 0x83, 0x01, 0x01, 0x02, 0x14, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0e, 0x00, 0xdb, 0xb7, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0c, 0x00, 0x6f, 0x00, 0xb7, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0c, - 0x00, 0x6f, 0x00, 0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee}, - { - 66, 5330, 0x83, 0x01, 0x01, 0x02, 0x15, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xcb, 0xa6, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x0858, 0x0854, 0x0850, 0x01eb, 0x01ec, 0x01ed}, - { - 68, 5340, 0x7c, 0x01, 0x01, 0x02, 0x16, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8d, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x085c, 0x0858, 0x0854, 0x01ea, 0x01eb, 0x01ec}, - { - 70, 5350, 0x7c, 0x01, 0x01, 0x02, 0x17, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xca, 0xa6, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0b, 0x00, 0x6f, 0x00, 0xa6, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0b, - 0x00, 0x6f, 0x00, 0x0860, 0x085c, 0x0858, 0x01e9, 0x01ea, 0x01eb}, - { - 72, 5360, 0x75, 0x01, 0x01, 0x02, 0x18, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0864, 0x0860, 0x085c, 0x01e8, 0x01e9, 0x01ea}, - { - 74, 5370, 0x75, 0x01, 0x01, 0x02, 0x19, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0d, 0x00, 0xc9, 0x95, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0868, 0x0864, 0x0860, 0x01e7, 0x01e8, 0x01e9}, - { - 76, 5380, 0x6e, 0x01, 0x01, 0x02, 0x1a, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x95, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x95, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x086c, 0x0868, 0x0864, 0x01e6, 0x01e7, 0x01e8}, - { - 78, 5390, 0x6e, 0x01, 0x01, 0x02, 0x1b, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0870, 0x086c, 0x0868, 0x01e5, 0x01e6, 0x01e7}, - { - 80, 5400, 0x67, 0x01, 0x01, 0x02, 0x1c, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb8, 0x84, 0x00, 0x03, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x03, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0874, 0x0870, 0x086c, 0x01e5, 0x01e5, 0x01e6}, - { - 82, 5410, 0x67, 0x01, 0x01, 0x02, 0x1d, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xb7, 0x84, 0x00, 0x02, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0878, 0x0874, 0x0870, 0x01e4, 0x01e5, 0x01e5}, - { - 84, 5420, 0x61, 0x01, 0x01, 0x02, 0x1e, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0c, 0x00, 0xa7, 0x84, 0x00, 0x02, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x087c, 0x0878, 0x0874, 0x01e3, 0x01e4, 0x01e5}, - { - 86, 5430, 0x61, 0x01, 0x01, 0x02, 0x1f, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x03, 0x03, 0x03, 0x8c, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, - 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x0a, - 0x00, 0x6f, 0x00, 0x0880, 0x087c, 0x0878, 0x01e2, 0x01e3, 0x01e4}, - { - 88, 5440, 0x5a, 0x01, 0x01, 0x02, 0x20, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0xa6, 0x84, 0x00, 0x02, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x02, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x0884, 0x0880, 0x087c, 0x01e1, 0x01e2, 0x01e3}, - { - 90, 5450, 0x5a, 0x01, 0x01, 0x02, 0x21, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x0888, 0x0884, 0x0880, 0x01e0, 0x01e1, 0x01e2}, - { - 92, 5460, 0x53, 0x01, 0x01, 0x02, 0x22, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x95, 0x84, 0x00, 0x01, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x84, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x088c, 0x0888, 0x0884, 0x01df, 0x01e0, 0x01e1}, - { - 94, 5470, 0x53, 0x01, 0x01, 0x02, 0x23, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8b, 0x0b, 0x00, 0x94, 0x73, 0x00, 0x01, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x0890, 0x088c, 0x0888, 0x01de, 0x01df, 0x01e0}, - { - 96, 5480, 0x4d, 0x01, 0x01, 0x02, 0x24, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x84, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x0894, 0x0890, 0x088c, 0x01dd, 0x01de, 0x01df}, - { - 98, 5490, 0x4d, 0x01, 0x01, 0x02, 0x25, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x83, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x0898, 0x0894, 0x0890, 0x01dd, 0x01dd, 0x01de}, - { - 100, 5500, 0x47, 0x01, 0x01, 0x02, 0x26, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd}, - { - 102, 5510, 0x47, 0x01, 0x01, 0x02, 0x27, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x82, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08a0, 0x089c, 0x0898, 0x01db, 0x01dc, 0x01dd}, - { - 104, 5520, 0x40, 0x01, 0x01, 0x02, 0x28, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x0a, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc}, - { - 106, 5530, 0x40, 0x01, 0x01, 0x02, 0x29, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x72, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08a8, 0x08a4, 0x08a0, 0x01d9, 0x01da, 0x01db}, - { - 108, 5540, 0x3a, 0x01, 0x01, 0x02, 0x2a, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x8a, 0x09, 0x00, 0x71, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da}, - { - 110, 5550, 0x3a, 0x01, 0x01, 0x02, 0x2b, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08b0, 0x08ac, 0x08a8, 0x01d7, 0x01d8, 0x01d9}, - { - 112, 5560, 0x34, 0x01, 0x01, 0x02, 0x2c, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8}, - { - 114, 5570, 0x34, 0x01, 0x01, 0x02, 0x2d, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x09, 0x00, 0x61, 0x62, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x09, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x09, - 0x00, 0x6f, 0x00, 0x08b8, 0x08b4, 0x08b0, 0x01d6, 0x01d7, 0x01d7}, - { - 116, 5580, 0x2e, 0x01, 0x01, 0x02, 0x2e, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x60, 0x62, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x08, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, - 0x00, 0x6f, 0x00, 0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7}, - { - 118, 5590, 0x2e, 0x01, 0x01, 0x02, 0x2f, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x04, 0x04, 0x04, 0x89, 0x08, 0x00, 0x50, 0x61, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x08, 0x00, 0x6f, 0x00, 0x61, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, - 0x00, 0x6f, 0x00, 0x08c0, 0x08bc, 0x08b8, 0x01d4, 0x01d5, 0x01d6}, - { - 120, 5600, 0x28, 0x01, 0x01, 0x02, 0x30, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, - 0x00, 0x6f, 0x00, 0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5}, - { - 122, 5610, 0x28, 0x01, 0x01, 0x02, 0x31, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x51, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x08, 0x00, 0x6f, 0x00, 0x51, 0x00, 0x00, 0x00, 0x77, 0x00, 0x08, - 0x00, 0x6f, 0x00, 0x08c8, 0x08c4, 0x08c0, 0x01d2, 0x01d3, 0x01d4}, - { - 124, 5620, 0x21, 0x01, 0x01, 0x02, 0x32, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x89, 0x08, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, - 0x00, 0x6f, 0x00, 0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3}, - { - 126, 5630, 0x21, 0x01, 0x01, 0x02, 0x33, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, - 0x00, 0x6f, 0x00, 0x08d0, 0x08cc, 0x08c8, 0x01d1, 0x01d2, 0x01d2}, - { - 128, 5640, 0x1c, 0x01, 0x01, 0x02, 0x34, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x07, 0x00, 0x6f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, - 0x00, 0x6f, 0x00, 0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2}, - { - 130, 5650, 0x1c, 0x01, 0x01, 0x02, 0x35, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x07, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x07, - 0x00, 0x6f, 0x00, 0x08d8, 0x08d4, 0x08d0, 0x01cf, 0x01d0, 0x01d1}, - { - 132, 5660, 0x16, 0x01, 0x01, 0x02, 0x36, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6f, 0x00, 0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0}, - { - 134, 5670, 0x16, 0x01, 0x01, 0x02, 0x37, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x88, 0x07, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6f, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, 0x01ce, 0x01cf}, - { - 136, 5680, 0x10, 0x01, 0x01, 0x02, 0x38, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6f, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce}, - { - 138, 5690, 0x10, 0x01, 0x01, 0x02, 0x39, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6f, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6f, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, 0x01cd, 0x01ce}, - { - 140, 5700, 0x0a, 0x01, 0x01, 0x02, 0x3a, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6e, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd}, - { - 142, 5710, 0x0a, 0x01, 0x01, 0x02, 0x3b, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6e, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, 0x01cb, 0x01cc}, - { - 144, 5720, 0x0a, 0x01, 0x01, 0x02, 0x3c, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6e, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, 0x01ca, 0x01cb}, - { - 145, 5725, 0x03, 0x01, 0x02, 0x04, 0x79, 0x05, 0x05, 0x02, 0x15, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x06, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6e, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, 0x01ca, 0x01cb}, - { - 146, 5730, 0x0a, 0x01, 0x01, 0x02, 0x3d, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6e, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, 0x01c9, 0x01ca}, - { - 147, 5735, 0x03, 0x01, 0x02, 0x04, 0x7b, 0x05, 0x05, 0x02, 0x15, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6d, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, 0x01c9, 0x01ca}, - { - 148, 5740, 0x0a, 0x01, 0x01, 0x02, 0x3e, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6d, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, 0x01c9, 0x01c9}, - { - 149, 5745, 0xfe, 0x00, 0x02, 0x04, 0x7d, 0x05, 0x05, 0x02, 0x15, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x06, 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06, - 0x00, 0x6d, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9}, - { - 150, 5750, 0x0a, 0x01, 0x01, 0x02, 0x3f, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6d, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, 0x01c8, 0x01c9}, - { - 151, 5755, 0xfe, 0x00, 0x02, 0x04, 0x7f, 0x05, 0x05, 0x02, 0x15, 0x01, - 0x05, 0x05, 0x05, 0x87, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6c, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, 0x01c8, 0x01c8}, - { - 152, 5760, 0x0a, 0x01, 0x01, 0x02, 0x40, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6c, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, 0x01c7, 0x01c8}, - { - 153, 5765, 0xf8, 0x00, 0x02, 0x04, 0x81, 0x05, 0x05, 0x02, 0x15, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x05, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6c, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8}, - { - 154, 5770, 0x0a, 0x01, 0x01, 0x02, 0x41, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, 0x01c6, 0x01c7}, - { - 155, 5775, 0xf8, 0x00, 0x02, 0x04, 0x83, 0x05, 0x05, 0x02, 0x15, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, 0x01c6, 0x01c7}, - { - 156, 5780, 0x0a, 0x01, 0x01, 0x02, 0x42, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x05, 0x05, 0x05, 0x86, 0x04, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, 0x01c6, 0x01c6}, - { - 157, 5785, 0xf2, 0x00, 0x02, 0x04, 0x85, 0x05, 0x05, 0x02, 0x15, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6}, - { - 158, 5790, 0x0a, 0x01, 0x01, 0x02, 0x43, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, 0x01c5, 0x01c6}, - { - 159, 5795, 0xf2, 0x00, 0x02, 0x04, 0x87, 0x05, 0x05, 0x02, 0x15, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, 0x01c4, 0x01c5}, - { - 160, 5800, 0x0a, 0x01, 0x01, 0x02, 0x44, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6b, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, 0x01c4, 0x01c5}, - { - 161, 5805, 0xed, 0x00, 0x02, 0x04, 0x89, 0x05, 0x05, 0x02, 0x15, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6a, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4}, - { - 162, 5810, 0x0a, 0x01, 0x01, 0x02, 0x45, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6a, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, 0x01c3, 0x01c4}, - { - 163, 5815, 0xed, 0x00, 0x02, 0x04, 0x8b, 0x05, 0x05, 0x02, 0x15, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6a, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, 0x01c3, 0x01c4}, - { - 164, 5820, 0x0a, 0x01, 0x01, 0x02, 0x46, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x6a, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, 0x01c2, 0x01c3}, - { - 165, 5825, 0xed, 0x00, 0x02, 0x04, 0x8d, 0x05, 0x05, 0x02, 0x15, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x69, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3}, - { - 166, 5830, 0x0a, 0x01, 0x01, 0x02, 0x47, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, - 0x00, 0x69, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, 0x01c2, 0x01c2}, - { - 168, 5840, 0x0a, 0x01, 0x01, 0x02, 0x48, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x86, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x69, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, 0x01c1, 0x01c2}, - { - 170, 5850, 0xe0, 0x00, 0x01, 0x02, 0x49, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x69, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, 0x01c0, 0x01c1}, - { - 172, 5860, 0xde, 0x00, 0x01, 0x02, 0x4a, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x69, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, 0x01bf, 0x01c0}, - { - 174, 5870, 0xdb, 0x00, 0x01, 0x02, 0x4b, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x68, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, 0x01bf, 0x01bf}, - { - 176, 5880, 0xd8, 0x00, 0x01, 0x02, 0x4c, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x68, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, 0x01be, 0x01bf}, - { - 178, 5890, 0xd6, 0x00, 0x01, 0x02, 0x4d, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x68, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, 0x01bd, 0x01be}, - { - 180, 5900, 0xd3, 0x00, 0x01, 0x02, 0x4e, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x68, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, 0x01bc, 0x01bd}, - { - 182, 5910, 0xd6, 0x00, 0x01, 0x02, 0x4f, 0x05, 0x05, 0x02, 0x0c, 0x01, - 0x06, 0x06, 0x06, 0x85, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, - 0x00, 0x04, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x04, - 0x00, 0x68, 0x00, 0x0940, 0x093c, 0x0938, 0x01bb, 0x01bc, 0x01bc}, - { - 1, 2412, 0x00, 0x01, 0x03, 0x09, 0x6c, 0x06, 0x06, 0x04, 0x2b, 0x01, - 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0b, 0x00, 0x0a, 0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443}, - { - 2, 2417, 0x00, 0x01, 0x03, 0x09, 0x71, 0x06, 0x06, 0x04, 0x2b, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0b, 0x00, 0x0a, 0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441}, - { - 3, 2422, 0x00, 0x01, 0x03, 0x09, 0x76, 0x06, 0x06, 0x04, 0x2b, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x67, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0b, 0x00, 0x0a, 0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f}, - { - 4, 2427, 0x00, 0x01, 0x03, 0x09, 0x7b, 0x06, 0x06, 0x04, 0x2b, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x57, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x0a, 0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d}, - { - 5, 2432, 0x00, 0x01, 0x03, 0x09, 0x80, 0x06, 0x06, 0x04, 0x2b, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x56, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x0a, 0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a}, - { - 6, 2437, 0x00, 0x01, 0x03, 0x09, 0x85, 0x06, 0x06, 0x04, 0x2b, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x46, 0x00, 0x03, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x0a, 0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438}, - { - 7, 2442, 0x00, 0x01, 0x03, 0x09, 0x8a, 0x06, 0x06, 0x04, 0x2b, 0x01, - 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x45, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x0a, 0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436}, - { - 8, 2447, 0x00, 0x01, 0x03, 0x09, 0x8f, 0x06, 0x06, 0x04, 0x2b, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x09, 0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434}, - { - 9, 2452, 0x00, 0x01, 0x03, 0x09, 0x94, 0x06, 0x06, 0x04, 0x2b, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x23, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x09, 0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431}, - { - 10, 2457, 0x00, 0x01, 0x03, 0x09, 0x99, 0x06, 0x06, 0x04, 0x2b, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x12, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x0a, 0x00, 0x09, 0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f}, - { - 11, 2462, 0x00, 0x01, 0x03, 0x09, 0x9e, 0x06, 0x06, 0x04, 0x2b, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x09, 0x00, 0x09, 0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d}, - { - 12, 2467, 0x00, 0x01, 0x03, 0x09, 0xa3, 0x06, 0x06, 0x04, 0x2b, 0x01, - 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x09, 0x00, 0x09, 0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b}, - { - 13, 2472, 0x00, 0x01, 0x03, 0x09, 0xa8, 0x06, 0x06, 0x04, 0x2b, 0x01, - 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x09, 0x00, 0x09, 0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429}, - { - 14, 2484, 0xff, 0x01, 0x03, 0x09, 0xb4, 0x06, 0x06, 0x04, 0x2b, 0x01, - 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x70, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00, - 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} -}; - -static chan_info_nphy_radio2057_t chan_info_nphyrev7_2057_rev4[] = { - { - 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, - 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b4, 0x07b0, 0x07ac, 0x0214, - 0x0215, - 0x0216, - }, - { - 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, - 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07b8, 0x07b4, 0x07b0, 0x0213, - 0x0214, - 0x0215, - }, - { - 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, - 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07bc, 0x07b8, 0x07b4, 0x0212, - 0x0213, - 0x0214, - }, - { - 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, - 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c0, 0x07bc, 0x07b8, 0x0211, - 0x0212, - 0x0213, - }, - { - 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, - 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c4, 0x07c0, 0x07bc, 0x020f, - 0x0211, - 0x0212, - }, - { - 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, - 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07c8, 0x07c4, 0x07c0, 0x020e, - 0x020f, - 0x0211, - }, - { - 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, - 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07cc, 0x07c8, 0x07c4, 0x020d, - 0x020e, - 0x020f, - }, - { - 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, - 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d0, 0x07cc, 0x07c8, 0x020c, - 0x020d, - 0x020e, - }, - { - 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, - 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d4, 0x07d0, 0x07cc, 0x020b, - 0x020c, - 0x020d, - }, - { - 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, - 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07d8, 0x07d4, 0x07d0, 0x020a, - 0x020b, - 0x020c, - }, - { - 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, - 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07dc, 0x07d8, 0x07d4, 0x0209, - 0x020a, - 0x020b, - }, - { - 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, - 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e0, 0x07dc, 0x07d8, 0x0208, - 0x0209, - 0x020a, - }, - { - 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, - 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e4, 0x07e0, 0x07dc, 0x0207, - 0x0208, - 0x0209, - }, - { - 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, - 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x07e8, 0x07e4, 0x07e0, 0x0206, - 0x0207, - 0x0208, - }, - { - 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x00, - 0x00, 0x0f, 0x0f, 0xe3, 0x00, 0xef, 0x07ec, 0x07e8, 0x07e4, 0x0205, - 0x0206, - 0x0207, - }, - { - 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00, - 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f0, 0x07ec, 0x07e8, 0x0204, - 0x0205, - 0x0206, - }, - { - 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x00, - 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xef, 0x07f4, 0x07f0, 0x07ec, 0x0203, - 0x0204, - 0x0205, - }, - { - 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00, - 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07f8, 0x07f4, 0x07f0, 0x0202, - 0x0203, - 0x0204, - }, - { - 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00, - 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x07fc, 0x07f8, 0x07f4, 0x0201, - 0x0202, - 0x0203, - }, - { - 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00, - 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0800, 0x07fc, 0x07f8, 0x0200, - 0x0201, - 0x0202, - }, - { - 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00, - 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0804, 0x0800, 0x07fc, 0x01ff, - 0x0200, - 0x0201, - }, - { - 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x00, - 0x00, 0x0e, 0x0f, 0xe3, 0x00, 0xd6, 0x0808, 0x0804, 0x0800, 0x01fe, - 0x01ff, - 0x0200, - }, - { - 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x00, - 0x00, 0x0e, 0x0e, 0xe3, 0x00, 0xd6, 0x080c, 0x0808, 0x0804, 0x01fd, - 0x01fe, - 0x01ff, - }, - { - 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00, - 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0814, 0x0810, 0x080c, 0x01fb, - 0x01fc, - 0x01fd, - }, - { - 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x00, - 0x00, 0x0d, 0x0e, 0xe3, 0x00, 0xd6, 0x0818, 0x0814, 0x0810, 0x01fa, - 0x01fb, - 0x01fc, - }, - { - 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00, - 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x081c, 0x0818, 0x0814, 0x01f9, - 0x01fa, - 0x01fb, - }, - { - 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00, - 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0820, 0x081c, 0x0818, 0x01f8, - 0x01f9, - 0x01fa, - }, - { - 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00, - 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0824, 0x0820, 0x081c, 0x01f7, - 0x01f8, - 0x01f9, - }, - { - 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x00, - 0x00, 0x0d, 0x0e, 0xd3, 0x00, 0xd6, 0x0828, 0x0824, 0x0820, 0x01f6, - 0x01f7, - 0x01f8, - }, - { - 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00, - 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x082c, 0x0828, 0x0824, 0x01f5, - 0x01f6, - 0x01f7, - }, - { - 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00, - 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0830, 0x082c, 0x0828, 0x01f4, - 0x01f5, - 0x01f6, - }, - { - 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00, - 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0834, 0x0830, 0x082c, 0x01f3, - 0x01f4, - 0x01f5, - }, - { - 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x00, - 0x00, 0x0c, 0x0e, 0xd3, 0x00, 0xd6, 0x0838, 0x0834, 0x0830, 0x01f2, - 0x01f3, - 0x01f4, - }, - { - 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00, - 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x083c, 0x0838, 0x0834, 0x01f1, - 0x01f2, - 0x01f3, - }, - { - 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x00, - 0x00, 0x0c, 0x0d, 0xd3, 0x00, 0xd6, 0x0840, 0x083c, 0x0838, 0x01f0, - 0x01f1, - 0x01f2, - }, - { - 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00, - 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0844, 0x0840, 0x083c, 0x01f0, - 0x01f0, - 0x01f1, - }, - { - 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00, - 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x0848, 0x0844, 0x0840, 0x01ef, - 0x01f0, - 0x01f0, - }, - { - 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x00, - 0x00, 0x0c, 0x0c, 0xc3, 0x00, 0xd4, 0x084c, 0x0848, 0x0844, 0x01ee, - 0x01ef, - 0x01f0, - }, - { - 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00, - 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0850, 0x084c, 0x0848, 0x01ed, - 0x01ee, - 0x01ef, - }, - { - 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00, - 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0854, 0x0850, 0x084c, 0x01ec, - 0x01ed, - 0x01ee, - }, - { - 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x00, - 0x00, 0x0b, 0x0c, 0xc3, 0x00, 0xd4, 0x0858, 0x0854, 0x0850, 0x01eb, - 0x01ec, - 0x01ed, - }, - { - 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x00, - 0x00, 0x0a, 0x0c, 0xc3, 0x00, 0xa1, 0x085c, 0x0858, 0x0854, 0x01ea, - 0x01eb, - 0x01ec, - }, - { - 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00, - 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0860, 0x085c, 0x0858, 0x01e9, - 0x01ea, - 0x01eb, - }, - { - 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00, - 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0864, 0x0860, 0x085c, 0x01e8, - 0x01e9, - 0x01ea, - }, - { - 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00, - 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x0868, 0x0864, 0x0860, 0x01e7, - 0x01e8, - 0x01e9, - }, - { - 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x00, - 0x00, 0x0a, 0x0b, 0xb3, 0x00, 0xa1, 0x086c, 0x0868, 0x0864, 0x01e6, - 0x01e7, - 0x01e8, - }, - { - 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x00, - 0x00, 0x0a, 0x0a, 0xa3, 0x00, 0xa1, 0x0870, 0x086c, 0x0868, 0x01e5, - 0x01e6, - 0x01e7, - }, - { - 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00, - 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0874, 0x0870, 0x086c, 0x01e5, - 0x01e5, - 0x01e6, - }, - { - 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x00, - 0x00, 0x09, 0x0a, 0xa3, 0x00, 0x90, 0x0878, 0x0874, 0x0870, 0x01e4, - 0x01e5, - 0x01e5, - }, - { - 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x00, - 0x00, 0x09, 0x09, 0xa3, 0x00, 0x90, 0x087c, 0x0878, 0x0874, 0x01e3, - 0x01e4, - 0x01e5, - }, - { - 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00, - 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0880, 0x087c, 0x0878, 0x01e2, - 0x01e3, - 0x01e4, - }, - { - 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00, - 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0884, 0x0880, 0x087c, 0x01e1, - 0x01e2, - 0x01e3, - }, - { - 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x00, - 0x00, 0x09, 0x09, 0x93, 0x00, 0x90, 0x0888, 0x0884, 0x0880, 0x01e0, - 0x01e1, - 0x01e2, - }, - { - 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x00, - 0x00, 0x08, 0x08, 0x93, 0x00, 0x90, 0x088c, 0x0888, 0x0884, 0x01df, - 0x01e0, - 0x01e1, - }, - { - 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x00, - 0x00, 0x08, 0x08, 0x93, 0x00, 0x60, 0x0890, 0x088c, 0x0888, 0x01de, - 0x01df, - 0x01e0, - }, - { - 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00, - 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0894, 0x0890, 0x088c, 0x01dd, - 0x01de, - 0x01df, - }, - { - 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00, - 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x0898, 0x0894, 0x0890, 0x01dd, - 0x01dd, - 0x01de, - }, - { - 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00, - 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x089c, 0x0898, 0x0894, 0x01dc, - 0x01dd, - 0x01dd, - }, - { - 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x00, - 0x00, 0x08, 0x07, 0x93, 0x00, 0x60, 0x08a0, 0x089c, 0x0898, 0x01db, - 0x01dc, - 0x01dd, - }, - { - 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00, - 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a4, 0x08a0, 0x089c, 0x01da, - 0x01db, - 0x01dc, - }, - { - 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00, - 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08a8, 0x08a4, 0x08a0, 0x01d9, - 0x01da, - 0x01db, - }, - { - 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x00, - 0x00, 0x08, 0x06, 0x93, 0x00, 0x60, 0x08ac, 0x08a8, 0x08a4, 0x01d8, - 0x01d9, - 0x01da, - }, - { - 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00, - 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b0, 0x08ac, 0x08a8, 0x01d7, - 0x01d8, - 0x01d9, - }, - { - 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00, - 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b4, 0x08b0, 0x08ac, 0x01d7, - 0x01d7, - 0x01d8, - }, - { - 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x00, - 0x00, 0x08, 0x05, 0x83, 0x00, 0x60, 0x08b8, 0x08b4, 0x08b0, 0x01d6, - 0x01d7, - 0x01d7, - }, - { - 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x00, - 0x00, 0x07, 0x05, 0x83, 0x00, 0x60, 0x08bc, 0x08b8, 0x08b4, 0x01d5, - 0x01d6, - 0x01d7, - }, - { - 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x00, - 0x00, 0x07, 0x04, 0x83, 0x00, 0x60, 0x08c0, 0x08bc, 0x08b8, 0x01d4, - 0x01d5, - 0x01d6, - }, - { - 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x00, - 0x00, 0x07, 0x04, 0x73, 0x00, 0x30, 0x08c4, 0x08c0, 0x08bc, 0x01d3, - 0x01d4, - 0x01d5, - }, - { - 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00, - 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08c8, 0x08c4, 0x08c0, 0x01d2, - 0x01d3, - 0x01d4, - }, - { - 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00, - 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08cc, 0x08c8, 0x08c4, 0x01d2, - 0x01d2, - 0x01d3, - }, - { - 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00, - 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d0, 0x08cc, 0x08c8, 0x01d1, - 0x01d2, - 0x01d2, - }, - { - 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x00, - 0x00, 0x06, 0x04, 0x73, 0x00, 0x30, 0x08d4, 0x08d0, 0x08cc, 0x01d0, - 0x01d1, - 0x01d2, - }, - { - 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00, - 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08d8, 0x08d4, 0x08d0, 0x01cf, - 0x01d0, - 0x01d1, - }, - { - 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x00, - 0x00, 0x06, 0x03, 0x63, 0x00, 0x30, 0x08dc, 0x08d8, 0x08d4, 0x01ce, - 0x01cf, - 0x01d0, - }, - { - 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x00, - 0x00, 0x05, 0x03, 0x63, 0x00, 0x00, 0x08e0, 0x08dc, 0x08d8, 0x01ce, - 0x01ce, - 0x01cf, - }, - { - 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00, - 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e4, 0x08e0, 0x08dc, 0x01cd, - 0x01ce, - 0x01ce, - }, - { - 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00, - 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08e8, 0x08e4, 0x08e0, 0x01cc, - 0x01cd, - 0x01ce, - }, - { - 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00, - 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08ec, 0x08e8, 0x08e4, 0x01cb, - 0x01cc, - 0x01cd, - }, - { - 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00, - 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f0, 0x08ec, 0x08e8, 0x01ca, - 0x01cb, - 0x01cc, - }, - { - 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x00, - 0x00, 0x05, 0x02, 0x53, 0x00, 0x00, 0x08f4, 0x08f0, 0x08ec, 0x01c9, - 0x01ca, - 0x01cb, - }, - { - 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x00, - 0x00, 0x05, 0x01, 0x53, 0x00, 0x00, 0x08f6, 0x08f2, 0x08ee, 0x01c9, - 0x01ca, - 0x01cb, - }, - { - 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08f8, 0x08f4, 0x08f0, 0x01c9, - 0x01c9, - 0x01ca, - }, - { - 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fa, 0x08f6, 0x08f2, 0x01c8, - 0x01c9, - 0x01ca, - }, - { - 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fc, 0x08f8, 0x08f4, 0x01c8, - 0x01c9, - 0x01c9, - }, - { - 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x08fe, 0x08fa, 0x08f6, 0x01c8, - 0x01c8, - 0x01c9, - }, - { - 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, - 0x01c8, - 0x01c9, - }, - { - 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x01, 0x53, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, - 0x01c8, - 0x01c8, - }, - { - 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, - 0x01c7, - 0x01c8, - }, - { - 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, - 0x01c7, - 0x01c8, - }, - { - 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, - 0x01c6, - 0x01c7, - }, - { - 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x01, 0x43, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, - 0x01c6, - 0x01c7, - }, - { - 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x01, 0x43, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, - 0x01c6, - 0x01c6, - }, - { - 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, - 0x01c5, - 0x01c6, - }, - { - 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, - 0x01c5, - 0x01c6, - }, - { - 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, - 0x01c4, - 0x01c5, - }, - { - 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, - 0x01c4, - 0x01c5, - }, - { - 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, - 0x01c4, - 0x01c4, - }, - { - 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, - 0x01c3, - 0x01c4, - }, - { - 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, - 0x01c3, - 0x01c4, - }, - { - 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, - 0x01c2, - 0x01c3, - }, - { - 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, - 0x01c2, - 0x01c3, - }, - { - 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, - 0x01c2, - 0x01c2, - }, - { - 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, - 0x01c1, - 0x01c2, - }, - { - 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04, - 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, - 0x01c0, - 0x01c1, - }, - { - 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04, - 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, - 0x01bf, - 0x01c0, - }, - { - 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04, - 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, - 0x01bf, - 0x01bf, - }, - { - 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03, - 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, - 0x01be, - 0x01bf, - }, - { - 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03, - 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, - 0x01bd, - 0x01be, - }, - { - 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03, - 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x43, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, - 0x01bc, - 0x01bd, - }, - { - 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f, - 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71, - 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a, - 0x043f, - 0x0443, - }, - { - 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f, - 0x0a, 0x00, 0x0a, 0x00, 0x71, 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71, - 0xa3, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438, - 0x043d, - 0x0441, - }, - { - 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f, - 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71, - 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436, - 0x043a, - 0x043f, - }, - { - 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f, - 0x09, 0x00, 0x09, 0x00, 0x71, 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x71, - 0x93, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434, - 0x0438, - 0x043d, - }, - { - 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f, - 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51, - 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431, - 0x0436, - 0x043a, - }, - { - 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f, - 0x08, 0x00, 0x08, 0x00, 0x51, 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51, - 0x83, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f, - 0x0434, - 0x0438, - }, - { - 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f, - 0x07, 0x00, 0x07, 0x00, 0x51, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x51, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d, - 0x0431, - 0x0436, - }, - { - 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f, - 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b, - 0x042f, - 0x0434, - }, - { - 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f, - 0x07, 0x00, 0x07, 0x00, 0x31, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429, - 0x042d, - 0x0431, - }, - { - 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f, - 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31, - 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427, - 0x042b, - 0x042f, - }, - { - 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f, - 0x06, 0x00, 0x06, 0x00, 0x31, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x31, - 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424, - 0x0429, - 0x042d, - }, - { - 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f, - 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11, - 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422, - 0x0427, - 0x042b, - }, - { - 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f, - 0x05, 0x00, 0x05, 0x00, 0x11, 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x11, - 0x53, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420, - 0x0424, - 0x0429, - }, - { - 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f, - 0x04, 0x00, 0x04, 0x00, 0x11, 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x11, - 0x43, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b, - 0x041f, - 0x0424} -}; - -static chan_info_nphy_radio2057_rev5_t chan_info_nphyrev8_2057_rev5[] = { - { - 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d, - 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1, - 0x043a, 0x043f, 0x0443}, - { - 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d, - 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3, - 0x0438, 0x043d, 0x0441}, - { - 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d, - 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5, - 0x0436, 0x043a, 0x043f}, - { - 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c, - 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7, - 0x0434, 0x0438, 0x043d}, - { - 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c, - 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9, - 0x0431, 0x0436, 0x043a}, - { - 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c, - 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb, - 0x042f, 0x0434, 0x0438}, - { - 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b, - 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd, - 0x042d, 0x0431, 0x0436}, - { - 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b, - 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf, - 0x042b, 0x042f, 0x0434}, - { - 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b, - 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1, - 0x0429, 0x042d, 0x0431}, - { - 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b, - 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3, - 0x0427, 0x042b, 0x042f}, - { - 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b, - 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5, - 0x0424, 0x0429, 0x042d}, - { - 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b, - 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7, - 0x0422, 0x0427, 0x042b}, - { - 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a, - 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9, - 0x0420, 0x0424, 0x0429}, - { - 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a, - 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de, - 0x041b, 0x041f, 0x0424} -}; - -static chan_info_nphy_radio2057_rev5_t chan_info_nphyrev9_2057_rev5v1[] = { - { - 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d, - 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1, - 0x043a, 0x043f, 0x0443}, - { - 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0d, - 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03cb, 0x03c7, 0x03c3, - 0x0438, 0x043d, 0x0441}, - { - 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0d, - 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61, 0x03, 0xef, 0x03cd, 0x03c9, 0x03c5, - 0x0436, 0x043a, 0x043f}, - { - 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0c, - 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61, 0x03, 0xdf, 0x03cf, 0x03cb, 0x03c7, - 0x0434, 0x0438, 0x043d}, - { - 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0c, - 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61, 0x03, 0xcf, 0x03d1, 0x03cd, 0x03c9, - 0x0431, 0x0436, 0x043a}, - { - 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0c, - 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61, 0x03, 0xbf, 0x03d3, 0x03cf, 0x03cb, - 0x042f, 0x0434, 0x0438}, - { - 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0b, - 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61, 0x03, 0xaf, 0x03d5, 0x03d1, 0x03cd, - 0x042d, 0x0431, 0x0436}, - { - 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0b, - 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61, 0x03, 0x9f, 0x03d7, 0x03d3, 0x03cf, - 0x042b, 0x042f, 0x0434}, - { - 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0b, - 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61, 0x03, 0x8f, 0x03d9, 0x03d5, 0x03d1, - 0x0429, 0x042d, 0x0431}, - { - 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0b, - 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61, 0x03, 0x7f, 0x03db, 0x03d7, 0x03d3, - 0x0427, 0x042b, 0x042f}, - { - 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0b, - 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61, 0x03, 0x6f, 0x03dd, 0x03d9, 0x03d5, - 0x0424, 0x0429, 0x042d}, - { - 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0b, - 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61, 0x03, 0x5f, 0x03df, 0x03db, 0x03d7, - 0x0422, 0x0427, 0x042b}, - { - 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0a, - 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61, 0x03, 0x4f, 0x03e1, 0x03dd, 0x03d9, - 0x0420, 0x0424, 0x0429}, - { - 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0a, - 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61, 0x03, 0x3f, 0x03e6, 0x03e2, 0x03de, - 0x041b, 0x041f, 0x0424} -}; - -static chan_info_nphy_radio2057_t chan_info_nphyrev8_2057_rev7[] = { - { - 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b4, 0x07b0, 0x07ac, 0x0214, - 0x0215, - 0x0216}, - { - 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213, - 0x0214, - 0x0215}, - { - 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212, - 0x0213, - 0x0214}, - { - 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211, - 0x0212, - 0x0213}, - { - 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f, - 0x0211, - 0x0212}, - { - 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e, - 0x020f, - 0x0211}, - { - 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d, - 0x020e, - 0x020f}, - { - 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c, - 0x020d, - 0x020e}, - { - 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b, - 0x020c, - 0x020d}, - { - 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a, - 0x020b, - 0x020c}, - { - 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209, - 0x020a, - 0x020b}, - { - 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208, - 0x0209, - 0x020a}, - { - 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207, - 0x0208, - 0x0209}, - { - 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206, - 0x0207, - 0x0208}, - { - 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205, - 0x0206, - 0x0207}, - { - 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204, - 0x0205, - 0x0206}, - { - 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203, - 0x0204, - 0x0205}, - { - 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202, - 0x0203, - 0x0204}, - { - 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, - 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201, - 0x0202, - 0x0203}, - { - 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, - 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200, - 0x0201, - 0x0202}, - { - 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, - 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff, - 0x0200, - 0x0201}, - { - 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, - 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe, - 0x01ff, - 0x0200}, - { - 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, - 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd, - 0x01fe, - 0x01ff}, - { - 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, - 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb, - 0x01fc, - 0x01fd}, - { - 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, - 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa, - 0x01fb, - 0x01fc}, - { - 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, - 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9, - 0x01fa, - 0x01fb}, - { - 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, - 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8, - 0x01f9, - 0x01fa}, - { - 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7, - 0x01f8, - 0x01f9}, - { - 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6, - 0x01f7, - 0x01f8}, - { - 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5, - 0x01f6, - 0x01f7}, - { - 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4, - 0x01f5, - 0x01f6}, - { - 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3, - 0x01f4, - 0x01f5}, - { - 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2, - 0x01f3, - 0x01f4}, - { - 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1, - 0x01f2, - 0x01f3}, - { - 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0, - 0x01f1, - 0x01f2}, - { - 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0, - 0x01f0, - 0x01f1}, - { - 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef, - 0x01f0, - 0x01f0}, - { - 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee, - 0x01ef, - 0x01f0}, - { - 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed, - 0x01ee, - 0x01ef}, - { - 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec, - 0x01ed, - 0x01ee}, - { - 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb, - 0x01ec, - 0x01ed}, - { - 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea, - 0x01eb, - 0x01ec}, - { - 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9, - 0x01ea, - 0x01eb}, - { - 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8, - 0x01e9, - 0x01ea}, - { - 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7, - 0x01e8, - 0x01e9}, - { - 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6, - 0x01e7, - 0x01e8}, - { - 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5, - 0x01e6, - 0x01e7}, - { - 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5, - 0x01e5, - 0x01e6}, - { - 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4, - 0x01e5, - 0x01e5}, - { - 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3, - 0x01e4, - 0x01e5}, - { - 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2, - 0x01e3, - 0x01e4}, - { - 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1, - 0x01e2, - 0x01e3}, - { - 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0, - 0x01e1, - 0x01e2}, - { - 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df, - 0x01e0, - 0x01e1}, - { - 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de, - 0x01df, - 0x01e0}, - { - 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd, - 0x01de, - 0x01df}, - { - 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd, - 0x01dd, - 0x01de}, - { - 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc, - 0x01dd, - 0x01dd}, - { - 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db, - 0x01dc, - 0x01dd}, - { - 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da, - 0x01db, - 0x01dc}, - { - 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9, - 0x01da, - 0x01db}, - { - 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8, - 0x01d9, - 0x01da}, - { - 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7, - 0x01d8, - 0x01d9}, - { - 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7, - 0x01d7, - 0x01d8}, - { - 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6, - 0x01d7, - 0x01d7}, - { - 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5, - 0x01d6, - 0x01d7}, - { - 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4, - 0x01d5, - 0x01d6}, - { - 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3, - 0x01d4, - 0x01d5}, - { - 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2, - 0x01d3, - 0x01d4}, - { - 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2, - 0x01d2, - 0x01d3}, - { - 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1, - 0x01d2, - 0x01d2}, - { - 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0, - 0x01d1, - 0x01d2}, - { - 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf, - 0x01d0, - 0x01d1}, - { - 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce, - 0x01cf, - 0x01d0}, - { - 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce, - 0x01ce, - 0x01cf}, - { - 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd, - 0x01ce, - 0x01ce}, - { - 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc, - 0x01cd, - 0x01ce}, - { - 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb, - 0x01cc, - 0x01cd}, - { - 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca, - 0x01cb, - 0x01cc}, - { - 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9, - 0x01ca, - 0x01cb}, - { - 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9, - 0x01ca, - 0x01cb}, - { - 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9, - 0x01c9, - 0x01ca}, - { - 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8, - 0x01c9, - 0x01ca}, - { - 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8, - 0x01c9, - 0x01c9}, - { - 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8, - 0x01c8, - 0x01c9}, - { - 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, - 0x01c8, - 0x01c9}, - { - 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, - 0x01c8, - 0x01c8}, - { - 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, - 0x01c7, - 0x01c8}, - { - 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, - 0x01c7, - 0x01c8}, - { - 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, - 0x01c6, - 0x01c7}, - { - 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, - 0x01c6, - 0x01c7}, - { - 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, - 0x01c6, - 0x01c6}, - { - 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, - 0x01c5, - 0x01c6}, - { - 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, - 0x01c5, - 0x01c6}, - { - 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, - 0x01c4, - 0x01c5}, - { - 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, - 0x01c4, - 0x01c5}, - { - 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, - 0x01c4, - 0x01c4}, - { - 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, - 0x01c3, - 0x01c4}, - { - 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, - 0x01c3, - 0x01c4}, - { - 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, - 0x01c2, - 0x01c3}, - { - 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, - 0x01c2, - 0x01c3}, - { - 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, - 0x01c2, - 0x01c2}, - { - 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, - 0x01c1, - 0x01c2}, - { - 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04, - 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, - 0x01c0, - 0x01c1}, - { - 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04, - 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, - 0x01bf, - 0x01c0}, - { - 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04, - 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, - 0x01bf, - 0x01bf}, - { - 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03, - 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, - 0x01be, - 0x01bf}, - { - 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03, - 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, - 0x01bd, - 0x01be}, - { - 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03, - 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, - 0x01bc, - 0x01bd}, - { - 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f, - 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a, - 0x043f, - 0x0443}, - { - 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f, - 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438, - 0x043d, - 0x0441}, - { - 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f, - 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436, - 0x043a, - 0x043f}, - { - 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f, - 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434, - 0x0438, - 0x043d}, - { - 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f, - 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431, - 0x0436, - 0x043a}, - { - 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f, - 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f, - 0x0434, - 0x0438}, - { - 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f, - 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d, - 0x0431, - 0x0436}, - { - 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f, - 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b, - 0x042f, - 0x0434}, - { - 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f, - 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429, - 0x042d, - 0x0431}, - { - 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f, - 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427, - 0x042b, - 0x042f}, - { - 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f, - 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424, - 0x0429, - 0x042d}, - { - 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f, - 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422, - 0x0427, - 0x042b}, - { - 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f, - 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420, - 0x0424, - 0x0429}, - { - 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f, - 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b, - 0x041f, - 0x0424} -}; - -static chan_info_nphy_radio2057_t chan_info_nphyrev8_2057_rev8[] = { - { - 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07b8, 0x07b4, 0x07b0, 0x0213, - 0x0214, - 0x0215}, - { - 188, 4940, 0x6e, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xee, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07bc, 0x07b8, 0x07b4, 0x0212, - 0x0213, - 0x0214}, - { - 190, 4950, 0x72, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xef, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c0, 0x07bc, 0x07b8, 0x0211, - 0x0212, - 0x0213}, - { - 192, 4960, 0x75, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf0, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c4, 0x07c0, 0x07bc, 0x020f, - 0x0211, - 0x0212}, - { - 194, 4970, 0x78, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf1, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07c8, 0x07c4, 0x07c0, 0x020e, - 0x020f, - 0x0211}, - { - 196, 4980, 0x7c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf2, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07cc, 0x07c8, 0x07c4, 0x020d, - 0x020e, - 0x020f}, - { - 198, 4990, 0x7f, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf3, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x07d0, 0x07cc, 0x07c8, 0x020c, - 0x020d, - 0x020e}, - { - 200, 5000, 0x82, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf4, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d4, 0x07d0, 0x07cc, 0x020b, - 0x020c, - 0x020d}, - { - 202, 5010, 0x86, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf5, 0x01, 0x0f, - 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07d8, 0x07d4, 0x07d0, 0x020a, - 0x020b, - 0x020c}, - { - 204, 5020, 0x89, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf6, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07dc, 0x07d8, 0x07d4, 0x0209, - 0x020a, - 0x020b}, - { - 206, 5030, 0x8c, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf7, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e0, 0x07dc, 0x07d8, 0x0208, - 0x0209, - 0x020a}, - { - 208, 5040, 0x90, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf8, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e4, 0x07e0, 0x07dc, 0x0207, - 0x0208, - 0x0209}, - { - 210, 5050, 0x93, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xf9, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07e8, 0x07e4, 0x07e0, 0x0206, - 0x0207, - 0x0208}, - { - 212, 5060, 0x96, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfa, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07ec, 0x07e8, 0x07e4, 0x0205, - 0x0206, - 0x0207}, - { - 214, 5070, 0x9a, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfb, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f0, 0x07ec, 0x07e8, 0x0204, - 0x0205, - 0x0206}, - { - 216, 5080, 0x9d, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfc, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f4, 0x07f0, 0x07ec, 0x0203, - 0x0204, - 0x0205}, - { - 218, 5090, 0xa0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfd, 0x01, 0x0e, - 0x00, 0x0e, 0x00, 0xee, 0x00, 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x00, - 0x00, 0x0f, 0x0f, 0xb3, 0x00, 0xff, 0x07f8, 0x07f4, 0x07f0, 0x0202, - 0x0203, - 0x0204}, - { - 220, 5100, 0xa4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xfe, 0x01, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, - 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x07fc, 0x07f8, 0x07f4, 0x0201, - 0x0202, - 0x0203}, - { - 222, 5110, 0xa7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xff, 0x01, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, - 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0800, 0x07fc, 0x07f8, 0x0200, - 0x0201, - 0x0202}, - { - 224, 5120, 0xaa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x00, 0x02, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, - 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0804, 0x0800, 0x07fc, 0x01ff, - 0x0200, - 0x0201}, - { - 226, 5130, 0xae, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x01, 0x02, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, - 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0808, 0x0804, 0x0800, 0x01fe, - 0x01ff, - 0x0200}, - { - 228, 5140, 0xb1, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x02, 0x02, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, - 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x080c, 0x0808, 0x0804, 0x01fd, - 0x01fe, - 0x01ff}, - { - 32, 5160, 0xb8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x04, 0x02, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, - 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0814, 0x0810, 0x080c, 0x01fb, - 0x01fc, - 0x01fd}, - { - 34, 5170, 0xbb, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x05, 0x02, 0x0d, - 0x00, 0x0d, 0x00, 0xdd, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, - 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0818, 0x0814, 0x0810, 0x01fa, - 0x01fb, - 0x01fc}, - { - 36, 5180, 0xbe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x06, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, - 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x081c, 0x0818, 0x0814, 0x01f9, - 0x01fa, - 0x01fb}, - { - 38, 5190, 0xc2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x07, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x00, - 0x00, 0x0f, 0x0f, 0xa3, 0x00, 0xfc, 0x0820, 0x081c, 0x0818, 0x01f8, - 0x01f9, - 0x01fa}, - { - 40, 5200, 0xc5, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x08, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0824, 0x0820, 0x081c, 0x01f7, - 0x01f8, - 0x01f9}, - { - 42, 5210, 0xc8, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x09, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0828, 0x0824, 0x0820, 0x01f6, - 0x01f7, - 0x01f8}, - { - 44, 5220, 0xcc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0a, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x082c, 0x0828, 0x0824, 0x01f5, - 0x01f6, - 0x01f7}, - { - 46, 5230, 0xcf, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0b, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0830, 0x082c, 0x0828, 0x01f4, - 0x01f5, - 0x01f6}, - { - 48, 5240, 0xd2, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0c, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0834, 0x0830, 0x082c, 0x01f3, - 0x01f4, - 0x01f5}, - { - 50, 5250, 0xd6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0d, 0x02, 0x0c, - 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0838, 0x0834, 0x0830, 0x01f2, - 0x01f3, - 0x01f4}, - { - 52, 5260, 0xd9, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0e, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x083c, 0x0838, 0x0834, 0x01f1, - 0x01f2, - 0x01f3}, - { - 54, 5270, 0xdc, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x0f, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0840, 0x083c, 0x0838, 0x01f0, - 0x01f1, - 0x01f2}, - { - 56, 5280, 0xe0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x10, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0844, 0x0840, 0x083c, 0x01f0, - 0x01f0, - 0x01f1}, - { - 58, 5290, 0xe3, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x11, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0x0f, 0x93, 0x00, 0xf8, 0x0848, 0x0844, 0x0840, 0x01ef, - 0x01f0, - 0x01f0}, - { - 60, 5300, 0xe6, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x12, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x084c, 0x0848, 0x0844, 0x01ee, - 0x01ef, - 0x01f0}, - { - 62, 5310, 0xea, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x13, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0850, 0x084c, 0x0848, 0x01ed, - 0x01ee, - 0x01ef}, - { - 64, 5320, 0xed, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x14, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0854, 0x0850, 0x084c, 0x01ec, - 0x01ed, - 0x01ee}, - { - 66, 5330, 0xf0, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x15, 0x02, 0x0b, - 0x00, 0x0b, 0x00, 0xbb, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0858, 0x0854, 0x0850, 0x01eb, - 0x01ec, - 0x01ed}, - { - 68, 5340, 0xf4, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x16, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x085c, 0x0858, 0x0854, 0x01ea, - 0x01eb, - 0x01ec}, - { - 70, 5350, 0xf7, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x17, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0860, 0x085c, 0x0858, 0x01e9, - 0x01ea, - 0x01eb}, - { - 72, 5360, 0xfa, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x18, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0864, 0x0860, 0x085c, 0x01e8, - 0x01e9, - 0x01ea}, - { - 74, 5370, 0xfe, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x19, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0868, 0x0864, 0x0860, 0x01e7, - 0x01e8, - 0x01e9}, - { - 76, 5380, 0x01, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1a, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x086c, 0x0868, 0x0864, 0x01e6, - 0x01e7, - 0x01e8}, - { - 78, 5390, 0x04, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1b, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x00, - 0x00, 0x0f, 0x0c, 0x83, 0x00, 0xf5, 0x0870, 0x086c, 0x0868, 0x01e5, - 0x01e6, - 0x01e7}, - { - 80, 5400, 0x08, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1c, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0874, 0x0870, 0x086c, 0x01e5, - 0x01e5, - 0x01e6}, - { - 82, 5410, 0x0b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1d, 0x02, 0x0a, - 0x00, 0x0a, 0x00, 0xaa, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0878, 0x0874, 0x0870, 0x01e4, - 0x01e5, - 0x01e5}, - { - 84, 5420, 0x0e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1e, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x087c, 0x0878, 0x0874, 0x01e3, - 0x01e4, - 0x01e5}, - { - 86, 5430, 0x12, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x1f, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0880, 0x087c, 0x0878, 0x01e2, - 0x01e3, - 0x01e4}, - { - 88, 5440, 0x15, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x20, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0884, 0x0880, 0x087c, 0x01e1, - 0x01e2, - 0x01e3}, - { - 90, 5450, 0x18, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x21, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0888, 0x0884, 0x0880, 0x01e0, - 0x01e1, - 0x01e2}, - { - 92, 5460, 0x1c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x22, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x088c, 0x0888, 0x0884, 0x01df, - 0x01e0, - 0x01e1}, - { - 94, 5470, 0x1f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x23, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0890, 0x088c, 0x0888, 0x01de, - 0x01df, - 0x01e0}, - { - 96, 5480, 0x22, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x24, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0894, 0x0890, 0x088c, 0x01dd, - 0x01de, - 0x01df}, - { - 98, 5490, 0x26, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x25, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x00, - 0x00, 0x0d, 0x09, 0x53, 0x00, 0xb1, 0x0898, 0x0894, 0x0890, 0x01dd, - 0x01dd, - 0x01de}, - { - 100, 5500, 0x29, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x26, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x089c, 0x0898, 0x0894, 0x01dc, - 0x01dd, - 0x01dd}, - { - 102, 5510, 0x2c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x27, 0x02, 0x09, - 0x00, 0x09, 0x00, 0x99, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a0, 0x089c, 0x0898, 0x01db, - 0x01dc, - 0x01dd}, - { - 104, 5520, 0x30, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x28, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a4, 0x08a0, 0x089c, 0x01da, - 0x01db, - 0x01dc}, - { - 106, 5530, 0x33, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x29, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08a8, 0x08a4, 0x08a0, 0x01d9, - 0x01da, - 0x01db}, - { - 108, 5540, 0x36, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2a, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08ac, 0x08a8, 0x08a4, 0x01d8, - 0x01d9, - 0x01da}, - { - 110, 5550, 0x3a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2b, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b0, 0x08ac, 0x08a8, 0x01d7, - 0x01d8, - 0x01d9}, - { - 112, 5560, 0x3d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2c, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b4, 0x08b0, 0x08ac, 0x01d7, - 0x01d7, - 0x01d8}, - { - 114, 5570, 0x40, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2d, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08b8, 0x08b4, 0x08b0, 0x01d6, - 0x01d7, - 0x01d7}, - { - 116, 5580, 0x44, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2e, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08bc, 0x08b8, 0x08b4, 0x01d5, - 0x01d6, - 0x01d7}, - { - 118, 5590, 0x47, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x2f, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x00, - 0x00, 0x0a, 0x06, 0x43, 0x00, 0x80, 0x08c0, 0x08bc, 0x08b8, 0x01d4, - 0x01d5, - 0x01d6}, - { - 120, 5600, 0x4a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x30, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c4, 0x08c0, 0x08bc, 0x01d3, - 0x01d4, - 0x01d5}, - { - 122, 5610, 0x4e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x31, 0x02, 0x08, - 0x00, 0x08, 0x00, 0x88, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08c8, 0x08c4, 0x08c0, 0x01d2, - 0x01d3, - 0x01d4}, - { - 124, 5620, 0x51, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x32, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08cc, 0x08c8, 0x08c4, 0x01d2, - 0x01d2, - 0x01d3}, - { - 126, 5630, 0x54, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x33, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d0, 0x08cc, 0x08c8, 0x01d1, - 0x01d2, - 0x01d2}, - { - 128, 5640, 0x58, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x34, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x04, 0x23, 0x00, 0x60, 0x08d4, 0x08d0, 0x08cc, 0x01d0, - 0x01d1, - 0x01d2}, - { - 130, 5650, 0x5b, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x35, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08d8, 0x08d4, 0x08d0, 0x01cf, - 0x01d0, - 0x01d1}, - { - 132, 5660, 0x5e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x36, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08dc, 0x08d8, 0x08d4, 0x01ce, - 0x01cf, - 0x01d0}, - { - 134, 5670, 0x62, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x37, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x03, 0x23, 0x00, 0x60, 0x08e0, 0x08dc, 0x08d8, 0x01ce, - 0x01ce, - 0x01cf}, - { - 136, 5680, 0x65, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x38, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e4, 0x08e0, 0x08dc, 0x01cd, - 0x01ce, - 0x01ce}, - { - 138, 5690, 0x68, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x39, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x00, - 0x00, 0x09, 0x02, 0x23, 0x00, 0x60, 0x08e8, 0x08e4, 0x08e0, 0x01cc, - 0x01cd, - 0x01ce}, - { - 140, 5700, 0x6c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3a, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08ec, 0x08e8, 0x08e4, 0x01cb, - 0x01cc, - 0x01cd}, - { - 142, 5710, 0x6f, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3b, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f0, 0x08ec, 0x08e8, 0x01ca, - 0x01cb, - 0x01cc}, - { - 144, 5720, 0x72, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3c, 0x02, 0x07, - 0x00, 0x07, 0x00, 0x77, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f4, 0x08f0, 0x08ec, 0x01c9, - 0x01ca, - 0x01cb}, - { - 145, 5725, 0x74, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x79, 0x04, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f6, 0x08f2, 0x08ee, 0x01c9, - 0x01ca, - 0x01cb}, - { - 146, 5730, 0x76, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3d, 0x02, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08f8, 0x08f4, 0x08f0, 0x01c9, - 0x01c9, - 0x01ca}, - { - 147, 5735, 0x77, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7b, 0x04, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fa, 0x08f6, 0x08f2, 0x01c8, - 0x01c9, - 0x01ca}, - { - 148, 5740, 0x79, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3e, 0x02, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fc, 0x08f8, 0x08f4, 0x01c8, - 0x01c9, - 0x01c9}, - { - 149, 5745, 0x7b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7d, 0x04, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x30, 0x08fe, 0x08fa, 0x08f6, 0x01c8, - 0x01c8, - 0x01c9}, - { - 150, 5750, 0x7c, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x3f, 0x02, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0900, 0x08fc, 0x08f8, 0x01c7, - 0x01c8, - 0x01c9}, - { - 151, 5755, 0x7e, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x7f, 0x04, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0902, 0x08fe, 0x08fa, 0x01c7, - 0x01c8, - 0x01c8}, - { - 152, 5760, 0x80, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x40, 0x02, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0904, 0x0900, 0x08fc, 0x01c6, - 0x01c7, - 0x01c8}, - { - 153, 5765, 0x81, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x81, 0x04, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0906, 0x0902, 0x08fe, 0x01c6, - 0x01c7, - 0x01c8}, - { - 154, 5770, 0x83, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x41, 0x02, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0908, 0x0904, 0x0900, 0x01c6, - 0x01c6, - 0x01c7}, - { - 155, 5775, 0x85, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x83, 0x04, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090a, 0x0906, 0x0902, 0x01c5, - 0x01c6, - 0x01c7}, - { - 156, 5780, 0x86, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x42, 0x02, 0x06, - 0x00, 0x06, 0x00, 0x66, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090c, 0x0908, 0x0904, 0x01c5, - 0x01c6, - 0x01c6}, - { - 157, 5785, 0x88, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x85, 0x04, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x090e, 0x090a, 0x0906, 0x01c4, - 0x01c5, - 0x01c6}, - { - 158, 5790, 0x8a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x43, 0x02, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0910, 0x090c, 0x0908, 0x01c4, - 0x01c5, - 0x01c6}, - { - 159, 5795, 0x8b, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x87, 0x04, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x02, 0x13, 0x00, 0x00, 0x0912, 0x090e, 0x090a, 0x01c4, - 0x01c4, - 0x01c5}, - { - 160, 5800, 0x8d, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x44, 0x02, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x01, 0x03, 0x00, 0x00, 0x0914, 0x0910, 0x090c, 0x01c3, - 0x01c4, - 0x01c5}, - { - 161, 5805, 0x8f, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x89, 0x04, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0916, 0x0912, 0x090e, 0x01c3, - 0x01c4, - 0x01c4}, - { - 162, 5810, 0x90, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x45, 0x02, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0918, 0x0914, 0x0910, 0x01c2, - 0x01c3, - 0x01c4}, - { - 163, 5815, 0x92, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8b, 0x04, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091a, 0x0916, 0x0912, 0x01c2, - 0x01c3, - 0x01c4}, - { - 164, 5820, 0x94, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x46, 0x02, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091c, 0x0918, 0x0914, 0x01c2, - 0x01c2, - 0x01c3}, - { - 165, 5825, 0x95, 0x17, 0x20, 0x14, 0x08, 0x08, 0x30, 0x8d, 0x04, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x091e, 0x091a, 0x0916, 0x01c1, - 0x01c2, - 0x01c3}, - { - 166, 5830, 0x97, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x47, 0x02, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0920, 0x091c, 0x0918, 0x01c1, - 0x01c2, - 0x01c2}, - { - 168, 5840, 0x9a, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x48, 0x02, 0x05, - 0x00, 0x05, 0x00, 0x55, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0924, 0x0920, 0x091c, 0x01c0, - 0x01c1, - 0x01c2}, - { - 170, 5850, 0x9e, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x49, 0x02, 0x04, - 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0928, 0x0924, 0x0920, 0x01bf, - 0x01c0, - 0x01c1}, - { - 172, 5860, 0xa1, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4a, 0x02, 0x04, - 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x092c, 0x0928, 0x0924, 0x01bf, - 0x01bf, - 0x01c0}, - { - 174, 5870, 0xa4, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4b, 0x02, 0x04, - 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0930, 0x092c, 0x0928, 0x01be, - 0x01bf, - 0x01bf}, - { - 176, 5880, 0xa8, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4c, 0x02, 0x03, - 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0934, 0x0930, 0x092c, 0x01bd, - 0x01be, - 0x01bf}, - { - 178, 5890, 0xab, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4d, 0x02, 0x03, - 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x0938, 0x0934, 0x0930, 0x01bc, - 0x01bd, - 0x01be}, - { - 180, 5900, 0xae, 0x17, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0x4e, 0x02, 0x03, - 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x093c, 0x0938, 0x0934, 0x01bc, - 0x01bc, - 0x01bd}, - { - 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0f, - 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03c9, 0x03c5, 0x03c1, 0x043a, - 0x043f, - 0x0443}, - { - 2, 2417, 0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 0x09, 0x0f, - 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cb, 0x03c7, 0x03c3, 0x0438, - 0x043d, - 0x0441}, - { - 3, 2422, 0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 0x09, 0x0f, - 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cd, 0x03c9, 0x03c5, 0x0436, - 0x043a, - 0x043f}, - { - 4, 2427, 0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 0x09, 0x0f, - 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03cf, 0x03cb, 0x03c7, 0x0434, - 0x0438, - 0x043d}, - { - 5, 2432, 0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 0x09, 0x0f, - 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d1, 0x03cd, 0x03c9, 0x0431, - 0x0436, - 0x043a}, - { - 6, 2437, 0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 0x09, 0x0f, - 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d3, 0x03cf, 0x03cb, 0x042f, - 0x0434, - 0x0438}, - { - 7, 2442, 0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 0x09, 0x0f, - 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d5, 0x03d1, 0x03cd, 0x042d, - 0x0431, - 0x0436}, - { - 8, 2447, 0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 0x09, 0x0f, - 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d7, 0x03d3, 0x03cf, 0x042b, - 0x042f, - 0x0434}, - { - 9, 2452, 0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 0x09, 0x0f, - 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03d9, 0x03d5, 0x03d1, 0x0429, - 0x042d, - 0x0431}, - { - 10, 2457, 0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 0x09, 0x0f, - 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03db, 0x03d7, 0x03d3, 0x0427, - 0x042b, - 0x042f}, - { - 11, 2462, 0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 0x09, 0x0f, - 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03dd, 0x03d9, 0x03d5, 0x0424, - 0x0429, - 0x042d}, - { - 12, 2467, 0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 0x09, 0x0f, - 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03df, 0x03db, 0x03d7, 0x0422, - 0x0427, - 0x042b}, - { - 13, 2472, 0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8, 0x09, 0x0f, - 0x05, 0x00, 0x05, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03e1, 0x03dd, 0x03d9, 0x0420, - 0x0424, - 0x0429}, - { - 14, 2484, 0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4, 0x09, 0x0f, - 0x04, 0x00, 0x04, 0x00, 0x61, 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x61, - 0x73, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x03e6, 0x03e2, 0x03de, 0x041b, - 0x041f, - 0x0424} -}; - -radio_regs_t regs_2055[] = { - {0x02, 0x80, 0x80, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0x27, 0x27, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0x27, 0x27, 0, 0}, - {0x07, 0x7f, 0x7f, 1, 1}, - {0x08, 0x7, 0x7, 1, 1}, - {0x09, 0x7f, 0x7f, 1, 1}, - {0x0A, 0x7, 0x7, 1, 1}, - {0x0B, 0x15, 0x15, 0, 0}, - {0x0C, 0x15, 0x15, 0, 0}, - {0x0D, 0x4f, 0x4f, 1, 1}, - {0x0E, 0x5, 0x5, 1, 1}, - {0x0F, 0x4f, 0x4f, 1, 1}, - {0x10, 0x5, 0x5, 1, 1}, - {0x11, 0xd0, 0xd0, 0, 0}, - {0x12, 0x2, 0x2, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0x40, 0x40, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0xc0, 0xc0, 0, 0}, - {0x1E, 0xff, 0xff, 0, 0}, - {0x1F, 0xc0, 0xc0, 0, 0}, - {0x20, 0xff, 0xff, 0, 0}, - {0x21, 0xc0, 0xc0, 0, 0}, - {0x22, 0, 0, 0, 0}, - {0x23, 0x2c, 0x2c, 0, 0}, - {0x24, 0, 0, 0, 0}, - {0x25, 0, 0, 0, 0}, - {0x26, 0, 0, 0, 0}, - {0x27, 0, 0, 0, 0}, - {0x28, 0, 0, 0, 0}, - {0x29, 0, 0, 0, 0}, - {0x2A, 0, 0, 0, 0}, - {0x2B, 0, 0, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0xa4, 0xa4, 0, 0}, - {0x2E, 0x38, 0x38, 0, 0}, - {0x2F, 0, 0, 0, 0}, - {0x30, 0x4, 0x4, 1, 1}, - {0x31, 0, 0, 0, 0}, - {0x32, 0xa, 0xa, 0, 0}, - {0x33, 0x87, 0x87, 0, 0}, - {0x34, 0x9, 0x9, 0, 0}, - {0x35, 0x70, 0x70, 0, 0}, - {0x36, 0x11, 0x11, 0, 0}, - {0x37, 0x18, 0x18, 1, 1}, - {0x38, 0x6, 0x6, 0, 0}, - {0x39, 0x4, 0x4, 1, 1}, - {0x3A, 0x6, 0x6, 0, 0}, - {0x3B, 0x9e, 0x9e, 0, 0}, - {0x3C, 0x9, 0x9, 0, 0}, - {0x3D, 0xc8, 0xc8, 1, 1}, - {0x3E, 0x88, 0x88, 0, 0}, - {0x3F, 0, 0, 0, 0}, - {0x40, 0, 0, 0, 0}, - {0x41, 0, 0, 0, 0}, - {0x42, 0x1, 0x1, 0, 0}, - {0x43, 0x2, 0x2, 0, 0}, - {0x44, 0x96, 0x96, 0, 0}, - {0x45, 0x3e, 0x3e, 0, 0}, - {0x46, 0x3e, 0x3e, 0, 0}, - {0x47, 0x13, 0x13, 0, 0}, - {0x48, 0x2, 0x2, 0, 0}, - {0x49, 0x15, 0x15, 0, 0}, - {0x4A, 0x7, 0x7, 0, 0}, - {0x4B, 0, 0, 0, 0}, - {0x4C, 0, 0, 0, 0}, - {0x4D, 0, 0, 0, 0}, - {0x4E, 0, 0, 0, 0}, - {0x4F, 0, 0, 0, 0}, - {0x50, 0x8, 0x8, 0, 0}, - {0x51, 0x8, 0x8, 0, 0}, - {0x52, 0x6, 0x6, 0, 0}, - {0x53, 0x84, 0x84, 1, 1}, - {0x54, 0xc3, 0xc3, 0, 0}, - {0x55, 0x8f, 0x8f, 0, 0}, - {0x56, 0xff, 0xff, 0, 0}, - {0x57, 0xff, 0xff, 0, 0}, - {0x58, 0x88, 0x88, 0, 0}, - {0x59, 0x88, 0x88, 0, 0}, - {0x5A, 0, 0, 0, 0}, - {0x5B, 0xcc, 0xcc, 0, 0}, - {0x5C, 0x6, 0x6, 0, 0}, - {0x5D, 0x80, 0x80, 0, 0}, - {0x5E, 0x80, 0x80, 0, 0}, - {0x5F, 0xf8, 0xf8, 0, 0}, - {0x60, 0x88, 0x88, 0, 0}, - {0x61, 0x88, 0x88, 0, 0}, - {0x62, 0x88, 0x8, 1, 1}, - {0x63, 0x88, 0x88, 0, 0}, - {0x64, 0, 0, 0, 0}, - {0x65, 0x1, 0x1, 1, 1}, - {0x66, 0x8a, 0x8a, 0, 0}, - {0x67, 0x8, 0x8, 0, 0}, - {0x68, 0x83, 0x83, 0, 0}, - {0x69, 0x6, 0x6, 0, 0}, - {0x6A, 0xa0, 0xa0, 0, 0}, - {0x6B, 0xa, 0xa, 0, 0}, - {0x6C, 0x87, 0x87, 1, 1}, - {0x6D, 0x2a, 0x2a, 0, 0}, - {0x6E, 0x2a, 0x2a, 0, 0}, - {0x6F, 0x2a, 0x2a, 0, 0}, - {0x70, 0x2a, 0x2a, 0, 0}, - {0x71, 0x18, 0x18, 0, 0}, - {0x72, 0x6a, 0x6a, 1, 1}, - {0x73, 0xab, 0xab, 1, 1}, - {0x74, 0x13, 0x13, 1, 1}, - {0x75, 0xc1, 0xc1, 1, 1}, - {0x76, 0xaa, 0xaa, 1, 1}, - {0x77, 0x87, 0x87, 1, 1}, - {0x78, 0, 0, 0, 0}, - {0x79, 0x6, 0x6, 0, 0}, - {0x7A, 0x7, 0x7, 0, 0}, - {0x7B, 0x7, 0x7, 0, 0}, - {0x7C, 0x15, 0x15, 0, 0}, - {0x7D, 0x55, 0x55, 0, 0}, - {0x7E, 0x97, 0x97, 1, 1}, - {0x7F, 0x8, 0x8, 0, 0}, - {0x80, 0x14, 0x14, 1, 1}, - {0x81, 0x33, 0x33, 0, 0}, - {0x82, 0x88, 0x88, 0, 0}, - {0x83, 0x6, 0x6, 0, 0}, - {0x84, 0x3, 0x3, 1, 1}, - {0x85, 0xa, 0xa, 0, 0}, - {0x86, 0x3, 0x3, 1, 1}, - {0x87, 0x2a, 0x2a, 0, 0}, - {0x88, 0xa4, 0xa4, 0, 0}, - {0x89, 0x18, 0x18, 0, 0}, - {0x8A, 0x28, 0x28, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0x4a, 0x4a, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0xf8, 0xf8, 0, 0}, - {0x8F, 0x88, 0x88, 0, 0}, - {0x90, 0x88, 0x88, 0, 0}, - {0x91, 0x88, 0x8, 1, 1}, - {0x92, 0x88, 0x88, 0, 0}, - {0x93, 0, 0, 0, 0}, - {0x94, 0x1, 0x1, 1, 1}, - {0x95, 0x8a, 0x8a, 0, 0}, - {0x96, 0x8, 0x8, 0, 0}, - {0x97, 0x83, 0x83, 0, 0}, - {0x98, 0x6, 0x6, 0, 0}, - {0x99, 0xa0, 0xa0, 0, 0}, - {0x9A, 0xa, 0xa, 0, 0}, - {0x9B, 0x87, 0x87, 1, 1}, - {0x9C, 0x2a, 0x2a, 0, 0}, - {0x9D, 0x2a, 0x2a, 0, 0}, - {0x9E, 0x2a, 0x2a, 0, 0}, - {0x9F, 0x2a, 0x2a, 0, 0}, - {0xA0, 0x18, 0x18, 0, 0}, - {0xA1, 0x6a, 0x6a, 1, 1}, - {0xA2, 0xab, 0xab, 1, 1}, - {0xA3, 0x13, 0x13, 1, 1}, - {0xA4, 0xc1, 0xc1, 1, 1}, - {0xA5, 0xaa, 0xaa, 1, 1}, - {0xA6, 0x87, 0x87, 1, 1}, - {0xA7, 0, 0, 0, 0}, - {0xA8, 0x6, 0x6, 0, 0}, - {0xA9, 0x7, 0x7, 0, 0}, - {0xAA, 0x7, 0x7, 0, 0}, - {0xAB, 0x15, 0x15, 0, 0}, - {0xAC, 0x55, 0x55, 0, 0}, - {0xAD, 0x97, 0x97, 1, 1}, - {0xAE, 0x8, 0x8, 0, 0}, - {0xAF, 0x14, 0x14, 1, 1}, - {0xB0, 0x33, 0x33, 0, 0}, - {0xB1, 0x88, 0x88, 0, 0}, - {0xB2, 0x6, 0x6, 0, 0}, - {0xB3, 0x3, 0x3, 1, 1}, - {0xB4, 0xa, 0xa, 0, 0}, - {0xB5, 0x3, 0x3, 1, 1}, - {0xB6, 0x2a, 0x2a, 0, 0}, - {0xB7, 0xa4, 0xa4, 0, 0}, - {0xB8, 0x18, 0x18, 0, 0}, - {0xB9, 0x28, 0x28, 0, 0}, - {0xBA, 0, 0, 0, 0}, - {0xBB, 0x4a, 0x4a, 0, 0}, - {0xBC, 0, 0, 0, 0}, - {0xBD, 0x71, 0x71, 0, 0}, - {0xBE, 0x72, 0x72, 0, 0}, - {0xBF, 0x73, 0x73, 0, 0}, - {0xC0, 0x74, 0x74, 0, 0}, - {0xC1, 0x75, 0x75, 0, 0}, - {0xC2, 0x76, 0x76, 0, 0}, - {0xC3, 0x77, 0x77, 0, 0}, - {0xC4, 0x78, 0x78, 0, 0}, - {0xC5, 0x79, 0x79, 0, 0}, - {0xC6, 0x7a, 0x7a, 0, 0}, - {0xC7, 0, 0, 0, 0}, - {0xC8, 0, 0, 0, 0}, - {0xC9, 0, 0, 0, 0}, - {0xCA, 0, 0, 0, 0}, - {0xCB, 0, 0, 0, 0}, - {0xCC, 0, 0, 0, 0}, - {0xCD, 0, 0, 0, 0}, - {0xCE, 0x6, 0x6, 0, 0}, - {0xCF, 0, 0, 0, 0}, - {0xD0, 0, 0, 0, 0}, - {0xD1, 0x18, 0x18, 0, 0}, - {0xD2, 0x88, 0x88, 0, 0}, - {0xD3, 0, 0, 0, 0}, - {0xD4, 0, 0, 0, 0}, - {0xD5, 0, 0, 0, 0}, - {0xD6, 0, 0, 0, 0}, - {0xD7, 0, 0, 0, 0}, - {0xD8, 0, 0, 0, 0}, - {0xD9, 0, 0, 0, 0}, - {0xDA, 0x6, 0x6, 0, 0}, - {0xDB, 0, 0, 0, 0}, - {0xDC, 0, 0, 0, 0}, - {0xDD, 0x18, 0x18, 0, 0}, - {0xDE, 0x88, 0x88, 0, 0}, - {0xDF, 0, 0, 0, 0}, - {0xE0, 0, 0, 0, 0}, - {0xE1, 0, 0, 0, 0}, - {0xE2, 0, 0, 0, 0}, - {0xFFFF, 0, 0, 0, 0}, -}; - -radio_regs_t regs_SYN_2056[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0x1, 0x1, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0, 0, 0, 0}, - {0x21, 0, 0, 0, 0}, - {0x22, 0x60, 0x60, 0, 0}, - {0x23, 0x6, 0x6, 0, 0}, - {0x24, 0xc, 0xc, 0, 0}, - {0x25, 0, 0, 0, 0}, - {0x26, 0, 0, 0, 0}, - {0x27, 0, 0, 0, 0}, - {0x28, 0x1, 0x1, 0, 0}, - {0x29, 0, 0, 0, 0}, - {0x2A, 0, 0, 0, 0}, - {0x2B, 0, 0, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0, 0, 0, 0}, - {0x2E, 0xd, 0xd, 0, 0}, - {0x2F, 0x1f, 0x1f, 0, 0}, - {0x30, 0x15, 0x15, 0, 0}, - {0x31, 0xf, 0xf, 0, 0}, - {0x32, 0, 0, 0, 0}, - {0x33, 0, 0, 0, 0}, - {0x34, 0, 0, 0, 0}, - {0x35, 0, 0, 0, 0}, - {0x36, 0, 0, 0, 0}, - {0x37, 0, 0, 0, 0}, - {0x38, 0, 0, 0, 0}, - {0x39, 0, 0, 0, 0}, - {0x3A, 0, 0, 0, 0}, - {0x3B, 0, 0, 0, 0}, - {0x3C, 0x13, 0x13, 0, 0}, - {0x3D, 0xf, 0xf, 0, 0}, - {0x3E, 0x18, 0x18, 0, 0}, - {0x3F, 0, 0, 0, 0}, - {0x40, 0, 0, 0, 0}, - {0x41, 0x20, 0x20, 0, 0}, - {0x42, 0x20, 0x20, 0, 0}, - {0x43, 0, 0, 0, 0}, - {0x44, 0x77, 0x77, 0, 0}, - {0x45, 0x7, 0x7, 0, 0}, - {0x46, 0x1, 0x1, 0, 0}, - {0x47, 0x4, 0x4, 0, 0}, - {0x48, 0xf, 0xf, 0, 0}, - {0x49, 0x30, 0x30, 0, 0}, - {0x4A, 0x32, 0x32, 0, 0}, - {0x4B, 0xd, 0xd, 0, 0}, - {0x4C, 0xd, 0xd, 0, 0}, - {0x4D, 0x4, 0x4, 0, 0}, - {0x4E, 0x6, 0x6, 0, 0}, - {0x4F, 0x1, 0x1, 0, 0}, - {0x50, 0x1c, 0x1c, 0, 0}, - {0x51, 0x2, 0x2, 0, 0}, - {0x52, 0x2, 0x2, 0, 0}, - {0x53, 0xf7, 0xf7, 1, 1}, - {0x54, 0xb4, 0xb4, 0, 0}, - {0x55, 0xd2, 0xd2, 0, 0}, - {0x56, 0, 0, 0, 0}, - {0x57, 0, 0, 0, 0}, - {0x58, 0x4, 0x4, 0, 0}, - {0x59, 0x96, 0x96, 0, 0}, - {0x5A, 0x3e, 0x3e, 0, 0}, - {0x5B, 0x3e, 0x3e, 0, 0}, - {0x5C, 0x13, 0x13, 0, 0}, - {0x5D, 0x2, 0x2, 0, 0}, - {0x5E, 0, 0, 0, 0}, - {0x5F, 0x7, 0x7, 0, 0}, - {0x60, 0x7, 0x7, 1, 1}, - {0x61, 0x8, 0x8, 0, 0}, - {0x62, 0x3, 0x3, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0, 0, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0, 0, 0, 0}, - {0x68, 0x40, 0x40, 0, 0}, - {0x69, 0, 0, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0, 0, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0x1, 0x1, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0x60, 0x60, 0, 0}, - {0x71, 0x66, 0x66, 0, 0}, - {0x72, 0xc, 0xc, 0, 0}, - {0x73, 0x66, 0x66, 0, 0}, - {0x74, 0x8f, 0x8f, 1, 1}, - {0x75, 0, 0, 0, 0}, - {0x76, 0xcc, 0xcc, 0, 0}, - {0x77, 0x1, 0x1, 0, 0}, - {0x78, 0x66, 0x66, 0, 0}, - {0x79, 0x66, 0x66, 0, 0}, - {0x7A, 0, 0, 0, 0}, - {0x7B, 0, 0, 0, 0}, - {0x7C, 0, 0, 0, 0}, - {0x7D, 0, 0, 0, 0}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0xff, 0xff, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0x93, 0, 0, 0, 0}, - {0x94, 0, 0, 0, 0}, - {0x95, 0, 0, 0, 0}, - {0x96, 0, 0, 0, 0}, - {0x97, 0, 0, 0, 0}, - {0x98, 0, 0, 0, 0}, - {0x99, 0, 0, 0, 0}, - {0x9A, 0, 0, 0, 0}, - {0x9B, 0, 0, 0, 0}, - {0x9C, 0, 0, 0, 0}, - {0x9D, 0, 0, 0, 0}, - {0x9E, 0, 0, 0, 0}, - {0x9F, 0x6, 0x6, 0, 0}, - {0xA0, 0x66, 0x66, 0, 0}, - {0xA1, 0x66, 0x66, 0, 0}, - {0xA2, 0x66, 0x66, 0, 0}, - {0xA3, 0x66, 0x66, 0, 0}, - {0xA4, 0x66, 0x66, 0, 0}, - {0xA5, 0x66, 0x66, 0, 0}, - {0xA6, 0x66, 0x66, 0, 0}, - {0xA7, 0x66, 0x66, 0, 0}, - {0xA8, 0x66, 0x66, 0, 0}, - {0xA9, 0x66, 0x66, 0, 0}, - {0xAA, 0x66, 0x66, 0, 0}, - {0xAB, 0x66, 0x66, 0, 0}, - {0xAC, 0x66, 0x66, 0, 0}, - {0xAD, 0x66, 0x66, 0, 0}, - {0xAE, 0x66, 0x66, 0, 0}, - {0xAF, 0x66, 0x66, 0, 0}, - {0xB0, 0x66, 0x66, 0, 0}, - {0xB1, 0x66, 0x66, 0, 0}, - {0xB2, 0x66, 0x66, 0, 0}, - {0xB3, 0xa, 0xa, 0, 0}, - {0xB4, 0, 0, 0, 0}, - {0xB5, 0, 0, 0, 0}, - {0xB6, 0, 0, 0, 0}, - {0xFFFF, 0, 0, 0, 0} -}; - -radio_regs_t regs_TX_2056[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0, 0, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0, 0, 0, 0}, - {0x21, 0x88, 0x88, 0, 0}, - {0x22, 0x88, 0x88, 0, 0}, - {0x23, 0x88, 0x88, 0, 0}, - {0x24, 0x88, 0x88, 0, 0}, - {0x25, 0xc, 0xc, 0, 0}, - {0x26, 0, 0, 0, 0}, - {0x27, 0x3, 0x3, 0, 0}, - {0x28, 0, 0, 0, 0}, - {0x29, 0x3, 0x3, 0, 0}, - {0x2A, 0x37, 0x37, 0, 0}, - {0x2B, 0x3, 0x3, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0, 0, 0, 0}, - {0x2E, 0x1, 0x1, 0, 0}, - {0x2F, 0x1, 0x1, 0, 0}, - {0x30, 0, 0, 0, 0}, - {0x31, 0, 0, 0, 0}, - {0x32, 0, 0, 0, 0}, - {0x33, 0x11, 0x11, 0, 0}, - {0x34, 0x11, 0x11, 0, 0}, - {0x35, 0, 0, 0, 0}, - {0x36, 0, 0, 0, 0}, - {0x37, 0x3, 0x3, 0, 0}, - {0x38, 0xf, 0xf, 0, 0}, - {0x39, 0, 0, 0, 0}, - {0x3A, 0x2d, 0x2d, 0, 0}, - {0x3B, 0, 0, 0, 0}, - {0x3C, 0x6e, 0x6e, 0, 0}, - {0x3D, 0xf0, 0xf0, 1, 1}, - {0x3E, 0, 0, 0, 0}, - {0x3F, 0, 0, 0, 0}, - {0x40, 0, 0, 0, 0}, - {0x41, 0x3, 0x3, 0, 0}, - {0x42, 0x3, 0x3, 0, 0}, - {0x43, 0, 0, 0, 0}, - {0x44, 0x1e, 0x1e, 0, 0}, - {0x45, 0, 0, 0, 0}, - {0x46, 0x6e, 0x6e, 0, 0}, - {0x47, 0xf0, 0xf0, 1, 1}, - {0x48, 0, 0, 0, 0}, - {0x49, 0x2, 0x2, 0, 0}, - {0x4A, 0xff, 0xff, 1, 1}, - {0x4B, 0xc, 0xc, 0, 0}, - {0x4C, 0, 0, 0, 0}, - {0x4D, 0x38, 0x38, 0, 0}, - {0x4E, 0x70, 0x70, 1, 1}, - {0x4F, 0x2, 0x2, 0, 0}, - {0x50, 0x88, 0x88, 0, 0}, - {0x51, 0xc, 0xc, 0, 0}, - {0x52, 0, 0, 0, 0}, - {0x53, 0x8, 0x8, 0, 0}, - {0x54, 0x70, 0x70, 1, 1}, - {0x55, 0x2, 0x2, 0, 0}, - {0x56, 0xff, 0xff, 1, 1}, - {0x57, 0, 0, 0, 0}, - {0x58, 0x83, 0x83, 0, 0}, - {0x59, 0x77, 0x77, 1, 1}, - {0x5A, 0, 0, 0, 0}, - {0x5B, 0x2, 0x2, 0, 0}, - {0x5C, 0x88, 0x88, 0, 0}, - {0x5D, 0, 0, 0, 0}, - {0x5E, 0x8, 0x8, 0, 0}, - {0x5F, 0x77, 0x77, 1, 1}, - {0x60, 0x1, 0x1, 0, 0}, - {0x61, 0, 0, 0, 0}, - {0x62, 0x7, 0x7, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0x7, 0x7, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0x74, 0x74, 1, 1}, - {0x68, 0, 0, 0, 0}, - {0x69, 0xa, 0xa, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0, 0, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0, 0, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0, 0, 0, 0}, - {0x71, 0x2, 0x2, 0, 0}, - {0x72, 0, 0, 0, 0}, - {0x73, 0, 0, 0, 0}, - {0x74, 0xe, 0xe, 0, 0}, - {0x75, 0xe, 0xe, 0, 0}, - {0x76, 0xe, 0xe, 0, 0}, - {0x77, 0x13, 0x13, 0, 0}, - {0x78, 0x13, 0x13, 0, 0}, - {0x79, 0x1b, 0x1b, 0, 0}, - {0x7A, 0x1b, 0x1b, 0, 0}, - {0x7B, 0x55, 0x55, 0, 0}, - {0x7C, 0x5b, 0x5b, 0, 0}, - {0x7D, 0, 0, 0, 0}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0, 0, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0xFFFF, 0, 0, 0, 0} -}; - -radio_regs_t regs_RX_2056[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0, 0, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0x3, 0x3, 0, 0}, - {0x21, 0, 0, 0, 0}, - {0x22, 0, 0, 0, 0}, - {0x23, 0x90, 0x90, 0, 0}, - {0x24, 0x55, 0x55, 0, 0}, - {0x25, 0x15, 0x15, 0, 0}, - {0x26, 0x5, 0x5, 0, 0}, - {0x27, 0x15, 0x15, 0, 0}, - {0x28, 0x5, 0x5, 0, 0}, - {0x29, 0x20, 0x20, 0, 0}, - {0x2A, 0x11, 0x11, 0, 0}, - {0x2B, 0x90, 0x90, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0x88, 0x88, 0, 0}, - {0x2E, 0x32, 0x32, 0, 0}, - {0x2F, 0x77, 0x77, 0, 0}, - {0x30, 0x17, 0x17, 1, 1}, - {0x31, 0xff, 0xff, 1, 1}, - {0x32, 0x20, 0x20, 0, 0}, - {0x33, 0, 0, 0, 0}, - {0x34, 0x88, 0x88, 0, 0}, - {0x35, 0x32, 0x32, 0, 0}, - {0x36, 0x77, 0x77, 0, 0}, - {0x37, 0x17, 0x17, 1, 1}, - {0x38, 0xf0, 0xf0, 1, 1}, - {0x39, 0x20, 0x20, 0, 0}, - {0x3A, 0x8, 0x8, 0, 0}, - {0x3B, 0x99, 0x99, 0, 0}, - {0x3C, 0, 0, 0, 0}, - {0x3D, 0x44, 0x44, 1, 1}, - {0x3E, 0, 0, 0, 0}, - {0x3F, 0x44, 0x44, 0, 0}, - {0x40, 0xf, 0xf, 1, 1}, - {0x41, 0x6, 0x6, 0, 0}, - {0x42, 0x4, 0x4, 0, 0}, - {0x43, 0x50, 0x50, 1, 1}, - {0x44, 0x8, 0x8, 0, 0}, - {0x45, 0x99, 0x99, 0, 0}, - {0x46, 0, 0, 0, 0}, - {0x47, 0x11, 0x11, 0, 0}, - {0x48, 0, 0, 0, 0}, - {0x49, 0x44, 0x44, 0, 0}, - {0x4A, 0x7, 0x7, 0, 0}, - {0x4B, 0x6, 0x6, 0, 0}, - {0x4C, 0x4, 0x4, 0, 0}, - {0x4D, 0, 0, 0, 0}, - {0x4E, 0, 0, 0, 0}, - {0x4F, 0x66, 0x66, 0, 0}, - {0x50, 0x66, 0x66, 0, 0}, - {0x51, 0x57, 0x57, 0, 0}, - {0x52, 0x57, 0x57, 0, 0}, - {0x53, 0x44, 0x44, 0, 0}, - {0x54, 0, 0, 0, 0}, - {0x55, 0, 0, 0, 0}, - {0x56, 0x8, 0x8, 0, 0}, - {0x57, 0x8, 0x8, 0, 0}, - {0x58, 0x7, 0x7, 0, 0}, - {0x59, 0x22, 0x22, 0, 0}, - {0x5A, 0x22, 0x22, 0, 0}, - {0x5B, 0x2, 0x2, 0, 0}, - {0x5C, 0x23, 0x23, 0, 0}, - {0x5D, 0x7, 0x7, 0, 0}, - {0x5E, 0x55, 0x55, 0, 0}, - {0x5F, 0x23, 0x23, 0, 0}, - {0x60, 0x41, 0x41, 0, 0}, - {0x61, 0x1, 0x1, 0, 0}, - {0x62, 0xa, 0xa, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0, 0, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0, 0, 0, 0}, - {0x68, 0, 0, 0, 0}, - {0x69, 0, 0, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0xc, 0xc, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0, 0, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0, 0, 0, 0}, - {0x71, 0, 0, 0, 0}, - {0x72, 0x22, 0x22, 0, 0}, - {0x73, 0x22, 0x22, 0, 0}, - {0x74, 0x2, 0x2, 0, 0}, - {0x75, 0xa, 0xa, 0, 0}, - {0x76, 0x1, 0x1, 0, 0}, - {0x77, 0x22, 0x22, 0, 0}, - {0x78, 0x30, 0x30, 0, 0}, - {0x79, 0, 0, 0, 0}, - {0x7A, 0, 0, 0, 0}, - {0x7B, 0, 0, 0, 0}, - {0x7C, 0, 0, 0, 0}, - {0x7D, 0, 0, 0, 0}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0, 0, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0x93, 0, 0, 0, 0}, - {0x94, 0, 0, 0, 0}, - {0xFFFF, 0, 0, 0, 0} -}; - -radio_regs_t regs_SYN_2056_A1[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0x1, 0x1, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0, 0, 0, 0}, - {0x21, 0, 0, 0, 0}, - {0x22, 0x60, 0x60, 0, 0}, - {0x23, 0x6, 0x6, 0, 0}, - {0x24, 0xc, 0xc, 0, 0}, - {0x25, 0, 0, 0, 0}, - {0x26, 0, 0, 0, 0}, - {0x27, 0, 0, 0, 0}, - {0x28, 0x1, 0x1, 0, 0}, - {0x29, 0, 0, 0, 0}, - {0x2A, 0, 0, 0, 0}, - {0x2B, 0, 0, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0, 0, 0, 0}, - {0x2E, 0xd, 0xd, 0, 0}, - {0x2F, 0x1f, 0x1f, 0, 0}, - {0x30, 0x15, 0x15, 0, 0}, - {0x31, 0xf, 0xf, 0, 0}, - {0x32, 0, 0, 0, 0}, - {0x33, 0, 0, 0, 0}, - {0x34, 0, 0, 0, 0}, - {0x35, 0, 0, 0, 0}, - {0x36, 0, 0, 0, 0}, - {0x37, 0, 0, 0, 0}, - {0x38, 0, 0, 0, 0}, - {0x39, 0, 0, 0, 0}, - {0x3A, 0, 0, 0, 0}, - {0x3B, 0, 0, 0, 0}, - {0x3C, 0x13, 0x13, 0, 0}, - {0x3D, 0xf, 0xf, 0, 0}, - {0x3E, 0x18, 0x18, 0, 0}, - {0x3F, 0, 0, 0, 0}, - {0x40, 0, 0, 0, 0}, - {0x41, 0x20, 0x20, 0, 0}, - {0x42, 0x20, 0x20, 0, 0}, - {0x43, 0, 0, 0, 0}, - {0x44, 0x77, 0x77, 0, 0}, - {0x45, 0x7, 0x7, 0, 0}, - {0x46, 0x1, 0x1, 0, 0}, - {0x47, 0x4, 0x4, 0, 0}, - {0x48, 0xf, 0xf, 0, 0}, - {0x49, 0x30, 0x30, 0, 0}, - {0x4A, 0x32, 0x32, 0, 0}, - {0x4B, 0xd, 0xd, 0, 0}, - {0x4C, 0xd, 0xd, 0, 0}, - {0x4D, 0x4, 0x4, 0, 0}, - {0x4E, 0x6, 0x6, 0, 0}, - {0x4F, 0x1, 0x1, 0, 0}, - {0x50, 0x1c, 0x1c, 0, 0}, - {0x51, 0x2, 0x2, 0, 0}, - {0x52, 0x2, 0x2, 0, 0}, - {0x53, 0xf7, 0xf7, 1, 1}, - {0x54, 0xb4, 0xb4, 0, 0}, - {0x55, 0xd2, 0xd2, 0, 0}, - {0x56, 0, 0, 0, 0}, - {0x57, 0, 0, 0, 0}, - {0x58, 0x4, 0x4, 0, 0}, - {0x59, 0x96, 0x96, 0, 0}, - {0x5A, 0x3e, 0x3e, 0, 0}, - {0x5B, 0x3e, 0x3e, 0, 0}, - {0x5C, 0x13, 0x13, 0, 0}, - {0x5D, 0x2, 0x2, 0, 0}, - {0x5E, 0, 0, 0, 0}, - {0x5F, 0x7, 0x7, 0, 0}, - {0x60, 0x7, 0x7, 1, 1}, - {0x61, 0x8, 0x8, 0, 0}, - {0x62, 0x3, 0x3, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0, 0, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0, 0, 0, 0}, - {0x68, 0x40, 0x40, 0, 0}, - {0x69, 0, 0, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0, 0, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0x1, 0x1, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0x60, 0x60, 0, 0}, - {0x71, 0x66, 0x66, 0, 0}, - {0x72, 0xc, 0xc, 0, 0}, - {0x73, 0x66, 0x66, 0, 0}, - {0x74, 0x8f, 0x8f, 1, 1}, - {0x75, 0, 0, 0, 0}, - {0x76, 0xcc, 0xcc, 0, 0}, - {0x77, 0x1, 0x1, 0, 0}, - {0x78, 0x66, 0x66, 0, 0}, - {0x79, 0x66, 0x66, 0, 0}, - {0x7A, 0, 0, 0, 0}, - {0x7B, 0, 0, 0, 0}, - {0x7C, 0, 0, 0, 0}, - {0x7D, 0, 0, 0, 0}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0xff, 0xff, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0x93, 0, 0, 0, 0}, - {0x94, 0, 0, 0, 0}, - {0x95, 0, 0, 0, 0}, - {0x96, 0, 0, 0, 0}, - {0x97, 0, 0, 0, 0}, - {0x98, 0, 0, 0, 0}, - {0x99, 0, 0, 0, 0}, - {0x9A, 0, 0, 0, 0}, - {0x9B, 0, 0, 0, 0}, - {0x9C, 0, 0, 0, 0}, - {0x9D, 0, 0, 0, 0}, - {0x9E, 0, 0, 0, 0}, - {0x9F, 0x6, 0x6, 0, 0}, - {0xA0, 0x66, 0x66, 0, 0}, - {0xA1, 0x66, 0x66, 0, 0}, - {0xA2, 0x66, 0x66, 0, 0}, - {0xA3, 0x66, 0x66, 0, 0}, - {0xA4, 0x66, 0x66, 0, 0}, - {0xA5, 0x66, 0x66, 0, 0}, - {0xA6, 0x66, 0x66, 0, 0}, - {0xA7, 0x66, 0x66, 0, 0}, - {0xA8, 0x66, 0x66, 0, 0}, - {0xA9, 0x66, 0x66, 0, 0}, - {0xAA, 0x66, 0x66, 0, 0}, - {0xAB, 0x66, 0x66, 0, 0}, - {0xAC, 0x66, 0x66, 0, 0}, - {0xAD, 0x66, 0x66, 0, 0}, - {0xAE, 0x66, 0x66, 0, 0}, - {0xAF, 0x66, 0x66, 0, 0}, - {0xB0, 0x66, 0x66, 0, 0}, - {0xB1, 0x66, 0x66, 0, 0}, - {0xB2, 0x66, 0x66, 0, 0}, - {0xB3, 0xa, 0xa, 0, 0}, - {0xB4, 0, 0, 0, 0}, - {0xB5, 0, 0, 0, 0}, - {0xB6, 0, 0, 0, 0}, - {0xFFFF, 0, 0, 0, 0} -}; - -radio_regs_t regs_TX_2056_A1[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0, 0, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0, 0, 0, 0}, - {0x21, 0x88, 0x88, 0, 0}, - {0x22, 0x88, 0x88, 0, 0}, - {0x23, 0x88, 0x88, 0, 0}, - {0x24, 0x88, 0x88, 0, 0}, - {0x25, 0xc, 0xc, 0, 0}, - {0x26, 0, 0, 0, 0}, - {0x27, 0x3, 0x3, 0, 0}, - {0x28, 0, 0, 0, 0}, - {0x29, 0x3, 0x3, 0, 0}, - {0x2A, 0x37, 0x37, 0, 0}, - {0x2B, 0x3, 0x3, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0, 0, 0, 0}, - {0x2E, 0x1, 0x1, 0, 0}, - {0x2F, 0x1, 0x1, 0, 0}, - {0x30, 0, 0, 0, 0}, - {0x31, 0, 0, 0, 0}, - {0x32, 0, 0, 0, 0}, - {0x33, 0x11, 0x11, 0, 0}, - {0x34, 0x11, 0x11, 0, 0}, - {0x35, 0, 0, 0, 0}, - {0x36, 0, 0, 0, 0}, - {0x37, 0x3, 0x3, 0, 0}, - {0x38, 0xf, 0xf, 0, 0}, - {0x39, 0, 0, 0, 0}, - {0x3A, 0x2d, 0x2d, 0, 0}, - {0x3B, 0, 0, 0, 0}, - {0x3C, 0x6e, 0x6e, 0, 0}, - {0x3D, 0xf0, 0xf0, 1, 1}, - {0x3E, 0, 0, 0, 0}, - {0x3F, 0, 0, 0, 0}, - {0x40, 0, 0, 0, 0}, - {0x41, 0x3, 0x3, 0, 0}, - {0x42, 0x3, 0x3, 0, 0}, - {0x43, 0, 0, 0, 0}, - {0x44, 0x1e, 0x1e, 0, 0}, - {0x45, 0, 0, 0, 0}, - {0x46, 0x6e, 0x6e, 0, 0}, - {0x47, 0xf0, 0xf0, 1, 1}, - {0x48, 0, 0, 0, 0}, - {0x49, 0x2, 0x2, 0, 0}, - {0x4A, 0xff, 0xff, 1, 1}, - {0x4B, 0xc, 0xc, 0, 0}, - {0x4C, 0, 0, 0, 0}, - {0x4D, 0x38, 0x38, 0, 0}, - {0x4E, 0x70, 0x70, 1, 1}, - {0x4F, 0x2, 0x2, 0, 0}, - {0x50, 0x88, 0x88, 0, 0}, - {0x51, 0xc, 0xc, 0, 0}, - {0x52, 0, 0, 0, 0}, - {0x53, 0x8, 0x8, 0, 0}, - {0x54, 0x70, 0x70, 1, 1}, - {0x55, 0x2, 0x2, 0, 0}, - {0x56, 0xff, 0xff, 1, 1}, - {0x57, 0, 0, 0, 0}, - {0x58, 0x83, 0x83, 0, 0}, - {0x59, 0x77, 0x77, 1, 1}, - {0x5A, 0, 0, 0, 0}, - {0x5B, 0x2, 0x2, 0, 0}, - {0x5C, 0x88, 0x88, 0, 0}, - {0x5D, 0, 0, 0, 0}, - {0x5E, 0x8, 0x8, 0, 0}, - {0x5F, 0x77, 0x77, 1, 1}, - {0x60, 0x1, 0x1, 0, 0}, - {0x61, 0, 0, 0, 0}, - {0x62, 0x7, 0x7, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0x7, 0x7, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0x72, 0x72, 1, 1}, - {0x68, 0, 0, 0, 0}, - {0x69, 0xa, 0xa, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0, 0, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0, 0, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0, 0, 0, 0}, - {0x71, 0x2, 0x2, 0, 0}, - {0x72, 0, 0, 0, 0}, - {0x73, 0, 0, 0, 0}, - {0x74, 0xe, 0xe, 0, 0}, - {0x75, 0xe, 0xe, 0, 0}, - {0x76, 0xe, 0xe, 0, 0}, - {0x77, 0x13, 0x13, 0, 0}, - {0x78, 0x13, 0x13, 0, 0}, - {0x79, 0x1b, 0x1b, 0, 0}, - {0x7A, 0x1b, 0x1b, 0, 0}, - {0x7B, 0x55, 0x55, 0, 0}, - {0x7C, 0x5b, 0x5b, 0, 0}, - {0x7D, 0, 0, 0, 0}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0, 0, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0xFFFF, 0, 0, 0, 0} -}; - -radio_regs_t regs_RX_2056_A1[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0, 0, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0x3, 0x3, 0, 0}, - {0x21, 0, 0, 0, 0}, - {0x22, 0, 0, 0, 0}, - {0x23, 0x90, 0x90, 0, 0}, - {0x24, 0x55, 0x55, 0, 0}, - {0x25, 0x15, 0x15, 0, 0}, - {0x26, 0x5, 0x5, 0, 0}, - {0x27, 0x15, 0x15, 0, 0}, - {0x28, 0x5, 0x5, 0, 0}, - {0x29, 0x20, 0x20, 0, 0}, - {0x2A, 0x11, 0x11, 0, 0}, - {0x2B, 0x90, 0x90, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0x88, 0x88, 0, 0}, - {0x2E, 0x32, 0x32, 0, 0}, - {0x2F, 0x77, 0x77, 0, 0}, - {0x30, 0x17, 0x17, 1, 1}, - {0x31, 0xff, 0xff, 1, 1}, - {0x32, 0x20, 0x20, 0, 0}, - {0x33, 0, 0, 0, 0}, - {0x34, 0x88, 0x88, 0, 0}, - {0x35, 0x32, 0x32, 0, 0}, - {0x36, 0x77, 0x77, 0, 0}, - {0x37, 0x17, 0x17, 1, 1}, - {0x38, 0xf0, 0xf0, 1, 1}, - {0x39, 0x20, 0x20, 0, 0}, - {0x3A, 0x8, 0x8, 0, 0}, - {0x3B, 0x55, 0x55, 1, 1}, - {0x3C, 0, 0, 0, 0}, - {0x3D, 0x44, 0x44, 1, 1}, - {0x3E, 0, 0, 0, 0}, - {0x3F, 0x44, 0x44, 0, 0}, - {0x40, 0xf, 0xf, 1, 1}, - {0x41, 0x6, 0x6, 0, 0}, - {0x42, 0x4, 0x4, 0, 0}, - {0x43, 0x50, 0x50, 1, 1}, - {0x44, 0x8, 0x8, 0, 0}, - {0x45, 0x55, 0x55, 1, 1}, - {0x46, 0, 0, 0, 0}, - {0x47, 0x11, 0x11, 0, 0}, - {0x48, 0, 0, 0, 0}, - {0x49, 0x44, 0x44, 0, 0}, - {0x4A, 0x7, 0x7, 0, 0}, - {0x4B, 0x6, 0x6, 0, 0}, - {0x4C, 0x4, 0x4, 0, 0}, - {0x4D, 0, 0, 0, 0}, - {0x4E, 0, 0, 0, 0}, - {0x4F, 0x26, 0x26, 1, 1}, - {0x50, 0x26, 0x26, 1, 1}, - {0x51, 0xf, 0xf, 1, 1}, - {0x52, 0xf, 0xf, 1, 1}, - {0x53, 0x44, 0x44, 0, 0}, - {0x54, 0, 0, 0, 0}, - {0x55, 0, 0, 0, 0}, - {0x56, 0x8, 0x8, 0, 0}, - {0x57, 0x8, 0x8, 0, 0}, - {0x58, 0x7, 0x7, 0, 0}, - {0x59, 0x22, 0x22, 0, 0}, - {0x5A, 0x22, 0x22, 0, 0}, - {0x5B, 0x2, 0x2, 0, 0}, - {0x5C, 0x2f, 0x2f, 1, 1}, - {0x5D, 0x7, 0x7, 0, 0}, - {0x5E, 0x55, 0x55, 0, 0}, - {0x5F, 0x23, 0x23, 0, 0}, - {0x60, 0x41, 0x41, 0, 0}, - {0x61, 0x1, 0x1, 0, 0}, - {0x62, 0xa, 0xa, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0, 0, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0, 0, 0, 0}, - {0x68, 0, 0, 0, 0}, - {0x69, 0, 0, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0xc, 0xc, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0, 0, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0, 0, 0, 0}, - {0x71, 0, 0, 0, 0}, - {0x72, 0x22, 0x22, 0, 0}, - {0x73, 0x22, 0x22, 0, 0}, - {0x74, 0, 0, 1, 1}, - {0x75, 0xa, 0xa, 0, 0}, - {0x76, 0x1, 0x1, 0, 0}, - {0x77, 0x22, 0x22, 0, 0}, - {0x78, 0x30, 0x30, 0, 0}, - {0x79, 0, 0, 0, 0}, - {0x7A, 0, 0, 0, 0}, - {0x7B, 0, 0, 0, 0}, - {0x7C, 0, 0, 0, 0}, - {0x7D, 0, 0, 0, 0}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0, 0, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0x93, 0, 0, 0, 0}, - {0x94, 0, 0, 0, 0}, - {0xFFFF, 0, 0, 0, 0} -}; - -radio_regs_t regs_SYN_2056_rev5[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0x1, 0x1, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0, 0, 0, 0}, - {0x21, 0, 0, 0, 0}, - {0x22, 0x60, 0x60, 0, 0}, - {0x23, 0x6, 0x6, 0, 0}, - {0x24, 0xc, 0xc, 0, 0}, - {0x25, 0, 0, 0, 0}, - {0x26, 0, 0, 0, 0}, - {0x27, 0, 0, 0, 0}, - {0x28, 0x1, 0x1, 0, 0}, - {0x29, 0, 0, 0, 0}, - {0x2A, 0, 0, 0, 0}, - {0x2B, 0, 0, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0, 0, 0, 0}, - {0x2E, 0, 0, 0, 0}, - {0x2F, 0x1f, 0x1f, 0, 0}, - {0x30, 0x15, 0x15, 0, 0}, - {0x31, 0xf, 0xf, 0, 0}, - {0x32, 0, 0, 0, 0}, - {0x33, 0, 0, 0, 0}, - {0x34, 0, 0, 0, 0}, - {0x35, 0, 0, 0, 0}, - {0x36, 0, 0, 0, 0}, - {0x37, 0, 0, 0, 0}, - {0x38, 0, 0, 0, 0}, - {0x39, 0, 0, 0, 0}, - {0x3A, 0, 0, 0, 0}, - {0x3B, 0, 0, 0, 0}, - {0x3C, 0x13, 0x13, 0, 0}, - {0x3D, 0xf, 0xf, 0, 0}, - {0x3E, 0x18, 0x18, 0, 0}, - {0x3F, 0, 0, 0, 0}, - {0x40, 0, 0, 0, 0}, - {0x41, 0x20, 0x20, 0, 0}, - {0x42, 0x20, 0x20, 0, 0}, - {0x43, 0, 0, 0, 0}, - {0x44, 0x77, 0x77, 0, 0}, - {0x45, 0x7, 0x7, 0, 0}, - {0x46, 0x1, 0x1, 0, 0}, - {0x47, 0x4, 0x4, 0, 0}, - {0x48, 0xf, 0xf, 0, 0}, - {0x49, 0x30, 0x30, 0, 0}, - {0x4A, 0x32, 0x32, 0, 0}, - {0x4B, 0xd, 0xd, 0, 0}, - {0x4C, 0xd, 0xd, 0, 0}, - {0x4D, 0x4, 0x4, 0, 0}, - {0x4E, 0x6, 0x6, 0, 0}, - {0x4F, 0x1, 0x1, 0, 0}, - {0x50, 0x1c, 0x1c, 0, 0}, - {0x51, 0x2, 0x2, 0, 0}, - {0x52, 0x2, 0x2, 0, 0}, - {0x53, 0xf7, 0xf7, 1, 1}, - {0x54, 0xb4, 0xb4, 0, 0}, - {0x55, 0xd2, 0xd2, 0, 0}, - {0x56, 0, 0, 0, 0}, - {0x57, 0, 0, 0, 0}, - {0x58, 0x4, 0x4, 0, 0}, - {0x59, 0x96, 0x96, 0, 0}, - {0x5A, 0x3e, 0x3e, 0, 0}, - {0x5B, 0x3e, 0x3e, 0, 0}, - {0x5C, 0x13, 0x13, 0, 0}, - {0x5D, 0x2, 0x2, 0, 0}, - {0x5E, 0, 0, 0, 0}, - {0x5F, 0x7, 0x7, 0, 0}, - {0x60, 0x7, 0x7, 1, 1}, - {0x61, 0x8, 0x8, 0, 0}, - {0x62, 0x3, 0x3, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0, 0, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0, 0, 0, 0}, - {0x68, 0x40, 0x40, 0, 0}, - {0x69, 0, 0, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0, 0, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0x1, 0x1, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0x60, 0x60, 0, 0}, - {0x71, 0x66, 0x66, 0, 0}, - {0x72, 0xc, 0xc, 0, 0}, - {0x73, 0x66, 0x66, 0, 0}, - {0x74, 0x8f, 0x8f, 1, 1}, - {0x75, 0, 0, 0, 0}, - {0x76, 0xcc, 0xcc, 0, 0}, - {0x77, 0x1, 0x1, 0, 0}, - {0x78, 0x66, 0x66, 0, 0}, - {0x79, 0x66, 0x66, 0, 0}, - {0x7A, 0, 0, 0, 0}, - {0x7B, 0, 0, 0, 0}, - {0x7C, 0, 0, 0, 0}, - {0x7D, 0, 0, 0, 0}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0xff, 0xff, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0x93, 0, 0, 0, 0}, - {0x94, 0, 0, 0, 0}, - {0x95, 0, 0, 0, 0}, - {0x96, 0, 0, 0, 0}, - {0x97, 0, 0, 0, 0}, - {0x98, 0, 0, 0, 0}, - {0x99, 0, 0, 0, 0}, - {0x9A, 0, 0, 0, 0}, - {0x9B, 0, 0, 0, 0}, - {0x9C, 0, 0, 0, 0}, - {0x9D, 0, 0, 0, 0}, - {0x9E, 0, 0, 0, 0}, - {0x9F, 0x6, 0x6, 0, 0}, - {0xA0, 0x66, 0x66, 0, 0}, - {0xA1, 0x66, 0x66, 0, 0}, - {0xA2, 0x66, 0x66, 0, 0}, - {0xA3, 0x66, 0x66, 0, 0}, - {0xA4, 0x66, 0x66, 0, 0}, - {0xA5, 0x66, 0x66, 0, 0}, - {0xA6, 0x66, 0x66, 0, 0}, - {0xA7, 0x66, 0x66, 0, 0}, - {0xA8, 0x66, 0x66, 0, 0}, - {0xA9, 0x66, 0x66, 0, 0}, - {0xAA, 0x66, 0x66, 0, 0}, - {0xAB, 0x66, 0x66, 0, 0}, - {0xAC, 0x66, 0x66, 0, 0}, - {0xAD, 0x66, 0x66, 0, 0}, - {0xAE, 0x66, 0x66, 0, 0}, - {0xAF, 0x66, 0x66, 0, 0}, - {0xB0, 0x66, 0x66, 0, 0}, - {0xB1, 0x66, 0x66, 0, 0}, - {0xB2, 0x66, 0x66, 0, 0}, - {0xB3, 0xa, 0xa, 0, 0}, - {0xB4, 0, 0, 0, 0}, - {0xB5, 0, 0, 0, 0}, - {0xB6, 0, 0, 0, 0}, - {0xFFFF, 0, 0, 0, 0} -}; - -radio_regs_t regs_TX_2056_rev5[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0, 0, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0, 0, 0, 0}, - {0x21, 0x88, 0x88, 0, 0}, - {0x22, 0x88, 0x88, 0, 0}, - {0x23, 0x88, 0x88, 0, 0}, - {0x24, 0x88, 0x88, 0, 0}, - {0x25, 0xc, 0xc, 0, 0}, - {0x26, 0, 0, 0, 0}, - {0x27, 0x3, 0x3, 0, 0}, - {0x28, 0, 0, 0, 0}, - {0x29, 0x3, 0x3, 0, 0}, - {0x2A, 0x37, 0x37, 0, 0}, - {0x2B, 0x3, 0x3, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0, 0, 0, 0}, - {0x2E, 0x1, 0x1, 0, 0}, - {0x2F, 0x1, 0x1, 0, 0}, - {0x30, 0, 0, 0, 0}, - {0x31, 0, 0, 0, 0}, - {0x32, 0, 0, 0, 0}, - {0x33, 0x11, 0x11, 0, 0}, - {0x34, 0x11, 0x11, 0, 0}, - {0x35, 0, 0, 0, 0}, - {0x36, 0, 0, 0, 0}, - {0x37, 0x3, 0x3, 0, 0}, - {0x38, 0xf, 0xf, 0, 0}, - {0x39, 0, 0, 0, 0}, - {0x3A, 0x2d, 0x2d, 0, 0}, - {0x3B, 0, 0, 0, 0}, - {0x3C, 0x6e, 0x6e, 0, 0}, - {0x3D, 0xf0, 0xf0, 1, 1}, - {0x3E, 0, 0, 0, 0}, - {0x3F, 0, 0, 0, 0}, - {0x40, 0, 0, 0, 0}, - {0x41, 0x3, 0x3, 0, 0}, - {0x42, 0x3, 0x3, 0, 0}, - {0x43, 0, 0, 0, 0}, - {0x44, 0x1e, 0x1e, 0, 0}, - {0x45, 0, 0, 0, 0}, - {0x46, 0x6e, 0x6e, 0, 0}, - {0x47, 0xf0, 0xf0, 1, 1}, - {0x48, 0, 0, 0, 0}, - {0x49, 0x2, 0x2, 0, 0}, - {0x4A, 0xff, 0xff, 1, 1}, - {0x4B, 0xc, 0xc, 0, 0}, - {0x4C, 0, 0, 0, 0}, - {0x4D, 0x38, 0x38, 0, 0}, - {0x4E, 0x70, 0x70, 1, 1}, - {0x4F, 0x2, 0x2, 0, 0}, - {0x50, 0x88, 0x88, 0, 0}, - {0x51, 0xc, 0xc, 0, 0}, - {0x52, 0, 0, 0, 0}, - {0x53, 0x8, 0x8, 0, 0}, - {0x54, 0x70, 0x70, 1, 1}, - {0x55, 0x2, 0x2, 0, 0}, - {0x56, 0xff, 0xff, 1, 1}, - {0x57, 0, 0, 0, 0}, - {0x58, 0x83, 0x83, 0, 0}, - {0x59, 0x77, 0x77, 1, 1}, - {0x5A, 0, 0, 0, 0}, - {0x5B, 0x2, 0x2, 0, 0}, - {0x5C, 0x88, 0x88, 0, 0}, - {0x5D, 0, 0, 0, 0}, - {0x5E, 0x8, 0x8, 0, 0}, - {0x5F, 0x77, 0x77, 1, 1}, - {0x60, 0x1, 0x1, 0, 0}, - {0x61, 0, 0, 0, 0}, - {0x62, 0x7, 0x7, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0x7, 0x7, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0, 0, 1, 1}, - {0x68, 0, 0, 0, 0}, - {0x69, 0xa, 0xa, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0, 0, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0, 0, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0, 0, 0, 0}, - {0x71, 0x2, 0x2, 0, 0}, - {0x72, 0, 0, 0, 0}, - {0x73, 0, 0, 0, 0}, - {0x74, 0xe, 0xe, 0, 0}, - {0x75, 0xe, 0xe, 0, 0}, - {0x76, 0xe, 0xe, 0, 0}, - {0x77, 0x13, 0x13, 0, 0}, - {0x78, 0x13, 0x13, 0, 0}, - {0x79, 0x1b, 0x1b, 0, 0}, - {0x7A, 0x1b, 0x1b, 0, 0}, - {0x7B, 0x55, 0x55, 0, 0}, - {0x7C, 0x5b, 0x5b, 0, 0}, - {0x7D, 0, 0, 0, 0}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0, 0, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0x93, 0x70, 0x70, 0, 0}, - {0x94, 0x70, 0x70, 0, 0}, - {0x95, 0x71, 0x71, 1, 1}, - {0x96, 0x71, 0x71, 1, 1}, - {0x97, 0x72, 0x72, 1, 1}, - {0x98, 0x73, 0x73, 1, 1}, - {0x99, 0x74, 0x74, 1, 1}, - {0x9A, 0x75, 0x75, 1, 1}, - {0xFFFF, 0, 0, 0, 0} -}; - -radio_regs_t regs_RX_2056_rev5[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0, 0, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0x3, 0x3, 0, 0}, - {0x21, 0, 0, 0, 0}, - {0x22, 0, 0, 0, 0}, - {0x23, 0x90, 0x90, 0, 0}, - {0x24, 0x55, 0x55, 0, 0}, - {0x25, 0x15, 0x15, 0, 0}, - {0x26, 0x5, 0x5, 0, 0}, - {0x27, 0x15, 0x15, 0, 0}, - {0x28, 0x5, 0x5, 0, 0}, - {0x29, 0x20, 0x20, 0, 0}, - {0x2A, 0x11, 0x11, 0, 0}, - {0x2B, 0x90, 0x90, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0x88, 0x88, 0, 0}, - {0x2E, 0x32, 0x32, 0, 0}, - {0x2F, 0x77, 0x77, 0, 0}, - {0x30, 0x17, 0x17, 1, 1}, - {0x31, 0xff, 0xff, 1, 1}, - {0x32, 0x20, 0x20, 0, 0}, - {0x33, 0, 0, 0, 0}, - {0x34, 0x88, 0x88, 0, 0}, - {0x35, 0x32, 0x32, 0, 0}, - {0x36, 0x77, 0x77, 0, 0}, - {0x37, 0x17, 0x17, 1, 1}, - {0x38, 0xf0, 0xf0, 1, 1}, - {0x39, 0x20, 0x20, 0, 0}, - {0x3A, 0x8, 0x8, 0, 0}, - {0x3B, 0x55, 0x55, 1, 1}, - {0x3C, 0, 0, 0, 0}, - {0x3D, 0x88, 0x88, 1, 1}, - {0x3E, 0, 0, 0, 0}, - {0x3F, 0, 0, 1, 1}, - {0x40, 0x7, 0x7, 1, 1}, - {0x41, 0x6, 0x6, 0, 0}, - {0x42, 0x4, 0x4, 0, 0}, - {0x43, 0, 0, 0, 0}, - {0x44, 0x8, 0x8, 0, 0}, - {0x45, 0x55, 0x55, 1, 1}, - {0x46, 0, 0, 0, 0}, - {0x47, 0x11, 0x11, 0, 0}, - {0x48, 0, 0, 0, 0}, - {0x49, 0, 0, 1, 1}, - {0x4A, 0x7, 0x7, 0, 0}, - {0x4B, 0x6, 0x6, 0, 0}, - {0x4C, 0x4, 0x4, 0, 0}, - {0x4D, 0, 0, 0, 0}, - {0x4E, 0, 0, 0, 0}, - {0x4F, 0x26, 0x26, 1, 1}, - {0x50, 0x26, 0x26, 1, 1}, - {0x51, 0xf, 0xf, 1, 1}, - {0x52, 0xf, 0xf, 1, 1}, - {0x53, 0x44, 0x44, 0, 0}, - {0x54, 0, 0, 0, 0}, - {0x55, 0, 0, 0, 0}, - {0x56, 0x8, 0x8, 0, 0}, - {0x57, 0x8, 0x8, 0, 0}, - {0x58, 0x7, 0x7, 0, 0}, - {0x59, 0x22, 0x22, 0, 0}, - {0x5A, 0x22, 0x22, 0, 0}, - {0x5B, 0x2, 0x2, 0, 0}, - {0x5C, 0x4, 0x4, 1, 1}, - {0x5D, 0x7, 0x7, 0, 0}, - {0x5E, 0x55, 0x55, 0, 0}, - {0x5F, 0x23, 0x23, 0, 0}, - {0x60, 0x41, 0x41, 0, 0}, - {0x61, 0x1, 0x1, 0, 0}, - {0x62, 0xa, 0xa, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0, 0, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0, 0, 0, 0}, - {0x68, 0, 0, 0, 0}, - {0x69, 0, 0, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0xc, 0xc, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0, 0, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0, 0, 0, 0}, - {0x71, 0, 0, 0, 0}, - {0x72, 0x22, 0x22, 0, 0}, - {0x73, 0x22, 0x22, 0, 0}, - {0x74, 0, 0, 1, 1}, - {0x75, 0xa, 0xa, 0, 0}, - {0x76, 0x1, 0x1, 0, 0}, - {0x77, 0x22, 0x22, 0, 0}, - {0x78, 0x30, 0x30, 0, 0}, - {0x79, 0, 0, 0, 0}, - {0x7A, 0, 0, 0, 0}, - {0x7B, 0, 0, 0, 0}, - {0x7C, 0, 0, 0, 0}, - {0x7D, 0, 0, 0, 0}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0, 0, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0x93, 0, 0, 0, 0}, - {0x94, 0, 0, 0, 0}, - {0xFFFF, 0, 0, 0, 0} -}; - -radio_regs_t regs_SYN_2056_rev6[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0x1, 0x1, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0, 0, 0, 0}, - {0x21, 0, 0, 0, 0}, - {0x22, 0x60, 0x60, 0, 0}, - {0x23, 0x6, 0x6, 0, 0}, - {0x24, 0xc, 0xc, 0, 0}, - {0x25, 0, 0, 0, 0}, - {0x26, 0, 0, 0, 0}, - {0x27, 0, 0, 0, 0}, - {0x28, 0x1, 0x1, 0, 0}, - {0x29, 0, 0, 0, 0}, - {0x2A, 0, 0, 0, 0}, - {0x2B, 0, 0, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0, 0, 0, 0}, - {0x2E, 0, 0, 0, 0}, - {0x2F, 0x1f, 0x1f, 0, 0}, - {0x30, 0x15, 0x15, 0, 0}, - {0x31, 0xf, 0xf, 0, 0}, - {0x32, 0, 0, 0, 0}, - {0x33, 0, 0, 0, 0}, - {0x34, 0, 0, 0, 0}, - {0x35, 0, 0, 0, 0}, - {0x36, 0, 0, 0, 0}, - {0x37, 0, 0, 0, 0}, - {0x38, 0, 0, 0, 0}, - {0x39, 0, 0, 0, 0}, - {0x3A, 0, 0, 0, 0}, - {0x3B, 0, 0, 0, 0}, - {0x3C, 0x13, 0x13, 0, 0}, - {0x3D, 0xf, 0xf, 0, 0}, - {0x3E, 0x18, 0x18, 0, 0}, - {0x3F, 0, 0, 0, 0}, - {0x40, 0, 0, 0, 0}, - {0x41, 0x20, 0x20, 0, 0}, - {0x42, 0x20, 0x20, 0, 0}, - {0x43, 0, 0, 0, 0}, - {0x44, 0x77, 0x77, 0, 0}, - {0x45, 0x7, 0x7, 0, 0}, - {0x46, 0x1, 0x1, 0, 0}, - {0x47, 0x4, 0x4, 0, 0}, - {0x48, 0xf, 0xf, 0, 0}, - {0x49, 0x30, 0x30, 0, 0}, - {0x4A, 0x32, 0x32, 0, 0}, - {0x4B, 0xd, 0xd, 0, 0}, - {0x4C, 0xd, 0xd, 0, 0}, - {0x4D, 0x4, 0x4, 0, 0}, - {0x4E, 0x6, 0x6, 0, 0}, - {0x4F, 0x1, 0x1, 0, 0}, - {0x50, 0x1c, 0x1c, 0, 0}, - {0x51, 0x2, 0x2, 0, 0}, - {0x52, 0x2, 0x2, 0, 0}, - {0x53, 0xf7, 0xf7, 1, 1}, - {0x54, 0xb4, 0xb4, 0, 0}, - {0x55, 0xd2, 0xd2, 0, 0}, - {0x56, 0, 0, 0, 0}, - {0x57, 0, 0, 0, 0}, - {0x58, 0x4, 0x4, 0, 0}, - {0x59, 0x96, 0x96, 0, 0}, - {0x5A, 0x3e, 0x3e, 0, 0}, - {0x5B, 0x3e, 0x3e, 0, 0}, - {0x5C, 0x13, 0x13, 0, 0}, - {0x5D, 0x2, 0x2, 0, 0}, - {0x5E, 0, 0, 0, 0}, - {0x5F, 0x7, 0x7, 0, 0}, - {0x60, 0x7, 0x7, 1, 1}, - {0x61, 0x8, 0x8, 0, 0}, - {0x62, 0x3, 0x3, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0, 0, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0, 0, 0, 0}, - {0x68, 0x40, 0x40, 0, 0}, - {0x69, 0, 0, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0, 0, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0x1, 0x1, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0x60, 0x60, 0, 0}, - {0x71, 0x66, 0x66, 0, 0}, - {0x72, 0xc, 0xc, 0, 0}, - {0x73, 0x66, 0x66, 0, 0}, - {0x74, 0x8f, 0x8f, 1, 1}, - {0x75, 0, 0, 0, 0}, - {0x76, 0xcc, 0xcc, 0, 0}, - {0x77, 0x1, 0x1, 0, 0}, - {0x78, 0x66, 0x66, 0, 0}, - {0x79, 0x66, 0x66, 0, 0}, - {0x7A, 0, 0, 0, 0}, - {0x7B, 0, 0, 0, 0}, - {0x7C, 0, 0, 0, 0}, - {0x7D, 0, 0, 0, 0}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0xff, 0xff, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0x93, 0, 0, 0, 0}, - {0x94, 0, 0, 0, 0}, - {0x95, 0, 0, 0, 0}, - {0x96, 0, 0, 0, 0}, - {0x97, 0, 0, 0, 0}, - {0x98, 0, 0, 0, 0}, - {0x99, 0, 0, 0, 0}, - {0x9A, 0, 0, 0, 0}, - {0x9B, 0, 0, 0, 0}, - {0x9C, 0, 0, 0, 0}, - {0x9D, 0, 0, 0, 0}, - {0x9E, 0, 0, 0, 0}, - {0x9F, 0x6, 0x6, 0, 0}, - {0xA0, 0x66, 0x66, 0, 0}, - {0xA1, 0x66, 0x66, 0, 0}, - {0xA2, 0x66, 0x66, 0, 0}, - {0xA3, 0x66, 0x66, 0, 0}, - {0xA4, 0x66, 0x66, 0, 0}, - {0xA5, 0x66, 0x66, 0, 0}, - {0xA6, 0x66, 0x66, 0, 0}, - {0xA7, 0x66, 0x66, 0, 0}, - {0xA8, 0x66, 0x66, 0, 0}, - {0xA9, 0x66, 0x66, 0, 0}, - {0xAA, 0x66, 0x66, 0, 0}, - {0xAB, 0x66, 0x66, 0, 0}, - {0xAC, 0x66, 0x66, 0, 0}, - {0xAD, 0x66, 0x66, 0, 0}, - {0xAE, 0x66, 0x66, 0, 0}, - {0xAF, 0x66, 0x66, 0, 0}, - {0xB0, 0x66, 0x66, 0, 0}, - {0xB1, 0x66, 0x66, 0, 0}, - {0xB2, 0x66, 0x66, 0, 0}, - {0xB3, 0xa, 0xa, 0, 0}, - {0xB4, 0, 0, 0, 0}, - {0xB5, 0, 0, 0, 0}, - {0xB6, 0, 0, 0, 0}, - {0xFFFF, 0, 0, 0, 0} -}; - -radio_regs_t regs_TX_2056_rev6[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0, 0, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0, 0, 0, 0}, - {0x21, 0x88, 0x88, 0, 0}, - {0x22, 0x88, 0x88, 0, 0}, - {0x23, 0x88, 0x88, 0, 0}, - {0x24, 0x88, 0x88, 0, 0}, - {0x25, 0xc, 0xc, 0, 0}, - {0x26, 0, 0, 0, 0}, - {0x27, 0x3, 0x3, 0, 0}, - {0x28, 0, 0, 0, 0}, - {0x29, 0x3, 0x3, 0, 0}, - {0x2A, 0x37, 0x37, 0, 0}, - {0x2B, 0x3, 0x3, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0, 0, 0, 0}, - {0x2E, 0x1, 0x1, 0, 0}, - {0x2F, 0x1, 0x1, 0, 0}, - {0x30, 0, 0, 0, 0}, - {0x31, 0, 0, 0, 0}, - {0x32, 0, 0, 0, 0}, - {0x33, 0x11, 0x11, 0, 0}, - {0x34, 0xee, 0xee, 1, 1}, - {0x35, 0, 0, 0, 0}, - {0x36, 0, 0, 0, 0}, - {0x37, 0x3, 0x3, 0, 0}, - {0x38, 0x50, 0x50, 1, 1}, - {0x39, 0, 0, 0, 0}, - {0x3A, 0x50, 0x50, 1, 1}, - {0x3B, 0, 0, 0, 0}, - {0x3C, 0x6e, 0x6e, 0, 0}, - {0x3D, 0xf0, 0xf0, 1, 1}, - {0x3E, 0, 0, 0, 0}, - {0x3F, 0, 0, 0, 0}, - {0x40, 0, 0, 0, 0}, - {0x41, 0x3, 0x3, 0, 0}, - {0x42, 0x3, 0x3, 0, 0}, - {0x43, 0, 0, 0, 0}, - {0x44, 0x1e, 0x1e, 0, 0}, - {0x45, 0, 0, 0, 0}, - {0x46, 0x6e, 0x6e, 0, 0}, - {0x47, 0xf0, 0xf0, 1, 1}, - {0x48, 0, 0, 0, 0}, - {0x49, 0x2, 0x2, 0, 0}, - {0x4A, 0xff, 0xff, 1, 1}, - {0x4B, 0xc, 0xc, 0, 0}, - {0x4C, 0, 0, 0, 0}, - {0x4D, 0x38, 0x38, 0, 0}, - {0x4E, 0x70, 0x70, 1, 1}, - {0x4F, 0x2, 0x2, 0, 0}, - {0x50, 0x88, 0x88, 0, 0}, - {0x51, 0xc, 0xc, 0, 0}, - {0x52, 0, 0, 0, 0}, - {0x53, 0x8, 0x8, 0, 0}, - {0x54, 0x70, 0x70, 1, 1}, - {0x55, 0x2, 0x2, 0, 0}, - {0x56, 0xff, 0xff, 1, 1}, - {0x57, 0, 0, 0, 0}, - {0x58, 0x83, 0x83, 0, 0}, - {0x59, 0x77, 0x77, 1, 1}, - {0x5A, 0, 0, 0, 0}, - {0x5B, 0x2, 0x2, 0, 0}, - {0x5C, 0x88, 0x88, 0, 0}, - {0x5D, 0, 0, 0, 0}, - {0x5E, 0x8, 0x8, 0, 0}, - {0x5F, 0x77, 0x77, 1, 1}, - {0x60, 0x1, 0x1, 0, 0}, - {0x61, 0, 0, 0, 0}, - {0x62, 0x7, 0x7, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0x7, 0x7, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0, 0, 1, 1}, - {0x68, 0, 0, 0, 0}, - {0x69, 0xa, 0xa, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0, 0, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0, 0, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0, 0, 0, 0}, - {0x71, 0x2, 0x2, 0, 0}, - {0x72, 0, 0, 0, 0}, - {0x73, 0, 0, 0, 0}, - {0x74, 0xe, 0xe, 0, 0}, - {0x75, 0xe, 0xe, 0, 0}, - {0x76, 0xe, 0xe, 0, 0}, - {0x77, 0x13, 0x13, 0, 0}, - {0x78, 0x13, 0x13, 0, 0}, - {0x79, 0x1b, 0x1b, 0, 0}, - {0x7A, 0x1b, 0x1b, 0, 0}, - {0x7B, 0x55, 0x55, 0, 0}, - {0x7C, 0x5b, 0x5b, 0, 0}, - {0x7D, 0x30, 0x30, 1, 1}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0, 0, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0x93, 0x70, 0x70, 0, 0}, - {0x94, 0x70, 0x70, 0, 0}, - {0x95, 0x70, 0x70, 0, 0}, - {0x96, 0x70, 0x70, 0, 0}, - {0x97, 0x70, 0x70, 0, 0}, - {0x98, 0x70, 0x70, 0, 0}, - {0x99, 0x70, 0x70, 0, 0}, - {0x9A, 0x70, 0x70, 0, 0}, - {0xFFFF, 0, 0, 0, 0} -}; - -radio_regs_t regs_RX_2056_rev6[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0, 0, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0x3, 0x3, 0, 0}, - {0x21, 0, 0, 0, 0}, - {0x22, 0, 0, 0, 0}, - {0x23, 0x90, 0x90, 0, 0}, - {0x24, 0x55, 0x55, 0, 0}, - {0x25, 0x15, 0x15, 0, 0}, - {0x26, 0x5, 0x5, 0, 0}, - {0x27, 0x15, 0x15, 0, 0}, - {0x28, 0x5, 0x5, 0, 0}, - {0x29, 0x20, 0x20, 0, 0}, - {0x2A, 0x11, 0x11, 0, 0}, - {0x2B, 0x90, 0x90, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0x88, 0x88, 0, 0}, - {0x2E, 0x32, 0x32, 0, 0}, - {0x2F, 0x77, 0x77, 0, 0}, - {0x30, 0x17, 0x17, 1, 1}, - {0x31, 0xff, 0xff, 1, 1}, - {0x32, 0x20, 0x20, 0, 0}, - {0x33, 0, 0, 0, 0}, - {0x34, 0x88, 0x88, 0, 0}, - {0x35, 0x32, 0x32, 0, 0}, - {0x36, 0x77, 0x77, 0, 0}, - {0x37, 0x17, 0x17, 1, 1}, - {0x38, 0xf0, 0xf0, 1, 1}, - {0x39, 0x20, 0x20, 0, 0}, - {0x3A, 0x8, 0x8, 0, 0}, - {0x3B, 0x55, 0x55, 1, 1}, - {0x3C, 0, 0, 0, 0}, - {0x3D, 0x88, 0x88, 1, 1}, - {0x3E, 0, 0, 0, 0}, - {0x3F, 0x44, 0x44, 0, 0}, - {0x40, 0x7, 0x7, 1, 1}, - {0x41, 0x6, 0x6, 0, 0}, - {0x42, 0x4, 0x4, 0, 0}, - {0x43, 0, 0, 0, 0}, - {0x44, 0x8, 0x8, 0, 0}, - {0x45, 0x55, 0x55, 1, 1}, - {0x46, 0, 0, 0, 0}, - {0x47, 0x11, 0x11, 0, 0}, - {0x48, 0, 0, 0, 0}, - {0x49, 0x44, 0x44, 0, 0}, - {0x4A, 0x7, 0x7, 0, 0}, - {0x4B, 0x6, 0x6, 0, 0}, - {0x4C, 0x4, 0x4, 0, 0}, - {0x4D, 0, 0, 0, 0}, - {0x4E, 0, 0, 0, 0}, - {0x4F, 0x26, 0x26, 1, 1}, - {0x50, 0x26, 0x26, 1, 1}, - {0x51, 0xf, 0xf, 1, 1}, - {0x52, 0xf, 0xf, 1, 1}, - {0x53, 0x44, 0x44, 0, 0}, - {0x54, 0, 0, 0, 0}, - {0x55, 0, 0, 0, 0}, - {0x56, 0x8, 0x8, 0, 0}, - {0x57, 0x8, 0x8, 0, 0}, - {0x58, 0x7, 0x7, 0, 0}, - {0x59, 0x22, 0x22, 0, 0}, - {0x5A, 0x22, 0x22, 0, 0}, - {0x5B, 0x2, 0x2, 0, 0}, - {0x5C, 0x4, 0x4, 1, 1}, - {0x5D, 0x7, 0x7, 0, 0}, - {0x5E, 0x55, 0x55, 0, 0}, - {0x5F, 0x23, 0x23, 0, 0}, - {0x60, 0x41, 0x41, 0, 0}, - {0x61, 0x1, 0x1, 0, 0}, - {0x62, 0xa, 0xa, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0, 0, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0, 0, 0, 0}, - {0x68, 0, 0, 0, 0}, - {0x69, 0, 0, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0xc, 0xc, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0, 0, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0, 0, 0, 0}, - {0x71, 0, 0, 0, 0}, - {0x72, 0x22, 0x22, 0, 0}, - {0x73, 0x22, 0x22, 0, 0}, - {0x74, 0, 0, 1, 1}, - {0x75, 0xa, 0xa, 0, 0}, - {0x76, 0x1, 0x1, 0, 0}, - {0x77, 0x22, 0x22, 0, 0}, - {0x78, 0x30, 0x30, 0, 0}, - {0x79, 0, 0, 0, 0}, - {0x7A, 0, 0, 0, 0}, - {0x7B, 0, 0, 0, 0}, - {0x7C, 0, 0, 0, 0}, - {0x7D, 0x5, 0x5, 1, 1}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0, 0, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0x93, 0, 0, 0, 0}, - {0x94, 0, 0, 0, 0}, - {0xFFFF, 0, 0, 0, 0} -}; - -radio_regs_t regs_SYN_2056_rev7[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0x1, 0x1, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0, 0, 0, 0}, - {0x21, 0, 0, 0, 0}, - {0x22, 0x60, 0x60, 0, 0}, - {0x23, 0x6, 0x6, 0, 0}, - {0x24, 0xc, 0xc, 0, 0}, - {0x25, 0, 0, 0, 0}, - {0x26, 0, 0, 0, 0}, - {0x27, 0, 0, 0, 0}, - {0x28, 0x1, 0x1, 0, 0}, - {0x29, 0, 0, 0, 0}, - {0x2A, 0, 0, 0, 0}, - {0x2B, 0, 0, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0, 0, 0, 0}, - {0x2E, 0, 0, 0, 0}, - {0x2F, 0x1f, 0x1f, 0, 0}, - {0x30, 0x15, 0x15, 0, 0}, - {0x31, 0xf, 0xf, 0, 0}, - {0x32, 0, 0, 0, 0}, - {0x33, 0, 0, 0, 0}, - {0x34, 0, 0, 0, 0}, - {0x35, 0, 0, 0, 0}, - {0x36, 0, 0, 0, 0}, - {0x37, 0, 0, 0, 0}, - {0x38, 0, 0, 0, 0}, - {0x39, 0, 0, 0, 0}, - {0x3A, 0, 0, 0, 0}, - {0x3B, 0, 0, 0, 0}, - {0x3C, 0x13, 0x13, 0, 0}, - {0x3D, 0xf, 0xf, 0, 0}, - {0x3E, 0x18, 0x18, 0, 0}, - {0x3F, 0, 0, 0, 0}, - {0x40, 0, 0, 0, 0}, - {0x41, 0x20, 0x20, 0, 0}, - {0x42, 0x20, 0x20, 0, 0}, - {0x43, 0, 0, 0, 0}, - {0x44, 0x77, 0x77, 0, 0}, - {0x45, 0x7, 0x7, 0, 0}, - {0x46, 0x1, 0x1, 0, 0}, - {0x47, 0x4, 0x4, 0, 0}, - {0x48, 0xf, 0xf, 0, 0}, - {0x49, 0x30, 0x30, 0, 0}, - {0x4A, 0x32, 0x32, 0, 0}, - {0x4B, 0xd, 0xd, 0, 0}, - {0x4C, 0xd, 0xd, 0, 0}, - {0x4D, 0x4, 0x4, 0, 0}, - {0x4E, 0x6, 0x6, 0, 0}, - {0x4F, 0x1, 0x1, 0, 0}, - {0x50, 0x1c, 0x1c, 0, 0}, - {0x51, 0x2, 0x2, 0, 0}, - {0x52, 0x2, 0x2, 0, 0}, - {0x53, 0xf7, 0xf7, 1, 1}, - {0x54, 0xb4, 0xb4, 0, 0}, - {0x55, 0xd2, 0xd2, 0, 0}, - {0x56, 0, 0, 0, 0}, - {0x57, 0, 0, 0, 0}, - {0x58, 0x4, 0x4, 0, 0}, - {0x59, 0x96, 0x96, 0, 0}, - {0x5A, 0x3e, 0x3e, 0, 0}, - {0x5B, 0x3e, 0x3e, 0, 0}, - {0x5C, 0x13, 0x13, 0, 0}, - {0x5D, 0x2, 0x2, 0, 0}, - {0x5E, 0, 0, 0, 0}, - {0x5F, 0x7, 0x7, 0, 0}, - {0x60, 0x7, 0x7, 1, 1}, - {0x61, 0x8, 0x8, 0, 0}, - {0x62, 0x3, 0x3, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0, 0, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0, 0, 0, 0}, - {0x68, 0x40, 0x40, 0, 0}, - {0x69, 0, 0, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0, 0, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0x1, 0x1, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0x60, 0x60, 0, 0}, - {0x71, 0x66, 0x66, 0, 0}, - {0x72, 0xc, 0xc, 0, 0}, - {0x73, 0x66, 0x66, 0, 0}, - {0x74, 0x8f, 0x8f, 1, 1}, - {0x75, 0, 0, 0, 0}, - {0x76, 0xcc, 0xcc, 0, 0}, - {0x77, 0x1, 0x1, 0, 0}, - {0x78, 0x66, 0x66, 0, 0}, - {0x79, 0x66, 0x66, 0, 0}, - {0x7A, 0, 0, 0, 0}, - {0x7B, 0, 0, 0, 0}, - {0x7C, 0, 0, 0, 0}, - {0x7D, 0, 0, 0, 0}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0xff, 0xff, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0x93, 0, 0, 0, 0}, - {0x94, 0, 0, 0, 0}, - {0x95, 0, 0, 0, 0}, - {0x96, 0, 0, 0, 0}, - {0x97, 0, 0, 0, 0}, - {0x98, 0, 0, 0, 0}, - {0x99, 0, 0, 0, 0}, - {0x9A, 0, 0, 0, 0}, - {0x9B, 0, 0, 0, 0}, - {0x9C, 0, 0, 0, 0}, - {0x9D, 0, 0, 0, 0}, - {0x9E, 0, 0, 0, 0}, - {0x9F, 0x6, 0x6, 0, 0}, - {0xA0, 0x66, 0x66, 0, 0}, - {0xA1, 0x66, 0x66, 0, 0}, - {0xA2, 0x66, 0x66, 0, 0}, - {0xA3, 0x66, 0x66, 0, 0}, - {0xA4, 0x66, 0x66, 0, 0}, - {0xA5, 0x66, 0x66, 0, 0}, - {0xA6, 0x66, 0x66, 0, 0}, - {0xA7, 0x66, 0x66, 0, 0}, - {0xA8, 0x66, 0x66, 0, 0}, - {0xA9, 0x66, 0x66, 0, 0}, - {0xAA, 0x66, 0x66, 0, 0}, - {0xAB, 0x66, 0x66, 0, 0}, - {0xAC, 0x66, 0x66, 0, 0}, - {0xAD, 0x66, 0x66, 0, 0}, - {0xAE, 0x66, 0x66, 0, 0}, - {0xAF, 0x66, 0x66, 0, 0}, - {0xB0, 0x66, 0x66, 0, 0}, - {0xB1, 0x66, 0x66, 0, 0}, - {0xB2, 0x66, 0x66, 0, 0}, - {0xB3, 0xa, 0xa, 0, 0}, - {0xB4, 0, 0, 0, 0}, - {0xB5, 0, 0, 0, 0}, - {0xB6, 0, 0, 0, 0}, - {0xFFFF, 0, 0, 0, 0}, -}; - -radio_regs_t regs_TX_2056_rev7[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0, 0, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0, 0, 0, 0}, - {0x21, 0x88, 0x88, 0, 0}, - {0x22, 0x88, 0x88, 0, 0}, - {0x23, 0x88, 0x88, 0, 0}, - {0x24, 0x88, 0x88, 0, 0}, - {0x25, 0xc, 0xc, 0, 0}, - {0x26, 0, 0, 0, 0}, - {0x27, 0x3, 0x3, 0, 0}, - {0x28, 0, 0, 0, 0}, - {0x29, 0x3, 0x3, 0, 0}, - {0x2A, 0x37, 0x37, 0, 0}, - {0x2B, 0x3, 0x3, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0, 0, 0, 0}, - {0x2E, 0x1, 0x1, 0, 0}, - {0x2F, 0x1, 0x1, 0, 0}, - {0x30, 0, 0, 0, 0}, - {0x31, 0, 0, 0, 0}, - {0x32, 0, 0, 0, 0}, - {0x33, 0x11, 0x11, 0, 0}, - {0x34, 0xee, 0xee, 1, 1}, - {0x35, 0, 0, 0, 0}, - {0x36, 0, 0, 0, 0}, - {0x37, 0x3, 0x3, 0, 0}, - {0x38, 0x50, 0x50, 1, 1}, - {0x39, 0, 0, 0, 0}, - {0x3A, 0x50, 0x50, 1, 1}, - {0x3B, 0, 0, 0, 0}, - {0x3C, 0x6e, 0x6e, 0, 0}, - {0x3D, 0xf0, 0xf0, 1, 1}, - {0x3E, 0, 0, 0, 0}, - {0x3F, 0, 0, 0, 0}, - {0x40, 0, 0, 0, 0}, - {0x41, 0x3, 0x3, 0, 0}, - {0x42, 0x3, 0x3, 0, 0}, - {0x43, 0, 0, 0, 0}, - {0x44, 0x1e, 0x1e, 0, 0}, - {0x45, 0, 0, 0, 0}, - {0x46, 0x6e, 0x6e, 0, 0}, - {0x47, 0xf0, 0xf0, 1, 1}, - {0x48, 0, 0, 0, 0}, - {0x49, 0x2, 0x2, 0, 0}, - {0x4A, 0xff, 0xff, 1, 1}, - {0x4B, 0xc, 0xc, 0, 0}, - {0x4C, 0, 0, 0, 0}, - {0x4D, 0x38, 0x38, 0, 0}, - {0x4E, 0x70, 0x70, 1, 1}, - {0x4F, 0x2, 0x2, 0, 0}, - {0x50, 0x88, 0x88, 0, 0}, - {0x51, 0xc, 0xc, 0, 0}, - {0x52, 0, 0, 0, 0}, - {0x53, 0x8, 0x8, 0, 0}, - {0x54, 0x70, 0x70, 1, 1}, - {0x55, 0x2, 0x2, 0, 0}, - {0x56, 0xff, 0xff, 1, 1}, - {0x57, 0, 0, 0, 0}, - {0x58, 0x83, 0x83, 0, 0}, - {0x59, 0x77, 0x77, 1, 1}, - {0x5A, 0, 0, 0, 0}, - {0x5B, 0x2, 0x2, 0, 0}, - {0x5C, 0x88, 0x88, 0, 0}, - {0x5D, 0, 0, 0, 0}, - {0x5E, 0x8, 0x8, 0, 0}, - {0x5F, 0x77, 0x77, 1, 1}, - {0x60, 0x1, 0x1, 0, 0}, - {0x61, 0, 0, 0, 0}, - {0x62, 0x7, 0x7, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0x7, 0x7, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0, 0, 1, 1}, - {0x68, 0, 0, 0, 0}, - {0x69, 0xa, 0xa, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0, 0, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0, 0, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0, 0, 0, 0}, - {0x71, 0x2, 0x2, 0, 0}, - {0x72, 0, 0, 0, 0}, - {0x73, 0, 0, 0, 0}, - {0x74, 0xe, 0xe, 0, 0}, - {0x75, 0xe, 0xe, 0, 0}, - {0x76, 0xe, 0xe, 0, 0}, - {0x77, 0x13, 0x13, 0, 0}, - {0x78, 0x13, 0x13, 0, 0}, - {0x79, 0x1b, 0x1b, 0, 0}, - {0x7A, 0x1b, 0x1b, 0, 0}, - {0x7B, 0x55, 0x55, 0, 0}, - {0x7C, 0x5b, 0x5b, 0, 0}, - {0x7D, 0x30, 0x30, 1, 1}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0, 0, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0x93, 0x70, 0x70, 0, 0}, - {0x94, 0x70, 0x70, 0, 0}, - {0x95, 0x71, 0x71, 1, 1}, - {0x96, 0x71, 0x71, 1, 1}, - {0x97, 0x72, 0x72, 1, 1}, - {0x98, 0x73, 0x73, 1, 1}, - {0x99, 0x74, 0x74, 1, 1}, - {0x9A, 0x75, 0x75, 1, 1}, - {0xFFFF, 0, 0, 0, 0}, -}; - -radio_regs_t regs_RX_2056_rev7[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0, 0, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0x3, 0x3, 0, 0}, - {0x21, 0, 0, 0, 0}, - {0x22, 0, 0, 0, 0}, - {0x23, 0x90, 0x90, 0, 0}, - {0x24, 0x55, 0x55, 0, 0}, - {0x25, 0x15, 0x15, 0, 0}, - {0x26, 0x5, 0x5, 0, 0}, - {0x27, 0x15, 0x15, 0, 0}, - {0x28, 0x5, 0x5, 0, 0}, - {0x29, 0x20, 0x20, 0, 0}, - {0x2A, 0x11, 0x11, 0, 0}, - {0x2B, 0x90, 0x90, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0x88, 0x88, 0, 0}, - {0x2E, 0x32, 0x32, 0, 0}, - {0x2F, 0x77, 0x77, 0, 0}, - {0x30, 0x17, 0x17, 1, 1}, - {0x31, 0xff, 0xff, 1, 1}, - {0x32, 0x20, 0x20, 0, 0}, - {0x33, 0, 0, 0, 0}, - {0x34, 0x88, 0x88, 0, 0}, - {0x35, 0x32, 0x32, 0, 0}, - {0x36, 0x77, 0x77, 0, 0}, - {0x37, 0x17, 0x17, 1, 1}, - {0x38, 0xf0, 0xf0, 1, 1}, - {0x39, 0x20, 0x20, 0, 0}, - {0x3A, 0x8, 0x8, 0, 0}, - {0x3B, 0x55, 0x55, 1, 1}, - {0x3C, 0, 0, 0, 0}, - {0x3D, 0x88, 0x88, 1, 1}, - {0x3E, 0, 0, 0, 0}, - {0x3F, 0, 0, 1, 1}, - {0x40, 0x7, 0x7, 1, 1}, - {0x41, 0x6, 0x6, 0, 0}, - {0x42, 0x4, 0x4, 0, 0}, - {0x43, 0, 0, 0, 0}, - {0x44, 0x8, 0x8, 0, 0}, - {0x45, 0x55, 0x55, 1, 1}, - {0x46, 0, 0, 0, 0}, - {0x47, 0x11, 0x11, 0, 0}, - {0x48, 0, 0, 0, 0}, - {0x49, 0, 0, 1, 1}, - {0x4A, 0x7, 0x7, 0, 0}, - {0x4B, 0x6, 0x6, 0, 0}, - {0x4C, 0x4, 0x4, 0, 0}, - {0x4D, 0, 0, 0, 0}, - {0x4E, 0, 0, 0, 0}, - {0x4F, 0x26, 0x26, 1, 1}, - {0x50, 0x26, 0x26, 1, 1}, - {0x51, 0xf, 0xf, 1, 1}, - {0x52, 0xf, 0xf, 1, 1}, - {0x53, 0x44, 0x44, 0, 0}, - {0x54, 0, 0, 0, 0}, - {0x55, 0, 0, 0, 0}, - {0x56, 0x8, 0x8, 0, 0}, - {0x57, 0x8, 0x8, 0, 0}, - {0x58, 0x7, 0x7, 0, 0}, - {0x59, 0x22, 0x22, 0, 0}, - {0x5A, 0x22, 0x22, 0, 0}, - {0x5B, 0x2, 0x2, 0, 0}, - {0x5C, 0x4, 0x4, 1, 1}, - {0x5D, 0x7, 0x7, 0, 0}, - {0x5E, 0x55, 0x55, 0, 0}, - {0x5F, 0x23, 0x23, 0, 0}, - {0x60, 0x41, 0x41, 0, 0}, - {0x61, 0x1, 0x1, 0, 0}, - {0x62, 0xa, 0xa, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0, 0, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0, 0, 0, 0}, - {0x68, 0, 0, 0, 0}, - {0x69, 0, 0, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0xc, 0xc, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0, 0, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0, 0, 0, 0}, - {0x71, 0, 0, 0, 0}, - {0x72, 0x22, 0x22, 0, 0}, - {0x73, 0x22, 0x22, 0, 0}, - {0x74, 0, 0, 1, 1}, - {0x75, 0xa, 0xa, 0, 0}, - {0x76, 0x1, 0x1, 0, 0}, - {0x77, 0x22, 0x22, 0, 0}, - {0x78, 0x30, 0x30, 0, 0}, - {0x79, 0, 0, 0, 0}, - {0x7A, 0, 0, 0, 0}, - {0x7B, 0, 0, 0, 0}, - {0x7C, 0, 0, 0, 0}, - {0x7D, 0, 0, 0, 0}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0, 0, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0x93, 0, 0, 0, 0}, - {0x94, 0, 0, 0, 0}, - {0xFFFF, 0, 0, 0, 0}, -}; - -radio_regs_t regs_SYN_2056_rev8[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0x1, 0x1, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0, 0, 0, 0}, - {0x21, 0, 0, 0, 0}, - {0x22, 0x60, 0x60, 0, 0}, - {0x23, 0x6, 0x6, 0, 0}, - {0x24, 0xc, 0xc, 0, 0}, - {0x25, 0, 0, 0, 0}, - {0x26, 0, 0, 0, 0}, - {0x27, 0, 0, 0, 0}, - {0x28, 0x1, 0x1, 0, 0}, - {0x29, 0, 0, 0, 0}, - {0x2A, 0, 0, 0, 0}, - {0x2B, 0, 0, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0, 0, 0, 0}, - {0x2E, 0, 0, 0, 0}, - {0x2F, 0x1f, 0x1f, 0, 0}, - {0x30, 0x15, 0x15, 0, 0}, - {0x31, 0xf, 0xf, 0, 0}, - {0x32, 0, 0, 0, 0}, - {0x33, 0, 0, 0, 0}, - {0x34, 0, 0, 0, 0}, - {0x35, 0, 0, 0, 0}, - {0x36, 0, 0, 0, 0}, - {0x37, 0, 0, 0, 0}, - {0x38, 0, 0, 0, 0}, - {0x39, 0, 0, 0, 0}, - {0x3A, 0, 0, 0, 0}, - {0x3B, 0, 0, 0, 0}, - {0x3C, 0x13, 0x13, 0, 0}, - {0x3D, 0xf, 0xf, 0, 0}, - {0x3E, 0x18, 0x18, 0, 0}, - {0x3F, 0, 0, 0, 0}, - {0x40, 0, 0, 0, 0}, - {0x41, 0x20, 0x20, 0, 0}, - {0x42, 0x20, 0x20, 0, 0}, - {0x43, 0, 0, 0, 0}, - {0x44, 0x77, 0x77, 0, 0}, - {0x45, 0x7, 0x7, 0, 0}, - {0x46, 0x1, 0x1, 0, 0}, - {0x47, 0x4, 0x4, 0, 0}, - {0x48, 0xf, 0xf, 0, 0}, - {0x49, 0x30, 0x30, 0, 0}, - {0x4A, 0x32, 0x32, 0, 0}, - {0x4B, 0xd, 0xd, 0, 0}, - {0x4C, 0xd, 0xd, 0, 0}, - {0x4D, 0x4, 0x4, 0, 0}, - {0x4E, 0x6, 0x6, 0, 0}, - {0x4F, 0x1, 0x1, 0, 0}, - {0x50, 0x1c, 0x1c, 0, 0}, - {0x51, 0x2, 0x2, 0, 0}, - {0x52, 0x2, 0x2, 0, 0}, - {0x53, 0xf7, 0xf7, 1, 1}, - {0x54, 0xb4, 0xb4, 0, 0}, - {0x55, 0xd2, 0xd2, 0, 0}, - {0x56, 0, 0, 0, 0}, - {0x57, 0, 0, 0, 0}, - {0x58, 0x4, 0x4, 0, 0}, - {0x59, 0x96, 0x96, 0, 0}, - {0x5A, 0x3e, 0x3e, 0, 0}, - {0x5B, 0x3e, 0x3e, 0, 0}, - {0x5C, 0x13, 0x13, 0, 0}, - {0x5D, 0x2, 0x2, 0, 0}, - {0x5E, 0, 0, 0, 0}, - {0x5F, 0x7, 0x7, 0, 0}, - {0x60, 0x7, 0x7, 1, 1}, - {0x61, 0x8, 0x8, 0, 0}, - {0x62, 0x3, 0x3, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0, 0, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0, 0, 0, 0}, - {0x68, 0x40, 0x40, 0, 0}, - {0x69, 0, 0, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0, 0, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0x1, 0x1, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0x60, 0x60, 0, 0}, - {0x71, 0x66, 0x66, 0, 0}, - {0x72, 0xc, 0xc, 0, 0}, - {0x73, 0x66, 0x66, 0, 0}, - {0x74, 0x8f, 0x8f, 1, 1}, - {0x75, 0, 0, 0, 0}, - {0x76, 0xcc, 0xcc, 0, 0}, - {0x77, 0x1, 0x1, 0, 0}, - {0x78, 0x66, 0x66, 0, 0}, - {0x79, 0x66, 0x66, 0, 0}, - {0x7A, 0, 0, 0, 0}, - {0x7B, 0, 0, 0, 0}, - {0x7C, 0, 0, 0, 0}, - {0x7D, 0, 0, 0, 0}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0xff, 0xff, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0x93, 0, 0, 0, 0}, - {0x94, 0, 0, 0, 0}, - {0x95, 0, 0, 0, 0}, - {0x96, 0, 0, 0, 0}, - {0x97, 0, 0, 0, 0}, - {0x98, 0, 0, 0, 0}, - {0x99, 0, 0, 0, 0}, - {0x9A, 0, 0, 0, 0}, - {0x9B, 0, 0, 0, 0}, - {0x9C, 0, 0, 0, 0}, - {0x9D, 0, 0, 0, 0}, - {0x9E, 0, 0, 0, 0}, - {0x9F, 0x6, 0x6, 0, 0}, - {0xA0, 0x66, 0x66, 0, 0}, - {0xA1, 0x66, 0x66, 0, 0}, - {0xA2, 0x66, 0x66, 0, 0}, - {0xA3, 0x66, 0x66, 0, 0}, - {0xA4, 0x66, 0x66, 0, 0}, - {0xA5, 0x66, 0x66, 0, 0}, - {0xA6, 0x66, 0x66, 0, 0}, - {0xA7, 0x66, 0x66, 0, 0}, - {0xA8, 0x66, 0x66, 0, 0}, - {0xA9, 0x66, 0x66, 0, 0}, - {0xAA, 0x66, 0x66, 0, 0}, - {0xAB, 0x66, 0x66, 0, 0}, - {0xAC, 0x66, 0x66, 0, 0}, - {0xAD, 0x66, 0x66, 0, 0}, - {0xAE, 0x66, 0x66, 0, 0}, - {0xAF, 0x66, 0x66, 0, 0}, - {0xB0, 0x66, 0x66, 0, 0}, - {0xB1, 0x66, 0x66, 0, 0}, - {0xB2, 0x66, 0x66, 0, 0}, - {0xB3, 0xa, 0xa, 0, 0}, - {0xB4, 0, 0, 0, 0}, - {0xB5, 0, 0, 0, 0}, - {0xB6, 0, 0, 0, 0}, - {0xFFFF, 0, 0, 0, 0}, -}; - -radio_regs_t regs_TX_2056_rev8[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0, 0, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0, 0, 0, 0}, - {0x21, 0x88, 0x88, 0, 0}, - {0x22, 0x88, 0x88, 0, 0}, - {0x23, 0x88, 0x88, 0, 0}, - {0x24, 0x88, 0x88, 0, 0}, - {0x25, 0xc, 0xc, 0, 0}, - {0x26, 0, 0, 0, 0}, - {0x27, 0x3, 0x3, 0, 0}, - {0x28, 0, 0, 0, 0}, - {0x29, 0x3, 0x3, 0, 0}, - {0x2A, 0x37, 0x37, 0, 0}, - {0x2B, 0x3, 0x3, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0, 0, 0, 0}, - {0x2E, 0x1, 0x1, 0, 0}, - {0x2F, 0x1, 0x1, 0, 0}, - {0x30, 0, 0, 0, 0}, - {0x31, 0, 0, 0, 0}, - {0x32, 0, 0, 0, 0}, - {0x33, 0x11, 0x11, 0, 0}, - {0x34, 0xee, 0xee, 1, 1}, - {0x35, 0, 0, 0, 0}, - {0x36, 0, 0, 0, 0}, - {0x37, 0x3, 0x3, 0, 0}, - {0x38, 0x50, 0x50, 1, 1}, - {0x39, 0, 0, 0, 0}, - {0x3A, 0x50, 0x50, 1, 1}, - {0x3B, 0, 0, 0, 0}, - {0x3C, 0x6e, 0x6e, 0, 0}, - {0x3D, 0xf0, 0xf0, 1, 1}, - {0x3E, 0, 0, 0, 0}, - {0x3F, 0, 0, 0, 0}, - {0x40, 0, 0, 0, 0}, - {0x41, 0x3, 0x3, 0, 0}, - {0x42, 0x3, 0x3, 0, 0}, - {0x43, 0, 0, 0, 0}, - {0x44, 0x1e, 0x1e, 0, 0}, - {0x45, 0, 0, 0, 0}, - {0x46, 0x6e, 0x6e, 0, 0}, - {0x47, 0xf0, 0xf0, 1, 1}, - {0x48, 0, 0, 0, 0}, - {0x49, 0x2, 0x2, 0, 0}, - {0x4A, 0xff, 0xff, 1, 1}, - {0x4B, 0xc, 0xc, 0, 0}, - {0x4C, 0, 0, 0, 0}, - {0x4D, 0x38, 0x38, 0, 0}, - {0x4E, 0x70, 0x70, 1, 1}, - {0x4F, 0x2, 0x2, 0, 0}, - {0x50, 0x88, 0x88, 0, 0}, - {0x51, 0xc, 0xc, 0, 0}, - {0x52, 0, 0, 0, 0}, - {0x53, 0x8, 0x8, 0, 0}, - {0x54, 0x70, 0x70, 1, 1}, - {0x55, 0x2, 0x2, 0, 0}, - {0x56, 0xff, 0xff, 1, 1}, - {0x57, 0, 0, 0, 0}, - {0x58, 0x83, 0x83, 0, 0}, - {0x59, 0x77, 0x77, 1, 1}, - {0x5A, 0, 0, 0, 0}, - {0x5B, 0x2, 0x2, 0, 0}, - {0x5C, 0x88, 0x88, 0, 0}, - {0x5D, 0, 0, 0, 0}, - {0x5E, 0x8, 0x8, 0, 0}, - {0x5F, 0x77, 0x77, 1, 1}, - {0x60, 0x1, 0x1, 0, 0}, - {0x61, 0, 0, 0, 0}, - {0x62, 0x7, 0x7, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0x7, 0x7, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0, 0, 1, 1}, - {0x68, 0, 0, 0, 0}, - {0x69, 0xa, 0xa, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0, 0, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0, 0, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0, 0, 0, 0}, - {0x71, 0x2, 0x2, 0, 0}, - {0x72, 0, 0, 0, 0}, - {0x73, 0, 0, 0, 0}, - {0x74, 0xe, 0xe, 0, 0}, - {0x75, 0xe, 0xe, 0, 0}, - {0x76, 0xe, 0xe, 0, 0}, - {0x77, 0x13, 0x13, 0, 0}, - {0x78, 0x13, 0x13, 0, 0}, - {0x79, 0x1b, 0x1b, 0, 0}, - {0x7A, 0x1b, 0x1b, 0, 0}, - {0x7B, 0x55, 0x55, 0, 0}, - {0x7C, 0x5b, 0x5b, 0, 0}, - {0x7D, 0x30, 0x30, 1, 1}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0, 0, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0x93, 0x70, 0x70, 0, 0}, - {0x94, 0x70, 0x70, 0, 0}, - {0x95, 0x70, 0x70, 0, 0}, - {0x96, 0x70, 0x70, 0, 0}, - {0x97, 0x70, 0x70, 0, 0}, - {0x98, 0x70, 0x70, 0, 0}, - {0x99, 0x70, 0x70, 0, 0}, - {0x9A, 0x70, 0x70, 0, 0}, - {0xFFFF, 0, 0, 0, 0}, -}; - -radio_regs_t regs_RX_2056_rev8[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0, 0, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0x3, 0x3, 0, 0}, - {0x21, 0, 0, 0, 0}, - {0x22, 0, 0, 0, 0}, - {0x23, 0x90, 0x90, 0, 0}, - {0x24, 0x55, 0x55, 0, 0}, - {0x25, 0x15, 0x15, 0, 0}, - {0x26, 0x5, 0x5, 0, 0}, - {0x27, 0x15, 0x15, 0, 0}, - {0x28, 0x5, 0x5, 0, 0}, - {0x29, 0x20, 0x20, 0, 0}, - {0x2A, 0x11, 0x11, 0, 0}, - {0x2B, 0x90, 0x90, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0x88, 0x88, 0, 0}, - {0x2E, 0x32, 0x32, 0, 0}, - {0x2F, 0x77, 0x77, 0, 0}, - {0x30, 0x17, 0x17, 1, 1}, - {0x31, 0xff, 0xff, 1, 1}, - {0x32, 0x20, 0x20, 0, 0}, - {0x33, 0, 0, 0, 0}, - {0x34, 0x88, 0x88, 0, 0}, - {0x35, 0x32, 0x32, 0, 0}, - {0x36, 0x77, 0x77, 0, 0}, - {0x37, 0x17, 0x17, 1, 1}, - {0x38, 0xf0, 0xf0, 1, 1}, - {0x39, 0x20, 0x20, 0, 0}, - {0x3A, 0x8, 0x8, 0, 0}, - {0x3B, 0x55, 0x55, 1, 1}, - {0x3C, 0, 0, 0, 0}, - {0x3D, 0x88, 0x88, 1, 1}, - {0x3E, 0, 0, 0, 0}, - {0x3F, 0x44, 0x44, 0, 0}, - {0x40, 0x7, 0x7, 1, 1}, - {0x41, 0x6, 0x6, 0, 0}, - {0x42, 0x4, 0x4, 0, 0}, - {0x43, 0, 0, 0, 0}, - {0x44, 0x8, 0x8, 0, 0}, - {0x45, 0x55, 0x55, 1, 1}, - {0x46, 0, 0, 0, 0}, - {0x47, 0x11, 0x11, 0, 0}, - {0x48, 0, 0, 0, 0}, - {0x49, 0x44, 0x44, 0, 0}, - {0x4A, 0x7, 0x7, 0, 0}, - {0x4B, 0x6, 0x6, 0, 0}, - {0x4C, 0x4, 0x4, 0, 0}, - {0x4D, 0, 0, 0, 0}, - {0x4E, 0, 0, 0, 0}, - {0x4F, 0x26, 0x26, 1, 1}, - {0x50, 0x26, 0x26, 1, 1}, - {0x51, 0xf, 0xf, 1, 1}, - {0x52, 0xf, 0xf, 1, 1}, - {0x53, 0x44, 0x44, 0, 0}, - {0x54, 0, 0, 0, 0}, - {0x55, 0, 0, 0, 0}, - {0x56, 0x8, 0x8, 0, 0}, - {0x57, 0x8, 0x8, 0, 0}, - {0x58, 0x7, 0x7, 0, 0}, - {0x59, 0x22, 0x22, 0, 0}, - {0x5A, 0x22, 0x22, 0, 0}, - {0x5B, 0x2, 0x2, 0, 0}, - {0x5C, 0x4, 0x4, 1, 1}, - {0x5D, 0x7, 0x7, 0, 0}, - {0x5E, 0x55, 0x55, 0, 0}, - {0x5F, 0x23, 0x23, 0, 0}, - {0x60, 0x41, 0x41, 0, 0}, - {0x61, 0x1, 0x1, 0, 0}, - {0x62, 0xa, 0xa, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0, 0, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0, 0, 0, 0}, - {0x68, 0, 0, 0, 0}, - {0x69, 0, 0, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0xc, 0xc, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0, 0, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0, 0, 0, 0}, - {0x71, 0, 0, 0, 0}, - {0x72, 0x22, 0x22, 0, 0}, - {0x73, 0x22, 0x22, 0, 0}, - {0x74, 0, 0, 1, 1}, - {0x75, 0xa, 0xa, 0, 0}, - {0x76, 0x1, 0x1, 0, 0}, - {0x77, 0x22, 0x22, 0, 0}, - {0x78, 0x30, 0x30, 0, 0}, - {0x79, 0, 0, 0, 0}, - {0x7A, 0, 0, 0, 0}, - {0x7B, 0, 0, 0, 0}, - {0x7C, 0, 0, 0, 0}, - {0x7D, 0x5, 0x5, 1, 1}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0, 0, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0x93, 0, 0, 0, 0}, - {0x94, 0, 0, 0, 0}, - {0xFFFF, 0, 0, 0, 0}, -}; - -radio_regs_t regs_SYN_2056_rev11[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0x1, 0x1, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0, 0, 0, 0}, - {0x21, 0, 0, 0, 0}, - {0x22, 0x60, 0x60, 0, 0}, - {0x23, 0x6, 0x6, 0, 0}, - {0x24, 0xc, 0xc, 0, 0}, - {0x25, 0, 0, 0, 0}, - {0x26, 0, 0, 0, 0}, - {0x27, 0, 0, 0, 0}, - {0x28, 0x1, 0x1, 0, 0}, - {0x29, 0, 0, 0, 0}, - {0x2A, 0, 0, 0, 0}, - {0x2B, 0, 0, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0, 0, 0, 0}, - {0x2E, 0, 0, 0, 0}, - {0x2F, 0x1f, 0x1f, 0, 0}, - {0x30, 0x15, 0x15, 0, 0}, - {0x31, 0xf, 0xf, 0, 0}, - {0x32, 0, 0, 0, 0}, - {0x33, 0, 0, 0, 0}, - {0x34, 0, 0, 0, 0}, - {0x35, 0, 0, 0, 0}, - {0x36, 0, 0, 0, 0}, - {0x37, 0, 0, 0, 0}, - {0x38, 0, 0, 0, 0}, - {0x39, 0, 0, 0, 0}, - {0x3A, 0, 0, 0, 0}, - {0x3B, 0, 0, 0, 0}, - {0x3C, 0x13, 0x13, 0, 0}, - {0x3D, 0xf, 0xf, 0, 0}, - {0x3E, 0x18, 0x18, 0, 0}, - {0x3F, 0, 0, 0, 0}, - {0x40, 0, 0, 0, 0}, - {0x41, 0x20, 0x20, 0, 0}, - {0x42, 0x20, 0x20, 0, 0}, - {0x43, 0, 0, 0, 0}, - {0x44, 0x77, 0x77, 0, 0}, - {0x45, 0x7, 0x7, 0, 0}, - {0x46, 0x1, 0x1, 0, 0}, - {0x47, 0x6, 0x6, 1, 1}, - {0x48, 0xf, 0xf, 0, 0}, - {0x49, 0x3f, 0x3f, 1, 1}, - {0x4A, 0x32, 0x32, 0, 0}, - {0x4B, 0x6, 0x6, 1, 1}, - {0x4C, 0x6, 0x6, 1, 1}, - {0x4D, 0x4, 0x4, 0, 0}, - {0x4E, 0x2b, 0x2b, 1, 1}, - {0x4F, 0x1, 0x1, 0, 0}, - {0x50, 0x1c, 0x1c, 0, 0}, - {0x51, 0x2, 0x2, 0, 0}, - {0x52, 0x2, 0x2, 0, 0}, - {0x53, 0xf7, 0xf7, 1, 1}, - {0x54, 0xb4, 0xb4, 0, 0}, - {0x55, 0xd2, 0xd2, 0, 0}, - {0x56, 0, 0, 0, 0}, - {0x57, 0, 0, 0, 0}, - {0x58, 0x4, 0x4, 0, 0}, - {0x59, 0x96, 0x96, 0, 0}, - {0x5A, 0x3e, 0x3e, 0, 0}, - {0x5B, 0x3e, 0x3e, 0, 0}, - {0x5C, 0x13, 0x13, 0, 0}, - {0x5D, 0x2, 0x2, 0, 0}, - {0x5E, 0, 0, 0, 0}, - {0x5F, 0x7, 0x7, 0, 0}, - {0x60, 0x7, 0x7, 1, 1}, - {0x61, 0x8, 0x8, 0, 0}, - {0x62, 0x3, 0x3, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0, 0, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0, 0, 0, 0}, - {0x68, 0x40, 0x40, 0, 0}, - {0x69, 0, 0, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0, 0, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0x1, 0x1, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0x60, 0x60, 0, 0}, - {0x71, 0x66, 0x66, 0, 0}, - {0x72, 0xc, 0xc, 0, 0}, - {0x73, 0x66, 0x66, 0, 0}, - {0x74, 0x8f, 0x8f, 1, 1}, - {0x75, 0, 0, 0, 0}, - {0x76, 0xcc, 0xcc, 0, 0}, - {0x77, 0x1, 0x1, 0, 0}, - {0x78, 0x66, 0x66, 0, 0}, - {0x79, 0x66, 0x66, 0, 0}, - {0x7A, 0, 0, 0, 0}, - {0x7B, 0, 0, 0, 0}, - {0x7C, 0, 0, 0, 0}, - {0x7D, 0, 0, 0, 0}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0xff, 0xff, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0x93, 0, 0, 0, 0}, - {0x94, 0, 0, 0, 0}, - {0x95, 0, 0, 0, 0}, - {0x96, 0, 0, 0, 0}, - {0x97, 0, 0, 0, 0}, - {0x98, 0, 0, 0, 0}, - {0x99, 0, 0, 0, 0}, - {0x9A, 0, 0, 0, 0}, - {0x9B, 0, 0, 0, 0}, - {0x9C, 0, 0, 0, 0}, - {0x9D, 0, 0, 0, 0}, - {0x9E, 0, 0, 0, 0}, - {0x9F, 0x6, 0x6, 0, 0}, - {0xA0, 0x66, 0x66, 0, 0}, - {0xA1, 0x66, 0x66, 0, 0}, - {0xA2, 0x66, 0x66, 0, 0}, - {0xA3, 0x66, 0x66, 0, 0}, - {0xA4, 0x66, 0x66, 0, 0}, - {0xA5, 0x66, 0x66, 0, 0}, - {0xA6, 0x66, 0x66, 0, 0}, - {0xA7, 0x66, 0x66, 0, 0}, - {0xA8, 0x66, 0x66, 0, 0}, - {0xA9, 0x66, 0x66, 0, 0}, - {0xAA, 0x66, 0x66, 0, 0}, - {0xAB, 0x66, 0x66, 0, 0}, - {0xAC, 0x66, 0x66, 0, 0}, - {0xAD, 0x66, 0x66, 0, 0}, - {0xAE, 0x66, 0x66, 0, 0}, - {0xAF, 0x66, 0x66, 0, 0}, - {0xB0, 0x66, 0x66, 0, 0}, - {0xB1, 0x66, 0x66, 0, 0}, - {0xB2, 0x66, 0x66, 0, 0}, - {0xB3, 0xa, 0xa, 0, 0}, - {0xB4, 0, 0, 0, 0}, - {0xB5, 0, 0, 0, 0}, - {0xB6, 0, 0, 0, 0}, - {0xFFFF, 0, 0, 0, 0}, -}; - -radio_regs_t regs_TX_2056_rev11[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0, 0, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0, 0, 0, 0}, - {0x21, 0x88, 0x88, 0, 0}, - {0x22, 0x88, 0x88, 0, 0}, - {0x23, 0x88, 0x88, 0, 0}, - {0x24, 0x88, 0x88, 0, 0}, - {0x25, 0xc, 0xc, 0, 0}, - {0x26, 0, 0, 0, 0}, - {0x27, 0x3, 0x3, 0, 0}, - {0x28, 0, 0, 0, 0}, - {0x29, 0x3, 0x3, 0, 0}, - {0x2A, 0x37, 0x37, 0, 0}, - {0x2B, 0x3, 0x3, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0, 0, 0, 0}, - {0x2E, 0x1, 0x1, 0, 0}, - {0x2F, 0x1, 0x1, 0, 0}, - {0x30, 0, 0, 0, 0}, - {0x31, 0, 0, 0, 0}, - {0x32, 0, 0, 0, 0}, - {0x33, 0x11, 0x11, 0, 0}, - {0x34, 0xee, 0xee, 1, 1}, - {0x35, 0, 0, 0, 0}, - {0x36, 0, 0, 0, 0}, - {0x37, 0x3, 0x3, 0, 0}, - {0x38, 0x50, 0x50, 1, 1}, - {0x39, 0, 0, 0, 0}, - {0x3A, 0x50, 0x50, 1, 1}, - {0x3B, 0, 0, 0, 0}, - {0x3C, 0x6e, 0x6e, 0, 0}, - {0x3D, 0xf0, 0xf0, 1, 1}, - {0x3E, 0, 0, 0, 0}, - {0x3F, 0, 0, 0, 0}, - {0x40, 0, 0, 0, 0}, - {0x41, 0x3, 0x3, 0, 0}, - {0x42, 0x3, 0x3, 0, 0}, - {0x43, 0, 0, 0, 0}, - {0x44, 0x1e, 0x1e, 0, 0}, - {0x45, 0, 0, 0, 0}, - {0x46, 0x6e, 0x6e, 0, 0}, - {0x47, 0xf0, 0xf0, 1, 1}, - {0x48, 0, 0, 0, 0}, - {0x49, 0x2, 0x2, 0, 0}, - {0x4A, 0xff, 0xff, 1, 1}, - {0x4B, 0xc, 0xc, 0, 0}, - {0x4C, 0, 0, 0, 0}, - {0x4D, 0x38, 0x38, 0, 0}, - {0x4E, 0x70, 0x70, 1, 1}, - {0x4F, 0x2, 0x2, 0, 0}, - {0x50, 0x88, 0x88, 0, 0}, - {0x51, 0xc, 0xc, 0, 0}, - {0x52, 0, 0, 0, 0}, - {0x53, 0x8, 0x8, 0, 0}, - {0x54, 0x70, 0x70, 1, 1}, - {0x55, 0x2, 0x2, 0, 0}, - {0x56, 0xff, 0xff, 1, 1}, - {0x57, 0, 0, 0, 0}, - {0x58, 0x83, 0x83, 0, 0}, - {0x59, 0x77, 0x77, 1, 1}, - {0x5A, 0, 0, 0, 0}, - {0x5B, 0x2, 0x2, 0, 0}, - {0x5C, 0x88, 0x88, 0, 0}, - {0x5D, 0, 0, 0, 0}, - {0x5E, 0x8, 0x8, 0, 0}, - {0x5F, 0x77, 0x77, 1, 1}, - {0x60, 0x1, 0x1, 0, 0}, - {0x61, 0, 0, 0, 0}, - {0x62, 0x7, 0x7, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0x7, 0x7, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0, 0, 1, 1}, - {0x68, 0, 0, 0, 0}, - {0x69, 0xa, 0xa, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0, 0, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0, 0, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0, 0, 0, 0}, - {0x71, 0x2, 0x2, 0, 0}, - {0x72, 0, 0, 0, 0}, - {0x73, 0, 0, 0, 0}, - {0x74, 0xe, 0xe, 0, 0}, - {0x75, 0xe, 0xe, 0, 0}, - {0x76, 0xe, 0xe, 0, 0}, - {0x77, 0x13, 0x13, 0, 0}, - {0x78, 0x13, 0x13, 0, 0}, - {0x79, 0x1b, 0x1b, 0, 0}, - {0x7A, 0x1b, 0x1b, 0, 0}, - {0x7B, 0x55, 0x55, 0, 0}, - {0x7C, 0x5b, 0x5b, 0, 0}, - {0x7D, 0x30, 0x30, 1, 1}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0, 0, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0x93, 0x70, 0x70, 0, 0}, - {0x94, 0x70, 0x70, 0, 0}, - {0x95, 0x70, 0x70, 0, 0}, - {0x96, 0x70, 0x70, 0, 0}, - {0x97, 0x70, 0x70, 0, 0}, - {0x98, 0x70, 0x70, 0, 0}, - {0x99, 0x70, 0x70, 0, 0}, - {0x9A, 0x70, 0x70, 0, 0}, - {0xFFFF, 0, 0, 0, 0}, -}; - -radio_regs_t regs_RX_2056_rev11[] = { - {0x02, 0, 0, 0, 0}, - {0x03, 0, 0, 0, 0}, - {0x04, 0, 0, 0, 0}, - {0x05, 0, 0, 0, 0}, - {0x06, 0, 0, 0, 0}, - {0x07, 0, 0, 0, 0}, - {0x08, 0, 0, 0, 0}, - {0x09, 0, 0, 0, 0}, - {0x0A, 0, 0, 0, 0}, - {0x0B, 0, 0, 0, 0}, - {0x0C, 0, 0, 0, 0}, - {0x0D, 0, 0, 0, 0}, - {0x0E, 0, 0, 0, 0}, - {0x0F, 0, 0, 0, 0}, - {0x10, 0, 0, 0, 0}, - {0x11, 0, 0, 0, 0}, - {0x12, 0, 0, 0, 0}, - {0x13, 0, 0, 0, 0}, - {0x14, 0, 0, 0, 0}, - {0x15, 0, 0, 0, 0}, - {0x16, 0, 0, 0, 0}, - {0x17, 0, 0, 0, 0}, - {0x18, 0, 0, 0, 0}, - {0x19, 0, 0, 0, 0}, - {0x1A, 0, 0, 0, 0}, - {0x1B, 0, 0, 0, 0}, - {0x1C, 0, 0, 0, 0}, - {0x1D, 0, 0, 0, 0}, - {0x1E, 0, 0, 0, 0}, - {0x1F, 0, 0, 0, 0}, - {0x20, 0x3, 0x3, 0, 0}, - {0x21, 0, 0, 0, 0}, - {0x22, 0, 0, 0, 0}, - {0x23, 0x90, 0x90, 0, 0}, - {0x24, 0x55, 0x55, 0, 0}, - {0x25, 0x15, 0x15, 0, 0}, - {0x26, 0x5, 0x5, 0, 0}, - {0x27, 0x15, 0x15, 0, 0}, - {0x28, 0x5, 0x5, 0, 0}, - {0x29, 0x20, 0x20, 0, 0}, - {0x2A, 0x11, 0x11, 0, 0}, - {0x2B, 0x90, 0x90, 0, 0}, - {0x2C, 0, 0, 0, 0}, - {0x2D, 0x88, 0x88, 0, 0}, - {0x2E, 0x32, 0x32, 0, 0}, - {0x2F, 0x77, 0x77, 0, 0}, - {0x30, 0x17, 0x17, 1, 1}, - {0x31, 0xff, 0xff, 1, 1}, - {0x32, 0x20, 0x20, 0, 0}, - {0x33, 0, 0, 0, 0}, - {0x34, 0x88, 0x88, 0, 0}, - {0x35, 0x32, 0x32, 0, 0}, - {0x36, 0x77, 0x77, 0, 0}, - {0x37, 0x17, 0x17, 1, 1}, - {0x38, 0xf0, 0xf0, 1, 1}, - {0x39, 0x20, 0x20, 0, 0}, - {0x3A, 0x8, 0x8, 0, 0}, - {0x3B, 0x55, 0x55, 1, 1}, - {0x3C, 0, 0, 0, 0}, - {0x3D, 0x88, 0x88, 1, 1}, - {0x3E, 0, 0, 0, 0}, - {0x3F, 0x44, 0x44, 0, 0}, - {0x40, 0x7, 0x7, 1, 1}, - {0x41, 0x6, 0x6, 0, 0}, - {0x42, 0x4, 0x4, 0, 0}, - {0x43, 0, 0, 0, 0}, - {0x44, 0x8, 0x8, 0, 0}, - {0x45, 0x55, 0x55, 1, 1}, - {0x46, 0, 0, 0, 0}, - {0x47, 0x11, 0x11, 0, 0}, - {0x48, 0, 0, 0, 0}, - {0x49, 0x44, 0x44, 0, 0}, - {0x4A, 0x7, 0x7, 0, 0}, - {0x4B, 0x6, 0x6, 0, 0}, - {0x4C, 0x4, 0x4, 0, 0}, - {0x4D, 0, 0, 0, 0}, - {0x4E, 0, 0, 0, 0}, - {0x4F, 0x26, 0x26, 1, 1}, - {0x50, 0x26, 0x26, 1, 1}, - {0x51, 0xf, 0xf, 1, 1}, - {0x52, 0xf, 0xf, 1, 1}, - {0x53, 0x44, 0x44, 0, 0}, - {0x54, 0, 0, 0, 0}, - {0x55, 0, 0, 0, 0}, - {0x56, 0x8, 0x8, 0, 0}, - {0x57, 0x8, 0x8, 0, 0}, - {0x58, 0x7, 0x7, 0, 0}, - {0x59, 0x22, 0x22, 0, 0}, - {0x5A, 0x22, 0x22, 0, 0}, - {0x5B, 0x2, 0x2, 0, 0}, - {0x5C, 0x4, 0x4, 1, 1}, - {0x5D, 0x7, 0x7, 0, 0}, - {0x5E, 0x55, 0x55, 0, 0}, - {0x5F, 0x23, 0x23, 0, 0}, - {0x60, 0x41, 0x41, 0, 0}, - {0x61, 0x1, 0x1, 0, 0}, - {0x62, 0xa, 0xa, 0, 0}, - {0x63, 0, 0, 0, 0}, - {0x64, 0, 0, 0, 0}, - {0x65, 0, 0, 0, 0}, - {0x66, 0, 0, 0, 0}, - {0x67, 0, 0, 0, 0}, - {0x68, 0, 0, 0, 0}, - {0x69, 0, 0, 0, 0}, - {0x6A, 0, 0, 0, 0}, - {0x6B, 0xc, 0xc, 0, 0}, - {0x6C, 0, 0, 0, 0}, - {0x6D, 0, 0, 0, 0}, - {0x6E, 0, 0, 0, 0}, - {0x6F, 0, 0, 0, 0}, - {0x70, 0, 0, 0, 0}, - {0x71, 0, 0, 0, 0}, - {0x72, 0x22, 0x22, 0, 0}, - {0x73, 0x22, 0x22, 0, 0}, - {0x74, 0, 0, 1, 1}, - {0x75, 0xa, 0xa, 0, 0}, - {0x76, 0x1, 0x1, 0, 0}, - {0x77, 0x22, 0x22, 0, 0}, - {0x78, 0x30, 0x30, 0, 0}, - {0x79, 0, 0, 0, 0}, - {0x7A, 0, 0, 0, 0}, - {0x7B, 0, 0, 0, 0}, - {0x7C, 0, 0, 0, 0}, - {0x7D, 0x5, 0x5, 1, 1}, - {0x7E, 0, 0, 0, 0}, - {0x7F, 0, 0, 0, 0}, - {0x80, 0, 0, 0, 0}, - {0x81, 0, 0, 0, 0}, - {0x82, 0, 0, 0, 0}, - {0x83, 0, 0, 0, 0}, - {0x84, 0, 0, 0, 0}, - {0x85, 0, 0, 0, 0}, - {0x86, 0, 0, 0, 0}, - {0x87, 0, 0, 0, 0}, - {0x88, 0, 0, 0, 0}, - {0x89, 0, 0, 0, 0}, - {0x8A, 0, 0, 0, 0}, - {0x8B, 0, 0, 0, 0}, - {0x8C, 0, 0, 0, 0}, - {0x8D, 0, 0, 0, 0}, - {0x8E, 0, 0, 0, 0}, - {0x8F, 0, 0, 0, 0}, - {0x90, 0, 0, 0, 0}, - {0x91, 0, 0, 0, 0}, - {0x92, 0, 0, 0, 0}, - {0x93, 0, 0, 0, 0}, - {0x94, 0, 0, 0, 0}, - {0xFFFF, 0, 0, 0, 0}, -}; - -radio_20xx_regs_t regs_2057_rev4[] = { - {0x00, 0x84, 0}, - {0x01, 0, 0}, - {0x02, 0x60, 0}, - {0x03, 0x1f, 0}, - {0x04, 0x4, 0}, - {0x05, 0x2, 0}, - {0x06, 0x1, 0}, - {0x07, 0x1, 0}, - {0x08, 0x1, 0}, - {0x09, 0x69, 0}, - {0x0A, 0x66, 0}, - {0x0B, 0x6, 0}, - {0x0C, 0x18, 0}, - {0x0D, 0x3, 0}, - {0x0E, 0x20, 1}, - {0x0F, 0x20, 0}, - {0x10, 0, 0}, - {0x11, 0x7c, 0}, - {0x12, 0x42, 0}, - {0x13, 0xbd, 0}, - {0x14, 0x7, 0}, - {0x15, 0xf7, 0}, - {0x16, 0x8, 0}, - {0x17, 0x17, 0}, - {0x18, 0x7, 0}, - {0x19, 0, 0}, - {0x1A, 0x2, 0}, - {0x1B, 0x13, 0}, - {0x1C, 0x3e, 0}, - {0x1D, 0x3e, 0}, - {0x1E, 0x96, 0}, - {0x1F, 0x4, 0}, - {0x20, 0, 0}, - {0x21, 0, 0}, - {0x22, 0x17, 0}, - {0x23, 0x4, 0}, - {0x24, 0x1, 0}, - {0x25, 0x6, 0}, - {0x26, 0x4, 0}, - {0x27, 0xd, 0}, - {0x28, 0xd, 0}, - {0x29, 0x30, 0}, - {0x2A, 0x32, 0}, - {0x2B, 0x8, 0}, - {0x2C, 0x1c, 0}, - {0x2D, 0x2, 0}, - {0x2E, 0x4, 0}, - {0x2F, 0x7f, 0}, - {0x30, 0x27, 0}, - {0x31, 0, 1}, - {0x32, 0, 1}, - {0x33, 0, 1}, - {0x34, 0, 0}, - {0x35, 0x26, 1}, - {0x36, 0x18, 0}, - {0x37, 0x7, 0}, - {0x38, 0x66, 0}, - {0x39, 0x66, 0}, - {0x3A, 0x66, 0}, - {0x3B, 0x66, 0}, - {0x3C, 0xff, 1}, - {0x3D, 0xff, 1}, - {0x3E, 0xff, 1}, - {0x3F, 0xff, 1}, - {0x40, 0x16, 0}, - {0x41, 0x7, 0}, - {0x42, 0x19, 0}, - {0x43, 0x7, 0}, - {0x44, 0x6, 0}, - {0x45, 0x3, 0}, - {0x46, 0x1, 0}, - {0x47, 0x7, 0}, - {0x48, 0x33, 0}, - {0x49, 0x5, 0}, - {0x4A, 0x77, 0}, - {0x4B, 0x66, 0}, - {0x4C, 0x66, 0}, - {0x4D, 0, 0}, - {0x4E, 0x4, 0}, - {0x4F, 0xc, 0}, - {0x50, 0, 0}, - {0x51, 0x75, 0}, - {0x56, 0x7, 0}, - {0x57, 0, 0}, - {0x58, 0, 0}, - {0x59, 0xa8, 0}, - {0x5A, 0, 0}, - {0x5B, 0x1f, 0}, - {0x5C, 0x30, 0}, - {0x5D, 0x1, 0}, - {0x5E, 0x30, 0}, - {0x5F, 0x70, 0}, - {0x60, 0, 0}, - {0x61, 0, 0}, - {0x62, 0x33, 1}, - {0x63, 0x19, 0}, - {0x64, 0x62, 0}, - {0x65, 0, 0}, - {0x66, 0x11, 0}, - {0x69, 0, 0}, - {0x6A, 0x7e, 0}, - {0x6B, 0x3f, 0}, - {0x6C, 0x7f, 0}, - {0x6D, 0x78, 0}, - {0x6E, 0xc8, 0}, - {0x6F, 0x88, 0}, - {0x70, 0x8, 0}, - {0x71, 0xf, 0}, - {0x72, 0xbc, 0}, - {0x73, 0x8, 0}, - {0x74, 0x60, 0}, - {0x75, 0x1e, 0}, - {0x76, 0x70, 0}, - {0x77, 0, 0}, - {0x78, 0, 0}, - {0x79, 0, 0}, - {0x7A, 0x33, 0}, - {0x7B, 0x1e, 0}, - {0x7C, 0x62, 0}, - {0x7D, 0x11, 0}, - {0x80, 0x3c, 0}, - {0x81, 0x9c, 0}, - {0x82, 0xa, 0}, - {0x83, 0x9d, 0}, - {0x84, 0xa, 0}, - {0x85, 0, 0}, - {0x86, 0x40, 0}, - {0x87, 0x40, 0}, - {0x88, 0x88, 0}, - {0x89, 0x10, 0}, - {0x8A, 0xf0, 1}, - {0x8B, 0x10, 1}, - {0x8C, 0xf0, 1}, - {0x8D, 0, 0}, - {0x8E, 0, 0}, - {0x8F, 0x10, 0}, - {0x90, 0x55, 0}, - {0x91, 0x3f, 1}, - {0x92, 0x36, 1}, - {0x93, 0, 0}, - {0x94, 0, 0}, - {0x95, 0, 0}, - {0x96, 0x87, 0}, - {0x97, 0x11, 0}, - {0x98, 0, 0}, - {0x99, 0x33, 0}, - {0x9A, 0x88, 0}, - {0x9B, 0, 0}, - {0x9C, 0x87, 0}, - {0x9D, 0x11, 0}, - {0x9E, 0, 0}, - {0x9F, 0x33, 0}, - {0xA0, 0x88, 0}, - {0xA1, 0xe1, 0}, - {0xA2, 0x3f, 0}, - {0xA3, 0x44, 0}, - {0xA4, 0x8c, 1}, - {0xA5, 0x6d, 0}, - {0xA6, 0x22, 0}, - {0xA7, 0xbe, 0}, - {0xA8, 0x55, 1}, - {0xA9, 0xc, 0}, - {0xAA, 0xc, 0}, - {0xAB, 0xaa, 0}, - {0xAC, 0x2, 0}, - {0xAD, 0, 0}, - {0xAE, 0x10, 0}, - {0xAF, 0x1, 1}, - {0xB0, 0, 0}, - {0xB1, 0, 0}, - {0xB2, 0x80, 0}, - {0xB3, 0x60, 0}, - {0xB4, 0x44, 0}, - {0xB5, 0x55, 0}, - {0xB6, 0x1, 0}, - {0xB7, 0x55, 0}, - {0xB8, 0x1, 0}, - {0xB9, 0x5, 0}, - {0xBA, 0x55, 0}, - {0xBB, 0x55, 0}, - {0xC1, 0, 0}, - {0xC2, 0, 0}, - {0xC3, 0, 0}, - {0xC4, 0, 0}, - {0xC5, 0, 0}, - {0xC6, 0, 0}, - {0xC7, 0, 0}, - {0xC8, 0, 0}, - {0xC9, 0, 0}, - {0xCA, 0, 0}, - {0xCB, 0, 0}, - {0xCC, 0, 0}, - {0xCD, 0, 0}, - {0xCE, 0x5e, 0}, - {0xCF, 0xc, 0}, - {0xD0, 0xc, 0}, - {0xD1, 0xc, 0}, - {0xD2, 0, 0}, - {0xD3, 0x2b, 0}, - {0xD4, 0xc, 0}, - {0xD5, 0, 0}, - {0xD6, 0x75, 0}, - {0xDB, 0x7, 0}, - {0xDC, 0, 0}, - {0xDD, 0, 0}, - {0xDE, 0xa8, 0}, - {0xDF, 0, 0}, - {0xE0, 0x1f, 0}, - {0xE1, 0x30, 0}, - {0xE2, 0x1, 0}, - {0xE3, 0x30, 0}, - {0xE4, 0x70, 0}, - {0xE5, 0, 0}, - {0xE6, 0, 0}, - {0xE7, 0x33, 0}, - {0xE8, 0x19, 0}, - {0xE9, 0x62, 0}, - {0xEA, 0, 0}, - {0xEB, 0x11, 0}, - {0xEE, 0, 0}, - {0xEF, 0x7e, 0}, - {0xF0, 0x3f, 0}, - {0xF1, 0x7f, 0}, - {0xF2, 0x78, 0}, - {0xF3, 0xc8, 0}, - {0xF4, 0x88, 0}, - {0xF5, 0x8, 0}, - {0xF6, 0xf, 0}, - {0xF7, 0xbc, 0}, - {0xF8, 0x8, 0}, - {0xF9, 0x60, 0}, - {0xFA, 0x1e, 0}, - {0xFB, 0x70, 0}, - {0xFC, 0, 0}, - {0xFD, 0, 0}, - {0xFE, 0, 0}, - {0xFF, 0x33, 0}, - {0x100, 0x1e, 0}, - {0x101, 0x62, 0}, - {0x102, 0x11, 0}, - {0x105, 0x3c, 0}, - {0x106, 0x9c, 0}, - {0x107, 0xa, 0}, - {0x108, 0x9d, 0}, - {0x109, 0xa, 0}, - {0x10A, 0, 0}, - {0x10B, 0x40, 0}, - {0x10C, 0x40, 0}, - {0x10D, 0x88, 0}, - {0x10E, 0x10, 0}, - {0x10F, 0xf0, 1}, - {0x110, 0x10, 1}, - {0x111, 0xf0, 1}, - {0x112, 0, 0}, - {0x113, 0, 0}, - {0x114, 0x10, 0}, - {0x115, 0x55, 0}, - {0x116, 0x3f, 1}, - {0x117, 0x36, 1}, - {0x118, 0, 0}, - {0x119, 0, 0}, - {0x11A, 0, 0}, - {0x11B, 0x87, 0}, - {0x11C, 0x11, 0}, - {0x11D, 0, 0}, - {0x11E, 0x33, 0}, - {0x11F, 0x88, 0}, - {0x120, 0, 0}, - {0x121, 0x87, 0}, - {0x122, 0x11, 0}, - {0x123, 0, 0}, - {0x124, 0x33, 0}, - {0x125, 0x88, 0}, - {0x126, 0xe1, 0}, - {0x127, 0x3f, 0}, - {0x128, 0x44, 0}, - {0x129, 0x8c, 1}, - {0x12A, 0x6d, 0}, - {0x12B, 0x22, 0}, - {0x12C, 0xbe, 0}, - {0x12D, 0x55, 1}, - {0x12E, 0xc, 0}, - {0x12F, 0xc, 0}, - {0x130, 0xaa, 0}, - {0x131, 0x2, 0}, - {0x132, 0, 0}, - {0x133, 0x10, 0}, - {0x134, 0x1, 1}, - {0x135, 0, 0}, - {0x136, 0, 0}, - {0x137, 0x80, 0}, - {0x138, 0x60, 0}, - {0x139, 0x44, 0}, - {0x13A, 0x55, 0}, - {0x13B, 0x1, 0}, - {0x13C, 0x55, 0}, - {0x13D, 0x1, 0}, - {0x13E, 0x5, 0}, - {0x13F, 0x55, 0}, - {0x140, 0x55, 0}, - {0x146, 0, 0}, - {0x147, 0, 0}, - {0x148, 0, 0}, - {0x149, 0, 0}, - {0x14A, 0, 0}, - {0x14B, 0, 0}, - {0x14C, 0, 0}, - {0x14D, 0, 0}, - {0x14E, 0, 0}, - {0x14F, 0, 0}, - {0x150, 0, 0}, - {0x151, 0, 0}, - {0x152, 0, 0}, - {0x153, 0, 0}, - {0x154, 0xc, 0}, - {0x155, 0xc, 0}, - {0x156, 0xc, 0}, - {0x157, 0, 0}, - {0x158, 0x2b, 0}, - {0x159, 0x84, 0}, - {0x15A, 0x15, 0}, - {0x15B, 0xf, 0}, - {0x15C, 0, 0}, - {0x15D, 0, 0}, - {0x15E, 0, 1}, - {0x15F, 0, 1}, - {0x160, 0, 1}, - {0x161, 0, 1}, - {0x162, 0, 1}, - {0x163, 0, 1}, - {0x164, 0, 0}, - {0x165, 0, 0}, - {0x166, 0, 0}, - {0x167, 0, 0}, - {0x168, 0, 0}, - {0x169, 0x2, 1}, - {0x16A, 0, 1}, - {0x16B, 0, 1}, - {0x16C, 0, 1}, - {0x16D, 0, 0}, - {0x170, 0, 0}, - {0x171, 0x77, 0}, - {0x172, 0x77, 0}, - {0x173, 0x77, 0}, - {0x174, 0x77, 0}, - {0x175, 0, 0}, - {0x176, 0x3, 0}, - {0x177, 0x37, 0}, - {0x178, 0x3, 0}, - {0x179, 0, 0}, - {0x17A, 0x21, 0}, - {0x17B, 0x21, 0}, - {0x17C, 0, 0}, - {0x17D, 0xaa, 0}, - {0x17E, 0, 0}, - {0x17F, 0xaa, 0}, - {0x180, 0, 0}, - {0x190, 0, 0}, - {0x191, 0x77, 0}, - {0x192, 0x77, 0}, - {0x193, 0x77, 0}, - {0x194, 0x77, 0}, - {0x195, 0, 0}, - {0x196, 0x3, 0}, - {0x197, 0x37, 0}, - {0x198, 0x3, 0}, - {0x199, 0, 0}, - {0x19A, 0x21, 0}, - {0x19B, 0x21, 0}, - {0x19C, 0, 0}, - {0x19D, 0xaa, 0}, - {0x19E, 0, 0}, - {0x19F, 0xaa, 0}, - {0x1A0, 0, 0}, - {0x1A1, 0x2, 0}, - {0x1A2, 0xf, 0}, - {0x1A3, 0xf, 0}, - {0x1A4, 0, 1}, - {0x1A5, 0, 1}, - {0x1A6, 0, 1}, - {0x1A7, 0x2, 0}, - {0x1A8, 0xf, 0}, - {0x1A9, 0xf, 0}, - {0x1AA, 0, 1}, - {0x1AB, 0, 1}, - {0x1AC, 0, 1}, - {0xFFFF, 0, 0}, -}; - -radio_20xx_regs_t regs_2057_rev5[] = { - {0x00, 0, 1}, - {0x01, 0x57, 1}, - {0x02, 0x20, 1}, - {0x03, 0x1f, 0}, - {0x04, 0x4, 0}, - {0x05, 0x2, 0}, - {0x06, 0x1, 0}, - {0x07, 0x1, 0}, - {0x08, 0x1, 0}, - {0x09, 0x69, 0}, - {0x0A, 0x66, 0}, - {0x0B, 0x6, 0}, - {0x0C, 0x18, 0}, - {0x0D, 0x3, 0}, - {0x0E, 0x20, 0}, - {0x0F, 0x20, 0}, - {0x10, 0, 0}, - {0x11, 0x7c, 0}, - {0x12, 0x42, 0}, - {0x13, 0xbd, 0}, - {0x14, 0x7, 0}, - {0x15, 0x87, 0}, - {0x16, 0x8, 0}, - {0x17, 0x17, 0}, - {0x18, 0x7, 0}, - {0x19, 0, 0}, - {0x1A, 0x2, 0}, - {0x1B, 0x13, 0}, - {0x1C, 0x3e, 0}, - {0x1D, 0x3e, 0}, - {0x1E, 0x96, 0}, - {0x1F, 0x4, 0}, - {0x20, 0, 0}, - {0x21, 0, 0}, - {0x22, 0x17, 0}, - {0x23, 0x6, 1}, - {0x24, 0x1, 0}, - {0x25, 0x6, 0}, - {0x26, 0x4, 0}, - {0x27, 0xd, 0}, - {0x28, 0xd, 0}, - {0x29, 0x30, 0}, - {0x2A, 0x32, 0}, - {0x2B, 0x8, 0}, - {0x2C, 0x1c, 0}, - {0x2D, 0x2, 0}, - {0x2E, 0x4, 0}, - {0x2F, 0x7f, 0}, - {0x30, 0x27, 0}, - {0x31, 0, 1}, - {0x32, 0, 1}, - {0x33, 0, 1}, - {0x34, 0, 0}, - {0x35, 0x20, 0}, - {0x36, 0x18, 0}, - {0x37, 0x7, 0}, - {0x38, 0x66, 0}, - {0x39, 0x66, 0}, - {0x3C, 0xff, 0}, - {0x3D, 0xff, 0}, - {0x40, 0x16, 0}, - {0x41, 0x7, 0}, - {0x45, 0x3, 0}, - {0x46, 0x1, 0}, - {0x47, 0x7, 0}, - {0x4B, 0x66, 0}, - {0x4C, 0x66, 0}, - {0x4D, 0, 0}, - {0x4E, 0x4, 0}, - {0x4F, 0xc, 0}, - {0x50, 0, 0}, - {0x51, 0x70, 1}, - {0x56, 0x7, 0}, - {0x57, 0, 0}, - {0x58, 0, 0}, - {0x59, 0x88, 1}, - {0x5A, 0, 0}, - {0x5B, 0x1f, 0}, - {0x5C, 0x20, 1}, - {0x5D, 0x1, 0}, - {0x5E, 0x30, 0}, - {0x5F, 0x70, 0}, - {0x60, 0, 0}, - {0x61, 0, 0}, - {0x62, 0x33, 1}, - {0x63, 0xf, 1}, - {0x64, 0xf, 1}, - {0x65, 0, 0}, - {0x66, 0x11, 0}, - {0x80, 0x3c, 0}, - {0x81, 0x1, 1}, - {0x82, 0xa, 0}, - {0x85, 0, 0}, - {0x86, 0x40, 0}, - {0x87, 0x40, 0}, - {0x88, 0x88, 0}, - {0x89, 0x10, 0}, - {0x8A, 0xf0, 0}, - {0x8B, 0x10, 0}, - {0x8C, 0xf0, 0}, - {0x8F, 0x10, 0}, - {0x90, 0x55, 0}, - {0x91, 0x3f, 1}, - {0x92, 0x36, 1}, - {0x93, 0, 0}, - {0x94, 0, 0}, - {0x95, 0, 0}, - {0x96, 0x87, 0}, - {0x97, 0x11, 0}, - {0x98, 0, 0}, - {0x99, 0x33, 0}, - {0x9A, 0x88, 0}, - {0xA1, 0x20, 1}, - {0xA2, 0x3f, 0}, - {0xA3, 0x44, 0}, - {0xA4, 0x8c, 0}, - {0xA5, 0x6c, 0}, - {0xA6, 0x22, 0}, - {0xA7, 0xbe, 0}, - {0xA8, 0x55, 0}, - {0xAA, 0xc, 0}, - {0xAB, 0xaa, 0}, - {0xAC, 0x2, 0}, - {0xAD, 0, 0}, - {0xAE, 0x10, 0}, - {0xAF, 0x1, 0}, - {0xB0, 0, 0}, - {0xB1, 0, 0}, - {0xB2, 0x80, 0}, - {0xB3, 0x60, 0}, - {0xB4, 0x44, 0}, - {0xB5, 0x55, 0}, - {0xB6, 0x1, 0}, - {0xB7, 0x55, 0}, - {0xB8, 0x1, 0}, - {0xB9, 0x5, 0}, - {0xBA, 0x55, 0}, - {0xBB, 0x55, 0}, - {0xC3, 0, 0}, - {0xC4, 0, 0}, - {0xC5, 0, 0}, - {0xC6, 0, 0}, - {0xC7, 0, 0}, - {0xC8, 0, 0}, - {0xC9, 0, 0}, - {0xCA, 0, 0}, - {0xCB, 0, 0}, - {0xCD, 0, 0}, - {0xCE, 0x5e, 0}, - {0xCF, 0xc, 0}, - {0xD0, 0xc, 0}, - {0xD1, 0xc, 0}, - {0xD2, 0, 0}, - {0xD3, 0x2b, 0}, - {0xD4, 0xc, 0}, - {0xD5, 0, 0}, - {0xD6, 0x70, 1}, - {0xDB, 0x7, 0}, - {0xDC, 0, 0}, - {0xDD, 0, 0}, - {0xDE, 0x88, 1}, - {0xDF, 0, 0}, - {0xE0, 0x1f, 0}, - {0xE1, 0x20, 1}, - {0xE2, 0x1, 0}, - {0xE3, 0x30, 0}, - {0xE4, 0x70, 0}, - {0xE5, 0, 0}, - {0xE6, 0, 0}, - {0xE7, 0x33, 0}, - {0xE8, 0xf, 1}, - {0xE9, 0xf, 1}, - {0xEA, 0, 0}, - {0xEB, 0x11, 0}, - {0x105, 0x3c, 0}, - {0x106, 0x1, 1}, - {0x107, 0xa, 0}, - {0x10A, 0, 0}, - {0x10B, 0x40, 0}, - {0x10C, 0x40, 0}, - {0x10D, 0x88, 0}, - {0x10E, 0x10, 0}, - {0x10F, 0xf0, 0}, - {0x110, 0x10, 0}, - {0x111, 0xf0, 0}, - {0x114, 0x10, 0}, - {0x115, 0x55, 0}, - {0x116, 0x3f, 1}, - {0x117, 0x36, 1}, - {0x118, 0, 0}, - {0x119, 0, 0}, - {0x11A, 0, 0}, - {0x11B, 0x87, 0}, - {0x11C, 0x11, 0}, - {0x11D, 0, 0}, - {0x11E, 0x33, 0}, - {0x11F, 0x88, 0}, - {0x126, 0x20, 1}, - {0x127, 0x3f, 0}, - {0x128, 0x44, 0}, - {0x129, 0x8c, 0}, - {0x12A, 0x6c, 0}, - {0x12B, 0x22, 0}, - {0x12C, 0xbe, 0}, - {0x12D, 0x55, 0}, - {0x12F, 0xc, 0}, - {0x130, 0xaa, 0}, - {0x131, 0x2, 0}, - {0x132, 0, 0}, - {0x133, 0x10, 0}, - {0x134, 0x1, 0}, - {0x135, 0, 0}, - {0x136, 0, 0}, - {0x137, 0x80, 0}, - {0x138, 0x60, 0}, - {0x139, 0x44, 0}, - {0x13A, 0x55, 0}, - {0x13B, 0x1, 0}, - {0x13C, 0x55, 0}, - {0x13D, 0x1, 0}, - {0x13E, 0x5, 0}, - {0x13F, 0x55, 0}, - {0x140, 0x55, 0}, - {0x148, 0, 0}, - {0x149, 0, 0}, - {0x14A, 0, 0}, - {0x14B, 0, 0}, - {0x14C, 0, 0}, - {0x14D, 0, 0}, - {0x14E, 0, 0}, - {0x14F, 0, 0}, - {0x150, 0, 0}, - {0x154, 0xc, 0}, - {0x155, 0xc, 0}, - {0x156, 0xc, 0}, - {0x157, 0, 0}, - {0x158, 0x2b, 0}, - {0x159, 0x84, 0}, - {0x15A, 0x15, 0}, - {0x15B, 0xf, 0}, - {0x15C, 0, 0}, - {0x15D, 0, 0}, - {0x15E, 0, 1}, - {0x15F, 0, 1}, - {0x160, 0, 1}, - {0x161, 0, 1}, - {0x162, 0, 1}, - {0x163, 0, 1}, - {0x164, 0, 0}, - {0x165, 0, 0}, - {0x166, 0, 0}, - {0x167, 0, 0}, - {0x168, 0, 0}, - {0x169, 0, 0}, - {0x16A, 0, 1}, - {0x16B, 0, 1}, - {0x16C, 0, 1}, - {0x16D, 0, 0}, - {0x170, 0, 0}, - {0x171, 0x77, 0}, - {0x172, 0x77, 0}, - {0x173, 0x77, 0}, - {0x174, 0x77, 0}, - {0x175, 0, 0}, - {0x176, 0x3, 0}, - {0x177, 0x37, 0}, - {0x178, 0x3, 0}, - {0x179, 0, 0}, - {0x17B, 0x21, 0}, - {0x17C, 0, 0}, - {0x17D, 0xaa, 0}, - {0x17E, 0, 0}, - {0x190, 0, 0}, - {0x191, 0x77, 0}, - {0x192, 0x77, 0}, - {0x193, 0x77, 0}, - {0x194, 0x77, 0}, - {0x195, 0, 0}, - {0x196, 0x3, 0}, - {0x197, 0x37, 0}, - {0x198, 0x3, 0}, - {0x199, 0, 0}, - {0x19B, 0x21, 0}, - {0x19C, 0, 0}, - {0x19D, 0xaa, 0}, - {0x19E, 0, 0}, - {0x1A1, 0x2, 0}, - {0x1A2, 0xf, 0}, - {0x1A3, 0xf, 0}, - {0x1A4, 0, 1}, - {0x1A5, 0, 1}, - {0x1A6, 0, 1}, - {0x1A7, 0x2, 0}, - {0x1A8, 0xf, 0}, - {0x1A9, 0xf, 0}, - {0x1AA, 0, 1}, - {0x1AB, 0, 1}, - {0x1AC, 0, 1}, - {0x1AD, 0x84, 0}, - {0x1AE, 0x60, 0}, - {0x1AF, 0x47, 0}, - {0x1B0, 0x47, 0}, - {0x1B1, 0, 0}, - {0x1B2, 0, 0}, - {0x1B3, 0, 0}, - {0x1B4, 0, 0}, - {0x1B5, 0, 0}, - {0x1B6, 0, 0}, - {0x1B7, 0xc, 1}, - {0x1B8, 0, 0}, - {0x1B9, 0, 0}, - {0x1BA, 0, 0}, - {0x1BB, 0, 0}, - {0x1BC, 0, 0}, - {0x1BD, 0, 0}, - {0x1BE, 0, 0}, - {0x1BF, 0, 0}, - {0x1C0, 0, 0}, - {0x1C1, 0x1, 1}, - {0x1C2, 0x80, 1}, - {0x1C3, 0, 0}, - {0x1C4, 0, 0}, - {0x1C5, 0, 0}, - {0x1C6, 0, 0}, - {0x1C7, 0, 0}, - {0x1C8, 0, 0}, - {0x1C9, 0, 0}, - {0x1CA, 0, 0}, - {0xFFFF, 0, 0} -}; - -radio_20xx_regs_t regs_2057_rev5v1[] = { - {0x00, 0x15, 1}, - {0x01, 0x57, 1}, - {0x02, 0x20, 1}, - {0x03, 0x1f, 0}, - {0x04, 0x4, 0}, - {0x05, 0x2, 0}, - {0x06, 0x1, 0}, - {0x07, 0x1, 0}, - {0x08, 0x1, 0}, - {0x09, 0x69, 0}, - {0x0A, 0x66, 0}, - {0x0B, 0x6, 0}, - {0x0C, 0x18, 0}, - {0x0D, 0x3, 0}, - {0x0E, 0x20, 0}, - {0x0F, 0x20, 0}, - {0x10, 0, 0}, - {0x11, 0x7c, 0}, - {0x12, 0x42, 0}, - {0x13, 0xbd, 0}, - {0x14, 0x7, 0}, - {0x15, 0x87, 0}, - {0x16, 0x8, 0}, - {0x17, 0x17, 0}, - {0x18, 0x7, 0}, - {0x19, 0, 0}, - {0x1A, 0x2, 0}, - {0x1B, 0x13, 0}, - {0x1C, 0x3e, 0}, - {0x1D, 0x3e, 0}, - {0x1E, 0x96, 0}, - {0x1F, 0x4, 0}, - {0x20, 0, 0}, - {0x21, 0, 0}, - {0x22, 0x17, 0}, - {0x23, 0x6, 1}, - {0x24, 0x1, 0}, - {0x25, 0x6, 0}, - {0x26, 0x4, 0}, - {0x27, 0xd, 0}, - {0x28, 0xd, 0}, - {0x29, 0x30, 0}, - {0x2A, 0x32, 0}, - {0x2B, 0x8, 0}, - {0x2C, 0x1c, 0}, - {0x2D, 0x2, 0}, - {0x2E, 0x4, 0}, - {0x2F, 0x7f, 0}, - {0x30, 0x27, 0}, - {0x31, 0, 1}, - {0x32, 0, 1}, - {0x33, 0, 1}, - {0x34, 0, 0}, - {0x35, 0x20, 0}, - {0x36, 0x18, 0}, - {0x37, 0x7, 0}, - {0x38, 0x66, 0}, - {0x39, 0x66, 0}, - {0x3C, 0xff, 0}, - {0x3D, 0xff, 0}, - {0x40, 0x16, 0}, - {0x41, 0x7, 0}, - {0x45, 0x3, 0}, - {0x46, 0x1, 0}, - {0x47, 0x7, 0}, - {0x4B, 0x66, 0}, - {0x4C, 0x66, 0}, - {0x4D, 0, 0}, - {0x4E, 0x4, 0}, - {0x4F, 0xc, 0}, - {0x50, 0, 0}, - {0x51, 0x70, 1}, - {0x56, 0x7, 0}, - {0x57, 0, 0}, - {0x58, 0, 0}, - {0x59, 0x88, 1}, - {0x5A, 0, 0}, - {0x5B, 0x1f, 0}, - {0x5C, 0x20, 1}, - {0x5D, 0x1, 0}, - {0x5E, 0x30, 0}, - {0x5F, 0x70, 0}, - {0x60, 0, 0}, - {0x61, 0, 0}, - {0x62, 0x33, 1}, - {0x63, 0xf, 1}, - {0x64, 0xf, 1}, - {0x65, 0, 0}, - {0x66, 0x11, 0}, - {0x80, 0x3c, 0}, - {0x81, 0x1, 1}, - {0x82, 0xa, 0}, - {0x85, 0, 0}, - {0x86, 0x40, 0}, - {0x87, 0x40, 0}, - {0x88, 0x88, 0}, - {0x89, 0x10, 0}, - {0x8A, 0xf0, 0}, - {0x8B, 0x10, 0}, - {0x8C, 0xf0, 0}, - {0x8F, 0x10, 0}, - {0x90, 0x55, 0}, - {0x91, 0x3f, 1}, - {0x92, 0x36, 1}, - {0x93, 0, 0}, - {0x94, 0, 0}, - {0x95, 0, 0}, - {0x96, 0x87, 0}, - {0x97, 0x11, 0}, - {0x98, 0, 0}, - {0x99, 0x33, 0}, - {0x9A, 0x88, 0}, - {0xA1, 0x20, 1}, - {0xA2, 0x3f, 0}, - {0xA3, 0x44, 0}, - {0xA4, 0x8c, 0}, - {0xA5, 0x6c, 0}, - {0xA6, 0x22, 0}, - {0xA7, 0xbe, 0}, - {0xA8, 0x55, 0}, - {0xAA, 0xc, 0}, - {0xAB, 0xaa, 0}, - {0xAC, 0x2, 0}, - {0xAD, 0, 0}, - {0xAE, 0x10, 0}, - {0xAF, 0x1, 0}, - {0xB0, 0, 0}, - {0xB1, 0, 0}, - {0xB2, 0x80, 0}, - {0xB3, 0x60, 0}, - {0xB4, 0x44, 0}, - {0xB5, 0x55, 0}, - {0xB6, 0x1, 0}, - {0xB7, 0x55, 0}, - {0xB8, 0x1, 0}, - {0xB9, 0x5, 0}, - {0xBA, 0x55, 0}, - {0xBB, 0x55, 0}, - {0xC3, 0, 0}, - {0xC4, 0, 0}, - {0xC5, 0, 0}, - {0xC6, 0, 0}, - {0xC7, 0, 0}, - {0xC8, 0, 0}, - {0xC9, 0x1, 1}, - {0xCA, 0, 0}, - {0xCB, 0, 0}, - {0xCD, 0, 0}, - {0xCE, 0x5e, 0}, - {0xCF, 0xc, 0}, - {0xD0, 0xc, 0}, - {0xD1, 0xc, 0}, - {0xD2, 0, 0}, - {0xD3, 0x2b, 0}, - {0xD4, 0xc, 0}, - {0xD5, 0, 0}, - {0xD6, 0x70, 1}, - {0xDB, 0x7, 0}, - {0xDC, 0, 0}, - {0xDD, 0, 0}, - {0xDE, 0x88, 1}, - {0xDF, 0, 0}, - {0xE0, 0x1f, 0}, - {0xE1, 0x20, 1}, - {0xE2, 0x1, 0}, - {0xE3, 0x30, 0}, - {0xE4, 0x70, 0}, - {0xE5, 0, 0}, - {0xE6, 0, 0}, - {0xE7, 0x33, 0}, - {0xE8, 0xf, 1}, - {0xE9, 0xf, 1}, - {0xEA, 0, 0}, - {0xEB, 0x11, 0}, - {0x105, 0x3c, 0}, - {0x106, 0x1, 1}, - {0x107, 0xa, 0}, - {0x10A, 0, 0}, - {0x10B, 0x40, 0}, - {0x10C, 0x40, 0}, - {0x10D, 0x88, 0}, - {0x10E, 0x10, 0}, - {0x10F, 0xf0, 0}, - {0x110, 0x10, 0}, - {0x111, 0xf0, 0}, - {0x114, 0x10, 0}, - {0x115, 0x55, 0}, - {0x116, 0x3f, 1}, - {0x117, 0x36, 1}, - {0x118, 0, 0}, - {0x119, 0, 0}, - {0x11A, 0, 0}, - {0x11B, 0x87, 0}, - {0x11C, 0x11, 0}, - {0x11D, 0, 0}, - {0x11E, 0x33, 0}, - {0x11F, 0x88, 0}, - {0x126, 0x20, 1}, - {0x127, 0x3f, 0}, - {0x128, 0x44, 0}, - {0x129, 0x8c, 0}, - {0x12A, 0x6c, 0}, - {0x12B, 0x22, 0}, - {0x12C, 0xbe, 0}, - {0x12D, 0x55, 0}, - {0x12F, 0xc, 0}, - {0x130, 0xaa, 0}, - {0x131, 0x2, 0}, - {0x132, 0, 0}, - {0x133, 0x10, 0}, - {0x134, 0x1, 0}, - {0x135, 0, 0}, - {0x136, 0, 0}, - {0x137, 0x80, 0}, - {0x138, 0x60, 0}, - {0x139, 0x44, 0}, - {0x13A, 0x55, 0}, - {0x13B, 0x1, 0}, - {0x13C, 0x55, 0}, - {0x13D, 0x1, 0}, - {0x13E, 0x5, 0}, - {0x13F, 0x55, 0}, - {0x140, 0x55, 0}, - {0x148, 0, 0}, - {0x149, 0, 0}, - {0x14A, 0, 0}, - {0x14B, 0, 0}, - {0x14C, 0, 0}, - {0x14D, 0, 0}, - {0x14E, 0x1, 1}, - {0x14F, 0, 0}, - {0x150, 0, 0}, - {0x154, 0xc, 0}, - {0x155, 0xc, 0}, - {0x156, 0xc, 0}, - {0x157, 0, 0}, - {0x158, 0x2b, 0}, - {0x159, 0x84, 0}, - {0x15A, 0x15, 0}, - {0x15B, 0xf, 0}, - {0x15C, 0, 0}, - {0x15D, 0, 0}, - {0x15E, 0, 1}, - {0x15F, 0, 1}, - {0x160, 0, 1}, - {0x161, 0, 1}, - {0x162, 0, 1}, - {0x163, 0, 1}, - {0x164, 0, 0}, - {0x165, 0, 0}, - {0x166, 0, 0}, - {0x167, 0, 0}, - {0x168, 0, 0}, - {0x169, 0, 0}, - {0x16A, 0, 1}, - {0x16B, 0, 1}, - {0x16C, 0, 1}, - {0x16D, 0, 0}, - {0x170, 0, 0}, - {0x171, 0x77, 0}, - {0x172, 0x77, 0}, - {0x173, 0x77, 0}, - {0x174, 0x77, 0}, - {0x175, 0, 0}, - {0x176, 0x3, 0}, - {0x177, 0x37, 0}, - {0x178, 0x3, 0}, - {0x179, 0, 0}, - {0x17B, 0x21, 0}, - {0x17C, 0, 0}, - {0x17D, 0xaa, 0}, - {0x17E, 0, 0}, - {0x190, 0, 0}, - {0x191, 0x77, 0}, - {0x192, 0x77, 0}, - {0x193, 0x77, 0}, - {0x194, 0x77, 0}, - {0x195, 0, 0}, - {0x196, 0x3, 0}, - {0x197, 0x37, 0}, - {0x198, 0x3, 0}, - {0x199, 0, 0}, - {0x19B, 0x21, 0}, - {0x19C, 0, 0}, - {0x19D, 0xaa, 0}, - {0x19E, 0, 0}, - {0x1A1, 0x2, 0}, - {0x1A2, 0xf, 0}, - {0x1A3, 0xf, 0}, - {0x1A4, 0, 1}, - {0x1A5, 0, 1}, - {0x1A6, 0, 1}, - {0x1A7, 0x2, 0}, - {0x1A8, 0xf, 0}, - {0x1A9, 0xf, 0}, - {0x1AA, 0, 1}, - {0x1AB, 0, 1}, - {0x1AC, 0, 1}, - {0x1AD, 0x84, 0}, - {0x1AE, 0x60, 0}, - {0x1AF, 0x47, 0}, - {0x1B0, 0x47, 0}, - {0x1B1, 0, 0}, - {0x1B2, 0, 0}, - {0x1B3, 0, 0}, - {0x1B4, 0, 0}, - {0x1B5, 0, 0}, - {0x1B6, 0, 0}, - {0x1B7, 0xc, 1}, - {0x1B8, 0, 0}, - {0x1B9, 0, 0}, - {0x1BA, 0, 0}, - {0x1BB, 0, 0}, - {0x1BC, 0, 0}, - {0x1BD, 0, 0}, - {0x1BE, 0, 0}, - {0x1BF, 0, 0}, - {0x1C0, 0, 0}, - {0x1C1, 0x1, 1}, - {0x1C2, 0x80, 1}, - {0x1C3, 0, 0}, - {0x1C4, 0, 0}, - {0x1C5, 0, 0}, - {0x1C6, 0, 0}, - {0x1C7, 0, 0}, - {0x1C8, 0, 0}, - {0x1C9, 0, 0}, - {0x1CA, 0, 0}, - {0xFFFF, 0, 0} -}; - -radio_20xx_regs_t regs_2057_rev7[] = { - {0x00, 0, 1}, - {0x01, 0x57, 1}, - {0x02, 0x20, 1}, - {0x03, 0x1f, 0}, - {0x04, 0x4, 0}, - {0x05, 0x2, 0}, - {0x06, 0x1, 0}, - {0x07, 0x1, 0}, - {0x08, 0x1, 0}, - {0x09, 0x69, 0}, - {0x0A, 0x66, 0}, - {0x0B, 0x6, 0}, - {0x0C, 0x18, 0}, - {0x0D, 0x3, 0}, - {0x0E, 0x20, 0}, - {0x0F, 0x20, 0}, - {0x10, 0, 0}, - {0x11, 0x7c, 0}, - {0x12, 0x42, 0}, - {0x13, 0xbd, 0}, - {0x14, 0x7, 0}, - {0x15, 0x87, 0}, - {0x16, 0x8, 0}, - {0x17, 0x17, 0}, - {0x18, 0x7, 0}, - {0x19, 0, 0}, - {0x1A, 0x2, 0}, - {0x1B, 0x13, 0}, - {0x1C, 0x3e, 0}, - {0x1D, 0x3e, 0}, - {0x1E, 0x96, 0}, - {0x1F, 0x4, 0}, - {0x20, 0, 0}, - {0x21, 0, 0}, - {0x22, 0x17, 0}, - {0x23, 0x6, 0}, - {0x24, 0x1, 0}, - {0x25, 0x6, 0}, - {0x26, 0x4, 0}, - {0x27, 0xd, 0}, - {0x28, 0xd, 0}, - {0x29, 0x30, 0}, - {0x2A, 0x32, 0}, - {0x2B, 0x8, 0}, - {0x2C, 0x1c, 0}, - {0x2D, 0x2, 0}, - {0x2E, 0x4, 0}, - {0x2F, 0x7f, 0}, - {0x30, 0x27, 0}, - {0x31, 0, 1}, - {0x32, 0, 1}, - {0x33, 0, 1}, - {0x34, 0, 0}, - {0x35, 0x20, 0}, - {0x36, 0x18, 0}, - {0x37, 0x7, 0}, - {0x38, 0x66, 0}, - {0x39, 0x66, 0}, - {0x3A, 0x66, 0}, - {0x3B, 0x66, 0}, - {0x3C, 0xff, 0}, - {0x3D, 0xff, 0}, - {0x3E, 0xff, 0}, - {0x3F, 0xff, 0}, - {0x40, 0x16, 0}, - {0x41, 0x7, 0}, - {0x42, 0x19, 0}, - {0x43, 0x7, 0}, - {0x44, 0x6, 0}, - {0x45, 0x3, 0}, - {0x46, 0x1, 0}, - {0x47, 0x7, 0}, - {0x48, 0x33, 0}, - {0x49, 0x5, 0}, - {0x4A, 0x77, 0}, - {0x4B, 0x66, 0}, - {0x4C, 0x66, 0}, - {0x4D, 0, 0}, - {0x4E, 0x4, 0}, - {0x4F, 0xc, 0}, - {0x50, 0, 0}, - {0x51, 0x70, 1}, - {0x56, 0x7, 0}, - {0x57, 0, 0}, - {0x58, 0, 0}, - {0x59, 0x88, 1}, - {0x5A, 0, 0}, - {0x5B, 0x1f, 0}, - {0x5C, 0x20, 1}, - {0x5D, 0x1, 0}, - {0x5E, 0x30, 0}, - {0x5F, 0x70, 0}, - {0x60, 0, 0}, - {0x61, 0, 0}, - {0x62, 0x33, 1}, - {0x63, 0xf, 1}, - {0x64, 0x13, 1}, - {0x65, 0, 0}, - {0x66, 0xee, 1}, - {0x69, 0, 0}, - {0x6A, 0x7e, 0}, - {0x6B, 0x3f, 0}, - {0x6C, 0x7f, 0}, - {0x6D, 0x78, 0}, - {0x6E, 0x58, 1}, - {0x6F, 0x88, 0}, - {0x70, 0x8, 0}, - {0x71, 0xf, 0}, - {0x72, 0xbc, 0}, - {0x73, 0x8, 0}, - {0x74, 0x60, 0}, - {0x75, 0x13, 1}, - {0x76, 0x70, 0}, - {0x77, 0, 0}, - {0x78, 0, 0}, - {0x79, 0, 0}, - {0x7A, 0x33, 0}, - {0x7B, 0x13, 1}, - {0x7C, 0x14, 1}, - {0x7D, 0xee, 1}, - {0x80, 0x3c, 0}, - {0x81, 0x1, 1}, - {0x82, 0xa, 0}, - {0x83, 0x9d, 0}, - {0x84, 0xa, 0}, - {0x85, 0, 0}, - {0x86, 0x40, 0}, - {0x87, 0x40, 0}, - {0x88, 0x88, 0}, - {0x89, 0x10, 0}, - {0x8A, 0xf0, 0}, - {0x8B, 0x10, 0}, - {0x8C, 0xf0, 0}, - {0x8D, 0, 0}, - {0x8E, 0, 0}, - {0x8F, 0x10, 0}, - {0x90, 0x55, 0}, - {0x91, 0x3f, 1}, - {0x92, 0x36, 1}, - {0x93, 0, 0}, - {0x94, 0, 0}, - {0x95, 0, 0}, - {0x96, 0x87, 0}, - {0x97, 0x11, 0}, - {0x98, 0, 0}, - {0x99, 0x33, 0}, - {0x9A, 0x88, 0}, - {0x9B, 0, 0}, - {0x9C, 0x87, 0}, - {0x9D, 0x11, 0}, - {0x9E, 0, 0}, - {0x9F, 0x33, 0}, - {0xA0, 0x88, 0}, - {0xA1, 0x20, 1}, - {0xA2, 0x3f, 0}, - {0xA3, 0x44, 0}, - {0xA4, 0x8c, 0}, - {0xA5, 0x6c, 0}, - {0xA6, 0x22, 0}, - {0xA7, 0xbe, 0}, - {0xA8, 0x55, 0}, - {0xAA, 0xc, 0}, - {0xAB, 0xaa, 0}, - {0xAC, 0x2, 0}, - {0xAD, 0, 0}, - {0xAE, 0x10, 0}, - {0xAF, 0x1, 0}, - {0xB0, 0, 0}, - {0xB1, 0, 0}, - {0xB2, 0x80, 0}, - {0xB3, 0x60, 0}, - {0xB4, 0x44, 0}, - {0xB5, 0x55, 0}, - {0xB6, 0x1, 0}, - {0xB7, 0x55, 0}, - {0xB8, 0x1, 0}, - {0xB9, 0x5, 0}, - {0xBA, 0x55, 0}, - {0xBB, 0x55, 0}, - {0xC1, 0, 0}, - {0xC2, 0, 0}, - {0xC3, 0, 0}, - {0xC4, 0, 0}, - {0xC5, 0, 0}, - {0xC6, 0, 0}, - {0xC7, 0, 0}, - {0xC8, 0, 0}, - {0xC9, 0, 0}, - {0xCA, 0, 0}, - {0xCB, 0, 0}, - {0xCC, 0, 0}, - {0xCD, 0, 0}, - {0xCE, 0x5e, 0}, - {0xCF, 0xc, 0}, - {0xD0, 0xc, 0}, - {0xD1, 0xc, 0}, - {0xD2, 0, 0}, - {0xD3, 0x2b, 0}, - {0xD4, 0xc, 0}, - {0xD5, 0, 0}, - {0xD6, 0x70, 1}, - {0xDB, 0x7, 0}, - {0xDC, 0, 0}, - {0xDD, 0, 0}, - {0xDE, 0x88, 1}, - {0xDF, 0, 0}, - {0xE0, 0x1f, 0}, - {0xE1, 0x20, 1}, - {0xE2, 0x1, 0}, - {0xE3, 0x30, 0}, - {0xE4, 0x70, 0}, - {0xE5, 0, 0}, - {0xE6, 0, 0}, - {0xE7, 0x33, 0}, - {0xE8, 0xf, 1}, - {0xE9, 0x13, 1}, - {0xEA, 0, 0}, - {0xEB, 0xee, 1}, - {0xEE, 0, 0}, - {0xEF, 0x7e, 0}, - {0xF0, 0x3f, 0}, - {0xF1, 0x7f, 0}, - {0xF2, 0x78, 0}, - {0xF3, 0x58, 1}, - {0xF4, 0x88, 0}, - {0xF5, 0x8, 0}, - {0xF6, 0xf, 0}, - {0xF7, 0xbc, 0}, - {0xF8, 0x8, 0}, - {0xF9, 0x60, 0}, - {0xFA, 0x13, 1}, - {0xFB, 0x70, 0}, - {0xFC, 0, 0}, - {0xFD, 0, 0}, - {0xFE, 0, 0}, - {0xFF, 0x33, 0}, - {0x100, 0x13, 1}, - {0x101, 0x14, 1}, - {0x102, 0xee, 1}, - {0x105, 0x3c, 0}, - {0x106, 0x1, 1}, - {0x107, 0xa, 0}, - {0x108, 0x9d, 0}, - {0x109, 0xa, 0}, - {0x10A, 0, 0}, - {0x10B, 0x40, 0}, - {0x10C, 0x40, 0}, - {0x10D, 0x88, 0}, - {0x10E, 0x10, 0}, - {0x10F, 0xf0, 0}, - {0x110, 0x10, 0}, - {0x111, 0xf0, 0}, - {0x112, 0, 0}, - {0x113, 0, 0}, - {0x114, 0x10, 0}, - {0x115, 0x55, 0}, - {0x116, 0x3f, 1}, - {0x117, 0x36, 1}, - {0x118, 0, 0}, - {0x119, 0, 0}, - {0x11A, 0, 0}, - {0x11B, 0x87, 0}, - {0x11C, 0x11, 0}, - {0x11D, 0, 0}, - {0x11E, 0x33, 0}, - {0x11F, 0x88, 0}, - {0x120, 0, 0}, - {0x121, 0x87, 0}, - {0x122, 0x11, 0}, - {0x123, 0, 0}, - {0x124, 0x33, 0}, - {0x125, 0x88, 0}, - {0x126, 0x20, 1}, - {0x127, 0x3f, 0}, - {0x128, 0x44, 0}, - {0x129, 0x8c, 0}, - {0x12A, 0x6c, 0}, - {0x12B, 0x22, 0}, - {0x12C, 0xbe, 0}, - {0x12D, 0x55, 0}, - {0x12F, 0xc, 0}, - {0x130, 0xaa, 0}, - {0x131, 0x2, 0}, - {0x132, 0, 0}, - {0x133, 0x10, 0}, - {0x134, 0x1, 0}, - {0x135, 0, 0}, - {0x136, 0, 0}, - {0x137, 0x80, 0}, - {0x138, 0x60, 0}, - {0x139, 0x44, 0}, - {0x13A, 0x55, 0}, - {0x13B, 0x1, 0}, - {0x13C, 0x55, 0}, - {0x13D, 0x1, 0}, - {0x13E, 0x5, 0}, - {0x13F, 0x55, 0}, - {0x140, 0x55, 0}, - {0x146, 0, 0}, - {0x147, 0, 0}, - {0x148, 0, 0}, - {0x149, 0, 0}, - {0x14A, 0, 0}, - {0x14B, 0, 0}, - {0x14C, 0, 0}, - {0x14D, 0, 0}, - {0x14E, 0, 0}, - {0x14F, 0, 0}, - {0x150, 0, 0}, - {0x151, 0, 0}, - {0x154, 0xc, 0}, - {0x155, 0xc, 0}, - {0x156, 0xc, 0}, - {0x157, 0, 0}, - {0x158, 0x2b, 0}, - {0x159, 0x84, 0}, - {0x15A, 0x15, 0}, - {0x15B, 0xf, 0}, - {0x15C, 0, 0}, - {0x15D, 0, 0}, - {0x15E, 0, 1}, - {0x15F, 0, 1}, - {0x160, 0, 1}, - {0x161, 0, 1}, - {0x162, 0, 1}, - {0x163, 0, 1}, - {0x164, 0, 0}, - {0x165, 0, 0}, - {0x166, 0, 0}, - {0x167, 0, 0}, - {0x168, 0, 0}, - {0x169, 0, 0}, - {0x16A, 0, 1}, - {0x16B, 0, 1}, - {0x16C, 0, 1}, - {0x16D, 0, 0}, - {0x170, 0, 0}, - {0x171, 0x77, 0}, - {0x172, 0x77, 0}, - {0x173, 0x77, 0}, - {0x174, 0x77, 0}, - {0x175, 0, 0}, - {0x176, 0x3, 0}, - {0x177, 0x37, 0}, - {0x178, 0x3, 0}, - {0x179, 0, 0}, - {0x17A, 0x21, 0}, - {0x17B, 0x21, 0}, - {0x17C, 0, 0}, - {0x17D, 0xaa, 0}, - {0x17E, 0, 0}, - {0x17F, 0xaa, 0}, - {0x180, 0, 0}, - {0x190, 0, 0}, - {0x191, 0x77, 0}, - {0x192, 0x77, 0}, - {0x193, 0x77, 0}, - {0x194, 0x77, 0}, - {0x195, 0, 0}, - {0x196, 0x3, 0}, - {0x197, 0x37, 0}, - {0x198, 0x3, 0}, - {0x199, 0, 0}, - {0x19A, 0x21, 0}, - {0x19B, 0x21, 0}, - {0x19C, 0, 0}, - {0x19D, 0xaa, 0}, - {0x19E, 0, 0}, - {0x19F, 0xaa, 0}, - {0x1A0, 0, 0}, - {0x1A1, 0x2, 0}, - {0x1A2, 0xf, 0}, - {0x1A3, 0xf, 0}, - {0x1A4, 0, 1}, - {0x1A5, 0, 1}, - {0x1A6, 0, 1}, - {0x1A7, 0x2, 0}, - {0x1A8, 0xf, 0}, - {0x1A9, 0xf, 0}, - {0x1AA, 0, 1}, - {0x1AB, 0, 1}, - {0x1AC, 0, 1}, - {0x1AD, 0x84, 0}, - {0x1AE, 0x60, 0}, - {0x1AF, 0x47, 0}, - {0x1B0, 0x47, 0}, - {0x1B1, 0, 0}, - {0x1B2, 0, 0}, - {0x1B3, 0, 0}, - {0x1B4, 0, 0}, - {0x1B5, 0, 0}, - {0x1B6, 0, 0}, - {0x1B7, 0x5, 1}, - {0x1B8, 0, 0}, - {0x1B9, 0, 0}, - {0x1BA, 0, 0}, - {0x1BB, 0, 0}, - {0x1BC, 0, 0}, - {0x1BD, 0, 0}, - {0x1BE, 0, 0}, - {0x1BF, 0, 0}, - {0x1C0, 0, 0}, - {0x1C1, 0, 0}, - {0x1C2, 0xa0, 1}, - {0x1C3, 0, 0}, - {0x1C4, 0, 0}, - {0x1C5, 0, 0}, - {0x1C6, 0, 0}, - {0x1C7, 0, 0}, - {0x1C8, 0, 0}, - {0x1C9, 0, 0}, - {0x1CA, 0, 0}, - {0xFFFF, 0, 0} -}; - -radio_20xx_regs_t regs_2057_rev8[] = { - {0x00, 0x8, 1}, - {0x01, 0x57, 1}, - {0x02, 0x20, 1}, - {0x03, 0x1f, 0}, - {0x04, 0x4, 0}, - {0x05, 0x2, 0}, - {0x06, 0x1, 0}, - {0x07, 0x1, 0}, - {0x08, 0x1, 0}, - {0x09, 0x69, 0}, - {0x0A, 0x66, 0}, - {0x0B, 0x6, 0}, - {0x0C, 0x18, 0}, - {0x0D, 0x3, 0}, - {0x0E, 0x20, 0}, - {0x0F, 0x20, 0}, - {0x10, 0, 0}, - {0x11, 0x7c, 0}, - {0x12, 0x42, 0}, - {0x13, 0xbd, 0}, - {0x14, 0x7, 0}, - {0x15, 0x87, 0}, - {0x16, 0x8, 0}, - {0x17, 0x17, 0}, - {0x18, 0x7, 0}, - {0x19, 0, 0}, - {0x1A, 0x2, 0}, - {0x1B, 0x13, 0}, - {0x1C, 0x3e, 0}, - {0x1D, 0x3e, 0}, - {0x1E, 0x96, 0}, - {0x1F, 0x4, 0}, - {0x20, 0, 0}, - {0x21, 0, 0}, - {0x22, 0x17, 0}, - {0x23, 0x6, 0}, - {0x24, 0x1, 0}, - {0x25, 0x6, 0}, - {0x26, 0x4, 0}, - {0x27, 0xd, 0}, - {0x28, 0xd, 0}, - {0x29, 0x30, 0}, - {0x2A, 0x32, 0}, - {0x2B, 0x8, 0}, - {0x2C, 0x1c, 0}, - {0x2D, 0x2, 0}, - {0x2E, 0x4, 0}, - {0x2F, 0x7f, 0}, - {0x30, 0x27, 0}, - {0x31, 0, 1}, - {0x32, 0, 1}, - {0x33, 0, 1}, - {0x34, 0, 0}, - {0x35, 0x20, 0}, - {0x36, 0x18, 0}, - {0x37, 0x7, 0}, - {0x38, 0x66, 0}, - {0x39, 0x66, 0}, - {0x3A, 0x66, 0}, - {0x3B, 0x66, 0}, - {0x3C, 0xff, 0}, - {0x3D, 0xff, 0}, - {0x3E, 0xff, 0}, - {0x3F, 0xff, 0}, - {0x40, 0x16, 0}, - {0x41, 0x7, 0}, - {0x42, 0x19, 0}, - {0x43, 0x7, 0}, - {0x44, 0x6, 0}, - {0x45, 0x3, 0}, - {0x46, 0x1, 0}, - {0x47, 0x7, 0}, - {0x48, 0x33, 0}, - {0x49, 0x5, 0}, - {0x4A, 0x77, 0}, - {0x4B, 0x66, 0}, - {0x4C, 0x66, 0}, - {0x4D, 0, 0}, - {0x4E, 0x4, 0}, - {0x4F, 0xc, 0}, - {0x50, 0, 0}, - {0x51, 0x70, 1}, - {0x56, 0x7, 0}, - {0x57, 0, 0}, - {0x58, 0, 0}, - {0x59, 0x88, 1}, - {0x5A, 0, 0}, - {0x5B, 0x1f, 0}, - {0x5C, 0x20, 1}, - {0x5D, 0x1, 0}, - {0x5E, 0x30, 0}, - {0x5F, 0x70, 0}, - {0x60, 0, 0}, - {0x61, 0, 0}, - {0x62, 0x33, 1}, - {0x63, 0xf, 1}, - {0x64, 0xf, 1}, - {0x65, 0, 0}, - {0x66, 0x11, 0}, - {0x69, 0, 0}, - {0x6A, 0x7e, 0}, - {0x6B, 0x3f, 0}, - {0x6C, 0x7f, 0}, - {0x6D, 0x78, 0}, - {0x6E, 0x58, 1}, - {0x6F, 0x88, 0}, - {0x70, 0x8, 0}, - {0x71, 0xf, 0}, - {0x72, 0xbc, 0}, - {0x73, 0x8, 0}, - {0x74, 0x60, 0}, - {0x75, 0x13, 1}, - {0x76, 0x70, 0}, - {0x77, 0, 0}, - {0x78, 0, 0}, - {0x79, 0, 0}, - {0x7A, 0x33, 0}, - {0x7B, 0x13, 1}, - {0x7C, 0xf, 1}, - {0x7D, 0xee, 1}, - {0x80, 0x3c, 0}, - {0x81, 0x1, 1}, - {0x82, 0xa, 0}, - {0x83, 0x9d, 0}, - {0x84, 0xa, 0}, - {0x85, 0, 0}, - {0x86, 0x40, 0}, - {0x87, 0x40, 0}, - {0x88, 0x88, 0}, - {0x89, 0x10, 0}, - {0x8A, 0xf0, 0}, - {0x8B, 0x10, 0}, - {0x8C, 0xf0, 0}, - {0x8D, 0, 0}, - {0x8E, 0, 0}, - {0x8F, 0x10, 0}, - {0x90, 0x55, 0}, - {0x91, 0x3f, 1}, - {0x92, 0x36, 1}, - {0x93, 0, 0}, - {0x94, 0, 0}, - {0x95, 0, 0}, - {0x96, 0x87, 0}, - {0x97, 0x11, 0}, - {0x98, 0, 0}, - {0x99, 0x33, 0}, - {0x9A, 0x88, 0}, - {0x9B, 0, 0}, - {0x9C, 0x87, 0}, - {0x9D, 0x11, 0}, - {0x9E, 0, 0}, - {0x9F, 0x33, 0}, - {0xA0, 0x88, 0}, - {0xA1, 0x20, 1}, - {0xA2, 0x3f, 0}, - {0xA3, 0x44, 0}, - {0xA4, 0x8c, 0}, - {0xA5, 0x6c, 0}, - {0xA6, 0x22, 0}, - {0xA7, 0xbe, 0}, - {0xA8, 0x55, 0}, - {0xAA, 0xc, 0}, - {0xAB, 0xaa, 0}, - {0xAC, 0x2, 0}, - {0xAD, 0, 0}, - {0xAE, 0x10, 0}, - {0xAF, 0x1, 0}, - {0xB0, 0, 0}, - {0xB1, 0, 0}, - {0xB2, 0x80, 0}, - {0xB3, 0x60, 0}, - {0xB4, 0x44, 0}, - {0xB5, 0x55, 0}, - {0xB6, 0x1, 0}, - {0xB7, 0x55, 0}, - {0xB8, 0x1, 0}, - {0xB9, 0x5, 0}, - {0xBA, 0x55, 0}, - {0xBB, 0x55, 0}, - {0xC1, 0, 0}, - {0xC2, 0, 0}, - {0xC3, 0, 0}, - {0xC4, 0, 0}, - {0xC5, 0, 0}, - {0xC6, 0, 0}, - {0xC7, 0, 0}, - {0xC8, 0, 0}, - {0xC9, 0x1, 1}, - {0xCA, 0, 0}, - {0xCB, 0, 0}, - {0xCC, 0, 0}, - {0xCD, 0, 0}, - {0xCE, 0x5e, 0}, - {0xCF, 0xc, 0}, - {0xD0, 0xc, 0}, - {0xD1, 0xc, 0}, - {0xD2, 0, 0}, - {0xD3, 0x2b, 0}, - {0xD4, 0xc, 0}, - {0xD5, 0, 0}, - {0xD6, 0x70, 1}, - {0xDB, 0x7, 0}, - {0xDC, 0, 0}, - {0xDD, 0, 0}, - {0xDE, 0x88, 1}, - {0xDF, 0, 0}, - {0xE0, 0x1f, 0}, - {0xE1, 0x20, 1}, - {0xE2, 0x1, 0}, - {0xE3, 0x30, 0}, - {0xE4, 0x70, 0}, - {0xE5, 0, 0}, - {0xE6, 0, 0}, - {0xE7, 0x33, 0}, - {0xE8, 0xf, 1}, - {0xE9, 0xf, 1}, - {0xEA, 0, 0}, - {0xEB, 0x11, 0}, - {0xEE, 0, 0}, - {0xEF, 0x7e, 0}, - {0xF0, 0x3f, 0}, - {0xF1, 0x7f, 0}, - {0xF2, 0x78, 0}, - {0xF3, 0x58, 1}, - {0xF4, 0x88, 0}, - {0xF5, 0x8, 0}, - {0xF6, 0xf, 0}, - {0xF7, 0xbc, 0}, - {0xF8, 0x8, 0}, - {0xF9, 0x60, 0}, - {0xFA, 0x13, 1}, - {0xFB, 0x70, 0}, - {0xFC, 0, 0}, - {0xFD, 0, 0}, - {0xFE, 0, 0}, - {0xFF, 0x33, 0}, - {0x100, 0x13, 1}, - {0x101, 0xf, 1}, - {0x102, 0xee, 1}, - {0x105, 0x3c, 0}, - {0x106, 0x1, 1}, - {0x107, 0xa, 0}, - {0x108, 0x9d, 0}, - {0x109, 0xa, 0}, - {0x10A, 0, 0}, - {0x10B, 0x40, 0}, - {0x10C, 0x40, 0}, - {0x10D, 0x88, 0}, - {0x10E, 0x10, 0}, - {0x10F, 0xf0, 0}, - {0x110, 0x10, 0}, - {0x111, 0xf0, 0}, - {0x112, 0, 0}, - {0x113, 0, 0}, - {0x114, 0x10, 0}, - {0x115, 0x55, 0}, - {0x116, 0x3f, 1}, - {0x117, 0x36, 1}, - {0x118, 0, 0}, - {0x119, 0, 0}, - {0x11A, 0, 0}, - {0x11B, 0x87, 0}, - {0x11C, 0x11, 0}, - {0x11D, 0, 0}, - {0x11E, 0x33, 0}, - {0x11F, 0x88, 0}, - {0x120, 0, 0}, - {0x121, 0x87, 0}, - {0x122, 0x11, 0}, - {0x123, 0, 0}, - {0x124, 0x33, 0}, - {0x125, 0x88, 0}, - {0x126, 0x20, 1}, - {0x127, 0x3f, 0}, - {0x128, 0x44, 0}, - {0x129, 0x8c, 0}, - {0x12A, 0x6c, 0}, - {0x12B, 0x22, 0}, - {0x12C, 0xbe, 0}, - {0x12D, 0x55, 0}, - {0x12F, 0xc, 0}, - {0x130, 0xaa, 0}, - {0x131, 0x2, 0}, - {0x132, 0, 0}, - {0x133, 0x10, 0}, - {0x134, 0x1, 0}, - {0x135, 0, 0}, - {0x136, 0, 0}, - {0x137, 0x80, 0}, - {0x138, 0x60, 0}, - {0x139, 0x44, 0}, - {0x13A, 0x55, 0}, - {0x13B, 0x1, 0}, - {0x13C, 0x55, 0}, - {0x13D, 0x1, 0}, - {0x13E, 0x5, 0}, - {0x13F, 0x55, 0}, - {0x140, 0x55, 0}, - {0x146, 0, 0}, - {0x147, 0, 0}, - {0x148, 0, 0}, - {0x149, 0, 0}, - {0x14A, 0, 0}, - {0x14B, 0, 0}, - {0x14C, 0, 0}, - {0x14D, 0, 0}, - {0x14E, 0x1, 1}, - {0x14F, 0, 0}, - {0x150, 0, 0}, - {0x151, 0, 0}, - {0x154, 0xc, 0}, - {0x155, 0xc, 0}, - {0x156, 0xc, 0}, - {0x157, 0, 0}, - {0x158, 0x2b, 0}, - {0x159, 0x84, 0}, - {0x15A, 0x15, 0}, - {0x15B, 0xf, 0}, - {0x15C, 0, 0}, - {0x15D, 0, 0}, - {0x15E, 0, 1}, - {0x15F, 0, 1}, - {0x160, 0, 1}, - {0x161, 0, 1}, - {0x162, 0, 1}, - {0x163, 0, 1}, - {0x164, 0, 0}, - {0x165, 0, 0}, - {0x166, 0, 0}, - {0x167, 0, 0}, - {0x168, 0, 0}, - {0x169, 0, 0}, - {0x16A, 0, 1}, - {0x16B, 0, 1}, - {0x16C, 0, 1}, - {0x16D, 0, 0}, - {0x170, 0, 0}, - {0x171, 0x77, 0}, - {0x172, 0x77, 0}, - {0x173, 0x77, 0}, - {0x174, 0x77, 0}, - {0x175, 0, 0}, - {0x176, 0x3, 0}, - {0x177, 0x37, 0}, - {0x178, 0x3, 0}, - {0x179, 0, 0}, - {0x17A, 0x21, 0}, - {0x17B, 0x21, 0}, - {0x17C, 0, 0}, - {0x17D, 0xaa, 0}, - {0x17E, 0, 0}, - {0x17F, 0xaa, 0}, - {0x180, 0, 0}, - {0x190, 0, 0}, - {0x191, 0x77, 0}, - {0x192, 0x77, 0}, - {0x193, 0x77, 0}, - {0x194, 0x77, 0}, - {0x195, 0, 0}, - {0x196, 0x3, 0}, - {0x197, 0x37, 0}, - {0x198, 0x3, 0}, - {0x199, 0, 0}, - {0x19A, 0x21, 0}, - {0x19B, 0x21, 0}, - {0x19C, 0, 0}, - {0x19D, 0xaa, 0}, - {0x19E, 0, 0}, - {0x19F, 0xaa, 0}, - {0x1A0, 0, 0}, - {0x1A1, 0x2, 0}, - {0x1A2, 0xf, 0}, - {0x1A3, 0xf, 0}, - {0x1A4, 0, 1}, - {0x1A5, 0, 1}, - {0x1A6, 0, 1}, - {0x1A7, 0x2, 0}, - {0x1A8, 0xf, 0}, - {0x1A9, 0xf, 0}, - {0x1AA, 0, 1}, - {0x1AB, 0, 1}, - {0x1AC, 0, 1}, - {0x1AD, 0x84, 0}, - {0x1AE, 0x60, 0}, - {0x1AF, 0x47, 0}, - {0x1B0, 0x47, 0}, - {0x1B1, 0, 0}, - {0x1B2, 0, 0}, - {0x1B3, 0, 0}, - {0x1B4, 0, 0}, - {0x1B5, 0, 0}, - {0x1B6, 0, 0}, - {0x1B7, 0x5, 1}, - {0x1B8, 0, 0}, - {0x1B9, 0, 0}, - {0x1BA, 0, 0}, - {0x1BB, 0, 0}, - {0x1BC, 0, 0}, - {0x1BD, 0, 0}, - {0x1BE, 0, 0}, - {0x1BF, 0, 0}, - {0x1C0, 0, 0}, - {0x1C1, 0, 0}, - {0x1C2, 0xa0, 1}, - {0x1C3, 0, 0}, - {0x1C4, 0, 0}, - {0x1C5, 0, 0}, - {0x1C6, 0, 0}, - {0x1C7, 0, 0}, - {0x1C8, 0, 0}, - {0x1C9, 0, 0}, - {0x1CA, 0, 0}, - {0xFFFF, 0, 0} -}; - -static s16 nphy_def_lnagains[] = { -2, 10, 19, 25 }; - -static s32 nphy_lnagain_est0[] = { -315, 40370 }; -static s32 nphy_lnagain_est1[] = { -224, 23242 }; - -static const u16 tbl_iqcal_gainparams_nphy[2][NPHY_IQCAL_NUMGAINS][8] = { - { - {0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69}, - {0x700, 7, 0, 0, 0x69, 0x69, 0x69, 0x69}, - {0x710, 7, 1, 0, 0x68, 0x68, 0x68, 0x68}, - {0x720, 7, 2, 0, 0x67, 0x67, 0x67, 0x67}, - {0x730, 7, 3, 0, 0x66, 0x66, 0x66, 0x66}, - {0x740, 7, 4, 0, 0x65, 0x65, 0x65, 0x65}, - {0x741, 7, 4, 1, 0x65, 0x65, 0x65, 0x65}, - {0x742, 7, 4, 2, 0x65, 0x65, 0x65, 0x65}, - {0x743, 7, 4, 3, 0x65, 0x65, 0x65, 0x65} - }, - { - {0x000, 7, 0, 0, 0x79, 0x79, 0x79, 0x79}, - {0x700, 7, 0, 0, 0x79, 0x79, 0x79, 0x79}, - {0x710, 7, 1, 0, 0x79, 0x79, 0x79, 0x79}, - {0x720, 7, 2, 0, 0x78, 0x78, 0x78, 0x78}, - {0x730, 7, 3, 0, 0x78, 0x78, 0x78, 0x78}, - {0x740, 7, 4, 0, 0x78, 0x78, 0x78, 0x78}, - {0x741, 7, 4, 1, 0x78, 0x78, 0x78, 0x78}, - {0x742, 7, 4, 2, 0x78, 0x78, 0x78, 0x78}, - {0x743, 7, 4, 3, 0x78, 0x78, 0x78, 0x78} - } -}; - -static const u32 nphy_tpc_txgain[] = { - 0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42, - 0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44, - 0x03c82a42, 0x03c82944, 0x03c82942, 0x03c82844, - 0x03c82842, 0x03c42b44, 0x03c42b42, 0x03c42a44, - 0x03c42a42, 0x03c42944, 0x03c42942, 0x03c42844, - 0x03c42842, 0x03c42744, 0x03c42742, 0x03c42644, - 0x03c42642, 0x03c42544, 0x03c42542, 0x03c42444, - 0x03c42442, 0x03c02b44, 0x03c02b42, 0x03c02a44, - 0x03c02a42, 0x03c02944, 0x03c02942, 0x03c02844, - 0x03c02842, 0x03c02744, 0x03c02742, 0x03b02b44, - 0x03b02b42, 0x03b02a44, 0x03b02a42, 0x03b02944, - 0x03b02942, 0x03b02844, 0x03b02842, 0x03b02744, - 0x03b02742, 0x03b02644, 0x03b02642, 0x03b02544, - 0x03b02542, 0x03a02b44, 0x03a02b42, 0x03a02a44, - 0x03a02a42, 0x03a02944, 0x03a02942, 0x03a02844, - 0x03a02842, 0x03a02744, 0x03a02742, 0x03902b44, - 0x03902b42, 0x03902a44, 0x03902a42, 0x03902944, - 0x03902942, 0x03902844, 0x03902842, 0x03902744, - 0x03902742, 0x03902644, 0x03902642, 0x03902544, - 0x03902542, 0x03802b44, 0x03802b42, 0x03802a44, - 0x03802a42, 0x03802944, 0x03802942, 0x03802844, - 0x03802842, 0x03802744, 0x03802742, 0x03802644, - 0x03802642, 0x03802544, 0x03802542, 0x03802444, - 0x03802442, 0x03802344, 0x03802342, 0x03802244, - 0x03802242, 0x03802144, 0x03802142, 0x03802044, - 0x03802042, 0x03801f44, 0x03801f42, 0x03801e44, - 0x03801e42, 0x03801d44, 0x03801d42, 0x03801c44, - 0x03801c42, 0x03801b44, 0x03801b42, 0x03801a44, - 0x03801a42, 0x03801944, 0x03801942, 0x03801844, - 0x03801842, 0x03801744, 0x03801742, 0x03801644, - 0x03801642, 0x03801544, 0x03801542, 0x03801444, - 0x03801442, 0x03801344, 0x03801342, 0x00002b00 -}; - -static const u16 nphy_tpc_loscale[] = { - 256, 256, 271, 271, 287, 256, 256, 271, - 271, 287, 287, 304, 304, 256, 256, 271, - 271, 287, 287, 304, 304, 322, 322, 341, - 341, 362, 362, 383, 383, 256, 256, 271, - 271, 287, 287, 304, 304, 322, 322, 256, - 256, 271, 271, 287, 287, 304, 304, 322, - 322, 341, 341, 362, 362, 256, 256, 271, - 271, 287, 287, 304, 304, 322, 322, 256, - 256, 271, 271, 287, 287, 304, 304, 322, - 322, 341, 341, 362, 362, 256, 256, 271, - 271, 287, 287, 304, 304, 322, 322, 341, - 341, 362, 362, 383, 383, 406, 406, 430, - 430, 455, 455, 482, 482, 511, 511, 541, - 541, 573, 573, 607, 607, 643, 643, 681, - 681, 722, 722, 764, 764, 810, 810, 858, - 858, 908, 908, 962, 962, 1019, 1019, 256 -}; - -static u32 nphy_tpc_txgain_ipa[] = { - 0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029, - 0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025, - 0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029, - 0x5ef70028, 0x5ef70027, 0x5ef70026, 0x5ef70025, - 0x5df7002d, 0x5df7002b, 0x5df7002a, 0x5df70029, - 0x5df70028, 0x5df70027, 0x5df70026, 0x5df70025, - 0x5cf7002d, 0x5cf7002b, 0x5cf7002a, 0x5cf70029, - 0x5cf70028, 0x5cf70027, 0x5cf70026, 0x5cf70025, - 0x5bf7002d, 0x5bf7002b, 0x5bf7002a, 0x5bf70029, - 0x5bf70028, 0x5bf70027, 0x5bf70026, 0x5bf70025, - 0x5af7002d, 0x5af7002b, 0x5af7002a, 0x5af70029, - 0x5af70028, 0x5af70027, 0x5af70026, 0x5af70025, - 0x59f7002d, 0x59f7002b, 0x59f7002a, 0x59f70029, - 0x59f70028, 0x59f70027, 0x59f70026, 0x59f70025, - 0x58f7002d, 0x58f7002b, 0x58f7002a, 0x58f70029, - 0x58f70028, 0x58f70027, 0x58f70026, 0x58f70025, - 0x57f7002d, 0x57f7002b, 0x57f7002a, 0x57f70029, - 0x57f70028, 0x57f70027, 0x57f70026, 0x57f70025, - 0x56f7002d, 0x56f7002b, 0x56f7002a, 0x56f70029, - 0x56f70028, 0x56f70027, 0x56f70026, 0x56f70025, - 0x55f7002d, 0x55f7002b, 0x55f7002a, 0x55f70029, - 0x55f70028, 0x55f70027, 0x55f70026, 0x55f70025, - 0x54f7002d, 0x54f7002b, 0x54f7002a, 0x54f70029, - 0x54f70028, 0x54f70027, 0x54f70026, 0x54f70025, - 0x53f7002d, 0x53f7002b, 0x53f7002a, 0x53f70029, - 0x53f70028, 0x53f70027, 0x53f70026, 0x53f70025, - 0x52f7002d, 0x52f7002b, 0x52f7002a, 0x52f70029, - 0x52f70028, 0x52f70027, 0x52f70026, 0x52f70025, - 0x51f7002d, 0x51f7002b, 0x51f7002a, 0x51f70029, - 0x51f70028, 0x51f70027, 0x51f70026, 0x51f70025, - 0x50f7002d, 0x50f7002b, 0x50f7002a, 0x50f70029, - 0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025 -}; - -static u32 nphy_tpc_txgain_ipa_rev5[] = { - 0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029, - 0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025, - 0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029, - 0x1ef70028, 0x1ef70027, 0x1ef70026, 0x1ef70025, - 0x1df7002d, 0x1df7002b, 0x1df7002a, 0x1df70029, - 0x1df70028, 0x1df70027, 0x1df70026, 0x1df70025, - 0x1cf7002d, 0x1cf7002b, 0x1cf7002a, 0x1cf70029, - 0x1cf70028, 0x1cf70027, 0x1cf70026, 0x1cf70025, - 0x1bf7002d, 0x1bf7002b, 0x1bf7002a, 0x1bf70029, - 0x1bf70028, 0x1bf70027, 0x1bf70026, 0x1bf70025, - 0x1af7002d, 0x1af7002b, 0x1af7002a, 0x1af70029, - 0x1af70028, 0x1af70027, 0x1af70026, 0x1af70025, - 0x19f7002d, 0x19f7002b, 0x19f7002a, 0x19f70029, - 0x19f70028, 0x19f70027, 0x19f70026, 0x19f70025, - 0x18f7002d, 0x18f7002b, 0x18f7002a, 0x18f70029, - 0x18f70028, 0x18f70027, 0x18f70026, 0x18f70025, - 0x17f7002d, 0x17f7002b, 0x17f7002a, 0x17f70029, - 0x17f70028, 0x17f70027, 0x17f70026, 0x17f70025, - 0x16f7002d, 0x16f7002b, 0x16f7002a, 0x16f70029, - 0x16f70028, 0x16f70027, 0x16f70026, 0x16f70025, - 0x15f7002d, 0x15f7002b, 0x15f7002a, 0x15f70029, - 0x15f70028, 0x15f70027, 0x15f70026, 0x15f70025, - 0x14f7002d, 0x14f7002b, 0x14f7002a, 0x14f70029, - 0x14f70028, 0x14f70027, 0x14f70026, 0x14f70025, - 0x13f7002d, 0x13f7002b, 0x13f7002a, 0x13f70029, - 0x13f70028, 0x13f70027, 0x13f70026, 0x13f70025, - 0x12f7002d, 0x12f7002b, 0x12f7002a, 0x12f70029, - 0x12f70028, 0x12f70027, 0x12f70026, 0x12f70025, - 0x11f7002d, 0x11f7002b, 0x11f7002a, 0x11f70029, - 0x11f70028, 0x11f70027, 0x11f70026, 0x11f70025, - 0x10f7002d, 0x10f7002b, 0x10f7002a, 0x10f70029, - 0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025 -}; - -static u32 nphy_tpc_txgain_ipa_rev6[] = { - 0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029, - 0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025, - 0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029, - 0x0ef70028, 0x0ef70027, 0x0ef70026, 0x0ef70025, - 0x0df7002d, 0x0df7002b, 0x0df7002a, 0x0df70029, - 0x0df70028, 0x0df70027, 0x0df70026, 0x0df70025, - 0x0cf7002d, 0x0cf7002b, 0x0cf7002a, 0x0cf70029, - 0x0cf70028, 0x0cf70027, 0x0cf70026, 0x0cf70025, - 0x0bf7002d, 0x0bf7002b, 0x0bf7002a, 0x0bf70029, - 0x0bf70028, 0x0bf70027, 0x0bf70026, 0x0bf70025, - 0x0af7002d, 0x0af7002b, 0x0af7002a, 0x0af70029, - 0x0af70028, 0x0af70027, 0x0af70026, 0x0af70025, - 0x09f7002d, 0x09f7002b, 0x09f7002a, 0x09f70029, - 0x09f70028, 0x09f70027, 0x09f70026, 0x09f70025, - 0x08f7002d, 0x08f7002b, 0x08f7002a, 0x08f70029, - 0x08f70028, 0x08f70027, 0x08f70026, 0x08f70025, - 0x07f7002d, 0x07f7002b, 0x07f7002a, 0x07f70029, - 0x07f70028, 0x07f70027, 0x07f70026, 0x07f70025, - 0x06f7002d, 0x06f7002b, 0x06f7002a, 0x06f70029, - 0x06f70028, 0x06f70027, 0x06f70026, 0x06f70025, - 0x05f7002d, 0x05f7002b, 0x05f7002a, 0x05f70029, - 0x05f70028, 0x05f70027, 0x05f70026, 0x05f70025, - 0x04f7002d, 0x04f7002b, 0x04f7002a, 0x04f70029, - 0x04f70028, 0x04f70027, 0x04f70026, 0x04f70025, - 0x03f7002d, 0x03f7002b, 0x03f7002a, 0x03f70029, - 0x03f70028, 0x03f70027, 0x03f70026, 0x03f70025, - 0x02f7002d, 0x02f7002b, 0x02f7002a, 0x02f70029, - 0x02f70028, 0x02f70027, 0x02f70026, 0x02f70025, - 0x01f7002d, 0x01f7002b, 0x01f7002a, 0x01f70029, - 0x01f70028, 0x01f70027, 0x01f70026, 0x01f70025, - 0x00f7002d, 0x00f7002b, 0x00f7002a, 0x00f70029, - 0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025 -}; - -static u32 nphy_tpc_txgain_ipa_2g_2057rev3[] = { - 0x70ff0040, 0x70f7003e, 0x70ef003b, 0x70e70039, - 0x70df0037, 0x70d70036, 0x70cf0033, 0x70c70032, - 0x70bf0031, 0x70b7002f, 0x70af002e, 0x70a7002d, - 0x709f002d, 0x7097002c, 0x708f002c, 0x7087002c, - 0x707f002b, 0x7077002c, 0x706f002c, 0x7067002d, - 0x705f002e, 0x705f002b, 0x705f0029, 0x7057002a, - 0x70570028, 0x704f002a, 0x7047002c, 0x7047002a, - 0x70470028, 0x70470026, 0x70470024, 0x70470022, - 0x7047001f, 0x70370027, 0x70370024, 0x70370022, - 0x70370020, 0x7037001f, 0x7037001d, 0x7037001b, - 0x7037001a, 0x70370018, 0x70370017, 0x7027001e, - 0x7027001d, 0x7027001a, 0x701f0024, 0x701f0022, - 0x701f0020, 0x701f001f, 0x701f001d, 0x701f001b, - 0x701f001a, 0x701f0018, 0x701f0017, 0x701f0015, - 0x701f0014, 0x701f0013, 0x701f0012, 0x701f0011, - 0x70170019, 0x70170018, 0x70170016, 0x70170015, - 0x70170014, 0x70170013, 0x70170012, 0x70170010, - 0x70170010, 0x7017000f, 0x700f001d, 0x700f001b, - 0x700f001a, 0x700f0018, 0x700f0017, 0x700f0015, - 0x700f0015, 0x700f0013, 0x700f0013, 0x700f0011, - 0x700f0010, 0x700f0010, 0x700f000f, 0x700f000e, - 0x700f000d, 0x700f000c, 0x700f000b, 0x700f000b, - 0x700f000b, 0x700f000a, 0x700f0009, 0x700f0009, - 0x700f0009, 0x700f0008, 0x700f0007, 0x700f0007, - 0x700f0006, 0x700f0006, 0x700f0006, 0x700f0006, - 0x700f0005, 0x700f0005, 0x700f0005, 0x700f0004, - 0x700f0004, 0x700f0004, 0x700f0004, 0x700f0004, - 0x700f0004, 0x700f0003, 0x700f0003, 0x700f0003, - 0x700f0003, 0x700f0002, 0x700f0002, 0x700f0002, - 0x700f0002, 0x700f0002, 0x700f0002, 0x700f0001, - 0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001, - 0x700f0001, 0x700f0001, 0x700f0001, 0x700f0001 -}; - -static u32 nphy_tpc_txgain_ipa_2g_2057rev4n6[] = { - 0xf0ff0040, 0xf0f7003e, 0xf0ef003b, 0xf0e70039, - 0xf0df0037, 0xf0d70036, 0xf0cf0033, 0xf0c70032, - 0xf0bf0031, 0xf0b7002f, 0xf0af002e, 0xf0a7002d, - 0xf09f002d, 0xf097002c, 0xf08f002c, 0xf087002c, - 0xf07f002b, 0xf077002c, 0xf06f002c, 0xf067002d, - 0xf05f002e, 0xf05f002b, 0xf05f0029, 0xf057002a, - 0xf0570028, 0xf04f002a, 0xf047002c, 0xf047002a, - 0xf0470028, 0xf0470026, 0xf0470024, 0xf0470022, - 0xf047001f, 0xf0370027, 0xf0370024, 0xf0370022, - 0xf0370020, 0xf037001f, 0xf037001d, 0xf037001b, - 0xf037001a, 0xf0370018, 0xf0370017, 0xf027001e, - 0xf027001d, 0xf027001a, 0xf01f0024, 0xf01f0022, - 0xf01f0020, 0xf01f001f, 0xf01f001d, 0xf01f001b, - 0xf01f001a, 0xf01f0018, 0xf01f0017, 0xf01f0015, - 0xf01f0014, 0xf01f0013, 0xf01f0012, 0xf01f0011, - 0xf0170019, 0xf0170018, 0xf0170016, 0xf0170015, - 0xf0170014, 0xf0170013, 0xf0170012, 0xf0170010, - 0xf0170010, 0xf017000f, 0xf00f001d, 0xf00f001b, - 0xf00f001a, 0xf00f0018, 0xf00f0017, 0xf00f0015, - 0xf00f0015, 0xf00f0013, 0xf00f0013, 0xf00f0011, - 0xf00f0010, 0xf00f0010, 0xf00f000f, 0xf00f000e, - 0xf00f000d, 0xf00f000c, 0xf00f000b, 0xf00f000b, - 0xf00f000b, 0xf00f000a, 0xf00f0009, 0xf00f0009, - 0xf00f0009, 0xf00f0008, 0xf00f0007, 0xf00f0007, - 0xf00f0006, 0xf00f0006, 0xf00f0006, 0xf00f0006, - 0xf00f0005, 0xf00f0005, 0xf00f0005, 0xf00f0004, - 0xf00f0004, 0xf00f0004, 0xf00f0004, 0xf00f0004, - 0xf00f0004, 0xf00f0003, 0xf00f0003, 0xf00f0003, - 0xf00f0003, 0xf00f0002, 0xf00f0002, 0xf00f0002, - 0xf00f0002, 0xf00f0002, 0xf00f0002, 0xf00f0001, - 0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001, - 0xf00f0001, 0xf00f0001, 0xf00f0001, 0xf00f0001 -}; - -static u32 nphy_tpc_txgain_ipa_2g_2057rev5[] = { - 0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e, - 0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033, - 0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e, - 0x3067002e, 0x305f002f, 0x30570030, 0x3057002d, - 0x304f002e, 0x30470031, 0x3047002e, 0x3047002c, - 0x30470029, 0x303f002c, 0x303f0029, 0x3037002d, - 0x3037002a, 0x30370028, 0x302f002c, 0x302f002a, - 0x302f0028, 0x302f0026, 0x3027002c, 0x30270029, - 0x30270027, 0x30270025, 0x30270023, 0x301f002c, - 0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024, - 0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b, - 0x30170028, 0x30170026, 0x30170024, 0x30170022, - 0x30170020, 0x3017001e, 0x3017001d, 0x3017001b, - 0x3017001a, 0x30170018, 0x30170017, 0x30170015, - 0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024, - 0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d, - 0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017, - 0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215, - 0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715 -}; - -static u32 nphy_tpc_txgain_ipa_2g_2057rev7[] = { - 0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e, - 0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033, - 0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e, - 0x3067002e, 0x305f002f, 0x30570030, 0x3057002d, - 0x304f002e, 0x30470031, 0x3047002e, 0x3047002c, - 0x30470029, 0x303f002c, 0x303f0029, 0x3037002d, - 0x3037002a, 0x30370028, 0x302f002c, 0x302f002a, - 0x302f0028, 0x302f0026, 0x3027002c, 0x30270029, - 0x30270027, 0x30270025, 0x30270023, 0x301f002c, - 0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024, - 0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b, - 0x30170028, 0x30170026, 0x30170024, 0x30170022, - 0x30170020, 0x3017001e, 0x3017001d, 0x3017001b, - 0x3017001a, 0x30170018, 0x30170017, 0x30170015, - 0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024, - 0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d, - 0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017, - 0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215, - 0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715, - 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715 -}; - -static u32 nphy_tpc_txgain_ipa_5g[] = { - 0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031, - 0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b, - 0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027, - 0x7ff70026, 0x7ff70024, 0x7ff70023, 0x7ff70022, - 0x7ef70028, 0x7ef70027, 0x7ef70026, 0x7ef70025, - 0x7ef70024, 0x7ef70023, 0x7df70028, 0x7df70027, - 0x7df70026, 0x7df70025, 0x7df70024, 0x7df70023, - 0x7df70022, 0x7cf70029, 0x7cf70028, 0x7cf70027, - 0x7cf70026, 0x7cf70025, 0x7cf70023, 0x7cf70022, - 0x7bf70029, 0x7bf70028, 0x7bf70026, 0x7bf70025, - 0x7bf70024, 0x7bf70023, 0x7bf70022, 0x7bf70021, - 0x7af70029, 0x7af70028, 0x7af70027, 0x7af70026, - 0x7af70025, 0x7af70024, 0x7af70023, 0x7af70022, - 0x79f70029, 0x79f70028, 0x79f70027, 0x79f70026, - 0x79f70025, 0x79f70024, 0x79f70023, 0x79f70022, - 0x78f70029, 0x78f70028, 0x78f70027, 0x78f70026, - 0x78f70025, 0x78f70024, 0x78f70023, 0x78f70022, - 0x77f70029, 0x77f70028, 0x77f70027, 0x77f70026, - 0x77f70025, 0x77f70024, 0x77f70023, 0x77f70022, - 0x76f70029, 0x76f70028, 0x76f70027, 0x76f70026, - 0x76f70024, 0x76f70023, 0x76f70022, 0x76f70021, - 0x75f70029, 0x75f70028, 0x75f70027, 0x75f70026, - 0x75f70025, 0x75f70024, 0x75f70023, 0x74f70029, - 0x74f70028, 0x74f70026, 0x74f70025, 0x74f70024, - 0x74f70023, 0x74f70022, 0x73f70029, 0x73f70027, - 0x73f70026, 0x73f70025, 0x73f70024, 0x73f70023, - 0x73f70022, 0x72f70028, 0x72f70027, 0x72f70026, - 0x72f70025, 0x72f70024, 0x72f70023, 0x72f70022, - 0x71f70028, 0x71f70027, 0x71f70026, 0x71f70025, - 0x71f70024, 0x71f70023, 0x70f70028, 0x70f70027, - 0x70f70026, 0x70f70024, 0x70f70023, 0x70f70022, - 0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f -}; - -static u32 nphy_tpc_txgain_ipa_5g_2057[] = { - 0x7f7f0044, 0x7f7f0040, 0x7f7f003c, 0x7f7f0039, - 0x7f7f0036, 0x7e7f003c, 0x7e7f0038, 0x7e7f0035, - 0x7d7f003c, 0x7d7f0039, 0x7d7f0036, 0x7d7f0033, - 0x7c7f003b, 0x7c7f0037, 0x7c7f0034, 0x7b7f003a, - 0x7b7f0036, 0x7b7f0033, 0x7a7f003c, 0x7a7f0039, - 0x7a7f0036, 0x7a7f0033, 0x797f003b, 0x797f0038, - 0x797f0035, 0x797f0032, 0x787f003b, 0x787f0038, - 0x787f0035, 0x787f0032, 0x777f003a, 0x777f0037, - 0x777f0034, 0x777f0031, 0x767f003a, 0x767f0036, - 0x767f0033, 0x767f0031, 0x757f003a, 0x757f0037, - 0x757f0034, 0x747f003c, 0x747f0039, 0x747f0036, - 0x747f0033, 0x737f003b, 0x737f0038, 0x737f0035, - 0x737f0032, 0x727f0039, 0x727f0036, 0x727f0033, - 0x727f0030, 0x717f003a, 0x717f0037, 0x717f0034, - 0x707f003b, 0x707f0038, 0x707f0035, 0x707f0032, - 0x707f002f, 0x707f002d, 0x707f002a, 0x707f0028, - 0x707f0025, 0x707f0023, 0x707f0021, 0x707f0020, - 0x707f001e, 0x707f001c, 0x707f001b, 0x707f0019, - 0x707f0018, 0x707f0016, 0x707f0015, 0x707f0014, - 0x707f0013, 0x707f0012, 0x707f0011, 0x707f0010, - 0x707f000f, 0x707f000e, 0x707f000d, 0x707f000d, - 0x707f000c, 0x707f000b, 0x707f000b, 0x707f000a, - 0x707f0009, 0x707f0009, 0x707f0008, 0x707f0008, - 0x707f0007, 0x707f0007, 0x707f0007, 0x707f0006, - 0x707f0006, 0x707f0006, 0x707f0005, 0x707f0005, - 0x707f0005, 0x707f0004, 0x707f0004, 0x707f0004, - 0x707f0004, 0x707f0004, 0x707f0003, 0x707f0003, - 0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003, - 0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002, - 0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002, - 0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001, - 0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001 -}; - -static u32 nphy_tpc_txgain_ipa_5g_2057rev7[] = { - 0x6f7f0031, 0x6f7f002e, 0x6f7f002c, 0x6f7f002a, - 0x6f7f0027, 0x6e7f002e, 0x6e7f002c, 0x6e7f002a, - 0x6d7f0030, 0x6d7f002d, 0x6d7f002a, 0x6d7f0028, - 0x6c7f0030, 0x6c7f002d, 0x6c7f002b, 0x6b7f002e, - 0x6b7f002c, 0x6b7f002a, 0x6b7f0027, 0x6a7f002e, - 0x6a7f002c, 0x6a7f002a, 0x697f0030, 0x697f002e, - 0x697f002b, 0x697f0029, 0x687f002f, 0x687f002d, - 0x687f002a, 0x687f0027, 0x677f002f, 0x677f002d, - 0x677f002a, 0x667f0031, 0x667f002e, 0x667f002c, - 0x667f002a, 0x657f0030, 0x657f002e, 0x657f002b, - 0x657f0029, 0x647f0030, 0x647f002d, 0x647f002b, - 0x647f0029, 0x637f002f, 0x637f002d, 0x637f002a, - 0x627f0030, 0x627f002d, 0x627f002b, 0x627f0029, - 0x617f0030, 0x617f002e, 0x617f002b, 0x617f0029, - 0x607f002f, 0x607f002d, 0x607f002a, 0x607f0027, - 0x607f0026, 0x607f0023, 0x607f0021, 0x607f0020, - 0x607f001e, 0x607f001c, 0x607f001a, 0x607f0019, - 0x607f0018, 0x607f0016, 0x607f0015, 0x607f0014, - 0x607f0012, 0x607f0012, 0x607f0011, 0x607f000f, - 0x607f000f, 0x607f000e, 0x607f000d, 0x607f000c, - 0x607f000c, 0x607f000b, 0x607f000b, 0x607f000a, - 0x607f0009, 0x607f0009, 0x607f0008, 0x607f0008, - 0x607f0008, 0x607f0007, 0x607f0007, 0x607f0006, - 0x607f0006, 0x607f0005, 0x607f0005, 0x607f0005, - 0x607f0005, 0x607f0005, 0x607f0004, 0x607f0004, - 0x607f0004, 0x607f0004, 0x607f0003, 0x607f0003, - 0x607f0003, 0x607f0003, 0x607f0002, 0x607f0002, - 0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002, - 0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002, - 0x607f0002, 0x607f0002, 0x607f0002, 0x607f0002, - 0x607f0002, 0x607f0001, 0x607f0001, 0x607f0001, - 0x607f0001, 0x607f0001, 0x607f0001, 0x607f0001 -}; - -static s8 nphy_papd_pga_gain_delta_ipa_2g[] = { - -114, -108, -98, -91, -84, -78, -70, -62, - -54, -46, -39, -31, -23, -15, -8, 0 -}; - -static s8 nphy_papd_pga_gain_delta_ipa_5g[] = { - -100, -95, -89, -83, -77, -70, -63, -56, - -48, -41, -33, -25, -19, -12, -6, 0 -}; - -static s16 nphy_papd_padgain_dlt_2g_2057rev3n4[] = { - -159, -113, -86, -72, -62, -54, -48, -43, - -39, -35, -31, -28, -25, -23, -20, -18, - -17, -15, -13, -11, -10, -8, -7, -6, - -5, -4, -3, -3, -2, -1, -1, 0 -}; - -static s16 nphy_papd_padgain_dlt_2g_2057rev5[] = { - -109, -109, -82, -68, -58, -50, -44, -39, - -35, -31, -28, -26, -23, -21, -19, -17, - -16, -14, -13, -11, -10, -9, -8, -7, - -5, -5, -4, -3, -2, -1, -1, 0 -}; - -static s16 nphy_papd_padgain_dlt_2g_2057rev7[] = { - -122, -122, -95, -80, -69, -61, -54, -49, - -43, -39, -35, -32, -28, -26, -23, -21, - -18, -16, -15, -13, -11, -10, -8, -7, - -6, -5, -4, -3, -2, -1, -1, 0 -}; - -static s8 nphy_papd_pgagain_dlt_5g_2057[] = { - -107, -101, -92, -85, -78, -71, -62, -55, - -47, -39, -32, -24, -19, -12, -6, 0 -}; - -static s8 nphy_papd_pgagain_dlt_5g_2057rev7[] = { - -110, -104, -95, -88, -81, -74, -66, -58, - -50, -44, -36, -28, -23, -15, -8, 0 -}; - -static u8 pad_gain_codes_used_2057rev5[] = { - 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, - 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 -}; - -static u8 pad_gain_codes_used_2057rev7[] = { - 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, - 5, 4, 3, 2, 1 -}; - -static u8 pad_all_gain_codes_2057[] = { - 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, - 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, - 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, - 1, 0 -}; - -static u8 pga_all_gain_codes_2057[] = { - 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 -}; - -static u32 nphy_papd_scaltbl[] = { - 0x0ae2002f, 0x0a3b0032, 0x09a70035, 0x09220038, - 0x0887003c, 0x081f003f, 0x07a20043, 0x07340047, - 0x06d2004b, 0x067a004f, 0x06170054, 0x05bf0059, - 0x0571005e, 0x051e0064, 0x04d3006a, 0x04910070, - 0x044c0077, 0x040f007e, 0x03d90085, 0x03a1008d, - 0x036f0095, 0x033d009e, 0x030b00a8, 0x02e000b2, - 0x02b900bc, 0x029200c7, 0x026d00d3, 0x024900e0, - 0x022900ed, 0x020a00fb, 0x01ec010a, 0x01d0011a, - 0x01b7012a, 0x019e013c, 0x0187014f, 0x01720162, - 0x015d0177, 0x0149018e, 0x013701a5, 0x012601be, - 0x011501d9, 0x010501f5, 0x00f70212, 0x00e90232, - 0x00dc0253, 0x00d00276, 0x00c4029c, 0x00b902c3, - 0x00af02ed, 0x00a5031a, 0x009c0349, 0x0093037a, - 0x008b03af, 0x008303e7, 0x007c0422, 0x00750461, - 0x006e04a3, 0x006804ea, 0x00620534, 0x005d0583, - 0x005805d7, 0x0053062f, 0x004e068d, 0x004a06f1 -}; - -static u32 nphy_tpc_txgain_rev3[] = { - 0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e, - 0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037, - 0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e, - 0x1e41003c, 0x1e41003b, 0x1e410039, 0x1e410037, - 0x1d410044, 0x1d410042, 0x1d410040, 0x1d41003e, - 0x1d41003c, 0x1d41003b, 0x1d410039, 0x1d410037, - 0x1c410044, 0x1c410042, 0x1c410040, 0x1c41003e, - 0x1c41003c, 0x1c41003b, 0x1c410039, 0x1c410037, - 0x1b410044, 0x1b410042, 0x1b410040, 0x1b41003e, - 0x1b41003c, 0x1b41003b, 0x1b410039, 0x1b410037, - 0x1a410044, 0x1a410042, 0x1a410040, 0x1a41003e, - 0x1a41003c, 0x1a41003b, 0x1a410039, 0x1a410037, - 0x19410044, 0x19410042, 0x19410040, 0x1941003e, - 0x1941003c, 0x1941003b, 0x19410039, 0x19410037, - 0x18410044, 0x18410042, 0x18410040, 0x1841003e, - 0x1841003c, 0x1841003b, 0x18410039, 0x18410037, - 0x17410044, 0x17410042, 0x17410040, 0x1741003e, - 0x1741003c, 0x1741003b, 0x17410039, 0x17410037, - 0x16410044, 0x16410042, 0x16410040, 0x1641003e, - 0x1641003c, 0x1641003b, 0x16410039, 0x16410037, - 0x15410044, 0x15410042, 0x15410040, 0x1541003e, - 0x1541003c, 0x1541003b, 0x15410039, 0x15410037, - 0x14410044, 0x14410042, 0x14410040, 0x1441003e, - 0x1441003c, 0x1441003b, 0x14410039, 0x14410037, - 0x13410044, 0x13410042, 0x13410040, 0x1341003e, - 0x1341003c, 0x1341003b, 0x13410039, 0x13410037, - 0x12410044, 0x12410042, 0x12410040, 0x1241003e, - 0x1241003c, 0x1241003b, 0x12410039, 0x12410037, - 0x11410044, 0x11410042, 0x11410040, 0x1141003e, - 0x1141003c, 0x1141003b, 0x11410039, 0x11410037, - 0x10410044, 0x10410042, 0x10410040, 0x1041003e, - 0x1041003c, 0x1041003b, 0x10410039, 0x10410037 -}; - -static u32 nphy_tpc_txgain_HiPwrEPA[] = { - 0x0f410044, 0x0f410042, 0x0f410040, 0x0f41003e, - 0x0f41003c, 0x0f41003b, 0x0f410039, 0x0f410037, - 0x0e410044, 0x0e410042, 0x0e410040, 0x0e41003e, - 0x0e41003c, 0x0e41003b, 0x0e410039, 0x0e410037, - 0x0d410044, 0x0d410042, 0x0d410040, 0x0d41003e, - 0x0d41003c, 0x0d41003b, 0x0d410039, 0x0d410037, - 0x0c410044, 0x0c410042, 0x0c410040, 0x0c41003e, - 0x0c41003c, 0x0c41003b, 0x0c410039, 0x0c410037, - 0x0b410044, 0x0b410042, 0x0b410040, 0x0b41003e, - 0x0b41003c, 0x0b41003b, 0x0b410039, 0x0b410037, - 0x0a410044, 0x0a410042, 0x0a410040, 0x0a41003e, - 0x0a41003c, 0x0a41003b, 0x0a410039, 0x0a410037, - 0x09410044, 0x09410042, 0x09410040, 0x0941003e, - 0x0941003c, 0x0941003b, 0x09410039, 0x09410037, - 0x08410044, 0x08410042, 0x08410040, 0x0841003e, - 0x0841003c, 0x0841003b, 0x08410039, 0x08410037, - 0x07410044, 0x07410042, 0x07410040, 0x0741003e, - 0x0741003c, 0x0741003b, 0x07410039, 0x07410037, - 0x06410044, 0x06410042, 0x06410040, 0x0641003e, - 0x0641003c, 0x0641003b, 0x06410039, 0x06410037, - 0x05410044, 0x05410042, 0x05410040, 0x0541003e, - 0x0541003c, 0x0541003b, 0x05410039, 0x05410037, - 0x04410044, 0x04410042, 0x04410040, 0x0441003e, - 0x0441003c, 0x0441003b, 0x04410039, 0x04410037, - 0x03410044, 0x03410042, 0x03410040, 0x0341003e, - 0x0341003c, 0x0341003b, 0x03410039, 0x03410037, - 0x02410044, 0x02410042, 0x02410040, 0x0241003e, - 0x0241003c, 0x0241003b, 0x02410039, 0x02410037, - 0x01410044, 0x01410042, 0x01410040, 0x0141003e, - 0x0141003c, 0x0141003b, 0x01410039, 0x01410037, - 0x00410044, 0x00410042, 0x00410040, 0x0041003e, - 0x0041003c, 0x0041003b, 0x00410039, 0x00410037 -}; - -static u32 nphy_tpc_txgain_epa_2057rev3[] = { - 0x80f90040, 0x80e10040, 0x80e1003c, 0x80c9003d, - 0x80b9003c, 0x80a9003d, 0x80a1003c, 0x8099003b, - 0x8091003b, 0x8089003a, 0x8081003a, 0x80790039, - 0x80710039, 0x8069003a, 0x8061003b, 0x8059003d, - 0x8051003f, 0x80490042, 0x8049003e, 0x8049003b, - 0x8041003e, 0x8041003b, 0x8039003e, 0x8039003b, - 0x80390038, 0x80390035, 0x8031003a, 0x80310036, - 0x80310033, 0x8029003a, 0x80290037, 0x80290034, - 0x80290031, 0x80210039, 0x80210036, 0x80210033, - 0x80210030, 0x8019003c, 0x80190039, 0x80190036, - 0x80190033, 0x80190030, 0x8019002d, 0x8019002b, - 0x80190028, 0x8011003a, 0x80110036, 0x80110033, - 0x80110030, 0x8011002e, 0x8011002b, 0x80110029, - 0x80110027, 0x80110024, 0x80110022, 0x80110020, - 0x8011001f, 0x8011001d, 0x8009003a, 0x80090037, - 0x80090034, 0x80090031, 0x8009002e, 0x8009002c, - 0x80090029, 0x80090027, 0x80090025, 0x80090023, - 0x80090021, 0x8009001f, 0x8009001d, 0x8009011d, - 0x8009021d, 0x8009031d, 0x8009041d, 0x8009051d, - 0x8009061d, 0x8009071d, 0x8009071d, 0x8009071d, - 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, - 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, - 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, - 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, - 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, - 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, - 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, - 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, - 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, - 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, - 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d, - 0x8009071d, 0x8009071d, 0x8009071d, 0x8009071d -}; - -static u32 nphy_tpc_txgain_epa_2057rev5[] = { - 0x10f90040, 0x10e10040, 0x10e1003c, 0x10c9003d, - 0x10b9003c, 0x10a9003d, 0x10a1003c, 0x1099003b, - 0x1091003b, 0x1089003a, 0x1081003a, 0x10790039, - 0x10710039, 0x1069003a, 0x1061003b, 0x1059003d, - 0x1051003f, 0x10490042, 0x1049003e, 0x1049003b, - 0x1041003e, 0x1041003b, 0x1039003e, 0x1039003b, - 0x10390038, 0x10390035, 0x1031003a, 0x10310036, - 0x10310033, 0x1029003a, 0x10290037, 0x10290034, - 0x10290031, 0x10210039, 0x10210036, 0x10210033, - 0x10210030, 0x1019003c, 0x10190039, 0x10190036, - 0x10190033, 0x10190030, 0x1019002d, 0x1019002b, - 0x10190028, 0x1011003a, 0x10110036, 0x10110033, - 0x10110030, 0x1011002e, 0x1011002b, 0x10110029, - 0x10110027, 0x10110024, 0x10110022, 0x10110020, - 0x1011001f, 0x1011001d, 0x1009003a, 0x10090037, - 0x10090034, 0x10090031, 0x1009002e, 0x1009002c, - 0x10090029, 0x10090027, 0x10090025, 0x10090023, - 0x10090021, 0x1009001f, 0x1009001d, 0x1009001b, - 0x1009001a, 0x10090018, 0x10090017, 0x10090016, - 0x10090015, 0x10090013, 0x10090012, 0x10090011, - 0x10090010, 0x1009000f, 0x1009000f, 0x1009000e, - 0x1009000d, 0x1009000c, 0x1009000c, 0x1009000b, - 0x1009000a, 0x1009000a, 0x10090009, 0x10090009, - 0x10090008, 0x10090008, 0x10090007, 0x10090007, - 0x10090007, 0x10090006, 0x10090006, 0x10090005, - 0x10090005, 0x10090005, 0x10090005, 0x10090004, - 0x10090004, 0x10090004, 0x10090004, 0x10090003, - 0x10090003, 0x10090003, 0x10090003, 0x10090003, - 0x10090003, 0x10090002, 0x10090002, 0x10090002, - 0x10090002, 0x10090002, 0x10090002, 0x10090002, - 0x10090002, 0x10090002, 0x10090001, 0x10090001, - 0x10090001, 0x10090001, 0x10090001, 0x10090001 -}; - -static u32 nphy_tpc_5GHz_txgain_rev3[] = { - 0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e, - 0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037, - 0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e, - 0xcef7003c, 0xcef7003b, 0xcef70039, 0xcef70037, - 0xcdf70044, 0xcdf70042, 0xcdf70040, 0xcdf7003e, - 0xcdf7003c, 0xcdf7003b, 0xcdf70039, 0xcdf70037, - 0xccf70044, 0xccf70042, 0xccf70040, 0xccf7003e, - 0xccf7003c, 0xccf7003b, 0xccf70039, 0xccf70037, - 0xcbf70044, 0xcbf70042, 0xcbf70040, 0xcbf7003e, - 0xcbf7003c, 0xcbf7003b, 0xcbf70039, 0xcbf70037, - 0xcaf70044, 0xcaf70042, 0xcaf70040, 0xcaf7003e, - 0xcaf7003c, 0xcaf7003b, 0xcaf70039, 0xcaf70037, - 0xc9f70044, 0xc9f70042, 0xc9f70040, 0xc9f7003e, - 0xc9f7003c, 0xc9f7003b, 0xc9f70039, 0xc9f70037, - 0xc8f70044, 0xc8f70042, 0xc8f70040, 0xc8f7003e, - 0xc8f7003c, 0xc8f7003b, 0xc8f70039, 0xc8f70037, - 0xc7f70044, 0xc7f70042, 0xc7f70040, 0xc7f7003e, - 0xc7f7003c, 0xc7f7003b, 0xc7f70039, 0xc7f70037, - 0xc6f70044, 0xc6f70042, 0xc6f70040, 0xc6f7003e, - 0xc6f7003c, 0xc6f7003b, 0xc6f70039, 0xc6f70037, - 0xc5f70044, 0xc5f70042, 0xc5f70040, 0xc5f7003e, - 0xc5f7003c, 0xc5f7003b, 0xc5f70039, 0xc5f70037, - 0xc4f70044, 0xc4f70042, 0xc4f70040, 0xc4f7003e, - 0xc4f7003c, 0xc4f7003b, 0xc4f70039, 0xc4f70037, - 0xc3f70044, 0xc3f70042, 0xc3f70040, 0xc3f7003e, - 0xc3f7003c, 0xc3f7003b, 0xc3f70039, 0xc3f70037, - 0xc2f70044, 0xc2f70042, 0xc2f70040, 0xc2f7003e, - 0xc2f7003c, 0xc2f7003b, 0xc2f70039, 0xc2f70037, - 0xc1f70044, 0xc1f70042, 0xc1f70040, 0xc1f7003e, - 0xc1f7003c, 0xc1f7003b, 0xc1f70039, 0xc1f70037, - 0xc0f70044, 0xc0f70042, 0xc0f70040, 0xc0f7003e, - 0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037 -}; - -static u32 nphy_tpc_5GHz_txgain_rev4[] = { - 0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e, - 0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037, - 0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e, - 0x2ef2003c, 0x2ef2003b, 0x2ef20039, 0x2ef20037, - 0x2df20044, 0x2df20042, 0x2df20040, 0x2df2003e, - 0x2df2003c, 0x2df2003b, 0x2df20039, 0x2df20037, - 0x2cf20044, 0x2cf20042, 0x2cf20040, 0x2cf2003e, - 0x2cf2003c, 0x2cf2003b, 0x2cf20039, 0x2cf20037, - 0x2bf20044, 0x2bf20042, 0x2bf20040, 0x2bf2003e, - 0x2bf2003c, 0x2bf2003b, 0x2bf20039, 0x2bf20037, - 0x2af20044, 0x2af20042, 0x2af20040, 0x2af2003e, - 0x2af2003c, 0x2af2003b, 0x2af20039, 0x2af20037, - 0x29f20044, 0x29f20042, 0x29f20040, 0x29f2003e, - 0x29f2003c, 0x29f2003b, 0x29f20039, 0x29f20037, - 0x28f20044, 0x28f20042, 0x28f20040, 0x28f2003e, - 0x28f2003c, 0x28f2003b, 0x28f20039, 0x28f20037, - 0x27f20044, 0x27f20042, 0x27f20040, 0x27f2003e, - 0x27f2003c, 0x27f2003b, 0x27f20039, 0x27f20037, - 0x26f20044, 0x26f20042, 0x26f20040, 0x26f2003e, - 0x26f2003c, 0x26f2003b, 0x26f20039, 0x26f20037, - 0x25f20044, 0x25f20042, 0x25f20040, 0x25f2003e, - 0x25f2003c, 0x25f2003b, 0x25f20039, 0x25f20037, - 0x24f20044, 0x24f20042, 0x24f20040, 0x24f2003e, - 0x24f2003c, 0x24f2003b, 0x24f20039, 0x24f20038, - 0x23f20041, 0x23f20040, 0x23f2003f, 0x23f2003e, - 0x23f2003c, 0x23f2003b, 0x23f20039, 0x23f20037, - 0x22f20044, 0x22f20042, 0x22f20040, 0x22f2003e, - 0x22f2003c, 0x22f2003b, 0x22f20039, 0x22f20037, - 0x21f20044, 0x21f20042, 0x21f20040, 0x21f2003e, - 0x21f2003c, 0x21f2003b, 0x21f20039, 0x21f20037, - 0x20d20043, 0x20d20041, 0x20d2003e, 0x20d2003c, - 0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034 -}; - -static u32 nphy_tpc_5GHz_txgain_rev5[] = { - 0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044, - 0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c, - 0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e, - 0x0e62003c, 0x0e62003d, 0x0e62003b, 0x0e62003a, - 0x0d620043, 0x0d620041, 0x0d620040, 0x0d62003e, - 0x0d62003d, 0x0d62003c, 0x0d62003b, 0x0d62003a, - 0x0c620041, 0x0c620040, 0x0c62003f, 0x0c62003e, - 0x0c62003c, 0x0c62003b, 0x0c620039, 0x0c620037, - 0x0b620046, 0x0b620044, 0x0b620042, 0x0b620040, - 0x0b62003e, 0x0b62003c, 0x0b62003b, 0x0b62003a, - 0x0a620041, 0x0a620040, 0x0a62003e, 0x0a62003c, - 0x0a62003b, 0x0a62003a, 0x0a620039, 0x0a620038, - 0x0962003e, 0x0962003d, 0x0962003c, 0x0962003b, - 0x09620039, 0x09620037, 0x09620035, 0x09620033, - 0x08620044, 0x08620042, 0x08620040, 0x0862003e, - 0x0862003c, 0x0862003b, 0x0862003a, 0x08620039, - 0x07620043, 0x07620042, 0x07620040, 0x0762003f, - 0x0762003d, 0x0762003b, 0x0762003a, 0x07620039, - 0x0662003e, 0x0662003d, 0x0662003c, 0x0662003b, - 0x06620039, 0x06620037, 0x06620035, 0x06620033, - 0x05620046, 0x05620044, 0x05620042, 0x05620040, - 0x0562003e, 0x0562003c, 0x0562003b, 0x05620039, - 0x04620044, 0x04620042, 0x04620040, 0x0462003e, - 0x0462003c, 0x0462003b, 0x04620039, 0x04620038, - 0x0362003c, 0x0362003b, 0x0362003a, 0x03620039, - 0x03620038, 0x03620037, 0x03620035, 0x03620033, - 0x0262004c, 0x0262004a, 0x02620048, 0x02620047, - 0x02620046, 0x02620044, 0x02620043, 0x02620042, - 0x0162004a, 0x01620048, 0x01620046, 0x01620044, - 0x01620043, 0x01620042, 0x01620041, 0x01620040, - 0x00620042, 0x00620040, 0x0062003e, 0x0062003c, - 0x0062003b, 0x00620039, 0x00620037, 0x00620035 -}; - -static u32 nphy_tpc_5GHz_txgain_HiPwrEPA[] = { - 0x2ff10044, 0x2ff10042, 0x2ff10040, 0x2ff1003e, - 0x2ff1003c, 0x2ff1003b, 0x2ff10039, 0x2ff10037, - 0x2ef10044, 0x2ef10042, 0x2ef10040, 0x2ef1003e, - 0x2ef1003c, 0x2ef1003b, 0x2ef10039, 0x2ef10037, - 0x2df10044, 0x2df10042, 0x2df10040, 0x2df1003e, - 0x2df1003c, 0x2df1003b, 0x2df10039, 0x2df10037, - 0x2cf10044, 0x2cf10042, 0x2cf10040, 0x2cf1003e, - 0x2cf1003c, 0x2cf1003b, 0x2cf10039, 0x2cf10037, - 0x2bf10044, 0x2bf10042, 0x2bf10040, 0x2bf1003e, - 0x2bf1003c, 0x2bf1003b, 0x2bf10039, 0x2bf10037, - 0x2af10044, 0x2af10042, 0x2af10040, 0x2af1003e, - 0x2af1003c, 0x2af1003b, 0x2af10039, 0x2af10037, - 0x29f10044, 0x29f10042, 0x29f10040, 0x29f1003e, - 0x29f1003c, 0x29f1003b, 0x29f10039, 0x29f10037, - 0x28f10044, 0x28f10042, 0x28f10040, 0x28f1003e, - 0x28f1003c, 0x28f1003b, 0x28f10039, 0x28f10037, - 0x27f10044, 0x27f10042, 0x27f10040, 0x27f1003e, - 0x27f1003c, 0x27f1003b, 0x27f10039, 0x27f10037, - 0x26f10044, 0x26f10042, 0x26f10040, 0x26f1003e, - 0x26f1003c, 0x26f1003b, 0x26f10039, 0x26f10037, - 0x25f10044, 0x25f10042, 0x25f10040, 0x25f1003e, - 0x25f1003c, 0x25f1003b, 0x25f10039, 0x25f10037, - 0x24f10044, 0x24f10042, 0x24f10040, 0x24f1003e, - 0x24f1003c, 0x24f1003b, 0x24f10039, 0x24f10038, - 0x23f10041, 0x23f10040, 0x23f1003f, 0x23f1003e, - 0x23f1003c, 0x23f1003b, 0x23f10039, 0x23f10037, - 0x22f10044, 0x22f10042, 0x22f10040, 0x22f1003e, - 0x22f1003c, 0x22f1003b, 0x22f10039, 0x22f10037, - 0x21f10044, 0x21f10042, 0x21f10040, 0x21f1003e, - 0x21f1003c, 0x21f1003b, 0x21f10039, 0x21f10037, - 0x20d10043, 0x20d10041, 0x20d1003e, 0x20d1003c, - 0x20d1003a, 0x20d10038, 0x20d10036, 0x20d10034 -}; - -static u8 ant_sw_ctrl_tbl_rev8_2o3[] = { 0x14, 0x18 }; -static u8 ant_sw_ctrl_tbl_rev8[] = { 0x4, 0x8, 0x4, 0x8, 0x11, 0x12 }; -static u8 ant_sw_ctrl_tbl_rev8_2057v7_core0[] = { - 0x09, 0x0a, 0x15, 0x16, 0x09, 0x0a }; -static u8 ant_sw_ctrl_tbl_rev8_2057v7_core1[] = { - 0x09, 0x0a, 0x09, 0x0a, 0x15, 0x16 }; - -static bool wlc_phy_chan2freq_nphy(phy_info_t *pi, uint channel, int *f, - chan_info_nphy_radio2057_t **t0, - chan_info_nphy_radio205x_t **t1, - chan_info_nphy_radio2057_rev5_t **t2, - chan_info_nphy_2055_t **t3); -static void wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chans, - const nphy_sfo_cfg_t *c); - -static void wlc_phy_adjust_rx_analpfbw_nphy(phy_info_t *pi, - u16 reduction_factr); -static void wlc_phy_adjust_min_noisevar_nphy(phy_info_t *pi, int ntones, int *, - u32 *buf); -static void wlc_phy_adjust_crsminpwr_nphy(phy_info_t *pi, u8 minpwr); -static void wlc_phy_txlpfbw_nphy(phy_info_t *pi); -static void wlc_phy_spurwar_nphy(phy_info_t *pi); - -static void wlc_phy_radio_preinit_2055(phy_info_t *pi); -static void wlc_phy_radio_init_2055(phy_info_t *pi); -static void wlc_phy_radio_postinit_2055(phy_info_t *pi); -static void wlc_phy_radio_preinit_205x(phy_info_t *pi); -static void wlc_phy_radio_init_2056(phy_info_t *pi); -static void wlc_phy_radio_postinit_2056(phy_info_t *pi); -static void wlc_phy_radio_init_2057(phy_info_t *pi); -static void wlc_phy_radio_postinit_2057(phy_info_t *pi); -static void wlc_phy_workarounds_nphy(phy_info_t *pi); -static void wlc_phy_workarounds_nphy_gainctrl(phy_info_t *pi); -static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(phy_info_t *pi); -static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(phy_info_t *pi); -static void wlc_phy_adjust_lnagaintbl_nphy(phy_info_t *pi); - -static void wlc_phy_restore_rssical_nphy(phy_info_t *pi); -static void wlc_phy_reapply_txcal_coeffs_nphy(phy_info_t *pi); -static void wlc_phy_tx_iq_war_nphy(phy_info_t *pi); -static int wlc_phy_cal_rxiq_nphy_rev3(phy_info_t *pi, nphy_txgains_t tg, - u8 type, bool d); -static void wlc_phy_rxcal_gainctrl_nphy_rev5(phy_info_t *pi, u8 rxcore, - u16 *rg, u8 type); -static void wlc_phy_update_mimoconfig_nphy(phy_info_t *pi, s32 preamble); -static void wlc_phy_savecal_nphy(phy_info_t *pi); -static void wlc_phy_restorecal_nphy(phy_info_t *pi); -static void wlc_phy_resetcca_nphy(phy_info_t *pi); - -static void wlc_phy_txpwrctrl_config_nphy(phy_info_t *pi); -static void wlc_phy_internal_cal_txgain_nphy(phy_info_t *pi); -static void wlc_phy_precal_txgain_nphy(phy_info_t *pi); -static void wlc_phy_update_txcal_ladder_nphy(phy_info_t *pi, u16 core); - -static void wlc_phy_extpa_set_tx_digi_filts_nphy(phy_info_t *pi); -static void wlc_phy_ipa_set_tx_digi_filts_nphy(phy_info_t *pi); -static void wlc_phy_ipa_restore_tx_digi_filts_nphy(phy_info_t *pi); -static u16 wlc_phy_ipa_get_bbmult_nphy(phy_info_t *pi); -static void wlc_phy_ipa_set_bbmult_nphy(phy_info_t *pi, u8 m0, u8 m1); -static u32 *wlc_phy_get_ipa_gaintbl_nphy(phy_info_t *pi); - -static void wlc_phy_a1_nphy(phy_info_t *pi, u8 core, u32 winsz, u32, - u32 e); -static u8 wlc_phy_a3_nphy(phy_info_t *pi, u8 start_gain, u8 core); -static void wlc_phy_a2_nphy(phy_info_t *pi, nphy_ipa_txcalgains_t *, - phy_cal_mode_t, u8); -static void wlc_phy_papd_cal_cleanup_nphy(phy_info_t *pi, - nphy_papd_restore_state *state); -static void wlc_phy_papd_cal_setup_nphy(phy_info_t *pi, - nphy_papd_restore_state *state, u8); - -static void wlc_phy_clip_det_nphy(phy_info_t *pi, u8 write, u16 *vals); - -static void wlc_phy_set_rfseq_nphy(phy_info_t *pi, u8 cmd, u8 *evts, - u8 *dlys, u8 len); - -static u16 wlc_phy_read_lpf_bw_ctl_nphy(phy_info_t *pi, u16 offset); - -static void -wlc_phy_rfctrl_override_nphy_rev7(phy_info_t *pi, u16 field, u16 value, - u8 core_mask, u8 off, - u8 override_id); - -static void wlc_phy_rssi_cal_nphy_rev2(phy_info_t *pi, u8 rssi_type); -static void wlc_phy_rssi_cal_nphy_rev3(phy_info_t *pi); - -static bool wlc_phy_txpwr_srom_read_nphy(phy_info_t *pi); -static void wlc_phy_txpwr_nphy_srom_convert(u8 *srom_max, - u16 *pwr_offset, - u8 tmp_max_pwr, u8 rate_start, - u8 rate_end); - -static void wlc_phy_txpwr_limit_to_tbl_nphy(phy_info_t *pi); -static void wlc_phy_txpwrctrl_coeff_setup_nphy(phy_info_t *pi); -static void wlc_phy_txpwrctrl_idle_tssi_nphy(phy_info_t *pi); -static void wlc_phy_txpwrctrl_pwr_setup_nphy(phy_info_t *pi); - -static bool wlc_phy_txpwr_ison_nphy(phy_info_t *pi); -static u8 wlc_phy_txpwr_idx_cur_get_nphy(phy_info_t *pi, u8 core); -static void wlc_phy_txpwr_idx_cur_set_nphy(phy_info_t *pi, u8 idx0, - u8 idx1); -static void wlc_phy_a4(phy_info_t *pi, bool full_cal); - -static u16 wlc_phy_radio205x_rcal(phy_info_t *pi); - -static u16 wlc_phy_radio2057_rccal(phy_info_t *pi); - -static u16 wlc_phy_gen_load_samples_nphy(phy_info_t *pi, u32 f_kHz, - u16 max_val, - u8 dac_test_mode); -static void wlc_phy_loadsampletable_nphy(phy_info_t *pi, cs32 *tone_buf, - u16 num_samps); -static void wlc_phy_runsamples_nphy(phy_info_t *pi, u16 n, u16 lps, - u16 wait, u8 iq, u8 dac_test_mode, - bool modify_bbmult); - -bool wlc_phy_bist_check_phy(wlc_phy_t *pih) -{ - phy_info_t *pi = (phy_info_t *) pih; - u32 phybist0, phybist1, phybist2, phybist3, phybist4; - - if (NREV_GE(pi->pubpi.phy_rev, 16)) - return true; - - phybist0 = read_phy_reg(pi, 0x0e); - phybist1 = read_phy_reg(pi, 0x0f); - phybist2 = read_phy_reg(pi, 0xea); - phybist3 = read_phy_reg(pi, 0xeb); - phybist4 = read_phy_reg(pi, 0x156); - - if ((phybist0 == 0) && (phybist1 == 0x4000) && (phybist2 == 0x1fe0) && - (phybist3 == 0) && (phybist4 == 0)) { - return true; - } - - return false; -} - -static void WLBANDINITFN(wlc_phy_bphy_init_nphy) (phy_info_t *pi) -{ - u16 addr, val; - - ASSERT(ISNPHY(pi)); - - val = 0x1e1f; - for (addr = (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT); - addr <= (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT_END); addr++) { - write_phy_reg(pi, addr, val); - if (addr == (NPHY_TO_BPHY_OFF + 0x97)) - val = 0x3e3f; - else - val -= 0x0202; - } - - if (NORADIO_ENAB(pi->pubpi)) { - - write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_PHYCRSTH, 0x3206); - - write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_RSSI_TRESH, 0x281e); - - or_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_LNA_GAIN_RANGE, 0x1a); - - } else { - - write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_STEP, 0x668); - } -} - -void -wlc_phy_table_write_nphy(phy_info_t *pi, u32 id, u32 len, u32 offset, - u32 width, const void *data) -{ - mimophytbl_info_t tbl; - - tbl.tbl_id = id; - tbl.tbl_len = len; - tbl.tbl_offset = offset; - tbl.tbl_width = width; - tbl.tbl_ptr = data; - wlc_phy_write_table_nphy(pi, &tbl); -} - -void -wlc_phy_table_read_nphy(phy_info_t *pi, u32 id, u32 len, u32 offset, - u32 width, void *data) -{ - mimophytbl_info_t tbl; - - tbl.tbl_id = id; - tbl.tbl_len = len; - tbl.tbl_offset = offset; - tbl.tbl_width = width; - tbl.tbl_ptr = data; - wlc_phy_read_table_nphy(pi, &tbl); -} - -static void WLBANDINITFN(wlc_phy_static_table_download_nphy) (phy_info_t *pi) -{ - uint idx; - - if (NREV_GE(pi->pubpi.phy_rev, 16)) { - for (idx = 0; idx < mimophytbl_info_sz_rev16; idx++) - wlc_phy_write_table_nphy(pi, - &mimophytbl_info_rev16[idx]); - } else if (NREV_GE(pi->pubpi.phy_rev, 7)) { - for (idx = 0; idx < mimophytbl_info_sz_rev7; idx++) - wlc_phy_write_table_nphy(pi, - &mimophytbl_info_rev7[idx]); - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - for (idx = 0; idx < mimophytbl_info_sz_rev3; idx++) - wlc_phy_write_table_nphy(pi, - &mimophytbl_info_rev3[idx]); - } else { - for (idx = 0; idx < mimophytbl_info_sz_rev0; idx++) - wlc_phy_write_table_nphy(pi, - &mimophytbl_info_rev0[idx]); - } -} - -static void WLBANDINITFN(wlc_phy_tbl_init_nphy) (phy_info_t *pi) -{ - uint idx = 0; - u8 antswctrllut; - - if (pi->phy_init_por) - wlc_phy_static_table_download_nphy(pi); - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - antswctrllut = CHSPEC_IS2G(pi->radio_chanspec) ? - pi->srom_fem2g.antswctrllut : pi->srom_fem5g.antswctrllut; - - switch (antswctrllut) { - case 0: - - break; - - case 1: - - if (pi->aa2g == 7) { - - wlc_phy_table_write_nphy(pi, - NPHY_TBL_ID_ANTSWCTRLLUT, - 2, 0x21, 8, - &ant_sw_ctrl_tbl_rev8_2o3 - [0]); - } else { - wlc_phy_table_write_nphy(pi, - NPHY_TBL_ID_ANTSWCTRLLUT, - 2, 0x21, 8, - &ant_sw_ctrl_tbl_rev8 - [0]); - } - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 2, 0x25, 8, - &ant_sw_ctrl_tbl_rev8[2]); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 2, 0x29, 8, - &ant_sw_ctrl_tbl_rev8[4]); - break; - - case 2: - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 2, 0x1, 8, - &ant_sw_ctrl_tbl_rev8_2057v7_core0 - [0]); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 2, 0x5, 8, - &ant_sw_ctrl_tbl_rev8_2057v7_core0 - [2]); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 2, 0x9, 8, - &ant_sw_ctrl_tbl_rev8_2057v7_core0 - [4]); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 2, 0x21, 8, - &ant_sw_ctrl_tbl_rev8_2057v7_core1 - [0]); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 2, 0x25, 8, - &ant_sw_ctrl_tbl_rev8_2057v7_core1 - [2]); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 2, 0x29, 8, - &ant_sw_ctrl_tbl_rev8_2057v7_core1 - [4]); - break; - - default: - - ASSERT(0); - break; - } - - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - for (idx = 0; idx < mimophytbl_info_sz_rev3_volatile; idx++) { - - if (idx == ANT_SWCTRL_TBL_REV3_IDX) { - antswctrllut = CHSPEC_IS2G(pi->radio_chanspec) ? - pi->srom_fem2g.antswctrllut : pi-> - srom_fem5g.antswctrllut; - switch (antswctrllut) { - case 0: - wlc_phy_write_table_nphy(pi, - &mimophytbl_info_rev3_volatile - [idx]); - break; - case 1: - wlc_phy_write_table_nphy(pi, - &mimophytbl_info_rev3_volatile1 - [idx]); - break; - case 2: - wlc_phy_write_table_nphy(pi, - &mimophytbl_info_rev3_volatile2 - [idx]); - break; - case 3: - wlc_phy_write_table_nphy(pi, - &mimophytbl_info_rev3_volatile3 - [idx]); - break; - default: - - ASSERT(0); - break; - } - } else { - wlc_phy_write_table_nphy(pi, - &mimophytbl_info_rev3_volatile - [idx]); - } - } - } else { - for (idx = 0; idx < mimophytbl_info_sz_rev0_volatile; idx++) { - wlc_phy_write_table_nphy(pi, - &mimophytbl_info_rev0_volatile - [idx]); - } - } -} - -static void -wlc_phy_write_txmacreg_nphy(phy_info_t *pi, u16 holdoff, u16 delay) -{ - write_phy_reg(pi, 0x77, holdoff); - write_phy_reg(pi, 0xb4, delay); -} - -void wlc_phy_nphy_tkip_rifs_war(phy_info_t *pi, u8 rifs) -{ - u16 holdoff, delay; - - if (rifs) { - - holdoff = 0x10; - delay = 0x258; - } else { - - holdoff = 0x15; - delay = 0x320; - } - - wlc_phy_write_txmacreg_nphy(pi, holdoff, delay); - - if (pi && pi->sh && (pi->sh->_rifs_phy != rifs)) { - pi->sh->_rifs_phy = rifs; - } -} - -bool wlc_phy_attach_nphy(phy_info_t *pi) -{ - uint i; - - if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 6)) { - pi->phyhang_avoid = true; - } - - if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) { - - pi->nphy_gband_spurwar_en = true; - - if (pi->sh->boardflags2 & BFL2_SPUR_WAR) { - pi->nphy_aband_spurwar_en = true; - } - } - if (NREV_GE(pi->pubpi.phy_rev, 6) && NREV_LT(pi->pubpi.phy_rev, 7)) { - - if (pi->sh->boardflags2 & BFL2_2G_SPUR_WAR) { - pi->nphy_gband_spurwar2_en = true; - } - } - - pi->n_preamble_override = AUTO; - if (NREV_IS(pi->pubpi.phy_rev, 3) || NREV_IS(pi->pubpi.phy_rev, 4)) - pi->n_preamble_override = WLC_N_PREAMBLE_MIXEDMODE; - - pi->nphy_txrx_chain = AUTO; - pi->phy_scraminit = AUTO; - - pi->nphy_rxcalparams = 0x010100B5; - - pi->nphy_perical = PHY_PERICAL_MPHASE; - pi->mphase_cal_phase_id = MPHASE_CAL_STATE_IDLE; - pi->mphase_txcal_numcmds = MPHASE_TXCAL_NUMCMDS; - - pi->nphy_gain_boost = true; - pi->nphy_elna_gain_config = false; - pi->radio_is_on = false; - - for (i = 0; i < pi->pubpi.phy_corenum; i++) { - pi->nphy_txpwrindex[i].index = AUTO; - } - - wlc_phy_txpwrctrl_config_nphy(pi); - if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON) - pi->hwpwrctrl_capable = true; - - pi->pi_fptr.init = wlc_phy_init_nphy; - pi->pi_fptr.calinit = wlc_phy_cal_init_nphy; - pi->pi_fptr.chanset = wlc_phy_chanspec_set_nphy; - pi->pi_fptr.txpwrrecalc = wlc_phy_txpower_recalc_target_nphy; - - if (!wlc_phy_txpwr_srom_read_nphy(pi)) - return false; - - return true; -} - -static void wlc_phy_txpwrctrl_config_nphy(phy_info_t *pi) -{ - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - pi->nphy_txpwrctrl = PHY_TPC_HW_ON; - pi->phy_5g_pwrgain = true; - return; - } - - pi->nphy_txpwrctrl = PHY_TPC_HW_OFF; - pi->phy_5g_pwrgain = false; - - if ((pi->sh->boardflags2 & BFL2_TXPWRCTRL_EN) && - NREV_GE(pi->pubpi.phy_rev, 2) && (pi->sh->sromrev >= 4)) - pi->nphy_txpwrctrl = PHY_TPC_HW_ON; - else if ((pi->sh->sromrev >= 4) - && (pi->sh->boardflags2 & BFL2_5G_PWRGAIN)) - pi->phy_5g_pwrgain = true; -} - -void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi) -{ - u16 val; - u16 clip1_ths[2]; - nphy_txgains_t target_gain; - u8 tx_pwr_ctrl_state; - bool do_nphy_cal = false; - uint core; - uint origidx, intr_val; - d11regs_t *regs; - u32 d11_clk_ctl_st; - - core = 0; - - if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN)) { - pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC; - } - - if ((ISNPHY(pi)) && (NREV_GE(pi->pubpi.phy_rev, 5)) && - ((pi->sh->chippkg == BCM4717_PKG_ID) || - (pi->sh->chippkg == BCM4718_PKG_ID))) { - if ((pi->sh->boardflags & BFL_EXTLNA) && - (CHSPEC_IS2G(pi->radio_chanspec))) { - si_corereg(pi->sh->sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol), 0x40, - 0x40); - } - } - - if ((!PHY_IPA(pi)) && (pi->sh->chip == BCM5357_CHIP_ID)) { - si_pmu_chipcontrol(pi->sh->sih, 1, CCTRL5357_EXTPA, - CCTRL5357_EXTPA); - } - - if ((pi->nphy_gband_spurwar2_en) && CHSPEC_IS2G(pi->radio_chanspec) && - CHSPEC_IS40(pi->radio_chanspec)) { - - regs = (d11regs_t *) si_switch_core(pi->sh->sih, D11_CORE_ID, - &origidx, &intr_val); - ASSERT(regs != NULL); - - d11_clk_ctl_st = R_REG(pi->sh->osh, ®s->clk_ctl_st); - AND_REG(pi->sh->osh, ®s->clk_ctl_st, - ~(CCS_FORCEHT | CCS_HTAREQ)); - - W_REG(pi->sh->osh, ®s->clk_ctl_st, d11_clk_ctl_st); - - si_restore_core(pi->sh->sih, origidx, intr_val); - } - - pi->use_int_tx_iqlo_cal_nphy = - (PHY_IPA(pi) || - (NREV_GE(pi->pubpi.phy_rev, 7) || - (NREV_GE(pi->pubpi.phy_rev, 5) - && pi->sh->boardflags2 & BFL2_INTERNDET_TXIQCAL))); - - pi->internal_tx_iqlo_cal_tapoff_intpa_nphy = false; - - pi->nphy_deaf_count = 0; - - wlc_phy_tbl_init_nphy(pi); - - pi->nphy_crsminpwr_adjusted = false; - pi->nphy_noisevars_adjusted = false; - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - write_phy_reg(pi, 0xe7, 0); - write_phy_reg(pi, 0xec, 0); - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - write_phy_reg(pi, 0x342, 0); - write_phy_reg(pi, 0x343, 0); - write_phy_reg(pi, 0x346, 0); - write_phy_reg(pi, 0x347, 0); - } - write_phy_reg(pi, 0xe5, 0); - write_phy_reg(pi, 0xe6, 0); - } else { - write_phy_reg(pi, 0xec, 0); - } - - write_phy_reg(pi, 0x91, 0); - write_phy_reg(pi, 0x92, 0); - if (NREV_LT(pi->pubpi.phy_rev, 6)) { - write_phy_reg(pi, 0x93, 0); - write_phy_reg(pi, 0x94, 0); - } - - and_phy_reg(pi, 0xa1, ~3); - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - write_phy_reg(pi, 0x8f, 0); - write_phy_reg(pi, 0xa5, 0); - } else { - write_phy_reg(pi, 0xa5, 0); - } - - if (NREV_IS(pi->pubpi.phy_rev, 2)) - mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b); - else if (NREV_LT(pi->pubpi.phy_rev, 2)) - mod_phy_reg(pi, 0xdc, 0x00ff, 0x40); - - write_phy_reg(pi, 0x203, 32); - write_phy_reg(pi, 0x201, 32); - - if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD) - write_phy_reg(pi, 0x20d, 160); - else - write_phy_reg(pi, 0x20d, 184); - - write_phy_reg(pi, 0x13a, 200); - - write_phy_reg(pi, 0x70, 80); - - write_phy_reg(pi, 0x1ff, 48); - - if (NREV_LT(pi->pubpi.phy_rev, 8)) { - wlc_phy_update_mimoconfig_nphy(pi, pi->n_preamble_override); - } - - wlc_phy_stf_chain_upd_nphy(pi); - - if (NREV_LT(pi->pubpi.phy_rev, 2)) { - write_phy_reg(pi, 0x180, 0xaa8); - write_phy_reg(pi, 0x181, 0x9a4); - } - - if (PHY_IPA(pi)) { - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (1) << 0); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x298 : - 0x29c, (0x1ff << 7), - (pi->nphy_papd_epsilon_offset[core]) << 7); - - } - - wlc_phy_ipa_set_tx_digi_filts_nphy(pi); - } else { - - if (NREV_GE(pi->pubpi.phy_rev, 5)) { - wlc_phy_extpa_set_tx_digi_filts_nphy(pi); - } - } - - wlc_phy_workarounds_nphy(pi); - - wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON); - - val = read_phy_reg(pi, 0x01); - write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA); - write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA)); - wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF); - - wlapi_bmac_macphyclk_set(pi->sh->physhim, ON); - - wlc_phy_pa_override_nphy(pi, OFF); - wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX); - wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); - wlc_phy_pa_override_nphy(pi, ON); - - wlc_phy_classifier_nphy(pi, 0, 0); - wlc_phy_clip_det_nphy(pi, 0, clip1_ths); - - if (CHSPEC_IS2G(pi->radio_chanspec)) - wlc_phy_bphy_init_nphy(pi); - - tx_pwr_ctrl_state = pi->nphy_txpwrctrl; - wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF); - - wlc_phy_txpwr_fixpower_nphy(pi); - - wlc_phy_txpwrctrl_idle_tssi_nphy(pi); - - wlc_phy_txpwrctrl_pwr_setup_nphy(pi); - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - u32 *tx_pwrctrl_tbl = NULL; - u16 idx; - s16 pga_gn = 0; - s16 pad_gn = 0; - s32 rfpwr_offset = 0; - - if (PHY_IPA(pi)) { - tx_pwrctrl_tbl = wlc_phy_get_ipa_gaintbl_nphy(pi); - } else { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - if NREV_IS - (pi->pubpi.phy_rev, 3) { - tx_pwrctrl_tbl = - nphy_tpc_5GHz_txgain_rev3; - } else if NREV_IS - (pi->pubpi.phy_rev, 4) { - tx_pwrctrl_tbl = - (pi->srom_fem5g.extpagain == 3) ? - nphy_tpc_5GHz_txgain_HiPwrEPA : - nphy_tpc_5GHz_txgain_rev4; - } else { - tx_pwrctrl_tbl = - nphy_tpc_5GHz_txgain_rev5; - } - - } else { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if (pi->pubpi.radiorev == 5) { - tx_pwrctrl_tbl = - nphy_tpc_txgain_epa_2057rev5; - } else if (pi->pubpi.radiorev == 3) { - tx_pwrctrl_tbl = - nphy_tpc_txgain_epa_2057rev3; - } - - } else { - if (NREV_GE(pi->pubpi.phy_rev, 5) && - (pi->srom_fem2g.extpagain == 3)) { - tx_pwrctrl_tbl = - nphy_tpc_txgain_HiPwrEPA; - } else { - tx_pwrctrl_tbl = - nphy_tpc_txgain_rev3; - } - } - } - } - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128, - 192, 32, tx_pwrctrl_tbl); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128, - 192, 32, tx_pwrctrl_tbl); - - pi->nphy_gmval = (u16) ((*tx_pwrctrl_tbl >> 16) & 0x7000); - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - for (idx = 0; idx < 128; idx++) { - pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf; - pad_gn = (tx_pwrctrl_tbl[idx] >> 19) & 0x1f; - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if ((pi->pubpi.radiorev == 3) || - (pi->pubpi.radiorev == 4) || - (pi->pubpi.radiorev == 6)) { - rfpwr_offset = (s16) - nphy_papd_padgain_dlt_2g_2057rev3n4 - [pad_gn]; - } else if (pi->pubpi.radiorev == 5) { - rfpwr_offset = (s16) - nphy_papd_padgain_dlt_2g_2057rev5 - [pad_gn]; - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == - 8)) { - rfpwr_offset = (s16) - nphy_papd_padgain_dlt_2g_2057rev7 - [pad_gn]; - } else { - ASSERT(0); - } - - } else { - if ((pi->pubpi.radiorev == 3) || - (pi->pubpi.radiorev == 4) || - (pi->pubpi.radiorev == 6)) { - rfpwr_offset = (s16) - nphy_papd_pgagain_dlt_5g_2057 - [pga_gn]; - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == - 8)) { - rfpwr_offset = (s16) - nphy_papd_pgagain_dlt_5g_2057rev7 - [pga_gn]; - } else { - ASSERT(0); - } - } - wlc_phy_table_write_nphy(pi, - NPHY_TBL_ID_CORE1TXPWRCTL, - 1, 576 + idx, 32, - &rfpwr_offset); - wlc_phy_table_write_nphy(pi, - NPHY_TBL_ID_CORE2TXPWRCTL, - 1, 576 + idx, 32, - &rfpwr_offset); - } - } else { - - for (idx = 0; idx < 128; idx++) { - pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf; - if (CHSPEC_IS2G(pi->radio_chanspec)) { - rfpwr_offset = (s16) - nphy_papd_pga_gain_delta_ipa_2g - [pga_gn]; - } else { - rfpwr_offset = (s16) - nphy_papd_pga_gain_delta_ipa_5g - [pga_gn]; - } - - wlc_phy_table_write_nphy(pi, - NPHY_TBL_ID_CORE1TXPWRCTL, - 1, 576 + idx, 32, - &rfpwr_offset); - wlc_phy_table_write_nphy(pi, - NPHY_TBL_ID_CORE2TXPWRCTL, - 1, 576 + idx, 32, - &rfpwr_offset); - } - - } - } else { - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128, - 192, 32, nphy_tpc_txgain); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128, - 192, 32, nphy_tpc_txgain); - } - - if (pi->sh->phyrxchain != 0x3) { - wlc_phy_rxcore_setstate_nphy((wlc_phy_t *) pi, - pi->sh->phyrxchain); - } - - if (PHY_PERICAL_MPHASE_PENDING(pi)) { - wlc_phy_cal_perical_mphase_restart(pi); - } - - if (!NORADIO_ENAB(pi->pubpi)) { - bool do_rssi_cal = false; - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - do_rssi_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ? - (pi->nphy_rssical_chanspec_2G == 0) : - (pi->nphy_rssical_chanspec_5G == 0); - - if (do_rssi_cal) { - wlc_phy_rssi_cal_nphy(pi); - } else { - wlc_phy_restore_rssical_nphy(pi); - } - } else { - wlc_phy_rssi_cal_nphy(pi); - } - - if (!SCAN_RM_IN_PROGRESS(pi)) { - do_nphy_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ? - (pi->nphy_iqcal_chanspec_2G == 0) : - (pi->nphy_iqcal_chanspec_5G == 0); - } - - if (!pi->do_initcal) - do_nphy_cal = false; - - if (do_nphy_cal) { - - target_gain = wlc_phy_get_tx_gain_nphy(pi); - - if (pi->antsel_type == ANTSEL_2x3) - wlc_phy_antsel_init((wlc_phy_t *) pi, true); - - if (pi->nphy_perical != PHY_PERICAL_MPHASE) { - wlc_phy_rssi_cal_nphy(pi); - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - pi->nphy_cal_orig_pwr_idx[0] = - pi->nphy_txpwrindex[PHY_CORE_0]. - index_internal; - pi->nphy_cal_orig_pwr_idx[1] = - pi->nphy_txpwrindex[PHY_CORE_1]. - index_internal; - - wlc_phy_precal_txgain_nphy(pi); - target_gain = - wlc_phy_get_tx_gain_nphy(pi); - } - - if (wlc_phy_cal_txiqlo_nphy - (pi, target_gain, true, false) == BCME_OK) { - if (wlc_phy_cal_rxiq_nphy - (pi, target_gain, 2, - false) == BCME_OK) { - wlc_phy_savecal_nphy(pi); - - } - } - } else if (pi->mphase_cal_phase_id == - MPHASE_CAL_STATE_IDLE) { - - wlc_phy_cal_perical((wlc_phy_t *) pi, - PHY_PERICAL_PHYINIT); - } - } else { - wlc_phy_restorecal_nphy(pi); - } - } - - wlc_phy_txpwrctrl_coeff_setup_nphy(pi); - - wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state); - - wlc_phy_nphy_tkip_rifs_war(pi, pi->sh->_rifs_phy); - - if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LE(pi->pubpi.phy_rev, 6)) - - write_phy_reg(pi, 0x70, 50); - - wlc_phy_txlpfbw_nphy(pi); - - wlc_phy_spurwar_nphy(pi); - -} - -static void wlc_phy_update_mimoconfig_nphy(phy_info_t *pi, s32 preamble) -{ - bool gf_preamble = false; - u16 val; - - if (preamble == WLC_N_PREAMBLE_GF) { - gf_preamble = true; - } - - val = read_phy_reg(pi, 0xed); - - val |= RX_GF_MM_AUTO; - val &= ~RX_GF_OR_MM; - if (gf_preamble) - val |= RX_GF_OR_MM; - - write_phy_reg(pi, 0xed, val); -} - -static void wlc_phy_resetcca_nphy(phy_info_t *pi) -{ - u16 val; - - ASSERT(0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); - - wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON); - - val = read_phy_reg(pi, 0x01); - write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA); - udelay(1); - write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA)); - - wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF); - - wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); -} - -void wlc_phy_pa_override_nphy(phy_info_t *pi, bool en) -{ - u16 rfctrlintc_override_val; - - if (!en) { - - pi->rfctrlIntc1_save = read_phy_reg(pi, 0x91); - pi->rfctrlIntc2_save = read_phy_reg(pi, 0x92); - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - rfctrlintc_override_val = 0x1480; - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - rfctrlintc_override_val = - CHSPEC_IS5G(pi->radio_chanspec) ? 0x600 : 0x480; - } else { - rfctrlintc_override_val = - CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120; - } - - write_phy_reg(pi, 0x91, rfctrlintc_override_val); - write_phy_reg(pi, 0x92, rfctrlintc_override_val); - } else { - - write_phy_reg(pi, 0x91, pi->rfctrlIntc1_save); - write_phy_reg(pi, 0x92, pi->rfctrlIntc2_save); - } - -} - -void wlc_phy_stf_chain_upd_nphy(phy_info_t *pi) -{ - - u16 txrx_chain = - (NPHY_RfseqCoreActv_TxRxChain0 | NPHY_RfseqCoreActv_TxRxChain1); - bool CoreActv_override = false; - - if (pi->nphy_txrx_chain == WLC_N_TXRX_CHAIN0) { - txrx_chain = NPHY_RfseqCoreActv_TxRxChain0; - CoreActv_override = true; - - if (NREV_LE(pi->pubpi.phy_rev, 2)) { - and_phy_reg(pi, 0xa0, ~0x20); - } - } else if (pi->nphy_txrx_chain == WLC_N_TXRX_CHAIN1) { - txrx_chain = NPHY_RfseqCoreActv_TxRxChain1; - CoreActv_override = true; - - if (NREV_LE(pi->pubpi.phy_rev, 2)) { - or_phy_reg(pi, 0xa0, 0x20); - } - } - - mod_phy_reg(pi, 0xa2, ((0xf << 0) | (0xf << 4)), txrx_chain); - - if (CoreActv_override) { - - pi->nphy_perical = PHY_PERICAL_DISABLE; - or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override); - } else { - pi->nphy_perical = PHY_PERICAL_MPHASE; - and_phy_reg(pi, 0xa1, ~NPHY_RfseqMode_CoreActv_override); - } -} - -void wlc_phy_rxcore_setstate_nphy(wlc_phy_t *pih, u8 rxcore_bitmask) -{ - u16 regval; - u16 tbl_buf[16]; - uint i; - phy_info_t *pi = (phy_info_t *) pih; - u16 tbl_opcode; - bool suspend; - - pi->sh->phyrxchain = rxcore_bitmask; - - if (!pi->sh->clk) - return; - - suspend = - (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); - if (!suspend) - wlapi_suspend_mac_and_wait(pi->sh->physhim); - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - regval = read_phy_reg(pi, 0xa2); - regval &= ~(0xf << 4); - regval |= ((u16) (rxcore_bitmask & 0x3)) << 4; - write_phy_reg(pi, 0xa2, regval); - - if ((rxcore_bitmask & 0x3) != 0x3) { - - write_phy_reg(pi, 0x20e, 1); - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if (pi->rx2tx_biasentry == -1) { - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, - ARRAY_SIZE(tbl_buf), 80, - 16, tbl_buf); - - for (i = 0; i < ARRAY_SIZE(tbl_buf); i++) { - if (tbl_buf[i] == - NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS) { - - pi->rx2tx_biasentry = (u8) i; - tbl_opcode = - NPHY_REV3_RFSEQ_CMD_NOP; - wlc_phy_table_write_nphy(pi, - NPHY_TBL_ID_RFSEQ, - 1, i, - 16, - &tbl_opcode); - break; - } else if (tbl_buf[i] == - NPHY_REV3_RFSEQ_CMD_END) { - break; - } - } - } - } - } else { - - write_phy_reg(pi, 0x20e, 30); - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if (pi->rx2tx_biasentry != -1) { - tbl_opcode = NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 1, pi->rx2tx_biasentry, - 16, &tbl_opcode); - pi->rx2tx_biasentry = -1; - } - } - } - - wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); - - if (!suspend) - wlapi_enable_mac(pi->sh->physhim); -} - -u8 wlc_phy_rxcore_getstate_nphy(wlc_phy_t *pih) -{ - u16 regval, rxen_bits; - phy_info_t *pi = (phy_info_t *) pih; - - regval = read_phy_reg(pi, 0xa2); - rxen_bits = (regval >> 4) & 0xf; - - return (u8) rxen_bits; -} - -bool wlc_phy_n_txpower_ipa_ison(phy_info_t *pi) -{ - return PHY_IPA(pi); -} - -static void wlc_phy_txpwr_limit_to_tbl_nphy(phy_info_t *pi) -{ - u8 idx, idx2, i, delta_ind; - - for (idx = TXP_FIRST_CCK; idx <= TXP_LAST_CCK; idx++) { - pi->adj_pwr_tbl_nphy[idx] = pi->tx_power_offset[idx]; - } - - for (i = 0; i < 4; i++) { - idx2 = 0; - - delta_ind = 0; - - switch (i) { - case 0: - - if (CHSPEC_IS40(pi->radio_chanspec) - && NPHY_IS_SROM_REINTERPRET) { - idx = TXP_FIRST_MCS_40_SISO; - } else { - idx = (CHSPEC_IS40(pi->radio_chanspec)) ? - TXP_FIRST_OFDM_40_SISO : TXP_FIRST_OFDM; - delta_ind = 1; - } - break; - - case 1: - - idx = (CHSPEC_IS40(pi->radio_chanspec)) ? - TXP_FIRST_MCS_40_CDD : TXP_FIRST_MCS_20_CDD; - break; - - case 2: - - idx = (CHSPEC_IS40(pi->radio_chanspec)) ? - TXP_FIRST_MCS_40_STBC : TXP_FIRST_MCS_20_STBC; - break; - - case 3: - - idx = (CHSPEC_IS40(pi->radio_chanspec)) ? - TXP_FIRST_MCS_40_SDM : TXP_FIRST_MCS_20_SDM; - break; - } - - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - idx = idx + delta_ind; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx++]; - - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx++]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx++]; - - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx++]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx++]; - - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx++]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - idx = idx + 1 - delta_ind; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - } -} - -void wlc_phy_cal_init_nphy(phy_info_t *pi) -{ -} - -static void wlc_phy_war_force_trsw_to_R_cliplo_nphy(phy_info_t *pi, u8 core) -{ - if (core == PHY_CORE_0) { - write_phy_reg(pi, 0x38, 0x4); - if (CHSPEC_IS2G(pi->radio_chanspec)) { - write_phy_reg(pi, 0x37, 0x0060); - } else { - write_phy_reg(pi, 0x37, 0x1080); - } - } else if (core == PHY_CORE_1) { - write_phy_reg(pi, 0x2ae, 0x4); - if (CHSPEC_IS2G(pi->radio_chanspec)) { - write_phy_reg(pi, 0x2ad, 0x0060); - } else { - write_phy_reg(pi, 0x2ad, 0x1080); - } - } -} - -static void wlc_phy_war_txchain_upd_nphy(phy_info_t *pi, u8 txchain) -{ - u8 txchain0, txchain1; - - txchain0 = txchain & 0x1; - txchain1 = (txchain & 0x2) >> 1; - if (!txchain0) { - wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0); - } - - if (!txchain1) { - wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1); - } -} - -static void wlc_phy_workarounds_nphy(phy_info_t *pi) -{ - u8 rfseq_rx2tx_events[] = { - NPHY_RFSEQ_CMD_NOP, - NPHY_RFSEQ_CMD_RXG_FBW, - NPHY_RFSEQ_CMD_TR_SWITCH, - NPHY_RFSEQ_CMD_CLR_HIQ_DIS, - NPHY_RFSEQ_CMD_RXPD_TXPD, - NPHY_RFSEQ_CMD_TX_GAIN, - NPHY_RFSEQ_CMD_EXT_PA - }; - u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 }; - u8 rfseq_tx2rx_events[] = { - NPHY_RFSEQ_CMD_NOP, - NPHY_RFSEQ_CMD_EXT_PA, - NPHY_RFSEQ_CMD_TX_GAIN, - NPHY_RFSEQ_CMD_RXPD_TXPD, - NPHY_RFSEQ_CMD_TR_SWITCH, - NPHY_RFSEQ_CMD_RXG_FBW, - NPHY_RFSEQ_CMD_CLR_HIQ_DIS - }; - u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 }; - u8 rfseq_tx2rx_events_rev3[] = { - NPHY_REV3_RFSEQ_CMD_EXT_PA, - NPHY_REV3_RFSEQ_CMD_INT_PA_PU, - NPHY_REV3_RFSEQ_CMD_TX_GAIN, - NPHY_REV3_RFSEQ_CMD_RXPD_TXPD, - NPHY_REV3_RFSEQ_CMD_TR_SWITCH, - NPHY_REV3_RFSEQ_CMD_RXG_FBW, - NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS, - NPHY_REV3_RFSEQ_CMD_END - }; - u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 }; - u8 rfseq_rx2tx_events_rev3[] = { - NPHY_REV3_RFSEQ_CMD_NOP, - NPHY_REV3_RFSEQ_CMD_RXG_FBW, - NPHY_REV3_RFSEQ_CMD_TR_SWITCH, - NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS, - NPHY_REV3_RFSEQ_CMD_RXPD_TXPD, - NPHY_REV3_RFSEQ_CMD_TX_GAIN, - NPHY_REV3_RFSEQ_CMD_INT_PA_PU, - NPHY_REV3_RFSEQ_CMD_EXT_PA, - NPHY_REV3_RFSEQ_CMD_END - }; - u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 }; - - u8 rfseq_rx2tx_events_rev3_ipa[] = { - NPHY_REV3_RFSEQ_CMD_NOP, - NPHY_REV3_RFSEQ_CMD_RXG_FBW, - NPHY_REV3_RFSEQ_CMD_TR_SWITCH, - NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS, - NPHY_REV3_RFSEQ_CMD_RXPD_TXPD, - NPHY_REV3_RFSEQ_CMD_TX_GAIN, - NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS, - NPHY_REV3_RFSEQ_CMD_INT_PA_PU, - NPHY_REV3_RFSEQ_CMD_END - }; - u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 }; - u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f }; - - s16 alpha0, alpha1, alpha2; - s16 beta0, beta1, beta2; - u32 leg_data_weights, ht_data_weights, nss1_data_weights, - stbc_data_weights; - u8 chan_freq_range = 0; - u16 dac_control = 0x0002; - u16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 }; - u16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 }; - u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 }; - u16 aux_adc_vmid_rev3[] = { 0xa2, 0xb4, 0xb4, 0x89 }; - u16 *aux_adc_vmid; - u16 aux_adc_gain_rev7[] = { 0x02, 0x02, 0x02, 0x02 }; - u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 }; - u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 }; - u16 *aux_adc_gain; - u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 }; - u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 }; - s32 min_nvar_val = 0x18d; - s32 min_nvar_offset_6mbps = 20; - u8 pdetrange; - u8 triso; - u16 regval; - u16 afectrl_adc_ctrl1_rev7 = 0x20; - u16 afectrl_adc_ctrl2_rev7 = 0x0; - u16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77; - u16 rfseq_tx2rx_lpf_h_hpc_rev7 = 0x77; - u16 rfseq_pktgn_lpf_h_hpc_rev7 = 0x77; - u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 }; - u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; - u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; - u16 ipalvlshift_3p3_war_en = 0; - u16 rccal_bcap_val, rccal_scap_val; - u16 rccal_tx20_11b_bcap = 0; - u16 rccal_tx20_11b_scap = 0; - u16 rccal_tx20_11n_bcap = 0; - u16 rccal_tx20_11n_scap = 0; - u16 rccal_tx40_11n_bcap = 0; - u16 rccal_tx40_11n_scap = 0; - u16 rx2tx_lpf_rc_lut_tx20_11b = 0; - u16 rx2tx_lpf_rc_lut_tx20_11n = 0; - u16 rx2tx_lpf_rc_lut_tx40_11n = 0; - u16 tx_lpf_bw_ofdm_20mhz = 0; - u16 tx_lpf_bw_ofdm_40mhz = 0; - u16 tx_lpf_bw_11b = 0; - u16 ipa2g_mainbias, ipa2g_casconv, ipa2g_biasfilt; - u16 txgm_idac_bleed = 0; - bool rccal_ovrd = false; - u16 freq; - int coreNum; - - if (CHSPEC_IS5G(pi->radio_chanspec)) { - wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 0); - } else { - wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 1); - } - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - if (!ISSIM_ENAB(pi->sh->sih)) { - or_phy_reg(pi, 0xb1, NPHY_IQFlip_ADC1 | NPHY_IQFlip_ADC2); - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - if (NREV_IS(pi->pubpi.phy_rev, 7)) { - mod_phy_reg(pi, 0x221, (0x1 << 4), (1 << 4)); - - mod_phy_reg(pi, 0x160, (0x7f << 0), (32 << 0)); - mod_phy_reg(pi, 0x160, (0x7f << 8), (39 << 8)); - mod_phy_reg(pi, 0x161, (0x7f << 0), (46 << 0)); - mod_phy_reg(pi, 0x161, (0x7f << 8), (51 << 8)); - mod_phy_reg(pi, 0x162, (0x7f << 0), (55 << 0)); - mod_phy_reg(pi, 0x162, (0x7f << 8), (58 << 8)); - mod_phy_reg(pi, 0x163, (0x7f << 0), (60 << 0)); - mod_phy_reg(pi, 0x163, (0x7f << 8), (62 << 8)); - mod_phy_reg(pi, 0x164, (0x7f << 0), (62 << 0)); - mod_phy_reg(pi, 0x164, (0x7f << 8), (63 << 8)); - mod_phy_reg(pi, 0x165, (0x7f << 0), (63 << 0)); - mod_phy_reg(pi, 0x165, (0x7f << 8), (64 << 8)); - mod_phy_reg(pi, 0x166, (0x7f << 0), (64 << 0)); - mod_phy_reg(pi, 0x166, (0x7f << 8), (64 << 8)); - mod_phy_reg(pi, 0x167, (0x7f << 0), (64 << 0)); - mod_phy_reg(pi, 0x167, (0x7f << 8), (64 << 8)); - } - - if (NREV_LE(pi->pubpi.phy_rev, 8)) { - write_phy_reg(pi, 0x23f, 0x1b0); - write_phy_reg(pi, 0x240, 0x1b0); - } - - if (NREV_GE(pi->pubpi.phy_rev, 8)) { - mod_phy_reg(pi, 0xbd, (0xff << 0), (114 << 0)); - } - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16, - &dac_control); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16, - &dac_control); - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL, - 1, 0, 32, &leg_data_weights); - leg_data_weights = leg_data_weights & 0xffffff; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL, - 1, 0, 32, &leg_data_weights); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 2, 0x15e, 16, - rfseq_rx2tx_dacbufpu_rev7); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x16e, 16, - rfseq_rx2tx_dacbufpu_rev7); - - if (PHY_IPA(pi)) { - wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, - rfseq_rx2tx_events_rev3_ipa, - rfseq_rx2tx_dlys_rev3_ipa, - sizeof - (rfseq_rx2tx_events_rev3_ipa) / - sizeof - (rfseq_rx2tx_events_rev3_ipa - [0])); - } - - mod_phy_reg(pi, 0x299, (0x3 << 14), (0x1 << 14)); - mod_phy_reg(pi, 0x29d, (0x3 << 14), (0x1 << 14)); - - tx_lpf_bw_ofdm_20mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x154); - tx_lpf_bw_ofdm_40mhz = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x159); - tx_lpf_bw_11b = wlc_phy_read_lpf_bw_ctl_nphy(pi, 0x152); - - if (PHY_IPA(pi)) { - - if (((pi->pubpi.radiorev == 5) - && (CHSPEC_IS40(pi->radio_chanspec) == 1)) - || (pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - - rccal_bcap_val = - read_radio_reg(pi, - RADIO_2057_RCCAL_BCAP_VAL); - rccal_scap_val = - read_radio_reg(pi, - RADIO_2057_RCCAL_SCAP_VAL); - - rccal_tx20_11b_bcap = rccal_bcap_val; - rccal_tx20_11b_scap = rccal_scap_val; - - if ((pi->pubpi.radiorev == 5) && - (CHSPEC_IS40(pi->radio_chanspec) == 1)) { - - rccal_tx20_11n_bcap = rccal_bcap_val; - rccal_tx20_11n_scap = rccal_scap_val; - rccal_tx40_11n_bcap = 0xc; - rccal_tx40_11n_scap = 0xc; - - rccal_ovrd = true; - - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - - tx_lpf_bw_ofdm_20mhz = 4; - tx_lpf_bw_11b = 1; - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - rccal_tx20_11n_bcap = 0xc; - rccal_tx20_11n_scap = 0xc; - rccal_tx40_11n_bcap = 0xa; - rccal_tx40_11n_scap = 0xa; - } else { - rccal_tx20_11n_bcap = 0x14; - rccal_tx20_11n_scap = 0x14; - rccal_tx40_11n_bcap = 0xf; - rccal_tx40_11n_scap = 0xf; - } - - rccal_ovrd = true; - } - } - - } else { - - if (pi->pubpi.radiorev == 5) { - - tx_lpf_bw_ofdm_20mhz = 1; - tx_lpf_bw_ofdm_40mhz = 3; - - rccal_bcap_val = - read_radio_reg(pi, - RADIO_2057_RCCAL_BCAP_VAL); - rccal_scap_val = - read_radio_reg(pi, - RADIO_2057_RCCAL_SCAP_VAL); - - rccal_tx20_11b_bcap = rccal_bcap_val; - rccal_tx20_11b_scap = rccal_scap_val; - - rccal_tx20_11n_bcap = 0x13; - rccal_tx20_11n_scap = 0x11; - rccal_tx40_11n_bcap = 0x13; - rccal_tx40_11n_scap = 0x11; - - rccal_ovrd = true; - } - } - - if (rccal_ovrd) { - - rx2tx_lpf_rc_lut_tx20_11b = (rccal_tx20_11b_bcap << 8) | - (rccal_tx20_11b_scap << 3) | tx_lpf_bw_11b; - rx2tx_lpf_rc_lut_tx20_11n = (rccal_tx20_11n_bcap << 8) | - (rccal_tx20_11n_scap << 3) | tx_lpf_bw_ofdm_20mhz; - rx2tx_lpf_rc_lut_tx40_11n = (rccal_tx40_11n_bcap << 8) | - (rccal_tx40_11n_scap << 3) | tx_lpf_bw_ofdm_40mhz; - - for (coreNum = 0; coreNum <= 1; coreNum++) { - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 1, - 0x152 + coreNum * 0x10, - 16, - &rx2tx_lpf_rc_lut_tx20_11b); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 1, - 0x153 + coreNum * 0x10, - 16, - &rx2tx_lpf_rc_lut_tx20_11n); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 1, - 0x154 + coreNum * 0x10, - 16, - &rx2tx_lpf_rc_lut_tx20_11n); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 1, - 0x155 + coreNum * 0x10, - 16, - &rx2tx_lpf_rc_lut_tx40_11n); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 1, - 0x156 + coreNum * 0x10, - 16, - &rx2tx_lpf_rc_lut_tx40_11n); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 1, - 0x157 + coreNum * 0x10, - 16, - &rx2tx_lpf_rc_lut_tx40_11n); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 1, - 0x158 + coreNum * 0x10, - 16, - &rx2tx_lpf_rc_lut_tx40_11n); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 1, - 0x159 + coreNum * 0x10, - 16, - &rx2tx_lpf_rc_lut_tx40_11n); - } - - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), - 1, 0x3, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID2); - } - - if (!NORADIO_ENAB(pi->pubpi)) { - write_phy_reg(pi, 0x32f, 0x3); - } - - if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), - 1, 0x3, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - } - - if ((pi->pubpi.radiorev == 3) || (pi->pubpi.radiorev == 4) || - (pi->pubpi.radiorev == 6)) { - if ((pi->sh->sromrev >= 8) - && (pi->sh->boardflags2 & BFL2_IPALVLSHIFT_3P3)) - ipalvlshift_3p3_war_en = 1; - - if (ipalvlshift_3p3_war_en) { - write_radio_reg(pi, RADIO_2057_GPAIO_CONFIG, - 0x5); - write_radio_reg(pi, RADIO_2057_GPAIO_SEL1, - 0x30); - write_radio_reg(pi, RADIO_2057_GPAIO_SEL0, 0x0); - or_radio_reg(pi, - RADIO_2057_RXTXBIAS_CONFIG_CORE0, - 0x1); - or_radio_reg(pi, - RADIO_2057_RXTXBIAS_CONFIG_CORE1, - 0x1); - - ipa2g_mainbias = 0x1f; - - ipa2g_casconv = 0x6f; - - ipa2g_biasfilt = 0xaa; - } else { - - ipa2g_mainbias = 0x2b; - - ipa2g_casconv = 0x7f; - - ipa2g_biasfilt = 0xee; - } - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - for (coreNum = 0; coreNum <= 1; coreNum++) { - WRITE_RADIO_REG4(pi, RADIO_2057, CORE, - coreNum, IPA2G_IMAIN, - ipa2g_mainbias); - WRITE_RADIO_REG4(pi, RADIO_2057, CORE, - coreNum, IPA2G_CASCONV, - ipa2g_casconv); - WRITE_RADIO_REG4(pi, RADIO_2057, CORE, - coreNum, - IPA2G_BIAS_FILTER, - ipa2g_biasfilt); - } - } - } - - if (PHY_IPA(pi)) { - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if ((pi->pubpi.radiorev == 3) - || (pi->pubpi.radiorev == 4) - || (pi->pubpi.radiorev == 6)) { - - txgm_idac_bleed = 0x7f; - } - - for (coreNum = 0; coreNum <= 1; coreNum++) { - if (txgm_idac_bleed != 0) - WRITE_RADIO_REG4(pi, RADIO_2057, - CORE, coreNum, - TXGM_IDAC_BLEED, - txgm_idac_bleed); - } - - if (pi->pubpi.radiorev == 5) { - - for (coreNum = 0; coreNum <= 1; - coreNum++) { - WRITE_RADIO_REG4(pi, RADIO_2057, - CORE, coreNum, - IPA2G_CASCONV, - 0x13); - WRITE_RADIO_REG4(pi, RADIO_2057, - CORE, coreNum, - IPA2G_IMAIN, - 0x1f); - WRITE_RADIO_REG4(pi, RADIO_2057, - CORE, coreNum, - IPA2G_BIAS_FILTER, - 0xee); - WRITE_RADIO_REG4(pi, RADIO_2057, - CORE, coreNum, - PAD2G_IDACS, - 0x8a); - WRITE_RADIO_REG4(pi, RADIO_2057, - CORE, coreNum, - PAD_BIAS_FILTER_BWS, - 0x3e); - } - - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - - if (CHSPEC_IS40(pi->radio_chanspec) == - 0) { - WRITE_RADIO_REG4(pi, RADIO_2057, - CORE, 0, - IPA2G_IMAIN, - 0x14); - WRITE_RADIO_REG4(pi, RADIO_2057, - CORE, 1, - IPA2G_IMAIN, - 0x12); - } else { - WRITE_RADIO_REG4(pi, RADIO_2057, - CORE, 0, - IPA2G_IMAIN, - 0x16); - WRITE_RADIO_REG4(pi, RADIO_2057, - CORE, 1, - IPA2G_IMAIN, - 0x16); - } - } - - } else { - freq = - CHAN5G_FREQ(CHSPEC_CHANNEL - (pi->radio_chanspec)); - if (((freq >= 5180) && (freq <= 5230)) - || ((freq >= 5745) && (freq <= 5805))) { - WRITE_RADIO_REG4(pi, RADIO_2057, CORE, - 0, IPA5G_BIAS_FILTER, - 0xff); - WRITE_RADIO_REG4(pi, RADIO_2057, CORE, - 1, IPA5G_BIAS_FILTER, - 0xff); - } - } - } else { - - if (pi->pubpi.radiorev != 5) { - for (coreNum = 0; coreNum <= 1; coreNum++) { - WRITE_RADIO_REG4(pi, RADIO_2057, CORE, - coreNum, - TXMIX2G_TUNE_BOOST_PU, - 0x61); - WRITE_RADIO_REG4(pi, RADIO_2057, CORE, - coreNum, - TXGM_IDAC_BLEED, 0x70); - } - } - } - - if (pi->pubpi.radiorev == 4) { - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, - 0x05, 16, - &afectrl_adc_ctrl1_rev7); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, - 0x15, 16, - &afectrl_adc_ctrl1_rev7); - - for (coreNum = 0; coreNum <= 1; coreNum++) { - WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum, - AFE_VCM_CAL_MASTER, 0x0); - WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum, - AFE_SET_VCM_I, 0x3f); - WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum, - AFE_SET_VCM_Q, 0x3f); - } - } else { - mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2)); - mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2)); - mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2)); - mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2)); - - mod_phy_reg(pi, 0xa6, (0x1 << 0), 0); - mod_phy_reg(pi, 0x8f, (0x1 << 0), (0x1 << 0)); - mod_phy_reg(pi, 0xa7, (0x1 << 0), 0); - mod_phy_reg(pi, 0xa5, (0x1 << 0), (0x1 << 0)); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, - 0x05, 16, - &afectrl_adc_ctrl2_rev7); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, - 0x15, 16, - &afectrl_adc_ctrl2_rev7); - - mod_phy_reg(pi, 0xa6, (0x1 << 2), 0); - mod_phy_reg(pi, 0x8f, (0x1 << 2), 0); - mod_phy_reg(pi, 0xa7, (0x1 << 2), 0); - mod_phy_reg(pi, 0xa5, (0x1 << 2), 0); - } - - write_phy_reg(pi, 0x6a, 0x2); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 256, 32, - &min_nvar_offset_6mbps); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x138, 16, - &rfseq_pktgn_lpf_hpc_rev7); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x141, 16, - &rfseq_pktgn_lpf_h_hpc_rev7); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 3, 0x133, 16, - &rfseq_htpktgn_lpf_hpc_rev7); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x146, 16, - &rfseq_cckpktgn_lpf_hpc_rev7); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x123, 16, - &rfseq_tx2rx_lpf_h_hpc_rev7); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, 0x12A, 16, - &rfseq_rx2tx_lpf_h_hpc_rev7); - - if (CHSPEC_IS40(pi->radio_chanspec) == 0) { - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3, - 32, &min_nvar_val); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, - 127, 32, &min_nvar_val); - } else { - min_nvar_val = noise_var_tbl_rev7[3]; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3, - 32, &min_nvar_val); - - min_nvar_val = noise_var_tbl_rev7[127]; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, - 127, 32, &min_nvar_val); - } - - wlc_phy_workarounds_nphy_gainctrl(pi); - - pdetrange = - (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g. - pdetrange : pi->srom_fem2g.pdetrange; - - if (pdetrange == 0) { - chan_freq_range = - wlc_phy_get_chan_freq_range_nphy(pi, 0); - if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) { - aux_adc_vmid_rev7_core0[3] = 0x70; - aux_adc_vmid_rev7_core1[3] = 0x70; - aux_adc_gain_rev7[3] = 2; - } else { - aux_adc_vmid_rev7_core0[3] = 0x80; - aux_adc_vmid_rev7_core1[3] = 0x80; - aux_adc_gain_rev7[3] = 3; - } - } else if (pdetrange == 1) { - if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) { - aux_adc_vmid_rev7_core0[3] = 0x7c; - aux_adc_vmid_rev7_core1[3] = 0x7c; - aux_adc_gain_rev7[3] = 2; - } else { - aux_adc_vmid_rev7_core0[3] = 0x8c; - aux_adc_vmid_rev7_core1[3] = 0x8c; - aux_adc_gain_rev7[3] = 1; - } - } else if (pdetrange == 2) { - if (pi->pubpi.radioid == BCM2057_ID) { - if ((pi->pubpi.radiorev == 5) - || (pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - if (chan_freq_range == - WL_CHAN_FREQ_RANGE_2G) { - aux_adc_vmid_rev7_core0[3] = - 0x8c; - aux_adc_vmid_rev7_core1[3] = - 0x8c; - aux_adc_gain_rev7[3] = 0; - } else { - aux_adc_vmid_rev7_core0[3] = - 0x96; - aux_adc_vmid_rev7_core1[3] = - 0x96; - aux_adc_gain_rev7[3] = 0; - } - } - } - - } else if (pdetrange == 3) { - if (chan_freq_range == WL_CHAN_FREQ_RANGE_2G) { - aux_adc_vmid_rev7_core0[3] = 0x89; - aux_adc_vmid_rev7_core1[3] = 0x89; - aux_adc_gain_rev7[3] = 0; - } - - } else if (pdetrange == 5) { - - if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) { - aux_adc_vmid_rev7_core0[3] = 0x80; - aux_adc_vmid_rev7_core1[3] = 0x80; - aux_adc_gain_rev7[3] = 3; - } else { - aux_adc_vmid_rev7_core0[3] = 0x70; - aux_adc_vmid_rev7_core1[3] = 0x70; - aux_adc_gain_rev7[3] = 2; - } - } - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x08, 16, - &aux_adc_vmid_rev7_core0); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x18, 16, - &aux_adc_vmid_rev7_core1); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x0c, 16, - &aux_adc_gain_rev7); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, 0x1c, 16, - &aux_adc_gain_rev7); - - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - - write_phy_reg(pi, 0x23f, 0x1f8); - write_phy_reg(pi, 0x240, 0x1f8); - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL, - 1, 0, 32, &leg_data_weights); - leg_data_weights = leg_data_weights & 0xffffff; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL, - 1, 0, 32, &leg_data_weights); - - alpha0 = 293; - alpha1 = 435; - alpha2 = 261; - beta0 = 366; - beta1 = 205; - beta2 = 32; - write_phy_reg(pi, 0x145, alpha0); - write_phy_reg(pi, 0x146, alpha1); - write_phy_reg(pi, 0x147, alpha2); - write_phy_reg(pi, 0x148, beta0); - write_phy_reg(pi, 0x149, beta1); - write_phy_reg(pi, 0x14a, beta2); - - write_phy_reg(pi, 0x38, 0xC); - write_phy_reg(pi, 0x2ae, 0xC); - - wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX, - rfseq_tx2rx_events_rev3, - rfseq_tx2rx_dlys_rev3, - sizeof(rfseq_tx2rx_events_rev3) / - sizeof(rfseq_tx2rx_events_rev3[0])); - - if (PHY_IPA(pi)) { - wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, - rfseq_rx2tx_events_rev3_ipa, - rfseq_rx2tx_dlys_rev3_ipa, - sizeof - (rfseq_rx2tx_events_rev3_ipa) / - sizeof - (rfseq_rx2tx_events_rev3_ipa - [0])); - } - - if ((pi->sh->hw_phyrxchain != 0x3) && - (pi->sh->hw_phyrxchain != pi->sh->hw_phytxchain)) { - - if (PHY_IPA(pi)) { - rfseq_rx2tx_dlys_rev3[5] = 59; - rfseq_rx2tx_dlys_rev3[6] = 1; - rfseq_rx2tx_events_rev3[7] = - NPHY_REV3_RFSEQ_CMD_END; - } - - wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, - rfseq_rx2tx_events_rev3, - rfseq_rx2tx_dlys_rev3, - sizeof(rfseq_rx2tx_events_rev3) / - sizeof(rfseq_rx2tx_events_rev3 - [0])); - } - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - write_phy_reg(pi, 0x6a, 0x2); - } else { - write_phy_reg(pi, 0x6a, 0x9c40); - } - - mod_phy_reg(pi, 0x294, (0xf << 8), (7 << 8)); - - if (CHSPEC_IS40(pi->radio_chanspec) == 0) { - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3, - 32, &min_nvar_val); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, - 127, 32, &min_nvar_val); - } else { - min_nvar_val = noise_var_tbl_rev3[3]; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, 3, - 32, &min_nvar_val); - - min_nvar_val = noise_var_tbl_rev3[127]; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, - 127, 32, &min_nvar_val); - } - - wlc_phy_workarounds_nphy_gainctrl(pi); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16, - &dac_control); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x10, 16, - &dac_control); - - pdetrange = - (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g. - pdetrange : pi->srom_fem2g.pdetrange; - - if (pdetrange == 0) { - if (NREV_GE(pi->pubpi.phy_rev, 4)) { - aux_adc_vmid = aux_adc_vmid_rev4; - aux_adc_gain = aux_adc_gain_rev4; - } else { - aux_adc_vmid = aux_adc_vmid_rev3; - aux_adc_gain = aux_adc_gain_rev3; - } - chan_freq_range = - wlc_phy_get_chan_freq_range_nphy(pi, 0); - if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) { - switch (chan_freq_range) { - case WL_CHAN_FREQ_RANGE_5GL: - aux_adc_vmid[3] = 0x89; - aux_adc_gain[3] = 0; - break; - case WL_CHAN_FREQ_RANGE_5GM: - aux_adc_vmid[3] = 0x89; - aux_adc_gain[3] = 0; - break; - case WL_CHAN_FREQ_RANGE_5GH: - aux_adc_vmid[3] = 0x89; - aux_adc_gain[3] = 0; - break; - default: - break; - } - } - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, - 0x08, 16, aux_adc_vmid); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, - 0x18, 16, aux_adc_vmid); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, - 0x0c, 16, aux_adc_gain); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, - 0x1c, 16, aux_adc_gain); - } else if (pdetrange == 1) { - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, - 0x08, 16, sk_adc_vmid); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, - 0x18, 16, sk_adc_vmid); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, - 0x0c, 16, sk_adc_gain); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, - 0x1c, 16, sk_adc_gain); - } else if (pdetrange == 2) { - - u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x74 }; - u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x04 }; - - if (NREV_GE(pi->pubpi.phy_rev, 6)) { - chan_freq_range = - wlc_phy_get_chan_freq_range_nphy(pi, 0); - if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) { - bcm_adc_vmid[3] = 0x8e; - bcm_adc_gain[3] = 0x03; - } else { - bcm_adc_vmid[3] = 0x94; - bcm_adc_gain[3] = 0x03; - } - } else if (NREV_IS(pi->pubpi.phy_rev, 5)) { - bcm_adc_vmid[3] = 0x84; - bcm_adc_gain[3] = 0x02; - } - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, - 0x08, 16, bcm_adc_vmid); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, - 0x18, 16, bcm_adc_vmid); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, - 0x0c, 16, bcm_adc_gain); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, - 0x1c, 16, bcm_adc_gain); - } else if (pdetrange == 3) { - chan_freq_range = - wlc_phy_get_chan_freq_range_nphy(pi, 0); - if ((NREV_GE(pi->pubpi.phy_rev, 4)) - && (chan_freq_range == WL_CHAN_FREQ_RANGE_2G)) { - - u16 auxadc_vmid[] = { - 0xa2, 0xb4, 0xb4, 0x270 }; - u16 auxadc_gain[] = { - 0x02, 0x02, 0x02, 0x00 }; - - wlc_phy_table_write_nphy(pi, - NPHY_TBL_ID_AFECTRL, 4, - 0x08, 16, auxadc_vmid); - wlc_phy_table_write_nphy(pi, - NPHY_TBL_ID_AFECTRL, 4, - 0x18, 16, auxadc_vmid); - wlc_phy_table_write_nphy(pi, - NPHY_TBL_ID_AFECTRL, 4, - 0x0c, 16, auxadc_gain); - wlc_phy_table_write_nphy(pi, - NPHY_TBL_ID_AFECTRL, 4, - 0x1c, 16, auxadc_gain); - } - } else if ((pdetrange == 4) || (pdetrange == 5)) { - u16 bcm_adc_vmid[] = { 0xa2, 0xb4, 0xb4, 0x0 }; - u16 bcm_adc_gain[] = { 0x02, 0x02, 0x02, 0x0 }; - u16 Vmid[2], Av[2]; - - chan_freq_range = - wlc_phy_get_chan_freq_range_nphy(pi, 0); - if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) { - Vmid[0] = (pdetrange == 4) ? 0x8e : 0x89; - Vmid[1] = (pdetrange == 4) ? 0x96 : 0x89; - Av[0] = (pdetrange == 4) ? 2 : 0; - Av[1] = (pdetrange == 4) ? 2 : 0; - } else { - Vmid[0] = (pdetrange == 4) ? 0x89 : 0x74; - Vmid[1] = (pdetrange == 4) ? 0x8b : 0x70; - Av[0] = (pdetrange == 4) ? 2 : 0; - Av[1] = (pdetrange == 4) ? 2 : 0; - } - - bcm_adc_vmid[3] = Vmid[0]; - bcm_adc_gain[3] = Av[0]; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, - 0x08, 16, bcm_adc_vmid); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, - 0x0c, 16, bcm_adc_gain); - - bcm_adc_vmid[3] = Vmid[1]; - bcm_adc_gain[3] = Av[1]; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, - 0x18, 16, bcm_adc_vmid); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, - 0x1c, 16, bcm_adc_gain); - } else { - ASSERT(0); - } - - write_radio_reg(pi, - (RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX0), - 0x0); - write_radio_reg(pi, - (RADIO_2056_RX_MIXA_MAST_BIAS | RADIO_2056_RX1), - 0x0); - - write_radio_reg(pi, - (RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX0), - 0x6); - write_radio_reg(pi, - (RADIO_2056_RX_MIXA_BIAS_MAIN | RADIO_2056_RX1), - 0x6); - - write_radio_reg(pi, - (RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX0), - 0x7); - write_radio_reg(pi, - (RADIO_2056_RX_MIXA_BIAS_AUX | RADIO_2056_RX1), - 0x7); - - write_radio_reg(pi, - (RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX0), - 0x88); - write_radio_reg(pi, - (RADIO_2056_RX_MIXA_LOB_BIAS | RADIO_2056_RX1), - 0x88); - - write_radio_reg(pi, - (RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX0), - 0x0); - write_radio_reg(pi, - (RADIO_2056_RX_MIXA_CMFB_IDAC | RADIO_2056_RX1), - 0x0); - - write_radio_reg(pi, - (RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX0), - 0x0); - write_radio_reg(pi, - (RADIO_2056_RX_MIXG_CMFB_IDAC | RADIO_2056_RX1), - 0x0); - - triso = - (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g. - triso : pi->srom_fem2g.triso; - if (triso == 7) { - wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0); - wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1); - } - - wlc_phy_war_txchain_upd_nphy(pi, pi->sh->hw_phytxchain); - - if (((pi->sh->boardflags2 & BFL2_APLL_WAR) && - (CHSPEC_IS5G(pi->radio_chanspec))) || - (((pi->sh->boardflags2 & BFL2_GPLL_WAR) || - (pi->sh->boardflags2 & BFL2_GPLL_WAR2)) && - (CHSPEC_IS2G(pi->radio_chanspec)))) { - nss1_data_weights = 0x00088888; - ht_data_weights = 0x00088888; - stbc_data_weights = 0x00088888; - } else { - nss1_data_weights = 0x88888888; - ht_data_weights = 0x88888888; - stbc_data_weights = 0x88888888; - } - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL, - 1, 1, 32, &nss1_data_weights); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL, - 1, 2, 32, &ht_data_weights); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL, - 1, 3, 32, &stbc_data_weights); - - if (NREV_IS(pi->pubpi.phy_rev, 4)) { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - write_radio_reg(pi, - RADIO_2056_TX_GMBB_IDAC | - RADIO_2056_TX0, 0x70); - write_radio_reg(pi, - RADIO_2056_TX_GMBB_IDAC | - RADIO_2056_TX1, 0x70); - } - } - - if (!pi->edcrs_threshold_lock) { - write_phy_reg(pi, 0x224, 0x3eb); - write_phy_reg(pi, 0x225, 0x3eb); - write_phy_reg(pi, 0x226, 0x341); - write_phy_reg(pi, 0x227, 0x341); - write_phy_reg(pi, 0x228, 0x42b); - write_phy_reg(pi, 0x229, 0x42b); - write_phy_reg(pi, 0x22a, 0x381); - write_phy_reg(pi, 0x22b, 0x381); - write_phy_reg(pi, 0x22c, 0x42b); - write_phy_reg(pi, 0x22d, 0x42b); - write_phy_reg(pi, 0x22e, 0x381); - write_phy_reg(pi, 0x22f, 0x381); - } - - if (NREV_GE(pi->pubpi.phy_rev, 6)) { - - if (pi->sh->boardflags2 & BFL2_SINGLEANT_CCK) { - wlapi_bmac_mhf(pi->sh->physhim, MHF4, - MHF4_BPHY_TXCORE0, - MHF4_BPHY_TXCORE0, WLC_BAND_ALL); - } - } - } else { - - if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD || - (pi->sh->boardtype == 0x8b)) { - uint i; - u8 war_dlys[] = { 1, 6, 6, 2, 4, 20, 1 }; - for (i = 0; i < ARRAY_SIZE(rfseq_rx2tx_dlys); i++) - rfseq_rx2tx_dlys[i] = war_dlys[i]; - } - - if (CHSPEC_IS5G(pi->radio_chanspec) && pi->phy_5g_pwrgain) { - and_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0xf7); - and_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0xf7); - } else { - or_radio_reg(pi, RADIO_2055_CORE1_TX_RF_SPARE, 0x8); - or_radio_reg(pi, RADIO_2055_CORE2_TX_RF_SPARE, 0x8); - } - - regval = 0x000a; - wlc_phy_table_write_nphy(pi, 8, 1, 0, 16, ®val); - wlc_phy_table_write_nphy(pi, 8, 1, 0x10, 16, ®val); - - if (NREV_LT(pi->pubpi.phy_rev, 3)) { - regval = 0xcdaa; - wlc_phy_table_write_nphy(pi, 8, 1, 0x02, 16, ®val); - wlc_phy_table_write_nphy(pi, 8, 1, 0x12, 16, ®val); - } - - if (NREV_LT(pi->pubpi.phy_rev, 2)) { - regval = 0x0000; - wlc_phy_table_write_nphy(pi, 8, 1, 0x08, 16, ®val); - wlc_phy_table_write_nphy(pi, 8, 1, 0x18, 16, ®val); - - regval = 0x7aab; - wlc_phy_table_write_nphy(pi, 8, 1, 0x07, 16, ®val); - wlc_phy_table_write_nphy(pi, 8, 1, 0x17, 16, ®val); - - regval = 0x0800; - wlc_phy_table_write_nphy(pi, 8, 1, 0x06, 16, ®val); - wlc_phy_table_write_nphy(pi, 8, 1, 0x16, 16, ®val); - } - - write_phy_reg(pi, 0xf8, 0x02d8); - write_phy_reg(pi, 0xf9, 0x0301); - write_phy_reg(pi, 0xfa, 0x02d8); - write_phy_reg(pi, 0xfb, 0x0301); - - wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, rfseq_rx2tx_events, - rfseq_rx2tx_dlys, - sizeof(rfseq_rx2tx_events) / - sizeof(rfseq_rx2tx_events[0])); - - wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_TX2RX, rfseq_tx2rx_events, - rfseq_tx2rx_dlys, - sizeof(rfseq_tx2rx_events) / - sizeof(rfseq_tx2rx_events[0])); - - wlc_phy_workarounds_nphy_gainctrl(pi); - - if (NREV_LT(pi->pubpi.phy_rev, 2)) { - - if (read_phy_reg(pi, 0xa0) & NPHY_MLenable) - wlapi_bmac_mhf(pi->sh->physhim, MHF3, - MHF3_NPHY_MLADV_WAR, - MHF3_NPHY_MLADV_WAR, - WLC_BAND_ALL); - - } else if (NREV_IS(pi->pubpi.phy_rev, 2)) { - write_phy_reg(pi, 0x1e3, 0x0); - write_phy_reg(pi, 0x1e4, 0x0); - } - - if (NREV_LT(pi->pubpi.phy_rev, 2)) - mod_phy_reg(pi, 0x90, (0x1 << 7), 0); - - alpha0 = 293; - alpha1 = 435; - alpha2 = 261; - beta0 = 366; - beta1 = 205; - beta2 = 32; - write_phy_reg(pi, 0x145, alpha0); - write_phy_reg(pi, 0x146, alpha1); - write_phy_reg(pi, 0x147, alpha2); - write_phy_reg(pi, 0x148, beta0); - write_phy_reg(pi, 0x149, beta1); - write_phy_reg(pi, 0x14a, beta2); - - if (NREV_LT(pi->pubpi.phy_rev, 3)) { - mod_phy_reg(pi, 0x142, (0xf << 12), 0); - - write_phy_reg(pi, 0x192, 0xb5); - write_phy_reg(pi, 0x193, 0xa4); - write_phy_reg(pi, 0x194, 0x0); - } - - if (NREV_IS(pi->pubpi.phy_rev, 2)) { - mod_phy_reg(pi, 0x221, - NPHY_FORCESIG_DECODEGATEDCLKS, - NPHY_FORCESIG_DECODEGATEDCLKS); - } - } - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); -} - -static void wlc_phy_workarounds_nphy_gainctrl(phy_info_t *pi) -{ - u16 w1th, hpf_code, currband; - int ctr; - u8 rfseq_updategainu_events[] = { - NPHY_RFSEQ_CMD_RX_GAIN, - NPHY_RFSEQ_CMD_CLR_HIQ_DIS, - NPHY_RFSEQ_CMD_SET_HPF_BW - }; - u8 rfseq_updategainu_dlys[] = { 10, 30, 1 }; - s8 lna1G_gain_db[] = { 7, 11, 16, 23 }; - s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 }; - s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 }; - s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 }; - s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 }; - s8 lna1A_gain_db[] = { 7, 11, 17, 23 }; - s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 }; - s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 }; - s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 }; - s8 *lna1_gain_db = NULL; - s8 lna2G_gain_db[] = { -5, 6, 10, 14 }; - s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 }; - s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 }; - s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 }; - s8 lna2A_gain_db[] = { -6, 2, 6, 10 }; - s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 }; - s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 }; - s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 }; - s8 *lna2_gain_db = NULL; - s8 tiaG_gain_db[] = { - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A }; - s8 tiaA_gain_db[] = { - 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 }; - s8 tiaA_gain_db_rev4[] = { - 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; - s8 tiaA_gain_db_rev5[] = { - 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; - s8 tiaA_gain_db_rev6[] = { - 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; - s8 *tia_gain_db; - s8 tiaG_gainbits[] = { - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 }; - s8 tiaA_gainbits[] = { - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 }; - s8 tiaA_gainbits_rev4[] = { - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; - s8 tiaA_gainbits_rev5[] = { - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; - s8 tiaA_gainbits_rev6[] = { - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; - s8 *tia_gainbits; - s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 }; - s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 }; - u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f }; - u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f }; - u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f }; - u16 rfseqG_init_gain_rev5_elna[] = { - 0x013f, 0x013f, 0x013f, 0x013f }; - u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f }; - u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f }; - u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f }; - u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f }; - u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f }; - u16 rfseqA_init_gain_rev4_elna[] = { - 0x314f, 0x314f, 0x314f, 0x314f }; - u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f }; - u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f }; - u16 *rfseq_init_gain; - u16 initG_gaincode = 0x627e; - u16 initG_gaincode_rev4 = 0x527e; - u16 initG_gaincode_rev5 = 0x427e; - u16 initG_gaincode_rev5_elna = 0x027e; - u16 initG_gaincode_rev6 = 0x527e; - u16 initG_gaincode_rev6_224B0 = 0x427e; - u16 initG_gaincode_rev6_elna = 0x127e; - u16 initA_gaincode = 0x52de; - u16 initA_gaincode_rev4 = 0x629e; - u16 initA_gaincode_rev4_elna = 0x329e; - u16 initA_gaincode_rev5 = 0x729e; - u16 initA_gaincode_rev6 = 0x729e; - u16 init_gaincode; - u16 clip1hiG_gaincode = 0x107e; - u16 clip1hiG_gaincode_rev4 = 0x007e; - u16 clip1hiG_gaincode_rev5 = 0x1076; - u16 clip1hiG_gaincode_rev6 = 0x007e; - u16 clip1hiA_gaincode = 0x00de; - u16 clip1hiA_gaincode_rev4 = 0x029e; - u16 clip1hiA_gaincode_rev5 = 0x029e; - u16 clip1hiA_gaincode_rev6 = 0x029e; - u16 clip1hi_gaincode; - u16 clip1mdG_gaincode = 0x0066; - u16 clip1mdA_gaincode = 0x00ca; - u16 clip1mdA_gaincode_rev4 = 0x1084; - u16 clip1mdA_gaincode_rev5 = 0x2084; - u16 clip1mdA_gaincode_rev6 = 0x2084; - u16 clip1md_gaincode = 0; - u16 clip1loG_gaincode = 0x0074; - u16 clip1loG_gaincode_rev5[] = { - 0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c - }; - u16 clip1loG_gaincode_rev6[] = { - 0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e - }; - u16 clip1loG_gaincode_rev6_224B0 = 0x1074; - u16 clip1loA_gaincode = 0x00cc; - u16 clip1loA_gaincode_rev4 = 0x0086; - u16 clip1loA_gaincode_rev5 = 0x2086; - u16 clip1loA_gaincode_rev6 = 0x2086; - u16 clip1lo_gaincode; - u8 crsminG_th = 0x18; - u8 crsminG_th_rev5 = 0x18; - u8 crsminG_th_rev6 = 0x18; - u8 crsminA_th = 0x1e; - u8 crsminA_th_rev4 = 0x24; - u8 crsminA_th_rev5 = 0x24; - u8 crsminA_th_rev6 = 0x24; - u8 crsmin_th; - u8 crsminlG_th = 0x18; - u8 crsminlG_th_rev5 = 0x18; - u8 crsminlG_th_rev6 = 0x18; - u8 crsminlA_th = 0x1e; - u8 crsminlA_th_rev4 = 0x24; - u8 crsminlA_th_rev5 = 0x24; - u8 crsminlA_th_rev6 = 0x24; - u8 crsminl_th = 0; - u8 crsminuG_th = 0x18; - u8 crsminuG_th_rev5 = 0x18; - u8 crsminuG_th_rev6 = 0x18; - u8 crsminuA_th = 0x1e; - u8 crsminuA_th_rev4 = 0x24; - u8 crsminuA_th_rev5 = 0x24; - u8 crsminuA_th_rev6 = 0x24; - u8 crsminuA_th_rev6_224B0 = 0x2d; - u8 crsminu_th; - u16 nbclipG_th = 0x20d; - u16 nbclipG_th_rev4 = 0x1a1; - u16 nbclipG_th_rev5 = 0x1d0; - u16 nbclipG_th_rev6 = 0x1d0; - u16 nbclipA_th = 0x1a1; - u16 nbclipA_th_rev4 = 0x107; - u16 nbclipA_th_rev5 = 0x0a9; - u16 nbclipA_th_rev6 = 0x0f0; - u16 nbclip_th = 0; - u8 w1clipG_th = 5; - u8 w1clipG_th_rev5 = 9; - u8 w1clipG_th_rev6 = 5; - u8 w1clipA_th = 25, w1clip_th; - u8 rssi_gain_default = 0x50; - u8 rssiG_gain_rev6_224B0 = 0x50; - u8 rssiA_gain_rev5 = 0x90; - u8 rssiA_gain_rev6 = 0x90; - u8 rssi_gain; - u16 regval[21]; - u8 triso; - - triso = (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.triso : - pi->srom_fem2g.triso; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if (pi->pubpi.radiorev == 5) { - - wlc_phy_workarounds_nphy_gainctrl_2057_rev5(pi); - } else if (pi->pubpi.radiorev == 7) { - wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi); - - mod_phy_reg(pi, 0x283, (0xff << 0), (0x44 << 0)); - mod_phy_reg(pi, 0x280, (0xff << 0), (0x44 << 0)); - - } else if ((pi->pubpi.radiorev == 3) - || (pi->pubpi.radiorev == 8)) { - wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi); - - if (pi->pubpi.radiorev == 8) { - mod_phy_reg(pi, 0x283, - (0xff << 0), (0x44 << 0)); - mod_phy_reg(pi, 0x280, - (0xff << 0), (0x44 << 0)); - } - } else { - wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi); - } - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - - mod_phy_reg(pi, 0xa0, (0x1 << 6), (1 << 6)); - - mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13)); - mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13)); - - currband = - read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand; - if (currband == 0) { - if (NREV_GE(pi->pubpi.phy_rev, 6)) { - if (pi->pubpi.radiorev == 11) { - lna1_gain_db = lna1G_gain_db_rev6_224B0; - lna2_gain_db = lna2G_gain_db_rev6_224B0; - rfseq_init_gain = - rfseqG_init_gain_rev6_224B0; - init_gaincode = - initG_gaincode_rev6_224B0; - clip1hi_gaincode = - clip1hiG_gaincode_rev6; - clip1lo_gaincode = - clip1loG_gaincode_rev6_224B0; - nbclip_th = nbclipG_th_rev6; - w1clip_th = w1clipG_th_rev6; - crsmin_th = crsminG_th_rev6; - crsminl_th = crsminlG_th_rev6; - crsminu_th = crsminuG_th_rev6; - rssi_gain = rssiG_gain_rev6_224B0; - } else { - lna1_gain_db = lna1G_gain_db_rev6; - lna2_gain_db = lna2G_gain_db_rev6; - if (pi->sh->boardflags & BFL_EXTLNA) { - - rfseq_init_gain = - rfseqG_init_gain_rev6_elna; - init_gaincode = - initG_gaincode_rev6_elna; - } else { - rfseq_init_gain = - rfseqG_init_gain_rev6; - init_gaincode = - initG_gaincode_rev6; - } - clip1hi_gaincode = - clip1hiG_gaincode_rev6; - switch (triso) { - case 0: - clip1lo_gaincode = - clip1loG_gaincode_rev6[0]; - break; - case 1: - clip1lo_gaincode = - clip1loG_gaincode_rev6[1]; - break; - case 2: - clip1lo_gaincode = - clip1loG_gaincode_rev6[2]; - break; - case 3: - default: - - clip1lo_gaincode = - clip1loG_gaincode_rev6[3]; - break; - case 4: - clip1lo_gaincode = - clip1loG_gaincode_rev6[4]; - break; - case 5: - clip1lo_gaincode = - clip1loG_gaincode_rev6[5]; - break; - case 6: - clip1lo_gaincode = - clip1loG_gaincode_rev6[6]; - break; - case 7: - clip1lo_gaincode = - clip1loG_gaincode_rev6[7]; - break; - } - nbclip_th = nbclipG_th_rev6; - w1clip_th = w1clipG_th_rev6; - crsmin_th = crsminG_th_rev6; - crsminl_th = crsminlG_th_rev6; - crsminu_th = crsminuG_th_rev6; - rssi_gain = rssi_gain_default; - } - } else if (NREV_IS(pi->pubpi.phy_rev, 5)) { - lna1_gain_db = lna1G_gain_db_rev5; - lna2_gain_db = lna2G_gain_db_rev5; - if (pi->sh->boardflags & BFL_EXTLNA) { - - rfseq_init_gain = - rfseqG_init_gain_rev5_elna; - init_gaincode = - initG_gaincode_rev5_elna; - } else { - rfseq_init_gain = rfseqG_init_gain_rev5; - init_gaincode = initG_gaincode_rev5; - } - clip1hi_gaincode = clip1hiG_gaincode_rev5; - switch (triso) { - case 0: - clip1lo_gaincode = - clip1loG_gaincode_rev5[0]; - break; - case 1: - clip1lo_gaincode = - clip1loG_gaincode_rev5[1]; - break; - case 2: - clip1lo_gaincode = - clip1loG_gaincode_rev5[2]; - break; - case 3: - - clip1lo_gaincode = - clip1loG_gaincode_rev5[3]; - break; - case 4: - clip1lo_gaincode = - clip1loG_gaincode_rev5[4]; - break; - case 5: - clip1lo_gaincode = - clip1loG_gaincode_rev5[5]; - break; - case 6: - clip1lo_gaincode = - clip1loG_gaincode_rev5[6]; - break; - case 7: - clip1lo_gaincode = - clip1loG_gaincode_rev5[7]; - break; - default: - clip1lo_gaincode = - clip1loG_gaincode_rev5[3]; - break; - } - nbclip_th = nbclipG_th_rev5; - w1clip_th = w1clipG_th_rev5; - crsmin_th = crsminG_th_rev5; - crsminl_th = crsminlG_th_rev5; - crsminu_th = crsminuG_th_rev5; - rssi_gain = rssi_gain_default; - } else if (NREV_IS(pi->pubpi.phy_rev, 4)) { - lna1_gain_db = lna1G_gain_db_rev4; - lna2_gain_db = lna2G_gain_db; - rfseq_init_gain = rfseqG_init_gain_rev4; - init_gaincode = initG_gaincode_rev4; - clip1hi_gaincode = clip1hiG_gaincode_rev4; - clip1lo_gaincode = clip1loG_gaincode; - nbclip_th = nbclipG_th_rev4; - w1clip_th = w1clipG_th; - crsmin_th = crsminG_th; - crsminl_th = crsminlG_th; - crsminu_th = crsminuG_th; - rssi_gain = rssi_gain_default; - } else { - lna1_gain_db = lna1G_gain_db; - lna2_gain_db = lna2G_gain_db; - rfseq_init_gain = rfseqG_init_gain; - init_gaincode = initG_gaincode; - clip1hi_gaincode = clip1hiG_gaincode; - clip1lo_gaincode = clip1loG_gaincode; - nbclip_th = nbclipG_th; - w1clip_th = w1clipG_th; - crsmin_th = crsminG_th; - crsminl_th = crsminlG_th; - crsminu_th = crsminuG_th; - rssi_gain = rssi_gain_default; - } - tia_gain_db = tiaG_gain_db; - tia_gainbits = tiaG_gainbits; - clip1md_gaincode = clip1mdG_gaincode; - } else { - if (NREV_GE(pi->pubpi.phy_rev, 6)) { - lna1_gain_db = lna1A_gain_db_rev6; - lna2_gain_db = lna2A_gain_db_rev6; - tia_gain_db = tiaA_gain_db_rev6; - tia_gainbits = tiaA_gainbits_rev6; - rfseq_init_gain = rfseqA_init_gain_rev6; - init_gaincode = initA_gaincode_rev6; - clip1hi_gaincode = clip1hiA_gaincode_rev6; - clip1md_gaincode = clip1mdA_gaincode_rev6; - clip1lo_gaincode = clip1loA_gaincode_rev6; - crsmin_th = crsminA_th_rev6; - crsminl_th = crsminlA_th_rev6; - if ((pi->pubpi.radiorev == 11) && - (CHSPEC_IS40(pi->radio_chanspec) == 0)) { - crsminu_th = crsminuA_th_rev6_224B0; - } else { - crsminu_th = crsminuA_th_rev6; - } - nbclip_th = nbclipA_th_rev6; - rssi_gain = rssiA_gain_rev6; - } else if (NREV_IS(pi->pubpi.phy_rev, 5)) { - lna1_gain_db = lna1A_gain_db_rev5; - lna2_gain_db = lna2A_gain_db_rev5; - tia_gain_db = tiaA_gain_db_rev5; - tia_gainbits = tiaA_gainbits_rev5; - rfseq_init_gain = rfseqA_init_gain_rev5; - init_gaincode = initA_gaincode_rev5; - clip1hi_gaincode = clip1hiA_gaincode_rev5; - clip1md_gaincode = clip1mdA_gaincode_rev5; - clip1lo_gaincode = clip1loA_gaincode_rev5; - crsmin_th = crsminA_th_rev5; - crsminl_th = crsminlA_th_rev5; - crsminu_th = crsminuA_th_rev5; - nbclip_th = nbclipA_th_rev5; - rssi_gain = rssiA_gain_rev5; - } else if (NREV_IS(pi->pubpi.phy_rev, 4)) { - lna1_gain_db = lna1A_gain_db_rev4; - lna2_gain_db = lna2A_gain_db_rev4; - tia_gain_db = tiaA_gain_db_rev4; - tia_gainbits = tiaA_gainbits_rev4; - if (pi->sh->boardflags & BFL_EXTLNA_5GHz) { - - rfseq_init_gain = - rfseqA_init_gain_rev4_elna; - init_gaincode = - initA_gaincode_rev4_elna; - } else { - rfseq_init_gain = rfseqA_init_gain_rev4; - init_gaincode = initA_gaincode_rev4; - } - clip1hi_gaincode = clip1hiA_gaincode_rev4; - clip1md_gaincode = clip1mdA_gaincode_rev4; - clip1lo_gaincode = clip1loA_gaincode_rev4; - crsmin_th = crsminA_th_rev4; - crsminl_th = crsminlA_th_rev4; - crsminu_th = crsminuA_th_rev4; - nbclip_th = nbclipA_th_rev4; - rssi_gain = rssi_gain_default; - } else { - lna1_gain_db = lna1A_gain_db; - lna2_gain_db = lna2A_gain_db; - tia_gain_db = tiaA_gain_db; - tia_gainbits = tiaA_gainbits; - rfseq_init_gain = rfseqA_init_gain; - init_gaincode = initA_gaincode; - clip1hi_gaincode = clip1hiA_gaincode; - clip1md_gaincode = clip1mdA_gaincode; - clip1lo_gaincode = clip1loA_gaincode; - crsmin_th = crsminA_th; - crsminl_th = crsminlA_th; - crsminu_th = crsminuA_th; - nbclip_th = nbclipA_th; - rssi_gain = rssi_gain_default; - } - w1clip_th = w1clipA_th; - } - - write_radio_reg(pi, - (RADIO_2056_RX_BIASPOLE_LNAG1_IDAC | - RADIO_2056_RX0), 0x17); - write_radio_reg(pi, - (RADIO_2056_RX_BIASPOLE_LNAG1_IDAC | - RADIO_2056_RX1), 0x17); - - write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX0), - 0xf0); - write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX1), - 0xf0); - - write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX0), - 0x0); - write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX1), - 0x0); - - write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX0), - rssi_gain); - write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX1), - rssi_gain); - - write_radio_reg(pi, - (RADIO_2056_RX_BIASPOLE_LNAA1_IDAC | - RADIO_2056_RX0), 0x17); - write_radio_reg(pi, - (RADIO_2056_RX_BIASPOLE_LNAA1_IDAC | - RADIO_2056_RX1), 0x17); - - write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX0), - 0xFF); - write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX1), - 0xFF); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, - 8, lna1_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, - 8, lna1_gain_db); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, - 8, lna2_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, - 8, lna2_gain_db); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, - 8, tia_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, - 8, tia_gain_db); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, - 8, tia_gainbits); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, - 8, tia_gainbits); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 6, 0x40, - 8, &lpf_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 6, 0x40, - 8, &lpf_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 6, 0x40, - 8, &lpf_gainbits); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 6, 0x40, - 8, &lpf_gainbits); - - write_phy_reg(pi, 0x20, init_gaincode); - write_phy_reg(pi, 0x2a7, init_gaincode); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - pi->pubpi.phy_corenum, 0x106, 16, - rfseq_init_gain); - - write_phy_reg(pi, 0x22, clip1hi_gaincode); - write_phy_reg(pi, 0x2a9, clip1hi_gaincode); - - write_phy_reg(pi, 0x24, clip1md_gaincode); - write_phy_reg(pi, 0x2ab, clip1md_gaincode); - - write_phy_reg(pi, 0x37, clip1lo_gaincode); - write_phy_reg(pi, 0x2ad, clip1lo_gaincode); - - mod_phy_reg(pi, 0x27d, (0xff << 0), (crsmin_th << 0)); - mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0)); - mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0)); - - write_phy_reg(pi, 0x2b, nbclip_th); - write_phy_reg(pi, 0x41, nbclip_th); - - mod_phy_reg(pi, 0x27, (0x3f << 0), (w1clip_th << 0)); - mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1clip_th << 0)); - - write_phy_reg(pi, 0x150, 0x809c); - - } else { - - mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13)); - mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13)); - - write_phy_reg(pi, 0x2b, 0x84); - write_phy_reg(pi, 0x41, 0x84); - - if (CHSPEC_IS20(pi->radio_chanspec)) { - write_phy_reg(pi, 0x6b, 0x2b); - write_phy_reg(pi, 0x6c, 0x2b); - write_phy_reg(pi, 0x6d, 0x9); - write_phy_reg(pi, 0x6e, 0x9); - } - - w1th = NPHY_RSSICAL_W1_TARGET - 4; - mod_phy_reg(pi, 0x27, (0x3f << 0), (w1th << 0)); - mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1th << 0)); - - if (CHSPEC_IS20(pi->radio_chanspec)) { - mod_phy_reg(pi, 0x1c, (0x1f << 0), (0x1 << 0)); - mod_phy_reg(pi, 0x32, (0x1f << 0), (0x1 << 0)); - - mod_phy_reg(pi, 0x1d, (0x1f << 0), (0x1 << 0)); - mod_phy_reg(pi, 0x33, (0x1f << 0), (0x1 << 0)); - } - - write_phy_reg(pi, 0x150, 0x809c); - - if (pi->nphy_gain_boost) - if ((CHSPEC_IS2G(pi->radio_chanspec)) && - (CHSPEC_IS40(pi->radio_chanspec))) - hpf_code = 4; - else - hpf_code = 5; - else if (CHSPEC_IS40(pi->radio_chanspec)) - hpf_code = 6; - else - hpf_code = 7; - - mod_phy_reg(pi, 0x20, (0x1f << 7), (hpf_code << 7)); - mod_phy_reg(pi, 0x36, (0x1f << 7), (hpf_code << 7)); - - for (ctr = 0; ctr < 4; ctr++) { - regval[ctr] = (hpf_code << 8) | 0x7c; - } - wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval); - - wlc_phy_adjust_lnagaintbl_nphy(pi); - - if (pi->nphy_elna_gain_config) { - regval[0] = 0; - regval[1] = 1; - regval[2] = 1; - regval[3] = 1; - wlc_phy_table_write_nphy(pi, 2, 4, 8, 16, regval); - wlc_phy_table_write_nphy(pi, 3, 4, 8, 16, regval); - - for (ctr = 0; ctr < 4; ctr++) { - regval[ctr] = (hpf_code << 8) | 0x74; - } - wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval); - } - - if (NREV_IS(pi->pubpi.phy_rev, 2)) { - for (ctr = 0; ctr < 21; ctr++) { - regval[ctr] = 3 * ctr; - } - wlc_phy_table_write_nphy(pi, 0, 21, 32, 16, regval); - wlc_phy_table_write_nphy(pi, 1, 21, 32, 16, regval); - - for (ctr = 0; ctr < 21; ctr++) { - regval[ctr] = (u16) ctr; - } - wlc_phy_table_write_nphy(pi, 2, 21, 32, 16, regval); - wlc_phy_table_write_nphy(pi, 3, 21, 32, 16, regval); - } - - wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_UPDATEGAINU, - rfseq_updategainu_events, - rfseq_updategainu_dlys, - sizeof(rfseq_updategainu_events) / - sizeof(rfseq_updategainu_events[0])); - - mod_phy_reg(pi, 0x153, (0xff << 8), (90 << 8)); - - if (CHSPEC_IS2G(pi->radio_chanspec)) - mod_phy_reg(pi, - (NPHY_TO_BPHY_OFF + BPHY_OPTIONAL_MODES), - 0x7f, 0x4); - } -} - -static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(phy_info_t *pi) -{ - s8 lna1_gain_db[] = { 8, 13, 17, 22 }; - s8 lna2_gain_db[] = { -2, 7, 11, 15 }; - s8 tia_gain_db[] = { -4, -1, 2, 5, 5, 5, 5, 5, 5, 5 }; - s8 tia_gainbits[] = { - 0x0, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 }; - - mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13)); - mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13)); - - mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0)); - - mod_phy_reg(pi, 0x283, (0xff << 0), (0x3c << 0)); - mod_phy_reg(pi, 0x280, (0xff << 0), (0x3c << 0)); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x8, 8, - lna1_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x8, 8, - lna1_gain_db); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, 8, - lna2_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, 8, - lna2_gain_db); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8, - tia_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8, - tia_gain_db); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8, - tia_gainbits); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8, - tia_gainbits); - - write_phy_reg(pi, 0x37, 0x74); - write_phy_reg(pi, 0x2ad, 0x74); - write_phy_reg(pi, 0x38, 0x18); - write_phy_reg(pi, 0x2ae, 0x18); - - write_phy_reg(pi, 0x2b, 0xe8); - write_phy_reg(pi, 0x41, 0xe8); - - if (CHSPEC_IS20(pi->radio_chanspec)) { - - mod_phy_reg(pi, 0x300, (0x3f << 0), (0x12 << 0)); - mod_phy_reg(pi, 0x301, (0x3f << 0), (0x12 << 0)); - } else { - - mod_phy_reg(pi, 0x300, (0x3f << 0), (0x10 << 0)); - mod_phy_reg(pi, 0x301, (0x3f << 0), (0x10 << 0)); - } -} - -static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(phy_info_t *pi) -{ - u16 currband; - s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 }; - s8 *lna1_gain_db = NULL; - s8 *lna1_gain_db_2 = NULL; - s8 *lna2_gain_db = NULL; - s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 }; - s8 *tia_gain_db; - s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 }; - s8 *tia_gainbits; - u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f }; - u16 *rfseq_init_gain; - u16 init_gaincode; - u16 clip1hi_gaincode; - u16 clip1md_gaincode = 0; - u16 clip1md_gaincode_B; - u16 clip1lo_gaincode; - u16 clip1lo_gaincode_B; - u8 crsminl_th = 0; - u8 crsminu_th; - u16 nbclip_th = 0; - u8 w1clip_th; - u16 freq; - s8 nvar_baseline_offset0 = 0, nvar_baseline_offset1 = 0; - u8 chg_nbclip_th = 0; - - mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13)); - mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13)); - - currband = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand; - if (currband == 0) { - - lna1_gain_db = lna1G_gain_db_rev7; - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8, - lna1_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8, - lna1_gain_db); - - mod_phy_reg(pi, 0x283, (0xff << 0), (0x40 << 0)); - - if (CHSPEC_IS40(pi->radio_chanspec)) { - mod_phy_reg(pi, 0x280, (0xff << 0), (0x3e << 0)); - mod_phy_reg(pi, 0x283, (0xff << 0), (0x3e << 0)); - } - - mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0)); - - if (CHSPEC_IS20(pi->radio_chanspec)) { - mod_phy_reg(pi, 0x300, (0x3f << 0), (13 << 0)); - mod_phy_reg(pi, 0x301, (0x3f << 0), (13 << 0)); - } - } else { - - init_gaincode = 0x9e; - clip1hi_gaincode = 0x9e; - clip1md_gaincode_B = 0x24; - clip1lo_gaincode = 0x8a; - clip1lo_gaincode_B = 8; - rfseq_init_gain = rfseqA_init_gain_rev7; - - tia_gain_db = tiaA_gain_db_rev7; - tia_gainbits = tiaA_gainbits_rev7; - - freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec)); - if (CHSPEC_IS20(pi->radio_chanspec)) { - - w1clip_th = 25; - clip1md_gaincode = 0x82; - - if ((freq <= 5080) || (freq == 5825)) { - - s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 }; - s8 lna1A_gain_db_2_rev7[] = { - 11, 17, 22, 25 }; - s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; - - crsminu_th = 0x3e; - lna1_gain_db = lna1A_gain_db_rev7; - lna1_gain_db_2 = lna1A_gain_db_2_rev7; - lna2_gain_db = lna2A_gain_db_rev7; - } else if ((freq >= 5500) && (freq <= 5700)) { - - s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 }; - s8 lna1A_gain_db_2_rev7[] = { - 12, 18, 22, 26 }; - s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 }; - - crsminu_th = 0x45; - clip1md_gaincode_B = 0x14; - nbclip_th = 0xff; - chg_nbclip_th = 1; - lna1_gain_db = lna1A_gain_db_rev7; - lna1_gain_db_2 = lna1A_gain_db_2_rev7; - lna2_gain_db = lna2A_gain_db_rev7; - } else { - - s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 }; - s8 lna1A_gain_db_2_rev7[] = { - 12, 18, 22, 26 }; - s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; - - crsminu_th = 0x41; - lna1_gain_db = lna1A_gain_db_rev7; - lna1_gain_db_2 = lna1A_gain_db_2_rev7; - lna2_gain_db = lna2A_gain_db_rev7; - } - - if (freq <= 4920) { - nvar_baseline_offset0 = 5; - nvar_baseline_offset1 = 5; - } else if ((freq > 4920) && (freq <= 5320)) { - nvar_baseline_offset0 = 3; - nvar_baseline_offset1 = 5; - } else if ((freq > 5320) && (freq <= 5700)) { - nvar_baseline_offset0 = 3; - nvar_baseline_offset1 = 2; - } else { - nvar_baseline_offset0 = 4; - nvar_baseline_offset1 = 0; - } - } else { - - crsminu_th = 0x3a; - crsminl_th = 0x3a; - w1clip_th = 20; - - if ((freq >= 4920) && (freq <= 5320)) { - nvar_baseline_offset0 = 4; - nvar_baseline_offset1 = 5; - } else if ((freq > 5320) && (freq <= 5550)) { - nvar_baseline_offset0 = 4; - nvar_baseline_offset1 = 2; - } else { - nvar_baseline_offset0 = 5; - nvar_baseline_offset1 = 3; - } - } - - write_phy_reg(pi, 0x20, init_gaincode); - write_phy_reg(pi, 0x2a7, init_gaincode); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - pi->pubpi.phy_corenum, 0x106, 16, - rfseq_init_gain); - - write_phy_reg(pi, 0x22, clip1hi_gaincode); - write_phy_reg(pi, 0x2a9, clip1hi_gaincode); - - write_phy_reg(pi, 0x36, clip1md_gaincode_B); - write_phy_reg(pi, 0x2ac, clip1md_gaincode_B); - - write_phy_reg(pi, 0x37, clip1lo_gaincode); - write_phy_reg(pi, 0x2ad, clip1lo_gaincode); - write_phy_reg(pi, 0x38, clip1lo_gaincode_B); - write_phy_reg(pi, 0x2ae, clip1lo_gaincode_B); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8, - tia_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8, - tia_gain_db); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8, - tia_gainbits); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8, - tia_gainbits); - - mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0)); - - if (chg_nbclip_th == 1) { - write_phy_reg(pi, 0x2b, nbclip_th); - write_phy_reg(pi, 0x41, nbclip_th); - } - - mod_phy_reg(pi, 0x300, (0x3f << 0), (w1clip_th << 0)); - mod_phy_reg(pi, 0x301, (0x3f << 0), (w1clip_th << 0)); - - mod_phy_reg(pi, 0x2e4, - (0x3f << 0), (nvar_baseline_offset0 << 0)); - - mod_phy_reg(pi, 0x2e4, - (0x3f << 6), (nvar_baseline_offset1 << 6)); - - if (CHSPEC_IS20(pi->radio_chanspec)) { - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8, - lna1_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8, - lna1_gain_db_2); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, - 8, lna2_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, - 8, lna2_gain_db); - - write_phy_reg(pi, 0x24, clip1md_gaincode); - write_phy_reg(pi, 0x2ab, clip1md_gaincode); - } else { - mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0)); - } - - } - -} - -static void wlc_phy_adjust_lnagaintbl_nphy(phy_info_t *pi) -{ - uint core; - int ctr; - s16 gain_delta[2]; - u8 curr_channel; - u16 minmax_gain[2]; - u16 regval[4]; - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - if (pi->nphy_gain_boost) { - if ((CHSPEC_IS2G(pi->radio_chanspec))) { - - gain_delta[0] = 6; - gain_delta[1] = 6; - } else { - - curr_channel = CHSPEC_CHANNEL(pi->radio_chanspec); - gain_delta[0] = - (s16) - PHY_HW_ROUND(((nphy_lnagain_est0[0] * - curr_channel) + - nphy_lnagain_est0[1]), 13); - gain_delta[1] = - (s16) - PHY_HW_ROUND(((nphy_lnagain_est1[0] * - curr_channel) + - nphy_lnagain_est1[1]), 13); - } - } else { - - gain_delta[0] = 0; - gain_delta[1] = 0; - } - - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - if (pi->nphy_elna_gain_config) { - - regval[0] = nphy_def_lnagains[2] + gain_delta[core]; - regval[1] = nphy_def_lnagains[3] + gain_delta[core]; - regval[2] = nphy_def_lnagains[3] + gain_delta[core]; - regval[3] = nphy_def_lnagains[3] + gain_delta[core]; - } else { - for (ctr = 0; ctr < 4; ctr++) { - regval[ctr] = - nphy_def_lnagains[ctr] + gain_delta[core]; - } - } - wlc_phy_table_write_nphy(pi, core, 4, 8, 16, regval); - - minmax_gain[core] = - (u16) (nphy_def_lnagains[2] + gain_delta[core] + 4); - } - - mod_phy_reg(pi, 0x1e, (0xff << 0), (minmax_gain[0] << 0)); - mod_phy_reg(pi, 0x34, (0xff << 0), (minmax_gain[1] << 0)); - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); -} - -void wlc_phy_switch_radio_nphy(phy_info_t *pi, bool on) -{ - if (on) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if (!pi->radio_is_on) { - wlc_phy_radio_preinit_205x(pi); - wlc_phy_radio_init_2057(pi); - wlc_phy_radio_postinit_2057(pi); - } - - wlc_phy_chanspec_set((wlc_phy_t *) pi, - pi->radio_chanspec); - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - wlc_phy_radio_preinit_205x(pi); - wlc_phy_radio_init_2056(pi); - wlc_phy_radio_postinit_2056(pi); - - wlc_phy_chanspec_set((wlc_phy_t *) pi, - pi->radio_chanspec); - } else { - wlc_phy_radio_preinit_2055(pi); - wlc_phy_radio_init_2055(pi); - wlc_phy_radio_postinit_2055(pi); - } - - pi->radio_is_on = true; - - } else { - - if (NREV_GE(pi->pubpi.phy_rev, 3) - && NREV_LT(pi->pubpi.phy_rev, 7)) { - and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU); - mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x0); - - write_radio_reg(pi, - RADIO_2056_TX_PADA_BOOST_TUNE | - RADIO_2056_TX0, 0); - write_radio_reg(pi, - RADIO_2056_TX_PADG_BOOST_TUNE | - RADIO_2056_TX0, 0); - write_radio_reg(pi, - RADIO_2056_TX_PGAA_BOOST_TUNE | - RADIO_2056_TX0, 0); - write_radio_reg(pi, - RADIO_2056_TX_PGAG_BOOST_TUNE | - RADIO_2056_TX0, 0); - mod_radio_reg(pi, - RADIO_2056_TX_MIXA_BOOST_TUNE | - RADIO_2056_TX0, 0xf0, 0); - write_radio_reg(pi, - RADIO_2056_TX_MIXG_BOOST_TUNE | - RADIO_2056_TX0, 0); - - write_radio_reg(pi, - RADIO_2056_TX_PADA_BOOST_TUNE | - RADIO_2056_TX1, 0); - write_radio_reg(pi, - RADIO_2056_TX_PADG_BOOST_TUNE | - RADIO_2056_TX1, 0); - write_radio_reg(pi, - RADIO_2056_TX_PGAA_BOOST_TUNE | - RADIO_2056_TX1, 0); - write_radio_reg(pi, - RADIO_2056_TX_PGAG_BOOST_TUNE | - RADIO_2056_TX1, 0); - mod_radio_reg(pi, - RADIO_2056_TX_MIXA_BOOST_TUNE | - RADIO_2056_TX1, 0xf0, 0); - write_radio_reg(pi, - RADIO_2056_TX_MIXG_BOOST_TUNE | - RADIO_2056_TX1, 0); - - pi->radio_is_on = false; - } - - if (NREV_GE(pi->pubpi.phy_rev, 8)) { - and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU); - pi->radio_is_on = false; - } - - } -} - -static void wlc_phy_radio_preinit_2055(phy_info_t *pi) -{ - - and_phy_reg(pi, 0x78, ~RFCC_POR_FORCE); - or_phy_reg(pi, 0x78, RFCC_CHIP0_PU | RFCC_OE_POR_FORCE); - - or_phy_reg(pi, 0x78, RFCC_POR_FORCE); -} - -static void wlc_phy_radio_init_2055(phy_info_t *pi) -{ - wlc_phy_init_radio_regs(pi, regs_2055, RADIO_DEFAULT_CORE); -} - -static void wlc_phy_radio_postinit_2055(phy_info_t *pi) -{ - - and_radio_reg(pi, RADIO_2055_MASTER_CNTRL1, - ~(RADIO_2055_JTAGCTRL_MASK | RADIO_2055_JTAGSYNC_MASK)); - - if (((pi->sh->sromrev >= 4) - && !(pi->sh->boardflags2 & BFL2_RXBB_INT_REG_DIS)) - || ((pi->sh->sromrev < 4))) { - and_radio_reg(pi, RADIO_2055_CORE1_RXBB_REGULATOR, 0x7F); - and_radio_reg(pi, RADIO_2055_CORE2_RXBB_REGULATOR, 0x7F); - } - - mod_radio_reg(pi, RADIO_2055_RRCCAL_N_OPT_SEL, 0x3F, 0x2C); - write_radio_reg(pi, RADIO_2055_CAL_MISC, 0x3C); - - and_radio_reg(pi, RADIO_2055_CAL_MISC, - ~(RADIO_2055_RRCAL_START | RADIO_2055_RRCAL_RST_N)); - - or_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL, RADIO_2055_CAL_LPO_ENABLE); - - or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_RST_N); - - udelay(1000); - - or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_START); - - SPINWAIT(((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) & - RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE), 2000); - - ASSERT((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) & - RADIO_2055_RCAL_DONE) == RADIO_2055_RCAL_DONE); - - and_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL, - ~(RADIO_2055_CAL_LPO_ENABLE)); - - wlc_phy_chanspec_set((wlc_phy_t *) pi, pi->radio_chanspec); - - write_radio_reg(pi, RADIO_2055_CORE1_RXBB_LPF, 9); - write_radio_reg(pi, RADIO_2055_CORE2_RXBB_LPF, 9); - - write_radio_reg(pi, RADIO_2055_CORE1_RXBB_MIDAC_HIPAS, 0x83); - write_radio_reg(pi, RADIO_2055_CORE2_RXBB_MIDAC_HIPAS, 0x83); - - mod_radio_reg(pi, RADIO_2055_CORE1_LNA_GAINBST, - RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE); - mod_radio_reg(pi, RADIO_2055_CORE2_LNA_GAINBST, - RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE); - if (pi->nphy_gain_boost) { - and_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1, - ~(RADIO_2055_GAINBST_DISABLE)); - and_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1, - ~(RADIO_2055_GAINBST_DISABLE)); - } else { - or_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1, - RADIO_2055_GAINBST_DISABLE); - or_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1, - RADIO_2055_GAINBST_DISABLE); - } - - udelay(2); -} - -static void wlc_phy_radio_preinit_205x(phy_info_t *pi) -{ - - and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU); - and_phy_reg(pi, 0x78, RFCC_OE_POR_FORCE); - - or_phy_reg(pi, 0x78, ~RFCC_OE_POR_FORCE); - or_phy_reg(pi, 0x78, RFCC_CHIP0_PU); - -} - -static void wlc_phy_radio_init_2056(phy_info_t *pi) -{ - radio_regs_t *regs_SYN_2056_ptr = NULL; - radio_regs_t *regs_TX_2056_ptr = NULL; - radio_regs_t *regs_RX_2056_ptr = NULL; - - if (NREV_IS(pi->pubpi.phy_rev, 3)) { - regs_SYN_2056_ptr = regs_SYN_2056; - regs_TX_2056_ptr = regs_TX_2056; - regs_RX_2056_ptr = regs_RX_2056; - } else if (NREV_IS(pi->pubpi.phy_rev, 4)) { - regs_SYN_2056_ptr = regs_SYN_2056_A1; - regs_TX_2056_ptr = regs_TX_2056_A1; - regs_RX_2056_ptr = regs_RX_2056_A1; - } else { - switch (pi->pubpi.radiorev) { - case 5: - regs_SYN_2056_ptr = regs_SYN_2056_rev5; - regs_TX_2056_ptr = regs_TX_2056_rev5; - regs_RX_2056_ptr = regs_RX_2056_rev5; - break; - - case 6: - regs_SYN_2056_ptr = regs_SYN_2056_rev6; - regs_TX_2056_ptr = regs_TX_2056_rev6; - regs_RX_2056_ptr = regs_RX_2056_rev6; - break; - - case 7: - case 9: - regs_SYN_2056_ptr = regs_SYN_2056_rev7; - regs_TX_2056_ptr = regs_TX_2056_rev7; - regs_RX_2056_ptr = regs_RX_2056_rev7; - break; - - case 8: - regs_SYN_2056_ptr = regs_SYN_2056_rev8; - regs_TX_2056_ptr = regs_TX_2056_rev8; - regs_RX_2056_ptr = regs_RX_2056_rev8; - break; - - case 11: - regs_SYN_2056_ptr = regs_SYN_2056_rev11; - regs_TX_2056_ptr = regs_TX_2056_rev11; - regs_RX_2056_ptr = regs_RX_2056_rev11; - break; - - default: - ASSERT(0); - break; - } - } - - wlc_phy_init_radio_regs(pi, regs_SYN_2056_ptr, (u16) RADIO_2056_SYN); - - wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX0); - - wlc_phy_init_radio_regs(pi, regs_TX_2056_ptr, (u16) RADIO_2056_TX1); - - wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX0); - - wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX1); -} - -static void wlc_phy_radio_postinit_2056(phy_info_t *pi) -{ - mod_radio_reg(pi, RADIO_2056_SYN_COM_CTRL, 0xb, 0xb); - - mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x2); - mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x2); - udelay(1000); - mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x0); - - if ((pi->sh->boardflags2 & BFL2_LEGACY) - || (pi->sh->boardflags2 & BFL2_XTALBUFOUTEN)) { - - mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xf4, 0x0); - } else { - - mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xfc, 0x0); - } - - mod_radio_reg(pi, RADIO_2056_SYN_RCCAL_CTRL0, 0x1, 0x0); - - if (pi->phy_init_por) { - wlc_phy_radio205x_rcal(pi); - } -} - -static void wlc_phy_radio_init_2057(phy_info_t *pi) -{ - radio_20xx_regs_t *regs_2057_ptr = NULL; - - if (NREV_IS(pi->pubpi.phy_rev, 7)) { - - regs_2057_ptr = regs_2057_rev4; - } else if (NREV_IS(pi->pubpi.phy_rev, 8) - || NREV_IS(pi->pubpi.phy_rev, 9)) { - switch (pi->pubpi.radiorev) { - case 5: - - if (pi->pubpi.radiover == 0x0) { - - regs_2057_ptr = regs_2057_rev5; - - } else if (pi->pubpi.radiover == 0x1) { - - regs_2057_ptr = regs_2057_rev5v1; - } else { - ASSERT(0); - break; - } - - case 7: - - regs_2057_ptr = regs_2057_rev7; - break; - - case 8: - - regs_2057_ptr = regs_2057_rev8; - break; - - default: - ASSERT(0); - break; - } - } else { - ASSERT(0); - } - - wlc_phy_init_radio_regs_allbands(pi, regs_2057_ptr); -} - -static void wlc_phy_radio_postinit_2057(phy_info_t *pi) -{ - - mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x1, 0x1); - - if (pi->sh->chip == !BCM6362_CHIP_ID) { - - mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x2, 0x2); - } - - mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x78); - mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x80); - mdelay(2); - mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x0); - mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x0); - - if (pi->phy_init_por) { - wlc_phy_radio205x_rcal(pi); - wlc_phy_radio2057_rccal(pi); - } - - mod_radio_reg(pi, RADIO_2057_RFPLL_MASTER, 0x8, 0x0); -} - -static bool -wlc_phy_chan2freq_nphy(phy_info_t *pi, uint channel, int *f, - chan_info_nphy_radio2057_t **t0, - chan_info_nphy_radio205x_t **t1, - chan_info_nphy_radio2057_rev5_t **t2, - chan_info_nphy_2055_t **t3) -{ - uint i; - chan_info_nphy_radio2057_t *chan_info_tbl_p_0 = NULL; - chan_info_nphy_radio205x_t *chan_info_tbl_p_1 = NULL; - chan_info_nphy_radio2057_rev5_t *chan_info_tbl_p_2 = NULL; - u32 tbl_len = 0; - - int freq = 0; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - if (NREV_IS(pi->pubpi.phy_rev, 7)) { - - chan_info_tbl_p_0 = chan_info_nphyrev7_2057_rev4; - tbl_len = ARRAY_SIZE(chan_info_nphyrev7_2057_rev4); - - } else if (NREV_IS(pi->pubpi.phy_rev, 8) - || NREV_IS(pi->pubpi.phy_rev, 9)) { - switch (pi->pubpi.radiorev) { - - case 5: - - if (pi->pubpi.radiover == 0x0) { - - chan_info_tbl_p_2 = - chan_info_nphyrev8_2057_rev5; - tbl_len = - ARRAY_SIZE - (chan_info_nphyrev8_2057_rev5); - - } else if (pi->pubpi.radiover == 0x1) { - - chan_info_tbl_p_2 = - chan_info_nphyrev9_2057_rev5v1; - tbl_len = - ARRAY_SIZE - (chan_info_nphyrev9_2057_rev5v1); - - } - break; - - case 7: - chan_info_tbl_p_0 = - chan_info_nphyrev8_2057_rev7; - tbl_len = - ARRAY_SIZE(chan_info_nphyrev8_2057_rev7); - break; - - case 8: - chan_info_tbl_p_0 = - chan_info_nphyrev8_2057_rev8; - tbl_len = - ARRAY_SIZE(chan_info_nphyrev8_2057_rev8); - break; - - default: - if (NORADIO_ENAB(pi->pubpi)) { - goto fail; - } - break; - } - } else if (NREV_IS(pi->pubpi.phy_rev, 16)) { - - chan_info_tbl_p_0 = chan_info_nphyrev8_2057_rev8; - tbl_len = ARRAY_SIZE(chan_info_nphyrev8_2057_rev8); - } else { - goto fail; - } - - for (i = 0; i < tbl_len; i++) { - if (pi->pubpi.radiorev == 5) { - - if (chan_info_tbl_p_2[i].chan == channel) - break; - } else { - - if (chan_info_tbl_p_0[i].chan == channel) - break; - } - } - - if (i >= tbl_len) { - ASSERT(i < tbl_len); - goto fail; - } - if (pi->pubpi.radiorev == 5) { - *t2 = &chan_info_tbl_p_2[i]; - freq = chan_info_tbl_p_2[i].freq; - } else { - *t0 = &chan_info_tbl_p_0[i]; - freq = chan_info_tbl_p_0[i].freq; - } - - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if (NREV_IS(pi->pubpi.phy_rev, 3)) { - chan_info_tbl_p_1 = chan_info_nphyrev3_2056; - tbl_len = ARRAY_SIZE(chan_info_nphyrev3_2056); - } else if (NREV_IS(pi->pubpi.phy_rev, 4)) { - chan_info_tbl_p_1 = chan_info_nphyrev4_2056_A1; - tbl_len = ARRAY_SIZE(chan_info_nphyrev4_2056_A1); - } else if (NREV_IS(pi->pubpi.phy_rev, 5) - || NREV_IS(pi->pubpi.phy_rev, 6)) { - switch (pi->pubpi.radiorev) { - case 5: - chan_info_tbl_p_1 = chan_info_nphyrev5_2056v5; - tbl_len = ARRAY_SIZE(chan_info_nphyrev5_2056v5); - break; - case 6: - chan_info_tbl_p_1 = chan_info_nphyrev6_2056v6; - tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v6); - break; - case 7: - case 9: - chan_info_tbl_p_1 = chan_info_nphyrev5n6_2056v7; - tbl_len = - ARRAY_SIZE(chan_info_nphyrev5n6_2056v7); - break; - case 8: - chan_info_tbl_p_1 = chan_info_nphyrev6_2056v8; - tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v8); - break; - case 11: - chan_info_tbl_p_1 = chan_info_nphyrev6_2056v11; - tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v11); - break; - default: - if (NORADIO_ENAB(pi->pubpi)) { - goto fail; - } - break; - } - } - - for (i = 0; i < tbl_len; i++) { - if (chan_info_tbl_p_1[i].chan == channel) - break; - } - - if (i >= tbl_len) { - ASSERT(i < tbl_len); - goto fail; - } - *t1 = &chan_info_tbl_p_1[i]; - freq = chan_info_tbl_p_1[i].freq; - - } else { - for (i = 0; i < ARRAY_SIZE(chan_info_nphy_2055); i++) - if (chan_info_nphy_2055[i].chan == channel) - break; - - if (i >= ARRAY_SIZE(chan_info_nphy_2055)) { - ASSERT(i < ARRAY_SIZE(chan_info_nphy_2055)); - goto fail; - } - *t3 = &chan_info_nphy_2055[i]; - freq = chan_info_nphy_2055[i].freq; - } - - *f = freq; - return true; - - fail: - *f = WL_CHAN_FREQ_RANGE_2G; - return false; -} - -u8 wlc_phy_get_chan_freq_range_nphy(phy_info_t *pi, uint channel) -{ - int freq; - chan_info_nphy_radio2057_t *t0 = NULL; - chan_info_nphy_radio205x_t *t1 = NULL; - chan_info_nphy_radio2057_rev5_t *t2 = NULL; - chan_info_nphy_2055_t *t3 = NULL; - - if (NORADIO_ENAB(pi->pubpi)) - return WL_CHAN_FREQ_RANGE_2G; - - if (channel == 0) - channel = CHSPEC_CHANNEL(pi->radio_chanspec); - - wlc_phy_chan2freq_nphy(pi, channel, &freq, &t0, &t1, &t2, &t3); - - if (CHSPEC_IS2G(pi->radio_chanspec)) - return WL_CHAN_FREQ_RANGE_2G; - - if ((freq >= BASE_LOW_5G_CHAN) && (freq < BASE_MID_5G_CHAN)) { - return WL_CHAN_FREQ_RANGE_5GL; - } else if ((freq >= BASE_MID_5G_CHAN) && (freq < BASE_HIGH_5G_CHAN)) { - return WL_CHAN_FREQ_RANGE_5GM; - } else { - return WL_CHAN_FREQ_RANGE_5GH; - } -} - -static void -wlc_phy_chanspec_radio2055_setup(phy_info_t *pi, chan_info_nphy_2055_t *ci) -{ - - write_radio_reg(pi, RADIO_2055_PLL_REF, ci->RF_pll_ref); - write_radio_reg(pi, RADIO_2055_RF_PLL_MOD0, ci->RF_rf_pll_mod0); - write_radio_reg(pi, RADIO_2055_RF_PLL_MOD1, ci->RF_rf_pll_mod1); - write_radio_reg(pi, RADIO_2055_VCO_CAP_TAIL, ci->RF_vco_cap_tail); - - WLC_PHY_WAR_PR51571(pi); - - write_radio_reg(pi, RADIO_2055_VCO_CAL1, ci->RF_vco_cal1); - write_radio_reg(pi, RADIO_2055_VCO_CAL2, ci->RF_vco_cal2); - write_radio_reg(pi, RADIO_2055_PLL_LF_C1, ci->RF_pll_lf_c1); - write_radio_reg(pi, RADIO_2055_PLL_LF_R1, ci->RF_pll_lf_r1); - - WLC_PHY_WAR_PR51571(pi); - - write_radio_reg(pi, RADIO_2055_PLL_LF_C2, ci->RF_pll_lf_c2); - write_radio_reg(pi, RADIO_2055_LGBUF_CEN_BUF, ci->RF_lgbuf_cen_buf); - write_radio_reg(pi, RADIO_2055_LGEN_TUNE1, ci->RF_lgen_tune1); - write_radio_reg(pi, RADIO_2055_LGEN_TUNE2, ci->RF_lgen_tune2); - - WLC_PHY_WAR_PR51571(pi); - - write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_A_TUNE, - ci->RF_core1_lgbuf_a_tune); - write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_G_TUNE, - ci->RF_core1_lgbuf_g_tune); - write_radio_reg(pi, RADIO_2055_CORE1_RXRF_REG1, ci->RF_core1_rxrf_reg1); - write_radio_reg(pi, RADIO_2055_CORE1_TX_PGA_PAD_TN, - ci->RF_core1_tx_pga_pad_tn); - - WLC_PHY_WAR_PR51571(pi); - - write_radio_reg(pi, RADIO_2055_CORE1_TX_MX_BGTRIM, - ci->RF_core1_tx_mx_bgtrim); - write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_A_TUNE, - ci->RF_core2_lgbuf_a_tune); - write_radio_reg(pi, RADIO_2055_CORE2_LGBUF_G_TUNE, - ci->RF_core2_lgbuf_g_tune); - write_radio_reg(pi, RADIO_2055_CORE2_RXRF_REG1, ci->RF_core2_rxrf_reg1); - - WLC_PHY_WAR_PR51571(pi); - - write_radio_reg(pi, RADIO_2055_CORE2_TX_PGA_PAD_TN, - ci->RF_core2_tx_pga_pad_tn); - write_radio_reg(pi, RADIO_2055_CORE2_TX_MX_BGTRIM, - ci->RF_core2_tx_mx_bgtrim); - - udelay(50); - - write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x05); - write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x45); - - WLC_PHY_WAR_PR51571(pi); - - write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x65); - - udelay(300); -} - -static void -wlc_phy_chanspec_radio2056_setup(phy_info_t *pi, - const chan_info_nphy_radio205x_t *ci) -{ - radio_regs_t *regs_SYN_2056_ptr = NULL; - - write_radio_reg(pi, - RADIO_2056_SYN_PLL_VCOCAL1 | RADIO_2056_SYN, - ci->RF_SYN_pll_vcocal1); - write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL2 | RADIO_2056_SYN, - ci->RF_SYN_pll_vcocal2); - write_radio_reg(pi, RADIO_2056_SYN_PLL_REFDIV | RADIO_2056_SYN, - ci->RF_SYN_pll_refdiv); - write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD2 | RADIO_2056_SYN, - ci->RF_SYN_pll_mmd2); - write_radio_reg(pi, RADIO_2056_SYN_PLL_MMD1 | RADIO_2056_SYN, - ci->RF_SYN_pll_mmd1); - write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN, - ci->RF_SYN_pll_loopfilter1); - write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN, - ci->RF_SYN_pll_loopfilter2); - write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER3 | RADIO_2056_SYN, - ci->RF_SYN_pll_loopfilter3); - write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN, - ci->RF_SYN_pll_loopfilter4); - write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER5 | RADIO_2056_SYN, - ci->RF_SYN_pll_loopfilter5); - write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR27 | RADIO_2056_SYN, - ci->RF_SYN_reserved_addr27); - write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR28 | RADIO_2056_SYN, - ci->RF_SYN_reserved_addr28); - write_radio_reg(pi, RADIO_2056_SYN_RESERVED_ADDR29 | RADIO_2056_SYN, - ci->RF_SYN_reserved_addr29); - write_radio_reg(pi, RADIO_2056_SYN_LOGEN_VCOBUF1 | RADIO_2056_SYN, - ci->RF_SYN_logen_VCOBUF1); - write_radio_reg(pi, RADIO_2056_SYN_LOGEN_MIXER2 | RADIO_2056_SYN, - ci->RF_SYN_logen_MIXER2); - write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF3 | RADIO_2056_SYN, - ci->RF_SYN_logen_BUF3); - write_radio_reg(pi, RADIO_2056_SYN_LOGEN_BUF4 | RADIO_2056_SYN, - ci->RF_SYN_logen_BUF4); - - write_radio_reg(pi, - RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX0, - ci->RF_RX0_lnaa_tune); - write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX0, - ci->RF_RX0_lnag_tune); - write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX0, - ci->RF_TX0_intpaa_boost_tune); - write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX0, - ci->RF_TX0_intpag_boost_tune); - write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX0, - ci->RF_TX0_pada_boost_tune); - write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX0, - ci->RF_TX0_padg_boost_tune); - write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX0, - ci->RF_TX0_pgaa_boost_tune); - write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX0, - ci->RF_TX0_pgag_boost_tune); - write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX0, - ci->RF_TX0_mixa_boost_tune); - write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX0, - ci->RF_TX0_mixg_boost_tune); - - write_radio_reg(pi, - RADIO_2056_RX_LNAA_TUNE | RADIO_2056_RX1, - ci->RF_RX1_lnaa_tune); - write_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | RADIO_2056_RX1, - ci->RF_RX1_lnag_tune); - write_radio_reg(pi, RADIO_2056_TX_INTPAA_BOOST_TUNE | RADIO_2056_TX1, - ci->RF_TX1_intpaa_boost_tune); - write_radio_reg(pi, RADIO_2056_TX_INTPAG_BOOST_TUNE | RADIO_2056_TX1, - ci->RF_TX1_intpag_boost_tune); - write_radio_reg(pi, RADIO_2056_TX_PADA_BOOST_TUNE | RADIO_2056_TX1, - ci->RF_TX1_pada_boost_tune); - write_radio_reg(pi, RADIO_2056_TX_PADG_BOOST_TUNE | RADIO_2056_TX1, - ci->RF_TX1_padg_boost_tune); - write_radio_reg(pi, RADIO_2056_TX_PGAA_BOOST_TUNE | RADIO_2056_TX1, - ci->RF_TX1_pgaa_boost_tune); - write_radio_reg(pi, RADIO_2056_TX_PGAG_BOOST_TUNE | RADIO_2056_TX1, - ci->RF_TX1_pgag_boost_tune); - write_radio_reg(pi, RADIO_2056_TX_MIXA_BOOST_TUNE | RADIO_2056_TX1, - ci->RF_TX1_mixa_boost_tune); - write_radio_reg(pi, RADIO_2056_TX_MIXG_BOOST_TUNE | RADIO_2056_TX1, - ci->RF_TX1_mixg_boost_tune); - - if (NREV_IS(pi->pubpi.phy_rev, 3)) - regs_SYN_2056_ptr = regs_SYN_2056; - else if (NREV_IS(pi->pubpi.phy_rev, 4)) - regs_SYN_2056_ptr = regs_SYN_2056_A1; - else { - switch (pi->pubpi.radiorev) { - case 5: - regs_SYN_2056_ptr = regs_SYN_2056_rev5; - break; - case 6: - regs_SYN_2056_ptr = regs_SYN_2056_rev6; - break; - case 7: - case 9: - regs_SYN_2056_ptr = regs_SYN_2056_rev7; - break; - case 8: - regs_SYN_2056_ptr = regs_SYN_2056_rev8; - break; - case 11: - regs_SYN_2056_ptr = regs_SYN_2056_rev11; - break; - } - } - if (CHSPEC_IS2G(pi->radio_chanspec)) { - write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 | - RADIO_2056_SYN, - (u16) regs_SYN_2056_ptr[0x49 - 2].init_g); - } else { - write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 | - RADIO_2056_SYN, - (u16) regs_SYN_2056_ptr[0x49 - 2].init_a); - } - - if (pi->sh->boardflags2 & BFL2_GPLL_WAR) { - if (CHSPEC_IS2G(pi->radio_chanspec)) { - write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 | - RADIO_2056_SYN, 0x1f); - write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 | - RADIO_2056_SYN, 0x1f); - - if ((pi->sh->chip == BCM4716_CHIP_ID) || - (pi->sh->chip == BCM47162_CHIP_ID)) { - - write_radio_reg(pi, - RADIO_2056_SYN_PLL_LOOPFILTER4 | - RADIO_2056_SYN, 0x14); - write_radio_reg(pi, - RADIO_2056_SYN_PLL_CP2 | - RADIO_2056_SYN, 0x00); - } else { - write_radio_reg(pi, - RADIO_2056_SYN_PLL_LOOPFILTER4 | - RADIO_2056_SYN, 0xb); - write_radio_reg(pi, - RADIO_2056_SYN_PLL_CP2 | - RADIO_2056_SYN, 0x14); - } - } - } - - if ((pi->sh->boardflags2 & BFL2_GPLL_WAR2) && - (CHSPEC_IS2G(pi->radio_chanspec))) { - write_radio_reg(pi, - RADIO_2056_SYN_PLL_LOOPFILTER1 | RADIO_2056_SYN, - 0x1f); - write_radio_reg(pi, - RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN, - 0x1f); - write_radio_reg(pi, - RADIO_2056_SYN_PLL_LOOPFILTER4 | RADIO_2056_SYN, - 0xb); - write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 | RADIO_2056_SYN, - 0x20); - } - - if (pi->sh->boardflags2 & BFL2_APLL_WAR) { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER1 | - RADIO_2056_SYN, 0x1f); - write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 | - RADIO_2056_SYN, 0x1f); - write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 | - RADIO_2056_SYN, 0x5); - write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 | - RADIO_2056_SYN, 0xc); - } - } - - if (PHY_IPA(pi) && CHSPEC_IS2G(pi->radio_chanspec)) { - u16 pag_boost_tune; - u16 padg_boost_tune; - u16 pgag_boost_tune; - u16 mixg_boost_tune; - u16 bias, cascbias; - uint core; - - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - - if (NREV_GE(pi->pubpi.phy_rev, 5)) { - - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - PADG_IDAC, 0xcc); - - if ((pi->sh->chip == BCM4716_CHIP_ID) || - (pi->sh->chip == - BCM47162_CHIP_ID)) { - bias = 0x40; - cascbias = 0x45; - pag_boost_tune = 0x5; - pgag_boost_tune = 0x33; - padg_boost_tune = 0x77; - mixg_boost_tune = 0x55; - } else { - bias = 0x25; - cascbias = 0x20; - - if ((pi->sh->chip == - BCM43224_CHIP_ID) - || (pi->sh->chip == - BCM43225_CHIP_ID) - || (pi->sh->chip == - BCM43421_CHIP_ID)) { - if (pi->sh->chippkg == - BCM43224_FAB_SMIC) { - bias = 0x2a; - cascbias = 0x38; - } - } - - pag_boost_tune = 0x4; - pgag_boost_tune = 0x03; - padg_boost_tune = 0x77; - mixg_boost_tune = 0x65; - } - - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAG_IMAIN_STAT, bias); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAG_IAUX_STAT, bias); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAG_CASCBIAS, cascbias); - - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAG_BOOST_TUNE, - pag_boost_tune); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - PGAG_BOOST_TUNE, - pgag_boost_tune); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - PADG_BOOST_TUNE, - padg_boost_tune); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - MIXG_BOOST_TUNE, - mixg_boost_tune); - } else { - - bias = IS40MHZ(pi) ? 0x40 : 0x20; - - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAG_IMAIN_STAT, bias); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAG_IAUX_STAT, bias); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAG_CASCBIAS, 0x30); - } - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, PA_SPARE1, - 0xee); - } - } - - if (PHY_IPA(pi) && NREV_IS(pi->pubpi.phy_rev, 6) - && CHSPEC_IS5G(pi->radio_chanspec)) { - u16 paa_boost_tune; - u16 pada_boost_tune; - u16 pgaa_boost_tune; - u16 mixa_boost_tune; - u16 freq, pabias, cascbias; - uint core; - - freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec)); - - if (freq < 5150) { - - paa_boost_tune = 0xa; - pada_boost_tune = 0x77; - pgaa_boost_tune = 0xf; - mixa_boost_tune = 0xf; - } else if (freq < 5340) { - - paa_boost_tune = 0x8; - pada_boost_tune = 0x77; - pgaa_boost_tune = 0xfb; - mixa_boost_tune = 0xf; - } else if (freq < 5650) { - - paa_boost_tune = 0x0; - pada_boost_tune = 0x77; - pgaa_boost_tune = 0xb; - mixa_boost_tune = 0xf; - } else { - - paa_boost_tune = 0x0; - pada_boost_tune = 0x77; - if (freq != 5825) { - pgaa_boost_tune = -(int)(freq - 18) / 36 + 168; - } else { - pgaa_boost_tune = 6; - } - mixa_boost_tune = 0xf; - } - - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAA_BOOST_TUNE, paa_boost_tune); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - PADA_BOOST_TUNE, pada_boost_tune); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - PGAA_BOOST_TUNE, pgaa_boost_tune); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - MIXA_BOOST_TUNE, mixa_boost_tune); - - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - TXSPARE1, 0x30); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - PA_SPARE2, 0xee); - - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - PADA_CASCBIAS, 0x3); - - cascbias = 0x30; - - if ((pi->sh->chip == BCM43224_CHIP_ID) || - (pi->sh->chip == BCM43225_CHIP_ID) || - (pi->sh->chip == BCM43421_CHIP_ID)) { - if (pi->sh->chippkg == BCM43224_FAB_SMIC) { - cascbias = 0x35; - } - } - - pabias = (pi->phy_pabias == 0) ? 0x30 : pi->phy_pabias; - - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAA_IAUX_STAT, pabias); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAA_IMAIN_STAT, pabias); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAA_CASCBIAS, cascbias); - } - } - - udelay(50); - - wlc_phy_radio205x_vcocal_nphy(pi); -} - -void wlc_phy_radio205x_vcocal_nphy(phy_info_t *pi) -{ - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x0); - mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04, 0x0); - mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x04, - (1 << 2)); - mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x01); - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL12, 0x0); - write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38); - write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x18); - write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x38); - write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST3, 0x39); - } - - udelay(300); -} - -#define MAX_205x_RCAL_WAITLOOPS 10000 - -static u16 wlc_phy_radio205x_rcal(phy_info_t *pi) -{ - u16 rcal_reg = 0; - int i; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - if (pi->pubpi.radiorev == 5) { - - and_phy_reg(pi, 0x342, ~(0x1 << 1)); - - udelay(10); - - mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x1); - mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2, - 0x1); - } - mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x1); - - udelay(10); - - mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x3, 0x3); - - for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { - rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS); - if (rcal_reg & 0x1) { - break; - } - udelay(100); - } - - ASSERT(i < MAX_205x_RCAL_WAITLOOPS); - - mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x2, 0x0); - - rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS) & 0x3e; - - mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x0); - if (pi->pubpi.radiorev == 5) { - - mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x0); - mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2, - 0x0); - } - - if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) { - - mod_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x3c, - rcal_reg); - mod_radio_reg(pi, RADIO_2057_BANDGAP_RCAL_TRIM, 0xf0, - rcal_reg << 2); - } - - } else if (NREV_IS(pi->pubpi.phy_rev, 3)) { - u16 savereg; - - savereg = - read_radio_reg(pi, - RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN); - write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN, - savereg | 0x7); - udelay(10); - - write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN, - 0x1); - udelay(10); - - write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN, - 0x9); - - for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { - rcal_reg = read_radio_reg(pi, - RADIO_2056_SYN_RCAL_CODE_OUT | - RADIO_2056_SYN); - if (rcal_reg & 0x80) { - break; - } - udelay(100); - } - - ASSERT(i < MAX_205x_RCAL_WAITLOOPS); - - write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN, - 0x1); - - rcal_reg = - read_radio_reg(pi, - RADIO_2056_SYN_RCAL_CODE_OUT | - RADIO_2056_SYN); - - write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN, - 0x0); - - write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN, - savereg); - - return rcal_reg & 0x1f; - } - return rcal_reg & 0x3e; -} - -static void -wlc_phy_chanspec_radio2057_setup(phy_info_t *pi, - const chan_info_nphy_radio2057_t *ci, - const chan_info_nphy_radio2057_rev5_t *ci2) -{ - int coreNum; - u16 txmix2g_tune_boost_pu = 0; - u16 pad2g_tune_pus = 0; - - if (pi->pubpi.radiorev == 5) { - - write_radio_reg(pi, - RADIO_2057_VCOCAL_COUNTVAL0, - ci2->RF_vcocal_countval0); - write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1, - ci2->RF_vcocal_countval1); - write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE, - ci2->RF_rfpll_refmaster_sparextalsize); - write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1, - ci2->RF_rfpll_loopfilter_r1); - write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2, - ci2->RF_rfpll_loopfilter_c2); - write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1, - ci2->RF_rfpll_loopfilter_c1); - write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, - ci2->RF_cp_kpd_idac); - write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci2->RF_rfpll_mmd0); - write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci2->RF_rfpll_mmd1); - write_radio_reg(pi, - RADIO_2057_VCOBUF_TUNE, ci2->RF_vcobuf_tune); - write_radio_reg(pi, - RADIO_2057_LOGEN_MX2G_TUNE, - ci2->RF_logen_mx2g_tune); - write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE, - ci2->RF_logen_indbuf2g_tune); - - write_radio_reg(pi, - RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0, - ci2->RF_txmix2g_tune_boost_pu_core0); - write_radio_reg(pi, - RADIO_2057_PAD2G_TUNE_PUS_CORE0, - ci2->RF_pad2g_tune_pus_core0); - write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0, - ci2->RF_lna2g_tune_core0); - - write_radio_reg(pi, - RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1, - ci2->RF_txmix2g_tune_boost_pu_core1); - write_radio_reg(pi, - RADIO_2057_PAD2G_TUNE_PUS_CORE1, - ci2->RF_pad2g_tune_pus_core1); - write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1, - ci2->RF_lna2g_tune_core1); - - } else { - - write_radio_reg(pi, - RADIO_2057_VCOCAL_COUNTVAL0, - ci->RF_vcocal_countval0); - write_radio_reg(pi, RADIO_2057_VCOCAL_COUNTVAL1, - ci->RF_vcocal_countval1); - write_radio_reg(pi, RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE, - ci->RF_rfpll_refmaster_sparextalsize); - write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1, - ci->RF_rfpll_loopfilter_r1); - write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2, - ci->RF_rfpll_loopfilter_c2); - write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1, - ci->RF_rfpll_loopfilter_c1); - write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, ci->RF_cp_kpd_idac); - write_radio_reg(pi, RADIO_2057_RFPLL_MMD0, ci->RF_rfpll_mmd0); - write_radio_reg(pi, RADIO_2057_RFPLL_MMD1, ci->RF_rfpll_mmd1); - write_radio_reg(pi, RADIO_2057_VCOBUF_TUNE, ci->RF_vcobuf_tune); - write_radio_reg(pi, - RADIO_2057_LOGEN_MX2G_TUNE, - ci->RF_logen_mx2g_tune); - write_radio_reg(pi, RADIO_2057_LOGEN_MX5G_TUNE, - ci->RF_logen_mx5g_tune); - write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF2G_TUNE, - ci->RF_logen_indbuf2g_tune); - write_radio_reg(pi, RADIO_2057_LOGEN_INDBUF5G_TUNE, - ci->RF_logen_indbuf5g_tune); - - write_radio_reg(pi, - RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0, - ci->RF_txmix2g_tune_boost_pu_core0); - write_radio_reg(pi, - RADIO_2057_PAD2G_TUNE_PUS_CORE0, - ci->RF_pad2g_tune_pus_core0); - write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE0, - ci->RF_pga_boost_tune_core0); - write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0, - ci->RF_txmix5g_boost_tune_core0); - write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0, - ci->RF_pad5g_tune_misc_pus_core0); - write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE0, - ci->RF_lna2g_tune_core0); - write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE0, - ci->RF_lna5g_tune_core0); - - write_radio_reg(pi, - RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1, - ci->RF_txmix2g_tune_boost_pu_core1); - write_radio_reg(pi, - RADIO_2057_PAD2G_TUNE_PUS_CORE1, - ci->RF_pad2g_tune_pus_core1); - write_radio_reg(pi, RADIO_2057_PGA_BOOST_TUNE_CORE1, - ci->RF_pga_boost_tune_core1); - write_radio_reg(pi, RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1, - ci->RF_txmix5g_boost_tune_core1); - write_radio_reg(pi, RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1, - ci->RF_pad5g_tune_misc_pus_core1); - write_radio_reg(pi, RADIO_2057_LNA2G_TUNE_CORE1, - ci->RF_lna2g_tune_core1); - write_radio_reg(pi, RADIO_2057_LNA5G_TUNE_CORE1, - ci->RF_lna5g_tune_core1); - } - - if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) { - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1, - 0x3f); - write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f); - write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1, - 0x8); - write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2, - 0x8); - } else { - write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1, - 0x1f); - write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f); - write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1, - 0x8); - write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2, - 0x8); - } - } else if ((pi->pubpi.radiorev == 5) || (pi->pubpi.radiorev == 7) || - (pi->pubpi.radiorev == 8)) { - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1, - 0x1b); - write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x30); - write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1, - 0xa); - write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2, - 0xa); - } else { - write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_R1, - 0x1f); - write_radio_reg(pi, RADIO_2057_CP_KPD_IDAC, 0x3f); - write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C1, - 0x8); - write_radio_reg(pi, RADIO_2057_RFPLL_LOOPFILTER_C2, - 0x8); - } - - } - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (PHY_IPA(pi)) { - if (pi->pubpi.radiorev == 3) { - txmix2g_tune_boost_pu = 0x6b; - } - - if (pi->pubpi.radiorev == 5) - pad2g_tune_pus = 0x73; - - } else { - if (pi->pubpi.radiorev != 5) { - pad2g_tune_pus = 0x3; - - txmix2g_tune_boost_pu = 0x61; - } - } - - for (coreNum = 0; coreNum <= 1; coreNum++) { - - if (txmix2g_tune_boost_pu != 0) - WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum, - TXMIX2G_TUNE_BOOST_PU, - txmix2g_tune_boost_pu); - - if (pad2g_tune_pus != 0) - WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum, - PAD2G_TUNE_PUS, - pad2g_tune_pus); - } - } - - udelay(50); - - wlc_phy_radio205x_vcocal_nphy(pi); -} - -static u16 wlc_phy_radio2057_rccal(phy_info_t *pi) -{ - u16 rccal_valid; - int i; - bool chip43226_6362A0; - - chip43226_6362A0 = ((pi->pubpi.radiorev == 3) - || (pi->pubpi.radiorev == 4) - || (pi->pubpi.radiorev == 6)); - - rccal_valid = 0; - if (chip43226_6362A0) { - write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x61); - write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xc0); - } else { - write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x61); - - write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xe9); - } - write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e); - write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55); - - for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { - rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP); - if (rccal_valid & 0x2) { - break; - } - udelay(500); - } - - ASSERT(rccal_valid & 0x2); - - write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15); - - rccal_valid = 0; - if (chip43226_6362A0) { - write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x69); - write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0); - } else { - write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x69); - - write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xd5); - } - write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e); - write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55); - - for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { - rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP); - if (rccal_valid & 0x2) { - break; - } - udelay(500); - } - - ASSERT(rccal_valid & 0x2); - - write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15); - - rccal_valid = 0; - if (chip43226_6362A0) { - write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x73); - - write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x28); - write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0); - } else { - write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x73); - write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e); - write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0x99); - } - write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55); - - for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { - rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP); - if (rccal_valid & 0x2) { - break; - } - udelay(500); - } - - ASSERT(rccal_valid & 0x2); - - write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15); - - return rccal_valid; -} - -static void -wlc_phy_adjust_rx_analpfbw_nphy(phy_info_t *pi, u16 reduction_factr) -{ - if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) { - if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) && - CHSPEC_IS40(pi->radio_chanspec)) { - if (!pi->nphy_anarxlpf_adjusted) { - write_radio_reg(pi, - (RADIO_2056_RX_RXLPF_RCCAL_LPC | - RADIO_2056_RX0), - ((pi->nphy_rccal_value + - reduction_factr) | 0x80)); - - pi->nphy_anarxlpf_adjusted = true; - } - } else { - if (pi->nphy_anarxlpf_adjusted) { - write_radio_reg(pi, - (RADIO_2056_RX_RXLPF_RCCAL_LPC | - RADIO_2056_RX0), - (pi->nphy_rccal_value | 0x80)); - - pi->nphy_anarxlpf_adjusted = false; - } - } - } -} - -static void -wlc_phy_adjust_min_noisevar_nphy(phy_info_t *pi, int ntones, int *tone_id_buf, - u32 *noise_var_buf) -{ - int i; - u32 offset; - int tone_id; - int tbllen = - CHSPEC_IS40(pi-> - radio_chanspec) ? NPHY_NOISEVAR_TBLLEN40 : - NPHY_NOISEVAR_TBLLEN20; - - if (pi->nphy_noisevars_adjusted) { - for (i = 0; i < pi->nphy_saved_noisevars.bufcount; i++) { - tone_id = pi->nphy_saved_noisevars.tone_id[i]; - offset = (tone_id >= 0) ? - ((tone_id * 2) + 1) : (tbllen + (tone_id * 2) + 1); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, - offset, 32, - (void *)&pi-> - nphy_saved_noisevars. - min_noise_vars[i]); - } - - pi->nphy_saved_noisevars.bufcount = 0; - pi->nphy_noisevars_adjusted = false; - } - - if ((noise_var_buf != NULL) && (tone_id_buf != NULL)) { - pi->nphy_saved_noisevars.bufcount = 0; - - for (i = 0; i < ntones; i++) { - tone_id = tone_id_buf[i]; - offset = (tone_id >= 0) ? - ((tone_id * 2) + 1) : (tbllen + (tone_id * 2) + 1); - pi->nphy_saved_noisevars.tone_id[i] = tone_id; - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, - offset, 32, - &pi->nphy_saved_noisevars. - min_noise_vars[i]); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, - offset, 32, - (void *)&noise_var_buf[i]); - pi->nphy_saved_noisevars.bufcount++; - } - - pi->nphy_noisevars_adjusted = true; - } -} - -static void wlc_phy_adjust_crsminpwr_nphy(phy_info_t *pi, u8 minpwr) -{ - u16 regval; - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) && - CHSPEC_IS40(pi->radio_chanspec)) { - if (!pi->nphy_crsminpwr_adjusted) { - regval = read_phy_reg(pi, 0x27d); - pi->nphy_crsminpwr[0] = regval & 0xff; - regval &= 0xff00; - regval |= (u16) minpwr; - write_phy_reg(pi, 0x27d, regval); - - regval = read_phy_reg(pi, 0x280); - pi->nphy_crsminpwr[1] = regval & 0xff; - regval &= 0xff00; - regval |= (u16) minpwr; - write_phy_reg(pi, 0x280, regval); - - regval = read_phy_reg(pi, 0x283); - pi->nphy_crsminpwr[2] = regval & 0xff; - regval &= 0xff00; - regval |= (u16) minpwr; - write_phy_reg(pi, 0x283, regval); - - pi->nphy_crsminpwr_adjusted = true; - } - } else { - if (pi->nphy_crsminpwr_adjusted) { - regval = read_phy_reg(pi, 0x27d); - regval &= 0xff00; - regval |= pi->nphy_crsminpwr[0]; - write_phy_reg(pi, 0x27d, regval); - - regval = read_phy_reg(pi, 0x280); - regval &= 0xff00; - regval |= pi->nphy_crsminpwr[1]; - write_phy_reg(pi, 0x280, regval); - - regval = read_phy_reg(pi, 0x283); - regval &= 0xff00; - regval |= pi->nphy_crsminpwr[2]; - write_phy_reg(pi, 0x283, regval); - - pi->nphy_crsminpwr_adjusted = false; - } - } - } -} - -static void wlc_phy_txlpfbw_nphy(phy_info_t *pi) -{ - u8 tx_lpf_bw = 0; - - if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) { - if (CHSPEC_IS40(pi->radio_chanspec)) { - tx_lpf_bw = 3; - } else { - tx_lpf_bw = 1; - } - - if (PHY_IPA(pi)) { - if (CHSPEC_IS40(pi->radio_chanspec)) { - tx_lpf_bw = 5; - } else { - tx_lpf_bw = 4; - } - } - write_phy_reg(pi, 0xe8, - (tx_lpf_bw << 0) | - (tx_lpf_bw << 3) | - (tx_lpf_bw << 6) | (tx_lpf_bw << 9)); - - if (PHY_IPA(pi)) { - - if (CHSPEC_IS40(pi->radio_chanspec)) { - tx_lpf_bw = 4; - } else { - tx_lpf_bw = 1; - } - - write_phy_reg(pi, 0xe9, - (tx_lpf_bw << 0) | - (tx_lpf_bw << 3) | - (tx_lpf_bw << 6) | (tx_lpf_bw << 9)); - } - } -} - -static void wlc_phy_spurwar_nphy(phy_info_t *pi) -{ - u16 cur_channel = 0; - int nphy_adj_tone_id_buf[] = { 57, 58 }; - u32 nphy_adj_noise_var_buf[] = { 0x3ff, 0x3ff }; - bool isAdjustNoiseVar = false; - uint numTonesAdjust = 0; - u32 tempval = 0; - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - cur_channel = CHSPEC_CHANNEL(pi->radio_chanspec); - - if (pi->nphy_gband_spurwar_en) { - - wlc_phy_adjust_rx_analpfbw_nphy(pi, - NPHY_ANARXLPFBW_REDUCTIONFACT); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if ((cur_channel == 11) - && CHSPEC_IS40(pi->radio_chanspec)) { - - wlc_phy_adjust_min_noisevar_nphy(pi, 2, - nphy_adj_tone_id_buf, - nphy_adj_noise_var_buf); - } else { - - wlc_phy_adjust_min_noisevar_nphy(pi, 0, - NULL, - NULL); - } - } - wlc_phy_adjust_crsminpwr_nphy(pi, - NPHY_ADJUSTED_MINCRSPOWER); - } - - if ((pi->nphy_gband_spurwar2_en) - && CHSPEC_IS2G(pi->radio_chanspec)) { - - if (CHSPEC_IS40(pi->radio_chanspec)) { - switch (cur_channel) { - case 3: - nphy_adj_tone_id_buf[0] = 57; - nphy_adj_tone_id_buf[1] = 58; - nphy_adj_noise_var_buf[0] = 0x22f; - nphy_adj_noise_var_buf[1] = 0x25f; - isAdjustNoiseVar = true; - break; - case 4: - nphy_adj_tone_id_buf[0] = 41; - nphy_adj_tone_id_buf[1] = 42; - nphy_adj_noise_var_buf[0] = 0x22f; - nphy_adj_noise_var_buf[1] = 0x25f; - isAdjustNoiseVar = true; - break; - case 5: - nphy_adj_tone_id_buf[0] = 25; - nphy_adj_tone_id_buf[1] = 26; - nphy_adj_noise_var_buf[0] = 0x24f; - nphy_adj_noise_var_buf[1] = 0x25f; - isAdjustNoiseVar = true; - break; - case 6: - nphy_adj_tone_id_buf[0] = 9; - nphy_adj_tone_id_buf[1] = 10; - nphy_adj_noise_var_buf[0] = 0x22f; - nphy_adj_noise_var_buf[1] = 0x24f; - isAdjustNoiseVar = true; - break; - case 7: - nphy_adj_tone_id_buf[0] = 121; - nphy_adj_tone_id_buf[1] = 122; - nphy_adj_noise_var_buf[0] = 0x18f; - nphy_adj_noise_var_buf[1] = 0x24f; - isAdjustNoiseVar = true; - break; - case 8: - nphy_adj_tone_id_buf[0] = 105; - nphy_adj_tone_id_buf[1] = 106; - nphy_adj_noise_var_buf[0] = 0x22f; - nphy_adj_noise_var_buf[1] = 0x25f; - isAdjustNoiseVar = true; - break; - case 9: - nphy_adj_tone_id_buf[0] = 89; - nphy_adj_tone_id_buf[1] = 90; - nphy_adj_noise_var_buf[0] = 0x22f; - nphy_adj_noise_var_buf[1] = 0x24f; - isAdjustNoiseVar = true; - break; - case 10: - nphy_adj_tone_id_buf[0] = 73; - nphy_adj_tone_id_buf[1] = 74; - nphy_adj_noise_var_buf[0] = 0x22f; - nphy_adj_noise_var_buf[1] = 0x24f; - isAdjustNoiseVar = true; - break; - default: - isAdjustNoiseVar = false; - break; - } - } - - if (isAdjustNoiseVar) { - numTonesAdjust = sizeof(nphy_adj_tone_id_buf) / - sizeof(nphy_adj_tone_id_buf[0]); - - wlc_phy_adjust_min_noisevar_nphy(pi, - numTonesAdjust, - nphy_adj_tone_id_buf, - nphy_adj_noise_var_buf); - - tempval = 0; - - } else { - - wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL, - NULL); - } - } - - if ((pi->nphy_aband_spurwar_en) && - (CHSPEC_IS5G(pi->radio_chanspec))) { - switch (cur_channel) { - case 54: - nphy_adj_tone_id_buf[0] = 32; - nphy_adj_noise_var_buf[0] = 0x25f; - break; - case 38: - case 102: - case 118: - if ((pi->sh->chip == BCM4716_CHIP_ID) && - (pi->sh->chippkg == BCM4717_PKG_ID)) { - nphy_adj_tone_id_buf[0] = 32; - nphy_adj_noise_var_buf[0] = 0x21f; - } else { - nphy_adj_tone_id_buf[0] = 0; - nphy_adj_noise_var_buf[0] = 0x0; - } - break; - case 134: - nphy_adj_tone_id_buf[0] = 32; - nphy_adj_noise_var_buf[0] = 0x21f; - break; - case 151: - nphy_adj_tone_id_buf[0] = 16; - nphy_adj_noise_var_buf[0] = 0x23f; - break; - case 153: - case 161: - nphy_adj_tone_id_buf[0] = 48; - nphy_adj_noise_var_buf[0] = 0x23f; - break; - default: - nphy_adj_tone_id_buf[0] = 0; - nphy_adj_noise_var_buf[0] = 0x0; - break; - } - - if (nphy_adj_tone_id_buf[0] - && nphy_adj_noise_var_buf[0]) { - wlc_phy_adjust_min_noisevar_nphy(pi, 1, - nphy_adj_tone_id_buf, - nphy_adj_noise_var_buf); - } else { - wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL, - NULL); - } - } - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); - } -} - -static void -wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chanspec, - const nphy_sfo_cfg_t *ci) -{ - u16 val; - - val = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand; - if (CHSPEC_IS5G(chanspec) && !val) { - - val = R_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param); - W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, - (val | MAC_PHY_FORCE_CLK)); - - or_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG), - (BBCFG_RESETCCA | BBCFG_RESETRX)); - - W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, val); - - or_phy_reg(pi, 0x09, NPHY_BandControl_currentBand); - } else if (!CHSPEC_IS5G(chanspec) && val) { - - and_phy_reg(pi, 0x09, ~NPHY_BandControl_currentBand); - - val = R_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param); - W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, - (val | MAC_PHY_FORCE_CLK)); - - and_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG), - (u16) (~(BBCFG_RESETCCA | BBCFG_RESETRX))); - - W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, val); - } - - write_phy_reg(pi, 0x1ce, ci->PHY_BW1a); - write_phy_reg(pi, 0x1cf, ci->PHY_BW2); - write_phy_reg(pi, 0x1d0, ci->PHY_BW3); - - write_phy_reg(pi, 0x1d1, ci->PHY_BW4); - write_phy_reg(pi, 0x1d2, ci->PHY_BW5); - write_phy_reg(pi, 0x1d3, ci->PHY_BW6); - - if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) { - wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en, 0); - - or_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, 0x800); - } else { - wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_ofdm_en, - NPHY_ClassifierCtrl_ofdm_en); - - if (CHSPEC_IS2G(chanspec)) - and_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, ~0x840); - } - - if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) { - wlc_phy_txpwr_fixpower_nphy(pi); - } - - if (NREV_LT(pi->pubpi.phy_rev, 3)) { - - wlc_phy_adjust_lnagaintbl_nphy(pi); - } - - wlc_phy_txlpfbw_nphy(pi); - - if (NREV_GE(pi->pubpi.phy_rev, 3) - && (pi->phy_spuravoid != SPURAVOID_DISABLE)) { - u8 spuravoid = 0; - - val = CHSPEC_CHANNEL(chanspec); - if (!CHSPEC_IS40(pi->radio_chanspec)) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if ((val == 13) || (val == 14) || (val == 153)) { - spuravoid = 1; - } - } else { - - if (((val >= 5) && (val <= 8)) || (val == 13) - || (val == 14)) { - spuravoid = 1; - } - } - } else { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if (val == 54) { - spuravoid = 1; - } - } else { - - if (pi->nphy_aband_spurwar_en && - ((val == 38) || (val == 102) - || (val == 118))) { - if ((pi->sh->chip == - BCM4716_CHIP_ID) - && (pi->sh->chippkg == - BCM4717_PKG_ID)) { - spuravoid = 0; - } else { - spuravoid = 1; - } - } - } - } - - if (pi->phy_spuravoid == SPURAVOID_FORCEON) - spuravoid = 1; - - if ((pi->sh->chip == BCM4716_CHIP_ID) || - (pi->sh->chip == BCM47162_CHIP_ID)) { - si_pmu_spuravoid(pi->sh->sih, pi->sh->osh, spuravoid); - } else { - wlapi_bmac_core_phypll_ctl(pi->sh->physhim, false); - si_pmu_spuravoid(pi->sh->sih, pi->sh->osh, spuravoid); - wlapi_bmac_core_phypll_ctl(pi->sh->physhim, true); - } - - if ((pi->sh->chip == BCM43224_CHIP_ID) || - (pi->sh->chip == BCM43225_CHIP_ID) || - (pi->sh->chip == BCM43421_CHIP_ID)) { - - if (spuravoid == 1) { - - W_REG(pi->sh->osh, &pi->regs->tsf_clk_frac_l, - 0x5341); - W_REG(pi->sh->osh, &pi->regs->tsf_clk_frac_h, - 0x8); - } else { - - W_REG(pi->sh->osh, &pi->regs->tsf_clk_frac_l, - 0x8889); - W_REG(pi->sh->osh, &pi->regs->tsf_clk_frac_h, - 0x8); - } - } - - if (!((pi->sh->chip == BCM4716_CHIP_ID) || - (pi->sh->chip == BCM47162_CHIP_ID))) { - wlapi_bmac_core_phypll_reset(pi->sh->physhim); - } - - mod_phy_reg(pi, 0x01, (0x1 << 15), - ((spuravoid > 0) ? (0x1 << 15) : 0)); - - wlc_phy_resetcca_nphy(pi); - - pi->phy_isspuravoid = (spuravoid > 0); - } - - if (NREV_LT(pi->pubpi.phy_rev, 7)) - write_phy_reg(pi, 0x17e, 0x3830); - - wlc_phy_spurwar_nphy(pi); -} - -void wlc_phy_chanspec_set_nphy(phy_info_t *pi, chanspec_t chanspec) -{ - int freq; - chan_info_nphy_radio2057_t *t0 = NULL; - chan_info_nphy_radio205x_t *t1 = NULL; - chan_info_nphy_radio2057_rev5_t *t2 = NULL; - chan_info_nphy_2055_t *t3 = NULL; - - if (NORADIO_ENAB(pi->pubpi)) { - return; - } - - if (!wlc_phy_chan2freq_nphy - (pi, CHSPEC_CHANNEL(chanspec), &freq, &t0, &t1, &t2, &t3)) - return; - - wlc_phy_chanspec_radio_set((wlc_phy_t *) pi, chanspec); - - if (CHSPEC_BW(chanspec) != pi->bw) - wlapi_bmac_bw_set(pi->sh->physhim, CHSPEC_BW(chanspec)); - - if (CHSPEC_IS40(chanspec)) { - if (CHSPEC_SB_UPPER(chanspec)) { - or_phy_reg(pi, 0xa0, BPHY_BAND_SEL_UP20); - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - or_phy_reg(pi, 0x310, PRIM_SEL_UP20); - } - } else { - and_phy_reg(pi, 0xa0, ~BPHY_BAND_SEL_UP20); - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - and_phy_reg(pi, 0x310, - (~PRIM_SEL_UP20 & 0xffff)); - } - } - } - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - if ((pi->pubpi.radiorev <= 4) - || (pi->pubpi.radiorev == 6)) { - mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE0, - 0x2, - (CHSPEC_IS5G(chanspec) ? (1 << 1) - : 0)); - mod_radio_reg(pi, RADIO_2057_TIA_CONFIG_CORE1, - 0x2, - (CHSPEC_IS5G(chanspec) ? (1 << 1) - : 0)); - } - - wlc_phy_chanspec_radio2057_setup(pi, t0, t2); - wlc_phy_chanspec_nphy_setup(pi, chanspec, - (pi->pubpi.radiorev == - 5) ? (const nphy_sfo_cfg_t - *)&(t2-> - PHY_BW1a) - : (const nphy_sfo_cfg_t *) - &(t0->PHY_BW1a)); - - } else { - - mod_radio_reg(pi, - RADIO_2056_SYN_COM_CTRL | RADIO_2056_SYN, - 0x4, - (CHSPEC_IS5G(chanspec) ? (0x1 << 2) : 0)); - wlc_phy_chanspec_radio2056_setup(pi, t1); - - wlc_phy_chanspec_nphy_setup(pi, chanspec, - (const nphy_sfo_cfg_t *) - &(t1->PHY_BW1a)); - } - - } else { - - mod_radio_reg(pi, RADIO_2055_MASTER_CNTRL1, 0x70, - (CHSPEC_IS5G(chanspec) ? (0x02 << 4) - : (0x05 << 4))); - - wlc_phy_chanspec_radio2055_setup(pi, t3); - wlc_phy_chanspec_nphy_setup(pi, chanspec, - (const nphy_sfo_cfg_t *)&(t3-> - PHY_BW1a)); - } - -} - -static void wlc_phy_savecal_nphy(phy_info_t *pi) -{ - void *tbl_ptr; - int coreNum; - u16 *txcal_radio_regs = NULL; - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - - wlc_phy_rx_iq_coeffs_nphy(pi, 0, - &pi->calibration_cache. - rxcal_coeffs_2G); - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - txcal_radio_regs = - pi->calibration_cache.txcal_radio_regs_2G; - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - - pi->calibration_cache.txcal_radio_regs_2G[0] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_I | - RADIO_2056_TX0); - pi->calibration_cache.txcal_radio_regs_2G[1] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_Q | - RADIO_2056_TX0); - pi->calibration_cache.txcal_radio_regs_2G[2] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_I | - RADIO_2056_TX1); - pi->calibration_cache.txcal_radio_regs_2G[3] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_Q | - RADIO_2056_TX1); - - pi->calibration_cache.txcal_radio_regs_2G[4] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_I | - RADIO_2056_TX0); - pi->calibration_cache.txcal_radio_regs_2G[5] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_Q | - RADIO_2056_TX0); - pi->calibration_cache.txcal_radio_regs_2G[6] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_I | - RADIO_2056_TX1); - pi->calibration_cache.txcal_radio_regs_2G[7] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_Q | - RADIO_2056_TX1); - } else { - pi->calibration_cache.txcal_radio_regs_2G[0] = - read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL); - pi->calibration_cache.txcal_radio_regs_2G[1] = - read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL); - pi->calibration_cache.txcal_radio_regs_2G[2] = - read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM); - pi->calibration_cache.txcal_radio_regs_2G[3] = - read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM); - } - - pi->nphy_iqcal_chanspec_2G = pi->radio_chanspec; - tbl_ptr = pi->calibration_cache.txcal_coeffs_2G; - } else { - - wlc_phy_rx_iq_coeffs_nphy(pi, 0, - &pi->calibration_cache. - rxcal_coeffs_5G); - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - txcal_radio_regs = - pi->calibration_cache.txcal_radio_regs_5G; - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - - pi->calibration_cache.txcal_radio_regs_5G[0] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_I | - RADIO_2056_TX0); - pi->calibration_cache.txcal_radio_regs_5G[1] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_Q | - RADIO_2056_TX0); - pi->calibration_cache.txcal_radio_regs_5G[2] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_I | - RADIO_2056_TX1); - pi->calibration_cache.txcal_radio_regs_5G[3] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_Q | - RADIO_2056_TX1); - - pi->calibration_cache.txcal_radio_regs_5G[4] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_I | - RADIO_2056_TX0); - pi->calibration_cache.txcal_radio_regs_5G[5] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_Q | - RADIO_2056_TX0); - pi->calibration_cache.txcal_radio_regs_5G[6] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_I | - RADIO_2056_TX1); - pi->calibration_cache.txcal_radio_regs_5G[7] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_Q | - RADIO_2056_TX1); - } else { - pi->calibration_cache.txcal_radio_regs_5G[0] = - read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL); - pi->calibration_cache.txcal_radio_regs_5G[1] = - read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL); - pi->calibration_cache.txcal_radio_regs_5G[2] = - read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM); - pi->calibration_cache.txcal_radio_regs_5G[3] = - read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM); - } - - pi->nphy_iqcal_chanspec_5G = pi->radio_chanspec; - tbl_ptr = pi->calibration_cache.txcal_coeffs_5G; - } - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - for (coreNum = 0; coreNum <= 1; coreNum++) { - - txcal_radio_regs[2 * coreNum] = - READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum, - LOFT_FINE_I); - txcal_radio_regs[2 * coreNum + 1] = - READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum, - LOFT_FINE_Q); - - txcal_radio_regs[2 * coreNum + 4] = - READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum, - LOFT_COARSE_I); - txcal_radio_regs[2 * coreNum + 5] = - READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum, - LOFT_COARSE_Q); - } - } - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 8, 80, 16, tbl_ptr); - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); -} - -static void wlc_phy_restorecal_nphy(phy_info_t *pi) -{ - u16 *loft_comp; - u16 txcal_coeffs_bphy[4]; - u16 *tbl_ptr; - int coreNum; - u16 *txcal_radio_regs = NULL; - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (pi->nphy_iqcal_chanspec_2G == 0) - return; - - tbl_ptr = pi->calibration_cache.txcal_coeffs_2G; - loft_comp = &pi->calibration_cache.txcal_coeffs_2G[5]; - } else { - if (pi->nphy_iqcal_chanspec_5G == 0) - return; - - tbl_ptr = pi->calibration_cache.txcal_coeffs_5G; - loft_comp = &pi->calibration_cache.txcal_coeffs_5G[5]; - } - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80, 16, - (void *)tbl_ptr); - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - txcal_coeffs_bphy[0] = tbl_ptr[0]; - txcal_coeffs_bphy[1] = tbl_ptr[1]; - txcal_coeffs_bphy[2] = tbl_ptr[2]; - txcal_coeffs_bphy[3] = tbl_ptr[3]; - } else { - txcal_coeffs_bphy[0] = 0; - txcal_coeffs_bphy[1] = 0; - txcal_coeffs_bphy[2] = 0; - txcal_coeffs_bphy[3] = 0; - } - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88, 16, - txcal_coeffs_bphy); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85, 16, loft_comp); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93, 16, loft_comp); - - if (NREV_LT(pi->pubpi.phy_rev, 2)) - wlc_phy_tx_iq_war_nphy(pi); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - txcal_radio_regs = - pi->calibration_cache.txcal_radio_regs_2G; - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - - write_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_I | - RADIO_2056_TX0, - pi->calibration_cache. - txcal_radio_regs_2G[0]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_Q | - RADIO_2056_TX0, - pi->calibration_cache. - txcal_radio_regs_2G[1]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_I | - RADIO_2056_TX1, - pi->calibration_cache. - txcal_radio_regs_2G[2]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_Q | - RADIO_2056_TX1, - pi->calibration_cache. - txcal_radio_regs_2G[3]); - - write_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_I | - RADIO_2056_TX0, - pi->calibration_cache. - txcal_radio_regs_2G[4]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_Q | - RADIO_2056_TX0, - pi->calibration_cache. - txcal_radio_regs_2G[5]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_I | - RADIO_2056_TX1, - pi->calibration_cache. - txcal_radio_regs_2G[6]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_Q | - RADIO_2056_TX1, - pi->calibration_cache. - txcal_radio_regs_2G[7]); - } else { - write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL, - pi->calibration_cache. - txcal_radio_regs_2G[0]); - write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL, - pi->calibration_cache. - txcal_radio_regs_2G[1]); - write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, - pi->calibration_cache. - txcal_radio_regs_2G[2]); - write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, - pi->calibration_cache. - txcal_radio_regs_2G[3]); - } - - wlc_phy_rx_iq_coeffs_nphy(pi, 1, - &pi->calibration_cache. - rxcal_coeffs_2G); - } else { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - txcal_radio_regs = - pi->calibration_cache.txcal_radio_regs_5G; - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - - write_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_I | - RADIO_2056_TX0, - pi->calibration_cache. - txcal_radio_regs_5G[0]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_Q | - RADIO_2056_TX0, - pi->calibration_cache. - txcal_radio_regs_5G[1]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_I | - RADIO_2056_TX1, - pi->calibration_cache. - txcal_radio_regs_5G[2]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_Q | - RADIO_2056_TX1, - pi->calibration_cache. - txcal_radio_regs_5G[3]); - - write_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_I | - RADIO_2056_TX0, - pi->calibration_cache. - txcal_radio_regs_5G[4]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_Q | - RADIO_2056_TX0, - pi->calibration_cache. - txcal_radio_regs_5G[5]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_I | - RADIO_2056_TX1, - pi->calibration_cache. - txcal_radio_regs_5G[6]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_Q | - RADIO_2056_TX1, - pi->calibration_cache. - txcal_radio_regs_5G[7]); - } else { - write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL, - pi->calibration_cache. - txcal_radio_regs_5G[0]); - write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL, - pi->calibration_cache. - txcal_radio_regs_5G[1]); - write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, - pi->calibration_cache. - txcal_radio_regs_5G[2]); - write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, - pi->calibration_cache. - txcal_radio_regs_5G[3]); - } - - wlc_phy_rx_iq_coeffs_nphy(pi, 1, - &pi->calibration_cache. - rxcal_coeffs_5G); - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - for (coreNum = 0; coreNum <= 1; coreNum++) { - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum, - LOFT_FINE_I, - txcal_radio_regs[2 * coreNum]); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum, - LOFT_FINE_Q, - txcal_radio_regs[2 * coreNum + 1]); - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum, - LOFT_COARSE_I, - txcal_radio_regs[2 * coreNum + 4]); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum, - LOFT_COARSE_Q, - txcal_radio_regs[2 * coreNum + 5]); - } - } -} - -void wlc_phy_antsel_init(wlc_phy_t *ppi, bool lut_init) -{ - phy_info_t *pi = (phy_info_t *) ppi; - u16 mask = 0xfc00; - u32 mc = 0; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) - return; - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - u16 v0 = 0x211, v1 = 0x222, v2 = 0x144, v3 = 0x188; - - if (lut_init == false) - return; - - if (pi->srom_fem2g.antswctrllut == 0) { - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 1, 0x02, 16, &v0); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 1, 0x03, 16, &v1); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 1, 0x08, 16, &v2); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 1, 0x0C, 16, &v3); - } else { - ASSERT(0); - } - - if (pi->srom_fem5g.antswctrllut == 0) { - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 1, 0x12, 16, &v0); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 1, 0x13, 16, &v1); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 1, 0x18, 16, &v2); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 1, 0x1C, 16, &v3); - } else { - ASSERT(0); - } - } else { - - write_phy_reg(pi, 0xc8, 0x0); - write_phy_reg(pi, 0xc9, 0x0); - - si_gpiocontrol(pi->sh->sih, mask, mask, GPIO_DRV_PRIORITY); - - mc = R_REG(pi->sh->osh, &pi->regs->maccontrol); - mc &= ~MCTL_GPOUT_SEL_MASK; - W_REG(pi->sh->osh, &pi->regs->maccontrol, mc); - - OR_REG(pi->sh->osh, &pi->regs->psm_gpio_oe, mask); - - AND_REG(pi->sh->osh, &pi->regs->psm_gpio_out, ~mask); - - if (lut_init) { - write_phy_reg(pi, 0xf8, 0x02d8); - write_phy_reg(pi, 0xf9, 0x0301); - write_phy_reg(pi, 0xfa, 0x02d8); - write_phy_reg(pi, 0xfb, 0x0301); - } - } -} - -u16 wlc_phy_classifier_nphy(phy_info_t *pi, u16 mask, u16 val) -{ - u16 curr_ctl, new_ctl; - bool suspended = false; - - if (D11REV_IS(pi->sh->corerev, 16)) { - suspended = - (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC) ? - false : true; - if (!suspended) - wlapi_suspend_mac_and_wait(pi->sh->physhim); - } - - curr_ctl = read_phy_reg(pi, 0xb0) & (0x7 << 0); - - new_ctl = (curr_ctl & (~mask)) | (val & mask); - - mod_phy_reg(pi, 0xb0, (0x7 << 0), new_ctl); - - if (D11REV_IS(pi->sh->corerev, 16) && !suspended) - wlapi_enable_mac(pi->sh->physhim); - - return new_ctl; -} - -static void wlc_phy_clip_det_nphy(phy_info_t *pi, u8 write, u16 *vals) -{ - - if (write == 0) { - vals[0] = read_phy_reg(pi, 0x2c); - vals[1] = read_phy_reg(pi, 0x42); - } else { - write_phy_reg(pi, 0x2c, vals[0]); - write_phy_reg(pi, 0x42, vals[1]); - } -} - -void wlc_phy_force_rfseq_nphy(phy_info_t *pi, u8 cmd) -{ - u16 trigger_mask, status_mask; - u16 orig_RfseqCoreActv; - - switch (cmd) { - case NPHY_RFSEQ_RX2TX: - trigger_mask = NPHY_RfseqTrigger_rx2tx; - status_mask = NPHY_RfseqStatus_rx2tx; - break; - case NPHY_RFSEQ_TX2RX: - trigger_mask = NPHY_RfseqTrigger_tx2rx; - status_mask = NPHY_RfseqStatus_tx2rx; - break; - case NPHY_RFSEQ_RESET2RX: - trigger_mask = NPHY_RfseqTrigger_reset2rx; - status_mask = NPHY_RfseqStatus_reset2rx; - break; - case NPHY_RFSEQ_UPDATEGAINH: - trigger_mask = NPHY_RfseqTrigger_updategainh; - status_mask = NPHY_RfseqStatus_updategainh; - break; - case NPHY_RFSEQ_UPDATEGAINL: - trigger_mask = NPHY_RfseqTrigger_updategainl; - status_mask = NPHY_RfseqStatus_updategainl; - break; - case NPHY_RFSEQ_UPDATEGAINU: - trigger_mask = NPHY_RfseqTrigger_updategainu; - status_mask = NPHY_RfseqStatus_updategainu; - break; - default: - return; - } - - orig_RfseqCoreActv = read_phy_reg(pi, 0xa1); - or_phy_reg(pi, 0xa1, - (NPHY_RfseqMode_CoreActv_override | - NPHY_RfseqMode_Trigger_override)); - or_phy_reg(pi, 0xa3, trigger_mask); - SPINWAIT((read_phy_reg(pi, 0xa4) & status_mask), 200000); - write_phy_reg(pi, 0xa1, orig_RfseqCoreActv); - - ASSERT((read_phy_reg(pi, 0xa4) & status_mask) == 0); -} - -static void -wlc_phy_set_rfseq_nphy(phy_info_t *pi, u8 cmd, u8 *events, u8 *dlys, - u8 len) -{ - u32 t1_offset, t2_offset; - u8 ctr; - u8 end_event = - NREV_GE(pi->pubpi.phy_rev, - 3) ? NPHY_REV3_RFSEQ_CMD_END : NPHY_RFSEQ_CMD_END; - u8 end_dly = 1; - - ASSERT(len <= 16); - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - t1_offset = cmd << 4; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t1_offset, 8, - events); - t2_offset = t1_offset + 0x080; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t2_offset, 8, - dlys); - - for (ctr = len; ctr < 16; ctr++) { - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, - t1_offset + ctr, 8, &end_event); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, - t2_offset + ctr, 8, &end_dly); - } - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); -} - -static u16 wlc_phy_read_lpf_bw_ctl_nphy(phy_info_t *pi, u16 offset) -{ - u16 lpf_bw_ctl_val = 0; - u16 rx2tx_lpf_rc_lut_offset = 0; - - if (offset == 0) { - if (CHSPEC_IS40(pi->radio_chanspec)) { - rx2tx_lpf_rc_lut_offset = 0x159; - } else { - rx2tx_lpf_rc_lut_offset = 0x154; - } - } else { - rx2tx_lpf_rc_lut_offset = offset; - } - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, - (u32) rx2tx_lpf_rc_lut_offset, 16, - &lpf_bw_ctl_val); - - lpf_bw_ctl_val = lpf_bw_ctl_val & 0x7; - - return lpf_bw_ctl_val; -} - -static void -wlc_phy_rfctrl_override_nphy_rev7(phy_info_t *pi, u16 field, u16 value, - u8 core_mask, u8 off, u8 override_id) -{ - u8 core_num; - u16 addr = 0, en_addr = 0, val_addr = 0, en_mask = 0, val_mask = 0; - u8 val_shift = 0; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - en_mask = field; - for (core_num = 0; core_num < 2; core_num++) { - if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID0) { - - switch (field) { - case (0x1 << 2): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : - 0x7d; - val_mask = (0x1 << 1); - val_shift = 1; - break; - case (0x1 << 3): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : - 0x7d; - val_mask = (0x1 << 2); - val_shift = 2; - break; - case (0x1 << 4): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : - 0x7d; - val_mask = (0x1 << 4); - val_shift = 4; - break; - case (0x1 << 5): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : - 0x7d; - val_mask = (0x1 << 5); - val_shift = 5; - break; - case (0x1 << 6): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : - 0x7d; - val_mask = (0x1 << 6); - val_shift = 6; - break; - case (0x1 << 7): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : - 0x7d; - val_mask = (0x1 << 7); - val_shift = 7; - break; - case (0x1 << 10): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0xf8 : - 0xfa; - val_mask = (0x7 << 4); - val_shift = 4; - break; - case (0x1 << 11): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7b : - 0x7e; - val_mask = (0xffff << 0); - val_shift = 0; - break; - case (0x1 << 12): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7c : - 0x7f; - val_mask = (0xffff << 0); - val_shift = 0; - break; - case (0x3 << 13): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x348 : - 0x349; - val_mask = (0xff << 0); - val_shift = 0; - break; - case (0x1 << 13): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x348 : - 0x349; - val_mask = (0xf << 0); - val_shift = 0; - break; - default: - addr = 0xffff; - break; - } - } else if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID1) { - - switch (field) { - case (0x1 << 1): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 1); - val_shift = 1; - break; - case (0x1 << 3): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 3); - val_shift = 3; - break; - case (0x1 << 5): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 5); - val_shift = 5; - break; - case (0x1 << 4): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 4); - val_shift = 4; - break; - case (0x1 << 2): - - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 2); - val_shift = 2; - break; - case (0x1 << 7): - - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x7 << 8); - val_shift = 8; - break; - case (0x1 << 11): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 14); - val_shift = 14; - break; - case (0x1 << 10): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 13); - val_shift = 13; - break; - case (0x1 << 9): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 12); - val_shift = 12; - break; - case (0x1 << 8): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 11); - val_shift = 11; - break; - case (0x1 << 6): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 6); - val_shift = 6; - break; - case (0x1 << 0): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 0); - val_shift = 0; - break; - default: - addr = 0xffff; - break; - } - } else if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID2) { - - switch (field) { - case (0x1 << 3): - en_addr = (core_num == 0) ? 0x346 : - 0x347; - val_addr = (core_num == 0) ? 0x344 : - 0x345; - val_mask = (0x1 << 3); - val_shift = 3; - break; - case (0x1 << 1): - en_addr = (core_num == 0) ? 0x346 : - 0x347; - val_addr = (core_num == 0) ? 0x344 : - 0x345; - val_mask = (0x1 << 1); - val_shift = 1; - break; - case (0x1 << 0): - en_addr = (core_num == 0) ? 0x346 : - 0x347; - val_addr = (core_num == 0) ? 0x344 : - 0x345; - val_mask = (0x1 << 0); - val_shift = 0; - break; - case (0x1 << 2): - en_addr = (core_num == 0) ? 0x346 : - 0x347; - val_addr = (core_num == 0) ? 0x344 : - 0x345; - val_mask = (0x1 << 2); - val_shift = 2; - break; - case (0x1 << 4): - en_addr = (core_num == 0) ? 0x346 : - 0x347; - val_addr = (core_num == 0) ? 0x344 : - 0x345; - val_mask = (0x1 << 4); - val_shift = 4; - break; - default: - addr = 0xffff; - break; - } - } - - if (off) { - and_phy_reg(pi, en_addr, ~en_mask); - and_phy_reg(pi, val_addr, ~val_mask); - } else { - - if ((core_mask == 0) - || (core_mask & (1 << core_num))) { - or_phy_reg(pi, en_addr, en_mask); - - if (addr != 0xffff) { - mod_phy_reg(pi, val_addr, - val_mask, - (value << - val_shift)); - } - } - } - } - } -} - -static void -wlc_phy_rfctrl_override_nphy(phy_info_t *pi, u16 field, u16 value, - u8 core_mask, u8 off) -{ - u8 core_num; - u16 addr = 0, mask = 0, en_addr = 0, val_addr = 0, en_mask = - 0, val_mask = 0; - u8 shift = 0, val_shift = 0; - - if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) { - - en_mask = field; - for (core_num = 0; core_num < 2; core_num++) { - - switch (field) { - case (0x1 << 1): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : 0x7d; - val_mask = (0x1 << 0); - val_shift = 0; - break; - case (0x1 << 2): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : 0x7d; - val_mask = (0x1 << 1); - val_shift = 1; - break; - case (0x1 << 3): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : 0x7d; - val_mask = (0x1 << 2); - val_shift = 2; - break; - case (0x1 << 4): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : 0x7d; - val_mask = (0x1 << 4); - val_shift = 4; - break; - case (0x1 << 5): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : 0x7d; - val_mask = (0x1 << 5); - val_shift = 5; - break; - case (0x1 << 6): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : 0x7d; - val_mask = (0x1 << 6); - val_shift = 6; - break; - case (0x1 << 7): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : 0x7d; - val_mask = (0x1 << 7); - val_shift = 7; - break; - case (0x1 << 8): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : 0x7d; - val_mask = (0x7 << 8); - val_shift = 8; - break; - case (0x1 << 11): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : 0x7d; - val_mask = (0x7 << 13); - val_shift = 13; - break; - - case (0x1 << 9): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0xf8 : 0xfa; - val_mask = (0x7 << 0); - val_shift = 0; - break; - - case (0x1 << 10): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0xf8 : 0xfa; - val_mask = (0x7 << 4); - val_shift = 4; - break; - - case (0x1 << 12): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7b : 0x7e; - val_mask = (0xffff << 0); - val_shift = 0; - break; - case (0x1 << 13): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7c : 0x7f; - val_mask = (0xffff << 0); - val_shift = 0; - break; - case (0x1 << 14): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0xf9 : 0xfb; - val_mask = (0x3 << 6); - val_shift = 6; - break; - case (0x1 << 0): - en_addr = (core_num == 0) ? 0xe5 : 0xe6; - val_addr = (core_num == 0) ? 0xf9 : 0xfb; - val_mask = (0x1 << 15); - val_shift = 15; - break; - default: - addr = 0xffff; - break; - } - - if (off) { - and_phy_reg(pi, en_addr, ~en_mask); - and_phy_reg(pi, val_addr, ~val_mask); - } else { - - if ((core_mask == 0) - || (core_mask & (1 << core_num))) { - or_phy_reg(pi, en_addr, en_mask); - - if (addr != 0xffff) { - mod_phy_reg(pi, val_addr, - val_mask, - (value << - val_shift)); - } - } - } - } - } else { - - if (off) { - and_phy_reg(pi, 0xec, ~field); - value = 0x0; - } else { - or_phy_reg(pi, 0xec, field); - } - - for (core_num = 0; core_num < 2; core_num++) { - - switch (field) { - case (0x1 << 1): - case (0x1 << 9): - case (0x1 << 12): - case (0x1 << 13): - case (0x1 << 14): - addr = 0x78; - - core_mask = 0x1; - break; - case (0x1 << 2): - case (0x1 << 3): - case (0x1 << 4): - case (0x1 << 5): - case (0x1 << 6): - case (0x1 << 7): - case (0x1 << 8): - addr = (core_num == 0) ? 0x7a : 0x7d; - break; - case (0x1 << 10): - addr = (core_num == 0) ? 0x7b : 0x7e; - break; - case (0x1 << 11): - addr = (core_num == 0) ? 0x7c : 0x7f; - break; - default: - addr = 0xffff; - } - - switch (field) { - case (0x1 << 1): - mask = (0x7 << 3); - shift = 3; - break; - case (0x1 << 9): - mask = (0x1 << 2); - shift = 2; - break; - case (0x1 << 12): - mask = (0x1 << 8); - shift = 8; - break; - case (0x1 << 13): - mask = (0x1 << 9); - shift = 9; - break; - case (0x1 << 14): - mask = (0xf << 12); - shift = 12; - break; - case (0x1 << 2): - mask = (0x1 << 0); - shift = 0; - break; - case (0x1 << 3): - mask = (0x1 << 1); - shift = 1; - break; - case (0x1 << 4): - mask = (0x1 << 2); - shift = 2; - break; - case (0x1 << 5): - mask = (0x3 << 4); - shift = 4; - break; - case (0x1 << 6): - mask = (0x3 << 6); - shift = 6; - break; - case (0x1 << 7): - mask = (0x1 << 8); - shift = 8; - break; - case (0x1 << 8): - mask = (0x1 << 9); - shift = 9; - break; - case (0x1 << 10): - mask = 0x1fff; - shift = 0x0; - break; - case (0x1 << 11): - mask = 0x1fff; - shift = 0x0; - break; - default: - mask = 0x0; - shift = 0x0; - break; - } - - if ((addr != 0xffff) && (core_mask & (1 << core_num))) { - mod_phy_reg(pi, addr, mask, (value << shift)); - } - } - - or_phy_reg(pi, 0xec, (0x1 << 0)); - or_phy_reg(pi, 0x78, (0x1 << 0)); - udelay(1); - and_phy_reg(pi, 0xec, ~(0x1 << 0)); - } -} - -static void -wlc_phy_rfctrl_override_1tomany_nphy(phy_info_t *pi, u16 cmd, u16 value, - u8 core_mask, u8 off) -{ - u16 rfmxgain = 0, lpfgain = 0; - u16 tgain = 0; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - switch (cmd) { - case NPHY_REV7_RfctrlOverride_cmd_rxrf_pu: - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), - value, core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), value, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), value, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - break; - case NPHY_REV7_RfctrlOverride_cmd_rx_pu: - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), - value, core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), value, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID2); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - break; - case NPHY_REV7_RfctrlOverride_cmd_tx_pu: - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), - value, core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), value, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID2); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), value, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID2); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 1, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - break; - case NPHY_REV7_RfctrlOverride_cmd_rxgain: - rfmxgain = value & 0x000ff; - lpfgain = value & 0x0ff00; - lpfgain = lpfgain >> 8; - - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), - rfmxgain, core_mask, - off, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x3 << 13), - lpfgain, core_mask, - off, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - break; - case NPHY_REV7_RfctrlOverride_cmd_txgain: - tgain = value & 0x7fff; - lpfgain = value & 0x8000; - lpfgain = lpfgain >> 14; - - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), - tgain, core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 13), - lpfgain, core_mask, - off, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - break; - } - } -} - -static void -wlc_phy_scale_offset_rssi_nphy(phy_info_t *pi, u16 scale, s8 offset, - u8 coresel, u8 rail, u8 rssi_type) -{ - u16 valuetostuff; - - offset = (offset > NPHY_RSSICAL_MAXREAD) ? - NPHY_RSSICAL_MAXREAD : offset; - offset = (offset < (-NPHY_RSSICAL_MAXREAD - 1)) ? - -NPHY_RSSICAL_MAXREAD - 1 : offset; - - valuetostuff = ((scale & 0x3f) << 8) | (offset & 0x3f); - - if (((coresel == RADIO_MIMO_CORESEL_CORE1) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB)) { - write_phy_reg(pi, 0x1a6, valuetostuff); - } - if (((coresel == RADIO_MIMO_CORESEL_CORE1) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB)) { - write_phy_reg(pi, 0x1ac, valuetostuff); - } - if (((coresel == RADIO_MIMO_CORESEL_CORE2) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB)) { - write_phy_reg(pi, 0x1b2, valuetostuff); - } - if (((coresel == RADIO_MIMO_CORESEL_CORE2) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB)) { - write_phy_reg(pi, 0x1b8, valuetostuff); - } - - if (((coresel == RADIO_MIMO_CORESEL_CORE1) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1)) { - write_phy_reg(pi, 0x1a4, valuetostuff); - } - if (((coresel == RADIO_MIMO_CORESEL_CORE1) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1)) { - write_phy_reg(pi, 0x1aa, valuetostuff); - } - if (((coresel == RADIO_MIMO_CORESEL_CORE2) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1)) { - write_phy_reg(pi, 0x1b0, valuetostuff); - } - if (((coresel == RADIO_MIMO_CORESEL_CORE2) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1)) { - write_phy_reg(pi, 0x1b6, valuetostuff); - } - - if (((coresel == RADIO_MIMO_CORESEL_CORE1) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2)) { - write_phy_reg(pi, 0x1a5, valuetostuff); - } - if (((coresel == RADIO_MIMO_CORESEL_CORE1) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2)) { - write_phy_reg(pi, 0x1ab, valuetostuff); - } - if (((coresel == RADIO_MIMO_CORESEL_CORE2) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2)) { - write_phy_reg(pi, 0x1b1, valuetostuff); - } - if (((coresel == RADIO_MIMO_CORESEL_CORE2) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2)) { - write_phy_reg(pi, 0x1b7, valuetostuff); - } - - if (((coresel == RADIO_MIMO_CORESEL_CORE1) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD)) { - write_phy_reg(pi, 0x1a7, valuetostuff); - } - if (((coresel == RADIO_MIMO_CORESEL_CORE1) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD)) { - write_phy_reg(pi, 0x1ad, valuetostuff); - } - if (((coresel == RADIO_MIMO_CORESEL_CORE2) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD)) { - write_phy_reg(pi, 0x1b3, valuetostuff); - } - if (((coresel == RADIO_MIMO_CORESEL_CORE2) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD)) { - write_phy_reg(pi, 0x1b9, valuetostuff); - } - - if (((coresel == RADIO_MIMO_CORESEL_CORE1) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ)) { - write_phy_reg(pi, 0x1a8, valuetostuff); - } - if (((coresel == RADIO_MIMO_CORESEL_CORE1) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ)) { - write_phy_reg(pi, 0x1ae, valuetostuff); - } - if (((coresel == RADIO_MIMO_CORESEL_CORE2) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ)) { - write_phy_reg(pi, 0x1b4, valuetostuff); - } - if (((coresel == RADIO_MIMO_CORESEL_CORE2) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ)) { - write_phy_reg(pi, 0x1ba, valuetostuff); - } - - if (((coresel == RADIO_MIMO_CORESEL_CORE1) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rssi_type == NPHY_RSSI_SEL_TSSI_2G)) { - write_phy_reg(pi, 0x1a9, valuetostuff); - } - if (((coresel == RADIO_MIMO_CORESEL_CORE2) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rssi_type == NPHY_RSSI_SEL_TSSI_2G)) { - write_phy_reg(pi, 0x1b5, valuetostuff); - } - - if (((coresel == RADIO_MIMO_CORESEL_CORE1) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rssi_type == NPHY_RSSI_SEL_TSSI_5G)) { - write_phy_reg(pi, 0x1af, valuetostuff); - } - if (((coresel == RADIO_MIMO_CORESEL_CORE2) || - (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rssi_type == NPHY_RSSI_SEL_TSSI_5G)) { - write_phy_reg(pi, 0x1bb, valuetostuff); - } -} - -void wlc_phy_rssisel_nphy(phy_info_t *pi, u8 core_code, u8 rssi_type) -{ - u16 mask, val; - u16 afectrlovr_rssi_val, rfctrlcmd_rxen_val, rfctrlcmd_coresel_val, - startseq; - u16 rfctrlovr_rssi_val, rfctrlovr_rxen_val, rfctrlovr_coresel_val, - rfctrlovr_trigger_val; - u16 afectrlovr_rssi_mask, rfctrlcmd_mask, rfctrlovr_mask; - u16 rfctrlcmd_val, rfctrlovr_val; - u8 core; - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if (core_code == RADIO_MIMO_CORESEL_OFF) { - mod_phy_reg(pi, 0x8f, (0x1 << 9), 0); - mod_phy_reg(pi, 0xa5, (0x1 << 9), 0); - - mod_phy_reg(pi, 0xa6, (0x3 << 8), 0); - mod_phy_reg(pi, 0xa7, (0x3 << 8), 0); - - mod_phy_reg(pi, 0xe5, (0x1 << 5), 0); - mod_phy_reg(pi, 0xe6, (0x1 << 5), 0); - - mask = (0x1 << 2) | - (0x1 << 3) | (0x1 << 4) | (0x1 << 5); - mod_phy_reg(pi, 0xf9, mask, 0); - mod_phy_reg(pi, 0xfb, mask, 0); - - } else { - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - if (core_code == RADIO_MIMO_CORESEL_CORE1 - && core == PHY_CORE_1) - continue; - else if (core_code == RADIO_MIMO_CORESEL_CORE2 - && core == PHY_CORE_0) - continue; - - mod_phy_reg(pi, (core == PHY_CORE_0) ? - 0x8f : 0xa5, (0x1 << 9), 1 << 9); - - if (rssi_type == NPHY_RSSI_SEL_W1 || - rssi_type == NPHY_RSSI_SEL_W2 || - rssi_type == NPHY_RSSI_SEL_NB) { - - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0xa6 : 0xa7, - (0x3 << 8), 0); - - mask = (0x1 << 2) | - (0x1 << 3) | - (0x1 << 4) | (0x1 << 5); - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0xf9 : 0xfb, - mask, 0); - - if (rssi_type == NPHY_RSSI_SEL_W1) { - if (CHSPEC_IS5G - (pi->radio_chanspec)) { - mask = (0x1 << 2); - val = 1 << 2; - } else { - mask = (0x1 << 3); - val = 1 << 3; - } - } else if (rssi_type == - NPHY_RSSI_SEL_W2) { - mask = (0x1 << 4); - val = 1 << 4; - } else { - mask = (0x1 << 5); - val = 1 << 5; - } - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0xf9 : 0xfb, - mask, val); - - mask = (0x1 << 5); - val = 1 << 5; - mod_phy_reg(pi, (core == PHY_CORE_0) ? - 0xe5 : 0xe6, mask, val); - } else { - if (rssi_type == NPHY_RSSI_SEL_TBD) { - - mask = (0x3 << 8); - val = 1 << 8; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0xa6 - : 0xa7, mask, val); - mask = (0x3 << 10); - val = 1 << 10; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0xa6 - : 0xa7, mask, val); - } else if (rssi_type == - NPHY_RSSI_SEL_IQ) { - - mask = (0x3 << 8); - val = 2 << 8; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0xa6 - : 0xa7, mask, val); - mask = (0x3 << 10); - val = 2 << 10; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0xa6 - : 0xa7, mask, val); - } else { - - mask = (0x3 << 8); - val = 3 << 8; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0xa6 - : 0xa7, mask, val); - mask = (0x3 << 10); - val = 3 << 10; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0xa6 - : 0xa7, mask, val); - - if (PHY_IPA(pi)) { - if (NREV_GE - (pi->pubpi.phy_rev, - 7)) { - - write_radio_reg - (pi, - ((core == - PHY_CORE_0) - ? - RADIO_2057_TX0_TX_SSI_MUX - : - RADIO_2057_TX1_TX_SSI_MUX), - (CHSPEC_IS5G - (pi-> - radio_chanspec) - ? 0xc : - 0xe)); - } else { - write_radio_reg - (pi, - RADIO_2056_TX_TX_SSI_MUX - | - ((core == - PHY_CORE_0) - ? - RADIO_2056_TX0 - : - RADIO_2056_TX1), - (CHSPEC_IS5G - (pi-> - radio_chanspec) - ? 0xc : - 0xe)); - } - } else { - - if (NREV_GE - (pi->pubpi.phy_rev, - 7)) { - write_radio_reg - (pi, - ((core == - PHY_CORE_0) - ? - RADIO_2057_TX0_TX_SSI_MUX - : - RADIO_2057_TX1_TX_SSI_MUX), - 0x11); - - if (pi->pubpi. - radioid == - BCM2057_ID) - write_radio_reg - (pi, - RADIO_2057_IQTEST_SEL_PU, - 0x1); - - } else { - write_radio_reg - (pi, - RADIO_2056_TX_TX_SSI_MUX - | - ((core == - PHY_CORE_0) - ? - RADIO_2056_TX0 - : - RADIO_2056_TX1), - 0x11); - } - } - - afectrlovr_rssi_val = 1 << 9; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x8f - : 0xa5, (0x1 << 9), - afectrlovr_rssi_val); - } - } - } - } - } else { - - if ((rssi_type == NPHY_RSSI_SEL_W1) || - (rssi_type == NPHY_RSSI_SEL_W2) || - (rssi_type == NPHY_RSSI_SEL_NB)) { - - val = 0x0; - } else if (rssi_type == NPHY_RSSI_SEL_TBD) { - - val = 0x1; - } else if (rssi_type == NPHY_RSSI_SEL_IQ) { - - val = 0x2; - } else { - - val = 0x3; - } - mask = ((0x3 << 12) | (0x3 << 14)); - val = (val << 12) | (val << 14); - mod_phy_reg(pi, 0xa6, mask, val); - mod_phy_reg(pi, 0xa7, mask, val); - - if ((rssi_type == NPHY_RSSI_SEL_W1) || - (rssi_type == NPHY_RSSI_SEL_W2) || - (rssi_type == NPHY_RSSI_SEL_NB)) { - if (rssi_type == NPHY_RSSI_SEL_W1) { - val = 0x1; - } - if (rssi_type == NPHY_RSSI_SEL_W2) { - val = 0x2; - } - if (rssi_type == NPHY_RSSI_SEL_NB) { - val = 0x3; - } - mask = (0x3 << 4); - val = (val << 4); - mod_phy_reg(pi, 0x7a, mask, val); - mod_phy_reg(pi, 0x7d, mask, val); - } - - if (core_code == RADIO_MIMO_CORESEL_OFF) { - afectrlovr_rssi_val = 0; - rfctrlcmd_rxen_val = 0; - rfctrlcmd_coresel_val = 0; - rfctrlovr_rssi_val = 0; - rfctrlovr_rxen_val = 0; - rfctrlovr_coresel_val = 0; - rfctrlovr_trigger_val = 0; - startseq = 0; - } else { - afectrlovr_rssi_val = 1; - rfctrlcmd_rxen_val = 1; - rfctrlcmd_coresel_val = core_code; - rfctrlovr_rssi_val = 1; - rfctrlovr_rxen_val = 1; - rfctrlovr_coresel_val = 1; - rfctrlovr_trigger_val = 1; - startseq = 1; - } - - afectrlovr_rssi_mask = ((0x1 << 12) | (0x1 << 13)); - afectrlovr_rssi_val = (afectrlovr_rssi_val << - 12) | (afectrlovr_rssi_val << 13); - mod_phy_reg(pi, 0xa5, afectrlovr_rssi_mask, - afectrlovr_rssi_val); - - if ((rssi_type == NPHY_RSSI_SEL_W1) || - (rssi_type == NPHY_RSSI_SEL_W2) || - (rssi_type == NPHY_RSSI_SEL_NB)) { - rfctrlcmd_mask = ((0x1 << 8) | (0x7 << 3)); - rfctrlcmd_val = (rfctrlcmd_rxen_val << 8) | - (rfctrlcmd_coresel_val << 3); - - rfctrlovr_mask = ((0x1 << 5) | - (0x1 << 12) | - (0x1 << 1) | (0x1 << 0)); - rfctrlovr_val = (rfctrlovr_rssi_val << - 5) | - (rfctrlovr_rxen_val << 12) | - (rfctrlovr_coresel_val << 1) | - (rfctrlovr_trigger_val << 0); - - mod_phy_reg(pi, 0x78, rfctrlcmd_mask, rfctrlcmd_val); - mod_phy_reg(pi, 0xec, rfctrlovr_mask, rfctrlovr_val); - - mod_phy_reg(pi, 0x78, (0x1 << 0), (startseq << 0)); - udelay(20); - - mod_phy_reg(pi, 0xec, (0x1 << 0), 0); - } - } -} - -int -wlc_phy_poll_rssi_nphy(phy_info_t *pi, u8 rssi_type, s32 *rssi_buf, - u8 nsamps) -{ - s16 rssi0, rssi1; - u16 afectrlCore1_save = 0; - u16 afectrlCore2_save = 0; - u16 afectrlOverride1_save = 0; - u16 afectrlOverride2_save = 0; - u16 rfctrlOverrideAux0_save = 0; - u16 rfctrlOverrideAux1_save = 0; - u16 rfctrlMiscReg1_save = 0; - u16 rfctrlMiscReg2_save = 0; - u16 rfctrlcmd_save = 0; - u16 rfctrloverride_save = 0; - u16 rfctrlrssiothers1_save = 0; - u16 rfctrlrssiothers2_save = 0; - s8 tmp_buf[4]; - u8 ctr = 0, samp = 0; - s32 rssi_out_val; - u16 gpiosel_orig; - - afectrlCore1_save = read_phy_reg(pi, 0xa6); - afectrlCore2_save = read_phy_reg(pi, 0xa7); - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - rfctrlMiscReg1_save = read_phy_reg(pi, 0xf9); - rfctrlMiscReg2_save = read_phy_reg(pi, 0xfb); - afectrlOverride1_save = read_phy_reg(pi, 0x8f); - afectrlOverride2_save = read_phy_reg(pi, 0xa5); - rfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5); - rfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6); - } else { - afectrlOverride1_save = read_phy_reg(pi, 0xa5); - rfctrlcmd_save = read_phy_reg(pi, 0x78); - rfctrloverride_save = read_phy_reg(pi, 0xec); - rfctrlrssiothers1_save = read_phy_reg(pi, 0x7a); - rfctrlrssiothers2_save = read_phy_reg(pi, 0x7d); - } - - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type); - - gpiosel_orig = read_phy_reg(pi, 0xca); - if (NREV_LT(pi->pubpi.phy_rev, 2)) { - write_phy_reg(pi, 0xca, 5); - } - - for (ctr = 0; ctr < 4; ctr++) { - rssi_buf[ctr] = 0; - } - - for (samp = 0; samp < nsamps; samp++) { - if (NREV_LT(pi->pubpi.phy_rev, 2)) { - rssi0 = read_phy_reg(pi, 0x1c9); - rssi1 = read_phy_reg(pi, 0x1ca); - } else { - rssi0 = read_phy_reg(pi, 0x219); - rssi1 = read_phy_reg(pi, 0x21a); - } - - ctr = 0; - tmp_buf[ctr++] = ((s8) ((rssi0 & 0x3f) << 2)) >> 2; - tmp_buf[ctr++] = ((s8) (((rssi0 >> 8) & 0x3f) << 2)) >> 2; - tmp_buf[ctr++] = ((s8) ((rssi1 & 0x3f) << 2)) >> 2; - tmp_buf[ctr++] = ((s8) (((rssi1 >> 8) & 0x3f) << 2)) >> 2; - - for (ctr = 0; ctr < 4; ctr++) { - rssi_buf[ctr] += tmp_buf[ctr]; - } - - } - - rssi_out_val = rssi_buf[3] & 0xff; - rssi_out_val |= (rssi_buf[2] & 0xff) << 8; - rssi_out_val |= (rssi_buf[1] & 0xff) << 16; - rssi_out_val |= (rssi_buf[0] & 0xff) << 24; - - if (NREV_LT(pi->pubpi.phy_rev, 2)) { - write_phy_reg(pi, 0xca, gpiosel_orig); - } - - write_phy_reg(pi, 0xa6, afectrlCore1_save); - write_phy_reg(pi, 0xa7, afectrlCore2_save); - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - write_phy_reg(pi, 0xf9, rfctrlMiscReg1_save); - write_phy_reg(pi, 0xfb, rfctrlMiscReg2_save); - write_phy_reg(pi, 0x8f, afectrlOverride1_save); - write_phy_reg(pi, 0xa5, afectrlOverride2_save); - write_phy_reg(pi, 0xe5, rfctrlOverrideAux0_save); - write_phy_reg(pi, 0xe6, rfctrlOverrideAux1_save); - } else { - write_phy_reg(pi, 0xa5, afectrlOverride1_save); - write_phy_reg(pi, 0x78, rfctrlcmd_save); - write_phy_reg(pi, 0xec, rfctrloverride_save); - write_phy_reg(pi, 0x7a, rfctrlrssiothers1_save); - write_phy_reg(pi, 0x7d, rfctrlrssiothers2_save); - } - - return rssi_out_val; -} - -s16 wlc_phy_tempsense_nphy(phy_info_t *pi) -{ - u16 core1_txrf_iqcal1_save, core1_txrf_iqcal2_save; - u16 core2_txrf_iqcal1_save, core2_txrf_iqcal2_save; - u16 pwrdet_rxtx_core1_save; - u16 pwrdet_rxtx_core2_save; - u16 afectrlCore1_save; - u16 afectrlCore2_save; - u16 afectrlOverride_save; - u16 afectrlOverride2_save; - u16 pd_pll_ts_save; - u16 gpioSel_save; - s32 radio_temp[4]; - s32 radio_temp2[4]; - u16 syn_tempprocsense_save; - s16 offset = 0; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - u16 auxADC_Vmid, auxADC_Av, auxADC_Vmid_save, auxADC_Av_save; - u16 auxADC_rssi_ctrlL_save, auxADC_rssi_ctrlH_save; - u16 auxADC_rssi_ctrlL, auxADC_rssi_ctrlH; - s32 auxADC_Vl; - u16 RfctrlOverride5_save, RfctrlOverride6_save; - u16 RfctrlMiscReg5_save, RfctrlMiscReg6_save; - u16 RSSIMultCoef0QPowerDet_save; - u16 tempsense_Rcal; - - syn_tempprocsense_save = - read_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG); - - afectrlCore1_save = read_phy_reg(pi, 0xa6); - afectrlCore2_save = read_phy_reg(pi, 0xa7); - afectrlOverride_save = read_phy_reg(pi, 0x8f); - afectrlOverride2_save = read_phy_reg(pi, 0xa5); - RSSIMultCoef0QPowerDet_save = read_phy_reg(pi, 0x1ae); - RfctrlOverride5_save = read_phy_reg(pi, 0x346); - RfctrlOverride6_save = read_phy_reg(pi, 0x347); - RfctrlMiscReg5_save = read_phy_reg(pi, 0x344); - RfctrlMiscReg6_save = read_phy_reg(pi, 0x345); - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16, - &auxADC_Vmid_save); - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16, - &auxADC_Av_save); - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16, - &auxADC_rssi_ctrlL_save); - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16, - &auxADC_rssi_ctrlH_save); - - write_phy_reg(pi, 0x1ae, 0x0); - - auxADC_rssi_ctrlL = 0x0; - auxADC_rssi_ctrlH = 0x20; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16, - &auxADC_rssi_ctrlL); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16, - &auxADC_rssi_ctrlH); - - tempsense_Rcal = syn_tempprocsense_save & 0x1c; - - write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, - tempsense_Rcal | 0x01); - - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), - 1, 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID2); - mod_phy_reg(pi, 0xa6, (0x1 << 7), 0); - mod_phy_reg(pi, 0xa7, (0x1 << 7), 0); - mod_phy_reg(pi, 0x8f, (0x1 << 7), (0x1 << 7)); - mod_phy_reg(pi, 0xa5, (0x1 << 7), (0x1 << 7)); - - mod_phy_reg(pi, 0xa6, (0x1 << 2), (0x1 << 2)); - mod_phy_reg(pi, 0xa7, (0x1 << 2), (0x1 << 2)); - mod_phy_reg(pi, 0x8f, (0x1 << 2), (0x1 << 2)); - mod_phy_reg(pi, 0xa5, (0x1 << 2), (0x1 << 2)); - udelay(5); - mod_phy_reg(pi, 0xa6, (0x1 << 2), 0); - mod_phy_reg(pi, 0xa7, (0x1 << 2), 0); - mod_phy_reg(pi, 0xa6, (0x1 << 3), 0); - mod_phy_reg(pi, 0xa7, (0x1 << 3), 0); - mod_phy_reg(pi, 0x8f, (0x1 << 3), (0x1 << 3)); - mod_phy_reg(pi, 0xa5, (0x1 << 3), (0x1 << 3)); - mod_phy_reg(pi, 0xa6, (0x1 << 6), 0); - mod_phy_reg(pi, 0xa7, (0x1 << 6), 0); - mod_phy_reg(pi, 0x8f, (0x1 << 6), (0x1 << 6)); - mod_phy_reg(pi, 0xa5, (0x1 << 6), (0x1 << 6)); - - auxADC_Vmid = 0xA3; - auxADC_Av = 0x0; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16, - &auxADC_Vmid); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16, - &auxADC_Av); - - udelay(3); - - wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1); - write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, - tempsense_Rcal | 0x03); - - udelay(5); - wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1); - - auxADC_Av = 0x7; - if (radio_temp[1] + radio_temp2[1] < -30) { - auxADC_Vmid = 0x45; - auxADC_Vl = 263; - } else if (radio_temp[1] + radio_temp2[1] < -9) { - auxADC_Vmid = 0x200; - auxADC_Vl = 467; - } else if (radio_temp[1] + radio_temp2[1] < 11) { - auxADC_Vmid = 0x266; - auxADC_Vl = 634; - } else { - auxADC_Vmid = 0x2D5; - auxADC_Vl = 816; - } - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16, - &auxADC_Vmid); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16, - &auxADC_Av); - - udelay(3); - - wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1); - write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, - tempsense_Rcal | 0x01); - - udelay(5); - wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1); - - write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, - syn_tempprocsense_save); - - write_phy_reg(pi, 0xa6, afectrlCore1_save); - write_phy_reg(pi, 0xa7, afectrlCore2_save); - write_phy_reg(pi, 0x8f, afectrlOverride_save); - write_phy_reg(pi, 0xa5, afectrlOverride2_save); - write_phy_reg(pi, 0x1ae, RSSIMultCoef0QPowerDet_save); - write_phy_reg(pi, 0x346, RfctrlOverride5_save); - write_phy_reg(pi, 0x347, RfctrlOverride6_save); - write_phy_reg(pi, 0x344, RfctrlMiscReg5_save); - write_phy_reg(pi, 0x345, RfctrlMiscReg5_save); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0A, 16, - &auxADC_Vmid_save); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x0E, 16, - &auxADC_Av_save); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x02, 16, - &auxADC_rssi_ctrlL_save); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16, - &auxADC_rssi_ctrlH_save); - - if (pi->sh->chip == BCM5357_CHIP_ID) { - radio_temp[0] = (193 * (radio_temp[1] + radio_temp2[1]) - + 88 * (auxADC_Vl) - 27111 + - 128) / 256; - } else if (pi->sh->chip == BCM43236_CHIP_ID) { - radio_temp[0] = (198 * (radio_temp[1] + radio_temp2[1]) - + 91 * (auxADC_Vl) - 27243 + - 128) / 256; - } else { - radio_temp[0] = (179 * (radio_temp[1] + radio_temp2[1]) - + 82 * (auxADC_Vl) - 28861 + - 128) / 256; - } - - offset = (s16) pi->phy_tempsense_offset; - - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - syn_tempprocsense_save = - read_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE); - - afectrlCore1_save = read_phy_reg(pi, 0xa6); - afectrlCore2_save = read_phy_reg(pi, 0xa7); - afectrlOverride_save = read_phy_reg(pi, 0x8f); - afectrlOverride2_save = read_phy_reg(pi, 0xa5); - gpioSel_save = read_phy_reg(pi, 0xca); - - write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01); - - wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1); - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - } else { - write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x05); - } - - wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1); - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x01); - } else { - write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01); - } - - radio_temp[0] = - (126 * (radio_temp[1] + radio_temp2[1]) + 3987) / 64; - - write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, - syn_tempprocsense_save); - - write_phy_reg(pi, 0xca, gpioSel_save); - write_phy_reg(pi, 0xa6, afectrlCore1_save); - write_phy_reg(pi, 0xa7, afectrlCore2_save); - write_phy_reg(pi, 0x8f, afectrlOverride_save); - write_phy_reg(pi, 0xa5, afectrlOverride2_save); - - offset = (s16) pi->phy_tempsense_offset; - } else { - - pwrdet_rxtx_core1_save = - read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1); - pwrdet_rxtx_core2_save = - read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2); - core1_txrf_iqcal1_save = - read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1); - core1_txrf_iqcal2_save = - read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2); - core2_txrf_iqcal1_save = - read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1); - core2_txrf_iqcal2_save = - read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2); - pd_pll_ts_save = read_radio_reg(pi, RADIO_2055_PD_PLL_TS); - - afectrlCore1_save = read_phy_reg(pi, 0xa6); - afectrlCore2_save = read_phy_reg(pi, 0xa7); - afectrlOverride_save = read_phy_reg(pi, 0xa5); - gpioSel_save = read_phy_reg(pi, 0xca); - - write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x01); - write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x01); - write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x08); - write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x08); - write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04); - write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04); - write_radio_reg(pi, RADIO_2055_PD_PLL_TS, 0x00); - - wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1); - xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80); - - wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1); - xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80); - - wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1); - xor_radio_reg(pi, RADIO_2055_CAL_TS, 0x80); - - radio_temp[0] = (radio_temp[0] + radio_temp2[0]); - radio_temp[1] = (radio_temp[1] + radio_temp2[1]); - radio_temp[2] = (radio_temp[2] + radio_temp2[2]); - radio_temp[3] = (radio_temp[3] + radio_temp2[3]); - - radio_temp[0] = - (radio_temp[0] + radio_temp[1] + radio_temp[2] + - radio_temp[3]); - - radio_temp[0] = - (radio_temp[0] + (8 * 32)) * (950 - 350) / 63 + (350 * 8); - - radio_temp[0] = (radio_temp[0] - (8 * 420)) / 38; - - write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, - pwrdet_rxtx_core1_save); - write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, - pwrdet_rxtx_core2_save); - write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, - core1_txrf_iqcal1_save); - write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, - core2_txrf_iqcal1_save); - write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, - core1_txrf_iqcal2_save); - write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, - core2_txrf_iqcal2_save); - write_radio_reg(pi, RADIO_2055_PD_PLL_TS, pd_pll_ts_save); - - write_phy_reg(pi, 0xca, gpioSel_save); - write_phy_reg(pi, 0xa6, afectrlCore1_save); - write_phy_reg(pi, 0xa7, afectrlCore2_save); - write_phy_reg(pi, 0xa5, afectrlOverride_save); - } - - return (s16) radio_temp[0] + offset; -} - -static void -wlc_phy_set_rssi_2055_vcm(phy_info_t *pi, u8 rssi_type, u8 *vcm_buf) -{ - u8 core; - - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - if (rssi_type == NPHY_RSSI_SEL_NB) { - if (core == PHY_CORE_0) { - mod_radio_reg(pi, - RADIO_2055_CORE1_B0_NBRSSI_VCM, - RADIO_2055_NBRSSI_VCM_I_MASK, - vcm_buf[2 * - core] << - RADIO_2055_NBRSSI_VCM_I_SHIFT); - mod_radio_reg(pi, - RADIO_2055_CORE1_RXBB_RSSI_CTRL5, - RADIO_2055_NBRSSI_VCM_Q_MASK, - vcm_buf[2 * core + - 1] << - RADIO_2055_NBRSSI_VCM_Q_SHIFT); - } else { - mod_radio_reg(pi, - RADIO_2055_CORE2_B0_NBRSSI_VCM, - RADIO_2055_NBRSSI_VCM_I_MASK, - vcm_buf[2 * - core] << - RADIO_2055_NBRSSI_VCM_I_SHIFT); - mod_radio_reg(pi, - RADIO_2055_CORE2_RXBB_RSSI_CTRL5, - RADIO_2055_NBRSSI_VCM_Q_MASK, - vcm_buf[2 * core + - 1] << - RADIO_2055_NBRSSI_VCM_Q_SHIFT); - } - } else { - - if (core == PHY_CORE_0) { - mod_radio_reg(pi, - RADIO_2055_CORE1_RXBB_RSSI_CTRL5, - RADIO_2055_WBRSSI_VCM_IQ_MASK, - vcm_buf[2 * - core] << - RADIO_2055_WBRSSI_VCM_IQ_SHIFT); - } else { - mod_radio_reg(pi, - RADIO_2055_CORE2_RXBB_RSSI_CTRL5, - RADIO_2055_WBRSSI_VCM_IQ_MASK, - vcm_buf[2 * - core] << - RADIO_2055_WBRSSI_VCM_IQ_SHIFT); - } - } - } -} - -void wlc_phy_rssi_cal_nphy(phy_info_t *pi) -{ - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - - wlc_phy_rssi_cal_nphy_rev3(pi); - } else { - wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_NB); - wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W1); - wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W2); - } -} - -static void wlc_phy_rssi_cal_nphy_rev2(phy_info_t *pi, u8 rssi_type) -{ - s32 target_code; - u16 classif_state; - u16 clip_state[2]; - u16 rssi_ctrl_state[2], pd_state[2]; - u16 rfctrlintc_state[2], rfpdcorerxtx_state[2]; - u16 rfctrlintc_override_val; - u16 clip_off[] = { 0xffff, 0xffff }; - u16 rf_pd_val, pd_mask, rssi_ctrl_mask; - u8 vcm, min_vcm, vcm_tmp[4]; - u8 vcm_final[4] = { 0, 0, 0, 0 }; - u8 result_idx, ctr; - s32 poll_results[4][4] = { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0} - }; - s32 poll_miniq[4][2] = { - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0} - }; - s32 min_d, curr_d; - s32 fine_digital_offset[4]; - s32 poll_results_min[4] = { 0, 0, 0, 0 }; - s32 min_poll; - - switch (rssi_type) { - case NPHY_RSSI_SEL_NB: - target_code = NPHY_RSSICAL_NB_TARGET; - break; - case NPHY_RSSI_SEL_W1: - target_code = NPHY_RSSICAL_W1_TARGET; - break; - case NPHY_RSSI_SEL_W2: - target_code = NPHY_RSSICAL_W2_TARGET; - break; - default: - return; - break; - } - - classif_state = wlc_phy_classifier_nphy(pi, 0, 0); - wlc_phy_classifier_nphy(pi, (0x7 << 0), 4); - wlc_phy_clip_det_nphy(pi, 0, clip_state); - wlc_phy_clip_det_nphy(pi, 1, clip_off); - - rf_pd_val = (rssi_type == NPHY_RSSI_SEL_NB) ? 0x6 : 0x4; - rfctrlintc_override_val = - CHSPEC_IS5G(pi->radio_chanspec) ? 0x140 : 0x110; - - rfctrlintc_state[0] = read_phy_reg(pi, 0x91); - rfpdcorerxtx_state[0] = read_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX); - write_phy_reg(pi, 0x91, rfctrlintc_override_val); - write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rf_pd_val); - - rfctrlintc_state[1] = read_phy_reg(pi, 0x92); - rfpdcorerxtx_state[1] = read_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX); - write_phy_reg(pi, 0x92, rfctrlintc_override_val); - write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rf_pd_val); - - pd_mask = RADIO_2055_NBRSSI_PD | RADIO_2055_WBRSSI_G1_PD | - RADIO_2055_WBRSSI_G2_PD; - pd_state[0] = - read_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC) & pd_mask; - pd_state[1] = - read_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC) & pd_mask; - mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, 0); - mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, 0); - rssi_ctrl_mask = RADIO_2055_NBRSSI_SEL | RADIO_2055_WBRSSI_G1_SEL | - RADIO_2055_WBRSSI_G2_SEL; - rssi_ctrl_state[0] = - read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE1) & rssi_ctrl_mask; - rssi_ctrl_state[1] = - read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE2) & rssi_ctrl_mask; - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type); - - wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX, - NPHY_RAIL_I, rssi_type); - wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX, - NPHY_RAIL_Q, rssi_type); - - for (vcm = 0; vcm < 4; vcm++) { - - vcm_tmp[0] = vcm_tmp[1] = vcm_tmp[2] = vcm_tmp[3] = vcm; - if (rssi_type != NPHY_RSSI_SEL_W2) { - wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_tmp); - } - - wlc_phy_poll_rssi_nphy(pi, rssi_type, &poll_results[vcm][0], - NPHY_RSSICAL_NPOLL); - - if ((rssi_type == NPHY_RSSI_SEL_W1) - || (rssi_type == NPHY_RSSI_SEL_W2)) { - for (ctr = 0; ctr < 2; ctr++) { - poll_miniq[vcm][ctr] = - min(poll_results[vcm][ctr * 2 + 0], - poll_results[vcm][ctr * 2 + 1]); - } - } - } - - for (result_idx = 0; result_idx < 4; result_idx++) { - min_d = NPHY_RSSICAL_MAXD; - min_vcm = 0; - min_poll = NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL + 1; - for (vcm = 0; vcm < 4; vcm++) { - curr_d = ABS(((rssi_type == NPHY_RSSI_SEL_NB) ? - poll_results[vcm][result_idx] : - poll_miniq[vcm][result_idx / 2]) - - (target_code * NPHY_RSSICAL_NPOLL)); - if (curr_d < min_d) { - min_d = curr_d; - min_vcm = vcm; - } - if (poll_results[vcm][result_idx] < min_poll) { - min_poll = poll_results[vcm][result_idx]; - } - } - vcm_final[result_idx] = min_vcm; - poll_results_min[result_idx] = min_poll; - } - - if (rssi_type != NPHY_RSSI_SEL_W2) { - wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_final); - } - - for (result_idx = 0; result_idx < 4; result_idx++) { - fine_digital_offset[result_idx] = - (target_code * NPHY_RSSICAL_NPOLL) - - poll_results[vcm_final[result_idx]][result_idx]; - if (fine_digital_offset[result_idx] < 0) { - fine_digital_offset[result_idx] = - ABS(fine_digital_offset[result_idx]); - fine_digital_offset[result_idx] += - (NPHY_RSSICAL_NPOLL / 2); - fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL; - fine_digital_offset[result_idx] = - -fine_digital_offset[result_idx]; - } else { - fine_digital_offset[result_idx] += - (NPHY_RSSICAL_NPOLL / 2); - fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL; - } - - if (poll_results_min[result_idx] == - NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL) { - fine_digital_offset[result_idx] = - (target_code - NPHY_RSSICAL_MAXREAD - 1); - } - - wlc_phy_scale_offset_rssi_nphy(pi, 0x0, - (s8) - fine_digital_offset[result_idx], - (result_idx / 2 == - 0) ? RADIO_MIMO_CORESEL_CORE1 : - RADIO_MIMO_CORESEL_CORE2, - (result_idx % 2 == - 0) ? NPHY_RAIL_I : NPHY_RAIL_Q, - rssi_type); - } - - mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, pd_state[0]); - mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, pd_state[1]); - if (rssi_ctrl_state[0] == RADIO_2055_NBRSSI_SEL) { - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, - NPHY_RSSI_SEL_NB); - } else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G1_SEL) { - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, - NPHY_RSSI_SEL_W1); - } else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G2_SEL) { - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, - NPHY_RSSI_SEL_W2); - } else { - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, - NPHY_RSSI_SEL_W2); - } - if (rssi_ctrl_state[1] == RADIO_2055_NBRSSI_SEL) { - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, - NPHY_RSSI_SEL_NB); - } else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G1_SEL) { - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, - NPHY_RSSI_SEL_W1); - } else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G2_SEL) { - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, - NPHY_RSSI_SEL_W2); - } else { - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, - NPHY_RSSI_SEL_W2); - } - - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, rssi_type); - - write_phy_reg(pi, 0x91, rfctrlintc_state[0]); - write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rfpdcorerxtx_state[0]); - write_phy_reg(pi, 0x92, rfctrlintc_state[1]); - write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rfpdcorerxtx_state[1]); - - wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state); - wlc_phy_clip_det_nphy(pi, 1, clip_state); - - wlc_phy_resetcca_nphy(pi); -} - -int BCMFASTPATH -wlc_phy_rssi_compute_nphy(phy_info_t *pi, wlc_d11rxhdr_t *wlc_rxh) -{ - d11rxhdr_t *rxh = &wlc_rxh->rxhdr; - s16 rxpwr, rxpwr0, rxpwr1; - s16 phyRx0_l, phyRx2_l; - - rxpwr = 0; - rxpwr0 = ltoh16(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR0_MASK; - rxpwr1 = (ltoh16(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR1_MASK) >> 8; - - if (rxpwr0 > 127) - rxpwr0 -= 256; - if (rxpwr1 > 127) - rxpwr1 -= 256; - - phyRx0_l = ltoh16(rxh->PhyRxStatus_0) & 0x00ff; - phyRx2_l = ltoh16(rxh->PhyRxStatus_2) & 0x00ff; - if (phyRx2_l > 127) - phyRx2_l -= 256; - - if (((rxpwr0 == 16) || (rxpwr0 == 32))) { - rxpwr0 = rxpwr1; - rxpwr1 = phyRx2_l; - } - - wlc_rxh->rxpwr[0] = (s8) rxpwr0; - wlc_rxh->rxpwr[1] = (s8) rxpwr1; - wlc_rxh->do_rssi_ma = 0; - - if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MAX) - rxpwr = (rxpwr0 > rxpwr1) ? rxpwr0 : rxpwr1; - else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MIN) - rxpwr = (rxpwr0 < rxpwr1) ? rxpwr0 : rxpwr1; - else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_AVG) - rxpwr = (rxpwr0 + rxpwr1) >> 1; - else - ASSERT(0); - - return rxpwr; -} - -static void -wlc_phy_rfctrlintc_override_nphy(phy_info_t *pi, u8 field, u16 value, - u8 core_code) -{ - u16 mask; - u16 val; - u8 core; - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - if (core_code == RADIO_MIMO_CORESEL_CORE1 - && core == PHY_CORE_1) - continue; - else if (core_code == RADIO_MIMO_CORESEL_CORE2 - && core == PHY_CORE_0) - continue; - - if (NREV_LT(pi->pubpi.phy_rev, 7)) { - - mask = (0x1 << 10); - val = 1 << 10; - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 : - 0x92, mask, val); - } - - if (field == NPHY_RfctrlIntc_override_OFF) { - - write_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 : - 0x92, 0); - - wlc_phy_force_rfseq_nphy(pi, - NPHY_RFSEQ_RESET2RX); - } else if (field == NPHY_RfctrlIntc_override_TRSW) { - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - mask = (0x1 << 6) | (0x1 << 7); - - val = value << 6; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - mask, val); - - or_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - (0x1 << 10)); - - and_phy_reg(pi, 0x2ff, (u16) - ~(0x3 << 14)); - or_phy_reg(pi, 0x2ff, (0x1 << 13)); - or_phy_reg(pi, 0x2ff, (0x1 << 0)); - } else { - - mask = (0x1 << 6) | - (0x1 << 7) | - (0x1 << 8) | (0x1 << 9); - val = value << 6; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - mask, val); - - mask = (0x1 << 0); - val = 1 << 0; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0xe7 : 0xec, - mask, val); - - mask = (core == PHY_CORE_0) ? (0x1 << 0) - : (0x1 << 1); - val = 1 << ((core == PHY_CORE_0) ? - 0 : 1); - mod_phy_reg(pi, 0x78, mask, val); - - SPINWAIT(((read_phy_reg(pi, 0x78) & val) - != 0), 10000); - ASSERT((read_phy_reg(pi, 0x78) & val) == - 0); - - mask = (0x1 << 0); - val = 0 << 0; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0xe7 : 0xec, - mask, val); - } - } else if (field == NPHY_RfctrlIntc_override_PA) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - mask = (0x1 << 4) | (0x1 << 5); - - if (CHSPEC_IS5G(pi->radio_chanspec)) { - val = value << 5; - } else { - val = value << 4; - } - - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - mask, val); - - or_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - (0x1 << 12)); - } else { - - if (CHSPEC_IS5G(pi->radio_chanspec)) { - mask = (0x1 << 5); - val = value << 5; - } else { - mask = (0x1 << 4); - val = value << 4; - } - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - mask, val); - } - } else if (field == NPHY_RfctrlIntc_override_EXT_LNA_PU) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - - mask = (0x1 << 0); - val = value << 0; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 - : 0x92, mask, val); - - mask = (0x1 << 2); - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 - : 0x92, mask, 0); - } else { - - mask = (0x1 << 2); - val = value << 2; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 - : 0x92, mask, val); - - mask = (0x1 << 0); - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 - : 0x92, mask, 0); - } - - mask = (0x1 << 11); - val = 1 << 11; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - mask, val); - } else { - - if (CHSPEC_IS5G(pi->radio_chanspec)) { - mask = (0x1 << 0); - val = value << 0; - } else { - mask = (0x1 << 2); - val = value << 2; - } - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - mask, val); - } - } else if (field == - NPHY_RfctrlIntc_override_EXT_LNA_GAIN) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - - mask = (0x1 << 1); - val = value << 1; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 - : 0x92, mask, val); - - mask = (0x1 << 3); - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 - : 0x92, mask, 0); - } else { - - mask = (0x1 << 3); - val = value << 3; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 - : 0x92, mask, val); - - mask = (0x1 << 1); - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 - : 0x92, mask, 0); - } - - mask = (0x1 << 11); - val = 1 << 11; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - mask, val); - } else { - - if (CHSPEC_IS5G(pi->radio_chanspec)) { - mask = (0x1 << 1); - val = value << 1; - } else { - mask = (0x1 << 3); - val = value << 3; - } - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - mask, val); - } - } - } - } else { - return; - } -} - -static void wlc_phy_rssi_cal_nphy_rev3(phy_info_t *pi) -{ - u16 classif_state; - u16 clip_state[2]; - u16 clip_off[] = { 0xffff, 0xffff }; - s32 target_code; - u8 vcm, min_vcm; - u8 vcm_final = 0; - u8 result_idx; - s32 poll_results[8][4] = { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0} - }; - s32 poll_result_core[4] = { 0, 0, 0, 0 }; - s32 min_d = NPHY_RSSICAL_MAXD, curr_d; - s32 fine_digital_offset[4]; - s32 poll_results_min[4] = { 0, 0, 0, 0 }; - s32 min_poll; - u8 vcm_level_max; - u8 core; - u8 wb_cnt; - u8 rssi_type; - u16 NPHY_Rfctrlintc1_save, NPHY_Rfctrlintc2_save; - u16 NPHY_AfectrlOverride1_save, NPHY_AfectrlOverride2_save; - u16 NPHY_AfectrlCore1_save, NPHY_AfectrlCore2_save; - u16 NPHY_RfctrlOverride0_save, NPHY_RfctrlOverride1_save; - u16 NPHY_RfctrlOverrideAux0_save, NPHY_RfctrlOverrideAux1_save; - u16 NPHY_RfctrlCmd_save; - u16 NPHY_RfctrlMiscReg1_save, NPHY_RfctrlMiscReg2_save; - u16 NPHY_RfctrlRSSIOTHERS1_save, NPHY_RfctrlRSSIOTHERS2_save; - u8 rxcore_state; - u16 NPHY_REV7_RfctrlOverride3_save, NPHY_REV7_RfctrlOverride4_save; - u16 NPHY_REV7_RfctrlOverride5_save, NPHY_REV7_RfctrlOverride6_save; - u16 NPHY_REV7_RfctrlMiscReg3_save, NPHY_REV7_RfctrlMiscReg4_save; - u16 NPHY_REV7_RfctrlMiscReg5_save, NPHY_REV7_RfctrlMiscReg6_save; - - NPHY_REV7_RfctrlOverride3_save = NPHY_REV7_RfctrlOverride4_save = - NPHY_REV7_RfctrlOverride5_save = NPHY_REV7_RfctrlOverride6_save = - NPHY_REV7_RfctrlMiscReg3_save = NPHY_REV7_RfctrlMiscReg4_save = - NPHY_REV7_RfctrlMiscReg5_save = NPHY_REV7_RfctrlMiscReg6_save = 0; - - classif_state = wlc_phy_classifier_nphy(pi, 0, 0); - wlc_phy_classifier_nphy(pi, (0x7 << 0), 4); - wlc_phy_clip_det_nphy(pi, 0, clip_state); - wlc_phy_clip_det_nphy(pi, 1, clip_off); - - NPHY_Rfctrlintc1_save = read_phy_reg(pi, 0x91); - NPHY_Rfctrlintc2_save = read_phy_reg(pi, 0x92); - NPHY_AfectrlOverride1_save = read_phy_reg(pi, 0x8f); - NPHY_AfectrlOverride2_save = read_phy_reg(pi, 0xa5); - NPHY_AfectrlCore1_save = read_phy_reg(pi, 0xa6); - NPHY_AfectrlCore2_save = read_phy_reg(pi, 0xa7); - NPHY_RfctrlOverride0_save = read_phy_reg(pi, 0xe7); - NPHY_RfctrlOverride1_save = read_phy_reg(pi, 0xec); - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - NPHY_REV7_RfctrlOverride3_save = read_phy_reg(pi, 0x342); - NPHY_REV7_RfctrlOverride4_save = read_phy_reg(pi, 0x343); - NPHY_REV7_RfctrlOverride5_save = read_phy_reg(pi, 0x346); - NPHY_REV7_RfctrlOverride6_save = read_phy_reg(pi, 0x347); - } - NPHY_RfctrlOverrideAux0_save = read_phy_reg(pi, 0xe5); - NPHY_RfctrlOverrideAux1_save = read_phy_reg(pi, 0xe6); - NPHY_RfctrlCmd_save = read_phy_reg(pi, 0x78); - NPHY_RfctrlMiscReg1_save = read_phy_reg(pi, 0xf9); - NPHY_RfctrlMiscReg2_save = read_phy_reg(pi, 0xfb); - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - NPHY_REV7_RfctrlMiscReg3_save = read_phy_reg(pi, 0x340); - NPHY_REV7_RfctrlMiscReg4_save = read_phy_reg(pi, 0x341); - NPHY_REV7_RfctrlMiscReg5_save = read_phy_reg(pi, 0x344); - NPHY_REV7_RfctrlMiscReg6_save = read_phy_reg(pi, 0x345); - } - NPHY_RfctrlRSSIOTHERS1_save = read_phy_reg(pi, 0x7a); - NPHY_RfctrlRSSIOTHERS2_save = read_phy_reg(pi, 0x7d); - - wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_OFF, 0, - RADIO_MIMO_CORESEL_ALLRXTX); - wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_TRSW, 1, - RADIO_MIMO_CORESEL_ALLRXTX); - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_rfctrl_override_1tomany_nphy(pi, - NPHY_REV7_RfctrlOverride_cmd_rxrf_pu, - 0, 0, 0); - } else { - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0, 0); - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_rfctrl_override_1tomany_nphy(pi, - NPHY_REV7_RfctrlOverride_cmd_rx_pu, - 1, 0, 0); - } else { - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0, 0); - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), - 1, 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 6), 1, 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - } else { - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 7), 1, 0, 0); - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 6), 1, 0, 0); - } - - if (CHSPEC_IS5G(pi->radio_chanspec)) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), - 0, 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 1, 0, - 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - } else { - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 0, 0, 0); - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 1, 0, 0); - } - - } else { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), - 0, 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 1, 0, - 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - } else { - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 0, 0, 0); - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 1, 0, 0); - } - } - - rxcore_state = wlc_phy_rxcore_getstate_nphy((wlc_phy_t *) pi); - - vcm_level_max = 8; - - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - - if ((rxcore_state & (1 << core)) == 0) - continue; - - wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, - core == - PHY_CORE_0 ? - RADIO_MIMO_CORESEL_CORE1 : - RADIO_MIMO_CORESEL_CORE2, - NPHY_RAIL_I, NPHY_RSSI_SEL_NB); - wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, - core == - PHY_CORE_0 ? - RADIO_MIMO_CORESEL_CORE1 : - RADIO_MIMO_CORESEL_CORE2, - NPHY_RAIL_Q, NPHY_RSSI_SEL_NB); - - for (vcm = 0; vcm < vcm_level_max; vcm++) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - mod_radio_reg(pi, (core == PHY_CORE_0) ? - RADIO_2057_NB_MASTER_CORE0 : - RADIO_2057_NB_MASTER_CORE1, - RADIO_2057_VCM_MASK, vcm); - } else { - - mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC | - ((core == - PHY_CORE_0) ? RADIO_2056_RX0 : - RADIO_2056_RX1), - RADIO_2056_VCM_MASK, - vcm << RADIO_2056_RSSI_VCM_SHIFT); - } - - wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_NB, - &poll_results[vcm][0], - NPHY_RSSICAL_NPOLL); - } - - for (result_idx = 0; result_idx < 4; result_idx++) { - if ((core == result_idx / 2) && (result_idx % 2 == 0)) { - - min_d = NPHY_RSSICAL_MAXD; - min_vcm = 0; - min_poll = - NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL + - 1; - for (vcm = 0; vcm < vcm_level_max; vcm++) { - curr_d = poll_results[vcm][result_idx] * - poll_results[vcm][result_idx] + - poll_results[vcm][result_idx + 1] * - poll_results[vcm][result_idx + 1]; - if (curr_d < min_d) { - min_d = curr_d; - min_vcm = vcm; - } - if (poll_results[vcm][result_idx] < - min_poll) { - min_poll = - poll_results[vcm] - [result_idx]; - } - } - vcm_final = min_vcm; - poll_results_min[result_idx] = min_poll; - } - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - mod_radio_reg(pi, (core == PHY_CORE_0) ? - RADIO_2057_NB_MASTER_CORE0 : - RADIO_2057_NB_MASTER_CORE1, - RADIO_2057_VCM_MASK, vcm_final); - } else { - mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC | - ((core == - PHY_CORE_0) ? RADIO_2056_RX0 : - RADIO_2056_RX1), RADIO_2056_VCM_MASK, - vcm_final << RADIO_2056_RSSI_VCM_SHIFT); - } - - for (result_idx = 0; result_idx < 4; result_idx++) { - if (core == result_idx / 2) { - fine_digital_offset[result_idx] = - (NPHY_RSSICAL_NB_TARGET * - NPHY_RSSICAL_NPOLL) - - poll_results[vcm_final][result_idx]; - if (fine_digital_offset[result_idx] < 0) { - fine_digital_offset[result_idx] = - ABS(fine_digital_offset - [result_idx]); - fine_digital_offset[result_idx] += - (NPHY_RSSICAL_NPOLL / 2); - fine_digital_offset[result_idx] /= - NPHY_RSSICAL_NPOLL; - fine_digital_offset[result_idx] = - -fine_digital_offset[result_idx]; - } else { - fine_digital_offset[result_idx] += - (NPHY_RSSICAL_NPOLL / 2); - fine_digital_offset[result_idx] /= - NPHY_RSSICAL_NPOLL; - } - - if (poll_results_min[result_idx] == - NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL) { - fine_digital_offset[result_idx] = - (NPHY_RSSICAL_NB_TARGET - - NPHY_RSSICAL_MAXREAD - 1); - } - - wlc_phy_scale_offset_rssi_nphy(pi, 0x0, - (s8) - fine_digital_offset - [result_idx], - (result_idx / - 2 == - 0) ? - RADIO_MIMO_CORESEL_CORE1 - : - RADIO_MIMO_CORESEL_CORE2, - (result_idx % - 2 == - 0) ? NPHY_RAIL_I - : NPHY_RAIL_Q, - NPHY_RSSI_SEL_NB); - } - } - - } - - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - - if ((rxcore_state & (1 << core)) == 0) - continue; - - for (wb_cnt = 0; wb_cnt < 2; wb_cnt++) { - if (wb_cnt == 0) { - rssi_type = NPHY_RSSI_SEL_W1; - target_code = NPHY_RSSICAL_W1_TARGET_REV3; - } else { - rssi_type = NPHY_RSSI_SEL_W2; - target_code = NPHY_RSSICAL_W2_TARGET_REV3; - } - - wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, - core == - PHY_CORE_0 ? - RADIO_MIMO_CORESEL_CORE1 - : - RADIO_MIMO_CORESEL_CORE2, - NPHY_RAIL_I, rssi_type); - wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, - core == - PHY_CORE_0 ? - RADIO_MIMO_CORESEL_CORE1 - : - RADIO_MIMO_CORESEL_CORE2, - NPHY_RAIL_Q, rssi_type); - - wlc_phy_poll_rssi_nphy(pi, rssi_type, poll_result_core, - NPHY_RSSICAL_NPOLL); - - for (result_idx = 0; result_idx < 4; result_idx++) { - if (core == result_idx / 2) { - fine_digital_offset[result_idx] = - (target_code * NPHY_RSSICAL_NPOLL) - - poll_result_core[result_idx]; - if (fine_digital_offset[result_idx] < 0) { - fine_digital_offset[result_idx] - = - ABS(fine_digital_offset - [result_idx]); - fine_digital_offset[result_idx] - += (NPHY_RSSICAL_NPOLL / 2); - fine_digital_offset[result_idx] - /= NPHY_RSSICAL_NPOLL; - fine_digital_offset[result_idx] - = - -fine_digital_offset - [result_idx]; - } else { - fine_digital_offset[result_idx] - += (NPHY_RSSICAL_NPOLL / 2); - fine_digital_offset[result_idx] - /= NPHY_RSSICAL_NPOLL; - } - - wlc_phy_scale_offset_rssi_nphy(pi, 0x0, - (s8) - fine_digital_offset - [core * - 2], - (core == - PHY_CORE_0) - ? - RADIO_MIMO_CORESEL_CORE1 - : - RADIO_MIMO_CORESEL_CORE2, - (result_idx - % 2 == - 0) ? - NPHY_RAIL_I - : - NPHY_RAIL_Q, - rssi_type); - } - } - - } - } - - write_phy_reg(pi, 0x91, NPHY_Rfctrlintc1_save); - write_phy_reg(pi, 0x92, NPHY_Rfctrlintc2_save); - - wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); - - mod_phy_reg(pi, 0xe7, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x78, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0xe7, (0x1 << 0), 0); - - mod_phy_reg(pi, 0xec, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x78, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0xec, (0x1 << 0), 0); - - write_phy_reg(pi, 0x8f, NPHY_AfectrlOverride1_save); - write_phy_reg(pi, 0xa5, NPHY_AfectrlOverride2_save); - write_phy_reg(pi, 0xa6, NPHY_AfectrlCore1_save); - write_phy_reg(pi, 0xa7, NPHY_AfectrlCore2_save); - write_phy_reg(pi, 0xe7, NPHY_RfctrlOverride0_save); - write_phy_reg(pi, 0xec, NPHY_RfctrlOverride1_save); - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - write_phy_reg(pi, 0x342, NPHY_REV7_RfctrlOverride3_save); - write_phy_reg(pi, 0x343, NPHY_REV7_RfctrlOverride4_save); - write_phy_reg(pi, 0x346, NPHY_REV7_RfctrlOverride5_save); - write_phy_reg(pi, 0x347, NPHY_REV7_RfctrlOverride6_save); - } - write_phy_reg(pi, 0xe5, NPHY_RfctrlOverrideAux0_save); - write_phy_reg(pi, 0xe6, NPHY_RfctrlOverrideAux1_save); - write_phy_reg(pi, 0x78, NPHY_RfctrlCmd_save); - write_phy_reg(pi, 0xf9, NPHY_RfctrlMiscReg1_save); - write_phy_reg(pi, 0xfb, NPHY_RfctrlMiscReg2_save); - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - write_phy_reg(pi, 0x340, NPHY_REV7_RfctrlMiscReg3_save); - write_phy_reg(pi, 0x341, NPHY_REV7_RfctrlMiscReg4_save); - write_phy_reg(pi, 0x344, NPHY_REV7_RfctrlMiscReg5_save); - write_phy_reg(pi, 0x345, NPHY_REV7_RfctrlMiscReg6_save); - } - write_phy_reg(pi, 0x7a, NPHY_RfctrlRSSIOTHERS1_save); - write_phy_reg(pi, 0x7d, NPHY_RfctrlRSSIOTHERS2_save); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - pi->rssical_cache.rssical_radio_regs_2G[0] = - read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0); - pi->rssical_cache.rssical_radio_regs_2G[1] = - read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1); - } else { - pi->rssical_cache.rssical_radio_regs_2G[0] = - read_radio_reg(pi, - RADIO_2056_RX_RSSI_MISC | - RADIO_2056_RX0); - pi->rssical_cache.rssical_radio_regs_2G[1] = - read_radio_reg(pi, - RADIO_2056_RX_RSSI_MISC | - RADIO_2056_RX1); - } - - pi->rssical_cache.rssical_phyregs_2G[0] = - read_phy_reg(pi, 0x1a6); - pi->rssical_cache.rssical_phyregs_2G[1] = - read_phy_reg(pi, 0x1ac); - pi->rssical_cache.rssical_phyregs_2G[2] = - read_phy_reg(pi, 0x1b2); - pi->rssical_cache.rssical_phyregs_2G[3] = - read_phy_reg(pi, 0x1b8); - pi->rssical_cache.rssical_phyregs_2G[4] = - read_phy_reg(pi, 0x1a4); - pi->rssical_cache.rssical_phyregs_2G[5] = - read_phy_reg(pi, 0x1aa); - pi->rssical_cache.rssical_phyregs_2G[6] = - read_phy_reg(pi, 0x1b0); - pi->rssical_cache.rssical_phyregs_2G[7] = - read_phy_reg(pi, 0x1b6); - pi->rssical_cache.rssical_phyregs_2G[8] = - read_phy_reg(pi, 0x1a5); - pi->rssical_cache.rssical_phyregs_2G[9] = - read_phy_reg(pi, 0x1ab); - pi->rssical_cache.rssical_phyregs_2G[10] = - read_phy_reg(pi, 0x1b1); - pi->rssical_cache.rssical_phyregs_2G[11] = - read_phy_reg(pi, 0x1b7); - - pi->nphy_rssical_chanspec_2G = pi->radio_chanspec; - } else { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - pi->rssical_cache.rssical_radio_regs_5G[0] = - read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0); - pi->rssical_cache.rssical_radio_regs_5G[1] = - read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1); - } else { - pi->rssical_cache.rssical_radio_regs_5G[0] = - read_radio_reg(pi, - RADIO_2056_RX_RSSI_MISC | - RADIO_2056_RX0); - pi->rssical_cache.rssical_radio_regs_5G[1] = - read_radio_reg(pi, - RADIO_2056_RX_RSSI_MISC | - RADIO_2056_RX1); - } - - pi->rssical_cache.rssical_phyregs_5G[0] = - read_phy_reg(pi, 0x1a6); - pi->rssical_cache.rssical_phyregs_5G[1] = - read_phy_reg(pi, 0x1ac); - pi->rssical_cache.rssical_phyregs_5G[2] = - read_phy_reg(pi, 0x1b2); - pi->rssical_cache.rssical_phyregs_5G[3] = - read_phy_reg(pi, 0x1b8); - pi->rssical_cache.rssical_phyregs_5G[4] = - read_phy_reg(pi, 0x1a4); - pi->rssical_cache.rssical_phyregs_5G[5] = - read_phy_reg(pi, 0x1aa); - pi->rssical_cache.rssical_phyregs_5G[6] = - read_phy_reg(pi, 0x1b0); - pi->rssical_cache.rssical_phyregs_5G[7] = - read_phy_reg(pi, 0x1b6); - pi->rssical_cache.rssical_phyregs_5G[8] = - read_phy_reg(pi, 0x1a5); - pi->rssical_cache.rssical_phyregs_5G[9] = - read_phy_reg(pi, 0x1ab); - pi->rssical_cache.rssical_phyregs_5G[10] = - read_phy_reg(pi, 0x1b1); - pi->rssical_cache.rssical_phyregs_5G[11] = - read_phy_reg(pi, 0x1b7); - - pi->nphy_rssical_chanspec_5G = pi->radio_chanspec; - } - - wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state); - wlc_phy_clip_det_nphy(pi, 1, clip_state); -} - -static void wlc_phy_restore_rssical_nphy(phy_info_t *pi) -{ - ASSERT(NREV_GE(pi->pubpi.phy_rev, 3)); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (pi->nphy_rssical_chanspec_2G == 0) - return; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0, - RADIO_2057_VCM_MASK, - pi->rssical_cache. - rssical_radio_regs_2G[0]); - mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1, - RADIO_2057_VCM_MASK, - pi->rssical_cache. - rssical_radio_regs_2G[1]); - } else { - mod_radio_reg(pi, - RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0, - RADIO_2056_VCM_MASK, - pi->rssical_cache. - rssical_radio_regs_2G[0]); - mod_radio_reg(pi, - RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1, - RADIO_2056_VCM_MASK, - pi->rssical_cache. - rssical_radio_regs_2G[1]); - } - - write_phy_reg(pi, 0x1a6, - pi->rssical_cache.rssical_phyregs_2G[0]); - write_phy_reg(pi, 0x1ac, - pi->rssical_cache.rssical_phyregs_2G[1]); - write_phy_reg(pi, 0x1b2, - pi->rssical_cache.rssical_phyregs_2G[2]); - write_phy_reg(pi, 0x1b8, - pi->rssical_cache.rssical_phyregs_2G[3]); - write_phy_reg(pi, 0x1a4, - pi->rssical_cache.rssical_phyregs_2G[4]); - write_phy_reg(pi, 0x1aa, - pi->rssical_cache.rssical_phyregs_2G[5]); - write_phy_reg(pi, 0x1b0, - pi->rssical_cache.rssical_phyregs_2G[6]); - write_phy_reg(pi, 0x1b6, - pi->rssical_cache.rssical_phyregs_2G[7]); - write_phy_reg(pi, 0x1a5, - pi->rssical_cache.rssical_phyregs_2G[8]); - write_phy_reg(pi, 0x1ab, - pi->rssical_cache.rssical_phyregs_2G[9]); - write_phy_reg(pi, 0x1b1, - pi->rssical_cache.rssical_phyregs_2G[10]); - write_phy_reg(pi, 0x1b7, - pi->rssical_cache.rssical_phyregs_2G[11]); - - } else { - if (pi->nphy_rssical_chanspec_5G == 0) - return; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0, - RADIO_2057_VCM_MASK, - pi->rssical_cache. - rssical_radio_regs_5G[0]); - mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1, - RADIO_2057_VCM_MASK, - pi->rssical_cache. - rssical_radio_regs_5G[1]); - } else { - mod_radio_reg(pi, - RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0, - RADIO_2056_VCM_MASK, - pi->rssical_cache. - rssical_radio_regs_5G[0]); - mod_radio_reg(pi, - RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1, - RADIO_2056_VCM_MASK, - pi->rssical_cache. - rssical_radio_regs_5G[1]); - } - - write_phy_reg(pi, 0x1a6, - pi->rssical_cache.rssical_phyregs_5G[0]); - write_phy_reg(pi, 0x1ac, - pi->rssical_cache.rssical_phyregs_5G[1]); - write_phy_reg(pi, 0x1b2, - pi->rssical_cache.rssical_phyregs_5G[2]); - write_phy_reg(pi, 0x1b8, - pi->rssical_cache.rssical_phyregs_5G[3]); - write_phy_reg(pi, 0x1a4, - pi->rssical_cache.rssical_phyregs_5G[4]); - write_phy_reg(pi, 0x1aa, - pi->rssical_cache.rssical_phyregs_5G[5]); - write_phy_reg(pi, 0x1b0, - pi->rssical_cache.rssical_phyregs_5G[6]); - write_phy_reg(pi, 0x1b6, - pi->rssical_cache.rssical_phyregs_5G[7]); - write_phy_reg(pi, 0x1a5, - pi->rssical_cache.rssical_phyregs_5G[8]); - write_phy_reg(pi, 0x1ab, - pi->rssical_cache.rssical_phyregs_5G[9]); - write_phy_reg(pi, 0x1b1, - pi->rssical_cache.rssical_phyregs_5G[10]); - write_phy_reg(pi, 0x1b7, - pi->rssical_cache.rssical_phyregs_5G[11]); - } -} - -static u16 -wlc_phy_gen_load_samples_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val, - u8 dac_test_mode) -{ - u8 phy_bw, is_phybw40; - u16 num_samps, t, spur; - fixed theta = 0, rot = 0; - u32 tbl_len; - cs32 *tone_buf = NULL; - - is_phybw40 = CHSPEC_IS40(pi->radio_chanspec); - phy_bw = (is_phybw40 == 1) ? 40 : 20; - tbl_len = (phy_bw << 3); - - if (dac_test_mode == 1) { - spur = read_phy_reg(pi, 0x01); - spur = (spur >> 15) & 1; - phy_bw = (spur == 1) ? 82 : 80; - phy_bw = (is_phybw40 == 1) ? (phy_bw << 1) : phy_bw; - - tbl_len = (phy_bw << 1); - } - - tone_buf = kmalloc(sizeof(cs32) * tbl_len, GFP_ATOMIC); - if (tone_buf == NULL) { - return 0; - } - - num_samps = (u16) tbl_len; - rot = FIXED((f_kHz * 36) / phy_bw) / 100; - theta = 0; - - for (t = 0; t < num_samps; t++) { - - wlc_phy_cordic(theta, &tone_buf[t]); - - theta += rot; - - tone_buf[t].q = (s32) FLOAT(tone_buf[t].q * max_val); - tone_buf[t].i = (s32) FLOAT(tone_buf[t].i * max_val); - } - - wlc_phy_loadsampletable_nphy(pi, tone_buf, num_samps); - - if (tone_buf != NULL) - kfree(tone_buf); - - return num_samps; -} - -int -wlc_phy_tx_tone_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val, - u8 iqmode, u8 dac_test_mode, bool modify_bbmult) -{ - u16 num_samps; - u16 loops = 0xffff; - u16 wait = 0; - - num_samps = - wlc_phy_gen_load_samples_nphy(pi, f_kHz, max_val, dac_test_mode); - if (num_samps == 0) { - return BCME_ERROR; - } - - wlc_phy_runsamples_nphy(pi, num_samps, loops, wait, iqmode, - dac_test_mode, modify_bbmult); - - return BCME_OK; -} - -static void -wlc_phy_loadsampletable_nphy(phy_info_t *pi, cs32 *tone_buf, - u16 num_samps) -{ - u16 t; - u32 *data_buf = NULL; - - data_buf = kmalloc(sizeof(u32) * num_samps, GFP_ATOMIC); - if (data_buf == NULL) { - return; - } - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - for (t = 0; t < num_samps; t++) { - data_buf[t] = ((((unsigned int)tone_buf[t].i) & 0x3ff) << 10) | - (((unsigned int)tone_buf[t].q) & 0x3ff); - } - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SAMPLEPLAY, num_samps, 0, 32, - data_buf); - - if (data_buf != NULL) - kfree(data_buf); - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); -} - -static void -wlc_phy_runsamples_nphy(phy_info_t *pi, u16 num_samps, u16 loops, - u16 wait, u8 iqmode, u8 dac_test_mode, - bool modify_bbmult) -{ - u16 bb_mult; - u8 phy_bw, sample_cmd; - u16 orig_RfseqCoreActv; - u16 lpf_bw_ctl_override3, lpf_bw_ctl_override4, lpf_bw_ctl_miscreg3, - lpf_bw_ctl_miscreg4; - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - phy_bw = 20; - if (CHSPEC_IS40(pi->radio_chanspec)) - phy_bw = 40; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - lpf_bw_ctl_override3 = read_phy_reg(pi, 0x342) & (0x1 << 7); - lpf_bw_ctl_override4 = read_phy_reg(pi, 0x343) & (0x1 << 7); - if (lpf_bw_ctl_override3 | lpf_bw_ctl_override4) { - lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) & - (0x7 << 8); - lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) & - (0x7 << 8); - } else { - wlc_phy_rfctrl_override_nphy_rev7(pi, - (0x1 << 7), - wlc_phy_read_lpf_bw_ctl_nphy - (pi, 0), 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - - pi->nphy_sample_play_lpf_bw_ctl_ovr = true; - - lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) & - (0x7 << 8); - lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) & - (0x7 << 8); - } - } - - if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) == 0) { - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16, - &bb_mult); - pi->nphy_bb_mult_save = - BB_MULT_VALID_MASK | (bb_mult & BB_MULT_MASK); - } - - if (modify_bbmult) { - bb_mult = (phy_bw == 20) ? 100 : 71; - bb_mult = (bb_mult << 8) + bb_mult; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16, - &bb_mult); - } - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); - - write_phy_reg(pi, 0xc6, num_samps - 1); - - if (loops != 0xffff) { - write_phy_reg(pi, 0xc4, loops - 1); - } else { - write_phy_reg(pi, 0xc4, loops); - } - write_phy_reg(pi, 0xc5, wait); - - orig_RfseqCoreActv = read_phy_reg(pi, 0xa1); - or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override); - if (iqmode) { - - and_phy_reg(pi, 0xc2, 0x7FFF); - - or_phy_reg(pi, 0xc2, 0x8000); - } else { - - sample_cmd = (dac_test_mode == 1) ? 0x5 : 0x1; - write_phy_reg(pi, 0xc3, sample_cmd); - } - - SPINWAIT(((read_phy_reg(pi, 0xa4) & 0x1) == 1), 1000); - - write_phy_reg(pi, 0xa1, orig_RfseqCoreActv); -} - -void wlc_phy_stopplayback_nphy(phy_info_t *pi) -{ - u16 playback_status; - u16 bb_mult; - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - playback_status = read_phy_reg(pi, 0xc7); - if (playback_status & 0x1) { - or_phy_reg(pi, 0xc3, NPHY_sampleCmd_STOP); - } else if (playback_status & 0x2) { - - and_phy_reg(pi, 0xc2, - (u16) ~NPHY_iqloCalCmdGctl_IQLO_CAL_EN); - } - - and_phy_reg(pi, 0xc3, (u16) ~(0x1 << 2)); - - if ((pi->nphy_bb_mult_save & BB_MULT_VALID_MASK) != 0) { - - bb_mult = pi->nphy_bb_mult_save & BB_MULT_MASK; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16, - &bb_mult); - - pi->nphy_bb_mult_save = 0; - } - - if (NREV_IS(pi->pubpi.phy_rev, 7) || NREV_GE(pi->pubpi.phy_rev, 8)) { - if (pi->nphy_sample_play_lpf_bw_ctl_ovr) { - wlc_phy_rfctrl_override_nphy_rev7(pi, - (0x1 << 7), - 0, 0, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - pi->nphy_sample_play_lpf_bw_ctl_ovr = false; - } - } - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); -} - -nphy_txgains_t wlc_phy_get_tx_gain_nphy(phy_info_t *pi) -{ - u16 base_idx[2], curr_gain[2]; - u8 core_no; - nphy_txgains_t target_gain; - u32 *tx_pwrctrl_tbl = NULL; - - if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) { - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, - curr_gain); - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); - - for (core_no = 0; core_no < 2; core_no++) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - target_gain.ipa[core_no] = - curr_gain[core_no] & 0x0007; - target_gain.pad[core_no] = - ((curr_gain[core_no] & 0x00F8) >> 3); - target_gain.pga[core_no] = - ((curr_gain[core_no] & 0x0F00) >> 8); - target_gain.txgm[core_no] = - ((curr_gain[core_no] & 0x7000) >> 12); - target_gain.txlpf[core_no] = - ((curr_gain[core_no] & 0x8000) >> 15); - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - target_gain.ipa[core_no] = - curr_gain[core_no] & 0x000F; - target_gain.pad[core_no] = - ((curr_gain[core_no] & 0x00F0) >> 4); - target_gain.pga[core_no] = - ((curr_gain[core_no] & 0x0F00) >> 8); - target_gain.txgm[core_no] = - ((curr_gain[core_no] & 0x7000) >> 12); - } else { - target_gain.ipa[core_no] = - curr_gain[core_no] & 0x0003; - target_gain.pad[core_no] = - ((curr_gain[core_no] & 0x000C) >> 2); - target_gain.pga[core_no] = - ((curr_gain[core_no] & 0x0070) >> 4); - target_gain.txgm[core_no] = - ((curr_gain[core_no] & 0x0380) >> 7); - } - } - } else { - base_idx[0] = (read_phy_reg(pi, 0x1ed) >> 8) & 0x7f; - base_idx[1] = (read_phy_reg(pi, 0x1ee) >> 8) & 0x7f; - for (core_no = 0; core_no < 2; core_no++) { - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if (PHY_IPA(pi)) { - tx_pwrctrl_tbl = - wlc_phy_get_ipa_gaintbl_nphy(pi); - } else { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - if NREV_IS - (pi->pubpi.phy_rev, 3) { - tx_pwrctrl_tbl = - nphy_tpc_5GHz_txgain_rev3; - } else if NREV_IS - (pi->pubpi.phy_rev, 4) { - tx_pwrctrl_tbl = - (pi->srom_fem5g. - extpagain == - 3) ? - nphy_tpc_5GHz_txgain_HiPwrEPA - : - nphy_tpc_5GHz_txgain_rev4; - } else { - tx_pwrctrl_tbl = - nphy_tpc_5GHz_txgain_rev5; - } - } else { - if (NREV_GE - (pi->pubpi.phy_rev, 7)) { - if (pi->pubpi. - radiorev == 3) { - tx_pwrctrl_tbl = - nphy_tpc_txgain_epa_2057rev3; - } else if (pi->pubpi. - radiorev == - 5) { - tx_pwrctrl_tbl = - nphy_tpc_txgain_epa_2057rev5; - } - - } else { - if (NREV_GE - (pi->pubpi.phy_rev, - 5) - && (pi->srom_fem2g. - extpagain == - 3)) { - tx_pwrctrl_tbl = - nphy_tpc_txgain_HiPwrEPA; - } else { - tx_pwrctrl_tbl = - nphy_tpc_txgain_rev3; - } - } - } - } - if NREV_GE - (pi->pubpi.phy_rev, 7) { - target_gain.ipa[core_no] = - (tx_pwrctrl_tbl[base_idx[core_no]] - >> 16) & 0x7; - target_gain.pad[core_no] = - (tx_pwrctrl_tbl[base_idx[core_no]] - >> 19) & 0x1f; - target_gain.pga[core_no] = - (tx_pwrctrl_tbl[base_idx[core_no]] - >> 24) & 0xf; - target_gain.txgm[core_no] = - (tx_pwrctrl_tbl[base_idx[core_no]] - >> 28) & 0x7; - target_gain.txlpf[core_no] = - (tx_pwrctrl_tbl[base_idx[core_no]] - >> 31) & 0x1; - } else { - target_gain.ipa[core_no] = - (tx_pwrctrl_tbl[base_idx[core_no]] - >> 16) & 0xf; - target_gain.pad[core_no] = - (tx_pwrctrl_tbl[base_idx[core_no]] - >> 20) & 0xf; - target_gain.pga[core_no] = - (tx_pwrctrl_tbl[base_idx[core_no]] - >> 24) & 0xf; - target_gain.txgm[core_no] = - (tx_pwrctrl_tbl[base_idx[core_no]] - >> 28) & 0x7; - } - } else { - target_gain.ipa[core_no] = - (nphy_tpc_txgain[base_idx[core_no]] >> 16) & - 0x3; - target_gain.pad[core_no] = - (nphy_tpc_txgain[base_idx[core_no]] >> 18) & - 0x3; - target_gain.pga[core_no] = - (nphy_tpc_txgain[base_idx[core_no]] >> 20) & - 0x7; - target_gain.txgm[core_no] = - (nphy_tpc_txgain[base_idx[core_no]] >> 23) & - 0x7; - } - } - } - - return target_gain; -} - -static void -wlc_phy_iqcal_gainparams_nphy(phy_info_t *pi, u16 core_no, - nphy_txgains_t target_gain, - nphy_iqcal_params_t *params) -{ - u8 k; - int idx; - u16 gain_index; - u8 band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0); - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - params->txlpf = target_gain.txlpf[core_no]; - } - params->txgm = target_gain.txgm[core_no]; - params->pga = target_gain.pga[core_no]; - params->pad = target_gain.pad[core_no]; - params->ipa = target_gain.ipa[core_no]; - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - params->cal_gain = - ((params->txlpf << 15) | (params-> - txgm << 12) | (params-> - pga << 8) | - (params->pad << 3) | (params->ipa)); - } else { - params->cal_gain = - ((params->txgm << 12) | (params-> - pga << 8) | (params-> - pad << 4) | - (params->ipa)); - } - params->ncorr[0] = 0x79; - params->ncorr[1] = 0x79; - params->ncorr[2] = 0x79; - params->ncorr[3] = 0x79; - params->ncorr[4] = 0x79; - } else { - - gain_index = ((target_gain.pad[core_no] << 0) | - (target_gain.pga[core_no] << 4) | (target_gain. - txgm[core_no] - << 8)); - - idx = -1; - for (k = 0; k < NPHY_IQCAL_NUMGAINS; k++) { - if (tbl_iqcal_gainparams_nphy[band_idx][k][0] == - gain_index) { - idx = k; - break; - } - } - - ASSERT(idx != -1); - - params->txgm = tbl_iqcal_gainparams_nphy[band_idx][k][1]; - params->pga = tbl_iqcal_gainparams_nphy[band_idx][k][2]; - params->pad = tbl_iqcal_gainparams_nphy[band_idx][k][3]; - params->cal_gain = ((params->txgm << 7) | (params->pga << 4) | - (params->pad << 2)); - params->ncorr[0] = tbl_iqcal_gainparams_nphy[band_idx][k][4]; - params->ncorr[1] = tbl_iqcal_gainparams_nphy[band_idx][k][5]; - params->ncorr[2] = tbl_iqcal_gainparams_nphy[band_idx][k][6]; - params->ncorr[3] = tbl_iqcal_gainparams_nphy[band_idx][k][7]; - } -} - -static void wlc_phy_txcal_radio_setup_nphy(phy_info_t *pi) -{ - u16 jtag_core, core; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - for (core = 0; core <= 1; core++) { - - pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - TX_SSI_MASTER); - - pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - IQCAL_VCM_HG); - - pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - IQCAL_IDAC); - - pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM); - - pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] = 0; - - pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - TX_SSI_MUX); - - if (pi->pubpi.radiorev != 5) - pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - TSSIA); - - pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG); - - pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - TSSI_MISC1); - - if (CHSPEC_IS5G(pi->radio_chanspec)) { - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TX_SSI_MASTER, 0x0a); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - IQCAL_VCM_HG, 0x43); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - IQCAL_IDAC, 0x55); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TSSI_VCM, 0x00); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TSSIG, 0x00); - if (pi->use_int_tx_iqlo_cal_nphy) { - WRITE_RADIO_REG3(pi, RADIO_2057, TX, - core, TX_SSI_MUX, 0x4); - if (! - (pi-> - internal_tx_iqlo_cal_tapoff_intpa_nphy)) { - - WRITE_RADIO_REG3(pi, RADIO_2057, - TX, core, - TSSIA, 0x31); - } else { - - WRITE_RADIO_REG3(pi, RADIO_2057, - TX, core, - TSSIA, 0x21); - } - } - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TSSI_MISC1, 0x00); - } else { - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TX_SSI_MASTER, 0x06); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - IQCAL_VCM_HG, 0x43); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - IQCAL_IDAC, 0x55); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TSSI_VCM, 0x00); - - if (pi->pubpi.radiorev != 5) - WRITE_RADIO_REG3(pi, RADIO_2057, TX, - core, TSSIA, 0x00); - if (pi->use_int_tx_iqlo_cal_nphy) { - WRITE_RADIO_REG3(pi, RADIO_2057, TX, - core, TX_SSI_MUX, - 0x06); - if (! - (pi-> - internal_tx_iqlo_cal_tapoff_intpa_nphy)) { - - WRITE_RADIO_REG3(pi, RADIO_2057, - TX, core, - TSSIG, 0x31); - } else { - - WRITE_RADIO_REG3(pi, RADIO_2057, - TX, core, - TSSIG, 0x21); - } - } - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TSSI_MISC1, 0x00); - } - } - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - - for (core = 0; core <= 1; core++) { - jtag_core = - (core == - PHY_CORE_0) ? RADIO_2056_TX0 : RADIO_2056_TX1; - - pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] = - read_radio_reg(pi, - RADIO_2056_TX_TX_SSI_MASTER | - jtag_core); - - pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] = - read_radio_reg(pi, - RADIO_2056_TX_IQCAL_VCM_HG | - jtag_core); - - pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] = - read_radio_reg(pi, - RADIO_2056_TX_IQCAL_IDAC | - jtag_core); - - pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] = - read_radio_reg(pi, - RADIO_2056_TX_TSSI_VCM | jtag_core); - - pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] = - read_radio_reg(pi, - RADIO_2056_TX_TX_AMP_DET | - jtag_core); - - pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] = - read_radio_reg(pi, - RADIO_2056_TX_TX_SSI_MUX | - jtag_core); - - pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] = - read_radio_reg(pi, RADIO_2056_TX_TSSIA | jtag_core); - - pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] = - read_radio_reg(pi, RADIO_2056_TX_TSSIG | jtag_core); - - pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] = - read_radio_reg(pi, - RADIO_2056_TX_TSSI_MISC1 | - jtag_core); - - pi->tx_rx_cal_radio_saveregs[(core * 11) + 9] = - read_radio_reg(pi, - RADIO_2056_TX_TSSI_MISC2 | - jtag_core); - - pi->tx_rx_cal_radio_saveregs[(core * 11) + 10] = - read_radio_reg(pi, - RADIO_2056_TX_TSSI_MISC3 | - jtag_core); - - if (CHSPEC_IS5G(pi->radio_chanspec)) { - write_radio_reg(pi, - RADIO_2056_TX_TX_SSI_MASTER | - jtag_core, 0x0a); - write_radio_reg(pi, - RADIO_2056_TX_IQCAL_VCM_HG | - jtag_core, 0x40); - write_radio_reg(pi, - RADIO_2056_TX_IQCAL_IDAC | - jtag_core, 0x55); - write_radio_reg(pi, - RADIO_2056_TX_TSSI_VCM | - jtag_core, 0x00); - write_radio_reg(pi, - RADIO_2056_TX_TX_AMP_DET | - jtag_core, 0x00); - - if (PHY_IPA(pi)) { - write_radio_reg(pi, - RADIO_2056_TX_TX_SSI_MUX - | jtag_core, 0x4); - write_radio_reg(pi, - RADIO_2056_TX_TSSIA | - jtag_core, 0x1); - } else { - write_radio_reg(pi, - RADIO_2056_TX_TX_SSI_MUX - | jtag_core, 0x00); - write_radio_reg(pi, - RADIO_2056_TX_TSSIA | - jtag_core, 0x2f); - } - write_radio_reg(pi, - RADIO_2056_TX_TSSIG | jtag_core, - 0x00); - write_radio_reg(pi, - RADIO_2056_TX_TSSI_MISC1 | - jtag_core, 0x00); - - write_radio_reg(pi, - RADIO_2056_TX_TSSI_MISC2 | - jtag_core, 0x00); - write_radio_reg(pi, - RADIO_2056_TX_TSSI_MISC3 | - jtag_core, 0x00); - } else { - write_radio_reg(pi, - RADIO_2056_TX_TX_SSI_MASTER | - jtag_core, 0x06); - write_radio_reg(pi, - RADIO_2056_TX_IQCAL_VCM_HG | - jtag_core, 0x40); - write_radio_reg(pi, - RADIO_2056_TX_IQCAL_IDAC | - jtag_core, 0x55); - write_radio_reg(pi, - RADIO_2056_TX_TSSI_VCM | - jtag_core, 0x00); - write_radio_reg(pi, - RADIO_2056_TX_TX_AMP_DET | - jtag_core, 0x00); - write_radio_reg(pi, - RADIO_2056_TX_TSSIA | jtag_core, - 0x00); - - if (PHY_IPA(pi)) { - - write_radio_reg(pi, - RADIO_2056_TX_TX_SSI_MUX - | jtag_core, 0x06); - if (NREV_LT(pi->pubpi.phy_rev, 5)) { - - write_radio_reg(pi, - RADIO_2056_TX_TSSIG - | jtag_core, - 0x11); - } else { - - write_radio_reg(pi, - RADIO_2056_TX_TSSIG - | jtag_core, - 0x1); - } - } else { - write_radio_reg(pi, - RADIO_2056_TX_TX_SSI_MUX - | jtag_core, 0x00); - write_radio_reg(pi, - RADIO_2056_TX_TSSIG | - jtag_core, 0x20); - } - - write_radio_reg(pi, - RADIO_2056_TX_TSSI_MISC1 | - jtag_core, 0x00); - write_radio_reg(pi, - RADIO_2056_TX_TSSI_MISC2 | - jtag_core, 0x00); - write_radio_reg(pi, - RADIO_2056_TX_TSSI_MISC3 | - jtag_core, 0x00); - } - } - } else { - - pi->tx_rx_cal_radio_saveregs[0] = - read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1); - write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x29); - pi->tx_rx_cal_radio_saveregs[1] = - read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2); - write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x54); - - pi->tx_rx_cal_radio_saveregs[2] = - read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1); - write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x29); - pi->tx_rx_cal_radio_saveregs[3] = - read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2); - write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x54); - - pi->tx_rx_cal_radio_saveregs[4] = - read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1); - pi->tx_rx_cal_radio_saveregs[5] = - read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2); - - if ((read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand) == - 0) { - - write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x04); - write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x04); - } else { - - write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, 0x20); - write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, 0x20); - } - - if (NREV_LT(pi->pubpi.phy_rev, 2)) { - - or_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0x20); - or_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0x20); - } else { - - and_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, 0xdf); - and_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, 0xdf); - } - } -} - -static void wlc_phy_txcal_radio_cleanup_nphy(phy_info_t *pi) -{ - u16 jtag_core, core; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - for (core = 0; core <= 1; core++) { - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TX_SSI_MASTER, - pi-> - tx_rx_cal_radio_saveregs[(core * 11) + - 0]); - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG, - pi-> - tx_rx_cal_radio_saveregs[(core * 11) + - 1]); - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC, - pi-> - tx_rx_cal_radio_saveregs[(core * 11) + - 2]); - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM, - pi-> - tx_rx_cal_radio_saveregs[(core * 11) + - 3]); - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TX_SSI_MUX, - pi-> - tx_rx_cal_radio_saveregs[(core * 11) + - 5]); - - if (pi->pubpi.radiorev != 5) - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TSSIA, - pi-> - tx_rx_cal_radio_saveregs[(core - * - 11) + - 6]); - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG, - pi-> - tx_rx_cal_radio_saveregs[(core * 11) + - 7]); - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1, - pi-> - tx_rx_cal_radio_saveregs[(core * 11) + - 8]); - } - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - for (core = 0; core <= 1; core++) { - jtag_core = - (core == - PHY_CORE_0) ? RADIO_2056_TX0 : RADIO_2056_TX1; - - write_radio_reg(pi, - RADIO_2056_TX_TX_SSI_MASTER | jtag_core, - pi-> - tx_rx_cal_radio_saveregs[(core * 11) + - 0]); - - write_radio_reg(pi, - RADIO_2056_TX_IQCAL_VCM_HG | jtag_core, - pi-> - tx_rx_cal_radio_saveregs[(core * 11) + - 1]); - - write_radio_reg(pi, - RADIO_2056_TX_IQCAL_IDAC | jtag_core, - pi-> - tx_rx_cal_radio_saveregs[(core * 11) + - 2]); - - write_radio_reg(pi, RADIO_2056_TX_TSSI_VCM | jtag_core, - pi-> - tx_rx_cal_radio_saveregs[(core * 11) + - 3]); - - write_radio_reg(pi, - RADIO_2056_TX_TX_AMP_DET | jtag_core, - pi-> - tx_rx_cal_radio_saveregs[(core * 11) + - 4]); - - write_radio_reg(pi, - RADIO_2056_TX_TX_SSI_MUX | jtag_core, - pi-> - tx_rx_cal_radio_saveregs[(core * 11) + - 5]); - - write_radio_reg(pi, RADIO_2056_TX_TSSIA | jtag_core, - pi-> - tx_rx_cal_radio_saveregs[(core * 11) + - 6]); - - write_radio_reg(pi, RADIO_2056_TX_TSSIG | jtag_core, - pi-> - tx_rx_cal_radio_saveregs[(core * 11) + - 7]); - - write_radio_reg(pi, - RADIO_2056_TX_TSSI_MISC1 | jtag_core, - pi-> - tx_rx_cal_radio_saveregs[(core * 11) + - 8]); - - write_radio_reg(pi, - RADIO_2056_TX_TSSI_MISC2 | jtag_core, - pi-> - tx_rx_cal_radio_saveregs[(core * 11) + - 9]); - - write_radio_reg(pi, - RADIO_2056_TX_TSSI_MISC3 | jtag_core, - pi-> - tx_rx_cal_radio_saveregs[(core * 11) + - 10]); - } - } else { - - write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, - pi->tx_rx_cal_radio_saveregs[0]); - write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, - pi->tx_rx_cal_radio_saveregs[1]); - write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, - pi->tx_rx_cal_radio_saveregs[2]); - write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, - pi->tx_rx_cal_radio_saveregs[3]); - write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1, - pi->tx_rx_cal_radio_saveregs[4]); - write_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2, - pi->tx_rx_cal_radio_saveregs[5]); - } -} - -static void wlc_phy_txcal_physetup_nphy(phy_info_t *pi) -{ - u16 val, mask; - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6); - pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7); - - mask = ((0x3 << 8) | (0x3 << 10)); - val = (0x2 << 8); - val |= (0x2 << 10); - mod_phy_reg(pi, 0xa6, mask, val); - mod_phy_reg(pi, 0xa7, mask, val); - - val = read_phy_reg(pi, 0x8f); - pi->tx_rx_cal_phy_saveregs[2] = val; - val |= ((0x1 << 9) | (0x1 << 10)); - write_phy_reg(pi, 0x8f, val); - - val = read_phy_reg(pi, 0xa5); - pi->tx_rx_cal_phy_saveregs[3] = val; - val |= ((0x1 << 9) | (0x1 << 10)); - write_phy_reg(pi, 0xa5, val); - - pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x01); - mod_phy_reg(pi, 0x01, (0x1 << 15), 0); - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16, - &val); - pi->tx_rx_cal_phy_saveregs[5] = val; - val = 0; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16, - &val); - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16, - &val); - pi->tx_rx_cal_phy_saveregs[6] = val; - val = 0; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16, - &val); - - pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0x91); - pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0x92); - - if (!(pi->use_int_tx_iqlo_cal_nphy)) { - - wlc_phy_rfctrlintc_override_nphy(pi, - NPHY_RfctrlIntc_override_PA, - 1, - RADIO_MIMO_CORESEL_CORE1 - | - RADIO_MIMO_CORESEL_CORE2); - } else { - - wlc_phy_rfctrlintc_override_nphy(pi, - NPHY_RfctrlIntc_override_PA, - 0, - RADIO_MIMO_CORESEL_CORE1 - | - RADIO_MIMO_CORESEL_CORE2); - } - - wlc_phy_rfctrlintc_override_nphy(pi, - NPHY_RfctrlIntc_override_TRSW, - 0x2, RADIO_MIMO_CORESEL_CORE1); - wlc_phy_rfctrlintc_override_nphy(pi, - NPHY_RfctrlIntc_override_TRSW, - 0x8, RADIO_MIMO_CORESEL_CORE2); - - pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297); - pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b); - mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (0) << 0); - - mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (0) << 0); - - if (NREV_IS(pi->pubpi.phy_rev, 7) - || NREV_GE(pi->pubpi.phy_rev, 8)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), - wlc_phy_read_lpf_bw_ctl_nphy - (pi, 0), 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - } - - if (pi->use_int_tx_iqlo_cal_nphy - && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) { - - if (NREV_IS(pi->pubpi.phy_rev, 7)) { - - mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4, - 1 << 4); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - mod_radio_reg(pi, - RADIO_2057_PAD2G_TUNE_PUS_CORE0, - 1, 0); - mod_radio_reg(pi, - RADIO_2057_PAD2G_TUNE_PUS_CORE1, - 1, 0); - } else { - mod_radio_reg(pi, - RADIO_2057_IPA5G_CASCOFFV_PU_CORE0, - 1, 0); - mod_radio_reg(pi, - RADIO_2057_IPA5G_CASCOFFV_PU_CORE1, - 1, 0); - } - } else if (NREV_GE(pi->pubpi.phy_rev, 8)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, - (0x1 << 3), 0, - 0x3, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - } - } - } else { - pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa6); - pi->tx_rx_cal_phy_saveregs[1] = read_phy_reg(pi, 0xa7); - - mask = ((0x3 << 12) | (0x3 << 14)); - val = (0x2 << 12); - val |= (0x2 << 14); - mod_phy_reg(pi, 0xa6, mask, val); - mod_phy_reg(pi, 0xa7, mask, val); - - val = read_phy_reg(pi, 0xa5); - pi->tx_rx_cal_phy_saveregs[2] = val; - val |= ((0x1 << 12) | (0x1 << 13)); - write_phy_reg(pi, 0xa5, val); - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16, - &val); - pi->tx_rx_cal_phy_saveregs[3] = val; - val |= 0x2000; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16, - &val); - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16, - &val); - pi->tx_rx_cal_phy_saveregs[4] = val; - val |= 0x2000; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16, - &val); - - pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x91); - pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x92); - val = CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120; - write_phy_reg(pi, 0x91, val); - write_phy_reg(pi, 0x92, val); - } -} - -static void wlc_phy_txcal_phycleanup_nphy(phy_info_t *pi) -{ - u16 mask; - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - write_phy_reg(pi, 0xa6, pi->tx_rx_cal_phy_saveregs[0]); - write_phy_reg(pi, 0xa7, pi->tx_rx_cal_phy_saveregs[1]); - write_phy_reg(pi, 0x8f, pi->tx_rx_cal_phy_saveregs[2]); - write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[3]); - write_phy_reg(pi, 0x01, pi->tx_rx_cal_phy_saveregs[4]); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 3, 16, - &pi->tx_rx_cal_phy_saveregs[5]); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 19, 16, - &pi->tx_rx_cal_phy_saveregs[6]); - - write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[7]); - write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[8]); - - write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]); - write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]); - - if (NREV_IS(pi->pubpi.phy_rev, 7) - || NREV_GE(pi->pubpi.phy_rev, 8)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), 0, 0, - 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - } - - wlc_phy_resetcca_nphy(pi); - - if (pi->use_int_tx_iqlo_cal_nphy - && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) { - - if (NREV_IS(pi->pubpi.phy_rev, 7)) { - if (CHSPEC_IS2G(pi->radio_chanspec)) { - mod_radio_reg(pi, - RADIO_2057_PAD2G_TUNE_PUS_CORE0, - 1, 1); - mod_radio_reg(pi, - RADIO_2057_PAD2G_TUNE_PUS_CORE1, - 1, 1); - } else { - mod_radio_reg(pi, - RADIO_2057_IPA5G_CASCOFFV_PU_CORE0, - 1, 1); - mod_radio_reg(pi, - RADIO_2057_IPA5G_CASCOFFV_PU_CORE1, - 1, 1); - } - - mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4, - 0); - } else if (NREV_GE(pi->pubpi.phy_rev, 8)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, - (0x1 << 3), 0, - 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - } - } - } else { - mask = ((0x3 << 12) | (0x3 << 14)); - mod_phy_reg(pi, 0xa6, mask, pi->tx_rx_cal_phy_saveregs[0]); - mod_phy_reg(pi, 0xa7, mask, pi->tx_rx_cal_phy_saveregs[1]); - write_phy_reg(pi, 0xa5, pi->tx_rx_cal_phy_saveregs[2]); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 2, 16, - &pi->tx_rx_cal_phy_saveregs[3]); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 18, 16, - &pi->tx_rx_cal_phy_saveregs[4]); - - write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[5]); - write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[6]); - } -} - -#define NPHY_CAL_TSSISAMPS 64 -#define NPHY_TEST_TONE_FREQ_40MHz 4000 -#define NPHY_TEST_TONE_FREQ_20MHz 2500 - -void -wlc_phy_est_tonepwr_nphy(phy_info_t *pi, s32 *qdBm_pwrbuf, u8 num_samps) -{ - u16 tssi_reg; - s32 temp, pwrindex[2]; - s32 idle_tssi[2]; - s32 rssi_buf[4]; - s32 tssival[2]; - u8 tssi_type; - - tssi_reg = read_phy_reg(pi, 0x1e9); - - temp = (s32) (tssi_reg & 0x3f); - idle_tssi[0] = (temp <= 31) ? temp : (temp - 64); - - temp = (s32) ((tssi_reg >> 8) & 0x3f); - idle_tssi[1] = (temp <= 31) ? temp : (temp - 64); - - tssi_type = - CHSPEC_IS5G(pi->radio_chanspec) ? - (u8)NPHY_RSSI_SEL_TSSI_5G:(u8)NPHY_RSSI_SEL_TSSI_2G; - - wlc_phy_poll_rssi_nphy(pi, tssi_type, rssi_buf, num_samps); - - tssival[0] = rssi_buf[0] / ((s32) num_samps); - tssival[1] = rssi_buf[2] / ((s32) num_samps); - - pwrindex[0] = idle_tssi[0] - tssival[0] + 64; - pwrindex[1] = idle_tssi[1] - tssival[1] + 64; - - if (pwrindex[0] < 0) { - pwrindex[0] = 0; - } else if (pwrindex[0] > 63) { - pwrindex[0] = 63; - } - - if (pwrindex[1] < 0) { - pwrindex[1] = 0; - } else if (pwrindex[1] > 63) { - pwrindex[1] = 63; - } - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 1, - (u32) pwrindex[0], 32, &qdBm_pwrbuf[0]); - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 1, - (u32) pwrindex[1], 32, &qdBm_pwrbuf[1]); -} - -static void wlc_phy_internal_cal_txgain_nphy(phy_info_t *pi) -{ - u16 txcal_gain[2]; - - pi->nphy_txcal_pwr_idx[0] = pi->nphy_cal_orig_pwr_idx[0]; - pi->nphy_txcal_pwr_idx[1] = pi->nphy_cal_orig_pwr_idx[0]; - wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true); - wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true); - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, - txcal_gain); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F40; - txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F40; - } else { - txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F60; - txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F60; - } - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, - txcal_gain); -} - -static void wlc_phy_precal_txgain_nphy(phy_info_t *pi) -{ - bool save_bbmult = false; - u8 txcal_index_2057_rev5n7 = 0; - u8 txcal_index_2057_rev3n4n6 = 10; - - if (pi->use_int_tx_iqlo_cal_nphy) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if ((pi->pubpi.radiorev == 3) || - (pi->pubpi.radiorev == 4) || - (pi->pubpi.radiorev == 6)) { - - pi->nphy_txcal_pwr_idx[0] = - txcal_index_2057_rev3n4n6; - pi->nphy_txcal_pwr_idx[1] = - txcal_index_2057_rev3n4n6; - wlc_phy_txpwr_index_nphy(pi, 3, - txcal_index_2057_rev3n4n6, - false); - } else { - - pi->nphy_txcal_pwr_idx[0] = - txcal_index_2057_rev5n7; - pi->nphy_txcal_pwr_idx[1] = - txcal_index_2057_rev5n7; - wlc_phy_txpwr_index_nphy(pi, 3, - txcal_index_2057_rev5n7, - false); - } - save_bbmult = true; - - } else if (NREV_LT(pi->pubpi.phy_rev, 5)) { - wlc_phy_cal_txgainctrl_nphy(pi, 11, false); - if (pi->sh->hw_phytxchain != 3) { - pi->nphy_txcal_pwr_idx[1] = - pi->nphy_txcal_pwr_idx[0]; - wlc_phy_txpwr_index_nphy(pi, 3, - pi-> - nphy_txcal_pwr_idx[0], - true); - save_bbmult = true; - } - - } else if (NREV_IS(pi->pubpi.phy_rev, 5)) { - if (PHY_IPA(pi)) { - if (CHSPEC_IS2G(pi->radio_chanspec)) { - wlc_phy_cal_txgainctrl_nphy(pi, 12, - false); - } else { - pi->nphy_txcal_pwr_idx[0] = 80; - pi->nphy_txcal_pwr_idx[1] = 80; - wlc_phy_txpwr_index_nphy(pi, 3, 80, - false); - save_bbmult = true; - } - } else { - - wlc_phy_internal_cal_txgain_nphy(pi); - save_bbmult = true; - } - - } else if (NREV_IS(pi->pubpi.phy_rev, 6)) { - if (PHY_IPA(pi)) { - if (CHSPEC_IS2G(pi->radio_chanspec)) { - wlc_phy_cal_txgainctrl_nphy(pi, 12, - false); - } else { - wlc_phy_cal_txgainctrl_nphy(pi, 14, - false); - } - } else { - - wlc_phy_internal_cal_txgain_nphy(pi); - save_bbmult = true; - } - } - - } else { - wlc_phy_cal_txgainctrl_nphy(pi, 10, false); - } - - if (save_bbmult) { - wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, - &pi->nphy_txcal_bbmult); - } -} - -void -wlc_phy_cal_txgainctrl_nphy(phy_info_t *pi, s32 dBm_targetpower, bool debug) -{ - int gainctrl_loopidx; - uint core; - u16 m0m1, curr_m0m1; - s32 delta_power; - s32 txpwrindex; - s32 qdBm_power[2]; - u16 orig_BBConfig; - u16 phy_saveregs[4]; - u32 freq_test; - u16 ampl_test = 250; - uint stepsize; - bool phyhang_avoid_state = false; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - stepsize = 2; - } else { - - stepsize = 1; - } - - if (CHSPEC_IS40(pi->radio_chanspec)) { - freq_test = 5000; - } else { - freq_test = 2500; - } - - wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true); - wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true); - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - phyhang_avoid_state = pi->phyhang_avoid; - pi->phyhang_avoid = false; - - phy_saveregs[0] = read_phy_reg(pi, 0x91); - phy_saveregs[1] = read_phy_reg(pi, 0x92); - phy_saveregs[2] = read_phy_reg(pi, 0xe7); - phy_saveregs[3] = read_phy_reg(pi, 0xec); - wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 1, - RADIO_MIMO_CORESEL_CORE1 | - RADIO_MIMO_CORESEL_CORE2); - - if (!debug) { - wlc_phy_rfctrlintc_override_nphy(pi, - NPHY_RfctrlIntc_override_TRSW, - 0x2, RADIO_MIMO_CORESEL_CORE1); - wlc_phy_rfctrlintc_override_nphy(pi, - NPHY_RfctrlIntc_override_TRSW, - 0x8, RADIO_MIMO_CORESEL_CORE2); - } else { - wlc_phy_rfctrlintc_override_nphy(pi, - NPHY_RfctrlIntc_override_TRSW, - 0x1, RADIO_MIMO_CORESEL_CORE1); - wlc_phy_rfctrlintc_override_nphy(pi, - NPHY_RfctrlIntc_override_TRSW, - 0x7, RADIO_MIMO_CORESEL_CORE2); - } - - orig_BBConfig = read_phy_reg(pi, 0x01); - mod_phy_reg(pi, 0x01, (0x1 << 15), 0); - - wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1); - - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - txpwrindex = (s32) pi->nphy_cal_orig_pwr_idx[core]; - - for (gainctrl_loopidx = 0; gainctrl_loopidx < 2; - gainctrl_loopidx++) { - wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0, - false); - - if (core == PHY_CORE_0) { - curr_m0m1 = m0m1 & 0xff00; - } else { - curr_m0m1 = m0m1 & 0x00ff; - } - - wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &curr_m0m1); - wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &curr_m0m1); - - udelay(50); - - wlc_phy_est_tonepwr_nphy(pi, qdBm_power, - NPHY_CAL_TSSISAMPS); - - pi->nphy_bb_mult_save = 0; - wlc_phy_stopplayback_nphy(pi); - - delta_power = (dBm_targetpower * 4) - qdBm_power[core]; - - txpwrindex -= stepsize * delta_power; - if (txpwrindex < 0) { - txpwrindex = 0; - } else if (txpwrindex > 127) { - txpwrindex = 127; - } - - if (CHSPEC_IS5G(pi->radio_chanspec)) { - if (NREV_IS(pi->pubpi.phy_rev, 4) && - (pi->srom_fem5g.extpagain == 3)) { - if (txpwrindex < 30) { - txpwrindex = 30; - } - } - } else { - if (NREV_GE(pi->pubpi.phy_rev, 5) && - (pi->srom_fem2g.extpagain == 3)) { - if (txpwrindex < 50) { - txpwrindex = 50; - } - } - } - - wlc_phy_txpwr_index_nphy(pi, (1 << core), - (u8) txpwrindex, true); - } - - pi->nphy_txcal_pwr_idx[core] = (u8) txpwrindex; - - if (debug) { - u16 radio_gain; - u16 dbg_m0m1; - - wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &dbg_m0m1); - - wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0, - false); - - wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &dbg_m0m1); - wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &dbg_m0m1); - - udelay(100); - - wlc_phy_est_tonepwr_nphy(pi, qdBm_power, - NPHY_CAL_TSSISAMPS); - - wlc_phy_table_read_nphy(pi, 7, 1, (0x110 + core), 16, - &radio_gain); - - mdelay(4000); - pi->nphy_bb_mult_save = 0; - wlc_phy_stopplayback_nphy(pi); - } - } - - wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_txcal_pwr_idx[0], true); - wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_txcal_pwr_idx[1], true); - - wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &pi->nphy_txcal_bbmult); - - write_phy_reg(pi, 0x01, orig_BBConfig); - - write_phy_reg(pi, 0x91, phy_saveregs[0]); - write_phy_reg(pi, 0x92, phy_saveregs[1]); - write_phy_reg(pi, 0xe7, phy_saveregs[2]); - write_phy_reg(pi, 0xec, phy_saveregs[3]); - - pi->phyhang_avoid = phyhang_avoid_state; - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); -} - -static void wlc_phy_update_txcal_ladder_nphy(phy_info_t *pi, u16 core) -{ - int index; - u32 bbmult_scale; - u16 bbmult; - u16 tblentry; - - nphy_txiqcal_ladder_t ladder_lo[] = { - {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0}, - {25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5}, - {25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7} - }; - - nphy_txiqcal_ladder_t ladder_iq[] = { - {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0}, - {25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1}, - {100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7} - }; - - bbmult = (core == PHY_CORE_0) ? - ((pi->nphy_txcal_bbmult >> 8) & 0xff) : (pi-> - nphy_txcal_bbmult & 0xff); - - for (index = 0; index < 18; index++) { - bbmult_scale = ladder_lo[index].percent * bbmult; - bbmult_scale /= 100; - - tblentry = - ((bbmult_scale & 0xff) << 8) | ladder_lo[index].g_env; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index, 16, - &tblentry); - - bbmult_scale = ladder_iq[index].percent * bbmult; - bbmult_scale /= 100; - - tblentry = - ((bbmult_scale & 0xff) << 8) | ladder_iq[index].g_env; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index + 32, - 16, &tblentry); - } -} - -void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype) -{ - nphy_txgains_t target_gain; - u8 tx_pwr_ctrl_state; - bool fullcal = true; - bool restore_tx_gain = false; - bool mphase; - - if (NORADIO_ENAB(pi->pubpi)) { - wlc_phy_cal_perical_mphase_reset(pi); - return; - } - - if (PHY_MUTED(pi)) - return; - - ASSERT(pi->nphy_perical != PHY_PERICAL_DISABLE); - - if (caltype == PHY_PERICAL_AUTO) - fullcal = (pi->radio_chanspec != pi->nphy_txiqlocal_chanspec); - else if (caltype == PHY_PERICAL_PARTIAL) - fullcal = false; - - if (pi->cal_type_override != PHY_PERICAL_AUTO) { - fullcal = - (pi->cal_type_override == PHY_PERICAL_FULL) ? true : false; - } - - if ((pi->mphase_cal_phase_id > MPHASE_CAL_STATE_INIT)) { - if (pi->nphy_txiqlocal_chanspec != pi->radio_chanspec) - wlc_phy_cal_perical_mphase_restart(pi); - } - - if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_RXCAL)) { - wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000); - } - - wlapi_suspend_mac_and_wait(pi->sh->physhim); - - wlc_phyreg_enter((wlc_phy_t *) pi); - - if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_IDLE) || - (pi->mphase_cal_phase_id == MPHASE_CAL_STATE_INIT)) { - pi->nphy_cal_orig_pwr_idx[0] = - (u8) ((read_phy_reg(pi, 0x1ed) >> 8) & 0x7f); - pi->nphy_cal_orig_pwr_idx[1] = - (u8) ((read_phy_reg(pi, 0x1ee) >> 8) & 0x7f); - - if (pi->nphy_txpwrctrl != PHY_TPC_HW_OFF) { - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, - 0x110, 16, - pi->nphy_cal_orig_tx_gain); - } else { - pi->nphy_cal_orig_tx_gain[0] = 0; - pi->nphy_cal_orig_tx_gain[1] = 0; - } - } - target_gain = wlc_phy_get_tx_gain_nphy(pi); - tx_pwr_ctrl_state = pi->nphy_txpwrctrl; - wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF); - - if (pi->antsel_type == ANTSEL_2x3) - wlc_phy_antsel_init((wlc_phy_t *) pi, true); - - mphase = (pi->mphase_cal_phase_id != MPHASE_CAL_STATE_IDLE); - if (!mphase) { - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - wlc_phy_precal_txgain_nphy(pi); - pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi); - restore_tx_gain = true; - - target_gain = pi->nphy_cal_target_gain; - } - if (BCME_OK == - wlc_phy_cal_txiqlo_nphy(pi, target_gain, fullcal, mphase)) { - if (PHY_IPA(pi)) - wlc_phy_a4(pi, true); - - wlc_phyreg_exit((wlc_phy_t *) pi); - wlapi_enable_mac(pi->sh->physhim); - wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, - 10000); - wlapi_suspend_mac_and_wait(pi->sh->physhim); - wlc_phyreg_enter((wlc_phy_t *) pi); - - if (BCME_OK == wlc_phy_cal_rxiq_nphy(pi, target_gain, - (pi-> - first_cal_after_assoc - || (pi-> - cal_type_override - == - PHY_PERICAL_FULL)) - ? 2 : 0, false)) { - wlc_phy_savecal_nphy(pi); - - wlc_phy_txpwrctrl_coeff_setup_nphy(pi); - - pi->nphy_perical_last = pi->sh->now; - } - } - if (caltype != PHY_PERICAL_AUTO) { - wlc_phy_rssi_cal_nphy(pi); - } - - if (pi->first_cal_after_assoc - || (pi->cal_type_override == PHY_PERICAL_FULL)) { - pi->first_cal_after_assoc = false; - wlc_phy_txpwrctrl_idle_tssi_nphy(pi); - wlc_phy_txpwrctrl_pwr_setup_nphy(pi); - } - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - wlc_phy_radio205x_vcocal_nphy(pi); - } - } else { - ASSERT(pi->nphy_perical >= PHY_PERICAL_MPHASE); - - switch (pi->mphase_cal_phase_id) { - case MPHASE_CAL_STATE_INIT: - pi->nphy_perical_last = pi->sh->now; - pi->nphy_txiqlocal_chanspec = pi->radio_chanspec; - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - wlc_phy_precal_txgain_nphy(pi); - } - pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi); - pi->mphase_cal_phase_id++; - break; - - case MPHASE_CAL_STATE_TXPHASE0: - case MPHASE_CAL_STATE_TXPHASE1: - case MPHASE_CAL_STATE_TXPHASE2: - case MPHASE_CAL_STATE_TXPHASE3: - case MPHASE_CAL_STATE_TXPHASE4: - case MPHASE_CAL_STATE_TXPHASE5: - if ((pi->radar_percal_mask & 0x10) != 0) - pi->nphy_rxcal_active = true; - - if (wlc_phy_cal_txiqlo_nphy - (pi, pi->nphy_cal_target_gain, fullcal, - true) != BCME_OK) { - - wlc_phy_cal_perical_mphase_reset(pi); - break; - } - - if (NREV_LE(pi->pubpi.phy_rev, 2) && - (pi->mphase_cal_phase_id == - MPHASE_CAL_STATE_TXPHASE4)) { - pi->mphase_cal_phase_id += 2; - } else { - pi->mphase_cal_phase_id++; - } - break; - - case MPHASE_CAL_STATE_PAPDCAL: - if ((pi->radar_percal_mask & 0x2) != 0) - pi->nphy_rxcal_active = true; - - if (PHY_IPA(pi)) { - wlc_phy_a4(pi, true); - } - pi->mphase_cal_phase_id++; - break; - - case MPHASE_CAL_STATE_RXCAL: - if ((pi->radar_percal_mask & 0x1) != 0) - pi->nphy_rxcal_active = true; - if (wlc_phy_cal_rxiq_nphy(pi, target_gain, - (pi->first_cal_after_assoc || - (pi->cal_type_override == - PHY_PERICAL_FULL)) ? 2 : 0, - false) == BCME_OK) { - wlc_phy_savecal_nphy(pi); - } - - pi->mphase_cal_phase_id++; - break; - - case MPHASE_CAL_STATE_RSSICAL: - if ((pi->radar_percal_mask & 0x4) != 0) - pi->nphy_rxcal_active = true; - wlc_phy_txpwrctrl_coeff_setup_nphy(pi); - wlc_phy_rssi_cal_nphy(pi); - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - wlc_phy_radio205x_vcocal_nphy(pi); - } - restore_tx_gain = true; - - if (pi->first_cal_after_assoc) { - pi->mphase_cal_phase_id++; - } else { - wlc_phy_cal_perical_mphase_reset(pi); - } - - break; - - case MPHASE_CAL_STATE_IDLETSSI: - if ((pi->radar_percal_mask & 0x8) != 0) - pi->nphy_rxcal_active = true; - - if (pi->first_cal_after_assoc) { - pi->first_cal_after_assoc = false; - wlc_phy_txpwrctrl_idle_tssi_nphy(pi); - wlc_phy_txpwrctrl_pwr_setup_nphy(pi); - } - - wlc_phy_cal_perical_mphase_reset(pi); - break; - - default: - ASSERT(0); - wlc_phy_cal_perical_mphase_reset(pi); - break; - } - } - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if (restore_tx_gain) { - if (tx_pwr_ctrl_state != PHY_TPC_HW_OFF) { - - wlc_phy_txpwr_index_nphy(pi, 1, - pi-> - nphy_cal_orig_pwr_idx - [0], false); - wlc_phy_txpwr_index_nphy(pi, 2, - pi-> - nphy_cal_orig_pwr_idx - [1], false); - - pi->nphy_txpwrindex[0].index = -1; - pi->nphy_txpwrindex[1].index = -1; - } else { - wlc_phy_txpwr_index_nphy(pi, (1 << 0), - (s8) (pi-> - nphy_txpwrindex - [0]. - index_internal), - false); - wlc_phy_txpwr_index_nphy(pi, (1 << 1), - (s8) (pi-> - nphy_txpwrindex - [1]. - index_internal), - false); - } - } - } - - wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state); - wlc_phyreg_exit((wlc_phy_t *) pi); - wlapi_enable_mac(pi->sh->physhim); -} - -int -wlc_phy_cal_txiqlo_nphy(phy_info_t *pi, nphy_txgains_t target_gain, - bool fullcal, bool mphase) -{ - u16 val; - u16 tbl_buf[11]; - u8 cal_cnt; - u16 cal_cmd; - u8 num_cals, max_cal_cmds; - u16 core_no, cal_type; - u16 diq_start = 0; - u8 phy_bw; - u16 max_val; - u16 tone_freq; - u16 gain_save[2]; - u16 cal_gain[2]; - nphy_iqcal_params_t cal_params[2]; - u32 tbl_len; - void *tbl_ptr; - bool ladder_updated[2]; - u8 mphase_cal_lastphase = 0; - int bcmerror = BCME_OK; - bool phyhang_avoid_state = false; - - u16 tbl_tx_iqlo_cal_loft_ladder_20[] = { - 0x0300, 0x0500, 0x0700, 0x0900, 0x0d00, 0x1100, 0x1900, 0x1901, - 0x1902, - 0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x2407, 0x3207, 0x4607, - 0x6407 - }; - - u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = { - 0x0200, 0x0300, 0x0600, 0x0900, 0x0d00, 0x1100, 0x1900, 0x2400, - 0x3200, - 0x4600, 0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406, - 0x6407 - }; - - u16 tbl_tx_iqlo_cal_loft_ladder_40[] = { - 0x0200, 0x0300, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1201, - 0x1202, - 0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1907, 0x2307, 0x3207, - 0x4707 - }; - - u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = { - 0x0100, 0x0200, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1900, - 0x2300, - 0x3200, 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706, - 0x4707 - }; - - u16 tbl_tx_iqlo_cal_startcoefs[] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000 - }; - - u16 tbl_tx_iqlo_cal_cmds_fullcal[] = { - 0x8123, 0x8264, 0x8086, 0x8245, 0x8056, - 0x9123, 0x9264, 0x9086, 0x9245, 0x9056 - }; - - u16 tbl_tx_iqlo_cal_cmds_recal[] = { - 0x8101, 0x8253, 0x8053, 0x8234, 0x8034, - 0x9101, 0x9253, 0x9053, 0x9234, 0x9034 - }; - - u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000 - }; - - u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = { - 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234, - 0x9434, 0x9334, 0x9084, 0x9267, 0x9056, 0x9234 - }; - - u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = { - 0x8423, 0x8323, 0x8073, 0x8256, 0x8045, 0x8223, - 0x9423, 0x9323, 0x9073, 0x9256, 0x9045, 0x9223 - }; - - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - if (NREV_GE(pi->pubpi.phy_rev, 4)) { - phyhang_avoid_state = pi->phyhang_avoid; - pi->phyhang_avoid = false; - } - - if (CHSPEC_IS40(pi->radio_chanspec)) { - phy_bw = 40; - } else { - phy_bw = 20; - } - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save); - - for (core_no = 0; core_no <= 1; core_no++) { - wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain, - &cal_params[core_no]); - cal_gain[core_no] = cal_params[core_no].cal_gain; - } - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain); - - wlc_phy_txcal_radio_setup_nphy(pi); - - wlc_phy_txcal_physetup_nphy(pi); - - ladder_updated[0] = ladder_updated[1] = false; - if (!(NREV_GE(pi->pubpi.phy_rev, 6) || - (NREV_IS(pi->pubpi.phy_rev, 5) && PHY_IPA(pi) - && (CHSPEC_IS2G(pi->radio_chanspec))))) { - - if (phy_bw == 40) { - tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_40; - tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_loft_ladder_40); - } else { - tbl_ptr = tbl_tx_iqlo_cal_loft_ladder_20; - tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_loft_ladder_20); - } - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 0, - 16, tbl_ptr); - - if (phy_bw == 40) { - tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_40; - tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_iqimb_ladder_40); - } else { - tbl_ptr = tbl_tx_iqlo_cal_iqimb_ladder_20; - tbl_len = ARRAY_SIZE(tbl_tx_iqlo_cal_iqimb_ladder_20); - } - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 32, - 16, tbl_ptr); - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - write_phy_reg(pi, 0xc2, 0x8ad9); - } else { - write_phy_reg(pi, 0xc2, 0x8aa9); - } - - max_val = 250; - tone_freq = (phy_bw == 20) ? 2500 : 5000; - - if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) { - wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff, 0, 1, 0, false); - bcmerror = BCME_OK; - } else { - bcmerror = - wlc_phy_tx_tone_nphy(pi, tone_freq, max_val, 1, 0, false); - } - - if (bcmerror == BCME_OK) { - - if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) { - tbl_ptr = pi->mphase_txcal_bestcoeffs; - tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs); - if (NREV_LT(pi->pubpi.phy_rev, 3)) { - - tbl_len -= 2; - } - } else { - if ((!fullcal) && (pi->nphy_txiqlocal_coeffsvalid)) { - - tbl_ptr = pi->nphy_txiqlocal_bestc; - tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc); - if (NREV_LT(pi->pubpi.phy_rev, 3)) { - - tbl_len -= 2; - } - } else { - - fullcal = true; - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - tbl_ptr = - tbl_tx_iqlo_cal_startcoefs_nphyrev3; - tbl_len = - ARRAY_SIZE - (tbl_tx_iqlo_cal_startcoefs_nphyrev3); - } else { - tbl_ptr = tbl_tx_iqlo_cal_startcoefs; - tbl_len = - ARRAY_SIZE - (tbl_tx_iqlo_cal_startcoefs); - } - } - } - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 64, - 16, tbl_ptr); - - if (fullcal) { - max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ? - ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3) : - ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_fullcal); - } else { - max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ? - ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_recal_nphyrev3) : - ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_recal); - } - - if (mphase) { - cal_cnt = pi->mphase_txcal_cmdidx; - if ((cal_cnt + pi->mphase_txcal_numcmds) < max_cal_cmds) { - num_cals = cal_cnt + pi->mphase_txcal_numcmds; - } else { - num_cals = max_cal_cmds; - } - } else { - cal_cnt = 0; - num_cals = max_cal_cmds; - } - - for (; cal_cnt < num_cals; cal_cnt++) { - - if (fullcal) { - cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ? - tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3 - [cal_cnt] : - tbl_tx_iqlo_cal_cmds_fullcal[cal_cnt]; - } else { - cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ? - tbl_tx_iqlo_cal_cmds_recal_nphyrev3[cal_cnt] - : tbl_tx_iqlo_cal_cmds_recal[cal_cnt]; - } - - core_no = ((cal_cmd & 0x3000) >> 12); - cal_type = ((cal_cmd & 0x0F00) >> 8); - - if (NREV_GE(pi->pubpi.phy_rev, 6) || - (NREV_IS(pi->pubpi.phy_rev, 5) && - PHY_IPA(pi) - && (CHSPEC_IS2G(pi->radio_chanspec)))) { - if (!ladder_updated[core_no]) { - wlc_phy_update_txcal_ladder_nphy(pi, - core_no); - ladder_updated[core_no] = true; - } - } - - val = - (cal_params[core_no]. - ncorr[cal_type] << 8) | NPHY_N_GCTL; - write_phy_reg(pi, 0xc1, val); - - if ((cal_type == 1) || (cal_type == 3) - || (cal_type == 4)) { - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, - 1, 69 + core_no, 16, - tbl_buf); - - diq_start = tbl_buf[0]; - - tbl_buf[0] = 0; - wlc_phy_table_write_nphy(pi, - NPHY_TBL_ID_IQLOCAL, 1, - 69 + core_no, 16, - tbl_buf); - } - - write_phy_reg(pi, 0xc0, cal_cmd); - - SPINWAIT(((read_phy_reg(pi, 0xc0) & 0xc000) != 0), - 20000); - ASSERT((read_phy_reg(pi, 0xc0) & 0xc000) == 0); - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, - tbl_len, 96, 16, tbl_buf); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, - tbl_len, 64, 16, tbl_buf); - - if ((cal_type == 1) || (cal_type == 3) - || (cal_type == 4)) { - - tbl_buf[0] = diq_start; - - } - - } - - if (mphase) { - pi->mphase_txcal_cmdidx = num_cals; - if (pi->mphase_txcal_cmdidx >= max_cal_cmds) - pi->mphase_txcal_cmdidx = 0; - } - - mphase_cal_lastphase = - (NREV_LE(pi->pubpi.phy_rev, 2)) ? - MPHASE_CAL_STATE_TXPHASE4 : MPHASE_CAL_STATE_TXPHASE5; - - if (!mphase - || (pi->mphase_cal_phase_id == mphase_cal_lastphase)) { - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 96, - 16, tbl_buf); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80, - 16, tbl_buf); - - if (NREV_LT(pi->pubpi.phy_rev, 2)) { - - tbl_buf[0] = 0; - tbl_buf[1] = 0; - tbl_buf[2] = 0; - tbl_buf[3] = 0; - - } - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88, - 16, tbl_buf); - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 101, - 16, tbl_buf); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85, - 16, tbl_buf); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93, - 16, tbl_buf); - - tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc); - if (NREV_LT(pi->pubpi.phy_rev, 3)) { - - tbl_len -= 2; - } - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, - tbl_len, 96, 16, - pi->nphy_txiqlocal_bestc); - - pi->nphy_txiqlocal_coeffsvalid = true; - pi->nphy_txiqlocal_chanspec = pi->radio_chanspec; - } else { - tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs); - if (NREV_LT(pi->pubpi.phy_rev, 3)) { - - tbl_len -= 2; - } - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, - tbl_len, 96, 16, - pi->mphase_txcal_bestcoeffs); - } - - wlc_phy_stopplayback_nphy(pi); - - write_phy_reg(pi, 0xc2, 0x0000); - - } - - wlc_phy_txcal_phycleanup_nphy(pi); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, - gain_save); - - wlc_phy_txcal_radio_cleanup_nphy(pi); - - if (NREV_LT(pi->pubpi.phy_rev, 2)) { - if (!mphase - || (pi->mphase_cal_phase_id == mphase_cal_lastphase)) - wlc_phy_tx_iq_war_nphy(pi); - } - - if (NREV_GE(pi->pubpi.phy_rev, 4)) { - pi->phyhang_avoid = phyhang_avoid_state; - } - - wlc_phy_stay_in_carriersearch_nphy(pi, false); - - return bcmerror; -} - -static void wlc_phy_reapply_txcal_coeffs_nphy(phy_info_t *pi) -{ - u16 tbl_buf[7]; - - ASSERT(NREV_LT(pi->pubpi.phy_rev, 2)); - - if ((pi->nphy_txiqlocal_chanspec == pi->radio_chanspec) && - (pi->nphy_txiqlocal_coeffsvalid)) { - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, - ARRAY_SIZE(tbl_buf), 80, 16, tbl_buf); - - if ((pi->nphy_txiqlocal_bestc[0] != tbl_buf[0]) || - (pi->nphy_txiqlocal_bestc[1] != tbl_buf[1]) || - (pi->nphy_txiqlocal_bestc[2] != tbl_buf[2]) || - (pi->nphy_txiqlocal_bestc[3] != tbl_buf[3])) { - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80, - 16, pi->nphy_txiqlocal_bestc); - - tbl_buf[0] = 0; - tbl_buf[1] = 0; - tbl_buf[2] = 0; - tbl_buf[3] = 0; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88, - 16, tbl_buf); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85, - 16, - &pi->nphy_txiqlocal_bestc[5]); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93, - 16, - &pi->nphy_txiqlocal_bestc[5]); - } - } -} - -static void wlc_phy_tx_iq_war_nphy(phy_info_t *pi) -{ - nphy_iq_comp_t tx_comp; - - wlc_phy_table_read_nphy(pi, 15, 4, 0x50, 16, (void *)&tx_comp); - - wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ, tx_comp.a0); - wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 2, tx_comp.b0); - wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 4, tx_comp.a1); - wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 6, tx_comp.b1); -} - -void -wlc_phy_rx_iq_coeffs_nphy(phy_info_t *pi, u8 write, nphy_iq_comp_t *pcomp) -{ - if (write) { - write_phy_reg(pi, 0x9a, pcomp->a0); - write_phy_reg(pi, 0x9b, pcomp->b0); - write_phy_reg(pi, 0x9c, pcomp->a1); - write_phy_reg(pi, 0x9d, pcomp->b1); - } else { - pcomp->a0 = read_phy_reg(pi, 0x9a); - pcomp->b0 = read_phy_reg(pi, 0x9b); - pcomp->a1 = read_phy_reg(pi, 0x9c); - pcomp->b1 = read_phy_reg(pi, 0x9d); - } -} - -void -wlc_phy_rx_iq_est_nphy(phy_info_t *pi, phy_iq_est_t *est, u16 num_samps, - u8 wait_time, u8 wait_for_crs) -{ - u8 core; - - write_phy_reg(pi, 0x12b, num_samps); - mod_phy_reg(pi, 0x12a, (0xff << 0), (wait_time << 0)); - mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqMode, - (wait_for_crs) ? NPHY_IqestCmd_iqMode : 0); - - mod_phy_reg(pi, 0x129, NPHY_IqestCmd_iqstart, NPHY_IqestCmd_iqstart); - - SPINWAIT(((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) != 0), - 10000); - ASSERT((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) == 0); - - if ((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) == 0) { - ASSERT(pi->pubpi.phy_corenum <= PHY_CORE_MAX); - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - est[core].i_pwr = - (read_phy_reg(pi, NPHY_IqestipwrAccHi(core)) << 16) - | read_phy_reg(pi, NPHY_IqestipwrAccLo(core)); - est[core].q_pwr = - (read_phy_reg(pi, NPHY_IqestqpwrAccHi(core)) << 16) - | read_phy_reg(pi, NPHY_IqestqpwrAccLo(core)); - est[core].iq_prod = - (read_phy_reg(pi, NPHY_IqestIqAccHi(core)) << 16) | - read_phy_reg(pi, NPHY_IqestIqAccLo(core)); - } - } -} - -#define CAL_RETRY_CNT 2 -static void wlc_phy_calc_rx_iq_comp_nphy(phy_info_t *pi, u8 core_mask) -{ - u8 curr_core; - phy_iq_est_t est[PHY_CORE_MAX]; - nphy_iq_comp_t old_comp, new_comp; - s32 iq = 0; - u32 ii = 0, qq = 0; - s16 iq_nbits, qq_nbits, brsh, arsh; - s32 a, b, temp; - int bcmerror = BCME_OK; - uint cal_retry = 0; - - if (core_mask == 0x0) - return; - - wlc_phy_rx_iq_coeffs_nphy(pi, 0, &old_comp); - new_comp.a0 = new_comp.b0 = new_comp.a1 = new_comp.b1 = 0x0; - wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp); - - cal_try: - wlc_phy_rx_iq_est_nphy(pi, est, 0x4000, 32, 0); - - new_comp = old_comp; - - for (curr_core = 0; curr_core < pi->pubpi.phy_corenum; curr_core++) { - - if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) { - iq = est[curr_core].iq_prod; - ii = est[curr_core].i_pwr; - qq = est[curr_core].q_pwr; - } else if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) { - iq = est[curr_core].iq_prod; - ii = est[curr_core].i_pwr; - qq = est[curr_core].q_pwr; - } else { - continue; - } - - if ((ii + qq) < NPHY_MIN_RXIQ_PWR) { - bcmerror = BCME_ERROR; - break; - } - - iq_nbits = wlc_phy_nbits(iq); - qq_nbits = wlc_phy_nbits(qq); - - arsh = 10 - (30 - iq_nbits); - if (arsh >= 0) { - a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh))); - temp = (s32) (ii >> arsh); - if (temp == 0) { - bcmerror = BCME_ERROR; - break; - } - } else { - a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh))); - temp = (s32) (ii << -arsh); - if (temp == 0) { - bcmerror = BCME_ERROR; - break; - } - } - - a /= temp; - - brsh = qq_nbits - 31 + 20; - if (brsh >= 0) { - b = (qq << (31 - qq_nbits)); - temp = (s32) (ii >> brsh); - if (temp == 0) { - bcmerror = BCME_ERROR; - break; - } - } else { - b = (qq << (31 - qq_nbits)); - temp = (s32) (ii << -brsh); - if (temp == 0) { - bcmerror = BCME_ERROR; - break; - } - } - b /= temp; - b -= a * a; - b = (s32) wlc_phy_sqrt_int((u32) b); - b -= (1 << 10); - - if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) { - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - new_comp.a0 = (s16) a & 0x3ff; - new_comp.b0 = (s16) b & 0x3ff; - } else { - - new_comp.a0 = (s16) b & 0x3ff; - new_comp.b0 = (s16) a & 0x3ff; - } - } - if ((curr_core == PHY_CORE_1) && (core_mask & 0x2)) { - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - new_comp.a1 = (s16) a & 0x3ff; - new_comp.b1 = (s16) b & 0x3ff; - } else { - - new_comp.a1 = (s16) b & 0x3ff; - new_comp.b1 = (s16) a & 0x3ff; - } - } - } - - if (bcmerror != BCME_OK) { - printk("%s: Failed, cnt = %d\n", __func__, cal_retry); - - if (cal_retry < CAL_RETRY_CNT) { - cal_retry++; - goto cal_try; - } - - new_comp = old_comp; - } else if (cal_retry > 0) { - } - - wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp); -} - -static void wlc_phy_rxcal_radio_setup_nphy(phy_info_t *pi, u8 rx_core) -{ - u16 offtune_val; - u16 bias_g = 0; - u16 bias_a = 0; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if (rx_core == PHY_CORE_0) { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - pi->tx_rx_cal_radio_saveregs[0] = - read_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP); - pi->tx_rx_cal_radio_saveregs[1] = - read_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN); - - write_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP, - 0x3); - write_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN, - 0xaf); - - } else { - pi->tx_rx_cal_radio_saveregs[0] = - read_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP); - pi->tx_rx_cal_radio_saveregs[1] = - read_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN); - - write_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP, - 0x3); - write_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN, - 0x7f); - } - - } else { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - pi->tx_rx_cal_radio_saveregs[0] = - read_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP); - pi->tx_rx_cal_radio_saveregs[1] = - read_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN); - - write_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP, - 0x3); - write_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN, - 0xaf); - - } else { - pi->tx_rx_cal_radio_saveregs[0] = - read_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP); - pi->tx_rx_cal_radio_saveregs[1] = - read_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN); - - write_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP, - 0x3); - write_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN, - 0x7f); - } - } - - } else { - if (rx_core == PHY_CORE_0) { - pi->tx_rx_cal_radio_saveregs[0] = - read_radio_reg(pi, - RADIO_2056_TX_RXIQCAL_TXMUX | - RADIO_2056_TX1); - pi->tx_rx_cal_radio_saveregs[1] = - read_radio_reg(pi, - RADIO_2056_RX_RXIQCAL_RXMUX | - RADIO_2056_RX0); - - if (pi->pubpi.radiorev >= 5) { - pi->tx_rx_cal_radio_saveregs[2] = - read_radio_reg(pi, - RADIO_2056_RX_RXSPARE2 | - RADIO_2056_RX0); - pi->tx_rx_cal_radio_saveregs[3] = - read_radio_reg(pi, - RADIO_2056_TX_TXSPARE2 | - RADIO_2056_TX1); - } - - if (CHSPEC_IS5G(pi->radio_chanspec)) { - - if (pi->pubpi.radiorev >= 5) { - pi->tx_rx_cal_radio_saveregs[4] = - read_radio_reg(pi, - RADIO_2056_RX_LNAA_MASTER - | RADIO_2056_RX0); - - write_radio_reg(pi, - RADIO_2056_RX_LNAA_MASTER - | RADIO_2056_RX0, 0x40); - - write_radio_reg(pi, - RADIO_2056_TX_TXSPARE2 | - RADIO_2056_TX1, bias_a); - - write_radio_reg(pi, - RADIO_2056_RX_RXSPARE2 | - RADIO_2056_RX0, bias_a); - } else { - pi->tx_rx_cal_radio_saveregs[4] = - read_radio_reg(pi, - RADIO_2056_RX_LNAA_TUNE - | RADIO_2056_RX0); - - offtune_val = - (pi-> - tx_rx_cal_radio_saveregs[2] & 0xF0) - >> 8; - offtune_val = - (offtune_val <= 0x7) ? 0xF : 0; - - mod_radio_reg(pi, - RADIO_2056_RX_LNAA_TUNE | - RADIO_2056_RX0, 0xF0, - (offtune_val << 8)); - } - - write_radio_reg(pi, - RADIO_2056_TX_RXIQCAL_TXMUX | - RADIO_2056_TX1, 0x9); - write_radio_reg(pi, - RADIO_2056_RX_RXIQCAL_RXMUX | - RADIO_2056_RX0, 0x9); - } else { - if (pi->pubpi.radiorev >= 5) { - pi->tx_rx_cal_radio_saveregs[4] = - read_radio_reg(pi, - RADIO_2056_RX_LNAG_MASTER - | RADIO_2056_RX0); - - write_radio_reg(pi, - RADIO_2056_RX_LNAG_MASTER - | RADIO_2056_RX0, 0x40); - - write_radio_reg(pi, - RADIO_2056_TX_TXSPARE2 | - RADIO_2056_TX1, bias_g); - - write_radio_reg(pi, - RADIO_2056_RX_RXSPARE2 | - RADIO_2056_RX0, bias_g); - - } else { - pi->tx_rx_cal_radio_saveregs[4] = - read_radio_reg(pi, - RADIO_2056_RX_LNAG_TUNE - | RADIO_2056_RX0); - - offtune_val = - (pi-> - tx_rx_cal_radio_saveregs[2] & 0xF0) - >> 8; - offtune_val = - (offtune_val <= 0x7) ? 0xF : 0; - - mod_radio_reg(pi, - RADIO_2056_RX_LNAG_TUNE | - RADIO_2056_RX0, 0xF0, - (offtune_val << 8)); - } - - write_radio_reg(pi, - RADIO_2056_TX_RXIQCAL_TXMUX | - RADIO_2056_TX1, 0x6); - write_radio_reg(pi, - RADIO_2056_RX_RXIQCAL_RXMUX | - RADIO_2056_RX0, 0x6); - } - - } else { - pi->tx_rx_cal_radio_saveregs[0] = - read_radio_reg(pi, - RADIO_2056_TX_RXIQCAL_TXMUX | - RADIO_2056_TX0); - pi->tx_rx_cal_radio_saveregs[1] = - read_radio_reg(pi, - RADIO_2056_RX_RXIQCAL_RXMUX | - RADIO_2056_RX1); - - if (pi->pubpi.radiorev >= 5) { - pi->tx_rx_cal_radio_saveregs[2] = - read_radio_reg(pi, - RADIO_2056_RX_RXSPARE2 | - RADIO_2056_RX1); - pi->tx_rx_cal_radio_saveregs[3] = - read_radio_reg(pi, - RADIO_2056_TX_TXSPARE2 | - RADIO_2056_TX0); - } - - if (CHSPEC_IS5G(pi->radio_chanspec)) { - - if (pi->pubpi.radiorev >= 5) { - pi->tx_rx_cal_radio_saveregs[4] = - read_radio_reg(pi, - RADIO_2056_RX_LNAA_MASTER - | RADIO_2056_RX1); - - write_radio_reg(pi, - RADIO_2056_RX_LNAA_MASTER - | RADIO_2056_RX1, 0x40); - - write_radio_reg(pi, - RADIO_2056_TX_TXSPARE2 | - RADIO_2056_TX0, bias_a); - - write_radio_reg(pi, - RADIO_2056_RX_RXSPARE2 | - RADIO_2056_RX1, bias_a); - } else { - pi->tx_rx_cal_radio_saveregs[4] = - read_radio_reg(pi, - RADIO_2056_RX_LNAA_TUNE - | RADIO_2056_RX1); - - offtune_val = - (pi-> - tx_rx_cal_radio_saveregs[2] & 0xF0) - >> 8; - offtune_val = - (offtune_val <= 0x7) ? 0xF : 0; - - mod_radio_reg(pi, - RADIO_2056_RX_LNAA_TUNE | - RADIO_2056_RX1, 0xF0, - (offtune_val << 8)); - } - - write_radio_reg(pi, - RADIO_2056_TX_RXIQCAL_TXMUX | - RADIO_2056_TX0, 0x9); - write_radio_reg(pi, - RADIO_2056_RX_RXIQCAL_RXMUX | - RADIO_2056_RX1, 0x9); - } else { - if (pi->pubpi.radiorev >= 5) { - pi->tx_rx_cal_radio_saveregs[4] = - read_radio_reg(pi, - RADIO_2056_RX_LNAG_MASTER - | RADIO_2056_RX1); - - write_radio_reg(pi, - RADIO_2056_RX_LNAG_MASTER - | RADIO_2056_RX1, 0x40); - - write_radio_reg(pi, - RADIO_2056_TX_TXSPARE2 | - RADIO_2056_TX0, bias_g); - - write_radio_reg(pi, - RADIO_2056_RX_RXSPARE2 | - RADIO_2056_RX1, bias_g); - } else { - pi->tx_rx_cal_radio_saveregs[4] = - read_radio_reg(pi, - RADIO_2056_RX_LNAG_TUNE - | RADIO_2056_RX1); - - offtune_val = - (pi-> - tx_rx_cal_radio_saveregs[2] & 0xF0) - >> 8; - offtune_val = - (offtune_val <= 0x7) ? 0xF : 0; - - mod_radio_reg(pi, - RADIO_2056_RX_LNAG_TUNE | - RADIO_2056_RX1, 0xF0, - (offtune_val << 8)); - } - - write_radio_reg(pi, - RADIO_2056_TX_RXIQCAL_TXMUX | - RADIO_2056_TX0, 0x6); - write_radio_reg(pi, - RADIO_2056_RX_RXIQCAL_RXMUX | - RADIO_2056_RX1, 0x6); - } - } - } -} - -static void wlc_phy_rxcal_radio_cleanup_nphy(phy_info_t *pi, u8 rx_core) -{ - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if (rx_core == PHY_CORE_0) { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - write_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP, - pi-> - tx_rx_cal_radio_saveregs[0]); - write_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN, - pi-> - tx_rx_cal_radio_saveregs[1]); - - } else { - write_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP, - pi-> - tx_rx_cal_radio_saveregs[0]); - write_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN, - pi-> - tx_rx_cal_radio_saveregs[1]); - } - - } else { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - write_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP, - pi-> - tx_rx_cal_radio_saveregs[0]); - write_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN, - pi-> - tx_rx_cal_radio_saveregs[1]); - - } else { - write_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP, - pi-> - tx_rx_cal_radio_saveregs[0]); - write_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN, - pi-> - tx_rx_cal_radio_saveregs[1]); - } - } - - } else { - if (rx_core == PHY_CORE_0) { - write_radio_reg(pi, - RADIO_2056_TX_RXIQCAL_TXMUX | - RADIO_2056_TX1, - pi->tx_rx_cal_radio_saveregs[0]); - - write_radio_reg(pi, - RADIO_2056_RX_RXIQCAL_RXMUX | - RADIO_2056_RX0, - pi->tx_rx_cal_radio_saveregs[1]); - - if (pi->pubpi.radiorev >= 5) { - write_radio_reg(pi, - RADIO_2056_RX_RXSPARE2 | - RADIO_2056_RX0, - pi-> - tx_rx_cal_radio_saveregs[2]); - - write_radio_reg(pi, - RADIO_2056_TX_TXSPARE2 | - RADIO_2056_TX1, - pi-> - tx_rx_cal_radio_saveregs[3]); - } - - if (CHSPEC_IS5G(pi->radio_chanspec)) { - if (pi->pubpi.radiorev >= 5) { - write_radio_reg(pi, - RADIO_2056_RX_LNAA_MASTER - | RADIO_2056_RX0, - pi-> - tx_rx_cal_radio_saveregs - [4]); - } else { - write_radio_reg(pi, - RADIO_2056_RX_LNAA_TUNE - | RADIO_2056_RX0, - pi-> - tx_rx_cal_radio_saveregs - [4]); - } - } else { - if (pi->pubpi.radiorev >= 5) { - write_radio_reg(pi, - RADIO_2056_RX_LNAG_MASTER - | RADIO_2056_RX0, - pi-> - tx_rx_cal_radio_saveregs - [4]); - } else { - write_radio_reg(pi, - RADIO_2056_RX_LNAG_TUNE - | RADIO_2056_RX0, - pi-> - tx_rx_cal_radio_saveregs - [4]); - } - } - - } else { - write_radio_reg(pi, - RADIO_2056_TX_RXIQCAL_TXMUX | - RADIO_2056_TX0, - pi->tx_rx_cal_radio_saveregs[0]); - - write_radio_reg(pi, - RADIO_2056_RX_RXIQCAL_RXMUX | - RADIO_2056_RX1, - pi->tx_rx_cal_radio_saveregs[1]); - - if (pi->pubpi.radiorev >= 5) { - write_radio_reg(pi, - RADIO_2056_RX_RXSPARE2 | - RADIO_2056_RX1, - pi-> - tx_rx_cal_radio_saveregs[2]); - - write_radio_reg(pi, - RADIO_2056_TX_TXSPARE2 | - RADIO_2056_TX0, - pi-> - tx_rx_cal_radio_saveregs[3]); - } - - if (CHSPEC_IS5G(pi->radio_chanspec)) { - if (pi->pubpi.radiorev >= 5) { - write_radio_reg(pi, - RADIO_2056_RX_LNAA_MASTER - | RADIO_2056_RX1, - pi-> - tx_rx_cal_radio_saveregs - [4]); - } else { - write_radio_reg(pi, - RADIO_2056_RX_LNAA_TUNE - | RADIO_2056_RX1, - pi-> - tx_rx_cal_radio_saveregs - [4]); - } - } else { - if (pi->pubpi.radiorev >= 5) { - write_radio_reg(pi, - RADIO_2056_RX_LNAG_MASTER - | RADIO_2056_RX1, - pi-> - tx_rx_cal_radio_saveregs - [4]); - } else { - write_radio_reg(pi, - RADIO_2056_RX_LNAG_TUNE - | RADIO_2056_RX1, - pi-> - tx_rx_cal_radio_saveregs - [4]); - } - } - } - } -} - -static void wlc_phy_rxcal_physetup_nphy(phy_info_t *pi, u8 rx_core) -{ - u8 tx_core; - u16 rx_antval, tx_antval; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - tx_core = rx_core; - } else { - tx_core = (rx_core == PHY_CORE_0) ? 1 : 0; - } - - pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa2); - pi->tx_rx_cal_phy_saveregs[1] = - read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7); - pi->tx_rx_cal_phy_saveregs[2] = - read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5); - pi->tx_rx_cal_phy_saveregs[3] = read_phy_reg(pi, 0x91); - pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x92); - pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x7a); - pi->tx_rx_cal_phy_saveregs[6] = read_phy_reg(pi, 0x7d); - pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0xe7); - pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0xec); - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - pi->tx_rx_cal_phy_saveregs[11] = read_phy_reg(pi, 0x342); - pi->tx_rx_cal_phy_saveregs[12] = read_phy_reg(pi, 0x343); - pi->tx_rx_cal_phy_saveregs[13] = read_phy_reg(pi, 0x346); - pi->tx_rx_cal_phy_saveregs[14] = read_phy_reg(pi, 0x347); - } - - pi->tx_rx_cal_phy_saveregs[9] = read_phy_reg(pi, 0x297); - pi->tx_rx_cal_phy_saveregs[10] = read_phy_reg(pi, 0x29b); - mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (0) << 0); - - mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (0) << 0); - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0); - - mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << (1 - rx_core)) << 12); - - } else { - - mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12); - mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0); - mod_phy_reg(pi, 0xa2, (0xf << 4), (1 << rx_core) << 4); - mod_phy_reg(pi, 0xa2, (0xf << 8), (1 << rx_core) << 8); - } - - mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7), (0x1 << 2), 0); - mod_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5, - (0x1 << 2), (0x1 << 2)); - if (NREV_LT(pi->pubpi.phy_rev, 7)) { - mod_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7), - (0x1 << 0) | (0x1 << 1), 0); - mod_phy_reg(pi, (rx_core == PHY_CORE_0) ? - 0x8f : 0xa5, - (0x1 << 0) | (0x1 << 1), (0x1 << 0) | (0x1 << 1)); - } - - wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 0, - RADIO_MIMO_CORESEL_CORE1 | - RADIO_MIMO_CORESEL_CORE2); - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), - 0, 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 0, 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 1, 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 1, 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID2); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - if (CHSPEC_IS40(pi->radio_chanspec)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, - (0x1 << 7), - 2, 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - } else { - wlc_phy_rfctrl_override_nphy_rev7(pi, - (0x1 << 7), - 0, 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - } - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), - 0, 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - } else { - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 3, 0); - } - - wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX); - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - wlc_phy_rfctrlintc_override_nphy(pi, - NPHY_RfctrlIntc_override_TRSW, - 0x1, rx_core + 1); - } else { - - if (rx_core == PHY_CORE_0) { - rx_antval = 0x1; - tx_antval = 0x8; - } else { - rx_antval = 0x4; - tx_antval = 0x2; - } - - wlc_phy_rfctrlintc_override_nphy(pi, - NPHY_RfctrlIntc_override_TRSW, - rx_antval, rx_core + 1); - wlc_phy_rfctrlintc_override_nphy(pi, - NPHY_RfctrlIntc_override_TRSW, - tx_antval, tx_core + 1); - } -} - -static void wlc_phy_rxcal_phycleanup_nphy(phy_info_t *pi, u8 rx_core) -{ - - write_phy_reg(pi, 0xa2, pi->tx_rx_cal_phy_saveregs[0]); - write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7, - pi->tx_rx_cal_phy_saveregs[1]); - write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5, - pi->tx_rx_cal_phy_saveregs[2]); - write_phy_reg(pi, 0x91, pi->tx_rx_cal_phy_saveregs[3]); - write_phy_reg(pi, 0x92, pi->tx_rx_cal_phy_saveregs[4]); - - write_phy_reg(pi, 0x7a, pi->tx_rx_cal_phy_saveregs[5]); - write_phy_reg(pi, 0x7d, pi->tx_rx_cal_phy_saveregs[6]); - write_phy_reg(pi, 0xe7, pi->tx_rx_cal_phy_saveregs[7]); - write_phy_reg(pi, 0xec, pi->tx_rx_cal_phy_saveregs[8]); - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - write_phy_reg(pi, 0x342, pi->tx_rx_cal_phy_saveregs[11]); - write_phy_reg(pi, 0x343, pi->tx_rx_cal_phy_saveregs[12]); - write_phy_reg(pi, 0x346, pi->tx_rx_cal_phy_saveregs[13]); - write_phy_reg(pi, 0x347, pi->tx_rx_cal_phy_saveregs[14]); - } - - write_phy_reg(pi, 0x297, pi->tx_rx_cal_phy_saveregs[9]); - write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]); -} - -static void -wlc_phy_rxcal_gainctrl_nphy_rev5(phy_info_t *pi, u8 rx_core, - u16 *rxgain, u8 cal_type) -{ - - u16 num_samps; - phy_iq_est_t est[PHY_CORE_MAX]; - u8 tx_core; - nphy_iq_comp_t save_comp, zero_comp; - u32 i_pwr, q_pwr, curr_pwr, optim_pwr = 0, prev_pwr = 0, thresh_pwr = - 10000; - s16 desired_log2_pwr, actual_log2_pwr, delta_pwr; - bool gainctrl_done = false; - u8 mix_tia_gain = 3; - s8 optim_gaintbl_index = 0, prev_gaintbl_index = 0; - s8 curr_gaintbl_index = 3; - u8 gainctrl_dirn = NPHY_RXCAL_GAIN_INIT; - nphy_ipa_txrxgain_t *nphy_rxcal_gaintbl; - u16 hpvga, lpf_biq1, lpf_biq0, lna2, lna1; - int fine_gain_idx; - s8 txpwrindex; - u16 nphy_rxcal_txgain[2]; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - tx_core = rx_core; - } else { - tx_core = 1 - rx_core; - } - - num_samps = 1024; - desired_log2_pwr = (cal_type == 0) ? 13 : 13; - - wlc_phy_rx_iq_coeffs_nphy(pi, 0, &save_comp); - zero_comp.a0 = zero_comp.b0 = zero_comp.a1 = zero_comp.b1 = 0x0; - wlc_phy_rx_iq_coeffs_nphy(pi, 1, &zero_comp); - - if (CHSPEC_IS5G(pi->radio_chanspec)) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - mix_tia_gain = 3; - } else if (NREV_GE(pi->pubpi.phy_rev, 4)) { - mix_tia_gain = 4; - } else { - mix_tia_gain = 6; - } - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz_rev7; - } else { - nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz; - } - } else { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz_rev7; - } else { - nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz; - } - } - - do { - - hpvga = (NREV_GE(pi->pubpi.phy_rev, 7)) ? - 0 : nphy_rxcal_gaintbl[curr_gaintbl_index].hpvga; - lpf_biq1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq1; - lpf_biq0 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq0; - lna2 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna2; - lna1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna1; - txpwrindex = nphy_rxcal_gaintbl[curr_gaintbl_index].txpwrindex; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_rfctrl_override_1tomany_nphy(pi, - NPHY_REV7_RfctrlOverride_cmd_rxgain, - ((lpf_biq1 << 12) | - (lpf_biq0 << 8) | - (mix_tia_gain << - 4) | (lna2 << 2) - | lna1), 0x3, 0); - } else { - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), - ((hpvga << 12) | - (lpf_biq1 << 10) | - (lpf_biq0 << 8) | - (mix_tia_gain << 4) | - (lna2 << 2) | lna1), 0x3, - 0); - } - - pi->nphy_rxcal_pwr_idx[tx_core] = txpwrindex; - - if (txpwrindex == -1) { - nphy_rxcal_txgain[0] = 0x8ff0 | pi->nphy_gmval; - nphy_rxcal_txgain[1] = 0x8ff0 | pi->nphy_gmval; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 2, 0x110, 16, - nphy_rxcal_txgain); - } else { - wlc_phy_txpwr_index_nphy(pi, tx_core + 1, txpwrindex, - false); - } - - wlc_phy_tx_tone_nphy(pi, (CHSPEC_IS40(pi->radio_chanspec)) ? - NPHY_RXCAL_TONEFREQ_40MHz : - NPHY_RXCAL_TONEFREQ_20MHz, - NPHY_RXCAL_TONEAMP, 0, cal_type, false); - - wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0); - i_pwr = (est[rx_core].i_pwr + num_samps / 2) / num_samps; - q_pwr = (est[rx_core].q_pwr + num_samps / 2) / num_samps; - curr_pwr = i_pwr + q_pwr; - - switch (gainctrl_dirn) { - case NPHY_RXCAL_GAIN_INIT: - if (curr_pwr > thresh_pwr) { - gainctrl_dirn = NPHY_RXCAL_GAIN_DOWN; - prev_gaintbl_index = curr_gaintbl_index; - curr_gaintbl_index--; - } else { - gainctrl_dirn = NPHY_RXCAL_GAIN_UP; - prev_gaintbl_index = curr_gaintbl_index; - curr_gaintbl_index++; - } - break; - - case NPHY_RXCAL_GAIN_UP: - if (curr_pwr > thresh_pwr) { - gainctrl_done = true; - optim_pwr = prev_pwr; - optim_gaintbl_index = prev_gaintbl_index; - } else { - prev_gaintbl_index = curr_gaintbl_index; - curr_gaintbl_index++; - } - break; - - case NPHY_RXCAL_GAIN_DOWN: - if (curr_pwr > thresh_pwr) { - prev_gaintbl_index = curr_gaintbl_index; - curr_gaintbl_index--; - } else { - gainctrl_done = true; - optim_pwr = curr_pwr; - optim_gaintbl_index = curr_gaintbl_index; - } - break; - - default: - ASSERT(0); - } - - if ((curr_gaintbl_index < 0) || - (curr_gaintbl_index > NPHY_IPA_RXCAL_MAXGAININDEX)) { - gainctrl_done = true; - optim_pwr = curr_pwr; - optim_gaintbl_index = prev_gaintbl_index; - } else { - prev_pwr = curr_pwr; - } - - wlc_phy_stopplayback_nphy(pi); - } while (!gainctrl_done); - - hpvga = nphy_rxcal_gaintbl[optim_gaintbl_index].hpvga; - lpf_biq1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq1; - lpf_biq0 = nphy_rxcal_gaintbl[optim_gaintbl_index].lpf_biq0; - lna2 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna2; - lna1 = nphy_rxcal_gaintbl[optim_gaintbl_index].lna1; - txpwrindex = nphy_rxcal_gaintbl[optim_gaintbl_index].txpwrindex; - - actual_log2_pwr = wlc_phy_nbits(optim_pwr); - delta_pwr = desired_log2_pwr - actual_log2_pwr; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - fine_gain_idx = (int)lpf_biq1 + delta_pwr; - - if (fine_gain_idx + (int)lpf_biq0 > 10) { - lpf_biq1 = 10 - lpf_biq0; - } else { - lpf_biq1 = (u16) max(fine_gain_idx, 0); - } - wlc_phy_rfctrl_override_1tomany_nphy(pi, - NPHY_REV7_RfctrlOverride_cmd_rxgain, - ((lpf_biq1 << 12) | - (lpf_biq0 << 8) | - (mix_tia_gain << 4) | - (lna2 << 2) | lna1), 0x3, - 0); - } else { - hpvga = (u16) max(min(((int)hpvga) + delta_pwr, 10), 0); - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), - ((hpvga << 12) | (lpf_biq1 << 10) | - (lpf_biq0 << 8) | (mix_tia_gain << - 4) | (lna2 << - 2) | - lna1), 0x3, 0); - - } - - if (rxgain != NULL) { - *rxgain++ = lna1; - *rxgain++ = lna2; - *rxgain++ = mix_tia_gain; - *rxgain++ = lpf_biq0; - *rxgain++ = lpf_biq1; - *rxgain = hpvga; - } - - wlc_phy_rx_iq_coeffs_nphy(pi, 1, &save_comp); -} - -static void -wlc_phy_rxcal_gainctrl_nphy(phy_info_t *pi, u8 rx_core, u16 *rxgain, - u8 cal_type) -{ - wlc_phy_rxcal_gainctrl_nphy_rev5(pi, rx_core, rxgain, cal_type); -} - -static u8 -wlc_phy_rc_sweep_nphy(phy_info_t *pi, u8 core_idx, u8 loopback_type) -{ - u32 target_bws[2] = { 9500, 21000 }; - u32 ref_tones[2] = { 3000, 6000 }; - u32 target_bw, ref_tone; - - u32 target_pwr_ratios[2] = { 28606, 18468 }; - u32 target_pwr_ratio, pwr_ratio, last_pwr_ratio = 0; - - u16 start_rccal_ovr_val = 128; - u16 txlpf_rccal_lpc_ovr_val = 128; - u16 rxlpf_rccal_hpc_ovr_val = 159; - - u16 orig_txlpf_rccal_lpc_ovr_val; - u16 orig_rxlpf_rccal_hpc_ovr_val; - u16 radio_addr_offset_rx; - u16 radio_addr_offset_tx; - u16 orig_dcBypass; - u16 orig_RxStrnFilt40Num[6]; - u16 orig_RxStrnFilt40Den[4]; - u16 orig_rfctrloverride[2]; - u16 orig_rfctrlauxreg[2]; - u16 orig_rfctrlrssiothers; - u16 tx_lpf_bw = 4; - - u16 rx_lpf_bw, rx_lpf_bws[2] = { 2, 4 }; - u16 lpf_hpc = 7, hpvga_hpc = 7; - - s8 rccal_stepsize; - u16 rccal_val, last_rccal_val = 0, best_rccal_val = 0; - u32 ref_iq_vals = 0, target_iq_vals = 0; - u16 num_samps, log_num_samps = 10; - phy_iq_est_t est[PHY_CORE_MAX]; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - return 0; - } - - num_samps = (1 << log_num_samps); - - if (CHSPEC_IS40(pi->radio_chanspec)) { - target_bw = target_bws[1]; - target_pwr_ratio = target_pwr_ratios[1]; - ref_tone = ref_tones[1]; - rx_lpf_bw = rx_lpf_bws[1]; - } else { - target_bw = target_bws[0]; - target_pwr_ratio = target_pwr_ratios[0]; - ref_tone = ref_tones[0]; - rx_lpf_bw = rx_lpf_bws[0]; - } - - if (core_idx == 0) { - radio_addr_offset_rx = RADIO_2056_RX0; - radio_addr_offset_tx = - (loopback_type == 0) ? RADIO_2056_TX0 : RADIO_2056_TX1; - } else { - radio_addr_offset_rx = RADIO_2056_RX1; - radio_addr_offset_tx = - (loopback_type == 0) ? RADIO_2056_TX1 : RADIO_2056_TX0; - } - - orig_txlpf_rccal_lpc_ovr_val = - read_radio_reg(pi, - (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx)); - orig_rxlpf_rccal_hpc_ovr_val = - read_radio_reg(pi, - (RADIO_2056_RX_RXLPF_RCCAL_HPC | - radio_addr_offset_rx)); - - orig_dcBypass = ((read_phy_reg(pi, 0x48) >> 8) & 1); - - orig_RxStrnFilt40Num[0] = read_phy_reg(pi, 0x267); - orig_RxStrnFilt40Num[1] = read_phy_reg(pi, 0x268); - orig_RxStrnFilt40Num[2] = read_phy_reg(pi, 0x269); - orig_RxStrnFilt40Den[0] = read_phy_reg(pi, 0x26a); - orig_RxStrnFilt40Den[1] = read_phy_reg(pi, 0x26b); - orig_RxStrnFilt40Num[3] = read_phy_reg(pi, 0x26c); - orig_RxStrnFilt40Num[4] = read_phy_reg(pi, 0x26d); - orig_RxStrnFilt40Num[5] = read_phy_reg(pi, 0x26e); - orig_RxStrnFilt40Den[2] = read_phy_reg(pi, 0x26f); - orig_RxStrnFilt40Den[3] = read_phy_reg(pi, 0x270); - - orig_rfctrloverride[0] = read_phy_reg(pi, 0xe7); - orig_rfctrloverride[1] = read_phy_reg(pi, 0xec); - orig_rfctrlauxreg[0] = read_phy_reg(pi, 0xf8); - orig_rfctrlauxreg[1] = read_phy_reg(pi, 0xfa); - orig_rfctrlrssiothers = read_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d); - - write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx), - txlpf_rccal_lpc_ovr_val); - - write_radio_reg(pi, - (RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx), - rxlpf_rccal_hpc_ovr_val); - - mod_phy_reg(pi, 0x48, (0x1 << 8), (0x1 << 8)); - - write_phy_reg(pi, 0x267, 0x02d4); - write_phy_reg(pi, 0x268, 0x0000); - write_phy_reg(pi, 0x269, 0x0000); - write_phy_reg(pi, 0x26a, 0x0000); - write_phy_reg(pi, 0x26b, 0x0000); - write_phy_reg(pi, 0x26c, 0x02d4); - write_phy_reg(pi, 0x26d, 0x0000); - write_phy_reg(pi, 0x26e, 0x0000); - write_phy_reg(pi, 0x26f, 0x0000); - write_phy_reg(pi, 0x270, 0x0000); - - or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 8)); - or_phy_reg(pi, (core_idx == 0) ? 0xec : 0xe7, (0x1 << 15)); - or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 9)); - or_phy_reg(pi, (core_idx == 0) ? 0xe7 : 0xec, (0x1 << 10)); - - mod_phy_reg(pi, (core_idx == 0) ? 0xfa : 0xf8, - (0x7 << 10), (tx_lpf_bw << 10)); - mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa, - (0x7 << 0), (hpvga_hpc << 0)); - mod_phy_reg(pi, (core_idx == 0) ? 0xf8 : 0xfa, - (0x7 << 4), (lpf_hpc << 4)); - mod_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d, - (0x7 << 8), (rx_lpf_bw << 8)); - - rccal_stepsize = 16; - rccal_val = start_rccal_ovr_val + rccal_stepsize; - - while (rccal_stepsize >= 0) { - write_radio_reg(pi, - (RADIO_2056_RX_RXLPF_RCCAL_LPC | - radio_addr_offset_rx), rccal_val); - - if (rccal_stepsize == 16) { - - wlc_phy_tx_tone_nphy(pi, ref_tone, NPHY_RXCAL_TONEAMP, - 0, 1, false); - udelay(2); - - wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0); - - if (core_idx == 0) { - ref_iq_vals = - max_t(u32, (est[0].i_pwr + - est[0].q_pwr) >> (log_num_samps + 1), - 1); - } else { - ref_iq_vals = - max_t(u32, (est[1].i_pwr + - est[1].q_pwr) >> (log_num_samps + 1), - 1); - } - - wlc_phy_tx_tone_nphy(pi, target_bw, NPHY_RXCAL_TONEAMP, - 0, 1, false); - udelay(2); - } - - wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0); - - if (core_idx == 0) { - target_iq_vals = - (est[0].i_pwr + est[0].q_pwr) >> (log_num_samps + - 1); - } else { - target_iq_vals = - (est[1].i_pwr + est[1].q_pwr) >> (log_num_samps + - 1); - } - pwr_ratio = (uint) ((target_iq_vals << 16) / ref_iq_vals); - - if (rccal_stepsize == 0) { - rccal_stepsize--; - } else if (rccal_stepsize == 1) { - last_rccal_val = rccal_val; - rccal_val += (pwr_ratio > target_pwr_ratio) ? 1 : -1; - last_pwr_ratio = pwr_ratio; - rccal_stepsize--; - } else { - rccal_stepsize = (rccal_stepsize >> 1); - rccal_val += ((pwr_ratio > target_pwr_ratio) ? - rccal_stepsize : (-rccal_stepsize)); - } - - if (rccal_stepsize == -1) { - best_rccal_val = - (ABS((int)last_pwr_ratio - (int)target_pwr_ratio) < - ABS((int)pwr_ratio - - (int)target_pwr_ratio)) ? last_rccal_val : - rccal_val; - - if (CHSPEC_IS40(pi->radio_chanspec)) { - if ((best_rccal_val > 140) - || (best_rccal_val < 135)) { - best_rccal_val = 138; - } - } else { - if ((best_rccal_val > 142) - || (best_rccal_val < 137)) { - best_rccal_val = 140; - } - } - - write_radio_reg(pi, - (RADIO_2056_RX_RXLPF_RCCAL_LPC | - radio_addr_offset_rx), best_rccal_val); - } - } - - wlc_phy_stopplayback_nphy(pi); - - write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx), - orig_txlpf_rccal_lpc_ovr_val); - write_radio_reg(pi, - (RADIO_2056_RX_RXLPF_RCCAL_HPC | radio_addr_offset_rx), - orig_rxlpf_rccal_hpc_ovr_val); - - mod_phy_reg(pi, 0x48, (0x1 << 8), (orig_dcBypass << 8)); - - write_phy_reg(pi, 0x267, orig_RxStrnFilt40Num[0]); - write_phy_reg(pi, 0x268, orig_RxStrnFilt40Num[1]); - write_phy_reg(pi, 0x269, orig_RxStrnFilt40Num[2]); - write_phy_reg(pi, 0x26a, orig_RxStrnFilt40Den[0]); - write_phy_reg(pi, 0x26b, orig_RxStrnFilt40Den[1]); - write_phy_reg(pi, 0x26c, orig_RxStrnFilt40Num[3]); - write_phy_reg(pi, 0x26d, orig_RxStrnFilt40Num[4]); - write_phy_reg(pi, 0x26e, orig_RxStrnFilt40Num[5]); - write_phy_reg(pi, 0x26f, orig_RxStrnFilt40Den[2]); - write_phy_reg(pi, 0x270, orig_RxStrnFilt40Den[3]); - - write_phy_reg(pi, 0xe7, orig_rfctrloverride[0]); - write_phy_reg(pi, 0xec, orig_rfctrloverride[1]); - write_phy_reg(pi, 0xf8, orig_rfctrlauxreg[0]); - write_phy_reg(pi, 0xfa, orig_rfctrlauxreg[1]); - write_phy_reg(pi, (core_idx == 0) ? 0x7a : 0x7d, orig_rfctrlrssiothers); - - pi->nphy_anarxlpf_adjusted = false; - - return best_rccal_val - 0x80; -} - -#define WAIT_FOR_SCOPE 4000 -static int -wlc_phy_cal_rxiq_nphy_rev3(phy_info_t *pi, nphy_txgains_t target_gain, - u8 cal_type, bool debug) -{ - u16 orig_BBConfig; - u8 core_no, rx_core; - u8 best_rccal[2]; - u16 gain_save[2]; - u16 cal_gain[2]; - nphy_iqcal_params_t cal_params[2]; - u8 rxcore_state; - s8 rxlpf_rccal_hpc, txlpf_rccal_lpc; - s8 txlpf_idac; - bool phyhang_avoid_state = false; - bool skip_rxiqcal = false; - - orig_BBConfig = read_phy_reg(pi, 0x01); - mod_phy_reg(pi, 0x01, (0x1 << 15), 0); - - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - if (NREV_GE(pi->pubpi.phy_rev, 4)) { - phyhang_avoid_state = pi->phyhang_avoid; - pi->phyhang_avoid = false; - } - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save); - - for (core_no = 0; core_no <= 1; core_no++) { - wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain, - &cal_params[core_no]); - cal_gain[core_no] = cal_params[core_no].cal_gain; - } - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain); - - rxcore_state = wlc_phy_rxcore_getstate_nphy((wlc_phy_t *) pi); - - for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) { - - skip_rxiqcal = - ((rxcore_state & (1 << rx_core)) == 0) ? true : false; - - wlc_phy_rxcal_physetup_nphy(pi, rx_core); - - wlc_phy_rxcal_radio_setup_nphy(pi, rx_core); - - if ((!skip_rxiqcal) && ((cal_type == 0) || (cal_type == 2))) { - - wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL, 0); - - wlc_phy_tx_tone_nphy(pi, - (CHSPEC_IS40(pi->radio_chanspec)) ? - NPHY_RXCAL_TONEFREQ_40MHz : - NPHY_RXCAL_TONEFREQ_20MHz, - NPHY_RXCAL_TONEAMP, 0, cal_type, - false); - - if (debug) - mdelay(WAIT_FOR_SCOPE); - - wlc_phy_calc_rx_iq_comp_nphy(pi, rx_core + 1); - wlc_phy_stopplayback_nphy(pi); - } - - if (((cal_type == 1) || (cal_type == 2)) - && NREV_LT(pi->pubpi.phy_rev, 7)) { - - if (rx_core == PHY_CORE_1) { - - if (rxcore_state == 1) { - wlc_phy_rxcore_setstate_nphy((wlc_phy_t - *) pi, 3); - } - - wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL, - 1); - - best_rccal[rx_core] = - wlc_phy_rc_sweep_nphy(pi, rx_core, 1); - pi->nphy_rccal_value = best_rccal[rx_core]; - - if (rxcore_state == 1) { - wlc_phy_rxcore_setstate_nphy((wlc_phy_t - *) pi, - rxcore_state); - } - } - } - - wlc_phy_rxcal_radio_cleanup_nphy(pi, rx_core); - - wlc_phy_rxcal_phycleanup_nphy(pi, rx_core); - wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); - } - - if ((cal_type == 1) || (cal_type == 2)) { - - best_rccal[0] = best_rccal[1]; - write_radio_reg(pi, - (RADIO_2056_RX_RXLPF_RCCAL_LPC | - RADIO_2056_RX0), (best_rccal[0] | 0x80)); - - for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) { - rxlpf_rccal_hpc = - (((int)best_rccal[rx_core] - 12) >> 1) + 10; - txlpf_rccal_lpc = ((int)best_rccal[rx_core] - 12) + 10; - - if (PHY_IPA(pi)) { - txlpf_rccal_lpc += IS40MHZ(pi) ? 24 : 12; - txlpf_idac = IS40MHZ(pi) ? 0x0e : 0x13; - WRITE_RADIO_REG2(pi, RADIO_2056, TX, rx_core, - TXLPF_IDAC_4, txlpf_idac); - } - - rxlpf_rccal_hpc = max(min_t(u8, rxlpf_rccal_hpc, 31), 0); - txlpf_rccal_lpc = max(min_t(u8, txlpf_rccal_lpc, 31), 0); - - write_radio_reg(pi, (RADIO_2056_RX_RXLPF_RCCAL_HPC | - ((rx_core == - PHY_CORE_0) ? RADIO_2056_RX0 : - RADIO_2056_RX1)), - (rxlpf_rccal_hpc | 0x80)); - - write_radio_reg(pi, (RADIO_2056_TX_TXLPF_RCCAL | - ((rx_core == - PHY_CORE_0) ? RADIO_2056_TX0 : - RADIO_2056_TX1)), - (txlpf_rccal_lpc | 0x80)); - } - } - - write_phy_reg(pi, 0x01, orig_BBConfig); - - wlc_phy_resetcca_nphy(pi); - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_rfctrl_override_1tomany_nphy(pi, - NPHY_REV7_RfctrlOverride_cmd_rxgain, - 0, 0x3, 1); - } else { - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1); - } - wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, - gain_save); - - if (NREV_GE(pi->pubpi.phy_rev, 4)) { - pi->phyhang_avoid = phyhang_avoid_state; - } - - wlc_phy_stay_in_carriersearch_nphy(pi, false); - - return BCME_OK; -} - -static int -wlc_phy_cal_rxiq_nphy_rev2(phy_info_t *pi, nphy_txgains_t target_gain, - bool debug) -{ - phy_iq_est_t est[PHY_CORE_MAX]; - u8 core_num, rx_core, tx_core; - u16 lna_vals[] = { 0x3, 0x3, 0x1 }; - u16 hpf1_vals[] = { 0x7, 0x2, 0x0 }; - u16 hpf2_vals[] = { 0x2, 0x0, 0x0 }; - s16 curr_hpf1, curr_hpf2, curr_hpf, curr_lna; - s16 desired_log2_pwr, actual_log2_pwr, hpf_change; - u16 orig_RfseqCoreActv, orig_AfectrlCore, orig_AfectrlOverride; - u16 orig_RfctrlIntcRx, orig_RfctrlIntcTx; - u16 num_samps; - u32 i_pwr, q_pwr, tot_pwr[3]; - u8 gain_pass, use_hpf_num; - u16 mask, val1, val2; - u16 core_no; - u16 gain_save[2]; - u16 cal_gain[2]; - nphy_iqcal_params_t cal_params[2]; - u8 phy_bw; - int bcmerror = BCME_OK; - bool first_playtone = true; - - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - if (NREV_LT(pi->pubpi.phy_rev, 2)) { - - wlc_phy_reapply_txcal_coeffs_nphy(pi); - } - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save); - - for (core_no = 0; core_no <= 1; core_no++) { - wlc_phy_iqcal_gainparams_nphy(pi, core_no, target_gain, - &cal_params[core_no]); - cal_gain[core_no] = cal_params[core_no].cal_gain; - } - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain); - - num_samps = 1024; - desired_log2_pwr = 13; - - for (core_num = 0; core_num < 2; core_num++) { - - rx_core = core_num; - tx_core = 1 - core_num; - - orig_RfseqCoreActv = read_phy_reg(pi, 0xa2); - orig_AfectrlCore = read_phy_reg(pi, (rx_core == PHY_CORE_0) ? - 0xa6 : 0xa7); - orig_AfectrlOverride = read_phy_reg(pi, 0xa5); - orig_RfctrlIntcRx = read_phy_reg(pi, (rx_core == PHY_CORE_0) ? - 0x91 : 0x92); - orig_RfctrlIntcTx = read_phy_reg(pi, (tx_core == PHY_CORE_0) ? - 0x91 : 0x92); - - mod_phy_reg(pi, 0xa2, (0xf << 12), (1 << tx_core) << 12); - mod_phy_reg(pi, 0xa2, (0xf << 0), (1 << tx_core) << 0); - - or_phy_reg(pi, ((rx_core == PHY_CORE_0) ? 0xa6 : 0xa7), - ((0x1 << 1) | (0x1 << 2))); - or_phy_reg(pi, 0xa5, ((0x1 << 1) | (0x1 << 2))); - - if (((pi->nphy_rxcalparams) & 0xff000000)) { - - write_phy_reg(pi, - (rx_core == PHY_CORE_0) ? 0x91 : 0x92, - (CHSPEC_IS5G(pi->radio_chanspec) ? 0x140 : - 0x110)); - } else { - - write_phy_reg(pi, - (rx_core == PHY_CORE_0) ? 0x91 : 0x92, - (CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : - 0x120)); - } - - write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 : 0x92, - (CHSPEC_IS5G(pi->radio_chanspec) ? 0x148 : - 0x114)); - - mask = RADIO_2055_COUPLE_RX_MASK | RADIO_2055_COUPLE_TX_MASK; - if (rx_core == PHY_CORE_0) { - val1 = RADIO_2055_COUPLE_RX_MASK; - val2 = RADIO_2055_COUPLE_TX_MASK; - } else { - val1 = RADIO_2055_COUPLE_TX_MASK; - val2 = RADIO_2055_COUPLE_RX_MASK; - } - - if ((pi->nphy_rxcalparams & 0x10000)) { - mod_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, mask, - val1); - mod_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, mask, - val2); - } - - for (gain_pass = 0; gain_pass < 4; gain_pass++) { - - if (debug) - mdelay(WAIT_FOR_SCOPE); - - if (gain_pass < 3) { - curr_lna = lna_vals[gain_pass]; - curr_hpf1 = hpf1_vals[gain_pass]; - curr_hpf2 = hpf2_vals[gain_pass]; - } else { - - if (tot_pwr[1] > 10000) { - curr_lna = lna_vals[2]; - curr_hpf1 = hpf1_vals[2]; - curr_hpf2 = hpf2_vals[2]; - use_hpf_num = 1; - curr_hpf = curr_hpf1; - actual_log2_pwr = - wlc_phy_nbits(tot_pwr[2]); - } else { - if (tot_pwr[0] > 10000) { - curr_lna = lna_vals[1]; - curr_hpf1 = hpf1_vals[1]; - curr_hpf2 = hpf2_vals[1]; - use_hpf_num = 1; - curr_hpf = curr_hpf1; - actual_log2_pwr = - wlc_phy_nbits(tot_pwr[1]); - } else { - curr_lna = lna_vals[0]; - curr_hpf1 = hpf1_vals[0]; - curr_hpf2 = hpf2_vals[0]; - use_hpf_num = 2; - curr_hpf = curr_hpf2; - actual_log2_pwr = - wlc_phy_nbits(tot_pwr[0]); - } - } - - hpf_change = desired_log2_pwr - actual_log2_pwr; - curr_hpf += hpf_change; - curr_hpf = max(min_t(u16, curr_hpf, 10), 0); - if (use_hpf_num == 1) { - curr_hpf1 = curr_hpf; - } else { - curr_hpf2 = curr_hpf; - } - } - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10), - ((curr_hpf2 << 8) | - (curr_hpf1 << 4) | - (curr_lna << 2)), 0x3, 0); - wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); - - wlc_phy_stopplayback_nphy(pi); - - if (first_playtone) { - bcmerror = wlc_phy_tx_tone_nphy(pi, 4000, - (u16) (pi-> - nphy_rxcalparams - & - 0xffff), - 0, 0, true); - first_playtone = false; - } else { - phy_bw = - (CHSPEC_IS40(pi->radio_chanspec)) ? 40 : 20; - wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff, - 0, 0, 0, true); - } - - if (bcmerror == BCME_OK) { - if (gain_pass < 3) { - - wlc_phy_rx_iq_est_nphy(pi, est, - num_samps, 32, - 0); - i_pwr = - (est[rx_core].i_pwr + - num_samps / 2) / num_samps; - q_pwr = - (est[rx_core].q_pwr + - num_samps / 2) / num_samps; - tot_pwr[gain_pass] = i_pwr + q_pwr; - } else { - - wlc_phy_calc_rx_iq_comp_nphy(pi, - (1 << - rx_core)); - } - - wlc_phy_stopplayback_nphy(pi); - } - - if (bcmerror != BCME_OK) - break; - } - - and_radio_reg(pi, RADIO_2055_CORE1_GEN_SPARE2, ~mask); - and_radio_reg(pi, RADIO_2055_CORE2_GEN_SPARE2, ~mask); - - write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 : - 0x92, orig_RfctrlIntcTx); - write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x91 : - 0x92, orig_RfctrlIntcRx); - write_phy_reg(pi, 0xa5, orig_AfectrlOverride); - write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : - 0xa7, orig_AfectrlCore); - write_phy_reg(pi, 0xa2, orig_RfseqCoreActv); - - if (bcmerror != BCME_OK) - break; - } - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10), 0, 0x3, 1); - wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, - gain_save); - - wlc_phy_stay_in_carriersearch_nphy(pi, false); - - return bcmerror; -} - -int -wlc_phy_cal_rxiq_nphy(phy_info_t *pi, nphy_txgains_t target_gain, - u8 cal_type, bool debug) -{ - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - cal_type = 0; - } - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - return wlc_phy_cal_rxiq_nphy_rev3(pi, target_gain, cal_type, - debug); - } else { - return wlc_phy_cal_rxiq_nphy_rev2(pi, target_gain, debug); - } -} - -static void wlc_phy_extpa_set_tx_digi_filts_nphy(phy_info_t *pi) -{ - int j, type = 2; - u16 addr_offset = 0x2c5; - - for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { - write_phy_reg(pi, addr_offset + j, - NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]); - } -} - -static void wlc_phy_ipa_set_tx_digi_filts_nphy(phy_info_t *pi) -{ - int j, type; - u16 addr_offset[] = { 0x186, 0x195, - 0x2c5 - }; - - for (type = 0; type < 3; type++) { - for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { - write_phy_reg(pi, addr_offset[type] + j, - NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]); - } - } - - if (IS40MHZ(pi)) { - for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { - write_phy_reg(pi, 0x186 + j, - NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]); - } - } else { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { - write_phy_reg(pi, 0x186 + j, - NPHY_IPA_REV4_txdigi_filtcoeffs[5] - [j]); - } - } - - if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) { - for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { - write_phy_reg(pi, 0x2c5 + j, - NPHY_IPA_REV4_txdigi_filtcoeffs[6] - [j]); - } - } - } -} - -static void wlc_phy_ipa_restore_tx_digi_filts_nphy(phy_info_t *pi) -{ - int j; - - if (IS40MHZ(pi)) { - for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { - write_phy_reg(pi, 0x195 + j, - NPHY_IPA_REV4_txdigi_filtcoeffs[4][j]); - } - } else { - for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { - write_phy_reg(pi, 0x186 + j, - NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]); - } - } -} - -static u16 wlc_phy_ipa_get_bbmult_nphy(phy_info_t *pi) -{ - u16 m0m1; - - wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1); - - return m0m1; -} - -static void wlc_phy_ipa_set_bbmult_nphy(phy_info_t *pi, u8 m0, u8 m1) -{ - u16 m0m1 = (u16) ((m0 << 8) | m1); - - wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m0m1); - wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &m0m1); -} - -static u32 *wlc_phy_get_ipa_gaintbl_nphy(phy_info_t *pi) -{ - u32 *tx_pwrctrl_tbl = NULL; - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - if ((pi->pubpi.radiorev == 4) - || (pi->pubpi.radiorev == 6)) { - - tx_pwrctrl_tbl = - nphy_tpc_txgain_ipa_2g_2057rev4n6; - } else if (pi->pubpi.radiorev == 3) { - - tx_pwrctrl_tbl = - nphy_tpc_txgain_ipa_2g_2057rev3; - } else if (pi->pubpi.radiorev == 5) { - - tx_pwrctrl_tbl = - nphy_tpc_txgain_ipa_2g_2057rev5; - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - - tx_pwrctrl_tbl = - nphy_tpc_txgain_ipa_2g_2057rev7; - } else { - ASSERT(0); - } - - } else if (NREV_IS(pi->pubpi.phy_rev, 6)) { - - tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev6; - if (pi->sh->chip == BCM47162_CHIP_ID) { - - tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5; - } - - } else if (NREV_IS(pi->pubpi.phy_rev, 5)) { - - tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5; - } else { - - tx_pwrctrl_tbl = nphy_tpc_txgain_ipa; - } - - } else { - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if ((pi->pubpi.radiorev == 3) || - (pi->pubpi.radiorev == 4) || - (pi->pubpi.radiorev == 6)) { - - tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g_2057; - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - - tx_pwrctrl_tbl = - nphy_tpc_txgain_ipa_5g_2057rev7; - } else { - ASSERT(0); - } - - } else { - tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g; - } - } - - return tx_pwrctrl_tbl; -} - -static void -wlc_phy_papd_cal_setup_nphy(phy_info_t *pi, nphy_papd_restore_state *state, - u8 core) -{ - s32 tone_freq; - u8 off_core; - u16 mixgain = 0; - - off_core = core ^ 0x1; - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - if (NREV_IS(pi->pubpi.phy_rev, 7) - || NREV_GE(pi->pubpi.phy_rev, 8)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), - wlc_phy_read_lpf_bw_ctl_nphy - (pi, 0), 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - } - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (pi->pubpi.radiorev == 5) { - mixgain = (core == 0) ? 0x20 : 0x00; - - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - - mixgain = 0x00; - - } else if ((pi->pubpi.radiorev <= 4) - || (pi->pubpi.radiorev == 6)) { - - mixgain = 0x00; - } else { - ASSERT(0); - } - - } else { - if ((pi->pubpi.radiorev == 4) || - (pi->pubpi.radiorev == 6)) { - - mixgain = 0x50; - } else if ((pi->pubpi.radiorev == 3) - || (pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - - mixgain = 0x0; - } else { - ASSERT(0); - } - } - - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), - mixgain, (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - - wlc_phy_rfctrl_override_1tomany_nphy(pi, - NPHY_REV7_RfctrlOverride_cmd_tx_pu, - 1, (1 << core), 0); - wlc_phy_rfctrl_override_1tomany_nphy(pi, - NPHY_REV7_RfctrlOverride_cmd_tx_pu, - 0, (1 << off_core), 0); - - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), - 0, 0x3, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1, - (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, - (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, - (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID2); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0, - (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1, - (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0, - (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1, - (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), - 0, (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0, - (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - - state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ? - 0xa6 : 0xa7); - state->afeoverride[core] = - read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5); - state->afectrl[off_core] = - read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa7 : 0xa6); - state->afeoverride[off_core] = - read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa5 : 0x8f); - - mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7), - (0x1 << 2), 0); - mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f : - 0xa5), (0x1 << 2), (0x1 << 2)); - - mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa7 : 0xa6), - (0x1 << 2), (0x1 << 2)); - mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa5 : - 0x8f), (0x1 << 2), (0x1 << 2)); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - state->pwrup[core] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_2G_PWRUP); - state->atten[core] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_2G_ATTEN); - state->pwrup[off_core] = - READ_RADIO_REG3(pi, RADIO_2057, TX, off_core, - TXRXCOUPLE_2G_PWRUP); - state->atten[off_core] = - READ_RADIO_REG3(pi, RADIO_2057, TX, off_core, - TXRXCOUPLE_2G_ATTEN); - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_2G_PWRUP, 0xc); - - if ((pi->pubpi.radiorev == 3) || - (pi->pubpi.radiorev == 4) || - (pi->pubpi.radiorev == 6)) { - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_2G_ATTEN, 0xf0); - - } else if (pi->pubpi.radiorev == 5) { - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_2G_ATTEN, - (core == 0) ? 0xf7 : 0xf2); - - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_2G_ATTEN, 0xf0); - - } else { - ASSERT(0); - } - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core, - TXRXCOUPLE_2G_PWRUP, 0x0); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core, - TXRXCOUPLE_2G_ATTEN, 0xff); - - } else { - state->pwrup[core] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_5G_PWRUP); - state->atten[core] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_5G_ATTEN); - state->pwrup[off_core] = - READ_RADIO_REG3(pi, RADIO_2057, TX, off_core, - TXRXCOUPLE_5G_PWRUP); - state->atten[off_core] = - READ_RADIO_REG3(pi, RADIO_2057, TX, off_core, - TXRXCOUPLE_5G_ATTEN); - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_5G_PWRUP, 0xc); - - if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_5G_ATTEN, 0xf4); - - } else { - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_5G_ATTEN, 0xf0); - } - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core, - TXRXCOUPLE_5G_PWRUP, 0x0); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core, - TXRXCOUPLE_5G_ATTEN, 0xff); - } - - tone_freq = 4000; - - wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 13), (1) << 13); - - mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_OFF) << 0); - - mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 13), (0) << 13); - - } else { - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 0); - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0, 0); - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 0); - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 1, 0x3, 0); - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0x3, 0); - - state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ? - 0xa6 : 0xa7); - state->afeoverride[core] = - read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5); - - mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7), - (0x1 << 0) | (0x1 << 1) | (0x1 << 2), 0); - mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f : - 0xa5), - (0x1 << 0) | - (0x1 << 1) | - (0x1 << 2), (0x1 << 0) | (0x1 << 1) | (0x1 << 2)); - - state->vga_master[core] = - READ_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER); - WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER, 0x2b); - if (CHSPEC_IS2G(pi->radio_chanspec)) { - state->fbmix[core] = - READ_RADIO_REG2(pi, RADIO_2056, RX, core, - TXFBMIX_G); - state->intpa_master[core] = - READ_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAG_MASTER); - - WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_G, - 0x03); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAG_MASTER, 0x04); - } else { - state->fbmix[core] = - READ_RADIO_REG2(pi, RADIO_2056, RX, core, - TXFBMIX_A); - state->intpa_master[core] = - READ_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAA_MASTER); - - WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_A, - 0x03); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAA_MASTER, 0x04); - - } - - tone_freq = 4000; - - wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (1) << 0); - - mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (0) << 0); - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0); - } -} - -static void -wlc_phy_papd_cal_cleanup_nphy(phy_info_t *pi, nphy_papd_restore_state *state) -{ - u8 core; - - wlc_phy_stopplayback_nphy(pi); - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_2G_PWRUP, 0); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_2G_ATTEN, - state->atten[core]); - } else { - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_5G_PWRUP, 0); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_5G_ATTEN, - state->atten[core]); - } - } - - if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), - 1, 0x3, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - } else { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), - 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - } - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), - 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID2); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID2); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 1, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID2); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - - write_phy_reg(pi, (core == PHY_CORE_0) ? - 0xa6 : 0xa7, state->afectrl[core]); - write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : - 0xa5, state->afeoverride[core]); - } - - wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff, - (state->mm & 0xff)); - - if (NREV_IS(pi->pubpi.phy_rev, 7) - || NREV_GE(pi->pubpi.phy_rev, 8)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), 0, 0, - 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - } - } else { - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1); - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 0x3, 1); - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 1); - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 0, 0x3, 1); - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 0, 0x3, 1); - - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - - WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER, - state->vga_master[core]); - if (CHSPEC_IS2G(pi->radio_chanspec)) { - WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, - TXFBMIX_G, state->fbmix[core]); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAG_MASTER, - state->intpa_master[core]); - } else { - WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, - TXFBMIX_A, state->fbmix[core]); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAA_MASTER, - state->intpa_master[core]); - } - - write_phy_reg(pi, (core == PHY_CORE_0) ? - 0xa6 : 0xa7, state->afectrl[core]); - write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : - 0xa5, state->afeoverride[core]); - } - - wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff, - (state->mm & 0xff)); - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 1); - } -} - -static void -wlc_phy_a1_nphy(phy_info_t *pi, u8 core, u32 winsz, u32 start, - u32 end) -{ - u32 *buf, *src, *dst, sz; - - sz = end - start + 1; - ASSERT(end > start); - ASSERT(end < NPHY_PAPD_EPS_TBL_SIZE); - - buf = kmalloc(2 * sizeof(u32) * NPHY_PAPD_EPS_TBL_SIZE, GFP_ATOMIC); - if (NULL == buf) { - return; - } - - src = buf; - dst = buf + NPHY_PAPD_EPS_TBL_SIZE; - - wlc_phy_table_read_nphy(pi, - (core == - PHY_CORE_0 ? NPHY_TBL_ID_EPSILONTBL0 : - NPHY_TBL_ID_EPSILONTBL1), - NPHY_PAPD_EPS_TBL_SIZE, 0, 32, src); - - do { - u32 phy_a1, phy_a2; - s32 phy_a3, phy_a4, phy_a5, phy_a6, phy_a7; - - phy_a1 = end - min(end, (winsz >> 1)); - phy_a2 = min_t(u32, NPHY_PAPD_EPS_TBL_SIZE - 1, end + (winsz >> 1)); - phy_a3 = phy_a2 - phy_a1 + 1; - phy_a6 = 0; - phy_a7 = 0; - - do { - wlc_phy_papd_decode_epsilon(src[phy_a2], &phy_a4, - &phy_a5); - phy_a6 += phy_a4; - phy_a7 += phy_a5; - } while (phy_a2-- != phy_a1); - - phy_a6 /= phy_a3; - phy_a7 /= phy_a3; - dst[end] = ((u32) phy_a7 << 13) | ((u32) phy_a6 & 0x1fff); - } while (end-- != start); - - wlc_phy_table_write_nphy(pi, - (core == - PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 : - NPHY_TBL_ID_EPSILONTBL1, sz, start, 32, dst); - - kfree(buf); -} - -static void -wlc_phy_a2_nphy(phy_info_t *pi, nphy_ipa_txcalgains_t *txgains, - phy_cal_mode_t cal_mode, u8 core) -{ - u16 phy_a1, phy_a2, phy_a3; - u16 phy_a4, phy_a5; - bool phy_a6; - u8 phy_a7, m[2]; - u32 phy_a8 = 0; - nphy_txgains_t phy_a9; - - if (NREV_LT(pi->pubpi.phy_rev, 3)) - return; - - phy_a7 = (core == PHY_CORE_0) ? 1 : 0; - - ASSERT((cal_mode == CAL_FULL) || (cal_mode == CAL_GCTRL) - || (cal_mode == CAL_SOFT)); - phy_a6 = ((cal_mode == CAL_GCTRL) - || (cal_mode == CAL_SOFT)) ? true : false; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - phy_a9 = wlc_phy_get_tx_gain_nphy(pi); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - phy_a5 = ((phy_a9.txlpf[core] << 15) | - (phy_a9.txgm[core] << 12) | - (phy_a9.pga[core] << 8) | - (txgains->gains.pad[core] << 3) | - (phy_a9.ipa[core])); - } else { - phy_a5 = ((phy_a9.txlpf[core] << 15) | - (phy_a9.txgm[core] << 12) | - (txgains->gains.pga[core] << 8) | - (phy_a9.pad[core] << 3) | (phy_a9.ipa[core])); - } - - wlc_phy_rfctrl_override_1tomany_nphy(pi, - NPHY_REV7_RfctrlOverride_cmd_txgain, - phy_a5, (1 << core), 0); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if ((pi->pubpi.radiorev <= 4) - || (pi->pubpi.radiorev == 6)) { - - m[core] = IS40MHZ(pi) ? 60 : 79; - } else { - - m[core] = IS40MHZ(pi) ? 45 : 64; - } - - } else { - m[core] = IS40MHZ(pi) ? 75 : 107; - } - - m[phy_a7] = 0; - wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]); - - phy_a2 = 63; - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (pi->sh->chip == BCM6362_CHIP_ID) { - phy_a1 = 35; - phy_a3 = 35; - } else if ((pi->pubpi.radiorev == 4) - || (pi->pubpi.radiorev == 6)) { - phy_a1 = 30; - phy_a3 = 30; - } else { - phy_a1 = 25; - phy_a3 = 25; - } - } else { - if ((pi->pubpi.radiorev == 5) - || (pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - phy_a1 = 25; - phy_a3 = 25; - } else { - phy_a1 = 35; - phy_a3 = 35; - } - } - - if (cal_mode == CAL_GCTRL) { - if ((pi->pubpi.radiorev == 5) - && (CHSPEC_IS2G(pi->radio_chanspec))) { - phy_a1 = 55; - } else if (((pi->pubpi.radiorev == 7) && - (CHSPEC_IS2G(pi->radio_chanspec))) || - ((pi->pubpi.radiorev == 8) && - (CHSPEC_IS2G(pi->radio_chanspec)))) { - phy_a1 = 60; - } else { - phy_a1 = 63; - } - - } else if ((cal_mode != CAL_FULL) && (cal_mode != CAL_SOFT)) { - - phy_a1 = 35; - phy_a3 = 35; - } - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (1) << 0); - - mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (0) << 0); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 13), (1) << 13); - - mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 13), (0) << 13); - - write_phy_reg(pi, 0x2a1, 0x80); - write_phy_reg(pi, 0x2a2, 0x100); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x7 << 4), (11) << 4); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x7 << 8), (11) << 8); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x7 << 0), (0x3) << 0); - - write_phy_reg(pi, 0x2e5, 0x20); - - mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0); - - mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0); - - mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8); - - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), - 1, ((core == 0) ? 1 : 2), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), - 0, ((core == 0) ? 2 : 1), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - - write_phy_reg(pi, 0x2be, 1); - SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000); - - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), - 0, 0x3, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - - wlc_phy_table_write_nphy(pi, - (core == - PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 - : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3, - 32, &phy_a8); - - if (cal_mode != CAL_GCTRL) { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - wlc_phy_a1_nphy(pi, core, 5, 0, 35); - } - } - - wlc_phy_rfctrl_override_1tomany_nphy(pi, - NPHY_REV7_RfctrlOverride_cmd_txgain, - phy_a5, (1 << core), 1); - - } else { - - if (txgains) { - if (txgains->useindex) { - phy_a4 = 15 - ((txgains->index) >> 3); - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (NREV_GE(pi->pubpi.phy_rev, 6)) { - phy_a5 = 0x00f7 | (phy_a4 << 8); - - if (pi->sh->chip == - BCM47162_CHIP_ID) { - phy_a5 = - 0x10f7 | (phy_a4 << - 8); - } - } else - if (NREV_IS(pi->pubpi.phy_rev, 5)) - phy_a5 = 0x10f7 | (phy_a4 << 8); - else - phy_a5 = 0x50f7 | (phy_a4 << 8); - } else { - phy_a5 = 0x70f7 | (phy_a4 << 8); - } - wlc_phy_rfctrl_override_nphy(pi, - (0x1 << 13), - phy_a5, - (1 << core), 0); - } else { - wlc_phy_rfctrl_override_nphy(pi, - (0x1 << 13), - 0x5bf7, - (1 << core), 0); - } - } - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - m[core] = IS40MHZ(pi) ? 45 : 64; - } else { - m[core] = IS40MHZ(pi) ? 75 : 107; - } - - m[phy_a7] = 0; - wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]); - - phy_a2 = 63; - - if (cal_mode == CAL_FULL) { - phy_a1 = 25; - phy_a3 = 25; - } else if (cal_mode == CAL_SOFT) { - phy_a1 = 25; - phy_a3 = 25; - } else if (cal_mode == CAL_GCTRL) { - phy_a1 = 63; - phy_a3 = 25; - } else { - - phy_a1 = 25; - phy_a3 = 25; - } - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (1) << 0); - - mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (0) << 0); - - if (NREV_GE(pi->pubpi.phy_rev, 6)) { - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 13), (1) << 13); - - mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 13), (0) << 13); - - write_phy_reg(pi, 0x2a1, 0x20); - write_phy_reg(pi, 0x2a2, 0x60); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0xf << 4), (9) << 4); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0xf << 8), (9) << 8); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0xf << 0), (0x2) << 0); - - write_phy_reg(pi, 0x2e5, 0x20); - } else { - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 11), (1) << 11); - - mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 11), (0) << 11); - - write_phy_reg(pi, 0x2a1, 0x80); - write_phy_reg(pi, 0x2a2, 0x600); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x7 << 4), (0) << 4); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x7 << 8), (0) << 8); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x7 << 0), (0x3) << 0); - - mod_phy_reg(pi, 0x2a0, (0x3f << 8), (0x20) << 8); - - } - - mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0); - - mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0); - - mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8); - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0x3, 0); - - write_phy_reg(pi, 0x2be, 1); - SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000); - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0); - - wlc_phy_table_write_nphy(pi, - (core == - PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 - : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3, - 32, &phy_a8); - - if (cal_mode != CAL_GCTRL) { - wlc_phy_a1_nphy(pi, core, 5, 0, 40); - } - } -} - -static u8 wlc_phy_a3_nphy(phy_info_t *pi, u8 start_gain, u8 core) -{ - int phy_a1; - int phy_a2; - bool phy_a3; - nphy_ipa_txcalgains_t phy_a4; - bool phy_a5 = false; - bool phy_a6 = true; - s32 phy_a7, phy_a8; - u32 phy_a9; - int phy_a10; - bool phy_a11 = false; - int phy_a12; - u8 phy_a13 = 0; - u8 phy_a14; - u8 *phy_a15 = NULL; - - phy_a4.useindex = true; - phy_a12 = start_gain; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - phy_a2 = 20; - phy_a1 = 1; - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (pi->pubpi.radiorev == 5) { - - phy_a15 = pad_gain_codes_used_2057rev5; - phy_a13 = sizeof(pad_gain_codes_used_2057rev5) / - sizeof(pad_gain_codes_used_2057rev5[0]) - 1; - - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - - phy_a15 = pad_gain_codes_used_2057rev7; - phy_a13 = sizeof(pad_gain_codes_used_2057rev7) / - sizeof(pad_gain_codes_used_2057rev7[0]) - 1; - - } else { - - phy_a15 = pad_all_gain_codes_2057; - phy_a13 = sizeof(pad_all_gain_codes_2057) / - sizeof(pad_all_gain_codes_2057[0]) - 1; - } - - } else { - - phy_a15 = pga_all_gain_codes_2057; - phy_a13 = sizeof(pga_all_gain_codes_2057) / - sizeof(pga_all_gain_codes_2057[0]) - 1; - } - - phy_a14 = 0; - - for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) { - if (CHSPEC_IS2G(pi->radio_chanspec)) { - phy_a4.gains.pad[core] = - (u16) phy_a15[phy_a12]; - } else { - phy_a4.gains.pga[core] = - (u16) phy_a15[phy_a12]; - } - - wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core); - - wlc_phy_table_read_nphy(pi, - (core == - PHY_CORE_0 ? - NPHY_TBL_ID_EPSILONTBL0 : - NPHY_TBL_ID_EPSILONTBL1), 1, - 63, 32, &phy_a9); - - wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8); - - phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) || - (phy_a8 == 4095) || (phy_a8 == -4096)); - - if (!phy_a6 && (phy_a3 != phy_a5)) { - if (!phy_a3) { - phy_a12 -= (u8) phy_a1; - } - phy_a11 = true; - break; - } - - if (phy_a3) - phy_a12 += (u8) phy_a1; - else - phy_a12 -= (u8) phy_a1; - - if ((phy_a12 < phy_a14) || (phy_a12 > phy_a13)) { - if (phy_a12 < phy_a14) { - phy_a12 = phy_a14; - } else { - phy_a12 = phy_a13; - } - phy_a11 = true; - break; - } - - phy_a6 = false; - phy_a5 = phy_a3; - } - - } else { - phy_a2 = 10; - phy_a1 = 8; - for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) { - phy_a4.index = (u8) phy_a12; - wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core); - - wlc_phy_table_read_nphy(pi, - (core == - PHY_CORE_0 ? - NPHY_TBL_ID_EPSILONTBL0 : - NPHY_TBL_ID_EPSILONTBL1), 1, - 63, 32, &phy_a9); - - wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8); - - phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) || - (phy_a8 == 4095) || (phy_a8 == -4096)); - - if (!phy_a6 && (phy_a3 != phy_a5)) { - if (!phy_a3) { - phy_a12 -= (u8) phy_a1; - } - phy_a11 = true; - break; - } - - if (phy_a3) - phy_a12 += (u8) phy_a1; - else - phy_a12 -= (u8) phy_a1; - - if ((phy_a12 < 0) || (phy_a12 > 127)) { - if (phy_a12 < 0) { - phy_a12 = 0; - } else { - phy_a12 = 127; - } - phy_a11 = true; - break; - } - - phy_a6 = false; - phy_a5 = phy_a3; - } - - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - return (u8) phy_a15[phy_a12]; - } else { - return (u8) phy_a12; - } - -} - -static void wlc_phy_a4(phy_info_t *pi, bool full_cal) -{ - nphy_ipa_txcalgains_t phy_b1[2]; - nphy_papd_restore_state phy_b2; - bool phy_b3; - u8 phy_b4; - u8 phy_b5; - s16 phy_b6, phy_b7, phy_b8; - u16 phy_b9; - s16 phy_b10, phy_b11, phy_b12; - - phy_b11 = 0; - phy_b12 = 0; - phy_b7 = 0; - phy_b8 = 0; - phy_b6 = 0; - - if (pi->nphy_papd_skip == 1) - return; - - phy_b3 = - (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); - if (!phy_b3) { - wlapi_suspend_mac_and_wait(pi->sh->physhim); - } - - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - pi->nphy_force_papd_cal = false; - - for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) - pi->nphy_papd_tx_gain_at_last_cal[phy_b5] = - wlc_phy_txpwr_idx_cur_get_nphy(pi, phy_b5); - - pi->nphy_papd_last_cal = pi->sh->now; - pi->nphy_papd_recal_counter++; - - if (NORADIO_ENAB(pi->pubpi)) - return; - - phy_b4 = pi->nphy_txpwrctrl; - wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL0, 64, 0, 32, - nphy_papd_scaltbl); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL1, 64, 0, 32, - nphy_papd_scaltbl); - - phy_b9 = read_phy_reg(pi, 0x01); - mod_phy_reg(pi, 0x01, (0x1 << 15), 0); - - for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) { - s32 i, val = 0; - for (i = 0; i < 64; i++) { - wlc_phy_table_write_nphy(pi, - ((phy_b5 == - PHY_CORE_0) ? - NPHY_TBL_ID_EPSILONTBL0 : - NPHY_TBL_ID_EPSILONTBL1), 1, - i, 32, &val); - } - } - - wlc_phy_ipa_restore_tx_digi_filts_nphy(pi); - - phy_b2.mm = wlc_phy_ipa_get_bbmult_nphy(pi); - for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) { - wlc_phy_papd_cal_setup_nphy(pi, &phy_b2, phy_b5); - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if (CHSPEC_IS2G(pi->radio_chanspec)) { - - if ((pi->pubpi.radiorev == 3) - || (pi->pubpi.radiorev == 4) - || (pi->pubpi.radiorev == 6)) { - - pi->nphy_papd_cal_gain_index[phy_b5] = - 23; - - } else if (pi->pubpi.radiorev == 5) { - - pi->nphy_papd_cal_gain_index[phy_b5] = - 0; - pi->nphy_papd_cal_gain_index[phy_b5] = - wlc_phy_a3_nphy(pi, - pi-> - nphy_papd_cal_gain_index - [phy_b5], phy_b5); - - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - - pi->nphy_papd_cal_gain_index[phy_b5] = - 0; - pi->nphy_papd_cal_gain_index[phy_b5] = - wlc_phy_a3_nphy(pi, - pi-> - nphy_papd_cal_gain_index - [phy_b5], phy_b5); - - } else { - ASSERT(0); - } - - phy_b1[phy_b5].gains.pad[phy_b5] = - pi->nphy_papd_cal_gain_index[phy_b5]; - - } else { - pi->nphy_papd_cal_gain_index[phy_b5] = 0; - pi->nphy_papd_cal_gain_index[phy_b5] = - wlc_phy_a3_nphy(pi, - pi-> - nphy_papd_cal_gain_index - [phy_b5], phy_b5); - phy_b1[phy_b5].gains.pga[phy_b5] = - pi->nphy_papd_cal_gain_index[phy_b5]; - } - } else { - phy_b1[phy_b5].useindex = true; - phy_b1[phy_b5].index = 16; - phy_b1[phy_b5].index = - wlc_phy_a3_nphy(pi, phy_b1[phy_b5].index, phy_b5); - - pi->nphy_papd_cal_gain_index[phy_b5] = - 15 - ((phy_b1[phy_b5].index) >> 3); - } - - switch (pi->nphy_papd_cal_type) { - case 0: - wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_FULL, phy_b5); - break; - case 1: - wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_SOFT, phy_b5); - break; - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2); - } - } - - if (NREV_LT(pi->pubpi.phy_rev, 7)) { - wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2); - } - - for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) { - int eps_offset = 0; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (pi->pubpi.radiorev == 3) { - eps_offset = -2; - } else if (pi->pubpi.radiorev == 5) { - eps_offset = 3; - } else { - eps_offset = -1; - } - } else { - eps_offset = 2; - } - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - phy_b8 = phy_b1[phy_b5].gains.pad[phy_b5]; - phy_b10 = 0; - if ((pi->pubpi.radiorev == 3) || - (pi->pubpi.radiorev == 4) || - (pi->pubpi.radiorev == 6)) { - phy_b12 = - - - (nphy_papd_padgain_dlt_2g_2057rev3n4 - [phy_b8] - + 1) / 2; - phy_b10 = -1; - } else if (pi->pubpi.radiorev == 5) { - phy_b12 = - -(nphy_papd_padgain_dlt_2g_2057rev5 - [phy_b8] - + 1) / 2; - } else if ((pi->pubpi.radiorev == 7) || - (pi->pubpi.radiorev == 8)) { - phy_b12 = - -(nphy_papd_padgain_dlt_2g_2057rev7 - [phy_b8] - + 1) / 2; - } else { - ASSERT(0); - } - } else { - phy_b7 = phy_b1[phy_b5].gains.pga[phy_b5]; - if ((pi->pubpi.radiorev == 3) || - (pi->pubpi.radiorev == 4) || - (pi->pubpi.radiorev == 6)) { - phy_b11 = - -(nphy_papd_pgagain_dlt_5g_2057 - [phy_b7] - + 1) / 2; - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - phy_b11 = - -(nphy_papd_pgagain_dlt_5g_2057rev7 - [phy_b7] - + 1) / 2; - } else { - ASSERT(0); - } - - phy_b10 = -9; - } - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - phy_b6 = - -60 + 27 + eps_offset + phy_b12 + phy_b10; - } else { - phy_b6 = - -60 + 27 + eps_offset + phy_b11 + phy_b10; - } - - mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 : - 0x29c, (0x1ff << 7), (phy_b6) << 7); - - pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6; - } else { - if (NREV_LT(pi->pubpi.phy_rev, 5)) { - eps_offset = 4; - } else { - eps_offset = 2; - } - - phy_b7 = 15 - ((phy_b1[phy_b5].index) >> 3); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - phy_b11 = - -(nphy_papd_pga_gain_delta_ipa_2g[phy_b7] + - 1) / 2; - phy_b10 = 0; - } else { - phy_b11 = - -(nphy_papd_pga_gain_delta_ipa_5g[phy_b7] + - 1) / 2; - phy_b10 = -9; - } - - phy_b6 = -60 + 27 + eps_offset + phy_b11 + phy_b10; - - mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 : - 0x29c, (0x1ff << 7), (phy_b6) << 7); - - pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6; - } - } - - mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0); - - mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0); - - if (NREV_GE(pi->pubpi.phy_rev, 6)) { - mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 13), (0) << 13); - - mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 13), (0) << 13); - - } else { - mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 11), (0) << 11); - - mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 11), (0) << 11); - - } - pi->nphy_papdcomp = NPHY_PAPD_COMP_ON; - - write_phy_reg(pi, 0x01, phy_b9); - - wlc_phy_ipa_set_tx_digi_filts_nphy(pi); - - wlc_phy_txpwrctrl_enable_nphy(pi, phy_b4); - if (phy_b4 == PHY_TPC_HW_OFF) { - wlc_phy_txpwr_index_nphy(pi, (1 << 0), - (s8) (pi->nphy_txpwrindex[0]. - index_internal), false); - wlc_phy_txpwr_index_nphy(pi, (1 << 1), - (s8) (pi->nphy_txpwrindex[1]. - index_internal), false); - } - - wlc_phy_stay_in_carriersearch_nphy(pi, false); - - if (!phy_b3) { - wlapi_enable_mac(pi->sh->physhim); - } -} - -void wlc_phy_txpwr_fixpower_nphy(phy_info_t *pi) -{ - uint core; - u32 txgain; - u16 rad_gain, dac_gain, bbmult, m1m2; - u8 txpi[2], chan_freq_range; - s32 rfpwr_offset; - - ASSERT(pi->nphy_txpwrctrl == PHY_TPC_HW_OFF); - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - if (pi->sh->sromrev < 4) { - txpi[0] = txpi[1] = 72; - } else { - - chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0); - switch (chan_freq_range) { - case WL_CHAN_FREQ_RANGE_2G: - txpi[0] = pi->nphy_txpid2g[0]; - txpi[1] = pi->nphy_txpid2g[1]; - break; - case WL_CHAN_FREQ_RANGE_5GL: - txpi[0] = pi->nphy_txpid5gl[0]; - txpi[1] = pi->nphy_txpid5gl[1]; - break; - case WL_CHAN_FREQ_RANGE_5GM: - txpi[0] = pi->nphy_txpid5g[0]; - txpi[1] = pi->nphy_txpid5g[1]; - break; - case WL_CHAN_FREQ_RANGE_5GH: - txpi[0] = pi->nphy_txpid5gh[0]; - txpi[1] = pi->nphy_txpid5gh[1]; - break; - default: - txpi[0] = txpi[1] = 91; - break; - } - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - txpi[0] = txpi[1] = 30; - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - txpi[0] = txpi[1] = 40; - } - - if (NREV_LT(pi->pubpi.phy_rev, 7)) { - - if ((txpi[0] < 40) || (txpi[0] > 100) || - (txpi[1] < 40) || (txpi[1] > 100)) - txpi[0] = txpi[1] = 91; - } - - pi->nphy_txpwrindex[PHY_CORE_0].index_internal = txpi[0]; - pi->nphy_txpwrindex[PHY_CORE_1].index_internal = txpi[1]; - pi->nphy_txpwrindex[PHY_CORE_0].index_internal_save = txpi[0]; - pi->nphy_txpwrindex[PHY_CORE_1].index_internal_save = txpi[1]; - - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if (PHY_IPA(pi)) { - u32 *tx_gaintbl = - wlc_phy_get_ipa_gaintbl_nphy(pi); - txgain = tx_gaintbl[txpi[core]]; - } else { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - if NREV_IS - (pi->pubpi.phy_rev, 3) { - txgain = - nphy_tpc_5GHz_txgain_rev3 - [txpi[core]]; - } else if NREV_IS - (pi->pubpi.phy_rev, 4) { - txgain = - (pi->srom_fem5g.extpagain == - 3) ? - nphy_tpc_5GHz_txgain_HiPwrEPA - [txpi[core]] : - nphy_tpc_5GHz_txgain_rev4 - [txpi[core]]; - } else { - txgain = - nphy_tpc_5GHz_txgain_rev5 - [txpi[core]]; - } - } else { - if (NREV_GE(pi->pubpi.phy_rev, 5) && - (pi->srom_fem2g.extpagain == 3)) { - txgain = - nphy_tpc_txgain_HiPwrEPA - [txpi[core]]; - } else { - txgain = - nphy_tpc_txgain_rev3[txpi - [core]]; - } - } - } - } else { - txgain = nphy_tpc_txgain[txpi[core]]; - } - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - rad_gain = (txgain >> 16) & ((1 << (32 - 16 + 1)) - 1); - } else { - rad_gain = (txgain >> 16) & ((1 << (28 - 16 + 1)) - 1); - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - dac_gain = (txgain >> 8) & ((1 << (10 - 8 + 1)) - 1); - } else { - dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1); - } - bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1); - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f : - 0xa5), (0x1 << 8), (0x1 << 8)); - } else { - mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14)); - } - write_phy_reg(pi, (core == PHY_CORE_0) ? 0xaa : 0xab, dac_gain); - - wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16, - &rad_gain); - - wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2); - m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00); - m1m2 |= ((core == PHY_CORE_0) ? (bbmult << 8) : (bbmult << 0)); - wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2); - - if (PHY_IPA(pi)) { - wlc_phy_table_read_nphy(pi, - (core == - PHY_CORE_0 ? - NPHY_TBL_ID_CORE1TXPWRCTL : - NPHY_TBL_ID_CORE2TXPWRCTL), 1, - 576 + txpi[core], 32, - &rfpwr_offset); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1ff << 4), - ((s16) rfpwr_offset) << 4); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 2), (1) << 2); - - } - } - - and_phy_reg(pi, 0xbf, (u16) (~(0x1f << 0))); - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); -} - -static void -wlc_phy_txpwr_nphy_srom_convert(u8 *srom_max, u16 *pwr_offset, - u8 tmp_max_pwr, u8 rate_start, - u8 rate_end) -{ - u8 rate; - u8 word_num, nibble_num; - u8 tmp_nibble; - - for (rate = rate_start; rate <= rate_end; rate++) { - word_num = (rate - rate_start) >> 2; - nibble_num = (rate - rate_start) & 0x3; - tmp_nibble = (pwr_offset[word_num] >> 4 * nibble_num) & 0xf; - - srom_max[rate] = tmp_max_pwr - 2 * tmp_nibble; - } -} - -static void -wlc_phy_txpwr_nphy_po_apply(u8 *srom_max, u8 pwr_offset, - u8 rate_start, u8 rate_end) -{ - u8 rate; - - for (rate = rate_start; rate <= rate_end; rate++) { - srom_max[rate] -= 2 * pwr_offset; - } -} - -void -wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start, - u8 rate_mcs_end, u8 rate_ofdm_start) -{ - u8 rate1, rate2; - - rate2 = rate_ofdm_start; - for (rate1 = rate_mcs_start; rate1 <= rate_mcs_end - 1; rate1++) { - power[rate1] = power[rate2]; - rate2 += (rate1 == rate_mcs_start) ? 2 : 1; - } - power[rate_mcs_end] = power[rate_mcs_end - 1]; -} - -void -wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power, u8 rate_ofdm_start, - u8 rate_ofdm_end, u8 rate_mcs_start) -{ - u8 rate1, rate2; - - for (rate1 = rate_ofdm_start, rate2 = rate_mcs_start; - rate1 <= rate_ofdm_end; rate1++, rate2++) { - power[rate1] = power[rate2]; - if (rate1 == rate_ofdm_start) - power[++rate1] = power[rate2]; - } -} - -void wlc_phy_txpwr_apply_nphy(phy_info_t *pi) -{ - uint rate1, rate2, band_num; - u8 tmp_bw40po = 0, tmp_cddpo = 0, tmp_stbcpo = 0; - u8 tmp_max_pwr = 0; - u16 pwr_offsets1[2], *pwr_offsets2 = NULL; - u8 *tx_srom_max_rate = NULL; - - for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP); band_num++) { - switch (band_num) { - case 0: - - tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_2g, - pi->nphy_pwrctrl_info[1].max_pwr_2g); - - pwr_offsets1[0] = pi->cck2gpo; - wlc_phy_txpwr_nphy_srom_convert(pi->tx_srom_max_rate_2g, - pwr_offsets1, - tmp_max_pwr, - TXP_FIRST_CCK, - TXP_LAST_CCK); - - pwr_offsets1[0] = (u16) (pi->ofdm2gpo & 0xffff); - pwr_offsets1[1] = - (u16) (pi->ofdm2gpo >> 16) & 0xffff; - - pwr_offsets2 = pi->mcs2gpo; - - tmp_cddpo = pi->cdd2gpo; - tmp_stbcpo = pi->stbc2gpo; - tmp_bw40po = pi->bw402gpo; - - tx_srom_max_rate = pi->tx_srom_max_rate_2g; - break; - case 1: - - tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gm, - pi->nphy_pwrctrl_info[1].max_pwr_5gm); - - pwr_offsets1[0] = (u16) (pi->ofdm5gpo & 0xffff); - pwr_offsets1[1] = - (u16) (pi->ofdm5gpo >> 16) & 0xffff; - - pwr_offsets2 = pi->mcs5gpo; - - tmp_cddpo = pi->cdd5gpo; - tmp_stbcpo = pi->stbc5gpo; - tmp_bw40po = pi->bw405gpo; - - tx_srom_max_rate = pi->tx_srom_max_rate_5g_mid; - break; - case 2: - - tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gl, - pi->nphy_pwrctrl_info[1].max_pwr_5gl); - - pwr_offsets1[0] = (u16) (pi->ofdm5glpo & 0xffff); - pwr_offsets1[1] = - (u16) (pi->ofdm5glpo >> 16) & 0xffff; - - pwr_offsets2 = pi->mcs5glpo; - - tmp_cddpo = pi->cdd5glpo; - tmp_stbcpo = pi->stbc5glpo; - tmp_bw40po = pi->bw405glpo; - - tx_srom_max_rate = pi->tx_srom_max_rate_5g_low; - break; - case 3: - - tmp_max_pwr = min(pi->nphy_pwrctrl_info[0].max_pwr_5gh, - pi->nphy_pwrctrl_info[1].max_pwr_5gh); - - pwr_offsets1[0] = (u16) (pi->ofdm5ghpo & 0xffff); - pwr_offsets1[1] = - (u16) (pi->ofdm5ghpo >> 16) & 0xffff; - - pwr_offsets2 = pi->mcs5ghpo; - - tmp_cddpo = pi->cdd5ghpo; - tmp_stbcpo = pi->stbc5ghpo; - tmp_bw40po = pi->bw405ghpo; - - tx_srom_max_rate = pi->tx_srom_max_rate_5g_hi; - break; - } - - wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets1, - tmp_max_pwr, TXP_FIRST_OFDM, - TXP_LAST_OFDM); - - wlc_phy_ofdm_to_mcs_powers_nphy(tx_srom_max_rate, - TXP_FIRST_MCS_20_SISO, - TXP_LAST_MCS_20_SISO, - TXP_FIRST_OFDM); - - wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2, - tmp_max_pwr, - TXP_FIRST_MCS_20_CDD, - TXP_LAST_MCS_20_CDD); - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - - wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo, - TXP_FIRST_MCS_20_CDD, - TXP_LAST_MCS_20_CDD); - } - - wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate, - TXP_FIRST_OFDM_20_CDD, - TXP_LAST_OFDM_20_CDD, - TXP_FIRST_MCS_20_CDD); - - wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, pwr_offsets2, - tmp_max_pwr, - TXP_FIRST_MCS_20_STBC, - TXP_LAST_MCS_20_STBC); - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - - wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, - tmp_stbcpo, - TXP_FIRST_MCS_20_STBC, - TXP_LAST_MCS_20_STBC); - } - - wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, - &pwr_offsets2[2], tmp_max_pwr, - TXP_FIRST_MCS_20_SDM, - TXP_LAST_MCS_20_SDM); - - if (NPHY_IS_SROM_REINTERPRET) { - - wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, - &pwr_offsets2[4], - tmp_max_pwr, - TXP_FIRST_MCS_40_SISO, - TXP_LAST_MCS_40_SISO); - - wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate, - TXP_FIRST_OFDM_40_SISO, - TXP_LAST_OFDM_40_SISO, - TXP_FIRST_MCS_40_SISO); - - wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, - &pwr_offsets2[4], - tmp_max_pwr, - TXP_FIRST_MCS_40_CDD, - TXP_LAST_MCS_40_CDD); - - wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo, - TXP_FIRST_MCS_40_CDD, - TXP_LAST_MCS_40_CDD); - - wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate, - TXP_FIRST_OFDM_40_CDD, - TXP_LAST_OFDM_40_CDD, - TXP_FIRST_MCS_40_CDD); - - wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, - &pwr_offsets2[4], - tmp_max_pwr, - TXP_FIRST_MCS_40_STBC, - TXP_LAST_MCS_40_STBC); - - wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, - tmp_stbcpo, - TXP_FIRST_MCS_40_STBC, - TXP_LAST_MCS_40_STBC); - - wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, - &pwr_offsets2[6], - tmp_max_pwr, - TXP_FIRST_MCS_40_SDM, - TXP_LAST_MCS_40_SDM); - } else { - - for (rate1 = TXP_FIRST_OFDM_40_SISO, rate2 = - TXP_FIRST_OFDM; rate1 <= TXP_LAST_MCS_40_SDM; - rate1++, rate2++) - tx_srom_max_rate[rate1] = - tx_srom_max_rate[rate2]; - } - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, - tmp_bw40po, - TXP_FIRST_OFDM_40_SISO, - TXP_LAST_MCS_40_SDM); - } - - tx_srom_max_rate[TXP_MCS_32] = - tx_srom_max_rate[TXP_FIRST_MCS_40_CDD]; - } - - return; -} - -static void wlc_phy_txpwr_srom_read_ppr_nphy(phy_info_t *pi) -{ - u16 bw40po, cddpo, stbcpo, bwduppo; - uint band_num; - - if (pi->sh->sromrev >= 9) { - - return; - } - - bw40po = (u16) PHY_GETINTVAR(pi, "bw40po"); - pi->bw402gpo = bw40po & 0xf; - pi->bw405gpo = (bw40po & 0xf0) >> 4; - pi->bw405glpo = (bw40po & 0xf00) >> 8; - pi->bw405ghpo = (bw40po & 0xf000) >> 12; - - cddpo = (u16) PHY_GETINTVAR(pi, "cddpo"); - pi->cdd2gpo = cddpo & 0xf; - pi->cdd5gpo = (cddpo & 0xf0) >> 4; - pi->cdd5glpo = (cddpo & 0xf00) >> 8; - pi->cdd5ghpo = (cddpo & 0xf000) >> 12; - - stbcpo = (u16) PHY_GETINTVAR(pi, "stbcpo"); - pi->stbc2gpo = stbcpo & 0xf; - pi->stbc5gpo = (stbcpo & 0xf0) >> 4; - pi->stbc5glpo = (stbcpo & 0xf00) >> 8; - pi->stbc5ghpo = (stbcpo & 0xf000) >> 12; - - bwduppo = (u16) PHY_GETINTVAR(pi, "bwduppo"); - pi->bwdup2gpo = bwduppo & 0xf; - pi->bwdup5gpo = (bwduppo & 0xf0) >> 4; - pi->bwdup5glpo = (bwduppo & 0xf00) >> 8; - pi->bwdup5ghpo = (bwduppo & 0xf000) >> 12; - - for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP); band_num++) { - switch (band_num) { - case 0: - - pi->nphy_txpid2g[PHY_CORE_0] = - (u8) PHY_GETINTVAR(pi, "txpid2ga0"); - pi->nphy_txpid2g[PHY_CORE_1] = - (u8) PHY_GETINTVAR(pi, "txpid2ga1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g = - (s8) PHY_GETINTVAR(pi, "maxp2ga0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_2g = - (s8) PHY_GETINTVAR(pi, "maxp2ga1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_a1 = - (s16) PHY_GETINTVAR(pi, "pa2gw0a0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_a1 = - (s16) PHY_GETINTVAR(pi, "pa2gw0a1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b0 = - (s16) PHY_GETINTVAR(pi, "pa2gw1a0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b0 = - (s16) PHY_GETINTVAR(pi, "pa2gw1a1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b1 = - (s16) PHY_GETINTVAR(pi, "pa2gw2a0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b1 = - (s16) PHY_GETINTVAR(pi, "pa2gw2a1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_2g = - (s8) PHY_GETINTVAR(pi, "itt2ga0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_2g = - (s8) PHY_GETINTVAR(pi, "itt2ga1"); - - pi->cck2gpo = (u16) PHY_GETINTVAR(pi, "cck2gpo"); - - pi->ofdm2gpo = (u32) PHY_GETINTVAR(pi, "ofdm2gpo"); - - pi->mcs2gpo[0] = (u16) PHY_GETINTVAR(pi, "mcs2gpo0"); - pi->mcs2gpo[1] = (u16) PHY_GETINTVAR(pi, "mcs2gpo1"); - pi->mcs2gpo[2] = (u16) PHY_GETINTVAR(pi, "mcs2gpo2"); - pi->mcs2gpo[3] = (u16) PHY_GETINTVAR(pi, "mcs2gpo3"); - pi->mcs2gpo[4] = (u16) PHY_GETINTVAR(pi, "mcs2gpo4"); - pi->mcs2gpo[5] = (u16) PHY_GETINTVAR(pi, "mcs2gpo5"); - pi->mcs2gpo[6] = (u16) PHY_GETINTVAR(pi, "mcs2gpo6"); - pi->mcs2gpo[7] = (u16) PHY_GETINTVAR(pi, "mcs2gpo7"); - break; - case 1: - - pi->nphy_txpid5g[PHY_CORE_0] = - (u8) PHY_GETINTVAR(pi, "txpid5ga0"); - pi->nphy_txpid5g[PHY_CORE_1] = - (u8) PHY_GETINTVAR(pi, "txpid5ga1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm = - (s8) PHY_GETINTVAR(pi, "maxp5ga0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm = - (s8) PHY_GETINTVAR(pi, "maxp5ga1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_a1 = - (s16) PHY_GETINTVAR(pi, "pa5gw0a0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_a1 = - (s16) PHY_GETINTVAR(pi, "pa5gw0a1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b0 = - (s16) PHY_GETINTVAR(pi, "pa5gw1a0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b0 = - (s16) PHY_GETINTVAR(pi, "pa5gw1a1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b1 = - (s16) PHY_GETINTVAR(pi, "pa5gw2a0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b1 = - (s16) PHY_GETINTVAR(pi, "pa5gw2a1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_5gm = - (s8) PHY_GETINTVAR(pi, "itt5ga0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_5gm = - (s8) PHY_GETINTVAR(pi, "itt5ga1"); - - pi->ofdm5gpo = (u32) PHY_GETINTVAR(pi, "ofdm5gpo"); - - pi->mcs5gpo[0] = (u16) PHY_GETINTVAR(pi, "mcs5gpo0"); - pi->mcs5gpo[1] = (u16) PHY_GETINTVAR(pi, "mcs5gpo1"); - pi->mcs5gpo[2] = (u16) PHY_GETINTVAR(pi, "mcs5gpo2"); - pi->mcs5gpo[3] = (u16) PHY_GETINTVAR(pi, "mcs5gpo3"); - pi->mcs5gpo[4] = (u16) PHY_GETINTVAR(pi, "mcs5gpo4"); - pi->mcs5gpo[5] = (u16) PHY_GETINTVAR(pi, "mcs5gpo5"); - pi->mcs5gpo[6] = (u16) PHY_GETINTVAR(pi, "mcs5gpo6"); - pi->mcs5gpo[7] = (u16) PHY_GETINTVAR(pi, "mcs5gpo7"); - break; - case 2: - - pi->nphy_txpid5gl[0] = - (u8) PHY_GETINTVAR(pi, "txpid5gla0"); - pi->nphy_txpid5gl[1] = - (u8) PHY_GETINTVAR(pi, "txpid5gla1"); - pi->nphy_pwrctrl_info[0].max_pwr_5gl = - (s8) PHY_GETINTVAR(pi, "maxp5gla0"); - pi->nphy_pwrctrl_info[1].max_pwr_5gl = - (s8) PHY_GETINTVAR(pi, "maxp5gla1"); - pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1 = - (s16) PHY_GETINTVAR(pi, "pa5glw0a0"); - pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1 = - (s16) PHY_GETINTVAR(pi, "pa5glw0a1"); - pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0 = - (s16) PHY_GETINTVAR(pi, "pa5glw1a0"); - pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0 = - (s16) PHY_GETINTVAR(pi, "pa5glw1a1"); - pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1 = - (s16) PHY_GETINTVAR(pi, "pa5glw2a0"); - pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1 = - (s16) PHY_GETINTVAR(pi, "pa5glw2a1"); - pi->nphy_pwrctrl_info[0].idle_targ_5gl = 0; - pi->nphy_pwrctrl_info[1].idle_targ_5gl = 0; - - pi->ofdm5glpo = (u32) PHY_GETINTVAR(pi, "ofdm5glpo"); - - pi->mcs5glpo[0] = - (u16) PHY_GETINTVAR(pi, "mcs5glpo0"); - pi->mcs5glpo[1] = - (u16) PHY_GETINTVAR(pi, "mcs5glpo1"); - pi->mcs5glpo[2] = - (u16) PHY_GETINTVAR(pi, "mcs5glpo2"); - pi->mcs5glpo[3] = - (u16) PHY_GETINTVAR(pi, "mcs5glpo3"); - pi->mcs5glpo[4] = - (u16) PHY_GETINTVAR(pi, "mcs5glpo4"); - pi->mcs5glpo[5] = - (u16) PHY_GETINTVAR(pi, "mcs5glpo5"); - pi->mcs5glpo[6] = - (u16) PHY_GETINTVAR(pi, "mcs5glpo6"); - pi->mcs5glpo[7] = - (u16) PHY_GETINTVAR(pi, "mcs5glpo7"); - break; - case 3: - - pi->nphy_txpid5gh[0] = - (u8) PHY_GETINTVAR(pi, "txpid5gha0"); - pi->nphy_txpid5gh[1] = - (u8) PHY_GETINTVAR(pi, "txpid5gha1"); - pi->nphy_pwrctrl_info[0].max_pwr_5gh = - (s8) PHY_GETINTVAR(pi, "maxp5gha0"); - pi->nphy_pwrctrl_info[1].max_pwr_5gh = - (s8) PHY_GETINTVAR(pi, "maxp5gha1"); - pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1 = - (s16) PHY_GETINTVAR(pi, "pa5ghw0a0"); - pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1 = - (s16) PHY_GETINTVAR(pi, "pa5ghw0a1"); - pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0 = - (s16) PHY_GETINTVAR(pi, "pa5ghw1a0"); - pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0 = - (s16) PHY_GETINTVAR(pi, "pa5ghw1a1"); - pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1 = - (s16) PHY_GETINTVAR(pi, "pa5ghw2a0"); - pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1 = - (s16) PHY_GETINTVAR(pi, "pa5ghw2a1"); - pi->nphy_pwrctrl_info[0].idle_targ_5gh = 0; - pi->nphy_pwrctrl_info[1].idle_targ_5gh = 0; - - pi->ofdm5ghpo = (u32) PHY_GETINTVAR(pi, "ofdm5ghpo"); - - pi->mcs5ghpo[0] = - (u16) PHY_GETINTVAR(pi, "mcs5ghpo0"); - pi->mcs5ghpo[1] = - (u16) PHY_GETINTVAR(pi, "mcs5ghpo1"); - pi->mcs5ghpo[2] = - (u16) PHY_GETINTVAR(pi, "mcs5ghpo2"); - pi->mcs5ghpo[3] = - (u16) PHY_GETINTVAR(pi, "mcs5ghpo3"); - pi->mcs5ghpo[4] = - (u16) PHY_GETINTVAR(pi, "mcs5ghpo4"); - pi->mcs5ghpo[5] = - (u16) PHY_GETINTVAR(pi, "mcs5ghpo5"); - pi->mcs5ghpo[6] = - (u16) PHY_GETINTVAR(pi, "mcs5ghpo6"); - pi->mcs5ghpo[7] = - (u16) PHY_GETINTVAR(pi, "mcs5ghpo7"); - break; - } - } - - wlc_phy_txpwr_apply_nphy(pi); -} - -static bool wlc_phy_txpwr_srom_read_nphy(phy_info_t *pi) -{ - - pi->antswitch = (u8) PHY_GETINTVAR(pi, "antswitch"); - pi->aa2g = (u8) PHY_GETINTVAR(pi, "aa2g"); - pi->aa5g = (u8) PHY_GETINTVAR(pi, "aa5g"); - - pi->srom_fem2g.tssipos = (u8) PHY_GETINTVAR(pi, "tssipos2g"); - pi->srom_fem2g.extpagain = (u8) PHY_GETINTVAR(pi, "extpagain2g"); - pi->srom_fem2g.pdetrange = (u8) PHY_GETINTVAR(pi, "pdetrange2g"); - pi->srom_fem2g.triso = (u8) PHY_GETINTVAR(pi, "triso2g"); - pi->srom_fem2g.antswctrllut = (u8) PHY_GETINTVAR(pi, "antswctl2g"); - - pi->srom_fem5g.tssipos = (u8) PHY_GETINTVAR(pi, "tssipos5g"); - pi->srom_fem5g.extpagain = (u8) PHY_GETINTVAR(pi, "extpagain5g"); - pi->srom_fem5g.pdetrange = (u8) PHY_GETINTVAR(pi, "pdetrange5g"); - pi->srom_fem5g.triso = (u8) PHY_GETINTVAR(pi, "triso5g"); - if (PHY_GETVAR(pi, "antswctl5g")) { - - pi->srom_fem5g.antswctrllut = - (u8) PHY_GETINTVAR(pi, "antswctl5g"); - } else { - - pi->srom_fem5g.antswctrllut = - (u8) PHY_GETINTVAR(pi, "antswctl2g"); - } - - wlc_phy_txpower_ipa_upd(pi); - - pi->phy_txcore_disable_temp = (s16) PHY_GETINTVAR(pi, "tempthresh"); - if (pi->phy_txcore_disable_temp == 0) { - pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP; - } - - pi->phy_tempsense_offset = (s8) PHY_GETINTVAR(pi, "tempoffset"); - if (pi->phy_tempsense_offset != 0) { - if (pi->phy_tempsense_offset > - (NPHY_SROM_TEMPSHIFT + NPHY_SROM_MAXTEMPOFFSET)) { - pi->phy_tempsense_offset = NPHY_SROM_MAXTEMPOFFSET; - } else if (pi->phy_tempsense_offset < (NPHY_SROM_TEMPSHIFT + - NPHY_SROM_MINTEMPOFFSET)) { - pi->phy_tempsense_offset = NPHY_SROM_MINTEMPOFFSET; - } else { - pi->phy_tempsense_offset -= NPHY_SROM_TEMPSHIFT; - } - } - - pi->phy_txcore_enable_temp = - pi->phy_txcore_disable_temp - PHY_HYSTERESIS_DELTATEMP; - - pi->phycal_tempdelta = (u8) PHY_GETINTVAR(pi, "phycal_tempdelta"); - if (pi->phycal_tempdelta > NPHY_CAL_MAXTEMPDELTA) { - pi->phycal_tempdelta = 0; - } - - wlc_phy_txpwr_srom_read_ppr_nphy(pi); - - return true; -} - -void wlc_phy_txpower_recalc_target_nphy(phy_info_t *pi) -{ - u8 tx_pwr_ctrl_state; - wlc_phy_txpwr_limit_to_tbl_nphy(pi); - wlc_phy_txpwrctrl_pwr_setup_nphy(pi); - - tx_pwr_ctrl_state = pi->nphy_txpwrctrl; - - if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) { - wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK); - (void)R_REG(pi->sh->osh, &pi->regs->maccontrol); - udelay(1); - } - - wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state); - - if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) - wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0); -} - -static void wlc_phy_txpwrctrl_coeff_setup_nphy(phy_info_t *pi) -{ - u32 idx; - u16 iqloCalbuf[7]; - u32 iqcomp, locomp, curr_locomp; - s8 locomp_i, locomp_q; - s8 curr_locomp_i, curr_locomp_q; - u32 tbl_id, tbl_len, tbl_offset; - u32 regval[128]; - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - wlc_phy_table_read_nphy(pi, 15, 7, 80, 16, iqloCalbuf); - - tbl_len = 128; - tbl_offset = 320; - for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL; - tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) { - iqcomp = - (tbl_id == - 26) ? (((u32) (iqloCalbuf[0] & 0x3ff)) << 10) | - (iqloCalbuf[1] & 0x3ff) - : (((u32) (iqloCalbuf[2] & 0x3ff)) << 10) | - (iqloCalbuf[3] & 0x3ff); - - for (idx = 0; idx < tbl_len; idx++) { - regval[idx] = iqcomp; - } - wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32, - regval); - } - - tbl_offset = 448; - for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL; - tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) { - - locomp = - (u32) ((tbl_id == 26) ? iqloCalbuf[5] : iqloCalbuf[6]); - locomp_i = (s8) ((locomp >> 8) & 0xff); - locomp_q = (s8) ((locomp) & 0xff); - for (idx = 0; idx < tbl_len; idx++) { - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - curr_locomp_i = locomp_i; - curr_locomp_q = locomp_q; - } else { - curr_locomp_i = (s8) ((locomp_i * - nphy_tpc_loscale[idx] + - 128) >> 8); - curr_locomp_q = - (s8) ((locomp_q * nphy_tpc_loscale[idx] + - 128) >> 8); - } - curr_locomp = (u32) ((curr_locomp_i & 0xff) << 8); - curr_locomp |= (u32) (curr_locomp_q & 0xff); - regval[idx] = curr_locomp; - } - wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32, - regval); - } - - if (NREV_LT(pi->pubpi.phy_rev, 2)) { - - wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX1, 0xFFFF); - wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX2, 0xFFFF); - } - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); -} - -static void wlc_phy_ipa_internal_tssi_setup_nphy(phy_info_t *pi) -{ - u8 core; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - if (CHSPEC_IS2G(pi->radio_chanspec)) { - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TX_SSI_MASTER, 0x5); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TX_SSI_MUX, 0xe); - - if (pi->pubpi.radiorev != 5) - WRITE_RADIO_REG3(pi, RADIO_2057, TX, - core, TSSIA, 0); - - if (!NREV_IS(pi->pubpi.phy_rev, 7)) { - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, - core, TSSIG, 0x1); - } else { - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, - core, TSSIG, 0x31); - } - } else { - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TX_SSI_MASTER, 0x9); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TX_SSI_MUX, 0xc); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TSSIG, 0); - - if (pi->pubpi.radiorev != 5) { - if (!NREV_IS(pi->pubpi.phy_rev, 7)) { - - WRITE_RADIO_REG3(pi, RADIO_2057, - TX, core, - TSSIA, 0x1); - } else { - - WRITE_RADIO_REG3(pi, RADIO_2057, - TX, core, - TSSIA, 0x31); - } - } - } - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG, - 0); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC, - 0); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM, - 0x3); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1, - 0x0); - } - } else { - WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR31, - (CHSPEC_IS2G(pi->radio_chanspec)) ? 0x128 : - 0x80); - WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR30, 0x0); - WRITE_RADIO_SYN(pi, RADIO_2056, GPIO_MASTER1, 0x29); - - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_VCM_HG, - 0x0); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_IDAC, - 0x0); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_VCM, - 0x3); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TX_AMP_DET, - 0x0); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC1, - 0x8); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC2, - 0x0); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC3, - 0x0); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - TX_SSI_MASTER, 0x5); - - if (pi->pubpi.radiorev != 5) - WRITE_RADIO_REG2(pi, RADIO_2056, TX, - core, TSSIA, 0x0); - if (NREV_GE(pi->pubpi.phy_rev, 5)) { - - WRITE_RADIO_REG2(pi, RADIO_2056, TX, - core, TSSIG, 0x31); - } else { - WRITE_RADIO_REG2(pi, RADIO_2056, TX, - core, TSSIG, 0x11); - } - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - TX_SSI_MUX, 0xe); - } else { - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - TX_SSI_MASTER, 0x9); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - TSSIA, 0x31); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - TSSIG, 0x0); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - TX_SSI_MUX, 0xc); - } - } - } -} - -static void wlc_phy_txpwrctrl_idle_tssi_nphy(phy_info_t *pi) -{ - s32 rssi_buf[4]; - s32 int_val; - - if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi) || PHY_MUTED(pi)) - - return; - - if (PHY_IPA(pi)) { - wlc_phy_ipa_internal_tssi_setup_nphy(pi); - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), - 0, 0x3, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 0); - } - - wlc_phy_stopplayback_nphy(pi); - - wlc_phy_tx_tone_nphy(pi, 4000, 0, 0, 0, false); - - udelay(20); - int_val = - wlc_phy_poll_rssi_nphy(pi, (u8) NPHY_RSSI_SEL_TSSI_2G, rssi_buf, - 1); - wlc_phy_stopplayback_nphy(pi); - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, 0); - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), - 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 1); - } - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - - pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g = - (u8) ((int_val >> 24) & 0xff); - pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g = - (u8) ((int_val >> 24) & 0xff); - - pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g = - (u8) ((int_val >> 8) & 0xff); - pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g = - (u8) ((int_val >> 8) & 0xff); - } else { - pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g = - (u8) ((int_val >> 24) & 0xff); - - pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g = - (u8) ((int_val >> 8) & 0xff); - - pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g = - (u8) ((int_val >> 16) & 0xff); - pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g = - (u8) ((int_val) & 0xff); - } - -} - -static void wlc_phy_txpwrctrl_pwr_setup_nphy(phy_info_t *pi) -{ - u32 idx; - s16 a1[2], b0[2], b1[2]; - s8 target_pwr_qtrdbm[2]; - s32 num, den, pwr_est; - u8 chan_freq_range; - u8 idle_tssi[2]; - u32 tbl_id, tbl_len, tbl_offset; - u32 regval[64]; - u8 core; - - if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) { - wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK); - (void)R_REG(pi->sh->osh, &pi->regs->maccontrol); - udelay(1); - } - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - or_phy_reg(pi, 0x122, (0x1 << 0)); - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - and_phy_reg(pi, 0x1e7, (u16) (~(0x1 << 15))); - } else { - - or_phy_reg(pi, 0x1e7, (0x1 << 15)); - } - - if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) - wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0); - - if (pi->sh->sromrev < 4) { - idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g; - idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g; - target_pwr_qtrdbm[0] = 13 * 4; - target_pwr_qtrdbm[1] = 13 * 4; - a1[0] = -424; - a1[1] = -424; - b0[0] = 5612; - b0[1] = 5612; - b1[1] = -1393; - b1[0] = -1393; - } else { - - chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0); - switch (chan_freq_range) { - case WL_CHAN_FREQ_RANGE_2G: - idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g; - idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g; - target_pwr_qtrdbm[0] = - pi->nphy_pwrctrl_info[0].max_pwr_2g; - target_pwr_qtrdbm[1] = - pi->nphy_pwrctrl_info[1].max_pwr_2g; - a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_a1; - a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_a1; - b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b0; - b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b0; - b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b1; - b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b1; - break; - case WL_CHAN_FREQ_RANGE_5GL: - idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g; - idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g; - target_pwr_qtrdbm[0] = - pi->nphy_pwrctrl_info[0].max_pwr_5gl; - target_pwr_qtrdbm[1] = - pi->nphy_pwrctrl_info[1].max_pwr_5gl; - a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1; - a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1; - b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0; - b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0; - b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1; - b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1; - break; - case WL_CHAN_FREQ_RANGE_5GM: - idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g; - idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g; - target_pwr_qtrdbm[0] = - pi->nphy_pwrctrl_info[0].max_pwr_5gm; - target_pwr_qtrdbm[1] = - pi->nphy_pwrctrl_info[1].max_pwr_5gm; - a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_a1; - a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_a1; - b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b0; - b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b0; - b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b1; - b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b1; - break; - case WL_CHAN_FREQ_RANGE_5GH: - idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g; - idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g; - target_pwr_qtrdbm[0] = - pi->nphy_pwrctrl_info[0].max_pwr_5gh; - target_pwr_qtrdbm[1] = - pi->nphy_pwrctrl_info[1].max_pwr_5gh; - a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1; - a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1; - b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0; - b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0; - b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1; - b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1; - break; - default: - idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g; - idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g; - target_pwr_qtrdbm[0] = 13 * 4; - target_pwr_qtrdbm[1] = 13 * 4; - a1[0] = -424; - a1[1] = -424; - b0[0] = 5612; - b0[1] = 5612; - b1[1] = -1393; - b1[0] = -1393; - break; - } - } - - target_pwr_qtrdbm[0] = (s8) pi->tx_power_max; - target_pwr_qtrdbm[1] = (s8) pi->tx_power_max; - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if (pi->srom_fem2g.tssipos) { - or_phy_reg(pi, 0x1e9, (0x1 << 14)); - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - for (core = 0; core <= 1; core++) { - if (PHY_IPA(pi)) { - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - WRITE_RADIO_REG3(pi, RADIO_2057, - TX, core, - TX_SSI_MUX, - 0xe); - } else { - WRITE_RADIO_REG3(pi, RADIO_2057, - TX, core, - TX_SSI_MUX, - 0xc); - } - } else { - } - } - } else { - if (PHY_IPA(pi)) { - - write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX | - RADIO_2056_TX0, - (CHSPEC_IS5G - (pi-> - radio_chanspec)) ? 0xc : 0xe); - write_radio_reg(pi, - RADIO_2056_TX_TX_SSI_MUX | - RADIO_2056_TX1, - (CHSPEC_IS5G - (pi-> - radio_chanspec)) ? 0xc : 0xe); - } else { - - write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX | - RADIO_2056_TX0, 0x11); - write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX | - RADIO_2056_TX1, 0x11); - } - } - } - - if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) { - wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK); - (void)R_REG(pi->sh->osh, &pi->regs->maccontrol); - udelay(1); - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - mod_phy_reg(pi, 0x1e7, (0x7f << 0), - (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0)); - } else { - mod_phy_reg(pi, 0x1e7, (0x7f << 0), - (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0)); - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - mod_phy_reg(pi, 0x222, (0xff << 0), - (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0)); - } else if (NREV_GT(pi->pubpi.phy_rev, 1)) { - mod_phy_reg(pi, 0x222, (0xff << 0), - (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0)); - } - - if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) - wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0); - - write_phy_reg(pi, 0x1e8, (0x3 << 8) | (240 << 0)); - - write_phy_reg(pi, 0x1e9, - (1 << 15) | (idle_tssi[0] << 0) | (idle_tssi[1] << 8)); - - write_phy_reg(pi, 0x1ea, - (target_pwr_qtrdbm[0] << 0) | - (target_pwr_qtrdbm[1] << 8)); - - tbl_len = 64; - tbl_offset = 0; - for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL; - tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) { - - for (idx = 0; idx < tbl_len; idx++) { - num = - 8 * (16 * b0[tbl_id - 26] + b1[tbl_id - 26] * idx); - den = 32768 + a1[tbl_id - 26] * idx; - pwr_est = max(((4 * num + den / 2) / den), -8); - if (NREV_LT(pi->pubpi.phy_rev, 3)) { - if (idx <= - (uint) (31 - idle_tssi[tbl_id - 26] + 1)) - pwr_est = - max(pwr_est, - target_pwr_qtrdbm[tbl_id - 26] + - 1); - } - regval[idx] = (u32) pwr_est; - } - wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32, - regval); - } - - wlc_phy_txpwr_limit_to_tbl_nphy(pi); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64, 8, - pi->adj_pwr_tbl_nphy); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64, 8, - pi->adj_pwr_tbl_nphy); - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); -} - -static bool wlc_phy_txpwr_ison_nphy(phy_info_t *pi) -{ - return read_phy_reg((pi), 0x1e7) & ((0x1 << 15) | - (0x1 << 14) | (0x1 << 13)); -} - -static u8 wlc_phy_txpwr_idx_cur_get_nphy(phy_info_t *pi, u8 core) -{ - u16 tmp; - tmp = read_phy_reg(pi, ((core == PHY_CORE_0) ? 0x1ed : 0x1ee)); - - tmp = (tmp & (0x7f << 8)) >> 8; - return (u8) tmp; -} - -static void -wlc_phy_txpwr_idx_cur_set_nphy(phy_info_t *pi, u8 idx0, u8 idx1) -{ - mod_phy_reg(pi, 0x1e7, (0x7f << 0), idx0); - - if (NREV_GT(pi->pubpi.phy_rev, 1)) - mod_phy_reg(pi, 0x222, (0xff << 0), idx1); -} - -u16 wlc_phy_txpwr_idx_get_nphy(phy_info_t *pi) -{ - u16 tmp; - u16 pwr_idx[2]; - - if (wlc_phy_txpwr_ison_nphy(pi)) { - pwr_idx[0] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_0); - pwr_idx[1] = wlc_phy_txpwr_idx_cur_get_nphy(pi, PHY_CORE_1); - - tmp = (pwr_idx[0] << 8) | pwr_idx[1]; - } else { - tmp = - ((pi->nphy_txpwrindex[PHY_CORE_0]. - index_internal & 0xff) << 8) | (pi-> - nphy_txpwrindex - [PHY_CORE_1]. - index_internal & 0xff); - } - - return tmp; -} - -void wlc_phy_txpwr_papd_cal_nphy(phy_info_t *pi) -{ - if (PHY_IPA(pi) - && (pi->nphy_force_papd_cal - || (wlc_phy_txpwr_ison_nphy(pi) - && - (((u32) - ABS(wlc_phy_txpwr_idx_cur_get_nphy(pi, 0) - - pi->nphy_papd_tx_gain_at_last_cal[0]) >= 4) - || ((u32) - ABS(wlc_phy_txpwr_idx_cur_get_nphy(pi, 1) - - pi->nphy_papd_tx_gain_at_last_cal[1]) >= 4))))) { - wlc_phy_a4(pi, true); - } -} - -void wlc_phy_txpwrctrl_enable_nphy(phy_info_t *pi, u8 ctrl_type) -{ - u16 mask = 0, val = 0, ishw = 0; - u8 ctr; - uint core; - u32 tbl_offset; - u32 tbl_len; - u16 regval[84]; - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - switch (ctrl_type) { - case PHY_TPC_HW_OFF: - case PHY_TPC_HW_ON: - pi->nphy_txpwrctrl = ctrl_type; - break; - default: - break; - } - - if (ctrl_type == PHY_TPC_HW_OFF) { - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - - if (wlc_phy_txpwr_ison_nphy(pi)) { - for (core = 0; core < pi->pubpi.phy_corenum; - core++) - pi->nphy_txpwr_idx[core] = - wlc_phy_txpwr_idx_cur_get_nphy(pi, - (u8) - core); - } - - } - - tbl_len = 84; - tbl_offset = 64; - for (ctr = 0; ctr < tbl_len; ctr++) { - regval[ctr] = 0; - } - wlc_phy_table_write_nphy(pi, 26, tbl_len, tbl_offset, 16, - regval); - wlc_phy_table_write_nphy(pi, 27, tbl_len, tbl_offset, 16, - regval); - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - - and_phy_reg(pi, 0x1e7, - (u16) (~((0x1 << 15) | - (0x1 << 14) | (0x1 << 13)))); - } else { - and_phy_reg(pi, 0x1e7, - (u16) (~((0x1 << 14) | (0x1 << 13)))); - } - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - or_phy_reg(pi, 0x8f, (0x1 << 8)); - or_phy_reg(pi, 0xa5, (0x1 << 8)); - } else { - or_phy_reg(pi, 0xa5, (0x1 << 14)); - } - - if (NREV_IS(pi->pubpi.phy_rev, 2)) - mod_phy_reg(pi, 0xdc, 0x00ff, 0x53); - else if (NREV_LT(pi->pubpi.phy_rev, 2)) - mod_phy_reg(pi, 0xdc, 0x00ff, 0x5a); - - if (NREV_LT(pi->pubpi.phy_rev, 2) && IS40MHZ(pi)) - wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR, - MHF1_IQSWAP_WAR, WLC_BAND_ALL); - - } else { - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64, - 8, pi->adj_pwr_tbl_nphy); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64, - 8, pi->adj_pwr_tbl_nphy); - - ishw = (ctrl_type == PHY_TPC_HW_ON) ? 0x1 : 0x0; - mask = (0x1 << 14) | (0x1 << 13); - val = (ishw << 14) | (ishw << 13); - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - mask |= (0x1 << 15); - val |= (ishw << 15); - } - - mod_phy_reg(pi, 0x1e7, mask, val); - - if (CHSPEC_IS5G(pi->radio_chanspec)) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x32); - mod_phy_reg(pi, 0x222, (0xff << 0), 0x32); - } else { - mod_phy_reg(pi, 0x1e7, (0x7f << 0), 0x64); - if (NREV_GT(pi->pubpi.phy_rev, 1)) - mod_phy_reg(pi, 0x222, - (0xff << 0), 0x64); - } - } - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if ((pi->nphy_txpwr_idx[0] != 128) - && (pi->nphy_txpwr_idx[1] != 128)) { - wlc_phy_txpwr_idx_cur_set_nphy(pi, - pi-> - nphy_txpwr_idx - [0], - pi-> - nphy_txpwr_idx - [1]); - } - } - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - and_phy_reg(pi, 0x8f, ~(0x1 << 8)); - and_phy_reg(pi, 0xa5, ~(0x1 << 8)); - } else { - and_phy_reg(pi, 0xa5, ~(0x1 << 14)); - } - - if (NREV_IS(pi->pubpi.phy_rev, 2)) - mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b); - else if (NREV_LT(pi->pubpi.phy_rev, 2)) - mod_phy_reg(pi, 0xdc, 0x00ff, 0x40); - - if (NREV_LT(pi->pubpi.phy_rev, 2) && IS40MHZ(pi)) - wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR, - 0x0, WLC_BAND_ALL); - - if (PHY_IPA(pi)) { - mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 2), (0) << 2); - - mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 2), (0) << 2); - - } - - } - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); -} - -void -wlc_phy_txpwr_index_nphy(phy_info_t *pi, u8 core_mask, s8 txpwrindex, - bool restore_cals) -{ - u8 core, txpwrctl_tbl; - u16 tx_ind0, iq_ind0, lo_ind0; - u16 m1m2; - u32 txgain; - u16 rad_gain, dac_gain; - u8 bbmult; - u32 iqcomp; - u16 iqcomp_a, iqcomp_b; - u32 locomp; - u16 tmpval; - u8 tx_pwr_ctrl_state; - s32 rfpwr_offset; - u16 regval[2]; - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - tx_ind0 = 192; - iq_ind0 = 320; - lo_ind0 = 448; - - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - - if ((core_mask & (1 << core)) == 0) { - continue; - } - - txpwrctl_tbl = (core == PHY_CORE_0) ? 26 : 27; - - if (txpwrindex < 0) { - if (pi->nphy_txpwrindex[core].index < 0) { - - continue; - } - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - mod_phy_reg(pi, 0x8f, - (0x1 << 8), - pi->nphy_txpwrindex[core]. - AfectrlOverride); - mod_phy_reg(pi, 0xa5, (0x1 << 8), - pi->nphy_txpwrindex[core]. - AfectrlOverride); - } else { - mod_phy_reg(pi, 0xa5, - (0x1 << 14), - pi->nphy_txpwrindex[core]. - AfectrlOverride); - } - - write_phy_reg(pi, (core == PHY_CORE_0) ? - 0xaa : 0xab, - pi->nphy_txpwrindex[core].AfeCtrlDacGain); - - wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16, - &pi->nphy_txpwrindex[core]. - rad_gain); - - wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2); - m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00); - m1m2 |= ((core == PHY_CORE_0) ? - (pi->nphy_txpwrindex[core].bbmult << 8) : - (pi->nphy_txpwrindex[core].bbmult << 0)); - wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2); - - if (restore_cals) { - - wlc_phy_table_write_nphy(pi, 15, 2, - (80 + 2 * core), 16, - (void *)&pi-> - nphy_txpwrindex[core]. - iqcomp_a); - - wlc_phy_table_write_nphy(pi, 15, 1, (85 + core), - 16, - &pi-> - nphy_txpwrindex[core]. - locomp); - wlc_phy_table_write_nphy(pi, 15, 1, (93 + core), - 16, - (void *)&pi-> - nphy_txpwrindex[core]. - locomp); - } - - wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl); - - pi->nphy_txpwrindex[core].index_internal = - pi->nphy_txpwrindex[core].index_internal_save; - } else { - - if (pi->nphy_txpwrindex[core].index < 0) { - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - mod_phy_reg(pi, 0x8f, - (0x1 << 8), - pi->nphy_txpwrindex[core]. - AfectrlOverride); - mod_phy_reg(pi, 0xa5, (0x1 << 8), - pi->nphy_txpwrindex[core]. - AfectrlOverride); - } else { - pi->nphy_txpwrindex[core]. - AfectrlOverride = - read_phy_reg(pi, 0xa5); - } - - pi->nphy_txpwrindex[core].AfeCtrlDacGain = - read_phy_reg(pi, - (core == - PHY_CORE_0) ? 0xaa : 0xab); - - wlc_phy_table_read_nphy(pi, 7, 1, - (0x110 + core), 16, - &pi-> - nphy_txpwrindex[core]. - rad_gain); - - wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, - &tmpval); - tmpval >>= ((core == PHY_CORE_0) ? 8 : 0); - tmpval &= 0xff; - pi->nphy_txpwrindex[core].bbmult = - (u8) tmpval; - - wlc_phy_table_read_nphy(pi, 15, 2, - (80 + 2 * core), 16, - (void *)&pi-> - nphy_txpwrindex[core]. - iqcomp_a); - - wlc_phy_table_read_nphy(pi, 15, 1, (85 + core), - 16, - (void *)&pi-> - nphy_txpwrindex[core]. - locomp); - - pi->nphy_txpwrindex[core].index_internal_save = - pi->nphy_txpwrindex[core].index_internal; - } - - tx_pwr_ctrl_state = pi->nphy_txpwrctrl; - wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF); - - if (NREV_IS(pi->pubpi.phy_rev, 1)) - wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON); - - wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1, - (tx_ind0 + txpwrindex), 32, - &txgain); - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - rad_gain = - (txgain >> 16) & ((1 << (32 - 16 + 1)) - 1); - } else { - rad_gain = - (txgain >> 16) & ((1 << (28 - 16 + 1)) - 1); - } - dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1); - bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1); - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f : - 0xa5), (0x1 << 8), (0x1 << 8)); - } else { - mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14)); - } - write_phy_reg(pi, (core == PHY_CORE_0) ? - 0xaa : 0xab, dac_gain); - - wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16, - &rad_gain); - - wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2); - m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00); - m1m2 |= - ((core == - PHY_CORE_0) ? (bbmult << 8) : (bbmult << 0)); - - wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2); - - wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1, - (iq_ind0 + txpwrindex), 32, - &iqcomp); - iqcomp_a = (iqcomp >> 10) & ((1 << (19 - 10 + 1)) - 1); - iqcomp_b = (iqcomp >> 0) & ((1 << (9 - 0 + 1)) - 1); - - if (restore_cals) { - regval[0] = (u16) iqcomp_a; - regval[1] = (u16) iqcomp_b; - wlc_phy_table_write_nphy(pi, 15, 2, - (80 + 2 * core), 16, - regval); - } - - wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1, - (lo_ind0 + txpwrindex), 32, - &locomp); - if (restore_cals) { - wlc_phy_table_write_nphy(pi, 15, 1, (85 + core), - 16, &locomp); - } - - if (NREV_IS(pi->pubpi.phy_rev, 1)) - wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF); - - if (PHY_IPA(pi)) { - wlc_phy_table_read_nphy(pi, - (core == - PHY_CORE_0 ? - NPHY_TBL_ID_CORE1TXPWRCTL - : - NPHY_TBL_ID_CORE2TXPWRCTL), - 1, 576 + txpwrindex, 32, - &rfpwr_offset); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1ff << 4), - ((s16) rfpwr_offset) << 4); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 2), (1) << 2); - - } - - wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state); - } - - pi->nphy_txpwrindex[core].index = txpwrindex; - } - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); -} - -void -wlc_phy_txpower_sromlimit_get_nphy(phy_info_t *pi, uint chan, u8 *max_pwr, - u8 txp_rate_idx) -{ - u8 chan_freq_range; - - chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, chan); - switch (chan_freq_range) { - case WL_CHAN_FREQ_RANGE_2G: - *max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx]; - break; - case WL_CHAN_FREQ_RANGE_5GM: - *max_pwr = pi->tx_srom_max_rate_5g_mid[txp_rate_idx]; - break; - case WL_CHAN_FREQ_RANGE_5GL: - *max_pwr = pi->tx_srom_max_rate_5g_low[txp_rate_idx]; - break; - case WL_CHAN_FREQ_RANGE_5GH: - *max_pwr = pi->tx_srom_max_rate_5g_hi[txp_rate_idx]; - break; - default: - ASSERT(0); - *max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx]; - break; - } - - return; -} - -void wlc_phy_stay_in_carriersearch_nphy(phy_info_t *pi, bool enable) -{ - u16 clip_off[] = { 0xffff, 0xffff }; - - ASSERT(0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); - - if (enable) { - if (pi->nphy_deaf_count == 0) { - pi->classifier_state = - wlc_phy_classifier_nphy(pi, 0, 0); - wlc_phy_classifier_nphy(pi, (0x7 << 0), 4); - wlc_phy_clip_det_nphy(pi, 0, pi->clip_state); - wlc_phy_clip_det_nphy(pi, 1, clip_off); - } - - pi->nphy_deaf_count++; - - wlc_phy_resetcca_nphy(pi); - - } else { - ASSERT(pi->nphy_deaf_count > 0); - - pi->nphy_deaf_count--; - - if (pi->nphy_deaf_count == 0) { - wlc_phy_classifier_nphy(pi, (0x7 << 0), - pi->classifier_state); - wlc_phy_clip_det_nphy(pi, 1, pi->clip_state); - } - } -} - -void wlc_nphy_deaf_mode(phy_info_t *pi, bool mode) -{ - wlapi_suspend_mac_and_wait(pi->sh->physhim); - - if (mode) { - if (pi->nphy_deaf_count == 0) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - } else { - if (pi->nphy_deaf_count > 0) - wlc_phy_stay_in_carriersearch_nphy(pi, false); - } - wlapi_enable_mac(pi->sh->physhim); -} diff --git a/drivers/staging/brcm80211/phy/wlc_phy_radio.h b/drivers/staging/brcm80211/phy/wlc_phy_radio.h deleted file mode 100644 index 72176ae2882c..000000000000 --- a/drivers/staging/brcm80211/phy/wlc_phy_radio.h +++ /dev/null @@ -1,1533 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _BCM20XX_H -#define _BCM20XX_H - -#define RADIO_IDCODE 0x01 - -#define RADIO_DEFAULT_CORE 0 - -#define RXC0_RSSI_RST 0x80 -#define RXC0_MODE_RSSI 0x40 -#define RXC0_MODE_OFF 0x20 -#define RXC0_MODE_CM 0x10 -#define RXC0_LAN_LOAD 0x08 -#define RXC0_OFF_ADJ_MASK 0x07 - -#define TXC0_MODE_TXLPF 0x04 -#define TXC0_PA_TSSI_EN 0x02 -#define TXC0_TSSI_EN 0x01 - -#define TXC1_PA_GAIN_MASK 0x60 -#define TXC1_PA_GAIN_3DB 0x40 -#define TXC1_PA_GAIN_2DB 0x20 -#define TXC1_TX_MIX_GAIN 0x10 -#define TXC1_OFF_I_MASK 0x0c -#define TXC1_OFF_Q_MASK 0x03 - -#define RADIO_2055_READ_OFF 0x100 -#define RADIO_2057_READ_OFF 0x200 - -#define RADIO_2055_GEN_SPARE 0x00 -#define RADIO_2055_SP_PIN_PD 0x02 -#define RADIO_2055_SP_RSSI_CORE1 0x03 -#define RADIO_2055_SP_PD_MISC_CORE1 0x04 -#define RADIO_2055_SP_RSSI_CORE2 0x05 -#define RADIO_2055_SP_PD_MISC_CORE2 0x06 -#define RADIO_2055_SP_RX_GC1_CORE1 0x07 -#define RADIO_2055_SP_RX_GC2_CORE1 0x08 -#define RADIO_2055_SP_RX_GC1_CORE2 0x09 -#define RADIO_2055_SP_RX_GC2_CORE2 0x0a -#define RADIO_2055_SP_LPF_BW_SELECT_CORE1 0x0b -#define RADIO_2055_SP_LPF_BW_SELECT_CORE2 0x0c -#define RADIO_2055_SP_TX_GC1_CORE1 0x0d -#define RADIO_2055_SP_TX_GC2_CORE1 0x0e -#define RADIO_2055_SP_TX_GC1_CORE2 0x0f -#define RADIO_2055_SP_TX_GC2_CORE2 0x10 -#define RADIO_2055_MASTER_CNTRL1 0x11 -#define RADIO_2055_MASTER_CNTRL2 0x12 -#define RADIO_2055_PD_LGEN 0x13 -#define RADIO_2055_PD_PLL_TS 0x14 -#define RADIO_2055_PD_CORE1_LGBUF 0x15 -#define RADIO_2055_PD_CORE1_TX 0x16 -#define RADIO_2055_PD_CORE1_RXTX 0x17 -#define RADIO_2055_PD_CORE1_RSSI_MISC 0x18 -#define RADIO_2055_PD_CORE2_LGBUF 0x19 -#define RADIO_2055_PD_CORE2_TX 0x1a -#define RADIO_2055_PD_CORE2_RXTX 0x1b -#define RADIO_2055_PD_CORE2_RSSI_MISC 0x1c -#define RADIO_2055_PWRDET_LGEN 0x1d -#define RADIO_2055_PWRDET_LGBUF_CORE1 0x1e -#define RADIO_2055_PWRDET_RXTX_CORE1 0x1f -#define RADIO_2055_PWRDET_LGBUF_CORE2 0x20 -#define RADIO_2055_PWRDET_RXTX_CORE2 0x21 -#define RADIO_2055_RRCCAL_CNTRL_SPARE 0x22 -#define RADIO_2055_RRCCAL_N_OPT_SEL 0x23 -#define RADIO_2055_CAL_MISC 0x24 -#define RADIO_2055_CAL_COUNTER_OUT 0x25 -#define RADIO_2055_CAL_COUNTER_OUT2 0x26 -#define RADIO_2055_CAL_CVAR_CNTRL 0x27 -#define RADIO_2055_CAL_RVAR_CNTRL 0x28 -#define RADIO_2055_CAL_LPO_CNTRL 0x29 -#define RADIO_2055_CAL_TS 0x2a -#define RADIO_2055_CAL_RCCAL_READ_TS 0x2b -#define RADIO_2055_CAL_RCAL_READ_TS 0x2c -#define RADIO_2055_PAD_DRIVER 0x2d -#define RADIO_2055_XO_CNTRL1 0x2e -#define RADIO_2055_XO_CNTRL2 0x2f -#define RADIO_2055_XO_REGULATOR 0x30 -#define RADIO_2055_XO_MISC 0x31 -#define RADIO_2055_PLL_LF_C1 0x32 -#define RADIO_2055_PLL_CAL_VTH 0x33 -#define RADIO_2055_PLL_LF_C2 0x34 -#define RADIO_2055_PLL_REF 0x35 -#define RADIO_2055_PLL_LF_R1 0x36 -#define RADIO_2055_PLL_PFD_CP 0x37 -#define RADIO_2055_PLL_IDAC_CPOPAMP 0x38 -#define RADIO_2055_PLL_CP_REGULATOR 0x39 -#define RADIO_2055_PLL_RCAL 0x3a -#define RADIO_2055_RF_PLL_MOD0 0x3b -#define RADIO_2055_RF_PLL_MOD1 0x3c -#define RADIO_2055_RF_MMD_IDAC1 0x3d -#define RADIO_2055_RF_MMD_IDAC0 0x3e -#define RADIO_2055_RF_MMD_SPARE 0x3f -#define RADIO_2055_VCO_CAL1 0x40 -#define RADIO_2055_VCO_CAL2 0x41 -#define RADIO_2055_VCO_CAL3 0x42 -#define RADIO_2055_VCO_CAL4 0x43 -#define RADIO_2055_VCO_CAL5 0x44 -#define RADIO_2055_VCO_CAL6 0x45 -#define RADIO_2055_VCO_CAL7 0x46 -#define RADIO_2055_VCO_CAL8 0x47 -#define RADIO_2055_VCO_CAL9 0x48 -#define RADIO_2055_VCO_CAL10 0x49 -#define RADIO_2055_VCO_CAL11 0x4a -#define RADIO_2055_VCO_CAL12 0x4b -#define RADIO_2055_VCO_CAL13 0x4c -#define RADIO_2055_VCO_CAL14 0x4d -#define RADIO_2055_VCO_CAL15 0x4e -#define RADIO_2055_VCO_CAL16 0x4f -#define RADIO_2055_VCO_KVCO 0x50 -#define RADIO_2055_VCO_CAP_TAIL 0x51 -#define RADIO_2055_VCO_IDAC_VCO 0x52 -#define RADIO_2055_VCO_REGULATOR 0x53 -#define RADIO_2055_PLL_RF_VTH 0x54 -#define RADIO_2055_LGBUF_CEN_BUF 0x55 -#define RADIO_2055_LGEN_TUNE1 0x56 -#define RADIO_2055_LGEN_TUNE2 0x57 -#define RADIO_2055_LGEN_IDAC1 0x58 -#define RADIO_2055_LGEN_IDAC2 0x59 -#define RADIO_2055_LGEN_BIAS_CNT 0x5a -#define RADIO_2055_LGEN_BIAS_IDAC 0x5b -#define RADIO_2055_LGEN_RCAL 0x5c -#define RADIO_2055_LGEN_DIV 0x5d -#define RADIO_2055_LGEN_SPARE2 0x5e -#define RADIO_2055_CORE1_LGBUF_A_TUNE 0x5f -#define RADIO_2055_CORE1_LGBUF_G_TUNE 0x60 -#define RADIO_2055_CORE1_LGBUF_DIV 0x61 -#define RADIO_2055_CORE1_LGBUF_A_IDAC 0x62 -#define RADIO_2055_CORE1_LGBUF_G_IDAC 0x63 -#define RADIO_2055_CORE1_LGBUF_IDACFIL_OVR 0x64 -#define RADIO_2055_CORE1_LGBUF_SPARE 0x65 -#define RADIO_2055_CORE1_RXRF_SPC1 0x66 -#define RADIO_2055_CORE1_RXRF_REG1 0x67 -#define RADIO_2055_CORE1_RXRF_REG2 0x68 -#define RADIO_2055_CORE1_RXRF_RCAL 0x69 -#define RADIO_2055_CORE1_RXBB_BUFI_LPFCMP 0x6a -#define RADIO_2055_CORE1_RXBB_LPF 0x6b -#define RADIO_2055_CORE1_RXBB_MIDAC_HIPAS 0x6c -#define RADIO_2055_CORE1_RXBB_VGA1_IDAC 0x6d -#define RADIO_2055_CORE1_RXBB_VGA2_IDAC 0x6e -#define RADIO_2055_CORE1_RXBB_VGA3_IDAC 0x6f -#define RADIO_2055_CORE1_RXBB_BUFO_CTRL 0x70 -#define RADIO_2055_CORE1_RXBB_RCCAL_CTRL 0x71 -#define RADIO_2055_CORE1_RXBB_RSSI_CTRL1 0x72 -#define RADIO_2055_CORE1_RXBB_RSSI_CTRL2 0x73 -#define RADIO_2055_CORE1_RXBB_RSSI_CTRL3 0x74 -#define RADIO_2055_CORE1_RXBB_RSSI_CTRL4 0x75 -#define RADIO_2055_CORE1_RXBB_RSSI_CTRL5 0x76 -#define RADIO_2055_CORE1_RXBB_REGULATOR 0x77 -#define RADIO_2055_CORE1_RXBB_SPARE1 0x78 -#define RADIO_2055_CORE1_RXTXBB_RCAL 0x79 -#define RADIO_2055_CORE1_TXRF_SGM_PGA 0x7a -#define RADIO_2055_CORE1_TXRF_SGM_PAD 0x7b -#define RADIO_2055_CORE1_TXRF_CNTR_PGA1 0x7c -#define RADIO_2055_CORE1_TXRF_CNTR_PAD1 0x7d -#define RADIO_2055_CORE1_TX_RFPGA_IDAC 0x7e -#define RADIO_2055_CORE1_TX_PGA_PAD_TN 0x7f -#define RADIO_2055_CORE1_TX_PAD_IDAC1 0x80 -#define RADIO_2055_CORE1_TX_PAD_IDAC2 0x81 -#define RADIO_2055_CORE1_TX_MX_BGTRIM 0x82 -#define RADIO_2055_CORE1_TXRF_RCAL 0x83 -#define RADIO_2055_CORE1_TXRF_PAD_TSSI1 0x84 -#define RADIO_2055_CORE1_TXRF_PAD_TSSI2 0x85 -#define RADIO_2055_CORE1_TX_RF_SPARE 0x86 -#define RADIO_2055_CORE1_TXRF_IQCAL1 0x87 -#define RADIO_2055_CORE1_TXRF_IQCAL2 0x88 -#define RADIO_2055_CORE1_TXBB_RCCAL_CTRL 0x89 -#define RADIO_2055_CORE1_TXBB_LPF1 0x8a -#define RADIO_2055_CORE1_TX_VOS_CNCL 0x8b -#define RADIO_2055_CORE1_TX_LPF_MXGM_IDAC 0x8c -#define RADIO_2055_CORE1_TX_BB_MXGM 0x8d -#define RADIO_2055_CORE2_LGBUF_A_TUNE 0x8e -#define RADIO_2055_CORE2_LGBUF_G_TUNE 0x8f -#define RADIO_2055_CORE2_LGBUF_DIV 0x90 -#define RADIO_2055_CORE2_LGBUF_A_IDAC 0x91 -#define RADIO_2055_CORE2_LGBUF_G_IDAC 0x92 -#define RADIO_2055_CORE2_LGBUF_IDACFIL_OVR 0x93 -#define RADIO_2055_CORE2_LGBUF_SPARE 0x94 -#define RADIO_2055_CORE2_RXRF_SPC1 0x95 -#define RADIO_2055_CORE2_RXRF_REG1 0x96 -#define RADIO_2055_CORE2_RXRF_REG2 0x97 -#define RADIO_2055_CORE2_RXRF_RCAL 0x98 -#define RADIO_2055_CORE2_RXBB_BUFI_LPFCMP 0x99 -#define RADIO_2055_CORE2_RXBB_LPF 0x9a -#define RADIO_2055_CORE2_RXBB_MIDAC_HIPAS 0x9b -#define RADIO_2055_CORE2_RXBB_VGA1_IDAC 0x9c -#define RADIO_2055_CORE2_RXBB_VGA2_IDAC 0x9d -#define RADIO_2055_CORE2_RXBB_VGA3_IDAC 0x9e -#define RADIO_2055_CORE2_RXBB_BUFO_CTRL 0x9f -#define RADIO_2055_CORE2_RXBB_RCCAL_CTRL 0xa0 -#define RADIO_2055_CORE2_RXBB_RSSI_CTRL1 0xa1 -#define RADIO_2055_CORE2_RXBB_RSSI_CTRL2 0xa2 -#define RADIO_2055_CORE2_RXBB_RSSI_CTRL3 0xa3 -#define RADIO_2055_CORE2_RXBB_RSSI_CTRL4 0xa4 -#define RADIO_2055_CORE2_RXBB_RSSI_CTRL5 0xa5 -#define RADIO_2055_CORE2_RXBB_REGULATOR 0xa6 -#define RADIO_2055_CORE2_RXBB_SPARE1 0xa7 -#define RADIO_2055_CORE2_RXTXBB_RCAL 0xa8 -#define RADIO_2055_CORE2_TXRF_SGM_PGA 0xa9 -#define RADIO_2055_CORE2_TXRF_SGM_PAD 0xaa -#define RADIO_2055_CORE2_TXRF_CNTR_PGA1 0xab -#define RADIO_2055_CORE2_TXRF_CNTR_PAD1 0xac -#define RADIO_2055_CORE2_TX_RFPGA_IDAC 0xad -#define RADIO_2055_CORE2_TX_PGA_PAD_TN 0xae -#define RADIO_2055_CORE2_TX_PAD_IDAC1 0xaf -#define RADIO_2055_CORE2_TX_PAD_IDAC2 0xb0 -#define RADIO_2055_CORE2_TX_MX_BGTRIM 0xb1 -#define RADIO_2055_CORE2_TXRF_RCAL 0xb2 -#define RADIO_2055_CORE2_TXRF_PAD_TSSI1 0xb3 -#define RADIO_2055_CORE2_TXRF_PAD_TSSI2 0xb4 -#define RADIO_2055_CORE2_TX_RF_SPARE 0xb5 -#define RADIO_2055_CORE2_TXRF_IQCAL1 0xb6 -#define RADIO_2055_CORE2_TXRF_IQCAL2 0xb7 -#define RADIO_2055_CORE2_TXBB_RCCAL_CTRL 0xb8 -#define RADIO_2055_CORE2_TXBB_LPF1 0xb9 -#define RADIO_2055_CORE2_TX_VOS_CNCL 0xba -#define RADIO_2055_CORE2_TX_LPF_MXGM_IDAC 0xbb -#define RADIO_2055_CORE2_TX_BB_MXGM 0xbc -#define RADIO_2055_PRG_GC_HPVGA23_21 0xbd -#define RADIO_2055_PRG_GC_HPVGA23_22 0xbe -#define RADIO_2055_PRG_GC_HPVGA23_23 0xbf -#define RADIO_2055_PRG_GC_HPVGA23_24 0xc0 -#define RADIO_2055_PRG_GC_HPVGA23_25 0xc1 -#define RADIO_2055_PRG_GC_HPVGA23_26 0xc2 -#define RADIO_2055_PRG_GC_HPVGA23_27 0xc3 -#define RADIO_2055_PRG_GC_HPVGA23_28 0xc4 -#define RADIO_2055_PRG_GC_HPVGA23_29 0xc5 -#define RADIO_2055_PRG_GC_HPVGA23_30 0xc6 -#define RADIO_2055_CORE1_LNA_GAINBST 0xcd -#define RADIO_2055_CORE1_B0_NBRSSI_VCM 0xd2 -#define RADIO_2055_CORE1_GEN_SPARE2 0xd6 -#define RADIO_2055_CORE2_LNA_GAINBST 0xd9 -#define RADIO_2055_CORE2_B0_NBRSSI_VCM 0xde -#define RADIO_2055_CORE2_GEN_SPARE2 0xe2 - -#define RADIO_2055_GAINBST_GAIN_DB 6 -#define RADIO_2055_GAINBST_CODE 0x6 - -#define RADIO_2055_JTAGCTRL_MASK 0x04 -#define RADIO_2055_JTAGSYNC_MASK 0x08 -#define RADIO_2055_RRCAL_START 0x40 -#define RADIO_2055_RRCAL_RST_N 0x01 -#define RADIO_2055_CAL_LPO_ENABLE 0x80 -#define RADIO_2055_RCAL_DONE 0x80 -#define RADIO_2055_NBRSSI_VCM_I_MASK 0x03 -#define RADIO_2055_NBRSSI_VCM_I_SHIFT 0x00 -#define RADIO_2055_NBRSSI_VCM_Q_MASK 0x03 -#define RADIO_2055_NBRSSI_VCM_Q_SHIFT 0x00 -#define RADIO_2055_WBRSSI_VCM_IQ_MASK 0x0c -#define RADIO_2055_WBRSSI_VCM_IQ_SHIFT 0x02 -#define RADIO_2055_NBRSSI_PD 0x01 -#define RADIO_2055_WBRSSI_G1_PD 0x04 -#define RADIO_2055_WBRSSI_G2_PD 0x02 -#define RADIO_2055_NBRSSI_SEL 0x01 -#define RADIO_2055_WBRSSI_G1_SEL 0x04 -#define RADIO_2055_WBRSSI_G2_SEL 0x02 -#define RADIO_2055_COUPLE_RX_MASK 0x01 -#define RADIO_2055_COUPLE_TX_MASK 0x02 -#define RADIO_2055_GAINBST_DISABLE 0x02 -#define RADIO_2055_GAINBST_VAL_MASK 0x07 -#define RADIO_2055_RXMX_GC_MASK 0x0c - -#define RADIO_MIMO_CORESEL_OFF 0x0 -#define RADIO_MIMO_CORESEL_CORE1 0x1 -#define RADIO_MIMO_CORESEL_CORE2 0x2 -#define RADIO_MIMO_CORESEL_CORE3 0x3 -#define RADIO_MIMO_CORESEL_CORE4 0x4 -#define RADIO_MIMO_CORESEL_ALLRX 0x5 -#define RADIO_MIMO_CORESEL_ALLTX 0x6 -#define RADIO_MIMO_CORESEL_ALLRXTX 0x7 - -#define RADIO_2064_READ_OFF 0x200 - -#define RADIO_2064_REG000 0x0 -#define RADIO_2064_REG001 0x1 -#define RADIO_2064_REG002 0x2 -#define RADIO_2064_REG003 0x3 -#define RADIO_2064_REG004 0x4 -#define RADIO_2064_REG005 0x5 -#define RADIO_2064_REG006 0x6 -#define RADIO_2064_REG007 0x7 -#define RADIO_2064_REG008 0x8 -#define RADIO_2064_REG009 0x9 -#define RADIO_2064_REG00A 0xa -#define RADIO_2064_REG00B 0xb -#define RADIO_2064_REG00C 0xc -#define RADIO_2064_REG00D 0xd -#define RADIO_2064_REG00E 0xe -#define RADIO_2064_REG00F 0xf -#define RADIO_2064_REG010 0x10 -#define RADIO_2064_REG011 0x11 -#define RADIO_2064_REG012 0x12 -#define RADIO_2064_REG013 0x13 -#define RADIO_2064_REG014 0x14 -#define RADIO_2064_REG015 0x15 -#define RADIO_2064_REG016 0x16 -#define RADIO_2064_REG017 0x17 -#define RADIO_2064_REG018 0x18 -#define RADIO_2064_REG019 0x19 -#define RADIO_2064_REG01A 0x1a -#define RADIO_2064_REG01B 0x1b -#define RADIO_2064_REG01C 0x1c -#define RADIO_2064_REG01D 0x1d -#define RADIO_2064_REG01E 0x1e -#define RADIO_2064_REG01F 0x1f -#define RADIO_2064_REG020 0x20 -#define RADIO_2064_REG021 0x21 -#define RADIO_2064_REG022 0x22 -#define RADIO_2064_REG023 0x23 -#define RADIO_2064_REG024 0x24 -#define RADIO_2064_REG025 0x25 -#define RADIO_2064_REG026 0x26 -#define RADIO_2064_REG027 0x27 -#define RADIO_2064_REG028 0x28 -#define RADIO_2064_REG029 0x29 -#define RADIO_2064_REG02A 0x2a -#define RADIO_2064_REG02B 0x2b -#define RADIO_2064_REG02C 0x2c -#define RADIO_2064_REG02D 0x2d -#define RADIO_2064_REG02E 0x2e -#define RADIO_2064_REG02F 0x2f -#define RADIO_2064_REG030 0x30 -#define RADIO_2064_REG031 0x31 -#define RADIO_2064_REG032 0x32 -#define RADIO_2064_REG033 0x33 -#define RADIO_2064_REG034 0x34 -#define RADIO_2064_REG035 0x35 -#define RADIO_2064_REG036 0x36 -#define RADIO_2064_REG037 0x37 -#define RADIO_2064_REG038 0x38 -#define RADIO_2064_REG039 0x39 -#define RADIO_2064_REG03A 0x3a -#define RADIO_2064_REG03B 0x3b -#define RADIO_2064_REG03C 0x3c -#define RADIO_2064_REG03D 0x3d -#define RADIO_2064_REG03E 0x3e -#define RADIO_2064_REG03F 0x3f -#define RADIO_2064_REG040 0x40 -#define RADIO_2064_REG041 0x41 -#define RADIO_2064_REG042 0x42 -#define RADIO_2064_REG043 0x43 -#define RADIO_2064_REG044 0x44 -#define RADIO_2064_REG045 0x45 -#define RADIO_2064_REG046 0x46 -#define RADIO_2064_REG047 0x47 -#define RADIO_2064_REG048 0x48 -#define RADIO_2064_REG049 0x49 -#define RADIO_2064_REG04A 0x4a -#define RADIO_2064_REG04B 0x4b -#define RADIO_2064_REG04C 0x4c -#define RADIO_2064_REG04D 0x4d -#define RADIO_2064_REG04E 0x4e -#define RADIO_2064_REG04F 0x4f -#define RADIO_2064_REG050 0x50 -#define RADIO_2064_REG051 0x51 -#define RADIO_2064_REG052 0x52 -#define RADIO_2064_REG053 0x53 -#define RADIO_2064_REG054 0x54 -#define RADIO_2064_REG055 0x55 -#define RADIO_2064_REG056 0x56 -#define RADIO_2064_REG057 0x57 -#define RADIO_2064_REG058 0x58 -#define RADIO_2064_REG059 0x59 -#define RADIO_2064_REG05A 0x5a -#define RADIO_2064_REG05B 0x5b -#define RADIO_2064_REG05C 0x5c -#define RADIO_2064_REG05D 0x5d -#define RADIO_2064_REG05E 0x5e -#define RADIO_2064_REG05F 0x5f -#define RADIO_2064_REG060 0x60 -#define RADIO_2064_REG061 0x61 -#define RADIO_2064_REG062 0x62 -#define RADIO_2064_REG063 0x63 -#define RADIO_2064_REG064 0x64 -#define RADIO_2064_REG065 0x65 -#define RADIO_2064_REG066 0x66 -#define RADIO_2064_REG067 0x67 -#define RADIO_2064_REG068 0x68 -#define RADIO_2064_REG069 0x69 -#define RADIO_2064_REG06A 0x6a -#define RADIO_2064_REG06B 0x6b -#define RADIO_2064_REG06C 0x6c -#define RADIO_2064_REG06D 0x6d -#define RADIO_2064_REG06E 0x6e -#define RADIO_2064_REG06F 0x6f -#define RADIO_2064_REG070 0x70 -#define RADIO_2064_REG071 0x71 -#define RADIO_2064_REG072 0x72 -#define RADIO_2064_REG073 0x73 -#define RADIO_2064_REG074 0x74 -#define RADIO_2064_REG075 0x75 -#define RADIO_2064_REG076 0x76 -#define RADIO_2064_REG077 0x77 -#define RADIO_2064_REG078 0x78 -#define RADIO_2064_REG079 0x79 -#define RADIO_2064_REG07A 0x7a -#define RADIO_2064_REG07B 0x7b -#define RADIO_2064_REG07C 0x7c -#define RADIO_2064_REG07D 0x7d -#define RADIO_2064_REG07E 0x7e -#define RADIO_2064_REG07F 0x7f -#define RADIO_2064_REG080 0x80 -#define RADIO_2064_REG081 0x81 -#define RADIO_2064_REG082 0x82 -#define RADIO_2064_REG083 0x83 -#define RADIO_2064_REG084 0x84 -#define RADIO_2064_REG085 0x85 -#define RADIO_2064_REG086 0x86 -#define RADIO_2064_REG087 0x87 -#define RADIO_2064_REG088 0x88 -#define RADIO_2064_REG089 0x89 -#define RADIO_2064_REG08A 0x8a -#define RADIO_2064_REG08B 0x8b -#define RADIO_2064_REG08C 0x8c -#define RADIO_2064_REG08D 0x8d -#define RADIO_2064_REG08E 0x8e -#define RADIO_2064_REG08F 0x8f -#define RADIO_2064_REG090 0x90 -#define RADIO_2064_REG091 0x91 -#define RADIO_2064_REG092 0x92 -#define RADIO_2064_REG093 0x93 -#define RADIO_2064_REG094 0x94 -#define RADIO_2064_REG095 0x95 -#define RADIO_2064_REG096 0x96 -#define RADIO_2064_REG097 0x97 -#define RADIO_2064_REG098 0x98 -#define RADIO_2064_REG099 0x99 -#define RADIO_2064_REG09A 0x9a -#define RADIO_2064_REG09B 0x9b -#define RADIO_2064_REG09C 0x9c -#define RADIO_2064_REG09D 0x9d -#define RADIO_2064_REG09E 0x9e -#define RADIO_2064_REG09F 0x9f -#define RADIO_2064_REG0A0 0xa0 -#define RADIO_2064_REG0A1 0xa1 -#define RADIO_2064_REG0A2 0xa2 -#define RADIO_2064_REG0A3 0xa3 -#define RADIO_2064_REG0A4 0xa4 -#define RADIO_2064_REG0A5 0xa5 -#define RADIO_2064_REG0A6 0xa6 -#define RADIO_2064_REG0A7 0xa7 -#define RADIO_2064_REG0A8 0xa8 -#define RADIO_2064_REG0A9 0xa9 -#define RADIO_2064_REG0AA 0xaa -#define RADIO_2064_REG0AB 0xab -#define RADIO_2064_REG0AC 0xac -#define RADIO_2064_REG0AD 0xad -#define RADIO_2064_REG0AE 0xae -#define RADIO_2064_REG0AF 0xaf -#define RADIO_2064_REG0B0 0xb0 -#define RADIO_2064_REG0B1 0xb1 -#define RADIO_2064_REG0B2 0xb2 -#define RADIO_2064_REG0B3 0xb3 -#define RADIO_2064_REG0B4 0xb4 -#define RADIO_2064_REG0B5 0xb5 -#define RADIO_2064_REG0B6 0xb6 -#define RADIO_2064_REG0B7 0xb7 -#define RADIO_2064_REG0B8 0xb8 -#define RADIO_2064_REG0B9 0xb9 -#define RADIO_2064_REG0BA 0xba -#define RADIO_2064_REG0BB 0xbb -#define RADIO_2064_REG0BC 0xbc -#define RADIO_2064_REG0BD 0xbd -#define RADIO_2064_REG0BE 0xbe -#define RADIO_2064_REG0BF 0xbf -#define RADIO_2064_REG0C0 0xc0 -#define RADIO_2064_REG0C1 0xc1 -#define RADIO_2064_REG0C2 0xc2 -#define RADIO_2064_REG0C3 0xc3 -#define RADIO_2064_REG0C4 0xc4 -#define RADIO_2064_REG0C5 0xc5 -#define RADIO_2064_REG0C6 0xc6 -#define RADIO_2064_REG0C7 0xc7 -#define RADIO_2064_REG0C8 0xc8 -#define RADIO_2064_REG0C9 0xc9 -#define RADIO_2064_REG0CA 0xca -#define RADIO_2064_REG0CB 0xcb -#define RADIO_2064_REG0CC 0xcc -#define RADIO_2064_REG0CD 0xcd -#define RADIO_2064_REG0CE 0xce -#define RADIO_2064_REG0CF 0xcf -#define RADIO_2064_REG0D0 0xd0 -#define RADIO_2064_REG0D1 0xd1 -#define RADIO_2064_REG0D2 0xd2 -#define RADIO_2064_REG0D3 0xd3 -#define RADIO_2064_REG0D4 0xd4 -#define RADIO_2064_REG0D5 0xd5 -#define RADIO_2064_REG0D6 0xd6 -#define RADIO_2064_REG0D7 0xd7 -#define RADIO_2064_REG0D8 0xd8 -#define RADIO_2064_REG0D9 0xd9 -#define RADIO_2064_REG0DA 0xda -#define RADIO_2064_REG0DB 0xdb -#define RADIO_2064_REG0DC 0xdc -#define RADIO_2064_REG0DD 0xdd -#define RADIO_2064_REG0DE 0xde -#define RADIO_2064_REG0DF 0xdf -#define RADIO_2064_REG0E0 0xe0 -#define RADIO_2064_REG0E1 0xe1 -#define RADIO_2064_REG0E2 0xe2 -#define RADIO_2064_REG0E3 0xe3 -#define RADIO_2064_REG0E4 0xe4 -#define RADIO_2064_REG0E5 0xe5 -#define RADIO_2064_REG0E6 0xe6 -#define RADIO_2064_REG0E7 0xe7 -#define RADIO_2064_REG0E8 0xe8 -#define RADIO_2064_REG0E9 0xe9 -#define RADIO_2064_REG0EA 0xea -#define RADIO_2064_REG0EB 0xeb -#define RADIO_2064_REG0EC 0xec -#define RADIO_2064_REG0ED 0xed -#define RADIO_2064_REG0EE 0xee -#define RADIO_2064_REG0EF 0xef -#define RADIO_2064_REG0F0 0xf0 -#define RADIO_2064_REG0F1 0xf1 -#define RADIO_2064_REG0F2 0xf2 -#define RADIO_2064_REG0F3 0xf3 -#define RADIO_2064_REG0F4 0xf4 -#define RADIO_2064_REG0F5 0xf5 -#define RADIO_2064_REG0F6 0xf6 -#define RADIO_2064_REG0F7 0xf7 -#define RADIO_2064_REG0F8 0xf8 -#define RADIO_2064_REG0F9 0xf9 -#define RADIO_2064_REG0FA 0xfa -#define RADIO_2064_REG0FB 0xfb -#define RADIO_2064_REG0FC 0xfc -#define RADIO_2064_REG0FD 0xfd -#define RADIO_2064_REG0FE 0xfe -#define RADIO_2064_REG0FF 0xff -#define RADIO_2064_REG100 0x100 -#define RADIO_2064_REG101 0x101 -#define RADIO_2064_REG102 0x102 -#define RADIO_2064_REG103 0x103 -#define RADIO_2064_REG104 0x104 -#define RADIO_2064_REG105 0x105 -#define RADIO_2064_REG106 0x106 -#define RADIO_2064_REG107 0x107 -#define RADIO_2064_REG108 0x108 -#define RADIO_2064_REG109 0x109 -#define RADIO_2064_REG10A 0x10a -#define RADIO_2064_REG10B 0x10b -#define RADIO_2064_REG10C 0x10c -#define RADIO_2064_REG10D 0x10d -#define RADIO_2064_REG10E 0x10e -#define RADIO_2064_REG10F 0x10f -#define RADIO_2064_REG110 0x110 -#define RADIO_2064_REG111 0x111 -#define RADIO_2064_REG112 0x112 -#define RADIO_2064_REG113 0x113 -#define RADIO_2064_REG114 0x114 -#define RADIO_2064_REG115 0x115 -#define RADIO_2064_REG116 0x116 -#define RADIO_2064_REG117 0x117 -#define RADIO_2064_REG118 0x118 -#define RADIO_2064_REG119 0x119 -#define RADIO_2064_REG11A 0x11a -#define RADIO_2064_REG11B 0x11b -#define RADIO_2064_REG11C 0x11c -#define RADIO_2064_REG11D 0x11d -#define RADIO_2064_REG11E 0x11e -#define RADIO_2064_REG11F 0x11f -#define RADIO_2064_REG120 0x120 -#define RADIO_2064_REG121 0x121 -#define RADIO_2064_REG122 0x122 -#define RADIO_2064_REG123 0x123 -#define RADIO_2064_REG124 0x124 -#define RADIO_2064_REG125 0x125 -#define RADIO_2064_REG126 0x126 -#define RADIO_2064_REG127 0x127 -#define RADIO_2064_REG128 0x128 -#define RADIO_2064_REG129 0x129 -#define RADIO_2064_REG12A 0x12a -#define RADIO_2064_REG12B 0x12b -#define RADIO_2064_REG12C 0x12c -#define RADIO_2064_REG12D 0x12d -#define RADIO_2064_REG12E 0x12e -#define RADIO_2064_REG12F 0x12f -#define RADIO_2064_REG130 0x130 - -#define RADIO_2056_SYN (0x0 << 12) -#define RADIO_2056_TX0 (0x2 << 12) -#define RADIO_2056_TX1 (0x3 << 12) -#define RADIO_2056_RX0 (0x6 << 12) -#define RADIO_2056_RX1 (0x7 << 12) -#define RADIO_2056_ALLTX (0xe << 12) -#define RADIO_2056_ALLRX (0xf << 12) - -#define RADIO_2056_SYN_RESERVED_ADDR0 0x0 -#define RADIO_2056_SYN_IDCODE 0x1 -#define RADIO_2056_SYN_RESERVED_ADDR2 0x2 -#define RADIO_2056_SYN_RESERVED_ADDR3 0x3 -#define RADIO_2056_SYN_RESERVED_ADDR4 0x4 -#define RADIO_2056_SYN_RESERVED_ADDR5 0x5 -#define RADIO_2056_SYN_RESERVED_ADDR6 0x6 -#define RADIO_2056_SYN_RESERVED_ADDR7 0x7 -#define RADIO_2056_SYN_COM_CTRL 0x8 -#define RADIO_2056_SYN_COM_PU 0x9 -#define RADIO_2056_SYN_COM_OVR 0xa -#define RADIO_2056_SYN_COM_RESET 0xb -#define RADIO_2056_SYN_COM_RCAL 0xc -#define RADIO_2056_SYN_COM_RC_RXLPF 0xd -#define RADIO_2056_SYN_COM_RC_TXLPF 0xe -#define RADIO_2056_SYN_COM_RC_RXHPF 0xf -#define RADIO_2056_SYN_RESERVED_ADDR16 0x10 -#define RADIO_2056_SYN_RESERVED_ADDR17 0x11 -#define RADIO_2056_SYN_RESERVED_ADDR18 0x12 -#define RADIO_2056_SYN_RESERVED_ADDR19 0x13 -#define RADIO_2056_SYN_RESERVED_ADDR20 0x14 -#define RADIO_2056_SYN_RESERVED_ADDR21 0x15 -#define RADIO_2056_SYN_RESERVED_ADDR22 0x16 -#define RADIO_2056_SYN_RESERVED_ADDR23 0x17 -#define RADIO_2056_SYN_RESERVED_ADDR24 0x18 -#define RADIO_2056_SYN_RESERVED_ADDR25 0x19 -#define RADIO_2056_SYN_RESERVED_ADDR26 0x1a -#define RADIO_2056_SYN_RESERVED_ADDR27 0x1b -#define RADIO_2056_SYN_RESERVED_ADDR28 0x1c -#define RADIO_2056_SYN_RESERVED_ADDR29 0x1d -#define RADIO_2056_SYN_RESERVED_ADDR30 0x1e -#define RADIO_2056_SYN_RESERVED_ADDR31 0x1f -#define RADIO_2056_SYN_GPIO_MASTER1 0x20 -#define RADIO_2056_SYN_GPIO_MASTER2 0x21 -#define RADIO_2056_SYN_TOPBIAS_MASTER 0x22 -#define RADIO_2056_SYN_TOPBIAS_RCAL 0x23 -#define RADIO_2056_SYN_AFEREG 0x24 -#define RADIO_2056_SYN_TEMPPROCSENSE 0x25 -#define RADIO_2056_SYN_TEMPPROCSENSEIDAC 0x26 -#define RADIO_2056_SYN_TEMPPROCSENSERCAL 0x27 -#define RADIO_2056_SYN_LPO 0x28 -#define RADIO_2056_SYN_VDDCAL_MASTER 0x29 -#define RADIO_2056_SYN_VDDCAL_IDAC 0x2a -#define RADIO_2056_SYN_VDDCAL_STATUS 0x2b -#define RADIO_2056_SYN_RCAL_MASTER 0x2c -#define RADIO_2056_SYN_RCAL_CODE_OUT 0x2d -#define RADIO_2056_SYN_RCCAL_CTRL0 0x2e -#define RADIO_2056_SYN_RCCAL_CTRL1 0x2f -#define RADIO_2056_SYN_RCCAL_CTRL2 0x30 -#define RADIO_2056_SYN_RCCAL_CTRL3 0x31 -#define RADIO_2056_SYN_RCCAL_CTRL4 0x32 -#define RADIO_2056_SYN_RCCAL_CTRL5 0x33 -#define RADIO_2056_SYN_RCCAL_CTRL6 0x34 -#define RADIO_2056_SYN_RCCAL_CTRL7 0x35 -#define RADIO_2056_SYN_RCCAL_CTRL8 0x36 -#define RADIO_2056_SYN_RCCAL_CTRL9 0x37 -#define RADIO_2056_SYN_RCCAL_CTRL10 0x38 -#define RADIO_2056_SYN_RCCAL_CTRL11 0x39 -#define RADIO_2056_SYN_ZCAL_SPARE1 0x3a -#define RADIO_2056_SYN_ZCAL_SPARE2 0x3b -#define RADIO_2056_SYN_PLL_MAST1 0x3c -#define RADIO_2056_SYN_PLL_MAST2 0x3d -#define RADIO_2056_SYN_PLL_MAST3 0x3e -#define RADIO_2056_SYN_PLL_BIAS_RESET 0x3f -#define RADIO_2056_SYN_PLL_XTAL0 0x40 -#define RADIO_2056_SYN_PLL_XTAL1 0x41 -#define RADIO_2056_SYN_PLL_XTAL3 0x42 -#define RADIO_2056_SYN_PLL_XTAL4 0x43 -#define RADIO_2056_SYN_PLL_XTAL5 0x44 -#define RADIO_2056_SYN_PLL_XTAL6 0x45 -#define RADIO_2056_SYN_PLL_REFDIV 0x46 -#define RADIO_2056_SYN_PLL_PFD 0x47 -#define RADIO_2056_SYN_PLL_CP1 0x48 -#define RADIO_2056_SYN_PLL_CP2 0x49 -#define RADIO_2056_SYN_PLL_CP3 0x4a -#define RADIO_2056_SYN_PLL_LOOPFILTER1 0x4b -#define RADIO_2056_SYN_PLL_LOOPFILTER2 0x4c -#define RADIO_2056_SYN_PLL_LOOPFILTER3 0x4d -#define RADIO_2056_SYN_PLL_LOOPFILTER4 0x4e -#define RADIO_2056_SYN_PLL_LOOPFILTER5 0x4f -#define RADIO_2056_SYN_PLL_MMD1 0x50 -#define RADIO_2056_SYN_PLL_MMD2 0x51 -#define RADIO_2056_SYN_PLL_VCO1 0x52 -#define RADIO_2056_SYN_PLL_VCO2 0x53 -#define RADIO_2056_SYN_PLL_MONITOR1 0x54 -#define RADIO_2056_SYN_PLL_MONITOR2 0x55 -#define RADIO_2056_SYN_PLL_VCOCAL1 0x56 -#define RADIO_2056_SYN_PLL_VCOCAL2 0x57 -#define RADIO_2056_SYN_PLL_VCOCAL4 0x58 -#define RADIO_2056_SYN_PLL_VCOCAL5 0x59 -#define RADIO_2056_SYN_PLL_VCOCAL6 0x5a -#define RADIO_2056_SYN_PLL_VCOCAL7 0x5b -#define RADIO_2056_SYN_PLL_VCOCAL8 0x5c -#define RADIO_2056_SYN_PLL_VCOCAL9 0x5d -#define RADIO_2056_SYN_PLL_VCOCAL10 0x5e -#define RADIO_2056_SYN_PLL_VCOCAL11 0x5f -#define RADIO_2056_SYN_PLL_VCOCAL12 0x60 -#define RADIO_2056_SYN_PLL_VCOCAL13 0x61 -#define RADIO_2056_SYN_PLL_VREG 0x62 -#define RADIO_2056_SYN_PLL_STATUS1 0x63 -#define RADIO_2056_SYN_PLL_STATUS2 0x64 -#define RADIO_2056_SYN_PLL_STATUS3 0x65 -#define RADIO_2056_SYN_LOGEN_PU0 0x66 -#define RADIO_2056_SYN_LOGEN_PU1 0x67 -#define RADIO_2056_SYN_LOGEN_PU2 0x68 -#define RADIO_2056_SYN_LOGEN_PU3 0x69 -#define RADIO_2056_SYN_LOGEN_PU5 0x6a -#define RADIO_2056_SYN_LOGEN_PU6 0x6b -#define RADIO_2056_SYN_LOGEN_PU7 0x6c -#define RADIO_2056_SYN_LOGEN_PU8 0x6d -#define RADIO_2056_SYN_LOGEN_BIAS_RESET 0x6e -#define RADIO_2056_SYN_LOGEN_RCCR1 0x6f -#define RADIO_2056_SYN_LOGEN_VCOBUF1 0x70 -#define RADIO_2056_SYN_LOGEN_MIXER1 0x71 -#define RADIO_2056_SYN_LOGEN_MIXER2 0x72 -#define RADIO_2056_SYN_LOGEN_BUF1 0x73 -#define RADIO_2056_SYN_LOGENBUF2 0x74 -#define RADIO_2056_SYN_LOGEN_BUF3 0x75 -#define RADIO_2056_SYN_LOGEN_BUF4 0x76 -#define RADIO_2056_SYN_LOGEN_DIV1 0x77 -#define RADIO_2056_SYN_LOGEN_DIV2 0x78 -#define RADIO_2056_SYN_LOGEN_DIV3 0x79 -#define RADIO_2056_SYN_LOGEN_ACL1 0x7a -#define RADIO_2056_SYN_LOGEN_ACL2 0x7b -#define RADIO_2056_SYN_LOGEN_ACL3 0x7c -#define RADIO_2056_SYN_LOGEN_ACL4 0x7d -#define RADIO_2056_SYN_LOGEN_ACL5 0x7e -#define RADIO_2056_SYN_LOGEN_ACL6 0x7f -#define RADIO_2056_SYN_LOGEN_ACLOUT 0x80 -#define RADIO_2056_SYN_LOGEN_ACLCAL1 0x81 -#define RADIO_2056_SYN_LOGEN_ACLCAL2 0x82 -#define RADIO_2056_SYN_LOGEN_ACLCAL3 0x83 -#define RADIO_2056_SYN_CALEN 0x84 -#define RADIO_2056_SYN_LOGEN_PEAKDET1 0x85 -#define RADIO_2056_SYN_LOGEN_CORE_ACL_OVR 0x86 -#define RADIO_2056_SYN_LOGEN_RX_DIFF_ACL_OVR 0x87 -#define RADIO_2056_SYN_LOGEN_TX_DIFF_ACL_OVR 0x88 -#define RADIO_2056_SYN_LOGEN_RX_CMOS_ACL_OVR 0x89 -#define RADIO_2056_SYN_LOGEN_TX_CMOS_ACL_OVR 0x8a -#define RADIO_2056_SYN_LOGEN_VCOBUF2 0x8b -#define RADIO_2056_SYN_LOGEN_MIXER3 0x8c -#define RADIO_2056_SYN_LOGEN_BUF5 0x8d -#define RADIO_2056_SYN_LOGEN_BUF6 0x8e -#define RADIO_2056_SYN_LOGEN_CBUFRX1 0x8f -#define RADIO_2056_SYN_LOGEN_CBUFRX2 0x90 -#define RADIO_2056_SYN_LOGEN_CBUFRX3 0x91 -#define RADIO_2056_SYN_LOGEN_CBUFRX4 0x92 -#define RADIO_2056_SYN_LOGEN_CBUFTX1 0x93 -#define RADIO_2056_SYN_LOGEN_CBUFTX2 0x94 -#define RADIO_2056_SYN_LOGEN_CBUFTX3 0x95 -#define RADIO_2056_SYN_LOGEN_CBUFTX4 0x96 -#define RADIO_2056_SYN_LOGEN_CMOSRX1 0x97 -#define RADIO_2056_SYN_LOGEN_CMOSRX2 0x98 -#define RADIO_2056_SYN_LOGEN_CMOSRX3 0x99 -#define RADIO_2056_SYN_LOGEN_CMOSRX4 0x9a -#define RADIO_2056_SYN_LOGEN_CMOSTX1 0x9b -#define RADIO_2056_SYN_LOGEN_CMOSTX2 0x9c -#define RADIO_2056_SYN_LOGEN_CMOSTX3 0x9d -#define RADIO_2056_SYN_LOGEN_CMOSTX4 0x9e -#define RADIO_2056_SYN_LOGEN_VCOBUF2_OVRVAL 0x9f -#define RADIO_2056_SYN_LOGEN_MIXER3_OVRVAL 0xa0 -#define RADIO_2056_SYN_LOGEN_BUF5_OVRVAL 0xa1 -#define RADIO_2056_SYN_LOGEN_BUF6_OVRVAL 0xa2 -#define RADIO_2056_SYN_LOGEN_CBUFRX1_OVRVAL 0xa3 -#define RADIO_2056_SYN_LOGEN_CBUFRX2_OVRVAL 0xa4 -#define RADIO_2056_SYN_LOGEN_CBUFRX3_OVRVAL 0xa5 -#define RADIO_2056_SYN_LOGEN_CBUFRX4_OVRVAL 0xa6 -#define RADIO_2056_SYN_LOGEN_CBUFTX1_OVRVAL 0xa7 -#define RADIO_2056_SYN_LOGEN_CBUFTX2_OVRVAL 0xa8 -#define RADIO_2056_SYN_LOGEN_CBUFTX3_OVRVAL 0xa9 -#define RADIO_2056_SYN_LOGEN_CBUFTX4_OVRVAL 0xaa -#define RADIO_2056_SYN_LOGEN_CMOSRX1_OVRVAL 0xab -#define RADIO_2056_SYN_LOGEN_CMOSRX2_OVRVAL 0xac -#define RADIO_2056_SYN_LOGEN_CMOSRX3_OVRVAL 0xad -#define RADIO_2056_SYN_LOGEN_CMOSRX4_OVRVAL 0xae -#define RADIO_2056_SYN_LOGEN_CMOSTX1_OVRVAL 0xaf -#define RADIO_2056_SYN_LOGEN_CMOSTX2_OVRVAL 0xb0 -#define RADIO_2056_SYN_LOGEN_CMOSTX3_OVRVAL 0xb1 -#define RADIO_2056_SYN_LOGEN_CMOSTX4_OVRVAL 0xb2 -#define RADIO_2056_SYN_LOGEN_ACL_WAITCNT 0xb3 -#define RADIO_2056_SYN_LOGEN_CORE_CALVALID 0xb4 -#define RADIO_2056_SYN_LOGEN_RX_CMOS_CALVALID 0xb5 -#define RADIO_2056_SYN_LOGEN_TX_CMOS_VALID 0xb6 - -#define RADIO_2056_TX_RESERVED_ADDR0 0x0 -#define RADIO_2056_TX_IDCODE 0x1 -#define RADIO_2056_TX_RESERVED_ADDR2 0x2 -#define RADIO_2056_TX_RESERVED_ADDR3 0x3 -#define RADIO_2056_TX_RESERVED_ADDR4 0x4 -#define RADIO_2056_TX_RESERVED_ADDR5 0x5 -#define RADIO_2056_TX_RESERVED_ADDR6 0x6 -#define RADIO_2056_TX_RESERVED_ADDR7 0x7 -#define RADIO_2056_TX_COM_CTRL 0x8 -#define RADIO_2056_TX_COM_PU 0x9 -#define RADIO_2056_TX_COM_OVR 0xa -#define RADIO_2056_TX_COM_RESET 0xb -#define RADIO_2056_TX_COM_RCAL 0xc -#define RADIO_2056_TX_COM_RC_RXLPF 0xd -#define RADIO_2056_TX_COM_RC_TXLPF 0xe -#define RADIO_2056_TX_COM_RC_RXHPF 0xf -#define RADIO_2056_TX_RESERVED_ADDR16 0x10 -#define RADIO_2056_TX_RESERVED_ADDR17 0x11 -#define RADIO_2056_TX_RESERVED_ADDR18 0x12 -#define RADIO_2056_TX_RESERVED_ADDR19 0x13 -#define RADIO_2056_TX_RESERVED_ADDR20 0x14 -#define RADIO_2056_TX_RESERVED_ADDR21 0x15 -#define RADIO_2056_TX_RESERVED_ADDR22 0x16 -#define RADIO_2056_TX_RESERVED_ADDR23 0x17 -#define RADIO_2056_TX_RESERVED_ADDR24 0x18 -#define RADIO_2056_TX_RESERVED_ADDR25 0x19 -#define RADIO_2056_TX_RESERVED_ADDR26 0x1a -#define RADIO_2056_TX_RESERVED_ADDR27 0x1b -#define RADIO_2056_TX_RESERVED_ADDR28 0x1c -#define RADIO_2056_TX_RESERVED_ADDR29 0x1d -#define RADIO_2056_TX_RESERVED_ADDR30 0x1e -#define RADIO_2056_TX_RESERVED_ADDR31 0x1f -#define RADIO_2056_TX_IQCAL_GAIN_BW 0x20 -#define RADIO_2056_TX_LOFT_FINE_I 0x21 -#define RADIO_2056_TX_LOFT_FINE_Q 0x22 -#define RADIO_2056_TX_LOFT_COARSE_I 0x23 -#define RADIO_2056_TX_LOFT_COARSE_Q 0x24 -#define RADIO_2056_TX_TX_COM_MASTER1 0x25 -#define RADIO_2056_TX_TX_COM_MASTER2 0x26 -#define RADIO_2056_TX_RXIQCAL_TXMUX 0x27 -#define RADIO_2056_TX_TX_SSI_MASTER 0x28 -#define RADIO_2056_TX_IQCAL_VCM_HG 0x29 -#define RADIO_2056_TX_IQCAL_IDAC 0x2a -#define RADIO_2056_TX_TSSI_VCM 0x2b -#define RADIO_2056_TX_TX_AMP_DET 0x2c -#define RADIO_2056_TX_TX_SSI_MUX 0x2d -#define RADIO_2056_TX_TSSIA 0x2e -#define RADIO_2056_TX_TSSIG 0x2f -#define RADIO_2056_TX_TSSI_MISC1 0x30 -#define RADIO_2056_TX_TSSI_MISC2 0x31 -#define RADIO_2056_TX_TSSI_MISC3 0x32 -#define RADIO_2056_TX_PA_SPARE1 0x33 -#define RADIO_2056_TX_PA_SPARE2 0x34 -#define RADIO_2056_TX_INTPAA_MASTER 0x35 -#define RADIO_2056_TX_INTPAA_GAIN 0x36 -#define RADIO_2056_TX_INTPAA_BOOST_TUNE 0x37 -#define RADIO_2056_TX_INTPAA_IAUX_STAT 0x38 -#define RADIO_2056_TX_INTPAA_IAUX_DYN 0x39 -#define RADIO_2056_TX_INTPAA_IMAIN_STAT 0x3a -#define RADIO_2056_TX_INTPAA_IMAIN_DYN 0x3b -#define RADIO_2056_TX_INTPAA_CASCBIAS 0x3c -#define RADIO_2056_TX_INTPAA_PASLOPE 0x3d -#define RADIO_2056_TX_INTPAA_PA_MISC 0x3e -#define RADIO_2056_TX_INTPAG_MASTER 0x3f -#define RADIO_2056_TX_INTPAG_GAIN 0x40 -#define RADIO_2056_TX_INTPAG_BOOST_TUNE 0x41 -#define RADIO_2056_TX_INTPAG_IAUX_STAT 0x42 -#define RADIO_2056_TX_INTPAG_IAUX_DYN 0x43 -#define RADIO_2056_TX_INTPAG_IMAIN_STAT 0x44 -#define RADIO_2056_TX_INTPAG_IMAIN_DYN 0x45 -#define RADIO_2056_TX_INTPAG_CASCBIAS 0x46 -#define RADIO_2056_TX_INTPAG_PASLOPE 0x47 -#define RADIO_2056_TX_INTPAG_PA_MISC 0x48 -#define RADIO_2056_TX_PADA_MASTER 0x49 -#define RADIO_2056_TX_PADA_IDAC 0x4a -#define RADIO_2056_TX_PADA_CASCBIAS 0x4b -#define RADIO_2056_TX_PADA_GAIN 0x4c -#define RADIO_2056_TX_PADA_BOOST_TUNE 0x4d -#define RADIO_2056_TX_PADA_SLOPE 0x4e -#define RADIO_2056_TX_PADG_MASTER 0x4f -#define RADIO_2056_TX_PADG_IDAC 0x50 -#define RADIO_2056_TX_PADG_CASCBIAS 0x51 -#define RADIO_2056_TX_PADG_GAIN 0x52 -#define RADIO_2056_TX_PADG_BOOST_TUNE 0x53 -#define RADIO_2056_TX_PADG_SLOPE 0x54 -#define RADIO_2056_TX_PGAA_MASTER 0x55 -#define RADIO_2056_TX_PGAA_IDAC 0x56 -#define RADIO_2056_TX_PGAA_GAIN 0x57 -#define RADIO_2056_TX_PGAA_BOOST_TUNE 0x58 -#define RADIO_2056_TX_PGAA_SLOPE 0x59 -#define RADIO_2056_TX_PGAA_MISC 0x5a -#define RADIO_2056_TX_PGAG_MASTER 0x5b -#define RADIO_2056_TX_PGAG_IDAC 0x5c -#define RADIO_2056_TX_PGAG_GAIN 0x5d -#define RADIO_2056_TX_PGAG_BOOST_TUNE 0x5e -#define RADIO_2056_TX_PGAG_SLOPE 0x5f -#define RADIO_2056_TX_PGAG_MISC 0x60 -#define RADIO_2056_TX_MIXA_MASTER 0x61 -#define RADIO_2056_TX_MIXA_BOOST_TUNE 0x62 -#define RADIO_2056_TX_MIXG 0x63 -#define RADIO_2056_TX_MIXG_BOOST_TUNE 0x64 -#define RADIO_2056_TX_BB_GM_MASTER 0x65 -#define RADIO_2056_TX_GMBB_GM 0x66 -#define RADIO_2056_TX_GMBB_IDAC 0x67 -#define RADIO_2056_TX_TXLPF_MASTER 0x68 -#define RADIO_2056_TX_TXLPF_RCCAL 0x69 -#define RADIO_2056_TX_TXLPF_RCCAL_OFF0 0x6a -#define RADIO_2056_TX_TXLPF_RCCAL_OFF1 0x6b -#define RADIO_2056_TX_TXLPF_RCCAL_OFF2 0x6c -#define RADIO_2056_TX_TXLPF_RCCAL_OFF3 0x6d -#define RADIO_2056_TX_TXLPF_RCCAL_OFF4 0x6e -#define RADIO_2056_TX_TXLPF_RCCAL_OFF5 0x6f -#define RADIO_2056_TX_TXLPF_RCCAL_OFF6 0x70 -#define RADIO_2056_TX_TXLPF_BW 0x71 -#define RADIO_2056_TX_TXLPF_GAIN 0x72 -#define RADIO_2056_TX_TXLPF_IDAC 0x73 -#define RADIO_2056_TX_TXLPF_IDAC_0 0x74 -#define RADIO_2056_TX_TXLPF_IDAC_1 0x75 -#define RADIO_2056_TX_TXLPF_IDAC_2 0x76 -#define RADIO_2056_TX_TXLPF_IDAC_3 0x77 -#define RADIO_2056_TX_TXLPF_IDAC_4 0x78 -#define RADIO_2056_TX_TXLPF_IDAC_5 0x79 -#define RADIO_2056_TX_TXLPF_IDAC_6 0x7a -#define RADIO_2056_TX_TXLPF_OPAMP_IDAC 0x7b -#define RADIO_2056_TX_TXLPF_MISC 0x7c -#define RADIO_2056_TX_TXSPARE1 0x7d -#define RADIO_2056_TX_TXSPARE2 0x7e -#define RADIO_2056_TX_TXSPARE3 0x7f -#define RADIO_2056_TX_TXSPARE4 0x80 -#define RADIO_2056_TX_TXSPARE5 0x81 -#define RADIO_2056_TX_TXSPARE6 0x82 -#define RADIO_2056_TX_TXSPARE7 0x83 -#define RADIO_2056_TX_TXSPARE8 0x84 -#define RADIO_2056_TX_TXSPARE9 0x85 -#define RADIO_2056_TX_TXSPARE10 0x86 -#define RADIO_2056_TX_TXSPARE11 0x87 -#define RADIO_2056_TX_TXSPARE12 0x88 -#define RADIO_2056_TX_TXSPARE13 0x89 -#define RADIO_2056_TX_TXSPARE14 0x8a -#define RADIO_2056_TX_TXSPARE15 0x8b -#define RADIO_2056_TX_TXSPARE16 0x8c -#define RADIO_2056_TX_STATUS_INTPA_GAIN 0x8d -#define RADIO_2056_TX_STATUS_PAD_GAIN 0x8e -#define RADIO_2056_TX_STATUS_PGA_GAIN 0x8f -#define RADIO_2056_TX_STATUS_GM_TXLPF_GAIN 0x90 -#define RADIO_2056_TX_STATUS_TXLPF_BW 0x91 -#define RADIO_2056_TX_STATUS_TXLPF_RC 0x92 -#define RADIO_2056_TX_GMBB_IDAC0 0x93 -#define RADIO_2056_TX_GMBB_IDAC1 0x94 -#define RADIO_2056_TX_GMBB_IDAC2 0x95 -#define RADIO_2056_TX_GMBB_IDAC3 0x96 -#define RADIO_2056_TX_GMBB_IDAC4 0x97 -#define RADIO_2056_TX_GMBB_IDAC5 0x98 -#define RADIO_2056_TX_GMBB_IDAC6 0x99 -#define RADIO_2056_TX_GMBB_IDAC7 0x9a - -#define RADIO_2056_RX_RESERVED_ADDR0 0x0 -#define RADIO_2056_RX_IDCODE 0x1 -#define RADIO_2056_RX_RESERVED_ADDR2 0x2 -#define RADIO_2056_RX_RESERVED_ADDR3 0x3 -#define RADIO_2056_RX_RESERVED_ADDR4 0x4 -#define RADIO_2056_RX_RESERVED_ADDR5 0x5 -#define RADIO_2056_RX_RESERVED_ADDR6 0x6 -#define RADIO_2056_RX_RESERVED_ADDR7 0x7 -#define RADIO_2056_RX_COM_CTRL 0x8 -#define RADIO_2056_RX_COM_PU 0x9 -#define RADIO_2056_RX_COM_OVR 0xa -#define RADIO_2056_RX_COM_RESET 0xb -#define RADIO_2056_RX_COM_RCAL 0xc -#define RADIO_2056_RX_COM_RC_RXLPF 0xd -#define RADIO_2056_RX_COM_RC_TXLPF 0xe -#define RADIO_2056_RX_COM_RC_RXHPF 0xf -#define RADIO_2056_RX_RESERVED_ADDR16 0x10 -#define RADIO_2056_RX_RESERVED_ADDR17 0x11 -#define RADIO_2056_RX_RESERVED_ADDR18 0x12 -#define RADIO_2056_RX_RESERVED_ADDR19 0x13 -#define RADIO_2056_RX_RESERVED_ADDR20 0x14 -#define RADIO_2056_RX_RESERVED_ADDR21 0x15 -#define RADIO_2056_RX_RESERVED_ADDR22 0x16 -#define RADIO_2056_RX_RESERVED_ADDR23 0x17 -#define RADIO_2056_RX_RESERVED_ADDR24 0x18 -#define RADIO_2056_RX_RESERVED_ADDR25 0x19 -#define RADIO_2056_RX_RESERVED_ADDR26 0x1a -#define RADIO_2056_RX_RESERVED_ADDR27 0x1b -#define RADIO_2056_RX_RESERVED_ADDR28 0x1c -#define RADIO_2056_RX_RESERVED_ADDR29 0x1d -#define RADIO_2056_RX_RESERVED_ADDR30 0x1e -#define RADIO_2056_RX_RESERVED_ADDR31 0x1f -#define RADIO_2056_RX_RXIQCAL_RXMUX 0x20 -#define RADIO_2056_RX_RSSI_PU 0x21 -#define RADIO_2056_RX_RSSI_SEL 0x22 -#define RADIO_2056_RX_RSSI_GAIN 0x23 -#define RADIO_2056_RX_RSSI_NB_IDAC 0x24 -#define RADIO_2056_RX_RSSI_WB2I_IDAC_1 0x25 -#define RADIO_2056_RX_RSSI_WB2I_IDAC_2 0x26 -#define RADIO_2056_RX_RSSI_WB2Q_IDAC_1 0x27 -#define RADIO_2056_RX_RSSI_WB2Q_IDAC_2 0x28 -#define RADIO_2056_RX_RSSI_POLE 0x29 -#define RADIO_2056_RX_RSSI_WB1_IDAC 0x2a -#define RADIO_2056_RX_RSSI_MISC 0x2b -#define RADIO_2056_RX_LNAA_MASTER 0x2c -#define RADIO_2056_RX_LNAA_TUNE 0x2d -#define RADIO_2056_RX_LNAA_GAIN 0x2e -#define RADIO_2056_RX_LNA_A_SLOPE 0x2f -#define RADIO_2056_RX_BIASPOLE_LNAA1_IDAC 0x30 -#define RADIO_2056_RX_LNAA2_IDAC 0x31 -#define RADIO_2056_RX_LNA1A_MISC 0x32 -#define RADIO_2056_RX_LNAG_MASTER 0x33 -#define RADIO_2056_RX_LNAG_TUNE 0x34 -#define RADIO_2056_RX_LNAG_GAIN 0x35 -#define RADIO_2056_RX_LNA_G_SLOPE 0x36 -#define RADIO_2056_RX_BIASPOLE_LNAG1_IDAC 0x37 -#define RADIO_2056_RX_LNAG2_IDAC 0x38 -#define RADIO_2056_RX_LNA1G_MISC 0x39 -#define RADIO_2056_RX_MIXA_MASTER 0x3a -#define RADIO_2056_RX_MIXA_VCM 0x3b -#define RADIO_2056_RX_MIXA_CTRLPTAT 0x3c -#define RADIO_2056_RX_MIXA_LOB_BIAS 0x3d -#define RADIO_2056_RX_MIXA_CORE_IDAC 0x3e -#define RADIO_2056_RX_MIXA_CMFB_IDAC 0x3f -#define RADIO_2056_RX_MIXA_BIAS_AUX 0x40 -#define RADIO_2056_RX_MIXA_BIAS_MAIN 0x41 -#define RADIO_2056_RX_MIXA_BIAS_MISC 0x42 -#define RADIO_2056_RX_MIXA_MAST_BIAS 0x43 -#define RADIO_2056_RX_MIXG_MASTER 0x44 -#define RADIO_2056_RX_MIXG_VCM 0x45 -#define RADIO_2056_RX_MIXG_CTRLPTAT 0x46 -#define RADIO_2056_RX_MIXG_LOB_BIAS 0x47 -#define RADIO_2056_RX_MIXG_CORE_IDAC 0x48 -#define RADIO_2056_RX_MIXG_CMFB_IDAC 0x49 -#define RADIO_2056_RX_MIXG_BIAS_AUX 0x4a -#define RADIO_2056_RX_MIXG_BIAS_MAIN 0x4b -#define RADIO_2056_RX_MIXG_BIAS_MISC 0x4c -#define RADIO_2056_RX_MIXG_MAST_BIAS 0x4d -#define RADIO_2056_RX_TIA_MASTER 0x4e -#define RADIO_2056_RX_TIA_IOPAMP 0x4f -#define RADIO_2056_RX_TIA_QOPAMP 0x50 -#define RADIO_2056_RX_TIA_IMISC 0x51 -#define RADIO_2056_RX_TIA_QMISC 0x52 -#define RADIO_2056_RX_TIA_GAIN 0x53 -#define RADIO_2056_RX_TIA_SPARE1 0x54 -#define RADIO_2056_RX_TIA_SPARE2 0x55 -#define RADIO_2056_RX_BB_LPF_MASTER 0x56 -#define RADIO_2056_RX_AACI_MASTER 0x57 -#define RADIO_2056_RX_RXLPF_IDAC 0x58 -#define RADIO_2056_RX_RXLPF_OPAMPBIAS_LOWQ 0x59 -#define RADIO_2056_RX_RXLPF_OPAMPBIAS_HIGHQ 0x5a -#define RADIO_2056_RX_RXLPF_BIAS_DCCANCEL 0x5b -#define RADIO_2056_RX_RXLPF_OUTVCM 0x5c -#define RADIO_2056_RX_RXLPF_INVCM_BODY 0x5d -#define RADIO_2056_RX_RXLPF_CC_OP 0x5e -#define RADIO_2056_RX_RXLPF_GAIN 0x5f -#define RADIO_2056_RX_RXLPF_Q_BW 0x60 -#define RADIO_2056_RX_RXLPF_HP_CORNER_BW 0x61 -#define RADIO_2056_RX_RXLPF_RCCAL_HPC 0x62 -#define RADIO_2056_RX_RXHPF_OFF0 0x63 -#define RADIO_2056_RX_RXHPF_OFF1 0x64 -#define RADIO_2056_RX_RXHPF_OFF2 0x65 -#define RADIO_2056_RX_RXHPF_OFF3 0x66 -#define RADIO_2056_RX_RXHPF_OFF4 0x67 -#define RADIO_2056_RX_RXHPF_OFF5 0x68 -#define RADIO_2056_RX_RXHPF_OFF6 0x69 -#define RADIO_2056_RX_RXHPF_OFF7 0x6a -#define RADIO_2056_RX_RXLPF_RCCAL_LPC 0x6b -#define RADIO_2056_RX_RXLPF_OFF_0 0x6c -#define RADIO_2056_RX_RXLPF_OFF_1 0x6d -#define RADIO_2056_RX_RXLPF_OFF_2 0x6e -#define RADIO_2056_RX_RXLPF_OFF_3 0x6f -#define RADIO_2056_RX_RXLPF_OFF_4 0x70 -#define RADIO_2056_RX_UNUSED 0x71 -#define RADIO_2056_RX_VGA_MASTER 0x72 -#define RADIO_2056_RX_VGA_BIAS 0x73 -#define RADIO_2056_RX_VGA_BIAS_DCCANCEL 0x74 -#define RADIO_2056_RX_VGA_GAIN 0x75 -#define RADIO_2056_RX_VGA_HP_CORNER_BW 0x76 -#define RADIO_2056_RX_VGABUF_BIAS 0x77 -#define RADIO_2056_RX_VGABUF_GAIN_BW 0x78 -#define RADIO_2056_RX_TXFBMIX_A 0x79 -#define RADIO_2056_RX_TXFBMIX_G 0x7a -#define RADIO_2056_RX_RXSPARE1 0x7b -#define RADIO_2056_RX_RXSPARE2 0x7c -#define RADIO_2056_RX_RXSPARE3 0x7d -#define RADIO_2056_RX_RXSPARE4 0x7e -#define RADIO_2056_RX_RXSPARE5 0x7f -#define RADIO_2056_RX_RXSPARE6 0x80 -#define RADIO_2056_RX_RXSPARE7 0x81 -#define RADIO_2056_RX_RXSPARE8 0x82 -#define RADIO_2056_RX_RXSPARE9 0x83 -#define RADIO_2056_RX_RXSPARE10 0x84 -#define RADIO_2056_RX_RXSPARE11 0x85 -#define RADIO_2056_RX_RXSPARE12 0x86 -#define RADIO_2056_RX_RXSPARE13 0x87 -#define RADIO_2056_RX_RXSPARE14 0x88 -#define RADIO_2056_RX_RXSPARE15 0x89 -#define RADIO_2056_RX_RXSPARE16 0x8a -#define RADIO_2056_RX_STATUS_LNAA_GAIN 0x8b -#define RADIO_2056_RX_STATUS_LNAG_GAIN 0x8c -#define RADIO_2056_RX_STATUS_MIXTIA_GAIN 0x8d -#define RADIO_2056_RX_STATUS_RXLPF_GAIN 0x8e -#define RADIO_2056_RX_STATUS_VGA_BUF_GAIN 0x8f -#define RADIO_2056_RX_STATUS_RXLPF_Q 0x90 -#define RADIO_2056_RX_STATUS_RXLPF_BUF_BW 0x91 -#define RADIO_2056_RX_STATUS_RXLPF_VGA_HPC 0x92 -#define RADIO_2056_RX_STATUS_RXLPF_RC 0x93 -#define RADIO_2056_RX_STATUS_HPC_RC 0x94 - -#define RADIO_2056_LNA1_A_PU 0x01 -#define RADIO_2056_LNA2_A_PU 0x02 -#define RADIO_2056_LNA1_G_PU 0x01 -#define RADIO_2056_LNA2_G_PU 0x02 -#define RADIO_2056_MIXA_PU_I 0x01 -#define RADIO_2056_MIXA_PU_Q 0x02 -#define RADIO_2056_MIXA_PU_GM 0x10 -#define RADIO_2056_MIXG_PU_I 0x01 -#define RADIO_2056_MIXG_PU_Q 0x02 -#define RADIO_2056_MIXG_PU_GM 0x10 -#define RADIO_2056_TIA_PU 0x01 -#define RADIO_2056_BB_LPF_PU 0x20 -#define RADIO_2056_W1_PU 0x02 -#define RADIO_2056_W2_PU 0x04 -#define RADIO_2056_NB_PU 0x08 -#define RADIO_2056_RSSI_W1_SEL 0x02 -#define RADIO_2056_RSSI_W2_SEL 0x04 -#define RADIO_2056_RSSI_NB_SEL 0x08 -#define RADIO_2056_VCM_MASK 0x1c -#define RADIO_2056_RSSI_VCM_SHIFT 0x02 - -#define RADIO_2057_DACBUF_VINCM_CORE0 0x0 -#define RADIO_2057_IDCODE 0x1 -#define RADIO_2057_RCCAL_MASTER 0x2 -#define RADIO_2057_RCCAL_CAP_SIZE 0x3 -#define RADIO_2057_RCAL_CONFIG 0x4 -#define RADIO_2057_GPAIO_CONFIG 0x5 -#define RADIO_2057_GPAIO_SEL1 0x6 -#define RADIO_2057_GPAIO_SEL0 0x7 -#define RADIO_2057_CLPO_CONFIG 0x8 -#define RADIO_2057_BANDGAP_CONFIG 0x9 -#define RADIO_2057_BANDGAP_RCAL_TRIM 0xa -#define RADIO_2057_AFEREG_CONFIG 0xb -#define RADIO_2057_TEMPSENSE_CONFIG 0xc -#define RADIO_2057_XTAL_CONFIG1 0xd -#define RADIO_2057_XTAL_ICORE_SIZE 0xe -#define RADIO_2057_XTAL_BUF_SIZE 0xf -#define RADIO_2057_XTAL_PULLCAP_SIZE 0x10 -#define RADIO_2057_RFPLL_MASTER 0x11 -#define RADIO_2057_VCOMONITOR_VTH_L 0x12 -#define RADIO_2057_VCOMONITOR_VTH_H 0x13 -#define RADIO_2057_VCOCAL_BIASRESET_RFPLLREG_VOUT 0x14 -#define RADIO_2057_VCO_VARCSIZE_IDAC 0x15 -#define RADIO_2057_VCOCAL_COUNTVAL0 0x16 -#define RADIO_2057_VCOCAL_COUNTVAL1 0x17 -#define RADIO_2057_VCOCAL_INTCLK_COUNT 0x18 -#define RADIO_2057_VCOCAL_MASTER 0x19 -#define RADIO_2057_VCOCAL_NUMCAPCHANGE 0x1a -#define RADIO_2057_VCOCAL_WINSIZE 0x1b -#define RADIO_2057_VCOCAL_DELAY_AFTER_REFRESH 0x1c -#define RADIO_2057_VCOCAL_DELAY_AFTER_CLOSELOOP 0x1d -#define RADIO_2057_VCOCAL_DELAY_AFTER_OPENLOOP 0x1e -#define RADIO_2057_VCOCAL_DELAY_BEFORE_OPENLOOP 0x1f -#define RADIO_2057_VCO_FORCECAPEN_FORCECAP1 0x20 -#define RADIO_2057_VCO_FORCECAP0 0x21 -#define RADIO_2057_RFPLL_REFMASTER_SPAREXTALSIZE 0x22 -#define RADIO_2057_RFPLL_PFD_RESET_PW 0x23 -#define RADIO_2057_RFPLL_LOOPFILTER_R2 0x24 -#define RADIO_2057_RFPLL_LOOPFILTER_R1 0x25 -#define RADIO_2057_RFPLL_LOOPFILTER_C3 0x26 -#define RADIO_2057_RFPLL_LOOPFILTER_C2 0x27 -#define RADIO_2057_RFPLL_LOOPFILTER_C1 0x28 -#define RADIO_2057_CP_KPD_IDAC 0x29 -#define RADIO_2057_RFPLL_IDACS 0x2a -#define RADIO_2057_RFPLL_MISC_EN 0x2b -#define RADIO_2057_RFPLL_MMD0 0x2c -#define RADIO_2057_RFPLL_MMD1 0x2d -#define RADIO_2057_RFPLL_MISC_CAL_RESETN 0x2e -#define RADIO_2057_JTAGXTAL_SIZE_CPBIAS_FILTRES 0x2f -#define RADIO_2057_VCO_ALCREF_BBPLLXTAL_SIZE 0x30 -#define RADIO_2057_VCOCAL_READCAP0 0x31 -#define RADIO_2057_VCOCAL_READCAP1 0x32 -#define RADIO_2057_VCOCAL_STATUS 0x33 -#define RADIO_2057_LOGEN_PUS 0x34 -#define RADIO_2057_LOGEN_PTAT_RESETS 0x35 -#define RADIO_2057_VCOBUF_IDACS 0x36 -#define RADIO_2057_VCOBUF_TUNE 0x37 -#define RADIO_2057_CMOSBUF_TX2GQ_IDACS 0x38 -#define RADIO_2057_CMOSBUF_TX2GI_IDACS 0x39 -#define RADIO_2057_CMOSBUF_TX5GQ_IDACS 0x3a -#define RADIO_2057_CMOSBUF_TX5GI_IDACS 0x3b -#define RADIO_2057_CMOSBUF_RX2GQ_IDACS 0x3c -#define RADIO_2057_CMOSBUF_RX2GI_IDACS 0x3d -#define RADIO_2057_CMOSBUF_RX5GQ_IDACS 0x3e -#define RADIO_2057_CMOSBUF_RX5GI_IDACS 0x3f -#define RADIO_2057_LOGEN_MX2G_IDACS 0x40 -#define RADIO_2057_LOGEN_MX2G_TUNE 0x41 -#define RADIO_2057_LOGEN_MX5G_IDACS 0x42 -#define RADIO_2057_LOGEN_MX5G_TUNE 0x43 -#define RADIO_2057_LOGEN_MX5G_RCCR 0x44 -#define RADIO_2057_LOGEN_INDBUF2G_IDAC 0x45 -#define RADIO_2057_LOGEN_INDBUF2G_IBOOST 0x46 -#define RADIO_2057_LOGEN_INDBUF2G_TUNE 0x47 -#define RADIO_2057_LOGEN_INDBUF5G_IDAC 0x48 -#define RADIO_2057_LOGEN_INDBUF5G_IBOOST 0x49 -#define RADIO_2057_LOGEN_INDBUF5G_TUNE 0x4a -#define RADIO_2057_CMOSBUF_TX_RCCR 0x4b -#define RADIO_2057_CMOSBUF_RX_RCCR 0x4c -#define RADIO_2057_LOGEN_SEL_PKDET 0x4d -#define RADIO_2057_CMOSBUF_SHAREIQ_PTAT 0x4e -#define RADIO_2057_RXTXBIAS_CONFIG_CORE0 0x4f -#define RADIO_2057_TXGM_TXRF_PUS_CORE0 0x50 -#define RADIO_2057_TXGM_IDAC_BLEED_CORE0 0x51 -#define RADIO_2057_TXGM_GAIN_CORE0 0x56 -#define RADIO_2057_TXGM2G_PKDET_PUS_CORE0 0x57 -#define RADIO_2057_PAD2G_PTATS_CORE0 0x58 -#define RADIO_2057_PAD2G_IDACS_CORE0 0x59 -#define RADIO_2057_PAD2G_BOOST_PU_CORE0 0x5a -#define RADIO_2057_PAD2G_CASCV_GAIN_CORE0 0x5b -#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE0 0x5c -#define RADIO_2057_TXMIX2G_LODC_CORE0 0x5d -#define RADIO_2057_PAD2G_TUNE_PUS_CORE0 0x5e -#define RADIO_2057_IPA2G_GAIN_CORE0 0x5f -#define RADIO_2057_TSSI2G_SPARE1_CORE0 0x60 -#define RADIO_2057_TSSI2G_SPARE2_CORE0 0x61 -#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE0 0x62 -#define RADIO_2057_IPA2G_IMAIN_CORE0 0x63 -#define RADIO_2057_IPA2G_CASCONV_CORE0 0x64 -#define RADIO_2057_IPA2G_CASCOFFV_CORE0 0x65 -#define RADIO_2057_IPA2G_BIAS_FILTER_CORE0 0x66 -#define RADIO_2057_TX5G_PKDET_CORE0 0x69 -#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE0 0x6a -#define RADIO_2057_PAD5G_PTATS1_CORE0 0x6b -#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE0 0x6c -#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE0 0x6d -#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE0 0x6e -#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE0 0x6f -#define RADIO_2057_PGA_BOOST_TUNE_CORE0 0x70 -#define RADIO_2057_PGA_GAIN_CORE0 0x71 -#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE0 0x72 -#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE0 0x73 -#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE0 0x74 -#define RADIO_2057_IPA5G_IAUX_CORE0 0x75 -#define RADIO_2057_IPA5G_GAIN_CORE0 0x76 -#define RADIO_2057_TSSI5G_SPARE1_CORE0 0x77 -#define RADIO_2057_TSSI5G_SPARE2_CORE0 0x78 -#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE0 0x79 -#define RADIO_2057_IPA5G_PTAT_CORE0 0x7a -#define RADIO_2057_IPA5G_IMAIN_CORE0 0x7b -#define RADIO_2057_IPA5G_CASCONV_CORE0 0x7c -#define RADIO_2057_IPA5G_BIAS_FILTER_CORE0 0x7d -#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE0 0x80 -#define RADIO_2057_TR2G_CONFIG1_CORE0_NU 0x81 -#define RADIO_2057_TR2G_CONFIG2_CORE0_NU 0x82 -#define RADIO_2057_LNA5G_RFEN_CORE0 0x83 -#define RADIO_2057_TR5G_CONFIG2_CORE0_NU 0x84 -#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE0 0x85 -#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE0 0x86 -#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE0 0x87 -#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE0 0x88 -#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE0 0x89 -#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE0 0x8a -#define RADIO_2057_LNA2_IAUX_PTAT_CORE0 0x8b -#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE0 0x8c -#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE0 0x8d -#define RADIO_2057_RXRFBIAS_BANDSEL_CORE0 0x8e -#define RADIO_2057_TIA_CONFIG_CORE0 0x8f -#define RADIO_2057_TIA_IQGAIN_CORE0 0x90 -#define RADIO_2057_TIA_IBIAS2_CORE0 0x91 -#define RADIO_2057_TIA_IBIAS1_CORE0 0x92 -#define RADIO_2057_TIA_SPARE_Q_CORE0 0x93 -#define RADIO_2057_TIA_SPARE_I_CORE0 0x94 -#define RADIO_2057_RXMIX2G_PUS_CORE0 0x95 -#define RADIO_2057_RXMIX2G_VCMREFS_CORE0 0x96 -#define RADIO_2057_RXMIX2G_LODC_QI_CORE0 0x97 -#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE0 0x98 -#define RADIO_2057_LNA2G_GAIN_CORE0 0x99 -#define RADIO_2057_LNA2G_TUNE_CORE0 0x9a -#define RADIO_2057_RXMIX5G_PUS_CORE0 0x9b -#define RADIO_2057_RXMIX5G_VCMREFS_CORE0 0x9c -#define RADIO_2057_RXMIX5G_LODC_QI_CORE0 0x9d -#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE0 0x9e -#define RADIO_2057_LNA5G_GAIN_CORE0 0x9f -#define RADIO_2057_LNA5G_TUNE_CORE0 0xa0 -#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE0 0xa1 -#define RADIO_2057_RXBB_BIAS_MASTER_CORE0 0xa2 -#define RADIO_2057_RXBB_VGABUF_IDACS_CORE0 0xa3 -#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE0 0xa4 -#define RADIO_2057_TXBUF_VINCM_CORE0 0xa5 -#define RADIO_2057_TXBUF_IDACS_CORE0 0xa6 -#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE0 0xa7 -#define RADIO_2057_RXBB_CC_CORE0 0xa8 -#define RADIO_2057_RXBB_SPARE3_CORE0 0xa9 -#define RADIO_2057_RXBB_RCCAL_HPC_CORE0 0xaa -#define RADIO_2057_LPF_IDACS_CORE0 0xab -#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE0 0xac -#define RADIO_2057_TXBUF_GAIN_CORE0 0xad -#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE0 0xae -#define RADIO_2057_RXBUF_DEGEN_CORE0 0xaf -#define RADIO_2057_RXBB_SPARE2_CORE0 0xb0 -#define RADIO_2057_RXBB_SPARE1_CORE0 0xb1 -#define RADIO_2057_RSSI_MASTER_CORE0 0xb2 -#define RADIO_2057_W2_MASTER_CORE0 0xb3 -#define RADIO_2057_NB_MASTER_CORE0 0xb4 -#define RADIO_2057_W2_IDACS0_Q_CORE0 0xb5 -#define RADIO_2057_W2_IDACS1_Q_CORE0 0xb6 -#define RADIO_2057_W2_IDACS0_I_CORE0 0xb7 -#define RADIO_2057_W2_IDACS1_I_CORE0 0xb8 -#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE0 0xb9 -#define RADIO_2057_NB_IDACS_Q_CORE0 0xba -#define RADIO_2057_NB_IDACS_I_CORE0 0xbb -#define RADIO_2057_BACKUP4_CORE0 0xc1 -#define RADIO_2057_BACKUP3_CORE0 0xc2 -#define RADIO_2057_BACKUP2_CORE0 0xc3 -#define RADIO_2057_BACKUP1_CORE0 0xc4 -#define RADIO_2057_SPARE16_CORE0 0xc5 -#define RADIO_2057_SPARE15_CORE0 0xc6 -#define RADIO_2057_SPARE14_CORE0 0xc7 -#define RADIO_2057_SPARE13_CORE0 0xc8 -#define RADIO_2057_SPARE12_CORE0 0xc9 -#define RADIO_2057_SPARE11_CORE0 0xca -#define RADIO_2057_TX2G_BIAS_RESETS_CORE0 0xcb -#define RADIO_2057_TX5G_BIAS_RESETS_CORE0 0xcc -#define RADIO_2057_IQTEST_SEL_PU 0xcd -#define RADIO_2057_XTAL_CONFIG2 0xce -#define RADIO_2057_BUFS_MISC_LPFBW_CORE0 0xcf -#define RADIO_2057_TXLPF_RCCAL_CORE0 0xd0 -#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE0 0xd1 -#define RADIO_2057_LPF_GAIN_CORE0 0xd2 -#define RADIO_2057_DACBUF_IDACS_BW_CORE0 0xd3 -#define RADIO_2057_RXTXBIAS_CONFIG_CORE1 0xd4 -#define RADIO_2057_TXGM_TXRF_PUS_CORE1 0xd5 -#define RADIO_2057_TXGM_IDAC_BLEED_CORE1 0xd6 -#define RADIO_2057_TXGM_GAIN_CORE1 0xdb -#define RADIO_2057_TXGM2G_PKDET_PUS_CORE1 0xdc -#define RADIO_2057_PAD2G_PTATS_CORE1 0xdd -#define RADIO_2057_PAD2G_IDACS_CORE1 0xde -#define RADIO_2057_PAD2G_BOOST_PU_CORE1 0xdf -#define RADIO_2057_PAD2G_CASCV_GAIN_CORE1 0xe0 -#define RADIO_2057_TXMIX2G_TUNE_BOOST_PU_CORE1 0xe1 -#define RADIO_2057_TXMIX2G_LODC_CORE1 0xe2 -#define RADIO_2057_PAD2G_TUNE_PUS_CORE1 0xe3 -#define RADIO_2057_IPA2G_GAIN_CORE1 0xe4 -#define RADIO_2057_TSSI2G_SPARE1_CORE1 0xe5 -#define RADIO_2057_TSSI2G_SPARE2_CORE1 0xe6 -#define RADIO_2057_IPA2G_TUNEV_CASCV_PTAT_CORE1 0xe7 -#define RADIO_2057_IPA2G_IMAIN_CORE1 0xe8 -#define RADIO_2057_IPA2G_CASCONV_CORE1 0xe9 -#define RADIO_2057_IPA2G_CASCOFFV_CORE1 0xea -#define RADIO_2057_IPA2G_BIAS_FILTER_CORE1 0xeb -#define RADIO_2057_TX5G_PKDET_CORE1 0xee -#define RADIO_2057_PGA_PTAT_TXGM5G_PU_CORE1 0xef -#define RADIO_2057_PAD5G_PTATS1_CORE1 0xf0 -#define RADIO_2057_PAD5G_CLASS_PTATS2_CORE1 0xf1 -#define RADIO_2057_PGA_BOOSTPTAT_IMAIN_CORE1 0xf2 -#define RADIO_2057_PAD5G_CASCV_IMAIN_CORE1 0xf3 -#define RADIO_2057_TXMIX5G_IBOOST_PAD_IAUX_CORE1 0xf4 -#define RADIO_2057_PGA_BOOST_TUNE_CORE1 0xf5 -#define RADIO_2057_PGA_GAIN_CORE1 0xf6 -#define RADIO_2057_PAD5G_CASCOFFV_GAIN_PUS_CORE1 0xf7 -#define RADIO_2057_TXMIX5G_BOOST_TUNE_CORE1 0xf8 -#define RADIO_2057_PAD5G_TUNE_MISC_PUS_CORE1 0xf9 -#define RADIO_2057_IPA5G_IAUX_CORE1 0xfa -#define RADIO_2057_IPA5G_GAIN_CORE1 0xfb -#define RADIO_2057_TSSI5G_SPARE1_CORE1 0xfc -#define RADIO_2057_TSSI5G_SPARE2_CORE1 0xfd -#define RADIO_2057_IPA5G_CASCOFFV_PU_CORE1 0xfe -#define RADIO_2057_IPA5G_PTAT_CORE1 0xff -#define RADIO_2057_IPA5G_IMAIN_CORE1 0x100 -#define RADIO_2057_IPA5G_CASCONV_CORE1 0x101 -#define RADIO_2057_IPA5G_BIAS_FILTER_CORE1 0x102 -#define RADIO_2057_PAD_BIAS_FILTER_BWS_CORE1 0x105 -#define RADIO_2057_TR2G_CONFIG1_CORE1_NU 0x106 -#define RADIO_2057_TR2G_CONFIG2_CORE1_NU 0x107 -#define RADIO_2057_LNA5G_RFEN_CORE1 0x108 -#define RADIO_2057_TR5G_CONFIG2_CORE1_NU 0x109 -#define RADIO_2057_RXRFBIAS_IBOOST_PU_CORE1 0x10a -#define RADIO_2057_RXRF_IABAND_RXGM_IMAIN_PTAT_CORE1 0x10b -#define RADIO_2057_RXGM_CMFBITAIL_AUXPTAT_CORE1 0x10c -#define RADIO_2057_RXMIX_ICORE_RXGM_IAUX_CORE1 0x10d -#define RADIO_2057_RXMIX_CMFBITAIL_PU_CORE1 0x10e -#define RADIO_2057_LNA2_IMAIN_PTAT_PU_CORE1 0x10f -#define RADIO_2057_LNA2_IAUX_PTAT_CORE1 0x110 -#define RADIO_2057_LNA1_IMAIN_PTAT_PU_CORE1 0x111 -#define RADIO_2057_LNA15G_INPUT_MATCH_TUNE_CORE1 0x112 -#define RADIO_2057_RXRFBIAS_BANDSEL_CORE1 0x113 -#define RADIO_2057_TIA_CONFIG_CORE1 0x114 -#define RADIO_2057_TIA_IQGAIN_CORE1 0x115 -#define RADIO_2057_TIA_IBIAS2_CORE1 0x116 -#define RADIO_2057_TIA_IBIAS1_CORE1 0x117 -#define RADIO_2057_TIA_SPARE_Q_CORE1 0x118 -#define RADIO_2057_TIA_SPARE_I_CORE1 0x119 -#define RADIO_2057_RXMIX2G_PUS_CORE1 0x11a -#define RADIO_2057_RXMIX2G_VCMREFS_CORE1 0x11b -#define RADIO_2057_RXMIX2G_LODC_QI_CORE1 0x11c -#define RADIO_2057_W12G_BW_LNA2G_PUS_CORE1 0x11d -#define RADIO_2057_LNA2G_GAIN_CORE1 0x11e -#define RADIO_2057_LNA2G_TUNE_CORE1 0x11f -#define RADIO_2057_RXMIX5G_PUS_CORE1 0x120 -#define RADIO_2057_RXMIX5G_VCMREFS_CORE1 0x121 -#define RADIO_2057_RXMIX5G_LODC_QI_CORE1 0x122 -#define RADIO_2057_W15G_BW_LNA5G_PUS_CORE1 0x123 -#define RADIO_2057_LNA5G_GAIN_CORE1 0x124 -#define RADIO_2057_LNA5G_TUNE_CORE1 0x125 -#define RADIO_2057_LPFSEL_TXRX_RXBB_PUS_CORE1 0x126 -#define RADIO_2057_RXBB_BIAS_MASTER_CORE1 0x127 -#define RADIO_2057_RXBB_VGABUF_IDACS_CORE1 0x128 -#define RADIO_2057_LPF_VCMREF_TXBUF_VCMREF_CORE1 0x129 -#define RADIO_2057_TXBUF_VINCM_CORE1 0x12a -#define RADIO_2057_TXBUF_IDACS_CORE1 0x12b -#define RADIO_2057_LPF_RESP_RXBUF_BW_CORE1 0x12c -#define RADIO_2057_RXBB_CC_CORE1 0x12d -#define RADIO_2057_RXBB_SPARE3_CORE1 0x12e -#define RADIO_2057_RXBB_RCCAL_HPC_CORE1 0x12f -#define RADIO_2057_LPF_IDACS_CORE1 0x130 -#define RADIO_2057_LPFBYP_DCLOOP_BYP_IDAC_CORE1 0x131 -#define RADIO_2057_TXBUF_GAIN_CORE1 0x132 -#define RADIO_2057_AFELOOPBACK_AACI_RESP_CORE1 0x133 -#define RADIO_2057_RXBUF_DEGEN_CORE1 0x134 -#define RADIO_2057_RXBB_SPARE2_CORE1 0x135 -#define RADIO_2057_RXBB_SPARE1_CORE1 0x136 -#define RADIO_2057_RSSI_MASTER_CORE1 0x137 -#define RADIO_2057_W2_MASTER_CORE1 0x138 -#define RADIO_2057_NB_MASTER_CORE1 0x139 -#define RADIO_2057_W2_IDACS0_Q_CORE1 0x13a -#define RADIO_2057_W2_IDACS1_Q_CORE1 0x13b -#define RADIO_2057_W2_IDACS0_I_CORE1 0x13c -#define RADIO_2057_W2_IDACS1_I_CORE1 0x13d -#define RADIO_2057_RSSI_GPAIOSEL_W1_IDACS_CORE1 0x13e -#define RADIO_2057_NB_IDACS_Q_CORE1 0x13f -#define RADIO_2057_NB_IDACS_I_CORE1 0x140 -#define RADIO_2057_BACKUP4_CORE1 0x146 -#define RADIO_2057_BACKUP3_CORE1 0x147 -#define RADIO_2057_BACKUP2_CORE1 0x148 -#define RADIO_2057_BACKUP1_CORE1 0x149 -#define RADIO_2057_SPARE16_CORE1 0x14a -#define RADIO_2057_SPARE15_CORE1 0x14b -#define RADIO_2057_SPARE14_CORE1 0x14c -#define RADIO_2057_SPARE13_CORE1 0x14d -#define RADIO_2057_SPARE12_CORE1 0x14e -#define RADIO_2057_SPARE11_CORE1 0x14f -#define RADIO_2057_TX2G_BIAS_RESETS_CORE1 0x150 -#define RADIO_2057_TX5G_BIAS_RESETS_CORE1 0x151 -#define RADIO_2057_SPARE8_CORE1 0x152 -#define RADIO_2057_SPARE7_CORE1 0x153 -#define RADIO_2057_BUFS_MISC_LPFBW_CORE1 0x154 -#define RADIO_2057_TXLPF_RCCAL_CORE1 0x155 -#define RADIO_2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE1 0x156 -#define RADIO_2057_LPF_GAIN_CORE1 0x157 -#define RADIO_2057_DACBUF_IDACS_BW_CORE1 0x158 -#define RADIO_2057_DACBUF_VINCM_CORE1 0x159 -#define RADIO_2057_RCCAL_START_R1_Q1_P1 0x15a -#define RADIO_2057_RCCAL_X1 0x15b -#define RADIO_2057_RCCAL_TRC0 0x15c -#define RADIO_2057_RCCAL_TRC1 0x15d -#define RADIO_2057_RCCAL_DONE_OSCCAP 0x15e -#define RADIO_2057_RCCAL_N0_0 0x15f -#define RADIO_2057_RCCAL_N0_1 0x160 -#define RADIO_2057_RCCAL_N1_0 0x161 -#define RADIO_2057_RCCAL_N1_1 0x162 -#define RADIO_2057_RCAL_STATUS 0x163 -#define RADIO_2057_XTALPUOVR_PINCTRL 0x164 -#define RADIO_2057_OVR_REG0 0x165 -#define RADIO_2057_OVR_REG1 0x166 -#define RADIO_2057_OVR_REG2 0x167 -#define RADIO_2057_OVR_REG3 0x168 -#define RADIO_2057_OVR_REG4 0x169 -#define RADIO_2057_RCCAL_SCAP_VAL 0x16a -#define RADIO_2057_RCCAL_BCAP_VAL 0x16b -#define RADIO_2057_RCCAL_HPC_VAL 0x16c -#define RADIO_2057_RCCAL_OVERRIDES 0x16d -#define RADIO_2057_TX0_IQCAL_GAIN_BW 0x170 -#define RADIO_2057_TX0_LOFT_FINE_I 0x171 -#define RADIO_2057_TX0_LOFT_FINE_Q 0x172 -#define RADIO_2057_TX0_LOFT_COARSE_I 0x173 -#define RADIO_2057_TX0_LOFT_COARSE_Q 0x174 -#define RADIO_2057_TX0_TX_SSI_MASTER 0x175 -#define RADIO_2057_TX0_IQCAL_VCM_HG 0x176 -#define RADIO_2057_TX0_IQCAL_IDAC 0x177 -#define RADIO_2057_TX0_TSSI_VCM 0x178 -#define RADIO_2057_TX0_TX_SSI_MUX 0x179 -#define RADIO_2057_TX0_TSSIA 0x17a -#define RADIO_2057_TX0_TSSIG 0x17b -#define RADIO_2057_TX0_TSSI_MISC1 0x17c -#define RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN 0x17d -#define RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP 0x17e -#define RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN 0x17f -#define RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP 0x180 -#define RADIO_2057_TX1_IQCAL_GAIN_BW 0x190 -#define RADIO_2057_TX1_LOFT_FINE_I 0x191 -#define RADIO_2057_TX1_LOFT_FINE_Q 0x192 -#define RADIO_2057_TX1_LOFT_COARSE_I 0x193 -#define RADIO_2057_TX1_LOFT_COARSE_Q 0x194 -#define RADIO_2057_TX1_TX_SSI_MASTER 0x195 -#define RADIO_2057_TX1_IQCAL_VCM_HG 0x196 -#define RADIO_2057_TX1_IQCAL_IDAC 0x197 -#define RADIO_2057_TX1_TSSI_VCM 0x198 -#define RADIO_2057_TX1_TX_SSI_MUX 0x199 -#define RADIO_2057_TX1_TSSIA 0x19a -#define RADIO_2057_TX1_TSSIG 0x19b -#define RADIO_2057_TX1_TSSI_MISC1 0x19c -#define RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN 0x19d -#define RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP 0x19e -#define RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN 0x19f -#define RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP 0x1a0 -#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE0 0x1a1 -#define RADIO_2057_AFE_SET_VCM_I_CORE0 0x1a2 -#define RADIO_2057_AFE_SET_VCM_Q_CORE0 0x1a3 -#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE0 0x1a4 -#define RADIO_2057_AFE_STATUS_VCM_I_CORE0 0x1a5 -#define RADIO_2057_AFE_STATUS_VCM_Q_CORE0 0x1a6 -#define RADIO_2057_AFE_VCM_CAL_MASTER_CORE1 0x1a7 -#define RADIO_2057_AFE_SET_VCM_I_CORE1 0x1a8 -#define RADIO_2057_AFE_SET_VCM_Q_CORE1 0x1a9 -#define RADIO_2057_AFE_STATUS_VCM_IQADC_CORE1 0x1aa -#define RADIO_2057_AFE_STATUS_VCM_I_CORE1 0x1ab -#define RADIO_2057_AFE_STATUS_VCM_Q_CORE1 0x1ac - -#define RADIO_2057v7_DACBUF_VINCM_CORE0 0x1ad -#define RADIO_2057v7_RCCAL_MASTER 0x1ae -#define RADIO_2057v7_TR2G_CONFIG3_CORE0_NU 0x1af -#define RADIO_2057v7_TR2G_CONFIG3_CORE1_NU 0x1b0 -#define RADIO_2057v7_LOGEN_PUS1 0x1b1 -#define RADIO_2057v7_OVR_REG5 0x1b2 -#define RADIO_2057v7_OVR_REG6 0x1b3 -#define RADIO_2057v7_OVR_REG7 0x1b4 -#define RADIO_2057v7_OVR_REG8 0x1b5 -#define RADIO_2057v7_OVR_REG9 0x1b6 -#define RADIO_2057v7_OVR_REG10 0x1b7 -#define RADIO_2057v7_OVR_REG11 0x1b8 -#define RADIO_2057v7_OVR_REG12 0x1b9 -#define RADIO_2057v7_OVR_REG13 0x1ba -#define RADIO_2057v7_OVR_REG14 0x1bb -#define RADIO_2057v7_OVR_REG15 0x1bc -#define RADIO_2057v7_OVR_REG16 0x1bd -#define RADIO_2057v7_OVR_REG1 0x1be -#define RADIO_2057v7_OVR_REG18 0x1bf -#define RADIO_2057v7_OVR_REG19 0x1c0 -#define RADIO_2057v7_OVR_REG20 0x1c1 -#define RADIO_2057v7_OVR_REG21 0x1c2 -#define RADIO_2057v7_OVR_REG2 0x1c3 -#define RADIO_2057v7_OVR_REG23 0x1c4 -#define RADIO_2057v7_OVR_REG24 0x1c5 -#define RADIO_2057v7_OVR_REG25 0x1c6 -#define RADIO_2057v7_OVR_REG26 0x1c7 -#define RADIO_2057v7_OVR_REG27 0x1c8 -#define RADIO_2057v7_OVR_REG28 0x1c9 -#define RADIO_2057v7_IQTEST_SEL_PU2 0x1ca - -#define RADIO_2057_VCM_MASK 0x7 - -#endif /* _BCM20XX_H */ diff --git a/drivers/staging/brcm80211/phy/wlc_phyreg_n.h b/drivers/staging/brcm80211/phy/wlc_phyreg_n.h deleted file mode 100644 index 211bc3a842af..000000000000 --- a/drivers/staging/brcm80211/phy/wlc_phyreg_n.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define NPHY_TBL_ID_GAIN1 0 -#define NPHY_TBL_ID_GAIN2 1 -#define NPHY_TBL_ID_GAINBITS1 2 -#define NPHY_TBL_ID_GAINBITS2 3 -#define NPHY_TBL_ID_GAINLIMIT 4 -#define NPHY_TBL_ID_WRSSIGainLimit 5 -#define NPHY_TBL_ID_RFSEQ 7 -#define NPHY_TBL_ID_AFECTRL 8 -#define NPHY_TBL_ID_ANTSWCTRLLUT 9 -#define NPHY_TBL_ID_IQLOCAL 15 -#define NPHY_TBL_ID_NOISEVAR 16 -#define NPHY_TBL_ID_SAMPLEPLAY 17 -#define NPHY_TBL_ID_CORE1TXPWRCTL 26 -#define NPHY_TBL_ID_CORE2TXPWRCTL 27 -#define NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL 30 - -#define NPHY_TBL_ID_EPSILONTBL0 31 -#define NPHY_TBL_ID_SCALARTBL0 32 -#define NPHY_TBL_ID_EPSILONTBL1 33 -#define NPHY_TBL_ID_SCALARTBL1 34 - -#define NPHY_TO_BPHY_OFF 0xc00 - -#define NPHY_BandControl_currentBand 0x0001 -#define RFCC_CHIP0_PU 0x0400 -#define RFCC_POR_FORCE 0x0040 -#define RFCC_OE_POR_FORCE 0x0080 -#define NPHY_RfctrlIntc_override_OFF 0 -#define NPHY_RfctrlIntc_override_TRSW 1 -#define NPHY_RfctrlIntc_override_PA 2 -#define NPHY_RfctrlIntc_override_EXT_LNA_PU 3 -#define NPHY_RfctrlIntc_override_EXT_LNA_GAIN 4 -#define RIFS_ENABLE 0x80 -#define BPHY_BAND_SEL_UP20 0x10 -#define NPHY_MLenable 0x02 - -#define NPHY_RfseqMode_CoreActv_override 0x0001 -#define NPHY_RfseqMode_Trigger_override 0x0002 -#define NPHY_RfseqCoreActv_TxRxChain0 (0x11) -#define NPHY_RfseqCoreActv_TxRxChain1 (0x22) - -#define NPHY_RfseqTrigger_rx2tx 0x0001 -#define NPHY_RfseqTrigger_tx2rx 0x0002 -#define NPHY_RfseqTrigger_updategainh 0x0004 -#define NPHY_RfseqTrigger_updategainl 0x0008 -#define NPHY_RfseqTrigger_updategainu 0x0010 -#define NPHY_RfseqTrigger_reset2rx 0x0020 -#define NPHY_RfseqStatus_rx2tx 0x0001 -#define NPHY_RfseqStatus_tx2rx 0x0002 -#define NPHY_RfseqStatus_updategainh 0x0004 -#define NPHY_RfseqStatus_updategainl 0x0008 -#define NPHY_RfseqStatus_updategainu 0x0010 -#define NPHY_RfseqStatus_reset2rx 0x0020 -#define NPHY_ClassifierCtrl_cck_en 0x1 -#define NPHY_ClassifierCtrl_ofdm_en 0x2 -#define NPHY_ClassifierCtrl_waited_en 0x4 -#define NPHY_IQFlip_ADC1 0x0001 -#define NPHY_IQFlip_ADC2 0x0010 -#define NPHY_sampleCmd_STOP 0x0002 - -#define RX_GF_OR_MM 0x0004 -#define RX_GF_MM_AUTO 0x0100 - -#define NPHY_iqloCalCmdGctl_IQLO_CAL_EN 0x8000 - -#define NPHY_IqestCmd_iqstart 0x1 -#define NPHY_IqestCmd_iqMode 0x2 - -#define NPHY_TxPwrCtrlCmd_pwrIndex_init 0x40 -#define NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 0x19 - -#define PRIM_SEL_UP20 0x8000 - -#define NPHY_RFSEQ_RX2TX 0x0 -#define NPHY_RFSEQ_TX2RX 0x1 -#define NPHY_RFSEQ_RESET2RX 0x2 -#define NPHY_RFSEQ_UPDATEGAINH 0x3 -#define NPHY_RFSEQ_UPDATEGAINL 0x4 -#define NPHY_RFSEQ_UPDATEGAINU 0x5 - -#define NPHY_RFSEQ_CMD_NOP 0x0 -#define NPHY_RFSEQ_CMD_RXG_FBW 0x1 -#define NPHY_RFSEQ_CMD_TR_SWITCH 0x2 -#define NPHY_RFSEQ_CMD_EXT_PA 0x3 -#define NPHY_RFSEQ_CMD_RXPD_TXPD 0x4 -#define NPHY_RFSEQ_CMD_TX_GAIN 0x5 -#define NPHY_RFSEQ_CMD_RX_GAIN 0x6 -#define NPHY_RFSEQ_CMD_SET_HPF_BW 0x7 -#define NPHY_RFSEQ_CMD_CLR_HIQ_DIS 0x8 -#define NPHY_RFSEQ_CMD_END 0xf - -#define NPHY_REV3_RFSEQ_CMD_NOP 0x0 -#define NPHY_REV3_RFSEQ_CMD_RXG_FBW 0x1 -#define NPHY_REV3_RFSEQ_CMD_TR_SWITCH 0x2 -#define NPHY_REV3_RFSEQ_CMD_INT_PA_PU 0x3 -#define NPHY_REV3_RFSEQ_CMD_EXT_PA 0x4 -#define NPHY_REV3_RFSEQ_CMD_RXPD_TXPD 0x5 -#define NPHY_REV3_RFSEQ_CMD_TX_GAIN 0x6 -#define NPHY_REV3_RFSEQ_CMD_RX_GAIN 0x7 -#define NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS 0x8 -#define NPHY_REV3_RFSEQ_CMD_SET_HPF_H_HPC 0x9 -#define NPHY_REV3_RFSEQ_CMD_SET_LPF_H_HPC 0xa -#define NPHY_REV3_RFSEQ_CMD_SET_HPF_M_HPC 0xb -#define NPHY_REV3_RFSEQ_CMD_SET_LPF_M_HPC 0xc -#define NPHY_REV3_RFSEQ_CMD_SET_HPF_L_HPC 0xd -#define NPHY_REV3_RFSEQ_CMD_SET_LPF_L_HPC 0xe -#define NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS 0xf -#define NPHY_REV3_RFSEQ_CMD_END 0x1f - -#define NPHY_RSSI_SEL_W1 0x0 -#define NPHY_RSSI_SEL_W2 0x1 -#define NPHY_RSSI_SEL_NB 0x2 -#define NPHY_RSSI_SEL_IQ 0x3 -#define NPHY_RSSI_SEL_TSSI_2G 0x4 -#define NPHY_RSSI_SEL_TSSI_5G 0x5 -#define NPHY_RSSI_SEL_TBD 0x6 - -#define NPHY_RAIL_I 0x0 -#define NPHY_RAIL_Q 0x1 - -#define NPHY_FORCESIG_DECODEGATEDCLKS 0x8 - -#define NPHY_REV7_RfctrlOverride_cmd_rxrf_pu 0x0 -#define NPHY_REV7_RfctrlOverride_cmd_rx_pu 0x1 -#define NPHY_REV7_RfctrlOverride_cmd_tx_pu 0x2 -#define NPHY_REV7_RfctrlOverride_cmd_rxgain 0x3 -#define NPHY_REV7_RfctrlOverride_cmd_txgain 0x4 - -#define NPHY_REV7_RXGAINCODE_RFMXGAIN_MASK 0x000ff -#define NPHY_REV7_RXGAINCODE_LPFGAIN_MASK 0x0ff00 -#define NPHY_REV7_RXGAINCODE_DVGAGAIN_MASK 0xf0000 - -#define NPHY_REV7_TXGAINCODE_TGAIN_MASK 0x7fff -#define NPHY_REV7_TXGAINCODE_LPFGAIN_MASK 0x8000 -#define NPHY_REV7_TXGAINCODE_BIQ0GAIN_SHIFT 14 - -#define NPHY_REV7_RFCTRLOVERRIDE_ID0 0x0 -#define NPHY_REV7_RFCTRLOVERRIDE_ID1 0x1 -#define NPHY_REV7_RFCTRLOVERRIDE_ID2 0x2 - -#define NPHY_IqestIqAccLo(core) ((core == 0) ? 0x12c : 0x134) - -#define NPHY_IqestIqAccHi(core) ((core == 0) ? 0x12d : 0x135) - -#define NPHY_IqestipwrAccLo(core) ((core == 0) ? 0x12e : 0x136) - -#define NPHY_IqestipwrAccHi(core) ((core == 0) ? 0x12f : 0x137) - -#define NPHY_IqestqpwrAccLo(core) ((core == 0) ? 0x130 : 0x138) - -#define NPHY_IqestqpwrAccHi(core) ((core == 0) ? 0x131 : 0x139) diff --git a/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c b/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c deleted file mode 100644 index 330b88152b65..000000000000 --- a/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c +++ /dev/null @@ -1,3641 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include - -const u32 dot11lcn_gain_tbl_rev0[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000004, - 0x00000000, - 0x00000004, - 0x00000008, - 0x00000001, - 0x00000005, - 0x00000009, - 0x0000000d, - 0x0000004d, - 0x0000008d, - 0x0000000d, - 0x0000004d, - 0x0000008d, - 0x000000cd, - 0x0000004f, - 0x0000008f, - 0x000000cf, - 0x000000d3, - 0x00000113, - 0x00000513, - 0x00000913, - 0x00000953, - 0x00000d53, - 0x00001153, - 0x00001193, - 0x00005193, - 0x00009193, - 0x0000d193, - 0x00011193, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000004, - 0x00000000, - 0x00000004, - 0x00000008, - 0x00000001, - 0x00000005, - 0x00000009, - 0x0000000d, - 0x0000004d, - 0x0000008d, - 0x0000000d, - 0x0000004d, - 0x0000008d, - 0x000000cd, - 0x0000004f, - 0x0000008f, - 0x000000cf, - 0x000000d3, - 0x00000113, - 0x00000513, - 0x00000913, - 0x00000953, - 0x00000d53, - 0x00001153, - 0x00005153, - 0x00009153, - 0x0000d153, - 0x00011153, - 0x00015153, - 0x00019153, - 0x0001d153, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -const u32 dot11lcn_gain_tbl_rev1[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000008, - 0x00000004, - 0x00000008, - 0x00000001, - 0x00000005, - 0x00000009, - 0x0000000D, - 0x00000011, - 0x00000051, - 0x00000091, - 0x00000011, - 0x00000051, - 0x00000091, - 0x000000d1, - 0x00000053, - 0x00000093, - 0x000000d3, - 0x000000d7, - 0x00000117, - 0x00000517, - 0x00000917, - 0x00000957, - 0x00000d57, - 0x00001157, - 0x00001197, - 0x00005197, - 0x00009197, - 0x0000d197, - 0x00011197, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000008, - 0x00000004, - 0x00000008, - 0x00000001, - 0x00000005, - 0x00000009, - 0x0000000D, - 0x00000011, - 0x00000051, - 0x00000091, - 0x00000011, - 0x00000051, - 0x00000091, - 0x000000d1, - 0x00000053, - 0x00000093, - 0x000000d3, - 0x000000d7, - 0x00000117, - 0x00000517, - 0x00000917, - 0x00000957, - 0x00000d57, - 0x00001157, - 0x00005157, - 0x00009157, - 0x0000d157, - 0x00011157, - 0x00015157, - 0x00019157, - 0x0001d157, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -const u16 dot11lcn_aux_gain_idx_tbl_rev0[] = { - 0x0401, - 0x0402, - 0x0403, - 0x0404, - 0x0405, - 0x0406, - 0x0407, - 0x0408, - 0x0409, - 0x040a, - 0x058b, - 0x058c, - 0x058d, - 0x058e, - 0x058f, - 0x0090, - 0x0091, - 0x0092, - 0x0193, - 0x0194, - 0x0195, - 0x0196, - 0x0197, - 0x0198, - 0x0199, - 0x019a, - 0x019b, - 0x019c, - 0x019d, - 0x019e, - 0x019f, - 0x01a0, - 0x01a1, - 0x01a2, - 0x01a3, - 0x01a4, - 0x01a5, - 0x0000, -}; - -const u32 dot11lcn_gain_idx_tbl_rev0[] = { - 0x00000000, - 0x00000000, - 0x10000000, - 0x00000000, - 0x20000000, - 0x00000000, - 0x30000000, - 0x00000000, - 0x40000000, - 0x00000000, - 0x50000000, - 0x00000000, - 0x60000000, - 0x00000000, - 0x70000000, - 0x00000000, - 0x80000000, - 0x00000000, - 0x90000000, - 0x00000008, - 0xa0000000, - 0x00000008, - 0xb0000000, - 0x00000008, - 0xc0000000, - 0x00000008, - 0xd0000000, - 0x00000008, - 0xe0000000, - 0x00000008, - 0xf0000000, - 0x00000008, - 0x00000000, - 0x00000009, - 0x10000000, - 0x00000009, - 0x20000000, - 0x00000019, - 0x30000000, - 0x00000019, - 0x40000000, - 0x00000019, - 0x50000000, - 0x00000019, - 0x60000000, - 0x00000019, - 0x70000000, - 0x00000019, - 0x80000000, - 0x00000019, - 0x90000000, - 0x00000019, - 0xa0000000, - 0x00000019, - 0xb0000000, - 0x00000019, - 0xc0000000, - 0x00000019, - 0xd0000000, - 0x00000019, - 0xe0000000, - 0x00000019, - 0xf0000000, - 0x00000019, - 0x00000000, - 0x0000001a, - 0x10000000, - 0x0000001a, - 0x20000000, - 0x0000001a, - 0x30000000, - 0x0000001a, - 0x40000000, - 0x0000001a, - 0x50000000, - 0x00000002, - 0x60000000, - 0x00000002, - 0x70000000, - 0x00000002, - 0x80000000, - 0x00000002, - 0x90000000, - 0x00000002, - 0xa0000000, - 0x00000002, - 0xb0000000, - 0x00000002, - 0xc0000000, - 0x0000000a, - 0xd0000000, - 0x0000000a, - 0xe0000000, - 0x0000000a, - 0xf0000000, - 0x0000000a, - 0x00000000, - 0x0000000b, - 0x10000000, - 0x0000000b, - 0x20000000, - 0x0000000b, - 0x30000000, - 0x0000000b, - 0x40000000, - 0x0000000b, - 0x50000000, - 0x0000001b, - 0x60000000, - 0x0000001b, - 0x70000000, - 0x0000001b, - 0x80000000, - 0x0000001b, - 0x90000000, - 0x0000001b, - 0xa0000000, - 0x0000001b, - 0xb0000000, - 0x0000001b, - 0xc0000000, - 0x0000001b, - 0xd0000000, - 0x0000001b, - 0xe0000000, - 0x0000001b, - 0xf0000000, - 0x0000001b, - 0x00000000, - 0x0000001c, - 0x10000000, - 0x0000001c, - 0x20000000, - 0x0000001c, - 0x30000000, - 0x0000001c, - 0x40000000, - 0x0000001c, - 0x50000000, - 0x0000001c, - 0x60000000, - 0x0000001c, - 0x70000000, - 0x0000001c, - 0x80000000, - 0x0000001c, - 0x90000000, - 0x0000001c, -}; - -const u16 dot11lcn_aux_gain_idx_tbl_2G[] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0001, - 0x0080, - 0x0081, - 0x0100, - 0x0101, - 0x0180, - 0x0181, - 0x0182, - 0x0183, - 0x0184, - 0x0185, - 0x0186, - 0x0187, - 0x0188, - 0x0285, - 0x0289, - 0x028a, - 0x028b, - 0x028c, - 0x028d, - 0x028e, - 0x028f, - 0x0290, - 0x0291, - 0x0292, - 0x0293, - 0x0294, - 0x0295, - 0x0296, - 0x0297, - 0x0298, - 0x0299, - 0x029a, - 0x0000 -}; - -const u8 dot11lcn_gain_val_tbl_2G[] = { - 0xfc, - 0x02, - 0x08, - 0x0e, - 0x13, - 0x1b, - 0xfc, - 0x02, - 0x08, - 0x0e, - 0x13, - 0x1b, - 0xfc, - 0x00, - 0x0c, - 0x03, - 0xeb, - 0xfe, - 0x07, - 0x0b, - 0x0f, - 0xfb, - 0xfe, - 0x01, - 0x05, - 0x08, - 0x0b, - 0x0e, - 0x11, - 0x14, - 0x17, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x03, - 0x06, - 0x09, - 0x0c, - 0x0f, - 0x12, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x03, - 0x06, - 0x09, - 0x0c, - 0x0f, - 0x12, - 0x15, - 0x18, - 0x1b, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; - -const u32 dot11lcn_gain_idx_tbl_2G[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x10000000, - 0x00000000, - 0x00000000, - 0x00000008, - 0x10000000, - 0x00000008, - 0x00000000, - 0x00000010, - 0x10000000, - 0x00000010, - 0x00000000, - 0x00000018, - 0x10000000, - 0x00000018, - 0x20000000, - 0x00000018, - 0x30000000, - 0x00000018, - 0x40000000, - 0x00000018, - 0x50000000, - 0x00000018, - 0x60000000, - 0x00000018, - 0x70000000, - 0x00000018, - 0x80000000, - 0x00000018, - 0x50000000, - 0x00000028, - 0x90000000, - 0x00000028, - 0xa0000000, - 0x00000028, - 0xb0000000, - 0x00000028, - 0xc0000000, - 0x00000028, - 0xd0000000, - 0x00000028, - 0xe0000000, - 0x00000028, - 0xf0000000, - 0x00000028, - 0x00000000, - 0x00000029, - 0x10000000, - 0x00000029, - 0x20000000, - 0x00000029, - 0x30000000, - 0x00000029, - 0x40000000, - 0x00000029, - 0x50000000, - 0x00000029, - 0x60000000, - 0x00000029, - 0x70000000, - 0x00000029, - 0x80000000, - 0x00000029, - 0x90000000, - 0x00000029, - 0xa0000000, - 0x00000029, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x10000000, - 0x00000000, - 0x00000000, - 0x00000008, - 0x10000000, - 0x00000008, - 0x00000000, - 0x00000010, - 0x10000000, - 0x00000010, - 0x00000000, - 0x00000018, - 0x10000000, - 0x00000018, - 0x20000000, - 0x00000018, - 0x30000000, - 0x00000018, - 0x40000000, - 0x00000018, - 0x50000000, - 0x00000018, - 0x60000000, - 0x00000018, - 0x70000000, - 0x00000018, - 0x80000000, - 0x00000018, - 0x50000000, - 0x00000028, - 0x90000000, - 0x00000028, - 0xa0000000, - 0x00000028, - 0xb0000000, - 0x00000028, - 0xc0000000, - 0x00000028, - 0xd0000000, - 0x00000028, - 0xe0000000, - 0x00000028, - 0xf0000000, - 0x00000028, - 0x00000000, - 0x00000029, - 0x10000000, - 0x00000029, - 0x20000000, - 0x00000029, - 0x30000000, - 0x00000029, - 0x40000000, - 0x00000029, - 0x50000000, - 0x00000029, - 0x60000000, - 0x00000029, - 0x70000000, - 0x00000029, - 0x80000000, - 0x00000029, - 0x90000000, - 0x00000029, - 0xa0000000, - 0x00000029, - 0xb0000000, - 0x00000029, - 0xc0000000, - 0x00000029, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000 -}; - -const u32 dot11lcn_gain_tbl_2G[] = { - 0x00000000, - 0x00000004, - 0x00000008, - 0x00000001, - 0x00000005, - 0x00000009, - 0x0000000d, - 0x0000004d, - 0x0000008d, - 0x00000049, - 0x00000089, - 0x000000c9, - 0x0000004b, - 0x0000008b, - 0x000000cb, - 0x000000cf, - 0x0000010f, - 0x0000050f, - 0x0000090f, - 0x0000094f, - 0x00000d4f, - 0x0000114f, - 0x0000118f, - 0x0000518f, - 0x0000918f, - 0x0000d18f, - 0x0001118f, - 0x0001518f, - 0x0001918f, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000 -}; - -const u32 dot11lcn_gain_tbl_extlna_2G[] = { - 0x00000000, - 0x00000004, - 0x00000008, - 0x00000001, - 0x00000005, - 0x00000009, - 0x0000000d, - 0x00000003, - 0x00000007, - 0x0000000b, - 0x0000000f, - 0x0000004f, - 0x0000008f, - 0x000000cf, - 0x0000010f, - 0x0000014f, - 0x0000018f, - 0x0000058f, - 0x0000098f, - 0x00000d8f, - 0x00008000, - 0x00008004, - 0x00008008, - 0x00008001, - 0x00008005, - 0x00008009, - 0x0000800d, - 0x00008003, - 0x00008007, - 0x0000800b, - 0x0000800f, - 0x0000804f, - 0x0000808f, - 0x000080cf, - 0x0000810f, - 0x0000814f, - 0x0000818f, - 0x0000858f, - 0x0000898f, - 0x00008d8f, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000 -}; - -const u16 dot11lcn_aux_gain_idx_tbl_extlna_2G[] = { - 0x0400, - 0x0400, - 0x0400, - 0x0400, - 0x0400, - 0x0400, - 0x0400, - 0x0400, - 0x0400, - 0x0401, - 0x0402, - 0x0403, - 0x0404, - 0x0483, - 0x0484, - 0x0485, - 0x0486, - 0x0583, - 0x0584, - 0x0585, - 0x0587, - 0x0588, - 0x0589, - 0x058a, - 0x0687, - 0x0688, - 0x0689, - 0x068a, - 0x068b, - 0x068c, - 0x068d, - 0x068e, - 0x068f, - 0x0690, - 0x0691, - 0x0692, - 0x0693, - 0x0000 -}; - -const u8 dot11lcn_gain_val_tbl_extlna_2G[] = { - 0xfc, - 0x02, - 0x08, - 0x0e, - 0x13, - 0x1b, - 0xfc, - 0x02, - 0x08, - 0x0e, - 0x13, - 0x1b, - 0xfc, - 0x00, - 0x0f, - 0x03, - 0xeb, - 0xfe, - 0x07, - 0x0b, - 0x0f, - 0xfb, - 0xfe, - 0x01, - 0x05, - 0x08, - 0x0b, - 0x0e, - 0x11, - 0x14, - 0x17, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x03, - 0x06, - 0x09, - 0x0c, - 0x0f, - 0x12, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x03, - 0x06, - 0x09, - 0x0c, - 0x0f, - 0x12, - 0x15, - 0x18, - 0x1b, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; - -const u32 dot11lcn_gain_idx_tbl_extlna_2G[] = { - 0x00000000, - 0x00000040, - 0x00000000, - 0x00000040, - 0x00000000, - 0x00000040, - 0x00000000, - 0x00000040, - 0x00000000, - 0x00000040, - 0x00000000, - 0x00000040, - 0x00000000, - 0x00000040, - 0x00000000, - 0x00000040, - 0x00000000, - 0x00000040, - 0x10000000, - 0x00000040, - 0x20000000, - 0x00000040, - 0x30000000, - 0x00000040, - 0x40000000, - 0x00000040, - 0x30000000, - 0x00000048, - 0x40000000, - 0x00000048, - 0x50000000, - 0x00000048, - 0x60000000, - 0x00000048, - 0x30000000, - 0x00000058, - 0x40000000, - 0x00000058, - 0x50000000, - 0x00000058, - 0x70000000, - 0x00000058, - 0x80000000, - 0x00000058, - 0x90000000, - 0x00000058, - 0xa0000000, - 0x00000058, - 0x70000000, - 0x00000068, - 0x80000000, - 0x00000068, - 0x90000000, - 0x00000068, - 0xa0000000, - 0x00000068, - 0xb0000000, - 0x00000068, - 0xc0000000, - 0x00000068, - 0xd0000000, - 0x00000068, - 0xe0000000, - 0x00000068, - 0xf0000000, - 0x00000068, - 0x00000000, - 0x00000069, - 0x10000000, - 0x00000069, - 0x20000000, - 0x00000069, - 0x30000000, - 0x00000069, - 0x40000000, - 0x00000041, - 0x40000000, - 0x00000041, - 0x40000000, - 0x00000041, - 0x40000000, - 0x00000041, - 0x40000000, - 0x00000041, - 0x40000000, - 0x00000041, - 0x40000000, - 0x00000041, - 0x40000000, - 0x00000041, - 0x40000000, - 0x00000041, - 0x50000000, - 0x00000041, - 0x60000000, - 0x00000041, - 0x70000000, - 0x00000041, - 0x80000000, - 0x00000041, - 0x70000000, - 0x00000049, - 0x80000000, - 0x00000049, - 0x90000000, - 0x00000049, - 0xa0000000, - 0x00000049, - 0x70000000, - 0x00000059, - 0x80000000, - 0x00000059, - 0x90000000, - 0x00000059, - 0xb0000000, - 0x00000059, - 0xc0000000, - 0x00000059, - 0xd0000000, - 0x00000059, - 0xe0000000, - 0x00000059, - 0xb0000000, - 0x00000069, - 0xc0000000, - 0x00000069, - 0xd0000000, - 0x00000069, - 0xe0000000, - 0x00000069, - 0xf0000000, - 0x00000069, - 0x00000000, - 0x0000006a, - 0x10000000, - 0x0000006a, - 0x20000000, - 0x0000006a, - 0x30000000, - 0x0000006a, - 0x40000000, - 0x0000006a, - 0x50000000, - 0x0000006a, - 0x60000000, - 0x0000006a, - 0x70000000, - 0x0000006a, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000 -}; - -const u32 dot11lcn_aux_gain_idx_tbl_5G[] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0001, - 0x0002, - 0x0003, - 0x0004, - 0x0083, - 0x0084, - 0x0085, - 0x0086, - 0x0087, - 0x0186, - 0x0187, - 0x0188, - 0x0189, - 0x018a, - 0x018b, - 0x018c, - 0x018d, - 0x018e, - 0x018f, - 0x0190, - 0x0191, - 0x0192, - 0x0193, - 0x0194, - 0x0195, - 0x0196, - 0x0197, - 0x0198, - 0x0199, - 0x019a, - 0x019b, - 0x019c, - 0x019d, - 0x0000 -}; - -const u32 dot11lcn_gain_val_tbl_5G[] = { - 0xf7, - 0xfd, - 0x00, - 0x04, - 0x04, - 0x04, - 0xf7, - 0xfd, - 0x00, - 0x04, - 0x04, - 0x04, - 0xf6, - 0x00, - 0x0c, - 0x03, - 0xeb, - 0xfe, - 0x06, - 0x0a, - 0x10, - 0x00, - 0x03, - 0x06, - 0x09, - 0x0c, - 0x0f, - 0x12, - 0x15, - 0x18, - 0x1b, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x03, - 0x06, - 0x09, - 0x0c, - 0x0f, - 0x12, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x03, - 0x06, - 0x09, - 0x0c, - 0x0f, - 0x12, - 0x15, - 0x18, - 0x1b, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; - -const u32 dot11lcn_gain_idx_tbl_5G[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x10000000, - 0x00000000, - 0x20000000, - 0x00000000, - 0x30000000, - 0x00000000, - 0x40000000, - 0x00000000, - 0x30000000, - 0x00000008, - 0x40000000, - 0x00000008, - 0x50000000, - 0x00000008, - 0x60000000, - 0x00000008, - 0x70000000, - 0x00000008, - 0x60000000, - 0x00000018, - 0x70000000, - 0x00000018, - 0x80000000, - 0x00000018, - 0x90000000, - 0x00000018, - 0xa0000000, - 0x00000018, - 0xb0000000, - 0x00000018, - 0xc0000000, - 0x00000018, - 0xd0000000, - 0x00000018, - 0xe0000000, - 0x00000018, - 0xf0000000, - 0x00000018, - 0x00000000, - 0x00000019, - 0x10000000, - 0x00000019, - 0x20000000, - 0x00000019, - 0x30000000, - 0x00000019, - 0x40000000, - 0x00000019, - 0x50000000, - 0x00000019, - 0x60000000, - 0x00000019, - 0x70000000, - 0x00000019, - 0x80000000, - 0x00000019, - 0x90000000, - 0x00000019, - 0xa0000000, - 0x00000019, - 0xb0000000, - 0x00000019, - 0xc0000000, - 0x00000019, - 0xd0000000, - 0x00000019, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000 -}; - -const u32 dot11lcn_gain_tbl_5G[] = { - 0x00000000, - 0x00000040, - 0x00000080, - 0x00000001, - 0x00000005, - 0x00000009, - 0x0000000d, - 0x00000011, - 0x00000015, - 0x00000055, - 0x00000095, - 0x00000017, - 0x0000001b, - 0x0000005b, - 0x0000009b, - 0x000000db, - 0x0000011b, - 0x0000015b, - 0x0000019b, - 0x0000059b, - 0x0000099b, - 0x00000d9b, - 0x0000119b, - 0x0000519b, - 0x0000919b, - 0x0000d19b, - 0x0001119b, - 0x0001519b, - 0x0001919b, - 0x0001d19b, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000 -}; - -const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev0[] = { - {&dot11lcn_gain_tbl_rev0, - sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18, - 0, 32} - , - {&dot11lcn_aux_gain_idx_tbl_rev0, - sizeof(dot11lcn_aux_gain_idx_tbl_rev0) / - sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16} - , - {&dot11lcn_gain_idx_tbl_rev0, - sizeof(dot11lcn_gain_idx_tbl_rev0) / - sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32} - , -}; - -const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev1[] = { - {&dot11lcn_gain_tbl_rev1, - sizeof(dot11lcn_gain_tbl_rev1) / sizeof(dot11lcn_gain_tbl_rev1[0]), 18, - 0, 32} - , - {&dot11lcn_aux_gain_idx_tbl_rev0, - sizeof(dot11lcn_aux_gain_idx_tbl_rev0) / - sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16} - , - {&dot11lcn_gain_idx_tbl_rev0, - sizeof(dot11lcn_gain_idx_tbl_rev0) / - sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32} - , -}; - -const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_2G_rev2[] = { - {&dot11lcn_gain_tbl_2G, - sizeof(dot11lcn_gain_tbl_2G) / sizeof(dot11lcn_gain_tbl_2G[0]), 18, 0, - 32} - , - {&dot11lcn_aux_gain_idx_tbl_2G, - sizeof(dot11lcn_aux_gain_idx_tbl_2G) / - sizeof(dot11lcn_aux_gain_idx_tbl_2G[0]), 14, 0, 16} - , - {&dot11lcn_gain_idx_tbl_2G, - sizeof(dot11lcn_gain_idx_tbl_2G) / sizeof(dot11lcn_gain_idx_tbl_2G[0]), - 13, 0, 32} - , - {&dot11lcn_gain_val_tbl_2G, - sizeof(dot11lcn_gain_val_tbl_2G) / sizeof(dot11lcn_gain_val_tbl_2G[0]), - 17, 0, 8} -}; - -const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_5G_rev2[] = { - {&dot11lcn_gain_tbl_5G, - sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0, - 32} - , - {&dot11lcn_aux_gain_idx_tbl_5G, - sizeof(dot11lcn_aux_gain_idx_tbl_5G) / - sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16} - , - {&dot11lcn_gain_idx_tbl_5G, - sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]), - 13, 0, 32} - , - {&dot11lcn_gain_val_tbl_5G, - sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]), - 17, 0, 8} -}; - -const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[] = { - {&dot11lcn_gain_tbl_extlna_2G, - sizeof(dot11lcn_gain_tbl_extlna_2G) / - sizeof(dot11lcn_gain_tbl_extlna_2G[0]), 18, 0, 32} - , - {&dot11lcn_aux_gain_idx_tbl_extlna_2G, - sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G) / - sizeof(dot11lcn_aux_gain_idx_tbl_extlna_2G[0]), 14, 0, 16} - , - {&dot11lcn_gain_idx_tbl_extlna_2G, - sizeof(dot11lcn_gain_idx_tbl_extlna_2G) / - sizeof(dot11lcn_gain_idx_tbl_extlna_2G[0]), 13, 0, 32} - , - {&dot11lcn_gain_val_tbl_extlna_2G, - sizeof(dot11lcn_gain_val_tbl_extlna_2G) / - sizeof(dot11lcn_gain_val_tbl_extlna_2G[0]), 17, 0, 8} -}; - -const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[] = { - {&dot11lcn_gain_tbl_5G, - sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0, - 32} - , - {&dot11lcn_aux_gain_idx_tbl_5G, - sizeof(dot11lcn_aux_gain_idx_tbl_5G) / - sizeof(dot11lcn_aux_gain_idx_tbl_5G[0]), 14, 0, 16} - , - {&dot11lcn_gain_idx_tbl_5G, - sizeof(dot11lcn_gain_idx_tbl_5G) / sizeof(dot11lcn_gain_idx_tbl_5G[0]), - 13, 0, 32} - , - {&dot11lcn_gain_val_tbl_5G, - sizeof(dot11lcn_gain_val_tbl_5G) / sizeof(dot11lcn_gain_val_tbl_5G[0]), - 17, 0, 8} -}; - -const u32 dot11lcnphytbl_rx_gain_info_sz_rev0 = - sizeof(dot11lcnphytbl_rx_gain_info_rev0) / - sizeof(dot11lcnphytbl_rx_gain_info_rev0[0]); - -const u32 dot11lcnphytbl_rx_gain_info_sz_rev1 = - sizeof(dot11lcnphytbl_rx_gain_info_rev1) / - sizeof(dot11lcnphytbl_rx_gain_info_rev1[0]); - -const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz = - sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2) / - sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2[0]); - -const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz = - sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2) / - sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2[0]); - -const u16 dot11lcn_min_sig_sq_tbl_rev0[] = { - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, - 0x014d, -}; - -const u16 dot11lcn_noise_scale_tbl_rev0[] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}; - -const u32 dot11lcn_fltr_ctrl_tbl_rev0[] = { - 0x000141f8, - 0x000021f8, - 0x000021fb, - 0x000041fb, - 0x0001fe4b, - 0x0000217b, - 0x00002133, - 0x000040eb, - 0x0001fea3, - 0x0000024b, -}; - -const u32 dot11lcn_ps_ctrl_tbl_rev0[] = { - 0x00100001, - 0x00200010, - 0x00300001, - 0x00400010, - 0x00500022, - 0x00600122, - 0x00700222, - 0x00800322, - 0x00900422, - 0x00a00522, - 0x00b00622, - 0x00c00722, - 0x00d00822, - 0x00f00922, - 0x00100a22, - 0x00200b22, - 0x00300c22, - 0x00400d22, - 0x00500e22, - 0x00600f22, -}; - -const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[] = { - 0x0007, - 0x0005, - 0x0006, - 0x0004, - 0x0007, - 0x0005, - 0x0006, - 0x0004, - 0x0007, - 0x0005, - 0x0006, - 0x0004, - 0x0007, - 0x0005, - 0x0006, - 0x0004, - 0x000b, - 0x000b, - 0x000a, - 0x000a, - 0x000b, - 0x000b, - 0x000a, - 0x000a, - 0x000b, - 0x000b, - 0x000a, - 0x000a, - 0x000b, - 0x000b, - 0x000a, - 0x000a, - 0x0007, - 0x0005, - 0x0006, - 0x0004, - 0x0007, - 0x0005, - 0x0006, - 0x0004, - 0x0007, - 0x0005, - 0x0006, - 0x0004, - 0x0007, - 0x0005, - 0x0006, - 0x0004, - 0x000b, - 0x000b, - 0x000a, - 0x000a, - 0x000b, - 0x000b, - 0x000a, - 0x000a, - 0x000b, - 0x000b, - 0x000a, - 0x000a, - 0x000b, - 0x000b, - 0x000a, - 0x000a, - -}; - -const u16 dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[] = { - 0x0007, - 0x0005, - 0x0002, - 0x0000, - 0x0007, - 0x0005, - 0x0002, - 0x0000, - 0x0007, - 0x0005, - 0x0002, - 0x0000, - 0x0007, - 0x0005, - 0x0002, - 0x0000, - 0x0007, - 0x0007, - 0x0002, - 0x0002, - 0x0007, - 0x0007, - 0x0002, - 0x0002, - 0x0007, - 0x0007, - 0x0002, - 0x0002, - 0x0007, - 0x0007, - 0x0002, - 0x0002, - 0x0007, - 0x0005, - 0x0002, - 0x0000, - 0x0007, - 0x0005, - 0x0002, - 0x0000, - 0x0007, - 0x0005, - 0x0002, - 0x0000, - 0x0007, - 0x0005, - 0x0002, - 0x0000, - 0x0007, - 0x0007, - 0x0002, - 0x0002, - 0x0007, - 0x0007, - 0x0002, - 0x0002, - 0x0007, - 0x0007, - 0x0002, - 0x0002, - 0x0007, - 0x0007, - 0x0002, - 0x0002, -}; - -const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = { - 0x0002, - 0x0008, - 0x0004, - 0x0001, - 0x0002, - 0x0008, - 0x0004, - 0x0001, - 0x0002, - 0x0008, - 0x0004, - 0x0001, - 0x0002, - 0x0008, - 0x0004, - 0x0001, - 0x0002, - 0x0008, - 0x0004, - 0x0001, - 0x0002, - 0x0008, - 0x0004, - 0x0001, - 0x0002, - 0x0008, - 0x0004, - 0x0001, - 0x0002, - 0x0008, - 0x0004, - 0x0001, - 0x0002, - 0x0008, - 0x0004, - 0x0001, - 0x0002, - 0x0008, - 0x0004, - 0x0001, - 0x0002, - 0x0008, - 0x0004, - 0x0001, - 0x0002, - 0x0008, - 0x0004, - 0x0001, - 0x0002, - 0x0008, - 0x0004, - 0x0001, - 0x0002, - 0x0008, - 0x0004, - 0x0001, - 0x0002, - 0x0008, - 0x0004, - 0x0001, - 0x0002, - 0x0008, - 0x0004, - 0x0001, -}; - -const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = { - 0x000a, - 0x0009, - 0x0006, - 0x0005, - 0x000a, - 0x0009, - 0x0006, - 0x0005, - 0x000a, - 0x0009, - 0x0006, - 0x0005, - 0x000a, - 0x0009, - 0x0006, - 0x0005, - 0x000a, - 0x0009, - 0x0006, - 0x0005, - 0x000a, - 0x0009, - 0x0006, - 0x0005, - 0x000a, - 0x0009, - 0x0006, - 0x0005, - 0x000a, - 0x0009, - 0x0006, - 0x0005, - 0x000a, - 0x0009, - 0x0006, - 0x0005, - 0x000a, - 0x0009, - 0x0006, - 0x0005, - 0x000a, - 0x0009, - 0x0006, - 0x0005, - 0x000a, - 0x0009, - 0x0006, - 0x0005, - 0x000a, - 0x0009, - 0x0006, - 0x0005, - 0x000a, - 0x0009, - 0x0006, - 0x0005, - 0x000a, - 0x0009, - 0x0006, - 0x0005, - 0x000a, - 0x0009, - 0x0006, - 0x0005, -}; - -const u16 dot11lcn_sw_ctrl_tbl_rev0[] = { - 0x0004, - 0x0004, - 0x0002, - 0x0002, - 0x0004, - 0x0004, - 0x0002, - 0x0002, - 0x0004, - 0x0004, - 0x0002, - 0x0002, - 0x0004, - 0x0004, - 0x0002, - 0x0002, - 0x0004, - 0x0004, - 0x0002, - 0x0002, - 0x0004, - 0x0004, - 0x0002, - 0x0002, - 0x0004, - 0x0004, - 0x0002, - 0x0002, - 0x0004, - 0x0004, - 0x0002, - 0x0002, - 0x0004, - 0x0004, - 0x0002, - 0x0002, - 0x0004, - 0x0004, - 0x0002, - 0x0002, - 0x0004, - 0x0004, - 0x0002, - 0x0002, - 0x0004, - 0x0004, - 0x0002, - 0x0002, - 0x0004, - 0x0004, - 0x0002, - 0x0002, - 0x0004, - 0x0004, - 0x0002, - 0x0002, - 0x0004, - 0x0004, - 0x0002, - 0x0002, - 0x0004, - 0x0004, - 0x0002, - 0x0002, -}; - -const u8 dot11lcn_nf_table_rev0[] = { - 0x5f, - 0x36, - 0x29, - 0x1f, - 0x5f, - 0x36, - 0x29, - 0x1f, - 0x5f, - 0x36, - 0x29, - 0x1f, - 0x5f, - 0x36, - 0x29, - 0x1f, -}; - -const u8 dot11lcn_gain_val_tbl_rev0[] = { - 0x09, - 0x0f, - 0x14, - 0x18, - 0xfe, - 0x07, - 0x0b, - 0x0f, - 0xfb, - 0xfe, - 0x01, - 0x05, - 0x08, - 0x0b, - 0x0e, - 0x11, - 0x14, - 0x17, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x03, - 0x06, - 0x09, - 0x0c, - 0x0f, - 0x12, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x03, - 0x06, - 0x09, - 0x0c, - 0x0f, - 0x12, - 0x15, - 0x18, - 0x1b, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x03, - 0xeb, - 0x00, - 0x00, -}; - -const u8 dot11lcn_spur_tbl_rev0[] = { - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x02, - 0x03, - 0x01, - 0x03, - 0x02, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x02, - 0x03, - 0x01, - 0x03, - 0x02, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, - 0x01, -}; - -const u16 dot11lcn_unsup_mcs_tbl_rev0[] = { - 0x001a, - 0x0034, - 0x004e, - 0x0068, - 0x009c, - 0x00d0, - 0x00ea, - 0x0104, - 0x0034, - 0x0068, - 0x009c, - 0x00d0, - 0x0138, - 0x01a0, - 0x01d4, - 0x0208, - 0x004e, - 0x009c, - 0x00ea, - 0x0138, - 0x01d4, - 0x0270, - 0x02be, - 0x030c, - 0x0068, - 0x00d0, - 0x0138, - 0x01a0, - 0x0270, - 0x0340, - 0x03a8, - 0x0410, - 0x0018, - 0x009c, - 0x00d0, - 0x0104, - 0x00ea, - 0x0138, - 0x0186, - 0x00d0, - 0x0104, - 0x0104, - 0x0138, - 0x016c, - 0x016c, - 0x01a0, - 0x0138, - 0x0186, - 0x0186, - 0x01d4, - 0x0222, - 0x0222, - 0x0270, - 0x0104, - 0x0138, - 0x016c, - 0x0138, - 0x016c, - 0x01a0, - 0x01d4, - 0x01a0, - 0x01d4, - 0x0208, - 0x0208, - 0x023c, - 0x0186, - 0x01d4, - 0x0222, - 0x01d4, - 0x0222, - 0x0270, - 0x02be, - 0x0270, - 0x02be, - 0x030c, - 0x030c, - 0x035a, - 0x0036, - 0x006c, - 0x00a2, - 0x00d8, - 0x0144, - 0x01b0, - 0x01e6, - 0x021c, - 0x006c, - 0x00d8, - 0x0144, - 0x01b0, - 0x0288, - 0x0360, - 0x03cc, - 0x0438, - 0x00a2, - 0x0144, - 0x01e6, - 0x0288, - 0x03cc, - 0x0510, - 0x05b2, - 0x0654, - 0x00d8, - 0x01b0, - 0x0288, - 0x0360, - 0x0510, - 0x06c0, - 0x0798, - 0x0870, - 0x0018, - 0x0144, - 0x01b0, - 0x021c, - 0x01e6, - 0x0288, - 0x032a, - 0x01b0, - 0x021c, - 0x021c, - 0x0288, - 0x02f4, - 0x02f4, - 0x0360, - 0x0288, - 0x032a, - 0x032a, - 0x03cc, - 0x046e, - 0x046e, - 0x0510, - 0x021c, - 0x0288, - 0x02f4, - 0x0288, - 0x02f4, - 0x0360, - 0x03cc, - 0x0360, - 0x03cc, - 0x0438, - 0x0438, - 0x04a4, - 0x032a, - 0x03cc, - 0x046e, - 0x03cc, - 0x046e, - 0x0510, - 0x05b2, - 0x0510, - 0x05b2, - 0x0654, - 0x0654, - 0x06f6, -}; - -const u16 dot11lcn_iq_local_tbl_rev0[] = { - 0x0200, - 0x0300, - 0x0400, - 0x0600, - 0x0800, - 0x0b00, - 0x1000, - 0x1001, - 0x1002, - 0x1003, - 0x1004, - 0x1005, - 0x1006, - 0x1007, - 0x1707, - 0x2007, - 0x2d07, - 0x4007, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0200, - 0x0300, - 0x0400, - 0x0600, - 0x0800, - 0x0b00, - 0x1000, - 0x1001, - 0x1002, - 0x1003, - 0x1004, - 0x1005, - 0x1006, - 0x1007, - 0x1707, - 0x2007, - 0x2d07, - 0x4007, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x4000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}; - -const u32 dot11lcn_papd_compdelta_tbl_rev0[] = { - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, - 0x00080000, -}; - -const dot11lcnphytbl_info_t dot11lcnphytbl_info_rev0[] = { - {&dot11lcn_min_sig_sq_tbl_rev0, - sizeof(dot11lcn_min_sig_sq_tbl_rev0) / - sizeof(dot11lcn_min_sig_sq_tbl_rev0[0]), 2, 0, 16} - , - {&dot11lcn_noise_scale_tbl_rev0, - sizeof(dot11lcn_noise_scale_tbl_rev0) / - sizeof(dot11lcn_noise_scale_tbl_rev0[0]), 1, 0, 16} - , - {&dot11lcn_fltr_ctrl_tbl_rev0, - sizeof(dot11lcn_fltr_ctrl_tbl_rev0) / - sizeof(dot11lcn_fltr_ctrl_tbl_rev0[0]), 11, 0, 32} - , - {&dot11lcn_ps_ctrl_tbl_rev0, - sizeof(dot11lcn_ps_ctrl_tbl_rev0) / - sizeof(dot11lcn_ps_ctrl_tbl_rev0[0]), 12, 0, 32} - , - {&dot11lcn_gain_idx_tbl_rev0, - sizeof(dot11lcn_gain_idx_tbl_rev0) / - sizeof(dot11lcn_gain_idx_tbl_rev0[0]), 13, 0, 32} - , - {&dot11lcn_aux_gain_idx_tbl_rev0, - sizeof(dot11lcn_aux_gain_idx_tbl_rev0) / - sizeof(dot11lcn_aux_gain_idx_tbl_rev0[0]), 14, 0, 16} - , - {&dot11lcn_sw_ctrl_tbl_rev0, - sizeof(dot11lcn_sw_ctrl_tbl_rev0) / - sizeof(dot11lcn_sw_ctrl_tbl_rev0[0]), 15, 0, 16} - , - {&dot11lcn_nf_table_rev0, - sizeof(dot11lcn_nf_table_rev0) / sizeof(dot11lcn_nf_table_rev0[0]), 16, - 0, 8} - , - {&dot11lcn_gain_val_tbl_rev0, - sizeof(dot11lcn_gain_val_tbl_rev0) / - sizeof(dot11lcn_gain_val_tbl_rev0[0]), 17, 0, 8} - , - {&dot11lcn_gain_tbl_rev0, - sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18, - 0, 32} - , - {&dot11lcn_spur_tbl_rev0, - sizeof(dot11lcn_spur_tbl_rev0) / sizeof(dot11lcn_spur_tbl_rev0[0]), 20, - 0, 8} - , - {&dot11lcn_unsup_mcs_tbl_rev0, - sizeof(dot11lcn_unsup_mcs_tbl_rev0) / - sizeof(dot11lcn_unsup_mcs_tbl_rev0[0]), 23, 0, 16} - , - {&dot11lcn_iq_local_tbl_rev0, - sizeof(dot11lcn_iq_local_tbl_rev0) / - sizeof(dot11lcn_iq_local_tbl_rev0[0]), 0, 0, 16} - , - {&dot11lcn_papd_compdelta_tbl_rev0, - sizeof(dot11lcn_papd_compdelta_tbl_rev0) / - sizeof(dot11lcn_papd_compdelta_tbl_rev0[0]), 24, 0, 32} - , -}; - -const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313 = { - &dot11lcn_sw_ctrl_tbl_4313_rev0, - sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0) / - sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0[0]), 15, 0, 16 -}; - -const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_epa = { - &dot11lcn_sw_ctrl_tbl_4313_epa_rev0, - sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0) / - sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0[0]), 15, 0, 16 -}; - -const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa = { - &dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo, - sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo) / - sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[0]), 15, 0, 16 -}; - -const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250 = { - &dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0, - sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0) / - sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[0]), 15, 0, 16 -}; - -const u32 dot11lcnphytbl_info_sz_rev0 = - sizeof(dot11lcnphytbl_info_rev0) / sizeof(dot11lcnphytbl_info_rev0[0]); - -const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[128] = { - {3, 0, 31, 0, 72,} - , - {3, 0, 31, 0, 70,} - , - {3, 0, 31, 0, 68,} - , - {3, 0, 30, 0, 67,} - , - {3, 0, 29, 0, 68,} - , - {3, 0, 28, 0, 68,} - , - {3, 0, 27, 0, 69,} - , - {3, 0, 26, 0, 70,} - , - {3, 0, 25, 0, 70,} - , - {3, 0, 24, 0, 71,} - , - {3, 0, 23, 0, 72,} - , - {3, 0, 23, 0, 70,} - , - {3, 0, 22, 0, 71,} - , - {3, 0, 21, 0, 72,} - , - {3, 0, 21, 0, 70,} - , - {3, 0, 21, 0, 68,} - , - {3, 0, 21, 0, 66,} - , - {3, 0, 21, 0, 64,} - , - {3, 0, 21, 0, 63,} - , - {3, 0, 20, 0, 64,} - , - {3, 0, 19, 0, 65,} - , - {3, 0, 19, 0, 64,} - , - {3, 0, 18, 0, 65,} - , - {3, 0, 18, 0, 64,} - , - {3, 0, 17, 0, 65,} - , - {3, 0, 17, 0, 64,} - , - {3, 0, 16, 0, 65,} - , - {3, 0, 16, 0, 64,} - , - {3, 0, 16, 0, 62,} - , - {3, 0, 16, 0, 60,} - , - {3, 0, 16, 0, 58,} - , - {3, 0, 15, 0, 61,} - , - {3, 0, 15, 0, 59,} - , - {3, 0, 14, 0, 61,} - , - {3, 0, 14, 0, 60,} - , - {3, 0, 14, 0, 58,} - , - {3, 0, 13, 0, 60,} - , - {3, 0, 13, 0, 59,} - , - {3, 0, 12, 0, 62,} - , - {3, 0, 12, 0, 60,} - , - {3, 0, 12, 0, 58,} - , - {3, 0, 11, 0, 62,} - , - {3, 0, 11, 0, 60,} - , - {3, 0, 11, 0, 59,} - , - {3, 0, 11, 0, 57,} - , - {3, 0, 10, 0, 61,} - , - {3, 0, 10, 0, 59,} - , - {3, 0, 10, 0, 57,} - , - {3, 0, 9, 0, 62,} - , - {3, 0, 9, 0, 60,} - , - {3, 0, 9, 0, 58,} - , - {3, 0, 9, 0, 57,} - , - {3, 0, 8, 0, 62,} - , - {3, 0, 8, 0, 60,} - , - {3, 0, 8, 0, 58,} - , - {3, 0, 8, 0, 57,} - , - {3, 0, 8, 0, 55,} - , - {3, 0, 7, 0, 61,} - , - {3, 0, 7, 0, 60,} - , - {3, 0, 7, 0, 58,} - , - {3, 0, 7, 0, 56,} - , - {3, 0, 7, 0, 55,} - , - {3, 0, 6, 0, 62,} - , - {3, 0, 6, 0, 60,} - , - {3, 0, 6, 0, 58,} - , - {3, 0, 6, 0, 57,} - , - {3, 0, 6, 0, 55,} - , - {3, 0, 6, 0, 54,} - , - {3, 0, 6, 0, 52,} - , - {3, 0, 5, 0, 61,} - , - {3, 0, 5, 0, 59,} - , - {3, 0, 5, 0, 57,} - , - {3, 0, 5, 0, 56,} - , - {3, 0, 5, 0, 54,} - , - {3, 0, 5, 0, 53,} - , - {3, 0, 5, 0, 51,} - , - {3, 0, 4, 0, 62,} - , - {3, 0, 4, 0, 60,} - , - {3, 0, 4, 0, 58,} - , - {3, 0, 4, 0, 57,} - , - {3, 0, 4, 0, 55,} - , - {3, 0, 4, 0, 54,} - , - {3, 0, 4, 0, 52,} - , - {3, 0, 4, 0, 51,} - , - {3, 0, 4, 0, 49,} - , - {3, 0, 4, 0, 48,} - , - {3, 0, 4, 0, 46,} - , - {3, 0, 3, 0, 60,} - , - {3, 0, 3, 0, 58,} - , - {3, 0, 3, 0, 57,} - , - {3, 0, 3, 0, 55,} - , - {3, 0, 3, 0, 54,} - , - {3, 0, 3, 0, 52,} - , - {3, 0, 3, 0, 51,} - , - {3, 0, 3, 0, 49,} - , - {3, 0, 3, 0, 48,} - , - {3, 0, 3, 0, 46,} - , - {3, 0, 3, 0, 45,} - , - {3, 0, 3, 0, 44,} - , - {3, 0, 3, 0, 43,} - , - {3, 0, 3, 0, 41,} - , - {3, 0, 2, 0, 61,} - , - {3, 0, 2, 0, 59,} - , - {3, 0, 2, 0, 57,} - , - {3, 0, 2, 0, 56,} - , - {3, 0, 2, 0, 54,} - , - {3, 0, 2, 0, 53,} - , - {3, 0, 2, 0, 51,} - , - {3, 0, 2, 0, 50,} - , - {3, 0, 2, 0, 48,} - , - {3, 0, 2, 0, 47,} - , - {3, 0, 2, 0, 46,} - , - {3, 0, 2, 0, 44,} - , - {3, 0, 2, 0, 43,} - , - {3, 0, 2, 0, 42,} - , - {3, 0, 2, 0, 41,} - , - {3, 0, 2, 0, 39,} - , - {3, 0, 2, 0, 38,} - , - {3, 0, 2, 0, 37,} - , - {3, 0, 2, 0, 36,} - , - {3, 0, 2, 0, 35,} - , - {3, 0, 2, 0, 34,} - , - {3, 0, 2, 0, 33,} - , - {3, 0, 2, 0, 32,} - , - {3, 0, 1, 0, 63,} - , - {3, 0, 1, 0, 61,} - , - {3, 0, 1, 0, 59,} - , - {3, 0, 1, 0, 57,} - , -}; - -const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[128] = { - {7, 0, 31, 0, 72,} - , - {7, 0, 31, 0, 70,} - , - {7, 0, 31, 0, 68,} - , - {7, 0, 30, 0, 67,} - , - {7, 0, 29, 0, 68,} - , - {7, 0, 28, 0, 68,} - , - {7, 0, 27, 0, 69,} - , - {7, 0, 26, 0, 70,} - , - {7, 0, 25, 0, 70,} - , - {7, 0, 24, 0, 71,} - , - {7, 0, 23, 0, 72,} - , - {7, 0, 23, 0, 70,} - , - {7, 0, 22, 0, 71,} - , - {7, 0, 21, 0, 72,} - , - {7, 0, 21, 0, 70,} - , - {7, 0, 21, 0, 68,} - , - {7, 0, 21, 0, 66,} - , - {7, 0, 21, 0, 64,} - , - {7, 0, 21, 0, 63,} - , - {7, 0, 20, 0, 64,} - , - {7, 0, 19, 0, 65,} - , - {7, 0, 19, 0, 64,} - , - {7, 0, 18, 0, 65,} - , - {7, 0, 18, 0, 64,} - , - {7, 0, 17, 0, 65,} - , - {7, 0, 17, 0, 64,} - , - {7, 0, 16, 0, 65,} - , - {7, 0, 16, 0, 64,} - , - {7, 0, 16, 0, 62,} - , - {7, 0, 16, 0, 60,} - , - {7, 0, 16, 0, 58,} - , - {7, 0, 15, 0, 61,} - , - {7, 0, 15, 0, 59,} - , - {7, 0, 14, 0, 61,} - , - {7, 0, 14, 0, 60,} - , - {7, 0, 14, 0, 58,} - , - {7, 0, 13, 0, 60,} - , - {7, 0, 13, 0, 59,} - , - {7, 0, 12, 0, 62,} - , - {7, 0, 12, 0, 60,} - , - {7, 0, 12, 0, 58,} - , - {7, 0, 11, 0, 62,} - , - {7, 0, 11, 0, 60,} - , - {7, 0, 11, 0, 59,} - , - {7, 0, 11, 0, 57,} - , - {7, 0, 10, 0, 61,} - , - {7, 0, 10, 0, 59,} - , - {7, 0, 10, 0, 57,} - , - {7, 0, 9, 0, 62,} - , - {7, 0, 9, 0, 60,} - , - {7, 0, 9, 0, 58,} - , - {7, 0, 9, 0, 57,} - , - {7, 0, 8, 0, 62,} - , - {7, 0, 8, 0, 60,} - , - {7, 0, 8, 0, 58,} - , - {7, 0, 8, 0, 57,} - , - {7, 0, 8, 0, 55,} - , - {7, 0, 7, 0, 61,} - , - {7, 0, 7, 0, 60,} - , - {7, 0, 7, 0, 58,} - , - {7, 0, 7, 0, 56,} - , - {7, 0, 7, 0, 55,} - , - {7, 0, 6, 0, 62,} - , - {7, 0, 6, 0, 60,} - , - {7, 0, 6, 0, 58,} - , - {7, 0, 6, 0, 57,} - , - {7, 0, 6, 0, 55,} - , - {7, 0, 6, 0, 54,} - , - {7, 0, 6, 0, 52,} - , - {7, 0, 5, 0, 61,} - , - {7, 0, 5, 0, 59,} - , - {7, 0, 5, 0, 57,} - , - {7, 0, 5, 0, 56,} - , - {7, 0, 5, 0, 54,} - , - {7, 0, 5, 0, 53,} - , - {7, 0, 5, 0, 51,} - , - {7, 0, 4, 0, 62,} - , - {7, 0, 4, 0, 60,} - , - {7, 0, 4, 0, 58,} - , - {7, 0, 4, 0, 57,} - , - {7, 0, 4, 0, 55,} - , - {7, 0, 4, 0, 54,} - , - {7, 0, 4, 0, 52,} - , - {7, 0, 4, 0, 51,} - , - {7, 0, 4, 0, 49,} - , - {7, 0, 4, 0, 48,} - , - {7, 0, 4, 0, 46,} - , - {7, 0, 3, 0, 60,} - , - {7, 0, 3, 0, 58,} - , - {7, 0, 3, 0, 57,} - , - {7, 0, 3, 0, 55,} - , - {7, 0, 3, 0, 54,} - , - {7, 0, 3, 0, 52,} - , - {7, 0, 3, 0, 51,} - , - {7, 0, 3, 0, 49,} - , - {7, 0, 3, 0, 48,} - , - {7, 0, 3, 0, 46,} - , - {7, 0, 3, 0, 45,} - , - {7, 0, 3, 0, 44,} - , - {7, 0, 3, 0, 43,} - , - {7, 0, 3, 0, 41,} - , - {7, 0, 2, 0, 61,} - , - {7, 0, 2, 0, 59,} - , - {7, 0, 2, 0, 57,} - , - {7, 0, 2, 0, 56,} - , - {7, 0, 2, 0, 54,} - , - {7, 0, 2, 0, 53,} - , - {7, 0, 2, 0, 51,} - , - {7, 0, 2, 0, 50,} - , - {7, 0, 2, 0, 48,} - , - {7, 0, 2, 0, 47,} - , - {7, 0, 2, 0, 46,} - , - {7, 0, 2, 0, 44,} - , - {7, 0, 2, 0, 43,} - , - {7, 0, 2, 0, 42,} - , - {7, 0, 2, 0, 41,} - , - {7, 0, 2, 0, 39,} - , - {7, 0, 2, 0, 38,} - , - {7, 0, 2, 0, 37,} - , - {7, 0, 2, 0, 36,} - , - {7, 0, 2, 0, 35,} - , - {7, 0, 2, 0, 34,} - , - {7, 0, 2, 0, 33,} - , - {7, 0, 2, 0, 32,} - , - {7, 0, 1, 0, 63,} - , - {7, 0, 1, 0, 61,} - , - {7, 0, 1, 0, 59,} - , - {7, 0, 1, 0, 57,} - , -}; - -const lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[128] = { - {255, 255, 0xf0, 0, 152,} - , - {255, 255, 0xf0, 0, 147,} - , - {255, 255, 0xf0, 0, 143,} - , - {255, 255, 0xf0, 0, 139,} - , - {255, 255, 0xf0, 0, 135,} - , - {255, 255, 0xf0, 0, 131,} - , - {255, 255, 0xf0, 0, 128,} - , - {255, 255, 0xf0, 0, 124,} - , - {255, 255, 0xf0, 0, 121,} - , - {255, 255, 0xf0, 0, 117,} - , - {255, 255, 0xf0, 0, 114,} - , - {255, 255, 0xf0, 0, 111,} - , - {255, 255, 0xf0, 0, 107,} - , - {255, 255, 0xf0, 0, 104,} - , - {255, 255, 0xf0, 0, 101,} - , - {255, 255, 0xf0, 0, 99,} - , - {255, 255, 0xf0, 0, 96,} - , - {255, 255, 0xf0, 0, 93,} - , - {255, 255, 0xf0, 0, 90,} - , - {255, 255, 0xf0, 0, 88,} - , - {255, 255, 0xf0, 0, 85,} - , - {255, 255, 0xf0, 0, 83,} - , - {255, 255, 0xf0, 0, 81,} - , - {255, 255, 0xf0, 0, 78,} - , - {255, 255, 0xf0, 0, 76,} - , - {255, 255, 0xf0, 0, 74,} - , - {255, 255, 0xf0, 0, 72,} - , - {255, 255, 0xf0, 0, 70,} - , - {255, 255, 0xf0, 0, 68,} - , - {255, 255, 0xf0, 0, 66,} - , - {255, 255, 0xf0, 0, 64,} - , - {255, 248, 0xf0, 0, 64,} - , - {255, 241, 0xf0, 0, 64,} - , - {255, 251, 0xe0, 0, 64,} - , - {255, 244, 0xe0, 0, 64,} - , - {255, 254, 0xd0, 0, 64,} - , - {255, 246, 0xd0, 0, 64,} - , - {255, 239, 0xd0, 0, 64,} - , - {255, 249, 0xc0, 0, 64,} - , - {255, 242, 0xc0, 0, 64,} - , - {255, 255, 0xb0, 0, 64,} - , - {255, 248, 0xb0, 0, 64,} - , - {255, 241, 0xb0, 0, 64,} - , - {255, 254, 0xa0, 0, 64,} - , - {255, 246, 0xa0, 0, 64,} - , - {255, 239, 0xa0, 0, 64,} - , - {255, 255, 0x90, 0, 64,} - , - {255, 248, 0x90, 0, 64,} - , - {255, 241, 0x90, 0, 64,} - , - {255, 234, 0x90, 0, 64,} - , - {255, 255, 0x80, 0, 64,} - , - {255, 248, 0x80, 0, 64,} - , - {255, 241, 0x80, 0, 64,} - , - {255, 234, 0x80, 0, 64,} - , - {255, 255, 0x70, 0, 64,} - , - {255, 248, 0x70, 0, 64,} - , - {255, 241, 0x70, 0, 64,} - , - {255, 234, 0x70, 0, 64,} - , - {255, 227, 0x70, 0, 64,} - , - {255, 221, 0x70, 0, 64,} - , - {255, 215, 0x70, 0, 64,} - , - {255, 208, 0x70, 0, 64,} - , - {255, 203, 0x70, 0, 64,} - , - {255, 197, 0x70, 0, 64,} - , - {255, 255, 0x60, 0, 64,} - , - {255, 248, 0x60, 0, 64,} - , - {255, 241, 0x60, 0, 64,} - , - {255, 234, 0x60, 0, 64,} - , - {255, 227, 0x60, 0, 64,} - , - {255, 221, 0x60, 0, 64,} - , - {255, 255, 0x50, 0, 64,} - , - {255, 248, 0x50, 0, 64,} - , - {255, 241, 0x50, 0, 64,} - , - {255, 234, 0x50, 0, 64,} - , - {255, 227, 0x50, 0, 64,} - , - {255, 221, 0x50, 0, 64,} - , - {255, 215, 0x50, 0, 64,} - , - {255, 208, 0x50, 0, 64,} - , - {255, 255, 0x40, 0, 64,} - , - {255, 248, 0x40, 0, 64,} - , - {255, 241, 0x40, 0, 64,} - , - {255, 234, 0x40, 0, 64,} - , - {255, 227, 0x40, 0, 64,} - , - {255, 221, 0x40, 0, 64,} - , - {255, 215, 0x40, 0, 64,} - , - {255, 208, 0x40, 0, 64,} - , - {255, 203, 0x40, 0, 64,} - , - {255, 197, 0x40, 0, 64,} - , - {255, 255, 0x30, 0, 64,} - , - {255, 248, 0x30, 0, 64,} - , - {255, 241, 0x30, 0, 64,} - , - {255, 234, 0x30, 0, 64,} - , - {255, 227, 0x30, 0, 64,} - , - {255, 221, 0x30, 0, 64,} - , - {255, 215, 0x30, 0, 64,} - , - {255, 208, 0x30, 0, 64,} - , - {255, 203, 0x30, 0, 64,} - , - {255, 197, 0x30, 0, 64,} - , - {255, 191, 0x30, 0, 64,} - , - {255, 186, 0x30, 0, 64,} - , - {255, 181, 0x30, 0, 64,} - , - {255, 175, 0x30, 0, 64,} - , - {255, 255, 0x20, 0, 64,} - , - {255, 248, 0x20, 0, 64,} - , - {255, 241, 0x20, 0, 64,} - , - {255, 234, 0x20, 0, 64,} - , - {255, 227, 0x20, 0, 64,} - , - {255, 221, 0x20, 0, 64,} - , - {255, 215, 0x20, 0, 64,} - , - {255, 208, 0x20, 0, 64,} - , - {255, 203, 0x20, 0, 64,} - , - {255, 197, 0x20, 0, 64,} - , - {255, 191, 0x20, 0, 64,} - , - {255, 186, 0x20, 0, 64,} - , - {255, 181, 0x20, 0, 64,} - , - {255, 175, 0x20, 0, 64,} - , - {255, 170, 0x20, 0, 64,} - , - {255, 166, 0x20, 0, 64,} - , - {255, 161, 0x20, 0, 64,} - , - {255, 156, 0x20, 0, 64,} - , - {255, 152, 0x20, 0, 64,} - , - {255, 148, 0x20, 0, 64,} - , - {255, 143, 0x20, 0, 64,} - , - {255, 139, 0x20, 0, 64,} - , - {255, 135, 0x20, 0, 64,} - , - {255, 132, 0x20, 0, 64,} - , - {255, 255, 0x10, 0, 64,} - , - {255, 248, 0x10, 0, 64,} - , -}; diff --git a/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.h b/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.h deleted file mode 100644 index 5a64a988d107..000000000000 --- a/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -typedef phytbl_info_t dot11lcnphytbl_info_t; - -extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev0[]; -extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev0; -extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313; -extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_epa; -extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_epa_combo; - -extern const dot11lcnphytbl_info_t dot11lcnphytbl_info_rev0[]; -extern const u32 dot11lcnphytbl_info_sz_rev0; - -extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_2G_rev2[]; -extern const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz; - -extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_5G_rev2[]; -extern const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz; - -extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[]; - -extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[]; - -typedef struct { - unsigned char gm; - unsigned char pga; - unsigned char pad; - unsigned char dac; - unsigned char bb_mult; -} lcnphy_tx_gain_tbl_entry; - -extern const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[]; -extern const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[]; - -extern const lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[]; diff --git a/drivers/staging/brcm80211/phy/wlc_phytbl_n.c b/drivers/staging/brcm80211/phy/wlc_phytbl_n.c deleted file mode 100644 index a9fc193721ef..000000000000 --- a/drivers/staging/brcm80211/phy/wlc_phytbl_n.c +++ /dev/null @@ -1,10634 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include - -#include -#include -#include -#include -#include - -const u32 frame_struct_rev0[] = { - 0x08004a04, - 0x00100000, - 0x01000a05, - 0x00100020, - 0x09804506, - 0x00100030, - 0x09804507, - 0x00100030, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x08004a0c, - 0x00100004, - 0x01000a0d, - 0x00100024, - 0x0980450e, - 0x00100034, - 0x0980450f, - 0x00100034, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000a04, - 0x00100000, - 0x11008a05, - 0x00100020, - 0x1980c506, - 0x00100030, - 0x21810506, - 0x00100030, - 0x21810506, - 0x00100030, - 0x01800504, - 0x00100030, - 0x11808505, - 0x00100030, - 0x29814507, - 0x01100030, - 0x00000a04, - 0x00100000, - 0x11008a05, - 0x00100020, - 0x21810506, - 0x00100030, - 0x21810506, - 0x00100030, - 0x29814507, - 0x01100030, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000a0c, - 0x00100008, - 0x11008a0d, - 0x00100028, - 0x1980c50e, - 0x00100038, - 0x2181050e, - 0x00100038, - 0x2181050e, - 0x00100038, - 0x0180050c, - 0x00100038, - 0x1180850d, - 0x00100038, - 0x2981450f, - 0x01100038, - 0x00000a0c, - 0x00100008, - 0x11008a0d, - 0x00100028, - 0x2181050e, - 0x00100038, - 0x2181050e, - 0x00100038, - 0x2981450f, - 0x01100038, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x08004a04, - 0x00100000, - 0x01000a05, - 0x00100020, - 0x1980c506, - 0x00100030, - 0x1980c506, - 0x00100030, - 0x11808504, - 0x00100030, - 0x3981ca05, - 0x00100030, - 0x29814507, - 0x01100030, - 0x00000000, - 0x00000000, - 0x10008a04, - 0x00100000, - 0x3981ca05, - 0x00100030, - 0x1980c506, - 0x00100030, - 0x29814507, - 0x01100030, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x08004a0c, - 0x00100008, - 0x01000a0d, - 0x00100028, - 0x1980c50e, - 0x00100038, - 0x1980c50e, - 0x00100038, - 0x1180850c, - 0x00100038, - 0x3981ca0d, - 0x00100038, - 0x2981450f, - 0x01100038, - 0x00000000, - 0x00000000, - 0x10008a0c, - 0x00100008, - 0x3981ca0d, - 0x00100038, - 0x1980c50e, - 0x00100038, - 0x2981450f, - 0x01100038, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x40021404, - 0x00100000, - 0x02001405, - 0x00100040, - 0x0b004a06, - 0x01900060, - 0x13008a06, - 0x01900060, - 0x13008a06, - 0x01900060, - 0x43020a04, - 0x00100060, - 0x1b00ca05, - 0x00100060, - 0x23010a07, - 0x01500060, - 0x40021404, - 0x00100000, - 0x1a00d405, - 0x00100040, - 0x13008a06, - 0x01900060, - 0x13008a06, - 0x01900060, - 0x23010a07, - 0x01500060, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x4002140c, - 0x00100010, - 0x0200140d, - 0x00100050, - 0x0b004a0e, - 0x01900070, - 0x13008a0e, - 0x01900070, - 0x13008a0e, - 0x01900070, - 0x43020a0c, - 0x00100070, - 0x1b00ca0d, - 0x00100070, - 0x23010a0f, - 0x01500070, - 0x4002140c, - 0x00100010, - 0x1a00d40d, - 0x00100050, - 0x13008a0e, - 0x01900070, - 0x13008a0e, - 0x01900070, - 0x23010a0f, - 0x01500070, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x50029404, - 0x00100000, - 0x32019405, - 0x00100040, - 0x0b004a06, - 0x01900060, - 0x0b004a06, - 0x01900060, - 0x5b02ca04, - 0x00100060, - 0x3b01d405, - 0x00100060, - 0x23010a07, - 0x01500060, - 0x00000000, - 0x00000000, - 0x5802d404, - 0x00100000, - 0x3b01d405, - 0x00100060, - 0x0b004a06, - 0x01900060, - 0x23010a07, - 0x01500060, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x5002940c, - 0x00100010, - 0x3201940d, - 0x00100050, - 0x0b004a0e, - 0x01900070, - 0x0b004a0e, - 0x01900070, - 0x5b02ca0c, - 0x00100070, - 0x3b01d40d, - 0x00100070, - 0x23010a0f, - 0x01500070, - 0x00000000, - 0x00000000, - 0x5802d40c, - 0x00100010, - 0x3b01d40d, - 0x00100070, - 0x0b004a0e, - 0x01900070, - 0x23010a0f, - 0x01500070, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x40021404, - 0x000f4800, - 0x62031405, - 0x00100040, - 0x53028a06, - 0x01900060, - 0x53028a07, - 0x01900060, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x4002140c, - 0x000f4808, - 0x6203140d, - 0x00100048, - 0x53028a0e, - 0x01900068, - 0x53028a0f, - 0x01900068, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000a0c, - 0x00100004, - 0x11008a0d, - 0x00100024, - 0x1980c50e, - 0x00100034, - 0x2181050e, - 0x00100034, - 0x2181050e, - 0x00100034, - 0x0180050c, - 0x00100038, - 0x1180850d, - 0x00100038, - 0x1181850d, - 0x00100038, - 0x2981450f, - 0x01100038, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000a0c, - 0x00100008, - 0x11008a0d, - 0x00100028, - 0x2181050e, - 0x00100038, - 0x2181050e, - 0x00100038, - 0x1181850d, - 0x00100038, - 0x2981450f, - 0x01100038, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x08004a04, - 0x00100000, - 0x01000a05, - 0x00100020, - 0x0180c506, - 0x00100030, - 0x0180c506, - 0x00100030, - 0x2180c50c, - 0x00100030, - 0x49820a0d, - 0x0016a130, - 0x41824a0d, - 0x0016a130, - 0x2981450f, - 0x01100030, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x2000ca0c, - 0x00100000, - 0x49820a0d, - 0x0016a130, - 0x1980c50e, - 0x00100030, - 0x41824a0d, - 0x0016a130, - 0x2981450f, - 0x01100030, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x4002140c, - 0x00100008, - 0x0200140d, - 0x00100048, - 0x0b004a0e, - 0x01900068, - 0x13008a0e, - 0x01900068, - 0x13008a0e, - 0x01900068, - 0x43020a0c, - 0x00100070, - 0x1b00ca0d, - 0x00100070, - 0x1b014a0d, - 0x00100070, - 0x23010a0f, - 0x01500070, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x4002140c, - 0x00100010, - 0x1a00d40d, - 0x00100050, - 0x13008a0e, - 0x01900070, - 0x13008a0e, - 0x01900070, - 0x1b014a0d, - 0x00100070, - 0x23010a0f, - 0x01500070, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x50029404, - 0x00100000, - 0x32019405, - 0x00100040, - 0x03004a06, - 0x01900060, - 0x03004a06, - 0x01900060, - 0x6b030a0c, - 0x00100060, - 0x4b02140d, - 0x0016a160, - 0x4302540d, - 0x0016a160, - 0x23010a0f, - 0x01500060, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x6b03140c, - 0x00100060, - 0x4b02140d, - 0x0016a160, - 0x0b004a0e, - 0x01900060, - 0x4302540d, - 0x0016a160, - 0x23010a0f, - 0x01500060, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x40021404, - 0x00100000, - 0x1a00d405, - 0x00100040, - 0x53028a06, - 0x01900060, - 0x5b02ca06, - 0x01900060, - 0x5b02ca06, - 0x01900060, - 0x43020a04, - 0x00100060, - 0x1b00ca05, - 0x00100060, - 0x53028a07, - 0x0190c060, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x4002140c, - 0x00100010, - 0x1a00d40d, - 0x00100050, - 0x53028a0e, - 0x01900070, - 0x5b02ca0e, - 0x01900070, - 0x5b02ca0e, - 0x01900070, - 0x43020a0c, - 0x00100070, - 0x1b00ca0d, - 0x00100070, - 0x53028a0f, - 0x0190c070, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x40021404, - 0x00100000, - 0x1a00d405, - 0x00100040, - 0x5b02ca06, - 0x01900060, - 0x5b02ca06, - 0x01900060, - 0x53028a07, - 0x0190c060, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x4002140c, - 0x00100010, - 0x1a00d40d, - 0x00100050, - 0x5b02ca0e, - 0x01900070, - 0x5b02ca0e, - 0x01900070, - 0x53028a0f, - 0x0190c070, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -const u8 frame_lut_rev0[] = { - 0x02, - 0x04, - 0x14, - 0x14, - 0x03, - 0x05, - 0x16, - 0x16, - 0x0a, - 0x0c, - 0x1c, - 0x1c, - 0x0b, - 0x0d, - 0x1e, - 0x1e, - 0x06, - 0x08, - 0x18, - 0x18, - 0x07, - 0x09, - 0x1a, - 0x1a, - 0x0e, - 0x10, - 0x20, - 0x28, - 0x0f, - 0x11, - 0x22, - 0x2a, -}; - -const u32 tmap_tbl_rev0[] = { - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0xf1111110, - 0x11111111, - 0x11f11111, - 0x00000111, - 0x11000000, - 0x1111f111, - 0x11111111, - 0x111111f1, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x000aa888, - 0x88880000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0xa1111110, - 0x11111111, - 0x11c11111, - 0x00000111, - 0x11000000, - 0x1111a111, - 0x11111111, - 0x111111a1, - 0xa2222220, - 0x22222222, - 0x22c22222, - 0x00000222, - 0x22000000, - 0x2222a222, - 0x22222222, - 0x222222a2, - 0xf1111110, - 0x11111111, - 0x11f11111, - 0x00011111, - 0x11110000, - 0x1111f111, - 0x11111111, - 0x111111f1, - 0xa8aa88a0, - 0xa88888a8, - 0xa8a8a88a, - 0x00088aaa, - 0xaaaa0000, - 0xa8a8aa88, - 0xa88aaaaa, - 0xaaaa8a8a, - 0xaaa8aaa0, - 0x8aaa8aaa, - 0xaa8a8a8a, - 0x000aaa88, - 0x8aaa0000, - 0xaaa8a888, - 0x8aa88a8a, - 0x8a88a888, - 0x08080a00, - 0x0a08080a, - 0x080a0a08, - 0x00080808, - 0x080a0000, - 0x080a0808, - 0x080a0808, - 0x0a0a0a08, - 0xa0a0a0a0, - 0x80a0a080, - 0x8080a0a0, - 0x00008080, - 0x80a00000, - 0x80a080a0, - 0xa080a0a0, - 0x8080a0a0, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x99999000, - 0x9b9b99bb, - 0x9bb99999, - 0x9999b9b9, - 0x9b99bb90, - 0x9bbbbb9b, - 0x9b9b9bb9, - 0x00000999, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00aaa888, - 0x22000000, - 0x2222b222, - 0x22222222, - 0x222222b2, - 0xb2222220, - 0x22222222, - 0x22d22222, - 0x00000222, - 0x11000000, - 0x1111a111, - 0x11111111, - 0x111111a1, - 0xa1111110, - 0x11111111, - 0x11c11111, - 0x00000111, - 0x33000000, - 0x3333b333, - 0x33333333, - 0x333333b3, - 0xb3333330, - 0x33333333, - 0x33d33333, - 0x00000333, - 0x22000000, - 0x2222a222, - 0x22222222, - 0x222222a2, - 0xa2222220, - 0x22222222, - 0x22c22222, - 0x00000222, - 0x99b99b00, - 0x9b9b99bb, - 0x9bb99999, - 0x9999b9b9, - 0x9b99bb99, - 0x9bbbbb9b, - 0x9b9b9bb9, - 0x00000999, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa88, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x08aaa888, - 0x22222200, - 0x2222f222, - 0x22222222, - 0x222222f2, - 0x22222222, - 0x22222222, - 0x22f22222, - 0x00000222, - 0x11000000, - 0x1111f111, - 0x11111111, - 0x11111111, - 0xf1111111, - 0x11111111, - 0x11f11111, - 0x01111111, - 0xbb9bb900, - 0xb9b9bb99, - 0xb99bbbbb, - 0xbbbb9b9b, - 0xb9bb99bb, - 0xb99999b9, - 0xb9b9b99b, - 0x00000bbb, - 0xaa000000, - 0xa8a8aa88, - 0xa88aaaaa, - 0xaaaa8a8a, - 0xa8aa88aa, - 0xa88888a8, - 0xa8a8a88a, - 0x0a888aaa, - 0xaa000000, - 0xa8a8aa88, - 0xa88aaaaa, - 0xaaaa8a8a, - 0xa8aa88a0, - 0xa88888a8, - 0xa8a8a88a, - 0x00000aaa, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0xbbbbbb00, - 0x999bbbbb, - 0x9bb99b9b, - 0xb9b9b9bb, - 0xb9b99bbb, - 0xb9b9b9bb, - 0xb9bb9b99, - 0x00000999, - 0x8a000000, - 0xaa88a888, - 0xa88888aa, - 0xa88a8a88, - 0xa88aa88a, - 0x88a8aaaa, - 0xa8aa8aaa, - 0x0888a88a, - 0x0b0b0b00, - 0x090b0b0b, - 0x0b090b0b, - 0x0909090b, - 0x09090b0b, - 0x09090b0b, - 0x09090b09, - 0x00000909, - 0x0a000000, - 0x0a080808, - 0x080a080a, - 0x080a0a08, - 0x080a080a, - 0x0808080a, - 0x0a0a0a08, - 0x0808080a, - 0xb0b0b000, - 0x9090b0b0, - 0x90b09090, - 0xb0b0b090, - 0xb0b090b0, - 0x90b0b0b0, - 0xb0b09090, - 0x00000090, - 0x80000000, - 0xa080a080, - 0xa08080a0, - 0xa0808080, - 0xa080a080, - 0x80a0a0a0, - 0xa0a080a0, - 0x00a0a0a0, - 0x22000000, - 0x2222f222, - 0x22222222, - 0x222222f2, - 0xf2222220, - 0x22222222, - 0x22f22222, - 0x00000222, - 0x11000000, - 0x1111f111, - 0x11111111, - 0x111111f1, - 0xf1111110, - 0x11111111, - 0x11f11111, - 0x00000111, - 0x33000000, - 0x3333f333, - 0x33333333, - 0x333333f3, - 0xf3333330, - 0x33333333, - 0x33f33333, - 0x00000333, - 0x22000000, - 0x2222f222, - 0x22222222, - 0x222222f2, - 0xf2222220, - 0x22222222, - 0x22f22222, - 0x00000222, - 0x99000000, - 0x9b9b99bb, - 0x9bb99999, - 0x9999b9b9, - 0x9b99bb90, - 0x9bbbbb9b, - 0x9b9b9bb9, - 0x00000999, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0x88888000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00aaa888, - 0x88a88a00, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa88, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa88, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x08aaa888, - 0x11000000, - 0x1111a111, - 0x11111111, - 0x111111a1, - 0xa1111110, - 0x11111111, - 0x11c11111, - 0x00000111, - 0x11000000, - 0x1111a111, - 0x11111111, - 0x111111a1, - 0xa1111110, - 0x11111111, - 0x11c11111, - 0x00000111, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -const u32 tdtrn_tbl_rev0[] = { - 0x061c061c, - 0x0050ee68, - 0xf592fe36, - 0xfe5212f6, - 0x00000c38, - 0xfe5212f6, - 0xf592fe36, - 0x0050ee68, - 0x061c061c, - 0xee680050, - 0xfe36f592, - 0x12f6fe52, - 0x0c380000, - 0x12f6fe52, - 0xfe36f592, - 0xee680050, - 0x061c061c, - 0x0050ee68, - 0xf592fe36, - 0xfe5212f6, - 0x00000c38, - 0xfe5212f6, - 0xf592fe36, - 0x0050ee68, - 0x061c061c, - 0xee680050, - 0xfe36f592, - 0x12f6fe52, - 0x0c380000, - 0x12f6fe52, - 0xfe36f592, - 0xee680050, - 0x05e305e3, - 0x004def0c, - 0xf5f3fe47, - 0xfe611246, - 0x00000bc7, - 0xfe611246, - 0xf5f3fe47, - 0x004def0c, - 0x05e305e3, - 0xef0c004d, - 0xfe47f5f3, - 0x1246fe61, - 0x0bc70000, - 0x1246fe61, - 0xfe47f5f3, - 0xef0c004d, - 0x05e305e3, - 0x004def0c, - 0xf5f3fe47, - 0xfe611246, - 0x00000bc7, - 0xfe611246, - 0xf5f3fe47, - 0x004def0c, - 0x05e305e3, - 0xef0c004d, - 0xfe47f5f3, - 0x1246fe61, - 0x0bc70000, - 0x1246fe61, - 0xfe47f5f3, - 0xef0c004d, - 0xfa58fa58, - 0xf895043b, - 0xff4c09c0, - 0xfbc6ffa8, - 0xfb84f384, - 0x0798f6f9, - 0x05760122, - 0x058409f6, - 0x0b500000, - 0x05b7f542, - 0x08860432, - 0x06ddfee7, - 0xfb84f384, - 0xf9d90664, - 0xf7e8025c, - 0x00fff7bd, - 0x05a805a8, - 0xf7bd00ff, - 0x025cf7e8, - 0x0664f9d9, - 0xf384fb84, - 0xfee706dd, - 0x04320886, - 0xf54205b7, - 0x00000b50, - 0x09f60584, - 0x01220576, - 0xf6f90798, - 0xf384fb84, - 0xffa8fbc6, - 0x09c0ff4c, - 0x043bf895, - 0x02d402d4, - 0x07de0270, - 0xfc96079c, - 0xf90afe94, - 0xfe00ff2c, - 0x02d4065d, - 0x092a0096, - 0x0014fbb8, - 0xfd2cfd2c, - 0x076afb3c, - 0x0096f752, - 0xf991fd87, - 0xfb2c0200, - 0xfeb8f960, - 0x08e0fc96, - 0x049802a8, - 0xfd2cfd2c, - 0x02a80498, - 0xfc9608e0, - 0xf960feb8, - 0x0200fb2c, - 0xfd87f991, - 0xf7520096, - 0xfb3c076a, - 0xfd2cfd2c, - 0xfbb80014, - 0x0096092a, - 0x065d02d4, - 0xff2cfe00, - 0xfe94f90a, - 0x079cfc96, - 0x027007de, - 0x02d402d4, - 0x027007de, - 0x079cfc96, - 0xfe94f90a, - 0xff2cfe00, - 0x065d02d4, - 0x0096092a, - 0xfbb80014, - 0xfd2cfd2c, - 0xfb3c076a, - 0xf7520096, - 0xfd87f991, - 0x0200fb2c, - 0xf960feb8, - 0xfc9608e0, - 0x02a80498, - 0xfd2cfd2c, - 0x049802a8, - 0x08e0fc96, - 0xfeb8f960, - 0xfb2c0200, - 0xf991fd87, - 0x0096f752, - 0x076afb3c, - 0xfd2cfd2c, - 0x0014fbb8, - 0x092a0096, - 0x02d4065d, - 0xfe00ff2c, - 0xf90afe94, - 0xfc96079c, - 0x07de0270, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x062a0000, - 0xfefa0759, - 0x08b80908, - 0xf396fc2d, - 0xf9d6045c, - 0xfc4ef608, - 0xf748f596, - 0x07b207bf, - 0x062a062a, - 0xf84ef841, - 0xf748f596, - 0x03b209f8, - 0xf9d6045c, - 0x0c6a03d3, - 0x08b80908, - 0x0106f8a7, - 0x062a0000, - 0xfefaf8a7, - 0x08b8f6f8, - 0xf39603d3, - 0xf9d6fba4, - 0xfc4e09f8, - 0xf7480a6a, - 0x07b2f841, - 0x062af9d6, - 0xf84e07bf, - 0xf7480a6a, - 0x03b2f608, - 0xf9d6fba4, - 0x0c6afc2d, - 0x08b8f6f8, - 0x01060759, - 0x062a0000, - 0xfefa0759, - 0x08b80908, - 0xf396fc2d, - 0xf9d6045c, - 0xfc4ef608, - 0xf748f596, - 0x07b207bf, - 0x062a062a, - 0xf84ef841, - 0xf748f596, - 0x03b209f8, - 0xf9d6045c, - 0x0c6a03d3, - 0x08b80908, - 0x0106f8a7, - 0x062a0000, - 0xfefaf8a7, - 0x08b8f6f8, - 0xf39603d3, - 0xf9d6fba4, - 0xfc4e09f8, - 0xf7480a6a, - 0x07b2f841, - 0x062af9d6, - 0xf84e07bf, - 0xf7480a6a, - 0x03b2f608, - 0xf9d6fba4, - 0x0c6afc2d, - 0x08b8f6f8, - 0x01060759, - 0x061c061c, - 0xff30009d, - 0xffb21141, - 0xfd87fb54, - 0xf65dfe59, - 0x02eef99e, - 0x0166f03c, - 0xfff809b6, - 0x000008a4, - 0x000af42b, - 0x00eff577, - 0xfa840bf2, - 0xfc02ff51, - 0x08260f67, - 0xfff0036f, - 0x0842f9c3, - 0x00000000, - 0x063df7be, - 0xfc910010, - 0xf099f7da, - 0x00af03fe, - 0xf40e057c, - 0x0a89ff11, - 0x0bd5fff6, - 0xf75c0000, - 0xf64a0008, - 0x0fc4fe9a, - 0x0662fd12, - 0x01a709a3, - 0x04ac0279, - 0xeebf004e, - 0xff6300d0, - 0xf9e4f9e4, - 0x00d0ff63, - 0x004eeebf, - 0x027904ac, - 0x09a301a7, - 0xfd120662, - 0xfe9a0fc4, - 0x0008f64a, - 0x0000f75c, - 0xfff60bd5, - 0xff110a89, - 0x057cf40e, - 0x03fe00af, - 0xf7daf099, - 0x0010fc91, - 0xf7be063d, - 0x00000000, - 0xf9c30842, - 0x036ffff0, - 0x0f670826, - 0xff51fc02, - 0x0bf2fa84, - 0xf57700ef, - 0xf42b000a, - 0x08a40000, - 0x09b6fff8, - 0xf03c0166, - 0xf99e02ee, - 0xfe59f65d, - 0xfb54fd87, - 0x1141ffb2, - 0x009dff30, - 0x05e30000, - 0xff060705, - 0x085408a0, - 0xf425fc59, - 0xfa1d042a, - 0xfc78f67a, - 0xf7acf60e, - 0x075a0766, - 0x05e305e3, - 0xf8a6f89a, - 0xf7acf60e, - 0x03880986, - 0xfa1d042a, - 0x0bdb03a7, - 0x085408a0, - 0x00faf8fb, - 0x05e30000, - 0xff06f8fb, - 0x0854f760, - 0xf42503a7, - 0xfa1dfbd6, - 0xfc780986, - 0xf7ac09f2, - 0x075af89a, - 0x05e3fa1d, - 0xf8a60766, - 0xf7ac09f2, - 0x0388f67a, - 0xfa1dfbd6, - 0x0bdbfc59, - 0x0854f760, - 0x00fa0705, - 0x05e30000, - 0xff060705, - 0x085408a0, - 0xf425fc59, - 0xfa1d042a, - 0xfc78f67a, - 0xf7acf60e, - 0x075a0766, - 0x05e305e3, - 0xf8a6f89a, - 0xf7acf60e, - 0x03880986, - 0xfa1d042a, - 0x0bdb03a7, - 0x085408a0, - 0x00faf8fb, - 0x05e30000, - 0xff06f8fb, - 0x0854f760, - 0xf42503a7, - 0xfa1dfbd6, - 0xfc780986, - 0xf7ac09f2, - 0x075af89a, - 0x05e3fa1d, - 0xf8a60766, - 0xf7ac09f2, - 0x0388f67a, - 0xfa1dfbd6, - 0x0bdbfc59, - 0x0854f760, - 0x00fa0705, - 0xfa58fa58, - 0xf8f0fe00, - 0x0448073d, - 0xfdc9fe46, - 0xf9910258, - 0x089d0407, - 0xfd5cf71a, - 0x02affde0, - 0x083e0496, - 0xff5a0740, - 0xff7afd97, - 0x00fe01f1, - 0x0009082e, - 0xfa94ff75, - 0xfecdf8ea, - 0xffb0f693, - 0xfd2cfa58, - 0x0433ff16, - 0xfba405dd, - 0xfa610341, - 0x06a606cb, - 0x0039fd2d, - 0x0677fa97, - 0x01fa05e0, - 0xf896003e, - 0x075a068b, - 0x012cfc3e, - 0xfa23f98d, - 0xfc7cfd43, - 0xff90fc0d, - 0x01c10982, - 0x00c601d6, - 0xfd2cfd2c, - 0x01d600c6, - 0x098201c1, - 0xfc0dff90, - 0xfd43fc7c, - 0xf98dfa23, - 0xfc3e012c, - 0x068b075a, - 0x003ef896, - 0x05e001fa, - 0xfa970677, - 0xfd2d0039, - 0x06cb06a6, - 0x0341fa61, - 0x05ddfba4, - 0xff160433, - 0xfa58fd2c, - 0xf693ffb0, - 0xf8eafecd, - 0xff75fa94, - 0x082e0009, - 0x01f100fe, - 0xfd97ff7a, - 0x0740ff5a, - 0x0496083e, - 0xfde002af, - 0xf71afd5c, - 0x0407089d, - 0x0258f991, - 0xfe46fdc9, - 0x073d0448, - 0xfe00f8f0, - 0xfd2cfd2c, - 0xfce00500, - 0xfc09fddc, - 0xfe680157, - 0x04c70571, - 0xfc3aff21, - 0xfcd70228, - 0x056d0277, - 0x0200fe00, - 0x0022f927, - 0xfe3c032b, - 0xfc44ff3c, - 0x03e9fbdb, - 0x04570313, - 0x04c9ff5c, - 0x000d03b8, - 0xfa580000, - 0xfbe900d2, - 0xf9d0fe0b, - 0x0125fdf9, - 0x042501bf, - 0x0328fa2b, - 0xffa902f0, - 0xfa250157, - 0x0200fe00, - 0x03740438, - 0xff0405fd, - 0x030cfe52, - 0x0037fb39, - 0xff6904c5, - 0x04f8fd23, - 0xfd31fc1b, - 0xfd2cfd2c, - 0xfc1bfd31, - 0xfd2304f8, - 0x04c5ff69, - 0xfb390037, - 0xfe52030c, - 0x05fdff04, - 0x04380374, - 0xfe000200, - 0x0157fa25, - 0x02f0ffa9, - 0xfa2b0328, - 0x01bf0425, - 0xfdf90125, - 0xfe0bf9d0, - 0x00d2fbe9, - 0x0000fa58, - 0x03b8000d, - 0xff5c04c9, - 0x03130457, - 0xfbdb03e9, - 0xff3cfc44, - 0x032bfe3c, - 0xf9270022, - 0xfe000200, - 0x0277056d, - 0x0228fcd7, - 0xff21fc3a, - 0x057104c7, - 0x0157fe68, - 0xfddcfc09, - 0x0500fce0, - 0xfd2cfd2c, - 0x0500fce0, - 0xfddcfc09, - 0x0157fe68, - 0x057104c7, - 0xff21fc3a, - 0x0228fcd7, - 0x0277056d, - 0xfe000200, - 0xf9270022, - 0x032bfe3c, - 0xff3cfc44, - 0xfbdb03e9, - 0x03130457, - 0xff5c04c9, - 0x03b8000d, - 0x0000fa58, - 0x00d2fbe9, - 0xfe0bf9d0, - 0xfdf90125, - 0x01bf0425, - 0xfa2b0328, - 0x02f0ffa9, - 0x0157fa25, - 0xfe000200, - 0x04380374, - 0x05fdff04, - 0xfe52030c, - 0xfb390037, - 0x04c5ff69, - 0xfd2304f8, - 0xfc1bfd31, - 0xfd2cfd2c, - 0xfd31fc1b, - 0x04f8fd23, - 0xff6904c5, - 0x0037fb39, - 0x030cfe52, - 0xff0405fd, - 0x03740438, - 0x0200fe00, - 0xfa250157, - 0xffa902f0, - 0x0328fa2b, - 0x042501bf, - 0x0125fdf9, - 0xf9d0fe0b, - 0xfbe900d2, - 0xfa580000, - 0x000d03b8, - 0x04c9ff5c, - 0x04570313, - 0x03e9fbdb, - 0xfc44ff3c, - 0xfe3c032b, - 0x0022f927, - 0x0200fe00, - 0x056d0277, - 0xfcd70228, - 0xfc3aff21, - 0x04c70571, - 0xfe680157, - 0xfc09fddc, - 0xfce00500, - 0x05a80000, - 0xff1006be, - 0x0800084a, - 0xf49cfc7e, - 0xfa580400, - 0xfc9cf6da, - 0xf800f672, - 0x0710071c, - 0x05a805a8, - 0xf8f0f8e4, - 0xf800f672, - 0x03640926, - 0xfa580400, - 0x0b640382, - 0x0800084a, - 0x00f0f942, - 0x05a80000, - 0xff10f942, - 0x0800f7b6, - 0xf49c0382, - 0xfa58fc00, - 0xfc9c0926, - 0xf800098e, - 0x0710f8e4, - 0x05a8fa58, - 0xf8f0071c, - 0xf800098e, - 0x0364f6da, - 0xfa58fc00, - 0x0b64fc7e, - 0x0800f7b6, - 0x00f006be, - 0x05a80000, - 0xff1006be, - 0x0800084a, - 0xf49cfc7e, - 0xfa580400, - 0xfc9cf6da, - 0xf800f672, - 0x0710071c, - 0x05a805a8, - 0xf8f0f8e4, - 0xf800f672, - 0x03640926, - 0xfa580400, - 0x0b640382, - 0x0800084a, - 0x00f0f942, - 0x05a80000, - 0xff10f942, - 0x0800f7b6, - 0xf49c0382, - 0xfa58fc00, - 0xfc9c0926, - 0xf800098e, - 0x0710f8e4, - 0x05a8fa58, - 0xf8f0071c, - 0xf800098e, - 0x0364f6da, - 0xfa58fc00, - 0x0b64fc7e, - 0x0800f7b6, - 0x00f006be, -}; - -const u32 intlv_tbl_rev0[] = { - 0x00802070, - 0x0671188d, - 0x0a60192c, - 0x0a300e46, - 0x00c1188d, - 0x080024d2, - 0x00000070, -}; - -const u16 pilot_tbl_rev0[] = { - 0xff08, - 0xff08, - 0xff08, - 0xff08, - 0xff08, - 0xff08, - 0xff08, - 0xff08, - 0x80d5, - 0x80d5, - 0x80d5, - 0x80d5, - 0x80d5, - 0x80d5, - 0x80d5, - 0x80d5, - 0xff0a, - 0xff82, - 0xffa0, - 0xff28, - 0xffff, - 0xffff, - 0xffff, - 0xffff, - 0xff82, - 0xffa0, - 0xff28, - 0xff0a, - 0xffff, - 0xffff, - 0xffff, - 0xffff, - 0xf83f, - 0xfa1f, - 0xfa97, - 0xfab5, - 0xf2bd, - 0xf0bf, - 0xffff, - 0xffff, - 0xf017, - 0xf815, - 0xf215, - 0xf095, - 0xf035, - 0xf01d, - 0xffff, - 0xffff, - 0xff08, - 0xff02, - 0xff80, - 0xff20, - 0xff08, - 0xff02, - 0xff80, - 0xff20, - 0xf01f, - 0xf817, - 0xfa15, - 0xf295, - 0xf0b5, - 0xf03d, - 0xffff, - 0xffff, - 0xf82a, - 0xfa0a, - 0xfa82, - 0xfaa0, - 0xf2a8, - 0xf0aa, - 0xffff, - 0xffff, - 0xf002, - 0xf800, - 0xf200, - 0xf080, - 0xf020, - 0xf008, - 0xffff, - 0xffff, - 0xf00a, - 0xf802, - 0xfa00, - 0xf280, - 0xf0a0, - 0xf028, - 0xffff, - 0xffff, -}; - -const u32 pltlut_tbl_rev0[] = { - 0x76540123, - 0x62407351, - 0x76543201, - 0x76540213, - 0x76540123, - 0x76430521, -}; - -const u32 tdi_tbl20_ant0_rev0[] = { - 0x00091226, - 0x000a1429, - 0x000b56ad, - 0x000c58b0, - 0x000d5ab3, - 0x000e9cb6, - 0x000f9eba, - 0x0000c13d, - 0x00020301, - 0x00030504, - 0x00040708, - 0x0005090b, - 0x00064b8e, - 0x00095291, - 0x000a5494, - 0x000b9718, - 0x000c9927, - 0x000d9b2a, - 0x000edd2e, - 0x000fdf31, - 0x000101b4, - 0x000243b7, - 0x000345bb, - 0x000447be, - 0x00058982, - 0x00068c05, - 0x00099309, - 0x000a950c, - 0x000bd78f, - 0x000cd992, - 0x000ddb96, - 0x000f1d99, - 0x00005fa8, - 0x0001422c, - 0x0002842f, - 0x00038632, - 0x00048835, - 0x0005ca38, - 0x0006ccbc, - 0x0009d3bf, - 0x000b1603, - 0x000c1806, - 0x000d1a0a, - 0x000e1c0d, - 0x000f5e10, - 0x00008093, - 0x00018297, - 0x0002c49a, - 0x0003c680, - 0x0004c880, - 0x00060b00, - 0x00070d00, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -const u32 tdi_tbl20_ant1_rev0[] = { - 0x00014b26, - 0x00028d29, - 0x000393ad, - 0x00049630, - 0x0005d833, - 0x0006da36, - 0x00099c3a, - 0x000a9e3d, - 0x000bc081, - 0x000cc284, - 0x000dc488, - 0x000f068b, - 0x0000488e, - 0x00018b91, - 0x0002d214, - 0x0003d418, - 0x0004d6a7, - 0x000618aa, - 0x00071aae, - 0x0009dcb1, - 0x000b1eb4, - 0x000c0137, - 0x000d033b, - 0x000e053e, - 0x000f4702, - 0x00008905, - 0x00020c09, - 0x0003128c, - 0x0004148f, - 0x00051712, - 0x00065916, - 0x00091b19, - 0x000a1d28, - 0x000b5f2c, - 0x000c41af, - 0x000d43b2, - 0x000e85b5, - 0x000f87b8, - 0x0000c9bc, - 0x00024cbf, - 0x00035303, - 0x00045506, - 0x0005978a, - 0x0006998d, - 0x00095b90, - 0x000a5d93, - 0x000b9f97, - 0x000c821a, - 0x000d8400, - 0x000ec600, - 0x000fc800, - 0x00010a00, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -const u32 tdi_tbl40_ant0_rev0[] = { - 0x0011a346, - 0x00136ccf, - 0x0014f5d9, - 0x001641e2, - 0x0017cb6b, - 0x00195475, - 0x001b2383, - 0x001cad0c, - 0x001e7616, - 0x0000821f, - 0x00020ba8, - 0x0003d4b2, - 0x00056447, - 0x00072dd0, - 0x0008b6da, - 0x000a02e3, - 0x000b8c6c, - 0x000d15f6, - 0x0011e484, - 0x0013ae0d, - 0x00153717, - 0x00168320, - 0x00180ca9, - 0x00199633, - 0x001b6548, - 0x001ceed1, - 0x001eb7db, - 0x0000c3e4, - 0x00024d6d, - 0x000416f7, - 0x0005a585, - 0x00076f0f, - 0x0008f818, - 0x000a4421, - 0x000bcdab, - 0x000d9734, - 0x00122649, - 0x0013efd2, - 0x001578dc, - 0x0016c4e5, - 0x00184e6e, - 0x001a17f8, - 0x001ba686, - 0x001d3010, - 0x001ef999, - 0x00010522, - 0x00028eac, - 0x00045835, - 0x0005e74a, - 0x0007b0d3, - 0x00093a5d, - 0x000a85e6, - 0x000c0f6f, - 0x000dd8f9, - 0x00126787, - 0x00143111, - 0x0015ba9a, - 0x00170623, - 0x00188fad, - 0x001a5936, - 0x001be84b, - 0x001db1d4, - 0x001f3b5e, - 0x000146e7, - 0x00031070, - 0x000499fa, - 0x00062888, - 0x0007f212, - 0x00097b9b, - 0x000ac7a4, - 0x000c50ae, - 0x000e1a37, - 0x0012a94c, - 0x001472d5, - 0x0015fc5f, - 0x00174868, - 0x0018d171, - 0x001a9afb, - 0x001c2989, - 0x001df313, - 0x001f7c9c, - 0x000188a5, - 0x000351af, - 0x0004db38, - 0x0006aa4d, - 0x000833d7, - 0x0009bd60, - 0x000b0969, - 0x000c9273, - 0x000e5bfc, - 0x00132a8a, - 0x0014b414, - 0x00163d9d, - 0x001789a6, - 0x001912b0, - 0x001adc39, - 0x001c6bce, - 0x001e34d8, - 0x001fbe61, - 0x0001ca6a, - 0x00039374, - 0x00051cfd, - 0x0006ec0b, - 0x00087515, - 0x0009fe9e, - 0x000b4aa7, - 0x000cd3b1, - 0x000e9d3a, - 0x00000000, - 0x00000000, -}; - -const u32 tdi_tbl40_ant1_rev0[] = { - 0x001edb36, - 0x000129ca, - 0x0002b353, - 0x00047cdd, - 0x0005c8e6, - 0x000791ef, - 0x00091bf9, - 0x000aaa07, - 0x000c3391, - 0x000dfd1a, - 0x00120923, - 0x0013d22d, - 0x00155c37, - 0x0016eacb, - 0x00187454, - 0x001a3dde, - 0x001b89e7, - 0x001d12f0, - 0x001f1cfa, - 0x00016b88, - 0x00033492, - 0x0004be1b, - 0x00060a24, - 0x0007d32e, - 0x00095d38, - 0x000aec4c, - 0x000c7555, - 0x000e3edf, - 0x00124ae8, - 0x001413f1, - 0x0015a37b, - 0x00172c89, - 0x0018b593, - 0x001a419c, - 0x001bcb25, - 0x001d942f, - 0x001f63b9, - 0x0001ad4d, - 0x00037657, - 0x0004c260, - 0x00068be9, - 0x000814f3, - 0x0009a47c, - 0x000b2d8a, - 0x000cb694, - 0x000e429d, - 0x00128c26, - 0x001455b0, - 0x0015e4ba, - 0x00176e4e, - 0x0018f758, - 0x001a8361, - 0x001c0cea, - 0x001dd674, - 0x001fa57d, - 0x0001ee8b, - 0x0003b795, - 0x0005039e, - 0x0006cd27, - 0x000856b1, - 0x0009e5c6, - 0x000b6f4f, - 0x000cf859, - 0x000e8462, - 0x00130deb, - 0x00149775, - 0x00162603, - 0x0017af8c, - 0x00193896, - 0x001ac49f, - 0x001c4e28, - 0x001e17b2, - 0x0000a6c7, - 0x00023050, - 0x0003f9da, - 0x00054563, - 0x00070eec, - 0x00089876, - 0x000a2704, - 0x000bb08d, - 0x000d3a17, - 0x001185a0, - 0x00134f29, - 0x0014d8b3, - 0x001667c8, - 0x0017f151, - 0x00197adb, - 0x001b0664, - 0x001c8fed, - 0x001e5977, - 0x0000e805, - 0x0002718f, - 0x00043b18, - 0x000586a1, - 0x0007502b, - 0x0008d9b4, - 0x000a68c9, - 0x000bf252, - 0x000dbbdc, - 0x0011c7e5, - 0x001390ee, - 0x00151a78, - 0x0016a906, - 0x00183290, - 0x0019bc19, - 0x001b4822, - 0x001cd12c, - 0x001e9ab5, - 0x00000000, - 0x00000000, -}; - -const u16 bdi_tbl_rev0[] = { - 0x0070, - 0x0126, - 0x012c, - 0x0246, - 0x048d, - 0x04d2, -}; - -const u32 chanest_tbl_rev0[] = { - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, -}; - -const u8 mcs_tbl_rev0[] = { - 0x00, - 0x08, - 0x0a, - 0x10, - 0x12, - 0x19, - 0x1a, - 0x1c, - 0x40, - 0x48, - 0x4a, - 0x50, - 0x52, - 0x59, - 0x5a, - 0x5c, - 0x80, - 0x88, - 0x8a, - 0x90, - 0x92, - 0x99, - 0x9a, - 0x9c, - 0xc0, - 0xc8, - 0xca, - 0xd0, - 0xd2, - 0xd9, - 0xda, - 0xdc, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x01, - 0x02, - 0x04, - 0x08, - 0x09, - 0x0a, - 0x0c, - 0x10, - 0x11, - 0x12, - 0x14, - 0x18, - 0x19, - 0x1a, - 0x1c, - 0x20, - 0x21, - 0x22, - 0x24, - 0x40, - 0x41, - 0x42, - 0x44, - 0x48, - 0x49, - 0x4a, - 0x4c, - 0x50, - 0x51, - 0x52, - 0x54, - 0x58, - 0x59, - 0x5a, - 0x5c, - 0x60, - 0x61, - 0x62, - 0x64, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, -}; - -const u32 noise_var_tbl0_rev0[] = { - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, -}; - -const u32 noise_var_tbl1_rev0[] = { - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, -}; - -const u8 est_pwr_lut_core0_rev0[] = { - 0x50, - 0x4f, - 0x4e, - 0x4d, - 0x4c, - 0x4b, - 0x4a, - 0x49, - 0x48, - 0x47, - 0x46, - 0x45, - 0x44, - 0x43, - 0x42, - 0x41, - 0x40, - 0x3f, - 0x3e, - 0x3d, - 0x3c, - 0x3b, - 0x3a, - 0x39, - 0x38, - 0x37, - 0x36, - 0x35, - 0x34, - 0x33, - 0x32, - 0x31, - 0x30, - 0x2f, - 0x2e, - 0x2d, - 0x2c, - 0x2b, - 0x2a, - 0x29, - 0x28, - 0x27, - 0x26, - 0x25, - 0x24, - 0x23, - 0x22, - 0x21, - 0x20, - 0x1f, - 0x1e, - 0x1d, - 0x1c, - 0x1b, - 0x1a, - 0x19, - 0x18, - 0x17, - 0x16, - 0x15, - 0x14, - 0x13, - 0x12, - 0x11, -}; - -const u8 est_pwr_lut_core1_rev0[] = { - 0x50, - 0x4f, - 0x4e, - 0x4d, - 0x4c, - 0x4b, - 0x4a, - 0x49, - 0x48, - 0x47, - 0x46, - 0x45, - 0x44, - 0x43, - 0x42, - 0x41, - 0x40, - 0x3f, - 0x3e, - 0x3d, - 0x3c, - 0x3b, - 0x3a, - 0x39, - 0x38, - 0x37, - 0x36, - 0x35, - 0x34, - 0x33, - 0x32, - 0x31, - 0x30, - 0x2f, - 0x2e, - 0x2d, - 0x2c, - 0x2b, - 0x2a, - 0x29, - 0x28, - 0x27, - 0x26, - 0x25, - 0x24, - 0x23, - 0x22, - 0x21, - 0x20, - 0x1f, - 0x1e, - 0x1d, - 0x1c, - 0x1b, - 0x1a, - 0x19, - 0x18, - 0x17, - 0x16, - 0x15, - 0x14, - 0x13, - 0x12, - 0x11, -}; - -const u8 adj_pwr_lut_core0_rev0[] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, -}; - -const u8 adj_pwr_lut_core1_rev0[] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, -}; - -const u32 gainctrl_lut_core0_rev0[] = { - 0x03cc2b44, - 0x03cc2b42, - 0x03cc2b40, - 0x03cc2b3e, - 0x03cc2b3d, - 0x03cc2b3b, - 0x03c82b44, - 0x03c82b42, - 0x03c82b40, - 0x03c82b3e, - 0x03c82b3d, - 0x03c82b3b, - 0x03c82b39, - 0x03c82b38, - 0x03c82b36, - 0x03c82b34, - 0x03c42b44, - 0x03c42b42, - 0x03c42b40, - 0x03c42b3e, - 0x03c42b3d, - 0x03c42b3b, - 0x03c42b39, - 0x03c42b38, - 0x03c42b36, - 0x03c42b34, - 0x03c42b33, - 0x03c42b32, - 0x03c42b30, - 0x03c42b2f, - 0x03c42b2d, - 0x03c02b44, - 0x03c02b42, - 0x03c02b40, - 0x03c02b3e, - 0x03c02b3d, - 0x03c02b3b, - 0x03c02b39, - 0x03c02b38, - 0x03c02b36, - 0x03c02b34, - 0x03b02b44, - 0x03b02b42, - 0x03b02b40, - 0x03b02b3e, - 0x03b02b3d, - 0x03b02b3b, - 0x03b02b39, - 0x03b02b38, - 0x03b02b36, - 0x03b02b34, - 0x03b02b33, - 0x03b02b32, - 0x03b02b30, - 0x03b02b2f, - 0x03b02b2d, - 0x03a02b44, - 0x03a02b42, - 0x03a02b40, - 0x03a02b3e, - 0x03a02b3d, - 0x03a02b3b, - 0x03a02b39, - 0x03a02b38, - 0x03a02b36, - 0x03a02b34, - 0x03902b44, - 0x03902b42, - 0x03902b40, - 0x03902b3e, - 0x03902b3d, - 0x03902b3b, - 0x03902b39, - 0x03902b38, - 0x03902b36, - 0x03902b34, - 0x03902b33, - 0x03902b32, - 0x03902b30, - 0x03802b44, - 0x03802b42, - 0x03802b40, - 0x03802b3e, - 0x03802b3d, - 0x03802b3b, - 0x03802b39, - 0x03802b38, - 0x03802b36, - 0x03802b34, - 0x03802b33, - 0x03802b32, - 0x03802b30, - 0x03802b2f, - 0x03802b2d, - 0x03802b2c, - 0x03802b2b, - 0x03802b2a, - 0x03802b29, - 0x03802b27, - 0x03802b26, - 0x03802b25, - 0x03802b24, - 0x03802b23, - 0x03802b22, - 0x03802b21, - 0x03802b20, - 0x03802b1f, - 0x03802b1e, - 0x03802b1e, - 0x03802b1d, - 0x03802b1c, - 0x03802b1b, - 0x03802b1a, - 0x03802b1a, - 0x03802b19, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x00002b00, -}; - -const u32 gainctrl_lut_core1_rev0[] = { - 0x03cc2b44, - 0x03cc2b42, - 0x03cc2b40, - 0x03cc2b3e, - 0x03cc2b3d, - 0x03cc2b3b, - 0x03c82b44, - 0x03c82b42, - 0x03c82b40, - 0x03c82b3e, - 0x03c82b3d, - 0x03c82b3b, - 0x03c82b39, - 0x03c82b38, - 0x03c82b36, - 0x03c82b34, - 0x03c42b44, - 0x03c42b42, - 0x03c42b40, - 0x03c42b3e, - 0x03c42b3d, - 0x03c42b3b, - 0x03c42b39, - 0x03c42b38, - 0x03c42b36, - 0x03c42b34, - 0x03c42b33, - 0x03c42b32, - 0x03c42b30, - 0x03c42b2f, - 0x03c42b2d, - 0x03c02b44, - 0x03c02b42, - 0x03c02b40, - 0x03c02b3e, - 0x03c02b3d, - 0x03c02b3b, - 0x03c02b39, - 0x03c02b38, - 0x03c02b36, - 0x03c02b34, - 0x03b02b44, - 0x03b02b42, - 0x03b02b40, - 0x03b02b3e, - 0x03b02b3d, - 0x03b02b3b, - 0x03b02b39, - 0x03b02b38, - 0x03b02b36, - 0x03b02b34, - 0x03b02b33, - 0x03b02b32, - 0x03b02b30, - 0x03b02b2f, - 0x03b02b2d, - 0x03a02b44, - 0x03a02b42, - 0x03a02b40, - 0x03a02b3e, - 0x03a02b3d, - 0x03a02b3b, - 0x03a02b39, - 0x03a02b38, - 0x03a02b36, - 0x03a02b34, - 0x03902b44, - 0x03902b42, - 0x03902b40, - 0x03902b3e, - 0x03902b3d, - 0x03902b3b, - 0x03902b39, - 0x03902b38, - 0x03902b36, - 0x03902b34, - 0x03902b33, - 0x03902b32, - 0x03902b30, - 0x03802b44, - 0x03802b42, - 0x03802b40, - 0x03802b3e, - 0x03802b3d, - 0x03802b3b, - 0x03802b39, - 0x03802b38, - 0x03802b36, - 0x03802b34, - 0x03802b33, - 0x03802b32, - 0x03802b30, - 0x03802b2f, - 0x03802b2d, - 0x03802b2c, - 0x03802b2b, - 0x03802b2a, - 0x03802b29, - 0x03802b27, - 0x03802b26, - 0x03802b25, - 0x03802b24, - 0x03802b23, - 0x03802b22, - 0x03802b21, - 0x03802b20, - 0x03802b1f, - 0x03802b1e, - 0x03802b1e, - 0x03802b1d, - 0x03802b1c, - 0x03802b1b, - 0x03802b1a, - 0x03802b1a, - 0x03802b19, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x03802b18, - 0x00002b00, -}; - -const u32 iq_lut_core0_rev0[] = { - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, -}; - -const u32 iq_lut_core1_rev0[] = { - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, - 0x0000007f, -}; - -const u16 loft_lut_core0_rev0[] = { - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, -}; - -const u16 loft_lut_core1_rev0[] = { - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, - 0x0000, - 0x0101, - 0x0002, - 0x0103, -}; - -const mimophytbl_info_t mimophytbl_info_rev0_volatile[] = { - {&bdi_tbl_rev0, sizeof(bdi_tbl_rev0) / sizeof(bdi_tbl_rev0[0]), 21, 0, - 16} - , - {&pltlut_tbl_rev0, sizeof(pltlut_tbl_rev0) / sizeof(pltlut_tbl_rev0[0]), - 20, 0, 32} - , - {&gainctrl_lut_core0_rev0, - sizeof(gainctrl_lut_core0_rev0) / sizeof(gainctrl_lut_core0_rev0[0]), - 26, 192, 32} - , - {&gainctrl_lut_core1_rev0, - sizeof(gainctrl_lut_core1_rev0) / sizeof(gainctrl_lut_core1_rev0[0]), - 27, 192, 32} - , - - {&est_pwr_lut_core0_rev0, - sizeof(est_pwr_lut_core0_rev0) / sizeof(est_pwr_lut_core0_rev0[0]), 26, - 0, 8} - , - {&est_pwr_lut_core1_rev0, - sizeof(est_pwr_lut_core1_rev0) / sizeof(est_pwr_lut_core1_rev0[0]), 27, - 0, 8} - , - {&adj_pwr_lut_core0_rev0, - sizeof(adj_pwr_lut_core0_rev0) / sizeof(adj_pwr_lut_core0_rev0[0]), 26, - 64, 8} - , - {&adj_pwr_lut_core1_rev0, - sizeof(adj_pwr_lut_core1_rev0) / sizeof(adj_pwr_lut_core1_rev0[0]), 27, - 64, 8} - , - {&iq_lut_core0_rev0, - sizeof(iq_lut_core0_rev0) / sizeof(iq_lut_core0_rev0[0]), 26, 320, 32} - , - {&iq_lut_core1_rev0, - sizeof(iq_lut_core1_rev0) / sizeof(iq_lut_core1_rev0[0]), 27, 320, 32} - , - {&loft_lut_core0_rev0, - sizeof(loft_lut_core0_rev0) / sizeof(loft_lut_core0_rev0[0]), 26, 448, - 16} - , - {&loft_lut_core1_rev0, - sizeof(loft_lut_core1_rev0) / sizeof(loft_lut_core1_rev0[0]), 27, 448, - 16} - , -}; - -const mimophytbl_info_t mimophytbl_info_rev0[] = { - {&frame_struct_rev0, - sizeof(frame_struct_rev0) / sizeof(frame_struct_rev0[0]), 10, 0, 32} - , - {&frame_lut_rev0, sizeof(frame_lut_rev0) / sizeof(frame_lut_rev0[0]), - 24, 0, 8} - , - {&tmap_tbl_rev0, sizeof(tmap_tbl_rev0) / sizeof(tmap_tbl_rev0[0]), 12, - 0, 32} - , - {&tdtrn_tbl_rev0, sizeof(tdtrn_tbl_rev0) / sizeof(tdtrn_tbl_rev0[0]), - 14, 0, 32} - , - {&intlv_tbl_rev0, sizeof(intlv_tbl_rev0) / sizeof(intlv_tbl_rev0[0]), - 13, 0, 32} - , - {&pilot_tbl_rev0, sizeof(pilot_tbl_rev0) / sizeof(pilot_tbl_rev0[0]), - 11, 0, 16} - , - {&tdi_tbl20_ant0_rev0, - sizeof(tdi_tbl20_ant0_rev0) / sizeof(tdi_tbl20_ant0_rev0[0]), 19, 128, - 32} - , - {&tdi_tbl20_ant1_rev0, - sizeof(tdi_tbl20_ant1_rev0) / sizeof(tdi_tbl20_ant1_rev0[0]), 19, 256, - 32} - , - {&tdi_tbl40_ant0_rev0, - sizeof(tdi_tbl40_ant0_rev0) / sizeof(tdi_tbl40_ant0_rev0[0]), 19, 640, - 32} - , - {&tdi_tbl40_ant1_rev0, - sizeof(tdi_tbl40_ant1_rev0) / sizeof(tdi_tbl40_ant1_rev0[0]), 19, 768, - 32} - , - {&chanest_tbl_rev0, - sizeof(chanest_tbl_rev0) / sizeof(chanest_tbl_rev0[0]), 22, 0, 32} - , - {&mcs_tbl_rev0, sizeof(mcs_tbl_rev0) / sizeof(mcs_tbl_rev0[0]), 18, 0, 8} - , - {&noise_var_tbl0_rev0, - sizeof(noise_var_tbl0_rev0) / sizeof(noise_var_tbl0_rev0[0]), 16, 0, - 32} - , - {&noise_var_tbl1_rev0, - sizeof(noise_var_tbl1_rev0) / sizeof(noise_var_tbl1_rev0[0]), 16, 128, - 32} - , -}; - -const u32 mimophytbl_info_sz_rev0 = - sizeof(mimophytbl_info_rev0) / sizeof(mimophytbl_info_rev0[0]); -const u32 mimophytbl_info_sz_rev0_volatile = - sizeof(mimophytbl_info_rev0_volatile) / - sizeof(mimophytbl_info_rev0_volatile[0]); - -const u16 ant_swctrl_tbl_rev3[] = { - 0x0082, - 0x0082, - 0x0211, - 0x0222, - 0x0328, - 0x0000, - 0x0000, - 0x0000, - 0x0144, - 0x0000, - 0x0000, - 0x0000, - 0x0188, - 0x0000, - 0x0000, - 0x0000, - 0x0082, - 0x0082, - 0x0211, - 0x0222, - 0x0328, - 0x0000, - 0x0000, - 0x0000, - 0x0144, - 0x0000, - 0x0000, - 0x0000, - 0x0188, - 0x0000, - 0x0000, - 0x0000, -}; - -const u16 ant_swctrl_tbl_rev3_1[] = { - 0x0022, - 0x0022, - 0x0011, - 0x0022, - 0x0022, - 0x0000, - 0x0000, - 0x0000, - 0x0011, - 0x0000, - 0x0000, - 0x0000, - 0x0022, - 0x0000, - 0x0000, - 0x0000, - 0x0022, - 0x0022, - 0x0011, - 0x0022, - 0x0022, - 0x0000, - 0x0000, - 0x0000, - 0x0011, - 0x0000, - 0x0000, - 0x0000, - 0x0022, - 0x0000, - 0x0000, - 0x0000, -}; - -const u16 ant_swctrl_tbl_rev3_2[] = { - 0x0088, - 0x0088, - 0x0044, - 0x0088, - 0x0088, - 0x0000, - 0x0000, - 0x0000, - 0x0044, - 0x0000, - 0x0000, - 0x0000, - 0x0088, - 0x0000, - 0x0000, - 0x0000, - 0x0088, - 0x0088, - 0x0044, - 0x0088, - 0x0088, - 0x0000, - 0x0000, - 0x0000, - 0x0044, - 0x0000, - 0x0000, - 0x0000, - 0x0088, - 0x0000, - 0x0000, - 0x0000, -}; - -const u16 ant_swctrl_tbl_rev3_3[] = { - 0x022, - 0x022, - 0x011, - 0x022, - 0x000, - 0x000, - 0x000, - 0x000, - 0x011, - 0x000, - 0x000, - 0x000, - 0x022, - 0x000, - 0x000, - 0x3cc, - 0x022, - 0x022, - 0x011, - 0x022, - 0x000, - 0x000, - 0x000, - 0x000, - 0x011, - 0x000, - 0x000, - 0x000, - 0x022, - 0x000, - 0x000, - 0x3cc -}; - -const u32 frame_struct_rev3[] = { - 0x08004a04, - 0x00100000, - 0x01000a05, - 0x00100020, - 0x09804506, - 0x00100030, - 0x09804507, - 0x00100030, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x08004a0c, - 0x00100004, - 0x01000a0d, - 0x00100024, - 0x0980450e, - 0x00100034, - 0x0980450f, - 0x00100034, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000a04, - 0x00100000, - 0x11008a05, - 0x00100020, - 0x1980c506, - 0x00100030, - 0x21810506, - 0x00100030, - 0x21810506, - 0x00100030, - 0x01800504, - 0x00100030, - 0x11808505, - 0x00100030, - 0x29814507, - 0x01100030, - 0x00000a04, - 0x00100000, - 0x11008a05, - 0x00100020, - 0x21810506, - 0x00100030, - 0x21810506, - 0x00100030, - 0x29814507, - 0x01100030, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000a0c, - 0x00100008, - 0x11008a0d, - 0x00100028, - 0x1980c50e, - 0x00100038, - 0x2181050e, - 0x00100038, - 0x2181050e, - 0x00100038, - 0x0180050c, - 0x00100038, - 0x1180850d, - 0x00100038, - 0x2981450f, - 0x01100038, - 0x00000a0c, - 0x00100008, - 0x11008a0d, - 0x00100028, - 0x2181050e, - 0x00100038, - 0x2181050e, - 0x00100038, - 0x2981450f, - 0x01100038, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x08004a04, - 0x00100000, - 0x01000a05, - 0x00100020, - 0x1980c506, - 0x00100030, - 0x1980c506, - 0x00100030, - 0x11808504, - 0x00100030, - 0x3981ca05, - 0x00100030, - 0x29814507, - 0x01100030, - 0x00000000, - 0x00000000, - 0x10008a04, - 0x00100000, - 0x3981ca05, - 0x00100030, - 0x1980c506, - 0x00100030, - 0x29814507, - 0x01100030, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x08004a0c, - 0x00100008, - 0x01000a0d, - 0x00100028, - 0x1980c50e, - 0x00100038, - 0x1980c50e, - 0x00100038, - 0x1180850c, - 0x00100038, - 0x3981ca0d, - 0x00100038, - 0x2981450f, - 0x01100038, - 0x00000000, - 0x00000000, - 0x10008a0c, - 0x00100008, - 0x3981ca0d, - 0x00100038, - 0x1980c50e, - 0x00100038, - 0x2981450f, - 0x01100038, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x40021404, - 0x00100000, - 0x02001405, - 0x00100040, - 0x0b004a06, - 0x01900060, - 0x13008a06, - 0x01900060, - 0x13008a06, - 0x01900060, - 0x43020a04, - 0x00100060, - 0x1b00ca05, - 0x00100060, - 0x23010a07, - 0x01500060, - 0x40021404, - 0x00100000, - 0x1a00d405, - 0x00100040, - 0x13008a06, - 0x01900060, - 0x13008a06, - 0x01900060, - 0x23010a07, - 0x01500060, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x4002140c, - 0x00100010, - 0x0200140d, - 0x00100050, - 0x0b004a0e, - 0x01900070, - 0x13008a0e, - 0x01900070, - 0x13008a0e, - 0x01900070, - 0x43020a0c, - 0x00100070, - 0x1b00ca0d, - 0x00100070, - 0x23010a0f, - 0x01500070, - 0x4002140c, - 0x00100010, - 0x1a00d40d, - 0x00100050, - 0x13008a0e, - 0x01900070, - 0x13008a0e, - 0x01900070, - 0x23010a0f, - 0x01500070, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x50029404, - 0x00100000, - 0x32019405, - 0x00100040, - 0x0b004a06, - 0x01900060, - 0x0b004a06, - 0x01900060, - 0x5b02ca04, - 0x00100060, - 0x3b01d405, - 0x00100060, - 0x23010a07, - 0x01500060, - 0x00000000, - 0x00000000, - 0x5802d404, - 0x00100000, - 0x3b01d405, - 0x00100060, - 0x0b004a06, - 0x01900060, - 0x23010a07, - 0x01500060, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x5002940c, - 0x00100010, - 0x3201940d, - 0x00100050, - 0x0b004a0e, - 0x01900070, - 0x0b004a0e, - 0x01900070, - 0x5b02ca0c, - 0x00100070, - 0x3b01d40d, - 0x00100070, - 0x23010a0f, - 0x01500070, - 0x00000000, - 0x00000000, - 0x5802d40c, - 0x00100010, - 0x3b01d40d, - 0x00100070, - 0x0b004a0e, - 0x01900070, - 0x23010a0f, - 0x01500070, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x40021404, - 0x000f4800, - 0x62031405, - 0x00100040, - 0x53028a06, - 0x01900060, - 0x53028a07, - 0x01900060, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x4002140c, - 0x000f4808, - 0x6203140d, - 0x00100048, - 0x53028a0e, - 0x01900068, - 0x53028a0f, - 0x01900068, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000a0c, - 0x00100004, - 0x11008a0d, - 0x00100024, - 0x1980c50e, - 0x00100034, - 0x2181050e, - 0x00100034, - 0x2181050e, - 0x00100034, - 0x0180050c, - 0x00100038, - 0x1180850d, - 0x00100038, - 0x1181850d, - 0x00100038, - 0x2981450f, - 0x01100038, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000a0c, - 0x00100008, - 0x11008a0d, - 0x00100028, - 0x2181050e, - 0x00100038, - 0x2181050e, - 0x00100038, - 0x1181850d, - 0x00100038, - 0x2981450f, - 0x01100038, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x08004a04, - 0x00100000, - 0x01000a05, - 0x00100020, - 0x0180c506, - 0x00100030, - 0x0180c506, - 0x00100030, - 0x2180c50c, - 0x00100030, - 0x49820a0d, - 0x0016a130, - 0x41824a0d, - 0x0016a130, - 0x2981450f, - 0x01100030, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x2000ca0c, - 0x00100000, - 0x49820a0d, - 0x0016a130, - 0x1980c50e, - 0x00100030, - 0x41824a0d, - 0x0016a130, - 0x2981450f, - 0x01100030, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x4002140c, - 0x00100008, - 0x0200140d, - 0x00100048, - 0x0b004a0e, - 0x01900068, - 0x13008a0e, - 0x01900068, - 0x13008a0e, - 0x01900068, - 0x43020a0c, - 0x00100070, - 0x1b00ca0d, - 0x00100070, - 0x1b014a0d, - 0x00100070, - 0x23010a0f, - 0x01500070, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x4002140c, - 0x00100010, - 0x1a00d40d, - 0x00100050, - 0x13008a0e, - 0x01900070, - 0x13008a0e, - 0x01900070, - 0x1b014a0d, - 0x00100070, - 0x23010a0f, - 0x01500070, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x50029404, - 0x00100000, - 0x32019405, - 0x00100040, - 0x03004a06, - 0x01900060, - 0x03004a06, - 0x01900060, - 0x6b030a0c, - 0x00100060, - 0x4b02140d, - 0x0016a160, - 0x4302540d, - 0x0016a160, - 0x23010a0f, - 0x01500060, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x6b03140c, - 0x00100060, - 0x4b02140d, - 0x0016a160, - 0x0b004a0e, - 0x01900060, - 0x4302540d, - 0x0016a160, - 0x23010a0f, - 0x01500060, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x40021404, - 0x00100000, - 0x1a00d405, - 0x00100040, - 0x53028a06, - 0x01900060, - 0x5b02ca06, - 0x01900060, - 0x5b02ca06, - 0x01900060, - 0x43020a04, - 0x00100060, - 0x1b00ca05, - 0x00100060, - 0x53028a07, - 0x0190c060, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x4002140c, - 0x00100010, - 0x1a00d40d, - 0x00100050, - 0x53028a0e, - 0x01900070, - 0x5b02ca0e, - 0x01900070, - 0x5b02ca0e, - 0x01900070, - 0x43020a0c, - 0x00100070, - 0x1b00ca0d, - 0x00100070, - 0x53028a0f, - 0x0190c070, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x40021404, - 0x00100000, - 0x1a00d405, - 0x00100040, - 0x5b02ca06, - 0x01900060, - 0x5b02ca06, - 0x01900060, - 0x53028a07, - 0x0190c060, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x4002140c, - 0x00100010, - 0x1a00d40d, - 0x00100050, - 0x5b02ca0e, - 0x01900070, - 0x5b02ca0e, - 0x01900070, - 0x53028a0f, - 0x0190c070, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -const u16 pilot_tbl_rev3[] = { - 0xff08, - 0xff08, - 0xff08, - 0xff08, - 0xff08, - 0xff08, - 0xff08, - 0xff08, - 0x80d5, - 0x80d5, - 0x80d5, - 0x80d5, - 0x80d5, - 0x80d5, - 0x80d5, - 0x80d5, - 0xff0a, - 0xff82, - 0xffa0, - 0xff28, - 0xffff, - 0xffff, - 0xffff, - 0xffff, - 0xff82, - 0xffa0, - 0xff28, - 0xff0a, - 0xffff, - 0xffff, - 0xffff, - 0xffff, - 0xf83f, - 0xfa1f, - 0xfa97, - 0xfab5, - 0xf2bd, - 0xf0bf, - 0xffff, - 0xffff, - 0xf017, - 0xf815, - 0xf215, - 0xf095, - 0xf035, - 0xf01d, - 0xffff, - 0xffff, - 0xff08, - 0xff02, - 0xff80, - 0xff20, - 0xff08, - 0xff02, - 0xff80, - 0xff20, - 0xf01f, - 0xf817, - 0xfa15, - 0xf295, - 0xf0b5, - 0xf03d, - 0xffff, - 0xffff, - 0xf82a, - 0xfa0a, - 0xfa82, - 0xfaa0, - 0xf2a8, - 0xf0aa, - 0xffff, - 0xffff, - 0xf002, - 0xf800, - 0xf200, - 0xf080, - 0xf020, - 0xf008, - 0xffff, - 0xffff, - 0xf00a, - 0xf802, - 0xfa00, - 0xf280, - 0xf0a0, - 0xf028, - 0xffff, - 0xffff, -}; - -const u32 tmap_tbl_rev3[] = { - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0xf1111110, - 0x11111111, - 0x11f11111, - 0x00000111, - 0x11000000, - 0x1111f111, - 0x11111111, - 0x111111f1, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x000aa888, - 0x88880000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0xa1111110, - 0x11111111, - 0x11c11111, - 0x00000111, - 0x11000000, - 0x1111a111, - 0x11111111, - 0x111111a1, - 0xa2222220, - 0x22222222, - 0x22c22222, - 0x00000222, - 0x22000000, - 0x2222a222, - 0x22222222, - 0x222222a2, - 0xf1111110, - 0x11111111, - 0x11f11111, - 0x00011111, - 0x11110000, - 0x1111f111, - 0x11111111, - 0x111111f1, - 0xa8aa88a0, - 0xa88888a8, - 0xa8a8a88a, - 0x00088aaa, - 0xaaaa0000, - 0xa8a8aa88, - 0xa88aaaaa, - 0xaaaa8a8a, - 0xaaa8aaa0, - 0x8aaa8aaa, - 0xaa8a8a8a, - 0x000aaa88, - 0x8aaa0000, - 0xaaa8a888, - 0x8aa88a8a, - 0x8a88a888, - 0x08080a00, - 0x0a08080a, - 0x080a0a08, - 0x00080808, - 0x080a0000, - 0x080a0808, - 0x080a0808, - 0x0a0a0a08, - 0xa0a0a0a0, - 0x80a0a080, - 0x8080a0a0, - 0x00008080, - 0x80a00000, - 0x80a080a0, - 0xa080a0a0, - 0x8080a0a0, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x99999000, - 0x9b9b99bb, - 0x9bb99999, - 0x9999b9b9, - 0x9b99bb90, - 0x9bbbbb9b, - 0x9b9b9bb9, - 0x00000999, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00aaa888, - 0x22000000, - 0x2222b222, - 0x22222222, - 0x222222b2, - 0xb2222220, - 0x22222222, - 0x22d22222, - 0x00000222, - 0x11000000, - 0x1111a111, - 0x11111111, - 0x111111a1, - 0xa1111110, - 0x11111111, - 0x11c11111, - 0x00000111, - 0x33000000, - 0x3333b333, - 0x33333333, - 0x333333b3, - 0xb3333330, - 0x33333333, - 0x33d33333, - 0x00000333, - 0x22000000, - 0x2222a222, - 0x22222222, - 0x222222a2, - 0xa2222220, - 0x22222222, - 0x22c22222, - 0x00000222, - 0x99b99b00, - 0x9b9b99bb, - 0x9bb99999, - 0x9999b9b9, - 0x9b99bb99, - 0x9bbbbb9b, - 0x9b9b9bb9, - 0x00000999, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa88, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x08aaa888, - 0x22222200, - 0x2222f222, - 0x22222222, - 0x222222f2, - 0x22222222, - 0x22222222, - 0x22f22222, - 0x00000222, - 0x11000000, - 0x1111f111, - 0x11111111, - 0x11111111, - 0xf1111111, - 0x11111111, - 0x11f11111, - 0x01111111, - 0xbb9bb900, - 0xb9b9bb99, - 0xb99bbbbb, - 0xbbbb9b9b, - 0xb9bb99bb, - 0xb99999b9, - 0xb9b9b99b, - 0x00000bbb, - 0xaa000000, - 0xa8a8aa88, - 0xa88aaaaa, - 0xaaaa8a8a, - 0xa8aa88aa, - 0xa88888a8, - 0xa8a8a88a, - 0x0a888aaa, - 0xaa000000, - 0xa8a8aa88, - 0xa88aaaaa, - 0xaaaa8a8a, - 0xa8aa88a0, - 0xa88888a8, - 0xa8a8a88a, - 0x00000aaa, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0xbbbbbb00, - 0x999bbbbb, - 0x9bb99b9b, - 0xb9b9b9bb, - 0xb9b99bbb, - 0xb9b9b9bb, - 0xb9bb9b99, - 0x00000999, - 0x8a000000, - 0xaa88a888, - 0xa88888aa, - 0xa88a8a88, - 0xa88aa88a, - 0x88a8aaaa, - 0xa8aa8aaa, - 0x0888a88a, - 0x0b0b0b00, - 0x090b0b0b, - 0x0b090b0b, - 0x0909090b, - 0x09090b0b, - 0x09090b0b, - 0x09090b09, - 0x00000909, - 0x0a000000, - 0x0a080808, - 0x080a080a, - 0x080a0a08, - 0x080a080a, - 0x0808080a, - 0x0a0a0a08, - 0x0808080a, - 0xb0b0b000, - 0x9090b0b0, - 0x90b09090, - 0xb0b0b090, - 0xb0b090b0, - 0x90b0b0b0, - 0xb0b09090, - 0x00000090, - 0x80000000, - 0xa080a080, - 0xa08080a0, - 0xa0808080, - 0xa080a080, - 0x80a0a0a0, - 0xa0a080a0, - 0x00a0a0a0, - 0x22000000, - 0x2222f222, - 0x22222222, - 0x222222f2, - 0xf2222220, - 0x22222222, - 0x22f22222, - 0x00000222, - 0x11000000, - 0x1111f111, - 0x11111111, - 0x111111f1, - 0xf1111110, - 0x11111111, - 0x11f11111, - 0x00000111, - 0x33000000, - 0x3333f333, - 0x33333333, - 0x333333f3, - 0xf3333330, - 0x33333333, - 0x33f33333, - 0x00000333, - 0x22000000, - 0x2222f222, - 0x22222222, - 0x222222f2, - 0xf2222220, - 0x22222222, - 0x22f22222, - 0x00000222, - 0x99000000, - 0x9b9b99bb, - 0x9bb99999, - 0x9999b9b9, - 0x9b99bb90, - 0x9bbbbb9b, - 0x9b9b9bb9, - 0x00000999, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0x88888000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00aaa888, - 0x88a88a00, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa88, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa88, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x08aaa888, - 0x11000000, - 0x1111a111, - 0x11111111, - 0x111111a1, - 0xa1111110, - 0x11111111, - 0x11c11111, - 0x00000111, - 0x11000000, - 0x1111a111, - 0x11111111, - 0x111111a1, - 0xa1111110, - 0x11111111, - 0x11c11111, - 0x00000111, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -const u32 intlv_tbl_rev3[] = { - 0x00802070, - 0x0671188d, - 0x0a60192c, - 0x0a300e46, - 0x00c1188d, - 0x080024d2, - 0x00000070, -}; - -const u32 tdtrn_tbl_rev3[] = { - 0x061c061c, - 0x0050ee68, - 0xf592fe36, - 0xfe5212f6, - 0x00000c38, - 0xfe5212f6, - 0xf592fe36, - 0x0050ee68, - 0x061c061c, - 0xee680050, - 0xfe36f592, - 0x12f6fe52, - 0x0c380000, - 0x12f6fe52, - 0xfe36f592, - 0xee680050, - 0x061c061c, - 0x0050ee68, - 0xf592fe36, - 0xfe5212f6, - 0x00000c38, - 0xfe5212f6, - 0xf592fe36, - 0x0050ee68, - 0x061c061c, - 0xee680050, - 0xfe36f592, - 0x12f6fe52, - 0x0c380000, - 0x12f6fe52, - 0xfe36f592, - 0xee680050, - 0x05e305e3, - 0x004def0c, - 0xf5f3fe47, - 0xfe611246, - 0x00000bc7, - 0xfe611246, - 0xf5f3fe47, - 0x004def0c, - 0x05e305e3, - 0xef0c004d, - 0xfe47f5f3, - 0x1246fe61, - 0x0bc70000, - 0x1246fe61, - 0xfe47f5f3, - 0xef0c004d, - 0x05e305e3, - 0x004def0c, - 0xf5f3fe47, - 0xfe611246, - 0x00000bc7, - 0xfe611246, - 0xf5f3fe47, - 0x004def0c, - 0x05e305e3, - 0xef0c004d, - 0xfe47f5f3, - 0x1246fe61, - 0x0bc70000, - 0x1246fe61, - 0xfe47f5f3, - 0xef0c004d, - 0xfa58fa58, - 0xf895043b, - 0xff4c09c0, - 0xfbc6ffa8, - 0xfb84f384, - 0x0798f6f9, - 0x05760122, - 0x058409f6, - 0x0b500000, - 0x05b7f542, - 0x08860432, - 0x06ddfee7, - 0xfb84f384, - 0xf9d90664, - 0xf7e8025c, - 0x00fff7bd, - 0x05a805a8, - 0xf7bd00ff, - 0x025cf7e8, - 0x0664f9d9, - 0xf384fb84, - 0xfee706dd, - 0x04320886, - 0xf54205b7, - 0x00000b50, - 0x09f60584, - 0x01220576, - 0xf6f90798, - 0xf384fb84, - 0xffa8fbc6, - 0x09c0ff4c, - 0x043bf895, - 0x02d402d4, - 0x07de0270, - 0xfc96079c, - 0xf90afe94, - 0xfe00ff2c, - 0x02d4065d, - 0x092a0096, - 0x0014fbb8, - 0xfd2cfd2c, - 0x076afb3c, - 0x0096f752, - 0xf991fd87, - 0xfb2c0200, - 0xfeb8f960, - 0x08e0fc96, - 0x049802a8, - 0xfd2cfd2c, - 0x02a80498, - 0xfc9608e0, - 0xf960feb8, - 0x0200fb2c, - 0xfd87f991, - 0xf7520096, - 0xfb3c076a, - 0xfd2cfd2c, - 0xfbb80014, - 0x0096092a, - 0x065d02d4, - 0xff2cfe00, - 0xfe94f90a, - 0x079cfc96, - 0x027007de, - 0x02d402d4, - 0x027007de, - 0x079cfc96, - 0xfe94f90a, - 0xff2cfe00, - 0x065d02d4, - 0x0096092a, - 0xfbb80014, - 0xfd2cfd2c, - 0xfb3c076a, - 0xf7520096, - 0xfd87f991, - 0x0200fb2c, - 0xf960feb8, - 0xfc9608e0, - 0x02a80498, - 0xfd2cfd2c, - 0x049802a8, - 0x08e0fc96, - 0xfeb8f960, - 0xfb2c0200, - 0xf991fd87, - 0x0096f752, - 0x076afb3c, - 0xfd2cfd2c, - 0x0014fbb8, - 0x092a0096, - 0x02d4065d, - 0xfe00ff2c, - 0xf90afe94, - 0xfc96079c, - 0x07de0270, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x062a0000, - 0xfefa0759, - 0x08b80908, - 0xf396fc2d, - 0xf9d6045c, - 0xfc4ef608, - 0xf748f596, - 0x07b207bf, - 0x062a062a, - 0xf84ef841, - 0xf748f596, - 0x03b209f8, - 0xf9d6045c, - 0x0c6a03d3, - 0x08b80908, - 0x0106f8a7, - 0x062a0000, - 0xfefaf8a7, - 0x08b8f6f8, - 0xf39603d3, - 0xf9d6fba4, - 0xfc4e09f8, - 0xf7480a6a, - 0x07b2f841, - 0x062af9d6, - 0xf84e07bf, - 0xf7480a6a, - 0x03b2f608, - 0xf9d6fba4, - 0x0c6afc2d, - 0x08b8f6f8, - 0x01060759, - 0x062a0000, - 0xfefa0759, - 0x08b80908, - 0xf396fc2d, - 0xf9d6045c, - 0xfc4ef608, - 0xf748f596, - 0x07b207bf, - 0x062a062a, - 0xf84ef841, - 0xf748f596, - 0x03b209f8, - 0xf9d6045c, - 0x0c6a03d3, - 0x08b80908, - 0x0106f8a7, - 0x062a0000, - 0xfefaf8a7, - 0x08b8f6f8, - 0xf39603d3, - 0xf9d6fba4, - 0xfc4e09f8, - 0xf7480a6a, - 0x07b2f841, - 0x062af9d6, - 0xf84e07bf, - 0xf7480a6a, - 0x03b2f608, - 0xf9d6fba4, - 0x0c6afc2d, - 0x08b8f6f8, - 0x01060759, - 0x061c061c, - 0xff30009d, - 0xffb21141, - 0xfd87fb54, - 0xf65dfe59, - 0x02eef99e, - 0x0166f03c, - 0xfff809b6, - 0x000008a4, - 0x000af42b, - 0x00eff577, - 0xfa840bf2, - 0xfc02ff51, - 0x08260f67, - 0xfff0036f, - 0x0842f9c3, - 0x00000000, - 0x063df7be, - 0xfc910010, - 0xf099f7da, - 0x00af03fe, - 0xf40e057c, - 0x0a89ff11, - 0x0bd5fff6, - 0xf75c0000, - 0xf64a0008, - 0x0fc4fe9a, - 0x0662fd12, - 0x01a709a3, - 0x04ac0279, - 0xeebf004e, - 0xff6300d0, - 0xf9e4f9e4, - 0x00d0ff63, - 0x004eeebf, - 0x027904ac, - 0x09a301a7, - 0xfd120662, - 0xfe9a0fc4, - 0x0008f64a, - 0x0000f75c, - 0xfff60bd5, - 0xff110a89, - 0x057cf40e, - 0x03fe00af, - 0xf7daf099, - 0x0010fc91, - 0xf7be063d, - 0x00000000, - 0xf9c30842, - 0x036ffff0, - 0x0f670826, - 0xff51fc02, - 0x0bf2fa84, - 0xf57700ef, - 0xf42b000a, - 0x08a40000, - 0x09b6fff8, - 0xf03c0166, - 0xf99e02ee, - 0xfe59f65d, - 0xfb54fd87, - 0x1141ffb2, - 0x009dff30, - 0x05e30000, - 0xff060705, - 0x085408a0, - 0xf425fc59, - 0xfa1d042a, - 0xfc78f67a, - 0xf7acf60e, - 0x075a0766, - 0x05e305e3, - 0xf8a6f89a, - 0xf7acf60e, - 0x03880986, - 0xfa1d042a, - 0x0bdb03a7, - 0x085408a0, - 0x00faf8fb, - 0x05e30000, - 0xff06f8fb, - 0x0854f760, - 0xf42503a7, - 0xfa1dfbd6, - 0xfc780986, - 0xf7ac09f2, - 0x075af89a, - 0x05e3fa1d, - 0xf8a60766, - 0xf7ac09f2, - 0x0388f67a, - 0xfa1dfbd6, - 0x0bdbfc59, - 0x0854f760, - 0x00fa0705, - 0x05e30000, - 0xff060705, - 0x085408a0, - 0xf425fc59, - 0xfa1d042a, - 0xfc78f67a, - 0xf7acf60e, - 0x075a0766, - 0x05e305e3, - 0xf8a6f89a, - 0xf7acf60e, - 0x03880986, - 0xfa1d042a, - 0x0bdb03a7, - 0x085408a0, - 0x00faf8fb, - 0x05e30000, - 0xff06f8fb, - 0x0854f760, - 0xf42503a7, - 0xfa1dfbd6, - 0xfc780986, - 0xf7ac09f2, - 0x075af89a, - 0x05e3fa1d, - 0xf8a60766, - 0xf7ac09f2, - 0x0388f67a, - 0xfa1dfbd6, - 0x0bdbfc59, - 0x0854f760, - 0x00fa0705, - 0xfa58fa58, - 0xf8f0fe00, - 0x0448073d, - 0xfdc9fe46, - 0xf9910258, - 0x089d0407, - 0xfd5cf71a, - 0x02affde0, - 0x083e0496, - 0xff5a0740, - 0xff7afd97, - 0x00fe01f1, - 0x0009082e, - 0xfa94ff75, - 0xfecdf8ea, - 0xffb0f693, - 0xfd2cfa58, - 0x0433ff16, - 0xfba405dd, - 0xfa610341, - 0x06a606cb, - 0x0039fd2d, - 0x0677fa97, - 0x01fa05e0, - 0xf896003e, - 0x075a068b, - 0x012cfc3e, - 0xfa23f98d, - 0xfc7cfd43, - 0xff90fc0d, - 0x01c10982, - 0x00c601d6, - 0xfd2cfd2c, - 0x01d600c6, - 0x098201c1, - 0xfc0dff90, - 0xfd43fc7c, - 0xf98dfa23, - 0xfc3e012c, - 0x068b075a, - 0x003ef896, - 0x05e001fa, - 0xfa970677, - 0xfd2d0039, - 0x06cb06a6, - 0x0341fa61, - 0x05ddfba4, - 0xff160433, - 0xfa58fd2c, - 0xf693ffb0, - 0xf8eafecd, - 0xff75fa94, - 0x082e0009, - 0x01f100fe, - 0xfd97ff7a, - 0x0740ff5a, - 0x0496083e, - 0xfde002af, - 0xf71afd5c, - 0x0407089d, - 0x0258f991, - 0xfe46fdc9, - 0x073d0448, - 0xfe00f8f0, - 0xfd2cfd2c, - 0xfce00500, - 0xfc09fddc, - 0xfe680157, - 0x04c70571, - 0xfc3aff21, - 0xfcd70228, - 0x056d0277, - 0x0200fe00, - 0x0022f927, - 0xfe3c032b, - 0xfc44ff3c, - 0x03e9fbdb, - 0x04570313, - 0x04c9ff5c, - 0x000d03b8, - 0xfa580000, - 0xfbe900d2, - 0xf9d0fe0b, - 0x0125fdf9, - 0x042501bf, - 0x0328fa2b, - 0xffa902f0, - 0xfa250157, - 0x0200fe00, - 0x03740438, - 0xff0405fd, - 0x030cfe52, - 0x0037fb39, - 0xff6904c5, - 0x04f8fd23, - 0xfd31fc1b, - 0xfd2cfd2c, - 0xfc1bfd31, - 0xfd2304f8, - 0x04c5ff69, - 0xfb390037, - 0xfe52030c, - 0x05fdff04, - 0x04380374, - 0xfe000200, - 0x0157fa25, - 0x02f0ffa9, - 0xfa2b0328, - 0x01bf0425, - 0xfdf90125, - 0xfe0bf9d0, - 0x00d2fbe9, - 0x0000fa58, - 0x03b8000d, - 0xff5c04c9, - 0x03130457, - 0xfbdb03e9, - 0xff3cfc44, - 0x032bfe3c, - 0xf9270022, - 0xfe000200, - 0x0277056d, - 0x0228fcd7, - 0xff21fc3a, - 0x057104c7, - 0x0157fe68, - 0xfddcfc09, - 0x0500fce0, - 0xfd2cfd2c, - 0x0500fce0, - 0xfddcfc09, - 0x0157fe68, - 0x057104c7, - 0xff21fc3a, - 0x0228fcd7, - 0x0277056d, - 0xfe000200, - 0xf9270022, - 0x032bfe3c, - 0xff3cfc44, - 0xfbdb03e9, - 0x03130457, - 0xff5c04c9, - 0x03b8000d, - 0x0000fa58, - 0x00d2fbe9, - 0xfe0bf9d0, - 0xfdf90125, - 0x01bf0425, - 0xfa2b0328, - 0x02f0ffa9, - 0x0157fa25, - 0xfe000200, - 0x04380374, - 0x05fdff04, - 0xfe52030c, - 0xfb390037, - 0x04c5ff69, - 0xfd2304f8, - 0xfc1bfd31, - 0xfd2cfd2c, - 0xfd31fc1b, - 0x04f8fd23, - 0xff6904c5, - 0x0037fb39, - 0x030cfe52, - 0xff0405fd, - 0x03740438, - 0x0200fe00, - 0xfa250157, - 0xffa902f0, - 0x0328fa2b, - 0x042501bf, - 0x0125fdf9, - 0xf9d0fe0b, - 0xfbe900d2, - 0xfa580000, - 0x000d03b8, - 0x04c9ff5c, - 0x04570313, - 0x03e9fbdb, - 0xfc44ff3c, - 0xfe3c032b, - 0x0022f927, - 0x0200fe00, - 0x056d0277, - 0xfcd70228, - 0xfc3aff21, - 0x04c70571, - 0xfe680157, - 0xfc09fddc, - 0xfce00500, - 0x05a80000, - 0xff1006be, - 0x0800084a, - 0xf49cfc7e, - 0xfa580400, - 0xfc9cf6da, - 0xf800f672, - 0x0710071c, - 0x05a805a8, - 0xf8f0f8e4, - 0xf800f672, - 0x03640926, - 0xfa580400, - 0x0b640382, - 0x0800084a, - 0x00f0f942, - 0x05a80000, - 0xff10f942, - 0x0800f7b6, - 0xf49c0382, - 0xfa58fc00, - 0xfc9c0926, - 0xf800098e, - 0x0710f8e4, - 0x05a8fa58, - 0xf8f0071c, - 0xf800098e, - 0x0364f6da, - 0xfa58fc00, - 0x0b64fc7e, - 0x0800f7b6, - 0x00f006be, - 0x05a80000, - 0xff1006be, - 0x0800084a, - 0xf49cfc7e, - 0xfa580400, - 0xfc9cf6da, - 0xf800f672, - 0x0710071c, - 0x05a805a8, - 0xf8f0f8e4, - 0xf800f672, - 0x03640926, - 0xfa580400, - 0x0b640382, - 0x0800084a, - 0x00f0f942, - 0x05a80000, - 0xff10f942, - 0x0800f7b6, - 0xf49c0382, - 0xfa58fc00, - 0xfc9c0926, - 0xf800098e, - 0x0710f8e4, - 0x05a8fa58, - 0xf8f0071c, - 0xf800098e, - 0x0364f6da, - 0xfa58fc00, - 0x0b64fc7e, - 0x0800f7b6, - 0x00f006be, -}; - -const u32 noise_var_tbl_rev3[] = { - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, - 0x02110211, - 0x0000014d, -}; - -const u16 mcs_tbl_rev3[] = { - 0x0000, - 0x0008, - 0x000a, - 0x0010, - 0x0012, - 0x0019, - 0x001a, - 0x001c, - 0x0080, - 0x0088, - 0x008a, - 0x0090, - 0x0092, - 0x0099, - 0x009a, - 0x009c, - 0x0100, - 0x0108, - 0x010a, - 0x0110, - 0x0112, - 0x0119, - 0x011a, - 0x011c, - 0x0180, - 0x0188, - 0x018a, - 0x0190, - 0x0192, - 0x0199, - 0x019a, - 0x019c, - 0x0000, - 0x0098, - 0x00a0, - 0x00a8, - 0x009a, - 0x00a2, - 0x00aa, - 0x0120, - 0x0128, - 0x0128, - 0x0130, - 0x0138, - 0x0138, - 0x0140, - 0x0122, - 0x012a, - 0x012a, - 0x0132, - 0x013a, - 0x013a, - 0x0142, - 0x01a8, - 0x01b0, - 0x01b8, - 0x01b0, - 0x01b8, - 0x01c0, - 0x01c8, - 0x01c0, - 0x01c8, - 0x01d0, - 0x01d0, - 0x01d8, - 0x01aa, - 0x01b2, - 0x01ba, - 0x01b2, - 0x01ba, - 0x01c2, - 0x01ca, - 0x01c2, - 0x01ca, - 0x01d2, - 0x01d2, - 0x01da, - 0x0001, - 0x0002, - 0x0004, - 0x0009, - 0x000c, - 0x0011, - 0x0014, - 0x0018, - 0x0020, - 0x0021, - 0x0022, - 0x0024, - 0x0081, - 0x0082, - 0x0084, - 0x0089, - 0x008c, - 0x0091, - 0x0094, - 0x0098, - 0x00a0, - 0x00a1, - 0x00a2, - 0x00a4, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, - 0x0007, -}; - -const u32 tdi_tbl20_ant0_rev3[] = { - 0x00091226, - 0x000a1429, - 0x000b56ad, - 0x000c58b0, - 0x000d5ab3, - 0x000e9cb6, - 0x000f9eba, - 0x0000c13d, - 0x00020301, - 0x00030504, - 0x00040708, - 0x0005090b, - 0x00064b8e, - 0x00095291, - 0x000a5494, - 0x000b9718, - 0x000c9927, - 0x000d9b2a, - 0x000edd2e, - 0x000fdf31, - 0x000101b4, - 0x000243b7, - 0x000345bb, - 0x000447be, - 0x00058982, - 0x00068c05, - 0x00099309, - 0x000a950c, - 0x000bd78f, - 0x000cd992, - 0x000ddb96, - 0x000f1d99, - 0x00005fa8, - 0x0001422c, - 0x0002842f, - 0x00038632, - 0x00048835, - 0x0005ca38, - 0x0006ccbc, - 0x0009d3bf, - 0x000b1603, - 0x000c1806, - 0x000d1a0a, - 0x000e1c0d, - 0x000f5e10, - 0x00008093, - 0x00018297, - 0x0002c49a, - 0x0003c680, - 0x0004c880, - 0x00060b00, - 0x00070d00, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -const u32 tdi_tbl20_ant1_rev3[] = { - 0x00014b26, - 0x00028d29, - 0x000393ad, - 0x00049630, - 0x0005d833, - 0x0006da36, - 0x00099c3a, - 0x000a9e3d, - 0x000bc081, - 0x000cc284, - 0x000dc488, - 0x000f068b, - 0x0000488e, - 0x00018b91, - 0x0002d214, - 0x0003d418, - 0x0004d6a7, - 0x000618aa, - 0x00071aae, - 0x0009dcb1, - 0x000b1eb4, - 0x000c0137, - 0x000d033b, - 0x000e053e, - 0x000f4702, - 0x00008905, - 0x00020c09, - 0x0003128c, - 0x0004148f, - 0x00051712, - 0x00065916, - 0x00091b19, - 0x000a1d28, - 0x000b5f2c, - 0x000c41af, - 0x000d43b2, - 0x000e85b5, - 0x000f87b8, - 0x0000c9bc, - 0x00024cbf, - 0x00035303, - 0x00045506, - 0x0005978a, - 0x0006998d, - 0x00095b90, - 0x000a5d93, - 0x000b9f97, - 0x000c821a, - 0x000d8400, - 0x000ec600, - 0x000fc800, - 0x00010a00, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -const u32 tdi_tbl40_ant0_rev3[] = { - 0x0011a346, - 0x00136ccf, - 0x0014f5d9, - 0x001641e2, - 0x0017cb6b, - 0x00195475, - 0x001b2383, - 0x001cad0c, - 0x001e7616, - 0x0000821f, - 0x00020ba8, - 0x0003d4b2, - 0x00056447, - 0x00072dd0, - 0x0008b6da, - 0x000a02e3, - 0x000b8c6c, - 0x000d15f6, - 0x0011e484, - 0x0013ae0d, - 0x00153717, - 0x00168320, - 0x00180ca9, - 0x00199633, - 0x001b6548, - 0x001ceed1, - 0x001eb7db, - 0x0000c3e4, - 0x00024d6d, - 0x000416f7, - 0x0005a585, - 0x00076f0f, - 0x0008f818, - 0x000a4421, - 0x000bcdab, - 0x000d9734, - 0x00122649, - 0x0013efd2, - 0x001578dc, - 0x0016c4e5, - 0x00184e6e, - 0x001a17f8, - 0x001ba686, - 0x001d3010, - 0x001ef999, - 0x00010522, - 0x00028eac, - 0x00045835, - 0x0005e74a, - 0x0007b0d3, - 0x00093a5d, - 0x000a85e6, - 0x000c0f6f, - 0x000dd8f9, - 0x00126787, - 0x00143111, - 0x0015ba9a, - 0x00170623, - 0x00188fad, - 0x001a5936, - 0x001be84b, - 0x001db1d4, - 0x001f3b5e, - 0x000146e7, - 0x00031070, - 0x000499fa, - 0x00062888, - 0x0007f212, - 0x00097b9b, - 0x000ac7a4, - 0x000c50ae, - 0x000e1a37, - 0x0012a94c, - 0x001472d5, - 0x0015fc5f, - 0x00174868, - 0x0018d171, - 0x001a9afb, - 0x001c2989, - 0x001df313, - 0x001f7c9c, - 0x000188a5, - 0x000351af, - 0x0004db38, - 0x0006aa4d, - 0x000833d7, - 0x0009bd60, - 0x000b0969, - 0x000c9273, - 0x000e5bfc, - 0x00132a8a, - 0x0014b414, - 0x00163d9d, - 0x001789a6, - 0x001912b0, - 0x001adc39, - 0x001c6bce, - 0x001e34d8, - 0x001fbe61, - 0x0001ca6a, - 0x00039374, - 0x00051cfd, - 0x0006ec0b, - 0x00087515, - 0x0009fe9e, - 0x000b4aa7, - 0x000cd3b1, - 0x000e9d3a, - 0x00000000, - 0x00000000, -}; - -const u32 tdi_tbl40_ant1_rev3[] = { - 0x001edb36, - 0x000129ca, - 0x0002b353, - 0x00047cdd, - 0x0005c8e6, - 0x000791ef, - 0x00091bf9, - 0x000aaa07, - 0x000c3391, - 0x000dfd1a, - 0x00120923, - 0x0013d22d, - 0x00155c37, - 0x0016eacb, - 0x00187454, - 0x001a3dde, - 0x001b89e7, - 0x001d12f0, - 0x001f1cfa, - 0x00016b88, - 0x00033492, - 0x0004be1b, - 0x00060a24, - 0x0007d32e, - 0x00095d38, - 0x000aec4c, - 0x000c7555, - 0x000e3edf, - 0x00124ae8, - 0x001413f1, - 0x0015a37b, - 0x00172c89, - 0x0018b593, - 0x001a419c, - 0x001bcb25, - 0x001d942f, - 0x001f63b9, - 0x0001ad4d, - 0x00037657, - 0x0004c260, - 0x00068be9, - 0x000814f3, - 0x0009a47c, - 0x000b2d8a, - 0x000cb694, - 0x000e429d, - 0x00128c26, - 0x001455b0, - 0x0015e4ba, - 0x00176e4e, - 0x0018f758, - 0x001a8361, - 0x001c0cea, - 0x001dd674, - 0x001fa57d, - 0x0001ee8b, - 0x0003b795, - 0x0005039e, - 0x0006cd27, - 0x000856b1, - 0x0009e5c6, - 0x000b6f4f, - 0x000cf859, - 0x000e8462, - 0x00130deb, - 0x00149775, - 0x00162603, - 0x0017af8c, - 0x00193896, - 0x001ac49f, - 0x001c4e28, - 0x001e17b2, - 0x0000a6c7, - 0x00023050, - 0x0003f9da, - 0x00054563, - 0x00070eec, - 0x00089876, - 0x000a2704, - 0x000bb08d, - 0x000d3a17, - 0x001185a0, - 0x00134f29, - 0x0014d8b3, - 0x001667c8, - 0x0017f151, - 0x00197adb, - 0x001b0664, - 0x001c8fed, - 0x001e5977, - 0x0000e805, - 0x0002718f, - 0x00043b18, - 0x000586a1, - 0x0007502b, - 0x0008d9b4, - 0x000a68c9, - 0x000bf252, - 0x000dbbdc, - 0x0011c7e5, - 0x001390ee, - 0x00151a78, - 0x0016a906, - 0x00183290, - 0x0019bc19, - 0x001b4822, - 0x001cd12c, - 0x001e9ab5, - 0x00000000, - 0x00000000, -}; - -const u32 pltlut_tbl_rev3[] = { - 0x76540213, - 0x62407351, - 0x76543210, - 0x76540213, - 0x76540213, - 0x76430521, -}; - -const u32 chanest_tbl_rev3[] = { - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x44444444, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, - 0x10101010, -}; - -const u8 frame_lut_rev3[] = { - 0x02, - 0x04, - 0x14, - 0x14, - 0x03, - 0x05, - 0x16, - 0x16, - 0x0a, - 0x0c, - 0x1c, - 0x1c, - 0x0b, - 0x0d, - 0x1e, - 0x1e, - 0x06, - 0x08, - 0x18, - 0x18, - 0x07, - 0x09, - 0x1a, - 0x1a, - 0x0e, - 0x10, - 0x20, - 0x28, - 0x0f, - 0x11, - 0x22, - 0x2a, -}; - -const u8 est_pwr_lut_core0_rev3[] = { - 0x55, - 0x54, - 0x54, - 0x53, - 0x52, - 0x52, - 0x51, - 0x51, - 0x50, - 0x4f, - 0x4f, - 0x4e, - 0x4e, - 0x4d, - 0x4c, - 0x4c, - 0x4b, - 0x4a, - 0x49, - 0x49, - 0x48, - 0x47, - 0x46, - 0x46, - 0x45, - 0x44, - 0x43, - 0x42, - 0x41, - 0x40, - 0x40, - 0x3f, - 0x3e, - 0x3d, - 0x3c, - 0x3a, - 0x39, - 0x38, - 0x37, - 0x36, - 0x35, - 0x33, - 0x32, - 0x31, - 0x2f, - 0x2e, - 0x2c, - 0x2b, - 0x29, - 0x27, - 0x25, - 0x23, - 0x21, - 0x1f, - 0x1d, - 0x1a, - 0x18, - 0x15, - 0x12, - 0x0e, - 0x0b, - 0x07, - 0x02, - 0xfd, -}; - -const u8 est_pwr_lut_core1_rev3[] = { - 0x55, - 0x54, - 0x54, - 0x53, - 0x52, - 0x52, - 0x51, - 0x51, - 0x50, - 0x4f, - 0x4f, - 0x4e, - 0x4e, - 0x4d, - 0x4c, - 0x4c, - 0x4b, - 0x4a, - 0x49, - 0x49, - 0x48, - 0x47, - 0x46, - 0x46, - 0x45, - 0x44, - 0x43, - 0x42, - 0x41, - 0x40, - 0x40, - 0x3f, - 0x3e, - 0x3d, - 0x3c, - 0x3a, - 0x39, - 0x38, - 0x37, - 0x36, - 0x35, - 0x33, - 0x32, - 0x31, - 0x2f, - 0x2e, - 0x2c, - 0x2b, - 0x29, - 0x27, - 0x25, - 0x23, - 0x21, - 0x1f, - 0x1d, - 0x1a, - 0x18, - 0x15, - 0x12, - 0x0e, - 0x0b, - 0x07, - 0x02, - 0xfd, -}; - -const u8 adj_pwr_lut_core0_rev3[] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, -}; - -const u8 adj_pwr_lut_core1_rev3[] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, -}; - -const u32 gainctrl_lut_core0_rev3[] = { - 0x5bf70044, - 0x5bf70042, - 0x5bf70040, - 0x5bf7003e, - 0x5bf7003c, - 0x5bf7003b, - 0x5bf70039, - 0x5bf70037, - 0x5bf70036, - 0x5bf70034, - 0x5bf70033, - 0x5bf70031, - 0x5bf70030, - 0x5ba70044, - 0x5ba70042, - 0x5ba70040, - 0x5ba7003e, - 0x5ba7003c, - 0x5ba7003b, - 0x5ba70039, - 0x5ba70037, - 0x5ba70036, - 0x5ba70034, - 0x5ba70033, - 0x5b770044, - 0x5b770042, - 0x5b770040, - 0x5b77003e, - 0x5b77003c, - 0x5b77003b, - 0x5b770039, - 0x5b770037, - 0x5b770036, - 0x5b770034, - 0x5b770033, - 0x5b770031, - 0x5b770030, - 0x5b77002f, - 0x5b77002d, - 0x5b77002c, - 0x5b470044, - 0x5b470042, - 0x5b470040, - 0x5b47003e, - 0x5b47003c, - 0x5b47003b, - 0x5b470039, - 0x5b470037, - 0x5b470036, - 0x5b470034, - 0x5b470033, - 0x5b470031, - 0x5b470030, - 0x5b47002f, - 0x5b47002d, - 0x5b47002c, - 0x5b47002b, - 0x5b47002a, - 0x5b270044, - 0x5b270042, - 0x5b270040, - 0x5b27003e, - 0x5b27003c, - 0x5b27003b, - 0x5b270039, - 0x5b270037, - 0x5b270036, - 0x5b270034, - 0x5b270033, - 0x5b270031, - 0x5b270030, - 0x5b27002f, - 0x5b170044, - 0x5b170042, - 0x5b170040, - 0x5b17003e, - 0x5b17003c, - 0x5b17003b, - 0x5b170039, - 0x5b170037, - 0x5b170036, - 0x5b170034, - 0x5b170033, - 0x5b170031, - 0x5b170030, - 0x5b17002f, - 0x5b17002d, - 0x5b17002c, - 0x5b17002b, - 0x5b17002a, - 0x5b170028, - 0x5b170027, - 0x5b170026, - 0x5b170025, - 0x5b170024, - 0x5b170023, - 0x5b070044, - 0x5b070042, - 0x5b070040, - 0x5b07003e, - 0x5b07003c, - 0x5b07003b, - 0x5b070039, - 0x5b070037, - 0x5b070036, - 0x5b070034, - 0x5b070033, - 0x5b070031, - 0x5b070030, - 0x5b07002f, - 0x5b07002d, - 0x5b07002c, - 0x5b07002b, - 0x5b07002a, - 0x5b070028, - 0x5b070027, - 0x5b070026, - 0x5b070025, - 0x5b070024, - 0x5b070023, - 0x5b070022, - 0x5b070021, - 0x5b070020, - 0x5b07001f, - 0x5b07001e, - 0x5b07001d, - 0x5b07001d, - 0x5b07001c, -}; - -const u32 gainctrl_lut_core1_rev3[] = { - 0x5bf70044, - 0x5bf70042, - 0x5bf70040, - 0x5bf7003e, - 0x5bf7003c, - 0x5bf7003b, - 0x5bf70039, - 0x5bf70037, - 0x5bf70036, - 0x5bf70034, - 0x5bf70033, - 0x5bf70031, - 0x5bf70030, - 0x5ba70044, - 0x5ba70042, - 0x5ba70040, - 0x5ba7003e, - 0x5ba7003c, - 0x5ba7003b, - 0x5ba70039, - 0x5ba70037, - 0x5ba70036, - 0x5ba70034, - 0x5ba70033, - 0x5b770044, - 0x5b770042, - 0x5b770040, - 0x5b77003e, - 0x5b77003c, - 0x5b77003b, - 0x5b770039, - 0x5b770037, - 0x5b770036, - 0x5b770034, - 0x5b770033, - 0x5b770031, - 0x5b770030, - 0x5b77002f, - 0x5b77002d, - 0x5b77002c, - 0x5b470044, - 0x5b470042, - 0x5b470040, - 0x5b47003e, - 0x5b47003c, - 0x5b47003b, - 0x5b470039, - 0x5b470037, - 0x5b470036, - 0x5b470034, - 0x5b470033, - 0x5b470031, - 0x5b470030, - 0x5b47002f, - 0x5b47002d, - 0x5b47002c, - 0x5b47002b, - 0x5b47002a, - 0x5b270044, - 0x5b270042, - 0x5b270040, - 0x5b27003e, - 0x5b27003c, - 0x5b27003b, - 0x5b270039, - 0x5b270037, - 0x5b270036, - 0x5b270034, - 0x5b270033, - 0x5b270031, - 0x5b270030, - 0x5b27002f, - 0x5b170044, - 0x5b170042, - 0x5b170040, - 0x5b17003e, - 0x5b17003c, - 0x5b17003b, - 0x5b170039, - 0x5b170037, - 0x5b170036, - 0x5b170034, - 0x5b170033, - 0x5b170031, - 0x5b170030, - 0x5b17002f, - 0x5b17002d, - 0x5b17002c, - 0x5b17002b, - 0x5b17002a, - 0x5b170028, - 0x5b170027, - 0x5b170026, - 0x5b170025, - 0x5b170024, - 0x5b170023, - 0x5b070044, - 0x5b070042, - 0x5b070040, - 0x5b07003e, - 0x5b07003c, - 0x5b07003b, - 0x5b070039, - 0x5b070037, - 0x5b070036, - 0x5b070034, - 0x5b070033, - 0x5b070031, - 0x5b070030, - 0x5b07002f, - 0x5b07002d, - 0x5b07002c, - 0x5b07002b, - 0x5b07002a, - 0x5b070028, - 0x5b070027, - 0x5b070026, - 0x5b070025, - 0x5b070024, - 0x5b070023, - 0x5b070022, - 0x5b070021, - 0x5b070020, - 0x5b07001f, - 0x5b07001e, - 0x5b07001d, - 0x5b07001d, - 0x5b07001c, -}; - -const u32 iq_lut_core0_rev3[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -const u32 iq_lut_core1_rev3[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -const u16 loft_lut_core0_rev3[] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}; - -const u16 loft_lut_core1_rev3[] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}; - -const u16 papd_comp_rfpwr_tbl_core0_rev3[] = { - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x002a, - 0x002a, - 0x002a, - 0x002a, - 0x002a, - 0x002a, - 0x002a, - 0x002a, - 0x002a, - 0x002a, - 0x002a, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, -}; - -const u16 papd_comp_rfpwr_tbl_core1_rev3[] = { - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x0036, - 0x002a, - 0x002a, - 0x002a, - 0x002a, - 0x002a, - 0x002a, - 0x002a, - 0x002a, - 0x002a, - 0x002a, - 0x002a, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x001e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x000e, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01fc, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01ee, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, - 0x01d6, -}; - -const u32 papd_comp_epsilon_tbl_core0_rev3[] = { - 0x00000000, - 0x00001fa0, - 0x00019f78, - 0x0001df7e, - 0x03fa9f86, - 0x03fd1f90, - 0x03fe5f8a, - 0x03fb1f94, - 0x03fd9fa0, - 0x00009f98, - 0x03fd1fac, - 0x03ff9fa2, - 0x03fe9fae, - 0x00001fae, - 0x03fddfb4, - 0x03ff1fb8, - 0x03ff9fbc, - 0x03ffdfbe, - 0x03fe9fc2, - 0x03fedfc6, - 0x03fedfc6, - 0x03ff9fc8, - 0x03ff5fc6, - 0x03fedfc2, - 0x03ff9fc0, - 0x03ff5fac, - 0x03ff5fac, - 0x03ff9fa2, - 0x03ff9fa6, - 0x03ff9faa, - 0x03ff5fb0, - 0x03ff5fb4, - 0x03ff1fca, - 0x03ff5fce, - 0x03fcdfdc, - 0x03fb4006, - 0x00000030, - 0x03ff808a, - 0x03ff80da, - 0x0000016c, - 0x03ff8318, - 0x03ff063a, - 0x03fd8bd6, - 0x00014ffe, - 0x00034ffe, - 0x00034ffe, - 0x0003cffe, - 0x00040ffe, - 0x00040ffe, - 0x0003cffe, - 0x0003cffe, - 0x00020ffe, - 0x03fe0ffe, - 0x03fdcffe, - 0x03f94ffe, - 0x03f54ffe, - 0x03f44ffe, - 0x03ef8ffe, - 0x03ee0ffe, - 0x03ebcffe, - 0x03e8cffe, - 0x03e74ffe, - 0x03e4cffe, - 0x03e38ffe, -}; - -const u32 papd_cal_scalars_tbl_core0_rev3[] = { - 0x05af005a, - 0x0571005e, - 0x05040066, - 0x04bd006c, - 0x047d0072, - 0x04430078, - 0x03f70081, - 0x03cb0087, - 0x03870091, - 0x035e0098, - 0x032e00a1, - 0x030300aa, - 0x02d800b4, - 0x02ae00bf, - 0x028900ca, - 0x026400d6, - 0x024100e3, - 0x022200f0, - 0x020200ff, - 0x01e5010e, - 0x01ca011e, - 0x01b0012f, - 0x01990140, - 0x01830153, - 0x016c0168, - 0x0158017d, - 0x01450193, - 0x013301ab, - 0x012101c5, - 0x011101e0, - 0x010201fc, - 0x00f4021a, - 0x00e6011d, - 0x00d9012e, - 0x00cd0140, - 0x00c20153, - 0x00b70167, - 0x00ac017c, - 0x00a30193, - 0x009a01ab, - 0x009101c4, - 0x008901df, - 0x008101fb, - 0x007a0219, - 0x00730239, - 0x006d025b, - 0x0067027e, - 0x006102a4, - 0x005c02cc, - 0x005602f6, - 0x00520323, - 0x004d0353, - 0x00490385, - 0x004503bb, - 0x004103f3, - 0x003d042f, - 0x003a046f, - 0x003704b2, - 0x003404f9, - 0x00310545, - 0x002e0596, - 0x002b05f5, - 0x00290640, - 0x002606a4, -}; - -const u32 papd_comp_epsilon_tbl_core1_rev3[] = { - 0x00000000, - 0x00001fa0, - 0x00019f78, - 0x0001df7e, - 0x03fa9f86, - 0x03fd1f90, - 0x03fe5f8a, - 0x03fb1f94, - 0x03fd9fa0, - 0x00009f98, - 0x03fd1fac, - 0x03ff9fa2, - 0x03fe9fae, - 0x00001fae, - 0x03fddfb4, - 0x03ff1fb8, - 0x03ff9fbc, - 0x03ffdfbe, - 0x03fe9fc2, - 0x03fedfc6, - 0x03fedfc6, - 0x03ff9fc8, - 0x03ff5fc6, - 0x03fedfc2, - 0x03ff9fc0, - 0x03ff5fac, - 0x03ff5fac, - 0x03ff9fa2, - 0x03ff9fa6, - 0x03ff9faa, - 0x03ff5fb0, - 0x03ff5fb4, - 0x03ff1fca, - 0x03ff5fce, - 0x03fcdfdc, - 0x03fb4006, - 0x00000030, - 0x03ff808a, - 0x03ff80da, - 0x0000016c, - 0x03ff8318, - 0x03ff063a, - 0x03fd8bd6, - 0x00014ffe, - 0x00034ffe, - 0x00034ffe, - 0x0003cffe, - 0x00040ffe, - 0x00040ffe, - 0x0003cffe, - 0x0003cffe, - 0x00020ffe, - 0x03fe0ffe, - 0x03fdcffe, - 0x03f94ffe, - 0x03f54ffe, - 0x03f44ffe, - 0x03ef8ffe, - 0x03ee0ffe, - 0x03ebcffe, - 0x03e8cffe, - 0x03e74ffe, - 0x03e4cffe, - 0x03e38ffe, -}; - -const u32 papd_cal_scalars_tbl_core1_rev3[] = { - 0x05af005a, - 0x0571005e, - 0x05040066, - 0x04bd006c, - 0x047d0072, - 0x04430078, - 0x03f70081, - 0x03cb0087, - 0x03870091, - 0x035e0098, - 0x032e00a1, - 0x030300aa, - 0x02d800b4, - 0x02ae00bf, - 0x028900ca, - 0x026400d6, - 0x024100e3, - 0x022200f0, - 0x020200ff, - 0x01e5010e, - 0x01ca011e, - 0x01b0012f, - 0x01990140, - 0x01830153, - 0x016c0168, - 0x0158017d, - 0x01450193, - 0x013301ab, - 0x012101c5, - 0x011101e0, - 0x010201fc, - 0x00f4021a, - 0x00e6011d, - 0x00d9012e, - 0x00cd0140, - 0x00c20153, - 0x00b70167, - 0x00ac017c, - 0x00a30193, - 0x009a01ab, - 0x009101c4, - 0x008901df, - 0x008101fb, - 0x007a0219, - 0x00730239, - 0x006d025b, - 0x0067027e, - 0x006102a4, - 0x005c02cc, - 0x005602f6, - 0x00520323, - 0x004d0353, - 0x00490385, - 0x004503bb, - 0x004103f3, - 0x003d042f, - 0x003a046f, - 0x003704b2, - 0x003404f9, - 0x00310545, - 0x002e0596, - 0x002b05f5, - 0x00290640, - 0x002606a4, -}; - -const mimophytbl_info_t mimophytbl_info_rev3_volatile[] = { - {&ant_swctrl_tbl_rev3, - sizeof(ant_swctrl_tbl_rev3) / sizeof(ant_swctrl_tbl_rev3[0]), 9, 0, 16} - , -}; - -const mimophytbl_info_t mimophytbl_info_rev3_volatile1[] = { - {&ant_swctrl_tbl_rev3_1, - sizeof(ant_swctrl_tbl_rev3_1) / sizeof(ant_swctrl_tbl_rev3_1[0]), 9, 0, - 16} - , -}; - -const mimophytbl_info_t mimophytbl_info_rev3_volatile2[] = { - {&ant_swctrl_tbl_rev3_2, - sizeof(ant_swctrl_tbl_rev3_2) / sizeof(ant_swctrl_tbl_rev3_2[0]), 9, 0, - 16} - , -}; - -const mimophytbl_info_t mimophytbl_info_rev3_volatile3[] = { - {&ant_swctrl_tbl_rev3_3, - sizeof(ant_swctrl_tbl_rev3_3) / sizeof(ant_swctrl_tbl_rev3_3[0]), 9, 0, - 16} - , -}; - -const mimophytbl_info_t mimophytbl_info_rev3[] = { - {&frame_struct_rev3, - sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32} - , - {&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]), - 11, 0, 16} - , - {&tmap_tbl_rev3, sizeof(tmap_tbl_rev3) / sizeof(tmap_tbl_rev3[0]), 12, - 0, 32} - , - {&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]), - 13, 0, 32} - , - {&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]), - 14, 0, 32} - , - {&noise_var_tbl_rev3, - sizeof(noise_var_tbl_rev3) / sizeof(noise_var_tbl_rev3[0]), 16, 0, 32} - , - {&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0, - 16} - , - {&tdi_tbl20_ant0_rev3, - sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128, - 32} - , - {&tdi_tbl20_ant1_rev3, - sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256, - 32} - , - {&tdi_tbl40_ant0_rev3, - sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640, - 32} - , - {&tdi_tbl40_ant1_rev3, - sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768, - 32} - , - {&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]), - 20, 0, 32} - , - {&chanest_tbl_rev3, - sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32} - , - {&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]), - 24, 0, 8} - , - {&est_pwr_lut_core0_rev3, - sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26, - 0, 8} - , - {&est_pwr_lut_core1_rev3, - sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27, - 0, 8} - , - {&adj_pwr_lut_core0_rev3, - sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26, - 64, 8} - , - {&adj_pwr_lut_core1_rev3, - sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27, - 64, 8} - , - {&gainctrl_lut_core0_rev3, - sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]), - 26, 192, 32} - , - {&gainctrl_lut_core1_rev3, - sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]), - 27, 192, 32} - , - {&iq_lut_core0_rev3, - sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32} - , - {&iq_lut_core1_rev3, - sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32} - , - {&loft_lut_core0_rev3, - sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448, - 16} - , - {&loft_lut_core1_rev3, - sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448, - 16} -}; - -const u32 mimophytbl_info_sz_rev3 = - sizeof(mimophytbl_info_rev3) / sizeof(mimophytbl_info_rev3[0]); -const u32 mimophytbl_info_sz_rev3_volatile = - sizeof(mimophytbl_info_rev3_volatile) / - sizeof(mimophytbl_info_rev3_volatile[0]); -const u32 mimophytbl_info_sz_rev3_volatile1 = - sizeof(mimophytbl_info_rev3_volatile1) / - sizeof(mimophytbl_info_rev3_volatile1[0]); -const u32 mimophytbl_info_sz_rev3_volatile2 = - sizeof(mimophytbl_info_rev3_volatile2) / - sizeof(mimophytbl_info_rev3_volatile2[0]); -const u32 mimophytbl_info_sz_rev3_volatile3 = - sizeof(mimophytbl_info_rev3_volatile3) / - sizeof(mimophytbl_info_rev3_volatile3[0]); - -const u32 tmap_tbl_rev7[] = { - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0xf1111110, - 0x11111111, - 0x11f11111, - 0x00000111, - 0x11000000, - 0x1111f111, - 0x11111111, - 0x111111f1, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x000aa888, - 0x88880000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0xa1111110, - 0x11111111, - 0x11c11111, - 0x00000111, - 0x11000000, - 0x1111a111, - 0x11111111, - 0x111111a1, - 0xa2222220, - 0x22222222, - 0x22c22222, - 0x00000222, - 0x22000000, - 0x2222a222, - 0x22222222, - 0x222222a2, - 0xf1111110, - 0x11111111, - 0x11f11111, - 0x00011111, - 0x11110000, - 0x1111f111, - 0x11111111, - 0x111111f1, - 0xa8aa88a0, - 0xa88888a8, - 0xa8a8a88a, - 0x00088aaa, - 0xaaaa0000, - 0xa8a8aa88, - 0xa88aaaaa, - 0xaaaa8a8a, - 0xaaa8aaa0, - 0x8aaa8aaa, - 0xaa8a8a8a, - 0x000aaa88, - 0x8aaa0000, - 0xaaa8a888, - 0x8aa88a8a, - 0x8a88a888, - 0x08080a00, - 0x0a08080a, - 0x080a0a08, - 0x00080808, - 0x080a0000, - 0x080a0808, - 0x080a0808, - 0x0a0a0a08, - 0xa0a0a0a0, - 0x80a0a080, - 0x8080a0a0, - 0x00008080, - 0x80a00000, - 0x80a080a0, - 0xa080a0a0, - 0x8080a0a0, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x99999000, - 0x9b9b99bb, - 0x9bb99999, - 0x9999b9b9, - 0x9b99bb90, - 0x9bbbbb9b, - 0x9b9b9bb9, - 0x00000999, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00aaa888, - 0x22000000, - 0x2222b222, - 0x22222222, - 0x222222b2, - 0xb2222220, - 0x22222222, - 0x22d22222, - 0x00000222, - 0x11000000, - 0x1111a111, - 0x11111111, - 0x111111a1, - 0xa1111110, - 0x11111111, - 0x11c11111, - 0x00000111, - 0x33000000, - 0x3333b333, - 0x33333333, - 0x333333b3, - 0xb3333330, - 0x33333333, - 0x33d33333, - 0x00000333, - 0x22000000, - 0x2222a222, - 0x22222222, - 0x222222a2, - 0xa2222220, - 0x22222222, - 0x22c22222, - 0x00000222, - 0x99b99b00, - 0x9b9b99bb, - 0x9bb99999, - 0x9999b9b9, - 0x9b99bb99, - 0x9bbbbb9b, - 0x9b9b9bb9, - 0x00000999, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa88, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x08aaa888, - 0x22222200, - 0x2222f222, - 0x22222222, - 0x222222f2, - 0x22222222, - 0x22222222, - 0x22f22222, - 0x00000222, - 0x11000000, - 0x1111f111, - 0x11111111, - 0x11111111, - 0xf1111111, - 0x11111111, - 0x11f11111, - 0x01111111, - 0xbb9bb900, - 0xb9b9bb99, - 0xb99bbbbb, - 0xbbbb9b9b, - 0xb9bb99bb, - 0xb99999b9, - 0xb9b9b99b, - 0x00000bbb, - 0xaa000000, - 0xa8a8aa88, - 0xa88aaaaa, - 0xaaaa8a8a, - 0xa8aa88aa, - 0xa88888a8, - 0xa8a8a88a, - 0x0a888aaa, - 0xaa000000, - 0xa8a8aa88, - 0xa88aaaaa, - 0xaaaa8a8a, - 0xa8aa88a0, - 0xa88888a8, - 0xa8a8a88a, - 0x00000aaa, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0xbbbbbb00, - 0x999bbbbb, - 0x9bb99b9b, - 0xb9b9b9bb, - 0xb9b99bbb, - 0xb9b9b9bb, - 0xb9bb9b99, - 0x00000999, - 0x8a000000, - 0xaa88a888, - 0xa88888aa, - 0xa88a8a88, - 0xa88aa88a, - 0x88a8aaaa, - 0xa8aa8aaa, - 0x0888a88a, - 0x0b0b0b00, - 0x090b0b0b, - 0x0b090b0b, - 0x0909090b, - 0x09090b0b, - 0x09090b0b, - 0x09090b09, - 0x00000909, - 0x0a000000, - 0x0a080808, - 0x080a080a, - 0x080a0a08, - 0x080a080a, - 0x0808080a, - 0x0a0a0a08, - 0x0808080a, - 0xb0b0b000, - 0x9090b0b0, - 0x90b09090, - 0xb0b0b090, - 0xb0b090b0, - 0x90b0b0b0, - 0xb0b09090, - 0x00000090, - 0x80000000, - 0xa080a080, - 0xa08080a0, - 0xa0808080, - 0xa080a080, - 0x80a0a0a0, - 0xa0a080a0, - 0x00a0a0a0, - 0x22000000, - 0x2222f222, - 0x22222222, - 0x222222f2, - 0xf2222220, - 0x22222222, - 0x22f22222, - 0x00000222, - 0x11000000, - 0x1111f111, - 0x11111111, - 0x111111f1, - 0xf1111110, - 0x11111111, - 0x11f11111, - 0x00000111, - 0x33000000, - 0x3333f333, - 0x33333333, - 0x333333f3, - 0xf3333330, - 0x33333333, - 0x33f33333, - 0x00000333, - 0x22000000, - 0x2222f222, - 0x22222222, - 0x222222f2, - 0xf2222220, - 0x22222222, - 0x22f22222, - 0x00000222, - 0x99000000, - 0x9b9b99bb, - 0x9bb99999, - 0x9999b9b9, - 0x9b99bb90, - 0x9bbbbb9b, - 0x9b9b9bb9, - 0x00000999, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0x88888000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00aaa888, - 0x88a88a00, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa88, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x000aa888, - 0x88880000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa88, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x08aaa888, - 0x11000000, - 0x1111a111, - 0x11111111, - 0x111111a1, - 0xa1111110, - 0x11111111, - 0x11c11111, - 0x00000111, - 0x11000000, - 0x1111a111, - 0x11111111, - 0x111111a1, - 0xa1111110, - 0x11111111, - 0x11c11111, - 0x00000111, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0x88000000, - 0x8a8a88aa, - 0x8aa88888, - 0x8888a8a8, - 0x8a88aa80, - 0x8aaaaa8a, - 0x8a8a8aa8, - 0x00000888, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -const u32 noise_var_tbl_rev7[] = { - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, - 0x020c020c, - 0x0000014d, -}; - -const u32 papd_comp_epsilon_tbl_core0_rev7[] = { - 0x00000000, - 0x00000000, - 0x00016023, - 0x00006028, - 0x00034036, - 0x0003402e, - 0x0007203c, - 0x0006e037, - 0x00070030, - 0x0009401f, - 0x0009a00f, - 0x000b600d, - 0x000c8007, - 0x000ce007, - 0x00101fff, - 0x00121ff9, - 0x0012e004, - 0x0014dffc, - 0x0016dff6, - 0x0018dfe9, - 0x001b3fe5, - 0x001c5fd0, - 0x001ddfc2, - 0x001f1fb6, - 0x00207fa4, - 0x00219f8f, - 0x0022ff7d, - 0x00247f6c, - 0x0024df5b, - 0x00267f4b, - 0x0027df3b, - 0x0029bf3b, - 0x002b5f2f, - 0x002d3f2e, - 0x002f5f2a, - 0x002fff15, - 0x00315f0b, - 0x0032defa, - 0x0033beeb, - 0x0034fed9, - 0x00353ec5, - 0x00361eb0, - 0x00363e9b, - 0x0036be87, - 0x0036be70, - 0x0038fe67, - 0x0044beb2, - 0x00513ef3, - 0x00595f11, - 0x00669f3d, - 0x0078dfdf, - 0x00a143aa, - 0x01642fff, - 0x0162afff, - 0x01620fff, - 0x0160cfff, - 0x015f0fff, - 0x015dafff, - 0x015bcfff, - 0x015bcfff, - 0x015b4fff, - 0x015acfff, - 0x01590fff, - 0x0156cfff, -}; - -const u32 papd_cal_scalars_tbl_core0_rev7[] = { - 0x0b5e002d, - 0x0ae2002f, - 0x0a3b0032, - 0x09a70035, - 0x09220038, - 0x08ab003b, - 0x081f003f, - 0x07a20043, - 0x07340047, - 0x06d2004b, - 0x067a004f, - 0x06170054, - 0x05bf0059, - 0x0571005e, - 0x051e0064, - 0x04d3006a, - 0x04910070, - 0x044c0077, - 0x040f007e, - 0x03d90085, - 0x03a1008d, - 0x036f0095, - 0x033d009e, - 0x030b00a8, - 0x02e000b2, - 0x02b900bc, - 0x029200c7, - 0x026d00d3, - 0x024900e0, - 0x022900ed, - 0x020a00fb, - 0x01ec010a, - 0x01d20119, - 0x01b7012a, - 0x019e013c, - 0x0188014e, - 0x01720162, - 0x015d0177, - 0x0149018e, - 0x013701a5, - 0x012601be, - 0x011501d8, - 0x010601f4, - 0x00f70212, - 0x00e90231, - 0x00dc0253, - 0x00d00276, - 0x00c4029b, - 0x00b902c3, - 0x00af02ed, - 0x00a50319, - 0x009c0348, - 0x0093037a, - 0x008b03af, - 0x008303e6, - 0x007c0422, - 0x00750460, - 0x006e04a3, - 0x006804e9, - 0x00620533, - 0x005d0582, - 0x005805d6, - 0x0053062e, - 0x004e068c, -}; - -const u32 papd_comp_epsilon_tbl_core1_rev7[] = { - 0x00000000, - 0x00000000, - 0x00016023, - 0x00006028, - 0x00034036, - 0x0003402e, - 0x0007203c, - 0x0006e037, - 0x00070030, - 0x0009401f, - 0x0009a00f, - 0x000b600d, - 0x000c8007, - 0x000ce007, - 0x00101fff, - 0x00121ff9, - 0x0012e004, - 0x0014dffc, - 0x0016dff6, - 0x0018dfe9, - 0x001b3fe5, - 0x001c5fd0, - 0x001ddfc2, - 0x001f1fb6, - 0x00207fa4, - 0x00219f8f, - 0x0022ff7d, - 0x00247f6c, - 0x0024df5b, - 0x00267f4b, - 0x0027df3b, - 0x0029bf3b, - 0x002b5f2f, - 0x002d3f2e, - 0x002f5f2a, - 0x002fff15, - 0x00315f0b, - 0x0032defa, - 0x0033beeb, - 0x0034fed9, - 0x00353ec5, - 0x00361eb0, - 0x00363e9b, - 0x0036be87, - 0x0036be70, - 0x0038fe67, - 0x0044beb2, - 0x00513ef3, - 0x00595f11, - 0x00669f3d, - 0x0078dfdf, - 0x00a143aa, - 0x01642fff, - 0x0162afff, - 0x01620fff, - 0x0160cfff, - 0x015f0fff, - 0x015dafff, - 0x015bcfff, - 0x015bcfff, - 0x015b4fff, - 0x015acfff, - 0x01590fff, - 0x0156cfff, -}; - -const u32 papd_cal_scalars_tbl_core1_rev7[] = { - 0x0b5e002d, - 0x0ae2002f, - 0x0a3b0032, - 0x09a70035, - 0x09220038, - 0x08ab003b, - 0x081f003f, - 0x07a20043, - 0x07340047, - 0x06d2004b, - 0x067a004f, - 0x06170054, - 0x05bf0059, - 0x0571005e, - 0x051e0064, - 0x04d3006a, - 0x04910070, - 0x044c0077, - 0x040f007e, - 0x03d90085, - 0x03a1008d, - 0x036f0095, - 0x033d009e, - 0x030b00a8, - 0x02e000b2, - 0x02b900bc, - 0x029200c7, - 0x026d00d3, - 0x024900e0, - 0x022900ed, - 0x020a00fb, - 0x01ec010a, - 0x01d20119, - 0x01b7012a, - 0x019e013c, - 0x0188014e, - 0x01720162, - 0x015d0177, - 0x0149018e, - 0x013701a5, - 0x012601be, - 0x011501d8, - 0x010601f4, - 0x00f70212, - 0x00e90231, - 0x00dc0253, - 0x00d00276, - 0x00c4029b, - 0x00b902c3, - 0x00af02ed, - 0x00a50319, - 0x009c0348, - 0x0093037a, - 0x008b03af, - 0x008303e6, - 0x007c0422, - 0x00750460, - 0x006e04a3, - 0x006804e9, - 0x00620533, - 0x005d0582, - 0x005805d6, - 0x0053062e, - 0x004e068c, -}; - -const mimophytbl_info_t mimophytbl_info_rev7[] = { - {&frame_struct_rev3, - sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32} - , - {&pilot_tbl_rev3, sizeof(pilot_tbl_rev3) / sizeof(pilot_tbl_rev3[0]), - 11, 0, 16} - , - {&tmap_tbl_rev7, sizeof(tmap_tbl_rev7) / sizeof(tmap_tbl_rev7[0]), 12, - 0, 32} - , - {&intlv_tbl_rev3, sizeof(intlv_tbl_rev3) / sizeof(intlv_tbl_rev3[0]), - 13, 0, 32} - , - {&tdtrn_tbl_rev3, sizeof(tdtrn_tbl_rev3) / sizeof(tdtrn_tbl_rev3[0]), - 14, 0, 32} - , - {&noise_var_tbl_rev7, - sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32} - , - {&mcs_tbl_rev3, sizeof(mcs_tbl_rev3) / sizeof(mcs_tbl_rev3[0]), 18, 0, - 16} - , - {&tdi_tbl20_ant0_rev3, - sizeof(tdi_tbl20_ant0_rev3) / sizeof(tdi_tbl20_ant0_rev3[0]), 19, 128, - 32} - , - {&tdi_tbl20_ant1_rev3, - sizeof(tdi_tbl20_ant1_rev3) / sizeof(tdi_tbl20_ant1_rev3[0]), 19, 256, - 32} - , - {&tdi_tbl40_ant0_rev3, - sizeof(tdi_tbl40_ant0_rev3) / sizeof(tdi_tbl40_ant0_rev3[0]), 19, 640, - 32} - , - {&tdi_tbl40_ant1_rev3, - sizeof(tdi_tbl40_ant1_rev3) / sizeof(tdi_tbl40_ant1_rev3[0]), 19, 768, - 32} - , - {&pltlut_tbl_rev3, sizeof(pltlut_tbl_rev3) / sizeof(pltlut_tbl_rev3[0]), - 20, 0, 32} - , - {&chanest_tbl_rev3, - sizeof(chanest_tbl_rev3) / sizeof(chanest_tbl_rev3[0]), 22, 0, 32} - , - {&frame_lut_rev3, sizeof(frame_lut_rev3) / sizeof(frame_lut_rev3[0]), - 24, 0, 8} - , - {&est_pwr_lut_core0_rev3, - sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26, - 0, 8} - , - {&est_pwr_lut_core1_rev3, - sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27, - 0, 8} - , - {&adj_pwr_lut_core0_rev3, - sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26, - 64, 8} - , - {&adj_pwr_lut_core1_rev3, - sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27, - 64, 8} - , - {&gainctrl_lut_core0_rev3, - sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]), - 26, 192, 32} - , - {&gainctrl_lut_core1_rev3, - sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]), - 27, 192, 32} - , - {&iq_lut_core0_rev3, - sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32} - , - {&iq_lut_core1_rev3, - sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32} - , - {&loft_lut_core0_rev3, - sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448, - 16} - , - {&loft_lut_core1_rev3, - sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448, - 16} - , - {&papd_comp_rfpwr_tbl_core0_rev3, - sizeof(papd_comp_rfpwr_tbl_core0_rev3) / - sizeof(papd_comp_rfpwr_tbl_core0_rev3[0]), 26, 576, 16} - , - {&papd_comp_rfpwr_tbl_core1_rev3, - sizeof(papd_comp_rfpwr_tbl_core1_rev3) / - sizeof(papd_comp_rfpwr_tbl_core1_rev3[0]), 27, 576, 16} - , - {&papd_comp_epsilon_tbl_core0_rev7, - sizeof(papd_comp_epsilon_tbl_core0_rev7) / - sizeof(papd_comp_epsilon_tbl_core0_rev7[0]), 31, 0, 32} - , - {&papd_cal_scalars_tbl_core0_rev7, - sizeof(papd_cal_scalars_tbl_core0_rev7) / - sizeof(papd_cal_scalars_tbl_core0_rev7[0]), 32, 0, 32} - , - {&papd_comp_epsilon_tbl_core1_rev7, - sizeof(papd_comp_epsilon_tbl_core1_rev7) / - sizeof(papd_comp_epsilon_tbl_core1_rev7[0]), 33, 0, 32} - , - {&papd_cal_scalars_tbl_core1_rev7, - sizeof(papd_cal_scalars_tbl_core1_rev7) / - sizeof(papd_cal_scalars_tbl_core1_rev7[0]), 34, 0, 32} - , -}; - -const u32 mimophytbl_info_sz_rev7 = - sizeof(mimophytbl_info_rev7) / sizeof(mimophytbl_info_rev7[0]); - -const mimophytbl_info_t mimophytbl_info_rev16[] = { - {&noise_var_tbl_rev7, - sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32} - , - {&est_pwr_lut_core0_rev3, - sizeof(est_pwr_lut_core0_rev3) / sizeof(est_pwr_lut_core0_rev3[0]), 26, - 0, 8} - , - {&est_pwr_lut_core1_rev3, - sizeof(est_pwr_lut_core1_rev3) / sizeof(est_pwr_lut_core1_rev3[0]), 27, - 0, 8} - , - {&adj_pwr_lut_core0_rev3, - sizeof(adj_pwr_lut_core0_rev3) / sizeof(adj_pwr_lut_core0_rev3[0]), 26, - 64, 8} - , - {&adj_pwr_lut_core1_rev3, - sizeof(adj_pwr_lut_core1_rev3) / sizeof(adj_pwr_lut_core1_rev3[0]), 27, - 64, 8} - , - {&gainctrl_lut_core0_rev3, - sizeof(gainctrl_lut_core0_rev3) / sizeof(gainctrl_lut_core0_rev3[0]), - 26, 192, 32} - , - {&gainctrl_lut_core1_rev3, - sizeof(gainctrl_lut_core1_rev3) / sizeof(gainctrl_lut_core1_rev3[0]), - 27, 192, 32} - , - {&iq_lut_core0_rev3, - sizeof(iq_lut_core0_rev3) / sizeof(iq_lut_core0_rev3[0]), 26, 320, 32} - , - {&iq_lut_core1_rev3, - sizeof(iq_lut_core1_rev3) / sizeof(iq_lut_core1_rev3[0]), 27, 320, 32} - , - {&loft_lut_core0_rev3, - sizeof(loft_lut_core0_rev3) / sizeof(loft_lut_core0_rev3[0]), 26, 448, - 16} - , - {&loft_lut_core1_rev3, - sizeof(loft_lut_core1_rev3) / sizeof(loft_lut_core1_rev3[0]), 27, 448, - 16} - , -}; - -const u32 mimophytbl_info_sz_rev16 = - sizeof(mimophytbl_info_rev16) / sizeof(mimophytbl_info_rev16[0]); diff --git a/drivers/staging/brcm80211/phy/wlc_phytbl_n.h b/drivers/staging/brcm80211/phy/wlc_phytbl_n.h deleted file mode 100644 index 396122f5e50b..000000000000 --- a/drivers/staging/brcm80211/phy/wlc_phytbl_n.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define ANT_SWCTRL_TBL_REV3_IDX (0) - -typedef phytbl_info_t mimophytbl_info_t; - -extern const mimophytbl_info_t mimophytbl_info_rev0[], - mimophytbl_info_rev0_volatile[]; -extern const u32 mimophytbl_info_sz_rev0, mimophytbl_info_sz_rev0_volatile; - -extern const mimophytbl_info_t mimophytbl_info_rev3[], - mimophytbl_info_rev3_volatile[], mimophytbl_info_rev3_volatile1[], - mimophytbl_info_rev3_volatile2[], mimophytbl_info_rev3_volatile3[]; -extern const u32 mimophytbl_info_sz_rev3, mimophytbl_info_sz_rev3_volatile, - mimophytbl_info_sz_rev3_volatile1, mimophytbl_info_sz_rev3_volatile2, - mimophytbl_info_sz_rev3_volatile3; - -extern const u32 noise_var_tbl_rev3[]; - -extern const mimophytbl_info_t mimophytbl_info_rev7[]; -extern const u32 mimophytbl_info_sz_rev7; -extern const u32 noise_var_tbl_rev7[]; - -extern const mimophytbl_info_t mimophytbl_info_rev16[]; -extern const u32 mimophytbl_info_sz_rev16; diff --git a/drivers/staging/brcm80211/sys/d11ucode_ext.h b/drivers/staging/brcm80211/sys/d11ucode_ext.h deleted file mode 100644 index c0c0d661e00e..000000000000 --- a/drivers/staging/brcm80211/sys/d11ucode_ext.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -enum { - D11UCODE_NAMETAG_START = 0, - D11LCN0BSINITVALS24, - D11LCN0INITVALS24, - D11LCN1BSINITVALS24, - D11LCN1INITVALS24, - D11LCN2BSINITVALS24, - D11LCN2INITVALS24, - D11N0ABSINITVALS16, - D11N0BSINITVALS16, - D11N0INITVALS16, - D11UCODE_OVERSIGHT16_MIMO, - D11UCODE_OVERSIGHT16_MIMOSZ, - D11UCODE_OVERSIGHT24_LCN, - D11UCODE_OVERSIGHT24_LCNSZ, - D11UCODE_OVERSIGHT_BOMMAJOR, - D11UCODE_OVERSIGHT_BOMMINOR -}; -#define UCODE_LOADER_API_VER 0 diff --git a/drivers/staging/brcm80211/sys/wl_dbg.h b/drivers/staging/brcm80211/sys/wl_dbg.h deleted file mode 100644 index 54af257598c2..000000000000 --- a/drivers/staging/brcm80211/sys/wl_dbg.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wl_dbg_h_ -#define _wl_dbg_h_ - -/* wl_msg_level is a bit vector with defs in wlioctl.h */ -extern u32 wl_msg_level; - -#define WL_NONE(fmt, args...) no_printk(fmt, ##args) - -#define WL_PRINT(level, fmt, args...) \ -do { \ - if (wl_msg_level & level) \ - printk(fmt, ##args); \ -} while (0) - -#ifdef BCMDBG - -#define WL_ERROR(fmt, args...) WL_PRINT(WL_ERROR_VAL, fmt, ##args) -#define WL_TRACE(fmt, args...) WL_PRINT(WL_TRACE_VAL, fmt, ##args) -#define WL_AMPDU(fmt, args...) WL_PRINT(WL_AMPDU_VAL, fmt, ##args) -#define WL_FFPLD(fmt, args...) WL_PRINT(WL_FFPLD_VAL, fmt, ##args) - -#define WL_ERROR_ON() (wl_msg_level & WL_ERROR_VAL) - -/* Extra message control for AMPDU debugging */ -#define WL_AMPDU_UPDN_VAL 0x00000001 /* Config up/down related */ -#define WL_AMPDU_ERR_VAL 0x00000002 /* Calls to beaocn update */ -#define WL_AMPDU_TX_VAL 0x00000004 /* Transmit data path */ -#define WL_AMPDU_RX_VAL 0x00000008 /* Receive data path */ -#define WL_AMPDU_CTL_VAL 0x00000010 /* TSF-related items */ -#define WL_AMPDU_HW_VAL 0x00000020 /* AMPDU_HW */ -#define WL_AMPDU_HWTXS_VAL 0x00000040 /* AMPDU_HWTXS */ -#define WL_AMPDU_HWDBG_VAL 0x00000080 /* AMPDU_DBG */ - -extern u32 wl_ampdu_dbg; - -#define WL_AMPDU_PRINT(level, fmt, args...) \ -do { \ - if (wl_ampdu_dbg & level) { \ - WL_AMPDU(fmt, ##args); \ - } \ -} while (0) - -#define WL_AMPDU_UPDN(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_UPDN_VAL, fmt, ##args) -#define WL_AMPDU_RX(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_RX_VAL, fmt, ##args) -#define WL_AMPDU_ERR(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_ERR_VAL, fmt, ##args) -#define WL_AMPDU_TX(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_TX_VAL, fmt, ##args) -#define WL_AMPDU_CTL(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_CTL_VAL, fmt, ##args) -#define WL_AMPDU_HW(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_HW_VAL, fmt, ##args) -#define WL_AMPDU_HWTXS(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_HWTXS_VAL, fmt, ##args) -#define WL_AMPDU_HWDBG(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_HWDBG_VAL, fmt, ##args) -#define WL_AMPDU_ERR_ON() (wl_ampdu_dbg & WL_AMPDU_ERR_VAL) -#define WL_AMPDU_HW_ON() (wl_ampdu_dbg & WL_AMPDU_HW_VAL) -#define WL_AMPDU_HWTXS_ON() (wl_ampdu_dbg & WL_AMPDU_HWTXS_VAL) - -#else /* BCMDBG */ - -#define WL_ERROR(fmt, args...) no_printk(fmt, ##args) -#define WL_TRACE(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU(fmt, args...) no_printk(fmt, ##args) -#define WL_FFPLD(fmt, args...) no_printk(fmt, ##args) - -#define WL_ERROR_ON() 0 - -#define WL_AMPDU_UPDN(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_RX(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_ERR(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_TX(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_CTL(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_HW(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_HWTXS(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_HWDBG(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_ERR_ON() 0 -#define WL_AMPDU_HW_ON() 0 -#define WL_AMPDU_HWTXS_ON() 0 - -#endif /* BCMDBG */ - -#endif /* _wl_dbg_h_ */ diff --git a/drivers/staging/brcm80211/sys/wl_export.h b/drivers/staging/brcm80211/sys/wl_export.h deleted file mode 100644 index aa8b5a3ed633..000000000000 --- a/drivers/staging/brcm80211/sys/wl_export.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wl_export_h_ -#define _wl_export_h_ - -/* misc callbacks */ -struct wl_info; -struct wl_if; -struct wlc_if; -extern void wl_init(struct wl_info *wl); -extern uint wl_reset(struct wl_info *wl); -extern void wl_intrson(struct wl_info *wl); -extern u32 wl_intrsoff(struct wl_info *wl); -extern void wl_intrsrestore(struct wl_info *wl, u32 macintmask); -extern void wl_event(struct wl_info *wl, char *ifname, wlc_event_t *e); -extern void wl_event_sendup(struct wl_info *wl, const wlc_event_t *e, - u8 *data, u32 len); -extern int wl_up(struct wl_info *wl); -extern void wl_down(struct wl_info *wl); -extern void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, - int prio); -extern bool wl_alloc_dma_resources(struct wl_info *wl, uint dmaddrwidth); - -/* timer functions */ -struct wl_timer; -extern struct wl_timer *wl_init_timer(struct wl_info *wl, - void (*fn) (void *arg), void *arg, - const char *name); -extern void wl_free_timer(struct wl_info *wl, struct wl_timer *timer); -extern void wl_add_timer(struct wl_info *wl, struct wl_timer *timer, uint ms, - int periodic); -extern bool wl_del_timer(struct wl_info *wl, struct wl_timer *timer); - -extern uint wl_buf_to_pktcopy(struct osl_info *osh, void *p, unsigned char *buf, - int len, uint offset); -extern void *wl_get_pktbuffer(struct osl_info *osh, int len); -extern int wl_set_pktlen(struct osl_info *osh, void *p, int len); - -#define wl_sort_bsslist(a, b) false - -extern int wl_tkip_miccheck(struct wl_info *wl, void *p, int hdr_len, - bool group_key, int id); -extern int wl_tkip_micadd(struct wl_info *wl, void *p, int hdr_len); -extern int wl_tkip_encrypt(struct wl_info *wl, void *p, int hdr_len); -extern int wl_tkip_decrypt(struct wl_info *wl, void *p, int hdr_len, - bool group_key); -extern void wl_tkip_printstats(struct wl_info *wl, bool group_key); -extern int wl_tkip_keyset(struct wl_info *wl, wsec_key_t *key); -#endif /* _wl_export_h_ */ diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c deleted file mode 100644 index 6bc6207bab3e..000000000000 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ /dev/null @@ -1,1846 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define __UNDEF_NO_VERSION__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define WLC_MAXBSSCFG 1 /* single BSS configs */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - - -static void wl_timer(unsigned long data); -static void _wl_timer(wl_timer_t *t); - - -static int ieee_hw_init(struct ieee80211_hw *hw); -static int ieee_hw_rate_init(struct ieee80211_hw *hw); - -static int wl_linux_watchdog(void *ctx); - -/* Flags we support */ -#define MAC_FILTERS (FIF_PROMISC_IN_BSS | \ - FIF_ALLMULTI | \ - FIF_FCSFAIL | \ - FIF_PLCPFAIL | \ - FIF_CONTROL | \ - FIF_OTHER_BSS | \ - FIF_BCN_PRBRESP_PROMISC) - -static int wl_found; - -struct ieee80211_tkip_data { -#define TKIP_KEY_LEN 32 - u8 key[TKIP_KEY_LEN]; - int key_set; - - u32 tx_iv32; - u16 tx_iv16; - u16 tx_ttak[5]; - int tx_phase1_done; - - u32 rx_iv32; - u16 rx_iv16; - u16 rx_ttak[5]; - int rx_phase1_done; - u32 rx_iv32_new; - u16 rx_iv16_new; - - u32 dot11RSNAStatsTKIPReplays; - u32 dot11RSNAStatsTKIPICVErrors; - u32 dot11RSNAStatsTKIPLocalMICFailures; - - int key_idx; - - struct crypto_tfm *tfm_arc4; - struct crypto_tfm *tfm_michael; - - /* scratch buffers for virt_to_page() (crypto API) */ - u8 rx_hdr[16], tx_hdr[16]; -}; - -#define WL_DEV_IF(dev) ((struct wl_if *)netdev_priv(dev)) -#define WL_INFO(dev) ((struct wl_info *)(WL_DEV_IF(dev)->wl)) -static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev); -static void wl_release_fw(struct wl_info *wl); - -/* local prototypes */ -static int wl_start(struct sk_buff *skb, struct wl_info *wl); -static int wl_start_int(struct wl_info *wl, struct ieee80211_hw *hw, - struct sk_buff *skb); -static void wl_dpc(unsigned long data); - -MODULE_AUTHOR("Broadcom Corporation"); -MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver."); -MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards"); -MODULE_LICENSE("Dual BSD/GPL"); - -/* recognized PCI IDs */ -static struct pci_device_id wl_id_table[] = { - {PCI_VENDOR_ID_BROADCOM, 0x4357, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43225 2G */ - {PCI_VENDOR_ID_BROADCOM, 0x4353, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43224 DUAL */ - {PCI_VENDOR_ID_BROADCOM, 0x4727, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 4313 DUAL */ - {0} -}; - -MODULE_DEVICE_TABLE(pci, wl_id_table); -static void wl_remove(struct pci_dev *pdev); - - -#ifdef BCMDBG -static int msglevel = 0xdeadbeef; -module_param(msglevel, int, 0); -static int phymsglevel = 0xdeadbeef; -module_param(phymsglevel, int, 0); -#endif /* BCMDBG */ - -#define HW_TO_WL(hw) (hw->priv) -#define WL_TO_HW(wl) (wl->pub->ieee_hw) -static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb); -static int wl_ops_start(struct ieee80211_hw *hw); -static void wl_ops_stop(struct ieee80211_hw *hw); -static int wl_ops_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif); -static void wl_ops_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif); -static int wl_ops_config(struct ieee80211_hw *hw, u32 changed); -static void wl_ops_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *info, - u32 changed); -static void wl_ops_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, u64 multicast); -static int wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, - bool set); -static void wl_ops_sw_scan_start(struct ieee80211_hw *hw); -static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw); -static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf); -static int wl_ops_get_stats(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats); -static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value); -static void wl_ops_sta_notify(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum sta_notify_cmd cmd, - struct ieee80211_sta *sta); -static int wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, - const struct ieee80211_tx_queue_params *params); -static u64 wl_ops_get_tsf(struct ieee80211_hw *hw); -static int wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta); -static int wl_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta); -static int wl_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn); - -static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - int status; - struct wl_info *wl = hw->priv; - WL_LOCK(wl); - if (!wl->pub->up) { - WL_ERROR("ops->tx called while down\n"); - status = -ENETDOWN; - goto done; - } - status = wl_start(skb, wl); - done: - WL_UNLOCK(wl); - return status; -} - -static int wl_ops_start(struct ieee80211_hw *hw) -{ - struct wl_info *wl = hw->priv; - /* - struct ieee80211_channel *curchan = hw->conf.channel; - WL_NONE("%s : Initial channel: %d\n", __func__, curchan->hw_value); - */ - - WL_LOCK(wl); - ieee80211_wake_queues(hw); - WL_UNLOCK(wl); - - return 0; -} - -static void wl_ops_stop(struct ieee80211_hw *hw) -{ - struct wl_info *wl = hw->priv; - ASSERT(wl); - WL_LOCK(wl); - wl_down(wl); - ieee80211_stop_queues(hw); - WL_UNLOCK(wl); - - return; -} - -static int -wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -{ - struct wl_info *wl; - int err; - - /* Just STA for now */ - if (vif->type != NL80211_IFTYPE_AP && - vif->type != NL80211_IFTYPE_MESH_POINT && - vif->type != NL80211_IFTYPE_STATION && - vif->type != NL80211_IFTYPE_WDS && - vif->type != NL80211_IFTYPE_ADHOC) { - WL_ERROR("%s: Attempt to add type %d, only STA for now\n", - __func__, vif->type); - return -EOPNOTSUPP; - } - - wl = HW_TO_WL(hw); - WL_LOCK(wl); - err = wl_up(wl); - WL_UNLOCK(wl); - - if (err != 0) - WL_ERROR("%s: wl_up() returned %d\n", __func__, err); - return err; -} - -static void -wl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -{ - return; -} - -static int -ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan, - enum nl80211_channel_type type) -{ - struct wl_info *wl = HW_TO_WL(hw); - int err = 0; - - switch (type) { - case NL80211_CHAN_HT20: - case NL80211_CHAN_NO_HT: - WL_LOCK(wl); - err = wlc_set(wl->wlc, WLC_SET_CHANNEL, chan->hw_value); - WL_UNLOCK(wl); - break; - case NL80211_CHAN_HT40MINUS: - case NL80211_CHAN_HT40PLUS: - WL_ERROR("%s: Need to implement 40 Mhz Channels!\n", __func__); - break; - } - - if (err) - return -EIO; - return err; -} - -static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) -{ - struct ieee80211_conf *conf = &hw->conf; - struct wl_info *wl = HW_TO_WL(hw); - int err = 0; - int new_int; - - if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { - WL_NONE("%s: Setting listen interval to %d\n", - __func__, conf->listen_interval); - if (wlc_iovar_setint - (wl->wlc, "bcn_li_bcn", conf->listen_interval)) { - WL_ERROR("%s: Error setting listen_interval\n", - __func__); - err = -EIO; - goto config_out; - } - wlc_iovar_getint(wl->wlc, "bcn_li_bcn", &new_int); - ASSERT(new_int == conf->listen_interval); - } - if (changed & IEEE80211_CONF_CHANGE_MONITOR) - WL_NONE("Need to set monitor mode\n"); - if (changed & IEEE80211_CONF_CHANGE_PS) - WL_NONE("Need to set Power-save mode\n"); - - if (changed & IEEE80211_CONF_CHANGE_POWER) { - WL_NONE("%s: Setting tx power to %d dbm\n", - __func__, conf->power_level); - if (wlc_iovar_setint - (wl->wlc, "qtxpower", conf->power_level * 4)) { - WL_ERROR("%s: Error setting power_level\n", __func__); - err = -EIO; - goto config_out; - } - wlc_iovar_getint(wl->wlc, "qtxpower", &new_int); - if (new_int != (conf->power_level * 4)) - WL_ERROR("%s: Power level req != actual, %d %d\n", - __func__, conf->power_level * 4, new_int); - } - if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - err = ieee_set_channel(hw, conf->channel, conf->channel_type); - } - if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { - WL_NONE("%s: srl %d, lrl %d\n", - __func__, - conf->short_frame_max_tx_count, - conf->long_frame_max_tx_count); - if (wlc_set - (wl->wlc, WLC_SET_SRL, - conf->short_frame_max_tx_count) < 0) { - WL_ERROR("%s: Error setting srl\n", __func__); - err = -EIO; - goto config_out; - } - if (wlc_set(wl->wlc, WLC_SET_LRL, conf->long_frame_max_tx_count) - < 0) { - WL_ERROR("%s: Error setting lrl\n", __func__); - err = -EIO; - goto config_out; - } - } - - config_out: - return err; -} - -static void -wl_ops_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *info, u32 changed) -{ - struct wl_info *wl = HW_TO_WL(hw); - int val; - - - if (changed & BSS_CHANGED_ASSOC) { - WL_ERROR("Associated:\t%s\n", info->assoc ? "True" : "False"); - /* association status changed (associated/disassociated) - * also implies a change in the AID. - */ - } - if (changed & BSS_CHANGED_ERP_CTS_PROT) { - WL_NONE("Use_cts_prot:\t%s Implement me\n", - info->use_cts_prot ? "True" : "False"); - /* CTS protection changed */ - } - if (changed & BSS_CHANGED_ERP_PREAMBLE) { - WL_NONE("Short preamble:\t%s Implement me\n", - info->use_short_preamble ? "True" : "False"); - /* preamble changed */ - } - if (changed & BSS_CHANGED_ERP_SLOT) { - WL_NONE("Changing short slot:\t%s\n", - info->use_short_slot ? "True" : "False"); - if (info->use_short_slot) - val = 1; - else - val = 0; - wlc_set(wl->wlc, WLC_SET_SHORTSLOT_OVERRIDE, val); - /* slot timing changed */ - } - - if (changed & BSS_CHANGED_HT) { - WL_NONE("%s: HT mode - Implement me\n", __func__); - /* 802.11n parameters changed */ - } - if (changed & BSS_CHANGED_BASIC_RATES) { - WL_NONE("Need to change Basic Rates:\t0x%x! Implement me\n", - (u32) info->basic_rates); - /* Basic rateset changed */ - } - if (changed & BSS_CHANGED_BEACON_INT) { - WL_NONE("Beacon Interval:\t%d Implement me\n", - info->beacon_int); - /* Beacon interval changed */ - } - if (changed & BSS_CHANGED_BSSID) { - WL_NONE("new BSSID:\taid %d bss:%pM\n", - info->aid, info->bssid); - /* BSSID changed, for whatever reason (IBSS and managed mode) */ - /* FIXME: need to store bssid in bsscfg */ - wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, - info->bssid); - } - if (changed & BSS_CHANGED_BEACON) { - WL_ERROR("BSS_CHANGED_BEACON\n"); - /* Beacon data changed, retrieve new beacon (beaconing modes) */ - } - if (changed & BSS_CHANGED_BEACON_ENABLED) { - WL_ERROR("Beacon enabled:\t%s\n", - info->enable_beacon ? "True" : "False"); - /* Beaconing should be enabled/disabled (beaconing modes) */ - } - return; -} - -static void -wl_ops_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, u64 multicast) -{ - struct wl_info *wl = hw->priv; - - changed_flags &= MAC_FILTERS; - *total_flags &= MAC_FILTERS; - if (changed_flags & FIF_PROMISC_IN_BSS) - WL_ERROR("FIF_PROMISC_IN_BSS\n"); - if (changed_flags & FIF_ALLMULTI) - WL_ERROR("FIF_ALLMULTI\n"); - if (changed_flags & FIF_FCSFAIL) - WL_ERROR("FIF_FCSFAIL\n"); - if (changed_flags & FIF_PLCPFAIL) - WL_ERROR("FIF_PLCPFAIL\n"); - if (changed_flags & FIF_CONTROL) - WL_ERROR("FIF_CONTROL\n"); - if (changed_flags & FIF_OTHER_BSS) - WL_ERROR("FIF_OTHER_BSS\n"); - if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { - WL_NONE("FIF_BCN_PRBRESP_PROMISC\n"); - WL_LOCK(wl); - if (*total_flags & FIF_BCN_PRBRESP_PROMISC) { - wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS; - wlc_mac_bcn_promisc_change(wl->wlc, 1); - } else { - wlc_mac_bcn_promisc_change(wl->wlc, 0); - wl->pub->mac80211_state &= ~MAC80211_PROMISC_BCNS; - } - WL_UNLOCK(wl); - } - return; -} - -static int -wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) -{ - WL_ERROR("%s: Enter\n", __func__); - return 0; -} - -static void wl_ops_sw_scan_start(struct ieee80211_hw *hw) -{ - WL_NONE("Scan Start\n"); - return; -} - -static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw) -{ - WL_NONE("Scan Complete\n"); - return; -} - -static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf) -{ - WL_ERROR("%s: Enter\n", __func__); - return; -} - -static int -wl_ops_get_stats(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats) -{ - WL_ERROR("%s: Enter\n", __func__); - return 0; -} - -static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value) -{ - WL_ERROR("%s: Enter\n", __func__); - return 0; -} - -static void -wl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - enum sta_notify_cmd cmd, struct ieee80211_sta *sta) -{ - WL_NONE("%s: Enter\n", __func__); - switch (cmd) { - default: - WL_ERROR("%s: Unknown cmd = %d\n", __func__, cmd); - break; - } - return; -} - -static int -wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, - const struct ieee80211_tx_queue_params *params) -{ - struct wl_info *wl = hw->priv; - - WL_NONE("%s: Enter (WME config)\n", __func__); - WL_NONE("queue %d, txop %d, cwmin %d, cwmax %d, aifs %d\n", queue, - params->txop, params->cw_min, params->cw_max, params->aifs); - - WL_LOCK(wl); - wlc_wme_setparams(wl->wlc, queue, (void *)params, true); - WL_UNLOCK(wl); - - return 0; -} - -static u64 wl_ops_get_tsf(struct ieee80211_hw *hw) -{ - WL_ERROR("%s: Enter\n", __func__); - return 0; -} - -static int -wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - struct scb *scb; - - int i; - struct wl_info *wl = hw->priv; - - /* Init the scb */ - scb = (struct scb *)sta->drv_priv; - memset(scb, 0, sizeof(struct scb)); - for (i = 0; i < NUMPRIO; i++) - scb->seqctl[i] = 0xFFFF; - scb->seqctl_nonqos = 0xFFFF; - scb->magic = SCB_MAGIC; - - wl->pub->global_scb = scb; - wl->pub->global_ampdu = &(scb->scb_ampdu); - wl->pub->global_ampdu->scb = scb; - wl->pub->global_ampdu->max_pdu = 16; - pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID, - AMPDU_MAX_SCB_TID * PKTQ_LEN_DEFAULT); - - sta->ht_cap.ht_supported = true; - sta->ht_cap.ampdu_factor = AMPDU_RX_FACTOR_64K; - sta->ht_cap.ampdu_density = AMPDU_DEF_MPDU_DENSITY; - sta->ht_cap.cap = IEEE80211_HT_CAP_GRN_FLD | - IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT; - - /* minstrel_ht initiates addBA on our behalf by calling ieee80211_start_tx_ba_session() */ - return 0; -} - -static int -wl_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - WL_NONE("%s: Enter\n", __func__); - return 0; -} - -static int -wl_ampdu_action(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn) -{ -#if defined(BCMDBG) - struct scb *scb = (struct scb *)sta->drv_priv; -#endif - struct wl_info *wl = hw->priv; - - ASSERT(scb->magic == SCB_MAGIC); - switch (action) { - case IEEE80211_AMPDU_RX_START: - WL_NONE("%s: action = IEEE80211_AMPDU_RX_START\n", __func__); - break; - case IEEE80211_AMPDU_RX_STOP: - WL_NONE("%s: action = IEEE80211_AMPDU_RX_STOP\n", __func__); - break; - case IEEE80211_AMPDU_TX_START: - if (!wlc_aggregatable(wl->wlc, tid)) { - /* WL_ERROR("START: tid %d is not agg' able, return FAILURE to stack\n", tid); */ - return -1; - } - /* XXX: Use the starting sequence number provided ... */ - *ssn = 0; - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); - break; - - case IEEE80211_AMPDU_TX_STOP: - ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); - break; - case IEEE80211_AMPDU_TX_OPERATIONAL: - /* Not sure what to do here */ - /* Power save wakeup */ - WL_NONE("%s: action = IEEE80211_AMPDU_TX_OPERATIONAL\n", - __func__); - break; - default: - WL_ERROR("%s: Invalid command, ignoring\n", __func__); - } - - return 0; -} - -static const struct ieee80211_ops wl_ops = { - .tx = wl_ops_tx, - .start = wl_ops_start, - .stop = wl_ops_stop, - .add_interface = wl_ops_add_interface, - .remove_interface = wl_ops_remove_interface, - .config = wl_ops_config, - .bss_info_changed = wl_ops_bss_info_changed, - .configure_filter = wl_ops_configure_filter, - .set_tim = wl_ops_set_tim, - .sw_scan_start = wl_ops_sw_scan_start, - .sw_scan_complete = wl_ops_sw_scan_complete, - .set_tsf = wl_ops_set_tsf, - .get_stats = wl_ops_get_stats, - .set_rts_threshold = wl_ops_set_rts_threshold, - .sta_notify = wl_ops_sta_notify, - .conf_tx = wl_ops_conf_tx, - .get_tsf = wl_ops_get_tsf, - .sta_add = wl_sta_add, - .sta_remove = wl_sta_remove, - .ampdu_action = wl_ampdu_action, -}; - -static int wl_set_hint(struct wl_info *wl, char *abbrev) -{ - WL_ERROR("%s: Sending country code %c%c to MAC80211\n", - __func__, abbrev[0], abbrev[1]); - return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev); -} - -/** - * attach to the WL device. - * - * Attach to the WL device identified by vendor and device parameters. - * regs is a host accessible memory address pointing to WL device registers. - * - * wl_attach is not defined as static because in the case where no bus - * is defined, wl_attach will never be called, and thus, gcc will issue - * a warning that this function is defined but not used if we declare - * it as static. - */ -static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, - uint bustype, void *btparam, uint irq) -{ - struct wl_info *wl; - struct osl_info *osh; - int unit, err; - - unsigned long base_addr; - struct ieee80211_hw *hw; - u8 perm[ETH_ALEN]; - - unit = wl_found; - err = 0; - - if (unit < 0) { - WL_ERROR("wl%d: unit number overflow, exiting\n", unit); - return NULL; - } - - osh = osl_attach(btparam, bustype); - ASSERT(osh); - - /* allocate private info */ - hw = pci_get_drvdata(btparam); /* btparam == pdev */ - wl = hw->priv; - ASSERT(wl); - - wl->osh = osh; - atomic_set(&wl->callbacks, 0); - - /* setup the bottom half handler */ - tasklet_init(&wl->tasklet, wl_dpc, (unsigned long) wl); - - - - base_addr = regs; - - if (bustype == PCI_BUS) { - wl->piomode = false; - } else if (bustype == RPC_BUS) { - /* Do nothing */ - } else { - bustype = PCI_BUS; - WL_TRACE("force to PCI\n"); - } - wl->bcm_bustype = bustype; - - wl->regsva = ioremap_nocache(base_addr, PCI_BAR0_WINSZ); - if (wl->regsva == NULL) { - WL_ERROR("wl%d: ioremap() failed\n", unit); - goto fail; - } - spin_lock_init(&wl->lock); - spin_lock_init(&wl->isr_lock); - - /* prepare ucode */ - if (wl_request_fw(wl, (struct pci_dev *)btparam)) { - printf("%s: Failed to find firmware usually in %s\n", - KBUILD_MODNAME, "/lib/firmware/brcm"); - wl_release_fw(wl); - wl_remove((struct pci_dev *)btparam); - goto fail1; - } - - /* common load-time initialization */ - wl->wlc = wlc_attach((void *)wl, vendor, device, unit, wl->piomode, osh, - wl->regsva, wl->bcm_bustype, btparam, &err); - wl_release_fw(wl); - if (!wl->wlc) { - printf("%s: wlc_attach() failed with code %d\n", - KBUILD_MODNAME, err); - goto fail; - } - wl->pub = wlc_pub(wl->wlc); - - wl->pub->ieee_hw = hw; - ASSERT(wl->pub->ieee_hw); - ASSERT(wl->pub->ieee_hw->priv == wl); - - - if (wlc_iovar_setint(wl->wlc, "mpc", 0)) { - WL_ERROR("wl%d: Error setting MPC variable to 0\n", unit); - } - - /* register our interrupt handler */ - if (request_irq(irq, wl_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { - WL_ERROR("wl%d: request_irq() failed\n", unit); - goto fail; - } - wl->irq = irq; - - /* register module */ - wlc_module_register(wl->pub, NULL, "linux", wl, NULL, wl_linux_watchdog, - NULL); - - if (ieee_hw_init(hw)) { - WL_ERROR("wl%d: %s: ieee_hw_init failed!\n", unit, __func__); - goto fail; - } - - bcopy(&wl->pub->cur_etheraddr, perm, ETH_ALEN); - ASSERT(is_valid_ether_addr(perm)); - SET_IEEE80211_PERM_ADDR(hw, perm); - - err = ieee80211_register_hw(hw); - if (err) { - WL_ERROR("%s: ieee80211_register_hw failed, status %d\n", - __func__, err); - } - - if (wl->pub->srom_ccode[0]) - err = wl_set_hint(wl, wl->pub->srom_ccode); - else - err = wl_set_hint(wl, "US"); - if (err) { - WL_ERROR("%s: regulatory_hint failed, status %d\n", - __func__, err); - } - WL_ERROR("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver (" PHY_VERSION_STR ")", - unit); - -#ifdef BCMDBG - printf(" (Compiled at " __TIME__ " on " __DATE__ ")"); -#endif /* BCMDBG */ - printf("\n"); - - wl_found++; - return wl; - - fail: - wl_free(wl); -fail1: - return NULL; -} - - - -#define CHAN2GHZ(channel, freqency, chflags) { \ - .band = IEEE80211_BAND_2GHZ, \ - .center_freq = (freqency), \ - .hw_value = (channel), \ - .flags = chflags, \ - .max_antenna_gain = 0, \ - .max_power = 19, \ -} - -static struct ieee80211_channel wl_2ghz_chantable[] = { - CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS), - CHAN2GHZ(2, 2417, IEEE80211_CHAN_NO_HT40MINUS), - CHAN2GHZ(3, 2422, IEEE80211_CHAN_NO_HT40MINUS), - CHAN2GHZ(4, 2427, IEEE80211_CHAN_NO_HT40MINUS), - CHAN2GHZ(5, 2432, 0), - CHAN2GHZ(6, 2437, 0), - CHAN2GHZ(7, 2442, 0), - CHAN2GHZ(8, 2447, IEEE80211_CHAN_NO_HT40PLUS), - CHAN2GHZ(9, 2452, IEEE80211_CHAN_NO_HT40PLUS), - CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS), - CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS), - CHAN2GHZ(12, 2467, - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_NO_HT40PLUS), - CHAN2GHZ(13, 2472, - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_NO_HT40PLUS), - CHAN2GHZ(14, 2484, - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS) -}; - -#define CHAN5GHZ(channel, chflags) { \ - .band = IEEE80211_BAND_5GHZ, \ - .center_freq = 5000 + 5*(channel), \ - .hw_value = (channel), \ - .flags = chflags, \ - .max_antenna_gain = 0, \ - .max_power = 21, \ -} - -static struct ieee80211_channel wl_5ghz_nphy_chantable[] = { - /* UNII-1 */ - CHAN5GHZ(36, IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(40, IEEE80211_CHAN_NO_HT40PLUS), - CHAN5GHZ(44, IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS), - /* UNII-2 */ - CHAN5GHZ(52, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(56, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), - CHAN5GHZ(60, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(64, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), - /* MID */ - CHAN5GHZ(100, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(104, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), - CHAN5GHZ(108, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(112, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), - CHAN5GHZ(116, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(120, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), - CHAN5GHZ(124, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(128, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), - CHAN5GHZ(132, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(136, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), - CHAN5GHZ(140, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS | - IEEE80211_CHAN_NO_HT40MINUS), - /* UNII-3 */ - CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(153, IEEE80211_CHAN_NO_HT40PLUS), - CHAN5GHZ(157, IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(161, IEEE80211_CHAN_NO_HT40PLUS), - CHAN5GHZ(165, IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS) -}; - -#define RATE(rate100m, _flags) { \ - .bitrate = (rate100m), \ - .flags = (_flags), \ - .hw_value = (rate100m / 5), \ -} - -static struct ieee80211_rate wl_legacy_ratetable[] = { - RATE(10, 0), - RATE(20, IEEE80211_RATE_SHORT_PREAMBLE), - RATE(55, IEEE80211_RATE_SHORT_PREAMBLE), - RATE(110, IEEE80211_RATE_SHORT_PREAMBLE), - RATE(60, 0), - RATE(90, 0), - RATE(120, 0), - RATE(180, 0), - RATE(240, 0), - RATE(360, 0), - RATE(480, 0), - RATE(540, 0), -}; - -static struct ieee80211_supported_band wl_band_2GHz_nphy = { - .band = IEEE80211_BAND_2GHZ, - .channels = wl_2ghz_chantable, - .n_channels = ARRAY_SIZE(wl_2ghz_chantable), - .bitrates = wl_legacy_ratetable, - .n_bitrates = ARRAY_SIZE(wl_legacy_ratetable), - .ht_cap = { - /* from include/linux/ieee80211.h */ - .cap = IEEE80211_HT_CAP_GRN_FLD | - IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, - .ht_supported = true, - .ampdu_factor = AMPDU_RX_FACTOR_64K, - .ampdu_density = AMPDU_DEF_MPDU_DENSITY, - .mcs = { - /* placeholders for now */ - .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0}, - .rx_highest = 500, - .tx_params = IEEE80211_HT_MCS_TX_DEFINED} - } -}; - -static struct ieee80211_supported_band wl_band_5GHz_nphy = { - .band = IEEE80211_BAND_5GHZ, - .channels = wl_5ghz_nphy_chantable, - .n_channels = ARRAY_SIZE(wl_5ghz_nphy_chantable), - .bitrates = wl_legacy_ratetable + 4, - .n_bitrates = ARRAY_SIZE(wl_legacy_ratetable) - 4, - .ht_cap = { - /* use IEEE80211_HT_CAP_* from include/linux/ieee80211.h */ - .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, /* No 40 mhz yet */ - .ht_supported = true, - .ampdu_factor = AMPDU_RX_FACTOR_64K, - .ampdu_density = AMPDU_DEF_MPDU_DENSITY, - .mcs = { - /* placeholders for now */ - .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0}, - .rx_highest = 500, - .tx_params = IEEE80211_HT_MCS_TX_DEFINED} - } -}; - -static int ieee_hw_rate_init(struct ieee80211_hw *hw) -{ - struct wl_info *wl = HW_TO_WL(hw); - int has_5g; - char phy_list[4]; - - has_5g = 0; - - hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL; - hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; - - if (wlc_get(wl->wlc, WLC_GET_PHYLIST, (int *)&phy_list) < 0) { - WL_ERROR("Phy list failed\n"); - } - WL_NONE("%s: phylist = %c\n", __func__, phy_list[0]); - - if (phy_list[0] == 'n' || phy_list[0] == 'c') { - if (phy_list[0] == 'c') { - /* Single stream */ - wl_band_2GHz_nphy.ht_cap.mcs.rx_mask[1] = 0; - wl_band_2GHz_nphy.ht_cap.mcs.rx_highest = 72; - } - hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl_band_2GHz_nphy; - } else { - BUG(); - return -1; - } - - /* Assume all bands use the same phy. True for 11n devices. */ - if (NBANDS_PUB(wl->pub) > 1) { - has_5g++; - if (phy_list[0] == 'n' || phy_list[0] == 'c') { - hw->wiphy->bands[IEEE80211_BAND_5GHZ] = - &wl_band_5GHz_nphy; - } else { - return -1; - } - } - - WL_NONE("%s: 2ghz = %d, 5ghz = %d\n", __func__, 1, has_5g); - - return 0; -} - -static int ieee_hw_init(struct ieee80211_hw *hw) -{ - hw->flags = IEEE80211_HW_SIGNAL_DBM - /* | IEEE80211_HW_CONNECTION_MONITOR What is this? */ - | IEEE80211_HW_REPORTS_TX_ACK_STATUS - | IEEE80211_HW_AMPDU_AGGREGATION; - - hw->extra_tx_headroom = wlc_get_header_len(); - /* FIXME: should get this from wlc->machwcap */ - hw->queues = 4; - /* FIXME: this doesn't seem to be used properly in minstrel_ht. - * mac80211/status.c:ieee80211_tx_status() checks this value, - * but mac80211/rc80211_minstrel_ht.c:minstrel_ht_get_rate() - * appears to always set 3 rates - */ - hw->max_rates = 2; /* Primary rate and 1 fallback rate */ - - hw->channel_change_time = 7 * 1000; /* channel change time is dependant on chip and band */ - hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); - - hw->rate_control_algorithm = "minstrel_ht"; - - hw->sta_data_size = sizeof(struct scb); - return ieee_hw_rate_init(hw); -} - -/** - * determines if a device is a WL device, and if so, attaches it. - * - * This function determines if a device pointed to by pdev is a WL device, - * and if so, performs a wl_attach() on it. - * - */ -int __devinit -wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - int rc; - struct wl_info *wl; - struct ieee80211_hw *hw; - u32 val; - - ASSERT(pdev); - - WL_TRACE("%s: bus %d slot %d func %d irq %d\n", - __func__, pdev->bus->number, PCI_SLOT(pdev->devfn), - PCI_FUNC(pdev->devfn), pdev->irq); - - if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) || - (((pdev->device & 0xff00) != 0x4300) && - ((pdev->device & 0xff00) != 0x4700) && - ((pdev->device < 43000) || (pdev->device > 43999)))) - return -ENODEV; - - rc = pci_enable_device(pdev); - if (rc) { - WL_ERROR("%s: Cannot enable device %d-%d_%d\n", - __func__, pdev->bus->number, PCI_SLOT(pdev->devfn), - PCI_FUNC(pdev->devfn)); - return -ENODEV; - } - pci_set_master(pdev); - - pci_read_config_dword(pdev, 0x40, &val); - if ((val & 0x0000ff00) != 0) - pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); - - hw = ieee80211_alloc_hw(sizeof(struct wl_info), &wl_ops); - if (!hw) { - WL_ERROR("%s: ieee80211_alloc_hw failed\n", __func__); - rc = -ENOMEM; - goto err_1; - } - - SET_IEEE80211_DEV(hw, &pdev->dev); - - pci_set_drvdata(pdev, hw); - - memset(hw->priv, 0, sizeof(*wl)); - - wl = wl_attach(pdev->vendor, pdev->device, pci_resource_start(pdev, 0), - PCI_BUS, pdev, pdev->irq); - - if (!wl) { - WL_ERROR("%s: %s: wl_attach failed!\n", - KBUILD_MODNAME, __func__); - return -ENODEV; - } - return 0; - err_1: - WL_ERROR("%s: err_1: Major hoarkage\n", __func__); - return 0; -} - -#ifdef LINUXSTA_PS -static int wl_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct wl_info *wl; - struct ieee80211_hw *hw; - - WL_TRACE("wl: wl_suspend\n"); - - hw = pci_get_drvdata(pdev); - wl = HW_TO_WL(hw); - if (!wl) { - WL_ERROR("wl: wl_suspend: pci_get_drvdata failed\n"); - return -ENODEV; - } - - WL_LOCK(wl); - wl_down(wl); - wl->pub->hw_up = false; - WL_UNLOCK(wl); - pci_save_state(pdev, wl->pci_psstate); - pci_disable_device(pdev); - return pci_set_power_state(pdev, PCI_D3hot); -} - -static int wl_resume(struct pci_dev *pdev) -{ - struct wl_info *wl; - struct ieee80211_hw *hw; - int err = 0; - u32 val; - - WL_TRACE("wl: wl_resume\n"); - hw = pci_get_drvdata(pdev); - wl = HW_TO_WL(hw); - if (!wl) { - WL_ERROR("wl: wl_resume: pci_get_drvdata failed\n"); - return -ENODEV; - } - - err = pci_set_power_state(pdev, PCI_D0); - if (err) - return err; - - pci_restore_state(pdev, wl->pci_psstate); - - err = pci_enable_device(pdev); - if (err) - return err; - - pci_set_master(pdev); - - pci_read_config_dword(pdev, 0x40, &val); - if ((val & 0x0000ff00) != 0) - pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); - - WL_LOCK(wl); - err = wl_up(wl); - WL_UNLOCK(wl); - - return err; -} -#endif /* LINUXSTA_PS */ - -static void wl_remove(struct pci_dev *pdev) -{ - struct wl_info *wl; - struct ieee80211_hw *hw; - - hw = pci_get_drvdata(pdev); - wl = HW_TO_WL(hw); - if (!wl) { - WL_ERROR("wl: wl_remove: pci_get_drvdata failed\n"); - return; - } - if (!wlc_chipmatch(pdev->vendor, pdev->device)) { - WL_ERROR("wl: wl_remove: wlc_chipmatch failed\n"); - return; - } - if (wl->wlc) { - ieee80211_unregister_hw(hw); - WL_LOCK(wl); - wl_down(wl); - WL_UNLOCK(wl); - WL_NONE("%s: Down\n", __func__); - } - pci_disable_device(pdev); - - wl_free(wl); - - pci_set_drvdata(pdev, NULL); - ieee80211_free_hw(hw); -} - -static struct pci_driver wl_pci_driver = { - .name = "brcm80211", - .probe = wl_pci_probe, -#ifdef LINUXSTA_PS - .suspend = wl_suspend, - .resume = wl_resume, -#endif /* LINUXSTA_PS */ - .remove = __devexit_p(wl_remove), - .id_table = wl_id_table, -}; - -/** - * This is the main entry point for the WL driver. - * - * This function determines if a device pointed to by pdev is a WL device, - * and if so, performs a wl_attach() on it. - * - */ -static int __init wl_module_init(void) -{ - int error = -ENODEV; - -#ifdef BCMDBG - if (msglevel != 0xdeadbeef) - wl_msg_level = msglevel; - else { - char *var = getvar(NULL, "wl_msglevel"); - if (var) - wl_msg_level = simple_strtoul(var, NULL, 0); - } - { - extern u32 phyhal_msg_level; - - if (phymsglevel != 0xdeadbeef) - phyhal_msg_level = phymsglevel; - else { - char *var = getvar(NULL, "phy_msglevel"); - if (var) - phyhal_msg_level = simple_strtoul(var, NULL, 0); - } - } -#endif /* BCMDBG */ - - error = pci_register_driver(&wl_pci_driver); - if (!error) - return 0; - - - - return error; -} - -/** - * This function unloads the WL driver from the system. - * - * This function unconditionally unloads the WL driver module from the - * system. - * - */ -static void __exit wl_module_exit(void) -{ - pci_unregister_driver(&wl_pci_driver); - -} - -module_init(wl_module_init); -module_exit(wl_module_exit); - -/** - * This function frees the WL per-device resources. - * - * This function frees resources owned by the WL device pointed to - * by the wl parameter. - * - */ -void wl_free(struct wl_info *wl) -{ - wl_timer_t *t, *next; - struct osl_info *osh; - - ASSERT(wl); - /* free ucode data */ - if (wl->fw.fw_cnt) - wl_ucode_data_free(); - if (wl->irq) - free_irq(wl->irq, wl); - - /* kill dpc */ - tasklet_kill(&wl->tasklet); - - if (wl->pub) { - wlc_module_unregister(wl->pub, "linux", wl); - } - - /* free common resources */ - if (wl->wlc) { - wlc_detach(wl->wlc); - wl->wlc = NULL; - wl->pub = NULL; - } - - /* virtual interface deletion is deferred so we cannot spinwait */ - - /* wait for all pending callbacks to complete */ - while (atomic_read(&wl->callbacks) > 0) - schedule(); - - /* free timers */ - for (t = wl->timers; t; t = next) { - next = t->next; -#ifdef BCMDBG - if (t->name) - kfree(t->name); -#endif - kfree(t); - } - - osh = wl->osh; - - /* - * unregister_netdev() calls get_stats() which may read chip registers - * so we cannot unmap the chip registers until after calling unregister_netdev() . - */ - if (wl->regsva && wl->bcm_bustype != SDIO_BUS && - wl->bcm_bustype != JTAG_BUS) { - iounmap((void *)wl->regsva); - } - wl->regsva = NULL; - - - osl_detach(osh); -} - -/* transmit a packet */ -static int BCMFASTPATH wl_start(struct sk_buff *skb, struct wl_info *wl) -{ - if (!wl) - return -ENETDOWN; - - return wl_start_int(wl, WL_TO_HW(wl), skb); -} - -static int BCMFASTPATH -wl_start_int(struct wl_info *wl, struct ieee80211_hw *hw, struct sk_buff *skb) -{ - wlc_sendpkt_mac80211(wl->wlc, skb, hw); - return NETDEV_TX_OK; -} - -void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, - int prio) -{ - WL_ERROR("Shouldn't be here %s\n", __func__); -} - -void wl_init(struct wl_info *wl) -{ - WL_TRACE("wl%d: wl_init\n", wl->pub->unit); - - wl_reset(wl); - - wlc_init(wl->wlc); -} - -uint wl_reset(struct wl_info *wl) -{ - WL_TRACE("wl%d: wl_reset\n", wl->pub->unit); - - wlc_reset(wl->wlc); - - /* dpc will not be rescheduled */ - wl->resched = 0; - - return 0; -} - -/* - * These are interrupt on/off entry points. Disable interrupts - * during interrupt state transition. - */ -void BCMFASTPATH wl_intrson(struct wl_info *wl) -{ - unsigned long flags; - - INT_LOCK(wl, flags); - wlc_intrson(wl->wlc); - INT_UNLOCK(wl, flags); -} - -bool wl_alloc_dma_resources(struct wl_info *wl, uint addrwidth) -{ - return true; -} - -u32 BCMFASTPATH wl_intrsoff(struct wl_info *wl) -{ - unsigned long flags; - u32 status; - - INT_LOCK(wl, flags); - status = wlc_intrsoff(wl->wlc); - INT_UNLOCK(wl, flags); - return status; -} - -void wl_intrsrestore(struct wl_info *wl, u32 macintmask) -{ - unsigned long flags; - - INT_LOCK(wl, flags); - wlc_intrsrestore(wl->wlc, macintmask); - INT_UNLOCK(wl, flags); -} - -int wl_up(struct wl_info *wl) -{ - int error = 0; - - if (wl->pub->up) - return 0; - - error = wlc_up(wl->wlc); - - return error; -} - -void wl_down(struct wl_info *wl) -{ - uint callbacks, ret_val = 0; - - /* call common down function */ - ret_val = wlc_down(wl->wlc); - callbacks = atomic_read(&wl->callbacks) - ret_val; - - /* wait for down callbacks to complete */ - WL_UNLOCK(wl); - - /* For HIGH_only driver, it's important to actually schedule other work, - * not just spin wait since everything runs at schedule level - */ - SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000); - - WL_LOCK(wl); -} - -irqreturn_t BCMFASTPATH wl_isr(int irq, void *dev_id) -{ - struct wl_info *wl; - bool ours, wantdpc; - unsigned long flags; - - wl = (struct wl_info *) dev_id; - - WL_ISRLOCK(wl, flags); - - /* call common first level interrupt handler */ - ours = wlc_isr(wl->wlc, &wantdpc); - if (ours) { - /* if more to do... */ - if (wantdpc) { - - /* ...and call the second level interrupt handler */ - /* schedule dpc */ - ASSERT(wl->resched == false); - tasklet_schedule(&wl->tasklet); - } - } - - WL_ISRUNLOCK(wl, flags); - - return IRQ_RETVAL(ours); -} - -static void BCMFASTPATH wl_dpc(unsigned long data) -{ - struct wl_info *wl; - - wl = (struct wl_info *) data; - - WL_LOCK(wl); - - /* call the common second level interrupt handler */ - if (wl->pub->up) { - if (wl->resched) { - unsigned long flags; - - INT_LOCK(wl, flags); - wlc_intrsupd(wl->wlc); - INT_UNLOCK(wl, flags); - } - - wl->resched = wlc_dpc(wl->wlc, true); - } - - /* wlc_dpc() may bring the driver down */ - if (!wl->pub->up) - goto done; - - /* re-schedule dpc */ - if (wl->resched) - tasklet_schedule(&wl->tasklet); - else { - /* re-enable interrupts */ - wl_intrson(wl); - } - - done: - WL_UNLOCK(wl); -} - -static void wl_link_up(struct wl_info *wl, char *ifname) -{ - WL_ERROR("wl%d: link up (%s)\n", wl->pub->unit, ifname); -} - -static void wl_link_down(struct wl_info *wl, char *ifname) -{ - WL_ERROR("wl%d: link down (%s)\n", wl->pub->unit, ifname); -} - -void wl_event(struct wl_info *wl, char *ifname, wlc_event_t *e) -{ - - switch (e->event.event_type) { - case WLC_E_LINK: - case WLC_E_NDIS_LINK: - if (e->event.flags & WLC_EVENT_MSG_LINK) - wl_link_up(wl, ifname); - else - wl_link_down(wl, ifname); - break; - case WLC_E_RADIO: - break; - } -} - -static void wl_timer(unsigned long data) -{ - _wl_timer((wl_timer_t *) data); -} - -static void _wl_timer(wl_timer_t *t) -{ - WL_LOCK(t->wl); - - if (t->set) { - if (t->periodic) { - t->timer.expires = jiffies + t->ms * HZ / 1000; - atomic_inc(&t->wl->callbacks); - add_timer(&t->timer); - t->set = true; - } else - t->set = false; - - t->fn(t->arg); - } - - atomic_dec(&t->wl->callbacks); - - WL_UNLOCK(t->wl); -} - -wl_timer_t *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg), void *arg, - const char *name) -{ - wl_timer_t *t; - - t = kmalloc(sizeof(wl_timer_t), GFP_ATOMIC); - if (!t) { - WL_ERROR("wl%d: wl_init_timer: out of memory\n", wl->pub->unit); - return 0; - } - - memset(t, 0, sizeof(wl_timer_t)); - - init_timer(&t->timer); - t->timer.data = (unsigned long) t; - t->timer.function = wl_timer; - t->wl = wl; - t->fn = fn; - t->arg = arg; - t->next = wl->timers; - wl->timers = t; - -#ifdef BCMDBG - t->name = kmalloc(strlen(name) + 1, GFP_ATOMIC); - if (t->name) - strcpy(t->name, name); -#endif - - return t; -} - -/* BMAC_NOTE: Add timer adds only the kernel timer since it's going to be more accurate - * as well as it's easier to make it periodic - */ -void wl_add_timer(struct wl_info *wl, wl_timer_t *t, uint ms, int periodic) -{ -#ifdef BCMDBG - if (t->set) { - WL_ERROR("%s: Already set. Name: %s, per %d\n", - __func__, t->name, periodic); - } -#endif - ASSERT(!t->set); - - t->ms = ms; - t->periodic = (bool) periodic; - t->set = true; - t->timer.expires = jiffies + ms * HZ / 1000; - - atomic_inc(&wl->callbacks); - add_timer(&t->timer); -} - -/* return true if timer successfully deleted, false if still pending */ -bool wl_del_timer(struct wl_info *wl, wl_timer_t *t) -{ - if (t->set) { - t->set = false; - if (!del_timer(&t->timer)) { - return false; - } - atomic_dec(&wl->callbacks); - } - - return true; -} - -void wl_free_timer(struct wl_info *wl, wl_timer_t *t) -{ - wl_timer_t *tmp; - - /* delete the timer in case it is active */ - wl_del_timer(wl, t); - - if (wl->timers == t) { - wl->timers = wl->timers->next; -#ifdef BCMDBG - if (t->name) - kfree(t->name); -#endif - kfree(t); - return; - - } - - tmp = wl->timers; - while (tmp) { - if (tmp->next == t) { - tmp->next = t->next; -#ifdef BCMDBG - if (t->name) - kfree(t->name); -#endif - kfree(t); - return; - } - tmp = tmp->next; - } - -} - -static int wl_linux_watchdog(void *ctx) -{ - struct wl_info *wl = (struct wl_info *) ctx; - struct net_device_stats *stats = NULL; - uint id; - /* refresh stats */ - if (wl->pub->up) { - ASSERT(wl->stats_id < 2); - - id = 1 - wl->stats_id; - - stats = &wl->stats_watchdog[id]; - stats->rx_packets = WLCNTVAL(wl->pub->_cnt->rxframe); - stats->tx_packets = WLCNTVAL(wl->pub->_cnt->txframe); - stats->rx_bytes = WLCNTVAL(wl->pub->_cnt->rxbyte); - stats->tx_bytes = WLCNTVAL(wl->pub->_cnt->txbyte); - stats->rx_errors = WLCNTVAL(wl->pub->_cnt->rxerror); - stats->tx_errors = WLCNTVAL(wl->pub->_cnt->txerror); - stats->collisions = 0; - - stats->rx_length_errors = 0; - stats->rx_over_errors = WLCNTVAL(wl->pub->_cnt->rxoflo); - stats->rx_crc_errors = WLCNTVAL(wl->pub->_cnt->rxcrc); - stats->rx_frame_errors = 0; - stats->rx_fifo_errors = WLCNTVAL(wl->pub->_cnt->rxoflo); - stats->rx_missed_errors = 0; - - stats->tx_fifo_errors = WLCNTVAL(wl->pub->_cnt->txuflo); - - wl->stats_id = id; - - } - - return 0; -} - -struct wl_fw_hdr { - u32 offset; - u32 len; - u32 idx; -}; - -char *wl_firmwares[WL_MAX_FW] = { - "brcm/bcm43xx", - NULL -}; - -int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx) -{ - int i, entry; - const u8 *pdata; - struct wl_fw_hdr *hdr; - for (i = 0; i < wl->fw.fw_cnt; i++) { - hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data; - for (entry = 0; entry < wl->fw.hdr_num_entries[i]; - entry++, hdr++) { - if (hdr->idx == idx) { - pdata = wl->fw.fw_bin[i]->data + hdr->offset; - *pbuf = kmalloc(hdr->len, GFP_ATOMIC); - if (*pbuf == NULL) { - printf("fail to alloc %d bytes\n", - hdr->len); - } - bcopy(pdata, *pbuf, hdr->len); - return 0; - } - } - } - printf("ERROR: ucode buf tag:%d can not be found!\n", idx); - *pbuf = NULL; - return -1; -} - -int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx) -{ - int i, entry; - const u8 *pdata; - struct wl_fw_hdr *hdr; - for (i = 0; i < wl->fw.fw_cnt; i++) { - hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data; - for (entry = 0; entry < wl->fw.hdr_num_entries[i]; - entry++, hdr++) { - if (hdr->idx == idx) { - pdata = wl->fw.fw_bin[i]->data + hdr->offset; - ASSERT(hdr->len == 4); - *data = *((u32 *) pdata); - return 0; - } - } - } - printf("ERROR: ucode tag:%d can not be found!\n", idx); - return -1; -} - -static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) -{ - int status; - struct device *device = &pdev->dev; - char fw_name[100]; - int i; - - memset((void *)&wl->fw, 0, sizeof(struct wl_firmware)); - for (i = 0; i < WL_MAX_FW; i++) { - if (wl_firmwares[i] == NULL) - break; - sprintf(fw_name, "%s-%d.fw", wl_firmwares[i], - UCODE_LOADER_API_VER); - WL_NONE("request fw %s\n", fw_name); - status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); - if (status) { - printf("%s: fail to load firmware %s\n", - KBUILD_MODNAME, fw_name); - wl_release_fw(wl); - return status; - } - WL_NONE("request fw %s\n", fw_name); - sprintf(fw_name, "%s_hdr-%d.fw", wl_firmwares[i], - UCODE_LOADER_API_VER); - status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); - if (status) { - printf("%s: fail to load firmware %s\n", - KBUILD_MODNAME, fw_name); - wl_release_fw(wl); - return status; - } - wl->fw.hdr_num_entries[i] = - wl->fw.fw_hdr[i]->size / (sizeof(struct wl_fw_hdr)); - WL_NONE("request fw %s find: %d entries\n", - fw_name, wl->fw.hdr_num_entries[i]); - } - wl->fw.fw_cnt = i; - return wl_ucode_data_init(wl); -} - -void wl_ucode_free_buf(void *p) -{ - kfree(p); -} - -static void wl_release_fw(struct wl_info *wl) -{ - int i; - for (i = 0; i < WL_MAX_FW; i++) { - release_firmware(wl->fw.fw_bin[i]); - release_firmware(wl->fw.fw_hdr[i]); - } -} - - -/* - * checks validity of all firmware images loaded from user space - */ -int wl_check_firmwares(struct wl_info *wl) -{ - int i; - int entry; - int rc = 0; - const struct firmware *fw; - const struct firmware *fw_hdr; - struct wl_fw_hdr *ucode_hdr; - for (i = 0; i < WL_MAX_FW && rc == 0; i++) { - fw = wl->fw.fw_bin[i]; - fw_hdr = wl->fw.fw_hdr[i]; - if (fw == NULL && fw_hdr == NULL) { - break; - } else if (fw == NULL || fw_hdr == NULL) { - WL_ERROR("%s: invalid bin/hdr fw\n", __func__); - rc = -EBADF; - } else if (fw_hdr->size % sizeof(struct wl_fw_hdr)) { - WL_ERROR("%s: non integral fw hdr file size %d/%zu\n", - __func__, fw_hdr->size, - sizeof(struct wl_fw_hdr)); - rc = -EBADF; - } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) { - WL_ERROR("%s: out of bounds fw file size %d\n", - __func__, fw->size); - rc = -EBADF; - } else { - /* check if ucode section overruns firmware image */ - ucode_hdr = (struct wl_fw_hdr *)fw_hdr->data; - for (entry = 0; entry < wl->fw.hdr_num_entries[i] && rc; - entry++, ucode_hdr++) { - if (ucode_hdr->offset + ucode_hdr->len > - fw->size) { - WL_ERROR("%s: conflicting bin/hdr\n", - __func__); - rc = -EBADF; - } - } - } - } - if (rc == 0 && wl->fw.fw_cnt != i) { - WL_ERROR("%s: invalid fw_cnt=%d\n", __func__, wl->fw.fw_cnt); - rc = -EBADF; - } - return rc; -} - diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.h b/drivers/staging/brcm80211/sys/wl_mac80211.h deleted file mode 100644 index bb39b7705947..000000000000 --- a/drivers/staging/brcm80211/sys/wl_mac80211.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wl_mac80211_h_ -#define _wl_mac80211_h_ - -#include - -/* BMAC Note: High-only driver is no longer working in softirq context as it needs to block and - * sleep so perimeter lock has to be a semaphore instead of spinlock. This requires timers to be - * submitted to workqueue instead of being on kernel timer - */ -typedef struct wl_timer { - struct timer_list timer; - struct wl_info *wl; - void (*fn) (void *); - void *arg; /* argument to fn */ - uint ms; - bool periodic; - bool set; - struct wl_timer *next; -#ifdef BCMDBG - char *name; /* Description of the timer */ -#endif -} wl_timer_t; - -/* contortion to call functions at safe time */ -/* In 2.6.20 kernels work functions get passed a pointer to the struct work, so things - * will continue to work as long as the work structure is the first component of the task structure. - */ -typedef struct wl_task { - struct work_struct work; - void *context; -} wl_task_t; - -struct wl_if { - uint subunit; /* WDS/BSS unit */ - struct pci_dev *pci_dev; -}; - -#define WL_MAX_FW 4 -struct wl_firmware { - u32 fw_cnt; - const struct firmware *fw_bin[WL_MAX_FW]; - const struct firmware *fw_hdr[WL_MAX_FW]; - u32 hdr_num_entries[WL_MAX_FW]; -}; - -struct wl_info { - struct wlc_pub *pub; /* pointer to public wlc state */ - void *wlc; /* pointer to private common os-independent data */ - struct osl_info *osh; /* pointer to os handler */ - u32 magic; - - int irq; - - spinlock_t lock; /* per-device perimeter lock */ - spinlock_t isr_lock; /* per-device ISR synchronization lock */ - uint bcm_bustype; /* bus type */ - bool piomode; /* set from insmod argument */ - void *regsva; /* opaque chip registers virtual address */ - atomic_t callbacks; /* # outstanding callback functions */ - struct wl_timer *timers; /* timer cleanup queue */ - struct tasklet_struct tasklet; /* dpc tasklet */ - bool resched; /* dpc needs to be and is rescheduled */ -#ifdef LINUXSTA_PS - u32 pci_psstate[16]; /* pci ps-state save/restore */ -#endif - /* RPC, handle, lock, txq, workitem */ - uint stats_id; /* the current set of stats */ - /* ping-pong stats counters updated by Linux watchdog */ - struct net_device_stats stats_watchdog[2]; - struct wl_firmware fw; -}; - -#define WL_LOCK(wl) spin_lock_bh(&(wl)->lock) -#define WL_UNLOCK(wl) spin_unlock_bh(&(wl)->lock) - -/* locking from inside wl_isr */ -#define WL_ISRLOCK(wl, flags) do {spin_lock(&(wl)->isr_lock); (void)(flags); } while (0) -#define WL_ISRUNLOCK(wl, flags) do {spin_unlock(&(wl)->isr_lock); (void)(flags); } while (0) - -/* locking under WL_LOCK() to synchronize with wl_isr */ -#define INT_LOCK(wl, flags) spin_lock_irqsave(&(wl)->isr_lock, flags) -#define INT_UNLOCK(wl, flags) spin_unlock_irqrestore(&(wl)->isr_lock, flags) - -#ifndef PCI_D0 -#define PCI_D0 0 -#endif - -#ifndef PCI_D3hot -#define PCI_D3hot 3 -#endif - -/* exported functions */ - -extern irqreturn_t wl_isr(int irq, void *dev_id); - -extern int __devinit wl_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent); -extern void wl_free(struct wl_info *wl); -extern int wl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); - -#endif /* _wl_mac80211_h_ */ diff --git a/drivers/staging/brcm80211/sys/wl_ucode.h b/drivers/staging/brcm80211/sys/wl_ucode.h deleted file mode 100644 index 2a0f4028f6f3..000000000000 --- a/drivers/staging/brcm80211/sys/wl_ucode.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define MIN_FW_SIZE 40000 /* minimum firmware file size in bytes */ -#define MAX_FW_SIZE 150000 - -typedef struct d11init { - u16 addr; - u16 size; - u32 value; -} d11init_t; - -extern d11init_t *d11lcn0bsinitvals24; -extern d11init_t *d11lcn0initvals24; -extern d11init_t *d11lcn1bsinitvals24; -extern d11init_t *d11lcn1initvals24; -extern d11init_t *d11lcn2bsinitvals24; -extern d11init_t *d11lcn2initvals24; -extern d11init_t *d11n0absinitvals16; -extern d11init_t *d11n0bsinitvals16; -extern d11init_t *d11n0initvals16; -extern u32 *bcm43xx_16_mimo; -extern u32 bcm43xx_16_mimosz; -extern u32 *bcm43xx_24_lcn; -extern u32 bcm43xx_24_lcnsz; -extern u32 *bcm43xx_bommajor; -extern u32 *bcm43xx_bomminor; - -extern int wl_ucode_data_init(struct wl_info *wl); -extern void wl_ucode_data_free(void); - -extern int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, unsigned int idx); -extern int wl_ucode_init_uint(struct wl_info *wl, unsigned *data, - unsigned int idx); -extern void wl_ucode_free_buf(void *); -extern int wl_check_firmwares(struct wl_info *wl); diff --git a/drivers/staging/brcm80211/sys/wl_ucode_loader.c b/drivers/staging/brcm80211/sys/wl_ucode_loader.c deleted file mode 100644 index 23e10f3dec0d..000000000000 --- a/drivers/staging/brcm80211/sys/wl_ucode_loader.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include - - - -d11init_t *d11lcn0bsinitvals24; -d11init_t *d11lcn0initvals24; -d11init_t *d11lcn1bsinitvals24; -d11init_t *d11lcn1initvals24; -d11init_t *d11lcn2bsinitvals24; -d11init_t *d11lcn2initvals24; -d11init_t *d11n0absinitvals16; -d11init_t *d11n0bsinitvals16; -d11init_t *d11n0initvals16; -u32 *bcm43xx_16_mimo; -u32 bcm43xx_16_mimosz; -u32 *bcm43xx_24_lcn; -u32 bcm43xx_24_lcnsz; -u32 *bcm43xx_bommajor; -u32 *bcm43xx_bomminor; - -int wl_ucode_data_init(struct wl_info *wl) -{ - int rc; - rc = wl_check_firmwares(wl); - if (rc < 0) - return rc; - wl_ucode_init_buf(wl, (void **)&d11lcn0bsinitvals24, - D11LCN0BSINITVALS24); - wl_ucode_init_buf(wl, (void **)&d11lcn0initvals24, D11LCN0INITVALS24); - wl_ucode_init_buf(wl, (void **)&d11lcn1bsinitvals24, - D11LCN1BSINITVALS24); - wl_ucode_init_buf(wl, (void **)&d11lcn1initvals24, D11LCN1INITVALS24); - wl_ucode_init_buf(wl, (void **)&d11lcn2bsinitvals24, - D11LCN2BSINITVALS24); - wl_ucode_init_buf(wl, (void **)&d11lcn2initvals24, D11LCN2INITVALS24); - wl_ucode_init_buf(wl, (void **)&d11n0absinitvals16, D11N0ABSINITVALS16); - wl_ucode_init_buf(wl, (void **)&d11n0bsinitvals16, D11N0BSINITVALS16); - wl_ucode_init_buf(wl, (void **)&d11n0initvals16, D11N0INITVALS16); - wl_ucode_init_buf(wl, (void **)&bcm43xx_16_mimo, - D11UCODE_OVERSIGHT16_MIMO); - wl_ucode_init_uint(wl, &bcm43xx_16_mimosz, D11UCODE_OVERSIGHT16_MIMOSZ); - wl_ucode_init_buf(wl, (void **)&bcm43xx_24_lcn, - D11UCODE_OVERSIGHT24_LCN); - wl_ucode_init_uint(wl, &bcm43xx_24_lcnsz, D11UCODE_OVERSIGHT24_LCNSZ); - wl_ucode_init_buf(wl, (void **)&bcm43xx_bommajor, - D11UCODE_OVERSIGHT_BOMMAJOR); - wl_ucode_init_buf(wl, (void **)&bcm43xx_bomminor, - D11UCODE_OVERSIGHT_BOMMINOR); - - return 0; -} - -void wl_ucode_data_free(void) -{ - wl_ucode_free_buf((void *)d11lcn0bsinitvals24); - wl_ucode_free_buf((void *)d11lcn0initvals24); - wl_ucode_free_buf((void *)d11lcn1bsinitvals24); - wl_ucode_free_buf((void *)d11lcn1initvals24); - wl_ucode_free_buf((void *)d11lcn2bsinitvals24); - wl_ucode_free_buf((void *)d11lcn2initvals24); - wl_ucode_free_buf((void *)d11n0absinitvals16); - wl_ucode_free_buf((void *)d11n0bsinitvals16); - wl_ucode_free_buf((void *)d11n0initvals16); - wl_ucode_free_buf((void *)bcm43xx_16_mimo); - wl_ucode_free_buf((void *)bcm43xx_24_lcn); - wl_ucode_free_buf((void *)bcm43xx_bommajor); - wl_ucode_free_buf((void *)bcm43xx_bomminor); - - return; -} diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.c b/drivers/staging/brcm80211/sys/wlc_alloc.c deleted file mode 100644 index 7a9fdbb5daee..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_alloc.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, - uint *err, uint devid); -static void wlc_pub_mfree(struct osl_info *osh, struct wlc_pub *pub); -static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid); - -void *wlc_calloc(struct osl_info *osh, uint unit, uint size) -{ - void *item; - - item = kzalloc(size, GFP_ATOMIC); - if (item == NULL) - WL_ERROR("wl%d: %s: out of memory\n", unit, __func__); - return item; -} - -void wlc_tunables_init(wlc_tunables_t *tunables, uint devid) -{ - tunables->ntxd = NTXD; - tunables->nrxd = NRXD; - tunables->rxbufsz = RXBUFSZ; - tunables->nrxbufpost = NRXBUFPOST; - tunables->maxscb = MAXSCB; - tunables->ampdunummpdu = AMPDU_NUM_MPDU; - tunables->maxpktcb = MAXPKTCB; - tunables->maxucodebss = WLC_MAX_UCODE_BSS; - tunables->maxucodebss4 = WLC_MAX_UCODE_BSS4; - tunables->maxbss = MAXBSS; - tunables->datahiwat = WLC_DATAHIWAT; - tunables->ampdudatahiwat = WLC_AMPDUDATAHIWAT; - tunables->rxbnd = RXBND; - tunables->txsbnd = TXSBND; -} - -static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, - uint *err, uint devid) -{ - struct wlc_pub *pub; - - pub = (struct wlc_pub *) wlc_calloc(osh, unit, sizeof(struct wlc_pub)); - if (pub == NULL) { - *err = 1001; - goto fail; - } - - pub->tunables = (wlc_tunables_t *)wlc_calloc(osh, unit, - sizeof(wlc_tunables_t)); - if (pub->tunables == NULL) { - *err = 1028; - goto fail; - } - - /* need to init the tunables now */ - wlc_tunables_init(pub->tunables, devid); - - pub->multicast = (u8 *)wlc_calloc(osh, unit, - (ETH_ALEN * MAXMULTILIST)); - if (pub->multicast == NULL) { - *err = 1003; - goto fail; - } - - return pub; - - fail: - wlc_pub_mfree(osh, pub); - return NULL; -} - -static void wlc_pub_mfree(struct osl_info *osh, struct wlc_pub *pub) -{ - if (pub == NULL) - return; - - if (pub->multicast) - kfree(pub->multicast); - if (pub->tunables) { - kfree(pub->tunables); - pub->tunables = NULL; - } - - kfree(pub); -} - -wlc_bsscfg_t *wlc_bsscfg_malloc(struct osl_info *osh, uint unit) -{ - wlc_bsscfg_t *cfg; - - cfg = (wlc_bsscfg_t *) wlc_calloc(osh, unit, sizeof(wlc_bsscfg_t)); - if (cfg == NULL) - goto fail; - - cfg->current_bss = (wlc_bss_info_t *)wlc_calloc(osh, unit, - sizeof(wlc_bss_info_t)); - if (cfg->current_bss == NULL) - goto fail; - - return cfg; - - fail: - wlc_bsscfg_mfree(osh, cfg); - return NULL; -} - -void wlc_bsscfg_mfree(struct osl_info *osh, wlc_bsscfg_t *cfg) -{ - if (cfg == NULL) - return; - - if (cfg->maclist) { - kfree(cfg->maclist); - cfg->maclist = NULL; - } - - if (cfg->current_bss != NULL) { - wlc_bss_info_t *current_bss = cfg->current_bss; - kfree(current_bss); - cfg->current_bss = NULL; - } - - kfree(cfg); -} - -void wlc_bsscfg_ID_assign(struct wlc_info *wlc, wlc_bsscfg_t *bsscfg) -{ - bsscfg->ID = wlc->next_bsscfg_ID; - wlc->next_bsscfg_ID++; -} - -/* - * The common driver entry routine. Error codes should be unique - */ -struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, - uint devid) -{ - struct wlc_info *wlc; - - wlc = (struct wlc_info *) wlc_calloc(osh, unit, - sizeof(struct wlc_info)); - if (wlc == NULL) { - *err = 1002; - goto fail; - } - - wlc->hwrxoff = WL_HWRXOFF; - - /* allocate struct wlc_pub state structure */ - wlc->pub = wlc_pub_malloc(osh, unit, err, devid); - if (wlc->pub == NULL) { - *err = 1003; - goto fail; - } - wlc->pub->wlc = wlc; - - /* allocate struct wlc_hw_info state structure */ - - wlc->hw = (struct wlc_hw_info *)wlc_calloc(osh, unit, - sizeof(struct wlc_hw_info)); - if (wlc->hw == NULL) { - *err = 1005; - goto fail; - } - wlc->hw->wlc = wlc; - - wlc->hw->bandstate[0] = (wlc_hwband_t *)wlc_calloc(osh, unit, - (sizeof(wlc_hwband_t) * MAXBANDS)); - if (wlc->hw->bandstate[0] == NULL) { - *err = 1006; - goto fail; - } else { - int i; - - for (i = 1; i < MAXBANDS; i++) { - wlc->hw->bandstate[i] = (wlc_hwband_t *) - ((unsigned long)wlc->hw->bandstate[0] + - (sizeof(wlc_hwband_t) * i)); - } - } - - wlc->modulecb = (modulecb_t *)wlc_calloc(osh, unit, - sizeof(modulecb_t) * WLC_MAXMODULES); - if (wlc->modulecb == NULL) { - *err = 1009; - goto fail; - } - - wlc->default_bss = (wlc_bss_info_t *)wlc_calloc(osh, unit, - sizeof(wlc_bss_info_t)); - if (wlc->default_bss == NULL) { - *err = 1010; - goto fail; - } - - wlc->cfg = wlc_bsscfg_malloc(osh, unit); - if (wlc->cfg == NULL) { - *err = 1011; - goto fail; - } - wlc_bsscfg_ID_assign(wlc, wlc->cfg); - - wlc->pkt_callback = (pkt_cb_t *)wlc_calloc(osh, unit, - (sizeof(pkt_cb_t) * (wlc->pub->tunables->maxpktcb + 1))); - if (wlc->pkt_callback == NULL) { - *err = 1013; - goto fail; - } - - wlc->wsec_def_keys[0] = (wsec_key_t *)wlc_calloc(osh, unit, - (sizeof(wsec_key_t) * WLC_DEFAULT_KEYS)); - if (wlc->wsec_def_keys[0] == NULL) { - *err = 1015; - goto fail; - } else { - int i; - for (i = 1; i < WLC_DEFAULT_KEYS; i++) { - wlc->wsec_def_keys[i] = (wsec_key_t *) - ((unsigned long)wlc->wsec_def_keys[0] + - (sizeof(wsec_key_t) * i)); - } - } - - wlc->protection = (wlc_protection_t *)wlc_calloc(osh, unit, - sizeof(wlc_protection_t)); - if (wlc->protection == NULL) { - *err = 1016; - goto fail; - } - - wlc->stf = (wlc_stf_t *)wlc_calloc(osh, unit, sizeof(wlc_stf_t)); - if (wlc->stf == NULL) { - *err = 1017; - goto fail; - } - - wlc->bandstate[0] = (struct wlcband *)wlc_calloc(osh, unit, - (sizeof(struct wlcband)*MAXBANDS)); - if (wlc->bandstate[0] == NULL) { - *err = 1025; - goto fail; - } else { - int i; - - for (i = 1; i < MAXBANDS; i++) { - wlc->bandstate[i] = - (struct wlcband *) ((unsigned long)wlc->bandstate[0] - + (sizeof(struct wlcband)*i)); - } - } - - wlc->corestate = (struct wlccore *)wlc_calloc(osh, unit, - sizeof(struct wlccore)); - if (wlc->corestate == NULL) { - *err = 1026; - goto fail; - } - - wlc->corestate->macstat_snapshot = - (macstat_t *)wlc_calloc(osh, unit, sizeof(macstat_t)); - if (wlc->corestate->macstat_snapshot == NULL) { - *err = 1027; - goto fail; - } - - return wlc; - - fail: - wlc_detach_mfree(wlc, osh); - return NULL; -} - -void wlc_detach_mfree(struct wlc_info *wlc, struct osl_info *osh) -{ - if (wlc == NULL) - return; - - if (wlc->modulecb) { - kfree(wlc->modulecb); - wlc->modulecb = NULL; - } - - if (wlc->default_bss) { - kfree(wlc->default_bss); - wlc->default_bss = NULL; - } - if (wlc->cfg) { - wlc_bsscfg_mfree(osh, wlc->cfg); - wlc->cfg = NULL; - } - - if (wlc->pkt_callback && wlc->pub && wlc->pub->tunables) { - kfree(wlc->pkt_callback); - wlc->pkt_callback = NULL; - } - - if (wlc->wsec_def_keys[0]) - kfree(wlc->wsec_def_keys[0]); - if (wlc->protection) { - kfree(wlc->protection); - wlc->protection = NULL; - } - - if (wlc->stf) { - kfree(wlc->stf); - wlc->stf = NULL; - } - - if (wlc->bandstate[0]) - kfree(wlc->bandstate[0]); - - if (wlc->corestate) { - if (wlc->corestate->macstat_snapshot) { - kfree(wlc->corestate->macstat_snapshot); wlc->corestate->macstat_snapshot = NULL; - } - kfree(wlc->corestate); - wlc->corestate = NULL; - } - - if (wlc->pub) { - /* free pub struct */ - wlc_pub_mfree(osh, wlc->pub); - wlc->pub = NULL; - } - - if (wlc->hw) { - if (wlc->hw->bandstate[0]) { - kfree(wlc->hw->bandstate[0]); - wlc->hw->bandstate[0] = NULL; - } - - /* free hw struct */ - kfree(wlc->hw); - wlc->hw = NULL; - } - - /* free the wlc */ - kfree(wlc); - wlc = NULL; -} diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.h b/drivers/staging/brcm80211/sys/wlc_alloc.h deleted file mode 100644 index ac34f782b400..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_alloc.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -extern void *wlc_calloc(struct osl_info *osh, uint unit, uint size); - -extern struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, - uint *err, uint devid); -extern void wlc_detach_mfree(struct wlc_info *wlc, struct osl_info *osh); - -struct wlc_bsscfg; -extern struct wlc_bsscfg *wlc_bsscfg_malloc(struct osl_info *osh, uint unit); -extern void wlc_bsscfg_mfree(struct osl_info *osh, struct wlc_bsscfg *cfg); diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c deleted file mode 100644 index 8e1011203481..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.c +++ /dev/null @@ -1,1356 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define AMPDU_MAX_MPDU 32 /* max number of mpdus in an ampdu */ -#define AMPDU_NUM_MPDU_LEGACY 16 /* max number of mpdus in an ampdu to a legacy */ -#define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */ -#define AMPDU_TX_BA_DEF_WSIZE 64 /* default Tx ba window size (in pdu) */ -#define AMPDU_RX_BA_DEF_WSIZE 64 /* max Rx ba window size (in pdu) */ -#define AMPDU_RX_BA_MAX_WSIZE 64 /* default Rx ba window size (in pdu) */ -#define AMPDU_MAX_DUR 5 /* max dur of tx ampdu (in msec) */ -#define AMPDU_DEF_RETRY_LIMIT 5 /* default tx retry limit */ -#define AMPDU_DEF_RR_RETRY_LIMIT 2 /* default tx retry limit at reg rate */ -#define AMPDU_DEF_TXPKT_WEIGHT 2 /* default weight of ampdu in txfifo */ -#define AMPDU_DEF_FFPLD_RSVD 2048 /* default ffpld reserved bytes */ -#define AMPDU_INI_FREE 10 /* # of inis to be freed on detach */ -#define AMPDU_SCB_MAX_RELEASE 20 /* max # of mpdus released at a time */ - -#define NUM_FFPLD_FIFO 4 /* number of fifo concerned by pre-loading */ -#define FFPLD_TX_MAX_UNFL 200 /* default value of the average number of ampdu - * without underflows - */ -#define FFPLD_MPDU_SIZE 1800 /* estimate of maximum mpdu size */ -#define FFPLD_MAX_MCS 23 /* we don't deal with mcs 32 */ -#define FFPLD_PLD_INCR 1000 /* increments in bytes */ -#define FFPLD_MAX_AMPDU_CNT 5000 /* maximum number of ampdu we - * accumulate between resets. - */ - -#define TX_SEQ_TO_INDEX(seq) ((seq) % AMPDU_TX_BA_MAX_WSIZE) - -/* max possible overhead per mpdu in the ampdu; 3 is for roundup if needed */ -#define AMPDU_MAX_MPDU_OVERHEAD (FCS_LEN + DOT11_ICV_AES_LEN +\ - AMPDU_DELIMITER_LEN + 3\ - + DOT11_A4_HDR_LEN + DOT11_QOS_LEN + DOT11_IV_MAX_LEN) - -#ifdef BCMDBG -u32 wl_ampdu_dbg = - WL_AMPDU_UPDN_VAL | - WL_AMPDU_ERR_VAL | - WL_AMPDU_TX_VAL | - WL_AMPDU_RX_VAL | - WL_AMPDU_CTL_VAL | - WL_AMPDU_HW_VAL | WL_AMPDU_HWTXS_VAL | WL_AMPDU_HWDBG_VAL; -#endif - -/* structure to hold tx fifo information and pre-loading state - * counters specific to tx underflows of ampdus - * some counters might be redundant with the ones in wlc or ampdu structures. - * This allows to maintain a specific state independantly of - * how often and/or when the wlc counters are updated. - */ -typedef struct wlc_fifo_info { - u16 ampdu_pld_size; /* number of bytes to be pre-loaded */ - u8 mcs2ampdu_table[FFPLD_MAX_MCS + 1]; /* per-mcs max # of mpdus in an ampdu */ - u16 prev_txfunfl; /* num of underflows last read from the HW macstats counter */ - u32 accum_txfunfl; /* num of underflows since we modified pld params */ - u32 accum_txampdu; /* num of tx ampdu since we modified pld params */ - u32 prev_txampdu; /* previous reading of tx ampdu */ - u32 dmaxferrate; /* estimated dma avg xfer rate in kbits/sec */ -} wlc_fifo_info_t; - -/* AMPDU module specific state */ -struct ampdu_info { - struct wlc_info *wlc; /* pointer to main wlc structure */ - int scb_handle; /* scb cubby handle to retrieve data from scb */ - u8 ini_enable[AMPDU_MAX_SCB_TID]; /* per-tid initiator enable/disable of ampdu */ - u8 ba_tx_wsize; /* Tx ba window size (in pdu) */ - u8 ba_rx_wsize; /* Rx ba window size (in pdu) */ - u8 retry_limit; /* mpdu transmit retry limit */ - u8 rr_retry_limit; /* mpdu transmit retry limit at regular rate */ - u8 retry_limit_tid[AMPDU_MAX_SCB_TID]; /* per-tid mpdu transmit retry limit */ - /* per-tid mpdu transmit retry limit at regular rate */ - u8 rr_retry_limit_tid[AMPDU_MAX_SCB_TID]; - u8 mpdu_density; /* min mpdu spacing (0-7) ==> 2^(x-1)/8 usec */ - s8 max_pdu; /* max pdus allowed in ampdu */ - u8 dur; /* max duration of an ampdu (in msec) */ - u8 txpkt_weight; /* weight of ampdu in txfifo; reduces rate lag */ - u8 rx_factor; /* maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes */ - u32 ffpld_rsvd; /* number of bytes to reserve for preload */ - u32 max_txlen[MCS_TABLE_SIZE][2][2]; /* max size of ampdu per mcs, bw and sgi */ - void *ini_free[AMPDU_INI_FREE]; /* array of ini's to be freed on detach */ - bool mfbr; /* enable multiple fallback rate */ - u32 tx_max_funl; /* underflows should be kept such that - * (tx_max_funfl*underflows) < tx frames - */ - wlc_fifo_info_t fifo_tb[NUM_FFPLD_FIFO]; /* table of fifo infos */ - -}; - -#define AMPDU_CLEANUPFLAG_RX (0x1) -#define AMPDU_CLEANUPFLAG_TX (0x2) - -#define SCB_AMPDU_CUBBY(ampdu, scb) (&(scb->scb_ampdu)) -#define SCB_AMPDU_INI(scb_ampdu, tid) (&(scb_ampdu->ini[tid])) - -static void wlc_ffpld_init(struct ampdu_info *ampdu); -static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int f); -static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f); - -static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu, - scb_ampdu_t *scb_ampdu, - u8 tid, bool override); -static void ampdu_cleanup_tid_ini(struct ampdu_info *ampdu, - scb_ampdu_t *scb_ampdu, - u8 tid, bool force); -static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur); -static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb); -static void scb_ampdu_update_config_all(struct ampdu_info *ampdu); - -#define wlc_ampdu_txflowcontrol(a, b, c) do {} while (0) - -static void wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, - struct scb *scb, - struct sk_buff *p, tx_status_t *txs, - u32 frmtxstatus, u32 frmtxstatus2); - -static inline u16 pkt_txh_seqnum(struct wlc_info *wlc, struct sk_buff *p) -{ - d11txh_t *txh; - struct ieee80211_hdr *h; - txh = (d11txh_t *) p->data; - h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); - return ltoh16(h->seq_ctrl) >> SEQNUM_SHIFT; -} - -struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc) -{ - struct ampdu_info *ampdu; - int i; - - /* some code depends on packed structures */ - ASSERT(DOT11_MAXNUMFRAGS == NBITS(u16)); - ASSERT(ISPOWEROF2(AMPDU_TX_BA_MAX_WSIZE)); - ASSERT(ISPOWEROF2(AMPDU_RX_BA_MAX_WSIZE)); - ASSERT(wlc->pub->tunables->ampdunummpdu <= AMPDU_MAX_MPDU); - ASSERT(wlc->pub->tunables->ampdunummpdu > 0); - - ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC); - if (!ampdu) { - WL_ERROR("wl%d: wlc_ampdu_attach: out of mem\n", - wlc->pub->unit); - return NULL; - } - ampdu->wlc = wlc; - - for (i = 0; i < AMPDU_MAX_SCB_TID; i++) - ampdu->ini_enable[i] = true; - /* Disable ampdu for VO by default */ - ampdu->ini_enable[PRIO_8021D_VO] = false; - ampdu->ini_enable[PRIO_8021D_NC] = false; - - /* Disable ampdu for BK by default since not enough fifo space */ - ampdu->ini_enable[PRIO_8021D_NONE] = false; - ampdu->ini_enable[PRIO_8021D_BK] = false; - - ampdu->ba_tx_wsize = AMPDU_TX_BA_DEF_WSIZE; - ampdu->ba_rx_wsize = AMPDU_RX_BA_DEF_WSIZE; - ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY; - ampdu->max_pdu = AUTO; - ampdu->dur = AMPDU_MAX_DUR; - ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT; - - ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD; - /* bump max ampdu rcv size to 64k for all 11n devices except 4321A0 and 4321A1 */ - if (WLCISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2)) - ampdu->rx_factor = AMPDU_RX_FACTOR_32K; - else - ampdu->rx_factor = AMPDU_RX_FACTOR_64K; - ampdu->retry_limit = AMPDU_DEF_RETRY_LIMIT; - ampdu->rr_retry_limit = AMPDU_DEF_RR_RETRY_LIMIT; - - for (i = 0; i < AMPDU_MAX_SCB_TID; i++) { - ampdu->retry_limit_tid[i] = ampdu->retry_limit; - ampdu->rr_retry_limit_tid[i] = ampdu->rr_retry_limit; - } - - ampdu_update_max_txlen(ampdu, ampdu->dur); - ampdu->mfbr = false; - /* try to set ampdu to the default value */ - wlc_ampdu_set(ampdu, wlc->pub->_ampdu); - - ampdu->tx_max_funl = FFPLD_TX_MAX_UNFL; - wlc_ffpld_init(ampdu); - - return ampdu; -} - -void wlc_ampdu_detach(struct ampdu_info *ampdu) -{ - int i; - - if (!ampdu) - return; - - /* free all ini's which were to be freed on callbacks which were never called */ - for (i = 0; i < AMPDU_INI_FREE; i++) { - if (ampdu->ini_free[i]) { - kfree(ampdu->ini_free[i]); - } - } - - wlc_module_unregister(ampdu->wlc->pub, "ampdu", ampdu); - kfree(ampdu); -} - -void scb_ampdu_cleanup(struct ampdu_info *ampdu, struct scb *scb) -{ - scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - u8 tid; - - WL_AMPDU_UPDN("scb_ampdu_cleanup: enter\n"); - ASSERT(scb_ampdu); - - for (tid = 0; tid < AMPDU_MAX_SCB_TID; tid++) { - ampdu_cleanup_tid_ini(ampdu, scb_ampdu, tid, false); - } -} - -/* reset the ampdu state machine so that it can gracefully handle packets that were - * freed from the dma and tx queues during reinit - */ -void wlc_ampdu_reset(struct ampdu_info *ampdu) -{ - WL_NONE("%s: Entering\n", __func__); -} - -static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb) -{ - scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - int i; - - scb_ampdu->max_pdu = (u8) ampdu->wlc->pub->tunables->ampdunummpdu; - - /* go back to legacy size if some preloading is occuring */ - for (i = 0; i < NUM_FFPLD_FIFO; i++) { - if (ampdu->fifo_tb[i].ampdu_pld_size > FFPLD_PLD_INCR) - scb_ampdu->max_pdu = AMPDU_NUM_MPDU_LEGACY; - } - - /* apply user override */ - if (ampdu->max_pdu != AUTO) - scb_ampdu->max_pdu = (u8) ampdu->max_pdu; - - scb_ampdu->release = min_t(u8, scb_ampdu->max_pdu, AMPDU_SCB_MAX_RELEASE); - - if (scb_ampdu->max_rxlen) - scb_ampdu->release = - min_t(u8, scb_ampdu->release, scb_ampdu->max_rxlen / 1600); - - scb_ampdu->release = min(scb_ampdu->release, - ampdu->fifo_tb[TX_AC_BE_FIFO]. - mcs2ampdu_table[FFPLD_MAX_MCS]); - - ASSERT(scb_ampdu->release); -} - -void scb_ampdu_update_config_all(struct ampdu_info *ampdu) -{ - scb_ampdu_update_config(ampdu, ampdu->wlc->pub->global_scb); -} - -static void wlc_ffpld_init(struct ampdu_info *ampdu) -{ - int i, j; - wlc_fifo_info_t *fifo; - - for (j = 0; j < NUM_FFPLD_FIFO; j++) { - fifo = (ampdu->fifo_tb + j); - fifo->ampdu_pld_size = 0; - for (i = 0; i <= FFPLD_MAX_MCS; i++) - fifo->mcs2ampdu_table[i] = 255; - fifo->dmaxferrate = 0; - fifo->accum_txampdu = 0; - fifo->prev_txfunfl = 0; - fifo->accum_txfunfl = 0; - - } -} - -/* evaluate the dma transfer rate using the tx underflows as feedback. - * If necessary, increase tx fifo preloading. If not enough, - * decrease maximum ampdu size for each mcs till underflows stop - * Return 1 if pre-loading not active, -1 if not an underflow event, - * 0 if pre-loading module took care of the event. - */ -static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) -{ - struct ampdu_info *ampdu = wlc->ampdu; - u32 phy_rate = MCS_RATE(FFPLD_MAX_MCS, true, false); - u32 txunfl_ratio; - u8 max_mpdu; - u32 current_ampdu_cnt = 0; - u16 max_pld_size; - u32 new_txunfl; - wlc_fifo_info_t *fifo = (ampdu->fifo_tb + fid); - uint xmtfifo_sz; - u16 cur_txunfl; - - /* return if we got here for a different reason than underflows */ - cur_txunfl = - wlc_read_shm(wlc, - M_UCODE_MACSTAT + offsetof(macstat_t, txfunfl[fid])); - new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl); - if (new_txunfl == 0) { - WL_FFPLD("check_txunfl : TX status FRAG set but no tx underflows\n"); - return -1; - } - fifo->prev_txfunfl = cur_txunfl; - - if (!ampdu->tx_max_funl) - return 1; - - /* check if fifo is big enough */ - if (wlc_xmtfifo_sz_get(wlc, fid, &xmtfifo_sz)) { - WL_FFPLD("check_txunfl : get xmtfifo_sz failed\n"); - return -1; - } - - if ((TXFIFO_SIZE_UNIT * (u32) xmtfifo_sz) <= ampdu->ffpld_rsvd) - return 1; - - max_pld_size = TXFIFO_SIZE_UNIT * xmtfifo_sz - ampdu->ffpld_rsvd; - fifo->accum_txfunfl += new_txunfl; - - /* we need to wait for at least 10 underflows */ - if (fifo->accum_txfunfl < 10) - return 0; - - WL_FFPLD("ampdu_count %d tx_underflows %d\n", - current_ampdu_cnt, fifo->accum_txfunfl); - - /* - compute the current ratio of tx unfl per ampdu. - When the current ampdu count becomes too - big while the ratio remains small, we reset - the current count in order to not - introduce too big of a latency in detecting a - large amount of tx underflows later. - */ - - txunfl_ratio = current_ampdu_cnt / fifo->accum_txfunfl; - - if (txunfl_ratio > ampdu->tx_max_funl) { - if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT) { - fifo->accum_txfunfl = 0; - } - return 0; - } - max_mpdu = - min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY); - - /* In case max value max_pdu is already lower than - the fifo depth, there is nothing more we can do. - */ - - if (fifo->ampdu_pld_size >= max_mpdu * FFPLD_MPDU_SIZE) { - WL_FFPLD(("tx fifo pld : max ampdu fits in fifo\n)")); - fifo->accum_txfunfl = 0; - return 0; - } - - if (fifo->ampdu_pld_size < max_pld_size) { - - /* increment by TX_FIFO_PLD_INC bytes */ - fifo->ampdu_pld_size += FFPLD_PLD_INCR; - if (fifo->ampdu_pld_size > max_pld_size) - fifo->ampdu_pld_size = max_pld_size; - - /* update scb release size */ - scb_ampdu_update_config_all(ampdu); - - /* - compute a new dma xfer rate for max_mpdu @ max mcs. - This is the minimum dma rate that - can acheive no unferflow condition for the current mpdu size. - */ - /* note : we divide/multiply by 100 to avoid integer overflows */ - fifo->dmaxferrate = - (((phy_rate / 100) * - (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size)) - / (max_mpdu * FFPLD_MPDU_SIZE)) * 100; - - WL_FFPLD("DMA estimated transfer rate %d; pre-load size %d\n", - fifo->dmaxferrate, fifo->ampdu_pld_size); - } else { - - /* decrease ampdu size */ - if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] > 1) { - if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] == 255) - fifo->mcs2ampdu_table[FFPLD_MAX_MCS] = - AMPDU_NUM_MPDU_LEGACY - 1; - else - fifo->mcs2ampdu_table[FFPLD_MAX_MCS] -= 1; - - /* recompute the table */ - wlc_ffpld_calc_mcs2ampdu_table(ampdu, fid); - - /* update scb release size */ - scb_ampdu_update_config_all(ampdu); - } - } - fifo->accum_txfunfl = 0; - return 0; -} - -static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f) -{ - int i; - u32 phy_rate, dma_rate, tmp; - u8 max_mpdu; - wlc_fifo_info_t *fifo = (ampdu->fifo_tb + f); - - /* recompute the dma rate */ - /* note : we divide/multiply by 100 to avoid integer overflows */ - max_mpdu = - min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY); - phy_rate = MCS_RATE(FFPLD_MAX_MCS, true, false); - dma_rate = - (((phy_rate / 100) * - (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size)) - / (max_mpdu * FFPLD_MPDU_SIZE)) * 100; - fifo->dmaxferrate = dma_rate; - - /* fill up the mcs2ampdu table; do not recalc the last mcs */ - dma_rate = dma_rate >> 7; - for (i = 0; i < FFPLD_MAX_MCS; i++) { - /* shifting to keep it within integer range */ - phy_rate = MCS_RATE(i, true, false) >> 7; - if (phy_rate > dma_rate) { - tmp = ((fifo->ampdu_pld_size * phy_rate) / - ((phy_rate - dma_rate) * FFPLD_MPDU_SIZE)) + 1; - tmp = min_t(u32, tmp, 255); - fifo->mcs2ampdu_table[i] = (u8) tmp; - } - } -} - -static void BCMFASTPATH -wlc_ampdu_agg(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p, - uint prec) -{ - scb_ampdu_t *scb_ampdu; - scb_ampdu_tid_ini_t *ini; - u8 tid = (u8) (p->priority); - - scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - - /* initialize initiator on first packet; sends addba req */ - ini = SCB_AMPDU_INI(scb_ampdu, tid); - if (ini->magic != INI_MAGIC) { - ini = wlc_ampdu_init_tid_ini(ampdu, scb_ampdu, tid, false); - } - return; -} - -int BCMFASTPATH -wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, - struct sk_buff **pdu, int prec) -{ - struct wlc_info *wlc; - struct osl_info *osh; - struct sk_buff *p, *pkt[AMPDU_MAX_MPDU]; - u8 tid, ndelim; - int err = 0; - u8 preamble_type = WLC_GF_PREAMBLE; - u8 fbr_preamble_type = WLC_GF_PREAMBLE; - u8 rts_preamble_type = WLC_LONG_PREAMBLE; - u8 rts_fbr_preamble_type = WLC_LONG_PREAMBLE; - - bool rr = true, fbr = false; - uint i, count = 0, fifo, seg_cnt = 0; - u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0; - u32 ampdu_len, maxlen = 0; - d11txh_t *txh = NULL; - u8 *plcp; - struct ieee80211_hdr *h; - struct scb *scb; - scb_ampdu_t *scb_ampdu; - scb_ampdu_tid_ini_t *ini; - u8 mcs = 0; - bool use_rts = false, use_cts = false; - ratespec_t rspec = 0, rspec_fallback = 0; - ratespec_t rts_rspec = 0, rts_rspec_fallback = 0; - u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; - struct ieee80211_rts *rts; - u8 rr_retry_limit; - wlc_fifo_info_t *f; - bool fbr_iscck; - struct ieee80211_tx_info *tx_info; - u16 qlen; - - wlc = ampdu->wlc; - osh = wlc->osh; - p = *pdu; - - ASSERT(p); - - tid = (u8) (p->priority); - ASSERT(tid < AMPDU_MAX_SCB_TID); - - f = ampdu->fifo_tb + prio2fifo[tid]; - - scb = wlc->pub->global_scb; - ASSERT(scb->magic == SCB_MAGIC); - - scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - ASSERT(scb_ampdu); - ini = &scb_ampdu->ini[tid]; - - /* Let pressure continue to build ... */ - qlen = pktq_plen(&qi->q, prec); - if (ini->tx_in_transit > 0 && qlen < scb_ampdu->max_pdu) { - return BCME_BUSY; - } - - wlc_ampdu_agg(ampdu, scb, p, tid); - - if (wlc->block_datafifo) { - WL_ERROR("%s: Fifo blocked\n", __func__); - return BCME_BUSY; - } - rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; - ampdu_len = 0; - dma_len = 0; - while (p) { - struct ieee80211_tx_rate *txrate; - - tx_info = IEEE80211_SKB_CB(p); - txrate = tx_info->status.rates; - - if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { - err = wlc_prep_pdu(wlc, p, &fifo); - } else { - WL_ERROR("%s: AMPDU flag is off!\n", __func__); - *pdu = NULL; - err = 0; - break; - } - - if (err) { - if (err == BCME_BUSY) { - WL_ERROR("wl%d: wlc_sendampdu: prep_xdu retry; seq 0x%x\n", - wlc->pub->unit, seq); - WLCNTINCR(ampdu->cnt->sduretry); - *pdu = p; - break; - } - - /* error in the packet; reject it */ - WL_AMPDU_ERR("wl%d: wlc_sendampdu: prep_xdu rejected; seq 0x%x\n", - wlc->pub->unit, seq); - WLCNTINCR(ampdu->cnt->sdurejected); - - *pdu = NULL; - break; - } - - /* pkt is good to be aggregated */ - ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); - txh = (d11txh_t *) p->data; - plcp = (u8 *) (txh + 1); - h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); - seq = ltoh16(h->seq_ctrl) >> SEQNUM_SHIFT; - index = TX_SEQ_TO_INDEX(seq); - - /* check mcl fields and test whether it can be agg'd */ - mcl = ltoh16(txh->MacTxControlLow); - mcl &= ~TXC_AMPDU_MASK; - fbr_iscck = !(ltoh16(txh->XtraFrameTypes) & 0x3); - ASSERT(!fbr_iscck); - txh->PreloadSize = 0; /* always default to 0 */ - - /* Handle retry limits */ - if (txrate[0].count <= rr_retry_limit) { - txrate[0].count++; - rr = true; - fbr = false; - ASSERT(!fbr); - } else { - fbr = true; - rr = false; - txrate[1].count++; - } - - /* extract the length info */ - len = fbr_iscck ? WLC_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) - : WLC_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); - - /* retrieve null delimiter count */ - ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; - seg_cnt += 1; - - WL_AMPDU_TX("wl%d: wlc_sendampdu: mpdu %d plcp_len %d\n", - wlc->pub->unit, count, len); - - /* - * aggregateable mpdu. For ucode/hw agg, - * test whether need to break or change the epoch - */ - if (count == 0) { - u16 fc; - mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT); - /* refill the bits since might be a retx mpdu */ - mcl |= TXC_STARTMSDU; - rts = (struct ieee80211_rts *)&txh->rts_frame; - fc = ltoh16(rts->frame_control); - if ((fc & FC_KIND_MASK) == FC_RTS) { - mcl |= TXC_SENDRTS; - use_rts = true; - } - if ((fc & FC_KIND_MASK) == FC_CTS) { - mcl |= TXC_SENDCTS; - use_cts = true; - } - } else { - mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT); - mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS); - } - - len = roundup(len, 4); - ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN); - - dma_len += (u16) pkttotlen(osh, p); - - WL_AMPDU_TX("wl%d: wlc_sendampdu: ampdu_len %d seg_cnt %d null delim %d\n", - wlc->pub->unit, ampdu_len, seg_cnt, ndelim); - - txh->MacTxControlLow = htol16(mcl); - - /* this packet is added */ - pkt[count++] = p; - - /* patch the first MPDU */ - if (count == 1) { - u8 plcp0, plcp3, is40, sgi; - struct ieee80211_sta *sta; - - sta = tx_info->control.sta; - - if (rr) { - plcp0 = plcp[0]; - plcp3 = plcp[3]; - } else { - plcp0 = txh->FragPLCPFallback[0]; - plcp3 = txh->FragPLCPFallback[3]; - - } - is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; - sgi = PLCP3_ISSGI(plcp3) ? 1 : 0; - mcs = plcp0 & ~MIMO_PLCP_40MHZ; - ASSERT(mcs < MCS_TABLE_SIZE); - maxlen = - min(scb_ampdu->max_rxlen, - ampdu->max_txlen[mcs][is40][sgi]); - - WL_NONE("sendampdu: sgi %d, is40 %d, mcs %d\n", - sgi, is40, mcs); - - maxlen = 64 * 1024; /* XXX Fix me to honor real max_rxlen */ - - if (is40) - mimo_ctlchbw = - CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC) - ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; - - /* rebuild the rspec and rspec_fallback */ - rspec = RSPEC_MIMORATE; - rspec |= plcp[0] & ~MIMO_PLCP_40MHZ; - if (plcp[0] & MIMO_PLCP_40MHZ) - rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT); - - if (fbr_iscck) /* CCK */ - rspec_fallback = - CCK_RSPEC(CCK_PHY2MAC_RATE - (txh->FragPLCPFallback[0])); - else { /* MIMO */ - rspec_fallback = RSPEC_MIMORATE; - rspec_fallback |= - txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ; - if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ) - rspec_fallback |= - (PHY_TXC1_BW_40MHZ << - RSPEC_BW_SHIFT); - } - - if (use_rts || use_cts) { - rts_rspec = - wlc_rspec_to_rts_rspec(wlc, rspec, false, - mimo_ctlchbw); - rts_rspec_fallback = - wlc_rspec_to_rts_rspec(wlc, rspec_fallback, - false, mimo_ctlchbw); - } - } - - /* if (first mpdu for host agg) */ - /* test whether to add more */ - if ((MCS_RATE(mcs, true, false) >= f->dmaxferrate) && - (count == f->mcs2ampdu_table[mcs])) { - WL_AMPDU_ERR("wl%d: PR 37644: stopping ampdu at %d for mcs %d\n", - wlc->pub->unit, count, mcs); - break; - } - - if (count == scb_ampdu->max_pdu) { - WL_NONE("Stop taking from q, reached %d deep\n", - scb_ampdu->max_pdu); - break; - } - - /* check to see if the next pkt is a candidate for aggregation */ - p = pktq_ppeek(&qi->q, prec); - tx_info = IEEE80211_SKB_CB(p); /* tx_info must be checked with current p */ - - if (p) { - if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && - ((u8) (p->priority) == tid)) { - - plen = - pkttotlen(osh, p) + AMPDU_MAX_MPDU_OVERHEAD; - plen = max(scb_ampdu->min_len, plen); - - if ((plen + ampdu_len) > maxlen) { - p = NULL; - WL_ERROR("%s: Bogus plen #1\n", - __func__); - ASSERT(3 == 4); - continue; - } - - /* check if there are enough descriptors available */ - if (TXAVAIL(wlc, fifo) <= (seg_cnt + 1)) { - WL_ERROR("%s: No fifo space !!!!!!\n", - __func__); - p = NULL; - continue; - } - p = pktq_pdeq(&qi->q, prec); - ASSERT(p); - } else { - p = NULL; - } - } - } /* end while(p) */ - - ini->tx_in_transit += count; - - if (count) { - WLCNTADD(ampdu->cnt->txmpdu, count); - - /* patch up the last txh */ - txh = (d11txh_t *) pkt[count - 1]->data; - mcl = ltoh16(txh->MacTxControlLow); - mcl &= ~TXC_AMPDU_MASK; - mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT); - txh->MacTxControlLow = htol16(mcl); - - /* remove the null delimiter after last mpdu */ - ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; - txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0; - ampdu_len -= ndelim * AMPDU_DELIMITER_LEN; - - /* remove the pad len from last mpdu */ - fbr_iscck = ((ltoh16(txh->XtraFrameTypes) & 0x3) == 0); - len = fbr_iscck ? WLC_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) - : WLC_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); - ampdu_len -= roundup(len, 4) - len; - - /* patch up the first txh & plcp */ - txh = (d11txh_t *) pkt[0]->data; - plcp = (u8 *) (txh + 1); - - WLC_SET_MIMO_PLCP_LEN(plcp, ampdu_len); - /* mark plcp to indicate ampdu */ - WLC_SET_MIMO_PLCP_AMPDU(plcp); - - /* reset the mixed mode header durations */ - if (txh->MModeLen) { - u16 mmodelen = - wlc_calc_lsig_len(wlc, rspec, ampdu_len); - txh->MModeLen = htol16(mmodelen); - preamble_type = WLC_MM_PREAMBLE; - } - if (txh->MModeFbrLen) { - u16 mmfbrlen = - wlc_calc_lsig_len(wlc, rspec_fallback, ampdu_len); - txh->MModeFbrLen = htol16(mmfbrlen); - fbr_preamble_type = WLC_MM_PREAMBLE; - } - - /* set the preload length */ - if (MCS_RATE(mcs, true, false) >= f->dmaxferrate) { - dma_len = min(dma_len, f->ampdu_pld_size); - txh->PreloadSize = htol16(dma_len); - } else - txh->PreloadSize = 0; - - mch = ltoh16(txh->MacTxControlHigh); - - /* update RTS dur fields */ - if (use_rts || use_cts) { - u16 durid; - rts = (struct ieee80211_rts *)&txh->rts_frame; - if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) == - TXC_PREAMBLE_RTS_MAIN_SHORT) - rts_preamble_type = WLC_SHORT_PREAMBLE; - - if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) == - TXC_PREAMBLE_RTS_FB_SHORT) - rts_fbr_preamble_type = WLC_SHORT_PREAMBLE; - - durid = - wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec, - rspec, rts_preamble_type, - preamble_type, ampdu_len, - true); - rts->duration = htol16(durid); - durid = wlc_compute_rtscts_dur(wlc, use_cts, - rts_rspec_fallback, - rspec_fallback, - rts_fbr_preamble_type, - fbr_preamble_type, - ampdu_len, true); - txh->RTSDurFallback = htol16(durid); - /* set TxFesTimeNormal */ - txh->TxFesTimeNormal = rts->duration; - /* set fallback rate version of TxFesTimeNormal */ - txh->TxFesTimeFallback = txh->RTSDurFallback; - } - - /* set flag and plcp for fallback rate */ - if (fbr) { - WLCNTADD(ampdu->cnt->txfbr_mpdu, count); - WLCNTINCR(ampdu->cnt->txfbr_ampdu); - mch |= TXC_AMPDU_FBR; - txh->MacTxControlHigh = htol16(mch); - WLC_SET_MIMO_PLCP_AMPDU(plcp); - WLC_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback); - } - - WL_AMPDU_TX("wl%d: wlc_sendampdu: count %d ampdu_len %d\n", - wlc->pub->unit, count, ampdu_len); - - /* inform rate_sel if it this is a rate probe pkt */ - frameid = ltoh16(txh->TxFrameID); - if (frameid & TXFID_RATE_PROBE_MASK) { - WL_ERROR("%s: XXX what to do with TXFID_RATE_PROBE_MASK!?\n", - __func__); - } - for (i = 0; i < count; i++) - wlc_txfifo(wlc, fifo, pkt[i], i == (count - 1), - ampdu->txpkt_weight); - - } - /* endif (count) */ - return err; -} - -void BCMFASTPATH -wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, - struct sk_buff *p, tx_status_t *txs) -{ - scb_ampdu_t *scb_ampdu; - struct wlc_info *wlc = ampdu->wlc; - scb_ampdu_tid_ini_t *ini; - u32 s1 = 0, s2 = 0; - struct ieee80211_tx_info *tx_info; - - tx_info = IEEE80211_SKB_CB(p); - ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); - ASSERT(scb); - ASSERT(scb->magic == SCB_MAGIC); - ASSERT(txs->status & TX_STATUS_AMPDU); - scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - ASSERT(scb_ampdu); - ini = SCB_AMPDU_INI(scb_ampdu, p->priority); - ASSERT(ini->scb == scb); - - /* BMAC_NOTE: For the split driver, second level txstatus comes later - * So if the ACK was received then wait for the second level else just - * call the first one - */ - if (txs->status & TX_STATUS_ACK_RCV) { - u8 status_delay = 0; - - /* wait till the next 8 bytes of txstatus is available */ - while (((s1 = - R_REG(wlc->osh, - &wlc->regs->frmtxstatus)) & TXS_V) == 0) { - udelay(1); - status_delay++; - if (status_delay > 10) { - ASSERT(status_delay <= 10); - return; - } - } - - ASSERT(!(s1 & TX_STATUS_INTERMEDIATE)); - ASSERT(s1 & TX_STATUS_AMPDU); - s2 = R_REG(wlc->osh, &wlc->regs->frmtxstatus2); - } - - wlc_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2); - wlc_ampdu_txflowcontrol(wlc, scb_ampdu, ini); -} - -void -rate_status(struct wlc_info *wlc, struct ieee80211_tx_info *tx_info, - tx_status_t *txs, u8 mcs) -{ - struct ieee80211_tx_rate *txrate = tx_info->status.rates; - int i; - - /* clear the rest of the rates */ - for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) { - txrate[i].idx = -1; - txrate[i].count = 0; - } -} - -#define SHORTNAME "AMPDU status" - -static void BCMFASTPATH -wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, - struct sk_buff *p, tx_status_t *txs, - u32 s1, u32 s2) -{ - scb_ampdu_t *scb_ampdu; - struct wlc_info *wlc = ampdu->wlc; - scb_ampdu_tid_ini_t *ini; - u8 bitmap[8], queue, tid; - d11txh_t *txh; - u8 *plcp; - struct ieee80211_hdr *h; - u16 seq, start_seq = 0, bindex, index, mcl; - u8 mcs = 0; - bool ba_recd = false, ack_recd = false; - u8 suc_mpdu = 0, tot_mpdu = 0; - uint supr_status; - bool update_rate = true, retry = true, tx_error = false; - u16 mimoantsel = 0; - u8 antselid = 0; - u8 retry_limit, rr_retry_limit; - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); - -#ifdef BCMDBG - u8 hole[AMPDU_MAX_MPDU]; - memset(hole, 0, sizeof(hole)); -#endif - - ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); - ASSERT(txs->status & TX_STATUS_AMPDU); - - scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - ASSERT(scb_ampdu); - - tid = (u8) (p->priority); - - ini = SCB_AMPDU_INI(scb_ampdu, tid); - retry_limit = ampdu->retry_limit_tid[tid]; - rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; - - ASSERT(ini->scb == scb); - - memset(bitmap, 0, sizeof(bitmap)); - queue = txs->frameid & TXFID_QUEUE_MASK; - ASSERT(queue < AC_COUNT); - - supr_status = txs->status & TX_STATUS_SUPR_MASK; - - if (txs->status & TX_STATUS_ACK_RCV) { - if (TX_STATUS_SUPR_UF == supr_status) { - update_rate = false; - } - - ASSERT(txs->status & TX_STATUS_INTERMEDIATE); - start_seq = txs->sequence >> SEQNUM_SHIFT; - bitmap[0] = (txs->status & TX_STATUS_BA_BMAP03_MASK) >> - TX_STATUS_BA_BMAP03_SHIFT; - - ASSERT(!(s1 & TX_STATUS_INTERMEDIATE)); - ASSERT(s1 & TX_STATUS_AMPDU); - - bitmap[0] |= - (s1 & TX_STATUS_BA_BMAP47_MASK) << - TX_STATUS_BA_BMAP47_SHIFT; - bitmap[1] = (s1 >> 8) & 0xff; - bitmap[2] = (s1 >> 16) & 0xff; - bitmap[3] = (s1 >> 24) & 0xff; - - bitmap[4] = s2 & 0xff; - bitmap[5] = (s2 >> 8) & 0xff; - bitmap[6] = (s2 >> 16) & 0xff; - bitmap[7] = (s2 >> 24) & 0xff; - - ba_recd = true; - } else { - WLCNTINCR(ampdu->cnt->noba); - if (supr_status) { - update_rate = false; - if (supr_status == TX_STATUS_SUPR_BADCH) { - WL_ERROR("%s: Pkt tx suppressed, illegal channel possibly %d\n", - __func__, - CHSPEC_CHANNEL(wlc->default_bss->chanspec)); - } else { - if (supr_status == TX_STATUS_SUPR_FRAG) - WL_NONE("%s: AMPDU frag err\n", - __func__); - else - WL_ERROR("%s: wlc_ampdu_dotxstatus: supr_status 0x%x\n", - __func__, supr_status); - } - /* no need to retry for badch; will fail again */ - if (supr_status == TX_STATUS_SUPR_BADCH || - supr_status == TX_STATUS_SUPR_EXPTIME) { - retry = false; - WLCNTINCR(wlc->pub->_cnt->txchanrej); - } else if (supr_status == TX_STATUS_SUPR_EXPTIME) { - - WLCNTINCR(wlc->pub->_cnt->txexptime); - - /* TX underflow : try tuning pre-loading or ampdu size */ - } else if (supr_status == TX_STATUS_SUPR_FRAG) { - /* if there were underflows, but pre-loading is not active, - notify rate adaptation. - */ - if (wlc_ffpld_check_txfunfl(wlc, prio2fifo[tid]) - > 0) { - tx_error = true; - } - } - } else if (txs->phyerr) { - update_rate = false; - WLCNTINCR(wlc->pub->_cnt->txphyerr); - WL_ERROR("wl%d: wlc_ampdu_dotxstatus: tx phy error (0x%x)\n", - wlc->pub->unit, txs->phyerr); - -#ifdef BCMDBG - if (WL_ERROR_ON()) { - prpkt("txpkt (AMPDU)", wlc->osh, p); - wlc_print_txdesc((d11txh_t *) p->data); - wlc_print_txstatus(txs); - } -#endif /* BCMDBG */ - } - } - - /* loop through all pkts and retry if not acked */ - while (p) { - tx_info = IEEE80211_SKB_CB(p); - ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); - txh = (d11txh_t *) p->data; - mcl = ltoh16(txh->MacTxControlLow); - plcp = (u8 *) (txh + 1); - h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); - seq = ltoh16(h->seq_ctrl) >> SEQNUM_SHIFT; - - if (tot_mpdu == 0) { - mcs = plcp[0] & MIMO_PLCP_MCS_MASK; - mimoantsel = ltoh16(txh->ABI_MimoAntSel); - } - - index = TX_SEQ_TO_INDEX(seq); - ack_recd = false; - if (ba_recd) { - bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); - - WL_AMPDU_TX("%s: tid %d seq is %d, start_seq is %d, bindex is %d set %d, index %d\n", - __func__, tid, seq, start_seq, bindex, - isset(bitmap, bindex), index); - - /* if acked then clear bit and free packet */ - if ((bindex < AMPDU_TX_BA_MAX_WSIZE) - && isset(bitmap, bindex)) { - ini->tx_in_transit--; - ini->txretry[index] = 0; - - /* ampdu_ack_len: number of acked aggregated frames */ - /* ampdu_ack_map: block ack bit map for the aggregation */ - /* ampdu_len: number of aggregated frames */ - rate_status(wlc, tx_info, txs, mcs); - tx_info->flags |= IEEE80211_TX_STAT_ACK; - tx_info->flags |= IEEE80211_TX_STAT_AMPDU; - - /* XXX TODO: Make these accurate. */ - tx_info->status.ampdu_ack_len = - (txs-> - status & TX_STATUS_FRM_RTX_MASK) >> - TX_STATUS_FRM_RTX_SHIFT; - tx_info->status.ampdu_len = - (txs-> - status & TX_STATUS_FRM_RTX_MASK) >> - TX_STATUS_FRM_RTX_SHIFT; - - skb_pull(p, D11_PHY_HDR_LEN); - skb_pull(p, D11_TXH_LEN); - - ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, - p); - ack_recd = true; - suc_mpdu++; - } - } - /* either retransmit or send bar if ack not recd */ - if (!ack_recd) { - struct ieee80211_tx_rate *txrate = - tx_info->status.rates; - if (retry && (txrate[0].count < (int)retry_limit)) { - ini->txretry[index]++; - ini->tx_in_transit--; - /* Use high prededence for retransmit to give some punch */ - /* wlc_txq_enq(wlc, scb, p, WLC_PRIO_TO_PREC(tid)); */ - wlc_txq_enq(wlc, scb, p, - WLC_PRIO_TO_HI_PREC(tid)); - } else { - /* Retry timeout */ - ini->tx_in_transit--; - ieee80211_tx_info_clear_status(tx_info); - tx_info->flags |= - IEEE80211_TX_STAT_AMPDU_NO_BACK; - skb_pull(p, D11_PHY_HDR_LEN); - skb_pull(p, D11_TXH_LEN); - WL_ERROR("%s: BA Timeout, seq %d, in_transit %d\n", - SHORTNAME, seq, ini->tx_in_transit); - ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, - p); - } - } - tot_mpdu++; - - /* break out if last packet of ampdu */ - if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) == - TXC_AMPDU_LAST) - break; - - p = GETNEXTTXP(wlc, queue); - if (p == NULL) { - ASSERT(p); - break; - } - } - wlc_send_q(wlc, wlc->active_queue); - - /* update rate state */ - if (WLANTSEL_ENAB(wlc)) - antselid = wlc_antsel_antsel2id(wlc->asi, mimoantsel); - - wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight); -} - -static void -ampdu_cleanup_tid_ini(struct ampdu_info *ampdu, scb_ampdu_t *scb_ampdu, u8 tid, - bool force) -{ - scb_ampdu_tid_ini_t *ini; - ini = SCB_AMPDU_INI(scb_ampdu, tid); - if (!ini) - return; - - WL_AMPDU_CTL("wl%d: ampdu_cleanup_tid_ini: tid %d\n", - ampdu->wlc->pub->unit, tid); - - if (ini->tx_in_transit && !force) - return; - - scb_ampdu = SCB_AMPDU_CUBBY(ampdu, ini->scb); - ASSERT(ini == &scb_ampdu->ini[ini->tid]); - - /* free all buffered tx packets */ - pktq_pflush(ampdu->wlc->osh, &scb_ampdu->txq, ini->tid, true, NULL, 0); -} - -/* initialize the initiator code for tid */ -static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu, - scb_ampdu_t *scb_ampdu, - u8 tid, bool override) -{ - scb_ampdu_tid_ini_t *ini; - - ASSERT(scb_ampdu); - ASSERT(scb_ampdu->scb); - ASSERT(SCB_AMPDU(scb_ampdu->scb)); - ASSERT(tid < AMPDU_MAX_SCB_TID); - - /* check for per-tid control of ampdu */ - if (!ampdu->ini_enable[tid]) { - WL_ERROR("%s: Rejecting tid %d\n", __func__, tid); - return NULL; - } - - ini = SCB_AMPDU_INI(scb_ampdu, tid); - ini->tid = tid; - ini->scb = scb_ampdu->scb; - ini->magic = INI_MAGIC; - WLCNTINCR(ampdu->cnt->txaddbareq); - - return ini; -} - -int wlc_ampdu_set(struct ampdu_info *ampdu, bool on) -{ - struct wlc_info *wlc = ampdu->wlc; - - wlc->pub->_ampdu = false; - - if (on) { - if (!N_ENAB(wlc->pub)) { - WL_AMPDU_ERR("wl%d: driver not nmode enabled\n", - wlc->pub->unit); - return BCME_UNSUPPORTED; - } - if (!wlc_ampdu_cap(ampdu)) { - WL_AMPDU_ERR("wl%d: device not ampdu capable\n", - wlc->pub->unit); - return BCME_UNSUPPORTED; - } - wlc->pub->_ampdu = on; - } - - return 0; -} - -bool wlc_ampdu_cap(struct ampdu_info *ampdu) -{ - if (WLC_PHY_11N_CAP(ampdu->wlc->band)) - return true; - else - return false; -} - -static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur) -{ - u32 rate, mcs; - - for (mcs = 0; mcs < MCS_TABLE_SIZE; mcs++) { - /* rate is in Kbps; dur is in msec ==> len = (rate * dur) / 8 */ - /* 20MHz, No SGI */ - rate = MCS_RATE(mcs, false, false); - ampdu->max_txlen[mcs][0][0] = (rate * dur) >> 3; - /* 40 MHz, No SGI */ - rate = MCS_RATE(mcs, true, false); - ampdu->max_txlen[mcs][1][0] = (rate * dur) >> 3; - /* 20MHz, SGI */ - rate = MCS_RATE(mcs, false, true); - ampdu->max_txlen[mcs][0][1] = (rate * dur) >> 3; - /* 40 MHz, SGI */ - rate = MCS_RATE(mcs, true, true); - ampdu->max_txlen[mcs][1][1] = (rate * dur) >> 3; - } -} - -u8 BCMFASTPATH -wlc_ampdu_null_delim_cnt(struct ampdu_info *ampdu, struct scb *scb, - ratespec_t rspec, int phylen) -{ - scb_ampdu_t *scb_ampdu; - int bytes, cnt, tmp; - u8 tx_density; - - ASSERT(scb); - ASSERT(SCB_AMPDU(scb)); - - scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - ASSERT(scb_ampdu); - - if (scb_ampdu->mpdu_density == 0) - return 0; - - /* RSPEC2RATE is in kbps units ==> ~RSPEC2RATE/2^13 is in bytes/usec - density x is in 2^(x-4) usec - ==> # of bytes needed for req density = rate/2^(17-x) - ==> # of null delimiters = ceil(ceil(rate/2^(17-x)) - phylen)/4) - */ - - tx_density = scb_ampdu->mpdu_density; - - ASSERT(tx_density <= AMPDU_MAX_MPDU_DENSITY); - tmp = 1 << (17 - tx_density); - bytes = CEIL(RSPEC2RATE(rspec), tmp); - - if (bytes > phylen) { - cnt = CEIL(bytes - phylen, AMPDU_DELIMITER_LEN); - ASSERT(cnt <= 255); - return (u8) cnt; - } else - return 0; -} - -void wlc_ampdu_macaddr_upd(struct wlc_info *wlc) -{ - char template[T_RAM_ACCESS_SZ * 2]; - - /* driver needs to write the ta in the template; ta is at offset 16 */ - memset(template, 0, sizeof(template)); - bcopy((char *)wlc->pub->cur_etheraddr, template, ETH_ALEN); - wlc_write_template_ram(wlc, (T_BA_TPL_BASE + 16), (T_RAM_ACCESS_SZ * 2), - template); -} - -bool wlc_aggregatable(struct wlc_info *wlc, u8 tid) -{ - return wlc->ampdu->ini_enable[tid]; -} - -void wlc_ampdu_shm_upd(struct ampdu_info *ampdu) -{ - struct wlc_info *wlc = ampdu->wlc; - - /* Extend ucode internal watchdog timer to match larger received frames */ - if ((ampdu->rx_factor & HT_PARAMS_RX_FACTOR_MASK) == - AMPDU_RX_FACTOR_64K) { - wlc_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX); - wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX); - } else { - wlc_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_DEF); - wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF); - } -} diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.h b/drivers/staging/brcm80211/sys/wlc_ampdu.h deleted file mode 100644 index 03457f63f2ab..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_ampdu_h_ -#define _wlc_ampdu_h_ - -extern struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc); -extern void wlc_ampdu_detach(struct ampdu_info *ampdu); -extern bool wlc_ampdu_cap(struct ampdu_info *ampdu); -extern int wlc_ampdu_set(struct ampdu_info *ampdu, bool on); -extern int wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, - struct sk_buff **aggp, int prec); -extern void wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, - struct sk_buff *p, tx_status_t *txs); -extern void wlc_ampdu_reset(struct ampdu_info *ampdu); -extern void wlc_ampdu_macaddr_upd(struct wlc_info *wlc); -extern void wlc_ampdu_shm_upd(struct ampdu_info *ampdu); - -extern u8 wlc_ampdu_null_delim_cnt(struct ampdu_info *ampdu, struct scb *scb, - ratespec_t rspec, int phylen); -extern void scb_ampdu_cleanup(struct ampdu_info *ampdu, struct scb *scb); - -#endif /* _wlc_ampdu_h_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_antsel.c b/drivers/staging/brcm80211/sys/wlc_antsel.c deleted file mode 100644 index 402ddf8f3371..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_antsel.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include - -#ifdef WLANTSEL - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* useful macros */ -#define WLC_ANTSEL_11N_0(ant) ((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf) -#define WLC_ANTSEL_11N_1(ant) (((ant) & ANT_SELCFG_MASK) & 0xf) -#define WLC_ANTIDX_11N(ant) (((WLC_ANTSEL_11N_0(ant)) << 2) + (WLC_ANTSEL_11N_1(ant))) -#define WLC_ANT_ISAUTO_11N(ant) (((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) -#define WLC_ANTSEL_11N(ant) ((ant) & ANT_SELCFG_MASK) - -/* antenna switch */ -/* defines for no boardlevel antenna diversity */ -#define ANT_SELCFG_DEF_2x2 0x01 /* default antenna configuration */ - -/* 2x3 antdiv defines and tables for GPIO communication */ -#define ANT_SELCFG_NUM_2x3 3 -#define ANT_SELCFG_DEF_2x3 0x01 /* default antenna configuration */ - -/* 2x4 antdiv rev4 defines and tables for GPIO communication */ -#define ANT_SELCFG_NUM_2x4 4 -#define ANT_SELCFG_DEF_2x4 0x02 /* default antenna configuration */ - -/* static functions */ -static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel); -static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id); -static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg); -static void wlc_antsel_init_cfg(struct antsel_info *asi, - wlc_antselcfg_t *antsel, - bool auto_sel); - -const u16 mimo_2x4_div_antselpat_tbl[] = { - 0, 0, 0x9, 0xa, /* ant0: 0 ant1: 2,3 */ - 0, 0, 0x5, 0x6, /* ant0: 1 ant1: 2,3 */ - 0, 0, 0, 0, /* n.a. */ - 0, 0, 0, 0 /* n.a. */ -}; - -const u8 mimo_2x4_div_antselid_tbl[16] = { - 0, 0, 0, 0, 0, 2, 3, 0, - 0, 0, 1, 0, 0, 0, 0, 0 /* pat to antselid */ -}; - -const u16 mimo_2x3_div_antselpat_tbl[] = { - 16, 0, 1, 16, /* ant0: 0 ant1: 1,2 */ - 16, 16, 16, 16, /* n.a. */ - 16, 2, 16, 16, /* ant0: 2 ant1: 1 */ - 16, 16, 16, 16 /* n.a. */ -}; - -const u8 mimo_2x3_div_antselid_tbl[16] = { - 0, 1, 2, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 /* pat to antselid */ -}; - -struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc, - struct osl_info *osh, - struct wlc_pub *pub, - struct wlc_hw_info *wlc_hw) { - struct antsel_info *asi; - - asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC); - if (!asi) { - WL_ERROR("wl%d: wlc_antsel_attach: out of mem\n", pub->unit); - return NULL; - } - - asi->wlc = wlc; - asi->pub = pub; - asi->antsel_type = ANTSEL_NA; - asi->antsel_avail = false; - asi->antsel_antswitch = (u8) getintvar(asi->pub->vars, "antswitch"); - - if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) { - switch (asi->antsel_antswitch) { - case ANTSWITCH_TYPE_1: - case ANTSWITCH_TYPE_2: - case ANTSWITCH_TYPE_3: - /* 4321/2 board with 2x3 switch logic */ - asi->antsel_type = ANTSEL_2x3; - /* Antenna selection availability */ - if (((u16) getintvar(asi->pub->vars, "aa2g") == 7) || - ((u16) getintvar(asi->pub->vars, "aa5g") == 7)) { - asi->antsel_avail = true; - } else - if (((u16) getintvar(asi->pub->vars, "aa2g") == - 3) - || ((u16) getintvar(asi->pub->vars, "aa5g") - == 3)) { - asi->antsel_avail = false; - } else { - asi->antsel_avail = false; - WL_ERROR("wlc_antsel_attach: 2o3 board cfg invalid\n"); - ASSERT(0); - } - break; - default: - break; - } - } else if ((asi->pub->sromrev == 4) && - ((u16) getintvar(asi->pub->vars, "aa2g") == 7) && - ((u16) getintvar(asi->pub->vars, "aa5g") == 0)) { - /* hack to match old 4321CB2 cards with 2of3 antenna switch */ - asi->antsel_type = ANTSEL_2x3; - asi->antsel_avail = true; - } else if (asi->pub->boardflags2 & BFL2_2X4_DIV) { - asi->antsel_type = ANTSEL_2x4; - asi->antsel_avail = true; - } - - /* Set the antenna selection type for the low driver */ - wlc_bmac_antsel_type_set(wlc_hw, asi->antsel_type); - - /* Init (auto/manual) antenna selection */ - wlc_antsel_init_cfg(asi, &asi->antcfg_11n, true); - wlc_antsel_init_cfg(asi, &asi->antcfg_cur, true); - - return asi; -} - -void wlc_antsel_detach(struct antsel_info *asi) -{ - if (!asi) - return; - - kfree(asi); -} - -void wlc_antsel_init(struct antsel_info *asi) -{ - if ((asi->antsel_type == ANTSEL_2x3) || - (asi->antsel_type == ANTSEL_2x4)) - wlc_antsel_cfgupd(asi, &asi->antcfg_11n); -} - -/* boardlevel antenna selection: init antenna selection structure */ -static void -wlc_antsel_init_cfg(struct antsel_info *asi, wlc_antselcfg_t *antsel, - bool auto_sel) -{ - if (asi->antsel_type == ANTSEL_2x3) { - u8 antcfg_def = ANT_SELCFG_DEF_2x3 | - ((asi->antsel_avail && auto_sel) ? ANT_SELCFG_AUTO : 0); - antsel->ant_config[ANT_SELCFG_TX_DEF] = antcfg_def; - antsel->ant_config[ANT_SELCFG_TX_UNICAST] = antcfg_def; - antsel->ant_config[ANT_SELCFG_RX_DEF] = antcfg_def; - antsel->ant_config[ANT_SELCFG_RX_UNICAST] = antcfg_def; - antsel->num_antcfg = ANT_SELCFG_NUM_2x3; - - } else if (asi->antsel_type == ANTSEL_2x4) { - - antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x4; - antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x4; - antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x4; - antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x4; - antsel->num_antcfg = ANT_SELCFG_NUM_2x4; - - } else { /* no antenna selection available */ - - antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x2; - antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x2; - antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x2; - antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x2; - antsel->num_antcfg = 0; - } -} - -void BCMFASTPATH -wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel, - u8 antselid, u8 fbantselid, u8 *antcfg, - u8 *fbantcfg) -{ - u8 ant; - - /* if use default, assign it and return */ - if (usedef) { - *antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_DEF]; - *fbantcfg = *antcfg; - return; - } - - if (!sel) { - *antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST]; - *fbantcfg = *antcfg; - - } else { - ant = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST]; - if ((ant & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) { - *antcfg = wlc_antsel_id2antcfg(asi, antselid); - *fbantcfg = wlc_antsel_id2antcfg(asi, fbantselid); - } else { - *antcfg = - asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST]; - *fbantcfg = *antcfg; - } - } - return; -} - -/* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */ -u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel) -{ - u8 antselid = 0; - - if (asi->antsel_type == ANTSEL_2x4) { - /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */ - antselid = mimo_2x4_div_antselid_tbl[(antsel & 0xf)]; - return antselid; - - } else if (asi->antsel_type == ANTSEL_2x3) { - /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */ - antselid = mimo_2x3_div_antselid_tbl[(antsel & 0xf)]; - return antselid; - } - - return antselid; -} - -/* boardlevel antenna selection: convert id to ant_cfg */ -static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id) -{ - u8 antcfg = ANT_SELCFG_DEF_2x2; - - if (asi->antsel_type == ANTSEL_2x4) { - /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */ - antcfg = (((id & 0x2) << 3) | ((id & 0x1) + 2)); - return antcfg; - - } else if (asi->antsel_type == ANTSEL_2x3) { - /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */ - antcfg = (((id & 0x02) << 4) | ((id & 0x1) + 1)); - return antcfg; - } - - return antcfg; -} - -/* boardlevel antenna selection: convert ant_cfg to mimo_antsel (ucode interface) */ -static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg) -{ - u8 idx = WLC_ANTIDX_11N(WLC_ANTSEL_11N(ant_cfg)); - u16 mimo_antsel = 0; - - if (asi->antsel_type == ANTSEL_2x4) { - /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */ - mimo_antsel = (mimo_2x4_div_antselpat_tbl[idx] & 0xf); - return mimo_antsel; - - } else if (asi->antsel_type == ANTSEL_2x3) { - /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */ - mimo_antsel = (mimo_2x3_div_antselpat_tbl[idx] & 0xf); - return mimo_antsel; - } - - return mimo_antsel; -} - -/* boardlevel antenna selection: ucode interface control */ -static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel) -{ - struct wlc_info *wlc = asi->wlc; - u8 ant_cfg; - u16 mimo_antsel; - - ASSERT(asi->antsel_type != ANTSEL_NA); - - /* 1) Update TX antconfig for all frames that are not unicast data - * (aka default TX) - */ - ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF]; - mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg); - wlc_write_shm(wlc, M_MIMO_ANTSEL_TXDFLT, mimo_antsel); - /* Update driver stats for currently selected default tx/rx antenna config */ - asi->antcfg_cur.ant_config[ANT_SELCFG_TX_DEF] = ant_cfg; - - /* 2) Update RX antconfig for all frames that are not unicast data - * (aka default RX) - */ - ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF]; - mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg); - wlc_write_shm(wlc, M_MIMO_ANTSEL_RXDFLT, mimo_antsel); - /* Update driver stats for currently selected default tx/rx antenna config */ - asi->antcfg_cur.ant_config[ANT_SELCFG_RX_DEF] = ant_cfg; - - return 0; -} - -#endif /* WLANTSEL */ diff --git a/drivers/staging/brcm80211/sys/wlc_antsel.h b/drivers/staging/brcm80211/sys/wlc_antsel.h deleted file mode 100644 index 8875b5848665..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_antsel.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_antsel_h_ -#define _wlc_antsel_h_ -extern struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc, - struct osl_info *osh, - struct wlc_pub *pub, - struct wlc_hw_info *wlc_hw); -extern void wlc_antsel_detach(struct antsel_info *asi); -extern void wlc_antsel_init(struct antsel_info *asi); -extern void wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, - bool sel, - u8 id, u8 fbid, u8 *antcfg, - u8 *fbantcfg); -extern u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel); -#endif /* _wlc_antsel_h_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c deleted file mode 100644 index e22ce1f79660..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ /dev/null @@ -1,4235 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -/* BMAC_NOTE: a WLC_HIGH compile include of wlc.h adds in more structures and type - * dependencies. Need to include these to files to allow a clean include of wlc.h - * with WLC_HIGH defined. - * At some point we may be able to skip the include of wlc.h and instead just - * define a stub wlc_info and band struct to allow rpc calls to get the rpc handle. - */ -#include -#include -#include -#include -#include -#include -#include "wl_ucode.h" -#include "d11ucode_ext.h" -#include - -/* BMAC_NOTE: With WLC_HIGH defined, some fns in this file make calls to high level - * functions defined in the headers below. We should be eliminating those calls and - * will be able to delete these include lines. - */ -#include - -#include - -#include -#include - -#define TIMER_INTERVAL_WATCHDOG_BMAC 1000 /* watchdog timer, in unit of ms */ - -#define SYNTHPU_DLY_APHY_US 3700 /* a phy synthpu_dly time in us */ -#define SYNTHPU_DLY_BPHY_US 1050 /* b/g phy synthpu_dly time in us, default */ -#define SYNTHPU_DLY_NPHY_US 2048 /* n phy REV3 synthpu_dly time in us, default */ -#define SYNTHPU_DLY_LPPHY_US 300 /* lpphy synthpu_dly time in us */ - -#define SYNTHPU_DLY_PHY_US_QT 100 /* QT synthpu_dly time in us */ - -#ifndef BMAC_DUP_TO_REMOVE -#define WLC_RM_WAIT_TX_SUSPEND 4 /* Wait Tx Suspend */ - -#define ANTCNT 10 /* vanilla M_MAX_ANTCNT value */ - -#endif /* BMAC_DUP_TO_REMOVE */ - -#define DMAREG(wlc_hw, direction, fifonum) (D11REV_LT(wlc_hw->corerev, 11) ? \ - ((direction == DMA_TX) ? \ - (void *)&(wlc_hw->regs->fifo.f32regs.dmaregs[fifonum].xmt) : \ - (void *)&(wlc_hw->regs->fifo.f32regs.dmaregs[fifonum].rcv)) : \ - ((direction == DMA_TX) ? \ - (void *)&(wlc_hw->regs->fifo.f64regs[fifonum].dmaxmt) : \ - (void *)&(wlc_hw->regs->fifo.f64regs[fifonum].dmarcv))) - -/* - * The following table lists the buffer memory allocated to xmt fifos in HW. - * the size is in units of 256bytes(one block), total size is HW dependent - * ucode has default fifo partition, sw can overwrite if necessary - * - * This is documented in twiki under the topic UcodeTxFifo. Please ensure - * the twiki is updated before making changes. - */ - -#define XMTFIFOTBL_STARTREV 20 /* Starting corerev for the fifo size table */ - -static u16 xmtfifo_sz[][NFIFO] = { - {20, 192, 192, 21, 17, 5}, /* corerev 20: 5120, 49152, 49152, 5376, 4352, 1280 */ - {9, 58, 22, 14, 14, 5}, /* corerev 21: 2304, 14848, 5632, 3584, 3584, 1280 */ - {20, 192, 192, 21, 17, 5}, /* corerev 22: 5120, 49152, 49152, 5376, 4352, 1280 */ - {20, 192, 192, 21, 17, 5}, /* corerev 23: 5120, 49152, 49152, 5376, 4352, 1280 */ - {9, 58, 22, 14, 14, 5}, /* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */ -}; - -static void wlc_clkctl_clk(struct wlc_hw_info *wlc, uint mode); -static void wlc_coreinit(struct wlc_info *wlc); - -/* used by wlc_wakeucode_init() */ -static void wlc_write_inits(struct wlc_hw_info *wlc_hw, const d11init_t *inits); -static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[], - const uint nbytes); -static void wlc_ucode_download(struct wlc_hw_info *wlc); -static void wlc_ucode_txant_set(struct wlc_hw_info *wlc_hw); - -/* used by wlc_dpc() */ -static bool wlc_bmac_dotxstatus(struct wlc_hw_info *wlc, tx_status_t *txs, - u32 s2); -static bool wlc_bmac_txstatus_corerev4(struct wlc_hw_info *wlc); -static bool wlc_bmac_txstatus(struct wlc_hw_info *wlc, bool bound, bool *fatal); -static bool wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound); - -/* used by wlc_down() */ -static void wlc_flushqueues(struct wlc_info *wlc); - -static void wlc_write_mhf(struct wlc_hw_info *wlc_hw, u16 *mhfs); -static void wlc_mctrl_reset(struct wlc_hw_info *wlc_hw); -static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw); - -/* Low Level Prototypes */ -static u16 wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, - u32 sel); -static void wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset, - u16 v, u32 sel); -static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme); -static void wlc_bmac_detach_dmapio(struct wlc_hw_info *wlc_hw); -static void wlc_ucode_bsinit(struct wlc_hw_info *wlc_hw); -static bool wlc_validboardtype(struct wlc_hw_info *wlc); -static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw); -static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw); -static void wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init); -static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw); -static void wlc_ucode_mute_override_set(struct wlc_hw_info *wlc_hw); -static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw); -static u32 wlc_wlintrsoff(struct wlc_info *wlc); -static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask); -static void wlc_gpio_init(struct wlc_info *wlc); -static void wlc_write_hw_bcntemplate0(struct wlc_hw_info *wlc_hw, void *bcn, - int len); -static void wlc_write_hw_bcntemplate1(struct wlc_hw_info *wlc_hw, void *bcn, - int len); -static void wlc_bmac_bsinit(struct wlc_info *wlc, chanspec_t chanspec); -static u32 wlc_setband_inact(struct wlc_info *wlc, uint bandunit); -static void wlc_bmac_setband(struct wlc_hw_info *wlc_hw, uint bandunit, - chanspec_t chanspec); -static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw, - bool shortslot); -static void wlc_upd_ofdm_pctl1_table(struct wlc_hw_info *wlc_hw); -static u16 wlc_bmac_ofdm_ratetable_offset(struct wlc_hw_info *wlc_hw, - u8 rate); - -/* === Low Level functions === */ - -void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot) -{ - wlc_hw->shortslot = shortslot; - - if (BAND_2G(wlc_hw->band->bandtype) && wlc_hw->up) { - wlc_suspend_mac_and_wait(wlc_hw->wlc); - wlc_bmac_update_slot_timing(wlc_hw, shortslot); - wlc_enable_mac(wlc_hw->wlc); - } -} - -/* - * Update the slot timing for standard 11b/g (20us slots) - * or shortslot 11g (9us slots) - * The PSM needs to be suspended for this call. - */ -static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw, - bool shortslot) -{ - struct osl_info *osh; - d11regs_t *regs; - - osh = wlc_hw->osh; - regs = wlc_hw->regs; - - if (shortslot) { - /* 11g short slot: 11a timing */ - W_REG(osh, ®s->ifs_slot, 0x0207); /* APHY_SLOT_TIME */ - wlc_bmac_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME); - } else { - /* 11g long slot: 11b timing */ - W_REG(osh, ®s->ifs_slot, 0x0212); /* BPHY_SLOT_TIME */ - wlc_bmac_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME); - } -} - -static void WLBANDINITFN(wlc_ucode_bsinit) (struct wlc_hw_info *wlc_hw) -{ - /* init microcode host flags */ - wlc_write_mhf(wlc_hw, wlc_hw->band->mhfs); - - /* do band-specific ucode IHR, SHM, and SCR inits */ - if (D11REV_IS(wlc_hw->corerev, 23)) { - if (WLCISNPHY(wlc_hw->band)) { - wlc_write_inits(wlc_hw, d11n0bsinitvals16); - } else { - WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); - } - } else { - if (D11REV_IS(wlc_hw->corerev, 24)) { - if (WLCISLCNPHY(wlc_hw->band)) { - wlc_write_inits(wlc_hw, d11lcn0bsinitvals24); - } else - WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, - wlc_hw->corerev); - } else { - WL_ERROR("%s: wl%d: unsupported corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); - } - } -} - -/* switch to new band but leave it inactive */ -static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - u32 macintmask; - u32 tmp; - - WL_TRACE("wl%d: wlc_setband_inact\n", wlc_hw->unit); - - ASSERT(bandunit != wlc_hw->band->bandunit); - ASSERT(si_iscoreup(wlc_hw->sih)); - ASSERT((R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol) & MCTL_EN_MAC) == - 0); - - /* disable interrupts */ - macintmask = wl_intrsoff(wlc->wl); - - /* radio off */ - wlc_phy_switch_radio(wlc_hw->band->pi, OFF); - - ASSERT(wlc_hw->clk); - - if (D11REV_LT(wlc_hw->corerev, 17)) - tmp = R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol); - - wlc_bmac_core_phy_clk(wlc_hw, OFF); - - wlc_setxband(wlc_hw, bandunit); - - return macintmask; -} - -/* Process received frames */ -/* - * Return true if more frames need to be processed. false otherwise. - * Param 'bound' indicates max. # frames to process before break out. - */ -static bool BCMFASTPATH -wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound) -{ - struct sk_buff *p; - struct sk_buff *head = NULL; - struct sk_buff *tail = NULL; - uint n = 0; - uint bound_limit = bound ? wlc_hw->wlc->pub->tunables->rxbnd : -1; - u32 tsf_h, tsf_l; - wlc_d11rxhdr_t *wlc_rxhdr = NULL; - - WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); - /* gather received frames */ - while ((p = dma_rx(wlc_hw->di[fifo]))) { - - if (!tail) - head = tail = p; - else { - tail->prev = p; - tail = p; - } - - /* !give others some time to run! */ - if (++n >= bound_limit) - break; - } - - /* get the TSF REG reading */ - wlc_bmac_read_tsf(wlc_hw, &tsf_l, &tsf_h); - - /* post more rbufs */ - dma_rxfill(wlc_hw->di[fifo]); - - /* process each frame */ - while ((p = head) != NULL) { - head = head->prev; - p->prev = NULL; - - /* record the tsf_l in wlc_rxd11hdr */ - wlc_rxhdr = (wlc_d11rxhdr_t *) p->data; - wlc_rxhdr->tsf_l = htol32(tsf_l); - - /* compute the RSSI from d11rxhdr and record it in wlc_rxd11hr */ - wlc_phy_rssi_compute(wlc_hw->band->pi, wlc_rxhdr); - - wlc_recv(wlc_hw->wlc, p); - } - - return n >= bound_limit; -} - -/* second-level interrupt processing - * Return true if another dpc needs to be re-scheduled. false otherwise. - * Param 'bounded' indicates if applicable loops should be bounded. - */ -bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) -{ - u32 macintstatus; - struct wlc_hw_info *wlc_hw = wlc->hw; - d11regs_t *regs = wlc_hw->regs; - bool fatal = false; - - if (DEVICEREMOVED(wlc)) { - WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); - wl_down(wlc->wl); - return false; - } - - /* grab and clear the saved software intstatus bits */ - macintstatus = wlc->macintstatus; - wlc->macintstatus = 0; - - WL_TRACE("wl%d: wlc_dpc: macintstatus 0x%x\n", - wlc_hw->unit, macintstatus); - - if (macintstatus & MI_PRQ) { - /* Process probe request FIFO */ - ASSERT(0 && "PRQ Interrupt in non-MBSS"); - } - - /* BCN template is available */ - /* ZZZ: Use AP_ACTIVE ? */ - if (AP_ENAB(wlc->pub) && (!APSTA_ENAB(wlc->pub) || wlc->aps_associated) - && (macintstatus & MI_BCNTPL)) { - wlc_update_beacon(wlc); - } - - /* PMQ entry addition */ - if (macintstatus & MI_PMQ) { - } - - /* tx status */ - if (macintstatus & MI_TFS) { - if (wlc_bmac_txstatus(wlc->hw, bounded, &fatal)) - wlc->macintstatus |= MI_TFS; - if (fatal) { - WL_ERROR("MI_TFS: fatal\n"); - goto fatal; - } - } - - if (macintstatus & (MI_TBTT | MI_DTIM_TBTT)) - wlc_tbtt(wlc, regs); - - /* ATIM window end */ - if (macintstatus & MI_ATIMWINEND) { - WL_TRACE("wlc_isr: end of ATIM window\n"); - - OR_REG(wlc_hw->osh, ®s->maccommand, wlc->qvalid); - wlc->qvalid = 0; - } - - /* phy tx error */ - if (macintstatus & MI_PHYTXERR) { - WLCNTINCR(wlc->pub->_cnt->txphyerr); - } - - /* received data or control frame, MI_DMAINT is indication of RX_FIFO interrupt */ - if (macintstatus & MI_DMAINT) { - if (wlc_bmac_recv(wlc_hw, RX_FIFO, bounded)) { - wlc->macintstatus |= MI_DMAINT; - } - } - - /* TX FIFO suspend/flush completion */ - if (macintstatus & MI_TXSTOP) { - if (wlc_bmac_tx_fifo_suspended(wlc_hw, TX_DATA_FIFO)) { - /* WL_ERROR("dpc: fifo_suspend_comlete\n"); */ - } - } - - /* noise sample collected */ - if (macintstatus & MI_BG_NOISE) { - wlc_phy_noise_sample_intr(wlc_hw->band->pi); - } - - if (macintstatus & MI_GP0) { - WL_ERROR("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", - wlc_hw->unit, wlc_hw->now); - - printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", - __func__, wlc_hw->sih->chip, - wlc_hw->sih->chiprev); - - WLCNTINCR(wlc->pub->_cnt->psmwds); - - /* big hammer */ - wl_init(wlc->wl); - } - - /* gptimer timeout */ - if (macintstatus & MI_TO) { - W_REG(wlc_hw->osh, ®s->gptimer, 0); - } - - if (macintstatus & MI_RFDISABLE) { -#if defined(BCMDBG) - u32 rfd = R_REG(wlc_hw->osh, ®s->phydebug) & PDBG_RFD; -#endif - - WL_ERROR("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n", - wlc_hw->unit, rfd); - - WLCNTINCR(wlc->pub->_cnt->rfdisable); - } - - /* send any enq'd tx packets. Just makes sure to jump start tx */ - if (!pktq_empty(&wlc->active_queue->q)) - wlc_send_q(wlc, wlc->active_queue); - - ASSERT(wlc_ps_check(wlc)); - - /* make sure the bound indication and the implementation are in sync */ - ASSERT(bounded == true || wlc->macintstatus == 0); - - /* it isn't done and needs to be resched if macintstatus is non-zero */ - return wlc->macintstatus != 0; - - fatal: - wl_init(wlc->wl); - return wlc->macintstatus != 0; -} - -/* common low-level watchdog code */ -void wlc_bmac_watchdog(void *arg) -{ - struct wlc_info *wlc = (struct wlc_info *) arg; - struct wlc_hw_info *wlc_hw = wlc->hw; - - WL_TRACE("wl%d: wlc_bmac_watchdog\n", wlc_hw->unit); - - if (!wlc_hw->up) - return; - - /* increment second count */ - wlc_hw->now++; - - /* Check for FIFO error interrupts */ - wlc_bmac_fifoerrors(wlc_hw); - - /* make sure RX dma has buffers */ - dma_rxfill(wlc->hw->di[RX_FIFO]); - if (D11REV_IS(wlc_hw->corerev, 4)) { - dma_rxfill(wlc->hw->di[RX_TXSTATUS_FIFO]); - } - - wlc_phy_watchdog(wlc_hw->band->pi); -} - -void -wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, - bool mute, struct txpwr_limits *txpwr) -{ - uint bandunit; - - WL_TRACE("wl%d: wlc_bmac_set_chanspec 0x%x\n", - wlc_hw->unit, chanspec); - - wlc_hw->chanspec = chanspec; - - /* Switch bands if necessary */ - if (NBANDS_HW(wlc_hw) > 1) { - bandunit = CHSPEC_WLCBANDUNIT(chanspec); - if (wlc_hw->band->bandunit != bandunit) { - /* wlc_bmac_setband disables other bandunit, - * use light band switch if not up yet - */ - if (wlc_hw->up) { - wlc_phy_chanspec_radio_set(wlc_hw-> - bandstate[bandunit]-> - pi, chanspec); - wlc_bmac_setband(wlc_hw, bandunit, chanspec); - } else { - wlc_setxband(wlc_hw, bandunit); - } - } - } - - wlc_phy_initcal_enable(wlc_hw->band->pi, !mute); - - if (!wlc_hw->up) { - if (wlc_hw->clk) - wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, - chanspec); - wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec); - } else { - wlc_phy_chanspec_set(wlc_hw->band->pi, chanspec); - wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec); - - /* Update muting of the channel */ - wlc_bmac_mute(wlc_hw, mute, 0); - } -} - -int wlc_bmac_revinfo_get(struct wlc_hw_info *wlc_hw, - wlc_bmac_revinfo_t *revinfo) -{ - si_t *sih = wlc_hw->sih; - uint idx; - - revinfo->vendorid = wlc_hw->vendorid; - revinfo->deviceid = wlc_hw->deviceid; - - revinfo->boardrev = wlc_hw->boardrev; - revinfo->corerev = wlc_hw->corerev; - revinfo->sromrev = wlc_hw->sromrev; - revinfo->chiprev = sih->chiprev; - revinfo->chip = sih->chip; - revinfo->chippkg = sih->chippkg; - revinfo->boardtype = sih->boardtype; - revinfo->boardvendor = sih->boardvendor; - revinfo->bustype = sih->bustype; - revinfo->buscoretype = sih->buscoretype; - revinfo->buscorerev = sih->buscorerev; - revinfo->issim = sih->issim; - - revinfo->nbands = NBANDS_HW(wlc_hw); - - for (idx = 0; idx < NBANDS_HW(wlc_hw); idx++) { - wlc_hwband_t *band = wlc_hw->bandstate[idx]; - revinfo->band[idx].bandunit = band->bandunit; - revinfo->band[idx].bandtype = band->bandtype; - revinfo->band[idx].phytype = band->phytype; - revinfo->band[idx].phyrev = band->phyrev; - revinfo->band[idx].radioid = band->radioid; - revinfo->band[idx].radiorev = band->radiorev; - revinfo->band[idx].abgphy_encore = band->abgphy_encore; - revinfo->band[idx].anarev = 0; - - } - return 0; -} - -int wlc_bmac_state_get(struct wlc_hw_info *wlc_hw, wlc_bmac_state_t *state) -{ - state->machwcap = wlc_hw->machwcap; - - return 0; -} - -static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) -{ - uint i; - char name[8]; - /* ucode host flag 2 needed for pio mode, independent of band and fifo */ - u16 pio_mhf2 = 0; - struct wlc_hw_info *wlc_hw = wlc->hw; - uint unit = wlc_hw->unit; - wlc_tunables_t *tune = wlc->pub->tunables; - - /* name and offsets for dma_attach */ - snprintf(name, sizeof(name), "wl%d", unit); - - if (wlc_hw->di[0] == 0) { /* Init FIFOs */ - uint addrwidth; - int dma_attach_err = 0; - struct osl_info *osh = wlc_hw->osh; - - /* Find out the DMA addressing capability and let OS know - * All the channels within one DMA core have 'common-minimum' same - * capability - */ - addrwidth = - dma_addrwidth(wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 0)); - - if (!wl_alloc_dma_resources(wlc_hw->wlc->wl, addrwidth)) { - WL_ERROR("wl%d: wlc_attach: alloc_dma_resources failed\n", - unit); - return false; - } - - /* - * FIFO 0 - * TX: TX_AC_BK_FIFO (TX AC Background data packets) - * RX: RX_FIFO (RX data packets) - */ - ASSERT(TX_AC_BK_FIFO == 0); - ASSERT(RX_FIFO == 0); - wlc_hw->di[0] = dma_attach(osh, name, wlc_hw->sih, - (wme ? DMAREG(wlc_hw, DMA_TX, 0) : - NULL), DMAREG(wlc_hw, DMA_RX, 0), - (wme ? tune->ntxd : 0), tune->nrxd, - tune->rxbufsz, -1, tune->nrxbufpost, - WL_HWRXOFF, &wl_msg_level); - dma_attach_err |= (NULL == wlc_hw->di[0]); - - /* - * FIFO 1 - * TX: TX_AC_BE_FIFO (TX AC Best-Effort data packets) - * (legacy) TX_DATA_FIFO (TX data packets) - * RX: UNUSED - */ - ASSERT(TX_AC_BE_FIFO == 1); - ASSERT(TX_DATA_FIFO == 1); - wlc_hw->di[1] = dma_attach(osh, name, wlc_hw->sih, - DMAREG(wlc_hw, DMA_TX, 1), NULL, - tune->ntxd, 0, 0, -1, 0, 0, - &wl_msg_level); - dma_attach_err |= (NULL == wlc_hw->di[1]); - - /* - * FIFO 2 - * TX: TX_AC_VI_FIFO (TX AC Video data packets) - * RX: UNUSED - */ - ASSERT(TX_AC_VI_FIFO == 2); - wlc_hw->di[2] = dma_attach(osh, name, wlc_hw->sih, - DMAREG(wlc_hw, DMA_TX, 2), NULL, - tune->ntxd, 0, 0, -1, 0, 0, - &wl_msg_level); - dma_attach_err |= (NULL == wlc_hw->di[2]); - /* - * FIFO 3 - * TX: TX_AC_VO_FIFO (TX AC Voice data packets) - * (legacy) TX_CTL_FIFO (TX control & mgmt packets) - * RX: RX_TXSTATUS_FIFO (transmit-status packets) - * for corerev < 5 only - */ - ASSERT(TX_AC_VO_FIFO == 3); - ASSERT(TX_CTL_FIFO == 3); - if (D11REV_IS(wlc_hw->corerev, 4)) { - ASSERT(RX_TXSTATUS_FIFO == 3); - wlc_hw->di[3] = dma_attach(osh, name, wlc_hw->sih, - DMAREG(wlc_hw, DMA_TX, 3), - DMAREG(wlc_hw, DMA_RX, 3), - tune->ntxd, tune->nrxd, - sizeof(tx_status_t), -1, - tune->nrxbufpost, 0, - &wl_msg_level); - dma_attach_err |= (NULL == wlc_hw->di[3]); - } else { - wlc_hw->di[3] = dma_attach(osh, name, wlc_hw->sih, - DMAREG(wlc_hw, DMA_TX, 3), - NULL, tune->ntxd, 0, 0, -1, - 0, 0, &wl_msg_level); - dma_attach_err |= (NULL == wlc_hw->di[3]); - } -/* Cleaner to leave this as if with AP defined */ - - if (dma_attach_err) { - WL_ERROR("wl%d: wlc_attach: dma_attach failed\n", unit); - return false; - } - - /* get pointer to dma engine tx flow control variable */ - for (i = 0; i < NFIFO; i++) - if (wlc_hw->di[i]) - wlc_hw->txavail[i] = - (uint *) dma_getvar(wlc_hw->di[i], - "&txavail"); - } - - /* initial ucode host flags */ - wlc_mhfdef(wlc, wlc_hw->band->mhfs, pio_mhf2); - - return true; -} - -static void wlc_bmac_detach_dmapio(struct wlc_hw_info *wlc_hw) -{ - uint j; - - for (j = 0; j < NFIFO; j++) { - if (wlc_hw->di[j]) { - dma_detach(wlc_hw->di[j]); - wlc_hw->di[j] = NULL; - } - } -} - -/* low level attach - * run backplane attach, init nvram - * run phy attach - * initialize software state for each core and band - * put the whole chip in reset(driver down state), no clock - */ -int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, - bool piomode, struct osl_info *osh, void *regsva, - uint bustype, void *btparam) -{ - struct wlc_hw_info *wlc_hw; - d11regs_t *regs; - char *macaddr = NULL; - char *vars; - uint err = 0; - uint j; - bool wme = false; - shared_phy_params_t sha_params; - - WL_TRACE("wl%d: wlc_bmac_attach: vendor 0x%x device 0x%x\n", - unit, vendor, device); - - ASSERT(sizeof(wlc_d11rxhdr_t) <= WL_HWRXOFF); - - wme = true; - - wlc_hw = wlc->hw; - wlc_hw->wlc = wlc; - wlc_hw->unit = unit; - wlc_hw->osh = osh; - wlc_hw->band = wlc_hw->bandstate[0]; - wlc_hw->_piomode = piomode; - - /* populate struct wlc_hw_info with default values */ - wlc_bmac_info_init(wlc_hw); - - /* - * Do the hardware portion of the attach. - * Also initialize software state that depends on the particular hardware - * we are running. - */ - wlc_hw->sih = si_attach((uint) device, osh, regsva, bustype, btparam, - &wlc_hw->vars, &wlc_hw->vars_size); - if (wlc_hw->sih == NULL) { - WL_ERROR("wl%d: wlc_bmac_attach: si_attach failed\n", unit); - err = 11; - goto fail; - } - vars = wlc_hw->vars; - - /* - * Get vendid/devid nvram overwrites, which could be different - * than those the BIOS recognizes for devices on PCMCIA_BUS, - * SDIO_BUS, and SROMless devices on PCI_BUS. - */ -#ifdef BCMBUSTYPE - bustype = BCMBUSTYPE; -#endif - if (bustype != SI_BUS) { - char *var; - - var = getvar(vars, "vendid"); - if (var) { - vendor = (u16) simple_strtoul(var, NULL, 0); - WL_ERROR("Overriding vendor id = 0x%x\n", vendor); - } - var = getvar(vars, "devid"); - if (var) { - u16 devid = (u16) simple_strtoul(var, NULL, 0); - if (devid != 0xffff) { - device = devid; - WL_ERROR("Overriding device id = 0x%x\n", - device); - } - } - - /* verify again the device is supported */ - if (!wlc_chipmatch(vendor, device)) { - WL_ERROR("wl%d: wlc_bmac_attach: Unsupported vendor/device (0x%x/0x%x)\n", - unit, vendor, device); - err = 12; - goto fail; - } - } - - wlc_hw->vendorid = vendor; - wlc_hw->deviceid = device; - - /* set bar0 window to point at D11 core */ - wlc_hw->regs = (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, 0); - wlc_hw->corerev = si_corerev(wlc_hw->sih); - - regs = wlc_hw->regs; - - wlc->regs = wlc_hw->regs; - - /* validate chip, chiprev and corerev */ - if (!wlc_isgoodchip(wlc_hw)) { - err = 13; - goto fail; - } - - /* initialize power control registers */ - si_clkctl_init(wlc_hw->sih); - - /* request fastclock and force fastclock for the rest of attach - * bring the d11 core out of reset. - * For PMU chips, the first wlc_clkctl_clk is no-op since core-clk is still false; - * But it will be called again inside wlc_corereset, after d11 is out of reset. - */ - wlc_clkctl_clk(wlc_hw, CLK_FAST); - wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); - - if (!wlc_bmac_validate_chip_access(wlc_hw)) { - WL_ERROR("wl%d: wlc_bmac_attach: validate_chip_access failed\n", - unit); - err = 14; - goto fail; - } - - /* get the board rev, used just below */ - j = getintvar(vars, "boardrev"); - /* promote srom boardrev of 0xFF to 1 */ - if (j == BOARDREV_PROMOTABLE) - j = BOARDREV_PROMOTED; - wlc_hw->boardrev = (u16) j; - if (!wlc_validboardtype(wlc_hw)) { - WL_ERROR("wl%d: wlc_bmac_attach: Unsupported Broadcom board type (0x%x)" " or revision level (0x%x)\n", - unit, wlc_hw->sih->boardtype, wlc_hw->boardrev); - err = 15; - goto fail; - } - wlc_hw->sromrev = (u8) getintvar(vars, "sromrev"); - wlc_hw->boardflags = (u32) getintvar(vars, "boardflags"); - wlc_hw->boardflags2 = (u32) getintvar(vars, "boardflags2"); - - if (D11REV_LE(wlc_hw->corerev, 4) - || (wlc_hw->boardflags & BFL_NOPLLDOWN)) - wlc_bmac_pllreq(wlc_hw, true, WLC_PLLREQ_SHARED); - - if ((wlc_hw->sih->bustype == PCI_BUS) - && (si_pci_war16165(wlc_hw->sih))) - wlc->war16165 = true; - - /* check device id(srom, nvram etc.) to set bands */ - if (wlc_hw->deviceid == BCM43224_D11N_ID) { - /* Dualband boards */ - wlc_hw->_nbands = 2; - } else - wlc_hw->_nbands = 1; - - if ((wlc_hw->sih->chip == BCM43225_CHIP_ID)) - wlc_hw->_nbands = 1; - - /* BMAC_NOTE: remove init of pub values when wlc_attach() unconditionally does the - * init of these values - */ - wlc->vendorid = wlc_hw->vendorid; - wlc->deviceid = wlc_hw->deviceid; - wlc->pub->sih = wlc_hw->sih; - wlc->pub->corerev = wlc_hw->corerev; - wlc->pub->sromrev = wlc_hw->sromrev; - wlc->pub->boardrev = wlc_hw->boardrev; - wlc->pub->boardflags = wlc_hw->boardflags; - wlc->pub->boardflags2 = wlc_hw->boardflags2; - wlc->pub->_nbands = wlc_hw->_nbands; - - wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc); - - if (wlc_hw->physhim == NULL) { - WL_ERROR("wl%d: wlc_bmac_attach: wlc_phy_shim_attach failed\n", - unit); - err = 25; - goto fail; - } - - /* pass all the parameters to wlc_phy_shared_attach in one struct */ - sha_params.osh = osh; - sha_params.sih = wlc_hw->sih; - sha_params.physhim = wlc_hw->physhim; - sha_params.unit = unit; - sha_params.corerev = wlc_hw->corerev; - sha_params.vars = vars; - sha_params.vid = wlc_hw->vendorid; - sha_params.did = wlc_hw->deviceid; - sha_params.chip = wlc_hw->sih->chip; - sha_params.chiprev = wlc_hw->sih->chiprev; - sha_params.chippkg = wlc_hw->sih->chippkg; - sha_params.sromrev = wlc_hw->sromrev; - sha_params.boardtype = wlc_hw->sih->boardtype; - sha_params.boardrev = wlc_hw->boardrev; - sha_params.boardvendor = wlc_hw->sih->boardvendor; - sha_params.boardflags = wlc_hw->boardflags; - sha_params.boardflags2 = wlc_hw->boardflags2; - sha_params.bustype = wlc_hw->sih->bustype; - sha_params.buscorerev = wlc_hw->sih->buscorerev; - - /* alloc and save pointer to shared phy state area */ - wlc_hw->phy_sh = wlc_phy_shared_attach(&sha_params); - if (!wlc_hw->phy_sh) { - err = 16; - goto fail; - } - - /* initialize software state for each core and band */ - for (j = 0; j < NBANDS_HW(wlc_hw); j++) { - /* - * band0 is always 2.4Ghz - * band1, if present, is 5Ghz - */ - - /* So if this is a single band 11a card, use band 1 */ - if (IS_SINGLEBAND_5G(wlc_hw->deviceid)) - j = BAND_5G_INDEX; - - wlc_setxband(wlc_hw, j); - - wlc_hw->band->bandunit = j; - wlc_hw->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G; - wlc->band->bandunit = j; - wlc->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G; - wlc->core->coreidx = si_coreidx(wlc_hw->sih); - - if (D11REV_GE(wlc_hw->corerev, 13)) { - wlc_hw->machwcap = R_REG(wlc_hw->osh, ®s->machwcap); - wlc_hw->machwcap_backup = wlc_hw->machwcap; - } - - /* init tx fifo size */ - ASSERT((wlc_hw->corerev - XMTFIFOTBL_STARTREV) < - ARRAY_SIZE(xmtfifo_sz)); - wlc_hw->xmtfifo_sz = - xmtfifo_sz[(wlc_hw->corerev - XMTFIFOTBL_STARTREV)]; - - /* Get a phy for this band */ - wlc_hw->band->pi = wlc_phy_attach(wlc_hw->phy_sh, - (void *)regs, wlc_hw->band->bandtype, vars); - if (wlc_hw->band->pi == NULL) { - WL_ERROR("wl%d: wlc_bmac_attach: wlc_phy_attach failed\n", - unit); - err = 17; - goto fail; - } - - wlc_phy_machwcap_set(wlc_hw->band->pi, wlc_hw->machwcap); - - wlc_phy_get_phyversion(wlc_hw->band->pi, &wlc_hw->band->phytype, - &wlc_hw->band->phyrev, - &wlc_hw->band->radioid, - &wlc_hw->band->radiorev); - wlc_hw->band->abgphy_encore = - wlc_phy_get_encore(wlc_hw->band->pi); - wlc->band->abgphy_encore = wlc_phy_get_encore(wlc_hw->band->pi); - wlc_hw->band->core_flags = - wlc_phy_get_coreflags(wlc_hw->band->pi); - - /* verify good phy_type & supported phy revision */ - if (WLCISNPHY(wlc_hw->band)) { - if (NCONF_HAS(wlc_hw->band->phyrev)) - goto good_phy; - else - goto bad_phy; - } else if (WLCISLCNPHY(wlc_hw->band)) { - if (LCNCONF_HAS(wlc_hw->band->phyrev)) - goto good_phy; - else - goto bad_phy; - } else { - bad_phy: - WL_ERROR("wl%d: wlc_bmac_attach: unsupported phy type/rev (%d/%d)\n", - unit, - wlc_hw->band->phytype, wlc_hw->band->phyrev); - err = 18; - goto fail; - } - - good_phy: - /* BMAC_NOTE: wlc->band->pi should not be set below and should be done in the - * high level attach. However we can not make that change until all low level access - * is changed to wlc_hw->band->pi. Instead do the wlc->band->pi init below, keeping - * wlc_hw->band->pi as well for incremental update of low level fns, and cut over - * low only init when all fns updated. - */ - wlc->band->pi = wlc_hw->band->pi; - wlc->band->phytype = wlc_hw->band->phytype; - wlc->band->phyrev = wlc_hw->band->phyrev; - wlc->band->radioid = wlc_hw->band->radioid; - wlc->band->radiorev = wlc_hw->band->radiorev; - - /* default contention windows size limits */ - wlc_hw->band->CWmin = APHY_CWMIN; - wlc_hw->band->CWmax = PHY_CWMAX; - - if (!wlc_bmac_attach_dmapio(wlc, j, wme)) { - err = 19; - goto fail; - } - } - - /* disable core to match driver "down" state */ - wlc_coredisable(wlc_hw); - - /* Match driver "down" state */ - if (wlc_hw->sih->bustype == PCI_BUS) - si_pci_down(wlc_hw->sih); - - /* register sb interrupt callback functions */ - si_register_intr_callback(wlc_hw->sih, (void *)wlc_wlintrsoff, - (void *)wlc_wlintrsrestore, NULL, wlc); - - /* turn off pll and xtal to match driver "down" state */ - wlc_bmac_xtal(wlc_hw, OFF); - - /* ********************************************************************* - * The hardware is in the DOWN state at this point. D11 core - * or cores are in reset with clocks off, and the board PLLs - * are off if possible. - * - * Beyond this point, wlc->sbclk == false and chip registers - * should not be touched. - ********************************************************************* - */ - - /* init etheraddr state variables */ - macaddr = wlc_get_macaddr(wlc_hw); - if (macaddr == NULL) { - WL_ERROR("wl%d: wlc_bmac_attach: macaddr not found\n", unit); - err = 21; - goto fail; - } - bcm_ether_atoe(macaddr, wlc_hw->etheraddr); - if (is_broadcast_ether_addr(wlc_hw->etheraddr) || - is_zero_ether_addr(wlc_hw->etheraddr)) { - WL_ERROR("wl%d: wlc_bmac_attach: bad macaddr %s\n", - unit, macaddr); - err = 22; - goto fail; - } - - WL_ERROR("%s:: deviceid 0x%x nbands %d board 0x%x macaddr: %s\n", - __func__, wlc_hw->deviceid, wlc_hw->_nbands, - wlc_hw->sih->boardtype, macaddr); - - return err; - - fail: - WL_ERROR("wl%d: wlc_bmac_attach: failed with err %d\n", unit, err); - return err; -} - -/* - * Initialize wlc_info default values ... - * may get overrides later in this function - * BMAC_NOTES, move low out and resolve the dangling ones - */ -void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw) -{ - struct wlc_info *wlc = wlc_hw->wlc; - - /* set default sw macintmask value */ - wlc->defmacintmask = DEF_MACINTMASK; - - /* various 802.11g modes */ - wlc_hw->shortslot = false; - - wlc_hw->SFBL = RETRY_SHORT_FB; - wlc_hw->LFBL = RETRY_LONG_FB; - - /* default mac retry limits */ - wlc_hw->SRL = RETRY_SHORT_DEF; - wlc_hw->LRL = RETRY_LONG_DEF; - wlc_hw->chanspec = CH20MHZ_CHSPEC(1); -} - -/* - * low level detach - */ -int wlc_bmac_detach(struct wlc_info *wlc) -{ - uint i; - wlc_hwband_t *band; - struct wlc_hw_info *wlc_hw = wlc->hw; - int callbacks; - - callbacks = 0; - - if (wlc_hw->sih) { - /* detach interrupt sync mechanism since interrupt is disabled and per-port - * interrupt object may has been freed. this must be done before sb core switch - */ - si_deregister_intr_callback(wlc_hw->sih); - - if (wlc_hw->sih->bustype == PCI_BUS) - si_pci_sleep(wlc_hw->sih); - } - - wlc_bmac_detach_dmapio(wlc_hw); - - band = wlc_hw->band; - for (i = 0; i < NBANDS_HW(wlc_hw); i++) { - if (band->pi) { - /* Detach this band's phy */ - wlc_phy_detach(band->pi); - band->pi = NULL; - } - band = wlc_hw->bandstate[OTHERBANDUNIT(wlc)]; - } - - /* Free shared phy state */ - wlc_phy_shared_detach(wlc_hw->phy_sh); - - wlc_phy_shim_detach(wlc_hw->physhim); - - /* free vars */ - if (wlc_hw->vars) { - kfree(wlc_hw->vars); - wlc_hw->vars = NULL; - } - - if (wlc_hw->sih) { - si_detach(wlc_hw->sih); - wlc_hw->sih = NULL; - } - - return callbacks; - -} - -void wlc_bmac_reset(struct wlc_hw_info *wlc_hw) -{ - WL_TRACE("wl%d: wlc_bmac_reset\n", wlc_hw->unit); - - WLCNTINCR(wlc_hw->wlc->pub->_cnt->reset); - - /* reset the core */ - if (!DEVICEREMOVED(wlc_hw->wlc)) - wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); - - /* purge the dma rings */ - wlc_flushqueues(wlc_hw->wlc); - - wlc_reset_bmac_done(wlc_hw->wlc); -} - -void -wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, - bool mute) { - u32 macintmask; - bool fastclk; - struct wlc_info *wlc = wlc_hw->wlc; - - WL_TRACE("wl%d: wlc_bmac_init\n", wlc_hw->unit); - - /* request FAST clock if not on */ - fastclk = wlc_hw->forcefastclk; - if (!fastclk) - wlc_clkctl_clk(wlc_hw, CLK_FAST); - - /* disable interrupts */ - macintmask = wl_intrsoff(wlc->wl); - - /* set up the specified band and chanspec */ - wlc_setxband(wlc_hw, CHSPEC_WLCBANDUNIT(chanspec)); - wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec); - - /* do one-time phy inits and calibration */ - wlc_phy_cal_init(wlc_hw->band->pi); - - /* core-specific initialization */ - wlc_coreinit(wlc); - - /* suspend the tx fifos and mute the phy for preism cac time */ - if (mute) - wlc_bmac_mute(wlc_hw, ON, PHY_MUTE_FOR_PREISM); - - /* band-specific inits */ - wlc_bmac_bsinit(wlc, chanspec); - - /* restore macintmask */ - wl_intrsrestore(wlc->wl, macintmask); - - /* seed wake_override with WLC_WAKE_OVERRIDE_MACSUSPEND since the mac is suspended - * and wlc_enable_mac() will clear this override bit. - */ - mboolset(wlc_hw->wake_override, WLC_WAKE_OVERRIDE_MACSUSPEND); - - /* - * initialize mac_suspend_depth to 1 to match ucode initial suspended state - */ - wlc_hw->mac_suspend_depth = 1; - - /* restore the clk */ - if (!fastclk) - wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); -} - -int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw) -{ - uint coremask; - - WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); - - ASSERT(wlc_hw->wlc->pub->hw_up && wlc_hw->wlc->macintmask == 0); - - /* - * Enable pll and xtal, initialize the power control registers, - * and force fastclock for the remainder of wlc_up(). - */ - wlc_bmac_xtal(wlc_hw, ON); - si_clkctl_init(wlc_hw->sih); - wlc_clkctl_clk(wlc_hw, CLK_FAST); - - /* - * Configure pci/pcmcia here instead of in wlc_attach() - * to allow mfg hotswap: down, hotswap (chip power cycle), up. - */ - coremask = (1 << wlc_hw->wlc->core->coreidx); - - if (wlc_hw->sih->bustype == PCI_BUS) - si_pci_setup(wlc_hw->sih, coremask); - - ASSERT(si_coreid(wlc_hw->sih) == D11_CORE_ID); - - /* - * Need to read the hwradio status here to cover the case where the system - * is loaded with the hw radio disabled. We do not want to bring the driver up in this case. - */ - if (wlc_bmac_radio_read_hwdisabled(wlc_hw)) { - /* put SB PCI in down state again */ - if (wlc_hw->sih->bustype == PCI_BUS) - si_pci_down(wlc_hw->sih); - wlc_bmac_xtal(wlc_hw, OFF); - return BCME_RADIOOFF; - } - - if (wlc_hw->sih->bustype == PCI_BUS) - si_pci_up(wlc_hw->sih); - - /* reset the d11 core */ - wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); - - return 0; -} - -int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw) -{ - WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); - - wlc_hw->up = true; - wlc_phy_hw_state_upd(wlc_hw->band->pi, true); - - /* FULLY enable dynamic power control and d11 core interrupt */ - wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); - ASSERT(wlc_hw->wlc->macintmask == 0); - wl_intrson(wlc_hw->wlc->wl); - return 0; -} - -int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw) -{ - bool dev_gone; - uint callbacks = 0; - - WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); - - if (!wlc_hw->up) - return callbacks; - - dev_gone = DEVICEREMOVED(wlc_hw->wlc); - - /* disable interrupts */ - if (dev_gone) - wlc_hw->wlc->macintmask = 0; - else { - /* now disable interrupts */ - wl_intrsoff(wlc_hw->wlc->wl); - - /* ensure we're running on the pll clock again */ - wlc_clkctl_clk(wlc_hw, CLK_FAST); - } - /* down phy at the last of this stage */ - callbacks += wlc_phy_down(wlc_hw->band->pi); - - return callbacks; -} - -int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw) -{ - uint callbacks = 0; - bool dev_gone; - - WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); - - if (!wlc_hw->up) - return callbacks; - - wlc_hw->up = false; - wlc_phy_hw_state_upd(wlc_hw->band->pi, false); - - dev_gone = DEVICEREMOVED(wlc_hw->wlc); - - if (dev_gone) { - wlc_hw->sbclk = false; - wlc_hw->clk = false; - wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); - - /* reclaim any posted packets */ - wlc_flushqueues(wlc_hw->wlc); - } else { - - /* Reset and disable the core */ - if (si_iscoreup(wlc_hw->sih)) { - if (R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol) & - MCTL_EN_MAC) - wlc_suspend_mac_and_wait(wlc_hw->wlc); - callbacks += wl_reset(wlc_hw->wlc->wl); - wlc_coredisable(wlc_hw); - } - - /* turn off primary xtal and pll */ - if (!wlc_hw->noreset) { - if (wlc_hw->sih->bustype == PCI_BUS) - si_pci_down(wlc_hw->sih); - wlc_bmac_xtal(wlc_hw, OFF); - } - } - - return callbacks; -} - -void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw) -{ - if (D11REV_IS(wlc_hw->corerev, 4)) /* no slowclock */ - udelay(5); - else { - /* delay before first read of ucode state */ - udelay(40); - - /* wait until ucode is no longer asleep */ - SPINWAIT((wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) == - DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly); - } - - ASSERT(wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) != DBGST_ASLEEP); -} - -void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, u8 *ea) -{ - bcopy(wlc_hw->etheraddr, ea, ETH_ALEN); -} - -void wlc_bmac_set_hw_etheraddr(struct wlc_hw_info *wlc_hw, - u8 *ea) -{ - bcopy(ea, wlc_hw->etheraddr, ETH_ALEN); -} - -int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw) -{ - return wlc_hw->band->bandtype; -} - -void *wlc_cur_phy(struct wlc_info *wlc) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - return (void *)wlc_hw->band->pi; -} - -/* control chip clock to save power, enable dynamic clock or force fast clock */ -static void wlc_clkctl_clk(struct wlc_hw_info *wlc_hw, uint mode) -{ - if (PMUCTL_ENAB(wlc_hw->sih)) { - /* new chips with PMU, CCS_FORCEHT will distribute the HT clock on backplane, - * but mac core will still run on ALP(not HT) when it enters powersave mode, - * which means the FCA bit may not be set. - * should wakeup mac if driver wants it to run on HT. - */ - - if (wlc_hw->clk) { - if (mode == CLK_FAST) { - OR_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, - CCS_FORCEHT); - - udelay(64); - - SPINWAIT(((R_REG - (wlc_hw->osh, - &wlc_hw->regs-> - clk_ctl_st) & CCS_HTAVAIL) == 0), - PMU_MAX_TRANSITION_DLY); - ASSERT(R_REG - (wlc_hw->osh, - &wlc_hw->regs-> - clk_ctl_st) & CCS_HTAVAIL); - } else { - if ((wlc_hw->sih->pmurev == 0) && - (R_REG - (wlc_hw->osh, - &wlc_hw->regs-> - clk_ctl_st) & (CCS_FORCEHT | CCS_HTAREQ))) - SPINWAIT(((R_REG - (wlc_hw->osh, - &wlc_hw->regs-> - clk_ctl_st) & CCS_HTAVAIL) - == 0), - PMU_MAX_TRANSITION_DLY); - AND_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, - ~CCS_FORCEHT); - } - } - wlc_hw->forcefastclk = (mode == CLK_FAST); - } else { - bool wakeup_ucode; - - /* old chips w/o PMU, force HT through cc, - * then use FCA to verify mac is running fast clock - */ - - wakeup_ucode = D11REV_LT(wlc_hw->corerev, 9); - - if (wlc_hw->up && wakeup_ucode) - wlc_ucode_wake_override_set(wlc_hw, - WLC_WAKE_OVERRIDE_CLKCTL); - - wlc_hw->forcefastclk = si_clkctl_cc(wlc_hw->sih, mode); - - if (D11REV_LT(wlc_hw->corerev, 11)) { - /* ucode WAR for old chips */ - if (wlc_hw->forcefastclk) - wlc_bmac_mhf(wlc_hw, MHF1, MHF1_FORCEFASTCLK, - MHF1_FORCEFASTCLK, WLC_BAND_ALL); - else - wlc_bmac_mhf(wlc_hw, MHF1, MHF1_FORCEFASTCLK, 0, - WLC_BAND_ALL); - } - - /* check fast clock is available (if core is not in reset) */ - if (D11REV_GT(wlc_hw->corerev, 4) && wlc_hw->forcefastclk - && wlc_hw->clk) - ASSERT(si_core_sflags(wlc_hw->sih, 0, 0) & SISF_FCLKA); - - /* keep the ucode wake bit on if forcefastclk is on - * since we do not want ucode to put us back to slow clock - * when it dozes for PM mode. - * Code below matches the wake override bit with current forcefastclk state - * Only setting bit in wake_override instead of waking ucode immediately - * since old code (wlc.c 1.4499) had this behavior. Older code set - * wlc->forcefastclk but only had the wake happen if the wakup_ucode work - * (protected by an up check) was executed just below. - */ - if (wlc_hw->forcefastclk) - mboolset(wlc_hw->wake_override, - WLC_WAKE_OVERRIDE_FORCEFAST); - else - mboolclr(wlc_hw->wake_override, - WLC_WAKE_OVERRIDE_FORCEFAST); - - /* ok to clear the wakeup now */ - if (wlc_hw->up && wakeup_ucode) - wlc_ucode_wake_override_clear(wlc_hw, - WLC_WAKE_OVERRIDE_CLKCTL); - } -} - -/* set initial host flags value */ -static void -wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - - memset(mhfs, 0, MHFMAX * sizeof(u16)); - - mhfs[MHF2] |= mhf2_init; - - /* prohibit use of slowclock on multifunction boards */ - if (wlc_hw->boardflags & BFL_NOPLLDOWN) - mhfs[MHF1] |= MHF1_FORCEFASTCLK; - - if (WLCISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 2)) { - mhfs[MHF2] |= MHF2_NPHY40MHZ_WAR; - mhfs[MHF1] |= MHF1_IQSWAP_WAR; - } -} - -/* set or clear ucode host flag bits - * it has an optimization for no-change write - * it only writes through shared memory when the core has clock; - * pre-CLK changes should use wlc_write_mhf to get around the optimization - * - * - * bands values are: WLC_BAND_AUTO <--- Current band only - * WLC_BAND_5G <--- 5G band only - * WLC_BAND_2G <--- 2G band only - * WLC_BAND_ALL <--- All bands - */ -void -wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, u16 val, - int bands) -{ - u16 save; - u16 addr[MHFMAX] = { - M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4, - M_HOST_FLAGS5 - }; - wlc_hwband_t *band; - - ASSERT((val & ~mask) == 0); - ASSERT(idx < MHFMAX); - ASSERT(ARRAY_SIZE(addr) == MHFMAX); - - switch (bands) { - /* Current band only or all bands, - * then set the band to current band - */ - case WLC_BAND_AUTO: - case WLC_BAND_ALL: - band = wlc_hw->band; - break; - case WLC_BAND_5G: - band = wlc_hw->bandstate[BAND_5G_INDEX]; - break; - case WLC_BAND_2G: - band = wlc_hw->bandstate[BAND_2G_INDEX]; - break; - default: - ASSERT(0); - band = NULL; - } - - if (band) { - save = band->mhfs[idx]; - band->mhfs[idx] = (band->mhfs[idx] & ~mask) | val; - - /* optimization: only write through if changed, and - * changed band is the current band - */ - if (wlc_hw->clk && (band->mhfs[idx] != save) - && (band == wlc_hw->band)) - wlc_bmac_write_shm(wlc_hw, addr[idx], - (u16) band->mhfs[idx]); - } - - if (bands == WLC_BAND_ALL) { - wlc_hw->bandstate[0]->mhfs[idx] = - (wlc_hw->bandstate[0]->mhfs[idx] & ~mask) | val; - wlc_hw->bandstate[1]->mhfs[idx] = - (wlc_hw->bandstate[1]->mhfs[idx] & ~mask) | val; - } -} - -u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands) -{ - wlc_hwband_t *band; - ASSERT(idx < MHFMAX); - - switch (bands) { - case WLC_BAND_AUTO: - band = wlc_hw->band; - break; - case WLC_BAND_5G: - band = wlc_hw->bandstate[BAND_5G_INDEX]; - break; - case WLC_BAND_2G: - band = wlc_hw->bandstate[BAND_2G_INDEX]; - break; - default: - ASSERT(0); - band = NULL; - } - - if (!band) - return 0; - - return band->mhfs[idx]; -} - -static void wlc_write_mhf(struct wlc_hw_info *wlc_hw, u16 *mhfs) -{ - u8 idx; - u16 addr[] = { - M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4, - M_HOST_FLAGS5 - }; - - ASSERT(ARRAY_SIZE(addr) == MHFMAX); - - for (idx = 0; idx < MHFMAX; idx++) { - wlc_bmac_write_shm(wlc_hw, addr[idx], mhfs[idx]); - } -} - -/* set the maccontrol register to desired reset state and - * initialize the sw cache of the register - */ -static void wlc_mctrl_reset(struct wlc_hw_info *wlc_hw) -{ - /* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */ - wlc_hw->maccontrol = 0; - wlc_hw->suspended_fifos = 0; - wlc_hw->wake_override = 0; - wlc_hw->mute_override = 0; - wlc_bmac_mctrl(wlc_hw, ~0, MCTL_IHR_EN | MCTL_WAKE); -} - -/* set or clear maccontrol bits */ -void wlc_bmac_mctrl(struct wlc_hw_info *wlc_hw, u32 mask, u32 val) -{ - u32 maccontrol; - u32 new_maccontrol; - - ASSERT((val & ~mask) == 0); - - maccontrol = wlc_hw->maccontrol; - new_maccontrol = (maccontrol & ~mask) | val; - - /* if the new maccontrol value is the same as the old, nothing to do */ - if (new_maccontrol == maccontrol) - return; - - /* something changed, cache the new value */ - wlc_hw->maccontrol = new_maccontrol; - - /* write the new values with overrides applied */ - wlc_mctrl_write(wlc_hw); -} - -/* write the software state of maccontrol and overrides to the maccontrol register */ -static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw) -{ - u32 maccontrol = wlc_hw->maccontrol; - - /* OR in the wake bit if overridden */ - if (wlc_hw->wake_override) - maccontrol |= MCTL_WAKE; - - /* set AP and INFRA bits for mute if needed */ - if (wlc_hw->mute_override) { - maccontrol &= ~(MCTL_AP); - maccontrol |= MCTL_INFRA; - } - - W_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol, maccontrol); -} - -void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, u32 override_bit) -{ - ASSERT((wlc_hw->wake_override & override_bit) == 0); - - if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) { - mboolset(wlc_hw->wake_override, override_bit); - return; - } - - mboolset(wlc_hw->wake_override, override_bit); - - wlc_mctrl_write(wlc_hw); - wlc_bmac_wait_for_wake(wlc_hw); - - return; -} - -void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw, u32 override_bit) -{ - ASSERT(wlc_hw->wake_override & override_bit); - - mboolclr(wlc_hw->wake_override, override_bit); - - if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) - return; - - wlc_mctrl_write(wlc_hw); - - return; -} - -/* When driver needs ucode to stop beaconing, it has to make sure that - * MCTL_AP is clear and MCTL_INFRA is set - * Mode MCTL_AP MCTL_INFRA - * AP 1 1 - * STA 0 1 <--- This will ensure no beacons - * IBSS 0 0 - */ -static void wlc_ucode_mute_override_set(struct wlc_hw_info *wlc_hw) -{ - wlc_hw->mute_override = 1; - - /* if maccontrol already has AP == 0 and INFRA == 1 without this - * override, then there is no change to write - */ - if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA) - return; - - wlc_mctrl_write(wlc_hw); - - return; -} - -/* Clear the override on AP and INFRA bits */ -static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw) -{ - if (wlc_hw->mute_override == 0) - return; - - wlc_hw->mute_override = 0; - - /* if maccontrol already has AP == 0 and INFRA == 1 without this - * override, then there is no change to write - */ - if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA) - return; - - wlc_mctrl_write(wlc_hw); -} - -/* - * Write a MAC address to the rcmta structure - */ -void -wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, - const u8 *addr) -{ - d11regs_t *regs = wlc_hw->regs; - volatile u16 *objdata16 = (volatile u16 *)®s->objdata; - u32 mac_hm; - u16 mac_l; - struct osl_info *osh; - - WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); - - ASSERT(wlc_hw->corerev > 4); - - mac_hm = - (addr[3] << 24) | (addr[2] << 16) | - (addr[1] << 8) | addr[0]; - mac_l = (addr[5] << 8) | addr[4]; - - osh = wlc_hw->osh; - - W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, ®s->objdata, mac_hm); - W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1))); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, objdata16, mac_l); -} - -/* - * Write a MAC address to the given match reg offset in the RXE match engine. - */ -void -wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset, - const u8 *addr) -{ - d11regs_t *regs; - u16 mac_l; - u16 mac_m; - u16 mac_h; - struct osl_info *osh; - - WL_TRACE("wl%d: wlc_bmac_set_addrmatch\n", wlc_hw->unit); - - ASSERT((match_reg_offset < RCM_SIZE) || (wlc_hw->corerev == 4)); - - regs = wlc_hw->regs; - mac_l = addr[0] | (addr[1] << 8); - mac_m = addr[2] | (addr[3] << 8); - mac_h = addr[4] | (addr[5] << 8); - - osh = wlc_hw->osh; - - /* enter the MAC addr into the RXE match registers */ - W_REG(osh, ®s->rcm_ctl, RCM_INC_DATA | match_reg_offset); - W_REG(osh, ®s->rcm_mat_data, mac_l); - W_REG(osh, ®s->rcm_mat_data, mac_m); - W_REG(osh, ®s->rcm_mat_data, mac_h); - -} - -void -wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, int len, - void *buf) -{ - d11regs_t *regs; - u32 word; - bool be_bit; -#ifdef IL_BIGENDIAN - volatile u16 *dptr = NULL; -#endif /* IL_BIGENDIAN */ - struct osl_info *osh; - - WL_TRACE("wl%d: wlc_bmac_write_template_ram\n", wlc_hw->unit); - - regs = wlc_hw->regs; - osh = wlc_hw->osh; - - ASSERT(IS_ALIGNED(offset, sizeof(u32))); - ASSERT(IS_ALIGNED(len, sizeof(u32))); - ASSERT((offset & ~0xffff) == 0); - - W_REG(osh, ®s->tplatewrptr, offset); - - /* if MCTL_BIGEND bit set in mac control register, - * the chip swaps data in fifo, as well as data in - * template ram - */ - be_bit = (R_REG(osh, ®s->maccontrol) & MCTL_BIGEND) != 0; - - while (len > 0) { - bcopy((u8 *) buf, &word, sizeof(u32)); - - if (be_bit) - word = hton32(word); - else - word = htol32(word); - - W_REG(osh, ®s->tplatewrdata, word); - - buf = (u8 *) buf + sizeof(u32); - len -= sizeof(u32); - } -} - -void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin) -{ - struct osl_info *osh; - - osh = wlc_hw->osh; - wlc_hw->band->CWmin = newmin; - - W_REG(osh, &wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMIN); - (void)R_REG(osh, &wlc_hw->regs->objaddr); - W_REG(osh, &wlc_hw->regs->objdata, newmin); -} - -void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax) -{ - struct osl_info *osh; - - osh = wlc_hw->osh; - wlc_hw->band->CWmax = newmax; - - W_REG(osh, &wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMAX); - (void)R_REG(osh, &wlc_hw->regs->objaddr); - W_REG(osh, &wlc_hw->regs->objdata, newmax); -} - -void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw) -{ - bool fastclk; - u32 tmp; - - /* request FAST clock if not on */ - fastclk = wlc_hw->forcefastclk; - if (!fastclk) - wlc_clkctl_clk(wlc_hw, CLK_FAST); - - wlc_phy_bw_state_set(wlc_hw->band->pi, bw); - - ASSERT(wlc_hw->clk); - if (D11REV_LT(wlc_hw->corerev, 17)) - tmp = R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol); - - wlc_bmac_phy_reset(wlc_hw); - wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi)); - - /* restore the clk */ - if (!fastclk) - wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); -} - -static void -wlc_write_hw_bcntemplate0(struct wlc_hw_info *wlc_hw, void *bcn, int len) -{ - d11regs_t *regs = wlc_hw->regs; - - wlc_bmac_write_template_ram(wlc_hw, T_BCN0_TPL_BASE, (len + 3) & ~3, - bcn); - /* write beacon length to SCR */ - ASSERT(len < 65536); - wlc_bmac_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len); - /* mark beacon0 valid */ - OR_REG(wlc_hw->osh, ®s->maccommand, MCMD_BCN0VLD); -} - -static void -wlc_write_hw_bcntemplate1(struct wlc_hw_info *wlc_hw, void *bcn, int len) -{ - d11regs_t *regs = wlc_hw->regs; - - wlc_bmac_write_template_ram(wlc_hw, T_BCN1_TPL_BASE, (len + 3) & ~3, - bcn); - /* write beacon length to SCR */ - ASSERT(len < 65536); - wlc_bmac_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len); - /* mark beacon1 valid */ - OR_REG(wlc_hw->osh, ®s->maccommand, MCMD_BCN1VLD); -} - -/* mac is assumed to be suspended at this point */ -void -wlc_bmac_write_hw_bcntemplates(struct wlc_hw_info *wlc_hw, void *bcn, int len, - bool both) -{ - d11regs_t *regs = wlc_hw->regs; - - if (both) { - wlc_write_hw_bcntemplate0(wlc_hw, bcn, len); - wlc_write_hw_bcntemplate1(wlc_hw, bcn, len); - } else { - /* bcn 0 */ - if (!(R_REG(wlc_hw->osh, ®s->maccommand) & MCMD_BCN0VLD)) - wlc_write_hw_bcntemplate0(wlc_hw, bcn, len); - /* bcn 1 */ - else if (! - (R_REG(wlc_hw->osh, ®s->maccommand) & MCMD_BCN1VLD)) - wlc_write_hw_bcntemplate1(wlc_hw, bcn, len); - else /* one template should always have been available */ - ASSERT(0); - } -} - -static void WLBANDINITFN(wlc_bmac_upd_synthpu) (struct wlc_hw_info *wlc_hw) -{ - u16 v; - struct wlc_info *wlc = wlc_hw->wlc; - /* update SYNTHPU_DLY */ - - if (WLCISLCNPHY(wlc->band)) { - v = SYNTHPU_DLY_LPPHY_US; - } else if (WLCISNPHY(wlc->band) && (NREV_GE(wlc->band->phyrev, 3))) { - v = SYNTHPU_DLY_NPHY_US; - } else { - v = SYNTHPU_DLY_BPHY_US; - } - - wlc_bmac_write_shm(wlc_hw, M_SYNTHPU_DLY, v); -} - -/* band-specific init */ -static void -WLBANDINITFN(wlc_bmac_bsinit) (struct wlc_info *wlc, chanspec_t chanspec) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - - WL_TRACE("wl%d: wlc_bmac_bsinit: bandunit %d\n", - wlc_hw->unit, wlc_hw->band->bandunit); - - /* sanity check */ - if (PHY_TYPE(R_REG(wlc_hw->osh, &wlc_hw->regs->phyversion)) != - PHY_TYPE_LCNXN) - ASSERT((uint) - PHY_TYPE(R_REG(wlc_hw->osh, &wlc_hw->regs->phyversion)) - == wlc_hw->band->phytype); - - wlc_ucode_bsinit(wlc_hw); - - wlc_phy_init(wlc_hw->band->pi, chanspec); - - wlc_ucode_txant_set(wlc_hw); - - /* cwmin is band-specific, update hardware with value for current band */ - wlc_bmac_set_cwmin(wlc_hw, wlc_hw->band->CWmin); - wlc_bmac_set_cwmax(wlc_hw, wlc_hw->band->CWmax); - - wlc_bmac_update_slot_timing(wlc_hw, - BAND_5G(wlc_hw->band-> - bandtype) ? true : wlc_hw-> - shortslot); - - /* write phytype and phyvers */ - wlc_bmac_write_shm(wlc_hw, M_PHYTYPE, (u16) wlc_hw->band->phytype); - wlc_bmac_write_shm(wlc_hw, M_PHYVER, (u16) wlc_hw->band->phyrev); - - /* initialize the txphyctl1 rate table since shmem is shared between bands */ - wlc_upd_ofdm_pctl1_table(wlc_hw); - - wlc_bmac_upd_synthpu(wlc_hw); -} - -void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk) -{ - WL_TRACE("wl%d: wlc_bmac_core_phy_clk: clk %d\n", wlc_hw->unit, clk); - - wlc_hw->phyclk = clk; - - if (OFF == clk) { /* clear gmode bit, put phy into reset */ - - si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC | SICF_GMODE), - (SICF_PRST | SICF_FGC)); - udelay(1); - si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_PRST); - udelay(1); - - } else { /* take phy out of reset */ - - si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_FGC); - udelay(1); - si_core_cflags(wlc_hw->sih, (SICF_FGC), 0); - udelay(1); - - } -} - -/* Perform a soft reset of the PHY PLL */ -void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw) -{ - WL_TRACE("wl%d: wlc_bmac_core_phypll_reset\n", wlc_hw->unit); - - si_corereg(wlc_hw->sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_addr), ~0, 0); - udelay(1); - si_corereg(wlc_hw->sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_data), 0x4, 0); - udelay(1); - si_corereg(wlc_hw->sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_data), 0x4, 4); - udelay(1); - si_corereg(wlc_hw->sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_data), 0x4, 0); - udelay(1); -} - -/* light way to turn on phy clock without reset for NPHY only - * refer to wlc_bmac_core_phy_clk for full version - */ -void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk) -{ - /* support(necessary for NPHY and HYPHY) only */ - if (!WLCISNPHY(wlc_hw->band)) - return; - - if (ON == clk) - si_core_cflags(wlc_hw->sih, SICF_FGC, SICF_FGC); - else - si_core_cflags(wlc_hw->sih, SICF_FGC, 0); - -} - -void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk) -{ - if (ON == clk) - si_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE); - else - si_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0); -} - -void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw) -{ - wlc_phy_t *pih = wlc_hw->band->pi; - u32 phy_bw_clkbits; - bool phy_in_reset = false; - - WL_TRACE("wl%d: wlc_bmac_phy_reset\n", wlc_hw->unit); - - if (pih == NULL) - return; - - phy_bw_clkbits = wlc_phy_clk_bwbits(wlc_hw->band->pi); - - /* Specfic reset sequence required for NPHY rev 3 and 4 */ - if (WLCISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) && - NREV_LE(wlc_hw->band->phyrev, 4)) { - /* Set the PHY bandwidth */ - si_core_cflags(wlc_hw->sih, SICF_BWMASK, phy_bw_clkbits); - - udelay(1); - - /* Perform a soft reset of the PHY PLL */ - wlc_bmac_core_phypll_reset(wlc_hw); - - /* reset the PHY */ - si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE), - (SICF_PRST | SICF_PCLKE)); - phy_in_reset = true; - } else { - - si_core_cflags(wlc_hw->sih, - (SICF_PRST | SICF_PCLKE | SICF_BWMASK), - (SICF_PRST | SICF_PCLKE | phy_bw_clkbits)); - } - - udelay(2); - wlc_bmac_core_phy_clk(wlc_hw, ON); - - if (pih) - wlc_phy_anacore(pih, ON); -} - -/* switch to and initialize new band */ -static void -WLBANDINITFN(wlc_bmac_setband) (struct wlc_hw_info *wlc_hw, uint bandunit, - chanspec_t chanspec) { - struct wlc_info *wlc = wlc_hw->wlc; - u32 macintmask; - - ASSERT(NBANDS_HW(wlc_hw) > 1); - ASSERT(bandunit != wlc_hw->band->bandunit); - - /* Enable the d11 core before accessing it */ - if (!si_iscoreup(wlc_hw->sih)) { - si_core_reset(wlc_hw->sih, 0, 0); - ASSERT(si_iscoreup(wlc_hw->sih)); - wlc_mctrl_reset(wlc_hw); - } - - macintmask = wlc_setband_inact(wlc, bandunit); - - if (!wlc_hw->up) - return; - - wlc_bmac_core_phy_clk(wlc_hw, ON); - - /* band-specific initializations */ - wlc_bmac_bsinit(wlc, chanspec); - - /* - * If there are any pending software interrupt bits, - * then replace these with a harmless nonzero value - * so wlc_dpc() will re-enable interrupts when done. - */ - if (wlc->macintstatus) - wlc->macintstatus = MI_DMAINT; - - /* restore macintmask */ - wl_intrsrestore(wlc->wl, macintmask); - - /* ucode should still be suspended.. */ - ASSERT((R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol) & MCTL_EN_MAC) == - 0); -} - -/* low-level band switch utility routine */ -void WLBANDINITFN(wlc_setxband) (struct wlc_hw_info *wlc_hw, uint bandunit) -{ - WL_TRACE("wl%d: wlc_setxband: bandunit %d\n", wlc_hw->unit, bandunit); - - wlc_hw->band = wlc_hw->bandstate[bandunit]; - - /* BMAC_NOTE: until we eliminate need for wlc->band refs in low level code */ - wlc_hw->wlc->band = wlc_hw->wlc->bandstate[bandunit]; - - /* set gmode core flag */ - if (wlc_hw->sbclk && !wlc_hw->noreset) { - si_core_cflags(wlc_hw->sih, SICF_GMODE, - ((bandunit == 0) ? SICF_GMODE : 0)); - } -} - -static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw) -{ - - /* reject unsupported corerev */ - if (!VALID_COREREV(wlc_hw->corerev)) { - WL_ERROR("unsupported core rev %d\n", wlc_hw->corerev); - return false; - } - - return true; -} - -static bool wlc_validboardtype(struct wlc_hw_info *wlc_hw) -{ - bool goodboard = true; - uint boardrev = wlc_hw->boardrev; - - if (boardrev == 0) - goodboard = false; - else if (boardrev > 0xff) { - uint brt = (boardrev & 0xf000) >> 12; - uint b0 = (boardrev & 0xf00) >> 8; - uint b1 = (boardrev & 0xf0) >> 4; - uint b2 = boardrev & 0xf; - - if ((brt > 2) || (brt == 0) || (b0 > 9) || (b0 == 0) || (b1 > 9) - || (b2 > 9)) - goodboard = false; - } - - if (wlc_hw->sih->boardvendor != VENDOR_BROADCOM) - return goodboard; - - return goodboard; -} - -static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw) -{ - const char *varname = "macaddr"; - char *macaddr; - - /* If macaddr exists, use it (Sromrev4, CIS, ...). */ - macaddr = getvar(wlc_hw->vars, varname); - if (macaddr != NULL) - return macaddr; - - if (NBANDS_HW(wlc_hw) > 1) - varname = "et1macaddr"; - else - varname = "il0macaddr"; - - macaddr = getvar(wlc_hw->vars, varname); - if (macaddr == NULL) { - WL_ERROR("wl%d: wlc_get_macaddr: macaddr getvar(%s) not found\n", - wlc_hw->unit, varname); - } - - return macaddr; -} - -/* - * Return true if radio is disabled, otherwise false. - * hw radio disable signal is an external pin, users activate it asynchronously - * this function could be called when driver is down and w/o clock - * it operates on different registers depending on corerev and boardflag. - */ -bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw) -{ - bool v, clk, xtal; - u32 resetbits = 0, flags = 0; - - xtal = wlc_hw->sbclk; - if (!xtal) - wlc_bmac_xtal(wlc_hw, ON); - - /* may need to take core out of reset first */ - clk = wlc_hw->clk; - if (!clk) { - if (D11REV_LE(wlc_hw->corerev, 11)) - resetbits |= SICF_PCLKE; - - /* - * corerev >= 18, mac no longer enables phyclk automatically when driver accesses - * phyreg throughput mac. This can be skipped since only mac reg is accessed below - */ - if (D11REV_GE(wlc_hw->corerev, 18)) - flags |= SICF_PCLKE; - - /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */ - if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || - (wlc_hw->sih->chip == BCM43225_CHIP_ID) || - (wlc_hw->sih->chip == BCM43421_CHIP_ID)) - wlc_hw->regs = - (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, - 0); - si_core_reset(wlc_hw->sih, flags, resetbits); - wlc_mctrl_reset(wlc_hw); - } - - v = ((R_REG(wlc_hw->osh, &wlc_hw->regs->phydebug) & PDBG_RFD) != 0); - - /* put core back into reset */ - if (!clk) - si_core_disable(wlc_hw->sih, 0); - - if (!xtal) - wlc_bmac_xtal(wlc_hw, OFF); - - return v; -} - -/* Initialize just the hardware when coming out of POR or S3/S5 system states */ -void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw) -{ - if (wlc_hw->wlc->pub->hw_up) - return; - - WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); - - /* - * Enable pll and xtal, initialize the power control registers, - * and force fastclock for the remainder of wlc_up(). - */ - wlc_bmac_xtal(wlc_hw, ON); - si_clkctl_init(wlc_hw->sih); - wlc_clkctl_clk(wlc_hw, CLK_FAST); - - if (wlc_hw->sih->bustype == PCI_BUS) { - si_pci_fixcfg(wlc_hw->sih); - - /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */ - if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || - (wlc_hw->sih->chip == BCM43225_CHIP_ID) || - (wlc_hw->sih->chip == BCM43421_CHIP_ID)) - wlc_hw->regs = - (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, - 0); - } - - /* Inform phy that a POR reset has occurred so it does a complete phy init */ - wlc_phy_por_inform(wlc_hw->band->pi); - - wlc_hw->ucode_loaded = false; - wlc_hw->wlc->pub->hw_up = true; - - if ((wlc_hw->boardflags & BFL_FEM) - && (wlc_hw->sih->chip == BCM4313_CHIP_ID)) { - if (! - (wlc_hw->boardrev >= 0x1250 - && (wlc_hw->boardflags & BFL_FEM_BT))) - si_epa_4313war(wlc_hw->sih); - } -} - -static bool wlc_dma_rxreset(struct wlc_hw_info *wlc_hw, uint fifo) -{ - struct hnddma_pub *di = wlc_hw->di[fifo]; - struct osl_info *osh; - - if (D11REV_LT(wlc_hw->corerev, 12)) { - bool rxidle = true; - u16 rcv_frm_cnt = 0; - - osh = wlc_hw->osh; - - W_REG(osh, &wlc_hw->regs->rcv_fifo_ctl, fifo << 8); - SPINWAIT((!(rxidle = dma_rxidle(di))) && - ((rcv_frm_cnt = - R_REG(osh, &wlc_hw->regs->rcv_frm_cnt)) != 0), - 50000); - - if (!rxidle && (rcv_frm_cnt != 0)) - WL_ERROR("wl%d: %s: rxdma[%d] not idle && rcv_frm_cnt(%d) not zero\n", - wlc_hw->unit, __func__, fifo, rcv_frm_cnt); - mdelay(2); - } - - return dma_rxreset(di); -} - -/* d11 core reset - * ensure fask clock during reset - * reset dma - * reset d11(out of reset) - * reset phy(out of reset) - * clear software macintstatus for fresh new start - * one testing hack wlc_hw->noreset will bypass the d11/phy reset - */ -void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags) -{ - d11regs_t *regs; - uint i; - bool fastclk; - u32 resetbits = 0; - - if (flags == WLC_USE_COREFLAGS) - flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0); - - WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); - - regs = wlc_hw->regs; - - /* request FAST clock if not on */ - fastclk = wlc_hw->forcefastclk; - if (!fastclk) - wlc_clkctl_clk(wlc_hw, CLK_FAST); - - /* reset the dma engines except first time thru */ - if (si_iscoreup(wlc_hw->sih)) { - for (i = 0; i < NFIFO; i++) - if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) { - WL_ERROR("wl%d: %s: dma_txreset[%d]: cannot stop dma\n", - wlc_hw->unit, __func__, i); - } - - if ((wlc_hw->di[RX_FIFO]) - && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) { - WL_ERROR("wl%d: %s: dma_rxreset[%d]: cannot stop dma\n", - wlc_hw->unit, __func__, RX_FIFO); - } - if (D11REV_IS(wlc_hw->corerev, 4) - && wlc_hw->di[RX_TXSTATUS_FIFO] - && (!wlc_dma_rxreset(wlc_hw, RX_TXSTATUS_FIFO))) { - WL_ERROR("wl%d: %s: dma_rxreset[%d]: cannot stop dma\n", - wlc_hw->unit, __func__, RX_TXSTATUS_FIFO); - } - } - /* if noreset, just stop the psm and return */ - if (wlc_hw->noreset) { - wlc_hw->wlc->macintstatus = 0; /* skip wl_dpc after down */ - wlc_bmac_mctrl(wlc_hw, MCTL_PSM_RUN | MCTL_EN_MAC, 0); - return; - } - - if (D11REV_LE(wlc_hw->corerev, 11)) - resetbits |= SICF_PCLKE; - - /* - * corerev >= 18, mac no longer enables phyclk automatically when driver accesses phyreg - * throughput mac, AND phy_reset is skipped at early stage when band->pi is invalid - * need to enable PHY CLK - */ - if (D11REV_GE(wlc_hw->corerev, 18)) - flags |= SICF_PCLKE; - - /* reset the core - * In chips with PMU, the fastclk request goes through d11 core reg 0x1e0, which - * is cleared by the core_reset. have to re-request it. - * This adds some delay and we can optimize it by also requesting fastclk through - * chipcommon during this period if necessary. But that has to work coordinate - * with other driver like mips/arm since they may touch chipcommon as well. - */ - wlc_hw->clk = false; - si_core_reset(wlc_hw->sih, flags, resetbits); - wlc_hw->clk = true; - if (wlc_hw->band && wlc_hw->band->pi) - wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true); - - wlc_mctrl_reset(wlc_hw); - - if (PMUCTL_ENAB(wlc_hw->sih)) - wlc_clkctl_clk(wlc_hw, CLK_FAST); - - wlc_bmac_phy_reset(wlc_hw); - - /* turn on PHY_PLL */ - wlc_bmac_core_phypll_ctl(wlc_hw, true); - - /* clear sw intstatus */ - wlc_hw->wlc->macintstatus = 0; - - /* restore the clk setting */ - if (!fastclk) - wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); -} - -/* If the ucode that supports corerev 5 is used for corerev 9 and above, - * txfifo sizes needs to be modified(increased) since the newer cores - * have more memory. - */ -static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw) -{ - d11regs_t *regs = wlc_hw->regs; - u16 fifo_nu; - u16 txfifo_startblk = TXFIFO_START_BLK, txfifo_endblk; - u16 txfifo_def, txfifo_def1; - u16 txfifo_cmd; - struct osl_info *osh; - - if (D11REV_LT(wlc_hw->corerev, 9)) - goto exit; - - /* tx fifos start at TXFIFO_START_BLK from the Base address */ - txfifo_startblk = TXFIFO_START_BLK; - - osh = wlc_hw->osh; - - /* sequence of operations: reset fifo, set fifo size, reset fifo */ - for (fifo_nu = 0; fifo_nu < NFIFO; fifo_nu++) { - - txfifo_endblk = txfifo_startblk + wlc_hw->xmtfifo_sz[fifo_nu]; - txfifo_def = (txfifo_startblk & 0xff) | - (((txfifo_endblk - 1) & 0xff) << TXFIFO_FIFOTOP_SHIFT); - txfifo_def1 = ((txfifo_startblk >> 8) & 0x1) | - ((((txfifo_endblk - - 1) >> 8) & 0x1) << TXFIFO_FIFOTOP_SHIFT); - txfifo_cmd = - TXFIFOCMD_RESET_MASK | (fifo_nu << TXFIFOCMD_FIFOSEL_SHIFT); - - W_REG(osh, ®s->xmtfifocmd, txfifo_cmd); - W_REG(osh, ®s->xmtfifodef, txfifo_def); - if (D11REV_GE(wlc_hw->corerev, 16)) - W_REG(osh, ®s->xmtfifodef1, txfifo_def1); - - W_REG(osh, ®s->xmtfifocmd, txfifo_cmd); - - txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu]; - } - exit: - /* need to propagate to shm location to be in sync since ucode/hw won't do this */ - wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE0, - wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]); - wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE1, - wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]); - wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE2, - ((wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO] << 8) | wlc_hw-> - xmtfifo_sz[TX_AC_BK_FIFO])); - wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE3, - ((wlc_hw->xmtfifo_sz[TX_ATIM_FIFO] << 8) | wlc_hw-> - xmtfifo_sz[TX_BCMC_FIFO])); -} - -/* d11 core init - * reset PSM - * download ucode/PCM - * let ucode run to suspended - * download ucode inits - * config other core registers - * init dma - */ -static void wlc_coreinit(struct wlc_info *wlc) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - d11regs_t *regs; - u32 sflags; - uint bcnint_us; - uint i = 0; - bool fifosz_fixup = false; - struct osl_info *osh; - int err = 0; - u16 buf[NFIFO]; - - regs = wlc_hw->regs; - osh = wlc_hw->osh; - - WL_TRACE("wl%d: wlc_coreinit\n", wlc_hw->unit); - - /* reset PSM */ - wlc_bmac_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE)); - - wlc_ucode_download(wlc_hw); - /* - * FIFOSZ fixup - * 1) core5-9 use ucode 5 to save space since the PSM is the same - * 2) newer chips, driver wants to controls the fifo allocation - */ - if (D11REV_GE(wlc_hw->corerev, 4)) - fifosz_fixup = true; - - /* let the PSM run to the suspended state, set mode to BSS STA */ - W_REG(osh, ®s->macintstatus, -1); - wlc_bmac_mctrl(wlc_hw, ~0, - (MCTL_IHR_EN | MCTL_INFRA | MCTL_PSM_RUN | MCTL_WAKE)); - - /* wait for ucode to self-suspend after auto-init */ - SPINWAIT(((R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD) == 0), - 1000 * 1000); - if ((R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD) == 0) - WL_ERROR("wl%d: wlc_coreinit: ucode did not self-suspend!\n", - wlc_hw->unit); - - wlc_gpio_init(wlc); - - sflags = si_core_sflags(wlc_hw->sih, 0, 0); - - if (D11REV_IS(wlc_hw->corerev, 23)) { - if (WLCISNPHY(wlc_hw->band)) - wlc_write_inits(wlc_hw, d11n0initvals16); - else - WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); - } else if (D11REV_IS(wlc_hw->corerev, 24)) { - if (WLCISLCNPHY(wlc_hw->band)) { - wlc_write_inits(wlc_hw, d11lcn0initvals24); - } else { - WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); - } - } else { - WL_ERROR("%s: wl%d: unsupported corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); - } - - /* For old ucode, txfifo sizes needs to be modified(increased) for Corerev >= 9 */ - if (fifosz_fixup == true) { - wlc_corerev_fifofixup(wlc_hw); - } - - /* check txfifo allocations match between ucode and driver */ - buf[TX_AC_BE_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE0); - if (buf[TX_AC_BE_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]) { - i = TX_AC_BE_FIFO; - err = -1; - } - buf[TX_AC_VI_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE1); - if (buf[TX_AC_VI_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]) { - i = TX_AC_VI_FIFO; - err = -1; - } - buf[TX_AC_BK_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE2); - buf[TX_AC_VO_FIFO] = (buf[TX_AC_BK_FIFO] >> 8) & 0xff; - buf[TX_AC_BK_FIFO] &= 0xff; - if (buf[TX_AC_BK_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BK_FIFO]) { - i = TX_AC_BK_FIFO; - err = -1; - } - if (buf[TX_AC_VO_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO]) { - i = TX_AC_VO_FIFO; - err = -1; - } - buf[TX_BCMC_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE3); - buf[TX_ATIM_FIFO] = (buf[TX_BCMC_FIFO] >> 8) & 0xff; - buf[TX_BCMC_FIFO] &= 0xff; - if (buf[TX_BCMC_FIFO] != wlc_hw->xmtfifo_sz[TX_BCMC_FIFO]) { - i = TX_BCMC_FIFO; - err = -1; - } - if (buf[TX_ATIM_FIFO] != wlc_hw->xmtfifo_sz[TX_ATIM_FIFO]) { - i = TX_ATIM_FIFO; - err = -1; - } - if (err != 0) { - WL_ERROR("wlc_coreinit: txfifo mismatch: ucode size %d driver size %d index %d\n", - buf[i], wlc_hw->xmtfifo_sz[i], i); - /* DO NOT ASSERT corerev < 4 even there is a mismatch - * shmem, since driver don't overwrite those chip and - * ucode initialize data will be used. - */ - if (D11REV_GE(wlc_hw->corerev, 4)) - ASSERT(0); - } - - /* make sure we can still talk to the mac */ - ASSERT(R_REG(osh, ®s->maccontrol) != 0xffffffff); - - /* band-specific inits done by wlc_bsinit() */ - - /* Set up frame burst size and antenna swap threshold init values */ - wlc_bmac_write_shm(wlc_hw, M_MBURST_SIZE, MAXTXFRAMEBURST); - wlc_bmac_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT); - - /* enable one rx interrupt per received frame */ - W_REG(osh, ®s->intrcvlazy[0], (1 << IRL_FC_SHIFT)); - if (D11REV_IS(wlc_hw->corerev, 4)) - W_REG(osh, ®s->intrcvlazy[3], (1 << IRL_FC_SHIFT)); - - /* set the station mode (BSS STA) */ - wlc_bmac_mctrl(wlc_hw, - (MCTL_INFRA | MCTL_DISCARD_PMQ | MCTL_AP), - (MCTL_INFRA | MCTL_DISCARD_PMQ)); - - /* set up Beacon interval */ - bcnint_us = 0x8000 << 10; - W_REG(osh, ®s->tsf_cfprep, (bcnint_us << CFPREP_CBI_SHIFT)); - W_REG(osh, ®s->tsf_cfpstart, bcnint_us); - W_REG(osh, ®s->macintstatus, MI_GP1); - - /* write interrupt mask */ - W_REG(osh, ®s->intctrlregs[RX_FIFO].intmask, DEF_RXINTMASK); - if (D11REV_IS(wlc_hw->corerev, 4)) - W_REG(osh, ®s->intctrlregs[RX_TXSTATUS_FIFO].intmask, - DEF_RXINTMASK); - - /* allow the MAC to control the PHY clock (dynamic on/off) */ - wlc_bmac_macphyclk_set(wlc_hw, ON); - - /* program dynamic clock control fast powerup delay register */ - if (D11REV_GT(wlc_hw->corerev, 4)) { - wlc->fastpwrup_dly = si_clkctl_fast_pwrup_delay(wlc_hw->sih); - W_REG(osh, ®s->scc_fastpwrup_dly, wlc->fastpwrup_dly); - } - - /* tell the ucode the corerev */ - wlc_bmac_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev); - - /* tell the ucode MAC capabilities */ - if (D11REV_GE(wlc_hw->corerev, 13)) { - wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_L, - (u16) (wlc_hw->machwcap & 0xffff)); - wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_H, - (u16) ((wlc_hw-> - machwcap >> 16) & 0xffff)); - } - - /* write retry limits to SCR, this done after PSM init */ - W_REG(osh, ®s->objaddr, OBJADDR_SCR_SEL | S_DOT11_SRC_LMT); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, ®s->objdata, wlc_hw->SRL); - W_REG(osh, ®s->objaddr, OBJADDR_SCR_SEL | S_DOT11_LRC_LMT); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, ®s->objdata, wlc_hw->LRL); - - /* write rate fallback retry limits */ - wlc_bmac_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL); - wlc_bmac_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL); - - if (D11REV_GE(wlc_hw->corerev, 16)) { - AND_REG(osh, ®s->ifs_ctl, 0x0FFF); - W_REG(osh, ®s->ifs_aifsn, EDCF_AIFSN_MIN); - } - - /* dma initializations */ - wlc->txpend16165war = 0; - - /* init the tx dma engines */ - for (i = 0; i < NFIFO; i++) { - if (wlc_hw->di[i]) - dma_txinit(wlc_hw->di[i]); - } - - /* init the rx dma engine(s) and post receive buffers */ - dma_rxinit(wlc_hw->di[RX_FIFO]); - dma_rxfill(wlc_hw->di[RX_FIFO]); - if (D11REV_IS(wlc_hw->corerev, 4)) { - dma_rxinit(wlc_hw->di[RX_TXSTATUS_FIFO]); - dma_rxfill(wlc_hw->di[RX_TXSTATUS_FIFO]); - } -} - -/* This function is used for changing the tsf frac register - * If spur avoidance mode is off, the mac freq will be 80/120/160Mhz - * If spur avoidance mode is on1, the mac freq will be 82/123/164Mhz - * If spur avoidance mode is on2, the mac freq will be 84/126/168Mhz - * HTPHY Formula is 2^26/freq(MHz) e.g. - * For spuron2 - 126MHz -> 2^26/126 = 532610.0 - * - 532610 = 0x82082 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x2082 - * For spuron: 123MHz -> 2^26/123 = 545600.5 - * - 545601 = 0x85341 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x5341 - * For spur off: 120MHz -> 2^26/120 = 559240.5 - * - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889 - */ - -void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode) -{ - d11regs_t *regs; - struct osl_info *osh; - regs = wlc_hw->regs; - osh = wlc_hw->osh; - - if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || - (wlc_hw->sih->chip == BCM43225_CHIP_ID)) { - if (spurmode == WL_SPURAVOID_ON2) { /* 126Mhz */ - W_REG(osh, ®s->tsf_clk_frac_l, 0x2082); - W_REG(osh, ®s->tsf_clk_frac_h, 0x8); - } else if (spurmode == WL_SPURAVOID_ON1) { /* 123Mhz */ - W_REG(osh, ®s->tsf_clk_frac_l, 0x5341); - W_REG(osh, ®s->tsf_clk_frac_h, 0x8); - } else { /* 120Mhz */ - W_REG(osh, ®s->tsf_clk_frac_l, 0x8889); - W_REG(osh, ®s->tsf_clk_frac_h, 0x8); - } - } else if (WLCISLCNPHY(wlc_hw->band)) { - if (spurmode == WL_SPURAVOID_ON1) { /* 82Mhz */ - W_REG(osh, ®s->tsf_clk_frac_l, 0x7CE0); - W_REG(osh, ®s->tsf_clk_frac_h, 0xC); - } else { /* 80Mhz */ - W_REG(osh, ®s->tsf_clk_frac_l, 0xCCCD); - W_REG(osh, ®s->tsf_clk_frac_h, 0xC); - } - } -} - -/* Initialize GPIOs that are controlled by D11 core */ -static void wlc_gpio_init(struct wlc_info *wlc) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - d11regs_t *regs; - u32 gc, gm; - struct osl_info *osh; - - regs = wlc_hw->regs; - osh = wlc_hw->osh; - - /* use GPIO select 0 to get all gpio signals from the gpio out reg */ - wlc_bmac_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0); - - /* - * Common GPIO setup: - * G0 = LED 0 = WLAN Activity - * G1 = LED 1 = WLAN 2.4 GHz Radio State - * G2 = LED 2 = WLAN 5 GHz Radio State - * G4 = radio disable input (HI enabled, LO disabled) - */ - - gc = gm = 0; - - /* Allocate GPIOs for mimo antenna diversity feature */ - if (WLANTSEL_ENAB(wlc)) { - if (wlc_hw->antsel_type == ANTSEL_2x3) { - /* Enable antenna diversity, use 2x3 mode */ - wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, - MHF3_ANTSEL_EN, WLC_BAND_ALL); - wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, - MHF3_ANTSEL_MODE, WLC_BAND_ALL); - - /* init superswitch control */ - wlc_phy_antsel_init(wlc_hw->band->pi, false); - - } else if (wlc_hw->antsel_type == ANTSEL_2x4) { - ASSERT((gm & BOARD_GPIO_12) == 0); - gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13); - /* The board itself is powered by these GPIOs (when not sending pattern) - * So set them high - */ - OR_REG(osh, ®s->psm_gpio_oe, - (BOARD_GPIO_12 | BOARD_GPIO_13)); - OR_REG(osh, ®s->psm_gpio_out, - (BOARD_GPIO_12 | BOARD_GPIO_13)); - - /* Enable antenna diversity, use 2x4 mode */ - wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, - MHF3_ANTSEL_EN, WLC_BAND_ALL); - wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0, - WLC_BAND_ALL); - - /* Configure the desired clock to be 4Mhz */ - wlc_bmac_write_shm(wlc_hw, M_ANTSEL_CLKDIV, - ANTSEL_CLKDIV_4MHZ); - } - } - /* gpio 9 controls the PA. ucode is responsible for wiggling out and oe */ - if (wlc_hw->boardflags & BFL_PACTRL) - gm |= gc |= BOARD_GPIO_PACTRL; - - /* apply to gpiocontrol register */ - si_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY); -} - -static void wlc_ucode_download(struct wlc_hw_info *wlc_hw) -{ - struct wlc_info *wlc; - wlc = wlc_hw->wlc; - - if (wlc_hw->ucode_loaded) - return; - - if (D11REV_IS(wlc_hw->corerev, 23)) { - if (WLCISNPHY(wlc_hw->band)) { - wlc_ucode_write(wlc_hw, bcm43xx_16_mimo, - bcm43xx_16_mimosz); - wlc_hw->ucode_loaded = true; - } else - WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); - } else if (D11REV_IS(wlc_hw->corerev, 24)) { - if (WLCISLCNPHY(wlc_hw->band)) { - wlc_ucode_write(wlc_hw, bcm43xx_24_lcn, - bcm43xx_24_lcnsz); - wlc_hw->ucode_loaded = true; - } else { - WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); - } - } -} - -static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[], - const uint nbytes) { - struct osl_info *osh; - d11regs_t *regs = wlc_hw->regs; - uint i; - uint count; - - osh = wlc_hw->osh; - - WL_TRACE("wl%d: wlc_ucode_write\n", wlc_hw->unit); - - ASSERT(IS_ALIGNED(nbytes, sizeof(u32))); - - count = (nbytes / sizeof(u32)); - - W_REG(osh, ®s->objaddr, (OBJADDR_AUTO_INC | OBJADDR_UCM_SEL)); - (void)R_REG(osh, ®s->objaddr); - for (i = 0; i < count; i++) - W_REG(osh, ®s->objdata, ucode[i]); -} - -static void wlc_write_inits(struct wlc_hw_info *wlc_hw, const d11init_t *inits) -{ - int i; - struct osl_info *osh; - volatile u8 *base; - - WL_TRACE("wl%d: wlc_write_inits\n", wlc_hw->unit); - - osh = wlc_hw->osh; - base = (volatile u8 *)wlc_hw->regs; - - for (i = 0; inits[i].addr != 0xffff; i++) { - ASSERT((inits[i].size == 2) || (inits[i].size == 4)); - - if (inits[i].size == 2) - W_REG(osh, (u16 *)(base + inits[i].addr), - inits[i].value); - else if (inits[i].size == 4) - W_REG(osh, (u32 *)(base + inits[i].addr), - inits[i].value); - } -} - -static void wlc_ucode_txant_set(struct wlc_hw_info *wlc_hw) -{ - u16 phyctl; - u16 phytxant = wlc_hw->bmac_phytxant; - u16 mask = PHY_TXC_ANT_MASK; - - /* set the Probe Response frame phy control word */ - phyctl = wlc_bmac_read_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS); - phyctl = (phyctl & ~mask) | phytxant; - wlc_bmac_write_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS, phyctl); - - /* set the Response (ACK/CTS) frame phy control word */ - phyctl = wlc_bmac_read_shm(wlc_hw, M_RSP_PCTLWD); - phyctl = (phyctl & ~mask) | phytxant; - wlc_bmac_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl); -} - -void wlc_bmac_txant_set(struct wlc_hw_info *wlc_hw, u16 phytxant) -{ - /* update sw state */ - wlc_hw->bmac_phytxant = phytxant; - - /* push to ucode if up */ - if (!wlc_hw->up) - return; - wlc_ucode_txant_set(wlc_hw); - -} - -u16 wlc_bmac_get_txant(struct wlc_hw_info *wlc_hw) -{ - return (u16) wlc_hw->wlc->stf->txant; -} - -void wlc_bmac_antsel_type_set(struct wlc_hw_info *wlc_hw, u8 antsel_type) -{ - wlc_hw->antsel_type = antsel_type; - - /* Update the antsel type for phy module to use */ - wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type); -} - -void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw) -{ - bool fatal = false; - uint unit; - uint intstatus, idx; - d11regs_t *regs = wlc_hw->regs; - - unit = wlc_hw->unit; - - for (idx = 0; idx < NFIFO; idx++) { - /* read intstatus register and ignore any non-error bits */ - intstatus = - R_REG(wlc_hw->osh, - ®s->intctrlregs[idx].intstatus) & I_ERRORS; - if (!intstatus) - continue; - - WL_TRACE("wl%d: wlc_bmac_fifoerrors: intstatus%d 0x%x\n", - unit, idx, intstatus); - - if (intstatus & I_RO) { - WL_ERROR("wl%d: fifo %d: receive fifo overflow\n", - unit, idx); - WLCNTINCR(wlc_hw->wlc->pub->_cnt->rxoflo); - fatal = true; - } - - if (intstatus & I_PC) { - WL_ERROR("wl%d: fifo %d: descriptor error\n", - unit, idx); - WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmade); - fatal = true; - } - - if (intstatus & I_PD) { - WL_ERROR("wl%d: fifo %d: data error\n", unit, idx); - WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmada); - fatal = true; - } - - if (intstatus & I_DE) { - WL_ERROR("wl%d: fifo %d: descriptor protocol error\n", - unit, idx); - WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmape); - fatal = true; - } - - if (intstatus & I_RU) { - WL_ERROR("wl%d: fifo %d: receive descriptor underflow\n", - idx, unit); - WLCNTINCR(wlc_hw->wlc->pub->_cnt->rxuflo[idx]); - } - - if (intstatus & I_XU) { - WL_ERROR("wl%d: fifo %d: transmit fifo underflow\n", - idx, unit); - WLCNTINCR(wlc_hw->wlc->pub->_cnt->txuflo); - fatal = true; - } - - if (fatal) { - wlc_fatal_error(wlc_hw->wlc); /* big hammer */ - break; - } else - W_REG(wlc_hw->osh, ®s->intctrlregs[idx].intstatus, - intstatus); - } -} - -void wlc_intrson(struct wlc_info *wlc) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - ASSERT(wlc->defmacintmask); - wlc->macintmask = wlc->defmacintmask; - W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, wlc->macintmask); -} - -/* callback for siutils.c, which has only wlc handler, no wl - * they both check up, not only because there is no need to off/restore d11 interrupt - * but also because per-port code may require sync with valid interrupt. - */ - -static u32 wlc_wlintrsoff(struct wlc_info *wlc) -{ - if (!wlc->hw->up) - return 0; - - return wl_intrsoff(wlc->wl); -} - -static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask) -{ - if (!wlc->hw->up) - return; - - wl_intrsrestore(wlc->wl, macintmask); -} - -u32 wlc_intrsoff(struct wlc_info *wlc) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - u32 macintmask; - - if (!wlc_hw->clk) - return 0; - - macintmask = wlc->macintmask; /* isr can still happen */ - - W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, 0); - (void)R_REG(wlc_hw->osh, &wlc_hw->regs->macintmask); /* sync readback */ - udelay(1); /* ensure int line is no longer driven */ - wlc->macintmask = 0; - - /* return previous macintmask; resolve race between us and our isr */ - return wlc->macintstatus ? 0 : macintmask; -} - -void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - if (!wlc_hw->clk) - return; - - wlc->macintmask = macintmask; - W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, wlc->macintmask); -} - -void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool on, mbool flags) -{ - u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; - - if (on) { - /* suspend tx fifos */ - wlc_bmac_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO); - wlc_bmac_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO); - wlc_bmac_tx_fifo_suspend(wlc_hw, TX_AC_BK_FIFO); - wlc_bmac_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO); - - /* zero the address match register so we do not send ACKs */ - wlc_bmac_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, - null_ether_addr); - } else { - /* resume tx fifos */ - if (!wlc_hw->wlc->tx_suspended) { - wlc_bmac_tx_fifo_resume(wlc_hw, TX_DATA_FIFO); - } - wlc_bmac_tx_fifo_resume(wlc_hw, TX_CTL_FIFO); - wlc_bmac_tx_fifo_resume(wlc_hw, TX_AC_BK_FIFO); - wlc_bmac_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO); - - /* Restore address */ - wlc_bmac_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, - wlc_hw->etheraddr); - } - - wlc_phy_mute_upd(wlc_hw->band->pi, on, flags); - - if (on) - wlc_ucode_mute_override_set(wlc_hw); - else - wlc_ucode_mute_override_clear(wlc_hw); -} - -void wlc_bmac_set_deaf(struct wlc_hw_info *wlc_hw, bool user_flag) -{ - wlc_phy_set_deaf(wlc_hw->band->pi, user_flag); -} - -int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, uint *blocks) -{ - if (fifo >= NFIFO) - return BCME_RANGE; - - *blocks = wlc_hw->xmtfifo_sz[fifo]; - - return 0; -} - -int wlc_bmac_xmtfifo_sz_set(struct wlc_hw_info *wlc_hw, uint fifo, uint blocks) -{ - if (fifo >= NFIFO || blocks > 299) - return BCME_RANGE; - - /* BMAC_NOTE, change blocks to u16 */ - wlc_hw->xmtfifo_sz[fifo] = (u16) blocks; - - return 0; -} - -/* wlc_bmac_tx_fifo_suspended: - * Check the MAC's tx suspend status for a tx fifo. - * - * When the MAC acknowledges a tx suspend, it indicates that no more - * packets will be transmitted out the radio. This is independent of - * DMA channel suspension---the DMA may have finished suspending, or may still - * be pulling data into a tx fifo, by the time the MAC acks the suspend - * request. - */ -bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, uint tx_fifo) -{ - /* check that a suspend has been requested and is no longer pending */ - - /* - * for DMA mode, the suspend request is set in xmtcontrol of the DMA engine, - * and the tx fifo suspend at the lower end of the MAC is acknowledged in the - * chnstatus register. - * The tx fifo suspend completion is independent of the DMA suspend completion and - * may be acked before or after the DMA is suspended. - */ - if (dma_txsuspended(wlc_hw->di[tx_fifo]) && - (R_REG(wlc_hw->osh, &wlc_hw->regs->chnstatus) & - (1 << tx_fifo)) == 0) - return true; - - return false; -} - -void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo) -{ - u8 fifo = 1 << tx_fifo; - - /* Two clients of this code, 11h Quiet period and scanning. */ - - /* only suspend if not already suspended */ - if ((wlc_hw->suspended_fifos & fifo) == fifo) - return; - - /* force the core awake only if not already */ - if (wlc_hw->suspended_fifos == 0) - wlc_ucode_wake_override_set(wlc_hw, WLC_WAKE_OVERRIDE_TXFIFO); - - wlc_hw->suspended_fifos |= fifo; - - if (wlc_hw->di[tx_fifo]) { - /* Suspending AMPDU transmissions in the middle can cause underflow - * which may result in mismatch between ucode and driver - * so suspend the mac before suspending the FIFO - */ - if (WLC_PHY_11N_CAP(wlc_hw->band)) - wlc_suspend_mac_and_wait(wlc_hw->wlc); - - dma_txsuspend(wlc_hw->di[tx_fifo]); - - if (WLC_PHY_11N_CAP(wlc_hw->band)) - wlc_enable_mac(wlc_hw->wlc); - } -} - -void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo) -{ - /* BMAC_NOTE: WLC_TX_FIFO_ENAB is done in wlc_dpc() for DMA case but need to be done - * here for PIO otherwise the watchdog will catch the inconsistency and fire - */ - /* Two clients of this code, 11h Quiet period and scanning. */ - if (wlc_hw->di[tx_fifo]) - dma_txresume(wlc_hw->di[tx_fifo]); - - /* allow core to sleep again */ - if (wlc_hw->suspended_fifos == 0) - return; - else { - wlc_hw->suspended_fifos &= ~(1 << tx_fifo); - if (wlc_hw->suspended_fifos == 0) - wlc_ucode_wake_override_clear(wlc_hw, - WLC_WAKE_OVERRIDE_TXFIFO); - } -} - -/* - * Read and clear macintmask and macintstatus and intstatus registers. - * This routine should be called with interrupts off - * Return: - * -1 if DEVICEREMOVED(wlc) evaluates to true; - * 0 if the interrupt is not for us, or we are in some special cases; - * device interrupt status bits otherwise. - */ -static inline u32 wlc_intstatus(struct wlc_info *wlc, bool in_isr) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - d11regs_t *regs = wlc_hw->regs; - u32 macintstatus; - u32 intstatus_rxfifo, intstatus_txsfifo; - struct osl_info *osh; - - osh = wlc_hw->osh; - - /* macintstatus includes a DMA interrupt summary bit */ - macintstatus = R_REG(osh, ®s->macintstatus); - - WL_TRACE("wl%d: macintstatus: 0x%x\n", wlc_hw->unit, macintstatus); - - /* detect cardbus removed, in power down(suspend) and in reset */ - if (DEVICEREMOVED(wlc)) - return -1; - - /* DEVICEREMOVED succeeds even when the core is still resetting, - * handle that case here. - */ - if (macintstatus == 0xffffffff) - return 0; - - /* defer unsolicited interrupts */ - macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask); - - /* if not for us */ - if (macintstatus == 0) - return 0; - - /* interrupts are already turned off for CFE build - * Caution: For CFE Turning off the interrupts again has some undesired - * consequences - */ - /* turn off the interrupts */ - W_REG(osh, ®s->macintmask, 0); - (void)R_REG(osh, ®s->macintmask); /* sync readback */ - wlc->macintmask = 0; - - /* clear device interrupts */ - W_REG(osh, ®s->macintstatus, macintstatus); - - /* MI_DMAINT is indication of non-zero intstatus */ - if (macintstatus & MI_DMAINT) { - if (D11REV_IS(wlc_hw->corerev, 4)) { - intstatus_rxfifo = - R_REG(osh, ®s->intctrlregs[RX_FIFO].intstatus); - intstatus_txsfifo = - R_REG(osh, - ®s->intctrlregs[RX_TXSTATUS_FIFO]. - intstatus); - WL_TRACE("wl%d: intstatus_rxfifo 0x%x, intstatus_txsfifo 0x%x\n", - wlc_hw->unit, - intstatus_rxfifo, intstatus_txsfifo); - - /* defer unsolicited interrupt hints */ - intstatus_rxfifo &= DEF_RXINTMASK; - intstatus_txsfifo &= DEF_RXINTMASK; - - /* MI_DMAINT bit in macintstatus is indication of RX_FIFO interrupt */ - /* clear interrupt hints */ - if (intstatus_rxfifo) - W_REG(osh, - ®s->intctrlregs[RX_FIFO].intstatus, - intstatus_rxfifo); - else - macintstatus &= ~MI_DMAINT; - - /* MI_TFS bit in macintstatus is encoding of RX_TXSTATUS_FIFO interrupt */ - if (intstatus_txsfifo) { - W_REG(osh, - ®s->intctrlregs[RX_TXSTATUS_FIFO]. - intstatus, intstatus_txsfifo); - macintstatus |= MI_TFS; - } - } else { - /* - * For corerevs >= 5, only fifo interrupt enabled is I_RI in RX_FIFO. - * If MI_DMAINT is set, assume it is set and clear the interrupt. - */ - W_REG(osh, ®s->intctrlregs[RX_FIFO].intstatus, - DEF_RXINTMASK); - } - } - - return macintstatus; -} - -/* Update wlc->macintstatus and wlc->intstatus[]. */ -/* Return true if they are updated successfully. false otherwise */ -bool wlc_intrsupd(struct wlc_info *wlc) -{ - u32 macintstatus; - - ASSERT(wlc->macintstatus != 0); - - /* read and clear macintstatus and intstatus registers */ - macintstatus = wlc_intstatus(wlc, false); - - /* device is removed */ - if (macintstatus == 0xffffffff) - return false; - - /* update interrupt status in software */ - wlc->macintstatus |= macintstatus; - - return true; -} - -/* - * First-level interrupt processing. - * Return true if this was our interrupt, false otherwise. - * *wantdpc will be set to true if further wlc_dpc() processing is required, - * false otherwise. - */ -bool BCMFASTPATH wlc_isr(struct wlc_info *wlc, bool *wantdpc) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - u32 macintstatus; - - *wantdpc = false; - - if (!wlc_hw->up || !wlc->macintmask) - return false; - - /* read and clear macintstatus and intstatus registers */ - macintstatus = wlc_intstatus(wlc, true); - - if (macintstatus == 0xffffffff) - WL_ERROR("DEVICEREMOVED detected in the ISR code path\n"); - - /* it is not for us */ - if (macintstatus == 0) - return false; - - *wantdpc = true; - - /* save interrupt status bits */ - ASSERT(wlc->macintstatus == 0); - wlc->macintstatus = macintstatus; - - return true; - -} - -/* process tx completion events for corerev < 5 */ -static bool wlc_bmac_txstatus_corerev4(struct wlc_hw_info *wlc_hw) -{ - struct sk_buff *status_p; - tx_status_t *txs; - struct osl_info *osh; - bool fatal = false; - - WL_TRACE("wl%d: wlc_txstatusrecv\n", wlc_hw->unit); - - osh = wlc_hw->osh; - - while (!fatal && (status_p = dma_rx(wlc_hw->di[RX_TXSTATUS_FIFO]))) { - - txs = (tx_status_t *) status_p->data; - /* MAC uses little endian only */ - ltoh16_buf((void *)txs, sizeof(tx_status_t)); - - /* shift low bits for tx_status_t status compatibility */ - txs->status = (txs->status & ~TXS_COMPAT_MASK) - | (((txs->status & TXS_COMPAT_MASK) << TXS_COMPAT_SHIFT)); - - fatal = wlc_bmac_dotxstatus(wlc_hw, txs, 0); - - pkt_buf_free_skb(osh, status_p, false); - } - - if (fatal) - return true; - - /* post more rbufs */ - dma_rxfill(wlc_hw->di[RX_TXSTATUS_FIFO]); - - return false; -} - -static bool BCMFASTPATH -wlc_bmac_dotxstatus(struct wlc_hw_info *wlc_hw, tx_status_t *txs, u32 s2) -{ - /* discard intermediate indications for ucode with one legitimate case: - * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent - * tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts - * transmission count) - */ - if (!(txs->status & TX_STATUS_AMPDU) - && (txs->status & TX_STATUS_INTERMEDIATE)) { - return false; - } - - return wlc_dotxstatus(wlc_hw->wlc, txs, s2); -} - -/* process tx completion events in BMAC - * Return true if more tx status need to be processed. false otherwise. - */ -static bool BCMFASTPATH -wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal) -{ - bool morepending = false; - struct wlc_info *wlc = wlc_hw->wlc; - - WL_TRACE("wl%d: wlc_bmac_txstatus\n", wlc_hw->unit); - - if (D11REV_IS(wlc_hw->corerev, 4)) { - /* to retire soon */ - *fatal = wlc_bmac_txstatus_corerev4(wlc->hw); - - if (*fatal) - return 0; - } else { - /* corerev >= 5 */ - d11regs_t *regs; - struct osl_info *osh; - tx_status_t txstatus, *txs; - u32 s1, s2; - uint n = 0; - /* Param 'max_tx_num' indicates max. # tx status to process before break out. */ - uint max_tx_num = bound ? wlc->pub->tunables->txsbnd : -1; - - txs = &txstatus; - regs = wlc_hw->regs; - osh = wlc_hw->osh; - while (!(*fatal) - && (s1 = R_REG(osh, ®s->frmtxstatus)) & TXS_V) { - - if (s1 == 0xffffffff) { - WL_ERROR("wl%d: %s: dead chip\n", - wlc_hw->unit, __func__); - ASSERT(s1 != 0xffffffff); - return morepending; - } - - s2 = R_REG(osh, ®s->frmtxstatus2); - - txs->status = s1 & TXS_STATUS_MASK; - txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT; - txs->sequence = s2 & TXS_SEQ_MASK; - txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT; - txs->lasttxtime = 0; - - *fatal = wlc_bmac_dotxstatus(wlc_hw, txs, s2); - - /* !give others some time to run! */ - if (++n >= max_tx_num) - break; - } - - if (*fatal) - return 0; - - if (n >= max_tx_num) - morepending = true; - } - - if (!pktq_empty(&wlc->active_queue->q)) - wlc_send_q(wlc, wlc->active_queue); - - return morepending; -} - -void wlc_suspend_mac_and_wait(struct wlc_info *wlc) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - d11regs_t *regs = wlc_hw->regs; - u32 mc, mi; - struct osl_info *osh; - - WL_TRACE("wl%d: wlc_suspend_mac_and_wait: bandunit %d\n", - wlc_hw->unit, wlc_hw->band->bandunit); - - /* - * Track overlapping suspend requests - */ - wlc_hw->mac_suspend_depth++; - if (wlc_hw->mac_suspend_depth > 1) - return; - - osh = wlc_hw->osh; - - /* force the core awake */ - wlc_ucode_wake_override_set(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND); - - mc = R_REG(osh, ®s->maccontrol); - - if (mc == 0xffffffff) { - WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); - wl_down(wlc->wl); - return; - } - ASSERT(!(mc & MCTL_PSM_JMP_0)); - ASSERT(mc & MCTL_PSM_RUN); - ASSERT(mc & MCTL_EN_MAC); - - mi = R_REG(osh, ®s->macintstatus); - if (mi == 0xffffffff) { - WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); - wl_down(wlc->wl); - return; - } - ASSERT(!(mi & MI_MACSSPNDD)); - - wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, 0); - - SPINWAIT(!(R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD), - WLC_MAX_MAC_SUSPEND); - - if (!(R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD)) { - WL_ERROR("wl%d: wlc_suspend_mac_and_wait: waited %d uS and MI_MACSSPNDD is still not on.\n", - wlc_hw->unit, WLC_MAX_MAC_SUSPEND); - WL_ERROR("wl%d: psmdebug 0x%08x, phydebug 0x%08x, psm_brc 0x%04x\n", - wlc_hw->unit, - R_REG(osh, ®s->psmdebug), - R_REG(osh, ®s->phydebug), - R_REG(osh, ®s->psm_brc)); - } - - mc = R_REG(osh, ®s->maccontrol); - if (mc == 0xffffffff) { - WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); - wl_down(wlc->wl); - return; - } - ASSERT(!(mc & MCTL_PSM_JMP_0)); - ASSERT(mc & MCTL_PSM_RUN); - ASSERT(!(mc & MCTL_EN_MAC)); -} - -void wlc_enable_mac(struct wlc_info *wlc) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - d11regs_t *regs = wlc_hw->regs; - u32 mc, mi; - struct osl_info *osh; - - WL_TRACE("wl%d: wlc_enable_mac: bandunit %d\n", - wlc_hw->unit, wlc->band->bandunit); - - /* - * Track overlapping suspend requests - */ - ASSERT(wlc_hw->mac_suspend_depth > 0); - wlc_hw->mac_suspend_depth--; - if (wlc_hw->mac_suspend_depth > 0) - return; - - osh = wlc_hw->osh; - - mc = R_REG(osh, ®s->maccontrol); - ASSERT(!(mc & MCTL_PSM_JMP_0)); - ASSERT(!(mc & MCTL_EN_MAC)); - ASSERT(mc & MCTL_PSM_RUN); - - wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC); - W_REG(osh, ®s->macintstatus, MI_MACSSPNDD); - - mc = R_REG(osh, ®s->maccontrol); - ASSERT(!(mc & MCTL_PSM_JMP_0)); - ASSERT(mc & MCTL_EN_MAC); - ASSERT(mc & MCTL_PSM_RUN); - - mi = R_REG(osh, ®s->macintstatus); - ASSERT(!(mi & MI_MACSSPNDD)); - - wlc_ucode_wake_override_clear(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND); -} - -void wlc_bmac_ifsctl_edcrs_set(struct wlc_hw_info *wlc_hw, bool abie, bool isht) -{ - if (!(WLCISNPHY(wlc_hw->band) && (D11REV_GE(wlc_hw->corerev, 16)))) - return; - - if (isht) { - if (WLCISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 3)) { - AND_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - ~IFS_CTL1_EDCRS); - } - } else { - /* enable EDCRS for non-11n association */ - OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, IFS_CTL1_EDCRS); - } - - if (WLCISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3)) { - if (CHSPEC_IS20(wlc_hw->chanspec)) { - /* 20 mhz, use 20U ED only */ - OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - IFS_CTL1_EDCRS); - AND_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - ~IFS_CTL1_EDCRS_20L); - AND_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - ~IFS_CTL1_EDCRS_40); - } else { - /* 40 mhz, use 20U 20L and 40 ED */ - OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - IFS_CTL1_EDCRS); - OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - IFS_CTL1_EDCRS_20L); - OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - IFS_CTL1_EDCRS_40); - } - } -} - -static void wlc_upd_ofdm_pctl1_table(struct wlc_hw_info *wlc_hw) -{ - u8 rate; - u8 rates[8] = { - WLC_RATE_6M, WLC_RATE_9M, WLC_RATE_12M, WLC_RATE_18M, - WLC_RATE_24M, WLC_RATE_36M, WLC_RATE_48M, WLC_RATE_54M - }; - u16 entry_ptr; - u16 pctl1; - uint i; - - if (!WLC_PHY_11N_CAP(wlc_hw->band)) - return; - - /* walk the phy rate table and update the entries */ - for (i = 0; i < ARRAY_SIZE(rates); i++) { - rate = rates[i]; - - entry_ptr = wlc_bmac_ofdm_ratetable_offset(wlc_hw, rate); - - /* read the SHM Rate Table entry OFDM PCTL1 values */ - pctl1 = - wlc_bmac_read_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS); - - /* modify the value */ - pctl1 &= ~PHY_TXC1_MODE_MASK; - pctl1 |= (wlc_hw->hw_stf_ss_opmode << PHY_TXC1_MODE_SHIFT); - - /* Update the SHM Rate Table entry OFDM PCTL1 values */ - wlc_bmac_write_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS, - pctl1); - } -} - -static u16 wlc_bmac_ofdm_ratetable_offset(struct wlc_hw_info *wlc_hw, u8 rate) -{ - uint i; - u8 plcp_rate = 0; - struct plcp_signal_rate_lookup { - u8 rate; - u8 signal_rate; - }; - /* OFDM RATE sub-field of PLCP SIGNAL field, per 802.11 sec 17.3.4.1 */ - const struct plcp_signal_rate_lookup rate_lookup[] = { - {WLC_RATE_6M, 0xB}, - {WLC_RATE_9M, 0xF}, - {WLC_RATE_12M, 0xA}, - {WLC_RATE_18M, 0xE}, - {WLC_RATE_24M, 0x9}, - {WLC_RATE_36M, 0xD}, - {WLC_RATE_48M, 0x8}, - {WLC_RATE_54M, 0xC} - }; - - for (i = 0; i < ARRAY_SIZE(rate_lookup); i++) { - if (rate == rate_lookup[i].rate) { - plcp_rate = rate_lookup[i].signal_rate; - break; - } - } - - /* Find the SHM pointer to the rate table entry by looking in the - * Direct-map Table - */ - return 2 * wlc_bmac_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2)); -} - -void wlc_bmac_band_stf_ss_set(struct wlc_hw_info *wlc_hw, u8 stf_mode) -{ - wlc_hw->hw_stf_ss_opmode = stf_mode; - - if (wlc_hw->clk) - wlc_upd_ofdm_pctl1_table(wlc_hw); -} - -void BCMFASTPATH -wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr, - u32 *tsf_h_ptr) -{ - d11regs_t *regs = wlc_hw->regs; - - /* read the tsf timer low, then high to get an atomic read */ - *tsf_l_ptr = R_REG(wlc_hw->osh, ®s->tsf_timerlow); - *tsf_h_ptr = R_REG(wlc_hw->osh, ®s->tsf_timerhigh); - - return; -} - -bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) -{ - d11regs_t *regs; - u32 w, val; - volatile u16 *reg16; - struct osl_info *osh; - - WL_TRACE("wl%d: validate_chip_access\n", wlc_hw->unit); - - regs = wlc_hw->regs; - osh = wlc_hw->osh; - - /* Validate dchip register access */ - - W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(osh, ®s->objaddr); - w = R_REG(osh, ®s->objdata); - - /* Can we write and read back a 32bit register? */ - W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, ®s->objdata, (u32) 0xaa5555aa); - - W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(osh, ®s->objaddr); - val = R_REG(osh, ®s->objdata); - if (val != (u32) 0xaa5555aa) { - WL_ERROR("wl%d: validate_chip_access: SHM = 0x%x, expected 0xaa5555aa\n", - wlc_hw->unit, val); - return false; - } - - W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, ®s->objdata, (u32) 0x55aaaa55); - - W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(osh, ®s->objaddr); - val = R_REG(osh, ®s->objdata); - if (val != (u32) 0x55aaaa55) { - WL_ERROR("wl%d: validate_chip_access: SHM = 0x%x, expected 0x55aaaa55\n", - wlc_hw->unit, val); - return false; - } - - W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, ®s->objdata, w); - - if (D11REV_LT(wlc_hw->corerev, 11)) { - /* if 32 bit writes are split into 16 bit writes, are they in the correct order - * for our interface, low to high - */ - reg16 = (volatile u16 *)®s->tsf_cfpstart; - - /* write the CFPStart register low half explicitly, starting a buffered write */ - W_REG(osh, reg16, 0xAAAA); - - /* Write a 32 bit value to CFPStart to test the 16 bit split order. - * If the low 16 bits are written first, followed by the high 16 bits then the - * 32 bit value 0xCCCCBBBB should end up in the register. - * If the order is reversed, then the write to the high half will trigger a buffered - * write of 0xCCCCAAAA. - * If the bus is 32 bits, then this is not much of a test, and the reg should - * have the correct value 0xCCCCBBBB. - */ - W_REG(osh, ®s->tsf_cfpstart, 0xCCCCBBBB); - - /* verify with the 16 bit registers that have no side effects */ - val = R_REG(osh, ®s->tsf_cfpstrt_l); - if (val != (uint) 0xBBBB) { - WL_ERROR("wl%d: validate_chip_access: tsf_cfpstrt_l = 0x%x, expected 0x%x\n", - wlc_hw->unit, val, 0xBBBB); - return false; - } - val = R_REG(osh, ®s->tsf_cfpstrt_h); - if (val != (uint) 0xCCCC) { - WL_ERROR("wl%d: validate_chip_access: tsf_cfpstrt_h = 0x%x, expected 0x%x\n", - wlc_hw->unit, val, 0xCCCC); - return false; - } - - } - - /* clear CFPStart */ - W_REG(osh, ®s->tsf_cfpstart, 0); - - w = R_REG(osh, ®s->maccontrol); - if ((w != (MCTL_IHR_EN | MCTL_WAKE)) && - (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) { - WL_ERROR("wl%d: validate_chip_access: maccontrol = 0x%x, expected 0x%x or 0x%x\n", - wlc_hw->unit, w, - (MCTL_IHR_EN | MCTL_WAKE), - (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE)); - return false; - } - - return true; -} - -#define PHYPLL_WAIT_US 100000 - -void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on) -{ - d11regs_t *regs; - struct osl_info *osh; - u32 tmp; - - WL_TRACE("wl%d: wlc_bmac_core_phypll_ctl\n", wlc_hw->unit); - - tmp = 0; - regs = wlc_hw->regs; - osh = wlc_hw->osh; - - if (D11REV_LE(wlc_hw->corerev, 16) || D11REV_IS(wlc_hw->corerev, 20)) - return; - - if (on) { - if ((wlc_hw->sih->chip == BCM4313_CHIP_ID)) { - OR_REG(osh, ®s->clk_ctl_st, - (CCS_ERSRC_REQ_HT | CCS_ERSRC_REQ_D11PLL | - CCS_ERSRC_REQ_PHYPLL)); - SPINWAIT((R_REG(osh, ®s->clk_ctl_st) & - (CCS_ERSRC_AVAIL_HT)) != (CCS_ERSRC_AVAIL_HT), - PHYPLL_WAIT_US); - - tmp = R_REG(osh, ®s->clk_ctl_st); - if ((tmp & (CCS_ERSRC_AVAIL_HT)) != - (CCS_ERSRC_AVAIL_HT)) { - WL_ERROR("%s: turn on PHY PLL failed\n", - __func__); - ASSERT(0); - } - } else { - OR_REG(osh, ®s->clk_ctl_st, - (CCS_ERSRC_REQ_D11PLL | CCS_ERSRC_REQ_PHYPLL)); - SPINWAIT((R_REG(osh, ®s->clk_ctl_st) & - (CCS_ERSRC_AVAIL_D11PLL | - CCS_ERSRC_AVAIL_PHYPLL)) != - (CCS_ERSRC_AVAIL_D11PLL | - CCS_ERSRC_AVAIL_PHYPLL), PHYPLL_WAIT_US); - - tmp = R_REG(osh, ®s->clk_ctl_st); - if ((tmp & - (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) - != - (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) { - WL_ERROR("%s: turn on PHY PLL failed\n", - __func__); - ASSERT(0); - } - } - } else { - /* Since the PLL may be shared, other cores can still be requesting it; - * so we'll deassert the request but not wait for status to comply. - */ - AND_REG(osh, ®s->clk_ctl_st, ~CCS_ERSRC_REQ_PHYPLL); - tmp = R_REG(osh, ®s->clk_ctl_st); - } -} - -void wlc_coredisable(struct wlc_hw_info *wlc_hw) -{ - bool dev_gone; - - WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); - - ASSERT(!wlc_hw->up); - - dev_gone = DEVICEREMOVED(wlc_hw->wlc); - - if (dev_gone) - return; - - if (wlc_hw->noreset) - return; - - /* radio off */ - wlc_phy_switch_radio(wlc_hw->band->pi, OFF); - - /* turn off analog core */ - wlc_phy_anacore(wlc_hw->band->pi, OFF); - - /* turn off PHYPLL to save power */ - wlc_bmac_core_phypll_ctl(wlc_hw, false); - - /* No need to set wlc->pub->radio_active = OFF - * because this function needs down capability and - * radio_active is designed for BCMNODOWN. - */ - - /* remove gpio controls */ - if (wlc_hw->ucode_dbgsel) - si_gpiocontrol(wlc_hw->sih, ~0, 0, GPIO_DRV_PRIORITY); - - wlc_hw->clk = false; - si_core_disable(wlc_hw->sih, 0); - wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); -} - -/* power both the pll and external oscillator on/off */ -void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want) -{ - WL_TRACE("wl%d: wlc_bmac_xtal: want %d\n", wlc_hw->unit, want); - - /* dont power down if plldown is false or we must poll hw radio disable */ - if (!want && wlc_hw->pllreq) - return; - - if (wlc_hw->sih) - si_clkctl_xtal(wlc_hw->sih, XTAL | PLL, want); - - wlc_hw->sbclk = want; - if (!wlc_hw->sbclk) { - wlc_hw->clk = false; - if (wlc_hw->band && wlc_hw->band->pi) - wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); - } -} - -static void wlc_flushqueues(struct wlc_info *wlc) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - uint i; - - wlc->txpend16165war = 0; - - /* free any posted tx packets */ - for (i = 0; i < NFIFO; i++) - if (wlc_hw->di[i]) { - dma_txreclaim(wlc_hw->di[i], HNDDMA_RANGE_ALL); - TXPKTPENDCLR(wlc, i); - WL_TRACE("wlc_flushqueues: pktpend fifo %d cleared\n", - i); - } - - /* free any posted rx packets */ - dma_rxreclaim(wlc_hw->di[RX_FIFO]); - if (D11REV_IS(wlc_hw->corerev, 4)) - dma_rxreclaim(wlc_hw->di[RX_TXSTATUS_FIFO]); -} - -u16 wlc_bmac_read_shm(struct wlc_hw_info *wlc_hw, uint offset) -{ - return wlc_bmac_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL); -} - -void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v) -{ - wlc_bmac_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL); -} - -/* Set a range of shared memory to a value. - * SHM 'offset' needs to be an even address and - * Buffer length 'len' must be an even number of bytes - */ -void wlc_bmac_set_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v, int len) -{ - int i; - - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) - return; - - for (i = 0; i < len; i += 2) { - wlc_bmac_write_objmem(wlc_hw, offset + i, v, OBJADDR_SHM_SEL); - } -} - -static u16 -wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, u32 sel) -{ - d11regs_t *regs = wlc_hw->regs; - volatile u16 *objdata_lo = (volatile u16 *)®s->objdata; - volatile u16 *objdata_hi = objdata_lo + 1; - u16 v; - - ASSERT((offset & 1) == 0); - - W_REG(wlc_hw->osh, ®s->objaddr, sel | (offset >> 2)); - (void)R_REG(wlc_hw->osh, ®s->objaddr); - if (offset & 2) { - v = R_REG(wlc_hw->osh, objdata_hi); - } else { - v = R_REG(wlc_hw->osh, objdata_lo); - } - - return v; -} - -static void -wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset, u16 v, u32 sel) -{ - d11regs_t *regs = wlc_hw->regs; - volatile u16 *objdata_lo = (volatile u16 *)®s->objdata; - volatile u16 *objdata_hi = objdata_lo + 1; - - ASSERT((offset & 1) == 0); - - W_REG(wlc_hw->osh, ®s->objaddr, sel | (offset >> 2)); - (void)R_REG(wlc_hw->osh, ®s->objaddr); - if (offset & 2) { - W_REG(wlc_hw->osh, objdata_hi, v); - } else { - W_REG(wlc_hw->osh, objdata_lo, v); - } -} - -/* Copy a buffer to shared memory of specified type . - * SHM 'offset' needs to be an even address and - * Buffer length 'len' must be an even number of bytes - * 'sel' selects the type of memory - */ -void -wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw, uint offset, const void *buf, - int len, u32 sel) -{ - u16 v; - const u8 *p = (const u8 *)buf; - int i; - - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) - return; - - for (i = 0; i < len; i += 2) { - v = p[i] | (p[i + 1] << 8); - wlc_bmac_write_objmem(wlc_hw, offset + i, v, sel); - } -} - -/* Copy a piece of shared memory of specified type to a buffer . - * SHM 'offset' needs to be an even address and - * Buffer length 'len' must be an even number of bytes - * 'sel' selects the type of memory - */ -void -wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset, void *buf, - int len, u32 sel) -{ - u16 v; - u8 *p = (u8 *) buf; - int i; - - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) - return; - - for (i = 0; i < len; i += 2) { - v = wlc_bmac_read_objmem(wlc_hw, offset + i, sel); - p[i] = v & 0xFF; - p[i + 1] = (v >> 8) & 0xFF; - } -} - -void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, uint *len) -{ - WL_TRACE("wlc_bmac_copyfrom_vars, nvram vars totlen=%d\n", - wlc_hw->vars_size); - - *buf = wlc_hw->vars; - *len = wlc_hw->vars_size; -} - -void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL, u16 LRL) -{ - wlc_hw->SRL = SRL; - wlc_hw->LRL = LRL; - - /* write retry limit to SCR, shouldn't need to suspend */ - if (wlc_hw->up) { - W_REG(wlc_hw->osh, &wlc_hw->regs->objaddr, - OBJADDR_SCR_SEL | S_DOT11_SRC_LMT); - (void)R_REG(wlc_hw->osh, &wlc_hw->regs->objaddr); - W_REG(wlc_hw->osh, &wlc_hw->regs->objdata, wlc_hw->SRL); - W_REG(wlc_hw->osh, &wlc_hw->regs->objaddr, - OBJADDR_SCR_SEL | S_DOT11_LRC_LMT); - (void)R_REG(wlc_hw->osh, &wlc_hw->regs->objaddr); - W_REG(wlc_hw->osh, &wlc_hw->regs->objdata, wlc_hw->LRL); - } -} - -void wlc_bmac_set_noreset(struct wlc_hw_info *wlc_hw, bool noreset_flag) -{ - wlc_hw->noreset = noreset_flag; -} - -void wlc_bmac_set_ucode_loaded(struct wlc_hw_info *wlc_hw, bool ucode_loaded) -{ - wlc_hw->ucode_loaded = ucode_loaded; -} - -void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, mbool req_bit) -{ - ASSERT(req_bit); - - if (set) { - if (mboolisset(wlc_hw->pllreq, req_bit)) - return; - - mboolset(wlc_hw->pllreq, req_bit); - - if (mboolisset(wlc_hw->pllreq, WLC_PLLREQ_FLIP)) { - if (!wlc_hw->sbclk) { - wlc_bmac_xtal(wlc_hw, ON); - } - } - } else { - if (!mboolisset(wlc_hw->pllreq, req_bit)) - return; - - mboolclr(wlc_hw->pllreq, req_bit); - - if (mboolisset(wlc_hw->pllreq, WLC_PLLREQ_FLIP)) { - if (wlc_hw->sbclk) { - wlc_bmac_xtal(wlc_hw, OFF); - } - } - } - - return; -} - -void wlc_bmac_set_clk(struct wlc_hw_info *wlc_hw, bool on) -{ - if (on) { - /* power up pll and oscillator */ - wlc_bmac_xtal(wlc_hw, ON); - - /* enable core(s), ignore bandlocked - * Leave with the same band selected as we entered - */ - wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); - } else { - /* if already down, must skip the core disable */ - if (wlc_hw->clk) { - /* disable core(s), ignore bandlocked */ - wlc_coredisable(wlc_hw); - } - /* power down pll and oscillator */ - wlc_bmac_xtal(wlc_hw, OFF); - } -} - -/* this will be true for all ai chips */ -bool wlc_bmac_taclear(struct wlc_hw_info *wlc_hw, bool ta_ok) -{ - return true; -} - -/* Lower down relevant GPIOs like LED when going down w/o - * doing PCI config cycles or touching interrupts - */ -void wlc_gpio_fast_deinit(struct wlc_hw_info *wlc_hw) -{ - if ((wlc_hw == NULL) || (wlc_hw->sih == NULL)) - return; - - /* Only chips with internal bus or PCIE cores or certain PCI cores - * are able to switch cores w/o disabling interrupts - */ - if (!((wlc_hw->sih->bustype == SI_BUS) || - ((wlc_hw->sih->bustype == PCI_BUS) && - ((wlc_hw->sih->buscoretype == PCIE_CORE_ID) || - (wlc_hw->sih->buscorerev >= 13))))) - return; - - WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); - return; -} - -bool wlc_bmac_radio_hw(struct wlc_hw_info *wlc_hw, bool enable) -{ - /* Do not access Phy registers if core is not up */ - if (si_iscoreup(wlc_hw->sih) == false) - return false; - - if (enable) { - if (PMUCTL_ENAB(wlc_hw->sih)) { - AND_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, - ~CCS_FORCEHWREQOFF); - si_pmu_radio_enable(wlc_hw->sih, true); - } - - wlc_phy_anacore(wlc_hw->band->pi, ON); - wlc_phy_switch_radio(wlc_hw->band->pi, ON); - - /* resume d11 core */ - wlc_enable_mac(wlc_hw->wlc); - } else { - /* suspend d11 core */ - wlc_suspend_mac_and_wait(wlc_hw->wlc); - - wlc_phy_switch_radio(wlc_hw->band->pi, OFF); - wlc_phy_anacore(wlc_hw->band->pi, OFF); - - if (PMUCTL_ENAB(wlc_hw->sih)) { - si_pmu_radio_enable(wlc_hw->sih, false); - OR_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, - CCS_FORCEHWREQOFF); - } - } - - return true; -} - -u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate) -{ - u16 table_ptr; - u8 phy_rate, index; - - /* get the phy specific rate encoding for the PLCP SIGNAL field */ - /* XXX4321 fixup needed ? */ - if (IS_OFDM(rate)) - table_ptr = M_RT_DIRMAP_A; - else - table_ptr = M_RT_DIRMAP_B; - - /* for a given rate, the LS-nibble of the PLCP SIGNAL field is - * the index into the rate table. - */ - phy_rate = rate_info[rate] & RATE_MASK; - index = phy_rate & 0xf; - - /* Find the SHM pointer to the rate table entry by looking in the - * Direct-map Table - */ - return 2 * wlc_bmac_read_shm(wlc_hw, table_ptr + (index * 2)); -} - -void wlc_bmac_set_txpwr_percent(struct wlc_hw_info *wlc_hw, u8 val) -{ - wlc_phy_txpwr_percent_set(wlc_hw->band->pi, val); -} - -void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail) -{ - wlc_hw->antsel_avail = antsel_avail; -} diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.h b/drivers/staging/brcm80211/sys/wlc_bmac.h deleted file mode 100644 index 03ce9521d652..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_bmac.h +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* XXXXX this interface is under wlc.c by design - * http://hwnbu-twiki.broadcom.com/bin/view/Mwgroup/WlBmacDesign - * - * high driver files(e.g. wlc_ampdu.c etc) - * wlc.h/wlc.c - * wlc_bmac.h/wlc_bmac.c - * - * So don't include this in files other than wlc.c, wlc_bmac* wl_rte.c(dongle port) and wl_phy.c - * create wrappers in wlc.c if needed - */ - -/* Revision and other info required from BMAC driver for functioning of high ONLY driver */ -typedef struct wlc_bmac_revinfo { - uint vendorid; /* PCI vendor id */ - uint deviceid; /* device id of chip */ - - uint boardrev; /* version # of particular board */ - uint corerev; /* core revision */ - uint sromrev; /* srom revision */ - uint chiprev; /* chip revision */ - uint chip; /* chip number */ - uint chippkg; /* chip package */ - uint boardtype; /* board type */ - uint boardvendor; /* board vendor */ - uint bustype; /* SB_BUS, PCI_BUS */ - uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */ - uint buscorerev; /* buscore rev */ - u32 issim; /* chip is in simulation or emulation */ - - uint nbands; - - struct band_info { - uint bandunit; /* To match on both sides */ - uint bandtype; /* To match on both sides */ - uint radiorev; - uint phytype; - uint phyrev; - uint anarev; - uint radioid; - bool abgphy_encore; - } band[MAXBANDS]; -} wlc_bmac_revinfo_t; - -/* dup state between BMAC(struct wlc_hw_info) and HIGH(struct wlc_info) - driver */ -typedef struct wlc_bmac_state { - u32 machwcap; /* mac hw capibility */ - u32 preamble_ovr; /* preamble override */ -} wlc_bmac_state_t; - -enum { - IOV_BMAC_DIAG, - IOV_BMAC_SBGPIOTIMERVAL, - IOV_BMAC_SBGPIOOUT, - IOV_BMAC_CCGPIOCTRL, /* CC GPIOCTRL REG */ - IOV_BMAC_CCGPIOOUT, /* CC GPIOOUT REG */ - IOV_BMAC_CCGPIOOUTEN, /* CC GPIOOUTEN REG */ - IOV_BMAC_CCGPIOIN, /* CC GPIOIN REG */ - IOV_BMAC_WPSGPIO, /* WPS push button GPIO pin */ - IOV_BMAC_OTPDUMP, - IOV_BMAC_OTPSTAT, - IOV_BMAC_PCIEASPM, /* obfuscation clkreq/aspm control */ - IOV_BMAC_PCIEADVCORRMASK, /* advanced correctable error mask */ - IOV_BMAC_PCIECLKREQ, /* PCIE 1.1 clockreq enab support */ - IOV_BMAC_PCIELCREG, /* PCIE LCREG */ - IOV_BMAC_SBGPIOTIMERMASK, - IOV_BMAC_RFDISABLEDLY, - IOV_BMAC_PCIEREG, /* PCIE REG */ - IOV_BMAC_PCICFGREG, /* PCI Config register */ - IOV_BMAC_PCIESERDESREG, /* PCIE SERDES REG (dev, 0}offset) */ - IOV_BMAC_PCIEGPIOOUT, /* PCIEOUT REG */ - IOV_BMAC_PCIEGPIOOUTEN, /* PCIEOUTEN REG */ - IOV_BMAC_PCIECLKREQENCTRL, /* clkreqenctrl REG (PCIE REV > 6.0 */ - IOV_BMAC_DMALPBK, - IOV_BMAC_CCREG, - IOV_BMAC_COREREG, - IOV_BMAC_SDCIS, - IOV_BMAC_SDIO_DRIVE, - IOV_BMAC_OTPW, - IOV_BMAC_NVOTPW, - IOV_BMAC_SROM, - IOV_BMAC_SRCRC, - IOV_BMAC_CIS_SOURCE, - IOV_BMAC_CISVAR, - IOV_BMAC_OTPLOCK, - IOV_BMAC_OTP_CHIPID, - IOV_BMAC_CUSTOMVAR1, - IOV_BMAC_BOARDFLAGS, - IOV_BMAC_BOARDFLAGS2, - IOV_BMAC_WPSLED, - IOV_BMAC_NVRAM_SOURCE, - IOV_BMAC_OTP_RAW_READ, - IOV_BMAC_LAST -}; - -typedef enum { - BMAC_DUMP_GPIO_ID, - BMAC_DUMP_SI_ID, - BMAC_DUMP_SIREG_ID, - BMAC_DUMP_SICLK_ID, - BMAC_DUMP_CCREG_ID, - BMAC_DUMP_PCIEREG_ID, - BMAC_DUMP_PHYREG_ID, - BMAC_DUMP_PHYTBL_ID, - BMAC_DUMP_PHYTBL2_ID, - BMAC_DUMP_PHY_RADIOREG_ID, - BMAC_DUMP_LAST -} wlc_bmac_dump_id_t; - -typedef enum { - WLCHW_STATE_ATTACH, - WLCHW_STATE_CLK, - WLCHW_STATE_UP, - WLCHW_STATE_ASSOC, - WLCHW_STATE_LAST -} wlc_bmac_state_id_t; - -extern int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, - uint unit, bool piomode, struct osl_info *osh, - void *regsva, uint bustype, void *btparam); -extern int wlc_bmac_detach(struct wlc_info *wlc); -extern void wlc_bmac_watchdog(void *arg); -extern void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw); - -/* up/down, reset, clk */ -extern void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want); - -extern void wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw, - uint offset, const void *buf, int len, - u32 sel); -extern void wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset, - void *buf, int len, u32 sel); -#define wlc_bmac_copyfrom_shm(wlc_hw, offset, buf, len) \ - wlc_bmac_copyfrom_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL) -#define wlc_bmac_copyto_shm(wlc_hw, offset, buf, len) \ - wlc_bmac_copyto_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL) - -extern void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk); -extern void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on); -extern void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk); -extern void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk); -extern void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags); -extern void wlc_bmac_reset(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, - bool mute); -extern int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw); -extern int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw); -extern int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw); -extern int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags); -extern void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode); - -/* chanspec, ucode interface */ -extern int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, - chanspec_t chanspec, - bool mute, struct txpwr_limits *txpwr); - -extern void wlc_bmac_txfifo(struct wlc_hw_info *wlc_hw, uint fifo, void *p, - bool commit, u16 frameid, u8 txpktpend); -extern int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, - uint *blocks); -extern void wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, - u16 val, int bands); -extern void wlc_bmac_mctrl(struct wlc_hw_info *wlc_hw, u32 mask, u32 val); -extern u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands); -extern int wlc_bmac_xmtfifo_sz_set(struct wlc_hw_info *wlc_hw, uint fifo, - uint blocks); -extern void wlc_bmac_txant_set(struct wlc_hw_info *wlc_hw, u16 phytxant); -extern u16 wlc_bmac_get_txant(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_antsel_type_set(struct wlc_hw_info *wlc_hw, - u8 antsel_type); -extern int wlc_bmac_revinfo_get(struct wlc_hw_info *wlc_hw, - wlc_bmac_revinfo_t *revinfo); -extern int wlc_bmac_state_get(struct wlc_hw_info *wlc_hw, - wlc_bmac_state_t *state); -extern void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v); -extern u16 wlc_bmac_read_shm(struct wlc_hw_info *wlc_hw, uint offset); -extern void wlc_bmac_set_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v, - int len); -extern void wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, - int len, void *buf); -extern void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, - uint *len); - -extern void wlc_bmac_process_ps_switch(struct wlc_hw_info *wlc, - struct ether_addr *ea, s8 ps_on); -extern void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, - u8 *ea); -extern void wlc_bmac_set_hw_etheraddr(struct wlc_hw_info *wlc_hw, - u8 *ea); -extern bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw); - -extern bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot); -extern void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool want, mbool flags); -extern void wlc_bmac_set_deaf(struct wlc_hw_info *wlc_hw, bool user_flag); -extern void wlc_bmac_band_stf_ss_set(struct wlc_hw_info *wlc_hw, u8 stf_mode); - -extern void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw); -extern bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, - uint tx_fifo); -extern void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo); -extern void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo); - -extern void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, - u32 override_bit); -extern void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw, - u32 override_bit); - -extern void wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, - const u8 *addr); -extern void wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, - int match_reg_offset, - const u8 *addr); -extern void wlc_bmac_write_hw_bcntemplates(struct wlc_hw_info *wlc_hw, - void *bcn, int len, bool both); - -extern void wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr, - u32 *tsf_h_ptr); -extern void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin); -extern void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax); -extern void wlc_bmac_set_noreset(struct wlc_hw_info *wlc, bool noreset_flag); -extern void wlc_bmac_set_ucode_loaded(struct wlc_hw_info *wlc, - bool ucode_loaded); - -extern void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL, - u16 LRL); - -extern void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw); - - -/* API for BMAC driver (e.g. wlc_phy.c etc) */ - -extern void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw); -extern void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, - mbool req_bit); -extern void wlc_bmac_set_clk(struct wlc_hw_info *wlc_hw, bool on); -extern bool wlc_bmac_taclear(struct wlc_hw_info *wlc_hw, bool ta_ok); -extern void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw); - -extern void wlc_bmac_dump(struct wlc_hw_info *wlc_hw, struct bcmstrbuf *b, - wlc_bmac_dump_id_t dump_id); -extern void wlc_gpio_fast_deinit(struct wlc_hw_info *wlc_hw); - -extern bool wlc_bmac_radio_hw(struct wlc_hw_info *wlc_hw, bool enable); -extern u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate); - -extern void wlc_bmac_assert_type_set(struct wlc_hw_info *wlc_hw, u32 type); -extern void wlc_bmac_set_txpwr_percent(struct wlc_hw_info *wlc_hw, u8 val); -extern void wlc_bmac_blink_sync(struct wlc_hw_info *wlc_hw, u32 led_pins); -extern void wlc_bmac_ifsctl_edcrs_set(struct wlc_hw_info *wlc_hw, bool abie, - bool isht); - -extern void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail); diff --git a/drivers/staging/brcm80211/sys/wlc_bsscfg.h b/drivers/staging/brcm80211/sys/wlc_bsscfg.h deleted file mode 100644 index 0bb4a212dd71..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_bsscfg.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _WLC_BSSCFG_H_ -#define _WLC_BSSCFG_H_ - -#include - -/* Check if a particular BSS config is AP or STA */ -#define BSSCFG_AP(cfg) (0) -#define BSSCFG_STA(cfg) (1) - -#define BSSCFG_IBSS(cfg) (!(cfg)->BSS) - -/* forward declarations */ -typedef struct wlc_bsscfg wlc_bsscfg_t; - -#include - -#define NTXRATE 64 /* # tx MPDUs rate is reported for */ -#define MAXMACLIST 64 /* max # source MAC matches */ -#define BCN_TEMPLATE_COUNT 2 - -/* Iterator for "associated" STA bss configs: - (struct wlc_info *wlc, int idx, wlc_bsscfg_t *cfg) */ -#define FOREACH_AS_STA(wlc, idx, cfg) \ - for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \ - if ((cfg = (wlc)->bsscfg[idx]) && BSSCFG_STA(cfg) && cfg->associated) - -/* As above for all non-NULL BSS configs */ -#define FOREACH_BSS(wlc, idx, cfg) \ - for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \ - if ((cfg = (wlc)->bsscfg[idx])) - -/* BSS configuration state */ -struct wlc_bsscfg { - struct wlc_info *wlc; /* wlc to which this bsscfg belongs to. */ - bool up; /* is this configuration up operational */ - bool enable; /* is this configuration enabled */ - bool associated; /* is BSS in ASSOCIATED state */ - bool BSS; /* infraustructure or adhac */ - bool dtim_programmed; -#ifdef LATER - bool _ap; /* is this configuration an AP */ - struct wlc_if *wlcif; /* virtual interface, NULL for primary bsscfg */ - void *sup; /* pointer to supplicant state */ - s8 sup_type; /* type of supplicant */ - bool sup_enable_wpa; /* supplicant WPA on/off */ - void *authenticator; /* pointer to authenticator state */ - bool sup_auth_pending; /* flag for auth timeout */ -#endif - u8 SSID_len; /* the length of SSID */ - u8 SSID[IEEE80211_MAX_SSID_LEN]; /* SSID string */ - struct scb *bcmc_scb[MAXBANDS]; /* one bcmc_scb per band */ - s8 _idx; /* the index of this bsscfg, - * assigned at wlc_bsscfg_alloc() - */ - /* MAC filter */ - uint nmac; /* # of entries on maclist array */ - int macmode; /* allow/deny stations on maclist array */ - struct ether_addr *maclist; /* list of source MAC addrs to match */ - - /* security */ - u32 wsec; /* wireless security bitvec */ - s16 auth; /* 802.11 authentication: Open, Shared Key, WPA */ - s16 openshared; /* try Open auth first, then Shared Key */ - bool wsec_restrict; /* drop unencrypted packets if wsec is enabled */ - bool eap_restrict; /* restrict data until 802.1X auth succeeds */ - u16 WPA_auth; /* WPA: authenticated key management */ - bool wpa2_preauth; /* default is true, wpa_cap sets value */ - bool wsec_portopen; /* indicates keys are plumbed */ - wsec_iv_t wpa_none_txiv; /* global txiv for WPA_NONE, tkip and aes */ - int wsec_index; /* 0-3: default tx key, -1: not set */ - wsec_key_t *bss_def_keys[WLC_DEFAULT_KEYS]; /* default key storage */ - - /* TKIP countermeasures */ - bool tkip_countermeasures; /* flags TKIP no-assoc period */ - u32 tk_cm_dt; /* detect timer */ - u32 tk_cm_bt; /* blocking timer */ - u32 tk_cm_bt_tmstmp; /* Timestamp when TKIP BT is activated */ - bool tk_cm_activate; /* activate countermeasures after EAPOL-Key sent */ - - u8 BSSID[ETH_ALEN]; /* BSSID (associated) */ - u8 cur_etheraddr[ETH_ALEN]; /* h/w address */ - u16 bcmc_fid; /* the last BCMC FID queued to TX_BCMC_FIFO */ - u16 bcmc_fid_shm; /* the last BCMC FID written to shared mem */ - - u32 flags; /* WLC_BSSCFG flags; see below */ - - u8 *bcn; /* AP beacon */ - uint bcn_len; /* AP beacon length */ - bool ar_disassoc; /* disassociated in associated recreation */ - - int auth_atmptd; /* auth type (open/shared) attempted */ - - pmkid_cand_t pmkid_cand[MAXPMKID]; /* PMKID candidate list */ - uint npmkid_cand; /* num PMKID candidates */ - pmkid_t pmkid[MAXPMKID]; /* PMKID cache */ - uint npmkid; /* num cached PMKIDs */ - - wlc_bss_info_t *target_bss; /* BSS parms during tran. to ASSOCIATED state */ - wlc_bss_info_t *current_bss; /* BSS parms in ASSOCIATED state */ - - /* PM states */ - bool PMawakebcn; /* bcn recvd during current waking state */ - bool PMpending; /* waiting for tx status with PM indicated set */ - bool priorPMstate; /* Detecting PM state transitions */ - bool PSpoll; /* whether there is an outstanding PS-Poll frame */ - - /* BSSID entry in RCMTA, use the wsec key management infrastructure to - * manage the RCMTA entries. - */ - wsec_key_t *rcmta; - - /* 'unique' ID of this bsscfg, assigned at bsscfg allocation */ - u16 ID; - - uint txrspecidx; /* index into tx rate circular buffer */ - ratespec_t txrspec[NTXRATE][2]; /* circular buffer of prev MPDUs tx rates */ -}; - -#define WLC_BSSCFG_11N_DISABLE 0x1000 /* Do not advertise .11n IEs for this BSS */ -#define WLC_BSSCFG_HW_BCN 0x20 /* The BSS is generating beacons in HW */ - -#define HWBCN_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_BCN) != 0) -#define HWPRB_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_PRB) != 0) - -extern void wlc_bsscfg_ID_assign(struct wlc_info *wlc, wlc_bsscfg_t * bsscfg); - -/* Extend N_ENAB to per-BSS */ -#define BSS_N_ENAB(wlc, cfg) \ - (N_ENAB((wlc)->pub) && !((cfg)->flags & WLC_BSSCFG_11N_DISABLE)) - -#define MBSS_BCN_ENAB(cfg) 0 -#define MBSS_PRB_ENAB(cfg) 0 -#define SOFTBCN_ENAB(pub) (0) -#define SOFTPRB_ENAB(pub) (0) -#define wlc_bsscfg_tx_check(a) do { } while (0); - -#endif /* _WLC_BSSCFG_H_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_cfg.h b/drivers/staging/brcm80211/sys/wlc_cfg.h deleted file mode 100644 index 3decb7d1a5e5..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_cfg.h +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_cfg_h_ -#define _wlc_cfg_h_ - -#define NBANDS(wlc) ((wlc)->pub->_nbands) -#define NBANDS_PUB(pub) ((pub)->_nbands) -#define NBANDS_HW(hw) ((hw)->_nbands) - -#define IS_SINGLEBAND_5G(device) 0 - -/* **** Core type/rev defaults **** */ -#define D11_DEFAULT 0x0fffffb0 /* Supported D11 revs: 4, 5, 7-27 - * also need to update wlc.h MAXCOREREV - */ - -#define NPHY_DEFAULT 0x000001ff /* Supported nphy revs: - * 0 4321a0 - * 1 4321a1 - * 2 4321b0/b1/c0/c1 - * 3 4322a0 - * 4 4322a1 - * 5 4716a0 - * 6 43222a0, 43224a0 - * 7 43226a0 - * 8 5357a0, 43236a0 - */ - -#define LCNPHY_DEFAULT 0x00000007 /* Supported lcnphy revs: - * 0 4313a0, 4336a0, 4330a0 - * 1 - * 2 4330a0 - */ - -#define SSLPNPHY_DEFAULT 0x0000000f /* Supported sslpnphy revs: - * 0 4329a0/k0 - * 1 4329b0/4329C0 - * 2 4319a0 - * 3 5356a0 - */ - - -/* For undefined values, use defaults */ -#ifndef D11CONF -#define D11CONF D11_DEFAULT -#endif -#ifndef NCONF -#define NCONF NPHY_DEFAULT -#endif -#ifndef LCNCONF -#define LCNCONF LCNPHY_DEFAULT -#endif - -#ifndef SSLPNCONF -#define SSLPNCONF SSLPNPHY_DEFAULT -#endif - -#define BAND2G -#define BAND5G -#define WLANTSEL 1 - -/******************************************************************** - * Phy/Core Configuration. Defines macros to to check core phy/rev * - * compile-time configuration. Defines default core support. * - * ****************************************************************** - */ - -/* Basic macros to check a configuration bitmask */ - -#define CONF_HAS(config, val) ((config) & (1 << (val))) -#define CONF_MSK(config, mask) ((config) & (mask)) -#define MSK_RANGE(low, hi) ((1 << ((hi)+1)) - (1 << (low))) -#define CONF_RANGE(config, low, hi) (CONF_MSK(config, MSK_RANGE(low, high))) - -#define CONF_IS(config, val) ((config) == (1 << (val))) -#define CONF_GE(config, val) ((config) & (0-(1 << (val)))) -#define CONF_GT(config, val) ((config) & (0-2*(1 << (val)))) -#define CONF_LT(config, val) ((config) & ((1 << (val))-1)) -#define CONF_LE(config, val) ((config) & (2*(1 << (val))-1)) - -/* Wrappers for some of the above, specific to config constants */ - -#define NCONF_HAS(val) CONF_HAS(NCONF, val) -#define NCONF_MSK(mask) CONF_MSK(NCONF, mask) -#define NCONF_IS(val) CONF_IS(NCONF, val) -#define NCONF_GE(val) CONF_GE(NCONF, val) -#define NCONF_GT(val) CONF_GT(NCONF, val) -#define NCONF_LT(val) CONF_LT(NCONF, val) -#define NCONF_LE(val) CONF_LE(NCONF, val) - -#define LCNCONF_HAS(val) CONF_HAS(LCNCONF, val) -#define LCNCONF_MSK(mask) CONF_MSK(LCNCONF, mask) -#define LCNCONF_IS(val) CONF_IS(LCNCONF, val) -#define LCNCONF_GE(val) CONF_GE(LCNCONF, val) -#define LCNCONF_GT(val) CONF_GT(LCNCONF, val) -#define LCNCONF_LT(val) CONF_LT(LCNCONF, val) -#define LCNCONF_LE(val) CONF_LE(LCNCONF, val) - -#define D11CONF_HAS(val) CONF_HAS(D11CONF, val) -#define D11CONF_MSK(mask) CONF_MSK(D11CONF, mask) -#define D11CONF_IS(val) CONF_IS(D11CONF, val) -#define D11CONF_GE(val) CONF_GE(D11CONF, val) -#define D11CONF_GT(val) CONF_GT(D11CONF, val) -#define D11CONF_LT(val) CONF_LT(D11CONF, val) -#define D11CONF_LE(val) CONF_LE(D11CONF, val) - -#define PHYCONF_HAS(val) CONF_HAS(PHYTYPE, val) -#define PHYCONF_IS(val) CONF_IS(PHYTYPE, val) - -#define NREV_IS(var, val) (NCONF_HAS(val) && (NCONF_IS(val) || ((var) == (val)))) -#define NREV_GE(var, val) (NCONF_GE(val) && (!NCONF_LT(val) || ((var) >= (val)))) -#define NREV_GT(var, val) (NCONF_GT(val) && (!NCONF_LE(val) || ((var) > (val)))) -#define NREV_LT(var, val) (NCONF_LT(val) && (!NCONF_GE(val) || ((var) < (val)))) -#define NREV_LE(var, val) (NCONF_LE(val) && (!NCONF_GT(val) || ((var) <= (val)))) - -#define LCNREV_IS(var, val) (LCNCONF_HAS(val) && (LCNCONF_IS(val) || ((var) == (val)))) -#define LCNREV_GE(var, val) (LCNCONF_GE(val) && (!LCNCONF_LT(val) || ((var) >= (val)))) -#define LCNREV_GT(var, val) (LCNCONF_GT(val) && (!LCNCONF_LE(val) || ((var) > (val)))) -#define LCNREV_LT(var, val) (LCNCONF_LT(val) && (!LCNCONF_GE(val) || ((var) < (val)))) -#define LCNREV_LE(var, val) (LCNCONF_LE(val) && (!LCNCONF_GT(val) || ((var) <= (val)))) - -#define D11REV_IS(var, val) (D11CONF_HAS(val) && (D11CONF_IS(val) || ((var) == (val)))) -#define D11REV_GE(var, val) (D11CONF_GE(val) && (!D11CONF_LT(val) || ((var) >= (val)))) -#define D11REV_GT(var, val) (D11CONF_GT(val) && (!D11CONF_LE(val) || ((var) > (val)))) -#define D11REV_LT(var, val) (D11CONF_LT(val) && (!D11CONF_GE(val) || ((var) < (val)))) -#define D11REV_LE(var, val) (D11CONF_LE(val) && (!D11CONF_GT(val) || ((var) <= (val)))) - -#define PHYTYPE_IS(var, val) (PHYCONF_HAS(val) && (PHYCONF_IS(val) || ((var) == (val)))) - -/* Finally, early-exit from switch case if anyone wants it... */ - -#define CASECHECK(config, val) if (!(CONF_HAS(config, val))) break -#define CASEMSK(config, mask) if (!(CONF_MSK(config, mask))) break - -#if (D11CONF ^ (D11CONF & D11_DEFAULT)) -#error "Unsupported MAC revision configured" -#endif -#if (NCONF ^ (NCONF & NPHY_DEFAULT)) -#error "Unsupported NPHY revision configured" -#endif -#if (LCNCONF ^ (LCNCONF & LCNPHY_DEFAULT)) -#error "Unsupported LPPHY revision configured" -#endif - -/* *** Consistency checks *** */ -#if !D11CONF -#error "No MAC revisions configured!" -#endif - -#if !NCONF && !LCNCONF && !SSLPNCONF -#error "No PHY configured!" -#endif - -/* Set up PHYTYPE automatically: (depends on PHY_TYPE_X, from d11.h) */ - -#define _PHYCONF_N (1 << PHY_TYPE_N) - -#if LCNCONF -#define _PHYCONF_LCN (1 << PHY_TYPE_LCN) -#else -#define _PHYCONF_LCN 0 -#endif /* LCNCONF */ - -#if SSLPNCONF -#define _PHYCONF_SSLPN (1 << PHY_TYPE_SSN) -#else -#define _PHYCONF_SSLPN 0 -#endif /* SSLPNCONF */ - -#define PHYTYPE (_PHYCONF_N | _PHYCONF_LCN | _PHYCONF_SSLPN) - -/* Utility macro to identify 802.11n (HT) capable PHYs */ -#define PHYTYPE_11N_CAP(phytype) \ - (PHYTYPE_IS(phytype, PHY_TYPE_N) || \ - PHYTYPE_IS(phytype, PHY_TYPE_LCN) || \ - PHYTYPE_IS(phytype, PHY_TYPE_SSN)) - -/* Last but not least: shorter wlc-specific var checks */ -#define WLCISNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_N) -#define WLCISLCNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_LCN) -#define WLCISSSLPNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_SSN) - -#define WLC_PHY_11N_CAP(band) PHYTYPE_11N_CAP((band)->phytype) - -/********************************************************************** - * ------------- End of Core phy/rev configuration. ----------------- * - * ******************************************************************** - */ - -/************************************************* - * Defaults for tunables (e.g. sizing constants) - * - * For each new tunable, add a member to the end - * of wlc_tunables_t in wlc_pub.h to enable - * runtime checks of tunable values. (Directly - * using the macros in code invalidates ROM code) - * - * *********************************************** - */ -#ifndef NTXD -#define NTXD 256 /* Max # of entries in Tx FIFO based on 4kb page size */ -#endif /* NTXD */ -#ifndef NRXD -#define NRXD 256 /* Max # of entries in Rx FIFO based on 4kb page size */ -#endif /* NRXD */ - -#ifndef NRXBUFPOST -#define NRXBUFPOST 32 /* try to keep this # rbufs posted to the chip */ -#endif /* NRXBUFPOST */ - -#ifndef MAXSCB /* station control blocks in cache */ -#define MAXSCB 32 /* Maximum SCBs in cache for STA */ -#endif /* MAXSCB */ - -#ifndef AMPDU_NUM_MPDU -#define AMPDU_NUM_MPDU 16 /* max allowed number of mpdus in an ampdu (2 streams) */ -#endif /* AMPDU_NUM_MPDU */ - -#ifndef AMPDU_NUM_MPDU_3STREAMS -#define AMPDU_NUM_MPDU_3STREAMS 32 /* max allowed number of mpdus in an ampdu for 3+ streams */ -#endif /* AMPDU_NUM_MPDU_3STREAMS */ - -/* Count of packet callback structures. either of following - * 1. Set to the number of SCBs since a STA - * can queue up a rate callback for each IBSS STA it knows about, and an AP can - * queue up an "are you there?" Null Data callback for each associated STA - * 2. controlled by tunable config file - */ -#ifndef MAXPKTCB -#define MAXPKTCB MAXSCB /* Max number of packet callbacks */ -#endif /* MAXPKTCB */ - -#ifndef CTFPOOLSZ -#define CTFPOOLSZ 128 -#endif /* CTFPOOLSZ */ - -/* NetBSD also needs to keep track of this */ -#define WLC_MAX_UCODE_BSS (16) /* Number of BSS handled in ucode bcn/prb */ -#define WLC_MAX_UCODE_BSS4 (4) /* Number of BSS handled in sw bcn/prb */ -#ifndef WLC_MAXBSSCFG -#define WLC_MAXBSSCFG (1) /* max # BSS configs */ -#endif /* WLC_MAXBSSCFG */ - -#ifndef MAXBSS -#define MAXBSS 64 /* max # available networks */ -#endif /* MAXBSS */ - -#ifndef WLC_DATAHIWAT -#define WLC_DATAHIWAT 50 /* data msg txq hiwat mark */ -#endif /* WLC_DATAHIWAT */ - -#ifndef WLC_AMPDUDATAHIWAT -#define WLC_AMPDUDATAHIWAT 255 -#endif /* WLC_AMPDUDATAHIWAT */ - -/* bounded rx loops */ -#ifndef RXBND -#define RXBND 8 /* max # frames to process in wlc_recv() */ -#endif /* RXBND */ -#ifndef TXSBND -#define TXSBND 8 /* max # tx status to process in wlc_txstatus() */ -#endif /* TXSBND */ - -#define BAND_5G(bt) ((bt) == WLC_BAND_5G) -#define BAND_2G(bt) ((bt) == WLC_BAND_2G) - -#define WLBANDINITDATA(_data) _data -#define WLBANDINITFN(_fn) _fn - -#define WLANTSEL_ENAB(wlc) 1 - -#endif /* _wlc_cfg_h_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_channel.c b/drivers/staging/brcm80211/sys/wlc_channel.c deleted file mode 100644 index a35c15214880..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_channel.c +++ /dev/null @@ -1,1609 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct wlc_cm_band { - u8 locale_flags; /* locale_info_t flags */ - chanvec_t valid_channels; /* List of valid channels in the country */ - const chanvec_t *restricted_channels; /* List of restricted use channels */ - const chanvec_t *radar_channels; /* List of radar sensitive channels */ - u8 PAD[8]; -} wlc_cm_band_t; - -struct wlc_cm_info { - struct wlc_pub *pub; - struct wlc_info *wlc; - char srom_ccode[WLC_CNTRY_BUF_SZ]; /* Country Code in SROM */ - uint srom_regrev; /* Regulatory Rev for the SROM ccode */ - const country_info_t *country; /* current country def */ - char ccode[WLC_CNTRY_BUF_SZ]; /* current internal Country Code */ - uint regrev; /* current Regulatory Revision */ - char country_abbrev[WLC_CNTRY_BUF_SZ]; /* current advertised ccode */ - wlc_cm_band_t bandstate[MAXBANDS]; /* per-band state (one per phy/radio) */ - /* quiet channels currently for radar sensitivity or 11h support */ - chanvec_t quiet_channels; /* channels on which we cannot transmit */ -}; - -static int wlc_channels_init(wlc_cm_info_t *wlc_cm, - const country_info_t *country); -static void wlc_set_country_common(wlc_cm_info_t *wlc_cm, - const char *country_abbrev, - const char *ccode, uint regrev, - const country_info_t *country); -static int wlc_country_aggregate_map(wlc_cm_info_t *wlc_cm, const char *ccode, - char *mapped_ccode, uint *mapped_regrev); -static const country_info_t *wlc_country_lookup_direct(const char *ccode, - uint regrev); -static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm, - const char *ccode, - char *mapped_ccode, - uint *mapped_regrev); -static void wlc_channels_commit(wlc_cm_info_t *wlc_cm); -static bool wlc_japan_ccode(const char *ccode); -static void wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t * - wlc_cm, - struct - txpwr_limits - *txpwr, - u8 - local_constraint_qdbm); -void wlc_locale_add_channels(chanvec_t *target, const chanvec_t *channels); -static const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx); -static const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx); - -/* QDB() macro takes a dB value and converts to a quarter dB value */ -#ifdef QDB -#undef QDB -#endif -#define QDB(n) ((n) * WLC_TXPWR_DB_FACTOR) - -/* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */ - -/* - * Some common channel sets - */ - -/* No channels */ -static const chanvec_t chanvec_none = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -/* All 2.4 GHz HW channels */ -const chanvec_t chanvec_all_2G = { - {0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -/* All 5 GHz HW channels */ -const chanvec_t chanvec_all_5G = { - {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x11, 0x11, - 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x20, 0x22, 0x22, 0x00, 0x00, 0x11, - 0x11, 0x11, 0x11, 0x01} -}; - -/* - * Radar channel sets - */ - -/* No radar */ -#define radar_set_none chanvec_none - -static const chanvec_t radar_set1 = { /* Channels 52 - 64, 100 - 140 */ - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, /* 52 - 60 */ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, /* 64, 100 - 124 */ - 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 128 - 140 */ - 0x00, 0x00, 0x00, 0x00} -}; - -/* - * Restricted channel sets - */ - -#define restricted_set_none chanvec_none - -/* Channels 34, 38, 42, 46 */ -static const chanvec_t restricted_set_japan_legacy = { - {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -/* Channels 12, 13 */ -static const chanvec_t restricted_set_2g_short = { - {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -/* Channel 165 */ -static const chanvec_t restricted_chan_165 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -/* Channels 36 - 48 & 149 - 165 */ -static const chanvec_t restricted_low_hi = { - {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x20, 0x22, 0x22, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -/* Channels 12 - 14 */ -static const chanvec_t restricted_set_12_13_14 = { - {0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -#define LOCALE_CHAN_01_11 (1<<0) -#define LOCALE_CHAN_12_13 (1<<1) -#define LOCALE_CHAN_14 (1<<2) -#define LOCALE_SET_5G_LOW_JP1 (1<<3) /* 34-48, step 2 */ -#define LOCALE_SET_5G_LOW_JP2 (1<<4) /* 34-46, step 4 */ -#define LOCALE_SET_5G_LOW1 (1<<5) /* 36-48, step 4 */ -#define LOCALE_SET_5G_LOW2 (1<<6) /* 52 */ -#define LOCALE_SET_5G_LOW3 (1<<7) /* 56-64, step 4 */ -#define LOCALE_SET_5G_MID1 (1<<8) /* 100-116, step 4 */ -#define LOCALE_SET_5G_MID2 (1<<9) /* 120-124, step 4 */ -#define LOCALE_SET_5G_MID3 (1<<10) /* 128 */ -#define LOCALE_SET_5G_HIGH1 (1<<11) /* 132-140, step 4 */ -#define LOCALE_SET_5G_HIGH2 (1<<12) /* 149-161, step 4 */ -#define LOCALE_SET_5G_HIGH3 (1<<13) /* 165 */ -#define LOCALE_CHAN_52_140_ALL (1<<14) -#define LOCALE_SET_5G_HIGH4 (1<<15) /* 184-216 */ - -#define LOCALE_CHAN_36_64 (LOCALE_SET_5G_LOW1 | LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3) -#define LOCALE_CHAN_52_64 (LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3) -#define LOCALE_CHAN_100_124 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2) -#define LOCALE_CHAN_100_140 \ - (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1) -#define LOCALE_CHAN_149_165 (LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3) -#define LOCALE_CHAN_184_216 LOCALE_SET_5G_HIGH4 - -#define LOCALE_CHAN_01_14 (LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13 | LOCALE_CHAN_14) - -#define LOCALE_RADAR_SET_NONE 0 -#define LOCALE_RADAR_SET_1 1 - -#define LOCALE_RESTRICTED_NONE 0 -#define LOCALE_RESTRICTED_SET_2G_SHORT 1 -#define LOCALE_RESTRICTED_CHAN_165 2 -#define LOCALE_CHAN_ALL_5G 3 -#define LOCALE_RESTRICTED_JAPAN_LEGACY 4 -#define LOCALE_RESTRICTED_11D_2G 5 -#define LOCALE_RESTRICTED_11D_5G 6 -#define LOCALE_RESTRICTED_LOW_HI 7 -#define LOCALE_RESTRICTED_12_13_14 8 - -/* global memory to provide working buffer for expanded locale */ - -static const chanvec_t *g_table_radar_set[] = { - &chanvec_none, - &radar_set1 -}; - -static const chanvec_t *g_table_restricted_chan[] = { - &chanvec_none, /* restricted_set_none */ - &restricted_set_2g_short, - &restricted_chan_165, - &chanvec_all_5G, - &restricted_set_japan_legacy, - &chanvec_all_2G, /* restricted_set_11d_2G */ - &chanvec_all_5G, /* restricted_set_11d_5G */ - &restricted_low_hi, - &restricted_set_12_13_14 -}; - -static const chanvec_t locale_2g_01_11 = { - {0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_2g_12_13 = { - {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_2g_14 = { - {0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_LOW_JP1 = { - {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_LOW_JP2 = { - {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_LOW1 = { - {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_LOW2 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_LOW3 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_MID1 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_MID2 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_MID3 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_HIGH1 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_HIGH2 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x20, 0x22, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_HIGH3 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_52_140_ALL = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_HIGH4 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, - 0x11, 0x11, 0x11, 0x11} -}; - -static const chanvec_t *g_table_locale_base[] = { - &locale_2g_01_11, - &locale_2g_12_13, - &locale_2g_14, - &locale_5g_LOW_JP1, - &locale_5g_LOW_JP2, - &locale_5g_LOW1, - &locale_5g_LOW2, - &locale_5g_LOW3, - &locale_5g_MID1, - &locale_5g_MID2, - &locale_5g_MID3, - &locale_5g_HIGH1, - &locale_5g_HIGH2, - &locale_5g_HIGH3, - &locale_5g_52_140_ALL, - &locale_5g_HIGH4 -}; - -void wlc_locale_add_channels(chanvec_t *target, const chanvec_t *channels) -{ - u8 i; - for (i = 0; i < sizeof(chanvec_t); i++) { - target->vec[i] |= channels->vec[i]; - } -} - -void wlc_locale_get_channels(const locale_info_t *locale, chanvec_t *channels) -{ - u8 i; - - memset(channels, 0, sizeof(chanvec_t)); - - for (i = 0; i < ARRAY_SIZE(g_table_locale_base); i++) { - if (locale->valid_channels & (1 << i)) { - wlc_locale_add_channels(channels, - g_table_locale_base[i]); - } - } -} - -/* - * Locale Definitions - 2.4 GHz - */ -static const locale_info_t locale_i = { /* locale i. channel 1 - 13 */ - LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13, - LOCALE_RADAR_SET_NONE, - LOCALE_RESTRICTED_SET_2G_SHORT, - {QDB(19), QDB(19), QDB(19), - QDB(19), QDB(19), QDB(19)}, - {20, 20, 20, 0}, - WLC_EIRP -}; - -/* - * Locale Definitions - 5 GHz - */ -static const locale_info_t locale_11 = { - /* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */ - LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165, - LOCALE_RADAR_SET_1, - LOCALE_RESTRICTED_NONE, - {QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)}, - {23, 23, 23, 30, 30}, - WLC_EIRP | WLC_DFS_EU -}; - -#define LOCALE_2G_IDX_i 0 -static const locale_info_t *g_locale_2g_table[] = { - &locale_i -}; - -#define LOCALE_5G_IDX_11 0 -static const locale_info_t *g_locale_5g_table[] = { - &locale_11 -}; - -/* - * MIMO Locale Definitions - 2.4 GHz - */ -static const locale_mimo_info_t locale_bn = { - {QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), - QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), - QDB(13), QDB(13), QDB(13)}, - {0, 0, QDB(13), QDB(13), QDB(13), - QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), - QDB(13), 0, 0}, - 0 -}; - -/* locale mimo 2g indexes */ -#define LOCALE_MIMO_IDX_bn 0 - -static const locale_mimo_info_t *g_mimo_2g_table[] = { - &locale_bn -}; - -/* - * MIMO Locale Definitions - 5 GHz - */ -static const locale_mimo_info_t locale_11n = { - { /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)}, - {QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)}, - 0 -}; - -#define LOCALE_MIMO_IDX_11n 0 -static const locale_mimo_info_t *g_mimo_5g_table[] = { - &locale_11n -}; - -#ifdef LC -#undef LC -#endif -#define LC(id) LOCALE_MIMO_IDX_ ## id - -#ifdef LC_2G -#undef LC_2G -#endif -#define LC_2G(id) LOCALE_2G_IDX_ ## id - -#ifdef LC_5G -#undef LC_5G -#endif -#define LC_5G(id) LOCALE_5G_IDX_ ## id - -#define LOCALES(band2, band5, mimo2, mimo5) {LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)} - -static const struct { - char abbrev[WLC_CNTRY_BUF_SZ]; /* country abbreviation */ - country_info_t country; -} cntry_locales[] = { - { - "X2", LOCALES(i, 11, bn, 11n)}, /* Worldwide RoW 2 */ -}; - -#ifdef SUPPORT_40MHZ -/* 20MHz channel info for 40MHz pairing support */ -struct chan20_info { - u8 sb; - u8 adj_sbs; -}; - -/* indicates adjacent channels that are allowed for a 40 Mhz channel and - * those that permitted by the HT - */ -struct chan20_info chan20_info[] = { - /* 11b/11g */ -/* 0 */ {1, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 1 */ {2, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 2 */ {3, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 3 */ {4, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 4 */ {5, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, -/* 5 */ {6, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, -/* 6 */ {7, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, -/* 7 */ {8, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, -/* 8 */ {9, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, -/* 9 */ {10, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 10 */ {11, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 11 */ {12, (CH_LOWER_SB)}, -/* 12 */ {13, (CH_LOWER_SB)}, -/* 13 */ {14, (CH_LOWER_SB)}, - -/* 11a japan high */ -/* 14 */ {34, (CH_UPPER_SB)}, -/* 15 */ {38, (CH_LOWER_SB)}, -/* 16 */ {42, (CH_LOWER_SB)}, -/* 17 */ {46, (CH_LOWER_SB)}, - -/* 11a usa low */ -/* 18 */ {36, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 19 */ {40, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 20 */ {44, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 21 */ {48, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 22 */ {52, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 23 */ {56, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 24 */ {60, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 25 */ {64, (CH_LOWER_SB | CH_EWA_VALID)}, - -/* 11a Europe */ -/* 26 */ {100, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 27 */ {104, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 28 */ {108, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 29 */ {112, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 30 */ {116, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 31 */ {120, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 32 */ {124, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 33 */ {128, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 34 */ {132, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 35 */ {136, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 36 */ {140, (CH_LOWER_SB)}, - -/* 11a usa high, ref5 only */ -/* The 0x80 bit in pdiv means these are REF5, other entries are REF20 */ -/* 37 */ {149, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 38 */ {153, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 39 */ {157, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 40 */ {161, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 41 */ {165, (CH_LOWER_SB)}, - -/* 11a japan */ -/* 42 */ {184, (CH_UPPER_SB)}, -/* 43 */ {188, (CH_LOWER_SB)}, -/* 44 */ {192, (CH_UPPER_SB)}, -/* 45 */ {196, (CH_LOWER_SB)}, -/* 46 */ {200, (CH_UPPER_SB)}, -/* 47 */ {204, (CH_LOWER_SB)}, -/* 48 */ {208, (CH_UPPER_SB)}, -/* 49 */ {212, (CH_LOWER_SB)}, -/* 50 */ {216, (CH_LOWER_SB)} -}; -#endif /* SUPPORT_40MHZ */ - -const locale_info_t *wlc_get_locale_2g(u8 locale_idx) -{ - if (locale_idx >= ARRAY_SIZE(g_locale_2g_table)) { - WL_ERROR("%s: locale 2g index size out of range %d\n", - __func__, locale_idx); - ASSERT(locale_idx < ARRAY_SIZE(g_locale_2g_table)); - return NULL; - } - return g_locale_2g_table[locale_idx]; -} - -const locale_info_t *wlc_get_locale_5g(u8 locale_idx) -{ - if (locale_idx >= ARRAY_SIZE(g_locale_5g_table)) { - WL_ERROR("%s: locale 5g index size out of range %d\n", - __func__, locale_idx); - ASSERT(locale_idx < ARRAY_SIZE(g_locale_5g_table)); - return NULL; - } - return g_locale_5g_table[locale_idx]; -} - -const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx) -{ - if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table)) { - WL_ERROR("%s: mimo 2g index size out of range %d\n", - __func__, locale_idx); - return NULL; - } - return g_mimo_2g_table[locale_idx]; -} - -const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx) -{ - if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table)) { - WL_ERROR("%s: mimo 5g index size out of range %d\n", - __func__, locale_idx); - return NULL; - } - return g_mimo_5g_table[locale_idx]; -} - -wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc) -{ - wlc_cm_info_t *wlc_cm; - char country_abbrev[WLC_CNTRY_BUF_SZ]; - const country_info_t *country; - struct wlc_pub *pub = wlc->pub; - char *ccode; - - WL_TRACE("wl%d: wlc_channel_mgr_attach\n", wlc->pub->unit); - - wlc_cm = kzalloc(sizeof(wlc_cm_info_t), GFP_ATOMIC); - if (wlc_cm == NULL) { - WL_ERROR("wl%d: %s: out of memory", pub->unit, __func__); - return NULL; - } - wlc_cm->pub = pub; - wlc_cm->wlc = wlc; - wlc->cmi = wlc_cm; - - /* store the country code for passing up as a regulatory hint */ - ccode = getvar(wlc->pub->vars, "ccode"); - if (ccode) { - strncpy(wlc->pub->srom_ccode, ccode, WLC_CNTRY_BUF_SZ - 1); - WL_NONE("%s: SROM country code is %c%c\n", - __func__, - wlc->pub->srom_ccode[0], wlc->pub->srom_ccode[1]); - } - - /* internal country information which must match regulatory constraints in firmware */ - memset(country_abbrev, 0, WLC_CNTRY_BUF_SZ); - strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1); - country = wlc_country_lookup(wlc, country_abbrev); - - ASSERT(country != NULL); - - /* save default country for exiting 11d regulatory mode */ - strncpy(wlc->country_default, country_abbrev, WLC_CNTRY_BUF_SZ - 1); - - /* initialize autocountry_default to driver default */ - strncpy(wlc->autocountry_default, "X2", WLC_CNTRY_BUF_SZ - 1); - - wlc_set_countrycode(wlc_cm, country_abbrev); - - return wlc_cm; -} - -void wlc_channel_mgr_detach(wlc_cm_info_t *wlc_cm) -{ - if (wlc_cm) - kfree(wlc_cm); -} - -const char *wlc_channel_country_abbrev(wlc_cm_info_t *wlc_cm) -{ - return wlc_cm->country_abbrev; -} - -u8 wlc_channel_locale_flags(wlc_cm_info_t *wlc_cm) -{ - struct wlc_info *wlc = wlc_cm->wlc; - - return wlc_cm->bandstate[wlc->band->bandunit].locale_flags; -} - -u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, uint bandunit) -{ - return wlc_cm->bandstate[bandunit].locale_flags; -} - -/* return chanvec for a given country code and band */ -bool -wlc_channel_get_chanvec(struct wlc_info *wlc, const char *country_abbrev, - int bandtype, chanvec_t *channels) -{ - const country_info_t *country; - const locale_info_t *locale = NULL; - - country = wlc_country_lookup(wlc, country_abbrev); - if (country == NULL) - return false; - - if (bandtype == WLC_BAND_2G) - locale = wlc_get_locale_2g(country->locale_2G); - else if (bandtype == WLC_BAND_5G) - locale = wlc_get_locale_5g(country->locale_5G); - if (locale == NULL) - return false; - - wlc_locale_get_channels(locale, channels); - return true; -} - -/* set the driver's current country and regulatory information using a country code - * as the source. Lookup built in country information found with the country code. - */ -int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode) -{ - char country_abbrev[WLC_CNTRY_BUF_SZ]; - strncpy(country_abbrev, ccode, WLC_CNTRY_BUF_SZ); - return wlc_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1); -} - -int -wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, - const char *country_abbrev, - const char *ccode, int regrev) -{ - const country_info_t *country; - char mapped_ccode[WLC_CNTRY_BUF_SZ]; - uint mapped_regrev; - - WL_NONE("%s: (country_abbrev \"%s\", ccode \"%s\", regrev %d) SPROM \"%s\"/%u\n", - __func__, country_abbrev, ccode, regrev, - wlc_cm->srom_ccode, wlc_cm->srom_regrev); - - /* if regrev is -1, lookup the mapped country code, - * otherwise use the ccode and regrev directly - */ - if (regrev == -1) { - /* map the country code to a built-in country code, regrev, and country_info */ - country = - wlc_countrycode_map(wlc_cm, ccode, mapped_ccode, - &mapped_regrev); - } else { - /* find the matching built-in country definition */ - ASSERT(0); - country = wlc_country_lookup_direct(ccode, regrev); - strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ); - mapped_regrev = regrev; - } - - if (country == NULL) - return BCME_BADARG; - - /* set the driver state for the country */ - wlc_set_country_common(wlc_cm, country_abbrev, mapped_ccode, - mapped_regrev, country); - - return 0; -} - -/* set the driver's current country and regulatory information using a country code - * as the source. Look up built in country information found with the country code. - */ -static void -wlc_set_country_common(wlc_cm_info_t *wlc_cm, - const char *country_abbrev, - const char *ccode, uint regrev, - const country_info_t *country) -{ - const locale_mimo_info_t *li_mimo; - const locale_info_t *locale; - struct wlc_info *wlc = wlc_cm->wlc; - char prev_country_abbrev[WLC_CNTRY_BUF_SZ]; - - ASSERT(country != NULL); - - /* save current country state */ - wlc_cm->country = country; - - memset(&prev_country_abbrev, 0, WLC_CNTRY_BUF_SZ); - strncpy(prev_country_abbrev, wlc_cm->country_abbrev, - WLC_CNTRY_BUF_SZ - 1); - - strncpy(wlc_cm->country_abbrev, country_abbrev, WLC_CNTRY_BUF_SZ - 1); - strncpy(wlc_cm->ccode, ccode, WLC_CNTRY_BUF_SZ - 1); - wlc_cm->regrev = regrev; - - /* disable/restore nmode based on country regulations */ - li_mimo = wlc_get_mimo_2g(country->locale_mimo_2G); - if (li_mimo && (li_mimo->flags & WLC_NO_MIMO)) { - wlc_set_nmode(wlc, OFF); - wlc->stf->no_cddstbc = true; - } else { - wlc->stf->no_cddstbc = false; - if (N_ENAB(wlc->pub) != wlc->protection->nmode_user) - wlc_set_nmode(wlc, wlc->protection->nmode_user); - } - - wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); - wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); - /* set or restore gmode as required by regulatory */ - locale = wlc_get_locale_2g(country->locale_2G); - if (locale && (locale->flags & WLC_NO_OFDM)) { - wlc_set_gmode(wlc, GMODE_LEGACY_B, false); - } else { - wlc_set_gmode(wlc, wlc->protection->gmode_user, false); - } - - wlc_channels_init(wlc_cm, country); - - return; -} - -/* Lookup a country info structure from a null terminated country code - * The lookup is case sensitive. - */ -const country_info_t *wlc_country_lookup(struct wlc_info *wlc, - const char *ccode) -{ - const country_info_t *country; - char mapped_ccode[WLC_CNTRY_BUF_SZ]; - uint mapped_regrev; - - /* map the country code to a built-in country code, regrev, and country_info struct */ - country = - wlc_countrycode_map(wlc->cmi, ccode, mapped_ccode, &mapped_regrev); - - return country; -} - -static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm, - const char *ccode, - char *mapped_ccode, - uint *mapped_regrev) -{ - struct wlc_info *wlc = wlc_cm->wlc; - const country_info_t *country; - uint srom_regrev = wlc_cm->srom_regrev; - const char *srom_ccode = wlc_cm->srom_ccode; - int mapped; - - /* check for currently supported ccode size */ - if (strlen(ccode) > (WLC_CNTRY_BUF_SZ - 1)) { - WL_ERROR("wl%d: %s: ccode \"%s\" too long for match\n", - wlc->pub->unit, __func__, ccode); - return NULL; - } - - /* default mapping is the given ccode and regrev 0 */ - strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ); - *mapped_regrev = 0; - - /* If the desired country code matches the srom country code, - * then the mapped country is the srom regulatory rev. - * Otherwise look for an aggregate mapping. - */ - if (!strcmp(srom_ccode, ccode)) { - *mapped_regrev = srom_regrev; - mapped = 0; - WL_ERROR("srom_code == ccode %s\n", __func__); - ASSERT(0); - } else { - mapped = - wlc_country_aggregate_map(wlc_cm, ccode, mapped_ccode, - mapped_regrev); - } - - /* find the matching built-in country definition */ - country = wlc_country_lookup_direct(mapped_ccode, *mapped_regrev); - - /* if there is not an exact rev match, default to rev zero */ - if (country == NULL && *mapped_regrev != 0) { - *mapped_regrev = 0; - ASSERT(0); - country = - wlc_country_lookup_direct(mapped_ccode, *mapped_regrev); - } - - return country; -} - -static int -wlc_country_aggregate_map(wlc_cm_info_t *wlc_cm, const char *ccode, - char *mapped_ccode, uint *mapped_regrev) -{ - return false; -} - -/* Lookup a country info structure from a null terminated country - * abbreviation and regrev directly with no translation. - */ -static const country_info_t *wlc_country_lookup_direct(const char *ccode, - uint regrev) -{ - uint size, i; - - /* Should just return 0 for single locale driver. */ - /* Keep it this way in case we add more locales. (for now anyway) */ - - /* all other country def arrays are for regrev == 0, so if regrev is non-zero, fail */ - if (regrev > 0) - return NULL; - - /* find matched table entry from country code */ - size = ARRAY_SIZE(cntry_locales); - for (i = 0; i < size; i++) { - if (strcmp(ccode, cntry_locales[i].abbrev) == 0) { - return &cntry_locales[i].country; - } - } - - WL_ERROR("%s: Returning NULL\n", __func__); - ASSERT(0); - return NULL; -} - -static int -wlc_channels_init(wlc_cm_info_t *wlc_cm, const country_info_t *country) -{ - struct wlc_info *wlc = wlc_cm->wlc; - uint i, j; - struct wlcband *band; - const locale_info_t *li; - chanvec_t sup_chan; - const locale_mimo_info_t *li_mimo; - - band = wlc->band; - for (i = 0; i < NBANDS(wlc); - i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { - - li = BAND_5G(band->bandtype) ? - wlc_get_locale_5g(country->locale_5G) : - wlc_get_locale_2g(country->locale_2G); - ASSERT(li); - wlc_cm->bandstate[band->bandunit].locale_flags = li->flags; - li_mimo = BAND_5G(band->bandtype) ? - wlc_get_mimo_5g(country->locale_mimo_5G) : - wlc_get_mimo_2g(country->locale_mimo_2G); - ASSERT(li_mimo); - - /* merge the mimo non-mimo locale flags */ - wlc_cm->bandstate[band->bandunit].locale_flags |= - li_mimo->flags; - - wlc_cm->bandstate[band->bandunit].restricted_channels = - g_table_restricted_chan[li->restricted_channels]; - wlc_cm->bandstate[band->bandunit].radar_channels = - g_table_radar_set[li->radar_channels]; - - /* set the channel availability, - * masking out the channels that may not be supported on this phy - */ - wlc_phy_chanspec_band_validch(band->pi, band->bandtype, - &sup_chan); - wlc_locale_get_channels(li, - &wlc_cm->bandstate[band->bandunit]. - valid_channels); - for (j = 0; j < sizeof(chanvec_t); j++) - wlc_cm->bandstate[band->bandunit].valid_channels. - vec[j] &= sup_chan.vec[j]; - } - - wlc_quiet_channels_reset(wlc_cm); - wlc_channels_commit(wlc_cm); - - return 0; -} - -/* Update the radio state (enable/disable) and tx power targets - * based on a new set of channel/regulatory information - */ -static void wlc_channels_commit(wlc_cm_info_t *wlc_cm) -{ - struct wlc_info *wlc = wlc_cm->wlc; - uint chan; - struct txpwr_limits txpwr; - - /* search for the existence of any valid channel */ - for (chan = 0; chan < MAXCHANNEL; chan++) { - if (VALID_CHANNEL20_DB(wlc, chan)) { - break; - } - } - if (chan == MAXCHANNEL) - chan = INVCHANNEL; - - /* based on the channel search above, set or clear WL_RADIO_COUNTRY_DISABLE */ - if (chan == INVCHANNEL) { - /* country/locale with no valid channels, set the radio disable bit */ - mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); - WL_ERROR("wl%d: %s: no valid channel for \"%s\" nbands %d bandlocked %d\n", - wlc->pub->unit, __func__, - wlc_cm->country_abbrev, NBANDS(wlc), wlc->bandlocked); - } else - if (mboolisset(wlc->pub->radio_disabled, - WL_RADIO_COUNTRY_DISABLE)) { - /* country/locale with valid channel, clear the radio disable bit */ - mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); - } - - /* Now that the country abbreviation is set, if the radio supports 2G, then - * set channel 14 restrictions based on the new locale. - */ - if (NBANDS(wlc) > 1 || BAND_2G(wlc->band->bandtype)) { - wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi, - wlc_japan(wlc) ? true : - false); - } - - if (wlc->pub->up && chan != INVCHANNEL) { - wlc_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr); - wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, - &txpwr, - WLC_TXPWR_MAX); - wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec); - } -} - -/* reset the quiet channels vector to the union of the restricted and radar channel sets */ -void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm) -{ - struct wlc_info *wlc = wlc_cm->wlc; - uint i, j; - struct wlcband *band; - const chanvec_t *chanvec; - - memset(&wlc_cm->quiet_channels, 0, sizeof(chanvec_t)); - - band = wlc->band; - for (i = 0; i < NBANDS(wlc); - i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { - - /* initialize quiet channels for restricted channels */ - chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels; - for (j = 0; j < sizeof(chanvec_t); j++) - wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j]; - - } -} - -bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec) -{ - return N_ENAB(wlc_cm->wlc->pub) && CHSPEC_IS40(chspec) ? - (isset - (wlc_cm->quiet_channels.vec, - LOWER_20_SB(CHSPEC_CHANNEL(chspec))) - || isset(wlc_cm->quiet_channels.vec, - UPPER_20_SB(CHSPEC_CHANNEL(chspec)))) : isset(wlc_cm-> - quiet_channels. - vec, - CHSPEC_CHANNEL - (chspec)); -} - -/* Is the channel valid for the current locale? (but don't consider channels not - * available due to bandlocking) - */ -bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val) -{ - struct wlc_info *wlc = wlc_cm->wlc; - - return VALID_CHANNEL20(wlc, val) || - (!wlc->bandlocked - && VALID_CHANNEL20_IN_BAND(wlc, OTHERBANDUNIT(wlc), val)); -} - -/* Is the channel valid for the current locale and specified band? */ -bool -wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, uint val) -{ - return ((val < MAXCHANNEL) - && isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val)); -} - -/* Is the channel valid for the current locale and current band? */ -bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val) -{ - struct wlc_info *wlc = wlc_cm->wlc; - - return ((val < MAXCHANNEL) && - isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec, - val)); -} - -/* Is the 40 MHz allowed for the current locale and specified band? */ -bool wlc_valid_40chanspec_in_band(wlc_cm_info_t *wlc_cm, uint bandunit) -{ - struct wlc_info *wlc = wlc_cm->wlc; - - return (((wlc_cm->bandstate[bandunit]. - locale_flags & (WLC_NO_MIMO | WLC_NO_40MHZ)) == 0) - && wlc->bandstate[bandunit]->mimo_cap_40); -} - -static void -wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t *wlc_cm, - struct txpwr_limits *txpwr, - u8 - local_constraint_qdbm) -{ - int j; - - /* CCK Rates */ - for (j = 0; j < WL_TX_POWER_CCK_NUM; j++) { - txpwr->cck[j] = min(txpwr->cck[j], local_constraint_qdbm); - } - - /* 20 MHz Legacy OFDM SISO */ - for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++) { - txpwr->ofdm[j] = min(txpwr->ofdm[j], local_constraint_qdbm); - } - - /* 20 MHz Legacy OFDM CDD */ - for (j = 0; j < WLC_NUM_RATES_OFDM; j++) { - txpwr->ofdm_cdd[j] = - min(txpwr->ofdm_cdd[j], local_constraint_qdbm); - } - - /* 40 MHz Legacy OFDM SISO */ - for (j = 0; j < WLC_NUM_RATES_OFDM; j++) { - txpwr->ofdm_40_siso[j] = - min(txpwr->ofdm_40_siso[j], local_constraint_qdbm); - } - - /* 40 MHz Legacy OFDM CDD */ - for (j = 0; j < WLC_NUM_RATES_OFDM; j++) { - txpwr->ofdm_40_cdd[j] = - min(txpwr->ofdm_40_cdd[j], local_constraint_qdbm); - } - - /* 20MHz MCS 0-7 SISO */ - for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { - txpwr->mcs_20_siso[j] = - min(txpwr->mcs_20_siso[j], local_constraint_qdbm); - } - - /* 20MHz MCS 0-7 CDD */ - for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { - txpwr->mcs_20_cdd[j] = - min(txpwr->mcs_20_cdd[j], local_constraint_qdbm); - } - - /* 20MHz MCS 0-7 STBC */ - for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { - txpwr->mcs_20_stbc[j] = - min(txpwr->mcs_20_stbc[j], local_constraint_qdbm); - } - - /* 20MHz MCS 8-15 MIMO */ - for (j = 0; j < WLC_NUM_RATES_MCS_2_STREAM; j++) - txpwr->mcs_20_mimo[j] = - min(txpwr->mcs_20_mimo[j], local_constraint_qdbm); - - /* 40MHz MCS 0-7 SISO */ - for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { - txpwr->mcs_40_siso[j] = - min(txpwr->mcs_40_siso[j], local_constraint_qdbm); - } - - /* 40MHz MCS 0-7 CDD */ - for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { - txpwr->mcs_40_cdd[j] = - min(txpwr->mcs_40_cdd[j], local_constraint_qdbm); - } - - /* 40MHz MCS 0-7 STBC */ - for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { - txpwr->mcs_40_stbc[j] = - min(txpwr->mcs_40_stbc[j], local_constraint_qdbm); - } - - /* 40MHz MCS 8-15 MIMO */ - for (j = 0; j < WLC_NUM_RATES_MCS_2_STREAM; j++) - txpwr->mcs_40_mimo[j] = - min(txpwr->mcs_40_mimo[j], local_constraint_qdbm); - - /* 40MHz MCS 32 */ - txpwr->mcs32 = min(txpwr->mcs32, local_constraint_qdbm); - -} - -void -wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, - u8 local_constraint_qdbm) -{ - struct wlc_info *wlc = wlc_cm->wlc; - struct txpwr_limits txpwr; - - wlc_channel_reg_limits(wlc_cm, chanspec, &txpwr); - - wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr, - local_constraint_qdbm); - - wlc_bmac_set_chanspec(wlc->hw, chanspec, - (wlc_quiet_chanspec(wlc_cm, chanspec) != 0), - &txpwr); -} - -int -wlc_channel_set_txpower_limit(wlc_cm_info_t *wlc_cm, - u8 local_constraint_qdbm) -{ - struct wlc_info *wlc = wlc_cm->wlc; - struct txpwr_limits txpwr; - - wlc_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr); - - wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr, - local_constraint_qdbm); - - wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec); - - return 0; -} - -#ifdef POWER_DBG -static void wlc_phy_txpower_limits_dump(txpwr_limits_t *txpwr) -{ - int i; - char fraction[4][4] = { " ", ".25", ".5 ", ".75" }; - - printf("CCK "); - for (i = 0; i < WLC_NUM_RATES_CCK; i++) { - printf(" %2d%s", txpwr->cck[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->cck[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("20 MHz OFDM SISO "); - for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { - printf(" %2d%s", txpwr->ofdm[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->ofdm[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("20 MHz OFDM CDD "); - for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { - printf(" %2d%s", txpwr->ofdm_cdd[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->ofdm_cdd[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("40 MHz OFDM SISO "); - for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { - printf(" %2d%s", txpwr->ofdm_40_siso[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->ofdm_40_siso[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("40 MHz OFDM CDD "); - for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { - printf(" %2d%s", txpwr->ofdm_40_cdd[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->ofdm_40_cdd[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("20 MHz MCS0-7 SISO "); - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_20_siso[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_20_siso[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("20 MHz MCS0-7 CDD "); - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_20_cdd[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_20_cdd[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("20 MHz MCS0-7 STBC "); - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_20_stbc[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_20_stbc[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("20 MHz MCS8-15 SDM "); - for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_20_mimo[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_20_mimo[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("40 MHz MCS0-7 SISO "); - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_40_siso[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_40_siso[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("40 MHz MCS0-7 CDD "); - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_40_cdd[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_40_cdd[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("40 MHz MCS0-7 STBC "); - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_40_stbc[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_40_stbc[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("40 MHz MCS8-15 SDM "); - for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_40_mimo[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_40_mimo[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("MCS32 %2d%s\n", - txpwr->mcs32 / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs32 % WLC_TXPWR_DB_FACTOR]); -} -#endif /* POWER_DBG */ - -void -wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, - txpwr_limits_t *txpwr) -{ - struct wlc_info *wlc = wlc_cm->wlc; - uint i; - uint chan; - int maxpwr; - int delta; - const country_info_t *country; - struct wlcband *band; - const locale_info_t *li; - int conducted_max; - int conducted_ofdm_max; - const locale_mimo_info_t *li_mimo; - int maxpwr20, maxpwr40; - int maxpwr_idx; - uint j; - - memset(txpwr, 0, sizeof(txpwr_limits_t)); - - if (!wlc_valid_chanspec_db(wlc_cm, chanspec)) { - country = wlc_country_lookup(wlc, wlc->autocountry_default); - if (country == NULL) - return; - } else { - country = wlc_cm->country; - } - - chan = CHSPEC_CHANNEL(chanspec); - band = wlc->bandstate[CHSPEC_WLCBANDUNIT(chanspec)]; - li = BAND_5G(band->bandtype) ? - wlc_get_locale_5g(country->locale_5G) : - wlc_get_locale_2g(country->locale_2G); - - li_mimo = BAND_5G(band->bandtype) ? - wlc_get_mimo_5g(country->locale_mimo_5G) : - wlc_get_mimo_2g(country->locale_mimo_2G); - - if (li->flags & WLC_EIRP) { - delta = band->antgain; - } else { - delta = 0; - if (band->antgain > QDB(6)) - delta = band->antgain - QDB(6); /* Excess over 6 dB */ - } - - if (li == &locale_i) { - conducted_max = QDB(22); - conducted_ofdm_max = QDB(22); - } - - /* CCK txpwr limits for 2.4G band */ - if (BAND_2G(band->bandtype)) { - maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_CCK(chan)]; - - maxpwr = maxpwr - delta; - maxpwr = max(maxpwr, 0); - maxpwr = min(maxpwr, conducted_max); - - for (i = 0; i < WLC_NUM_RATES_CCK; i++) - txpwr->cck[i] = (u8) maxpwr; - } - - /* OFDM txpwr limits for 2.4G or 5G bands */ - if (BAND_2G(band->bandtype)) { - maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_OFDM(chan)]; - - } else { - maxpwr = li->maxpwr[CHANNEL_POWER_IDX_5G(chan)]; - } - - maxpwr = maxpwr - delta; - maxpwr = max(maxpwr, 0); - maxpwr = min(maxpwr, conducted_ofdm_max); - - /* Keep OFDM lmit below CCK limit */ - if (BAND_2G(band->bandtype)) - maxpwr = min_t(int, maxpwr, txpwr->cck[0]); - - for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { - txpwr->ofdm[i] = (u8) maxpwr; - } - - for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { - /* OFDM 40 MHz SISO has the same power as the corresponding MCS0-7 rate unless - * overriden by the locale specific code. We set this value to 0 as a - * flag (presumably 0 dBm isn't a possibility) and then copy the MCS0-7 value - * to the 40 MHz value if it wasn't explicitly set. - */ - txpwr->ofdm_40_siso[i] = 0; - - txpwr->ofdm_cdd[i] = (u8) maxpwr; - - txpwr->ofdm_40_cdd[i] = 0; - } - - /* MIMO/HT specific limits */ - if (li_mimo->flags & WLC_EIRP) { - delta = band->antgain; - } else { - delta = 0; - if (band->antgain > QDB(6)) - delta = band->antgain - QDB(6); /* Excess over 6 dB */ - } - - if (BAND_2G(band->bandtype)) - maxpwr_idx = (chan - 1); - else - maxpwr_idx = CHANNEL_POWER_IDX_5G(chan); - - maxpwr20 = li_mimo->maxpwr20[maxpwr_idx]; - maxpwr40 = li_mimo->maxpwr40[maxpwr_idx]; - - maxpwr20 = maxpwr20 - delta; - maxpwr20 = max(maxpwr20, 0); - maxpwr40 = maxpwr40 - delta; - maxpwr40 = max(maxpwr40, 0); - - /* Fill in the MCS 0-7 (SISO) rates */ - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - - /* 20 MHz has the same power as the corresponding OFDM rate unless - * overriden by the locale specific code. - */ - txpwr->mcs_20_siso[i] = txpwr->ofdm[i]; - txpwr->mcs_40_siso[i] = 0; - } - - /* Fill in the MCS 0-7 CDD rates */ - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - txpwr->mcs_20_cdd[i] = (u8) maxpwr20; - txpwr->mcs_40_cdd[i] = (u8) maxpwr40; - } - - /* These locales have SISO expressed in the table and override CDD later */ - if (li_mimo == &locale_bn) { - if (li_mimo == &locale_bn) { - maxpwr20 = QDB(16); - maxpwr40 = 0; - - if (chan >= 3 && chan <= 11) { - maxpwr40 = QDB(16); - } - } - - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - txpwr->mcs_20_siso[i] = (u8) maxpwr20; - txpwr->mcs_40_siso[i] = (u8) maxpwr40; - } - } - - /* Fill in the MCS 0-7 STBC rates */ - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - txpwr->mcs_20_stbc[i] = 0; - txpwr->mcs_40_stbc[i] = 0; - } - - /* Fill in the MCS 8-15 SDM rates */ - for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) { - txpwr->mcs_20_mimo[i] = (u8) maxpwr20; - txpwr->mcs_40_mimo[i] = (u8) maxpwr40; - } - - /* Fill in MCS32 */ - txpwr->mcs32 = (u8) maxpwr40; - - for (i = 0, j = 0; i < WLC_NUM_RATES_OFDM; i++, j++) { - if (txpwr->ofdm_40_cdd[i] == 0) - txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j]; - if (i == 0) { - i = i + 1; - if (txpwr->ofdm_40_cdd[i] == 0) - txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j]; - } - } - - /* Copy the 40 MHZ MCS 0-7 CDD value to the 40 MHZ MCS 0-7 SISO value if it wasn't - * provided explicitly. - */ - - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - if (txpwr->mcs_40_siso[i] == 0) - txpwr->mcs_40_siso[i] = txpwr->mcs_40_cdd[i]; - } - - for (i = 0, j = 0; i < WLC_NUM_RATES_OFDM; i++, j++) { - if (txpwr->ofdm_40_siso[i] == 0) - txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j]; - if (i == 0) { - i = i + 1; - if (txpwr->ofdm_40_siso[i] == 0) - txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j]; - } - } - - /* Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding STBC values if they weren't - * provided explicitly. - */ - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - if (txpwr->mcs_20_stbc[i] == 0) - txpwr->mcs_20_stbc[i] = txpwr->mcs_20_cdd[i]; - - if (txpwr->mcs_40_stbc[i] == 0) - txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i]; - } - -#ifdef POWER_DBG - wlc_phy_txpower_limits_dump(txpwr); -#endif - return; -} - -/* Returns true if currently set country is Japan or variant */ -bool wlc_japan(struct wlc_info *wlc) -{ - return wlc_japan_ccode(wlc->cmi->country_abbrev); -} - -/* JP, J1 - J10 are Japan ccodes */ -static bool wlc_japan_ccode(const char *ccode) -{ - return (ccode[0] == 'J' && - (ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9'))); -} - -/* - * Validate the chanspec for this locale, for 40MHZ we need to also check that the sidebands - * are valid 20MZH channels in this locale and they are also a legal HT combination - */ -static bool -wlc_valid_chanspec_ext(wlc_cm_info_t *wlc_cm, chanspec_t chspec, bool dualband) -{ - struct wlc_info *wlc = wlc_cm->wlc; - u8 channel = CHSPEC_CHANNEL(chspec); - - /* check the chanspec */ - if (wf_chspec_malformed(chspec)) { - WL_ERROR("wl%d: malformed chanspec 0x%x\n", - wlc->pub->unit, chspec); - ASSERT(0); - return false; - } - - if (CHANNEL_BANDUNIT(wlc_cm->wlc, channel) != - CHSPEC_WLCBANDUNIT(chspec)) - return false; - - /* Check a 20Mhz channel */ - if (CHSPEC_IS20(chspec)) { - if (dualband) - return VALID_CHANNEL20_DB(wlc_cm->wlc, channel); - else - return VALID_CHANNEL20(wlc_cm->wlc, channel); - } -#ifdef SUPPORT_40MHZ - /* We know we are now checking a 40MHZ channel, so we should only be here - * for NPHYS - */ - if (WLCISNPHY(wlc->band) || WLCISSSLPNPHY(wlc->band)) { - u8 upper_sideband = 0, idx; - u8 num_ch20_entries = - sizeof(chan20_info) / sizeof(struct chan20_info); - - if (!VALID_40CHANSPEC_IN_BAND(wlc, CHSPEC_WLCBANDUNIT(chspec))) - return false; - - if (dualband) { - if (!VALID_CHANNEL20_DB(wlc, LOWER_20_SB(channel)) || - !VALID_CHANNEL20_DB(wlc, UPPER_20_SB(channel))) - return false; - } else { - if (!VALID_CHANNEL20(wlc, LOWER_20_SB(channel)) || - !VALID_CHANNEL20(wlc, UPPER_20_SB(channel))) - return false; - } - - /* find the lower sideband info in the sideband array */ - for (idx = 0; idx < num_ch20_entries; idx++) { - if (chan20_info[idx].sb == LOWER_20_SB(channel)) - upper_sideband = chan20_info[idx].adj_sbs; - } - /* check that the lower sideband allows an upper sideband */ - if ((upper_sideband & (CH_UPPER_SB | CH_EWA_VALID)) == - (CH_UPPER_SB | CH_EWA_VALID)) - return true; - return false; - } -#endif /* 40 MHZ */ - - return false; -} - -bool wlc_valid_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec) -{ - return wlc_valid_chanspec_ext(wlc_cm, chspec, false); -} - -bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec) -{ - return wlc_valid_chanspec_ext(wlc_cm, chspec, true); -} diff --git a/drivers/staging/brcm80211/sys/wlc_channel.h b/drivers/staging/brcm80211/sys/wlc_channel.h deleted file mode 100644 index 1f170aff68fd..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_channel.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _WLC_CHANNEL_H_ -#define _WLC_CHANNEL_H_ - -#include - -#define WLC_TXPWR_DB_FACTOR 4 /* conversion for phy txpwr cacluations that use .25 dB units */ - -struct wlc_info; - -/* maxpwr mapping to 5GHz band channels: - * maxpwr[0] - channels [34-48] - * maxpwr[1] - channels [52-60] - * maxpwr[2] - channels [62-64] - * maxpwr[3] - channels [100-140] - * maxpwr[4] - channels [149-165] - */ -#define BAND_5G_PWR_LVLS 5 /* 5 power levels for 5G */ - -/* power level in group of 2.4GHz band channels: - * maxpwr[0] - CCK channels [1] - * maxpwr[1] - CCK channels [2-10] - * maxpwr[2] - CCK channels [11-14] - * maxpwr[3] - OFDM channels [1] - * maxpwr[4] - OFDM channels [2-10] - * maxpwr[5] - OFDM channels [11-14] - */ - -/* macro to get 2.4 GHz channel group index for tx power */ -#define CHANNEL_POWER_IDX_2G_CCK(c) (((c) < 2) ? 0 : (((c) < 11) ? 1 : 2)) /* cck index */ -#define CHANNEL_POWER_IDX_2G_OFDM(c) (((c) < 2) ? 3 : (((c) < 11) ? 4 : 5)) /* ofdm index */ - -/* macro to get 5 GHz channel group index for tx power */ -#define CHANNEL_POWER_IDX_5G(c) \ - (((c) < 52) ? 0 : (((c) < 62) ? 1 : (((c) < 100) ? 2 : (((c) < 149) ? 3 : 4)))) - -#define WLC_MAXPWR_TBL_SIZE 6 /* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */ -#define WLC_MAXPWR_MIMO_TBL_SIZE 14 /* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */ - -/* locale channel and power info. */ -typedef struct { - u32 valid_channels; - u8 radar_channels; /* List of radar sensitive channels */ - u8 restricted_channels; /* List of channels used only if APs are detected */ - s8 maxpwr[WLC_MAXPWR_TBL_SIZE]; /* Max tx pwr in qdBm for each sub-band */ - s8 pub_maxpwr[BAND_5G_PWR_LVLS]; /* Country IE advertised max tx pwr in dBm - * per sub-band - */ - u8 flags; -} locale_info_t; - -/* bits for locale_info flags */ -#define WLC_PEAK_CONDUCTED 0x00 /* Peak for locals */ -#define WLC_EIRP 0x01 /* Flag for EIRP */ -#define WLC_DFS_TPC 0x02 /* Flag for DFS TPC */ -#define WLC_NO_OFDM 0x04 /* Flag for No OFDM */ -#define WLC_NO_40MHZ 0x08 /* Flag for No MIMO 40MHz */ -#define WLC_NO_MIMO 0x10 /* Flag for No MIMO, 20 or 40 MHz */ -#define WLC_RADAR_TYPE_EU 0x20 /* Flag for EU */ -#define WLC_DFS_FCC WLC_DFS_TPC /* Flag for DFS FCC */ -#define WLC_DFS_EU (WLC_DFS_TPC | WLC_RADAR_TYPE_EU) /* Flag for DFS EU */ - -#define ISDFS_EU(fl) (((fl) & WLC_DFS_EU) == WLC_DFS_EU) - -/* locale per-channel tx power limits for MIMO frames - * maxpwr arrays are index by channel for 2.4 GHz limits, and - * by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel) - */ -typedef struct { - s8 maxpwr20[WLC_MAXPWR_MIMO_TBL_SIZE]; /* tx 20 MHz power limits, qdBm units */ - s8 maxpwr40[WLC_MAXPWR_MIMO_TBL_SIZE]; /* tx 40 MHz power limits, qdBm units */ - u8 flags; -} locale_mimo_info_t; - -extern const chanvec_t chanvec_all_2G; -extern const chanvec_t chanvec_all_5G; - -/* - * Country names and abbreviations with locale defined from ISO 3166 - */ -struct country_info { - const u8 locale_2G; /* 2.4G band locale */ - const u8 locale_5G; /* 5G band locale */ - const u8 locale_mimo_2G; /* 2.4G mimo info */ - const u8 locale_mimo_5G; /* 5G mimo info */ -}; - -typedef struct country_info country_info_t; - -typedef struct wlc_cm_info wlc_cm_info_t; - -extern wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc); -extern void wlc_channel_mgr_detach(wlc_cm_info_t *wlc_cm); - -extern int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode); -extern int wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, - const char *country_abbrev, - const char *ccode, int regrev); - -extern const char *wlc_channel_country_abbrev(wlc_cm_info_t *wlc_cm); -extern u8 wlc_channel_locale_flags(wlc_cm_info_t *wlc_cm); -extern u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, - uint bandunit); - -extern void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm); -extern bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec); - -#define VALID_CHANNEL20_DB(wlc, val) wlc_valid_channel20_db((wlc)->cmi, val) -#define VALID_CHANNEL20_IN_BAND(wlc, bandunit, val) \ - wlc_valid_channel20_in_band((wlc)->cmi, bandunit, val) -#define VALID_CHANNEL20(wlc, val) wlc_valid_channel20((wlc)->cmi, val) -#define VALID_40CHANSPEC_IN_BAND(wlc, bandunit) wlc_valid_40chanspec_in_band((wlc)->cmi, bandunit) - -extern bool wlc_valid_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec); -extern bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec); -extern bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val); -extern bool wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, - uint val); -extern bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val); -extern bool wlc_valid_40chanspec_in_band(wlc_cm_info_t *wlc_cm, uint bandunit); - -extern void wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, - chanspec_t chanspec, - struct txpwr_limits *txpwr); -extern void wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm, - chanspec_t chanspec, - u8 local_constraint_qdbm); -extern int wlc_channel_set_txpower_limit(wlc_cm_info_t *wlc_cm, - u8 local_constraint_qdbm); - -extern const country_info_t *wlc_country_lookup(struct wlc_info *wlc, - const char *ccode); -extern void wlc_locale_get_channels(const locale_info_t *locale, - chanvec_t *valid_channels); -extern const locale_info_t *wlc_get_locale_2g(u8 locale_idx); -extern const locale_info_t *wlc_get_locale_5g(u8 locale_idx); -extern bool wlc_japan(struct wlc_info *wlc); - -extern u8 wlc_get_regclass(wlc_cm_info_t *wlc_cm, chanspec_t chanspec); -extern bool wlc_channel_get_chanvec(struct wlc_info *wlc, - const char *country_abbrev, int bandtype, - chanvec_t *channels); - -#endif /* _WLC_CHANNEL_H */ diff --git a/drivers/staging/brcm80211/sys/wlc_event.c b/drivers/staging/brcm80211/sys/wlc_event.c deleted file mode 100644 index dabd7094cd73..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_event.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#ifdef MSGTRACE -#include -#endif -#include - -/* Local prototypes */ -static void wlc_timer_cb(void *arg); - -/* Private data structures */ -struct wlc_eventq { - wlc_event_t *head; - wlc_event_t *tail; - struct wlc_info *wlc; - void *wl; - struct wlc_pub *pub; - bool tpending; - bool workpending; - struct wl_timer *timer; - wlc_eventq_cb_t cb; - u8 event_inds_mask[broken_roundup(WLC_E_LAST, NBBY) / NBBY]; -}; - -/* - * Export functions - */ -wlc_eventq_t *wlc_eventq_attach(struct wlc_pub *pub, struct wlc_info *wlc, - void *wl, - wlc_eventq_cb_t cb) -{ - wlc_eventq_t *eq; - - eq = kzalloc(sizeof(wlc_eventq_t), GFP_ATOMIC); - if (eq == NULL) - return NULL; - - eq->cb = cb; - eq->wlc = wlc; - eq->wl = wl; - eq->pub = pub; - - eq->timer = wl_init_timer(eq->wl, wlc_timer_cb, eq, "eventq"); - if (!eq->timer) { - WL_ERROR("wl%d: wlc_eventq_attach: timer failed\n", - pub->unit); - kfree(eq); - return NULL; - } - - return eq; -} - -int wlc_eventq_detach(wlc_eventq_t *eq) -{ - /* Clean up pending events */ - wlc_eventq_down(eq); - - if (eq->timer) { - if (eq->tpending) { - wl_del_timer(eq->wl, eq->timer); - eq->tpending = false; - } - wl_free_timer(eq->wl, eq->timer); - eq->timer = NULL; - } - - ASSERT(wlc_eventq_avail(eq) == false); - kfree(eq); - return 0; -} - -int wlc_eventq_down(wlc_eventq_t *eq) -{ - int callbacks = 0; - if (eq->tpending && !eq->workpending) { - if (!wl_del_timer(eq->wl, eq->timer)) - callbacks++; - - ASSERT(wlc_eventq_avail(eq) == true); - ASSERT(eq->workpending == false); - eq->workpending = true; - if (eq->cb) - eq->cb(eq->wlc); - - ASSERT(eq->workpending == true); - eq->workpending = false; - eq->tpending = false; - } else { - ASSERT(eq->workpending || wlc_eventq_avail(eq) == false); - } - return callbacks; -} - -wlc_event_t *wlc_event_alloc(wlc_eventq_t *eq) -{ - wlc_event_t *e; - - e = kzalloc(sizeof(wlc_event_t), GFP_ATOMIC); - - if (e == NULL) - return NULL; - - return e; -} - -void wlc_event_free(wlc_eventq_t *eq, wlc_event_t *e) -{ - ASSERT(e->data == NULL); - ASSERT(e->next == NULL); - kfree(e); -} - -void wlc_eventq_enq(wlc_eventq_t *eq, wlc_event_t *e) -{ - ASSERT(e->next == NULL); - e->next = NULL; - - if (eq->tail) { - eq->tail->next = e; - eq->tail = e; - } else - eq->head = eq->tail = e; - - if (!eq->tpending) { - eq->tpending = true; - /* Use a zero-delay timer to trigger - * delayed processing of the event. - */ - wl_add_timer(eq->wl, eq->timer, 0, 0); - } -} - -wlc_event_t *wlc_eventq_deq(wlc_eventq_t *eq) -{ - wlc_event_t *e; - - e = eq->head; - if (e) { - eq->head = e->next; - e->next = NULL; - - if (eq->head == NULL) - eq->tail = eq->head; - } - return e; -} - -wlc_event_t *wlc_eventq_next(wlc_eventq_t *eq, wlc_event_t *e) -{ -#ifdef BCMDBG - wlc_event_t *etmp; - - for (etmp = eq->head; etmp; etmp = etmp->next) { - if (etmp == e) - break; - } - ASSERT(etmp != NULL); -#endif - - return e->next; -} - -int wlc_eventq_cnt(wlc_eventq_t *eq) -{ - wlc_event_t *etmp; - int cnt = 0; - - for (etmp = eq->head; etmp; etmp = etmp->next) - cnt++; - - return cnt; -} - -bool wlc_eventq_avail(wlc_eventq_t *eq) -{ - return (eq->head != NULL); -} - -/* - * Local Functions - */ -static void wlc_timer_cb(void *arg) -{ - struct wlc_eventq *eq = (struct wlc_eventq *)arg; - - ASSERT(eq->tpending == true); - ASSERT(wlc_eventq_avail(eq) == true); - ASSERT(eq->workpending == false); - eq->workpending = true; - - if (eq->cb) - eq->cb(eq->wlc); - - ASSERT(wlc_eventq_avail(eq) == false); - ASSERT(eq->tpending == true); - eq->workpending = false; - eq->tpending = false; -} diff --git a/drivers/staging/brcm80211/sys/wlc_event.h b/drivers/staging/brcm80211/sys/wlc_event.h deleted file mode 100644 index e75582dcdd93..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_event.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _WLC_EVENT_H_ -#define _WLC_EVENT_H_ - -typedef struct wlc_eventq wlc_eventq_t; - -typedef void (*wlc_eventq_cb_t) (void *arg); - -extern wlc_eventq_t *wlc_eventq_attach(struct wlc_pub *pub, - struct wlc_info *wlc, - void *wl, wlc_eventq_cb_t cb); -extern int wlc_eventq_detach(wlc_eventq_t *eq); -extern int wlc_eventq_down(wlc_eventq_t *eq); -extern void wlc_event_free(wlc_eventq_t *eq, wlc_event_t *e); -extern wlc_event_t *wlc_eventq_next(wlc_eventq_t *eq, wlc_event_t *e); -extern int wlc_eventq_cnt(wlc_eventq_t *eq); -extern bool wlc_eventq_avail(wlc_eventq_t *eq); -extern wlc_event_t *wlc_eventq_deq(wlc_eventq_t *eq); -extern void wlc_eventq_enq(wlc_eventq_t *eq, wlc_event_t *e); -extern wlc_event_t *wlc_event_alloc(wlc_eventq_t *eq); - -extern int wlc_eventq_register_ind(wlc_eventq_t *eq, void *bitvect); -extern int wlc_eventq_query_ind(wlc_eventq_t *eq, void *bitvect); -extern int wlc_eventq_test_ind(wlc_eventq_t *eq, int et); -extern int wlc_eventq_set_ind(wlc_eventq_t *eq, uint et, bool on); -extern void wlc_eventq_flush(wlc_eventq_t *eq); -extern void wlc_assign_event_msg(struct wlc_info *wlc, wl_event_msg_t *msg, - const wlc_event_t *e, u8 *data, - u32 len); - -#ifdef MSGTRACE -extern void wlc_event_sendup_trace(struct wlc_info *wlc, hndrte_dev_t *bus, - u8 *hdr, u16 hdrlen, u8 *buf, - u16 buflen); -#endif - -#endif /* _WLC_EVENT_H_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_key.h b/drivers/staging/brcm80211/sys/wlc_key.h deleted file mode 100644 index 3e23d5145919..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_key.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_key_h_ -#define _wlc_key_h_ - -struct scb; -struct wlc_info; -struct wlc_bsscfg; -/* Maximum # of keys that wl driver supports in S/W. - * Keys supported in H/W is less than or equal to WSEC_MAX_KEYS. - */ -#define WSEC_MAX_KEYS 54 /* Max # of keys (50 + 4 default keys) */ -#define WLC_DEFAULT_KEYS 4 /* Default # of keys */ - -#define WSEC_MAX_WOWL_KEYS 5 /* Max keys in WOWL mode (1 + 4 default keys) */ - -#define WPA2_GTK_MAX 3 - -/* -* Max # of keys currently supported: -* -* s/w keys if WSEC_SW(wlc->wsec). -* h/w keys otherwise. -*/ -#define WLC_MAX_WSEC_KEYS(wlc) WSEC_MAX_KEYS - -/* number of 802.11 default (non-paired, group keys) */ -#define WSEC_MAX_DEFAULT_KEYS 4 /* # of default keys */ - -/* Max # of hardware keys supported */ -#define WLC_MAX_WSEC_HW_KEYS(wlc) WSEC_MAX_RCMTA_KEYS - -/* Max # of hardware TKIP MIC keys supported */ -#define WLC_MAX_TKMIC_HW_KEYS(wlc) ((D11REV_GE((wlc)->pub->corerev, 13)) ? \ - WSEC_MAX_TKMIC_ENGINE_KEYS : 0) - -#define WSEC_HW_TKMIC_KEY(wlc, key, bsscfg) \ - (((D11REV_GE((wlc)->pub->corerev, 13)) && ((wlc)->machwcap & MCAP_TKIPMIC)) && \ - (key) && ((key)->algo == CRYPTO_ALGO_TKIP) && \ - !WSEC_SOFTKEY(wlc, key, bsscfg) && \ - WSEC_KEY_INDEX(wlc, key) >= WLC_DEFAULT_KEYS && \ - (WSEC_KEY_INDEX(wlc, key) < WSEC_MAX_TKMIC_ENGINE_KEYS)) - -/* index of key in key table */ -#define WSEC_KEY_INDEX(wlc, key) ((key)->idx) - -#define WSEC_SOFTKEY(wlc, key, bsscfg) (WLC_SW_KEYS(wlc, bsscfg) || \ - WSEC_KEY_INDEX(wlc, key) >= WLC_MAX_WSEC_HW_KEYS(wlc)) - -/* get a key, non-NULL only if key allocated and not clear */ -#define WSEC_KEY(wlc, i) (((wlc)->wsec_keys[i] && (wlc)->wsec_keys[i]->len) ? \ - (wlc)->wsec_keys[i] : NULL) - -#define WSEC_SCB_KEY_VALID(scb) (((scb)->key && (scb)->key->len) ? true : false) - -/* default key */ -#define WSEC_BSS_DEFAULT_KEY(bsscfg) (((bsscfg)->wsec_index == -1) ? \ - (struct wsec_key *)NULL:(bsscfg)->bss_def_keys[(bsscfg)->wsec_index]) - -/* Macros for key management in IBSS mode */ -#define WSEC_IBSS_MAX_PEERS 16 /* Max # of IBSS Peers */ -#define WSEC_IBSS_RCMTA_INDEX(idx) \ - (((idx - WSEC_MAX_DEFAULT_KEYS) % WSEC_IBSS_MAX_PEERS) + WSEC_MAX_DEFAULT_KEYS) - -/* contiguous # key slots for infrastructure mode STA */ -#define WSEC_BSS_STA_KEY_GROUP_SIZE 5 - -typedef struct wsec_iv { - u32 hi; /* upper 32 bits of IV */ - u16 lo; /* lower 16 bits of IV */ -} wsec_iv_t; - -#define WLC_NUMRXIVS 16 /* # rx IVs (one per 802.11e TID) */ - -typedef struct wsec_key { - u8 ea[ETH_ALEN]; /* per station */ - u8 idx; /* key index in wsec_keys array */ - u8 id; /* key ID [0-3] */ - u8 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ - u8 rcmta; /* rcmta entry index, same as idx by default */ - u16 flags; /* misc flags */ - u8 algo_hw; /* cache for hw register */ - u8 aes_mode; /* cache for hw register */ - s8 iv_len; /* IV length */ - s8 icv_len; /* ICV length */ - u32 len; /* key length..don't move this var */ - /* data is 4byte aligned */ - u8 data[DOT11_MAX_KEY_SIZE]; /* key data */ - wsec_iv_t rxiv[WLC_NUMRXIVS]; /* Rx IV (one per TID) */ - wsec_iv_t txiv; /* Tx IV */ - -} wsec_key_t; - -#define broken_roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) -typedef struct { - u8 vec[broken_roundup(WSEC_MAX_KEYS, NBBY) / NBBY]; /* bitvec of wsec_key indexes */ -} wsec_key_vec_t; - -/* For use with wsec_key_t.flags */ - -#define WSEC_BS_UPDATE (1 << 0) /* Indicates hw needs key update on BS switch */ -#define WSEC_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */ -#define WSEC_TKIP_ERROR (1 << 2) /* Provoke deliberate MIC error */ -#define WSEC_REPLAY_ERROR (1 << 3) /* Provoke deliberate replay */ -#define WSEC_IBSS_PEER_GROUP_KEY (1 << 7) /* Flag: group key for a IBSS PEER */ -#define WSEC_ICV_ERROR (1 << 8) /* Provoke deliberate ICV error */ - -#define wlc_key_insert(a, b, c, d, e, f, g, h, i, j) (BCME_ERROR) -#define wlc_key_update(a, b, c) do {} while (0) -#define wlc_key_remove(a, b, c) do {} while (0) -#define wlc_key_remove_all(a, b) do {} while (0) -#define wlc_key_delete(a, b, c) do {} while (0) -#define wlc_scb_key_delete(a, b) do {} while (0) -#define wlc_key_lookup(a, b, c, d, e) (NULL) -#define wlc_key_hw_init_all(a) do {} while (0) -#define wlc_key_hw_init(a, b, c) do {} while (0) -#define wlc_key_hw_wowl_init(a, b, c, d) do {} while (0) -#define wlc_key_sw_wowl_update(a, b, c, d, e) do {} while (0) -#define wlc_key_sw_wowl_create(a, b, c) (BCME_ERROR) -#define wlc_key_iv_update(a, b, c, d, e) do {(void)e; } while (0) -#define wlc_key_iv_init(a, b, c) do {} while (0) -#define wlc_key_set_error(a, b, c) (BCME_ERROR) -#define wlc_key_dump_hw(a, b) (BCME_ERROR) -#define wlc_key_dump_sw(a, b) (BCME_ERROR) -#define wlc_key_defkeyflag(a) (0) -#define wlc_rcmta_add_bssid(a, b) do {} while (0) -#define wlc_rcmta_del_bssid(a, b) do {} while (0) -#define wlc_key_scb_delete(a, b) do {} while (0) - -#endif /* _wlc_key_h_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c deleted file mode 100644 index 5eb41d64bc23..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ /dev/null @@ -1,8479 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "d11ucode_ext.h" -#include -#include -#include - - -/* - * WPA(2) definitions - */ -#define RSN_CAP_4_REPLAY_CNTRS 2 -#define RSN_CAP_16_REPLAY_CNTRS 3 - -#define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS -#define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS - -/* - * buffer length needed for wlc_format_ssid - * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. - */ -#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) - -#define TIMER_INTERVAL_WATCHDOG 1000 /* watchdog timer, in unit of ms */ -#define TIMER_INTERVAL_RADIOCHK 800 /* radio monitor timer, in unit of ms */ - -#ifndef WLC_MPC_MAX_DELAYCNT -#define WLC_MPC_MAX_DELAYCNT 10 /* Max MPC timeout, in unit of watchdog */ -#endif -#define WLC_MPC_MIN_DELAYCNT 1 /* Min MPC timeout, in unit of watchdog */ -#define WLC_MPC_THRESHOLD 3 /* MPC count threshold level */ - -#define BEACON_INTERVAL_DEFAULT 100 /* beacon interval, in unit of 1024TU */ -#define DTIM_INTERVAL_DEFAULT 3 /* DTIM interval, in unit of beacon interval */ - -/* Scale down delays to accommodate QT slow speed */ -#define BEACON_INTERVAL_DEF_QT 20 /* beacon interval, in unit of 1024TU */ -#define DTIM_INTERVAL_DEF_QT 1 /* DTIM interval, in unit of beacon interval */ - -#define TBTT_ALIGN_LEEWAY_US 100 /* min leeway before first TBTT in us */ - -/* - * driver maintains internal 'tick'(wlc->pub->now) which increments in 1s OS timer(soft - * watchdog) it is not a wall clock and won't increment when driver is in "down" state - * this low resolution driver tick can be used for maintenance tasks such as phy - * calibration and scb update - */ - -/* watchdog trigger mode: OSL timer or TBTT */ -#define WLC_WATCHDOG_TBTT(wlc) \ - (wlc->stas_associated > 0 && wlc->PM != PM_OFF && wlc->pub->align_wd_tbtt) - -/* To inform the ucode of the last mcast frame posted so that it can clear moredata bit */ -#define BCMCFID(wlc, fid) wlc_bmac_write_shm((wlc)->hw, M_BCMC_FID, (fid)) - -#define WLC_WAR16165(wlc) (wlc->pub->sih->bustype == PCI_BUS && \ - (!AP_ENAB(wlc->pub)) && (wlc->war16165)) - -/* debug/trace */ -uint wl_msg_level = -#if defined(BCMDBG) - WL_ERROR_VAL; -#else - 0; -#endif /* BCMDBG */ - -/* Find basic rate for a given rate */ -#define WLC_BASIC_RATE(wlc, rspec) (IS_MCS(rspec) ? \ - (wlc)->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK].leg_ofdm] : \ - (wlc)->band->basic_rate[rspec & RSPEC_RATE_MASK]) - -#define FRAMETYPE(r, mimoframe) (IS_MCS(r) ? mimoframe : (IS_CCK(r) ? FT_CCK : FT_OFDM)) - -#define RFDISABLE_DEFAULT 10000000 /* rfdisable delay timer 500 ms, runs of ALP clock */ - -#define WLC_TEMPSENSE_PERIOD 10 /* 10 second timeout */ - -#define SCAN_IN_PROGRESS(x) 0 - -#define EPI_VERSION_NUM 0x054b0b00 - -#ifdef BCMDBG -/* pointer to most recently allocated wl/wlc */ -static struct wlc_info *wlc_info_dbg = (struct wlc_info *) (NULL); -#endif - -/* IOVar table */ - -/* Parameter IDs, for use only internally to wlc -- in the wlc_iovars - * table and by the wlc_doiovar() function. No ordering is imposed: - * the table is keyed by name, and the function uses a switch. - */ -enum { - IOV_MPC = 1, - IOV_QTXPOWER, - IOV_BCN_LI_BCN, /* Beacon listen interval in # of beacons */ - IOV_LAST /* In case of a need to check max ID number */ -}; - -const bcm_iovar_t wlc_iovars[] = { - {"mpc", IOV_MPC, (IOVF_OPEN_ALLOW), IOVT_BOOL, 0}, - {"qtxpower", IOV_QTXPOWER, (IOVF_WHL | IOVF_OPEN_ALLOW), IOVT_UINT32, - 0}, - {"bcn_li_bcn", IOV_BCN_LI_BCN, 0, IOVT_UINT8, 0}, - {NULL, 0, 0, 0, 0} -}; - -const u8 prio2fifo[NUMPRIO] = { - TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */ - TX_AC_BK_FIFO, /* 1 BK AC_BK Background */ - TX_AC_BK_FIFO, /* 2 -- AC_BK Background */ - TX_AC_BE_FIFO, /* 3 EE AC_BE Best Effort */ - TX_AC_VI_FIFO, /* 4 CL AC_VI Video */ - TX_AC_VI_FIFO, /* 5 VI AC_VI Video */ - TX_AC_VO_FIFO, /* 6 VO AC_VO Voice */ - TX_AC_VO_FIFO /* 7 NC AC_VO Voice */ -}; - -/* precedences numbers for wlc queues. These are twice as may levels as - * 802.1D priorities. - * Odd numbers are used for HI priority traffic at same precedence levels - * These constants are used ONLY by wlc_prio2prec_map. Do not use them elsewhere. - */ -#define _WLC_PREC_NONE 0 /* None = - */ -#define _WLC_PREC_BK 2 /* BK - Background */ -#define _WLC_PREC_BE 4 /* BE - Best-effort */ -#define _WLC_PREC_EE 6 /* EE - Excellent-effort */ -#define _WLC_PREC_CL 8 /* CL - Controlled Load */ -#define _WLC_PREC_VI 10 /* Vi - Video */ -#define _WLC_PREC_VO 12 /* Vo - Voice */ -#define _WLC_PREC_NC 14 /* NC - Network Control */ - -/* 802.1D Priority to precedence queue mapping */ -const u8 wlc_prio2prec_map[] = { - _WLC_PREC_BE, /* 0 BE - Best-effort */ - _WLC_PREC_BK, /* 1 BK - Background */ - _WLC_PREC_NONE, /* 2 None = - */ - _WLC_PREC_EE, /* 3 EE - Excellent-effort */ - _WLC_PREC_CL, /* 4 CL - Controlled Load */ - _WLC_PREC_VI, /* 5 Vi - Video */ - _WLC_PREC_VO, /* 6 Vo - Voice */ - _WLC_PREC_NC, /* 7 NC - Network Control */ -}; - -/* Sanity check for tx_prec_map and fifo synchup - * Either there are some packets pending for the fifo, else if fifo is empty then - * all the corresponding precmap bits should be set - */ -#define WLC_TX_FIFO_CHECK(wlc, fifo) (TXPKTPENDGET((wlc), (fifo)) || \ - (TXPKTPENDGET((wlc), (fifo)) == 0 && \ - ((wlc)->tx_prec_map & (wlc)->fifo2prec_map[(fifo)]) == \ - (wlc)->fifo2prec_map[(fifo)])) - -/* TX FIFO number to WME/802.1E Access Category */ -const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE }; - -/* WME/802.1E Access Category to TX FIFO number */ -static const u8 wme_ac2fifo[] = { 1, 0, 2, 3 }; - -static bool in_send_q = false; - -/* Shared memory location index for various AC params */ -#define wme_shmemacindex(ac) wme_ac2fifo[ac] - -#ifdef BCMDBG -static const char *fifo_names[] = { - "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; -const char *aci_names[] = { "AC_BE", "AC_BK", "AC_VI", "AC_VO" }; -#endif - -static const u8 acbitmap2maxprio[] = { - PRIO_8021D_BE, PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_BK, - PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, - PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, - PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO -}; - -/* currently the best mechanism for determining SIFS is the band in use */ -#define SIFS(band) ((band)->bandtype == WLC_BAND_5G ? APHY_SIFS_TIME : BPHY_SIFS_TIME); - -/* value for # replay counters currently supported */ -#define WLC_REPLAY_CNTRS_VALUE WPA_CAP_16_REPLAY_CNTRS - -/* local prototypes */ -static u16 BCMFASTPATH wlc_d11hdrs_mac80211(struct wlc_info *wlc, - struct ieee80211_hw *hw, - struct sk_buff *p, - struct scb *scb, uint frag, - uint nfrags, uint queue, - uint next_frag_len, - wsec_key_t *key, - ratespec_t rspec_override); - -static void wlc_bss_default_init(struct wlc_info *wlc); -static void wlc_ucode_mac_upd(struct wlc_info *wlc); -static ratespec_t mac80211_wlc_set_nrate(struct wlc_info *wlc, - struct wlcband *cur_band, u32 int_val); -static void wlc_tx_prec_map_init(struct wlc_info *wlc); -static void wlc_watchdog(void *arg); -static void wlc_watchdog_by_timer(void *arg); -static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg); -static int wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, - const bcm_iovar_t *vi); -static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc); - -/* send and receive */ -static wlc_txq_info_t *wlc_txq_alloc(struct wlc_info *wlc, - struct osl_info *osh); -static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh, - wlc_txq_info_t *qi); -static void wlc_txflowcontrol_signal(struct wlc_info *wlc, wlc_txq_info_t *qi, - bool on, int prio); -static void wlc_txflowcontrol_reset(struct wlc_info *wlc); -static u16 wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, - uint length); -static void wlc_compute_cck_plcp(ratespec_t rate, uint length, u8 *plcp); -static void wlc_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp); -static void wlc_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp); -static u16 wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, - u8 preamble_type, uint next_frag_len); -static void wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, - d11rxhdr_t *rxh, struct sk_buff *p); -static uint wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t rate, - u8 preamble_type, uint dur); -static uint wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rate, - u8 preamble_type); -static uint wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rate, - u8 preamble_type); -/* interrupt, up/down, band */ -static void wlc_setband(struct wlc_info *wlc, uint bandunit); -static chanspec_t wlc_init_chanspec(struct wlc_info *wlc); -static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec); -static void wlc_bsinit(struct wlc_info *wlc); -static int wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, - bool writeToShm); -static void wlc_radio_hwdisable_upd(struct wlc_info *wlc); -static bool wlc_radio_monitor_start(struct wlc_info *wlc); -static void wlc_radio_timer(void *arg); -static void wlc_radio_enable(struct wlc_info *wlc); -static void wlc_radio_upd(struct wlc_info *wlc); - -/* scan, association, BSS */ -static uint wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rate, - u8 preamble_type); -static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap); -static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val); -static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val); -static void wlc_war16165(struct wlc_info *wlc, bool tx); - -static void wlc_process_eventq(void *arg); -static void wlc_wme_retries_write(struct wlc_info *wlc); -static bool wlc_attach_stf_ant_init(struct wlc_info *wlc); -static uint wlc_attach_module(struct wlc_info *wlc); -static void wlc_detach_module(struct wlc_info *wlc); -static void wlc_timers_deinit(struct wlc_info *wlc); -static void wlc_down_led_upd(struct wlc_info *wlc); -static uint wlc_down_del_timer(struct wlc_info *wlc); -static void wlc_ofdm_rateset_war(struct wlc_info *wlc); -static int _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, - struct wlc_if *wlcif); - -#if defined(BCMDBG) -void wlc_get_rcmta(struct wlc_info *wlc, int idx, u8 *addr) -{ - d11regs_t *regs = wlc->regs; - u32 v32; - struct osl_info *osh; - - WL_TRACE("wl%d: %s\n", WLCWLUNIT(wlc), __func__); - - ASSERT(wlc->pub->corerev > 4); - - osh = wlc->osh; - - W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); - (void)R_REG(osh, ®s->objaddr); - v32 = R_REG(osh, ®s->objdata); - addr[0] = (u8) v32; - addr[1] = (u8) (v32 >> 8); - addr[2] = (u8) (v32 >> 16); - addr[3] = (u8) (v32 >> 24); - W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1))); - (void)R_REG(osh, ®s->objaddr); - v32 = R_REG(osh, (volatile u16 *)®s->objdata); - addr[4] = (u8) v32; - addr[5] = (u8) (v32 >> 8); -} -#endif /* defined(BCMDBG) */ - -/* keep the chip awake if needed */ -bool wlc_stay_awake(struct wlc_info *wlc) -{ - return true; -} - -/* conditions under which the PM bit should be set in outgoing frames and STAY_AWAKE is meaningful - */ -bool wlc_ps_allowed(struct wlc_info *wlc) -{ - int idx; - wlc_bsscfg_t *cfg; - - /* disallow PS when one of the following global conditions meets */ - if (!wlc->pub->associated || !wlc->PMenabled || wlc->PM_override) - return false; - - /* disallow PS when one of these meets when not scanning */ - if (!wlc->PMblocked) { - if (AP_ACTIVE(wlc) || wlc->monitor) - return false; - } - - FOREACH_AS_STA(wlc, idx, cfg) { - /* disallow PS when one of the following bsscfg specific conditions meets */ - if (!cfg->BSS || !WLC_PORTOPEN(cfg)) - return false; - - if (!cfg->dtim_programmed) - return false; - } - - return true; -} - -void wlc_reset(struct wlc_info *wlc) -{ - WL_TRACE("wl%d: wlc_reset\n", wlc->pub->unit); - - wlc->check_for_unaligned_tbtt = false; - - /* slurp up hw mac counters before core reset */ - if (WLC_UPDATE_STATS(wlc)) { - wlc_statsupd(wlc); - - /* reset our snapshot of macstat counters */ - memset((char *)wlc->core->macstat_snapshot, 0, - sizeof(macstat_t)); - } - - wlc_bmac_reset(wlc->hw); - wlc_ampdu_reset(wlc->ampdu); - wlc->txretried = 0; - -} - -void wlc_fatal_error(struct wlc_info *wlc) -{ - WL_ERROR("wl%d: fatal error, reinitializing\n", wlc->pub->unit); - wl_init(wlc->wl); -} - -/* Return the channel the driver should initialize during wlc_init. - * the channel may have to be changed from the currently configured channel - * if other configurations are in conflict (bandlocked, 11n mode disabled, - * invalid channel for current country, etc.) - */ -static chanspec_t wlc_init_chanspec(struct wlc_info *wlc) -{ - chanspec_t chanspec = - 1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE | - WL_CHANSPEC_BAND_2G; - - /* make sure the channel is on the supported band if we are band-restricted */ - if (wlc->bandlocked || NBANDS(wlc) == 1) { - ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit); - } - ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec)); - return chanspec; -} - -struct scb global_scb; - -static void wlc_init_scb(struct wlc_info *wlc, struct scb *scb) -{ - int i; - scb->flags = SCB_WMECAP | SCB_HTCAP; - for (i = 0; i < NUMPRIO; i++) - scb->seqnum[i] = 0; -} - -void wlc_init(struct wlc_info *wlc) -{ - d11regs_t *regs; - chanspec_t chanspec; - int i; - wlc_bsscfg_t *bsscfg; - bool mute = false; - - WL_TRACE("wl%d: wlc_init\n", wlc->pub->unit); - - regs = wlc->regs; - - /* This will happen if a big-hammer was executed. In that case, we want to go back - * to the channel that we were on and not new channel - */ - if (wlc->pub->associated) - chanspec = wlc->home_chanspec; - else - chanspec = wlc_init_chanspec(wlc); - - wlc_bmac_init(wlc->hw, chanspec, mute); - - wlc->seckeys = wlc_bmac_read_shm(wlc->hw, M_SECRXKEYS_PTR) * 2; - if (D11REV_GE(wlc->pub->corerev, 15) && (wlc->machwcap & MCAP_TKIPMIC)) - wlc->tkmickeys = - wlc_bmac_read_shm(wlc->hw, M_TKMICKEYS_PTR) * 2; - - /* update beacon listen interval */ - wlc_bcn_li_upd(wlc); - wlc->bcn_wait_prd = - (u8) (wlc_bmac_read_shm(wlc->hw, M_NOSLPZNATDTIM) >> 10); - ASSERT(wlc->bcn_wait_prd > 0); - - /* the world is new again, so is our reported rate */ - wlc_reprate_init(wlc); - - /* write ethernet address to core */ - FOREACH_BSS(wlc, i, bsscfg) { - wlc_set_mac(bsscfg); - wlc_set_bssid(bsscfg); - } - - /* Update tsf_cfprep if associated and up */ - if (wlc->pub->associated) { - FOREACH_BSS(wlc, i, bsscfg) { - if (bsscfg->up) { - u32 bi; - - /* get beacon period from bsscfg and convert to uS */ - bi = bsscfg->current_bss->beacon_period << 10; - /* update the tsf_cfprep register */ - /* since init path would reset to default value */ - W_REG(wlc->osh, ®s->tsf_cfprep, - (bi << CFPREP_CBI_SHIFT)); - - /* Update maccontrol PM related bits */ - wlc_set_ps_ctrl(wlc); - - break; - } - } - } - - wlc_key_hw_init_all(wlc); - - wlc_bandinit_ordered(wlc, chanspec); - - wlc_init_scb(wlc, &global_scb); - - /* init probe response timeout */ - wlc_write_shm(wlc, M_PRS_MAXTIME, wlc->prb_resp_timeout); - - /* init max burst txop (framebursting) */ - wlc_write_shm(wlc, M_MBURST_TXOP, - (wlc-> - _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP)); - - /* initialize maximum allowed duty cycle */ - wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true); - wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true); - - /* Update some shared memory locations related to max AMPDU size allowed to received */ - wlc_ampdu_shm_upd(wlc->ampdu); - - /* band-specific inits */ - wlc_bsinit(wlc); - - /* Enable EDCF mode (while the MAC is suspended) */ - if (EDCF_ENAB(wlc->pub)) { - OR_REG(wlc->osh, ®s->ifs_ctl, IFS_USEEDCF); - wlc_edcf_setparams(wlc->cfg, false); - } - - /* Init precedence maps for empty FIFOs */ - wlc_tx_prec_map_init(wlc); - - /* read the ucode version if we have not yet done so */ - if (wlc->ucode_rev == 0) { - wlc->ucode_rev = - wlc_read_shm(wlc, M_BOM_REV_MAJOR) << NBITS(u16); - wlc->ucode_rev |= wlc_read_shm(wlc, M_BOM_REV_MINOR); - } - - /* ..now really unleash hell (allow the MAC out of suspend) */ - wlc_enable_mac(wlc); - - /* clear tx flow control */ - wlc_txflowcontrol_reset(wlc); - - /* clear tx data fifo suspends */ - wlc->tx_suspended = false; - - /* enable the RF Disable Delay timer */ - if (D11REV_GE(wlc->pub->corerev, 10)) - W_REG(wlc->osh, &wlc->regs->rfdisabledly, RFDISABLE_DEFAULT); - - /* initialize mpc delay */ - wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; - - /* - * Initialize WME parameters; if they haven't been set by some other - * mechanism (IOVar, etc) then read them from the hardware. - */ - if (WLC_WME_RETRY_SHORT_GET(wlc, 0) == 0) { /* Unintialized; read from HW */ - int ac; - - ASSERT(wlc->clk); - for (ac = 0; ac < AC_COUNT; ac++) { - wlc->wme_retries[ac] = - wlc_read_shm(wlc, M_AC_TXLMT_ADDR(ac)); - } - } -} - -void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc) -{ - wlc->bcnmisc_monitor = promisc; - wlc_mac_bcn_promisc(wlc); -} - -void wlc_mac_bcn_promisc(struct wlc_info *wlc) -{ - if ((AP_ENAB(wlc->pub) && (N_ENAB(wlc->pub) || wlc->band->gmode)) || - wlc->bcnmisc_ibss || wlc->bcnmisc_scan || wlc->bcnmisc_monitor) - wlc_mctrl(wlc, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC); - else - wlc_mctrl(wlc, MCTL_BCNS_PROMISC, 0); -} - -/* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */ -void wlc_mac_promisc(struct wlc_info *wlc) -{ - u32 promisc_bits = 0; - - /* promiscuous mode just sets MCTL_PROMISC - * Note: APs get all BSS traffic without the need to set the MCTL_PROMISC bit - * since all BSS data traffic is directed at the AP - */ - if (PROMISC_ENAB(wlc->pub) && !AP_ENAB(wlc->pub) && !wlc->wet) - promisc_bits |= MCTL_PROMISC; - - /* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL - * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is - * handled in wlc_mac_bcn_promisc() - */ - if (MONITOR_ENAB(wlc)) - promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL; - - wlc_mctrl(wlc, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits); -} - -/* check if hps and wake states of sw and hw are in sync */ -bool wlc_ps_check(struct wlc_info *wlc) -{ - bool res = true; - bool hps, wake; - bool wake_ok; - - if (!AP_ACTIVE(wlc)) { - volatile u32 tmp; - tmp = R_REG(wlc->osh, &wlc->regs->maccontrol); - - /* If deviceremoved is detected, then don't take any action as this can be called - * in any context. Assume that caller will take care of the condition. This is just - * to avoid assert - */ - if (tmp == 0xffffffff) { - WL_ERROR("wl%d: %s: dead chip\n", - wlc->pub->unit, __func__); - return DEVICEREMOVED(wlc); - } - - hps = PS_ALLOWED(wlc); - - if (hps != ((tmp & MCTL_HPS) != 0)) { - int idx; - wlc_bsscfg_t *cfg; - WL_ERROR("wl%d: hps not sync, sw %d, maccontrol 0x%x\n", - wlc->pub->unit, hps, tmp); - FOREACH_BSS(wlc, idx, cfg) { - if (!BSSCFG_STA(cfg)) - continue; - } - - res = false; - } - /* For a monolithic build the wake check can be exact since it looks at wake - * override bits. The MCTL_WAKE bit should match the 'wake' value. - */ - wake = STAY_AWAKE(wlc) || wlc->hw->wake_override; - wake_ok = (wake == ((tmp & MCTL_WAKE) != 0)); - if (hps && !wake_ok) { - WL_ERROR("wl%d: wake not sync, sw %d maccontrol 0x%x\n", - wlc->pub->unit, wake, tmp); - res = false; - } - } - ASSERT(res); - return res; -} - -/* push sw hps and wake state through hardware */ -void wlc_set_ps_ctrl(struct wlc_info *wlc) -{ - u32 v1, v2; - bool hps, wake; - bool awake_before; - - hps = PS_ALLOWED(wlc); - wake = hps ? (STAY_AWAKE(wlc)) : true; - - WL_TRACE("wl%d: wlc_set_ps_ctrl: hps %d wake %d\n", - wlc->pub->unit, hps, wake); - - v1 = R_REG(wlc->osh, &wlc->regs->maccontrol); - v2 = 0; - if (hps) - v2 |= MCTL_HPS; - if (wake) - v2 |= MCTL_WAKE; - - wlc_mctrl(wlc, MCTL_WAKE | MCTL_HPS, v2); - - awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0)); - - if (wake && !awake_before) - wlc_bmac_wait_for_wake(wlc->hw); - -} - -/* - * Write this BSS config's MAC address to core. - * Updates RXE match engine. - */ -int wlc_set_mac(wlc_bsscfg_t *cfg) -{ - int err = 0; - struct wlc_info *wlc = cfg->wlc; - - if (cfg == wlc->cfg) { - /* enter the MAC addr into the RXE match registers */ - wlc_set_addrmatch(wlc, RCM_MAC_OFFSET, cfg->cur_etheraddr); - } - - wlc_ampdu_macaddr_upd(wlc); - - return err; -} - -/* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl). - * Updates RXE match engine. - */ -void wlc_set_bssid(wlc_bsscfg_t *cfg) -{ - struct wlc_info *wlc = cfg->wlc; - - /* if primary config, we need to update BSSID in RXE match registers */ - if (cfg == wlc->cfg) { - wlc_set_addrmatch(wlc, RCM_BSSID_OFFSET, cfg->BSSID); - } -#ifdef SUPPORT_HWKEYS - else if (BSSCFG_STA(cfg) && cfg->BSS) { - wlc_rcmta_add_bssid(wlc, cfg); - } -#endif -} - -/* - * Suspend the the MAC and update the slot timing - * for standard 11b/g (20us slots) or shortslot 11g (9us slots). - */ -void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot) -{ - int idx; - wlc_bsscfg_t *cfg; - - ASSERT(wlc->band->gmode); - - /* use the override if it is set */ - if (wlc->shortslot_override != WLC_SHORTSLOT_AUTO) - shortslot = (wlc->shortslot_override == WLC_SHORTSLOT_ON); - - if (wlc->shortslot == shortslot) - return; - - wlc->shortslot = shortslot; - - /* update the capability based on current shortslot mode */ - FOREACH_BSS(wlc, idx, cfg) { - if (!cfg->associated) - continue; - cfg->current_bss->capability &= - ~WLAN_CAPABILITY_SHORT_SLOT_TIME; - if (wlc->shortslot) - cfg->current_bss->capability |= - WLAN_CAPABILITY_SHORT_SLOT_TIME; - } - - wlc_bmac_set_shortslot(wlc->hw, shortslot); -} - -static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc) -{ - u8 local; - s16 local_max; - - local = WLC_TXPWR_MAX; - if (wlc->pub->associated && - (wf_chspec_ctlchan(wlc->chanspec) == - wf_chspec_ctlchan(wlc->home_chanspec))) { - - /* get the local power constraint if we are on the AP's - * channel [802.11h, 7.3.2.13] - */ - /* Clamp the value between 0 and WLC_TXPWR_MAX w/o overflowing the target */ - local_max = - (wlc->txpwr_local_max - - wlc->txpwr_local_constraint) * WLC_TXPWR_DB_FACTOR; - if (local_max > 0 && local_max < WLC_TXPWR_MAX) - return (u8) local_max; - if (local_max < 0) - return 0; - } - - return local; -} - -/* propagate home chanspec to all bsscfgs in case bsscfg->current_bss->chanspec is referenced */ -void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec) -{ - if (wlc->home_chanspec != chanspec) { - int idx; - wlc_bsscfg_t *cfg; - - wlc->home_chanspec = chanspec; - - FOREACH_BSS(wlc, idx, cfg) { - if (!cfg->associated) - continue; - cfg->target_bss->chanspec = chanspec; - cfg->current_bss->chanspec = chanspec; - } - - } -} - -static void wlc_set_phy_chanspec(struct wlc_info *wlc, chanspec_t chanspec) -{ - /* Save our copy of the chanspec */ - wlc->chanspec = chanspec; - - /* Set the chanspec and power limits for this locale after computing - * any 11h local tx power constraints. - */ - wlc_channel_set_chanspec(wlc->cmi, chanspec, - wlc_local_constraint_qdbm(wlc)); - - if (wlc->stf->ss_algosel_auto) - wlc_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel, - chanspec); - - wlc_stf_ss_update(wlc, wlc->band); - -} - -void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec) -{ - uint bandunit; - bool switchband = false; - chanspec_t old_chanspec = wlc->chanspec; - - if (!wlc_valid_chanspec_db(wlc->cmi, chanspec)) { - WL_ERROR("wl%d: %s: Bad channel %d\n", - wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); - ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec)); - return; - } - - /* Switch bands if necessary */ - if (NBANDS(wlc) > 1) { - bandunit = CHSPEC_WLCBANDUNIT(chanspec); - if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) { - switchband = true; - if (wlc->bandlocked) { - WL_ERROR("wl%d: %s: chspec %d band is locked!\n", - wlc->pub->unit, __func__, - CHSPEC_CHANNEL(chanspec)); - return; - } - /* BMAC_NOTE: should the setband call come after the wlc_bmac_chanspec() ? - * if the setband updates (wlc_bsinit) use low level calls to inspect and - * set state, the state inspected may be from the wrong band, or the - * following wlc_bmac_set_chanspec() may undo the work. - */ - wlc_setband(wlc, bandunit); - } - } - - ASSERT(N_ENAB(wlc->pub) || !CHSPEC_IS40(chanspec)); - - /* sync up phy/radio chanspec */ - wlc_set_phy_chanspec(wlc, chanspec); - - /* init antenna selection */ - if (CHSPEC_WLC_BW(old_chanspec) != CHSPEC_WLC_BW(chanspec)) { - if (WLANTSEL_ENAB(wlc)) - wlc_antsel_init(wlc->asi); - - /* Fix the hardware rateset based on bw. - * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz - */ - wlc_rateset_bw_mcs_filter(&wlc->band->hw_rateset, - wlc->band-> - mimo_cap_40 ? CHSPEC_WLC_BW(chanspec) - : 0); - } - - /* update some mac configuration since chanspec changed */ - wlc_ucode_mac_upd(wlc); -} - -#if defined(BCMDBG) -static int wlc_get_current_txpwr(struct wlc_info *wlc, void *pwr, uint len) -{ - txpwr_limits_t txpwr; - tx_power_t power; - tx_power_legacy_t *old_power = NULL; - int r, c; - uint qdbm; - bool override; - - if (len == sizeof(tx_power_legacy_t)) - old_power = (tx_power_legacy_t *) pwr; - else if (len < sizeof(tx_power_t)) - return BCME_BUFTOOSHORT; - - memset(&power, 0, sizeof(tx_power_t)); - - power.chanspec = WLC_BAND_PI_RADIO_CHANSPEC; - if (wlc->pub->associated) - power.local_chanspec = wlc->home_chanspec; - - /* Return the user target tx power limits for the various rates. Note wlc_phy.c's - * public interface only implements getting and setting a single value for all of - * rates, so we need to fill the array ourselves. - */ - wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override); - for (r = 0; r < WL_TX_POWER_RATES; r++) { - power.user_limit[r] = (u8) qdbm; - } - - power.local_max = wlc->txpwr_local_max * WLC_TXPWR_DB_FACTOR; - power.local_constraint = - wlc->txpwr_local_constraint * WLC_TXPWR_DB_FACTOR; - - power.antgain[0] = wlc->bandstate[BAND_2G_INDEX]->antgain; - power.antgain[1] = wlc->bandstate[BAND_5G_INDEX]->antgain; - - wlc_channel_reg_limits(wlc->cmi, power.chanspec, &txpwr); - -#if WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK -#error "WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK" -#endif - - /* CCK tx power limits */ - for (c = 0, r = WL_TX_POWER_CCK_FIRST; c < WL_TX_POWER_CCK_NUM; - c++, r++) - power.reg_limit[r] = txpwr.cck[c]; - -#if WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM -#error "WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM" -#endif - - /* 20 MHz OFDM SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM_FIRST; c < WL_TX_POWER_OFDM_NUM; - c++, r++) - power.reg_limit[r] = txpwr.ofdm[c]; - - if (WLC_PHY_11N_CAP(wlc->band)) { - - /* 20 MHz OFDM CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM20_CDD_FIRST; - c < WL_TX_POWER_OFDM_NUM; c++, r++) - power.reg_limit[r] = txpwr.ofdm_cdd[c]; - - /* 40 MHz OFDM SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM40_SISO_FIRST; - c < WL_TX_POWER_OFDM_NUM; c++, r++) - power.reg_limit[r] = txpwr.ofdm_40_siso[c]; - - /* 40 MHz OFDM CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM40_CDD_FIRST; - c < WL_TX_POWER_OFDM_NUM; c++, r++) - power.reg_limit[r] = txpwr.ofdm_40_cdd[c]; - -#if WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM -#error "WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM" -#endif - - /* 20MHz MCS0-7 SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_SISO_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_siso[c]; - - /* 20MHz MCS0-7 CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_CDD_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_cdd[c]; - - /* 20MHz MCS0-7 STBC tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_STBC_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_stbc[c]; - - /* 40MHz MCS0-7 SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_SISO_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_siso[c]; - - /* 40MHz MCS0-7 CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_CDD_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_cdd[c]; - - /* 40MHz MCS0-7 STBC tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_STBC_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_stbc[c]; - -#if WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM -#error "WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM" -#endif - - /* 20MHz MCS8-15 SDM tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_SDM_FIRST; - c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_mimo[c]; - - /* 40MHz MCS8-15 SDM tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_SDM_FIRST; - c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_mimo[c]; - - /* MCS 32 */ - power.reg_limit[WL_TX_POWER_MCS_32] = txpwr.mcs32; - } - - wlc_phy_txpower_get_current(wlc->band->pi, &power, - CHSPEC_CHANNEL(power.chanspec)); - - /* copy the tx_power_t struct to the return buffer, - * or convert to a tx_power_legacy_t struct - */ - if (!old_power) { - bcopy(&power, pwr, sizeof(tx_power_t)); - } else { - int band_idx = CHSPEC_IS2G(power.chanspec) ? 0 : 1; - - memset(old_power, 0, sizeof(tx_power_legacy_t)); - - old_power->txpwr_local_max = power.local_max; - old_power->txpwr_local_constraint = power.local_constraint; - if (CHSPEC_IS2G(power.chanspec)) { - old_power->txpwr_chan_reg_max = txpwr.cck[0]; - old_power->txpwr_est_Pout[band_idx] = - power.est_Pout_cck; - old_power->txpwr_est_Pout_gofdm = power.est_Pout[0]; - } else { - old_power->txpwr_chan_reg_max = txpwr.ofdm[0]; - old_power->txpwr_est_Pout[band_idx] = power.est_Pout[0]; - } - old_power->txpwr_antgain[0] = power.antgain[0]; - old_power->txpwr_antgain[1] = power.antgain[1]; - - for (r = 0; r < NUM_PWRCTRL_RATES; r++) { - old_power->txpwr_band_max[r] = power.user_limit[r]; - old_power->txpwr_limit[r] = power.reg_limit[r]; - old_power->txpwr_target[band_idx][r] = power.target[r]; - if (CHSPEC_IS2G(power.chanspec)) - old_power->txpwr_bphy_cck_max[r] = - power.board_limit[r]; - else - old_power->txpwr_aphy_max[r] = - power.board_limit[r]; - } - } - - return 0; -} -#endif /* defined(BCMDBG) */ - -static u32 wlc_watchdog_backup_bi(struct wlc_info *wlc) -{ - u32 bi; - bi = 2 * wlc->cfg->current_bss->dtim_period * - wlc->cfg->current_bss->beacon_period; - if (wlc->bcn_li_dtim) - bi *= wlc->bcn_li_dtim; - else if (wlc->bcn_li_bcn) - /* recalculate bi based on bcn_li_bcn */ - bi = 2 * wlc->bcn_li_bcn * wlc->cfg->current_bss->beacon_period; - - if (bi < 2 * TIMER_INTERVAL_WATCHDOG) - bi = 2 * TIMER_INTERVAL_WATCHDOG; - return bi; -} - -/* Change to run the watchdog either from a periodic timer or from tbtt handler. - * Call watchdog from tbtt handler if tbtt is true, watchdog timer otherwise. - */ -void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt) -{ - /* make sure changing watchdog driver is allowed */ - if (!wlc->pub->up || !wlc->pub->align_wd_tbtt) - return; - if (!tbtt && wlc->WDarmed) { - wl_del_timer(wlc->wl, wlc->wdtimer); - wlc->WDarmed = false; - } - - /* stop watchdog timer and use tbtt interrupt to drive watchdog */ - if (tbtt && wlc->WDarmed) { - wl_del_timer(wlc->wl, wlc->wdtimer); - wlc->WDarmed = false; - wlc->WDlast = OSL_SYSUPTIME(); - } - /* arm watchdog timer and drive the watchdog there */ - else if (!tbtt && !wlc->WDarmed) { - wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, - true); - wlc->WDarmed = true; - } - if (tbtt && !wlc->WDarmed) { - wl_add_timer(wlc->wl, wlc->wdtimer, wlc_watchdog_backup_bi(wlc), - true); - wlc->WDarmed = true; - } -} - -ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, wlc_rateset_t *rs) -{ - ratespec_t lowest_basic_rspec; - uint i; - - /* Use the lowest basic rate */ - lowest_basic_rspec = rs->rates[0] & RATE_MASK; - for (i = 0; i < rs->count; i++) { - if (rs->rates[i] & WLC_RATE_FLAG) { - lowest_basic_rspec = rs->rates[i] & RATE_MASK; - break; - } - } -#if NCONF - /* pick siso/cdd as default for OFDM (note no basic rate MCSs are supported yet) */ - if (IS_OFDM(lowest_basic_rspec)) { - lowest_basic_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT); - } -#endif - - return lowest_basic_rspec; -} - -/* This function changes the phytxctl for beacon based on current beacon ratespec AND txant - * setting as per this table: - * ratespec CCK ant = wlc->stf->txant - * OFDM ant = 3 - */ -void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, ratespec_t bcn_rspec) -{ - u16 phyctl; - u16 phytxant = wlc->stf->phytxant; - u16 mask = PHY_TXC_ANT_MASK; - - /* for non-siso rates or default setting, use the available chains */ - if (WLC_PHY_11N_CAP(wlc->band)) { - phytxant = wlc_stf_phytxchain_sel(wlc, bcn_rspec); - } - - phyctl = wlc_read_shm(wlc, M_BCN_PCTLWD); - phyctl = (phyctl & ~mask) | phytxant; - wlc_write_shm(wlc, M_BCN_PCTLWD, phyctl); -} - -/* centralized protection config change function to simplify debugging, no consistency checking - * this should be called only on changes to avoid overhead in periodic function -*/ -void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val) -{ - WL_TRACE("wlc_protection_upd: idx %d, val %d\n", idx, val); - - switch (idx) { - case WLC_PROT_G_SPEC: - wlc->protection->_g = (bool) val; - break; - case WLC_PROT_G_OVR: - wlc->protection->g_override = (s8) val; - break; - case WLC_PROT_G_USER: - wlc->protection->gmode_user = (u8) val; - break; - case WLC_PROT_OVERLAP: - wlc->protection->overlap = (s8) val; - break; - case WLC_PROT_N_USER: - wlc->protection->nmode_user = (s8) val; - break; - case WLC_PROT_N_CFG: - wlc->protection->n_cfg = (s8) val; - break; - case WLC_PROT_N_CFG_OVR: - wlc->protection->n_cfg_override = (s8) val; - break; - case WLC_PROT_N_NONGF: - wlc->protection->nongf = (bool) val; - break; - case WLC_PROT_N_NONGF_OVR: - wlc->protection->nongf_override = (s8) val; - break; - case WLC_PROT_N_PAM_OVR: - wlc->protection->n_pam_override = (s8) val; - break; - case WLC_PROT_N_OBSS: - wlc->protection->n_obss = (bool) val; - break; - - default: - ASSERT(0); - break; - } - -} - -static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val) -{ - wlc->ht_cap.cap_info &= ~(IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_SGI_40); - wlc->ht_cap.cap_info |= (val & WLC_N_SGI_20) ? - IEEE80211_HT_CAP_SGI_20 : 0; - wlc->ht_cap.cap_info |= (val & WLC_N_SGI_40) ? - IEEE80211_HT_CAP_SGI_40 : 0; - - if (wlc->pub->up) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - } -} - -static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val) -{ - wlc->stf->ldpc = val; - - wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_LDPC_CODING; - if (wlc->stf->ldpc != OFF) - wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_LDPC_CODING; - - if (wlc->pub->up) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - wlc_phy_ldpc_override_set(wlc->band->pi, (val ? true : false)); - } -} - -/* - * ucode, hwmac update - * Channel dependent updates for ucode and hw - */ -static void wlc_ucode_mac_upd(struct wlc_info *wlc) -{ - /* enable or disable any active IBSSs depending on whether or not - * we are on the home channel - */ - if (wlc->home_chanspec == WLC_BAND_PI_RADIO_CHANSPEC) { - if (wlc->pub->associated) { - /* BMAC_NOTE: This is something that should be fixed in ucode inits. - * I think that the ucode inits set up the bcn templates and shm values - * with a bogus beacon. This should not be done in the inits. If ucode needs - * to set up a beacon for testing, the test routines should write it down, - * not expect the inits to populate a bogus beacon. - */ - if (WLC_PHY_11N_CAP(wlc->band)) { - wlc_write_shm(wlc, M_BCN_TXTSF_OFFSET, - wlc->band->bcntsfoff); - } - } - } else { - /* disable an active IBSS if we are not on the home channel */ - } - - /* update the various promisc bits */ - wlc_mac_bcn_promisc(wlc); - wlc_mac_promisc(wlc); -} - -static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec) -{ - wlc_rateset_t default_rateset; - uint parkband; - uint i, band_order[2]; - - WL_TRACE("wl%d: wlc_bandinit_ordered\n", wlc->pub->unit); - /* - * We might have been bandlocked during down and the chip power-cycled (hibernate). - * figure out the right band to park on - */ - if (wlc->bandlocked || NBANDS(wlc) == 1) { - ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit); - - parkband = wlc->band->bandunit; /* updated in wlc_bandlock() */ - band_order[0] = band_order[1] = parkband; - } else { - /* park on the band of the specified chanspec */ - parkband = CHSPEC_WLCBANDUNIT(chanspec); - - /* order so that parkband initialize last */ - band_order[0] = parkband ^ 1; - band_order[1] = parkband; - } - - /* make each band operational, software state init */ - for (i = 0; i < NBANDS(wlc); i++) { - uint j = band_order[i]; - - wlc->band = wlc->bandstate[j]; - - wlc_default_rateset(wlc, &default_rateset); - - /* fill in hw_rate */ - wlc_rateset_filter(&default_rateset, &wlc->band->hw_rateset, - false, WLC_RATES_CCK_OFDM, RATE_MASK, - (bool) N_ENAB(wlc->pub)); - - /* init basic rate lookup */ - wlc_rate_lookup_init(wlc, &default_rateset); - } - - /* sync up phy/radio chanspec */ - wlc_set_phy_chanspec(wlc, chanspec); -} - -/* band-specific init */ -static void WLBANDINITFN(wlc_bsinit) (struct wlc_info *wlc) -{ - WL_TRACE("wl%d: wlc_bsinit: bandunit %d\n", - wlc->pub->unit, wlc->band->bandunit); - - /* write ucode ACK/CTS rate table */ - wlc_set_ratetable(wlc); - - /* update some band specific mac configuration */ - wlc_ucode_mac_upd(wlc); - - /* init antenna selection */ - if (WLANTSEL_ENAB(wlc)) - wlc_antsel_init(wlc->asi); - -} - -/* switch to and initialize new band */ -static void WLBANDINITFN(wlc_setband) (struct wlc_info *wlc, uint bandunit) -{ - int idx; - wlc_bsscfg_t *cfg; - - ASSERT(NBANDS(wlc) > 1); - ASSERT(!wlc->bandlocked); - ASSERT(bandunit != wlc->band->bandunit || wlc->bandinit_pending); - - wlc->band = wlc->bandstate[bandunit]; - - if (!wlc->pub->up) - return; - - /* wait for at least one beacon before entering sleeping state */ - wlc->PMawakebcn = true; - FOREACH_AS_STA(wlc, idx, cfg) - cfg->PMawakebcn = true; - wlc_set_ps_ctrl(wlc); - - /* band-specific initializations */ - wlc_bsinit(wlc); -} - -/* Initialize a WME Parameter Info Element with default STA parameters from WMM Spec, Table 12 */ -void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe) -{ - static const wme_param_ie_t stadef = { - WME_OUI, - WME_TYPE, - WME_SUBTYPE_PARAM_IE, - WME_VER, - 0, - 0, - { - {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA, - HTOL16(EDCF_AC_BE_TXOP_STA)}, - {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA, - HTOL16(EDCF_AC_BK_TXOP_STA)}, - {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA, - HTOL16(EDCF_AC_VI_TXOP_STA)}, - {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA, - HTOL16(EDCF_AC_VO_TXOP_STA)} - } - }; - - ASSERT(sizeof(*pe) == WME_PARAM_IE_LEN); - memcpy(pe, &stadef, sizeof(*pe)); -} - -void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend) -{ - int i; - shm_acparams_t acp_shm; - u16 *shm_entry; - struct ieee80211_tx_queue_params *params = arg; - - ASSERT(wlc); - - /* Only apply params if the core is out of reset and has clocks */ - if (!wlc->clk) { - WL_ERROR("wl%d: %s : no-clock\n", wlc->pub->unit, __func__); - return; - } - - /* - * AP uses AC params from wme_param_ie_ap. - * AP advertises AC params from wme_param_ie. - * STA uses AC params from wme_param_ie. - */ - - wlc->wme_admctl = 0; - - do { - memset((char *)&acp_shm, 0, sizeof(shm_acparams_t)); - /* find out which ac this set of params applies to */ - ASSERT(aci < AC_COUNT); - /* set the admission control policy for this AC */ - /* wlc->wme_admctl |= 1 << aci; *//* should be set ?? seems like off by default */ - - /* fill in shm ac params struct */ - acp_shm.txop = ltoh16(params->txop); - /* convert from units of 32us to us for ucode */ - wlc->edcf_txop[aci & 0x3] = acp_shm.txop = - EDCF_TXOP2USEC(acp_shm.txop); - acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK); - - if (aci == AC_VI && acp_shm.txop == 0 - && acp_shm.aifs < EDCF_AIFSN_MAX) - acp_shm.aifs++; - - if (acp_shm.aifs < EDCF_AIFSN_MIN - || acp_shm.aifs > EDCF_AIFSN_MAX) { - WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n", - wlc->pub->unit, acp_shm.aifs); - continue; - } - - acp_shm.cwmin = params->cw_min; - acp_shm.cwmax = params->cw_max; - acp_shm.cwcur = acp_shm.cwmin; - acp_shm.bslots = - R_REG(wlc->osh, &wlc->regs->tsf_random) & acp_shm.cwcur; - acp_shm.reggap = acp_shm.bslots + acp_shm.aifs; - /* Indicate the new params to the ucode */ - acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO + - wme_shmemacindex(aci) * - M_EDCF_QLEN + - M_EDCF_STATUS_OFF)); - acp_shm.status |= WME_STATUS_NEWAC; - - /* Fill in shm acparam table */ - shm_entry = (u16 *) &acp_shm; - for (i = 0; i < (int)sizeof(shm_acparams_t); i += 2) - wlc_write_shm(wlc, - M_EDCF_QINFO + - wme_shmemacindex(aci) * M_EDCF_QLEN + i, - *shm_entry++); - - } while (0); - - if (suspend) - wlc_suspend_mac_and_wait(wlc); - - if (suspend) - wlc_enable_mac(wlc); - -} - -void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend) -{ - struct wlc_info *wlc = cfg->wlc; - uint aci, i, j; - edcf_acparam_t *edcf_acp; - shm_acparams_t acp_shm; - u16 *shm_entry; - - ASSERT(cfg); - ASSERT(wlc); - - /* Only apply params if the core is out of reset and has clocks */ - if (!wlc->clk) - return; - - /* - * AP uses AC params from wme_param_ie_ap. - * AP advertises AC params from wme_param_ie. - * STA uses AC params from wme_param_ie. - */ - - edcf_acp = (edcf_acparam_t *) &wlc->wme_param_ie.acparam[0]; - - wlc->wme_admctl = 0; - - for (i = 0; i < AC_COUNT; i++, edcf_acp++) { - memset((char *)&acp_shm, 0, sizeof(shm_acparams_t)); - /* find out which ac this set of params applies to */ - aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT; - ASSERT(aci < AC_COUNT); - /* set the admission control policy for this AC */ - if (edcf_acp->ACI & EDCF_ACM_MASK) { - wlc->wme_admctl |= 1 << aci; - } - - /* fill in shm ac params struct */ - acp_shm.txop = ltoh16(edcf_acp->TXOP); - /* convert from units of 32us to us for ucode */ - wlc->edcf_txop[aci] = acp_shm.txop = - EDCF_TXOP2USEC(acp_shm.txop); - acp_shm.aifs = (edcf_acp->ACI & EDCF_AIFSN_MASK); - - if (aci == AC_VI && acp_shm.txop == 0 - && acp_shm.aifs < EDCF_AIFSN_MAX) - acp_shm.aifs++; - - if (acp_shm.aifs < EDCF_AIFSN_MIN - || acp_shm.aifs > EDCF_AIFSN_MAX) { - WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n", - wlc->pub->unit, acp_shm.aifs); - continue; - } - - /* CWmin = 2^(ECWmin) - 1 */ - acp_shm.cwmin = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK); - /* CWmax = 2^(ECWmax) - 1 */ - acp_shm.cwmax = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK) - >> EDCF_ECWMAX_SHIFT); - acp_shm.cwcur = acp_shm.cwmin; - acp_shm.bslots = - R_REG(wlc->osh, &wlc->regs->tsf_random) & acp_shm.cwcur; - acp_shm.reggap = acp_shm.bslots + acp_shm.aifs; - /* Indicate the new params to the ucode */ - acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO + - wme_shmemacindex(aci) * - M_EDCF_QLEN + - M_EDCF_STATUS_OFF)); - acp_shm.status |= WME_STATUS_NEWAC; - - /* Fill in shm acparam table */ - shm_entry = (u16 *) &acp_shm; - for (j = 0; j < (int)sizeof(shm_acparams_t); j += 2) - wlc_write_shm(wlc, - M_EDCF_QINFO + - wme_shmemacindex(aci) * M_EDCF_QLEN + j, - *shm_entry++); - } - - if (suspend) - wlc_suspend_mac_and_wait(wlc); - - if (AP_ENAB(wlc->pub) && WME_ENAB(wlc->pub)) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, false); - } - - if (suspend) - wlc_enable_mac(wlc); - -} - -bool wlc_timers_init(struct wlc_info *wlc, int unit) -{ - wlc->wdtimer = wl_init_timer(wlc->wl, wlc_watchdog_by_timer, - wlc, "watchdog"); - if (!wlc->wdtimer) { - WL_ERROR("wl%d: wl_init_timer for wdtimer failed\n", unit); - goto fail; - } - - wlc->radio_timer = wl_init_timer(wlc->wl, wlc_radio_timer, - wlc, "radio"); - if (!wlc->radio_timer) { - WL_ERROR("wl%d: wl_init_timer for radio_timer failed\n", unit); - goto fail; - } - - return true; - - fail: - return false; -} - -/* - * Initialize wlc_info default values ... - * may get overrides later in this function - */ -void wlc_info_init(struct wlc_info *wlc, int unit) -{ - int i; - /* Assume the device is there until proven otherwise */ - wlc->device_present = true; - - /* set default power output percentage to 100 percent */ - wlc->txpwr_percent = 100; - - /* Save our copy of the chanspec */ - wlc->chanspec = CH20MHZ_CHSPEC(1); - - /* initialize CCK preamble mode to unassociated state */ - wlc->shortpreamble = false; - - wlc->legacy_probe = true; - - /* various 802.11g modes */ - wlc->shortslot = false; - wlc->shortslot_override = WLC_SHORTSLOT_AUTO; - - wlc->barker_overlap_control = true; - wlc->barker_preamble = WLC_BARKER_SHORT_ALLOWED; - wlc->txburst_limit_override = AUTO; - - wlc_protection_upd(wlc, WLC_PROT_G_OVR, WLC_PROTECTION_AUTO); - wlc_protection_upd(wlc, WLC_PROT_G_SPEC, false); - - wlc_protection_upd(wlc, WLC_PROT_N_CFG_OVR, WLC_PROTECTION_AUTO); - wlc_protection_upd(wlc, WLC_PROT_N_CFG, WLC_N_PROTECTION_OFF); - wlc_protection_upd(wlc, WLC_PROT_N_NONGF_OVR, WLC_PROTECTION_AUTO); - wlc_protection_upd(wlc, WLC_PROT_N_NONGF, false); - wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR, AUTO); - - wlc_protection_upd(wlc, WLC_PROT_OVERLAP, WLC_PROTECTION_CTL_OVERLAP); - - /* 802.11g draft 4.0 NonERP elt advertisement */ - wlc->include_legacy_erp = true; - - wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF; - wlc->stf->txant = ANT_TX_DEF; - - wlc->prb_resp_timeout = WLC_PRB_RESP_TIMEOUT; - - wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN; - for (i = 0; i < NFIFO; i++) - wlc->fragthresh[i] = DOT11_DEFAULT_FRAG_LEN; - wlc->RTSThresh = DOT11_DEFAULT_RTS_LEN; - - /* default rate fallback retry limits */ - wlc->SFBL = RETRY_SHORT_FB; - wlc->LFBL = RETRY_LONG_FB; - - /* default mac retry limits */ - wlc->SRL = RETRY_SHORT_DEF; - wlc->LRL = RETRY_LONG_DEF; - - /* init PM state */ - wlc->PM = PM_OFF; /* User's setting of PM mode through IOCTL */ - wlc->PM_override = false; /* Prevents from going to PM if our AP is 'ill' */ - wlc->PMenabled = false; /* Current PM state */ - wlc->PMpending = false; /* Tracks whether STA indicated PM in the last attempt */ - wlc->PMblocked = false; /* To allow blocking going into PM during RM and scans */ - - /* In WMM Auto mode, PM is allowed if association is a UAPSD association */ - wlc->WME_PM_blocked = false; - - /* Init wme queuing method */ - wlc->wme_prec_queuing = false; - - /* Overrides for the core to stay awake under zillion conditions Look for STAY_AWAKE */ - wlc->wake = false; - /* Are we waiting for a response to PS-Poll that we sent */ - wlc->PSpoll = false; - - /* APSD defaults */ - wlc->wme_apsd = true; - wlc->apsd_sta_usp = false; - wlc->apsd_trigger_timeout = 0; /* disable the trigger timer */ - wlc->apsd_trigger_ac = AC_BITMAP_ALL; - - /* Set flag to indicate that hw keys should be used when available. */ - wlc->wsec_swkeys = false; - - /* init the 4 static WEP default keys */ - for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) { - wlc->wsec_keys[i] = wlc->wsec_def_keys[i]; - wlc->wsec_keys[i]->idx = (u8) i; - } - - wlc->_regulatory_domain = false; /* 802.11d */ - - /* WME QoS mode is Auto by default */ - wlc->pub->_wme = AUTO; - -#ifdef BCMSDIODEV_ENABLED - wlc->pub->_priofc = true; /* enable priority flow control for sdio dongle */ -#endif - - wlc->pub->_ampdu = AMPDU_AGG_HOST; - wlc->pub->bcmerror = 0; - wlc->ibss_allowed = true; - wlc->ibss_coalesce_allowed = true; - wlc->pub->_coex = ON; - - /* intialize mpc delay */ - wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; - - wlc->pr80838_war = true; -} - -static bool wlc_state_bmac_sync(struct wlc_info *wlc) -{ - wlc_bmac_state_t state_bmac; - - if (wlc_bmac_state_get(wlc->hw, &state_bmac) != 0) - return false; - - wlc->machwcap = state_bmac.machwcap; - wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR, - (s8) state_bmac.preamble_ovr); - - return true; -} - -static uint wlc_attach_module(struct wlc_info *wlc) -{ - uint err = 0; - uint unit; - unit = wlc->pub->unit; - - wlc->asi = wlc_antsel_attach(wlc, wlc->osh, wlc->pub, wlc->hw); - if (wlc->asi == NULL) { - WL_ERROR("wl%d: wlc_attach: wlc_antsel_attach failed\n", unit); - err = 44; - goto fail; - } - - wlc->ampdu = wlc_ampdu_attach(wlc); - if (wlc->ampdu == NULL) { - WL_ERROR("wl%d: wlc_attach: wlc_ampdu_attach failed\n", unit); - err = 50; - goto fail; - } - - /* Initialize event queue; needed before following calls */ - wlc->eventq = - wlc_eventq_attach(wlc->pub, wlc, wlc->wl, wlc_process_eventq); - if (wlc->eventq == NULL) { - WL_ERROR("wl%d: wlc_attach: wlc_eventq_attachfailed\n", unit); - err = 57; - goto fail; - } - - if ((wlc_stf_attach(wlc) != 0)) { - WL_ERROR("wl%d: wlc_attach: wlc_stf_attach failed\n", unit); - err = 68; - goto fail; - } - fail: - return err; -} - -struct wlc_pub *wlc_pub(void *wlc) -{ - return ((struct wlc_info *) wlc)->pub; -} - -#define CHIP_SUPPORTS_11N(wlc) 1 - -/* - * The common driver entry routine. Error codes should be unique - */ -void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, - struct osl_info *osh, void *regsva, uint bustype, - void *btparam, uint *perr) -{ - struct wlc_info *wlc; - uint err = 0; - uint j; - struct wlc_pub *pub; - wlc_txq_info_t *qi; - uint n_disabled; - - WL_NONE("wl%d: %s: vendor 0x%x device 0x%x\n", - unit, __func__, vendor, device); - - ASSERT(WSEC_MAX_RCMTA_KEYS <= WSEC_MAX_KEYS); - ASSERT(WSEC_MAX_DEFAULT_KEYS == WLC_DEFAULT_KEYS); - - /* some code depends on packed structures */ - ASSERT(sizeof(struct ethhdr) == ETH_HLEN); - ASSERT(sizeof(d11regs_t) == SI_CORE_SIZE); - ASSERT(sizeof(ofdm_phy_hdr_t) == D11_PHY_HDR_LEN); - ASSERT(sizeof(cck_phy_hdr_t) == D11_PHY_HDR_LEN); - ASSERT(sizeof(d11txh_t) == D11_TXH_LEN); - ASSERT(sizeof(d11rxhdr_t) == RXHDR_LEN); - ASSERT(sizeof(struct ieee80211_hdr) == DOT11_A4_HDR_LEN); - ASSERT(sizeof(struct ieee80211_rts) == DOT11_RTS_LEN); - ASSERT(sizeof(tx_status_t) == TXSTATUS_LEN); - ASSERT(sizeof(struct ieee80211_ht_cap) == HT_CAP_IE_LEN); -#ifdef BRCM_FULLMAC - ASSERT(offsetof(wl_scan_params_t, channel_list) == - WL_SCAN_PARAMS_FIXED_SIZE); -#endif - ASSERT(IS_ALIGNED(offsetof(wsec_key_t, data), sizeof(u32))); - ASSERT(ISPOWEROF2(MA_WINDOW_SZ)); - - ASSERT(sizeof(wlc_d11rxhdr_t) <= WL_HWRXOFF); - - /* - * Number of replay counters value used in WPA IE must match # rxivs - * supported in wsec_key_t struct. See 802.11i/D3.0 sect. 7.3.2.17 - * 'RSN Information Element' figure 8 for this mapping. - */ - ASSERT((WPA_CAP_16_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE - && 16 == WLC_NUMRXIVS) - || (WPA_CAP_4_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE - && 4 == WLC_NUMRXIVS)); - - /* allocate struct wlc_info state and its substructures */ - wlc = (struct wlc_info *) wlc_attach_malloc(osh, unit, &err, device); - if (wlc == NULL) - goto fail; - wlc->osh = osh; - pub = wlc->pub; - -#if defined(BCMDBG) - wlc_info_dbg = wlc; -#endif - - wlc->band = wlc->bandstate[0]; - wlc->core = wlc->corestate; - wlc->wl = wl; - pub->unit = unit; - pub->osh = osh; - wlc->btparam = btparam; - pub->_piomode = piomode; - wlc->bandinit_pending = false; - /* By default restrict TKIP associations from 11n STA's */ - wlc->ht_wsec_restriction = WLC_HT_TKIP_RESTRICT; - - /* populate struct wlc_info with default values */ - wlc_info_init(wlc, unit); - - /* update sta/ap related parameters */ - wlc_ap_upd(wlc); - - /* 11n_disable nvram */ - n_disabled = getintvar(pub->vars, "11n_disable"); - - /* register a module (to handle iovars) */ - wlc_module_register(wlc->pub, wlc_iovars, "wlc_iovars", wlc, - wlc_doiovar, NULL, NULL); - - /* low level attach steps(all hw accesses go inside, no more in rest of the attach) */ - err = wlc_bmac_attach(wlc, vendor, device, unit, piomode, osh, regsva, - bustype, btparam); - if (err) - goto fail; - - /* for some states, due to different info pointer(e,g, wlc, wlc_hw) or master/slave split, - * HIGH driver(both monolithic and HIGH_ONLY) needs to sync states FROM BMAC portion driver - */ - if (!wlc_state_bmac_sync(wlc)) { - err = 20; - goto fail; - } - - pub->phy_11ncapable = WLC_PHY_11N_CAP(wlc->band); - - /* propagate *vars* from BMAC driver to high driver */ - wlc_bmac_copyfrom_vars(wlc->hw, &pub->vars, &wlc->vars_size); - - - /* set maximum allowed duty cycle */ - wlc->tx_duty_cycle_ofdm = - (u16) getintvar(pub->vars, "tx_duty_cycle_ofdm"); - wlc->tx_duty_cycle_cck = - (u16) getintvar(pub->vars, "tx_duty_cycle_cck"); - - wlc_stf_phy_chain_calc(wlc); - - /* txchain 1: txant 0, txchain 2: txant 1 */ - if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1)) - wlc->stf->txant = wlc->stf->hw_txchain - 1; - - /* push to BMAC driver */ - wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain, - wlc->stf->hw_rxchain); - - /* pull up some info resulting from the low attach */ - { - int i; - for (i = 0; i < NFIFO; i++) - wlc->core->txavail[i] = wlc->hw->txavail[i]; - } - - wlc_bmac_hw_etheraddr(wlc->hw, wlc->perm_etheraddr); - - bcopy((char *)&wlc->perm_etheraddr, (char *)&pub->cur_etheraddr, - ETH_ALEN); - - for (j = 0; j < NBANDS(wlc); j++) { - /* Use band 1 for single band 11a */ - if (IS_SINGLEBAND_5G(wlc->deviceid)) - j = BAND_5G_INDEX; - - wlc->band = wlc->bandstate[j]; - - if (!wlc_attach_stf_ant_init(wlc)) { - err = 24; - goto fail; - } - - /* default contention windows size limits */ - wlc->band->CWmin = APHY_CWMIN; - wlc->band->CWmax = PHY_CWMAX; - - /* init gmode value */ - if (BAND_2G(wlc->band->bandtype)) { - wlc->band->gmode = GMODE_AUTO; - wlc_protection_upd(wlc, WLC_PROT_G_USER, - wlc->band->gmode); - } - - /* init _n_enab supported mode */ - if (WLC_PHY_11N_CAP(wlc->band) && CHIP_SUPPORTS_11N(wlc)) { - if (n_disabled & WLFEATURE_DISABLE_11N) { - pub->_n_enab = OFF; - wlc_protection_upd(wlc, WLC_PROT_N_USER, OFF); - } else { - pub->_n_enab = SUPPORT_11N; - wlc_protection_upd(wlc, WLC_PROT_N_USER, - ((pub->_n_enab == - SUPPORT_11N) ? WL_11N_2x2 : - WL_11N_3x3)); - } - } - - /* init per-band default rateset, depend on band->gmode */ - wlc_default_rateset(wlc, &wlc->band->defrateset); - - /* fill in hw_rateset (used early by WLC_SET_RATESET) */ - wlc_rateset_filter(&wlc->band->defrateset, - &wlc->band->hw_rateset, false, - WLC_RATES_CCK_OFDM, RATE_MASK, - (bool) N_ENAB(wlc->pub)); - } - - /* update antenna config due to wlc->stf->txant/txchain/ant_rx_ovr change */ - wlc_stf_phy_txant_upd(wlc); - - /* attach each modules */ - err = wlc_attach_module(wlc); - if (err != 0) - goto fail; - - if (!wlc_timers_init(wlc, unit)) { - WL_ERROR("wl%d: %s: wlc_init_timer failed\n", unit, __func__); - err = 32; - goto fail; - } - - /* depend on rateset, gmode */ - wlc->cmi = wlc_channel_mgr_attach(wlc); - if (!wlc->cmi) { - WL_ERROR("wl%d: %s: wlc_channel_mgr_attach failed\n", - unit, __func__); - err = 33; - goto fail; - } - - /* init default when all parameters are ready, i.e. ->rateset */ - wlc_bss_default_init(wlc); - - /* - * Complete the wlc default state initializations.. - */ - - /* allocate our initial queue */ - qi = wlc_txq_alloc(wlc, osh); - if (qi == NULL) { - WL_ERROR("wl%d: %s: failed to malloc tx queue\n", - unit, __func__); - err = 100; - goto fail; - } - wlc->active_queue = qi; - - wlc->bsscfg[0] = wlc->cfg; - wlc->cfg->_idx = 0; - wlc->cfg->wlc = wlc; - pub->txmaxpkts = MAXTXPKTS; - - WLCNTSET(pub->_cnt->version, WL_CNT_T_VERSION); - WLCNTSET(pub->_cnt->length, sizeof(wl_cnt_t)); - - WLCNTSET(pub->_wme_cnt->version, WL_WME_CNT_VERSION); - WLCNTSET(pub->_wme_cnt->length, sizeof(wl_wme_cnt_t)); - - wlc_wme_initparams_sta(wlc, &wlc->wme_param_ie); - - wlc->mimoft = FT_HT; - wlc->ht_cap.cap_info = HT_CAP; - if (HT_ENAB(wlc->pub)) - wlc->stf->ldpc = AUTO; - - wlc->mimo_40txbw = AUTO; - wlc->ofdm_40txbw = AUTO; - wlc->cck_40txbw = AUTO; - wlc_update_mimo_band_bwcap(wlc, WLC_N_BW_20IN2G_40IN5G); - - /* Enable setting the RIFS Mode bit by default in HT Info IE */ - wlc->rifs_advert = AUTO; - - /* Set default values of SGI */ - if (WLC_SGI_CAP_PHY(wlc)) { - wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40)); - wlc->sgi_tx = AUTO; - } else if (WLCISSSLPNPHY(wlc->band)) { - wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40)); - wlc->sgi_tx = AUTO; - } else { - wlc_ht_update_sgi_rx(wlc, 0); - wlc->sgi_tx = OFF; - } - - /* *******nvram 11n config overrides Start ********* */ - - /* apply the sgi override from nvram conf */ - if (n_disabled & WLFEATURE_DISABLE_11N_SGI_TX) - wlc->sgi_tx = OFF; - - if (n_disabled & WLFEATURE_DISABLE_11N_SGI_RX) - wlc_ht_update_sgi_rx(wlc, 0); - - /* apply the stbc override from nvram conf */ - if (n_disabled & WLFEATURE_DISABLE_11N_STBC_TX) { - wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF; - wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF; - wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC; - } - if (n_disabled & WLFEATURE_DISABLE_11N_STBC_RX) - wlc_stf_stbc_rx_set(wlc, HT_CAP_RX_STBC_NO); - - /* apply the GF override from nvram conf */ - if (n_disabled & WLFEATURE_DISABLE_11N_GF) - wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_GRN_FLD; - - /* initialize radio_mpc_disable according to wlc->mpc */ - wlc_radio_mpc_upd(wlc); - - if (WLANTSEL_ENAB(wlc)) { - if ((wlc->pub->sih->chip) == BCM43235_CHIP_ID) { - if ((getintvar(wlc->pub->vars, "aa2g") == 7) || - (getintvar(wlc->pub->vars, "aa5g") == 7)) { - wlc_bmac_antsel_set(wlc->hw, 1); - } - } else { - wlc_bmac_antsel_set(wlc->hw, wlc->asi->antsel_avail); - } - } - - if (perr) - *perr = 0; - - return (void *)wlc; - - fail: - WL_ERROR("wl%d: %s: failed with err %d\n", unit, __func__, err); - if (wlc) - wlc_detach(wlc); - - if (perr) - *perr = err; - return NULL; -} - -static void wlc_attach_antgain_init(struct wlc_info *wlc) -{ - uint unit; - unit = wlc->pub->unit; - - if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) { - /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */ - wlc->band->antgain = 8; - } else if (wlc->band->antgain == -1) { - WL_ERROR("wl%d: %s: Invalid antennas available in srom, using 2dB\n", - unit, __func__); - wlc->band->antgain = 8; - } else { - s8 gain, fract; - /* Older sroms specified gain in whole dbm only. In order - * be able to specify qdbm granularity and remain backward compatible - * the whole dbms are now encoded in only low 6 bits and remaining qdbms - * are encoded in the hi 2 bits. 6 bit signed number ranges from - * -32 - 31. Examples: 0x1 = 1 db, - * 0xc1 = 1.75 db (1 + 3 quarters), - * 0x3f = -1 (-1 + 0 quarters), - * 0x7f = -.75 (-1 in low 6 bits + 1 quarters in hi 2 bits) = -3 qdbm. - * 0xbf = -.50 (-1 in low 6 bits + 2 quarters in hi 2 bits) = -2 qdbm. - */ - gain = wlc->band->antgain & 0x3f; - gain <<= 2; /* Sign extend */ - gain >>= 2; - fract = (wlc->band->antgain & 0xc0) >> 6; - wlc->band->antgain = 4 * gain + fract; - } -} - -static bool wlc_attach_stf_ant_init(struct wlc_info *wlc) -{ - int aa; - uint unit; - char *vars; - int bandtype; - - unit = wlc->pub->unit; - vars = wlc->pub->vars; - bandtype = wlc->band->bandtype; - - /* get antennas available */ - aa = (s8) getintvar(vars, (BAND_5G(bandtype) ? "aa5g" : "aa2g")); - if (aa == 0) - aa = (s8) getintvar(vars, - (BAND_5G(bandtype) ? "aa1" : "aa0")); - if ((aa < 1) || (aa > 15)) { - WL_ERROR("wl%d: %s: Invalid antennas available in srom (0x%x), using 3\n", - unit, __func__, aa); - aa = 3; - } - - /* reset the defaults if we have a single antenna */ - if (aa == 1) { - wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_0; - wlc->stf->txant = ANT_TX_FORCE_0; - } else if (aa == 2) { - wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_1; - wlc->stf->txant = ANT_TX_FORCE_1; - } else { - } - - /* Compute Antenna Gain */ - wlc->band->antgain = - (s8) getintvar(vars, (BAND_5G(bandtype) ? "ag1" : "ag0")); - wlc_attach_antgain_init(wlc); - - return true; -} - - -static void wlc_timers_deinit(struct wlc_info *wlc) -{ - /* free timer state */ - if (wlc->wdtimer) { - wl_free_timer(wlc->wl, wlc->wdtimer); - wlc->wdtimer = NULL; - } - if (wlc->radio_timer) { - wl_free_timer(wlc->wl, wlc->radio_timer); - wlc->radio_timer = NULL; - } -} - -static void wlc_detach_module(struct wlc_info *wlc) -{ - if (wlc->asi) { - wlc_antsel_detach(wlc->asi); - wlc->asi = NULL; - } - - if (wlc->ampdu) { - wlc_ampdu_detach(wlc->ampdu); - wlc->ampdu = NULL; - } - - wlc_stf_detach(wlc); -} - -/* - * Return a count of the number of driver callbacks still pending. - * - * General policy is that wlc_detach can only dealloc/free software states. It can NOT - * touch hardware registers since the d11core may be in reset and clock may not be available. - * One exception is sb register access, which is possible if crystal is turned on - * After "down" state, driver should avoid software timer with the exception of radio_monitor. - */ -uint wlc_detach(struct wlc_info *wlc) -{ - uint i; - uint callbacks = 0; - - if (wlc == NULL) - return 0; - - WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__); - - ASSERT(!wlc->pub->up); - - callbacks += wlc_bmac_detach(wlc); - - /* delete software timers */ - if (!wlc_radio_monitor_stop(wlc)) - callbacks++; - - if (wlc->eventq) { - wlc_eventq_detach(wlc->eventq); - wlc->eventq = NULL; - } - - wlc_channel_mgr_detach(wlc->cmi); - - wlc_timers_deinit(wlc); - - wlc_detach_module(wlc); - - /* free other state */ - - -#ifdef BCMDBG - if (wlc->country_ie_override) { - kfree(wlc->country_ie_override); - wlc->country_ie_override = NULL; - } -#endif /* BCMDBG */ - - { - /* free dumpcb list */ - dumpcb_t *prev, *ptr; - prev = ptr = wlc->dumpcb_head; - while (ptr) { - ptr = prev->next; - kfree(prev); - prev = ptr; - } - wlc->dumpcb_head = NULL; - } - - /* Detach from iovar manager */ - wlc_module_unregister(wlc->pub, "wlc_iovars", wlc); - - while (wlc->tx_queues != NULL) { - wlc_txq_free(wlc, wlc->osh, wlc->tx_queues); - } - - /* - * consistency check: wlc_module_register/wlc_module_unregister calls - * should match therefore nothing should be left here. - */ - for (i = 0; i < WLC_MAXMODULES; i++) - ASSERT(wlc->modulecb[i].name[0] == '\0'); - - wlc_detach_mfree(wlc, wlc->osh); - return callbacks; -} - -/* update state that depends on the current value of "ap" */ -void wlc_ap_upd(struct wlc_info *wlc) -{ - if (AP_ENAB(wlc->pub)) - wlc->PLCPHdr_override = WLC_PLCP_AUTO; /* AP: short not allowed, but not enforced */ - else - wlc->PLCPHdr_override = WLC_PLCP_SHORT; /* STA-BSS; short capable */ - - /* disable vlan_mode on AP since some legacy STAs cannot rx tagged pkts */ - wlc->vlan_mode = AP_ENAB(wlc->pub) ? OFF : AUTO; - - /* fixup mpc */ - wlc->mpc = true; -} - -/* read hwdisable state and propagate to wlc flag */ -static void wlc_radio_hwdisable_upd(struct wlc_info *wlc) -{ - if (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO || wlc->pub->hw_off) - return; - - if (wlc_bmac_radio_read_hwdisabled(wlc->hw)) { - mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); - } else { - mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); - } -} - -/* return true if Minimum Power Consumption should be entered, false otherwise */ -bool wlc_is_non_delay_mpc(struct wlc_info *wlc) -{ - return false; -} - -bool wlc_ismpc(struct wlc_info *wlc) -{ - return (wlc->mpc_delay_off == 0) && (wlc_is_non_delay_mpc(wlc)); -} - -void wlc_radio_mpc_upd(struct wlc_info *wlc) -{ - bool mpc_radio, radio_state; - - /* - * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled - * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio - * monitor also when WL_RADIO_MPC_DISABLE is the only reason that - * the radio is going down. - */ - if (!wlc->mpc) { - if (!wlc->pub->radio_disabled) - return; - mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); - wlc_radio_upd(wlc); - if (!wlc->pub->radio_disabled) - wlc_radio_monitor_stop(wlc); - return; - } - - /* - * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in wlc->pub->radio_disabled - * to go ON, always call radio_upd synchronously - * to go OFF, postpone radio_upd to later when context is safe(e.g. watchdog) - */ - radio_state = - (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF : - ON); - mpc_radio = (wlc_ismpc(wlc) == true) ? OFF : ON; - - if (radio_state == ON && mpc_radio == OFF) - wlc->mpc_delay_off = wlc->mpc_dlycnt; - else if (radio_state == OFF && mpc_radio == ON) { - mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); - wlc_radio_upd(wlc); - if (wlc->mpc_offcnt < WLC_MPC_THRESHOLD) { - wlc->mpc_dlycnt = WLC_MPC_MAX_DELAYCNT; - } else - wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; - wlc->mpc_dur += OSL_SYSUPTIME() - wlc->mpc_laston_ts; - } - /* Below logic is meant to capture the transition from mpc off to mpc on for reasons - * other than wlc->mpc_delay_off keeping the mpc off. In that case reset - * wlc->mpc_delay_off to wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off - */ - if ((wlc->prev_non_delay_mpc == false) && - (wlc_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off) { - wlc->mpc_delay_off = wlc->mpc_dlycnt; - } - wlc->prev_non_delay_mpc = wlc_is_non_delay_mpc(wlc); -} - -/* - * centralized radio disable/enable function, - * invoke radio enable/disable after updating hwradio status - */ -static void wlc_radio_upd(struct wlc_info *wlc) -{ - if (wlc->pub->radio_disabled) - wlc_radio_disable(wlc); - else - wlc_radio_enable(wlc); -} - -/* maintain LED behavior in down state */ -static void wlc_down_led_upd(struct wlc_info *wlc) -{ - ASSERT(!wlc->pub->up); - - /* maintain LEDs while in down state, turn on sbclk if not available yet */ - /* turn on sbclk if necessary */ - if (!AP_ENAB(wlc->pub)) { - wlc_pllreq(wlc, true, WLC_PLLREQ_FLIP); - - wlc_pllreq(wlc, false, WLC_PLLREQ_FLIP); - } -} - -void wlc_radio_disable(struct wlc_info *wlc) -{ - if (!wlc->pub->up) { - wlc_down_led_upd(wlc); - return; - } - - wlc_radio_monitor_start(wlc); - wl_down(wlc->wl); -} - -static void wlc_radio_enable(struct wlc_info *wlc) -{ - if (wlc->pub->up) - return; - - if (DEVICEREMOVED(wlc)) - return; - - if (!wlc->down_override) { /* imposed by wl down/out ioctl */ - wl_up(wlc->wl); - } -} - -/* periodical query hw radio button while driver is "down" */ -static void wlc_radio_timer(void *arg) -{ - struct wlc_info *wlc = (struct wlc_info *) arg; - - if (DEVICEREMOVED(wlc)) { - WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); - wl_down(wlc->wl); - return; - } - - /* cap mpc off count */ - if (wlc->mpc_offcnt < WLC_MPC_MAX_DELAYCNT) - wlc->mpc_offcnt++; - - /* validate all the reasons driver could be down and running this radio_timer */ - ASSERT(wlc->pub->radio_disabled || wlc->down_override); - wlc_radio_hwdisable_upd(wlc); - wlc_radio_upd(wlc); -} - -static bool wlc_radio_monitor_start(struct wlc_info *wlc) -{ - /* Don't start the timer if HWRADIO feature is disabled */ - if (wlc->radio_monitor || (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO)) - return true; - - wlc->radio_monitor = true; - wlc_pllreq(wlc, true, WLC_PLLREQ_RADIO_MON); - wl_add_timer(wlc->wl, wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true); - return true; -} - -bool wlc_radio_monitor_stop(struct wlc_info *wlc) -{ - if (!wlc->radio_monitor) - return true; - - ASSERT((wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO) != - WL_SWFL_NOHWRADIO); - - wlc->radio_monitor = false; - wlc_pllreq(wlc, false, WLC_PLLREQ_RADIO_MON); - return wl_del_timer(wlc->wl, wlc->radio_timer); -} - -/* bring the driver down, but don't reset hardware */ -void wlc_out(struct wlc_info *wlc) -{ - wlc_bmac_set_noreset(wlc->hw, true); - wlc_radio_upd(wlc); - wl_down(wlc->wl); - wlc_bmac_set_noreset(wlc->hw, false); - - /* core clk is true in BMAC driver due to noreset, need to mirror it in HIGH */ - wlc->clk = true; - - /* This will make sure that when 'up' is done - * after 'out' it'll restore hardware (especially gpios) - */ - wlc->pub->hw_up = false; -} - -#if defined(BCMDBG) -/* Verify the sanity of wlc->tx_prec_map. This can be done only by making sure that - * if there is no packet pending for the FIFO, then the corresponding prec bits should be set - * in prec_map. Of course, ignore this rule when block_datafifo is set - */ -static bool wlc_tx_prec_map_verify(struct wlc_info *wlc) -{ - /* For non-WME, both fifos have overlapping prec_map. So it's an error only if both - * fail the check. - */ - if (!EDCF_ENAB(wlc->pub)) { - if (!(WLC_TX_FIFO_CHECK(wlc, TX_DATA_FIFO) || - WLC_TX_FIFO_CHECK(wlc, TX_CTL_FIFO))) - return false; - else - return true; - } - - return WLC_TX_FIFO_CHECK(wlc, TX_AC_BK_FIFO) - && WLC_TX_FIFO_CHECK(wlc, TX_AC_BE_FIFO) - && WLC_TX_FIFO_CHECK(wlc, TX_AC_VI_FIFO) - && WLC_TX_FIFO_CHECK(wlc, TX_AC_VO_FIFO); -} -#endif /* BCMDBG */ - -static void wlc_watchdog_by_timer(void *arg) -{ - struct wlc_info *wlc = (struct wlc_info *) arg; - wlc_watchdog(arg); - if (WLC_WATCHDOG_TBTT(wlc)) { - /* set to normal osl watchdog period */ - wl_del_timer(wlc->wl, wlc->wdtimer); - wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, - true); - } -} - -/* common watchdog code */ -static void wlc_watchdog(void *arg) -{ - struct wlc_info *wlc = (struct wlc_info *) arg; - int i; - wlc_bsscfg_t *cfg; - - WL_TRACE("wl%d: wlc_watchdog\n", wlc->pub->unit); - - if (!wlc->pub->up) - return; - - if (DEVICEREMOVED(wlc)) { - WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); - wl_down(wlc->wl); - return; - } - - /* increment second count */ - wlc->pub->now++; - - /* delay radio disable */ - if (wlc->mpc_delay_off) { - if (--wlc->mpc_delay_off == 0) { - mboolset(wlc->pub->radio_disabled, - WL_RADIO_MPC_DISABLE); - if (wlc->mpc && wlc_ismpc(wlc)) - wlc->mpc_offcnt = 0; - wlc->mpc_laston_ts = OSL_SYSUPTIME(); - } - } - - /* mpc sync */ - wlc_radio_mpc_upd(wlc); - /* radio sync: sw/hw/mpc --> radio_disable/radio_enable */ - wlc_radio_hwdisable_upd(wlc); - wlc_radio_upd(wlc); - /* if ismpc, driver should be in down state if up/down is allowed */ - if (wlc->mpc && wlc_ismpc(wlc)) - ASSERT(!wlc->pub->up); - /* if radio is disable, driver may be down, quit here */ - if (wlc->pub->radio_disabled) - return; - - wlc_bmac_watchdog(wlc); - - /* occasionally sample mac stat counters to detect 16-bit counter wrap */ - if ((WLC_UPDATE_STATS(wlc)) - && (!(wlc->pub->now % SW_TIMER_MAC_STAT_UPD))) - wlc_statsupd(wlc); - - /* Manage TKIP countermeasures timers */ - FOREACH_BSS(wlc, i, cfg) { - if (cfg->tk_cm_dt) { - cfg->tk_cm_dt--; - } - if (cfg->tk_cm_bt) { - cfg->tk_cm_bt--; - } - } - - /* Call any registered watchdog handlers */ - for (i = 0; i < WLC_MAXMODULES; i++) { - if (wlc->modulecb[i].watchdog_fn) - wlc->modulecb[i].watchdog_fn(wlc->modulecb[i].hdl); - } - - if (WLCISNPHY(wlc->band) && !wlc->pub->tempsense_disable && - ((wlc->pub->now - wlc->tempsense_lasttime) >= - WLC_TEMPSENSE_PERIOD)) { - wlc->tempsense_lasttime = wlc->pub->now; - wlc_tempsense_upd(wlc); - } - /* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */ - ASSERT(wlc_bmac_taclear(wlc->hw, true)); - - /* Verify that tx_prec_map and fifos are in sync to avoid lock ups */ - ASSERT(wlc_tx_prec_map_verify(wlc)); - - ASSERT(wlc_ps_check(wlc)); -} - -/* make interface operational */ -int wlc_up(struct wlc_info *wlc) -{ - WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__); - - /* HW is turned off so don't try to access it */ - if (wlc->pub->hw_off || DEVICEREMOVED(wlc)) - return BCME_RADIOOFF; - - if (!wlc->pub->hw_up) { - wlc_bmac_hw_up(wlc->hw); - wlc->pub->hw_up = true; - } - - if ((wlc->pub->boardflags & BFL_FEM) - && (wlc->pub->sih->chip == BCM4313_CHIP_ID)) { - if (wlc->pub->boardrev >= 0x1250 - && (wlc->pub->boardflags & BFL_FEM_BT)) { - wlc_mhf(wlc, MHF5, MHF5_4313_GPIOCTRL, - MHF5_4313_GPIOCTRL, WLC_BAND_ALL); - } else { - wlc_mhf(wlc, MHF4, MHF4_EXTPA_ENABLE, MHF4_EXTPA_ENABLE, - WLC_BAND_ALL); - } - } - - /* - * Need to read the hwradio status here to cover the case where the system - * is loaded with the hw radio disabled. We do not want to bring the driver up in this case. - * if radio is disabled, abort up, lower power, start radio timer and return 0(for NDIS) - * don't call radio_update to avoid looping wlc_up. - * - * wlc_bmac_up_prep() returns either 0 or BCME_RADIOOFF only - */ - if (!wlc->pub->radio_disabled) { - int status = wlc_bmac_up_prep(wlc->hw); - if (status == BCME_RADIOOFF) { - if (!mboolisset - (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) { - int idx; - wlc_bsscfg_t *bsscfg; - mboolset(wlc->pub->radio_disabled, - WL_RADIO_HW_DISABLE); - - FOREACH_BSS(wlc, idx, bsscfg) { - if (!BSSCFG_STA(bsscfg) - || !bsscfg->enable || !bsscfg->BSS) - continue; - WL_ERROR("wl%d.%d: wlc_up: rfdisable -> " "wlc_bsscfg_disable()\n", - wlc->pub->unit, idx); - } - } - } else - ASSERT(!status); - } - - if (wlc->pub->radio_disabled) { - wlc_radio_monitor_start(wlc); - return 0; - } - - /* wlc_bmac_up_prep has done wlc_corereset(). so clk is on, set it */ - wlc->clk = true; - - wlc_radio_monitor_stop(wlc); - - /* Set EDCF hostflags */ - if (EDCF_ENAB(wlc->pub)) { - wlc_mhf(wlc, MHF1, MHF1_EDCF, MHF1_EDCF, WLC_BAND_ALL); - } else { - wlc_mhf(wlc, MHF1, MHF1_EDCF, 0, WLC_BAND_ALL); - } - - if (WLC_WAR16165(wlc)) - wlc_mhf(wlc, MHF2, MHF2_PCISLOWCLKWAR, MHF2_PCISLOWCLKWAR, - WLC_BAND_ALL); - - wl_init(wlc->wl); - wlc->pub->up = true; - - if (wlc->bandinit_pending) { - wlc_suspend_mac_and_wait(wlc); - wlc_set_chanspec(wlc, wlc->default_bss->chanspec); - wlc->bandinit_pending = false; - wlc_enable_mac(wlc); - } - - wlc_bmac_up_finish(wlc->hw); - - /* other software states up after ISR is running */ - /* start APs that were to be brought up but are not up yet */ - /* if (AP_ENAB(wlc->pub)) wlc_restart_ap(wlc->ap); */ - - /* Program the TX wme params with the current settings */ - wlc_wme_retries_write(wlc); - - /* start one second watchdog timer */ - ASSERT(!wlc->WDarmed); - wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true); - wlc->WDarmed = true; - - /* ensure antenna config is up to date */ - wlc_stf_phy_txant_upd(wlc); - /* ensure LDPC config is in sync */ - wlc_ht_update_ldpc(wlc, wlc->stf->ldpc); - - return 0; -} - -/* Initialize the base precedence map for dequeueing from txq based on WME settings */ -static void wlc_tx_prec_map_init(struct wlc_info *wlc) -{ - wlc->tx_prec_map = WLC_PREC_BMP_ALL; - memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16)); - - /* For non-WME, both fifos have overlapping MAXPRIO. So just disable all precedences - * if either is full. - */ - if (!EDCF_ENAB(wlc->pub)) { - wlc->fifo2prec_map[TX_DATA_FIFO] = WLC_PREC_BMP_ALL; - wlc->fifo2prec_map[TX_CTL_FIFO] = WLC_PREC_BMP_ALL; - } else { - wlc->fifo2prec_map[TX_AC_BK_FIFO] = WLC_PREC_BMP_AC_BK; - wlc->fifo2prec_map[TX_AC_BE_FIFO] = WLC_PREC_BMP_AC_BE; - wlc->fifo2prec_map[TX_AC_VI_FIFO] = WLC_PREC_BMP_AC_VI; - wlc->fifo2prec_map[TX_AC_VO_FIFO] = WLC_PREC_BMP_AC_VO; - } -} - -static uint wlc_down_del_timer(struct wlc_info *wlc) -{ - uint callbacks = 0; - - return callbacks; -} - -/* - * Mark the interface nonoperational, stop the software mechanisms, - * disable the hardware, free any transient buffer state. - * Return a count of the number of driver callbacks still pending. - */ -uint wlc_down(struct wlc_info *wlc) -{ - - uint callbacks = 0; - int i; - bool dev_gone = false; - wlc_txq_info_t *qi; - - WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__); - - /* check if we are already in the going down path */ - if (wlc->going_down) { - WL_ERROR("wl%d: %s: Driver going down so return\n", - wlc->pub->unit, __func__); - return 0; - } - if (!wlc->pub->up) - return callbacks; - - /* in between, mpc could try to bring down again.. */ - wlc->going_down = true; - - callbacks += wlc_bmac_down_prep(wlc->hw); - - dev_gone = DEVICEREMOVED(wlc); - - /* Call any registered down handlers */ - for (i = 0; i < WLC_MAXMODULES; i++) { - if (wlc->modulecb[i].down_fn) - callbacks += - wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl); - } - - /* cancel the watchdog timer */ - if (wlc->WDarmed) { - if (!wl_del_timer(wlc->wl, wlc->wdtimer)) - callbacks++; - wlc->WDarmed = false; - } - /* cancel all other timers */ - callbacks += wlc_down_del_timer(wlc); - - /* interrupt must have been blocked */ - ASSERT((wlc->macintmask == 0) || !wlc->pub->up); - - wlc->pub->up = false; - - wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL); - - /* clear txq flow control */ - wlc_txflowcontrol_reset(wlc); - - /* flush tx queues */ - for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { - pktq_flush(wlc->osh, &qi->q, true, NULL, 0); - ASSERT(pktq_empty(&qi->q)); - } - - /* flush event queue. - * Should be the last thing done after all the events are generated - * Just delivers the events synchronously instead of waiting for a timer - */ - callbacks += wlc_eventq_down(wlc->eventq); - - callbacks += wlc_bmac_down_finish(wlc->hw); - - /* wlc_bmac_down_finish has done wlc_coredisable(). so clk is off */ - wlc->clk = false; - - - /* Verify all packets are flushed from the driver */ - if (wlc->osh->pktalloced != 0) { - WL_ERROR("%d packets not freed at wlc_down!!!!!!\n", - wlc->osh->pktalloced); - } -#ifdef BCMDBG - /* Since all the packets should have been freed, - * all callbacks should have been called - */ - for (i = 1; i <= wlc->pub->tunables->maxpktcb; i++) - ASSERT(wlc->pkt_callback[i].fn == NULL); -#endif - wlc->going_down = false; - return callbacks; -} - -/* Set the current gmode configuration */ -int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) -{ - int ret = 0; - uint i; - wlc_rateset_t rs; - /* Default to 54g Auto */ - s8 shortslot = WLC_SHORTSLOT_AUTO; /* Advertise and use shortslot (-1/0/1 Auto/Off/On) */ - bool shortslot_restrict = false; /* Restrict association to stations that support shortslot - */ - bool ignore_bcns = true; /* Ignore legacy beacons on the same channel */ - bool ofdm_basic = false; /* Make 6, 12, and 24 basic rates */ - int preamble = WLC_PLCP_LONG; /* Advertise and use short preambles (-1/0/1 Auto/Off/On) */ - bool preamble_restrict = false; /* Restrict association to stations that support short - * preambles - */ - struct wlcband *band; - - /* if N-support is enabled, allow Gmode set as long as requested - * Gmode is not GMODE_LEGACY_B - */ - if (N_ENAB(wlc->pub) && gmode == GMODE_LEGACY_B) - return BCME_UNSUPPORTED; - - /* verify that we are dealing with 2G band and grab the band pointer */ - if (wlc->band->bandtype == WLC_BAND_2G) - band = wlc->band; - else if ((NBANDS(wlc) > 1) && - (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == WLC_BAND_2G)) - band = wlc->bandstate[OTHERBANDUNIT(wlc)]; - else - return BCME_BADBAND; - - /* Legacy or bust when no OFDM is supported by regulatory */ - if ((wlc_channel_locale_flags_in_band(wlc->cmi, band->bandunit) & - WLC_NO_OFDM) && (gmode != GMODE_LEGACY_B)) - return BCME_RANGE; - - /* update configuration value */ - if (config == true) - wlc_protection_upd(wlc, WLC_PROT_G_USER, gmode); - - /* Clear supported rates filter */ - memset(&wlc->sup_rates_override, 0, sizeof(wlc_rateset_t)); - - /* Clear rateset override */ - memset(&rs, 0, sizeof(wlc_rateset_t)); - - switch (gmode) { - case GMODE_LEGACY_B: - shortslot = WLC_SHORTSLOT_OFF; - wlc_rateset_copy(&gphy_legacy_rates, &rs); - - break; - - case GMODE_LRS: - if (AP_ENAB(wlc->pub)) - wlc_rateset_copy(&cck_rates, &wlc->sup_rates_override); - break; - - case GMODE_AUTO: - /* Accept defaults */ - break; - - case GMODE_ONLY: - ofdm_basic = true; - preamble = WLC_PLCP_SHORT; - preamble_restrict = true; - break; - - case GMODE_PERFORMANCE: - if (AP_ENAB(wlc->pub)) /* Put all rates into the Supported Rates element */ - wlc_rateset_copy(&cck_ofdm_rates, - &wlc->sup_rates_override); - - shortslot = WLC_SHORTSLOT_ON; - shortslot_restrict = true; - ofdm_basic = true; - preamble = WLC_PLCP_SHORT; - preamble_restrict = true; - break; - - default: - /* Error */ - WL_ERROR("wl%d: %s: invalid gmode %d\n", - wlc->pub->unit, __func__, gmode); - return BCME_UNSUPPORTED; - } - - /* - * If we are switching to gmode == GMODE_LEGACY_B, - * clean up rate info that may refer to OFDM rates. - */ - if ((gmode == GMODE_LEGACY_B) && (band->gmode != GMODE_LEGACY_B)) { - band->gmode = gmode; - if (band->rspec_override && !IS_CCK(band->rspec_override)) { - band->rspec_override = 0; - wlc_reprate_init(wlc); - } - if (band->mrspec_override && !IS_CCK(band->mrspec_override)) { - band->mrspec_override = 0; - } - } - - band->gmode = gmode; - - wlc->ignore_bcns = ignore_bcns; - - wlc->shortslot_override = shortslot; - - if (AP_ENAB(wlc->pub)) { - /* wlc->ap->shortslot_restrict = shortslot_restrict; */ - wlc->PLCPHdr_override = - (preamble != - WLC_PLCP_LONG) ? WLC_PLCP_SHORT : WLC_PLCP_AUTO; - } - - if ((AP_ENAB(wlc->pub) && preamble != WLC_PLCP_LONG) - || preamble == WLC_PLCP_SHORT) - wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE; - else - wlc->default_bss->capability &= ~WLAN_CAPABILITY_SHORT_PREAMBLE; - - /* Update shortslot capability bit for AP and IBSS */ - if ((AP_ENAB(wlc->pub) && shortslot == WLC_SHORTSLOT_AUTO) || - shortslot == WLC_SHORTSLOT_ON) - wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_SLOT_TIME; - else - wlc->default_bss->capability &= - ~WLAN_CAPABILITY_SHORT_SLOT_TIME; - - /* Use the default 11g rateset */ - if (!rs.count) - wlc_rateset_copy(&cck_ofdm_rates, &rs); - - if (ofdm_basic) { - for (i = 0; i < rs.count; i++) { - if (rs.rates[i] == WLC_RATE_6M - || rs.rates[i] == WLC_RATE_12M - || rs.rates[i] == WLC_RATE_24M) - rs.rates[i] |= WLC_RATE_FLAG; - } - } - - /* Set default bss rateset */ - wlc->default_bss->rateset.count = rs.count; - bcopy((char *)rs.rates, (char *)wlc->default_bss->rateset.rates, - sizeof(wlc->default_bss->rateset.rates)); - - return ret; -} - -static int wlc_nmode_validate(struct wlc_info *wlc, s32 nmode) -{ - int err = 0; - - switch (nmode) { - - case OFF: - break; - - case AUTO: - case WL_11N_2x2: - case WL_11N_3x3: - if (!(WLC_PHY_11N_CAP(wlc->band))) - err = BCME_BADBAND; - break; - - default: - err = BCME_RANGE; - break; - } - - return err; -} - -int wlc_set_nmode(struct wlc_info *wlc, s32 nmode) -{ - uint i; - int err; - - err = wlc_nmode_validate(wlc, nmode); - ASSERT(err == 0); - if (err) - return err; - - switch (nmode) { - case OFF: - wlc->pub->_n_enab = OFF; - wlc->default_bss->flags &= ~WLC_BSS_HT; - /* delete the mcs rates from the default and hw ratesets */ - wlc_rateset_mcs_clear(&wlc->default_bss->rateset); - for (i = 0; i < NBANDS(wlc); i++) { - memset(wlc->bandstate[i]->hw_rateset.mcs, 0, - MCSSET_LEN); - if (IS_MCS(wlc->band->rspec_override)) { - wlc->bandstate[i]->rspec_override = 0; - wlc_reprate_init(wlc); - } - if (IS_MCS(wlc->band->mrspec_override)) - wlc->bandstate[i]->mrspec_override = 0; - } - break; - - case AUTO: - if (wlc->stf->txstreams == WL_11N_3x3) - nmode = WL_11N_3x3; - else - nmode = WL_11N_2x2; - case WL_11N_2x2: - case WL_11N_3x3: - ASSERT(WLC_PHY_11N_CAP(wlc->band)); - /* force GMODE_AUTO if NMODE is ON */ - wlc_set_gmode(wlc, GMODE_AUTO, true); - if (nmode == WL_11N_3x3) - wlc->pub->_n_enab = SUPPORT_HT; - else - wlc->pub->_n_enab = SUPPORT_11N; - wlc->default_bss->flags |= WLC_BSS_HT; - /* add the mcs rates to the default and hw ratesets */ - wlc_rateset_mcs_build(&wlc->default_bss->rateset, - wlc->stf->txstreams); - for (i = 0; i < NBANDS(wlc); i++) - memcpy(wlc->bandstate[i]->hw_rateset.mcs, - wlc->default_bss->rateset.mcs, MCSSET_LEN); - break; - - default: - ASSERT(0); - break; - } - - return err; -} - -static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg) -{ - wlc_rateset_t rs, new; - uint bandunit; - - bcopy((char *)rs_arg, (char *)&rs, sizeof(wlc_rateset_t)); - - /* check for bad count value */ - if ((rs.count == 0) || (rs.count > WLC_NUMRATES)) - return BCME_BADRATESET; - - /* try the current band */ - bandunit = wlc->band->bandunit; - bcopy((char *)&rs, (char *)&new, sizeof(wlc_rateset_t)); - if (wlc_rate_hwrs_filter_sort_validate - (&new, &wlc->bandstate[bandunit]->hw_rateset, true, - wlc->stf->txstreams)) - goto good; - - /* try the other band */ - if (IS_MBAND_UNLOCKED(wlc)) { - bandunit = OTHERBANDUNIT(wlc); - bcopy((char *)&rs, (char *)&new, sizeof(wlc_rateset_t)); - if (wlc_rate_hwrs_filter_sort_validate(&new, - &wlc-> - bandstate[bandunit]-> - hw_rateset, true, - wlc->stf->txstreams)) - goto good; - } - - return BCME_ERROR; - - good: - /* apply new rateset */ - bcopy((char *)&new, (char *)&wlc->default_bss->rateset, - sizeof(wlc_rateset_t)); - bcopy((char *)&new, (char *)&wlc->bandstate[bandunit]->defrateset, - sizeof(wlc_rateset_t)); - return 0; -} - -/* simplified integer set interface for common ioctl handler */ -int wlc_set(struct wlc_info *wlc, int cmd, int arg) -{ - return wlc_ioctl(wlc, cmd, (void *)&arg, sizeof(arg), NULL); -} - -/* simplified integer get interface for common ioctl handler */ -int wlc_get(struct wlc_info *wlc, int cmd, int *arg) -{ - return wlc_ioctl(wlc, cmd, arg, sizeof(int), NULL); -} - -static void wlc_ofdm_rateset_war(struct wlc_info *wlc) -{ - u8 r; - bool war = false; - - if (wlc->cfg->associated) - r = wlc->cfg->current_bss->rateset.rates[0]; - else - r = wlc->default_bss->rateset.rates[0]; - - wlc_phy_ofdm_rateset_war(wlc->band->pi, war); - - return; -} - -int -wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, - struct wlc_if *wlcif) -{ - return _wlc_ioctl(wlc, cmd, arg, len, wlcif); -} - -/* common ioctl handler. return: 0=ok, -1=error, positive=particular error */ -static int -_wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, - struct wlc_if *wlcif) -{ - int val, *pval; - bool bool_val; - int bcmerror; - d11regs_t *regs; - uint i; - struct scb *nextscb; - bool ta_ok; - uint band; - rw_reg_t *r; - wlc_bsscfg_t *bsscfg; - struct osl_info *osh; - wlc_bss_info_t *current_bss; - - /* update bsscfg pointer */ - bsscfg = NULL; /* XXX: Hack bsscfg to be size one and use this globally */ - current_bss = NULL; - - /* initialize the following to get rid of compiler warning */ - nextscb = NULL; - ta_ok = false; - band = 0; - r = NULL; - - /* If the device is turned off, then it's not "removed" */ - if (!wlc->pub->hw_off && DEVICEREMOVED(wlc)) { - WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); - wl_down(wlc->wl); - return BCME_ERROR; - } - - ASSERT(!(wlc->pub->hw_off && wlc->pub->up)); - - /* default argument is generic integer */ - pval = arg ? (int *)arg:NULL; - - /* This will prevent the misaligned access */ - if (pval && (u32) len >= sizeof(val)) - bcopy(pval, &val, sizeof(val)); - else - val = 0; - - /* bool conversion to avoid duplication below */ - bool_val = val != 0; - - if (cmd != WLC_SET_CHANNEL) - WL_NONE("WLC_IOCTL: cmd %d val 0x%x (%d) len %d\n", - cmd, (uint)val, val, len); - - bcmerror = 0; - regs = wlc->regs; - osh = wlc->osh; - - /* A few commands don't need any arguments; all the others do. */ - switch (cmd) { - case WLC_UP: - case WLC_OUT: - case WLC_DOWN: - case WLC_DISASSOC: - case WLC_RESTART: - case WLC_REBOOT: - case WLC_START_CHANNEL_QA: - case WLC_INIT: - break; - - default: - if ((arg == NULL) || (len <= 0)) { - WL_ERROR("wl%d: %s: Command %d needs arguments\n", - wlc->pub->unit, __func__, cmd); - bcmerror = BCME_BADARG; - goto done; - } - } - - switch (cmd) { - -#if defined(BCMDBG) - case WLC_GET_MSGLEVEL: - *pval = wl_msg_level; - break; - - case WLC_SET_MSGLEVEL: - wl_msg_level = val; - break; -#endif - - case WLC_GET_INSTANCE: - *pval = wlc->pub->unit; - break; - - case WLC_GET_CHANNEL:{ - channel_info_t *ci = (channel_info_t *) arg; - - ASSERT(len > (int)sizeof(ci)); - - ci->hw_channel = - CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC); - ci->target_channel = - CHSPEC_CHANNEL(wlc->default_bss->chanspec); - ci->scan_channel = 0; - - break; - } - - case WLC_SET_CHANNEL:{ - chanspec_t chspec = CH20MHZ_CHSPEC(val); - - if (val < 0 || val > MAXCHANNEL) { - bcmerror = BCME_OUTOFRANGECHAN; - break; - } - - if (!wlc_valid_chanspec_db(wlc->cmi, chspec)) { - bcmerror = BCME_BADCHAN; - break; - } - - if (!wlc->pub->up && IS_MBAND_UNLOCKED(wlc)) { - if (wlc->band->bandunit != - CHSPEC_WLCBANDUNIT(chspec)) - wlc->bandinit_pending = true; - else - wlc->bandinit_pending = false; - } - - wlc->default_bss->chanspec = chspec; - /* wlc_BSSinit() will sanitize the rateset before using it.. */ - if (wlc->pub->up && !wlc->pub->associated && - (WLC_BAND_PI_RADIO_CHANSPEC != chspec)) { - wlc_set_home_chanspec(wlc, chspec); - wlc_suspend_mac_and_wait(wlc); - wlc_set_chanspec(wlc, chspec); - wlc_enable_mac(wlc); - } - break; - } - -#if defined(BCMDBG) - case WLC_GET_UCFLAGS: - if (!wlc->pub->up) { - bcmerror = BCME_NOTUP; - break; - } - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (val >= MHFMAX) { - bcmerror = BCME_RANGE; - break; - } - - *pval = wlc_bmac_mhf_get(wlc->hw, (u8) val, WLC_BAND_AUTO); - break; - - case WLC_SET_UCFLAGS: - if (!wlc->pub->up) { - bcmerror = BCME_NOTUP; - break; - } - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - i = (u16) val; - if (i >= MHFMAX) { - bcmerror = BCME_RANGE; - break; - } - - wlc_mhf(wlc, (u8) i, 0xffff, (u16) (val >> NBITS(u16)), - WLC_BAND_AUTO); - break; - - case WLC_GET_SHMEM: - ta_ok = true; - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (val & 1) { - bcmerror = BCME_BADADDR; - break; - } - - *pval = wlc_read_shm(wlc, (u16) val); - break; - - case WLC_SET_SHMEM: - ta_ok = true; - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (val & 1) { - bcmerror = BCME_BADADDR; - break; - } - - wlc_write_shm(wlc, (u16) val, - (u16) (val >> NBITS(u16))); - break; - - case WLC_R_REG: /* MAC registers */ - ta_ok = true; - r = (rw_reg_t *) arg; - band = WLC_BAND_AUTO; - - if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - if (len >= (int)sizeof(rw_reg_t)) - band = r->band; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if ((r->byteoff + r->size) > sizeof(d11regs_t)) { - bcmerror = BCME_BADADDR; - break; - } - if (r->size == sizeof(u32)) - r->val = - R_REG(osh, - (u32 *)((unsigned char *)(unsigned long)regs + - r->byteoff)); - else if (r->size == sizeof(u16)) - r->val = - R_REG(osh, - (u16 *)((unsigned char *)(unsigned long)regs + - r->byteoff)); - else - bcmerror = BCME_BADADDR; - break; - - case WLC_W_REG: - ta_ok = true; - r = (rw_reg_t *) arg; - band = WLC_BAND_AUTO; - - if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - if (len >= (int)sizeof(rw_reg_t)) - band = r->band; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (r->byteoff + r->size > sizeof(d11regs_t)) { - bcmerror = BCME_BADADDR; - break; - } - if (r->size == sizeof(u32)) - W_REG(osh, - (u32 *)((unsigned char *)(unsigned long) regs + - r->byteoff), r->val); - else if (r->size == sizeof(u16)) - W_REG(osh, - (u16 *)((unsigned char *)(unsigned long) regs + - r->byteoff), r->val); - else - bcmerror = BCME_BADADDR; - break; -#endif /* BCMDBG */ - - case WLC_GET_TXANT: - *pval = wlc->stf->txant; - break; - - case WLC_SET_TXANT: - bcmerror = wlc_stf_ant_txant_validate(wlc, (s8) val); - if (bcmerror < 0) - break; - - wlc->stf->txant = (s8) val; - - /* if down, we are done */ - if (!wlc->pub->up) - break; - - wlc_suspend_mac_and_wait(wlc); - - wlc_stf_phy_txant_upd(wlc); - wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec); - - wlc_enable_mac(wlc); - - break; - - case WLC_GET_ANTDIV:{ - u8 phy_antdiv; - - /* return configured value if core is down */ - if (!wlc->pub->up) { - *pval = wlc->stf->ant_rx_ovr; - - } else { - if (wlc_phy_ant_rxdiv_get - (wlc->band->pi, &phy_antdiv)) - *pval = (int)phy_antdiv; - else - *pval = (int)wlc->stf->ant_rx_ovr; - } - - break; - } - case WLC_SET_ANTDIV: - /* values are -1=driver default, 0=force0, 1=force1, 2=start1, 3=start0 */ - if ((val < -1) || (val > 3)) { - bcmerror = BCME_RANGE; - break; - } - - if (val == -1) - val = ANT_RX_DIV_DEF; - - wlc->stf->ant_rx_ovr = (u8) val; - wlc_phy_ant_rxdiv_set(wlc->band->pi, (u8) val); - break; - - case WLC_GET_RX_ANT:{ /* get latest used rx antenna */ - u16 rxstatus; - - if (!wlc->pub->up) { - bcmerror = BCME_NOTUP; - break; - } - - rxstatus = R_REG(wlc->osh, &wlc->regs->phyrxstatus0); - if (rxstatus == 0xdead || rxstatus == (u16) -1) { - bcmerror = BCME_ERROR; - break; - } - *pval = (rxstatus & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; - break; - } - -#if defined(BCMDBG) - case WLC_GET_UCANTDIV: - if (!wlc->clk) { - bcmerror = BCME_NOCLK; - break; - } - - *pval = - (wlc_bmac_mhf_get(wlc->hw, MHF1, WLC_BAND_AUTO) & - MHF1_ANTDIV); - break; - - case WLC_SET_UCANTDIV:{ - if (!wlc->pub->up) { - bcmerror = BCME_NOTUP; - break; - } - - /* if multiband, band must be locked */ - if (IS_MBAND_UNLOCKED(wlc)) { - bcmerror = BCME_NOTBANDLOCKED; - break; - } - - /* 4322 supports antdiv in phy, no need to set it to ucode */ - if (WLCISNPHY(wlc->band) - && D11REV_IS(wlc->pub->corerev, 16)) { - WL_ERROR("wl%d: can't set ucantdiv for 4322\n", - wlc->pub->unit); - bcmerror = BCME_UNSUPPORTED; - } else - wlc_mhf(wlc, MHF1, MHF1_ANTDIV, - (val ? MHF1_ANTDIV : 0), WLC_BAND_AUTO); - break; - } -#endif /* defined(BCMDBG) */ - - case WLC_GET_SRL: - *pval = wlc->SRL; - break; - - case WLC_SET_SRL: - if (val >= 1 && val <= RETRY_SHORT_MAX) { - int ac; - wlc->SRL = (u16) val; - - wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); - - for (ac = 0; ac < AC_COUNT; ac++) { - WLC_WME_RETRY_SHORT_SET(wlc, ac, wlc->SRL); - } - wlc_wme_retries_write(wlc); - } else - bcmerror = BCME_RANGE; - break; - - case WLC_GET_LRL: - *pval = wlc->LRL; - break; - - case WLC_SET_LRL: - if (val >= 1 && val <= 255) { - int ac; - wlc->LRL = (u16) val; - - wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); - - for (ac = 0; ac < AC_COUNT; ac++) { - WLC_WME_RETRY_LONG_SET(wlc, ac, wlc->LRL); - } - wlc_wme_retries_write(wlc); - } else - bcmerror = BCME_RANGE; - break; - - case WLC_GET_CWMIN: - *pval = wlc->band->CWmin; - break; - - case WLC_SET_CWMIN: - if (!wlc->clk) { - bcmerror = BCME_NOCLK; - break; - } - - if (val >= 1 && val <= 255) { - wlc_set_cwmin(wlc, (u16) val); - } else - bcmerror = BCME_RANGE; - break; - - case WLC_GET_CWMAX: - *pval = wlc->band->CWmax; - break; - - case WLC_SET_CWMAX: - if (!wlc->clk) { - bcmerror = BCME_NOCLK; - break; - } - - if (val >= 255 && val <= 2047) { - wlc_set_cwmax(wlc, (u16) val); - } else - bcmerror = BCME_RANGE; - break; - - case WLC_GET_RADIO: /* use mask if don't want to expose some internal bits */ - *pval = wlc->pub->radio_disabled; - break; - - case WLC_SET_RADIO:{ /* 32 bits input, higher 16 bits are mask, lower 16 bits are value to - * set - */ - u16 radiomask, radioval; - uint validbits = - WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE; - mbool new = 0; - - radiomask = (val & 0xffff0000) >> 16; - radioval = val & 0x0000ffff; - - if ((radiomask == 0) || (radiomask & ~validbits) - || (radioval & ~validbits) - || ((radioval & ~radiomask) != 0)) { - WL_ERROR("SET_RADIO with wrong bits 0x%x\n", - val); - bcmerror = BCME_RANGE; - break; - } - - new = - (wlc->pub->radio_disabled & ~radiomask) | radioval; - wlc->pub->radio_disabled = new; - - wlc_radio_hwdisable_upd(wlc); - wlc_radio_upd(wlc); - break; - } - - case WLC_GET_PHYTYPE: - *pval = WLC_PHYTYPE(wlc->band->phytype); - break; - -#if defined(BCMDBG) - case WLC_GET_KEY: - if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc))) { - wl_wsec_key_t key; - - wsec_key_t *src_key = wlc->wsec_keys[val]; - - if (len < (int)sizeof(key)) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - memset((char *)&key, 0, sizeof(key)); - if (src_key) { - key.index = src_key->id; - key.len = src_key->len; - bcopy(src_key->data, key.data, key.len); - key.algo = src_key->algo; - if (WSEC_SOFTKEY(wlc, src_key, bsscfg)) - key.flags |= WL_SOFT_KEY; - if (src_key->flags & WSEC_PRIMARY_KEY) - key.flags |= WL_PRIMARY_KEY; - - bcopy(src_key->ea, key.ea, - ETH_ALEN); - } - - bcopy((char *)&key, arg, sizeof(key)); - } else - bcmerror = BCME_BADKEYIDX; - break; -#endif /* defined(BCMDBG) */ - - case WLC_SET_KEY: - bcmerror = - wlc_iovar_op(wlc, "wsec_key", NULL, 0, arg, len, IOV_SET, - wlcif); - break; - - case WLC_GET_KEY_SEQ:{ - wsec_key_t *key; - - if (len < DOT11_WPA_KEY_RSC_LEN) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - /* Return the key's tx iv as an EAPOL sequence counter. - * This will be used to supply the RSC value to a supplicant. - * The format is 8 bytes, with least significant in seq[0]. - */ - - key = WSEC_KEY(wlc, val); - if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc)) && - (key != NULL)) { - u8 seq[DOT11_WPA_KEY_RSC_LEN]; - u16 lo; - u32 hi; - /* group keys in WPA-NONE (IBSS only, AES and TKIP) use a global TXIV */ - if ((bsscfg->WPA_auth & WPA_AUTH_NONE) && - is_zero_ether_addr(key->ea)) { - lo = bsscfg->wpa_none_txiv.lo; - hi = bsscfg->wpa_none_txiv.hi; - } else { - lo = key->txiv.lo; - hi = key->txiv.hi; - } - - /* format the buffer, low to high */ - seq[0] = lo & 0xff; - seq[1] = (lo >> 8) & 0xff; - seq[2] = hi & 0xff; - seq[3] = (hi >> 8) & 0xff; - seq[4] = (hi >> 16) & 0xff; - seq[5] = (hi >> 24) & 0xff; - seq[6] = 0; - seq[7] = 0; - - bcopy((char *)seq, arg, sizeof(seq)); - } else { - bcmerror = BCME_BADKEYIDX; - } - break; - } - - case WLC_GET_CURR_RATESET:{ - wl_rateset_t *ret_rs = (wl_rateset_t *) arg; - wlc_rateset_t *rs; - - if (bsscfg->associated) - rs = ¤t_bss->rateset; - else - rs = &wlc->default_bss->rateset; - - if (len < (int)(rs->count + sizeof(rs->count))) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - /* Copy only legacy rateset section */ - ret_rs->count = rs->count; - bcopy(&rs->rates, &ret_rs->rates, rs->count); - break; - } - - case WLC_GET_RATESET:{ - wlc_rateset_t rs; - wl_rateset_t *ret_rs = (wl_rateset_t *) arg; - - memset(&rs, 0, sizeof(wlc_rateset_t)); - wlc_default_rateset(wlc, (wlc_rateset_t *) &rs); - - if (len < (int)(rs.count + sizeof(rs.count))) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - /* Copy only legacy rateset section */ - ret_rs->count = rs.count; - bcopy(&rs.rates, &ret_rs->rates, rs.count); - break; - } - - case WLC_SET_RATESET:{ - wlc_rateset_t rs; - wl_rateset_t *in_rs = (wl_rateset_t *) arg; - - if (len < (int)(in_rs->count + sizeof(in_rs->count))) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - if (in_rs->count > WLC_NUMRATES) { - bcmerror = BCME_BUFTOOLONG; - break; - } - - memset(&rs, 0, sizeof(wlc_rateset_t)); - - /* Copy only legacy rateset section */ - rs.count = in_rs->count; - bcopy(&in_rs->rates, &rs.rates, rs.count); - - /* merge rateset coming in with the current mcsset */ - if (N_ENAB(wlc->pub)) { - if (bsscfg->associated) - bcopy(¤t_bss->rateset.mcs[0], - rs.mcs, MCSSET_LEN); - else - bcopy(&wlc->default_bss->rateset.mcs[0], - rs.mcs, MCSSET_LEN); - } - - bcmerror = wlc_set_rateset(wlc, &rs); - - if (!bcmerror) - wlc_ofdm_rateset_war(wlc); - - break; - } - - case WLC_GET_BCNPRD: - if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated) - *pval = current_bss->beacon_period; - else - *pval = wlc->default_bss->beacon_period; - break; - - case WLC_SET_BCNPRD: - /* range [1, 0xffff] */ - if (val >= DOT11_MIN_BEACON_PERIOD - && val <= DOT11_MAX_BEACON_PERIOD) { - wlc->default_bss->beacon_period = (u16) val; - } else - bcmerror = BCME_RANGE; - break; - - case WLC_GET_DTIMPRD: - if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated) - *pval = current_bss->dtim_period; - else - *pval = wlc->default_bss->dtim_period; - break; - - case WLC_SET_DTIMPRD: - /* range [1, 0xff] */ - if (val >= DOT11_MIN_DTIM_PERIOD - && val <= DOT11_MAX_DTIM_PERIOD) { - wlc->default_bss->dtim_period = (u8) val; - } else - bcmerror = BCME_RANGE; - break; - -#ifdef SUPPORT_PS - case WLC_GET_PM: - *pval = wlc->PM; - break; - - case WLC_SET_PM: - if ((val >= PM_OFF) && (val <= PM_MAX)) { - wlc->PM = (u8) val; - if (wlc->pub->up) { - } - /* Change watchdog driver to align watchdog with tbtt if possible */ - wlc_watchdog_upd(wlc, PS_ALLOWED(wlc)); - } else - bcmerror = BCME_ERROR; - break; -#endif /* SUPPORT_PS */ - -#ifdef SUPPORT_PS -#ifdef BCMDBG - case WLC_GET_WAKE: - if (AP_ENAB(wlc->pub)) { - bcmerror = BCME_NOTSTA; - break; - } - *pval = wlc->wake; - break; - - case WLC_SET_WAKE: - if (AP_ENAB(wlc->pub)) { - bcmerror = BCME_NOTSTA; - break; - } - - wlc->wake = val ? true : false; - - /* if down, we're done */ - if (!wlc->pub->up) - break; - - /* apply to the mac */ - wlc_set_ps_ctrl(wlc); - break; -#endif /* BCMDBG */ -#endif /* SUPPORT_PS */ - - case WLC_GET_REVINFO: - bcmerror = wlc_get_revision_info(wlc, arg, (uint) len); - break; - - case WLC_GET_AP: - *pval = (int)AP_ENAB(wlc->pub); - break; - - case WLC_GET_ATIM: - if (bsscfg->associated) - *pval = (int)current_bss->atim_window; - else - *pval = (int)wlc->default_bss->atim_window; - break; - - case WLC_SET_ATIM: - wlc->default_bss->atim_window = (u32) val; - break; - - case WLC_GET_PKTCNTS:{ - get_pktcnt_t *pktcnt = (get_pktcnt_t *) pval; - if (WLC_UPDATE_STATS(wlc)) - wlc_statsupd(wlc); - pktcnt->rx_good_pkt = WLCNTVAL(wlc->pub->_cnt->rxframe); - pktcnt->rx_bad_pkt = WLCNTVAL(wlc->pub->_cnt->rxerror); - pktcnt->tx_good_pkt = - WLCNTVAL(wlc->pub->_cnt->txfrmsnt); - pktcnt->tx_bad_pkt = - WLCNTVAL(wlc->pub->_cnt->txerror) + - WLCNTVAL(wlc->pub->_cnt->txfail); - if (len >= (int)sizeof(get_pktcnt_t)) { - /* Be backward compatible - only if buffer is large enough */ - pktcnt->rx_ocast_good_pkt = - WLCNTVAL(wlc->pub->_cnt->rxmfrmocast); - } - break; - } - -#ifdef SUPPORT_HWKEY - case WLC_GET_WSEC: - bcmerror = - wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_GET, - wlcif); - break; - - case WLC_SET_WSEC: - bcmerror = - wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_SET, - wlcif); - break; - - case WLC_GET_WPA_AUTH: - *pval = (int)bsscfg->WPA_auth; - break; - - case WLC_SET_WPA_AUTH: - /* change of WPA_Auth modifies the PS_ALLOWED state */ - if (BSSCFG_STA(bsscfg)) { - bsscfg->WPA_auth = (u16) val; - } else - bsscfg->WPA_auth = (u16) val; - break; -#endif /* SUPPORT_HWKEY */ - - case WLC_GET_BANDLIST: - /* count of number of bands, followed by each band type */ - *pval++ = NBANDS(wlc); - *pval++ = wlc->band->bandtype; - if (NBANDS(wlc) > 1) - *pval++ = wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype; - break; - - case WLC_GET_BAND: - *pval = wlc->bandlocked ? wlc->band->bandtype : WLC_BAND_AUTO; - break; - - case WLC_GET_PHYLIST: - { - unsigned char *cp = arg; - if (len < 3) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - if (WLCISNPHY(wlc->band)) { - *cp++ = 'n'; - } else if (WLCISLCNPHY(wlc->band)) { - *cp++ = 'c'; - } else if (WLCISSSLPNPHY(wlc->band)) { - *cp++ = 's'; - } - *cp = '\0'; - break; - } - - case WLC_GET_SHORTSLOT: - *pval = wlc->shortslot; - break; - - case WLC_GET_SHORTSLOT_OVERRIDE: - *pval = wlc->shortslot_override; - break; - - case WLC_SET_SHORTSLOT_OVERRIDE: - if ((val != WLC_SHORTSLOT_AUTO) && - (val != WLC_SHORTSLOT_OFF) && (val != WLC_SHORTSLOT_ON)) { - bcmerror = BCME_RANGE; - break; - } - - wlc->shortslot_override = (s8) val; - - /* shortslot is an 11g feature, so no more work if we are - * currently on the 5G band - */ - if (BAND_5G(wlc->band->bandtype)) - break; - - if (wlc->pub->up && wlc->pub->associated) { - /* let watchdog or beacon processing update shortslot */ - } else if (wlc->pub->up) { - /* unassociated shortslot is off */ - wlc_switch_shortslot(wlc, false); - } else { - /* driver is down, so just update the wlc_info value */ - if (wlc->shortslot_override == WLC_SHORTSLOT_AUTO) { - wlc->shortslot = false; - } else { - wlc->shortslot = - (wlc->shortslot_override == - WLC_SHORTSLOT_ON); - } - } - - break; - - case WLC_GET_LEGACY_ERP: - *pval = wlc->include_legacy_erp; - break; - - case WLC_SET_LEGACY_ERP: - if (wlc->include_legacy_erp == bool_val) - break; - - wlc->include_legacy_erp = bool_val; - - if (AP_ENAB(wlc->pub) && wlc->clk) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - } - break; - - case WLC_GET_GMODE: - if (wlc->band->bandtype == WLC_BAND_2G) - *pval = wlc->band->gmode; - else if (NBANDS(wlc) > 1) - *pval = wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode; - break; - - case WLC_SET_GMODE: - if (!wlc->pub->associated) - bcmerror = wlc_set_gmode(wlc, (u8) val, true); - else { - bcmerror = BCME_ASSOCIATED; - break; - } - break; - - case WLC_GET_GMODE_PROTECTION: - *pval = wlc->protection->_g; - break; - - case WLC_GET_PROTECTION_CONTROL: - *pval = wlc->protection->overlap; - break; - - case WLC_SET_PROTECTION_CONTROL: - if ((val != WLC_PROTECTION_CTL_OFF) && - (val != WLC_PROTECTION_CTL_LOCAL) && - (val != WLC_PROTECTION_CTL_OVERLAP)) { - bcmerror = BCME_RANGE; - break; - } - - wlc_protection_upd(wlc, WLC_PROT_OVERLAP, (s8) val); - - /* Current g_protection will sync up to the specified control alg in watchdog - * if the driver is up and associated. - * If the driver is down or not associated, the control setting has no effect. - */ - break; - - case WLC_GET_GMODE_PROTECTION_OVERRIDE: - *pval = wlc->protection->g_override; - break; - - case WLC_SET_GMODE_PROTECTION_OVERRIDE: - if ((val != WLC_PROTECTION_AUTO) && - (val != WLC_PROTECTION_OFF) && (val != WLC_PROTECTION_ON)) { - bcmerror = BCME_RANGE; - break; - } - - wlc_protection_upd(wlc, WLC_PROT_G_OVR, (s8) val); - - break; - - case WLC_SET_SUP_RATESET_OVERRIDE:{ - wlc_rateset_t rs, new; - - /* copyin */ - if (len < (int)sizeof(wlc_rateset_t)) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - bcopy((char *)arg, (char *)&rs, sizeof(wlc_rateset_t)); - - /* check for bad count value */ - if (rs.count > WLC_NUMRATES) { - bcmerror = BCME_BADRATESET; /* invalid rateset */ - break; - } - - /* this command is only appropriate for gmode operation */ - if (!(wlc->band->gmode || - ((NBANDS(wlc) > 1) - && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) { - bcmerror = BCME_BADBAND; /* gmode only command when not in gmode */ - break; - } - - /* check for an empty rateset to clear the override */ - if (rs.count == 0) { - memset(&wlc->sup_rates_override, 0, - sizeof(wlc_rateset_t)); - break; - } - - /* validate rateset by comparing pre and post sorted against 11g hw rates */ - wlc_rateset_filter(&rs, &new, false, WLC_RATES_CCK_OFDM, - RATE_MASK, BSS_N_ENAB(wlc, bsscfg)); - wlc_rate_hwrs_filter_sort_validate(&new, - &cck_ofdm_rates, - false, - wlc->stf->txstreams); - if (rs.count != new.count) { - bcmerror = BCME_BADRATESET; /* invalid rateset */ - break; - } - - /* apply new rateset to the override */ - bcopy((char *)&new, (char *)&wlc->sup_rates_override, - sizeof(wlc_rateset_t)); - - /* update bcn and probe resp if needed */ - if (wlc->pub->up && AP_ENAB(wlc->pub) - && wlc->pub->associated) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - } - break; - } - - case WLC_GET_SUP_RATESET_OVERRIDE: - /* this command is only appropriate for gmode operation */ - if (!(wlc->band->gmode || - ((NBANDS(wlc) > 1) - && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) { - bcmerror = BCME_BADBAND; /* gmode only command when not in gmode */ - break; - } - if (len < (int)sizeof(wlc_rateset_t)) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - bcopy((char *)&wlc->sup_rates_override, (char *)arg, - sizeof(wlc_rateset_t)); - - break; - - case WLC_GET_PRB_RESP_TIMEOUT: - *pval = wlc->prb_resp_timeout; - break; - - case WLC_SET_PRB_RESP_TIMEOUT: - if (wlc->pub->up) { - bcmerror = BCME_NOTDOWN; - break; - } - if (val < 0 || val >= 0xFFFF) { - bcmerror = BCME_RANGE; /* bad value */ - break; - } - wlc->prb_resp_timeout = (u16) val; - break; - - case WLC_GET_KEY_PRIMARY:{ - wsec_key_t *key; - - /* treat the 'val' parm as the key id */ - key = WSEC_BSS_DEFAULT_KEY(bsscfg); - if (key != NULL) { - *pval = key->id == val ? true : false; - } else { - bcmerror = BCME_BADKEYIDX; - } - break; - } - - case WLC_SET_KEY_PRIMARY:{ - wsec_key_t *key, *old_key; - - bcmerror = BCME_BADKEYIDX; - - /* treat the 'val' parm as the key id */ - for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) { - key = bsscfg->bss_def_keys[i]; - if (key != NULL && key->id == val) { - old_key = WSEC_BSS_DEFAULT_KEY(bsscfg); - if (old_key != NULL) - old_key->flags &= - ~WSEC_PRIMARY_KEY; - key->flags |= WSEC_PRIMARY_KEY; - bsscfg->wsec_index = i; - bcmerror = BCME_OK; - } - } - break; - } - -#ifdef BCMDBG - case WLC_INIT: - wl_init(wlc->wl); - break; -#endif - - case WLC_SET_VAR: - case WLC_GET_VAR:{ - char *name; - /* validate the name value */ - name = (char *)arg; - for (i = 0; i < (uint) len && *name != '\0'; - i++, name++) - ; - - if (i == (uint) len) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - i++; /* include the null in the string length */ - - if (cmd == WLC_GET_VAR) { - bcmerror = - wlc_iovar_op(wlc, arg, - (void *)((s8 *) arg + i), - len - i, arg, len, IOV_GET, - wlcif); - } else - bcmerror = - wlc_iovar_op(wlc, arg, NULL, 0, - (void *)((s8 *) arg + i), - len - i, IOV_SET, wlcif); - - break; - } - - case WLC_SET_WSEC_PMK: - bcmerror = BCME_UNSUPPORTED; - break; - -#if defined(BCMDBG) - case WLC_CURRENT_PWR: - if (!wlc->pub->up) - bcmerror = BCME_NOTUP; - else - bcmerror = wlc_get_current_txpwr(wlc, arg, len); - break; -#endif - - case WLC_LAST: - WL_ERROR("%s: WLC_LAST\n", __func__); - } - done: - - if (bcmerror) { - if (VALID_BCMERROR(bcmerror)) - wlc->pub->bcmerror = bcmerror; - else { - bcmerror = 0; - } - - } - /* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */ - /* In hw_off condition, IOCTLs that reach here are deemed safe but taclear would - * certainly result in getting -1 for register reads. So skip ta_clear altogether - */ - if (!(wlc->pub->hw_off)) - ASSERT(wlc_bmac_taclear(wlc->hw, ta_ok) || !ta_ok); - - return bcmerror; -} - -#if defined(BCMDBG) -/* consolidated register access ioctl error checking */ -int wlc_iocregchk(struct wlc_info *wlc, uint band) -{ - /* if band is specified, it must be the current band */ - if ((band != WLC_BAND_AUTO) && (band != (uint) wlc->band->bandtype)) - return BCME_BADBAND; - - /* if multiband and band is not specified, band must be locked */ - if ((band == WLC_BAND_AUTO) && IS_MBAND_UNLOCKED(wlc)) - return BCME_NOTBANDLOCKED; - - /* must have core clocks */ - if (!wlc->clk) - return BCME_NOCLK; - - return 0; -} -#endif /* defined(BCMDBG) */ - -#if defined(BCMDBG) -/* For some ioctls, make sure that the pi pointer matches the current phy */ -int wlc_iocpichk(struct wlc_info *wlc, uint phytype) -{ - if (wlc->band->phytype != phytype) - return BCME_BADBAND; - return 0; -} -#endif - -/* Look up the given var name in the given table */ -static const bcm_iovar_t *wlc_iovar_lookup(const bcm_iovar_t *table, - const char *name) -{ - const bcm_iovar_t *vi; - const char *lookup_name; - - /* skip any ':' delimited option prefixes */ - lookup_name = strrchr(name, ':'); - if (lookup_name != NULL) - lookup_name++; - else - lookup_name = name; - - ASSERT(table != NULL); - - for (vi = table; vi->name; vi++) { - if (!strcmp(vi->name, lookup_name)) - return vi; - } - /* ran to end of table */ - - return NULL; /* var name not found */ -} - -/* simplified integer get interface for common WLC_GET_VAR ioctl handler */ -int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg) -{ - return wlc_iovar_op(wlc, name, NULL, 0, arg, sizeof(s32), IOV_GET, - NULL); -} - -/* simplified integer set interface for common WLC_SET_VAR ioctl handler */ -int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg) -{ - return wlc_iovar_op(wlc, name, NULL, 0, (void *)&arg, sizeof(arg), - IOV_SET, NULL); -} - -/* simplified s8 get interface for common WLC_GET_VAR ioctl handler */ -int wlc_iovar_gets8(struct wlc_info *wlc, const char *name, s8 *arg) -{ - int iovar_int; - int err; - - err = - wlc_iovar_op(wlc, name, NULL, 0, &iovar_int, sizeof(iovar_int), - IOV_GET, NULL); - if (!err) - *arg = (s8) iovar_int; - - return err; -} - -/* - * register iovar table, watchdog and down handlers. - * calling function must keep 'iovars' until wlc_module_unregister is called. - * 'iovar' must have the last entry's name field being NULL as terminator. - */ -int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, - const char *name, void *hdl, iovar_fn_t i_fn, - watchdog_fn_t w_fn, down_fn_t d_fn) -{ - struct wlc_info *wlc = (struct wlc_info *) pub->wlc; - int i; - - ASSERT(name != NULL); - ASSERT(i_fn != NULL || w_fn != NULL || d_fn != NULL); - - /* find an empty entry and just add, no duplication check! */ - for (i = 0; i < WLC_MAXMODULES; i++) { - if (wlc->modulecb[i].name[0] == '\0') { - strncpy(wlc->modulecb[i].name, name, - sizeof(wlc->modulecb[i].name) - 1); - wlc->modulecb[i].iovars = iovars; - wlc->modulecb[i].hdl = hdl; - wlc->modulecb[i].iovar_fn = i_fn; - wlc->modulecb[i].watchdog_fn = w_fn; - wlc->modulecb[i].down_fn = d_fn; - return 0; - } - } - - /* it is time to increase the capacity */ - ASSERT(i < WLC_MAXMODULES); - return BCME_NORESOURCE; -} - -/* unregister module callbacks */ -int wlc_module_unregister(struct wlc_pub *pub, const char *name, void *hdl) -{ - struct wlc_info *wlc = (struct wlc_info *) pub->wlc; - int i; - - if (wlc == NULL) - return BCME_NOTFOUND; - - ASSERT(name != NULL); - - for (i = 0; i < WLC_MAXMODULES; i++) { - if (!strcmp(wlc->modulecb[i].name, name) && - (wlc->modulecb[i].hdl == hdl)) { - memset(&wlc->modulecb[i], 0, sizeof(modulecb_t)); - return 0; - } - } - - /* table not found! */ - return BCME_NOTFOUND; -} - -/* Write WME tunable parameters for retransmit/max rate from wlc struct to ucode */ -static void wlc_wme_retries_write(struct wlc_info *wlc) -{ - int ac; - - /* Need clock to do this */ - if (!wlc->clk) - return; - - for (ac = 0; ac < AC_COUNT; ac++) { - wlc_write_shm(wlc, M_AC_TXLMT_ADDR(ac), wlc->wme_retries[ac]); - } -} - -/* Get or set an iovar. The params/p_len pair specifies any additional - * qualifying parameters (e.g. an "element index") for a get, while the - * arg/len pair is the buffer for the value to be set or retrieved. - * Operation (get/set) is specified by the last argument. - * interface context provided by wlcif - * - * All pointers may point into the same buffer. - */ -int -wlc_iovar_op(struct wlc_info *wlc, const char *name, - void *params, int p_len, void *arg, int len, - bool set, struct wlc_if *wlcif) -{ - int err = 0; - int val_size; - const bcm_iovar_t *vi = NULL; - u32 actionid; - int i; - - ASSERT(name != NULL); - - ASSERT(len >= 0); - - /* Get MUST have return space */ - ASSERT(set || (arg && len)); - - ASSERT(!(wlc->pub->hw_off && wlc->pub->up)); - - /* Set does NOT take qualifiers */ - ASSERT(!set || (!params && !p_len)); - - if (!set && (len == sizeof(int)) && - !(IS_ALIGNED((unsigned long)(arg), (uint) sizeof(int)))) { - WL_ERROR("wl%d: %s unaligned get ptr for %s\n", - wlc->pub->unit, __func__, name); - ASSERT(0); - } - - /* find the given iovar name */ - for (i = 0; i < WLC_MAXMODULES; i++) { - if (!wlc->modulecb[i].iovars) - continue; - vi = wlc_iovar_lookup(wlc->modulecb[i].iovars, name); - if (vi) - break; - } - /* iovar name not found */ - if (i >= WLC_MAXMODULES) { - err = BCME_UNSUPPORTED; - goto exit; - } - - /* set up 'params' pointer in case this is a set command so that - * the convenience int and bool code can be common to set and get - */ - if (params == NULL) { - params = arg; - p_len = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - /* all other types are integer sized */ - val_size = sizeof(int); - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - - /* Do the actual parameter implementation */ - err = wlc->modulecb[i].iovar_fn(wlc->modulecb[i].hdl, vi, actionid, - name, params, p_len, arg, len, val_size, - wlcif); - - exit: - return err; -} - -int -wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, void *arg, int len, - bool set) -{ - struct wlc_info *wlc = (struct wlc_info *) pub->wlc; - int err = 0; - s32 int_val = 0; - - /* check generic condition flags */ - if (set) { - if (((vi->flags & IOVF_SET_DOWN) && wlc->pub->up) || - ((vi->flags & IOVF_SET_UP) && !wlc->pub->up)) { - err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP); - } else if ((vi->flags & IOVF_SET_BAND) - && IS_MBAND_UNLOCKED(wlc)) { - err = BCME_NOTBANDLOCKED; - } else if ((vi->flags & IOVF_SET_CLK) && !wlc->clk) { - err = BCME_NOCLK; - } - } else { - if (((vi->flags & IOVF_GET_DOWN) && wlc->pub->up) || - ((vi->flags & IOVF_GET_UP) && !wlc->pub->up)) { - err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP); - } else if ((vi->flags & IOVF_GET_BAND) - && IS_MBAND_UNLOCKED(wlc)) { - err = BCME_NOTBANDLOCKED; - } else if ((vi->flags & IOVF_GET_CLK) && !wlc->clk) { - err = BCME_NOCLK; - } - } - - if (err) - goto exit; - - /* length check on io buf */ - err = bcm_iovar_lencheck(vi, arg, len, set); - if (err) - goto exit; - - /* On set, check value ranges for integer types */ - if (set) { - switch (vi->type) { - case IOVT_BOOL: - case IOVT_INT8: - case IOVT_INT16: - case IOVT_INT32: - case IOVT_UINT8: - case IOVT_UINT16: - case IOVT_UINT32: - bcopy(arg, &int_val, sizeof(int)); - err = wlc_iovar_rangecheck(wlc, int_val, vi); - break; - } - } - exit: - return err; -} - -/* handler for iovar table wlc_iovars */ -/* - * IMPLEMENTATION NOTE: In order to avoid checking for get/set in each - * iovar case, the switch statement maps the iovar id into separate get - * and set values. If you add a new iovar to the switch you MUST use - * IOV_GVAL and/or IOV_SVAL in the case labels to avoid conflict with - * another case. - * Please use params for additional qualifying parameters. - */ -int -wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, - const char *name, void *params, uint p_len, void *arg, int len, - int val_size, struct wlc_if *wlcif) -{ - struct wlc_info *wlc = hdl; - wlc_bsscfg_t *bsscfg; - int err = 0; - s32 int_val = 0; - s32 int_val2 = 0; - s32 *ret_int_ptr; - bool bool_val; - bool bool_val2; - wlc_bss_info_t *current_bss; - - WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__); - - bsscfg = NULL; - current_bss = NULL; - - err = wlc_iovar_check(wlc->pub, vi, arg, len, IOV_ISSET(actionid)); - if (err != 0) - return err; - - /* convenience int and bool vals for first 8 bytes of buffer */ - if (p_len >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); - - if (p_len >= (int)sizeof(int_val) * 2) - bcopy((void *)((unsigned long)params + sizeof(int_val)), &int_val2, - sizeof(int_val)); - - /* convenience int ptr for 4-byte gets (requires int aligned arg) */ - ret_int_ptr = (s32 *) arg; - - bool_val = (int_val != 0) ? true : false; - bool_val2 = (int_val2 != 0) ? true : false; - - WL_TRACE("wl%d: %s: id %d\n", - wlc->pub->unit, __func__, IOV_ID(actionid)); - /* Do the actual parameter implementation */ - switch (actionid) { - - case IOV_GVAL(IOV_QTXPOWER):{ - uint qdbm; - bool override; - - err = wlc_phy_txpower_get(wlc->band->pi, &qdbm, - &override); - if (err != BCME_OK) - return err; - - /* Return qdbm units */ - *ret_int_ptr = - qdbm | (override ? WL_TXPWR_OVERRIDE : 0); - break; - } - - /* As long as override is false, this only sets the *user* targets. - User can twiddle this all he wants with no harm. - wlc_phy_txpower_set() explicitly sets override to false if - not internal or test. - */ - case IOV_SVAL(IOV_QTXPOWER):{ - u8 qdbm; - bool override; - - /* Remove override bit and clip to max qdbm value */ - qdbm = (u8)min_t(u32, (int_val & ~WL_TXPWR_OVERRIDE), 0xff); - /* Extract override setting */ - override = (int_val & WL_TXPWR_OVERRIDE) ? true : false; - err = - wlc_phy_txpower_set(wlc->band->pi, qdbm, override); - break; - } - - case IOV_GVAL(IOV_MPC): - *ret_int_ptr = (s32) wlc->mpc; - break; - - case IOV_SVAL(IOV_MPC): - wlc->mpc = bool_val; - wlc_radio_mpc_upd(wlc); - - break; - - case IOV_GVAL(IOV_BCN_LI_BCN): - *ret_int_ptr = wlc->bcn_li_bcn; - break; - - case IOV_SVAL(IOV_BCN_LI_BCN): - wlc->bcn_li_bcn = (u8) int_val; - if (wlc->pub->up) - wlc_bcn_li_upd(wlc); - break; - - default: - WL_ERROR("wl%d: %s: unsupported\n", wlc->pub->unit, __func__); - err = BCME_UNSUPPORTED; - break; - } - - goto exit; /* avoid unused label warning */ - - exit: - return err; -} - -static int -wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, const bcm_iovar_t *vi) -{ - int err = 0; - u32 min_val = 0; - u32 max_val = 0; - - /* Only ranged integers are checked */ - switch (vi->type) { - case IOVT_INT32: - max_val |= 0x7fffffff; - /* fall through */ - case IOVT_INT16: - max_val |= 0x00007fff; - /* fall through */ - case IOVT_INT8: - max_val |= 0x0000007f; - min_val = ~max_val; - if (vi->flags & IOVF_NTRL) - min_val = 1; - else if (vi->flags & IOVF_WHL) - min_val = 0; - /* Signed values are checked against max_val and min_val */ - if ((s32) val < (s32) min_val - || (s32) val > (s32) max_val) - err = BCME_RANGE; - break; - - case IOVT_UINT32: - max_val |= 0xffffffff; - /* fall through */ - case IOVT_UINT16: - max_val |= 0x0000ffff; - /* fall through */ - case IOVT_UINT8: - max_val |= 0x000000ff; - if (vi->flags & IOVF_NTRL) - min_val = 1; - if ((val < min_val) || (val > max_val)) - err = BCME_RANGE; - break; - } - - return err; -} - -#ifdef BCMDBG -static const char *supr_reason[] = { - "None", "PMQ Entry", "Flush request", - "Previous frag failure", "Channel mismatch", - "Lifetime Expiry", "Underflow" -}; - -static void wlc_print_txs_status(u16 s) -{ - printf("[15:12] %d frame attempts\n", (s & TX_STATUS_FRM_RTX_MASK) >> - TX_STATUS_FRM_RTX_SHIFT); - printf(" [11:8] %d rts attempts\n", (s & TX_STATUS_RTS_RTX_MASK) >> - TX_STATUS_RTS_RTX_SHIFT); - printf(" [7] %d PM mode indicated\n", - ((s & TX_STATUS_PMINDCTD) ? 1 : 0)); - printf(" [6] %d intermediate status\n", - ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0)); - printf(" [5] %d AMPDU\n", (s & TX_STATUS_AMPDU) ? 1 : 0); - printf(" [4:2] %d Frame Suppressed Reason (%s)\n", - ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT), - supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]); - printf(" [1] %d acked\n", ((s & TX_STATUS_ACK_RCV) ? 1 : 0)); -} -#endif /* BCMDBG */ - -void wlc_print_txstatus(tx_status_t *txs) -{ -#if defined(BCMDBG) - u16 s = txs->status; - u16 ackphyrxsh = txs->ackphyrxsh; - - printf("\ntxpkt (MPDU) Complete\n"); - - printf("FrameID: %04x ", txs->frameid); - printf("TxStatus: %04x", s); - printf("\n"); -#ifdef BCMDBG - wlc_print_txs_status(s); -#endif - printf("LastTxTime: %04x ", txs->lasttxtime); - printf("Seq: %04x ", txs->sequence); - printf("PHYTxStatus: %04x ", txs->phyerr); - printf("RxAckRSSI: %04x ", - (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT); - printf("RxAckSQ: %04x", (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); - printf("\n"); -#endif /* defined(BCMDBG) */ -} - -#define MACSTATUPD(name) \ - wlc_ctrupd_cache(macstats.name, &wlc->core->macstat_snapshot->name, &wlc->pub->_cnt->name) - -void wlc_statsupd(struct wlc_info *wlc) -{ - int i; -#ifdef BCMDBG - u16 delta; - u16 rxf0ovfl; - u16 txfunfl[NFIFO]; -#endif /* BCMDBG */ - - /* if driver down, make no sense to update stats */ - if (!wlc->pub->up) - return; - -#ifdef BCMDBG - /* save last rx fifo 0 overflow count */ - rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl; - - /* save last tx fifo underflow count */ - for (i = 0; i < NFIFO; i++) - txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i]; -#endif /* BCMDBG */ - -#ifdef BCMDBG - /* check for rx fifo 0 overflow */ - delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); - if (delta) - WL_ERROR("wl%d: %u rx fifo 0 overflows!\n", - wlc->pub->unit, delta); - - /* check for tx fifo underflows */ - for (i = 0; i < NFIFO; i++) { - delta = - (u16) (wlc->core->macstat_snapshot->txfunfl[i] - - txfunfl[i]); - if (delta) - WL_ERROR("wl%d: %u tx fifo %d underflows!\n", - wlc->pub->unit, delta, i); - } -#endif /* BCMDBG */ - - /* dot11 counter update */ - - WLCNTSET(wlc->pub->_cnt->txrts, - (wlc->pub->_cnt->rxctsucast - - wlc->pub->_cnt->d11cnt_txrts_off)); - WLCNTSET(wlc->pub->_cnt->rxcrc, - (wlc->pub->_cnt->rxbadfcs - wlc->pub->_cnt->d11cnt_rxcrc_off)); - WLCNTSET(wlc->pub->_cnt->txnocts, - ((wlc->pub->_cnt->txrtsfrm - wlc->pub->_cnt->rxctsucast) - - wlc->pub->_cnt->d11cnt_txnocts_off)); - - /* merge counters from dma module */ - for (i = 0; i < NFIFO; i++) { - if (wlc->hw->di[i]) { - WLCNTADD(wlc->pub->_cnt->txnobuf, - (wlc->hw->di[i])->txnobuf); - WLCNTADD(wlc->pub->_cnt->rxnobuf, - (wlc->hw->di[i])->rxnobuf); - WLCNTADD(wlc->pub->_cnt->rxgiant, - (wlc->hw->di[i])->rxgiants); - dma_counterreset(wlc->hw->di[i]); - } - } - - /* - * Aggregate transmit and receive errors that probably resulted - * in the loss of a frame are computed on the fly. - */ - WLCNTSET(wlc->pub->_cnt->txerror, - wlc->pub->_cnt->txnobuf + wlc->pub->_cnt->txnoassoc + - wlc->pub->_cnt->txuflo + wlc->pub->_cnt->txrunt + - wlc->pub->_cnt->dmade + wlc->pub->_cnt->dmada + - wlc->pub->_cnt->dmape); - WLCNTSET(wlc->pub->_cnt->rxerror, - wlc->pub->_cnt->rxoflo + wlc->pub->_cnt->rxnobuf + - wlc->pub->_cnt->rxfragerr + wlc->pub->_cnt->rxrunt + - wlc->pub->_cnt->rxgiant + wlc->pub->_cnt->rxnoscb + - wlc->pub->_cnt->rxbadsrcmac); - for (i = 0; i < NFIFO; i++) - WLCNTADD(wlc->pub->_cnt->rxerror, wlc->pub->_cnt->rxuflo[i]); -} - -bool wlc_chipmatch(u16 vendor, u16 device) -{ - if (vendor != VENDOR_BROADCOM) { - WL_ERROR("wlc_chipmatch: unknown vendor id %04x\n", vendor); - return false; - } - - if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID)) - return true; - - if (device == BCM4313_D11N2G_ID) - return true; - if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID)) - return true; - - WL_ERROR("wlc_chipmatch: unknown device id %04x\n", device); - return false; -} - -#if defined(BCMDBG) -void wlc_print_txdesc(d11txh_t *txh) -{ - u16 mtcl = ltoh16(txh->MacTxControlLow); - u16 mtch = ltoh16(txh->MacTxControlHigh); - u16 mfc = ltoh16(txh->MacFrameControl); - u16 tfest = ltoh16(txh->TxFesTimeNormal); - u16 ptcw = ltoh16(txh->PhyTxControlWord); - u16 ptcw_1 = ltoh16(txh->PhyTxControlWord_1); - u16 ptcw_1_Fbr = ltoh16(txh->PhyTxControlWord_1_Fbr); - u16 ptcw_1_Rts = ltoh16(txh->PhyTxControlWord_1_Rts); - u16 ptcw_1_FbrRts = ltoh16(txh->PhyTxControlWord_1_FbrRts); - u16 mainrates = ltoh16(txh->MainRates); - u16 xtraft = ltoh16(txh->XtraFrameTypes); - u8 *iv = txh->IV; - u8 *ra = txh->TxFrameRA; - u16 tfestfb = ltoh16(txh->TxFesTimeFallback); - u8 *rtspfb = txh->RTSPLCPFallback; - u16 rtsdfb = ltoh16(txh->RTSDurFallback); - u8 *fragpfb = txh->FragPLCPFallback; - u16 fragdfb = ltoh16(txh->FragDurFallback); - u16 mmodelen = ltoh16(txh->MModeLen); - u16 mmodefbrlen = ltoh16(txh->MModeFbrLen); - u16 tfid = ltoh16(txh->TxFrameID); - u16 txs = ltoh16(txh->TxStatus); - u16 mnmpdu = ltoh16(txh->MaxNMpdus); - u16 mabyte = ltoh16(txh->MaxABytes_MRT); - u16 mabyte_f = ltoh16(txh->MaxABytes_FBR); - u16 mmbyte = ltoh16(txh->MinMBytes); - - u8 *rtsph = txh->RTSPhyHeader; - struct ieee80211_rts rts = txh->rts_frame; - char hexbuf[256]; - - /* add plcp header along with txh descriptor */ - prhex("Raw TxDesc + plcp header", (unsigned char *) txh, sizeof(d11txh_t) + 48); - - printf("TxCtlLow: %04x ", mtcl); - printf("TxCtlHigh: %04x ", mtch); - printf("FC: %04x ", mfc); - printf("FES Time: %04x\n", tfest); - printf("PhyCtl: %04x%s ", ptcw, - (ptcw & PHY_TXC_SHORT_HDR) ? " short" : ""); - printf("PhyCtl_1: %04x ", ptcw_1); - printf("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr); - printf("PhyCtl_1_Rts: %04x ", ptcw_1_Rts); - printf("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts); - printf("MainRates: %04x ", mainrates); - printf("XtraFrameTypes: %04x ", xtraft); - printf("\n"); - - bcm_format_hex(hexbuf, iv, sizeof(txh->IV)); - printf("SecIV: %s\n", hexbuf); - bcm_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA)); - printf("RA: %s\n", hexbuf); - - printf("Fb FES Time: %04x ", tfestfb); - bcm_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback)); - printf("RTS PLCP: %s ", hexbuf); - printf("RTS DUR: %04x ", rtsdfb); - bcm_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback)); - printf("PLCP: %s ", hexbuf); - printf("DUR: %04x", fragdfb); - printf("\n"); - - printf("MModeLen: %04x ", mmodelen); - printf("MModeFbrLen: %04x\n", mmodefbrlen); - - printf("FrameID: %04x\n", tfid); - printf("TxStatus: %04x\n", txs); - - printf("MaxNumMpdu: %04x\n", mnmpdu); - printf("MaxAggbyte: %04x\n", mabyte); - printf("MaxAggbyte_fb: %04x\n", mabyte_f); - printf("MinByte: %04x\n", mmbyte); - - bcm_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader)); - printf("RTS PLCP: %s ", hexbuf); - bcm_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame)); - printf("RTS Frame: %s", hexbuf); - printf("\n"); - -} -#endif /* defined(BCMDBG) */ - -#if defined(BCMDBG) -void wlc_print_rxh(d11rxhdr_t *rxh) -{ - u16 len = rxh->RxFrameSize; - u16 phystatus_0 = rxh->PhyRxStatus_0; - u16 phystatus_1 = rxh->PhyRxStatus_1; - u16 phystatus_2 = rxh->PhyRxStatus_2; - u16 phystatus_3 = rxh->PhyRxStatus_3; - u16 macstatus1 = rxh->RxStatus1; - u16 macstatus2 = rxh->RxStatus2; - char flagstr[64]; - char lenbuf[20]; - static const bcm_bit_desc_t macstat_flags[] = { - {RXS_FCSERR, "FCSErr"}, - {RXS_RESPFRAMETX, "Reply"}, - {RXS_PBPRES, "PADDING"}, - {RXS_DECATMPT, "DeCr"}, - {RXS_DECERR, "DeCrErr"}, - {RXS_BCNSENT, "Bcn"}, - {0, NULL} - }; - - prhex("Raw RxDesc", (unsigned char *) rxh, sizeof(d11rxhdr_t)); - - bcm_format_flags(macstat_flags, macstatus1, flagstr, 64); - - snprintf(lenbuf, sizeof(lenbuf), "0x%x", len); - - printf("RxFrameSize: %6s (%d)%s\n", lenbuf, len, - (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : ""); - printf("RxPHYStatus: %04x %04x %04x %04x\n", - phystatus_0, phystatus_1, phystatus_2, phystatus_3); - printf("RxMACStatus: %x %s\n", macstatus1, flagstr); - printf("RXMACaggtype: %x\n", (macstatus2 & RXS_AGGTYPE_MASK)); - printf("RxTSFTime: %04x\n", rxh->RxTSFTime); -} -#endif /* defined(BCMDBG) */ - -#if defined(BCMDBG) -int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len) -{ - uint i, c; - char *p = buf; - char *endp = buf + SSID_FMT_BUF_LEN; - - if (ssid_len > IEEE80211_MAX_SSID_LEN) - ssid_len = IEEE80211_MAX_SSID_LEN; - - for (i = 0; i < ssid_len; i++) { - c = (uint) ssid[i]; - if (c == '\\') { - *p++ = '\\'; - *p++ = '\\'; - } else if (isprint((unsigned char) c)) { - *p++ = (char)c; - } else { - p += snprintf(p, (endp - p), "\\x%02X", c); - } - } - *p = '\0'; - ASSERT(p < endp); - - return (int)(p - buf); -} -#endif /* defined(BCMDBG) */ - -u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate) -{ - return wlc_bmac_rate_shm_offset(wlc->hw, rate); -} - -/* Callback for device removed */ - -/* - * Attempts to queue a packet onto a multiple-precedence queue, - * if necessary evicting a lower precedence packet from the queue. - * - * 'prec' is the precedence number that has already been mapped - * from the packet priority. - * - * Returns true if packet consumed (queued), false if not. - */ -bool BCMFASTPATH -wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, int prec) -{ - return wlc_prec_enq_head(wlc, q, pkt, prec, false); -} - -bool BCMFASTPATH -wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, - int prec, bool head) -{ - struct sk_buff *p; - int eprec = -1; /* precedence to evict from */ - - /* Determine precedence from which to evict packet, if any */ - if (pktq_pfull(q, prec)) - eprec = prec; - else if (pktq_full(q)) { - p = pktq_peek_tail(q, &eprec); - ASSERT(p != NULL); - if (eprec > prec) { - WL_ERROR("%s: Failing: eprec %d > prec %d\n", - __func__, eprec, prec); - return false; - } - } - - /* Evict if needed */ - if (eprec >= 0) { - bool discard_oldest; - - /* Detect queueing to unconfigured precedence */ - ASSERT(!pktq_pempty(q, eprec)); - - discard_oldest = AC_BITMAP_TST(wlc->wme_dp, eprec); - - /* Refuse newer packet unless configured to discard oldest */ - if (eprec == prec && !discard_oldest) { - WL_ERROR("%s: No where to go, prec == %d\n", - __func__, prec); - return false; - } - - /* Evict packet according to discard policy */ - p = discard_oldest ? pktq_pdeq(q, eprec) : pktq_pdeq_tail(q, - eprec); - ASSERT(p != NULL); - - /* Increment wme stats */ - if (WME_ENAB(wlc->pub)) { - WLCNTINCR(wlc->pub->_wme_cnt-> - tx_failed[WME_PRIO2AC(p->priority)].packets); - WLCNTADD(wlc->pub->_wme_cnt-> - tx_failed[WME_PRIO2AC(p->priority)].bytes, - pkttotlen(wlc->osh, p)); - } - - ASSERT(0); - pkt_buf_free_skb(wlc->osh, p, true); - WLCNTINCR(wlc->pub->_cnt->txnobuf); - } - - /* Enqueue */ - if (head) - p = pktq_penq_head(q, prec, pkt); - else - p = pktq_penq(q, prec, pkt); - ASSERT(p != NULL); - - return true; -} - -void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, - uint prec) -{ - struct wlc_info *wlc = (struct wlc_info *) ctx; - wlc_txq_info_t *qi = wlc->active_queue; /* Check me */ - struct pktq *q = &qi->q; - int prio; - - prio = sdu->priority; - - ASSERT(pktq_max(q) >= wlc->pub->tunables->datahiwat); - - if (!wlc_prec_enq(wlc, q, sdu, prec)) { - if (!EDCF_ENAB(wlc->pub) - || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) - WL_ERROR("wl%d: wlc_txq_enq: txq overflow\n", - wlc->pub->unit); - - /* ASSERT(9 == 8); *//* XXX we might hit this condtion in case packet flooding from mac80211 stack */ - pkt_buf_free_skb(wlc->osh, sdu, true); - WLCNTINCR(wlc->pub->_cnt->txnobuf); - } - - /* Check if flow control needs to be turned on after enqueuing the packet - * Don't turn on flow control if EDCF is enabled. Driver would make the decision on what - * to drop instead of relying on stack to make the right decision - */ - if (!EDCF_ENAB(wlc->pub) - || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) { - if (pktq_len(q) >= wlc->pub->tunables->datahiwat) { - wlc_txflowcontrol(wlc, qi, ON, ALLPRIO); - } - } else if (wlc->pub->_priofc) { - if (pktq_plen(q, wlc_prio2prec_map[prio]) >= - wlc->pub->tunables->datahiwat) { - wlc_txflowcontrol(wlc, qi, ON, prio); - } - } -} - -bool BCMFASTPATH -wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, - struct ieee80211_hw *hw) -{ - u8 prio; - uint fifo; - void *pkt; - struct scb *scb = &global_scb; - struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data); - u16 type, fc; - - ASSERT(sdu); - - fc = ltoh16(d11_header->frame_control); - type = (fc & IEEE80211_FCTL_FTYPE); - - /* 802.11 standard requires management traffic to go at highest priority */ - prio = (type == IEEE80211_FTYPE_DATA ? sdu->priority : MAXPRIO); - fifo = prio2fifo[prio]; - - ASSERT((uint) skb_headroom(sdu) >= TXOFF); - ASSERT(!(sdu->cloned)); - ASSERT(!(sdu->next)); - ASSERT(!(sdu->prev)); - ASSERT(fifo < NFIFO); - - pkt = sdu; - if (unlikely - (wlc_d11hdrs_mac80211(wlc, hw, pkt, scb, 0, 1, fifo, 0, NULL, 0))) - return -EINVAL; - wlc_txq_enq(wlc, scb, pkt, WLC_PRIO_TO_PREC(prio)); - wlc_send_q(wlc, wlc->active_queue); - - WLCNTINCR(wlc->pub->_cnt->ieee_tx); - return 0; -} - -void BCMFASTPATH wlc_send_q(struct wlc_info *wlc, wlc_txq_info_t *qi) -{ - struct sk_buff *pkt[DOT11_MAXNUMFRAGS]; - int prec; - u16 prec_map; - int err = 0, i, count; - uint fifo; - struct pktq *q = &qi->q; - struct ieee80211_tx_info *tx_info; - - /* only do work for the active queue */ - if (qi != wlc->active_queue) - return; - - if (in_send_q) - return; - else - in_send_q = true; - - prec_map = wlc->tx_prec_map; - - /* Send all the enq'd pkts that we can. - * Dequeue packets with precedence with empty HW fifo only - */ - while (prec_map && (pkt[0] = pktq_mdeq(q, prec_map, &prec))) { - tx_info = IEEE80211_SKB_CB(pkt[0]); - if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { - err = wlc_sendampdu(wlc->ampdu, qi, pkt, prec); - } else { - count = 1; - err = wlc_prep_pdu(wlc, pkt[0], &fifo); - if (!err) { - for (i = 0; i < count; i++) { - wlc_txfifo(wlc, fifo, pkt[i], true, 1); - } - } - } - - if (err == BCME_BUSY) { - pktq_penq_head(q, prec, pkt[0]); - /* If send failed due to any other reason than a change in - * HW FIFO condition, quit. Otherwise, read the new prec_map! - */ - if (prec_map == wlc->tx_prec_map) - break; - prec_map = wlc->tx_prec_map; - } - } - - /* Check if flow control needs to be turned off after sending the packet */ - if (!EDCF_ENAB(wlc->pub) - || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) { - if (wlc_txflowcontrol_prio_isset(wlc, qi, ALLPRIO) - && (pktq_len(q) < wlc->pub->tunables->datahiwat / 2)) { - wlc_txflowcontrol(wlc, qi, OFF, ALLPRIO); - } - } else if (wlc->pub->_priofc) { - int prio; - for (prio = MAXPRIO; prio >= 0; prio--) { - if (wlc_txflowcontrol_prio_isset(wlc, qi, prio) && - (pktq_plen(q, wlc_prio2prec_map[prio]) < - wlc->pub->tunables->datahiwat / 2)) { - wlc_txflowcontrol(wlc, qi, OFF, prio); - } - } - } - in_send_q = false; -} - -/* - * bcmc_fid_generate: - * Generate frame ID for a BCMC packet. The frag field is not used - * for MC frames so is used as part of the sequence number. - */ -static inline u16 -bcmc_fid_generate(struct wlc_info *wlc, wlc_bsscfg_t *bsscfg, d11txh_t *txh) -{ - u16 frameid; - - frameid = ltoh16(txh->TxFrameID) & ~(TXFID_SEQ_MASK | TXFID_QUEUE_MASK); - frameid |= - (((wlc-> - mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) | - TX_BCMC_FIFO; - - return frameid; -} - -void BCMFASTPATH -wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit, - s8 txpktpend) -{ - u16 frameid = INVALIDFID; - d11txh_t *txh; - - ASSERT(fifo < NFIFO); - txh = (d11txh_t *) (p->data); - - /* When a BC/MC frame is being committed to the BCMC fifo via DMA (NOT PIO), update - * ucode or BSS info as appropriate. - */ - if (fifo == TX_BCMC_FIFO) { - frameid = ltoh16(txh->TxFrameID); - - } - - if (WLC_WAR16165(wlc)) - wlc_war16165(wlc, true); - - - /* Bump up pending count for if not using rpc. If rpc is used, this will be handled - * in wlc_bmac_txfifo() - */ - if (commit) { - TXPKTPENDINC(wlc, fifo, txpktpend); - WL_TRACE("wlc_txfifo, pktpend inc %d to %d\n", - txpktpend, TXPKTPENDGET(wlc, fifo)); - } - - /* Commit BCMC sequence number in the SHM frame ID location */ - if (frameid != INVALIDFID) - BCMCFID(wlc, frameid); - - if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) { - WL_ERROR("wlc_txfifo: fatal, toss frames !!!\n"); - } -} - -static u16 -wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, uint length) -{ - u16 usec = 0; - uint mac_rate = RSPEC2RATE(rspec); - uint nsyms; - - if (IS_MCS(rspec)) { - /* not supported yet */ - ASSERT(0); - } else if (IS_OFDM(rspec)) { - /* nsyms = Ceiling(Nbits / (Nbits/sym)) - * - * Nbits = length * 8 - * Nbits/sym = Mbps * 4 = mac_rate * 2 - */ - nsyms = CEIL((length * 8), (mac_rate * 2)); - - /* usec = symbols * usec/symbol */ - usec = (u16) (nsyms * APHY_SYMBOL_TIME); - return usec; - } else { - switch (mac_rate) { - case WLC_RATE_1M: - usec = length << 3; - break; - case WLC_RATE_2M: - usec = length << 2; - break; - case WLC_RATE_5M5: - usec = (length << 4) / 11; - break; - case WLC_RATE_11M: - usec = (length << 3) / 11; - break; - default: - WL_ERROR("wl%d: wlc_compute_airtime: unsupported rspec 0x%x\n", - wlc->pub->unit, rspec); - ASSERT((const char *)"Bad phy_rate" == NULL); - break; - } - } - - return usec; -} - -void BCMFASTPATH -wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rspec, uint length, u8 *plcp) -{ - if (IS_MCS(rspec)) { - wlc_compute_mimo_plcp(rspec, length, plcp); - } else if (IS_OFDM(rspec)) { - wlc_compute_ofdm_plcp(rspec, length, plcp); - } else { - wlc_compute_cck_plcp(rspec, length, plcp); - } - return; -} - -/* Rate: 802.11 rate code, length: PSDU length in octets */ -static void wlc_compute_mimo_plcp(ratespec_t rspec, uint length, u8 *plcp) -{ - u8 mcs = (u8) (rspec & RSPEC_RATE_MASK); - ASSERT(IS_MCS(rspec)); - plcp[0] = mcs; - if (RSPEC_IS40MHZ(rspec) || (mcs == 32)) - plcp[0] |= MIMO_PLCP_40MHZ; - WLC_SET_MIMO_PLCP_LEN(plcp, length); - plcp[3] = RSPEC_MIMOPLCP3(rspec); /* rspec already holds this byte */ - plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */ - plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */ - plcp[5] = 0; -} - -/* Rate: 802.11 rate code, length: PSDU length in octets */ -static void BCMFASTPATH -wlc_compute_ofdm_plcp(ratespec_t rspec, u32 length, u8 *plcp) -{ - u8 rate_signal; - u32 tmp = 0; - int rate = RSPEC2RATE(rspec); - - ASSERT(IS_OFDM(rspec)); - - /* encode rate per 802.11a-1999 sec 17.3.4.1, with lsb transmitted first */ - rate_signal = rate_info[rate] & RATE_MASK; - ASSERT(rate_signal != 0); - - memset(plcp, 0, D11_PHY_HDR_LEN); - D11A_PHY_HDR_SRATE((ofdm_phy_hdr_t *) plcp, rate_signal); - - tmp = (length & 0xfff) << 5; - plcp[2] |= (tmp >> 16) & 0xff; - plcp[1] |= (tmp >> 8) & 0xff; - plcp[0] |= tmp & 0xff; - - return; -} - -/* - * Compute PLCP, but only requires actual rate and length of pkt. - * Rate is given in the driver standard multiple of 500 kbps. - * le is set for 11 Mbps rate if necessary. - * Broken out for PRQ. - */ - -static void wlc_cck_plcp_set(int rate_500, uint length, u8 *plcp) -{ - u16 usec = 0; - u8 le = 0; - - switch (rate_500) { - case WLC_RATE_1M: - usec = length << 3; - break; - case WLC_RATE_2M: - usec = length << 2; - break; - case WLC_RATE_5M5: - usec = (length << 4) / 11; - if ((length << 4) - (usec * 11) > 0) - usec++; - break; - case WLC_RATE_11M: - usec = (length << 3) / 11; - if ((length << 3) - (usec * 11) > 0) { - usec++; - if ((usec * 11) - (length << 3) >= 8) - le = D11B_PLCP_SIGNAL_LE; - } - break; - - default: - WL_ERROR("wlc_cck_plcp_set: unsupported rate %d\n", rate_500); - rate_500 = WLC_RATE_1M; - usec = length << 3; - break; - } - /* PLCP signal byte */ - plcp[0] = rate_500 * 5; /* r (500kbps) * 5 == r (100kbps) */ - /* PLCP service byte */ - plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED); - /* PLCP length u16, little endian */ - plcp[2] = usec & 0xff; - plcp[3] = (usec >> 8) & 0xff; - /* PLCP CRC16 */ - plcp[4] = 0; - plcp[5] = 0; -} - -/* Rate: 802.11 rate code, length: PSDU length in octets */ -static void wlc_compute_cck_plcp(ratespec_t rspec, uint length, u8 *plcp) -{ - int rate = RSPEC2RATE(rspec); - - ASSERT(IS_CCK(rspec)); - - wlc_cck_plcp_set(rate, length, plcp); -} - -/* wlc_compute_frame_dur() - * - * Calculate the 802.11 MAC header DUR field for MPDU - * DUR for a single frame = 1 SIFS + 1 ACK - * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time - * - * rate MPDU rate in unit of 500kbps - * next_frag_len next MPDU length in bytes - * preamble_type use short/GF or long/MM PLCP header - */ -static u16 BCMFASTPATH -wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type, - uint next_frag_len) -{ - u16 dur, sifs; - - sifs = SIFS(wlc->band); - - dur = sifs; - dur += (u16) wlc_calc_ack_time(wlc, rate, preamble_type); - - if (next_frag_len) { - /* Double the current DUR to get 2 SIFS + 2 ACKs */ - dur *= 2; - /* add another SIFS and the frag time */ - dur += sifs; - dur += - (u16) wlc_calc_frame_time(wlc, rate, preamble_type, - next_frag_len); - } - return dur; -} - -/* wlc_compute_rtscts_dur() - * - * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame - * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK - * DUR for CTS-TO-SELF w/ frame = 2 SIFS + next frame time + 1 ACK - * - * cts cts-to-self or rts/cts - * rts_rate rts or cts rate in unit of 500kbps - * rate next MPDU rate in unit of 500kbps - * frame_len next MPDU frame length in bytes - */ -u16 BCMFASTPATH -wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, ratespec_t rts_rate, - ratespec_t frame_rate, u8 rts_preamble_type, - u8 frame_preamble_type, uint frame_len, bool ba) -{ - u16 dur, sifs; - - sifs = SIFS(wlc->band); - - if (!cts_only) { /* RTS/CTS */ - dur = 3 * sifs; - dur += - (u16) wlc_calc_cts_time(wlc, rts_rate, - rts_preamble_type); - } else { /* CTS-TO-SELF */ - dur = 2 * sifs; - } - - dur += - (u16) wlc_calc_frame_time(wlc, frame_rate, frame_preamble_type, - frame_len); - if (ba) - dur += - (u16) wlc_calc_ba_time(wlc, frame_rate, - WLC_SHORT_PREAMBLE); - else - dur += - (u16) wlc_calc_ack_time(wlc, frame_rate, - frame_preamble_type); - return dur; -} - -static bool wlc_phy_rspec_check(struct wlc_info *wlc, u16 bw, ratespec_t rspec) -{ - if (IS_MCS(rspec)) { - uint mcs = rspec & RSPEC_RATE_MASK; - - if (mcs < 8) { - ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM); - } else if ((mcs >= 8) && (mcs <= 23)) { - ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SDM); - } else if (mcs == 32) { - ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM); - ASSERT(bw == PHY_TXC1_BW_40MHZ_DUP); - } - } else if (IS_OFDM(rspec)) { - ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_STBC); - } else { - ASSERT(IS_CCK(rspec)); - - ASSERT((bw == PHY_TXC1_BW_20MHZ) - || (bw == PHY_TXC1_BW_20MHZ_UP)); - ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SISO); - } - - return true; -} - -u16 BCMFASTPATH wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec) -{ - u16 phyctl1 = 0; - u16 bw; - - if (WLCISLCNPHY(wlc->band)) { - bw = PHY_TXC1_BW_20MHZ; - } else { - bw = RSPEC_GET_BW(rspec); - /* 10Mhz is not supported yet */ - if (bw < PHY_TXC1_BW_20MHZ) { - WL_ERROR("wlc_phytxctl1_calc: bw %d is not supported yet, set to 20L\n", - bw); - bw = PHY_TXC1_BW_20MHZ; - } - - wlc_phy_rspec_check(wlc, bw, rspec); - } - - if (IS_MCS(rspec)) { - uint mcs = rspec & RSPEC_RATE_MASK; - - /* bw, stf, coding-type is part of RSPEC_PHYTXBYTE2 returns */ - phyctl1 = RSPEC_PHYTXBYTE2(rspec); - /* set the upper byte of phyctl1 */ - phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8); - } else if (IS_CCK(rspec) && !WLCISLCNPHY(wlc->band) - && !WLCISSSLPNPHY(wlc->band)) { - /* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */ - /* Eventually MIMOPHY would also be converted to this format */ - /* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */ - phyctl1 = (bw | (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT)); - } else { /* legacy OFDM/CCK */ - s16 phycfg; - /* get the phyctl byte from rate phycfg table */ - phycfg = wlc_rate_legacy_phyctl(RSPEC2RATE(rspec)); - if (phycfg == -1) { - WL_ERROR("wlc_phytxctl1_calc: wrong legacy OFDM/CCK rate\n"); - ASSERT(0); - phycfg = 0; - } - /* set the upper byte of phyctl1 */ - phyctl1 = - (bw | (phycfg << 8) | - (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT)); - } - -#ifdef BCMDBG - /* phy clock must support 40Mhz if tx descriptor uses it */ - if ((phyctl1 & PHY_TXC1_BW_MASK) >= PHY_TXC1_BW_40MHZ) { - ASSERT(CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ); - ASSERT(wlc->chanspec == wlc_phy_chanspec_get(wlc->band->pi)); - } -#endif /* BCMDBG */ - return phyctl1; -} - -ratespec_t BCMFASTPATH -wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, bool use_rspec, - u16 mimo_ctlchbw) -{ - ratespec_t rts_rspec = 0; - - if (use_rspec) { - /* use frame rate as rts rate */ - rts_rspec = rspec; - - } else if (wlc->band->gmode && wlc->protection->_g && !IS_CCK(rspec)) { - /* Use 11Mbps as the g protection RTS target rate and fallback. - * Use the WLC_BASIC_RATE() lookup to find the best basic rate under the - * target in case 11 Mbps is not Basic. - * 6 and 9 Mbps are not usually selected by rate selection, but even - * if the OFDM rate we are protecting is 6 or 9 Mbps, 11 is more robust. - */ - rts_rspec = WLC_BASIC_RATE(wlc, WLC_RATE_11M); - } else { - /* calculate RTS rate and fallback rate based on the frame rate - * RTS must be sent at a basic rate since it is a - * control frame, sec 9.6 of 802.11 spec - */ - rts_rspec = WLC_BASIC_RATE(wlc, rspec); - } - - if (WLC_PHY_11N_CAP(wlc->band)) { - /* set rts txbw to correct side band */ - rts_rspec &= ~RSPEC_BW_MASK; - - /* if rspec/rspec_fallback is 40MHz, then send RTS on both 20MHz channel - * (DUP), otherwise send RTS on control channel - */ - if (RSPEC_IS40MHZ(rspec) && !IS_CCK(rts_rspec)) - rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT); - else - rts_rspec |= (mimo_ctlchbw << RSPEC_BW_SHIFT); - - /* pick siso/cdd as default for ofdm */ - if (IS_OFDM(rts_rspec)) { - rts_rspec &= ~RSPEC_STF_MASK; - rts_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT); - } - } - return rts_rspec; -} - -/* - * Add d11txh_t, cck_phy_hdr_t. - * - * 'p' data must start with 802.11 MAC header - * 'p' must allow enough bytes of local headers to be "pushed" onto the packet - * - * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes) - * - */ -static u16 BCMFASTPATH -wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, - struct sk_buff *p, struct scb *scb, uint frag, - uint nfrags, uint queue, uint next_frag_len, - wsec_key_t *key, ratespec_t rspec_override) -{ - struct ieee80211_hdr *h; - d11txh_t *txh; - u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN]; - struct osl_info *osh; - int len, phylen, rts_phylen; - u16 fc, type, frameid, mch, phyctl, xfts, mainrates; - u16 seq = 0, mcl = 0, status = 0; - ratespec_t rspec[2] = { WLC_RATE_1M, WLC_RATE_1M }, rts_rspec[2] = { - WLC_RATE_1M, WLC_RATE_1M}; - bool use_rts = false; - bool use_cts = false; - bool use_rifs = false; - bool short_preamble[2] = { false, false }; - u8 preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE }; - u8 rts_preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE }; - u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN]; - struct ieee80211_rts *rts = NULL; - bool qos; - uint ac; - u32 rate_val[2]; - bool hwtkmic = false; - u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; -#ifdef WLANTSEL -#define ANTCFG_NONE 0xFF - u8 antcfg = ANTCFG_NONE; - u8 fbantcfg = ANTCFG_NONE; -#endif - uint phyctl1_stf = 0; - u16 durid = 0; - struct ieee80211_tx_rate *txrate[2]; - int k; - struct ieee80211_tx_info *tx_info; - bool is_mcs[2]; - u16 mimo_txbw; - u8 mimo_preamble_type; - - frameid = 0; - - ASSERT(queue < NFIFO); - - osh = wlc->osh; - - /* locate 802.11 MAC header */ - h = (struct ieee80211_hdr *)(p->data); - fc = ltoh16(h->frame_control); - type = (fc & IEEE80211_FCTL_FTYPE); - - qos = (type == IEEE80211_FTYPE_DATA && - FC_SUBTYPE_ANY_QOS(fc)); - - /* compute length of frame in bytes for use in PLCP computations */ - len = pkttotlen(osh, p); - phylen = len + FCS_LEN; - - /* If WEP enabled, add room in phylen for the additional bytes of - * ICV which MAC generates. We do NOT add the additional bytes to - * the packet itself, thus phylen = packet length + ICV_LEN + FCS_LEN - * in this case - */ - if (key) { - phylen += key->icv_len; - } - - /* Get tx_info */ - tx_info = IEEE80211_SKB_CB(p); - ASSERT(tx_info); - - /* add PLCP */ - plcp = skb_push(p, D11_PHY_HDR_LEN); - - /* add Broadcom tx descriptor header */ - txh = (d11txh_t *) skb_push(p, D11_TXH_LEN); - memset((char *)txh, 0, D11_TXH_LEN); - - /* setup frameid */ - if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { - /* non-AP STA should never use BCMC queue */ - ASSERT(queue != TX_BCMC_FIFO); - if (queue == TX_BCMC_FIFO) { - WL_ERROR("wl%d: %s: ASSERT queue == TX_BCMC!\n", - WLCWLUNIT(wlc), __func__); - frameid = bcmc_fid_generate(wlc, NULL, txh); - } else { - /* Increment the counter for first fragment */ - if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) { - SCB_SEQNUM(scb, p->priority)++; - } - - /* extract fragment number from frame first */ - seq = ltoh16(seq) & FRAGNUM_MASK; - seq |= (SCB_SEQNUM(scb, p->priority) << SEQNUM_SHIFT); - h->seq_ctrl = htol16(seq); - - frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) | - (queue & TXFID_QUEUE_MASK); - } - } - frameid |= queue & TXFID_QUEUE_MASK; - - /* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */ - if (SCB_PS(scb) || ((fc & FC_KIND_MASK) == FC_BEACON)) - mcl |= TXC_IGNOREPMQ; - - ASSERT(hw->max_rates <= IEEE80211_TX_MAX_RATES); - ASSERT(hw->max_rates == 2); - - txrate[0] = tx_info->control.rates; - txrate[1] = txrate[0] + 1; - - ASSERT(txrate[0]->idx >= 0); - /* if rate control algorithm didn't give us a fallback rate, use the primary rate */ - if (txrate[1]->idx < 0) { - txrate[1] = txrate[0]; - } - - for (k = 0; k < hw->max_rates; k++) { - is_mcs[k] = - txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false; - if (!is_mcs[k]) { - ASSERT(!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)); - if ((txrate[k]->idx >= 0) - && (txrate[k]->idx < - hw->wiphy->bands[tx_info->band]->n_bitrates)) { - rate_val[k] = - hw->wiphy->bands[tx_info->band]-> - bitrates[txrate[k]->idx].hw_value; - short_preamble[k] = - txrate[k]-> - flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ? - true : false; - } else { - ASSERT((txrate[k]->idx >= 0) && - (txrate[k]->idx < - hw->wiphy->bands[tx_info->band]-> - n_bitrates)); - rate_val[k] = WLC_RATE_1M; - } - } else { - rate_val[k] = txrate[k]->idx; - } - /* Currently only support same setting for primay and fallback rates. - * Unify flags for each rate into a single value for the frame - */ - use_rts |= - txrate[k]-> - flags & IEEE80211_TX_RC_USE_RTS_CTS ? true : false; - use_cts |= - txrate[k]-> - flags & IEEE80211_TX_RC_USE_CTS_PROTECT ? true : false; - - if (is_mcs[k]) - rate_val[k] |= NRATE_MCS_INUSE; - - rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band, rate_val[k]); - - /* (1) RATE: determine and validate primary rate and fallback rates */ - if (!RSPEC_ACTIVE(rspec[k])) { - ASSERT(RSPEC_ACTIVE(rspec[k])); - rspec[k] = WLC_RATE_1M; - } else { - if (WLANTSEL_ENAB(wlc) && - !is_multicast_ether_addr(h->addr1)) { - /* set tx antenna config */ - wlc_antsel_antcfg_get(wlc->asi, false, false, 0, - 0, &antcfg, &fbantcfg); - } - } - } - - phyctl1_stf = wlc->stf->ss_opmode; - - if (N_ENAB(wlc->pub)) { - for (k = 0; k < hw->max_rates; k++) { - /* apply siso/cdd to single stream mcs's or ofdm if rspec is auto selected */ - if (((IS_MCS(rspec[k]) && - IS_SINGLE_STREAM(rspec[k] & RSPEC_RATE_MASK)) || - IS_OFDM(rspec[k])) - && ((rspec[k] & RSPEC_OVERRIDE_MCS_ONLY) - || !(rspec[k] & RSPEC_OVERRIDE))) { - rspec[k] &= ~(RSPEC_STF_MASK | RSPEC_STC_MASK); - - /* For SISO MCS use STBC if possible */ - if (IS_MCS(rspec[k]) - && WLC_STF_SS_STBC_TX(wlc, scb)) { - u8 stc; - - ASSERT(WLC_STBC_CAP_PHY(wlc)); - stc = 1; /* Nss for single stream is always 1 */ - rspec[k] |= - (PHY_TXC1_MODE_STBC << - RSPEC_STF_SHIFT) | (stc << - RSPEC_STC_SHIFT); - } else - rspec[k] |= - (phyctl1_stf << RSPEC_STF_SHIFT); - } - - /* Is the phy configured to use 40MHZ frames? If so then pick the desired txbw */ - if (CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ) { - /* default txbw is 20in40 SB */ - mimo_ctlchbw = mimo_txbw = - CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC) - ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; - - if (IS_MCS(rspec[k])) { - /* mcs 32 must be 40b/w DUP */ - if ((rspec[k] & RSPEC_RATE_MASK) == 32) { - mimo_txbw = - PHY_TXC1_BW_40MHZ_DUP; - /* use override */ - } else if (wlc->mimo_40txbw != AUTO) - mimo_txbw = wlc->mimo_40txbw; - /* else check if dst is using 40 Mhz */ - else if (scb->flags & SCB_IS40) - mimo_txbw = PHY_TXC1_BW_40MHZ; - } else if (IS_OFDM(rspec[k])) { - if (wlc->ofdm_40txbw != AUTO) - mimo_txbw = wlc->ofdm_40txbw; - } else { - ASSERT(IS_CCK(rspec[k])); - if (wlc->cck_40txbw != AUTO) - mimo_txbw = wlc->cck_40txbw; - } - } else { - /* mcs32 is 40 b/w only. - * This is possible for probe packets on a STA during SCAN - */ - if ((rspec[k] & RSPEC_RATE_MASK) == 32) { - /* mcs 0 */ - rspec[k] = RSPEC_MIMORATE; - } - mimo_txbw = PHY_TXC1_BW_20MHZ; - } - - /* Set channel width */ - rspec[k] &= ~RSPEC_BW_MASK; - if ((k == 0) || ((k > 0) && IS_MCS(rspec[k]))) - rspec[k] |= (mimo_txbw << RSPEC_BW_SHIFT); - else - rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT); - - /* Set Short GI */ -#ifdef NOSGIYET - if (IS_MCS(rspec[k]) - && (txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI)) - rspec[k] |= RSPEC_SHORT_GI; - else if (!(txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI)) - rspec[k] &= ~RSPEC_SHORT_GI; -#else - rspec[k] &= ~RSPEC_SHORT_GI; -#endif - - mimo_preamble_type = WLC_MM_PREAMBLE; - if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD) - mimo_preamble_type = WLC_GF_PREAMBLE; - - if ((txrate[k]->flags & IEEE80211_TX_RC_MCS) - && (!IS_MCS(rspec[k]))) { - WL_ERROR("wl%d: %s: IEEE80211_TX_RC_MCS != IS_MCS(rspec)\n", - WLCWLUNIT(wlc), __func__); - ASSERT(0 && "Rate mismatch"); - } - - if (IS_MCS(rspec[k])) { - preamble_type[k] = mimo_preamble_type; - - /* if SGI is selected, then forced mm for single stream */ - if ((rspec[k] & RSPEC_SHORT_GI) - && IS_SINGLE_STREAM(rspec[k] & - RSPEC_RATE_MASK)) { - preamble_type[k] = WLC_MM_PREAMBLE; - } - } - - /* mimo bw field MUST now be valid in the rspec (it affects duration calculations) */ - ASSERT(VALID_RATE_DBG(wlc, rspec[0])); - - /* should be better conditionalized */ - if (!IS_MCS(rspec[0]) - && (tx_info->control.rates[0]. - flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)) - preamble_type[k] = WLC_SHORT_PREAMBLE; - - ASSERT(!IS_MCS(rspec[0]) - || WLC_IS_MIMO_PREAMBLE(preamble_type[k])); - } - } else { - for (k = 0; k < hw->max_rates; k++) { - /* Set ctrlchbw as 20Mhz */ - ASSERT(!IS_MCS(rspec[k])); - rspec[k] &= ~RSPEC_BW_MASK; - rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT); - - /* for nphy, stf of ofdm frames must follow policies */ - if (WLCISNPHY(wlc->band) && IS_OFDM(rspec[k])) { - rspec[k] &= ~RSPEC_STF_MASK; - rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT; - } - } - } - - /* Reset these for use with AMPDU's */ - txrate[0]->count = 0; - txrate[1]->count = 0; - - /* (3) PLCP: determine PLCP header and MAC duration, fill d11txh_t */ - wlc_compute_plcp(wlc, rspec[0], phylen, plcp); - wlc_compute_plcp(wlc, rspec[1], phylen, plcp_fallback); - bcopy(plcp_fallback, (char *)&txh->FragPLCPFallback, - sizeof(txh->FragPLCPFallback)); - - /* Length field now put in CCK FBR CRC field */ - if (IS_CCK(rspec[1])) { - txh->FragPLCPFallback[4] = phylen & 0xff; - txh->FragPLCPFallback[5] = (phylen & 0xff00) >> 8; - } - - /* MIMO-RATE: need validation ?? */ - mainrates = - IS_OFDM(rspec[0]) ? D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) plcp) : - plcp[0]; - - /* DUR field for main rate */ - if ((fc != FC_PS_POLL) && - !is_multicast_ether_addr(h->addr1) && !use_rifs) { - durid = - wlc_compute_frame_dur(wlc, rspec[0], preamble_type[0], - next_frag_len); - h->duration_id = htol16(durid); - } else if (use_rifs) { - /* NAV protect to end of next max packet size */ - durid = - (u16) wlc_calc_frame_time(wlc, rspec[0], - preamble_type[0], - DOT11_MAX_FRAG_LEN); - durid += RIFS_11N_TIME; - h->duration_id = htol16(durid); - } - - /* DUR field for fallback rate */ - if (fc == FC_PS_POLL) - txh->FragDurFallback = h->duration_id; - else if (is_multicast_ether_addr(h->addr1) || use_rifs) - txh->FragDurFallback = 0; - else { - durid = wlc_compute_frame_dur(wlc, rspec[1], - preamble_type[1], next_frag_len); - txh->FragDurFallback = htol16(durid); - } - - /* (4) MAC-HDR: MacTxControlLow */ - if (frag == 0) - mcl |= TXC_STARTMSDU; - - if (!is_multicast_ether_addr(h->addr1)) - mcl |= TXC_IMMEDACK; - - if (BAND_5G(wlc->band->bandtype)) - mcl |= TXC_FREQBAND_5G; - - if (CHSPEC_IS40(WLC_BAND_PI_RADIO_CHANSPEC)) - mcl |= TXC_BW_40; - - /* set AMIC bit if using hardware TKIP MIC */ - if (hwtkmic) - mcl |= TXC_AMIC; - - txh->MacTxControlLow = htol16(mcl); - - /* MacTxControlHigh */ - mch = 0; - - /* Set fallback rate preamble type */ - if ((preamble_type[1] == WLC_SHORT_PREAMBLE) || - (preamble_type[1] == WLC_GF_PREAMBLE)) { - ASSERT((preamble_type[1] == WLC_GF_PREAMBLE) || - (!IS_MCS(rspec[1]))); - if (RSPEC2RATE(rspec[1]) != WLC_RATE_1M) - mch |= TXC_PREAMBLE_DATA_FB_SHORT; - } - - /* MacFrameControl */ - bcopy((char *)&h->frame_control, (char *)&txh->MacFrameControl, - sizeof(u16)); - txh->TxFesTimeNormal = htol16(0); - - txh->TxFesTimeFallback = htol16(0); - - /* TxFrameRA */ - bcopy((char *)&h->addr1, (char *)&txh->TxFrameRA, ETH_ALEN); - - /* TxFrameID */ - txh->TxFrameID = htol16(frameid); - - /* TxStatus, Note the case of recreating the first frag of a suppressed frame - * then we may need to reset the retry cnt's via the status reg - */ - txh->TxStatus = htol16(status); - - if (D11REV_GE(wlc->pub->corerev, 16)) { - /* extra fields for ucode AMPDU aggregation, the new fields are added to - * the END of previous structure so that it's compatible in driver. - * In old rev ucode, these fields should be ignored - */ - txh->MaxNMpdus = htol16(0); - txh->MaxABytes_MRT = htol16(0); - txh->MaxABytes_FBR = htol16(0); - txh->MinMBytes = htol16(0); - } - - /* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration, furnish d11txh_t */ - /* RTS PLCP header and RTS frame */ - if (use_rts || use_cts) { - if (use_rts && use_cts) - use_cts = false; - - for (k = 0; k < 2; k++) { - rts_rspec[k] = wlc_rspec_to_rts_rspec(wlc, rspec[k], - false, - mimo_ctlchbw); - } - - if (!IS_OFDM(rts_rspec[0]) && - !((RSPEC2RATE(rts_rspec[0]) == WLC_RATE_1M) || - (wlc->PLCPHdr_override == WLC_PLCP_LONG))) { - rts_preamble_type[0] = WLC_SHORT_PREAMBLE; - mch |= TXC_PREAMBLE_RTS_MAIN_SHORT; - } - - if (!IS_OFDM(rts_rspec[1]) && - !((RSPEC2RATE(rts_rspec[1]) == WLC_RATE_1M) || - (wlc->PLCPHdr_override == WLC_PLCP_LONG))) { - rts_preamble_type[1] = WLC_SHORT_PREAMBLE; - mch |= TXC_PREAMBLE_RTS_FB_SHORT; - } - - /* RTS/CTS additions to MacTxControlLow */ - if (use_cts) { - txh->MacTxControlLow |= htol16(TXC_SENDCTS); - } else { - txh->MacTxControlLow |= htol16(TXC_SENDRTS); - txh->MacTxControlLow |= htol16(TXC_LONGFRAME); - } - - /* RTS PLCP header */ - ASSERT(IS_ALIGNED((unsigned long)txh->RTSPhyHeader, sizeof(u16))); - rts_plcp = txh->RTSPhyHeader; - if (use_cts) - rts_phylen = DOT11_CTS_LEN + FCS_LEN; - else - rts_phylen = DOT11_RTS_LEN + FCS_LEN; - - wlc_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp); - - /* fallback rate version of RTS PLCP header */ - wlc_compute_plcp(wlc, rts_rspec[1], rts_phylen, - rts_plcp_fallback); - bcopy(rts_plcp_fallback, (char *)&txh->RTSPLCPFallback, - sizeof(txh->RTSPLCPFallback)); - - /* RTS frame fields... */ - rts = (struct ieee80211_rts *)&txh->rts_frame; - - durid = wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec[0], - rspec[0], rts_preamble_type[0], - preamble_type[0], phylen, false); - rts->duration = htol16(durid); - /* fallback rate version of RTS DUR field */ - durid = wlc_compute_rtscts_dur(wlc, use_cts, - rts_rspec[1], rspec[1], - rts_preamble_type[1], - preamble_type[1], phylen, false); - txh->RTSDurFallback = htol16(durid); - - if (use_cts) { - rts->frame_control = htol16(FC_CTS); - bcopy((char *)&h->addr2, (char *)&rts->ra, ETH_ALEN); - } else { - rts->frame_control = htol16((u16) FC_RTS); - bcopy((char *)&h->addr1, (char *)&rts->ra, - 2 * ETH_ALEN); - } - - /* mainrate - * low 8 bits: main frag rate/mcs, - * high 8 bits: rts/cts rate/mcs - */ - mainrates |= (IS_OFDM(rts_rspec[0]) ? - D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) rts_plcp) : - rts_plcp[0]) << 8; - } else { - memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN); - memset((char *)&txh->rts_frame, 0, - sizeof(struct ieee80211_rts)); - memset((char *)txh->RTSPLCPFallback, 0, - sizeof(txh->RTSPLCPFallback)); - txh->RTSDurFallback = 0; - } - -#ifdef SUPPORT_40MHZ - /* add null delimiter count */ - if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && IS_MCS(rspec)) { - txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = - wlc_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen); - } -#endif - - /* Now that RTS/RTS FB preamble types are updated, write the final value */ - txh->MacTxControlHigh = htol16(mch); - - /* MainRates (both the rts and frag plcp rates have been calculated now) */ - txh->MainRates = htol16(mainrates); - - /* XtraFrameTypes */ - xfts = FRAMETYPE(rspec[1], wlc->mimoft); - xfts |= (FRAMETYPE(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT); - xfts |= (FRAMETYPE(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT); - xfts |= - CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC) << XFTS_CHANNEL_SHIFT; - txh->XtraFrameTypes = htol16(xfts); - - /* PhyTxControlWord */ - phyctl = FRAMETYPE(rspec[0], wlc->mimoft); - if ((preamble_type[0] == WLC_SHORT_PREAMBLE) || - (preamble_type[0] == WLC_GF_PREAMBLE)) { - ASSERT((preamble_type[0] == WLC_GF_PREAMBLE) - || !IS_MCS(rspec[0])); - if (RSPEC2RATE(rspec[0]) != WLC_RATE_1M) - phyctl |= PHY_TXC_SHORT_HDR; - WLCNTINCR(wlc->pub->_cnt->txprshort); - } - - /* phytxant is properly bit shifted */ - phyctl |= wlc_stf_d11hdrs_phyctl_txant(wlc, rspec[0]); - txh->PhyTxControlWord = htol16(phyctl); - - /* PhyTxControlWord_1 */ - if (WLC_PHY_11N_CAP(wlc->band)) { - u16 phyctl1 = 0; - - phyctl1 = wlc_phytxctl1_calc(wlc, rspec[0]); - txh->PhyTxControlWord_1 = htol16(phyctl1); - phyctl1 = wlc_phytxctl1_calc(wlc, rspec[1]); - txh->PhyTxControlWord_1_Fbr = htol16(phyctl1); - - if (use_rts || use_cts) { - phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[0]); - txh->PhyTxControlWord_1_Rts = htol16(phyctl1); - phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[1]); - txh->PhyTxControlWord_1_FbrRts = htol16(phyctl1); - } - - /* - * For mcs frames, if mixedmode(overloaded with long preamble) is going to be set, - * fill in non-zero MModeLen and/or MModeFbrLen - * it will be unnecessary if they are separated - */ - if (IS_MCS(rspec[0]) && (preamble_type[0] == WLC_MM_PREAMBLE)) { - u16 mmodelen = - wlc_calc_lsig_len(wlc, rspec[0], phylen); - txh->MModeLen = htol16(mmodelen); - } - - if (IS_MCS(rspec[1]) && (preamble_type[1] == WLC_MM_PREAMBLE)) { - u16 mmodefbrlen = - wlc_calc_lsig_len(wlc, rspec[1], phylen); - txh->MModeFbrLen = htol16(mmodefbrlen); - } - } - - if (IS_MCS(rspec[0])) - ASSERT(IS_MCS(rspec[1])); - - ASSERT(!IS_MCS(rspec[0]) || - ((preamble_type[0] == WLC_MM_PREAMBLE) == (txh->MModeLen != 0))); - ASSERT(!IS_MCS(rspec[1]) || - ((preamble_type[1] == WLC_MM_PREAMBLE) == - (txh->MModeFbrLen != 0))); - - ac = wme_fifo2ac[queue]; - if (SCB_WME(scb) && qos && wlc->edcf_txop[ac]) { - uint frag_dur, dur, dur_fallback; - - ASSERT(!is_multicast_ether_addr(h->addr1)); - - /* WME: Update TXOP threshold */ - if ((!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) && (frag == 0)) { - frag_dur = - wlc_calc_frame_time(wlc, rspec[0], preamble_type[0], - phylen); - - if (rts) { - /* 1 RTS or CTS-to-self frame */ - dur = - wlc_calc_cts_time(wlc, rts_rspec[0], - rts_preamble_type[0]); - dur_fallback = - wlc_calc_cts_time(wlc, rts_rspec[1], - rts_preamble_type[1]); - /* (SIFS + CTS) + SIFS + frame + SIFS + ACK */ - dur += ltoh16(rts->duration); - dur_fallback += ltoh16(txh->RTSDurFallback); - } else if (use_rifs) { - dur = frag_dur; - dur_fallback = 0; - } else { - /* frame + SIFS + ACK */ - dur = frag_dur; - dur += - wlc_compute_frame_dur(wlc, rspec[0], - preamble_type[0], 0); - - dur_fallback = - wlc_calc_frame_time(wlc, rspec[1], - preamble_type[1], - phylen); - dur_fallback += - wlc_compute_frame_dur(wlc, rspec[1], - preamble_type[1], 0); - } - /* NEED to set TxFesTimeNormal (hard) */ - txh->TxFesTimeNormal = htol16((u16) dur); - /* NEED to set fallback rate version of TxFesTimeNormal (hard) */ - txh->TxFesTimeFallback = htol16((u16) dur_fallback); - - /* update txop byte threshold (txop minus intraframe overhead) */ - if (wlc->edcf_txop[ac] >= (dur - frag_dur)) { - { - uint newfragthresh; - - newfragthresh = - wlc_calc_frame_len(wlc, rspec[0], - preamble_type[0], - (wlc-> - edcf_txop[ac] - - (dur - - frag_dur))); - /* range bound the fragthreshold */ - if (newfragthresh < DOT11_MIN_FRAG_LEN) - newfragthresh = - DOT11_MIN_FRAG_LEN; - else if (newfragthresh > - wlc->usr_fragthresh) - newfragthresh = - wlc->usr_fragthresh; - /* update the fragthresh and do txc update */ - if (wlc->fragthresh[queue] != - (u16) newfragthresh) { - wlc->fragthresh[queue] = - (u16) newfragthresh; - } - } - } else - WL_ERROR("wl%d: %s txop invalid for rate %d\n", - wlc->pub->unit, fifo_names[queue], - RSPEC2RATE(rspec[0])); - - if (dur > wlc->edcf_txop[ac]) - WL_ERROR("wl%d: %s: %s txop exceeded phylen %d/%d dur %d/%d\n", - wlc->pub->unit, __func__, - fifo_names[queue], - phylen, wlc->fragthresh[queue], - dur, wlc->edcf_txop[ac]); - } - } - - return 0; -} - -void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs) -{ - wlc_bsscfg_t *cfg = wlc->cfg; - - WLCNTINCR(wlc->pub->_cnt->tbtt); - - if (BSSCFG_STA(cfg)) { - /* run watchdog here if the watchdog timer is not armed */ - if (WLC_WATCHDOG_TBTT(wlc)) { - u32 cur, delta; - if (wlc->WDarmed) { - wl_del_timer(wlc->wl, wlc->wdtimer); - wlc->WDarmed = false; - } - - cur = OSL_SYSUPTIME(); - delta = cur > wlc->WDlast ? cur - wlc->WDlast : - (u32) ~0 - wlc->WDlast + cur + 1; - if (delta >= TIMER_INTERVAL_WATCHDOG) { - wlc_watchdog((void *)wlc); - wlc->WDlast = cur; - } - - wl_add_timer(wlc->wl, wlc->wdtimer, - wlc_watchdog_backup_bi(wlc), true); - wlc->WDarmed = true; - } - } - - if (!cfg->BSS) { - /* DirFrmQ is now valid...defer setting until end of ATIM window */ - wlc->qvalid |= MCMD_DIRFRMQVAL; - } -} - -/* GP timer is a freerunning 32 bit counter, decrements at 1 us rate */ -void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us) -{ - ASSERT(wlc->pub->corerev >= 3); /* no gptimer in earlier revs */ - W_REG(wlc->osh, &wlc->regs->gptimer, us); -} - -void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc) -{ - ASSERT(wlc->pub->corerev >= 3); - W_REG(wlc->osh, &wlc->regs->gptimer, 0); -} - -static void wlc_hwtimer_gptimer_cb(struct wlc_info *wlc) -{ - /* when interrupt is generated, the counter is loaded with last value - * written and continue to decrement. So it has to be cleaned first - */ - W_REG(wlc->osh, &wlc->regs->gptimer, 0); -} - -/* - * This fn has all the high level dpc processing from wlc_dpc. - * POLICY: no macinstatus change, no bounding loop. - * All dpc bounding should be handled in BMAC dpc, like txstatus and rxint - */ -void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus) -{ - d11regs_t *regs = wlc->regs; -#ifdef BCMDBG - char flagstr[128]; - static const bcm_bit_desc_t int_flags[] = { - {MI_MACSSPNDD, "MACSSPNDD"}, - {MI_BCNTPL, "BCNTPL"}, - {MI_TBTT, "TBTT"}, - {MI_BCNSUCCESS, "BCNSUCCESS"}, - {MI_BCNCANCLD, "BCNCANCLD"}, - {MI_ATIMWINEND, "ATIMWINEND"}, - {MI_PMQ, "PMQ"}, - {MI_NSPECGEN_0, "NSPECGEN_0"}, - {MI_NSPECGEN_1, "NSPECGEN_1"}, - {MI_MACTXERR, "MACTXERR"}, - {MI_NSPECGEN_3, "NSPECGEN_3"}, - {MI_PHYTXERR, "PHYTXERR"}, - {MI_PME, "PME"}, - {MI_GP0, "GP0"}, - {MI_GP1, "GP1"}, - {MI_DMAINT, "DMAINT"}, - {MI_TXSTOP, "TXSTOP"}, - {MI_CCA, "CCA"}, - {MI_BG_NOISE, "BG_NOISE"}, - {MI_DTIM_TBTT, "DTIM_TBTT"}, - {MI_PRQ, "PRQ"}, - {MI_PWRUP, "PWRUP"}, - {MI_RFDISABLE, "RFDISABLE"}, - {MI_TFS, "TFS"}, - {MI_PHYCHANGED, "PHYCHANGED"}, - {MI_TO, "TO"}, - {0, NULL} - }; - - if (macintstatus & ~(MI_TBTT | MI_TXSTOP)) { - bcm_format_flags(int_flags, macintstatus, flagstr, - sizeof(flagstr)); - WL_TRACE("wl%d: macintstatus 0x%x %s\n", - wlc->pub->unit, macintstatus, flagstr); - } -#endif /* BCMDBG */ - - if (macintstatus & MI_PRQ) { - /* Process probe request FIFO */ - ASSERT(0 && "PRQ Interrupt in non-MBSS"); - } - - /* TBTT indication */ - /* ucode only gives either TBTT or DTIM_TBTT, not both */ - if (macintstatus & (MI_TBTT | MI_DTIM_TBTT)) - wlc_tbtt(wlc, regs); - - if (macintstatus & MI_GP0) { - WL_ERROR("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", - wlc->pub->unit, wlc->pub->now); - - printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", - __func__, wlc->pub->sih->chip, - wlc->pub->sih->chiprev); - - WLCNTINCR(wlc->pub->_cnt->psmwds); - - /* big hammer */ - wl_init(wlc->wl); - } - - /* gptimer timeout */ - if (macintstatus & MI_TO) { - wlc_hwtimer_gptimer_cb(wlc); - } - - if (macintstatus & MI_RFDISABLE) { - WL_ERROR("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n", - wlc->pub->unit, - R_REG(wlc->osh, ®s->phydebug) & PDBG_RFD); - /* delay the cleanup to wl_down in IBSS case */ - if ((R_REG(wlc->osh, ®s->phydebug) & PDBG_RFD)) { - int idx; - wlc_bsscfg_t *bsscfg; - FOREACH_BSS(wlc, idx, bsscfg) { - if (!BSSCFG_STA(bsscfg) || !bsscfg->enable - || !bsscfg->BSS) - continue; - WL_ERROR("wl%d: wlc_dpc: rfdisable -> wlc_bsscfg_disable()\n", - wlc->pub->unit); - } - } - } - - /* send any enq'd tx packets. Just makes sure to jump start tx */ - if (!pktq_empty(&wlc->active_queue->q)) - wlc_send_q(wlc, wlc->active_queue); - - ASSERT(wlc_ps_check(wlc)); -} - -static void *wlc_15420war(struct wlc_info *wlc, uint queue) -{ - struct hnddma_pub *di; - void *p; - - ASSERT(queue < NFIFO); - - if ((D11REV_IS(wlc->pub->corerev, 4)) - || (D11REV_GT(wlc->pub->corerev, 6))) - return NULL; - - di = wlc->hw->di[queue]; - ASSERT(di != NULL); - - /* get next packet, ignoring XmtStatus.Curr */ - p = dma_getnexttxp(di, HNDDMA_RANGE_ALL); - - /* sw block tx dma */ - dma_txblock(di); - - /* if tx ring is now empty, reset and re-init the tx dma channel */ - if (dma_txactive(wlc->hw->di[queue]) == 0) { - WLCNTINCR(wlc->pub->_cnt->txdmawar); - if (!dma_txreset(di)) - WL_ERROR("wl%d: %s: dma_txreset[%d]: cannot stop dma\n", - wlc->pub->unit, __func__, queue); - dma_txinit(di); - } - return p; -} - -static void wlc_war16165(struct wlc_info *wlc, bool tx) -{ - if (tx) { - /* the post-increment is used in STAY_AWAKE macro */ - if (wlc->txpend16165war++ == 0) - wlc_set_ps_ctrl(wlc); - } else { - wlc->txpend16165war--; - if (wlc->txpend16165war == 0) - wlc_set_ps_ctrl(wlc); - } -} - -/* process an individual tx_status_t */ -/* WLC_HIGH_API */ -bool BCMFASTPATH -wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) -{ - struct sk_buff *p; - uint queue; - d11txh_t *txh; - struct scb *scb = NULL; - bool free_pdu; - struct osl_info *osh; - int tx_rts, tx_frame_count, tx_rts_count; - uint totlen, supr_status; - bool lastframe; - struct ieee80211_hdr *h; - u16 fc; - u16 mcl; - struct ieee80211_tx_info *tx_info; - struct ieee80211_tx_rate *txrate; - int i; - - (void)(frm_tx2); /* Compiler reference to avoid unused variable warning */ - - /* discard intermediate indications for ucode with one legitimate case: - * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent - * tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts - * transmission count) - */ - if (!(txs->status & TX_STATUS_AMPDU) - && (txs->status & TX_STATUS_INTERMEDIATE)) { - WLCNTADD(wlc->pub->_cnt->txnoack, - ((txs-> - status & TX_STATUS_FRM_RTX_MASK) >> - TX_STATUS_FRM_RTX_SHIFT)); - WL_ERROR("%s: INTERMEDIATE but not AMPDU\n", __func__); - return false; - } - - osh = wlc->osh; - queue = txs->frameid & TXFID_QUEUE_MASK; - ASSERT(queue < NFIFO); - if (queue >= NFIFO) { - p = NULL; - goto fatal; - } - - p = GETNEXTTXP(wlc, queue); - if (WLC_WAR16165(wlc)) - wlc_war16165(wlc, false); - if (p == NULL) - p = wlc_15420war(wlc, queue); - ASSERT(p != NULL); - if (p == NULL) - goto fatal; - - txh = (d11txh_t *) (p->data); - mcl = ltoh16(txh->MacTxControlLow); - - if (txs->phyerr) { - WL_ERROR("phyerr 0x%x, rate 0x%x\n", - txs->phyerr, txh->MainRates); - wlc_print_txdesc(txh); - wlc_print_txstatus(txs); - } - - ASSERT(txs->frameid == htol16(txh->TxFrameID)); - if (txs->frameid != htol16(txh->TxFrameID)) - goto fatal; - - tx_info = IEEE80211_SKB_CB(p); - h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); - fc = ltoh16(h->frame_control); - - scb = (struct scb *)tx_info->control.sta->drv_priv; - - if (N_ENAB(wlc->pub)) { - u8 *plcp = (u8 *) (txh + 1); - if (PLCP3_ISSGI(plcp[3])) - WLCNTINCR(wlc->pub->_cnt->txmpdu_sgi); - if (PLCP3_ISSTBC(plcp[3])) - WLCNTINCR(wlc->pub->_cnt->txmpdu_stbc); - } - - if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { - ASSERT((mcl & TXC_AMPDU_MASK) != TXC_AMPDU_NONE); - wlc_ampdu_dotxstatus(wlc->ampdu, scb, p, txs); - return false; - } - - supr_status = txs->status & TX_STATUS_SUPR_MASK; - if (supr_status == TX_STATUS_SUPR_BADCH) - WL_NONE("%s: Pkt tx suppressed, possibly channel %d\n", - __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec)); - - tx_rts = htol16(txh->MacTxControlLow) & TXC_SENDRTS; - tx_frame_count = - (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT; - tx_rts_count = - (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT; - - lastframe = (fc & IEEE80211_FCTL_MOREFRAGS) == 0; - - if (!lastframe) { - WL_ERROR("Not last frame!\n"); - } else { - u16 sfbl, lfbl; - ieee80211_tx_info_clear_status(tx_info); - if (queue < AC_COUNT) { - sfbl = WLC_WME_RETRY_SFB_GET(wlc, wme_fifo2ac[queue]); - lfbl = WLC_WME_RETRY_LFB_GET(wlc, wme_fifo2ac[queue]); - } else { - sfbl = wlc->SFBL; - lfbl = wlc->LFBL; - } - - txrate = tx_info->status.rates; - /* FIXME: this should use a combination of sfbl, lfbl depending on frame length and RTS setting */ - if ((tx_frame_count > sfbl) && (txrate[1].idx >= 0)) { - /* rate selection requested a fallback rate and we used it */ - txrate->count = lfbl; - txrate[1].count = tx_frame_count - lfbl; - } else { - /* rate selection did not request fallback rate, or we didn't need it */ - txrate->count = tx_frame_count; - /* rc80211_minstrel.c:minstrel_tx_status() expects unused rates to be marked with idx = -1 */ - txrate[1].idx = -1; - txrate[1].count = 0; - } - - /* clear the rest of the rates */ - for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) { - txrate[i].idx = -1; - txrate[i].count = 0; - } - - if (txs->status & TX_STATUS_ACK_RCV) - tx_info->flags |= IEEE80211_TX_STAT_ACK; - } - - totlen = pkttotlen(osh, p); - free_pdu = true; - - wlc_txfifo_complete(wlc, queue, 1); - - if (lastframe) { - p->next = NULL; - p->prev = NULL; - wlc->txretried = 0; - /* remove PLCP & Broadcom tx descriptor header */ - skb_pull(p, D11_PHY_HDR_LEN); - skb_pull(p, D11_TXH_LEN); - ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); - WLCNTINCR(wlc->pub->_cnt->ieee_tx_status); - } else { - WL_ERROR("%s: Not last frame => not calling tx_status\n", - __func__); - } - - return false; - - fatal: - ASSERT(0); - if (p) - pkt_buf_free_skb(osh, p, true); - - return true; - -} - -void BCMFASTPATH -wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend) -{ - TXPKTPENDDEC(wlc, fifo, txpktpend); - WL_TRACE("wlc_txfifo_complete, pktpend dec %d to %d\n", - txpktpend, TXPKTPENDGET(wlc, fifo)); - - /* There is more room; mark precedences related to this FIFO sendable */ - WLC_TX_FIFO_ENAB(wlc, fifo); - ASSERT(TXPKTPENDGET(wlc, fifo) >= 0); - - if (!TXPKTPENDTOT(wlc)) { - if (wlc->block_datafifo & DATA_BLOCK_TX_SUPR) - wlc_bsscfg_tx_check(wlc); - } - - /* Clear MHF2_TXBCMC_NOW flag if BCMC fifo has drained */ - if (AP_ENAB(wlc->pub) && - wlc->bcmcfifo_drain && !TXPKTPENDGET(wlc, TX_BCMC_FIFO)) { - wlc->bcmcfifo_drain = false; - wlc_mhf(wlc, MHF2, MHF2_TXBCMC_NOW, 0, WLC_BAND_AUTO); - } - - /* figure out which bsscfg is being worked on... */ -} - -/* Given the beacon interval in kus, and a 64 bit TSF in us, - * return the offset (in us) of the TSF from the last TBTT - */ -u32 wlc_calc_tbtt_offset(u32 bp, u32 tsf_h, u32 tsf_l) -{ - u32 k, btklo, btkhi, offset; - - /* TBTT is always an even multiple of the beacon_interval, - * so the TBTT less than or equal to the beacon timestamp is - * the beacon timestamp minus the beacon timestamp modulo - * the beacon interval. - * - * TBTT = BT - (BT % BIu) - * = (BTk - (BTk % BP)) * 2^10 - * - * BT = beacon timestamp (usec, 64bits) - * BTk = beacon timestamp (Kusec, 54bits) - * BP = beacon interval (Kusec, 16bits) - * BIu = BP * 2^10 = beacon interval (usec, 26bits) - * - * To keep the calculations in u32s, the modulo operation - * on the high part of BT needs to be done in parts using the - * relations: - * X*Y mod Z = ((X mod Z) * (Y mod Z)) mod Z - * and - * (X + Y) mod Z = ((X mod Z) + (Y mod Z)) mod Z - * - * So, if BTk[n] = u16 n [0,3] of BTk. - * BTk % BP = SUM((BTk[n] * 2^16n) % BP , 0<=n<4) % BP - * and the SUM term can be broken down: - * (BTk[n] * 2^16n) % BP - * (BTk[n] * (2^16n % BP)) % BP - * - * Create a set of power of 2 mod BP constants: - * K[n] = 2^(16n) % BP - * = (K[n-1] * 2^16) % BP - * K[2] = 2^32 % BP = ((2^16 % BP) * 2^16) % BP - * - * BTk % BP = BTk[0-1] % BP + - * (BTk[2] * K[2]) % BP + - * (BTk[3] * K[3]) % BP - * - * Since K[n] < 2^16 and BTk[n] is < 2^16, then BTk[n] * K[n] < 2^32 - */ - - /* BTk = BT >> 10, btklo = BTk[0-3], bkthi = BTk[4-6] */ - btklo = (tsf_h << 22) | (tsf_l >> 10); - btkhi = tsf_h >> 10; - - /* offset = BTk % BP */ - offset = btklo % bp; - - /* K[2] = ((2^16 % BP) * 2^16) % BP */ - k = (u32) (1 << 16) % bp; - k = (u32) (k * 1 << 16) % (u32) bp; - - /* offset += (BTk[2] * K[2]) % BP */ - offset += ((btkhi & 0xffff) * k) % bp; - - /* BTk[3] */ - btkhi = btkhi >> 16; - - /* k[3] = (K[2] * 2^16) % BP */ - k = (k << 16) % bp; - - /* offset += (BTk[3] * K[3]) % BP */ - offset += ((btkhi & 0xffff) * k) % bp; - - offset = offset % bp; - - /* convert offset from kus to us by shifting up 10 bits and - * add in the low 10 bits of tsf that we ignored - */ - offset = (offset << 10) + (tsf_l & 0x3FF); - - return offset; -} - -/* Update beacon listen interval in shared memory */ -void wlc_bcn_li_upd(struct wlc_info *wlc) -{ - if (AP_ENAB(wlc->pub)) - return; - - /* wake up every DTIM is the default */ - if (wlc->bcn_li_dtim == 1) - wlc_write_shm(wlc, M_BCN_LI, 0); - else - wlc_write_shm(wlc, M_BCN_LI, - (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn); -} - -static void -prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, - struct ieee80211_rx_status *rx_status) -{ - u32 tsf_l, tsf_h; - wlc_d11rxhdr_t *wlc_rxh = (wlc_d11rxhdr_t *) rxh; - int preamble; - int channel; - ratespec_t rspec; - unsigned char *plcp; - - wlc_read_tsf(wlc, &tsf_l, &tsf_h); /* mactime */ - rx_status->mactime = tsf_h; - rx_status->mactime <<= 32; - rx_status->mactime |= tsf_l; - rx_status->flag |= RX_FLAG_TSFT; - - channel = WLC_CHAN_CHANNEL(rxh->RxChan); - - /* XXX Channel/badn needs to be filtered against whether we are single/dual band card */ - if (channel > 14) { - rx_status->band = IEEE80211_BAND_5GHZ; - rx_status->freq = ieee80211_ofdm_chan_to_freq( - WF_CHAN_FACTOR_5_G/2, channel); - - } else { - rx_status->band = IEEE80211_BAND_2GHZ; - rx_status->freq = ieee80211_dsss_chan_to_freq(channel); - } - - rx_status->signal = wlc_rxh->rssi; /* signal */ - - /* noise */ - /* qual */ - rx_status->antenna = (rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; /* ant */ - - plcp = p->data; - - rspec = wlc_compute_rspec(rxh, plcp); - if (IS_MCS(rspec)) { - rx_status->rate_idx = rspec & RSPEC_RATE_MASK; - rx_status->flag |= RX_FLAG_HT; - if (RSPEC_IS40MHZ(rspec)) - rx_status->flag |= RX_FLAG_40MHZ; - } else { - switch (RSPEC2RATE(rspec)) { - case WLC_RATE_1M: - rx_status->rate_idx = 0; - break; - case WLC_RATE_2M: - rx_status->rate_idx = 1; - break; - case WLC_RATE_5M5: - rx_status->rate_idx = 2; - break; - case WLC_RATE_11M: - rx_status->rate_idx = 3; - break; - case WLC_RATE_6M: - rx_status->rate_idx = 4; - break; - case WLC_RATE_9M: - rx_status->rate_idx = 5; - break; - case WLC_RATE_12M: - rx_status->rate_idx = 6; - break; - case WLC_RATE_18M: - rx_status->rate_idx = 7; - break; - case WLC_RATE_24M: - rx_status->rate_idx = 8; - break; - case WLC_RATE_36M: - rx_status->rate_idx = 9; - break; - case WLC_RATE_48M: - rx_status->rate_idx = 10; - break; - case WLC_RATE_54M: - rx_status->rate_idx = 11; - break; - default: - WL_ERROR("%s: Unknown rate\n", __func__); - } - - /* Determine short preamble and rate_idx */ - preamble = 0; - if (IS_CCK(rspec)) { - if (rxh->PhyRxStatus_0 & PRXS0_SHORTH) - WL_ERROR("Short CCK\n"); - rx_status->flag |= RX_FLAG_SHORTPRE; - } else if (IS_OFDM(rspec)) { - rx_status->flag |= RX_FLAG_SHORTPRE; - } else { - WL_ERROR("%s: Unknown modulation\n", __func__); - } - } - - if (PLCP3_ISSGI(plcp[3])) - rx_status->flag |= RX_FLAG_SHORT_GI; - - if (rxh->RxStatus1 & RXS_DECERR) { - rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC; - WL_ERROR("%s: RX_FLAG_FAILED_PLCP_CRC\n", __func__); - } - if (rxh->RxStatus1 & RXS_FCSERR) { - rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; - WL_ERROR("%s: RX_FLAG_FAILED_FCS_CRC\n", __func__); - } -} - -static void -wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, d11rxhdr_t *rxh, - struct sk_buff *p) -{ - int len_mpdu; - struct ieee80211_rx_status rx_status; -#if defined(BCMDBG) - struct sk_buff *skb = p; -#endif /* BCMDBG */ - /* Todo: - * Cache plcp for first MPDU of AMPD and use chacched version for INTERMEDIATE. - * Test for INTERMEDIATE like so: - * if (!(plcp[0] | plcp[1] | plcp[2])) - */ - - memset(&rx_status, 0, sizeof(rx_status)); - prep_mac80211_status(wlc, rxh, p, &rx_status); - - /* mac header+body length, exclude CRC and plcp header */ - len_mpdu = p->len - D11_PHY_HDR_LEN - FCS_LEN; - skb_pull(p, D11_PHY_HDR_LEN); - __skb_trim(p, len_mpdu); - - ASSERT(!(p->next)); - ASSERT(!(p->prev)); - - ASSERT(IS_ALIGNED((unsigned long)skb->data, 2)); - - memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status)); - ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p); - - WLCNTINCR(wlc->pub->_cnt->ieee_rx); - osh->pktalloced--; - return; -} - -void wlc_bss_list_free(struct wlc_info *wlc, wlc_bss_list_t *bss_list) -{ - uint index; - wlc_bss_info_t *bi; - - if (!bss_list) { - WL_ERROR("%s: Attempting to free NULL list\n", __func__); - return; - } - /* inspect all BSS descriptor */ - for (index = 0; index < bss_list->count; index++) { - bi = bss_list->ptrs[index]; - if (bi) { - kfree(bi); - bss_list->ptrs[index] = NULL; - } - } - bss_list->count = 0; -} - -/* Process received frames */ -/* - * Return true if more frames need to be processed. false otherwise. - * Param 'bound' indicates max. # frames to process before break out. - */ -/* WLC_HIGH_API */ -void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) -{ - d11rxhdr_t *rxh; - struct ieee80211_hdr *h; - struct osl_info *osh; - u16 fc; - uint len; - bool is_amsdu; - - WL_TRACE("wl%d: wlc_recv\n", wlc->pub->unit); - - osh = wlc->osh; - - /* frame starts with rxhdr */ - rxh = (d11rxhdr_t *) (p->data); - - /* strip off rxhdr */ - skb_pull(p, wlc->hwrxoff); - - /* fixup rx header endianness */ - ltoh16_buf((void *)rxh, sizeof(d11rxhdr_t)); - - /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ - if (rxh->RxStatus1 & RXS_PBPRES) { - if (p->len < 2) { - WLCNTINCR(wlc->pub->_cnt->rxrunt); - WL_ERROR("wl%d: wlc_recv: rcvd runt of len %d\n", - wlc->pub->unit, p->len); - goto toss; - } - skb_pull(p, 2); - } - - h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN); - len = p->len; - - if (rxh->RxStatus1 & RXS_FCSERR) { - if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) { - WL_ERROR("FCSERR while scanning******* - tossing\n"); - goto toss; - } else { - WL_ERROR("RCSERR!!!\n"); - goto toss; - } - } - - /* check received pkt has at least frame control field */ - if (len >= D11_PHY_HDR_LEN + sizeof(h->frame_control)) { - fc = ltoh16(h->frame_control); - } else { - WLCNTINCR(wlc->pub->_cnt->rxrunt); - goto toss; - } - - is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK; - - /* explicitly test bad src address to avoid sending bad deauth */ - if (!is_amsdu) { - /* CTS and ACK CTL frames are w/o a2 */ - if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA || - (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { - if ((is_zero_ether_addr(h->addr2) || - is_multicast_ether_addr(h->addr2))) { - WL_ERROR("wl%d: %s: dropping a frame with " - "invalid src mac address, a2: %pM\n", - wlc->pub->unit, __func__, h->addr2); - WLCNTINCR(wlc->pub->_cnt->rxbadsrcmac); - goto toss; - } - WLCNTINCR(wlc->pub->_cnt->rxfrag); - } - } - - /* due to sheer numbers, toss out probe reqs for now */ - if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { - if ((fc & FC_KIND_MASK) == FC_PROBE_REQ) - goto toss; - } - - if (is_amsdu) { - WL_ERROR("%s: is_amsdu causing toss\n", __func__); - goto toss; - } - - wlc_recvctl(wlc, osh, rxh, p); - return; - - toss: - pkt_buf_free_skb(osh, p, false); -} - -/* calculate frame duration for Mixed-mode L-SIG spoofing, return - * number of bytes goes in the length field - * - * Formula given by HT PHY Spec v 1.13 - * len = 3(nsyms + nstream + 3) - 3 - */ -u16 BCMFASTPATH -wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, uint mac_len) -{ - uint nsyms, len = 0, kNdps; - - WL_TRACE("wl%d: wlc_calc_lsig_len: rate %d, len%d\n", - wlc->pub->unit, RSPEC2RATE(ratespec), mac_len); - - if (IS_MCS(ratespec)) { - uint mcs = ratespec & RSPEC_RATE_MASK; - /* MCS_TXS(mcs) returns num tx streams - 1 */ - int tot_streams = (MCS_TXS(mcs) + 1) + RSPEC_STC(ratespec); - - ASSERT(WLC_PHY_11N_CAP(wlc->band)); - /* the payload duration calculation matches that of regular ofdm */ - /* 1000Ndbps = kbps * 4 */ - kNdps = - MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec), - RSPEC_ISSGI(ratespec)) * 4; - - if (RSPEC_STC(ratespec) == 0) - /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ - nsyms = - CEIL((APHY_SERVICE_NBITS + 8 * mac_len + - APHY_TAIL_NBITS) * 1000, kNdps); - else - /* STBC needs to have even number of symbols */ - nsyms = - 2 * - CEIL((APHY_SERVICE_NBITS + 8 * mac_len + - APHY_TAIL_NBITS) * 1000, 2 * kNdps); - - nsyms += (tot_streams + 3); /* (+3) account for HT-SIG(2) and HT-STF(1) */ - /* 3 bytes/symbol @ legacy 6Mbps rate */ - len = (3 * nsyms) - 3; /* (-3) excluding service bits and tail bits */ - } - - return (u16) len; -} - -/* calculate frame duration of a given rate and length, return time in usec unit */ -uint BCMFASTPATH -wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, - uint mac_len) -{ - uint nsyms, dur = 0, Ndps, kNdps; - uint rate = RSPEC2RATE(ratespec); - - if (rate == 0) { - ASSERT(0); - WL_ERROR("wl%d: WAR: using rate of 1 mbps\n", wlc->pub->unit); - rate = WLC_RATE_1M; - } - - WL_TRACE("wl%d: wlc_calc_frame_time: rspec 0x%x, preamble_type %d, len%d\n", - wlc->pub->unit, ratespec, preamble_type, mac_len); - - if (IS_MCS(ratespec)) { - uint mcs = ratespec & RSPEC_RATE_MASK; - int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec); - ASSERT(WLC_PHY_11N_CAP(wlc->band)); - ASSERT(WLC_IS_MIMO_PREAMBLE(preamble_type)); - - dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT); - if (preamble_type == WLC_MM_PREAMBLE) - dur += PREN_MM_EXT; - /* 1000Ndbps = kbps * 4 */ - kNdps = - MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec), - RSPEC_ISSGI(ratespec)) * 4; - - if (RSPEC_STC(ratespec) == 0) - /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ - nsyms = - CEIL((APHY_SERVICE_NBITS + 8 * mac_len + - APHY_TAIL_NBITS) * 1000, kNdps); - else - /* STBC needs to have even number of symbols */ - nsyms = - 2 * - CEIL((APHY_SERVICE_NBITS + 8 * mac_len + - APHY_TAIL_NBITS) * 1000, 2 * kNdps); - - dur += APHY_SYMBOL_TIME * nsyms; - if (BAND_2G(wlc->band->bandtype)) - dur += DOT11_OFDM_SIGNAL_EXTENSION; - } else if (IS_OFDM(rate)) { - dur = APHY_PREAMBLE_TIME; - dur += APHY_SIGNAL_TIME; - /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */ - Ndps = rate * 2; - /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ - nsyms = - CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS), - Ndps); - dur += APHY_SYMBOL_TIME * nsyms; - if (BAND_2G(wlc->band->bandtype)) - dur += DOT11_OFDM_SIGNAL_EXTENSION; - } else { - /* calc # bits * 2 so factor of 2 in rate (1/2 mbps) will divide out */ - mac_len = mac_len * 8 * 2; - /* calc ceiling of bits/rate = microseconds of air time */ - dur = (mac_len + rate - 1) / rate; - if (preamble_type & WLC_SHORT_PREAMBLE) - dur += BPHY_PLCP_SHORT_TIME; - else - dur += BPHY_PLCP_TIME; - } - return dur; -} - -/* The opposite of wlc_calc_frame_time */ -static uint -wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, - uint dur) -{ - uint nsyms, mac_len, Ndps, kNdps; - uint rate = RSPEC2RATE(ratespec); - - WL_TRACE("wl%d: wlc_calc_frame_len: rspec 0x%x, preamble_type %d, dur %d\n", - wlc->pub->unit, ratespec, preamble_type, dur); - - if (IS_MCS(ratespec)) { - uint mcs = ratespec & RSPEC_RATE_MASK; - int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec); - ASSERT(WLC_PHY_11N_CAP(wlc->band)); - dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT); - /* payload calculation matches that of regular ofdm */ - if (BAND_2G(wlc->band->bandtype)) - dur -= DOT11_OFDM_SIGNAL_EXTENSION; - /* kNdbps = kbps * 4 */ - kNdps = - MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec), - RSPEC_ISSGI(ratespec)) * 4; - nsyms = dur / APHY_SYMBOL_TIME; - mac_len = - ((nsyms * kNdps) - - ((APHY_SERVICE_NBITS + APHY_TAIL_NBITS) * 1000)) / 8000; - } else if (IS_OFDM(ratespec)) { - dur -= APHY_PREAMBLE_TIME; - dur -= APHY_SIGNAL_TIME; - /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */ - Ndps = rate * 2; - nsyms = dur / APHY_SYMBOL_TIME; - mac_len = - ((nsyms * Ndps) - - (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8; - } else { - if (preamble_type & WLC_SHORT_PREAMBLE) - dur -= BPHY_PLCP_SHORT_TIME; - else - dur -= BPHY_PLCP_TIME; - mac_len = dur * rate; - /* divide out factor of 2 in rate (1/2 mbps) */ - mac_len = mac_len / 8 / 2; - } - return mac_len; -} - -static uint -wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) -{ - WL_TRACE("wl%d: wlc_calc_ba_time: rspec 0x%x, preamble_type %d\n", - wlc->pub->unit, rspec, preamble_type); - /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than - * or equal to the rate of the immediately previous frame in the FES - */ - rspec = WLC_BASIC_RATE(wlc, rspec); - ASSERT(VALID_RATE_DBG(wlc, rspec)); - - /* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */ - return wlc_calc_frame_time(wlc, rspec, preamble_type, - (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN + - FCS_LEN)); -} - -static uint BCMFASTPATH -wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) -{ - uint dur = 0; - - WL_TRACE("wl%d: wlc_calc_ack_time: rspec 0x%x, preamble_type %d\n", - wlc->pub->unit, rspec, preamble_type); - /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than - * or equal to the rate of the immediately previous frame in the FES - */ - rspec = WLC_BASIC_RATE(wlc, rspec); - ASSERT(VALID_RATE_DBG(wlc, rspec)); - - /* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */ - dur = - wlc_calc_frame_time(wlc, rspec, preamble_type, - (DOT11_ACK_LEN + FCS_LEN)); - return dur; -} - -static uint -wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) -{ - WL_TRACE("wl%d: wlc_calc_cts_time: ratespec 0x%x, preamble_type %d\n", - wlc->pub->unit, rspec, preamble_type); - return wlc_calc_ack_time(wlc, rspec, preamble_type); -} - -/* derive wlc->band->basic_rate[] table from 'rateset' */ -void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset) -{ - u8 rate; - u8 mandatory; - u8 cck_basic = 0; - u8 ofdm_basic = 0; - u8 *br = wlc->band->basic_rate; - uint i; - - /* incoming rates are in 500kbps units as in 802.11 Supported Rates */ - memset(br, 0, WLC_MAXRATE + 1); - - /* For each basic rate in the rates list, make an entry in the - * best basic lookup. - */ - for (i = 0; i < rateset->count; i++) { - /* only make an entry for a basic rate */ - if (!(rateset->rates[i] & WLC_RATE_FLAG)) - continue; - - /* mask off basic bit */ - rate = (rateset->rates[i] & RATE_MASK); - - if (rate > WLC_MAXRATE) { - WL_ERROR("wlc_rate_lookup_init: invalid rate 0x%X in rate set\n", - rateset->rates[i]); - continue; - } - - br[rate] = rate; - } - - /* The rate lookup table now has non-zero entries for each - * basic rate, equal to the basic rate: br[basicN] = basicN - * - * To look up the best basic rate corresponding to any - * particular rate, code can use the basic_rate table - * like this - * - * basic_rate = wlc->band->basic_rate[tx_rate] - * - * Make sure there is a best basic rate entry for - * every rate by walking up the table from low rates - * to high, filling in holes in the lookup table - */ - - for (i = 0; i < wlc->band->hw_rateset.count; i++) { - rate = wlc->band->hw_rateset.rates[i]; - ASSERT(rate <= WLC_MAXRATE); - - if (br[rate] != 0) { - /* This rate is a basic rate. - * Keep track of the best basic rate so far by - * modulation type. - */ - if (IS_OFDM(rate)) - ofdm_basic = rate; - else - cck_basic = rate; - - continue; - } - - /* This rate is not a basic rate so figure out the - * best basic rate less than this rate and fill in - * the hole in the table - */ - - br[rate] = IS_OFDM(rate) ? ofdm_basic : cck_basic; - - if (br[rate] != 0) - continue; - - if (IS_OFDM(rate)) { - /* In 11g and 11a, the OFDM mandatory rates are 6, 12, and 24 Mbps */ - if (rate >= WLC_RATE_24M) - mandatory = WLC_RATE_24M; - else if (rate >= WLC_RATE_12M) - mandatory = WLC_RATE_12M; - else - mandatory = WLC_RATE_6M; - } else { - /* In 11b, all the CCK rates are mandatory 1 - 11 Mbps */ - mandatory = rate; - } - - br[rate] = mandatory; - } -} - -static void wlc_write_rate_shm(struct wlc_info *wlc, u8 rate, u8 basic_rate) -{ - u8 phy_rate, index; - u8 basic_phy_rate, basic_index; - u16 dir_table, basic_table; - u16 basic_ptr; - - /* Shared memory address for the table we are reading */ - dir_table = IS_OFDM(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B; - - /* Shared memory address for the table we are writing */ - basic_table = IS_OFDM(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B; - - /* - * for a given rate, the LS-nibble of the PLCP SIGNAL field is - * the index into the rate table. - */ - phy_rate = rate_info[rate] & RATE_MASK; - basic_phy_rate = rate_info[basic_rate] & RATE_MASK; - index = phy_rate & 0xf; - basic_index = basic_phy_rate & 0xf; - - /* Find the SHM pointer to the ACK rate entry by looking in the - * Direct-map Table - */ - basic_ptr = wlc_read_shm(wlc, (dir_table + basic_index * 2)); - - /* Update the SHM BSS-basic-rate-set mapping table with the pointer - * to the correct basic rate for the given incoming rate - */ - wlc_write_shm(wlc, (basic_table + index * 2), basic_ptr); -} - -static const wlc_rateset_t *wlc_rateset_get_hwrs(struct wlc_info *wlc) -{ - const wlc_rateset_t *rs_dflt; - - if (WLC_PHY_11N_CAP(wlc->band)) { - if (BAND_5G(wlc->band->bandtype)) - rs_dflt = &ofdm_mimo_rates; - else - rs_dflt = &cck_ofdm_mimo_rates; - } else if (wlc->band->gmode) - rs_dflt = &cck_ofdm_rates; - else - rs_dflt = &cck_rates; - - return rs_dflt; -} - -void wlc_set_ratetable(struct wlc_info *wlc) -{ - const wlc_rateset_t *rs_dflt; - wlc_rateset_t rs; - u8 rate, basic_rate; - uint i; - - rs_dflt = wlc_rateset_get_hwrs(wlc); - ASSERT(rs_dflt != NULL); - - wlc_rateset_copy(rs_dflt, &rs); - wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams); - - /* walk the phy rate table and update SHM basic rate lookup table */ - for (i = 0; i < rs.count; i++) { - rate = rs.rates[i] & RATE_MASK; - - /* for a given rate WLC_BASIC_RATE returns the rate at - * which a response ACK/CTS should be sent. - */ - basic_rate = WLC_BASIC_RATE(wlc, rate); - if (basic_rate == 0) { - /* This should only happen if we are using a - * restricted rateset. - */ - basic_rate = rs.rates[0] & RATE_MASK; - } - - wlc_write_rate_shm(wlc, rate, basic_rate); - } -} - -/* - * Return true if the specified rate is supported by the specified band. - * WLC_BAND_AUTO indicates the current band. - */ -bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rspec, int band, - bool verbose) -{ - wlc_rateset_t *hw_rateset; - uint i; - - if ((band == WLC_BAND_AUTO) || (band == wlc->band->bandtype)) { - hw_rateset = &wlc->band->hw_rateset; - } else if (NBANDS(wlc) > 1) { - hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset; - } else { - /* other band specified and we are a single band device */ - return false; - } - - /* check if this is a mimo rate */ - if (IS_MCS(rspec)) { - if (!VALID_MCS((rspec & RSPEC_RATE_MASK))) - goto error; - - return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK)); - } - - for (i = 0; i < hw_rateset->count; i++) - if (hw_rateset->rates[i] == RSPEC2RATE(rspec)) - return true; - error: - if (verbose) { - WL_ERROR("wl%d: wlc_valid_rate: rate spec 0x%x not in hw_rateset\n", - wlc->pub->unit, rspec); - } - - return false; -} - -static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap) -{ - uint i; - struct wlcband *band; - - for (i = 0; i < NBANDS(wlc); i++) { - if (IS_SINGLEBAND_5G(wlc->deviceid)) - i = BAND_5G_INDEX; - band = wlc->bandstate[i]; - if (band->bandtype == WLC_BAND_5G) { - if ((bwcap == WLC_N_BW_40ALL) - || (bwcap == WLC_N_BW_20IN2G_40IN5G)) - band->mimo_cap_40 = true; - else - band->mimo_cap_40 = false; - } else { - ASSERT(band->bandtype == WLC_BAND_2G); - if (bwcap == WLC_N_BW_40ALL) - band->mimo_cap_40 = true; - else - band->mimo_cap_40 = false; - } - } - - wlc->mimo_band_bwcap = bwcap; -} - -void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len) -{ - const wlc_rateset_t *rs_dflt; - wlc_rateset_t rs; - u8 rate; - u16 entry_ptr; - u8 plcp[D11_PHY_HDR_LEN]; - u16 dur, sifs; - uint i; - - sifs = SIFS(wlc->band); - - rs_dflt = wlc_rateset_get_hwrs(wlc); - ASSERT(rs_dflt != NULL); - - wlc_rateset_copy(rs_dflt, &rs); - wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams); - - /* walk the phy rate table and update MAC core SHM basic rate table entries */ - for (i = 0; i < rs.count; i++) { - rate = rs.rates[i] & RATE_MASK; - - entry_ptr = wlc_rate_shm_offset(wlc, rate); - - /* Calculate the Probe Response PLCP for the given rate */ - wlc_compute_plcp(wlc, rate, frame_len, plcp); - - /* Calculate the duration of the Probe Response frame plus SIFS for the MAC */ - dur = - (u16) wlc_calc_frame_time(wlc, rate, WLC_LONG_PREAMBLE, - frame_len); - dur += sifs; - - /* Update the SHM Rate Table entry Probe Response values */ - wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS, - (u16) (plcp[0] + (plcp[1] << 8))); - wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS + 2, - (u16) (plcp[2] + (plcp[3] << 8))); - wlc_write_shm(wlc, entry_ptr + M_RT_PRS_DUR_POS, dur); - } -} - -u16 -wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec, - bool short_preamble, bool phydelay) -{ - uint bcntsfoff = 0; - - if (IS_MCS(rspec)) { - WL_ERROR("wl%d: recd beacon with mcs rate; rspec 0x%x\n", - wlc->pub->unit, rspec); - } else if (IS_OFDM(rspec)) { - /* tx delay from MAC through phy to air (2.1 usec) + - * phy header time (preamble + PLCP SIGNAL == 20 usec) + - * PLCP SERVICE + MAC header time (SERVICE + FC + DUR + A1 + A2 + A3 + SEQ == 26 - * bytes at beacon rate) - */ - bcntsfoff += phydelay ? D11A_PHY_TX_DELAY : 0; - bcntsfoff += APHY_PREAMBLE_TIME + APHY_SIGNAL_TIME; - bcntsfoff += - wlc_compute_airtime(wlc, rspec, - APHY_SERVICE_NBITS / 8 + - DOT11_MAC_HDR_LEN); - } else { - /* tx delay from MAC through phy to air (3.4 usec) + - * phy header time (long preamble + PLCP == 192 usec) + - * MAC header time (FC + DUR + A1 + A2 + A3 + SEQ == 24 bytes at beacon rate) - */ - bcntsfoff += phydelay ? D11B_PHY_TX_DELAY : 0; - bcntsfoff += - short_preamble ? D11B_PHY_SPREHDR_TIME : - D11B_PHY_LPREHDR_TIME; - bcntsfoff += wlc_compute_airtime(wlc, rspec, DOT11_MAC_HDR_LEN); - } - return (u16) (bcntsfoff); -} - -/* Max buffering needed for beacon template/prb resp template is 142 bytes. - * - * PLCP header is 6 bytes. - * 802.11 A3 header is 24 bytes. - * Max beacon frame body template length is 112 bytes. - * Max probe resp frame body template length is 110 bytes. - * - * *len on input contains the max length of the packet available. - * - * The *len value is set to the number of bytes in buf used, and starts with the PLCP - * and included up to, but not including, the 4 byte FCS. - */ -static void -wlc_bcn_prb_template(struct wlc_info *wlc, uint type, ratespec_t bcn_rspec, - wlc_bsscfg_t *cfg, u16 *buf, int *len) -{ - static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; - cck_phy_hdr_t *plcp; - struct ieee80211_mgmt *h; - int hdr_len, body_len; - - ASSERT(*len >= 142); - ASSERT(type == FC_BEACON || type == FC_PROBE_RESP); - - if (MBSS_BCN_ENAB(cfg) && type == FC_BEACON) - hdr_len = DOT11_MAC_HDR_LEN; - else - hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN; - body_len = *len - hdr_len; /* calc buffer size provided for frame body */ - - *len = hdr_len + body_len; /* return actual size */ - - /* format PHY and MAC headers */ - memset((char *)buf, 0, hdr_len); - - plcp = (cck_phy_hdr_t *) buf; - - /* PLCP for Probe Response frames are filled in from core's rate table */ - if (type == FC_BEACON && !MBSS_BCN_ENAB(cfg)) { - /* fill in PLCP */ - wlc_compute_plcp(wlc, bcn_rspec, - (DOT11_MAC_HDR_LEN + body_len + FCS_LEN), - (u8 *) plcp); - - } - /* "Regular" and 16 MBSS but not for 4 MBSS */ - /* Update the phytxctl for the beacon based on the rspec */ - if (!SOFTBCN_ENAB(cfg)) - wlc_beacon_phytxctl_txant_upd(wlc, bcn_rspec); - - if (MBSS_BCN_ENAB(cfg) && type == FC_BEACON) - h = (struct ieee80211_mgmt *)&plcp[0]; - else - h = (struct ieee80211_mgmt *)&plcp[1]; - - /* fill in 802.11 header */ - h->frame_control = htol16((u16) type); - - /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */ - /* A1 filled in by MAC for prb resp, broadcast for bcn */ - if (type == FC_BEACON) - bcopy((const char *)ðer_bcast, (char *)&h->da, - ETH_ALEN); - bcopy((char *)&cfg->cur_etheraddr, (char *)&h->sa, ETH_ALEN); - bcopy((char *)&cfg->BSSID, (char *)&h->bssid, ETH_ALEN); - - /* SEQ filled in by MAC */ - - return; -} - -int wlc_get_header_len() -{ - return TXOFF; -} - -/* Update a beacon for a particular BSS - * For MBSS, this updates the software template and sets "latest" to the index of the - * template updated. - * Otherwise, it updates the hardware template. - */ -void wlc_bss_update_beacon(struct wlc_info *wlc, wlc_bsscfg_t *cfg) -{ - int len = BCN_TMPL_LEN; - - /* Clear the soft intmask */ - wlc->defmacintmask &= ~MI_BCNTPL; - - if (!cfg->up) { /* Only allow updates on an UP bss */ - return; - } - - if (MBSS_BCN_ENAB(cfg)) { /* Optimize: Some of if/else could be combined */ - } else if (HWBCN_ENAB(cfg)) { /* Hardware beaconing for this config */ - u16 bcn[BCN_TMPL_LEN / 2]; - u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD; - d11regs_t *regs = wlc->regs; - struct osl_info *osh = NULL; - - osh = wlc->osh; - - /* Check if both templates are in use, if so sched. an interrupt - * that will call back into this routine - */ - if ((R_REG(osh, ®s->maccommand) & both_valid) == both_valid) { - /* clear any previous status */ - W_REG(osh, ®s->macintstatus, MI_BCNTPL); - } - /* Check that after scheduling the interrupt both of the - * templates are still busy. if not clear the int. & remask - */ - if ((R_REG(osh, ®s->maccommand) & both_valid) == both_valid) { - wlc->defmacintmask |= MI_BCNTPL; - return; - } - - wlc->bcn_rspec = - wlc_lowest_basic_rspec(wlc, &cfg->current_bss->rateset); - ASSERT(wlc_valid_rate - (wlc, wlc->bcn_rspec, - CHSPEC_IS2G(cfg->current_bss-> - chanspec) ? WLC_BAND_2G : WLC_BAND_5G, - true)); - - /* update the template and ucode shm */ - wlc_bcn_prb_template(wlc, FC_BEACON, wlc->bcn_rspec, cfg, bcn, - &len); - wlc_write_hw_bcntemplates(wlc, bcn, len, false); - } -} - -/* - * Update all beacons for the system. - */ -void wlc_update_beacon(struct wlc_info *wlc) -{ - int idx; - wlc_bsscfg_t *bsscfg; - - /* update AP or IBSS beacons */ - FOREACH_BSS(wlc, idx, bsscfg) { - if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS)) - wlc_bss_update_beacon(wlc, bsscfg); - } -} - -/* Write ssid into shared memory */ -void wlc_shm_ssid_upd(struct wlc_info *wlc, wlc_bsscfg_t *cfg) -{ - u8 *ssidptr = cfg->SSID; - u16 base = M_SSID; - u8 ssidbuf[IEEE80211_MAX_SSID_LEN]; - - /* padding the ssid with zero and copy it into shm */ - memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN); - bcopy(ssidptr, ssidbuf, cfg->SSID_len); - - wlc_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN); - - if (!MBSS_BCN_ENAB(cfg)) - wlc_write_shm(wlc, M_SSIDLEN, (u16) cfg->SSID_len); -} - -void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend) -{ - int idx; - wlc_bsscfg_t *bsscfg; - - /* update AP or IBSS probe responses */ - FOREACH_BSS(wlc, idx, bsscfg) { - if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS)) - wlc_bss_update_probe_resp(wlc, bsscfg, suspend); - } -} - -void -wlc_bss_update_probe_resp(struct wlc_info *wlc, wlc_bsscfg_t *cfg, bool suspend) -{ - u16 prb_resp[BCN_TMPL_LEN / 2]; - int len = BCN_TMPL_LEN; - - /* write the probe response to hardware, or save in the config structure */ - if (!MBSS_PRB_ENAB(cfg)) { - - /* create the probe response template */ - wlc_bcn_prb_template(wlc, FC_PROBE_RESP, 0, cfg, prb_resp, - &len); - - if (suspend) - wlc_suspend_mac_and_wait(wlc); - - /* write the probe response into the template region */ - wlc_bmac_write_template_ram(wlc->hw, T_PRS_TPL_BASE, - (len + 3) & ~3, prb_resp); - - /* write the length of the probe response frame (+PLCP/-FCS) */ - wlc_write_shm(wlc, M_PRB_RESP_FRM_LEN, (u16) len); - - /* write the SSID and SSID length */ - wlc_shm_ssid_upd(wlc, cfg); - - /* - * Write PLCP headers and durations for probe response frames at all rates. - * Use the actual frame length covered by the PLCP header for the call to - * wlc_mod_prb_rsp_rate_table() by subtracting the PLCP len and adding the FCS. - */ - len += (-D11_PHY_HDR_LEN + FCS_LEN); - wlc_mod_prb_rsp_rate_table(wlc, (u16) len); - - if (suspend) - wlc_enable_mac(wlc); - } else { /* Generating probe resp in sw; update local template */ - ASSERT(0 && "No software probe response support without MBSS"); - } -} - -/* prepares pdu for transmission. returns BCM error codes */ -int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) -{ - struct osl_info *osh; - uint fifo; - d11txh_t *txh; - struct ieee80211_hdr *h; - struct scb *scb; - u16 fc; - - osh = wlc->osh; - - ASSERT(pdu); - txh = (d11txh_t *) (pdu->data); - ASSERT(txh); - h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); - ASSERT(h); - fc = ltoh16(h->frame_control); - - /* get the pkt queue info. This was put at wlc_sendctl or wlc_send for PDU */ - fifo = ltoh16(txh->TxFrameID) & TXFID_QUEUE_MASK; - - scb = NULL; - - *fifop = fifo; - - /* return if insufficient dma resources */ - if (TXAVAIL(wlc, fifo) < MAX_DMA_SEGS) { - /* Mark precedences related to this FIFO, unsendable */ - WLC_TX_FIFO_CLEAR(wlc, fifo); - return BCME_BUSY; - } - - if ((ltoh16(txh->MacFrameControl) & IEEE80211_FCTL_FTYPE) != - IEEE80211_FTYPE_DATA) - WLCNTINCR(wlc->pub->_cnt->txctl); - - return 0; -} - -/* init tx reported rate mechanism */ -void wlc_reprate_init(struct wlc_info *wlc) -{ - int i; - wlc_bsscfg_t *bsscfg; - - FOREACH_BSS(wlc, i, bsscfg) { - wlc_bsscfg_reprate_init(bsscfg); - } -} - -/* per bsscfg init tx reported rate mechanism */ -void wlc_bsscfg_reprate_init(wlc_bsscfg_t *bsscfg) -{ - bsscfg->txrspecidx = 0; - memset((char *)bsscfg->txrspec, 0, sizeof(bsscfg->txrspec)); -} - -/* Retrieve a consolidated set of revision information, - * typically for the WLC_GET_REVINFO ioctl - */ -int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len) -{ - wlc_rev_info_t *rinfo = (wlc_rev_info_t *) buf; - - if (len < WL_REV_INFO_LEGACY_LENGTH) - return BCME_BUFTOOSHORT; - - rinfo->vendorid = wlc->vendorid; - rinfo->deviceid = wlc->deviceid; - rinfo->radiorev = (wlc->band->radiorev << IDCODE_REV_SHIFT) | - (wlc->band->radioid << IDCODE_ID_SHIFT); - rinfo->chiprev = wlc->pub->sih->chiprev; - rinfo->corerev = wlc->pub->corerev; - rinfo->boardid = wlc->pub->sih->boardtype; - rinfo->boardvendor = wlc->pub->sih->boardvendor; - rinfo->boardrev = wlc->pub->boardrev; - rinfo->ucoderev = wlc->ucode_rev; - rinfo->driverrev = EPI_VERSION_NUM; - rinfo->bus = wlc->pub->sih->bustype; - rinfo->chipnum = wlc->pub->sih->chip; - - if (len >= (offsetof(wlc_rev_info_t, chippkg))) { - rinfo->phytype = wlc->band->phytype; - rinfo->phyrev = wlc->band->phyrev; - rinfo->anarev = 0; /* obsolete stuff, suppress */ - } - - if (len >= sizeof(*rinfo)) { - rinfo->chippkg = wlc->pub->sih->chippkg; - } - - return BCME_OK; -} - -void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs) -{ - wlc_rateset_default(rs, NULL, wlc->band->phytype, wlc->band->bandtype, - false, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub), - CHSPEC_WLC_BW(wlc->default_bss->chanspec), - wlc->stf->txstreams); -} - -static void wlc_bss_default_init(struct wlc_info *wlc) -{ - chanspec_t chanspec; - struct wlcband *band; - wlc_bss_info_t *bi = wlc->default_bss; - - /* init default and target BSS with some sane initial values */ - memset((char *)(bi), 0, sizeof(wlc_bss_info_t)); - bi->beacon_period = ISSIM_ENAB(wlc->pub->sih) ? BEACON_INTERVAL_DEF_QT : - BEACON_INTERVAL_DEFAULT; - bi->dtim_period = ISSIM_ENAB(wlc->pub->sih) ? DTIM_INTERVAL_DEF_QT : - DTIM_INTERVAL_DEFAULT; - - /* fill the default channel as the first valid channel - * starting from the 2G channels - */ - chanspec = CH20MHZ_CHSPEC(1); - ASSERT(chanspec != INVCHANSPEC); - - wlc->home_chanspec = bi->chanspec = chanspec; - - /* find the band of our default channel */ - band = wlc->band; - if (NBANDS(wlc) > 1 && band->bandunit != CHSPEC_WLCBANDUNIT(chanspec)) - band = wlc->bandstate[OTHERBANDUNIT(wlc)]; - - /* init bss rates to the band specific default rate set */ - wlc_rateset_default(&bi->rateset, NULL, band->phytype, band->bandtype, - false, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub), - CHSPEC_WLC_BW(chanspec), wlc->stf->txstreams); - - if (N_ENAB(wlc->pub)) - bi->flags |= WLC_BSS_HT; -} - -/* Deferred event processing */ -static void wlc_process_eventq(void *arg) -{ - struct wlc_info *wlc = (struct wlc_info *) arg; - wlc_event_t *etmp; - - while ((etmp = wlc_eventq_deq(wlc->eventq))) { - /* Perform OS specific event processing */ - wl_event(wlc->wl, etmp->event.ifname, etmp); - if (etmp->data) { - kfree(etmp->data); - etmp->data = NULL; - } - wlc_event_free(wlc->eventq, etmp); - } -} - -void -wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, u32 b_low) -{ - if (b_low > *a_low) { - /* low half needs a carry */ - b_high += 1; - } - *a_low -= b_low; - *a_high -= b_high; -} - -static ratespec_t -mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, - u32 int_val) -{ - u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT; - u8 rate = int_val & NRATE_RATE_MASK; - ratespec_t rspec; - bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE); - bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT); - bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY) - == NRATE_OVERRIDE_MCS_ONLY); - int bcmerror = 0; - - if (!ismcs) { - return (ratespec_t) rate; - } - - /* validate the combination of rate/mcs/stf is allowed */ - if (N_ENAB(wlc->pub) && ismcs) { - /* mcs only allowed when nmode */ - if (stf > PHY_TXC1_MODE_SDM) { - WL_ERROR("wl%d: %s: Invalid stf\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - - /* mcs 32 is a special case, DUP mode 40 only */ - if (rate == 32) { - if (!CHSPEC_IS40(wlc->home_chanspec) || - ((stf != PHY_TXC1_MODE_SISO) - && (stf != PHY_TXC1_MODE_CDD))) { - WL_ERROR("wl%d: %s: Invalid mcs 32\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - /* mcs > 7 must use stf SDM */ - } else if (rate > HIGHEST_SINGLE_STREAM_MCS) { - /* mcs > 7 must use stf SDM */ - if (stf != PHY_TXC1_MODE_SDM) { - WL_TRACE("wl%d: %s: enabling SDM mode for mcs %d\n", - WLCWLUNIT(wlc), __func__, rate); - stf = PHY_TXC1_MODE_SDM; - } - } else { - /* MCS 0-7 may use SISO, CDD, and for phy_rev >= 3 STBC */ - if ((stf > PHY_TXC1_MODE_STBC) || - (!WLC_STBC_CAP_PHY(wlc) - && (stf == PHY_TXC1_MODE_STBC))) { - WL_ERROR("wl%d: %s: Invalid STBC\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - } - } else if (IS_OFDM(rate)) { - if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) { - WL_ERROR("wl%d: %s: Invalid OFDM\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - } else if (IS_CCK(rate)) { - if ((cur_band->bandtype != WLC_BAND_2G) - || (stf != PHY_TXC1_MODE_SISO)) { - WL_ERROR("wl%d: %s: Invalid CCK\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - } else { - WL_ERROR("wl%d: %s: Unknown rate type\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - /* make sure multiple antennae are available for non-siso rates */ - if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) { - WL_ERROR("wl%d: %s: SISO antenna but !SISO request\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - - rspec = rate; - if (ismcs) { - rspec |= RSPEC_MIMORATE; - /* For STBC populate the STC field of the ratespec */ - if (stf == PHY_TXC1_MODE_STBC) { - u8 stc; - stc = 1; /* Nss for single stream is always 1 */ - rspec |= (stc << RSPEC_STC_SHIFT); - } - } - - rspec |= (stf << RSPEC_STF_SHIFT); - - if (override_mcs_only) - rspec |= RSPEC_OVERRIDE_MCS_ONLY; - - if (issgi) - rspec |= RSPEC_SHORT_GI; - - if ((rate != 0) - && !wlc_valid_rate(wlc, rspec, cur_band->bandtype, true)) { - return rate; - } - - return rspec; - done: - WL_ERROR("Hoark\n"); - return rate; -} - -/* formula: IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */ -static int -wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, - bool writeToShm) -{ - int idle_busy_ratio_x_16 = 0; - uint offset = - isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM : - M_TX_IDLE_BUSY_RATIO_X_16_CCK; - if (duty_cycle > 100 || duty_cycle < 0) { - WL_ERROR("wl%d: duty cycle value off limit\n", wlc->pub->unit); - return BCME_RANGE; - } - if (duty_cycle) - idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle; - /* Only write to shared memory when wl is up */ - if (writeToShm) - wlc_write_shm(wlc, offset, (u16) idle_busy_ratio_x_16); - - if (isOFDM) - wlc->tx_duty_cycle_ofdm = (u16) duty_cycle; - else - wlc->tx_duty_cycle_cck = (u16) duty_cycle; - - return BCME_OK; -} - -/* Read a single u16 from shared memory. - * SHM 'offset' needs to be an even address - */ -u16 wlc_read_shm(struct wlc_info *wlc, uint offset) -{ - return wlc_bmac_read_shm(wlc->hw, offset); -} - -/* Write a single u16 to shared memory. - * SHM 'offset' needs to be an even address - */ -void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v) -{ - wlc_bmac_write_shm(wlc->hw, offset, v); -} - -/* Set a range of shared memory to a value. - * SHM 'offset' needs to be an even address and - * Range length 'len' must be an even number of bytes - */ -void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len) -{ - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) - return; - - wlc_bmac_set_shm(wlc->hw, offset, v, len); -} - -/* Copy a buffer to shared memory. - * SHM 'offset' needs to be an even address and - * Buffer length 'len' must be an even number of bytes - */ -void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, int len) -{ - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) - return; - wlc_bmac_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL); - -} - -/* Copy from shared memory to a buffer. - * SHM 'offset' needs to be an even address and - * Buffer length 'len' must be an even number of bytes - */ -void wlc_copyfrom_shm(struct wlc_info *wlc, uint offset, void *buf, int len) -{ - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) - return; - - wlc_bmac_copyfrom_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL); -} - -/* wrapper BMAC functions to for HIGH driver access */ -void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val) -{ - wlc_bmac_mctrl(wlc->hw, mask, val); -} - -void wlc_corereset(struct wlc_info *wlc, u32 flags) -{ - wlc_bmac_corereset(wlc->hw, flags); -} - -void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val, int bands) -{ - wlc_bmac_mhf(wlc->hw, idx, mask, val, bands); -} - -u16 wlc_mhf_get(struct wlc_info *wlc, u8 idx, int bands) -{ - return wlc_bmac_mhf_get(wlc->hw, idx, bands); -} - -int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks) -{ - return wlc_bmac_xmtfifo_sz_get(wlc->hw, fifo, blocks); -} - -void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len, - void *buf) -{ - wlc_bmac_write_template_ram(wlc->hw, offset, len, buf); -} - -void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len, - bool both) -{ - wlc_bmac_write_hw_bcntemplates(wlc->hw, bcn, len, both); -} - -void -wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, - const u8 *addr) -{ - wlc_bmac_set_addrmatch(wlc->hw, match_reg_offset, addr); -} - -void wlc_set_rcmta(struct wlc_info *wlc, int idx, const u8 *addr) -{ - wlc_bmac_set_rcmta(wlc->hw, idx, addr); -} - -void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, u32 *tsf_h_ptr) -{ - wlc_bmac_read_tsf(wlc->hw, tsf_l_ptr, tsf_h_ptr); -} - -void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin) -{ - wlc->band->CWmin = newmin; - wlc_bmac_set_cwmin(wlc->hw, newmin); -} - -void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax) -{ - wlc->band->CWmax = newmax; - wlc_bmac_set_cwmax(wlc->hw, newmax); -} - -void wlc_fifoerrors(struct wlc_info *wlc) -{ - - wlc_bmac_fifoerrors(wlc->hw); -} - -/* Search mem rw utilities */ - -void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit) -{ - wlc_bmac_pllreq(wlc->hw, set, req_bit); -} - -void wlc_reset_bmac_done(struct wlc_info *wlc) -{ -} - -void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode) -{ - wlc->ht_cap.cap_info &= ~HT_CAP_MIMO_PS_MASK; - wlc->ht_cap.cap_info |= (mimops_mode << IEEE80211_HT_CAP_SM_PS_SHIFT); - - if (AP_ENAB(wlc->pub) && wlc->clk) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - } -} - -/* check for the particular priority flow control bit being set */ -bool -wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, wlc_txq_info_t *q, int prio) -{ - uint prio_mask; - - if (prio == ALLPRIO) { - prio_mask = TXQ_STOP_FOR_PRIOFC_MASK; - } else { - ASSERT(prio >= 0 && prio <= MAXPRIO); - prio_mask = NBITVAL(prio); - } - - return (q->stopped & prio_mask) == prio_mask; -} - -/* propogate the flow control to all interfaces using the given tx queue */ -void wlc_txflowcontrol(struct wlc_info *wlc, wlc_txq_info_t *qi, - bool on, int prio) -{ - uint prio_bits; - uint cur_bits; - - WL_ERROR("%s: flow control kicks in\n", __func__); - - if (prio == ALLPRIO) { - prio_bits = TXQ_STOP_FOR_PRIOFC_MASK; - } else { - ASSERT(prio >= 0 && prio <= MAXPRIO); - prio_bits = NBITVAL(prio); - } - - cur_bits = qi->stopped & prio_bits; - - /* Check for the case of no change and return early - * Otherwise update the bit and continue - */ - if (on) { - if (cur_bits == prio_bits) { - return; - } - mboolset(qi->stopped, prio_bits); - } else { - if (cur_bits == 0) { - return; - } - mboolclr(qi->stopped, prio_bits); - } - - /* If there is a flow control override we will not change the external - * flow control state. - */ - if (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK) { - return; - } - - wlc_txflowcontrol_signal(wlc, qi, on, prio); -} - -void -wlc_txflowcontrol_override(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, - uint override) -{ - uint prev_override; - - ASSERT(override != 0); - ASSERT((override & TXQ_STOP_FOR_PRIOFC_MASK) == 0); - - prev_override = (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK); - - /* Update the flow control bits and do an early return if there is - * no change in the external flow control state. - */ - if (on) { - mboolset(qi->stopped, override); - /* if there was a previous override bit on, then setting this - * makes no difference. - */ - if (prev_override) { - return; - } - - wlc_txflowcontrol_signal(wlc, qi, ON, ALLPRIO); - } else { - mboolclr(qi->stopped, override); - /* clearing an override bit will only make a difference for - * flow control if it was the only bit set. For any other - * override setting, just return - */ - if (prev_override != override) { - return; - } - - if (qi->stopped == 0) { - wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); - } else { - int prio; - - for (prio = MAXPRIO; prio >= 0; prio--) { - if (!mboolisset(qi->stopped, NBITVAL(prio))) - wlc_txflowcontrol_signal(wlc, qi, OFF, - prio); - } - } - } -} - -static void wlc_txflowcontrol_reset(struct wlc_info *wlc) -{ - wlc_txq_info_t *qi; - - for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { - if (qi->stopped) { - wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); - qi->stopped = 0; - } - } -} - -static void -wlc_txflowcontrol_signal(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, - int prio) -{ - struct wlc_if *wlcif; - - for (wlcif = wlc->wlcif_list; wlcif != NULL; wlcif = wlcif->next) { - if (wlcif->qi == qi && wlcif->flags & WLC_IF_LINKED) - wl_txflowcontrol(wlc->wl, wlcif->wlif, on, prio); - } -} - -static wlc_txq_info_t *wlc_txq_alloc(struct wlc_info *wlc, struct osl_info *osh) -{ - wlc_txq_info_t *qi, *p; - - qi = (wlc_txq_info_t *) wlc_calloc(osh, wlc->pub->unit, - sizeof(wlc_txq_info_t)); - if (qi == NULL) { - return NULL; - } - - /* Have enough room for control packets along with HI watermark */ - /* Also, add room to txq for total psq packets if all the SCBs leave PS mode */ - /* The watermark for flowcontrol to OS packets will remain the same */ - pktq_init(&qi->q, WLC_PREC_COUNT, - (2 * wlc->pub->tunables->datahiwat) + PKTQ_LEN_DEFAULT + - wlc->pub->psq_pkts_total); - - /* add this queue to the the global list */ - p = wlc->tx_queues; - if (p == NULL) { - wlc->tx_queues = qi; - } else { - while (p->next != NULL) - p = p->next; - p->next = qi; - } - - return qi; -} - -static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh, - wlc_txq_info_t *qi) -{ - wlc_txq_info_t *p; - - if (qi == NULL) - return; - - /* remove the queue from the linked list */ - p = wlc->tx_queues; - if (p == qi) - wlc->tx_queues = p->next; - else { - while (p != NULL && p->next != qi) - p = p->next; - ASSERT(p->next == qi); - if (p != NULL) - p->next = p->next->next; - } - - kfree(qi); -} diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h deleted file mode 100644 index f56b58141c09..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ /dev/null @@ -1,989 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_h_ -#define _wlc_h_ - -#include -#include -#include -#include -#include - -#define MA_WINDOW_SZ 8 /* moving average window size */ -#define WL_HWRXOFF 38 /* chip rx buffer offset */ -#define INVCHANNEL 255 /* invalid channel */ -#define MAXCOREREV 28 /* max # supported core revisions (0 .. MAXCOREREV - 1) */ -#define WLC_MAXMODULES 22 /* max # wlc_module_register() calls */ - -/* network protection config */ -#define WLC_PROT_G_SPEC 1 /* SPEC g protection */ -#define WLC_PROT_G_OVR 2 /* SPEC g prot override */ -#define WLC_PROT_G_USER 3 /* gmode specified by user */ -#define WLC_PROT_OVERLAP 4 /* overlap */ -#define WLC_PROT_N_USER 10 /* nmode specified by user */ -#define WLC_PROT_N_CFG 11 /* n protection */ -#define WLC_PROT_N_CFG_OVR 12 /* n protection override */ -#define WLC_PROT_N_NONGF 13 /* non-GF protection */ -#define WLC_PROT_N_NONGF_OVR 14 /* non-GF protection override */ -#define WLC_PROT_N_PAM_OVR 15 /* n preamble override */ -#define WLC_PROT_N_OBSS 16 /* non-HT OBSS present */ - -#define WLC_BITSCNT(x) bcm_bitcount((u8 *)&(x), sizeof(u8)) - -/* Maximum wait time for a MAC suspend */ -#define WLC_MAX_MAC_SUSPEND 83000 /* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */ - -/* Probe Response timeout - responses for probe requests older that this are tossed, zero to disable - */ -#define WLC_PRB_RESP_TIMEOUT 0 /* Disable probe response timeout */ - -/* transmit buffer max headroom for protocol headers */ -#define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN) - -/* For managing scan result lists */ -typedef struct wlc_bss_list { - uint count; - bool beacon; /* set for beacon, cleared for probe response */ - wlc_bss_info_t *ptrs[MAXBSS]; -} wlc_bss_list_t; - -#define SW_TIMER_MAC_STAT_UPD 30 /* periodic MAC stats update */ - -/* Double check that unsupported cores are not enabled */ -#if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV) -#error "Configuration for D11CONF includes unsupported versions." -#endif /* Bad versions */ - -#define VALID_COREREV(corerev) CONF_HAS(D11CONF, corerev) - -/* values for shortslot_override */ -#define WLC_SHORTSLOT_AUTO -1 /* Driver will manage Shortslot setting */ -#define WLC_SHORTSLOT_OFF 0 /* Turn off short slot */ -#define WLC_SHORTSLOT_ON 1 /* Turn on short slot */ - -/* value for short/long and mixmode/greenfield preamble */ - -#define WLC_LONG_PREAMBLE (0) -#define WLC_SHORT_PREAMBLE (1 << 0) -#define WLC_GF_PREAMBLE (1 << 1) -#define WLC_MM_PREAMBLE (1 << 2) -#define WLC_IS_MIMO_PREAMBLE(_pre) (((_pre) == WLC_GF_PREAMBLE) || ((_pre) == WLC_MM_PREAMBLE)) - -/* values for barker_preamble */ -#define WLC_BARKER_SHORT_ALLOWED 0 /* Short pre-amble allowed */ - -/* A fifo is full. Clear precedences related to that FIFO */ -#define WLC_TX_FIFO_CLEAR(wlc, fifo) ((wlc)->tx_prec_map &= ~(wlc)->fifo2prec_map[fifo]) - -/* Fifo is NOT full. Enable precedences for that FIFO */ -#define WLC_TX_FIFO_ENAB(wlc, fifo) ((wlc)->tx_prec_map |= (wlc)->fifo2prec_map[fifo]) - -/* TxFrameID */ -/* seq and frag bits: SEQNUM_SHIFT, FRAGNUM_MASK (802.11.h) */ -/* rate epoch bits: TXFID_RATE_SHIFT, TXFID_RATE_MASK ((wlc_rate.c) */ -#define TXFID_QUEUE_MASK 0x0007 /* Bits 0-2 */ -#define TXFID_SEQ_MASK 0x7FE0 /* Bits 5-15 */ -#define TXFID_SEQ_SHIFT 5 /* Number of bit shifts */ -#define TXFID_RATE_PROBE_MASK 0x8000 /* Bit 15 for rate probe */ -#define TXFID_RATE_MASK 0x0018 /* Mask for bits 3 and 4 */ -#define TXFID_RATE_SHIFT 3 /* Shift 3 bits for rate mask */ - -/* promote boardrev */ -#define BOARDREV_PROMOTABLE 0xFF /* from */ -#define BOARDREV_PROMOTED 1 /* to */ - -/* if wpa is in use then portopen is true when the group key is plumbed otherwise it is always true - */ -#define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) -#define WLC_SW_KEYS(wlc, bsscfg) ((((wlc)->wsec_swkeys) || \ - ((bsscfg)->wsec & WSEC_SWFLAG))) - -#define WLC_PORTOPEN(cfg) \ - (((cfg)->WPA_auth != WPA_AUTH_DISABLED && WSEC_ENABLED((cfg)->wsec)) ? \ - (cfg)->wsec_portopen : true) - -#define PS_ALLOWED(wlc) wlc_ps_allowed(wlc) -#define STAY_AWAKE(wlc) wlc_stay_awake(wlc) - -#define DATA_BLOCK_TX_SUPR (1 << 4) - -/* 802.1D Priority to TX FIFO number for wme */ -extern const u8 prio2fifo[]; - -/* Ucode MCTL_WAKE override bits */ -#define WLC_WAKE_OVERRIDE_CLKCTL 0x01 -#define WLC_WAKE_OVERRIDE_PHYREG 0x02 -#define WLC_WAKE_OVERRIDE_MACSUSPEND 0x04 -#define WLC_WAKE_OVERRIDE_TXFIFO 0x08 -#define WLC_WAKE_OVERRIDE_FORCEFAST 0x10 - -/* stuff pulled in from wlc.c */ - -/* Interrupt bit error summary. Don't include I_RU: we refill DMA at other - * times; and if we run out, constant I_RU interrupts may cause lockup. We - * will still get error counts from rx0ovfl. - */ -#define I_ERRORS (I_PC | I_PD | I_DE | I_RO | I_XU) -/* default software intmasks */ -#define DEF_RXINTMASK (I_RI) /* enable rx int on rxfifo only */ -#define DEF_MACINTMASK (MI_TXSTOP | MI_TBTT | MI_ATIMWINEND | MI_PMQ | \ - MI_PHYTXERR | MI_DMAINT | MI_TFS | MI_BG_NOISE | \ - MI_CCA | MI_TO | MI_GP0 | MI_RFDISABLE | MI_PWRUP) - -#define RETRY_SHORT_DEF 7 /* Default Short retry Limit */ -#define RETRY_SHORT_MAX 255 /* Maximum Short retry Limit */ -#define RETRY_LONG_DEF 4 /* Default Long retry count */ -#define RETRY_SHORT_FB 3 /* Short retry count for fallback rate */ -#define RETRY_LONG_FB 2 /* Long retry count for fallback rate */ - -#define MAXTXPKTS 6 /* max # pkts pending */ - -/* frameburst */ -#define MAXTXFRAMEBURST 8 /* vanilla xpress mode: max frames/burst */ -#define MAXFRAMEBURST_TXOP 10000 /* Frameburst TXOP in usec */ - -/* Per-AC retry limit register definitions; uses bcmdefs.h bitfield macros */ -#define EDCF_SHORT_S 0 -#define EDCF_SFB_S 4 -#define EDCF_LONG_S 8 -#define EDCF_LFB_S 12 -#define EDCF_SHORT_M BITFIELD_MASK(4) -#define EDCF_SFB_M BITFIELD_MASK(4) -#define EDCF_LONG_M BITFIELD_MASK(4) -#define EDCF_LFB_M BITFIELD_MASK(4) - -#define WLC_WME_RETRY_SHORT_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_SHORT) -#define WLC_WME_RETRY_SFB_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_SFB) -#define WLC_WME_RETRY_LONG_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_LONG) -#define WLC_WME_RETRY_LFB_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_LFB) - -#define WLC_WME_RETRY_SHORT_SET(wlc, ac, val) \ - (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SHORT, val)) -#define WLC_WME_RETRY_SFB_SET(wlc, ac, val) \ - (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SFB, val)) -#define WLC_WME_RETRY_LONG_SET(wlc, ac, val) \ - (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LONG, val)) -#define WLC_WME_RETRY_LFB_SET(wlc, ac, val) \ - (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LFB, val)) - -/* PLL requests */ -#define WLC_PLLREQ_SHARED 0x1 /* pll is shared on old chips */ -#define WLC_PLLREQ_RADIO_MON 0x2 /* hold pll for radio monitor register checking */ -#define WLC_PLLREQ_FLIP 0x4 /* hold/release pll for some short operation */ - -/* Do we support this rate? */ -#define VALID_RATE_DBG(wlc, rspec) wlc_valid_rate(wlc, rspec, WLC_BAND_AUTO, true) - -/* - * Macros to check if AP or STA is active. - * AP Active means more than just configured: driver and BSS are "up"; - * that is, we are beaconing/responding as an AP (aps_associated). - * STA Active similarly means the driver is up and a configured STA BSS - * is up: either associated (stas_associated) or trying. - * - * Macro definitions vary as per AP/STA ifdefs, allowing references to - * ifdef'd structure fields and constant values (0) for optimization. - * Make sure to enclose blocks of code such that any routines they - * reference can also be unused and optimized out by the linker. - */ -/* NOTE: References structure fields defined in wlc.h */ -#define AP_ACTIVE(wlc) (0) - -/* - * Detect Card removed. - * Even checking an sbconfig register read will not false trigger when the core is in reset. - * it breaks CF address mechanism. Accessing gphy phyversion will cause SB error if aphy - * is in reset on 4306B0-DB. Need a simple accessible reg with fixed 0/1 pattern - * (some platforms return all 0). - * If clocks are present, call the sb routine which will figure out if the device is removed. - */ -#define DEVICEREMOVED(wlc) \ - ((wlc->hw->clk) ? \ - ((R_REG(wlc->hw->osh, &wlc->hw->regs->maccontrol) & \ - (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN) : \ - (si_deviceremoved(wlc->hw->sih))) - -#define WLCWLUNIT(wlc) ((wlc)->pub->unit) - -typedef struct wlc_protection { - bool _g; /* use g spec protection, driver internal */ - s8 g_override; /* override for use of g spec protection */ - u8 gmode_user; /* user config gmode, operating band->gmode is different */ - s8 overlap; /* Overlap BSS/IBSS protection for both 11g and 11n */ - s8 nmode_user; /* user config nmode, operating pub->nmode is different */ - s8 n_cfg; /* use OFDM protection on MIMO frames */ - s8 n_cfg_override; /* override for use of N protection */ - bool nongf; /* non-GF present protection */ - s8 nongf_override; /* override for use of GF protection */ - s8 n_pam_override; /* override for preamble: MM or GF */ - bool n_obss; /* indicated OBSS Non-HT STA present */ - - uint longpre_detect_timeout; /* #sec until long preamble bcns gone */ - uint barker_detect_timeout; /* #sec until bcns signaling Barker long preamble */ - /* only is gone */ - uint ofdm_ibss_timeout; /* #sec until ofdm IBSS beacons gone */ - uint ofdm_ovlp_timeout; /* #sec until ofdm overlapping BSS bcns gone */ - uint nonerp_ibss_timeout; /* #sec until nonerp IBSS beacons gone */ - uint nonerp_ovlp_timeout; /* #sec until nonerp overlapping BSS bcns gone */ - uint g_ibss_timeout; /* #sec until bcns signaling Use_Protection gone */ - uint n_ibss_timeout; /* #sec until bcns signaling Use_OFDM_Protection gone */ - uint ht20in40_ovlp_timeout; /* #sec until 20MHz overlapping OPMODE gone */ - uint ht20in40_ibss_timeout; /* #sec until 20MHz-only HT station bcns gone */ - uint non_gf_ibss_timeout; /* #sec until non-GF bcns gone */ -} wlc_protection_t; - -/* anything affects the single/dual streams/antenna operation */ -typedef struct wlc_stf { - u8 hw_txchain; /* HW txchain bitmap cfg */ - u8 txchain; /* txchain bitmap being used */ - u8 txstreams; /* number of txchains being used */ - - u8 hw_rxchain; /* HW rxchain bitmap cfg */ - u8 rxchain; /* rxchain bitmap being used */ - u8 rxstreams; /* number of rxchains being used */ - - u8 ant_rx_ovr; /* rx antenna override */ - s8 txant; /* userTx antenna setting */ - u16 phytxant; /* phyTx antenna setting in txheader */ - - u8 ss_opmode; /* singlestream Operational mode, 0:siso; 1:cdd */ - bool ss_algosel_auto; /* if true, use wlc->stf->ss_algo_channel; */ - /* else use wlc->band->stf->ss_mode_band; */ - u16 ss_algo_channel; /* ss based on per-channel algo: 0: SISO, 1: CDD 2: STBC */ - u8 no_cddstbc; /* stf override, 1: no CDD (or STBC) allowed */ - - u8 rxchain_restore_delay; /* delay time to restore default rxchain */ - - s8 ldpc; /* AUTO/ON/OFF ldpc cap supported */ - u8 txcore[MAX_STREAMS_SUPPORTED + 1]; /* bitmap of selected core for each Nsts */ - s8 spatial_policy; -} wlc_stf_t; - -#define WLC_STF_SS_STBC_TX(wlc, scb) \ - (((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) || \ - (SCB_STBC_CAP((scb)) && \ - (wlc)->band->band_stf_stbc_tx == AUTO && \ - isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC)))) - -#define WLC_STBC_CAP_PHY(wlc) (WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3)) - -#define WLC_SGI_CAP_PHY(wlc) ((WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3)) || \ - WLCISLCNPHY(wlc->band)) - -#define WLC_CHAN_PHYTYPE(x) (((x) & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT) -#define WLC_CHAN_CHANNEL(x) (((x) & RXS_CHAN_ID_MASK) >> RXS_CHAN_ID_SHIFT) -#define WLC_RX_CHANNEL(rxh) (WLC_CHAN_CHANNEL((rxh)->RxChan)) - -/* wlc_bss_info flag bit values */ -#define WLC_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */ - -/* Flags used in wlc_txq_info.stopped */ -#define TXQ_STOP_FOR_PRIOFC_MASK 0x000000FF /* per prio flow control bits */ -#define TXQ_STOP_FOR_PKT_DRAIN 0x00000100 /* stop txq enqueue for packet drain */ -#define TXQ_STOP_FOR_AMPDU_FLOW_CNTRL 0x00000200 /* stop txq enqueue for ampdu flow control */ - -#define WLC_HT_WEP_RESTRICT 0x01 /* restrict HT with WEP */ -#define WLC_HT_TKIP_RESTRICT 0x02 /* restrict HT with TKIP */ - -/* - * core state (mac) - */ -struct wlccore { - uint coreidx; /* # sb enumerated core */ - - /* fifo */ - uint *txavail[NFIFO]; /* # tx descriptors available */ - s16 txpktpend[NFIFO]; /* tx admission control */ - - macstat_t *macstat_snapshot; /* mac hw prev read values */ -}; - -/* - * band state (phy+ana+radio) - */ -struct wlcband { - int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */ - uint bandunit; /* bandstate[] index */ - - u16 phytype; /* phytype */ - u16 phyrev; - u16 radioid; - u16 radiorev; - wlc_phy_t *pi; /* pointer to phy specific information */ - bool abgphy_encore; - - u8 gmode; /* currently active gmode (see wlioctl.h) */ - - struct scb *hwrs_scb; /* permanent scb for hw rateset */ - - wlc_rateset_t defrateset; /* band-specific copy of default_bss.rateset */ - - ratespec_t rspec_override; /* 802.11 rate override */ - ratespec_t mrspec_override; /* multicast rate override */ - u8 band_stf_ss_mode; /* Configured STF type, 0:siso; 1:cdd */ - s8 band_stf_stbc_tx; /* STBC TX 0:off; 1:force on; -1:auto */ - wlc_rateset_t hw_rateset; /* rates supported by chip (phy-specific) */ - u8 basic_rate[WLC_MAXRATE + 1]; /* basic rates indexed by rate */ - bool mimo_cap_40; /* 40 MHz cap enabled on this band */ - s8 antgain; /* antenna gain from srom */ - - u16 CWmin; /* The minimum size of contention window, in unit of aSlotTime */ - u16 CWmax; /* The maximum size of contention window, in unit of aSlotTime */ - u16 bcntsfoff; /* beacon tsf offset */ -}; - -/* generic function callback takes just one arg */ -typedef void (*cb_fn_t) (void *); - -/* tx completion callback takes 3 args */ -typedef void (*pkcb_fn_t) (struct wlc_info *wlc, uint txstatus, void *arg); - -typedef struct pkt_cb { - pkcb_fn_t fn; /* function to call when tx frame completes */ - void *arg; /* void arg for fn */ - u8 nextidx; /* index of next call back if threading */ - bool entered; /* recursion check */ -} pkt_cb_t; - - /* module control blocks */ -typedef struct modulecb { - char name[32]; /* module name : NULL indicates empty array member */ - const bcm_iovar_t *iovars; /* iovar table */ - void *hdl; /* handle passed when handler 'doiovar' is called */ - watchdog_fn_t watchdog_fn; /* watchdog handler */ - iovar_fn_t iovar_fn; /* iovar handler */ - down_fn_t down_fn; /* down handler. Note: the int returned - * by the down function is a count of the - * number of timers that could not be - * freed. - */ -} modulecb_t; - - /* dump control blocks */ -typedef struct dumpcb_s { - const char *name; /* dump name */ - dump_fn_t dump_fn; /* 'wl dump' handler */ - void *dump_fn_arg; - struct dumpcb_s *next; -} dumpcb_t; - -/* virtual interface */ -struct wlc_if { - struct wlc_if *next; - u8 type; /* WLC_IFTYPE_BSS or WLC_IFTYPE_WDS */ - u8 index; /* assigned in wl_add_if(), index of the wlif if any, - * not necessarily corresponding to bsscfg._idx or - * AID2PVBMAP(scb). - */ - u8 flags; /* flags for the interface */ - struct wl_if *wlif; /* pointer to wlif */ - struct wlc_txq_info *qi; /* pointer to associated tx queue */ - union { - struct scb *scb; /* pointer to scb if WLC_IFTYPE_WDS */ - struct wlc_bsscfg *bsscfg; /* pointer to bsscfg if WLC_IFTYPE_BSS */ - } u; -}; - -/* flags for the interface */ -#define WLC_IF_LINKED 0x02 /* this interface is linked to a wl_if */ - -typedef struct wlc_hwband { - int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */ - uint bandunit; /* bandstate[] index */ - u16 mhfs[MHFMAX]; /* MHF array shadow */ - u8 bandhw_stf_ss_mode; /* HW configured STF type, 0:siso; 1:cdd */ - u16 CWmin; - u16 CWmax; - u32 core_flags; - - u16 phytype; /* phytype */ - u16 phyrev; - u16 radioid; - u16 radiorev; - wlc_phy_t *pi; /* pointer to phy specific information */ - bool abgphy_encore; -} wlc_hwband_t; - -struct wlc_hw_info { - struct osl_info *osh; /* pointer to os handle */ - bool _piomode; /* true if pio mode */ - struct wlc_info *wlc; - - /* fifo */ - struct hnddma_pub *di[NFIFO]; /* hnddma handles, per fifo */ - - uint unit; /* device instance number */ - - /* version info */ - u16 vendorid; /* PCI vendor id */ - u16 deviceid; /* PCI device id */ - uint corerev; /* core revision */ - u8 sromrev; /* version # of the srom */ - u16 boardrev; /* version # of particular board */ - u32 boardflags; /* Board specific flags from srom */ - u32 boardflags2; /* More board flags if sromrev >= 4 */ - u32 machwcap; /* MAC capabilities (corerev >= 13) */ - u32 machwcap_backup; /* backup of machwcap (corerev >= 13) */ - u16 ucode_dbgsel; /* dbgsel for ucode debug(config gpio) */ - - si_t *sih; /* SB handle (cookie for siutils calls) */ - char *vars; /* "environment" name=value */ - uint vars_size; /* size of vars, free vars on detach */ - d11regs_t *regs; /* pointer to device registers */ - void *physhim; /* phy shim layer handler */ - void *phy_sh; /* pointer to shared phy state */ - wlc_hwband_t *band; /* pointer to active per-band state */ - wlc_hwband_t *bandstate[MAXBANDS]; /* per-band state (one per phy/radio) */ - u16 bmac_phytxant; /* cache of high phytxant state */ - bool shortslot; /* currently using 11g ShortSlot timing */ - u16 SRL; /* 802.11 dot11ShortRetryLimit */ - u16 LRL; /* 802.11 dot11LongRetryLimit */ - u16 SFBL; /* Short Frame Rate Fallback Limit */ - u16 LFBL; /* Long Frame Rate Fallback Limit */ - - bool up; /* d11 hardware up and running */ - uint now; /* # elapsed seconds */ - uint _nbands; /* # bands supported */ - chanspec_t chanspec; /* bmac chanspec shadow */ - - uint *txavail[NFIFO]; /* # tx descriptors available */ - u16 *xmtfifo_sz; /* fifo size in 256B for each xmt fifo */ - - mbool pllreq; /* pll requests to keep PLL on */ - - u8 suspended_fifos; /* Which TX fifo to remain awake for */ - u32 maccontrol; /* Cached value of maccontrol */ - uint mac_suspend_depth; /* current depth of mac_suspend levels */ - u32 wake_override; /* Various conditions to force MAC to WAKE mode */ - u32 mute_override; /* Prevent ucode from sending beacons */ - u8 etheraddr[ETH_ALEN]; /* currently configured ethernet address */ - u32 led_gpio_mask; /* LED GPIO Mask */ - bool noreset; /* true= do not reset hw, used by WLC_OUT */ - bool forcefastclk; /* true if the h/w is forcing the use of fast clk */ - bool clk; /* core is out of reset and has clock */ - bool sbclk; /* sb has clock */ - struct bmac_pmq *bmac_pmq; /* bmac PM states derived from ucode PMQ */ - bool phyclk; /* phy is out of reset and has clock */ - bool dma_lpbk; /* core is in DMA loopback */ - - bool ucode_loaded; /* true after ucode downloaded */ - - - u8 hw_stf_ss_opmode; /* STF single stream operation mode */ - u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic - * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board - */ - u32 antsel_avail; /* - * put struct antsel_info here if more info is - * needed - */ -}; - -/* TX Queue information - * - * Each flow of traffic out of the device has a TX Queue with independent - * flow control. Several interfaces may be associated with a single TX Queue - * if they belong to the same flow of traffic from the device. For multi-channel - * operation there are independent TX Queues for each channel. - */ -typedef struct wlc_txq_info { - struct wlc_txq_info *next; - struct pktq q; - uint stopped; /* tx flow control bits */ -} wlc_txq_info_t; - -/* - * Principal common (os-independent) software data structure. - */ -struct wlc_info { - struct wlc_pub *pub; /* pointer to wlc public state */ - struct osl_info *osh; /* pointer to os handle */ - struct wl_info *wl; /* pointer to os-specific private state */ - d11regs_t *regs; /* pointer to device registers */ - - struct wlc_hw_info *hw; /* HW related state used primarily by BMAC */ - - /* clock */ - int clkreq_override; /* setting for clkreq for PCIE : Auto, 0, 1 */ - u16 fastpwrup_dly; /* time in us needed to bring up d11 fast clock */ - - /* interrupt */ - u32 macintstatus; /* bit channel between isr and dpc */ - u32 macintmask; /* sw runtime master macintmask value */ - u32 defmacintmask; /* default "on" macintmask value */ - - /* up and down */ - bool device_present; /* (removable) device is present */ - - bool clk; /* core is out of reset and has clock */ - - /* multiband */ - struct wlccore *core; /* pointer to active io core */ - struct wlcband *band; /* pointer to active per-band state */ - struct wlccore *corestate; /* per-core state (one per hw core) */ - /* per-band state (one per phy/radio): */ - struct wlcband *bandstate[MAXBANDS]; - - bool war16165; /* PCI slow clock 16165 war flag */ - - bool tx_suspended; /* data fifos need to remain suspended */ - - uint txpend16165war; - - /* packet queue */ - uint qvalid; /* DirFrmQValid and BcMcFrmQValid */ - - /* Regulatory power limits */ - s8 txpwr_local_max; /* regulatory local txpwr max */ - u8 txpwr_local_constraint; /* local power contraint in dB */ - - - struct ampdu_info *ampdu; /* ampdu module handler */ - struct antsel_info *asi; /* antsel module handler */ - wlc_cm_info_t *cmi; /* channel manager module handler */ - - void *btparam; /* bus type specific cookie */ - - uint vars_size; /* size of vars, free vars on detach */ - - u16 vendorid; /* PCI vendor id */ - u16 deviceid; /* PCI device id */ - uint ucode_rev; /* microcode revision */ - - u32 machwcap; /* MAC capabilities, BMAC shadow */ - - u8 perm_etheraddr[ETH_ALEN]; /* original sprom local ethernet address */ - - bool bandlocked; /* disable auto multi-band switching */ - bool bandinit_pending; /* track band init in auto band */ - - bool radio_monitor; /* radio timer is running */ - bool down_override; /* true=down */ - bool going_down; /* down path intermediate variable */ - - bool mpc; /* enable minimum power consumption */ - u8 mpc_dlycnt; /* # of watchdog cnt before turn disable radio */ - u8 mpc_offcnt; /* # of watchdog cnt that radio is disabled */ - u8 mpc_delay_off; /* delay radio disable by # of watchdog cnt */ - u8 prev_non_delay_mpc; /* prev state wlc_is_non_delay_mpc */ - - /* timer */ - struct wl_timer *wdtimer; /* timer for watchdog routine */ - uint fast_timer; /* Periodic timeout for 'fast' timer */ - uint slow_timer; /* Periodic timeout for 'slow' timer */ - uint glacial_timer; /* Periodic timeout for 'glacial' timer */ - uint phycal_mlo; /* last time measurelow calibration was done */ - uint phycal_txpower; /* last time txpower calibration was done */ - - struct wl_timer *radio_timer; /* timer for hw radio button monitor routine */ - struct wl_timer *pspoll_timer; /* periodic pspoll timer */ - - /* promiscuous */ - bool monitor; /* monitor (MPDU sniffing) mode */ - bool bcnmisc_ibss; /* bcns promisc mode override for IBSS */ - bool bcnmisc_scan; /* bcns promisc mode override for scan */ - bool bcnmisc_monitor; /* bcns promisc mode override for monitor */ - - u8 bcn_wait_prd; /* max waiting period (for beacon) in 1024TU */ - - /* driver feature */ - bool _rifs; /* enable per-packet rifs */ - s32 rifs_advert; /* RIFS mode advertisement */ - s8 sgi_tx; /* sgi tx */ - bool wet; /* true if wireless ethernet bridging mode */ - - /* AP-STA synchronization, power save */ - bool check_for_unaligned_tbtt; /* check unaligned tbtt flag */ - bool PM_override; /* no power-save flag, override PM(user input) */ - bool PMenabled; /* current power-management state (CAM or PS) */ - bool PMpending; /* waiting for tx status with PM indicated set */ - bool PMblocked; /* block any PSPolling in PS mode, used to buffer - * AP traffic, also used to indicate in progress - * of scan, rm, etc. off home channel activity. - */ - bool PSpoll; /* whether there is an outstanding PS-Poll frame */ - u8 PM; /* power-management mode (CAM, PS or FASTPS) */ - bool PMawakebcn; /* bcn recvd during current waking state */ - - bool WME_PM_blocked; /* Can STA go to PM when in WME Auto mode */ - bool wake; /* host-specified PS-mode sleep state */ - u8 pspoll_prd; /* pspoll interval in milliseconds */ - u8 bcn_li_bcn; /* beacon listen interval in # beacons */ - u8 bcn_li_dtim; /* beacon listen interval in # dtims */ - - bool WDarmed; /* watchdog timer is armed */ - u32 WDlast; /* last time wlc_watchdog() was called */ - - /* WME */ - ac_bitmap_t wme_dp; /* Discard (oldest first) policy per AC */ - bool wme_apsd; /* enable Advanced Power Save Delivery */ - ac_bitmap_t wme_admctl; /* bit i set if AC i under admission control */ - u16 edcf_txop[AC_COUNT]; /* current txop for each ac */ - wme_param_ie_t wme_param_ie; /* WME parameter info element, which on STA - * contains parameters in use locally, and on - * AP contains parameters advertised to STA - * in beacons and assoc responses. - */ - bool wme_prec_queuing; /* enable/disable non-wme STA prec queuing */ - u16 wme_retries[AC_COUNT]; /* per-AC retry limits */ - - int vlan_mode; /* OK to use 802.1Q Tags (ON, OFF, AUTO) */ - u16 tx_prec_map; /* Precedence map based on HW FIFO space */ - u16 fifo2prec_map[NFIFO]; /* pointer to fifo2_prec map based on WME */ - - /* BSS Configurations */ - wlc_bsscfg_t *bsscfg[WLC_MAXBSSCFG]; /* set of BSS configurations, idx 0 is default and - * always valid - */ - wlc_bsscfg_t *cfg; /* the primary bsscfg (can be AP or STA) */ - u8 stas_associated; /* count of ASSOCIATED STA bsscfgs */ - u8 aps_associated; /* count of UP AP bsscfgs */ - u8 block_datafifo; /* prohibit posting frames to data fifos */ - bool bcmcfifo_drain; /* TX_BCMC_FIFO is set to drain */ - - /* tx queue */ - wlc_txq_info_t *tx_queues; /* common TX Queue list */ - - /* event */ - wlc_eventq_t *eventq; /* event queue for deferred processing */ - - /* security */ - wsec_key_t *wsec_keys[WSEC_MAX_KEYS]; /* dynamic key storage */ - wsec_key_t *wsec_def_keys[WLC_DEFAULT_KEYS]; /* default key storage */ - bool wsec_swkeys; /* indicates that all keys should be - * treated as sw keys (used for debugging) - */ - modulecb_t *modulecb; - dumpcb_t *dumpcb_head; - - u8 mimoft; /* SIGN or 11N */ - u8 mimo_band_bwcap; /* bw cap per band type */ - s8 txburst_limit_override; /* tx burst limit override */ - u16 txburst_limit; /* tx burst limit value */ - s8 cck_40txbw; /* 11N, cck tx b/w override when in 40MHZ mode */ - s8 ofdm_40txbw; /* 11N, ofdm tx b/w override when in 40MHZ mode */ - s8 mimo_40txbw; /* 11N, mimo tx b/w override when in 40MHZ mode */ - /* HT CAP IE being advertised by this node: */ - struct ieee80211_ht_cap ht_cap; - - uint seckeys; /* 54 key table shm address */ - uint tkmickeys; /* 12 TKIP MIC key table shm address */ - - wlc_bss_info_t *default_bss; /* configured BSS parameters */ - - u16 AID; /* association ID */ - u16 counter; /* per-sdu monotonically increasing counter */ - u16 mc_fid_counter; /* BC/MC FIFO frame ID counter */ - - bool ibss_allowed; /* false, all IBSS will be ignored during a scan - * and the driver will not allow the creation of - * an IBSS network - */ - bool ibss_coalesce_allowed; - - char country_default[WLC_CNTRY_BUF_SZ]; /* saved country for leaving 802.11d - * auto-country mode - */ - char autocountry_default[WLC_CNTRY_BUF_SZ]; /* initial country for 802.11d - * auto-country mode - */ -#ifdef BCMDBG - bcm_tlv_t *country_ie_override; /* debug override of announced Country IE */ -#endif - - u16 prb_resp_timeout; /* do not send prb resp if request older than this, - * 0 = disable - */ - - wlc_rateset_t sup_rates_override; /* use only these rates in 11g supported rates if - * specifed - */ - - chanspec_t home_chanspec; /* shared home chanspec */ - - /* PHY parameters */ - chanspec_t chanspec; /* target operational channel */ - u16 usr_fragthresh; /* user configured fragmentation threshold */ - u16 fragthresh[NFIFO]; /* per-fifo fragmentation thresholds */ - u16 RTSThresh; /* 802.11 dot11RTSThreshold */ - u16 SRL; /* 802.11 dot11ShortRetryLimit */ - u16 LRL; /* 802.11 dot11LongRetryLimit */ - u16 SFBL; /* Short Frame Rate Fallback Limit */ - u16 LFBL; /* Long Frame Rate Fallback Limit */ - - /* network config */ - bool shortpreamble; /* currently operating with CCK ShortPreambles */ - bool shortslot; /* currently using 11g ShortSlot timing */ - s8 barker_preamble; /* current Barker Preamble Mode */ - s8 shortslot_override; /* 11g ShortSlot override */ - bool include_legacy_erp; /* include Legacy ERP info elt ID 47 as well as g ID 42 */ - bool barker_overlap_control; /* true: be aware of overlapping BSSs for barker */ - bool ignore_bcns; /* override: ignore non shortslot bcns in a 11g network */ - bool legacy_probe; /* restricts probe requests to CCK rates */ - - wlc_protection_t *protection; - s8 PLCPHdr_override; /* 802.11b Preamble Type override */ - - wlc_stf_t *stf; - - pkt_cb_t *pkt_callback; /* tx completion callback handlers */ - - u32 txretried; /* tx retried number in one msdu */ - - ratespec_t bcn_rspec; /* save bcn ratespec purpose */ - - bool apsd_sta_usp; /* Unscheduled Service Period in progress on STA */ - struct wl_timer *apsd_trigger_timer; /* timer for wme apsd trigger frames */ - u32 apsd_trigger_timeout; /* timeout value for apsd_trigger_timer (in ms) - * 0 == disable - */ - ac_bitmap_t apsd_trigger_ac; /* Permissible Acess Category in which APSD Null - * Trigger frames can be send - */ - u8 htphy_membership; /* HT PHY membership */ - - bool _regulatory_domain; /* 802.11d enabled? */ - - u8 mimops_PM; - - u8 txpwr_percent; /* power output percentage */ - - u8 ht_wsec_restriction; /* the restriction of HT with TKIP or WEP */ - - uint tempsense_lasttime; - - u16 tx_duty_cycle_ofdm; /* maximum allowed duty cycle for OFDM */ - u16 tx_duty_cycle_cck; /* maximum allowed duty cycle for CCK */ - - u16 next_bsscfg_ID; - - struct wlc_if *wlcif_list; /* linked list of wlc_if structs */ - wlc_txq_info_t *active_queue; /* txq for the currently active transmit context */ - u32 mpc_dur; /* total time (ms) in mpc mode except for the - * portion since radio is turned off last time - */ - u32 mpc_laston_ts; /* timestamp (ms) when radio is turned off last - * time - */ - bool pr80838_war; - uint hwrxoff; -}; - -/* antsel module specific state */ -struct antsel_info { - struct wlc_info *wlc; /* pointer to main wlc structure */ - struct wlc_pub *pub; /* pointer to public fn */ - u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic - * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board - */ - u8 antsel_antswitch; /* board level antenna switch type */ - bool antsel_avail; /* Ant selection availability (SROM based) */ - wlc_antselcfg_t antcfg_11n; /* antenna configuration */ - wlc_antselcfg_t antcfg_cur; /* current antenna config (auto) */ -}; - -#define CHANNEL_BANDUNIT(wlc, ch) (((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX) -#define OTHERBANDUNIT(wlc) ((uint)((wlc)->band->bandunit ? BAND_2G_INDEX : BAND_5G_INDEX)) - -#define IS_MBAND_UNLOCKED(wlc) \ - ((NBANDS(wlc) > 1) && !(wlc)->bandlocked) - -#define WLC_BAND_PI_RADIO_CHANSPEC wlc_phy_chanspec_get(wlc->band->pi) - -/* sum the individual fifo tx pending packet counts */ -#define TXPKTPENDTOT(wlc) ((wlc)->core->txpktpend[0] + (wlc)->core->txpktpend[1] + \ - (wlc)->core->txpktpend[2] + (wlc)->core->txpktpend[3]) -#define TXPKTPENDGET(wlc, fifo) ((wlc)->core->txpktpend[(fifo)]) -#define TXPKTPENDINC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] += (val)) -#define TXPKTPENDDEC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] -= (val)) -#define TXPKTPENDCLR(wlc, fifo) ((wlc)->core->txpktpend[(fifo)] = 0) -#define TXAVAIL(wlc, fifo) (*(wlc)->core->txavail[(fifo)]) -#define GETNEXTTXP(wlc, _queue) \ - dma_getnexttxp((wlc)->hw->di[(_queue)], HNDDMA_RANGE_TRANSMITTED) - -#define WLC_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \ - ((len1 == len2) && !memcmp(ssid1, ssid2, len1)) - -extern void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus); -extern void wlc_fatal_error(struct wlc_info *wlc); -extern void wlc_bmac_rpc_watchdog(struct wlc_info *wlc); -extern void wlc_recv(struct wlc_info *wlc, struct sk_buff *p); -extern bool wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2); -extern void wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, - bool commit, s8 txpktpend); -extern void wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend); -extern void wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, - uint prec); -extern void wlc_info_init(struct wlc_info *wlc, int unit); -extern void wlc_print_txstatus(tx_status_t *txs); -extern int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks); -extern void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len, - void *buf); -extern void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len, - bool both); -#if defined(BCMDBG) -extern void wlc_get_rcmta(struct wlc_info *wlc, int idx, - u8 *addr); -#endif -extern void wlc_set_rcmta(struct wlc_info *wlc, int idx, - const u8 *addr); -extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, - const u8 *addr); -extern void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, - u32 *tsf_h_ptr); -extern void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin); -extern void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax); -extern void wlc_fifoerrors(struct wlc_info *wlc); -extern void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit); -extern void wlc_reset_bmac_done(struct wlc_info *wlc); -extern void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val); -extern void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us); -extern void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc); - -#if defined(BCMDBG) -extern void wlc_print_rxh(d11rxhdr_t *rxh); -extern void wlc_print_hdrs(struct wlc_info *wlc, const char *prefix, u8 *frame, - d11txh_t *txh, d11rxhdr_t *rxh, uint len); -extern void wlc_print_txdesc(d11txh_t *txh); -#endif -#if defined(BCMDBG) -extern void wlc_print_dot11_mac_hdr(u8 *buf, int len); -#endif - -extern void wlc_setxband(struct wlc_hw_info *wlc_hw, uint bandunit); -extern void wlc_coredisable(struct wlc_hw_info *wlc_hw); - -extern bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rate, int band, - bool verbose); -extern void wlc_ap_upd(struct wlc_info *wlc); - -/* helper functions */ -extern void wlc_shm_ssid_upd(struct wlc_info *wlc, wlc_bsscfg_t *cfg); -extern int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config); - -extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc); -extern void wlc_mac_bcn_promisc(struct wlc_info *wlc); -extern void wlc_mac_promisc(struct wlc_info *wlc); -extern void wlc_txflowcontrol(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, - int prio); -extern void wlc_txflowcontrol_override(struct wlc_info *wlc, wlc_txq_info_t *qi, - bool on, uint override); -extern bool wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, - wlc_txq_info_t *qi, int prio); -extern void wlc_send_q(struct wlc_info *wlc, wlc_txq_info_t *qi); -extern int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifo); - -extern u16 wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, - uint mac_len); -extern ratespec_t wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, - bool use_rspec, u16 mimo_ctlchbw); -extern u16 wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, - ratespec_t rts_rate, ratespec_t frame_rate, - u8 rts_preamble_type, - u8 frame_preamble_type, uint frame_len, - bool ba); - -extern void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs); - -#if defined(BCMDBG) -extern void wlc_dump_ie(struct wlc_info *wlc, bcm_tlv_t *ie, - struct bcmstrbuf *b); -#endif - -extern bool wlc_ps_check(struct wlc_info *wlc); -extern void wlc_reprate_init(struct wlc_info *wlc); -extern void wlc_bsscfg_reprate_init(wlc_bsscfg_t *bsscfg); -extern void wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, - u32 b_low); -extern u32 wlc_calc_tbtt_offset(u32 bi, u32 tsf_h, u32 tsf_l); - -/* Shared memory access */ -extern void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v); -extern u16 wlc_read_shm(struct wlc_info *wlc, uint offset); -extern void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len); -extern void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, - int len); -extern void wlc_copyfrom_shm(struct wlc_info *wlc, uint offset, void *buf, - int len); - -extern void wlc_update_beacon(struct wlc_info *wlc); -extern void wlc_bss_update_beacon(struct wlc_info *wlc, - struct wlc_bsscfg *bsscfg); - -extern void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend); -extern void wlc_bss_update_probe_resp(struct wlc_info *wlc, wlc_bsscfg_t *cfg, - bool suspend); - -extern bool wlc_ismpc(struct wlc_info *wlc); -extern bool wlc_is_non_delay_mpc(struct wlc_info *wlc); -extern void wlc_radio_mpc_upd(struct wlc_info *wlc); -extern bool wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, - int prec); -extern bool wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, - struct sk_buff *pkt, int prec, bool head); -extern u16 wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec); -extern void wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rate, uint length, - u8 *plcp); -extern uint wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, - u8 preamble_type, uint mac_len); - -extern void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec); - -extern bool wlc_timers_init(struct wlc_info *wlc, int unit); - -extern const bcm_iovar_t wlc_iovars[]; - -extern int wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, - const char *name, void *params, uint p_len, void *arg, - int len, int val_size, struct wlc_if *wlcif); - -#if defined(BCMDBG) -extern void wlc_print_ies(struct wlc_info *wlc, u8 *ies, uint ies_len); -#endif - -extern int wlc_set_nmode(struct wlc_info *wlc, s32 nmode); -extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode); -extern void wlc_mimops_action_ht_send(struct wlc_info *wlc, - wlc_bsscfg_t *bsscfg, u8 mimops_mode); - -extern void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot); -extern void wlc_set_bssid(wlc_bsscfg_t *cfg); -extern void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend); - -extern void wlc_set_ratetable(struct wlc_info *wlc); -extern int wlc_set_mac(wlc_bsscfg_t *cfg); -extern void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, - ratespec_t bcn_rate); -extern void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len); -extern ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, - wlc_rateset_t *rs); -extern u16 wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec, - bool short_preamble, bool phydelay); -extern void wlc_radio_disable(struct wlc_info *wlc); -extern void wlc_bcn_li_upd(struct wlc_info *wlc); - -extern int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len); -extern void wlc_out(struct wlc_info *wlc); -extern void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec); -extern void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt); -extern bool wlc_ps_allowed(struct wlc_info *wlc); -extern bool wlc_stay_awake(struct wlc_info *wlc); -extern void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe); - -extern void wlc_bss_list_free(struct wlc_info *wlc, wlc_bss_list_t *bss_list); -extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode); -#endif /* _wlc_h_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_phy_shim.c b/drivers/staging/brcm80211/sys/wlc_phy_shim.c deleted file mode 100644 index 8bd4ede4c92a..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_phy_shim.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * This is "two-way" interface, acting as the SHIM layer between WL and PHY layer. - * WL driver can optinally call this translation layer to do some preprocessing, then reach PHY. - * On the PHY->WL driver direction, all calls go through this layer since PHY doesn't have the - * access to wlc_hw pointer. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -/* PHY SHIM module specific state */ -struct wlc_phy_shim_info { - struct wlc_hw_info *wlc_hw; /* pointer to main wlc_hw structure */ - void *wlc; /* pointer to main wlc structure */ - void *wl; /* pointer to os-specific private state */ -}; - -wlc_phy_shim_info_t *wlc_phy_shim_attach(struct wlc_hw_info *wlc_hw, - void *wl, void *wlc) { - wlc_phy_shim_info_t *physhim = NULL; - - physhim = kzalloc(sizeof(wlc_phy_shim_info_t), GFP_ATOMIC); - if (!physhim) { - WL_ERROR("wl%d: wlc_phy_shim_attach: out of mem\n", - wlc_hw->unit); - return NULL; - } - physhim->wlc_hw = wlc_hw; - physhim->wlc = wlc; - physhim->wl = wl; - - return physhim; -} - -void wlc_phy_shim_detach(wlc_phy_shim_info_t *physhim) -{ - if (!physhim) - return; - - kfree(physhim); -} - -struct wlapi_timer *wlapi_init_timer(wlc_phy_shim_info_t *physhim, - void (*fn) (void *arg), void *arg, - const char *name) -{ - return (struct wlapi_timer *)wl_init_timer(physhim->wl, fn, arg, name); -} - -void wlapi_free_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t) -{ - wl_free_timer(physhim->wl, (struct wl_timer *)t); -} - -void -wlapi_add_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t, uint ms, - int periodic) -{ - wl_add_timer(physhim->wl, (struct wl_timer *)t, ms, periodic); -} - -bool wlapi_del_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t) -{ - return wl_del_timer(physhim->wl, (struct wl_timer *)t); -} - -void wlapi_intrson(wlc_phy_shim_info_t *physhim) -{ - wl_intrson(physhim->wl); -} - -u32 wlapi_intrsoff(wlc_phy_shim_info_t *physhim) -{ - return wl_intrsoff(physhim->wl); -} - -void wlapi_intrsrestore(wlc_phy_shim_info_t *physhim, u32 macintmask) -{ - wl_intrsrestore(physhim->wl, macintmask); -} - -void wlapi_bmac_write_shm(wlc_phy_shim_info_t *physhim, uint offset, u16 v) -{ - wlc_bmac_write_shm(physhim->wlc_hw, offset, v); -} - -u16 wlapi_bmac_read_shm(wlc_phy_shim_info_t *physhim, uint offset) -{ - return wlc_bmac_read_shm(physhim->wlc_hw, offset); -} - -void -wlapi_bmac_mhf(wlc_phy_shim_info_t *physhim, u8 idx, u16 mask, - u16 val, int bands) -{ - wlc_bmac_mhf(physhim->wlc_hw, idx, mask, val, bands); -} - -void wlapi_bmac_corereset(wlc_phy_shim_info_t *physhim, u32 flags) -{ - wlc_bmac_corereset(physhim->wlc_hw, flags); -} - -void wlapi_suspend_mac_and_wait(wlc_phy_shim_info_t *physhim) -{ - wlc_suspend_mac_and_wait(physhim->wlc); -} - -void wlapi_switch_macfreq(wlc_phy_shim_info_t *physhim, u8 spurmode) -{ - wlc_bmac_switch_macfreq(physhim->wlc_hw, spurmode); -} - -void wlapi_enable_mac(wlc_phy_shim_info_t *physhim) -{ - wlc_enable_mac(physhim->wlc); -} - -void wlapi_bmac_mctrl(wlc_phy_shim_info_t *physhim, u32 mask, u32 val) -{ - wlc_bmac_mctrl(physhim->wlc_hw, mask, val); -} - -void wlapi_bmac_phy_reset(wlc_phy_shim_info_t *physhim) -{ - wlc_bmac_phy_reset(physhim->wlc_hw); -} - -void wlapi_bmac_bw_set(wlc_phy_shim_info_t *physhim, u16 bw) -{ - wlc_bmac_bw_set(physhim->wlc_hw, bw); -} - -u16 wlapi_bmac_get_txant(wlc_phy_shim_info_t *physhim) -{ - return wlc_bmac_get_txant(physhim->wlc_hw); -} - -void wlapi_bmac_phyclk_fgc(wlc_phy_shim_info_t *physhim, bool clk) -{ - wlc_bmac_phyclk_fgc(physhim->wlc_hw, clk); -} - -void wlapi_bmac_macphyclk_set(wlc_phy_shim_info_t *physhim, bool clk) -{ - wlc_bmac_macphyclk_set(physhim->wlc_hw, clk); -} - -void wlapi_bmac_core_phypll_ctl(wlc_phy_shim_info_t *physhim, bool on) -{ - wlc_bmac_core_phypll_ctl(physhim->wlc_hw, on); -} - -void wlapi_bmac_core_phypll_reset(wlc_phy_shim_info_t *physhim) -{ - wlc_bmac_core_phypll_reset(physhim->wlc_hw); -} - -void wlapi_bmac_ucode_wake_override_phyreg_set(wlc_phy_shim_info_t *physhim) -{ - wlc_ucode_wake_override_set(physhim->wlc_hw, WLC_WAKE_OVERRIDE_PHYREG); -} - -void wlapi_bmac_ucode_wake_override_phyreg_clear(wlc_phy_shim_info_t *physhim) -{ - wlc_ucode_wake_override_clear(physhim->wlc_hw, - WLC_WAKE_OVERRIDE_PHYREG); -} - -void -wlapi_bmac_write_template_ram(wlc_phy_shim_info_t *physhim, int offset, - int len, void *buf) -{ - wlc_bmac_write_template_ram(physhim->wlc_hw, offset, len, buf); -} - -u16 wlapi_bmac_rate_shm_offset(wlc_phy_shim_info_t *physhim, u8 rate) -{ - return wlc_bmac_rate_shm_offset(physhim->wlc_hw, rate); -} - -void wlapi_ucode_sample_init(wlc_phy_shim_info_t *physhim) -{ -} - -void -wlapi_copyfrom_objmem(wlc_phy_shim_info_t *physhim, uint offset, void *buf, - int len, u32 sel) -{ - wlc_bmac_copyfrom_objmem(physhim->wlc_hw, offset, buf, len, sel); -} - -void -wlapi_copyto_objmem(wlc_phy_shim_info_t *physhim, uint offset, const void *buf, - int l, u32 sel) -{ - wlc_bmac_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel); -} diff --git a/drivers/staging/brcm80211/sys/wlc_phy_shim.h b/drivers/staging/brcm80211/sys/wlc_phy_shim.h deleted file mode 100644 index c151a5d8c693..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_phy_shim.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_phy_shim_h_ -#define _wlc_phy_shim_h_ - -#define RADAR_TYPE_NONE 0 /* Radar type None */ -#define RADAR_TYPE_ETSI_1 1 /* ETSI 1 Radar type */ -#define RADAR_TYPE_ETSI_2 2 /* ETSI 2 Radar type */ -#define RADAR_TYPE_ETSI_3 3 /* ETSI 3 Radar type */ -#define RADAR_TYPE_ITU_E 4 /* ITU E Radar type */ -#define RADAR_TYPE_ITU_K 5 /* ITU K Radar type */ -#define RADAR_TYPE_UNCLASSIFIED 6 /* Unclassified Radar type */ -#define RADAR_TYPE_BIN5 7 /* long pulse radar type */ -#define RADAR_TYPE_STG2 8 /* staggered-2 radar */ -#define RADAR_TYPE_STG3 9 /* staggered-3 radar */ -#define RADAR_TYPE_FRA 10 /* French radar */ - -/* French radar pulse widths */ -#define FRA_T1_20MHZ 52770 -#define FRA_T2_20MHZ 61538 -#define FRA_T3_20MHZ 66002 -#define FRA_T1_40MHZ 105541 -#define FRA_T2_40MHZ 123077 -#define FRA_T3_40MHZ 132004 -#define FRA_ERR_20MHZ 60 -#define FRA_ERR_40MHZ 120 - -#define ANTSEL_NA 0 /* No boardlevel selection available */ -#define ANTSEL_2x4 1 /* 2x4 boardlevel selection available */ -#define ANTSEL_2x3 2 /* 2x3 CB2 boardlevel selection available */ - -/* Rx Antenna diversity control values */ -#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */ -#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */ -#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */ -#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */ -#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */ -#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */ - -/* Forward declarations */ -struct wlc_hw_info; -typedef struct wlc_phy_shim_info wlc_phy_shim_info_t; - -extern wlc_phy_shim_info_t *wlc_phy_shim_attach(struct wlc_hw_info *wlc_hw, - void *wl, void *wlc); -extern void wlc_phy_shim_detach(wlc_phy_shim_info_t *physhim); - -/* PHY to WL utility functions */ -struct wlapi_timer; -extern struct wlapi_timer *wlapi_init_timer(wlc_phy_shim_info_t *physhim, - void (*fn) (void *arg), void *arg, - const char *name); -extern void wlapi_free_timer(wlc_phy_shim_info_t *physhim, - struct wlapi_timer *t); -extern void wlapi_add_timer(wlc_phy_shim_info_t *physhim, - struct wlapi_timer *t, uint ms, int periodic); -extern bool wlapi_del_timer(wlc_phy_shim_info_t *physhim, - struct wlapi_timer *t); -extern void wlapi_intrson(wlc_phy_shim_info_t *physhim); -extern u32 wlapi_intrsoff(wlc_phy_shim_info_t *physhim); -extern void wlapi_intrsrestore(wlc_phy_shim_info_t *physhim, - u32 macintmask); - -extern void wlapi_bmac_write_shm(wlc_phy_shim_info_t *physhim, uint offset, - u16 v); -extern u16 wlapi_bmac_read_shm(wlc_phy_shim_info_t *physhim, uint offset); -extern void wlapi_bmac_mhf(wlc_phy_shim_info_t *physhim, u8 idx, - u16 mask, u16 val, int bands); -extern void wlapi_bmac_corereset(wlc_phy_shim_info_t *physhim, u32 flags); -extern void wlapi_suspend_mac_and_wait(wlc_phy_shim_info_t *physhim); -extern void wlapi_switch_macfreq(wlc_phy_shim_info_t *physhim, u8 spurmode); -extern void wlapi_enable_mac(wlc_phy_shim_info_t *physhim); -extern void wlapi_bmac_mctrl(wlc_phy_shim_info_t *physhim, u32 mask, - u32 val); -extern void wlapi_bmac_phy_reset(wlc_phy_shim_info_t *physhim); -extern void wlapi_bmac_bw_set(wlc_phy_shim_info_t *physhim, u16 bw); -extern void wlapi_bmac_phyclk_fgc(wlc_phy_shim_info_t *physhim, bool clk); -extern void wlapi_bmac_macphyclk_set(wlc_phy_shim_info_t *physhim, bool clk); -extern void wlapi_bmac_core_phypll_ctl(wlc_phy_shim_info_t *physhim, bool on); -extern void wlapi_bmac_core_phypll_reset(wlc_phy_shim_info_t *physhim); -extern void wlapi_bmac_ucode_wake_override_phyreg_set(wlc_phy_shim_info_t * - physhim); -extern void wlapi_bmac_ucode_wake_override_phyreg_clear(wlc_phy_shim_info_t * - physhim); -extern void wlapi_bmac_write_template_ram(wlc_phy_shim_info_t *physhim, int o, - int len, void *buf); -extern u16 wlapi_bmac_rate_shm_offset(wlc_phy_shim_info_t *physhim, - u8 rate); -extern void wlapi_ucode_sample_init(wlc_phy_shim_info_t *physhim); -extern void wlapi_copyfrom_objmem(wlc_phy_shim_info_t *physhim, uint, - void *buf, int, u32 sel); -extern void wlapi_copyto_objmem(wlc_phy_shim_info_t *physhim, uint, - const void *buf, int, u32); - -extern void wlapi_high_update_phy_mode(wlc_phy_shim_info_t *physhim, - u32 phy_mode); -extern u16 wlapi_bmac_get_txant(wlc_phy_shim_info_t *physhim); -#endif /* _wlc_phy_shim_h_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_pub.h b/drivers/staging/brcm80211/sys/wlc_pub.h deleted file mode 100644 index 23e99685d548..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_pub.h +++ /dev/null @@ -1,624 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_pub_h_ -#define _wlc_pub_h_ - -#include -#include - -#define WLC_NUMRATES 16 /* max # of rates in a rateset */ -#define MAXMULTILIST 32 /* max # multicast addresses */ -#define D11_PHY_HDR_LEN 6 /* Phy header length - 6 bytes */ - -/* phy types */ -#define PHY_TYPE_A 0 /* Phy type A */ -#define PHY_TYPE_G 2 /* Phy type G */ -#define PHY_TYPE_N 4 /* Phy type N */ -#define PHY_TYPE_LP 5 /* Phy type Low Power A/B/G */ -#define PHY_TYPE_SSN 6 /* Phy type Single Stream N */ -#define PHY_TYPE_LCN 8 /* Phy type Single Stream N */ -#define PHY_TYPE_LCNXN 9 /* Phy type 2-stream N */ -#define PHY_TYPE_HT 7 /* Phy type 3-Stream N */ - -/* bw */ -#define WLC_10_MHZ 10 /* 10Mhz nphy channel bandwidth */ -#define WLC_20_MHZ 20 /* 20Mhz nphy channel bandwidth */ -#define WLC_40_MHZ 40 /* 40Mhz nphy channel bandwidth */ - -#define CHSPEC_WLC_BW(chanspec) (CHSPEC_IS40(chanspec) ? WLC_40_MHZ : \ - CHSPEC_IS20(chanspec) ? WLC_20_MHZ : \ - WLC_10_MHZ) - -#define WLC_RSSI_MINVAL -200 /* Low value, e.g. for forcing roam */ -#define WLC_RSSI_NO_SIGNAL -91 /* NDIS RSSI link quality cutoffs */ -#define WLC_RSSI_VERY_LOW -80 /* Very low quality cutoffs */ -#define WLC_RSSI_LOW -70 /* Low quality cutoffs */ -#define WLC_RSSI_GOOD -68 /* Good quality cutoffs */ -#define WLC_RSSI_VERY_GOOD -58 /* Very good quality cutoffs */ -#define WLC_RSSI_EXCELLENT -57 /* Excellent quality cutoffs */ - -#define WLC_PHYTYPE(_x) (_x) /* macro to perform WLC PHY -> D11 PHY TYPE, currently 1:1 */ - -#define MA_WINDOW_SZ 8 /* moving average window size */ - -#define WLC_SNR_INVALID 0 /* invalid SNR value */ - -/* a large TX Power as an init value to factor out of min() calculations, - * keep low enough to fit in an s8, units are .25 dBm - */ -#define WLC_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */ - -/* legacy rx Antenna diversity for SISO rates */ -#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */ -#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */ -#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */ -#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */ -#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */ -#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */ - -/* legacy rx Antenna diversity for SISO rates */ -#define ANT_TX_FORCE_0 0 /* Tx on antenna 0, "legacy term Main" */ -#define ANT_TX_FORCE_1 1 /* Tx on antenna 1, "legacy term Aux" */ -#define ANT_TX_LAST_RX 3 /* Tx on phy's last good Rx antenna */ -#define ANT_TX_DEF 3 /* driver's default tx antenna setting */ - -#define TXCORE_POLICY_ALL 0x1 /* use all available core for transmit */ - -/* Tx Chain values */ -#define TXCHAIN_DEF 0x1 /* def bitmap of txchain */ -#define TXCHAIN_DEF_NPHY 0x3 /* default bitmap of tx chains for nphy */ -#define TXCHAIN_DEF_HTPHY 0x7 /* default bitmap of tx chains for nphy */ -#define RXCHAIN_DEF 0x1 /* def bitmap of rxchain */ -#define RXCHAIN_DEF_NPHY 0x3 /* default bitmap of rx chains for nphy */ -#define RXCHAIN_DEF_HTPHY 0x7 /* default bitmap of rx chains for nphy */ -#define ANTSWITCH_NONE 0 /* no antenna switch */ -#define ANTSWITCH_TYPE_1 1 /* antenna switch on 4321CB2, 2of3 */ -#define ANTSWITCH_TYPE_2 2 /* antenna switch on 4321MPCI, 2of3 */ -#define ANTSWITCH_TYPE_3 3 /* antenna switch on 4322, 2of3 */ - -#define RXBUFSZ PKTBUFSZ -#ifndef AIDMAPSZ -#define AIDMAPSZ (roundup(MAXSCB, NBBY)/NBBY) /* aid bitmap size in bytes */ -#endif /* AIDMAPSZ */ - -typedef struct wlc_tunables { - int ntxd; /* size of tx descriptor table */ - int nrxd; /* size of rx descriptor table */ - int rxbufsz; /* size of rx buffers to post */ - int nrxbufpost; /* # of rx buffers to post */ - int maxscb; /* # of SCBs supported */ - int ampdunummpdu; /* max number of mpdu in an ampdu */ - int maxpktcb; /* max # of packet callbacks */ - int maxucodebss; /* max # of BSS handled in ucode bcn/prb */ - int maxucodebss4; /* max # of BSS handled in sw bcn/prb */ - int maxbss; /* max # of bss info elements in scan list */ - int datahiwat; /* data msg txq hiwat mark */ - int ampdudatahiwat; /* AMPDU msg txq hiwat mark */ - int rxbnd; /* max # of rx bufs to process before deferring to dpc */ - int txsbnd; /* max # tx status to process in wlc_txstatus() */ - int memreserved; /* memory reserved for BMAC's USB dma rx */ -} wlc_tunables_t; - -typedef struct wlc_rateset { - uint count; /* number of rates in rates[] */ - u8 rates[WLC_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */ - u8 htphy_membership; /* HT PHY Membership */ - u8 mcs[MCSSET_LEN]; /* supported mcs index bit map */ -} wlc_rateset_t; - -struct rsn_parms { - u8 flags; /* misc booleans (e.g., supported) */ - u8 multicast; /* multicast cipher */ - u8 ucount; /* count of unicast ciphers */ - u8 unicast[4]; /* unicast ciphers */ - u8 acount; /* count of auth modes */ - u8 auth[4]; /* Authentication modes */ - u8 PAD[4]; /* padding for future growth */ -}; - -/* - * buffer length needed for wlc_format_ssid - * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. - */ -#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) - -#define RSN_FLAGS_SUPPORTED 0x1 /* Flag for rsn_params */ -#define RSN_FLAGS_PREAUTH 0x2 /* Flag for WPA2 rsn_params */ - -/* All the HT-specific default advertised capabilities (including AMPDU) - * should be grouped here at one place - */ -#define AMPDU_DEF_MPDU_DENSITY 6 /* default mpdu density (110 ==> 4us) */ - -/* defaults for the HT (MIMO) bss */ -#define HT_CAP ((HT_CAP_MIMO_PS_OFF << IEEE80211_HT_CAP_SM_PS_SHIFT) |\ - IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_GRN_FLD |\ - HT_CAP_MAX_AMSDU | IEEE80211_HT_CAP_DSSSCCK40) - -/* WLC packet type is a void * */ -typedef void *wlc_pkt_t; - -/* Event data type */ -typedef struct wlc_event { - wl_event_msg_t event; /* encapsulated event */ - struct ether_addr *addr; /* used to keep a trace of the potential present of - * an address in wlc_event_msg_t - */ - int bsscfgidx; /* BSS config when needed */ - struct wl_if *wlif; /* pointer to wlif */ - void *data; /* used to hang additional data on an event */ - struct wlc_event *next; /* enables ordered list of pending events */ -} wlc_event_t; - -/* wlc internal bss_info, wl external one is in wlioctl.h */ -typedef struct wlc_bss_info { - u8 BSSID[ETH_ALEN]; /* network BSSID */ - u16 flags; /* flags for internal attributes */ - u8 SSID_len; /* the length of SSID */ - u8 SSID[32]; /* SSID string */ - s16 RSSI; /* receive signal strength (in dBm) */ - s16 SNR; /* receive signal SNR in dB */ - u16 beacon_period; /* units are Kusec */ - u16 atim_window; /* units are Kusec */ - chanspec_t chanspec; /* Channel num, bw, ctrl_sb and band */ - s8 infra; /* 0=IBSS, 1=infrastructure, 2=unknown */ - wlc_rateset_t rateset; /* supported rates */ - u8 dtim_period; /* DTIM period */ - s8 phy_noise; /* noise right after tx (in dBm) */ - u16 capability; /* Capability information */ - u8 wme_qosinfo; /* QoS Info from WME IE; valid if WLC_BSS_WME flag set */ - struct rsn_parms wpa; - struct rsn_parms wpa2; - u16 qbss_load_aac; /* qbss load available admission capacity */ - /* qbss_load_chan_free <- (0xff - channel_utilization of qbss_load_ie_t) */ - u8 qbss_load_chan_free; /* indicates how free the channel is */ - u8 mcipher; /* multicast cipher */ - u8 wpacfg; /* wpa config index */ -} wlc_bss_info_t; - -/* forward declarations */ -struct wlc_if; - -/* wlc_ioctl error codes */ -#define WLC_ENOIOCTL 1 /* No such Ioctl */ -#define WLC_EINVAL 2 /* Invalid value */ -#define WLC_ETOOSMALL 3 /* Value too small */ -#define WLC_ETOOBIG 4 /* Value too big */ -#define WLC_ERANGE 5 /* Out of range */ -#define WLC_EDOWN 6 /* Down */ -#define WLC_EUP 7 /* Up */ -#define WLC_ENOMEM 8 /* No Memory */ -#define WLC_EBUSY 9 /* Busy */ - -/* IOVar flags for common error checks */ -#define IOVF_MFG (1<<3) /* flag for mfgtest iovars */ -#define IOVF_WHL (1<<4) /* value must be whole (0-max) */ -#define IOVF_NTRL (1<<5) /* value must be natural (1-max) */ - -#define IOVF_SET_UP (1<<6) /* set requires driver be up */ -#define IOVF_SET_DOWN (1<<7) /* set requires driver be down */ -#define IOVF_SET_CLK (1<<8) /* set requires core clock */ -#define IOVF_SET_BAND (1<<9) /* set requires fixed band */ - -#define IOVF_GET_UP (1<<10) /* get requires driver be up */ -#define IOVF_GET_DOWN (1<<11) /* get requires driver be down */ -#define IOVF_GET_CLK (1<<12) /* get requires core clock */ -#define IOVF_GET_BAND (1<<13) /* get requires fixed band */ -#define IOVF_OPEN_ALLOW (1<<14) /* set allowed iovar for opensrc */ - -/* watchdog down and dump callback function proto's */ -typedef int (*watchdog_fn_t) (void *handle); -typedef int (*down_fn_t) (void *handle); -typedef int (*dump_fn_t) (void *handle, struct bcmstrbuf *b); - -/* IOVar handler - * - * handle - a pointer value registered with the function - * vi - iovar_info that was looked up - * actionid - action ID, calculated by IOV_GVAL() and IOV_SVAL() based on varid. - * name - the actual iovar name - * params/plen - parameters and length for a get, input only. - * arg/len - buffer and length for value to be set or retrieved, input or output. - * vsize - value size, valid for integer type only. - * wlcif - interface context (wlc_if pointer) - * - * All pointers may point into the same buffer. - */ -typedef int (*iovar_fn_t) (void *handle, const bcm_iovar_t *vi, - u32 actionid, const char *name, void *params, - uint plen, void *arg, int alen, int vsize, - struct wlc_if *wlcif); - -#define MAC80211_PROMISC_BCNS (1 << 0) -#define MAC80211_SCAN (1 << 1) - -/* - * Public portion of "common" os-independent state structure. - * The wlc handle points at this. - */ -struct wlc_pub { - void *wlc; - - struct ieee80211_hw *ieee_hw; - struct scb *global_scb; - scb_ampdu_t *global_ampdu; - uint mac80211_state; - uint unit; /* device instance number */ - uint corerev; /* core revision */ - struct osl_info *osh; /* pointer to os handle */ - si_t *sih; /* SB handle (cookie for siutils calls) */ - char *vars; /* "environment" name=value */ - bool up; /* interface up and running */ - bool hw_off; /* HW is off */ - wlc_tunables_t *tunables; /* tunables: ntxd, nrxd, maxscb, etc. */ - bool hw_up; /* one time hw up/down(from boot or hibernation) */ - bool _piomode; /* true if pio mode *//* BMAC_NOTE: NEED In both */ - uint _nbands; /* # bands supported */ - uint now; /* # elapsed seconds */ - - bool promisc; /* promiscuous destination address */ - bool delayed_down; /* down delayed */ - bool _ap; /* AP mode enabled */ - bool _apsta; /* simultaneous AP/STA mode enabled */ - bool _assoc_recreate; /* association recreation on up transitions */ - int _wme; /* WME QoS mode */ - u8 _mbss; /* MBSS mode on */ - bool allmulti; /* enable all multicasts */ - bool associated; /* true:part of [I]BSS, false: not */ - /* (union of stas_associated, aps_associated) */ - bool phytest_on; /* whether a PHY test is running */ - bool bf_preempt_4306; /* True to enable 'darwin' mode */ - bool _ampdu; /* ampdu enabled or not */ - bool _cac; /* 802.11e CAC enabled */ - u8 _n_enab; /* bitmap of 11N + HT support */ - bool _n_reqd; /* N support required for clients */ - - s8 _coex; /* 20/40 MHz BSS Management AUTO, ENAB, DISABLE */ - bool _priofc; /* Priority-based flowcontrol */ - - u8 cur_etheraddr[ETH_ALEN]; /* our local ethernet address */ - - u8 *multicast; /* ptr to list of multicast addresses */ - uint nmulticast; /* # enabled multicast addresses */ - - u32 wlfeatureflag; /* Flags to control sw features from registry */ - int psq_pkts_total; /* total num of ps pkts */ - - u16 txmaxpkts; /* max number of large pkts allowed to be pending */ - - /* s/w decryption counters */ - u32 swdecrypt; /* s/w decrypt attempts */ - - int bcmerror; /* last bcm error */ - - mbool radio_disabled; /* bit vector for radio disabled reasons */ - bool radio_active; /* radio on/off state */ - u16 roam_time_thresh; /* Max. # secs. of not hearing beacons - * before roaming. - */ - bool align_wd_tbtt; /* Align watchdog with tbtt indication - * handling. This flag is cleared by default - * and is set by per port code explicitly and - * you need to make sure the OSL_SYSUPTIME() - * is implemented properly in osl of that port - * when it enables this Power Save feature. - */ - - u16 boardrev; /* version # of particular board */ - u8 sromrev; /* version # of the srom */ - char srom_ccode[WLC_CNTRY_BUF_SZ]; /* Country Code in SROM */ - u32 boardflags; /* Board specific flags from srom */ - u32 boardflags2; /* More board flags if sromrev >= 4 */ - bool tempsense_disable; /* disable periodic tempsense check */ - - bool _lmac; /* lmac module included and enabled */ - bool _lmacproto; /* lmac protocol module included and enabled */ - bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */ - bool _ampdumac; /* mac assist ampdu enabled or not */ -}; - -/* wl_monitor rx status per packet */ -typedef struct wl_rxsts { - uint pkterror; /* error flags per pkt */ - uint phytype; /* 802.11 A/B/G ... */ - uint channel; /* channel */ - uint datarate; /* rate in 500kbps */ - uint antenna; /* antenna pkts received on */ - uint pktlength; /* pkt length minus bcm phy hdr */ - u32 mactime; /* time stamp from mac, count per 1us */ - uint sq; /* signal quality */ - s32 signal; /* in dbm */ - s32 noise; /* in dbm */ - uint preamble; /* Unknown, short, long */ - uint encoding; /* Unknown, CCK, PBCC, OFDM */ - uint nfrmtype; /* special 802.11n frames(AMPDU, AMSDU) */ - struct wl_if *wlif; /* wl interface */ -} wl_rxsts_t; - -/* status per error RX pkt */ -#define WL_RXS_CRC_ERROR 0x00000001 /* CRC Error in packet */ -#define WL_RXS_RUNT_ERROR 0x00000002 /* Runt packet */ -#define WL_RXS_ALIGN_ERROR 0x00000004 /* Misaligned packet */ -#define WL_RXS_OVERSIZE_ERROR 0x00000008 /* packet bigger than RX_LENGTH (usually 1518) */ -#define WL_RXS_WEP_ICV_ERROR 0x00000010 /* Integrity Check Value error */ -#define WL_RXS_WEP_ENCRYPTED 0x00000020 /* Encrypted with WEP */ -#define WL_RXS_PLCP_SHORT 0x00000040 /* Short PLCP error */ -#define WL_RXS_DECRYPT_ERR 0x00000080 /* Decryption error */ -#define WL_RXS_OTHER_ERR 0x80000000 /* Other errors */ - -/* phy type */ -#define WL_RXS_PHY_A 0x00000000 /* A phy type */ -#define WL_RXS_PHY_B 0x00000001 /* B phy type */ -#define WL_RXS_PHY_G 0x00000002 /* G phy type */ -#define WL_RXS_PHY_N 0x00000004 /* N phy type */ - -/* encoding */ -#define WL_RXS_ENCODING_CCK 0x00000000 /* CCK encoding */ -#define WL_RXS_ENCODING_OFDM 0x00000001 /* OFDM encoding */ - -/* preamble */ -#define WL_RXS_UNUSED_STUB 0x0 /* stub to match with wlc_ethereal.h */ -#define WL_RXS_PREAMBLE_SHORT 0x00000001 /* Short preamble */ -#define WL_RXS_PREAMBLE_LONG 0x00000002 /* Long preamble */ -#define WL_RXS_PREAMBLE_MIMO_MM 0x00000003 /* MIMO mixed mode preamble */ -#define WL_RXS_PREAMBLE_MIMO_GF 0x00000004 /* MIMO green field preamble */ - -#define WL_RXS_NFRM_AMPDU_FIRST 0x00000001 /* first MPDU in A-MPDU */ -#define WL_RXS_NFRM_AMPDU_SUB 0x00000002 /* subsequent MPDU(s) in A-MPDU */ -#define WL_RXS_NFRM_AMSDU_FIRST 0x00000004 /* first MSDU in A-MSDU */ -#define WL_RXS_NFRM_AMSDU_SUB 0x00000008 /* subsequent MSDU(s) in A-MSDU */ - -/* forward declare and use the struct notation so we don't have to - * have it defined if not necessary. - */ -struct wlc_info; -struct wlc_hw_info; -struct wlc_bsscfg; -struct wlc_if; - -/*********************************************** - * Feature-related macros to optimize out code * - * ********************************************* - */ - -/* AP Support (versus STA) */ -#define AP_ENAB(pub) (0) - -/* Macro to check if APSTA mode enabled */ -#define APSTA_ENAB(pub) (0) - -/* Some useful combinations */ -#define STA_ONLY(pub) (!AP_ENAB(pub)) -#define AP_ONLY(pub) (AP_ENAB(pub) && !APSTA_ENAB(pub)) - -#define ENAB_1x1 0x01 -#define ENAB_2x2 0x02 -#define ENAB_3x3 0x04 -#define ENAB_4x4 0x08 -#define SUPPORT_11N (ENAB_1x1|ENAB_2x2) -#define SUPPORT_HT (ENAB_1x1|ENAB_2x2|ENAB_3x3) -/* WL11N Support */ -#if ((defined(NCONF) && (NCONF != 0)) || (defined(LCNCONF) && (LCNCONF != 0)) || \ - (defined(HTCONF) && (HTCONF != 0)) || (defined(SSLPNCONF) && (SSLPNCONF != 0))) -#define N_ENAB(pub) ((pub)->_n_enab & SUPPORT_11N) -#define N_REQD(pub) ((pub)->_n_reqd) -#else -#define N_ENAB(pub) 0 -#define N_REQD(pub) 0 -#endif - -#if (defined(HTCONF) && (HTCONF != 0)) -#define HT_ENAB(pub) (((pub)->_n_enab & SUPPORT_HT) == SUPPORT_HT) -#else -#define HT_ENAB(pub) 0 -#endif - -#define AMPDU_AGG_HOST 1 -#define AMPDU_ENAB(pub) ((pub)->_ampdu) - -#define EDCF_ENAB(pub) (WME_ENAB(pub)) -#define QOS_ENAB(pub) (WME_ENAB(pub) || N_ENAB(pub)) - -#define MONITOR_ENAB(wlc) ((wlc)->monitor) - -#define PROMISC_ENAB(wlc) ((wlc)->promisc) - -#define WLC_PREC_COUNT 16 /* Max precedence level implemented */ - -/* pri is priority encoded in the packet. This maps the Packet priority to - * enqueue precedence as defined in wlc_prec_map - */ -extern const u8 wlc_prio2prec_map[]; -#define WLC_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7] - -/* This maps priority to one precedence higher - Used by PS-Poll response packets to - * simulate enqueue-at-head operation, but still maintain the order on the queue - */ -#define WLC_PRIO_TO_HI_PREC(pri) min(WLC_PRIO_TO_PREC(pri) + 1, WLC_PREC_COUNT - 1) - -extern const u8 wme_fifo2ac[]; -#define WME_PRIO2AC(prio) wme_fifo2ac[prio2fifo[(prio)]] - -/* Mask to describe all precedence levels */ -#define WLC_PREC_BMP_ALL MAXBITVAL(WLC_PREC_COUNT) - -/* Define a bitmap of precedences comprised by each AC */ -#define WLC_PREC_BMP_AC_BE (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BE)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BE)) | \ - NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_EE)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_EE))) -#define WLC_PREC_BMP_AC_BK (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BK)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BK)) | \ - NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NONE)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NONE))) -#define WLC_PREC_BMP_AC_VI (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_CL)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_CL)) | \ - NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VI)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VI))) -#define WLC_PREC_BMP_AC_VO (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VO)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VO)) | \ - NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NC)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NC))) - -/* WME Support */ -#define WME_ENAB(pub) ((pub)->_wme != OFF) -#define WME_AUTO(wlc) ((wlc)->pub->_wme == AUTO) - -#define WLC_USE_COREFLAGS 0xffffffff /* invalid core flags, use the saved coreflags */ - -#define WLC_UPDATE_STATS(wlc) 0 /* No stats support */ -#define WLCNTINCR(a) /* No stats support */ -#define WLCNTDECR(a) /* No stats support */ -#define WLCNTADD(a, delta) /* No stats support */ -#define WLCNTSET(a, value) /* No stats support */ -#define WLCNTVAL(a) 0 /* No stats support */ - -/* common functions for every port */ -extern void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, - bool piomode, struct osl_info *osh, void *regsva, - uint bustype, void *btparam, uint *perr); -extern uint wlc_detach(struct wlc_info *wlc); -extern int wlc_up(struct wlc_info *wlc); -extern uint wlc_down(struct wlc_info *wlc); - -extern int wlc_set(struct wlc_info *wlc, int cmd, int arg); -extern int wlc_get(struct wlc_info *wlc, int cmd, int *arg); -extern int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg); -extern int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg); -extern bool wlc_chipmatch(u16 vendor, u16 device); -extern void wlc_init(struct wlc_info *wlc); -extern void wlc_reset(struct wlc_info *wlc); - -extern void wlc_intrson(struct wlc_info *wlc); -extern u32 wlc_intrsoff(struct wlc_info *wlc); -extern void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask); -extern bool wlc_intrsupd(struct wlc_info *wlc); -extern bool wlc_isr(struct wlc_info *wlc, bool *wantdpc); -extern bool wlc_dpc(struct wlc_info *wlc, bool bounded); -extern bool wlc_send80211_raw(struct wlc_info *wlc, struct wlc_if *wlcif, - void *p, uint ac); -extern bool wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, - struct ieee80211_hw *hw); -extern int wlc_iovar_op(struct wlc_info *wlc, const char *name, void *params, - int p_len, void *arg, int len, bool set, - struct wlc_if *wlcif); -extern int wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, - struct wlc_if *wlcif); -/* helper functions */ -extern void wlc_statsupd(struct wlc_info *wlc); -extern int wlc_get_header_len(void); -extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc); -extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, - const u8 *addr); -extern void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, - bool suspend); - -extern struct wlc_pub *wlc_pub(void *wlc); - -/* common functions for every port */ -extern int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw); -extern int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw); -extern int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw); -extern int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw); - -extern u32 wlc_reg_read(struct wlc_info *wlc, void *r, uint size); -extern void wlc_reg_write(struct wlc_info *wlc, void *r, u32 v, uint size); -extern void wlc_corereset(struct wlc_info *wlc, u32 flags); -extern void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val, - int bands); -extern u16 wlc_mhf_get(struct wlc_info *wlc, u8 idx, int bands); -extern u32 wlc_delta_txfunfl(struct wlc_info *wlc, int fifo); -extern void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset); -extern void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs); - -/* wlc_phy.c helper functions */ -extern void wlc_set_ps_ctrl(struct wlc_info *wlc); -extern void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val); -extern void wlc_scb_ratesel_init_all(struct wlc_info *wlc); - -/* ioctl */ -extern int wlc_iovar_gets8(struct wlc_info *wlc, const char *name, - s8 *arg); -extern int wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, - void *arg, - int len, bool set); - -extern int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, - const char *name, void *hdl, iovar_fn_t iovar_fn, - watchdog_fn_t watchdog_fn, down_fn_t down_fn); -extern int wlc_module_unregister(struct wlc_pub *pub, const char *name, - void *hdl); -extern void wlc_event_if(struct wlc_info *wlc, struct wlc_bsscfg *cfg, - wlc_event_t *e, const struct ether_addr *addr); -extern void wlc_suspend_mac_and_wait(struct wlc_info *wlc); -extern void wlc_enable_mac(struct wlc_info *wlc); -extern u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate); -extern u32 wlc_get_rspec_history(struct wlc_bsscfg *cfg); -extern u32 wlc_get_current_highest_rate(struct wlc_bsscfg *cfg); - -static inline int wlc_iovar_getuint(struct wlc_info *wlc, const char *name, - uint *arg) -{ - return wlc_iovar_getint(wlc, name, (int *)arg); -} - -static inline int wlc_iovar_getu8(struct wlc_info *wlc, const char *name, - u8 *arg) -{ - return wlc_iovar_gets8(wlc, name, (s8 *) arg); -} - -static inline int wlc_iovar_setuint(struct wlc_info *wlc, const char *name, - uint arg) -{ - return wlc_iovar_setint(wlc, name, (int)arg); -} - -#if defined(BCMDBG) -extern int wlc_iocregchk(struct wlc_info *wlc, uint band); -#endif -#if defined(BCMDBG) -extern int wlc_iocpichk(struct wlc_info *wlc, uint phytype); -#endif - -/* helper functions */ -extern void wlc_getrand(struct wlc_info *wlc, u8 *buf, int len); - -struct scb; -extern void wlc_ps_on(struct wlc_info *wlc, struct scb *scb); -extern void wlc_ps_off(struct wlc_info *wlc, struct scb *scb, bool discard); -extern bool wlc_radio_monitor_stop(struct wlc_info *wlc); - -#if defined(BCMDBG) -extern int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len); -#endif - -extern void wlc_pmkid_build_cand_list(struct wlc_bsscfg *cfg, bool check_SSID); -extern void wlc_pmkid_event(struct wlc_bsscfg *cfg); - -#define MAXBANDS 2 /* Maximum #of bands */ -/* bandstate array indices */ -#define BAND_2G_INDEX 0 /* wlc->bandstate[x] index */ -#define BAND_5G_INDEX 1 /* wlc->bandstate[x] index */ - -#define BAND_2G_NAME "2.4G" -#define BAND_5G_NAME "5G" - -/* BMAC RPC: 7 u32 params: pkttotlen, fifo, commit, fid, txpktpend, pktflag, rpc_id */ -#define WLC_RPCTX_PARAMS 32 - -#endif /* _wlc_pub_h_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_rate.c b/drivers/staging/brcm80211/sys/wlc_rate.c deleted file mode 100644 index ab7d0bed3c0a..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_rate.c +++ /dev/null @@ -1,501 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* Rate info per rate: It tells whether a rate is ofdm or not and its phy_rate value */ -const u8 rate_info[WLC_MAXRATE + 1] = { - /* 0 1 2 3 4 5 6 7 8 9 */ -/* 0 */ 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 10 */ 0x00, 0x37, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00, -/* 20 */ 0x00, 0x00, 0x6e, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, -/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, -/* 50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 70 */ 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, -/* 100 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c -}; - -/* rates are in units of Kbps */ -const mcs_info_t mcs_table[MCS_TABLE_SIZE] = { - /* MCS 0: SS 1, MOD: BPSK, CR 1/2 */ - {6500, 13500, CEIL(6500 * 10, 9), CEIL(13500 * 10, 9), 0x00, - WLC_RATE_6M}, - /* MCS 1: SS 1, MOD: QPSK, CR 1/2 */ - {13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x08, - WLC_RATE_12M}, - /* MCS 2: SS 1, MOD: QPSK, CR 3/4 */ - {19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x0A, - WLC_RATE_18M}, - /* MCS 3: SS 1, MOD: 16QAM, CR 1/2 */ - {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x10, - WLC_RATE_24M}, - /* MCS 4: SS 1, MOD: 16QAM, CR 3/4 */ - {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x12, - WLC_RATE_36M}, - /* MCS 5: SS 1, MOD: 64QAM, CR 2/3 */ - {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x19, - WLC_RATE_48M}, - /* MCS 6: SS 1, MOD: 64QAM, CR 3/4 */ - {58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x1A, - WLC_RATE_54M}, - /* MCS 7: SS 1, MOD: 64QAM, CR 5/6 */ - {65000, 135000, CEIL(65000 * 10, 9), CEIL(135000 * 10, 9), 0x1C, - WLC_RATE_54M}, - /* MCS 8: SS 2, MOD: BPSK, CR 1/2 */ - {13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x40, - WLC_RATE_6M}, - /* MCS 9: SS 2, MOD: QPSK, CR 1/2 */ - {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x48, - WLC_RATE_12M}, - /* MCS 10: SS 2, MOD: QPSK, CR 3/4 */ - {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x4A, - WLC_RATE_18M}, - /* MCS 11: SS 2, MOD: 16QAM, CR 1/2 */ - {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x50, - WLC_RATE_24M}, - /* MCS 12: SS 2, MOD: 16QAM, CR 3/4 */ - {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x52, - WLC_RATE_36M}, - /* MCS 13: SS 2, MOD: 64QAM, CR 2/3 */ - {104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0x59, - WLC_RATE_48M}, - /* MCS 14: SS 2, MOD: 64QAM, CR 3/4 */ - {117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x5A, - WLC_RATE_54M}, - /* MCS 15: SS 2, MOD: 64QAM, CR 5/6 */ - {130000, 270000, CEIL(130000 * 10, 9), CEIL(270000 * 10, 9), 0x5C, - WLC_RATE_54M}, - /* MCS 16: SS 3, MOD: BPSK, CR 1/2 */ - {19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x80, - WLC_RATE_6M}, - /* MCS 17: SS 3, MOD: QPSK, CR 1/2 */ - {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x88, - WLC_RATE_12M}, - /* MCS 18: SS 3, MOD: QPSK, CR 3/4 */ - {58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x8A, - WLC_RATE_18M}, - /* MCS 19: SS 3, MOD: 16QAM, CR 1/2 */ - {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x90, - WLC_RATE_24M}, - /* MCS 20: SS 3, MOD: 16QAM, CR 3/4 */ - {117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x92, - WLC_RATE_36M}, - /* MCS 21: SS 3, MOD: 64QAM, CR 2/3 */ - {156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0x99, - WLC_RATE_48M}, - /* MCS 22: SS 3, MOD: 64QAM, CR 3/4 */ - {175500, 364500, CEIL(175500 * 10, 9), CEIL(364500 * 10, 9), 0x9A, - WLC_RATE_54M}, - /* MCS 23: SS 3, MOD: 64QAM, CR 5/6 */ - {195000, 405000, CEIL(195000 * 10, 9), CEIL(405000 * 10, 9), 0x9B, - WLC_RATE_54M}, - /* MCS 24: SS 4, MOD: BPSK, CR 1/2 */ - {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0xC0, - WLC_RATE_6M}, - /* MCS 25: SS 4, MOD: QPSK, CR 1/2 */ - {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0xC8, - WLC_RATE_12M}, - /* MCS 26: SS 4, MOD: QPSK, CR 3/4 */ - {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0xCA, - WLC_RATE_18M}, - /* MCS 27: SS 4, MOD: 16QAM, CR 1/2 */ - {104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0xD0, - WLC_RATE_24M}, - /* MCS 28: SS 4, MOD: 16QAM, CR 3/4 */ - {156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0xD2, - WLC_RATE_36M}, - /* MCS 29: SS 4, MOD: 64QAM, CR 2/3 */ - {208000, 432000, CEIL(208000 * 10, 9), CEIL(432000 * 10, 9), 0xD9, - WLC_RATE_48M}, - /* MCS 30: SS 4, MOD: 64QAM, CR 3/4 */ - {234000, 486000, CEIL(234000 * 10, 9), CEIL(486000 * 10, 9), 0xDA, - WLC_RATE_54M}, - /* MCS 31: SS 4, MOD: 64QAM, CR 5/6 */ - {260000, 540000, CEIL(260000 * 10, 9), CEIL(540000 * 10, 9), 0xDB, - WLC_RATE_54M}, - /* MCS 32: SS 1, MOD: BPSK, CR 1/2 */ - {0, 6000, 0, CEIL(6000 * 10, 9), 0x00, WLC_RATE_6M}, -}; - -/* phycfg for legacy OFDM frames: code rate, modulation scheme, spatial streams - * Number of spatial streams: always 1 - * other fields: refer to table 78 of section 17.3.2.2 of the original .11a standard - */ -typedef struct legacy_phycfg { - u32 rate_ofdm; /* ofdm mac rate */ - u8 tx_phy_ctl3; /* phy ctl byte 3, code rate, modulation type, # of streams */ -} legacy_phycfg_t; - -#define LEGACY_PHYCFG_TABLE_SIZE 12 /* Number of legacy_rate_cfg entries in the table */ - -/* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */ -/* Eventually MIMOPHY would also be converted to this format */ -/* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */ -static const legacy_phycfg_t legacy_phycfg_table[LEGACY_PHYCFG_TABLE_SIZE] = { - {WLC_RATE_1M, 0x00}, /* CCK 1Mbps, data rate 0 */ - {WLC_RATE_2M, 0x08}, /* CCK 2Mbps, data rate 1 */ - {WLC_RATE_5M5, 0x10}, /* CCK 5.5Mbps, data rate 2 */ - {WLC_RATE_11M, 0x18}, /* CCK 11Mbps, data rate 3 */ - {WLC_RATE_6M, 0x00}, /* OFDM 6Mbps, code rate 1/2, BPSK, 1 spatial stream */ - {WLC_RATE_9M, 0x02}, /* OFDM 9Mbps, code rate 3/4, BPSK, 1 spatial stream */ - {WLC_RATE_12M, 0x08}, /* OFDM 12Mbps, code rate 1/2, QPSK, 1 spatial stream */ - {WLC_RATE_18M, 0x0A}, /* OFDM 18Mbps, code rate 3/4, QPSK, 1 spatial stream */ - {WLC_RATE_24M, 0x10}, /* OFDM 24Mbps, code rate 1/2, 16-QAM, 1 spatial stream */ - {WLC_RATE_36M, 0x12}, /* OFDM 36Mbps, code rate 3/4, 16-QAM, 1 spatial stream */ - {WLC_RATE_48M, 0x19}, /* OFDM 48Mbps, code rate 2/3, 64-QAM, 1 spatial stream */ - {WLC_RATE_54M, 0x1A}, /* OFDM 54Mbps, code rate 3/4, 64-QAM, 1 spatial stream */ -}; - -/* Hardware rates (also encodes default basic rates) */ - -const wlc_rateset_t cck_ofdm_mimo_rates = { - 12, - { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */ - 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60, - 0x6c}, - 0x00, - {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -const wlc_rateset_t ofdm_mimo_rates = { - 8, - { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */ - 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c}, - 0x00, - {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -/* Default ratesets that include MCS32 for 40BW channels */ -const wlc_rateset_t cck_ofdm_40bw_mimo_rates = { - 12, - { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */ - 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60, - 0x6c}, - 0x00, - {0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -const wlc_rateset_t ofdm_40bw_mimo_rates = { - 8, - { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */ - 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c}, - 0x00, - {0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -const wlc_rateset_t cck_ofdm_rates = { - 12, - { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */ - 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60, - 0x6c}, - 0x00, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -const wlc_rateset_t gphy_legacy_rates = { - 4, - { /* 1b, 2b, 5.5b, 11b Mbps */ - 0x82, 0x84, 0x8b, 0x96}, - 0x00, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -const wlc_rateset_t ofdm_rates = { - 8, - { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */ - 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c}, - 0x00, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -const wlc_rateset_t cck_rates = { - 4, - { /* 1b, 2b, 5.5, 11 Mbps */ - 0x82, 0x84, 0x0b, 0x16}, - 0x00, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static bool wlc_rateset_valid(wlc_rateset_t *rs, bool check_brate); - -/* check if rateset is valid. - * if check_brate is true, rateset without a basic rate is considered NOT valid. - */ -static bool wlc_rateset_valid(wlc_rateset_t *rs, bool check_brate) -{ - uint idx; - - if (!rs->count) - return false; - - if (!check_brate) - return true; - - /* error if no basic rates */ - for (idx = 0; idx < rs->count; idx++) { - if (rs->rates[idx] & WLC_RATE_FLAG) - return true; - } - return false; -} - -void wlc_rateset_mcs_upd(wlc_rateset_t *rs, u8 txstreams) -{ - int i; - for (i = txstreams; i < MAX_STREAMS_SUPPORTED; i++) - rs->mcs[i] = 0; -} - -/* filter based on hardware rateset, and sort filtered rateset with basic bit(s) preserved, - * and check if resulting rateset is valid. -*/ -bool -wlc_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs, - const wlc_rateset_t *hw_rs, - bool check_brate, u8 txstreams) -{ - u8 rateset[WLC_MAXRATE + 1]; - u8 r; - uint count; - uint i; - - memset(rateset, 0, sizeof(rateset)); - count = rs->count; - - for (i = 0; i < count; i++) { - /* mask off "basic rate" bit, WLC_RATE_FLAG */ - r = (int)rs->rates[i] & RATE_MASK; - if ((r > WLC_MAXRATE) || (rate_info[r] == 0)) { - continue; - } - rateset[r] = rs->rates[i]; /* preserve basic bit! */ - } - - /* fill out the rates in order, looking at only supported rates */ - count = 0; - for (i = 0; i < hw_rs->count; i++) { - r = hw_rs->rates[i] & RATE_MASK; - ASSERT(r <= WLC_MAXRATE); - if (rateset[r]) - rs->rates[count++] = rateset[r]; - } - - rs->count = count; - - /* only set the mcs rate bit if the equivalent hw mcs bit is set */ - for (i = 0; i < MCSSET_LEN; i++) - rs->mcs[i] = (rs->mcs[i] & hw_rs->mcs[i]); - - if (wlc_rateset_valid(rs, check_brate)) - return true; - else - return false; -} - -/* caluclate the rate of a rx'd frame and return it as a ratespec */ -ratespec_t BCMFASTPATH wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp) -{ - int phy_type; - ratespec_t rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT; - - phy_type = - ((rxh->RxChan & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT); - - if ((phy_type == PHY_TYPE_N) || (phy_type == PHY_TYPE_SSN) || - (phy_type == PHY_TYPE_LCN) || (phy_type == PHY_TYPE_HT)) { - switch (rxh->PhyRxStatus_0 & PRXS0_FT_MASK) { - case PRXS0_CCK: - rspec = - CCK_PHY2MAC_RATE(((cck_phy_hdr_t *) plcp)->signal); - break; - case PRXS0_OFDM: - rspec = - OFDM_PHY2MAC_RATE(((ofdm_phy_hdr_t *) plcp)-> - rlpt[0]); - break; - case PRXS0_PREN: - rspec = (plcp[0] & MIMO_PLCP_MCS_MASK) | RSPEC_MIMORATE; - if (plcp[0] & MIMO_PLCP_40MHZ) { - /* indicate rspec is for 40 MHz mode */ - rspec &= ~RSPEC_BW_MASK; - rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT); - } - break; - case PRXS0_STDN: - /* fallthru */ - default: - /* not supported */ - ASSERT(0); - break; - } - if (PLCP3_ISSGI(plcp[3])) - rspec |= RSPEC_SHORT_GI; - } else - if ((phy_type == PHY_TYPE_A) || (rxh->PhyRxStatus_0 & PRXS0_OFDM)) - rspec = OFDM_PHY2MAC_RATE(((ofdm_phy_hdr_t *) plcp)->rlpt[0]); - else - rspec = CCK_PHY2MAC_RATE(((cck_phy_hdr_t *) plcp)->signal); - - return rspec; -} - -/* copy rateset src to dst as-is (no masking or sorting) */ -void wlc_rateset_copy(const wlc_rateset_t *src, wlc_rateset_t *dst) -{ - bcopy(src, dst, sizeof(wlc_rateset_t)); -} - -/* - * Copy and selectively filter one rateset to another. - * 'basic_only' means only copy basic rates. - * 'rates' indicates cck (11b) and ofdm rates combinations. - * - 0: cck and ofdm - * - 1: cck only - * - 2: ofdm only - * 'xmask' is the copy mask (typically 0x7f or 0xff). - */ -void -wlc_rateset_filter(wlc_rateset_t *src, wlc_rateset_t *dst, bool basic_only, - u8 rates, uint xmask, bool mcsallow) -{ - uint i; - uint r; - uint count; - - count = 0; - for (i = 0; i < src->count; i++) { - r = src->rates[i]; - if (basic_only && !(r & WLC_RATE_FLAG)) - continue; - if ((rates == WLC_RATES_CCK) && IS_OFDM((r & RATE_MASK))) - continue; - if ((rates == WLC_RATES_OFDM) && IS_CCK((r & RATE_MASK))) - continue; - dst->rates[count++] = r & xmask; - } - dst->count = count; - dst->htphy_membership = src->htphy_membership; - - if (mcsallow && rates != WLC_RATES_CCK) - bcopy(&src->mcs[0], &dst->mcs[0], MCSSET_LEN); - else - wlc_rateset_mcs_clear(dst); -} - -/* select rateset for a given phy_type and bandtype and filter it, sort it - * and fill rs_tgt with result - */ -void -wlc_rateset_default(wlc_rateset_t *rs_tgt, const wlc_rateset_t *rs_hw, - uint phy_type, int bandtype, bool cck_only, uint rate_mask, - bool mcsallow, u8 bw, u8 txstreams) -{ - const wlc_rateset_t *rs_dflt; - wlc_rateset_t rs_sel; - if ((PHYTYPE_IS(phy_type, PHY_TYPE_HT)) || - (PHYTYPE_IS(phy_type, PHY_TYPE_N)) || - (PHYTYPE_IS(phy_type, PHY_TYPE_LCN)) || - (PHYTYPE_IS(phy_type, PHY_TYPE_SSN))) { - if (BAND_5G(bandtype)) { - rs_dflt = (bw == WLC_20_MHZ ? - &ofdm_mimo_rates : &ofdm_40bw_mimo_rates); - } else { - rs_dflt = (bw == WLC_20_MHZ ? - &cck_ofdm_mimo_rates : - &cck_ofdm_40bw_mimo_rates); - } - } else if (PHYTYPE_IS(phy_type, PHY_TYPE_LP)) { - rs_dflt = (BAND_5G(bandtype)) ? &ofdm_rates : &cck_ofdm_rates; - } else if (PHYTYPE_IS(phy_type, PHY_TYPE_A)) { - rs_dflt = &ofdm_rates; - } else if (PHYTYPE_IS(phy_type, PHY_TYPE_G)) { - rs_dflt = &cck_ofdm_rates; - } else { - ASSERT(0); /* should not happen */ - rs_dflt = &cck_rates; /* force cck */ - } - - /* if hw rateset is not supplied, assign selected rateset to it */ - if (!rs_hw) - rs_hw = rs_dflt; - - wlc_rateset_copy(rs_dflt, &rs_sel); - wlc_rateset_mcs_upd(&rs_sel, txstreams); - wlc_rateset_filter(&rs_sel, rs_tgt, false, - cck_only ? WLC_RATES_CCK : WLC_RATES_CCK_OFDM, - rate_mask, mcsallow); - wlc_rate_hwrs_filter_sort_validate(rs_tgt, rs_hw, false, - mcsallow ? txstreams : 1); -} - -s16 BCMFASTPATH wlc_rate_legacy_phyctl(uint rate) -{ - uint i; - for (i = 0; i < LEGACY_PHYCFG_TABLE_SIZE; i++) - if (rate == legacy_phycfg_table[i].rate_ofdm) - return legacy_phycfg_table[i].tx_phy_ctl3; - - return -1; -} - -void wlc_rateset_mcs_clear(wlc_rateset_t *rateset) -{ - uint i; - for (i = 0; i < MCSSET_LEN; i++) - rateset->mcs[i] = 0; -} - -void wlc_rateset_mcs_build(wlc_rateset_t *rateset, u8 txstreams) -{ - bcopy(&cck_ofdm_mimo_rates.mcs[0], &rateset->mcs[0], MCSSET_LEN); - wlc_rateset_mcs_upd(rateset, txstreams); -} - -/* Based on bandwidth passed, allow/disallow MCS 32 in the rateset */ -void wlc_rateset_bw_mcs_filter(wlc_rateset_t *rateset, u8 bw) -{ - if (bw == WLC_40_MHZ) - setbit(rateset->mcs, 32); - else - clrbit(rateset->mcs, 32); -} diff --git a/drivers/staging/brcm80211/sys/wlc_rate.h b/drivers/staging/brcm80211/sys/wlc_rate.h deleted file mode 100644 index 25ba2a423639..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_rate.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _WLC_RATE_H_ -#define _WLC_RATE_H_ - -extern const u8 rate_info[]; -extern const struct wlc_rateset cck_ofdm_mimo_rates; -extern const struct wlc_rateset ofdm_mimo_rates; -extern const struct wlc_rateset cck_ofdm_rates; -extern const struct wlc_rateset ofdm_rates; -extern const struct wlc_rateset cck_rates; -extern const struct wlc_rateset gphy_legacy_rates; -extern const struct wlc_rateset wlc_lrs_rates; -extern const struct wlc_rateset rate_limit_1_2; - -typedef struct mcs_info { - u32 phy_rate_20; /* phy rate in kbps [20Mhz] */ - u32 phy_rate_40; /* phy rate in kbps [40Mhz] */ - u32 phy_rate_20_sgi; /* phy rate in kbps [20Mhz] with SGI */ - u32 phy_rate_40_sgi; /* phy rate in kbps [40Mhz] with SGI */ - u8 tx_phy_ctl3; /* phy ctl byte 3, code rate, modulation type, # of streams */ - u8 leg_ofdm; /* matching legacy ofdm rate in 500bkps */ -} mcs_info_t; - -#define WLC_MAXMCS 32 /* max valid mcs index */ -#define MCS_TABLE_SIZE 33 /* Number of mcs entries in the table */ -extern const mcs_info_t mcs_table[]; - -#define MCS_INVALID 0xFF -#define MCS_CR_MASK 0x07 /* Code Rate bit mask */ -#define MCS_MOD_MASK 0x38 /* Modulation bit shift */ -#define MCS_MOD_SHIFT 3 /* MOdulation bit shift */ -#define MCS_TXS_MASK 0xc0 /* num tx streams - 1 bit mask */ -#define MCS_TXS_SHIFT 6 /* num tx streams - 1 bit shift */ -#define MCS_CR(_mcs) (mcs_table[_mcs].tx_phy_ctl3 & MCS_CR_MASK) -#define MCS_MOD(_mcs) ((mcs_table[_mcs].tx_phy_ctl3 & MCS_MOD_MASK) >> MCS_MOD_SHIFT) -#define MCS_TXS(_mcs) ((mcs_table[_mcs].tx_phy_ctl3 & MCS_TXS_MASK) >> MCS_TXS_SHIFT) -#define MCS_RATE(_mcs, _is40, _sgi) (_sgi ? \ - (_is40 ? mcs_table[_mcs].phy_rate_40_sgi : mcs_table[_mcs].phy_rate_20_sgi) : \ - (_is40 ? mcs_table[_mcs].phy_rate_40 : mcs_table[_mcs].phy_rate_20)) -#define VALID_MCS(_mcs) ((_mcs < MCS_TABLE_SIZE)) - -#define WLC_RATE_FLAG 0x80 /* Rate flag: basic or ofdm */ - -/* Macros to use the rate_info table */ -#define RATE_MASK 0x7f /* Rate value mask w/o basic rate flag */ -#define RATE_MASK_FULL 0xff /* Rate value mask with basic rate flag */ - -#define WLC_RATE_500K_TO_BPS(rate) ((rate) * 500000) /* convert 500kbps to bps */ - -/* rate spec : holds rate and mode specific information required to generate a tx frame. */ -/* Legacy CCK and OFDM information is held in the same manner as was done in the past */ -/* (in the lower byte) the upper 3 bytes primarily hold MIMO specific information */ -typedef u32 ratespec_t; - -/* rate spec bit fields */ -#define RSPEC_RATE_MASK 0x0000007F /* Either 500Kbps units or MIMO MCS idx */ -#define RSPEC_MIMORATE 0x08000000 /* mimo MCS is stored in RSPEC_RATE_MASK */ -#define RSPEC_BW_MASK 0x00000700 /* mimo bw mask */ -#define RSPEC_BW_SHIFT 8 /* mimo bw shift */ -#define RSPEC_STF_MASK 0x00003800 /* mimo Space/Time/Frequency mode mask */ -#define RSPEC_STF_SHIFT 11 /* mimo Space/Time/Frequency mode shift */ -#define RSPEC_CT_MASK 0x0000C000 /* mimo coding type mask */ -#define RSPEC_CT_SHIFT 14 /* mimo coding type shift */ -#define RSPEC_STC_MASK 0x00300000 /* mimo num STC streams per PLCP defn. */ -#define RSPEC_STC_SHIFT 20 /* mimo num STC streams per PLCP defn. */ -#define RSPEC_LDPC_CODING 0x00400000 /* mimo bit indicates adv coding in use */ -#define RSPEC_SHORT_GI 0x00800000 /* mimo bit indicates short GI in use */ -#define RSPEC_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */ -#define RSPEC_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicates override rate only */ - -#define WLC_HTPHY 127 /* HT PHY Membership */ - -#define RSPEC_ACTIVE(rspec) (rspec & (RSPEC_RATE_MASK | RSPEC_MIMORATE)) -#define RSPEC2RATE(rspec) ((rspec & RSPEC_MIMORATE) ? \ - MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec)) : \ - (rspec & RSPEC_RATE_MASK)) -/* return rate in unit of 500Kbps -- for internal use in wlc_rate_sel.c */ -#define RSPEC2RATE500K(rspec) ((rspec & RSPEC_MIMORATE) ? \ - MCS_RATE((rspec & RSPEC_RATE_MASK), state->is40bw, RSPEC_ISSGI(rspec))/500 : \ - (rspec & RSPEC_RATE_MASK)) -#define CRSPEC2RATE500K(rspec) ((rspec & RSPEC_MIMORATE) ? \ - MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec))/500 :\ - (rspec & RSPEC_RATE_MASK)) - -#define RSPEC2KBPS(rspec) (IS_MCS(rspec) ? RSPEC2RATE(rspec) : RSPEC2RATE(rspec)*500) -#define RSPEC_PHYTXBYTE2(rspec) ((rspec & 0xff00) >> 8) -#define RSPEC_GET_BW(rspec) ((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT) -#define RSPEC_IS40MHZ(rspec) ((((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT) == \ - PHY_TXC1_BW_40MHZ) || (((rspec & RSPEC_BW_MASK) >> \ - RSPEC_BW_SHIFT) == PHY_TXC1_BW_40MHZ_DUP)) -#define RSPEC_ISSGI(rspec) ((rspec & RSPEC_SHORT_GI) == RSPEC_SHORT_GI) -#define RSPEC_MIMOPLCP3(rspec) ((rspec & 0xf00000) >> 16) -#define PLCP3_ISSGI(plcp) (plcp & (RSPEC_SHORT_GI >> 16)) -#define RSPEC_STC(rspec) ((rspec & RSPEC_STC_MASK) >> RSPEC_STC_SHIFT) -#define RSPEC_STF(rspec) ((rspec & RSPEC_STF_MASK) >> RSPEC_STF_SHIFT) -#define PLCP3_ISSTBC(plcp) ((plcp & (RSPEC_STC_MASK) >> 16) == 0x10) -#define PLCP3_STC_MASK 0x30 -#define PLCP3_STC_SHIFT 4 - -/* Rate info table; takes a legacy rate or ratespec_t */ -#define IS_MCS(r) (r & RSPEC_MIMORATE) -#define IS_OFDM(r) (!IS_MCS(r) && (rate_info[(r) & RSPEC_RATE_MASK] & WLC_RATE_FLAG)) -#define IS_CCK(r) (!IS_MCS(r) && (((r) & RATE_MASK) == WLC_RATE_1M || \ - ((r) & RATE_MASK) == WLC_RATE_2M || \ - ((r) & RATE_MASK) == WLC_RATE_5M5 || ((r) & RATE_MASK) == WLC_RATE_11M)) -#define IS_SINGLE_STREAM(mcs) (((mcs) <= HIGHEST_SINGLE_STREAM_MCS) || ((mcs) == 32)) -#define CCK_RSPEC(cck) ((cck) & RSPEC_RATE_MASK) -#define OFDM_RSPEC(ofdm) (((ofdm) & RSPEC_RATE_MASK) |\ - (PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT)) -#define LEGACY_RSPEC(rate) (IS_CCK(rate) ? CCK_RSPEC(rate) : OFDM_RSPEC(rate)) - -#define MCS_RSPEC(mcs) (((mcs) & RSPEC_RATE_MASK) | RSPEC_MIMORATE | \ - (IS_SINGLE_STREAM(mcs) ? (PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT) : \ - (PHY_TXC1_MODE_SDM << RSPEC_STF_SHIFT))) - -/* Convert encoded rate value in plcp header to numerical rates in 500 KHz increments */ -extern const u8 ofdm_rate_lookup[]; -#define OFDM_PHY2MAC_RATE(rlpt) (ofdm_rate_lookup[rlpt & 0x7]) -#define CCK_PHY2MAC_RATE(signal) (signal/5) - -/* Rates specified in wlc_rateset_filter() */ -#define WLC_RATES_CCK_OFDM 0 -#define WLC_RATES_CCK 1 -#define WLC_RATES_OFDM 2 - -/* use the stuct form instead of typedef to fix dependency problems */ -struct wlc_rateset; - -/* sanitize, and sort a rateset with the basic bit(s) preserved, validate rateset */ -extern bool wlc_rate_hwrs_filter_sort_validate(struct wlc_rateset *rs, - const struct wlc_rateset *hw_rs, - bool check_brate, - u8 txstreams); -/* copy rateset src to dst as-is (no masking or sorting) */ -extern void wlc_rateset_copy(const struct wlc_rateset *src, - struct wlc_rateset *dst); - -/* would be nice to have these documented ... */ -extern ratespec_t wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp); - -extern void wlc_rateset_filter(struct wlc_rateset *src, struct wlc_rateset *dst, - bool basic_only, u8 rates, uint xmask, - bool mcsallow); -extern void wlc_rateset_default(struct wlc_rateset *rs_tgt, - const struct wlc_rateset *rs_hw, uint phy_type, - int bandtype, bool cck_only, uint rate_mask, - bool mcsallow, u8 bw, u8 txstreams); -extern s16 wlc_rate_legacy_phyctl(uint rate); - -extern void wlc_rateset_mcs_upd(struct wlc_rateset *rs, u8 txstreams); -extern void wlc_rateset_mcs_clear(struct wlc_rateset *rateset); -extern void wlc_rateset_mcs_build(struct wlc_rateset *rateset, u8 txstreams); -extern void wlc_rateset_bw_mcs_filter(struct wlc_rateset *rateset, u8 bw); - -#endif /* _WLC_RATE_H_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_scb.h b/drivers/staging/brcm80211/sys/wlc_scb.h deleted file mode 100644 index 142b75674444..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_scb.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_scb_h_ -#define _wlc_scb_h_ - -#include - -extern bool wlc_aggregatable(struct wlc_info *wlc, u8 tid); - -#define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */ -/* structure to store per-tid state for the ampdu initiator */ -typedef struct scb_ampdu_tid_ini { - u32 magic; - u8 tx_in_transit; /* number of pending mpdus in transit in driver */ - u8 tid; /* initiator tid for easy lookup */ - u8 txretry[AMPDU_TX_BA_MAX_WSIZE]; /* tx retry count; indexed by seq modulo */ - struct scb *scb; /* backptr for easy lookup */ -} scb_ampdu_tid_ini_t; - -#define AMPDU_MAX_SCB_TID NUMPRIO - -typedef struct scb_ampdu { - struct scb *scb; /* back pointer for easy reference */ - u8 mpdu_density; /* mpdu density */ - u8 max_pdu; /* max pdus allowed in ampdu */ - u8 release; /* # of mpdus released at a time */ - u16 min_len; /* min mpdu len to support the density */ - u32 max_rxlen; /* max ampdu rcv length; 8k, 16k, 32k, 64k */ - struct pktq txq; /* sdu transmit queue pending aggregation */ - - /* This could easily be a ini[] pointer and we keep this info in wl itself instead - * of having mac80211 hold it for us. Also could be made dynamic per tid instead of - * static. - */ - scb_ampdu_tid_ini_t ini[AMPDU_MAX_SCB_TID]; /* initiator info - per tid (NUMPRIO) */ -} scb_ampdu_t; - -#define SCB_MAGIC 0xbeefcafe -#define INI_MAGIC 0xabcd1234 - -/* station control block - one per remote MAC address */ -struct scb { - u32 magic; - u32 flags; /* various bit flags as defined below */ - u32 flags2; /* various bit flags2 as defined below */ - u8 state; /* current state bitfield of auth/assoc process */ - u8 ea[ETH_ALEN]; /* station address */ - void *fragbuf[NUMPRIO]; /* defragmentation buffer per prio */ - uint fragresid[NUMPRIO]; /* #bytes unused in frag buffer per prio */ - - u16 seqctl[NUMPRIO]; /* seqctl of last received frame (for dups) */ - u16 seqctl_nonqos; /* seqctl of last received frame (for dups) for - * non-QoS data and management - */ - u16 seqnum[NUMPRIO]; /* WME: driver maintained sw seqnum per priority */ - - scb_ampdu_t scb_ampdu; /* AMPDU state including per tid info */ -}; - -/* scb flags */ -#define SCB_WMECAP 0x0040 /* may ONLY be set if WME_ENAB(wlc) */ -#define SCB_HTCAP 0x10000 /* HT (MIMO) capable device */ -#define SCB_IS40 0x80000 /* 40MHz capable */ -#define SCB_STBCCAP 0x40000000 /* STBC Capable */ -#define SCB_WME(a) ((a)->flags & SCB_WMECAP)/* implies WME_ENAB */ -#define SCB_SEQNUM(scb, prio) ((scb)->seqnum[(prio)]) -#define SCB_PS(a) NULL -#define SCB_STBC_CAP(a) ((a)->flags & SCB_STBCCAP) -#define SCB_AMPDU(a) true -#endif /* _wlc_scb_h_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_stf.c b/drivers/staging/brcm80211/sys/wlc_stf.c deleted file mode 100644 index 10c9f447cdf0..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_stf.c +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define WLC_STF_SS_STBC_RX(wlc) (WLCISNPHY(wlc->band) && \ - NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6)) - -static s8 wlc_stf_stbc_rx_get(struct wlc_info *wlc); -static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val); -static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 val); -static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val); -static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val); - -static void _wlc_stf_phy_txant_upd(struct wlc_info *wlc); -static u16 _wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec); - -#define NSTS_1 1 -#define NSTS_2 2 -#define NSTS_3 3 -#define NSTS_4 4 -const u8 txcore_default[5] = { - (0), /* bitmap of the core enabled */ - (0x01), /* For Nsts = 1, enable core 1 */ - (0x03), /* For Nsts = 2, enable core 1 & 2 */ - (0x07), /* For Nsts = 3, enable core 1, 2 & 3 */ - (0x0f) /* For Nsts = 4, enable all cores */ -}; - -static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val) -{ - ASSERT((val == HT_CAP_RX_STBC_NO) - || (val == HT_CAP_RX_STBC_ONE_STREAM)); - - /* MIMOPHYs rev3-6 cannot receive STBC with only one rx core active */ - if (WLC_STF_SS_STBC_RX(wlc)) { - if ((wlc->stf->rxstreams == 1) && (val != HT_CAP_RX_STBC_NO)) - return; - } - - wlc->ht_cap.cap_info &= ~HT_CAP_RX_STBC_MASK; - wlc->ht_cap.cap_info |= (val << HT_CAP_RX_STBC_SHIFT); - - if (wlc->pub->up) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - } -} - -/* every WLC_TEMPSENSE_PERIOD seconds temperature check to decide whether to turn on/off txchain */ -void wlc_tempsense_upd(struct wlc_info *wlc) -{ - wlc_phy_t *pi = wlc->band->pi; - uint active_chains, txchain; - - /* Check if the chip is too hot. Disable one Tx chain, if it is */ - /* high 4 bits are for Rx chain, low 4 bits are for Tx chain */ - active_chains = wlc_phy_stf_chain_active_get(pi); - txchain = active_chains & 0xf; - - if (wlc->stf->txchain == wlc->stf->hw_txchain) { - if (txchain && (txchain < wlc->stf->hw_txchain)) { - /* turn off 1 tx chain */ - wlc_stf_txchain_set(wlc, txchain, true); - } - } else if (wlc->stf->txchain < wlc->stf->hw_txchain) { - if (txchain == wlc->stf->hw_txchain) { - /* turn back on txchain */ - wlc_stf_txchain_set(wlc, txchain, true); - } - } -} - -void -wlc_stf_ss_algo_channel_get(struct wlc_info *wlc, u16 *ss_algo_channel, - chanspec_t chanspec) -{ - tx_power_t power; - u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id; - - /* Clear previous settings */ - *ss_algo_channel = 0; - - if (!wlc->pub->up) { - *ss_algo_channel = (u16) -1; - return; - } - - wlc_phy_txpower_get_current(wlc->band->pi, &power, - CHSPEC_CHANNEL(chanspec)); - - siso_mcs_id = (CHSPEC_IS40(chanspec)) ? - WL_TX_POWER_MCS40_SISO_FIRST : WL_TX_POWER_MCS20_SISO_FIRST; - cdd_mcs_id = (CHSPEC_IS40(chanspec)) ? - WL_TX_POWER_MCS40_CDD_FIRST : WL_TX_POWER_MCS20_CDD_FIRST; - stbc_mcs_id = (CHSPEC_IS40(chanspec)) ? - WL_TX_POWER_MCS40_STBC_FIRST : WL_TX_POWER_MCS20_STBC_FIRST; - - /* criteria to choose stf mode */ - - /* the "+3dbm (12 0.25db units)" is to account for the fact that with CDD, tx occurs - * on both chains - */ - if (power.target[siso_mcs_id] > (power.target[cdd_mcs_id] + 12)) - setbit(ss_algo_channel, PHY_TXC1_MODE_SISO); - else - setbit(ss_algo_channel, PHY_TXC1_MODE_CDD); - - /* STBC is ORed into to algo channel as STBC requires per-packet SCB capability check - * so cannot be default mode of operation. One of SISO, CDD have to be set - */ - if (power.target[siso_mcs_id] <= (power.target[stbc_mcs_id] + 12)) - setbit(ss_algo_channel, PHY_TXC1_MODE_STBC); -} - -static s8 wlc_stf_stbc_rx_get(struct wlc_info *wlc) -{ - return (wlc->ht_cap.cap_info & HT_CAP_RX_STBC_MASK) - >> HT_CAP_RX_STBC_SHIFT; -} - -static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val) -{ - if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON)) { - return false; - } - - if ((int_val == ON) && (wlc->stf->txstreams == 1)) - return false; - - if ((int_val == OFF) || (wlc->stf->txstreams == 1) - || !WLC_STBC_CAP_PHY(wlc)) - wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC; - else - wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_TX_STBC; - - wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = (s8) int_val; - wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = (s8) int_val; - - return true; -} - -bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val) -{ - if ((int_val != HT_CAP_RX_STBC_NO) - && (int_val != HT_CAP_RX_STBC_ONE_STREAM)) { - return false; - } - - if (WLC_STF_SS_STBC_RX(wlc)) { - if ((int_val != HT_CAP_RX_STBC_NO) - && (wlc->stf->rxstreams == 1)) - return false; - } - - wlc_stf_stbc_rx_ht_update(wlc, int_val); - return true; -} - -static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 core_mask) -{ - WL_TRACE("wl%d: %s: Nsts %d core_mask %x\n", - wlc->pub->unit, __func__, Nsts, core_mask); - - ASSERT((Nsts > 0) && (Nsts <= MAX_STREAMS_SUPPORTED)); - - if (WLC_BITSCNT(core_mask) > wlc->stf->txstreams) { - core_mask = 0; - } - - if ((WLC_BITSCNT(core_mask) == wlc->stf->txstreams) && - ((core_mask & ~wlc->stf->txchain) - || !(core_mask & wlc->stf->txchain))) { - core_mask = wlc->stf->txchain; - } - - ASSERT(!core_mask || Nsts <= WLC_BITSCNT(core_mask)); - - wlc->stf->txcore[Nsts] = core_mask; - /* Nsts = 1..4, txcore index = 1..4 */ - if (Nsts == 1) { - /* Needs to update beacon and ucode generated response - * frames when 1 stream core map changed - */ - wlc->stf->phytxant = core_mask << PHY_TXC_ANT_SHIFT; - wlc_bmac_txant_set(wlc->hw, wlc->stf->phytxant); - if (wlc->clk) { - wlc_suspend_mac_and_wait(wlc); - wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec); - wlc_enable_mac(wlc); - } - } - - return BCME_OK; -} - -static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val) -{ - int i; - u8 core_mask = 0; - - WL_TRACE("wl%d: %s: val %x\n", wlc->pub->unit, __func__, val); - - wlc->stf->spatial_policy = (s8) val; - for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) { - core_mask = (val == MAX_SPATIAL_EXPANSION) ? - wlc->stf->txchain : txcore_default[i]; - wlc_stf_txcore_set(wlc, (u8) i, core_mask); - } - return BCME_OK; -} - -int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force) -{ - u8 txchain = (u8) int_val; - u8 txstreams; - uint i; - - if (wlc->stf->txchain == txchain) - return BCME_OK; - - if ((txchain & ~wlc->stf->hw_txchain) - || !(txchain & wlc->stf->hw_txchain)) - return BCME_RANGE; - - /* if nrate override is configured to be non-SISO STF mode, reject reducing txchain to 1 */ - txstreams = (u8) WLC_BITSCNT(txchain); - if (txstreams > MAX_STREAMS_SUPPORTED) - return BCME_RANGE; - - if (txstreams == 1) { - for (i = 0; i < NBANDS(wlc); i++) - if ((RSPEC_STF(wlc->bandstate[i]->rspec_override) != - PHY_TXC1_MODE_SISO) - || (RSPEC_STF(wlc->bandstate[i]->mrspec_override) != - PHY_TXC1_MODE_SISO)) { - if (!force) - return BCME_ERROR; - - /* over-write the override rspec */ - if (RSPEC_STF(wlc->bandstate[i]->rspec_override) - != PHY_TXC1_MODE_SISO) { - wlc->bandstate[i]->rspec_override = 0; - WL_ERROR("%s(): temp sense override non-SISO rspec_override\n", - __func__); - } - if (RSPEC_STF - (wlc->bandstate[i]->mrspec_override) != - PHY_TXC1_MODE_SISO) { - wlc->bandstate[i]->mrspec_override = 0; - WL_ERROR("%s(): temp sense override non-SISO mrspec_override\n", - __func__); - } - } - } - - wlc->stf->txchain = txchain; - wlc->stf->txstreams = txstreams; - wlc_stf_stbc_tx_set(wlc, wlc->band->band_stf_stbc_tx); - wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); - wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); - wlc->stf->txant = - (wlc->stf->txstreams == 1) ? ANT_TX_FORCE_0 : ANT_TX_DEF; - _wlc_stf_phy_txant_upd(wlc); - - wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, - wlc->stf->rxchain); - - for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) - wlc_stf_txcore_set(wlc, (u8) i, txcore_default[i]); - - return BCME_OK; -} - -int wlc_stf_rxchain_set(struct wlc_info *wlc, s32 int_val) -{ - u8 rxchain_cnt; - u8 rxchain = (u8) int_val; - u8 mimops_mode; - u8 old_rxchain, old_rxchain_cnt; - - if (wlc->stf->rxchain == rxchain) - return BCME_OK; - - if ((rxchain & ~wlc->stf->hw_rxchain) - || !(rxchain & wlc->stf->hw_rxchain)) - return BCME_RANGE; - - rxchain_cnt = (u8) WLC_BITSCNT(rxchain); - if (WLC_STF_SS_STBC_RX(wlc)) { - if ((rxchain_cnt == 1) - && (wlc_stf_stbc_rx_get(wlc) != HT_CAP_RX_STBC_NO)) - return BCME_RANGE; - } - - if (APSTA_ENAB(wlc->pub) && (wlc->pub->associated)) - return BCME_ASSOCIATED; - - old_rxchain = wlc->stf->rxchain; - old_rxchain_cnt = wlc->stf->rxstreams; - - wlc->stf->rxchain = rxchain; - wlc->stf->rxstreams = rxchain_cnt; - - if (rxchain_cnt != old_rxchain_cnt) { - mimops_mode = - (rxchain_cnt == 1) ? HT_CAP_MIMO_PS_ON : HT_CAP_MIMO_PS_OFF; - wlc->mimops_PM = mimops_mode; - if (AP_ENAB(wlc->pub)) { - wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, - wlc->stf->rxchain); - wlc_ht_mimops_cap_update(wlc, mimops_mode); - if (wlc->pub->associated) - wlc_mimops_action_ht_send(wlc, wlc->cfg, - mimops_mode); - return BCME_OK; - } - if (wlc->pub->associated) { - if (mimops_mode == HT_CAP_MIMO_PS_OFF) { - /* if mimops is off, turn on the Rx chain first */ - wlc_phy_stf_chain_set(wlc->band->pi, - wlc->stf->txchain, - wlc->stf->rxchain); - wlc_ht_mimops_cap_update(wlc, mimops_mode); - } - } else { - wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, - wlc->stf->rxchain); - wlc_ht_mimops_cap_update(wlc, mimops_mode); - } - } else if (old_rxchain != rxchain) - wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, - wlc->stf->rxchain); - - return BCME_OK; -} - -/* update wlc->stf->ss_opmode which represents the operational stf_ss mode we're using */ -int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band) -{ - int ret_code = 0; - u8 prev_stf_ss; - u8 upd_stf_ss; - - prev_stf_ss = wlc->stf->ss_opmode; - - /* NOTE: opmode can only be SISO or CDD as STBC is decided on a per-packet basis */ - if (WLC_STBC_CAP_PHY(wlc) && - wlc->stf->ss_algosel_auto - && (wlc->stf->ss_algo_channel != (u16) -1)) { - ASSERT(isset(&wlc->stf->ss_algo_channel, PHY_TXC1_MODE_CDD) - || isset(&wlc->stf->ss_algo_channel, - PHY_TXC1_MODE_SISO)); - upd_stf_ss = (wlc->stf->no_cddstbc || (wlc->stf->txstreams == 1) - || isset(&wlc->stf->ss_algo_channel, - PHY_TXC1_MODE_SISO)) ? PHY_TXC1_MODE_SISO - : PHY_TXC1_MODE_CDD; - } else { - if (wlc->band != band) - return ret_code; - upd_stf_ss = (wlc->stf->no_cddstbc - || (wlc->stf->txstreams == - 1)) ? PHY_TXC1_MODE_SISO : band-> - band_stf_ss_mode; - } - if (prev_stf_ss != upd_stf_ss) { - wlc->stf->ss_opmode = upd_stf_ss; - wlc_bmac_band_stf_ss_set(wlc->hw, upd_stf_ss); - } - - return ret_code; -} - -int wlc_stf_attach(struct wlc_info *wlc) -{ - wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_SISO; - wlc->bandstate[BAND_5G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_CDD; - - if (WLCISNPHY(wlc->band) && - (wlc_phy_txpower_hw_ctrl_get(wlc->band->pi) != PHY_TPC_HW_ON)) - wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = - PHY_TXC1_MODE_CDD; - wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); - wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); - - wlc_stf_stbc_rx_ht_update(wlc, HT_CAP_RX_STBC_NO); - wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF; - wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF; - - if (WLC_STBC_CAP_PHY(wlc)) { - wlc->stf->ss_algosel_auto = true; - wlc->stf->ss_algo_channel = (u16) -1; /* Init the default value */ - } - return 0; -} - -void wlc_stf_detach(struct wlc_info *wlc) -{ -} - -int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val) -{ - int bcmerror = BCME_OK; - - /* when there is only 1 tx_streams, don't allow to change the txant */ - if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1)) - return ((val == wlc->stf->txant) ? bcmerror : BCME_RANGE); - - switch (val) { - case -1: - val = ANT_TX_DEF; - break; - case 0: - val = ANT_TX_FORCE_0; - break; - case 1: - val = ANT_TX_FORCE_1; - break; - case 3: - val = ANT_TX_LAST_RX; - break; - default: - bcmerror = BCME_RANGE; - break; - } - - if (bcmerror == BCME_OK) - wlc->stf->txant = (s8) val; - - return bcmerror; - -} - -/* - * Centralized txant update function. call it whenever wlc->stf->txant and/or wlc->stf->txchain - * change - * - * Antennas are controlled by ucode indirectly, which drives PHY or GPIO to - * achieve various tx/rx antenna selection schemes - * - * legacy phy, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means auto(last rx) - * for NREV<3, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means last rx and - * do tx-antenna selection for SISO transmissions - * for NREV=3, bit 6 and bit _8_ means antenna 0 and 1 respectively, bit6+bit7 means last rx and - * do tx-antenna selection for SISO transmissions - * for NREV>=7, bit 6 and bit 7 mean antenna 0 and 1 respectively, nit6+bit7 means both cores active -*/ -static void _wlc_stf_phy_txant_upd(struct wlc_info *wlc) -{ - s8 txant; - - txant = (s8) wlc->stf->txant; - ASSERT(txant == ANT_TX_FORCE_0 || txant == ANT_TX_FORCE_1 - || txant == ANT_TX_LAST_RX); - - if (WLC_PHY_11N_CAP(wlc->band)) { - if (txant == ANT_TX_FORCE_0) { - wlc->stf->phytxant = PHY_TXC_ANT_0; - } else if (txant == ANT_TX_FORCE_1) { - wlc->stf->phytxant = PHY_TXC_ANT_1; - - if (WLCISNPHY(wlc->band) && - NREV_GE(wlc->band->phyrev, 3) - && NREV_LT(wlc->band->phyrev, 7)) { - wlc->stf->phytxant = PHY_TXC_ANT_2; - } - } else { - if (WLCISLCNPHY(wlc->band) || WLCISSSLPNPHY(wlc->band)) - wlc->stf->phytxant = PHY_TXC_LCNPHY_ANT_LAST; - else { - /* keep this assert to catch out of sync wlc->stf->txcore */ - ASSERT(wlc->stf->txchain > 0); - wlc->stf->phytxant = - wlc->stf->txchain << PHY_TXC_ANT_SHIFT; - } - } - } else { - if (txant == ANT_TX_FORCE_0) - wlc->stf->phytxant = PHY_TXC_OLD_ANT_0; - else if (txant == ANT_TX_FORCE_1) - wlc->stf->phytxant = PHY_TXC_OLD_ANT_1; - else - wlc->stf->phytxant = PHY_TXC_OLD_ANT_LAST; - } - - wlc_bmac_txant_set(wlc->hw, wlc->stf->phytxant); -} - -void wlc_stf_phy_txant_upd(struct wlc_info *wlc) -{ - _wlc_stf_phy_txant_upd(wlc); -} - -void wlc_stf_phy_chain_calc(struct wlc_info *wlc) -{ - /* get available rx/tx chains */ - wlc->stf->hw_txchain = (u8) getintvar(wlc->pub->vars, "txchain"); - wlc->stf->hw_rxchain = (u8) getintvar(wlc->pub->vars, "rxchain"); - - /* these parameter are intended to be used for all PHY types */ - if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) { - if (WLCISNPHY(wlc->band)) { - wlc->stf->hw_txchain = TXCHAIN_DEF_NPHY; - } else { - wlc->stf->hw_txchain = TXCHAIN_DEF; - } - } - - wlc->stf->txchain = wlc->stf->hw_txchain; - wlc->stf->txstreams = (u8) WLC_BITSCNT(wlc->stf->hw_txchain); - - if (wlc->stf->hw_rxchain == 0 || wlc->stf->hw_rxchain == 0xf) { - if (WLCISNPHY(wlc->band)) { - wlc->stf->hw_rxchain = RXCHAIN_DEF_NPHY; - } else { - wlc->stf->hw_rxchain = RXCHAIN_DEF; - } - } - - wlc->stf->rxchain = wlc->stf->hw_rxchain; - wlc->stf->rxstreams = (u8) WLC_BITSCNT(wlc->stf->hw_rxchain); - - /* initialize the txcore table */ - bcopy(txcore_default, wlc->stf->txcore, sizeof(wlc->stf->txcore)); - - /* default spatial_policy */ - wlc->stf->spatial_policy = MIN_SPATIAL_EXPANSION; - wlc_stf_spatial_policy_set(wlc, MIN_SPATIAL_EXPANSION); -} - -static u16 _wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec) -{ - u16 phytxant = wlc->stf->phytxant; - - if (RSPEC_STF(rspec) != PHY_TXC1_MODE_SISO) { - ASSERT(wlc->stf->txstreams > 1); - phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT; - } else if (wlc->stf->txant == ANT_TX_DEF) - phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT; - phytxant &= PHY_TXC_ANT_MASK; - return phytxant; -} - -u16 wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec) -{ - return _wlc_stf_phytxchain_sel(wlc, rspec); -} - -u16 wlc_stf_d11hdrs_phyctl_txant(struct wlc_info *wlc, ratespec_t rspec) -{ - u16 phytxant = wlc->stf->phytxant; - u16 mask = PHY_TXC_ANT_MASK; - - /* for non-siso rates or default setting, use the available chains */ - if (WLCISNPHY(wlc->band)) { - ASSERT(wlc->stf->txchain != 0); - phytxant = _wlc_stf_phytxchain_sel(wlc, rspec); - mask = PHY_TXC_HTANT_MASK; - } - phytxant |= phytxant & mask; - return phytxant; -} diff --git a/drivers/staging/brcm80211/sys/wlc_stf.h b/drivers/staging/brcm80211/sys/wlc_stf.h deleted file mode 100644 index 8de6382e620d..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_stf.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_stf_h_ -#define _wlc_stf_h_ - -#define MIN_SPATIAL_EXPANSION 0 -#define MAX_SPATIAL_EXPANSION 1 - -extern int wlc_stf_attach(struct wlc_info *wlc); -extern void wlc_stf_detach(struct wlc_info *wlc); - -extern void wlc_tempsense_upd(struct wlc_info *wlc); -extern void wlc_stf_ss_algo_channel_get(struct wlc_info *wlc, - u16 *ss_algo_channel, - chanspec_t chanspec); -extern int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band); -extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc); -extern int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force); -extern int wlc_stf_rxchain_set(struct wlc_info *wlc, s32 int_val); -extern bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val); - -extern int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val); -extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc); -extern void wlc_stf_phy_chain_calc(struct wlc_info *wlc); -extern u16 wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec); -extern u16 wlc_stf_d11hdrs_phyctl_txant(struct wlc_info *wlc, ratespec_t rspec); -extern u16 wlc_stf_spatial_expansion_get(struct wlc_info *wlc, - ratespec_t rspec); -#endif /* _wlc_stf_h_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_types.h b/drivers/staging/brcm80211/sys/wlc_types.h deleted file mode 100644 index df6e04c6ac58..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_types.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_types_h_ -#define _wlc_types_h_ - -/* forward declarations */ - -struct wlc_info; -struct wlc_hw_info; -struct wlc_if; -struct wl_if; -struct ampdu_info; -struct antsel_info; -struct bmac_pmq; - -struct d11init; - -#ifndef _hnddma_pub_ -#define _hnddma_pub_ -struct hnddma_pub; -#endif /* _hnddma_pub_ */ - -#endif /* _wlc_types_h_ */ diff --git a/drivers/staging/brcm80211/util/aiutils.c b/drivers/staging/brcm80211/util/aiutils.c index ddd2f9d64c20..b6e7a9e97379 100644 --- a/drivers/staging/brcm80211/util/aiutils.c +++ b/drivers/staging/brcm80211/util/aiutils.c @@ -18,9 +18,6 @@ #include #include #include -#ifdef BRCM_FULLMAC -#include -#endif #include #include #include diff --git a/drivers/staging/brcm80211/util/bcmwifi.c b/drivers/staging/brcm80211/util/bcmwifi.c index cb6f21ae36cc..b22d14b9aef4 100644 --- a/drivers/staging/brcm80211/util/bcmwifi.c +++ b/drivers/staging/brcm80211/util/bcmwifi.c @@ -15,9 +15,6 @@ */ #include #include -#ifdef BRCM_FULLMAC -#include -#endif #include #include #include diff --git a/drivers/staging/brcm80211/util/hndpmu.c b/drivers/staging/brcm80211/util/hndpmu.c index 6cc59a895868..49d19a121f7b 100644 --- a/drivers/staging/brcm80211/util/hndpmu.c +++ b/drivers/staging/brcm80211/util/hndpmu.c @@ -18,9 +18,6 @@ #include #include #include -#ifdef BRCM_FULLMAC -#include -#endif #include #include #include diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index b66de9b35a5a..b0e7695097e8 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -18,9 +18,6 @@ #include #include #include -#ifdef BRCM_FULLMAC -#include -#endif #include #include #include -- cgit v1.2.3 From 5e72615c130d8fe9800711be2d713caeaa2d4a64 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 21 Jan 2011 10:54:49 +0100 Subject: staging: brcm80211: cleanup on the brcm80211 include directory moved several files to specific source directory as these do not need to be shared between drivers. Also removed some unused include files from the include directory. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmcdc.h | 98 ++ drivers/staging/brcm80211/brcmfmac/bcmsdbus.h | 113 ++ drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h | 110 ++ drivers/staging/brcm80211/brcmfmac/dhdioctl.h | 100 ++ .../staging/brcm80211/brcmfmac/hndrte_armtrap.h | 75 + drivers/staging/brcm80211/brcmfmac/hndrte_cons.h | 57 + drivers/staging/brcm80211/brcmfmac/msgtrace.h | 61 + drivers/staging/brcm80211/brcmfmac/sdioh.h | 63 + drivers/staging/brcm80211/brcmfmac/sdiovar.h | 38 + drivers/staging/brcm80211/brcmsmac/Makefile | 1 + drivers/staging/brcm80211/brcmsmac/d11.h | 1765 ++++++++++++++++++++ drivers/staging/brcm80211/brcmsmac/sbhndpio.h | 52 + drivers/staging/brcm80211/brcmsmac/sys/wlc_event.c | 3 - drivers/staging/brcm80211/include/bcmcdc.h | 98 -- drivers/staging/brcm80211/include/bcmsdbus.h | 113 -- drivers/staging/brcm80211/include/bcmsdh_sdmmc.h | 110 -- drivers/staging/brcm80211/include/bcmsrom_tbl.h | 583 ------- drivers/staging/brcm80211/include/d11.h | 1765 -------------------- drivers/staging/brcm80211/include/dhdioctl.h | 100 -- drivers/staging/brcm80211/include/hndrte_armtrap.h | 75 - drivers/staging/brcm80211/include/hndrte_cons.h | 57 - drivers/staging/brcm80211/include/msgtrace.h | 61 - drivers/staging/brcm80211/include/pci_core.h | 122 -- drivers/staging/brcm80211/include/rpc_osl.h | 33 - drivers/staging/brcm80211/include/sbhndpio.h | 52 - drivers/staging/brcm80211/include/sbpcmcia.h | 217 --- drivers/staging/brcm80211/include/sbsocram.h | 175 -- drivers/staging/brcm80211/include/sdioh.h | 63 - drivers/staging/brcm80211/include/sdiovar.h | 38 - drivers/staging/brcm80211/include/spid.h | 155 -- drivers/staging/brcm80211/util/bcmsrom_tbl.h | 583 +++++++ drivers/staging/brcm80211/util/pci_core.h | 122 ++ drivers/staging/brcm80211/util/sbpcmcia.h | 217 +++ drivers/staging/brcm80211/util/sbsocram.h | 175 ++ 34 files changed, 3630 insertions(+), 3820 deletions(-) create mode 100644 drivers/staging/brcm80211/brcmfmac/bcmcdc.h create mode 100644 drivers/staging/brcm80211/brcmfmac/bcmsdbus.h create mode 100644 drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h create mode 100644 drivers/staging/brcm80211/brcmfmac/dhdioctl.h create mode 100644 drivers/staging/brcm80211/brcmfmac/hndrte_armtrap.h create mode 100644 drivers/staging/brcm80211/brcmfmac/hndrte_cons.h create mode 100644 drivers/staging/brcm80211/brcmfmac/msgtrace.h create mode 100644 drivers/staging/brcm80211/brcmfmac/sdioh.h create mode 100644 drivers/staging/brcm80211/brcmfmac/sdiovar.h create mode 100644 drivers/staging/brcm80211/brcmsmac/d11.h create mode 100644 drivers/staging/brcm80211/brcmsmac/sbhndpio.h delete mode 100644 drivers/staging/brcm80211/include/bcmcdc.h delete mode 100644 drivers/staging/brcm80211/include/bcmsdbus.h delete mode 100644 drivers/staging/brcm80211/include/bcmsdh_sdmmc.h delete mode 100644 drivers/staging/brcm80211/include/bcmsrom_tbl.h delete mode 100644 drivers/staging/brcm80211/include/d11.h delete mode 100644 drivers/staging/brcm80211/include/dhdioctl.h delete mode 100644 drivers/staging/brcm80211/include/hndrte_armtrap.h delete mode 100644 drivers/staging/brcm80211/include/hndrte_cons.h delete mode 100644 drivers/staging/brcm80211/include/msgtrace.h delete mode 100644 drivers/staging/brcm80211/include/pci_core.h delete mode 100644 drivers/staging/brcm80211/include/rpc_osl.h delete mode 100644 drivers/staging/brcm80211/include/sbhndpio.h delete mode 100644 drivers/staging/brcm80211/include/sbpcmcia.h delete mode 100644 drivers/staging/brcm80211/include/sbsocram.h delete mode 100644 drivers/staging/brcm80211/include/sdioh.h delete mode 100644 drivers/staging/brcm80211/include/sdiovar.h delete mode 100644 drivers/staging/brcm80211/include/spid.h create mode 100644 drivers/staging/brcm80211/util/bcmsrom_tbl.h create mode 100644 drivers/staging/brcm80211/util/pci_core.h create mode 100644 drivers/staging/brcm80211/util/sbpcmcia.h create mode 100644 drivers/staging/brcm80211/util/sbsocram.h (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/bcmcdc.h b/drivers/staging/brcm80211/brcmfmac/bcmcdc.h new file mode 100644 index 000000000000..ed4c4a517eca --- /dev/null +++ b/drivers/staging/brcm80211/brcmfmac/bcmcdc.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include + +typedef struct cdc_ioctl { + u32 cmd; /* ioctl command value */ + u32 len; /* lower 16: output buflen; upper 16: + input buflen (excludes header) */ + u32 flags; /* flag defns given below */ + u32 status; /* status code returned from the device */ +} cdc_ioctl_t; + +/* Max valid buffer size that can be sent to the dongle */ +#define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN) + +/* len field is divided into input and output buffer lengths */ +#define CDCL_IOC_OUTLEN_MASK 0x0000FFFF /* maximum or expected + response length, */ + /* excluding IOCTL header */ +#define CDCL_IOC_OUTLEN_SHIFT 0 +#define CDCL_IOC_INLEN_MASK 0xFFFF0000 /* input buffer length, + excluding IOCTL header */ +#define CDCL_IOC_INLEN_SHIFT 16 + +/* CDC flag definitions */ +#define CDCF_IOC_ERROR 0x01 /* 0=success, 1=ioctl cmd failed */ +#define CDCF_IOC_SET 0x02 /* 0=get, 1=set cmd */ +#define CDCF_IOC_IF_MASK 0xF000 /* I/F index */ +#define CDCF_IOC_IF_SHIFT 12 +#define CDCF_IOC_ID_MASK 0xFFFF0000 /* used to uniquely id an ioctl + req/resp pairing */ +#define CDCF_IOC_ID_SHIFT 16 /* # of bits of shift for ID Mask */ + +#define CDC_IOC_IF_IDX(flags) \ + (((flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT) +#define CDC_IOC_ID(flags) \ + (((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT) + +#define CDC_GET_IF_IDX(hdr) \ + ((int)((((hdr)->flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT)) +#define CDC_SET_IF_IDX(hdr, idx) \ + ((hdr)->flags = (((hdr)->flags & ~CDCF_IOC_IF_MASK) | \ + ((idx) << CDCF_IOC_IF_SHIFT))) + +/* + * BDC header + * + * The BDC header is used on data packets to convey priority across USB. + */ + +#define BDC_HEADER_LEN 4 + +#define BDC_PROTO_VER 1 /* Protocol version */ + +#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */ +#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */ + +#define BDC_FLAG__UNUSED 0x03 /* Unassigned */ +#define BDC_FLAG_SUM_GOOD 0x04 /* Dongle has verified good + RX checksums */ +#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */ + +#define BDC_PRIORITY_MASK 0x7 + +#define BDC_FLAG2_FC_FLAG 0x10 /* flag to indicate if pkt contains */ + /* FLOW CONTROL info only */ +#define BDC_PRIORITY_FC_SHIFT 4 /* flow control info shift */ + +#define BDC_FLAG2_IF_MASK 0x0f /* APSTA: interface on which the + packet was received */ +#define BDC_FLAG2_IF_SHIFT 0 + +#define BDC_GET_IF_IDX(hdr) \ + ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT)) +#define BDC_SET_IF_IDX(hdr, idx) \ + ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \ + ((idx) << BDC_FLAG2_IF_SHIFT))) + +struct bdc_header { + u8 flags; /* Flags */ + u8 priority; /* 802.1d Priority 0:2 bits, 4:7 flow + control info for usb */ + u8 flags2; + u8 rssi; +}; diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h b/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h new file mode 100644 index 000000000000..89059dd8088b --- /dev/null +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _sdio_api_h_ +#define _sdio_api_h_ + +#define SDIOH_API_RC_SUCCESS (0x00) +#define SDIOH_API_RC_FAIL (0x01) +#define SDIOH_API_SUCCESS(status) (status == 0) + +#define SDIOH_READ 0 /* Read request */ +#define SDIOH_WRITE 1 /* Write request */ + +#define SDIOH_DATA_FIX 0 /* Fixed addressing */ +#define SDIOH_DATA_INC 1 /* Incremental addressing */ + +#define SDIOH_CMD_TYPE_NORMAL 0 /* Normal command */ +#define SDIOH_CMD_TYPE_APPEND 1 /* Append command */ +#define SDIOH_CMD_TYPE_CUTTHRU 2 /* Cut-through command */ + +#define SDIOH_DATA_PIO 0 /* PIO mode */ +#define SDIOH_DATA_DMA 1 /* DMA mode */ + +typedef int SDIOH_API_RC; + +/* SDio Host structure */ +typedef struct sdioh_info sdioh_info_t; + +/* callback function, taking one arg */ +typedef void (*sdioh_cb_fn_t) (void *); + +/* attach, return handler on success, NULL if failed. + * The handler shall be provided by all subsequent calls. No local cache + * cfghdl points to the starting address of pci device mapped memory + */ +extern sdioh_info_t *sdioh_attach(struct osl_info *osh, void *cfghdl, uint irq); +extern SDIOH_API_RC sdioh_detach(struct osl_info *osh, sdioh_info_t *si); +extern SDIOH_API_RC sdioh_interrupt_register(sdioh_info_t *si, + sdioh_cb_fn_t fn, void *argh); +extern SDIOH_API_RC sdioh_interrupt_deregister(sdioh_info_t *si); + +/* query whether SD interrupt is enabled or not */ +extern SDIOH_API_RC sdioh_interrupt_query(sdioh_info_t *si, bool *onoff); + +/* enable or disable SD interrupt */ +extern SDIOH_API_RC sdioh_interrupt_set(sdioh_info_t *si, bool enable_disable); + +#if defined(BCMDBG) +extern bool sdioh_interrupt_pending(sdioh_info_t *si); +#endif + +extern int sdioh_claim_host_and_lock(sdioh_info_t *si); +extern int sdioh_release_host_and_unlock(sdioh_info_t *si); + +/* read or write one byte using cmd52 */ +extern SDIOH_API_RC sdioh_request_byte(sdioh_info_t *si, uint rw, uint fnc, + uint addr, u8 *byte); + +/* read or write 2/4 bytes using cmd53 */ +extern SDIOH_API_RC sdioh_request_word(sdioh_info_t *si, uint cmd_type, + uint rw, uint fnc, uint addr, + u32 *word, uint nbyte); + +/* read or write any buffer using cmd53 */ +extern SDIOH_API_RC sdioh_request_buffer(sdioh_info_t *si, uint pio_dma, + uint fix_inc, uint rw, uint fnc_num, + u32 addr, uint regwidth, + u32 buflen, u8 *buffer, + struct sk_buff *pkt); + +/* get cis data */ +extern SDIOH_API_RC sdioh_cis_read(sdioh_info_t *si, uint fuc, u8 *cis, + u32 length); + +extern SDIOH_API_RC sdioh_cfg_read(sdioh_info_t *si, uint fuc, u32 addr, + u8 *data); +extern SDIOH_API_RC sdioh_cfg_write(sdioh_info_t *si, uint fuc, u32 addr, + u8 *data); + +/* query number of io functions */ +extern uint sdioh_query_iofnum(sdioh_info_t *si); + +/* handle iovars */ +extern int sdioh_iovar_op(sdioh_info_t *si, const char *name, + void *params, int plen, void *arg, int len, bool set); + +/* Issue abort to the specified function and clear controller as needed */ +extern int sdioh_abort(sdioh_info_t *si, uint fnc); + +/* Start and Stop SDIO without re-enumerating the SD card. */ +extern int sdioh_start(sdioh_info_t *si, int stage); +extern int sdioh_stop(sdioh_info_t *si); + +/* Reset and re-initialize the device */ +extern int sdioh_sdio_reset(sdioh_info_t *si); + +/* Helper function */ +void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh); + +#endif /* _sdio_api_h_ */ diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h new file mode 100644 index 000000000000..4d671ddb3af1 --- /dev/null +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __BCMSDH_SDMMC_H__ +#define __BCMSDH_SDMMC_H__ + +#ifdef BCMDBG +#define sd_err(x) do { if ((sd_msglevel & SDH_ERROR_VAL) && net_ratelimit()) printf x; } while (0) +#define sd_trace(x) do { if ((sd_msglevel & SDH_TRACE_VAL) && net_ratelimit()) printf x; } while (0) +#define sd_info(x) do { if ((sd_msglevel & SDH_INFO_VAL) && net_ratelimit()) printf x; } while (0) +#define sd_debug(x) do { if ((sd_msglevel & SDH_DEBUG_VAL) && net_ratelimit()) printf x; } while (0) +#define sd_data(x) do { if ((sd_msglevel & SDH_DATA_VAL) && net_ratelimit()) printf x; } while (0) +#define sd_ctrl(x) do { if ((sd_msglevel & SDH_CTRL_VAL) && net_ratelimit()) printf x; } while (0) +#else +#define sd_err(x) +#define sd_trace(x) +#define sd_info(x) +#define sd_debug(x) +#define sd_data(x) +#define sd_ctrl(x) +#endif + +/* Allocate/init/free per-OS private data */ +extern int sdioh_sdmmc_osinit(sdioh_info_t *sd); +extern void sdioh_sdmmc_osfree(sdioh_info_t *sd); + +#define BLOCK_SIZE_64 64 +#define BLOCK_SIZE_512 512 +#define BLOCK_SIZE_4318 64 +#define BLOCK_SIZE_4328 512 + +/* internal return code */ +#define SUCCESS 0 +#define ERROR 1 + +/* private bus modes */ +#define SDIOH_MODE_SD4 2 +#define CLIENT_INTR 0x100 /* Get rid of this! */ + +struct sdioh_info { + struct osl_info *osh; /* osh handler */ + bool client_intr_enabled; /* interrupt connnected flag */ + bool intr_handler_valid; /* client driver interrupt handler valid */ + sdioh_cb_fn_t intr_handler; /* registered interrupt handler */ + void *intr_handler_arg; /* argument to call interrupt handler */ + u16 intmask; /* Current active interrupts */ + void *sdos_info; /* Pointer to per-OS private data */ + + uint irq; /* Client irq */ + int intrcount; /* Client interrupts */ + bool sd_use_dma; /* DMA on CMD53 */ + bool sd_blockmode; /* sd_blockmode == false => 64 Byte Cmd 53s. */ + /* Must be on for sd_multiblock to be effective */ + bool use_client_ints; /* If this is false, make sure to restore */ + int sd_mode; /* SD1/SD4/SPI */ + int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */ + u8 num_funcs; /* Supported funcs on client */ + u32 com_cis_ptr; + u32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; + uint max_dma_len; + uint max_dma_descriptors; /* DMA Descriptors supported by this controller. */ + /* SDDMA_DESCRIPTOR SGList[32]; *//* Scatter/Gather DMA List */ +}; + +/************************************************************ + * Internal interfaces: per-port references into bcmsdh_sdmmc.c + */ + +/* Global message bits */ +extern uint sd_msglevel; + +/* OS-independent interrupt handler */ +extern bool check_client_intr(sdioh_info_t *sd); + +/* Core interrupt enable/disable of device interrupts */ +extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd); +extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd); + +/************************************************************** + * Internal interfaces: bcmsdh_sdmmc.c references to per-port code + */ + +/* Register mapping routines */ +extern u32 *sdioh_sdmmc_reg_map(struct osl_info *osh, s32 addr, int size); +extern void sdioh_sdmmc_reg_unmap(struct osl_info *osh, s32 addr, int size); + +/* Interrupt (de)registration routines */ +extern int sdioh_sdmmc_register_irq(sdioh_info_t *sd, uint irq); +extern void sdioh_sdmmc_free_irq(uint irq, sdioh_info_t *sd); + +typedef struct _BCMSDH_SDMMC_INSTANCE { + sdioh_info_t *sd; + struct sdio_func *func[SDIOD_MAX_IOFUNCS]; + u32 host_claimed; +} BCMSDH_SDMMC_INSTANCE, *PBCMSDH_SDMMC_INSTANCE; + +#endif /* __BCMSDH_SDMMC_H__ */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhdioctl.h b/drivers/staging/brcm80211/brcmfmac/dhdioctl.h new file mode 100644 index 000000000000..f0ba53558ccd --- /dev/null +++ b/drivers/staging/brcm80211/brcmfmac/dhdioctl.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _dhdioctl_h_ +#define _dhdioctl_h_ + +/* Linux network driver ioctl encoding */ +typedef struct dhd_ioctl { + uint cmd; /* common ioctl definition */ + void *buf; /* pointer to user buffer */ + uint len; /* length of user buffer */ + bool set; /* get or set request (optional) */ + uint used; /* bytes read or written (optional) */ + uint needed; /* bytes needed (optional) */ + uint driver; /* to identify target driver */ +} dhd_ioctl_t; + +/* per-driver magic numbers */ +#define DHD_IOCTL_MAGIC 0x00444944 + +/* bump this number if you change the ioctl interface */ +#define DHD_IOCTL_VERSION 1 + +#define DHD_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */ +#define DHD_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */ + +/* common ioctl definitions */ +#define DHD_GET_MAGIC 0 +#define DHD_GET_VERSION 1 +#define DHD_GET_VAR 2 +#define DHD_SET_VAR 3 + +/* message levels */ +#define DHD_ERROR_VAL 0x0001 +#define DHD_TRACE_VAL 0x0002 +#define DHD_INFO_VAL 0x0004 +#define DHD_DATA_VAL 0x0008 +#define DHD_CTL_VAL 0x0010 +#define DHD_TIMER_VAL 0x0020 +#define DHD_HDRS_VAL 0x0040 +#define DHD_BYTES_VAL 0x0080 +#define DHD_INTR_VAL 0x0100 +#define DHD_LOG_VAL 0x0200 +#define DHD_GLOM_VAL 0x0400 +#define DHD_EVENT_VAL 0x0800 +#define DHD_BTA_VAL 0x1000 +#define DHD_ISCAN_VAL 0x2000 + +#ifdef SDTEST +/* For pktgen iovar */ +typedef struct dhd_pktgen { + uint version; /* To allow structure change tracking */ + uint freq; /* Max ticks between tx/rx attempts */ + uint count; /* Test packets to send/rcv each attempt */ + uint print; /* Print counts every attempts */ + uint total; /* Total packets (or bursts) */ + uint minlen; /* Minimum length of packets to send */ + uint maxlen; /* Maximum length of packets to send */ + uint numsent; /* Count of test packets sent */ + uint numrcvd; /* Count of test packets received */ + uint numfail; /* Count of test send failures */ + uint mode; /* Test mode (type of test packets) */ + uint stop; /* Stop after this many tx failures */ +} dhd_pktgen_t; + +/* Version in case structure changes */ +#define DHD_PKTGEN_VERSION 2 + +/* Type of test packets to use */ +#define DHD_PKTGEN_ECHO 1 /* Send echo requests */ +#define DHD_PKTGEN_SEND 2 /* Send discard packets */ +#define DHD_PKTGEN_RXBURST 3 /* Request dongle send N packets */ +#define DHD_PKTGEN_RECV 4 /* Continuous rx from continuous + tx dongle */ +#endif /* SDTEST */ + +/* Enter idle immediately (no timeout) */ +#define DHD_IDLE_IMMEDIATE (-1) + +/* Values for idleclock iovar: other values are the sd_divisor to use + when idle */ +#define DHD_IDLE_ACTIVE 0 /* Do not request any SD clock change + when idle */ +#define DHD_IDLE_STOP (-1) /* Request SD clock be stopped + (and use SD1 mode) */ + +#endif /* _dhdioctl_h_ */ diff --git a/drivers/staging/brcm80211/brcmfmac/hndrte_armtrap.h b/drivers/staging/brcm80211/brcmfmac/hndrte_armtrap.h new file mode 100644 index 000000000000..28f092c9e027 --- /dev/null +++ b/drivers/staging/brcm80211/brcmfmac/hndrte_armtrap.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _hndrte_armtrap_h +#define _hndrte_armtrap_h + +/* ARM trap handling */ + +/* Trap types defined by ARM (see arminc.h) */ + +/* Trap locations in lo memory */ +#define TRAP_STRIDE 4 +#define FIRST_TRAP TR_RST +#define LAST_TRAP (TR_FIQ * TRAP_STRIDE) + +#if defined(__ARM_ARCH_4T__) +#define MAX_TRAP_TYPE (TR_FIQ + 1) +#elif defined(__ARM_ARCH_7M__) +#define MAX_TRAP_TYPE (TR_ISR + ARMCM3_NUMINTS) +#endif /* __ARM_ARCH_7M__ */ + +/* The trap structure is defined here as offsets for assembly */ +#define TR_TYPE 0x00 +#define TR_EPC 0x04 +#define TR_CPSR 0x08 +#define TR_SPSR 0x0c +#define TR_REGS 0x10 +#define TR_REG(n) (TR_REGS + (n) * 4) +#define TR_SP TR_REG(13) +#define TR_LR TR_REG(14) +#define TR_PC TR_REG(15) + +#define TRAP_T_SIZE 80 + +#ifndef _LANGUAGE_ASSEMBLY + +typedef struct _trap_struct { + u32 type; + u32 epc; + u32 cpsr; + u32 spsr; + u32 r0; + u32 r1; + u32 r2; + u32 r3; + u32 r4; + u32 r5; + u32 r6; + u32 r7; + u32 r8; + u32 r9; + u32 r10; + u32 r11; + u32 r12; + u32 r13; + u32 r14; + u32 pc; +} trap_t; + +#endif /* !_LANGUAGE_ASSEMBLY */ + +#endif /* _hndrte_armtrap_h */ diff --git a/drivers/staging/brcm80211/brcmfmac/hndrte_cons.h b/drivers/staging/brcm80211/brcmfmac/hndrte_cons.h new file mode 100644 index 000000000000..5caa53fb6552 --- /dev/null +++ b/drivers/staging/brcm80211/brcmfmac/hndrte_cons.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define CBUF_LEN (128) + +#define LOG_BUF_LEN 1024 + +typedef struct { + u32 buf; /* Can't be pointer on (64-bit) hosts */ + uint buf_size; + uint idx; + char *_buf_compat; /* Redundant pointer for backward compat. */ +} hndrte_log_t; + +typedef struct { + /* Virtual UART + * When there is no UART (e.g. Quickturn), + * the host should write a complete + * input line directly into cbuf and then write + * the length into vcons_in. + * This may also be used when there is a real UART + * (at risk of conflicting with + * the real UART). vcons_out is currently unused. + */ + volatile uint vcons_in; + volatile uint vcons_out; + + /* Output (logging) buffer + * Console output is written to a ring buffer log_buf at index log_idx. + * The host may read the output when it sees log_idx advance. + * Output will be lost if the output wraps around faster than the host + * polls. + */ + hndrte_log_t log; + + /* Console input line buffer + * Characters are read one at a time into cbuf + * until is received, then + * the buffer is processed as a command line. + * Also used for virtual UART. + */ + uint cbuf_idx; + char cbuf[CBUF_LEN]; +} hndrte_cons_t; diff --git a/drivers/staging/brcm80211/brcmfmac/msgtrace.h b/drivers/staging/brcm80211/brcmfmac/msgtrace.h new file mode 100644 index 000000000000..d654671a5a30 --- /dev/null +++ b/drivers/staging/brcm80211/brcmfmac/msgtrace.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _MSGTRACE_H +#define _MSGTRACE_H + +#define MSGTRACE_VERSION 1 + +/* Message trace header */ +typedef struct msgtrace_hdr { + u8 version; + u8 spare; + u16 len; /* Len of the trace */ + u32 seqnum; /* Sequence number of message. Useful + * if the messsage has been lost + * because of DMA error or a bus reset + * (ex: SDIO Func2) + */ + u32 discarded_bytes; /* Number of discarded bytes because of + trace overflow */ + u32 discarded_printf; /* Number of discarded printf + because of trace overflow */ +} __attribute__((packed)) msgtrace_hdr_t; + +#define MSGTRACE_HDRLEN sizeof(msgtrace_hdr_t) + +/* The hbus driver generates traces when sending a trace message. + * This causes endless traces. + * This flag must be set to true in any hbus traces. + * The flag is reset in the function msgtrace_put. + * This prevents endless traces but generates hasardous + * lost of traces only in bus device code. + * It is recommendat to set this flag in macro SD_TRACE + * but not in SD_ERROR for avoiding missing + * hbus error traces. hbus error trace should not generates endless traces. + */ +extern bool msgtrace_hbus_trace; + +typedef void (*msgtrace_func_send_t) (void *hdl1, void *hdl2, u8 *hdr, + u16 hdrlen, u8 *buf, + u16 buflen); + +extern void msgtrace_sent(void); +extern void msgtrace_put(char *buf, int count); +extern void msgtrace_init(void *hdl1, void *hdl2, + msgtrace_func_send_t func_send); + +#endif /* _MSGTRACE_H */ diff --git a/drivers/staging/brcm80211/brcmfmac/sdioh.h b/drivers/staging/brcm80211/brcmfmac/sdioh.h new file mode 100644 index 000000000000..f96aaf9cec74 --- /dev/null +++ b/drivers/staging/brcm80211/brcmfmac/sdioh.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _SDIOH_H +#define _SDIOH_H + +#define SD_SysAddr 0x000 +#define SD_BlockSize 0x004 +#define SD_BlockCount 0x006 +#define SD_Arg0 0x008 +#define SD_Arg1 0x00A +#define SD_TransferMode 0x00C +#define SD_Command 0x00E +#define SD_Response0 0x010 +#define SD_Response1 0x012 +#define SD_Response2 0x014 +#define SD_Response3 0x016 +#define SD_Response4 0x018 +#define SD_Response5 0x01A +#define SD_Response6 0x01C +#define SD_Response7 0x01E +#define SD_BufferDataPort0 0x020 +#define SD_BufferDataPort1 0x022 +#define SD_PresentState 0x024 +#define SD_HostCntrl 0x028 +#define SD_PwrCntrl 0x029 +#define SD_BlockGapCntrl 0x02A +#define SD_WakeupCntrl 0x02B +#define SD_ClockCntrl 0x02C +#define SD_TimeoutCntrl 0x02E +#define SD_SoftwareReset 0x02F +#define SD_IntrStatus 0x030 +#define SD_ErrorIntrStatus 0x032 +#define SD_IntrStatusEnable 0x034 +#define SD_ErrorIntrStatusEnable 0x036 +#define SD_IntrSignalEnable 0x038 +#define SD_ErrorIntrSignalEnable 0x03A +#define SD_CMD12ErrorStatus 0x03C +#define SD_Capabilities 0x040 +#define SD_Capabilities_Reserved 0x044 +#define SD_MaxCurCap 0x048 +#define SD_MaxCurCap_Reserved 0x04C +#define SD_ADMA_SysAddr 0x58 +#define SD_SlotInterruptStatus 0x0FC +#define SD_HostControllerVersion 0x0FE + +/* SD specific registers in PCI config space */ +#define SD_SlotInfo 0x40 + +#endif /* _SDIOH_H */ diff --git a/drivers/staging/brcm80211/brcmfmac/sdiovar.h b/drivers/staging/brcm80211/brcmfmac/sdiovar.h new file mode 100644 index 000000000000..d1cfa5f0a982 --- /dev/null +++ b/drivers/staging/brcm80211/brcmfmac/sdiovar.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _sdiovar_h_ +#define _sdiovar_h_ + +typedef struct sdreg { + int func; + int offset; + int value; +} sdreg_t; + +/* Common msglevel constants */ +#define SDH_ERROR_VAL 0x0001 /* Error */ +#define SDH_TRACE_VAL 0x0002 /* Trace */ +#define SDH_INFO_VAL 0x0004 /* Info */ +#define SDH_DEBUG_VAL 0x0008 /* Debug */ +#define SDH_DATA_VAL 0x0010 /* Data */ +#define SDH_CTRL_VAL 0x0020 /* Control Regs */ +#define SDH_LOG_VAL 0x0040 /* Enable bcmlog */ +#define SDH_DMA_VAL 0x0080 /* DMA */ + +#define NUM_PREV_TRANSACTIONS 16 + +#endif /* _sdiovar_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/Makefile b/drivers/staging/brcm80211/brcmsmac/Makefile index 910196a37353..e5dda8689890 100644 --- a/drivers/staging/brcm80211/brcmsmac/Makefile +++ b/drivers/staging/brcm80211/brcmsmac/Makefile @@ -25,6 +25,7 @@ ccflags-y := \ -DDBAND \ -DBCMDMA32 \ -DBCMNVRAMR \ + -Idrivers/staging/brcm80211/brcmsmac \ -Idrivers/staging/brcm80211/brcmsmac/sys \ -Idrivers/staging/brcm80211/brcmsmac/phy \ -Idrivers/staging/brcm80211/util \ diff --git a/drivers/staging/brcm80211/brcmsmac/d11.h b/drivers/staging/brcm80211/brcmsmac/d11.h new file mode 100644 index 000000000000..50883af62496 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/d11.h @@ -0,0 +1,1765 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _D11_H +#define _D11_H + +#ifndef WL_RSSI_ANT_MAX +#define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */ +#elif WL_RSSI_ANT_MAX != 4 +#error "WL_RSSI_ANT_MAX does not match" +#endif + +/* cpp contortions to concatenate w/arg prescan */ +#ifndef PAD +#define _PADLINE(line) pad ## line +#define _XSTR(line) _PADLINE(line) +#define PAD _XSTR(__LINE__) +#endif + +#define BCN_TMPL_LEN 512 /* length of the BCN template area */ + +/* RX FIFO numbers */ +#define RX_FIFO 0 /* data and ctl frames */ +#define RX_TXSTATUS_FIFO 3 /* RX fifo for tx status packages */ + +/* TX FIFO numbers using WME Access Classes */ +#define TX_AC_BK_FIFO 0 /* Access Category Background TX FIFO */ +#define TX_AC_BE_FIFO 1 /* Access Category Best-Effort TX FIFO */ +#define TX_AC_VI_FIFO 2 /* Access Class Video TX FIFO */ +#define TX_AC_VO_FIFO 3 /* Access Class Voice TX FIFO */ +#define TX_BCMC_FIFO 4 /* Broadcast/Multicast TX FIFO */ +#define TX_ATIM_FIFO 5 /* TX fifo for ATIM window info */ + +/* Addr is byte address used by SW; offset is word offset used by uCode */ + +/* Per AC TX limit settings */ +#define M_AC_TXLMT_BASE_ADDR (0x180 * 2) +#define M_AC_TXLMT_ADDR(_ac) (M_AC_TXLMT_BASE_ADDR + (2 * (_ac))) + +/* Legacy TX FIFO numbers */ +#define TX_DATA_FIFO TX_AC_BE_FIFO +#define TX_CTL_FIFO TX_AC_VO_FIFO + +typedef volatile struct { + u32 intstatus; + u32 intmask; +} intctrlregs_t; + +/* read: 32-bit register that can be read as 32-bit or as 2 16-bit + * write: only low 16b-it half can be written + */ +typedef volatile union { + u32 pmqhostdata; /* read only! */ + struct { + u16 pmqctrlstatus; /* read/write */ + u16 PAD; + } w; +} pmqreg_t; + +/* pio register set 2/4 bytes union for d11 fifo */ +typedef volatile union { + pio2regp_t b2; /* < corerev 8 */ + pio4regp_t b4; /* >= corerev 8 */ +} u_pioreg_t; + +/* dma/pio corerev < 11 */ +typedef volatile struct { + dma32regp_t dmaregs[8]; /* 0x200 - 0x2fc */ + u_pioreg_t pioregs[8]; /* 0x300 */ +} fifo32_t; + +/* dma/pio corerev >= 11 */ +typedef volatile struct { + dma64regs_t dmaxmt; /* dma tx */ + pio4regs_t piotx; /* pio tx */ + dma64regs_t dmarcv; /* dma rx */ + pio4regs_t piorx; /* pio rx */ +} fifo64_t; + +/* + * Host Interface Registers + * - primed from hnd_cores/dot11mac/systemC/registers/ihr.h + * - but definitely not complete + */ +typedef volatile struct _d11regs { + /* Device Control ("semi-standard host registers") */ + u32 PAD[3]; /* 0x0 - 0x8 */ + u32 biststatus; /* 0xC */ + u32 biststatus2; /* 0x10 */ + u32 PAD; /* 0x14 */ + u32 gptimer; /* 0x18 *//* for corerev >= 3 */ + u32 usectimer; /* 0x1c *//* for corerev >= 26 */ + + /* Interrupt Control *//* 0x20 */ + intctrlregs_t intctrlregs[8]; + + u32 PAD[40]; /* 0x60 - 0xFC */ + + /* tx fifos 6-7 and rx fifos 1-3 removed in corerev 5 */ + u32 intrcvlazy[4]; /* 0x100 - 0x10C */ + + u32 PAD[4]; /* 0x110 - 0x11c */ + + u32 maccontrol; /* 0x120 */ + u32 maccommand; /* 0x124 */ + u32 macintstatus; /* 0x128 */ + u32 macintmask; /* 0x12C */ + + /* Transmit Template Access */ + u32 tplatewrptr; /* 0x130 */ + u32 tplatewrdata; /* 0x134 */ + u32 PAD[2]; /* 0x138 - 0x13C */ + + /* PMQ registers */ + pmqreg_t pmqreg; /* 0x140 */ + u32 pmqpatl; /* 0x144 */ + u32 pmqpath; /* 0x148 */ + u32 PAD; /* 0x14C */ + + u32 chnstatus; /* 0x150 */ + u32 psmdebug; /* 0x154 *//* for corerev >= 3 */ + u32 phydebug; /* 0x158 *//* for corerev >= 3 */ + u32 machwcap; /* 0x15C *//* Corerev >= 13 */ + + /* Extended Internal Objects */ + u32 objaddr; /* 0x160 */ + u32 objdata; /* 0x164 */ + u32 PAD[2]; /* 0x168 - 0x16c */ + + /* New txstatus registers on corerev >= 5 */ + u32 frmtxstatus; /* 0x170 */ + u32 frmtxstatus2; /* 0x174 */ + u32 PAD[2]; /* 0x178 - 0x17c */ + + /* New TSF host access on corerev >= 3 */ + + u32 tsf_timerlow; /* 0x180 */ + u32 tsf_timerhigh; /* 0x184 */ + u32 tsf_cfprep; /* 0x188 */ + u32 tsf_cfpstart; /* 0x18c */ + u32 tsf_cfpmaxdur32; /* 0x190 */ + u32 PAD[3]; /* 0x194 - 0x19c */ + + u32 maccontrol1; /* 0x1a0 */ + u32 machwcap1; /* 0x1a4 */ + u32 PAD[14]; /* 0x1a8 - 0x1dc */ + + /* Clock control and hardware workarounds (corerev >= 13) */ + u32 clk_ctl_st; /* 0x1e0 */ + u32 hw_war; + u32 d11_phypllctl; /* 0x1e8 (corerev == 16), the phypll request/avail bits are + * moved to clk_ctl_st for corerev >= 17 + */ + u32 PAD[5]; /* 0x1ec - 0x1fc */ + + /* 0x200-0x37F dma/pio registers */ + volatile union { + fifo32_t f32regs; /* tx fifos 6-7 and rx fifos 1-3 (corerev < 5) */ + fifo64_t f64regs[6]; /* on corerev >= 11 */ + } fifo; + + /* FIFO diagnostic port access */ + dma32diag_t dmafifo; /* 0x380 - 0x38C */ + + u32 aggfifocnt; /* 0x390 */ + u32 aggfifodata; /* 0x394 */ + u32 PAD[16]; /* 0x398 - 0x3d4 */ + u16 radioregaddr; /* 0x3d8 */ + u16 radioregdata; /* 0x3da */ + + /* time delay between the change on rf disable input and radio shutdown corerev 10 */ + u32 rfdisabledly; /* 0x3DC */ + + /* PHY register access */ + u16 phyversion; /* 0x3e0 - 0x0 */ + u16 phybbconfig; /* 0x3e2 - 0x1 */ + u16 phyadcbias; /* 0x3e4 - 0x2 Bphy only */ + u16 phyanacore; /* 0x3e6 - 0x3 pwwrdwn on aphy */ + u16 phyrxstatus0; /* 0x3e8 - 0x4 */ + u16 phyrxstatus1; /* 0x3ea - 0x5 */ + u16 phycrsth; /* 0x3ec - 0x6 */ + u16 phytxerror; /* 0x3ee - 0x7 */ + u16 phychannel; /* 0x3f0 - 0x8 */ + u16 PAD[1]; /* 0x3f2 - 0x9 */ + u16 phytest; /* 0x3f4 - 0xa */ + u16 phy4waddr; /* 0x3f6 - 0xb */ + u16 phy4wdatahi; /* 0x3f8 - 0xc */ + u16 phy4wdatalo; /* 0x3fa - 0xd */ + u16 phyregaddr; /* 0x3fc - 0xe */ + u16 phyregdata; /* 0x3fe - 0xf */ + + /* IHR *//* 0x400 - 0x7FE */ + + /* RXE Block */ + u16 PAD[3]; /* 0x400 - 0x406 */ + u16 rcv_fifo_ctl; /* 0x406 */ + u16 PAD; /* 0x408 - 0x40a */ + u16 rcv_frm_cnt; /* 0x40a */ + u16 PAD[4]; /* 0x40a - 0x414 */ + u16 rssi; /* 0x414 */ + u16 PAD[5]; /* 0x414 - 0x420 */ + u16 rcm_ctl; /* 0x420 */ + u16 rcm_mat_data; /* 0x422 */ + u16 rcm_mat_mask; /* 0x424 */ + u16 rcm_mat_dly; /* 0x426 */ + u16 rcm_cond_mask_l; /* 0x428 */ + u16 rcm_cond_mask_h; /* 0x42A */ + u16 rcm_cond_dly; /* 0x42C */ + u16 PAD[1]; /* 0x42E */ + u16 ext_ihr_addr; /* 0x430 */ + u16 ext_ihr_data; /* 0x432 */ + u16 rxe_phyrs_2; /* 0x434 */ + u16 rxe_phyrs_3; /* 0x436 */ + u16 phy_mode; /* 0x438 */ + u16 rcmta_ctl; /* 0x43a */ + u16 rcmta_size; /* 0x43c */ + u16 rcmta_addr0; /* 0x43e */ + u16 rcmta_addr1; /* 0x440 */ + u16 rcmta_addr2; /* 0x442 */ + u16 PAD[30]; /* 0x444 - 0x480 */ + + /* PSM Block *//* 0x480 - 0x500 */ + + u16 PAD; /* 0x480 */ + u16 psm_maccontrol_h; /* 0x482 */ + u16 psm_macintstatus_l; /* 0x484 */ + u16 psm_macintstatus_h; /* 0x486 */ + u16 psm_macintmask_l; /* 0x488 */ + u16 psm_macintmask_h; /* 0x48A */ + u16 PAD; /* 0x48C */ + u16 psm_maccommand; /* 0x48E */ + u16 psm_brc; /* 0x490 */ + u16 psm_phy_hdr_param; /* 0x492 */ + u16 psm_postcard; /* 0x494 */ + u16 psm_pcard_loc_l; /* 0x496 */ + u16 psm_pcard_loc_h; /* 0x498 */ + u16 psm_gpio_in; /* 0x49A */ + u16 psm_gpio_out; /* 0x49C */ + u16 psm_gpio_oe; /* 0x49E */ + + u16 psm_bred_0; /* 0x4A0 */ + u16 psm_bred_1; /* 0x4A2 */ + u16 psm_bred_2; /* 0x4A4 */ + u16 psm_bred_3; /* 0x4A6 */ + u16 psm_brcl_0; /* 0x4A8 */ + u16 psm_brcl_1; /* 0x4AA */ + u16 psm_brcl_2; /* 0x4AC */ + u16 psm_brcl_3; /* 0x4AE */ + u16 psm_brpo_0; /* 0x4B0 */ + u16 psm_brpo_1; /* 0x4B2 */ + u16 psm_brpo_2; /* 0x4B4 */ + u16 psm_brpo_3; /* 0x4B6 */ + u16 psm_brwk_0; /* 0x4B8 */ + u16 psm_brwk_1; /* 0x4BA */ + u16 psm_brwk_2; /* 0x4BC */ + u16 psm_brwk_3; /* 0x4BE */ + + u16 psm_base_0; /* 0x4C0 */ + u16 psm_base_1; /* 0x4C2 */ + u16 psm_base_2; /* 0x4C4 */ + u16 psm_base_3; /* 0x4C6 */ + u16 psm_base_4; /* 0x4C8 */ + u16 psm_base_5; /* 0x4CA */ + u16 psm_base_6; /* 0x4CC */ + u16 psm_pc_reg_0; /* 0x4CE */ + u16 psm_pc_reg_1; /* 0x4D0 */ + u16 psm_pc_reg_2; /* 0x4D2 */ + u16 psm_pc_reg_3; /* 0x4D4 */ + u16 PAD[0xD]; /* 0x4D6 - 0x4DE */ + u16 psm_corectlsts; /* 0x4f0 *//* Corerev >= 13 */ + u16 PAD[0x7]; /* 0x4f2 - 0x4fE */ + + /* TXE0 Block *//* 0x500 - 0x580 */ + u16 txe_ctl; /* 0x500 */ + u16 txe_aux; /* 0x502 */ + u16 txe_ts_loc; /* 0x504 */ + u16 txe_time_out; /* 0x506 */ + u16 txe_wm_0; /* 0x508 */ + u16 txe_wm_1; /* 0x50A */ + u16 txe_phyctl; /* 0x50C */ + u16 txe_status; /* 0x50E */ + u16 txe_mmplcp0; /* 0x510 */ + u16 txe_mmplcp1; /* 0x512 */ + u16 txe_phyctl1; /* 0x514 */ + + u16 PAD[0x05]; /* 0x510 - 0x51E */ + + /* Transmit control */ + u16 xmtfifodef; /* 0x520 */ + u16 xmtfifo_frame_cnt; /* 0x522 *//* Corerev >= 16 */ + u16 xmtfifo_byte_cnt; /* 0x524 *//* Corerev >= 16 */ + u16 xmtfifo_head; /* 0x526 *//* Corerev >= 16 */ + u16 xmtfifo_rd_ptr; /* 0x528 *//* Corerev >= 16 */ + u16 xmtfifo_wr_ptr; /* 0x52A *//* Corerev >= 16 */ + u16 xmtfifodef1; /* 0x52C *//* Corerev >= 16 */ + + u16 PAD[0x09]; /* 0x52E - 0x53E */ + + u16 xmtfifocmd; /* 0x540 */ + u16 xmtfifoflush; /* 0x542 */ + u16 xmtfifothresh; /* 0x544 */ + u16 xmtfifordy; /* 0x546 */ + u16 xmtfifoprirdy; /* 0x548 */ + u16 xmtfiforqpri; /* 0x54A */ + u16 xmttplatetxptr; /* 0x54C */ + u16 PAD; /* 0x54E */ + u16 xmttplateptr; /* 0x550 */ + u16 smpl_clct_strptr; /* 0x552 *//* Corerev >= 22 */ + u16 smpl_clct_stpptr; /* 0x554 *//* Corerev >= 22 */ + u16 smpl_clct_curptr; /* 0x556 *//* Corerev >= 22 */ + u16 PAD[0x04]; /* 0x558 - 0x55E */ + u16 xmttplatedatalo; /* 0x560 */ + u16 xmttplatedatahi; /* 0x562 */ + + u16 PAD[2]; /* 0x564 - 0x566 */ + + u16 xmtsel; /* 0x568 */ + u16 xmttxcnt; /* 0x56A */ + u16 xmttxshmaddr; /* 0x56C */ + + u16 PAD[0x09]; /* 0x56E - 0x57E */ + + /* TXE1 Block */ + u16 PAD[0x40]; /* 0x580 - 0x5FE */ + + /* TSF Block */ + u16 PAD[0X02]; /* 0x600 - 0x602 */ + u16 tsf_cfpstrt_l; /* 0x604 */ + u16 tsf_cfpstrt_h; /* 0x606 */ + u16 PAD[0X05]; /* 0x608 - 0x610 */ + u16 tsf_cfppretbtt; /* 0x612 */ + u16 PAD[0XD]; /* 0x614 - 0x62C */ + u16 tsf_clk_frac_l; /* 0x62E */ + u16 tsf_clk_frac_h; /* 0x630 */ + u16 PAD[0X14]; /* 0x632 - 0x658 */ + u16 tsf_random; /* 0x65A */ + u16 PAD[0x05]; /* 0x65C - 0x664 */ + /* GPTimer 2 registers are corerev >= 3 */ + u16 tsf_gpt2_stat; /* 0x666 */ + u16 tsf_gpt2_ctr_l; /* 0x668 */ + u16 tsf_gpt2_ctr_h; /* 0x66A */ + u16 tsf_gpt2_val_l; /* 0x66C */ + u16 tsf_gpt2_val_h; /* 0x66E */ + u16 tsf_gptall_stat; /* 0x670 */ + u16 PAD[0x07]; /* 0x672 - 0x67E */ + + /* IFS Block */ + u16 ifs_sifs_rx_tx_tx; /* 0x680 */ + u16 ifs_sifs_nav_tx; /* 0x682 */ + u16 ifs_slot; /* 0x684 */ + u16 PAD; /* 0x686 */ + u16 ifs_ctl; /* 0x688 */ + u16 PAD[0x3]; /* 0x68a - 0x68F */ + u16 ifsstat; /* 0x690 */ + u16 ifsmedbusyctl; /* 0x692 */ + u16 iftxdur; /* 0x694 */ + u16 PAD[0x3]; /* 0x696 - 0x69b */ + /* EDCF support in dot11macs with corerevs >= 16 */ + u16 ifs_aifsn; /* 0x69c */ + u16 ifs_ctl1; /* 0x69e */ + + /* New slow clock registers on corerev >= 5 */ + u16 scc_ctl; /* 0x6a0 */ + u16 scc_timer_l; /* 0x6a2 */ + u16 scc_timer_h; /* 0x6a4 */ + u16 scc_frac; /* 0x6a6 */ + u16 scc_fastpwrup_dly; /* 0x6a8 */ + u16 scc_per; /* 0x6aa */ + u16 scc_per_frac; /* 0x6ac */ + u16 scc_cal_timer_l; /* 0x6ae */ + u16 scc_cal_timer_h; /* 0x6b0 */ + u16 PAD; /* 0x6b2 */ + + u16 PAD[0x26]; + + /* NAV Block */ + u16 nav_ctl; /* 0x700 */ + u16 navstat; /* 0x702 */ + u16 PAD[0x3e]; /* 0x702 - 0x77E */ + + /* WEP/PMQ Block *//* 0x780 - 0x7FE */ + u16 PAD[0x20]; /* 0x780 - 0x7BE */ + + u16 wepctl; /* 0x7C0 */ + u16 wepivloc; /* 0x7C2 */ + u16 wepivkey; /* 0x7C4 */ + u16 wepwkey; /* 0x7C6 */ + + u16 PAD[4]; /* 0x7C8 - 0x7CE */ + u16 pcmctl; /* 0X7D0 */ + u16 pcmstat; /* 0X7D2 */ + u16 PAD[6]; /* 0x7D4 - 0x7DE */ + + u16 pmqctl; /* 0x7E0 */ + u16 pmqstatus; /* 0x7E2 */ + u16 pmqpat0; /* 0x7E4 */ + u16 pmqpat1; /* 0x7E6 */ + u16 pmqpat2; /* 0x7E8 */ + + u16 pmqdat; /* 0x7EA */ + u16 pmqdator; /* 0x7EC */ + u16 pmqhst; /* 0x7EE */ + u16 pmqpath0; /* 0x7F0 */ + u16 pmqpath1; /* 0x7F2 */ + u16 pmqpath2; /* 0x7F4 */ + u16 pmqdath; /* 0x7F6 */ + + u16 PAD[0x04]; /* 0x7F8 - 0x7FE */ + + /* SHM *//* 0x800 - 0xEFE */ + u16 PAD[0x380]; /* 0x800 - 0xEFE */ + + /* SB configuration registers: 0xF00 */ + sbconfig_t sbconfig; /* sb config regs occupy top 256 bytes */ +} d11regs_t; + +#define PIHR_BASE 0x0400 /* byte address of packed IHR region */ + +/* biststatus */ +#define BT_DONE (1U << 31) /* bist done */ +#define BT_B2S (1 << 30) /* bist2 ram summary bit */ + +/* intstatus and intmask */ +#define I_PC (1 << 10) /* pci descriptor error */ +#define I_PD (1 << 11) /* pci data error */ +#define I_DE (1 << 12) /* descriptor protocol error */ +#define I_RU (1 << 13) /* receive descriptor underflow */ +#define I_RO (1 << 14) /* receive fifo overflow */ +#define I_XU (1 << 15) /* transmit fifo underflow */ +#define I_RI (1 << 16) /* receive interrupt */ +#define I_XI (1 << 24) /* transmit interrupt */ + +/* interrupt receive lazy */ +#define IRL_TO_MASK 0x00ffffff /* timeout */ +#define IRL_FC_MASK 0xff000000 /* frame count */ +#define IRL_FC_SHIFT 24 /* frame count */ + +/* maccontrol register */ +#define MCTL_GMODE (1U << 31) +#define MCTL_DISCARD_PMQ (1 << 30) +#define MCTL_WAKE (1 << 26) +#define MCTL_HPS (1 << 25) +#define MCTL_PROMISC (1 << 24) +#define MCTL_KEEPBADFCS (1 << 23) +#define MCTL_KEEPCONTROL (1 << 22) +#define MCTL_PHYLOCK (1 << 21) +#define MCTL_BCNS_PROMISC (1 << 20) +#define MCTL_LOCK_RADIO (1 << 19) +#define MCTL_AP (1 << 18) +#define MCTL_INFRA (1 << 17) +#define MCTL_BIGEND (1 << 16) +#define MCTL_GPOUT_SEL_MASK (3 << 14) +#define MCTL_GPOUT_SEL_SHIFT 14 +#define MCTL_EN_PSMDBG (1 << 13) +#define MCTL_IHR_EN (1 << 10) +#define MCTL_SHM_UPPER (1 << 9) +#define MCTL_SHM_EN (1 << 8) +#define MCTL_PSM_JMP_0 (1 << 2) +#define MCTL_PSM_RUN (1 << 1) +#define MCTL_EN_MAC (1 << 0) + +/* maccommand register */ +#define MCMD_BCN0VLD (1 << 0) +#define MCMD_BCN1VLD (1 << 1) +#define MCMD_DIRFRMQVAL (1 << 2) +#define MCMD_CCA (1 << 3) +#define MCMD_BG_NOISE (1 << 4) +#define MCMD_SKIP_SHMINIT (1 << 5) /* only used for simulation */ +#define MCMD_SAMPLECOLL MCMD_SKIP_SHMINIT /* reuse for sample collect */ + +/* macintstatus/macintmask */ +#define MI_MACSSPNDD (1 << 0) /* MAC has gracefully suspended */ +#define MI_BCNTPL (1 << 1) /* beacon template available */ +#define MI_TBTT (1 << 2) /* TBTT indication */ +#define MI_BCNSUCCESS (1 << 3) /* beacon successfully tx'd */ +#define MI_BCNCANCLD (1 << 4) /* beacon canceled (IBSS) */ +#define MI_ATIMWINEND (1 << 5) /* end of ATIM-window (IBSS) */ +#define MI_PMQ (1 << 6) /* PMQ entries available */ +#define MI_NSPECGEN_0 (1 << 7) /* non-specific gen-stat bits that are set by PSM */ +#define MI_NSPECGEN_1 (1 << 8) /* non-specific gen-stat bits that are set by PSM */ +#define MI_MACTXERR (1 << 9) /* MAC level Tx error */ +#define MI_NSPECGEN_3 (1 << 10) /* non-specific gen-stat bits that are set by PSM */ +#define MI_PHYTXERR (1 << 11) /* PHY Tx error */ +#define MI_PME (1 << 12) /* Power Management Event */ +#define MI_GP0 (1 << 13) /* General-purpose timer0 */ +#define MI_GP1 (1 << 14) /* General-purpose timer1 */ +#define MI_DMAINT (1 << 15) /* (ORed) DMA-interrupts */ +#define MI_TXSTOP (1 << 16) /* MAC has completed a TX FIFO Suspend/Flush */ +#define MI_CCA (1 << 17) /* MAC has completed a CCA measurement */ +#define MI_BG_NOISE (1 << 18) /* MAC has collected background noise samples */ +#define MI_DTIM_TBTT (1 << 19) /* MBSS DTIM TBTT indication */ +#define MI_PRQ (1 << 20) /* Probe response queue needs attention */ +#define MI_PWRUP (1 << 21) /* Radio/PHY has been powered back up. */ +#define MI_RESERVED3 (1 << 22) +#define MI_RESERVED2 (1 << 23) +#define MI_RESERVED1 (1 << 25) +#define MI_RFDISABLE (1 << 28) /* MAC detected a change on RF Disable input + * (corerev >= 10) + */ +#define MI_TFS (1 << 29) /* MAC has completed a TX (corerev >= 5) */ +#define MI_PHYCHANGED (1 << 30) /* A phy status change wrt G mode */ +#define MI_TO (1U << 31) /* general purpose timeout (corerev >= 3) */ + +/* Mac capabilities registers */ +/* machwcap */ +#define MCAP_TKIPMIC 0x80000000 /* TKIP MIC hardware present */ + +/* pmqhost data */ +#define PMQH_DATA_MASK 0xffff0000 /* data entry of head pmq entry */ +#define PMQH_BSSCFG 0x00100000 /* PM entry for BSS config */ +#define PMQH_PMOFF 0x00010000 /* PM Mode OFF: power save off */ +#define PMQH_PMON 0x00020000 /* PM Mode ON: power save on */ +#define PMQH_DASAT 0x00040000 /* Dis-associated or De-authenticated */ +#define PMQH_ATIMFAIL 0x00080000 /* ATIM not acknowledged */ +#define PMQH_DEL_ENTRY 0x00000001 /* delete head entry */ +#define PMQH_DEL_MULT 0x00000002 /* delete head entry to cur read pointer -1 */ +#define PMQH_OFLO 0x00000004 /* pmq overflow indication */ +#define PMQH_NOT_EMPTY 0x00000008 /* entries are present in pmq */ + +/* phydebug (corerev >= 3) */ +#define PDBG_CRS (1 << 0) /* phy is asserting carrier sense */ +#define PDBG_TXA (1 << 1) /* phy is taking xmit byte from mac this cycle */ +#define PDBG_TXF (1 << 2) /* mac is instructing the phy to transmit a frame */ +#define PDBG_TXE (1 << 3) /* phy is signalling a transmit Error to the mac */ +#define PDBG_RXF (1 << 4) /* phy detected the end of a valid frame preamble */ +#define PDBG_RXS (1 << 5) /* phy detected the end of a valid PLCP header */ +#define PDBG_RXFRG (1 << 6) /* rx start not asserted */ +#define PDBG_RXV (1 << 7) /* mac is taking receive byte from phy this cycle */ +#define PDBG_RFD (1 << 16) /* RF portion of the radio is disabled */ + +/* objaddr register */ +#define OBJADDR_SEL_MASK 0x000F0000 +#define OBJADDR_UCM_SEL 0x00000000 +#define OBJADDR_SHM_SEL 0x00010000 +#define OBJADDR_SCR_SEL 0x00020000 +#define OBJADDR_IHR_SEL 0x00030000 +#define OBJADDR_RCMTA_SEL 0x00040000 +#define OBJADDR_SRCHM_SEL 0x00060000 +#define OBJADDR_WINC 0x01000000 +#define OBJADDR_RINC 0x02000000 +#define OBJADDR_AUTO_INC 0x03000000 + +#define WEP_PCMADDR 0x07d4 +#define WEP_PCMDATA 0x07d6 + +/* frmtxstatus */ +#define TXS_V (1 << 0) /* valid bit */ +#define TXS_STATUS_MASK 0xffff +/* sw mask to map txstatus for corerevs <= 4 to be the same as for corerev > 4 */ +#define TXS_COMPAT_MASK 0x3 +#define TXS_COMPAT_SHIFT 1 +#define TXS_FID_MASK 0xffff0000 +#define TXS_FID_SHIFT 16 + +/* frmtxstatus2 */ +#define TXS_SEQ_MASK 0xffff +#define TXS_PTX_MASK 0xff0000 +#define TXS_PTX_SHIFT 16 +#define TXS_MU_MASK 0x01000000 +#define TXS_MU_SHIFT 24 + +/* clk_ctl_st, corerev >= 17 */ +#define CCS_ERSRC_REQ_D11PLL 0x00000100 /* d11 core pll request */ +#define CCS_ERSRC_REQ_PHYPLL 0x00000200 /* PHY pll request */ +#define CCS_ERSRC_AVAIL_D11PLL 0x01000000 /* d11 core pll available */ +#define CCS_ERSRC_AVAIL_PHYPLL 0x02000000 /* PHY pll available */ + +/* HT Cloclk Ctrl and Clock Avail for 4313 */ +#define CCS_ERSRC_REQ_HT 0x00000010 /* HT avail request */ +#define CCS_ERSRC_AVAIL_HT 0x00020000 /* HT clock available */ + +/* d11_pwrctl, corerev16 only */ +#define D11_PHYPLL_AVAIL_REQ 0x000010000 /* request PHY PLL resource */ +#define D11_PHYPLL_AVAIL_STS 0x001000000 /* PHY PLL is available */ + +/* tsf_cfprep register */ +#define CFPREP_CBI_MASK 0xffffffc0 +#define CFPREP_CBI_SHIFT 6 +#define CFPREP_CFPP 0x00000001 + +/* tx fifo sizes for corerev >= 9 */ +/* tx fifo sizes values are in terms of 256 byte blocks */ +#define TXFIFOCMD_RESET_MASK (1 << 15) /* reset */ +#define TXFIFOCMD_FIFOSEL_SHIFT 8 /* fifo */ +#define TXFIFO_FIFOTOP_SHIFT 8 /* fifo start */ + +#define TXFIFO_START_BLK16 65 /* Base address + 32 * 512 B/P */ +#define TXFIFO_START_BLK 6 /* Base address + 6 * 256 B */ +#define TXFIFO_SIZE_UNIT 256 /* one unit corresponds to 256 bytes */ +#define MBSS16_TEMPLMEM_MINBLKS 65 /* one unit corresponds to 256 bytes */ + +/* phy versions, PhyVersion:Revision field */ +#define PV_AV_MASK 0xf000 /* analog block version */ +#define PV_AV_SHIFT 12 /* analog block version bitfield offset */ +#define PV_PT_MASK 0x0f00 /* phy type */ +#define PV_PT_SHIFT 8 /* phy type bitfield offset */ +#define PV_PV_MASK 0x000f /* phy version */ +#define PHY_TYPE(v) ((v & PV_PT_MASK) >> PV_PT_SHIFT) + +/* phy types, PhyVersion:PhyType field */ +#define PHY_TYPE_N 4 /* N-Phy value */ +#define PHY_TYPE_SSN 6 /* SSLPN-Phy value */ +#define PHY_TYPE_LCN 8 /* LCN-Phy value */ +#define PHY_TYPE_LCNXN 9 /* LCNXN-Phy value */ +#define PHY_TYPE_NULL 0xf /* Invalid Phy value */ + +/* analog types, PhyVersion:AnalogType field */ +#define ANA_11N_013 5 + +/* 802.11a PLCP header def */ +typedef struct ofdm_phy_hdr ofdm_phy_hdr_t; +struct ofdm_phy_hdr { + u8 rlpt[3]; /* rate, length, parity, tail */ + u16 service; + u8 pad; +} __attribute__((packed)); + +#define D11A_PHY_HDR_GRATE(phdr) ((phdr)->rlpt[0] & 0x0f) +#define D11A_PHY_HDR_GRES(phdr) (((phdr)->rlpt[0] >> 4) & 0x01) +#define D11A_PHY_HDR_GLENGTH(phdr) (((u32 *)((phdr)->rlpt) >> 5) & 0x0fff) +#define D11A_PHY_HDR_GPARITY(phdr) (((phdr)->rlpt[3] >> 1) & 0x01) +#define D11A_PHY_HDR_GTAIL(phdr) (((phdr)->rlpt[3] >> 2) & 0x3f) + +/* rate encoded per 802.11a-1999 sec 17.3.4.1 */ +#define D11A_PHY_HDR_SRATE(phdr, rate) \ + ((phdr)->rlpt[0] = ((phdr)->rlpt[0] & 0xf0) | ((rate) & 0xf)) +/* set reserved field to zero */ +#define D11A_PHY_HDR_SRES(phdr) ((phdr)->rlpt[0] &= 0xef) +/* length is number of octets in PSDU */ +#define D11A_PHY_HDR_SLENGTH(phdr, length) \ + (*(u32 *)((phdr)->rlpt) = *(u32 *)((phdr)->rlpt) | \ + (((length) & 0x0fff) << 5)) +/* set the tail to all zeros */ +#define D11A_PHY_HDR_STAIL(phdr) ((phdr)->rlpt[3] &= 0x03) + +#define D11A_PHY_HDR_LEN_L 3 /* low-rate part of PLCP header */ +#define D11A_PHY_HDR_LEN_R 2 /* high-rate part of PLCP header */ + +#define D11A_PHY_TX_DELAY (2) /* 2.1 usec */ + +#define D11A_PHY_HDR_TIME (4) /* low-rate part of PLCP header */ +#define D11A_PHY_PRE_TIME (16) +#define D11A_PHY_PREHDR_TIME (D11A_PHY_PRE_TIME + D11A_PHY_HDR_TIME) + +/* 802.11b PLCP header def */ +typedef struct cck_phy_hdr cck_phy_hdr_t; +struct cck_phy_hdr { + u8 signal; + u8 service; + u16 length; + u16 crc; +} __attribute__((packed)); + +#define D11B_PHY_HDR_LEN 6 + +#define D11B_PHY_TX_DELAY (3) /* 3.4 usec */ + +#define D11B_PHY_LHDR_TIME (D11B_PHY_HDR_LEN << 3) +#define D11B_PHY_LPRE_TIME (144) +#define D11B_PHY_LPREHDR_TIME (D11B_PHY_LPRE_TIME + D11B_PHY_LHDR_TIME) + +#define D11B_PHY_SHDR_TIME (D11B_PHY_LHDR_TIME >> 1) +#define D11B_PHY_SPRE_TIME (D11B_PHY_LPRE_TIME >> 1) +#define D11B_PHY_SPREHDR_TIME (D11B_PHY_SPRE_TIME + D11B_PHY_SHDR_TIME) + +#define D11B_PLCP_SIGNAL_LOCKED (1 << 2) +#define D11B_PLCP_SIGNAL_LE (1 << 7) + +#define MIMO_PLCP_MCS_MASK 0x7f /* mcs index */ +#define MIMO_PLCP_40MHZ 0x80 /* 40 Hz frame */ +#define MIMO_PLCP_AMPDU 0x08 /* ampdu */ + +#define WLC_GET_CCK_PLCP_LEN(plcp) (plcp[4] + (plcp[5] << 8)) +#define WLC_GET_MIMO_PLCP_LEN(plcp) (plcp[1] + (plcp[2] << 8)) +#define WLC_SET_MIMO_PLCP_LEN(plcp, len) \ + do { \ + plcp[1] = len & 0xff; \ + plcp[2] = ((len >> 8) & 0xff); \ + } while (0); + +#define WLC_SET_MIMO_PLCP_AMPDU(plcp) (plcp[3] |= MIMO_PLCP_AMPDU) +#define WLC_CLR_MIMO_PLCP_AMPDU(plcp) (plcp[3] &= ~MIMO_PLCP_AMPDU) +#define WLC_IS_MIMO_PLCP_AMPDU(plcp) (plcp[3] & MIMO_PLCP_AMPDU) + +/* The dot11a PLCP header is 5 bytes. To simplify the software (so that we + * don't need e.g. different tx DMA headers for 11a and 11b), the PLCP header has + * padding added in the ucode. + */ +#define D11_PHY_HDR_LEN 6 + +/* TX DMA buffer header */ +typedef struct d11txh d11txh_t; +struct d11txh { + u16 MacTxControlLow; /* 0x0 */ + u16 MacTxControlHigh; /* 0x1 */ + u16 MacFrameControl; /* 0x2 */ + u16 TxFesTimeNormal; /* 0x3 */ + u16 PhyTxControlWord; /* 0x4 */ + u16 PhyTxControlWord_1; /* 0x5 */ + u16 PhyTxControlWord_1_Fbr; /* 0x6 */ + u16 PhyTxControlWord_1_Rts; /* 0x7 */ + u16 PhyTxControlWord_1_FbrRts; /* 0x8 */ + u16 MainRates; /* 0x9 */ + u16 XtraFrameTypes; /* 0xa */ + u8 IV[16]; /* 0x0b - 0x12 */ + u8 TxFrameRA[6]; /* 0x13 - 0x15 */ + u16 TxFesTimeFallback; /* 0x16 */ + u8 RTSPLCPFallback[6]; /* 0x17 - 0x19 */ + u16 RTSDurFallback; /* 0x1a */ + u8 FragPLCPFallback[6]; /* 0x1b - 1d */ + u16 FragDurFallback; /* 0x1e */ + u16 MModeLen; /* 0x1f */ + u16 MModeFbrLen; /* 0x20 */ + u16 TstampLow; /* 0x21 */ + u16 TstampHigh; /* 0x22 */ + u16 ABI_MimoAntSel; /* 0x23 */ + u16 PreloadSize; /* 0x24 */ + u16 AmpduSeqCtl; /* 0x25 */ + u16 TxFrameID; /* 0x26 */ + u16 TxStatus; /* 0x27 */ + u16 MaxNMpdus; /* 0x28 corerev >=16 */ + u16 MaxABytes_MRT; /* 0x29 corerev >=16 */ + u16 MaxABytes_FBR; /* 0x2a corerev >=16 */ + u16 MinMBytes; /* 0x2b corerev >=16 */ + u8 RTSPhyHeader[D11_PHY_HDR_LEN]; /* 0x2c - 0x2e */ + struct ieee80211_rts rts_frame; /* 0x2f - 0x36 */ + u16 PAD; /* 0x37 */ +} __attribute__((packed)); + +#define D11_TXH_LEN 112 /* bytes */ + +/* Frame Types */ +#define FT_CCK 0 +#define FT_OFDM 1 +#define FT_HT 2 +#define FT_N 3 + +/* Position of MPDU inside A-MPDU; indicated with bits 10:9 of MacTxControlLow */ +#define TXC_AMPDU_SHIFT 9 /* shift for ampdu settings */ +#define TXC_AMPDU_NONE 0 /* Regular MPDU, not an A-MPDU */ +#define TXC_AMPDU_FIRST 1 /* first MPDU of an A-MPDU */ +#define TXC_AMPDU_MIDDLE 2 /* intermediate MPDU of an A-MPDU */ +#define TXC_AMPDU_LAST 3 /* last (or single) MPDU of an A-MPDU */ + +/* MacTxControlLow */ +#define TXC_AMIC 0x8000 +#define TXC_SENDCTS 0x0800 +#define TXC_AMPDU_MASK 0x0600 +#define TXC_BW_40 0x0100 +#define TXC_FREQBAND_5G 0x0080 +#define TXC_DFCS 0x0040 +#define TXC_IGNOREPMQ 0x0020 +#define TXC_HWSEQ 0x0010 +#define TXC_STARTMSDU 0x0008 +#define TXC_SENDRTS 0x0004 +#define TXC_LONGFRAME 0x0002 +#define TXC_IMMEDACK 0x0001 + +/* MacTxControlHigh */ +#define TXC_PREAMBLE_RTS_FB_SHORT 0x8000 /* RTS fallback preamble type 1 = SHORT 0 = LONG */ +#define TXC_PREAMBLE_RTS_MAIN_SHORT 0x4000 /* RTS main rate preamble type 1 = SHORT 0 = LONG */ +#define TXC_PREAMBLE_DATA_FB_SHORT 0x2000 /* Main fallback rate preamble type + * 1 = SHORT for OFDM/GF for MIMO + * 0 = LONG for CCK/MM for MIMO + */ +/* TXC_PREAMBLE_DATA_MAIN is in PhyTxControl bit 5 */ +#define TXC_AMPDU_FBR 0x1000 /* use fallback rate for this AMPDU */ +#define TXC_SECKEY_MASK 0x0FF0 +#define TXC_SECKEY_SHIFT 4 +#define TXC_ALT_TXPWR 0x0008 /* Use alternate txpwr defined at loc. M_ALT_TXPWR_IDX */ +#define TXC_SECTYPE_MASK 0x0007 +#define TXC_SECTYPE_SHIFT 0 + +/* Null delimiter for Fallback rate */ +#define AMPDU_FBR_NULL_DELIM 5 /* Location of Null delimiter count for AMPDU */ + +/* PhyTxControl for Mimophy */ +#define PHY_TXC_PWR_MASK 0xFC00 +#define PHY_TXC_PWR_SHIFT 10 +#define PHY_TXC_ANT_MASK 0x03C0 /* bit 6, 7, 8, 9 */ +#define PHY_TXC_ANT_SHIFT 6 +#define PHY_TXC_ANT_0_1 0x00C0 /* auto, last rx */ +#define PHY_TXC_LCNPHY_ANT_LAST 0x0000 +#define PHY_TXC_ANT_3 0x0200 /* virtual antenna 3 */ +#define PHY_TXC_ANT_2 0x0100 /* virtual antenna 2 */ +#define PHY_TXC_ANT_1 0x0080 /* virtual antenna 1 */ +#define PHY_TXC_ANT_0 0x0040 /* virtual antenna 0 */ +#define PHY_TXC_SHORT_HDR 0x0010 + +#define PHY_TXC_OLD_ANT_0 0x0000 +#define PHY_TXC_OLD_ANT_1 0x0100 +#define PHY_TXC_OLD_ANT_LAST 0x0300 + +/* PhyTxControl_1 for Mimophy */ +#define PHY_TXC1_BW_MASK 0x0007 +#define PHY_TXC1_BW_10MHZ 0 +#define PHY_TXC1_BW_10MHZ_UP 1 +#define PHY_TXC1_BW_20MHZ 2 +#define PHY_TXC1_BW_20MHZ_UP 3 +#define PHY_TXC1_BW_40MHZ 4 +#define PHY_TXC1_BW_40MHZ_DUP 5 +#define PHY_TXC1_MODE_SHIFT 3 +#define PHY_TXC1_MODE_MASK 0x0038 +#define PHY_TXC1_MODE_SISO 0 +#define PHY_TXC1_MODE_CDD 1 +#define PHY_TXC1_MODE_STBC 2 +#define PHY_TXC1_MODE_SDM 3 + +/* PhyTxControl for HTphy that are different from Mimophy */ +#define PHY_TXC_HTANT_MASK 0x3fC0 /* bit 6, 7, 8, 9, 10, 11, 12, 13 */ + +/* XtraFrameTypes */ +#define XFTS_RTS_FT_SHIFT 2 +#define XFTS_FBRRTS_FT_SHIFT 4 +#define XFTS_CHANNEL_SHIFT 8 + +/* Antenna diversity bit in ant_wr_settle */ +#define PHY_AWS_ANTDIV 0x2000 + +/* IFS ctl */ +#define IFS_USEEDCF (1 << 2) + +/* IFS ctl1 */ +#define IFS_CTL1_EDCRS (1 << 3) +#define IFS_CTL1_EDCRS_20L (1 << 4) +#define IFS_CTL1_EDCRS_40 (1 << 5) + +/* ABI_MimoAntSel */ +#define ABI_MAS_ADDR_BMP_IDX_MASK 0x0f00 +#define ABI_MAS_ADDR_BMP_IDX_SHIFT 8 +#define ABI_MAS_FBR_ANT_PTN_MASK 0x00f0 +#define ABI_MAS_FBR_ANT_PTN_SHIFT 4 +#define ABI_MAS_MRT_ANT_PTN_MASK 0x000f + +/* tx status packet */ +typedef struct tx_status tx_status_t; +struct tx_status { + u16 framelen; + u16 PAD; + u16 frameid; + u16 status; + u16 lasttxtime; + u16 sequence; + u16 phyerr; + u16 ackphyrxsh; +} __attribute__((packed)); + +#define TXSTATUS_LEN 16 + +/* status field bit definitions */ +#define TX_STATUS_FRM_RTX_MASK 0xF000 +#define TX_STATUS_FRM_RTX_SHIFT 12 +#define TX_STATUS_RTS_RTX_MASK 0x0F00 +#define TX_STATUS_RTS_RTX_SHIFT 8 +#define TX_STATUS_MASK 0x00FE +#define TX_STATUS_PMINDCTD (1 << 7) /* PM mode indicated to AP */ +#define TX_STATUS_INTERMEDIATE (1 << 6) /* intermediate or 1st ampdu pkg */ +#define TX_STATUS_AMPDU (1 << 5) /* AMPDU status */ +#define TX_STATUS_SUPR_MASK 0x1C /* suppress status bits (4:2) */ +#define TX_STATUS_SUPR_SHIFT 2 +#define TX_STATUS_ACK_RCV (1 << 1) /* ACK received */ +#define TX_STATUS_VALID (1 << 0) /* Tx status valid (corerev >= 5) */ +#define TX_STATUS_NO_ACK 0 + +/* suppress status reason codes */ +#define TX_STATUS_SUPR_PMQ (1 << 2) /* PMQ entry */ +#define TX_STATUS_SUPR_FLUSH (2 << 2) /* flush request */ +#define TX_STATUS_SUPR_FRAG (3 << 2) /* previous frag failure */ +#define TX_STATUS_SUPR_TBTT (3 << 2) /* SHARED: Probe response supr for TBTT */ +#define TX_STATUS_SUPR_BADCH (4 << 2) /* channel mismatch */ +#define TX_STATUS_SUPR_EXPTIME (5 << 2) /* lifetime expiry */ +#define TX_STATUS_SUPR_UF (6 << 2) /* underflow */ + +/* Unexpected tx status for rate update */ +#define TX_STATUS_UNEXP(status) \ + ((((status) & TX_STATUS_INTERMEDIATE) != 0) && \ + TX_STATUS_UNEXP_AMPDU(status)) + +/* Unexpected tx status for A-MPDU rate update */ +#define TX_STATUS_UNEXP_AMPDU(status) \ + ((((status) & TX_STATUS_SUPR_MASK) != 0) && \ + (((status) & TX_STATUS_SUPR_MASK) != TX_STATUS_SUPR_EXPTIME)) + +#define TX_STATUS_BA_BMAP03_MASK 0xF000 /* ba bitmap 0:3 in 1st pkg */ +#define TX_STATUS_BA_BMAP03_SHIFT 12 /* ba bitmap 0:3 in 1st pkg */ +#define TX_STATUS_BA_BMAP47_MASK 0x001E /* ba bitmap 4:7 in 2nd pkg */ +#define TX_STATUS_BA_BMAP47_SHIFT 3 /* ba bitmap 4:7 in 2nd pkg */ + +/* RXE (Receive Engine) */ + +/* RCM_CTL */ +#define RCM_INC_MASK_H 0x0080 +#define RCM_INC_MASK_L 0x0040 +#define RCM_INC_DATA 0x0020 +#define RCM_INDEX_MASK 0x001F +#define RCM_SIZE 15 + +#define RCM_MAC_OFFSET 0 /* current MAC address */ +#define RCM_BSSID_OFFSET 3 /* current BSSID address */ +#define RCM_F_BSSID_0_OFFSET 6 /* foreign BSS CFP tracking */ +#define RCM_F_BSSID_1_OFFSET 9 /* foreign BSS CFP tracking */ +#define RCM_F_BSSID_2_OFFSET 12 /* foreign BSS CFP tracking */ + +#define RCM_WEP_TA0_OFFSET 16 +#define RCM_WEP_TA1_OFFSET 19 +#define RCM_WEP_TA2_OFFSET 22 +#define RCM_WEP_TA3_OFFSET 25 + +/* PSM Block */ + +/* psm_phy_hdr_param bits */ +#define MAC_PHY_RESET 1 +#define MAC_PHY_CLOCK_EN 2 +#define MAC_PHY_FORCE_CLK 4 + +/* WEP Block */ + +/* WEP_WKEY */ +#define WKEY_START (1 << 8) +#define WKEY_SEL_MASK 0x1F + +/* WEP data formats */ + +/* the number of RCMTA entries */ +#define RCMTA_SIZE 50 + +#define M_ADDR_BMP_BLK (0x37e * 2) +#define M_ADDR_BMP_BLK_SZ 12 + +#define ADDR_BMP_RA (1 << 0) /* Receiver Address (RA) */ +#define ADDR_BMP_TA (1 << 1) /* Transmitter Address (TA) */ +#define ADDR_BMP_BSSID (1 << 2) /* BSSID */ +#define ADDR_BMP_AP (1 << 3) /* Infra-BSS Access Point (AP) */ +#define ADDR_BMP_STA (1 << 4) /* Infra-BSS Station (STA) */ +#define ADDR_BMP_RESERVED1 (1 << 5) +#define ADDR_BMP_RESERVED2 (1 << 6) +#define ADDR_BMP_RESERVED3 (1 << 7) +#define ADDR_BMP_BSS_IDX_MASK (3 << 8) /* BSS control block index */ +#define ADDR_BMP_BSS_IDX_SHIFT 8 + +#define WSEC_MAX_RCMTA_KEYS 54 + +/* max keys in M_TKMICKEYS_BLK */ +#define WSEC_MAX_TKMIC_ENGINE_KEYS 12 /* 8 + 4 default */ + +/* max RXE match registers */ +#define WSEC_MAX_RXE_KEYS 4 + +/* SECKINDXALGO (Security Key Index & Algorithm Block) word format */ +/* SKL (Security Key Lookup) */ +#define SKL_ALGO_MASK 0x0007 +#define SKL_ALGO_SHIFT 0 +#define SKL_KEYID_MASK 0x0008 +#define SKL_KEYID_SHIFT 3 +#define SKL_INDEX_MASK 0x03F0 +#define SKL_INDEX_SHIFT 4 +#define SKL_GRP_ALGO_MASK 0x1c00 +#define SKL_GRP_ALGO_SHIFT 10 + +/* additional bits defined for IBSS group key support */ +#define SKL_IBSS_INDEX_MASK 0x01F0 +#define SKL_IBSS_INDEX_SHIFT 4 +#define SKL_IBSS_KEYID1_MASK 0x0600 +#define SKL_IBSS_KEYID1_SHIFT 9 +#define SKL_IBSS_KEYID2_MASK 0x1800 +#define SKL_IBSS_KEYID2_SHIFT 11 +#define SKL_IBSS_KEYALGO_MASK 0xE000 +#define SKL_IBSS_KEYALGO_SHIFT 13 + +#define WSEC_MODE_OFF 0 +#define WSEC_MODE_HW 1 +#define WSEC_MODE_SW 2 + +#define WSEC_ALGO_OFF 0 +#define WSEC_ALGO_WEP1 1 +#define WSEC_ALGO_TKIP 2 +#define WSEC_ALGO_AES 3 +#define WSEC_ALGO_WEP128 4 +#define WSEC_ALGO_AES_LEGACY 5 +#define WSEC_ALGO_NALG 6 + +#define AES_MODE_NONE 0 +#define AES_MODE_CCM 1 + +/* WEP_CTL (Rev 0) */ +#define WECR0_KEYREG_SHIFT 0 +#define WECR0_KEYREG_MASK 0x7 +#define WECR0_DECRYPT (1 << 3) +#define WECR0_IVINLINE (1 << 4) +#define WECR0_WEPALG_SHIFT 5 +#define WECR0_WEPALG_MASK (0x7 << 5) +#define WECR0_WKEYSEL_SHIFT 8 +#define WECR0_WKEYSEL_MASK (0x7 << 8) +#define WECR0_WKEYSTART (1 << 11) +#define WECR0_WEPINIT (1 << 14) +#define WECR0_ICVERR (1 << 15) + +/* Frame template map byte offsets */ +#define T_ACTS_TPL_BASE (0) +#define T_NULL_TPL_BASE (0xc * 2) +#define T_QNULL_TPL_BASE (0x1c * 2) +#define T_RR_TPL_BASE (0x2c * 2) +#define T_BCN0_TPL_BASE (0x34 * 2) +#define T_PRS_TPL_BASE (0x134 * 2) +#define T_BCN1_TPL_BASE (0x234 * 2) +#define T_TX_FIFO_TXRAM_BASE (T_ACTS_TPL_BASE + (TXFIFO_START_BLK * TXFIFO_SIZE_UNIT)) + +#define T_BA_TPL_BASE T_QNULL_TPL_BASE /* template area for BA */ + +#define T_RAM_ACCESS_SZ 4 /* template ram is 4 byte access only */ + +/* Shared Mem byte offsets */ + +/* Location where the ucode expects the corerev */ +#define M_MACHW_VER (0x00b * 2) + +/* Location where the ucode expects the MAC capabilities */ +#define M_MACHW_CAP_L (0x060 * 2) +#define M_MACHW_CAP_H (0x061 * 2) + +/* WME shared memory */ +#define M_EDCF_STATUS_OFF (0x007 * 2) +#define M_TXF_CUR_INDEX (0x018 * 2) +#define M_EDCF_QINFO (0x120 * 2) + +/* PS-mode related parameters */ +#define M_DOT11_SLOT (0x008 * 2) +#define M_DOT11_DTIMPERIOD (0x009 * 2) +#define M_NOSLPZNATDTIM (0x026 * 2) + +/* Beacon-related parameters */ +#define M_BCN0_FRM_BYTESZ (0x00c * 2) /* Bcn 0 template length */ +#define M_BCN1_FRM_BYTESZ (0x00d * 2) /* Bcn 1 template length */ +#define M_BCN_TXTSF_OFFSET (0x00e * 2) +#define M_TIMBPOS_INBEACON (0x00f * 2) +#define M_SFRMTXCNTFBRTHSD (0x022 * 2) +#define M_LFRMTXCNTFBRTHSD (0x023 * 2) +#define M_BCN_PCTLWD (0x02a * 2) +#define M_BCN_LI (0x05b * 2) /* beacon listen interval */ + +/* MAX Rx Frame len */ +#define M_MAXRXFRM_LEN (0x010 * 2) + +/* ACK/CTS related params */ +#define M_RSP_PCTLWD (0x011 * 2) + +/* Hardware Power Control */ +#define M_TXPWR_N (0x012 * 2) +#define M_TXPWR_TARGET (0x013 * 2) +#define M_TXPWR_MAX (0x014 * 2) +#define M_TXPWR_CUR (0x019 * 2) + +/* Rx-related parameters */ +#define M_RX_PAD_DATA_OFFSET (0x01a * 2) + +/* WEP Shared mem data */ +#define M_SEC_DEFIVLOC (0x01e * 2) +#define M_SEC_VALNUMSOFTMCHTA (0x01f * 2) +#define M_PHYVER (0x028 * 2) +#define M_PHYTYPE (0x029 * 2) +#define M_SECRXKEYS_PTR (0x02b * 2) +#define M_TKMICKEYS_PTR (0x059 * 2) +#define M_SECKINDXALGO_BLK (0x2ea * 2) +#define M_SECKINDXALGO_BLK_SZ 54 +#define M_SECPSMRXTAMCH_BLK (0x2fa * 2) +#define M_TKIP_TSC_TTAK (0x18c * 2) +#define D11_MAX_KEY_SIZE 16 + +#define M_MAX_ANTCNT (0x02e * 2) /* antenna swap threshold */ + +/* Probe response related parameters */ +#define M_SSIDLEN (0x024 * 2) +#define M_PRB_RESP_FRM_LEN (0x025 * 2) +#define M_PRS_MAXTIME (0x03a * 2) +#define M_SSID (0xb0 * 2) +#define M_CTXPRS_BLK (0xc0 * 2) +#define C_CTX_PCTLWD_POS (0x4 * 2) + +/* Delta between OFDM and CCK power in CCK power boost mode */ +#define M_OFDM_OFFSET (0x027 * 2) + +/* TSSI for last 4 11b/g CCK packets transmitted */ +#define M_B_TSSI_0 (0x02c * 2) +#define M_B_TSSI_1 (0x02d * 2) + +/* Host flags to turn on ucode options */ +#define M_HOST_FLAGS1 (0x02f * 2) +#define M_HOST_FLAGS2 (0x030 * 2) +#define M_HOST_FLAGS3 (0x031 * 2) +#define M_HOST_FLAGS4 (0x03c * 2) +#define M_HOST_FLAGS5 (0x06a * 2) +#define M_HOST_FLAGS_SZ 16 + +#define M_RADAR_REG (0x033 * 2) + +/* TSSI for last 4 11a OFDM packets transmitted */ +#define M_A_TSSI_0 (0x034 * 2) +#define M_A_TSSI_1 (0x035 * 2) + +/* noise interference measurement */ +#define M_NOISE_IF_COUNT (0x034 * 2) +#define M_NOISE_IF_TIMEOUT (0x035 * 2) + +#define M_RF_RX_SP_REG1 (0x036 * 2) + +/* TSSI for last 4 11g OFDM packets transmitted */ +#define M_G_TSSI_0 (0x038 * 2) +#define M_G_TSSI_1 (0x039 * 2) + +/* Background noise measure */ +#define M_JSSI_0 (0x44 * 2) +#define M_JSSI_1 (0x45 * 2) +#define M_JSSI_AUX (0x46 * 2) + +#define M_CUR_2050_RADIOCODE (0x47 * 2) + +/* TX fifo sizes */ +#define M_FIFOSIZE0 (0x4c * 2) +#define M_FIFOSIZE1 (0x4d * 2) +#define M_FIFOSIZE2 (0x4e * 2) +#define M_FIFOSIZE3 (0x4f * 2) +#define D11_MAX_TX_FRMS 32 /* max frames allowed in tx fifo */ + +/* Current channel number plus upper bits */ +#define M_CURCHANNEL (0x50 * 2) +#define D11_CURCHANNEL_5G 0x0100; +#define D11_CURCHANNEL_40 0x0200; +#define D11_CURCHANNEL_MAX 0x00FF; + +/* last posted frameid on the bcmc fifo */ +#define M_BCMC_FID (0x54 * 2) +#define INVALIDFID 0xffff + +/* extended beacon phyctl bytes for 11N */ +#define M_BCN_PCTL1WD (0x058 * 2) + +/* idle busy ratio to duty_cycle requirement */ +#define M_TX_IDLE_BUSY_RATIO_X_16_CCK (0x52 * 2) +#define M_TX_IDLE_BUSY_RATIO_X_16_OFDM (0x5A * 2) + +/* CW RSSI for LCNPHY */ +#define M_LCN_RSSI_0 0x1332 +#define M_LCN_RSSI_1 0x1338 +#define M_LCN_RSSI_2 0x133e +#define M_LCN_RSSI_3 0x1344 + +/* SNR for LCNPHY */ +#define M_LCN_SNR_A_0 0x1334 +#define M_LCN_SNR_B_0 0x1336 + +#define M_LCN_SNR_A_1 0x133a +#define M_LCN_SNR_B_1 0x133c + +#define M_LCN_SNR_A_2 0x1340 +#define M_LCN_SNR_B_2 0x1342 + +#define M_LCN_SNR_A_3 0x1346 +#define M_LCN_SNR_B_3 0x1348 + +#define M_LCN_LAST_RESET (81*2) +#define M_LCN_LAST_LOC (63*2) +#define M_LCNPHY_RESET_STATUS (4902) +#define M_LCNPHY_DSC_TIME (0x98d*2) +#define M_LCNPHY_RESET_CNT_DSC (0x98b*2) +#define M_LCNPHY_RESET_CNT (0x98c*2) + +/* Rate table offsets */ +#define M_RT_DIRMAP_A (0xe0 * 2) +#define M_RT_BBRSMAP_A (0xf0 * 2) +#define M_RT_DIRMAP_B (0x100 * 2) +#define M_RT_BBRSMAP_B (0x110 * 2) + +/* Rate table entry offsets */ +#define M_RT_PRS_PLCP_POS 10 +#define M_RT_PRS_DUR_POS 16 +#define M_RT_OFDM_PCTL1_POS 18 + +#define M_20IN40_IQ (0x380 * 2) + +/* SHM locations where ucode stores the current power index */ +#define M_CURR_IDX1 (0x384 * 2) +#define M_CURR_IDX2 (0x387 * 2) + +#define M_BSCALE_ANT0 (0x5e * 2) +#define M_BSCALE_ANT1 (0x5f * 2) + +/* Antenna Diversity Testing */ +#define M_MIMO_ANTSEL_RXDFLT (0x63 * 2) +#define M_ANTSEL_CLKDIV (0x61 * 2) +#define M_MIMO_ANTSEL_TXDFLT (0x64 * 2) + +#define M_MIMO_MAXSYM (0x5d * 2) +#define MIMO_MAXSYM_DEF 0x8000 /* 32k */ +#define MIMO_MAXSYM_MAX 0xffff /* 64k */ + +#define M_WATCHDOG_8TU (0x1e * 2) +#define WATCHDOG_8TU_DEF 5 +#define WATCHDOG_8TU_MAX 10 + +/* Manufacturing Test Variables */ +#define M_PKTENG_CTRL (0x6c * 2) /* PER test mode */ +#define M_PKTENG_IFS (0x6d * 2) /* IFS for TX mode */ +#define M_PKTENG_FRMCNT_LO (0x6e * 2) /* Lower word of tx frmcnt/rx lostcnt */ +#define M_PKTENG_FRMCNT_HI (0x6f * 2) /* Upper word of tx frmcnt/rx lostcnt */ + +/* Index variation in vbat ripple */ +#define M_LCN_PWR_IDX_MAX (0x67 * 2) /* highest index read by ucode */ +#define M_LCN_PWR_IDX_MIN (0x66 * 2) /* lowest index read by ucode */ + +/* M_PKTENG_CTRL bit definitions */ +#define M_PKTENG_MODE_TX 0x0001 +#define M_PKTENG_MODE_TX_RIFS 0x0004 +#define M_PKTENG_MODE_TX_CTS 0x0008 +#define M_PKTENG_MODE_RX 0x0002 +#define M_PKTENG_MODE_RX_WITH_ACK 0x0402 +#define M_PKTENG_MODE_MASK 0x0003 +#define M_PKTENG_FRMCNT_VLD 0x0100 /* TX frames indicated in the frmcnt reg */ + +/* Sample Collect parameters (bitmap and type) */ +#define M_SMPL_COL_BMP (0x37d * 2) /* Trigger bitmap for sample collect */ +#define M_SMPL_COL_CTL (0x3b2 * 2) /* Sample collect type */ + +#define ANTSEL_CLKDIV_4MHZ 6 +#define MIMO_ANTSEL_BUSY 0x4000 /* bit 14 (busy) */ +#define MIMO_ANTSEL_SEL 0x8000 /* bit 15 write the value */ +#define MIMO_ANTSEL_WAIT 50 /* 50us wait */ +#define MIMO_ANTSEL_OVERRIDE 0x8000 /* flag */ + +typedef struct shm_acparams shm_acparams_t; +struct shm_acparams { + u16 txop; + u16 cwmin; + u16 cwmax; + u16 cwcur; + u16 aifs; + u16 bslots; + u16 reggap; + u16 status; + u16 rsvd[8]; +} __attribute__((packed)); +#define M_EDCF_QLEN (16 * 2) + +#define WME_STATUS_NEWAC (1 << 8) + +/* M_HOST_FLAGS */ +#define MHFMAX 5 /* Number of valid hostflag half-word (u16) */ +#define MHF1 0 /* Hostflag 1 index */ +#define MHF2 1 /* Hostflag 2 index */ +#define MHF3 2 /* Hostflag 3 index */ +#define MHF4 3 /* Hostflag 4 index */ +#define MHF5 4 /* Hostflag 5 index */ + +/* Flags in M_HOST_FLAGS */ +#define MHF1_ANTDIV 0x0001 /* Enable ucode antenna diversity help */ +#define MHF1_EDCF 0x0100 /* Enable EDCF access control */ +#define MHF1_IQSWAP_WAR 0x0200 +#define MHF1_FORCEFASTCLK 0x0400 /* Disable Slow clock request, for corerev < 11 */ + +/* Flags in M_HOST_FLAGS2 */ +#define MHF2_PCISLOWCLKWAR 0x0008 /* PR16165WAR : Enable ucode PCI slow clock WAR */ +#define MHF2_TXBCMC_NOW 0x0040 /* Flush BCMC FIFO immediately */ +#define MHF2_HWPWRCTL 0x0080 /* Enable ucode/hw power control */ +#define MHF2_NPHY40MHZ_WAR 0x0800 + +/* Flags in M_HOST_FLAGS3 */ +#define MHF3_ANTSEL_EN 0x0001 /* enabled mimo antenna selection */ +#define MHF3_ANTSEL_MODE 0x0002 /* antenna selection mode: 0: 2x3, 1: 2x4 */ +#define MHF3_RESERVED1 0x0004 +#define MHF3_RESERVED2 0x0008 +#define MHF3_NPHY_MLADV_WAR 0x0010 + +/* Flags in M_HOST_FLAGS4 */ +#define MHF4_BPHY_TXCORE0 0x0080 /* force bphy Tx on core 0 (board level WAR) */ +#define MHF4_EXTPA_ENABLE 0x4000 /* for 4313A0 FEM boards */ + +/* Flags in M_HOST_FLAGS5 */ +#define MHF5_4313_GPIOCTRL 0x0001 +#define MHF5_RESERVED1 0x0002 +#define MHF5_RESERVED2 0x0004 +/* Radio power setting for ucode */ +#define M_RADIO_PWR (0x32 * 2) + +/* phy noise recorded by ucode right after tx */ +#define M_PHY_NOISE (0x037 * 2) +#define PHY_NOISE_MASK 0x00ff + +/* Receive Frame Data Header for 802.11b DCF-only frames */ +typedef struct d11rxhdr d11rxhdr_t; +struct d11rxhdr { + u16 RxFrameSize; /* Actual byte length of the frame data received */ + u16 PAD; + u16 PhyRxStatus_0; /* PhyRxStatus 15:0 */ + u16 PhyRxStatus_1; /* PhyRxStatus 31:16 */ + u16 PhyRxStatus_2; /* PhyRxStatus 47:32 */ + u16 PhyRxStatus_3; /* PhyRxStatus 63:48 */ + u16 PhyRxStatus_4; /* PhyRxStatus 79:64 */ + u16 PhyRxStatus_5; /* PhyRxStatus 95:80 */ + u16 RxStatus1; /* MAC Rx Status */ + u16 RxStatus2; /* extended MAC Rx status */ + u16 RxTSFTime; /* RxTSFTime time of first MAC symbol + M_PHY_PLCPRX_DLY */ + u16 RxChan; /* gain code, channel radio code, and phy type */ +} __attribute__((packed)); + +#define RXHDR_LEN 24 /* sizeof d11rxhdr_t */ +#define FRAMELEN(h) ((h)->RxFrameSize) + +typedef struct wlc_d11rxhdr wlc_d11rxhdr_t; +struct wlc_d11rxhdr { + d11rxhdr_t rxhdr; + u32 tsf_l; /* TSF_L reading */ + s8 rssi; /* computed instanteneous rssi in BMAC */ + s8 rxpwr0; /* obsoleted, place holder for legacy ROM code. use rxpwr[] */ + s8 rxpwr1; /* obsoleted, place holder for legacy ROM code. use rxpwr[] */ + s8 do_rssi_ma; /* do per-pkt sampling for per-antenna ma in HIGH */ + s8 rxpwr[WL_RSSI_ANT_MAX]; /* rssi for supported antennas */ +} __attribute__((packed)); + +/* PhyRxStatus_0: */ +#define PRXS0_FT_MASK 0x0003 /* NPHY only: CCK, OFDM, preN, N */ +#define PRXS0_CLIP_MASK 0x000C /* NPHY only: clip count adjustment steps by AGC */ +#define PRXS0_CLIP_SHIFT 2 +#define PRXS0_UNSRATE 0x0010 /* PHY received a frame with unsupported rate */ +#define PRXS0_RXANT_UPSUBBAND 0x0020 /* GPHY: rx ant, NPHY: upper sideband */ +#define PRXS0_LCRS 0x0040 /* CCK frame only: lost crs during cck frame reception */ +#define PRXS0_SHORTH 0x0080 /* Short Preamble */ +#define PRXS0_PLCPFV 0x0100 /* PLCP violation */ +#define PRXS0_PLCPHCF 0x0200 /* PLCP header integrity check failed */ +#define PRXS0_GAIN_CTL 0x4000 /* legacy PHY gain control */ +#define PRXS0_ANTSEL_MASK 0xF000 /* NPHY: Antennas used for received frame, bitmask */ +#define PRXS0_ANTSEL_SHIFT 0x12 + +/* subfield PRXS0_FT_MASK */ +#define PRXS0_CCK 0x0000 +#define PRXS0_OFDM 0x0001 /* valid only for G phy, use rxh->RxChan for A phy */ +#define PRXS0_PREN 0x0002 +#define PRXS0_STDN 0x0003 + +/* subfield PRXS0_ANTSEL_MASK */ +#define PRXS0_ANTSEL_0 0x0 /* antenna 0 is used */ +#define PRXS0_ANTSEL_1 0x2 /* antenna 1 is used */ +#define PRXS0_ANTSEL_2 0x4 /* antenna 2 is used */ +#define PRXS0_ANTSEL_3 0x8 /* antenna 3 is used */ + +/* PhyRxStatus_1: */ +#define PRXS1_JSSI_MASK 0x00FF +#define PRXS1_JSSI_SHIFT 0 +#define PRXS1_SQ_MASK 0xFF00 +#define PRXS1_SQ_SHIFT 8 + +/* nphy PhyRxStatus_1: */ +#define PRXS1_nphy_PWR0_MASK 0x00FF +#define PRXS1_nphy_PWR1_MASK 0xFF00 + +/* HTPHY Rx Status defines */ +/* htphy PhyRxStatus_0: those bit are overlapped with PhyRxStatus_0 */ +#define PRXS0_BAND 0x0400 /* 0 = 2.4G, 1 = 5G */ +#define PRXS0_RSVD 0x0800 /* reserved; set to 0 */ +#define PRXS0_UNUSED 0xF000 /* unused and not defined; set to 0 */ + +/* htphy PhyRxStatus_1: */ +#define PRXS1_HTPHY_CORE_MASK 0x000F /* core enables for {3..0}, 0=disabled, 1=enabled */ +#define PRXS1_HTPHY_ANTCFG_MASK 0x00F0 /* antenna configation */ +#define PRXS1_HTPHY_MMPLCPLenL_MASK 0xFF00 /* Mixmode PLCP Length low byte mask */ + +/* htphy PhyRxStatus_2: */ +#define PRXS2_HTPHY_MMPLCPLenH_MASK 0x000F /* Mixmode PLCP Length high byte maskw */ +#define PRXS2_HTPHY_MMPLCH_RATE_MASK 0x00F0 /* Mixmode PLCP rate mask */ +#define PRXS2_HTPHY_RXPWR_ANT0 0xFF00 /* Rx power on core 0 */ + +/* htphy PhyRxStatus_3: */ +#define PRXS3_HTPHY_RXPWR_ANT1 0x00FF /* Rx power on core 1 */ +#define PRXS3_HTPHY_RXPWR_ANT2 0xFF00 /* Rx power on core 2 */ + +/* htphy PhyRxStatus_4: */ +#define PRXS4_HTPHY_RXPWR_ANT3 0x00FF /* Rx power on core 3 */ +#define PRXS4_HTPHY_CFO 0xFF00 /* Coarse frequency offset */ + +/* htphy PhyRxStatus_5: */ +#define PRXS5_HTPHY_FFO 0x00FF /* Fine frequency offset */ +#define PRXS5_HTPHY_AR 0xFF00 /* Advance Retard */ + +#define HTPHY_MMPLCPLen(rxs) ((((rxs)->PhyRxStatus_1 & PRXS1_HTPHY_MMPLCPLenL_MASK) >> 8) | \ + (((rxs)->PhyRxStatus_2 & PRXS2_HTPHY_MMPLCPLenH_MASK) << 8)) +/* Get Rx power on core 0 */ +#define HTPHY_RXPWR_ANT0(rxs) ((((rxs)->PhyRxStatus_2) & PRXS2_HTPHY_RXPWR_ANT0) >> 8) +/* Get Rx power on core 1 */ +#define HTPHY_RXPWR_ANT1(rxs) (((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT1) +/* Get Rx power on core 2 */ +#define HTPHY_RXPWR_ANT2(rxs) ((((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT2) >> 8) + +/* ucode RxStatus1: */ +#define RXS_BCNSENT 0x8000 +#define RXS_SECKINDX_MASK 0x07e0 +#define RXS_SECKINDX_SHIFT 5 +#define RXS_DECERR (1 << 4) +#define RXS_DECATMPT (1 << 3) +#define RXS_PBPRES (1 << 2) /* PAD bytes to make IP data 4 bytes aligned */ +#define RXS_RESPFRAMETX (1 << 1) +#define RXS_FCSERR (1 << 0) + +/* ucode RxStatus2: */ +#define RXS_AMSDU_MASK 1 +#define RXS_AGGTYPE_MASK 0x6 +#define RXS_AGGTYPE_SHIFT 1 +#define RXS_PHYRXST_VALID (1 << 8) +#define RXS_RXANT_MASK 0x3 +#define RXS_RXANT_SHIFT 12 + +/* RxChan */ +#define RXS_CHAN_40 0x1000 +#define RXS_CHAN_5G 0x0800 +#define RXS_CHAN_ID_MASK 0x07f8 +#define RXS_CHAN_ID_SHIFT 3 +#define RXS_CHAN_PHYTYPE_MASK 0x0007 +#define RXS_CHAN_PHYTYPE_SHIFT 0 + +/* Index of attenuations used during ucode power control. */ +#define M_PWRIND_BLKS (0x184 * 2) +#define M_PWRIND_MAP0 (M_PWRIND_BLKS + 0x0) +#define M_PWRIND_MAP1 (M_PWRIND_BLKS + 0x2) +#define M_PWRIND_MAP2 (M_PWRIND_BLKS + 0x4) +#define M_PWRIND_MAP3 (M_PWRIND_BLKS + 0x6) +/* M_PWRIND_MAP(core) macro */ +#define M_PWRIND_MAP(core) (M_PWRIND_BLKS + ((core)<<1)) + +/* PSM SHM variable offsets */ +#define M_PSM_SOFT_REGS 0x0 +#define M_BOM_REV_MAJOR (M_PSM_SOFT_REGS + 0x0) +#define M_BOM_REV_MINOR (M_PSM_SOFT_REGS + 0x2) +#define M_UCODE_DBGST (M_PSM_SOFT_REGS + 0x40) /* ucode debug status code */ +#define M_UCODE_MACSTAT (M_PSM_SOFT_REGS + 0xE0) /* macstat counters */ + +#define M_AGING_THRSH (0x3e * 2) /* max time waiting for medium before tx */ +#define M_MBURST_SIZE (0x40 * 2) /* max frames in a frameburst */ +#define M_MBURST_TXOP (0x41 * 2) /* max frameburst TXOP in unit of us */ +#define M_SYNTHPU_DLY (0x4a * 2) /* pre-wakeup for synthpu, default: 500 */ +#define M_PRETBTT (0x4b * 2) + +#define M_ALT_TXPWR_IDX (M_PSM_SOFT_REGS + (0x3b * 2)) /* offset to the target txpwr */ +#define M_PHY_TX_FLT_PTR (M_PSM_SOFT_REGS + (0x3d * 2)) +#define M_CTS_DURATION (M_PSM_SOFT_REGS + (0x5c * 2)) +#define M_LP_RCCAL_OVR (M_PSM_SOFT_REGS + (0x6b * 2)) + +/* PKTENG Rx Stats Block */ +#define M_RXSTATS_BLK_PTR (M_PSM_SOFT_REGS + (0x65 * 2)) + +/* ucode debug status codes */ +#define DBGST_INACTIVE 0 /* not valid really */ +#define DBGST_INIT 1 /* after zeroing SHM, before suspending at init */ +#define DBGST_ACTIVE 2 /* "normal" state */ +#define DBGST_SUSPENDED 3 /* suspended */ +#define DBGST_ASLEEP 4 /* asleep (PS mode) */ + +/* Scratch Reg defs */ +typedef enum { + S_RSV0 = 0, + S_RSV1, + S_RSV2, + + /* scratch registers for Dot11-contants */ + S_DOT11_CWMIN, /* CW-minimum 0x03 */ + S_DOT11_CWMAX, /* CW-maximum 0x04 */ + S_DOT11_CWCUR, /* CW-current 0x05 */ + S_DOT11_SRC_LMT, /* short retry count limit 0x06 */ + S_DOT11_LRC_LMT, /* long retry count limit 0x07 */ + S_DOT11_DTIMCOUNT, /* DTIM-count 0x08 */ + + /* Tx-side scratch registers */ + S_SEQ_NUM, /* hardware sequence number reg 0x09 */ + S_SEQ_NUM_FRAG, /* seq-num for frags (Set at the start os MSDU 0x0A */ + S_FRMRETX_CNT, /* frame retx count 0x0B */ + S_SSRC, /* Station short retry count 0x0C */ + S_SLRC, /* Station long retry count 0x0D */ + S_EXP_RSP, /* Expected response frame 0x0E */ + S_OLD_BREM, /* Remaining backoff ctr 0x0F */ + S_OLD_CWWIN, /* saved-off CW-cur 0x10 */ + S_TXECTL, /* TXE-Ctl word constructed in scr-pad 0x11 */ + S_CTXTST, /* frm type-subtype as read from Tx-descr 0x12 */ + + /* Rx-side scratch registers */ + S_RXTST, /* Type and subtype in Rxframe 0x13 */ + + /* Global state register */ + S_STREG, /* state storage actual bit maps below 0x14 */ + + S_TXPWR_SUM, /* Tx power control: accumulator 0x15 */ + S_TXPWR_ITER, /* Tx power control: iteration 0x16 */ + S_RX_FRMTYPE, /* Rate and PHY type for frames 0x17 */ + S_THIS_AGG, /* Size of this AGG (A-MSDU) 0x18 */ + + S_KEYINDX, /* 0x19 */ + S_RXFRMLEN, /* Receive MPDU length in bytes 0x1A */ + + /* Receive TSF time stored in SCR */ + S_RXTSFTMRVAL_WD3, /* TSF value at the start of rx 0x1B */ + S_RXTSFTMRVAL_WD2, /* TSF value at the start of rx 0x1C */ + S_RXTSFTMRVAL_WD1, /* TSF value at the start of rx 0x1D */ + S_RXTSFTMRVAL_WD0, /* TSF value at the start of rx 0x1E */ + S_RXSSN, /* Received start seq number for A-MPDU BA 0x1F */ + S_RXQOSFLD, /* Rx-QoS field (if present) 0x20 */ + + /* Scratch pad regs used in microcode as temp storage */ + S_TMP0, /* stmp0 0x21 */ + S_TMP1, /* stmp1 0x22 */ + S_TMP2, /* stmp2 0x23 */ + S_TMP3, /* stmp3 0x24 */ + S_TMP4, /* stmp4 0x25 */ + S_TMP5, /* stmp5 0x26 */ + S_PRQPENALTY_CTR, /* Probe response queue penalty counter 0x27 */ + S_ANTCNT, /* unsuccessful attempts on current ant. 0x28 */ + S_SYMBOL, /* flag for possible symbol ctl frames 0x29 */ + S_RXTP, /* rx frame type 0x2A */ + S_STREG2, /* extra state storage 0x2B */ + S_STREG3, /* even more extra state storage 0x2C */ + S_STREG4, /* ... 0x2D */ + S_STREG5, /* remember to initialize it to zero 0x2E */ + + S_ADJPWR_IDX, + S_CUR_PTR, /* Temp pointer for A-MPDU re-Tx SHM table 0x32 */ + S_REVID4, /* 0x33 */ + S_INDX, /* 0x34 */ + S_ADDR0, /* 0x35 */ + S_ADDR1, /* 0x36 */ + S_ADDR2, /* 0x37 */ + S_ADDR3, /* 0x38 */ + S_ADDR4, /* 0x39 */ + S_ADDR5, /* 0x3A */ + S_TMP6, /* 0x3B */ + S_KEYINDX_BU, /* Backup for Key index 0x3C */ + S_MFGTEST_TMP0, /* Temp register used for RX test calculations 0x3D */ + S_RXESN, /* Received end sequence number for A-MPDU BA 0x3E */ + S_STREG6, /* 0x3F */ +} ePsmScratchPadRegDefinitions; + +#define S_BEACON_INDX S_OLD_BREM +#define S_PRS_INDX S_OLD_CWWIN +#define S_PHYTYPE S_SSRC +#define S_PHYVER S_SLRC + +/* IHR SLOW_CTRL values */ +#define SLOW_CTRL_PDE (1 << 0) +#define SLOW_CTRL_FD (1 << 8) + +/* ucode mac statistic counters in shared memory */ +typedef struct macstat { + u16 txallfrm; /* 0x80 */ + u16 txrtsfrm; /* 0x82 */ + u16 txctsfrm; /* 0x84 */ + u16 txackfrm; /* 0x86 */ + u16 txdnlfrm; /* 0x88 */ + u16 txbcnfrm; /* 0x8a */ + u16 txfunfl[8]; /* 0x8c - 0x9b */ + u16 txtplunfl; /* 0x9c */ + u16 txphyerr; /* 0x9e */ + u16 pktengrxducast; /* 0xa0 */ + u16 pktengrxdmcast; /* 0xa2 */ + u16 rxfrmtoolong; /* 0xa4 */ + u16 rxfrmtooshrt; /* 0xa6 */ + u16 rxinvmachdr; /* 0xa8 */ + u16 rxbadfcs; /* 0xaa */ + u16 rxbadplcp; /* 0xac */ + u16 rxcrsglitch; /* 0xae */ + u16 rxstrt; /* 0xb0 */ + u16 rxdfrmucastmbss; /* 0xb2 */ + u16 rxmfrmucastmbss; /* 0xb4 */ + u16 rxcfrmucast; /* 0xb6 */ + u16 rxrtsucast; /* 0xb8 */ + u16 rxctsucast; /* 0xba */ + u16 rxackucast; /* 0xbc */ + u16 rxdfrmocast; /* 0xbe */ + u16 rxmfrmocast; /* 0xc0 */ + u16 rxcfrmocast; /* 0xc2 */ + u16 rxrtsocast; /* 0xc4 */ + u16 rxctsocast; /* 0xc6 */ + u16 rxdfrmmcast; /* 0xc8 */ + u16 rxmfrmmcast; /* 0xca */ + u16 rxcfrmmcast; /* 0xcc */ + u16 rxbeaconmbss; /* 0xce */ + u16 rxdfrmucastobss; /* 0xd0 */ + u16 rxbeaconobss; /* 0xd2 */ + u16 rxrsptmout; /* 0xd4 */ + u16 bcntxcancl; /* 0xd6 */ + u16 PAD; + u16 rxf0ovfl; /* 0xda */ + u16 rxf1ovfl; /* 0xdc */ + u16 rxf2ovfl; /* 0xde */ + u16 txsfovfl; /* 0xe0 */ + u16 pmqovfl; /* 0xe2 */ + u16 rxcgprqfrm; /* 0xe4 */ + u16 rxcgprsqovfl; /* 0xe6 */ + u16 txcgprsfail; /* 0xe8 */ + u16 txcgprssuc; /* 0xea */ + u16 prs_timeout; /* 0xec */ + u16 rxnack; + u16 frmscons; + u16 txnack; + u16 txglitch_nack; + u16 txburst; /* 0xf6 # tx bursts */ + u16 bphy_rxcrsglitch; /* bphy rx crs glitch */ + u16 phywatchdog; /* 0xfa # of phy watchdog events */ + u16 PAD; + u16 bphy_badplcp; /* bphy bad plcp */ +} macstat_t; + +/* dot11 core-specific control flags */ +#define SICF_PCLKE 0x0004 /* PHY clock enable */ +#define SICF_PRST 0x0008 /* PHY reset */ +#define SICF_MPCLKE 0x0010 /* MAC PHY clockcontrol enable */ +#define SICF_FREF 0x0020 /* PLL FreqRefSelect (corerev >= 5) */ +/* NOTE: the following bw bits only apply when the core is attached + * to a NPHY (and corerev >= 11 which it will always be for NPHYs). + */ +#define SICF_BWMASK 0x00c0 /* phy clock mask (b6 & b7) */ +#define SICF_BW40 0x0080 /* 40MHz BW (160MHz phyclk) */ +#define SICF_BW20 0x0040 /* 20MHz BW (80MHz phyclk) */ +#define SICF_BW10 0x0000 /* 10MHz BW (40MHz phyclk) */ +#define SICF_GMODE 0x2000 /* gmode enable */ + +/* dot11 core-specific status flags */ +#define SISF_2G_PHY 0x0001 /* 2.4G capable phy (corerev >= 5) */ +#define SISF_5G_PHY 0x0002 /* 5G capable phy (corerev >= 5) */ +#define SISF_FCLKA 0x0004 /* FastClkAvailable (corerev >= 5) */ +#define SISF_DB_PHY 0x0008 /* Dualband phy (corerev >= 11) */ + +/* === End of MAC reg, Beginning of PHY(b/a/g/n) reg, radio and LPPHY regs are separated === */ + +#define BPHY_REG_OFT_BASE 0x0 +/* offsets for indirect access to bphy registers */ +#define BPHY_BB_CONFIG 0x01 +#define BPHY_ADCBIAS 0x02 +#define BPHY_ANACORE 0x03 +#define BPHY_PHYCRSTH 0x06 +#define BPHY_TEST 0x0a +#define BPHY_PA_TX_TO 0x10 +#define BPHY_SYNTH_DC_TO 0x11 +#define BPHY_PA_TX_TIME_UP 0x12 +#define BPHY_RX_FLTR_TIME_UP 0x13 +#define BPHY_TX_POWER_OVERRIDE 0x14 +#define BPHY_RF_OVERRIDE 0x15 +#define BPHY_RF_TR_LOOKUP1 0x16 +#define BPHY_RF_TR_LOOKUP2 0x17 +#define BPHY_COEFFS 0x18 +#define BPHY_PLL_OUT 0x19 +#define BPHY_REFRESH_MAIN 0x1a +#define BPHY_REFRESH_TO0 0x1b +#define BPHY_REFRESH_TO1 0x1c +#define BPHY_RSSI_TRESH 0x20 +#define BPHY_IQ_TRESH_HH 0x21 +#define BPHY_IQ_TRESH_H 0x22 +#define BPHY_IQ_TRESH_L 0x23 +#define BPHY_IQ_TRESH_LL 0x24 +#define BPHY_GAIN 0x25 +#define BPHY_LNA_GAIN_RANGE 0x26 +#define BPHY_JSSI 0x27 +#define BPHY_TSSI_CTL 0x28 +#define BPHY_TSSI 0x29 +#define BPHY_TR_LOSS_CTL 0x2a +#define BPHY_LO_LEAKAGE 0x2b +#define BPHY_LO_RSSI_ACC 0x2c +#define BPHY_LO_IQMAG_ACC 0x2d +#define BPHY_TX_DC_OFF1 0x2e +#define BPHY_TX_DC_OFF2 0x2f +#define BPHY_PEAK_CNT_THRESH 0x30 +#define BPHY_FREQ_OFFSET 0x31 +#define BPHY_DIVERSITY_CTL 0x32 +#define BPHY_PEAK_ENERGY_LO 0x33 +#define BPHY_PEAK_ENERGY_HI 0x34 +#define BPHY_SYNC_CTL 0x35 +#define BPHY_TX_PWR_CTRL 0x36 +#define BPHY_TX_EST_PWR 0x37 +#define BPHY_STEP 0x38 +#define BPHY_WARMUP 0x39 +#define BPHY_LMS_CFF_READ 0x3a +#define BPHY_LMS_COEFF_I 0x3b +#define BPHY_LMS_COEFF_Q 0x3c +#define BPHY_SIG_POW 0x3d +#define BPHY_RFDC_CANCEL_CTL 0x3e +#define BPHY_HDR_TYPE 0x40 +#define BPHY_SFD_TO 0x41 +#define BPHY_SFD_CTL 0x42 +#define BPHY_DEBUG 0x43 +#define BPHY_RX_DELAY_COMP 0x44 +#define BPHY_CRS_DROP_TO 0x45 +#define BPHY_SHORT_SFD_NZEROS 0x46 +#define BPHY_DSSS_COEFF1 0x48 +#define BPHY_DSSS_COEFF2 0x49 +#define BPHY_CCK_COEFF1 0x4a +#define BPHY_CCK_COEFF2 0x4b +#define BPHY_TR_CORR 0x4c +#define BPHY_ANGLE_SCALE 0x4d +#define BPHY_TX_PWR_BASE_IDX 0x4e +#define BPHY_OPTIONAL_MODES2 0x4f +#define BPHY_CCK_LMS_STEP 0x50 +#define BPHY_BYPASS 0x51 +#define BPHY_CCK_DELAY_LONG 0x52 +#define BPHY_CCK_DELAY_SHORT 0x53 +#define BPHY_PPROC_CHAN_DELAY 0x54 +#define BPHY_DDFS_ENABLE 0x58 +#define BPHY_PHASE_SCALE 0x59 +#define BPHY_FREQ_CONTROL 0x5a +#define BPHY_LNA_GAIN_RANGE_10 0x5b +#define BPHY_LNA_GAIN_RANGE_32 0x5c +#define BPHY_OPTIONAL_MODES 0x5d +#define BPHY_RX_STATUS2 0x5e +#define BPHY_RX_STATUS3 0x5f +#define BPHY_DAC_CONTROL 0x60 +#define BPHY_ANA11G_FILT_CTRL 0x62 +#define BPHY_REFRESH_CTRL 0x64 +#define BPHY_RF_OVERRIDE2 0x65 +#define BPHY_SPUR_CANCEL_CTRL 0x66 +#define BPHY_FINE_DIGIGAIN_CTRL 0x67 +#define BPHY_RSSI_LUT 0x88 +#define BPHY_RSSI_LUT_END 0xa7 +#define BPHY_TSSI_LUT 0xa8 +#define BPHY_TSSI_LUT_END 0xc7 +#define BPHY_TSSI2PWR_LUT 0x380 +#define BPHY_TSSI2PWR_LUT_END 0x39f +#define BPHY_LOCOMP_LUT 0x3a0 +#define BPHY_LOCOMP_LUT_END 0x3bf +#define BPHY_TXGAIN_LUT 0x3c0 +#define BPHY_TXGAIN_LUT_END 0x3ff + +/* Bits in BB_CONFIG: */ +#define PHY_BBC_ANT_MASK 0x0180 +#define PHY_BBC_ANT_SHIFT 7 +#define BB_DARWIN 0x1000 +#define BBCFG_RESETCCA 0x4000 +#define BBCFG_RESETRX 0x8000 + +/* Bits in phytest(0x0a): */ +#define TST_DDFS 0x2000 +#define TST_TXFILT1 0x0800 +#define TST_UNSCRAM 0x0400 +#define TST_CARR_SUPP 0x0200 +#define TST_DC_COMP_LOOP 0x0100 +#define TST_LOOPBACK 0x0080 +#define TST_TXFILT0 0x0040 +#define TST_TXTEST_ENABLE 0x0020 +#define TST_TXTEST_RATE 0x0018 +#define TST_TXTEST_PHASE 0x0007 + +/* phytest txTestRate values */ +#define TST_TXTEST_RATE_1MBPS 0 +#define TST_TXTEST_RATE_2MBPS 1 +#define TST_TXTEST_RATE_5_5MBPS 2 +#define TST_TXTEST_RATE_11MBPS 3 +#define TST_TXTEST_RATE_SHIFT 3 + +#define SHM_BYT_CNT 0x2 /* IHR location */ +#define MAX_BYT_CNT 0x600 /* Maximum frame len */ + +#endif /* _D11_H */ diff --git a/drivers/staging/brcm80211/brcmsmac/sbhndpio.h b/drivers/staging/brcm80211/brcmsmac/sbhndpio.h new file mode 100644 index 000000000000..9eabdb56da73 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/sbhndpio.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _sbhndpio_h_ +#define _sbhndpio_h_ + +/* PIO structure, + * support two PIO format: 2 bytes access and 4 bytes access + * basic FIFO register set is per channel(transmit or receive) + * a pair of channels is defined for convenience + */ + +/* 2byte-wide pio register set per channel(xmt or rcv) */ +typedef volatile struct { + u16 fifocontrol; + u16 fifodata; + u16 fifofree; /* only valid in xmt channel, not in rcv channel */ + u16 PAD; +} pio2regs_t; + +/* a pair of pio channels(tx and rx) */ +typedef volatile struct { + pio2regs_t tx; + pio2regs_t rx; +} pio2regp_t; + +/* 4byte-wide pio register set per channel(xmt or rcv) */ +typedef volatile struct { + u32 fifocontrol; + u32 fifodata; +} pio4regs_t; + +/* a pair of pio channels(tx and rx) */ +typedef volatile struct { + pio4regs_t tx; + pio4regs_t rx; +} pio4regp_t; + +#endif /* _sbhndpio_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_event.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_event.c index dabd7094cd73..12b156a82ff2 100644 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_event.c +++ b/drivers/staging/brcm80211/brcmsmac/sys/wlc_event.c @@ -33,9 +33,6 @@ #include #include #include -#ifdef MSGTRACE -#include -#endif #include /* Local prototypes */ diff --git a/drivers/staging/brcm80211/include/bcmcdc.h b/drivers/staging/brcm80211/include/bcmcdc.h deleted file mode 100644 index ed4c4a517eca..000000000000 --- a/drivers/staging/brcm80211/include/bcmcdc.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include - -typedef struct cdc_ioctl { - u32 cmd; /* ioctl command value */ - u32 len; /* lower 16: output buflen; upper 16: - input buflen (excludes header) */ - u32 flags; /* flag defns given below */ - u32 status; /* status code returned from the device */ -} cdc_ioctl_t; - -/* Max valid buffer size that can be sent to the dongle */ -#define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN) - -/* len field is divided into input and output buffer lengths */ -#define CDCL_IOC_OUTLEN_MASK 0x0000FFFF /* maximum or expected - response length, */ - /* excluding IOCTL header */ -#define CDCL_IOC_OUTLEN_SHIFT 0 -#define CDCL_IOC_INLEN_MASK 0xFFFF0000 /* input buffer length, - excluding IOCTL header */ -#define CDCL_IOC_INLEN_SHIFT 16 - -/* CDC flag definitions */ -#define CDCF_IOC_ERROR 0x01 /* 0=success, 1=ioctl cmd failed */ -#define CDCF_IOC_SET 0x02 /* 0=get, 1=set cmd */ -#define CDCF_IOC_IF_MASK 0xF000 /* I/F index */ -#define CDCF_IOC_IF_SHIFT 12 -#define CDCF_IOC_ID_MASK 0xFFFF0000 /* used to uniquely id an ioctl - req/resp pairing */ -#define CDCF_IOC_ID_SHIFT 16 /* # of bits of shift for ID Mask */ - -#define CDC_IOC_IF_IDX(flags) \ - (((flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT) -#define CDC_IOC_ID(flags) \ - (((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT) - -#define CDC_GET_IF_IDX(hdr) \ - ((int)((((hdr)->flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT)) -#define CDC_SET_IF_IDX(hdr, idx) \ - ((hdr)->flags = (((hdr)->flags & ~CDCF_IOC_IF_MASK) | \ - ((idx) << CDCF_IOC_IF_SHIFT))) - -/* - * BDC header - * - * The BDC header is used on data packets to convey priority across USB. - */ - -#define BDC_HEADER_LEN 4 - -#define BDC_PROTO_VER 1 /* Protocol version */ - -#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */ -#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */ - -#define BDC_FLAG__UNUSED 0x03 /* Unassigned */ -#define BDC_FLAG_SUM_GOOD 0x04 /* Dongle has verified good - RX checksums */ -#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */ - -#define BDC_PRIORITY_MASK 0x7 - -#define BDC_FLAG2_FC_FLAG 0x10 /* flag to indicate if pkt contains */ - /* FLOW CONTROL info only */ -#define BDC_PRIORITY_FC_SHIFT 4 /* flow control info shift */ - -#define BDC_FLAG2_IF_MASK 0x0f /* APSTA: interface on which the - packet was received */ -#define BDC_FLAG2_IF_SHIFT 0 - -#define BDC_GET_IF_IDX(hdr) \ - ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT)) -#define BDC_SET_IF_IDX(hdr, idx) \ - ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \ - ((idx) << BDC_FLAG2_IF_SHIFT))) - -struct bdc_header { - u8 flags; /* Flags */ - u8 priority; /* 802.1d Priority 0:2 bits, 4:7 flow - control info for usb */ - u8 flags2; - u8 rssi; -}; diff --git a/drivers/staging/brcm80211/include/bcmsdbus.h b/drivers/staging/brcm80211/include/bcmsdbus.h deleted file mode 100644 index 89059dd8088b..000000000000 --- a/drivers/staging/brcm80211/include/bcmsdbus.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _sdio_api_h_ -#define _sdio_api_h_ - -#define SDIOH_API_RC_SUCCESS (0x00) -#define SDIOH_API_RC_FAIL (0x01) -#define SDIOH_API_SUCCESS(status) (status == 0) - -#define SDIOH_READ 0 /* Read request */ -#define SDIOH_WRITE 1 /* Write request */ - -#define SDIOH_DATA_FIX 0 /* Fixed addressing */ -#define SDIOH_DATA_INC 1 /* Incremental addressing */ - -#define SDIOH_CMD_TYPE_NORMAL 0 /* Normal command */ -#define SDIOH_CMD_TYPE_APPEND 1 /* Append command */ -#define SDIOH_CMD_TYPE_CUTTHRU 2 /* Cut-through command */ - -#define SDIOH_DATA_PIO 0 /* PIO mode */ -#define SDIOH_DATA_DMA 1 /* DMA mode */ - -typedef int SDIOH_API_RC; - -/* SDio Host structure */ -typedef struct sdioh_info sdioh_info_t; - -/* callback function, taking one arg */ -typedef void (*sdioh_cb_fn_t) (void *); - -/* attach, return handler on success, NULL if failed. - * The handler shall be provided by all subsequent calls. No local cache - * cfghdl points to the starting address of pci device mapped memory - */ -extern sdioh_info_t *sdioh_attach(struct osl_info *osh, void *cfghdl, uint irq); -extern SDIOH_API_RC sdioh_detach(struct osl_info *osh, sdioh_info_t *si); -extern SDIOH_API_RC sdioh_interrupt_register(sdioh_info_t *si, - sdioh_cb_fn_t fn, void *argh); -extern SDIOH_API_RC sdioh_interrupt_deregister(sdioh_info_t *si); - -/* query whether SD interrupt is enabled or not */ -extern SDIOH_API_RC sdioh_interrupt_query(sdioh_info_t *si, bool *onoff); - -/* enable or disable SD interrupt */ -extern SDIOH_API_RC sdioh_interrupt_set(sdioh_info_t *si, bool enable_disable); - -#if defined(BCMDBG) -extern bool sdioh_interrupt_pending(sdioh_info_t *si); -#endif - -extern int sdioh_claim_host_and_lock(sdioh_info_t *si); -extern int sdioh_release_host_and_unlock(sdioh_info_t *si); - -/* read or write one byte using cmd52 */ -extern SDIOH_API_RC sdioh_request_byte(sdioh_info_t *si, uint rw, uint fnc, - uint addr, u8 *byte); - -/* read or write 2/4 bytes using cmd53 */ -extern SDIOH_API_RC sdioh_request_word(sdioh_info_t *si, uint cmd_type, - uint rw, uint fnc, uint addr, - u32 *word, uint nbyte); - -/* read or write any buffer using cmd53 */ -extern SDIOH_API_RC sdioh_request_buffer(sdioh_info_t *si, uint pio_dma, - uint fix_inc, uint rw, uint fnc_num, - u32 addr, uint regwidth, - u32 buflen, u8 *buffer, - struct sk_buff *pkt); - -/* get cis data */ -extern SDIOH_API_RC sdioh_cis_read(sdioh_info_t *si, uint fuc, u8 *cis, - u32 length); - -extern SDIOH_API_RC sdioh_cfg_read(sdioh_info_t *si, uint fuc, u32 addr, - u8 *data); -extern SDIOH_API_RC sdioh_cfg_write(sdioh_info_t *si, uint fuc, u32 addr, - u8 *data); - -/* query number of io functions */ -extern uint sdioh_query_iofnum(sdioh_info_t *si); - -/* handle iovars */ -extern int sdioh_iovar_op(sdioh_info_t *si, const char *name, - void *params, int plen, void *arg, int len, bool set); - -/* Issue abort to the specified function and clear controller as needed */ -extern int sdioh_abort(sdioh_info_t *si, uint fnc); - -/* Start and Stop SDIO without re-enumerating the SD card. */ -extern int sdioh_start(sdioh_info_t *si, int stage); -extern int sdioh_stop(sdioh_info_t *si); - -/* Reset and re-initialize the device */ -extern int sdioh_sdio_reset(sdioh_info_t *si); - -/* Helper function */ -void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh); - -#endif /* _sdio_api_h_ */ diff --git a/drivers/staging/brcm80211/include/bcmsdh_sdmmc.h b/drivers/staging/brcm80211/include/bcmsdh_sdmmc.h deleted file mode 100644 index 4d671ddb3af1..000000000000 --- a/drivers/staging/brcm80211/include/bcmsdh_sdmmc.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __BCMSDH_SDMMC_H__ -#define __BCMSDH_SDMMC_H__ - -#ifdef BCMDBG -#define sd_err(x) do { if ((sd_msglevel & SDH_ERROR_VAL) && net_ratelimit()) printf x; } while (0) -#define sd_trace(x) do { if ((sd_msglevel & SDH_TRACE_VAL) && net_ratelimit()) printf x; } while (0) -#define sd_info(x) do { if ((sd_msglevel & SDH_INFO_VAL) && net_ratelimit()) printf x; } while (0) -#define sd_debug(x) do { if ((sd_msglevel & SDH_DEBUG_VAL) && net_ratelimit()) printf x; } while (0) -#define sd_data(x) do { if ((sd_msglevel & SDH_DATA_VAL) && net_ratelimit()) printf x; } while (0) -#define sd_ctrl(x) do { if ((sd_msglevel & SDH_CTRL_VAL) && net_ratelimit()) printf x; } while (0) -#else -#define sd_err(x) -#define sd_trace(x) -#define sd_info(x) -#define sd_debug(x) -#define sd_data(x) -#define sd_ctrl(x) -#endif - -/* Allocate/init/free per-OS private data */ -extern int sdioh_sdmmc_osinit(sdioh_info_t *sd); -extern void sdioh_sdmmc_osfree(sdioh_info_t *sd); - -#define BLOCK_SIZE_64 64 -#define BLOCK_SIZE_512 512 -#define BLOCK_SIZE_4318 64 -#define BLOCK_SIZE_4328 512 - -/* internal return code */ -#define SUCCESS 0 -#define ERROR 1 - -/* private bus modes */ -#define SDIOH_MODE_SD4 2 -#define CLIENT_INTR 0x100 /* Get rid of this! */ - -struct sdioh_info { - struct osl_info *osh; /* osh handler */ - bool client_intr_enabled; /* interrupt connnected flag */ - bool intr_handler_valid; /* client driver interrupt handler valid */ - sdioh_cb_fn_t intr_handler; /* registered interrupt handler */ - void *intr_handler_arg; /* argument to call interrupt handler */ - u16 intmask; /* Current active interrupts */ - void *sdos_info; /* Pointer to per-OS private data */ - - uint irq; /* Client irq */ - int intrcount; /* Client interrupts */ - bool sd_use_dma; /* DMA on CMD53 */ - bool sd_blockmode; /* sd_blockmode == false => 64 Byte Cmd 53s. */ - /* Must be on for sd_multiblock to be effective */ - bool use_client_ints; /* If this is false, make sure to restore */ - int sd_mode; /* SD1/SD4/SPI */ - int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */ - u8 num_funcs; /* Supported funcs on client */ - u32 com_cis_ptr; - u32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; - uint max_dma_len; - uint max_dma_descriptors; /* DMA Descriptors supported by this controller. */ - /* SDDMA_DESCRIPTOR SGList[32]; *//* Scatter/Gather DMA List */ -}; - -/************************************************************ - * Internal interfaces: per-port references into bcmsdh_sdmmc.c - */ - -/* Global message bits */ -extern uint sd_msglevel; - -/* OS-independent interrupt handler */ -extern bool check_client_intr(sdioh_info_t *sd); - -/* Core interrupt enable/disable of device interrupts */ -extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd); -extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd); - -/************************************************************** - * Internal interfaces: bcmsdh_sdmmc.c references to per-port code - */ - -/* Register mapping routines */ -extern u32 *sdioh_sdmmc_reg_map(struct osl_info *osh, s32 addr, int size); -extern void sdioh_sdmmc_reg_unmap(struct osl_info *osh, s32 addr, int size); - -/* Interrupt (de)registration routines */ -extern int sdioh_sdmmc_register_irq(sdioh_info_t *sd, uint irq); -extern void sdioh_sdmmc_free_irq(uint irq, sdioh_info_t *sd); - -typedef struct _BCMSDH_SDMMC_INSTANCE { - sdioh_info_t *sd; - struct sdio_func *func[SDIOD_MAX_IOFUNCS]; - u32 host_claimed; -} BCMSDH_SDMMC_INSTANCE, *PBCMSDH_SDMMC_INSTANCE; - -#endif /* __BCMSDH_SDMMC_H__ */ diff --git a/drivers/staging/brcm80211/include/bcmsrom_tbl.h b/drivers/staging/brcm80211/include/bcmsrom_tbl.h deleted file mode 100644 index 22ae7c1c18fb..000000000000 --- a/drivers/staging/brcm80211/include/bcmsrom_tbl.h +++ /dev/null @@ -1,583 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _bcmsrom_tbl_h_ -#define _bcmsrom_tbl_h_ - -#include "sbpcmcia.h" -#include "wlioctl.h" - -typedef struct { - const char *name; - u32 revmask; - u32 flags; - u16 off; - u16 mask; -} sromvar_t; - -#define SRFL_MORE 1 /* value continues as described by the next entry */ -#define SRFL_NOFFS 2 /* value bits can't be all one's */ -#define SRFL_PRHEX 4 /* value is in hexdecimal format */ -#define SRFL_PRSIGN 8 /* value is in signed decimal format */ -#define SRFL_CCODE 0x10 /* value is in country code format */ -#define SRFL_ETHADDR 0x20 /* value is an Ethernet address */ -#define SRFL_LEDDC 0x40 /* value is an LED duty cycle */ -#define SRFL_NOVAR 0x80 /* do not generate a nvram param, entry is for mfgc */ - -/* Assumptions: - * - Ethernet address spans across 3 consective words - * - * Table rules: - * - Add multiple entries next to each other if a value spans across multiple words - * (even multiple fields in the same word) with each entry except the last having - * it's SRFL_MORE bit set. - * - Ethernet address entry does not follow above rule and must not have SRFL_MORE - * bit set. Its SRFL_ETHADDR bit implies it takes multiple words. - * - The last entry's name field must be NULL to indicate the end of the table. Other - * entries must have non-NULL name. - */ - -static const sromvar_t pci_sromvars[] = { - {"devid", 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID, 0xffff}, - {"boardrev", 0x0000000e, SRFL_PRHEX, SROM_AABREV, SROM_BR_MASK}, - {"boardrev", 0x000000f0, SRFL_PRHEX, SROM4_BREV, 0xffff}, - {"boardrev", 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff}, - {"boardflags", 0x00000002, SRFL_PRHEX, SROM_BFL, 0xffff}, - {"boardflags", 0x00000004, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff}, - {"", 0, 0, SROM_BFL2, 0xffff}, - {"boardflags", 0x00000008, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff}, - {"", 0, 0, SROM3_BFL2, 0xffff}, - {"boardflags", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL0, 0xffff}, - {"", 0, 0, SROM4_BFL1, 0xffff}, - {"boardflags", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL0, 0xffff}, - {"", 0, 0, SROM5_BFL1, 0xffff}, - {"boardflags", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0, 0xffff}, - {"", 0, 0, SROM8_BFL1, 0xffff}, - {"boardflags2", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL2, 0xffff}, - {"", 0, 0, SROM4_BFL3, 0xffff}, - {"boardflags2", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL2, 0xffff}, - {"", 0, 0, SROM5_BFL3, 0xffff}, - {"boardflags2", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2, 0xffff}, - {"", 0, 0, SROM8_BFL3, 0xffff}, - {"boardtype", 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff}, - {"boardnum", 0x00000006, 0, SROM_MACLO_IL0, 0xffff}, - {"boardnum", 0x00000008, 0, SROM3_MACLO, 0xffff}, - {"boardnum", 0x00000010, 0, SROM4_MACLO, 0xffff}, - {"boardnum", 0x000000e0, 0, SROM5_MACLO, 0xffff}, - {"boardnum", 0xffffff00, 0, SROM8_MACLO, 0xffff}, - {"cc", 0x00000002, 0, SROM_AABREV, SROM_CC_MASK}, - {"regrev", 0x00000008, 0, SROM_OPO, 0xff00}, - {"regrev", 0x00000010, 0, SROM4_REGREV, 0x00ff}, - {"regrev", 0x000000e0, 0, SROM5_REGREV, 0x00ff}, - {"regrev", 0xffffff00, 0, SROM8_REGREV, 0x00ff}, - {"ledbh0", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0x00ff}, - {"ledbh1", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0xff00}, - {"ledbh2", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0x00ff}, - {"ledbh3", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0xff00}, - {"ledbh0", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0x00ff}, - {"ledbh1", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0xff00}, - {"ledbh2", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0x00ff}, - {"ledbh3", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0xff00}, - {"ledbh0", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0x00ff}, - {"ledbh1", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0xff00}, - {"ledbh2", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0x00ff}, - {"ledbh3", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0xff00}, - {"ledbh0", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff}, - {"ledbh1", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00}, - {"ledbh2", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff}, - {"ledbh3", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00}, - {"pa0b0", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB0, 0xffff}, - {"pa0b1", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB1, 0xffff}, - {"pa0b2", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB2, 0xffff}, - {"pa0itssit", 0x0000000e, 0, SROM_ITT, 0x00ff}, - {"pa0maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0x00ff}, - {"pa0b0", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff}, - {"pa0b1", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff}, - {"pa0b2", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff}, - {"pa0itssit", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00}, - {"pa0maxpwr", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff}, - {"opo", 0x0000000c, 0, SROM_OPO, 0x00ff}, - {"opo", 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff}, - {"aa2g", 0x0000000e, 0, SROM_AABREV, SROM_AA0_MASK}, - {"aa2g", 0x000000f0, 0, SROM4_AA, 0x00ff}, - {"aa2g", 0xffffff00, 0, SROM8_AA, 0x00ff}, - {"aa5g", 0x0000000e, 0, SROM_AABREV, SROM_AA1_MASK}, - {"aa5g", 0x000000f0, 0, SROM4_AA, 0xff00}, - {"aa5g", 0xffffff00, 0, SROM8_AA, 0xff00}, - {"ag0", 0x0000000e, 0, SROM_AG10, 0x00ff}, - {"ag1", 0x0000000e, 0, SROM_AG10, 0xff00}, - {"ag0", 0x000000f0, 0, SROM4_AG10, 0x00ff}, - {"ag1", 0x000000f0, 0, SROM4_AG10, 0xff00}, - {"ag2", 0x000000f0, 0, SROM4_AG32, 0x00ff}, - {"ag3", 0x000000f0, 0, SROM4_AG32, 0xff00}, - {"ag0", 0xffffff00, 0, SROM8_AG10, 0x00ff}, - {"ag1", 0xffffff00, 0, SROM8_AG10, 0xff00}, - {"ag2", 0xffffff00, 0, SROM8_AG32, 0x00ff}, - {"ag3", 0xffffff00, 0, SROM8_AG32, 0xff00}, - {"pa1b0", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB0, 0xffff}, - {"pa1b1", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB1, 0xffff}, - {"pa1b2", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB2, 0xffff}, - {"pa1lob0", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB0, 0xffff}, - {"pa1lob1", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB1, 0xffff}, - {"pa1lob2", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB2, 0xffff}, - {"pa1hib0", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB0, 0xffff}, - {"pa1hib1", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB1, 0xffff}, - {"pa1hib2", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB2, 0xffff}, - {"pa1itssit", 0x0000000e, 0, SROM_ITT, 0xff00}, - {"pa1maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0xff00}, - {"pa1lomaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0xff00}, - {"pa1himaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0x00ff}, - {"pa1b0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff}, - {"pa1b1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff}, - {"pa1b2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff}, - {"pa1lob0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_LC, 0xffff}, - {"pa1lob1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_LC, 0xffff}, - {"pa1lob2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_LC, 0xffff}, - {"pa1hib0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_HC, 0xffff}, - {"pa1hib1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_HC, 0xffff}, - {"pa1hib2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_HC, 0xffff}, - {"pa1itssit", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0xff00}, - {"pa1maxpwr", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff}, - {"pa1lomaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00}, - {"pa1himaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff}, - {"bxa2g", 0x00000008, 0, SROM_BXARSSI2G, 0x1800}, - {"rssisav2g", 0x00000008, 0, SROM_BXARSSI2G, 0x0700}, - {"rssismc2g", 0x00000008, 0, SROM_BXARSSI2G, 0x00f0}, - {"rssismf2g", 0x00000008, 0, SROM_BXARSSI2G, 0x000f}, - {"bxa2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800}, - {"rssisav2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700}, - {"rssismc2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0}, - {"rssismf2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f}, - {"bxa5g", 0x00000008, 0, SROM_BXARSSI5G, 0x1800}, - {"rssisav5g", 0x00000008, 0, SROM_BXARSSI5G, 0x0700}, - {"rssismc5g", 0x00000008, 0, SROM_BXARSSI5G, 0x00f0}, - {"rssismf5g", 0x00000008, 0, SROM_BXARSSI5G, 0x000f}, - {"bxa5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800}, - {"rssisav5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700}, - {"rssismc5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0}, - {"rssismf5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f}, - {"tri2g", 0x00000008, 0, SROM_TRI52G, 0x00ff}, - {"tri5g", 0x00000008, 0, SROM_TRI52G, 0xff00}, - {"tri5gl", 0x00000008, 0, SROM_TRI5GHL, 0x00ff}, - {"tri5gh", 0x00000008, 0, SROM_TRI5GHL, 0xff00}, - {"tri2g", 0xffffff00, 0, SROM8_TRI52G, 0x00ff}, - {"tri5g", 0xffffff00, 0, SROM8_TRI52G, 0xff00}, - {"tri5gl", 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff}, - {"tri5gh", 0xffffff00, 0, SROM8_TRI5GHL, 0xff00}, - {"rxpo2g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0x00ff}, - {"rxpo5g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0xff00}, - {"rxpo2g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff}, - {"rxpo5g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00}, - {"txchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_TXCHAIN_MASK}, - {"rxchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_RXCHAIN_MASK}, - {"antswitch", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_SWITCH_MASK}, - {"txchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_TXCHAIN_MASK}, - {"rxchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_RXCHAIN_MASK}, - {"antswitch", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_SWITCH_MASK}, - {"tssipos2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TSSIPOS_MASK}, - {"extpagain2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_EXTPA_GAIN_MASK}, - {"pdetrange2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_PDET_RANGE_MASK}, - {"triso2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TR_ISO_MASK}, - {"antswctl2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_ANTSWLUT_MASK}, - {"tssipos5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TSSIPOS_MASK}, - {"extpagain5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_EXTPA_GAIN_MASK}, - {"pdetrange5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_PDET_RANGE_MASK}, - {"triso5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TR_ISO_MASK}, - {"antswctl5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_ANTSWLUT_MASK}, - {"tempthresh", 0xffffff00, 0, SROM8_THERMAL, 0xff00}, - {"tempoffset", 0xffffff00, 0, SROM8_THERMAL, 0x00ff}, - {"txpid2ga0", 0x000000f0, 0, SROM4_TXPID2G, 0x00ff}, - {"txpid2ga1", 0x000000f0, 0, SROM4_TXPID2G, 0xff00}, - {"txpid2ga2", 0x000000f0, 0, SROM4_TXPID2G + 1, 0x00ff}, - {"txpid2ga3", 0x000000f0, 0, SROM4_TXPID2G + 1, 0xff00}, - {"txpid5ga0", 0x000000f0, 0, SROM4_TXPID5G, 0x00ff}, - {"txpid5ga1", 0x000000f0, 0, SROM4_TXPID5G, 0xff00}, - {"txpid5ga2", 0x000000f0, 0, SROM4_TXPID5G + 1, 0x00ff}, - {"txpid5ga3", 0x000000f0, 0, SROM4_TXPID5G + 1, 0xff00}, - {"txpid5gla0", 0x000000f0, 0, SROM4_TXPID5GL, 0x00ff}, - {"txpid5gla1", 0x000000f0, 0, SROM4_TXPID5GL, 0xff00}, - {"txpid5gla2", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0x00ff}, - {"txpid5gla3", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0xff00}, - {"txpid5gha0", 0x000000f0, 0, SROM4_TXPID5GH, 0x00ff}, - {"txpid5gha1", 0x000000f0, 0, SROM4_TXPID5GH, 0xff00}, - {"txpid5gha2", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0x00ff}, - {"txpid5gha3", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0xff00}, - - {"ccode", 0x0000000f, SRFL_CCODE, SROM_CCODE, 0xffff}, - {"ccode", 0x00000010, SRFL_CCODE, SROM4_CCODE, 0xffff}, - {"ccode", 0x000000e0, SRFL_CCODE, SROM5_CCODE, 0xffff}, - {"ccode", 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff}, - {"macaddr", 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff}, - {"macaddr", 0x000000e0, SRFL_ETHADDR, SROM5_MACHI, 0xffff}, - {"macaddr", 0x00000010, SRFL_ETHADDR, SROM4_MACHI, 0xffff}, - {"macaddr", 0x00000008, SRFL_ETHADDR, SROM3_MACHI, 0xffff}, - {"il0macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_IL0, 0xffff}, - {"et1macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_ET1, 0xffff}, - {"leddc", 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC, 0xffff}, - {"leddc", 0x000000e0, SRFL_NOFFS | SRFL_LEDDC, SROM5_LEDDC, 0xffff}, - {"leddc", 0x00000010, SRFL_NOFFS | SRFL_LEDDC, SROM4_LEDDC, 0xffff}, - {"leddc", 0x00000008, SRFL_NOFFS | SRFL_LEDDC, SROM3_LEDDC, 0xffff}, - {"rawtempsense", 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0x01ff}, - {"measpower", 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0xfe00}, - {"tempsense_slope", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, - 0x00ff}, - {"tempcorrx", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0xfc00}, - {"tempsense_option", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, - 0x0300}, - {"freqoffset_corr", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, - 0x000f}, - {"iqcal_swp_dis", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0010}, - {"hw_iqcal_en", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0020}, - {"phycal_tempdelta", 0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA, 0x00ff}, - - {"cck2gpo", 0x000000f0, 0, SROM4_2G_CCKPO, 0xffff}, - {"cck2gpo", 0x00000100, 0, SROM8_2G_CCKPO, 0xffff}, - {"ofdm2gpo", 0x000000f0, SRFL_MORE, SROM4_2G_OFDMPO, 0xffff}, - {"", 0, 0, SROM4_2G_OFDMPO + 1, 0xffff}, - {"ofdm5gpo", 0x000000f0, SRFL_MORE, SROM4_5G_OFDMPO, 0xffff}, - {"", 0, 0, SROM4_5G_OFDMPO + 1, 0xffff}, - {"ofdm5glpo", 0x000000f0, SRFL_MORE, SROM4_5GL_OFDMPO, 0xffff}, - {"", 0, 0, SROM4_5GL_OFDMPO + 1, 0xffff}, - {"ofdm5ghpo", 0x000000f0, SRFL_MORE, SROM4_5GH_OFDMPO, 0xffff}, - {"", 0, 0, SROM4_5GH_OFDMPO + 1, 0xffff}, - {"ofdm2gpo", 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff}, - {"", 0, 0, SROM8_2G_OFDMPO + 1, 0xffff}, - {"ofdm5gpo", 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff}, - {"", 0, 0, SROM8_5G_OFDMPO + 1, 0xffff}, - {"ofdm5glpo", 0x00000100, SRFL_MORE, SROM8_5GL_OFDMPO, 0xffff}, - {"", 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff}, - {"ofdm5ghpo", 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff}, - {"", 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff}, - {"mcs2gpo0", 0x000000f0, 0, SROM4_2G_MCSPO, 0xffff}, - {"mcs2gpo1", 0x000000f0, 0, SROM4_2G_MCSPO + 1, 0xffff}, - {"mcs2gpo2", 0x000000f0, 0, SROM4_2G_MCSPO + 2, 0xffff}, - {"mcs2gpo3", 0x000000f0, 0, SROM4_2G_MCSPO + 3, 0xffff}, - {"mcs2gpo4", 0x000000f0, 0, SROM4_2G_MCSPO + 4, 0xffff}, - {"mcs2gpo5", 0x000000f0, 0, SROM4_2G_MCSPO + 5, 0xffff}, - {"mcs2gpo6", 0x000000f0, 0, SROM4_2G_MCSPO + 6, 0xffff}, - {"mcs2gpo7", 0x000000f0, 0, SROM4_2G_MCSPO + 7, 0xffff}, - {"mcs5gpo0", 0x000000f0, 0, SROM4_5G_MCSPO, 0xffff}, - {"mcs5gpo1", 0x000000f0, 0, SROM4_5G_MCSPO + 1, 0xffff}, - {"mcs5gpo2", 0x000000f0, 0, SROM4_5G_MCSPO + 2, 0xffff}, - {"mcs5gpo3", 0x000000f0, 0, SROM4_5G_MCSPO + 3, 0xffff}, - {"mcs5gpo4", 0x000000f0, 0, SROM4_5G_MCSPO + 4, 0xffff}, - {"mcs5gpo5", 0x000000f0, 0, SROM4_5G_MCSPO + 5, 0xffff}, - {"mcs5gpo6", 0x000000f0, 0, SROM4_5G_MCSPO + 6, 0xffff}, - {"mcs5gpo7", 0x000000f0, 0, SROM4_5G_MCSPO + 7, 0xffff}, - {"mcs5glpo0", 0x000000f0, 0, SROM4_5GL_MCSPO, 0xffff}, - {"mcs5glpo1", 0x000000f0, 0, SROM4_5GL_MCSPO + 1, 0xffff}, - {"mcs5glpo2", 0x000000f0, 0, SROM4_5GL_MCSPO + 2, 0xffff}, - {"mcs5glpo3", 0x000000f0, 0, SROM4_5GL_MCSPO + 3, 0xffff}, - {"mcs5glpo4", 0x000000f0, 0, SROM4_5GL_MCSPO + 4, 0xffff}, - {"mcs5glpo5", 0x000000f0, 0, SROM4_5GL_MCSPO + 5, 0xffff}, - {"mcs5glpo6", 0x000000f0, 0, SROM4_5GL_MCSPO + 6, 0xffff}, - {"mcs5glpo7", 0x000000f0, 0, SROM4_5GL_MCSPO + 7, 0xffff}, - {"mcs5ghpo0", 0x000000f0, 0, SROM4_5GH_MCSPO, 0xffff}, - {"mcs5ghpo1", 0x000000f0, 0, SROM4_5GH_MCSPO + 1, 0xffff}, - {"mcs5ghpo2", 0x000000f0, 0, SROM4_5GH_MCSPO + 2, 0xffff}, - {"mcs5ghpo3", 0x000000f0, 0, SROM4_5GH_MCSPO + 3, 0xffff}, - {"mcs5ghpo4", 0x000000f0, 0, SROM4_5GH_MCSPO + 4, 0xffff}, - {"mcs5ghpo5", 0x000000f0, 0, SROM4_5GH_MCSPO + 5, 0xffff}, - {"mcs5ghpo6", 0x000000f0, 0, SROM4_5GH_MCSPO + 6, 0xffff}, - {"mcs5ghpo7", 0x000000f0, 0, SROM4_5GH_MCSPO + 7, 0xffff}, - {"mcs2gpo0", 0x00000100, 0, SROM8_2G_MCSPO, 0xffff}, - {"mcs2gpo1", 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff}, - {"mcs2gpo2", 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff}, - {"mcs2gpo3", 0x00000100, 0, SROM8_2G_MCSPO + 3, 0xffff}, - {"mcs2gpo4", 0x00000100, 0, SROM8_2G_MCSPO + 4, 0xffff}, - {"mcs2gpo5", 0x00000100, 0, SROM8_2G_MCSPO + 5, 0xffff}, - {"mcs2gpo6", 0x00000100, 0, SROM8_2G_MCSPO + 6, 0xffff}, - {"mcs2gpo7", 0x00000100, 0, SROM8_2G_MCSPO + 7, 0xffff}, - {"mcs5gpo0", 0x00000100, 0, SROM8_5G_MCSPO, 0xffff}, - {"mcs5gpo1", 0x00000100, 0, SROM8_5G_MCSPO + 1, 0xffff}, - {"mcs5gpo2", 0x00000100, 0, SROM8_5G_MCSPO + 2, 0xffff}, - {"mcs5gpo3", 0x00000100, 0, SROM8_5G_MCSPO + 3, 0xffff}, - {"mcs5gpo4", 0x00000100, 0, SROM8_5G_MCSPO + 4, 0xffff}, - {"mcs5gpo5", 0x00000100, 0, SROM8_5G_MCSPO + 5, 0xffff}, - {"mcs5gpo6", 0x00000100, 0, SROM8_5G_MCSPO + 6, 0xffff}, - {"mcs5gpo7", 0x00000100, 0, SROM8_5G_MCSPO + 7, 0xffff}, - {"mcs5glpo0", 0x00000100, 0, SROM8_5GL_MCSPO, 0xffff}, - {"mcs5glpo1", 0x00000100, 0, SROM8_5GL_MCSPO + 1, 0xffff}, - {"mcs5glpo2", 0x00000100, 0, SROM8_5GL_MCSPO + 2, 0xffff}, - {"mcs5glpo3", 0x00000100, 0, SROM8_5GL_MCSPO + 3, 0xffff}, - {"mcs5glpo4", 0x00000100, 0, SROM8_5GL_MCSPO + 4, 0xffff}, - {"mcs5glpo5", 0x00000100, 0, SROM8_5GL_MCSPO + 5, 0xffff}, - {"mcs5glpo6", 0x00000100, 0, SROM8_5GL_MCSPO + 6, 0xffff}, - {"mcs5glpo7", 0x00000100, 0, SROM8_5GL_MCSPO + 7, 0xffff}, - {"mcs5ghpo0", 0x00000100, 0, SROM8_5GH_MCSPO, 0xffff}, - {"mcs5ghpo1", 0x00000100, 0, SROM8_5GH_MCSPO + 1, 0xffff}, - {"mcs5ghpo2", 0x00000100, 0, SROM8_5GH_MCSPO + 2, 0xffff}, - {"mcs5ghpo3", 0x00000100, 0, SROM8_5GH_MCSPO + 3, 0xffff}, - {"mcs5ghpo4", 0x00000100, 0, SROM8_5GH_MCSPO + 4, 0xffff}, - {"mcs5ghpo5", 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff}, - {"mcs5ghpo6", 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff}, - {"mcs5ghpo7", 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff}, - {"cddpo", 0x000000f0, 0, SROM4_CDDPO, 0xffff}, - {"stbcpo", 0x000000f0, 0, SROM4_STBCPO, 0xffff}, - {"bw40po", 0x000000f0, 0, SROM4_BW40PO, 0xffff}, - {"bwduppo", 0x000000f0, 0, SROM4_BWDUPPO, 0xffff}, - {"cddpo", 0x00000100, 0, SROM8_CDDPO, 0xffff}, - {"stbcpo", 0x00000100, 0, SROM8_STBCPO, 0xffff}, - {"bw40po", 0x00000100, 0, SROM8_BW40PO, 0xffff}, - {"bwduppo", 0x00000100, 0, SROM8_BWDUPPO, 0xffff}, - - /* power per rate from sromrev 9 */ - {"cckbw202gpo", 0xfffffe00, 0, SROM9_2GPO_CCKBW20, 0xffff}, - {"cckbw20ul2gpo", 0xfffffe00, 0, SROM9_2GPO_CCKBW20UL, 0xffff}, - {"legofdmbw202gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_LOFDMBW20, - 0xffff}, - {"", 0, 0, SROM9_2GPO_LOFDMBW20 + 1, 0xffff}, - {"legofdmbw20ul2gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_LOFDMBW20UL, - 0xffff}, - {"", 0, 0, SROM9_2GPO_LOFDMBW20UL + 1, 0xffff}, - {"legofdmbw205glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_LOFDMBW20, - 0xffff}, - {"", 0, 0, SROM9_5GLPO_LOFDMBW20 + 1, 0xffff}, - {"legofdmbw20ul5glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_LOFDMBW20UL, - 0xffff}, - {"", 0, 0, SROM9_5GLPO_LOFDMBW20UL + 1, 0xffff}, - {"legofdmbw205gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_LOFDMBW20, - 0xffff}, - {"", 0, 0, SROM9_5GMPO_LOFDMBW20 + 1, 0xffff}, - {"legofdmbw20ul5gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_LOFDMBW20UL, - 0xffff}, - {"", 0, 0, SROM9_5GMPO_LOFDMBW20UL + 1, 0xffff}, - {"legofdmbw205ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_LOFDMBW20, - 0xffff}, - {"", 0, 0, SROM9_5GHPO_LOFDMBW20 + 1, 0xffff}, - {"legofdmbw20ul5ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_LOFDMBW20UL, - 0xffff}, - {"", 0, 0, SROM9_5GHPO_LOFDMBW20UL + 1, 0xffff}, - {"mcsbw202gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20, 0xffff}, - {"", 0, 0, SROM9_2GPO_MCSBW20 + 1, 0xffff}, - {"mcsbw20ul2gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20UL, 0xffff}, - {"", 0, 0, SROM9_2GPO_MCSBW20UL + 1, 0xffff}, - {"mcsbw402gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW40, 0xffff}, - {"", 0, 0, SROM9_2GPO_MCSBW40 + 1, 0xffff}, - {"mcsbw205glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20, 0xffff}, - {"", 0, 0, SROM9_5GLPO_MCSBW20 + 1, 0xffff}, - {"mcsbw20ul5glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20UL, - 0xffff}, - {"", 0, 0, SROM9_5GLPO_MCSBW20UL + 1, 0xffff}, - {"mcsbw405glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW40, 0xffff}, - {"", 0, 0, SROM9_5GLPO_MCSBW40 + 1, 0xffff}, - {"mcsbw205gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20, 0xffff}, - {"", 0, 0, SROM9_5GMPO_MCSBW20 + 1, 0xffff}, - {"mcsbw20ul5gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20UL, - 0xffff}, - {"", 0, 0, SROM9_5GMPO_MCSBW20UL + 1, 0xffff}, - {"mcsbw405gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW40, 0xffff}, - {"", 0, 0, SROM9_5GMPO_MCSBW40 + 1, 0xffff}, - {"mcsbw205ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20, 0xffff}, - {"", 0, 0, SROM9_5GHPO_MCSBW20 + 1, 0xffff}, - {"mcsbw20ul5ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20UL, - 0xffff}, - {"", 0, 0, SROM9_5GHPO_MCSBW20UL + 1, 0xffff}, - {"mcsbw405ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW40, 0xffff}, - {"", 0, 0, SROM9_5GHPO_MCSBW40 + 1, 0xffff}, - {"mcs32po", 0xfffffe00, 0, SROM9_PO_MCS32, 0xffff}, - {"legofdm40duppo", 0xfffffe00, 0, SROM9_PO_LOFDM40DUP, 0xffff}, - - {NULL, 0, 0, 0, 0} -}; - -static const sromvar_t perpath_pci_sromvars[] = { - {"maxp2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0x00ff}, - {"itt2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff00}, - {"itt5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff00}, - {"pa2gw0a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA, 0xffff}, - {"pa2gw1a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 1, 0xffff}, - {"pa2gw2a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 2, 0xffff}, - {"pa2gw3a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 3, 0xffff}, - {"maxp5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0x00ff}, - {"maxp5gha", 0x000000f0, 0, SROM4_5GLH_MAXP, 0x00ff}, - {"maxp5gla", 0x000000f0, 0, SROM4_5GLH_MAXP, 0xff00}, - {"pa5gw0a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA, 0xffff}, - {"pa5gw1a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 1, 0xffff}, - {"pa5gw2a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 2, 0xffff}, - {"pa5gw3a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 3, 0xffff}, - {"pa5glw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA, 0xffff}, - {"pa5glw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 1, 0xffff}, - {"pa5glw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 2, 0xffff}, - {"pa5glw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 3, 0xffff}, - {"pa5ghw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA, 0xffff}, - {"pa5ghw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 1, 0xffff}, - {"pa5ghw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 2, 0xffff}, - {"pa5ghw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 3, 0xffff}, - {"maxp2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff}, - {"itt2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00}, - {"itt5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00}, - {"pa2gw0a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA, 0xffff}, - {"pa2gw1a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 1, 0xffff}, - {"pa2gw2a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 2, 0xffff}, - {"maxp5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0x00ff}, - {"maxp5gha", 0xffffff00, 0, SROM8_5GLH_MAXP, 0x00ff}, - {"maxp5gla", 0xffffff00, 0, SROM8_5GLH_MAXP, 0xff00}, - {"pa5gw0a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA, 0xffff}, - {"pa5gw1a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 1, 0xffff}, - {"pa5gw2a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 2, 0xffff}, - {"pa5glw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA, 0xffff}, - {"pa5glw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 1, 0xffff}, - {"pa5glw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 2, 0xffff}, - {"pa5ghw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA, 0xffff}, - {"pa5ghw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 1, 0xffff}, - {"pa5ghw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 2, 0xffff}, - {NULL, 0, 0, 0, 0} -}; - -#if !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP)) -#define PHY_TYPE_N 4 /* N-Phy value */ -#define PHY_TYPE_LP 5 /* LP-Phy value */ -#endif /* !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP)) */ -#if !defined(PHY_TYPE_NULL) -#define PHY_TYPE_NULL 0xf /* Invalid Phy value */ -#endif /* !defined(PHY_TYPE_NULL) */ - -typedef struct { - u16 phy_type; - u16 bandrange; - u16 chain; - const char *vars; -} pavars_t; - -static const pavars_t pavars[] = { - /* NPHY */ - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 0, "pa2gw0a0 pa2gw1a0 pa2gw2a0"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 1, "pa2gw0a1 pa2gw1a1 pa2gw2a1"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 0, - "pa5glw0a0 pa5glw1a0 pa5glw2a0"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 1, - "pa5glw0a1 pa5glw1a1 pa5glw2a1"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 0, "pa5gw0a0 pa5gw1a0 pa5gw2a0"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 1, "pa5gw0a1 pa5gw1a1 pa5gw2a1"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 0, - "pa5ghw0a0 pa5ghw1a0 pa5ghw2a0"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 1, - "pa5ghw0a1 pa5ghw1a1 pa5ghw2a1"}, - /* LPPHY */ - {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_2G, 0, "pa0b0 pa0b1 pa0b2"}, - {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GL, 0, "pa1lob0 pa1lob1 pa1lob2"}, - {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GM, 0, "pa1b0 pa1b1 pa1b2"}, - {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GH, 0, "pa1hib0 pa1hib1 pa1hib2"}, - {PHY_TYPE_NULL, 0, 0, ""} -}; - -typedef struct { - u16 phy_type; - u16 bandrange; - const char *vars; -} povars_t; - -static const povars_t povars[] = { - /* NPHY */ - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, - "mcs2gpo0 mcs2gpo1 mcs2gpo2 mcs2gpo3 " - "mcs2gpo4 mcs2gpo5 mcs2gpo6 mcs2gpo7"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, - "mcs5glpo0 mcs5glpo1 mcs5glpo2 mcs5glpo3 " - "mcs5glpo4 mcs5glpo5 mcs5glpo6 mcs5glpo7"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, - "mcs5gpo0 mcs5gpo1 mcs5gpo2 mcs5gpo3 " - "mcs5gpo4 mcs5gpo5 mcs5gpo6 mcs5gpo7"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, - "mcs5ghpo0 mcs5ghpo1 mcs5ghpo2 mcs5ghpo3 " - "mcs5ghpo4 mcs5ghpo5 mcs5ghpo6 mcs5ghpo7"}, - {PHY_TYPE_NULL, 0, ""} -}; - -typedef struct { - u8 tag; /* Broadcom subtag name */ - u8 len; /* Length field of the tuple, note that it includes the - * subtag name (1 byte): 1 + tuple content length - */ - const char *params; -} cis_tuple_t; - -#define OTP_RAW (0xff - 1) /* Reserved tuple number for wrvar Raw input */ -#define OTP_VERS_1 (0xff - 2) /* CISTPL_VERS_1 */ -#define OTP_MANFID (0xff - 3) /* CISTPL_MANFID */ -#define OTP_RAW1 (0xff - 4) /* Like RAW, but comes first */ - -static const cis_tuple_t cis_hnbuvars[] = { - {OTP_RAW1, 0, ""}, /* special case */ - {OTP_VERS_1, 0, "smanf sproductname"}, /* special case (non BRCM tuple) */ - {OTP_MANFID, 4, "2manfid 2prodid"}, /* special case (non BRCM tuple) */ - {HNBU_SROMREV, 2, "1sromrev"}, - /* NOTE: subdevid is also written to boardtype. - * Need to write HNBU_BOARDTYPE to change it if it is different. - */ - {HNBU_CHIPID, 11, "2vendid 2devid 2chiprev 2subvendid 2subdevid"}, - {HNBU_BOARDREV, 3, "2boardrev"}, - {HNBU_PAPARMS, 10, "2pa0b0 2pa0b1 2pa0b2 1pa0itssit 1pa0maxpwr 1opo"}, - {HNBU_AA, 3, "1aa2g 1aa5g"}, - {HNBU_AA, 3, "1aa0 1aa1"}, /* backward compatibility */ - {HNBU_AG, 5, "1ag0 1ag1 1ag2 1ag3"}, - {HNBU_BOARDFLAGS, 9, "4boardflags 4boardflags2"}, - {HNBU_LEDS, 5, "1ledbh0 1ledbh1 1ledbh2 1ledbh3"}, - {HNBU_CCODE, 4, "2ccode 1cctl"}, - {HNBU_CCKPO, 3, "2cckpo"}, - {HNBU_OFDMPO, 5, "4ofdmpo"}, - {HNBU_RDLID, 3, "2rdlid"}, - {HNBU_RSSISMBXA2G, 3, "0rssismf2g 0rssismc2g 0rssisav2g 0bxa2g"}, /* special case */ - {HNBU_RSSISMBXA5G, 3, "0rssismf5g 0rssismc5g 0rssisav5g 0bxa5g"}, /* special case */ - {HNBU_XTALFREQ, 5, "4xtalfreq"}, - {HNBU_TRI2G, 2, "1tri2g"}, - {HNBU_TRI5G, 4, "1tri5gl 1tri5g 1tri5gh"}, - {HNBU_RXPO2G, 2, "1rxpo2g"}, - {HNBU_RXPO5G, 2, "1rxpo5g"}, - {HNBU_BOARDNUM, 3, "2boardnum"}, - {HNBU_MACADDR, 7, "6macaddr"}, /* special case */ - {HNBU_RDLSN, 3, "2rdlsn"}, - {HNBU_BOARDTYPE, 3, "2boardtype"}, - {HNBU_LEDDC, 3, "2leddc"}, - {HNBU_RDLRNDIS, 2, "1rdlndis"}, - {HNBU_CHAINSWITCH, 5, "1txchain 1rxchain 2antswitch"}, - {HNBU_REGREV, 2, "1regrev"}, - {HNBU_FEM, 5, "0antswctl2g, 0triso2g, 0pdetrange2g, 0extpagain2g, 0tssipos2g" "0antswctl5g, 0triso5g, 0pdetrange5g, 0extpagain5g, 0tssipos5g"}, /* special case */ - {HNBU_PAPARMS_C0, 31, "1maxp2ga0 1itt2ga0 2pa2gw0a0 2pa2gw1a0 " - "2pa2gw2a0 1maxp5ga0 1itt5ga0 1maxp5gha0 1maxp5gla0 2pa5gw0a0 " - "2pa5gw1a0 2pa5gw2a0 2pa5glw0a0 2pa5glw1a0 2pa5glw2a0 2pa5ghw0a0 " - "2pa5ghw1a0 2pa5ghw2a0"}, - {HNBU_PAPARMS_C1, 31, "1maxp2ga1 1itt2ga1 2pa2gw0a1 2pa2gw1a1 " - "2pa2gw2a1 1maxp5ga1 1itt5ga1 1maxp5gha1 1maxp5gla1 2pa5gw0a1 " - "2pa5gw1a1 2pa5gw2a1 2pa5glw0a1 2pa5glw1a1 2pa5glw2a1 2pa5ghw0a1 " - "2pa5ghw1a1 2pa5ghw2a1"}, - {HNBU_PO_CCKOFDM, 19, "2cck2gpo 4ofdm2gpo 4ofdm5gpo 4ofdm5glpo " - "4ofdm5ghpo"}, - {HNBU_PO_MCS2G, 17, "2mcs2gpo0 2mcs2gpo1 2mcs2gpo2 2mcs2gpo3 " - "2mcs2gpo4 2mcs2gpo5 2mcs2gpo6 2mcs2gpo7"}, - {HNBU_PO_MCS5GM, 17, "2mcs5gpo0 2mcs5gpo1 2mcs5gpo2 2mcs5gpo3 " - "2mcs5gpo4 2mcs5gpo5 2mcs5gpo6 2mcs5gpo7"}, - {HNBU_PO_MCS5GLH, 33, "2mcs5glpo0 2mcs5glpo1 2mcs5glpo2 2mcs5glpo3 " - "2mcs5glpo4 2mcs5glpo5 2mcs5glpo6 2mcs5glpo7 " - "2mcs5ghpo0 2mcs5ghpo1 2mcs5ghpo2 2mcs5ghpo3 " - "2mcs5ghpo4 2mcs5ghpo5 2mcs5ghpo6 2mcs5ghpo7"}, - {HNBU_CCKFILTTYPE, 2, "1cckdigfilttype"}, - {HNBU_PO_CDD, 3, "2cddpo"}, - {HNBU_PO_STBC, 3, "2stbcpo"}, - {HNBU_PO_40M, 3, "2bw40po"}, - {HNBU_PO_40MDUP, 3, "2bwduppo"}, - {HNBU_RDLRWU, 2, "1rdlrwu"}, - {HNBU_WPS, 3, "1wpsgpio 1wpsled"}, - {HNBU_USBFS, 2, "1usbfs"}, - {HNBU_CUSTOM1, 5, "4customvar1"}, - {OTP_RAW, 0, ""}, /* special case */ - {HNBU_OFDMPO5G, 13, "4ofdm5gpo 4ofdm5glpo 4ofdm5ghpo"}, - {HNBU_USBEPNUM, 3, "2usbepnum"}, - {0xFF, 0, ""} -}; - -#endif /* _bcmsrom_tbl_h_ */ diff --git a/drivers/staging/brcm80211/include/d11.h b/drivers/staging/brcm80211/include/d11.h deleted file mode 100644 index 50883af62496..000000000000 --- a/drivers/staging/brcm80211/include/d11.h +++ /dev/null @@ -1,1765 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _D11_H -#define _D11_H - -#ifndef WL_RSSI_ANT_MAX -#define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */ -#elif WL_RSSI_ANT_MAX != 4 -#error "WL_RSSI_ANT_MAX does not match" -#endif - -/* cpp contortions to concatenate w/arg prescan */ -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif - -#define BCN_TMPL_LEN 512 /* length of the BCN template area */ - -/* RX FIFO numbers */ -#define RX_FIFO 0 /* data and ctl frames */ -#define RX_TXSTATUS_FIFO 3 /* RX fifo for tx status packages */ - -/* TX FIFO numbers using WME Access Classes */ -#define TX_AC_BK_FIFO 0 /* Access Category Background TX FIFO */ -#define TX_AC_BE_FIFO 1 /* Access Category Best-Effort TX FIFO */ -#define TX_AC_VI_FIFO 2 /* Access Class Video TX FIFO */ -#define TX_AC_VO_FIFO 3 /* Access Class Voice TX FIFO */ -#define TX_BCMC_FIFO 4 /* Broadcast/Multicast TX FIFO */ -#define TX_ATIM_FIFO 5 /* TX fifo for ATIM window info */ - -/* Addr is byte address used by SW; offset is word offset used by uCode */ - -/* Per AC TX limit settings */ -#define M_AC_TXLMT_BASE_ADDR (0x180 * 2) -#define M_AC_TXLMT_ADDR(_ac) (M_AC_TXLMT_BASE_ADDR + (2 * (_ac))) - -/* Legacy TX FIFO numbers */ -#define TX_DATA_FIFO TX_AC_BE_FIFO -#define TX_CTL_FIFO TX_AC_VO_FIFO - -typedef volatile struct { - u32 intstatus; - u32 intmask; -} intctrlregs_t; - -/* read: 32-bit register that can be read as 32-bit or as 2 16-bit - * write: only low 16b-it half can be written - */ -typedef volatile union { - u32 pmqhostdata; /* read only! */ - struct { - u16 pmqctrlstatus; /* read/write */ - u16 PAD; - } w; -} pmqreg_t; - -/* pio register set 2/4 bytes union for d11 fifo */ -typedef volatile union { - pio2regp_t b2; /* < corerev 8 */ - pio4regp_t b4; /* >= corerev 8 */ -} u_pioreg_t; - -/* dma/pio corerev < 11 */ -typedef volatile struct { - dma32regp_t dmaregs[8]; /* 0x200 - 0x2fc */ - u_pioreg_t pioregs[8]; /* 0x300 */ -} fifo32_t; - -/* dma/pio corerev >= 11 */ -typedef volatile struct { - dma64regs_t dmaxmt; /* dma tx */ - pio4regs_t piotx; /* pio tx */ - dma64regs_t dmarcv; /* dma rx */ - pio4regs_t piorx; /* pio rx */ -} fifo64_t; - -/* - * Host Interface Registers - * - primed from hnd_cores/dot11mac/systemC/registers/ihr.h - * - but definitely not complete - */ -typedef volatile struct _d11regs { - /* Device Control ("semi-standard host registers") */ - u32 PAD[3]; /* 0x0 - 0x8 */ - u32 biststatus; /* 0xC */ - u32 biststatus2; /* 0x10 */ - u32 PAD; /* 0x14 */ - u32 gptimer; /* 0x18 *//* for corerev >= 3 */ - u32 usectimer; /* 0x1c *//* for corerev >= 26 */ - - /* Interrupt Control *//* 0x20 */ - intctrlregs_t intctrlregs[8]; - - u32 PAD[40]; /* 0x60 - 0xFC */ - - /* tx fifos 6-7 and rx fifos 1-3 removed in corerev 5 */ - u32 intrcvlazy[4]; /* 0x100 - 0x10C */ - - u32 PAD[4]; /* 0x110 - 0x11c */ - - u32 maccontrol; /* 0x120 */ - u32 maccommand; /* 0x124 */ - u32 macintstatus; /* 0x128 */ - u32 macintmask; /* 0x12C */ - - /* Transmit Template Access */ - u32 tplatewrptr; /* 0x130 */ - u32 tplatewrdata; /* 0x134 */ - u32 PAD[2]; /* 0x138 - 0x13C */ - - /* PMQ registers */ - pmqreg_t pmqreg; /* 0x140 */ - u32 pmqpatl; /* 0x144 */ - u32 pmqpath; /* 0x148 */ - u32 PAD; /* 0x14C */ - - u32 chnstatus; /* 0x150 */ - u32 psmdebug; /* 0x154 *//* for corerev >= 3 */ - u32 phydebug; /* 0x158 *//* for corerev >= 3 */ - u32 machwcap; /* 0x15C *//* Corerev >= 13 */ - - /* Extended Internal Objects */ - u32 objaddr; /* 0x160 */ - u32 objdata; /* 0x164 */ - u32 PAD[2]; /* 0x168 - 0x16c */ - - /* New txstatus registers on corerev >= 5 */ - u32 frmtxstatus; /* 0x170 */ - u32 frmtxstatus2; /* 0x174 */ - u32 PAD[2]; /* 0x178 - 0x17c */ - - /* New TSF host access on corerev >= 3 */ - - u32 tsf_timerlow; /* 0x180 */ - u32 tsf_timerhigh; /* 0x184 */ - u32 tsf_cfprep; /* 0x188 */ - u32 tsf_cfpstart; /* 0x18c */ - u32 tsf_cfpmaxdur32; /* 0x190 */ - u32 PAD[3]; /* 0x194 - 0x19c */ - - u32 maccontrol1; /* 0x1a0 */ - u32 machwcap1; /* 0x1a4 */ - u32 PAD[14]; /* 0x1a8 - 0x1dc */ - - /* Clock control and hardware workarounds (corerev >= 13) */ - u32 clk_ctl_st; /* 0x1e0 */ - u32 hw_war; - u32 d11_phypllctl; /* 0x1e8 (corerev == 16), the phypll request/avail bits are - * moved to clk_ctl_st for corerev >= 17 - */ - u32 PAD[5]; /* 0x1ec - 0x1fc */ - - /* 0x200-0x37F dma/pio registers */ - volatile union { - fifo32_t f32regs; /* tx fifos 6-7 and rx fifos 1-3 (corerev < 5) */ - fifo64_t f64regs[6]; /* on corerev >= 11 */ - } fifo; - - /* FIFO diagnostic port access */ - dma32diag_t dmafifo; /* 0x380 - 0x38C */ - - u32 aggfifocnt; /* 0x390 */ - u32 aggfifodata; /* 0x394 */ - u32 PAD[16]; /* 0x398 - 0x3d4 */ - u16 radioregaddr; /* 0x3d8 */ - u16 radioregdata; /* 0x3da */ - - /* time delay between the change on rf disable input and radio shutdown corerev 10 */ - u32 rfdisabledly; /* 0x3DC */ - - /* PHY register access */ - u16 phyversion; /* 0x3e0 - 0x0 */ - u16 phybbconfig; /* 0x3e2 - 0x1 */ - u16 phyadcbias; /* 0x3e4 - 0x2 Bphy only */ - u16 phyanacore; /* 0x3e6 - 0x3 pwwrdwn on aphy */ - u16 phyrxstatus0; /* 0x3e8 - 0x4 */ - u16 phyrxstatus1; /* 0x3ea - 0x5 */ - u16 phycrsth; /* 0x3ec - 0x6 */ - u16 phytxerror; /* 0x3ee - 0x7 */ - u16 phychannel; /* 0x3f0 - 0x8 */ - u16 PAD[1]; /* 0x3f2 - 0x9 */ - u16 phytest; /* 0x3f4 - 0xa */ - u16 phy4waddr; /* 0x3f6 - 0xb */ - u16 phy4wdatahi; /* 0x3f8 - 0xc */ - u16 phy4wdatalo; /* 0x3fa - 0xd */ - u16 phyregaddr; /* 0x3fc - 0xe */ - u16 phyregdata; /* 0x3fe - 0xf */ - - /* IHR *//* 0x400 - 0x7FE */ - - /* RXE Block */ - u16 PAD[3]; /* 0x400 - 0x406 */ - u16 rcv_fifo_ctl; /* 0x406 */ - u16 PAD; /* 0x408 - 0x40a */ - u16 rcv_frm_cnt; /* 0x40a */ - u16 PAD[4]; /* 0x40a - 0x414 */ - u16 rssi; /* 0x414 */ - u16 PAD[5]; /* 0x414 - 0x420 */ - u16 rcm_ctl; /* 0x420 */ - u16 rcm_mat_data; /* 0x422 */ - u16 rcm_mat_mask; /* 0x424 */ - u16 rcm_mat_dly; /* 0x426 */ - u16 rcm_cond_mask_l; /* 0x428 */ - u16 rcm_cond_mask_h; /* 0x42A */ - u16 rcm_cond_dly; /* 0x42C */ - u16 PAD[1]; /* 0x42E */ - u16 ext_ihr_addr; /* 0x430 */ - u16 ext_ihr_data; /* 0x432 */ - u16 rxe_phyrs_2; /* 0x434 */ - u16 rxe_phyrs_3; /* 0x436 */ - u16 phy_mode; /* 0x438 */ - u16 rcmta_ctl; /* 0x43a */ - u16 rcmta_size; /* 0x43c */ - u16 rcmta_addr0; /* 0x43e */ - u16 rcmta_addr1; /* 0x440 */ - u16 rcmta_addr2; /* 0x442 */ - u16 PAD[30]; /* 0x444 - 0x480 */ - - /* PSM Block *//* 0x480 - 0x500 */ - - u16 PAD; /* 0x480 */ - u16 psm_maccontrol_h; /* 0x482 */ - u16 psm_macintstatus_l; /* 0x484 */ - u16 psm_macintstatus_h; /* 0x486 */ - u16 psm_macintmask_l; /* 0x488 */ - u16 psm_macintmask_h; /* 0x48A */ - u16 PAD; /* 0x48C */ - u16 psm_maccommand; /* 0x48E */ - u16 psm_brc; /* 0x490 */ - u16 psm_phy_hdr_param; /* 0x492 */ - u16 psm_postcard; /* 0x494 */ - u16 psm_pcard_loc_l; /* 0x496 */ - u16 psm_pcard_loc_h; /* 0x498 */ - u16 psm_gpio_in; /* 0x49A */ - u16 psm_gpio_out; /* 0x49C */ - u16 psm_gpio_oe; /* 0x49E */ - - u16 psm_bred_0; /* 0x4A0 */ - u16 psm_bred_1; /* 0x4A2 */ - u16 psm_bred_2; /* 0x4A4 */ - u16 psm_bred_3; /* 0x4A6 */ - u16 psm_brcl_0; /* 0x4A8 */ - u16 psm_brcl_1; /* 0x4AA */ - u16 psm_brcl_2; /* 0x4AC */ - u16 psm_brcl_3; /* 0x4AE */ - u16 psm_brpo_0; /* 0x4B0 */ - u16 psm_brpo_1; /* 0x4B2 */ - u16 psm_brpo_2; /* 0x4B4 */ - u16 psm_brpo_3; /* 0x4B6 */ - u16 psm_brwk_0; /* 0x4B8 */ - u16 psm_brwk_1; /* 0x4BA */ - u16 psm_brwk_2; /* 0x4BC */ - u16 psm_brwk_3; /* 0x4BE */ - - u16 psm_base_0; /* 0x4C0 */ - u16 psm_base_1; /* 0x4C2 */ - u16 psm_base_2; /* 0x4C4 */ - u16 psm_base_3; /* 0x4C6 */ - u16 psm_base_4; /* 0x4C8 */ - u16 psm_base_5; /* 0x4CA */ - u16 psm_base_6; /* 0x4CC */ - u16 psm_pc_reg_0; /* 0x4CE */ - u16 psm_pc_reg_1; /* 0x4D0 */ - u16 psm_pc_reg_2; /* 0x4D2 */ - u16 psm_pc_reg_3; /* 0x4D4 */ - u16 PAD[0xD]; /* 0x4D6 - 0x4DE */ - u16 psm_corectlsts; /* 0x4f0 *//* Corerev >= 13 */ - u16 PAD[0x7]; /* 0x4f2 - 0x4fE */ - - /* TXE0 Block *//* 0x500 - 0x580 */ - u16 txe_ctl; /* 0x500 */ - u16 txe_aux; /* 0x502 */ - u16 txe_ts_loc; /* 0x504 */ - u16 txe_time_out; /* 0x506 */ - u16 txe_wm_0; /* 0x508 */ - u16 txe_wm_1; /* 0x50A */ - u16 txe_phyctl; /* 0x50C */ - u16 txe_status; /* 0x50E */ - u16 txe_mmplcp0; /* 0x510 */ - u16 txe_mmplcp1; /* 0x512 */ - u16 txe_phyctl1; /* 0x514 */ - - u16 PAD[0x05]; /* 0x510 - 0x51E */ - - /* Transmit control */ - u16 xmtfifodef; /* 0x520 */ - u16 xmtfifo_frame_cnt; /* 0x522 *//* Corerev >= 16 */ - u16 xmtfifo_byte_cnt; /* 0x524 *//* Corerev >= 16 */ - u16 xmtfifo_head; /* 0x526 *//* Corerev >= 16 */ - u16 xmtfifo_rd_ptr; /* 0x528 *//* Corerev >= 16 */ - u16 xmtfifo_wr_ptr; /* 0x52A *//* Corerev >= 16 */ - u16 xmtfifodef1; /* 0x52C *//* Corerev >= 16 */ - - u16 PAD[0x09]; /* 0x52E - 0x53E */ - - u16 xmtfifocmd; /* 0x540 */ - u16 xmtfifoflush; /* 0x542 */ - u16 xmtfifothresh; /* 0x544 */ - u16 xmtfifordy; /* 0x546 */ - u16 xmtfifoprirdy; /* 0x548 */ - u16 xmtfiforqpri; /* 0x54A */ - u16 xmttplatetxptr; /* 0x54C */ - u16 PAD; /* 0x54E */ - u16 xmttplateptr; /* 0x550 */ - u16 smpl_clct_strptr; /* 0x552 *//* Corerev >= 22 */ - u16 smpl_clct_stpptr; /* 0x554 *//* Corerev >= 22 */ - u16 smpl_clct_curptr; /* 0x556 *//* Corerev >= 22 */ - u16 PAD[0x04]; /* 0x558 - 0x55E */ - u16 xmttplatedatalo; /* 0x560 */ - u16 xmttplatedatahi; /* 0x562 */ - - u16 PAD[2]; /* 0x564 - 0x566 */ - - u16 xmtsel; /* 0x568 */ - u16 xmttxcnt; /* 0x56A */ - u16 xmttxshmaddr; /* 0x56C */ - - u16 PAD[0x09]; /* 0x56E - 0x57E */ - - /* TXE1 Block */ - u16 PAD[0x40]; /* 0x580 - 0x5FE */ - - /* TSF Block */ - u16 PAD[0X02]; /* 0x600 - 0x602 */ - u16 tsf_cfpstrt_l; /* 0x604 */ - u16 tsf_cfpstrt_h; /* 0x606 */ - u16 PAD[0X05]; /* 0x608 - 0x610 */ - u16 tsf_cfppretbtt; /* 0x612 */ - u16 PAD[0XD]; /* 0x614 - 0x62C */ - u16 tsf_clk_frac_l; /* 0x62E */ - u16 tsf_clk_frac_h; /* 0x630 */ - u16 PAD[0X14]; /* 0x632 - 0x658 */ - u16 tsf_random; /* 0x65A */ - u16 PAD[0x05]; /* 0x65C - 0x664 */ - /* GPTimer 2 registers are corerev >= 3 */ - u16 tsf_gpt2_stat; /* 0x666 */ - u16 tsf_gpt2_ctr_l; /* 0x668 */ - u16 tsf_gpt2_ctr_h; /* 0x66A */ - u16 tsf_gpt2_val_l; /* 0x66C */ - u16 tsf_gpt2_val_h; /* 0x66E */ - u16 tsf_gptall_stat; /* 0x670 */ - u16 PAD[0x07]; /* 0x672 - 0x67E */ - - /* IFS Block */ - u16 ifs_sifs_rx_tx_tx; /* 0x680 */ - u16 ifs_sifs_nav_tx; /* 0x682 */ - u16 ifs_slot; /* 0x684 */ - u16 PAD; /* 0x686 */ - u16 ifs_ctl; /* 0x688 */ - u16 PAD[0x3]; /* 0x68a - 0x68F */ - u16 ifsstat; /* 0x690 */ - u16 ifsmedbusyctl; /* 0x692 */ - u16 iftxdur; /* 0x694 */ - u16 PAD[0x3]; /* 0x696 - 0x69b */ - /* EDCF support in dot11macs with corerevs >= 16 */ - u16 ifs_aifsn; /* 0x69c */ - u16 ifs_ctl1; /* 0x69e */ - - /* New slow clock registers on corerev >= 5 */ - u16 scc_ctl; /* 0x6a0 */ - u16 scc_timer_l; /* 0x6a2 */ - u16 scc_timer_h; /* 0x6a4 */ - u16 scc_frac; /* 0x6a6 */ - u16 scc_fastpwrup_dly; /* 0x6a8 */ - u16 scc_per; /* 0x6aa */ - u16 scc_per_frac; /* 0x6ac */ - u16 scc_cal_timer_l; /* 0x6ae */ - u16 scc_cal_timer_h; /* 0x6b0 */ - u16 PAD; /* 0x6b2 */ - - u16 PAD[0x26]; - - /* NAV Block */ - u16 nav_ctl; /* 0x700 */ - u16 navstat; /* 0x702 */ - u16 PAD[0x3e]; /* 0x702 - 0x77E */ - - /* WEP/PMQ Block *//* 0x780 - 0x7FE */ - u16 PAD[0x20]; /* 0x780 - 0x7BE */ - - u16 wepctl; /* 0x7C0 */ - u16 wepivloc; /* 0x7C2 */ - u16 wepivkey; /* 0x7C4 */ - u16 wepwkey; /* 0x7C6 */ - - u16 PAD[4]; /* 0x7C8 - 0x7CE */ - u16 pcmctl; /* 0X7D0 */ - u16 pcmstat; /* 0X7D2 */ - u16 PAD[6]; /* 0x7D4 - 0x7DE */ - - u16 pmqctl; /* 0x7E0 */ - u16 pmqstatus; /* 0x7E2 */ - u16 pmqpat0; /* 0x7E4 */ - u16 pmqpat1; /* 0x7E6 */ - u16 pmqpat2; /* 0x7E8 */ - - u16 pmqdat; /* 0x7EA */ - u16 pmqdator; /* 0x7EC */ - u16 pmqhst; /* 0x7EE */ - u16 pmqpath0; /* 0x7F0 */ - u16 pmqpath1; /* 0x7F2 */ - u16 pmqpath2; /* 0x7F4 */ - u16 pmqdath; /* 0x7F6 */ - - u16 PAD[0x04]; /* 0x7F8 - 0x7FE */ - - /* SHM *//* 0x800 - 0xEFE */ - u16 PAD[0x380]; /* 0x800 - 0xEFE */ - - /* SB configuration registers: 0xF00 */ - sbconfig_t sbconfig; /* sb config regs occupy top 256 bytes */ -} d11regs_t; - -#define PIHR_BASE 0x0400 /* byte address of packed IHR region */ - -/* biststatus */ -#define BT_DONE (1U << 31) /* bist done */ -#define BT_B2S (1 << 30) /* bist2 ram summary bit */ - -/* intstatus and intmask */ -#define I_PC (1 << 10) /* pci descriptor error */ -#define I_PD (1 << 11) /* pci data error */ -#define I_DE (1 << 12) /* descriptor protocol error */ -#define I_RU (1 << 13) /* receive descriptor underflow */ -#define I_RO (1 << 14) /* receive fifo overflow */ -#define I_XU (1 << 15) /* transmit fifo underflow */ -#define I_RI (1 << 16) /* receive interrupt */ -#define I_XI (1 << 24) /* transmit interrupt */ - -/* interrupt receive lazy */ -#define IRL_TO_MASK 0x00ffffff /* timeout */ -#define IRL_FC_MASK 0xff000000 /* frame count */ -#define IRL_FC_SHIFT 24 /* frame count */ - -/* maccontrol register */ -#define MCTL_GMODE (1U << 31) -#define MCTL_DISCARD_PMQ (1 << 30) -#define MCTL_WAKE (1 << 26) -#define MCTL_HPS (1 << 25) -#define MCTL_PROMISC (1 << 24) -#define MCTL_KEEPBADFCS (1 << 23) -#define MCTL_KEEPCONTROL (1 << 22) -#define MCTL_PHYLOCK (1 << 21) -#define MCTL_BCNS_PROMISC (1 << 20) -#define MCTL_LOCK_RADIO (1 << 19) -#define MCTL_AP (1 << 18) -#define MCTL_INFRA (1 << 17) -#define MCTL_BIGEND (1 << 16) -#define MCTL_GPOUT_SEL_MASK (3 << 14) -#define MCTL_GPOUT_SEL_SHIFT 14 -#define MCTL_EN_PSMDBG (1 << 13) -#define MCTL_IHR_EN (1 << 10) -#define MCTL_SHM_UPPER (1 << 9) -#define MCTL_SHM_EN (1 << 8) -#define MCTL_PSM_JMP_0 (1 << 2) -#define MCTL_PSM_RUN (1 << 1) -#define MCTL_EN_MAC (1 << 0) - -/* maccommand register */ -#define MCMD_BCN0VLD (1 << 0) -#define MCMD_BCN1VLD (1 << 1) -#define MCMD_DIRFRMQVAL (1 << 2) -#define MCMD_CCA (1 << 3) -#define MCMD_BG_NOISE (1 << 4) -#define MCMD_SKIP_SHMINIT (1 << 5) /* only used for simulation */ -#define MCMD_SAMPLECOLL MCMD_SKIP_SHMINIT /* reuse for sample collect */ - -/* macintstatus/macintmask */ -#define MI_MACSSPNDD (1 << 0) /* MAC has gracefully suspended */ -#define MI_BCNTPL (1 << 1) /* beacon template available */ -#define MI_TBTT (1 << 2) /* TBTT indication */ -#define MI_BCNSUCCESS (1 << 3) /* beacon successfully tx'd */ -#define MI_BCNCANCLD (1 << 4) /* beacon canceled (IBSS) */ -#define MI_ATIMWINEND (1 << 5) /* end of ATIM-window (IBSS) */ -#define MI_PMQ (1 << 6) /* PMQ entries available */ -#define MI_NSPECGEN_0 (1 << 7) /* non-specific gen-stat bits that are set by PSM */ -#define MI_NSPECGEN_1 (1 << 8) /* non-specific gen-stat bits that are set by PSM */ -#define MI_MACTXERR (1 << 9) /* MAC level Tx error */ -#define MI_NSPECGEN_3 (1 << 10) /* non-specific gen-stat bits that are set by PSM */ -#define MI_PHYTXERR (1 << 11) /* PHY Tx error */ -#define MI_PME (1 << 12) /* Power Management Event */ -#define MI_GP0 (1 << 13) /* General-purpose timer0 */ -#define MI_GP1 (1 << 14) /* General-purpose timer1 */ -#define MI_DMAINT (1 << 15) /* (ORed) DMA-interrupts */ -#define MI_TXSTOP (1 << 16) /* MAC has completed a TX FIFO Suspend/Flush */ -#define MI_CCA (1 << 17) /* MAC has completed a CCA measurement */ -#define MI_BG_NOISE (1 << 18) /* MAC has collected background noise samples */ -#define MI_DTIM_TBTT (1 << 19) /* MBSS DTIM TBTT indication */ -#define MI_PRQ (1 << 20) /* Probe response queue needs attention */ -#define MI_PWRUP (1 << 21) /* Radio/PHY has been powered back up. */ -#define MI_RESERVED3 (1 << 22) -#define MI_RESERVED2 (1 << 23) -#define MI_RESERVED1 (1 << 25) -#define MI_RFDISABLE (1 << 28) /* MAC detected a change on RF Disable input - * (corerev >= 10) - */ -#define MI_TFS (1 << 29) /* MAC has completed a TX (corerev >= 5) */ -#define MI_PHYCHANGED (1 << 30) /* A phy status change wrt G mode */ -#define MI_TO (1U << 31) /* general purpose timeout (corerev >= 3) */ - -/* Mac capabilities registers */ -/* machwcap */ -#define MCAP_TKIPMIC 0x80000000 /* TKIP MIC hardware present */ - -/* pmqhost data */ -#define PMQH_DATA_MASK 0xffff0000 /* data entry of head pmq entry */ -#define PMQH_BSSCFG 0x00100000 /* PM entry for BSS config */ -#define PMQH_PMOFF 0x00010000 /* PM Mode OFF: power save off */ -#define PMQH_PMON 0x00020000 /* PM Mode ON: power save on */ -#define PMQH_DASAT 0x00040000 /* Dis-associated or De-authenticated */ -#define PMQH_ATIMFAIL 0x00080000 /* ATIM not acknowledged */ -#define PMQH_DEL_ENTRY 0x00000001 /* delete head entry */ -#define PMQH_DEL_MULT 0x00000002 /* delete head entry to cur read pointer -1 */ -#define PMQH_OFLO 0x00000004 /* pmq overflow indication */ -#define PMQH_NOT_EMPTY 0x00000008 /* entries are present in pmq */ - -/* phydebug (corerev >= 3) */ -#define PDBG_CRS (1 << 0) /* phy is asserting carrier sense */ -#define PDBG_TXA (1 << 1) /* phy is taking xmit byte from mac this cycle */ -#define PDBG_TXF (1 << 2) /* mac is instructing the phy to transmit a frame */ -#define PDBG_TXE (1 << 3) /* phy is signalling a transmit Error to the mac */ -#define PDBG_RXF (1 << 4) /* phy detected the end of a valid frame preamble */ -#define PDBG_RXS (1 << 5) /* phy detected the end of a valid PLCP header */ -#define PDBG_RXFRG (1 << 6) /* rx start not asserted */ -#define PDBG_RXV (1 << 7) /* mac is taking receive byte from phy this cycle */ -#define PDBG_RFD (1 << 16) /* RF portion of the radio is disabled */ - -/* objaddr register */ -#define OBJADDR_SEL_MASK 0x000F0000 -#define OBJADDR_UCM_SEL 0x00000000 -#define OBJADDR_SHM_SEL 0x00010000 -#define OBJADDR_SCR_SEL 0x00020000 -#define OBJADDR_IHR_SEL 0x00030000 -#define OBJADDR_RCMTA_SEL 0x00040000 -#define OBJADDR_SRCHM_SEL 0x00060000 -#define OBJADDR_WINC 0x01000000 -#define OBJADDR_RINC 0x02000000 -#define OBJADDR_AUTO_INC 0x03000000 - -#define WEP_PCMADDR 0x07d4 -#define WEP_PCMDATA 0x07d6 - -/* frmtxstatus */ -#define TXS_V (1 << 0) /* valid bit */ -#define TXS_STATUS_MASK 0xffff -/* sw mask to map txstatus for corerevs <= 4 to be the same as for corerev > 4 */ -#define TXS_COMPAT_MASK 0x3 -#define TXS_COMPAT_SHIFT 1 -#define TXS_FID_MASK 0xffff0000 -#define TXS_FID_SHIFT 16 - -/* frmtxstatus2 */ -#define TXS_SEQ_MASK 0xffff -#define TXS_PTX_MASK 0xff0000 -#define TXS_PTX_SHIFT 16 -#define TXS_MU_MASK 0x01000000 -#define TXS_MU_SHIFT 24 - -/* clk_ctl_st, corerev >= 17 */ -#define CCS_ERSRC_REQ_D11PLL 0x00000100 /* d11 core pll request */ -#define CCS_ERSRC_REQ_PHYPLL 0x00000200 /* PHY pll request */ -#define CCS_ERSRC_AVAIL_D11PLL 0x01000000 /* d11 core pll available */ -#define CCS_ERSRC_AVAIL_PHYPLL 0x02000000 /* PHY pll available */ - -/* HT Cloclk Ctrl and Clock Avail for 4313 */ -#define CCS_ERSRC_REQ_HT 0x00000010 /* HT avail request */ -#define CCS_ERSRC_AVAIL_HT 0x00020000 /* HT clock available */ - -/* d11_pwrctl, corerev16 only */ -#define D11_PHYPLL_AVAIL_REQ 0x000010000 /* request PHY PLL resource */ -#define D11_PHYPLL_AVAIL_STS 0x001000000 /* PHY PLL is available */ - -/* tsf_cfprep register */ -#define CFPREP_CBI_MASK 0xffffffc0 -#define CFPREP_CBI_SHIFT 6 -#define CFPREP_CFPP 0x00000001 - -/* tx fifo sizes for corerev >= 9 */ -/* tx fifo sizes values are in terms of 256 byte blocks */ -#define TXFIFOCMD_RESET_MASK (1 << 15) /* reset */ -#define TXFIFOCMD_FIFOSEL_SHIFT 8 /* fifo */ -#define TXFIFO_FIFOTOP_SHIFT 8 /* fifo start */ - -#define TXFIFO_START_BLK16 65 /* Base address + 32 * 512 B/P */ -#define TXFIFO_START_BLK 6 /* Base address + 6 * 256 B */ -#define TXFIFO_SIZE_UNIT 256 /* one unit corresponds to 256 bytes */ -#define MBSS16_TEMPLMEM_MINBLKS 65 /* one unit corresponds to 256 bytes */ - -/* phy versions, PhyVersion:Revision field */ -#define PV_AV_MASK 0xf000 /* analog block version */ -#define PV_AV_SHIFT 12 /* analog block version bitfield offset */ -#define PV_PT_MASK 0x0f00 /* phy type */ -#define PV_PT_SHIFT 8 /* phy type bitfield offset */ -#define PV_PV_MASK 0x000f /* phy version */ -#define PHY_TYPE(v) ((v & PV_PT_MASK) >> PV_PT_SHIFT) - -/* phy types, PhyVersion:PhyType field */ -#define PHY_TYPE_N 4 /* N-Phy value */ -#define PHY_TYPE_SSN 6 /* SSLPN-Phy value */ -#define PHY_TYPE_LCN 8 /* LCN-Phy value */ -#define PHY_TYPE_LCNXN 9 /* LCNXN-Phy value */ -#define PHY_TYPE_NULL 0xf /* Invalid Phy value */ - -/* analog types, PhyVersion:AnalogType field */ -#define ANA_11N_013 5 - -/* 802.11a PLCP header def */ -typedef struct ofdm_phy_hdr ofdm_phy_hdr_t; -struct ofdm_phy_hdr { - u8 rlpt[3]; /* rate, length, parity, tail */ - u16 service; - u8 pad; -} __attribute__((packed)); - -#define D11A_PHY_HDR_GRATE(phdr) ((phdr)->rlpt[0] & 0x0f) -#define D11A_PHY_HDR_GRES(phdr) (((phdr)->rlpt[0] >> 4) & 0x01) -#define D11A_PHY_HDR_GLENGTH(phdr) (((u32 *)((phdr)->rlpt) >> 5) & 0x0fff) -#define D11A_PHY_HDR_GPARITY(phdr) (((phdr)->rlpt[3] >> 1) & 0x01) -#define D11A_PHY_HDR_GTAIL(phdr) (((phdr)->rlpt[3] >> 2) & 0x3f) - -/* rate encoded per 802.11a-1999 sec 17.3.4.1 */ -#define D11A_PHY_HDR_SRATE(phdr, rate) \ - ((phdr)->rlpt[0] = ((phdr)->rlpt[0] & 0xf0) | ((rate) & 0xf)) -/* set reserved field to zero */ -#define D11A_PHY_HDR_SRES(phdr) ((phdr)->rlpt[0] &= 0xef) -/* length is number of octets in PSDU */ -#define D11A_PHY_HDR_SLENGTH(phdr, length) \ - (*(u32 *)((phdr)->rlpt) = *(u32 *)((phdr)->rlpt) | \ - (((length) & 0x0fff) << 5)) -/* set the tail to all zeros */ -#define D11A_PHY_HDR_STAIL(phdr) ((phdr)->rlpt[3] &= 0x03) - -#define D11A_PHY_HDR_LEN_L 3 /* low-rate part of PLCP header */ -#define D11A_PHY_HDR_LEN_R 2 /* high-rate part of PLCP header */ - -#define D11A_PHY_TX_DELAY (2) /* 2.1 usec */ - -#define D11A_PHY_HDR_TIME (4) /* low-rate part of PLCP header */ -#define D11A_PHY_PRE_TIME (16) -#define D11A_PHY_PREHDR_TIME (D11A_PHY_PRE_TIME + D11A_PHY_HDR_TIME) - -/* 802.11b PLCP header def */ -typedef struct cck_phy_hdr cck_phy_hdr_t; -struct cck_phy_hdr { - u8 signal; - u8 service; - u16 length; - u16 crc; -} __attribute__((packed)); - -#define D11B_PHY_HDR_LEN 6 - -#define D11B_PHY_TX_DELAY (3) /* 3.4 usec */ - -#define D11B_PHY_LHDR_TIME (D11B_PHY_HDR_LEN << 3) -#define D11B_PHY_LPRE_TIME (144) -#define D11B_PHY_LPREHDR_TIME (D11B_PHY_LPRE_TIME + D11B_PHY_LHDR_TIME) - -#define D11B_PHY_SHDR_TIME (D11B_PHY_LHDR_TIME >> 1) -#define D11B_PHY_SPRE_TIME (D11B_PHY_LPRE_TIME >> 1) -#define D11B_PHY_SPREHDR_TIME (D11B_PHY_SPRE_TIME + D11B_PHY_SHDR_TIME) - -#define D11B_PLCP_SIGNAL_LOCKED (1 << 2) -#define D11B_PLCP_SIGNAL_LE (1 << 7) - -#define MIMO_PLCP_MCS_MASK 0x7f /* mcs index */ -#define MIMO_PLCP_40MHZ 0x80 /* 40 Hz frame */ -#define MIMO_PLCP_AMPDU 0x08 /* ampdu */ - -#define WLC_GET_CCK_PLCP_LEN(plcp) (plcp[4] + (plcp[5] << 8)) -#define WLC_GET_MIMO_PLCP_LEN(plcp) (plcp[1] + (plcp[2] << 8)) -#define WLC_SET_MIMO_PLCP_LEN(plcp, len) \ - do { \ - plcp[1] = len & 0xff; \ - plcp[2] = ((len >> 8) & 0xff); \ - } while (0); - -#define WLC_SET_MIMO_PLCP_AMPDU(plcp) (plcp[3] |= MIMO_PLCP_AMPDU) -#define WLC_CLR_MIMO_PLCP_AMPDU(plcp) (plcp[3] &= ~MIMO_PLCP_AMPDU) -#define WLC_IS_MIMO_PLCP_AMPDU(plcp) (plcp[3] & MIMO_PLCP_AMPDU) - -/* The dot11a PLCP header is 5 bytes. To simplify the software (so that we - * don't need e.g. different tx DMA headers for 11a and 11b), the PLCP header has - * padding added in the ucode. - */ -#define D11_PHY_HDR_LEN 6 - -/* TX DMA buffer header */ -typedef struct d11txh d11txh_t; -struct d11txh { - u16 MacTxControlLow; /* 0x0 */ - u16 MacTxControlHigh; /* 0x1 */ - u16 MacFrameControl; /* 0x2 */ - u16 TxFesTimeNormal; /* 0x3 */ - u16 PhyTxControlWord; /* 0x4 */ - u16 PhyTxControlWord_1; /* 0x5 */ - u16 PhyTxControlWord_1_Fbr; /* 0x6 */ - u16 PhyTxControlWord_1_Rts; /* 0x7 */ - u16 PhyTxControlWord_1_FbrRts; /* 0x8 */ - u16 MainRates; /* 0x9 */ - u16 XtraFrameTypes; /* 0xa */ - u8 IV[16]; /* 0x0b - 0x12 */ - u8 TxFrameRA[6]; /* 0x13 - 0x15 */ - u16 TxFesTimeFallback; /* 0x16 */ - u8 RTSPLCPFallback[6]; /* 0x17 - 0x19 */ - u16 RTSDurFallback; /* 0x1a */ - u8 FragPLCPFallback[6]; /* 0x1b - 1d */ - u16 FragDurFallback; /* 0x1e */ - u16 MModeLen; /* 0x1f */ - u16 MModeFbrLen; /* 0x20 */ - u16 TstampLow; /* 0x21 */ - u16 TstampHigh; /* 0x22 */ - u16 ABI_MimoAntSel; /* 0x23 */ - u16 PreloadSize; /* 0x24 */ - u16 AmpduSeqCtl; /* 0x25 */ - u16 TxFrameID; /* 0x26 */ - u16 TxStatus; /* 0x27 */ - u16 MaxNMpdus; /* 0x28 corerev >=16 */ - u16 MaxABytes_MRT; /* 0x29 corerev >=16 */ - u16 MaxABytes_FBR; /* 0x2a corerev >=16 */ - u16 MinMBytes; /* 0x2b corerev >=16 */ - u8 RTSPhyHeader[D11_PHY_HDR_LEN]; /* 0x2c - 0x2e */ - struct ieee80211_rts rts_frame; /* 0x2f - 0x36 */ - u16 PAD; /* 0x37 */ -} __attribute__((packed)); - -#define D11_TXH_LEN 112 /* bytes */ - -/* Frame Types */ -#define FT_CCK 0 -#define FT_OFDM 1 -#define FT_HT 2 -#define FT_N 3 - -/* Position of MPDU inside A-MPDU; indicated with bits 10:9 of MacTxControlLow */ -#define TXC_AMPDU_SHIFT 9 /* shift for ampdu settings */ -#define TXC_AMPDU_NONE 0 /* Regular MPDU, not an A-MPDU */ -#define TXC_AMPDU_FIRST 1 /* first MPDU of an A-MPDU */ -#define TXC_AMPDU_MIDDLE 2 /* intermediate MPDU of an A-MPDU */ -#define TXC_AMPDU_LAST 3 /* last (or single) MPDU of an A-MPDU */ - -/* MacTxControlLow */ -#define TXC_AMIC 0x8000 -#define TXC_SENDCTS 0x0800 -#define TXC_AMPDU_MASK 0x0600 -#define TXC_BW_40 0x0100 -#define TXC_FREQBAND_5G 0x0080 -#define TXC_DFCS 0x0040 -#define TXC_IGNOREPMQ 0x0020 -#define TXC_HWSEQ 0x0010 -#define TXC_STARTMSDU 0x0008 -#define TXC_SENDRTS 0x0004 -#define TXC_LONGFRAME 0x0002 -#define TXC_IMMEDACK 0x0001 - -/* MacTxControlHigh */ -#define TXC_PREAMBLE_RTS_FB_SHORT 0x8000 /* RTS fallback preamble type 1 = SHORT 0 = LONG */ -#define TXC_PREAMBLE_RTS_MAIN_SHORT 0x4000 /* RTS main rate preamble type 1 = SHORT 0 = LONG */ -#define TXC_PREAMBLE_DATA_FB_SHORT 0x2000 /* Main fallback rate preamble type - * 1 = SHORT for OFDM/GF for MIMO - * 0 = LONG for CCK/MM for MIMO - */ -/* TXC_PREAMBLE_DATA_MAIN is in PhyTxControl bit 5 */ -#define TXC_AMPDU_FBR 0x1000 /* use fallback rate for this AMPDU */ -#define TXC_SECKEY_MASK 0x0FF0 -#define TXC_SECKEY_SHIFT 4 -#define TXC_ALT_TXPWR 0x0008 /* Use alternate txpwr defined at loc. M_ALT_TXPWR_IDX */ -#define TXC_SECTYPE_MASK 0x0007 -#define TXC_SECTYPE_SHIFT 0 - -/* Null delimiter for Fallback rate */ -#define AMPDU_FBR_NULL_DELIM 5 /* Location of Null delimiter count for AMPDU */ - -/* PhyTxControl for Mimophy */ -#define PHY_TXC_PWR_MASK 0xFC00 -#define PHY_TXC_PWR_SHIFT 10 -#define PHY_TXC_ANT_MASK 0x03C0 /* bit 6, 7, 8, 9 */ -#define PHY_TXC_ANT_SHIFT 6 -#define PHY_TXC_ANT_0_1 0x00C0 /* auto, last rx */ -#define PHY_TXC_LCNPHY_ANT_LAST 0x0000 -#define PHY_TXC_ANT_3 0x0200 /* virtual antenna 3 */ -#define PHY_TXC_ANT_2 0x0100 /* virtual antenna 2 */ -#define PHY_TXC_ANT_1 0x0080 /* virtual antenna 1 */ -#define PHY_TXC_ANT_0 0x0040 /* virtual antenna 0 */ -#define PHY_TXC_SHORT_HDR 0x0010 - -#define PHY_TXC_OLD_ANT_0 0x0000 -#define PHY_TXC_OLD_ANT_1 0x0100 -#define PHY_TXC_OLD_ANT_LAST 0x0300 - -/* PhyTxControl_1 for Mimophy */ -#define PHY_TXC1_BW_MASK 0x0007 -#define PHY_TXC1_BW_10MHZ 0 -#define PHY_TXC1_BW_10MHZ_UP 1 -#define PHY_TXC1_BW_20MHZ 2 -#define PHY_TXC1_BW_20MHZ_UP 3 -#define PHY_TXC1_BW_40MHZ 4 -#define PHY_TXC1_BW_40MHZ_DUP 5 -#define PHY_TXC1_MODE_SHIFT 3 -#define PHY_TXC1_MODE_MASK 0x0038 -#define PHY_TXC1_MODE_SISO 0 -#define PHY_TXC1_MODE_CDD 1 -#define PHY_TXC1_MODE_STBC 2 -#define PHY_TXC1_MODE_SDM 3 - -/* PhyTxControl for HTphy that are different from Mimophy */ -#define PHY_TXC_HTANT_MASK 0x3fC0 /* bit 6, 7, 8, 9, 10, 11, 12, 13 */ - -/* XtraFrameTypes */ -#define XFTS_RTS_FT_SHIFT 2 -#define XFTS_FBRRTS_FT_SHIFT 4 -#define XFTS_CHANNEL_SHIFT 8 - -/* Antenna diversity bit in ant_wr_settle */ -#define PHY_AWS_ANTDIV 0x2000 - -/* IFS ctl */ -#define IFS_USEEDCF (1 << 2) - -/* IFS ctl1 */ -#define IFS_CTL1_EDCRS (1 << 3) -#define IFS_CTL1_EDCRS_20L (1 << 4) -#define IFS_CTL1_EDCRS_40 (1 << 5) - -/* ABI_MimoAntSel */ -#define ABI_MAS_ADDR_BMP_IDX_MASK 0x0f00 -#define ABI_MAS_ADDR_BMP_IDX_SHIFT 8 -#define ABI_MAS_FBR_ANT_PTN_MASK 0x00f0 -#define ABI_MAS_FBR_ANT_PTN_SHIFT 4 -#define ABI_MAS_MRT_ANT_PTN_MASK 0x000f - -/* tx status packet */ -typedef struct tx_status tx_status_t; -struct tx_status { - u16 framelen; - u16 PAD; - u16 frameid; - u16 status; - u16 lasttxtime; - u16 sequence; - u16 phyerr; - u16 ackphyrxsh; -} __attribute__((packed)); - -#define TXSTATUS_LEN 16 - -/* status field bit definitions */ -#define TX_STATUS_FRM_RTX_MASK 0xF000 -#define TX_STATUS_FRM_RTX_SHIFT 12 -#define TX_STATUS_RTS_RTX_MASK 0x0F00 -#define TX_STATUS_RTS_RTX_SHIFT 8 -#define TX_STATUS_MASK 0x00FE -#define TX_STATUS_PMINDCTD (1 << 7) /* PM mode indicated to AP */ -#define TX_STATUS_INTERMEDIATE (1 << 6) /* intermediate or 1st ampdu pkg */ -#define TX_STATUS_AMPDU (1 << 5) /* AMPDU status */ -#define TX_STATUS_SUPR_MASK 0x1C /* suppress status bits (4:2) */ -#define TX_STATUS_SUPR_SHIFT 2 -#define TX_STATUS_ACK_RCV (1 << 1) /* ACK received */ -#define TX_STATUS_VALID (1 << 0) /* Tx status valid (corerev >= 5) */ -#define TX_STATUS_NO_ACK 0 - -/* suppress status reason codes */ -#define TX_STATUS_SUPR_PMQ (1 << 2) /* PMQ entry */ -#define TX_STATUS_SUPR_FLUSH (2 << 2) /* flush request */ -#define TX_STATUS_SUPR_FRAG (3 << 2) /* previous frag failure */ -#define TX_STATUS_SUPR_TBTT (3 << 2) /* SHARED: Probe response supr for TBTT */ -#define TX_STATUS_SUPR_BADCH (4 << 2) /* channel mismatch */ -#define TX_STATUS_SUPR_EXPTIME (5 << 2) /* lifetime expiry */ -#define TX_STATUS_SUPR_UF (6 << 2) /* underflow */ - -/* Unexpected tx status for rate update */ -#define TX_STATUS_UNEXP(status) \ - ((((status) & TX_STATUS_INTERMEDIATE) != 0) && \ - TX_STATUS_UNEXP_AMPDU(status)) - -/* Unexpected tx status for A-MPDU rate update */ -#define TX_STATUS_UNEXP_AMPDU(status) \ - ((((status) & TX_STATUS_SUPR_MASK) != 0) && \ - (((status) & TX_STATUS_SUPR_MASK) != TX_STATUS_SUPR_EXPTIME)) - -#define TX_STATUS_BA_BMAP03_MASK 0xF000 /* ba bitmap 0:3 in 1st pkg */ -#define TX_STATUS_BA_BMAP03_SHIFT 12 /* ba bitmap 0:3 in 1st pkg */ -#define TX_STATUS_BA_BMAP47_MASK 0x001E /* ba bitmap 4:7 in 2nd pkg */ -#define TX_STATUS_BA_BMAP47_SHIFT 3 /* ba bitmap 4:7 in 2nd pkg */ - -/* RXE (Receive Engine) */ - -/* RCM_CTL */ -#define RCM_INC_MASK_H 0x0080 -#define RCM_INC_MASK_L 0x0040 -#define RCM_INC_DATA 0x0020 -#define RCM_INDEX_MASK 0x001F -#define RCM_SIZE 15 - -#define RCM_MAC_OFFSET 0 /* current MAC address */ -#define RCM_BSSID_OFFSET 3 /* current BSSID address */ -#define RCM_F_BSSID_0_OFFSET 6 /* foreign BSS CFP tracking */ -#define RCM_F_BSSID_1_OFFSET 9 /* foreign BSS CFP tracking */ -#define RCM_F_BSSID_2_OFFSET 12 /* foreign BSS CFP tracking */ - -#define RCM_WEP_TA0_OFFSET 16 -#define RCM_WEP_TA1_OFFSET 19 -#define RCM_WEP_TA2_OFFSET 22 -#define RCM_WEP_TA3_OFFSET 25 - -/* PSM Block */ - -/* psm_phy_hdr_param bits */ -#define MAC_PHY_RESET 1 -#define MAC_PHY_CLOCK_EN 2 -#define MAC_PHY_FORCE_CLK 4 - -/* WEP Block */ - -/* WEP_WKEY */ -#define WKEY_START (1 << 8) -#define WKEY_SEL_MASK 0x1F - -/* WEP data formats */ - -/* the number of RCMTA entries */ -#define RCMTA_SIZE 50 - -#define M_ADDR_BMP_BLK (0x37e * 2) -#define M_ADDR_BMP_BLK_SZ 12 - -#define ADDR_BMP_RA (1 << 0) /* Receiver Address (RA) */ -#define ADDR_BMP_TA (1 << 1) /* Transmitter Address (TA) */ -#define ADDR_BMP_BSSID (1 << 2) /* BSSID */ -#define ADDR_BMP_AP (1 << 3) /* Infra-BSS Access Point (AP) */ -#define ADDR_BMP_STA (1 << 4) /* Infra-BSS Station (STA) */ -#define ADDR_BMP_RESERVED1 (1 << 5) -#define ADDR_BMP_RESERVED2 (1 << 6) -#define ADDR_BMP_RESERVED3 (1 << 7) -#define ADDR_BMP_BSS_IDX_MASK (3 << 8) /* BSS control block index */ -#define ADDR_BMP_BSS_IDX_SHIFT 8 - -#define WSEC_MAX_RCMTA_KEYS 54 - -/* max keys in M_TKMICKEYS_BLK */ -#define WSEC_MAX_TKMIC_ENGINE_KEYS 12 /* 8 + 4 default */ - -/* max RXE match registers */ -#define WSEC_MAX_RXE_KEYS 4 - -/* SECKINDXALGO (Security Key Index & Algorithm Block) word format */ -/* SKL (Security Key Lookup) */ -#define SKL_ALGO_MASK 0x0007 -#define SKL_ALGO_SHIFT 0 -#define SKL_KEYID_MASK 0x0008 -#define SKL_KEYID_SHIFT 3 -#define SKL_INDEX_MASK 0x03F0 -#define SKL_INDEX_SHIFT 4 -#define SKL_GRP_ALGO_MASK 0x1c00 -#define SKL_GRP_ALGO_SHIFT 10 - -/* additional bits defined for IBSS group key support */ -#define SKL_IBSS_INDEX_MASK 0x01F0 -#define SKL_IBSS_INDEX_SHIFT 4 -#define SKL_IBSS_KEYID1_MASK 0x0600 -#define SKL_IBSS_KEYID1_SHIFT 9 -#define SKL_IBSS_KEYID2_MASK 0x1800 -#define SKL_IBSS_KEYID2_SHIFT 11 -#define SKL_IBSS_KEYALGO_MASK 0xE000 -#define SKL_IBSS_KEYALGO_SHIFT 13 - -#define WSEC_MODE_OFF 0 -#define WSEC_MODE_HW 1 -#define WSEC_MODE_SW 2 - -#define WSEC_ALGO_OFF 0 -#define WSEC_ALGO_WEP1 1 -#define WSEC_ALGO_TKIP 2 -#define WSEC_ALGO_AES 3 -#define WSEC_ALGO_WEP128 4 -#define WSEC_ALGO_AES_LEGACY 5 -#define WSEC_ALGO_NALG 6 - -#define AES_MODE_NONE 0 -#define AES_MODE_CCM 1 - -/* WEP_CTL (Rev 0) */ -#define WECR0_KEYREG_SHIFT 0 -#define WECR0_KEYREG_MASK 0x7 -#define WECR0_DECRYPT (1 << 3) -#define WECR0_IVINLINE (1 << 4) -#define WECR0_WEPALG_SHIFT 5 -#define WECR0_WEPALG_MASK (0x7 << 5) -#define WECR0_WKEYSEL_SHIFT 8 -#define WECR0_WKEYSEL_MASK (0x7 << 8) -#define WECR0_WKEYSTART (1 << 11) -#define WECR0_WEPINIT (1 << 14) -#define WECR0_ICVERR (1 << 15) - -/* Frame template map byte offsets */ -#define T_ACTS_TPL_BASE (0) -#define T_NULL_TPL_BASE (0xc * 2) -#define T_QNULL_TPL_BASE (0x1c * 2) -#define T_RR_TPL_BASE (0x2c * 2) -#define T_BCN0_TPL_BASE (0x34 * 2) -#define T_PRS_TPL_BASE (0x134 * 2) -#define T_BCN1_TPL_BASE (0x234 * 2) -#define T_TX_FIFO_TXRAM_BASE (T_ACTS_TPL_BASE + (TXFIFO_START_BLK * TXFIFO_SIZE_UNIT)) - -#define T_BA_TPL_BASE T_QNULL_TPL_BASE /* template area for BA */ - -#define T_RAM_ACCESS_SZ 4 /* template ram is 4 byte access only */ - -/* Shared Mem byte offsets */ - -/* Location where the ucode expects the corerev */ -#define M_MACHW_VER (0x00b * 2) - -/* Location where the ucode expects the MAC capabilities */ -#define M_MACHW_CAP_L (0x060 * 2) -#define M_MACHW_CAP_H (0x061 * 2) - -/* WME shared memory */ -#define M_EDCF_STATUS_OFF (0x007 * 2) -#define M_TXF_CUR_INDEX (0x018 * 2) -#define M_EDCF_QINFO (0x120 * 2) - -/* PS-mode related parameters */ -#define M_DOT11_SLOT (0x008 * 2) -#define M_DOT11_DTIMPERIOD (0x009 * 2) -#define M_NOSLPZNATDTIM (0x026 * 2) - -/* Beacon-related parameters */ -#define M_BCN0_FRM_BYTESZ (0x00c * 2) /* Bcn 0 template length */ -#define M_BCN1_FRM_BYTESZ (0x00d * 2) /* Bcn 1 template length */ -#define M_BCN_TXTSF_OFFSET (0x00e * 2) -#define M_TIMBPOS_INBEACON (0x00f * 2) -#define M_SFRMTXCNTFBRTHSD (0x022 * 2) -#define M_LFRMTXCNTFBRTHSD (0x023 * 2) -#define M_BCN_PCTLWD (0x02a * 2) -#define M_BCN_LI (0x05b * 2) /* beacon listen interval */ - -/* MAX Rx Frame len */ -#define M_MAXRXFRM_LEN (0x010 * 2) - -/* ACK/CTS related params */ -#define M_RSP_PCTLWD (0x011 * 2) - -/* Hardware Power Control */ -#define M_TXPWR_N (0x012 * 2) -#define M_TXPWR_TARGET (0x013 * 2) -#define M_TXPWR_MAX (0x014 * 2) -#define M_TXPWR_CUR (0x019 * 2) - -/* Rx-related parameters */ -#define M_RX_PAD_DATA_OFFSET (0x01a * 2) - -/* WEP Shared mem data */ -#define M_SEC_DEFIVLOC (0x01e * 2) -#define M_SEC_VALNUMSOFTMCHTA (0x01f * 2) -#define M_PHYVER (0x028 * 2) -#define M_PHYTYPE (0x029 * 2) -#define M_SECRXKEYS_PTR (0x02b * 2) -#define M_TKMICKEYS_PTR (0x059 * 2) -#define M_SECKINDXALGO_BLK (0x2ea * 2) -#define M_SECKINDXALGO_BLK_SZ 54 -#define M_SECPSMRXTAMCH_BLK (0x2fa * 2) -#define M_TKIP_TSC_TTAK (0x18c * 2) -#define D11_MAX_KEY_SIZE 16 - -#define M_MAX_ANTCNT (0x02e * 2) /* antenna swap threshold */ - -/* Probe response related parameters */ -#define M_SSIDLEN (0x024 * 2) -#define M_PRB_RESP_FRM_LEN (0x025 * 2) -#define M_PRS_MAXTIME (0x03a * 2) -#define M_SSID (0xb0 * 2) -#define M_CTXPRS_BLK (0xc0 * 2) -#define C_CTX_PCTLWD_POS (0x4 * 2) - -/* Delta between OFDM and CCK power in CCK power boost mode */ -#define M_OFDM_OFFSET (0x027 * 2) - -/* TSSI for last 4 11b/g CCK packets transmitted */ -#define M_B_TSSI_0 (0x02c * 2) -#define M_B_TSSI_1 (0x02d * 2) - -/* Host flags to turn on ucode options */ -#define M_HOST_FLAGS1 (0x02f * 2) -#define M_HOST_FLAGS2 (0x030 * 2) -#define M_HOST_FLAGS3 (0x031 * 2) -#define M_HOST_FLAGS4 (0x03c * 2) -#define M_HOST_FLAGS5 (0x06a * 2) -#define M_HOST_FLAGS_SZ 16 - -#define M_RADAR_REG (0x033 * 2) - -/* TSSI for last 4 11a OFDM packets transmitted */ -#define M_A_TSSI_0 (0x034 * 2) -#define M_A_TSSI_1 (0x035 * 2) - -/* noise interference measurement */ -#define M_NOISE_IF_COUNT (0x034 * 2) -#define M_NOISE_IF_TIMEOUT (0x035 * 2) - -#define M_RF_RX_SP_REG1 (0x036 * 2) - -/* TSSI for last 4 11g OFDM packets transmitted */ -#define M_G_TSSI_0 (0x038 * 2) -#define M_G_TSSI_1 (0x039 * 2) - -/* Background noise measure */ -#define M_JSSI_0 (0x44 * 2) -#define M_JSSI_1 (0x45 * 2) -#define M_JSSI_AUX (0x46 * 2) - -#define M_CUR_2050_RADIOCODE (0x47 * 2) - -/* TX fifo sizes */ -#define M_FIFOSIZE0 (0x4c * 2) -#define M_FIFOSIZE1 (0x4d * 2) -#define M_FIFOSIZE2 (0x4e * 2) -#define M_FIFOSIZE3 (0x4f * 2) -#define D11_MAX_TX_FRMS 32 /* max frames allowed in tx fifo */ - -/* Current channel number plus upper bits */ -#define M_CURCHANNEL (0x50 * 2) -#define D11_CURCHANNEL_5G 0x0100; -#define D11_CURCHANNEL_40 0x0200; -#define D11_CURCHANNEL_MAX 0x00FF; - -/* last posted frameid on the bcmc fifo */ -#define M_BCMC_FID (0x54 * 2) -#define INVALIDFID 0xffff - -/* extended beacon phyctl bytes for 11N */ -#define M_BCN_PCTL1WD (0x058 * 2) - -/* idle busy ratio to duty_cycle requirement */ -#define M_TX_IDLE_BUSY_RATIO_X_16_CCK (0x52 * 2) -#define M_TX_IDLE_BUSY_RATIO_X_16_OFDM (0x5A * 2) - -/* CW RSSI for LCNPHY */ -#define M_LCN_RSSI_0 0x1332 -#define M_LCN_RSSI_1 0x1338 -#define M_LCN_RSSI_2 0x133e -#define M_LCN_RSSI_3 0x1344 - -/* SNR for LCNPHY */ -#define M_LCN_SNR_A_0 0x1334 -#define M_LCN_SNR_B_0 0x1336 - -#define M_LCN_SNR_A_1 0x133a -#define M_LCN_SNR_B_1 0x133c - -#define M_LCN_SNR_A_2 0x1340 -#define M_LCN_SNR_B_2 0x1342 - -#define M_LCN_SNR_A_3 0x1346 -#define M_LCN_SNR_B_3 0x1348 - -#define M_LCN_LAST_RESET (81*2) -#define M_LCN_LAST_LOC (63*2) -#define M_LCNPHY_RESET_STATUS (4902) -#define M_LCNPHY_DSC_TIME (0x98d*2) -#define M_LCNPHY_RESET_CNT_DSC (0x98b*2) -#define M_LCNPHY_RESET_CNT (0x98c*2) - -/* Rate table offsets */ -#define M_RT_DIRMAP_A (0xe0 * 2) -#define M_RT_BBRSMAP_A (0xf0 * 2) -#define M_RT_DIRMAP_B (0x100 * 2) -#define M_RT_BBRSMAP_B (0x110 * 2) - -/* Rate table entry offsets */ -#define M_RT_PRS_PLCP_POS 10 -#define M_RT_PRS_DUR_POS 16 -#define M_RT_OFDM_PCTL1_POS 18 - -#define M_20IN40_IQ (0x380 * 2) - -/* SHM locations where ucode stores the current power index */ -#define M_CURR_IDX1 (0x384 * 2) -#define M_CURR_IDX2 (0x387 * 2) - -#define M_BSCALE_ANT0 (0x5e * 2) -#define M_BSCALE_ANT1 (0x5f * 2) - -/* Antenna Diversity Testing */ -#define M_MIMO_ANTSEL_RXDFLT (0x63 * 2) -#define M_ANTSEL_CLKDIV (0x61 * 2) -#define M_MIMO_ANTSEL_TXDFLT (0x64 * 2) - -#define M_MIMO_MAXSYM (0x5d * 2) -#define MIMO_MAXSYM_DEF 0x8000 /* 32k */ -#define MIMO_MAXSYM_MAX 0xffff /* 64k */ - -#define M_WATCHDOG_8TU (0x1e * 2) -#define WATCHDOG_8TU_DEF 5 -#define WATCHDOG_8TU_MAX 10 - -/* Manufacturing Test Variables */ -#define M_PKTENG_CTRL (0x6c * 2) /* PER test mode */ -#define M_PKTENG_IFS (0x6d * 2) /* IFS for TX mode */ -#define M_PKTENG_FRMCNT_LO (0x6e * 2) /* Lower word of tx frmcnt/rx lostcnt */ -#define M_PKTENG_FRMCNT_HI (0x6f * 2) /* Upper word of tx frmcnt/rx lostcnt */ - -/* Index variation in vbat ripple */ -#define M_LCN_PWR_IDX_MAX (0x67 * 2) /* highest index read by ucode */ -#define M_LCN_PWR_IDX_MIN (0x66 * 2) /* lowest index read by ucode */ - -/* M_PKTENG_CTRL bit definitions */ -#define M_PKTENG_MODE_TX 0x0001 -#define M_PKTENG_MODE_TX_RIFS 0x0004 -#define M_PKTENG_MODE_TX_CTS 0x0008 -#define M_PKTENG_MODE_RX 0x0002 -#define M_PKTENG_MODE_RX_WITH_ACK 0x0402 -#define M_PKTENG_MODE_MASK 0x0003 -#define M_PKTENG_FRMCNT_VLD 0x0100 /* TX frames indicated in the frmcnt reg */ - -/* Sample Collect parameters (bitmap and type) */ -#define M_SMPL_COL_BMP (0x37d * 2) /* Trigger bitmap for sample collect */ -#define M_SMPL_COL_CTL (0x3b2 * 2) /* Sample collect type */ - -#define ANTSEL_CLKDIV_4MHZ 6 -#define MIMO_ANTSEL_BUSY 0x4000 /* bit 14 (busy) */ -#define MIMO_ANTSEL_SEL 0x8000 /* bit 15 write the value */ -#define MIMO_ANTSEL_WAIT 50 /* 50us wait */ -#define MIMO_ANTSEL_OVERRIDE 0x8000 /* flag */ - -typedef struct shm_acparams shm_acparams_t; -struct shm_acparams { - u16 txop; - u16 cwmin; - u16 cwmax; - u16 cwcur; - u16 aifs; - u16 bslots; - u16 reggap; - u16 status; - u16 rsvd[8]; -} __attribute__((packed)); -#define M_EDCF_QLEN (16 * 2) - -#define WME_STATUS_NEWAC (1 << 8) - -/* M_HOST_FLAGS */ -#define MHFMAX 5 /* Number of valid hostflag half-word (u16) */ -#define MHF1 0 /* Hostflag 1 index */ -#define MHF2 1 /* Hostflag 2 index */ -#define MHF3 2 /* Hostflag 3 index */ -#define MHF4 3 /* Hostflag 4 index */ -#define MHF5 4 /* Hostflag 5 index */ - -/* Flags in M_HOST_FLAGS */ -#define MHF1_ANTDIV 0x0001 /* Enable ucode antenna diversity help */ -#define MHF1_EDCF 0x0100 /* Enable EDCF access control */ -#define MHF1_IQSWAP_WAR 0x0200 -#define MHF1_FORCEFASTCLK 0x0400 /* Disable Slow clock request, for corerev < 11 */ - -/* Flags in M_HOST_FLAGS2 */ -#define MHF2_PCISLOWCLKWAR 0x0008 /* PR16165WAR : Enable ucode PCI slow clock WAR */ -#define MHF2_TXBCMC_NOW 0x0040 /* Flush BCMC FIFO immediately */ -#define MHF2_HWPWRCTL 0x0080 /* Enable ucode/hw power control */ -#define MHF2_NPHY40MHZ_WAR 0x0800 - -/* Flags in M_HOST_FLAGS3 */ -#define MHF3_ANTSEL_EN 0x0001 /* enabled mimo antenna selection */ -#define MHF3_ANTSEL_MODE 0x0002 /* antenna selection mode: 0: 2x3, 1: 2x4 */ -#define MHF3_RESERVED1 0x0004 -#define MHF3_RESERVED2 0x0008 -#define MHF3_NPHY_MLADV_WAR 0x0010 - -/* Flags in M_HOST_FLAGS4 */ -#define MHF4_BPHY_TXCORE0 0x0080 /* force bphy Tx on core 0 (board level WAR) */ -#define MHF4_EXTPA_ENABLE 0x4000 /* for 4313A0 FEM boards */ - -/* Flags in M_HOST_FLAGS5 */ -#define MHF5_4313_GPIOCTRL 0x0001 -#define MHF5_RESERVED1 0x0002 -#define MHF5_RESERVED2 0x0004 -/* Radio power setting for ucode */ -#define M_RADIO_PWR (0x32 * 2) - -/* phy noise recorded by ucode right after tx */ -#define M_PHY_NOISE (0x037 * 2) -#define PHY_NOISE_MASK 0x00ff - -/* Receive Frame Data Header for 802.11b DCF-only frames */ -typedef struct d11rxhdr d11rxhdr_t; -struct d11rxhdr { - u16 RxFrameSize; /* Actual byte length of the frame data received */ - u16 PAD; - u16 PhyRxStatus_0; /* PhyRxStatus 15:0 */ - u16 PhyRxStatus_1; /* PhyRxStatus 31:16 */ - u16 PhyRxStatus_2; /* PhyRxStatus 47:32 */ - u16 PhyRxStatus_3; /* PhyRxStatus 63:48 */ - u16 PhyRxStatus_4; /* PhyRxStatus 79:64 */ - u16 PhyRxStatus_5; /* PhyRxStatus 95:80 */ - u16 RxStatus1; /* MAC Rx Status */ - u16 RxStatus2; /* extended MAC Rx status */ - u16 RxTSFTime; /* RxTSFTime time of first MAC symbol + M_PHY_PLCPRX_DLY */ - u16 RxChan; /* gain code, channel radio code, and phy type */ -} __attribute__((packed)); - -#define RXHDR_LEN 24 /* sizeof d11rxhdr_t */ -#define FRAMELEN(h) ((h)->RxFrameSize) - -typedef struct wlc_d11rxhdr wlc_d11rxhdr_t; -struct wlc_d11rxhdr { - d11rxhdr_t rxhdr; - u32 tsf_l; /* TSF_L reading */ - s8 rssi; /* computed instanteneous rssi in BMAC */ - s8 rxpwr0; /* obsoleted, place holder for legacy ROM code. use rxpwr[] */ - s8 rxpwr1; /* obsoleted, place holder for legacy ROM code. use rxpwr[] */ - s8 do_rssi_ma; /* do per-pkt sampling for per-antenna ma in HIGH */ - s8 rxpwr[WL_RSSI_ANT_MAX]; /* rssi for supported antennas */ -} __attribute__((packed)); - -/* PhyRxStatus_0: */ -#define PRXS0_FT_MASK 0x0003 /* NPHY only: CCK, OFDM, preN, N */ -#define PRXS0_CLIP_MASK 0x000C /* NPHY only: clip count adjustment steps by AGC */ -#define PRXS0_CLIP_SHIFT 2 -#define PRXS0_UNSRATE 0x0010 /* PHY received a frame with unsupported rate */ -#define PRXS0_RXANT_UPSUBBAND 0x0020 /* GPHY: rx ant, NPHY: upper sideband */ -#define PRXS0_LCRS 0x0040 /* CCK frame only: lost crs during cck frame reception */ -#define PRXS0_SHORTH 0x0080 /* Short Preamble */ -#define PRXS0_PLCPFV 0x0100 /* PLCP violation */ -#define PRXS0_PLCPHCF 0x0200 /* PLCP header integrity check failed */ -#define PRXS0_GAIN_CTL 0x4000 /* legacy PHY gain control */ -#define PRXS0_ANTSEL_MASK 0xF000 /* NPHY: Antennas used for received frame, bitmask */ -#define PRXS0_ANTSEL_SHIFT 0x12 - -/* subfield PRXS0_FT_MASK */ -#define PRXS0_CCK 0x0000 -#define PRXS0_OFDM 0x0001 /* valid only for G phy, use rxh->RxChan for A phy */ -#define PRXS0_PREN 0x0002 -#define PRXS0_STDN 0x0003 - -/* subfield PRXS0_ANTSEL_MASK */ -#define PRXS0_ANTSEL_0 0x0 /* antenna 0 is used */ -#define PRXS0_ANTSEL_1 0x2 /* antenna 1 is used */ -#define PRXS0_ANTSEL_2 0x4 /* antenna 2 is used */ -#define PRXS0_ANTSEL_3 0x8 /* antenna 3 is used */ - -/* PhyRxStatus_1: */ -#define PRXS1_JSSI_MASK 0x00FF -#define PRXS1_JSSI_SHIFT 0 -#define PRXS1_SQ_MASK 0xFF00 -#define PRXS1_SQ_SHIFT 8 - -/* nphy PhyRxStatus_1: */ -#define PRXS1_nphy_PWR0_MASK 0x00FF -#define PRXS1_nphy_PWR1_MASK 0xFF00 - -/* HTPHY Rx Status defines */ -/* htphy PhyRxStatus_0: those bit are overlapped with PhyRxStatus_0 */ -#define PRXS0_BAND 0x0400 /* 0 = 2.4G, 1 = 5G */ -#define PRXS0_RSVD 0x0800 /* reserved; set to 0 */ -#define PRXS0_UNUSED 0xF000 /* unused and not defined; set to 0 */ - -/* htphy PhyRxStatus_1: */ -#define PRXS1_HTPHY_CORE_MASK 0x000F /* core enables for {3..0}, 0=disabled, 1=enabled */ -#define PRXS1_HTPHY_ANTCFG_MASK 0x00F0 /* antenna configation */ -#define PRXS1_HTPHY_MMPLCPLenL_MASK 0xFF00 /* Mixmode PLCP Length low byte mask */ - -/* htphy PhyRxStatus_2: */ -#define PRXS2_HTPHY_MMPLCPLenH_MASK 0x000F /* Mixmode PLCP Length high byte maskw */ -#define PRXS2_HTPHY_MMPLCH_RATE_MASK 0x00F0 /* Mixmode PLCP rate mask */ -#define PRXS2_HTPHY_RXPWR_ANT0 0xFF00 /* Rx power on core 0 */ - -/* htphy PhyRxStatus_3: */ -#define PRXS3_HTPHY_RXPWR_ANT1 0x00FF /* Rx power on core 1 */ -#define PRXS3_HTPHY_RXPWR_ANT2 0xFF00 /* Rx power on core 2 */ - -/* htphy PhyRxStatus_4: */ -#define PRXS4_HTPHY_RXPWR_ANT3 0x00FF /* Rx power on core 3 */ -#define PRXS4_HTPHY_CFO 0xFF00 /* Coarse frequency offset */ - -/* htphy PhyRxStatus_5: */ -#define PRXS5_HTPHY_FFO 0x00FF /* Fine frequency offset */ -#define PRXS5_HTPHY_AR 0xFF00 /* Advance Retard */ - -#define HTPHY_MMPLCPLen(rxs) ((((rxs)->PhyRxStatus_1 & PRXS1_HTPHY_MMPLCPLenL_MASK) >> 8) | \ - (((rxs)->PhyRxStatus_2 & PRXS2_HTPHY_MMPLCPLenH_MASK) << 8)) -/* Get Rx power on core 0 */ -#define HTPHY_RXPWR_ANT0(rxs) ((((rxs)->PhyRxStatus_2) & PRXS2_HTPHY_RXPWR_ANT0) >> 8) -/* Get Rx power on core 1 */ -#define HTPHY_RXPWR_ANT1(rxs) (((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT1) -/* Get Rx power on core 2 */ -#define HTPHY_RXPWR_ANT2(rxs) ((((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT2) >> 8) - -/* ucode RxStatus1: */ -#define RXS_BCNSENT 0x8000 -#define RXS_SECKINDX_MASK 0x07e0 -#define RXS_SECKINDX_SHIFT 5 -#define RXS_DECERR (1 << 4) -#define RXS_DECATMPT (1 << 3) -#define RXS_PBPRES (1 << 2) /* PAD bytes to make IP data 4 bytes aligned */ -#define RXS_RESPFRAMETX (1 << 1) -#define RXS_FCSERR (1 << 0) - -/* ucode RxStatus2: */ -#define RXS_AMSDU_MASK 1 -#define RXS_AGGTYPE_MASK 0x6 -#define RXS_AGGTYPE_SHIFT 1 -#define RXS_PHYRXST_VALID (1 << 8) -#define RXS_RXANT_MASK 0x3 -#define RXS_RXANT_SHIFT 12 - -/* RxChan */ -#define RXS_CHAN_40 0x1000 -#define RXS_CHAN_5G 0x0800 -#define RXS_CHAN_ID_MASK 0x07f8 -#define RXS_CHAN_ID_SHIFT 3 -#define RXS_CHAN_PHYTYPE_MASK 0x0007 -#define RXS_CHAN_PHYTYPE_SHIFT 0 - -/* Index of attenuations used during ucode power control. */ -#define M_PWRIND_BLKS (0x184 * 2) -#define M_PWRIND_MAP0 (M_PWRIND_BLKS + 0x0) -#define M_PWRIND_MAP1 (M_PWRIND_BLKS + 0x2) -#define M_PWRIND_MAP2 (M_PWRIND_BLKS + 0x4) -#define M_PWRIND_MAP3 (M_PWRIND_BLKS + 0x6) -/* M_PWRIND_MAP(core) macro */ -#define M_PWRIND_MAP(core) (M_PWRIND_BLKS + ((core)<<1)) - -/* PSM SHM variable offsets */ -#define M_PSM_SOFT_REGS 0x0 -#define M_BOM_REV_MAJOR (M_PSM_SOFT_REGS + 0x0) -#define M_BOM_REV_MINOR (M_PSM_SOFT_REGS + 0x2) -#define M_UCODE_DBGST (M_PSM_SOFT_REGS + 0x40) /* ucode debug status code */ -#define M_UCODE_MACSTAT (M_PSM_SOFT_REGS + 0xE0) /* macstat counters */ - -#define M_AGING_THRSH (0x3e * 2) /* max time waiting for medium before tx */ -#define M_MBURST_SIZE (0x40 * 2) /* max frames in a frameburst */ -#define M_MBURST_TXOP (0x41 * 2) /* max frameburst TXOP in unit of us */ -#define M_SYNTHPU_DLY (0x4a * 2) /* pre-wakeup for synthpu, default: 500 */ -#define M_PRETBTT (0x4b * 2) - -#define M_ALT_TXPWR_IDX (M_PSM_SOFT_REGS + (0x3b * 2)) /* offset to the target txpwr */ -#define M_PHY_TX_FLT_PTR (M_PSM_SOFT_REGS + (0x3d * 2)) -#define M_CTS_DURATION (M_PSM_SOFT_REGS + (0x5c * 2)) -#define M_LP_RCCAL_OVR (M_PSM_SOFT_REGS + (0x6b * 2)) - -/* PKTENG Rx Stats Block */ -#define M_RXSTATS_BLK_PTR (M_PSM_SOFT_REGS + (0x65 * 2)) - -/* ucode debug status codes */ -#define DBGST_INACTIVE 0 /* not valid really */ -#define DBGST_INIT 1 /* after zeroing SHM, before suspending at init */ -#define DBGST_ACTIVE 2 /* "normal" state */ -#define DBGST_SUSPENDED 3 /* suspended */ -#define DBGST_ASLEEP 4 /* asleep (PS mode) */ - -/* Scratch Reg defs */ -typedef enum { - S_RSV0 = 0, - S_RSV1, - S_RSV2, - - /* scratch registers for Dot11-contants */ - S_DOT11_CWMIN, /* CW-minimum 0x03 */ - S_DOT11_CWMAX, /* CW-maximum 0x04 */ - S_DOT11_CWCUR, /* CW-current 0x05 */ - S_DOT11_SRC_LMT, /* short retry count limit 0x06 */ - S_DOT11_LRC_LMT, /* long retry count limit 0x07 */ - S_DOT11_DTIMCOUNT, /* DTIM-count 0x08 */ - - /* Tx-side scratch registers */ - S_SEQ_NUM, /* hardware sequence number reg 0x09 */ - S_SEQ_NUM_FRAG, /* seq-num for frags (Set at the start os MSDU 0x0A */ - S_FRMRETX_CNT, /* frame retx count 0x0B */ - S_SSRC, /* Station short retry count 0x0C */ - S_SLRC, /* Station long retry count 0x0D */ - S_EXP_RSP, /* Expected response frame 0x0E */ - S_OLD_BREM, /* Remaining backoff ctr 0x0F */ - S_OLD_CWWIN, /* saved-off CW-cur 0x10 */ - S_TXECTL, /* TXE-Ctl word constructed in scr-pad 0x11 */ - S_CTXTST, /* frm type-subtype as read from Tx-descr 0x12 */ - - /* Rx-side scratch registers */ - S_RXTST, /* Type and subtype in Rxframe 0x13 */ - - /* Global state register */ - S_STREG, /* state storage actual bit maps below 0x14 */ - - S_TXPWR_SUM, /* Tx power control: accumulator 0x15 */ - S_TXPWR_ITER, /* Tx power control: iteration 0x16 */ - S_RX_FRMTYPE, /* Rate and PHY type for frames 0x17 */ - S_THIS_AGG, /* Size of this AGG (A-MSDU) 0x18 */ - - S_KEYINDX, /* 0x19 */ - S_RXFRMLEN, /* Receive MPDU length in bytes 0x1A */ - - /* Receive TSF time stored in SCR */ - S_RXTSFTMRVAL_WD3, /* TSF value at the start of rx 0x1B */ - S_RXTSFTMRVAL_WD2, /* TSF value at the start of rx 0x1C */ - S_RXTSFTMRVAL_WD1, /* TSF value at the start of rx 0x1D */ - S_RXTSFTMRVAL_WD0, /* TSF value at the start of rx 0x1E */ - S_RXSSN, /* Received start seq number for A-MPDU BA 0x1F */ - S_RXQOSFLD, /* Rx-QoS field (if present) 0x20 */ - - /* Scratch pad regs used in microcode as temp storage */ - S_TMP0, /* stmp0 0x21 */ - S_TMP1, /* stmp1 0x22 */ - S_TMP2, /* stmp2 0x23 */ - S_TMP3, /* stmp3 0x24 */ - S_TMP4, /* stmp4 0x25 */ - S_TMP5, /* stmp5 0x26 */ - S_PRQPENALTY_CTR, /* Probe response queue penalty counter 0x27 */ - S_ANTCNT, /* unsuccessful attempts on current ant. 0x28 */ - S_SYMBOL, /* flag for possible symbol ctl frames 0x29 */ - S_RXTP, /* rx frame type 0x2A */ - S_STREG2, /* extra state storage 0x2B */ - S_STREG3, /* even more extra state storage 0x2C */ - S_STREG4, /* ... 0x2D */ - S_STREG5, /* remember to initialize it to zero 0x2E */ - - S_ADJPWR_IDX, - S_CUR_PTR, /* Temp pointer for A-MPDU re-Tx SHM table 0x32 */ - S_REVID4, /* 0x33 */ - S_INDX, /* 0x34 */ - S_ADDR0, /* 0x35 */ - S_ADDR1, /* 0x36 */ - S_ADDR2, /* 0x37 */ - S_ADDR3, /* 0x38 */ - S_ADDR4, /* 0x39 */ - S_ADDR5, /* 0x3A */ - S_TMP6, /* 0x3B */ - S_KEYINDX_BU, /* Backup for Key index 0x3C */ - S_MFGTEST_TMP0, /* Temp register used for RX test calculations 0x3D */ - S_RXESN, /* Received end sequence number for A-MPDU BA 0x3E */ - S_STREG6, /* 0x3F */ -} ePsmScratchPadRegDefinitions; - -#define S_BEACON_INDX S_OLD_BREM -#define S_PRS_INDX S_OLD_CWWIN -#define S_PHYTYPE S_SSRC -#define S_PHYVER S_SLRC - -/* IHR SLOW_CTRL values */ -#define SLOW_CTRL_PDE (1 << 0) -#define SLOW_CTRL_FD (1 << 8) - -/* ucode mac statistic counters in shared memory */ -typedef struct macstat { - u16 txallfrm; /* 0x80 */ - u16 txrtsfrm; /* 0x82 */ - u16 txctsfrm; /* 0x84 */ - u16 txackfrm; /* 0x86 */ - u16 txdnlfrm; /* 0x88 */ - u16 txbcnfrm; /* 0x8a */ - u16 txfunfl[8]; /* 0x8c - 0x9b */ - u16 txtplunfl; /* 0x9c */ - u16 txphyerr; /* 0x9e */ - u16 pktengrxducast; /* 0xa0 */ - u16 pktengrxdmcast; /* 0xa2 */ - u16 rxfrmtoolong; /* 0xa4 */ - u16 rxfrmtooshrt; /* 0xa6 */ - u16 rxinvmachdr; /* 0xa8 */ - u16 rxbadfcs; /* 0xaa */ - u16 rxbadplcp; /* 0xac */ - u16 rxcrsglitch; /* 0xae */ - u16 rxstrt; /* 0xb0 */ - u16 rxdfrmucastmbss; /* 0xb2 */ - u16 rxmfrmucastmbss; /* 0xb4 */ - u16 rxcfrmucast; /* 0xb6 */ - u16 rxrtsucast; /* 0xb8 */ - u16 rxctsucast; /* 0xba */ - u16 rxackucast; /* 0xbc */ - u16 rxdfrmocast; /* 0xbe */ - u16 rxmfrmocast; /* 0xc0 */ - u16 rxcfrmocast; /* 0xc2 */ - u16 rxrtsocast; /* 0xc4 */ - u16 rxctsocast; /* 0xc6 */ - u16 rxdfrmmcast; /* 0xc8 */ - u16 rxmfrmmcast; /* 0xca */ - u16 rxcfrmmcast; /* 0xcc */ - u16 rxbeaconmbss; /* 0xce */ - u16 rxdfrmucastobss; /* 0xd0 */ - u16 rxbeaconobss; /* 0xd2 */ - u16 rxrsptmout; /* 0xd4 */ - u16 bcntxcancl; /* 0xd6 */ - u16 PAD; - u16 rxf0ovfl; /* 0xda */ - u16 rxf1ovfl; /* 0xdc */ - u16 rxf2ovfl; /* 0xde */ - u16 txsfovfl; /* 0xe0 */ - u16 pmqovfl; /* 0xe2 */ - u16 rxcgprqfrm; /* 0xe4 */ - u16 rxcgprsqovfl; /* 0xe6 */ - u16 txcgprsfail; /* 0xe8 */ - u16 txcgprssuc; /* 0xea */ - u16 prs_timeout; /* 0xec */ - u16 rxnack; - u16 frmscons; - u16 txnack; - u16 txglitch_nack; - u16 txburst; /* 0xf6 # tx bursts */ - u16 bphy_rxcrsglitch; /* bphy rx crs glitch */ - u16 phywatchdog; /* 0xfa # of phy watchdog events */ - u16 PAD; - u16 bphy_badplcp; /* bphy bad plcp */ -} macstat_t; - -/* dot11 core-specific control flags */ -#define SICF_PCLKE 0x0004 /* PHY clock enable */ -#define SICF_PRST 0x0008 /* PHY reset */ -#define SICF_MPCLKE 0x0010 /* MAC PHY clockcontrol enable */ -#define SICF_FREF 0x0020 /* PLL FreqRefSelect (corerev >= 5) */ -/* NOTE: the following bw bits only apply when the core is attached - * to a NPHY (and corerev >= 11 which it will always be for NPHYs). - */ -#define SICF_BWMASK 0x00c0 /* phy clock mask (b6 & b7) */ -#define SICF_BW40 0x0080 /* 40MHz BW (160MHz phyclk) */ -#define SICF_BW20 0x0040 /* 20MHz BW (80MHz phyclk) */ -#define SICF_BW10 0x0000 /* 10MHz BW (40MHz phyclk) */ -#define SICF_GMODE 0x2000 /* gmode enable */ - -/* dot11 core-specific status flags */ -#define SISF_2G_PHY 0x0001 /* 2.4G capable phy (corerev >= 5) */ -#define SISF_5G_PHY 0x0002 /* 5G capable phy (corerev >= 5) */ -#define SISF_FCLKA 0x0004 /* FastClkAvailable (corerev >= 5) */ -#define SISF_DB_PHY 0x0008 /* Dualband phy (corerev >= 11) */ - -/* === End of MAC reg, Beginning of PHY(b/a/g/n) reg, radio and LPPHY regs are separated === */ - -#define BPHY_REG_OFT_BASE 0x0 -/* offsets for indirect access to bphy registers */ -#define BPHY_BB_CONFIG 0x01 -#define BPHY_ADCBIAS 0x02 -#define BPHY_ANACORE 0x03 -#define BPHY_PHYCRSTH 0x06 -#define BPHY_TEST 0x0a -#define BPHY_PA_TX_TO 0x10 -#define BPHY_SYNTH_DC_TO 0x11 -#define BPHY_PA_TX_TIME_UP 0x12 -#define BPHY_RX_FLTR_TIME_UP 0x13 -#define BPHY_TX_POWER_OVERRIDE 0x14 -#define BPHY_RF_OVERRIDE 0x15 -#define BPHY_RF_TR_LOOKUP1 0x16 -#define BPHY_RF_TR_LOOKUP2 0x17 -#define BPHY_COEFFS 0x18 -#define BPHY_PLL_OUT 0x19 -#define BPHY_REFRESH_MAIN 0x1a -#define BPHY_REFRESH_TO0 0x1b -#define BPHY_REFRESH_TO1 0x1c -#define BPHY_RSSI_TRESH 0x20 -#define BPHY_IQ_TRESH_HH 0x21 -#define BPHY_IQ_TRESH_H 0x22 -#define BPHY_IQ_TRESH_L 0x23 -#define BPHY_IQ_TRESH_LL 0x24 -#define BPHY_GAIN 0x25 -#define BPHY_LNA_GAIN_RANGE 0x26 -#define BPHY_JSSI 0x27 -#define BPHY_TSSI_CTL 0x28 -#define BPHY_TSSI 0x29 -#define BPHY_TR_LOSS_CTL 0x2a -#define BPHY_LO_LEAKAGE 0x2b -#define BPHY_LO_RSSI_ACC 0x2c -#define BPHY_LO_IQMAG_ACC 0x2d -#define BPHY_TX_DC_OFF1 0x2e -#define BPHY_TX_DC_OFF2 0x2f -#define BPHY_PEAK_CNT_THRESH 0x30 -#define BPHY_FREQ_OFFSET 0x31 -#define BPHY_DIVERSITY_CTL 0x32 -#define BPHY_PEAK_ENERGY_LO 0x33 -#define BPHY_PEAK_ENERGY_HI 0x34 -#define BPHY_SYNC_CTL 0x35 -#define BPHY_TX_PWR_CTRL 0x36 -#define BPHY_TX_EST_PWR 0x37 -#define BPHY_STEP 0x38 -#define BPHY_WARMUP 0x39 -#define BPHY_LMS_CFF_READ 0x3a -#define BPHY_LMS_COEFF_I 0x3b -#define BPHY_LMS_COEFF_Q 0x3c -#define BPHY_SIG_POW 0x3d -#define BPHY_RFDC_CANCEL_CTL 0x3e -#define BPHY_HDR_TYPE 0x40 -#define BPHY_SFD_TO 0x41 -#define BPHY_SFD_CTL 0x42 -#define BPHY_DEBUG 0x43 -#define BPHY_RX_DELAY_COMP 0x44 -#define BPHY_CRS_DROP_TO 0x45 -#define BPHY_SHORT_SFD_NZEROS 0x46 -#define BPHY_DSSS_COEFF1 0x48 -#define BPHY_DSSS_COEFF2 0x49 -#define BPHY_CCK_COEFF1 0x4a -#define BPHY_CCK_COEFF2 0x4b -#define BPHY_TR_CORR 0x4c -#define BPHY_ANGLE_SCALE 0x4d -#define BPHY_TX_PWR_BASE_IDX 0x4e -#define BPHY_OPTIONAL_MODES2 0x4f -#define BPHY_CCK_LMS_STEP 0x50 -#define BPHY_BYPASS 0x51 -#define BPHY_CCK_DELAY_LONG 0x52 -#define BPHY_CCK_DELAY_SHORT 0x53 -#define BPHY_PPROC_CHAN_DELAY 0x54 -#define BPHY_DDFS_ENABLE 0x58 -#define BPHY_PHASE_SCALE 0x59 -#define BPHY_FREQ_CONTROL 0x5a -#define BPHY_LNA_GAIN_RANGE_10 0x5b -#define BPHY_LNA_GAIN_RANGE_32 0x5c -#define BPHY_OPTIONAL_MODES 0x5d -#define BPHY_RX_STATUS2 0x5e -#define BPHY_RX_STATUS3 0x5f -#define BPHY_DAC_CONTROL 0x60 -#define BPHY_ANA11G_FILT_CTRL 0x62 -#define BPHY_REFRESH_CTRL 0x64 -#define BPHY_RF_OVERRIDE2 0x65 -#define BPHY_SPUR_CANCEL_CTRL 0x66 -#define BPHY_FINE_DIGIGAIN_CTRL 0x67 -#define BPHY_RSSI_LUT 0x88 -#define BPHY_RSSI_LUT_END 0xa7 -#define BPHY_TSSI_LUT 0xa8 -#define BPHY_TSSI_LUT_END 0xc7 -#define BPHY_TSSI2PWR_LUT 0x380 -#define BPHY_TSSI2PWR_LUT_END 0x39f -#define BPHY_LOCOMP_LUT 0x3a0 -#define BPHY_LOCOMP_LUT_END 0x3bf -#define BPHY_TXGAIN_LUT 0x3c0 -#define BPHY_TXGAIN_LUT_END 0x3ff - -/* Bits in BB_CONFIG: */ -#define PHY_BBC_ANT_MASK 0x0180 -#define PHY_BBC_ANT_SHIFT 7 -#define BB_DARWIN 0x1000 -#define BBCFG_RESETCCA 0x4000 -#define BBCFG_RESETRX 0x8000 - -/* Bits in phytest(0x0a): */ -#define TST_DDFS 0x2000 -#define TST_TXFILT1 0x0800 -#define TST_UNSCRAM 0x0400 -#define TST_CARR_SUPP 0x0200 -#define TST_DC_COMP_LOOP 0x0100 -#define TST_LOOPBACK 0x0080 -#define TST_TXFILT0 0x0040 -#define TST_TXTEST_ENABLE 0x0020 -#define TST_TXTEST_RATE 0x0018 -#define TST_TXTEST_PHASE 0x0007 - -/* phytest txTestRate values */ -#define TST_TXTEST_RATE_1MBPS 0 -#define TST_TXTEST_RATE_2MBPS 1 -#define TST_TXTEST_RATE_5_5MBPS 2 -#define TST_TXTEST_RATE_11MBPS 3 -#define TST_TXTEST_RATE_SHIFT 3 - -#define SHM_BYT_CNT 0x2 /* IHR location */ -#define MAX_BYT_CNT 0x600 /* Maximum frame len */ - -#endif /* _D11_H */ diff --git a/drivers/staging/brcm80211/include/dhdioctl.h b/drivers/staging/brcm80211/include/dhdioctl.h deleted file mode 100644 index f0ba53558ccd..000000000000 --- a/drivers/staging/brcm80211/include/dhdioctl.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _dhdioctl_h_ -#define _dhdioctl_h_ - -/* Linux network driver ioctl encoding */ -typedef struct dhd_ioctl { - uint cmd; /* common ioctl definition */ - void *buf; /* pointer to user buffer */ - uint len; /* length of user buffer */ - bool set; /* get or set request (optional) */ - uint used; /* bytes read or written (optional) */ - uint needed; /* bytes needed (optional) */ - uint driver; /* to identify target driver */ -} dhd_ioctl_t; - -/* per-driver magic numbers */ -#define DHD_IOCTL_MAGIC 0x00444944 - -/* bump this number if you change the ioctl interface */ -#define DHD_IOCTL_VERSION 1 - -#define DHD_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */ -#define DHD_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */ - -/* common ioctl definitions */ -#define DHD_GET_MAGIC 0 -#define DHD_GET_VERSION 1 -#define DHD_GET_VAR 2 -#define DHD_SET_VAR 3 - -/* message levels */ -#define DHD_ERROR_VAL 0x0001 -#define DHD_TRACE_VAL 0x0002 -#define DHD_INFO_VAL 0x0004 -#define DHD_DATA_VAL 0x0008 -#define DHD_CTL_VAL 0x0010 -#define DHD_TIMER_VAL 0x0020 -#define DHD_HDRS_VAL 0x0040 -#define DHD_BYTES_VAL 0x0080 -#define DHD_INTR_VAL 0x0100 -#define DHD_LOG_VAL 0x0200 -#define DHD_GLOM_VAL 0x0400 -#define DHD_EVENT_VAL 0x0800 -#define DHD_BTA_VAL 0x1000 -#define DHD_ISCAN_VAL 0x2000 - -#ifdef SDTEST -/* For pktgen iovar */ -typedef struct dhd_pktgen { - uint version; /* To allow structure change tracking */ - uint freq; /* Max ticks between tx/rx attempts */ - uint count; /* Test packets to send/rcv each attempt */ - uint print; /* Print counts every attempts */ - uint total; /* Total packets (or bursts) */ - uint minlen; /* Minimum length of packets to send */ - uint maxlen; /* Maximum length of packets to send */ - uint numsent; /* Count of test packets sent */ - uint numrcvd; /* Count of test packets received */ - uint numfail; /* Count of test send failures */ - uint mode; /* Test mode (type of test packets) */ - uint stop; /* Stop after this many tx failures */ -} dhd_pktgen_t; - -/* Version in case structure changes */ -#define DHD_PKTGEN_VERSION 2 - -/* Type of test packets to use */ -#define DHD_PKTGEN_ECHO 1 /* Send echo requests */ -#define DHD_PKTGEN_SEND 2 /* Send discard packets */ -#define DHD_PKTGEN_RXBURST 3 /* Request dongle send N packets */ -#define DHD_PKTGEN_RECV 4 /* Continuous rx from continuous - tx dongle */ -#endif /* SDTEST */ - -/* Enter idle immediately (no timeout) */ -#define DHD_IDLE_IMMEDIATE (-1) - -/* Values for idleclock iovar: other values are the sd_divisor to use - when idle */ -#define DHD_IDLE_ACTIVE 0 /* Do not request any SD clock change - when idle */ -#define DHD_IDLE_STOP (-1) /* Request SD clock be stopped - (and use SD1 mode) */ - -#endif /* _dhdioctl_h_ */ diff --git a/drivers/staging/brcm80211/include/hndrte_armtrap.h b/drivers/staging/brcm80211/include/hndrte_armtrap.h deleted file mode 100644 index 28f092c9e027..000000000000 --- a/drivers/staging/brcm80211/include/hndrte_armtrap.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _hndrte_armtrap_h -#define _hndrte_armtrap_h - -/* ARM trap handling */ - -/* Trap types defined by ARM (see arminc.h) */ - -/* Trap locations in lo memory */ -#define TRAP_STRIDE 4 -#define FIRST_TRAP TR_RST -#define LAST_TRAP (TR_FIQ * TRAP_STRIDE) - -#if defined(__ARM_ARCH_4T__) -#define MAX_TRAP_TYPE (TR_FIQ + 1) -#elif defined(__ARM_ARCH_7M__) -#define MAX_TRAP_TYPE (TR_ISR + ARMCM3_NUMINTS) -#endif /* __ARM_ARCH_7M__ */ - -/* The trap structure is defined here as offsets for assembly */ -#define TR_TYPE 0x00 -#define TR_EPC 0x04 -#define TR_CPSR 0x08 -#define TR_SPSR 0x0c -#define TR_REGS 0x10 -#define TR_REG(n) (TR_REGS + (n) * 4) -#define TR_SP TR_REG(13) -#define TR_LR TR_REG(14) -#define TR_PC TR_REG(15) - -#define TRAP_T_SIZE 80 - -#ifndef _LANGUAGE_ASSEMBLY - -typedef struct _trap_struct { - u32 type; - u32 epc; - u32 cpsr; - u32 spsr; - u32 r0; - u32 r1; - u32 r2; - u32 r3; - u32 r4; - u32 r5; - u32 r6; - u32 r7; - u32 r8; - u32 r9; - u32 r10; - u32 r11; - u32 r12; - u32 r13; - u32 r14; - u32 pc; -} trap_t; - -#endif /* !_LANGUAGE_ASSEMBLY */ - -#endif /* _hndrte_armtrap_h */ diff --git a/drivers/staging/brcm80211/include/hndrte_cons.h b/drivers/staging/brcm80211/include/hndrte_cons.h deleted file mode 100644 index 5caa53fb6552..000000000000 --- a/drivers/staging/brcm80211/include/hndrte_cons.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define CBUF_LEN (128) - -#define LOG_BUF_LEN 1024 - -typedef struct { - u32 buf; /* Can't be pointer on (64-bit) hosts */ - uint buf_size; - uint idx; - char *_buf_compat; /* Redundant pointer for backward compat. */ -} hndrte_log_t; - -typedef struct { - /* Virtual UART - * When there is no UART (e.g. Quickturn), - * the host should write a complete - * input line directly into cbuf and then write - * the length into vcons_in. - * This may also be used when there is a real UART - * (at risk of conflicting with - * the real UART). vcons_out is currently unused. - */ - volatile uint vcons_in; - volatile uint vcons_out; - - /* Output (logging) buffer - * Console output is written to a ring buffer log_buf at index log_idx. - * The host may read the output when it sees log_idx advance. - * Output will be lost if the output wraps around faster than the host - * polls. - */ - hndrte_log_t log; - - /* Console input line buffer - * Characters are read one at a time into cbuf - * until is received, then - * the buffer is processed as a command line. - * Also used for virtual UART. - */ - uint cbuf_idx; - char cbuf[CBUF_LEN]; -} hndrte_cons_t; diff --git a/drivers/staging/brcm80211/include/msgtrace.h b/drivers/staging/brcm80211/include/msgtrace.h deleted file mode 100644 index d654671a5a30..000000000000 --- a/drivers/staging/brcm80211/include/msgtrace.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _MSGTRACE_H -#define _MSGTRACE_H - -#define MSGTRACE_VERSION 1 - -/* Message trace header */ -typedef struct msgtrace_hdr { - u8 version; - u8 spare; - u16 len; /* Len of the trace */ - u32 seqnum; /* Sequence number of message. Useful - * if the messsage has been lost - * because of DMA error or a bus reset - * (ex: SDIO Func2) - */ - u32 discarded_bytes; /* Number of discarded bytes because of - trace overflow */ - u32 discarded_printf; /* Number of discarded printf - because of trace overflow */ -} __attribute__((packed)) msgtrace_hdr_t; - -#define MSGTRACE_HDRLEN sizeof(msgtrace_hdr_t) - -/* The hbus driver generates traces when sending a trace message. - * This causes endless traces. - * This flag must be set to true in any hbus traces. - * The flag is reset in the function msgtrace_put. - * This prevents endless traces but generates hasardous - * lost of traces only in bus device code. - * It is recommendat to set this flag in macro SD_TRACE - * but not in SD_ERROR for avoiding missing - * hbus error traces. hbus error trace should not generates endless traces. - */ -extern bool msgtrace_hbus_trace; - -typedef void (*msgtrace_func_send_t) (void *hdl1, void *hdl2, u8 *hdr, - u16 hdrlen, u8 *buf, - u16 buflen); - -extern void msgtrace_sent(void); -extern void msgtrace_put(char *buf, int count); -extern void msgtrace_init(void *hdl1, void *hdl2, - msgtrace_func_send_t func_send); - -#endif /* _MSGTRACE_H */ diff --git a/drivers/staging/brcm80211/include/pci_core.h b/drivers/staging/brcm80211/include/pci_core.h deleted file mode 100644 index 9153dcb8160e..000000000000 --- a/drivers/staging/brcm80211/include/pci_core.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _PCI_CORE_H_ -#define _PCI_CORE_H_ - -#ifndef _LANGUAGE_ASSEMBLY - -/* cpp contortions to concatenate w/arg prescan */ -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif - -/* Sonics side: PCI core and host control registers */ -struct sbpciregs { - u32 control; /* PCI control */ - u32 PAD[3]; - u32 arbcontrol; /* PCI arbiter control */ - u32 clkrun; /* Clkrun Control (>=rev11) */ - u32 PAD[2]; - u32 intstatus; /* Interrupt status */ - u32 intmask; /* Interrupt mask */ - u32 sbtopcimailbox; /* Sonics to PCI mailbox */ - u32 PAD[9]; - u32 bcastaddr; /* Sonics broadcast address */ - u32 bcastdata; /* Sonics broadcast data */ - u32 PAD[2]; - u32 gpioin; /* ro: gpio input (>=rev2) */ - u32 gpioout; /* rw: gpio output (>=rev2) */ - u32 gpioouten; /* rw: gpio output enable (>= rev2) */ - u32 gpiocontrol; /* rw: gpio control (>= rev2) */ - u32 PAD[36]; - u32 sbtopci0; /* Sonics to PCI translation 0 */ - u32 sbtopci1; /* Sonics to PCI translation 1 */ - u32 sbtopci2; /* Sonics to PCI translation 2 */ - u32 PAD[189]; - u32 pcicfg[4][64]; /* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */ - u16 sprom[36]; /* SPROM shadow Area */ - u32 PAD[46]; -}; - -#endif /* _LANGUAGE_ASSEMBLY */ - -/* PCI control */ -#define PCI_RST_OE 0x01 /* When set, drives PCI_RESET out to pin */ -#define PCI_RST 0x02 /* Value driven out to pin */ -#define PCI_CLK_OE 0x04 /* When set, drives clock as gated by PCI_CLK out to pin */ -#define PCI_CLK 0x08 /* Gate for clock driven out to pin */ - -/* PCI arbiter control */ -#define PCI_INT_ARB 0x01 /* When set, use an internal arbiter */ -#define PCI_EXT_ARB 0x02 /* When set, use an external arbiter */ -/* ParkID - for PCI corerev >= 8 */ -#define PCI_PARKID_MASK 0x1c /* Selects which agent is parked on an idle bus */ -#define PCI_PARKID_SHIFT 2 -#define PCI_PARKID_EXT0 0 /* External master 0 */ -#define PCI_PARKID_EXT1 1 /* External master 1 */ -#define PCI_PARKID_EXT2 2 /* External master 2 */ -#define PCI_PARKID_EXT3 3 /* External master 3 (rev >= 11) */ -#define PCI_PARKID_INT 3 /* Internal master (rev < 11) */ -#define PCI11_PARKID_INT 4 /* Internal master (rev >= 11) */ -#define PCI_PARKID_LAST 4 /* Last active master (rev < 11) */ -#define PCI11_PARKID_LAST 5 /* Last active master (rev >= 11) */ - -#define PCI_CLKRUN_DSBL 0x8000 /* Bit 15 forceClkrun */ - -/* Interrupt status/mask */ -#define PCI_INTA 0x01 /* PCI INTA# is asserted */ -#define PCI_INTB 0x02 /* PCI INTB# is asserted */ -#define PCI_SERR 0x04 /* PCI SERR# has been asserted (write one to clear) */ -#define PCI_PERR 0x08 /* PCI PERR# has been asserted (write one to clear) */ -#define PCI_PME 0x10 /* PCI PME# is asserted */ - -/* (General) PCI/SB mailbox interrupts, two bits per pci function */ -#define MAILBOX_F0_0 0x100 /* function 0, int 0 */ -#define MAILBOX_F0_1 0x200 /* function 0, int 1 */ -#define MAILBOX_F1_0 0x400 /* function 1, int 0 */ -#define MAILBOX_F1_1 0x800 /* function 1, int 1 */ -#define MAILBOX_F2_0 0x1000 /* function 2, int 0 */ -#define MAILBOX_F2_1 0x2000 /* function 2, int 1 */ -#define MAILBOX_F3_0 0x4000 /* function 3, int 0 */ -#define MAILBOX_F3_1 0x8000 /* function 3, int 1 */ - -/* Sonics broadcast address */ -#define BCAST_ADDR_MASK 0xff /* Broadcast register address */ - -/* Sonics to PCI translation types */ -#define SBTOPCI0_MASK 0xfc000000 -#define SBTOPCI1_MASK 0xfc000000 -#define SBTOPCI2_MASK 0xc0000000 -#define SBTOPCI_MEM 0 -#define SBTOPCI_IO 1 -#define SBTOPCI_CFG0 2 -#define SBTOPCI_CFG1 3 -#define SBTOPCI_PREF 0x4 /* prefetch enable */ -#define SBTOPCI_BURST 0x8 /* burst enable */ -#define SBTOPCI_RC_MASK 0x30 /* read command (>= rev11) */ -#define SBTOPCI_RC_READ 0x00 /* memory read */ -#define SBTOPCI_RC_READLINE 0x10 /* memory read line */ -#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */ - -/* PCI core index in SROM shadow area */ -#define SRSH_PI_OFFSET 0 /* first word */ -#define SRSH_PI_MASK 0xf000 /* bit 15:12 */ -#define SRSH_PI_SHIFT 12 /* bit 15:12 */ - -#endif /* _PCI_CORE_H_ */ diff --git a/drivers/staging/brcm80211/include/rpc_osl.h b/drivers/staging/brcm80211/include/rpc_osl.h deleted file mode 100644 index c59d9ed1397a..000000000000 --- a/drivers/staging/brcm80211/include/rpc_osl.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _rpcosl_h_ -#define _rpcosl_h_ - -typedef struct rpc_osl rpc_osl_t; -extern rpc_osl_t *rpc_osl_attach(struct osl_info *osh); -extern void rpc_osl_detach(rpc_osl_t *rpc_osh); - -#define RPC_OSL_LOCK(rpc_osh) rpc_osl_lock((rpc_osh)) -#define RPC_OSL_UNLOCK(rpc_osh) rpc_osl_unlock((rpc_osh)) -#define RPC_OSL_WAIT(rpc_osh, to, ptimedout) rpc_osl_wait((rpc_osh), (to), (ptimedout)) -#define RPC_OSL_WAKE(rpc_osh) rpc_osl_wake((rpc_osh)) -extern void rpc_osl_lock(rpc_osl_t *rpc_osh); -extern void rpc_osl_unlock(rpc_osl_t *rpc_osh); -extern int rpc_osl_wait(rpc_osl_t *rpc_osh, uint ms, bool *ptimedout); -extern void rpc_osl_wake(rpc_osl_t *rpc_osh); - -#endif /* _rpcosl_h_ */ diff --git a/drivers/staging/brcm80211/include/sbhndpio.h b/drivers/staging/brcm80211/include/sbhndpio.h deleted file mode 100644 index 9eabdb56da73..000000000000 --- a/drivers/staging/brcm80211/include/sbhndpio.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _sbhndpio_h_ -#define _sbhndpio_h_ - -/* PIO structure, - * support two PIO format: 2 bytes access and 4 bytes access - * basic FIFO register set is per channel(transmit or receive) - * a pair of channels is defined for convenience - */ - -/* 2byte-wide pio register set per channel(xmt or rcv) */ -typedef volatile struct { - u16 fifocontrol; - u16 fifodata; - u16 fifofree; /* only valid in xmt channel, not in rcv channel */ - u16 PAD; -} pio2regs_t; - -/* a pair of pio channels(tx and rx) */ -typedef volatile struct { - pio2regs_t tx; - pio2regs_t rx; -} pio2regp_t; - -/* 4byte-wide pio register set per channel(xmt or rcv) */ -typedef volatile struct { - u32 fifocontrol; - u32 fifodata; -} pio4regs_t; - -/* a pair of pio channels(tx and rx) */ -typedef volatile struct { - pio4regs_t tx; - pio4regs_t rx; -} pio4regp_t; - -#endif /* _sbhndpio_h_ */ diff --git a/drivers/staging/brcm80211/include/sbpcmcia.h b/drivers/staging/brcm80211/include/sbpcmcia.h deleted file mode 100644 index 6b9923f551a9..000000000000 --- a/drivers/staging/brcm80211/include/sbpcmcia.h +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _SBPCMCIA_H -#define _SBPCMCIA_H - -/* All the addresses that are offsets in attribute space are divided - * by two to account for the fact that odd bytes are invalid in - * attribute space and our read/write routines make the space appear - * as if they didn't exist. Still we want to show the original numbers - * as documented in the hnd_pcmcia core manual. - */ - -/* PCMCIA Function Configuration Registers */ -#define PCMCIA_FCR (0x700 / 2) - -#define FCR0_OFF 0 -#define FCR1_OFF (0x40 / 2) -#define FCR2_OFF (0x80 / 2) -#define FCR3_OFF (0xc0 / 2) - -#define PCMCIA_FCR0 (0x700 / 2) -#define PCMCIA_FCR1 (0x740 / 2) -#define PCMCIA_FCR2 (0x780 / 2) -#define PCMCIA_FCR3 (0x7c0 / 2) - -/* Standard PCMCIA FCR registers */ - -#define PCMCIA_COR 0 - -#define COR_RST 0x80 -#define COR_LEV 0x40 -#define COR_IRQEN 0x04 -#define COR_BLREN 0x01 -#define COR_FUNEN 0x01 - -#define PCICIA_FCSR (2 / 2) -#define PCICIA_PRR (4 / 2) -#define PCICIA_SCR (6 / 2) -#define PCICIA_ESR (8 / 2) - -#define PCM_MEMOFF 0x0000 -#define F0_MEMOFF 0x1000 -#define F1_MEMOFF 0x2000 -#define F2_MEMOFF 0x3000 -#define F3_MEMOFF 0x4000 - -/* Memory base in the function fcr's */ -#define MEM_ADDR0 (0x728 / 2) -#define MEM_ADDR1 (0x72a / 2) -#define MEM_ADDR2 (0x72c / 2) - -/* PCMCIA base plus Srom access in fcr0: */ -#define PCMCIA_ADDR0 (0x072e / 2) -#define PCMCIA_ADDR1 (0x0730 / 2) -#define PCMCIA_ADDR2 (0x0732 / 2) - -#define MEM_SEG (0x0734 / 2) -#define SROM_CS (0x0736 / 2) -#define SROM_DATAL (0x0738 / 2) -#define SROM_DATAH (0x073a / 2) -#define SROM_ADDRL (0x073c / 2) -#define SROM_ADDRH (0x073e / 2) -#define SROM_INFO2 (0x0772 / 2) /* Corerev >= 2 && <= 5 */ -#define SROM_INFO (0x07be / 2) /* Corerev >= 6 */ - -/* Values for srom_cs: */ -#define SROM_IDLE 0 -#define SROM_WRITE 1 -#define SROM_READ 2 -#define SROM_WEN 4 -#define SROM_WDS 7 -#define SROM_DONE 8 - -/* Fields in srom_info: */ -#define SRI_SZ_MASK 0x03 -#define SRI_BLANK 0x04 -#define SRI_OTP 0x80 - -#if !defined(ESTA_POSTMOGRIFY_REMOVAL) -/* CIS stuff */ - -/* The CIS stops where the FCRs start */ -#define CIS_SIZE PCMCIA_FCR - -/* CIS tuple length field max */ -#define CIS_TUPLE_LEN_MAX 0xff - -/* Standard tuples we know about */ - -#define CISTPL_NULL 0x00 -#define CISTPL_VERS_1 0x15 /* CIS ver, manf, dev & ver strings */ -#define CISTPL_MANFID 0x20 /* Manufacturer and device id */ -#define CISTPL_FUNCID 0x21 /* Function identification */ -#define CISTPL_FUNCE 0x22 /* Function extensions */ -#define CISTPL_CFTABLE 0x1b /* Config table entry */ -#define CISTPL_END 0xff /* End of the CIS tuple chain */ - -/* Function identifier provides context for the function extentions tuple */ -#define CISTPL_FID_SDIO 0x0c /* Extensions defined by SDIO spec */ - -/* Function extensions for LANs (assumed for extensions other than SDIO) */ -#define LAN_TECH 1 /* Technology type */ -#define LAN_SPEED 2 /* Raw bit rate */ -#define LAN_MEDIA 3 /* Transmission media */ -#define LAN_NID 4 /* Node identification (aka MAC addr) */ -#define LAN_CONN 5 /* Connector standard */ - -/* CFTable */ -#define CFTABLE_REGWIN_2K 0x08 /* 2k reg windows size */ -#define CFTABLE_REGWIN_4K 0x10 /* 4k reg windows size */ -#define CFTABLE_REGWIN_8K 0x20 /* 8k reg windows size */ - -/* Vendor unique tuples are 0x80-0x8f. Within Broadcom we'll - * take one for HNBU, and use "extensions" (a la FUNCE) within it. - */ - -#define CISTPL_BRCM_HNBU 0x80 - -/* Subtypes of BRCM_HNBU: */ - -#define HNBU_SROMREV 0x00 /* A byte with sromrev, 1 if not present */ -#define HNBU_CHIPID 0x01 /* Two 16bit values: PCI vendor & device id */ -#define HNBU_BOARDREV 0x02 /* One byte board revision */ -#define HNBU_PAPARMS 0x03 /* PA parameters: 8 (sromrev == 1) - * or 9 (sromrev > 1) bytes - */ -#define HNBU_OEM 0x04 /* Eight bytes OEM data (sromrev == 1) */ -#define HNBU_CC 0x05 /* Default country code (sromrev == 1) */ -#define HNBU_AA 0x06 /* Antennas available */ -#define HNBU_AG 0x07 /* Antenna gain */ -#define HNBU_BOARDFLAGS 0x08 /* board flags (2 or 4 bytes) */ -#define HNBU_LEDS 0x09 /* LED set */ -#define HNBU_CCODE 0x0a /* Country code (2 bytes ascii + 1 byte cctl) - * in rev 2 - */ -#define HNBU_CCKPO 0x0b /* 2 byte cck power offsets in rev 3 */ -#define HNBU_OFDMPO 0x0c /* 4 byte 11g ofdm power offsets in rev 3 */ -#define HNBU_GPIOTIMER 0x0d /* 2 bytes with on/off values in rev 3 */ -#define HNBU_PAPARMS5G 0x0e /* 5G PA params */ -#define HNBU_ANT5G 0x0f /* 4328 5G antennas available/gain */ -#define HNBU_RDLID 0x10 /* 2 byte USB remote downloader (RDL) product Id */ -#define HNBU_RSSISMBXA2G 0x11 /* 4328 2G RSSI mid pt sel & board switch arch, - * 2 bytes, rev 3. - */ -#define HNBU_RSSISMBXA5G 0x12 /* 4328 5G RSSI mid pt sel & board switch arch, - * 2 bytes, rev 3. - */ -#define HNBU_XTALFREQ 0x13 /* 4 byte Crystal frequency in kilohertz */ -#define HNBU_TRI2G 0x14 /* 4328 2G TR isolation, 1 byte */ -#define HNBU_TRI5G 0x15 /* 4328 5G TR isolation, 3 bytes */ -#define HNBU_RXPO2G 0x16 /* 4328 2G RX power offset, 1 byte */ -#define HNBU_RXPO5G 0x17 /* 4328 5G RX power offset, 1 byte */ -#define HNBU_BOARDNUM 0x18 /* board serial number, independent of mac addr */ -#define HNBU_MACADDR 0x19 /* mac addr override for the standard CIS LAN_NID */ -#define HNBU_RDLSN 0x1a /* 2 bytes; serial # advertised in USB descriptor */ -#define HNBU_BOARDTYPE 0x1b /* 2 bytes; boardtype */ -#define HNBU_LEDDC 0x1c /* 2 bytes; LED duty cycle */ -#define HNBU_HNBUCIS 0x1d /* what follows is proprietary HNBU CIS format */ -#define HNBU_PAPARMS_SSLPNPHY 0x1e /* SSLPNPHY PA params */ -#define HNBU_RSSISMBXA2G_SSLPNPHY 0x1f /* SSLPNPHY RSSI mid pt sel & board switch arch */ -#define HNBU_RDLRNDIS 0x20 /* 1 byte; 1 = RDL advertises RNDIS config */ -#define HNBU_CHAINSWITCH 0x21 /* 2 byte; txchain, rxchain */ -#define HNBU_REGREV 0x22 /* 1 byte; */ -#define HNBU_FEM 0x23 /* 2 or 4 byte: 11n frontend specification */ -#define HNBU_PAPARMS_C0 0x24 /* 8 or 30 bytes: 11n pa paramater for chain 0 */ -#define HNBU_PAPARMS_C1 0x25 /* 8 or 30 bytes: 11n pa paramater for chain 1 */ -#define HNBU_PAPARMS_C2 0x26 /* 8 or 30 bytes: 11n pa paramater for chain 2 */ -#define HNBU_PAPARMS_C3 0x27 /* 8 or 30 bytes: 11n pa paramater for chain 3 */ -#define HNBU_PO_CCKOFDM 0x28 /* 6 or 18 bytes: cck2g/ofdm2g/ofdm5g power offset */ -#define HNBU_PO_MCS2G 0x29 /* 8 bytes: mcs2g power offset */ -#define HNBU_PO_MCS5GM 0x2a /* 8 bytes: mcs5g mid band power offset */ -#define HNBU_PO_MCS5GLH 0x2b /* 16 bytes: mcs5g low-high band power offset */ -#define HNBU_PO_CDD 0x2c /* 2 bytes: cdd2g/5g power offset */ -#define HNBU_PO_STBC 0x2d /* 2 bytes: stbc2g/5g power offset */ -#define HNBU_PO_40M 0x2e /* 2 bytes: 40Mhz channel 2g/5g power offset */ -#define HNBU_PO_40MDUP 0x2f /* 2 bytes: 40Mhz channel dup 2g/5g power offset */ - -#define HNBU_RDLRWU 0x30 /* 1 byte; 1 = RDL advertises Remote Wake-up */ -#define HNBU_WPS 0x31 /* 1 byte; GPIO pin for WPS button */ -#define HNBU_USBFS 0x32 /* 1 byte; 1 = USB advertises FS mode only */ -#define HNBU_BRMIN 0x33 /* 4 byte bootloader min resource mask */ -#define HNBU_BRMAX 0x34 /* 4 byte bootloader max resource mask */ -#define HNBU_PATCH 0x35 /* bootloader patch addr(2b) & data(4b) pair */ -#define HNBU_CCKFILTTYPE 0x36 /* CCK digital filter selection options */ -#define HNBU_OFDMPO5G 0x37 /* 4 * 3 = 12 byte 11a ofdm power offsets in rev 3 */ - -#define HNBU_USBEPNUM 0x40 /* USB endpoint numbers */ -#define HNBU_SROM3SWRGN 0x80 /* 78 bytes; srom rev 3 s/w region without crc8 - * plus extra info appended. - */ -#define HNBU_RESERVED 0x81 /* Reserved for non-BRCM post-mfg additions */ -#define HNBU_CUSTOM1 0x82 /* 4 byte; For non-BRCM post-mfg additions */ -#define HNBU_CUSTOM2 0x83 /* Reserved; For non-BRCM post-mfg additions */ -#endif /* !defined(ESTA_POSTMOGRIFY_REMOVAL) */ - -/* sbtmstatelow */ -#define SBTML_INT_ACK 0x40000 /* ack the sb interrupt */ -#define SBTML_INT_EN 0x20000 /* enable sb interrupt */ - -/* sbtmstatehigh */ -#define SBTMH_INT_STATUS 0x40000 /* sb interrupt status */ - -#endif /* _SBPCMCIA_H */ diff --git a/drivers/staging/brcm80211/include/sbsocram.h b/drivers/staging/brcm80211/include/sbsocram.h deleted file mode 100644 index 0cfe9852b27f..000000000000 --- a/drivers/staging/brcm80211/include/sbsocram.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _SBSOCRAM_H -#define _SBSOCRAM_H - -#ifndef _LANGUAGE_ASSEMBLY - -/* cpp contortions to concatenate w/arg prescan */ -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif /* PAD */ - -/* Memcsocram core registers */ -typedef volatile struct sbsocramregs { - u32 coreinfo; - u32 bwalloc; - u32 extracoreinfo; - u32 biststat; - u32 bankidx; - u32 standbyctrl; - - u32 errlogstatus; /* rev 6 */ - u32 errlogaddr; /* rev 6 */ - /* used for patching rev 3 & 5 */ - u32 cambankidx; - u32 cambankstandbyctrl; - u32 cambankpatchctrl; - u32 cambankpatchtblbaseaddr; - u32 cambankcmdreg; - u32 cambankdatareg; - u32 cambankmaskreg; - u32 PAD[1]; - u32 bankinfo; /* corev 8 */ - u32 PAD[15]; - u32 extmemconfig; - u32 extmemparitycsr; - u32 extmemparityerrdata; - u32 extmemparityerrcnt; - u32 extmemwrctrlandsize; - u32 PAD[84]; - u32 workaround; - u32 pwrctl; /* corerev >= 2 */ -} sbsocramregs_t; - -#endif /* _LANGUAGE_ASSEMBLY */ - -/* Register offsets */ -#define SR_COREINFO 0x00 -#define SR_BWALLOC 0x04 -#define SR_BISTSTAT 0x0c -#define SR_BANKINDEX 0x10 -#define SR_BANKSTBYCTL 0x14 -#define SR_PWRCTL 0x1e8 - -/* Coreinfo register */ -#define SRCI_PT_MASK 0x00070000 /* corerev >= 6; port type[18:16] */ -#define SRCI_PT_SHIFT 16 -/* port types : SRCI_PT__ */ -#define SRCI_PT_OCP_OCP 0 -#define SRCI_PT_AXI_OCP 1 -#define SRCI_PT_ARM7AHB_OCP 2 -#define SRCI_PT_CM3AHB_OCP 3 -#define SRCI_PT_AXI_AXI 4 -#define SRCI_PT_AHB_AXI 5 -/* corerev >= 3 */ -#define SRCI_LSS_MASK 0x00f00000 -#define SRCI_LSS_SHIFT 20 -#define SRCI_LRS_MASK 0x0f000000 -#define SRCI_LRS_SHIFT 24 - -/* In corerev 0, the memory size is 2 to the power of the - * base plus 16 plus to the contents of the memsize field plus 1. - */ -#define SRCI_MS0_MASK 0xf -#define SR_MS0_BASE 16 - -/* - * In corerev 1 the bank size is 2 ^ the bank size field plus 14, - * the memory size is number of banks times bank size. - * The same applies to rom size. - */ -#define SRCI_ROMNB_MASK 0xf000 -#define SRCI_ROMNB_SHIFT 12 -#define SRCI_ROMBSZ_MASK 0xf00 -#define SRCI_ROMBSZ_SHIFT 8 -#define SRCI_SRNB_MASK 0xf0 -#define SRCI_SRNB_SHIFT 4 -#define SRCI_SRBSZ_MASK 0xf -#define SRCI_SRBSZ_SHIFT 0 - -#define SR_BSZ_BASE 14 - -/* Standby control register */ -#define SRSC_SBYOVR_MASK 0x80000000 -#define SRSC_SBYOVR_SHIFT 31 -#define SRSC_SBYOVRVAL_MASK 0x60000000 -#define SRSC_SBYOVRVAL_SHIFT 29 -#define SRSC_SBYEN_MASK 0x01000000 /* rev >= 3 */ -#define SRSC_SBYEN_SHIFT 24 - -/* Power control register */ -#define SRPC_PMU_STBYDIS_MASK 0x00000010 /* rev >= 3 */ -#define SRPC_PMU_STBYDIS_SHIFT 4 -#define SRPC_STBYOVRVAL_MASK 0x00000008 -#define SRPC_STBYOVRVAL_SHIFT 3 -#define SRPC_STBYOVR_MASK 0x00000007 -#define SRPC_STBYOVR_SHIFT 0 - -/* Extra core capability register */ -#define SRECC_NUM_BANKS_MASK 0x000000F0 -#define SRECC_NUM_BANKS_SHIFT 4 -#define SRECC_BANKSIZE_MASK 0x0000000F -#define SRECC_BANKSIZE_SHIFT 0 - -#define SRECC_BANKSIZE(value) (1 << (value)) - -/* CAM bank patch control */ -#define SRCBPC_PATCHENABLE 0x80000000 - -#define SRP_ADDRESS 0x0001FFFC -#define SRP_VALID 0x8000 - -/* CAM bank command reg */ -#define SRCMD_WRITE 0x00020000 -#define SRCMD_READ 0x00010000 -#define SRCMD_DONE 0x80000000 - -#define SRCMD_DONE_DLY 1000 - -/* bankidx and bankinfo reg defines corerev >= 8 */ -#define SOCRAM_BANKINFO_SZMASK 0x3f -#define SOCRAM_BANKIDX_ROM_MASK 0x100 - -#define SOCRAM_BANKIDX_MEMTYPE_SHIFT 8 -/* socram bankinfo memtype */ -#define SOCRAM_MEMTYPE_RAM 0 -#define SOCRAM_MEMTYPE_R0M 1 -#define SOCRAM_MEMTYPE_DEVRAM 2 - -#define SOCRAM_BANKINFO_REG 0x40 -#define SOCRAM_BANKIDX_REG 0x10 -#define SOCRAM_BANKINFO_STDBY_MASK 0x400 -#define SOCRAM_BANKINFO_STDBY_TIMER 0x800 - -/* bankinfo rev >= 10 */ -#define SOCRAM_BANKINFO_DEVRAMSEL_SHIFT 13 -#define SOCRAM_BANKINFO_DEVRAMSEL_MASK 0x2000 -#define SOCRAM_BANKINFO_DEVRAMPRO_SHIFT 14 -#define SOCRAM_BANKINFO_DEVRAMPRO_MASK 0x4000 - -/* extracoreinfo register */ -#define SOCRAM_DEVRAMBANK_MASK 0xF000 -#define SOCRAM_DEVRAMBANK_SHIFT 12 - -/* bank info to calculate bank size */ -#define SOCRAM_BANKINFO_SZBASE 8192 -#define SOCRAM_BANKSIZE_SHIFT 13 /* SOCRAM_BANKINFO_SZBASE */ - -#endif /* _SBSOCRAM_H */ diff --git a/drivers/staging/brcm80211/include/sdioh.h b/drivers/staging/brcm80211/include/sdioh.h deleted file mode 100644 index f96aaf9cec74..000000000000 --- a/drivers/staging/brcm80211/include/sdioh.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _SDIOH_H -#define _SDIOH_H - -#define SD_SysAddr 0x000 -#define SD_BlockSize 0x004 -#define SD_BlockCount 0x006 -#define SD_Arg0 0x008 -#define SD_Arg1 0x00A -#define SD_TransferMode 0x00C -#define SD_Command 0x00E -#define SD_Response0 0x010 -#define SD_Response1 0x012 -#define SD_Response2 0x014 -#define SD_Response3 0x016 -#define SD_Response4 0x018 -#define SD_Response5 0x01A -#define SD_Response6 0x01C -#define SD_Response7 0x01E -#define SD_BufferDataPort0 0x020 -#define SD_BufferDataPort1 0x022 -#define SD_PresentState 0x024 -#define SD_HostCntrl 0x028 -#define SD_PwrCntrl 0x029 -#define SD_BlockGapCntrl 0x02A -#define SD_WakeupCntrl 0x02B -#define SD_ClockCntrl 0x02C -#define SD_TimeoutCntrl 0x02E -#define SD_SoftwareReset 0x02F -#define SD_IntrStatus 0x030 -#define SD_ErrorIntrStatus 0x032 -#define SD_IntrStatusEnable 0x034 -#define SD_ErrorIntrStatusEnable 0x036 -#define SD_IntrSignalEnable 0x038 -#define SD_ErrorIntrSignalEnable 0x03A -#define SD_CMD12ErrorStatus 0x03C -#define SD_Capabilities 0x040 -#define SD_Capabilities_Reserved 0x044 -#define SD_MaxCurCap 0x048 -#define SD_MaxCurCap_Reserved 0x04C -#define SD_ADMA_SysAddr 0x58 -#define SD_SlotInterruptStatus 0x0FC -#define SD_HostControllerVersion 0x0FE - -/* SD specific registers in PCI config space */ -#define SD_SlotInfo 0x40 - -#endif /* _SDIOH_H */ diff --git a/drivers/staging/brcm80211/include/sdiovar.h b/drivers/staging/brcm80211/include/sdiovar.h deleted file mode 100644 index d1cfa5f0a982..000000000000 --- a/drivers/staging/brcm80211/include/sdiovar.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _sdiovar_h_ -#define _sdiovar_h_ - -typedef struct sdreg { - int func; - int offset; - int value; -} sdreg_t; - -/* Common msglevel constants */ -#define SDH_ERROR_VAL 0x0001 /* Error */ -#define SDH_TRACE_VAL 0x0002 /* Trace */ -#define SDH_INFO_VAL 0x0004 /* Info */ -#define SDH_DEBUG_VAL 0x0008 /* Debug */ -#define SDH_DATA_VAL 0x0010 /* Data */ -#define SDH_CTRL_VAL 0x0020 /* Control Regs */ -#define SDH_LOG_VAL 0x0040 /* Enable bcmlog */ -#define SDH_DMA_VAL 0x0080 /* DMA */ - -#define NUM_PREV_TRANSACTIONS 16 - -#endif /* _sdiovar_h_ */ diff --git a/drivers/staging/brcm80211/include/spid.h b/drivers/staging/brcm80211/include/spid.h deleted file mode 100644 index e0abb8432886..000000000000 --- a/drivers/staging/brcm80211/include/spid.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _SPI_H -#define _SPI_H - -/* - * Brcm SPI Device Register Map. - * - */ - -typedef volatile struct { - u8 config; /* 0x00, len, endian, clock, speed, polarity, wakeup */ - u8 response_delay; /* 0x01, read response delay in bytes (corerev < 3) */ - u8 status_enable; /* 0x02, status-enable, intr with status, response_delay - * function selection, command/data error check - */ - u8 reset_bp; /* 0x03, reset on wlan/bt backplane reset (corerev >= 1) */ - u16 intr_reg; /* 0x04, Intr status register */ - u16 intr_en_reg; /* 0x06, Intr mask register */ - u32 status_reg; /* 0x08, RO, Status bits of last spi transfer */ - u16 f1_info_reg; /* 0x0c, RO, enabled, ready for data transfer, blocksize */ - u16 f2_info_reg; /* 0x0e, RO, enabled, ready for data transfer, blocksize */ - u16 f3_info_reg; /* 0x10, RO, enabled, ready for data transfer, blocksize */ - u32 test_read; /* 0x14, RO 0xfeedbead signature */ - u32 test_rw; /* 0x18, RW */ - u8 resp_delay_f0; /* 0x1c, read resp delay bytes for F0 (corerev >= 3) */ - u8 resp_delay_f1; /* 0x1d, read resp delay bytes for F1 (corerev >= 3) */ - u8 resp_delay_f2; /* 0x1e, read resp delay bytes for F2 (corerev >= 3) */ - u8 resp_delay_f3; /* 0x1f, read resp delay bytes for F3 (corerev >= 3) */ -} spi_regs_t; - -/* SPI device register offsets */ -#define SPID_CONFIG 0x00 -#define SPID_RESPONSE_DELAY 0x01 -#define SPID_STATUS_ENABLE 0x02 -#define SPID_RESET_BP 0x03 /* (corerev >= 1) */ -#define SPID_INTR_REG 0x04 /* 16 bits - Interrupt status */ -#define SPID_INTR_EN_REG 0x06 /* 16 bits - Interrupt mask */ -#define SPID_STATUS_REG 0x08 /* 32 bits */ -#define SPID_F1_INFO_REG 0x0C /* 16 bits */ -#define SPID_F2_INFO_REG 0x0E /* 16 bits */ -#define SPID_F3_INFO_REG 0x10 /* 16 bits */ -#define SPID_TEST_READ 0x14 /* 32 bits */ -#define SPID_TEST_RW 0x18 /* 32 bits */ -#define SPID_RESP_DELAY_F0 0x1c /* 8 bits (corerev >= 3) */ -#define SPID_RESP_DELAY_F1 0x1d /* 8 bits (corerev >= 3) */ -#define SPID_RESP_DELAY_F2 0x1e /* 8 bits (corerev >= 3) */ -#define SPID_RESP_DELAY_F3 0x1f /* 8 bits (corerev >= 3) */ - -/* Bit masks for SPID_CONFIG device register */ -#define WORD_LENGTH_32 0x1 /* 0/1 16/32 bit word length */ -#define ENDIAN_BIG 0x2 /* 0/1 Little/Big Endian */ -#define CLOCK_PHASE 0x4 /* 0/1 clock phase delay */ -#define CLOCK_POLARITY 0x8 /* 0/1 Idle state clock polarity is low/high */ -#define HIGH_SPEED_MODE 0x10 /* 1/0 High Speed mode / Normal mode */ -#define INTR_POLARITY 0x20 /* 1/0 Interrupt active polarity is high/low */ -#define WAKE_UP 0x80 /* 0/1 Wake-up command from Host to WLAN */ - -/* Bit mask for SPID_RESPONSE_DELAY device register */ -#define RESPONSE_DELAY_MASK 0xFF /* Configurable rd response delay in multiples of 8 bits */ - -/* Bit mask for SPID_STATUS_ENABLE device register */ -#define STATUS_ENABLE 0x1 /* 1/0 Status sent/not sent to host after read/write */ -#define INTR_WITH_STATUS 0x2 /* 0/1 Do-not / do-interrupt if status is sent */ -#define RESP_DELAY_ALL 0x4 /* Applicability of resp delay to F1 or all func's read */ -#define DWORD_PKT_LEN_EN 0x8 /* Packet len denoted in dwords instead of bytes */ -#define CMD_ERR_CHK_EN 0x20 /* Command error check enable */ -#define DATA_ERR_CHK_EN 0x40 /* Data error check enable */ - -/* Bit mask for SPID_RESET_BP device register */ -#define RESET_ON_WLAN_BP_RESET 0x4 /* enable reset for WLAN backplane */ -#define RESET_ON_BT_BP_RESET 0x8 /* enable reset for BT backplane */ -#define RESET_SPI 0x80 /* reset the above enabled logic */ - -/* Bit mask for SPID_INTR_REG device register */ -#define DATA_UNAVAILABLE 0x0001 /* Requested data not available; Clear by writing a "1" */ -#define F2_F3_FIFO_RD_UNDERFLOW 0x0002 -#define F2_F3_FIFO_WR_OVERFLOW 0x0004 -#define COMMAND_ERROR 0x0008 /* Cleared by writing 1 */ -#define DATA_ERROR 0x0010 /* Cleared by writing 1 */ -#define F2_PACKET_AVAILABLE 0x0020 -#define F3_PACKET_AVAILABLE 0x0040 -#define F1_OVERFLOW 0x0080 /* Due to last write. Bkplane has pending write requests */ -#define MISC_INTR0 0x0100 -#define MISC_INTR1 0x0200 -#define MISC_INTR2 0x0400 -#define MISC_INTR3 0x0800 -#define MISC_INTR4 0x1000 -#define F1_INTR 0x2000 -#define F2_INTR 0x4000 -#define F3_INTR 0x8000 - -/* Bit mask for 32bit SPID_STATUS_REG device register */ -#define STATUS_DATA_NOT_AVAILABLE 0x00000001 -#define STATUS_UNDERFLOW 0x00000002 -#define STATUS_OVERFLOW 0x00000004 -#define STATUS_F2_INTR 0x00000008 -#define STATUS_F3_INTR 0x00000010 -#define STATUS_F2_RX_READY 0x00000020 -#define STATUS_F3_RX_READY 0x00000040 -#define STATUS_HOST_CMD_DATA_ERR 0x00000080 -#define STATUS_F2_PKT_AVAILABLE 0x00000100 -#define STATUS_F2_PKT_LEN_MASK 0x000FFE00 -#define STATUS_F2_PKT_LEN_SHIFT 9 -#define STATUS_F3_PKT_AVAILABLE 0x00100000 -#define STATUS_F3_PKT_LEN_MASK 0xFFE00000 -#define STATUS_F3_PKT_LEN_SHIFT 21 - -/* Bit mask for 16 bits SPID_F1_INFO_REG device register */ -#define F1_ENABLED 0x0001 -#define F1_RDY_FOR_DATA_TRANSFER 0x0002 -#define F1_MAX_PKT_SIZE 0x01FC - -/* Bit mask for 16 bits SPID_F2_INFO_REG device register */ -#define F2_ENABLED 0x0001 -#define F2_RDY_FOR_DATA_TRANSFER 0x0002 -#define F2_MAX_PKT_SIZE 0x3FFC - -/* Bit mask for 16 bits SPID_F3_INFO_REG device register */ -#define F3_ENABLED 0x0001 -#define F3_RDY_FOR_DATA_TRANSFER 0x0002 -#define F3_MAX_PKT_SIZE 0x3FFC - -/* Bit mask for 32 bits SPID_TEST_READ device register read in 16bit LE mode */ -#define TEST_RO_DATA_32BIT_LE 0xFEEDBEAD - -/* Maximum number of I/O funcs */ -#define SPI_MAX_IOFUNCS 4 - -#define SPI_MAX_PKT_LEN (2048*4) - -/* Misc defines */ -#define SPI_FUNC_0 0 -#define SPI_FUNC_1 1 -#define SPI_FUNC_2 2 -#define SPI_FUNC_3 3 - -#define WAIT_F2RXFIFORDY 100 -#define WAIT_F2RXFIFORDY_DELAY 20 - -#endif /* _SPI_H */ diff --git a/drivers/staging/brcm80211/util/bcmsrom_tbl.h b/drivers/staging/brcm80211/util/bcmsrom_tbl.h new file mode 100644 index 000000000000..22ae7c1c18fb --- /dev/null +++ b/drivers/staging/brcm80211/util/bcmsrom_tbl.h @@ -0,0 +1,583 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _bcmsrom_tbl_h_ +#define _bcmsrom_tbl_h_ + +#include "sbpcmcia.h" +#include "wlioctl.h" + +typedef struct { + const char *name; + u32 revmask; + u32 flags; + u16 off; + u16 mask; +} sromvar_t; + +#define SRFL_MORE 1 /* value continues as described by the next entry */ +#define SRFL_NOFFS 2 /* value bits can't be all one's */ +#define SRFL_PRHEX 4 /* value is in hexdecimal format */ +#define SRFL_PRSIGN 8 /* value is in signed decimal format */ +#define SRFL_CCODE 0x10 /* value is in country code format */ +#define SRFL_ETHADDR 0x20 /* value is an Ethernet address */ +#define SRFL_LEDDC 0x40 /* value is an LED duty cycle */ +#define SRFL_NOVAR 0x80 /* do not generate a nvram param, entry is for mfgc */ + +/* Assumptions: + * - Ethernet address spans across 3 consective words + * + * Table rules: + * - Add multiple entries next to each other if a value spans across multiple words + * (even multiple fields in the same word) with each entry except the last having + * it's SRFL_MORE bit set. + * - Ethernet address entry does not follow above rule and must not have SRFL_MORE + * bit set. Its SRFL_ETHADDR bit implies it takes multiple words. + * - The last entry's name field must be NULL to indicate the end of the table. Other + * entries must have non-NULL name. + */ + +static const sromvar_t pci_sromvars[] = { + {"devid", 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID, 0xffff}, + {"boardrev", 0x0000000e, SRFL_PRHEX, SROM_AABREV, SROM_BR_MASK}, + {"boardrev", 0x000000f0, SRFL_PRHEX, SROM4_BREV, 0xffff}, + {"boardrev", 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff}, + {"boardflags", 0x00000002, SRFL_PRHEX, SROM_BFL, 0xffff}, + {"boardflags", 0x00000004, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff}, + {"", 0, 0, SROM_BFL2, 0xffff}, + {"boardflags", 0x00000008, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff}, + {"", 0, 0, SROM3_BFL2, 0xffff}, + {"boardflags", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL0, 0xffff}, + {"", 0, 0, SROM4_BFL1, 0xffff}, + {"boardflags", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL0, 0xffff}, + {"", 0, 0, SROM5_BFL1, 0xffff}, + {"boardflags", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0, 0xffff}, + {"", 0, 0, SROM8_BFL1, 0xffff}, + {"boardflags2", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL2, 0xffff}, + {"", 0, 0, SROM4_BFL3, 0xffff}, + {"boardflags2", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL2, 0xffff}, + {"", 0, 0, SROM5_BFL3, 0xffff}, + {"boardflags2", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2, 0xffff}, + {"", 0, 0, SROM8_BFL3, 0xffff}, + {"boardtype", 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff}, + {"boardnum", 0x00000006, 0, SROM_MACLO_IL0, 0xffff}, + {"boardnum", 0x00000008, 0, SROM3_MACLO, 0xffff}, + {"boardnum", 0x00000010, 0, SROM4_MACLO, 0xffff}, + {"boardnum", 0x000000e0, 0, SROM5_MACLO, 0xffff}, + {"boardnum", 0xffffff00, 0, SROM8_MACLO, 0xffff}, + {"cc", 0x00000002, 0, SROM_AABREV, SROM_CC_MASK}, + {"regrev", 0x00000008, 0, SROM_OPO, 0xff00}, + {"regrev", 0x00000010, 0, SROM4_REGREV, 0x00ff}, + {"regrev", 0x000000e0, 0, SROM5_REGREV, 0x00ff}, + {"regrev", 0xffffff00, 0, SROM8_REGREV, 0x00ff}, + {"ledbh0", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0x00ff}, + {"ledbh1", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0xff00}, + {"ledbh2", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0x00ff}, + {"ledbh3", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0xff00}, + {"ledbh0", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0x00ff}, + {"ledbh1", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0xff00}, + {"ledbh2", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0x00ff}, + {"ledbh3", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0xff00}, + {"ledbh0", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0x00ff}, + {"ledbh1", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0xff00}, + {"ledbh2", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0x00ff}, + {"ledbh3", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0xff00}, + {"ledbh0", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff}, + {"ledbh1", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00}, + {"ledbh2", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff}, + {"ledbh3", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00}, + {"pa0b0", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB0, 0xffff}, + {"pa0b1", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB1, 0xffff}, + {"pa0b2", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB2, 0xffff}, + {"pa0itssit", 0x0000000e, 0, SROM_ITT, 0x00ff}, + {"pa0maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0x00ff}, + {"pa0b0", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff}, + {"pa0b1", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff}, + {"pa0b2", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff}, + {"pa0itssit", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00}, + {"pa0maxpwr", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff}, + {"opo", 0x0000000c, 0, SROM_OPO, 0x00ff}, + {"opo", 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff}, + {"aa2g", 0x0000000e, 0, SROM_AABREV, SROM_AA0_MASK}, + {"aa2g", 0x000000f0, 0, SROM4_AA, 0x00ff}, + {"aa2g", 0xffffff00, 0, SROM8_AA, 0x00ff}, + {"aa5g", 0x0000000e, 0, SROM_AABREV, SROM_AA1_MASK}, + {"aa5g", 0x000000f0, 0, SROM4_AA, 0xff00}, + {"aa5g", 0xffffff00, 0, SROM8_AA, 0xff00}, + {"ag0", 0x0000000e, 0, SROM_AG10, 0x00ff}, + {"ag1", 0x0000000e, 0, SROM_AG10, 0xff00}, + {"ag0", 0x000000f0, 0, SROM4_AG10, 0x00ff}, + {"ag1", 0x000000f0, 0, SROM4_AG10, 0xff00}, + {"ag2", 0x000000f0, 0, SROM4_AG32, 0x00ff}, + {"ag3", 0x000000f0, 0, SROM4_AG32, 0xff00}, + {"ag0", 0xffffff00, 0, SROM8_AG10, 0x00ff}, + {"ag1", 0xffffff00, 0, SROM8_AG10, 0xff00}, + {"ag2", 0xffffff00, 0, SROM8_AG32, 0x00ff}, + {"ag3", 0xffffff00, 0, SROM8_AG32, 0xff00}, + {"pa1b0", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB0, 0xffff}, + {"pa1b1", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB1, 0xffff}, + {"pa1b2", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB2, 0xffff}, + {"pa1lob0", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB0, 0xffff}, + {"pa1lob1", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB1, 0xffff}, + {"pa1lob2", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB2, 0xffff}, + {"pa1hib0", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB0, 0xffff}, + {"pa1hib1", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB1, 0xffff}, + {"pa1hib2", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB2, 0xffff}, + {"pa1itssit", 0x0000000e, 0, SROM_ITT, 0xff00}, + {"pa1maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0xff00}, + {"pa1lomaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0xff00}, + {"pa1himaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0x00ff}, + {"pa1b0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff}, + {"pa1b1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff}, + {"pa1b2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff}, + {"pa1lob0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_LC, 0xffff}, + {"pa1lob1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_LC, 0xffff}, + {"pa1lob2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_LC, 0xffff}, + {"pa1hib0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_HC, 0xffff}, + {"pa1hib1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_HC, 0xffff}, + {"pa1hib2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_HC, 0xffff}, + {"pa1itssit", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0xff00}, + {"pa1maxpwr", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff}, + {"pa1lomaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00}, + {"pa1himaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff}, + {"bxa2g", 0x00000008, 0, SROM_BXARSSI2G, 0x1800}, + {"rssisav2g", 0x00000008, 0, SROM_BXARSSI2G, 0x0700}, + {"rssismc2g", 0x00000008, 0, SROM_BXARSSI2G, 0x00f0}, + {"rssismf2g", 0x00000008, 0, SROM_BXARSSI2G, 0x000f}, + {"bxa2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800}, + {"rssisav2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700}, + {"rssismc2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0}, + {"rssismf2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f}, + {"bxa5g", 0x00000008, 0, SROM_BXARSSI5G, 0x1800}, + {"rssisav5g", 0x00000008, 0, SROM_BXARSSI5G, 0x0700}, + {"rssismc5g", 0x00000008, 0, SROM_BXARSSI5G, 0x00f0}, + {"rssismf5g", 0x00000008, 0, SROM_BXARSSI5G, 0x000f}, + {"bxa5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800}, + {"rssisav5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700}, + {"rssismc5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0}, + {"rssismf5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f}, + {"tri2g", 0x00000008, 0, SROM_TRI52G, 0x00ff}, + {"tri5g", 0x00000008, 0, SROM_TRI52G, 0xff00}, + {"tri5gl", 0x00000008, 0, SROM_TRI5GHL, 0x00ff}, + {"tri5gh", 0x00000008, 0, SROM_TRI5GHL, 0xff00}, + {"tri2g", 0xffffff00, 0, SROM8_TRI52G, 0x00ff}, + {"tri5g", 0xffffff00, 0, SROM8_TRI52G, 0xff00}, + {"tri5gl", 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff}, + {"tri5gh", 0xffffff00, 0, SROM8_TRI5GHL, 0xff00}, + {"rxpo2g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0x00ff}, + {"rxpo5g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0xff00}, + {"rxpo2g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff}, + {"rxpo5g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00}, + {"txchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_TXCHAIN_MASK}, + {"rxchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_RXCHAIN_MASK}, + {"antswitch", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_SWITCH_MASK}, + {"txchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_TXCHAIN_MASK}, + {"rxchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_RXCHAIN_MASK}, + {"antswitch", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_SWITCH_MASK}, + {"tssipos2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TSSIPOS_MASK}, + {"extpagain2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_EXTPA_GAIN_MASK}, + {"pdetrange2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_PDET_RANGE_MASK}, + {"triso2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TR_ISO_MASK}, + {"antswctl2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_ANTSWLUT_MASK}, + {"tssipos5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TSSIPOS_MASK}, + {"extpagain5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_EXTPA_GAIN_MASK}, + {"pdetrange5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_PDET_RANGE_MASK}, + {"triso5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TR_ISO_MASK}, + {"antswctl5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_ANTSWLUT_MASK}, + {"tempthresh", 0xffffff00, 0, SROM8_THERMAL, 0xff00}, + {"tempoffset", 0xffffff00, 0, SROM8_THERMAL, 0x00ff}, + {"txpid2ga0", 0x000000f0, 0, SROM4_TXPID2G, 0x00ff}, + {"txpid2ga1", 0x000000f0, 0, SROM4_TXPID2G, 0xff00}, + {"txpid2ga2", 0x000000f0, 0, SROM4_TXPID2G + 1, 0x00ff}, + {"txpid2ga3", 0x000000f0, 0, SROM4_TXPID2G + 1, 0xff00}, + {"txpid5ga0", 0x000000f0, 0, SROM4_TXPID5G, 0x00ff}, + {"txpid5ga1", 0x000000f0, 0, SROM4_TXPID5G, 0xff00}, + {"txpid5ga2", 0x000000f0, 0, SROM4_TXPID5G + 1, 0x00ff}, + {"txpid5ga3", 0x000000f0, 0, SROM4_TXPID5G + 1, 0xff00}, + {"txpid5gla0", 0x000000f0, 0, SROM4_TXPID5GL, 0x00ff}, + {"txpid5gla1", 0x000000f0, 0, SROM4_TXPID5GL, 0xff00}, + {"txpid5gla2", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0x00ff}, + {"txpid5gla3", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0xff00}, + {"txpid5gha0", 0x000000f0, 0, SROM4_TXPID5GH, 0x00ff}, + {"txpid5gha1", 0x000000f0, 0, SROM4_TXPID5GH, 0xff00}, + {"txpid5gha2", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0x00ff}, + {"txpid5gha3", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0xff00}, + + {"ccode", 0x0000000f, SRFL_CCODE, SROM_CCODE, 0xffff}, + {"ccode", 0x00000010, SRFL_CCODE, SROM4_CCODE, 0xffff}, + {"ccode", 0x000000e0, SRFL_CCODE, SROM5_CCODE, 0xffff}, + {"ccode", 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff}, + {"macaddr", 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff}, + {"macaddr", 0x000000e0, SRFL_ETHADDR, SROM5_MACHI, 0xffff}, + {"macaddr", 0x00000010, SRFL_ETHADDR, SROM4_MACHI, 0xffff}, + {"macaddr", 0x00000008, SRFL_ETHADDR, SROM3_MACHI, 0xffff}, + {"il0macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_IL0, 0xffff}, + {"et1macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_ET1, 0xffff}, + {"leddc", 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC, 0xffff}, + {"leddc", 0x000000e0, SRFL_NOFFS | SRFL_LEDDC, SROM5_LEDDC, 0xffff}, + {"leddc", 0x00000010, SRFL_NOFFS | SRFL_LEDDC, SROM4_LEDDC, 0xffff}, + {"leddc", 0x00000008, SRFL_NOFFS | SRFL_LEDDC, SROM3_LEDDC, 0xffff}, + {"rawtempsense", 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0x01ff}, + {"measpower", 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0xfe00}, + {"tempsense_slope", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, + 0x00ff}, + {"tempcorrx", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0xfc00}, + {"tempsense_option", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, + 0x0300}, + {"freqoffset_corr", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, + 0x000f}, + {"iqcal_swp_dis", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0010}, + {"hw_iqcal_en", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0020}, + {"phycal_tempdelta", 0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA, 0x00ff}, + + {"cck2gpo", 0x000000f0, 0, SROM4_2G_CCKPO, 0xffff}, + {"cck2gpo", 0x00000100, 0, SROM8_2G_CCKPO, 0xffff}, + {"ofdm2gpo", 0x000000f0, SRFL_MORE, SROM4_2G_OFDMPO, 0xffff}, + {"", 0, 0, SROM4_2G_OFDMPO + 1, 0xffff}, + {"ofdm5gpo", 0x000000f0, SRFL_MORE, SROM4_5G_OFDMPO, 0xffff}, + {"", 0, 0, SROM4_5G_OFDMPO + 1, 0xffff}, + {"ofdm5glpo", 0x000000f0, SRFL_MORE, SROM4_5GL_OFDMPO, 0xffff}, + {"", 0, 0, SROM4_5GL_OFDMPO + 1, 0xffff}, + {"ofdm5ghpo", 0x000000f0, SRFL_MORE, SROM4_5GH_OFDMPO, 0xffff}, + {"", 0, 0, SROM4_5GH_OFDMPO + 1, 0xffff}, + {"ofdm2gpo", 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff}, + {"", 0, 0, SROM8_2G_OFDMPO + 1, 0xffff}, + {"ofdm5gpo", 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff}, + {"", 0, 0, SROM8_5G_OFDMPO + 1, 0xffff}, + {"ofdm5glpo", 0x00000100, SRFL_MORE, SROM8_5GL_OFDMPO, 0xffff}, + {"", 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff}, + {"ofdm5ghpo", 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff}, + {"", 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff}, + {"mcs2gpo0", 0x000000f0, 0, SROM4_2G_MCSPO, 0xffff}, + {"mcs2gpo1", 0x000000f0, 0, SROM4_2G_MCSPO + 1, 0xffff}, + {"mcs2gpo2", 0x000000f0, 0, SROM4_2G_MCSPO + 2, 0xffff}, + {"mcs2gpo3", 0x000000f0, 0, SROM4_2G_MCSPO + 3, 0xffff}, + {"mcs2gpo4", 0x000000f0, 0, SROM4_2G_MCSPO + 4, 0xffff}, + {"mcs2gpo5", 0x000000f0, 0, SROM4_2G_MCSPO + 5, 0xffff}, + {"mcs2gpo6", 0x000000f0, 0, SROM4_2G_MCSPO + 6, 0xffff}, + {"mcs2gpo7", 0x000000f0, 0, SROM4_2G_MCSPO + 7, 0xffff}, + {"mcs5gpo0", 0x000000f0, 0, SROM4_5G_MCSPO, 0xffff}, + {"mcs5gpo1", 0x000000f0, 0, SROM4_5G_MCSPO + 1, 0xffff}, + {"mcs5gpo2", 0x000000f0, 0, SROM4_5G_MCSPO + 2, 0xffff}, + {"mcs5gpo3", 0x000000f0, 0, SROM4_5G_MCSPO + 3, 0xffff}, + {"mcs5gpo4", 0x000000f0, 0, SROM4_5G_MCSPO + 4, 0xffff}, + {"mcs5gpo5", 0x000000f0, 0, SROM4_5G_MCSPO + 5, 0xffff}, + {"mcs5gpo6", 0x000000f0, 0, SROM4_5G_MCSPO + 6, 0xffff}, + {"mcs5gpo7", 0x000000f0, 0, SROM4_5G_MCSPO + 7, 0xffff}, + {"mcs5glpo0", 0x000000f0, 0, SROM4_5GL_MCSPO, 0xffff}, + {"mcs5glpo1", 0x000000f0, 0, SROM4_5GL_MCSPO + 1, 0xffff}, + {"mcs5glpo2", 0x000000f0, 0, SROM4_5GL_MCSPO + 2, 0xffff}, + {"mcs5glpo3", 0x000000f0, 0, SROM4_5GL_MCSPO + 3, 0xffff}, + {"mcs5glpo4", 0x000000f0, 0, SROM4_5GL_MCSPO + 4, 0xffff}, + {"mcs5glpo5", 0x000000f0, 0, SROM4_5GL_MCSPO + 5, 0xffff}, + {"mcs5glpo6", 0x000000f0, 0, SROM4_5GL_MCSPO + 6, 0xffff}, + {"mcs5glpo7", 0x000000f0, 0, SROM4_5GL_MCSPO + 7, 0xffff}, + {"mcs5ghpo0", 0x000000f0, 0, SROM4_5GH_MCSPO, 0xffff}, + {"mcs5ghpo1", 0x000000f0, 0, SROM4_5GH_MCSPO + 1, 0xffff}, + {"mcs5ghpo2", 0x000000f0, 0, SROM4_5GH_MCSPO + 2, 0xffff}, + {"mcs5ghpo3", 0x000000f0, 0, SROM4_5GH_MCSPO + 3, 0xffff}, + {"mcs5ghpo4", 0x000000f0, 0, SROM4_5GH_MCSPO + 4, 0xffff}, + {"mcs5ghpo5", 0x000000f0, 0, SROM4_5GH_MCSPO + 5, 0xffff}, + {"mcs5ghpo6", 0x000000f0, 0, SROM4_5GH_MCSPO + 6, 0xffff}, + {"mcs5ghpo7", 0x000000f0, 0, SROM4_5GH_MCSPO + 7, 0xffff}, + {"mcs2gpo0", 0x00000100, 0, SROM8_2G_MCSPO, 0xffff}, + {"mcs2gpo1", 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff}, + {"mcs2gpo2", 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff}, + {"mcs2gpo3", 0x00000100, 0, SROM8_2G_MCSPO + 3, 0xffff}, + {"mcs2gpo4", 0x00000100, 0, SROM8_2G_MCSPO + 4, 0xffff}, + {"mcs2gpo5", 0x00000100, 0, SROM8_2G_MCSPO + 5, 0xffff}, + {"mcs2gpo6", 0x00000100, 0, SROM8_2G_MCSPO + 6, 0xffff}, + {"mcs2gpo7", 0x00000100, 0, SROM8_2G_MCSPO + 7, 0xffff}, + {"mcs5gpo0", 0x00000100, 0, SROM8_5G_MCSPO, 0xffff}, + {"mcs5gpo1", 0x00000100, 0, SROM8_5G_MCSPO + 1, 0xffff}, + {"mcs5gpo2", 0x00000100, 0, SROM8_5G_MCSPO + 2, 0xffff}, + {"mcs5gpo3", 0x00000100, 0, SROM8_5G_MCSPO + 3, 0xffff}, + {"mcs5gpo4", 0x00000100, 0, SROM8_5G_MCSPO + 4, 0xffff}, + {"mcs5gpo5", 0x00000100, 0, SROM8_5G_MCSPO + 5, 0xffff}, + {"mcs5gpo6", 0x00000100, 0, SROM8_5G_MCSPO + 6, 0xffff}, + {"mcs5gpo7", 0x00000100, 0, SROM8_5G_MCSPO + 7, 0xffff}, + {"mcs5glpo0", 0x00000100, 0, SROM8_5GL_MCSPO, 0xffff}, + {"mcs5glpo1", 0x00000100, 0, SROM8_5GL_MCSPO + 1, 0xffff}, + {"mcs5glpo2", 0x00000100, 0, SROM8_5GL_MCSPO + 2, 0xffff}, + {"mcs5glpo3", 0x00000100, 0, SROM8_5GL_MCSPO + 3, 0xffff}, + {"mcs5glpo4", 0x00000100, 0, SROM8_5GL_MCSPO + 4, 0xffff}, + {"mcs5glpo5", 0x00000100, 0, SROM8_5GL_MCSPO + 5, 0xffff}, + {"mcs5glpo6", 0x00000100, 0, SROM8_5GL_MCSPO + 6, 0xffff}, + {"mcs5glpo7", 0x00000100, 0, SROM8_5GL_MCSPO + 7, 0xffff}, + {"mcs5ghpo0", 0x00000100, 0, SROM8_5GH_MCSPO, 0xffff}, + {"mcs5ghpo1", 0x00000100, 0, SROM8_5GH_MCSPO + 1, 0xffff}, + {"mcs5ghpo2", 0x00000100, 0, SROM8_5GH_MCSPO + 2, 0xffff}, + {"mcs5ghpo3", 0x00000100, 0, SROM8_5GH_MCSPO + 3, 0xffff}, + {"mcs5ghpo4", 0x00000100, 0, SROM8_5GH_MCSPO + 4, 0xffff}, + {"mcs5ghpo5", 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff}, + {"mcs5ghpo6", 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff}, + {"mcs5ghpo7", 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff}, + {"cddpo", 0x000000f0, 0, SROM4_CDDPO, 0xffff}, + {"stbcpo", 0x000000f0, 0, SROM4_STBCPO, 0xffff}, + {"bw40po", 0x000000f0, 0, SROM4_BW40PO, 0xffff}, + {"bwduppo", 0x000000f0, 0, SROM4_BWDUPPO, 0xffff}, + {"cddpo", 0x00000100, 0, SROM8_CDDPO, 0xffff}, + {"stbcpo", 0x00000100, 0, SROM8_STBCPO, 0xffff}, + {"bw40po", 0x00000100, 0, SROM8_BW40PO, 0xffff}, + {"bwduppo", 0x00000100, 0, SROM8_BWDUPPO, 0xffff}, + + /* power per rate from sromrev 9 */ + {"cckbw202gpo", 0xfffffe00, 0, SROM9_2GPO_CCKBW20, 0xffff}, + {"cckbw20ul2gpo", 0xfffffe00, 0, SROM9_2GPO_CCKBW20UL, 0xffff}, + {"legofdmbw202gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_LOFDMBW20, + 0xffff}, + {"", 0, 0, SROM9_2GPO_LOFDMBW20 + 1, 0xffff}, + {"legofdmbw20ul2gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_LOFDMBW20UL, + 0xffff}, + {"", 0, 0, SROM9_2GPO_LOFDMBW20UL + 1, 0xffff}, + {"legofdmbw205glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_LOFDMBW20, + 0xffff}, + {"", 0, 0, SROM9_5GLPO_LOFDMBW20 + 1, 0xffff}, + {"legofdmbw20ul5glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_LOFDMBW20UL, + 0xffff}, + {"", 0, 0, SROM9_5GLPO_LOFDMBW20UL + 1, 0xffff}, + {"legofdmbw205gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_LOFDMBW20, + 0xffff}, + {"", 0, 0, SROM9_5GMPO_LOFDMBW20 + 1, 0xffff}, + {"legofdmbw20ul5gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_LOFDMBW20UL, + 0xffff}, + {"", 0, 0, SROM9_5GMPO_LOFDMBW20UL + 1, 0xffff}, + {"legofdmbw205ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_LOFDMBW20, + 0xffff}, + {"", 0, 0, SROM9_5GHPO_LOFDMBW20 + 1, 0xffff}, + {"legofdmbw20ul5ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_LOFDMBW20UL, + 0xffff}, + {"", 0, 0, SROM9_5GHPO_LOFDMBW20UL + 1, 0xffff}, + {"mcsbw202gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20, 0xffff}, + {"", 0, 0, SROM9_2GPO_MCSBW20 + 1, 0xffff}, + {"mcsbw20ul2gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20UL, 0xffff}, + {"", 0, 0, SROM9_2GPO_MCSBW20UL + 1, 0xffff}, + {"mcsbw402gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW40, 0xffff}, + {"", 0, 0, SROM9_2GPO_MCSBW40 + 1, 0xffff}, + {"mcsbw205glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20, 0xffff}, + {"", 0, 0, SROM9_5GLPO_MCSBW20 + 1, 0xffff}, + {"mcsbw20ul5glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20UL, + 0xffff}, + {"", 0, 0, SROM9_5GLPO_MCSBW20UL + 1, 0xffff}, + {"mcsbw405glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW40, 0xffff}, + {"", 0, 0, SROM9_5GLPO_MCSBW40 + 1, 0xffff}, + {"mcsbw205gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20, 0xffff}, + {"", 0, 0, SROM9_5GMPO_MCSBW20 + 1, 0xffff}, + {"mcsbw20ul5gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20UL, + 0xffff}, + {"", 0, 0, SROM9_5GMPO_MCSBW20UL + 1, 0xffff}, + {"mcsbw405gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW40, 0xffff}, + {"", 0, 0, SROM9_5GMPO_MCSBW40 + 1, 0xffff}, + {"mcsbw205ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20, 0xffff}, + {"", 0, 0, SROM9_5GHPO_MCSBW20 + 1, 0xffff}, + {"mcsbw20ul5ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20UL, + 0xffff}, + {"", 0, 0, SROM9_5GHPO_MCSBW20UL + 1, 0xffff}, + {"mcsbw405ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW40, 0xffff}, + {"", 0, 0, SROM9_5GHPO_MCSBW40 + 1, 0xffff}, + {"mcs32po", 0xfffffe00, 0, SROM9_PO_MCS32, 0xffff}, + {"legofdm40duppo", 0xfffffe00, 0, SROM9_PO_LOFDM40DUP, 0xffff}, + + {NULL, 0, 0, 0, 0} +}; + +static const sromvar_t perpath_pci_sromvars[] = { + {"maxp2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0x00ff}, + {"itt2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff00}, + {"itt5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff00}, + {"pa2gw0a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA, 0xffff}, + {"pa2gw1a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 1, 0xffff}, + {"pa2gw2a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 2, 0xffff}, + {"pa2gw3a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 3, 0xffff}, + {"maxp5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0x00ff}, + {"maxp5gha", 0x000000f0, 0, SROM4_5GLH_MAXP, 0x00ff}, + {"maxp5gla", 0x000000f0, 0, SROM4_5GLH_MAXP, 0xff00}, + {"pa5gw0a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA, 0xffff}, + {"pa5gw1a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 1, 0xffff}, + {"pa5gw2a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 2, 0xffff}, + {"pa5gw3a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 3, 0xffff}, + {"pa5glw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA, 0xffff}, + {"pa5glw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 1, 0xffff}, + {"pa5glw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 2, 0xffff}, + {"pa5glw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 3, 0xffff}, + {"pa5ghw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA, 0xffff}, + {"pa5ghw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 1, 0xffff}, + {"pa5ghw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 2, 0xffff}, + {"pa5ghw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 3, 0xffff}, + {"maxp2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff}, + {"itt2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00}, + {"itt5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00}, + {"pa2gw0a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA, 0xffff}, + {"pa2gw1a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 1, 0xffff}, + {"pa2gw2a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 2, 0xffff}, + {"maxp5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0x00ff}, + {"maxp5gha", 0xffffff00, 0, SROM8_5GLH_MAXP, 0x00ff}, + {"maxp5gla", 0xffffff00, 0, SROM8_5GLH_MAXP, 0xff00}, + {"pa5gw0a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA, 0xffff}, + {"pa5gw1a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 1, 0xffff}, + {"pa5gw2a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 2, 0xffff}, + {"pa5glw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA, 0xffff}, + {"pa5glw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 1, 0xffff}, + {"pa5glw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 2, 0xffff}, + {"pa5ghw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA, 0xffff}, + {"pa5ghw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 1, 0xffff}, + {"pa5ghw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 2, 0xffff}, + {NULL, 0, 0, 0, 0} +}; + +#if !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP)) +#define PHY_TYPE_N 4 /* N-Phy value */ +#define PHY_TYPE_LP 5 /* LP-Phy value */ +#endif /* !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP)) */ +#if !defined(PHY_TYPE_NULL) +#define PHY_TYPE_NULL 0xf /* Invalid Phy value */ +#endif /* !defined(PHY_TYPE_NULL) */ + +typedef struct { + u16 phy_type; + u16 bandrange; + u16 chain; + const char *vars; +} pavars_t; + +static const pavars_t pavars[] = { + /* NPHY */ + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 0, "pa2gw0a0 pa2gw1a0 pa2gw2a0"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 1, "pa2gw0a1 pa2gw1a1 pa2gw2a1"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 0, + "pa5glw0a0 pa5glw1a0 pa5glw2a0"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 1, + "pa5glw0a1 pa5glw1a1 pa5glw2a1"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 0, "pa5gw0a0 pa5gw1a0 pa5gw2a0"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 1, "pa5gw0a1 pa5gw1a1 pa5gw2a1"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 0, + "pa5ghw0a0 pa5ghw1a0 pa5ghw2a0"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 1, + "pa5ghw0a1 pa5ghw1a1 pa5ghw2a1"}, + /* LPPHY */ + {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_2G, 0, "pa0b0 pa0b1 pa0b2"}, + {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GL, 0, "pa1lob0 pa1lob1 pa1lob2"}, + {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GM, 0, "pa1b0 pa1b1 pa1b2"}, + {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GH, 0, "pa1hib0 pa1hib1 pa1hib2"}, + {PHY_TYPE_NULL, 0, 0, ""} +}; + +typedef struct { + u16 phy_type; + u16 bandrange; + const char *vars; +} povars_t; + +static const povars_t povars[] = { + /* NPHY */ + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, + "mcs2gpo0 mcs2gpo1 mcs2gpo2 mcs2gpo3 " + "mcs2gpo4 mcs2gpo5 mcs2gpo6 mcs2gpo7"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, + "mcs5glpo0 mcs5glpo1 mcs5glpo2 mcs5glpo3 " + "mcs5glpo4 mcs5glpo5 mcs5glpo6 mcs5glpo7"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, + "mcs5gpo0 mcs5gpo1 mcs5gpo2 mcs5gpo3 " + "mcs5gpo4 mcs5gpo5 mcs5gpo6 mcs5gpo7"}, + {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, + "mcs5ghpo0 mcs5ghpo1 mcs5ghpo2 mcs5ghpo3 " + "mcs5ghpo4 mcs5ghpo5 mcs5ghpo6 mcs5ghpo7"}, + {PHY_TYPE_NULL, 0, ""} +}; + +typedef struct { + u8 tag; /* Broadcom subtag name */ + u8 len; /* Length field of the tuple, note that it includes the + * subtag name (1 byte): 1 + tuple content length + */ + const char *params; +} cis_tuple_t; + +#define OTP_RAW (0xff - 1) /* Reserved tuple number for wrvar Raw input */ +#define OTP_VERS_1 (0xff - 2) /* CISTPL_VERS_1 */ +#define OTP_MANFID (0xff - 3) /* CISTPL_MANFID */ +#define OTP_RAW1 (0xff - 4) /* Like RAW, but comes first */ + +static const cis_tuple_t cis_hnbuvars[] = { + {OTP_RAW1, 0, ""}, /* special case */ + {OTP_VERS_1, 0, "smanf sproductname"}, /* special case (non BRCM tuple) */ + {OTP_MANFID, 4, "2manfid 2prodid"}, /* special case (non BRCM tuple) */ + {HNBU_SROMREV, 2, "1sromrev"}, + /* NOTE: subdevid is also written to boardtype. + * Need to write HNBU_BOARDTYPE to change it if it is different. + */ + {HNBU_CHIPID, 11, "2vendid 2devid 2chiprev 2subvendid 2subdevid"}, + {HNBU_BOARDREV, 3, "2boardrev"}, + {HNBU_PAPARMS, 10, "2pa0b0 2pa0b1 2pa0b2 1pa0itssit 1pa0maxpwr 1opo"}, + {HNBU_AA, 3, "1aa2g 1aa5g"}, + {HNBU_AA, 3, "1aa0 1aa1"}, /* backward compatibility */ + {HNBU_AG, 5, "1ag0 1ag1 1ag2 1ag3"}, + {HNBU_BOARDFLAGS, 9, "4boardflags 4boardflags2"}, + {HNBU_LEDS, 5, "1ledbh0 1ledbh1 1ledbh2 1ledbh3"}, + {HNBU_CCODE, 4, "2ccode 1cctl"}, + {HNBU_CCKPO, 3, "2cckpo"}, + {HNBU_OFDMPO, 5, "4ofdmpo"}, + {HNBU_RDLID, 3, "2rdlid"}, + {HNBU_RSSISMBXA2G, 3, "0rssismf2g 0rssismc2g 0rssisav2g 0bxa2g"}, /* special case */ + {HNBU_RSSISMBXA5G, 3, "0rssismf5g 0rssismc5g 0rssisav5g 0bxa5g"}, /* special case */ + {HNBU_XTALFREQ, 5, "4xtalfreq"}, + {HNBU_TRI2G, 2, "1tri2g"}, + {HNBU_TRI5G, 4, "1tri5gl 1tri5g 1tri5gh"}, + {HNBU_RXPO2G, 2, "1rxpo2g"}, + {HNBU_RXPO5G, 2, "1rxpo5g"}, + {HNBU_BOARDNUM, 3, "2boardnum"}, + {HNBU_MACADDR, 7, "6macaddr"}, /* special case */ + {HNBU_RDLSN, 3, "2rdlsn"}, + {HNBU_BOARDTYPE, 3, "2boardtype"}, + {HNBU_LEDDC, 3, "2leddc"}, + {HNBU_RDLRNDIS, 2, "1rdlndis"}, + {HNBU_CHAINSWITCH, 5, "1txchain 1rxchain 2antswitch"}, + {HNBU_REGREV, 2, "1regrev"}, + {HNBU_FEM, 5, "0antswctl2g, 0triso2g, 0pdetrange2g, 0extpagain2g, 0tssipos2g" "0antswctl5g, 0triso5g, 0pdetrange5g, 0extpagain5g, 0tssipos5g"}, /* special case */ + {HNBU_PAPARMS_C0, 31, "1maxp2ga0 1itt2ga0 2pa2gw0a0 2pa2gw1a0 " + "2pa2gw2a0 1maxp5ga0 1itt5ga0 1maxp5gha0 1maxp5gla0 2pa5gw0a0 " + "2pa5gw1a0 2pa5gw2a0 2pa5glw0a0 2pa5glw1a0 2pa5glw2a0 2pa5ghw0a0 " + "2pa5ghw1a0 2pa5ghw2a0"}, + {HNBU_PAPARMS_C1, 31, "1maxp2ga1 1itt2ga1 2pa2gw0a1 2pa2gw1a1 " + "2pa2gw2a1 1maxp5ga1 1itt5ga1 1maxp5gha1 1maxp5gla1 2pa5gw0a1 " + "2pa5gw1a1 2pa5gw2a1 2pa5glw0a1 2pa5glw1a1 2pa5glw2a1 2pa5ghw0a1 " + "2pa5ghw1a1 2pa5ghw2a1"}, + {HNBU_PO_CCKOFDM, 19, "2cck2gpo 4ofdm2gpo 4ofdm5gpo 4ofdm5glpo " + "4ofdm5ghpo"}, + {HNBU_PO_MCS2G, 17, "2mcs2gpo0 2mcs2gpo1 2mcs2gpo2 2mcs2gpo3 " + "2mcs2gpo4 2mcs2gpo5 2mcs2gpo6 2mcs2gpo7"}, + {HNBU_PO_MCS5GM, 17, "2mcs5gpo0 2mcs5gpo1 2mcs5gpo2 2mcs5gpo3 " + "2mcs5gpo4 2mcs5gpo5 2mcs5gpo6 2mcs5gpo7"}, + {HNBU_PO_MCS5GLH, 33, "2mcs5glpo0 2mcs5glpo1 2mcs5glpo2 2mcs5glpo3 " + "2mcs5glpo4 2mcs5glpo5 2mcs5glpo6 2mcs5glpo7 " + "2mcs5ghpo0 2mcs5ghpo1 2mcs5ghpo2 2mcs5ghpo3 " + "2mcs5ghpo4 2mcs5ghpo5 2mcs5ghpo6 2mcs5ghpo7"}, + {HNBU_CCKFILTTYPE, 2, "1cckdigfilttype"}, + {HNBU_PO_CDD, 3, "2cddpo"}, + {HNBU_PO_STBC, 3, "2stbcpo"}, + {HNBU_PO_40M, 3, "2bw40po"}, + {HNBU_PO_40MDUP, 3, "2bwduppo"}, + {HNBU_RDLRWU, 2, "1rdlrwu"}, + {HNBU_WPS, 3, "1wpsgpio 1wpsled"}, + {HNBU_USBFS, 2, "1usbfs"}, + {HNBU_CUSTOM1, 5, "4customvar1"}, + {OTP_RAW, 0, ""}, /* special case */ + {HNBU_OFDMPO5G, 13, "4ofdm5gpo 4ofdm5glpo 4ofdm5ghpo"}, + {HNBU_USBEPNUM, 3, "2usbepnum"}, + {0xFF, 0, ""} +}; + +#endif /* _bcmsrom_tbl_h_ */ diff --git a/drivers/staging/brcm80211/util/pci_core.h b/drivers/staging/brcm80211/util/pci_core.h new file mode 100644 index 000000000000..9153dcb8160e --- /dev/null +++ b/drivers/staging/brcm80211/util/pci_core.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _PCI_CORE_H_ +#define _PCI_CORE_H_ + +#ifndef _LANGUAGE_ASSEMBLY + +/* cpp contortions to concatenate w/arg prescan */ +#ifndef PAD +#define _PADLINE(line) pad ## line +#define _XSTR(line) _PADLINE(line) +#define PAD _XSTR(__LINE__) +#endif + +/* Sonics side: PCI core and host control registers */ +struct sbpciregs { + u32 control; /* PCI control */ + u32 PAD[3]; + u32 arbcontrol; /* PCI arbiter control */ + u32 clkrun; /* Clkrun Control (>=rev11) */ + u32 PAD[2]; + u32 intstatus; /* Interrupt status */ + u32 intmask; /* Interrupt mask */ + u32 sbtopcimailbox; /* Sonics to PCI mailbox */ + u32 PAD[9]; + u32 bcastaddr; /* Sonics broadcast address */ + u32 bcastdata; /* Sonics broadcast data */ + u32 PAD[2]; + u32 gpioin; /* ro: gpio input (>=rev2) */ + u32 gpioout; /* rw: gpio output (>=rev2) */ + u32 gpioouten; /* rw: gpio output enable (>= rev2) */ + u32 gpiocontrol; /* rw: gpio control (>= rev2) */ + u32 PAD[36]; + u32 sbtopci0; /* Sonics to PCI translation 0 */ + u32 sbtopci1; /* Sonics to PCI translation 1 */ + u32 sbtopci2; /* Sonics to PCI translation 2 */ + u32 PAD[189]; + u32 pcicfg[4][64]; /* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */ + u16 sprom[36]; /* SPROM shadow Area */ + u32 PAD[46]; +}; + +#endif /* _LANGUAGE_ASSEMBLY */ + +/* PCI control */ +#define PCI_RST_OE 0x01 /* When set, drives PCI_RESET out to pin */ +#define PCI_RST 0x02 /* Value driven out to pin */ +#define PCI_CLK_OE 0x04 /* When set, drives clock as gated by PCI_CLK out to pin */ +#define PCI_CLK 0x08 /* Gate for clock driven out to pin */ + +/* PCI arbiter control */ +#define PCI_INT_ARB 0x01 /* When set, use an internal arbiter */ +#define PCI_EXT_ARB 0x02 /* When set, use an external arbiter */ +/* ParkID - for PCI corerev >= 8 */ +#define PCI_PARKID_MASK 0x1c /* Selects which agent is parked on an idle bus */ +#define PCI_PARKID_SHIFT 2 +#define PCI_PARKID_EXT0 0 /* External master 0 */ +#define PCI_PARKID_EXT1 1 /* External master 1 */ +#define PCI_PARKID_EXT2 2 /* External master 2 */ +#define PCI_PARKID_EXT3 3 /* External master 3 (rev >= 11) */ +#define PCI_PARKID_INT 3 /* Internal master (rev < 11) */ +#define PCI11_PARKID_INT 4 /* Internal master (rev >= 11) */ +#define PCI_PARKID_LAST 4 /* Last active master (rev < 11) */ +#define PCI11_PARKID_LAST 5 /* Last active master (rev >= 11) */ + +#define PCI_CLKRUN_DSBL 0x8000 /* Bit 15 forceClkrun */ + +/* Interrupt status/mask */ +#define PCI_INTA 0x01 /* PCI INTA# is asserted */ +#define PCI_INTB 0x02 /* PCI INTB# is asserted */ +#define PCI_SERR 0x04 /* PCI SERR# has been asserted (write one to clear) */ +#define PCI_PERR 0x08 /* PCI PERR# has been asserted (write one to clear) */ +#define PCI_PME 0x10 /* PCI PME# is asserted */ + +/* (General) PCI/SB mailbox interrupts, two bits per pci function */ +#define MAILBOX_F0_0 0x100 /* function 0, int 0 */ +#define MAILBOX_F0_1 0x200 /* function 0, int 1 */ +#define MAILBOX_F1_0 0x400 /* function 1, int 0 */ +#define MAILBOX_F1_1 0x800 /* function 1, int 1 */ +#define MAILBOX_F2_0 0x1000 /* function 2, int 0 */ +#define MAILBOX_F2_1 0x2000 /* function 2, int 1 */ +#define MAILBOX_F3_0 0x4000 /* function 3, int 0 */ +#define MAILBOX_F3_1 0x8000 /* function 3, int 1 */ + +/* Sonics broadcast address */ +#define BCAST_ADDR_MASK 0xff /* Broadcast register address */ + +/* Sonics to PCI translation types */ +#define SBTOPCI0_MASK 0xfc000000 +#define SBTOPCI1_MASK 0xfc000000 +#define SBTOPCI2_MASK 0xc0000000 +#define SBTOPCI_MEM 0 +#define SBTOPCI_IO 1 +#define SBTOPCI_CFG0 2 +#define SBTOPCI_CFG1 3 +#define SBTOPCI_PREF 0x4 /* prefetch enable */ +#define SBTOPCI_BURST 0x8 /* burst enable */ +#define SBTOPCI_RC_MASK 0x30 /* read command (>= rev11) */ +#define SBTOPCI_RC_READ 0x00 /* memory read */ +#define SBTOPCI_RC_READLINE 0x10 /* memory read line */ +#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */ + +/* PCI core index in SROM shadow area */ +#define SRSH_PI_OFFSET 0 /* first word */ +#define SRSH_PI_MASK 0xf000 /* bit 15:12 */ +#define SRSH_PI_SHIFT 12 /* bit 15:12 */ + +#endif /* _PCI_CORE_H_ */ diff --git a/drivers/staging/brcm80211/util/sbpcmcia.h b/drivers/staging/brcm80211/util/sbpcmcia.h new file mode 100644 index 000000000000..6b9923f551a9 --- /dev/null +++ b/drivers/staging/brcm80211/util/sbpcmcia.h @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _SBPCMCIA_H +#define _SBPCMCIA_H + +/* All the addresses that are offsets in attribute space are divided + * by two to account for the fact that odd bytes are invalid in + * attribute space and our read/write routines make the space appear + * as if they didn't exist. Still we want to show the original numbers + * as documented in the hnd_pcmcia core manual. + */ + +/* PCMCIA Function Configuration Registers */ +#define PCMCIA_FCR (0x700 / 2) + +#define FCR0_OFF 0 +#define FCR1_OFF (0x40 / 2) +#define FCR2_OFF (0x80 / 2) +#define FCR3_OFF (0xc0 / 2) + +#define PCMCIA_FCR0 (0x700 / 2) +#define PCMCIA_FCR1 (0x740 / 2) +#define PCMCIA_FCR2 (0x780 / 2) +#define PCMCIA_FCR3 (0x7c0 / 2) + +/* Standard PCMCIA FCR registers */ + +#define PCMCIA_COR 0 + +#define COR_RST 0x80 +#define COR_LEV 0x40 +#define COR_IRQEN 0x04 +#define COR_BLREN 0x01 +#define COR_FUNEN 0x01 + +#define PCICIA_FCSR (2 / 2) +#define PCICIA_PRR (4 / 2) +#define PCICIA_SCR (6 / 2) +#define PCICIA_ESR (8 / 2) + +#define PCM_MEMOFF 0x0000 +#define F0_MEMOFF 0x1000 +#define F1_MEMOFF 0x2000 +#define F2_MEMOFF 0x3000 +#define F3_MEMOFF 0x4000 + +/* Memory base in the function fcr's */ +#define MEM_ADDR0 (0x728 / 2) +#define MEM_ADDR1 (0x72a / 2) +#define MEM_ADDR2 (0x72c / 2) + +/* PCMCIA base plus Srom access in fcr0: */ +#define PCMCIA_ADDR0 (0x072e / 2) +#define PCMCIA_ADDR1 (0x0730 / 2) +#define PCMCIA_ADDR2 (0x0732 / 2) + +#define MEM_SEG (0x0734 / 2) +#define SROM_CS (0x0736 / 2) +#define SROM_DATAL (0x0738 / 2) +#define SROM_DATAH (0x073a / 2) +#define SROM_ADDRL (0x073c / 2) +#define SROM_ADDRH (0x073e / 2) +#define SROM_INFO2 (0x0772 / 2) /* Corerev >= 2 && <= 5 */ +#define SROM_INFO (0x07be / 2) /* Corerev >= 6 */ + +/* Values for srom_cs: */ +#define SROM_IDLE 0 +#define SROM_WRITE 1 +#define SROM_READ 2 +#define SROM_WEN 4 +#define SROM_WDS 7 +#define SROM_DONE 8 + +/* Fields in srom_info: */ +#define SRI_SZ_MASK 0x03 +#define SRI_BLANK 0x04 +#define SRI_OTP 0x80 + +#if !defined(ESTA_POSTMOGRIFY_REMOVAL) +/* CIS stuff */ + +/* The CIS stops where the FCRs start */ +#define CIS_SIZE PCMCIA_FCR + +/* CIS tuple length field max */ +#define CIS_TUPLE_LEN_MAX 0xff + +/* Standard tuples we know about */ + +#define CISTPL_NULL 0x00 +#define CISTPL_VERS_1 0x15 /* CIS ver, manf, dev & ver strings */ +#define CISTPL_MANFID 0x20 /* Manufacturer and device id */ +#define CISTPL_FUNCID 0x21 /* Function identification */ +#define CISTPL_FUNCE 0x22 /* Function extensions */ +#define CISTPL_CFTABLE 0x1b /* Config table entry */ +#define CISTPL_END 0xff /* End of the CIS tuple chain */ + +/* Function identifier provides context for the function extentions tuple */ +#define CISTPL_FID_SDIO 0x0c /* Extensions defined by SDIO spec */ + +/* Function extensions for LANs (assumed for extensions other than SDIO) */ +#define LAN_TECH 1 /* Technology type */ +#define LAN_SPEED 2 /* Raw bit rate */ +#define LAN_MEDIA 3 /* Transmission media */ +#define LAN_NID 4 /* Node identification (aka MAC addr) */ +#define LAN_CONN 5 /* Connector standard */ + +/* CFTable */ +#define CFTABLE_REGWIN_2K 0x08 /* 2k reg windows size */ +#define CFTABLE_REGWIN_4K 0x10 /* 4k reg windows size */ +#define CFTABLE_REGWIN_8K 0x20 /* 8k reg windows size */ + +/* Vendor unique tuples are 0x80-0x8f. Within Broadcom we'll + * take one for HNBU, and use "extensions" (a la FUNCE) within it. + */ + +#define CISTPL_BRCM_HNBU 0x80 + +/* Subtypes of BRCM_HNBU: */ + +#define HNBU_SROMREV 0x00 /* A byte with sromrev, 1 if not present */ +#define HNBU_CHIPID 0x01 /* Two 16bit values: PCI vendor & device id */ +#define HNBU_BOARDREV 0x02 /* One byte board revision */ +#define HNBU_PAPARMS 0x03 /* PA parameters: 8 (sromrev == 1) + * or 9 (sromrev > 1) bytes + */ +#define HNBU_OEM 0x04 /* Eight bytes OEM data (sromrev == 1) */ +#define HNBU_CC 0x05 /* Default country code (sromrev == 1) */ +#define HNBU_AA 0x06 /* Antennas available */ +#define HNBU_AG 0x07 /* Antenna gain */ +#define HNBU_BOARDFLAGS 0x08 /* board flags (2 or 4 bytes) */ +#define HNBU_LEDS 0x09 /* LED set */ +#define HNBU_CCODE 0x0a /* Country code (2 bytes ascii + 1 byte cctl) + * in rev 2 + */ +#define HNBU_CCKPO 0x0b /* 2 byte cck power offsets in rev 3 */ +#define HNBU_OFDMPO 0x0c /* 4 byte 11g ofdm power offsets in rev 3 */ +#define HNBU_GPIOTIMER 0x0d /* 2 bytes with on/off values in rev 3 */ +#define HNBU_PAPARMS5G 0x0e /* 5G PA params */ +#define HNBU_ANT5G 0x0f /* 4328 5G antennas available/gain */ +#define HNBU_RDLID 0x10 /* 2 byte USB remote downloader (RDL) product Id */ +#define HNBU_RSSISMBXA2G 0x11 /* 4328 2G RSSI mid pt sel & board switch arch, + * 2 bytes, rev 3. + */ +#define HNBU_RSSISMBXA5G 0x12 /* 4328 5G RSSI mid pt sel & board switch arch, + * 2 bytes, rev 3. + */ +#define HNBU_XTALFREQ 0x13 /* 4 byte Crystal frequency in kilohertz */ +#define HNBU_TRI2G 0x14 /* 4328 2G TR isolation, 1 byte */ +#define HNBU_TRI5G 0x15 /* 4328 5G TR isolation, 3 bytes */ +#define HNBU_RXPO2G 0x16 /* 4328 2G RX power offset, 1 byte */ +#define HNBU_RXPO5G 0x17 /* 4328 5G RX power offset, 1 byte */ +#define HNBU_BOARDNUM 0x18 /* board serial number, independent of mac addr */ +#define HNBU_MACADDR 0x19 /* mac addr override for the standard CIS LAN_NID */ +#define HNBU_RDLSN 0x1a /* 2 bytes; serial # advertised in USB descriptor */ +#define HNBU_BOARDTYPE 0x1b /* 2 bytes; boardtype */ +#define HNBU_LEDDC 0x1c /* 2 bytes; LED duty cycle */ +#define HNBU_HNBUCIS 0x1d /* what follows is proprietary HNBU CIS format */ +#define HNBU_PAPARMS_SSLPNPHY 0x1e /* SSLPNPHY PA params */ +#define HNBU_RSSISMBXA2G_SSLPNPHY 0x1f /* SSLPNPHY RSSI mid pt sel & board switch arch */ +#define HNBU_RDLRNDIS 0x20 /* 1 byte; 1 = RDL advertises RNDIS config */ +#define HNBU_CHAINSWITCH 0x21 /* 2 byte; txchain, rxchain */ +#define HNBU_REGREV 0x22 /* 1 byte; */ +#define HNBU_FEM 0x23 /* 2 or 4 byte: 11n frontend specification */ +#define HNBU_PAPARMS_C0 0x24 /* 8 or 30 bytes: 11n pa paramater for chain 0 */ +#define HNBU_PAPARMS_C1 0x25 /* 8 or 30 bytes: 11n pa paramater for chain 1 */ +#define HNBU_PAPARMS_C2 0x26 /* 8 or 30 bytes: 11n pa paramater for chain 2 */ +#define HNBU_PAPARMS_C3 0x27 /* 8 or 30 bytes: 11n pa paramater for chain 3 */ +#define HNBU_PO_CCKOFDM 0x28 /* 6 or 18 bytes: cck2g/ofdm2g/ofdm5g power offset */ +#define HNBU_PO_MCS2G 0x29 /* 8 bytes: mcs2g power offset */ +#define HNBU_PO_MCS5GM 0x2a /* 8 bytes: mcs5g mid band power offset */ +#define HNBU_PO_MCS5GLH 0x2b /* 16 bytes: mcs5g low-high band power offset */ +#define HNBU_PO_CDD 0x2c /* 2 bytes: cdd2g/5g power offset */ +#define HNBU_PO_STBC 0x2d /* 2 bytes: stbc2g/5g power offset */ +#define HNBU_PO_40M 0x2e /* 2 bytes: 40Mhz channel 2g/5g power offset */ +#define HNBU_PO_40MDUP 0x2f /* 2 bytes: 40Mhz channel dup 2g/5g power offset */ + +#define HNBU_RDLRWU 0x30 /* 1 byte; 1 = RDL advertises Remote Wake-up */ +#define HNBU_WPS 0x31 /* 1 byte; GPIO pin for WPS button */ +#define HNBU_USBFS 0x32 /* 1 byte; 1 = USB advertises FS mode only */ +#define HNBU_BRMIN 0x33 /* 4 byte bootloader min resource mask */ +#define HNBU_BRMAX 0x34 /* 4 byte bootloader max resource mask */ +#define HNBU_PATCH 0x35 /* bootloader patch addr(2b) & data(4b) pair */ +#define HNBU_CCKFILTTYPE 0x36 /* CCK digital filter selection options */ +#define HNBU_OFDMPO5G 0x37 /* 4 * 3 = 12 byte 11a ofdm power offsets in rev 3 */ + +#define HNBU_USBEPNUM 0x40 /* USB endpoint numbers */ +#define HNBU_SROM3SWRGN 0x80 /* 78 bytes; srom rev 3 s/w region without crc8 + * plus extra info appended. + */ +#define HNBU_RESERVED 0x81 /* Reserved for non-BRCM post-mfg additions */ +#define HNBU_CUSTOM1 0x82 /* 4 byte; For non-BRCM post-mfg additions */ +#define HNBU_CUSTOM2 0x83 /* Reserved; For non-BRCM post-mfg additions */ +#endif /* !defined(ESTA_POSTMOGRIFY_REMOVAL) */ + +/* sbtmstatelow */ +#define SBTML_INT_ACK 0x40000 /* ack the sb interrupt */ +#define SBTML_INT_EN 0x20000 /* enable sb interrupt */ + +/* sbtmstatehigh */ +#define SBTMH_INT_STATUS 0x40000 /* sb interrupt status */ + +#endif /* _SBPCMCIA_H */ diff --git a/drivers/staging/brcm80211/util/sbsocram.h b/drivers/staging/brcm80211/util/sbsocram.h new file mode 100644 index 000000000000..0cfe9852b27f --- /dev/null +++ b/drivers/staging/brcm80211/util/sbsocram.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _SBSOCRAM_H +#define _SBSOCRAM_H + +#ifndef _LANGUAGE_ASSEMBLY + +/* cpp contortions to concatenate w/arg prescan */ +#ifndef PAD +#define _PADLINE(line) pad ## line +#define _XSTR(line) _PADLINE(line) +#define PAD _XSTR(__LINE__) +#endif /* PAD */ + +/* Memcsocram core registers */ +typedef volatile struct sbsocramregs { + u32 coreinfo; + u32 bwalloc; + u32 extracoreinfo; + u32 biststat; + u32 bankidx; + u32 standbyctrl; + + u32 errlogstatus; /* rev 6 */ + u32 errlogaddr; /* rev 6 */ + /* used for patching rev 3 & 5 */ + u32 cambankidx; + u32 cambankstandbyctrl; + u32 cambankpatchctrl; + u32 cambankpatchtblbaseaddr; + u32 cambankcmdreg; + u32 cambankdatareg; + u32 cambankmaskreg; + u32 PAD[1]; + u32 bankinfo; /* corev 8 */ + u32 PAD[15]; + u32 extmemconfig; + u32 extmemparitycsr; + u32 extmemparityerrdata; + u32 extmemparityerrcnt; + u32 extmemwrctrlandsize; + u32 PAD[84]; + u32 workaround; + u32 pwrctl; /* corerev >= 2 */ +} sbsocramregs_t; + +#endif /* _LANGUAGE_ASSEMBLY */ + +/* Register offsets */ +#define SR_COREINFO 0x00 +#define SR_BWALLOC 0x04 +#define SR_BISTSTAT 0x0c +#define SR_BANKINDEX 0x10 +#define SR_BANKSTBYCTL 0x14 +#define SR_PWRCTL 0x1e8 + +/* Coreinfo register */ +#define SRCI_PT_MASK 0x00070000 /* corerev >= 6; port type[18:16] */ +#define SRCI_PT_SHIFT 16 +/* port types : SRCI_PT__ */ +#define SRCI_PT_OCP_OCP 0 +#define SRCI_PT_AXI_OCP 1 +#define SRCI_PT_ARM7AHB_OCP 2 +#define SRCI_PT_CM3AHB_OCP 3 +#define SRCI_PT_AXI_AXI 4 +#define SRCI_PT_AHB_AXI 5 +/* corerev >= 3 */ +#define SRCI_LSS_MASK 0x00f00000 +#define SRCI_LSS_SHIFT 20 +#define SRCI_LRS_MASK 0x0f000000 +#define SRCI_LRS_SHIFT 24 + +/* In corerev 0, the memory size is 2 to the power of the + * base plus 16 plus to the contents of the memsize field plus 1. + */ +#define SRCI_MS0_MASK 0xf +#define SR_MS0_BASE 16 + +/* + * In corerev 1 the bank size is 2 ^ the bank size field plus 14, + * the memory size is number of banks times bank size. + * The same applies to rom size. + */ +#define SRCI_ROMNB_MASK 0xf000 +#define SRCI_ROMNB_SHIFT 12 +#define SRCI_ROMBSZ_MASK 0xf00 +#define SRCI_ROMBSZ_SHIFT 8 +#define SRCI_SRNB_MASK 0xf0 +#define SRCI_SRNB_SHIFT 4 +#define SRCI_SRBSZ_MASK 0xf +#define SRCI_SRBSZ_SHIFT 0 + +#define SR_BSZ_BASE 14 + +/* Standby control register */ +#define SRSC_SBYOVR_MASK 0x80000000 +#define SRSC_SBYOVR_SHIFT 31 +#define SRSC_SBYOVRVAL_MASK 0x60000000 +#define SRSC_SBYOVRVAL_SHIFT 29 +#define SRSC_SBYEN_MASK 0x01000000 /* rev >= 3 */ +#define SRSC_SBYEN_SHIFT 24 + +/* Power control register */ +#define SRPC_PMU_STBYDIS_MASK 0x00000010 /* rev >= 3 */ +#define SRPC_PMU_STBYDIS_SHIFT 4 +#define SRPC_STBYOVRVAL_MASK 0x00000008 +#define SRPC_STBYOVRVAL_SHIFT 3 +#define SRPC_STBYOVR_MASK 0x00000007 +#define SRPC_STBYOVR_SHIFT 0 + +/* Extra core capability register */ +#define SRECC_NUM_BANKS_MASK 0x000000F0 +#define SRECC_NUM_BANKS_SHIFT 4 +#define SRECC_BANKSIZE_MASK 0x0000000F +#define SRECC_BANKSIZE_SHIFT 0 + +#define SRECC_BANKSIZE(value) (1 << (value)) + +/* CAM bank patch control */ +#define SRCBPC_PATCHENABLE 0x80000000 + +#define SRP_ADDRESS 0x0001FFFC +#define SRP_VALID 0x8000 + +/* CAM bank command reg */ +#define SRCMD_WRITE 0x00020000 +#define SRCMD_READ 0x00010000 +#define SRCMD_DONE 0x80000000 + +#define SRCMD_DONE_DLY 1000 + +/* bankidx and bankinfo reg defines corerev >= 8 */ +#define SOCRAM_BANKINFO_SZMASK 0x3f +#define SOCRAM_BANKIDX_ROM_MASK 0x100 + +#define SOCRAM_BANKIDX_MEMTYPE_SHIFT 8 +/* socram bankinfo memtype */ +#define SOCRAM_MEMTYPE_RAM 0 +#define SOCRAM_MEMTYPE_R0M 1 +#define SOCRAM_MEMTYPE_DEVRAM 2 + +#define SOCRAM_BANKINFO_REG 0x40 +#define SOCRAM_BANKIDX_REG 0x10 +#define SOCRAM_BANKINFO_STDBY_MASK 0x400 +#define SOCRAM_BANKINFO_STDBY_TIMER 0x800 + +/* bankinfo rev >= 10 */ +#define SOCRAM_BANKINFO_DEVRAMSEL_SHIFT 13 +#define SOCRAM_BANKINFO_DEVRAMSEL_MASK 0x2000 +#define SOCRAM_BANKINFO_DEVRAMPRO_SHIFT 14 +#define SOCRAM_BANKINFO_DEVRAMPRO_MASK 0x4000 + +/* extracoreinfo register */ +#define SOCRAM_DEVRAMBANK_MASK 0xF000 +#define SOCRAM_DEVRAMBANK_SHIFT 12 + +/* bank info to calculate bank size */ +#define SOCRAM_BANKINFO_SZBASE 8192 +#define SOCRAM_BANKSIZE_SHIFT 13 /* SOCRAM_BANKINFO_SZBASE */ + +#endif /* _SBSOCRAM_H */ -- cgit v1.2.3 From d8941ea65ac3e0200e960957125be50f245d164c Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 21 Jan 2011 10:54:50 +0100 Subject: staging: brcm80211: removed sys directory layer from brcmsmac driver Based on review comments moved sources from brcm80211/brcmsmac/sys to its parent directory. The phy directory is kept for maintainance logistics around phy source code. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/Makefile | 3 + drivers/staging/brcm80211/brcmfmac/Makefile | 2 - drivers/staging/brcm80211/brcmsmac/Makefile | 28 +- drivers/staging/brcm80211/brcmsmac/d11ucode_ext.h | 35 + .../staging/brcm80211/brcmsmac/sys/d11ucode_ext.h | 35 - drivers/staging/brcm80211/brcmsmac/sys/wl_dbg.h | 102 - drivers/staging/brcm80211/brcmsmac/sys/wl_export.h | 63 - .../staging/brcm80211/brcmsmac/sys/wl_mac80211.c | 1846 ----- .../staging/brcm80211/brcmsmac/sys/wl_mac80211.h | 117 - drivers/staging/brcm80211/brcmsmac/sys/wl_ucode.h | 49 - .../brcm80211/brcmsmac/sys/wl_ucode_loader.c | 89 - drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.c | 371 - drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.h | 25 - drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.c | 1356 ---- drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.h | 36 - .../staging/brcm80211/brcmsmac/sys/wlc_antsel.c | 329 - .../staging/brcm80211/brcmsmac/sys/wlc_antsel.h | 30 - drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.c | 4235 ---------- drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.h | 273 - .../staging/brcm80211/brcmsmac/sys/wlc_bsscfg.h | 153 - drivers/staging/brcm80211/brcmsmac/sys/wlc_cfg.h | 286 - .../staging/brcm80211/brcmsmac/sys/wlc_channel.c | 1609 ---- .../staging/brcm80211/brcmsmac/sys/wlc_channel.h | 159 - drivers/staging/brcm80211/brcmsmac/sys/wlc_event.c | 229 - drivers/staging/brcm80211/brcmsmac/sys/wlc_event.h | 52 - drivers/staging/brcm80211/brcmsmac/sys/wlc_key.h | 144 - .../staging/brcm80211/brcmsmac/sys/wlc_mac80211.c | 8479 -------------------- .../staging/brcm80211/brcmsmac/sys/wlc_mac80211.h | 989 --- .../staging/brcm80211/brcmsmac/sys/wlc_phy_shim.c | 247 - .../staging/brcm80211/brcmsmac/sys/wlc_phy_shim.h | 112 - drivers/staging/brcm80211/brcmsmac/sys/wlc_pub.h | 624 -- drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.c | 501 -- drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.h | 170 - drivers/staging/brcm80211/brcmsmac/sys/wlc_scb.h | 84 - drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.c | 600 -- drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.h | 43 - drivers/staging/brcm80211/brcmsmac/sys/wlc_types.h | 37 - drivers/staging/brcm80211/brcmsmac/wl_dbg.h | 102 + drivers/staging/brcm80211/brcmsmac/wl_export.h | 63 + drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 1846 +++++ drivers/staging/brcm80211/brcmsmac/wl_mac80211.h | 117 + drivers/staging/brcm80211/brcmsmac/wl_ucode.h | 49 + .../staging/brcm80211/brcmsmac/wl_ucode_loader.c | 89 + drivers/staging/brcm80211/brcmsmac/wlc_alloc.c | 371 + drivers/staging/brcm80211/brcmsmac/wlc_alloc.h | 25 + drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 1356 ++++ drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h | 36 + drivers/staging/brcm80211/brcmsmac/wlc_antsel.c | 329 + drivers/staging/brcm80211/brcmsmac/wlc_antsel.h | 30 + drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 4235 ++++++++++ drivers/staging/brcm80211/brcmsmac/wlc_bmac.h | 273 + drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h | 153 + drivers/staging/brcm80211/brcmsmac/wlc_cfg.h | 286 + drivers/staging/brcm80211/brcmsmac/wlc_channel.c | 1609 ++++ drivers/staging/brcm80211/brcmsmac/wlc_channel.h | 159 + drivers/staging/brcm80211/brcmsmac/wlc_event.c | 229 + drivers/staging/brcm80211/brcmsmac/wlc_event.h | 52 + drivers/staging/brcm80211/brcmsmac/wlc_key.h | 144 + drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 8479 ++++++++++++++++++++ drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h | 989 +++ drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c | 247 + drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h | 112 + drivers/staging/brcm80211/brcmsmac/wlc_pub.h | 624 ++ drivers/staging/brcm80211/brcmsmac/wlc_rate.c | 501 ++ drivers/staging/brcm80211/brcmsmac/wlc_rate.h | 170 + drivers/staging/brcm80211/brcmsmac/wlc_scb.h | 84 + drivers/staging/brcm80211/brcmsmac/wlc_stf.c | 600 ++ drivers/staging/brcm80211/brcmsmac/wlc_stf.h | 43 + drivers/staging/brcm80211/brcmsmac/wlc_types.h | 37 + 69 files changed, 23490 insertions(+), 23491 deletions(-) create mode 100644 drivers/staging/brcm80211/brcmsmac/d11ucode_ext.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/d11ucode_ext.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wl_dbg.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wl_export.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wl_mac80211.c delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wl_mac80211.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wl_ucode.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wl_ucode_loader.c delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.c delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.c delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_antsel.c delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_antsel.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.c delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_bsscfg.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_cfg.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_channel.c delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_channel.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_event.c delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_event.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_key.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_mac80211.c delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_mac80211.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_phy_shim.c delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_phy_shim.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_pub.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.c delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_scb.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.c delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.h delete mode 100644 drivers/staging/brcm80211/brcmsmac/sys/wlc_types.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wl_dbg.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wl_export.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wl_mac80211.c create mode 100644 drivers/staging/brcm80211/brcmsmac/wl_mac80211.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wl_ucode.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_alloc.c create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_alloc.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_antsel.c create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_antsel.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_bmac.c create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_bmac.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_cfg.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_channel.c create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_channel.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_event.c create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_event.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_key.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_pub.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_rate.c create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_rate.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_scb.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_stf.c create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_stf.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_types.h (limited to 'drivers') diff --git a/drivers/staging/brcm80211/Makefile b/drivers/staging/brcm80211/Makefile index a0695195614f..5caaea597d50 100644 --- a/drivers/staging/brcm80211/Makefile +++ b/drivers/staging/brcm80211/Makefile @@ -15,5 +15,8 @@ # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# one and only common flag +subdir-ccflags-y := -DBCMDBG + obj-$(CONFIG_BRCMFMAC) += brcmfmac/ obj-$(CONFIG_BRCMSMAC) += brcmsmac/ diff --git a/drivers/staging/brcm80211/brcmfmac/Makefile b/drivers/staging/brcm80211/brcmfmac/Makefile index 13df7c3c79d3..b3931b03f8d7 100644 --- a/drivers/staging/brcm80211/brcmfmac/Makefile +++ b/drivers/staging/brcm80211/brcmfmac/Makefile @@ -17,7 +17,6 @@ ccflags-y := \ -DARP_OFFLOAD_SUPPORT \ - -DBCMDBG \ -DBCMLXSDMMC \ -DBCMPLATFORM_BUS \ -DBCMSDIO \ @@ -60,4 +59,3 @@ DHDOFILES = \ obj-m += brcmfmac.o brcmfmac-objs += $(DHDOFILES) - diff --git a/drivers/staging/brcm80211/brcmsmac/Makefile b/drivers/staging/brcm80211/brcmsmac/Makefile index e5dda8689890..ea297023c614 100644 --- a/drivers/staging/brcm80211/brcmsmac/Makefile +++ b/drivers/staging/brcm80211/brcmsmac/Makefile @@ -16,7 +16,6 @@ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ccflags-y := \ - -DBCMDBG \ -DWLC_HIGH \ -DWLC_LOW \ -DSTA \ @@ -25,25 +24,24 @@ ccflags-y := \ -DDBAND \ -DBCMDMA32 \ -DBCMNVRAMR \ - -Idrivers/staging/brcm80211/brcmsmac \ - -Idrivers/staging/brcm80211/brcmsmac/sys \ + -Idrivers/staging/brcm80211/brcmsmac \ -Idrivers/staging/brcm80211/brcmsmac/phy \ -Idrivers/staging/brcm80211/util \ -Idrivers/staging/brcm80211/include BRCMSMAC_OFILES := \ - sys/wl_mac80211.o \ - sys/wl_ucode_loader.o \ - sys/wlc_alloc.o \ - sys/wlc_ampdu.o \ - sys/wlc_antsel.o \ - sys/wlc_bmac.o \ - sys/wlc_channel.o \ - sys/wlc_event.o \ - sys/wlc_mac80211.o \ - sys/wlc_phy_shim.o \ - sys/wlc_rate.o \ - sys/wlc_stf.o \ + wl_mac80211.o \ + wl_ucode_loader.o \ + wlc_alloc.o \ + wlc_ampdu.o \ + wlc_antsel.o \ + wlc_bmac.o \ + wlc_channel.o \ + wlc_event.o \ + wlc_mac80211.o \ + wlc_phy_shim.o \ + wlc_rate.o \ + wlc_stf.o \ phy/wlc_phy_cmn.o \ phy/wlc_phy_lcn.o \ phy/wlc_phy_n.o \ diff --git a/drivers/staging/brcm80211/brcmsmac/d11ucode_ext.h b/drivers/staging/brcm80211/brcmsmac/d11ucode_ext.h new file mode 100644 index 000000000000..c0c0d661e00e --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/d11ucode_ext.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +enum { + D11UCODE_NAMETAG_START = 0, + D11LCN0BSINITVALS24, + D11LCN0INITVALS24, + D11LCN1BSINITVALS24, + D11LCN1INITVALS24, + D11LCN2BSINITVALS24, + D11LCN2INITVALS24, + D11N0ABSINITVALS16, + D11N0BSINITVALS16, + D11N0INITVALS16, + D11UCODE_OVERSIGHT16_MIMO, + D11UCODE_OVERSIGHT16_MIMOSZ, + D11UCODE_OVERSIGHT24_LCN, + D11UCODE_OVERSIGHT24_LCNSZ, + D11UCODE_OVERSIGHT_BOMMAJOR, + D11UCODE_OVERSIGHT_BOMMINOR +}; +#define UCODE_LOADER_API_VER 0 diff --git a/drivers/staging/brcm80211/brcmsmac/sys/d11ucode_ext.h b/drivers/staging/brcm80211/brcmsmac/sys/d11ucode_ext.h deleted file mode 100644 index c0c0d661e00e..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/d11ucode_ext.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -enum { - D11UCODE_NAMETAG_START = 0, - D11LCN0BSINITVALS24, - D11LCN0INITVALS24, - D11LCN1BSINITVALS24, - D11LCN1INITVALS24, - D11LCN2BSINITVALS24, - D11LCN2INITVALS24, - D11N0ABSINITVALS16, - D11N0BSINITVALS16, - D11N0INITVALS16, - D11UCODE_OVERSIGHT16_MIMO, - D11UCODE_OVERSIGHT16_MIMOSZ, - D11UCODE_OVERSIGHT24_LCN, - D11UCODE_OVERSIGHT24_LCNSZ, - D11UCODE_OVERSIGHT_BOMMAJOR, - D11UCODE_OVERSIGHT_BOMMINOR -}; -#define UCODE_LOADER_API_VER 0 diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wl_dbg.h b/drivers/staging/brcm80211/brcmsmac/sys/wl_dbg.h deleted file mode 100644 index 54af257598c2..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wl_dbg.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wl_dbg_h_ -#define _wl_dbg_h_ - -/* wl_msg_level is a bit vector with defs in wlioctl.h */ -extern u32 wl_msg_level; - -#define WL_NONE(fmt, args...) no_printk(fmt, ##args) - -#define WL_PRINT(level, fmt, args...) \ -do { \ - if (wl_msg_level & level) \ - printk(fmt, ##args); \ -} while (0) - -#ifdef BCMDBG - -#define WL_ERROR(fmt, args...) WL_PRINT(WL_ERROR_VAL, fmt, ##args) -#define WL_TRACE(fmt, args...) WL_PRINT(WL_TRACE_VAL, fmt, ##args) -#define WL_AMPDU(fmt, args...) WL_PRINT(WL_AMPDU_VAL, fmt, ##args) -#define WL_FFPLD(fmt, args...) WL_PRINT(WL_FFPLD_VAL, fmt, ##args) - -#define WL_ERROR_ON() (wl_msg_level & WL_ERROR_VAL) - -/* Extra message control for AMPDU debugging */ -#define WL_AMPDU_UPDN_VAL 0x00000001 /* Config up/down related */ -#define WL_AMPDU_ERR_VAL 0x00000002 /* Calls to beaocn update */ -#define WL_AMPDU_TX_VAL 0x00000004 /* Transmit data path */ -#define WL_AMPDU_RX_VAL 0x00000008 /* Receive data path */ -#define WL_AMPDU_CTL_VAL 0x00000010 /* TSF-related items */ -#define WL_AMPDU_HW_VAL 0x00000020 /* AMPDU_HW */ -#define WL_AMPDU_HWTXS_VAL 0x00000040 /* AMPDU_HWTXS */ -#define WL_AMPDU_HWDBG_VAL 0x00000080 /* AMPDU_DBG */ - -extern u32 wl_ampdu_dbg; - -#define WL_AMPDU_PRINT(level, fmt, args...) \ -do { \ - if (wl_ampdu_dbg & level) { \ - WL_AMPDU(fmt, ##args); \ - } \ -} while (0) - -#define WL_AMPDU_UPDN(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_UPDN_VAL, fmt, ##args) -#define WL_AMPDU_RX(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_RX_VAL, fmt, ##args) -#define WL_AMPDU_ERR(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_ERR_VAL, fmt, ##args) -#define WL_AMPDU_TX(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_TX_VAL, fmt, ##args) -#define WL_AMPDU_CTL(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_CTL_VAL, fmt, ##args) -#define WL_AMPDU_HW(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_HW_VAL, fmt, ##args) -#define WL_AMPDU_HWTXS(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_HWTXS_VAL, fmt, ##args) -#define WL_AMPDU_HWDBG(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_HWDBG_VAL, fmt, ##args) -#define WL_AMPDU_ERR_ON() (wl_ampdu_dbg & WL_AMPDU_ERR_VAL) -#define WL_AMPDU_HW_ON() (wl_ampdu_dbg & WL_AMPDU_HW_VAL) -#define WL_AMPDU_HWTXS_ON() (wl_ampdu_dbg & WL_AMPDU_HWTXS_VAL) - -#else /* BCMDBG */ - -#define WL_ERROR(fmt, args...) no_printk(fmt, ##args) -#define WL_TRACE(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU(fmt, args...) no_printk(fmt, ##args) -#define WL_FFPLD(fmt, args...) no_printk(fmt, ##args) - -#define WL_ERROR_ON() 0 - -#define WL_AMPDU_UPDN(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_RX(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_ERR(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_TX(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_CTL(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_HW(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_HWTXS(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_HWDBG(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_ERR_ON() 0 -#define WL_AMPDU_HW_ON() 0 -#define WL_AMPDU_HWTXS_ON() 0 - -#endif /* BCMDBG */ - -#endif /* _wl_dbg_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wl_export.h b/drivers/staging/brcm80211/brcmsmac/sys/wl_export.h deleted file mode 100644 index aa8b5a3ed633..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wl_export.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wl_export_h_ -#define _wl_export_h_ - -/* misc callbacks */ -struct wl_info; -struct wl_if; -struct wlc_if; -extern void wl_init(struct wl_info *wl); -extern uint wl_reset(struct wl_info *wl); -extern void wl_intrson(struct wl_info *wl); -extern u32 wl_intrsoff(struct wl_info *wl); -extern void wl_intrsrestore(struct wl_info *wl, u32 macintmask); -extern void wl_event(struct wl_info *wl, char *ifname, wlc_event_t *e); -extern void wl_event_sendup(struct wl_info *wl, const wlc_event_t *e, - u8 *data, u32 len); -extern int wl_up(struct wl_info *wl); -extern void wl_down(struct wl_info *wl); -extern void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, - int prio); -extern bool wl_alloc_dma_resources(struct wl_info *wl, uint dmaddrwidth); - -/* timer functions */ -struct wl_timer; -extern struct wl_timer *wl_init_timer(struct wl_info *wl, - void (*fn) (void *arg), void *arg, - const char *name); -extern void wl_free_timer(struct wl_info *wl, struct wl_timer *timer); -extern void wl_add_timer(struct wl_info *wl, struct wl_timer *timer, uint ms, - int periodic); -extern bool wl_del_timer(struct wl_info *wl, struct wl_timer *timer); - -extern uint wl_buf_to_pktcopy(struct osl_info *osh, void *p, unsigned char *buf, - int len, uint offset); -extern void *wl_get_pktbuffer(struct osl_info *osh, int len); -extern int wl_set_pktlen(struct osl_info *osh, void *p, int len); - -#define wl_sort_bsslist(a, b) false - -extern int wl_tkip_miccheck(struct wl_info *wl, void *p, int hdr_len, - bool group_key, int id); -extern int wl_tkip_micadd(struct wl_info *wl, void *p, int hdr_len); -extern int wl_tkip_encrypt(struct wl_info *wl, void *p, int hdr_len); -extern int wl_tkip_decrypt(struct wl_info *wl, void *p, int hdr_len, - bool group_key); -extern void wl_tkip_printstats(struct wl_info *wl, bool group_key); -extern int wl_tkip_keyset(struct wl_info *wl, wsec_key_t *key); -#endif /* _wl_export_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/sys/wl_mac80211.c deleted file mode 100644 index 6bc6207bab3e..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wl_mac80211.c +++ /dev/null @@ -1,1846 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define __UNDEF_NO_VERSION__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define WLC_MAXBSSCFG 1 /* single BSS configs */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - - -static void wl_timer(unsigned long data); -static void _wl_timer(wl_timer_t *t); - - -static int ieee_hw_init(struct ieee80211_hw *hw); -static int ieee_hw_rate_init(struct ieee80211_hw *hw); - -static int wl_linux_watchdog(void *ctx); - -/* Flags we support */ -#define MAC_FILTERS (FIF_PROMISC_IN_BSS | \ - FIF_ALLMULTI | \ - FIF_FCSFAIL | \ - FIF_PLCPFAIL | \ - FIF_CONTROL | \ - FIF_OTHER_BSS | \ - FIF_BCN_PRBRESP_PROMISC) - -static int wl_found; - -struct ieee80211_tkip_data { -#define TKIP_KEY_LEN 32 - u8 key[TKIP_KEY_LEN]; - int key_set; - - u32 tx_iv32; - u16 tx_iv16; - u16 tx_ttak[5]; - int tx_phase1_done; - - u32 rx_iv32; - u16 rx_iv16; - u16 rx_ttak[5]; - int rx_phase1_done; - u32 rx_iv32_new; - u16 rx_iv16_new; - - u32 dot11RSNAStatsTKIPReplays; - u32 dot11RSNAStatsTKIPICVErrors; - u32 dot11RSNAStatsTKIPLocalMICFailures; - - int key_idx; - - struct crypto_tfm *tfm_arc4; - struct crypto_tfm *tfm_michael; - - /* scratch buffers for virt_to_page() (crypto API) */ - u8 rx_hdr[16], tx_hdr[16]; -}; - -#define WL_DEV_IF(dev) ((struct wl_if *)netdev_priv(dev)) -#define WL_INFO(dev) ((struct wl_info *)(WL_DEV_IF(dev)->wl)) -static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev); -static void wl_release_fw(struct wl_info *wl); - -/* local prototypes */ -static int wl_start(struct sk_buff *skb, struct wl_info *wl); -static int wl_start_int(struct wl_info *wl, struct ieee80211_hw *hw, - struct sk_buff *skb); -static void wl_dpc(unsigned long data); - -MODULE_AUTHOR("Broadcom Corporation"); -MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver."); -MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards"); -MODULE_LICENSE("Dual BSD/GPL"); - -/* recognized PCI IDs */ -static struct pci_device_id wl_id_table[] = { - {PCI_VENDOR_ID_BROADCOM, 0x4357, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43225 2G */ - {PCI_VENDOR_ID_BROADCOM, 0x4353, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43224 DUAL */ - {PCI_VENDOR_ID_BROADCOM, 0x4727, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 4313 DUAL */ - {0} -}; - -MODULE_DEVICE_TABLE(pci, wl_id_table); -static void wl_remove(struct pci_dev *pdev); - - -#ifdef BCMDBG -static int msglevel = 0xdeadbeef; -module_param(msglevel, int, 0); -static int phymsglevel = 0xdeadbeef; -module_param(phymsglevel, int, 0); -#endif /* BCMDBG */ - -#define HW_TO_WL(hw) (hw->priv) -#define WL_TO_HW(wl) (wl->pub->ieee_hw) -static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb); -static int wl_ops_start(struct ieee80211_hw *hw); -static void wl_ops_stop(struct ieee80211_hw *hw); -static int wl_ops_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif); -static void wl_ops_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif); -static int wl_ops_config(struct ieee80211_hw *hw, u32 changed); -static void wl_ops_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *info, - u32 changed); -static void wl_ops_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, u64 multicast); -static int wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, - bool set); -static void wl_ops_sw_scan_start(struct ieee80211_hw *hw); -static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw); -static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf); -static int wl_ops_get_stats(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats); -static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value); -static void wl_ops_sta_notify(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum sta_notify_cmd cmd, - struct ieee80211_sta *sta); -static int wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, - const struct ieee80211_tx_queue_params *params); -static u64 wl_ops_get_tsf(struct ieee80211_hw *hw); -static int wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta); -static int wl_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta); -static int wl_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn); - -static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - int status; - struct wl_info *wl = hw->priv; - WL_LOCK(wl); - if (!wl->pub->up) { - WL_ERROR("ops->tx called while down\n"); - status = -ENETDOWN; - goto done; - } - status = wl_start(skb, wl); - done: - WL_UNLOCK(wl); - return status; -} - -static int wl_ops_start(struct ieee80211_hw *hw) -{ - struct wl_info *wl = hw->priv; - /* - struct ieee80211_channel *curchan = hw->conf.channel; - WL_NONE("%s : Initial channel: %d\n", __func__, curchan->hw_value); - */ - - WL_LOCK(wl); - ieee80211_wake_queues(hw); - WL_UNLOCK(wl); - - return 0; -} - -static void wl_ops_stop(struct ieee80211_hw *hw) -{ - struct wl_info *wl = hw->priv; - ASSERT(wl); - WL_LOCK(wl); - wl_down(wl); - ieee80211_stop_queues(hw); - WL_UNLOCK(wl); - - return; -} - -static int -wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -{ - struct wl_info *wl; - int err; - - /* Just STA for now */ - if (vif->type != NL80211_IFTYPE_AP && - vif->type != NL80211_IFTYPE_MESH_POINT && - vif->type != NL80211_IFTYPE_STATION && - vif->type != NL80211_IFTYPE_WDS && - vif->type != NL80211_IFTYPE_ADHOC) { - WL_ERROR("%s: Attempt to add type %d, only STA for now\n", - __func__, vif->type); - return -EOPNOTSUPP; - } - - wl = HW_TO_WL(hw); - WL_LOCK(wl); - err = wl_up(wl); - WL_UNLOCK(wl); - - if (err != 0) - WL_ERROR("%s: wl_up() returned %d\n", __func__, err); - return err; -} - -static void -wl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -{ - return; -} - -static int -ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan, - enum nl80211_channel_type type) -{ - struct wl_info *wl = HW_TO_WL(hw); - int err = 0; - - switch (type) { - case NL80211_CHAN_HT20: - case NL80211_CHAN_NO_HT: - WL_LOCK(wl); - err = wlc_set(wl->wlc, WLC_SET_CHANNEL, chan->hw_value); - WL_UNLOCK(wl); - break; - case NL80211_CHAN_HT40MINUS: - case NL80211_CHAN_HT40PLUS: - WL_ERROR("%s: Need to implement 40 Mhz Channels!\n", __func__); - break; - } - - if (err) - return -EIO; - return err; -} - -static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) -{ - struct ieee80211_conf *conf = &hw->conf; - struct wl_info *wl = HW_TO_WL(hw); - int err = 0; - int new_int; - - if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { - WL_NONE("%s: Setting listen interval to %d\n", - __func__, conf->listen_interval); - if (wlc_iovar_setint - (wl->wlc, "bcn_li_bcn", conf->listen_interval)) { - WL_ERROR("%s: Error setting listen_interval\n", - __func__); - err = -EIO; - goto config_out; - } - wlc_iovar_getint(wl->wlc, "bcn_li_bcn", &new_int); - ASSERT(new_int == conf->listen_interval); - } - if (changed & IEEE80211_CONF_CHANGE_MONITOR) - WL_NONE("Need to set monitor mode\n"); - if (changed & IEEE80211_CONF_CHANGE_PS) - WL_NONE("Need to set Power-save mode\n"); - - if (changed & IEEE80211_CONF_CHANGE_POWER) { - WL_NONE("%s: Setting tx power to %d dbm\n", - __func__, conf->power_level); - if (wlc_iovar_setint - (wl->wlc, "qtxpower", conf->power_level * 4)) { - WL_ERROR("%s: Error setting power_level\n", __func__); - err = -EIO; - goto config_out; - } - wlc_iovar_getint(wl->wlc, "qtxpower", &new_int); - if (new_int != (conf->power_level * 4)) - WL_ERROR("%s: Power level req != actual, %d %d\n", - __func__, conf->power_level * 4, new_int); - } - if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - err = ieee_set_channel(hw, conf->channel, conf->channel_type); - } - if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { - WL_NONE("%s: srl %d, lrl %d\n", - __func__, - conf->short_frame_max_tx_count, - conf->long_frame_max_tx_count); - if (wlc_set - (wl->wlc, WLC_SET_SRL, - conf->short_frame_max_tx_count) < 0) { - WL_ERROR("%s: Error setting srl\n", __func__); - err = -EIO; - goto config_out; - } - if (wlc_set(wl->wlc, WLC_SET_LRL, conf->long_frame_max_tx_count) - < 0) { - WL_ERROR("%s: Error setting lrl\n", __func__); - err = -EIO; - goto config_out; - } - } - - config_out: - return err; -} - -static void -wl_ops_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *info, u32 changed) -{ - struct wl_info *wl = HW_TO_WL(hw); - int val; - - - if (changed & BSS_CHANGED_ASSOC) { - WL_ERROR("Associated:\t%s\n", info->assoc ? "True" : "False"); - /* association status changed (associated/disassociated) - * also implies a change in the AID. - */ - } - if (changed & BSS_CHANGED_ERP_CTS_PROT) { - WL_NONE("Use_cts_prot:\t%s Implement me\n", - info->use_cts_prot ? "True" : "False"); - /* CTS protection changed */ - } - if (changed & BSS_CHANGED_ERP_PREAMBLE) { - WL_NONE("Short preamble:\t%s Implement me\n", - info->use_short_preamble ? "True" : "False"); - /* preamble changed */ - } - if (changed & BSS_CHANGED_ERP_SLOT) { - WL_NONE("Changing short slot:\t%s\n", - info->use_short_slot ? "True" : "False"); - if (info->use_short_slot) - val = 1; - else - val = 0; - wlc_set(wl->wlc, WLC_SET_SHORTSLOT_OVERRIDE, val); - /* slot timing changed */ - } - - if (changed & BSS_CHANGED_HT) { - WL_NONE("%s: HT mode - Implement me\n", __func__); - /* 802.11n parameters changed */ - } - if (changed & BSS_CHANGED_BASIC_RATES) { - WL_NONE("Need to change Basic Rates:\t0x%x! Implement me\n", - (u32) info->basic_rates); - /* Basic rateset changed */ - } - if (changed & BSS_CHANGED_BEACON_INT) { - WL_NONE("Beacon Interval:\t%d Implement me\n", - info->beacon_int); - /* Beacon interval changed */ - } - if (changed & BSS_CHANGED_BSSID) { - WL_NONE("new BSSID:\taid %d bss:%pM\n", - info->aid, info->bssid); - /* BSSID changed, for whatever reason (IBSS and managed mode) */ - /* FIXME: need to store bssid in bsscfg */ - wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, - info->bssid); - } - if (changed & BSS_CHANGED_BEACON) { - WL_ERROR("BSS_CHANGED_BEACON\n"); - /* Beacon data changed, retrieve new beacon (beaconing modes) */ - } - if (changed & BSS_CHANGED_BEACON_ENABLED) { - WL_ERROR("Beacon enabled:\t%s\n", - info->enable_beacon ? "True" : "False"); - /* Beaconing should be enabled/disabled (beaconing modes) */ - } - return; -} - -static void -wl_ops_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, u64 multicast) -{ - struct wl_info *wl = hw->priv; - - changed_flags &= MAC_FILTERS; - *total_flags &= MAC_FILTERS; - if (changed_flags & FIF_PROMISC_IN_BSS) - WL_ERROR("FIF_PROMISC_IN_BSS\n"); - if (changed_flags & FIF_ALLMULTI) - WL_ERROR("FIF_ALLMULTI\n"); - if (changed_flags & FIF_FCSFAIL) - WL_ERROR("FIF_FCSFAIL\n"); - if (changed_flags & FIF_PLCPFAIL) - WL_ERROR("FIF_PLCPFAIL\n"); - if (changed_flags & FIF_CONTROL) - WL_ERROR("FIF_CONTROL\n"); - if (changed_flags & FIF_OTHER_BSS) - WL_ERROR("FIF_OTHER_BSS\n"); - if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { - WL_NONE("FIF_BCN_PRBRESP_PROMISC\n"); - WL_LOCK(wl); - if (*total_flags & FIF_BCN_PRBRESP_PROMISC) { - wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS; - wlc_mac_bcn_promisc_change(wl->wlc, 1); - } else { - wlc_mac_bcn_promisc_change(wl->wlc, 0); - wl->pub->mac80211_state &= ~MAC80211_PROMISC_BCNS; - } - WL_UNLOCK(wl); - } - return; -} - -static int -wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) -{ - WL_ERROR("%s: Enter\n", __func__); - return 0; -} - -static void wl_ops_sw_scan_start(struct ieee80211_hw *hw) -{ - WL_NONE("Scan Start\n"); - return; -} - -static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw) -{ - WL_NONE("Scan Complete\n"); - return; -} - -static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf) -{ - WL_ERROR("%s: Enter\n", __func__); - return; -} - -static int -wl_ops_get_stats(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats) -{ - WL_ERROR("%s: Enter\n", __func__); - return 0; -} - -static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value) -{ - WL_ERROR("%s: Enter\n", __func__); - return 0; -} - -static void -wl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - enum sta_notify_cmd cmd, struct ieee80211_sta *sta) -{ - WL_NONE("%s: Enter\n", __func__); - switch (cmd) { - default: - WL_ERROR("%s: Unknown cmd = %d\n", __func__, cmd); - break; - } - return; -} - -static int -wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, - const struct ieee80211_tx_queue_params *params) -{ - struct wl_info *wl = hw->priv; - - WL_NONE("%s: Enter (WME config)\n", __func__); - WL_NONE("queue %d, txop %d, cwmin %d, cwmax %d, aifs %d\n", queue, - params->txop, params->cw_min, params->cw_max, params->aifs); - - WL_LOCK(wl); - wlc_wme_setparams(wl->wlc, queue, (void *)params, true); - WL_UNLOCK(wl); - - return 0; -} - -static u64 wl_ops_get_tsf(struct ieee80211_hw *hw) -{ - WL_ERROR("%s: Enter\n", __func__); - return 0; -} - -static int -wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - struct scb *scb; - - int i; - struct wl_info *wl = hw->priv; - - /* Init the scb */ - scb = (struct scb *)sta->drv_priv; - memset(scb, 0, sizeof(struct scb)); - for (i = 0; i < NUMPRIO; i++) - scb->seqctl[i] = 0xFFFF; - scb->seqctl_nonqos = 0xFFFF; - scb->magic = SCB_MAGIC; - - wl->pub->global_scb = scb; - wl->pub->global_ampdu = &(scb->scb_ampdu); - wl->pub->global_ampdu->scb = scb; - wl->pub->global_ampdu->max_pdu = 16; - pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID, - AMPDU_MAX_SCB_TID * PKTQ_LEN_DEFAULT); - - sta->ht_cap.ht_supported = true; - sta->ht_cap.ampdu_factor = AMPDU_RX_FACTOR_64K; - sta->ht_cap.ampdu_density = AMPDU_DEF_MPDU_DENSITY; - sta->ht_cap.cap = IEEE80211_HT_CAP_GRN_FLD | - IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT; - - /* minstrel_ht initiates addBA on our behalf by calling ieee80211_start_tx_ba_session() */ - return 0; -} - -static int -wl_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - WL_NONE("%s: Enter\n", __func__); - return 0; -} - -static int -wl_ampdu_action(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn) -{ -#if defined(BCMDBG) - struct scb *scb = (struct scb *)sta->drv_priv; -#endif - struct wl_info *wl = hw->priv; - - ASSERT(scb->magic == SCB_MAGIC); - switch (action) { - case IEEE80211_AMPDU_RX_START: - WL_NONE("%s: action = IEEE80211_AMPDU_RX_START\n", __func__); - break; - case IEEE80211_AMPDU_RX_STOP: - WL_NONE("%s: action = IEEE80211_AMPDU_RX_STOP\n", __func__); - break; - case IEEE80211_AMPDU_TX_START: - if (!wlc_aggregatable(wl->wlc, tid)) { - /* WL_ERROR("START: tid %d is not agg' able, return FAILURE to stack\n", tid); */ - return -1; - } - /* XXX: Use the starting sequence number provided ... */ - *ssn = 0; - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); - break; - - case IEEE80211_AMPDU_TX_STOP: - ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); - break; - case IEEE80211_AMPDU_TX_OPERATIONAL: - /* Not sure what to do here */ - /* Power save wakeup */ - WL_NONE("%s: action = IEEE80211_AMPDU_TX_OPERATIONAL\n", - __func__); - break; - default: - WL_ERROR("%s: Invalid command, ignoring\n", __func__); - } - - return 0; -} - -static const struct ieee80211_ops wl_ops = { - .tx = wl_ops_tx, - .start = wl_ops_start, - .stop = wl_ops_stop, - .add_interface = wl_ops_add_interface, - .remove_interface = wl_ops_remove_interface, - .config = wl_ops_config, - .bss_info_changed = wl_ops_bss_info_changed, - .configure_filter = wl_ops_configure_filter, - .set_tim = wl_ops_set_tim, - .sw_scan_start = wl_ops_sw_scan_start, - .sw_scan_complete = wl_ops_sw_scan_complete, - .set_tsf = wl_ops_set_tsf, - .get_stats = wl_ops_get_stats, - .set_rts_threshold = wl_ops_set_rts_threshold, - .sta_notify = wl_ops_sta_notify, - .conf_tx = wl_ops_conf_tx, - .get_tsf = wl_ops_get_tsf, - .sta_add = wl_sta_add, - .sta_remove = wl_sta_remove, - .ampdu_action = wl_ampdu_action, -}; - -static int wl_set_hint(struct wl_info *wl, char *abbrev) -{ - WL_ERROR("%s: Sending country code %c%c to MAC80211\n", - __func__, abbrev[0], abbrev[1]); - return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev); -} - -/** - * attach to the WL device. - * - * Attach to the WL device identified by vendor and device parameters. - * regs is a host accessible memory address pointing to WL device registers. - * - * wl_attach is not defined as static because in the case where no bus - * is defined, wl_attach will never be called, and thus, gcc will issue - * a warning that this function is defined but not used if we declare - * it as static. - */ -static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, - uint bustype, void *btparam, uint irq) -{ - struct wl_info *wl; - struct osl_info *osh; - int unit, err; - - unsigned long base_addr; - struct ieee80211_hw *hw; - u8 perm[ETH_ALEN]; - - unit = wl_found; - err = 0; - - if (unit < 0) { - WL_ERROR("wl%d: unit number overflow, exiting\n", unit); - return NULL; - } - - osh = osl_attach(btparam, bustype); - ASSERT(osh); - - /* allocate private info */ - hw = pci_get_drvdata(btparam); /* btparam == pdev */ - wl = hw->priv; - ASSERT(wl); - - wl->osh = osh; - atomic_set(&wl->callbacks, 0); - - /* setup the bottom half handler */ - tasklet_init(&wl->tasklet, wl_dpc, (unsigned long) wl); - - - - base_addr = regs; - - if (bustype == PCI_BUS) { - wl->piomode = false; - } else if (bustype == RPC_BUS) { - /* Do nothing */ - } else { - bustype = PCI_BUS; - WL_TRACE("force to PCI\n"); - } - wl->bcm_bustype = bustype; - - wl->regsva = ioremap_nocache(base_addr, PCI_BAR0_WINSZ); - if (wl->regsva == NULL) { - WL_ERROR("wl%d: ioremap() failed\n", unit); - goto fail; - } - spin_lock_init(&wl->lock); - spin_lock_init(&wl->isr_lock); - - /* prepare ucode */ - if (wl_request_fw(wl, (struct pci_dev *)btparam)) { - printf("%s: Failed to find firmware usually in %s\n", - KBUILD_MODNAME, "/lib/firmware/brcm"); - wl_release_fw(wl); - wl_remove((struct pci_dev *)btparam); - goto fail1; - } - - /* common load-time initialization */ - wl->wlc = wlc_attach((void *)wl, vendor, device, unit, wl->piomode, osh, - wl->regsva, wl->bcm_bustype, btparam, &err); - wl_release_fw(wl); - if (!wl->wlc) { - printf("%s: wlc_attach() failed with code %d\n", - KBUILD_MODNAME, err); - goto fail; - } - wl->pub = wlc_pub(wl->wlc); - - wl->pub->ieee_hw = hw; - ASSERT(wl->pub->ieee_hw); - ASSERT(wl->pub->ieee_hw->priv == wl); - - - if (wlc_iovar_setint(wl->wlc, "mpc", 0)) { - WL_ERROR("wl%d: Error setting MPC variable to 0\n", unit); - } - - /* register our interrupt handler */ - if (request_irq(irq, wl_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { - WL_ERROR("wl%d: request_irq() failed\n", unit); - goto fail; - } - wl->irq = irq; - - /* register module */ - wlc_module_register(wl->pub, NULL, "linux", wl, NULL, wl_linux_watchdog, - NULL); - - if (ieee_hw_init(hw)) { - WL_ERROR("wl%d: %s: ieee_hw_init failed!\n", unit, __func__); - goto fail; - } - - bcopy(&wl->pub->cur_etheraddr, perm, ETH_ALEN); - ASSERT(is_valid_ether_addr(perm)); - SET_IEEE80211_PERM_ADDR(hw, perm); - - err = ieee80211_register_hw(hw); - if (err) { - WL_ERROR("%s: ieee80211_register_hw failed, status %d\n", - __func__, err); - } - - if (wl->pub->srom_ccode[0]) - err = wl_set_hint(wl, wl->pub->srom_ccode); - else - err = wl_set_hint(wl, "US"); - if (err) { - WL_ERROR("%s: regulatory_hint failed, status %d\n", - __func__, err); - } - WL_ERROR("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver (" PHY_VERSION_STR ")", - unit); - -#ifdef BCMDBG - printf(" (Compiled at " __TIME__ " on " __DATE__ ")"); -#endif /* BCMDBG */ - printf("\n"); - - wl_found++; - return wl; - - fail: - wl_free(wl); -fail1: - return NULL; -} - - - -#define CHAN2GHZ(channel, freqency, chflags) { \ - .band = IEEE80211_BAND_2GHZ, \ - .center_freq = (freqency), \ - .hw_value = (channel), \ - .flags = chflags, \ - .max_antenna_gain = 0, \ - .max_power = 19, \ -} - -static struct ieee80211_channel wl_2ghz_chantable[] = { - CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS), - CHAN2GHZ(2, 2417, IEEE80211_CHAN_NO_HT40MINUS), - CHAN2GHZ(3, 2422, IEEE80211_CHAN_NO_HT40MINUS), - CHAN2GHZ(4, 2427, IEEE80211_CHAN_NO_HT40MINUS), - CHAN2GHZ(5, 2432, 0), - CHAN2GHZ(6, 2437, 0), - CHAN2GHZ(7, 2442, 0), - CHAN2GHZ(8, 2447, IEEE80211_CHAN_NO_HT40PLUS), - CHAN2GHZ(9, 2452, IEEE80211_CHAN_NO_HT40PLUS), - CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS), - CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS), - CHAN2GHZ(12, 2467, - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_NO_HT40PLUS), - CHAN2GHZ(13, 2472, - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_NO_HT40PLUS), - CHAN2GHZ(14, 2484, - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS) -}; - -#define CHAN5GHZ(channel, chflags) { \ - .band = IEEE80211_BAND_5GHZ, \ - .center_freq = 5000 + 5*(channel), \ - .hw_value = (channel), \ - .flags = chflags, \ - .max_antenna_gain = 0, \ - .max_power = 21, \ -} - -static struct ieee80211_channel wl_5ghz_nphy_chantable[] = { - /* UNII-1 */ - CHAN5GHZ(36, IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(40, IEEE80211_CHAN_NO_HT40PLUS), - CHAN5GHZ(44, IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS), - /* UNII-2 */ - CHAN5GHZ(52, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(56, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), - CHAN5GHZ(60, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(64, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), - /* MID */ - CHAN5GHZ(100, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(104, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), - CHAN5GHZ(108, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(112, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), - CHAN5GHZ(116, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(120, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), - CHAN5GHZ(124, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(128, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), - CHAN5GHZ(132, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(136, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), - CHAN5GHZ(140, - IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS | - IEEE80211_CHAN_NO_HT40MINUS), - /* UNII-3 */ - CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(153, IEEE80211_CHAN_NO_HT40PLUS), - CHAN5GHZ(157, IEEE80211_CHAN_NO_HT40MINUS), - CHAN5GHZ(161, IEEE80211_CHAN_NO_HT40PLUS), - CHAN5GHZ(165, IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS) -}; - -#define RATE(rate100m, _flags) { \ - .bitrate = (rate100m), \ - .flags = (_flags), \ - .hw_value = (rate100m / 5), \ -} - -static struct ieee80211_rate wl_legacy_ratetable[] = { - RATE(10, 0), - RATE(20, IEEE80211_RATE_SHORT_PREAMBLE), - RATE(55, IEEE80211_RATE_SHORT_PREAMBLE), - RATE(110, IEEE80211_RATE_SHORT_PREAMBLE), - RATE(60, 0), - RATE(90, 0), - RATE(120, 0), - RATE(180, 0), - RATE(240, 0), - RATE(360, 0), - RATE(480, 0), - RATE(540, 0), -}; - -static struct ieee80211_supported_band wl_band_2GHz_nphy = { - .band = IEEE80211_BAND_2GHZ, - .channels = wl_2ghz_chantable, - .n_channels = ARRAY_SIZE(wl_2ghz_chantable), - .bitrates = wl_legacy_ratetable, - .n_bitrates = ARRAY_SIZE(wl_legacy_ratetable), - .ht_cap = { - /* from include/linux/ieee80211.h */ - .cap = IEEE80211_HT_CAP_GRN_FLD | - IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, - .ht_supported = true, - .ampdu_factor = AMPDU_RX_FACTOR_64K, - .ampdu_density = AMPDU_DEF_MPDU_DENSITY, - .mcs = { - /* placeholders for now */ - .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0}, - .rx_highest = 500, - .tx_params = IEEE80211_HT_MCS_TX_DEFINED} - } -}; - -static struct ieee80211_supported_band wl_band_5GHz_nphy = { - .band = IEEE80211_BAND_5GHZ, - .channels = wl_5ghz_nphy_chantable, - .n_channels = ARRAY_SIZE(wl_5ghz_nphy_chantable), - .bitrates = wl_legacy_ratetable + 4, - .n_bitrates = ARRAY_SIZE(wl_legacy_ratetable) - 4, - .ht_cap = { - /* use IEEE80211_HT_CAP_* from include/linux/ieee80211.h */ - .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, /* No 40 mhz yet */ - .ht_supported = true, - .ampdu_factor = AMPDU_RX_FACTOR_64K, - .ampdu_density = AMPDU_DEF_MPDU_DENSITY, - .mcs = { - /* placeholders for now */ - .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0}, - .rx_highest = 500, - .tx_params = IEEE80211_HT_MCS_TX_DEFINED} - } -}; - -static int ieee_hw_rate_init(struct ieee80211_hw *hw) -{ - struct wl_info *wl = HW_TO_WL(hw); - int has_5g; - char phy_list[4]; - - has_5g = 0; - - hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL; - hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; - - if (wlc_get(wl->wlc, WLC_GET_PHYLIST, (int *)&phy_list) < 0) { - WL_ERROR("Phy list failed\n"); - } - WL_NONE("%s: phylist = %c\n", __func__, phy_list[0]); - - if (phy_list[0] == 'n' || phy_list[0] == 'c') { - if (phy_list[0] == 'c') { - /* Single stream */ - wl_band_2GHz_nphy.ht_cap.mcs.rx_mask[1] = 0; - wl_band_2GHz_nphy.ht_cap.mcs.rx_highest = 72; - } - hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl_band_2GHz_nphy; - } else { - BUG(); - return -1; - } - - /* Assume all bands use the same phy. True for 11n devices. */ - if (NBANDS_PUB(wl->pub) > 1) { - has_5g++; - if (phy_list[0] == 'n' || phy_list[0] == 'c') { - hw->wiphy->bands[IEEE80211_BAND_5GHZ] = - &wl_band_5GHz_nphy; - } else { - return -1; - } - } - - WL_NONE("%s: 2ghz = %d, 5ghz = %d\n", __func__, 1, has_5g); - - return 0; -} - -static int ieee_hw_init(struct ieee80211_hw *hw) -{ - hw->flags = IEEE80211_HW_SIGNAL_DBM - /* | IEEE80211_HW_CONNECTION_MONITOR What is this? */ - | IEEE80211_HW_REPORTS_TX_ACK_STATUS - | IEEE80211_HW_AMPDU_AGGREGATION; - - hw->extra_tx_headroom = wlc_get_header_len(); - /* FIXME: should get this from wlc->machwcap */ - hw->queues = 4; - /* FIXME: this doesn't seem to be used properly in minstrel_ht. - * mac80211/status.c:ieee80211_tx_status() checks this value, - * but mac80211/rc80211_minstrel_ht.c:minstrel_ht_get_rate() - * appears to always set 3 rates - */ - hw->max_rates = 2; /* Primary rate and 1 fallback rate */ - - hw->channel_change_time = 7 * 1000; /* channel change time is dependant on chip and band */ - hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); - - hw->rate_control_algorithm = "minstrel_ht"; - - hw->sta_data_size = sizeof(struct scb); - return ieee_hw_rate_init(hw); -} - -/** - * determines if a device is a WL device, and if so, attaches it. - * - * This function determines if a device pointed to by pdev is a WL device, - * and if so, performs a wl_attach() on it. - * - */ -int __devinit -wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - int rc; - struct wl_info *wl; - struct ieee80211_hw *hw; - u32 val; - - ASSERT(pdev); - - WL_TRACE("%s: bus %d slot %d func %d irq %d\n", - __func__, pdev->bus->number, PCI_SLOT(pdev->devfn), - PCI_FUNC(pdev->devfn), pdev->irq); - - if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) || - (((pdev->device & 0xff00) != 0x4300) && - ((pdev->device & 0xff00) != 0x4700) && - ((pdev->device < 43000) || (pdev->device > 43999)))) - return -ENODEV; - - rc = pci_enable_device(pdev); - if (rc) { - WL_ERROR("%s: Cannot enable device %d-%d_%d\n", - __func__, pdev->bus->number, PCI_SLOT(pdev->devfn), - PCI_FUNC(pdev->devfn)); - return -ENODEV; - } - pci_set_master(pdev); - - pci_read_config_dword(pdev, 0x40, &val); - if ((val & 0x0000ff00) != 0) - pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); - - hw = ieee80211_alloc_hw(sizeof(struct wl_info), &wl_ops); - if (!hw) { - WL_ERROR("%s: ieee80211_alloc_hw failed\n", __func__); - rc = -ENOMEM; - goto err_1; - } - - SET_IEEE80211_DEV(hw, &pdev->dev); - - pci_set_drvdata(pdev, hw); - - memset(hw->priv, 0, sizeof(*wl)); - - wl = wl_attach(pdev->vendor, pdev->device, pci_resource_start(pdev, 0), - PCI_BUS, pdev, pdev->irq); - - if (!wl) { - WL_ERROR("%s: %s: wl_attach failed!\n", - KBUILD_MODNAME, __func__); - return -ENODEV; - } - return 0; - err_1: - WL_ERROR("%s: err_1: Major hoarkage\n", __func__); - return 0; -} - -#ifdef LINUXSTA_PS -static int wl_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct wl_info *wl; - struct ieee80211_hw *hw; - - WL_TRACE("wl: wl_suspend\n"); - - hw = pci_get_drvdata(pdev); - wl = HW_TO_WL(hw); - if (!wl) { - WL_ERROR("wl: wl_suspend: pci_get_drvdata failed\n"); - return -ENODEV; - } - - WL_LOCK(wl); - wl_down(wl); - wl->pub->hw_up = false; - WL_UNLOCK(wl); - pci_save_state(pdev, wl->pci_psstate); - pci_disable_device(pdev); - return pci_set_power_state(pdev, PCI_D3hot); -} - -static int wl_resume(struct pci_dev *pdev) -{ - struct wl_info *wl; - struct ieee80211_hw *hw; - int err = 0; - u32 val; - - WL_TRACE("wl: wl_resume\n"); - hw = pci_get_drvdata(pdev); - wl = HW_TO_WL(hw); - if (!wl) { - WL_ERROR("wl: wl_resume: pci_get_drvdata failed\n"); - return -ENODEV; - } - - err = pci_set_power_state(pdev, PCI_D0); - if (err) - return err; - - pci_restore_state(pdev, wl->pci_psstate); - - err = pci_enable_device(pdev); - if (err) - return err; - - pci_set_master(pdev); - - pci_read_config_dword(pdev, 0x40, &val); - if ((val & 0x0000ff00) != 0) - pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); - - WL_LOCK(wl); - err = wl_up(wl); - WL_UNLOCK(wl); - - return err; -} -#endif /* LINUXSTA_PS */ - -static void wl_remove(struct pci_dev *pdev) -{ - struct wl_info *wl; - struct ieee80211_hw *hw; - - hw = pci_get_drvdata(pdev); - wl = HW_TO_WL(hw); - if (!wl) { - WL_ERROR("wl: wl_remove: pci_get_drvdata failed\n"); - return; - } - if (!wlc_chipmatch(pdev->vendor, pdev->device)) { - WL_ERROR("wl: wl_remove: wlc_chipmatch failed\n"); - return; - } - if (wl->wlc) { - ieee80211_unregister_hw(hw); - WL_LOCK(wl); - wl_down(wl); - WL_UNLOCK(wl); - WL_NONE("%s: Down\n", __func__); - } - pci_disable_device(pdev); - - wl_free(wl); - - pci_set_drvdata(pdev, NULL); - ieee80211_free_hw(hw); -} - -static struct pci_driver wl_pci_driver = { - .name = "brcm80211", - .probe = wl_pci_probe, -#ifdef LINUXSTA_PS - .suspend = wl_suspend, - .resume = wl_resume, -#endif /* LINUXSTA_PS */ - .remove = __devexit_p(wl_remove), - .id_table = wl_id_table, -}; - -/** - * This is the main entry point for the WL driver. - * - * This function determines if a device pointed to by pdev is a WL device, - * and if so, performs a wl_attach() on it. - * - */ -static int __init wl_module_init(void) -{ - int error = -ENODEV; - -#ifdef BCMDBG - if (msglevel != 0xdeadbeef) - wl_msg_level = msglevel; - else { - char *var = getvar(NULL, "wl_msglevel"); - if (var) - wl_msg_level = simple_strtoul(var, NULL, 0); - } - { - extern u32 phyhal_msg_level; - - if (phymsglevel != 0xdeadbeef) - phyhal_msg_level = phymsglevel; - else { - char *var = getvar(NULL, "phy_msglevel"); - if (var) - phyhal_msg_level = simple_strtoul(var, NULL, 0); - } - } -#endif /* BCMDBG */ - - error = pci_register_driver(&wl_pci_driver); - if (!error) - return 0; - - - - return error; -} - -/** - * This function unloads the WL driver from the system. - * - * This function unconditionally unloads the WL driver module from the - * system. - * - */ -static void __exit wl_module_exit(void) -{ - pci_unregister_driver(&wl_pci_driver); - -} - -module_init(wl_module_init); -module_exit(wl_module_exit); - -/** - * This function frees the WL per-device resources. - * - * This function frees resources owned by the WL device pointed to - * by the wl parameter. - * - */ -void wl_free(struct wl_info *wl) -{ - wl_timer_t *t, *next; - struct osl_info *osh; - - ASSERT(wl); - /* free ucode data */ - if (wl->fw.fw_cnt) - wl_ucode_data_free(); - if (wl->irq) - free_irq(wl->irq, wl); - - /* kill dpc */ - tasklet_kill(&wl->tasklet); - - if (wl->pub) { - wlc_module_unregister(wl->pub, "linux", wl); - } - - /* free common resources */ - if (wl->wlc) { - wlc_detach(wl->wlc); - wl->wlc = NULL; - wl->pub = NULL; - } - - /* virtual interface deletion is deferred so we cannot spinwait */ - - /* wait for all pending callbacks to complete */ - while (atomic_read(&wl->callbacks) > 0) - schedule(); - - /* free timers */ - for (t = wl->timers; t; t = next) { - next = t->next; -#ifdef BCMDBG - if (t->name) - kfree(t->name); -#endif - kfree(t); - } - - osh = wl->osh; - - /* - * unregister_netdev() calls get_stats() which may read chip registers - * so we cannot unmap the chip registers until after calling unregister_netdev() . - */ - if (wl->regsva && wl->bcm_bustype != SDIO_BUS && - wl->bcm_bustype != JTAG_BUS) { - iounmap((void *)wl->regsva); - } - wl->regsva = NULL; - - - osl_detach(osh); -} - -/* transmit a packet */ -static int BCMFASTPATH wl_start(struct sk_buff *skb, struct wl_info *wl) -{ - if (!wl) - return -ENETDOWN; - - return wl_start_int(wl, WL_TO_HW(wl), skb); -} - -static int BCMFASTPATH -wl_start_int(struct wl_info *wl, struct ieee80211_hw *hw, struct sk_buff *skb) -{ - wlc_sendpkt_mac80211(wl->wlc, skb, hw); - return NETDEV_TX_OK; -} - -void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, - int prio) -{ - WL_ERROR("Shouldn't be here %s\n", __func__); -} - -void wl_init(struct wl_info *wl) -{ - WL_TRACE("wl%d: wl_init\n", wl->pub->unit); - - wl_reset(wl); - - wlc_init(wl->wlc); -} - -uint wl_reset(struct wl_info *wl) -{ - WL_TRACE("wl%d: wl_reset\n", wl->pub->unit); - - wlc_reset(wl->wlc); - - /* dpc will not be rescheduled */ - wl->resched = 0; - - return 0; -} - -/* - * These are interrupt on/off entry points. Disable interrupts - * during interrupt state transition. - */ -void BCMFASTPATH wl_intrson(struct wl_info *wl) -{ - unsigned long flags; - - INT_LOCK(wl, flags); - wlc_intrson(wl->wlc); - INT_UNLOCK(wl, flags); -} - -bool wl_alloc_dma_resources(struct wl_info *wl, uint addrwidth) -{ - return true; -} - -u32 BCMFASTPATH wl_intrsoff(struct wl_info *wl) -{ - unsigned long flags; - u32 status; - - INT_LOCK(wl, flags); - status = wlc_intrsoff(wl->wlc); - INT_UNLOCK(wl, flags); - return status; -} - -void wl_intrsrestore(struct wl_info *wl, u32 macintmask) -{ - unsigned long flags; - - INT_LOCK(wl, flags); - wlc_intrsrestore(wl->wlc, macintmask); - INT_UNLOCK(wl, flags); -} - -int wl_up(struct wl_info *wl) -{ - int error = 0; - - if (wl->pub->up) - return 0; - - error = wlc_up(wl->wlc); - - return error; -} - -void wl_down(struct wl_info *wl) -{ - uint callbacks, ret_val = 0; - - /* call common down function */ - ret_val = wlc_down(wl->wlc); - callbacks = atomic_read(&wl->callbacks) - ret_val; - - /* wait for down callbacks to complete */ - WL_UNLOCK(wl); - - /* For HIGH_only driver, it's important to actually schedule other work, - * not just spin wait since everything runs at schedule level - */ - SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000); - - WL_LOCK(wl); -} - -irqreturn_t BCMFASTPATH wl_isr(int irq, void *dev_id) -{ - struct wl_info *wl; - bool ours, wantdpc; - unsigned long flags; - - wl = (struct wl_info *) dev_id; - - WL_ISRLOCK(wl, flags); - - /* call common first level interrupt handler */ - ours = wlc_isr(wl->wlc, &wantdpc); - if (ours) { - /* if more to do... */ - if (wantdpc) { - - /* ...and call the second level interrupt handler */ - /* schedule dpc */ - ASSERT(wl->resched == false); - tasklet_schedule(&wl->tasklet); - } - } - - WL_ISRUNLOCK(wl, flags); - - return IRQ_RETVAL(ours); -} - -static void BCMFASTPATH wl_dpc(unsigned long data) -{ - struct wl_info *wl; - - wl = (struct wl_info *) data; - - WL_LOCK(wl); - - /* call the common second level interrupt handler */ - if (wl->pub->up) { - if (wl->resched) { - unsigned long flags; - - INT_LOCK(wl, flags); - wlc_intrsupd(wl->wlc); - INT_UNLOCK(wl, flags); - } - - wl->resched = wlc_dpc(wl->wlc, true); - } - - /* wlc_dpc() may bring the driver down */ - if (!wl->pub->up) - goto done; - - /* re-schedule dpc */ - if (wl->resched) - tasklet_schedule(&wl->tasklet); - else { - /* re-enable interrupts */ - wl_intrson(wl); - } - - done: - WL_UNLOCK(wl); -} - -static void wl_link_up(struct wl_info *wl, char *ifname) -{ - WL_ERROR("wl%d: link up (%s)\n", wl->pub->unit, ifname); -} - -static void wl_link_down(struct wl_info *wl, char *ifname) -{ - WL_ERROR("wl%d: link down (%s)\n", wl->pub->unit, ifname); -} - -void wl_event(struct wl_info *wl, char *ifname, wlc_event_t *e) -{ - - switch (e->event.event_type) { - case WLC_E_LINK: - case WLC_E_NDIS_LINK: - if (e->event.flags & WLC_EVENT_MSG_LINK) - wl_link_up(wl, ifname); - else - wl_link_down(wl, ifname); - break; - case WLC_E_RADIO: - break; - } -} - -static void wl_timer(unsigned long data) -{ - _wl_timer((wl_timer_t *) data); -} - -static void _wl_timer(wl_timer_t *t) -{ - WL_LOCK(t->wl); - - if (t->set) { - if (t->periodic) { - t->timer.expires = jiffies + t->ms * HZ / 1000; - atomic_inc(&t->wl->callbacks); - add_timer(&t->timer); - t->set = true; - } else - t->set = false; - - t->fn(t->arg); - } - - atomic_dec(&t->wl->callbacks); - - WL_UNLOCK(t->wl); -} - -wl_timer_t *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg), void *arg, - const char *name) -{ - wl_timer_t *t; - - t = kmalloc(sizeof(wl_timer_t), GFP_ATOMIC); - if (!t) { - WL_ERROR("wl%d: wl_init_timer: out of memory\n", wl->pub->unit); - return 0; - } - - memset(t, 0, sizeof(wl_timer_t)); - - init_timer(&t->timer); - t->timer.data = (unsigned long) t; - t->timer.function = wl_timer; - t->wl = wl; - t->fn = fn; - t->arg = arg; - t->next = wl->timers; - wl->timers = t; - -#ifdef BCMDBG - t->name = kmalloc(strlen(name) + 1, GFP_ATOMIC); - if (t->name) - strcpy(t->name, name); -#endif - - return t; -} - -/* BMAC_NOTE: Add timer adds only the kernel timer since it's going to be more accurate - * as well as it's easier to make it periodic - */ -void wl_add_timer(struct wl_info *wl, wl_timer_t *t, uint ms, int periodic) -{ -#ifdef BCMDBG - if (t->set) { - WL_ERROR("%s: Already set. Name: %s, per %d\n", - __func__, t->name, periodic); - } -#endif - ASSERT(!t->set); - - t->ms = ms; - t->periodic = (bool) periodic; - t->set = true; - t->timer.expires = jiffies + ms * HZ / 1000; - - atomic_inc(&wl->callbacks); - add_timer(&t->timer); -} - -/* return true if timer successfully deleted, false if still pending */ -bool wl_del_timer(struct wl_info *wl, wl_timer_t *t) -{ - if (t->set) { - t->set = false; - if (!del_timer(&t->timer)) { - return false; - } - atomic_dec(&wl->callbacks); - } - - return true; -} - -void wl_free_timer(struct wl_info *wl, wl_timer_t *t) -{ - wl_timer_t *tmp; - - /* delete the timer in case it is active */ - wl_del_timer(wl, t); - - if (wl->timers == t) { - wl->timers = wl->timers->next; -#ifdef BCMDBG - if (t->name) - kfree(t->name); -#endif - kfree(t); - return; - - } - - tmp = wl->timers; - while (tmp) { - if (tmp->next == t) { - tmp->next = t->next; -#ifdef BCMDBG - if (t->name) - kfree(t->name); -#endif - kfree(t); - return; - } - tmp = tmp->next; - } - -} - -static int wl_linux_watchdog(void *ctx) -{ - struct wl_info *wl = (struct wl_info *) ctx; - struct net_device_stats *stats = NULL; - uint id; - /* refresh stats */ - if (wl->pub->up) { - ASSERT(wl->stats_id < 2); - - id = 1 - wl->stats_id; - - stats = &wl->stats_watchdog[id]; - stats->rx_packets = WLCNTVAL(wl->pub->_cnt->rxframe); - stats->tx_packets = WLCNTVAL(wl->pub->_cnt->txframe); - stats->rx_bytes = WLCNTVAL(wl->pub->_cnt->rxbyte); - stats->tx_bytes = WLCNTVAL(wl->pub->_cnt->txbyte); - stats->rx_errors = WLCNTVAL(wl->pub->_cnt->rxerror); - stats->tx_errors = WLCNTVAL(wl->pub->_cnt->txerror); - stats->collisions = 0; - - stats->rx_length_errors = 0; - stats->rx_over_errors = WLCNTVAL(wl->pub->_cnt->rxoflo); - stats->rx_crc_errors = WLCNTVAL(wl->pub->_cnt->rxcrc); - stats->rx_frame_errors = 0; - stats->rx_fifo_errors = WLCNTVAL(wl->pub->_cnt->rxoflo); - stats->rx_missed_errors = 0; - - stats->tx_fifo_errors = WLCNTVAL(wl->pub->_cnt->txuflo); - - wl->stats_id = id; - - } - - return 0; -} - -struct wl_fw_hdr { - u32 offset; - u32 len; - u32 idx; -}; - -char *wl_firmwares[WL_MAX_FW] = { - "brcm/bcm43xx", - NULL -}; - -int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx) -{ - int i, entry; - const u8 *pdata; - struct wl_fw_hdr *hdr; - for (i = 0; i < wl->fw.fw_cnt; i++) { - hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data; - for (entry = 0; entry < wl->fw.hdr_num_entries[i]; - entry++, hdr++) { - if (hdr->idx == idx) { - pdata = wl->fw.fw_bin[i]->data + hdr->offset; - *pbuf = kmalloc(hdr->len, GFP_ATOMIC); - if (*pbuf == NULL) { - printf("fail to alloc %d bytes\n", - hdr->len); - } - bcopy(pdata, *pbuf, hdr->len); - return 0; - } - } - } - printf("ERROR: ucode buf tag:%d can not be found!\n", idx); - *pbuf = NULL; - return -1; -} - -int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx) -{ - int i, entry; - const u8 *pdata; - struct wl_fw_hdr *hdr; - for (i = 0; i < wl->fw.fw_cnt; i++) { - hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data; - for (entry = 0; entry < wl->fw.hdr_num_entries[i]; - entry++, hdr++) { - if (hdr->idx == idx) { - pdata = wl->fw.fw_bin[i]->data + hdr->offset; - ASSERT(hdr->len == 4); - *data = *((u32 *) pdata); - return 0; - } - } - } - printf("ERROR: ucode tag:%d can not be found!\n", idx); - return -1; -} - -static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) -{ - int status; - struct device *device = &pdev->dev; - char fw_name[100]; - int i; - - memset((void *)&wl->fw, 0, sizeof(struct wl_firmware)); - for (i = 0; i < WL_MAX_FW; i++) { - if (wl_firmwares[i] == NULL) - break; - sprintf(fw_name, "%s-%d.fw", wl_firmwares[i], - UCODE_LOADER_API_VER); - WL_NONE("request fw %s\n", fw_name); - status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); - if (status) { - printf("%s: fail to load firmware %s\n", - KBUILD_MODNAME, fw_name); - wl_release_fw(wl); - return status; - } - WL_NONE("request fw %s\n", fw_name); - sprintf(fw_name, "%s_hdr-%d.fw", wl_firmwares[i], - UCODE_LOADER_API_VER); - status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); - if (status) { - printf("%s: fail to load firmware %s\n", - KBUILD_MODNAME, fw_name); - wl_release_fw(wl); - return status; - } - wl->fw.hdr_num_entries[i] = - wl->fw.fw_hdr[i]->size / (sizeof(struct wl_fw_hdr)); - WL_NONE("request fw %s find: %d entries\n", - fw_name, wl->fw.hdr_num_entries[i]); - } - wl->fw.fw_cnt = i; - return wl_ucode_data_init(wl); -} - -void wl_ucode_free_buf(void *p) -{ - kfree(p); -} - -static void wl_release_fw(struct wl_info *wl) -{ - int i; - for (i = 0; i < WL_MAX_FW; i++) { - release_firmware(wl->fw.fw_bin[i]); - release_firmware(wl->fw.fw_hdr[i]); - } -} - - -/* - * checks validity of all firmware images loaded from user space - */ -int wl_check_firmwares(struct wl_info *wl) -{ - int i; - int entry; - int rc = 0; - const struct firmware *fw; - const struct firmware *fw_hdr; - struct wl_fw_hdr *ucode_hdr; - for (i = 0; i < WL_MAX_FW && rc == 0; i++) { - fw = wl->fw.fw_bin[i]; - fw_hdr = wl->fw.fw_hdr[i]; - if (fw == NULL && fw_hdr == NULL) { - break; - } else if (fw == NULL || fw_hdr == NULL) { - WL_ERROR("%s: invalid bin/hdr fw\n", __func__); - rc = -EBADF; - } else if (fw_hdr->size % sizeof(struct wl_fw_hdr)) { - WL_ERROR("%s: non integral fw hdr file size %d/%zu\n", - __func__, fw_hdr->size, - sizeof(struct wl_fw_hdr)); - rc = -EBADF; - } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) { - WL_ERROR("%s: out of bounds fw file size %d\n", - __func__, fw->size); - rc = -EBADF; - } else { - /* check if ucode section overruns firmware image */ - ucode_hdr = (struct wl_fw_hdr *)fw_hdr->data; - for (entry = 0; entry < wl->fw.hdr_num_entries[i] && rc; - entry++, ucode_hdr++) { - if (ucode_hdr->offset + ucode_hdr->len > - fw->size) { - WL_ERROR("%s: conflicting bin/hdr\n", - __func__); - rc = -EBADF; - } - } - } - } - if (rc == 0 && wl->fw.fw_cnt != i) { - WL_ERROR("%s: invalid fw_cnt=%d\n", __func__, wl->fw.fw_cnt); - rc = -EBADF; - } - return rc; -} - diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wl_mac80211.h b/drivers/staging/brcm80211/brcmsmac/sys/wl_mac80211.h deleted file mode 100644 index bb39b7705947..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wl_mac80211.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wl_mac80211_h_ -#define _wl_mac80211_h_ - -#include - -/* BMAC Note: High-only driver is no longer working in softirq context as it needs to block and - * sleep so perimeter lock has to be a semaphore instead of spinlock. This requires timers to be - * submitted to workqueue instead of being on kernel timer - */ -typedef struct wl_timer { - struct timer_list timer; - struct wl_info *wl; - void (*fn) (void *); - void *arg; /* argument to fn */ - uint ms; - bool periodic; - bool set; - struct wl_timer *next; -#ifdef BCMDBG - char *name; /* Description of the timer */ -#endif -} wl_timer_t; - -/* contortion to call functions at safe time */ -/* In 2.6.20 kernels work functions get passed a pointer to the struct work, so things - * will continue to work as long as the work structure is the first component of the task structure. - */ -typedef struct wl_task { - struct work_struct work; - void *context; -} wl_task_t; - -struct wl_if { - uint subunit; /* WDS/BSS unit */ - struct pci_dev *pci_dev; -}; - -#define WL_MAX_FW 4 -struct wl_firmware { - u32 fw_cnt; - const struct firmware *fw_bin[WL_MAX_FW]; - const struct firmware *fw_hdr[WL_MAX_FW]; - u32 hdr_num_entries[WL_MAX_FW]; -}; - -struct wl_info { - struct wlc_pub *pub; /* pointer to public wlc state */ - void *wlc; /* pointer to private common os-independent data */ - struct osl_info *osh; /* pointer to os handler */ - u32 magic; - - int irq; - - spinlock_t lock; /* per-device perimeter lock */ - spinlock_t isr_lock; /* per-device ISR synchronization lock */ - uint bcm_bustype; /* bus type */ - bool piomode; /* set from insmod argument */ - void *regsva; /* opaque chip registers virtual address */ - atomic_t callbacks; /* # outstanding callback functions */ - struct wl_timer *timers; /* timer cleanup queue */ - struct tasklet_struct tasklet; /* dpc tasklet */ - bool resched; /* dpc needs to be and is rescheduled */ -#ifdef LINUXSTA_PS - u32 pci_psstate[16]; /* pci ps-state save/restore */ -#endif - /* RPC, handle, lock, txq, workitem */ - uint stats_id; /* the current set of stats */ - /* ping-pong stats counters updated by Linux watchdog */ - struct net_device_stats stats_watchdog[2]; - struct wl_firmware fw; -}; - -#define WL_LOCK(wl) spin_lock_bh(&(wl)->lock) -#define WL_UNLOCK(wl) spin_unlock_bh(&(wl)->lock) - -/* locking from inside wl_isr */ -#define WL_ISRLOCK(wl, flags) do {spin_lock(&(wl)->isr_lock); (void)(flags); } while (0) -#define WL_ISRUNLOCK(wl, flags) do {spin_unlock(&(wl)->isr_lock); (void)(flags); } while (0) - -/* locking under WL_LOCK() to synchronize with wl_isr */ -#define INT_LOCK(wl, flags) spin_lock_irqsave(&(wl)->isr_lock, flags) -#define INT_UNLOCK(wl, flags) spin_unlock_irqrestore(&(wl)->isr_lock, flags) - -#ifndef PCI_D0 -#define PCI_D0 0 -#endif - -#ifndef PCI_D3hot -#define PCI_D3hot 3 -#endif - -/* exported functions */ - -extern irqreturn_t wl_isr(int irq, void *dev_id); - -extern int __devinit wl_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent); -extern void wl_free(struct wl_info *wl); -extern int wl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); - -#endif /* _wl_mac80211_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wl_ucode.h b/drivers/staging/brcm80211/brcmsmac/sys/wl_ucode.h deleted file mode 100644 index 2a0f4028f6f3..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wl_ucode.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define MIN_FW_SIZE 40000 /* minimum firmware file size in bytes */ -#define MAX_FW_SIZE 150000 - -typedef struct d11init { - u16 addr; - u16 size; - u32 value; -} d11init_t; - -extern d11init_t *d11lcn0bsinitvals24; -extern d11init_t *d11lcn0initvals24; -extern d11init_t *d11lcn1bsinitvals24; -extern d11init_t *d11lcn1initvals24; -extern d11init_t *d11lcn2bsinitvals24; -extern d11init_t *d11lcn2initvals24; -extern d11init_t *d11n0absinitvals16; -extern d11init_t *d11n0bsinitvals16; -extern d11init_t *d11n0initvals16; -extern u32 *bcm43xx_16_mimo; -extern u32 bcm43xx_16_mimosz; -extern u32 *bcm43xx_24_lcn; -extern u32 bcm43xx_24_lcnsz; -extern u32 *bcm43xx_bommajor; -extern u32 *bcm43xx_bomminor; - -extern int wl_ucode_data_init(struct wl_info *wl); -extern void wl_ucode_data_free(void); - -extern int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, unsigned int idx); -extern int wl_ucode_init_uint(struct wl_info *wl, unsigned *data, - unsigned int idx); -extern void wl_ucode_free_buf(void *); -extern int wl_check_firmwares(struct wl_info *wl); diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wl_ucode_loader.c b/drivers/staging/brcm80211/brcmsmac/sys/wl_ucode_loader.c deleted file mode 100644 index 23e10f3dec0d..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wl_ucode_loader.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include - - - -d11init_t *d11lcn0bsinitvals24; -d11init_t *d11lcn0initvals24; -d11init_t *d11lcn1bsinitvals24; -d11init_t *d11lcn1initvals24; -d11init_t *d11lcn2bsinitvals24; -d11init_t *d11lcn2initvals24; -d11init_t *d11n0absinitvals16; -d11init_t *d11n0bsinitvals16; -d11init_t *d11n0initvals16; -u32 *bcm43xx_16_mimo; -u32 bcm43xx_16_mimosz; -u32 *bcm43xx_24_lcn; -u32 bcm43xx_24_lcnsz; -u32 *bcm43xx_bommajor; -u32 *bcm43xx_bomminor; - -int wl_ucode_data_init(struct wl_info *wl) -{ - int rc; - rc = wl_check_firmwares(wl); - if (rc < 0) - return rc; - wl_ucode_init_buf(wl, (void **)&d11lcn0bsinitvals24, - D11LCN0BSINITVALS24); - wl_ucode_init_buf(wl, (void **)&d11lcn0initvals24, D11LCN0INITVALS24); - wl_ucode_init_buf(wl, (void **)&d11lcn1bsinitvals24, - D11LCN1BSINITVALS24); - wl_ucode_init_buf(wl, (void **)&d11lcn1initvals24, D11LCN1INITVALS24); - wl_ucode_init_buf(wl, (void **)&d11lcn2bsinitvals24, - D11LCN2BSINITVALS24); - wl_ucode_init_buf(wl, (void **)&d11lcn2initvals24, D11LCN2INITVALS24); - wl_ucode_init_buf(wl, (void **)&d11n0absinitvals16, D11N0ABSINITVALS16); - wl_ucode_init_buf(wl, (void **)&d11n0bsinitvals16, D11N0BSINITVALS16); - wl_ucode_init_buf(wl, (void **)&d11n0initvals16, D11N0INITVALS16); - wl_ucode_init_buf(wl, (void **)&bcm43xx_16_mimo, - D11UCODE_OVERSIGHT16_MIMO); - wl_ucode_init_uint(wl, &bcm43xx_16_mimosz, D11UCODE_OVERSIGHT16_MIMOSZ); - wl_ucode_init_buf(wl, (void **)&bcm43xx_24_lcn, - D11UCODE_OVERSIGHT24_LCN); - wl_ucode_init_uint(wl, &bcm43xx_24_lcnsz, D11UCODE_OVERSIGHT24_LCNSZ); - wl_ucode_init_buf(wl, (void **)&bcm43xx_bommajor, - D11UCODE_OVERSIGHT_BOMMAJOR); - wl_ucode_init_buf(wl, (void **)&bcm43xx_bomminor, - D11UCODE_OVERSIGHT_BOMMINOR); - - return 0; -} - -void wl_ucode_data_free(void) -{ - wl_ucode_free_buf((void *)d11lcn0bsinitvals24); - wl_ucode_free_buf((void *)d11lcn0initvals24); - wl_ucode_free_buf((void *)d11lcn1bsinitvals24); - wl_ucode_free_buf((void *)d11lcn1initvals24); - wl_ucode_free_buf((void *)d11lcn2bsinitvals24); - wl_ucode_free_buf((void *)d11lcn2initvals24); - wl_ucode_free_buf((void *)d11n0absinitvals16); - wl_ucode_free_buf((void *)d11n0bsinitvals16); - wl_ucode_free_buf((void *)d11n0initvals16); - wl_ucode_free_buf((void *)bcm43xx_16_mimo); - wl_ucode_free_buf((void *)bcm43xx_24_lcn); - wl_ucode_free_buf((void *)bcm43xx_bommajor); - wl_ucode_free_buf((void *)bcm43xx_bomminor); - - return; -} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.c deleted file mode 100644 index 7a9fdbb5daee..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, - uint *err, uint devid); -static void wlc_pub_mfree(struct osl_info *osh, struct wlc_pub *pub); -static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid); - -void *wlc_calloc(struct osl_info *osh, uint unit, uint size) -{ - void *item; - - item = kzalloc(size, GFP_ATOMIC); - if (item == NULL) - WL_ERROR("wl%d: %s: out of memory\n", unit, __func__); - return item; -} - -void wlc_tunables_init(wlc_tunables_t *tunables, uint devid) -{ - tunables->ntxd = NTXD; - tunables->nrxd = NRXD; - tunables->rxbufsz = RXBUFSZ; - tunables->nrxbufpost = NRXBUFPOST; - tunables->maxscb = MAXSCB; - tunables->ampdunummpdu = AMPDU_NUM_MPDU; - tunables->maxpktcb = MAXPKTCB; - tunables->maxucodebss = WLC_MAX_UCODE_BSS; - tunables->maxucodebss4 = WLC_MAX_UCODE_BSS4; - tunables->maxbss = MAXBSS; - tunables->datahiwat = WLC_DATAHIWAT; - tunables->ampdudatahiwat = WLC_AMPDUDATAHIWAT; - tunables->rxbnd = RXBND; - tunables->txsbnd = TXSBND; -} - -static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, - uint *err, uint devid) -{ - struct wlc_pub *pub; - - pub = (struct wlc_pub *) wlc_calloc(osh, unit, sizeof(struct wlc_pub)); - if (pub == NULL) { - *err = 1001; - goto fail; - } - - pub->tunables = (wlc_tunables_t *)wlc_calloc(osh, unit, - sizeof(wlc_tunables_t)); - if (pub->tunables == NULL) { - *err = 1028; - goto fail; - } - - /* need to init the tunables now */ - wlc_tunables_init(pub->tunables, devid); - - pub->multicast = (u8 *)wlc_calloc(osh, unit, - (ETH_ALEN * MAXMULTILIST)); - if (pub->multicast == NULL) { - *err = 1003; - goto fail; - } - - return pub; - - fail: - wlc_pub_mfree(osh, pub); - return NULL; -} - -static void wlc_pub_mfree(struct osl_info *osh, struct wlc_pub *pub) -{ - if (pub == NULL) - return; - - if (pub->multicast) - kfree(pub->multicast); - if (pub->tunables) { - kfree(pub->tunables); - pub->tunables = NULL; - } - - kfree(pub); -} - -wlc_bsscfg_t *wlc_bsscfg_malloc(struct osl_info *osh, uint unit) -{ - wlc_bsscfg_t *cfg; - - cfg = (wlc_bsscfg_t *) wlc_calloc(osh, unit, sizeof(wlc_bsscfg_t)); - if (cfg == NULL) - goto fail; - - cfg->current_bss = (wlc_bss_info_t *)wlc_calloc(osh, unit, - sizeof(wlc_bss_info_t)); - if (cfg->current_bss == NULL) - goto fail; - - return cfg; - - fail: - wlc_bsscfg_mfree(osh, cfg); - return NULL; -} - -void wlc_bsscfg_mfree(struct osl_info *osh, wlc_bsscfg_t *cfg) -{ - if (cfg == NULL) - return; - - if (cfg->maclist) { - kfree(cfg->maclist); - cfg->maclist = NULL; - } - - if (cfg->current_bss != NULL) { - wlc_bss_info_t *current_bss = cfg->current_bss; - kfree(current_bss); - cfg->current_bss = NULL; - } - - kfree(cfg); -} - -void wlc_bsscfg_ID_assign(struct wlc_info *wlc, wlc_bsscfg_t *bsscfg) -{ - bsscfg->ID = wlc->next_bsscfg_ID; - wlc->next_bsscfg_ID++; -} - -/* - * The common driver entry routine. Error codes should be unique - */ -struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, - uint devid) -{ - struct wlc_info *wlc; - - wlc = (struct wlc_info *) wlc_calloc(osh, unit, - sizeof(struct wlc_info)); - if (wlc == NULL) { - *err = 1002; - goto fail; - } - - wlc->hwrxoff = WL_HWRXOFF; - - /* allocate struct wlc_pub state structure */ - wlc->pub = wlc_pub_malloc(osh, unit, err, devid); - if (wlc->pub == NULL) { - *err = 1003; - goto fail; - } - wlc->pub->wlc = wlc; - - /* allocate struct wlc_hw_info state structure */ - - wlc->hw = (struct wlc_hw_info *)wlc_calloc(osh, unit, - sizeof(struct wlc_hw_info)); - if (wlc->hw == NULL) { - *err = 1005; - goto fail; - } - wlc->hw->wlc = wlc; - - wlc->hw->bandstate[0] = (wlc_hwband_t *)wlc_calloc(osh, unit, - (sizeof(wlc_hwband_t) * MAXBANDS)); - if (wlc->hw->bandstate[0] == NULL) { - *err = 1006; - goto fail; - } else { - int i; - - for (i = 1; i < MAXBANDS; i++) { - wlc->hw->bandstate[i] = (wlc_hwband_t *) - ((unsigned long)wlc->hw->bandstate[0] + - (sizeof(wlc_hwband_t) * i)); - } - } - - wlc->modulecb = (modulecb_t *)wlc_calloc(osh, unit, - sizeof(modulecb_t) * WLC_MAXMODULES); - if (wlc->modulecb == NULL) { - *err = 1009; - goto fail; - } - - wlc->default_bss = (wlc_bss_info_t *)wlc_calloc(osh, unit, - sizeof(wlc_bss_info_t)); - if (wlc->default_bss == NULL) { - *err = 1010; - goto fail; - } - - wlc->cfg = wlc_bsscfg_malloc(osh, unit); - if (wlc->cfg == NULL) { - *err = 1011; - goto fail; - } - wlc_bsscfg_ID_assign(wlc, wlc->cfg); - - wlc->pkt_callback = (pkt_cb_t *)wlc_calloc(osh, unit, - (sizeof(pkt_cb_t) * (wlc->pub->tunables->maxpktcb + 1))); - if (wlc->pkt_callback == NULL) { - *err = 1013; - goto fail; - } - - wlc->wsec_def_keys[0] = (wsec_key_t *)wlc_calloc(osh, unit, - (sizeof(wsec_key_t) * WLC_DEFAULT_KEYS)); - if (wlc->wsec_def_keys[0] == NULL) { - *err = 1015; - goto fail; - } else { - int i; - for (i = 1; i < WLC_DEFAULT_KEYS; i++) { - wlc->wsec_def_keys[i] = (wsec_key_t *) - ((unsigned long)wlc->wsec_def_keys[0] + - (sizeof(wsec_key_t) * i)); - } - } - - wlc->protection = (wlc_protection_t *)wlc_calloc(osh, unit, - sizeof(wlc_protection_t)); - if (wlc->protection == NULL) { - *err = 1016; - goto fail; - } - - wlc->stf = (wlc_stf_t *)wlc_calloc(osh, unit, sizeof(wlc_stf_t)); - if (wlc->stf == NULL) { - *err = 1017; - goto fail; - } - - wlc->bandstate[0] = (struct wlcband *)wlc_calloc(osh, unit, - (sizeof(struct wlcband)*MAXBANDS)); - if (wlc->bandstate[0] == NULL) { - *err = 1025; - goto fail; - } else { - int i; - - for (i = 1; i < MAXBANDS; i++) { - wlc->bandstate[i] = - (struct wlcband *) ((unsigned long)wlc->bandstate[0] - + (sizeof(struct wlcband)*i)); - } - } - - wlc->corestate = (struct wlccore *)wlc_calloc(osh, unit, - sizeof(struct wlccore)); - if (wlc->corestate == NULL) { - *err = 1026; - goto fail; - } - - wlc->corestate->macstat_snapshot = - (macstat_t *)wlc_calloc(osh, unit, sizeof(macstat_t)); - if (wlc->corestate->macstat_snapshot == NULL) { - *err = 1027; - goto fail; - } - - return wlc; - - fail: - wlc_detach_mfree(wlc, osh); - return NULL; -} - -void wlc_detach_mfree(struct wlc_info *wlc, struct osl_info *osh) -{ - if (wlc == NULL) - return; - - if (wlc->modulecb) { - kfree(wlc->modulecb); - wlc->modulecb = NULL; - } - - if (wlc->default_bss) { - kfree(wlc->default_bss); - wlc->default_bss = NULL; - } - if (wlc->cfg) { - wlc_bsscfg_mfree(osh, wlc->cfg); - wlc->cfg = NULL; - } - - if (wlc->pkt_callback && wlc->pub && wlc->pub->tunables) { - kfree(wlc->pkt_callback); - wlc->pkt_callback = NULL; - } - - if (wlc->wsec_def_keys[0]) - kfree(wlc->wsec_def_keys[0]); - if (wlc->protection) { - kfree(wlc->protection); - wlc->protection = NULL; - } - - if (wlc->stf) { - kfree(wlc->stf); - wlc->stf = NULL; - } - - if (wlc->bandstate[0]) - kfree(wlc->bandstate[0]); - - if (wlc->corestate) { - if (wlc->corestate->macstat_snapshot) { - kfree(wlc->corestate->macstat_snapshot); wlc->corestate->macstat_snapshot = NULL; - } - kfree(wlc->corestate); - wlc->corestate = NULL; - } - - if (wlc->pub) { - /* free pub struct */ - wlc_pub_mfree(osh, wlc->pub); - wlc->pub = NULL; - } - - if (wlc->hw) { - if (wlc->hw->bandstate[0]) { - kfree(wlc->hw->bandstate[0]); - wlc->hw->bandstate[0] = NULL; - } - - /* free hw struct */ - kfree(wlc->hw); - wlc->hw = NULL; - } - - /* free the wlc */ - kfree(wlc); - wlc = NULL; -} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.h deleted file mode 100644 index ac34f782b400..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_alloc.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -extern void *wlc_calloc(struct osl_info *osh, uint unit, uint size); - -extern struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, - uint *err, uint devid); -extern void wlc_detach_mfree(struct wlc_info *wlc, struct osl_info *osh); - -struct wlc_bsscfg; -extern struct wlc_bsscfg *wlc_bsscfg_malloc(struct osl_info *osh, uint unit); -extern void wlc_bsscfg_mfree(struct osl_info *osh, struct wlc_bsscfg *cfg); diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.c deleted file mode 100644 index 8e1011203481..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.c +++ /dev/null @@ -1,1356 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define AMPDU_MAX_MPDU 32 /* max number of mpdus in an ampdu */ -#define AMPDU_NUM_MPDU_LEGACY 16 /* max number of mpdus in an ampdu to a legacy */ -#define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */ -#define AMPDU_TX_BA_DEF_WSIZE 64 /* default Tx ba window size (in pdu) */ -#define AMPDU_RX_BA_DEF_WSIZE 64 /* max Rx ba window size (in pdu) */ -#define AMPDU_RX_BA_MAX_WSIZE 64 /* default Rx ba window size (in pdu) */ -#define AMPDU_MAX_DUR 5 /* max dur of tx ampdu (in msec) */ -#define AMPDU_DEF_RETRY_LIMIT 5 /* default tx retry limit */ -#define AMPDU_DEF_RR_RETRY_LIMIT 2 /* default tx retry limit at reg rate */ -#define AMPDU_DEF_TXPKT_WEIGHT 2 /* default weight of ampdu in txfifo */ -#define AMPDU_DEF_FFPLD_RSVD 2048 /* default ffpld reserved bytes */ -#define AMPDU_INI_FREE 10 /* # of inis to be freed on detach */ -#define AMPDU_SCB_MAX_RELEASE 20 /* max # of mpdus released at a time */ - -#define NUM_FFPLD_FIFO 4 /* number of fifo concerned by pre-loading */ -#define FFPLD_TX_MAX_UNFL 200 /* default value of the average number of ampdu - * without underflows - */ -#define FFPLD_MPDU_SIZE 1800 /* estimate of maximum mpdu size */ -#define FFPLD_MAX_MCS 23 /* we don't deal with mcs 32 */ -#define FFPLD_PLD_INCR 1000 /* increments in bytes */ -#define FFPLD_MAX_AMPDU_CNT 5000 /* maximum number of ampdu we - * accumulate between resets. - */ - -#define TX_SEQ_TO_INDEX(seq) ((seq) % AMPDU_TX_BA_MAX_WSIZE) - -/* max possible overhead per mpdu in the ampdu; 3 is for roundup if needed */ -#define AMPDU_MAX_MPDU_OVERHEAD (FCS_LEN + DOT11_ICV_AES_LEN +\ - AMPDU_DELIMITER_LEN + 3\ - + DOT11_A4_HDR_LEN + DOT11_QOS_LEN + DOT11_IV_MAX_LEN) - -#ifdef BCMDBG -u32 wl_ampdu_dbg = - WL_AMPDU_UPDN_VAL | - WL_AMPDU_ERR_VAL | - WL_AMPDU_TX_VAL | - WL_AMPDU_RX_VAL | - WL_AMPDU_CTL_VAL | - WL_AMPDU_HW_VAL | WL_AMPDU_HWTXS_VAL | WL_AMPDU_HWDBG_VAL; -#endif - -/* structure to hold tx fifo information and pre-loading state - * counters specific to tx underflows of ampdus - * some counters might be redundant with the ones in wlc or ampdu structures. - * This allows to maintain a specific state independantly of - * how often and/or when the wlc counters are updated. - */ -typedef struct wlc_fifo_info { - u16 ampdu_pld_size; /* number of bytes to be pre-loaded */ - u8 mcs2ampdu_table[FFPLD_MAX_MCS + 1]; /* per-mcs max # of mpdus in an ampdu */ - u16 prev_txfunfl; /* num of underflows last read from the HW macstats counter */ - u32 accum_txfunfl; /* num of underflows since we modified pld params */ - u32 accum_txampdu; /* num of tx ampdu since we modified pld params */ - u32 prev_txampdu; /* previous reading of tx ampdu */ - u32 dmaxferrate; /* estimated dma avg xfer rate in kbits/sec */ -} wlc_fifo_info_t; - -/* AMPDU module specific state */ -struct ampdu_info { - struct wlc_info *wlc; /* pointer to main wlc structure */ - int scb_handle; /* scb cubby handle to retrieve data from scb */ - u8 ini_enable[AMPDU_MAX_SCB_TID]; /* per-tid initiator enable/disable of ampdu */ - u8 ba_tx_wsize; /* Tx ba window size (in pdu) */ - u8 ba_rx_wsize; /* Rx ba window size (in pdu) */ - u8 retry_limit; /* mpdu transmit retry limit */ - u8 rr_retry_limit; /* mpdu transmit retry limit at regular rate */ - u8 retry_limit_tid[AMPDU_MAX_SCB_TID]; /* per-tid mpdu transmit retry limit */ - /* per-tid mpdu transmit retry limit at regular rate */ - u8 rr_retry_limit_tid[AMPDU_MAX_SCB_TID]; - u8 mpdu_density; /* min mpdu spacing (0-7) ==> 2^(x-1)/8 usec */ - s8 max_pdu; /* max pdus allowed in ampdu */ - u8 dur; /* max duration of an ampdu (in msec) */ - u8 txpkt_weight; /* weight of ampdu in txfifo; reduces rate lag */ - u8 rx_factor; /* maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes */ - u32 ffpld_rsvd; /* number of bytes to reserve for preload */ - u32 max_txlen[MCS_TABLE_SIZE][2][2]; /* max size of ampdu per mcs, bw and sgi */ - void *ini_free[AMPDU_INI_FREE]; /* array of ini's to be freed on detach */ - bool mfbr; /* enable multiple fallback rate */ - u32 tx_max_funl; /* underflows should be kept such that - * (tx_max_funfl*underflows) < tx frames - */ - wlc_fifo_info_t fifo_tb[NUM_FFPLD_FIFO]; /* table of fifo infos */ - -}; - -#define AMPDU_CLEANUPFLAG_RX (0x1) -#define AMPDU_CLEANUPFLAG_TX (0x2) - -#define SCB_AMPDU_CUBBY(ampdu, scb) (&(scb->scb_ampdu)) -#define SCB_AMPDU_INI(scb_ampdu, tid) (&(scb_ampdu->ini[tid])) - -static void wlc_ffpld_init(struct ampdu_info *ampdu); -static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int f); -static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f); - -static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu, - scb_ampdu_t *scb_ampdu, - u8 tid, bool override); -static void ampdu_cleanup_tid_ini(struct ampdu_info *ampdu, - scb_ampdu_t *scb_ampdu, - u8 tid, bool force); -static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur); -static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb); -static void scb_ampdu_update_config_all(struct ampdu_info *ampdu); - -#define wlc_ampdu_txflowcontrol(a, b, c) do {} while (0) - -static void wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, - struct scb *scb, - struct sk_buff *p, tx_status_t *txs, - u32 frmtxstatus, u32 frmtxstatus2); - -static inline u16 pkt_txh_seqnum(struct wlc_info *wlc, struct sk_buff *p) -{ - d11txh_t *txh; - struct ieee80211_hdr *h; - txh = (d11txh_t *) p->data; - h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); - return ltoh16(h->seq_ctrl) >> SEQNUM_SHIFT; -} - -struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc) -{ - struct ampdu_info *ampdu; - int i; - - /* some code depends on packed structures */ - ASSERT(DOT11_MAXNUMFRAGS == NBITS(u16)); - ASSERT(ISPOWEROF2(AMPDU_TX_BA_MAX_WSIZE)); - ASSERT(ISPOWEROF2(AMPDU_RX_BA_MAX_WSIZE)); - ASSERT(wlc->pub->tunables->ampdunummpdu <= AMPDU_MAX_MPDU); - ASSERT(wlc->pub->tunables->ampdunummpdu > 0); - - ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC); - if (!ampdu) { - WL_ERROR("wl%d: wlc_ampdu_attach: out of mem\n", - wlc->pub->unit); - return NULL; - } - ampdu->wlc = wlc; - - for (i = 0; i < AMPDU_MAX_SCB_TID; i++) - ampdu->ini_enable[i] = true; - /* Disable ampdu for VO by default */ - ampdu->ini_enable[PRIO_8021D_VO] = false; - ampdu->ini_enable[PRIO_8021D_NC] = false; - - /* Disable ampdu for BK by default since not enough fifo space */ - ampdu->ini_enable[PRIO_8021D_NONE] = false; - ampdu->ini_enable[PRIO_8021D_BK] = false; - - ampdu->ba_tx_wsize = AMPDU_TX_BA_DEF_WSIZE; - ampdu->ba_rx_wsize = AMPDU_RX_BA_DEF_WSIZE; - ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY; - ampdu->max_pdu = AUTO; - ampdu->dur = AMPDU_MAX_DUR; - ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT; - - ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD; - /* bump max ampdu rcv size to 64k for all 11n devices except 4321A0 and 4321A1 */ - if (WLCISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2)) - ampdu->rx_factor = AMPDU_RX_FACTOR_32K; - else - ampdu->rx_factor = AMPDU_RX_FACTOR_64K; - ampdu->retry_limit = AMPDU_DEF_RETRY_LIMIT; - ampdu->rr_retry_limit = AMPDU_DEF_RR_RETRY_LIMIT; - - for (i = 0; i < AMPDU_MAX_SCB_TID; i++) { - ampdu->retry_limit_tid[i] = ampdu->retry_limit; - ampdu->rr_retry_limit_tid[i] = ampdu->rr_retry_limit; - } - - ampdu_update_max_txlen(ampdu, ampdu->dur); - ampdu->mfbr = false; - /* try to set ampdu to the default value */ - wlc_ampdu_set(ampdu, wlc->pub->_ampdu); - - ampdu->tx_max_funl = FFPLD_TX_MAX_UNFL; - wlc_ffpld_init(ampdu); - - return ampdu; -} - -void wlc_ampdu_detach(struct ampdu_info *ampdu) -{ - int i; - - if (!ampdu) - return; - - /* free all ini's which were to be freed on callbacks which were never called */ - for (i = 0; i < AMPDU_INI_FREE; i++) { - if (ampdu->ini_free[i]) { - kfree(ampdu->ini_free[i]); - } - } - - wlc_module_unregister(ampdu->wlc->pub, "ampdu", ampdu); - kfree(ampdu); -} - -void scb_ampdu_cleanup(struct ampdu_info *ampdu, struct scb *scb) -{ - scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - u8 tid; - - WL_AMPDU_UPDN("scb_ampdu_cleanup: enter\n"); - ASSERT(scb_ampdu); - - for (tid = 0; tid < AMPDU_MAX_SCB_TID; tid++) { - ampdu_cleanup_tid_ini(ampdu, scb_ampdu, tid, false); - } -} - -/* reset the ampdu state machine so that it can gracefully handle packets that were - * freed from the dma and tx queues during reinit - */ -void wlc_ampdu_reset(struct ampdu_info *ampdu) -{ - WL_NONE("%s: Entering\n", __func__); -} - -static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb) -{ - scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - int i; - - scb_ampdu->max_pdu = (u8) ampdu->wlc->pub->tunables->ampdunummpdu; - - /* go back to legacy size if some preloading is occuring */ - for (i = 0; i < NUM_FFPLD_FIFO; i++) { - if (ampdu->fifo_tb[i].ampdu_pld_size > FFPLD_PLD_INCR) - scb_ampdu->max_pdu = AMPDU_NUM_MPDU_LEGACY; - } - - /* apply user override */ - if (ampdu->max_pdu != AUTO) - scb_ampdu->max_pdu = (u8) ampdu->max_pdu; - - scb_ampdu->release = min_t(u8, scb_ampdu->max_pdu, AMPDU_SCB_MAX_RELEASE); - - if (scb_ampdu->max_rxlen) - scb_ampdu->release = - min_t(u8, scb_ampdu->release, scb_ampdu->max_rxlen / 1600); - - scb_ampdu->release = min(scb_ampdu->release, - ampdu->fifo_tb[TX_AC_BE_FIFO]. - mcs2ampdu_table[FFPLD_MAX_MCS]); - - ASSERT(scb_ampdu->release); -} - -void scb_ampdu_update_config_all(struct ampdu_info *ampdu) -{ - scb_ampdu_update_config(ampdu, ampdu->wlc->pub->global_scb); -} - -static void wlc_ffpld_init(struct ampdu_info *ampdu) -{ - int i, j; - wlc_fifo_info_t *fifo; - - for (j = 0; j < NUM_FFPLD_FIFO; j++) { - fifo = (ampdu->fifo_tb + j); - fifo->ampdu_pld_size = 0; - for (i = 0; i <= FFPLD_MAX_MCS; i++) - fifo->mcs2ampdu_table[i] = 255; - fifo->dmaxferrate = 0; - fifo->accum_txampdu = 0; - fifo->prev_txfunfl = 0; - fifo->accum_txfunfl = 0; - - } -} - -/* evaluate the dma transfer rate using the tx underflows as feedback. - * If necessary, increase tx fifo preloading. If not enough, - * decrease maximum ampdu size for each mcs till underflows stop - * Return 1 if pre-loading not active, -1 if not an underflow event, - * 0 if pre-loading module took care of the event. - */ -static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) -{ - struct ampdu_info *ampdu = wlc->ampdu; - u32 phy_rate = MCS_RATE(FFPLD_MAX_MCS, true, false); - u32 txunfl_ratio; - u8 max_mpdu; - u32 current_ampdu_cnt = 0; - u16 max_pld_size; - u32 new_txunfl; - wlc_fifo_info_t *fifo = (ampdu->fifo_tb + fid); - uint xmtfifo_sz; - u16 cur_txunfl; - - /* return if we got here for a different reason than underflows */ - cur_txunfl = - wlc_read_shm(wlc, - M_UCODE_MACSTAT + offsetof(macstat_t, txfunfl[fid])); - new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl); - if (new_txunfl == 0) { - WL_FFPLD("check_txunfl : TX status FRAG set but no tx underflows\n"); - return -1; - } - fifo->prev_txfunfl = cur_txunfl; - - if (!ampdu->tx_max_funl) - return 1; - - /* check if fifo is big enough */ - if (wlc_xmtfifo_sz_get(wlc, fid, &xmtfifo_sz)) { - WL_FFPLD("check_txunfl : get xmtfifo_sz failed\n"); - return -1; - } - - if ((TXFIFO_SIZE_UNIT * (u32) xmtfifo_sz) <= ampdu->ffpld_rsvd) - return 1; - - max_pld_size = TXFIFO_SIZE_UNIT * xmtfifo_sz - ampdu->ffpld_rsvd; - fifo->accum_txfunfl += new_txunfl; - - /* we need to wait for at least 10 underflows */ - if (fifo->accum_txfunfl < 10) - return 0; - - WL_FFPLD("ampdu_count %d tx_underflows %d\n", - current_ampdu_cnt, fifo->accum_txfunfl); - - /* - compute the current ratio of tx unfl per ampdu. - When the current ampdu count becomes too - big while the ratio remains small, we reset - the current count in order to not - introduce too big of a latency in detecting a - large amount of tx underflows later. - */ - - txunfl_ratio = current_ampdu_cnt / fifo->accum_txfunfl; - - if (txunfl_ratio > ampdu->tx_max_funl) { - if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT) { - fifo->accum_txfunfl = 0; - } - return 0; - } - max_mpdu = - min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY); - - /* In case max value max_pdu is already lower than - the fifo depth, there is nothing more we can do. - */ - - if (fifo->ampdu_pld_size >= max_mpdu * FFPLD_MPDU_SIZE) { - WL_FFPLD(("tx fifo pld : max ampdu fits in fifo\n)")); - fifo->accum_txfunfl = 0; - return 0; - } - - if (fifo->ampdu_pld_size < max_pld_size) { - - /* increment by TX_FIFO_PLD_INC bytes */ - fifo->ampdu_pld_size += FFPLD_PLD_INCR; - if (fifo->ampdu_pld_size > max_pld_size) - fifo->ampdu_pld_size = max_pld_size; - - /* update scb release size */ - scb_ampdu_update_config_all(ampdu); - - /* - compute a new dma xfer rate for max_mpdu @ max mcs. - This is the minimum dma rate that - can acheive no unferflow condition for the current mpdu size. - */ - /* note : we divide/multiply by 100 to avoid integer overflows */ - fifo->dmaxferrate = - (((phy_rate / 100) * - (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size)) - / (max_mpdu * FFPLD_MPDU_SIZE)) * 100; - - WL_FFPLD("DMA estimated transfer rate %d; pre-load size %d\n", - fifo->dmaxferrate, fifo->ampdu_pld_size); - } else { - - /* decrease ampdu size */ - if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] > 1) { - if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] == 255) - fifo->mcs2ampdu_table[FFPLD_MAX_MCS] = - AMPDU_NUM_MPDU_LEGACY - 1; - else - fifo->mcs2ampdu_table[FFPLD_MAX_MCS] -= 1; - - /* recompute the table */ - wlc_ffpld_calc_mcs2ampdu_table(ampdu, fid); - - /* update scb release size */ - scb_ampdu_update_config_all(ampdu); - } - } - fifo->accum_txfunfl = 0; - return 0; -} - -static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f) -{ - int i; - u32 phy_rate, dma_rate, tmp; - u8 max_mpdu; - wlc_fifo_info_t *fifo = (ampdu->fifo_tb + f); - - /* recompute the dma rate */ - /* note : we divide/multiply by 100 to avoid integer overflows */ - max_mpdu = - min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY); - phy_rate = MCS_RATE(FFPLD_MAX_MCS, true, false); - dma_rate = - (((phy_rate / 100) * - (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size)) - / (max_mpdu * FFPLD_MPDU_SIZE)) * 100; - fifo->dmaxferrate = dma_rate; - - /* fill up the mcs2ampdu table; do not recalc the last mcs */ - dma_rate = dma_rate >> 7; - for (i = 0; i < FFPLD_MAX_MCS; i++) { - /* shifting to keep it within integer range */ - phy_rate = MCS_RATE(i, true, false) >> 7; - if (phy_rate > dma_rate) { - tmp = ((fifo->ampdu_pld_size * phy_rate) / - ((phy_rate - dma_rate) * FFPLD_MPDU_SIZE)) + 1; - tmp = min_t(u32, tmp, 255); - fifo->mcs2ampdu_table[i] = (u8) tmp; - } - } -} - -static void BCMFASTPATH -wlc_ampdu_agg(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p, - uint prec) -{ - scb_ampdu_t *scb_ampdu; - scb_ampdu_tid_ini_t *ini; - u8 tid = (u8) (p->priority); - - scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - - /* initialize initiator on first packet; sends addba req */ - ini = SCB_AMPDU_INI(scb_ampdu, tid); - if (ini->magic != INI_MAGIC) { - ini = wlc_ampdu_init_tid_ini(ampdu, scb_ampdu, tid, false); - } - return; -} - -int BCMFASTPATH -wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, - struct sk_buff **pdu, int prec) -{ - struct wlc_info *wlc; - struct osl_info *osh; - struct sk_buff *p, *pkt[AMPDU_MAX_MPDU]; - u8 tid, ndelim; - int err = 0; - u8 preamble_type = WLC_GF_PREAMBLE; - u8 fbr_preamble_type = WLC_GF_PREAMBLE; - u8 rts_preamble_type = WLC_LONG_PREAMBLE; - u8 rts_fbr_preamble_type = WLC_LONG_PREAMBLE; - - bool rr = true, fbr = false; - uint i, count = 0, fifo, seg_cnt = 0; - u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0; - u32 ampdu_len, maxlen = 0; - d11txh_t *txh = NULL; - u8 *plcp; - struct ieee80211_hdr *h; - struct scb *scb; - scb_ampdu_t *scb_ampdu; - scb_ampdu_tid_ini_t *ini; - u8 mcs = 0; - bool use_rts = false, use_cts = false; - ratespec_t rspec = 0, rspec_fallback = 0; - ratespec_t rts_rspec = 0, rts_rspec_fallback = 0; - u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; - struct ieee80211_rts *rts; - u8 rr_retry_limit; - wlc_fifo_info_t *f; - bool fbr_iscck; - struct ieee80211_tx_info *tx_info; - u16 qlen; - - wlc = ampdu->wlc; - osh = wlc->osh; - p = *pdu; - - ASSERT(p); - - tid = (u8) (p->priority); - ASSERT(tid < AMPDU_MAX_SCB_TID); - - f = ampdu->fifo_tb + prio2fifo[tid]; - - scb = wlc->pub->global_scb; - ASSERT(scb->magic == SCB_MAGIC); - - scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - ASSERT(scb_ampdu); - ini = &scb_ampdu->ini[tid]; - - /* Let pressure continue to build ... */ - qlen = pktq_plen(&qi->q, prec); - if (ini->tx_in_transit > 0 && qlen < scb_ampdu->max_pdu) { - return BCME_BUSY; - } - - wlc_ampdu_agg(ampdu, scb, p, tid); - - if (wlc->block_datafifo) { - WL_ERROR("%s: Fifo blocked\n", __func__); - return BCME_BUSY; - } - rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; - ampdu_len = 0; - dma_len = 0; - while (p) { - struct ieee80211_tx_rate *txrate; - - tx_info = IEEE80211_SKB_CB(p); - txrate = tx_info->status.rates; - - if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { - err = wlc_prep_pdu(wlc, p, &fifo); - } else { - WL_ERROR("%s: AMPDU flag is off!\n", __func__); - *pdu = NULL; - err = 0; - break; - } - - if (err) { - if (err == BCME_BUSY) { - WL_ERROR("wl%d: wlc_sendampdu: prep_xdu retry; seq 0x%x\n", - wlc->pub->unit, seq); - WLCNTINCR(ampdu->cnt->sduretry); - *pdu = p; - break; - } - - /* error in the packet; reject it */ - WL_AMPDU_ERR("wl%d: wlc_sendampdu: prep_xdu rejected; seq 0x%x\n", - wlc->pub->unit, seq); - WLCNTINCR(ampdu->cnt->sdurejected); - - *pdu = NULL; - break; - } - - /* pkt is good to be aggregated */ - ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); - txh = (d11txh_t *) p->data; - plcp = (u8 *) (txh + 1); - h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); - seq = ltoh16(h->seq_ctrl) >> SEQNUM_SHIFT; - index = TX_SEQ_TO_INDEX(seq); - - /* check mcl fields and test whether it can be agg'd */ - mcl = ltoh16(txh->MacTxControlLow); - mcl &= ~TXC_AMPDU_MASK; - fbr_iscck = !(ltoh16(txh->XtraFrameTypes) & 0x3); - ASSERT(!fbr_iscck); - txh->PreloadSize = 0; /* always default to 0 */ - - /* Handle retry limits */ - if (txrate[0].count <= rr_retry_limit) { - txrate[0].count++; - rr = true; - fbr = false; - ASSERT(!fbr); - } else { - fbr = true; - rr = false; - txrate[1].count++; - } - - /* extract the length info */ - len = fbr_iscck ? WLC_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) - : WLC_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); - - /* retrieve null delimiter count */ - ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; - seg_cnt += 1; - - WL_AMPDU_TX("wl%d: wlc_sendampdu: mpdu %d plcp_len %d\n", - wlc->pub->unit, count, len); - - /* - * aggregateable mpdu. For ucode/hw agg, - * test whether need to break or change the epoch - */ - if (count == 0) { - u16 fc; - mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT); - /* refill the bits since might be a retx mpdu */ - mcl |= TXC_STARTMSDU; - rts = (struct ieee80211_rts *)&txh->rts_frame; - fc = ltoh16(rts->frame_control); - if ((fc & FC_KIND_MASK) == FC_RTS) { - mcl |= TXC_SENDRTS; - use_rts = true; - } - if ((fc & FC_KIND_MASK) == FC_CTS) { - mcl |= TXC_SENDCTS; - use_cts = true; - } - } else { - mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT); - mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS); - } - - len = roundup(len, 4); - ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN); - - dma_len += (u16) pkttotlen(osh, p); - - WL_AMPDU_TX("wl%d: wlc_sendampdu: ampdu_len %d seg_cnt %d null delim %d\n", - wlc->pub->unit, ampdu_len, seg_cnt, ndelim); - - txh->MacTxControlLow = htol16(mcl); - - /* this packet is added */ - pkt[count++] = p; - - /* patch the first MPDU */ - if (count == 1) { - u8 plcp0, plcp3, is40, sgi; - struct ieee80211_sta *sta; - - sta = tx_info->control.sta; - - if (rr) { - plcp0 = plcp[0]; - plcp3 = plcp[3]; - } else { - plcp0 = txh->FragPLCPFallback[0]; - plcp3 = txh->FragPLCPFallback[3]; - - } - is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; - sgi = PLCP3_ISSGI(plcp3) ? 1 : 0; - mcs = plcp0 & ~MIMO_PLCP_40MHZ; - ASSERT(mcs < MCS_TABLE_SIZE); - maxlen = - min(scb_ampdu->max_rxlen, - ampdu->max_txlen[mcs][is40][sgi]); - - WL_NONE("sendampdu: sgi %d, is40 %d, mcs %d\n", - sgi, is40, mcs); - - maxlen = 64 * 1024; /* XXX Fix me to honor real max_rxlen */ - - if (is40) - mimo_ctlchbw = - CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC) - ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; - - /* rebuild the rspec and rspec_fallback */ - rspec = RSPEC_MIMORATE; - rspec |= plcp[0] & ~MIMO_PLCP_40MHZ; - if (plcp[0] & MIMO_PLCP_40MHZ) - rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT); - - if (fbr_iscck) /* CCK */ - rspec_fallback = - CCK_RSPEC(CCK_PHY2MAC_RATE - (txh->FragPLCPFallback[0])); - else { /* MIMO */ - rspec_fallback = RSPEC_MIMORATE; - rspec_fallback |= - txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ; - if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ) - rspec_fallback |= - (PHY_TXC1_BW_40MHZ << - RSPEC_BW_SHIFT); - } - - if (use_rts || use_cts) { - rts_rspec = - wlc_rspec_to_rts_rspec(wlc, rspec, false, - mimo_ctlchbw); - rts_rspec_fallback = - wlc_rspec_to_rts_rspec(wlc, rspec_fallback, - false, mimo_ctlchbw); - } - } - - /* if (first mpdu for host agg) */ - /* test whether to add more */ - if ((MCS_RATE(mcs, true, false) >= f->dmaxferrate) && - (count == f->mcs2ampdu_table[mcs])) { - WL_AMPDU_ERR("wl%d: PR 37644: stopping ampdu at %d for mcs %d\n", - wlc->pub->unit, count, mcs); - break; - } - - if (count == scb_ampdu->max_pdu) { - WL_NONE("Stop taking from q, reached %d deep\n", - scb_ampdu->max_pdu); - break; - } - - /* check to see if the next pkt is a candidate for aggregation */ - p = pktq_ppeek(&qi->q, prec); - tx_info = IEEE80211_SKB_CB(p); /* tx_info must be checked with current p */ - - if (p) { - if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && - ((u8) (p->priority) == tid)) { - - plen = - pkttotlen(osh, p) + AMPDU_MAX_MPDU_OVERHEAD; - plen = max(scb_ampdu->min_len, plen); - - if ((plen + ampdu_len) > maxlen) { - p = NULL; - WL_ERROR("%s: Bogus plen #1\n", - __func__); - ASSERT(3 == 4); - continue; - } - - /* check if there are enough descriptors available */ - if (TXAVAIL(wlc, fifo) <= (seg_cnt + 1)) { - WL_ERROR("%s: No fifo space !!!!!!\n", - __func__); - p = NULL; - continue; - } - p = pktq_pdeq(&qi->q, prec); - ASSERT(p); - } else { - p = NULL; - } - } - } /* end while(p) */ - - ini->tx_in_transit += count; - - if (count) { - WLCNTADD(ampdu->cnt->txmpdu, count); - - /* patch up the last txh */ - txh = (d11txh_t *) pkt[count - 1]->data; - mcl = ltoh16(txh->MacTxControlLow); - mcl &= ~TXC_AMPDU_MASK; - mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT); - txh->MacTxControlLow = htol16(mcl); - - /* remove the null delimiter after last mpdu */ - ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; - txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0; - ampdu_len -= ndelim * AMPDU_DELIMITER_LEN; - - /* remove the pad len from last mpdu */ - fbr_iscck = ((ltoh16(txh->XtraFrameTypes) & 0x3) == 0); - len = fbr_iscck ? WLC_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) - : WLC_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); - ampdu_len -= roundup(len, 4) - len; - - /* patch up the first txh & plcp */ - txh = (d11txh_t *) pkt[0]->data; - plcp = (u8 *) (txh + 1); - - WLC_SET_MIMO_PLCP_LEN(plcp, ampdu_len); - /* mark plcp to indicate ampdu */ - WLC_SET_MIMO_PLCP_AMPDU(plcp); - - /* reset the mixed mode header durations */ - if (txh->MModeLen) { - u16 mmodelen = - wlc_calc_lsig_len(wlc, rspec, ampdu_len); - txh->MModeLen = htol16(mmodelen); - preamble_type = WLC_MM_PREAMBLE; - } - if (txh->MModeFbrLen) { - u16 mmfbrlen = - wlc_calc_lsig_len(wlc, rspec_fallback, ampdu_len); - txh->MModeFbrLen = htol16(mmfbrlen); - fbr_preamble_type = WLC_MM_PREAMBLE; - } - - /* set the preload length */ - if (MCS_RATE(mcs, true, false) >= f->dmaxferrate) { - dma_len = min(dma_len, f->ampdu_pld_size); - txh->PreloadSize = htol16(dma_len); - } else - txh->PreloadSize = 0; - - mch = ltoh16(txh->MacTxControlHigh); - - /* update RTS dur fields */ - if (use_rts || use_cts) { - u16 durid; - rts = (struct ieee80211_rts *)&txh->rts_frame; - if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) == - TXC_PREAMBLE_RTS_MAIN_SHORT) - rts_preamble_type = WLC_SHORT_PREAMBLE; - - if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) == - TXC_PREAMBLE_RTS_FB_SHORT) - rts_fbr_preamble_type = WLC_SHORT_PREAMBLE; - - durid = - wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec, - rspec, rts_preamble_type, - preamble_type, ampdu_len, - true); - rts->duration = htol16(durid); - durid = wlc_compute_rtscts_dur(wlc, use_cts, - rts_rspec_fallback, - rspec_fallback, - rts_fbr_preamble_type, - fbr_preamble_type, - ampdu_len, true); - txh->RTSDurFallback = htol16(durid); - /* set TxFesTimeNormal */ - txh->TxFesTimeNormal = rts->duration; - /* set fallback rate version of TxFesTimeNormal */ - txh->TxFesTimeFallback = txh->RTSDurFallback; - } - - /* set flag and plcp for fallback rate */ - if (fbr) { - WLCNTADD(ampdu->cnt->txfbr_mpdu, count); - WLCNTINCR(ampdu->cnt->txfbr_ampdu); - mch |= TXC_AMPDU_FBR; - txh->MacTxControlHigh = htol16(mch); - WLC_SET_MIMO_PLCP_AMPDU(plcp); - WLC_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback); - } - - WL_AMPDU_TX("wl%d: wlc_sendampdu: count %d ampdu_len %d\n", - wlc->pub->unit, count, ampdu_len); - - /* inform rate_sel if it this is a rate probe pkt */ - frameid = ltoh16(txh->TxFrameID); - if (frameid & TXFID_RATE_PROBE_MASK) { - WL_ERROR("%s: XXX what to do with TXFID_RATE_PROBE_MASK!?\n", - __func__); - } - for (i = 0; i < count; i++) - wlc_txfifo(wlc, fifo, pkt[i], i == (count - 1), - ampdu->txpkt_weight); - - } - /* endif (count) */ - return err; -} - -void BCMFASTPATH -wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, - struct sk_buff *p, tx_status_t *txs) -{ - scb_ampdu_t *scb_ampdu; - struct wlc_info *wlc = ampdu->wlc; - scb_ampdu_tid_ini_t *ini; - u32 s1 = 0, s2 = 0; - struct ieee80211_tx_info *tx_info; - - tx_info = IEEE80211_SKB_CB(p); - ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); - ASSERT(scb); - ASSERT(scb->magic == SCB_MAGIC); - ASSERT(txs->status & TX_STATUS_AMPDU); - scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - ASSERT(scb_ampdu); - ini = SCB_AMPDU_INI(scb_ampdu, p->priority); - ASSERT(ini->scb == scb); - - /* BMAC_NOTE: For the split driver, second level txstatus comes later - * So if the ACK was received then wait for the second level else just - * call the first one - */ - if (txs->status & TX_STATUS_ACK_RCV) { - u8 status_delay = 0; - - /* wait till the next 8 bytes of txstatus is available */ - while (((s1 = - R_REG(wlc->osh, - &wlc->regs->frmtxstatus)) & TXS_V) == 0) { - udelay(1); - status_delay++; - if (status_delay > 10) { - ASSERT(status_delay <= 10); - return; - } - } - - ASSERT(!(s1 & TX_STATUS_INTERMEDIATE)); - ASSERT(s1 & TX_STATUS_AMPDU); - s2 = R_REG(wlc->osh, &wlc->regs->frmtxstatus2); - } - - wlc_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2); - wlc_ampdu_txflowcontrol(wlc, scb_ampdu, ini); -} - -void -rate_status(struct wlc_info *wlc, struct ieee80211_tx_info *tx_info, - tx_status_t *txs, u8 mcs) -{ - struct ieee80211_tx_rate *txrate = tx_info->status.rates; - int i; - - /* clear the rest of the rates */ - for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) { - txrate[i].idx = -1; - txrate[i].count = 0; - } -} - -#define SHORTNAME "AMPDU status" - -static void BCMFASTPATH -wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, - struct sk_buff *p, tx_status_t *txs, - u32 s1, u32 s2) -{ - scb_ampdu_t *scb_ampdu; - struct wlc_info *wlc = ampdu->wlc; - scb_ampdu_tid_ini_t *ini; - u8 bitmap[8], queue, tid; - d11txh_t *txh; - u8 *plcp; - struct ieee80211_hdr *h; - u16 seq, start_seq = 0, bindex, index, mcl; - u8 mcs = 0; - bool ba_recd = false, ack_recd = false; - u8 suc_mpdu = 0, tot_mpdu = 0; - uint supr_status; - bool update_rate = true, retry = true, tx_error = false; - u16 mimoantsel = 0; - u8 antselid = 0; - u8 retry_limit, rr_retry_limit; - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); - -#ifdef BCMDBG - u8 hole[AMPDU_MAX_MPDU]; - memset(hole, 0, sizeof(hole)); -#endif - - ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); - ASSERT(txs->status & TX_STATUS_AMPDU); - - scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - ASSERT(scb_ampdu); - - tid = (u8) (p->priority); - - ini = SCB_AMPDU_INI(scb_ampdu, tid); - retry_limit = ampdu->retry_limit_tid[tid]; - rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; - - ASSERT(ini->scb == scb); - - memset(bitmap, 0, sizeof(bitmap)); - queue = txs->frameid & TXFID_QUEUE_MASK; - ASSERT(queue < AC_COUNT); - - supr_status = txs->status & TX_STATUS_SUPR_MASK; - - if (txs->status & TX_STATUS_ACK_RCV) { - if (TX_STATUS_SUPR_UF == supr_status) { - update_rate = false; - } - - ASSERT(txs->status & TX_STATUS_INTERMEDIATE); - start_seq = txs->sequence >> SEQNUM_SHIFT; - bitmap[0] = (txs->status & TX_STATUS_BA_BMAP03_MASK) >> - TX_STATUS_BA_BMAP03_SHIFT; - - ASSERT(!(s1 & TX_STATUS_INTERMEDIATE)); - ASSERT(s1 & TX_STATUS_AMPDU); - - bitmap[0] |= - (s1 & TX_STATUS_BA_BMAP47_MASK) << - TX_STATUS_BA_BMAP47_SHIFT; - bitmap[1] = (s1 >> 8) & 0xff; - bitmap[2] = (s1 >> 16) & 0xff; - bitmap[3] = (s1 >> 24) & 0xff; - - bitmap[4] = s2 & 0xff; - bitmap[5] = (s2 >> 8) & 0xff; - bitmap[6] = (s2 >> 16) & 0xff; - bitmap[7] = (s2 >> 24) & 0xff; - - ba_recd = true; - } else { - WLCNTINCR(ampdu->cnt->noba); - if (supr_status) { - update_rate = false; - if (supr_status == TX_STATUS_SUPR_BADCH) { - WL_ERROR("%s: Pkt tx suppressed, illegal channel possibly %d\n", - __func__, - CHSPEC_CHANNEL(wlc->default_bss->chanspec)); - } else { - if (supr_status == TX_STATUS_SUPR_FRAG) - WL_NONE("%s: AMPDU frag err\n", - __func__); - else - WL_ERROR("%s: wlc_ampdu_dotxstatus: supr_status 0x%x\n", - __func__, supr_status); - } - /* no need to retry for badch; will fail again */ - if (supr_status == TX_STATUS_SUPR_BADCH || - supr_status == TX_STATUS_SUPR_EXPTIME) { - retry = false; - WLCNTINCR(wlc->pub->_cnt->txchanrej); - } else if (supr_status == TX_STATUS_SUPR_EXPTIME) { - - WLCNTINCR(wlc->pub->_cnt->txexptime); - - /* TX underflow : try tuning pre-loading or ampdu size */ - } else if (supr_status == TX_STATUS_SUPR_FRAG) { - /* if there were underflows, but pre-loading is not active, - notify rate adaptation. - */ - if (wlc_ffpld_check_txfunfl(wlc, prio2fifo[tid]) - > 0) { - tx_error = true; - } - } - } else if (txs->phyerr) { - update_rate = false; - WLCNTINCR(wlc->pub->_cnt->txphyerr); - WL_ERROR("wl%d: wlc_ampdu_dotxstatus: tx phy error (0x%x)\n", - wlc->pub->unit, txs->phyerr); - -#ifdef BCMDBG - if (WL_ERROR_ON()) { - prpkt("txpkt (AMPDU)", wlc->osh, p); - wlc_print_txdesc((d11txh_t *) p->data); - wlc_print_txstatus(txs); - } -#endif /* BCMDBG */ - } - } - - /* loop through all pkts and retry if not acked */ - while (p) { - tx_info = IEEE80211_SKB_CB(p); - ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); - txh = (d11txh_t *) p->data; - mcl = ltoh16(txh->MacTxControlLow); - plcp = (u8 *) (txh + 1); - h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); - seq = ltoh16(h->seq_ctrl) >> SEQNUM_SHIFT; - - if (tot_mpdu == 0) { - mcs = plcp[0] & MIMO_PLCP_MCS_MASK; - mimoantsel = ltoh16(txh->ABI_MimoAntSel); - } - - index = TX_SEQ_TO_INDEX(seq); - ack_recd = false; - if (ba_recd) { - bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); - - WL_AMPDU_TX("%s: tid %d seq is %d, start_seq is %d, bindex is %d set %d, index %d\n", - __func__, tid, seq, start_seq, bindex, - isset(bitmap, bindex), index); - - /* if acked then clear bit and free packet */ - if ((bindex < AMPDU_TX_BA_MAX_WSIZE) - && isset(bitmap, bindex)) { - ini->tx_in_transit--; - ini->txretry[index] = 0; - - /* ampdu_ack_len: number of acked aggregated frames */ - /* ampdu_ack_map: block ack bit map for the aggregation */ - /* ampdu_len: number of aggregated frames */ - rate_status(wlc, tx_info, txs, mcs); - tx_info->flags |= IEEE80211_TX_STAT_ACK; - tx_info->flags |= IEEE80211_TX_STAT_AMPDU; - - /* XXX TODO: Make these accurate. */ - tx_info->status.ampdu_ack_len = - (txs-> - status & TX_STATUS_FRM_RTX_MASK) >> - TX_STATUS_FRM_RTX_SHIFT; - tx_info->status.ampdu_len = - (txs-> - status & TX_STATUS_FRM_RTX_MASK) >> - TX_STATUS_FRM_RTX_SHIFT; - - skb_pull(p, D11_PHY_HDR_LEN); - skb_pull(p, D11_TXH_LEN); - - ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, - p); - ack_recd = true; - suc_mpdu++; - } - } - /* either retransmit or send bar if ack not recd */ - if (!ack_recd) { - struct ieee80211_tx_rate *txrate = - tx_info->status.rates; - if (retry && (txrate[0].count < (int)retry_limit)) { - ini->txretry[index]++; - ini->tx_in_transit--; - /* Use high prededence for retransmit to give some punch */ - /* wlc_txq_enq(wlc, scb, p, WLC_PRIO_TO_PREC(tid)); */ - wlc_txq_enq(wlc, scb, p, - WLC_PRIO_TO_HI_PREC(tid)); - } else { - /* Retry timeout */ - ini->tx_in_transit--; - ieee80211_tx_info_clear_status(tx_info); - tx_info->flags |= - IEEE80211_TX_STAT_AMPDU_NO_BACK; - skb_pull(p, D11_PHY_HDR_LEN); - skb_pull(p, D11_TXH_LEN); - WL_ERROR("%s: BA Timeout, seq %d, in_transit %d\n", - SHORTNAME, seq, ini->tx_in_transit); - ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, - p); - } - } - tot_mpdu++; - - /* break out if last packet of ampdu */ - if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) == - TXC_AMPDU_LAST) - break; - - p = GETNEXTTXP(wlc, queue); - if (p == NULL) { - ASSERT(p); - break; - } - } - wlc_send_q(wlc, wlc->active_queue); - - /* update rate state */ - if (WLANTSEL_ENAB(wlc)) - antselid = wlc_antsel_antsel2id(wlc->asi, mimoantsel); - - wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight); -} - -static void -ampdu_cleanup_tid_ini(struct ampdu_info *ampdu, scb_ampdu_t *scb_ampdu, u8 tid, - bool force) -{ - scb_ampdu_tid_ini_t *ini; - ini = SCB_AMPDU_INI(scb_ampdu, tid); - if (!ini) - return; - - WL_AMPDU_CTL("wl%d: ampdu_cleanup_tid_ini: tid %d\n", - ampdu->wlc->pub->unit, tid); - - if (ini->tx_in_transit && !force) - return; - - scb_ampdu = SCB_AMPDU_CUBBY(ampdu, ini->scb); - ASSERT(ini == &scb_ampdu->ini[ini->tid]); - - /* free all buffered tx packets */ - pktq_pflush(ampdu->wlc->osh, &scb_ampdu->txq, ini->tid, true, NULL, 0); -} - -/* initialize the initiator code for tid */ -static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu, - scb_ampdu_t *scb_ampdu, - u8 tid, bool override) -{ - scb_ampdu_tid_ini_t *ini; - - ASSERT(scb_ampdu); - ASSERT(scb_ampdu->scb); - ASSERT(SCB_AMPDU(scb_ampdu->scb)); - ASSERT(tid < AMPDU_MAX_SCB_TID); - - /* check for per-tid control of ampdu */ - if (!ampdu->ini_enable[tid]) { - WL_ERROR("%s: Rejecting tid %d\n", __func__, tid); - return NULL; - } - - ini = SCB_AMPDU_INI(scb_ampdu, tid); - ini->tid = tid; - ini->scb = scb_ampdu->scb; - ini->magic = INI_MAGIC; - WLCNTINCR(ampdu->cnt->txaddbareq); - - return ini; -} - -int wlc_ampdu_set(struct ampdu_info *ampdu, bool on) -{ - struct wlc_info *wlc = ampdu->wlc; - - wlc->pub->_ampdu = false; - - if (on) { - if (!N_ENAB(wlc->pub)) { - WL_AMPDU_ERR("wl%d: driver not nmode enabled\n", - wlc->pub->unit); - return BCME_UNSUPPORTED; - } - if (!wlc_ampdu_cap(ampdu)) { - WL_AMPDU_ERR("wl%d: device not ampdu capable\n", - wlc->pub->unit); - return BCME_UNSUPPORTED; - } - wlc->pub->_ampdu = on; - } - - return 0; -} - -bool wlc_ampdu_cap(struct ampdu_info *ampdu) -{ - if (WLC_PHY_11N_CAP(ampdu->wlc->band)) - return true; - else - return false; -} - -static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur) -{ - u32 rate, mcs; - - for (mcs = 0; mcs < MCS_TABLE_SIZE; mcs++) { - /* rate is in Kbps; dur is in msec ==> len = (rate * dur) / 8 */ - /* 20MHz, No SGI */ - rate = MCS_RATE(mcs, false, false); - ampdu->max_txlen[mcs][0][0] = (rate * dur) >> 3; - /* 40 MHz, No SGI */ - rate = MCS_RATE(mcs, true, false); - ampdu->max_txlen[mcs][1][0] = (rate * dur) >> 3; - /* 20MHz, SGI */ - rate = MCS_RATE(mcs, false, true); - ampdu->max_txlen[mcs][0][1] = (rate * dur) >> 3; - /* 40 MHz, SGI */ - rate = MCS_RATE(mcs, true, true); - ampdu->max_txlen[mcs][1][1] = (rate * dur) >> 3; - } -} - -u8 BCMFASTPATH -wlc_ampdu_null_delim_cnt(struct ampdu_info *ampdu, struct scb *scb, - ratespec_t rspec, int phylen) -{ - scb_ampdu_t *scb_ampdu; - int bytes, cnt, tmp; - u8 tx_density; - - ASSERT(scb); - ASSERT(SCB_AMPDU(scb)); - - scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - ASSERT(scb_ampdu); - - if (scb_ampdu->mpdu_density == 0) - return 0; - - /* RSPEC2RATE is in kbps units ==> ~RSPEC2RATE/2^13 is in bytes/usec - density x is in 2^(x-4) usec - ==> # of bytes needed for req density = rate/2^(17-x) - ==> # of null delimiters = ceil(ceil(rate/2^(17-x)) - phylen)/4) - */ - - tx_density = scb_ampdu->mpdu_density; - - ASSERT(tx_density <= AMPDU_MAX_MPDU_DENSITY); - tmp = 1 << (17 - tx_density); - bytes = CEIL(RSPEC2RATE(rspec), tmp); - - if (bytes > phylen) { - cnt = CEIL(bytes - phylen, AMPDU_DELIMITER_LEN); - ASSERT(cnt <= 255); - return (u8) cnt; - } else - return 0; -} - -void wlc_ampdu_macaddr_upd(struct wlc_info *wlc) -{ - char template[T_RAM_ACCESS_SZ * 2]; - - /* driver needs to write the ta in the template; ta is at offset 16 */ - memset(template, 0, sizeof(template)); - bcopy((char *)wlc->pub->cur_etheraddr, template, ETH_ALEN); - wlc_write_template_ram(wlc, (T_BA_TPL_BASE + 16), (T_RAM_ACCESS_SZ * 2), - template); -} - -bool wlc_aggregatable(struct wlc_info *wlc, u8 tid) -{ - return wlc->ampdu->ini_enable[tid]; -} - -void wlc_ampdu_shm_upd(struct ampdu_info *ampdu) -{ - struct wlc_info *wlc = ampdu->wlc; - - /* Extend ucode internal watchdog timer to match larger received frames */ - if ((ampdu->rx_factor & HT_PARAMS_RX_FACTOR_MASK) == - AMPDU_RX_FACTOR_64K) { - wlc_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX); - wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX); - } else { - wlc_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_DEF); - wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF); - } -} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.h deleted file mode 100644 index 03457f63f2ab..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_ampdu.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_ampdu_h_ -#define _wlc_ampdu_h_ - -extern struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc); -extern void wlc_ampdu_detach(struct ampdu_info *ampdu); -extern bool wlc_ampdu_cap(struct ampdu_info *ampdu); -extern int wlc_ampdu_set(struct ampdu_info *ampdu, bool on); -extern int wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, - struct sk_buff **aggp, int prec); -extern void wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, - struct sk_buff *p, tx_status_t *txs); -extern void wlc_ampdu_reset(struct ampdu_info *ampdu); -extern void wlc_ampdu_macaddr_upd(struct wlc_info *wlc); -extern void wlc_ampdu_shm_upd(struct ampdu_info *ampdu); - -extern u8 wlc_ampdu_null_delim_cnt(struct ampdu_info *ampdu, struct scb *scb, - ratespec_t rspec, int phylen); -extern void scb_ampdu_cleanup(struct ampdu_info *ampdu, struct scb *scb); - -#endif /* _wlc_ampdu_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_antsel.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_antsel.c deleted file mode 100644 index 402ddf8f3371..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_antsel.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include - -#ifdef WLANTSEL - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* useful macros */ -#define WLC_ANTSEL_11N_0(ant) ((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf) -#define WLC_ANTSEL_11N_1(ant) (((ant) & ANT_SELCFG_MASK) & 0xf) -#define WLC_ANTIDX_11N(ant) (((WLC_ANTSEL_11N_0(ant)) << 2) + (WLC_ANTSEL_11N_1(ant))) -#define WLC_ANT_ISAUTO_11N(ant) (((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) -#define WLC_ANTSEL_11N(ant) ((ant) & ANT_SELCFG_MASK) - -/* antenna switch */ -/* defines for no boardlevel antenna diversity */ -#define ANT_SELCFG_DEF_2x2 0x01 /* default antenna configuration */ - -/* 2x3 antdiv defines and tables for GPIO communication */ -#define ANT_SELCFG_NUM_2x3 3 -#define ANT_SELCFG_DEF_2x3 0x01 /* default antenna configuration */ - -/* 2x4 antdiv rev4 defines and tables for GPIO communication */ -#define ANT_SELCFG_NUM_2x4 4 -#define ANT_SELCFG_DEF_2x4 0x02 /* default antenna configuration */ - -/* static functions */ -static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel); -static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id); -static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg); -static void wlc_antsel_init_cfg(struct antsel_info *asi, - wlc_antselcfg_t *antsel, - bool auto_sel); - -const u16 mimo_2x4_div_antselpat_tbl[] = { - 0, 0, 0x9, 0xa, /* ant0: 0 ant1: 2,3 */ - 0, 0, 0x5, 0x6, /* ant0: 1 ant1: 2,3 */ - 0, 0, 0, 0, /* n.a. */ - 0, 0, 0, 0 /* n.a. */ -}; - -const u8 mimo_2x4_div_antselid_tbl[16] = { - 0, 0, 0, 0, 0, 2, 3, 0, - 0, 0, 1, 0, 0, 0, 0, 0 /* pat to antselid */ -}; - -const u16 mimo_2x3_div_antselpat_tbl[] = { - 16, 0, 1, 16, /* ant0: 0 ant1: 1,2 */ - 16, 16, 16, 16, /* n.a. */ - 16, 2, 16, 16, /* ant0: 2 ant1: 1 */ - 16, 16, 16, 16 /* n.a. */ -}; - -const u8 mimo_2x3_div_antselid_tbl[16] = { - 0, 1, 2, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 /* pat to antselid */ -}; - -struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc, - struct osl_info *osh, - struct wlc_pub *pub, - struct wlc_hw_info *wlc_hw) { - struct antsel_info *asi; - - asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC); - if (!asi) { - WL_ERROR("wl%d: wlc_antsel_attach: out of mem\n", pub->unit); - return NULL; - } - - asi->wlc = wlc; - asi->pub = pub; - asi->antsel_type = ANTSEL_NA; - asi->antsel_avail = false; - asi->antsel_antswitch = (u8) getintvar(asi->pub->vars, "antswitch"); - - if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) { - switch (asi->antsel_antswitch) { - case ANTSWITCH_TYPE_1: - case ANTSWITCH_TYPE_2: - case ANTSWITCH_TYPE_3: - /* 4321/2 board with 2x3 switch logic */ - asi->antsel_type = ANTSEL_2x3; - /* Antenna selection availability */ - if (((u16) getintvar(asi->pub->vars, "aa2g") == 7) || - ((u16) getintvar(asi->pub->vars, "aa5g") == 7)) { - asi->antsel_avail = true; - } else - if (((u16) getintvar(asi->pub->vars, "aa2g") == - 3) - || ((u16) getintvar(asi->pub->vars, "aa5g") - == 3)) { - asi->antsel_avail = false; - } else { - asi->antsel_avail = false; - WL_ERROR("wlc_antsel_attach: 2o3 board cfg invalid\n"); - ASSERT(0); - } - break; - default: - break; - } - } else if ((asi->pub->sromrev == 4) && - ((u16) getintvar(asi->pub->vars, "aa2g") == 7) && - ((u16) getintvar(asi->pub->vars, "aa5g") == 0)) { - /* hack to match old 4321CB2 cards with 2of3 antenna switch */ - asi->antsel_type = ANTSEL_2x3; - asi->antsel_avail = true; - } else if (asi->pub->boardflags2 & BFL2_2X4_DIV) { - asi->antsel_type = ANTSEL_2x4; - asi->antsel_avail = true; - } - - /* Set the antenna selection type for the low driver */ - wlc_bmac_antsel_type_set(wlc_hw, asi->antsel_type); - - /* Init (auto/manual) antenna selection */ - wlc_antsel_init_cfg(asi, &asi->antcfg_11n, true); - wlc_antsel_init_cfg(asi, &asi->antcfg_cur, true); - - return asi; -} - -void wlc_antsel_detach(struct antsel_info *asi) -{ - if (!asi) - return; - - kfree(asi); -} - -void wlc_antsel_init(struct antsel_info *asi) -{ - if ((asi->antsel_type == ANTSEL_2x3) || - (asi->antsel_type == ANTSEL_2x4)) - wlc_antsel_cfgupd(asi, &asi->antcfg_11n); -} - -/* boardlevel antenna selection: init antenna selection structure */ -static void -wlc_antsel_init_cfg(struct antsel_info *asi, wlc_antselcfg_t *antsel, - bool auto_sel) -{ - if (asi->antsel_type == ANTSEL_2x3) { - u8 antcfg_def = ANT_SELCFG_DEF_2x3 | - ((asi->antsel_avail && auto_sel) ? ANT_SELCFG_AUTO : 0); - antsel->ant_config[ANT_SELCFG_TX_DEF] = antcfg_def; - antsel->ant_config[ANT_SELCFG_TX_UNICAST] = antcfg_def; - antsel->ant_config[ANT_SELCFG_RX_DEF] = antcfg_def; - antsel->ant_config[ANT_SELCFG_RX_UNICAST] = antcfg_def; - antsel->num_antcfg = ANT_SELCFG_NUM_2x3; - - } else if (asi->antsel_type == ANTSEL_2x4) { - - antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x4; - antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x4; - antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x4; - antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x4; - antsel->num_antcfg = ANT_SELCFG_NUM_2x4; - - } else { /* no antenna selection available */ - - antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x2; - antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x2; - antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x2; - antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x2; - antsel->num_antcfg = 0; - } -} - -void BCMFASTPATH -wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel, - u8 antselid, u8 fbantselid, u8 *antcfg, - u8 *fbantcfg) -{ - u8 ant; - - /* if use default, assign it and return */ - if (usedef) { - *antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_DEF]; - *fbantcfg = *antcfg; - return; - } - - if (!sel) { - *antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST]; - *fbantcfg = *antcfg; - - } else { - ant = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST]; - if ((ant & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) { - *antcfg = wlc_antsel_id2antcfg(asi, antselid); - *fbantcfg = wlc_antsel_id2antcfg(asi, fbantselid); - } else { - *antcfg = - asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST]; - *fbantcfg = *antcfg; - } - } - return; -} - -/* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */ -u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel) -{ - u8 antselid = 0; - - if (asi->antsel_type == ANTSEL_2x4) { - /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */ - antselid = mimo_2x4_div_antselid_tbl[(antsel & 0xf)]; - return antselid; - - } else if (asi->antsel_type == ANTSEL_2x3) { - /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */ - antselid = mimo_2x3_div_antselid_tbl[(antsel & 0xf)]; - return antselid; - } - - return antselid; -} - -/* boardlevel antenna selection: convert id to ant_cfg */ -static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id) -{ - u8 antcfg = ANT_SELCFG_DEF_2x2; - - if (asi->antsel_type == ANTSEL_2x4) { - /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */ - antcfg = (((id & 0x2) << 3) | ((id & 0x1) + 2)); - return antcfg; - - } else if (asi->antsel_type == ANTSEL_2x3) { - /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */ - antcfg = (((id & 0x02) << 4) | ((id & 0x1) + 1)); - return antcfg; - } - - return antcfg; -} - -/* boardlevel antenna selection: convert ant_cfg to mimo_antsel (ucode interface) */ -static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg) -{ - u8 idx = WLC_ANTIDX_11N(WLC_ANTSEL_11N(ant_cfg)); - u16 mimo_antsel = 0; - - if (asi->antsel_type == ANTSEL_2x4) { - /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */ - mimo_antsel = (mimo_2x4_div_antselpat_tbl[idx] & 0xf); - return mimo_antsel; - - } else if (asi->antsel_type == ANTSEL_2x3) { - /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */ - mimo_antsel = (mimo_2x3_div_antselpat_tbl[idx] & 0xf); - return mimo_antsel; - } - - return mimo_antsel; -} - -/* boardlevel antenna selection: ucode interface control */ -static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel) -{ - struct wlc_info *wlc = asi->wlc; - u8 ant_cfg; - u16 mimo_antsel; - - ASSERT(asi->antsel_type != ANTSEL_NA); - - /* 1) Update TX antconfig for all frames that are not unicast data - * (aka default TX) - */ - ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF]; - mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg); - wlc_write_shm(wlc, M_MIMO_ANTSEL_TXDFLT, mimo_antsel); - /* Update driver stats for currently selected default tx/rx antenna config */ - asi->antcfg_cur.ant_config[ANT_SELCFG_TX_DEF] = ant_cfg; - - /* 2) Update RX antconfig for all frames that are not unicast data - * (aka default RX) - */ - ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF]; - mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg); - wlc_write_shm(wlc, M_MIMO_ANTSEL_RXDFLT, mimo_antsel); - /* Update driver stats for currently selected default tx/rx antenna config */ - asi->antcfg_cur.ant_config[ANT_SELCFG_RX_DEF] = ant_cfg; - - return 0; -} - -#endif /* WLANTSEL */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_antsel.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_antsel.h deleted file mode 100644 index 8875b5848665..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_antsel.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_antsel_h_ -#define _wlc_antsel_h_ -extern struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc, - struct osl_info *osh, - struct wlc_pub *pub, - struct wlc_hw_info *wlc_hw); -extern void wlc_antsel_detach(struct antsel_info *asi); -extern void wlc_antsel_init(struct antsel_info *asi); -extern void wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, - bool sel, - u8 id, u8 fbid, u8 *antcfg, - u8 *fbantcfg); -extern u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel); -#endif /* _wlc_antsel_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.c deleted file mode 100644 index e22ce1f79660..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.c +++ /dev/null @@ -1,4235 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -/* BMAC_NOTE: a WLC_HIGH compile include of wlc.h adds in more structures and type - * dependencies. Need to include these to files to allow a clean include of wlc.h - * with WLC_HIGH defined. - * At some point we may be able to skip the include of wlc.h and instead just - * define a stub wlc_info and band struct to allow rpc calls to get the rpc handle. - */ -#include -#include -#include -#include -#include -#include -#include "wl_ucode.h" -#include "d11ucode_ext.h" -#include - -/* BMAC_NOTE: With WLC_HIGH defined, some fns in this file make calls to high level - * functions defined in the headers below. We should be eliminating those calls and - * will be able to delete these include lines. - */ -#include - -#include - -#include -#include - -#define TIMER_INTERVAL_WATCHDOG_BMAC 1000 /* watchdog timer, in unit of ms */ - -#define SYNTHPU_DLY_APHY_US 3700 /* a phy synthpu_dly time in us */ -#define SYNTHPU_DLY_BPHY_US 1050 /* b/g phy synthpu_dly time in us, default */ -#define SYNTHPU_DLY_NPHY_US 2048 /* n phy REV3 synthpu_dly time in us, default */ -#define SYNTHPU_DLY_LPPHY_US 300 /* lpphy synthpu_dly time in us */ - -#define SYNTHPU_DLY_PHY_US_QT 100 /* QT synthpu_dly time in us */ - -#ifndef BMAC_DUP_TO_REMOVE -#define WLC_RM_WAIT_TX_SUSPEND 4 /* Wait Tx Suspend */ - -#define ANTCNT 10 /* vanilla M_MAX_ANTCNT value */ - -#endif /* BMAC_DUP_TO_REMOVE */ - -#define DMAREG(wlc_hw, direction, fifonum) (D11REV_LT(wlc_hw->corerev, 11) ? \ - ((direction == DMA_TX) ? \ - (void *)&(wlc_hw->regs->fifo.f32regs.dmaregs[fifonum].xmt) : \ - (void *)&(wlc_hw->regs->fifo.f32regs.dmaregs[fifonum].rcv)) : \ - ((direction == DMA_TX) ? \ - (void *)&(wlc_hw->regs->fifo.f64regs[fifonum].dmaxmt) : \ - (void *)&(wlc_hw->regs->fifo.f64regs[fifonum].dmarcv))) - -/* - * The following table lists the buffer memory allocated to xmt fifos in HW. - * the size is in units of 256bytes(one block), total size is HW dependent - * ucode has default fifo partition, sw can overwrite if necessary - * - * This is documented in twiki under the topic UcodeTxFifo. Please ensure - * the twiki is updated before making changes. - */ - -#define XMTFIFOTBL_STARTREV 20 /* Starting corerev for the fifo size table */ - -static u16 xmtfifo_sz[][NFIFO] = { - {20, 192, 192, 21, 17, 5}, /* corerev 20: 5120, 49152, 49152, 5376, 4352, 1280 */ - {9, 58, 22, 14, 14, 5}, /* corerev 21: 2304, 14848, 5632, 3584, 3584, 1280 */ - {20, 192, 192, 21, 17, 5}, /* corerev 22: 5120, 49152, 49152, 5376, 4352, 1280 */ - {20, 192, 192, 21, 17, 5}, /* corerev 23: 5120, 49152, 49152, 5376, 4352, 1280 */ - {9, 58, 22, 14, 14, 5}, /* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */ -}; - -static void wlc_clkctl_clk(struct wlc_hw_info *wlc, uint mode); -static void wlc_coreinit(struct wlc_info *wlc); - -/* used by wlc_wakeucode_init() */ -static void wlc_write_inits(struct wlc_hw_info *wlc_hw, const d11init_t *inits); -static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[], - const uint nbytes); -static void wlc_ucode_download(struct wlc_hw_info *wlc); -static void wlc_ucode_txant_set(struct wlc_hw_info *wlc_hw); - -/* used by wlc_dpc() */ -static bool wlc_bmac_dotxstatus(struct wlc_hw_info *wlc, tx_status_t *txs, - u32 s2); -static bool wlc_bmac_txstatus_corerev4(struct wlc_hw_info *wlc); -static bool wlc_bmac_txstatus(struct wlc_hw_info *wlc, bool bound, bool *fatal); -static bool wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound); - -/* used by wlc_down() */ -static void wlc_flushqueues(struct wlc_info *wlc); - -static void wlc_write_mhf(struct wlc_hw_info *wlc_hw, u16 *mhfs); -static void wlc_mctrl_reset(struct wlc_hw_info *wlc_hw); -static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw); - -/* Low Level Prototypes */ -static u16 wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, - u32 sel); -static void wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset, - u16 v, u32 sel); -static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme); -static void wlc_bmac_detach_dmapio(struct wlc_hw_info *wlc_hw); -static void wlc_ucode_bsinit(struct wlc_hw_info *wlc_hw); -static bool wlc_validboardtype(struct wlc_hw_info *wlc); -static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw); -static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw); -static void wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init); -static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw); -static void wlc_ucode_mute_override_set(struct wlc_hw_info *wlc_hw); -static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw); -static u32 wlc_wlintrsoff(struct wlc_info *wlc); -static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask); -static void wlc_gpio_init(struct wlc_info *wlc); -static void wlc_write_hw_bcntemplate0(struct wlc_hw_info *wlc_hw, void *bcn, - int len); -static void wlc_write_hw_bcntemplate1(struct wlc_hw_info *wlc_hw, void *bcn, - int len); -static void wlc_bmac_bsinit(struct wlc_info *wlc, chanspec_t chanspec); -static u32 wlc_setband_inact(struct wlc_info *wlc, uint bandunit); -static void wlc_bmac_setband(struct wlc_hw_info *wlc_hw, uint bandunit, - chanspec_t chanspec); -static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw, - bool shortslot); -static void wlc_upd_ofdm_pctl1_table(struct wlc_hw_info *wlc_hw); -static u16 wlc_bmac_ofdm_ratetable_offset(struct wlc_hw_info *wlc_hw, - u8 rate); - -/* === Low Level functions === */ - -void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot) -{ - wlc_hw->shortslot = shortslot; - - if (BAND_2G(wlc_hw->band->bandtype) && wlc_hw->up) { - wlc_suspend_mac_and_wait(wlc_hw->wlc); - wlc_bmac_update_slot_timing(wlc_hw, shortslot); - wlc_enable_mac(wlc_hw->wlc); - } -} - -/* - * Update the slot timing for standard 11b/g (20us slots) - * or shortslot 11g (9us slots) - * The PSM needs to be suspended for this call. - */ -static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw, - bool shortslot) -{ - struct osl_info *osh; - d11regs_t *regs; - - osh = wlc_hw->osh; - regs = wlc_hw->regs; - - if (shortslot) { - /* 11g short slot: 11a timing */ - W_REG(osh, ®s->ifs_slot, 0x0207); /* APHY_SLOT_TIME */ - wlc_bmac_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME); - } else { - /* 11g long slot: 11b timing */ - W_REG(osh, ®s->ifs_slot, 0x0212); /* BPHY_SLOT_TIME */ - wlc_bmac_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME); - } -} - -static void WLBANDINITFN(wlc_ucode_bsinit) (struct wlc_hw_info *wlc_hw) -{ - /* init microcode host flags */ - wlc_write_mhf(wlc_hw, wlc_hw->band->mhfs); - - /* do band-specific ucode IHR, SHM, and SCR inits */ - if (D11REV_IS(wlc_hw->corerev, 23)) { - if (WLCISNPHY(wlc_hw->band)) { - wlc_write_inits(wlc_hw, d11n0bsinitvals16); - } else { - WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); - } - } else { - if (D11REV_IS(wlc_hw->corerev, 24)) { - if (WLCISLCNPHY(wlc_hw->band)) { - wlc_write_inits(wlc_hw, d11lcn0bsinitvals24); - } else - WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, - wlc_hw->corerev); - } else { - WL_ERROR("%s: wl%d: unsupported corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); - } - } -} - -/* switch to new band but leave it inactive */ -static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - u32 macintmask; - u32 tmp; - - WL_TRACE("wl%d: wlc_setband_inact\n", wlc_hw->unit); - - ASSERT(bandunit != wlc_hw->band->bandunit); - ASSERT(si_iscoreup(wlc_hw->sih)); - ASSERT((R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol) & MCTL_EN_MAC) == - 0); - - /* disable interrupts */ - macintmask = wl_intrsoff(wlc->wl); - - /* radio off */ - wlc_phy_switch_radio(wlc_hw->band->pi, OFF); - - ASSERT(wlc_hw->clk); - - if (D11REV_LT(wlc_hw->corerev, 17)) - tmp = R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol); - - wlc_bmac_core_phy_clk(wlc_hw, OFF); - - wlc_setxband(wlc_hw, bandunit); - - return macintmask; -} - -/* Process received frames */ -/* - * Return true if more frames need to be processed. false otherwise. - * Param 'bound' indicates max. # frames to process before break out. - */ -static bool BCMFASTPATH -wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound) -{ - struct sk_buff *p; - struct sk_buff *head = NULL; - struct sk_buff *tail = NULL; - uint n = 0; - uint bound_limit = bound ? wlc_hw->wlc->pub->tunables->rxbnd : -1; - u32 tsf_h, tsf_l; - wlc_d11rxhdr_t *wlc_rxhdr = NULL; - - WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); - /* gather received frames */ - while ((p = dma_rx(wlc_hw->di[fifo]))) { - - if (!tail) - head = tail = p; - else { - tail->prev = p; - tail = p; - } - - /* !give others some time to run! */ - if (++n >= bound_limit) - break; - } - - /* get the TSF REG reading */ - wlc_bmac_read_tsf(wlc_hw, &tsf_l, &tsf_h); - - /* post more rbufs */ - dma_rxfill(wlc_hw->di[fifo]); - - /* process each frame */ - while ((p = head) != NULL) { - head = head->prev; - p->prev = NULL; - - /* record the tsf_l in wlc_rxd11hdr */ - wlc_rxhdr = (wlc_d11rxhdr_t *) p->data; - wlc_rxhdr->tsf_l = htol32(tsf_l); - - /* compute the RSSI from d11rxhdr and record it in wlc_rxd11hr */ - wlc_phy_rssi_compute(wlc_hw->band->pi, wlc_rxhdr); - - wlc_recv(wlc_hw->wlc, p); - } - - return n >= bound_limit; -} - -/* second-level interrupt processing - * Return true if another dpc needs to be re-scheduled. false otherwise. - * Param 'bounded' indicates if applicable loops should be bounded. - */ -bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) -{ - u32 macintstatus; - struct wlc_hw_info *wlc_hw = wlc->hw; - d11regs_t *regs = wlc_hw->regs; - bool fatal = false; - - if (DEVICEREMOVED(wlc)) { - WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); - wl_down(wlc->wl); - return false; - } - - /* grab and clear the saved software intstatus bits */ - macintstatus = wlc->macintstatus; - wlc->macintstatus = 0; - - WL_TRACE("wl%d: wlc_dpc: macintstatus 0x%x\n", - wlc_hw->unit, macintstatus); - - if (macintstatus & MI_PRQ) { - /* Process probe request FIFO */ - ASSERT(0 && "PRQ Interrupt in non-MBSS"); - } - - /* BCN template is available */ - /* ZZZ: Use AP_ACTIVE ? */ - if (AP_ENAB(wlc->pub) && (!APSTA_ENAB(wlc->pub) || wlc->aps_associated) - && (macintstatus & MI_BCNTPL)) { - wlc_update_beacon(wlc); - } - - /* PMQ entry addition */ - if (macintstatus & MI_PMQ) { - } - - /* tx status */ - if (macintstatus & MI_TFS) { - if (wlc_bmac_txstatus(wlc->hw, bounded, &fatal)) - wlc->macintstatus |= MI_TFS; - if (fatal) { - WL_ERROR("MI_TFS: fatal\n"); - goto fatal; - } - } - - if (macintstatus & (MI_TBTT | MI_DTIM_TBTT)) - wlc_tbtt(wlc, regs); - - /* ATIM window end */ - if (macintstatus & MI_ATIMWINEND) { - WL_TRACE("wlc_isr: end of ATIM window\n"); - - OR_REG(wlc_hw->osh, ®s->maccommand, wlc->qvalid); - wlc->qvalid = 0; - } - - /* phy tx error */ - if (macintstatus & MI_PHYTXERR) { - WLCNTINCR(wlc->pub->_cnt->txphyerr); - } - - /* received data or control frame, MI_DMAINT is indication of RX_FIFO interrupt */ - if (macintstatus & MI_DMAINT) { - if (wlc_bmac_recv(wlc_hw, RX_FIFO, bounded)) { - wlc->macintstatus |= MI_DMAINT; - } - } - - /* TX FIFO suspend/flush completion */ - if (macintstatus & MI_TXSTOP) { - if (wlc_bmac_tx_fifo_suspended(wlc_hw, TX_DATA_FIFO)) { - /* WL_ERROR("dpc: fifo_suspend_comlete\n"); */ - } - } - - /* noise sample collected */ - if (macintstatus & MI_BG_NOISE) { - wlc_phy_noise_sample_intr(wlc_hw->band->pi); - } - - if (macintstatus & MI_GP0) { - WL_ERROR("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", - wlc_hw->unit, wlc_hw->now); - - printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", - __func__, wlc_hw->sih->chip, - wlc_hw->sih->chiprev); - - WLCNTINCR(wlc->pub->_cnt->psmwds); - - /* big hammer */ - wl_init(wlc->wl); - } - - /* gptimer timeout */ - if (macintstatus & MI_TO) { - W_REG(wlc_hw->osh, ®s->gptimer, 0); - } - - if (macintstatus & MI_RFDISABLE) { -#if defined(BCMDBG) - u32 rfd = R_REG(wlc_hw->osh, ®s->phydebug) & PDBG_RFD; -#endif - - WL_ERROR("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n", - wlc_hw->unit, rfd); - - WLCNTINCR(wlc->pub->_cnt->rfdisable); - } - - /* send any enq'd tx packets. Just makes sure to jump start tx */ - if (!pktq_empty(&wlc->active_queue->q)) - wlc_send_q(wlc, wlc->active_queue); - - ASSERT(wlc_ps_check(wlc)); - - /* make sure the bound indication and the implementation are in sync */ - ASSERT(bounded == true || wlc->macintstatus == 0); - - /* it isn't done and needs to be resched if macintstatus is non-zero */ - return wlc->macintstatus != 0; - - fatal: - wl_init(wlc->wl); - return wlc->macintstatus != 0; -} - -/* common low-level watchdog code */ -void wlc_bmac_watchdog(void *arg) -{ - struct wlc_info *wlc = (struct wlc_info *) arg; - struct wlc_hw_info *wlc_hw = wlc->hw; - - WL_TRACE("wl%d: wlc_bmac_watchdog\n", wlc_hw->unit); - - if (!wlc_hw->up) - return; - - /* increment second count */ - wlc_hw->now++; - - /* Check for FIFO error interrupts */ - wlc_bmac_fifoerrors(wlc_hw); - - /* make sure RX dma has buffers */ - dma_rxfill(wlc->hw->di[RX_FIFO]); - if (D11REV_IS(wlc_hw->corerev, 4)) { - dma_rxfill(wlc->hw->di[RX_TXSTATUS_FIFO]); - } - - wlc_phy_watchdog(wlc_hw->band->pi); -} - -void -wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, - bool mute, struct txpwr_limits *txpwr) -{ - uint bandunit; - - WL_TRACE("wl%d: wlc_bmac_set_chanspec 0x%x\n", - wlc_hw->unit, chanspec); - - wlc_hw->chanspec = chanspec; - - /* Switch bands if necessary */ - if (NBANDS_HW(wlc_hw) > 1) { - bandunit = CHSPEC_WLCBANDUNIT(chanspec); - if (wlc_hw->band->bandunit != bandunit) { - /* wlc_bmac_setband disables other bandunit, - * use light band switch if not up yet - */ - if (wlc_hw->up) { - wlc_phy_chanspec_radio_set(wlc_hw-> - bandstate[bandunit]-> - pi, chanspec); - wlc_bmac_setband(wlc_hw, bandunit, chanspec); - } else { - wlc_setxband(wlc_hw, bandunit); - } - } - } - - wlc_phy_initcal_enable(wlc_hw->band->pi, !mute); - - if (!wlc_hw->up) { - if (wlc_hw->clk) - wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, - chanspec); - wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec); - } else { - wlc_phy_chanspec_set(wlc_hw->band->pi, chanspec); - wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec); - - /* Update muting of the channel */ - wlc_bmac_mute(wlc_hw, mute, 0); - } -} - -int wlc_bmac_revinfo_get(struct wlc_hw_info *wlc_hw, - wlc_bmac_revinfo_t *revinfo) -{ - si_t *sih = wlc_hw->sih; - uint idx; - - revinfo->vendorid = wlc_hw->vendorid; - revinfo->deviceid = wlc_hw->deviceid; - - revinfo->boardrev = wlc_hw->boardrev; - revinfo->corerev = wlc_hw->corerev; - revinfo->sromrev = wlc_hw->sromrev; - revinfo->chiprev = sih->chiprev; - revinfo->chip = sih->chip; - revinfo->chippkg = sih->chippkg; - revinfo->boardtype = sih->boardtype; - revinfo->boardvendor = sih->boardvendor; - revinfo->bustype = sih->bustype; - revinfo->buscoretype = sih->buscoretype; - revinfo->buscorerev = sih->buscorerev; - revinfo->issim = sih->issim; - - revinfo->nbands = NBANDS_HW(wlc_hw); - - for (idx = 0; idx < NBANDS_HW(wlc_hw); idx++) { - wlc_hwband_t *band = wlc_hw->bandstate[idx]; - revinfo->band[idx].bandunit = band->bandunit; - revinfo->band[idx].bandtype = band->bandtype; - revinfo->band[idx].phytype = band->phytype; - revinfo->band[idx].phyrev = band->phyrev; - revinfo->band[idx].radioid = band->radioid; - revinfo->band[idx].radiorev = band->radiorev; - revinfo->band[idx].abgphy_encore = band->abgphy_encore; - revinfo->band[idx].anarev = 0; - - } - return 0; -} - -int wlc_bmac_state_get(struct wlc_hw_info *wlc_hw, wlc_bmac_state_t *state) -{ - state->machwcap = wlc_hw->machwcap; - - return 0; -} - -static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) -{ - uint i; - char name[8]; - /* ucode host flag 2 needed for pio mode, independent of band and fifo */ - u16 pio_mhf2 = 0; - struct wlc_hw_info *wlc_hw = wlc->hw; - uint unit = wlc_hw->unit; - wlc_tunables_t *tune = wlc->pub->tunables; - - /* name and offsets for dma_attach */ - snprintf(name, sizeof(name), "wl%d", unit); - - if (wlc_hw->di[0] == 0) { /* Init FIFOs */ - uint addrwidth; - int dma_attach_err = 0; - struct osl_info *osh = wlc_hw->osh; - - /* Find out the DMA addressing capability and let OS know - * All the channels within one DMA core have 'common-minimum' same - * capability - */ - addrwidth = - dma_addrwidth(wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 0)); - - if (!wl_alloc_dma_resources(wlc_hw->wlc->wl, addrwidth)) { - WL_ERROR("wl%d: wlc_attach: alloc_dma_resources failed\n", - unit); - return false; - } - - /* - * FIFO 0 - * TX: TX_AC_BK_FIFO (TX AC Background data packets) - * RX: RX_FIFO (RX data packets) - */ - ASSERT(TX_AC_BK_FIFO == 0); - ASSERT(RX_FIFO == 0); - wlc_hw->di[0] = dma_attach(osh, name, wlc_hw->sih, - (wme ? DMAREG(wlc_hw, DMA_TX, 0) : - NULL), DMAREG(wlc_hw, DMA_RX, 0), - (wme ? tune->ntxd : 0), tune->nrxd, - tune->rxbufsz, -1, tune->nrxbufpost, - WL_HWRXOFF, &wl_msg_level); - dma_attach_err |= (NULL == wlc_hw->di[0]); - - /* - * FIFO 1 - * TX: TX_AC_BE_FIFO (TX AC Best-Effort data packets) - * (legacy) TX_DATA_FIFO (TX data packets) - * RX: UNUSED - */ - ASSERT(TX_AC_BE_FIFO == 1); - ASSERT(TX_DATA_FIFO == 1); - wlc_hw->di[1] = dma_attach(osh, name, wlc_hw->sih, - DMAREG(wlc_hw, DMA_TX, 1), NULL, - tune->ntxd, 0, 0, -1, 0, 0, - &wl_msg_level); - dma_attach_err |= (NULL == wlc_hw->di[1]); - - /* - * FIFO 2 - * TX: TX_AC_VI_FIFO (TX AC Video data packets) - * RX: UNUSED - */ - ASSERT(TX_AC_VI_FIFO == 2); - wlc_hw->di[2] = dma_attach(osh, name, wlc_hw->sih, - DMAREG(wlc_hw, DMA_TX, 2), NULL, - tune->ntxd, 0, 0, -1, 0, 0, - &wl_msg_level); - dma_attach_err |= (NULL == wlc_hw->di[2]); - /* - * FIFO 3 - * TX: TX_AC_VO_FIFO (TX AC Voice data packets) - * (legacy) TX_CTL_FIFO (TX control & mgmt packets) - * RX: RX_TXSTATUS_FIFO (transmit-status packets) - * for corerev < 5 only - */ - ASSERT(TX_AC_VO_FIFO == 3); - ASSERT(TX_CTL_FIFO == 3); - if (D11REV_IS(wlc_hw->corerev, 4)) { - ASSERT(RX_TXSTATUS_FIFO == 3); - wlc_hw->di[3] = dma_attach(osh, name, wlc_hw->sih, - DMAREG(wlc_hw, DMA_TX, 3), - DMAREG(wlc_hw, DMA_RX, 3), - tune->ntxd, tune->nrxd, - sizeof(tx_status_t), -1, - tune->nrxbufpost, 0, - &wl_msg_level); - dma_attach_err |= (NULL == wlc_hw->di[3]); - } else { - wlc_hw->di[3] = dma_attach(osh, name, wlc_hw->sih, - DMAREG(wlc_hw, DMA_TX, 3), - NULL, tune->ntxd, 0, 0, -1, - 0, 0, &wl_msg_level); - dma_attach_err |= (NULL == wlc_hw->di[3]); - } -/* Cleaner to leave this as if with AP defined */ - - if (dma_attach_err) { - WL_ERROR("wl%d: wlc_attach: dma_attach failed\n", unit); - return false; - } - - /* get pointer to dma engine tx flow control variable */ - for (i = 0; i < NFIFO; i++) - if (wlc_hw->di[i]) - wlc_hw->txavail[i] = - (uint *) dma_getvar(wlc_hw->di[i], - "&txavail"); - } - - /* initial ucode host flags */ - wlc_mhfdef(wlc, wlc_hw->band->mhfs, pio_mhf2); - - return true; -} - -static void wlc_bmac_detach_dmapio(struct wlc_hw_info *wlc_hw) -{ - uint j; - - for (j = 0; j < NFIFO; j++) { - if (wlc_hw->di[j]) { - dma_detach(wlc_hw->di[j]); - wlc_hw->di[j] = NULL; - } - } -} - -/* low level attach - * run backplane attach, init nvram - * run phy attach - * initialize software state for each core and band - * put the whole chip in reset(driver down state), no clock - */ -int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, - bool piomode, struct osl_info *osh, void *regsva, - uint bustype, void *btparam) -{ - struct wlc_hw_info *wlc_hw; - d11regs_t *regs; - char *macaddr = NULL; - char *vars; - uint err = 0; - uint j; - bool wme = false; - shared_phy_params_t sha_params; - - WL_TRACE("wl%d: wlc_bmac_attach: vendor 0x%x device 0x%x\n", - unit, vendor, device); - - ASSERT(sizeof(wlc_d11rxhdr_t) <= WL_HWRXOFF); - - wme = true; - - wlc_hw = wlc->hw; - wlc_hw->wlc = wlc; - wlc_hw->unit = unit; - wlc_hw->osh = osh; - wlc_hw->band = wlc_hw->bandstate[0]; - wlc_hw->_piomode = piomode; - - /* populate struct wlc_hw_info with default values */ - wlc_bmac_info_init(wlc_hw); - - /* - * Do the hardware portion of the attach. - * Also initialize software state that depends on the particular hardware - * we are running. - */ - wlc_hw->sih = si_attach((uint) device, osh, regsva, bustype, btparam, - &wlc_hw->vars, &wlc_hw->vars_size); - if (wlc_hw->sih == NULL) { - WL_ERROR("wl%d: wlc_bmac_attach: si_attach failed\n", unit); - err = 11; - goto fail; - } - vars = wlc_hw->vars; - - /* - * Get vendid/devid nvram overwrites, which could be different - * than those the BIOS recognizes for devices on PCMCIA_BUS, - * SDIO_BUS, and SROMless devices on PCI_BUS. - */ -#ifdef BCMBUSTYPE - bustype = BCMBUSTYPE; -#endif - if (bustype != SI_BUS) { - char *var; - - var = getvar(vars, "vendid"); - if (var) { - vendor = (u16) simple_strtoul(var, NULL, 0); - WL_ERROR("Overriding vendor id = 0x%x\n", vendor); - } - var = getvar(vars, "devid"); - if (var) { - u16 devid = (u16) simple_strtoul(var, NULL, 0); - if (devid != 0xffff) { - device = devid; - WL_ERROR("Overriding device id = 0x%x\n", - device); - } - } - - /* verify again the device is supported */ - if (!wlc_chipmatch(vendor, device)) { - WL_ERROR("wl%d: wlc_bmac_attach: Unsupported vendor/device (0x%x/0x%x)\n", - unit, vendor, device); - err = 12; - goto fail; - } - } - - wlc_hw->vendorid = vendor; - wlc_hw->deviceid = device; - - /* set bar0 window to point at D11 core */ - wlc_hw->regs = (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, 0); - wlc_hw->corerev = si_corerev(wlc_hw->sih); - - regs = wlc_hw->regs; - - wlc->regs = wlc_hw->regs; - - /* validate chip, chiprev and corerev */ - if (!wlc_isgoodchip(wlc_hw)) { - err = 13; - goto fail; - } - - /* initialize power control registers */ - si_clkctl_init(wlc_hw->sih); - - /* request fastclock and force fastclock for the rest of attach - * bring the d11 core out of reset. - * For PMU chips, the first wlc_clkctl_clk is no-op since core-clk is still false; - * But it will be called again inside wlc_corereset, after d11 is out of reset. - */ - wlc_clkctl_clk(wlc_hw, CLK_FAST); - wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); - - if (!wlc_bmac_validate_chip_access(wlc_hw)) { - WL_ERROR("wl%d: wlc_bmac_attach: validate_chip_access failed\n", - unit); - err = 14; - goto fail; - } - - /* get the board rev, used just below */ - j = getintvar(vars, "boardrev"); - /* promote srom boardrev of 0xFF to 1 */ - if (j == BOARDREV_PROMOTABLE) - j = BOARDREV_PROMOTED; - wlc_hw->boardrev = (u16) j; - if (!wlc_validboardtype(wlc_hw)) { - WL_ERROR("wl%d: wlc_bmac_attach: Unsupported Broadcom board type (0x%x)" " or revision level (0x%x)\n", - unit, wlc_hw->sih->boardtype, wlc_hw->boardrev); - err = 15; - goto fail; - } - wlc_hw->sromrev = (u8) getintvar(vars, "sromrev"); - wlc_hw->boardflags = (u32) getintvar(vars, "boardflags"); - wlc_hw->boardflags2 = (u32) getintvar(vars, "boardflags2"); - - if (D11REV_LE(wlc_hw->corerev, 4) - || (wlc_hw->boardflags & BFL_NOPLLDOWN)) - wlc_bmac_pllreq(wlc_hw, true, WLC_PLLREQ_SHARED); - - if ((wlc_hw->sih->bustype == PCI_BUS) - && (si_pci_war16165(wlc_hw->sih))) - wlc->war16165 = true; - - /* check device id(srom, nvram etc.) to set bands */ - if (wlc_hw->deviceid == BCM43224_D11N_ID) { - /* Dualband boards */ - wlc_hw->_nbands = 2; - } else - wlc_hw->_nbands = 1; - - if ((wlc_hw->sih->chip == BCM43225_CHIP_ID)) - wlc_hw->_nbands = 1; - - /* BMAC_NOTE: remove init of pub values when wlc_attach() unconditionally does the - * init of these values - */ - wlc->vendorid = wlc_hw->vendorid; - wlc->deviceid = wlc_hw->deviceid; - wlc->pub->sih = wlc_hw->sih; - wlc->pub->corerev = wlc_hw->corerev; - wlc->pub->sromrev = wlc_hw->sromrev; - wlc->pub->boardrev = wlc_hw->boardrev; - wlc->pub->boardflags = wlc_hw->boardflags; - wlc->pub->boardflags2 = wlc_hw->boardflags2; - wlc->pub->_nbands = wlc_hw->_nbands; - - wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc); - - if (wlc_hw->physhim == NULL) { - WL_ERROR("wl%d: wlc_bmac_attach: wlc_phy_shim_attach failed\n", - unit); - err = 25; - goto fail; - } - - /* pass all the parameters to wlc_phy_shared_attach in one struct */ - sha_params.osh = osh; - sha_params.sih = wlc_hw->sih; - sha_params.physhim = wlc_hw->physhim; - sha_params.unit = unit; - sha_params.corerev = wlc_hw->corerev; - sha_params.vars = vars; - sha_params.vid = wlc_hw->vendorid; - sha_params.did = wlc_hw->deviceid; - sha_params.chip = wlc_hw->sih->chip; - sha_params.chiprev = wlc_hw->sih->chiprev; - sha_params.chippkg = wlc_hw->sih->chippkg; - sha_params.sromrev = wlc_hw->sromrev; - sha_params.boardtype = wlc_hw->sih->boardtype; - sha_params.boardrev = wlc_hw->boardrev; - sha_params.boardvendor = wlc_hw->sih->boardvendor; - sha_params.boardflags = wlc_hw->boardflags; - sha_params.boardflags2 = wlc_hw->boardflags2; - sha_params.bustype = wlc_hw->sih->bustype; - sha_params.buscorerev = wlc_hw->sih->buscorerev; - - /* alloc and save pointer to shared phy state area */ - wlc_hw->phy_sh = wlc_phy_shared_attach(&sha_params); - if (!wlc_hw->phy_sh) { - err = 16; - goto fail; - } - - /* initialize software state for each core and band */ - for (j = 0; j < NBANDS_HW(wlc_hw); j++) { - /* - * band0 is always 2.4Ghz - * band1, if present, is 5Ghz - */ - - /* So if this is a single band 11a card, use band 1 */ - if (IS_SINGLEBAND_5G(wlc_hw->deviceid)) - j = BAND_5G_INDEX; - - wlc_setxband(wlc_hw, j); - - wlc_hw->band->bandunit = j; - wlc_hw->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G; - wlc->band->bandunit = j; - wlc->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G; - wlc->core->coreidx = si_coreidx(wlc_hw->sih); - - if (D11REV_GE(wlc_hw->corerev, 13)) { - wlc_hw->machwcap = R_REG(wlc_hw->osh, ®s->machwcap); - wlc_hw->machwcap_backup = wlc_hw->machwcap; - } - - /* init tx fifo size */ - ASSERT((wlc_hw->corerev - XMTFIFOTBL_STARTREV) < - ARRAY_SIZE(xmtfifo_sz)); - wlc_hw->xmtfifo_sz = - xmtfifo_sz[(wlc_hw->corerev - XMTFIFOTBL_STARTREV)]; - - /* Get a phy for this band */ - wlc_hw->band->pi = wlc_phy_attach(wlc_hw->phy_sh, - (void *)regs, wlc_hw->band->bandtype, vars); - if (wlc_hw->band->pi == NULL) { - WL_ERROR("wl%d: wlc_bmac_attach: wlc_phy_attach failed\n", - unit); - err = 17; - goto fail; - } - - wlc_phy_machwcap_set(wlc_hw->band->pi, wlc_hw->machwcap); - - wlc_phy_get_phyversion(wlc_hw->band->pi, &wlc_hw->band->phytype, - &wlc_hw->band->phyrev, - &wlc_hw->band->radioid, - &wlc_hw->band->radiorev); - wlc_hw->band->abgphy_encore = - wlc_phy_get_encore(wlc_hw->band->pi); - wlc->band->abgphy_encore = wlc_phy_get_encore(wlc_hw->band->pi); - wlc_hw->band->core_flags = - wlc_phy_get_coreflags(wlc_hw->band->pi); - - /* verify good phy_type & supported phy revision */ - if (WLCISNPHY(wlc_hw->band)) { - if (NCONF_HAS(wlc_hw->band->phyrev)) - goto good_phy; - else - goto bad_phy; - } else if (WLCISLCNPHY(wlc_hw->band)) { - if (LCNCONF_HAS(wlc_hw->band->phyrev)) - goto good_phy; - else - goto bad_phy; - } else { - bad_phy: - WL_ERROR("wl%d: wlc_bmac_attach: unsupported phy type/rev (%d/%d)\n", - unit, - wlc_hw->band->phytype, wlc_hw->band->phyrev); - err = 18; - goto fail; - } - - good_phy: - /* BMAC_NOTE: wlc->band->pi should not be set below and should be done in the - * high level attach. However we can not make that change until all low level access - * is changed to wlc_hw->band->pi. Instead do the wlc->band->pi init below, keeping - * wlc_hw->band->pi as well for incremental update of low level fns, and cut over - * low only init when all fns updated. - */ - wlc->band->pi = wlc_hw->band->pi; - wlc->band->phytype = wlc_hw->band->phytype; - wlc->band->phyrev = wlc_hw->band->phyrev; - wlc->band->radioid = wlc_hw->band->radioid; - wlc->band->radiorev = wlc_hw->band->radiorev; - - /* default contention windows size limits */ - wlc_hw->band->CWmin = APHY_CWMIN; - wlc_hw->band->CWmax = PHY_CWMAX; - - if (!wlc_bmac_attach_dmapio(wlc, j, wme)) { - err = 19; - goto fail; - } - } - - /* disable core to match driver "down" state */ - wlc_coredisable(wlc_hw); - - /* Match driver "down" state */ - if (wlc_hw->sih->bustype == PCI_BUS) - si_pci_down(wlc_hw->sih); - - /* register sb interrupt callback functions */ - si_register_intr_callback(wlc_hw->sih, (void *)wlc_wlintrsoff, - (void *)wlc_wlintrsrestore, NULL, wlc); - - /* turn off pll and xtal to match driver "down" state */ - wlc_bmac_xtal(wlc_hw, OFF); - - /* ********************************************************************* - * The hardware is in the DOWN state at this point. D11 core - * or cores are in reset with clocks off, and the board PLLs - * are off if possible. - * - * Beyond this point, wlc->sbclk == false and chip registers - * should not be touched. - ********************************************************************* - */ - - /* init etheraddr state variables */ - macaddr = wlc_get_macaddr(wlc_hw); - if (macaddr == NULL) { - WL_ERROR("wl%d: wlc_bmac_attach: macaddr not found\n", unit); - err = 21; - goto fail; - } - bcm_ether_atoe(macaddr, wlc_hw->etheraddr); - if (is_broadcast_ether_addr(wlc_hw->etheraddr) || - is_zero_ether_addr(wlc_hw->etheraddr)) { - WL_ERROR("wl%d: wlc_bmac_attach: bad macaddr %s\n", - unit, macaddr); - err = 22; - goto fail; - } - - WL_ERROR("%s:: deviceid 0x%x nbands %d board 0x%x macaddr: %s\n", - __func__, wlc_hw->deviceid, wlc_hw->_nbands, - wlc_hw->sih->boardtype, macaddr); - - return err; - - fail: - WL_ERROR("wl%d: wlc_bmac_attach: failed with err %d\n", unit, err); - return err; -} - -/* - * Initialize wlc_info default values ... - * may get overrides later in this function - * BMAC_NOTES, move low out and resolve the dangling ones - */ -void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw) -{ - struct wlc_info *wlc = wlc_hw->wlc; - - /* set default sw macintmask value */ - wlc->defmacintmask = DEF_MACINTMASK; - - /* various 802.11g modes */ - wlc_hw->shortslot = false; - - wlc_hw->SFBL = RETRY_SHORT_FB; - wlc_hw->LFBL = RETRY_LONG_FB; - - /* default mac retry limits */ - wlc_hw->SRL = RETRY_SHORT_DEF; - wlc_hw->LRL = RETRY_LONG_DEF; - wlc_hw->chanspec = CH20MHZ_CHSPEC(1); -} - -/* - * low level detach - */ -int wlc_bmac_detach(struct wlc_info *wlc) -{ - uint i; - wlc_hwband_t *band; - struct wlc_hw_info *wlc_hw = wlc->hw; - int callbacks; - - callbacks = 0; - - if (wlc_hw->sih) { - /* detach interrupt sync mechanism since interrupt is disabled and per-port - * interrupt object may has been freed. this must be done before sb core switch - */ - si_deregister_intr_callback(wlc_hw->sih); - - if (wlc_hw->sih->bustype == PCI_BUS) - si_pci_sleep(wlc_hw->sih); - } - - wlc_bmac_detach_dmapio(wlc_hw); - - band = wlc_hw->band; - for (i = 0; i < NBANDS_HW(wlc_hw); i++) { - if (band->pi) { - /* Detach this band's phy */ - wlc_phy_detach(band->pi); - band->pi = NULL; - } - band = wlc_hw->bandstate[OTHERBANDUNIT(wlc)]; - } - - /* Free shared phy state */ - wlc_phy_shared_detach(wlc_hw->phy_sh); - - wlc_phy_shim_detach(wlc_hw->physhim); - - /* free vars */ - if (wlc_hw->vars) { - kfree(wlc_hw->vars); - wlc_hw->vars = NULL; - } - - if (wlc_hw->sih) { - si_detach(wlc_hw->sih); - wlc_hw->sih = NULL; - } - - return callbacks; - -} - -void wlc_bmac_reset(struct wlc_hw_info *wlc_hw) -{ - WL_TRACE("wl%d: wlc_bmac_reset\n", wlc_hw->unit); - - WLCNTINCR(wlc_hw->wlc->pub->_cnt->reset); - - /* reset the core */ - if (!DEVICEREMOVED(wlc_hw->wlc)) - wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); - - /* purge the dma rings */ - wlc_flushqueues(wlc_hw->wlc); - - wlc_reset_bmac_done(wlc_hw->wlc); -} - -void -wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, - bool mute) { - u32 macintmask; - bool fastclk; - struct wlc_info *wlc = wlc_hw->wlc; - - WL_TRACE("wl%d: wlc_bmac_init\n", wlc_hw->unit); - - /* request FAST clock if not on */ - fastclk = wlc_hw->forcefastclk; - if (!fastclk) - wlc_clkctl_clk(wlc_hw, CLK_FAST); - - /* disable interrupts */ - macintmask = wl_intrsoff(wlc->wl); - - /* set up the specified band and chanspec */ - wlc_setxband(wlc_hw, CHSPEC_WLCBANDUNIT(chanspec)); - wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec); - - /* do one-time phy inits and calibration */ - wlc_phy_cal_init(wlc_hw->band->pi); - - /* core-specific initialization */ - wlc_coreinit(wlc); - - /* suspend the tx fifos and mute the phy for preism cac time */ - if (mute) - wlc_bmac_mute(wlc_hw, ON, PHY_MUTE_FOR_PREISM); - - /* band-specific inits */ - wlc_bmac_bsinit(wlc, chanspec); - - /* restore macintmask */ - wl_intrsrestore(wlc->wl, macintmask); - - /* seed wake_override with WLC_WAKE_OVERRIDE_MACSUSPEND since the mac is suspended - * and wlc_enable_mac() will clear this override bit. - */ - mboolset(wlc_hw->wake_override, WLC_WAKE_OVERRIDE_MACSUSPEND); - - /* - * initialize mac_suspend_depth to 1 to match ucode initial suspended state - */ - wlc_hw->mac_suspend_depth = 1; - - /* restore the clk */ - if (!fastclk) - wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); -} - -int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw) -{ - uint coremask; - - WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); - - ASSERT(wlc_hw->wlc->pub->hw_up && wlc_hw->wlc->macintmask == 0); - - /* - * Enable pll and xtal, initialize the power control registers, - * and force fastclock for the remainder of wlc_up(). - */ - wlc_bmac_xtal(wlc_hw, ON); - si_clkctl_init(wlc_hw->sih); - wlc_clkctl_clk(wlc_hw, CLK_FAST); - - /* - * Configure pci/pcmcia here instead of in wlc_attach() - * to allow mfg hotswap: down, hotswap (chip power cycle), up. - */ - coremask = (1 << wlc_hw->wlc->core->coreidx); - - if (wlc_hw->sih->bustype == PCI_BUS) - si_pci_setup(wlc_hw->sih, coremask); - - ASSERT(si_coreid(wlc_hw->sih) == D11_CORE_ID); - - /* - * Need to read the hwradio status here to cover the case where the system - * is loaded with the hw radio disabled. We do not want to bring the driver up in this case. - */ - if (wlc_bmac_radio_read_hwdisabled(wlc_hw)) { - /* put SB PCI in down state again */ - if (wlc_hw->sih->bustype == PCI_BUS) - si_pci_down(wlc_hw->sih); - wlc_bmac_xtal(wlc_hw, OFF); - return BCME_RADIOOFF; - } - - if (wlc_hw->sih->bustype == PCI_BUS) - si_pci_up(wlc_hw->sih); - - /* reset the d11 core */ - wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); - - return 0; -} - -int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw) -{ - WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); - - wlc_hw->up = true; - wlc_phy_hw_state_upd(wlc_hw->band->pi, true); - - /* FULLY enable dynamic power control and d11 core interrupt */ - wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); - ASSERT(wlc_hw->wlc->macintmask == 0); - wl_intrson(wlc_hw->wlc->wl); - return 0; -} - -int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw) -{ - bool dev_gone; - uint callbacks = 0; - - WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); - - if (!wlc_hw->up) - return callbacks; - - dev_gone = DEVICEREMOVED(wlc_hw->wlc); - - /* disable interrupts */ - if (dev_gone) - wlc_hw->wlc->macintmask = 0; - else { - /* now disable interrupts */ - wl_intrsoff(wlc_hw->wlc->wl); - - /* ensure we're running on the pll clock again */ - wlc_clkctl_clk(wlc_hw, CLK_FAST); - } - /* down phy at the last of this stage */ - callbacks += wlc_phy_down(wlc_hw->band->pi); - - return callbacks; -} - -int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw) -{ - uint callbacks = 0; - bool dev_gone; - - WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); - - if (!wlc_hw->up) - return callbacks; - - wlc_hw->up = false; - wlc_phy_hw_state_upd(wlc_hw->band->pi, false); - - dev_gone = DEVICEREMOVED(wlc_hw->wlc); - - if (dev_gone) { - wlc_hw->sbclk = false; - wlc_hw->clk = false; - wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); - - /* reclaim any posted packets */ - wlc_flushqueues(wlc_hw->wlc); - } else { - - /* Reset and disable the core */ - if (si_iscoreup(wlc_hw->sih)) { - if (R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol) & - MCTL_EN_MAC) - wlc_suspend_mac_and_wait(wlc_hw->wlc); - callbacks += wl_reset(wlc_hw->wlc->wl); - wlc_coredisable(wlc_hw); - } - - /* turn off primary xtal and pll */ - if (!wlc_hw->noreset) { - if (wlc_hw->sih->bustype == PCI_BUS) - si_pci_down(wlc_hw->sih); - wlc_bmac_xtal(wlc_hw, OFF); - } - } - - return callbacks; -} - -void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw) -{ - if (D11REV_IS(wlc_hw->corerev, 4)) /* no slowclock */ - udelay(5); - else { - /* delay before first read of ucode state */ - udelay(40); - - /* wait until ucode is no longer asleep */ - SPINWAIT((wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) == - DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly); - } - - ASSERT(wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) != DBGST_ASLEEP); -} - -void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, u8 *ea) -{ - bcopy(wlc_hw->etheraddr, ea, ETH_ALEN); -} - -void wlc_bmac_set_hw_etheraddr(struct wlc_hw_info *wlc_hw, - u8 *ea) -{ - bcopy(ea, wlc_hw->etheraddr, ETH_ALEN); -} - -int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw) -{ - return wlc_hw->band->bandtype; -} - -void *wlc_cur_phy(struct wlc_info *wlc) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - return (void *)wlc_hw->band->pi; -} - -/* control chip clock to save power, enable dynamic clock or force fast clock */ -static void wlc_clkctl_clk(struct wlc_hw_info *wlc_hw, uint mode) -{ - if (PMUCTL_ENAB(wlc_hw->sih)) { - /* new chips with PMU, CCS_FORCEHT will distribute the HT clock on backplane, - * but mac core will still run on ALP(not HT) when it enters powersave mode, - * which means the FCA bit may not be set. - * should wakeup mac if driver wants it to run on HT. - */ - - if (wlc_hw->clk) { - if (mode == CLK_FAST) { - OR_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, - CCS_FORCEHT); - - udelay(64); - - SPINWAIT(((R_REG - (wlc_hw->osh, - &wlc_hw->regs-> - clk_ctl_st) & CCS_HTAVAIL) == 0), - PMU_MAX_TRANSITION_DLY); - ASSERT(R_REG - (wlc_hw->osh, - &wlc_hw->regs-> - clk_ctl_st) & CCS_HTAVAIL); - } else { - if ((wlc_hw->sih->pmurev == 0) && - (R_REG - (wlc_hw->osh, - &wlc_hw->regs-> - clk_ctl_st) & (CCS_FORCEHT | CCS_HTAREQ))) - SPINWAIT(((R_REG - (wlc_hw->osh, - &wlc_hw->regs-> - clk_ctl_st) & CCS_HTAVAIL) - == 0), - PMU_MAX_TRANSITION_DLY); - AND_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, - ~CCS_FORCEHT); - } - } - wlc_hw->forcefastclk = (mode == CLK_FAST); - } else { - bool wakeup_ucode; - - /* old chips w/o PMU, force HT through cc, - * then use FCA to verify mac is running fast clock - */ - - wakeup_ucode = D11REV_LT(wlc_hw->corerev, 9); - - if (wlc_hw->up && wakeup_ucode) - wlc_ucode_wake_override_set(wlc_hw, - WLC_WAKE_OVERRIDE_CLKCTL); - - wlc_hw->forcefastclk = si_clkctl_cc(wlc_hw->sih, mode); - - if (D11REV_LT(wlc_hw->corerev, 11)) { - /* ucode WAR for old chips */ - if (wlc_hw->forcefastclk) - wlc_bmac_mhf(wlc_hw, MHF1, MHF1_FORCEFASTCLK, - MHF1_FORCEFASTCLK, WLC_BAND_ALL); - else - wlc_bmac_mhf(wlc_hw, MHF1, MHF1_FORCEFASTCLK, 0, - WLC_BAND_ALL); - } - - /* check fast clock is available (if core is not in reset) */ - if (D11REV_GT(wlc_hw->corerev, 4) && wlc_hw->forcefastclk - && wlc_hw->clk) - ASSERT(si_core_sflags(wlc_hw->sih, 0, 0) & SISF_FCLKA); - - /* keep the ucode wake bit on if forcefastclk is on - * since we do not want ucode to put us back to slow clock - * when it dozes for PM mode. - * Code below matches the wake override bit with current forcefastclk state - * Only setting bit in wake_override instead of waking ucode immediately - * since old code (wlc.c 1.4499) had this behavior. Older code set - * wlc->forcefastclk but only had the wake happen if the wakup_ucode work - * (protected by an up check) was executed just below. - */ - if (wlc_hw->forcefastclk) - mboolset(wlc_hw->wake_override, - WLC_WAKE_OVERRIDE_FORCEFAST); - else - mboolclr(wlc_hw->wake_override, - WLC_WAKE_OVERRIDE_FORCEFAST); - - /* ok to clear the wakeup now */ - if (wlc_hw->up && wakeup_ucode) - wlc_ucode_wake_override_clear(wlc_hw, - WLC_WAKE_OVERRIDE_CLKCTL); - } -} - -/* set initial host flags value */ -static void -wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - - memset(mhfs, 0, MHFMAX * sizeof(u16)); - - mhfs[MHF2] |= mhf2_init; - - /* prohibit use of slowclock on multifunction boards */ - if (wlc_hw->boardflags & BFL_NOPLLDOWN) - mhfs[MHF1] |= MHF1_FORCEFASTCLK; - - if (WLCISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 2)) { - mhfs[MHF2] |= MHF2_NPHY40MHZ_WAR; - mhfs[MHF1] |= MHF1_IQSWAP_WAR; - } -} - -/* set or clear ucode host flag bits - * it has an optimization for no-change write - * it only writes through shared memory when the core has clock; - * pre-CLK changes should use wlc_write_mhf to get around the optimization - * - * - * bands values are: WLC_BAND_AUTO <--- Current band only - * WLC_BAND_5G <--- 5G band only - * WLC_BAND_2G <--- 2G band only - * WLC_BAND_ALL <--- All bands - */ -void -wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, u16 val, - int bands) -{ - u16 save; - u16 addr[MHFMAX] = { - M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4, - M_HOST_FLAGS5 - }; - wlc_hwband_t *band; - - ASSERT((val & ~mask) == 0); - ASSERT(idx < MHFMAX); - ASSERT(ARRAY_SIZE(addr) == MHFMAX); - - switch (bands) { - /* Current band only or all bands, - * then set the band to current band - */ - case WLC_BAND_AUTO: - case WLC_BAND_ALL: - band = wlc_hw->band; - break; - case WLC_BAND_5G: - band = wlc_hw->bandstate[BAND_5G_INDEX]; - break; - case WLC_BAND_2G: - band = wlc_hw->bandstate[BAND_2G_INDEX]; - break; - default: - ASSERT(0); - band = NULL; - } - - if (band) { - save = band->mhfs[idx]; - band->mhfs[idx] = (band->mhfs[idx] & ~mask) | val; - - /* optimization: only write through if changed, and - * changed band is the current band - */ - if (wlc_hw->clk && (band->mhfs[idx] != save) - && (band == wlc_hw->band)) - wlc_bmac_write_shm(wlc_hw, addr[idx], - (u16) band->mhfs[idx]); - } - - if (bands == WLC_BAND_ALL) { - wlc_hw->bandstate[0]->mhfs[idx] = - (wlc_hw->bandstate[0]->mhfs[idx] & ~mask) | val; - wlc_hw->bandstate[1]->mhfs[idx] = - (wlc_hw->bandstate[1]->mhfs[idx] & ~mask) | val; - } -} - -u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands) -{ - wlc_hwband_t *band; - ASSERT(idx < MHFMAX); - - switch (bands) { - case WLC_BAND_AUTO: - band = wlc_hw->band; - break; - case WLC_BAND_5G: - band = wlc_hw->bandstate[BAND_5G_INDEX]; - break; - case WLC_BAND_2G: - band = wlc_hw->bandstate[BAND_2G_INDEX]; - break; - default: - ASSERT(0); - band = NULL; - } - - if (!band) - return 0; - - return band->mhfs[idx]; -} - -static void wlc_write_mhf(struct wlc_hw_info *wlc_hw, u16 *mhfs) -{ - u8 idx; - u16 addr[] = { - M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4, - M_HOST_FLAGS5 - }; - - ASSERT(ARRAY_SIZE(addr) == MHFMAX); - - for (idx = 0; idx < MHFMAX; idx++) { - wlc_bmac_write_shm(wlc_hw, addr[idx], mhfs[idx]); - } -} - -/* set the maccontrol register to desired reset state and - * initialize the sw cache of the register - */ -static void wlc_mctrl_reset(struct wlc_hw_info *wlc_hw) -{ - /* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */ - wlc_hw->maccontrol = 0; - wlc_hw->suspended_fifos = 0; - wlc_hw->wake_override = 0; - wlc_hw->mute_override = 0; - wlc_bmac_mctrl(wlc_hw, ~0, MCTL_IHR_EN | MCTL_WAKE); -} - -/* set or clear maccontrol bits */ -void wlc_bmac_mctrl(struct wlc_hw_info *wlc_hw, u32 mask, u32 val) -{ - u32 maccontrol; - u32 new_maccontrol; - - ASSERT((val & ~mask) == 0); - - maccontrol = wlc_hw->maccontrol; - new_maccontrol = (maccontrol & ~mask) | val; - - /* if the new maccontrol value is the same as the old, nothing to do */ - if (new_maccontrol == maccontrol) - return; - - /* something changed, cache the new value */ - wlc_hw->maccontrol = new_maccontrol; - - /* write the new values with overrides applied */ - wlc_mctrl_write(wlc_hw); -} - -/* write the software state of maccontrol and overrides to the maccontrol register */ -static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw) -{ - u32 maccontrol = wlc_hw->maccontrol; - - /* OR in the wake bit if overridden */ - if (wlc_hw->wake_override) - maccontrol |= MCTL_WAKE; - - /* set AP and INFRA bits for mute if needed */ - if (wlc_hw->mute_override) { - maccontrol &= ~(MCTL_AP); - maccontrol |= MCTL_INFRA; - } - - W_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol, maccontrol); -} - -void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, u32 override_bit) -{ - ASSERT((wlc_hw->wake_override & override_bit) == 0); - - if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) { - mboolset(wlc_hw->wake_override, override_bit); - return; - } - - mboolset(wlc_hw->wake_override, override_bit); - - wlc_mctrl_write(wlc_hw); - wlc_bmac_wait_for_wake(wlc_hw); - - return; -} - -void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw, u32 override_bit) -{ - ASSERT(wlc_hw->wake_override & override_bit); - - mboolclr(wlc_hw->wake_override, override_bit); - - if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) - return; - - wlc_mctrl_write(wlc_hw); - - return; -} - -/* When driver needs ucode to stop beaconing, it has to make sure that - * MCTL_AP is clear and MCTL_INFRA is set - * Mode MCTL_AP MCTL_INFRA - * AP 1 1 - * STA 0 1 <--- This will ensure no beacons - * IBSS 0 0 - */ -static void wlc_ucode_mute_override_set(struct wlc_hw_info *wlc_hw) -{ - wlc_hw->mute_override = 1; - - /* if maccontrol already has AP == 0 and INFRA == 1 without this - * override, then there is no change to write - */ - if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA) - return; - - wlc_mctrl_write(wlc_hw); - - return; -} - -/* Clear the override on AP and INFRA bits */ -static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw) -{ - if (wlc_hw->mute_override == 0) - return; - - wlc_hw->mute_override = 0; - - /* if maccontrol already has AP == 0 and INFRA == 1 without this - * override, then there is no change to write - */ - if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA) - return; - - wlc_mctrl_write(wlc_hw); -} - -/* - * Write a MAC address to the rcmta structure - */ -void -wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, - const u8 *addr) -{ - d11regs_t *regs = wlc_hw->regs; - volatile u16 *objdata16 = (volatile u16 *)®s->objdata; - u32 mac_hm; - u16 mac_l; - struct osl_info *osh; - - WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); - - ASSERT(wlc_hw->corerev > 4); - - mac_hm = - (addr[3] << 24) | (addr[2] << 16) | - (addr[1] << 8) | addr[0]; - mac_l = (addr[5] << 8) | addr[4]; - - osh = wlc_hw->osh; - - W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, ®s->objdata, mac_hm); - W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1))); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, objdata16, mac_l); -} - -/* - * Write a MAC address to the given match reg offset in the RXE match engine. - */ -void -wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset, - const u8 *addr) -{ - d11regs_t *regs; - u16 mac_l; - u16 mac_m; - u16 mac_h; - struct osl_info *osh; - - WL_TRACE("wl%d: wlc_bmac_set_addrmatch\n", wlc_hw->unit); - - ASSERT((match_reg_offset < RCM_SIZE) || (wlc_hw->corerev == 4)); - - regs = wlc_hw->regs; - mac_l = addr[0] | (addr[1] << 8); - mac_m = addr[2] | (addr[3] << 8); - mac_h = addr[4] | (addr[5] << 8); - - osh = wlc_hw->osh; - - /* enter the MAC addr into the RXE match registers */ - W_REG(osh, ®s->rcm_ctl, RCM_INC_DATA | match_reg_offset); - W_REG(osh, ®s->rcm_mat_data, mac_l); - W_REG(osh, ®s->rcm_mat_data, mac_m); - W_REG(osh, ®s->rcm_mat_data, mac_h); - -} - -void -wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, int len, - void *buf) -{ - d11regs_t *regs; - u32 word; - bool be_bit; -#ifdef IL_BIGENDIAN - volatile u16 *dptr = NULL; -#endif /* IL_BIGENDIAN */ - struct osl_info *osh; - - WL_TRACE("wl%d: wlc_bmac_write_template_ram\n", wlc_hw->unit); - - regs = wlc_hw->regs; - osh = wlc_hw->osh; - - ASSERT(IS_ALIGNED(offset, sizeof(u32))); - ASSERT(IS_ALIGNED(len, sizeof(u32))); - ASSERT((offset & ~0xffff) == 0); - - W_REG(osh, ®s->tplatewrptr, offset); - - /* if MCTL_BIGEND bit set in mac control register, - * the chip swaps data in fifo, as well as data in - * template ram - */ - be_bit = (R_REG(osh, ®s->maccontrol) & MCTL_BIGEND) != 0; - - while (len > 0) { - bcopy((u8 *) buf, &word, sizeof(u32)); - - if (be_bit) - word = hton32(word); - else - word = htol32(word); - - W_REG(osh, ®s->tplatewrdata, word); - - buf = (u8 *) buf + sizeof(u32); - len -= sizeof(u32); - } -} - -void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin) -{ - struct osl_info *osh; - - osh = wlc_hw->osh; - wlc_hw->band->CWmin = newmin; - - W_REG(osh, &wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMIN); - (void)R_REG(osh, &wlc_hw->regs->objaddr); - W_REG(osh, &wlc_hw->regs->objdata, newmin); -} - -void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax) -{ - struct osl_info *osh; - - osh = wlc_hw->osh; - wlc_hw->band->CWmax = newmax; - - W_REG(osh, &wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMAX); - (void)R_REG(osh, &wlc_hw->regs->objaddr); - W_REG(osh, &wlc_hw->regs->objdata, newmax); -} - -void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw) -{ - bool fastclk; - u32 tmp; - - /* request FAST clock if not on */ - fastclk = wlc_hw->forcefastclk; - if (!fastclk) - wlc_clkctl_clk(wlc_hw, CLK_FAST); - - wlc_phy_bw_state_set(wlc_hw->band->pi, bw); - - ASSERT(wlc_hw->clk); - if (D11REV_LT(wlc_hw->corerev, 17)) - tmp = R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol); - - wlc_bmac_phy_reset(wlc_hw); - wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi)); - - /* restore the clk */ - if (!fastclk) - wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); -} - -static void -wlc_write_hw_bcntemplate0(struct wlc_hw_info *wlc_hw, void *bcn, int len) -{ - d11regs_t *regs = wlc_hw->regs; - - wlc_bmac_write_template_ram(wlc_hw, T_BCN0_TPL_BASE, (len + 3) & ~3, - bcn); - /* write beacon length to SCR */ - ASSERT(len < 65536); - wlc_bmac_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len); - /* mark beacon0 valid */ - OR_REG(wlc_hw->osh, ®s->maccommand, MCMD_BCN0VLD); -} - -static void -wlc_write_hw_bcntemplate1(struct wlc_hw_info *wlc_hw, void *bcn, int len) -{ - d11regs_t *regs = wlc_hw->regs; - - wlc_bmac_write_template_ram(wlc_hw, T_BCN1_TPL_BASE, (len + 3) & ~3, - bcn); - /* write beacon length to SCR */ - ASSERT(len < 65536); - wlc_bmac_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len); - /* mark beacon1 valid */ - OR_REG(wlc_hw->osh, ®s->maccommand, MCMD_BCN1VLD); -} - -/* mac is assumed to be suspended at this point */ -void -wlc_bmac_write_hw_bcntemplates(struct wlc_hw_info *wlc_hw, void *bcn, int len, - bool both) -{ - d11regs_t *regs = wlc_hw->regs; - - if (both) { - wlc_write_hw_bcntemplate0(wlc_hw, bcn, len); - wlc_write_hw_bcntemplate1(wlc_hw, bcn, len); - } else { - /* bcn 0 */ - if (!(R_REG(wlc_hw->osh, ®s->maccommand) & MCMD_BCN0VLD)) - wlc_write_hw_bcntemplate0(wlc_hw, bcn, len); - /* bcn 1 */ - else if (! - (R_REG(wlc_hw->osh, ®s->maccommand) & MCMD_BCN1VLD)) - wlc_write_hw_bcntemplate1(wlc_hw, bcn, len); - else /* one template should always have been available */ - ASSERT(0); - } -} - -static void WLBANDINITFN(wlc_bmac_upd_synthpu) (struct wlc_hw_info *wlc_hw) -{ - u16 v; - struct wlc_info *wlc = wlc_hw->wlc; - /* update SYNTHPU_DLY */ - - if (WLCISLCNPHY(wlc->band)) { - v = SYNTHPU_DLY_LPPHY_US; - } else if (WLCISNPHY(wlc->band) && (NREV_GE(wlc->band->phyrev, 3))) { - v = SYNTHPU_DLY_NPHY_US; - } else { - v = SYNTHPU_DLY_BPHY_US; - } - - wlc_bmac_write_shm(wlc_hw, M_SYNTHPU_DLY, v); -} - -/* band-specific init */ -static void -WLBANDINITFN(wlc_bmac_bsinit) (struct wlc_info *wlc, chanspec_t chanspec) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - - WL_TRACE("wl%d: wlc_bmac_bsinit: bandunit %d\n", - wlc_hw->unit, wlc_hw->band->bandunit); - - /* sanity check */ - if (PHY_TYPE(R_REG(wlc_hw->osh, &wlc_hw->regs->phyversion)) != - PHY_TYPE_LCNXN) - ASSERT((uint) - PHY_TYPE(R_REG(wlc_hw->osh, &wlc_hw->regs->phyversion)) - == wlc_hw->band->phytype); - - wlc_ucode_bsinit(wlc_hw); - - wlc_phy_init(wlc_hw->band->pi, chanspec); - - wlc_ucode_txant_set(wlc_hw); - - /* cwmin is band-specific, update hardware with value for current band */ - wlc_bmac_set_cwmin(wlc_hw, wlc_hw->band->CWmin); - wlc_bmac_set_cwmax(wlc_hw, wlc_hw->band->CWmax); - - wlc_bmac_update_slot_timing(wlc_hw, - BAND_5G(wlc_hw->band-> - bandtype) ? true : wlc_hw-> - shortslot); - - /* write phytype and phyvers */ - wlc_bmac_write_shm(wlc_hw, M_PHYTYPE, (u16) wlc_hw->band->phytype); - wlc_bmac_write_shm(wlc_hw, M_PHYVER, (u16) wlc_hw->band->phyrev); - - /* initialize the txphyctl1 rate table since shmem is shared between bands */ - wlc_upd_ofdm_pctl1_table(wlc_hw); - - wlc_bmac_upd_synthpu(wlc_hw); -} - -void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk) -{ - WL_TRACE("wl%d: wlc_bmac_core_phy_clk: clk %d\n", wlc_hw->unit, clk); - - wlc_hw->phyclk = clk; - - if (OFF == clk) { /* clear gmode bit, put phy into reset */ - - si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC | SICF_GMODE), - (SICF_PRST | SICF_FGC)); - udelay(1); - si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_PRST); - udelay(1); - - } else { /* take phy out of reset */ - - si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_FGC); - udelay(1); - si_core_cflags(wlc_hw->sih, (SICF_FGC), 0); - udelay(1); - - } -} - -/* Perform a soft reset of the PHY PLL */ -void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw) -{ - WL_TRACE("wl%d: wlc_bmac_core_phypll_reset\n", wlc_hw->unit); - - si_corereg(wlc_hw->sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_addr), ~0, 0); - udelay(1); - si_corereg(wlc_hw->sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_data), 0x4, 0); - udelay(1); - si_corereg(wlc_hw->sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_data), 0x4, 4); - udelay(1); - si_corereg(wlc_hw->sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_data), 0x4, 0); - udelay(1); -} - -/* light way to turn on phy clock without reset for NPHY only - * refer to wlc_bmac_core_phy_clk for full version - */ -void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk) -{ - /* support(necessary for NPHY and HYPHY) only */ - if (!WLCISNPHY(wlc_hw->band)) - return; - - if (ON == clk) - si_core_cflags(wlc_hw->sih, SICF_FGC, SICF_FGC); - else - si_core_cflags(wlc_hw->sih, SICF_FGC, 0); - -} - -void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk) -{ - if (ON == clk) - si_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE); - else - si_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0); -} - -void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw) -{ - wlc_phy_t *pih = wlc_hw->band->pi; - u32 phy_bw_clkbits; - bool phy_in_reset = false; - - WL_TRACE("wl%d: wlc_bmac_phy_reset\n", wlc_hw->unit); - - if (pih == NULL) - return; - - phy_bw_clkbits = wlc_phy_clk_bwbits(wlc_hw->band->pi); - - /* Specfic reset sequence required for NPHY rev 3 and 4 */ - if (WLCISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) && - NREV_LE(wlc_hw->band->phyrev, 4)) { - /* Set the PHY bandwidth */ - si_core_cflags(wlc_hw->sih, SICF_BWMASK, phy_bw_clkbits); - - udelay(1); - - /* Perform a soft reset of the PHY PLL */ - wlc_bmac_core_phypll_reset(wlc_hw); - - /* reset the PHY */ - si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE), - (SICF_PRST | SICF_PCLKE)); - phy_in_reset = true; - } else { - - si_core_cflags(wlc_hw->sih, - (SICF_PRST | SICF_PCLKE | SICF_BWMASK), - (SICF_PRST | SICF_PCLKE | phy_bw_clkbits)); - } - - udelay(2); - wlc_bmac_core_phy_clk(wlc_hw, ON); - - if (pih) - wlc_phy_anacore(pih, ON); -} - -/* switch to and initialize new band */ -static void -WLBANDINITFN(wlc_bmac_setband) (struct wlc_hw_info *wlc_hw, uint bandunit, - chanspec_t chanspec) { - struct wlc_info *wlc = wlc_hw->wlc; - u32 macintmask; - - ASSERT(NBANDS_HW(wlc_hw) > 1); - ASSERT(bandunit != wlc_hw->band->bandunit); - - /* Enable the d11 core before accessing it */ - if (!si_iscoreup(wlc_hw->sih)) { - si_core_reset(wlc_hw->sih, 0, 0); - ASSERT(si_iscoreup(wlc_hw->sih)); - wlc_mctrl_reset(wlc_hw); - } - - macintmask = wlc_setband_inact(wlc, bandunit); - - if (!wlc_hw->up) - return; - - wlc_bmac_core_phy_clk(wlc_hw, ON); - - /* band-specific initializations */ - wlc_bmac_bsinit(wlc, chanspec); - - /* - * If there are any pending software interrupt bits, - * then replace these with a harmless nonzero value - * so wlc_dpc() will re-enable interrupts when done. - */ - if (wlc->macintstatus) - wlc->macintstatus = MI_DMAINT; - - /* restore macintmask */ - wl_intrsrestore(wlc->wl, macintmask); - - /* ucode should still be suspended.. */ - ASSERT((R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol) & MCTL_EN_MAC) == - 0); -} - -/* low-level band switch utility routine */ -void WLBANDINITFN(wlc_setxband) (struct wlc_hw_info *wlc_hw, uint bandunit) -{ - WL_TRACE("wl%d: wlc_setxband: bandunit %d\n", wlc_hw->unit, bandunit); - - wlc_hw->band = wlc_hw->bandstate[bandunit]; - - /* BMAC_NOTE: until we eliminate need for wlc->band refs in low level code */ - wlc_hw->wlc->band = wlc_hw->wlc->bandstate[bandunit]; - - /* set gmode core flag */ - if (wlc_hw->sbclk && !wlc_hw->noreset) { - si_core_cflags(wlc_hw->sih, SICF_GMODE, - ((bandunit == 0) ? SICF_GMODE : 0)); - } -} - -static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw) -{ - - /* reject unsupported corerev */ - if (!VALID_COREREV(wlc_hw->corerev)) { - WL_ERROR("unsupported core rev %d\n", wlc_hw->corerev); - return false; - } - - return true; -} - -static bool wlc_validboardtype(struct wlc_hw_info *wlc_hw) -{ - bool goodboard = true; - uint boardrev = wlc_hw->boardrev; - - if (boardrev == 0) - goodboard = false; - else if (boardrev > 0xff) { - uint brt = (boardrev & 0xf000) >> 12; - uint b0 = (boardrev & 0xf00) >> 8; - uint b1 = (boardrev & 0xf0) >> 4; - uint b2 = boardrev & 0xf; - - if ((brt > 2) || (brt == 0) || (b0 > 9) || (b0 == 0) || (b1 > 9) - || (b2 > 9)) - goodboard = false; - } - - if (wlc_hw->sih->boardvendor != VENDOR_BROADCOM) - return goodboard; - - return goodboard; -} - -static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw) -{ - const char *varname = "macaddr"; - char *macaddr; - - /* If macaddr exists, use it (Sromrev4, CIS, ...). */ - macaddr = getvar(wlc_hw->vars, varname); - if (macaddr != NULL) - return macaddr; - - if (NBANDS_HW(wlc_hw) > 1) - varname = "et1macaddr"; - else - varname = "il0macaddr"; - - macaddr = getvar(wlc_hw->vars, varname); - if (macaddr == NULL) { - WL_ERROR("wl%d: wlc_get_macaddr: macaddr getvar(%s) not found\n", - wlc_hw->unit, varname); - } - - return macaddr; -} - -/* - * Return true if radio is disabled, otherwise false. - * hw radio disable signal is an external pin, users activate it asynchronously - * this function could be called when driver is down and w/o clock - * it operates on different registers depending on corerev and boardflag. - */ -bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw) -{ - bool v, clk, xtal; - u32 resetbits = 0, flags = 0; - - xtal = wlc_hw->sbclk; - if (!xtal) - wlc_bmac_xtal(wlc_hw, ON); - - /* may need to take core out of reset first */ - clk = wlc_hw->clk; - if (!clk) { - if (D11REV_LE(wlc_hw->corerev, 11)) - resetbits |= SICF_PCLKE; - - /* - * corerev >= 18, mac no longer enables phyclk automatically when driver accesses - * phyreg throughput mac. This can be skipped since only mac reg is accessed below - */ - if (D11REV_GE(wlc_hw->corerev, 18)) - flags |= SICF_PCLKE; - - /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */ - if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || - (wlc_hw->sih->chip == BCM43225_CHIP_ID) || - (wlc_hw->sih->chip == BCM43421_CHIP_ID)) - wlc_hw->regs = - (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, - 0); - si_core_reset(wlc_hw->sih, flags, resetbits); - wlc_mctrl_reset(wlc_hw); - } - - v = ((R_REG(wlc_hw->osh, &wlc_hw->regs->phydebug) & PDBG_RFD) != 0); - - /* put core back into reset */ - if (!clk) - si_core_disable(wlc_hw->sih, 0); - - if (!xtal) - wlc_bmac_xtal(wlc_hw, OFF); - - return v; -} - -/* Initialize just the hardware when coming out of POR or S3/S5 system states */ -void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw) -{ - if (wlc_hw->wlc->pub->hw_up) - return; - - WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); - - /* - * Enable pll and xtal, initialize the power control registers, - * and force fastclock for the remainder of wlc_up(). - */ - wlc_bmac_xtal(wlc_hw, ON); - si_clkctl_init(wlc_hw->sih); - wlc_clkctl_clk(wlc_hw, CLK_FAST); - - if (wlc_hw->sih->bustype == PCI_BUS) { - si_pci_fixcfg(wlc_hw->sih); - - /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */ - if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || - (wlc_hw->sih->chip == BCM43225_CHIP_ID) || - (wlc_hw->sih->chip == BCM43421_CHIP_ID)) - wlc_hw->regs = - (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, - 0); - } - - /* Inform phy that a POR reset has occurred so it does a complete phy init */ - wlc_phy_por_inform(wlc_hw->band->pi); - - wlc_hw->ucode_loaded = false; - wlc_hw->wlc->pub->hw_up = true; - - if ((wlc_hw->boardflags & BFL_FEM) - && (wlc_hw->sih->chip == BCM4313_CHIP_ID)) { - if (! - (wlc_hw->boardrev >= 0x1250 - && (wlc_hw->boardflags & BFL_FEM_BT))) - si_epa_4313war(wlc_hw->sih); - } -} - -static bool wlc_dma_rxreset(struct wlc_hw_info *wlc_hw, uint fifo) -{ - struct hnddma_pub *di = wlc_hw->di[fifo]; - struct osl_info *osh; - - if (D11REV_LT(wlc_hw->corerev, 12)) { - bool rxidle = true; - u16 rcv_frm_cnt = 0; - - osh = wlc_hw->osh; - - W_REG(osh, &wlc_hw->regs->rcv_fifo_ctl, fifo << 8); - SPINWAIT((!(rxidle = dma_rxidle(di))) && - ((rcv_frm_cnt = - R_REG(osh, &wlc_hw->regs->rcv_frm_cnt)) != 0), - 50000); - - if (!rxidle && (rcv_frm_cnt != 0)) - WL_ERROR("wl%d: %s: rxdma[%d] not idle && rcv_frm_cnt(%d) not zero\n", - wlc_hw->unit, __func__, fifo, rcv_frm_cnt); - mdelay(2); - } - - return dma_rxreset(di); -} - -/* d11 core reset - * ensure fask clock during reset - * reset dma - * reset d11(out of reset) - * reset phy(out of reset) - * clear software macintstatus for fresh new start - * one testing hack wlc_hw->noreset will bypass the d11/phy reset - */ -void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags) -{ - d11regs_t *regs; - uint i; - bool fastclk; - u32 resetbits = 0; - - if (flags == WLC_USE_COREFLAGS) - flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0); - - WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); - - regs = wlc_hw->regs; - - /* request FAST clock if not on */ - fastclk = wlc_hw->forcefastclk; - if (!fastclk) - wlc_clkctl_clk(wlc_hw, CLK_FAST); - - /* reset the dma engines except first time thru */ - if (si_iscoreup(wlc_hw->sih)) { - for (i = 0; i < NFIFO; i++) - if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) { - WL_ERROR("wl%d: %s: dma_txreset[%d]: cannot stop dma\n", - wlc_hw->unit, __func__, i); - } - - if ((wlc_hw->di[RX_FIFO]) - && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) { - WL_ERROR("wl%d: %s: dma_rxreset[%d]: cannot stop dma\n", - wlc_hw->unit, __func__, RX_FIFO); - } - if (D11REV_IS(wlc_hw->corerev, 4) - && wlc_hw->di[RX_TXSTATUS_FIFO] - && (!wlc_dma_rxreset(wlc_hw, RX_TXSTATUS_FIFO))) { - WL_ERROR("wl%d: %s: dma_rxreset[%d]: cannot stop dma\n", - wlc_hw->unit, __func__, RX_TXSTATUS_FIFO); - } - } - /* if noreset, just stop the psm and return */ - if (wlc_hw->noreset) { - wlc_hw->wlc->macintstatus = 0; /* skip wl_dpc after down */ - wlc_bmac_mctrl(wlc_hw, MCTL_PSM_RUN | MCTL_EN_MAC, 0); - return; - } - - if (D11REV_LE(wlc_hw->corerev, 11)) - resetbits |= SICF_PCLKE; - - /* - * corerev >= 18, mac no longer enables phyclk automatically when driver accesses phyreg - * throughput mac, AND phy_reset is skipped at early stage when band->pi is invalid - * need to enable PHY CLK - */ - if (D11REV_GE(wlc_hw->corerev, 18)) - flags |= SICF_PCLKE; - - /* reset the core - * In chips with PMU, the fastclk request goes through d11 core reg 0x1e0, which - * is cleared by the core_reset. have to re-request it. - * This adds some delay and we can optimize it by also requesting fastclk through - * chipcommon during this period if necessary. But that has to work coordinate - * with other driver like mips/arm since they may touch chipcommon as well. - */ - wlc_hw->clk = false; - si_core_reset(wlc_hw->sih, flags, resetbits); - wlc_hw->clk = true; - if (wlc_hw->band && wlc_hw->band->pi) - wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true); - - wlc_mctrl_reset(wlc_hw); - - if (PMUCTL_ENAB(wlc_hw->sih)) - wlc_clkctl_clk(wlc_hw, CLK_FAST); - - wlc_bmac_phy_reset(wlc_hw); - - /* turn on PHY_PLL */ - wlc_bmac_core_phypll_ctl(wlc_hw, true); - - /* clear sw intstatus */ - wlc_hw->wlc->macintstatus = 0; - - /* restore the clk setting */ - if (!fastclk) - wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); -} - -/* If the ucode that supports corerev 5 is used for corerev 9 and above, - * txfifo sizes needs to be modified(increased) since the newer cores - * have more memory. - */ -static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw) -{ - d11regs_t *regs = wlc_hw->regs; - u16 fifo_nu; - u16 txfifo_startblk = TXFIFO_START_BLK, txfifo_endblk; - u16 txfifo_def, txfifo_def1; - u16 txfifo_cmd; - struct osl_info *osh; - - if (D11REV_LT(wlc_hw->corerev, 9)) - goto exit; - - /* tx fifos start at TXFIFO_START_BLK from the Base address */ - txfifo_startblk = TXFIFO_START_BLK; - - osh = wlc_hw->osh; - - /* sequence of operations: reset fifo, set fifo size, reset fifo */ - for (fifo_nu = 0; fifo_nu < NFIFO; fifo_nu++) { - - txfifo_endblk = txfifo_startblk + wlc_hw->xmtfifo_sz[fifo_nu]; - txfifo_def = (txfifo_startblk & 0xff) | - (((txfifo_endblk - 1) & 0xff) << TXFIFO_FIFOTOP_SHIFT); - txfifo_def1 = ((txfifo_startblk >> 8) & 0x1) | - ((((txfifo_endblk - - 1) >> 8) & 0x1) << TXFIFO_FIFOTOP_SHIFT); - txfifo_cmd = - TXFIFOCMD_RESET_MASK | (fifo_nu << TXFIFOCMD_FIFOSEL_SHIFT); - - W_REG(osh, ®s->xmtfifocmd, txfifo_cmd); - W_REG(osh, ®s->xmtfifodef, txfifo_def); - if (D11REV_GE(wlc_hw->corerev, 16)) - W_REG(osh, ®s->xmtfifodef1, txfifo_def1); - - W_REG(osh, ®s->xmtfifocmd, txfifo_cmd); - - txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu]; - } - exit: - /* need to propagate to shm location to be in sync since ucode/hw won't do this */ - wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE0, - wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]); - wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE1, - wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]); - wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE2, - ((wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO] << 8) | wlc_hw-> - xmtfifo_sz[TX_AC_BK_FIFO])); - wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE3, - ((wlc_hw->xmtfifo_sz[TX_ATIM_FIFO] << 8) | wlc_hw-> - xmtfifo_sz[TX_BCMC_FIFO])); -} - -/* d11 core init - * reset PSM - * download ucode/PCM - * let ucode run to suspended - * download ucode inits - * config other core registers - * init dma - */ -static void wlc_coreinit(struct wlc_info *wlc) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - d11regs_t *regs; - u32 sflags; - uint bcnint_us; - uint i = 0; - bool fifosz_fixup = false; - struct osl_info *osh; - int err = 0; - u16 buf[NFIFO]; - - regs = wlc_hw->regs; - osh = wlc_hw->osh; - - WL_TRACE("wl%d: wlc_coreinit\n", wlc_hw->unit); - - /* reset PSM */ - wlc_bmac_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE)); - - wlc_ucode_download(wlc_hw); - /* - * FIFOSZ fixup - * 1) core5-9 use ucode 5 to save space since the PSM is the same - * 2) newer chips, driver wants to controls the fifo allocation - */ - if (D11REV_GE(wlc_hw->corerev, 4)) - fifosz_fixup = true; - - /* let the PSM run to the suspended state, set mode to BSS STA */ - W_REG(osh, ®s->macintstatus, -1); - wlc_bmac_mctrl(wlc_hw, ~0, - (MCTL_IHR_EN | MCTL_INFRA | MCTL_PSM_RUN | MCTL_WAKE)); - - /* wait for ucode to self-suspend after auto-init */ - SPINWAIT(((R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD) == 0), - 1000 * 1000); - if ((R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD) == 0) - WL_ERROR("wl%d: wlc_coreinit: ucode did not self-suspend!\n", - wlc_hw->unit); - - wlc_gpio_init(wlc); - - sflags = si_core_sflags(wlc_hw->sih, 0, 0); - - if (D11REV_IS(wlc_hw->corerev, 23)) { - if (WLCISNPHY(wlc_hw->band)) - wlc_write_inits(wlc_hw, d11n0initvals16); - else - WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); - } else if (D11REV_IS(wlc_hw->corerev, 24)) { - if (WLCISLCNPHY(wlc_hw->band)) { - wlc_write_inits(wlc_hw, d11lcn0initvals24); - } else { - WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); - } - } else { - WL_ERROR("%s: wl%d: unsupported corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); - } - - /* For old ucode, txfifo sizes needs to be modified(increased) for Corerev >= 9 */ - if (fifosz_fixup == true) { - wlc_corerev_fifofixup(wlc_hw); - } - - /* check txfifo allocations match between ucode and driver */ - buf[TX_AC_BE_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE0); - if (buf[TX_AC_BE_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]) { - i = TX_AC_BE_FIFO; - err = -1; - } - buf[TX_AC_VI_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE1); - if (buf[TX_AC_VI_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]) { - i = TX_AC_VI_FIFO; - err = -1; - } - buf[TX_AC_BK_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE2); - buf[TX_AC_VO_FIFO] = (buf[TX_AC_BK_FIFO] >> 8) & 0xff; - buf[TX_AC_BK_FIFO] &= 0xff; - if (buf[TX_AC_BK_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BK_FIFO]) { - i = TX_AC_BK_FIFO; - err = -1; - } - if (buf[TX_AC_VO_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO]) { - i = TX_AC_VO_FIFO; - err = -1; - } - buf[TX_BCMC_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE3); - buf[TX_ATIM_FIFO] = (buf[TX_BCMC_FIFO] >> 8) & 0xff; - buf[TX_BCMC_FIFO] &= 0xff; - if (buf[TX_BCMC_FIFO] != wlc_hw->xmtfifo_sz[TX_BCMC_FIFO]) { - i = TX_BCMC_FIFO; - err = -1; - } - if (buf[TX_ATIM_FIFO] != wlc_hw->xmtfifo_sz[TX_ATIM_FIFO]) { - i = TX_ATIM_FIFO; - err = -1; - } - if (err != 0) { - WL_ERROR("wlc_coreinit: txfifo mismatch: ucode size %d driver size %d index %d\n", - buf[i], wlc_hw->xmtfifo_sz[i], i); - /* DO NOT ASSERT corerev < 4 even there is a mismatch - * shmem, since driver don't overwrite those chip and - * ucode initialize data will be used. - */ - if (D11REV_GE(wlc_hw->corerev, 4)) - ASSERT(0); - } - - /* make sure we can still talk to the mac */ - ASSERT(R_REG(osh, ®s->maccontrol) != 0xffffffff); - - /* band-specific inits done by wlc_bsinit() */ - - /* Set up frame burst size and antenna swap threshold init values */ - wlc_bmac_write_shm(wlc_hw, M_MBURST_SIZE, MAXTXFRAMEBURST); - wlc_bmac_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT); - - /* enable one rx interrupt per received frame */ - W_REG(osh, ®s->intrcvlazy[0], (1 << IRL_FC_SHIFT)); - if (D11REV_IS(wlc_hw->corerev, 4)) - W_REG(osh, ®s->intrcvlazy[3], (1 << IRL_FC_SHIFT)); - - /* set the station mode (BSS STA) */ - wlc_bmac_mctrl(wlc_hw, - (MCTL_INFRA | MCTL_DISCARD_PMQ | MCTL_AP), - (MCTL_INFRA | MCTL_DISCARD_PMQ)); - - /* set up Beacon interval */ - bcnint_us = 0x8000 << 10; - W_REG(osh, ®s->tsf_cfprep, (bcnint_us << CFPREP_CBI_SHIFT)); - W_REG(osh, ®s->tsf_cfpstart, bcnint_us); - W_REG(osh, ®s->macintstatus, MI_GP1); - - /* write interrupt mask */ - W_REG(osh, ®s->intctrlregs[RX_FIFO].intmask, DEF_RXINTMASK); - if (D11REV_IS(wlc_hw->corerev, 4)) - W_REG(osh, ®s->intctrlregs[RX_TXSTATUS_FIFO].intmask, - DEF_RXINTMASK); - - /* allow the MAC to control the PHY clock (dynamic on/off) */ - wlc_bmac_macphyclk_set(wlc_hw, ON); - - /* program dynamic clock control fast powerup delay register */ - if (D11REV_GT(wlc_hw->corerev, 4)) { - wlc->fastpwrup_dly = si_clkctl_fast_pwrup_delay(wlc_hw->sih); - W_REG(osh, ®s->scc_fastpwrup_dly, wlc->fastpwrup_dly); - } - - /* tell the ucode the corerev */ - wlc_bmac_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev); - - /* tell the ucode MAC capabilities */ - if (D11REV_GE(wlc_hw->corerev, 13)) { - wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_L, - (u16) (wlc_hw->machwcap & 0xffff)); - wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_H, - (u16) ((wlc_hw-> - machwcap >> 16) & 0xffff)); - } - - /* write retry limits to SCR, this done after PSM init */ - W_REG(osh, ®s->objaddr, OBJADDR_SCR_SEL | S_DOT11_SRC_LMT); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, ®s->objdata, wlc_hw->SRL); - W_REG(osh, ®s->objaddr, OBJADDR_SCR_SEL | S_DOT11_LRC_LMT); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, ®s->objdata, wlc_hw->LRL); - - /* write rate fallback retry limits */ - wlc_bmac_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL); - wlc_bmac_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL); - - if (D11REV_GE(wlc_hw->corerev, 16)) { - AND_REG(osh, ®s->ifs_ctl, 0x0FFF); - W_REG(osh, ®s->ifs_aifsn, EDCF_AIFSN_MIN); - } - - /* dma initializations */ - wlc->txpend16165war = 0; - - /* init the tx dma engines */ - for (i = 0; i < NFIFO; i++) { - if (wlc_hw->di[i]) - dma_txinit(wlc_hw->di[i]); - } - - /* init the rx dma engine(s) and post receive buffers */ - dma_rxinit(wlc_hw->di[RX_FIFO]); - dma_rxfill(wlc_hw->di[RX_FIFO]); - if (D11REV_IS(wlc_hw->corerev, 4)) { - dma_rxinit(wlc_hw->di[RX_TXSTATUS_FIFO]); - dma_rxfill(wlc_hw->di[RX_TXSTATUS_FIFO]); - } -} - -/* This function is used for changing the tsf frac register - * If spur avoidance mode is off, the mac freq will be 80/120/160Mhz - * If spur avoidance mode is on1, the mac freq will be 82/123/164Mhz - * If spur avoidance mode is on2, the mac freq will be 84/126/168Mhz - * HTPHY Formula is 2^26/freq(MHz) e.g. - * For spuron2 - 126MHz -> 2^26/126 = 532610.0 - * - 532610 = 0x82082 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x2082 - * For spuron: 123MHz -> 2^26/123 = 545600.5 - * - 545601 = 0x85341 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x5341 - * For spur off: 120MHz -> 2^26/120 = 559240.5 - * - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889 - */ - -void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode) -{ - d11regs_t *regs; - struct osl_info *osh; - regs = wlc_hw->regs; - osh = wlc_hw->osh; - - if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || - (wlc_hw->sih->chip == BCM43225_CHIP_ID)) { - if (spurmode == WL_SPURAVOID_ON2) { /* 126Mhz */ - W_REG(osh, ®s->tsf_clk_frac_l, 0x2082); - W_REG(osh, ®s->tsf_clk_frac_h, 0x8); - } else if (spurmode == WL_SPURAVOID_ON1) { /* 123Mhz */ - W_REG(osh, ®s->tsf_clk_frac_l, 0x5341); - W_REG(osh, ®s->tsf_clk_frac_h, 0x8); - } else { /* 120Mhz */ - W_REG(osh, ®s->tsf_clk_frac_l, 0x8889); - W_REG(osh, ®s->tsf_clk_frac_h, 0x8); - } - } else if (WLCISLCNPHY(wlc_hw->band)) { - if (spurmode == WL_SPURAVOID_ON1) { /* 82Mhz */ - W_REG(osh, ®s->tsf_clk_frac_l, 0x7CE0); - W_REG(osh, ®s->tsf_clk_frac_h, 0xC); - } else { /* 80Mhz */ - W_REG(osh, ®s->tsf_clk_frac_l, 0xCCCD); - W_REG(osh, ®s->tsf_clk_frac_h, 0xC); - } - } -} - -/* Initialize GPIOs that are controlled by D11 core */ -static void wlc_gpio_init(struct wlc_info *wlc) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - d11regs_t *regs; - u32 gc, gm; - struct osl_info *osh; - - regs = wlc_hw->regs; - osh = wlc_hw->osh; - - /* use GPIO select 0 to get all gpio signals from the gpio out reg */ - wlc_bmac_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0); - - /* - * Common GPIO setup: - * G0 = LED 0 = WLAN Activity - * G1 = LED 1 = WLAN 2.4 GHz Radio State - * G2 = LED 2 = WLAN 5 GHz Radio State - * G4 = radio disable input (HI enabled, LO disabled) - */ - - gc = gm = 0; - - /* Allocate GPIOs for mimo antenna diversity feature */ - if (WLANTSEL_ENAB(wlc)) { - if (wlc_hw->antsel_type == ANTSEL_2x3) { - /* Enable antenna diversity, use 2x3 mode */ - wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, - MHF3_ANTSEL_EN, WLC_BAND_ALL); - wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, - MHF3_ANTSEL_MODE, WLC_BAND_ALL); - - /* init superswitch control */ - wlc_phy_antsel_init(wlc_hw->band->pi, false); - - } else if (wlc_hw->antsel_type == ANTSEL_2x4) { - ASSERT((gm & BOARD_GPIO_12) == 0); - gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13); - /* The board itself is powered by these GPIOs (when not sending pattern) - * So set them high - */ - OR_REG(osh, ®s->psm_gpio_oe, - (BOARD_GPIO_12 | BOARD_GPIO_13)); - OR_REG(osh, ®s->psm_gpio_out, - (BOARD_GPIO_12 | BOARD_GPIO_13)); - - /* Enable antenna diversity, use 2x4 mode */ - wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, - MHF3_ANTSEL_EN, WLC_BAND_ALL); - wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0, - WLC_BAND_ALL); - - /* Configure the desired clock to be 4Mhz */ - wlc_bmac_write_shm(wlc_hw, M_ANTSEL_CLKDIV, - ANTSEL_CLKDIV_4MHZ); - } - } - /* gpio 9 controls the PA. ucode is responsible for wiggling out and oe */ - if (wlc_hw->boardflags & BFL_PACTRL) - gm |= gc |= BOARD_GPIO_PACTRL; - - /* apply to gpiocontrol register */ - si_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY); -} - -static void wlc_ucode_download(struct wlc_hw_info *wlc_hw) -{ - struct wlc_info *wlc; - wlc = wlc_hw->wlc; - - if (wlc_hw->ucode_loaded) - return; - - if (D11REV_IS(wlc_hw->corerev, 23)) { - if (WLCISNPHY(wlc_hw->band)) { - wlc_ucode_write(wlc_hw, bcm43xx_16_mimo, - bcm43xx_16_mimosz); - wlc_hw->ucode_loaded = true; - } else - WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); - } else if (D11REV_IS(wlc_hw->corerev, 24)) { - if (WLCISLCNPHY(wlc_hw->band)) { - wlc_ucode_write(wlc_hw, bcm43xx_24_lcn, - bcm43xx_24_lcnsz); - wlc_hw->ucode_loaded = true; - } else { - WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); - } - } -} - -static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[], - const uint nbytes) { - struct osl_info *osh; - d11regs_t *regs = wlc_hw->regs; - uint i; - uint count; - - osh = wlc_hw->osh; - - WL_TRACE("wl%d: wlc_ucode_write\n", wlc_hw->unit); - - ASSERT(IS_ALIGNED(nbytes, sizeof(u32))); - - count = (nbytes / sizeof(u32)); - - W_REG(osh, ®s->objaddr, (OBJADDR_AUTO_INC | OBJADDR_UCM_SEL)); - (void)R_REG(osh, ®s->objaddr); - for (i = 0; i < count; i++) - W_REG(osh, ®s->objdata, ucode[i]); -} - -static void wlc_write_inits(struct wlc_hw_info *wlc_hw, const d11init_t *inits) -{ - int i; - struct osl_info *osh; - volatile u8 *base; - - WL_TRACE("wl%d: wlc_write_inits\n", wlc_hw->unit); - - osh = wlc_hw->osh; - base = (volatile u8 *)wlc_hw->regs; - - for (i = 0; inits[i].addr != 0xffff; i++) { - ASSERT((inits[i].size == 2) || (inits[i].size == 4)); - - if (inits[i].size == 2) - W_REG(osh, (u16 *)(base + inits[i].addr), - inits[i].value); - else if (inits[i].size == 4) - W_REG(osh, (u32 *)(base + inits[i].addr), - inits[i].value); - } -} - -static void wlc_ucode_txant_set(struct wlc_hw_info *wlc_hw) -{ - u16 phyctl; - u16 phytxant = wlc_hw->bmac_phytxant; - u16 mask = PHY_TXC_ANT_MASK; - - /* set the Probe Response frame phy control word */ - phyctl = wlc_bmac_read_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS); - phyctl = (phyctl & ~mask) | phytxant; - wlc_bmac_write_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS, phyctl); - - /* set the Response (ACK/CTS) frame phy control word */ - phyctl = wlc_bmac_read_shm(wlc_hw, M_RSP_PCTLWD); - phyctl = (phyctl & ~mask) | phytxant; - wlc_bmac_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl); -} - -void wlc_bmac_txant_set(struct wlc_hw_info *wlc_hw, u16 phytxant) -{ - /* update sw state */ - wlc_hw->bmac_phytxant = phytxant; - - /* push to ucode if up */ - if (!wlc_hw->up) - return; - wlc_ucode_txant_set(wlc_hw); - -} - -u16 wlc_bmac_get_txant(struct wlc_hw_info *wlc_hw) -{ - return (u16) wlc_hw->wlc->stf->txant; -} - -void wlc_bmac_antsel_type_set(struct wlc_hw_info *wlc_hw, u8 antsel_type) -{ - wlc_hw->antsel_type = antsel_type; - - /* Update the antsel type for phy module to use */ - wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type); -} - -void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw) -{ - bool fatal = false; - uint unit; - uint intstatus, idx; - d11regs_t *regs = wlc_hw->regs; - - unit = wlc_hw->unit; - - for (idx = 0; idx < NFIFO; idx++) { - /* read intstatus register and ignore any non-error bits */ - intstatus = - R_REG(wlc_hw->osh, - ®s->intctrlregs[idx].intstatus) & I_ERRORS; - if (!intstatus) - continue; - - WL_TRACE("wl%d: wlc_bmac_fifoerrors: intstatus%d 0x%x\n", - unit, idx, intstatus); - - if (intstatus & I_RO) { - WL_ERROR("wl%d: fifo %d: receive fifo overflow\n", - unit, idx); - WLCNTINCR(wlc_hw->wlc->pub->_cnt->rxoflo); - fatal = true; - } - - if (intstatus & I_PC) { - WL_ERROR("wl%d: fifo %d: descriptor error\n", - unit, idx); - WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmade); - fatal = true; - } - - if (intstatus & I_PD) { - WL_ERROR("wl%d: fifo %d: data error\n", unit, idx); - WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmada); - fatal = true; - } - - if (intstatus & I_DE) { - WL_ERROR("wl%d: fifo %d: descriptor protocol error\n", - unit, idx); - WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmape); - fatal = true; - } - - if (intstatus & I_RU) { - WL_ERROR("wl%d: fifo %d: receive descriptor underflow\n", - idx, unit); - WLCNTINCR(wlc_hw->wlc->pub->_cnt->rxuflo[idx]); - } - - if (intstatus & I_XU) { - WL_ERROR("wl%d: fifo %d: transmit fifo underflow\n", - idx, unit); - WLCNTINCR(wlc_hw->wlc->pub->_cnt->txuflo); - fatal = true; - } - - if (fatal) { - wlc_fatal_error(wlc_hw->wlc); /* big hammer */ - break; - } else - W_REG(wlc_hw->osh, ®s->intctrlregs[idx].intstatus, - intstatus); - } -} - -void wlc_intrson(struct wlc_info *wlc) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - ASSERT(wlc->defmacintmask); - wlc->macintmask = wlc->defmacintmask; - W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, wlc->macintmask); -} - -/* callback for siutils.c, which has only wlc handler, no wl - * they both check up, not only because there is no need to off/restore d11 interrupt - * but also because per-port code may require sync with valid interrupt. - */ - -static u32 wlc_wlintrsoff(struct wlc_info *wlc) -{ - if (!wlc->hw->up) - return 0; - - return wl_intrsoff(wlc->wl); -} - -static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask) -{ - if (!wlc->hw->up) - return; - - wl_intrsrestore(wlc->wl, macintmask); -} - -u32 wlc_intrsoff(struct wlc_info *wlc) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - u32 macintmask; - - if (!wlc_hw->clk) - return 0; - - macintmask = wlc->macintmask; /* isr can still happen */ - - W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, 0); - (void)R_REG(wlc_hw->osh, &wlc_hw->regs->macintmask); /* sync readback */ - udelay(1); /* ensure int line is no longer driven */ - wlc->macintmask = 0; - - /* return previous macintmask; resolve race between us and our isr */ - return wlc->macintstatus ? 0 : macintmask; -} - -void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - if (!wlc_hw->clk) - return; - - wlc->macintmask = macintmask; - W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, wlc->macintmask); -} - -void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool on, mbool flags) -{ - u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; - - if (on) { - /* suspend tx fifos */ - wlc_bmac_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO); - wlc_bmac_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO); - wlc_bmac_tx_fifo_suspend(wlc_hw, TX_AC_BK_FIFO); - wlc_bmac_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO); - - /* zero the address match register so we do not send ACKs */ - wlc_bmac_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, - null_ether_addr); - } else { - /* resume tx fifos */ - if (!wlc_hw->wlc->tx_suspended) { - wlc_bmac_tx_fifo_resume(wlc_hw, TX_DATA_FIFO); - } - wlc_bmac_tx_fifo_resume(wlc_hw, TX_CTL_FIFO); - wlc_bmac_tx_fifo_resume(wlc_hw, TX_AC_BK_FIFO); - wlc_bmac_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO); - - /* Restore address */ - wlc_bmac_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, - wlc_hw->etheraddr); - } - - wlc_phy_mute_upd(wlc_hw->band->pi, on, flags); - - if (on) - wlc_ucode_mute_override_set(wlc_hw); - else - wlc_ucode_mute_override_clear(wlc_hw); -} - -void wlc_bmac_set_deaf(struct wlc_hw_info *wlc_hw, bool user_flag) -{ - wlc_phy_set_deaf(wlc_hw->band->pi, user_flag); -} - -int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, uint *blocks) -{ - if (fifo >= NFIFO) - return BCME_RANGE; - - *blocks = wlc_hw->xmtfifo_sz[fifo]; - - return 0; -} - -int wlc_bmac_xmtfifo_sz_set(struct wlc_hw_info *wlc_hw, uint fifo, uint blocks) -{ - if (fifo >= NFIFO || blocks > 299) - return BCME_RANGE; - - /* BMAC_NOTE, change blocks to u16 */ - wlc_hw->xmtfifo_sz[fifo] = (u16) blocks; - - return 0; -} - -/* wlc_bmac_tx_fifo_suspended: - * Check the MAC's tx suspend status for a tx fifo. - * - * When the MAC acknowledges a tx suspend, it indicates that no more - * packets will be transmitted out the radio. This is independent of - * DMA channel suspension---the DMA may have finished suspending, or may still - * be pulling data into a tx fifo, by the time the MAC acks the suspend - * request. - */ -bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, uint tx_fifo) -{ - /* check that a suspend has been requested and is no longer pending */ - - /* - * for DMA mode, the suspend request is set in xmtcontrol of the DMA engine, - * and the tx fifo suspend at the lower end of the MAC is acknowledged in the - * chnstatus register. - * The tx fifo suspend completion is independent of the DMA suspend completion and - * may be acked before or after the DMA is suspended. - */ - if (dma_txsuspended(wlc_hw->di[tx_fifo]) && - (R_REG(wlc_hw->osh, &wlc_hw->regs->chnstatus) & - (1 << tx_fifo)) == 0) - return true; - - return false; -} - -void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo) -{ - u8 fifo = 1 << tx_fifo; - - /* Two clients of this code, 11h Quiet period and scanning. */ - - /* only suspend if not already suspended */ - if ((wlc_hw->suspended_fifos & fifo) == fifo) - return; - - /* force the core awake only if not already */ - if (wlc_hw->suspended_fifos == 0) - wlc_ucode_wake_override_set(wlc_hw, WLC_WAKE_OVERRIDE_TXFIFO); - - wlc_hw->suspended_fifos |= fifo; - - if (wlc_hw->di[tx_fifo]) { - /* Suspending AMPDU transmissions in the middle can cause underflow - * which may result in mismatch between ucode and driver - * so suspend the mac before suspending the FIFO - */ - if (WLC_PHY_11N_CAP(wlc_hw->band)) - wlc_suspend_mac_and_wait(wlc_hw->wlc); - - dma_txsuspend(wlc_hw->di[tx_fifo]); - - if (WLC_PHY_11N_CAP(wlc_hw->band)) - wlc_enable_mac(wlc_hw->wlc); - } -} - -void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo) -{ - /* BMAC_NOTE: WLC_TX_FIFO_ENAB is done in wlc_dpc() for DMA case but need to be done - * here for PIO otherwise the watchdog will catch the inconsistency and fire - */ - /* Two clients of this code, 11h Quiet period and scanning. */ - if (wlc_hw->di[tx_fifo]) - dma_txresume(wlc_hw->di[tx_fifo]); - - /* allow core to sleep again */ - if (wlc_hw->suspended_fifos == 0) - return; - else { - wlc_hw->suspended_fifos &= ~(1 << tx_fifo); - if (wlc_hw->suspended_fifos == 0) - wlc_ucode_wake_override_clear(wlc_hw, - WLC_WAKE_OVERRIDE_TXFIFO); - } -} - -/* - * Read and clear macintmask and macintstatus and intstatus registers. - * This routine should be called with interrupts off - * Return: - * -1 if DEVICEREMOVED(wlc) evaluates to true; - * 0 if the interrupt is not for us, or we are in some special cases; - * device interrupt status bits otherwise. - */ -static inline u32 wlc_intstatus(struct wlc_info *wlc, bool in_isr) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - d11regs_t *regs = wlc_hw->regs; - u32 macintstatus; - u32 intstatus_rxfifo, intstatus_txsfifo; - struct osl_info *osh; - - osh = wlc_hw->osh; - - /* macintstatus includes a DMA interrupt summary bit */ - macintstatus = R_REG(osh, ®s->macintstatus); - - WL_TRACE("wl%d: macintstatus: 0x%x\n", wlc_hw->unit, macintstatus); - - /* detect cardbus removed, in power down(suspend) and in reset */ - if (DEVICEREMOVED(wlc)) - return -1; - - /* DEVICEREMOVED succeeds even when the core is still resetting, - * handle that case here. - */ - if (macintstatus == 0xffffffff) - return 0; - - /* defer unsolicited interrupts */ - macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask); - - /* if not for us */ - if (macintstatus == 0) - return 0; - - /* interrupts are already turned off for CFE build - * Caution: For CFE Turning off the interrupts again has some undesired - * consequences - */ - /* turn off the interrupts */ - W_REG(osh, ®s->macintmask, 0); - (void)R_REG(osh, ®s->macintmask); /* sync readback */ - wlc->macintmask = 0; - - /* clear device interrupts */ - W_REG(osh, ®s->macintstatus, macintstatus); - - /* MI_DMAINT is indication of non-zero intstatus */ - if (macintstatus & MI_DMAINT) { - if (D11REV_IS(wlc_hw->corerev, 4)) { - intstatus_rxfifo = - R_REG(osh, ®s->intctrlregs[RX_FIFO].intstatus); - intstatus_txsfifo = - R_REG(osh, - ®s->intctrlregs[RX_TXSTATUS_FIFO]. - intstatus); - WL_TRACE("wl%d: intstatus_rxfifo 0x%x, intstatus_txsfifo 0x%x\n", - wlc_hw->unit, - intstatus_rxfifo, intstatus_txsfifo); - - /* defer unsolicited interrupt hints */ - intstatus_rxfifo &= DEF_RXINTMASK; - intstatus_txsfifo &= DEF_RXINTMASK; - - /* MI_DMAINT bit in macintstatus is indication of RX_FIFO interrupt */ - /* clear interrupt hints */ - if (intstatus_rxfifo) - W_REG(osh, - ®s->intctrlregs[RX_FIFO].intstatus, - intstatus_rxfifo); - else - macintstatus &= ~MI_DMAINT; - - /* MI_TFS bit in macintstatus is encoding of RX_TXSTATUS_FIFO interrupt */ - if (intstatus_txsfifo) { - W_REG(osh, - ®s->intctrlregs[RX_TXSTATUS_FIFO]. - intstatus, intstatus_txsfifo); - macintstatus |= MI_TFS; - } - } else { - /* - * For corerevs >= 5, only fifo interrupt enabled is I_RI in RX_FIFO. - * If MI_DMAINT is set, assume it is set and clear the interrupt. - */ - W_REG(osh, ®s->intctrlregs[RX_FIFO].intstatus, - DEF_RXINTMASK); - } - } - - return macintstatus; -} - -/* Update wlc->macintstatus and wlc->intstatus[]. */ -/* Return true if they are updated successfully. false otherwise */ -bool wlc_intrsupd(struct wlc_info *wlc) -{ - u32 macintstatus; - - ASSERT(wlc->macintstatus != 0); - - /* read and clear macintstatus and intstatus registers */ - macintstatus = wlc_intstatus(wlc, false); - - /* device is removed */ - if (macintstatus == 0xffffffff) - return false; - - /* update interrupt status in software */ - wlc->macintstatus |= macintstatus; - - return true; -} - -/* - * First-level interrupt processing. - * Return true if this was our interrupt, false otherwise. - * *wantdpc will be set to true if further wlc_dpc() processing is required, - * false otherwise. - */ -bool BCMFASTPATH wlc_isr(struct wlc_info *wlc, bool *wantdpc) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - u32 macintstatus; - - *wantdpc = false; - - if (!wlc_hw->up || !wlc->macintmask) - return false; - - /* read and clear macintstatus and intstatus registers */ - macintstatus = wlc_intstatus(wlc, true); - - if (macintstatus == 0xffffffff) - WL_ERROR("DEVICEREMOVED detected in the ISR code path\n"); - - /* it is not for us */ - if (macintstatus == 0) - return false; - - *wantdpc = true; - - /* save interrupt status bits */ - ASSERT(wlc->macintstatus == 0); - wlc->macintstatus = macintstatus; - - return true; - -} - -/* process tx completion events for corerev < 5 */ -static bool wlc_bmac_txstatus_corerev4(struct wlc_hw_info *wlc_hw) -{ - struct sk_buff *status_p; - tx_status_t *txs; - struct osl_info *osh; - bool fatal = false; - - WL_TRACE("wl%d: wlc_txstatusrecv\n", wlc_hw->unit); - - osh = wlc_hw->osh; - - while (!fatal && (status_p = dma_rx(wlc_hw->di[RX_TXSTATUS_FIFO]))) { - - txs = (tx_status_t *) status_p->data; - /* MAC uses little endian only */ - ltoh16_buf((void *)txs, sizeof(tx_status_t)); - - /* shift low bits for tx_status_t status compatibility */ - txs->status = (txs->status & ~TXS_COMPAT_MASK) - | (((txs->status & TXS_COMPAT_MASK) << TXS_COMPAT_SHIFT)); - - fatal = wlc_bmac_dotxstatus(wlc_hw, txs, 0); - - pkt_buf_free_skb(osh, status_p, false); - } - - if (fatal) - return true; - - /* post more rbufs */ - dma_rxfill(wlc_hw->di[RX_TXSTATUS_FIFO]); - - return false; -} - -static bool BCMFASTPATH -wlc_bmac_dotxstatus(struct wlc_hw_info *wlc_hw, tx_status_t *txs, u32 s2) -{ - /* discard intermediate indications for ucode with one legitimate case: - * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent - * tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts - * transmission count) - */ - if (!(txs->status & TX_STATUS_AMPDU) - && (txs->status & TX_STATUS_INTERMEDIATE)) { - return false; - } - - return wlc_dotxstatus(wlc_hw->wlc, txs, s2); -} - -/* process tx completion events in BMAC - * Return true if more tx status need to be processed. false otherwise. - */ -static bool BCMFASTPATH -wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal) -{ - bool morepending = false; - struct wlc_info *wlc = wlc_hw->wlc; - - WL_TRACE("wl%d: wlc_bmac_txstatus\n", wlc_hw->unit); - - if (D11REV_IS(wlc_hw->corerev, 4)) { - /* to retire soon */ - *fatal = wlc_bmac_txstatus_corerev4(wlc->hw); - - if (*fatal) - return 0; - } else { - /* corerev >= 5 */ - d11regs_t *regs; - struct osl_info *osh; - tx_status_t txstatus, *txs; - u32 s1, s2; - uint n = 0; - /* Param 'max_tx_num' indicates max. # tx status to process before break out. */ - uint max_tx_num = bound ? wlc->pub->tunables->txsbnd : -1; - - txs = &txstatus; - regs = wlc_hw->regs; - osh = wlc_hw->osh; - while (!(*fatal) - && (s1 = R_REG(osh, ®s->frmtxstatus)) & TXS_V) { - - if (s1 == 0xffffffff) { - WL_ERROR("wl%d: %s: dead chip\n", - wlc_hw->unit, __func__); - ASSERT(s1 != 0xffffffff); - return morepending; - } - - s2 = R_REG(osh, ®s->frmtxstatus2); - - txs->status = s1 & TXS_STATUS_MASK; - txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT; - txs->sequence = s2 & TXS_SEQ_MASK; - txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT; - txs->lasttxtime = 0; - - *fatal = wlc_bmac_dotxstatus(wlc_hw, txs, s2); - - /* !give others some time to run! */ - if (++n >= max_tx_num) - break; - } - - if (*fatal) - return 0; - - if (n >= max_tx_num) - morepending = true; - } - - if (!pktq_empty(&wlc->active_queue->q)) - wlc_send_q(wlc, wlc->active_queue); - - return morepending; -} - -void wlc_suspend_mac_and_wait(struct wlc_info *wlc) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - d11regs_t *regs = wlc_hw->regs; - u32 mc, mi; - struct osl_info *osh; - - WL_TRACE("wl%d: wlc_suspend_mac_and_wait: bandunit %d\n", - wlc_hw->unit, wlc_hw->band->bandunit); - - /* - * Track overlapping suspend requests - */ - wlc_hw->mac_suspend_depth++; - if (wlc_hw->mac_suspend_depth > 1) - return; - - osh = wlc_hw->osh; - - /* force the core awake */ - wlc_ucode_wake_override_set(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND); - - mc = R_REG(osh, ®s->maccontrol); - - if (mc == 0xffffffff) { - WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); - wl_down(wlc->wl); - return; - } - ASSERT(!(mc & MCTL_PSM_JMP_0)); - ASSERT(mc & MCTL_PSM_RUN); - ASSERT(mc & MCTL_EN_MAC); - - mi = R_REG(osh, ®s->macintstatus); - if (mi == 0xffffffff) { - WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); - wl_down(wlc->wl); - return; - } - ASSERT(!(mi & MI_MACSSPNDD)); - - wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, 0); - - SPINWAIT(!(R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD), - WLC_MAX_MAC_SUSPEND); - - if (!(R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD)) { - WL_ERROR("wl%d: wlc_suspend_mac_and_wait: waited %d uS and MI_MACSSPNDD is still not on.\n", - wlc_hw->unit, WLC_MAX_MAC_SUSPEND); - WL_ERROR("wl%d: psmdebug 0x%08x, phydebug 0x%08x, psm_brc 0x%04x\n", - wlc_hw->unit, - R_REG(osh, ®s->psmdebug), - R_REG(osh, ®s->phydebug), - R_REG(osh, ®s->psm_brc)); - } - - mc = R_REG(osh, ®s->maccontrol); - if (mc == 0xffffffff) { - WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); - wl_down(wlc->wl); - return; - } - ASSERT(!(mc & MCTL_PSM_JMP_0)); - ASSERT(mc & MCTL_PSM_RUN); - ASSERT(!(mc & MCTL_EN_MAC)); -} - -void wlc_enable_mac(struct wlc_info *wlc) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - d11regs_t *regs = wlc_hw->regs; - u32 mc, mi; - struct osl_info *osh; - - WL_TRACE("wl%d: wlc_enable_mac: bandunit %d\n", - wlc_hw->unit, wlc->band->bandunit); - - /* - * Track overlapping suspend requests - */ - ASSERT(wlc_hw->mac_suspend_depth > 0); - wlc_hw->mac_suspend_depth--; - if (wlc_hw->mac_suspend_depth > 0) - return; - - osh = wlc_hw->osh; - - mc = R_REG(osh, ®s->maccontrol); - ASSERT(!(mc & MCTL_PSM_JMP_0)); - ASSERT(!(mc & MCTL_EN_MAC)); - ASSERT(mc & MCTL_PSM_RUN); - - wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC); - W_REG(osh, ®s->macintstatus, MI_MACSSPNDD); - - mc = R_REG(osh, ®s->maccontrol); - ASSERT(!(mc & MCTL_PSM_JMP_0)); - ASSERT(mc & MCTL_EN_MAC); - ASSERT(mc & MCTL_PSM_RUN); - - mi = R_REG(osh, ®s->macintstatus); - ASSERT(!(mi & MI_MACSSPNDD)); - - wlc_ucode_wake_override_clear(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND); -} - -void wlc_bmac_ifsctl_edcrs_set(struct wlc_hw_info *wlc_hw, bool abie, bool isht) -{ - if (!(WLCISNPHY(wlc_hw->band) && (D11REV_GE(wlc_hw->corerev, 16)))) - return; - - if (isht) { - if (WLCISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 3)) { - AND_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - ~IFS_CTL1_EDCRS); - } - } else { - /* enable EDCRS for non-11n association */ - OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, IFS_CTL1_EDCRS); - } - - if (WLCISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3)) { - if (CHSPEC_IS20(wlc_hw->chanspec)) { - /* 20 mhz, use 20U ED only */ - OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - IFS_CTL1_EDCRS); - AND_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - ~IFS_CTL1_EDCRS_20L); - AND_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - ~IFS_CTL1_EDCRS_40); - } else { - /* 40 mhz, use 20U 20L and 40 ED */ - OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - IFS_CTL1_EDCRS); - OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - IFS_CTL1_EDCRS_20L); - OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - IFS_CTL1_EDCRS_40); - } - } -} - -static void wlc_upd_ofdm_pctl1_table(struct wlc_hw_info *wlc_hw) -{ - u8 rate; - u8 rates[8] = { - WLC_RATE_6M, WLC_RATE_9M, WLC_RATE_12M, WLC_RATE_18M, - WLC_RATE_24M, WLC_RATE_36M, WLC_RATE_48M, WLC_RATE_54M - }; - u16 entry_ptr; - u16 pctl1; - uint i; - - if (!WLC_PHY_11N_CAP(wlc_hw->band)) - return; - - /* walk the phy rate table and update the entries */ - for (i = 0; i < ARRAY_SIZE(rates); i++) { - rate = rates[i]; - - entry_ptr = wlc_bmac_ofdm_ratetable_offset(wlc_hw, rate); - - /* read the SHM Rate Table entry OFDM PCTL1 values */ - pctl1 = - wlc_bmac_read_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS); - - /* modify the value */ - pctl1 &= ~PHY_TXC1_MODE_MASK; - pctl1 |= (wlc_hw->hw_stf_ss_opmode << PHY_TXC1_MODE_SHIFT); - - /* Update the SHM Rate Table entry OFDM PCTL1 values */ - wlc_bmac_write_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS, - pctl1); - } -} - -static u16 wlc_bmac_ofdm_ratetable_offset(struct wlc_hw_info *wlc_hw, u8 rate) -{ - uint i; - u8 plcp_rate = 0; - struct plcp_signal_rate_lookup { - u8 rate; - u8 signal_rate; - }; - /* OFDM RATE sub-field of PLCP SIGNAL field, per 802.11 sec 17.3.4.1 */ - const struct plcp_signal_rate_lookup rate_lookup[] = { - {WLC_RATE_6M, 0xB}, - {WLC_RATE_9M, 0xF}, - {WLC_RATE_12M, 0xA}, - {WLC_RATE_18M, 0xE}, - {WLC_RATE_24M, 0x9}, - {WLC_RATE_36M, 0xD}, - {WLC_RATE_48M, 0x8}, - {WLC_RATE_54M, 0xC} - }; - - for (i = 0; i < ARRAY_SIZE(rate_lookup); i++) { - if (rate == rate_lookup[i].rate) { - plcp_rate = rate_lookup[i].signal_rate; - break; - } - } - - /* Find the SHM pointer to the rate table entry by looking in the - * Direct-map Table - */ - return 2 * wlc_bmac_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2)); -} - -void wlc_bmac_band_stf_ss_set(struct wlc_hw_info *wlc_hw, u8 stf_mode) -{ - wlc_hw->hw_stf_ss_opmode = stf_mode; - - if (wlc_hw->clk) - wlc_upd_ofdm_pctl1_table(wlc_hw); -} - -void BCMFASTPATH -wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr, - u32 *tsf_h_ptr) -{ - d11regs_t *regs = wlc_hw->regs; - - /* read the tsf timer low, then high to get an atomic read */ - *tsf_l_ptr = R_REG(wlc_hw->osh, ®s->tsf_timerlow); - *tsf_h_ptr = R_REG(wlc_hw->osh, ®s->tsf_timerhigh); - - return; -} - -bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) -{ - d11regs_t *regs; - u32 w, val; - volatile u16 *reg16; - struct osl_info *osh; - - WL_TRACE("wl%d: validate_chip_access\n", wlc_hw->unit); - - regs = wlc_hw->regs; - osh = wlc_hw->osh; - - /* Validate dchip register access */ - - W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(osh, ®s->objaddr); - w = R_REG(osh, ®s->objdata); - - /* Can we write and read back a 32bit register? */ - W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, ®s->objdata, (u32) 0xaa5555aa); - - W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(osh, ®s->objaddr); - val = R_REG(osh, ®s->objdata); - if (val != (u32) 0xaa5555aa) { - WL_ERROR("wl%d: validate_chip_access: SHM = 0x%x, expected 0xaa5555aa\n", - wlc_hw->unit, val); - return false; - } - - W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, ®s->objdata, (u32) 0x55aaaa55); - - W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(osh, ®s->objaddr); - val = R_REG(osh, ®s->objdata); - if (val != (u32) 0x55aaaa55) { - WL_ERROR("wl%d: validate_chip_access: SHM = 0x%x, expected 0x55aaaa55\n", - wlc_hw->unit, val); - return false; - } - - W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, ®s->objdata, w); - - if (D11REV_LT(wlc_hw->corerev, 11)) { - /* if 32 bit writes are split into 16 bit writes, are they in the correct order - * for our interface, low to high - */ - reg16 = (volatile u16 *)®s->tsf_cfpstart; - - /* write the CFPStart register low half explicitly, starting a buffered write */ - W_REG(osh, reg16, 0xAAAA); - - /* Write a 32 bit value to CFPStart to test the 16 bit split order. - * If the low 16 bits are written first, followed by the high 16 bits then the - * 32 bit value 0xCCCCBBBB should end up in the register. - * If the order is reversed, then the write to the high half will trigger a buffered - * write of 0xCCCCAAAA. - * If the bus is 32 bits, then this is not much of a test, and the reg should - * have the correct value 0xCCCCBBBB. - */ - W_REG(osh, ®s->tsf_cfpstart, 0xCCCCBBBB); - - /* verify with the 16 bit registers that have no side effects */ - val = R_REG(osh, ®s->tsf_cfpstrt_l); - if (val != (uint) 0xBBBB) { - WL_ERROR("wl%d: validate_chip_access: tsf_cfpstrt_l = 0x%x, expected 0x%x\n", - wlc_hw->unit, val, 0xBBBB); - return false; - } - val = R_REG(osh, ®s->tsf_cfpstrt_h); - if (val != (uint) 0xCCCC) { - WL_ERROR("wl%d: validate_chip_access: tsf_cfpstrt_h = 0x%x, expected 0x%x\n", - wlc_hw->unit, val, 0xCCCC); - return false; - } - - } - - /* clear CFPStart */ - W_REG(osh, ®s->tsf_cfpstart, 0); - - w = R_REG(osh, ®s->maccontrol); - if ((w != (MCTL_IHR_EN | MCTL_WAKE)) && - (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) { - WL_ERROR("wl%d: validate_chip_access: maccontrol = 0x%x, expected 0x%x or 0x%x\n", - wlc_hw->unit, w, - (MCTL_IHR_EN | MCTL_WAKE), - (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE)); - return false; - } - - return true; -} - -#define PHYPLL_WAIT_US 100000 - -void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on) -{ - d11regs_t *regs; - struct osl_info *osh; - u32 tmp; - - WL_TRACE("wl%d: wlc_bmac_core_phypll_ctl\n", wlc_hw->unit); - - tmp = 0; - regs = wlc_hw->regs; - osh = wlc_hw->osh; - - if (D11REV_LE(wlc_hw->corerev, 16) || D11REV_IS(wlc_hw->corerev, 20)) - return; - - if (on) { - if ((wlc_hw->sih->chip == BCM4313_CHIP_ID)) { - OR_REG(osh, ®s->clk_ctl_st, - (CCS_ERSRC_REQ_HT | CCS_ERSRC_REQ_D11PLL | - CCS_ERSRC_REQ_PHYPLL)); - SPINWAIT((R_REG(osh, ®s->clk_ctl_st) & - (CCS_ERSRC_AVAIL_HT)) != (CCS_ERSRC_AVAIL_HT), - PHYPLL_WAIT_US); - - tmp = R_REG(osh, ®s->clk_ctl_st); - if ((tmp & (CCS_ERSRC_AVAIL_HT)) != - (CCS_ERSRC_AVAIL_HT)) { - WL_ERROR("%s: turn on PHY PLL failed\n", - __func__); - ASSERT(0); - } - } else { - OR_REG(osh, ®s->clk_ctl_st, - (CCS_ERSRC_REQ_D11PLL | CCS_ERSRC_REQ_PHYPLL)); - SPINWAIT((R_REG(osh, ®s->clk_ctl_st) & - (CCS_ERSRC_AVAIL_D11PLL | - CCS_ERSRC_AVAIL_PHYPLL)) != - (CCS_ERSRC_AVAIL_D11PLL | - CCS_ERSRC_AVAIL_PHYPLL), PHYPLL_WAIT_US); - - tmp = R_REG(osh, ®s->clk_ctl_st); - if ((tmp & - (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) - != - (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) { - WL_ERROR("%s: turn on PHY PLL failed\n", - __func__); - ASSERT(0); - } - } - } else { - /* Since the PLL may be shared, other cores can still be requesting it; - * so we'll deassert the request but not wait for status to comply. - */ - AND_REG(osh, ®s->clk_ctl_st, ~CCS_ERSRC_REQ_PHYPLL); - tmp = R_REG(osh, ®s->clk_ctl_st); - } -} - -void wlc_coredisable(struct wlc_hw_info *wlc_hw) -{ - bool dev_gone; - - WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); - - ASSERT(!wlc_hw->up); - - dev_gone = DEVICEREMOVED(wlc_hw->wlc); - - if (dev_gone) - return; - - if (wlc_hw->noreset) - return; - - /* radio off */ - wlc_phy_switch_radio(wlc_hw->band->pi, OFF); - - /* turn off analog core */ - wlc_phy_anacore(wlc_hw->band->pi, OFF); - - /* turn off PHYPLL to save power */ - wlc_bmac_core_phypll_ctl(wlc_hw, false); - - /* No need to set wlc->pub->radio_active = OFF - * because this function needs down capability and - * radio_active is designed for BCMNODOWN. - */ - - /* remove gpio controls */ - if (wlc_hw->ucode_dbgsel) - si_gpiocontrol(wlc_hw->sih, ~0, 0, GPIO_DRV_PRIORITY); - - wlc_hw->clk = false; - si_core_disable(wlc_hw->sih, 0); - wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); -} - -/* power both the pll and external oscillator on/off */ -void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want) -{ - WL_TRACE("wl%d: wlc_bmac_xtal: want %d\n", wlc_hw->unit, want); - - /* dont power down if plldown is false or we must poll hw radio disable */ - if (!want && wlc_hw->pllreq) - return; - - if (wlc_hw->sih) - si_clkctl_xtal(wlc_hw->sih, XTAL | PLL, want); - - wlc_hw->sbclk = want; - if (!wlc_hw->sbclk) { - wlc_hw->clk = false; - if (wlc_hw->band && wlc_hw->band->pi) - wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); - } -} - -static void wlc_flushqueues(struct wlc_info *wlc) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - uint i; - - wlc->txpend16165war = 0; - - /* free any posted tx packets */ - for (i = 0; i < NFIFO; i++) - if (wlc_hw->di[i]) { - dma_txreclaim(wlc_hw->di[i], HNDDMA_RANGE_ALL); - TXPKTPENDCLR(wlc, i); - WL_TRACE("wlc_flushqueues: pktpend fifo %d cleared\n", - i); - } - - /* free any posted rx packets */ - dma_rxreclaim(wlc_hw->di[RX_FIFO]); - if (D11REV_IS(wlc_hw->corerev, 4)) - dma_rxreclaim(wlc_hw->di[RX_TXSTATUS_FIFO]); -} - -u16 wlc_bmac_read_shm(struct wlc_hw_info *wlc_hw, uint offset) -{ - return wlc_bmac_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL); -} - -void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v) -{ - wlc_bmac_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL); -} - -/* Set a range of shared memory to a value. - * SHM 'offset' needs to be an even address and - * Buffer length 'len' must be an even number of bytes - */ -void wlc_bmac_set_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v, int len) -{ - int i; - - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) - return; - - for (i = 0; i < len; i += 2) { - wlc_bmac_write_objmem(wlc_hw, offset + i, v, OBJADDR_SHM_SEL); - } -} - -static u16 -wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, u32 sel) -{ - d11regs_t *regs = wlc_hw->regs; - volatile u16 *objdata_lo = (volatile u16 *)®s->objdata; - volatile u16 *objdata_hi = objdata_lo + 1; - u16 v; - - ASSERT((offset & 1) == 0); - - W_REG(wlc_hw->osh, ®s->objaddr, sel | (offset >> 2)); - (void)R_REG(wlc_hw->osh, ®s->objaddr); - if (offset & 2) { - v = R_REG(wlc_hw->osh, objdata_hi); - } else { - v = R_REG(wlc_hw->osh, objdata_lo); - } - - return v; -} - -static void -wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset, u16 v, u32 sel) -{ - d11regs_t *regs = wlc_hw->regs; - volatile u16 *objdata_lo = (volatile u16 *)®s->objdata; - volatile u16 *objdata_hi = objdata_lo + 1; - - ASSERT((offset & 1) == 0); - - W_REG(wlc_hw->osh, ®s->objaddr, sel | (offset >> 2)); - (void)R_REG(wlc_hw->osh, ®s->objaddr); - if (offset & 2) { - W_REG(wlc_hw->osh, objdata_hi, v); - } else { - W_REG(wlc_hw->osh, objdata_lo, v); - } -} - -/* Copy a buffer to shared memory of specified type . - * SHM 'offset' needs to be an even address and - * Buffer length 'len' must be an even number of bytes - * 'sel' selects the type of memory - */ -void -wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw, uint offset, const void *buf, - int len, u32 sel) -{ - u16 v; - const u8 *p = (const u8 *)buf; - int i; - - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) - return; - - for (i = 0; i < len; i += 2) { - v = p[i] | (p[i + 1] << 8); - wlc_bmac_write_objmem(wlc_hw, offset + i, v, sel); - } -} - -/* Copy a piece of shared memory of specified type to a buffer . - * SHM 'offset' needs to be an even address and - * Buffer length 'len' must be an even number of bytes - * 'sel' selects the type of memory - */ -void -wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset, void *buf, - int len, u32 sel) -{ - u16 v; - u8 *p = (u8 *) buf; - int i; - - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) - return; - - for (i = 0; i < len; i += 2) { - v = wlc_bmac_read_objmem(wlc_hw, offset + i, sel); - p[i] = v & 0xFF; - p[i + 1] = (v >> 8) & 0xFF; - } -} - -void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, uint *len) -{ - WL_TRACE("wlc_bmac_copyfrom_vars, nvram vars totlen=%d\n", - wlc_hw->vars_size); - - *buf = wlc_hw->vars; - *len = wlc_hw->vars_size; -} - -void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL, u16 LRL) -{ - wlc_hw->SRL = SRL; - wlc_hw->LRL = LRL; - - /* write retry limit to SCR, shouldn't need to suspend */ - if (wlc_hw->up) { - W_REG(wlc_hw->osh, &wlc_hw->regs->objaddr, - OBJADDR_SCR_SEL | S_DOT11_SRC_LMT); - (void)R_REG(wlc_hw->osh, &wlc_hw->regs->objaddr); - W_REG(wlc_hw->osh, &wlc_hw->regs->objdata, wlc_hw->SRL); - W_REG(wlc_hw->osh, &wlc_hw->regs->objaddr, - OBJADDR_SCR_SEL | S_DOT11_LRC_LMT); - (void)R_REG(wlc_hw->osh, &wlc_hw->regs->objaddr); - W_REG(wlc_hw->osh, &wlc_hw->regs->objdata, wlc_hw->LRL); - } -} - -void wlc_bmac_set_noreset(struct wlc_hw_info *wlc_hw, bool noreset_flag) -{ - wlc_hw->noreset = noreset_flag; -} - -void wlc_bmac_set_ucode_loaded(struct wlc_hw_info *wlc_hw, bool ucode_loaded) -{ - wlc_hw->ucode_loaded = ucode_loaded; -} - -void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, mbool req_bit) -{ - ASSERT(req_bit); - - if (set) { - if (mboolisset(wlc_hw->pllreq, req_bit)) - return; - - mboolset(wlc_hw->pllreq, req_bit); - - if (mboolisset(wlc_hw->pllreq, WLC_PLLREQ_FLIP)) { - if (!wlc_hw->sbclk) { - wlc_bmac_xtal(wlc_hw, ON); - } - } - } else { - if (!mboolisset(wlc_hw->pllreq, req_bit)) - return; - - mboolclr(wlc_hw->pllreq, req_bit); - - if (mboolisset(wlc_hw->pllreq, WLC_PLLREQ_FLIP)) { - if (wlc_hw->sbclk) { - wlc_bmac_xtal(wlc_hw, OFF); - } - } - } - - return; -} - -void wlc_bmac_set_clk(struct wlc_hw_info *wlc_hw, bool on) -{ - if (on) { - /* power up pll and oscillator */ - wlc_bmac_xtal(wlc_hw, ON); - - /* enable core(s), ignore bandlocked - * Leave with the same band selected as we entered - */ - wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); - } else { - /* if already down, must skip the core disable */ - if (wlc_hw->clk) { - /* disable core(s), ignore bandlocked */ - wlc_coredisable(wlc_hw); - } - /* power down pll and oscillator */ - wlc_bmac_xtal(wlc_hw, OFF); - } -} - -/* this will be true for all ai chips */ -bool wlc_bmac_taclear(struct wlc_hw_info *wlc_hw, bool ta_ok) -{ - return true; -} - -/* Lower down relevant GPIOs like LED when going down w/o - * doing PCI config cycles or touching interrupts - */ -void wlc_gpio_fast_deinit(struct wlc_hw_info *wlc_hw) -{ - if ((wlc_hw == NULL) || (wlc_hw->sih == NULL)) - return; - - /* Only chips with internal bus or PCIE cores or certain PCI cores - * are able to switch cores w/o disabling interrupts - */ - if (!((wlc_hw->sih->bustype == SI_BUS) || - ((wlc_hw->sih->bustype == PCI_BUS) && - ((wlc_hw->sih->buscoretype == PCIE_CORE_ID) || - (wlc_hw->sih->buscorerev >= 13))))) - return; - - WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); - return; -} - -bool wlc_bmac_radio_hw(struct wlc_hw_info *wlc_hw, bool enable) -{ - /* Do not access Phy registers if core is not up */ - if (si_iscoreup(wlc_hw->sih) == false) - return false; - - if (enable) { - if (PMUCTL_ENAB(wlc_hw->sih)) { - AND_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, - ~CCS_FORCEHWREQOFF); - si_pmu_radio_enable(wlc_hw->sih, true); - } - - wlc_phy_anacore(wlc_hw->band->pi, ON); - wlc_phy_switch_radio(wlc_hw->band->pi, ON); - - /* resume d11 core */ - wlc_enable_mac(wlc_hw->wlc); - } else { - /* suspend d11 core */ - wlc_suspend_mac_and_wait(wlc_hw->wlc); - - wlc_phy_switch_radio(wlc_hw->band->pi, OFF); - wlc_phy_anacore(wlc_hw->band->pi, OFF); - - if (PMUCTL_ENAB(wlc_hw->sih)) { - si_pmu_radio_enable(wlc_hw->sih, false); - OR_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, - CCS_FORCEHWREQOFF); - } - } - - return true; -} - -u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate) -{ - u16 table_ptr; - u8 phy_rate, index; - - /* get the phy specific rate encoding for the PLCP SIGNAL field */ - /* XXX4321 fixup needed ? */ - if (IS_OFDM(rate)) - table_ptr = M_RT_DIRMAP_A; - else - table_ptr = M_RT_DIRMAP_B; - - /* for a given rate, the LS-nibble of the PLCP SIGNAL field is - * the index into the rate table. - */ - phy_rate = rate_info[rate] & RATE_MASK; - index = phy_rate & 0xf; - - /* Find the SHM pointer to the rate table entry by looking in the - * Direct-map Table - */ - return 2 * wlc_bmac_read_shm(wlc_hw, table_ptr + (index * 2)); -} - -void wlc_bmac_set_txpwr_percent(struct wlc_hw_info *wlc_hw, u8 val) -{ - wlc_phy_txpwr_percent_set(wlc_hw->band->pi, val); -} - -void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail) -{ - wlc_hw->antsel_avail = antsel_avail; -} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.h deleted file mode 100644 index 03ce9521d652..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_bmac.h +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* XXXXX this interface is under wlc.c by design - * http://hwnbu-twiki.broadcom.com/bin/view/Mwgroup/WlBmacDesign - * - * high driver files(e.g. wlc_ampdu.c etc) - * wlc.h/wlc.c - * wlc_bmac.h/wlc_bmac.c - * - * So don't include this in files other than wlc.c, wlc_bmac* wl_rte.c(dongle port) and wl_phy.c - * create wrappers in wlc.c if needed - */ - -/* Revision and other info required from BMAC driver for functioning of high ONLY driver */ -typedef struct wlc_bmac_revinfo { - uint vendorid; /* PCI vendor id */ - uint deviceid; /* device id of chip */ - - uint boardrev; /* version # of particular board */ - uint corerev; /* core revision */ - uint sromrev; /* srom revision */ - uint chiprev; /* chip revision */ - uint chip; /* chip number */ - uint chippkg; /* chip package */ - uint boardtype; /* board type */ - uint boardvendor; /* board vendor */ - uint bustype; /* SB_BUS, PCI_BUS */ - uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */ - uint buscorerev; /* buscore rev */ - u32 issim; /* chip is in simulation or emulation */ - - uint nbands; - - struct band_info { - uint bandunit; /* To match on both sides */ - uint bandtype; /* To match on both sides */ - uint radiorev; - uint phytype; - uint phyrev; - uint anarev; - uint radioid; - bool abgphy_encore; - } band[MAXBANDS]; -} wlc_bmac_revinfo_t; - -/* dup state between BMAC(struct wlc_hw_info) and HIGH(struct wlc_info) - driver */ -typedef struct wlc_bmac_state { - u32 machwcap; /* mac hw capibility */ - u32 preamble_ovr; /* preamble override */ -} wlc_bmac_state_t; - -enum { - IOV_BMAC_DIAG, - IOV_BMAC_SBGPIOTIMERVAL, - IOV_BMAC_SBGPIOOUT, - IOV_BMAC_CCGPIOCTRL, /* CC GPIOCTRL REG */ - IOV_BMAC_CCGPIOOUT, /* CC GPIOOUT REG */ - IOV_BMAC_CCGPIOOUTEN, /* CC GPIOOUTEN REG */ - IOV_BMAC_CCGPIOIN, /* CC GPIOIN REG */ - IOV_BMAC_WPSGPIO, /* WPS push button GPIO pin */ - IOV_BMAC_OTPDUMP, - IOV_BMAC_OTPSTAT, - IOV_BMAC_PCIEASPM, /* obfuscation clkreq/aspm control */ - IOV_BMAC_PCIEADVCORRMASK, /* advanced correctable error mask */ - IOV_BMAC_PCIECLKREQ, /* PCIE 1.1 clockreq enab support */ - IOV_BMAC_PCIELCREG, /* PCIE LCREG */ - IOV_BMAC_SBGPIOTIMERMASK, - IOV_BMAC_RFDISABLEDLY, - IOV_BMAC_PCIEREG, /* PCIE REG */ - IOV_BMAC_PCICFGREG, /* PCI Config register */ - IOV_BMAC_PCIESERDESREG, /* PCIE SERDES REG (dev, 0}offset) */ - IOV_BMAC_PCIEGPIOOUT, /* PCIEOUT REG */ - IOV_BMAC_PCIEGPIOOUTEN, /* PCIEOUTEN REG */ - IOV_BMAC_PCIECLKREQENCTRL, /* clkreqenctrl REG (PCIE REV > 6.0 */ - IOV_BMAC_DMALPBK, - IOV_BMAC_CCREG, - IOV_BMAC_COREREG, - IOV_BMAC_SDCIS, - IOV_BMAC_SDIO_DRIVE, - IOV_BMAC_OTPW, - IOV_BMAC_NVOTPW, - IOV_BMAC_SROM, - IOV_BMAC_SRCRC, - IOV_BMAC_CIS_SOURCE, - IOV_BMAC_CISVAR, - IOV_BMAC_OTPLOCK, - IOV_BMAC_OTP_CHIPID, - IOV_BMAC_CUSTOMVAR1, - IOV_BMAC_BOARDFLAGS, - IOV_BMAC_BOARDFLAGS2, - IOV_BMAC_WPSLED, - IOV_BMAC_NVRAM_SOURCE, - IOV_BMAC_OTP_RAW_READ, - IOV_BMAC_LAST -}; - -typedef enum { - BMAC_DUMP_GPIO_ID, - BMAC_DUMP_SI_ID, - BMAC_DUMP_SIREG_ID, - BMAC_DUMP_SICLK_ID, - BMAC_DUMP_CCREG_ID, - BMAC_DUMP_PCIEREG_ID, - BMAC_DUMP_PHYREG_ID, - BMAC_DUMP_PHYTBL_ID, - BMAC_DUMP_PHYTBL2_ID, - BMAC_DUMP_PHY_RADIOREG_ID, - BMAC_DUMP_LAST -} wlc_bmac_dump_id_t; - -typedef enum { - WLCHW_STATE_ATTACH, - WLCHW_STATE_CLK, - WLCHW_STATE_UP, - WLCHW_STATE_ASSOC, - WLCHW_STATE_LAST -} wlc_bmac_state_id_t; - -extern int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, - uint unit, bool piomode, struct osl_info *osh, - void *regsva, uint bustype, void *btparam); -extern int wlc_bmac_detach(struct wlc_info *wlc); -extern void wlc_bmac_watchdog(void *arg); -extern void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw); - -/* up/down, reset, clk */ -extern void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want); - -extern void wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw, - uint offset, const void *buf, int len, - u32 sel); -extern void wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset, - void *buf, int len, u32 sel); -#define wlc_bmac_copyfrom_shm(wlc_hw, offset, buf, len) \ - wlc_bmac_copyfrom_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL) -#define wlc_bmac_copyto_shm(wlc_hw, offset, buf, len) \ - wlc_bmac_copyto_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL) - -extern void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk); -extern void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on); -extern void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk); -extern void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk); -extern void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags); -extern void wlc_bmac_reset(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, - bool mute); -extern int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw); -extern int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw); -extern int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw); -extern int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags); -extern void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode); - -/* chanspec, ucode interface */ -extern int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, - chanspec_t chanspec, - bool mute, struct txpwr_limits *txpwr); - -extern void wlc_bmac_txfifo(struct wlc_hw_info *wlc_hw, uint fifo, void *p, - bool commit, u16 frameid, u8 txpktpend); -extern int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, - uint *blocks); -extern void wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, - u16 val, int bands); -extern void wlc_bmac_mctrl(struct wlc_hw_info *wlc_hw, u32 mask, u32 val); -extern u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands); -extern int wlc_bmac_xmtfifo_sz_set(struct wlc_hw_info *wlc_hw, uint fifo, - uint blocks); -extern void wlc_bmac_txant_set(struct wlc_hw_info *wlc_hw, u16 phytxant); -extern u16 wlc_bmac_get_txant(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_antsel_type_set(struct wlc_hw_info *wlc_hw, - u8 antsel_type); -extern int wlc_bmac_revinfo_get(struct wlc_hw_info *wlc_hw, - wlc_bmac_revinfo_t *revinfo); -extern int wlc_bmac_state_get(struct wlc_hw_info *wlc_hw, - wlc_bmac_state_t *state); -extern void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v); -extern u16 wlc_bmac_read_shm(struct wlc_hw_info *wlc_hw, uint offset); -extern void wlc_bmac_set_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v, - int len); -extern void wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, - int len, void *buf); -extern void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, - uint *len); - -extern void wlc_bmac_process_ps_switch(struct wlc_hw_info *wlc, - struct ether_addr *ea, s8 ps_on); -extern void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, - u8 *ea); -extern void wlc_bmac_set_hw_etheraddr(struct wlc_hw_info *wlc_hw, - u8 *ea); -extern bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw); - -extern bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot); -extern void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool want, mbool flags); -extern void wlc_bmac_set_deaf(struct wlc_hw_info *wlc_hw, bool user_flag); -extern void wlc_bmac_band_stf_ss_set(struct wlc_hw_info *wlc_hw, u8 stf_mode); - -extern void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw); -extern bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, - uint tx_fifo); -extern void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo); -extern void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo); - -extern void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, - u32 override_bit); -extern void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw, - u32 override_bit); - -extern void wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, - const u8 *addr); -extern void wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, - int match_reg_offset, - const u8 *addr); -extern void wlc_bmac_write_hw_bcntemplates(struct wlc_hw_info *wlc_hw, - void *bcn, int len, bool both); - -extern void wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr, - u32 *tsf_h_ptr); -extern void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin); -extern void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax); -extern void wlc_bmac_set_noreset(struct wlc_hw_info *wlc, bool noreset_flag); -extern void wlc_bmac_set_ucode_loaded(struct wlc_hw_info *wlc, - bool ucode_loaded); - -extern void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL, - u16 LRL); - -extern void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw); - - -/* API for BMAC driver (e.g. wlc_phy.c etc) */ - -extern void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw); -extern void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, - mbool req_bit); -extern void wlc_bmac_set_clk(struct wlc_hw_info *wlc_hw, bool on); -extern bool wlc_bmac_taclear(struct wlc_hw_info *wlc_hw, bool ta_ok); -extern void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw); - -extern void wlc_bmac_dump(struct wlc_hw_info *wlc_hw, struct bcmstrbuf *b, - wlc_bmac_dump_id_t dump_id); -extern void wlc_gpio_fast_deinit(struct wlc_hw_info *wlc_hw); - -extern bool wlc_bmac_radio_hw(struct wlc_hw_info *wlc_hw, bool enable); -extern u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate); - -extern void wlc_bmac_assert_type_set(struct wlc_hw_info *wlc_hw, u32 type); -extern void wlc_bmac_set_txpwr_percent(struct wlc_hw_info *wlc_hw, u8 val); -extern void wlc_bmac_blink_sync(struct wlc_hw_info *wlc_hw, u32 led_pins); -extern void wlc_bmac_ifsctl_edcrs_set(struct wlc_hw_info *wlc_hw, bool abie, - bool isht); - -extern void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail); diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_bsscfg.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_bsscfg.h deleted file mode 100644 index 0bb4a212dd71..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_bsscfg.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _WLC_BSSCFG_H_ -#define _WLC_BSSCFG_H_ - -#include - -/* Check if a particular BSS config is AP or STA */ -#define BSSCFG_AP(cfg) (0) -#define BSSCFG_STA(cfg) (1) - -#define BSSCFG_IBSS(cfg) (!(cfg)->BSS) - -/* forward declarations */ -typedef struct wlc_bsscfg wlc_bsscfg_t; - -#include - -#define NTXRATE 64 /* # tx MPDUs rate is reported for */ -#define MAXMACLIST 64 /* max # source MAC matches */ -#define BCN_TEMPLATE_COUNT 2 - -/* Iterator for "associated" STA bss configs: - (struct wlc_info *wlc, int idx, wlc_bsscfg_t *cfg) */ -#define FOREACH_AS_STA(wlc, idx, cfg) \ - for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \ - if ((cfg = (wlc)->bsscfg[idx]) && BSSCFG_STA(cfg) && cfg->associated) - -/* As above for all non-NULL BSS configs */ -#define FOREACH_BSS(wlc, idx, cfg) \ - for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \ - if ((cfg = (wlc)->bsscfg[idx])) - -/* BSS configuration state */ -struct wlc_bsscfg { - struct wlc_info *wlc; /* wlc to which this bsscfg belongs to. */ - bool up; /* is this configuration up operational */ - bool enable; /* is this configuration enabled */ - bool associated; /* is BSS in ASSOCIATED state */ - bool BSS; /* infraustructure or adhac */ - bool dtim_programmed; -#ifdef LATER - bool _ap; /* is this configuration an AP */ - struct wlc_if *wlcif; /* virtual interface, NULL for primary bsscfg */ - void *sup; /* pointer to supplicant state */ - s8 sup_type; /* type of supplicant */ - bool sup_enable_wpa; /* supplicant WPA on/off */ - void *authenticator; /* pointer to authenticator state */ - bool sup_auth_pending; /* flag for auth timeout */ -#endif - u8 SSID_len; /* the length of SSID */ - u8 SSID[IEEE80211_MAX_SSID_LEN]; /* SSID string */ - struct scb *bcmc_scb[MAXBANDS]; /* one bcmc_scb per band */ - s8 _idx; /* the index of this bsscfg, - * assigned at wlc_bsscfg_alloc() - */ - /* MAC filter */ - uint nmac; /* # of entries on maclist array */ - int macmode; /* allow/deny stations on maclist array */ - struct ether_addr *maclist; /* list of source MAC addrs to match */ - - /* security */ - u32 wsec; /* wireless security bitvec */ - s16 auth; /* 802.11 authentication: Open, Shared Key, WPA */ - s16 openshared; /* try Open auth first, then Shared Key */ - bool wsec_restrict; /* drop unencrypted packets if wsec is enabled */ - bool eap_restrict; /* restrict data until 802.1X auth succeeds */ - u16 WPA_auth; /* WPA: authenticated key management */ - bool wpa2_preauth; /* default is true, wpa_cap sets value */ - bool wsec_portopen; /* indicates keys are plumbed */ - wsec_iv_t wpa_none_txiv; /* global txiv for WPA_NONE, tkip and aes */ - int wsec_index; /* 0-3: default tx key, -1: not set */ - wsec_key_t *bss_def_keys[WLC_DEFAULT_KEYS]; /* default key storage */ - - /* TKIP countermeasures */ - bool tkip_countermeasures; /* flags TKIP no-assoc period */ - u32 tk_cm_dt; /* detect timer */ - u32 tk_cm_bt; /* blocking timer */ - u32 tk_cm_bt_tmstmp; /* Timestamp when TKIP BT is activated */ - bool tk_cm_activate; /* activate countermeasures after EAPOL-Key sent */ - - u8 BSSID[ETH_ALEN]; /* BSSID (associated) */ - u8 cur_etheraddr[ETH_ALEN]; /* h/w address */ - u16 bcmc_fid; /* the last BCMC FID queued to TX_BCMC_FIFO */ - u16 bcmc_fid_shm; /* the last BCMC FID written to shared mem */ - - u32 flags; /* WLC_BSSCFG flags; see below */ - - u8 *bcn; /* AP beacon */ - uint bcn_len; /* AP beacon length */ - bool ar_disassoc; /* disassociated in associated recreation */ - - int auth_atmptd; /* auth type (open/shared) attempted */ - - pmkid_cand_t pmkid_cand[MAXPMKID]; /* PMKID candidate list */ - uint npmkid_cand; /* num PMKID candidates */ - pmkid_t pmkid[MAXPMKID]; /* PMKID cache */ - uint npmkid; /* num cached PMKIDs */ - - wlc_bss_info_t *target_bss; /* BSS parms during tran. to ASSOCIATED state */ - wlc_bss_info_t *current_bss; /* BSS parms in ASSOCIATED state */ - - /* PM states */ - bool PMawakebcn; /* bcn recvd during current waking state */ - bool PMpending; /* waiting for tx status with PM indicated set */ - bool priorPMstate; /* Detecting PM state transitions */ - bool PSpoll; /* whether there is an outstanding PS-Poll frame */ - - /* BSSID entry in RCMTA, use the wsec key management infrastructure to - * manage the RCMTA entries. - */ - wsec_key_t *rcmta; - - /* 'unique' ID of this bsscfg, assigned at bsscfg allocation */ - u16 ID; - - uint txrspecidx; /* index into tx rate circular buffer */ - ratespec_t txrspec[NTXRATE][2]; /* circular buffer of prev MPDUs tx rates */ -}; - -#define WLC_BSSCFG_11N_DISABLE 0x1000 /* Do not advertise .11n IEs for this BSS */ -#define WLC_BSSCFG_HW_BCN 0x20 /* The BSS is generating beacons in HW */ - -#define HWBCN_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_BCN) != 0) -#define HWPRB_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_PRB) != 0) - -extern void wlc_bsscfg_ID_assign(struct wlc_info *wlc, wlc_bsscfg_t * bsscfg); - -/* Extend N_ENAB to per-BSS */ -#define BSS_N_ENAB(wlc, cfg) \ - (N_ENAB((wlc)->pub) && !((cfg)->flags & WLC_BSSCFG_11N_DISABLE)) - -#define MBSS_BCN_ENAB(cfg) 0 -#define MBSS_PRB_ENAB(cfg) 0 -#define SOFTBCN_ENAB(pub) (0) -#define SOFTPRB_ENAB(pub) (0) -#define wlc_bsscfg_tx_check(a) do { } while (0); - -#endif /* _WLC_BSSCFG_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_cfg.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_cfg.h deleted file mode 100644 index 3decb7d1a5e5..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_cfg.h +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_cfg_h_ -#define _wlc_cfg_h_ - -#define NBANDS(wlc) ((wlc)->pub->_nbands) -#define NBANDS_PUB(pub) ((pub)->_nbands) -#define NBANDS_HW(hw) ((hw)->_nbands) - -#define IS_SINGLEBAND_5G(device) 0 - -/* **** Core type/rev defaults **** */ -#define D11_DEFAULT 0x0fffffb0 /* Supported D11 revs: 4, 5, 7-27 - * also need to update wlc.h MAXCOREREV - */ - -#define NPHY_DEFAULT 0x000001ff /* Supported nphy revs: - * 0 4321a0 - * 1 4321a1 - * 2 4321b0/b1/c0/c1 - * 3 4322a0 - * 4 4322a1 - * 5 4716a0 - * 6 43222a0, 43224a0 - * 7 43226a0 - * 8 5357a0, 43236a0 - */ - -#define LCNPHY_DEFAULT 0x00000007 /* Supported lcnphy revs: - * 0 4313a0, 4336a0, 4330a0 - * 1 - * 2 4330a0 - */ - -#define SSLPNPHY_DEFAULT 0x0000000f /* Supported sslpnphy revs: - * 0 4329a0/k0 - * 1 4329b0/4329C0 - * 2 4319a0 - * 3 5356a0 - */ - - -/* For undefined values, use defaults */ -#ifndef D11CONF -#define D11CONF D11_DEFAULT -#endif -#ifndef NCONF -#define NCONF NPHY_DEFAULT -#endif -#ifndef LCNCONF -#define LCNCONF LCNPHY_DEFAULT -#endif - -#ifndef SSLPNCONF -#define SSLPNCONF SSLPNPHY_DEFAULT -#endif - -#define BAND2G -#define BAND5G -#define WLANTSEL 1 - -/******************************************************************** - * Phy/Core Configuration. Defines macros to to check core phy/rev * - * compile-time configuration. Defines default core support. * - * ****************************************************************** - */ - -/* Basic macros to check a configuration bitmask */ - -#define CONF_HAS(config, val) ((config) & (1 << (val))) -#define CONF_MSK(config, mask) ((config) & (mask)) -#define MSK_RANGE(low, hi) ((1 << ((hi)+1)) - (1 << (low))) -#define CONF_RANGE(config, low, hi) (CONF_MSK(config, MSK_RANGE(low, high))) - -#define CONF_IS(config, val) ((config) == (1 << (val))) -#define CONF_GE(config, val) ((config) & (0-(1 << (val)))) -#define CONF_GT(config, val) ((config) & (0-2*(1 << (val)))) -#define CONF_LT(config, val) ((config) & ((1 << (val))-1)) -#define CONF_LE(config, val) ((config) & (2*(1 << (val))-1)) - -/* Wrappers for some of the above, specific to config constants */ - -#define NCONF_HAS(val) CONF_HAS(NCONF, val) -#define NCONF_MSK(mask) CONF_MSK(NCONF, mask) -#define NCONF_IS(val) CONF_IS(NCONF, val) -#define NCONF_GE(val) CONF_GE(NCONF, val) -#define NCONF_GT(val) CONF_GT(NCONF, val) -#define NCONF_LT(val) CONF_LT(NCONF, val) -#define NCONF_LE(val) CONF_LE(NCONF, val) - -#define LCNCONF_HAS(val) CONF_HAS(LCNCONF, val) -#define LCNCONF_MSK(mask) CONF_MSK(LCNCONF, mask) -#define LCNCONF_IS(val) CONF_IS(LCNCONF, val) -#define LCNCONF_GE(val) CONF_GE(LCNCONF, val) -#define LCNCONF_GT(val) CONF_GT(LCNCONF, val) -#define LCNCONF_LT(val) CONF_LT(LCNCONF, val) -#define LCNCONF_LE(val) CONF_LE(LCNCONF, val) - -#define D11CONF_HAS(val) CONF_HAS(D11CONF, val) -#define D11CONF_MSK(mask) CONF_MSK(D11CONF, mask) -#define D11CONF_IS(val) CONF_IS(D11CONF, val) -#define D11CONF_GE(val) CONF_GE(D11CONF, val) -#define D11CONF_GT(val) CONF_GT(D11CONF, val) -#define D11CONF_LT(val) CONF_LT(D11CONF, val) -#define D11CONF_LE(val) CONF_LE(D11CONF, val) - -#define PHYCONF_HAS(val) CONF_HAS(PHYTYPE, val) -#define PHYCONF_IS(val) CONF_IS(PHYTYPE, val) - -#define NREV_IS(var, val) (NCONF_HAS(val) && (NCONF_IS(val) || ((var) == (val)))) -#define NREV_GE(var, val) (NCONF_GE(val) && (!NCONF_LT(val) || ((var) >= (val)))) -#define NREV_GT(var, val) (NCONF_GT(val) && (!NCONF_LE(val) || ((var) > (val)))) -#define NREV_LT(var, val) (NCONF_LT(val) && (!NCONF_GE(val) || ((var) < (val)))) -#define NREV_LE(var, val) (NCONF_LE(val) && (!NCONF_GT(val) || ((var) <= (val)))) - -#define LCNREV_IS(var, val) (LCNCONF_HAS(val) && (LCNCONF_IS(val) || ((var) == (val)))) -#define LCNREV_GE(var, val) (LCNCONF_GE(val) && (!LCNCONF_LT(val) || ((var) >= (val)))) -#define LCNREV_GT(var, val) (LCNCONF_GT(val) && (!LCNCONF_LE(val) || ((var) > (val)))) -#define LCNREV_LT(var, val) (LCNCONF_LT(val) && (!LCNCONF_GE(val) || ((var) < (val)))) -#define LCNREV_LE(var, val) (LCNCONF_LE(val) && (!LCNCONF_GT(val) || ((var) <= (val)))) - -#define D11REV_IS(var, val) (D11CONF_HAS(val) && (D11CONF_IS(val) || ((var) == (val)))) -#define D11REV_GE(var, val) (D11CONF_GE(val) && (!D11CONF_LT(val) || ((var) >= (val)))) -#define D11REV_GT(var, val) (D11CONF_GT(val) && (!D11CONF_LE(val) || ((var) > (val)))) -#define D11REV_LT(var, val) (D11CONF_LT(val) && (!D11CONF_GE(val) || ((var) < (val)))) -#define D11REV_LE(var, val) (D11CONF_LE(val) && (!D11CONF_GT(val) || ((var) <= (val)))) - -#define PHYTYPE_IS(var, val) (PHYCONF_HAS(val) && (PHYCONF_IS(val) || ((var) == (val)))) - -/* Finally, early-exit from switch case if anyone wants it... */ - -#define CASECHECK(config, val) if (!(CONF_HAS(config, val))) break -#define CASEMSK(config, mask) if (!(CONF_MSK(config, mask))) break - -#if (D11CONF ^ (D11CONF & D11_DEFAULT)) -#error "Unsupported MAC revision configured" -#endif -#if (NCONF ^ (NCONF & NPHY_DEFAULT)) -#error "Unsupported NPHY revision configured" -#endif -#if (LCNCONF ^ (LCNCONF & LCNPHY_DEFAULT)) -#error "Unsupported LPPHY revision configured" -#endif - -/* *** Consistency checks *** */ -#if !D11CONF -#error "No MAC revisions configured!" -#endif - -#if !NCONF && !LCNCONF && !SSLPNCONF -#error "No PHY configured!" -#endif - -/* Set up PHYTYPE automatically: (depends on PHY_TYPE_X, from d11.h) */ - -#define _PHYCONF_N (1 << PHY_TYPE_N) - -#if LCNCONF -#define _PHYCONF_LCN (1 << PHY_TYPE_LCN) -#else -#define _PHYCONF_LCN 0 -#endif /* LCNCONF */ - -#if SSLPNCONF -#define _PHYCONF_SSLPN (1 << PHY_TYPE_SSN) -#else -#define _PHYCONF_SSLPN 0 -#endif /* SSLPNCONF */ - -#define PHYTYPE (_PHYCONF_N | _PHYCONF_LCN | _PHYCONF_SSLPN) - -/* Utility macro to identify 802.11n (HT) capable PHYs */ -#define PHYTYPE_11N_CAP(phytype) \ - (PHYTYPE_IS(phytype, PHY_TYPE_N) || \ - PHYTYPE_IS(phytype, PHY_TYPE_LCN) || \ - PHYTYPE_IS(phytype, PHY_TYPE_SSN)) - -/* Last but not least: shorter wlc-specific var checks */ -#define WLCISNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_N) -#define WLCISLCNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_LCN) -#define WLCISSSLPNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_SSN) - -#define WLC_PHY_11N_CAP(band) PHYTYPE_11N_CAP((band)->phytype) - -/********************************************************************** - * ------------- End of Core phy/rev configuration. ----------------- * - * ******************************************************************** - */ - -/************************************************* - * Defaults for tunables (e.g. sizing constants) - * - * For each new tunable, add a member to the end - * of wlc_tunables_t in wlc_pub.h to enable - * runtime checks of tunable values. (Directly - * using the macros in code invalidates ROM code) - * - * *********************************************** - */ -#ifndef NTXD -#define NTXD 256 /* Max # of entries in Tx FIFO based on 4kb page size */ -#endif /* NTXD */ -#ifndef NRXD -#define NRXD 256 /* Max # of entries in Rx FIFO based on 4kb page size */ -#endif /* NRXD */ - -#ifndef NRXBUFPOST -#define NRXBUFPOST 32 /* try to keep this # rbufs posted to the chip */ -#endif /* NRXBUFPOST */ - -#ifndef MAXSCB /* station control blocks in cache */ -#define MAXSCB 32 /* Maximum SCBs in cache for STA */ -#endif /* MAXSCB */ - -#ifndef AMPDU_NUM_MPDU -#define AMPDU_NUM_MPDU 16 /* max allowed number of mpdus in an ampdu (2 streams) */ -#endif /* AMPDU_NUM_MPDU */ - -#ifndef AMPDU_NUM_MPDU_3STREAMS -#define AMPDU_NUM_MPDU_3STREAMS 32 /* max allowed number of mpdus in an ampdu for 3+ streams */ -#endif /* AMPDU_NUM_MPDU_3STREAMS */ - -/* Count of packet callback structures. either of following - * 1. Set to the number of SCBs since a STA - * can queue up a rate callback for each IBSS STA it knows about, and an AP can - * queue up an "are you there?" Null Data callback for each associated STA - * 2. controlled by tunable config file - */ -#ifndef MAXPKTCB -#define MAXPKTCB MAXSCB /* Max number of packet callbacks */ -#endif /* MAXPKTCB */ - -#ifndef CTFPOOLSZ -#define CTFPOOLSZ 128 -#endif /* CTFPOOLSZ */ - -/* NetBSD also needs to keep track of this */ -#define WLC_MAX_UCODE_BSS (16) /* Number of BSS handled in ucode bcn/prb */ -#define WLC_MAX_UCODE_BSS4 (4) /* Number of BSS handled in sw bcn/prb */ -#ifndef WLC_MAXBSSCFG -#define WLC_MAXBSSCFG (1) /* max # BSS configs */ -#endif /* WLC_MAXBSSCFG */ - -#ifndef MAXBSS -#define MAXBSS 64 /* max # available networks */ -#endif /* MAXBSS */ - -#ifndef WLC_DATAHIWAT -#define WLC_DATAHIWAT 50 /* data msg txq hiwat mark */ -#endif /* WLC_DATAHIWAT */ - -#ifndef WLC_AMPDUDATAHIWAT -#define WLC_AMPDUDATAHIWAT 255 -#endif /* WLC_AMPDUDATAHIWAT */ - -/* bounded rx loops */ -#ifndef RXBND -#define RXBND 8 /* max # frames to process in wlc_recv() */ -#endif /* RXBND */ -#ifndef TXSBND -#define TXSBND 8 /* max # tx status to process in wlc_txstatus() */ -#endif /* TXSBND */ - -#define BAND_5G(bt) ((bt) == WLC_BAND_5G) -#define BAND_2G(bt) ((bt) == WLC_BAND_2G) - -#define WLBANDINITDATA(_data) _data -#define WLBANDINITFN(_fn) _fn - -#define WLANTSEL_ENAB(wlc) 1 - -#endif /* _wlc_cfg_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_channel.c deleted file mode 100644 index a35c15214880..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_channel.c +++ /dev/null @@ -1,1609 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct wlc_cm_band { - u8 locale_flags; /* locale_info_t flags */ - chanvec_t valid_channels; /* List of valid channels in the country */ - const chanvec_t *restricted_channels; /* List of restricted use channels */ - const chanvec_t *radar_channels; /* List of radar sensitive channels */ - u8 PAD[8]; -} wlc_cm_band_t; - -struct wlc_cm_info { - struct wlc_pub *pub; - struct wlc_info *wlc; - char srom_ccode[WLC_CNTRY_BUF_SZ]; /* Country Code in SROM */ - uint srom_regrev; /* Regulatory Rev for the SROM ccode */ - const country_info_t *country; /* current country def */ - char ccode[WLC_CNTRY_BUF_SZ]; /* current internal Country Code */ - uint regrev; /* current Regulatory Revision */ - char country_abbrev[WLC_CNTRY_BUF_SZ]; /* current advertised ccode */ - wlc_cm_band_t bandstate[MAXBANDS]; /* per-band state (one per phy/radio) */ - /* quiet channels currently for radar sensitivity or 11h support */ - chanvec_t quiet_channels; /* channels on which we cannot transmit */ -}; - -static int wlc_channels_init(wlc_cm_info_t *wlc_cm, - const country_info_t *country); -static void wlc_set_country_common(wlc_cm_info_t *wlc_cm, - const char *country_abbrev, - const char *ccode, uint regrev, - const country_info_t *country); -static int wlc_country_aggregate_map(wlc_cm_info_t *wlc_cm, const char *ccode, - char *mapped_ccode, uint *mapped_regrev); -static const country_info_t *wlc_country_lookup_direct(const char *ccode, - uint regrev); -static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm, - const char *ccode, - char *mapped_ccode, - uint *mapped_regrev); -static void wlc_channels_commit(wlc_cm_info_t *wlc_cm); -static bool wlc_japan_ccode(const char *ccode); -static void wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t * - wlc_cm, - struct - txpwr_limits - *txpwr, - u8 - local_constraint_qdbm); -void wlc_locale_add_channels(chanvec_t *target, const chanvec_t *channels); -static const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx); -static const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx); - -/* QDB() macro takes a dB value and converts to a quarter dB value */ -#ifdef QDB -#undef QDB -#endif -#define QDB(n) ((n) * WLC_TXPWR_DB_FACTOR) - -/* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */ - -/* - * Some common channel sets - */ - -/* No channels */ -static const chanvec_t chanvec_none = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -/* All 2.4 GHz HW channels */ -const chanvec_t chanvec_all_2G = { - {0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -/* All 5 GHz HW channels */ -const chanvec_t chanvec_all_5G = { - {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x11, 0x11, - 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x20, 0x22, 0x22, 0x00, 0x00, 0x11, - 0x11, 0x11, 0x11, 0x01} -}; - -/* - * Radar channel sets - */ - -/* No radar */ -#define radar_set_none chanvec_none - -static const chanvec_t radar_set1 = { /* Channels 52 - 64, 100 - 140 */ - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, /* 52 - 60 */ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, /* 64, 100 - 124 */ - 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 128 - 140 */ - 0x00, 0x00, 0x00, 0x00} -}; - -/* - * Restricted channel sets - */ - -#define restricted_set_none chanvec_none - -/* Channels 34, 38, 42, 46 */ -static const chanvec_t restricted_set_japan_legacy = { - {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -/* Channels 12, 13 */ -static const chanvec_t restricted_set_2g_short = { - {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -/* Channel 165 */ -static const chanvec_t restricted_chan_165 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -/* Channels 36 - 48 & 149 - 165 */ -static const chanvec_t restricted_low_hi = { - {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x20, 0x22, 0x22, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -/* Channels 12 - 14 */ -static const chanvec_t restricted_set_12_13_14 = { - {0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -#define LOCALE_CHAN_01_11 (1<<0) -#define LOCALE_CHAN_12_13 (1<<1) -#define LOCALE_CHAN_14 (1<<2) -#define LOCALE_SET_5G_LOW_JP1 (1<<3) /* 34-48, step 2 */ -#define LOCALE_SET_5G_LOW_JP2 (1<<4) /* 34-46, step 4 */ -#define LOCALE_SET_5G_LOW1 (1<<5) /* 36-48, step 4 */ -#define LOCALE_SET_5G_LOW2 (1<<6) /* 52 */ -#define LOCALE_SET_5G_LOW3 (1<<7) /* 56-64, step 4 */ -#define LOCALE_SET_5G_MID1 (1<<8) /* 100-116, step 4 */ -#define LOCALE_SET_5G_MID2 (1<<9) /* 120-124, step 4 */ -#define LOCALE_SET_5G_MID3 (1<<10) /* 128 */ -#define LOCALE_SET_5G_HIGH1 (1<<11) /* 132-140, step 4 */ -#define LOCALE_SET_5G_HIGH2 (1<<12) /* 149-161, step 4 */ -#define LOCALE_SET_5G_HIGH3 (1<<13) /* 165 */ -#define LOCALE_CHAN_52_140_ALL (1<<14) -#define LOCALE_SET_5G_HIGH4 (1<<15) /* 184-216 */ - -#define LOCALE_CHAN_36_64 (LOCALE_SET_5G_LOW1 | LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3) -#define LOCALE_CHAN_52_64 (LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3) -#define LOCALE_CHAN_100_124 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2) -#define LOCALE_CHAN_100_140 \ - (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1) -#define LOCALE_CHAN_149_165 (LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3) -#define LOCALE_CHAN_184_216 LOCALE_SET_5G_HIGH4 - -#define LOCALE_CHAN_01_14 (LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13 | LOCALE_CHAN_14) - -#define LOCALE_RADAR_SET_NONE 0 -#define LOCALE_RADAR_SET_1 1 - -#define LOCALE_RESTRICTED_NONE 0 -#define LOCALE_RESTRICTED_SET_2G_SHORT 1 -#define LOCALE_RESTRICTED_CHAN_165 2 -#define LOCALE_CHAN_ALL_5G 3 -#define LOCALE_RESTRICTED_JAPAN_LEGACY 4 -#define LOCALE_RESTRICTED_11D_2G 5 -#define LOCALE_RESTRICTED_11D_5G 6 -#define LOCALE_RESTRICTED_LOW_HI 7 -#define LOCALE_RESTRICTED_12_13_14 8 - -/* global memory to provide working buffer for expanded locale */ - -static const chanvec_t *g_table_radar_set[] = { - &chanvec_none, - &radar_set1 -}; - -static const chanvec_t *g_table_restricted_chan[] = { - &chanvec_none, /* restricted_set_none */ - &restricted_set_2g_short, - &restricted_chan_165, - &chanvec_all_5G, - &restricted_set_japan_legacy, - &chanvec_all_2G, /* restricted_set_11d_2G */ - &chanvec_all_5G, /* restricted_set_11d_5G */ - &restricted_low_hi, - &restricted_set_12_13_14 -}; - -static const chanvec_t locale_2g_01_11 = { - {0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_2g_12_13 = { - {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_2g_14 = { - {0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_LOW_JP1 = { - {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_LOW_JP2 = { - {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_LOW1 = { - {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_LOW2 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_LOW3 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_MID1 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_MID2 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_MID3 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_HIGH1 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_HIGH2 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x20, 0x22, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_HIGH3 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_52_140_ALL = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static const chanvec_t locale_5g_HIGH4 = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, - 0x11, 0x11, 0x11, 0x11} -}; - -static const chanvec_t *g_table_locale_base[] = { - &locale_2g_01_11, - &locale_2g_12_13, - &locale_2g_14, - &locale_5g_LOW_JP1, - &locale_5g_LOW_JP2, - &locale_5g_LOW1, - &locale_5g_LOW2, - &locale_5g_LOW3, - &locale_5g_MID1, - &locale_5g_MID2, - &locale_5g_MID3, - &locale_5g_HIGH1, - &locale_5g_HIGH2, - &locale_5g_HIGH3, - &locale_5g_52_140_ALL, - &locale_5g_HIGH4 -}; - -void wlc_locale_add_channels(chanvec_t *target, const chanvec_t *channels) -{ - u8 i; - for (i = 0; i < sizeof(chanvec_t); i++) { - target->vec[i] |= channels->vec[i]; - } -} - -void wlc_locale_get_channels(const locale_info_t *locale, chanvec_t *channels) -{ - u8 i; - - memset(channels, 0, sizeof(chanvec_t)); - - for (i = 0; i < ARRAY_SIZE(g_table_locale_base); i++) { - if (locale->valid_channels & (1 << i)) { - wlc_locale_add_channels(channels, - g_table_locale_base[i]); - } - } -} - -/* - * Locale Definitions - 2.4 GHz - */ -static const locale_info_t locale_i = { /* locale i. channel 1 - 13 */ - LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13, - LOCALE_RADAR_SET_NONE, - LOCALE_RESTRICTED_SET_2G_SHORT, - {QDB(19), QDB(19), QDB(19), - QDB(19), QDB(19), QDB(19)}, - {20, 20, 20, 0}, - WLC_EIRP -}; - -/* - * Locale Definitions - 5 GHz - */ -static const locale_info_t locale_11 = { - /* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */ - LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165, - LOCALE_RADAR_SET_1, - LOCALE_RESTRICTED_NONE, - {QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)}, - {23, 23, 23, 30, 30}, - WLC_EIRP | WLC_DFS_EU -}; - -#define LOCALE_2G_IDX_i 0 -static const locale_info_t *g_locale_2g_table[] = { - &locale_i -}; - -#define LOCALE_5G_IDX_11 0 -static const locale_info_t *g_locale_5g_table[] = { - &locale_11 -}; - -/* - * MIMO Locale Definitions - 2.4 GHz - */ -static const locale_mimo_info_t locale_bn = { - {QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), - QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), - QDB(13), QDB(13), QDB(13)}, - {0, 0, QDB(13), QDB(13), QDB(13), - QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), - QDB(13), 0, 0}, - 0 -}; - -/* locale mimo 2g indexes */ -#define LOCALE_MIMO_IDX_bn 0 - -static const locale_mimo_info_t *g_mimo_2g_table[] = { - &locale_bn -}; - -/* - * MIMO Locale Definitions - 5 GHz - */ -static const locale_mimo_info_t locale_11n = { - { /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)}, - {QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)}, - 0 -}; - -#define LOCALE_MIMO_IDX_11n 0 -static const locale_mimo_info_t *g_mimo_5g_table[] = { - &locale_11n -}; - -#ifdef LC -#undef LC -#endif -#define LC(id) LOCALE_MIMO_IDX_ ## id - -#ifdef LC_2G -#undef LC_2G -#endif -#define LC_2G(id) LOCALE_2G_IDX_ ## id - -#ifdef LC_5G -#undef LC_5G -#endif -#define LC_5G(id) LOCALE_5G_IDX_ ## id - -#define LOCALES(band2, band5, mimo2, mimo5) {LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)} - -static const struct { - char abbrev[WLC_CNTRY_BUF_SZ]; /* country abbreviation */ - country_info_t country; -} cntry_locales[] = { - { - "X2", LOCALES(i, 11, bn, 11n)}, /* Worldwide RoW 2 */ -}; - -#ifdef SUPPORT_40MHZ -/* 20MHz channel info for 40MHz pairing support */ -struct chan20_info { - u8 sb; - u8 adj_sbs; -}; - -/* indicates adjacent channels that are allowed for a 40 Mhz channel and - * those that permitted by the HT - */ -struct chan20_info chan20_info[] = { - /* 11b/11g */ -/* 0 */ {1, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 1 */ {2, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 2 */ {3, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 3 */ {4, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 4 */ {5, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, -/* 5 */ {6, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, -/* 6 */ {7, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, -/* 7 */ {8, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, -/* 8 */ {9, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, -/* 9 */ {10, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 10 */ {11, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 11 */ {12, (CH_LOWER_SB)}, -/* 12 */ {13, (CH_LOWER_SB)}, -/* 13 */ {14, (CH_LOWER_SB)}, - -/* 11a japan high */ -/* 14 */ {34, (CH_UPPER_SB)}, -/* 15 */ {38, (CH_LOWER_SB)}, -/* 16 */ {42, (CH_LOWER_SB)}, -/* 17 */ {46, (CH_LOWER_SB)}, - -/* 11a usa low */ -/* 18 */ {36, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 19 */ {40, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 20 */ {44, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 21 */ {48, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 22 */ {52, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 23 */ {56, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 24 */ {60, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 25 */ {64, (CH_LOWER_SB | CH_EWA_VALID)}, - -/* 11a Europe */ -/* 26 */ {100, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 27 */ {104, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 28 */ {108, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 29 */ {112, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 30 */ {116, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 31 */ {120, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 32 */ {124, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 33 */ {128, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 34 */ {132, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 35 */ {136, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 36 */ {140, (CH_LOWER_SB)}, - -/* 11a usa high, ref5 only */ -/* The 0x80 bit in pdiv means these are REF5, other entries are REF20 */ -/* 37 */ {149, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 38 */ {153, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 39 */ {157, (CH_UPPER_SB | CH_EWA_VALID)}, -/* 40 */ {161, (CH_LOWER_SB | CH_EWA_VALID)}, -/* 41 */ {165, (CH_LOWER_SB)}, - -/* 11a japan */ -/* 42 */ {184, (CH_UPPER_SB)}, -/* 43 */ {188, (CH_LOWER_SB)}, -/* 44 */ {192, (CH_UPPER_SB)}, -/* 45 */ {196, (CH_LOWER_SB)}, -/* 46 */ {200, (CH_UPPER_SB)}, -/* 47 */ {204, (CH_LOWER_SB)}, -/* 48 */ {208, (CH_UPPER_SB)}, -/* 49 */ {212, (CH_LOWER_SB)}, -/* 50 */ {216, (CH_LOWER_SB)} -}; -#endif /* SUPPORT_40MHZ */ - -const locale_info_t *wlc_get_locale_2g(u8 locale_idx) -{ - if (locale_idx >= ARRAY_SIZE(g_locale_2g_table)) { - WL_ERROR("%s: locale 2g index size out of range %d\n", - __func__, locale_idx); - ASSERT(locale_idx < ARRAY_SIZE(g_locale_2g_table)); - return NULL; - } - return g_locale_2g_table[locale_idx]; -} - -const locale_info_t *wlc_get_locale_5g(u8 locale_idx) -{ - if (locale_idx >= ARRAY_SIZE(g_locale_5g_table)) { - WL_ERROR("%s: locale 5g index size out of range %d\n", - __func__, locale_idx); - ASSERT(locale_idx < ARRAY_SIZE(g_locale_5g_table)); - return NULL; - } - return g_locale_5g_table[locale_idx]; -} - -const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx) -{ - if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table)) { - WL_ERROR("%s: mimo 2g index size out of range %d\n", - __func__, locale_idx); - return NULL; - } - return g_mimo_2g_table[locale_idx]; -} - -const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx) -{ - if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table)) { - WL_ERROR("%s: mimo 5g index size out of range %d\n", - __func__, locale_idx); - return NULL; - } - return g_mimo_5g_table[locale_idx]; -} - -wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc) -{ - wlc_cm_info_t *wlc_cm; - char country_abbrev[WLC_CNTRY_BUF_SZ]; - const country_info_t *country; - struct wlc_pub *pub = wlc->pub; - char *ccode; - - WL_TRACE("wl%d: wlc_channel_mgr_attach\n", wlc->pub->unit); - - wlc_cm = kzalloc(sizeof(wlc_cm_info_t), GFP_ATOMIC); - if (wlc_cm == NULL) { - WL_ERROR("wl%d: %s: out of memory", pub->unit, __func__); - return NULL; - } - wlc_cm->pub = pub; - wlc_cm->wlc = wlc; - wlc->cmi = wlc_cm; - - /* store the country code for passing up as a regulatory hint */ - ccode = getvar(wlc->pub->vars, "ccode"); - if (ccode) { - strncpy(wlc->pub->srom_ccode, ccode, WLC_CNTRY_BUF_SZ - 1); - WL_NONE("%s: SROM country code is %c%c\n", - __func__, - wlc->pub->srom_ccode[0], wlc->pub->srom_ccode[1]); - } - - /* internal country information which must match regulatory constraints in firmware */ - memset(country_abbrev, 0, WLC_CNTRY_BUF_SZ); - strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1); - country = wlc_country_lookup(wlc, country_abbrev); - - ASSERT(country != NULL); - - /* save default country for exiting 11d regulatory mode */ - strncpy(wlc->country_default, country_abbrev, WLC_CNTRY_BUF_SZ - 1); - - /* initialize autocountry_default to driver default */ - strncpy(wlc->autocountry_default, "X2", WLC_CNTRY_BUF_SZ - 1); - - wlc_set_countrycode(wlc_cm, country_abbrev); - - return wlc_cm; -} - -void wlc_channel_mgr_detach(wlc_cm_info_t *wlc_cm) -{ - if (wlc_cm) - kfree(wlc_cm); -} - -const char *wlc_channel_country_abbrev(wlc_cm_info_t *wlc_cm) -{ - return wlc_cm->country_abbrev; -} - -u8 wlc_channel_locale_flags(wlc_cm_info_t *wlc_cm) -{ - struct wlc_info *wlc = wlc_cm->wlc; - - return wlc_cm->bandstate[wlc->band->bandunit].locale_flags; -} - -u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, uint bandunit) -{ - return wlc_cm->bandstate[bandunit].locale_flags; -} - -/* return chanvec for a given country code and band */ -bool -wlc_channel_get_chanvec(struct wlc_info *wlc, const char *country_abbrev, - int bandtype, chanvec_t *channels) -{ - const country_info_t *country; - const locale_info_t *locale = NULL; - - country = wlc_country_lookup(wlc, country_abbrev); - if (country == NULL) - return false; - - if (bandtype == WLC_BAND_2G) - locale = wlc_get_locale_2g(country->locale_2G); - else if (bandtype == WLC_BAND_5G) - locale = wlc_get_locale_5g(country->locale_5G); - if (locale == NULL) - return false; - - wlc_locale_get_channels(locale, channels); - return true; -} - -/* set the driver's current country and regulatory information using a country code - * as the source. Lookup built in country information found with the country code. - */ -int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode) -{ - char country_abbrev[WLC_CNTRY_BUF_SZ]; - strncpy(country_abbrev, ccode, WLC_CNTRY_BUF_SZ); - return wlc_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1); -} - -int -wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, - const char *country_abbrev, - const char *ccode, int regrev) -{ - const country_info_t *country; - char mapped_ccode[WLC_CNTRY_BUF_SZ]; - uint mapped_regrev; - - WL_NONE("%s: (country_abbrev \"%s\", ccode \"%s\", regrev %d) SPROM \"%s\"/%u\n", - __func__, country_abbrev, ccode, regrev, - wlc_cm->srom_ccode, wlc_cm->srom_regrev); - - /* if regrev is -1, lookup the mapped country code, - * otherwise use the ccode and regrev directly - */ - if (regrev == -1) { - /* map the country code to a built-in country code, regrev, and country_info */ - country = - wlc_countrycode_map(wlc_cm, ccode, mapped_ccode, - &mapped_regrev); - } else { - /* find the matching built-in country definition */ - ASSERT(0); - country = wlc_country_lookup_direct(ccode, regrev); - strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ); - mapped_regrev = regrev; - } - - if (country == NULL) - return BCME_BADARG; - - /* set the driver state for the country */ - wlc_set_country_common(wlc_cm, country_abbrev, mapped_ccode, - mapped_regrev, country); - - return 0; -} - -/* set the driver's current country and regulatory information using a country code - * as the source. Look up built in country information found with the country code. - */ -static void -wlc_set_country_common(wlc_cm_info_t *wlc_cm, - const char *country_abbrev, - const char *ccode, uint regrev, - const country_info_t *country) -{ - const locale_mimo_info_t *li_mimo; - const locale_info_t *locale; - struct wlc_info *wlc = wlc_cm->wlc; - char prev_country_abbrev[WLC_CNTRY_BUF_SZ]; - - ASSERT(country != NULL); - - /* save current country state */ - wlc_cm->country = country; - - memset(&prev_country_abbrev, 0, WLC_CNTRY_BUF_SZ); - strncpy(prev_country_abbrev, wlc_cm->country_abbrev, - WLC_CNTRY_BUF_SZ - 1); - - strncpy(wlc_cm->country_abbrev, country_abbrev, WLC_CNTRY_BUF_SZ - 1); - strncpy(wlc_cm->ccode, ccode, WLC_CNTRY_BUF_SZ - 1); - wlc_cm->regrev = regrev; - - /* disable/restore nmode based on country regulations */ - li_mimo = wlc_get_mimo_2g(country->locale_mimo_2G); - if (li_mimo && (li_mimo->flags & WLC_NO_MIMO)) { - wlc_set_nmode(wlc, OFF); - wlc->stf->no_cddstbc = true; - } else { - wlc->stf->no_cddstbc = false; - if (N_ENAB(wlc->pub) != wlc->protection->nmode_user) - wlc_set_nmode(wlc, wlc->protection->nmode_user); - } - - wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); - wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); - /* set or restore gmode as required by regulatory */ - locale = wlc_get_locale_2g(country->locale_2G); - if (locale && (locale->flags & WLC_NO_OFDM)) { - wlc_set_gmode(wlc, GMODE_LEGACY_B, false); - } else { - wlc_set_gmode(wlc, wlc->protection->gmode_user, false); - } - - wlc_channels_init(wlc_cm, country); - - return; -} - -/* Lookup a country info structure from a null terminated country code - * The lookup is case sensitive. - */ -const country_info_t *wlc_country_lookup(struct wlc_info *wlc, - const char *ccode) -{ - const country_info_t *country; - char mapped_ccode[WLC_CNTRY_BUF_SZ]; - uint mapped_regrev; - - /* map the country code to a built-in country code, regrev, and country_info struct */ - country = - wlc_countrycode_map(wlc->cmi, ccode, mapped_ccode, &mapped_regrev); - - return country; -} - -static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm, - const char *ccode, - char *mapped_ccode, - uint *mapped_regrev) -{ - struct wlc_info *wlc = wlc_cm->wlc; - const country_info_t *country; - uint srom_regrev = wlc_cm->srom_regrev; - const char *srom_ccode = wlc_cm->srom_ccode; - int mapped; - - /* check for currently supported ccode size */ - if (strlen(ccode) > (WLC_CNTRY_BUF_SZ - 1)) { - WL_ERROR("wl%d: %s: ccode \"%s\" too long for match\n", - wlc->pub->unit, __func__, ccode); - return NULL; - } - - /* default mapping is the given ccode and regrev 0 */ - strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ); - *mapped_regrev = 0; - - /* If the desired country code matches the srom country code, - * then the mapped country is the srom regulatory rev. - * Otherwise look for an aggregate mapping. - */ - if (!strcmp(srom_ccode, ccode)) { - *mapped_regrev = srom_regrev; - mapped = 0; - WL_ERROR("srom_code == ccode %s\n", __func__); - ASSERT(0); - } else { - mapped = - wlc_country_aggregate_map(wlc_cm, ccode, mapped_ccode, - mapped_regrev); - } - - /* find the matching built-in country definition */ - country = wlc_country_lookup_direct(mapped_ccode, *mapped_regrev); - - /* if there is not an exact rev match, default to rev zero */ - if (country == NULL && *mapped_regrev != 0) { - *mapped_regrev = 0; - ASSERT(0); - country = - wlc_country_lookup_direct(mapped_ccode, *mapped_regrev); - } - - return country; -} - -static int -wlc_country_aggregate_map(wlc_cm_info_t *wlc_cm, const char *ccode, - char *mapped_ccode, uint *mapped_regrev) -{ - return false; -} - -/* Lookup a country info structure from a null terminated country - * abbreviation and regrev directly with no translation. - */ -static const country_info_t *wlc_country_lookup_direct(const char *ccode, - uint regrev) -{ - uint size, i; - - /* Should just return 0 for single locale driver. */ - /* Keep it this way in case we add more locales. (for now anyway) */ - - /* all other country def arrays are for regrev == 0, so if regrev is non-zero, fail */ - if (regrev > 0) - return NULL; - - /* find matched table entry from country code */ - size = ARRAY_SIZE(cntry_locales); - for (i = 0; i < size; i++) { - if (strcmp(ccode, cntry_locales[i].abbrev) == 0) { - return &cntry_locales[i].country; - } - } - - WL_ERROR("%s: Returning NULL\n", __func__); - ASSERT(0); - return NULL; -} - -static int -wlc_channels_init(wlc_cm_info_t *wlc_cm, const country_info_t *country) -{ - struct wlc_info *wlc = wlc_cm->wlc; - uint i, j; - struct wlcband *band; - const locale_info_t *li; - chanvec_t sup_chan; - const locale_mimo_info_t *li_mimo; - - band = wlc->band; - for (i = 0; i < NBANDS(wlc); - i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { - - li = BAND_5G(band->bandtype) ? - wlc_get_locale_5g(country->locale_5G) : - wlc_get_locale_2g(country->locale_2G); - ASSERT(li); - wlc_cm->bandstate[band->bandunit].locale_flags = li->flags; - li_mimo = BAND_5G(band->bandtype) ? - wlc_get_mimo_5g(country->locale_mimo_5G) : - wlc_get_mimo_2g(country->locale_mimo_2G); - ASSERT(li_mimo); - - /* merge the mimo non-mimo locale flags */ - wlc_cm->bandstate[band->bandunit].locale_flags |= - li_mimo->flags; - - wlc_cm->bandstate[band->bandunit].restricted_channels = - g_table_restricted_chan[li->restricted_channels]; - wlc_cm->bandstate[band->bandunit].radar_channels = - g_table_radar_set[li->radar_channels]; - - /* set the channel availability, - * masking out the channels that may not be supported on this phy - */ - wlc_phy_chanspec_band_validch(band->pi, band->bandtype, - &sup_chan); - wlc_locale_get_channels(li, - &wlc_cm->bandstate[band->bandunit]. - valid_channels); - for (j = 0; j < sizeof(chanvec_t); j++) - wlc_cm->bandstate[band->bandunit].valid_channels. - vec[j] &= sup_chan.vec[j]; - } - - wlc_quiet_channels_reset(wlc_cm); - wlc_channels_commit(wlc_cm); - - return 0; -} - -/* Update the radio state (enable/disable) and tx power targets - * based on a new set of channel/regulatory information - */ -static void wlc_channels_commit(wlc_cm_info_t *wlc_cm) -{ - struct wlc_info *wlc = wlc_cm->wlc; - uint chan; - struct txpwr_limits txpwr; - - /* search for the existence of any valid channel */ - for (chan = 0; chan < MAXCHANNEL; chan++) { - if (VALID_CHANNEL20_DB(wlc, chan)) { - break; - } - } - if (chan == MAXCHANNEL) - chan = INVCHANNEL; - - /* based on the channel search above, set or clear WL_RADIO_COUNTRY_DISABLE */ - if (chan == INVCHANNEL) { - /* country/locale with no valid channels, set the radio disable bit */ - mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); - WL_ERROR("wl%d: %s: no valid channel for \"%s\" nbands %d bandlocked %d\n", - wlc->pub->unit, __func__, - wlc_cm->country_abbrev, NBANDS(wlc), wlc->bandlocked); - } else - if (mboolisset(wlc->pub->radio_disabled, - WL_RADIO_COUNTRY_DISABLE)) { - /* country/locale with valid channel, clear the radio disable bit */ - mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); - } - - /* Now that the country abbreviation is set, if the radio supports 2G, then - * set channel 14 restrictions based on the new locale. - */ - if (NBANDS(wlc) > 1 || BAND_2G(wlc->band->bandtype)) { - wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi, - wlc_japan(wlc) ? true : - false); - } - - if (wlc->pub->up && chan != INVCHANNEL) { - wlc_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr); - wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, - &txpwr, - WLC_TXPWR_MAX); - wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec); - } -} - -/* reset the quiet channels vector to the union of the restricted and radar channel sets */ -void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm) -{ - struct wlc_info *wlc = wlc_cm->wlc; - uint i, j; - struct wlcband *band; - const chanvec_t *chanvec; - - memset(&wlc_cm->quiet_channels, 0, sizeof(chanvec_t)); - - band = wlc->band; - for (i = 0; i < NBANDS(wlc); - i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { - - /* initialize quiet channels for restricted channels */ - chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels; - for (j = 0; j < sizeof(chanvec_t); j++) - wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j]; - - } -} - -bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec) -{ - return N_ENAB(wlc_cm->wlc->pub) && CHSPEC_IS40(chspec) ? - (isset - (wlc_cm->quiet_channels.vec, - LOWER_20_SB(CHSPEC_CHANNEL(chspec))) - || isset(wlc_cm->quiet_channels.vec, - UPPER_20_SB(CHSPEC_CHANNEL(chspec)))) : isset(wlc_cm-> - quiet_channels. - vec, - CHSPEC_CHANNEL - (chspec)); -} - -/* Is the channel valid for the current locale? (but don't consider channels not - * available due to bandlocking) - */ -bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val) -{ - struct wlc_info *wlc = wlc_cm->wlc; - - return VALID_CHANNEL20(wlc, val) || - (!wlc->bandlocked - && VALID_CHANNEL20_IN_BAND(wlc, OTHERBANDUNIT(wlc), val)); -} - -/* Is the channel valid for the current locale and specified band? */ -bool -wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, uint val) -{ - return ((val < MAXCHANNEL) - && isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val)); -} - -/* Is the channel valid for the current locale and current band? */ -bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val) -{ - struct wlc_info *wlc = wlc_cm->wlc; - - return ((val < MAXCHANNEL) && - isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec, - val)); -} - -/* Is the 40 MHz allowed for the current locale and specified band? */ -bool wlc_valid_40chanspec_in_band(wlc_cm_info_t *wlc_cm, uint bandunit) -{ - struct wlc_info *wlc = wlc_cm->wlc; - - return (((wlc_cm->bandstate[bandunit]. - locale_flags & (WLC_NO_MIMO | WLC_NO_40MHZ)) == 0) - && wlc->bandstate[bandunit]->mimo_cap_40); -} - -static void -wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t *wlc_cm, - struct txpwr_limits *txpwr, - u8 - local_constraint_qdbm) -{ - int j; - - /* CCK Rates */ - for (j = 0; j < WL_TX_POWER_CCK_NUM; j++) { - txpwr->cck[j] = min(txpwr->cck[j], local_constraint_qdbm); - } - - /* 20 MHz Legacy OFDM SISO */ - for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++) { - txpwr->ofdm[j] = min(txpwr->ofdm[j], local_constraint_qdbm); - } - - /* 20 MHz Legacy OFDM CDD */ - for (j = 0; j < WLC_NUM_RATES_OFDM; j++) { - txpwr->ofdm_cdd[j] = - min(txpwr->ofdm_cdd[j], local_constraint_qdbm); - } - - /* 40 MHz Legacy OFDM SISO */ - for (j = 0; j < WLC_NUM_RATES_OFDM; j++) { - txpwr->ofdm_40_siso[j] = - min(txpwr->ofdm_40_siso[j], local_constraint_qdbm); - } - - /* 40 MHz Legacy OFDM CDD */ - for (j = 0; j < WLC_NUM_RATES_OFDM; j++) { - txpwr->ofdm_40_cdd[j] = - min(txpwr->ofdm_40_cdd[j], local_constraint_qdbm); - } - - /* 20MHz MCS 0-7 SISO */ - for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { - txpwr->mcs_20_siso[j] = - min(txpwr->mcs_20_siso[j], local_constraint_qdbm); - } - - /* 20MHz MCS 0-7 CDD */ - for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { - txpwr->mcs_20_cdd[j] = - min(txpwr->mcs_20_cdd[j], local_constraint_qdbm); - } - - /* 20MHz MCS 0-7 STBC */ - for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { - txpwr->mcs_20_stbc[j] = - min(txpwr->mcs_20_stbc[j], local_constraint_qdbm); - } - - /* 20MHz MCS 8-15 MIMO */ - for (j = 0; j < WLC_NUM_RATES_MCS_2_STREAM; j++) - txpwr->mcs_20_mimo[j] = - min(txpwr->mcs_20_mimo[j], local_constraint_qdbm); - - /* 40MHz MCS 0-7 SISO */ - for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { - txpwr->mcs_40_siso[j] = - min(txpwr->mcs_40_siso[j], local_constraint_qdbm); - } - - /* 40MHz MCS 0-7 CDD */ - for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { - txpwr->mcs_40_cdd[j] = - min(txpwr->mcs_40_cdd[j], local_constraint_qdbm); - } - - /* 40MHz MCS 0-7 STBC */ - for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { - txpwr->mcs_40_stbc[j] = - min(txpwr->mcs_40_stbc[j], local_constraint_qdbm); - } - - /* 40MHz MCS 8-15 MIMO */ - for (j = 0; j < WLC_NUM_RATES_MCS_2_STREAM; j++) - txpwr->mcs_40_mimo[j] = - min(txpwr->mcs_40_mimo[j], local_constraint_qdbm); - - /* 40MHz MCS 32 */ - txpwr->mcs32 = min(txpwr->mcs32, local_constraint_qdbm); - -} - -void -wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, - u8 local_constraint_qdbm) -{ - struct wlc_info *wlc = wlc_cm->wlc; - struct txpwr_limits txpwr; - - wlc_channel_reg_limits(wlc_cm, chanspec, &txpwr); - - wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr, - local_constraint_qdbm); - - wlc_bmac_set_chanspec(wlc->hw, chanspec, - (wlc_quiet_chanspec(wlc_cm, chanspec) != 0), - &txpwr); -} - -int -wlc_channel_set_txpower_limit(wlc_cm_info_t *wlc_cm, - u8 local_constraint_qdbm) -{ - struct wlc_info *wlc = wlc_cm->wlc; - struct txpwr_limits txpwr; - - wlc_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr); - - wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr, - local_constraint_qdbm); - - wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec); - - return 0; -} - -#ifdef POWER_DBG -static void wlc_phy_txpower_limits_dump(txpwr_limits_t *txpwr) -{ - int i; - char fraction[4][4] = { " ", ".25", ".5 ", ".75" }; - - printf("CCK "); - for (i = 0; i < WLC_NUM_RATES_CCK; i++) { - printf(" %2d%s", txpwr->cck[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->cck[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("20 MHz OFDM SISO "); - for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { - printf(" %2d%s", txpwr->ofdm[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->ofdm[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("20 MHz OFDM CDD "); - for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { - printf(" %2d%s", txpwr->ofdm_cdd[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->ofdm_cdd[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("40 MHz OFDM SISO "); - for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { - printf(" %2d%s", txpwr->ofdm_40_siso[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->ofdm_40_siso[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("40 MHz OFDM CDD "); - for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { - printf(" %2d%s", txpwr->ofdm_40_cdd[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->ofdm_40_cdd[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("20 MHz MCS0-7 SISO "); - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_20_siso[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_20_siso[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("20 MHz MCS0-7 CDD "); - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_20_cdd[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_20_cdd[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("20 MHz MCS0-7 STBC "); - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_20_stbc[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_20_stbc[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("20 MHz MCS8-15 SDM "); - for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_20_mimo[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_20_mimo[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("40 MHz MCS0-7 SISO "); - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_40_siso[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_40_siso[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("40 MHz MCS0-7 CDD "); - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_40_cdd[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_40_cdd[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("40 MHz MCS0-7 STBC "); - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_40_stbc[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_40_stbc[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("40 MHz MCS8-15 SDM "); - for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_40_mimo[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_40_mimo[i] % WLC_TXPWR_DB_FACTOR]); - } - printf("\n"); - - printf("MCS32 %2d%s\n", - txpwr->mcs32 / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs32 % WLC_TXPWR_DB_FACTOR]); -} -#endif /* POWER_DBG */ - -void -wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, - txpwr_limits_t *txpwr) -{ - struct wlc_info *wlc = wlc_cm->wlc; - uint i; - uint chan; - int maxpwr; - int delta; - const country_info_t *country; - struct wlcband *band; - const locale_info_t *li; - int conducted_max; - int conducted_ofdm_max; - const locale_mimo_info_t *li_mimo; - int maxpwr20, maxpwr40; - int maxpwr_idx; - uint j; - - memset(txpwr, 0, sizeof(txpwr_limits_t)); - - if (!wlc_valid_chanspec_db(wlc_cm, chanspec)) { - country = wlc_country_lookup(wlc, wlc->autocountry_default); - if (country == NULL) - return; - } else { - country = wlc_cm->country; - } - - chan = CHSPEC_CHANNEL(chanspec); - band = wlc->bandstate[CHSPEC_WLCBANDUNIT(chanspec)]; - li = BAND_5G(band->bandtype) ? - wlc_get_locale_5g(country->locale_5G) : - wlc_get_locale_2g(country->locale_2G); - - li_mimo = BAND_5G(band->bandtype) ? - wlc_get_mimo_5g(country->locale_mimo_5G) : - wlc_get_mimo_2g(country->locale_mimo_2G); - - if (li->flags & WLC_EIRP) { - delta = band->antgain; - } else { - delta = 0; - if (band->antgain > QDB(6)) - delta = band->antgain - QDB(6); /* Excess over 6 dB */ - } - - if (li == &locale_i) { - conducted_max = QDB(22); - conducted_ofdm_max = QDB(22); - } - - /* CCK txpwr limits for 2.4G band */ - if (BAND_2G(band->bandtype)) { - maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_CCK(chan)]; - - maxpwr = maxpwr - delta; - maxpwr = max(maxpwr, 0); - maxpwr = min(maxpwr, conducted_max); - - for (i = 0; i < WLC_NUM_RATES_CCK; i++) - txpwr->cck[i] = (u8) maxpwr; - } - - /* OFDM txpwr limits for 2.4G or 5G bands */ - if (BAND_2G(band->bandtype)) { - maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_OFDM(chan)]; - - } else { - maxpwr = li->maxpwr[CHANNEL_POWER_IDX_5G(chan)]; - } - - maxpwr = maxpwr - delta; - maxpwr = max(maxpwr, 0); - maxpwr = min(maxpwr, conducted_ofdm_max); - - /* Keep OFDM lmit below CCK limit */ - if (BAND_2G(band->bandtype)) - maxpwr = min_t(int, maxpwr, txpwr->cck[0]); - - for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { - txpwr->ofdm[i] = (u8) maxpwr; - } - - for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { - /* OFDM 40 MHz SISO has the same power as the corresponding MCS0-7 rate unless - * overriden by the locale specific code. We set this value to 0 as a - * flag (presumably 0 dBm isn't a possibility) and then copy the MCS0-7 value - * to the 40 MHz value if it wasn't explicitly set. - */ - txpwr->ofdm_40_siso[i] = 0; - - txpwr->ofdm_cdd[i] = (u8) maxpwr; - - txpwr->ofdm_40_cdd[i] = 0; - } - - /* MIMO/HT specific limits */ - if (li_mimo->flags & WLC_EIRP) { - delta = band->antgain; - } else { - delta = 0; - if (band->antgain > QDB(6)) - delta = band->antgain - QDB(6); /* Excess over 6 dB */ - } - - if (BAND_2G(band->bandtype)) - maxpwr_idx = (chan - 1); - else - maxpwr_idx = CHANNEL_POWER_IDX_5G(chan); - - maxpwr20 = li_mimo->maxpwr20[maxpwr_idx]; - maxpwr40 = li_mimo->maxpwr40[maxpwr_idx]; - - maxpwr20 = maxpwr20 - delta; - maxpwr20 = max(maxpwr20, 0); - maxpwr40 = maxpwr40 - delta; - maxpwr40 = max(maxpwr40, 0); - - /* Fill in the MCS 0-7 (SISO) rates */ - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - - /* 20 MHz has the same power as the corresponding OFDM rate unless - * overriden by the locale specific code. - */ - txpwr->mcs_20_siso[i] = txpwr->ofdm[i]; - txpwr->mcs_40_siso[i] = 0; - } - - /* Fill in the MCS 0-7 CDD rates */ - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - txpwr->mcs_20_cdd[i] = (u8) maxpwr20; - txpwr->mcs_40_cdd[i] = (u8) maxpwr40; - } - - /* These locales have SISO expressed in the table and override CDD later */ - if (li_mimo == &locale_bn) { - if (li_mimo == &locale_bn) { - maxpwr20 = QDB(16); - maxpwr40 = 0; - - if (chan >= 3 && chan <= 11) { - maxpwr40 = QDB(16); - } - } - - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - txpwr->mcs_20_siso[i] = (u8) maxpwr20; - txpwr->mcs_40_siso[i] = (u8) maxpwr40; - } - } - - /* Fill in the MCS 0-7 STBC rates */ - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - txpwr->mcs_20_stbc[i] = 0; - txpwr->mcs_40_stbc[i] = 0; - } - - /* Fill in the MCS 8-15 SDM rates */ - for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) { - txpwr->mcs_20_mimo[i] = (u8) maxpwr20; - txpwr->mcs_40_mimo[i] = (u8) maxpwr40; - } - - /* Fill in MCS32 */ - txpwr->mcs32 = (u8) maxpwr40; - - for (i = 0, j = 0; i < WLC_NUM_RATES_OFDM; i++, j++) { - if (txpwr->ofdm_40_cdd[i] == 0) - txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j]; - if (i == 0) { - i = i + 1; - if (txpwr->ofdm_40_cdd[i] == 0) - txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j]; - } - } - - /* Copy the 40 MHZ MCS 0-7 CDD value to the 40 MHZ MCS 0-7 SISO value if it wasn't - * provided explicitly. - */ - - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - if (txpwr->mcs_40_siso[i] == 0) - txpwr->mcs_40_siso[i] = txpwr->mcs_40_cdd[i]; - } - - for (i = 0, j = 0; i < WLC_NUM_RATES_OFDM; i++, j++) { - if (txpwr->ofdm_40_siso[i] == 0) - txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j]; - if (i == 0) { - i = i + 1; - if (txpwr->ofdm_40_siso[i] == 0) - txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j]; - } - } - - /* Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding STBC values if they weren't - * provided explicitly. - */ - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - if (txpwr->mcs_20_stbc[i] == 0) - txpwr->mcs_20_stbc[i] = txpwr->mcs_20_cdd[i]; - - if (txpwr->mcs_40_stbc[i] == 0) - txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i]; - } - -#ifdef POWER_DBG - wlc_phy_txpower_limits_dump(txpwr); -#endif - return; -} - -/* Returns true if currently set country is Japan or variant */ -bool wlc_japan(struct wlc_info *wlc) -{ - return wlc_japan_ccode(wlc->cmi->country_abbrev); -} - -/* JP, J1 - J10 are Japan ccodes */ -static bool wlc_japan_ccode(const char *ccode) -{ - return (ccode[0] == 'J' && - (ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9'))); -} - -/* - * Validate the chanspec for this locale, for 40MHZ we need to also check that the sidebands - * are valid 20MZH channels in this locale and they are also a legal HT combination - */ -static bool -wlc_valid_chanspec_ext(wlc_cm_info_t *wlc_cm, chanspec_t chspec, bool dualband) -{ - struct wlc_info *wlc = wlc_cm->wlc; - u8 channel = CHSPEC_CHANNEL(chspec); - - /* check the chanspec */ - if (wf_chspec_malformed(chspec)) { - WL_ERROR("wl%d: malformed chanspec 0x%x\n", - wlc->pub->unit, chspec); - ASSERT(0); - return false; - } - - if (CHANNEL_BANDUNIT(wlc_cm->wlc, channel) != - CHSPEC_WLCBANDUNIT(chspec)) - return false; - - /* Check a 20Mhz channel */ - if (CHSPEC_IS20(chspec)) { - if (dualband) - return VALID_CHANNEL20_DB(wlc_cm->wlc, channel); - else - return VALID_CHANNEL20(wlc_cm->wlc, channel); - } -#ifdef SUPPORT_40MHZ - /* We know we are now checking a 40MHZ channel, so we should only be here - * for NPHYS - */ - if (WLCISNPHY(wlc->band) || WLCISSSLPNPHY(wlc->band)) { - u8 upper_sideband = 0, idx; - u8 num_ch20_entries = - sizeof(chan20_info) / sizeof(struct chan20_info); - - if (!VALID_40CHANSPEC_IN_BAND(wlc, CHSPEC_WLCBANDUNIT(chspec))) - return false; - - if (dualband) { - if (!VALID_CHANNEL20_DB(wlc, LOWER_20_SB(channel)) || - !VALID_CHANNEL20_DB(wlc, UPPER_20_SB(channel))) - return false; - } else { - if (!VALID_CHANNEL20(wlc, LOWER_20_SB(channel)) || - !VALID_CHANNEL20(wlc, UPPER_20_SB(channel))) - return false; - } - - /* find the lower sideband info in the sideband array */ - for (idx = 0; idx < num_ch20_entries; idx++) { - if (chan20_info[idx].sb == LOWER_20_SB(channel)) - upper_sideband = chan20_info[idx].adj_sbs; - } - /* check that the lower sideband allows an upper sideband */ - if ((upper_sideband & (CH_UPPER_SB | CH_EWA_VALID)) == - (CH_UPPER_SB | CH_EWA_VALID)) - return true; - return false; - } -#endif /* 40 MHZ */ - - return false; -} - -bool wlc_valid_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec) -{ - return wlc_valid_chanspec_ext(wlc_cm, chspec, false); -} - -bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec) -{ - return wlc_valid_chanspec_ext(wlc_cm, chspec, true); -} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_channel.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_channel.h deleted file mode 100644 index 1f170aff68fd..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_channel.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _WLC_CHANNEL_H_ -#define _WLC_CHANNEL_H_ - -#include - -#define WLC_TXPWR_DB_FACTOR 4 /* conversion for phy txpwr cacluations that use .25 dB units */ - -struct wlc_info; - -/* maxpwr mapping to 5GHz band channels: - * maxpwr[0] - channels [34-48] - * maxpwr[1] - channels [52-60] - * maxpwr[2] - channels [62-64] - * maxpwr[3] - channels [100-140] - * maxpwr[4] - channels [149-165] - */ -#define BAND_5G_PWR_LVLS 5 /* 5 power levels for 5G */ - -/* power level in group of 2.4GHz band channels: - * maxpwr[0] - CCK channels [1] - * maxpwr[1] - CCK channels [2-10] - * maxpwr[2] - CCK channels [11-14] - * maxpwr[3] - OFDM channels [1] - * maxpwr[4] - OFDM channels [2-10] - * maxpwr[5] - OFDM channels [11-14] - */ - -/* macro to get 2.4 GHz channel group index for tx power */ -#define CHANNEL_POWER_IDX_2G_CCK(c) (((c) < 2) ? 0 : (((c) < 11) ? 1 : 2)) /* cck index */ -#define CHANNEL_POWER_IDX_2G_OFDM(c) (((c) < 2) ? 3 : (((c) < 11) ? 4 : 5)) /* ofdm index */ - -/* macro to get 5 GHz channel group index for tx power */ -#define CHANNEL_POWER_IDX_5G(c) \ - (((c) < 52) ? 0 : (((c) < 62) ? 1 : (((c) < 100) ? 2 : (((c) < 149) ? 3 : 4)))) - -#define WLC_MAXPWR_TBL_SIZE 6 /* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */ -#define WLC_MAXPWR_MIMO_TBL_SIZE 14 /* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */ - -/* locale channel and power info. */ -typedef struct { - u32 valid_channels; - u8 radar_channels; /* List of radar sensitive channels */ - u8 restricted_channels; /* List of channels used only if APs are detected */ - s8 maxpwr[WLC_MAXPWR_TBL_SIZE]; /* Max tx pwr in qdBm for each sub-band */ - s8 pub_maxpwr[BAND_5G_PWR_LVLS]; /* Country IE advertised max tx pwr in dBm - * per sub-band - */ - u8 flags; -} locale_info_t; - -/* bits for locale_info flags */ -#define WLC_PEAK_CONDUCTED 0x00 /* Peak for locals */ -#define WLC_EIRP 0x01 /* Flag for EIRP */ -#define WLC_DFS_TPC 0x02 /* Flag for DFS TPC */ -#define WLC_NO_OFDM 0x04 /* Flag for No OFDM */ -#define WLC_NO_40MHZ 0x08 /* Flag for No MIMO 40MHz */ -#define WLC_NO_MIMO 0x10 /* Flag for No MIMO, 20 or 40 MHz */ -#define WLC_RADAR_TYPE_EU 0x20 /* Flag for EU */ -#define WLC_DFS_FCC WLC_DFS_TPC /* Flag for DFS FCC */ -#define WLC_DFS_EU (WLC_DFS_TPC | WLC_RADAR_TYPE_EU) /* Flag for DFS EU */ - -#define ISDFS_EU(fl) (((fl) & WLC_DFS_EU) == WLC_DFS_EU) - -/* locale per-channel tx power limits for MIMO frames - * maxpwr arrays are index by channel for 2.4 GHz limits, and - * by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel) - */ -typedef struct { - s8 maxpwr20[WLC_MAXPWR_MIMO_TBL_SIZE]; /* tx 20 MHz power limits, qdBm units */ - s8 maxpwr40[WLC_MAXPWR_MIMO_TBL_SIZE]; /* tx 40 MHz power limits, qdBm units */ - u8 flags; -} locale_mimo_info_t; - -extern const chanvec_t chanvec_all_2G; -extern const chanvec_t chanvec_all_5G; - -/* - * Country names and abbreviations with locale defined from ISO 3166 - */ -struct country_info { - const u8 locale_2G; /* 2.4G band locale */ - const u8 locale_5G; /* 5G band locale */ - const u8 locale_mimo_2G; /* 2.4G mimo info */ - const u8 locale_mimo_5G; /* 5G mimo info */ -}; - -typedef struct country_info country_info_t; - -typedef struct wlc_cm_info wlc_cm_info_t; - -extern wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc); -extern void wlc_channel_mgr_detach(wlc_cm_info_t *wlc_cm); - -extern int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode); -extern int wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, - const char *country_abbrev, - const char *ccode, int regrev); - -extern const char *wlc_channel_country_abbrev(wlc_cm_info_t *wlc_cm); -extern u8 wlc_channel_locale_flags(wlc_cm_info_t *wlc_cm); -extern u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, - uint bandunit); - -extern void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm); -extern bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec); - -#define VALID_CHANNEL20_DB(wlc, val) wlc_valid_channel20_db((wlc)->cmi, val) -#define VALID_CHANNEL20_IN_BAND(wlc, bandunit, val) \ - wlc_valid_channel20_in_band((wlc)->cmi, bandunit, val) -#define VALID_CHANNEL20(wlc, val) wlc_valid_channel20((wlc)->cmi, val) -#define VALID_40CHANSPEC_IN_BAND(wlc, bandunit) wlc_valid_40chanspec_in_band((wlc)->cmi, bandunit) - -extern bool wlc_valid_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec); -extern bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec); -extern bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val); -extern bool wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, - uint val); -extern bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val); -extern bool wlc_valid_40chanspec_in_band(wlc_cm_info_t *wlc_cm, uint bandunit); - -extern void wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, - chanspec_t chanspec, - struct txpwr_limits *txpwr); -extern void wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm, - chanspec_t chanspec, - u8 local_constraint_qdbm); -extern int wlc_channel_set_txpower_limit(wlc_cm_info_t *wlc_cm, - u8 local_constraint_qdbm); - -extern const country_info_t *wlc_country_lookup(struct wlc_info *wlc, - const char *ccode); -extern void wlc_locale_get_channels(const locale_info_t *locale, - chanvec_t *valid_channels); -extern const locale_info_t *wlc_get_locale_2g(u8 locale_idx); -extern const locale_info_t *wlc_get_locale_5g(u8 locale_idx); -extern bool wlc_japan(struct wlc_info *wlc); - -extern u8 wlc_get_regclass(wlc_cm_info_t *wlc_cm, chanspec_t chanspec); -extern bool wlc_channel_get_chanvec(struct wlc_info *wlc, - const char *country_abbrev, int bandtype, - chanvec_t *channels); - -#endif /* _WLC_CHANNEL_H */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_event.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_event.c deleted file mode 100644 index 12b156a82ff2..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_event.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* Local prototypes */ -static void wlc_timer_cb(void *arg); - -/* Private data structures */ -struct wlc_eventq { - wlc_event_t *head; - wlc_event_t *tail; - struct wlc_info *wlc; - void *wl; - struct wlc_pub *pub; - bool tpending; - bool workpending; - struct wl_timer *timer; - wlc_eventq_cb_t cb; - u8 event_inds_mask[broken_roundup(WLC_E_LAST, NBBY) / NBBY]; -}; - -/* - * Export functions - */ -wlc_eventq_t *wlc_eventq_attach(struct wlc_pub *pub, struct wlc_info *wlc, - void *wl, - wlc_eventq_cb_t cb) -{ - wlc_eventq_t *eq; - - eq = kzalloc(sizeof(wlc_eventq_t), GFP_ATOMIC); - if (eq == NULL) - return NULL; - - eq->cb = cb; - eq->wlc = wlc; - eq->wl = wl; - eq->pub = pub; - - eq->timer = wl_init_timer(eq->wl, wlc_timer_cb, eq, "eventq"); - if (!eq->timer) { - WL_ERROR("wl%d: wlc_eventq_attach: timer failed\n", - pub->unit); - kfree(eq); - return NULL; - } - - return eq; -} - -int wlc_eventq_detach(wlc_eventq_t *eq) -{ - /* Clean up pending events */ - wlc_eventq_down(eq); - - if (eq->timer) { - if (eq->tpending) { - wl_del_timer(eq->wl, eq->timer); - eq->tpending = false; - } - wl_free_timer(eq->wl, eq->timer); - eq->timer = NULL; - } - - ASSERT(wlc_eventq_avail(eq) == false); - kfree(eq); - return 0; -} - -int wlc_eventq_down(wlc_eventq_t *eq) -{ - int callbacks = 0; - if (eq->tpending && !eq->workpending) { - if (!wl_del_timer(eq->wl, eq->timer)) - callbacks++; - - ASSERT(wlc_eventq_avail(eq) == true); - ASSERT(eq->workpending == false); - eq->workpending = true; - if (eq->cb) - eq->cb(eq->wlc); - - ASSERT(eq->workpending == true); - eq->workpending = false; - eq->tpending = false; - } else { - ASSERT(eq->workpending || wlc_eventq_avail(eq) == false); - } - return callbacks; -} - -wlc_event_t *wlc_event_alloc(wlc_eventq_t *eq) -{ - wlc_event_t *e; - - e = kzalloc(sizeof(wlc_event_t), GFP_ATOMIC); - - if (e == NULL) - return NULL; - - return e; -} - -void wlc_event_free(wlc_eventq_t *eq, wlc_event_t *e) -{ - ASSERT(e->data == NULL); - ASSERT(e->next == NULL); - kfree(e); -} - -void wlc_eventq_enq(wlc_eventq_t *eq, wlc_event_t *e) -{ - ASSERT(e->next == NULL); - e->next = NULL; - - if (eq->tail) { - eq->tail->next = e; - eq->tail = e; - } else - eq->head = eq->tail = e; - - if (!eq->tpending) { - eq->tpending = true; - /* Use a zero-delay timer to trigger - * delayed processing of the event. - */ - wl_add_timer(eq->wl, eq->timer, 0, 0); - } -} - -wlc_event_t *wlc_eventq_deq(wlc_eventq_t *eq) -{ - wlc_event_t *e; - - e = eq->head; - if (e) { - eq->head = e->next; - e->next = NULL; - - if (eq->head == NULL) - eq->tail = eq->head; - } - return e; -} - -wlc_event_t *wlc_eventq_next(wlc_eventq_t *eq, wlc_event_t *e) -{ -#ifdef BCMDBG - wlc_event_t *etmp; - - for (etmp = eq->head; etmp; etmp = etmp->next) { - if (etmp == e) - break; - } - ASSERT(etmp != NULL); -#endif - - return e->next; -} - -int wlc_eventq_cnt(wlc_eventq_t *eq) -{ - wlc_event_t *etmp; - int cnt = 0; - - for (etmp = eq->head; etmp; etmp = etmp->next) - cnt++; - - return cnt; -} - -bool wlc_eventq_avail(wlc_eventq_t *eq) -{ - return (eq->head != NULL); -} - -/* - * Local Functions - */ -static void wlc_timer_cb(void *arg) -{ - struct wlc_eventq *eq = (struct wlc_eventq *)arg; - - ASSERT(eq->tpending == true); - ASSERT(wlc_eventq_avail(eq) == true); - ASSERT(eq->workpending == false); - eq->workpending = true; - - if (eq->cb) - eq->cb(eq->wlc); - - ASSERT(wlc_eventq_avail(eq) == false); - ASSERT(eq->tpending == true); - eq->workpending = false; - eq->tpending = false; -} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_event.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_event.h deleted file mode 100644 index e75582dcdd93..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_event.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _WLC_EVENT_H_ -#define _WLC_EVENT_H_ - -typedef struct wlc_eventq wlc_eventq_t; - -typedef void (*wlc_eventq_cb_t) (void *arg); - -extern wlc_eventq_t *wlc_eventq_attach(struct wlc_pub *pub, - struct wlc_info *wlc, - void *wl, wlc_eventq_cb_t cb); -extern int wlc_eventq_detach(wlc_eventq_t *eq); -extern int wlc_eventq_down(wlc_eventq_t *eq); -extern void wlc_event_free(wlc_eventq_t *eq, wlc_event_t *e); -extern wlc_event_t *wlc_eventq_next(wlc_eventq_t *eq, wlc_event_t *e); -extern int wlc_eventq_cnt(wlc_eventq_t *eq); -extern bool wlc_eventq_avail(wlc_eventq_t *eq); -extern wlc_event_t *wlc_eventq_deq(wlc_eventq_t *eq); -extern void wlc_eventq_enq(wlc_eventq_t *eq, wlc_event_t *e); -extern wlc_event_t *wlc_event_alloc(wlc_eventq_t *eq); - -extern int wlc_eventq_register_ind(wlc_eventq_t *eq, void *bitvect); -extern int wlc_eventq_query_ind(wlc_eventq_t *eq, void *bitvect); -extern int wlc_eventq_test_ind(wlc_eventq_t *eq, int et); -extern int wlc_eventq_set_ind(wlc_eventq_t *eq, uint et, bool on); -extern void wlc_eventq_flush(wlc_eventq_t *eq); -extern void wlc_assign_event_msg(struct wlc_info *wlc, wl_event_msg_t *msg, - const wlc_event_t *e, u8 *data, - u32 len); - -#ifdef MSGTRACE -extern void wlc_event_sendup_trace(struct wlc_info *wlc, hndrte_dev_t *bus, - u8 *hdr, u16 hdrlen, u8 *buf, - u16 buflen); -#endif - -#endif /* _WLC_EVENT_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_key.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_key.h deleted file mode 100644 index 3e23d5145919..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_key.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_key_h_ -#define _wlc_key_h_ - -struct scb; -struct wlc_info; -struct wlc_bsscfg; -/* Maximum # of keys that wl driver supports in S/W. - * Keys supported in H/W is less than or equal to WSEC_MAX_KEYS. - */ -#define WSEC_MAX_KEYS 54 /* Max # of keys (50 + 4 default keys) */ -#define WLC_DEFAULT_KEYS 4 /* Default # of keys */ - -#define WSEC_MAX_WOWL_KEYS 5 /* Max keys in WOWL mode (1 + 4 default keys) */ - -#define WPA2_GTK_MAX 3 - -/* -* Max # of keys currently supported: -* -* s/w keys if WSEC_SW(wlc->wsec). -* h/w keys otherwise. -*/ -#define WLC_MAX_WSEC_KEYS(wlc) WSEC_MAX_KEYS - -/* number of 802.11 default (non-paired, group keys) */ -#define WSEC_MAX_DEFAULT_KEYS 4 /* # of default keys */ - -/* Max # of hardware keys supported */ -#define WLC_MAX_WSEC_HW_KEYS(wlc) WSEC_MAX_RCMTA_KEYS - -/* Max # of hardware TKIP MIC keys supported */ -#define WLC_MAX_TKMIC_HW_KEYS(wlc) ((D11REV_GE((wlc)->pub->corerev, 13)) ? \ - WSEC_MAX_TKMIC_ENGINE_KEYS : 0) - -#define WSEC_HW_TKMIC_KEY(wlc, key, bsscfg) \ - (((D11REV_GE((wlc)->pub->corerev, 13)) && ((wlc)->machwcap & MCAP_TKIPMIC)) && \ - (key) && ((key)->algo == CRYPTO_ALGO_TKIP) && \ - !WSEC_SOFTKEY(wlc, key, bsscfg) && \ - WSEC_KEY_INDEX(wlc, key) >= WLC_DEFAULT_KEYS && \ - (WSEC_KEY_INDEX(wlc, key) < WSEC_MAX_TKMIC_ENGINE_KEYS)) - -/* index of key in key table */ -#define WSEC_KEY_INDEX(wlc, key) ((key)->idx) - -#define WSEC_SOFTKEY(wlc, key, bsscfg) (WLC_SW_KEYS(wlc, bsscfg) || \ - WSEC_KEY_INDEX(wlc, key) >= WLC_MAX_WSEC_HW_KEYS(wlc)) - -/* get a key, non-NULL only if key allocated and not clear */ -#define WSEC_KEY(wlc, i) (((wlc)->wsec_keys[i] && (wlc)->wsec_keys[i]->len) ? \ - (wlc)->wsec_keys[i] : NULL) - -#define WSEC_SCB_KEY_VALID(scb) (((scb)->key && (scb)->key->len) ? true : false) - -/* default key */ -#define WSEC_BSS_DEFAULT_KEY(bsscfg) (((bsscfg)->wsec_index == -1) ? \ - (struct wsec_key *)NULL:(bsscfg)->bss_def_keys[(bsscfg)->wsec_index]) - -/* Macros for key management in IBSS mode */ -#define WSEC_IBSS_MAX_PEERS 16 /* Max # of IBSS Peers */ -#define WSEC_IBSS_RCMTA_INDEX(idx) \ - (((idx - WSEC_MAX_DEFAULT_KEYS) % WSEC_IBSS_MAX_PEERS) + WSEC_MAX_DEFAULT_KEYS) - -/* contiguous # key slots for infrastructure mode STA */ -#define WSEC_BSS_STA_KEY_GROUP_SIZE 5 - -typedef struct wsec_iv { - u32 hi; /* upper 32 bits of IV */ - u16 lo; /* lower 16 bits of IV */ -} wsec_iv_t; - -#define WLC_NUMRXIVS 16 /* # rx IVs (one per 802.11e TID) */ - -typedef struct wsec_key { - u8 ea[ETH_ALEN]; /* per station */ - u8 idx; /* key index in wsec_keys array */ - u8 id; /* key ID [0-3] */ - u8 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ - u8 rcmta; /* rcmta entry index, same as idx by default */ - u16 flags; /* misc flags */ - u8 algo_hw; /* cache for hw register */ - u8 aes_mode; /* cache for hw register */ - s8 iv_len; /* IV length */ - s8 icv_len; /* ICV length */ - u32 len; /* key length..don't move this var */ - /* data is 4byte aligned */ - u8 data[DOT11_MAX_KEY_SIZE]; /* key data */ - wsec_iv_t rxiv[WLC_NUMRXIVS]; /* Rx IV (one per TID) */ - wsec_iv_t txiv; /* Tx IV */ - -} wsec_key_t; - -#define broken_roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) -typedef struct { - u8 vec[broken_roundup(WSEC_MAX_KEYS, NBBY) / NBBY]; /* bitvec of wsec_key indexes */ -} wsec_key_vec_t; - -/* For use with wsec_key_t.flags */ - -#define WSEC_BS_UPDATE (1 << 0) /* Indicates hw needs key update on BS switch */ -#define WSEC_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */ -#define WSEC_TKIP_ERROR (1 << 2) /* Provoke deliberate MIC error */ -#define WSEC_REPLAY_ERROR (1 << 3) /* Provoke deliberate replay */ -#define WSEC_IBSS_PEER_GROUP_KEY (1 << 7) /* Flag: group key for a IBSS PEER */ -#define WSEC_ICV_ERROR (1 << 8) /* Provoke deliberate ICV error */ - -#define wlc_key_insert(a, b, c, d, e, f, g, h, i, j) (BCME_ERROR) -#define wlc_key_update(a, b, c) do {} while (0) -#define wlc_key_remove(a, b, c) do {} while (0) -#define wlc_key_remove_all(a, b) do {} while (0) -#define wlc_key_delete(a, b, c) do {} while (0) -#define wlc_scb_key_delete(a, b) do {} while (0) -#define wlc_key_lookup(a, b, c, d, e) (NULL) -#define wlc_key_hw_init_all(a) do {} while (0) -#define wlc_key_hw_init(a, b, c) do {} while (0) -#define wlc_key_hw_wowl_init(a, b, c, d) do {} while (0) -#define wlc_key_sw_wowl_update(a, b, c, d, e) do {} while (0) -#define wlc_key_sw_wowl_create(a, b, c) (BCME_ERROR) -#define wlc_key_iv_update(a, b, c, d, e) do {(void)e; } while (0) -#define wlc_key_iv_init(a, b, c) do {} while (0) -#define wlc_key_set_error(a, b, c) (BCME_ERROR) -#define wlc_key_dump_hw(a, b) (BCME_ERROR) -#define wlc_key_dump_sw(a, b) (BCME_ERROR) -#define wlc_key_defkeyflag(a) (0) -#define wlc_rcmta_add_bssid(a, b) do {} while (0) -#define wlc_rcmta_del_bssid(a, b) do {} while (0) -#define wlc_key_scb_delete(a, b) do {} while (0) - -#endif /* _wlc_key_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_mac80211.c deleted file mode 100644 index 5eb41d64bc23..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_mac80211.c +++ /dev/null @@ -1,8479 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "d11ucode_ext.h" -#include -#include -#include - - -/* - * WPA(2) definitions - */ -#define RSN_CAP_4_REPLAY_CNTRS 2 -#define RSN_CAP_16_REPLAY_CNTRS 3 - -#define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS -#define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS - -/* - * buffer length needed for wlc_format_ssid - * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. - */ -#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) - -#define TIMER_INTERVAL_WATCHDOG 1000 /* watchdog timer, in unit of ms */ -#define TIMER_INTERVAL_RADIOCHK 800 /* radio monitor timer, in unit of ms */ - -#ifndef WLC_MPC_MAX_DELAYCNT -#define WLC_MPC_MAX_DELAYCNT 10 /* Max MPC timeout, in unit of watchdog */ -#endif -#define WLC_MPC_MIN_DELAYCNT 1 /* Min MPC timeout, in unit of watchdog */ -#define WLC_MPC_THRESHOLD 3 /* MPC count threshold level */ - -#define BEACON_INTERVAL_DEFAULT 100 /* beacon interval, in unit of 1024TU */ -#define DTIM_INTERVAL_DEFAULT 3 /* DTIM interval, in unit of beacon interval */ - -/* Scale down delays to accommodate QT slow speed */ -#define BEACON_INTERVAL_DEF_QT 20 /* beacon interval, in unit of 1024TU */ -#define DTIM_INTERVAL_DEF_QT 1 /* DTIM interval, in unit of beacon interval */ - -#define TBTT_ALIGN_LEEWAY_US 100 /* min leeway before first TBTT in us */ - -/* - * driver maintains internal 'tick'(wlc->pub->now) which increments in 1s OS timer(soft - * watchdog) it is not a wall clock and won't increment when driver is in "down" state - * this low resolution driver tick can be used for maintenance tasks such as phy - * calibration and scb update - */ - -/* watchdog trigger mode: OSL timer or TBTT */ -#define WLC_WATCHDOG_TBTT(wlc) \ - (wlc->stas_associated > 0 && wlc->PM != PM_OFF && wlc->pub->align_wd_tbtt) - -/* To inform the ucode of the last mcast frame posted so that it can clear moredata bit */ -#define BCMCFID(wlc, fid) wlc_bmac_write_shm((wlc)->hw, M_BCMC_FID, (fid)) - -#define WLC_WAR16165(wlc) (wlc->pub->sih->bustype == PCI_BUS && \ - (!AP_ENAB(wlc->pub)) && (wlc->war16165)) - -/* debug/trace */ -uint wl_msg_level = -#if defined(BCMDBG) - WL_ERROR_VAL; -#else - 0; -#endif /* BCMDBG */ - -/* Find basic rate for a given rate */ -#define WLC_BASIC_RATE(wlc, rspec) (IS_MCS(rspec) ? \ - (wlc)->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK].leg_ofdm] : \ - (wlc)->band->basic_rate[rspec & RSPEC_RATE_MASK]) - -#define FRAMETYPE(r, mimoframe) (IS_MCS(r) ? mimoframe : (IS_CCK(r) ? FT_CCK : FT_OFDM)) - -#define RFDISABLE_DEFAULT 10000000 /* rfdisable delay timer 500 ms, runs of ALP clock */ - -#define WLC_TEMPSENSE_PERIOD 10 /* 10 second timeout */ - -#define SCAN_IN_PROGRESS(x) 0 - -#define EPI_VERSION_NUM 0x054b0b00 - -#ifdef BCMDBG -/* pointer to most recently allocated wl/wlc */ -static struct wlc_info *wlc_info_dbg = (struct wlc_info *) (NULL); -#endif - -/* IOVar table */ - -/* Parameter IDs, for use only internally to wlc -- in the wlc_iovars - * table and by the wlc_doiovar() function. No ordering is imposed: - * the table is keyed by name, and the function uses a switch. - */ -enum { - IOV_MPC = 1, - IOV_QTXPOWER, - IOV_BCN_LI_BCN, /* Beacon listen interval in # of beacons */ - IOV_LAST /* In case of a need to check max ID number */ -}; - -const bcm_iovar_t wlc_iovars[] = { - {"mpc", IOV_MPC, (IOVF_OPEN_ALLOW), IOVT_BOOL, 0}, - {"qtxpower", IOV_QTXPOWER, (IOVF_WHL | IOVF_OPEN_ALLOW), IOVT_UINT32, - 0}, - {"bcn_li_bcn", IOV_BCN_LI_BCN, 0, IOVT_UINT8, 0}, - {NULL, 0, 0, 0, 0} -}; - -const u8 prio2fifo[NUMPRIO] = { - TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */ - TX_AC_BK_FIFO, /* 1 BK AC_BK Background */ - TX_AC_BK_FIFO, /* 2 -- AC_BK Background */ - TX_AC_BE_FIFO, /* 3 EE AC_BE Best Effort */ - TX_AC_VI_FIFO, /* 4 CL AC_VI Video */ - TX_AC_VI_FIFO, /* 5 VI AC_VI Video */ - TX_AC_VO_FIFO, /* 6 VO AC_VO Voice */ - TX_AC_VO_FIFO /* 7 NC AC_VO Voice */ -}; - -/* precedences numbers for wlc queues. These are twice as may levels as - * 802.1D priorities. - * Odd numbers are used for HI priority traffic at same precedence levels - * These constants are used ONLY by wlc_prio2prec_map. Do not use them elsewhere. - */ -#define _WLC_PREC_NONE 0 /* None = - */ -#define _WLC_PREC_BK 2 /* BK - Background */ -#define _WLC_PREC_BE 4 /* BE - Best-effort */ -#define _WLC_PREC_EE 6 /* EE - Excellent-effort */ -#define _WLC_PREC_CL 8 /* CL - Controlled Load */ -#define _WLC_PREC_VI 10 /* Vi - Video */ -#define _WLC_PREC_VO 12 /* Vo - Voice */ -#define _WLC_PREC_NC 14 /* NC - Network Control */ - -/* 802.1D Priority to precedence queue mapping */ -const u8 wlc_prio2prec_map[] = { - _WLC_PREC_BE, /* 0 BE - Best-effort */ - _WLC_PREC_BK, /* 1 BK - Background */ - _WLC_PREC_NONE, /* 2 None = - */ - _WLC_PREC_EE, /* 3 EE - Excellent-effort */ - _WLC_PREC_CL, /* 4 CL - Controlled Load */ - _WLC_PREC_VI, /* 5 Vi - Video */ - _WLC_PREC_VO, /* 6 Vo - Voice */ - _WLC_PREC_NC, /* 7 NC - Network Control */ -}; - -/* Sanity check for tx_prec_map and fifo synchup - * Either there are some packets pending for the fifo, else if fifo is empty then - * all the corresponding precmap bits should be set - */ -#define WLC_TX_FIFO_CHECK(wlc, fifo) (TXPKTPENDGET((wlc), (fifo)) || \ - (TXPKTPENDGET((wlc), (fifo)) == 0 && \ - ((wlc)->tx_prec_map & (wlc)->fifo2prec_map[(fifo)]) == \ - (wlc)->fifo2prec_map[(fifo)])) - -/* TX FIFO number to WME/802.1E Access Category */ -const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE }; - -/* WME/802.1E Access Category to TX FIFO number */ -static const u8 wme_ac2fifo[] = { 1, 0, 2, 3 }; - -static bool in_send_q = false; - -/* Shared memory location index for various AC params */ -#define wme_shmemacindex(ac) wme_ac2fifo[ac] - -#ifdef BCMDBG -static const char *fifo_names[] = { - "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; -const char *aci_names[] = { "AC_BE", "AC_BK", "AC_VI", "AC_VO" }; -#endif - -static const u8 acbitmap2maxprio[] = { - PRIO_8021D_BE, PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_BK, - PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, - PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, - PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO -}; - -/* currently the best mechanism for determining SIFS is the band in use */ -#define SIFS(band) ((band)->bandtype == WLC_BAND_5G ? APHY_SIFS_TIME : BPHY_SIFS_TIME); - -/* value for # replay counters currently supported */ -#define WLC_REPLAY_CNTRS_VALUE WPA_CAP_16_REPLAY_CNTRS - -/* local prototypes */ -static u16 BCMFASTPATH wlc_d11hdrs_mac80211(struct wlc_info *wlc, - struct ieee80211_hw *hw, - struct sk_buff *p, - struct scb *scb, uint frag, - uint nfrags, uint queue, - uint next_frag_len, - wsec_key_t *key, - ratespec_t rspec_override); - -static void wlc_bss_default_init(struct wlc_info *wlc); -static void wlc_ucode_mac_upd(struct wlc_info *wlc); -static ratespec_t mac80211_wlc_set_nrate(struct wlc_info *wlc, - struct wlcband *cur_band, u32 int_val); -static void wlc_tx_prec_map_init(struct wlc_info *wlc); -static void wlc_watchdog(void *arg); -static void wlc_watchdog_by_timer(void *arg); -static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg); -static int wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, - const bcm_iovar_t *vi); -static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc); - -/* send and receive */ -static wlc_txq_info_t *wlc_txq_alloc(struct wlc_info *wlc, - struct osl_info *osh); -static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh, - wlc_txq_info_t *qi); -static void wlc_txflowcontrol_signal(struct wlc_info *wlc, wlc_txq_info_t *qi, - bool on, int prio); -static void wlc_txflowcontrol_reset(struct wlc_info *wlc); -static u16 wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, - uint length); -static void wlc_compute_cck_plcp(ratespec_t rate, uint length, u8 *plcp); -static void wlc_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp); -static void wlc_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp); -static u16 wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, - u8 preamble_type, uint next_frag_len); -static void wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, - d11rxhdr_t *rxh, struct sk_buff *p); -static uint wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t rate, - u8 preamble_type, uint dur); -static uint wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rate, - u8 preamble_type); -static uint wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rate, - u8 preamble_type); -/* interrupt, up/down, band */ -static void wlc_setband(struct wlc_info *wlc, uint bandunit); -static chanspec_t wlc_init_chanspec(struct wlc_info *wlc); -static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec); -static void wlc_bsinit(struct wlc_info *wlc); -static int wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, - bool writeToShm); -static void wlc_radio_hwdisable_upd(struct wlc_info *wlc); -static bool wlc_radio_monitor_start(struct wlc_info *wlc); -static void wlc_radio_timer(void *arg); -static void wlc_radio_enable(struct wlc_info *wlc); -static void wlc_radio_upd(struct wlc_info *wlc); - -/* scan, association, BSS */ -static uint wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rate, - u8 preamble_type); -static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap); -static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val); -static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val); -static void wlc_war16165(struct wlc_info *wlc, bool tx); - -static void wlc_process_eventq(void *arg); -static void wlc_wme_retries_write(struct wlc_info *wlc); -static bool wlc_attach_stf_ant_init(struct wlc_info *wlc); -static uint wlc_attach_module(struct wlc_info *wlc); -static void wlc_detach_module(struct wlc_info *wlc); -static void wlc_timers_deinit(struct wlc_info *wlc); -static void wlc_down_led_upd(struct wlc_info *wlc); -static uint wlc_down_del_timer(struct wlc_info *wlc); -static void wlc_ofdm_rateset_war(struct wlc_info *wlc); -static int _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, - struct wlc_if *wlcif); - -#if defined(BCMDBG) -void wlc_get_rcmta(struct wlc_info *wlc, int idx, u8 *addr) -{ - d11regs_t *regs = wlc->regs; - u32 v32; - struct osl_info *osh; - - WL_TRACE("wl%d: %s\n", WLCWLUNIT(wlc), __func__); - - ASSERT(wlc->pub->corerev > 4); - - osh = wlc->osh; - - W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); - (void)R_REG(osh, ®s->objaddr); - v32 = R_REG(osh, ®s->objdata); - addr[0] = (u8) v32; - addr[1] = (u8) (v32 >> 8); - addr[2] = (u8) (v32 >> 16); - addr[3] = (u8) (v32 >> 24); - W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1))); - (void)R_REG(osh, ®s->objaddr); - v32 = R_REG(osh, (volatile u16 *)®s->objdata); - addr[4] = (u8) v32; - addr[5] = (u8) (v32 >> 8); -} -#endif /* defined(BCMDBG) */ - -/* keep the chip awake if needed */ -bool wlc_stay_awake(struct wlc_info *wlc) -{ - return true; -} - -/* conditions under which the PM bit should be set in outgoing frames and STAY_AWAKE is meaningful - */ -bool wlc_ps_allowed(struct wlc_info *wlc) -{ - int idx; - wlc_bsscfg_t *cfg; - - /* disallow PS when one of the following global conditions meets */ - if (!wlc->pub->associated || !wlc->PMenabled || wlc->PM_override) - return false; - - /* disallow PS when one of these meets when not scanning */ - if (!wlc->PMblocked) { - if (AP_ACTIVE(wlc) || wlc->monitor) - return false; - } - - FOREACH_AS_STA(wlc, idx, cfg) { - /* disallow PS when one of the following bsscfg specific conditions meets */ - if (!cfg->BSS || !WLC_PORTOPEN(cfg)) - return false; - - if (!cfg->dtim_programmed) - return false; - } - - return true; -} - -void wlc_reset(struct wlc_info *wlc) -{ - WL_TRACE("wl%d: wlc_reset\n", wlc->pub->unit); - - wlc->check_for_unaligned_tbtt = false; - - /* slurp up hw mac counters before core reset */ - if (WLC_UPDATE_STATS(wlc)) { - wlc_statsupd(wlc); - - /* reset our snapshot of macstat counters */ - memset((char *)wlc->core->macstat_snapshot, 0, - sizeof(macstat_t)); - } - - wlc_bmac_reset(wlc->hw); - wlc_ampdu_reset(wlc->ampdu); - wlc->txretried = 0; - -} - -void wlc_fatal_error(struct wlc_info *wlc) -{ - WL_ERROR("wl%d: fatal error, reinitializing\n", wlc->pub->unit); - wl_init(wlc->wl); -} - -/* Return the channel the driver should initialize during wlc_init. - * the channel may have to be changed from the currently configured channel - * if other configurations are in conflict (bandlocked, 11n mode disabled, - * invalid channel for current country, etc.) - */ -static chanspec_t wlc_init_chanspec(struct wlc_info *wlc) -{ - chanspec_t chanspec = - 1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE | - WL_CHANSPEC_BAND_2G; - - /* make sure the channel is on the supported band if we are band-restricted */ - if (wlc->bandlocked || NBANDS(wlc) == 1) { - ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit); - } - ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec)); - return chanspec; -} - -struct scb global_scb; - -static void wlc_init_scb(struct wlc_info *wlc, struct scb *scb) -{ - int i; - scb->flags = SCB_WMECAP | SCB_HTCAP; - for (i = 0; i < NUMPRIO; i++) - scb->seqnum[i] = 0; -} - -void wlc_init(struct wlc_info *wlc) -{ - d11regs_t *regs; - chanspec_t chanspec; - int i; - wlc_bsscfg_t *bsscfg; - bool mute = false; - - WL_TRACE("wl%d: wlc_init\n", wlc->pub->unit); - - regs = wlc->regs; - - /* This will happen if a big-hammer was executed. In that case, we want to go back - * to the channel that we were on and not new channel - */ - if (wlc->pub->associated) - chanspec = wlc->home_chanspec; - else - chanspec = wlc_init_chanspec(wlc); - - wlc_bmac_init(wlc->hw, chanspec, mute); - - wlc->seckeys = wlc_bmac_read_shm(wlc->hw, M_SECRXKEYS_PTR) * 2; - if (D11REV_GE(wlc->pub->corerev, 15) && (wlc->machwcap & MCAP_TKIPMIC)) - wlc->tkmickeys = - wlc_bmac_read_shm(wlc->hw, M_TKMICKEYS_PTR) * 2; - - /* update beacon listen interval */ - wlc_bcn_li_upd(wlc); - wlc->bcn_wait_prd = - (u8) (wlc_bmac_read_shm(wlc->hw, M_NOSLPZNATDTIM) >> 10); - ASSERT(wlc->bcn_wait_prd > 0); - - /* the world is new again, so is our reported rate */ - wlc_reprate_init(wlc); - - /* write ethernet address to core */ - FOREACH_BSS(wlc, i, bsscfg) { - wlc_set_mac(bsscfg); - wlc_set_bssid(bsscfg); - } - - /* Update tsf_cfprep if associated and up */ - if (wlc->pub->associated) { - FOREACH_BSS(wlc, i, bsscfg) { - if (bsscfg->up) { - u32 bi; - - /* get beacon period from bsscfg and convert to uS */ - bi = bsscfg->current_bss->beacon_period << 10; - /* update the tsf_cfprep register */ - /* since init path would reset to default value */ - W_REG(wlc->osh, ®s->tsf_cfprep, - (bi << CFPREP_CBI_SHIFT)); - - /* Update maccontrol PM related bits */ - wlc_set_ps_ctrl(wlc); - - break; - } - } - } - - wlc_key_hw_init_all(wlc); - - wlc_bandinit_ordered(wlc, chanspec); - - wlc_init_scb(wlc, &global_scb); - - /* init probe response timeout */ - wlc_write_shm(wlc, M_PRS_MAXTIME, wlc->prb_resp_timeout); - - /* init max burst txop (framebursting) */ - wlc_write_shm(wlc, M_MBURST_TXOP, - (wlc-> - _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP)); - - /* initialize maximum allowed duty cycle */ - wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true); - wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true); - - /* Update some shared memory locations related to max AMPDU size allowed to received */ - wlc_ampdu_shm_upd(wlc->ampdu); - - /* band-specific inits */ - wlc_bsinit(wlc); - - /* Enable EDCF mode (while the MAC is suspended) */ - if (EDCF_ENAB(wlc->pub)) { - OR_REG(wlc->osh, ®s->ifs_ctl, IFS_USEEDCF); - wlc_edcf_setparams(wlc->cfg, false); - } - - /* Init precedence maps for empty FIFOs */ - wlc_tx_prec_map_init(wlc); - - /* read the ucode version if we have not yet done so */ - if (wlc->ucode_rev == 0) { - wlc->ucode_rev = - wlc_read_shm(wlc, M_BOM_REV_MAJOR) << NBITS(u16); - wlc->ucode_rev |= wlc_read_shm(wlc, M_BOM_REV_MINOR); - } - - /* ..now really unleash hell (allow the MAC out of suspend) */ - wlc_enable_mac(wlc); - - /* clear tx flow control */ - wlc_txflowcontrol_reset(wlc); - - /* clear tx data fifo suspends */ - wlc->tx_suspended = false; - - /* enable the RF Disable Delay timer */ - if (D11REV_GE(wlc->pub->corerev, 10)) - W_REG(wlc->osh, &wlc->regs->rfdisabledly, RFDISABLE_DEFAULT); - - /* initialize mpc delay */ - wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; - - /* - * Initialize WME parameters; if they haven't been set by some other - * mechanism (IOVar, etc) then read them from the hardware. - */ - if (WLC_WME_RETRY_SHORT_GET(wlc, 0) == 0) { /* Unintialized; read from HW */ - int ac; - - ASSERT(wlc->clk); - for (ac = 0; ac < AC_COUNT; ac++) { - wlc->wme_retries[ac] = - wlc_read_shm(wlc, M_AC_TXLMT_ADDR(ac)); - } - } -} - -void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc) -{ - wlc->bcnmisc_monitor = promisc; - wlc_mac_bcn_promisc(wlc); -} - -void wlc_mac_bcn_promisc(struct wlc_info *wlc) -{ - if ((AP_ENAB(wlc->pub) && (N_ENAB(wlc->pub) || wlc->band->gmode)) || - wlc->bcnmisc_ibss || wlc->bcnmisc_scan || wlc->bcnmisc_monitor) - wlc_mctrl(wlc, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC); - else - wlc_mctrl(wlc, MCTL_BCNS_PROMISC, 0); -} - -/* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */ -void wlc_mac_promisc(struct wlc_info *wlc) -{ - u32 promisc_bits = 0; - - /* promiscuous mode just sets MCTL_PROMISC - * Note: APs get all BSS traffic without the need to set the MCTL_PROMISC bit - * since all BSS data traffic is directed at the AP - */ - if (PROMISC_ENAB(wlc->pub) && !AP_ENAB(wlc->pub) && !wlc->wet) - promisc_bits |= MCTL_PROMISC; - - /* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL - * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is - * handled in wlc_mac_bcn_promisc() - */ - if (MONITOR_ENAB(wlc)) - promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL; - - wlc_mctrl(wlc, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits); -} - -/* check if hps and wake states of sw and hw are in sync */ -bool wlc_ps_check(struct wlc_info *wlc) -{ - bool res = true; - bool hps, wake; - bool wake_ok; - - if (!AP_ACTIVE(wlc)) { - volatile u32 tmp; - tmp = R_REG(wlc->osh, &wlc->regs->maccontrol); - - /* If deviceremoved is detected, then don't take any action as this can be called - * in any context. Assume that caller will take care of the condition. This is just - * to avoid assert - */ - if (tmp == 0xffffffff) { - WL_ERROR("wl%d: %s: dead chip\n", - wlc->pub->unit, __func__); - return DEVICEREMOVED(wlc); - } - - hps = PS_ALLOWED(wlc); - - if (hps != ((tmp & MCTL_HPS) != 0)) { - int idx; - wlc_bsscfg_t *cfg; - WL_ERROR("wl%d: hps not sync, sw %d, maccontrol 0x%x\n", - wlc->pub->unit, hps, tmp); - FOREACH_BSS(wlc, idx, cfg) { - if (!BSSCFG_STA(cfg)) - continue; - } - - res = false; - } - /* For a monolithic build the wake check can be exact since it looks at wake - * override bits. The MCTL_WAKE bit should match the 'wake' value. - */ - wake = STAY_AWAKE(wlc) || wlc->hw->wake_override; - wake_ok = (wake == ((tmp & MCTL_WAKE) != 0)); - if (hps && !wake_ok) { - WL_ERROR("wl%d: wake not sync, sw %d maccontrol 0x%x\n", - wlc->pub->unit, wake, tmp); - res = false; - } - } - ASSERT(res); - return res; -} - -/* push sw hps and wake state through hardware */ -void wlc_set_ps_ctrl(struct wlc_info *wlc) -{ - u32 v1, v2; - bool hps, wake; - bool awake_before; - - hps = PS_ALLOWED(wlc); - wake = hps ? (STAY_AWAKE(wlc)) : true; - - WL_TRACE("wl%d: wlc_set_ps_ctrl: hps %d wake %d\n", - wlc->pub->unit, hps, wake); - - v1 = R_REG(wlc->osh, &wlc->regs->maccontrol); - v2 = 0; - if (hps) - v2 |= MCTL_HPS; - if (wake) - v2 |= MCTL_WAKE; - - wlc_mctrl(wlc, MCTL_WAKE | MCTL_HPS, v2); - - awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0)); - - if (wake && !awake_before) - wlc_bmac_wait_for_wake(wlc->hw); - -} - -/* - * Write this BSS config's MAC address to core. - * Updates RXE match engine. - */ -int wlc_set_mac(wlc_bsscfg_t *cfg) -{ - int err = 0; - struct wlc_info *wlc = cfg->wlc; - - if (cfg == wlc->cfg) { - /* enter the MAC addr into the RXE match registers */ - wlc_set_addrmatch(wlc, RCM_MAC_OFFSET, cfg->cur_etheraddr); - } - - wlc_ampdu_macaddr_upd(wlc); - - return err; -} - -/* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl). - * Updates RXE match engine. - */ -void wlc_set_bssid(wlc_bsscfg_t *cfg) -{ - struct wlc_info *wlc = cfg->wlc; - - /* if primary config, we need to update BSSID in RXE match registers */ - if (cfg == wlc->cfg) { - wlc_set_addrmatch(wlc, RCM_BSSID_OFFSET, cfg->BSSID); - } -#ifdef SUPPORT_HWKEYS - else if (BSSCFG_STA(cfg) && cfg->BSS) { - wlc_rcmta_add_bssid(wlc, cfg); - } -#endif -} - -/* - * Suspend the the MAC and update the slot timing - * for standard 11b/g (20us slots) or shortslot 11g (9us slots). - */ -void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot) -{ - int idx; - wlc_bsscfg_t *cfg; - - ASSERT(wlc->band->gmode); - - /* use the override if it is set */ - if (wlc->shortslot_override != WLC_SHORTSLOT_AUTO) - shortslot = (wlc->shortslot_override == WLC_SHORTSLOT_ON); - - if (wlc->shortslot == shortslot) - return; - - wlc->shortslot = shortslot; - - /* update the capability based on current shortslot mode */ - FOREACH_BSS(wlc, idx, cfg) { - if (!cfg->associated) - continue; - cfg->current_bss->capability &= - ~WLAN_CAPABILITY_SHORT_SLOT_TIME; - if (wlc->shortslot) - cfg->current_bss->capability |= - WLAN_CAPABILITY_SHORT_SLOT_TIME; - } - - wlc_bmac_set_shortslot(wlc->hw, shortslot); -} - -static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc) -{ - u8 local; - s16 local_max; - - local = WLC_TXPWR_MAX; - if (wlc->pub->associated && - (wf_chspec_ctlchan(wlc->chanspec) == - wf_chspec_ctlchan(wlc->home_chanspec))) { - - /* get the local power constraint if we are on the AP's - * channel [802.11h, 7.3.2.13] - */ - /* Clamp the value between 0 and WLC_TXPWR_MAX w/o overflowing the target */ - local_max = - (wlc->txpwr_local_max - - wlc->txpwr_local_constraint) * WLC_TXPWR_DB_FACTOR; - if (local_max > 0 && local_max < WLC_TXPWR_MAX) - return (u8) local_max; - if (local_max < 0) - return 0; - } - - return local; -} - -/* propagate home chanspec to all bsscfgs in case bsscfg->current_bss->chanspec is referenced */ -void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec) -{ - if (wlc->home_chanspec != chanspec) { - int idx; - wlc_bsscfg_t *cfg; - - wlc->home_chanspec = chanspec; - - FOREACH_BSS(wlc, idx, cfg) { - if (!cfg->associated) - continue; - cfg->target_bss->chanspec = chanspec; - cfg->current_bss->chanspec = chanspec; - } - - } -} - -static void wlc_set_phy_chanspec(struct wlc_info *wlc, chanspec_t chanspec) -{ - /* Save our copy of the chanspec */ - wlc->chanspec = chanspec; - - /* Set the chanspec and power limits for this locale after computing - * any 11h local tx power constraints. - */ - wlc_channel_set_chanspec(wlc->cmi, chanspec, - wlc_local_constraint_qdbm(wlc)); - - if (wlc->stf->ss_algosel_auto) - wlc_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel, - chanspec); - - wlc_stf_ss_update(wlc, wlc->band); - -} - -void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec) -{ - uint bandunit; - bool switchband = false; - chanspec_t old_chanspec = wlc->chanspec; - - if (!wlc_valid_chanspec_db(wlc->cmi, chanspec)) { - WL_ERROR("wl%d: %s: Bad channel %d\n", - wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); - ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec)); - return; - } - - /* Switch bands if necessary */ - if (NBANDS(wlc) > 1) { - bandunit = CHSPEC_WLCBANDUNIT(chanspec); - if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) { - switchband = true; - if (wlc->bandlocked) { - WL_ERROR("wl%d: %s: chspec %d band is locked!\n", - wlc->pub->unit, __func__, - CHSPEC_CHANNEL(chanspec)); - return; - } - /* BMAC_NOTE: should the setband call come after the wlc_bmac_chanspec() ? - * if the setband updates (wlc_bsinit) use low level calls to inspect and - * set state, the state inspected may be from the wrong band, or the - * following wlc_bmac_set_chanspec() may undo the work. - */ - wlc_setband(wlc, bandunit); - } - } - - ASSERT(N_ENAB(wlc->pub) || !CHSPEC_IS40(chanspec)); - - /* sync up phy/radio chanspec */ - wlc_set_phy_chanspec(wlc, chanspec); - - /* init antenna selection */ - if (CHSPEC_WLC_BW(old_chanspec) != CHSPEC_WLC_BW(chanspec)) { - if (WLANTSEL_ENAB(wlc)) - wlc_antsel_init(wlc->asi); - - /* Fix the hardware rateset based on bw. - * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz - */ - wlc_rateset_bw_mcs_filter(&wlc->band->hw_rateset, - wlc->band-> - mimo_cap_40 ? CHSPEC_WLC_BW(chanspec) - : 0); - } - - /* update some mac configuration since chanspec changed */ - wlc_ucode_mac_upd(wlc); -} - -#if defined(BCMDBG) -static int wlc_get_current_txpwr(struct wlc_info *wlc, void *pwr, uint len) -{ - txpwr_limits_t txpwr; - tx_power_t power; - tx_power_legacy_t *old_power = NULL; - int r, c; - uint qdbm; - bool override; - - if (len == sizeof(tx_power_legacy_t)) - old_power = (tx_power_legacy_t *) pwr; - else if (len < sizeof(tx_power_t)) - return BCME_BUFTOOSHORT; - - memset(&power, 0, sizeof(tx_power_t)); - - power.chanspec = WLC_BAND_PI_RADIO_CHANSPEC; - if (wlc->pub->associated) - power.local_chanspec = wlc->home_chanspec; - - /* Return the user target tx power limits for the various rates. Note wlc_phy.c's - * public interface only implements getting and setting a single value for all of - * rates, so we need to fill the array ourselves. - */ - wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override); - for (r = 0; r < WL_TX_POWER_RATES; r++) { - power.user_limit[r] = (u8) qdbm; - } - - power.local_max = wlc->txpwr_local_max * WLC_TXPWR_DB_FACTOR; - power.local_constraint = - wlc->txpwr_local_constraint * WLC_TXPWR_DB_FACTOR; - - power.antgain[0] = wlc->bandstate[BAND_2G_INDEX]->antgain; - power.antgain[1] = wlc->bandstate[BAND_5G_INDEX]->antgain; - - wlc_channel_reg_limits(wlc->cmi, power.chanspec, &txpwr); - -#if WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK -#error "WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK" -#endif - - /* CCK tx power limits */ - for (c = 0, r = WL_TX_POWER_CCK_FIRST; c < WL_TX_POWER_CCK_NUM; - c++, r++) - power.reg_limit[r] = txpwr.cck[c]; - -#if WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM -#error "WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM" -#endif - - /* 20 MHz OFDM SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM_FIRST; c < WL_TX_POWER_OFDM_NUM; - c++, r++) - power.reg_limit[r] = txpwr.ofdm[c]; - - if (WLC_PHY_11N_CAP(wlc->band)) { - - /* 20 MHz OFDM CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM20_CDD_FIRST; - c < WL_TX_POWER_OFDM_NUM; c++, r++) - power.reg_limit[r] = txpwr.ofdm_cdd[c]; - - /* 40 MHz OFDM SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM40_SISO_FIRST; - c < WL_TX_POWER_OFDM_NUM; c++, r++) - power.reg_limit[r] = txpwr.ofdm_40_siso[c]; - - /* 40 MHz OFDM CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM40_CDD_FIRST; - c < WL_TX_POWER_OFDM_NUM; c++, r++) - power.reg_limit[r] = txpwr.ofdm_40_cdd[c]; - -#if WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM -#error "WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM" -#endif - - /* 20MHz MCS0-7 SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_SISO_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_siso[c]; - - /* 20MHz MCS0-7 CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_CDD_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_cdd[c]; - - /* 20MHz MCS0-7 STBC tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_STBC_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_stbc[c]; - - /* 40MHz MCS0-7 SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_SISO_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_siso[c]; - - /* 40MHz MCS0-7 CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_CDD_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_cdd[c]; - - /* 40MHz MCS0-7 STBC tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_STBC_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_stbc[c]; - -#if WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM -#error "WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM" -#endif - - /* 20MHz MCS8-15 SDM tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_SDM_FIRST; - c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_mimo[c]; - - /* 40MHz MCS8-15 SDM tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_SDM_FIRST; - c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_mimo[c]; - - /* MCS 32 */ - power.reg_limit[WL_TX_POWER_MCS_32] = txpwr.mcs32; - } - - wlc_phy_txpower_get_current(wlc->band->pi, &power, - CHSPEC_CHANNEL(power.chanspec)); - - /* copy the tx_power_t struct to the return buffer, - * or convert to a tx_power_legacy_t struct - */ - if (!old_power) { - bcopy(&power, pwr, sizeof(tx_power_t)); - } else { - int band_idx = CHSPEC_IS2G(power.chanspec) ? 0 : 1; - - memset(old_power, 0, sizeof(tx_power_legacy_t)); - - old_power->txpwr_local_max = power.local_max; - old_power->txpwr_local_constraint = power.local_constraint; - if (CHSPEC_IS2G(power.chanspec)) { - old_power->txpwr_chan_reg_max = txpwr.cck[0]; - old_power->txpwr_est_Pout[band_idx] = - power.est_Pout_cck; - old_power->txpwr_est_Pout_gofdm = power.est_Pout[0]; - } else { - old_power->txpwr_chan_reg_max = txpwr.ofdm[0]; - old_power->txpwr_est_Pout[band_idx] = power.est_Pout[0]; - } - old_power->txpwr_antgain[0] = power.antgain[0]; - old_power->txpwr_antgain[1] = power.antgain[1]; - - for (r = 0; r < NUM_PWRCTRL_RATES; r++) { - old_power->txpwr_band_max[r] = power.user_limit[r]; - old_power->txpwr_limit[r] = power.reg_limit[r]; - old_power->txpwr_target[band_idx][r] = power.target[r]; - if (CHSPEC_IS2G(power.chanspec)) - old_power->txpwr_bphy_cck_max[r] = - power.board_limit[r]; - else - old_power->txpwr_aphy_max[r] = - power.board_limit[r]; - } - } - - return 0; -} -#endif /* defined(BCMDBG) */ - -static u32 wlc_watchdog_backup_bi(struct wlc_info *wlc) -{ - u32 bi; - bi = 2 * wlc->cfg->current_bss->dtim_period * - wlc->cfg->current_bss->beacon_period; - if (wlc->bcn_li_dtim) - bi *= wlc->bcn_li_dtim; - else if (wlc->bcn_li_bcn) - /* recalculate bi based on bcn_li_bcn */ - bi = 2 * wlc->bcn_li_bcn * wlc->cfg->current_bss->beacon_period; - - if (bi < 2 * TIMER_INTERVAL_WATCHDOG) - bi = 2 * TIMER_INTERVAL_WATCHDOG; - return bi; -} - -/* Change to run the watchdog either from a periodic timer or from tbtt handler. - * Call watchdog from tbtt handler if tbtt is true, watchdog timer otherwise. - */ -void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt) -{ - /* make sure changing watchdog driver is allowed */ - if (!wlc->pub->up || !wlc->pub->align_wd_tbtt) - return; - if (!tbtt && wlc->WDarmed) { - wl_del_timer(wlc->wl, wlc->wdtimer); - wlc->WDarmed = false; - } - - /* stop watchdog timer and use tbtt interrupt to drive watchdog */ - if (tbtt && wlc->WDarmed) { - wl_del_timer(wlc->wl, wlc->wdtimer); - wlc->WDarmed = false; - wlc->WDlast = OSL_SYSUPTIME(); - } - /* arm watchdog timer and drive the watchdog there */ - else if (!tbtt && !wlc->WDarmed) { - wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, - true); - wlc->WDarmed = true; - } - if (tbtt && !wlc->WDarmed) { - wl_add_timer(wlc->wl, wlc->wdtimer, wlc_watchdog_backup_bi(wlc), - true); - wlc->WDarmed = true; - } -} - -ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, wlc_rateset_t *rs) -{ - ratespec_t lowest_basic_rspec; - uint i; - - /* Use the lowest basic rate */ - lowest_basic_rspec = rs->rates[0] & RATE_MASK; - for (i = 0; i < rs->count; i++) { - if (rs->rates[i] & WLC_RATE_FLAG) { - lowest_basic_rspec = rs->rates[i] & RATE_MASK; - break; - } - } -#if NCONF - /* pick siso/cdd as default for OFDM (note no basic rate MCSs are supported yet) */ - if (IS_OFDM(lowest_basic_rspec)) { - lowest_basic_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT); - } -#endif - - return lowest_basic_rspec; -} - -/* This function changes the phytxctl for beacon based on current beacon ratespec AND txant - * setting as per this table: - * ratespec CCK ant = wlc->stf->txant - * OFDM ant = 3 - */ -void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, ratespec_t bcn_rspec) -{ - u16 phyctl; - u16 phytxant = wlc->stf->phytxant; - u16 mask = PHY_TXC_ANT_MASK; - - /* for non-siso rates or default setting, use the available chains */ - if (WLC_PHY_11N_CAP(wlc->band)) { - phytxant = wlc_stf_phytxchain_sel(wlc, bcn_rspec); - } - - phyctl = wlc_read_shm(wlc, M_BCN_PCTLWD); - phyctl = (phyctl & ~mask) | phytxant; - wlc_write_shm(wlc, M_BCN_PCTLWD, phyctl); -} - -/* centralized protection config change function to simplify debugging, no consistency checking - * this should be called only on changes to avoid overhead in periodic function -*/ -void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val) -{ - WL_TRACE("wlc_protection_upd: idx %d, val %d\n", idx, val); - - switch (idx) { - case WLC_PROT_G_SPEC: - wlc->protection->_g = (bool) val; - break; - case WLC_PROT_G_OVR: - wlc->protection->g_override = (s8) val; - break; - case WLC_PROT_G_USER: - wlc->protection->gmode_user = (u8) val; - break; - case WLC_PROT_OVERLAP: - wlc->protection->overlap = (s8) val; - break; - case WLC_PROT_N_USER: - wlc->protection->nmode_user = (s8) val; - break; - case WLC_PROT_N_CFG: - wlc->protection->n_cfg = (s8) val; - break; - case WLC_PROT_N_CFG_OVR: - wlc->protection->n_cfg_override = (s8) val; - break; - case WLC_PROT_N_NONGF: - wlc->protection->nongf = (bool) val; - break; - case WLC_PROT_N_NONGF_OVR: - wlc->protection->nongf_override = (s8) val; - break; - case WLC_PROT_N_PAM_OVR: - wlc->protection->n_pam_override = (s8) val; - break; - case WLC_PROT_N_OBSS: - wlc->protection->n_obss = (bool) val; - break; - - default: - ASSERT(0); - break; - } - -} - -static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val) -{ - wlc->ht_cap.cap_info &= ~(IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_SGI_40); - wlc->ht_cap.cap_info |= (val & WLC_N_SGI_20) ? - IEEE80211_HT_CAP_SGI_20 : 0; - wlc->ht_cap.cap_info |= (val & WLC_N_SGI_40) ? - IEEE80211_HT_CAP_SGI_40 : 0; - - if (wlc->pub->up) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - } -} - -static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val) -{ - wlc->stf->ldpc = val; - - wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_LDPC_CODING; - if (wlc->stf->ldpc != OFF) - wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_LDPC_CODING; - - if (wlc->pub->up) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - wlc_phy_ldpc_override_set(wlc->band->pi, (val ? true : false)); - } -} - -/* - * ucode, hwmac update - * Channel dependent updates for ucode and hw - */ -static void wlc_ucode_mac_upd(struct wlc_info *wlc) -{ - /* enable or disable any active IBSSs depending on whether or not - * we are on the home channel - */ - if (wlc->home_chanspec == WLC_BAND_PI_RADIO_CHANSPEC) { - if (wlc->pub->associated) { - /* BMAC_NOTE: This is something that should be fixed in ucode inits. - * I think that the ucode inits set up the bcn templates and shm values - * with a bogus beacon. This should not be done in the inits. If ucode needs - * to set up a beacon for testing, the test routines should write it down, - * not expect the inits to populate a bogus beacon. - */ - if (WLC_PHY_11N_CAP(wlc->band)) { - wlc_write_shm(wlc, M_BCN_TXTSF_OFFSET, - wlc->band->bcntsfoff); - } - } - } else { - /* disable an active IBSS if we are not on the home channel */ - } - - /* update the various promisc bits */ - wlc_mac_bcn_promisc(wlc); - wlc_mac_promisc(wlc); -} - -static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec) -{ - wlc_rateset_t default_rateset; - uint parkband; - uint i, band_order[2]; - - WL_TRACE("wl%d: wlc_bandinit_ordered\n", wlc->pub->unit); - /* - * We might have been bandlocked during down and the chip power-cycled (hibernate). - * figure out the right band to park on - */ - if (wlc->bandlocked || NBANDS(wlc) == 1) { - ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit); - - parkband = wlc->band->bandunit; /* updated in wlc_bandlock() */ - band_order[0] = band_order[1] = parkband; - } else { - /* park on the band of the specified chanspec */ - parkband = CHSPEC_WLCBANDUNIT(chanspec); - - /* order so that parkband initialize last */ - band_order[0] = parkband ^ 1; - band_order[1] = parkband; - } - - /* make each band operational, software state init */ - for (i = 0; i < NBANDS(wlc); i++) { - uint j = band_order[i]; - - wlc->band = wlc->bandstate[j]; - - wlc_default_rateset(wlc, &default_rateset); - - /* fill in hw_rate */ - wlc_rateset_filter(&default_rateset, &wlc->band->hw_rateset, - false, WLC_RATES_CCK_OFDM, RATE_MASK, - (bool) N_ENAB(wlc->pub)); - - /* init basic rate lookup */ - wlc_rate_lookup_init(wlc, &default_rateset); - } - - /* sync up phy/radio chanspec */ - wlc_set_phy_chanspec(wlc, chanspec); -} - -/* band-specific init */ -static void WLBANDINITFN(wlc_bsinit) (struct wlc_info *wlc) -{ - WL_TRACE("wl%d: wlc_bsinit: bandunit %d\n", - wlc->pub->unit, wlc->band->bandunit); - - /* write ucode ACK/CTS rate table */ - wlc_set_ratetable(wlc); - - /* update some band specific mac configuration */ - wlc_ucode_mac_upd(wlc); - - /* init antenna selection */ - if (WLANTSEL_ENAB(wlc)) - wlc_antsel_init(wlc->asi); - -} - -/* switch to and initialize new band */ -static void WLBANDINITFN(wlc_setband) (struct wlc_info *wlc, uint bandunit) -{ - int idx; - wlc_bsscfg_t *cfg; - - ASSERT(NBANDS(wlc) > 1); - ASSERT(!wlc->bandlocked); - ASSERT(bandunit != wlc->band->bandunit || wlc->bandinit_pending); - - wlc->band = wlc->bandstate[bandunit]; - - if (!wlc->pub->up) - return; - - /* wait for at least one beacon before entering sleeping state */ - wlc->PMawakebcn = true; - FOREACH_AS_STA(wlc, idx, cfg) - cfg->PMawakebcn = true; - wlc_set_ps_ctrl(wlc); - - /* band-specific initializations */ - wlc_bsinit(wlc); -} - -/* Initialize a WME Parameter Info Element with default STA parameters from WMM Spec, Table 12 */ -void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe) -{ - static const wme_param_ie_t stadef = { - WME_OUI, - WME_TYPE, - WME_SUBTYPE_PARAM_IE, - WME_VER, - 0, - 0, - { - {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA, - HTOL16(EDCF_AC_BE_TXOP_STA)}, - {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA, - HTOL16(EDCF_AC_BK_TXOP_STA)}, - {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA, - HTOL16(EDCF_AC_VI_TXOP_STA)}, - {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA, - HTOL16(EDCF_AC_VO_TXOP_STA)} - } - }; - - ASSERT(sizeof(*pe) == WME_PARAM_IE_LEN); - memcpy(pe, &stadef, sizeof(*pe)); -} - -void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend) -{ - int i; - shm_acparams_t acp_shm; - u16 *shm_entry; - struct ieee80211_tx_queue_params *params = arg; - - ASSERT(wlc); - - /* Only apply params if the core is out of reset and has clocks */ - if (!wlc->clk) { - WL_ERROR("wl%d: %s : no-clock\n", wlc->pub->unit, __func__); - return; - } - - /* - * AP uses AC params from wme_param_ie_ap. - * AP advertises AC params from wme_param_ie. - * STA uses AC params from wme_param_ie. - */ - - wlc->wme_admctl = 0; - - do { - memset((char *)&acp_shm, 0, sizeof(shm_acparams_t)); - /* find out which ac this set of params applies to */ - ASSERT(aci < AC_COUNT); - /* set the admission control policy for this AC */ - /* wlc->wme_admctl |= 1 << aci; *//* should be set ?? seems like off by default */ - - /* fill in shm ac params struct */ - acp_shm.txop = ltoh16(params->txop); - /* convert from units of 32us to us for ucode */ - wlc->edcf_txop[aci & 0x3] = acp_shm.txop = - EDCF_TXOP2USEC(acp_shm.txop); - acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK); - - if (aci == AC_VI && acp_shm.txop == 0 - && acp_shm.aifs < EDCF_AIFSN_MAX) - acp_shm.aifs++; - - if (acp_shm.aifs < EDCF_AIFSN_MIN - || acp_shm.aifs > EDCF_AIFSN_MAX) { - WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n", - wlc->pub->unit, acp_shm.aifs); - continue; - } - - acp_shm.cwmin = params->cw_min; - acp_shm.cwmax = params->cw_max; - acp_shm.cwcur = acp_shm.cwmin; - acp_shm.bslots = - R_REG(wlc->osh, &wlc->regs->tsf_random) & acp_shm.cwcur; - acp_shm.reggap = acp_shm.bslots + acp_shm.aifs; - /* Indicate the new params to the ucode */ - acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO + - wme_shmemacindex(aci) * - M_EDCF_QLEN + - M_EDCF_STATUS_OFF)); - acp_shm.status |= WME_STATUS_NEWAC; - - /* Fill in shm acparam table */ - shm_entry = (u16 *) &acp_shm; - for (i = 0; i < (int)sizeof(shm_acparams_t); i += 2) - wlc_write_shm(wlc, - M_EDCF_QINFO + - wme_shmemacindex(aci) * M_EDCF_QLEN + i, - *shm_entry++); - - } while (0); - - if (suspend) - wlc_suspend_mac_and_wait(wlc); - - if (suspend) - wlc_enable_mac(wlc); - -} - -void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend) -{ - struct wlc_info *wlc = cfg->wlc; - uint aci, i, j; - edcf_acparam_t *edcf_acp; - shm_acparams_t acp_shm; - u16 *shm_entry; - - ASSERT(cfg); - ASSERT(wlc); - - /* Only apply params if the core is out of reset and has clocks */ - if (!wlc->clk) - return; - - /* - * AP uses AC params from wme_param_ie_ap. - * AP advertises AC params from wme_param_ie. - * STA uses AC params from wme_param_ie. - */ - - edcf_acp = (edcf_acparam_t *) &wlc->wme_param_ie.acparam[0]; - - wlc->wme_admctl = 0; - - for (i = 0; i < AC_COUNT; i++, edcf_acp++) { - memset((char *)&acp_shm, 0, sizeof(shm_acparams_t)); - /* find out which ac this set of params applies to */ - aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT; - ASSERT(aci < AC_COUNT); - /* set the admission control policy for this AC */ - if (edcf_acp->ACI & EDCF_ACM_MASK) { - wlc->wme_admctl |= 1 << aci; - } - - /* fill in shm ac params struct */ - acp_shm.txop = ltoh16(edcf_acp->TXOP); - /* convert from units of 32us to us for ucode */ - wlc->edcf_txop[aci] = acp_shm.txop = - EDCF_TXOP2USEC(acp_shm.txop); - acp_shm.aifs = (edcf_acp->ACI & EDCF_AIFSN_MASK); - - if (aci == AC_VI && acp_shm.txop == 0 - && acp_shm.aifs < EDCF_AIFSN_MAX) - acp_shm.aifs++; - - if (acp_shm.aifs < EDCF_AIFSN_MIN - || acp_shm.aifs > EDCF_AIFSN_MAX) { - WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n", - wlc->pub->unit, acp_shm.aifs); - continue; - } - - /* CWmin = 2^(ECWmin) - 1 */ - acp_shm.cwmin = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK); - /* CWmax = 2^(ECWmax) - 1 */ - acp_shm.cwmax = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK) - >> EDCF_ECWMAX_SHIFT); - acp_shm.cwcur = acp_shm.cwmin; - acp_shm.bslots = - R_REG(wlc->osh, &wlc->regs->tsf_random) & acp_shm.cwcur; - acp_shm.reggap = acp_shm.bslots + acp_shm.aifs; - /* Indicate the new params to the ucode */ - acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO + - wme_shmemacindex(aci) * - M_EDCF_QLEN + - M_EDCF_STATUS_OFF)); - acp_shm.status |= WME_STATUS_NEWAC; - - /* Fill in shm acparam table */ - shm_entry = (u16 *) &acp_shm; - for (j = 0; j < (int)sizeof(shm_acparams_t); j += 2) - wlc_write_shm(wlc, - M_EDCF_QINFO + - wme_shmemacindex(aci) * M_EDCF_QLEN + j, - *shm_entry++); - } - - if (suspend) - wlc_suspend_mac_and_wait(wlc); - - if (AP_ENAB(wlc->pub) && WME_ENAB(wlc->pub)) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, false); - } - - if (suspend) - wlc_enable_mac(wlc); - -} - -bool wlc_timers_init(struct wlc_info *wlc, int unit) -{ - wlc->wdtimer = wl_init_timer(wlc->wl, wlc_watchdog_by_timer, - wlc, "watchdog"); - if (!wlc->wdtimer) { - WL_ERROR("wl%d: wl_init_timer for wdtimer failed\n", unit); - goto fail; - } - - wlc->radio_timer = wl_init_timer(wlc->wl, wlc_radio_timer, - wlc, "radio"); - if (!wlc->radio_timer) { - WL_ERROR("wl%d: wl_init_timer for radio_timer failed\n", unit); - goto fail; - } - - return true; - - fail: - return false; -} - -/* - * Initialize wlc_info default values ... - * may get overrides later in this function - */ -void wlc_info_init(struct wlc_info *wlc, int unit) -{ - int i; - /* Assume the device is there until proven otherwise */ - wlc->device_present = true; - - /* set default power output percentage to 100 percent */ - wlc->txpwr_percent = 100; - - /* Save our copy of the chanspec */ - wlc->chanspec = CH20MHZ_CHSPEC(1); - - /* initialize CCK preamble mode to unassociated state */ - wlc->shortpreamble = false; - - wlc->legacy_probe = true; - - /* various 802.11g modes */ - wlc->shortslot = false; - wlc->shortslot_override = WLC_SHORTSLOT_AUTO; - - wlc->barker_overlap_control = true; - wlc->barker_preamble = WLC_BARKER_SHORT_ALLOWED; - wlc->txburst_limit_override = AUTO; - - wlc_protection_upd(wlc, WLC_PROT_G_OVR, WLC_PROTECTION_AUTO); - wlc_protection_upd(wlc, WLC_PROT_G_SPEC, false); - - wlc_protection_upd(wlc, WLC_PROT_N_CFG_OVR, WLC_PROTECTION_AUTO); - wlc_protection_upd(wlc, WLC_PROT_N_CFG, WLC_N_PROTECTION_OFF); - wlc_protection_upd(wlc, WLC_PROT_N_NONGF_OVR, WLC_PROTECTION_AUTO); - wlc_protection_upd(wlc, WLC_PROT_N_NONGF, false); - wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR, AUTO); - - wlc_protection_upd(wlc, WLC_PROT_OVERLAP, WLC_PROTECTION_CTL_OVERLAP); - - /* 802.11g draft 4.0 NonERP elt advertisement */ - wlc->include_legacy_erp = true; - - wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF; - wlc->stf->txant = ANT_TX_DEF; - - wlc->prb_resp_timeout = WLC_PRB_RESP_TIMEOUT; - - wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN; - for (i = 0; i < NFIFO; i++) - wlc->fragthresh[i] = DOT11_DEFAULT_FRAG_LEN; - wlc->RTSThresh = DOT11_DEFAULT_RTS_LEN; - - /* default rate fallback retry limits */ - wlc->SFBL = RETRY_SHORT_FB; - wlc->LFBL = RETRY_LONG_FB; - - /* default mac retry limits */ - wlc->SRL = RETRY_SHORT_DEF; - wlc->LRL = RETRY_LONG_DEF; - - /* init PM state */ - wlc->PM = PM_OFF; /* User's setting of PM mode through IOCTL */ - wlc->PM_override = false; /* Prevents from going to PM if our AP is 'ill' */ - wlc->PMenabled = false; /* Current PM state */ - wlc->PMpending = false; /* Tracks whether STA indicated PM in the last attempt */ - wlc->PMblocked = false; /* To allow blocking going into PM during RM and scans */ - - /* In WMM Auto mode, PM is allowed if association is a UAPSD association */ - wlc->WME_PM_blocked = false; - - /* Init wme queuing method */ - wlc->wme_prec_queuing = false; - - /* Overrides for the core to stay awake under zillion conditions Look for STAY_AWAKE */ - wlc->wake = false; - /* Are we waiting for a response to PS-Poll that we sent */ - wlc->PSpoll = false; - - /* APSD defaults */ - wlc->wme_apsd = true; - wlc->apsd_sta_usp = false; - wlc->apsd_trigger_timeout = 0; /* disable the trigger timer */ - wlc->apsd_trigger_ac = AC_BITMAP_ALL; - - /* Set flag to indicate that hw keys should be used when available. */ - wlc->wsec_swkeys = false; - - /* init the 4 static WEP default keys */ - for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) { - wlc->wsec_keys[i] = wlc->wsec_def_keys[i]; - wlc->wsec_keys[i]->idx = (u8) i; - } - - wlc->_regulatory_domain = false; /* 802.11d */ - - /* WME QoS mode is Auto by default */ - wlc->pub->_wme = AUTO; - -#ifdef BCMSDIODEV_ENABLED - wlc->pub->_priofc = true; /* enable priority flow control for sdio dongle */ -#endif - - wlc->pub->_ampdu = AMPDU_AGG_HOST; - wlc->pub->bcmerror = 0; - wlc->ibss_allowed = true; - wlc->ibss_coalesce_allowed = true; - wlc->pub->_coex = ON; - - /* intialize mpc delay */ - wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; - - wlc->pr80838_war = true; -} - -static bool wlc_state_bmac_sync(struct wlc_info *wlc) -{ - wlc_bmac_state_t state_bmac; - - if (wlc_bmac_state_get(wlc->hw, &state_bmac) != 0) - return false; - - wlc->machwcap = state_bmac.machwcap; - wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR, - (s8) state_bmac.preamble_ovr); - - return true; -} - -static uint wlc_attach_module(struct wlc_info *wlc) -{ - uint err = 0; - uint unit; - unit = wlc->pub->unit; - - wlc->asi = wlc_antsel_attach(wlc, wlc->osh, wlc->pub, wlc->hw); - if (wlc->asi == NULL) { - WL_ERROR("wl%d: wlc_attach: wlc_antsel_attach failed\n", unit); - err = 44; - goto fail; - } - - wlc->ampdu = wlc_ampdu_attach(wlc); - if (wlc->ampdu == NULL) { - WL_ERROR("wl%d: wlc_attach: wlc_ampdu_attach failed\n", unit); - err = 50; - goto fail; - } - - /* Initialize event queue; needed before following calls */ - wlc->eventq = - wlc_eventq_attach(wlc->pub, wlc, wlc->wl, wlc_process_eventq); - if (wlc->eventq == NULL) { - WL_ERROR("wl%d: wlc_attach: wlc_eventq_attachfailed\n", unit); - err = 57; - goto fail; - } - - if ((wlc_stf_attach(wlc) != 0)) { - WL_ERROR("wl%d: wlc_attach: wlc_stf_attach failed\n", unit); - err = 68; - goto fail; - } - fail: - return err; -} - -struct wlc_pub *wlc_pub(void *wlc) -{ - return ((struct wlc_info *) wlc)->pub; -} - -#define CHIP_SUPPORTS_11N(wlc) 1 - -/* - * The common driver entry routine. Error codes should be unique - */ -void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, - struct osl_info *osh, void *regsva, uint bustype, - void *btparam, uint *perr) -{ - struct wlc_info *wlc; - uint err = 0; - uint j; - struct wlc_pub *pub; - wlc_txq_info_t *qi; - uint n_disabled; - - WL_NONE("wl%d: %s: vendor 0x%x device 0x%x\n", - unit, __func__, vendor, device); - - ASSERT(WSEC_MAX_RCMTA_KEYS <= WSEC_MAX_KEYS); - ASSERT(WSEC_MAX_DEFAULT_KEYS == WLC_DEFAULT_KEYS); - - /* some code depends on packed structures */ - ASSERT(sizeof(struct ethhdr) == ETH_HLEN); - ASSERT(sizeof(d11regs_t) == SI_CORE_SIZE); - ASSERT(sizeof(ofdm_phy_hdr_t) == D11_PHY_HDR_LEN); - ASSERT(sizeof(cck_phy_hdr_t) == D11_PHY_HDR_LEN); - ASSERT(sizeof(d11txh_t) == D11_TXH_LEN); - ASSERT(sizeof(d11rxhdr_t) == RXHDR_LEN); - ASSERT(sizeof(struct ieee80211_hdr) == DOT11_A4_HDR_LEN); - ASSERT(sizeof(struct ieee80211_rts) == DOT11_RTS_LEN); - ASSERT(sizeof(tx_status_t) == TXSTATUS_LEN); - ASSERT(sizeof(struct ieee80211_ht_cap) == HT_CAP_IE_LEN); -#ifdef BRCM_FULLMAC - ASSERT(offsetof(wl_scan_params_t, channel_list) == - WL_SCAN_PARAMS_FIXED_SIZE); -#endif - ASSERT(IS_ALIGNED(offsetof(wsec_key_t, data), sizeof(u32))); - ASSERT(ISPOWEROF2(MA_WINDOW_SZ)); - - ASSERT(sizeof(wlc_d11rxhdr_t) <= WL_HWRXOFF); - - /* - * Number of replay counters value used in WPA IE must match # rxivs - * supported in wsec_key_t struct. See 802.11i/D3.0 sect. 7.3.2.17 - * 'RSN Information Element' figure 8 for this mapping. - */ - ASSERT((WPA_CAP_16_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE - && 16 == WLC_NUMRXIVS) - || (WPA_CAP_4_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE - && 4 == WLC_NUMRXIVS)); - - /* allocate struct wlc_info state and its substructures */ - wlc = (struct wlc_info *) wlc_attach_malloc(osh, unit, &err, device); - if (wlc == NULL) - goto fail; - wlc->osh = osh; - pub = wlc->pub; - -#if defined(BCMDBG) - wlc_info_dbg = wlc; -#endif - - wlc->band = wlc->bandstate[0]; - wlc->core = wlc->corestate; - wlc->wl = wl; - pub->unit = unit; - pub->osh = osh; - wlc->btparam = btparam; - pub->_piomode = piomode; - wlc->bandinit_pending = false; - /* By default restrict TKIP associations from 11n STA's */ - wlc->ht_wsec_restriction = WLC_HT_TKIP_RESTRICT; - - /* populate struct wlc_info with default values */ - wlc_info_init(wlc, unit); - - /* update sta/ap related parameters */ - wlc_ap_upd(wlc); - - /* 11n_disable nvram */ - n_disabled = getintvar(pub->vars, "11n_disable"); - - /* register a module (to handle iovars) */ - wlc_module_register(wlc->pub, wlc_iovars, "wlc_iovars", wlc, - wlc_doiovar, NULL, NULL); - - /* low level attach steps(all hw accesses go inside, no more in rest of the attach) */ - err = wlc_bmac_attach(wlc, vendor, device, unit, piomode, osh, regsva, - bustype, btparam); - if (err) - goto fail; - - /* for some states, due to different info pointer(e,g, wlc, wlc_hw) or master/slave split, - * HIGH driver(both monolithic and HIGH_ONLY) needs to sync states FROM BMAC portion driver - */ - if (!wlc_state_bmac_sync(wlc)) { - err = 20; - goto fail; - } - - pub->phy_11ncapable = WLC_PHY_11N_CAP(wlc->band); - - /* propagate *vars* from BMAC driver to high driver */ - wlc_bmac_copyfrom_vars(wlc->hw, &pub->vars, &wlc->vars_size); - - - /* set maximum allowed duty cycle */ - wlc->tx_duty_cycle_ofdm = - (u16) getintvar(pub->vars, "tx_duty_cycle_ofdm"); - wlc->tx_duty_cycle_cck = - (u16) getintvar(pub->vars, "tx_duty_cycle_cck"); - - wlc_stf_phy_chain_calc(wlc); - - /* txchain 1: txant 0, txchain 2: txant 1 */ - if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1)) - wlc->stf->txant = wlc->stf->hw_txchain - 1; - - /* push to BMAC driver */ - wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain, - wlc->stf->hw_rxchain); - - /* pull up some info resulting from the low attach */ - { - int i; - for (i = 0; i < NFIFO; i++) - wlc->core->txavail[i] = wlc->hw->txavail[i]; - } - - wlc_bmac_hw_etheraddr(wlc->hw, wlc->perm_etheraddr); - - bcopy((char *)&wlc->perm_etheraddr, (char *)&pub->cur_etheraddr, - ETH_ALEN); - - for (j = 0; j < NBANDS(wlc); j++) { - /* Use band 1 for single band 11a */ - if (IS_SINGLEBAND_5G(wlc->deviceid)) - j = BAND_5G_INDEX; - - wlc->band = wlc->bandstate[j]; - - if (!wlc_attach_stf_ant_init(wlc)) { - err = 24; - goto fail; - } - - /* default contention windows size limits */ - wlc->band->CWmin = APHY_CWMIN; - wlc->band->CWmax = PHY_CWMAX; - - /* init gmode value */ - if (BAND_2G(wlc->band->bandtype)) { - wlc->band->gmode = GMODE_AUTO; - wlc_protection_upd(wlc, WLC_PROT_G_USER, - wlc->band->gmode); - } - - /* init _n_enab supported mode */ - if (WLC_PHY_11N_CAP(wlc->band) && CHIP_SUPPORTS_11N(wlc)) { - if (n_disabled & WLFEATURE_DISABLE_11N) { - pub->_n_enab = OFF; - wlc_protection_upd(wlc, WLC_PROT_N_USER, OFF); - } else { - pub->_n_enab = SUPPORT_11N; - wlc_protection_upd(wlc, WLC_PROT_N_USER, - ((pub->_n_enab == - SUPPORT_11N) ? WL_11N_2x2 : - WL_11N_3x3)); - } - } - - /* init per-band default rateset, depend on band->gmode */ - wlc_default_rateset(wlc, &wlc->band->defrateset); - - /* fill in hw_rateset (used early by WLC_SET_RATESET) */ - wlc_rateset_filter(&wlc->band->defrateset, - &wlc->band->hw_rateset, false, - WLC_RATES_CCK_OFDM, RATE_MASK, - (bool) N_ENAB(wlc->pub)); - } - - /* update antenna config due to wlc->stf->txant/txchain/ant_rx_ovr change */ - wlc_stf_phy_txant_upd(wlc); - - /* attach each modules */ - err = wlc_attach_module(wlc); - if (err != 0) - goto fail; - - if (!wlc_timers_init(wlc, unit)) { - WL_ERROR("wl%d: %s: wlc_init_timer failed\n", unit, __func__); - err = 32; - goto fail; - } - - /* depend on rateset, gmode */ - wlc->cmi = wlc_channel_mgr_attach(wlc); - if (!wlc->cmi) { - WL_ERROR("wl%d: %s: wlc_channel_mgr_attach failed\n", - unit, __func__); - err = 33; - goto fail; - } - - /* init default when all parameters are ready, i.e. ->rateset */ - wlc_bss_default_init(wlc); - - /* - * Complete the wlc default state initializations.. - */ - - /* allocate our initial queue */ - qi = wlc_txq_alloc(wlc, osh); - if (qi == NULL) { - WL_ERROR("wl%d: %s: failed to malloc tx queue\n", - unit, __func__); - err = 100; - goto fail; - } - wlc->active_queue = qi; - - wlc->bsscfg[0] = wlc->cfg; - wlc->cfg->_idx = 0; - wlc->cfg->wlc = wlc; - pub->txmaxpkts = MAXTXPKTS; - - WLCNTSET(pub->_cnt->version, WL_CNT_T_VERSION); - WLCNTSET(pub->_cnt->length, sizeof(wl_cnt_t)); - - WLCNTSET(pub->_wme_cnt->version, WL_WME_CNT_VERSION); - WLCNTSET(pub->_wme_cnt->length, sizeof(wl_wme_cnt_t)); - - wlc_wme_initparams_sta(wlc, &wlc->wme_param_ie); - - wlc->mimoft = FT_HT; - wlc->ht_cap.cap_info = HT_CAP; - if (HT_ENAB(wlc->pub)) - wlc->stf->ldpc = AUTO; - - wlc->mimo_40txbw = AUTO; - wlc->ofdm_40txbw = AUTO; - wlc->cck_40txbw = AUTO; - wlc_update_mimo_band_bwcap(wlc, WLC_N_BW_20IN2G_40IN5G); - - /* Enable setting the RIFS Mode bit by default in HT Info IE */ - wlc->rifs_advert = AUTO; - - /* Set default values of SGI */ - if (WLC_SGI_CAP_PHY(wlc)) { - wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40)); - wlc->sgi_tx = AUTO; - } else if (WLCISSSLPNPHY(wlc->band)) { - wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40)); - wlc->sgi_tx = AUTO; - } else { - wlc_ht_update_sgi_rx(wlc, 0); - wlc->sgi_tx = OFF; - } - - /* *******nvram 11n config overrides Start ********* */ - - /* apply the sgi override from nvram conf */ - if (n_disabled & WLFEATURE_DISABLE_11N_SGI_TX) - wlc->sgi_tx = OFF; - - if (n_disabled & WLFEATURE_DISABLE_11N_SGI_RX) - wlc_ht_update_sgi_rx(wlc, 0); - - /* apply the stbc override from nvram conf */ - if (n_disabled & WLFEATURE_DISABLE_11N_STBC_TX) { - wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF; - wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF; - wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC; - } - if (n_disabled & WLFEATURE_DISABLE_11N_STBC_RX) - wlc_stf_stbc_rx_set(wlc, HT_CAP_RX_STBC_NO); - - /* apply the GF override from nvram conf */ - if (n_disabled & WLFEATURE_DISABLE_11N_GF) - wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_GRN_FLD; - - /* initialize radio_mpc_disable according to wlc->mpc */ - wlc_radio_mpc_upd(wlc); - - if (WLANTSEL_ENAB(wlc)) { - if ((wlc->pub->sih->chip) == BCM43235_CHIP_ID) { - if ((getintvar(wlc->pub->vars, "aa2g") == 7) || - (getintvar(wlc->pub->vars, "aa5g") == 7)) { - wlc_bmac_antsel_set(wlc->hw, 1); - } - } else { - wlc_bmac_antsel_set(wlc->hw, wlc->asi->antsel_avail); - } - } - - if (perr) - *perr = 0; - - return (void *)wlc; - - fail: - WL_ERROR("wl%d: %s: failed with err %d\n", unit, __func__, err); - if (wlc) - wlc_detach(wlc); - - if (perr) - *perr = err; - return NULL; -} - -static void wlc_attach_antgain_init(struct wlc_info *wlc) -{ - uint unit; - unit = wlc->pub->unit; - - if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) { - /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */ - wlc->band->antgain = 8; - } else if (wlc->band->antgain == -1) { - WL_ERROR("wl%d: %s: Invalid antennas available in srom, using 2dB\n", - unit, __func__); - wlc->band->antgain = 8; - } else { - s8 gain, fract; - /* Older sroms specified gain in whole dbm only. In order - * be able to specify qdbm granularity and remain backward compatible - * the whole dbms are now encoded in only low 6 bits and remaining qdbms - * are encoded in the hi 2 bits. 6 bit signed number ranges from - * -32 - 31. Examples: 0x1 = 1 db, - * 0xc1 = 1.75 db (1 + 3 quarters), - * 0x3f = -1 (-1 + 0 quarters), - * 0x7f = -.75 (-1 in low 6 bits + 1 quarters in hi 2 bits) = -3 qdbm. - * 0xbf = -.50 (-1 in low 6 bits + 2 quarters in hi 2 bits) = -2 qdbm. - */ - gain = wlc->band->antgain & 0x3f; - gain <<= 2; /* Sign extend */ - gain >>= 2; - fract = (wlc->band->antgain & 0xc0) >> 6; - wlc->band->antgain = 4 * gain + fract; - } -} - -static bool wlc_attach_stf_ant_init(struct wlc_info *wlc) -{ - int aa; - uint unit; - char *vars; - int bandtype; - - unit = wlc->pub->unit; - vars = wlc->pub->vars; - bandtype = wlc->band->bandtype; - - /* get antennas available */ - aa = (s8) getintvar(vars, (BAND_5G(bandtype) ? "aa5g" : "aa2g")); - if (aa == 0) - aa = (s8) getintvar(vars, - (BAND_5G(bandtype) ? "aa1" : "aa0")); - if ((aa < 1) || (aa > 15)) { - WL_ERROR("wl%d: %s: Invalid antennas available in srom (0x%x), using 3\n", - unit, __func__, aa); - aa = 3; - } - - /* reset the defaults if we have a single antenna */ - if (aa == 1) { - wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_0; - wlc->stf->txant = ANT_TX_FORCE_0; - } else if (aa == 2) { - wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_1; - wlc->stf->txant = ANT_TX_FORCE_1; - } else { - } - - /* Compute Antenna Gain */ - wlc->band->antgain = - (s8) getintvar(vars, (BAND_5G(bandtype) ? "ag1" : "ag0")); - wlc_attach_antgain_init(wlc); - - return true; -} - - -static void wlc_timers_deinit(struct wlc_info *wlc) -{ - /* free timer state */ - if (wlc->wdtimer) { - wl_free_timer(wlc->wl, wlc->wdtimer); - wlc->wdtimer = NULL; - } - if (wlc->radio_timer) { - wl_free_timer(wlc->wl, wlc->radio_timer); - wlc->radio_timer = NULL; - } -} - -static void wlc_detach_module(struct wlc_info *wlc) -{ - if (wlc->asi) { - wlc_antsel_detach(wlc->asi); - wlc->asi = NULL; - } - - if (wlc->ampdu) { - wlc_ampdu_detach(wlc->ampdu); - wlc->ampdu = NULL; - } - - wlc_stf_detach(wlc); -} - -/* - * Return a count of the number of driver callbacks still pending. - * - * General policy is that wlc_detach can only dealloc/free software states. It can NOT - * touch hardware registers since the d11core may be in reset and clock may not be available. - * One exception is sb register access, which is possible if crystal is turned on - * After "down" state, driver should avoid software timer with the exception of radio_monitor. - */ -uint wlc_detach(struct wlc_info *wlc) -{ - uint i; - uint callbacks = 0; - - if (wlc == NULL) - return 0; - - WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__); - - ASSERT(!wlc->pub->up); - - callbacks += wlc_bmac_detach(wlc); - - /* delete software timers */ - if (!wlc_radio_monitor_stop(wlc)) - callbacks++; - - if (wlc->eventq) { - wlc_eventq_detach(wlc->eventq); - wlc->eventq = NULL; - } - - wlc_channel_mgr_detach(wlc->cmi); - - wlc_timers_deinit(wlc); - - wlc_detach_module(wlc); - - /* free other state */ - - -#ifdef BCMDBG - if (wlc->country_ie_override) { - kfree(wlc->country_ie_override); - wlc->country_ie_override = NULL; - } -#endif /* BCMDBG */ - - { - /* free dumpcb list */ - dumpcb_t *prev, *ptr; - prev = ptr = wlc->dumpcb_head; - while (ptr) { - ptr = prev->next; - kfree(prev); - prev = ptr; - } - wlc->dumpcb_head = NULL; - } - - /* Detach from iovar manager */ - wlc_module_unregister(wlc->pub, "wlc_iovars", wlc); - - while (wlc->tx_queues != NULL) { - wlc_txq_free(wlc, wlc->osh, wlc->tx_queues); - } - - /* - * consistency check: wlc_module_register/wlc_module_unregister calls - * should match therefore nothing should be left here. - */ - for (i = 0; i < WLC_MAXMODULES; i++) - ASSERT(wlc->modulecb[i].name[0] == '\0'); - - wlc_detach_mfree(wlc, wlc->osh); - return callbacks; -} - -/* update state that depends on the current value of "ap" */ -void wlc_ap_upd(struct wlc_info *wlc) -{ - if (AP_ENAB(wlc->pub)) - wlc->PLCPHdr_override = WLC_PLCP_AUTO; /* AP: short not allowed, but not enforced */ - else - wlc->PLCPHdr_override = WLC_PLCP_SHORT; /* STA-BSS; short capable */ - - /* disable vlan_mode on AP since some legacy STAs cannot rx tagged pkts */ - wlc->vlan_mode = AP_ENAB(wlc->pub) ? OFF : AUTO; - - /* fixup mpc */ - wlc->mpc = true; -} - -/* read hwdisable state and propagate to wlc flag */ -static void wlc_radio_hwdisable_upd(struct wlc_info *wlc) -{ - if (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO || wlc->pub->hw_off) - return; - - if (wlc_bmac_radio_read_hwdisabled(wlc->hw)) { - mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); - } else { - mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); - } -} - -/* return true if Minimum Power Consumption should be entered, false otherwise */ -bool wlc_is_non_delay_mpc(struct wlc_info *wlc) -{ - return false; -} - -bool wlc_ismpc(struct wlc_info *wlc) -{ - return (wlc->mpc_delay_off == 0) && (wlc_is_non_delay_mpc(wlc)); -} - -void wlc_radio_mpc_upd(struct wlc_info *wlc) -{ - bool mpc_radio, radio_state; - - /* - * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled - * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio - * monitor also when WL_RADIO_MPC_DISABLE is the only reason that - * the radio is going down. - */ - if (!wlc->mpc) { - if (!wlc->pub->radio_disabled) - return; - mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); - wlc_radio_upd(wlc); - if (!wlc->pub->radio_disabled) - wlc_radio_monitor_stop(wlc); - return; - } - - /* - * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in wlc->pub->radio_disabled - * to go ON, always call radio_upd synchronously - * to go OFF, postpone radio_upd to later when context is safe(e.g. watchdog) - */ - radio_state = - (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF : - ON); - mpc_radio = (wlc_ismpc(wlc) == true) ? OFF : ON; - - if (radio_state == ON && mpc_radio == OFF) - wlc->mpc_delay_off = wlc->mpc_dlycnt; - else if (radio_state == OFF && mpc_radio == ON) { - mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); - wlc_radio_upd(wlc); - if (wlc->mpc_offcnt < WLC_MPC_THRESHOLD) { - wlc->mpc_dlycnt = WLC_MPC_MAX_DELAYCNT; - } else - wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; - wlc->mpc_dur += OSL_SYSUPTIME() - wlc->mpc_laston_ts; - } - /* Below logic is meant to capture the transition from mpc off to mpc on for reasons - * other than wlc->mpc_delay_off keeping the mpc off. In that case reset - * wlc->mpc_delay_off to wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off - */ - if ((wlc->prev_non_delay_mpc == false) && - (wlc_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off) { - wlc->mpc_delay_off = wlc->mpc_dlycnt; - } - wlc->prev_non_delay_mpc = wlc_is_non_delay_mpc(wlc); -} - -/* - * centralized radio disable/enable function, - * invoke radio enable/disable after updating hwradio status - */ -static void wlc_radio_upd(struct wlc_info *wlc) -{ - if (wlc->pub->radio_disabled) - wlc_radio_disable(wlc); - else - wlc_radio_enable(wlc); -} - -/* maintain LED behavior in down state */ -static void wlc_down_led_upd(struct wlc_info *wlc) -{ - ASSERT(!wlc->pub->up); - - /* maintain LEDs while in down state, turn on sbclk if not available yet */ - /* turn on sbclk if necessary */ - if (!AP_ENAB(wlc->pub)) { - wlc_pllreq(wlc, true, WLC_PLLREQ_FLIP); - - wlc_pllreq(wlc, false, WLC_PLLREQ_FLIP); - } -} - -void wlc_radio_disable(struct wlc_info *wlc) -{ - if (!wlc->pub->up) { - wlc_down_led_upd(wlc); - return; - } - - wlc_radio_monitor_start(wlc); - wl_down(wlc->wl); -} - -static void wlc_radio_enable(struct wlc_info *wlc) -{ - if (wlc->pub->up) - return; - - if (DEVICEREMOVED(wlc)) - return; - - if (!wlc->down_override) { /* imposed by wl down/out ioctl */ - wl_up(wlc->wl); - } -} - -/* periodical query hw radio button while driver is "down" */ -static void wlc_radio_timer(void *arg) -{ - struct wlc_info *wlc = (struct wlc_info *) arg; - - if (DEVICEREMOVED(wlc)) { - WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); - wl_down(wlc->wl); - return; - } - - /* cap mpc off count */ - if (wlc->mpc_offcnt < WLC_MPC_MAX_DELAYCNT) - wlc->mpc_offcnt++; - - /* validate all the reasons driver could be down and running this radio_timer */ - ASSERT(wlc->pub->radio_disabled || wlc->down_override); - wlc_radio_hwdisable_upd(wlc); - wlc_radio_upd(wlc); -} - -static bool wlc_radio_monitor_start(struct wlc_info *wlc) -{ - /* Don't start the timer if HWRADIO feature is disabled */ - if (wlc->radio_monitor || (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO)) - return true; - - wlc->radio_monitor = true; - wlc_pllreq(wlc, true, WLC_PLLREQ_RADIO_MON); - wl_add_timer(wlc->wl, wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true); - return true; -} - -bool wlc_radio_monitor_stop(struct wlc_info *wlc) -{ - if (!wlc->radio_monitor) - return true; - - ASSERT((wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO) != - WL_SWFL_NOHWRADIO); - - wlc->radio_monitor = false; - wlc_pllreq(wlc, false, WLC_PLLREQ_RADIO_MON); - return wl_del_timer(wlc->wl, wlc->radio_timer); -} - -/* bring the driver down, but don't reset hardware */ -void wlc_out(struct wlc_info *wlc) -{ - wlc_bmac_set_noreset(wlc->hw, true); - wlc_radio_upd(wlc); - wl_down(wlc->wl); - wlc_bmac_set_noreset(wlc->hw, false); - - /* core clk is true in BMAC driver due to noreset, need to mirror it in HIGH */ - wlc->clk = true; - - /* This will make sure that when 'up' is done - * after 'out' it'll restore hardware (especially gpios) - */ - wlc->pub->hw_up = false; -} - -#if defined(BCMDBG) -/* Verify the sanity of wlc->tx_prec_map. This can be done only by making sure that - * if there is no packet pending for the FIFO, then the corresponding prec bits should be set - * in prec_map. Of course, ignore this rule when block_datafifo is set - */ -static bool wlc_tx_prec_map_verify(struct wlc_info *wlc) -{ - /* For non-WME, both fifos have overlapping prec_map. So it's an error only if both - * fail the check. - */ - if (!EDCF_ENAB(wlc->pub)) { - if (!(WLC_TX_FIFO_CHECK(wlc, TX_DATA_FIFO) || - WLC_TX_FIFO_CHECK(wlc, TX_CTL_FIFO))) - return false; - else - return true; - } - - return WLC_TX_FIFO_CHECK(wlc, TX_AC_BK_FIFO) - && WLC_TX_FIFO_CHECK(wlc, TX_AC_BE_FIFO) - && WLC_TX_FIFO_CHECK(wlc, TX_AC_VI_FIFO) - && WLC_TX_FIFO_CHECK(wlc, TX_AC_VO_FIFO); -} -#endif /* BCMDBG */ - -static void wlc_watchdog_by_timer(void *arg) -{ - struct wlc_info *wlc = (struct wlc_info *) arg; - wlc_watchdog(arg); - if (WLC_WATCHDOG_TBTT(wlc)) { - /* set to normal osl watchdog period */ - wl_del_timer(wlc->wl, wlc->wdtimer); - wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, - true); - } -} - -/* common watchdog code */ -static void wlc_watchdog(void *arg) -{ - struct wlc_info *wlc = (struct wlc_info *) arg; - int i; - wlc_bsscfg_t *cfg; - - WL_TRACE("wl%d: wlc_watchdog\n", wlc->pub->unit); - - if (!wlc->pub->up) - return; - - if (DEVICEREMOVED(wlc)) { - WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); - wl_down(wlc->wl); - return; - } - - /* increment second count */ - wlc->pub->now++; - - /* delay radio disable */ - if (wlc->mpc_delay_off) { - if (--wlc->mpc_delay_off == 0) { - mboolset(wlc->pub->radio_disabled, - WL_RADIO_MPC_DISABLE); - if (wlc->mpc && wlc_ismpc(wlc)) - wlc->mpc_offcnt = 0; - wlc->mpc_laston_ts = OSL_SYSUPTIME(); - } - } - - /* mpc sync */ - wlc_radio_mpc_upd(wlc); - /* radio sync: sw/hw/mpc --> radio_disable/radio_enable */ - wlc_radio_hwdisable_upd(wlc); - wlc_radio_upd(wlc); - /* if ismpc, driver should be in down state if up/down is allowed */ - if (wlc->mpc && wlc_ismpc(wlc)) - ASSERT(!wlc->pub->up); - /* if radio is disable, driver may be down, quit here */ - if (wlc->pub->radio_disabled) - return; - - wlc_bmac_watchdog(wlc); - - /* occasionally sample mac stat counters to detect 16-bit counter wrap */ - if ((WLC_UPDATE_STATS(wlc)) - && (!(wlc->pub->now % SW_TIMER_MAC_STAT_UPD))) - wlc_statsupd(wlc); - - /* Manage TKIP countermeasures timers */ - FOREACH_BSS(wlc, i, cfg) { - if (cfg->tk_cm_dt) { - cfg->tk_cm_dt--; - } - if (cfg->tk_cm_bt) { - cfg->tk_cm_bt--; - } - } - - /* Call any registered watchdog handlers */ - for (i = 0; i < WLC_MAXMODULES; i++) { - if (wlc->modulecb[i].watchdog_fn) - wlc->modulecb[i].watchdog_fn(wlc->modulecb[i].hdl); - } - - if (WLCISNPHY(wlc->band) && !wlc->pub->tempsense_disable && - ((wlc->pub->now - wlc->tempsense_lasttime) >= - WLC_TEMPSENSE_PERIOD)) { - wlc->tempsense_lasttime = wlc->pub->now; - wlc_tempsense_upd(wlc); - } - /* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */ - ASSERT(wlc_bmac_taclear(wlc->hw, true)); - - /* Verify that tx_prec_map and fifos are in sync to avoid lock ups */ - ASSERT(wlc_tx_prec_map_verify(wlc)); - - ASSERT(wlc_ps_check(wlc)); -} - -/* make interface operational */ -int wlc_up(struct wlc_info *wlc) -{ - WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__); - - /* HW is turned off so don't try to access it */ - if (wlc->pub->hw_off || DEVICEREMOVED(wlc)) - return BCME_RADIOOFF; - - if (!wlc->pub->hw_up) { - wlc_bmac_hw_up(wlc->hw); - wlc->pub->hw_up = true; - } - - if ((wlc->pub->boardflags & BFL_FEM) - && (wlc->pub->sih->chip == BCM4313_CHIP_ID)) { - if (wlc->pub->boardrev >= 0x1250 - && (wlc->pub->boardflags & BFL_FEM_BT)) { - wlc_mhf(wlc, MHF5, MHF5_4313_GPIOCTRL, - MHF5_4313_GPIOCTRL, WLC_BAND_ALL); - } else { - wlc_mhf(wlc, MHF4, MHF4_EXTPA_ENABLE, MHF4_EXTPA_ENABLE, - WLC_BAND_ALL); - } - } - - /* - * Need to read the hwradio status here to cover the case where the system - * is loaded with the hw radio disabled. We do not want to bring the driver up in this case. - * if radio is disabled, abort up, lower power, start radio timer and return 0(for NDIS) - * don't call radio_update to avoid looping wlc_up. - * - * wlc_bmac_up_prep() returns either 0 or BCME_RADIOOFF only - */ - if (!wlc->pub->radio_disabled) { - int status = wlc_bmac_up_prep(wlc->hw); - if (status == BCME_RADIOOFF) { - if (!mboolisset - (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) { - int idx; - wlc_bsscfg_t *bsscfg; - mboolset(wlc->pub->radio_disabled, - WL_RADIO_HW_DISABLE); - - FOREACH_BSS(wlc, idx, bsscfg) { - if (!BSSCFG_STA(bsscfg) - || !bsscfg->enable || !bsscfg->BSS) - continue; - WL_ERROR("wl%d.%d: wlc_up: rfdisable -> " "wlc_bsscfg_disable()\n", - wlc->pub->unit, idx); - } - } - } else - ASSERT(!status); - } - - if (wlc->pub->radio_disabled) { - wlc_radio_monitor_start(wlc); - return 0; - } - - /* wlc_bmac_up_prep has done wlc_corereset(). so clk is on, set it */ - wlc->clk = true; - - wlc_radio_monitor_stop(wlc); - - /* Set EDCF hostflags */ - if (EDCF_ENAB(wlc->pub)) { - wlc_mhf(wlc, MHF1, MHF1_EDCF, MHF1_EDCF, WLC_BAND_ALL); - } else { - wlc_mhf(wlc, MHF1, MHF1_EDCF, 0, WLC_BAND_ALL); - } - - if (WLC_WAR16165(wlc)) - wlc_mhf(wlc, MHF2, MHF2_PCISLOWCLKWAR, MHF2_PCISLOWCLKWAR, - WLC_BAND_ALL); - - wl_init(wlc->wl); - wlc->pub->up = true; - - if (wlc->bandinit_pending) { - wlc_suspend_mac_and_wait(wlc); - wlc_set_chanspec(wlc, wlc->default_bss->chanspec); - wlc->bandinit_pending = false; - wlc_enable_mac(wlc); - } - - wlc_bmac_up_finish(wlc->hw); - - /* other software states up after ISR is running */ - /* start APs that were to be brought up but are not up yet */ - /* if (AP_ENAB(wlc->pub)) wlc_restart_ap(wlc->ap); */ - - /* Program the TX wme params with the current settings */ - wlc_wme_retries_write(wlc); - - /* start one second watchdog timer */ - ASSERT(!wlc->WDarmed); - wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true); - wlc->WDarmed = true; - - /* ensure antenna config is up to date */ - wlc_stf_phy_txant_upd(wlc); - /* ensure LDPC config is in sync */ - wlc_ht_update_ldpc(wlc, wlc->stf->ldpc); - - return 0; -} - -/* Initialize the base precedence map for dequeueing from txq based on WME settings */ -static void wlc_tx_prec_map_init(struct wlc_info *wlc) -{ - wlc->tx_prec_map = WLC_PREC_BMP_ALL; - memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16)); - - /* For non-WME, both fifos have overlapping MAXPRIO. So just disable all precedences - * if either is full. - */ - if (!EDCF_ENAB(wlc->pub)) { - wlc->fifo2prec_map[TX_DATA_FIFO] = WLC_PREC_BMP_ALL; - wlc->fifo2prec_map[TX_CTL_FIFO] = WLC_PREC_BMP_ALL; - } else { - wlc->fifo2prec_map[TX_AC_BK_FIFO] = WLC_PREC_BMP_AC_BK; - wlc->fifo2prec_map[TX_AC_BE_FIFO] = WLC_PREC_BMP_AC_BE; - wlc->fifo2prec_map[TX_AC_VI_FIFO] = WLC_PREC_BMP_AC_VI; - wlc->fifo2prec_map[TX_AC_VO_FIFO] = WLC_PREC_BMP_AC_VO; - } -} - -static uint wlc_down_del_timer(struct wlc_info *wlc) -{ - uint callbacks = 0; - - return callbacks; -} - -/* - * Mark the interface nonoperational, stop the software mechanisms, - * disable the hardware, free any transient buffer state. - * Return a count of the number of driver callbacks still pending. - */ -uint wlc_down(struct wlc_info *wlc) -{ - - uint callbacks = 0; - int i; - bool dev_gone = false; - wlc_txq_info_t *qi; - - WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__); - - /* check if we are already in the going down path */ - if (wlc->going_down) { - WL_ERROR("wl%d: %s: Driver going down so return\n", - wlc->pub->unit, __func__); - return 0; - } - if (!wlc->pub->up) - return callbacks; - - /* in between, mpc could try to bring down again.. */ - wlc->going_down = true; - - callbacks += wlc_bmac_down_prep(wlc->hw); - - dev_gone = DEVICEREMOVED(wlc); - - /* Call any registered down handlers */ - for (i = 0; i < WLC_MAXMODULES; i++) { - if (wlc->modulecb[i].down_fn) - callbacks += - wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl); - } - - /* cancel the watchdog timer */ - if (wlc->WDarmed) { - if (!wl_del_timer(wlc->wl, wlc->wdtimer)) - callbacks++; - wlc->WDarmed = false; - } - /* cancel all other timers */ - callbacks += wlc_down_del_timer(wlc); - - /* interrupt must have been blocked */ - ASSERT((wlc->macintmask == 0) || !wlc->pub->up); - - wlc->pub->up = false; - - wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL); - - /* clear txq flow control */ - wlc_txflowcontrol_reset(wlc); - - /* flush tx queues */ - for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { - pktq_flush(wlc->osh, &qi->q, true, NULL, 0); - ASSERT(pktq_empty(&qi->q)); - } - - /* flush event queue. - * Should be the last thing done after all the events are generated - * Just delivers the events synchronously instead of waiting for a timer - */ - callbacks += wlc_eventq_down(wlc->eventq); - - callbacks += wlc_bmac_down_finish(wlc->hw); - - /* wlc_bmac_down_finish has done wlc_coredisable(). so clk is off */ - wlc->clk = false; - - - /* Verify all packets are flushed from the driver */ - if (wlc->osh->pktalloced != 0) { - WL_ERROR("%d packets not freed at wlc_down!!!!!!\n", - wlc->osh->pktalloced); - } -#ifdef BCMDBG - /* Since all the packets should have been freed, - * all callbacks should have been called - */ - for (i = 1; i <= wlc->pub->tunables->maxpktcb; i++) - ASSERT(wlc->pkt_callback[i].fn == NULL); -#endif - wlc->going_down = false; - return callbacks; -} - -/* Set the current gmode configuration */ -int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) -{ - int ret = 0; - uint i; - wlc_rateset_t rs; - /* Default to 54g Auto */ - s8 shortslot = WLC_SHORTSLOT_AUTO; /* Advertise and use shortslot (-1/0/1 Auto/Off/On) */ - bool shortslot_restrict = false; /* Restrict association to stations that support shortslot - */ - bool ignore_bcns = true; /* Ignore legacy beacons on the same channel */ - bool ofdm_basic = false; /* Make 6, 12, and 24 basic rates */ - int preamble = WLC_PLCP_LONG; /* Advertise and use short preambles (-1/0/1 Auto/Off/On) */ - bool preamble_restrict = false; /* Restrict association to stations that support short - * preambles - */ - struct wlcband *band; - - /* if N-support is enabled, allow Gmode set as long as requested - * Gmode is not GMODE_LEGACY_B - */ - if (N_ENAB(wlc->pub) && gmode == GMODE_LEGACY_B) - return BCME_UNSUPPORTED; - - /* verify that we are dealing with 2G band and grab the band pointer */ - if (wlc->band->bandtype == WLC_BAND_2G) - band = wlc->band; - else if ((NBANDS(wlc) > 1) && - (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == WLC_BAND_2G)) - band = wlc->bandstate[OTHERBANDUNIT(wlc)]; - else - return BCME_BADBAND; - - /* Legacy or bust when no OFDM is supported by regulatory */ - if ((wlc_channel_locale_flags_in_band(wlc->cmi, band->bandunit) & - WLC_NO_OFDM) && (gmode != GMODE_LEGACY_B)) - return BCME_RANGE; - - /* update configuration value */ - if (config == true) - wlc_protection_upd(wlc, WLC_PROT_G_USER, gmode); - - /* Clear supported rates filter */ - memset(&wlc->sup_rates_override, 0, sizeof(wlc_rateset_t)); - - /* Clear rateset override */ - memset(&rs, 0, sizeof(wlc_rateset_t)); - - switch (gmode) { - case GMODE_LEGACY_B: - shortslot = WLC_SHORTSLOT_OFF; - wlc_rateset_copy(&gphy_legacy_rates, &rs); - - break; - - case GMODE_LRS: - if (AP_ENAB(wlc->pub)) - wlc_rateset_copy(&cck_rates, &wlc->sup_rates_override); - break; - - case GMODE_AUTO: - /* Accept defaults */ - break; - - case GMODE_ONLY: - ofdm_basic = true; - preamble = WLC_PLCP_SHORT; - preamble_restrict = true; - break; - - case GMODE_PERFORMANCE: - if (AP_ENAB(wlc->pub)) /* Put all rates into the Supported Rates element */ - wlc_rateset_copy(&cck_ofdm_rates, - &wlc->sup_rates_override); - - shortslot = WLC_SHORTSLOT_ON; - shortslot_restrict = true; - ofdm_basic = true; - preamble = WLC_PLCP_SHORT; - preamble_restrict = true; - break; - - default: - /* Error */ - WL_ERROR("wl%d: %s: invalid gmode %d\n", - wlc->pub->unit, __func__, gmode); - return BCME_UNSUPPORTED; - } - - /* - * If we are switching to gmode == GMODE_LEGACY_B, - * clean up rate info that may refer to OFDM rates. - */ - if ((gmode == GMODE_LEGACY_B) && (band->gmode != GMODE_LEGACY_B)) { - band->gmode = gmode; - if (band->rspec_override && !IS_CCK(band->rspec_override)) { - band->rspec_override = 0; - wlc_reprate_init(wlc); - } - if (band->mrspec_override && !IS_CCK(band->mrspec_override)) { - band->mrspec_override = 0; - } - } - - band->gmode = gmode; - - wlc->ignore_bcns = ignore_bcns; - - wlc->shortslot_override = shortslot; - - if (AP_ENAB(wlc->pub)) { - /* wlc->ap->shortslot_restrict = shortslot_restrict; */ - wlc->PLCPHdr_override = - (preamble != - WLC_PLCP_LONG) ? WLC_PLCP_SHORT : WLC_PLCP_AUTO; - } - - if ((AP_ENAB(wlc->pub) && preamble != WLC_PLCP_LONG) - || preamble == WLC_PLCP_SHORT) - wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE; - else - wlc->default_bss->capability &= ~WLAN_CAPABILITY_SHORT_PREAMBLE; - - /* Update shortslot capability bit for AP and IBSS */ - if ((AP_ENAB(wlc->pub) && shortslot == WLC_SHORTSLOT_AUTO) || - shortslot == WLC_SHORTSLOT_ON) - wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_SLOT_TIME; - else - wlc->default_bss->capability &= - ~WLAN_CAPABILITY_SHORT_SLOT_TIME; - - /* Use the default 11g rateset */ - if (!rs.count) - wlc_rateset_copy(&cck_ofdm_rates, &rs); - - if (ofdm_basic) { - for (i = 0; i < rs.count; i++) { - if (rs.rates[i] == WLC_RATE_6M - || rs.rates[i] == WLC_RATE_12M - || rs.rates[i] == WLC_RATE_24M) - rs.rates[i] |= WLC_RATE_FLAG; - } - } - - /* Set default bss rateset */ - wlc->default_bss->rateset.count = rs.count; - bcopy((char *)rs.rates, (char *)wlc->default_bss->rateset.rates, - sizeof(wlc->default_bss->rateset.rates)); - - return ret; -} - -static int wlc_nmode_validate(struct wlc_info *wlc, s32 nmode) -{ - int err = 0; - - switch (nmode) { - - case OFF: - break; - - case AUTO: - case WL_11N_2x2: - case WL_11N_3x3: - if (!(WLC_PHY_11N_CAP(wlc->band))) - err = BCME_BADBAND; - break; - - default: - err = BCME_RANGE; - break; - } - - return err; -} - -int wlc_set_nmode(struct wlc_info *wlc, s32 nmode) -{ - uint i; - int err; - - err = wlc_nmode_validate(wlc, nmode); - ASSERT(err == 0); - if (err) - return err; - - switch (nmode) { - case OFF: - wlc->pub->_n_enab = OFF; - wlc->default_bss->flags &= ~WLC_BSS_HT; - /* delete the mcs rates from the default and hw ratesets */ - wlc_rateset_mcs_clear(&wlc->default_bss->rateset); - for (i = 0; i < NBANDS(wlc); i++) { - memset(wlc->bandstate[i]->hw_rateset.mcs, 0, - MCSSET_LEN); - if (IS_MCS(wlc->band->rspec_override)) { - wlc->bandstate[i]->rspec_override = 0; - wlc_reprate_init(wlc); - } - if (IS_MCS(wlc->band->mrspec_override)) - wlc->bandstate[i]->mrspec_override = 0; - } - break; - - case AUTO: - if (wlc->stf->txstreams == WL_11N_3x3) - nmode = WL_11N_3x3; - else - nmode = WL_11N_2x2; - case WL_11N_2x2: - case WL_11N_3x3: - ASSERT(WLC_PHY_11N_CAP(wlc->band)); - /* force GMODE_AUTO if NMODE is ON */ - wlc_set_gmode(wlc, GMODE_AUTO, true); - if (nmode == WL_11N_3x3) - wlc->pub->_n_enab = SUPPORT_HT; - else - wlc->pub->_n_enab = SUPPORT_11N; - wlc->default_bss->flags |= WLC_BSS_HT; - /* add the mcs rates to the default and hw ratesets */ - wlc_rateset_mcs_build(&wlc->default_bss->rateset, - wlc->stf->txstreams); - for (i = 0; i < NBANDS(wlc); i++) - memcpy(wlc->bandstate[i]->hw_rateset.mcs, - wlc->default_bss->rateset.mcs, MCSSET_LEN); - break; - - default: - ASSERT(0); - break; - } - - return err; -} - -static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg) -{ - wlc_rateset_t rs, new; - uint bandunit; - - bcopy((char *)rs_arg, (char *)&rs, sizeof(wlc_rateset_t)); - - /* check for bad count value */ - if ((rs.count == 0) || (rs.count > WLC_NUMRATES)) - return BCME_BADRATESET; - - /* try the current band */ - bandunit = wlc->band->bandunit; - bcopy((char *)&rs, (char *)&new, sizeof(wlc_rateset_t)); - if (wlc_rate_hwrs_filter_sort_validate - (&new, &wlc->bandstate[bandunit]->hw_rateset, true, - wlc->stf->txstreams)) - goto good; - - /* try the other band */ - if (IS_MBAND_UNLOCKED(wlc)) { - bandunit = OTHERBANDUNIT(wlc); - bcopy((char *)&rs, (char *)&new, sizeof(wlc_rateset_t)); - if (wlc_rate_hwrs_filter_sort_validate(&new, - &wlc-> - bandstate[bandunit]-> - hw_rateset, true, - wlc->stf->txstreams)) - goto good; - } - - return BCME_ERROR; - - good: - /* apply new rateset */ - bcopy((char *)&new, (char *)&wlc->default_bss->rateset, - sizeof(wlc_rateset_t)); - bcopy((char *)&new, (char *)&wlc->bandstate[bandunit]->defrateset, - sizeof(wlc_rateset_t)); - return 0; -} - -/* simplified integer set interface for common ioctl handler */ -int wlc_set(struct wlc_info *wlc, int cmd, int arg) -{ - return wlc_ioctl(wlc, cmd, (void *)&arg, sizeof(arg), NULL); -} - -/* simplified integer get interface for common ioctl handler */ -int wlc_get(struct wlc_info *wlc, int cmd, int *arg) -{ - return wlc_ioctl(wlc, cmd, arg, sizeof(int), NULL); -} - -static void wlc_ofdm_rateset_war(struct wlc_info *wlc) -{ - u8 r; - bool war = false; - - if (wlc->cfg->associated) - r = wlc->cfg->current_bss->rateset.rates[0]; - else - r = wlc->default_bss->rateset.rates[0]; - - wlc_phy_ofdm_rateset_war(wlc->band->pi, war); - - return; -} - -int -wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, - struct wlc_if *wlcif) -{ - return _wlc_ioctl(wlc, cmd, arg, len, wlcif); -} - -/* common ioctl handler. return: 0=ok, -1=error, positive=particular error */ -static int -_wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, - struct wlc_if *wlcif) -{ - int val, *pval; - bool bool_val; - int bcmerror; - d11regs_t *regs; - uint i; - struct scb *nextscb; - bool ta_ok; - uint band; - rw_reg_t *r; - wlc_bsscfg_t *bsscfg; - struct osl_info *osh; - wlc_bss_info_t *current_bss; - - /* update bsscfg pointer */ - bsscfg = NULL; /* XXX: Hack bsscfg to be size one and use this globally */ - current_bss = NULL; - - /* initialize the following to get rid of compiler warning */ - nextscb = NULL; - ta_ok = false; - band = 0; - r = NULL; - - /* If the device is turned off, then it's not "removed" */ - if (!wlc->pub->hw_off && DEVICEREMOVED(wlc)) { - WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); - wl_down(wlc->wl); - return BCME_ERROR; - } - - ASSERT(!(wlc->pub->hw_off && wlc->pub->up)); - - /* default argument is generic integer */ - pval = arg ? (int *)arg:NULL; - - /* This will prevent the misaligned access */ - if (pval && (u32) len >= sizeof(val)) - bcopy(pval, &val, sizeof(val)); - else - val = 0; - - /* bool conversion to avoid duplication below */ - bool_val = val != 0; - - if (cmd != WLC_SET_CHANNEL) - WL_NONE("WLC_IOCTL: cmd %d val 0x%x (%d) len %d\n", - cmd, (uint)val, val, len); - - bcmerror = 0; - regs = wlc->regs; - osh = wlc->osh; - - /* A few commands don't need any arguments; all the others do. */ - switch (cmd) { - case WLC_UP: - case WLC_OUT: - case WLC_DOWN: - case WLC_DISASSOC: - case WLC_RESTART: - case WLC_REBOOT: - case WLC_START_CHANNEL_QA: - case WLC_INIT: - break; - - default: - if ((arg == NULL) || (len <= 0)) { - WL_ERROR("wl%d: %s: Command %d needs arguments\n", - wlc->pub->unit, __func__, cmd); - bcmerror = BCME_BADARG; - goto done; - } - } - - switch (cmd) { - -#if defined(BCMDBG) - case WLC_GET_MSGLEVEL: - *pval = wl_msg_level; - break; - - case WLC_SET_MSGLEVEL: - wl_msg_level = val; - break; -#endif - - case WLC_GET_INSTANCE: - *pval = wlc->pub->unit; - break; - - case WLC_GET_CHANNEL:{ - channel_info_t *ci = (channel_info_t *) arg; - - ASSERT(len > (int)sizeof(ci)); - - ci->hw_channel = - CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC); - ci->target_channel = - CHSPEC_CHANNEL(wlc->default_bss->chanspec); - ci->scan_channel = 0; - - break; - } - - case WLC_SET_CHANNEL:{ - chanspec_t chspec = CH20MHZ_CHSPEC(val); - - if (val < 0 || val > MAXCHANNEL) { - bcmerror = BCME_OUTOFRANGECHAN; - break; - } - - if (!wlc_valid_chanspec_db(wlc->cmi, chspec)) { - bcmerror = BCME_BADCHAN; - break; - } - - if (!wlc->pub->up && IS_MBAND_UNLOCKED(wlc)) { - if (wlc->band->bandunit != - CHSPEC_WLCBANDUNIT(chspec)) - wlc->bandinit_pending = true; - else - wlc->bandinit_pending = false; - } - - wlc->default_bss->chanspec = chspec; - /* wlc_BSSinit() will sanitize the rateset before using it.. */ - if (wlc->pub->up && !wlc->pub->associated && - (WLC_BAND_PI_RADIO_CHANSPEC != chspec)) { - wlc_set_home_chanspec(wlc, chspec); - wlc_suspend_mac_and_wait(wlc); - wlc_set_chanspec(wlc, chspec); - wlc_enable_mac(wlc); - } - break; - } - -#if defined(BCMDBG) - case WLC_GET_UCFLAGS: - if (!wlc->pub->up) { - bcmerror = BCME_NOTUP; - break; - } - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (val >= MHFMAX) { - bcmerror = BCME_RANGE; - break; - } - - *pval = wlc_bmac_mhf_get(wlc->hw, (u8) val, WLC_BAND_AUTO); - break; - - case WLC_SET_UCFLAGS: - if (!wlc->pub->up) { - bcmerror = BCME_NOTUP; - break; - } - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - i = (u16) val; - if (i >= MHFMAX) { - bcmerror = BCME_RANGE; - break; - } - - wlc_mhf(wlc, (u8) i, 0xffff, (u16) (val >> NBITS(u16)), - WLC_BAND_AUTO); - break; - - case WLC_GET_SHMEM: - ta_ok = true; - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (val & 1) { - bcmerror = BCME_BADADDR; - break; - } - - *pval = wlc_read_shm(wlc, (u16) val); - break; - - case WLC_SET_SHMEM: - ta_ok = true; - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (val & 1) { - bcmerror = BCME_BADADDR; - break; - } - - wlc_write_shm(wlc, (u16) val, - (u16) (val >> NBITS(u16))); - break; - - case WLC_R_REG: /* MAC registers */ - ta_ok = true; - r = (rw_reg_t *) arg; - band = WLC_BAND_AUTO; - - if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - if (len >= (int)sizeof(rw_reg_t)) - band = r->band; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if ((r->byteoff + r->size) > sizeof(d11regs_t)) { - bcmerror = BCME_BADADDR; - break; - } - if (r->size == sizeof(u32)) - r->val = - R_REG(osh, - (u32 *)((unsigned char *)(unsigned long)regs + - r->byteoff)); - else if (r->size == sizeof(u16)) - r->val = - R_REG(osh, - (u16 *)((unsigned char *)(unsigned long)regs + - r->byteoff)); - else - bcmerror = BCME_BADADDR; - break; - - case WLC_W_REG: - ta_ok = true; - r = (rw_reg_t *) arg; - band = WLC_BAND_AUTO; - - if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - if (len >= (int)sizeof(rw_reg_t)) - band = r->band; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (r->byteoff + r->size > sizeof(d11regs_t)) { - bcmerror = BCME_BADADDR; - break; - } - if (r->size == sizeof(u32)) - W_REG(osh, - (u32 *)((unsigned char *)(unsigned long) regs + - r->byteoff), r->val); - else if (r->size == sizeof(u16)) - W_REG(osh, - (u16 *)((unsigned char *)(unsigned long) regs + - r->byteoff), r->val); - else - bcmerror = BCME_BADADDR; - break; -#endif /* BCMDBG */ - - case WLC_GET_TXANT: - *pval = wlc->stf->txant; - break; - - case WLC_SET_TXANT: - bcmerror = wlc_stf_ant_txant_validate(wlc, (s8) val); - if (bcmerror < 0) - break; - - wlc->stf->txant = (s8) val; - - /* if down, we are done */ - if (!wlc->pub->up) - break; - - wlc_suspend_mac_and_wait(wlc); - - wlc_stf_phy_txant_upd(wlc); - wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec); - - wlc_enable_mac(wlc); - - break; - - case WLC_GET_ANTDIV:{ - u8 phy_antdiv; - - /* return configured value if core is down */ - if (!wlc->pub->up) { - *pval = wlc->stf->ant_rx_ovr; - - } else { - if (wlc_phy_ant_rxdiv_get - (wlc->band->pi, &phy_antdiv)) - *pval = (int)phy_antdiv; - else - *pval = (int)wlc->stf->ant_rx_ovr; - } - - break; - } - case WLC_SET_ANTDIV: - /* values are -1=driver default, 0=force0, 1=force1, 2=start1, 3=start0 */ - if ((val < -1) || (val > 3)) { - bcmerror = BCME_RANGE; - break; - } - - if (val == -1) - val = ANT_RX_DIV_DEF; - - wlc->stf->ant_rx_ovr = (u8) val; - wlc_phy_ant_rxdiv_set(wlc->band->pi, (u8) val); - break; - - case WLC_GET_RX_ANT:{ /* get latest used rx antenna */ - u16 rxstatus; - - if (!wlc->pub->up) { - bcmerror = BCME_NOTUP; - break; - } - - rxstatus = R_REG(wlc->osh, &wlc->regs->phyrxstatus0); - if (rxstatus == 0xdead || rxstatus == (u16) -1) { - bcmerror = BCME_ERROR; - break; - } - *pval = (rxstatus & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; - break; - } - -#if defined(BCMDBG) - case WLC_GET_UCANTDIV: - if (!wlc->clk) { - bcmerror = BCME_NOCLK; - break; - } - - *pval = - (wlc_bmac_mhf_get(wlc->hw, MHF1, WLC_BAND_AUTO) & - MHF1_ANTDIV); - break; - - case WLC_SET_UCANTDIV:{ - if (!wlc->pub->up) { - bcmerror = BCME_NOTUP; - break; - } - - /* if multiband, band must be locked */ - if (IS_MBAND_UNLOCKED(wlc)) { - bcmerror = BCME_NOTBANDLOCKED; - break; - } - - /* 4322 supports antdiv in phy, no need to set it to ucode */ - if (WLCISNPHY(wlc->band) - && D11REV_IS(wlc->pub->corerev, 16)) { - WL_ERROR("wl%d: can't set ucantdiv for 4322\n", - wlc->pub->unit); - bcmerror = BCME_UNSUPPORTED; - } else - wlc_mhf(wlc, MHF1, MHF1_ANTDIV, - (val ? MHF1_ANTDIV : 0), WLC_BAND_AUTO); - break; - } -#endif /* defined(BCMDBG) */ - - case WLC_GET_SRL: - *pval = wlc->SRL; - break; - - case WLC_SET_SRL: - if (val >= 1 && val <= RETRY_SHORT_MAX) { - int ac; - wlc->SRL = (u16) val; - - wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); - - for (ac = 0; ac < AC_COUNT; ac++) { - WLC_WME_RETRY_SHORT_SET(wlc, ac, wlc->SRL); - } - wlc_wme_retries_write(wlc); - } else - bcmerror = BCME_RANGE; - break; - - case WLC_GET_LRL: - *pval = wlc->LRL; - break; - - case WLC_SET_LRL: - if (val >= 1 && val <= 255) { - int ac; - wlc->LRL = (u16) val; - - wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); - - for (ac = 0; ac < AC_COUNT; ac++) { - WLC_WME_RETRY_LONG_SET(wlc, ac, wlc->LRL); - } - wlc_wme_retries_write(wlc); - } else - bcmerror = BCME_RANGE; - break; - - case WLC_GET_CWMIN: - *pval = wlc->band->CWmin; - break; - - case WLC_SET_CWMIN: - if (!wlc->clk) { - bcmerror = BCME_NOCLK; - break; - } - - if (val >= 1 && val <= 255) { - wlc_set_cwmin(wlc, (u16) val); - } else - bcmerror = BCME_RANGE; - break; - - case WLC_GET_CWMAX: - *pval = wlc->band->CWmax; - break; - - case WLC_SET_CWMAX: - if (!wlc->clk) { - bcmerror = BCME_NOCLK; - break; - } - - if (val >= 255 && val <= 2047) { - wlc_set_cwmax(wlc, (u16) val); - } else - bcmerror = BCME_RANGE; - break; - - case WLC_GET_RADIO: /* use mask if don't want to expose some internal bits */ - *pval = wlc->pub->radio_disabled; - break; - - case WLC_SET_RADIO:{ /* 32 bits input, higher 16 bits are mask, lower 16 bits are value to - * set - */ - u16 radiomask, radioval; - uint validbits = - WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE; - mbool new = 0; - - radiomask = (val & 0xffff0000) >> 16; - radioval = val & 0x0000ffff; - - if ((radiomask == 0) || (radiomask & ~validbits) - || (radioval & ~validbits) - || ((radioval & ~radiomask) != 0)) { - WL_ERROR("SET_RADIO with wrong bits 0x%x\n", - val); - bcmerror = BCME_RANGE; - break; - } - - new = - (wlc->pub->radio_disabled & ~radiomask) | radioval; - wlc->pub->radio_disabled = new; - - wlc_radio_hwdisable_upd(wlc); - wlc_radio_upd(wlc); - break; - } - - case WLC_GET_PHYTYPE: - *pval = WLC_PHYTYPE(wlc->band->phytype); - break; - -#if defined(BCMDBG) - case WLC_GET_KEY: - if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc))) { - wl_wsec_key_t key; - - wsec_key_t *src_key = wlc->wsec_keys[val]; - - if (len < (int)sizeof(key)) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - memset((char *)&key, 0, sizeof(key)); - if (src_key) { - key.index = src_key->id; - key.len = src_key->len; - bcopy(src_key->data, key.data, key.len); - key.algo = src_key->algo; - if (WSEC_SOFTKEY(wlc, src_key, bsscfg)) - key.flags |= WL_SOFT_KEY; - if (src_key->flags & WSEC_PRIMARY_KEY) - key.flags |= WL_PRIMARY_KEY; - - bcopy(src_key->ea, key.ea, - ETH_ALEN); - } - - bcopy((char *)&key, arg, sizeof(key)); - } else - bcmerror = BCME_BADKEYIDX; - break; -#endif /* defined(BCMDBG) */ - - case WLC_SET_KEY: - bcmerror = - wlc_iovar_op(wlc, "wsec_key", NULL, 0, arg, len, IOV_SET, - wlcif); - break; - - case WLC_GET_KEY_SEQ:{ - wsec_key_t *key; - - if (len < DOT11_WPA_KEY_RSC_LEN) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - /* Return the key's tx iv as an EAPOL sequence counter. - * This will be used to supply the RSC value to a supplicant. - * The format is 8 bytes, with least significant in seq[0]. - */ - - key = WSEC_KEY(wlc, val); - if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc)) && - (key != NULL)) { - u8 seq[DOT11_WPA_KEY_RSC_LEN]; - u16 lo; - u32 hi; - /* group keys in WPA-NONE (IBSS only, AES and TKIP) use a global TXIV */ - if ((bsscfg->WPA_auth & WPA_AUTH_NONE) && - is_zero_ether_addr(key->ea)) { - lo = bsscfg->wpa_none_txiv.lo; - hi = bsscfg->wpa_none_txiv.hi; - } else { - lo = key->txiv.lo; - hi = key->txiv.hi; - } - - /* format the buffer, low to high */ - seq[0] = lo & 0xff; - seq[1] = (lo >> 8) & 0xff; - seq[2] = hi & 0xff; - seq[3] = (hi >> 8) & 0xff; - seq[4] = (hi >> 16) & 0xff; - seq[5] = (hi >> 24) & 0xff; - seq[6] = 0; - seq[7] = 0; - - bcopy((char *)seq, arg, sizeof(seq)); - } else { - bcmerror = BCME_BADKEYIDX; - } - break; - } - - case WLC_GET_CURR_RATESET:{ - wl_rateset_t *ret_rs = (wl_rateset_t *) arg; - wlc_rateset_t *rs; - - if (bsscfg->associated) - rs = ¤t_bss->rateset; - else - rs = &wlc->default_bss->rateset; - - if (len < (int)(rs->count + sizeof(rs->count))) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - /* Copy only legacy rateset section */ - ret_rs->count = rs->count; - bcopy(&rs->rates, &ret_rs->rates, rs->count); - break; - } - - case WLC_GET_RATESET:{ - wlc_rateset_t rs; - wl_rateset_t *ret_rs = (wl_rateset_t *) arg; - - memset(&rs, 0, sizeof(wlc_rateset_t)); - wlc_default_rateset(wlc, (wlc_rateset_t *) &rs); - - if (len < (int)(rs.count + sizeof(rs.count))) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - /* Copy only legacy rateset section */ - ret_rs->count = rs.count; - bcopy(&rs.rates, &ret_rs->rates, rs.count); - break; - } - - case WLC_SET_RATESET:{ - wlc_rateset_t rs; - wl_rateset_t *in_rs = (wl_rateset_t *) arg; - - if (len < (int)(in_rs->count + sizeof(in_rs->count))) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - if (in_rs->count > WLC_NUMRATES) { - bcmerror = BCME_BUFTOOLONG; - break; - } - - memset(&rs, 0, sizeof(wlc_rateset_t)); - - /* Copy only legacy rateset section */ - rs.count = in_rs->count; - bcopy(&in_rs->rates, &rs.rates, rs.count); - - /* merge rateset coming in with the current mcsset */ - if (N_ENAB(wlc->pub)) { - if (bsscfg->associated) - bcopy(¤t_bss->rateset.mcs[0], - rs.mcs, MCSSET_LEN); - else - bcopy(&wlc->default_bss->rateset.mcs[0], - rs.mcs, MCSSET_LEN); - } - - bcmerror = wlc_set_rateset(wlc, &rs); - - if (!bcmerror) - wlc_ofdm_rateset_war(wlc); - - break; - } - - case WLC_GET_BCNPRD: - if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated) - *pval = current_bss->beacon_period; - else - *pval = wlc->default_bss->beacon_period; - break; - - case WLC_SET_BCNPRD: - /* range [1, 0xffff] */ - if (val >= DOT11_MIN_BEACON_PERIOD - && val <= DOT11_MAX_BEACON_PERIOD) { - wlc->default_bss->beacon_period = (u16) val; - } else - bcmerror = BCME_RANGE; - break; - - case WLC_GET_DTIMPRD: - if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated) - *pval = current_bss->dtim_period; - else - *pval = wlc->default_bss->dtim_period; - break; - - case WLC_SET_DTIMPRD: - /* range [1, 0xff] */ - if (val >= DOT11_MIN_DTIM_PERIOD - && val <= DOT11_MAX_DTIM_PERIOD) { - wlc->default_bss->dtim_period = (u8) val; - } else - bcmerror = BCME_RANGE; - break; - -#ifdef SUPPORT_PS - case WLC_GET_PM: - *pval = wlc->PM; - break; - - case WLC_SET_PM: - if ((val >= PM_OFF) && (val <= PM_MAX)) { - wlc->PM = (u8) val; - if (wlc->pub->up) { - } - /* Change watchdog driver to align watchdog with tbtt if possible */ - wlc_watchdog_upd(wlc, PS_ALLOWED(wlc)); - } else - bcmerror = BCME_ERROR; - break; -#endif /* SUPPORT_PS */ - -#ifdef SUPPORT_PS -#ifdef BCMDBG - case WLC_GET_WAKE: - if (AP_ENAB(wlc->pub)) { - bcmerror = BCME_NOTSTA; - break; - } - *pval = wlc->wake; - break; - - case WLC_SET_WAKE: - if (AP_ENAB(wlc->pub)) { - bcmerror = BCME_NOTSTA; - break; - } - - wlc->wake = val ? true : false; - - /* if down, we're done */ - if (!wlc->pub->up) - break; - - /* apply to the mac */ - wlc_set_ps_ctrl(wlc); - break; -#endif /* BCMDBG */ -#endif /* SUPPORT_PS */ - - case WLC_GET_REVINFO: - bcmerror = wlc_get_revision_info(wlc, arg, (uint) len); - break; - - case WLC_GET_AP: - *pval = (int)AP_ENAB(wlc->pub); - break; - - case WLC_GET_ATIM: - if (bsscfg->associated) - *pval = (int)current_bss->atim_window; - else - *pval = (int)wlc->default_bss->atim_window; - break; - - case WLC_SET_ATIM: - wlc->default_bss->atim_window = (u32) val; - break; - - case WLC_GET_PKTCNTS:{ - get_pktcnt_t *pktcnt = (get_pktcnt_t *) pval; - if (WLC_UPDATE_STATS(wlc)) - wlc_statsupd(wlc); - pktcnt->rx_good_pkt = WLCNTVAL(wlc->pub->_cnt->rxframe); - pktcnt->rx_bad_pkt = WLCNTVAL(wlc->pub->_cnt->rxerror); - pktcnt->tx_good_pkt = - WLCNTVAL(wlc->pub->_cnt->txfrmsnt); - pktcnt->tx_bad_pkt = - WLCNTVAL(wlc->pub->_cnt->txerror) + - WLCNTVAL(wlc->pub->_cnt->txfail); - if (len >= (int)sizeof(get_pktcnt_t)) { - /* Be backward compatible - only if buffer is large enough */ - pktcnt->rx_ocast_good_pkt = - WLCNTVAL(wlc->pub->_cnt->rxmfrmocast); - } - break; - } - -#ifdef SUPPORT_HWKEY - case WLC_GET_WSEC: - bcmerror = - wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_GET, - wlcif); - break; - - case WLC_SET_WSEC: - bcmerror = - wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_SET, - wlcif); - break; - - case WLC_GET_WPA_AUTH: - *pval = (int)bsscfg->WPA_auth; - break; - - case WLC_SET_WPA_AUTH: - /* change of WPA_Auth modifies the PS_ALLOWED state */ - if (BSSCFG_STA(bsscfg)) { - bsscfg->WPA_auth = (u16) val; - } else - bsscfg->WPA_auth = (u16) val; - break; -#endif /* SUPPORT_HWKEY */ - - case WLC_GET_BANDLIST: - /* count of number of bands, followed by each band type */ - *pval++ = NBANDS(wlc); - *pval++ = wlc->band->bandtype; - if (NBANDS(wlc) > 1) - *pval++ = wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype; - break; - - case WLC_GET_BAND: - *pval = wlc->bandlocked ? wlc->band->bandtype : WLC_BAND_AUTO; - break; - - case WLC_GET_PHYLIST: - { - unsigned char *cp = arg; - if (len < 3) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - if (WLCISNPHY(wlc->band)) { - *cp++ = 'n'; - } else if (WLCISLCNPHY(wlc->band)) { - *cp++ = 'c'; - } else if (WLCISSSLPNPHY(wlc->band)) { - *cp++ = 's'; - } - *cp = '\0'; - break; - } - - case WLC_GET_SHORTSLOT: - *pval = wlc->shortslot; - break; - - case WLC_GET_SHORTSLOT_OVERRIDE: - *pval = wlc->shortslot_override; - break; - - case WLC_SET_SHORTSLOT_OVERRIDE: - if ((val != WLC_SHORTSLOT_AUTO) && - (val != WLC_SHORTSLOT_OFF) && (val != WLC_SHORTSLOT_ON)) { - bcmerror = BCME_RANGE; - break; - } - - wlc->shortslot_override = (s8) val; - - /* shortslot is an 11g feature, so no more work if we are - * currently on the 5G band - */ - if (BAND_5G(wlc->band->bandtype)) - break; - - if (wlc->pub->up && wlc->pub->associated) { - /* let watchdog or beacon processing update shortslot */ - } else if (wlc->pub->up) { - /* unassociated shortslot is off */ - wlc_switch_shortslot(wlc, false); - } else { - /* driver is down, so just update the wlc_info value */ - if (wlc->shortslot_override == WLC_SHORTSLOT_AUTO) { - wlc->shortslot = false; - } else { - wlc->shortslot = - (wlc->shortslot_override == - WLC_SHORTSLOT_ON); - } - } - - break; - - case WLC_GET_LEGACY_ERP: - *pval = wlc->include_legacy_erp; - break; - - case WLC_SET_LEGACY_ERP: - if (wlc->include_legacy_erp == bool_val) - break; - - wlc->include_legacy_erp = bool_val; - - if (AP_ENAB(wlc->pub) && wlc->clk) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - } - break; - - case WLC_GET_GMODE: - if (wlc->band->bandtype == WLC_BAND_2G) - *pval = wlc->band->gmode; - else if (NBANDS(wlc) > 1) - *pval = wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode; - break; - - case WLC_SET_GMODE: - if (!wlc->pub->associated) - bcmerror = wlc_set_gmode(wlc, (u8) val, true); - else { - bcmerror = BCME_ASSOCIATED; - break; - } - break; - - case WLC_GET_GMODE_PROTECTION: - *pval = wlc->protection->_g; - break; - - case WLC_GET_PROTECTION_CONTROL: - *pval = wlc->protection->overlap; - break; - - case WLC_SET_PROTECTION_CONTROL: - if ((val != WLC_PROTECTION_CTL_OFF) && - (val != WLC_PROTECTION_CTL_LOCAL) && - (val != WLC_PROTECTION_CTL_OVERLAP)) { - bcmerror = BCME_RANGE; - break; - } - - wlc_protection_upd(wlc, WLC_PROT_OVERLAP, (s8) val); - - /* Current g_protection will sync up to the specified control alg in watchdog - * if the driver is up and associated. - * If the driver is down or not associated, the control setting has no effect. - */ - break; - - case WLC_GET_GMODE_PROTECTION_OVERRIDE: - *pval = wlc->protection->g_override; - break; - - case WLC_SET_GMODE_PROTECTION_OVERRIDE: - if ((val != WLC_PROTECTION_AUTO) && - (val != WLC_PROTECTION_OFF) && (val != WLC_PROTECTION_ON)) { - bcmerror = BCME_RANGE; - break; - } - - wlc_protection_upd(wlc, WLC_PROT_G_OVR, (s8) val); - - break; - - case WLC_SET_SUP_RATESET_OVERRIDE:{ - wlc_rateset_t rs, new; - - /* copyin */ - if (len < (int)sizeof(wlc_rateset_t)) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - bcopy((char *)arg, (char *)&rs, sizeof(wlc_rateset_t)); - - /* check for bad count value */ - if (rs.count > WLC_NUMRATES) { - bcmerror = BCME_BADRATESET; /* invalid rateset */ - break; - } - - /* this command is only appropriate for gmode operation */ - if (!(wlc->band->gmode || - ((NBANDS(wlc) > 1) - && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) { - bcmerror = BCME_BADBAND; /* gmode only command when not in gmode */ - break; - } - - /* check for an empty rateset to clear the override */ - if (rs.count == 0) { - memset(&wlc->sup_rates_override, 0, - sizeof(wlc_rateset_t)); - break; - } - - /* validate rateset by comparing pre and post sorted against 11g hw rates */ - wlc_rateset_filter(&rs, &new, false, WLC_RATES_CCK_OFDM, - RATE_MASK, BSS_N_ENAB(wlc, bsscfg)); - wlc_rate_hwrs_filter_sort_validate(&new, - &cck_ofdm_rates, - false, - wlc->stf->txstreams); - if (rs.count != new.count) { - bcmerror = BCME_BADRATESET; /* invalid rateset */ - break; - } - - /* apply new rateset to the override */ - bcopy((char *)&new, (char *)&wlc->sup_rates_override, - sizeof(wlc_rateset_t)); - - /* update bcn and probe resp if needed */ - if (wlc->pub->up && AP_ENAB(wlc->pub) - && wlc->pub->associated) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - } - break; - } - - case WLC_GET_SUP_RATESET_OVERRIDE: - /* this command is only appropriate for gmode operation */ - if (!(wlc->band->gmode || - ((NBANDS(wlc) > 1) - && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) { - bcmerror = BCME_BADBAND; /* gmode only command when not in gmode */ - break; - } - if (len < (int)sizeof(wlc_rateset_t)) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - bcopy((char *)&wlc->sup_rates_override, (char *)arg, - sizeof(wlc_rateset_t)); - - break; - - case WLC_GET_PRB_RESP_TIMEOUT: - *pval = wlc->prb_resp_timeout; - break; - - case WLC_SET_PRB_RESP_TIMEOUT: - if (wlc->pub->up) { - bcmerror = BCME_NOTDOWN; - break; - } - if (val < 0 || val >= 0xFFFF) { - bcmerror = BCME_RANGE; /* bad value */ - break; - } - wlc->prb_resp_timeout = (u16) val; - break; - - case WLC_GET_KEY_PRIMARY:{ - wsec_key_t *key; - - /* treat the 'val' parm as the key id */ - key = WSEC_BSS_DEFAULT_KEY(bsscfg); - if (key != NULL) { - *pval = key->id == val ? true : false; - } else { - bcmerror = BCME_BADKEYIDX; - } - break; - } - - case WLC_SET_KEY_PRIMARY:{ - wsec_key_t *key, *old_key; - - bcmerror = BCME_BADKEYIDX; - - /* treat the 'val' parm as the key id */ - for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) { - key = bsscfg->bss_def_keys[i]; - if (key != NULL && key->id == val) { - old_key = WSEC_BSS_DEFAULT_KEY(bsscfg); - if (old_key != NULL) - old_key->flags &= - ~WSEC_PRIMARY_KEY; - key->flags |= WSEC_PRIMARY_KEY; - bsscfg->wsec_index = i; - bcmerror = BCME_OK; - } - } - break; - } - -#ifdef BCMDBG - case WLC_INIT: - wl_init(wlc->wl); - break; -#endif - - case WLC_SET_VAR: - case WLC_GET_VAR:{ - char *name; - /* validate the name value */ - name = (char *)arg; - for (i = 0; i < (uint) len && *name != '\0'; - i++, name++) - ; - - if (i == (uint) len) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - i++; /* include the null in the string length */ - - if (cmd == WLC_GET_VAR) { - bcmerror = - wlc_iovar_op(wlc, arg, - (void *)((s8 *) arg + i), - len - i, arg, len, IOV_GET, - wlcif); - } else - bcmerror = - wlc_iovar_op(wlc, arg, NULL, 0, - (void *)((s8 *) arg + i), - len - i, IOV_SET, wlcif); - - break; - } - - case WLC_SET_WSEC_PMK: - bcmerror = BCME_UNSUPPORTED; - break; - -#if defined(BCMDBG) - case WLC_CURRENT_PWR: - if (!wlc->pub->up) - bcmerror = BCME_NOTUP; - else - bcmerror = wlc_get_current_txpwr(wlc, arg, len); - break; -#endif - - case WLC_LAST: - WL_ERROR("%s: WLC_LAST\n", __func__); - } - done: - - if (bcmerror) { - if (VALID_BCMERROR(bcmerror)) - wlc->pub->bcmerror = bcmerror; - else { - bcmerror = 0; - } - - } - /* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */ - /* In hw_off condition, IOCTLs that reach here are deemed safe but taclear would - * certainly result in getting -1 for register reads. So skip ta_clear altogether - */ - if (!(wlc->pub->hw_off)) - ASSERT(wlc_bmac_taclear(wlc->hw, ta_ok) || !ta_ok); - - return bcmerror; -} - -#if defined(BCMDBG) -/* consolidated register access ioctl error checking */ -int wlc_iocregchk(struct wlc_info *wlc, uint band) -{ - /* if band is specified, it must be the current band */ - if ((band != WLC_BAND_AUTO) && (band != (uint) wlc->band->bandtype)) - return BCME_BADBAND; - - /* if multiband and band is not specified, band must be locked */ - if ((band == WLC_BAND_AUTO) && IS_MBAND_UNLOCKED(wlc)) - return BCME_NOTBANDLOCKED; - - /* must have core clocks */ - if (!wlc->clk) - return BCME_NOCLK; - - return 0; -} -#endif /* defined(BCMDBG) */ - -#if defined(BCMDBG) -/* For some ioctls, make sure that the pi pointer matches the current phy */ -int wlc_iocpichk(struct wlc_info *wlc, uint phytype) -{ - if (wlc->band->phytype != phytype) - return BCME_BADBAND; - return 0; -} -#endif - -/* Look up the given var name in the given table */ -static const bcm_iovar_t *wlc_iovar_lookup(const bcm_iovar_t *table, - const char *name) -{ - const bcm_iovar_t *vi; - const char *lookup_name; - - /* skip any ':' delimited option prefixes */ - lookup_name = strrchr(name, ':'); - if (lookup_name != NULL) - lookup_name++; - else - lookup_name = name; - - ASSERT(table != NULL); - - for (vi = table; vi->name; vi++) { - if (!strcmp(vi->name, lookup_name)) - return vi; - } - /* ran to end of table */ - - return NULL; /* var name not found */ -} - -/* simplified integer get interface for common WLC_GET_VAR ioctl handler */ -int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg) -{ - return wlc_iovar_op(wlc, name, NULL, 0, arg, sizeof(s32), IOV_GET, - NULL); -} - -/* simplified integer set interface for common WLC_SET_VAR ioctl handler */ -int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg) -{ - return wlc_iovar_op(wlc, name, NULL, 0, (void *)&arg, sizeof(arg), - IOV_SET, NULL); -} - -/* simplified s8 get interface for common WLC_GET_VAR ioctl handler */ -int wlc_iovar_gets8(struct wlc_info *wlc, const char *name, s8 *arg) -{ - int iovar_int; - int err; - - err = - wlc_iovar_op(wlc, name, NULL, 0, &iovar_int, sizeof(iovar_int), - IOV_GET, NULL); - if (!err) - *arg = (s8) iovar_int; - - return err; -} - -/* - * register iovar table, watchdog and down handlers. - * calling function must keep 'iovars' until wlc_module_unregister is called. - * 'iovar' must have the last entry's name field being NULL as terminator. - */ -int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, - const char *name, void *hdl, iovar_fn_t i_fn, - watchdog_fn_t w_fn, down_fn_t d_fn) -{ - struct wlc_info *wlc = (struct wlc_info *) pub->wlc; - int i; - - ASSERT(name != NULL); - ASSERT(i_fn != NULL || w_fn != NULL || d_fn != NULL); - - /* find an empty entry and just add, no duplication check! */ - for (i = 0; i < WLC_MAXMODULES; i++) { - if (wlc->modulecb[i].name[0] == '\0') { - strncpy(wlc->modulecb[i].name, name, - sizeof(wlc->modulecb[i].name) - 1); - wlc->modulecb[i].iovars = iovars; - wlc->modulecb[i].hdl = hdl; - wlc->modulecb[i].iovar_fn = i_fn; - wlc->modulecb[i].watchdog_fn = w_fn; - wlc->modulecb[i].down_fn = d_fn; - return 0; - } - } - - /* it is time to increase the capacity */ - ASSERT(i < WLC_MAXMODULES); - return BCME_NORESOURCE; -} - -/* unregister module callbacks */ -int wlc_module_unregister(struct wlc_pub *pub, const char *name, void *hdl) -{ - struct wlc_info *wlc = (struct wlc_info *) pub->wlc; - int i; - - if (wlc == NULL) - return BCME_NOTFOUND; - - ASSERT(name != NULL); - - for (i = 0; i < WLC_MAXMODULES; i++) { - if (!strcmp(wlc->modulecb[i].name, name) && - (wlc->modulecb[i].hdl == hdl)) { - memset(&wlc->modulecb[i], 0, sizeof(modulecb_t)); - return 0; - } - } - - /* table not found! */ - return BCME_NOTFOUND; -} - -/* Write WME tunable parameters for retransmit/max rate from wlc struct to ucode */ -static void wlc_wme_retries_write(struct wlc_info *wlc) -{ - int ac; - - /* Need clock to do this */ - if (!wlc->clk) - return; - - for (ac = 0; ac < AC_COUNT; ac++) { - wlc_write_shm(wlc, M_AC_TXLMT_ADDR(ac), wlc->wme_retries[ac]); - } -} - -/* Get or set an iovar. The params/p_len pair specifies any additional - * qualifying parameters (e.g. an "element index") for a get, while the - * arg/len pair is the buffer for the value to be set or retrieved. - * Operation (get/set) is specified by the last argument. - * interface context provided by wlcif - * - * All pointers may point into the same buffer. - */ -int -wlc_iovar_op(struct wlc_info *wlc, const char *name, - void *params, int p_len, void *arg, int len, - bool set, struct wlc_if *wlcif) -{ - int err = 0; - int val_size; - const bcm_iovar_t *vi = NULL; - u32 actionid; - int i; - - ASSERT(name != NULL); - - ASSERT(len >= 0); - - /* Get MUST have return space */ - ASSERT(set || (arg && len)); - - ASSERT(!(wlc->pub->hw_off && wlc->pub->up)); - - /* Set does NOT take qualifiers */ - ASSERT(!set || (!params && !p_len)); - - if (!set && (len == sizeof(int)) && - !(IS_ALIGNED((unsigned long)(arg), (uint) sizeof(int)))) { - WL_ERROR("wl%d: %s unaligned get ptr for %s\n", - wlc->pub->unit, __func__, name); - ASSERT(0); - } - - /* find the given iovar name */ - for (i = 0; i < WLC_MAXMODULES; i++) { - if (!wlc->modulecb[i].iovars) - continue; - vi = wlc_iovar_lookup(wlc->modulecb[i].iovars, name); - if (vi) - break; - } - /* iovar name not found */ - if (i >= WLC_MAXMODULES) { - err = BCME_UNSUPPORTED; - goto exit; - } - - /* set up 'params' pointer in case this is a set command so that - * the convenience int and bool code can be common to set and get - */ - if (params == NULL) { - params = arg; - p_len = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - /* all other types are integer sized */ - val_size = sizeof(int); - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - - /* Do the actual parameter implementation */ - err = wlc->modulecb[i].iovar_fn(wlc->modulecb[i].hdl, vi, actionid, - name, params, p_len, arg, len, val_size, - wlcif); - - exit: - return err; -} - -int -wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, void *arg, int len, - bool set) -{ - struct wlc_info *wlc = (struct wlc_info *) pub->wlc; - int err = 0; - s32 int_val = 0; - - /* check generic condition flags */ - if (set) { - if (((vi->flags & IOVF_SET_DOWN) && wlc->pub->up) || - ((vi->flags & IOVF_SET_UP) && !wlc->pub->up)) { - err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP); - } else if ((vi->flags & IOVF_SET_BAND) - && IS_MBAND_UNLOCKED(wlc)) { - err = BCME_NOTBANDLOCKED; - } else if ((vi->flags & IOVF_SET_CLK) && !wlc->clk) { - err = BCME_NOCLK; - } - } else { - if (((vi->flags & IOVF_GET_DOWN) && wlc->pub->up) || - ((vi->flags & IOVF_GET_UP) && !wlc->pub->up)) { - err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP); - } else if ((vi->flags & IOVF_GET_BAND) - && IS_MBAND_UNLOCKED(wlc)) { - err = BCME_NOTBANDLOCKED; - } else if ((vi->flags & IOVF_GET_CLK) && !wlc->clk) { - err = BCME_NOCLK; - } - } - - if (err) - goto exit; - - /* length check on io buf */ - err = bcm_iovar_lencheck(vi, arg, len, set); - if (err) - goto exit; - - /* On set, check value ranges for integer types */ - if (set) { - switch (vi->type) { - case IOVT_BOOL: - case IOVT_INT8: - case IOVT_INT16: - case IOVT_INT32: - case IOVT_UINT8: - case IOVT_UINT16: - case IOVT_UINT32: - bcopy(arg, &int_val, sizeof(int)); - err = wlc_iovar_rangecheck(wlc, int_val, vi); - break; - } - } - exit: - return err; -} - -/* handler for iovar table wlc_iovars */ -/* - * IMPLEMENTATION NOTE: In order to avoid checking for get/set in each - * iovar case, the switch statement maps the iovar id into separate get - * and set values. If you add a new iovar to the switch you MUST use - * IOV_GVAL and/or IOV_SVAL in the case labels to avoid conflict with - * another case. - * Please use params for additional qualifying parameters. - */ -int -wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, - const char *name, void *params, uint p_len, void *arg, int len, - int val_size, struct wlc_if *wlcif) -{ - struct wlc_info *wlc = hdl; - wlc_bsscfg_t *bsscfg; - int err = 0; - s32 int_val = 0; - s32 int_val2 = 0; - s32 *ret_int_ptr; - bool bool_val; - bool bool_val2; - wlc_bss_info_t *current_bss; - - WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__); - - bsscfg = NULL; - current_bss = NULL; - - err = wlc_iovar_check(wlc->pub, vi, arg, len, IOV_ISSET(actionid)); - if (err != 0) - return err; - - /* convenience int and bool vals for first 8 bytes of buffer */ - if (p_len >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); - - if (p_len >= (int)sizeof(int_val) * 2) - bcopy((void *)((unsigned long)params + sizeof(int_val)), &int_val2, - sizeof(int_val)); - - /* convenience int ptr for 4-byte gets (requires int aligned arg) */ - ret_int_ptr = (s32 *) arg; - - bool_val = (int_val != 0) ? true : false; - bool_val2 = (int_val2 != 0) ? true : false; - - WL_TRACE("wl%d: %s: id %d\n", - wlc->pub->unit, __func__, IOV_ID(actionid)); - /* Do the actual parameter implementation */ - switch (actionid) { - - case IOV_GVAL(IOV_QTXPOWER):{ - uint qdbm; - bool override; - - err = wlc_phy_txpower_get(wlc->band->pi, &qdbm, - &override); - if (err != BCME_OK) - return err; - - /* Return qdbm units */ - *ret_int_ptr = - qdbm | (override ? WL_TXPWR_OVERRIDE : 0); - break; - } - - /* As long as override is false, this only sets the *user* targets. - User can twiddle this all he wants with no harm. - wlc_phy_txpower_set() explicitly sets override to false if - not internal or test. - */ - case IOV_SVAL(IOV_QTXPOWER):{ - u8 qdbm; - bool override; - - /* Remove override bit and clip to max qdbm value */ - qdbm = (u8)min_t(u32, (int_val & ~WL_TXPWR_OVERRIDE), 0xff); - /* Extract override setting */ - override = (int_val & WL_TXPWR_OVERRIDE) ? true : false; - err = - wlc_phy_txpower_set(wlc->band->pi, qdbm, override); - break; - } - - case IOV_GVAL(IOV_MPC): - *ret_int_ptr = (s32) wlc->mpc; - break; - - case IOV_SVAL(IOV_MPC): - wlc->mpc = bool_val; - wlc_radio_mpc_upd(wlc); - - break; - - case IOV_GVAL(IOV_BCN_LI_BCN): - *ret_int_ptr = wlc->bcn_li_bcn; - break; - - case IOV_SVAL(IOV_BCN_LI_BCN): - wlc->bcn_li_bcn = (u8) int_val; - if (wlc->pub->up) - wlc_bcn_li_upd(wlc); - break; - - default: - WL_ERROR("wl%d: %s: unsupported\n", wlc->pub->unit, __func__); - err = BCME_UNSUPPORTED; - break; - } - - goto exit; /* avoid unused label warning */ - - exit: - return err; -} - -static int -wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, const bcm_iovar_t *vi) -{ - int err = 0; - u32 min_val = 0; - u32 max_val = 0; - - /* Only ranged integers are checked */ - switch (vi->type) { - case IOVT_INT32: - max_val |= 0x7fffffff; - /* fall through */ - case IOVT_INT16: - max_val |= 0x00007fff; - /* fall through */ - case IOVT_INT8: - max_val |= 0x0000007f; - min_val = ~max_val; - if (vi->flags & IOVF_NTRL) - min_val = 1; - else if (vi->flags & IOVF_WHL) - min_val = 0; - /* Signed values are checked against max_val and min_val */ - if ((s32) val < (s32) min_val - || (s32) val > (s32) max_val) - err = BCME_RANGE; - break; - - case IOVT_UINT32: - max_val |= 0xffffffff; - /* fall through */ - case IOVT_UINT16: - max_val |= 0x0000ffff; - /* fall through */ - case IOVT_UINT8: - max_val |= 0x000000ff; - if (vi->flags & IOVF_NTRL) - min_val = 1; - if ((val < min_val) || (val > max_val)) - err = BCME_RANGE; - break; - } - - return err; -} - -#ifdef BCMDBG -static const char *supr_reason[] = { - "None", "PMQ Entry", "Flush request", - "Previous frag failure", "Channel mismatch", - "Lifetime Expiry", "Underflow" -}; - -static void wlc_print_txs_status(u16 s) -{ - printf("[15:12] %d frame attempts\n", (s & TX_STATUS_FRM_RTX_MASK) >> - TX_STATUS_FRM_RTX_SHIFT); - printf(" [11:8] %d rts attempts\n", (s & TX_STATUS_RTS_RTX_MASK) >> - TX_STATUS_RTS_RTX_SHIFT); - printf(" [7] %d PM mode indicated\n", - ((s & TX_STATUS_PMINDCTD) ? 1 : 0)); - printf(" [6] %d intermediate status\n", - ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0)); - printf(" [5] %d AMPDU\n", (s & TX_STATUS_AMPDU) ? 1 : 0); - printf(" [4:2] %d Frame Suppressed Reason (%s)\n", - ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT), - supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]); - printf(" [1] %d acked\n", ((s & TX_STATUS_ACK_RCV) ? 1 : 0)); -} -#endif /* BCMDBG */ - -void wlc_print_txstatus(tx_status_t *txs) -{ -#if defined(BCMDBG) - u16 s = txs->status; - u16 ackphyrxsh = txs->ackphyrxsh; - - printf("\ntxpkt (MPDU) Complete\n"); - - printf("FrameID: %04x ", txs->frameid); - printf("TxStatus: %04x", s); - printf("\n"); -#ifdef BCMDBG - wlc_print_txs_status(s); -#endif - printf("LastTxTime: %04x ", txs->lasttxtime); - printf("Seq: %04x ", txs->sequence); - printf("PHYTxStatus: %04x ", txs->phyerr); - printf("RxAckRSSI: %04x ", - (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT); - printf("RxAckSQ: %04x", (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); - printf("\n"); -#endif /* defined(BCMDBG) */ -} - -#define MACSTATUPD(name) \ - wlc_ctrupd_cache(macstats.name, &wlc->core->macstat_snapshot->name, &wlc->pub->_cnt->name) - -void wlc_statsupd(struct wlc_info *wlc) -{ - int i; -#ifdef BCMDBG - u16 delta; - u16 rxf0ovfl; - u16 txfunfl[NFIFO]; -#endif /* BCMDBG */ - - /* if driver down, make no sense to update stats */ - if (!wlc->pub->up) - return; - -#ifdef BCMDBG - /* save last rx fifo 0 overflow count */ - rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl; - - /* save last tx fifo underflow count */ - for (i = 0; i < NFIFO; i++) - txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i]; -#endif /* BCMDBG */ - -#ifdef BCMDBG - /* check for rx fifo 0 overflow */ - delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); - if (delta) - WL_ERROR("wl%d: %u rx fifo 0 overflows!\n", - wlc->pub->unit, delta); - - /* check for tx fifo underflows */ - for (i = 0; i < NFIFO; i++) { - delta = - (u16) (wlc->core->macstat_snapshot->txfunfl[i] - - txfunfl[i]); - if (delta) - WL_ERROR("wl%d: %u tx fifo %d underflows!\n", - wlc->pub->unit, delta, i); - } -#endif /* BCMDBG */ - - /* dot11 counter update */ - - WLCNTSET(wlc->pub->_cnt->txrts, - (wlc->pub->_cnt->rxctsucast - - wlc->pub->_cnt->d11cnt_txrts_off)); - WLCNTSET(wlc->pub->_cnt->rxcrc, - (wlc->pub->_cnt->rxbadfcs - wlc->pub->_cnt->d11cnt_rxcrc_off)); - WLCNTSET(wlc->pub->_cnt->txnocts, - ((wlc->pub->_cnt->txrtsfrm - wlc->pub->_cnt->rxctsucast) - - wlc->pub->_cnt->d11cnt_txnocts_off)); - - /* merge counters from dma module */ - for (i = 0; i < NFIFO; i++) { - if (wlc->hw->di[i]) { - WLCNTADD(wlc->pub->_cnt->txnobuf, - (wlc->hw->di[i])->txnobuf); - WLCNTADD(wlc->pub->_cnt->rxnobuf, - (wlc->hw->di[i])->rxnobuf); - WLCNTADD(wlc->pub->_cnt->rxgiant, - (wlc->hw->di[i])->rxgiants); - dma_counterreset(wlc->hw->di[i]); - } - } - - /* - * Aggregate transmit and receive errors that probably resulted - * in the loss of a frame are computed on the fly. - */ - WLCNTSET(wlc->pub->_cnt->txerror, - wlc->pub->_cnt->txnobuf + wlc->pub->_cnt->txnoassoc + - wlc->pub->_cnt->txuflo + wlc->pub->_cnt->txrunt + - wlc->pub->_cnt->dmade + wlc->pub->_cnt->dmada + - wlc->pub->_cnt->dmape); - WLCNTSET(wlc->pub->_cnt->rxerror, - wlc->pub->_cnt->rxoflo + wlc->pub->_cnt->rxnobuf + - wlc->pub->_cnt->rxfragerr + wlc->pub->_cnt->rxrunt + - wlc->pub->_cnt->rxgiant + wlc->pub->_cnt->rxnoscb + - wlc->pub->_cnt->rxbadsrcmac); - for (i = 0; i < NFIFO; i++) - WLCNTADD(wlc->pub->_cnt->rxerror, wlc->pub->_cnt->rxuflo[i]); -} - -bool wlc_chipmatch(u16 vendor, u16 device) -{ - if (vendor != VENDOR_BROADCOM) { - WL_ERROR("wlc_chipmatch: unknown vendor id %04x\n", vendor); - return false; - } - - if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID)) - return true; - - if (device == BCM4313_D11N2G_ID) - return true; - if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID)) - return true; - - WL_ERROR("wlc_chipmatch: unknown device id %04x\n", device); - return false; -} - -#if defined(BCMDBG) -void wlc_print_txdesc(d11txh_t *txh) -{ - u16 mtcl = ltoh16(txh->MacTxControlLow); - u16 mtch = ltoh16(txh->MacTxControlHigh); - u16 mfc = ltoh16(txh->MacFrameControl); - u16 tfest = ltoh16(txh->TxFesTimeNormal); - u16 ptcw = ltoh16(txh->PhyTxControlWord); - u16 ptcw_1 = ltoh16(txh->PhyTxControlWord_1); - u16 ptcw_1_Fbr = ltoh16(txh->PhyTxControlWord_1_Fbr); - u16 ptcw_1_Rts = ltoh16(txh->PhyTxControlWord_1_Rts); - u16 ptcw_1_FbrRts = ltoh16(txh->PhyTxControlWord_1_FbrRts); - u16 mainrates = ltoh16(txh->MainRates); - u16 xtraft = ltoh16(txh->XtraFrameTypes); - u8 *iv = txh->IV; - u8 *ra = txh->TxFrameRA; - u16 tfestfb = ltoh16(txh->TxFesTimeFallback); - u8 *rtspfb = txh->RTSPLCPFallback; - u16 rtsdfb = ltoh16(txh->RTSDurFallback); - u8 *fragpfb = txh->FragPLCPFallback; - u16 fragdfb = ltoh16(txh->FragDurFallback); - u16 mmodelen = ltoh16(txh->MModeLen); - u16 mmodefbrlen = ltoh16(txh->MModeFbrLen); - u16 tfid = ltoh16(txh->TxFrameID); - u16 txs = ltoh16(txh->TxStatus); - u16 mnmpdu = ltoh16(txh->MaxNMpdus); - u16 mabyte = ltoh16(txh->MaxABytes_MRT); - u16 mabyte_f = ltoh16(txh->MaxABytes_FBR); - u16 mmbyte = ltoh16(txh->MinMBytes); - - u8 *rtsph = txh->RTSPhyHeader; - struct ieee80211_rts rts = txh->rts_frame; - char hexbuf[256]; - - /* add plcp header along with txh descriptor */ - prhex("Raw TxDesc + plcp header", (unsigned char *) txh, sizeof(d11txh_t) + 48); - - printf("TxCtlLow: %04x ", mtcl); - printf("TxCtlHigh: %04x ", mtch); - printf("FC: %04x ", mfc); - printf("FES Time: %04x\n", tfest); - printf("PhyCtl: %04x%s ", ptcw, - (ptcw & PHY_TXC_SHORT_HDR) ? " short" : ""); - printf("PhyCtl_1: %04x ", ptcw_1); - printf("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr); - printf("PhyCtl_1_Rts: %04x ", ptcw_1_Rts); - printf("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts); - printf("MainRates: %04x ", mainrates); - printf("XtraFrameTypes: %04x ", xtraft); - printf("\n"); - - bcm_format_hex(hexbuf, iv, sizeof(txh->IV)); - printf("SecIV: %s\n", hexbuf); - bcm_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA)); - printf("RA: %s\n", hexbuf); - - printf("Fb FES Time: %04x ", tfestfb); - bcm_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback)); - printf("RTS PLCP: %s ", hexbuf); - printf("RTS DUR: %04x ", rtsdfb); - bcm_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback)); - printf("PLCP: %s ", hexbuf); - printf("DUR: %04x", fragdfb); - printf("\n"); - - printf("MModeLen: %04x ", mmodelen); - printf("MModeFbrLen: %04x\n", mmodefbrlen); - - printf("FrameID: %04x\n", tfid); - printf("TxStatus: %04x\n", txs); - - printf("MaxNumMpdu: %04x\n", mnmpdu); - printf("MaxAggbyte: %04x\n", mabyte); - printf("MaxAggbyte_fb: %04x\n", mabyte_f); - printf("MinByte: %04x\n", mmbyte); - - bcm_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader)); - printf("RTS PLCP: %s ", hexbuf); - bcm_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame)); - printf("RTS Frame: %s", hexbuf); - printf("\n"); - -} -#endif /* defined(BCMDBG) */ - -#if defined(BCMDBG) -void wlc_print_rxh(d11rxhdr_t *rxh) -{ - u16 len = rxh->RxFrameSize; - u16 phystatus_0 = rxh->PhyRxStatus_0; - u16 phystatus_1 = rxh->PhyRxStatus_1; - u16 phystatus_2 = rxh->PhyRxStatus_2; - u16 phystatus_3 = rxh->PhyRxStatus_3; - u16 macstatus1 = rxh->RxStatus1; - u16 macstatus2 = rxh->RxStatus2; - char flagstr[64]; - char lenbuf[20]; - static const bcm_bit_desc_t macstat_flags[] = { - {RXS_FCSERR, "FCSErr"}, - {RXS_RESPFRAMETX, "Reply"}, - {RXS_PBPRES, "PADDING"}, - {RXS_DECATMPT, "DeCr"}, - {RXS_DECERR, "DeCrErr"}, - {RXS_BCNSENT, "Bcn"}, - {0, NULL} - }; - - prhex("Raw RxDesc", (unsigned char *) rxh, sizeof(d11rxhdr_t)); - - bcm_format_flags(macstat_flags, macstatus1, flagstr, 64); - - snprintf(lenbuf, sizeof(lenbuf), "0x%x", len); - - printf("RxFrameSize: %6s (%d)%s\n", lenbuf, len, - (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : ""); - printf("RxPHYStatus: %04x %04x %04x %04x\n", - phystatus_0, phystatus_1, phystatus_2, phystatus_3); - printf("RxMACStatus: %x %s\n", macstatus1, flagstr); - printf("RXMACaggtype: %x\n", (macstatus2 & RXS_AGGTYPE_MASK)); - printf("RxTSFTime: %04x\n", rxh->RxTSFTime); -} -#endif /* defined(BCMDBG) */ - -#if defined(BCMDBG) -int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len) -{ - uint i, c; - char *p = buf; - char *endp = buf + SSID_FMT_BUF_LEN; - - if (ssid_len > IEEE80211_MAX_SSID_LEN) - ssid_len = IEEE80211_MAX_SSID_LEN; - - for (i = 0; i < ssid_len; i++) { - c = (uint) ssid[i]; - if (c == '\\') { - *p++ = '\\'; - *p++ = '\\'; - } else if (isprint((unsigned char) c)) { - *p++ = (char)c; - } else { - p += snprintf(p, (endp - p), "\\x%02X", c); - } - } - *p = '\0'; - ASSERT(p < endp); - - return (int)(p - buf); -} -#endif /* defined(BCMDBG) */ - -u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate) -{ - return wlc_bmac_rate_shm_offset(wlc->hw, rate); -} - -/* Callback for device removed */ - -/* - * Attempts to queue a packet onto a multiple-precedence queue, - * if necessary evicting a lower precedence packet from the queue. - * - * 'prec' is the precedence number that has already been mapped - * from the packet priority. - * - * Returns true if packet consumed (queued), false if not. - */ -bool BCMFASTPATH -wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, int prec) -{ - return wlc_prec_enq_head(wlc, q, pkt, prec, false); -} - -bool BCMFASTPATH -wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, - int prec, bool head) -{ - struct sk_buff *p; - int eprec = -1; /* precedence to evict from */ - - /* Determine precedence from which to evict packet, if any */ - if (pktq_pfull(q, prec)) - eprec = prec; - else if (pktq_full(q)) { - p = pktq_peek_tail(q, &eprec); - ASSERT(p != NULL); - if (eprec > prec) { - WL_ERROR("%s: Failing: eprec %d > prec %d\n", - __func__, eprec, prec); - return false; - } - } - - /* Evict if needed */ - if (eprec >= 0) { - bool discard_oldest; - - /* Detect queueing to unconfigured precedence */ - ASSERT(!pktq_pempty(q, eprec)); - - discard_oldest = AC_BITMAP_TST(wlc->wme_dp, eprec); - - /* Refuse newer packet unless configured to discard oldest */ - if (eprec == prec && !discard_oldest) { - WL_ERROR("%s: No where to go, prec == %d\n", - __func__, prec); - return false; - } - - /* Evict packet according to discard policy */ - p = discard_oldest ? pktq_pdeq(q, eprec) : pktq_pdeq_tail(q, - eprec); - ASSERT(p != NULL); - - /* Increment wme stats */ - if (WME_ENAB(wlc->pub)) { - WLCNTINCR(wlc->pub->_wme_cnt-> - tx_failed[WME_PRIO2AC(p->priority)].packets); - WLCNTADD(wlc->pub->_wme_cnt-> - tx_failed[WME_PRIO2AC(p->priority)].bytes, - pkttotlen(wlc->osh, p)); - } - - ASSERT(0); - pkt_buf_free_skb(wlc->osh, p, true); - WLCNTINCR(wlc->pub->_cnt->txnobuf); - } - - /* Enqueue */ - if (head) - p = pktq_penq_head(q, prec, pkt); - else - p = pktq_penq(q, prec, pkt); - ASSERT(p != NULL); - - return true; -} - -void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, - uint prec) -{ - struct wlc_info *wlc = (struct wlc_info *) ctx; - wlc_txq_info_t *qi = wlc->active_queue; /* Check me */ - struct pktq *q = &qi->q; - int prio; - - prio = sdu->priority; - - ASSERT(pktq_max(q) >= wlc->pub->tunables->datahiwat); - - if (!wlc_prec_enq(wlc, q, sdu, prec)) { - if (!EDCF_ENAB(wlc->pub) - || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) - WL_ERROR("wl%d: wlc_txq_enq: txq overflow\n", - wlc->pub->unit); - - /* ASSERT(9 == 8); *//* XXX we might hit this condtion in case packet flooding from mac80211 stack */ - pkt_buf_free_skb(wlc->osh, sdu, true); - WLCNTINCR(wlc->pub->_cnt->txnobuf); - } - - /* Check if flow control needs to be turned on after enqueuing the packet - * Don't turn on flow control if EDCF is enabled. Driver would make the decision on what - * to drop instead of relying on stack to make the right decision - */ - if (!EDCF_ENAB(wlc->pub) - || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) { - if (pktq_len(q) >= wlc->pub->tunables->datahiwat) { - wlc_txflowcontrol(wlc, qi, ON, ALLPRIO); - } - } else if (wlc->pub->_priofc) { - if (pktq_plen(q, wlc_prio2prec_map[prio]) >= - wlc->pub->tunables->datahiwat) { - wlc_txflowcontrol(wlc, qi, ON, prio); - } - } -} - -bool BCMFASTPATH -wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, - struct ieee80211_hw *hw) -{ - u8 prio; - uint fifo; - void *pkt; - struct scb *scb = &global_scb; - struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data); - u16 type, fc; - - ASSERT(sdu); - - fc = ltoh16(d11_header->frame_control); - type = (fc & IEEE80211_FCTL_FTYPE); - - /* 802.11 standard requires management traffic to go at highest priority */ - prio = (type == IEEE80211_FTYPE_DATA ? sdu->priority : MAXPRIO); - fifo = prio2fifo[prio]; - - ASSERT((uint) skb_headroom(sdu) >= TXOFF); - ASSERT(!(sdu->cloned)); - ASSERT(!(sdu->next)); - ASSERT(!(sdu->prev)); - ASSERT(fifo < NFIFO); - - pkt = sdu; - if (unlikely - (wlc_d11hdrs_mac80211(wlc, hw, pkt, scb, 0, 1, fifo, 0, NULL, 0))) - return -EINVAL; - wlc_txq_enq(wlc, scb, pkt, WLC_PRIO_TO_PREC(prio)); - wlc_send_q(wlc, wlc->active_queue); - - WLCNTINCR(wlc->pub->_cnt->ieee_tx); - return 0; -} - -void BCMFASTPATH wlc_send_q(struct wlc_info *wlc, wlc_txq_info_t *qi) -{ - struct sk_buff *pkt[DOT11_MAXNUMFRAGS]; - int prec; - u16 prec_map; - int err = 0, i, count; - uint fifo; - struct pktq *q = &qi->q; - struct ieee80211_tx_info *tx_info; - - /* only do work for the active queue */ - if (qi != wlc->active_queue) - return; - - if (in_send_q) - return; - else - in_send_q = true; - - prec_map = wlc->tx_prec_map; - - /* Send all the enq'd pkts that we can. - * Dequeue packets with precedence with empty HW fifo only - */ - while (prec_map && (pkt[0] = pktq_mdeq(q, prec_map, &prec))) { - tx_info = IEEE80211_SKB_CB(pkt[0]); - if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { - err = wlc_sendampdu(wlc->ampdu, qi, pkt, prec); - } else { - count = 1; - err = wlc_prep_pdu(wlc, pkt[0], &fifo); - if (!err) { - for (i = 0; i < count; i++) { - wlc_txfifo(wlc, fifo, pkt[i], true, 1); - } - } - } - - if (err == BCME_BUSY) { - pktq_penq_head(q, prec, pkt[0]); - /* If send failed due to any other reason than a change in - * HW FIFO condition, quit. Otherwise, read the new prec_map! - */ - if (prec_map == wlc->tx_prec_map) - break; - prec_map = wlc->tx_prec_map; - } - } - - /* Check if flow control needs to be turned off after sending the packet */ - if (!EDCF_ENAB(wlc->pub) - || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) { - if (wlc_txflowcontrol_prio_isset(wlc, qi, ALLPRIO) - && (pktq_len(q) < wlc->pub->tunables->datahiwat / 2)) { - wlc_txflowcontrol(wlc, qi, OFF, ALLPRIO); - } - } else if (wlc->pub->_priofc) { - int prio; - for (prio = MAXPRIO; prio >= 0; prio--) { - if (wlc_txflowcontrol_prio_isset(wlc, qi, prio) && - (pktq_plen(q, wlc_prio2prec_map[prio]) < - wlc->pub->tunables->datahiwat / 2)) { - wlc_txflowcontrol(wlc, qi, OFF, prio); - } - } - } - in_send_q = false; -} - -/* - * bcmc_fid_generate: - * Generate frame ID for a BCMC packet. The frag field is not used - * for MC frames so is used as part of the sequence number. - */ -static inline u16 -bcmc_fid_generate(struct wlc_info *wlc, wlc_bsscfg_t *bsscfg, d11txh_t *txh) -{ - u16 frameid; - - frameid = ltoh16(txh->TxFrameID) & ~(TXFID_SEQ_MASK | TXFID_QUEUE_MASK); - frameid |= - (((wlc-> - mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) | - TX_BCMC_FIFO; - - return frameid; -} - -void BCMFASTPATH -wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit, - s8 txpktpend) -{ - u16 frameid = INVALIDFID; - d11txh_t *txh; - - ASSERT(fifo < NFIFO); - txh = (d11txh_t *) (p->data); - - /* When a BC/MC frame is being committed to the BCMC fifo via DMA (NOT PIO), update - * ucode or BSS info as appropriate. - */ - if (fifo == TX_BCMC_FIFO) { - frameid = ltoh16(txh->TxFrameID); - - } - - if (WLC_WAR16165(wlc)) - wlc_war16165(wlc, true); - - - /* Bump up pending count for if not using rpc. If rpc is used, this will be handled - * in wlc_bmac_txfifo() - */ - if (commit) { - TXPKTPENDINC(wlc, fifo, txpktpend); - WL_TRACE("wlc_txfifo, pktpend inc %d to %d\n", - txpktpend, TXPKTPENDGET(wlc, fifo)); - } - - /* Commit BCMC sequence number in the SHM frame ID location */ - if (frameid != INVALIDFID) - BCMCFID(wlc, frameid); - - if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) { - WL_ERROR("wlc_txfifo: fatal, toss frames !!!\n"); - } -} - -static u16 -wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, uint length) -{ - u16 usec = 0; - uint mac_rate = RSPEC2RATE(rspec); - uint nsyms; - - if (IS_MCS(rspec)) { - /* not supported yet */ - ASSERT(0); - } else if (IS_OFDM(rspec)) { - /* nsyms = Ceiling(Nbits / (Nbits/sym)) - * - * Nbits = length * 8 - * Nbits/sym = Mbps * 4 = mac_rate * 2 - */ - nsyms = CEIL((length * 8), (mac_rate * 2)); - - /* usec = symbols * usec/symbol */ - usec = (u16) (nsyms * APHY_SYMBOL_TIME); - return usec; - } else { - switch (mac_rate) { - case WLC_RATE_1M: - usec = length << 3; - break; - case WLC_RATE_2M: - usec = length << 2; - break; - case WLC_RATE_5M5: - usec = (length << 4) / 11; - break; - case WLC_RATE_11M: - usec = (length << 3) / 11; - break; - default: - WL_ERROR("wl%d: wlc_compute_airtime: unsupported rspec 0x%x\n", - wlc->pub->unit, rspec); - ASSERT((const char *)"Bad phy_rate" == NULL); - break; - } - } - - return usec; -} - -void BCMFASTPATH -wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rspec, uint length, u8 *plcp) -{ - if (IS_MCS(rspec)) { - wlc_compute_mimo_plcp(rspec, length, plcp); - } else if (IS_OFDM(rspec)) { - wlc_compute_ofdm_plcp(rspec, length, plcp); - } else { - wlc_compute_cck_plcp(rspec, length, plcp); - } - return; -} - -/* Rate: 802.11 rate code, length: PSDU length in octets */ -static void wlc_compute_mimo_plcp(ratespec_t rspec, uint length, u8 *plcp) -{ - u8 mcs = (u8) (rspec & RSPEC_RATE_MASK); - ASSERT(IS_MCS(rspec)); - plcp[0] = mcs; - if (RSPEC_IS40MHZ(rspec) || (mcs == 32)) - plcp[0] |= MIMO_PLCP_40MHZ; - WLC_SET_MIMO_PLCP_LEN(plcp, length); - plcp[3] = RSPEC_MIMOPLCP3(rspec); /* rspec already holds this byte */ - plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */ - plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */ - plcp[5] = 0; -} - -/* Rate: 802.11 rate code, length: PSDU length in octets */ -static void BCMFASTPATH -wlc_compute_ofdm_plcp(ratespec_t rspec, u32 length, u8 *plcp) -{ - u8 rate_signal; - u32 tmp = 0; - int rate = RSPEC2RATE(rspec); - - ASSERT(IS_OFDM(rspec)); - - /* encode rate per 802.11a-1999 sec 17.3.4.1, with lsb transmitted first */ - rate_signal = rate_info[rate] & RATE_MASK; - ASSERT(rate_signal != 0); - - memset(plcp, 0, D11_PHY_HDR_LEN); - D11A_PHY_HDR_SRATE((ofdm_phy_hdr_t *) plcp, rate_signal); - - tmp = (length & 0xfff) << 5; - plcp[2] |= (tmp >> 16) & 0xff; - plcp[1] |= (tmp >> 8) & 0xff; - plcp[0] |= tmp & 0xff; - - return; -} - -/* - * Compute PLCP, but only requires actual rate and length of pkt. - * Rate is given in the driver standard multiple of 500 kbps. - * le is set for 11 Mbps rate if necessary. - * Broken out for PRQ. - */ - -static void wlc_cck_plcp_set(int rate_500, uint length, u8 *plcp) -{ - u16 usec = 0; - u8 le = 0; - - switch (rate_500) { - case WLC_RATE_1M: - usec = length << 3; - break; - case WLC_RATE_2M: - usec = length << 2; - break; - case WLC_RATE_5M5: - usec = (length << 4) / 11; - if ((length << 4) - (usec * 11) > 0) - usec++; - break; - case WLC_RATE_11M: - usec = (length << 3) / 11; - if ((length << 3) - (usec * 11) > 0) { - usec++; - if ((usec * 11) - (length << 3) >= 8) - le = D11B_PLCP_SIGNAL_LE; - } - break; - - default: - WL_ERROR("wlc_cck_plcp_set: unsupported rate %d\n", rate_500); - rate_500 = WLC_RATE_1M; - usec = length << 3; - break; - } - /* PLCP signal byte */ - plcp[0] = rate_500 * 5; /* r (500kbps) * 5 == r (100kbps) */ - /* PLCP service byte */ - plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED); - /* PLCP length u16, little endian */ - plcp[2] = usec & 0xff; - plcp[3] = (usec >> 8) & 0xff; - /* PLCP CRC16 */ - plcp[4] = 0; - plcp[5] = 0; -} - -/* Rate: 802.11 rate code, length: PSDU length in octets */ -static void wlc_compute_cck_plcp(ratespec_t rspec, uint length, u8 *plcp) -{ - int rate = RSPEC2RATE(rspec); - - ASSERT(IS_CCK(rspec)); - - wlc_cck_plcp_set(rate, length, plcp); -} - -/* wlc_compute_frame_dur() - * - * Calculate the 802.11 MAC header DUR field for MPDU - * DUR for a single frame = 1 SIFS + 1 ACK - * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time - * - * rate MPDU rate in unit of 500kbps - * next_frag_len next MPDU length in bytes - * preamble_type use short/GF or long/MM PLCP header - */ -static u16 BCMFASTPATH -wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type, - uint next_frag_len) -{ - u16 dur, sifs; - - sifs = SIFS(wlc->band); - - dur = sifs; - dur += (u16) wlc_calc_ack_time(wlc, rate, preamble_type); - - if (next_frag_len) { - /* Double the current DUR to get 2 SIFS + 2 ACKs */ - dur *= 2; - /* add another SIFS and the frag time */ - dur += sifs; - dur += - (u16) wlc_calc_frame_time(wlc, rate, preamble_type, - next_frag_len); - } - return dur; -} - -/* wlc_compute_rtscts_dur() - * - * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame - * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK - * DUR for CTS-TO-SELF w/ frame = 2 SIFS + next frame time + 1 ACK - * - * cts cts-to-self or rts/cts - * rts_rate rts or cts rate in unit of 500kbps - * rate next MPDU rate in unit of 500kbps - * frame_len next MPDU frame length in bytes - */ -u16 BCMFASTPATH -wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, ratespec_t rts_rate, - ratespec_t frame_rate, u8 rts_preamble_type, - u8 frame_preamble_type, uint frame_len, bool ba) -{ - u16 dur, sifs; - - sifs = SIFS(wlc->band); - - if (!cts_only) { /* RTS/CTS */ - dur = 3 * sifs; - dur += - (u16) wlc_calc_cts_time(wlc, rts_rate, - rts_preamble_type); - } else { /* CTS-TO-SELF */ - dur = 2 * sifs; - } - - dur += - (u16) wlc_calc_frame_time(wlc, frame_rate, frame_preamble_type, - frame_len); - if (ba) - dur += - (u16) wlc_calc_ba_time(wlc, frame_rate, - WLC_SHORT_PREAMBLE); - else - dur += - (u16) wlc_calc_ack_time(wlc, frame_rate, - frame_preamble_type); - return dur; -} - -static bool wlc_phy_rspec_check(struct wlc_info *wlc, u16 bw, ratespec_t rspec) -{ - if (IS_MCS(rspec)) { - uint mcs = rspec & RSPEC_RATE_MASK; - - if (mcs < 8) { - ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM); - } else if ((mcs >= 8) && (mcs <= 23)) { - ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SDM); - } else if (mcs == 32) { - ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM); - ASSERT(bw == PHY_TXC1_BW_40MHZ_DUP); - } - } else if (IS_OFDM(rspec)) { - ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_STBC); - } else { - ASSERT(IS_CCK(rspec)); - - ASSERT((bw == PHY_TXC1_BW_20MHZ) - || (bw == PHY_TXC1_BW_20MHZ_UP)); - ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SISO); - } - - return true; -} - -u16 BCMFASTPATH wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec) -{ - u16 phyctl1 = 0; - u16 bw; - - if (WLCISLCNPHY(wlc->band)) { - bw = PHY_TXC1_BW_20MHZ; - } else { - bw = RSPEC_GET_BW(rspec); - /* 10Mhz is not supported yet */ - if (bw < PHY_TXC1_BW_20MHZ) { - WL_ERROR("wlc_phytxctl1_calc: bw %d is not supported yet, set to 20L\n", - bw); - bw = PHY_TXC1_BW_20MHZ; - } - - wlc_phy_rspec_check(wlc, bw, rspec); - } - - if (IS_MCS(rspec)) { - uint mcs = rspec & RSPEC_RATE_MASK; - - /* bw, stf, coding-type is part of RSPEC_PHYTXBYTE2 returns */ - phyctl1 = RSPEC_PHYTXBYTE2(rspec); - /* set the upper byte of phyctl1 */ - phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8); - } else if (IS_CCK(rspec) && !WLCISLCNPHY(wlc->band) - && !WLCISSSLPNPHY(wlc->band)) { - /* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */ - /* Eventually MIMOPHY would also be converted to this format */ - /* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */ - phyctl1 = (bw | (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT)); - } else { /* legacy OFDM/CCK */ - s16 phycfg; - /* get the phyctl byte from rate phycfg table */ - phycfg = wlc_rate_legacy_phyctl(RSPEC2RATE(rspec)); - if (phycfg == -1) { - WL_ERROR("wlc_phytxctl1_calc: wrong legacy OFDM/CCK rate\n"); - ASSERT(0); - phycfg = 0; - } - /* set the upper byte of phyctl1 */ - phyctl1 = - (bw | (phycfg << 8) | - (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT)); - } - -#ifdef BCMDBG - /* phy clock must support 40Mhz if tx descriptor uses it */ - if ((phyctl1 & PHY_TXC1_BW_MASK) >= PHY_TXC1_BW_40MHZ) { - ASSERT(CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ); - ASSERT(wlc->chanspec == wlc_phy_chanspec_get(wlc->band->pi)); - } -#endif /* BCMDBG */ - return phyctl1; -} - -ratespec_t BCMFASTPATH -wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, bool use_rspec, - u16 mimo_ctlchbw) -{ - ratespec_t rts_rspec = 0; - - if (use_rspec) { - /* use frame rate as rts rate */ - rts_rspec = rspec; - - } else if (wlc->band->gmode && wlc->protection->_g && !IS_CCK(rspec)) { - /* Use 11Mbps as the g protection RTS target rate and fallback. - * Use the WLC_BASIC_RATE() lookup to find the best basic rate under the - * target in case 11 Mbps is not Basic. - * 6 and 9 Mbps are not usually selected by rate selection, but even - * if the OFDM rate we are protecting is 6 or 9 Mbps, 11 is more robust. - */ - rts_rspec = WLC_BASIC_RATE(wlc, WLC_RATE_11M); - } else { - /* calculate RTS rate and fallback rate based on the frame rate - * RTS must be sent at a basic rate since it is a - * control frame, sec 9.6 of 802.11 spec - */ - rts_rspec = WLC_BASIC_RATE(wlc, rspec); - } - - if (WLC_PHY_11N_CAP(wlc->band)) { - /* set rts txbw to correct side band */ - rts_rspec &= ~RSPEC_BW_MASK; - - /* if rspec/rspec_fallback is 40MHz, then send RTS on both 20MHz channel - * (DUP), otherwise send RTS on control channel - */ - if (RSPEC_IS40MHZ(rspec) && !IS_CCK(rts_rspec)) - rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT); - else - rts_rspec |= (mimo_ctlchbw << RSPEC_BW_SHIFT); - - /* pick siso/cdd as default for ofdm */ - if (IS_OFDM(rts_rspec)) { - rts_rspec &= ~RSPEC_STF_MASK; - rts_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT); - } - } - return rts_rspec; -} - -/* - * Add d11txh_t, cck_phy_hdr_t. - * - * 'p' data must start with 802.11 MAC header - * 'p' must allow enough bytes of local headers to be "pushed" onto the packet - * - * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes) - * - */ -static u16 BCMFASTPATH -wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, - struct sk_buff *p, struct scb *scb, uint frag, - uint nfrags, uint queue, uint next_frag_len, - wsec_key_t *key, ratespec_t rspec_override) -{ - struct ieee80211_hdr *h; - d11txh_t *txh; - u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN]; - struct osl_info *osh; - int len, phylen, rts_phylen; - u16 fc, type, frameid, mch, phyctl, xfts, mainrates; - u16 seq = 0, mcl = 0, status = 0; - ratespec_t rspec[2] = { WLC_RATE_1M, WLC_RATE_1M }, rts_rspec[2] = { - WLC_RATE_1M, WLC_RATE_1M}; - bool use_rts = false; - bool use_cts = false; - bool use_rifs = false; - bool short_preamble[2] = { false, false }; - u8 preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE }; - u8 rts_preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE }; - u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN]; - struct ieee80211_rts *rts = NULL; - bool qos; - uint ac; - u32 rate_val[2]; - bool hwtkmic = false; - u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; -#ifdef WLANTSEL -#define ANTCFG_NONE 0xFF - u8 antcfg = ANTCFG_NONE; - u8 fbantcfg = ANTCFG_NONE; -#endif - uint phyctl1_stf = 0; - u16 durid = 0; - struct ieee80211_tx_rate *txrate[2]; - int k; - struct ieee80211_tx_info *tx_info; - bool is_mcs[2]; - u16 mimo_txbw; - u8 mimo_preamble_type; - - frameid = 0; - - ASSERT(queue < NFIFO); - - osh = wlc->osh; - - /* locate 802.11 MAC header */ - h = (struct ieee80211_hdr *)(p->data); - fc = ltoh16(h->frame_control); - type = (fc & IEEE80211_FCTL_FTYPE); - - qos = (type == IEEE80211_FTYPE_DATA && - FC_SUBTYPE_ANY_QOS(fc)); - - /* compute length of frame in bytes for use in PLCP computations */ - len = pkttotlen(osh, p); - phylen = len + FCS_LEN; - - /* If WEP enabled, add room in phylen for the additional bytes of - * ICV which MAC generates. We do NOT add the additional bytes to - * the packet itself, thus phylen = packet length + ICV_LEN + FCS_LEN - * in this case - */ - if (key) { - phylen += key->icv_len; - } - - /* Get tx_info */ - tx_info = IEEE80211_SKB_CB(p); - ASSERT(tx_info); - - /* add PLCP */ - plcp = skb_push(p, D11_PHY_HDR_LEN); - - /* add Broadcom tx descriptor header */ - txh = (d11txh_t *) skb_push(p, D11_TXH_LEN); - memset((char *)txh, 0, D11_TXH_LEN); - - /* setup frameid */ - if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { - /* non-AP STA should never use BCMC queue */ - ASSERT(queue != TX_BCMC_FIFO); - if (queue == TX_BCMC_FIFO) { - WL_ERROR("wl%d: %s: ASSERT queue == TX_BCMC!\n", - WLCWLUNIT(wlc), __func__); - frameid = bcmc_fid_generate(wlc, NULL, txh); - } else { - /* Increment the counter for first fragment */ - if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) { - SCB_SEQNUM(scb, p->priority)++; - } - - /* extract fragment number from frame first */ - seq = ltoh16(seq) & FRAGNUM_MASK; - seq |= (SCB_SEQNUM(scb, p->priority) << SEQNUM_SHIFT); - h->seq_ctrl = htol16(seq); - - frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) | - (queue & TXFID_QUEUE_MASK); - } - } - frameid |= queue & TXFID_QUEUE_MASK; - - /* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */ - if (SCB_PS(scb) || ((fc & FC_KIND_MASK) == FC_BEACON)) - mcl |= TXC_IGNOREPMQ; - - ASSERT(hw->max_rates <= IEEE80211_TX_MAX_RATES); - ASSERT(hw->max_rates == 2); - - txrate[0] = tx_info->control.rates; - txrate[1] = txrate[0] + 1; - - ASSERT(txrate[0]->idx >= 0); - /* if rate control algorithm didn't give us a fallback rate, use the primary rate */ - if (txrate[1]->idx < 0) { - txrate[1] = txrate[0]; - } - - for (k = 0; k < hw->max_rates; k++) { - is_mcs[k] = - txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false; - if (!is_mcs[k]) { - ASSERT(!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)); - if ((txrate[k]->idx >= 0) - && (txrate[k]->idx < - hw->wiphy->bands[tx_info->band]->n_bitrates)) { - rate_val[k] = - hw->wiphy->bands[tx_info->band]-> - bitrates[txrate[k]->idx].hw_value; - short_preamble[k] = - txrate[k]-> - flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ? - true : false; - } else { - ASSERT((txrate[k]->idx >= 0) && - (txrate[k]->idx < - hw->wiphy->bands[tx_info->band]-> - n_bitrates)); - rate_val[k] = WLC_RATE_1M; - } - } else { - rate_val[k] = txrate[k]->idx; - } - /* Currently only support same setting for primay and fallback rates. - * Unify flags for each rate into a single value for the frame - */ - use_rts |= - txrate[k]-> - flags & IEEE80211_TX_RC_USE_RTS_CTS ? true : false; - use_cts |= - txrate[k]-> - flags & IEEE80211_TX_RC_USE_CTS_PROTECT ? true : false; - - if (is_mcs[k]) - rate_val[k] |= NRATE_MCS_INUSE; - - rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band, rate_val[k]); - - /* (1) RATE: determine and validate primary rate and fallback rates */ - if (!RSPEC_ACTIVE(rspec[k])) { - ASSERT(RSPEC_ACTIVE(rspec[k])); - rspec[k] = WLC_RATE_1M; - } else { - if (WLANTSEL_ENAB(wlc) && - !is_multicast_ether_addr(h->addr1)) { - /* set tx antenna config */ - wlc_antsel_antcfg_get(wlc->asi, false, false, 0, - 0, &antcfg, &fbantcfg); - } - } - } - - phyctl1_stf = wlc->stf->ss_opmode; - - if (N_ENAB(wlc->pub)) { - for (k = 0; k < hw->max_rates; k++) { - /* apply siso/cdd to single stream mcs's or ofdm if rspec is auto selected */ - if (((IS_MCS(rspec[k]) && - IS_SINGLE_STREAM(rspec[k] & RSPEC_RATE_MASK)) || - IS_OFDM(rspec[k])) - && ((rspec[k] & RSPEC_OVERRIDE_MCS_ONLY) - || !(rspec[k] & RSPEC_OVERRIDE))) { - rspec[k] &= ~(RSPEC_STF_MASK | RSPEC_STC_MASK); - - /* For SISO MCS use STBC if possible */ - if (IS_MCS(rspec[k]) - && WLC_STF_SS_STBC_TX(wlc, scb)) { - u8 stc; - - ASSERT(WLC_STBC_CAP_PHY(wlc)); - stc = 1; /* Nss for single stream is always 1 */ - rspec[k] |= - (PHY_TXC1_MODE_STBC << - RSPEC_STF_SHIFT) | (stc << - RSPEC_STC_SHIFT); - } else - rspec[k] |= - (phyctl1_stf << RSPEC_STF_SHIFT); - } - - /* Is the phy configured to use 40MHZ frames? If so then pick the desired txbw */ - if (CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ) { - /* default txbw is 20in40 SB */ - mimo_ctlchbw = mimo_txbw = - CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC) - ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; - - if (IS_MCS(rspec[k])) { - /* mcs 32 must be 40b/w DUP */ - if ((rspec[k] & RSPEC_RATE_MASK) == 32) { - mimo_txbw = - PHY_TXC1_BW_40MHZ_DUP; - /* use override */ - } else if (wlc->mimo_40txbw != AUTO) - mimo_txbw = wlc->mimo_40txbw; - /* else check if dst is using 40 Mhz */ - else if (scb->flags & SCB_IS40) - mimo_txbw = PHY_TXC1_BW_40MHZ; - } else if (IS_OFDM(rspec[k])) { - if (wlc->ofdm_40txbw != AUTO) - mimo_txbw = wlc->ofdm_40txbw; - } else { - ASSERT(IS_CCK(rspec[k])); - if (wlc->cck_40txbw != AUTO) - mimo_txbw = wlc->cck_40txbw; - } - } else { - /* mcs32 is 40 b/w only. - * This is possible for probe packets on a STA during SCAN - */ - if ((rspec[k] & RSPEC_RATE_MASK) == 32) { - /* mcs 0 */ - rspec[k] = RSPEC_MIMORATE; - } - mimo_txbw = PHY_TXC1_BW_20MHZ; - } - - /* Set channel width */ - rspec[k] &= ~RSPEC_BW_MASK; - if ((k == 0) || ((k > 0) && IS_MCS(rspec[k]))) - rspec[k] |= (mimo_txbw << RSPEC_BW_SHIFT); - else - rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT); - - /* Set Short GI */ -#ifdef NOSGIYET - if (IS_MCS(rspec[k]) - && (txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI)) - rspec[k] |= RSPEC_SHORT_GI; - else if (!(txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI)) - rspec[k] &= ~RSPEC_SHORT_GI; -#else - rspec[k] &= ~RSPEC_SHORT_GI; -#endif - - mimo_preamble_type = WLC_MM_PREAMBLE; - if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD) - mimo_preamble_type = WLC_GF_PREAMBLE; - - if ((txrate[k]->flags & IEEE80211_TX_RC_MCS) - && (!IS_MCS(rspec[k]))) { - WL_ERROR("wl%d: %s: IEEE80211_TX_RC_MCS != IS_MCS(rspec)\n", - WLCWLUNIT(wlc), __func__); - ASSERT(0 && "Rate mismatch"); - } - - if (IS_MCS(rspec[k])) { - preamble_type[k] = mimo_preamble_type; - - /* if SGI is selected, then forced mm for single stream */ - if ((rspec[k] & RSPEC_SHORT_GI) - && IS_SINGLE_STREAM(rspec[k] & - RSPEC_RATE_MASK)) { - preamble_type[k] = WLC_MM_PREAMBLE; - } - } - - /* mimo bw field MUST now be valid in the rspec (it affects duration calculations) */ - ASSERT(VALID_RATE_DBG(wlc, rspec[0])); - - /* should be better conditionalized */ - if (!IS_MCS(rspec[0]) - && (tx_info->control.rates[0]. - flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)) - preamble_type[k] = WLC_SHORT_PREAMBLE; - - ASSERT(!IS_MCS(rspec[0]) - || WLC_IS_MIMO_PREAMBLE(preamble_type[k])); - } - } else { - for (k = 0; k < hw->max_rates; k++) { - /* Set ctrlchbw as 20Mhz */ - ASSERT(!IS_MCS(rspec[k])); - rspec[k] &= ~RSPEC_BW_MASK; - rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT); - - /* for nphy, stf of ofdm frames must follow policies */ - if (WLCISNPHY(wlc->band) && IS_OFDM(rspec[k])) { - rspec[k] &= ~RSPEC_STF_MASK; - rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT; - } - } - } - - /* Reset these for use with AMPDU's */ - txrate[0]->count = 0; - txrate[1]->count = 0; - - /* (3) PLCP: determine PLCP header and MAC duration, fill d11txh_t */ - wlc_compute_plcp(wlc, rspec[0], phylen, plcp); - wlc_compute_plcp(wlc, rspec[1], phylen, plcp_fallback); - bcopy(plcp_fallback, (char *)&txh->FragPLCPFallback, - sizeof(txh->FragPLCPFallback)); - - /* Length field now put in CCK FBR CRC field */ - if (IS_CCK(rspec[1])) { - txh->FragPLCPFallback[4] = phylen & 0xff; - txh->FragPLCPFallback[5] = (phylen & 0xff00) >> 8; - } - - /* MIMO-RATE: need validation ?? */ - mainrates = - IS_OFDM(rspec[0]) ? D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) plcp) : - plcp[0]; - - /* DUR field for main rate */ - if ((fc != FC_PS_POLL) && - !is_multicast_ether_addr(h->addr1) && !use_rifs) { - durid = - wlc_compute_frame_dur(wlc, rspec[0], preamble_type[0], - next_frag_len); - h->duration_id = htol16(durid); - } else if (use_rifs) { - /* NAV protect to end of next max packet size */ - durid = - (u16) wlc_calc_frame_time(wlc, rspec[0], - preamble_type[0], - DOT11_MAX_FRAG_LEN); - durid += RIFS_11N_TIME; - h->duration_id = htol16(durid); - } - - /* DUR field for fallback rate */ - if (fc == FC_PS_POLL) - txh->FragDurFallback = h->duration_id; - else if (is_multicast_ether_addr(h->addr1) || use_rifs) - txh->FragDurFallback = 0; - else { - durid = wlc_compute_frame_dur(wlc, rspec[1], - preamble_type[1], next_frag_len); - txh->FragDurFallback = htol16(durid); - } - - /* (4) MAC-HDR: MacTxControlLow */ - if (frag == 0) - mcl |= TXC_STARTMSDU; - - if (!is_multicast_ether_addr(h->addr1)) - mcl |= TXC_IMMEDACK; - - if (BAND_5G(wlc->band->bandtype)) - mcl |= TXC_FREQBAND_5G; - - if (CHSPEC_IS40(WLC_BAND_PI_RADIO_CHANSPEC)) - mcl |= TXC_BW_40; - - /* set AMIC bit if using hardware TKIP MIC */ - if (hwtkmic) - mcl |= TXC_AMIC; - - txh->MacTxControlLow = htol16(mcl); - - /* MacTxControlHigh */ - mch = 0; - - /* Set fallback rate preamble type */ - if ((preamble_type[1] == WLC_SHORT_PREAMBLE) || - (preamble_type[1] == WLC_GF_PREAMBLE)) { - ASSERT((preamble_type[1] == WLC_GF_PREAMBLE) || - (!IS_MCS(rspec[1]))); - if (RSPEC2RATE(rspec[1]) != WLC_RATE_1M) - mch |= TXC_PREAMBLE_DATA_FB_SHORT; - } - - /* MacFrameControl */ - bcopy((char *)&h->frame_control, (char *)&txh->MacFrameControl, - sizeof(u16)); - txh->TxFesTimeNormal = htol16(0); - - txh->TxFesTimeFallback = htol16(0); - - /* TxFrameRA */ - bcopy((char *)&h->addr1, (char *)&txh->TxFrameRA, ETH_ALEN); - - /* TxFrameID */ - txh->TxFrameID = htol16(frameid); - - /* TxStatus, Note the case of recreating the first frag of a suppressed frame - * then we may need to reset the retry cnt's via the status reg - */ - txh->TxStatus = htol16(status); - - if (D11REV_GE(wlc->pub->corerev, 16)) { - /* extra fields for ucode AMPDU aggregation, the new fields are added to - * the END of previous structure so that it's compatible in driver. - * In old rev ucode, these fields should be ignored - */ - txh->MaxNMpdus = htol16(0); - txh->MaxABytes_MRT = htol16(0); - txh->MaxABytes_FBR = htol16(0); - txh->MinMBytes = htol16(0); - } - - /* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration, furnish d11txh_t */ - /* RTS PLCP header and RTS frame */ - if (use_rts || use_cts) { - if (use_rts && use_cts) - use_cts = false; - - for (k = 0; k < 2; k++) { - rts_rspec[k] = wlc_rspec_to_rts_rspec(wlc, rspec[k], - false, - mimo_ctlchbw); - } - - if (!IS_OFDM(rts_rspec[0]) && - !((RSPEC2RATE(rts_rspec[0]) == WLC_RATE_1M) || - (wlc->PLCPHdr_override == WLC_PLCP_LONG))) { - rts_preamble_type[0] = WLC_SHORT_PREAMBLE; - mch |= TXC_PREAMBLE_RTS_MAIN_SHORT; - } - - if (!IS_OFDM(rts_rspec[1]) && - !((RSPEC2RATE(rts_rspec[1]) == WLC_RATE_1M) || - (wlc->PLCPHdr_override == WLC_PLCP_LONG))) { - rts_preamble_type[1] = WLC_SHORT_PREAMBLE; - mch |= TXC_PREAMBLE_RTS_FB_SHORT; - } - - /* RTS/CTS additions to MacTxControlLow */ - if (use_cts) { - txh->MacTxControlLow |= htol16(TXC_SENDCTS); - } else { - txh->MacTxControlLow |= htol16(TXC_SENDRTS); - txh->MacTxControlLow |= htol16(TXC_LONGFRAME); - } - - /* RTS PLCP header */ - ASSERT(IS_ALIGNED((unsigned long)txh->RTSPhyHeader, sizeof(u16))); - rts_plcp = txh->RTSPhyHeader; - if (use_cts) - rts_phylen = DOT11_CTS_LEN + FCS_LEN; - else - rts_phylen = DOT11_RTS_LEN + FCS_LEN; - - wlc_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp); - - /* fallback rate version of RTS PLCP header */ - wlc_compute_plcp(wlc, rts_rspec[1], rts_phylen, - rts_plcp_fallback); - bcopy(rts_plcp_fallback, (char *)&txh->RTSPLCPFallback, - sizeof(txh->RTSPLCPFallback)); - - /* RTS frame fields... */ - rts = (struct ieee80211_rts *)&txh->rts_frame; - - durid = wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec[0], - rspec[0], rts_preamble_type[0], - preamble_type[0], phylen, false); - rts->duration = htol16(durid); - /* fallback rate version of RTS DUR field */ - durid = wlc_compute_rtscts_dur(wlc, use_cts, - rts_rspec[1], rspec[1], - rts_preamble_type[1], - preamble_type[1], phylen, false); - txh->RTSDurFallback = htol16(durid); - - if (use_cts) { - rts->frame_control = htol16(FC_CTS); - bcopy((char *)&h->addr2, (char *)&rts->ra, ETH_ALEN); - } else { - rts->frame_control = htol16((u16) FC_RTS); - bcopy((char *)&h->addr1, (char *)&rts->ra, - 2 * ETH_ALEN); - } - - /* mainrate - * low 8 bits: main frag rate/mcs, - * high 8 bits: rts/cts rate/mcs - */ - mainrates |= (IS_OFDM(rts_rspec[0]) ? - D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) rts_plcp) : - rts_plcp[0]) << 8; - } else { - memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN); - memset((char *)&txh->rts_frame, 0, - sizeof(struct ieee80211_rts)); - memset((char *)txh->RTSPLCPFallback, 0, - sizeof(txh->RTSPLCPFallback)); - txh->RTSDurFallback = 0; - } - -#ifdef SUPPORT_40MHZ - /* add null delimiter count */ - if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && IS_MCS(rspec)) { - txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = - wlc_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen); - } -#endif - - /* Now that RTS/RTS FB preamble types are updated, write the final value */ - txh->MacTxControlHigh = htol16(mch); - - /* MainRates (both the rts and frag plcp rates have been calculated now) */ - txh->MainRates = htol16(mainrates); - - /* XtraFrameTypes */ - xfts = FRAMETYPE(rspec[1], wlc->mimoft); - xfts |= (FRAMETYPE(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT); - xfts |= (FRAMETYPE(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT); - xfts |= - CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC) << XFTS_CHANNEL_SHIFT; - txh->XtraFrameTypes = htol16(xfts); - - /* PhyTxControlWord */ - phyctl = FRAMETYPE(rspec[0], wlc->mimoft); - if ((preamble_type[0] == WLC_SHORT_PREAMBLE) || - (preamble_type[0] == WLC_GF_PREAMBLE)) { - ASSERT((preamble_type[0] == WLC_GF_PREAMBLE) - || !IS_MCS(rspec[0])); - if (RSPEC2RATE(rspec[0]) != WLC_RATE_1M) - phyctl |= PHY_TXC_SHORT_HDR; - WLCNTINCR(wlc->pub->_cnt->txprshort); - } - - /* phytxant is properly bit shifted */ - phyctl |= wlc_stf_d11hdrs_phyctl_txant(wlc, rspec[0]); - txh->PhyTxControlWord = htol16(phyctl); - - /* PhyTxControlWord_1 */ - if (WLC_PHY_11N_CAP(wlc->band)) { - u16 phyctl1 = 0; - - phyctl1 = wlc_phytxctl1_calc(wlc, rspec[0]); - txh->PhyTxControlWord_1 = htol16(phyctl1); - phyctl1 = wlc_phytxctl1_calc(wlc, rspec[1]); - txh->PhyTxControlWord_1_Fbr = htol16(phyctl1); - - if (use_rts || use_cts) { - phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[0]); - txh->PhyTxControlWord_1_Rts = htol16(phyctl1); - phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[1]); - txh->PhyTxControlWord_1_FbrRts = htol16(phyctl1); - } - - /* - * For mcs frames, if mixedmode(overloaded with long preamble) is going to be set, - * fill in non-zero MModeLen and/or MModeFbrLen - * it will be unnecessary if they are separated - */ - if (IS_MCS(rspec[0]) && (preamble_type[0] == WLC_MM_PREAMBLE)) { - u16 mmodelen = - wlc_calc_lsig_len(wlc, rspec[0], phylen); - txh->MModeLen = htol16(mmodelen); - } - - if (IS_MCS(rspec[1]) && (preamble_type[1] == WLC_MM_PREAMBLE)) { - u16 mmodefbrlen = - wlc_calc_lsig_len(wlc, rspec[1], phylen); - txh->MModeFbrLen = htol16(mmodefbrlen); - } - } - - if (IS_MCS(rspec[0])) - ASSERT(IS_MCS(rspec[1])); - - ASSERT(!IS_MCS(rspec[0]) || - ((preamble_type[0] == WLC_MM_PREAMBLE) == (txh->MModeLen != 0))); - ASSERT(!IS_MCS(rspec[1]) || - ((preamble_type[1] == WLC_MM_PREAMBLE) == - (txh->MModeFbrLen != 0))); - - ac = wme_fifo2ac[queue]; - if (SCB_WME(scb) && qos && wlc->edcf_txop[ac]) { - uint frag_dur, dur, dur_fallback; - - ASSERT(!is_multicast_ether_addr(h->addr1)); - - /* WME: Update TXOP threshold */ - if ((!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) && (frag == 0)) { - frag_dur = - wlc_calc_frame_time(wlc, rspec[0], preamble_type[0], - phylen); - - if (rts) { - /* 1 RTS or CTS-to-self frame */ - dur = - wlc_calc_cts_time(wlc, rts_rspec[0], - rts_preamble_type[0]); - dur_fallback = - wlc_calc_cts_time(wlc, rts_rspec[1], - rts_preamble_type[1]); - /* (SIFS + CTS) + SIFS + frame + SIFS + ACK */ - dur += ltoh16(rts->duration); - dur_fallback += ltoh16(txh->RTSDurFallback); - } else if (use_rifs) { - dur = frag_dur; - dur_fallback = 0; - } else { - /* frame + SIFS + ACK */ - dur = frag_dur; - dur += - wlc_compute_frame_dur(wlc, rspec[0], - preamble_type[0], 0); - - dur_fallback = - wlc_calc_frame_time(wlc, rspec[1], - preamble_type[1], - phylen); - dur_fallback += - wlc_compute_frame_dur(wlc, rspec[1], - preamble_type[1], 0); - } - /* NEED to set TxFesTimeNormal (hard) */ - txh->TxFesTimeNormal = htol16((u16) dur); - /* NEED to set fallback rate version of TxFesTimeNormal (hard) */ - txh->TxFesTimeFallback = htol16((u16) dur_fallback); - - /* update txop byte threshold (txop minus intraframe overhead) */ - if (wlc->edcf_txop[ac] >= (dur - frag_dur)) { - { - uint newfragthresh; - - newfragthresh = - wlc_calc_frame_len(wlc, rspec[0], - preamble_type[0], - (wlc-> - edcf_txop[ac] - - (dur - - frag_dur))); - /* range bound the fragthreshold */ - if (newfragthresh < DOT11_MIN_FRAG_LEN) - newfragthresh = - DOT11_MIN_FRAG_LEN; - else if (newfragthresh > - wlc->usr_fragthresh) - newfragthresh = - wlc->usr_fragthresh; - /* update the fragthresh and do txc update */ - if (wlc->fragthresh[queue] != - (u16) newfragthresh) { - wlc->fragthresh[queue] = - (u16) newfragthresh; - } - } - } else - WL_ERROR("wl%d: %s txop invalid for rate %d\n", - wlc->pub->unit, fifo_names[queue], - RSPEC2RATE(rspec[0])); - - if (dur > wlc->edcf_txop[ac]) - WL_ERROR("wl%d: %s: %s txop exceeded phylen %d/%d dur %d/%d\n", - wlc->pub->unit, __func__, - fifo_names[queue], - phylen, wlc->fragthresh[queue], - dur, wlc->edcf_txop[ac]); - } - } - - return 0; -} - -void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs) -{ - wlc_bsscfg_t *cfg = wlc->cfg; - - WLCNTINCR(wlc->pub->_cnt->tbtt); - - if (BSSCFG_STA(cfg)) { - /* run watchdog here if the watchdog timer is not armed */ - if (WLC_WATCHDOG_TBTT(wlc)) { - u32 cur, delta; - if (wlc->WDarmed) { - wl_del_timer(wlc->wl, wlc->wdtimer); - wlc->WDarmed = false; - } - - cur = OSL_SYSUPTIME(); - delta = cur > wlc->WDlast ? cur - wlc->WDlast : - (u32) ~0 - wlc->WDlast + cur + 1; - if (delta >= TIMER_INTERVAL_WATCHDOG) { - wlc_watchdog((void *)wlc); - wlc->WDlast = cur; - } - - wl_add_timer(wlc->wl, wlc->wdtimer, - wlc_watchdog_backup_bi(wlc), true); - wlc->WDarmed = true; - } - } - - if (!cfg->BSS) { - /* DirFrmQ is now valid...defer setting until end of ATIM window */ - wlc->qvalid |= MCMD_DIRFRMQVAL; - } -} - -/* GP timer is a freerunning 32 bit counter, decrements at 1 us rate */ -void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us) -{ - ASSERT(wlc->pub->corerev >= 3); /* no gptimer in earlier revs */ - W_REG(wlc->osh, &wlc->regs->gptimer, us); -} - -void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc) -{ - ASSERT(wlc->pub->corerev >= 3); - W_REG(wlc->osh, &wlc->regs->gptimer, 0); -} - -static void wlc_hwtimer_gptimer_cb(struct wlc_info *wlc) -{ - /* when interrupt is generated, the counter is loaded with last value - * written and continue to decrement. So it has to be cleaned first - */ - W_REG(wlc->osh, &wlc->regs->gptimer, 0); -} - -/* - * This fn has all the high level dpc processing from wlc_dpc. - * POLICY: no macinstatus change, no bounding loop. - * All dpc bounding should be handled in BMAC dpc, like txstatus and rxint - */ -void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus) -{ - d11regs_t *regs = wlc->regs; -#ifdef BCMDBG - char flagstr[128]; - static const bcm_bit_desc_t int_flags[] = { - {MI_MACSSPNDD, "MACSSPNDD"}, - {MI_BCNTPL, "BCNTPL"}, - {MI_TBTT, "TBTT"}, - {MI_BCNSUCCESS, "BCNSUCCESS"}, - {MI_BCNCANCLD, "BCNCANCLD"}, - {MI_ATIMWINEND, "ATIMWINEND"}, - {MI_PMQ, "PMQ"}, - {MI_NSPECGEN_0, "NSPECGEN_0"}, - {MI_NSPECGEN_1, "NSPECGEN_1"}, - {MI_MACTXERR, "MACTXERR"}, - {MI_NSPECGEN_3, "NSPECGEN_3"}, - {MI_PHYTXERR, "PHYTXERR"}, - {MI_PME, "PME"}, - {MI_GP0, "GP0"}, - {MI_GP1, "GP1"}, - {MI_DMAINT, "DMAINT"}, - {MI_TXSTOP, "TXSTOP"}, - {MI_CCA, "CCA"}, - {MI_BG_NOISE, "BG_NOISE"}, - {MI_DTIM_TBTT, "DTIM_TBTT"}, - {MI_PRQ, "PRQ"}, - {MI_PWRUP, "PWRUP"}, - {MI_RFDISABLE, "RFDISABLE"}, - {MI_TFS, "TFS"}, - {MI_PHYCHANGED, "PHYCHANGED"}, - {MI_TO, "TO"}, - {0, NULL} - }; - - if (macintstatus & ~(MI_TBTT | MI_TXSTOP)) { - bcm_format_flags(int_flags, macintstatus, flagstr, - sizeof(flagstr)); - WL_TRACE("wl%d: macintstatus 0x%x %s\n", - wlc->pub->unit, macintstatus, flagstr); - } -#endif /* BCMDBG */ - - if (macintstatus & MI_PRQ) { - /* Process probe request FIFO */ - ASSERT(0 && "PRQ Interrupt in non-MBSS"); - } - - /* TBTT indication */ - /* ucode only gives either TBTT or DTIM_TBTT, not both */ - if (macintstatus & (MI_TBTT | MI_DTIM_TBTT)) - wlc_tbtt(wlc, regs); - - if (macintstatus & MI_GP0) { - WL_ERROR("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", - wlc->pub->unit, wlc->pub->now); - - printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", - __func__, wlc->pub->sih->chip, - wlc->pub->sih->chiprev); - - WLCNTINCR(wlc->pub->_cnt->psmwds); - - /* big hammer */ - wl_init(wlc->wl); - } - - /* gptimer timeout */ - if (macintstatus & MI_TO) { - wlc_hwtimer_gptimer_cb(wlc); - } - - if (macintstatus & MI_RFDISABLE) { - WL_ERROR("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n", - wlc->pub->unit, - R_REG(wlc->osh, ®s->phydebug) & PDBG_RFD); - /* delay the cleanup to wl_down in IBSS case */ - if ((R_REG(wlc->osh, ®s->phydebug) & PDBG_RFD)) { - int idx; - wlc_bsscfg_t *bsscfg; - FOREACH_BSS(wlc, idx, bsscfg) { - if (!BSSCFG_STA(bsscfg) || !bsscfg->enable - || !bsscfg->BSS) - continue; - WL_ERROR("wl%d: wlc_dpc: rfdisable -> wlc_bsscfg_disable()\n", - wlc->pub->unit); - } - } - } - - /* send any enq'd tx packets. Just makes sure to jump start tx */ - if (!pktq_empty(&wlc->active_queue->q)) - wlc_send_q(wlc, wlc->active_queue); - - ASSERT(wlc_ps_check(wlc)); -} - -static void *wlc_15420war(struct wlc_info *wlc, uint queue) -{ - struct hnddma_pub *di; - void *p; - - ASSERT(queue < NFIFO); - - if ((D11REV_IS(wlc->pub->corerev, 4)) - || (D11REV_GT(wlc->pub->corerev, 6))) - return NULL; - - di = wlc->hw->di[queue]; - ASSERT(di != NULL); - - /* get next packet, ignoring XmtStatus.Curr */ - p = dma_getnexttxp(di, HNDDMA_RANGE_ALL); - - /* sw block tx dma */ - dma_txblock(di); - - /* if tx ring is now empty, reset and re-init the tx dma channel */ - if (dma_txactive(wlc->hw->di[queue]) == 0) { - WLCNTINCR(wlc->pub->_cnt->txdmawar); - if (!dma_txreset(di)) - WL_ERROR("wl%d: %s: dma_txreset[%d]: cannot stop dma\n", - wlc->pub->unit, __func__, queue); - dma_txinit(di); - } - return p; -} - -static void wlc_war16165(struct wlc_info *wlc, bool tx) -{ - if (tx) { - /* the post-increment is used in STAY_AWAKE macro */ - if (wlc->txpend16165war++ == 0) - wlc_set_ps_ctrl(wlc); - } else { - wlc->txpend16165war--; - if (wlc->txpend16165war == 0) - wlc_set_ps_ctrl(wlc); - } -} - -/* process an individual tx_status_t */ -/* WLC_HIGH_API */ -bool BCMFASTPATH -wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) -{ - struct sk_buff *p; - uint queue; - d11txh_t *txh; - struct scb *scb = NULL; - bool free_pdu; - struct osl_info *osh; - int tx_rts, tx_frame_count, tx_rts_count; - uint totlen, supr_status; - bool lastframe; - struct ieee80211_hdr *h; - u16 fc; - u16 mcl; - struct ieee80211_tx_info *tx_info; - struct ieee80211_tx_rate *txrate; - int i; - - (void)(frm_tx2); /* Compiler reference to avoid unused variable warning */ - - /* discard intermediate indications for ucode with one legitimate case: - * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent - * tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts - * transmission count) - */ - if (!(txs->status & TX_STATUS_AMPDU) - && (txs->status & TX_STATUS_INTERMEDIATE)) { - WLCNTADD(wlc->pub->_cnt->txnoack, - ((txs-> - status & TX_STATUS_FRM_RTX_MASK) >> - TX_STATUS_FRM_RTX_SHIFT)); - WL_ERROR("%s: INTERMEDIATE but not AMPDU\n", __func__); - return false; - } - - osh = wlc->osh; - queue = txs->frameid & TXFID_QUEUE_MASK; - ASSERT(queue < NFIFO); - if (queue >= NFIFO) { - p = NULL; - goto fatal; - } - - p = GETNEXTTXP(wlc, queue); - if (WLC_WAR16165(wlc)) - wlc_war16165(wlc, false); - if (p == NULL) - p = wlc_15420war(wlc, queue); - ASSERT(p != NULL); - if (p == NULL) - goto fatal; - - txh = (d11txh_t *) (p->data); - mcl = ltoh16(txh->MacTxControlLow); - - if (txs->phyerr) { - WL_ERROR("phyerr 0x%x, rate 0x%x\n", - txs->phyerr, txh->MainRates); - wlc_print_txdesc(txh); - wlc_print_txstatus(txs); - } - - ASSERT(txs->frameid == htol16(txh->TxFrameID)); - if (txs->frameid != htol16(txh->TxFrameID)) - goto fatal; - - tx_info = IEEE80211_SKB_CB(p); - h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); - fc = ltoh16(h->frame_control); - - scb = (struct scb *)tx_info->control.sta->drv_priv; - - if (N_ENAB(wlc->pub)) { - u8 *plcp = (u8 *) (txh + 1); - if (PLCP3_ISSGI(plcp[3])) - WLCNTINCR(wlc->pub->_cnt->txmpdu_sgi); - if (PLCP3_ISSTBC(plcp[3])) - WLCNTINCR(wlc->pub->_cnt->txmpdu_stbc); - } - - if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { - ASSERT((mcl & TXC_AMPDU_MASK) != TXC_AMPDU_NONE); - wlc_ampdu_dotxstatus(wlc->ampdu, scb, p, txs); - return false; - } - - supr_status = txs->status & TX_STATUS_SUPR_MASK; - if (supr_status == TX_STATUS_SUPR_BADCH) - WL_NONE("%s: Pkt tx suppressed, possibly channel %d\n", - __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec)); - - tx_rts = htol16(txh->MacTxControlLow) & TXC_SENDRTS; - tx_frame_count = - (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT; - tx_rts_count = - (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT; - - lastframe = (fc & IEEE80211_FCTL_MOREFRAGS) == 0; - - if (!lastframe) { - WL_ERROR("Not last frame!\n"); - } else { - u16 sfbl, lfbl; - ieee80211_tx_info_clear_status(tx_info); - if (queue < AC_COUNT) { - sfbl = WLC_WME_RETRY_SFB_GET(wlc, wme_fifo2ac[queue]); - lfbl = WLC_WME_RETRY_LFB_GET(wlc, wme_fifo2ac[queue]); - } else { - sfbl = wlc->SFBL; - lfbl = wlc->LFBL; - } - - txrate = tx_info->status.rates; - /* FIXME: this should use a combination of sfbl, lfbl depending on frame length and RTS setting */ - if ((tx_frame_count > sfbl) && (txrate[1].idx >= 0)) { - /* rate selection requested a fallback rate and we used it */ - txrate->count = lfbl; - txrate[1].count = tx_frame_count - lfbl; - } else { - /* rate selection did not request fallback rate, or we didn't need it */ - txrate->count = tx_frame_count; - /* rc80211_minstrel.c:minstrel_tx_status() expects unused rates to be marked with idx = -1 */ - txrate[1].idx = -1; - txrate[1].count = 0; - } - - /* clear the rest of the rates */ - for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) { - txrate[i].idx = -1; - txrate[i].count = 0; - } - - if (txs->status & TX_STATUS_ACK_RCV) - tx_info->flags |= IEEE80211_TX_STAT_ACK; - } - - totlen = pkttotlen(osh, p); - free_pdu = true; - - wlc_txfifo_complete(wlc, queue, 1); - - if (lastframe) { - p->next = NULL; - p->prev = NULL; - wlc->txretried = 0; - /* remove PLCP & Broadcom tx descriptor header */ - skb_pull(p, D11_PHY_HDR_LEN); - skb_pull(p, D11_TXH_LEN); - ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); - WLCNTINCR(wlc->pub->_cnt->ieee_tx_status); - } else { - WL_ERROR("%s: Not last frame => not calling tx_status\n", - __func__); - } - - return false; - - fatal: - ASSERT(0); - if (p) - pkt_buf_free_skb(osh, p, true); - - return true; - -} - -void BCMFASTPATH -wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend) -{ - TXPKTPENDDEC(wlc, fifo, txpktpend); - WL_TRACE("wlc_txfifo_complete, pktpend dec %d to %d\n", - txpktpend, TXPKTPENDGET(wlc, fifo)); - - /* There is more room; mark precedences related to this FIFO sendable */ - WLC_TX_FIFO_ENAB(wlc, fifo); - ASSERT(TXPKTPENDGET(wlc, fifo) >= 0); - - if (!TXPKTPENDTOT(wlc)) { - if (wlc->block_datafifo & DATA_BLOCK_TX_SUPR) - wlc_bsscfg_tx_check(wlc); - } - - /* Clear MHF2_TXBCMC_NOW flag if BCMC fifo has drained */ - if (AP_ENAB(wlc->pub) && - wlc->bcmcfifo_drain && !TXPKTPENDGET(wlc, TX_BCMC_FIFO)) { - wlc->bcmcfifo_drain = false; - wlc_mhf(wlc, MHF2, MHF2_TXBCMC_NOW, 0, WLC_BAND_AUTO); - } - - /* figure out which bsscfg is being worked on... */ -} - -/* Given the beacon interval in kus, and a 64 bit TSF in us, - * return the offset (in us) of the TSF from the last TBTT - */ -u32 wlc_calc_tbtt_offset(u32 bp, u32 tsf_h, u32 tsf_l) -{ - u32 k, btklo, btkhi, offset; - - /* TBTT is always an even multiple of the beacon_interval, - * so the TBTT less than or equal to the beacon timestamp is - * the beacon timestamp minus the beacon timestamp modulo - * the beacon interval. - * - * TBTT = BT - (BT % BIu) - * = (BTk - (BTk % BP)) * 2^10 - * - * BT = beacon timestamp (usec, 64bits) - * BTk = beacon timestamp (Kusec, 54bits) - * BP = beacon interval (Kusec, 16bits) - * BIu = BP * 2^10 = beacon interval (usec, 26bits) - * - * To keep the calculations in u32s, the modulo operation - * on the high part of BT needs to be done in parts using the - * relations: - * X*Y mod Z = ((X mod Z) * (Y mod Z)) mod Z - * and - * (X + Y) mod Z = ((X mod Z) + (Y mod Z)) mod Z - * - * So, if BTk[n] = u16 n [0,3] of BTk. - * BTk % BP = SUM((BTk[n] * 2^16n) % BP , 0<=n<4) % BP - * and the SUM term can be broken down: - * (BTk[n] * 2^16n) % BP - * (BTk[n] * (2^16n % BP)) % BP - * - * Create a set of power of 2 mod BP constants: - * K[n] = 2^(16n) % BP - * = (K[n-1] * 2^16) % BP - * K[2] = 2^32 % BP = ((2^16 % BP) * 2^16) % BP - * - * BTk % BP = BTk[0-1] % BP + - * (BTk[2] * K[2]) % BP + - * (BTk[3] * K[3]) % BP - * - * Since K[n] < 2^16 and BTk[n] is < 2^16, then BTk[n] * K[n] < 2^32 - */ - - /* BTk = BT >> 10, btklo = BTk[0-3], bkthi = BTk[4-6] */ - btklo = (tsf_h << 22) | (tsf_l >> 10); - btkhi = tsf_h >> 10; - - /* offset = BTk % BP */ - offset = btklo % bp; - - /* K[2] = ((2^16 % BP) * 2^16) % BP */ - k = (u32) (1 << 16) % bp; - k = (u32) (k * 1 << 16) % (u32) bp; - - /* offset += (BTk[2] * K[2]) % BP */ - offset += ((btkhi & 0xffff) * k) % bp; - - /* BTk[3] */ - btkhi = btkhi >> 16; - - /* k[3] = (K[2] * 2^16) % BP */ - k = (k << 16) % bp; - - /* offset += (BTk[3] * K[3]) % BP */ - offset += ((btkhi & 0xffff) * k) % bp; - - offset = offset % bp; - - /* convert offset from kus to us by shifting up 10 bits and - * add in the low 10 bits of tsf that we ignored - */ - offset = (offset << 10) + (tsf_l & 0x3FF); - - return offset; -} - -/* Update beacon listen interval in shared memory */ -void wlc_bcn_li_upd(struct wlc_info *wlc) -{ - if (AP_ENAB(wlc->pub)) - return; - - /* wake up every DTIM is the default */ - if (wlc->bcn_li_dtim == 1) - wlc_write_shm(wlc, M_BCN_LI, 0); - else - wlc_write_shm(wlc, M_BCN_LI, - (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn); -} - -static void -prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, - struct ieee80211_rx_status *rx_status) -{ - u32 tsf_l, tsf_h; - wlc_d11rxhdr_t *wlc_rxh = (wlc_d11rxhdr_t *) rxh; - int preamble; - int channel; - ratespec_t rspec; - unsigned char *plcp; - - wlc_read_tsf(wlc, &tsf_l, &tsf_h); /* mactime */ - rx_status->mactime = tsf_h; - rx_status->mactime <<= 32; - rx_status->mactime |= tsf_l; - rx_status->flag |= RX_FLAG_TSFT; - - channel = WLC_CHAN_CHANNEL(rxh->RxChan); - - /* XXX Channel/badn needs to be filtered against whether we are single/dual band card */ - if (channel > 14) { - rx_status->band = IEEE80211_BAND_5GHZ; - rx_status->freq = ieee80211_ofdm_chan_to_freq( - WF_CHAN_FACTOR_5_G/2, channel); - - } else { - rx_status->band = IEEE80211_BAND_2GHZ; - rx_status->freq = ieee80211_dsss_chan_to_freq(channel); - } - - rx_status->signal = wlc_rxh->rssi; /* signal */ - - /* noise */ - /* qual */ - rx_status->antenna = (rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; /* ant */ - - plcp = p->data; - - rspec = wlc_compute_rspec(rxh, plcp); - if (IS_MCS(rspec)) { - rx_status->rate_idx = rspec & RSPEC_RATE_MASK; - rx_status->flag |= RX_FLAG_HT; - if (RSPEC_IS40MHZ(rspec)) - rx_status->flag |= RX_FLAG_40MHZ; - } else { - switch (RSPEC2RATE(rspec)) { - case WLC_RATE_1M: - rx_status->rate_idx = 0; - break; - case WLC_RATE_2M: - rx_status->rate_idx = 1; - break; - case WLC_RATE_5M5: - rx_status->rate_idx = 2; - break; - case WLC_RATE_11M: - rx_status->rate_idx = 3; - break; - case WLC_RATE_6M: - rx_status->rate_idx = 4; - break; - case WLC_RATE_9M: - rx_status->rate_idx = 5; - break; - case WLC_RATE_12M: - rx_status->rate_idx = 6; - break; - case WLC_RATE_18M: - rx_status->rate_idx = 7; - break; - case WLC_RATE_24M: - rx_status->rate_idx = 8; - break; - case WLC_RATE_36M: - rx_status->rate_idx = 9; - break; - case WLC_RATE_48M: - rx_status->rate_idx = 10; - break; - case WLC_RATE_54M: - rx_status->rate_idx = 11; - break; - default: - WL_ERROR("%s: Unknown rate\n", __func__); - } - - /* Determine short preamble and rate_idx */ - preamble = 0; - if (IS_CCK(rspec)) { - if (rxh->PhyRxStatus_0 & PRXS0_SHORTH) - WL_ERROR("Short CCK\n"); - rx_status->flag |= RX_FLAG_SHORTPRE; - } else if (IS_OFDM(rspec)) { - rx_status->flag |= RX_FLAG_SHORTPRE; - } else { - WL_ERROR("%s: Unknown modulation\n", __func__); - } - } - - if (PLCP3_ISSGI(plcp[3])) - rx_status->flag |= RX_FLAG_SHORT_GI; - - if (rxh->RxStatus1 & RXS_DECERR) { - rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC; - WL_ERROR("%s: RX_FLAG_FAILED_PLCP_CRC\n", __func__); - } - if (rxh->RxStatus1 & RXS_FCSERR) { - rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; - WL_ERROR("%s: RX_FLAG_FAILED_FCS_CRC\n", __func__); - } -} - -static void -wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, d11rxhdr_t *rxh, - struct sk_buff *p) -{ - int len_mpdu; - struct ieee80211_rx_status rx_status; -#if defined(BCMDBG) - struct sk_buff *skb = p; -#endif /* BCMDBG */ - /* Todo: - * Cache plcp for first MPDU of AMPD and use chacched version for INTERMEDIATE. - * Test for INTERMEDIATE like so: - * if (!(plcp[0] | plcp[1] | plcp[2])) - */ - - memset(&rx_status, 0, sizeof(rx_status)); - prep_mac80211_status(wlc, rxh, p, &rx_status); - - /* mac header+body length, exclude CRC and plcp header */ - len_mpdu = p->len - D11_PHY_HDR_LEN - FCS_LEN; - skb_pull(p, D11_PHY_HDR_LEN); - __skb_trim(p, len_mpdu); - - ASSERT(!(p->next)); - ASSERT(!(p->prev)); - - ASSERT(IS_ALIGNED((unsigned long)skb->data, 2)); - - memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status)); - ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p); - - WLCNTINCR(wlc->pub->_cnt->ieee_rx); - osh->pktalloced--; - return; -} - -void wlc_bss_list_free(struct wlc_info *wlc, wlc_bss_list_t *bss_list) -{ - uint index; - wlc_bss_info_t *bi; - - if (!bss_list) { - WL_ERROR("%s: Attempting to free NULL list\n", __func__); - return; - } - /* inspect all BSS descriptor */ - for (index = 0; index < bss_list->count; index++) { - bi = bss_list->ptrs[index]; - if (bi) { - kfree(bi); - bss_list->ptrs[index] = NULL; - } - } - bss_list->count = 0; -} - -/* Process received frames */ -/* - * Return true if more frames need to be processed. false otherwise. - * Param 'bound' indicates max. # frames to process before break out. - */ -/* WLC_HIGH_API */ -void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) -{ - d11rxhdr_t *rxh; - struct ieee80211_hdr *h; - struct osl_info *osh; - u16 fc; - uint len; - bool is_amsdu; - - WL_TRACE("wl%d: wlc_recv\n", wlc->pub->unit); - - osh = wlc->osh; - - /* frame starts with rxhdr */ - rxh = (d11rxhdr_t *) (p->data); - - /* strip off rxhdr */ - skb_pull(p, wlc->hwrxoff); - - /* fixup rx header endianness */ - ltoh16_buf((void *)rxh, sizeof(d11rxhdr_t)); - - /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ - if (rxh->RxStatus1 & RXS_PBPRES) { - if (p->len < 2) { - WLCNTINCR(wlc->pub->_cnt->rxrunt); - WL_ERROR("wl%d: wlc_recv: rcvd runt of len %d\n", - wlc->pub->unit, p->len); - goto toss; - } - skb_pull(p, 2); - } - - h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN); - len = p->len; - - if (rxh->RxStatus1 & RXS_FCSERR) { - if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) { - WL_ERROR("FCSERR while scanning******* - tossing\n"); - goto toss; - } else { - WL_ERROR("RCSERR!!!\n"); - goto toss; - } - } - - /* check received pkt has at least frame control field */ - if (len >= D11_PHY_HDR_LEN + sizeof(h->frame_control)) { - fc = ltoh16(h->frame_control); - } else { - WLCNTINCR(wlc->pub->_cnt->rxrunt); - goto toss; - } - - is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK; - - /* explicitly test bad src address to avoid sending bad deauth */ - if (!is_amsdu) { - /* CTS and ACK CTL frames are w/o a2 */ - if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA || - (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { - if ((is_zero_ether_addr(h->addr2) || - is_multicast_ether_addr(h->addr2))) { - WL_ERROR("wl%d: %s: dropping a frame with " - "invalid src mac address, a2: %pM\n", - wlc->pub->unit, __func__, h->addr2); - WLCNTINCR(wlc->pub->_cnt->rxbadsrcmac); - goto toss; - } - WLCNTINCR(wlc->pub->_cnt->rxfrag); - } - } - - /* due to sheer numbers, toss out probe reqs for now */ - if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { - if ((fc & FC_KIND_MASK) == FC_PROBE_REQ) - goto toss; - } - - if (is_amsdu) { - WL_ERROR("%s: is_amsdu causing toss\n", __func__); - goto toss; - } - - wlc_recvctl(wlc, osh, rxh, p); - return; - - toss: - pkt_buf_free_skb(osh, p, false); -} - -/* calculate frame duration for Mixed-mode L-SIG spoofing, return - * number of bytes goes in the length field - * - * Formula given by HT PHY Spec v 1.13 - * len = 3(nsyms + nstream + 3) - 3 - */ -u16 BCMFASTPATH -wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, uint mac_len) -{ - uint nsyms, len = 0, kNdps; - - WL_TRACE("wl%d: wlc_calc_lsig_len: rate %d, len%d\n", - wlc->pub->unit, RSPEC2RATE(ratespec), mac_len); - - if (IS_MCS(ratespec)) { - uint mcs = ratespec & RSPEC_RATE_MASK; - /* MCS_TXS(mcs) returns num tx streams - 1 */ - int tot_streams = (MCS_TXS(mcs) + 1) + RSPEC_STC(ratespec); - - ASSERT(WLC_PHY_11N_CAP(wlc->band)); - /* the payload duration calculation matches that of regular ofdm */ - /* 1000Ndbps = kbps * 4 */ - kNdps = - MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec), - RSPEC_ISSGI(ratespec)) * 4; - - if (RSPEC_STC(ratespec) == 0) - /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ - nsyms = - CEIL((APHY_SERVICE_NBITS + 8 * mac_len + - APHY_TAIL_NBITS) * 1000, kNdps); - else - /* STBC needs to have even number of symbols */ - nsyms = - 2 * - CEIL((APHY_SERVICE_NBITS + 8 * mac_len + - APHY_TAIL_NBITS) * 1000, 2 * kNdps); - - nsyms += (tot_streams + 3); /* (+3) account for HT-SIG(2) and HT-STF(1) */ - /* 3 bytes/symbol @ legacy 6Mbps rate */ - len = (3 * nsyms) - 3; /* (-3) excluding service bits and tail bits */ - } - - return (u16) len; -} - -/* calculate frame duration of a given rate and length, return time in usec unit */ -uint BCMFASTPATH -wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, - uint mac_len) -{ - uint nsyms, dur = 0, Ndps, kNdps; - uint rate = RSPEC2RATE(ratespec); - - if (rate == 0) { - ASSERT(0); - WL_ERROR("wl%d: WAR: using rate of 1 mbps\n", wlc->pub->unit); - rate = WLC_RATE_1M; - } - - WL_TRACE("wl%d: wlc_calc_frame_time: rspec 0x%x, preamble_type %d, len%d\n", - wlc->pub->unit, ratespec, preamble_type, mac_len); - - if (IS_MCS(ratespec)) { - uint mcs = ratespec & RSPEC_RATE_MASK; - int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec); - ASSERT(WLC_PHY_11N_CAP(wlc->band)); - ASSERT(WLC_IS_MIMO_PREAMBLE(preamble_type)); - - dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT); - if (preamble_type == WLC_MM_PREAMBLE) - dur += PREN_MM_EXT; - /* 1000Ndbps = kbps * 4 */ - kNdps = - MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec), - RSPEC_ISSGI(ratespec)) * 4; - - if (RSPEC_STC(ratespec) == 0) - /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ - nsyms = - CEIL((APHY_SERVICE_NBITS + 8 * mac_len + - APHY_TAIL_NBITS) * 1000, kNdps); - else - /* STBC needs to have even number of symbols */ - nsyms = - 2 * - CEIL((APHY_SERVICE_NBITS + 8 * mac_len + - APHY_TAIL_NBITS) * 1000, 2 * kNdps); - - dur += APHY_SYMBOL_TIME * nsyms; - if (BAND_2G(wlc->band->bandtype)) - dur += DOT11_OFDM_SIGNAL_EXTENSION; - } else if (IS_OFDM(rate)) { - dur = APHY_PREAMBLE_TIME; - dur += APHY_SIGNAL_TIME; - /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */ - Ndps = rate * 2; - /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ - nsyms = - CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS), - Ndps); - dur += APHY_SYMBOL_TIME * nsyms; - if (BAND_2G(wlc->band->bandtype)) - dur += DOT11_OFDM_SIGNAL_EXTENSION; - } else { - /* calc # bits * 2 so factor of 2 in rate (1/2 mbps) will divide out */ - mac_len = mac_len * 8 * 2; - /* calc ceiling of bits/rate = microseconds of air time */ - dur = (mac_len + rate - 1) / rate; - if (preamble_type & WLC_SHORT_PREAMBLE) - dur += BPHY_PLCP_SHORT_TIME; - else - dur += BPHY_PLCP_TIME; - } - return dur; -} - -/* The opposite of wlc_calc_frame_time */ -static uint -wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, - uint dur) -{ - uint nsyms, mac_len, Ndps, kNdps; - uint rate = RSPEC2RATE(ratespec); - - WL_TRACE("wl%d: wlc_calc_frame_len: rspec 0x%x, preamble_type %d, dur %d\n", - wlc->pub->unit, ratespec, preamble_type, dur); - - if (IS_MCS(ratespec)) { - uint mcs = ratespec & RSPEC_RATE_MASK; - int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec); - ASSERT(WLC_PHY_11N_CAP(wlc->band)); - dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT); - /* payload calculation matches that of regular ofdm */ - if (BAND_2G(wlc->band->bandtype)) - dur -= DOT11_OFDM_SIGNAL_EXTENSION; - /* kNdbps = kbps * 4 */ - kNdps = - MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec), - RSPEC_ISSGI(ratespec)) * 4; - nsyms = dur / APHY_SYMBOL_TIME; - mac_len = - ((nsyms * kNdps) - - ((APHY_SERVICE_NBITS + APHY_TAIL_NBITS) * 1000)) / 8000; - } else if (IS_OFDM(ratespec)) { - dur -= APHY_PREAMBLE_TIME; - dur -= APHY_SIGNAL_TIME; - /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */ - Ndps = rate * 2; - nsyms = dur / APHY_SYMBOL_TIME; - mac_len = - ((nsyms * Ndps) - - (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8; - } else { - if (preamble_type & WLC_SHORT_PREAMBLE) - dur -= BPHY_PLCP_SHORT_TIME; - else - dur -= BPHY_PLCP_TIME; - mac_len = dur * rate; - /* divide out factor of 2 in rate (1/2 mbps) */ - mac_len = mac_len / 8 / 2; - } - return mac_len; -} - -static uint -wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) -{ - WL_TRACE("wl%d: wlc_calc_ba_time: rspec 0x%x, preamble_type %d\n", - wlc->pub->unit, rspec, preamble_type); - /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than - * or equal to the rate of the immediately previous frame in the FES - */ - rspec = WLC_BASIC_RATE(wlc, rspec); - ASSERT(VALID_RATE_DBG(wlc, rspec)); - - /* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */ - return wlc_calc_frame_time(wlc, rspec, preamble_type, - (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN + - FCS_LEN)); -} - -static uint BCMFASTPATH -wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) -{ - uint dur = 0; - - WL_TRACE("wl%d: wlc_calc_ack_time: rspec 0x%x, preamble_type %d\n", - wlc->pub->unit, rspec, preamble_type); - /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than - * or equal to the rate of the immediately previous frame in the FES - */ - rspec = WLC_BASIC_RATE(wlc, rspec); - ASSERT(VALID_RATE_DBG(wlc, rspec)); - - /* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */ - dur = - wlc_calc_frame_time(wlc, rspec, preamble_type, - (DOT11_ACK_LEN + FCS_LEN)); - return dur; -} - -static uint -wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) -{ - WL_TRACE("wl%d: wlc_calc_cts_time: ratespec 0x%x, preamble_type %d\n", - wlc->pub->unit, rspec, preamble_type); - return wlc_calc_ack_time(wlc, rspec, preamble_type); -} - -/* derive wlc->band->basic_rate[] table from 'rateset' */ -void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset) -{ - u8 rate; - u8 mandatory; - u8 cck_basic = 0; - u8 ofdm_basic = 0; - u8 *br = wlc->band->basic_rate; - uint i; - - /* incoming rates are in 500kbps units as in 802.11 Supported Rates */ - memset(br, 0, WLC_MAXRATE + 1); - - /* For each basic rate in the rates list, make an entry in the - * best basic lookup. - */ - for (i = 0; i < rateset->count; i++) { - /* only make an entry for a basic rate */ - if (!(rateset->rates[i] & WLC_RATE_FLAG)) - continue; - - /* mask off basic bit */ - rate = (rateset->rates[i] & RATE_MASK); - - if (rate > WLC_MAXRATE) { - WL_ERROR("wlc_rate_lookup_init: invalid rate 0x%X in rate set\n", - rateset->rates[i]); - continue; - } - - br[rate] = rate; - } - - /* The rate lookup table now has non-zero entries for each - * basic rate, equal to the basic rate: br[basicN] = basicN - * - * To look up the best basic rate corresponding to any - * particular rate, code can use the basic_rate table - * like this - * - * basic_rate = wlc->band->basic_rate[tx_rate] - * - * Make sure there is a best basic rate entry for - * every rate by walking up the table from low rates - * to high, filling in holes in the lookup table - */ - - for (i = 0; i < wlc->band->hw_rateset.count; i++) { - rate = wlc->band->hw_rateset.rates[i]; - ASSERT(rate <= WLC_MAXRATE); - - if (br[rate] != 0) { - /* This rate is a basic rate. - * Keep track of the best basic rate so far by - * modulation type. - */ - if (IS_OFDM(rate)) - ofdm_basic = rate; - else - cck_basic = rate; - - continue; - } - - /* This rate is not a basic rate so figure out the - * best basic rate less than this rate and fill in - * the hole in the table - */ - - br[rate] = IS_OFDM(rate) ? ofdm_basic : cck_basic; - - if (br[rate] != 0) - continue; - - if (IS_OFDM(rate)) { - /* In 11g and 11a, the OFDM mandatory rates are 6, 12, and 24 Mbps */ - if (rate >= WLC_RATE_24M) - mandatory = WLC_RATE_24M; - else if (rate >= WLC_RATE_12M) - mandatory = WLC_RATE_12M; - else - mandatory = WLC_RATE_6M; - } else { - /* In 11b, all the CCK rates are mandatory 1 - 11 Mbps */ - mandatory = rate; - } - - br[rate] = mandatory; - } -} - -static void wlc_write_rate_shm(struct wlc_info *wlc, u8 rate, u8 basic_rate) -{ - u8 phy_rate, index; - u8 basic_phy_rate, basic_index; - u16 dir_table, basic_table; - u16 basic_ptr; - - /* Shared memory address for the table we are reading */ - dir_table = IS_OFDM(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B; - - /* Shared memory address for the table we are writing */ - basic_table = IS_OFDM(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B; - - /* - * for a given rate, the LS-nibble of the PLCP SIGNAL field is - * the index into the rate table. - */ - phy_rate = rate_info[rate] & RATE_MASK; - basic_phy_rate = rate_info[basic_rate] & RATE_MASK; - index = phy_rate & 0xf; - basic_index = basic_phy_rate & 0xf; - - /* Find the SHM pointer to the ACK rate entry by looking in the - * Direct-map Table - */ - basic_ptr = wlc_read_shm(wlc, (dir_table + basic_index * 2)); - - /* Update the SHM BSS-basic-rate-set mapping table with the pointer - * to the correct basic rate for the given incoming rate - */ - wlc_write_shm(wlc, (basic_table + index * 2), basic_ptr); -} - -static const wlc_rateset_t *wlc_rateset_get_hwrs(struct wlc_info *wlc) -{ - const wlc_rateset_t *rs_dflt; - - if (WLC_PHY_11N_CAP(wlc->band)) { - if (BAND_5G(wlc->band->bandtype)) - rs_dflt = &ofdm_mimo_rates; - else - rs_dflt = &cck_ofdm_mimo_rates; - } else if (wlc->band->gmode) - rs_dflt = &cck_ofdm_rates; - else - rs_dflt = &cck_rates; - - return rs_dflt; -} - -void wlc_set_ratetable(struct wlc_info *wlc) -{ - const wlc_rateset_t *rs_dflt; - wlc_rateset_t rs; - u8 rate, basic_rate; - uint i; - - rs_dflt = wlc_rateset_get_hwrs(wlc); - ASSERT(rs_dflt != NULL); - - wlc_rateset_copy(rs_dflt, &rs); - wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams); - - /* walk the phy rate table and update SHM basic rate lookup table */ - for (i = 0; i < rs.count; i++) { - rate = rs.rates[i] & RATE_MASK; - - /* for a given rate WLC_BASIC_RATE returns the rate at - * which a response ACK/CTS should be sent. - */ - basic_rate = WLC_BASIC_RATE(wlc, rate); - if (basic_rate == 0) { - /* This should only happen if we are using a - * restricted rateset. - */ - basic_rate = rs.rates[0] & RATE_MASK; - } - - wlc_write_rate_shm(wlc, rate, basic_rate); - } -} - -/* - * Return true if the specified rate is supported by the specified band. - * WLC_BAND_AUTO indicates the current band. - */ -bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rspec, int band, - bool verbose) -{ - wlc_rateset_t *hw_rateset; - uint i; - - if ((band == WLC_BAND_AUTO) || (band == wlc->band->bandtype)) { - hw_rateset = &wlc->band->hw_rateset; - } else if (NBANDS(wlc) > 1) { - hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset; - } else { - /* other band specified and we are a single band device */ - return false; - } - - /* check if this is a mimo rate */ - if (IS_MCS(rspec)) { - if (!VALID_MCS((rspec & RSPEC_RATE_MASK))) - goto error; - - return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK)); - } - - for (i = 0; i < hw_rateset->count; i++) - if (hw_rateset->rates[i] == RSPEC2RATE(rspec)) - return true; - error: - if (verbose) { - WL_ERROR("wl%d: wlc_valid_rate: rate spec 0x%x not in hw_rateset\n", - wlc->pub->unit, rspec); - } - - return false; -} - -static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap) -{ - uint i; - struct wlcband *band; - - for (i = 0; i < NBANDS(wlc); i++) { - if (IS_SINGLEBAND_5G(wlc->deviceid)) - i = BAND_5G_INDEX; - band = wlc->bandstate[i]; - if (band->bandtype == WLC_BAND_5G) { - if ((bwcap == WLC_N_BW_40ALL) - || (bwcap == WLC_N_BW_20IN2G_40IN5G)) - band->mimo_cap_40 = true; - else - band->mimo_cap_40 = false; - } else { - ASSERT(band->bandtype == WLC_BAND_2G); - if (bwcap == WLC_N_BW_40ALL) - band->mimo_cap_40 = true; - else - band->mimo_cap_40 = false; - } - } - - wlc->mimo_band_bwcap = bwcap; -} - -void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len) -{ - const wlc_rateset_t *rs_dflt; - wlc_rateset_t rs; - u8 rate; - u16 entry_ptr; - u8 plcp[D11_PHY_HDR_LEN]; - u16 dur, sifs; - uint i; - - sifs = SIFS(wlc->band); - - rs_dflt = wlc_rateset_get_hwrs(wlc); - ASSERT(rs_dflt != NULL); - - wlc_rateset_copy(rs_dflt, &rs); - wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams); - - /* walk the phy rate table and update MAC core SHM basic rate table entries */ - for (i = 0; i < rs.count; i++) { - rate = rs.rates[i] & RATE_MASK; - - entry_ptr = wlc_rate_shm_offset(wlc, rate); - - /* Calculate the Probe Response PLCP for the given rate */ - wlc_compute_plcp(wlc, rate, frame_len, plcp); - - /* Calculate the duration of the Probe Response frame plus SIFS for the MAC */ - dur = - (u16) wlc_calc_frame_time(wlc, rate, WLC_LONG_PREAMBLE, - frame_len); - dur += sifs; - - /* Update the SHM Rate Table entry Probe Response values */ - wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS, - (u16) (plcp[0] + (plcp[1] << 8))); - wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS + 2, - (u16) (plcp[2] + (plcp[3] << 8))); - wlc_write_shm(wlc, entry_ptr + M_RT_PRS_DUR_POS, dur); - } -} - -u16 -wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec, - bool short_preamble, bool phydelay) -{ - uint bcntsfoff = 0; - - if (IS_MCS(rspec)) { - WL_ERROR("wl%d: recd beacon with mcs rate; rspec 0x%x\n", - wlc->pub->unit, rspec); - } else if (IS_OFDM(rspec)) { - /* tx delay from MAC through phy to air (2.1 usec) + - * phy header time (preamble + PLCP SIGNAL == 20 usec) + - * PLCP SERVICE + MAC header time (SERVICE + FC + DUR + A1 + A2 + A3 + SEQ == 26 - * bytes at beacon rate) - */ - bcntsfoff += phydelay ? D11A_PHY_TX_DELAY : 0; - bcntsfoff += APHY_PREAMBLE_TIME + APHY_SIGNAL_TIME; - bcntsfoff += - wlc_compute_airtime(wlc, rspec, - APHY_SERVICE_NBITS / 8 + - DOT11_MAC_HDR_LEN); - } else { - /* tx delay from MAC through phy to air (3.4 usec) + - * phy header time (long preamble + PLCP == 192 usec) + - * MAC header time (FC + DUR + A1 + A2 + A3 + SEQ == 24 bytes at beacon rate) - */ - bcntsfoff += phydelay ? D11B_PHY_TX_DELAY : 0; - bcntsfoff += - short_preamble ? D11B_PHY_SPREHDR_TIME : - D11B_PHY_LPREHDR_TIME; - bcntsfoff += wlc_compute_airtime(wlc, rspec, DOT11_MAC_HDR_LEN); - } - return (u16) (bcntsfoff); -} - -/* Max buffering needed for beacon template/prb resp template is 142 bytes. - * - * PLCP header is 6 bytes. - * 802.11 A3 header is 24 bytes. - * Max beacon frame body template length is 112 bytes. - * Max probe resp frame body template length is 110 bytes. - * - * *len on input contains the max length of the packet available. - * - * The *len value is set to the number of bytes in buf used, and starts with the PLCP - * and included up to, but not including, the 4 byte FCS. - */ -static void -wlc_bcn_prb_template(struct wlc_info *wlc, uint type, ratespec_t bcn_rspec, - wlc_bsscfg_t *cfg, u16 *buf, int *len) -{ - static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; - cck_phy_hdr_t *plcp; - struct ieee80211_mgmt *h; - int hdr_len, body_len; - - ASSERT(*len >= 142); - ASSERT(type == FC_BEACON || type == FC_PROBE_RESP); - - if (MBSS_BCN_ENAB(cfg) && type == FC_BEACON) - hdr_len = DOT11_MAC_HDR_LEN; - else - hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN; - body_len = *len - hdr_len; /* calc buffer size provided for frame body */ - - *len = hdr_len + body_len; /* return actual size */ - - /* format PHY and MAC headers */ - memset((char *)buf, 0, hdr_len); - - plcp = (cck_phy_hdr_t *) buf; - - /* PLCP for Probe Response frames are filled in from core's rate table */ - if (type == FC_BEACON && !MBSS_BCN_ENAB(cfg)) { - /* fill in PLCP */ - wlc_compute_plcp(wlc, bcn_rspec, - (DOT11_MAC_HDR_LEN + body_len + FCS_LEN), - (u8 *) plcp); - - } - /* "Regular" and 16 MBSS but not for 4 MBSS */ - /* Update the phytxctl for the beacon based on the rspec */ - if (!SOFTBCN_ENAB(cfg)) - wlc_beacon_phytxctl_txant_upd(wlc, bcn_rspec); - - if (MBSS_BCN_ENAB(cfg) && type == FC_BEACON) - h = (struct ieee80211_mgmt *)&plcp[0]; - else - h = (struct ieee80211_mgmt *)&plcp[1]; - - /* fill in 802.11 header */ - h->frame_control = htol16((u16) type); - - /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */ - /* A1 filled in by MAC for prb resp, broadcast for bcn */ - if (type == FC_BEACON) - bcopy((const char *)ðer_bcast, (char *)&h->da, - ETH_ALEN); - bcopy((char *)&cfg->cur_etheraddr, (char *)&h->sa, ETH_ALEN); - bcopy((char *)&cfg->BSSID, (char *)&h->bssid, ETH_ALEN); - - /* SEQ filled in by MAC */ - - return; -} - -int wlc_get_header_len() -{ - return TXOFF; -} - -/* Update a beacon for a particular BSS - * For MBSS, this updates the software template and sets "latest" to the index of the - * template updated. - * Otherwise, it updates the hardware template. - */ -void wlc_bss_update_beacon(struct wlc_info *wlc, wlc_bsscfg_t *cfg) -{ - int len = BCN_TMPL_LEN; - - /* Clear the soft intmask */ - wlc->defmacintmask &= ~MI_BCNTPL; - - if (!cfg->up) { /* Only allow updates on an UP bss */ - return; - } - - if (MBSS_BCN_ENAB(cfg)) { /* Optimize: Some of if/else could be combined */ - } else if (HWBCN_ENAB(cfg)) { /* Hardware beaconing for this config */ - u16 bcn[BCN_TMPL_LEN / 2]; - u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD; - d11regs_t *regs = wlc->regs; - struct osl_info *osh = NULL; - - osh = wlc->osh; - - /* Check if both templates are in use, if so sched. an interrupt - * that will call back into this routine - */ - if ((R_REG(osh, ®s->maccommand) & both_valid) == both_valid) { - /* clear any previous status */ - W_REG(osh, ®s->macintstatus, MI_BCNTPL); - } - /* Check that after scheduling the interrupt both of the - * templates are still busy. if not clear the int. & remask - */ - if ((R_REG(osh, ®s->maccommand) & both_valid) == both_valid) { - wlc->defmacintmask |= MI_BCNTPL; - return; - } - - wlc->bcn_rspec = - wlc_lowest_basic_rspec(wlc, &cfg->current_bss->rateset); - ASSERT(wlc_valid_rate - (wlc, wlc->bcn_rspec, - CHSPEC_IS2G(cfg->current_bss-> - chanspec) ? WLC_BAND_2G : WLC_BAND_5G, - true)); - - /* update the template and ucode shm */ - wlc_bcn_prb_template(wlc, FC_BEACON, wlc->bcn_rspec, cfg, bcn, - &len); - wlc_write_hw_bcntemplates(wlc, bcn, len, false); - } -} - -/* - * Update all beacons for the system. - */ -void wlc_update_beacon(struct wlc_info *wlc) -{ - int idx; - wlc_bsscfg_t *bsscfg; - - /* update AP or IBSS beacons */ - FOREACH_BSS(wlc, idx, bsscfg) { - if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS)) - wlc_bss_update_beacon(wlc, bsscfg); - } -} - -/* Write ssid into shared memory */ -void wlc_shm_ssid_upd(struct wlc_info *wlc, wlc_bsscfg_t *cfg) -{ - u8 *ssidptr = cfg->SSID; - u16 base = M_SSID; - u8 ssidbuf[IEEE80211_MAX_SSID_LEN]; - - /* padding the ssid with zero and copy it into shm */ - memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN); - bcopy(ssidptr, ssidbuf, cfg->SSID_len); - - wlc_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN); - - if (!MBSS_BCN_ENAB(cfg)) - wlc_write_shm(wlc, M_SSIDLEN, (u16) cfg->SSID_len); -} - -void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend) -{ - int idx; - wlc_bsscfg_t *bsscfg; - - /* update AP or IBSS probe responses */ - FOREACH_BSS(wlc, idx, bsscfg) { - if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS)) - wlc_bss_update_probe_resp(wlc, bsscfg, suspend); - } -} - -void -wlc_bss_update_probe_resp(struct wlc_info *wlc, wlc_bsscfg_t *cfg, bool suspend) -{ - u16 prb_resp[BCN_TMPL_LEN / 2]; - int len = BCN_TMPL_LEN; - - /* write the probe response to hardware, or save in the config structure */ - if (!MBSS_PRB_ENAB(cfg)) { - - /* create the probe response template */ - wlc_bcn_prb_template(wlc, FC_PROBE_RESP, 0, cfg, prb_resp, - &len); - - if (suspend) - wlc_suspend_mac_and_wait(wlc); - - /* write the probe response into the template region */ - wlc_bmac_write_template_ram(wlc->hw, T_PRS_TPL_BASE, - (len + 3) & ~3, prb_resp); - - /* write the length of the probe response frame (+PLCP/-FCS) */ - wlc_write_shm(wlc, M_PRB_RESP_FRM_LEN, (u16) len); - - /* write the SSID and SSID length */ - wlc_shm_ssid_upd(wlc, cfg); - - /* - * Write PLCP headers and durations for probe response frames at all rates. - * Use the actual frame length covered by the PLCP header for the call to - * wlc_mod_prb_rsp_rate_table() by subtracting the PLCP len and adding the FCS. - */ - len += (-D11_PHY_HDR_LEN + FCS_LEN); - wlc_mod_prb_rsp_rate_table(wlc, (u16) len); - - if (suspend) - wlc_enable_mac(wlc); - } else { /* Generating probe resp in sw; update local template */ - ASSERT(0 && "No software probe response support without MBSS"); - } -} - -/* prepares pdu for transmission. returns BCM error codes */ -int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) -{ - struct osl_info *osh; - uint fifo; - d11txh_t *txh; - struct ieee80211_hdr *h; - struct scb *scb; - u16 fc; - - osh = wlc->osh; - - ASSERT(pdu); - txh = (d11txh_t *) (pdu->data); - ASSERT(txh); - h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); - ASSERT(h); - fc = ltoh16(h->frame_control); - - /* get the pkt queue info. This was put at wlc_sendctl or wlc_send for PDU */ - fifo = ltoh16(txh->TxFrameID) & TXFID_QUEUE_MASK; - - scb = NULL; - - *fifop = fifo; - - /* return if insufficient dma resources */ - if (TXAVAIL(wlc, fifo) < MAX_DMA_SEGS) { - /* Mark precedences related to this FIFO, unsendable */ - WLC_TX_FIFO_CLEAR(wlc, fifo); - return BCME_BUSY; - } - - if ((ltoh16(txh->MacFrameControl) & IEEE80211_FCTL_FTYPE) != - IEEE80211_FTYPE_DATA) - WLCNTINCR(wlc->pub->_cnt->txctl); - - return 0; -} - -/* init tx reported rate mechanism */ -void wlc_reprate_init(struct wlc_info *wlc) -{ - int i; - wlc_bsscfg_t *bsscfg; - - FOREACH_BSS(wlc, i, bsscfg) { - wlc_bsscfg_reprate_init(bsscfg); - } -} - -/* per bsscfg init tx reported rate mechanism */ -void wlc_bsscfg_reprate_init(wlc_bsscfg_t *bsscfg) -{ - bsscfg->txrspecidx = 0; - memset((char *)bsscfg->txrspec, 0, sizeof(bsscfg->txrspec)); -} - -/* Retrieve a consolidated set of revision information, - * typically for the WLC_GET_REVINFO ioctl - */ -int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len) -{ - wlc_rev_info_t *rinfo = (wlc_rev_info_t *) buf; - - if (len < WL_REV_INFO_LEGACY_LENGTH) - return BCME_BUFTOOSHORT; - - rinfo->vendorid = wlc->vendorid; - rinfo->deviceid = wlc->deviceid; - rinfo->radiorev = (wlc->band->radiorev << IDCODE_REV_SHIFT) | - (wlc->band->radioid << IDCODE_ID_SHIFT); - rinfo->chiprev = wlc->pub->sih->chiprev; - rinfo->corerev = wlc->pub->corerev; - rinfo->boardid = wlc->pub->sih->boardtype; - rinfo->boardvendor = wlc->pub->sih->boardvendor; - rinfo->boardrev = wlc->pub->boardrev; - rinfo->ucoderev = wlc->ucode_rev; - rinfo->driverrev = EPI_VERSION_NUM; - rinfo->bus = wlc->pub->sih->bustype; - rinfo->chipnum = wlc->pub->sih->chip; - - if (len >= (offsetof(wlc_rev_info_t, chippkg))) { - rinfo->phytype = wlc->band->phytype; - rinfo->phyrev = wlc->band->phyrev; - rinfo->anarev = 0; /* obsolete stuff, suppress */ - } - - if (len >= sizeof(*rinfo)) { - rinfo->chippkg = wlc->pub->sih->chippkg; - } - - return BCME_OK; -} - -void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs) -{ - wlc_rateset_default(rs, NULL, wlc->band->phytype, wlc->band->bandtype, - false, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub), - CHSPEC_WLC_BW(wlc->default_bss->chanspec), - wlc->stf->txstreams); -} - -static void wlc_bss_default_init(struct wlc_info *wlc) -{ - chanspec_t chanspec; - struct wlcband *band; - wlc_bss_info_t *bi = wlc->default_bss; - - /* init default and target BSS with some sane initial values */ - memset((char *)(bi), 0, sizeof(wlc_bss_info_t)); - bi->beacon_period = ISSIM_ENAB(wlc->pub->sih) ? BEACON_INTERVAL_DEF_QT : - BEACON_INTERVAL_DEFAULT; - bi->dtim_period = ISSIM_ENAB(wlc->pub->sih) ? DTIM_INTERVAL_DEF_QT : - DTIM_INTERVAL_DEFAULT; - - /* fill the default channel as the first valid channel - * starting from the 2G channels - */ - chanspec = CH20MHZ_CHSPEC(1); - ASSERT(chanspec != INVCHANSPEC); - - wlc->home_chanspec = bi->chanspec = chanspec; - - /* find the band of our default channel */ - band = wlc->band; - if (NBANDS(wlc) > 1 && band->bandunit != CHSPEC_WLCBANDUNIT(chanspec)) - band = wlc->bandstate[OTHERBANDUNIT(wlc)]; - - /* init bss rates to the band specific default rate set */ - wlc_rateset_default(&bi->rateset, NULL, band->phytype, band->bandtype, - false, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub), - CHSPEC_WLC_BW(chanspec), wlc->stf->txstreams); - - if (N_ENAB(wlc->pub)) - bi->flags |= WLC_BSS_HT; -} - -/* Deferred event processing */ -static void wlc_process_eventq(void *arg) -{ - struct wlc_info *wlc = (struct wlc_info *) arg; - wlc_event_t *etmp; - - while ((etmp = wlc_eventq_deq(wlc->eventq))) { - /* Perform OS specific event processing */ - wl_event(wlc->wl, etmp->event.ifname, etmp); - if (etmp->data) { - kfree(etmp->data); - etmp->data = NULL; - } - wlc_event_free(wlc->eventq, etmp); - } -} - -void -wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, u32 b_low) -{ - if (b_low > *a_low) { - /* low half needs a carry */ - b_high += 1; - } - *a_low -= b_low; - *a_high -= b_high; -} - -static ratespec_t -mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, - u32 int_val) -{ - u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT; - u8 rate = int_val & NRATE_RATE_MASK; - ratespec_t rspec; - bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE); - bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT); - bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY) - == NRATE_OVERRIDE_MCS_ONLY); - int bcmerror = 0; - - if (!ismcs) { - return (ratespec_t) rate; - } - - /* validate the combination of rate/mcs/stf is allowed */ - if (N_ENAB(wlc->pub) && ismcs) { - /* mcs only allowed when nmode */ - if (stf > PHY_TXC1_MODE_SDM) { - WL_ERROR("wl%d: %s: Invalid stf\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - - /* mcs 32 is a special case, DUP mode 40 only */ - if (rate == 32) { - if (!CHSPEC_IS40(wlc->home_chanspec) || - ((stf != PHY_TXC1_MODE_SISO) - && (stf != PHY_TXC1_MODE_CDD))) { - WL_ERROR("wl%d: %s: Invalid mcs 32\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - /* mcs > 7 must use stf SDM */ - } else if (rate > HIGHEST_SINGLE_STREAM_MCS) { - /* mcs > 7 must use stf SDM */ - if (stf != PHY_TXC1_MODE_SDM) { - WL_TRACE("wl%d: %s: enabling SDM mode for mcs %d\n", - WLCWLUNIT(wlc), __func__, rate); - stf = PHY_TXC1_MODE_SDM; - } - } else { - /* MCS 0-7 may use SISO, CDD, and for phy_rev >= 3 STBC */ - if ((stf > PHY_TXC1_MODE_STBC) || - (!WLC_STBC_CAP_PHY(wlc) - && (stf == PHY_TXC1_MODE_STBC))) { - WL_ERROR("wl%d: %s: Invalid STBC\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - } - } else if (IS_OFDM(rate)) { - if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) { - WL_ERROR("wl%d: %s: Invalid OFDM\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - } else if (IS_CCK(rate)) { - if ((cur_band->bandtype != WLC_BAND_2G) - || (stf != PHY_TXC1_MODE_SISO)) { - WL_ERROR("wl%d: %s: Invalid CCK\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - } else { - WL_ERROR("wl%d: %s: Unknown rate type\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - /* make sure multiple antennae are available for non-siso rates */ - if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) { - WL_ERROR("wl%d: %s: SISO antenna but !SISO request\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - - rspec = rate; - if (ismcs) { - rspec |= RSPEC_MIMORATE; - /* For STBC populate the STC field of the ratespec */ - if (stf == PHY_TXC1_MODE_STBC) { - u8 stc; - stc = 1; /* Nss for single stream is always 1 */ - rspec |= (stc << RSPEC_STC_SHIFT); - } - } - - rspec |= (stf << RSPEC_STF_SHIFT); - - if (override_mcs_only) - rspec |= RSPEC_OVERRIDE_MCS_ONLY; - - if (issgi) - rspec |= RSPEC_SHORT_GI; - - if ((rate != 0) - && !wlc_valid_rate(wlc, rspec, cur_band->bandtype, true)) { - return rate; - } - - return rspec; - done: - WL_ERROR("Hoark\n"); - return rate; -} - -/* formula: IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */ -static int -wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, - bool writeToShm) -{ - int idle_busy_ratio_x_16 = 0; - uint offset = - isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM : - M_TX_IDLE_BUSY_RATIO_X_16_CCK; - if (duty_cycle > 100 || duty_cycle < 0) { - WL_ERROR("wl%d: duty cycle value off limit\n", wlc->pub->unit); - return BCME_RANGE; - } - if (duty_cycle) - idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle; - /* Only write to shared memory when wl is up */ - if (writeToShm) - wlc_write_shm(wlc, offset, (u16) idle_busy_ratio_x_16); - - if (isOFDM) - wlc->tx_duty_cycle_ofdm = (u16) duty_cycle; - else - wlc->tx_duty_cycle_cck = (u16) duty_cycle; - - return BCME_OK; -} - -/* Read a single u16 from shared memory. - * SHM 'offset' needs to be an even address - */ -u16 wlc_read_shm(struct wlc_info *wlc, uint offset) -{ - return wlc_bmac_read_shm(wlc->hw, offset); -} - -/* Write a single u16 to shared memory. - * SHM 'offset' needs to be an even address - */ -void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v) -{ - wlc_bmac_write_shm(wlc->hw, offset, v); -} - -/* Set a range of shared memory to a value. - * SHM 'offset' needs to be an even address and - * Range length 'len' must be an even number of bytes - */ -void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len) -{ - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) - return; - - wlc_bmac_set_shm(wlc->hw, offset, v, len); -} - -/* Copy a buffer to shared memory. - * SHM 'offset' needs to be an even address and - * Buffer length 'len' must be an even number of bytes - */ -void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, int len) -{ - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) - return; - wlc_bmac_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL); - -} - -/* Copy from shared memory to a buffer. - * SHM 'offset' needs to be an even address and - * Buffer length 'len' must be an even number of bytes - */ -void wlc_copyfrom_shm(struct wlc_info *wlc, uint offset, void *buf, int len) -{ - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) - return; - - wlc_bmac_copyfrom_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL); -} - -/* wrapper BMAC functions to for HIGH driver access */ -void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val) -{ - wlc_bmac_mctrl(wlc->hw, mask, val); -} - -void wlc_corereset(struct wlc_info *wlc, u32 flags) -{ - wlc_bmac_corereset(wlc->hw, flags); -} - -void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val, int bands) -{ - wlc_bmac_mhf(wlc->hw, idx, mask, val, bands); -} - -u16 wlc_mhf_get(struct wlc_info *wlc, u8 idx, int bands) -{ - return wlc_bmac_mhf_get(wlc->hw, idx, bands); -} - -int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks) -{ - return wlc_bmac_xmtfifo_sz_get(wlc->hw, fifo, blocks); -} - -void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len, - void *buf) -{ - wlc_bmac_write_template_ram(wlc->hw, offset, len, buf); -} - -void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len, - bool both) -{ - wlc_bmac_write_hw_bcntemplates(wlc->hw, bcn, len, both); -} - -void -wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, - const u8 *addr) -{ - wlc_bmac_set_addrmatch(wlc->hw, match_reg_offset, addr); -} - -void wlc_set_rcmta(struct wlc_info *wlc, int idx, const u8 *addr) -{ - wlc_bmac_set_rcmta(wlc->hw, idx, addr); -} - -void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, u32 *tsf_h_ptr) -{ - wlc_bmac_read_tsf(wlc->hw, tsf_l_ptr, tsf_h_ptr); -} - -void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin) -{ - wlc->band->CWmin = newmin; - wlc_bmac_set_cwmin(wlc->hw, newmin); -} - -void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax) -{ - wlc->band->CWmax = newmax; - wlc_bmac_set_cwmax(wlc->hw, newmax); -} - -void wlc_fifoerrors(struct wlc_info *wlc) -{ - - wlc_bmac_fifoerrors(wlc->hw); -} - -/* Search mem rw utilities */ - -void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit) -{ - wlc_bmac_pllreq(wlc->hw, set, req_bit); -} - -void wlc_reset_bmac_done(struct wlc_info *wlc) -{ -} - -void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode) -{ - wlc->ht_cap.cap_info &= ~HT_CAP_MIMO_PS_MASK; - wlc->ht_cap.cap_info |= (mimops_mode << IEEE80211_HT_CAP_SM_PS_SHIFT); - - if (AP_ENAB(wlc->pub) && wlc->clk) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - } -} - -/* check for the particular priority flow control bit being set */ -bool -wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, wlc_txq_info_t *q, int prio) -{ - uint prio_mask; - - if (prio == ALLPRIO) { - prio_mask = TXQ_STOP_FOR_PRIOFC_MASK; - } else { - ASSERT(prio >= 0 && prio <= MAXPRIO); - prio_mask = NBITVAL(prio); - } - - return (q->stopped & prio_mask) == prio_mask; -} - -/* propogate the flow control to all interfaces using the given tx queue */ -void wlc_txflowcontrol(struct wlc_info *wlc, wlc_txq_info_t *qi, - bool on, int prio) -{ - uint prio_bits; - uint cur_bits; - - WL_ERROR("%s: flow control kicks in\n", __func__); - - if (prio == ALLPRIO) { - prio_bits = TXQ_STOP_FOR_PRIOFC_MASK; - } else { - ASSERT(prio >= 0 && prio <= MAXPRIO); - prio_bits = NBITVAL(prio); - } - - cur_bits = qi->stopped & prio_bits; - - /* Check for the case of no change and return early - * Otherwise update the bit and continue - */ - if (on) { - if (cur_bits == prio_bits) { - return; - } - mboolset(qi->stopped, prio_bits); - } else { - if (cur_bits == 0) { - return; - } - mboolclr(qi->stopped, prio_bits); - } - - /* If there is a flow control override we will not change the external - * flow control state. - */ - if (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK) { - return; - } - - wlc_txflowcontrol_signal(wlc, qi, on, prio); -} - -void -wlc_txflowcontrol_override(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, - uint override) -{ - uint prev_override; - - ASSERT(override != 0); - ASSERT((override & TXQ_STOP_FOR_PRIOFC_MASK) == 0); - - prev_override = (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK); - - /* Update the flow control bits and do an early return if there is - * no change in the external flow control state. - */ - if (on) { - mboolset(qi->stopped, override); - /* if there was a previous override bit on, then setting this - * makes no difference. - */ - if (prev_override) { - return; - } - - wlc_txflowcontrol_signal(wlc, qi, ON, ALLPRIO); - } else { - mboolclr(qi->stopped, override); - /* clearing an override bit will only make a difference for - * flow control if it was the only bit set. For any other - * override setting, just return - */ - if (prev_override != override) { - return; - } - - if (qi->stopped == 0) { - wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); - } else { - int prio; - - for (prio = MAXPRIO; prio >= 0; prio--) { - if (!mboolisset(qi->stopped, NBITVAL(prio))) - wlc_txflowcontrol_signal(wlc, qi, OFF, - prio); - } - } - } -} - -static void wlc_txflowcontrol_reset(struct wlc_info *wlc) -{ - wlc_txq_info_t *qi; - - for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { - if (qi->stopped) { - wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); - qi->stopped = 0; - } - } -} - -static void -wlc_txflowcontrol_signal(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, - int prio) -{ - struct wlc_if *wlcif; - - for (wlcif = wlc->wlcif_list; wlcif != NULL; wlcif = wlcif->next) { - if (wlcif->qi == qi && wlcif->flags & WLC_IF_LINKED) - wl_txflowcontrol(wlc->wl, wlcif->wlif, on, prio); - } -} - -static wlc_txq_info_t *wlc_txq_alloc(struct wlc_info *wlc, struct osl_info *osh) -{ - wlc_txq_info_t *qi, *p; - - qi = (wlc_txq_info_t *) wlc_calloc(osh, wlc->pub->unit, - sizeof(wlc_txq_info_t)); - if (qi == NULL) { - return NULL; - } - - /* Have enough room for control packets along with HI watermark */ - /* Also, add room to txq for total psq packets if all the SCBs leave PS mode */ - /* The watermark for flowcontrol to OS packets will remain the same */ - pktq_init(&qi->q, WLC_PREC_COUNT, - (2 * wlc->pub->tunables->datahiwat) + PKTQ_LEN_DEFAULT + - wlc->pub->psq_pkts_total); - - /* add this queue to the the global list */ - p = wlc->tx_queues; - if (p == NULL) { - wlc->tx_queues = qi; - } else { - while (p->next != NULL) - p = p->next; - p->next = qi; - } - - return qi; -} - -static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh, - wlc_txq_info_t *qi) -{ - wlc_txq_info_t *p; - - if (qi == NULL) - return; - - /* remove the queue from the linked list */ - p = wlc->tx_queues; - if (p == qi) - wlc->tx_queues = p->next; - else { - while (p != NULL && p->next != qi) - p = p->next; - ASSERT(p->next == qi); - if (p != NULL) - p->next = p->next->next; - } - - kfree(qi); -} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_mac80211.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_mac80211.h deleted file mode 100644 index f56b58141c09..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_mac80211.h +++ /dev/null @@ -1,989 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_h_ -#define _wlc_h_ - -#include -#include -#include -#include -#include - -#define MA_WINDOW_SZ 8 /* moving average window size */ -#define WL_HWRXOFF 38 /* chip rx buffer offset */ -#define INVCHANNEL 255 /* invalid channel */ -#define MAXCOREREV 28 /* max # supported core revisions (0 .. MAXCOREREV - 1) */ -#define WLC_MAXMODULES 22 /* max # wlc_module_register() calls */ - -/* network protection config */ -#define WLC_PROT_G_SPEC 1 /* SPEC g protection */ -#define WLC_PROT_G_OVR 2 /* SPEC g prot override */ -#define WLC_PROT_G_USER 3 /* gmode specified by user */ -#define WLC_PROT_OVERLAP 4 /* overlap */ -#define WLC_PROT_N_USER 10 /* nmode specified by user */ -#define WLC_PROT_N_CFG 11 /* n protection */ -#define WLC_PROT_N_CFG_OVR 12 /* n protection override */ -#define WLC_PROT_N_NONGF 13 /* non-GF protection */ -#define WLC_PROT_N_NONGF_OVR 14 /* non-GF protection override */ -#define WLC_PROT_N_PAM_OVR 15 /* n preamble override */ -#define WLC_PROT_N_OBSS 16 /* non-HT OBSS present */ - -#define WLC_BITSCNT(x) bcm_bitcount((u8 *)&(x), sizeof(u8)) - -/* Maximum wait time for a MAC suspend */ -#define WLC_MAX_MAC_SUSPEND 83000 /* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */ - -/* Probe Response timeout - responses for probe requests older that this are tossed, zero to disable - */ -#define WLC_PRB_RESP_TIMEOUT 0 /* Disable probe response timeout */ - -/* transmit buffer max headroom for protocol headers */ -#define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN) - -/* For managing scan result lists */ -typedef struct wlc_bss_list { - uint count; - bool beacon; /* set for beacon, cleared for probe response */ - wlc_bss_info_t *ptrs[MAXBSS]; -} wlc_bss_list_t; - -#define SW_TIMER_MAC_STAT_UPD 30 /* periodic MAC stats update */ - -/* Double check that unsupported cores are not enabled */ -#if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV) -#error "Configuration for D11CONF includes unsupported versions." -#endif /* Bad versions */ - -#define VALID_COREREV(corerev) CONF_HAS(D11CONF, corerev) - -/* values for shortslot_override */ -#define WLC_SHORTSLOT_AUTO -1 /* Driver will manage Shortslot setting */ -#define WLC_SHORTSLOT_OFF 0 /* Turn off short slot */ -#define WLC_SHORTSLOT_ON 1 /* Turn on short slot */ - -/* value for short/long and mixmode/greenfield preamble */ - -#define WLC_LONG_PREAMBLE (0) -#define WLC_SHORT_PREAMBLE (1 << 0) -#define WLC_GF_PREAMBLE (1 << 1) -#define WLC_MM_PREAMBLE (1 << 2) -#define WLC_IS_MIMO_PREAMBLE(_pre) (((_pre) == WLC_GF_PREAMBLE) || ((_pre) == WLC_MM_PREAMBLE)) - -/* values for barker_preamble */ -#define WLC_BARKER_SHORT_ALLOWED 0 /* Short pre-amble allowed */ - -/* A fifo is full. Clear precedences related to that FIFO */ -#define WLC_TX_FIFO_CLEAR(wlc, fifo) ((wlc)->tx_prec_map &= ~(wlc)->fifo2prec_map[fifo]) - -/* Fifo is NOT full. Enable precedences for that FIFO */ -#define WLC_TX_FIFO_ENAB(wlc, fifo) ((wlc)->tx_prec_map |= (wlc)->fifo2prec_map[fifo]) - -/* TxFrameID */ -/* seq and frag bits: SEQNUM_SHIFT, FRAGNUM_MASK (802.11.h) */ -/* rate epoch bits: TXFID_RATE_SHIFT, TXFID_RATE_MASK ((wlc_rate.c) */ -#define TXFID_QUEUE_MASK 0x0007 /* Bits 0-2 */ -#define TXFID_SEQ_MASK 0x7FE0 /* Bits 5-15 */ -#define TXFID_SEQ_SHIFT 5 /* Number of bit shifts */ -#define TXFID_RATE_PROBE_MASK 0x8000 /* Bit 15 for rate probe */ -#define TXFID_RATE_MASK 0x0018 /* Mask for bits 3 and 4 */ -#define TXFID_RATE_SHIFT 3 /* Shift 3 bits for rate mask */ - -/* promote boardrev */ -#define BOARDREV_PROMOTABLE 0xFF /* from */ -#define BOARDREV_PROMOTED 1 /* to */ - -/* if wpa is in use then portopen is true when the group key is plumbed otherwise it is always true - */ -#define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) -#define WLC_SW_KEYS(wlc, bsscfg) ((((wlc)->wsec_swkeys) || \ - ((bsscfg)->wsec & WSEC_SWFLAG))) - -#define WLC_PORTOPEN(cfg) \ - (((cfg)->WPA_auth != WPA_AUTH_DISABLED && WSEC_ENABLED((cfg)->wsec)) ? \ - (cfg)->wsec_portopen : true) - -#define PS_ALLOWED(wlc) wlc_ps_allowed(wlc) -#define STAY_AWAKE(wlc) wlc_stay_awake(wlc) - -#define DATA_BLOCK_TX_SUPR (1 << 4) - -/* 802.1D Priority to TX FIFO number for wme */ -extern const u8 prio2fifo[]; - -/* Ucode MCTL_WAKE override bits */ -#define WLC_WAKE_OVERRIDE_CLKCTL 0x01 -#define WLC_WAKE_OVERRIDE_PHYREG 0x02 -#define WLC_WAKE_OVERRIDE_MACSUSPEND 0x04 -#define WLC_WAKE_OVERRIDE_TXFIFO 0x08 -#define WLC_WAKE_OVERRIDE_FORCEFAST 0x10 - -/* stuff pulled in from wlc.c */ - -/* Interrupt bit error summary. Don't include I_RU: we refill DMA at other - * times; and if we run out, constant I_RU interrupts may cause lockup. We - * will still get error counts from rx0ovfl. - */ -#define I_ERRORS (I_PC | I_PD | I_DE | I_RO | I_XU) -/* default software intmasks */ -#define DEF_RXINTMASK (I_RI) /* enable rx int on rxfifo only */ -#define DEF_MACINTMASK (MI_TXSTOP | MI_TBTT | MI_ATIMWINEND | MI_PMQ | \ - MI_PHYTXERR | MI_DMAINT | MI_TFS | MI_BG_NOISE | \ - MI_CCA | MI_TO | MI_GP0 | MI_RFDISABLE | MI_PWRUP) - -#define RETRY_SHORT_DEF 7 /* Default Short retry Limit */ -#define RETRY_SHORT_MAX 255 /* Maximum Short retry Limit */ -#define RETRY_LONG_DEF 4 /* Default Long retry count */ -#define RETRY_SHORT_FB 3 /* Short retry count for fallback rate */ -#define RETRY_LONG_FB 2 /* Long retry count for fallback rate */ - -#define MAXTXPKTS 6 /* max # pkts pending */ - -/* frameburst */ -#define MAXTXFRAMEBURST 8 /* vanilla xpress mode: max frames/burst */ -#define MAXFRAMEBURST_TXOP 10000 /* Frameburst TXOP in usec */ - -/* Per-AC retry limit register definitions; uses bcmdefs.h bitfield macros */ -#define EDCF_SHORT_S 0 -#define EDCF_SFB_S 4 -#define EDCF_LONG_S 8 -#define EDCF_LFB_S 12 -#define EDCF_SHORT_M BITFIELD_MASK(4) -#define EDCF_SFB_M BITFIELD_MASK(4) -#define EDCF_LONG_M BITFIELD_MASK(4) -#define EDCF_LFB_M BITFIELD_MASK(4) - -#define WLC_WME_RETRY_SHORT_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_SHORT) -#define WLC_WME_RETRY_SFB_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_SFB) -#define WLC_WME_RETRY_LONG_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_LONG) -#define WLC_WME_RETRY_LFB_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_LFB) - -#define WLC_WME_RETRY_SHORT_SET(wlc, ac, val) \ - (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SHORT, val)) -#define WLC_WME_RETRY_SFB_SET(wlc, ac, val) \ - (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SFB, val)) -#define WLC_WME_RETRY_LONG_SET(wlc, ac, val) \ - (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LONG, val)) -#define WLC_WME_RETRY_LFB_SET(wlc, ac, val) \ - (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LFB, val)) - -/* PLL requests */ -#define WLC_PLLREQ_SHARED 0x1 /* pll is shared on old chips */ -#define WLC_PLLREQ_RADIO_MON 0x2 /* hold pll for radio monitor register checking */ -#define WLC_PLLREQ_FLIP 0x4 /* hold/release pll for some short operation */ - -/* Do we support this rate? */ -#define VALID_RATE_DBG(wlc, rspec) wlc_valid_rate(wlc, rspec, WLC_BAND_AUTO, true) - -/* - * Macros to check if AP or STA is active. - * AP Active means more than just configured: driver and BSS are "up"; - * that is, we are beaconing/responding as an AP (aps_associated). - * STA Active similarly means the driver is up and a configured STA BSS - * is up: either associated (stas_associated) or trying. - * - * Macro definitions vary as per AP/STA ifdefs, allowing references to - * ifdef'd structure fields and constant values (0) for optimization. - * Make sure to enclose blocks of code such that any routines they - * reference can also be unused and optimized out by the linker. - */ -/* NOTE: References structure fields defined in wlc.h */ -#define AP_ACTIVE(wlc) (0) - -/* - * Detect Card removed. - * Even checking an sbconfig register read will not false trigger when the core is in reset. - * it breaks CF address mechanism. Accessing gphy phyversion will cause SB error if aphy - * is in reset on 4306B0-DB. Need a simple accessible reg with fixed 0/1 pattern - * (some platforms return all 0). - * If clocks are present, call the sb routine which will figure out if the device is removed. - */ -#define DEVICEREMOVED(wlc) \ - ((wlc->hw->clk) ? \ - ((R_REG(wlc->hw->osh, &wlc->hw->regs->maccontrol) & \ - (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN) : \ - (si_deviceremoved(wlc->hw->sih))) - -#define WLCWLUNIT(wlc) ((wlc)->pub->unit) - -typedef struct wlc_protection { - bool _g; /* use g spec protection, driver internal */ - s8 g_override; /* override for use of g spec protection */ - u8 gmode_user; /* user config gmode, operating band->gmode is different */ - s8 overlap; /* Overlap BSS/IBSS protection for both 11g and 11n */ - s8 nmode_user; /* user config nmode, operating pub->nmode is different */ - s8 n_cfg; /* use OFDM protection on MIMO frames */ - s8 n_cfg_override; /* override for use of N protection */ - bool nongf; /* non-GF present protection */ - s8 nongf_override; /* override for use of GF protection */ - s8 n_pam_override; /* override for preamble: MM or GF */ - bool n_obss; /* indicated OBSS Non-HT STA present */ - - uint longpre_detect_timeout; /* #sec until long preamble bcns gone */ - uint barker_detect_timeout; /* #sec until bcns signaling Barker long preamble */ - /* only is gone */ - uint ofdm_ibss_timeout; /* #sec until ofdm IBSS beacons gone */ - uint ofdm_ovlp_timeout; /* #sec until ofdm overlapping BSS bcns gone */ - uint nonerp_ibss_timeout; /* #sec until nonerp IBSS beacons gone */ - uint nonerp_ovlp_timeout; /* #sec until nonerp overlapping BSS bcns gone */ - uint g_ibss_timeout; /* #sec until bcns signaling Use_Protection gone */ - uint n_ibss_timeout; /* #sec until bcns signaling Use_OFDM_Protection gone */ - uint ht20in40_ovlp_timeout; /* #sec until 20MHz overlapping OPMODE gone */ - uint ht20in40_ibss_timeout; /* #sec until 20MHz-only HT station bcns gone */ - uint non_gf_ibss_timeout; /* #sec until non-GF bcns gone */ -} wlc_protection_t; - -/* anything affects the single/dual streams/antenna operation */ -typedef struct wlc_stf { - u8 hw_txchain; /* HW txchain bitmap cfg */ - u8 txchain; /* txchain bitmap being used */ - u8 txstreams; /* number of txchains being used */ - - u8 hw_rxchain; /* HW rxchain bitmap cfg */ - u8 rxchain; /* rxchain bitmap being used */ - u8 rxstreams; /* number of rxchains being used */ - - u8 ant_rx_ovr; /* rx antenna override */ - s8 txant; /* userTx antenna setting */ - u16 phytxant; /* phyTx antenna setting in txheader */ - - u8 ss_opmode; /* singlestream Operational mode, 0:siso; 1:cdd */ - bool ss_algosel_auto; /* if true, use wlc->stf->ss_algo_channel; */ - /* else use wlc->band->stf->ss_mode_band; */ - u16 ss_algo_channel; /* ss based on per-channel algo: 0: SISO, 1: CDD 2: STBC */ - u8 no_cddstbc; /* stf override, 1: no CDD (or STBC) allowed */ - - u8 rxchain_restore_delay; /* delay time to restore default rxchain */ - - s8 ldpc; /* AUTO/ON/OFF ldpc cap supported */ - u8 txcore[MAX_STREAMS_SUPPORTED + 1]; /* bitmap of selected core for each Nsts */ - s8 spatial_policy; -} wlc_stf_t; - -#define WLC_STF_SS_STBC_TX(wlc, scb) \ - (((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) || \ - (SCB_STBC_CAP((scb)) && \ - (wlc)->band->band_stf_stbc_tx == AUTO && \ - isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC)))) - -#define WLC_STBC_CAP_PHY(wlc) (WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3)) - -#define WLC_SGI_CAP_PHY(wlc) ((WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3)) || \ - WLCISLCNPHY(wlc->band)) - -#define WLC_CHAN_PHYTYPE(x) (((x) & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT) -#define WLC_CHAN_CHANNEL(x) (((x) & RXS_CHAN_ID_MASK) >> RXS_CHAN_ID_SHIFT) -#define WLC_RX_CHANNEL(rxh) (WLC_CHAN_CHANNEL((rxh)->RxChan)) - -/* wlc_bss_info flag bit values */ -#define WLC_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */ - -/* Flags used in wlc_txq_info.stopped */ -#define TXQ_STOP_FOR_PRIOFC_MASK 0x000000FF /* per prio flow control bits */ -#define TXQ_STOP_FOR_PKT_DRAIN 0x00000100 /* stop txq enqueue for packet drain */ -#define TXQ_STOP_FOR_AMPDU_FLOW_CNTRL 0x00000200 /* stop txq enqueue for ampdu flow control */ - -#define WLC_HT_WEP_RESTRICT 0x01 /* restrict HT with WEP */ -#define WLC_HT_TKIP_RESTRICT 0x02 /* restrict HT with TKIP */ - -/* - * core state (mac) - */ -struct wlccore { - uint coreidx; /* # sb enumerated core */ - - /* fifo */ - uint *txavail[NFIFO]; /* # tx descriptors available */ - s16 txpktpend[NFIFO]; /* tx admission control */ - - macstat_t *macstat_snapshot; /* mac hw prev read values */ -}; - -/* - * band state (phy+ana+radio) - */ -struct wlcband { - int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */ - uint bandunit; /* bandstate[] index */ - - u16 phytype; /* phytype */ - u16 phyrev; - u16 radioid; - u16 radiorev; - wlc_phy_t *pi; /* pointer to phy specific information */ - bool abgphy_encore; - - u8 gmode; /* currently active gmode (see wlioctl.h) */ - - struct scb *hwrs_scb; /* permanent scb for hw rateset */ - - wlc_rateset_t defrateset; /* band-specific copy of default_bss.rateset */ - - ratespec_t rspec_override; /* 802.11 rate override */ - ratespec_t mrspec_override; /* multicast rate override */ - u8 band_stf_ss_mode; /* Configured STF type, 0:siso; 1:cdd */ - s8 band_stf_stbc_tx; /* STBC TX 0:off; 1:force on; -1:auto */ - wlc_rateset_t hw_rateset; /* rates supported by chip (phy-specific) */ - u8 basic_rate[WLC_MAXRATE + 1]; /* basic rates indexed by rate */ - bool mimo_cap_40; /* 40 MHz cap enabled on this band */ - s8 antgain; /* antenna gain from srom */ - - u16 CWmin; /* The minimum size of contention window, in unit of aSlotTime */ - u16 CWmax; /* The maximum size of contention window, in unit of aSlotTime */ - u16 bcntsfoff; /* beacon tsf offset */ -}; - -/* generic function callback takes just one arg */ -typedef void (*cb_fn_t) (void *); - -/* tx completion callback takes 3 args */ -typedef void (*pkcb_fn_t) (struct wlc_info *wlc, uint txstatus, void *arg); - -typedef struct pkt_cb { - pkcb_fn_t fn; /* function to call when tx frame completes */ - void *arg; /* void arg for fn */ - u8 nextidx; /* index of next call back if threading */ - bool entered; /* recursion check */ -} pkt_cb_t; - - /* module control blocks */ -typedef struct modulecb { - char name[32]; /* module name : NULL indicates empty array member */ - const bcm_iovar_t *iovars; /* iovar table */ - void *hdl; /* handle passed when handler 'doiovar' is called */ - watchdog_fn_t watchdog_fn; /* watchdog handler */ - iovar_fn_t iovar_fn; /* iovar handler */ - down_fn_t down_fn; /* down handler. Note: the int returned - * by the down function is a count of the - * number of timers that could not be - * freed. - */ -} modulecb_t; - - /* dump control blocks */ -typedef struct dumpcb_s { - const char *name; /* dump name */ - dump_fn_t dump_fn; /* 'wl dump' handler */ - void *dump_fn_arg; - struct dumpcb_s *next; -} dumpcb_t; - -/* virtual interface */ -struct wlc_if { - struct wlc_if *next; - u8 type; /* WLC_IFTYPE_BSS or WLC_IFTYPE_WDS */ - u8 index; /* assigned in wl_add_if(), index of the wlif if any, - * not necessarily corresponding to bsscfg._idx or - * AID2PVBMAP(scb). - */ - u8 flags; /* flags for the interface */ - struct wl_if *wlif; /* pointer to wlif */ - struct wlc_txq_info *qi; /* pointer to associated tx queue */ - union { - struct scb *scb; /* pointer to scb if WLC_IFTYPE_WDS */ - struct wlc_bsscfg *bsscfg; /* pointer to bsscfg if WLC_IFTYPE_BSS */ - } u; -}; - -/* flags for the interface */ -#define WLC_IF_LINKED 0x02 /* this interface is linked to a wl_if */ - -typedef struct wlc_hwband { - int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */ - uint bandunit; /* bandstate[] index */ - u16 mhfs[MHFMAX]; /* MHF array shadow */ - u8 bandhw_stf_ss_mode; /* HW configured STF type, 0:siso; 1:cdd */ - u16 CWmin; - u16 CWmax; - u32 core_flags; - - u16 phytype; /* phytype */ - u16 phyrev; - u16 radioid; - u16 radiorev; - wlc_phy_t *pi; /* pointer to phy specific information */ - bool abgphy_encore; -} wlc_hwband_t; - -struct wlc_hw_info { - struct osl_info *osh; /* pointer to os handle */ - bool _piomode; /* true if pio mode */ - struct wlc_info *wlc; - - /* fifo */ - struct hnddma_pub *di[NFIFO]; /* hnddma handles, per fifo */ - - uint unit; /* device instance number */ - - /* version info */ - u16 vendorid; /* PCI vendor id */ - u16 deviceid; /* PCI device id */ - uint corerev; /* core revision */ - u8 sromrev; /* version # of the srom */ - u16 boardrev; /* version # of particular board */ - u32 boardflags; /* Board specific flags from srom */ - u32 boardflags2; /* More board flags if sromrev >= 4 */ - u32 machwcap; /* MAC capabilities (corerev >= 13) */ - u32 machwcap_backup; /* backup of machwcap (corerev >= 13) */ - u16 ucode_dbgsel; /* dbgsel for ucode debug(config gpio) */ - - si_t *sih; /* SB handle (cookie for siutils calls) */ - char *vars; /* "environment" name=value */ - uint vars_size; /* size of vars, free vars on detach */ - d11regs_t *regs; /* pointer to device registers */ - void *physhim; /* phy shim layer handler */ - void *phy_sh; /* pointer to shared phy state */ - wlc_hwband_t *band; /* pointer to active per-band state */ - wlc_hwband_t *bandstate[MAXBANDS]; /* per-band state (one per phy/radio) */ - u16 bmac_phytxant; /* cache of high phytxant state */ - bool shortslot; /* currently using 11g ShortSlot timing */ - u16 SRL; /* 802.11 dot11ShortRetryLimit */ - u16 LRL; /* 802.11 dot11LongRetryLimit */ - u16 SFBL; /* Short Frame Rate Fallback Limit */ - u16 LFBL; /* Long Frame Rate Fallback Limit */ - - bool up; /* d11 hardware up and running */ - uint now; /* # elapsed seconds */ - uint _nbands; /* # bands supported */ - chanspec_t chanspec; /* bmac chanspec shadow */ - - uint *txavail[NFIFO]; /* # tx descriptors available */ - u16 *xmtfifo_sz; /* fifo size in 256B for each xmt fifo */ - - mbool pllreq; /* pll requests to keep PLL on */ - - u8 suspended_fifos; /* Which TX fifo to remain awake for */ - u32 maccontrol; /* Cached value of maccontrol */ - uint mac_suspend_depth; /* current depth of mac_suspend levels */ - u32 wake_override; /* Various conditions to force MAC to WAKE mode */ - u32 mute_override; /* Prevent ucode from sending beacons */ - u8 etheraddr[ETH_ALEN]; /* currently configured ethernet address */ - u32 led_gpio_mask; /* LED GPIO Mask */ - bool noreset; /* true= do not reset hw, used by WLC_OUT */ - bool forcefastclk; /* true if the h/w is forcing the use of fast clk */ - bool clk; /* core is out of reset and has clock */ - bool sbclk; /* sb has clock */ - struct bmac_pmq *bmac_pmq; /* bmac PM states derived from ucode PMQ */ - bool phyclk; /* phy is out of reset and has clock */ - bool dma_lpbk; /* core is in DMA loopback */ - - bool ucode_loaded; /* true after ucode downloaded */ - - - u8 hw_stf_ss_opmode; /* STF single stream operation mode */ - u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic - * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board - */ - u32 antsel_avail; /* - * put struct antsel_info here if more info is - * needed - */ -}; - -/* TX Queue information - * - * Each flow of traffic out of the device has a TX Queue with independent - * flow control. Several interfaces may be associated with a single TX Queue - * if they belong to the same flow of traffic from the device. For multi-channel - * operation there are independent TX Queues for each channel. - */ -typedef struct wlc_txq_info { - struct wlc_txq_info *next; - struct pktq q; - uint stopped; /* tx flow control bits */ -} wlc_txq_info_t; - -/* - * Principal common (os-independent) software data structure. - */ -struct wlc_info { - struct wlc_pub *pub; /* pointer to wlc public state */ - struct osl_info *osh; /* pointer to os handle */ - struct wl_info *wl; /* pointer to os-specific private state */ - d11regs_t *regs; /* pointer to device registers */ - - struct wlc_hw_info *hw; /* HW related state used primarily by BMAC */ - - /* clock */ - int clkreq_override; /* setting for clkreq for PCIE : Auto, 0, 1 */ - u16 fastpwrup_dly; /* time in us needed to bring up d11 fast clock */ - - /* interrupt */ - u32 macintstatus; /* bit channel between isr and dpc */ - u32 macintmask; /* sw runtime master macintmask value */ - u32 defmacintmask; /* default "on" macintmask value */ - - /* up and down */ - bool device_present; /* (removable) device is present */ - - bool clk; /* core is out of reset and has clock */ - - /* multiband */ - struct wlccore *core; /* pointer to active io core */ - struct wlcband *band; /* pointer to active per-band state */ - struct wlccore *corestate; /* per-core state (one per hw core) */ - /* per-band state (one per phy/radio): */ - struct wlcband *bandstate[MAXBANDS]; - - bool war16165; /* PCI slow clock 16165 war flag */ - - bool tx_suspended; /* data fifos need to remain suspended */ - - uint txpend16165war; - - /* packet queue */ - uint qvalid; /* DirFrmQValid and BcMcFrmQValid */ - - /* Regulatory power limits */ - s8 txpwr_local_max; /* regulatory local txpwr max */ - u8 txpwr_local_constraint; /* local power contraint in dB */ - - - struct ampdu_info *ampdu; /* ampdu module handler */ - struct antsel_info *asi; /* antsel module handler */ - wlc_cm_info_t *cmi; /* channel manager module handler */ - - void *btparam; /* bus type specific cookie */ - - uint vars_size; /* size of vars, free vars on detach */ - - u16 vendorid; /* PCI vendor id */ - u16 deviceid; /* PCI device id */ - uint ucode_rev; /* microcode revision */ - - u32 machwcap; /* MAC capabilities, BMAC shadow */ - - u8 perm_etheraddr[ETH_ALEN]; /* original sprom local ethernet address */ - - bool bandlocked; /* disable auto multi-band switching */ - bool bandinit_pending; /* track band init in auto band */ - - bool radio_monitor; /* radio timer is running */ - bool down_override; /* true=down */ - bool going_down; /* down path intermediate variable */ - - bool mpc; /* enable minimum power consumption */ - u8 mpc_dlycnt; /* # of watchdog cnt before turn disable radio */ - u8 mpc_offcnt; /* # of watchdog cnt that radio is disabled */ - u8 mpc_delay_off; /* delay radio disable by # of watchdog cnt */ - u8 prev_non_delay_mpc; /* prev state wlc_is_non_delay_mpc */ - - /* timer */ - struct wl_timer *wdtimer; /* timer for watchdog routine */ - uint fast_timer; /* Periodic timeout for 'fast' timer */ - uint slow_timer; /* Periodic timeout for 'slow' timer */ - uint glacial_timer; /* Periodic timeout for 'glacial' timer */ - uint phycal_mlo; /* last time measurelow calibration was done */ - uint phycal_txpower; /* last time txpower calibration was done */ - - struct wl_timer *radio_timer; /* timer for hw radio button monitor routine */ - struct wl_timer *pspoll_timer; /* periodic pspoll timer */ - - /* promiscuous */ - bool monitor; /* monitor (MPDU sniffing) mode */ - bool bcnmisc_ibss; /* bcns promisc mode override for IBSS */ - bool bcnmisc_scan; /* bcns promisc mode override for scan */ - bool bcnmisc_monitor; /* bcns promisc mode override for monitor */ - - u8 bcn_wait_prd; /* max waiting period (for beacon) in 1024TU */ - - /* driver feature */ - bool _rifs; /* enable per-packet rifs */ - s32 rifs_advert; /* RIFS mode advertisement */ - s8 sgi_tx; /* sgi tx */ - bool wet; /* true if wireless ethernet bridging mode */ - - /* AP-STA synchronization, power save */ - bool check_for_unaligned_tbtt; /* check unaligned tbtt flag */ - bool PM_override; /* no power-save flag, override PM(user input) */ - bool PMenabled; /* current power-management state (CAM or PS) */ - bool PMpending; /* waiting for tx status with PM indicated set */ - bool PMblocked; /* block any PSPolling in PS mode, used to buffer - * AP traffic, also used to indicate in progress - * of scan, rm, etc. off home channel activity. - */ - bool PSpoll; /* whether there is an outstanding PS-Poll frame */ - u8 PM; /* power-management mode (CAM, PS or FASTPS) */ - bool PMawakebcn; /* bcn recvd during current waking state */ - - bool WME_PM_blocked; /* Can STA go to PM when in WME Auto mode */ - bool wake; /* host-specified PS-mode sleep state */ - u8 pspoll_prd; /* pspoll interval in milliseconds */ - u8 bcn_li_bcn; /* beacon listen interval in # beacons */ - u8 bcn_li_dtim; /* beacon listen interval in # dtims */ - - bool WDarmed; /* watchdog timer is armed */ - u32 WDlast; /* last time wlc_watchdog() was called */ - - /* WME */ - ac_bitmap_t wme_dp; /* Discard (oldest first) policy per AC */ - bool wme_apsd; /* enable Advanced Power Save Delivery */ - ac_bitmap_t wme_admctl; /* bit i set if AC i under admission control */ - u16 edcf_txop[AC_COUNT]; /* current txop for each ac */ - wme_param_ie_t wme_param_ie; /* WME parameter info element, which on STA - * contains parameters in use locally, and on - * AP contains parameters advertised to STA - * in beacons and assoc responses. - */ - bool wme_prec_queuing; /* enable/disable non-wme STA prec queuing */ - u16 wme_retries[AC_COUNT]; /* per-AC retry limits */ - - int vlan_mode; /* OK to use 802.1Q Tags (ON, OFF, AUTO) */ - u16 tx_prec_map; /* Precedence map based on HW FIFO space */ - u16 fifo2prec_map[NFIFO]; /* pointer to fifo2_prec map based on WME */ - - /* BSS Configurations */ - wlc_bsscfg_t *bsscfg[WLC_MAXBSSCFG]; /* set of BSS configurations, idx 0 is default and - * always valid - */ - wlc_bsscfg_t *cfg; /* the primary bsscfg (can be AP or STA) */ - u8 stas_associated; /* count of ASSOCIATED STA bsscfgs */ - u8 aps_associated; /* count of UP AP bsscfgs */ - u8 block_datafifo; /* prohibit posting frames to data fifos */ - bool bcmcfifo_drain; /* TX_BCMC_FIFO is set to drain */ - - /* tx queue */ - wlc_txq_info_t *tx_queues; /* common TX Queue list */ - - /* event */ - wlc_eventq_t *eventq; /* event queue for deferred processing */ - - /* security */ - wsec_key_t *wsec_keys[WSEC_MAX_KEYS]; /* dynamic key storage */ - wsec_key_t *wsec_def_keys[WLC_DEFAULT_KEYS]; /* default key storage */ - bool wsec_swkeys; /* indicates that all keys should be - * treated as sw keys (used for debugging) - */ - modulecb_t *modulecb; - dumpcb_t *dumpcb_head; - - u8 mimoft; /* SIGN or 11N */ - u8 mimo_band_bwcap; /* bw cap per band type */ - s8 txburst_limit_override; /* tx burst limit override */ - u16 txburst_limit; /* tx burst limit value */ - s8 cck_40txbw; /* 11N, cck tx b/w override when in 40MHZ mode */ - s8 ofdm_40txbw; /* 11N, ofdm tx b/w override when in 40MHZ mode */ - s8 mimo_40txbw; /* 11N, mimo tx b/w override when in 40MHZ mode */ - /* HT CAP IE being advertised by this node: */ - struct ieee80211_ht_cap ht_cap; - - uint seckeys; /* 54 key table shm address */ - uint tkmickeys; /* 12 TKIP MIC key table shm address */ - - wlc_bss_info_t *default_bss; /* configured BSS parameters */ - - u16 AID; /* association ID */ - u16 counter; /* per-sdu monotonically increasing counter */ - u16 mc_fid_counter; /* BC/MC FIFO frame ID counter */ - - bool ibss_allowed; /* false, all IBSS will be ignored during a scan - * and the driver will not allow the creation of - * an IBSS network - */ - bool ibss_coalesce_allowed; - - char country_default[WLC_CNTRY_BUF_SZ]; /* saved country for leaving 802.11d - * auto-country mode - */ - char autocountry_default[WLC_CNTRY_BUF_SZ]; /* initial country for 802.11d - * auto-country mode - */ -#ifdef BCMDBG - bcm_tlv_t *country_ie_override; /* debug override of announced Country IE */ -#endif - - u16 prb_resp_timeout; /* do not send prb resp if request older than this, - * 0 = disable - */ - - wlc_rateset_t sup_rates_override; /* use only these rates in 11g supported rates if - * specifed - */ - - chanspec_t home_chanspec; /* shared home chanspec */ - - /* PHY parameters */ - chanspec_t chanspec; /* target operational channel */ - u16 usr_fragthresh; /* user configured fragmentation threshold */ - u16 fragthresh[NFIFO]; /* per-fifo fragmentation thresholds */ - u16 RTSThresh; /* 802.11 dot11RTSThreshold */ - u16 SRL; /* 802.11 dot11ShortRetryLimit */ - u16 LRL; /* 802.11 dot11LongRetryLimit */ - u16 SFBL; /* Short Frame Rate Fallback Limit */ - u16 LFBL; /* Long Frame Rate Fallback Limit */ - - /* network config */ - bool shortpreamble; /* currently operating with CCK ShortPreambles */ - bool shortslot; /* currently using 11g ShortSlot timing */ - s8 barker_preamble; /* current Barker Preamble Mode */ - s8 shortslot_override; /* 11g ShortSlot override */ - bool include_legacy_erp; /* include Legacy ERP info elt ID 47 as well as g ID 42 */ - bool barker_overlap_control; /* true: be aware of overlapping BSSs for barker */ - bool ignore_bcns; /* override: ignore non shortslot bcns in a 11g network */ - bool legacy_probe; /* restricts probe requests to CCK rates */ - - wlc_protection_t *protection; - s8 PLCPHdr_override; /* 802.11b Preamble Type override */ - - wlc_stf_t *stf; - - pkt_cb_t *pkt_callback; /* tx completion callback handlers */ - - u32 txretried; /* tx retried number in one msdu */ - - ratespec_t bcn_rspec; /* save bcn ratespec purpose */ - - bool apsd_sta_usp; /* Unscheduled Service Period in progress on STA */ - struct wl_timer *apsd_trigger_timer; /* timer for wme apsd trigger frames */ - u32 apsd_trigger_timeout; /* timeout value for apsd_trigger_timer (in ms) - * 0 == disable - */ - ac_bitmap_t apsd_trigger_ac; /* Permissible Acess Category in which APSD Null - * Trigger frames can be send - */ - u8 htphy_membership; /* HT PHY membership */ - - bool _regulatory_domain; /* 802.11d enabled? */ - - u8 mimops_PM; - - u8 txpwr_percent; /* power output percentage */ - - u8 ht_wsec_restriction; /* the restriction of HT with TKIP or WEP */ - - uint tempsense_lasttime; - - u16 tx_duty_cycle_ofdm; /* maximum allowed duty cycle for OFDM */ - u16 tx_duty_cycle_cck; /* maximum allowed duty cycle for CCK */ - - u16 next_bsscfg_ID; - - struct wlc_if *wlcif_list; /* linked list of wlc_if structs */ - wlc_txq_info_t *active_queue; /* txq for the currently active transmit context */ - u32 mpc_dur; /* total time (ms) in mpc mode except for the - * portion since radio is turned off last time - */ - u32 mpc_laston_ts; /* timestamp (ms) when radio is turned off last - * time - */ - bool pr80838_war; - uint hwrxoff; -}; - -/* antsel module specific state */ -struct antsel_info { - struct wlc_info *wlc; /* pointer to main wlc structure */ - struct wlc_pub *pub; /* pointer to public fn */ - u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic - * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board - */ - u8 antsel_antswitch; /* board level antenna switch type */ - bool antsel_avail; /* Ant selection availability (SROM based) */ - wlc_antselcfg_t antcfg_11n; /* antenna configuration */ - wlc_antselcfg_t antcfg_cur; /* current antenna config (auto) */ -}; - -#define CHANNEL_BANDUNIT(wlc, ch) (((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX) -#define OTHERBANDUNIT(wlc) ((uint)((wlc)->band->bandunit ? BAND_2G_INDEX : BAND_5G_INDEX)) - -#define IS_MBAND_UNLOCKED(wlc) \ - ((NBANDS(wlc) > 1) && !(wlc)->bandlocked) - -#define WLC_BAND_PI_RADIO_CHANSPEC wlc_phy_chanspec_get(wlc->band->pi) - -/* sum the individual fifo tx pending packet counts */ -#define TXPKTPENDTOT(wlc) ((wlc)->core->txpktpend[0] + (wlc)->core->txpktpend[1] + \ - (wlc)->core->txpktpend[2] + (wlc)->core->txpktpend[3]) -#define TXPKTPENDGET(wlc, fifo) ((wlc)->core->txpktpend[(fifo)]) -#define TXPKTPENDINC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] += (val)) -#define TXPKTPENDDEC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] -= (val)) -#define TXPKTPENDCLR(wlc, fifo) ((wlc)->core->txpktpend[(fifo)] = 0) -#define TXAVAIL(wlc, fifo) (*(wlc)->core->txavail[(fifo)]) -#define GETNEXTTXP(wlc, _queue) \ - dma_getnexttxp((wlc)->hw->di[(_queue)], HNDDMA_RANGE_TRANSMITTED) - -#define WLC_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \ - ((len1 == len2) && !memcmp(ssid1, ssid2, len1)) - -extern void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus); -extern void wlc_fatal_error(struct wlc_info *wlc); -extern void wlc_bmac_rpc_watchdog(struct wlc_info *wlc); -extern void wlc_recv(struct wlc_info *wlc, struct sk_buff *p); -extern bool wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2); -extern void wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, - bool commit, s8 txpktpend); -extern void wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend); -extern void wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, - uint prec); -extern void wlc_info_init(struct wlc_info *wlc, int unit); -extern void wlc_print_txstatus(tx_status_t *txs); -extern int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks); -extern void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len, - void *buf); -extern void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len, - bool both); -#if defined(BCMDBG) -extern void wlc_get_rcmta(struct wlc_info *wlc, int idx, - u8 *addr); -#endif -extern void wlc_set_rcmta(struct wlc_info *wlc, int idx, - const u8 *addr); -extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, - const u8 *addr); -extern void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, - u32 *tsf_h_ptr); -extern void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin); -extern void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax); -extern void wlc_fifoerrors(struct wlc_info *wlc); -extern void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit); -extern void wlc_reset_bmac_done(struct wlc_info *wlc); -extern void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val); -extern void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us); -extern void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc); - -#if defined(BCMDBG) -extern void wlc_print_rxh(d11rxhdr_t *rxh); -extern void wlc_print_hdrs(struct wlc_info *wlc, const char *prefix, u8 *frame, - d11txh_t *txh, d11rxhdr_t *rxh, uint len); -extern void wlc_print_txdesc(d11txh_t *txh); -#endif -#if defined(BCMDBG) -extern void wlc_print_dot11_mac_hdr(u8 *buf, int len); -#endif - -extern void wlc_setxband(struct wlc_hw_info *wlc_hw, uint bandunit); -extern void wlc_coredisable(struct wlc_hw_info *wlc_hw); - -extern bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rate, int band, - bool verbose); -extern void wlc_ap_upd(struct wlc_info *wlc); - -/* helper functions */ -extern void wlc_shm_ssid_upd(struct wlc_info *wlc, wlc_bsscfg_t *cfg); -extern int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config); - -extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc); -extern void wlc_mac_bcn_promisc(struct wlc_info *wlc); -extern void wlc_mac_promisc(struct wlc_info *wlc); -extern void wlc_txflowcontrol(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, - int prio); -extern void wlc_txflowcontrol_override(struct wlc_info *wlc, wlc_txq_info_t *qi, - bool on, uint override); -extern bool wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, - wlc_txq_info_t *qi, int prio); -extern void wlc_send_q(struct wlc_info *wlc, wlc_txq_info_t *qi); -extern int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifo); - -extern u16 wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, - uint mac_len); -extern ratespec_t wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, - bool use_rspec, u16 mimo_ctlchbw); -extern u16 wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, - ratespec_t rts_rate, ratespec_t frame_rate, - u8 rts_preamble_type, - u8 frame_preamble_type, uint frame_len, - bool ba); - -extern void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs); - -#if defined(BCMDBG) -extern void wlc_dump_ie(struct wlc_info *wlc, bcm_tlv_t *ie, - struct bcmstrbuf *b); -#endif - -extern bool wlc_ps_check(struct wlc_info *wlc); -extern void wlc_reprate_init(struct wlc_info *wlc); -extern void wlc_bsscfg_reprate_init(wlc_bsscfg_t *bsscfg); -extern void wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, - u32 b_low); -extern u32 wlc_calc_tbtt_offset(u32 bi, u32 tsf_h, u32 tsf_l); - -/* Shared memory access */ -extern void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v); -extern u16 wlc_read_shm(struct wlc_info *wlc, uint offset); -extern void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len); -extern void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, - int len); -extern void wlc_copyfrom_shm(struct wlc_info *wlc, uint offset, void *buf, - int len); - -extern void wlc_update_beacon(struct wlc_info *wlc); -extern void wlc_bss_update_beacon(struct wlc_info *wlc, - struct wlc_bsscfg *bsscfg); - -extern void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend); -extern void wlc_bss_update_probe_resp(struct wlc_info *wlc, wlc_bsscfg_t *cfg, - bool suspend); - -extern bool wlc_ismpc(struct wlc_info *wlc); -extern bool wlc_is_non_delay_mpc(struct wlc_info *wlc); -extern void wlc_radio_mpc_upd(struct wlc_info *wlc); -extern bool wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, - int prec); -extern bool wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, - struct sk_buff *pkt, int prec, bool head); -extern u16 wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec); -extern void wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rate, uint length, - u8 *plcp); -extern uint wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, - u8 preamble_type, uint mac_len); - -extern void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec); - -extern bool wlc_timers_init(struct wlc_info *wlc, int unit); - -extern const bcm_iovar_t wlc_iovars[]; - -extern int wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, - const char *name, void *params, uint p_len, void *arg, - int len, int val_size, struct wlc_if *wlcif); - -#if defined(BCMDBG) -extern void wlc_print_ies(struct wlc_info *wlc, u8 *ies, uint ies_len); -#endif - -extern int wlc_set_nmode(struct wlc_info *wlc, s32 nmode); -extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode); -extern void wlc_mimops_action_ht_send(struct wlc_info *wlc, - wlc_bsscfg_t *bsscfg, u8 mimops_mode); - -extern void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot); -extern void wlc_set_bssid(wlc_bsscfg_t *cfg); -extern void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend); - -extern void wlc_set_ratetable(struct wlc_info *wlc); -extern int wlc_set_mac(wlc_bsscfg_t *cfg); -extern void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, - ratespec_t bcn_rate); -extern void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len); -extern ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, - wlc_rateset_t *rs); -extern u16 wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec, - bool short_preamble, bool phydelay); -extern void wlc_radio_disable(struct wlc_info *wlc); -extern void wlc_bcn_li_upd(struct wlc_info *wlc); - -extern int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len); -extern void wlc_out(struct wlc_info *wlc); -extern void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec); -extern void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt); -extern bool wlc_ps_allowed(struct wlc_info *wlc); -extern bool wlc_stay_awake(struct wlc_info *wlc); -extern void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe); - -extern void wlc_bss_list_free(struct wlc_info *wlc, wlc_bss_list_t *bss_list); -extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode); -#endif /* _wlc_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_phy_shim.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_phy_shim.c deleted file mode 100644 index 8bd4ede4c92a..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_phy_shim.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * This is "two-way" interface, acting as the SHIM layer between WL and PHY layer. - * WL driver can optinally call this translation layer to do some preprocessing, then reach PHY. - * On the PHY->WL driver direction, all calls go through this layer since PHY doesn't have the - * access to wlc_hw pointer. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -/* PHY SHIM module specific state */ -struct wlc_phy_shim_info { - struct wlc_hw_info *wlc_hw; /* pointer to main wlc_hw structure */ - void *wlc; /* pointer to main wlc structure */ - void *wl; /* pointer to os-specific private state */ -}; - -wlc_phy_shim_info_t *wlc_phy_shim_attach(struct wlc_hw_info *wlc_hw, - void *wl, void *wlc) { - wlc_phy_shim_info_t *physhim = NULL; - - physhim = kzalloc(sizeof(wlc_phy_shim_info_t), GFP_ATOMIC); - if (!physhim) { - WL_ERROR("wl%d: wlc_phy_shim_attach: out of mem\n", - wlc_hw->unit); - return NULL; - } - physhim->wlc_hw = wlc_hw; - physhim->wlc = wlc; - physhim->wl = wl; - - return physhim; -} - -void wlc_phy_shim_detach(wlc_phy_shim_info_t *physhim) -{ - if (!physhim) - return; - - kfree(physhim); -} - -struct wlapi_timer *wlapi_init_timer(wlc_phy_shim_info_t *physhim, - void (*fn) (void *arg), void *arg, - const char *name) -{ - return (struct wlapi_timer *)wl_init_timer(physhim->wl, fn, arg, name); -} - -void wlapi_free_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t) -{ - wl_free_timer(physhim->wl, (struct wl_timer *)t); -} - -void -wlapi_add_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t, uint ms, - int periodic) -{ - wl_add_timer(physhim->wl, (struct wl_timer *)t, ms, periodic); -} - -bool wlapi_del_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t) -{ - return wl_del_timer(physhim->wl, (struct wl_timer *)t); -} - -void wlapi_intrson(wlc_phy_shim_info_t *physhim) -{ - wl_intrson(physhim->wl); -} - -u32 wlapi_intrsoff(wlc_phy_shim_info_t *physhim) -{ - return wl_intrsoff(physhim->wl); -} - -void wlapi_intrsrestore(wlc_phy_shim_info_t *physhim, u32 macintmask) -{ - wl_intrsrestore(physhim->wl, macintmask); -} - -void wlapi_bmac_write_shm(wlc_phy_shim_info_t *physhim, uint offset, u16 v) -{ - wlc_bmac_write_shm(physhim->wlc_hw, offset, v); -} - -u16 wlapi_bmac_read_shm(wlc_phy_shim_info_t *physhim, uint offset) -{ - return wlc_bmac_read_shm(physhim->wlc_hw, offset); -} - -void -wlapi_bmac_mhf(wlc_phy_shim_info_t *physhim, u8 idx, u16 mask, - u16 val, int bands) -{ - wlc_bmac_mhf(physhim->wlc_hw, idx, mask, val, bands); -} - -void wlapi_bmac_corereset(wlc_phy_shim_info_t *physhim, u32 flags) -{ - wlc_bmac_corereset(physhim->wlc_hw, flags); -} - -void wlapi_suspend_mac_and_wait(wlc_phy_shim_info_t *physhim) -{ - wlc_suspend_mac_and_wait(physhim->wlc); -} - -void wlapi_switch_macfreq(wlc_phy_shim_info_t *physhim, u8 spurmode) -{ - wlc_bmac_switch_macfreq(physhim->wlc_hw, spurmode); -} - -void wlapi_enable_mac(wlc_phy_shim_info_t *physhim) -{ - wlc_enable_mac(physhim->wlc); -} - -void wlapi_bmac_mctrl(wlc_phy_shim_info_t *physhim, u32 mask, u32 val) -{ - wlc_bmac_mctrl(physhim->wlc_hw, mask, val); -} - -void wlapi_bmac_phy_reset(wlc_phy_shim_info_t *physhim) -{ - wlc_bmac_phy_reset(physhim->wlc_hw); -} - -void wlapi_bmac_bw_set(wlc_phy_shim_info_t *physhim, u16 bw) -{ - wlc_bmac_bw_set(physhim->wlc_hw, bw); -} - -u16 wlapi_bmac_get_txant(wlc_phy_shim_info_t *physhim) -{ - return wlc_bmac_get_txant(physhim->wlc_hw); -} - -void wlapi_bmac_phyclk_fgc(wlc_phy_shim_info_t *physhim, bool clk) -{ - wlc_bmac_phyclk_fgc(physhim->wlc_hw, clk); -} - -void wlapi_bmac_macphyclk_set(wlc_phy_shim_info_t *physhim, bool clk) -{ - wlc_bmac_macphyclk_set(physhim->wlc_hw, clk); -} - -void wlapi_bmac_core_phypll_ctl(wlc_phy_shim_info_t *physhim, bool on) -{ - wlc_bmac_core_phypll_ctl(physhim->wlc_hw, on); -} - -void wlapi_bmac_core_phypll_reset(wlc_phy_shim_info_t *physhim) -{ - wlc_bmac_core_phypll_reset(physhim->wlc_hw); -} - -void wlapi_bmac_ucode_wake_override_phyreg_set(wlc_phy_shim_info_t *physhim) -{ - wlc_ucode_wake_override_set(physhim->wlc_hw, WLC_WAKE_OVERRIDE_PHYREG); -} - -void wlapi_bmac_ucode_wake_override_phyreg_clear(wlc_phy_shim_info_t *physhim) -{ - wlc_ucode_wake_override_clear(physhim->wlc_hw, - WLC_WAKE_OVERRIDE_PHYREG); -} - -void -wlapi_bmac_write_template_ram(wlc_phy_shim_info_t *physhim, int offset, - int len, void *buf) -{ - wlc_bmac_write_template_ram(physhim->wlc_hw, offset, len, buf); -} - -u16 wlapi_bmac_rate_shm_offset(wlc_phy_shim_info_t *physhim, u8 rate) -{ - return wlc_bmac_rate_shm_offset(physhim->wlc_hw, rate); -} - -void wlapi_ucode_sample_init(wlc_phy_shim_info_t *physhim) -{ -} - -void -wlapi_copyfrom_objmem(wlc_phy_shim_info_t *physhim, uint offset, void *buf, - int len, u32 sel) -{ - wlc_bmac_copyfrom_objmem(physhim->wlc_hw, offset, buf, len, sel); -} - -void -wlapi_copyto_objmem(wlc_phy_shim_info_t *physhim, uint offset, const void *buf, - int l, u32 sel) -{ - wlc_bmac_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel); -} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_phy_shim.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_phy_shim.h deleted file mode 100644 index c151a5d8c693..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_phy_shim.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_phy_shim_h_ -#define _wlc_phy_shim_h_ - -#define RADAR_TYPE_NONE 0 /* Radar type None */ -#define RADAR_TYPE_ETSI_1 1 /* ETSI 1 Radar type */ -#define RADAR_TYPE_ETSI_2 2 /* ETSI 2 Radar type */ -#define RADAR_TYPE_ETSI_3 3 /* ETSI 3 Radar type */ -#define RADAR_TYPE_ITU_E 4 /* ITU E Radar type */ -#define RADAR_TYPE_ITU_K 5 /* ITU K Radar type */ -#define RADAR_TYPE_UNCLASSIFIED 6 /* Unclassified Radar type */ -#define RADAR_TYPE_BIN5 7 /* long pulse radar type */ -#define RADAR_TYPE_STG2 8 /* staggered-2 radar */ -#define RADAR_TYPE_STG3 9 /* staggered-3 radar */ -#define RADAR_TYPE_FRA 10 /* French radar */ - -/* French radar pulse widths */ -#define FRA_T1_20MHZ 52770 -#define FRA_T2_20MHZ 61538 -#define FRA_T3_20MHZ 66002 -#define FRA_T1_40MHZ 105541 -#define FRA_T2_40MHZ 123077 -#define FRA_T3_40MHZ 132004 -#define FRA_ERR_20MHZ 60 -#define FRA_ERR_40MHZ 120 - -#define ANTSEL_NA 0 /* No boardlevel selection available */ -#define ANTSEL_2x4 1 /* 2x4 boardlevel selection available */ -#define ANTSEL_2x3 2 /* 2x3 CB2 boardlevel selection available */ - -/* Rx Antenna diversity control values */ -#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */ -#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */ -#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */ -#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */ -#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */ -#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */ - -/* Forward declarations */ -struct wlc_hw_info; -typedef struct wlc_phy_shim_info wlc_phy_shim_info_t; - -extern wlc_phy_shim_info_t *wlc_phy_shim_attach(struct wlc_hw_info *wlc_hw, - void *wl, void *wlc); -extern void wlc_phy_shim_detach(wlc_phy_shim_info_t *physhim); - -/* PHY to WL utility functions */ -struct wlapi_timer; -extern struct wlapi_timer *wlapi_init_timer(wlc_phy_shim_info_t *physhim, - void (*fn) (void *arg), void *arg, - const char *name); -extern void wlapi_free_timer(wlc_phy_shim_info_t *physhim, - struct wlapi_timer *t); -extern void wlapi_add_timer(wlc_phy_shim_info_t *physhim, - struct wlapi_timer *t, uint ms, int periodic); -extern bool wlapi_del_timer(wlc_phy_shim_info_t *physhim, - struct wlapi_timer *t); -extern void wlapi_intrson(wlc_phy_shim_info_t *physhim); -extern u32 wlapi_intrsoff(wlc_phy_shim_info_t *physhim); -extern void wlapi_intrsrestore(wlc_phy_shim_info_t *physhim, - u32 macintmask); - -extern void wlapi_bmac_write_shm(wlc_phy_shim_info_t *physhim, uint offset, - u16 v); -extern u16 wlapi_bmac_read_shm(wlc_phy_shim_info_t *physhim, uint offset); -extern void wlapi_bmac_mhf(wlc_phy_shim_info_t *physhim, u8 idx, - u16 mask, u16 val, int bands); -extern void wlapi_bmac_corereset(wlc_phy_shim_info_t *physhim, u32 flags); -extern void wlapi_suspend_mac_and_wait(wlc_phy_shim_info_t *physhim); -extern void wlapi_switch_macfreq(wlc_phy_shim_info_t *physhim, u8 spurmode); -extern void wlapi_enable_mac(wlc_phy_shim_info_t *physhim); -extern void wlapi_bmac_mctrl(wlc_phy_shim_info_t *physhim, u32 mask, - u32 val); -extern void wlapi_bmac_phy_reset(wlc_phy_shim_info_t *physhim); -extern void wlapi_bmac_bw_set(wlc_phy_shim_info_t *physhim, u16 bw); -extern void wlapi_bmac_phyclk_fgc(wlc_phy_shim_info_t *physhim, bool clk); -extern void wlapi_bmac_macphyclk_set(wlc_phy_shim_info_t *physhim, bool clk); -extern void wlapi_bmac_core_phypll_ctl(wlc_phy_shim_info_t *physhim, bool on); -extern void wlapi_bmac_core_phypll_reset(wlc_phy_shim_info_t *physhim); -extern void wlapi_bmac_ucode_wake_override_phyreg_set(wlc_phy_shim_info_t * - physhim); -extern void wlapi_bmac_ucode_wake_override_phyreg_clear(wlc_phy_shim_info_t * - physhim); -extern void wlapi_bmac_write_template_ram(wlc_phy_shim_info_t *physhim, int o, - int len, void *buf); -extern u16 wlapi_bmac_rate_shm_offset(wlc_phy_shim_info_t *physhim, - u8 rate); -extern void wlapi_ucode_sample_init(wlc_phy_shim_info_t *physhim); -extern void wlapi_copyfrom_objmem(wlc_phy_shim_info_t *physhim, uint, - void *buf, int, u32 sel); -extern void wlapi_copyto_objmem(wlc_phy_shim_info_t *physhim, uint, - const void *buf, int, u32); - -extern void wlapi_high_update_phy_mode(wlc_phy_shim_info_t *physhim, - u32 phy_mode); -extern u16 wlapi_bmac_get_txant(wlc_phy_shim_info_t *physhim); -#endif /* _wlc_phy_shim_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_pub.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_pub.h deleted file mode 100644 index 23e99685d548..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_pub.h +++ /dev/null @@ -1,624 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_pub_h_ -#define _wlc_pub_h_ - -#include -#include - -#define WLC_NUMRATES 16 /* max # of rates in a rateset */ -#define MAXMULTILIST 32 /* max # multicast addresses */ -#define D11_PHY_HDR_LEN 6 /* Phy header length - 6 bytes */ - -/* phy types */ -#define PHY_TYPE_A 0 /* Phy type A */ -#define PHY_TYPE_G 2 /* Phy type G */ -#define PHY_TYPE_N 4 /* Phy type N */ -#define PHY_TYPE_LP 5 /* Phy type Low Power A/B/G */ -#define PHY_TYPE_SSN 6 /* Phy type Single Stream N */ -#define PHY_TYPE_LCN 8 /* Phy type Single Stream N */ -#define PHY_TYPE_LCNXN 9 /* Phy type 2-stream N */ -#define PHY_TYPE_HT 7 /* Phy type 3-Stream N */ - -/* bw */ -#define WLC_10_MHZ 10 /* 10Mhz nphy channel bandwidth */ -#define WLC_20_MHZ 20 /* 20Mhz nphy channel bandwidth */ -#define WLC_40_MHZ 40 /* 40Mhz nphy channel bandwidth */ - -#define CHSPEC_WLC_BW(chanspec) (CHSPEC_IS40(chanspec) ? WLC_40_MHZ : \ - CHSPEC_IS20(chanspec) ? WLC_20_MHZ : \ - WLC_10_MHZ) - -#define WLC_RSSI_MINVAL -200 /* Low value, e.g. for forcing roam */ -#define WLC_RSSI_NO_SIGNAL -91 /* NDIS RSSI link quality cutoffs */ -#define WLC_RSSI_VERY_LOW -80 /* Very low quality cutoffs */ -#define WLC_RSSI_LOW -70 /* Low quality cutoffs */ -#define WLC_RSSI_GOOD -68 /* Good quality cutoffs */ -#define WLC_RSSI_VERY_GOOD -58 /* Very good quality cutoffs */ -#define WLC_RSSI_EXCELLENT -57 /* Excellent quality cutoffs */ - -#define WLC_PHYTYPE(_x) (_x) /* macro to perform WLC PHY -> D11 PHY TYPE, currently 1:1 */ - -#define MA_WINDOW_SZ 8 /* moving average window size */ - -#define WLC_SNR_INVALID 0 /* invalid SNR value */ - -/* a large TX Power as an init value to factor out of min() calculations, - * keep low enough to fit in an s8, units are .25 dBm - */ -#define WLC_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */ - -/* legacy rx Antenna diversity for SISO rates */ -#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */ -#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */ -#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */ -#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */ -#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */ -#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */ - -/* legacy rx Antenna diversity for SISO rates */ -#define ANT_TX_FORCE_0 0 /* Tx on antenna 0, "legacy term Main" */ -#define ANT_TX_FORCE_1 1 /* Tx on antenna 1, "legacy term Aux" */ -#define ANT_TX_LAST_RX 3 /* Tx on phy's last good Rx antenna */ -#define ANT_TX_DEF 3 /* driver's default tx antenna setting */ - -#define TXCORE_POLICY_ALL 0x1 /* use all available core for transmit */ - -/* Tx Chain values */ -#define TXCHAIN_DEF 0x1 /* def bitmap of txchain */ -#define TXCHAIN_DEF_NPHY 0x3 /* default bitmap of tx chains for nphy */ -#define TXCHAIN_DEF_HTPHY 0x7 /* default bitmap of tx chains for nphy */ -#define RXCHAIN_DEF 0x1 /* def bitmap of rxchain */ -#define RXCHAIN_DEF_NPHY 0x3 /* default bitmap of rx chains for nphy */ -#define RXCHAIN_DEF_HTPHY 0x7 /* default bitmap of rx chains for nphy */ -#define ANTSWITCH_NONE 0 /* no antenna switch */ -#define ANTSWITCH_TYPE_1 1 /* antenna switch on 4321CB2, 2of3 */ -#define ANTSWITCH_TYPE_2 2 /* antenna switch on 4321MPCI, 2of3 */ -#define ANTSWITCH_TYPE_3 3 /* antenna switch on 4322, 2of3 */ - -#define RXBUFSZ PKTBUFSZ -#ifndef AIDMAPSZ -#define AIDMAPSZ (roundup(MAXSCB, NBBY)/NBBY) /* aid bitmap size in bytes */ -#endif /* AIDMAPSZ */ - -typedef struct wlc_tunables { - int ntxd; /* size of tx descriptor table */ - int nrxd; /* size of rx descriptor table */ - int rxbufsz; /* size of rx buffers to post */ - int nrxbufpost; /* # of rx buffers to post */ - int maxscb; /* # of SCBs supported */ - int ampdunummpdu; /* max number of mpdu in an ampdu */ - int maxpktcb; /* max # of packet callbacks */ - int maxucodebss; /* max # of BSS handled in ucode bcn/prb */ - int maxucodebss4; /* max # of BSS handled in sw bcn/prb */ - int maxbss; /* max # of bss info elements in scan list */ - int datahiwat; /* data msg txq hiwat mark */ - int ampdudatahiwat; /* AMPDU msg txq hiwat mark */ - int rxbnd; /* max # of rx bufs to process before deferring to dpc */ - int txsbnd; /* max # tx status to process in wlc_txstatus() */ - int memreserved; /* memory reserved for BMAC's USB dma rx */ -} wlc_tunables_t; - -typedef struct wlc_rateset { - uint count; /* number of rates in rates[] */ - u8 rates[WLC_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */ - u8 htphy_membership; /* HT PHY Membership */ - u8 mcs[MCSSET_LEN]; /* supported mcs index bit map */ -} wlc_rateset_t; - -struct rsn_parms { - u8 flags; /* misc booleans (e.g., supported) */ - u8 multicast; /* multicast cipher */ - u8 ucount; /* count of unicast ciphers */ - u8 unicast[4]; /* unicast ciphers */ - u8 acount; /* count of auth modes */ - u8 auth[4]; /* Authentication modes */ - u8 PAD[4]; /* padding for future growth */ -}; - -/* - * buffer length needed for wlc_format_ssid - * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. - */ -#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) - -#define RSN_FLAGS_SUPPORTED 0x1 /* Flag for rsn_params */ -#define RSN_FLAGS_PREAUTH 0x2 /* Flag for WPA2 rsn_params */ - -/* All the HT-specific default advertised capabilities (including AMPDU) - * should be grouped here at one place - */ -#define AMPDU_DEF_MPDU_DENSITY 6 /* default mpdu density (110 ==> 4us) */ - -/* defaults for the HT (MIMO) bss */ -#define HT_CAP ((HT_CAP_MIMO_PS_OFF << IEEE80211_HT_CAP_SM_PS_SHIFT) |\ - IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_GRN_FLD |\ - HT_CAP_MAX_AMSDU | IEEE80211_HT_CAP_DSSSCCK40) - -/* WLC packet type is a void * */ -typedef void *wlc_pkt_t; - -/* Event data type */ -typedef struct wlc_event { - wl_event_msg_t event; /* encapsulated event */ - struct ether_addr *addr; /* used to keep a trace of the potential present of - * an address in wlc_event_msg_t - */ - int bsscfgidx; /* BSS config when needed */ - struct wl_if *wlif; /* pointer to wlif */ - void *data; /* used to hang additional data on an event */ - struct wlc_event *next; /* enables ordered list of pending events */ -} wlc_event_t; - -/* wlc internal bss_info, wl external one is in wlioctl.h */ -typedef struct wlc_bss_info { - u8 BSSID[ETH_ALEN]; /* network BSSID */ - u16 flags; /* flags for internal attributes */ - u8 SSID_len; /* the length of SSID */ - u8 SSID[32]; /* SSID string */ - s16 RSSI; /* receive signal strength (in dBm) */ - s16 SNR; /* receive signal SNR in dB */ - u16 beacon_period; /* units are Kusec */ - u16 atim_window; /* units are Kusec */ - chanspec_t chanspec; /* Channel num, bw, ctrl_sb and band */ - s8 infra; /* 0=IBSS, 1=infrastructure, 2=unknown */ - wlc_rateset_t rateset; /* supported rates */ - u8 dtim_period; /* DTIM period */ - s8 phy_noise; /* noise right after tx (in dBm) */ - u16 capability; /* Capability information */ - u8 wme_qosinfo; /* QoS Info from WME IE; valid if WLC_BSS_WME flag set */ - struct rsn_parms wpa; - struct rsn_parms wpa2; - u16 qbss_load_aac; /* qbss load available admission capacity */ - /* qbss_load_chan_free <- (0xff - channel_utilization of qbss_load_ie_t) */ - u8 qbss_load_chan_free; /* indicates how free the channel is */ - u8 mcipher; /* multicast cipher */ - u8 wpacfg; /* wpa config index */ -} wlc_bss_info_t; - -/* forward declarations */ -struct wlc_if; - -/* wlc_ioctl error codes */ -#define WLC_ENOIOCTL 1 /* No such Ioctl */ -#define WLC_EINVAL 2 /* Invalid value */ -#define WLC_ETOOSMALL 3 /* Value too small */ -#define WLC_ETOOBIG 4 /* Value too big */ -#define WLC_ERANGE 5 /* Out of range */ -#define WLC_EDOWN 6 /* Down */ -#define WLC_EUP 7 /* Up */ -#define WLC_ENOMEM 8 /* No Memory */ -#define WLC_EBUSY 9 /* Busy */ - -/* IOVar flags for common error checks */ -#define IOVF_MFG (1<<3) /* flag for mfgtest iovars */ -#define IOVF_WHL (1<<4) /* value must be whole (0-max) */ -#define IOVF_NTRL (1<<5) /* value must be natural (1-max) */ - -#define IOVF_SET_UP (1<<6) /* set requires driver be up */ -#define IOVF_SET_DOWN (1<<7) /* set requires driver be down */ -#define IOVF_SET_CLK (1<<8) /* set requires core clock */ -#define IOVF_SET_BAND (1<<9) /* set requires fixed band */ - -#define IOVF_GET_UP (1<<10) /* get requires driver be up */ -#define IOVF_GET_DOWN (1<<11) /* get requires driver be down */ -#define IOVF_GET_CLK (1<<12) /* get requires core clock */ -#define IOVF_GET_BAND (1<<13) /* get requires fixed band */ -#define IOVF_OPEN_ALLOW (1<<14) /* set allowed iovar for opensrc */ - -/* watchdog down and dump callback function proto's */ -typedef int (*watchdog_fn_t) (void *handle); -typedef int (*down_fn_t) (void *handle); -typedef int (*dump_fn_t) (void *handle, struct bcmstrbuf *b); - -/* IOVar handler - * - * handle - a pointer value registered with the function - * vi - iovar_info that was looked up - * actionid - action ID, calculated by IOV_GVAL() and IOV_SVAL() based on varid. - * name - the actual iovar name - * params/plen - parameters and length for a get, input only. - * arg/len - buffer and length for value to be set or retrieved, input or output. - * vsize - value size, valid for integer type only. - * wlcif - interface context (wlc_if pointer) - * - * All pointers may point into the same buffer. - */ -typedef int (*iovar_fn_t) (void *handle, const bcm_iovar_t *vi, - u32 actionid, const char *name, void *params, - uint plen, void *arg, int alen, int vsize, - struct wlc_if *wlcif); - -#define MAC80211_PROMISC_BCNS (1 << 0) -#define MAC80211_SCAN (1 << 1) - -/* - * Public portion of "common" os-independent state structure. - * The wlc handle points at this. - */ -struct wlc_pub { - void *wlc; - - struct ieee80211_hw *ieee_hw; - struct scb *global_scb; - scb_ampdu_t *global_ampdu; - uint mac80211_state; - uint unit; /* device instance number */ - uint corerev; /* core revision */ - struct osl_info *osh; /* pointer to os handle */ - si_t *sih; /* SB handle (cookie for siutils calls) */ - char *vars; /* "environment" name=value */ - bool up; /* interface up and running */ - bool hw_off; /* HW is off */ - wlc_tunables_t *tunables; /* tunables: ntxd, nrxd, maxscb, etc. */ - bool hw_up; /* one time hw up/down(from boot or hibernation) */ - bool _piomode; /* true if pio mode *//* BMAC_NOTE: NEED In both */ - uint _nbands; /* # bands supported */ - uint now; /* # elapsed seconds */ - - bool promisc; /* promiscuous destination address */ - bool delayed_down; /* down delayed */ - bool _ap; /* AP mode enabled */ - bool _apsta; /* simultaneous AP/STA mode enabled */ - bool _assoc_recreate; /* association recreation on up transitions */ - int _wme; /* WME QoS mode */ - u8 _mbss; /* MBSS mode on */ - bool allmulti; /* enable all multicasts */ - bool associated; /* true:part of [I]BSS, false: not */ - /* (union of stas_associated, aps_associated) */ - bool phytest_on; /* whether a PHY test is running */ - bool bf_preempt_4306; /* True to enable 'darwin' mode */ - bool _ampdu; /* ampdu enabled or not */ - bool _cac; /* 802.11e CAC enabled */ - u8 _n_enab; /* bitmap of 11N + HT support */ - bool _n_reqd; /* N support required for clients */ - - s8 _coex; /* 20/40 MHz BSS Management AUTO, ENAB, DISABLE */ - bool _priofc; /* Priority-based flowcontrol */ - - u8 cur_etheraddr[ETH_ALEN]; /* our local ethernet address */ - - u8 *multicast; /* ptr to list of multicast addresses */ - uint nmulticast; /* # enabled multicast addresses */ - - u32 wlfeatureflag; /* Flags to control sw features from registry */ - int psq_pkts_total; /* total num of ps pkts */ - - u16 txmaxpkts; /* max number of large pkts allowed to be pending */ - - /* s/w decryption counters */ - u32 swdecrypt; /* s/w decrypt attempts */ - - int bcmerror; /* last bcm error */ - - mbool radio_disabled; /* bit vector for radio disabled reasons */ - bool radio_active; /* radio on/off state */ - u16 roam_time_thresh; /* Max. # secs. of not hearing beacons - * before roaming. - */ - bool align_wd_tbtt; /* Align watchdog with tbtt indication - * handling. This flag is cleared by default - * and is set by per port code explicitly and - * you need to make sure the OSL_SYSUPTIME() - * is implemented properly in osl of that port - * when it enables this Power Save feature. - */ - - u16 boardrev; /* version # of particular board */ - u8 sromrev; /* version # of the srom */ - char srom_ccode[WLC_CNTRY_BUF_SZ]; /* Country Code in SROM */ - u32 boardflags; /* Board specific flags from srom */ - u32 boardflags2; /* More board flags if sromrev >= 4 */ - bool tempsense_disable; /* disable periodic tempsense check */ - - bool _lmac; /* lmac module included and enabled */ - bool _lmacproto; /* lmac protocol module included and enabled */ - bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */ - bool _ampdumac; /* mac assist ampdu enabled or not */ -}; - -/* wl_monitor rx status per packet */ -typedef struct wl_rxsts { - uint pkterror; /* error flags per pkt */ - uint phytype; /* 802.11 A/B/G ... */ - uint channel; /* channel */ - uint datarate; /* rate in 500kbps */ - uint antenna; /* antenna pkts received on */ - uint pktlength; /* pkt length minus bcm phy hdr */ - u32 mactime; /* time stamp from mac, count per 1us */ - uint sq; /* signal quality */ - s32 signal; /* in dbm */ - s32 noise; /* in dbm */ - uint preamble; /* Unknown, short, long */ - uint encoding; /* Unknown, CCK, PBCC, OFDM */ - uint nfrmtype; /* special 802.11n frames(AMPDU, AMSDU) */ - struct wl_if *wlif; /* wl interface */ -} wl_rxsts_t; - -/* status per error RX pkt */ -#define WL_RXS_CRC_ERROR 0x00000001 /* CRC Error in packet */ -#define WL_RXS_RUNT_ERROR 0x00000002 /* Runt packet */ -#define WL_RXS_ALIGN_ERROR 0x00000004 /* Misaligned packet */ -#define WL_RXS_OVERSIZE_ERROR 0x00000008 /* packet bigger than RX_LENGTH (usually 1518) */ -#define WL_RXS_WEP_ICV_ERROR 0x00000010 /* Integrity Check Value error */ -#define WL_RXS_WEP_ENCRYPTED 0x00000020 /* Encrypted with WEP */ -#define WL_RXS_PLCP_SHORT 0x00000040 /* Short PLCP error */ -#define WL_RXS_DECRYPT_ERR 0x00000080 /* Decryption error */ -#define WL_RXS_OTHER_ERR 0x80000000 /* Other errors */ - -/* phy type */ -#define WL_RXS_PHY_A 0x00000000 /* A phy type */ -#define WL_RXS_PHY_B 0x00000001 /* B phy type */ -#define WL_RXS_PHY_G 0x00000002 /* G phy type */ -#define WL_RXS_PHY_N 0x00000004 /* N phy type */ - -/* encoding */ -#define WL_RXS_ENCODING_CCK 0x00000000 /* CCK encoding */ -#define WL_RXS_ENCODING_OFDM 0x00000001 /* OFDM encoding */ - -/* preamble */ -#define WL_RXS_UNUSED_STUB 0x0 /* stub to match with wlc_ethereal.h */ -#define WL_RXS_PREAMBLE_SHORT 0x00000001 /* Short preamble */ -#define WL_RXS_PREAMBLE_LONG 0x00000002 /* Long preamble */ -#define WL_RXS_PREAMBLE_MIMO_MM 0x00000003 /* MIMO mixed mode preamble */ -#define WL_RXS_PREAMBLE_MIMO_GF 0x00000004 /* MIMO green field preamble */ - -#define WL_RXS_NFRM_AMPDU_FIRST 0x00000001 /* first MPDU in A-MPDU */ -#define WL_RXS_NFRM_AMPDU_SUB 0x00000002 /* subsequent MPDU(s) in A-MPDU */ -#define WL_RXS_NFRM_AMSDU_FIRST 0x00000004 /* first MSDU in A-MSDU */ -#define WL_RXS_NFRM_AMSDU_SUB 0x00000008 /* subsequent MSDU(s) in A-MSDU */ - -/* forward declare and use the struct notation so we don't have to - * have it defined if not necessary. - */ -struct wlc_info; -struct wlc_hw_info; -struct wlc_bsscfg; -struct wlc_if; - -/*********************************************** - * Feature-related macros to optimize out code * - * ********************************************* - */ - -/* AP Support (versus STA) */ -#define AP_ENAB(pub) (0) - -/* Macro to check if APSTA mode enabled */ -#define APSTA_ENAB(pub) (0) - -/* Some useful combinations */ -#define STA_ONLY(pub) (!AP_ENAB(pub)) -#define AP_ONLY(pub) (AP_ENAB(pub) && !APSTA_ENAB(pub)) - -#define ENAB_1x1 0x01 -#define ENAB_2x2 0x02 -#define ENAB_3x3 0x04 -#define ENAB_4x4 0x08 -#define SUPPORT_11N (ENAB_1x1|ENAB_2x2) -#define SUPPORT_HT (ENAB_1x1|ENAB_2x2|ENAB_3x3) -/* WL11N Support */ -#if ((defined(NCONF) && (NCONF != 0)) || (defined(LCNCONF) && (LCNCONF != 0)) || \ - (defined(HTCONF) && (HTCONF != 0)) || (defined(SSLPNCONF) && (SSLPNCONF != 0))) -#define N_ENAB(pub) ((pub)->_n_enab & SUPPORT_11N) -#define N_REQD(pub) ((pub)->_n_reqd) -#else -#define N_ENAB(pub) 0 -#define N_REQD(pub) 0 -#endif - -#if (defined(HTCONF) && (HTCONF != 0)) -#define HT_ENAB(pub) (((pub)->_n_enab & SUPPORT_HT) == SUPPORT_HT) -#else -#define HT_ENAB(pub) 0 -#endif - -#define AMPDU_AGG_HOST 1 -#define AMPDU_ENAB(pub) ((pub)->_ampdu) - -#define EDCF_ENAB(pub) (WME_ENAB(pub)) -#define QOS_ENAB(pub) (WME_ENAB(pub) || N_ENAB(pub)) - -#define MONITOR_ENAB(wlc) ((wlc)->monitor) - -#define PROMISC_ENAB(wlc) ((wlc)->promisc) - -#define WLC_PREC_COUNT 16 /* Max precedence level implemented */ - -/* pri is priority encoded in the packet. This maps the Packet priority to - * enqueue precedence as defined in wlc_prec_map - */ -extern const u8 wlc_prio2prec_map[]; -#define WLC_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7] - -/* This maps priority to one precedence higher - Used by PS-Poll response packets to - * simulate enqueue-at-head operation, but still maintain the order on the queue - */ -#define WLC_PRIO_TO_HI_PREC(pri) min(WLC_PRIO_TO_PREC(pri) + 1, WLC_PREC_COUNT - 1) - -extern const u8 wme_fifo2ac[]; -#define WME_PRIO2AC(prio) wme_fifo2ac[prio2fifo[(prio)]] - -/* Mask to describe all precedence levels */ -#define WLC_PREC_BMP_ALL MAXBITVAL(WLC_PREC_COUNT) - -/* Define a bitmap of precedences comprised by each AC */ -#define WLC_PREC_BMP_AC_BE (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BE)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BE)) | \ - NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_EE)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_EE))) -#define WLC_PREC_BMP_AC_BK (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BK)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BK)) | \ - NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NONE)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NONE))) -#define WLC_PREC_BMP_AC_VI (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_CL)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_CL)) | \ - NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VI)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VI))) -#define WLC_PREC_BMP_AC_VO (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VO)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VO)) | \ - NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NC)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NC))) - -/* WME Support */ -#define WME_ENAB(pub) ((pub)->_wme != OFF) -#define WME_AUTO(wlc) ((wlc)->pub->_wme == AUTO) - -#define WLC_USE_COREFLAGS 0xffffffff /* invalid core flags, use the saved coreflags */ - -#define WLC_UPDATE_STATS(wlc) 0 /* No stats support */ -#define WLCNTINCR(a) /* No stats support */ -#define WLCNTDECR(a) /* No stats support */ -#define WLCNTADD(a, delta) /* No stats support */ -#define WLCNTSET(a, value) /* No stats support */ -#define WLCNTVAL(a) 0 /* No stats support */ - -/* common functions for every port */ -extern void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, - bool piomode, struct osl_info *osh, void *regsva, - uint bustype, void *btparam, uint *perr); -extern uint wlc_detach(struct wlc_info *wlc); -extern int wlc_up(struct wlc_info *wlc); -extern uint wlc_down(struct wlc_info *wlc); - -extern int wlc_set(struct wlc_info *wlc, int cmd, int arg); -extern int wlc_get(struct wlc_info *wlc, int cmd, int *arg); -extern int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg); -extern int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg); -extern bool wlc_chipmatch(u16 vendor, u16 device); -extern void wlc_init(struct wlc_info *wlc); -extern void wlc_reset(struct wlc_info *wlc); - -extern void wlc_intrson(struct wlc_info *wlc); -extern u32 wlc_intrsoff(struct wlc_info *wlc); -extern void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask); -extern bool wlc_intrsupd(struct wlc_info *wlc); -extern bool wlc_isr(struct wlc_info *wlc, bool *wantdpc); -extern bool wlc_dpc(struct wlc_info *wlc, bool bounded); -extern bool wlc_send80211_raw(struct wlc_info *wlc, struct wlc_if *wlcif, - void *p, uint ac); -extern bool wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, - struct ieee80211_hw *hw); -extern int wlc_iovar_op(struct wlc_info *wlc, const char *name, void *params, - int p_len, void *arg, int len, bool set, - struct wlc_if *wlcif); -extern int wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, - struct wlc_if *wlcif); -/* helper functions */ -extern void wlc_statsupd(struct wlc_info *wlc); -extern int wlc_get_header_len(void); -extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc); -extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, - const u8 *addr); -extern void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, - bool suspend); - -extern struct wlc_pub *wlc_pub(void *wlc); - -/* common functions for every port */ -extern int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw); -extern int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw); -extern int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw); -extern int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw); - -extern u32 wlc_reg_read(struct wlc_info *wlc, void *r, uint size); -extern void wlc_reg_write(struct wlc_info *wlc, void *r, u32 v, uint size); -extern void wlc_corereset(struct wlc_info *wlc, u32 flags); -extern void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val, - int bands); -extern u16 wlc_mhf_get(struct wlc_info *wlc, u8 idx, int bands); -extern u32 wlc_delta_txfunfl(struct wlc_info *wlc, int fifo); -extern void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset); -extern void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs); - -/* wlc_phy.c helper functions */ -extern void wlc_set_ps_ctrl(struct wlc_info *wlc); -extern void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val); -extern void wlc_scb_ratesel_init_all(struct wlc_info *wlc); - -/* ioctl */ -extern int wlc_iovar_gets8(struct wlc_info *wlc, const char *name, - s8 *arg); -extern int wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, - void *arg, - int len, bool set); - -extern int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, - const char *name, void *hdl, iovar_fn_t iovar_fn, - watchdog_fn_t watchdog_fn, down_fn_t down_fn); -extern int wlc_module_unregister(struct wlc_pub *pub, const char *name, - void *hdl); -extern void wlc_event_if(struct wlc_info *wlc, struct wlc_bsscfg *cfg, - wlc_event_t *e, const struct ether_addr *addr); -extern void wlc_suspend_mac_and_wait(struct wlc_info *wlc); -extern void wlc_enable_mac(struct wlc_info *wlc); -extern u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate); -extern u32 wlc_get_rspec_history(struct wlc_bsscfg *cfg); -extern u32 wlc_get_current_highest_rate(struct wlc_bsscfg *cfg); - -static inline int wlc_iovar_getuint(struct wlc_info *wlc, const char *name, - uint *arg) -{ - return wlc_iovar_getint(wlc, name, (int *)arg); -} - -static inline int wlc_iovar_getu8(struct wlc_info *wlc, const char *name, - u8 *arg) -{ - return wlc_iovar_gets8(wlc, name, (s8 *) arg); -} - -static inline int wlc_iovar_setuint(struct wlc_info *wlc, const char *name, - uint arg) -{ - return wlc_iovar_setint(wlc, name, (int)arg); -} - -#if defined(BCMDBG) -extern int wlc_iocregchk(struct wlc_info *wlc, uint band); -#endif -#if defined(BCMDBG) -extern int wlc_iocpichk(struct wlc_info *wlc, uint phytype); -#endif - -/* helper functions */ -extern void wlc_getrand(struct wlc_info *wlc, u8 *buf, int len); - -struct scb; -extern void wlc_ps_on(struct wlc_info *wlc, struct scb *scb); -extern void wlc_ps_off(struct wlc_info *wlc, struct scb *scb, bool discard); -extern bool wlc_radio_monitor_stop(struct wlc_info *wlc); - -#if defined(BCMDBG) -extern int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len); -#endif - -extern void wlc_pmkid_build_cand_list(struct wlc_bsscfg *cfg, bool check_SSID); -extern void wlc_pmkid_event(struct wlc_bsscfg *cfg); - -#define MAXBANDS 2 /* Maximum #of bands */ -/* bandstate array indices */ -#define BAND_2G_INDEX 0 /* wlc->bandstate[x] index */ -#define BAND_5G_INDEX 1 /* wlc->bandstate[x] index */ - -#define BAND_2G_NAME "2.4G" -#define BAND_5G_NAME "5G" - -/* BMAC RPC: 7 u32 params: pkttotlen, fifo, commit, fid, txpktpend, pktflag, rpc_id */ -#define WLC_RPCTX_PARAMS 32 - -#endif /* _wlc_pub_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.c deleted file mode 100644 index ab7d0bed3c0a..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.c +++ /dev/null @@ -1,501 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* Rate info per rate: It tells whether a rate is ofdm or not and its phy_rate value */ -const u8 rate_info[WLC_MAXRATE + 1] = { - /* 0 1 2 3 4 5 6 7 8 9 */ -/* 0 */ 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 10 */ 0x00, 0x37, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00, -/* 20 */ 0x00, 0x00, 0x6e, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, -/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, -/* 50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 70 */ 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, -/* 100 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c -}; - -/* rates are in units of Kbps */ -const mcs_info_t mcs_table[MCS_TABLE_SIZE] = { - /* MCS 0: SS 1, MOD: BPSK, CR 1/2 */ - {6500, 13500, CEIL(6500 * 10, 9), CEIL(13500 * 10, 9), 0x00, - WLC_RATE_6M}, - /* MCS 1: SS 1, MOD: QPSK, CR 1/2 */ - {13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x08, - WLC_RATE_12M}, - /* MCS 2: SS 1, MOD: QPSK, CR 3/4 */ - {19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x0A, - WLC_RATE_18M}, - /* MCS 3: SS 1, MOD: 16QAM, CR 1/2 */ - {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x10, - WLC_RATE_24M}, - /* MCS 4: SS 1, MOD: 16QAM, CR 3/4 */ - {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x12, - WLC_RATE_36M}, - /* MCS 5: SS 1, MOD: 64QAM, CR 2/3 */ - {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x19, - WLC_RATE_48M}, - /* MCS 6: SS 1, MOD: 64QAM, CR 3/4 */ - {58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x1A, - WLC_RATE_54M}, - /* MCS 7: SS 1, MOD: 64QAM, CR 5/6 */ - {65000, 135000, CEIL(65000 * 10, 9), CEIL(135000 * 10, 9), 0x1C, - WLC_RATE_54M}, - /* MCS 8: SS 2, MOD: BPSK, CR 1/2 */ - {13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x40, - WLC_RATE_6M}, - /* MCS 9: SS 2, MOD: QPSK, CR 1/2 */ - {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x48, - WLC_RATE_12M}, - /* MCS 10: SS 2, MOD: QPSK, CR 3/4 */ - {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x4A, - WLC_RATE_18M}, - /* MCS 11: SS 2, MOD: 16QAM, CR 1/2 */ - {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x50, - WLC_RATE_24M}, - /* MCS 12: SS 2, MOD: 16QAM, CR 3/4 */ - {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x52, - WLC_RATE_36M}, - /* MCS 13: SS 2, MOD: 64QAM, CR 2/3 */ - {104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0x59, - WLC_RATE_48M}, - /* MCS 14: SS 2, MOD: 64QAM, CR 3/4 */ - {117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x5A, - WLC_RATE_54M}, - /* MCS 15: SS 2, MOD: 64QAM, CR 5/6 */ - {130000, 270000, CEIL(130000 * 10, 9), CEIL(270000 * 10, 9), 0x5C, - WLC_RATE_54M}, - /* MCS 16: SS 3, MOD: BPSK, CR 1/2 */ - {19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x80, - WLC_RATE_6M}, - /* MCS 17: SS 3, MOD: QPSK, CR 1/2 */ - {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x88, - WLC_RATE_12M}, - /* MCS 18: SS 3, MOD: QPSK, CR 3/4 */ - {58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x8A, - WLC_RATE_18M}, - /* MCS 19: SS 3, MOD: 16QAM, CR 1/2 */ - {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x90, - WLC_RATE_24M}, - /* MCS 20: SS 3, MOD: 16QAM, CR 3/4 */ - {117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x92, - WLC_RATE_36M}, - /* MCS 21: SS 3, MOD: 64QAM, CR 2/3 */ - {156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0x99, - WLC_RATE_48M}, - /* MCS 22: SS 3, MOD: 64QAM, CR 3/4 */ - {175500, 364500, CEIL(175500 * 10, 9), CEIL(364500 * 10, 9), 0x9A, - WLC_RATE_54M}, - /* MCS 23: SS 3, MOD: 64QAM, CR 5/6 */ - {195000, 405000, CEIL(195000 * 10, 9), CEIL(405000 * 10, 9), 0x9B, - WLC_RATE_54M}, - /* MCS 24: SS 4, MOD: BPSK, CR 1/2 */ - {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0xC0, - WLC_RATE_6M}, - /* MCS 25: SS 4, MOD: QPSK, CR 1/2 */ - {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0xC8, - WLC_RATE_12M}, - /* MCS 26: SS 4, MOD: QPSK, CR 3/4 */ - {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0xCA, - WLC_RATE_18M}, - /* MCS 27: SS 4, MOD: 16QAM, CR 1/2 */ - {104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0xD0, - WLC_RATE_24M}, - /* MCS 28: SS 4, MOD: 16QAM, CR 3/4 */ - {156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0xD2, - WLC_RATE_36M}, - /* MCS 29: SS 4, MOD: 64QAM, CR 2/3 */ - {208000, 432000, CEIL(208000 * 10, 9), CEIL(432000 * 10, 9), 0xD9, - WLC_RATE_48M}, - /* MCS 30: SS 4, MOD: 64QAM, CR 3/4 */ - {234000, 486000, CEIL(234000 * 10, 9), CEIL(486000 * 10, 9), 0xDA, - WLC_RATE_54M}, - /* MCS 31: SS 4, MOD: 64QAM, CR 5/6 */ - {260000, 540000, CEIL(260000 * 10, 9), CEIL(540000 * 10, 9), 0xDB, - WLC_RATE_54M}, - /* MCS 32: SS 1, MOD: BPSK, CR 1/2 */ - {0, 6000, 0, CEIL(6000 * 10, 9), 0x00, WLC_RATE_6M}, -}; - -/* phycfg for legacy OFDM frames: code rate, modulation scheme, spatial streams - * Number of spatial streams: always 1 - * other fields: refer to table 78 of section 17.3.2.2 of the original .11a standard - */ -typedef struct legacy_phycfg { - u32 rate_ofdm; /* ofdm mac rate */ - u8 tx_phy_ctl3; /* phy ctl byte 3, code rate, modulation type, # of streams */ -} legacy_phycfg_t; - -#define LEGACY_PHYCFG_TABLE_SIZE 12 /* Number of legacy_rate_cfg entries in the table */ - -/* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */ -/* Eventually MIMOPHY would also be converted to this format */ -/* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */ -static const legacy_phycfg_t legacy_phycfg_table[LEGACY_PHYCFG_TABLE_SIZE] = { - {WLC_RATE_1M, 0x00}, /* CCK 1Mbps, data rate 0 */ - {WLC_RATE_2M, 0x08}, /* CCK 2Mbps, data rate 1 */ - {WLC_RATE_5M5, 0x10}, /* CCK 5.5Mbps, data rate 2 */ - {WLC_RATE_11M, 0x18}, /* CCK 11Mbps, data rate 3 */ - {WLC_RATE_6M, 0x00}, /* OFDM 6Mbps, code rate 1/2, BPSK, 1 spatial stream */ - {WLC_RATE_9M, 0x02}, /* OFDM 9Mbps, code rate 3/4, BPSK, 1 spatial stream */ - {WLC_RATE_12M, 0x08}, /* OFDM 12Mbps, code rate 1/2, QPSK, 1 spatial stream */ - {WLC_RATE_18M, 0x0A}, /* OFDM 18Mbps, code rate 3/4, QPSK, 1 spatial stream */ - {WLC_RATE_24M, 0x10}, /* OFDM 24Mbps, code rate 1/2, 16-QAM, 1 spatial stream */ - {WLC_RATE_36M, 0x12}, /* OFDM 36Mbps, code rate 3/4, 16-QAM, 1 spatial stream */ - {WLC_RATE_48M, 0x19}, /* OFDM 48Mbps, code rate 2/3, 64-QAM, 1 spatial stream */ - {WLC_RATE_54M, 0x1A}, /* OFDM 54Mbps, code rate 3/4, 64-QAM, 1 spatial stream */ -}; - -/* Hardware rates (also encodes default basic rates) */ - -const wlc_rateset_t cck_ofdm_mimo_rates = { - 12, - { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */ - 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60, - 0x6c}, - 0x00, - {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -const wlc_rateset_t ofdm_mimo_rates = { - 8, - { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */ - 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c}, - 0x00, - {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -/* Default ratesets that include MCS32 for 40BW channels */ -const wlc_rateset_t cck_ofdm_40bw_mimo_rates = { - 12, - { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */ - 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60, - 0x6c}, - 0x00, - {0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -const wlc_rateset_t ofdm_40bw_mimo_rates = { - 8, - { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */ - 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c}, - 0x00, - {0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -const wlc_rateset_t cck_ofdm_rates = { - 12, - { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */ - 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60, - 0x6c}, - 0x00, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -const wlc_rateset_t gphy_legacy_rates = { - 4, - { /* 1b, 2b, 5.5b, 11b Mbps */ - 0x82, 0x84, 0x8b, 0x96}, - 0x00, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -const wlc_rateset_t ofdm_rates = { - 8, - { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */ - 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c}, - 0x00, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -const wlc_rateset_t cck_rates = { - 4, - { /* 1b, 2b, 5.5, 11 Mbps */ - 0x82, 0x84, 0x0b, 0x16}, - 0x00, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} -}; - -static bool wlc_rateset_valid(wlc_rateset_t *rs, bool check_brate); - -/* check if rateset is valid. - * if check_brate is true, rateset without a basic rate is considered NOT valid. - */ -static bool wlc_rateset_valid(wlc_rateset_t *rs, bool check_brate) -{ - uint idx; - - if (!rs->count) - return false; - - if (!check_brate) - return true; - - /* error if no basic rates */ - for (idx = 0; idx < rs->count; idx++) { - if (rs->rates[idx] & WLC_RATE_FLAG) - return true; - } - return false; -} - -void wlc_rateset_mcs_upd(wlc_rateset_t *rs, u8 txstreams) -{ - int i; - for (i = txstreams; i < MAX_STREAMS_SUPPORTED; i++) - rs->mcs[i] = 0; -} - -/* filter based on hardware rateset, and sort filtered rateset with basic bit(s) preserved, - * and check if resulting rateset is valid. -*/ -bool -wlc_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs, - const wlc_rateset_t *hw_rs, - bool check_brate, u8 txstreams) -{ - u8 rateset[WLC_MAXRATE + 1]; - u8 r; - uint count; - uint i; - - memset(rateset, 0, sizeof(rateset)); - count = rs->count; - - for (i = 0; i < count; i++) { - /* mask off "basic rate" bit, WLC_RATE_FLAG */ - r = (int)rs->rates[i] & RATE_MASK; - if ((r > WLC_MAXRATE) || (rate_info[r] == 0)) { - continue; - } - rateset[r] = rs->rates[i]; /* preserve basic bit! */ - } - - /* fill out the rates in order, looking at only supported rates */ - count = 0; - for (i = 0; i < hw_rs->count; i++) { - r = hw_rs->rates[i] & RATE_MASK; - ASSERT(r <= WLC_MAXRATE); - if (rateset[r]) - rs->rates[count++] = rateset[r]; - } - - rs->count = count; - - /* only set the mcs rate bit if the equivalent hw mcs bit is set */ - for (i = 0; i < MCSSET_LEN; i++) - rs->mcs[i] = (rs->mcs[i] & hw_rs->mcs[i]); - - if (wlc_rateset_valid(rs, check_brate)) - return true; - else - return false; -} - -/* caluclate the rate of a rx'd frame and return it as a ratespec */ -ratespec_t BCMFASTPATH wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp) -{ - int phy_type; - ratespec_t rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT; - - phy_type = - ((rxh->RxChan & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT); - - if ((phy_type == PHY_TYPE_N) || (phy_type == PHY_TYPE_SSN) || - (phy_type == PHY_TYPE_LCN) || (phy_type == PHY_TYPE_HT)) { - switch (rxh->PhyRxStatus_0 & PRXS0_FT_MASK) { - case PRXS0_CCK: - rspec = - CCK_PHY2MAC_RATE(((cck_phy_hdr_t *) plcp)->signal); - break; - case PRXS0_OFDM: - rspec = - OFDM_PHY2MAC_RATE(((ofdm_phy_hdr_t *) plcp)-> - rlpt[0]); - break; - case PRXS0_PREN: - rspec = (plcp[0] & MIMO_PLCP_MCS_MASK) | RSPEC_MIMORATE; - if (plcp[0] & MIMO_PLCP_40MHZ) { - /* indicate rspec is for 40 MHz mode */ - rspec &= ~RSPEC_BW_MASK; - rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT); - } - break; - case PRXS0_STDN: - /* fallthru */ - default: - /* not supported */ - ASSERT(0); - break; - } - if (PLCP3_ISSGI(plcp[3])) - rspec |= RSPEC_SHORT_GI; - } else - if ((phy_type == PHY_TYPE_A) || (rxh->PhyRxStatus_0 & PRXS0_OFDM)) - rspec = OFDM_PHY2MAC_RATE(((ofdm_phy_hdr_t *) plcp)->rlpt[0]); - else - rspec = CCK_PHY2MAC_RATE(((cck_phy_hdr_t *) plcp)->signal); - - return rspec; -} - -/* copy rateset src to dst as-is (no masking or sorting) */ -void wlc_rateset_copy(const wlc_rateset_t *src, wlc_rateset_t *dst) -{ - bcopy(src, dst, sizeof(wlc_rateset_t)); -} - -/* - * Copy and selectively filter one rateset to another. - * 'basic_only' means only copy basic rates. - * 'rates' indicates cck (11b) and ofdm rates combinations. - * - 0: cck and ofdm - * - 1: cck only - * - 2: ofdm only - * 'xmask' is the copy mask (typically 0x7f or 0xff). - */ -void -wlc_rateset_filter(wlc_rateset_t *src, wlc_rateset_t *dst, bool basic_only, - u8 rates, uint xmask, bool mcsallow) -{ - uint i; - uint r; - uint count; - - count = 0; - for (i = 0; i < src->count; i++) { - r = src->rates[i]; - if (basic_only && !(r & WLC_RATE_FLAG)) - continue; - if ((rates == WLC_RATES_CCK) && IS_OFDM((r & RATE_MASK))) - continue; - if ((rates == WLC_RATES_OFDM) && IS_CCK((r & RATE_MASK))) - continue; - dst->rates[count++] = r & xmask; - } - dst->count = count; - dst->htphy_membership = src->htphy_membership; - - if (mcsallow && rates != WLC_RATES_CCK) - bcopy(&src->mcs[0], &dst->mcs[0], MCSSET_LEN); - else - wlc_rateset_mcs_clear(dst); -} - -/* select rateset for a given phy_type and bandtype and filter it, sort it - * and fill rs_tgt with result - */ -void -wlc_rateset_default(wlc_rateset_t *rs_tgt, const wlc_rateset_t *rs_hw, - uint phy_type, int bandtype, bool cck_only, uint rate_mask, - bool mcsallow, u8 bw, u8 txstreams) -{ - const wlc_rateset_t *rs_dflt; - wlc_rateset_t rs_sel; - if ((PHYTYPE_IS(phy_type, PHY_TYPE_HT)) || - (PHYTYPE_IS(phy_type, PHY_TYPE_N)) || - (PHYTYPE_IS(phy_type, PHY_TYPE_LCN)) || - (PHYTYPE_IS(phy_type, PHY_TYPE_SSN))) { - if (BAND_5G(bandtype)) { - rs_dflt = (bw == WLC_20_MHZ ? - &ofdm_mimo_rates : &ofdm_40bw_mimo_rates); - } else { - rs_dflt = (bw == WLC_20_MHZ ? - &cck_ofdm_mimo_rates : - &cck_ofdm_40bw_mimo_rates); - } - } else if (PHYTYPE_IS(phy_type, PHY_TYPE_LP)) { - rs_dflt = (BAND_5G(bandtype)) ? &ofdm_rates : &cck_ofdm_rates; - } else if (PHYTYPE_IS(phy_type, PHY_TYPE_A)) { - rs_dflt = &ofdm_rates; - } else if (PHYTYPE_IS(phy_type, PHY_TYPE_G)) { - rs_dflt = &cck_ofdm_rates; - } else { - ASSERT(0); /* should not happen */ - rs_dflt = &cck_rates; /* force cck */ - } - - /* if hw rateset is not supplied, assign selected rateset to it */ - if (!rs_hw) - rs_hw = rs_dflt; - - wlc_rateset_copy(rs_dflt, &rs_sel); - wlc_rateset_mcs_upd(&rs_sel, txstreams); - wlc_rateset_filter(&rs_sel, rs_tgt, false, - cck_only ? WLC_RATES_CCK : WLC_RATES_CCK_OFDM, - rate_mask, mcsallow); - wlc_rate_hwrs_filter_sort_validate(rs_tgt, rs_hw, false, - mcsallow ? txstreams : 1); -} - -s16 BCMFASTPATH wlc_rate_legacy_phyctl(uint rate) -{ - uint i; - for (i = 0; i < LEGACY_PHYCFG_TABLE_SIZE; i++) - if (rate == legacy_phycfg_table[i].rate_ofdm) - return legacy_phycfg_table[i].tx_phy_ctl3; - - return -1; -} - -void wlc_rateset_mcs_clear(wlc_rateset_t *rateset) -{ - uint i; - for (i = 0; i < MCSSET_LEN; i++) - rateset->mcs[i] = 0; -} - -void wlc_rateset_mcs_build(wlc_rateset_t *rateset, u8 txstreams) -{ - bcopy(&cck_ofdm_mimo_rates.mcs[0], &rateset->mcs[0], MCSSET_LEN); - wlc_rateset_mcs_upd(rateset, txstreams); -} - -/* Based on bandwidth passed, allow/disallow MCS 32 in the rateset */ -void wlc_rateset_bw_mcs_filter(wlc_rateset_t *rateset, u8 bw) -{ - if (bw == WLC_40_MHZ) - setbit(rateset->mcs, 32); - else - clrbit(rateset->mcs, 32); -} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.h deleted file mode 100644 index 25ba2a423639..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_rate.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _WLC_RATE_H_ -#define _WLC_RATE_H_ - -extern const u8 rate_info[]; -extern const struct wlc_rateset cck_ofdm_mimo_rates; -extern const struct wlc_rateset ofdm_mimo_rates; -extern const struct wlc_rateset cck_ofdm_rates; -extern const struct wlc_rateset ofdm_rates; -extern const struct wlc_rateset cck_rates; -extern const struct wlc_rateset gphy_legacy_rates; -extern const struct wlc_rateset wlc_lrs_rates; -extern const struct wlc_rateset rate_limit_1_2; - -typedef struct mcs_info { - u32 phy_rate_20; /* phy rate in kbps [20Mhz] */ - u32 phy_rate_40; /* phy rate in kbps [40Mhz] */ - u32 phy_rate_20_sgi; /* phy rate in kbps [20Mhz] with SGI */ - u32 phy_rate_40_sgi; /* phy rate in kbps [40Mhz] with SGI */ - u8 tx_phy_ctl3; /* phy ctl byte 3, code rate, modulation type, # of streams */ - u8 leg_ofdm; /* matching legacy ofdm rate in 500bkps */ -} mcs_info_t; - -#define WLC_MAXMCS 32 /* max valid mcs index */ -#define MCS_TABLE_SIZE 33 /* Number of mcs entries in the table */ -extern const mcs_info_t mcs_table[]; - -#define MCS_INVALID 0xFF -#define MCS_CR_MASK 0x07 /* Code Rate bit mask */ -#define MCS_MOD_MASK 0x38 /* Modulation bit shift */ -#define MCS_MOD_SHIFT 3 /* MOdulation bit shift */ -#define MCS_TXS_MASK 0xc0 /* num tx streams - 1 bit mask */ -#define MCS_TXS_SHIFT 6 /* num tx streams - 1 bit shift */ -#define MCS_CR(_mcs) (mcs_table[_mcs].tx_phy_ctl3 & MCS_CR_MASK) -#define MCS_MOD(_mcs) ((mcs_table[_mcs].tx_phy_ctl3 & MCS_MOD_MASK) >> MCS_MOD_SHIFT) -#define MCS_TXS(_mcs) ((mcs_table[_mcs].tx_phy_ctl3 & MCS_TXS_MASK) >> MCS_TXS_SHIFT) -#define MCS_RATE(_mcs, _is40, _sgi) (_sgi ? \ - (_is40 ? mcs_table[_mcs].phy_rate_40_sgi : mcs_table[_mcs].phy_rate_20_sgi) : \ - (_is40 ? mcs_table[_mcs].phy_rate_40 : mcs_table[_mcs].phy_rate_20)) -#define VALID_MCS(_mcs) ((_mcs < MCS_TABLE_SIZE)) - -#define WLC_RATE_FLAG 0x80 /* Rate flag: basic or ofdm */ - -/* Macros to use the rate_info table */ -#define RATE_MASK 0x7f /* Rate value mask w/o basic rate flag */ -#define RATE_MASK_FULL 0xff /* Rate value mask with basic rate flag */ - -#define WLC_RATE_500K_TO_BPS(rate) ((rate) * 500000) /* convert 500kbps to bps */ - -/* rate spec : holds rate and mode specific information required to generate a tx frame. */ -/* Legacy CCK and OFDM information is held in the same manner as was done in the past */ -/* (in the lower byte) the upper 3 bytes primarily hold MIMO specific information */ -typedef u32 ratespec_t; - -/* rate spec bit fields */ -#define RSPEC_RATE_MASK 0x0000007F /* Either 500Kbps units or MIMO MCS idx */ -#define RSPEC_MIMORATE 0x08000000 /* mimo MCS is stored in RSPEC_RATE_MASK */ -#define RSPEC_BW_MASK 0x00000700 /* mimo bw mask */ -#define RSPEC_BW_SHIFT 8 /* mimo bw shift */ -#define RSPEC_STF_MASK 0x00003800 /* mimo Space/Time/Frequency mode mask */ -#define RSPEC_STF_SHIFT 11 /* mimo Space/Time/Frequency mode shift */ -#define RSPEC_CT_MASK 0x0000C000 /* mimo coding type mask */ -#define RSPEC_CT_SHIFT 14 /* mimo coding type shift */ -#define RSPEC_STC_MASK 0x00300000 /* mimo num STC streams per PLCP defn. */ -#define RSPEC_STC_SHIFT 20 /* mimo num STC streams per PLCP defn. */ -#define RSPEC_LDPC_CODING 0x00400000 /* mimo bit indicates adv coding in use */ -#define RSPEC_SHORT_GI 0x00800000 /* mimo bit indicates short GI in use */ -#define RSPEC_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */ -#define RSPEC_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicates override rate only */ - -#define WLC_HTPHY 127 /* HT PHY Membership */ - -#define RSPEC_ACTIVE(rspec) (rspec & (RSPEC_RATE_MASK | RSPEC_MIMORATE)) -#define RSPEC2RATE(rspec) ((rspec & RSPEC_MIMORATE) ? \ - MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec)) : \ - (rspec & RSPEC_RATE_MASK)) -/* return rate in unit of 500Kbps -- for internal use in wlc_rate_sel.c */ -#define RSPEC2RATE500K(rspec) ((rspec & RSPEC_MIMORATE) ? \ - MCS_RATE((rspec & RSPEC_RATE_MASK), state->is40bw, RSPEC_ISSGI(rspec))/500 : \ - (rspec & RSPEC_RATE_MASK)) -#define CRSPEC2RATE500K(rspec) ((rspec & RSPEC_MIMORATE) ? \ - MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec))/500 :\ - (rspec & RSPEC_RATE_MASK)) - -#define RSPEC2KBPS(rspec) (IS_MCS(rspec) ? RSPEC2RATE(rspec) : RSPEC2RATE(rspec)*500) -#define RSPEC_PHYTXBYTE2(rspec) ((rspec & 0xff00) >> 8) -#define RSPEC_GET_BW(rspec) ((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT) -#define RSPEC_IS40MHZ(rspec) ((((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT) == \ - PHY_TXC1_BW_40MHZ) || (((rspec & RSPEC_BW_MASK) >> \ - RSPEC_BW_SHIFT) == PHY_TXC1_BW_40MHZ_DUP)) -#define RSPEC_ISSGI(rspec) ((rspec & RSPEC_SHORT_GI) == RSPEC_SHORT_GI) -#define RSPEC_MIMOPLCP3(rspec) ((rspec & 0xf00000) >> 16) -#define PLCP3_ISSGI(plcp) (plcp & (RSPEC_SHORT_GI >> 16)) -#define RSPEC_STC(rspec) ((rspec & RSPEC_STC_MASK) >> RSPEC_STC_SHIFT) -#define RSPEC_STF(rspec) ((rspec & RSPEC_STF_MASK) >> RSPEC_STF_SHIFT) -#define PLCP3_ISSTBC(plcp) ((plcp & (RSPEC_STC_MASK) >> 16) == 0x10) -#define PLCP3_STC_MASK 0x30 -#define PLCP3_STC_SHIFT 4 - -/* Rate info table; takes a legacy rate or ratespec_t */ -#define IS_MCS(r) (r & RSPEC_MIMORATE) -#define IS_OFDM(r) (!IS_MCS(r) && (rate_info[(r) & RSPEC_RATE_MASK] & WLC_RATE_FLAG)) -#define IS_CCK(r) (!IS_MCS(r) && (((r) & RATE_MASK) == WLC_RATE_1M || \ - ((r) & RATE_MASK) == WLC_RATE_2M || \ - ((r) & RATE_MASK) == WLC_RATE_5M5 || ((r) & RATE_MASK) == WLC_RATE_11M)) -#define IS_SINGLE_STREAM(mcs) (((mcs) <= HIGHEST_SINGLE_STREAM_MCS) || ((mcs) == 32)) -#define CCK_RSPEC(cck) ((cck) & RSPEC_RATE_MASK) -#define OFDM_RSPEC(ofdm) (((ofdm) & RSPEC_RATE_MASK) |\ - (PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT)) -#define LEGACY_RSPEC(rate) (IS_CCK(rate) ? CCK_RSPEC(rate) : OFDM_RSPEC(rate)) - -#define MCS_RSPEC(mcs) (((mcs) & RSPEC_RATE_MASK) | RSPEC_MIMORATE | \ - (IS_SINGLE_STREAM(mcs) ? (PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT) : \ - (PHY_TXC1_MODE_SDM << RSPEC_STF_SHIFT))) - -/* Convert encoded rate value in plcp header to numerical rates in 500 KHz increments */ -extern const u8 ofdm_rate_lookup[]; -#define OFDM_PHY2MAC_RATE(rlpt) (ofdm_rate_lookup[rlpt & 0x7]) -#define CCK_PHY2MAC_RATE(signal) (signal/5) - -/* Rates specified in wlc_rateset_filter() */ -#define WLC_RATES_CCK_OFDM 0 -#define WLC_RATES_CCK 1 -#define WLC_RATES_OFDM 2 - -/* use the stuct form instead of typedef to fix dependency problems */ -struct wlc_rateset; - -/* sanitize, and sort a rateset with the basic bit(s) preserved, validate rateset */ -extern bool wlc_rate_hwrs_filter_sort_validate(struct wlc_rateset *rs, - const struct wlc_rateset *hw_rs, - bool check_brate, - u8 txstreams); -/* copy rateset src to dst as-is (no masking or sorting) */ -extern void wlc_rateset_copy(const struct wlc_rateset *src, - struct wlc_rateset *dst); - -/* would be nice to have these documented ... */ -extern ratespec_t wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp); - -extern void wlc_rateset_filter(struct wlc_rateset *src, struct wlc_rateset *dst, - bool basic_only, u8 rates, uint xmask, - bool mcsallow); -extern void wlc_rateset_default(struct wlc_rateset *rs_tgt, - const struct wlc_rateset *rs_hw, uint phy_type, - int bandtype, bool cck_only, uint rate_mask, - bool mcsallow, u8 bw, u8 txstreams); -extern s16 wlc_rate_legacy_phyctl(uint rate); - -extern void wlc_rateset_mcs_upd(struct wlc_rateset *rs, u8 txstreams); -extern void wlc_rateset_mcs_clear(struct wlc_rateset *rateset); -extern void wlc_rateset_mcs_build(struct wlc_rateset *rateset, u8 txstreams); -extern void wlc_rateset_bw_mcs_filter(struct wlc_rateset *rateset, u8 bw); - -#endif /* _WLC_RATE_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_scb.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_scb.h deleted file mode 100644 index 142b75674444..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_scb.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_scb_h_ -#define _wlc_scb_h_ - -#include - -extern bool wlc_aggregatable(struct wlc_info *wlc, u8 tid); - -#define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */ -/* structure to store per-tid state for the ampdu initiator */ -typedef struct scb_ampdu_tid_ini { - u32 magic; - u8 tx_in_transit; /* number of pending mpdus in transit in driver */ - u8 tid; /* initiator tid for easy lookup */ - u8 txretry[AMPDU_TX_BA_MAX_WSIZE]; /* tx retry count; indexed by seq modulo */ - struct scb *scb; /* backptr for easy lookup */ -} scb_ampdu_tid_ini_t; - -#define AMPDU_MAX_SCB_TID NUMPRIO - -typedef struct scb_ampdu { - struct scb *scb; /* back pointer for easy reference */ - u8 mpdu_density; /* mpdu density */ - u8 max_pdu; /* max pdus allowed in ampdu */ - u8 release; /* # of mpdus released at a time */ - u16 min_len; /* min mpdu len to support the density */ - u32 max_rxlen; /* max ampdu rcv length; 8k, 16k, 32k, 64k */ - struct pktq txq; /* sdu transmit queue pending aggregation */ - - /* This could easily be a ini[] pointer and we keep this info in wl itself instead - * of having mac80211 hold it for us. Also could be made dynamic per tid instead of - * static. - */ - scb_ampdu_tid_ini_t ini[AMPDU_MAX_SCB_TID]; /* initiator info - per tid (NUMPRIO) */ -} scb_ampdu_t; - -#define SCB_MAGIC 0xbeefcafe -#define INI_MAGIC 0xabcd1234 - -/* station control block - one per remote MAC address */ -struct scb { - u32 magic; - u32 flags; /* various bit flags as defined below */ - u32 flags2; /* various bit flags2 as defined below */ - u8 state; /* current state bitfield of auth/assoc process */ - u8 ea[ETH_ALEN]; /* station address */ - void *fragbuf[NUMPRIO]; /* defragmentation buffer per prio */ - uint fragresid[NUMPRIO]; /* #bytes unused in frag buffer per prio */ - - u16 seqctl[NUMPRIO]; /* seqctl of last received frame (for dups) */ - u16 seqctl_nonqos; /* seqctl of last received frame (for dups) for - * non-QoS data and management - */ - u16 seqnum[NUMPRIO]; /* WME: driver maintained sw seqnum per priority */ - - scb_ampdu_t scb_ampdu; /* AMPDU state including per tid info */ -}; - -/* scb flags */ -#define SCB_WMECAP 0x0040 /* may ONLY be set if WME_ENAB(wlc) */ -#define SCB_HTCAP 0x10000 /* HT (MIMO) capable device */ -#define SCB_IS40 0x80000 /* 40MHz capable */ -#define SCB_STBCCAP 0x40000000 /* STBC Capable */ -#define SCB_WME(a) ((a)->flags & SCB_WMECAP)/* implies WME_ENAB */ -#define SCB_SEQNUM(scb, prio) ((scb)->seqnum[(prio)]) -#define SCB_PS(a) NULL -#define SCB_STBC_CAP(a) ((a)->flags & SCB_STBCCAP) -#define SCB_AMPDU(a) true -#endif /* _wlc_scb_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.c deleted file mode 100644 index 10c9f447cdf0..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.c +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define WLC_STF_SS_STBC_RX(wlc) (WLCISNPHY(wlc->band) && \ - NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6)) - -static s8 wlc_stf_stbc_rx_get(struct wlc_info *wlc); -static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val); -static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 val); -static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val); -static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val); - -static void _wlc_stf_phy_txant_upd(struct wlc_info *wlc); -static u16 _wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec); - -#define NSTS_1 1 -#define NSTS_2 2 -#define NSTS_3 3 -#define NSTS_4 4 -const u8 txcore_default[5] = { - (0), /* bitmap of the core enabled */ - (0x01), /* For Nsts = 1, enable core 1 */ - (0x03), /* For Nsts = 2, enable core 1 & 2 */ - (0x07), /* For Nsts = 3, enable core 1, 2 & 3 */ - (0x0f) /* For Nsts = 4, enable all cores */ -}; - -static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val) -{ - ASSERT((val == HT_CAP_RX_STBC_NO) - || (val == HT_CAP_RX_STBC_ONE_STREAM)); - - /* MIMOPHYs rev3-6 cannot receive STBC with only one rx core active */ - if (WLC_STF_SS_STBC_RX(wlc)) { - if ((wlc->stf->rxstreams == 1) && (val != HT_CAP_RX_STBC_NO)) - return; - } - - wlc->ht_cap.cap_info &= ~HT_CAP_RX_STBC_MASK; - wlc->ht_cap.cap_info |= (val << HT_CAP_RX_STBC_SHIFT); - - if (wlc->pub->up) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - } -} - -/* every WLC_TEMPSENSE_PERIOD seconds temperature check to decide whether to turn on/off txchain */ -void wlc_tempsense_upd(struct wlc_info *wlc) -{ - wlc_phy_t *pi = wlc->band->pi; - uint active_chains, txchain; - - /* Check if the chip is too hot. Disable one Tx chain, if it is */ - /* high 4 bits are for Rx chain, low 4 bits are for Tx chain */ - active_chains = wlc_phy_stf_chain_active_get(pi); - txchain = active_chains & 0xf; - - if (wlc->stf->txchain == wlc->stf->hw_txchain) { - if (txchain && (txchain < wlc->stf->hw_txchain)) { - /* turn off 1 tx chain */ - wlc_stf_txchain_set(wlc, txchain, true); - } - } else if (wlc->stf->txchain < wlc->stf->hw_txchain) { - if (txchain == wlc->stf->hw_txchain) { - /* turn back on txchain */ - wlc_stf_txchain_set(wlc, txchain, true); - } - } -} - -void -wlc_stf_ss_algo_channel_get(struct wlc_info *wlc, u16 *ss_algo_channel, - chanspec_t chanspec) -{ - tx_power_t power; - u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id; - - /* Clear previous settings */ - *ss_algo_channel = 0; - - if (!wlc->pub->up) { - *ss_algo_channel = (u16) -1; - return; - } - - wlc_phy_txpower_get_current(wlc->band->pi, &power, - CHSPEC_CHANNEL(chanspec)); - - siso_mcs_id = (CHSPEC_IS40(chanspec)) ? - WL_TX_POWER_MCS40_SISO_FIRST : WL_TX_POWER_MCS20_SISO_FIRST; - cdd_mcs_id = (CHSPEC_IS40(chanspec)) ? - WL_TX_POWER_MCS40_CDD_FIRST : WL_TX_POWER_MCS20_CDD_FIRST; - stbc_mcs_id = (CHSPEC_IS40(chanspec)) ? - WL_TX_POWER_MCS40_STBC_FIRST : WL_TX_POWER_MCS20_STBC_FIRST; - - /* criteria to choose stf mode */ - - /* the "+3dbm (12 0.25db units)" is to account for the fact that with CDD, tx occurs - * on both chains - */ - if (power.target[siso_mcs_id] > (power.target[cdd_mcs_id] + 12)) - setbit(ss_algo_channel, PHY_TXC1_MODE_SISO); - else - setbit(ss_algo_channel, PHY_TXC1_MODE_CDD); - - /* STBC is ORed into to algo channel as STBC requires per-packet SCB capability check - * so cannot be default mode of operation. One of SISO, CDD have to be set - */ - if (power.target[siso_mcs_id] <= (power.target[stbc_mcs_id] + 12)) - setbit(ss_algo_channel, PHY_TXC1_MODE_STBC); -} - -static s8 wlc_stf_stbc_rx_get(struct wlc_info *wlc) -{ - return (wlc->ht_cap.cap_info & HT_CAP_RX_STBC_MASK) - >> HT_CAP_RX_STBC_SHIFT; -} - -static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val) -{ - if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON)) { - return false; - } - - if ((int_val == ON) && (wlc->stf->txstreams == 1)) - return false; - - if ((int_val == OFF) || (wlc->stf->txstreams == 1) - || !WLC_STBC_CAP_PHY(wlc)) - wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC; - else - wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_TX_STBC; - - wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = (s8) int_val; - wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = (s8) int_val; - - return true; -} - -bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val) -{ - if ((int_val != HT_CAP_RX_STBC_NO) - && (int_val != HT_CAP_RX_STBC_ONE_STREAM)) { - return false; - } - - if (WLC_STF_SS_STBC_RX(wlc)) { - if ((int_val != HT_CAP_RX_STBC_NO) - && (wlc->stf->rxstreams == 1)) - return false; - } - - wlc_stf_stbc_rx_ht_update(wlc, int_val); - return true; -} - -static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 core_mask) -{ - WL_TRACE("wl%d: %s: Nsts %d core_mask %x\n", - wlc->pub->unit, __func__, Nsts, core_mask); - - ASSERT((Nsts > 0) && (Nsts <= MAX_STREAMS_SUPPORTED)); - - if (WLC_BITSCNT(core_mask) > wlc->stf->txstreams) { - core_mask = 0; - } - - if ((WLC_BITSCNT(core_mask) == wlc->stf->txstreams) && - ((core_mask & ~wlc->stf->txchain) - || !(core_mask & wlc->stf->txchain))) { - core_mask = wlc->stf->txchain; - } - - ASSERT(!core_mask || Nsts <= WLC_BITSCNT(core_mask)); - - wlc->stf->txcore[Nsts] = core_mask; - /* Nsts = 1..4, txcore index = 1..4 */ - if (Nsts == 1) { - /* Needs to update beacon and ucode generated response - * frames when 1 stream core map changed - */ - wlc->stf->phytxant = core_mask << PHY_TXC_ANT_SHIFT; - wlc_bmac_txant_set(wlc->hw, wlc->stf->phytxant); - if (wlc->clk) { - wlc_suspend_mac_and_wait(wlc); - wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec); - wlc_enable_mac(wlc); - } - } - - return BCME_OK; -} - -static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val) -{ - int i; - u8 core_mask = 0; - - WL_TRACE("wl%d: %s: val %x\n", wlc->pub->unit, __func__, val); - - wlc->stf->spatial_policy = (s8) val; - for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) { - core_mask = (val == MAX_SPATIAL_EXPANSION) ? - wlc->stf->txchain : txcore_default[i]; - wlc_stf_txcore_set(wlc, (u8) i, core_mask); - } - return BCME_OK; -} - -int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force) -{ - u8 txchain = (u8) int_val; - u8 txstreams; - uint i; - - if (wlc->stf->txchain == txchain) - return BCME_OK; - - if ((txchain & ~wlc->stf->hw_txchain) - || !(txchain & wlc->stf->hw_txchain)) - return BCME_RANGE; - - /* if nrate override is configured to be non-SISO STF mode, reject reducing txchain to 1 */ - txstreams = (u8) WLC_BITSCNT(txchain); - if (txstreams > MAX_STREAMS_SUPPORTED) - return BCME_RANGE; - - if (txstreams == 1) { - for (i = 0; i < NBANDS(wlc); i++) - if ((RSPEC_STF(wlc->bandstate[i]->rspec_override) != - PHY_TXC1_MODE_SISO) - || (RSPEC_STF(wlc->bandstate[i]->mrspec_override) != - PHY_TXC1_MODE_SISO)) { - if (!force) - return BCME_ERROR; - - /* over-write the override rspec */ - if (RSPEC_STF(wlc->bandstate[i]->rspec_override) - != PHY_TXC1_MODE_SISO) { - wlc->bandstate[i]->rspec_override = 0; - WL_ERROR("%s(): temp sense override non-SISO rspec_override\n", - __func__); - } - if (RSPEC_STF - (wlc->bandstate[i]->mrspec_override) != - PHY_TXC1_MODE_SISO) { - wlc->bandstate[i]->mrspec_override = 0; - WL_ERROR("%s(): temp sense override non-SISO mrspec_override\n", - __func__); - } - } - } - - wlc->stf->txchain = txchain; - wlc->stf->txstreams = txstreams; - wlc_stf_stbc_tx_set(wlc, wlc->band->band_stf_stbc_tx); - wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); - wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); - wlc->stf->txant = - (wlc->stf->txstreams == 1) ? ANT_TX_FORCE_0 : ANT_TX_DEF; - _wlc_stf_phy_txant_upd(wlc); - - wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, - wlc->stf->rxchain); - - for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) - wlc_stf_txcore_set(wlc, (u8) i, txcore_default[i]); - - return BCME_OK; -} - -int wlc_stf_rxchain_set(struct wlc_info *wlc, s32 int_val) -{ - u8 rxchain_cnt; - u8 rxchain = (u8) int_val; - u8 mimops_mode; - u8 old_rxchain, old_rxchain_cnt; - - if (wlc->stf->rxchain == rxchain) - return BCME_OK; - - if ((rxchain & ~wlc->stf->hw_rxchain) - || !(rxchain & wlc->stf->hw_rxchain)) - return BCME_RANGE; - - rxchain_cnt = (u8) WLC_BITSCNT(rxchain); - if (WLC_STF_SS_STBC_RX(wlc)) { - if ((rxchain_cnt == 1) - && (wlc_stf_stbc_rx_get(wlc) != HT_CAP_RX_STBC_NO)) - return BCME_RANGE; - } - - if (APSTA_ENAB(wlc->pub) && (wlc->pub->associated)) - return BCME_ASSOCIATED; - - old_rxchain = wlc->stf->rxchain; - old_rxchain_cnt = wlc->stf->rxstreams; - - wlc->stf->rxchain = rxchain; - wlc->stf->rxstreams = rxchain_cnt; - - if (rxchain_cnt != old_rxchain_cnt) { - mimops_mode = - (rxchain_cnt == 1) ? HT_CAP_MIMO_PS_ON : HT_CAP_MIMO_PS_OFF; - wlc->mimops_PM = mimops_mode; - if (AP_ENAB(wlc->pub)) { - wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, - wlc->stf->rxchain); - wlc_ht_mimops_cap_update(wlc, mimops_mode); - if (wlc->pub->associated) - wlc_mimops_action_ht_send(wlc, wlc->cfg, - mimops_mode); - return BCME_OK; - } - if (wlc->pub->associated) { - if (mimops_mode == HT_CAP_MIMO_PS_OFF) { - /* if mimops is off, turn on the Rx chain first */ - wlc_phy_stf_chain_set(wlc->band->pi, - wlc->stf->txchain, - wlc->stf->rxchain); - wlc_ht_mimops_cap_update(wlc, mimops_mode); - } - } else { - wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, - wlc->stf->rxchain); - wlc_ht_mimops_cap_update(wlc, mimops_mode); - } - } else if (old_rxchain != rxchain) - wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, - wlc->stf->rxchain); - - return BCME_OK; -} - -/* update wlc->stf->ss_opmode which represents the operational stf_ss mode we're using */ -int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band) -{ - int ret_code = 0; - u8 prev_stf_ss; - u8 upd_stf_ss; - - prev_stf_ss = wlc->stf->ss_opmode; - - /* NOTE: opmode can only be SISO or CDD as STBC is decided on a per-packet basis */ - if (WLC_STBC_CAP_PHY(wlc) && - wlc->stf->ss_algosel_auto - && (wlc->stf->ss_algo_channel != (u16) -1)) { - ASSERT(isset(&wlc->stf->ss_algo_channel, PHY_TXC1_MODE_CDD) - || isset(&wlc->stf->ss_algo_channel, - PHY_TXC1_MODE_SISO)); - upd_stf_ss = (wlc->stf->no_cddstbc || (wlc->stf->txstreams == 1) - || isset(&wlc->stf->ss_algo_channel, - PHY_TXC1_MODE_SISO)) ? PHY_TXC1_MODE_SISO - : PHY_TXC1_MODE_CDD; - } else { - if (wlc->band != band) - return ret_code; - upd_stf_ss = (wlc->stf->no_cddstbc - || (wlc->stf->txstreams == - 1)) ? PHY_TXC1_MODE_SISO : band-> - band_stf_ss_mode; - } - if (prev_stf_ss != upd_stf_ss) { - wlc->stf->ss_opmode = upd_stf_ss; - wlc_bmac_band_stf_ss_set(wlc->hw, upd_stf_ss); - } - - return ret_code; -} - -int wlc_stf_attach(struct wlc_info *wlc) -{ - wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_SISO; - wlc->bandstate[BAND_5G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_CDD; - - if (WLCISNPHY(wlc->band) && - (wlc_phy_txpower_hw_ctrl_get(wlc->band->pi) != PHY_TPC_HW_ON)) - wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = - PHY_TXC1_MODE_CDD; - wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); - wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); - - wlc_stf_stbc_rx_ht_update(wlc, HT_CAP_RX_STBC_NO); - wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF; - wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF; - - if (WLC_STBC_CAP_PHY(wlc)) { - wlc->stf->ss_algosel_auto = true; - wlc->stf->ss_algo_channel = (u16) -1; /* Init the default value */ - } - return 0; -} - -void wlc_stf_detach(struct wlc_info *wlc) -{ -} - -int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val) -{ - int bcmerror = BCME_OK; - - /* when there is only 1 tx_streams, don't allow to change the txant */ - if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1)) - return ((val == wlc->stf->txant) ? bcmerror : BCME_RANGE); - - switch (val) { - case -1: - val = ANT_TX_DEF; - break; - case 0: - val = ANT_TX_FORCE_0; - break; - case 1: - val = ANT_TX_FORCE_1; - break; - case 3: - val = ANT_TX_LAST_RX; - break; - default: - bcmerror = BCME_RANGE; - break; - } - - if (bcmerror == BCME_OK) - wlc->stf->txant = (s8) val; - - return bcmerror; - -} - -/* - * Centralized txant update function. call it whenever wlc->stf->txant and/or wlc->stf->txchain - * change - * - * Antennas are controlled by ucode indirectly, which drives PHY or GPIO to - * achieve various tx/rx antenna selection schemes - * - * legacy phy, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means auto(last rx) - * for NREV<3, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means last rx and - * do tx-antenna selection for SISO transmissions - * for NREV=3, bit 6 and bit _8_ means antenna 0 and 1 respectively, bit6+bit7 means last rx and - * do tx-antenna selection for SISO transmissions - * for NREV>=7, bit 6 and bit 7 mean antenna 0 and 1 respectively, nit6+bit7 means both cores active -*/ -static void _wlc_stf_phy_txant_upd(struct wlc_info *wlc) -{ - s8 txant; - - txant = (s8) wlc->stf->txant; - ASSERT(txant == ANT_TX_FORCE_0 || txant == ANT_TX_FORCE_1 - || txant == ANT_TX_LAST_RX); - - if (WLC_PHY_11N_CAP(wlc->band)) { - if (txant == ANT_TX_FORCE_0) { - wlc->stf->phytxant = PHY_TXC_ANT_0; - } else if (txant == ANT_TX_FORCE_1) { - wlc->stf->phytxant = PHY_TXC_ANT_1; - - if (WLCISNPHY(wlc->band) && - NREV_GE(wlc->band->phyrev, 3) - && NREV_LT(wlc->band->phyrev, 7)) { - wlc->stf->phytxant = PHY_TXC_ANT_2; - } - } else { - if (WLCISLCNPHY(wlc->band) || WLCISSSLPNPHY(wlc->band)) - wlc->stf->phytxant = PHY_TXC_LCNPHY_ANT_LAST; - else { - /* keep this assert to catch out of sync wlc->stf->txcore */ - ASSERT(wlc->stf->txchain > 0); - wlc->stf->phytxant = - wlc->stf->txchain << PHY_TXC_ANT_SHIFT; - } - } - } else { - if (txant == ANT_TX_FORCE_0) - wlc->stf->phytxant = PHY_TXC_OLD_ANT_0; - else if (txant == ANT_TX_FORCE_1) - wlc->stf->phytxant = PHY_TXC_OLD_ANT_1; - else - wlc->stf->phytxant = PHY_TXC_OLD_ANT_LAST; - } - - wlc_bmac_txant_set(wlc->hw, wlc->stf->phytxant); -} - -void wlc_stf_phy_txant_upd(struct wlc_info *wlc) -{ - _wlc_stf_phy_txant_upd(wlc); -} - -void wlc_stf_phy_chain_calc(struct wlc_info *wlc) -{ - /* get available rx/tx chains */ - wlc->stf->hw_txchain = (u8) getintvar(wlc->pub->vars, "txchain"); - wlc->stf->hw_rxchain = (u8) getintvar(wlc->pub->vars, "rxchain"); - - /* these parameter are intended to be used for all PHY types */ - if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) { - if (WLCISNPHY(wlc->band)) { - wlc->stf->hw_txchain = TXCHAIN_DEF_NPHY; - } else { - wlc->stf->hw_txchain = TXCHAIN_DEF; - } - } - - wlc->stf->txchain = wlc->stf->hw_txchain; - wlc->stf->txstreams = (u8) WLC_BITSCNT(wlc->stf->hw_txchain); - - if (wlc->stf->hw_rxchain == 0 || wlc->stf->hw_rxchain == 0xf) { - if (WLCISNPHY(wlc->band)) { - wlc->stf->hw_rxchain = RXCHAIN_DEF_NPHY; - } else { - wlc->stf->hw_rxchain = RXCHAIN_DEF; - } - } - - wlc->stf->rxchain = wlc->stf->hw_rxchain; - wlc->stf->rxstreams = (u8) WLC_BITSCNT(wlc->stf->hw_rxchain); - - /* initialize the txcore table */ - bcopy(txcore_default, wlc->stf->txcore, sizeof(wlc->stf->txcore)); - - /* default spatial_policy */ - wlc->stf->spatial_policy = MIN_SPATIAL_EXPANSION; - wlc_stf_spatial_policy_set(wlc, MIN_SPATIAL_EXPANSION); -} - -static u16 _wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec) -{ - u16 phytxant = wlc->stf->phytxant; - - if (RSPEC_STF(rspec) != PHY_TXC1_MODE_SISO) { - ASSERT(wlc->stf->txstreams > 1); - phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT; - } else if (wlc->stf->txant == ANT_TX_DEF) - phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT; - phytxant &= PHY_TXC_ANT_MASK; - return phytxant; -} - -u16 wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec) -{ - return _wlc_stf_phytxchain_sel(wlc, rspec); -} - -u16 wlc_stf_d11hdrs_phyctl_txant(struct wlc_info *wlc, ratespec_t rspec) -{ - u16 phytxant = wlc->stf->phytxant; - u16 mask = PHY_TXC_ANT_MASK; - - /* for non-siso rates or default setting, use the available chains */ - if (WLCISNPHY(wlc->band)) { - ASSERT(wlc->stf->txchain != 0); - phytxant = _wlc_stf_phytxchain_sel(wlc, rspec); - mask = PHY_TXC_HTANT_MASK; - } - phytxant |= phytxant & mask; - return phytxant; -} diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.h deleted file mode 100644 index 8de6382e620d..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_stf.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_stf_h_ -#define _wlc_stf_h_ - -#define MIN_SPATIAL_EXPANSION 0 -#define MAX_SPATIAL_EXPANSION 1 - -extern int wlc_stf_attach(struct wlc_info *wlc); -extern void wlc_stf_detach(struct wlc_info *wlc); - -extern void wlc_tempsense_upd(struct wlc_info *wlc); -extern void wlc_stf_ss_algo_channel_get(struct wlc_info *wlc, - u16 *ss_algo_channel, - chanspec_t chanspec); -extern int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band); -extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc); -extern int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force); -extern int wlc_stf_rxchain_set(struct wlc_info *wlc, s32 int_val); -extern bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val); - -extern int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val); -extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc); -extern void wlc_stf_phy_chain_calc(struct wlc_info *wlc); -extern u16 wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec); -extern u16 wlc_stf_d11hdrs_phyctl_txant(struct wlc_info *wlc, ratespec_t rspec); -extern u16 wlc_stf_spatial_expansion_get(struct wlc_info *wlc, - ratespec_t rspec); -#endif /* _wlc_stf_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/sys/wlc_types.h b/drivers/staging/brcm80211/brcmsmac/sys/wlc_types.h deleted file mode 100644 index df6e04c6ac58..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sys/wlc_types.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_types_h_ -#define _wlc_types_h_ - -/* forward declarations */ - -struct wlc_info; -struct wlc_hw_info; -struct wlc_if; -struct wl_if; -struct ampdu_info; -struct antsel_info; -struct bmac_pmq; - -struct d11init; - -#ifndef _hnddma_pub_ -#define _hnddma_pub_ -struct hnddma_pub; -#endif /* _hnddma_pub_ */ - -#endif /* _wlc_types_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wl_dbg.h b/drivers/staging/brcm80211/brcmsmac/wl_dbg.h new file mode 100644 index 000000000000..54af257598c2 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wl_dbg.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wl_dbg_h_ +#define _wl_dbg_h_ + +/* wl_msg_level is a bit vector with defs in wlioctl.h */ +extern u32 wl_msg_level; + +#define WL_NONE(fmt, args...) no_printk(fmt, ##args) + +#define WL_PRINT(level, fmt, args...) \ +do { \ + if (wl_msg_level & level) \ + printk(fmt, ##args); \ +} while (0) + +#ifdef BCMDBG + +#define WL_ERROR(fmt, args...) WL_PRINT(WL_ERROR_VAL, fmt, ##args) +#define WL_TRACE(fmt, args...) WL_PRINT(WL_TRACE_VAL, fmt, ##args) +#define WL_AMPDU(fmt, args...) WL_PRINT(WL_AMPDU_VAL, fmt, ##args) +#define WL_FFPLD(fmt, args...) WL_PRINT(WL_FFPLD_VAL, fmt, ##args) + +#define WL_ERROR_ON() (wl_msg_level & WL_ERROR_VAL) + +/* Extra message control for AMPDU debugging */ +#define WL_AMPDU_UPDN_VAL 0x00000001 /* Config up/down related */ +#define WL_AMPDU_ERR_VAL 0x00000002 /* Calls to beaocn update */ +#define WL_AMPDU_TX_VAL 0x00000004 /* Transmit data path */ +#define WL_AMPDU_RX_VAL 0x00000008 /* Receive data path */ +#define WL_AMPDU_CTL_VAL 0x00000010 /* TSF-related items */ +#define WL_AMPDU_HW_VAL 0x00000020 /* AMPDU_HW */ +#define WL_AMPDU_HWTXS_VAL 0x00000040 /* AMPDU_HWTXS */ +#define WL_AMPDU_HWDBG_VAL 0x00000080 /* AMPDU_DBG */ + +extern u32 wl_ampdu_dbg; + +#define WL_AMPDU_PRINT(level, fmt, args...) \ +do { \ + if (wl_ampdu_dbg & level) { \ + WL_AMPDU(fmt, ##args); \ + } \ +} while (0) + +#define WL_AMPDU_UPDN(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_UPDN_VAL, fmt, ##args) +#define WL_AMPDU_RX(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_RX_VAL, fmt, ##args) +#define WL_AMPDU_ERR(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_ERR_VAL, fmt, ##args) +#define WL_AMPDU_TX(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_TX_VAL, fmt, ##args) +#define WL_AMPDU_CTL(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_CTL_VAL, fmt, ##args) +#define WL_AMPDU_HW(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_HW_VAL, fmt, ##args) +#define WL_AMPDU_HWTXS(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_HWTXS_VAL, fmt, ##args) +#define WL_AMPDU_HWDBG(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_HWDBG_VAL, fmt, ##args) +#define WL_AMPDU_ERR_ON() (wl_ampdu_dbg & WL_AMPDU_ERR_VAL) +#define WL_AMPDU_HW_ON() (wl_ampdu_dbg & WL_AMPDU_HW_VAL) +#define WL_AMPDU_HWTXS_ON() (wl_ampdu_dbg & WL_AMPDU_HWTXS_VAL) + +#else /* BCMDBG */ + +#define WL_ERROR(fmt, args...) no_printk(fmt, ##args) +#define WL_TRACE(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU(fmt, args...) no_printk(fmt, ##args) +#define WL_FFPLD(fmt, args...) no_printk(fmt, ##args) + +#define WL_ERROR_ON() 0 + +#define WL_AMPDU_UPDN(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_RX(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_ERR(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_TX(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_CTL(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_HW(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_HWTXS(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_HWDBG(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_ERR_ON() 0 +#define WL_AMPDU_HW_ON() 0 +#define WL_AMPDU_HWTXS_ON() 0 + +#endif /* BCMDBG */ + +#endif /* _wl_dbg_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wl_export.h b/drivers/staging/brcm80211/brcmsmac/wl_export.h new file mode 100644 index 000000000000..aa8b5a3ed633 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wl_export.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wl_export_h_ +#define _wl_export_h_ + +/* misc callbacks */ +struct wl_info; +struct wl_if; +struct wlc_if; +extern void wl_init(struct wl_info *wl); +extern uint wl_reset(struct wl_info *wl); +extern void wl_intrson(struct wl_info *wl); +extern u32 wl_intrsoff(struct wl_info *wl); +extern void wl_intrsrestore(struct wl_info *wl, u32 macintmask); +extern void wl_event(struct wl_info *wl, char *ifname, wlc_event_t *e); +extern void wl_event_sendup(struct wl_info *wl, const wlc_event_t *e, + u8 *data, u32 len); +extern int wl_up(struct wl_info *wl); +extern void wl_down(struct wl_info *wl); +extern void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, + int prio); +extern bool wl_alloc_dma_resources(struct wl_info *wl, uint dmaddrwidth); + +/* timer functions */ +struct wl_timer; +extern struct wl_timer *wl_init_timer(struct wl_info *wl, + void (*fn) (void *arg), void *arg, + const char *name); +extern void wl_free_timer(struct wl_info *wl, struct wl_timer *timer); +extern void wl_add_timer(struct wl_info *wl, struct wl_timer *timer, uint ms, + int periodic); +extern bool wl_del_timer(struct wl_info *wl, struct wl_timer *timer); + +extern uint wl_buf_to_pktcopy(struct osl_info *osh, void *p, unsigned char *buf, + int len, uint offset); +extern void *wl_get_pktbuffer(struct osl_info *osh, int len); +extern int wl_set_pktlen(struct osl_info *osh, void *p, int len); + +#define wl_sort_bsslist(a, b) false + +extern int wl_tkip_miccheck(struct wl_info *wl, void *p, int hdr_len, + bool group_key, int id); +extern int wl_tkip_micadd(struct wl_info *wl, void *p, int hdr_len); +extern int wl_tkip_encrypt(struct wl_info *wl, void *p, int hdr_len); +extern int wl_tkip_decrypt(struct wl_info *wl, void *p, int hdr_len, + bool group_key); +extern void wl_tkip_printstats(struct wl_info *wl, bool group_key); +extern int wl_tkip_keyset(struct wl_info *wl, wsec_key_t *key); +#endif /* _wl_export_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c new file mode 100644 index 000000000000..6bc6207bab3e --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -0,0 +1,1846 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define __UNDEF_NO_VERSION__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define WLC_MAXBSSCFG 1 /* single BSS configs */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +static void wl_timer(unsigned long data); +static void _wl_timer(wl_timer_t *t); + + +static int ieee_hw_init(struct ieee80211_hw *hw); +static int ieee_hw_rate_init(struct ieee80211_hw *hw); + +static int wl_linux_watchdog(void *ctx); + +/* Flags we support */ +#define MAC_FILTERS (FIF_PROMISC_IN_BSS | \ + FIF_ALLMULTI | \ + FIF_FCSFAIL | \ + FIF_PLCPFAIL | \ + FIF_CONTROL | \ + FIF_OTHER_BSS | \ + FIF_BCN_PRBRESP_PROMISC) + +static int wl_found; + +struct ieee80211_tkip_data { +#define TKIP_KEY_LEN 32 + u8 key[TKIP_KEY_LEN]; + int key_set; + + u32 tx_iv32; + u16 tx_iv16; + u16 tx_ttak[5]; + int tx_phase1_done; + + u32 rx_iv32; + u16 rx_iv16; + u16 rx_ttak[5]; + int rx_phase1_done; + u32 rx_iv32_new; + u16 rx_iv16_new; + + u32 dot11RSNAStatsTKIPReplays; + u32 dot11RSNAStatsTKIPICVErrors; + u32 dot11RSNAStatsTKIPLocalMICFailures; + + int key_idx; + + struct crypto_tfm *tfm_arc4; + struct crypto_tfm *tfm_michael; + + /* scratch buffers for virt_to_page() (crypto API) */ + u8 rx_hdr[16], tx_hdr[16]; +}; + +#define WL_DEV_IF(dev) ((struct wl_if *)netdev_priv(dev)) +#define WL_INFO(dev) ((struct wl_info *)(WL_DEV_IF(dev)->wl)) +static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev); +static void wl_release_fw(struct wl_info *wl); + +/* local prototypes */ +static int wl_start(struct sk_buff *skb, struct wl_info *wl); +static int wl_start_int(struct wl_info *wl, struct ieee80211_hw *hw, + struct sk_buff *skb); +static void wl_dpc(unsigned long data); + +MODULE_AUTHOR("Broadcom Corporation"); +MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver."); +MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards"); +MODULE_LICENSE("Dual BSD/GPL"); + +/* recognized PCI IDs */ +static struct pci_device_id wl_id_table[] = { + {PCI_VENDOR_ID_BROADCOM, 0x4357, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43225 2G */ + {PCI_VENDOR_ID_BROADCOM, 0x4353, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43224 DUAL */ + {PCI_VENDOR_ID_BROADCOM, 0x4727, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 4313 DUAL */ + {0} +}; + +MODULE_DEVICE_TABLE(pci, wl_id_table); +static void wl_remove(struct pci_dev *pdev); + + +#ifdef BCMDBG +static int msglevel = 0xdeadbeef; +module_param(msglevel, int, 0); +static int phymsglevel = 0xdeadbeef; +module_param(phymsglevel, int, 0); +#endif /* BCMDBG */ + +#define HW_TO_WL(hw) (hw->priv) +#define WL_TO_HW(wl) (wl->pub->ieee_hw) +static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb); +static int wl_ops_start(struct ieee80211_hw *hw); +static void wl_ops_stop(struct ieee80211_hw *hw); +static int wl_ops_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +static void wl_ops_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +static int wl_ops_config(struct ieee80211_hw *hw, u32 changed); +static void wl_ops_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, + u32 changed); +static void wl_ops_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, u64 multicast); +static int wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, + bool set); +static void wl_ops_sw_scan_start(struct ieee80211_hw *hw); +static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw); +static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf); +static int wl_ops_get_stats(struct ieee80211_hw *hw, + struct ieee80211_low_level_stats *stats); +static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value); +static void wl_ops_sta_notify(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum sta_notify_cmd cmd, + struct ieee80211_sta *sta); +static int wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, + const struct ieee80211_tx_queue_params *params); +static u64 wl_ops_get_tsf(struct ieee80211_hw *hw); +static int wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +static int wl_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +static int wl_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + enum ieee80211_ampdu_mlme_action action, + struct ieee80211_sta *sta, u16 tid, u16 *ssn); + +static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + int status; + struct wl_info *wl = hw->priv; + WL_LOCK(wl); + if (!wl->pub->up) { + WL_ERROR("ops->tx called while down\n"); + status = -ENETDOWN; + goto done; + } + status = wl_start(skb, wl); + done: + WL_UNLOCK(wl); + return status; +} + +static int wl_ops_start(struct ieee80211_hw *hw) +{ + struct wl_info *wl = hw->priv; + /* + struct ieee80211_channel *curchan = hw->conf.channel; + WL_NONE("%s : Initial channel: %d\n", __func__, curchan->hw_value); + */ + + WL_LOCK(wl); + ieee80211_wake_queues(hw); + WL_UNLOCK(wl); + + return 0; +} + +static void wl_ops_stop(struct ieee80211_hw *hw) +{ + struct wl_info *wl = hw->priv; + ASSERT(wl); + WL_LOCK(wl); + wl_down(wl); + ieee80211_stop_queues(hw); + WL_UNLOCK(wl); + + return; +} + +static int +wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct wl_info *wl; + int err; + + /* Just STA for now */ + if (vif->type != NL80211_IFTYPE_AP && + vif->type != NL80211_IFTYPE_MESH_POINT && + vif->type != NL80211_IFTYPE_STATION && + vif->type != NL80211_IFTYPE_WDS && + vif->type != NL80211_IFTYPE_ADHOC) { + WL_ERROR("%s: Attempt to add type %d, only STA for now\n", + __func__, vif->type); + return -EOPNOTSUPP; + } + + wl = HW_TO_WL(hw); + WL_LOCK(wl); + err = wl_up(wl); + WL_UNLOCK(wl); + + if (err != 0) + WL_ERROR("%s: wl_up() returned %d\n", __func__, err); + return err; +} + +static void +wl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + return; +} + +static int +ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan, + enum nl80211_channel_type type) +{ + struct wl_info *wl = HW_TO_WL(hw); + int err = 0; + + switch (type) { + case NL80211_CHAN_HT20: + case NL80211_CHAN_NO_HT: + WL_LOCK(wl); + err = wlc_set(wl->wlc, WLC_SET_CHANNEL, chan->hw_value); + WL_UNLOCK(wl); + break; + case NL80211_CHAN_HT40MINUS: + case NL80211_CHAN_HT40PLUS: + WL_ERROR("%s: Need to implement 40 Mhz Channels!\n", __func__); + break; + } + + if (err) + return -EIO; + return err; +} + +static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) +{ + struct ieee80211_conf *conf = &hw->conf; + struct wl_info *wl = HW_TO_WL(hw); + int err = 0; + int new_int; + + if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { + WL_NONE("%s: Setting listen interval to %d\n", + __func__, conf->listen_interval); + if (wlc_iovar_setint + (wl->wlc, "bcn_li_bcn", conf->listen_interval)) { + WL_ERROR("%s: Error setting listen_interval\n", + __func__); + err = -EIO; + goto config_out; + } + wlc_iovar_getint(wl->wlc, "bcn_li_bcn", &new_int); + ASSERT(new_int == conf->listen_interval); + } + if (changed & IEEE80211_CONF_CHANGE_MONITOR) + WL_NONE("Need to set monitor mode\n"); + if (changed & IEEE80211_CONF_CHANGE_PS) + WL_NONE("Need to set Power-save mode\n"); + + if (changed & IEEE80211_CONF_CHANGE_POWER) { + WL_NONE("%s: Setting tx power to %d dbm\n", + __func__, conf->power_level); + if (wlc_iovar_setint + (wl->wlc, "qtxpower", conf->power_level * 4)) { + WL_ERROR("%s: Error setting power_level\n", __func__); + err = -EIO; + goto config_out; + } + wlc_iovar_getint(wl->wlc, "qtxpower", &new_int); + if (new_int != (conf->power_level * 4)) + WL_ERROR("%s: Power level req != actual, %d %d\n", + __func__, conf->power_level * 4, new_int); + } + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + err = ieee_set_channel(hw, conf->channel, conf->channel_type); + } + if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { + WL_NONE("%s: srl %d, lrl %d\n", + __func__, + conf->short_frame_max_tx_count, + conf->long_frame_max_tx_count); + if (wlc_set + (wl->wlc, WLC_SET_SRL, + conf->short_frame_max_tx_count) < 0) { + WL_ERROR("%s: Error setting srl\n", __func__); + err = -EIO; + goto config_out; + } + if (wlc_set(wl->wlc, WLC_SET_LRL, conf->long_frame_max_tx_count) + < 0) { + WL_ERROR("%s: Error setting lrl\n", __func__); + err = -EIO; + goto config_out; + } + } + + config_out: + return err; +} + +static void +wl_ops_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, u32 changed) +{ + struct wl_info *wl = HW_TO_WL(hw); + int val; + + + if (changed & BSS_CHANGED_ASSOC) { + WL_ERROR("Associated:\t%s\n", info->assoc ? "True" : "False"); + /* association status changed (associated/disassociated) + * also implies a change in the AID. + */ + } + if (changed & BSS_CHANGED_ERP_CTS_PROT) { + WL_NONE("Use_cts_prot:\t%s Implement me\n", + info->use_cts_prot ? "True" : "False"); + /* CTS protection changed */ + } + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + WL_NONE("Short preamble:\t%s Implement me\n", + info->use_short_preamble ? "True" : "False"); + /* preamble changed */ + } + if (changed & BSS_CHANGED_ERP_SLOT) { + WL_NONE("Changing short slot:\t%s\n", + info->use_short_slot ? "True" : "False"); + if (info->use_short_slot) + val = 1; + else + val = 0; + wlc_set(wl->wlc, WLC_SET_SHORTSLOT_OVERRIDE, val); + /* slot timing changed */ + } + + if (changed & BSS_CHANGED_HT) { + WL_NONE("%s: HT mode - Implement me\n", __func__); + /* 802.11n parameters changed */ + } + if (changed & BSS_CHANGED_BASIC_RATES) { + WL_NONE("Need to change Basic Rates:\t0x%x! Implement me\n", + (u32) info->basic_rates); + /* Basic rateset changed */ + } + if (changed & BSS_CHANGED_BEACON_INT) { + WL_NONE("Beacon Interval:\t%d Implement me\n", + info->beacon_int); + /* Beacon interval changed */ + } + if (changed & BSS_CHANGED_BSSID) { + WL_NONE("new BSSID:\taid %d bss:%pM\n", + info->aid, info->bssid); + /* BSSID changed, for whatever reason (IBSS and managed mode) */ + /* FIXME: need to store bssid in bsscfg */ + wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, + info->bssid); + } + if (changed & BSS_CHANGED_BEACON) { + WL_ERROR("BSS_CHANGED_BEACON\n"); + /* Beacon data changed, retrieve new beacon (beaconing modes) */ + } + if (changed & BSS_CHANGED_BEACON_ENABLED) { + WL_ERROR("Beacon enabled:\t%s\n", + info->enable_beacon ? "True" : "False"); + /* Beaconing should be enabled/disabled (beaconing modes) */ + } + return; +} + +static void +wl_ops_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, u64 multicast) +{ + struct wl_info *wl = hw->priv; + + changed_flags &= MAC_FILTERS; + *total_flags &= MAC_FILTERS; + if (changed_flags & FIF_PROMISC_IN_BSS) + WL_ERROR("FIF_PROMISC_IN_BSS\n"); + if (changed_flags & FIF_ALLMULTI) + WL_ERROR("FIF_ALLMULTI\n"); + if (changed_flags & FIF_FCSFAIL) + WL_ERROR("FIF_FCSFAIL\n"); + if (changed_flags & FIF_PLCPFAIL) + WL_ERROR("FIF_PLCPFAIL\n"); + if (changed_flags & FIF_CONTROL) + WL_ERROR("FIF_CONTROL\n"); + if (changed_flags & FIF_OTHER_BSS) + WL_ERROR("FIF_OTHER_BSS\n"); + if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { + WL_NONE("FIF_BCN_PRBRESP_PROMISC\n"); + WL_LOCK(wl); + if (*total_flags & FIF_BCN_PRBRESP_PROMISC) { + wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS; + wlc_mac_bcn_promisc_change(wl->wlc, 1); + } else { + wlc_mac_bcn_promisc_change(wl->wlc, 0); + wl->pub->mac80211_state &= ~MAC80211_PROMISC_BCNS; + } + WL_UNLOCK(wl); + } + return; +} + +static int +wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) +{ + WL_ERROR("%s: Enter\n", __func__); + return 0; +} + +static void wl_ops_sw_scan_start(struct ieee80211_hw *hw) +{ + WL_NONE("Scan Start\n"); + return; +} + +static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw) +{ + WL_NONE("Scan Complete\n"); + return; +} + +static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf) +{ + WL_ERROR("%s: Enter\n", __func__); + return; +} + +static int +wl_ops_get_stats(struct ieee80211_hw *hw, + struct ieee80211_low_level_stats *stats) +{ + WL_ERROR("%s: Enter\n", __func__); + return 0; +} + +static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value) +{ + WL_ERROR("%s: Enter\n", __func__); + return 0; +} + +static void +wl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + enum sta_notify_cmd cmd, struct ieee80211_sta *sta) +{ + WL_NONE("%s: Enter\n", __func__); + switch (cmd) { + default: + WL_ERROR("%s: Unknown cmd = %d\n", __func__, cmd); + break; + } + return; +} + +static int +wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, + const struct ieee80211_tx_queue_params *params) +{ + struct wl_info *wl = hw->priv; + + WL_NONE("%s: Enter (WME config)\n", __func__); + WL_NONE("queue %d, txop %d, cwmin %d, cwmax %d, aifs %d\n", queue, + params->txop, params->cw_min, params->cw_max, params->aifs); + + WL_LOCK(wl); + wlc_wme_setparams(wl->wlc, queue, (void *)params, true); + WL_UNLOCK(wl); + + return 0; +} + +static u64 wl_ops_get_tsf(struct ieee80211_hw *hw) +{ + WL_ERROR("%s: Enter\n", __func__); + return 0; +} + +static int +wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct scb *scb; + + int i; + struct wl_info *wl = hw->priv; + + /* Init the scb */ + scb = (struct scb *)sta->drv_priv; + memset(scb, 0, sizeof(struct scb)); + for (i = 0; i < NUMPRIO; i++) + scb->seqctl[i] = 0xFFFF; + scb->seqctl_nonqos = 0xFFFF; + scb->magic = SCB_MAGIC; + + wl->pub->global_scb = scb; + wl->pub->global_ampdu = &(scb->scb_ampdu); + wl->pub->global_ampdu->scb = scb; + wl->pub->global_ampdu->max_pdu = 16; + pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID, + AMPDU_MAX_SCB_TID * PKTQ_LEN_DEFAULT); + + sta->ht_cap.ht_supported = true; + sta->ht_cap.ampdu_factor = AMPDU_RX_FACTOR_64K; + sta->ht_cap.ampdu_density = AMPDU_DEF_MPDU_DENSITY; + sta->ht_cap.cap = IEEE80211_HT_CAP_GRN_FLD | + IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT; + + /* minstrel_ht initiates addBA on our behalf by calling ieee80211_start_tx_ba_session() */ + return 0; +} + +static int +wl_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + WL_NONE("%s: Enter\n", __func__); + return 0; +} + +static int +wl_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum ieee80211_ampdu_mlme_action action, + struct ieee80211_sta *sta, u16 tid, u16 *ssn) +{ +#if defined(BCMDBG) + struct scb *scb = (struct scb *)sta->drv_priv; +#endif + struct wl_info *wl = hw->priv; + + ASSERT(scb->magic == SCB_MAGIC); + switch (action) { + case IEEE80211_AMPDU_RX_START: + WL_NONE("%s: action = IEEE80211_AMPDU_RX_START\n", __func__); + break; + case IEEE80211_AMPDU_RX_STOP: + WL_NONE("%s: action = IEEE80211_AMPDU_RX_STOP\n", __func__); + break; + case IEEE80211_AMPDU_TX_START: + if (!wlc_aggregatable(wl->wlc, tid)) { + /* WL_ERROR("START: tid %d is not agg' able, return FAILURE to stack\n", tid); */ + return -1; + } + /* XXX: Use the starting sequence number provided ... */ + *ssn = 0; + ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + break; + + case IEEE80211_AMPDU_TX_STOP: + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + break; + case IEEE80211_AMPDU_TX_OPERATIONAL: + /* Not sure what to do here */ + /* Power save wakeup */ + WL_NONE("%s: action = IEEE80211_AMPDU_TX_OPERATIONAL\n", + __func__); + break; + default: + WL_ERROR("%s: Invalid command, ignoring\n", __func__); + } + + return 0; +} + +static const struct ieee80211_ops wl_ops = { + .tx = wl_ops_tx, + .start = wl_ops_start, + .stop = wl_ops_stop, + .add_interface = wl_ops_add_interface, + .remove_interface = wl_ops_remove_interface, + .config = wl_ops_config, + .bss_info_changed = wl_ops_bss_info_changed, + .configure_filter = wl_ops_configure_filter, + .set_tim = wl_ops_set_tim, + .sw_scan_start = wl_ops_sw_scan_start, + .sw_scan_complete = wl_ops_sw_scan_complete, + .set_tsf = wl_ops_set_tsf, + .get_stats = wl_ops_get_stats, + .set_rts_threshold = wl_ops_set_rts_threshold, + .sta_notify = wl_ops_sta_notify, + .conf_tx = wl_ops_conf_tx, + .get_tsf = wl_ops_get_tsf, + .sta_add = wl_sta_add, + .sta_remove = wl_sta_remove, + .ampdu_action = wl_ampdu_action, +}; + +static int wl_set_hint(struct wl_info *wl, char *abbrev) +{ + WL_ERROR("%s: Sending country code %c%c to MAC80211\n", + __func__, abbrev[0], abbrev[1]); + return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev); +} + +/** + * attach to the WL device. + * + * Attach to the WL device identified by vendor and device parameters. + * regs is a host accessible memory address pointing to WL device registers. + * + * wl_attach is not defined as static because in the case where no bus + * is defined, wl_attach will never be called, and thus, gcc will issue + * a warning that this function is defined but not used if we declare + * it as static. + */ +static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, + uint bustype, void *btparam, uint irq) +{ + struct wl_info *wl; + struct osl_info *osh; + int unit, err; + + unsigned long base_addr; + struct ieee80211_hw *hw; + u8 perm[ETH_ALEN]; + + unit = wl_found; + err = 0; + + if (unit < 0) { + WL_ERROR("wl%d: unit number overflow, exiting\n", unit); + return NULL; + } + + osh = osl_attach(btparam, bustype); + ASSERT(osh); + + /* allocate private info */ + hw = pci_get_drvdata(btparam); /* btparam == pdev */ + wl = hw->priv; + ASSERT(wl); + + wl->osh = osh; + atomic_set(&wl->callbacks, 0); + + /* setup the bottom half handler */ + tasklet_init(&wl->tasklet, wl_dpc, (unsigned long) wl); + + + + base_addr = regs; + + if (bustype == PCI_BUS) { + wl->piomode = false; + } else if (bustype == RPC_BUS) { + /* Do nothing */ + } else { + bustype = PCI_BUS; + WL_TRACE("force to PCI\n"); + } + wl->bcm_bustype = bustype; + + wl->regsva = ioremap_nocache(base_addr, PCI_BAR0_WINSZ); + if (wl->regsva == NULL) { + WL_ERROR("wl%d: ioremap() failed\n", unit); + goto fail; + } + spin_lock_init(&wl->lock); + spin_lock_init(&wl->isr_lock); + + /* prepare ucode */ + if (wl_request_fw(wl, (struct pci_dev *)btparam)) { + printf("%s: Failed to find firmware usually in %s\n", + KBUILD_MODNAME, "/lib/firmware/brcm"); + wl_release_fw(wl); + wl_remove((struct pci_dev *)btparam); + goto fail1; + } + + /* common load-time initialization */ + wl->wlc = wlc_attach((void *)wl, vendor, device, unit, wl->piomode, osh, + wl->regsva, wl->bcm_bustype, btparam, &err); + wl_release_fw(wl); + if (!wl->wlc) { + printf("%s: wlc_attach() failed with code %d\n", + KBUILD_MODNAME, err); + goto fail; + } + wl->pub = wlc_pub(wl->wlc); + + wl->pub->ieee_hw = hw; + ASSERT(wl->pub->ieee_hw); + ASSERT(wl->pub->ieee_hw->priv == wl); + + + if (wlc_iovar_setint(wl->wlc, "mpc", 0)) { + WL_ERROR("wl%d: Error setting MPC variable to 0\n", unit); + } + + /* register our interrupt handler */ + if (request_irq(irq, wl_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { + WL_ERROR("wl%d: request_irq() failed\n", unit); + goto fail; + } + wl->irq = irq; + + /* register module */ + wlc_module_register(wl->pub, NULL, "linux", wl, NULL, wl_linux_watchdog, + NULL); + + if (ieee_hw_init(hw)) { + WL_ERROR("wl%d: %s: ieee_hw_init failed!\n", unit, __func__); + goto fail; + } + + bcopy(&wl->pub->cur_etheraddr, perm, ETH_ALEN); + ASSERT(is_valid_ether_addr(perm)); + SET_IEEE80211_PERM_ADDR(hw, perm); + + err = ieee80211_register_hw(hw); + if (err) { + WL_ERROR("%s: ieee80211_register_hw failed, status %d\n", + __func__, err); + } + + if (wl->pub->srom_ccode[0]) + err = wl_set_hint(wl, wl->pub->srom_ccode); + else + err = wl_set_hint(wl, "US"); + if (err) { + WL_ERROR("%s: regulatory_hint failed, status %d\n", + __func__, err); + } + WL_ERROR("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver (" PHY_VERSION_STR ")", + unit); + +#ifdef BCMDBG + printf(" (Compiled at " __TIME__ " on " __DATE__ ")"); +#endif /* BCMDBG */ + printf("\n"); + + wl_found++; + return wl; + + fail: + wl_free(wl); +fail1: + return NULL; +} + + + +#define CHAN2GHZ(channel, freqency, chflags) { \ + .band = IEEE80211_BAND_2GHZ, \ + .center_freq = (freqency), \ + .hw_value = (channel), \ + .flags = chflags, \ + .max_antenna_gain = 0, \ + .max_power = 19, \ +} + +static struct ieee80211_channel wl_2ghz_chantable[] = { + CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS), + CHAN2GHZ(2, 2417, IEEE80211_CHAN_NO_HT40MINUS), + CHAN2GHZ(3, 2422, IEEE80211_CHAN_NO_HT40MINUS), + CHAN2GHZ(4, 2427, IEEE80211_CHAN_NO_HT40MINUS), + CHAN2GHZ(5, 2432, 0), + CHAN2GHZ(6, 2437, 0), + CHAN2GHZ(7, 2442, 0), + CHAN2GHZ(8, 2447, IEEE80211_CHAN_NO_HT40PLUS), + CHAN2GHZ(9, 2452, IEEE80211_CHAN_NO_HT40PLUS), + CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS), + CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS), + CHAN2GHZ(12, 2467, + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_NO_HT40PLUS), + CHAN2GHZ(13, 2472, + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_NO_HT40PLUS), + CHAN2GHZ(14, 2484, + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS) +}; + +#define CHAN5GHZ(channel, chflags) { \ + .band = IEEE80211_BAND_5GHZ, \ + .center_freq = 5000 + 5*(channel), \ + .hw_value = (channel), \ + .flags = chflags, \ + .max_antenna_gain = 0, \ + .max_power = 21, \ +} + +static struct ieee80211_channel wl_5ghz_nphy_chantable[] = { + /* UNII-1 */ + CHAN5GHZ(36, IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(40, IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(44, IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS), + /* UNII-2 */ + CHAN5GHZ(52, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(56, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(60, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(64, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), + /* MID */ + CHAN5GHZ(100, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(104, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(108, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(112, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(116, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(120, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(124, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(128, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(132, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(136, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(140, + IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS | + IEEE80211_CHAN_NO_HT40MINUS), + /* UNII-3 */ + CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(153, IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(157, IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(161, IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(165, IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS) +}; + +#define RATE(rate100m, _flags) { \ + .bitrate = (rate100m), \ + .flags = (_flags), \ + .hw_value = (rate100m / 5), \ +} + +static struct ieee80211_rate wl_legacy_ratetable[] = { + RATE(10, 0), + RATE(20, IEEE80211_RATE_SHORT_PREAMBLE), + RATE(55, IEEE80211_RATE_SHORT_PREAMBLE), + RATE(110, IEEE80211_RATE_SHORT_PREAMBLE), + RATE(60, 0), + RATE(90, 0), + RATE(120, 0), + RATE(180, 0), + RATE(240, 0), + RATE(360, 0), + RATE(480, 0), + RATE(540, 0), +}; + +static struct ieee80211_supported_band wl_band_2GHz_nphy = { + .band = IEEE80211_BAND_2GHZ, + .channels = wl_2ghz_chantable, + .n_channels = ARRAY_SIZE(wl_2ghz_chantable), + .bitrates = wl_legacy_ratetable, + .n_bitrates = ARRAY_SIZE(wl_legacy_ratetable), + .ht_cap = { + /* from include/linux/ieee80211.h */ + .cap = IEEE80211_HT_CAP_GRN_FLD | + IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, + .ht_supported = true, + .ampdu_factor = AMPDU_RX_FACTOR_64K, + .ampdu_density = AMPDU_DEF_MPDU_DENSITY, + .mcs = { + /* placeholders for now */ + .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0}, + .rx_highest = 500, + .tx_params = IEEE80211_HT_MCS_TX_DEFINED} + } +}; + +static struct ieee80211_supported_band wl_band_5GHz_nphy = { + .band = IEEE80211_BAND_5GHZ, + .channels = wl_5ghz_nphy_chantable, + .n_channels = ARRAY_SIZE(wl_5ghz_nphy_chantable), + .bitrates = wl_legacy_ratetable + 4, + .n_bitrates = ARRAY_SIZE(wl_legacy_ratetable) - 4, + .ht_cap = { + /* use IEEE80211_HT_CAP_* from include/linux/ieee80211.h */ + .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, /* No 40 mhz yet */ + .ht_supported = true, + .ampdu_factor = AMPDU_RX_FACTOR_64K, + .ampdu_density = AMPDU_DEF_MPDU_DENSITY, + .mcs = { + /* placeholders for now */ + .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0}, + .rx_highest = 500, + .tx_params = IEEE80211_HT_MCS_TX_DEFINED} + } +}; + +static int ieee_hw_rate_init(struct ieee80211_hw *hw) +{ + struct wl_info *wl = HW_TO_WL(hw); + int has_5g; + char phy_list[4]; + + has_5g = 0; + + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL; + hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; + + if (wlc_get(wl->wlc, WLC_GET_PHYLIST, (int *)&phy_list) < 0) { + WL_ERROR("Phy list failed\n"); + } + WL_NONE("%s: phylist = %c\n", __func__, phy_list[0]); + + if (phy_list[0] == 'n' || phy_list[0] == 'c') { + if (phy_list[0] == 'c') { + /* Single stream */ + wl_band_2GHz_nphy.ht_cap.mcs.rx_mask[1] = 0; + wl_band_2GHz_nphy.ht_cap.mcs.rx_highest = 72; + } + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl_band_2GHz_nphy; + } else { + BUG(); + return -1; + } + + /* Assume all bands use the same phy. True for 11n devices. */ + if (NBANDS_PUB(wl->pub) > 1) { + has_5g++; + if (phy_list[0] == 'n' || phy_list[0] == 'c') { + hw->wiphy->bands[IEEE80211_BAND_5GHZ] = + &wl_band_5GHz_nphy; + } else { + return -1; + } + } + + WL_NONE("%s: 2ghz = %d, 5ghz = %d\n", __func__, 1, has_5g); + + return 0; +} + +static int ieee_hw_init(struct ieee80211_hw *hw) +{ + hw->flags = IEEE80211_HW_SIGNAL_DBM + /* | IEEE80211_HW_CONNECTION_MONITOR What is this? */ + | IEEE80211_HW_REPORTS_TX_ACK_STATUS + | IEEE80211_HW_AMPDU_AGGREGATION; + + hw->extra_tx_headroom = wlc_get_header_len(); + /* FIXME: should get this from wlc->machwcap */ + hw->queues = 4; + /* FIXME: this doesn't seem to be used properly in minstrel_ht. + * mac80211/status.c:ieee80211_tx_status() checks this value, + * but mac80211/rc80211_minstrel_ht.c:minstrel_ht_get_rate() + * appears to always set 3 rates + */ + hw->max_rates = 2; /* Primary rate and 1 fallback rate */ + + hw->channel_change_time = 7 * 1000; /* channel change time is dependant on chip and band */ + hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + + hw->rate_control_algorithm = "minstrel_ht"; + + hw->sta_data_size = sizeof(struct scb); + return ieee_hw_rate_init(hw); +} + +/** + * determines if a device is a WL device, and if so, attaches it. + * + * This function determines if a device pointed to by pdev is a WL device, + * and if so, performs a wl_attach() on it. + * + */ +int __devinit +wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int rc; + struct wl_info *wl; + struct ieee80211_hw *hw; + u32 val; + + ASSERT(pdev); + + WL_TRACE("%s: bus %d slot %d func %d irq %d\n", + __func__, pdev->bus->number, PCI_SLOT(pdev->devfn), + PCI_FUNC(pdev->devfn), pdev->irq); + + if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) || + (((pdev->device & 0xff00) != 0x4300) && + ((pdev->device & 0xff00) != 0x4700) && + ((pdev->device < 43000) || (pdev->device > 43999)))) + return -ENODEV; + + rc = pci_enable_device(pdev); + if (rc) { + WL_ERROR("%s: Cannot enable device %d-%d_%d\n", + __func__, pdev->bus->number, PCI_SLOT(pdev->devfn), + PCI_FUNC(pdev->devfn)); + return -ENODEV; + } + pci_set_master(pdev); + + pci_read_config_dword(pdev, 0x40, &val); + if ((val & 0x0000ff00) != 0) + pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); + + hw = ieee80211_alloc_hw(sizeof(struct wl_info), &wl_ops); + if (!hw) { + WL_ERROR("%s: ieee80211_alloc_hw failed\n", __func__); + rc = -ENOMEM; + goto err_1; + } + + SET_IEEE80211_DEV(hw, &pdev->dev); + + pci_set_drvdata(pdev, hw); + + memset(hw->priv, 0, sizeof(*wl)); + + wl = wl_attach(pdev->vendor, pdev->device, pci_resource_start(pdev, 0), + PCI_BUS, pdev, pdev->irq); + + if (!wl) { + WL_ERROR("%s: %s: wl_attach failed!\n", + KBUILD_MODNAME, __func__); + return -ENODEV; + } + return 0; + err_1: + WL_ERROR("%s: err_1: Major hoarkage\n", __func__); + return 0; +} + +#ifdef LINUXSTA_PS +static int wl_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct wl_info *wl; + struct ieee80211_hw *hw; + + WL_TRACE("wl: wl_suspend\n"); + + hw = pci_get_drvdata(pdev); + wl = HW_TO_WL(hw); + if (!wl) { + WL_ERROR("wl: wl_suspend: pci_get_drvdata failed\n"); + return -ENODEV; + } + + WL_LOCK(wl); + wl_down(wl); + wl->pub->hw_up = false; + WL_UNLOCK(wl); + pci_save_state(pdev, wl->pci_psstate); + pci_disable_device(pdev); + return pci_set_power_state(pdev, PCI_D3hot); +} + +static int wl_resume(struct pci_dev *pdev) +{ + struct wl_info *wl; + struct ieee80211_hw *hw; + int err = 0; + u32 val; + + WL_TRACE("wl: wl_resume\n"); + hw = pci_get_drvdata(pdev); + wl = HW_TO_WL(hw); + if (!wl) { + WL_ERROR("wl: wl_resume: pci_get_drvdata failed\n"); + return -ENODEV; + } + + err = pci_set_power_state(pdev, PCI_D0); + if (err) + return err; + + pci_restore_state(pdev, wl->pci_psstate); + + err = pci_enable_device(pdev); + if (err) + return err; + + pci_set_master(pdev); + + pci_read_config_dword(pdev, 0x40, &val); + if ((val & 0x0000ff00) != 0) + pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); + + WL_LOCK(wl); + err = wl_up(wl); + WL_UNLOCK(wl); + + return err; +} +#endif /* LINUXSTA_PS */ + +static void wl_remove(struct pci_dev *pdev) +{ + struct wl_info *wl; + struct ieee80211_hw *hw; + + hw = pci_get_drvdata(pdev); + wl = HW_TO_WL(hw); + if (!wl) { + WL_ERROR("wl: wl_remove: pci_get_drvdata failed\n"); + return; + } + if (!wlc_chipmatch(pdev->vendor, pdev->device)) { + WL_ERROR("wl: wl_remove: wlc_chipmatch failed\n"); + return; + } + if (wl->wlc) { + ieee80211_unregister_hw(hw); + WL_LOCK(wl); + wl_down(wl); + WL_UNLOCK(wl); + WL_NONE("%s: Down\n", __func__); + } + pci_disable_device(pdev); + + wl_free(wl); + + pci_set_drvdata(pdev, NULL); + ieee80211_free_hw(hw); +} + +static struct pci_driver wl_pci_driver = { + .name = "brcm80211", + .probe = wl_pci_probe, +#ifdef LINUXSTA_PS + .suspend = wl_suspend, + .resume = wl_resume, +#endif /* LINUXSTA_PS */ + .remove = __devexit_p(wl_remove), + .id_table = wl_id_table, +}; + +/** + * This is the main entry point for the WL driver. + * + * This function determines if a device pointed to by pdev is a WL device, + * and if so, performs a wl_attach() on it. + * + */ +static int __init wl_module_init(void) +{ + int error = -ENODEV; + +#ifdef BCMDBG + if (msglevel != 0xdeadbeef) + wl_msg_level = msglevel; + else { + char *var = getvar(NULL, "wl_msglevel"); + if (var) + wl_msg_level = simple_strtoul(var, NULL, 0); + } + { + extern u32 phyhal_msg_level; + + if (phymsglevel != 0xdeadbeef) + phyhal_msg_level = phymsglevel; + else { + char *var = getvar(NULL, "phy_msglevel"); + if (var) + phyhal_msg_level = simple_strtoul(var, NULL, 0); + } + } +#endif /* BCMDBG */ + + error = pci_register_driver(&wl_pci_driver); + if (!error) + return 0; + + + + return error; +} + +/** + * This function unloads the WL driver from the system. + * + * This function unconditionally unloads the WL driver module from the + * system. + * + */ +static void __exit wl_module_exit(void) +{ + pci_unregister_driver(&wl_pci_driver); + +} + +module_init(wl_module_init); +module_exit(wl_module_exit); + +/** + * This function frees the WL per-device resources. + * + * This function frees resources owned by the WL device pointed to + * by the wl parameter. + * + */ +void wl_free(struct wl_info *wl) +{ + wl_timer_t *t, *next; + struct osl_info *osh; + + ASSERT(wl); + /* free ucode data */ + if (wl->fw.fw_cnt) + wl_ucode_data_free(); + if (wl->irq) + free_irq(wl->irq, wl); + + /* kill dpc */ + tasklet_kill(&wl->tasklet); + + if (wl->pub) { + wlc_module_unregister(wl->pub, "linux", wl); + } + + /* free common resources */ + if (wl->wlc) { + wlc_detach(wl->wlc); + wl->wlc = NULL; + wl->pub = NULL; + } + + /* virtual interface deletion is deferred so we cannot spinwait */ + + /* wait for all pending callbacks to complete */ + while (atomic_read(&wl->callbacks) > 0) + schedule(); + + /* free timers */ + for (t = wl->timers; t; t = next) { + next = t->next; +#ifdef BCMDBG + if (t->name) + kfree(t->name); +#endif + kfree(t); + } + + osh = wl->osh; + + /* + * unregister_netdev() calls get_stats() which may read chip registers + * so we cannot unmap the chip registers until after calling unregister_netdev() . + */ + if (wl->regsva && wl->bcm_bustype != SDIO_BUS && + wl->bcm_bustype != JTAG_BUS) { + iounmap((void *)wl->regsva); + } + wl->regsva = NULL; + + + osl_detach(osh); +} + +/* transmit a packet */ +static int BCMFASTPATH wl_start(struct sk_buff *skb, struct wl_info *wl) +{ + if (!wl) + return -ENETDOWN; + + return wl_start_int(wl, WL_TO_HW(wl), skb); +} + +static int BCMFASTPATH +wl_start_int(struct wl_info *wl, struct ieee80211_hw *hw, struct sk_buff *skb) +{ + wlc_sendpkt_mac80211(wl->wlc, skb, hw); + return NETDEV_TX_OK; +} + +void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, + int prio) +{ + WL_ERROR("Shouldn't be here %s\n", __func__); +} + +void wl_init(struct wl_info *wl) +{ + WL_TRACE("wl%d: wl_init\n", wl->pub->unit); + + wl_reset(wl); + + wlc_init(wl->wlc); +} + +uint wl_reset(struct wl_info *wl) +{ + WL_TRACE("wl%d: wl_reset\n", wl->pub->unit); + + wlc_reset(wl->wlc); + + /* dpc will not be rescheduled */ + wl->resched = 0; + + return 0; +} + +/* + * These are interrupt on/off entry points. Disable interrupts + * during interrupt state transition. + */ +void BCMFASTPATH wl_intrson(struct wl_info *wl) +{ + unsigned long flags; + + INT_LOCK(wl, flags); + wlc_intrson(wl->wlc); + INT_UNLOCK(wl, flags); +} + +bool wl_alloc_dma_resources(struct wl_info *wl, uint addrwidth) +{ + return true; +} + +u32 BCMFASTPATH wl_intrsoff(struct wl_info *wl) +{ + unsigned long flags; + u32 status; + + INT_LOCK(wl, flags); + status = wlc_intrsoff(wl->wlc); + INT_UNLOCK(wl, flags); + return status; +} + +void wl_intrsrestore(struct wl_info *wl, u32 macintmask) +{ + unsigned long flags; + + INT_LOCK(wl, flags); + wlc_intrsrestore(wl->wlc, macintmask); + INT_UNLOCK(wl, flags); +} + +int wl_up(struct wl_info *wl) +{ + int error = 0; + + if (wl->pub->up) + return 0; + + error = wlc_up(wl->wlc); + + return error; +} + +void wl_down(struct wl_info *wl) +{ + uint callbacks, ret_val = 0; + + /* call common down function */ + ret_val = wlc_down(wl->wlc); + callbacks = atomic_read(&wl->callbacks) - ret_val; + + /* wait for down callbacks to complete */ + WL_UNLOCK(wl); + + /* For HIGH_only driver, it's important to actually schedule other work, + * not just spin wait since everything runs at schedule level + */ + SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000); + + WL_LOCK(wl); +} + +irqreturn_t BCMFASTPATH wl_isr(int irq, void *dev_id) +{ + struct wl_info *wl; + bool ours, wantdpc; + unsigned long flags; + + wl = (struct wl_info *) dev_id; + + WL_ISRLOCK(wl, flags); + + /* call common first level interrupt handler */ + ours = wlc_isr(wl->wlc, &wantdpc); + if (ours) { + /* if more to do... */ + if (wantdpc) { + + /* ...and call the second level interrupt handler */ + /* schedule dpc */ + ASSERT(wl->resched == false); + tasklet_schedule(&wl->tasklet); + } + } + + WL_ISRUNLOCK(wl, flags); + + return IRQ_RETVAL(ours); +} + +static void BCMFASTPATH wl_dpc(unsigned long data) +{ + struct wl_info *wl; + + wl = (struct wl_info *) data; + + WL_LOCK(wl); + + /* call the common second level interrupt handler */ + if (wl->pub->up) { + if (wl->resched) { + unsigned long flags; + + INT_LOCK(wl, flags); + wlc_intrsupd(wl->wlc); + INT_UNLOCK(wl, flags); + } + + wl->resched = wlc_dpc(wl->wlc, true); + } + + /* wlc_dpc() may bring the driver down */ + if (!wl->pub->up) + goto done; + + /* re-schedule dpc */ + if (wl->resched) + tasklet_schedule(&wl->tasklet); + else { + /* re-enable interrupts */ + wl_intrson(wl); + } + + done: + WL_UNLOCK(wl); +} + +static void wl_link_up(struct wl_info *wl, char *ifname) +{ + WL_ERROR("wl%d: link up (%s)\n", wl->pub->unit, ifname); +} + +static void wl_link_down(struct wl_info *wl, char *ifname) +{ + WL_ERROR("wl%d: link down (%s)\n", wl->pub->unit, ifname); +} + +void wl_event(struct wl_info *wl, char *ifname, wlc_event_t *e) +{ + + switch (e->event.event_type) { + case WLC_E_LINK: + case WLC_E_NDIS_LINK: + if (e->event.flags & WLC_EVENT_MSG_LINK) + wl_link_up(wl, ifname); + else + wl_link_down(wl, ifname); + break; + case WLC_E_RADIO: + break; + } +} + +static void wl_timer(unsigned long data) +{ + _wl_timer((wl_timer_t *) data); +} + +static void _wl_timer(wl_timer_t *t) +{ + WL_LOCK(t->wl); + + if (t->set) { + if (t->periodic) { + t->timer.expires = jiffies + t->ms * HZ / 1000; + atomic_inc(&t->wl->callbacks); + add_timer(&t->timer); + t->set = true; + } else + t->set = false; + + t->fn(t->arg); + } + + atomic_dec(&t->wl->callbacks); + + WL_UNLOCK(t->wl); +} + +wl_timer_t *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg), void *arg, + const char *name) +{ + wl_timer_t *t; + + t = kmalloc(sizeof(wl_timer_t), GFP_ATOMIC); + if (!t) { + WL_ERROR("wl%d: wl_init_timer: out of memory\n", wl->pub->unit); + return 0; + } + + memset(t, 0, sizeof(wl_timer_t)); + + init_timer(&t->timer); + t->timer.data = (unsigned long) t; + t->timer.function = wl_timer; + t->wl = wl; + t->fn = fn; + t->arg = arg; + t->next = wl->timers; + wl->timers = t; + +#ifdef BCMDBG + t->name = kmalloc(strlen(name) + 1, GFP_ATOMIC); + if (t->name) + strcpy(t->name, name); +#endif + + return t; +} + +/* BMAC_NOTE: Add timer adds only the kernel timer since it's going to be more accurate + * as well as it's easier to make it periodic + */ +void wl_add_timer(struct wl_info *wl, wl_timer_t *t, uint ms, int periodic) +{ +#ifdef BCMDBG + if (t->set) { + WL_ERROR("%s: Already set. Name: %s, per %d\n", + __func__, t->name, periodic); + } +#endif + ASSERT(!t->set); + + t->ms = ms; + t->periodic = (bool) periodic; + t->set = true; + t->timer.expires = jiffies + ms * HZ / 1000; + + atomic_inc(&wl->callbacks); + add_timer(&t->timer); +} + +/* return true if timer successfully deleted, false if still pending */ +bool wl_del_timer(struct wl_info *wl, wl_timer_t *t) +{ + if (t->set) { + t->set = false; + if (!del_timer(&t->timer)) { + return false; + } + atomic_dec(&wl->callbacks); + } + + return true; +} + +void wl_free_timer(struct wl_info *wl, wl_timer_t *t) +{ + wl_timer_t *tmp; + + /* delete the timer in case it is active */ + wl_del_timer(wl, t); + + if (wl->timers == t) { + wl->timers = wl->timers->next; +#ifdef BCMDBG + if (t->name) + kfree(t->name); +#endif + kfree(t); + return; + + } + + tmp = wl->timers; + while (tmp) { + if (tmp->next == t) { + tmp->next = t->next; +#ifdef BCMDBG + if (t->name) + kfree(t->name); +#endif + kfree(t); + return; + } + tmp = tmp->next; + } + +} + +static int wl_linux_watchdog(void *ctx) +{ + struct wl_info *wl = (struct wl_info *) ctx; + struct net_device_stats *stats = NULL; + uint id; + /* refresh stats */ + if (wl->pub->up) { + ASSERT(wl->stats_id < 2); + + id = 1 - wl->stats_id; + + stats = &wl->stats_watchdog[id]; + stats->rx_packets = WLCNTVAL(wl->pub->_cnt->rxframe); + stats->tx_packets = WLCNTVAL(wl->pub->_cnt->txframe); + stats->rx_bytes = WLCNTVAL(wl->pub->_cnt->rxbyte); + stats->tx_bytes = WLCNTVAL(wl->pub->_cnt->txbyte); + stats->rx_errors = WLCNTVAL(wl->pub->_cnt->rxerror); + stats->tx_errors = WLCNTVAL(wl->pub->_cnt->txerror); + stats->collisions = 0; + + stats->rx_length_errors = 0; + stats->rx_over_errors = WLCNTVAL(wl->pub->_cnt->rxoflo); + stats->rx_crc_errors = WLCNTVAL(wl->pub->_cnt->rxcrc); + stats->rx_frame_errors = 0; + stats->rx_fifo_errors = WLCNTVAL(wl->pub->_cnt->rxoflo); + stats->rx_missed_errors = 0; + + stats->tx_fifo_errors = WLCNTVAL(wl->pub->_cnt->txuflo); + + wl->stats_id = id; + + } + + return 0; +} + +struct wl_fw_hdr { + u32 offset; + u32 len; + u32 idx; +}; + +char *wl_firmwares[WL_MAX_FW] = { + "brcm/bcm43xx", + NULL +}; + +int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx) +{ + int i, entry; + const u8 *pdata; + struct wl_fw_hdr *hdr; + for (i = 0; i < wl->fw.fw_cnt; i++) { + hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data; + for (entry = 0; entry < wl->fw.hdr_num_entries[i]; + entry++, hdr++) { + if (hdr->idx == idx) { + pdata = wl->fw.fw_bin[i]->data + hdr->offset; + *pbuf = kmalloc(hdr->len, GFP_ATOMIC); + if (*pbuf == NULL) { + printf("fail to alloc %d bytes\n", + hdr->len); + } + bcopy(pdata, *pbuf, hdr->len); + return 0; + } + } + } + printf("ERROR: ucode buf tag:%d can not be found!\n", idx); + *pbuf = NULL; + return -1; +} + +int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx) +{ + int i, entry; + const u8 *pdata; + struct wl_fw_hdr *hdr; + for (i = 0; i < wl->fw.fw_cnt; i++) { + hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data; + for (entry = 0; entry < wl->fw.hdr_num_entries[i]; + entry++, hdr++) { + if (hdr->idx == idx) { + pdata = wl->fw.fw_bin[i]->data + hdr->offset; + ASSERT(hdr->len == 4); + *data = *((u32 *) pdata); + return 0; + } + } + } + printf("ERROR: ucode tag:%d can not be found!\n", idx); + return -1; +} + +static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) +{ + int status; + struct device *device = &pdev->dev; + char fw_name[100]; + int i; + + memset((void *)&wl->fw, 0, sizeof(struct wl_firmware)); + for (i = 0; i < WL_MAX_FW; i++) { + if (wl_firmwares[i] == NULL) + break; + sprintf(fw_name, "%s-%d.fw", wl_firmwares[i], + UCODE_LOADER_API_VER); + WL_NONE("request fw %s\n", fw_name); + status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); + if (status) { + printf("%s: fail to load firmware %s\n", + KBUILD_MODNAME, fw_name); + wl_release_fw(wl); + return status; + } + WL_NONE("request fw %s\n", fw_name); + sprintf(fw_name, "%s_hdr-%d.fw", wl_firmwares[i], + UCODE_LOADER_API_VER); + status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); + if (status) { + printf("%s: fail to load firmware %s\n", + KBUILD_MODNAME, fw_name); + wl_release_fw(wl); + return status; + } + wl->fw.hdr_num_entries[i] = + wl->fw.fw_hdr[i]->size / (sizeof(struct wl_fw_hdr)); + WL_NONE("request fw %s find: %d entries\n", + fw_name, wl->fw.hdr_num_entries[i]); + } + wl->fw.fw_cnt = i; + return wl_ucode_data_init(wl); +} + +void wl_ucode_free_buf(void *p) +{ + kfree(p); +} + +static void wl_release_fw(struct wl_info *wl) +{ + int i; + for (i = 0; i < WL_MAX_FW; i++) { + release_firmware(wl->fw.fw_bin[i]); + release_firmware(wl->fw.fw_hdr[i]); + } +} + + +/* + * checks validity of all firmware images loaded from user space + */ +int wl_check_firmwares(struct wl_info *wl) +{ + int i; + int entry; + int rc = 0; + const struct firmware *fw; + const struct firmware *fw_hdr; + struct wl_fw_hdr *ucode_hdr; + for (i = 0; i < WL_MAX_FW && rc == 0; i++) { + fw = wl->fw.fw_bin[i]; + fw_hdr = wl->fw.fw_hdr[i]; + if (fw == NULL && fw_hdr == NULL) { + break; + } else if (fw == NULL || fw_hdr == NULL) { + WL_ERROR("%s: invalid bin/hdr fw\n", __func__); + rc = -EBADF; + } else if (fw_hdr->size % sizeof(struct wl_fw_hdr)) { + WL_ERROR("%s: non integral fw hdr file size %d/%zu\n", + __func__, fw_hdr->size, + sizeof(struct wl_fw_hdr)); + rc = -EBADF; + } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) { + WL_ERROR("%s: out of bounds fw file size %d\n", + __func__, fw->size); + rc = -EBADF; + } else { + /* check if ucode section overruns firmware image */ + ucode_hdr = (struct wl_fw_hdr *)fw_hdr->data; + for (entry = 0; entry < wl->fw.hdr_num_entries[i] && rc; + entry++, ucode_hdr++) { + if (ucode_hdr->offset + ucode_hdr->len > + fw->size) { + WL_ERROR("%s: conflicting bin/hdr\n", + __func__); + rc = -EBADF; + } + } + } + } + if (rc == 0 && wl->fw.fw_cnt != i) { + WL_ERROR("%s: invalid fw_cnt=%d\n", __func__, wl->fw.fw_cnt); + rc = -EBADF; + } + return rc; +} + diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h new file mode 100644 index 000000000000..bb39b7705947 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wl_mac80211_h_ +#define _wl_mac80211_h_ + +#include + +/* BMAC Note: High-only driver is no longer working in softirq context as it needs to block and + * sleep so perimeter lock has to be a semaphore instead of spinlock. This requires timers to be + * submitted to workqueue instead of being on kernel timer + */ +typedef struct wl_timer { + struct timer_list timer; + struct wl_info *wl; + void (*fn) (void *); + void *arg; /* argument to fn */ + uint ms; + bool periodic; + bool set; + struct wl_timer *next; +#ifdef BCMDBG + char *name; /* Description of the timer */ +#endif +} wl_timer_t; + +/* contortion to call functions at safe time */ +/* In 2.6.20 kernels work functions get passed a pointer to the struct work, so things + * will continue to work as long as the work structure is the first component of the task structure. + */ +typedef struct wl_task { + struct work_struct work; + void *context; +} wl_task_t; + +struct wl_if { + uint subunit; /* WDS/BSS unit */ + struct pci_dev *pci_dev; +}; + +#define WL_MAX_FW 4 +struct wl_firmware { + u32 fw_cnt; + const struct firmware *fw_bin[WL_MAX_FW]; + const struct firmware *fw_hdr[WL_MAX_FW]; + u32 hdr_num_entries[WL_MAX_FW]; +}; + +struct wl_info { + struct wlc_pub *pub; /* pointer to public wlc state */ + void *wlc; /* pointer to private common os-independent data */ + struct osl_info *osh; /* pointer to os handler */ + u32 magic; + + int irq; + + spinlock_t lock; /* per-device perimeter lock */ + spinlock_t isr_lock; /* per-device ISR synchronization lock */ + uint bcm_bustype; /* bus type */ + bool piomode; /* set from insmod argument */ + void *regsva; /* opaque chip registers virtual address */ + atomic_t callbacks; /* # outstanding callback functions */ + struct wl_timer *timers; /* timer cleanup queue */ + struct tasklet_struct tasklet; /* dpc tasklet */ + bool resched; /* dpc needs to be and is rescheduled */ +#ifdef LINUXSTA_PS + u32 pci_psstate[16]; /* pci ps-state save/restore */ +#endif + /* RPC, handle, lock, txq, workitem */ + uint stats_id; /* the current set of stats */ + /* ping-pong stats counters updated by Linux watchdog */ + struct net_device_stats stats_watchdog[2]; + struct wl_firmware fw; +}; + +#define WL_LOCK(wl) spin_lock_bh(&(wl)->lock) +#define WL_UNLOCK(wl) spin_unlock_bh(&(wl)->lock) + +/* locking from inside wl_isr */ +#define WL_ISRLOCK(wl, flags) do {spin_lock(&(wl)->isr_lock); (void)(flags); } while (0) +#define WL_ISRUNLOCK(wl, flags) do {spin_unlock(&(wl)->isr_lock); (void)(flags); } while (0) + +/* locking under WL_LOCK() to synchronize with wl_isr */ +#define INT_LOCK(wl, flags) spin_lock_irqsave(&(wl)->isr_lock, flags) +#define INT_UNLOCK(wl, flags) spin_unlock_irqrestore(&(wl)->isr_lock, flags) + +#ifndef PCI_D0 +#define PCI_D0 0 +#endif + +#ifndef PCI_D3hot +#define PCI_D3hot 3 +#endif + +/* exported functions */ + +extern irqreturn_t wl_isr(int irq, void *dev_id); + +extern int __devinit wl_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent); +extern void wl_free(struct wl_info *wl); +extern int wl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); + +#endif /* _wl_mac80211_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wl_ucode.h b/drivers/staging/brcm80211/brcmsmac/wl_ucode.h new file mode 100644 index 000000000000..2a0f4028f6f3 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wl_ucode.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define MIN_FW_SIZE 40000 /* minimum firmware file size in bytes */ +#define MAX_FW_SIZE 150000 + +typedef struct d11init { + u16 addr; + u16 size; + u32 value; +} d11init_t; + +extern d11init_t *d11lcn0bsinitvals24; +extern d11init_t *d11lcn0initvals24; +extern d11init_t *d11lcn1bsinitvals24; +extern d11init_t *d11lcn1initvals24; +extern d11init_t *d11lcn2bsinitvals24; +extern d11init_t *d11lcn2initvals24; +extern d11init_t *d11n0absinitvals16; +extern d11init_t *d11n0bsinitvals16; +extern d11init_t *d11n0initvals16; +extern u32 *bcm43xx_16_mimo; +extern u32 bcm43xx_16_mimosz; +extern u32 *bcm43xx_24_lcn; +extern u32 bcm43xx_24_lcnsz; +extern u32 *bcm43xx_bommajor; +extern u32 *bcm43xx_bomminor; + +extern int wl_ucode_data_init(struct wl_info *wl); +extern void wl_ucode_data_free(void); + +extern int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, unsigned int idx); +extern int wl_ucode_init_uint(struct wl_info *wl, unsigned *data, + unsigned int idx); +extern void wl_ucode_free_buf(void *); +extern int wl_check_firmwares(struct wl_info *wl); diff --git a/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c b/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c new file mode 100644 index 000000000000..23e10f3dec0d --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + + + +d11init_t *d11lcn0bsinitvals24; +d11init_t *d11lcn0initvals24; +d11init_t *d11lcn1bsinitvals24; +d11init_t *d11lcn1initvals24; +d11init_t *d11lcn2bsinitvals24; +d11init_t *d11lcn2initvals24; +d11init_t *d11n0absinitvals16; +d11init_t *d11n0bsinitvals16; +d11init_t *d11n0initvals16; +u32 *bcm43xx_16_mimo; +u32 bcm43xx_16_mimosz; +u32 *bcm43xx_24_lcn; +u32 bcm43xx_24_lcnsz; +u32 *bcm43xx_bommajor; +u32 *bcm43xx_bomminor; + +int wl_ucode_data_init(struct wl_info *wl) +{ + int rc; + rc = wl_check_firmwares(wl); + if (rc < 0) + return rc; + wl_ucode_init_buf(wl, (void **)&d11lcn0bsinitvals24, + D11LCN0BSINITVALS24); + wl_ucode_init_buf(wl, (void **)&d11lcn0initvals24, D11LCN0INITVALS24); + wl_ucode_init_buf(wl, (void **)&d11lcn1bsinitvals24, + D11LCN1BSINITVALS24); + wl_ucode_init_buf(wl, (void **)&d11lcn1initvals24, D11LCN1INITVALS24); + wl_ucode_init_buf(wl, (void **)&d11lcn2bsinitvals24, + D11LCN2BSINITVALS24); + wl_ucode_init_buf(wl, (void **)&d11lcn2initvals24, D11LCN2INITVALS24); + wl_ucode_init_buf(wl, (void **)&d11n0absinitvals16, D11N0ABSINITVALS16); + wl_ucode_init_buf(wl, (void **)&d11n0bsinitvals16, D11N0BSINITVALS16); + wl_ucode_init_buf(wl, (void **)&d11n0initvals16, D11N0INITVALS16); + wl_ucode_init_buf(wl, (void **)&bcm43xx_16_mimo, + D11UCODE_OVERSIGHT16_MIMO); + wl_ucode_init_uint(wl, &bcm43xx_16_mimosz, D11UCODE_OVERSIGHT16_MIMOSZ); + wl_ucode_init_buf(wl, (void **)&bcm43xx_24_lcn, + D11UCODE_OVERSIGHT24_LCN); + wl_ucode_init_uint(wl, &bcm43xx_24_lcnsz, D11UCODE_OVERSIGHT24_LCNSZ); + wl_ucode_init_buf(wl, (void **)&bcm43xx_bommajor, + D11UCODE_OVERSIGHT_BOMMAJOR); + wl_ucode_init_buf(wl, (void **)&bcm43xx_bomminor, + D11UCODE_OVERSIGHT_BOMMINOR); + + return 0; +} + +void wl_ucode_data_free(void) +{ + wl_ucode_free_buf((void *)d11lcn0bsinitvals24); + wl_ucode_free_buf((void *)d11lcn0initvals24); + wl_ucode_free_buf((void *)d11lcn1bsinitvals24); + wl_ucode_free_buf((void *)d11lcn1initvals24); + wl_ucode_free_buf((void *)d11lcn2bsinitvals24); + wl_ucode_free_buf((void *)d11lcn2initvals24); + wl_ucode_free_buf((void *)d11n0absinitvals16); + wl_ucode_free_buf((void *)d11n0bsinitvals16); + wl_ucode_free_buf((void *)d11n0initvals16); + wl_ucode_free_buf((void *)bcm43xx_16_mimo); + wl_ucode_free_buf((void *)bcm43xx_24_lcn); + wl_ucode_free_buf((void *)bcm43xx_bommajor); + wl_ucode_free_buf((void *)bcm43xx_bomminor); + + return; +} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c new file mode 100644 index 000000000000..7a9fdbb5daee --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, + uint *err, uint devid); +static void wlc_pub_mfree(struct osl_info *osh, struct wlc_pub *pub); +static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid); + +void *wlc_calloc(struct osl_info *osh, uint unit, uint size) +{ + void *item; + + item = kzalloc(size, GFP_ATOMIC); + if (item == NULL) + WL_ERROR("wl%d: %s: out of memory\n", unit, __func__); + return item; +} + +void wlc_tunables_init(wlc_tunables_t *tunables, uint devid) +{ + tunables->ntxd = NTXD; + tunables->nrxd = NRXD; + tunables->rxbufsz = RXBUFSZ; + tunables->nrxbufpost = NRXBUFPOST; + tunables->maxscb = MAXSCB; + tunables->ampdunummpdu = AMPDU_NUM_MPDU; + tunables->maxpktcb = MAXPKTCB; + tunables->maxucodebss = WLC_MAX_UCODE_BSS; + tunables->maxucodebss4 = WLC_MAX_UCODE_BSS4; + tunables->maxbss = MAXBSS; + tunables->datahiwat = WLC_DATAHIWAT; + tunables->ampdudatahiwat = WLC_AMPDUDATAHIWAT; + tunables->rxbnd = RXBND; + tunables->txsbnd = TXSBND; +} + +static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, + uint *err, uint devid) +{ + struct wlc_pub *pub; + + pub = (struct wlc_pub *) wlc_calloc(osh, unit, sizeof(struct wlc_pub)); + if (pub == NULL) { + *err = 1001; + goto fail; + } + + pub->tunables = (wlc_tunables_t *)wlc_calloc(osh, unit, + sizeof(wlc_tunables_t)); + if (pub->tunables == NULL) { + *err = 1028; + goto fail; + } + + /* need to init the tunables now */ + wlc_tunables_init(pub->tunables, devid); + + pub->multicast = (u8 *)wlc_calloc(osh, unit, + (ETH_ALEN * MAXMULTILIST)); + if (pub->multicast == NULL) { + *err = 1003; + goto fail; + } + + return pub; + + fail: + wlc_pub_mfree(osh, pub); + return NULL; +} + +static void wlc_pub_mfree(struct osl_info *osh, struct wlc_pub *pub) +{ + if (pub == NULL) + return; + + if (pub->multicast) + kfree(pub->multicast); + if (pub->tunables) { + kfree(pub->tunables); + pub->tunables = NULL; + } + + kfree(pub); +} + +wlc_bsscfg_t *wlc_bsscfg_malloc(struct osl_info *osh, uint unit) +{ + wlc_bsscfg_t *cfg; + + cfg = (wlc_bsscfg_t *) wlc_calloc(osh, unit, sizeof(wlc_bsscfg_t)); + if (cfg == NULL) + goto fail; + + cfg->current_bss = (wlc_bss_info_t *)wlc_calloc(osh, unit, + sizeof(wlc_bss_info_t)); + if (cfg->current_bss == NULL) + goto fail; + + return cfg; + + fail: + wlc_bsscfg_mfree(osh, cfg); + return NULL; +} + +void wlc_bsscfg_mfree(struct osl_info *osh, wlc_bsscfg_t *cfg) +{ + if (cfg == NULL) + return; + + if (cfg->maclist) { + kfree(cfg->maclist); + cfg->maclist = NULL; + } + + if (cfg->current_bss != NULL) { + wlc_bss_info_t *current_bss = cfg->current_bss; + kfree(current_bss); + cfg->current_bss = NULL; + } + + kfree(cfg); +} + +void wlc_bsscfg_ID_assign(struct wlc_info *wlc, wlc_bsscfg_t *bsscfg) +{ + bsscfg->ID = wlc->next_bsscfg_ID; + wlc->next_bsscfg_ID++; +} + +/* + * The common driver entry routine. Error codes should be unique + */ +struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, + uint devid) +{ + struct wlc_info *wlc; + + wlc = (struct wlc_info *) wlc_calloc(osh, unit, + sizeof(struct wlc_info)); + if (wlc == NULL) { + *err = 1002; + goto fail; + } + + wlc->hwrxoff = WL_HWRXOFF; + + /* allocate struct wlc_pub state structure */ + wlc->pub = wlc_pub_malloc(osh, unit, err, devid); + if (wlc->pub == NULL) { + *err = 1003; + goto fail; + } + wlc->pub->wlc = wlc; + + /* allocate struct wlc_hw_info state structure */ + + wlc->hw = (struct wlc_hw_info *)wlc_calloc(osh, unit, + sizeof(struct wlc_hw_info)); + if (wlc->hw == NULL) { + *err = 1005; + goto fail; + } + wlc->hw->wlc = wlc; + + wlc->hw->bandstate[0] = (wlc_hwband_t *)wlc_calloc(osh, unit, + (sizeof(wlc_hwband_t) * MAXBANDS)); + if (wlc->hw->bandstate[0] == NULL) { + *err = 1006; + goto fail; + } else { + int i; + + for (i = 1; i < MAXBANDS; i++) { + wlc->hw->bandstate[i] = (wlc_hwband_t *) + ((unsigned long)wlc->hw->bandstate[0] + + (sizeof(wlc_hwband_t) * i)); + } + } + + wlc->modulecb = (modulecb_t *)wlc_calloc(osh, unit, + sizeof(modulecb_t) * WLC_MAXMODULES); + if (wlc->modulecb == NULL) { + *err = 1009; + goto fail; + } + + wlc->default_bss = (wlc_bss_info_t *)wlc_calloc(osh, unit, + sizeof(wlc_bss_info_t)); + if (wlc->default_bss == NULL) { + *err = 1010; + goto fail; + } + + wlc->cfg = wlc_bsscfg_malloc(osh, unit); + if (wlc->cfg == NULL) { + *err = 1011; + goto fail; + } + wlc_bsscfg_ID_assign(wlc, wlc->cfg); + + wlc->pkt_callback = (pkt_cb_t *)wlc_calloc(osh, unit, + (sizeof(pkt_cb_t) * (wlc->pub->tunables->maxpktcb + 1))); + if (wlc->pkt_callback == NULL) { + *err = 1013; + goto fail; + } + + wlc->wsec_def_keys[0] = (wsec_key_t *)wlc_calloc(osh, unit, + (sizeof(wsec_key_t) * WLC_DEFAULT_KEYS)); + if (wlc->wsec_def_keys[0] == NULL) { + *err = 1015; + goto fail; + } else { + int i; + for (i = 1; i < WLC_DEFAULT_KEYS; i++) { + wlc->wsec_def_keys[i] = (wsec_key_t *) + ((unsigned long)wlc->wsec_def_keys[0] + + (sizeof(wsec_key_t) * i)); + } + } + + wlc->protection = (wlc_protection_t *)wlc_calloc(osh, unit, + sizeof(wlc_protection_t)); + if (wlc->protection == NULL) { + *err = 1016; + goto fail; + } + + wlc->stf = (wlc_stf_t *)wlc_calloc(osh, unit, sizeof(wlc_stf_t)); + if (wlc->stf == NULL) { + *err = 1017; + goto fail; + } + + wlc->bandstate[0] = (struct wlcband *)wlc_calloc(osh, unit, + (sizeof(struct wlcband)*MAXBANDS)); + if (wlc->bandstate[0] == NULL) { + *err = 1025; + goto fail; + } else { + int i; + + for (i = 1; i < MAXBANDS; i++) { + wlc->bandstate[i] = + (struct wlcband *) ((unsigned long)wlc->bandstate[0] + + (sizeof(struct wlcband)*i)); + } + } + + wlc->corestate = (struct wlccore *)wlc_calloc(osh, unit, + sizeof(struct wlccore)); + if (wlc->corestate == NULL) { + *err = 1026; + goto fail; + } + + wlc->corestate->macstat_snapshot = + (macstat_t *)wlc_calloc(osh, unit, sizeof(macstat_t)); + if (wlc->corestate->macstat_snapshot == NULL) { + *err = 1027; + goto fail; + } + + return wlc; + + fail: + wlc_detach_mfree(wlc, osh); + return NULL; +} + +void wlc_detach_mfree(struct wlc_info *wlc, struct osl_info *osh) +{ + if (wlc == NULL) + return; + + if (wlc->modulecb) { + kfree(wlc->modulecb); + wlc->modulecb = NULL; + } + + if (wlc->default_bss) { + kfree(wlc->default_bss); + wlc->default_bss = NULL; + } + if (wlc->cfg) { + wlc_bsscfg_mfree(osh, wlc->cfg); + wlc->cfg = NULL; + } + + if (wlc->pkt_callback && wlc->pub && wlc->pub->tunables) { + kfree(wlc->pkt_callback); + wlc->pkt_callback = NULL; + } + + if (wlc->wsec_def_keys[0]) + kfree(wlc->wsec_def_keys[0]); + if (wlc->protection) { + kfree(wlc->protection); + wlc->protection = NULL; + } + + if (wlc->stf) { + kfree(wlc->stf); + wlc->stf = NULL; + } + + if (wlc->bandstate[0]) + kfree(wlc->bandstate[0]); + + if (wlc->corestate) { + if (wlc->corestate->macstat_snapshot) { + kfree(wlc->corestate->macstat_snapshot); wlc->corestate->macstat_snapshot = NULL; + } + kfree(wlc->corestate); + wlc->corestate = NULL; + } + + if (wlc->pub) { + /* free pub struct */ + wlc_pub_mfree(osh, wlc->pub); + wlc->pub = NULL; + } + + if (wlc->hw) { + if (wlc->hw->bandstate[0]) { + kfree(wlc->hw->bandstate[0]); + wlc->hw->bandstate[0] = NULL; + } + + /* free hw struct */ + kfree(wlc->hw); + wlc->hw = NULL; + } + + /* free the wlc */ + kfree(wlc); + wlc = NULL; +} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h new file mode 100644 index 000000000000..ac34f782b400 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +extern void *wlc_calloc(struct osl_info *osh, uint unit, uint size); + +extern struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, + uint *err, uint devid); +extern void wlc_detach_mfree(struct wlc_info *wlc, struct osl_info *osh); + +struct wlc_bsscfg; +extern struct wlc_bsscfg *wlc_bsscfg_malloc(struct osl_info *osh, uint unit); +extern void wlc_bsscfg_mfree(struct osl_info *osh, struct wlc_bsscfg *cfg); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c new file mode 100644 index 000000000000..8e1011203481 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -0,0 +1,1356 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define AMPDU_MAX_MPDU 32 /* max number of mpdus in an ampdu */ +#define AMPDU_NUM_MPDU_LEGACY 16 /* max number of mpdus in an ampdu to a legacy */ +#define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */ +#define AMPDU_TX_BA_DEF_WSIZE 64 /* default Tx ba window size (in pdu) */ +#define AMPDU_RX_BA_DEF_WSIZE 64 /* max Rx ba window size (in pdu) */ +#define AMPDU_RX_BA_MAX_WSIZE 64 /* default Rx ba window size (in pdu) */ +#define AMPDU_MAX_DUR 5 /* max dur of tx ampdu (in msec) */ +#define AMPDU_DEF_RETRY_LIMIT 5 /* default tx retry limit */ +#define AMPDU_DEF_RR_RETRY_LIMIT 2 /* default tx retry limit at reg rate */ +#define AMPDU_DEF_TXPKT_WEIGHT 2 /* default weight of ampdu in txfifo */ +#define AMPDU_DEF_FFPLD_RSVD 2048 /* default ffpld reserved bytes */ +#define AMPDU_INI_FREE 10 /* # of inis to be freed on detach */ +#define AMPDU_SCB_MAX_RELEASE 20 /* max # of mpdus released at a time */ + +#define NUM_FFPLD_FIFO 4 /* number of fifo concerned by pre-loading */ +#define FFPLD_TX_MAX_UNFL 200 /* default value of the average number of ampdu + * without underflows + */ +#define FFPLD_MPDU_SIZE 1800 /* estimate of maximum mpdu size */ +#define FFPLD_MAX_MCS 23 /* we don't deal with mcs 32 */ +#define FFPLD_PLD_INCR 1000 /* increments in bytes */ +#define FFPLD_MAX_AMPDU_CNT 5000 /* maximum number of ampdu we + * accumulate between resets. + */ + +#define TX_SEQ_TO_INDEX(seq) ((seq) % AMPDU_TX_BA_MAX_WSIZE) + +/* max possible overhead per mpdu in the ampdu; 3 is for roundup if needed */ +#define AMPDU_MAX_MPDU_OVERHEAD (FCS_LEN + DOT11_ICV_AES_LEN +\ + AMPDU_DELIMITER_LEN + 3\ + + DOT11_A4_HDR_LEN + DOT11_QOS_LEN + DOT11_IV_MAX_LEN) + +#ifdef BCMDBG +u32 wl_ampdu_dbg = + WL_AMPDU_UPDN_VAL | + WL_AMPDU_ERR_VAL | + WL_AMPDU_TX_VAL | + WL_AMPDU_RX_VAL | + WL_AMPDU_CTL_VAL | + WL_AMPDU_HW_VAL | WL_AMPDU_HWTXS_VAL | WL_AMPDU_HWDBG_VAL; +#endif + +/* structure to hold tx fifo information and pre-loading state + * counters specific to tx underflows of ampdus + * some counters might be redundant with the ones in wlc or ampdu structures. + * This allows to maintain a specific state independantly of + * how often and/or when the wlc counters are updated. + */ +typedef struct wlc_fifo_info { + u16 ampdu_pld_size; /* number of bytes to be pre-loaded */ + u8 mcs2ampdu_table[FFPLD_MAX_MCS + 1]; /* per-mcs max # of mpdus in an ampdu */ + u16 prev_txfunfl; /* num of underflows last read from the HW macstats counter */ + u32 accum_txfunfl; /* num of underflows since we modified pld params */ + u32 accum_txampdu; /* num of tx ampdu since we modified pld params */ + u32 prev_txampdu; /* previous reading of tx ampdu */ + u32 dmaxferrate; /* estimated dma avg xfer rate in kbits/sec */ +} wlc_fifo_info_t; + +/* AMPDU module specific state */ +struct ampdu_info { + struct wlc_info *wlc; /* pointer to main wlc structure */ + int scb_handle; /* scb cubby handle to retrieve data from scb */ + u8 ini_enable[AMPDU_MAX_SCB_TID]; /* per-tid initiator enable/disable of ampdu */ + u8 ba_tx_wsize; /* Tx ba window size (in pdu) */ + u8 ba_rx_wsize; /* Rx ba window size (in pdu) */ + u8 retry_limit; /* mpdu transmit retry limit */ + u8 rr_retry_limit; /* mpdu transmit retry limit at regular rate */ + u8 retry_limit_tid[AMPDU_MAX_SCB_TID]; /* per-tid mpdu transmit retry limit */ + /* per-tid mpdu transmit retry limit at regular rate */ + u8 rr_retry_limit_tid[AMPDU_MAX_SCB_TID]; + u8 mpdu_density; /* min mpdu spacing (0-7) ==> 2^(x-1)/8 usec */ + s8 max_pdu; /* max pdus allowed in ampdu */ + u8 dur; /* max duration of an ampdu (in msec) */ + u8 txpkt_weight; /* weight of ampdu in txfifo; reduces rate lag */ + u8 rx_factor; /* maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes */ + u32 ffpld_rsvd; /* number of bytes to reserve for preload */ + u32 max_txlen[MCS_TABLE_SIZE][2][2]; /* max size of ampdu per mcs, bw and sgi */ + void *ini_free[AMPDU_INI_FREE]; /* array of ini's to be freed on detach */ + bool mfbr; /* enable multiple fallback rate */ + u32 tx_max_funl; /* underflows should be kept such that + * (tx_max_funfl*underflows) < tx frames + */ + wlc_fifo_info_t fifo_tb[NUM_FFPLD_FIFO]; /* table of fifo infos */ + +}; + +#define AMPDU_CLEANUPFLAG_RX (0x1) +#define AMPDU_CLEANUPFLAG_TX (0x2) + +#define SCB_AMPDU_CUBBY(ampdu, scb) (&(scb->scb_ampdu)) +#define SCB_AMPDU_INI(scb_ampdu, tid) (&(scb_ampdu->ini[tid])) + +static void wlc_ffpld_init(struct ampdu_info *ampdu); +static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int f); +static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f); + +static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu, + scb_ampdu_t *scb_ampdu, + u8 tid, bool override); +static void ampdu_cleanup_tid_ini(struct ampdu_info *ampdu, + scb_ampdu_t *scb_ampdu, + u8 tid, bool force); +static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur); +static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb); +static void scb_ampdu_update_config_all(struct ampdu_info *ampdu); + +#define wlc_ampdu_txflowcontrol(a, b, c) do {} while (0) + +static void wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, + struct scb *scb, + struct sk_buff *p, tx_status_t *txs, + u32 frmtxstatus, u32 frmtxstatus2); + +static inline u16 pkt_txh_seqnum(struct wlc_info *wlc, struct sk_buff *p) +{ + d11txh_t *txh; + struct ieee80211_hdr *h; + txh = (d11txh_t *) p->data; + h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); + return ltoh16(h->seq_ctrl) >> SEQNUM_SHIFT; +} + +struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc) +{ + struct ampdu_info *ampdu; + int i; + + /* some code depends on packed structures */ + ASSERT(DOT11_MAXNUMFRAGS == NBITS(u16)); + ASSERT(ISPOWEROF2(AMPDU_TX_BA_MAX_WSIZE)); + ASSERT(ISPOWEROF2(AMPDU_RX_BA_MAX_WSIZE)); + ASSERT(wlc->pub->tunables->ampdunummpdu <= AMPDU_MAX_MPDU); + ASSERT(wlc->pub->tunables->ampdunummpdu > 0); + + ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC); + if (!ampdu) { + WL_ERROR("wl%d: wlc_ampdu_attach: out of mem\n", + wlc->pub->unit); + return NULL; + } + ampdu->wlc = wlc; + + for (i = 0; i < AMPDU_MAX_SCB_TID; i++) + ampdu->ini_enable[i] = true; + /* Disable ampdu for VO by default */ + ampdu->ini_enable[PRIO_8021D_VO] = false; + ampdu->ini_enable[PRIO_8021D_NC] = false; + + /* Disable ampdu for BK by default since not enough fifo space */ + ampdu->ini_enable[PRIO_8021D_NONE] = false; + ampdu->ini_enable[PRIO_8021D_BK] = false; + + ampdu->ba_tx_wsize = AMPDU_TX_BA_DEF_WSIZE; + ampdu->ba_rx_wsize = AMPDU_RX_BA_DEF_WSIZE; + ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY; + ampdu->max_pdu = AUTO; + ampdu->dur = AMPDU_MAX_DUR; + ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT; + + ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD; + /* bump max ampdu rcv size to 64k for all 11n devices except 4321A0 and 4321A1 */ + if (WLCISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2)) + ampdu->rx_factor = AMPDU_RX_FACTOR_32K; + else + ampdu->rx_factor = AMPDU_RX_FACTOR_64K; + ampdu->retry_limit = AMPDU_DEF_RETRY_LIMIT; + ampdu->rr_retry_limit = AMPDU_DEF_RR_RETRY_LIMIT; + + for (i = 0; i < AMPDU_MAX_SCB_TID; i++) { + ampdu->retry_limit_tid[i] = ampdu->retry_limit; + ampdu->rr_retry_limit_tid[i] = ampdu->rr_retry_limit; + } + + ampdu_update_max_txlen(ampdu, ampdu->dur); + ampdu->mfbr = false; + /* try to set ampdu to the default value */ + wlc_ampdu_set(ampdu, wlc->pub->_ampdu); + + ampdu->tx_max_funl = FFPLD_TX_MAX_UNFL; + wlc_ffpld_init(ampdu); + + return ampdu; +} + +void wlc_ampdu_detach(struct ampdu_info *ampdu) +{ + int i; + + if (!ampdu) + return; + + /* free all ini's which were to be freed on callbacks which were never called */ + for (i = 0; i < AMPDU_INI_FREE; i++) { + if (ampdu->ini_free[i]) { + kfree(ampdu->ini_free[i]); + } + } + + wlc_module_unregister(ampdu->wlc->pub, "ampdu", ampdu); + kfree(ampdu); +} + +void scb_ampdu_cleanup(struct ampdu_info *ampdu, struct scb *scb) +{ + scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); + u8 tid; + + WL_AMPDU_UPDN("scb_ampdu_cleanup: enter\n"); + ASSERT(scb_ampdu); + + for (tid = 0; tid < AMPDU_MAX_SCB_TID; tid++) { + ampdu_cleanup_tid_ini(ampdu, scb_ampdu, tid, false); + } +} + +/* reset the ampdu state machine so that it can gracefully handle packets that were + * freed from the dma and tx queues during reinit + */ +void wlc_ampdu_reset(struct ampdu_info *ampdu) +{ + WL_NONE("%s: Entering\n", __func__); +} + +static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb) +{ + scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); + int i; + + scb_ampdu->max_pdu = (u8) ampdu->wlc->pub->tunables->ampdunummpdu; + + /* go back to legacy size if some preloading is occuring */ + for (i = 0; i < NUM_FFPLD_FIFO; i++) { + if (ampdu->fifo_tb[i].ampdu_pld_size > FFPLD_PLD_INCR) + scb_ampdu->max_pdu = AMPDU_NUM_MPDU_LEGACY; + } + + /* apply user override */ + if (ampdu->max_pdu != AUTO) + scb_ampdu->max_pdu = (u8) ampdu->max_pdu; + + scb_ampdu->release = min_t(u8, scb_ampdu->max_pdu, AMPDU_SCB_MAX_RELEASE); + + if (scb_ampdu->max_rxlen) + scb_ampdu->release = + min_t(u8, scb_ampdu->release, scb_ampdu->max_rxlen / 1600); + + scb_ampdu->release = min(scb_ampdu->release, + ampdu->fifo_tb[TX_AC_BE_FIFO]. + mcs2ampdu_table[FFPLD_MAX_MCS]); + + ASSERT(scb_ampdu->release); +} + +void scb_ampdu_update_config_all(struct ampdu_info *ampdu) +{ + scb_ampdu_update_config(ampdu, ampdu->wlc->pub->global_scb); +} + +static void wlc_ffpld_init(struct ampdu_info *ampdu) +{ + int i, j; + wlc_fifo_info_t *fifo; + + for (j = 0; j < NUM_FFPLD_FIFO; j++) { + fifo = (ampdu->fifo_tb + j); + fifo->ampdu_pld_size = 0; + for (i = 0; i <= FFPLD_MAX_MCS; i++) + fifo->mcs2ampdu_table[i] = 255; + fifo->dmaxferrate = 0; + fifo->accum_txampdu = 0; + fifo->prev_txfunfl = 0; + fifo->accum_txfunfl = 0; + + } +} + +/* evaluate the dma transfer rate using the tx underflows as feedback. + * If necessary, increase tx fifo preloading. If not enough, + * decrease maximum ampdu size for each mcs till underflows stop + * Return 1 if pre-loading not active, -1 if not an underflow event, + * 0 if pre-loading module took care of the event. + */ +static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) +{ + struct ampdu_info *ampdu = wlc->ampdu; + u32 phy_rate = MCS_RATE(FFPLD_MAX_MCS, true, false); + u32 txunfl_ratio; + u8 max_mpdu; + u32 current_ampdu_cnt = 0; + u16 max_pld_size; + u32 new_txunfl; + wlc_fifo_info_t *fifo = (ampdu->fifo_tb + fid); + uint xmtfifo_sz; + u16 cur_txunfl; + + /* return if we got here for a different reason than underflows */ + cur_txunfl = + wlc_read_shm(wlc, + M_UCODE_MACSTAT + offsetof(macstat_t, txfunfl[fid])); + new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl); + if (new_txunfl == 0) { + WL_FFPLD("check_txunfl : TX status FRAG set but no tx underflows\n"); + return -1; + } + fifo->prev_txfunfl = cur_txunfl; + + if (!ampdu->tx_max_funl) + return 1; + + /* check if fifo is big enough */ + if (wlc_xmtfifo_sz_get(wlc, fid, &xmtfifo_sz)) { + WL_FFPLD("check_txunfl : get xmtfifo_sz failed\n"); + return -1; + } + + if ((TXFIFO_SIZE_UNIT * (u32) xmtfifo_sz) <= ampdu->ffpld_rsvd) + return 1; + + max_pld_size = TXFIFO_SIZE_UNIT * xmtfifo_sz - ampdu->ffpld_rsvd; + fifo->accum_txfunfl += new_txunfl; + + /* we need to wait for at least 10 underflows */ + if (fifo->accum_txfunfl < 10) + return 0; + + WL_FFPLD("ampdu_count %d tx_underflows %d\n", + current_ampdu_cnt, fifo->accum_txfunfl); + + /* + compute the current ratio of tx unfl per ampdu. + When the current ampdu count becomes too + big while the ratio remains small, we reset + the current count in order to not + introduce too big of a latency in detecting a + large amount of tx underflows later. + */ + + txunfl_ratio = current_ampdu_cnt / fifo->accum_txfunfl; + + if (txunfl_ratio > ampdu->tx_max_funl) { + if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT) { + fifo->accum_txfunfl = 0; + } + return 0; + } + max_mpdu = + min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY); + + /* In case max value max_pdu is already lower than + the fifo depth, there is nothing more we can do. + */ + + if (fifo->ampdu_pld_size >= max_mpdu * FFPLD_MPDU_SIZE) { + WL_FFPLD(("tx fifo pld : max ampdu fits in fifo\n)")); + fifo->accum_txfunfl = 0; + return 0; + } + + if (fifo->ampdu_pld_size < max_pld_size) { + + /* increment by TX_FIFO_PLD_INC bytes */ + fifo->ampdu_pld_size += FFPLD_PLD_INCR; + if (fifo->ampdu_pld_size > max_pld_size) + fifo->ampdu_pld_size = max_pld_size; + + /* update scb release size */ + scb_ampdu_update_config_all(ampdu); + + /* + compute a new dma xfer rate for max_mpdu @ max mcs. + This is the minimum dma rate that + can acheive no unferflow condition for the current mpdu size. + */ + /* note : we divide/multiply by 100 to avoid integer overflows */ + fifo->dmaxferrate = + (((phy_rate / 100) * + (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size)) + / (max_mpdu * FFPLD_MPDU_SIZE)) * 100; + + WL_FFPLD("DMA estimated transfer rate %d; pre-load size %d\n", + fifo->dmaxferrate, fifo->ampdu_pld_size); + } else { + + /* decrease ampdu size */ + if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] > 1) { + if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] == 255) + fifo->mcs2ampdu_table[FFPLD_MAX_MCS] = + AMPDU_NUM_MPDU_LEGACY - 1; + else + fifo->mcs2ampdu_table[FFPLD_MAX_MCS] -= 1; + + /* recompute the table */ + wlc_ffpld_calc_mcs2ampdu_table(ampdu, fid); + + /* update scb release size */ + scb_ampdu_update_config_all(ampdu); + } + } + fifo->accum_txfunfl = 0; + return 0; +} + +static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f) +{ + int i; + u32 phy_rate, dma_rate, tmp; + u8 max_mpdu; + wlc_fifo_info_t *fifo = (ampdu->fifo_tb + f); + + /* recompute the dma rate */ + /* note : we divide/multiply by 100 to avoid integer overflows */ + max_mpdu = + min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY); + phy_rate = MCS_RATE(FFPLD_MAX_MCS, true, false); + dma_rate = + (((phy_rate / 100) * + (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size)) + / (max_mpdu * FFPLD_MPDU_SIZE)) * 100; + fifo->dmaxferrate = dma_rate; + + /* fill up the mcs2ampdu table; do not recalc the last mcs */ + dma_rate = dma_rate >> 7; + for (i = 0; i < FFPLD_MAX_MCS; i++) { + /* shifting to keep it within integer range */ + phy_rate = MCS_RATE(i, true, false) >> 7; + if (phy_rate > dma_rate) { + tmp = ((fifo->ampdu_pld_size * phy_rate) / + ((phy_rate - dma_rate) * FFPLD_MPDU_SIZE)) + 1; + tmp = min_t(u32, tmp, 255); + fifo->mcs2ampdu_table[i] = (u8) tmp; + } + } +} + +static void BCMFASTPATH +wlc_ampdu_agg(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p, + uint prec) +{ + scb_ampdu_t *scb_ampdu; + scb_ampdu_tid_ini_t *ini; + u8 tid = (u8) (p->priority); + + scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); + + /* initialize initiator on first packet; sends addba req */ + ini = SCB_AMPDU_INI(scb_ampdu, tid); + if (ini->magic != INI_MAGIC) { + ini = wlc_ampdu_init_tid_ini(ampdu, scb_ampdu, tid, false); + } + return; +} + +int BCMFASTPATH +wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, + struct sk_buff **pdu, int prec) +{ + struct wlc_info *wlc; + struct osl_info *osh; + struct sk_buff *p, *pkt[AMPDU_MAX_MPDU]; + u8 tid, ndelim; + int err = 0; + u8 preamble_type = WLC_GF_PREAMBLE; + u8 fbr_preamble_type = WLC_GF_PREAMBLE; + u8 rts_preamble_type = WLC_LONG_PREAMBLE; + u8 rts_fbr_preamble_type = WLC_LONG_PREAMBLE; + + bool rr = true, fbr = false; + uint i, count = 0, fifo, seg_cnt = 0; + u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0; + u32 ampdu_len, maxlen = 0; + d11txh_t *txh = NULL; + u8 *plcp; + struct ieee80211_hdr *h; + struct scb *scb; + scb_ampdu_t *scb_ampdu; + scb_ampdu_tid_ini_t *ini; + u8 mcs = 0; + bool use_rts = false, use_cts = false; + ratespec_t rspec = 0, rspec_fallback = 0; + ratespec_t rts_rspec = 0, rts_rspec_fallback = 0; + u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; + struct ieee80211_rts *rts; + u8 rr_retry_limit; + wlc_fifo_info_t *f; + bool fbr_iscck; + struct ieee80211_tx_info *tx_info; + u16 qlen; + + wlc = ampdu->wlc; + osh = wlc->osh; + p = *pdu; + + ASSERT(p); + + tid = (u8) (p->priority); + ASSERT(tid < AMPDU_MAX_SCB_TID); + + f = ampdu->fifo_tb + prio2fifo[tid]; + + scb = wlc->pub->global_scb; + ASSERT(scb->magic == SCB_MAGIC); + + scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); + ASSERT(scb_ampdu); + ini = &scb_ampdu->ini[tid]; + + /* Let pressure continue to build ... */ + qlen = pktq_plen(&qi->q, prec); + if (ini->tx_in_transit > 0 && qlen < scb_ampdu->max_pdu) { + return BCME_BUSY; + } + + wlc_ampdu_agg(ampdu, scb, p, tid); + + if (wlc->block_datafifo) { + WL_ERROR("%s: Fifo blocked\n", __func__); + return BCME_BUSY; + } + rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; + ampdu_len = 0; + dma_len = 0; + while (p) { + struct ieee80211_tx_rate *txrate; + + tx_info = IEEE80211_SKB_CB(p); + txrate = tx_info->status.rates; + + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { + err = wlc_prep_pdu(wlc, p, &fifo); + } else { + WL_ERROR("%s: AMPDU flag is off!\n", __func__); + *pdu = NULL; + err = 0; + break; + } + + if (err) { + if (err == BCME_BUSY) { + WL_ERROR("wl%d: wlc_sendampdu: prep_xdu retry; seq 0x%x\n", + wlc->pub->unit, seq); + WLCNTINCR(ampdu->cnt->sduretry); + *pdu = p; + break; + } + + /* error in the packet; reject it */ + WL_AMPDU_ERR("wl%d: wlc_sendampdu: prep_xdu rejected; seq 0x%x\n", + wlc->pub->unit, seq); + WLCNTINCR(ampdu->cnt->sdurejected); + + *pdu = NULL; + break; + } + + /* pkt is good to be aggregated */ + ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); + txh = (d11txh_t *) p->data; + plcp = (u8 *) (txh + 1); + h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); + seq = ltoh16(h->seq_ctrl) >> SEQNUM_SHIFT; + index = TX_SEQ_TO_INDEX(seq); + + /* check mcl fields and test whether it can be agg'd */ + mcl = ltoh16(txh->MacTxControlLow); + mcl &= ~TXC_AMPDU_MASK; + fbr_iscck = !(ltoh16(txh->XtraFrameTypes) & 0x3); + ASSERT(!fbr_iscck); + txh->PreloadSize = 0; /* always default to 0 */ + + /* Handle retry limits */ + if (txrate[0].count <= rr_retry_limit) { + txrate[0].count++; + rr = true; + fbr = false; + ASSERT(!fbr); + } else { + fbr = true; + rr = false; + txrate[1].count++; + } + + /* extract the length info */ + len = fbr_iscck ? WLC_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) + : WLC_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); + + /* retrieve null delimiter count */ + ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; + seg_cnt += 1; + + WL_AMPDU_TX("wl%d: wlc_sendampdu: mpdu %d plcp_len %d\n", + wlc->pub->unit, count, len); + + /* + * aggregateable mpdu. For ucode/hw agg, + * test whether need to break or change the epoch + */ + if (count == 0) { + u16 fc; + mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT); + /* refill the bits since might be a retx mpdu */ + mcl |= TXC_STARTMSDU; + rts = (struct ieee80211_rts *)&txh->rts_frame; + fc = ltoh16(rts->frame_control); + if ((fc & FC_KIND_MASK) == FC_RTS) { + mcl |= TXC_SENDRTS; + use_rts = true; + } + if ((fc & FC_KIND_MASK) == FC_CTS) { + mcl |= TXC_SENDCTS; + use_cts = true; + } + } else { + mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT); + mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS); + } + + len = roundup(len, 4); + ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN); + + dma_len += (u16) pkttotlen(osh, p); + + WL_AMPDU_TX("wl%d: wlc_sendampdu: ampdu_len %d seg_cnt %d null delim %d\n", + wlc->pub->unit, ampdu_len, seg_cnt, ndelim); + + txh->MacTxControlLow = htol16(mcl); + + /* this packet is added */ + pkt[count++] = p; + + /* patch the first MPDU */ + if (count == 1) { + u8 plcp0, plcp3, is40, sgi; + struct ieee80211_sta *sta; + + sta = tx_info->control.sta; + + if (rr) { + plcp0 = plcp[0]; + plcp3 = plcp[3]; + } else { + plcp0 = txh->FragPLCPFallback[0]; + plcp3 = txh->FragPLCPFallback[3]; + + } + is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; + sgi = PLCP3_ISSGI(plcp3) ? 1 : 0; + mcs = plcp0 & ~MIMO_PLCP_40MHZ; + ASSERT(mcs < MCS_TABLE_SIZE); + maxlen = + min(scb_ampdu->max_rxlen, + ampdu->max_txlen[mcs][is40][sgi]); + + WL_NONE("sendampdu: sgi %d, is40 %d, mcs %d\n", + sgi, is40, mcs); + + maxlen = 64 * 1024; /* XXX Fix me to honor real max_rxlen */ + + if (is40) + mimo_ctlchbw = + CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC) + ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; + + /* rebuild the rspec and rspec_fallback */ + rspec = RSPEC_MIMORATE; + rspec |= plcp[0] & ~MIMO_PLCP_40MHZ; + if (plcp[0] & MIMO_PLCP_40MHZ) + rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT); + + if (fbr_iscck) /* CCK */ + rspec_fallback = + CCK_RSPEC(CCK_PHY2MAC_RATE + (txh->FragPLCPFallback[0])); + else { /* MIMO */ + rspec_fallback = RSPEC_MIMORATE; + rspec_fallback |= + txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ; + if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ) + rspec_fallback |= + (PHY_TXC1_BW_40MHZ << + RSPEC_BW_SHIFT); + } + + if (use_rts || use_cts) { + rts_rspec = + wlc_rspec_to_rts_rspec(wlc, rspec, false, + mimo_ctlchbw); + rts_rspec_fallback = + wlc_rspec_to_rts_rspec(wlc, rspec_fallback, + false, mimo_ctlchbw); + } + } + + /* if (first mpdu for host agg) */ + /* test whether to add more */ + if ((MCS_RATE(mcs, true, false) >= f->dmaxferrate) && + (count == f->mcs2ampdu_table[mcs])) { + WL_AMPDU_ERR("wl%d: PR 37644: stopping ampdu at %d for mcs %d\n", + wlc->pub->unit, count, mcs); + break; + } + + if (count == scb_ampdu->max_pdu) { + WL_NONE("Stop taking from q, reached %d deep\n", + scb_ampdu->max_pdu); + break; + } + + /* check to see if the next pkt is a candidate for aggregation */ + p = pktq_ppeek(&qi->q, prec); + tx_info = IEEE80211_SKB_CB(p); /* tx_info must be checked with current p */ + + if (p) { + if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && + ((u8) (p->priority) == tid)) { + + plen = + pkttotlen(osh, p) + AMPDU_MAX_MPDU_OVERHEAD; + plen = max(scb_ampdu->min_len, plen); + + if ((plen + ampdu_len) > maxlen) { + p = NULL; + WL_ERROR("%s: Bogus plen #1\n", + __func__); + ASSERT(3 == 4); + continue; + } + + /* check if there are enough descriptors available */ + if (TXAVAIL(wlc, fifo) <= (seg_cnt + 1)) { + WL_ERROR("%s: No fifo space !!!!!!\n", + __func__); + p = NULL; + continue; + } + p = pktq_pdeq(&qi->q, prec); + ASSERT(p); + } else { + p = NULL; + } + } + } /* end while(p) */ + + ini->tx_in_transit += count; + + if (count) { + WLCNTADD(ampdu->cnt->txmpdu, count); + + /* patch up the last txh */ + txh = (d11txh_t *) pkt[count - 1]->data; + mcl = ltoh16(txh->MacTxControlLow); + mcl &= ~TXC_AMPDU_MASK; + mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT); + txh->MacTxControlLow = htol16(mcl); + + /* remove the null delimiter after last mpdu */ + ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; + txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0; + ampdu_len -= ndelim * AMPDU_DELIMITER_LEN; + + /* remove the pad len from last mpdu */ + fbr_iscck = ((ltoh16(txh->XtraFrameTypes) & 0x3) == 0); + len = fbr_iscck ? WLC_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) + : WLC_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); + ampdu_len -= roundup(len, 4) - len; + + /* patch up the first txh & plcp */ + txh = (d11txh_t *) pkt[0]->data; + plcp = (u8 *) (txh + 1); + + WLC_SET_MIMO_PLCP_LEN(plcp, ampdu_len); + /* mark plcp to indicate ampdu */ + WLC_SET_MIMO_PLCP_AMPDU(plcp); + + /* reset the mixed mode header durations */ + if (txh->MModeLen) { + u16 mmodelen = + wlc_calc_lsig_len(wlc, rspec, ampdu_len); + txh->MModeLen = htol16(mmodelen); + preamble_type = WLC_MM_PREAMBLE; + } + if (txh->MModeFbrLen) { + u16 mmfbrlen = + wlc_calc_lsig_len(wlc, rspec_fallback, ampdu_len); + txh->MModeFbrLen = htol16(mmfbrlen); + fbr_preamble_type = WLC_MM_PREAMBLE; + } + + /* set the preload length */ + if (MCS_RATE(mcs, true, false) >= f->dmaxferrate) { + dma_len = min(dma_len, f->ampdu_pld_size); + txh->PreloadSize = htol16(dma_len); + } else + txh->PreloadSize = 0; + + mch = ltoh16(txh->MacTxControlHigh); + + /* update RTS dur fields */ + if (use_rts || use_cts) { + u16 durid; + rts = (struct ieee80211_rts *)&txh->rts_frame; + if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) == + TXC_PREAMBLE_RTS_MAIN_SHORT) + rts_preamble_type = WLC_SHORT_PREAMBLE; + + if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) == + TXC_PREAMBLE_RTS_FB_SHORT) + rts_fbr_preamble_type = WLC_SHORT_PREAMBLE; + + durid = + wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec, + rspec, rts_preamble_type, + preamble_type, ampdu_len, + true); + rts->duration = htol16(durid); + durid = wlc_compute_rtscts_dur(wlc, use_cts, + rts_rspec_fallback, + rspec_fallback, + rts_fbr_preamble_type, + fbr_preamble_type, + ampdu_len, true); + txh->RTSDurFallback = htol16(durid); + /* set TxFesTimeNormal */ + txh->TxFesTimeNormal = rts->duration; + /* set fallback rate version of TxFesTimeNormal */ + txh->TxFesTimeFallback = txh->RTSDurFallback; + } + + /* set flag and plcp for fallback rate */ + if (fbr) { + WLCNTADD(ampdu->cnt->txfbr_mpdu, count); + WLCNTINCR(ampdu->cnt->txfbr_ampdu); + mch |= TXC_AMPDU_FBR; + txh->MacTxControlHigh = htol16(mch); + WLC_SET_MIMO_PLCP_AMPDU(plcp); + WLC_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback); + } + + WL_AMPDU_TX("wl%d: wlc_sendampdu: count %d ampdu_len %d\n", + wlc->pub->unit, count, ampdu_len); + + /* inform rate_sel if it this is a rate probe pkt */ + frameid = ltoh16(txh->TxFrameID); + if (frameid & TXFID_RATE_PROBE_MASK) { + WL_ERROR("%s: XXX what to do with TXFID_RATE_PROBE_MASK!?\n", + __func__); + } + for (i = 0; i < count; i++) + wlc_txfifo(wlc, fifo, pkt[i], i == (count - 1), + ampdu->txpkt_weight); + + } + /* endif (count) */ + return err; +} + +void BCMFASTPATH +wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, + struct sk_buff *p, tx_status_t *txs) +{ + scb_ampdu_t *scb_ampdu; + struct wlc_info *wlc = ampdu->wlc; + scb_ampdu_tid_ini_t *ini; + u32 s1 = 0, s2 = 0; + struct ieee80211_tx_info *tx_info; + + tx_info = IEEE80211_SKB_CB(p); + ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); + ASSERT(scb); + ASSERT(scb->magic == SCB_MAGIC); + ASSERT(txs->status & TX_STATUS_AMPDU); + scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); + ASSERT(scb_ampdu); + ini = SCB_AMPDU_INI(scb_ampdu, p->priority); + ASSERT(ini->scb == scb); + + /* BMAC_NOTE: For the split driver, second level txstatus comes later + * So if the ACK was received then wait for the second level else just + * call the first one + */ + if (txs->status & TX_STATUS_ACK_RCV) { + u8 status_delay = 0; + + /* wait till the next 8 bytes of txstatus is available */ + while (((s1 = + R_REG(wlc->osh, + &wlc->regs->frmtxstatus)) & TXS_V) == 0) { + udelay(1); + status_delay++; + if (status_delay > 10) { + ASSERT(status_delay <= 10); + return; + } + } + + ASSERT(!(s1 & TX_STATUS_INTERMEDIATE)); + ASSERT(s1 & TX_STATUS_AMPDU); + s2 = R_REG(wlc->osh, &wlc->regs->frmtxstatus2); + } + + wlc_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2); + wlc_ampdu_txflowcontrol(wlc, scb_ampdu, ini); +} + +void +rate_status(struct wlc_info *wlc, struct ieee80211_tx_info *tx_info, + tx_status_t *txs, u8 mcs) +{ + struct ieee80211_tx_rate *txrate = tx_info->status.rates; + int i; + + /* clear the rest of the rates */ + for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) { + txrate[i].idx = -1; + txrate[i].count = 0; + } +} + +#define SHORTNAME "AMPDU status" + +static void BCMFASTPATH +wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, + struct sk_buff *p, tx_status_t *txs, + u32 s1, u32 s2) +{ + scb_ampdu_t *scb_ampdu; + struct wlc_info *wlc = ampdu->wlc; + scb_ampdu_tid_ini_t *ini; + u8 bitmap[8], queue, tid; + d11txh_t *txh; + u8 *plcp; + struct ieee80211_hdr *h; + u16 seq, start_seq = 0, bindex, index, mcl; + u8 mcs = 0; + bool ba_recd = false, ack_recd = false; + u8 suc_mpdu = 0, tot_mpdu = 0; + uint supr_status; + bool update_rate = true, retry = true, tx_error = false; + u16 mimoantsel = 0; + u8 antselid = 0; + u8 retry_limit, rr_retry_limit; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); + +#ifdef BCMDBG + u8 hole[AMPDU_MAX_MPDU]; + memset(hole, 0, sizeof(hole)); +#endif + + ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); + ASSERT(txs->status & TX_STATUS_AMPDU); + + scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); + ASSERT(scb_ampdu); + + tid = (u8) (p->priority); + + ini = SCB_AMPDU_INI(scb_ampdu, tid); + retry_limit = ampdu->retry_limit_tid[tid]; + rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; + + ASSERT(ini->scb == scb); + + memset(bitmap, 0, sizeof(bitmap)); + queue = txs->frameid & TXFID_QUEUE_MASK; + ASSERT(queue < AC_COUNT); + + supr_status = txs->status & TX_STATUS_SUPR_MASK; + + if (txs->status & TX_STATUS_ACK_RCV) { + if (TX_STATUS_SUPR_UF == supr_status) { + update_rate = false; + } + + ASSERT(txs->status & TX_STATUS_INTERMEDIATE); + start_seq = txs->sequence >> SEQNUM_SHIFT; + bitmap[0] = (txs->status & TX_STATUS_BA_BMAP03_MASK) >> + TX_STATUS_BA_BMAP03_SHIFT; + + ASSERT(!(s1 & TX_STATUS_INTERMEDIATE)); + ASSERT(s1 & TX_STATUS_AMPDU); + + bitmap[0] |= + (s1 & TX_STATUS_BA_BMAP47_MASK) << + TX_STATUS_BA_BMAP47_SHIFT; + bitmap[1] = (s1 >> 8) & 0xff; + bitmap[2] = (s1 >> 16) & 0xff; + bitmap[3] = (s1 >> 24) & 0xff; + + bitmap[4] = s2 & 0xff; + bitmap[5] = (s2 >> 8) & 0xff; + bitmap[6] = (s2 >> 16) & 0xff; + bitmap[7] = (s2 >> 24) & 0xff; + + ba_recd = true; + } else { + WLCNTINCR(ampdu->cnt->noba); + if (supr_status) { + update_rate = false; + if (supr_status == TX_STATUS_SUPR_BADCH) { + WL_ERROR("%s: Pkt tx suppressed, illegal channel possibly %d\n", + __func__, + CHSPEC_CHANNEL(wlc->default_bss->chanspec)); + } else { + if (supr_status == TX_STATUS_SUPR_FRAG) + WL_NONE("%s: AMPDU frag err\n", + __func__); + else + WL_ERROR("%s: wlc_ampdu_dotxstatus: supr_status 0x%x\n", + __func__, supr_status); + } + /* no need to retry for badch; will fail again */ + if (supr_status == TX_STATUS_SUPR_BADCH || + supr_status == TX_STATUS_SUPR_EXPTIME) { + retry = false; + WLCNTINCR(wlc->pub->_cnt->txchanrej); + } else if (supr_status == TX_STATUS_SUPR_EXPTIME) { + + WLCNTINCR(wlc->pub->_cnt->txexptime); + + /* TX underflow : try tuning pre-loading or ampdu size */ + } else if (supr_status == TX_STATUS_SUPR_FRAG) { + /* if there were underflows, but pre-loading is not active, + notify rate adaptation. + */ + if (wlc_ffpld_check_txfunfl(wlc, prio2fifo[tid]) + > 0) { + tx_error = true; + } + } + } else if (txs->phyerr) { + update_rate = false; + WLCNTINCR(wlc->pub->_cnt->txphyerr); + WL_ERROR("wl%d: wlc_ampdu_dotxstatus: tx phy error (0x%x)\n", + wlc->pub->unit, txs->phyerr); + +#ifdef BCMDBG + if (WL_ERROR_ON()) { + prpkt("txpkt (AMPDU)", wlc->osh, p); + wlc_print_txdesc((d11txh_t *) p->data); + wlc_print_txstatus(txs); + } +#endif /* BCMDBG */ + } + } + + /* loop through all pkts and retry if not acked */ + while (p) { + tx_info = IEEE80211_SKB_CB(p); + ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); + txh = (d11txh_t *) p->data; + mcl = ltoh16(txh->MacTxControlLow); + plcp = (u8 *) (txh + 1); + h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); + seq = ltoh16(h->seq_ctrl) >> SEQNUM_SHIFT; + + if (tot_mpdu == 0) { + mcs = plcp[0] & MIMO_PLCP_MCS_MASK; + mimoantsel = ltoh16(txh->ABI_MimoAntSel); + } + + index = TX_SEQ_TO_INDEX(seq); + ack_recd = false; + if (ba_recd) { + bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); + + WL_AMPDU_TX("%s: tid %d seq is %d, start_seq is %d, bindex is %d set %d, index %d\n", + __func__, tid, seq, start_seq, bindex, + isset(bitmap, bindex), index); + + /* if acked then clear bit and free packet */ + if ((bindex < AMPDU_TX_BA_MAX_WSIZE) + && isset(bitmap, bindex)) { + ini->tx_in_transit--; + ini->txretry[index] = 0; + + /* ampdu_ack_len: number of acked aggregated frames */ + /* ampdu_ack_map: block ack bit map for the aggregation */ + /* ampdu_len: number of aggregated frames */ + rate_status(wlc, tx_info, txs, mcs); + tx_info->flags |= IEEE80211_TX_STAT_ACK; + tx_info->flags |= IEEE80211_TX_STAT_AMPDU; + + /* XXX TODO: Make these accurate. */ + tx_info->status.ampdu_ack_len = + (txs-> + status & TX_STATUS_FRM_RTX_MASK) >> + TX_STATUS_FRM_RTX_SHIFT; + tx_info->status.ampdu_len = + (txs-> + status & TX_STATUS_FRM_RTX_MASK) >> + TX_STATUS_FRM_RTX_SHIFT; + + skb_pull(p, D11_PHY_HDR_LEN); + skb_pull(p, D11_TXH_LEN); + + ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, + p); + ack_recd = true; + suc_mpdu++; + } + } + /* either retransmit or send bar if ack not recd */ + if (!ack_recd) { + struct ieee80211_tx_rate *txrate = + tx_info->status.rates; + if (retry && (txrate[0].count < (int)retry_limit)) { + ini->txretry[index]++; + ini->tx_in_transit--; + /* Use high prededence for retransmit to give some punch */ + /* wlc_txq_enq(wlc, scb, p, WLC_PRIO_TO_PREC(tid)); */ + wlc_txq_enq(wlc, scb, p, + WLC_PRIO_TO_HI_PREC(tid)); + } else { + /* Retry timeout */ + ini->tx_in_transit--; + ieee80211_tx_info_clear_status(tx_info); + tx_info->flags |= + IEEE80211_TX_STAT_AMPDU_NO_BACK; + skb_pull(p, D11_PHY_HDR_LEN); + skb_pull(p, D11_TXH_LEN); + WL_ERROR("%s: BA Timeout, seq %d, in_transit %d\n", + SHORTNAME, seq, ini->tx_in_transit); + ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, + p); + } + } + tot_mpdu++; + + /* break out if last packet of ampdu */ + if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) == + TXC_AMPDU_LAST) + break; + + p = GETNEXTTXP(wlc, queue); + if (p == NULL) { + ASSERT(p); + break; + } + } + wlc_send_q(wlc, wlc->active_queue); + + /* update rate state */ + if (WLANTSEL_ENAB(wlc)) + antselid = wlc_antsel_antsel2id(wlc->asi, mimoantsel); + + wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight); +} + +static void +ampdu_cleanup_tid_ini(struct ampdu_info *ampdu, scb_ampdu_t *scb_ampdu, u8 tid, + bool force) +{ + scb_ampdu_tid_ini_t *ini; + ini = SCB_AMPDU_INI(scb_ampdu, tid); + if (!ini) + return; + + WL_AMPDU_CTL("wl%d: ampdu_cleanup_tid_ini: tid %d\n", + ampdu->wlc->pub->unit, tid); + + if (ini->tx_in_transit && !force) + return; + + scb_ampdu = SCB_AMPDU_CUBBY(ampdu, ini->scb); + ASSERT(ini == &scb_ampdu->ini[ini->tid]); + + /* free all buffered tx packets */ + pktq_pflush(ampdu->wlc->osh, &scb_ampdu->txq, ini->tid, true, NULL, 0); +} + +/* initialize the initiator code for tid */ +static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu, + scb_ampdu_t *scb_ampdu, + u8 tid, bool override) +{ + scb_ampdu_tid_ini_t *ini; + + ASSERT(scb_ampdu); + ASSERT(scb_ampdu->scb); + ASSERT(SCB_AMPDU(scb_ampdu->scb)); + ASSERT(tid < AMPDU_MAX_SCB_TID); + + /* check for per-tid control of ampdu */ + if (!ampdu->ini_enable[tid]) { + WL_ERROR("%s: Rejecting tid %d\n", __func__, tid); + return NULL; + } + + ini = SCB_AMPDU_INI(scb_ampdu, tid); + ini->tid = tid; + ini->scb = scb_ampdu->scb; + ini->magic = INI_MAGIC; + WLCNTINCR(ampdu->cnt->txaddbareq); + + return ini; +} + +int wlc_ampdu_set(struct ampdu_info *ampdu, bool on) +{ + struct wlc_info *wlc = ampdu->wlc; + + wlc->pub->_ampdu = false; + + if (on) { + if (!N_ENAB(wlc->pub)) { + WL_AMPDU_ERR("wl%d: driver not nmode enabled\n", + wlc->pub->unit); + return BCME_UNSUPPORTED; + } + if (!wlc_ampdu_cap(ampdu)) { + WL_AMPDU_ERR("wl%d: device not ampdu capable\n", + wlc->pub->unit); + return BCME_UNSUPPORTED; + } + wlc->pub->_ampdu = on; + } + + return 0; +} + +bool wlc_ampdu_cap(struct ampdu_info *ampdu) +{ + if (WLC_PHY_11N_CAP(ampdu->wlc->band)) + return true; + else + return false; +} + +static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur) +{ + u32 rate, mcs; + + for (mcs = 0; mcs < MCS_TABLE_SIZE; mcs++) { + /* rate is in Kbps; dur is in msec ==> len = (rate * dur) / 8 */ + /* 20MHz, No SGI */ + rate = MCS_RATE(mcs, false, false); + ampdu->max_txlen[mcs][0][0] = (rate * dur) >> 3; + /* 40 MHz, No SGI */ + rate = MCS_RATE(mcs, true, false); + ampdu->max_txlen[mcs][1][0] = (rate * dur) >> 3; + /* 20MHz, SGI */ + rate = MCS_RATE(mcs, false, true); + ampdu->max_txlen[mcs][0][1] = (rate * dur) >> 3; + /* 40 MHz, SGI */ + rate = MCS_RATE(mcs, true, true); + ampdu->max_txlen[mcs][1][1] = (rate * dur) >> 3; + } +} + +u8 BCMFASTPATH +wlc_ampdu_null_delim_cnt(struct ampdu_info *ampdu, struct scb *scb, + ratespec_t rspec, int phylen) +{ + scb_ampdu_t *scb_ampdu; + int bytes, cnt, tmp; + u8 tx_density; + + ASSERT(scb); + ASSERT(SCB_AMPDU(scb)); + + scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); + ASSERT(scb_ampdu); + + if (scb_ampdu->mpdu_density == 0) + return 0; + + /* RSPEC2RATE is in kbps units ==> ~RSPEC2RATE/2^13 is in bytes/usec + density x is in 2^(x-4) usec + ==> # of bytes needed for req density = rate/2^(17-x) + ==> # of null delimiters = ceil(ceil(rate/2^(17-x)) - phylen)/4) + */ + + tx_density = scb_ampdu->mpdu_density; + + ASSERT(tx_density <= AMPDU_MAX_MPDU_DENSITY); + tmp = 1 << (17 - tx_density); + bytes = CEIL(RSPEC2RATE(rspec), tmp); + + if (bytes > phylen) { + cnt = CEIL(bytes - phylen, AMPDU_DELIMITER_LEN); + ASSERT(cnt <= 255); + return (u8) cnt; + } else + return 0; +} + +void wlc_ampdu_macaddr_upd(struct wlc_info *wlc) +{ + char template[T_RAM_ACCESS_SZ * 2]; + + /* driver needs to write the ta in the template; ta is at offset 16 */ + memset(template, 0, sizeof(template)); + bcopy((char *)wlc->pub->cur_etheraddr, template, ETH_ALEN); + wlc_write_template_ram(wlc, (T_BA_TPL_BASE + 16), (T_RAM_ACCESS_SZ * 2), + template); +} + +bool wlc_aggregatable(struct wlc_info *wlc, u8 tid) +{ + return wlc->ampdu->ini_enable[tid]; +} + +void wlc_ampdu_shm_upd(struct ampdu_info *ampdu) +{ + struct wlc_info *wlc = ampdu->wlc; + + /* Extend ucode internal watchdog timer to match larger received frames */ + if ((ampdu->rx_factor & HT_PARAMS_RX_FACTOR_MASK) == + AMPDU_RX_FACTOR_64K) { + wlc_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX); + wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX); + } else { + wlc_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_DEF); + wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF); + } +} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h new file mode 100644 index 000000000000..03457f63f2ab --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_ampdu_h_ +#define _wlc_ampdu_h_ + +extern struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc); +extern void wlc_ampdu_detach(struct ampdu_info *ampdu); +extern bool wlc_ampdu_cap(struct ampdu_info *ampdu); +extern int wlc_ampdu_set(struct ampdu_info *ampdu, bool on); +extern int wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, + struct sk_buff **aggp, int prec); +extern void wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, + struct sk_buff *p, tx_status_t *txs); +extern void wlc_ampdu_reset(struct ampdu_info *ampdu); +extern void wlc_ampdu_macaddr_upd(struct wlc_info *wlc); +extern void wlc_ampdu_shm_upd(struct ampdu_info *ampdu); + +extern u8 wlc_ampdu_null_delim_cnt(struct ampdu_info *ampdu, struct scb *scb, + ratespec_t rspec, int phylen); +extern void scb_ampdu_cleanup(struct ampdu_info *ampdu, struct scb *scb); + +#endif /* _wlc_ampdu_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c new file mode 100644 index 000000000000..402ddf8f3371 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#ifdef WLANTSEL + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* useful macros */ +#define WLC_ANTSEL_11N_0(ant) ((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf) +#define WLC_ANTSEL_11N_1(ant) (((ant) & ANT_SELCFG_MASK) & 0xf) +#define WLC_ANTIDX_11N(ant) (((WLC_ANTSEL_11N_0(ant)) << 2) + (WLC_ANTSEL_11N_1(ant))) +#define WLC_ANT_ISAUTO_11N(ant) (((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) +#define WLC_ANTSEL_11N(ant) ((ant) & ANT_SELCFG_MASK) + +/* antenna switch */ +/* defines for no boardlevel antenna diversity */ +#define ANT_SELCFG_DEF_2x2 0x01 /* default antenna configuration */ + +/* 2x3 antdiv defines and tables for GPIO communication */ +#define ANT_SELCFG_NUM_2x3 3 +#define ANT_SELCFG_DEF_2x3 0x01 /* default antenna configuration */ + +/* 2x4 antdiv rev4 defines and tables for GPIO communication */ +#define ANT_SELCFG_NUM_2x4 4 +#define ANT_SELCFG_DEF_2x4 0x02 /* default antenna configuration */ + +/* static functions */ +static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel); +static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id); +static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg); +static void wlc_antsel_init_cfg(struct antsel_info *asi, + wlc_antselcfg_t *antsel, + bool auto_sel); + +const u16 mimo_2x4_div_antselpat_tbl[] = { + 0, 0, 0x9, 0xa, /* ant0: 0 ant1: 2,3 */ + 0, 0, 0x5, 0x6, /* ant0: 1 ant1: 2,3 */ + 0, 0, 0, 0, /* n.a. */ + 0, 0, 0, 0 /* n.a. */ +}; + +const u8 mimo_2x4_div_antselid_tbl[16] = { + 0, 0, 0, 0, 0, 2, 3, 0, + 0, 0, 1, 0, 0, 0, 0, 0 /* pat to antselid */ +}; + +const u16 mimo_2x3_div_antselpat_tbl[] = { + 16, 0, 1, 16, /* ant0: 0 ant1: 1,2 */ + 16, 16, 16, 16, /* n.a. */ + 16, 2, 16, 16, /* ant0: 2 ant1: 1 */ + 16, 16, 16, 16 /* n.a. */ +}; + +const u8 mimo_2x3_div_antselid_tbl[16] = { + 0, 1, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 /* pat to antselid */ +}; + +struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc, + struct osl_info *osh, + struct wlc_pub *pub, + struct wlc_hw_info *wlc_hw) { + struct antsel_info *asi; + + asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC); + if (!asi) { + WL_ERROR("wl%d: wlc_antsel_attach: out of mem\n", pub->unit); + return NULL; + } + + asi->wlc = wlc; + asi->pub = pub; + asi->antsel_type = ANTSEL_NA; + asi->antsel_avail = false; + asi->antsel_antswitch = (u8) getintvar(asi->pub->vars, "antswitch"); + + if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) { + switch (asi->antsel_antswitch) { + case ANTSWITCH_TYPE_1: + case ANTSWITCH_TYPE_2: + case ANTSWITCH_TYPE_3: + /* 4321/2 board with 2x3 switch logic */ + asi->antsel_type = ANTSEL_2x3; + /* Antenna selection availability */ + if (((u16) getintvar(asi->pub->vars, "aa2g") == 7) || + ((u16) getintvar(asi->pub->vars, "aa5g") == 7)) { + asi->antsel_avail = true; + } else + if (((u16) getintvar(asi->pub->vars, "aa2g") == + 3) + || ((u16) getintvar(asi->pub->vars, "aa5g") + == 3)) { + asi->antsel_avail = false; + } else { + asi->antsel_avail = false; + WL_ERROR("wlc_antsel_attach: 2o3 board cfg invalid\n"); + ASSERT(0); + } + break; + default: + break; + } + } else if ((asi->pub->sromrev == 4) && + ((u16) getintvar(asi->pub->vars, "aa2g") == 7) && + ((u16) getintvar(asi->pub->vars, "aa5g") == 0)) { + /* hack to match old 4321CB2 cards with 2of3 antenna switch */ + asi->antsel_type = ANTSEL_2x3; + asi->antsel_avail = true; + } else if (asi->pub->boardflags2 & BFL2_2X4_DIV) { + asi->antsel_type = ANTSEL_2x4; + asi->antsel_avail = true; + } + + /* Set the antenna selection type for the low driver */ + wlc_bmac_antsel_type_set(wlc_hw, asi->antsel_type); + + /* Init (auto/manual) antenna selection */ + wlc_antsel_init_cfg(asi, &asi->antcfg_11n, true); + wlc_antsel_init_cfg(asi, &asi->antcfg_cur, true); + + return asi; +} + +void wlc_antsel_detach(struct antsel_info *asi) +{ + if (!asi) + return; + + kfree(asi); +} + +void wlc_antsel_init(struct antsel_info *asi) +{ + if ((asi->antsel_type == ANTSEL_2x3) || + (asi->antsel_type == ANTSEL_2x4)) + wlc_antsel_cfgupd(asi, &asi->antcfg_11n); +} + +/* boardlevel antenna selection: init antenna selection structure */ +static void +wlc_antsel_init_cfg(struct antsel_info *asi, wlc_antselcfg_t *antsel, + bool auto_sel) +{ + if (asi->antsel_type == ANTSEL_2x3) { + u8 antcfg_def = ANT_SELCFG_DEF_2x3 | + ((asi->antsel_avail && auto_sel) ? ANT_SELCFG_AUTO : 0); + antsel->ant_config[ANT_SELCFG_TX_DEF] = antcfg_def; + antsel->ant_config[ANT_SELCFG_TX_UNICAST] = antcfg_def; + antsel->ant_config[ANT_SELCFG_RX_DEF] = antcfg_def; + antsel->ant_config[ANT_SELCFG_RX_UNICAST] = antcfg_def; + antsel->num_antcfg = ANT_SELCFG_NUM_2x3; + + } else if (asi->antsel_type == ANTSEL_2x4) { + + antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x4; + antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x4; + antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x4; + antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x4; + antsel->num_antcfg = ANT_SELCFG_NUM_2x4; + + } else { /* no antenna selection available */ + + antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x2; + antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x2; + antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x2; + antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x2; + antsel->num_antcfg = 0; + } +} + +void BCMFASTPATH +wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel, + u8 antselid, u8 fbantselid, u8 *antcfg, + u8 *fbantcfg) +{ + u8 ant; + + /* if use default, assign it and return */ + if (usedef) { + *antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_DEF]; + *fbantcfg = *antcfg; + return; + } + + if (!sel) { + *antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST]; + *fbantcfg = *antcfg; + + } else { + ant = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST]; + if ((ant & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) { + *antcfg = wlc_antsel_id2antcfg(asi, antselid); + *fbantcfg = wlc_antsel_id2antcfg(asi, fbantselid); + } else { + *antcfg = + asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST]; + *fbantcfg = *antcfg; + } + } + return; +} + +/* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */ +u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel) +{ + u8 antselid = 0; + + if (asi->antsel_type == ANTSEL_2x4) { + /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */ + antselid = mimo_2x4_div_antselid_tbl[(antsel & 0xf)]; + return antselid; + + } else if (asi->antsel_type == ANTSEL_2x3) { + /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */ + antselid = mimo_2x3_div_antselid_tbl[(antsel & 0xf)]; + return antselid; + } + + return antselid; +} + +/* boardlevel antenna selection: convert id to ant_cfg */ +static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id) +{ + u8 antcfg = ANT_SELCFG_DEF_2x2; + + if (asi->antsel_type == ANTSEL_2x4) { + /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */ + antcfg = (((id & 0x2) << 3) | ((id & 0x1) + 2)); + return antcfg; + + } else if (asi->antsel_type == ANTSEL_2x3) { + /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */ + antcfg = (((id & 0x02) << 4) | ((id & 0x1) + 1)); + return antcfg; + } + + return antcfg; +} + +/* boardlevel antenna selection: convert ant_cfg to mimo_antsel (ucode interface) */ +static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg) +{ + u8 idx = WLC_ANTIDX_11N(WLC_ANTSEL_11N(ant_cfg)); + u16 mimo_antsel = 0; + + if (asi->antsel_type == ANTSEL_2x4) { + /* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */ + mimo_antsel = (mimo_2x4_div_antselpat_tbl[idx] & 0xf); + return mimo_antsel; + + } else if (asi->antsel_type == ANTSEL_2x3) { + /* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */ + mimo_antsel = (mimo_2x3_div_antselpat_tbl[idx] & 0xf); + return mimo_antsel; + } + + return mimo_antsel; +} + +/* boardlevel antenna selection: ucode interface control */ +static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel) +{ + struct wlc_info *wlc = asi->wlc; + u8 ant_cfg; + u16 mimo_antsel; + + ASSERT(asi->antsel_type != ANTSEL_NA); + + /* 1) Update TX antconfig for all frames that are not unicast data + * (aka default TX) + */ + ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF]; + mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg); + wlc_write_shm(wlc, M_MIMO_ANTSEL_TXDFLT, mimo_antsel); + /* Update driver stats for currently selected default tx/rx antenna config */ + asi->antcfg_cur.ant_config[ANT_SELCFG_TX_DEF] = ant_cfg; + + /* 2) Update RX antconfig for all frames that are not unicast data + * (aka default RX) + */ + ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF]; + mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg); + wlc_write_shm(wlc, M_MIMO_ANTSEL_RXDFLT, mimo_antsel); + /* Update driver stats for currently selected default tx/rx antenna config */ + asi->antcfg_cur.ant_config[ANT_SELCFG_RX_DEF] = ant_cfg; + + return 0; +} + +#endif /* WLANTSEL */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.h b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.h new file mode 100644 index 000000000000..8875b5848665 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_antsel_h_ +#define _wlc_antsel_h_ +extern struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc, + struct osl_info *osh, + struct wlc_pub *pub, + struct wlc_hw_info *wlc_hw); +extern void wlc_antsel_detach(struct antsel_info *asi); +extern void wlc_antsel_init(struct antsel_info *asi); +extern void wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, + bool sel, + u8 id, u8 fbid, u8 *antcfg, + u8 *fbantcfg); +extern u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel); +#endif /* _wlc_antsel_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c new file mode 100644 index 000000000000..e22ce1f79660 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -0,0 +1,4235 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* BMAC_NOTE: a WLC_HIGH compile include of wlc.h adds in more structures and type + * dependencies. Need to include these to files to allow a clean include of wlc.h + * with WLC_HIGH defined. + * At some point we may be able to skip the include of wlc.h and instead just + * define a stub wlc_info and band struct to allow rpc calls to get the rpc handle. + */ +#include +#include +#include +#include +#include +#include +#include "wl_ucode.h" +#include "d11ucode_ext.h" +#include + +/* BMAC_NOTE: With WLC_HIGH defined, some fns in this file make calls to high level + * functions defined in the headers below. We should be eliminating those calls and + * will be able to delete these include lines. + */ +#include + +#include + +#include +#include + +#define TIMER_INTERVAL_WATCHDOG_BMAC 1000 /* watchdog timer, in unit of ms */ + +#define SYNTHPU_DLY_APHY_US 3700 /* a phy synthpu_dly time in us */ +#define SYNTHPU_DLY_BPHY_US 1050 /* b/g phy synthpu_dly time in us, default */ +#define SYNTHPU_DLY_NPHY_US 2048 /* n phy REV3 synthpu_dly time in us, default */ +#define SYNTHPU_DLY_LPPHY_US 300 /* lpphy synthpu_dly time in us */ + +#define SYNTHPU_DLY_PHY_US_QT 100 /* QT synthpu_dly time in us */ + +#ifndef BMAC_DUP_TO_REMOVE +#define WLC_RM_WAIT_TX_SUSPEND 4 /* Wait Tx Suspend */ + +#define ANTCNT 10 /* vanilla M_MAX_ANTCNT value */ + +#endif /* BMAC_DUP_TO_REMOVE */ + +#define DMAREG(wlc_hw, direction, fifonum) (D11REV_LT(wlc_hw->corerev, 11) ? \ + ((direction == DMA_TX) ? \ + (void *)&(wlc_hw->regs->fifo.f32regs.dmaregs[fifonum].xmt) : \ + (void *)&(wlc_hw->regs->fifo.f32regs.dmaregs[fifonum].rcv)) : \ + ((direction == DMA_TX) ? \ + (void *)&(wlc_hw->regs->fifo.f64regs[fifonum].dmaxmt) : \ + (void *)&(wlc_hw->regs->fifo.f64regs[fifonum].dmarcv))) + +/* + * The following table lists the buffer memory allocated to xmt fifos in HW. + * the size is in units of 256bytes(one block), total size is HW dependent + * ucode has default fifo partition, sw can overwrite if necessary + * + * This is documented in twiki under the topic UcodeTxFifo. Please ensure + * the twiki is updated before making changes. + */ + +#define XMTFIFOTBL_STARTREV 20 /* Starting corerev for the fifo size table */ + +static u16 xmtfifo_sz[][NFIFO] = { + {20, 192, 192, 21, 17, 5}, /* corerev 20: 5120, 49152, 49152, 5376, 4352, 1280 */ + {9, 58, 22, 14, 14, 5}, /* corerev 21: 2304, 14848, 5632, 3584, 3584, 1280 */ + {20, 192, 192, 21, 17, 5}, /* corerev 22: 5120, 49152, 49152, 5376, 4352, 1280 */ + {20, 192, 192, 21, 17, 5}, /* corerev 23: 5120, 49152, 49152, 5376, 4352, 1280 */ + {9, 58, 22, 14, 14, 5}, /* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */ +}; + +static void wlc_clkctl_clk(struct wlc_hw_info *wlc, uint mode); +static void wlc_coreinit(struct wlc_info *wlc); + +/* used by wlc_wakeucode_init() */ +static void wlc_write_inits(struct wlc_hw_info *wlc_hw, const d11init_t *inits); +static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[], + const uint nbytes); +static void wlc_ucode_download(struct wlc_hw_info *wlc); +static void wlc_ucode_txant_set(struct wlc_hw_info *wlc_hw); + +/* used by wlc_dpc() */ +static bool wlc_bmac_dotxstatus(struct wlc_hw_info *wlc, tx_status_t *txs, + u32 s2); +static bool wlc_bmac_txstatus_corerev4(struct wlc_hw_info *wlc); +static bool wlc_bmac_txstatus(struct wlc_hw_info *wlc, bool bound, bool *fatal); +static bool wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound); + +/* used by wlc_down() */ +static void wlc_flushqueues(struct wlc_info *wlc); + +static void wlc_write_mhf(struct wlc_hw_info *wlc_hw, u16 *mhfs); +static void wlc_mctrl_reset(struct wlc_hw_info *wlc_hw); +static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw); + +/* Low Level Prototypes */ +static u16 wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, + u32 sel); +static void wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset, + u16 v, u32 sel); +static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme); +static void wlc_bmac_detach_dmapio(struct wlc_hw_info *wlc_hw); +static void wlc_ucode_bsinit(struct wlc_hw_info *wlc_hw); +static bool wlc_validboardtype(struct wlc_hw_info *wlc); +static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw); +static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw); +static void wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init); +static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw); +static void wlc_ucode_mute_override_set(struct wlc_hw_info *wlc_hw); +static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw); +static u32 wlc_wlintrsoff(struct wlc_info *wlc); +static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask); +static void wlc_gpio_init(struct wlc_info *wlc); +static void wlc_write_hw_bcntemplate0(struct wlc_hw_info *wlc_hw, void *bcn, + int len); +static void wlc_write_hw_bcntemplate1(struct wlc_hw_info *wlc_hw, void *bcn, + int len); +static void wlc_bmac_bsinit(struct wlc_info *wlc, chanspec_t chanspec); +static u32 wlc_setband_inact(struct wlc_info *wlc, uint bandunit); +static void wlc_bmac_setband(struct wlc_hw_info *wlc_hw, uint bandunit, + chanspec_t chanspec); +static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw, + bool shortslot); +static void wlc_upd_ofdm_pctl1_table(struct wlc_hw_info *wlc_hw); +static u16 wlc_bmac_ofdm_ratetable_offset(struct wlc_hw_info *wlc_hw, + u8 rate); + +/* === Low Level functions === */ + +void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot) +{ + wlc_hw->shortslot = shortslot; + + if (BAND_2G(wlc_hw->band->bandtype) && wlc_hw->up) { + wlc_suspend_mac_and_wait(wlc_hw->wlc); + wlc_bmac_update_slot_timing(wlc_hw, shortslot); + wlc_enable_mac(wlc_hw->wlc); + } +} + +/* + * Update the slot timing for standard 11b/g (20us slots) + * or shortslot 11g (9us slots) + * The PSM needs to be suspended for this call. + */ +static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw, + bool shortslot) +{ + struct osl_info *osh; + d11regs_t *regs; + + osh = wlc_hw->osh; + regs = wlc_hw->regs; + + if (shortslot) { + /* 11g short slot: 11a timing */ + W_REG(osh, ®s->ifs_slot, 0x0207); /* APHY_SLOT_TIME */ + wlc_bmac_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME); + } else { + /* 11g long slot: 11b timing */ + W_REG(osh, ®s->ifs_slot, 0x0212); /* BPHY_SLOT_TIME */ + wlc_bmac_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME); + } +} + +static void WLBANDINITFN(wlc_ucode_bsinit) (struct wlc_hw_info *wlc_hw) +{ + /* init microcode host flags */ + wlc_write_mhf(wlc_hw, wlc_hw->band->mhfs); + + /* do band-specific ucode IHR, SHM, and SCR inits */ + if (D11REV_IS(wlc_hw->corerev, 23)) { + if (WLCISNPHY(wlc_hw->band)) { + wlc_write_inits(wlc_hw, d11n0bsinitvals16); + } else { + WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); + } + } else { + if (D11REV_IS(wlc_hw->corerev, 24)) { + if (WLCISLCNPHY(wlc_hw->band)) { + wlc_write_inits(wlc_hw, d11lcn0bsinitvals24); + } else + WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", + __func__, wlc_hw->unit, + wlc_hw->corerev); + } else { + WL_ERROR("%s: wl%d: unsupported corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); + } + } +} + +/* switch to new band but leave it inactive */ +static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + u32 macintmask; + u32 tmp; + + WL_TRACE("wl%d: wlc_setband_inact\n", wlc_hw->unit); + + ASSERT(bandunit != wlc_hw->band->bandunit); + ASSERT(si_iscoreup(wlc_hw->sih)); + ASSERT((R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol) & MCTL_EN_MAC) == + 0); + + /* disable interrupts */ + macintmask = wl_intrsoff(wlc->wl); + + /* radio off */ + wlc_phy_switch_radio(wlc_hw->band->pi, OFF); + + ASSERT(wlc_hw->clk); + + if (D11REV_LT(wlc_hw->corerev, 17)) + tmp = R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol); + + wlc_bmac_core_phy_clk(wlc_hw, OFF); + + wlc_setxband(wlc_hw, bandunit); + + return macintmask; +} + +/* Process received frames */ +/* + * Return true if more frames need to be processed. false otherwise. + * Param 'bound' indicates max. # frames to process before break out. + */ +static bool BCMFASTPATH +wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound) +{ + struct sk_buff *p; + struct sk_buff *head = NULL; + struct sk_buff *tail = NULL; + uint n = 0; + uint bound_limit = bound ? wlc_hw->wlc->pub->tunables->rxbnd : -1; + u32 tsf_h, tsf_l; + wlc_d11rxhdr_t *wlc_rxhdr = NULL; + + WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); + /* gather received frames */ + while ((p = dma_rx(wlc_hw->di[fifo]))) { + + if (!tail) + head = tail = p; + else { + tail->prev = p; + tail = p; + } + + /* !give others some time to run! */ + if (++n >= bound_limit) + break; + } + + /* get the TSF REG reading */ + wlc_bmac_read_tsf(wlc_hw, &tsf_l, &tsf_h); + + /* post more rbufs */ + dma_rxfill(wlc_hw->di[fifo]); + + /* process each frame */ + while ((p = head) != NULL) { + head = head->prev; + p->prev = NULL; + + /* record the tsf_l in wlc_rxd11hdr */ + wlc_rxhdr = (wlc_d11rxhdr_t *) p->data; + wlc_rxhdr->tsf_l = htol32(tsf_l); + + /* compute the RSSI from d11rxhdr and record it in wlc_rxd11hr */ + wlc_phy_rssi_compute(wlc_hw->band->pi, wlc_rxhdr); + + wlc_recv(wlc_hw->wlc, p); + } + + return n >= bound_limit; +} + +/* second-level interrupt processing + * Return true if another dpc needs to be re-scheduled. false otherwise. + * Param 'bounded' indicates if applicable loops should be bounded. + */ +bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) +{ + u32 macintstatus; + struct wlc_hw_info *wlc_hw = wlc->hw; + d11regs_t *regs = wlc_hw->regs; + bool fatal = false; + + if (DEVICEREMOVED(wlc)) { + WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); + wl_down(wlc->wl); + return false; + } + + /* grab and clear the saved software intstatus bits */ + macintstatus = wlc->macintstatus; + wlc->macintstatus = 0; + + WL_TRACE("wl%d: wlc_dpc: macintstatus 0x%x\n", + wlc_hw->unit, macintstatus); + + if (macintstatus & MI_PRQ) { + /* Process probe request FIFO */ + ASSERT(0 && "PRQ Interrupt in non-MBSS"); + } + + /* BCN template is available */ + /* ZZZ: Use AP_ACTIVE ? */ + if (AP_ENAB(wlc->pub) && (!APSTA_ENAB(wlc->pub) || wlc->aps_associated) + && (macintstatus & MI_BCNTPL)) { + wlc_update_beacon(wlc); + } + + /* PMQ entry addition */ + if (macintstatus & MI_PMQ) { + } + + /* tx status */ + if (macintstatus & MI_TFS) { + if (wlc_bmac_txstatus(wlc->hw, bounded, &fatal)) + wlc->macintstatus |= MI_TFS; + if (fatal) { + WL_ERROR("MI_TFS: fatal\n"); + goto fatal; + } + } + + if (macintstatus & (MI_TBTT | MI_DTIM_TBTT)) + wlc_tbtt(wlc, regs); + + /* ATIM window end */ + if (macintstatus & MI_ATIMWINEND) { + WL_TRACE("wlc_isr: end of ATIM window\n"); + + OR_REG(wlc_hw->osh, ®s->maccommand, wlc->qvalid); + wlc->qvalid = 0; + } + + /* phy tx error */ + if (macintstatus & MI_PHYTXERR) { + WLCNTINCR(wlc->pub->_cnt->txphyerr); + } + + /* received data or control frame, MI_DMAINT is indication of RX_FIFO interrupt */ + if (macintstatus & MI_DMAINT) { + if (wlc_bmac_recv(wlc_hw, RX_FIFO, bounded)) { + wlc->macintstatus |= MI_DMAINT; + } + } + + /* TX FIFO suspend/flush completion */ + if (macintstatus & MI_TXSTOP) { + if (wlc_bmac_tx_fifo_suspended(wlc_hw, TX_DATA_FIFO)) { + /* WL_ERROR("dpc: fifo_suspend_comlete\n"); */ + } + } + + /* noise sample collected */ + if (macintstatus & MI_BG_NOISE) { + wlc_phy_noise_sample_intr(wlc_hw->band->pi); + } + + if (macintstatus & MI_GP0) { + WL_ERROR("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", + wlc_hw->unit, wlc_hw->now); + + printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", + __func__, wlc_hw->sih->chip, + wlc_hw->sih->chiprev); + + WLCNTINCR(wlc->pub->_cnt->psmwds); + + /* big hammer */ + wl_init(wlc->wl); + } + + /* gptimer timeout */ + if (macintstatus & MI_TO) { + W_REG(wlc_hw->osh, ®s->gptimer, 0); + } + + if (macintstatus & MI_RFDISABLE) { +#if defined(BCMDBG) + u32 rfd = R_REG(wlc_hw->osh, ®s->phydebug) & PDBG_RFD; +#endif + + WL_ERROR("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n", + wlc_hw->unit, rfd); + + WLCNTINCR(wlc->pub->_cnt->rfdisable); + } + + /* send any enq'd tx packets. Just makes sure to jump start tx */ + if (!pktq_empty(&wlc->active_queue->q)) + wlc_send_q(wlc, wlc->active_queue); + + ASSERT(wlc_ps_check(wlc)); + + /* make sure the bound indication and the implementation are in sync */ + ASSERT(bounded == true || wlc->macintstatus == 0); + + /* it isn't done and needs to be resched if macintstatus is non-zero */ + return wlc->macintstatus != 0; + + fatal: + wl_init(wlc->wl); + return wlc->macintstatus != 0; +} + +/* common low-level watchdog code */ +void wlc_bmac_watchdog(void *arg) +{ + struct wlc_info *wlc = (struct wlc_info *) arg; + struct wlc_hw_info *wlc_hw = wlc->hw; + + WL_TRACE("wl%d: wlc_bmac_watchdog\n", wlc_hw->unit); + + if (!wlc_hw->up) + return; + + /* increment second count */ + wlc_hw->now++; + + /* Check for FIFO error interrupts */ + wlc_bmac_fifoerrors(wlc_hw); + + /* make sure RX dma has buffers */ + dma_rxfill(wlc->hw->di[RX_FIFO]); + if (D11REV_IS(wlc_hw->corerev, 4)) { + dma_rxfill(wlc->hw->di[RX_TXSTATUS_FIFO]); + } + + wlc_phy_watchdog(wlc_hw->band->pi); +} + +void +wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, + bool mute, struct txpwr_limits *txpwr) +{ + uint bandunit; + + WL_TRACE("wl%d: wlc_bmac_set_chanspec 0x%x\n", + wlc_hw->unit, chanspec); + + wlc_hw->chanspec = chanspec; + + /* Switch bands if necessary */ + if (NBANDS_HW(wlc_hw) > 1) { + bandunit = CHSPEC_WLCBANDUNIT(chanspec); + if (wlc_hw->band->bandunit != bandunit) { + /* wlc_bmac_setband disables other bandunit, + * use light band switch if not up yet + */ + if (wlc_hw->up) { + wlc_phy_chanspec_radio_set(wlc_hw-> + bandstate[bandunit]-> + pi, chanspec); + wlc_bmac_setband(wlc_hw, bandunit, chanspec); + } else { + wlc_setxband(wlc_hw, bandunit); + } + } + } + + wlc_phy_initcal_enable(wlc_hw->band->pi, !mute); + + if (!wlc_hw->up) { + if (wlc_hw->clk) + wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, + chanspec); + wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec); + } else { + wlc_phy_chanspec_set(wlc_hw->band->pi, chanspec); + wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec); + + /* Update muting of the channel */ + wlc_bmac_mute(wlc_hw, mute, 0); + } +} + +int wlc_bmac_revinfo_get(struct wlc_hw_info *wlc_hw, + wlc_bmac_revinfo_t *revinfo) +{ + si_t *sih = wlc_hw->sih; + uint idx; + + revinfo->vendorid = wlc_hw->vendorid; + revinfo->deviceid = wlc_hw->deviceid; + + revinfo->boardrev = wlc_hw->boardrev; + revinfo->corerev = wlc_hw->corerev; + revinfo->sromrev = wlc_hw->sromrev; + revinfo->chiprev = sih->chiprev; + revinfo->chip = sih->chip; + revinfo->chippkg = sih->chippkg; + revinfo->boardtype = sih->boardtype; + revinfo->boardvendor = sih->boardvendor; + revinfo->bustype = sih->bustype; + revinfo->buscoretype = sih->buscoretype; + revinfo->buscorerev = sih->buscorerev; + revinfo->issim = sih->issim; + + revinfo->nbands = NBANDS_HW(wlc_hw); + + for (idx = 0; idx < NBANDS_HW(wlc_hw); idx++) { + wlc_hwband_t *band = wlc_hw->bandstate[idx]; + revinfo->band[idx].bandunit = band->bandunit; + revinfo->band[idx].bandtype = band->bandtype; + revinfo->band[idx].phytype = band->phytype; + revinfo->band[idx].phyrev = band->phyrev; + revinfo->band[idx].radioid = band->radioid; + revinfo->band[idx].radiorev = band->radiorev; + revinfo->band[idx].abgphy_encore = band->abgphy_encore; + revinfo->band[idx].anarev = 0; + + } + return 0; +} + +int wlc_bmac_state_get(struct wlc_hw_info *wlc_hw, wlc_bmac_state_t *state) +{ + state->machwcap = wlc_hw->machwcap; + + return 0; +} + +static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) +{ + uint i; + char name[8]; + /* ucode host flag 2 needed for pio mode, independent of band and fifo */ + u16 pio_mhf2 = 0; + struct wlc_hw_info *wlc_hw = wlc->hw; + uint unit = wlc_hw->unit; + wlc_tunables_t *tune = wlc->pub->tunables; + + /* name and offsets for dma_attach */ + snprintf(name, sizeof(name), "wl%d", unit); + + if (wlc_hw->di[0] == 0) { /* Init FIFOs */ + uint addrwidth; + int dma_attach_err = 0; + struct osl_info *osh = wlc_hw->osh; + + /* Find out the DMA addressing capability and let OS know + * All the channels within one DMA core have 'common-minimum' same + * capability + */ + addrwidth = + dma_addrwidth(wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 0)); + + if (!wl_alloc_dma_resources(wlc_hw->wlc->wl, addrwidth)) { + WL_ERROR("wl%d: wlc_attach: alloc_dma_resources failed\n", + unit); + return false; + } + + /* + * FIFO 0 + * TX: TX_AC_BK_FIFO (TX AC Background data packets) + * RX: RX_FIFO (RX data packets) + */ + ASSERT(TX_AC_BK_FIFO == 0); + ASSERT(RX_FIFO == 0); + wlc_hw->di[0] = dma_attach(osh, name, wlc_hw->sih, + (wme ? DMAREG(wlc_hw, DMA_TX, 0) : + NULL), DMAREG(wlc_hw, DMA_RX, 0), + (wme ? tune->ntxd : 0), tune->nrxd, + tune->rxbufsz, -1, tune->nrxbufpost, + WL_HWRXOFF, &wl_msg_level); + dma_attach_err |= (NULL == wlc_hw->di[0]); + + /* + * FIFO 1 + * TX: TX_AC_BE_FIFO (TX AC Best-Effort data packets) + * (legacy) TX_DATA_FIFO (TX data packets) + * RX: UNUSED + */ + ASSERT(TX_AC_BE_FIFO == 1); + ASSERT(TX_DATA_FIFO == 1); + wlc_hw->di[1] = dma_attach(osh, name, wlc_hw->sih, + DMAREG(wlc_hw, DMA_TX, 1), NULL, + tune->ntxd, 0, 0, -1, 0, 0, + &wl_msg_level); + dma_attach_err |= (NULL == wlc_hw->di[1]); + + /* + * FIFO 2 + * TX: TX_AC_VI_FIFO (TX AC Video data packets) + * RX: UNUSED + */ + ASSERT(TX_AC_VI_FIFO == 2); + wlc_hw->di[2] = dma_attach(osh, name, wlc_hw->sih, + DMAREG(wlc_hw, DMA_TX, 2), NULL, + tune->ntxd, 0, 0, -1, 0, 0, + &wl_msg_level); + dma_attach_err |= (NULL == wlc_hw->di[2]); + /* + * FIFO 3 + * TX: TX_AC_VO_FIFO (TX AC Voice data packets) + * (legacy) TX_CTL_FIFO (TX control & mgmt packets) + * RX: RX_TXSTATUS_FIFO (transmit-status packets) + * for corerev < 5 only + */ + ASSERT(TX_AC_VO_FIFO == 3); + ASSERT(TX_CTL_FIFO == 3); + if (D11REV_IS(wlc_hw->corerev, 4)) { + ASSERT(RX_TXSTATUS_FIFO == 3); + wlc_hw->di[3] = dma_attach(osh, name, wlc_hw->sih, + DMAREG(wlc_hw, DMA_TX, 3), + DMAREG(wlc_hw, DMA_RX, 3), + tune->ntxd, tune->nrxd, + sizeof(tx_status_t), -1, + tune->nrxbufpost, 0, + &wl_msg_level); + dma_attach_err |= (NULL == wlc_hw->di[3]); + } else { + wlc_hw->di[3] = dma_attach(osh, name, wlc_hw->sih, + DMAREG(wlc_hw, DMA_TX, 3), + NULL, tune->ntxd, 0, 0, -1, + 0, 0, &wl_msg_level); + dma_attach_err |= (NULL == wlc_hw->di[3]); + } +/* Cleaner to leave this as if with AP defined */ + + if (dma_attach_err) { + WL_ERROR("wl%d: wlc_attach: dma_attach failed\n", unit); + return false; + } + + /* get pointer to dma engine tx flow control variable */ + for (i = 0; i < NFIFO; i++) + if (wlc_hw->di[i]) + wlc_hw->txavail[i] = + (uint *) dma_getvar(wlc_hw->di[i], + "&txavail"); + } + + /* initial ucode host flags */ + wlc_mhfdef(wlc, wlc_hw->band->mhfs, pio_mhf2); + + return true; +} + +static void wlc_bmac_detach_dmapio(struct wlc_hw_info *wlc_hw) +{ + uint j; + + for (j = 0; j < NFIFO; j++) { + if (wlc_hw->di[j]) { + dma_detach(wlc_hw->di[j]); + wlc_hw->di[j] = NULL; + } + } +} + +/* low level attach + * run backplane attach, init nvram + * run phy attach + * initialize software state for each core and band + * put the whole chip in reset(driver down state), no clock + */ +int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, + bool piomode, struct osl_info *osh, void *regsva, + uint bustype, void *btparam) +{ + struct wlc_hw_info *wlc_hw; + d11regs_t *regs; + char *macaddr = NULL; + char *vars; + uint err = 0; + uint j; + bool wme = false; + shared_phy_params_t sha_params; + + WL_TRACE("wl%d: wlc_bmac_attach: vendor 0x%x device 0x%x\n", + unit, vendor, device); + + ASSERT(sizeof(wlc_d11rxhdr_t) <= WL_HWRXOFF); + + wme = true; + + wlc_hw = wlc->hw; + wlc_hw->wlc = wlc; + wlc_hw->unit = unit; + wlc_hw->osh = osh; + wlc_hw->band = wlc_hw->bandstate[0]; + wlc_hw->_piomode = piomode; + + /* populate struct wlc_hw_info with default values */ + wlc_bmac_info_init(wlc_hw); + + /* + * Do the hardware portion of the attach. + * Also initialize software state that depends on the particular hardware + * we are running. + */ + wlc_hw->sih = si_attach((uint) device, osh, regsva, bustype, btparam, + &wlc_hw->vars, &wlc_hw->vars_size); + if (wlc_hw->sih == NULL) { + WL_ERROR("wl%d: wlc_bmac_attach: si_attach failed\n", unit); + err = 11; + goto fail; + } + vars = wlc_hw->vars; + + /* + * Get vendid/devid nvram overwrites, which could be different + * than those the BIOS recognizes for devices on PCMCIA_BUS, + * SDIO_BUS, and SROMless devices on PCI_BUS. + */ +#ifdef BCMBUSTYPE + bustype = BCMBUSTYPE; +#endif + if (bustype != SI_BUS) { + char *var; + + var = getvar(vars, "vendid"); + if (var) { + vendor = (u16) simple_strtoul(var, NULL, 0); + WL_ERROR("Overriding vendor id = 0x%x\n", vendor); + } + var = getvar(vars, "devid"); + if (var) { + u16 devid = (u16) simple_strtoul(var, NULL, 0); + if (devid != 0xffff) { + device = devid; + WL_ERROR("Overriding device id = 0x%x\n", + device); + } + } + + /* verify again the device is supported */ + if (!wlc_chipmatch(vendor, device)) { + WL_ERROR("wl%d: wlc_bmac_attach: Unsupported vendor/device (0x%x/0x%x)\n", + unit, vendor, device); + err = 12; + goto fail; + } + } + + wlc_hw->vendorid = vendor; + wlc_hw->deviceid = device; + + /* set bar0 window to point at D11 core */ + wlc_hw->regs = (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, 0); + wlc_hw->corerev = si_corerev(wlc_hw->sih); + + regs = wlc_hw->regs; + + wlc->regs = wlc_hw->regs; + + /* validate chip, chiprev and corerev */ + if (!wlc_isgoodchip(wlc_hw)) { + err = 13; + goto fail; + } + + /* initialize power control registers */ + si_clkctl_init(wlc_hw->sih); + + /* request fastclock and force fastclock for the rest of attach + * bring the d11 core out of reset. + * For PMU chips, the first wlc_clkctl_clk is no-op since core-clk is still false; + * But it will be called again inside wlc_corereset, after d11 is out of reset. + */ + wlc_clkctl_clk(wlc_hw, CLK_FAST); + wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); + + if (!wlc_bmac_validate_chip_access(wlc_hw)) { + WL_ERROR("wl%d: wlc_bmac_attach: validate_chip_access failed\n", + unit); + err = 14; + goto fail; + } + + /* get the board rev, used just below */ + j = getintvar(vars, "boardrev"); + /* promote srom boardrev of 0xFF to 1 */ + if (j == BOARDREV_PROMOTABLE) + j = BOARDREV_PROMOTED; + wlc_hw->boardrev = (u16) j; + if (!wlc_validboardtype(wlc_hw)) { + WL_ERROR("wl%d: wlc_bmac_attach: Unsupported Broadcom board type (0x%x)" " or revision level (0x%x)\n", + unit, wlc_hw->sih->boardtype, wlc_hw->boardrev); + err = 15; + goto fail; + } + wlc_hw->sromrev = (u8) getintvar(vars, "sromrev"); + wlc_hw->boardflags = (u32) getintvar(vars, "boardflags"); + wlc_hw->boardflags2 = (u32) getintvar(vars, "boardflags2"); + + if (D11REV_LE(wlc_hw->corerev, 4) + || (wlc_hw->boardflags & BFL_NOPLLDOWN)) + wlc_bmac_pllreq(wlc_hw, true, WLC_PLLREQ_SHARED); + + if ((wlc_hw->sih->bustype == PCI_BUS) + && (si_pci_war16165(wlc_hw->sih))) + wlc->war16165 = true; + + /* check device id(srom, nvram etc.) to set bands */ + if (wlc_hw->deviceid == BCM43224_D11N_ID) { + /* Dualband boards */ + wlc_hw->_nbands = 2; + } else + wlc_hw->_nbands = 1; + + if ((wlc_hw->sih->chip == BCM43225_CHIP_ID)) + wlc_hw->_nbands = 1; + + /* BMAC_NOTE: remove init of pub values when wlc_attach() unconditionally does the + * init of these values + */ + wlc->vendorid = wlc_hw->vendorid; + wlc->deviceid = wlc_hw->deviceid; + wlc->pub->sih = wlc_hw->sih; + wlc->pub->corerev = wlc_hw->corerev; + wlc->pub->sromrev = wlc_hw->sromrev; + wlc->pub->boardrev = wlc_hw->boardrev; + wlc->pub->boardflags = wlc_hw->boardflags; + wlc->pub->boardflags2 = wlc_hw->boardflags2; + wlc->pub->_nbands = wlc_hw->_nbands; + + wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc); + + if (wlc_hw->physhim == NULL) { + WL_ERROR("wl%d: wlc_bmac_attach: wlc_phy_shim_attach failed\n", + unit); + err = 25; + goto fail; + } + + /* pass all the parameters to wlc_phy_shared_attach in one struct */ + sha_params.osh = osh; + sha_params.sih = wlc_hw->sih; + sha_params.physhim = wlc_hw->physhim; + sha_params.unit = unit; + sha_params.corerev = wlc_hw->corerev; + sha_params.vars = vars; + sha_params.vid = wlc_hw->vendorid; + sha_params.did = wlc_hw->deviceid; + sha_params.chip = wlc_hw->sih->chip; + sha_params.chiprev = wlc_hw->sih->chiprev; + sha_params.chippkg = wlc_hw->sih->chippkg; + sha_params.sromrev = wlc_hw->sromrev; + sha_params.boardtype = wlc_hw->sih->boardtype; + sha_params.boardrev = wlc_hw->boardrev; + sha_params.boardvendor = wlc_hw->sih->boardvendor; + sha_params.boardflags = wlc_hw->boardflags; + sha_params.boardflags2 = wlc_hw->boardflags2; + sha_params.bustype = wlc_hw->sih->bustype; + sha_params.buscorerev = wlc_hw->sih->buscorerev; + + /* alloc and save pointer to shared phy state area */ + wlc_hw->phy_sh = wlc_phy_shared_attach(&sha_params); + if (!wlc_hw->phy_sh) { + err = 16; + goto fail; + } + + /* initialize software state for each core and band */ + for (j = 0; j < NBANDS_HW(wlc_hw); j++) { + /* + * band0 is always 2.4Ghz + * band1, if present, is 5Ghz + */ + + /* So if this is a single band 11a card, use band 1 */ + if (IS_SINGLEBAND_5G(wlc_hw->deviceid)) + j = BAND_5G_INDEX; + + wlc_setxband(wlc_hw, j); + + wlc_hw->band->bandunit = j; + wlc_hw->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G; + wlc->band->bandunit = j; + wlc->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G; + wlc->core->coreidx = si_coreidx(wlc_hw->sih); + + if (D11REV_GE(wlc_hw->corerev, 13)) { + wlc_hw->machwcap = R_REG(wlc_hw->osh, ®s->machwcap); + wlc_hw->machwcap_backup = wlc_hw->machwcap; + } + + /* init tx fifo size */ + ASSERT((wlc_hw->corerev - XMTFIFOTBL_STARTREV) < + ARRAY_SIZE(xmtfifo_sz)); + wlc_hw->xmtfifo_sz = + xmtfifo_sz[(wlc_hw->corerev - XMTFIFOTBL_STARTREV)]; + + /* Get a phy for this band */ + wlc_hw->band->pi = wlc_phy_attach(wlc_hw->phy_sh, + (void *)regs, wlc_hw->band->bandtype, vars); + if (wlc_hw->band->pi == NULL) { + WL_ERROR("wl%d: wlc_bmac_attach: wlc_phy_attach failed\n", + unit); + err = 17; + goto fail; + } + + wlc_phy_machwcap_set(wlc_hw->band->pi, wlc_hw->machwcap); + + wlc_phy_get_phyversion(wlc_hw->band->pi, &wlc_hw->band->phytype, + &wlc_hw->band->phyrev, + &wlc_hw->band->radioid, + &wlc_hw->band->radiorev); + wlc_hw->band->abgphy_encore = + wlc_phy_get_encore(wlc_hw->band->pi); + wlc->band->abgphy_encore = wlc_phy_get_encore(wlc_hw->band->pi); + wlc_hw->band->core_flags = + wlc_phy_get_coreflags(wlc_hw->band->pi); + + /* verify good phy_type & supported phy revision */ + if (WLCISNPHY(wlc_hw->band)) { + if (NCONF_HAS(wlc_hw->band->phyrev)) + goto good_phy; + else + goto bad_phy; + } else if (WLCISLCNPHY(wlc_hw->band)) { + if (LCNCONF_HAS(wlc_hw->band->phyrev)) + goto good_phy; + else + goto bad_phy; + } else { + bad_phy: + WL_ERROR("wl%d: wlc_bmac_attach: unsupported phy type/rev (%d/%d)\n", + unit, + wlc_hw->band->phytype, wlc_hw->band->phyrev); + err = 18; + goto fail; + } + + good_phy: + /* BMAC_NOTE: wlc->band->pi should not be set below and should be done in the + * high level attach. However we can not make that change until all low level access + * is changed to wlc_hw->band->pi. Instead do the wlc->band->pi init below, keeping + * wlc_hw->band->pi as well for incremental update of low level fns, and cut over + * low only init when all fns updated. + */ + wlc->band->pi = wlc_hw->band->pi; + wlc->band->phytype = wlc_hw->band->phytype; + wlc->band->phyrev = wlc_hw->band->phyrev; + wlc->band->radioid = wlc_hw->band->radioid; + wlc->band->radiorev = wlc_hw->band->radiorev; + + /* default contention windows size limits */ + wlc_hw->band->CWmin = APHY_CWMIN; + wlc_hw->band->CWmax = PHY_CWMAX; + + if (!wlc_bmac_attach_dmapio(wlc, j, wme)) { + err = 19; + goto fail; + } + } + + /* disable core to match driver "down" state */ + wlc_coredisable(wlc_hw); + + /* Match driver "down" state */ + if (wlc_hw->sih->bustype == PCI_BUS) + si_pci_down(wlc_hw->sih); + + /* register sb interrupt callback functions */ + si_register_intr_callback(wlc_hw->sih, (void *)wlc_wlintrsoff, + (void *)wlc_wlintrsrestore, NULL, wlc); + + /* turn off pll and xtal to match driver "down" state */ + wlc_bmac_xtal(wlc_hw, OFF); + + /* ********************************************************************* + * The hardware is in the DOWN state at this point. D11 core + * or cores are in reset with clocks off, and the board PLLs + * are off if possible. + * + * Beyond this point, wlc->sbclk == false and chip registers + * should not be touched. + ********************************************************************* + */ + + /* init etheraddr state variables */ + macaddr = wlc_get_macaddr(wlc_hw); + if (macaddr == NULL) { + WL_ERROR("wl%d: wlc_bmac_attach: macaddr not found\n", unit); + err = 21; + goto fail; + } + bcm_ether_atoe(macaddr, wlc_hw->etheraddr); + if (is_broadcast_ether_addr(wlc_hw->etheraddr) || + is_zero_ether_addr(wlc_hw->etheraddr)) { + WL_ERROR("wl%d: wlc_bmac_attach: bad macaddr %s\n", + unit, macaddr); + err = 22; + goto fail; + } + + WL_ERROR("%s:: deviceid 0x%x nbands %d board 0x%x macaddr: %s\n", + __func__, wlc_hw->deviceid, wlc_hw->_nbands, + wlc_hw->sih->boardtype, macaddr); + + return err; + + fail: + WL_ERROR("wl%d: wlc_bmac_attach: failed with err %d\n", unit, err); + return err; +} + +/* + * Initialize wlc_info default values ... + * may get overrides later in this function + * BMAC_NOTES, move low out and resolve the dangling ones + */ +void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw) +{ + struct wlc_info *wlc = wlc_hw->wlc; + + /* set default sw macintmask value */ + wlc->defmacintmask = DEF_MACINTMASK; + + /* various 802.11g modes */ + wlc_hw->shortslot = false; + + wlc_hw->SFBL = RETRY_SHORT_FB; + wlc_hw->LFBL = RETRY_LONG_FB; + + /* default mac retry limits */ + wlc_hw->SRL = RETRY_SHORT_DEF; + wlc_hw->LRL = RETRY_LONG_DEF; + wlc_hw->chanspec = CH20MHZ_CHSPEC(1); +} + +/* + * low level detach + */ +int wlc_bmac_detach(struct wlc_info *wlc) +{ + uint i; + wlc_hwband_t *band; + struct wlc_hw_info *wlc_hw = wlc->hw; + int callbacks; + + callbacks = 0; + + if (wlc_hw->sih) { + /* detach interrupt sync mechanism since interrupt is disabled and per-port + * interrupt object may has been freed. this must be done before sb core switch + */ + si_deregister_intr_callback(wlc_hw->sih); + + if (wlc_hw->sih->bustype == PCI_BUS) + si_pci_sleep(wlc_hw->sih); + } + + wlc_bmac_detach_dmapio(wlc_hw); + + band = wlc_hw->band; + for (i = 0; i < NBANDS_HW(wlc_hw); i++) { + if (band->pi) { + /* Detach this band's phy */ + wlc_phy_detach(band->pi); + band->pi = NULL; + } + band = wlc_hw->bandstate[OTHERBANDUNIT(wlc)]; + } + + /* Free shared phy state */ + wlc_phy_shared_detach(wlc_hw->phy_sh); + + wlc_phy_shim_detach(wlc_hw->physhim); + + /* free vars */ + if (wlc_hw->vars) { + kfree(wlc_hw->vars); + wlc_hw->vars = NULL; + } + + if (wlc_hw->sih) { + si_detach(wlc_hw->sih); + wlc_hw->sih = NULL; + } + + return callbacks; + +} + +void wlc_bmac_reset(struct wlc_hw_info *wlc_hw) +{ + WL_TRACE("wl%d: wlc_bmac_reset\n", wlc_hw->unit); + + WLCNTINCR(wlc_hw->wlc->pub->_cnt->reset); + + /* reset the core */ + if (!DEVICEREMOVED(wlc_hw->wlc)) + wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); + + /* purge the dma rings */ + wlc_flushqueues(wlc_hw->wlc); + + wlc_reset_bmac_done(wlc_hw->wlc); +} + +void +wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, + bool mute) { + u32 macintmask; + bool fastclk; + struct wlc_info *wlc = wlc_hw->wlc; + + WL_TRACE("wl%d: wlc_bmac_init\n", wlc_hw->unit); + + /* request FAST clock if not on */ + fastclk = wlc_hw->forcefastclk; + if (!fastclk) + wlc_clkctl_clk(wlc_hw, CLK_FAST); + + /* disable interrupts */ + macintmask = wl_intrsoff(wlc->wl); + + /* set up the specified band and chanspec */ + wlc_setxband(wlc_hw, CHSPEC_WLCBANDUNIT(chanspec)); + wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec); + + /* do one-time phy inits and calibration */ + wlc_phy_cal_init(wlc_hw->band->pi); + + /* core-specific initialization */ + wlc_coreinit(wlc); + + /* suspend the tx fifos and mute the phy for preism cac time */ + if (mute) + wlc_bmac_mute(wlc_hw, ON, PHY_MUTE_FOR_PREISM); + + /* band-specific inits */ + wlc_bmac_bsinit(wlc, chanspec); + + /* restore macintmask */ + wl_intrsrestore(wlc->wl, macintmask); + + /* seed wake_override with WLC_WAKE_OVERRIDE_MACSUSPEND since the mac is suspended + * and wlc_enable_mac() will clear this override bit. + */ + mboolset(wlc_hw->wake_override, WLC_WAKE_OVERRIDE_MACSUSPEND); + + /* + * initialize mac_suspend_depth to 1 to match ucode initial suspended state + */ + wlc_hw->mac_suspend_depth = 1; + + /* restore the clk */ + if (!fastclk) + wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); +} + +int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw) +{ + uint coremask; + + WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); + + ASSERT(wlc_hw->wlc->pub->hw_up && wlc_hw->wlc->macintmask == 0); + + /* + * Enable pll and xtal, initialize the power control registers, + * and force fastclock for the remainder of wlc_up(). + */ + wlc_bmac_xtal(wlc_hw, ON); + si_clkctl_init(wlc_hw->sih); + wlc_clkctl_clk(wlc_hw, CLK_FAST); + + /* + * Configure pci/pcmcia here instead of in wlc_attach() + * to allow mfg hotswap: down, hotswap (chip power cycle), up. + */ + coremask = (1 << wlc_hw->wlc->core->coreidx); + + if (wlc_hw->sih->bustype == PCI_BUS) + si_pci_setup(wlc_hw->sih, coremask); + + ASSERT(si_coreid(wlc_hw->sih) == D11_CORE_ID); + + /* + * Need to read the hwradio status here to cover the case where the system + * is loaded with the hw radio disabled. We do not want to bring the driver up in this case. + */ + if (wlc_bmac_radio_read_hwdisabled(wlc_hw)) { + /* put SB PCI in down state again */ + if (wlc_hw->sih->bustype == PCI_BUS) + si_pci_down(wlc_hw->sih); + wlc_bmac_xtal(wlc_hw, OFF); + return BCME_RADIOOFF; + } + + if (wlc_hw->sih->bustype == PCI_BUS) + si_pci_up(wlc_hw->sih); + + /* reset the d11 core */ + wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); + + return 0; +} + +int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw) +{ + WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); + + wlc_hw->up = true; + wlc_phy_hw_state_upd(wlc_hw->band->pi, true); + + /* FULLY enable dynamic power control and d11 core interrupt */ + wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); + ASSERT(wlc_hw->wlc->macintmask == 0); + wl_intrson(wlc_hw->wlc->wl); + return 0; +} + +int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw) +{ + bool dev_gone; + uint callbacks = 0; + + WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); + + if (!wlc_hw->up) + return callbacks; + + dev_gone = DEVICEREMOVED(wlc_hw->wlc); + + /* disable interrupts */ + if (dev_gone) + wlc_hw->wlc->macintmask = 0; + else { + /* now disable interrupts */ + wl_intrsoff(wlc_hw->wlc->wl); + + /* ensure we're running on the pll clock again */ + wlc_clkctl_clk(wlc_hw, CLK_FAST); + } + /* down phy at the last of this stage */ + callbacks += wlc_phy_down(wlc_hw->band->pi); + + return callbacks; +} + +int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw) +{ + uint callbacks = 0; + bool dev_gone; + + WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); + + if (!wlc_hw->up) + return callbacks; + + wlc_hw->up = false; + wlc_phy_hw_state_upd(wlc_hw->band->pi, false); + + dev_gone = DEVICEREMOVED(wlc_hw->wlc); + + if (dev_gone) { + wlc_hw->sbclk = false; + wlc_hw->clk = false; + wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); + + /* reclaim any posted packets */ + wlc_flushqueues(wlc_hw->wlc); + } else { + + /* Reset and disable the core */ + if (si_iscoreup(wlc_hw->sih)) { + if (R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol) & + MCTL_EN_MAC) + wlc_suspend_mac_and_wait(wlc_hw->wlc); + callbacks += wl_reset(wlc_hw->wlc->wl); + wlc_coredisable(wlc_hw); + } + + /* turn off primary xtal and pll */ + if (!wlc_hw->noreset) { + if (wlc_hw->sih->bustype == PCI_BUS) + si_pci_down(wlc_hw->sih); + wlc_bmac_xtal(wlc_hw, OFF); + } + } + + return callbacks; +} + +void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw) +{ + if (D11REV_IS(wlc_hw->corerev, 4)) /* no slowclock */ + udelay(5); + else { + /* delay before first read of ucode state */ + udelay(40); + + /* wait until ucode is no longer asleep */ + SPINWAIT((wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) == + DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly); + } + + ASSERT(wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) != DBGST_ASLEEP); +} + +void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, u8 *ea) +{ + bcopy(wlc_hw->etheraddr, ea, ETH_ALEN); +} + +void wlc_bmac_set_hw_etheraddr(struct wlc_hw_info *wlc_hw, + u8 *ea) +{ + bcopy(ea, wlc_hw->etheraddr, ETH_ALEN); +} + +int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw) +{ + return wlc_hw->band->bandtype; +} + +void *wlc_cur_phy(struct wlc_info *wlc) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + return (void *)wlc_hw->band->pi; +} + +/* control chip clock to save power, enable dynamic clock or force fast clock */ +static void wlc_clkctl_clk(struct wlc_hw_info *wlc_hw, uint mode) +{ + if (PMUCTL_ENAB(wlc_hw->sih)) { + /* new chips with PMU, CCS_FORCEHT will distribute the HT clock on backplane, + * but mac core will still run on ALP(not HT) when it enters powersave mode, + * which means the FCA bit may not be set. + * should wakeup mac if driver wants it to run on HT. + */ + + if (wlc_hw->clk) { + if (mode == CLK_FAST) { + OR_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, + CCS_FORCEHT); + + udelay(64); + + SPINWAIT(((R_REG + (wlc_hw->osh, + &wlc_hw->regs-> + clk_ctl_st) & CCS_HTAVAIL) == 0), + PMU_MAX_TRANSITION_DLY); + ASSERT(R_REG + (wlc_hw->osh, + &wlc_hw->regs-> + clk_ctl_st) & CCS_HTAVAIL); + } else { + if ((wlc_hw->sih->pmurev == 0) && + (R_REG + (wlc_hw->osh, + &wlc_hw->regs-> + clk_ctl_st) & (CCS_FORCEHT | CCS_HTAREQ))) + SPINWAIT(((R_REG + (wlc_hw->osh, + &wlc_hw->regs-> + clk_ctl_st) & CCS_HTAVAIL) + == 0), + PMU_MAX_TRANSITION_DLY); + AND_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, + ~CCS_FORCEHT); + } + } + wlc_hw->forcefastclk = (mode == CLK_FAST); + } else { + bool wakeup_ucode; + + /* old chips w/o PMU, force HT through cc, + * then use FCA to verify mac is running fast clock + */ + + wakeup_ucode = D11REV_LT(wlc_hw->corerev, 9); + + if (wlc_hw->up && wakeup_ucode) + wlc_ucode_wake_override_set(wlc_hw, + WLC_WAKE_OVERRIDE_CLKCTL); + + wlc_hw->forcefastclk = si_clkctl_cc(wlc_hw->sih, mode); + + if (D11REV_LT(wlc_hw->corerev, 11)) { + /* ucode WAR for old chips */ + if (wlc_hw->forcefastclk) + wlc_bmac_mhf(wlc_hw, MHF1, MHF1_FORCEFASTCLK, + MHF1_FORCEFASTCLK, WLC_BAND_ALL); + else + wlc_bmac_mhf(wlc_hw, MHF1, MHF1_FORCEFASTCLK, 0, + WLC_BAND_ALL); + } + + /* check fast clock is available (if core is not in reset) */ + if (D11REV_GT(wlc_hw->corerev, 4) && wlc_hw->forcefastclk + && wlc_hw->clk) + ASSERT(si_core_sflags(wlc_hw->sih, 0, 0) & SISF_FCLKA); + + /* keep the ucode wake bit on if forcefastclk is on + * since we do not want ucode to put us back to slow clock + * when it dozes for PM mode. + * Code below matches the wake override bit with current forcefastclk state + * Only setting bit in wake_override instead of waking ucode immediately + * since old code (wlc.c 1.4499) had this behavior. Older code set + * wlc->forcefastclk but only had the wake happen if the wakup_ucode work + * (protected by an up check) was executed just below. + */ + if (wlc_hw->forcefastclk) + mboolset(wlc_hw->wake_override, + WLC_WAKE_OVERRIDE_FORCEFAST); + else + mboolclr(wlc_hw->wake_override, + WLC_WAKE_OVERRIDE_FORCEFAST); + + /* ok to clear the wakeup now */ + if (wlc_hw->up && wakeup_ucode) + wlc_ucode_wake_override_clear(wlc_hw, + WLC_WAKE_OVERRIDE_CLKCTL); + } +} + +/* set initial host flags value */ +static void +wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + + memset(mhfs, 0, MHFMAX * sizeof(u16)); + + mhfs[MHF2] |= mhf2_init; + + /* prohibit use of slowclock on multifunction boards */ + if (wlc_hw->boardflags & BFL_NOPLLDOWN) + mhfs[MHF1] |= MHF1_FORCEFASTCLK; + + if (WLCISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 2)) { + mhfs[MHF2] |= MHF2_NPHY40MHZ_WAR; + mhfs[MHF1] |= MHF1_IQSWAP_WAR; + } +} + +/* set or clear ucode host flag bits + * it has an optimization for no-change write + * it only writes through shared memory when the core has clock; + * pre-CLK changes should use wlc_write_mhf to get around the optimization + * + * + * bands values are: WLC_BAND_AUTO <--- Current band only + * WLC_BAND_5G <--- 5G band only + * WLC_BAND_2G <--- 2G band only + * WLC_BAND_ALL <--- All bands + */ +void +wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, u16 val, + int bands) +{ + u16 save; + u16 addr[MHFMAX] = { + M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4, + M_HOST_FLAGS5 + }; + wlc_hwband_t *band; + + ASSERT((val & ~mask) == 0); + ASSERT(idx < MHFMAX); + ASSERT(ARRAY_SIZE(addr) == MHFMAX); + + switch (bands) { + /* Current band only or all bands, + * then set the band to current band + */ + case WLC_BAND_AUTO: + case WLC_BAND_ALL: + band = wlc_hw->band; + break; + case WLC_BAND_5G: + band = wlc_hw->bandstate[BAND_5G_INDEX]; + break; + case WLC_BAND_2G: + band = wlc_hw->bandstate[BAND_2G_INDEX]; + break; + default: + ASSERT(0); + band = NULL; + } + + if (band) { + save = band->mhfs[idx]; + band->mhfs[idx] = (band->mhfs[idx] & ~mask) | val; + + /* optimization: only write through if changed, and + * changed band is the current band + */ + if (wlc_hw->clk && (band->mhfs[idx] != save) + && (band == wlc_hw->band)) + wlc_bmac_write_shm(wlc_hw, addr[idx], + (u16) band->mhfs[idx]); + } + + if (bands == WLC_BAND_ALL) { + wlc_hw->bandstate[0]->mhfs[idx] = + (wlc_hw->bandstate[0]->mhfs[idx] & ~mask) | val; + wlc_hw->bandstate[1]->mhfs[idx] = + (wlc_hw->bandstate[1]->mhfs[idx] & ~mask) | val; + } +} + +u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands) +{ + wlc_hwband_t *band; + ASSERT(idx < MHFMAX); + + switch (bands) { + case WLC_BAND_AUTO: + band = wlc_hw->band; + break; + case WLC_BAND_5G: + band = wlc_hw->bandstate[BAND_5G_INDEX]; + break; + case WLC_BAND_2G: + band = wlc_hw->bandstate[BAND_2G_INDEX]; + break; + default: + ASSERT(0); + band = NULL; + } + + if (!band) + return 0; + + return band->mhfs[idx]; +} + +static void wlc_write_mhf(struct wlc_hw_info *wlc_hw, u16 *mhfs) +{ + u8 idx; + u16 addr[] = { + M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4, + M_HOST_FLAGS5 + }; + + ASSERT(ARRAY_SIZE(addr) == MHFMAX); + + for (idx = 0; idx < MHFMAX; idx++) { + wlc_bmac_write_shm(wlc_hw, addr[idx], mhfs[idx]); + } +} + +/* set the maccontrol register to desired reset state and + * initialize the sw cache of the register + */ +static void wlc_mctrl_reset(struct wlc_hw_info *wlc_hw) +{ + /* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */ + wlc_hw->maccontrol = 0; + wlc_hw->suspended_fifos = 0; + wlc_hw->wake_override = 0; + wlc_hw->mute_override = 0; + wlc_bmac_mctrl(wlc_hw, ~0, MCTL_IHR_EN | MCTL_WAKE); +} + +/* set or clear maccontrol bits */ +void wlc_bmac_mctrl(struct wlc_hw_info *wlc_hw, u32 mask, u32 val) +{ + u32 maccontrol; + u32 new_maccontrol; + + ASSERT((val & ~mask) == 0); + + maccontrol = wlc_hw->maccontrol; + new_maccontrol = (maccontrol & ~mask) | val; + + /* if the new maccontrol value is the same as the old, nothing to do */ + if (new_maccontrol == maccontrol) + return; + + /* something changed, cache the new value */ + wlc_hw->maccontrol = new_maccontrol; + + /* write the new values with overrides applied */ + wlc_mctrl_write(wlc_hw); +} + +/* write the software state of maccontrol and overrides to the maccontrol register */ +static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw) +{ + u32 maccontrol = wlc_hw->maccontrol; + + /* OR in the wake bit if overridden */ + if (wlc_hw->wake_override) + maccontrol |= MCTL_WAKE; + + /* set AP and INFRA bits for mute if needed */ + if (wlc_hw->mute_override) { + maccontrol &= ~(MCTL_AP); + maccontrol |= MCTL_INFRA; + } + + W_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol, maccontrol); +} + +void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, u32 override_bit) +{ + ASSERT((wlc_hw->wake_override & override_bit) == 0); + + if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) { + mboolset(wlc_hw->wake_override, override_bit); + return; + } + + mboolset(wlc_hw->wake_override, override_bit); + + wlc_mctrl_write(wlc_hw); + wlc_bmac_wait_for_wake(wlc_hw); + + return; +} + +void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw, u32 override_bit) +{ + ASSERT(wlc_hw->wake_override & override_bit); + + mboolclr(wlc_hw->wake_override, override_bit); + + if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) + return; + + wlc_mctrl_write(wlc_hw); + + return; +} + +/* When driver needs ucode to stop beaconing, it has to make sure that + * MCTL_AP is clear and MCTL_INFRA is set + * Mode MCTL_AP MCTL_INFRA + * AP 1 1 + * STA 0 1 <--- This will ensure no beacons + * IBSS 0 0 + */ +static void wlc_ucode_mute_override_set(struct wlc_hw_info *wlc_hw) +{ + wlc_hw->mute_override = 1; + + /* if maccontrol already has AP == 0 and INFRA == 1 without this + * override, then there is no change to write + */ + if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA) + return; + + wlc_mctrl_write(wlc_hw); + + return; +} + +/* Clear the override on AP and INFRA bits */ +static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw) +{ + if (wlc_hw->mute_override == 0) + return; + + wlc_hw->mute_override = 0; + + /* if maccontrol already has AP == 0 and INFRA == 1 without this + * override, then there is no change to write + */ + if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA) + return; + + wlc_mctrl_write(wlc_hw); +} + +/* + * Write a MAC address to the rcmta structure + */ +void +wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, + const u8 *addr) +{ + d11regs_t *regs = wlc_hw->regs; + volatile u16 *objdata16 = (volatile u16 *)®s->objdata; + u32 mac_hm; + u16 mac_l; + struct osl_info *osh; + + WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); + + ASSERT(wlc_hw->corerev > 4); + + mac_hm = + (addr[3] << 24) | (addr[2] << 16) | + (addr[1] << 8) | addr[0]; + mac_l = (addr[5] << 8) | addr[4]; + + osh = wlc_hw->osh; + + W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); + (void)R_REG(osh, ®s->objaddr); + W_REG(osh, ®s->objdata, mac_hm); + W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1))); + (void)R_REG(osh, ®s->objaddr); + W_REG(osh, objdata16, mac_l); +} + +/* + * Write a MAC address to the given match reg offset in the RXE match engine. + */ +void +wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset, + const u8 *addr) +{ + d11regs_t *regs; + u16 mac_l; + u16 mac_m; + u16 mac_h; + struct osl_info *osh; + + WL_TRACE("wl%d: wlc_bmac_set_addrmatch\n", wlc_hw->unit); + + ASSERT((match_reg_offset < RCM_SIZE) || (wlc_hw->corerev == 4)); + + regs = wlc_hw->regs; + mac_l = addr[0] | (addr[1] << 8); + mac_m = addr[2] | (addr[3] << 8); + mac_h = addr[4] | (addr[5] << 8); + + osh = wlc_hw->osh; + + /* enter the MAC addr into the RXE match registers */ + W_REG(osh, ®s->rcm_ctl, RCM_INC_DATA | match_reg_offset); + W_REG(osh, ®s->rcm_mat_data, mac_l); + W_REG(osh, ®s->rcm_mat_data, mac_m); + W_REG(osh, ®s->rcm_mat_data, mac_h); + +} + +void +wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, int len, + void *buf) +{ + d11regs_t *regs; + u32 word; + bool be_bit; +#ifdef IL_BIGENDIAN + volatile u16 *dptr = NULL; +#endif /* IL_BIGENDIAN */ + struct osl_info *osh; + + WL_TRACE("wl%d: wlc_bmac_write_template_ram\n", wlc_hw->unit); + + regs = wlc_hw->regs; + osh = wlc_hw->osh; + + ASSERT(IS_ALIGNED(offset, sizeof(u32))); + ASSERT(IS_ALIGNED(len, sizeof(u32))); + ASSERT((offset & ~0xffff) == 0); + + W_REG(osh, ®s->tplatewrptr, offset); + + /* if MCTL_BIGEND bit set in mac control register, + * the chip swaps data in fifo, as well as data in + * template ram + */ + be_bit = (R_REG(osh, ®s->maccontrol) & MCTL_BIGEND) != 0; + + while (len > 0) { + bcopy((u8 *) buf, &word, sizeof(u32)); + + if (be_bit) + word = hton32(word); + else + word = htol32(word); + + W_REG(osh, ®s->tplatewrdata, word); + + buf = (u8 *) buf + sizeof(u32); + len -= sizeof(u32); + } +} + +void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin) +{ + struct osl_info *osh; + + osh = wlc_hw->osh; + wlc_hw->band->CWmin = newmin; + + W_REG(osh, &wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMIN); + (void)R_REG(osh, &wlc_hw->regs->objaddr); + W_REG(osh, &wlc_hw->regs->objdata, newmin); +} + +void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax) +{ + struct osl_info *osh; + + osh = wlc_hw->osh; + wlc_hw->band->CWmax = newmax; + + W_REG(osh, &wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMAX); + (void)R_REG(osh, &wlc_hw->regs->objaddr); + W_REG(osh, &wlc_hw->regs->objdata, newmax); +} + +void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw) +{ + bool fastclk; + u32 tmp; + + /* request FAST clock if not on */ + fastclk = wlc_hw->forcefastclk; + if (!fastclk) + wlc_clkctl_clk(wlc_hw, CLK_FAST); + + wlc_phy_bw_state_set(wlc_hw->band->pi, bw); + + ASSERT(wlc_hw->clk); + if (D11REV_LT(wlc_hw->corerev, 17)) + tmp = R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol); + + wlc_bmac_phy_reset(wlc_hw); + wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi)); + + /* restore the clk */ + if (!fastclk) + wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); +} + +static void +wlc_write_hw_bcntemplate0(struct wlc_hw_info *wlc_hw, void *bcn, int len) +{ + d11regs_t *regs = wlc_hw->regs; + + wlc_bmac_write_template_ram(wlc_hw, T_BCN0_TPL_BASE, (len + 3) & ~3, + bcn); + /* write beacon length to SCR */ + ASSERT(len < 65536); + wlc_bmac_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len); + /* mark beacon0 valid */ + OR_REG(wlc_hw->osh, ®s->maccommand, MCMD_BCN0VLD); +} + +static void +wlc_write_hw_bcntemplate1(struct wlc_hw_info *wlc_hw, void *bcn, int len) +{ + d11regs_t *regs = wlc_hw->regs; + + wlc_bmac_write_template_ram(wlc_hw, T_BCN1_TPL_BASE, (len + 3) & ~3, + bcn); + /* write beacon length to SCR */ + ASSERT(len < 65536); + wlc_bmac_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len); + /* mark beacon1 valid */ + OR_REG(wlc_hw->osh, ®s->maccommand, MCMD_BCN1VLD); +} + +/* mac is assumed to be suspended at this point */ +void +wlc_bmac_write_hw_bcntemplates(struct wlc_hw_info *wlc_hw, void *bcn, int len, + bool both) +{ + d11regs_t *regs = wlc_hw->regs; + + if (both) { + wlc_write_hw_bcntemplate0(wlc_hw, bcn, len); + wlc_write_hw_bcntemplate1(wlc_hw, bcn, len); + } else { + /* bcn 0 */ + if (!(R_REG(wlc_hw->osh, ®s->maccommand) & MCMD_BCN0VLD)) + wlc_write_hw_bcntemplate0(wlc_hw, bcn, len); + /* bcn 1 */ + else if (! + (R_REG(wlc_hw->osh, ®s->maccommand) & MCMD_BCN1VLD)) + wlc_write_hw_bcntemplate1(wlc_hw, bcn, len); + else /* one template should always have been available */ + ASSERT(0); + } +} + +static void WLBANDINITFN(wlc_bmac_upd_synthpu) (struct wlc_hw_info *wlc_hw) +{ + u16 v; + struct wlc_info *wlc = wlc_hw->wlc; + /* update SYNTHPU_DLY */ + + if (WLCISLCNPHY(wlc->band)) { + v = SYNTHPU_DLY_LPPHY_US; + } else if (WLCISNPHY(wlc->band) && (NREV_GE(wlc->band->phyrev, 3))) { + v = SYNTHPU_DLY_NPHY_US; + } else { + v = SYNTHPU_DLY_BPHY_US; + } + + wlc_bmac_write_shm(wlc_hw, M_SYNTHPU_DLY, v); +} + +/* band-specific init */ +static void +WLBANDINITFN(wlc_bmac_bsinit) (struct wlc_info *wlc, chanspec_t chanspec) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + + WL_TRACE("wl%d: wlc_bmac_bsinit: bandunit %d\n", + wlc_hw->unit, wlc_hw->band->bandunit); + + /* sanity check */ + if (PHY_TYPE(R_REG(wlc_hw->osh, &wlc_hw->regs->phyversion)) != + PHY_TYPE_LCNXN) + ASSERT((uint) + PHY_TYPE(R_REG(wlc_hw->osh, &wlc_hw->regs->phyversion)) + == wlc_hw->band->phytype); + + wlc_ucode_bsinit(wlc_hw); + + wlc_phy_init(wlc_hw->band->pi, chanspec); + + wlc_ucode_txant_set(wlc_hw); + + /* cwmin is band-specific, update hardware with value for current band */ + wlc_bmac_set_cwmin(wlc_hw, wlc_hw->band->CWmin); + wlc_bmac_set_cwmax(wlc_hw, wlc_hw->band->CWmax); + + wlc_bmac_update_slot_timing(wlc_hw, + BAND_5G(wlc_hw->band-> + bandtype) ? true : wlc_hw-> + shortslot); + + /* write phytype and phyvers */ + wlc_bmac_write_shm(wlc_hw, M_PHYTYPE, (u16) wlc_hw->band->phytype); + wlc_bmac_write_shm(wlc_hw, M_PHYVER, (u16) wlc_hw->band->phyrev); + + /* initialize the txphyctl1 rate table since shmem is shared between bands */ + wlc_upd_ofdm_pctl1_table(wlc_hw); + + wlc_bmac_upd_synthpu(wlc_hw); +} + +void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk) +{ + WL_TRACE("wl%d: wlc_bmac_core_phy_clk: clk %d\n", wlc_hw->unit, clk); + + wlc_hw->phyclk = clk; + + if (OFF == clk) { /* clear gmode bit, put phy into reset */ + + si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC | SICF_GMODE), + (SICF_PRST | SICF_FGC)); + udelay(1); + si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_PRST); + udelay(1); + + } else { /* take phy out of reset */ + + si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_FGC); + udelay(1); + si_core_cflags(wlc_hw->sih, (SICF_FGC), 0); + udelay(1); + + } +} + +/* Perform a soft reset of the PHY PLL */ +void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw) +{ + WL_TRACE("wl%d: wlc_bmac_core_phypll_reset\n", wlc_hw->unit); + + si_corereg(wlc_hw->sih, SI_CC_IDX, + offsetof(chipcregs_t, chipcontrol_addr), ~0, 0); + udelay(1); + si_corereg(wlc_hw->sih, SI_CC_IDX, + offsetof(chipcregs_t, chipcontrol_data), 0x4, 0); + udelay(1); + si_corereg(wlc_hw->sih, SI_CC_IDX, + offsetof(chipcregs_t, chipcontrol_data), 0x4, 4); + udelay(1); + si_corereg(wlc_hw->sih, SI_CC_IDX, + offsetof(chipcregs_t, chipcontrol_data), 0x4, 0); + udelay(1); +} + +/* light way to turn on phy clock without reset for NPHY only + * refer to wlc_bmac_core_phy_clk for full version + */ +void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk) +{ + /* support(necessary for NPHY and HYPHY) only */ + if (!WLCISNPHY(wlc_hw->band)) + return; + + if (ON == clk) + si_core_cflags(wlc_hw->sih, SICF_FGC, SICF_FGC); + else + si_core_cflags(wlc_hw->sih, SICF_FGC, 0); + +} + +void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk) +{ + if (ON == clk) + si_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE); + else + si_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0); +} + +void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw) +{ + wlc_phy_t *pih = wlc_hw->band->pi; + u32 phy_bw_clkbits; + bool phy_in_reset = false; + + WL_TRACE("wl%d: wlc_bmac_phy_reset\n", wlc_hw->unit); + + if (pih == NULL) + return; + + phy_bw_clkbits = wlc_phy_clk_bwbits(wlc_hw->band->pi); + + /* Specfic reset sequence required for NPHY rev 3 and 4 */ + if (WLCISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) && + NREV_LE(wlc_hw->band->phyrev, 4)) { + /* Set the PHY bandwidth */ + si_core_cflags(wlc_hw->sih, SICF_BWMASK, phy_bw_clkbits); + + udelay(1); + + /* Perform a soft reset of the PHY PLL */ + wlc_bmac_core_phypll_reset(wlc_hw); + + /* reset the PHY */ + si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE), + (SICF_PRST | SICF_PCLKE)); + phy_in_reset = true; + } else { + + si_core_cflags(wlc_hw->sih, + (SICF_PRST | SICF_PCLKE | SICF_BWMASK), + (SICF_PRST | SICF_PCLKE | phy_bw_clkbits)); + } + + udelay(2); + wlc_bmac_core_phy_clk(wlc_hw, ON); + + if (pih) + wlc_phy_anacore(pih, ON); +} + +/* switch to and initialize new band */ +static void +WLBANDINITFN(wlc_bmac_setband) (struct wlc_hw_info *wlc_hw, uint bandunit, + chanspec_t chanspec) { + struct wlc_info *wlc = wlc_hw->wlc; + u32 macintmask; + + ASSERT(NBANDS_HW(wlc_hw) > 1); + ASSERT(bandunit != wlc_hw->band->bandunit); + + /* Enable the d11 core before accessing it */ + if (!si_iscoreup(wlc_hw->sih)) { + si_core_reset(wlc_hw->sih, 0, 0); + ASSERT(si_iscoreup(wlc_hw->sih)); + wlc_mctrl_reset(wlc_hw); + } + + macintmask = wlc_setband_inact(wlc, bandunit); + + if (!wlc_hw->up) + return; + + wlc_bmac_core_phy_clk(wlc_hw, ON); + + /* band-specific initializations */ + wlc_bmac_bsinit(wlc, chanspec); + + /* + * If there are any pending software interrupt bits, + * then replace these with a harmless nonzero value + * so wlc_dpc() will re-enable interrupts when done. + */ + if (wlc->macintstatus) + wlc->macintstatus = MI_DMAINT; + + /* restore macintmask */ + wl_intrsrestore(wlc->wl, macintmask); + + /* ucode should still be suspended.. */ + ASSERT((R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol) & MCTL_EN_MAC) == + 0); +} + +/* low-level band switch utility routine */ +void WLBANDINITFN(wlc_setxband) (struct wlc_hw_info *wlc_hw, uint bandunit) +{ + WL_TRACE("wl%d: wlc_setxband: bandunit %d\n", wlc_hw->unit, bandunit); + + wlc_hw->band = wlc_hw->bandstate[bandunit]; + + /* BMAC_NOTE: until we eliminate need for wlc->band refs in low level code */ + wlc_hw->wlc->band = wlc_hw->wlc->bandstate[bandunit]; + + /* set gmode core flag */ + if (wlc_hw->sbclk && !wlc_hw->noreset) { + si_core_cflags(wlc_hw->sih, SICF_GMODE, + ((bandunit == 0) ? SICF_GMODE : 0)); + } +} + +static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw) +{ + + /* reject unsupported corerev */ + if (!VALID_COREREV(wlc_hw->corerev)) { + WL_ERROR("unsupported core rev %d\n", wlc_hw->corerev); + return false; + } + + return true; +} + +static bool wlc_validboardtype(struct wlc_hw_info *wlc_hw) +{ + bool goodboard = true; + uint boardrev = wlc_hw->boardrev; + + if (boardrev == 0) + goodboard = false; + else if (boardrev > 0xff) { + uint brt = (boardrev & 0xf000) >> 12; + uint b0 = (boardrev & 0xf00) >> 8; + uint b1 = (boardrev & 0xf0) >> 4; + uint b2 = boardrev & 0xf; + + if ((brt > 2) || (brt == 0) || (b0 > 9) || (b0 == 0) || (b1 > 9) + || (b2 > 9)) + goodboard = false; + } + + if (wlc_hw->sih->boardvendor != VENDOR_BROADCOM) + return goodboard; + + return goodboard; +} + +static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw) +{ + const char *varname = "macaddr"; + char *macaddr; + + /* If macaddr exists, use it (Sromrev4, CIS, ...). */ + macaddr = getvar(wlc_hw->vars, varname); + if (macaddr != NULL) + return macaddr; + + if (NBANDS_HW(wlc_hw) > 1) + varname = "et1macaddr"; + else + varname = "il0macaddr"; + + macaddr = getvar(wlc_hw->vars, varname); + if (macaddr == NULL) { + WL_ERROR("wl%d: wlc_get_macaddr: macaddr getvar(%s) not found\n", + wlc_hw->unit, varname); + } + + return macaddr; +} + +/* + * Return true if radio is disabled, otherwise false. + * hw radio disable signal is an external pin, users activate it asynchronously + * this function could be called when driver is down and w/o clock + * it operates on different registers depending on corerev and boardflag. + */ +bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw) +{ + bool v, clk, xtal; + u32 resetbits = 0, flags = 0; + + xtal = wlc_hw->sbclk; + if (!xtal) + wlc_bmac_xtal(wlc_hw, ON); + + /* may need to take core out of reset first */ + clk = wlc_hw->clk; + if (!clk) { + if (D11REV_LE(wlc_hw->corerev, 11)) + resetbits |= SICF_PCLKE; + + /* + * corerev >= 18, mac no longer enables phyclk automatically when driver accesses + * phyreg throughput mac. This can be skipped since only mac reg is accessed below + */ + if (D11REV_GE(wlc_hw->corerev, 18)) + flags |= SICF_PCLKE; + + /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */ + if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || + (wlc_hw->sih->chip == BCM43225_CHIP_ID) || + (wlc_hw->sih->chip == BCM43421_CHIP_ID)) + wlc_hw->regs = + (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, + 0); + si_core_reset(wlc_hw->sih, flags, resetbits); + wlc_mctrl_reset(wlc_hw); + } + + v = ((R_REG(wlc_hw->osh, &wlc_hw->regs->phydebug) & PDBG_RFD) != 0); + + /* put core back into reset */ + if (!clk) + si_core_disable(wlc_hw->sih, 0); + + if (!xtal) + wlc_bmac_xtal(wlc_hw, OFF); + + return v; +} + +/* Initialize just the hardware when coming out of POR or S3/S5 system states */ +void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw) +{ + if (wlc_hw->wlc->pub->hw_up) + return; + + WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); + + /* + * Enable pll and xtal, initialize the power control registers, + * and force fastclock for the remainder of wlc_up(). + */ + wlc_bmac_xtal(wlc_hw, ON); + si_clkctl_init(wlc_hw->sih); + wlc_clkctl_clk(wlc_hw, CLK_FAST); + + if (wlc_hw->sih->bustype == PCI_BUS) { + si_pci_fixcfg(wlc_hw->sih); + + /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */ + if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || + (wlc_hw->sih->chip == BCM43225_CHIP_ID) || + (wlc_hw->sih->chip == BCM43421_CHIP_ID)) + wlc_hw->regs = + (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, + 0); + } + + /* Inform phy that a POR reset has occurred so it does a complete phy init */ + wlc_phy_por_inform(wlc_hw->band->pi); + + wlc_hw->ucode_loaded = false; + wlc_hw->wlc->pub->hw_up = true; + + if ((wlc_hw->boardflags & BFL_FEM) + && (wlc_hw->sih->chip == BCM4313_CHIP_ID)) { + if (! + (wlc_hw->boardrev >= 0x1250 + && (wlc_hw->boardflags & BFL_FEM_BT))) + si_epa_4313war(wlc_hw->sih); + } +} + +static bool wlc_dma_rxreset(struct wlc_hw_info *wlc_hw, uint fifo) +{ + struct hnddma_pub *di = wlc_hw->di[fifo]; + struct osl_info *osh; + + if (D11REV_LT(wlc_hw->corerev, 12)) { + bool rxidle = true; + u16 rcv_frm_cnt = 0; + + osh = wlc_hw->osh; + + W_REG(osh, &wlc_hw->regs->rcv_fifo_ctl, fifo << 8); + SPINWAIT((!(rxidle = dma_rxidle(di))) && + ((rcv_frm_cnt = + R_REG(osh, &wlc_hw->regs->rcv_frm_cnt)) != 0), + 50000); + + if (!rxidle && (rcv_frm_cnt != 0)) + WL_ERROR("wl%d: %s: rxdma[%d] not idle && rcv_frm_cnt(%d) not zero\n", + wlc_hw->unit, __func__, fifo, rcv_frm_cnt); + mdelay(2); + } + + return dma_rxreset(di); +} + +/* d11 core reset + * ensure fask clock during reset + * reset dma + * reset d11(out of reset) + * reset phy(out of reset) + * clear software macintstatus for fresh new start + * one testing hack wlc_hw->noreset will bypass the d11/phy reset + */ +void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags) +{ + d11regs_t *regs; + uint i; + bool fastclk; + u32 resetbits = 0; + + if (flags == WLC_USE_COREFLAGS) + flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0); + + WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); + + regs = wlc_hw->regs; + + /* request FAST clock if not on */ + fastclk = wlc_hw->forcefastclk; + if (!fastclk) + wlc_clkctl_clk(wlc_hw, CLK_FAST); + + /* reset the dma engines except first time thru */ + if (si_iscoreup(wlc_hw->sih)) { + for (i = 0; i < NFIFO; i++) + if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) { + WL_ERROR("wl%d: %s: dma_txreset[%d]: cannot stop dma\n", + wlc_hw->unit, __func__, i); + } + + if ((wlc_hw->di[RX_FIFO]) + && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) { + WL_ERROR("wl%d: %s: dma_rxreset[%d]: cannot stop dma\n", + wlc_hw->unit, __func__, RX_FIFO); + } + if (D11REV_IS(wlc_hw->corerev, 4) + && wlc_hw->di[RX_TXSTATUS_FIFO] + && (!wlc_dma_rxreset(wlc_hw, RX_TXSTATUS_FIFO))) { + WL_ERROR("wl%d: %s: dma_rxreset[%d]: cannot stop dma\n", + wlc_hw->unit, __func__, RX_TXSTATUS_FIFO); + } + } + /* if noreset, just stop the psm and return */ + if (wlc_hw->noreset) { + wlc_hw->wlc->macintstatus = 0; /* skip wl_dpc after down */ + wlc_bmac_mctrl(wlc_hw, MCTL_PSM_RUN | MCTL_EN_MAC, 0); + return; + } + + if (D11REV_LE(wlc_hw->corerev, 11)) + resetbits |= SICF_PCLKE; + + /* + * corerev >= 18, mac no longer enables phyclk automatically when driver accesses phyreg + * throughput mac, AND phy_reset is skipped at early stage when band->pi is invalid + * need to enable PHY CLK + */ + if (D11REV_GE(wlc_hw->corerev, 18)) + flags |= SICF_PCLKE; + + /* reset the core + * In chips with PMU, the fastclk request goes through d11 core reg 0x1e0, which + * is cleared by the core_reset. have to re-request it. + * This adds some delay and we can optimize it by also requesting fastclk through + * chipcommon during this period if necessary. But that has to work coordinate + * with other driver like mips/arm since they may touch chipcommon as well. + */ + wlc_hw->clk = false; + si_core_reset(wlc_hw->sih, flags, resetbits); + wlc_hw->clk = true; + if (wlc_hw->band && wlc_hw->band->pi) + wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true); + + wlc_mctrl_reset(wlc_hw); + + if (PMUCTL_ENAB(wlc_hw->sih)) + wlc_clkctl_clk(wlc_hw, CLK_FAST); + + wlc_bmac_phy_reset(wlc_hw); + + /* turn on PHY_PLL */ + wlc_bmac_core_phypll_ctl(wlc_hw, true); + + /* clear sw intstatus */ + wlc_hw->wlc->macintstatus = 0; + + /* restore the clk setting */ + if (!fastclk) + wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); +} + +/* If the ucode that supports corerev 5 is used for corerev 9 and above, + * txfifo sizes needs to be modified(increased) since the newer cores + * have more memory. + */ +static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw) +{ + d11regs_t *regs = wlc_hw->regs; + u16 fifo_nu; + u16 txfifo_startblk = TXFIFO_START_BLK, txfifo_endblk; + u16 txfifo_def, txfifo_def1; + u16 txfifo_cmd; + struct osl_info *osh; + + if (D11REV_LT(wlc_hw->corerev, 9)) + goto exit; + + /* tx fifos start at TXFIFO_START_BLK from the Base address */ + txfifo_startblk = TXFIFO_START_BLK; + + osh = wlc_hw->osh; + + /* sequence of operations: reset fifo, set fifo size, reset fifo */ + for (fifo_nu = 0; fifo_nu < NFIFO; fifo_nu++) { + + txfifo_endblk = txfifo_startblk + wlc_hw->xmtfifo_sz[fifo_nu]; + txfifo_def = (txfifo_startblk & 0xff) | + (((txfifo_endblk - 1) & 0xff) << TXFIFO_FIFOTOP_SHIFT); + txfifo_def1 = ((txfifo_startblk >> 8) & 0x1) | + ((((txfifo_endblk - + 1) >> 8) & 0x1) << TXFIFO_FIFOTOP_SHIFT); + txfifo_cmd = + TXFIFOCMD_RESET_MASK | (fifo_nu << TXFIFOCMD_FIFOSEL_SHIFT); + + W_REG(osh, ®s->xmtfifocmd, txfifo_cmd); + W_REG(osh, ®s->xmtfifodef, txfifo_def); + if (D11REV_GE(wlc_hw->corerev, 16)) + W_REG(osh, ®s->xmtfifodef1, txfifo_def1); + + W_REG(osh, ®s->xmtfifocmd, txfifo_cmd); + + txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu]; + } + exit: + /* need to propagate to shm location to be in sync since ucode/hw won't do this */ + wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE0, + wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]); + wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE1, + wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]); + wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE2, + ((wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO] << 8) | wlc_hw-> + xmtfifo_sz[TX_AC_BK_FIFO])); + wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE3, + ((wlc_hw->xmtfifo_sz[TX_ATIM_FIFO] << 8) | wlc_hw-> + xmtfifo_sz[TX_BCMC_FIFO])); +} + +/* d11 core init + * reset PSM + * download ucode/PCM + * let ucode run to suspended + * download ucode inits + * config other core registers + * init dma + */ +static void wlc_coreinit(struct wlc_info *wlc) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + d11regs_t *regs; + u32 sflags; + uint bcnint_us; + uint i = 0; + bool fifosz_fixup = false; + struct osl_info *osh; + int err = 0; + u16 buf[NFIFO]; + + regs = wlc_hw->regs; + osh = wlc_hw->osh; + + WL_TRACE("wl%d: wlc_coreinit\n", wlc_hw->unit); + + /* reset PSM */ + wlc_bmac_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE)); + + wlc_ucode_download(wlc_hw); + /* + * FIFOSZ fixup + * 1) core5-9 use ucode 5 to save space since the PSM is the same + * 2) newer chips, driver wants to controls the fifo allocation + */ + if (D11REV_GE(wlc_hw->corerev, 4)) + fifosz_fixup = true; + + /* let the PSM run to the suspended state, set mode to BSS STA */ + W_REG(osh, ®s->macintstatus, -1); + wlc_bmac_mctrl(wlc_hw, ~0, + (MCTL_IHR_EN | MCTL_INFRA | MCTL_PSM_RUN | MCTL_WAKE)); + + /* wait for ucode to self-suspend after auto-init */ + SPINWAIT(((R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD) == 0), + 1000 * 1000); + if ((R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD) == 0) + WL_ERROR("wl%d: wlc_coreinit: ucode did not self-suspend!\n", + wlc_hw->unit); + + wlc_gpio_init(wlc); + + sflags = si_core_sflags(wlc_hw->sih, 0, 0); + + if (D11REV_IS(wlc_hw->corerev, 23)) { + if (WLCISNPHY(wlc_hw->band)) + wlc_write_inits(wlc_hw, d11n0initvals16); + else + WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); + } else if (D11REV_IS(wlc_hw->corerev, 24)) { + if (WLCISLCNPHY(wlc_hw->band)) { + wlc_write_inits(wlc_hw, d11lcn0initvals24); + } else { + WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); + } + } else { + WL_ERROR("%s: wl%d: unsupported corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); + } + + /* For old ucode, txfifo sizes needs to be modified(increased) for Corerev >= 9 */ + if (fifosz_fixup == true) { + wlc_corerev_fifofixup(wlc_hw); + } + + /* check txfifo allocations match between ucode and driver */ + buf[TX_AC_BE_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE0); + if (buf[TX_AC_BE_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]) { + i = TX_AC_BE_FIFO; + err = -1; + } + buf[TX_AC_VI_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE1); + if (buf[TX_AC_VI_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]) { + i = TX_AC_VI_FIFO; + err = -1; + } + buf[TX_AC_BK_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE2); + buf[TX_AC_VO_FIFO] = (buf[TX_AC_BK_FIFO] >> 8) & 0xff; + buf[TX_AC_BK_FIFO] &= 0xff; + if (buf[TX_AC_BK_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BK_FIFO]) { + i = TX_AC_BK_FIFO; + err = -1; + } + if (buf[TX_AC_VO_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO]) { + i = TX_AC_VO_FIFO; + err = -1; + } + buf[TX_BCMC_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE3); + buf[TX_ATIM_FIFO] = (buf[TX_BCMC_FIFO] >> 8) & 0xff; + buf[TX_BCMC_FIFO] &= 0xff; + if (buf[TX_BCMC_FIFO] != wlc_hw->xmtfifo_sz[TX_BCMC_FIFO]) { + i = TX_BCMC_FIFO; + err = -1; + } + if (buf[TX_ATIM_FIFO] != wlc_hw->xmtfifo_sz[TX_ATIM_FIFO]) { + i = TX_ATIM_FIFO; + err = -1; + } + if (err != 0) { + WL_ERROR("wlc_coreinit: txfifo mismatch: ucode size %d driver size %d index %d\n", + buf[i], wlc_hw->xmtfifo_sz[i], i); + /* DO NOT ASSERT corerev < 4 even there is a mismatch + * shmem, since driver don't overwrite those chip and + * ucode initialize data will be used. + */ + if (D11REV_GE(wlc_hw->corerev, 4)) + ASSERT(0); + } + + /* make sure we can still talk to the mac */ + ASSERT(R_REG(osh, ®s->maccontrol) != 0xffffffff); + + /* band-specific inits done by wlc_bsinit() */ + + /* Set up frame burst size and antenna swap threshold init values */ + wlc_bmac_write_shm(wlc_hw, M_MBURST_SIZE, MAXTXFRAMEBURST); + wlc_bmac_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT); + + /* enable one rx interrupt per received frame */ + W_REG(osh, ®s->intrcvlazy[0], (1 << IRL_FC_SHIFT)); + if (D11REV_IS(wlc_hw->corerev, 4)) + W_REG(osh, ®s->intrcvlazy[3], (1 << IRL_FC_SHIFT)); + + /* set the station mode (BSS STA) */ + wlc_bmac_mctrl(wlc_hw, + (MCTL_INFRA | MCTL_DISCARD_PMQ | MCTL_AP), + (MCTL_INFRA | MCTL_DISCARD_PMQ)); + + /* set up Beacon interval */ + bcnint_us = 0x8000 << 10; + W_REG(osh, ®s->tsf_cfprep, (bcnint_us << CFPREP_CBI_SHIFT)); + W_REG(osh, ®s->tsf_cfpstart, bcnint_us); + W_REG(osh, ®s->macintstatus, MI_GP1); + + /* write interrupt mask */ + W_REG(osh, ®s->intctrlregs[RX_FIFO].intmask, DEF_RXINTMASK); + if (D11REV_IS(wlc_hw->corerev, 4)) + W_REG(osh, ®s->intctrlregs[RX_TXSTATUS_FIFO].intmask, + DEF_RXINTMASK); + + /* allow the MAC to control the PHY clock (dynamic on/off) */ + wlc_bmac_macphyclk_set(wlc_hw, ON); + + /* program dynamic clock control fast powerup delay register */ + if (D11REV_GT(wlc_hw->corerev, 4)) { + wlc->fastpwrup_dly = si_clkctl_fast_pwrup_delay(wlc_hw->sih); + W_REG(osh, ®s->scc_fastpwrup_dly, wlc->fastpwrup_dly); + } + + /* tell the ucode the corerev */ + wlc_bmac_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev); + + /* tell the ucode MAC capabilities */ + if (D11REV_GE(wlc_hw->corerev, 13)) { + wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_L, + (u16) (wlc_hw->machwcap & 0xffff)); + wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_H, + (u16) ((wlc_hw-> + machwcap >> 16) & 0xffff)); + } + + /* write retry limits to SCR, this done after PSM init */ + W_REG(osh, ®s->objaddr, OBJADDR_SCR_SEL | S_DOT11_SRC_LMT); + (void)R_REG(osh, ®s->objaddr); + W_REG(osh, ®s->objdata, wlc_hw->SRL); + W_REG(osh, ®s->objaddr, OBJADDR_SCR_SEL | S_DOT11_LRC_LMT); + (void)R_REG(osh, ®s->objaddr); + W_REG(osh, ®s->objdata, wlc_hw->LRL); + + /* write rate fallback retry limits */ + wlc_bmac_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL); + wlc_bmac_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL); + + if (D11REV_GE(wlc_hw->corerev, 16)) { + AND_REG(osh, ®s->ifs_ctl, 0x0FFF); + W_REG(osh, ®s->ifs_aifsn, EDCF_AIFSN_MIN); + } + + /* dma initializations */ + wlc->txpend16165war = 0; + + /* init the tx dma engines */ + for (i = 0; i < NFIFO; i++) { + if (wlc_hw->di[i]) + dma_txinit(wlc_hw->di[i]); + } + + /* init the rx dma engine(s) and post receive buffers */ + dma_rxinit(wlc_hw->di[RX_FIFO]); + dma_rxfill(wlc_hw->di[RX_FIFO]); + if (D11REV_IS(wlc_hw->corerev, 4)) { + dma_rxinit(wlc_hw->di[RX_TXSTATUS_FIFO]); + dma_rxfill(wlc_hw->di[RX_TXSTATUS_FIFO]); + } +} + +/* This function is used for changing the tsf frac register + * If spur avoidance mode is off, the mac freq will be 80/120/160Mhz + * If spur avoidance mode is on1, the mac freq will be 82/123/164Mhz + * If spur avoidance mode is on2, the mac freq will be 84/126/168Mhz + * HTPHY Formula is 2^26/freq(MHz) e.g. + * For spuron2 - 126MHz -> 2^26/126 = 532610.0 + * - 532610 = 0x82082 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x2082 + * For spuron: 123MHz -> 2^26/123 = 545600.5 + * - 545601 = 0x85341 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x5341 + * For spur off: 120MHz -> 2^26/120 = 559240.5 + * - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889 + */ + +void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode) +{ + d11regs_t *regs; + struct osl_info *osh; + regs = wlc_hw->regs; + osh = wlc_hw->osh; + + if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || + (wlc_hw->sih->chip == BCM43225_CHIP_ID)) { + if (spurmode == WL_SPURAVOID_ON2) { /* 126Mhz */ + W_REG(osh, ®s->tsf_clk_frac_l, 0x2082); + W_REG(osh, ®s->tsf_clk_frac_h, 0x8); + } else if (spurmode == WL_SPURAVOID_ON1) { /* 123Mhz */ + W_REG(osh, ®s->tsf_clk_frac_l, 0x5341); + W_REG(osh, ®s->tsf_clk_frac_h, 0x8); + } else { /* 120Mhz */ + W_REG(osh, ®s->tsf_clk_frac_l, 0x8889); + W_REG(osh, ®s->tsf_clk_frac_h, 0x8); + } + } else if (WLCISLCNPHY(wlc_hw->band)) { + if (spurmode == WL_SPURAVOID_ON1) { /* 82Mhz */ + W_REG(osh, ®s->tsf_clk_frac_l, 0x7CE0); + W_REG(osh, ®s->tsf_clk_frac_h, 0xC); + } else { /* 80Mhz */ + W_REG(osh, ®s->tsf_clk_frac_l, 0xCCCD); + W_REG(osh, ®s->tsf_clk_frac_h, 0xC); + } + } +} + +/* Initialize GPIOs that are controlled by D11 core */ +static void wlc_gpio_init(struct wlc_info *wlc) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + d11regs_t *regs; + u32 gc, gm; + struct osl_info *osh; + + regs = wlc_hw->regs; + osh = wlc_hw->osh; + + /* use GPIO select 0 to get all gpio signals from the gpio out reg */ + wlc_bmac_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0); + + /* + * Common GPIO setup: + * G0 = LED 0 = WLAN Activity + * G1 = LED 1 = WLAN 2.4 GHz Radio State + * G2 = LED 2 = WLAN 5 GHz Radio State + * G4 = radio disable input (HI enabled, LO disabled) + */ + + gc = gm = 0; + + /* Allocate GPIOs for mimo antenna diversity feature */ + if (WLANTSEL_ENAB(wlc)) { + if (wlc_hw->antsel_type == ANTSEL_2x3) { + /* Enable antenna diversity, use 2x3 mode */ + wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, + MHF3_ANTSEL_EN, WLC_BAND_ALL); + wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, + MHF3_ANTSEL_MODE, WLC_BAND_ALL); + + /* init superswitch control */ + wlc_phy_antsel_init(wlc_hw->band->pi, false); + + } else if (wlc_hw->antsel_type == ANTSEL_2x4) { + ASSERT((gm & BOARD_GPIO_12) == 0); + gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13); + /* The board itself is powered by these GPIOs (when not sending pattern) + * So set them high + */ + OR_REG(osh, ®s->psm_gpio_oe, + (BOARD_GPIO_12 | BOARD_GPIO_13)); + OR_REG(osh, ®s->psm_gpio_out, + (BOARD_GPIO_12 | BOARD_GPIO_13)); + + /* Enable antenna diversity, use 2x4 mode */ + wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, + MHF3_ANTSEL_EN, WLC_BAND_ALL); + wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0, + WLC_BAND_ALL); + + /* Configure the desired clock to be 4Mhz */ + wlc_bmac_write_shm(wlc_hw, M_ANTSEL_CLKDIV, + ANTSEL_CLKDIV_4MHZ); + } + } + /* gpio 9 controls the PA. ucode is responsible for wiggling out and oe */ + if (wlc_hw->boardflags & BFL_PACTRL) + gm |= gc |= BOARD_GPIO_PACTRL; + + /* apply to gpiocontrol register */ + si_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY); +} + +static void wlc_ucode_download(struct wlc_hw_info *wlc_hw) +{ + struct wlc_info *wlc; + wlc = wlc_hw->wlc; + + if (wlc_hw->ucode_loaded) + return; + + if (D11REV_IS(wlc_hw->corerev, 23)) { + if (WLCISNPHY(wlc_hw->band)) { + wlc_ucode_write(wlc_hw, bcm43xx_16_mimo, + bcm43xx_16_mimosz); + wlc_hw->ucode_loaded = true; + } else + WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); + } else if (D11REV_IS(wlc_hw->corerev, 24)) { + if (WLCISLCNPHY(wlc_hw->band)) { + wlc_ucode_write(wlc_hw, bcm43xx_24_lcn, + bcm43xx_24_lcnsz); + wlc_hw->ucode_loaded = true; + } else { + WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); + } + } +} + +static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[], + const uint nbytes) { + struct osl_info *osh; + d11regs_t *regs = wlc_hw->regs; + uint i; + uint count; + + osh = wlc_hw->osh; + + WL_TRACE("wl%d: wlc_ucode_write\n", wlc_hw->unit); + + ASSERT(IS_ALIGNED(nbytes, sizeof(u32))); + + count = (nbytes / sizeof(u32)); + + W_REG(osh, ®s->objaddr, (OBJADDR_AUTO_INC | OBJADDR_UCM_SEL)); + (void)R_REG(osh, ®s->objaddr); + for (i = 0; i < count; i++) + W_REG(osh, ®s->objdata, ucode[i]); +} + +static void wlc_write_inits(struct wlc_hw_info *wlc_hw, const d11init_t *inits) +{ + int i; + struct osl_info *osh; + volatile u8 *base; + + WL_TRACE("wl%d: wlc_write_inits\n", wlc_hw->unit); + + osh = wlc_hw->osh; + base = (volatile u8 *)wlc_hw->regs; + + for (i = 0; inits[i].addr != 0xffff; i++) { + ASSERT((inits[i].size == 2) || (inits[i].size == 4)); + + if (inits[i].size == 2) + W_REG(osh, (u16 *)(base + inits[i].addr), + inits[i].value); + else if (inits[i].size == 4) + W_REG(osh, (u32 *)(base + inits[i].addr), + inits[i].value); + } +} + +static void wlc_ucode_txant_set(struct wlc_hw_info *wlc_hw) +{ + u16 phyctl; + u16 phytxant = wlc_hw->bmac_phytxant; + u16 mask = PHY_TXC_ANT_MASK; + + /* set the Probe Response frame phy control word */ + phyctl = wlc_bmac_read_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS); + phyctl = (phyctl & ~mask) | phytxant; + wlc_bmac_write_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS, phyctl); + + /* set the Response (ACK/CTS) frame phy control word */ + phyctl = wlc_bmac_read_shm(wlc_hw, M_RSP_PCTLWD); + phyctl = (phyctl & ~mask) | phytxant; + wlc_bmac_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl); +} + +void wlc_bmac_txant_set(struct wlc_hw_info *wlc_hw, u16 phytxant) +{ + /* update sw state */ + wlc_hw->bmac_phytxant = phytxant; + + /* push to ucode if up */ + if (!wlc_hw->up) + return; + wlc_ucode_txant_set(wlc_hw); + +} + +u16 wlc_bmac_get_txant(struct wlc_hw_info *wlc_hw) +{ + return (u16) wlc_hw->wlc->stf->txant; +} + +void wlc_bmac_antsel_type_set(struct wlc_hw_info *wlc_hw, u8 antsel_type) +{ + wlc_hw->antsel_type = antsel_type; + + /* Update the antsel type for phy module to use */ + wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type); +} + +void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw) +{ + bool fatal = false; + uint unit; + uint intstatus, idx; + d11regs_t *regs = wlc_hw->regs; + + unit = wlc_hw->unit; + + for (idx = 0; idx < NFIFO; idx++) { + /* read intstatus register and ignore any non-error bits */ + intstatus = + R_REG(wlc_hw->osh, + ®s->intctrlregs[idx].intstatus) & I_ERRORS; + if (!intstatus) + continue; + + WL_TRACE("wl%d: wlc_bmac_fifoerrors: intstatus%d 0x%x\n", + unit, idx, intstatus); + + if (intstatus & I_RO) { + WL_ERROR("wl%d: fifo %d: receive fifo overflow\n", + unit, idx); + WLCNTINCR(wlc_hw->wlc->pub->_cnt->rxoflo); + fatal = true; + } + + if (intstatus & I_PC) { + WL_ERROR("wl%d: fifo %d: descriptor error\n", + unit, idx); + WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmade); + fatal = true; + } + + if (intstatus & I_PD) { + WL_ERROR("wl%d: fifo %d: data error\n", unit, idx); + WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmada); + fatal = true; + } + + if (intstatus & I_DE) { + WL_ERROR("wl%d: fifo %d: descriptor protocol error\n", + unit, idx); + WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmape); + fatal = true; + } + + if (intstatus & I_RU) { + WL_ERROR("wl%d: fifo %d: receive descriptor underflow\n", + idx, unit); + WLCNTINCR(wlc_hw->wlc->pub->_cnt->rxuflo[idx]); + } + + if (intstatus & I_XU) { + WL_ERROR("wl%d: fifo %d: transmit fifo underflow\n", + idx, unit); + WLCNTINCR(wlc_hw->wlc->pub->_cnt->txuflo); + fatal = true; + } + + if (fatal) { + wlc_fatal_error(wlc_hw->wlc); /* big hammer */ + break; + } else + W_REG(wlc_hw->osh, ®s->intctrlregs[idx].intstatus, + intstatus); + } +} + +void wlc_intrson(struct wlc_info *wlc) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + ASSERT(wlc->defmacintmask); + wlc->macintmask = wlc->defmacintmask; + W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, wlc->macintmask); +} + +/* callback for siutils.c, which has only wlc handler, no wl + * they both check up, not only because there is no need to off/restore d11 interrupt + * but also because per-port code may require sync with valid interrupt. + */ + +static u32 wlc_wlintrsoff(struct wlc_info *wlc) +{ + if (!wlc->hw->up) + return 0; + + return wl_intrsoff(wlc->wl); +} + +static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask) +{ + if (!wlc->hw->up) + return; + + wl_intrsrestore(wlc->wl, macintmask); +} + +u32 wlc_intrsoff(struct wlc_info *wlc) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + u32 macintmask; + + if (!wlc_hw->clk) + return 0; + + macintmask = wlc->macintmask; /* isr can still happen */ + + W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, 0); + (void)R_REG(wlc_hw->osh, &wlc_hw->regs->macintmask); /* sync readback */ + udelay(1); /* ensure int line is no longer driven */ + wlc->macintmask = 0; + + /* return previous macintmask; resolve race between us and our isr */ + return wlc->macintstatus ? 0 : macintmask; +} + +void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + if (!wlc_hw->clk) + return; + + wlc->macintmask = macintmask; + W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, wlc->macintmask); +} + +void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool on, mbool flags) +{ + u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; + + if (on) { + /* suspend tx fifos */ + wlc_bmac_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO); + wlc_bmac_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO); + wlc_bmac_tx_fifo_suspend(wlc_hw, TX_AC_BK_FIFO); + wlc_bmac_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO); + + /* zero the address match register so we do not send ACKs */ + wlc_bmac_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, + null_ether_addr); + } else { + /* resume tx fifos */ + if (!wlc_hw->wlc->tx_suspended) { + wlc_bmac_tx_fifo_resume(wlc_hw, TX_DATA_FIFO); + } + wlc_bmac_tx_fifo_resume(wlc_hw, TX_CTL_FIFO); + wlc_bmac_tx_fifo_resume(wlc_hw, TX_AC_BK_FIFO); + wlc_bmac_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO); + + /* Restore address */ + wlc_bmac_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, + wlc_hw->etheraddr); + } + + wlc_phy_mute_upd(wlc_hw->band->pi, on, flags); + + if (on) + wlc_ucode_mute_override_set(wlc_hw); + else + wlc_ucode_mute_override_clear(wlc_hw); +} + +void wlc_bmac_set_deaf(struct wlc_hw_info *wlc_hw, bool user_flag) +{ + wlc_phy_set_deaf(wlc_hw->band->pi, user_flag); +} + +int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, uint *blocks) +{ + if (fifo >= NFIFO) + return BCME_RANGE; + + *blocks = wlc_hw->xmtfifo_sz[fifo]; + + return 0; +} + +int wlc_bmac_xmtfifo_sz_set(struct wlc_hw_info *wlc_hw, uint fifo, uint blocks) +{ + if (fifo >= NFIFO || blocks > 299) + return BCME_RANGE; + + /* BMAC_NOTE, change blocks to u16 */ + wlc_hw->xmtfifo_sz[fifo] = (u16) blocks; + + return 0; +} + +/* wlc_bmac_tx_fifo_suspended: + * Check the MAC's tx suspend status for a tx fifo. + * + * When the MAC acknowledges a tx suspend, it indicates that no more + * packets will be transmitted out the radio. This is independent of + * DMA channel suspension---the DMA may have finished suspending, or may still + * be pulling data into a tx fifo, by the time the MAC acks the suspend + * request. + */ +bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, uint tx_fifo) +{ + /* check that a suspend has been requested and is no longer pending */ + + /* + * for DMA mode, the suspend request is set in xmtcontrol of the DMA engine, + * and the tx fifo suspend at the lower end of the MAC is acknowledged in the + * chnstatus register. + * The tx fifo suspend completion is independent of the DMA suspend completion and + * may be acked before or after the DMA is suspended. + */ + if (dma_txsuspended(wlc_hw->di[tx_fifo]) && + (R_REG(wlc_hw->osh, &wlc_hw->regs->chnstatus) & + (1 << tx_fifo)) == 0) + return true; + + return false; +} + +void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo) +{ + u8 fifo = 1 << tx_fifo; + + /* Two clients of this code, 11h Quiet period and scanning. */ + + /* only suspend if not already suspended */ + if ((wlc_hw->suspended_fifos & fifo) == fifo) + return; + + /* force the core awake only if not already */ + if (wlc_hw->suspended_fifos == 0) + wlc_ucode_wake_override_set(wlc_hw, WLC_WAKE_OVERRIDE_TXFIFO); + + wlc_hw->suspended_fifos |= fifo; + + if (wlc_hw->di[tx_fifo]) { + /* Suspending AMPDU transmissions in the middle can cause underflow + * which may result in mismatch between ucode and driver + * so suspend the mac before suspending the FIFO + */ + if (WLC_PHY_11N_CAP(wlc_hw->band)) + wlc_suspend_mac_and_wait(wlc_hw->wlc); + + dma_txsuspend(wlc_hw->di[tx_fifo]); + + if (WLC_PHY_11N_CAP(wlc_hw->band)) + wlc_enable_mac(wlc_hw->wlc); + } +} + +void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo) +{ + /* BMAC_NOTE: WLC_TX_FIFO_ENAB is done in wlc_dpc() for DMA case but need to be done + * here for PIO otherwise the watchdog will catch the inconsistency and fire + */ + /* Two clients of this code, 11h Quiet period and scanning. */ + if (wlc_hw->di[tx_fifo]) + dma_txresume(wlc_hw->di[tx_fifo]); + + /* allow core to sleep again */ + if (wlc_hw->suspended_fifos == 0) + return; + else { + wlc_hw->suspended_fifos &= ~(1 << tx_fifo); + if (wlc_hw->suspended_fifos == 0) + wlc_ucode_wake_override_clear(wlc_hw, + WLC_WAKE_OVERRIDE_TXFIFO); + } +} + +/* + * Read and clear macintmask and macintstatus and intstatus registers. + * This routine should be called with interrupts off + * Return: + * -1 if DEVICEREMOVED(wlc) evaluates to true; + * 0 if the interrupt is not for us, or we are in some special cases; + * device interrupt status bits otherwise. + */ +static inline u32 wlc_intstatus(struct wlc_info *wlc, bool in_isr) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + d11regs_t *regs = wlc_hw->regs; + u32 macintstatus; + u32 intstatus_rxfifo, intstatus_txsfifo; + struct osl_info *osh; + + osh = wlc_hw->osh; + + /* macintstatus includes a DMA interrupt summary bit */ + macintstatus = R_REG(osh, ®s->macintstatus); + + WL_TRACE("wl%d: macintstatus: 0x%x\n", wlc_hw->unit, macintstatus); + + /* detect cardbus removed, in power down(suspend) and in reset */ + if (DEVICEREMOVED(wlc)) + return -1; + + /* DEVICEREMOVED succeeds even when the core is still resetting, + * handle that case here. + */ + if (macintstatus == 0xffffffff) + return 0; + + /* defer unsolicited interrupts */ + macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask); + + /* if not for us */ + if (macintstatus == 0) + return 0; + + /* interrupts are already turned off for CFE build + * Caution: For CFE Turning off the interrupts again has some undesired + * consequences + */ + /* turn off the interrupts */ + W_REG(osh, ®s->macintmask, 0); + (void)R_REG(osh, ®s->macintmask); /* sync readback */ + wlc->macintmask = 0; + + /* clear device interrupts */ + W_REG(osh, ®s->macintstatus, macintstatus); + + /* MI_DMAINT is indication of non-zero intstatus */ + if (macintstatus & MI_DMAINT) { + if (D11REV_IS(wlc_hw->corerev, 4)) { + intstatus_rxfifo = + R_REG(osh, ®s->intctrlregs[RX_FIFO].intstatus); + intstatus_txsfifo = + R_REG(osh, + ®s->intctrlregs[RX_TXSTATUS_FIFO]. + intstatus); + WL_TRACE("wl%d: intstatus_rxfifo 0x%x, intstatus_txsfifo 0x%x\n", + wlc_hw->unit, + intstatus_rxfifo, intstatus_txsfifo); + + /* defer unsolicited interrupt hints */ + intstatus_rxfifo &= DEF_RXINTMASK; + intstatus_txsfifo &= DEF_RXINTMASK; + + /* MI_DMAINT bit in macintstatus is indication of RX_FIFO interrupt */ + /* clear interrupt hints */ + if (intstatus_rxfifo) + W_REG(osh, + ®s->intctrlregs[RX_FIFO].intstatus, + intstatus_rxfifo); + else + macintstatus &= ~MI_DMAINT; + + /* MI_TFS bit in macintstatus is encoding of RX_TXSTATUS_FIFO interrupt */ + if (intstatus_txsfifo) { + W_REG(osh, + ®s->intctrlregs[RX_TXSTATUS_FIFO]. + intstatus, intstatus_txsfifo); + macintstatus |= MI_TFS; + } + } else { + /* + * For corerevs >= 5, only fifo interrupt enabled is I_RI in RX_FIFO. + * If MI_DMAINT is set, assume it is set and clear the interrupt. + */ + W_REG(osh, ®s->intctrlregs[RX_FIFO].intstatus, + DEF_RXINTMASK); + } + } + + return macintstatus; +} + +/* Update wlc->macintstatus and wlc->intstatus[]. */ +/* Return true if they are updated successfully. false otherwise */ +bool wlc_intrsupd(struct wlc_info *wlc) +{ + u32 macintstatus; + + ASSERT(wlc->macintstatus != 0); + + /* read and clear macintstatus and intstatus registers */ + macintstatus = wlc_intstatus(wlc, false); + + /* device is removed */ + if (macintstatus == 0xffffffff) + return false; + + /* update interrupt status in software */ + wlc->macintstatus |= macintstatus; + + return true; +} + +/* + * First-level interrupt processing. + * Return true if this was our interrupt, false otherwise. + * *wantdpc will be set to true if further wlc_dpc() processing is required, + * false otherwise. + */ +bool BCMFASTPATH wlc_isr(struct wlc_info *wlc, bool *wantdpc) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + u32 macintstatus; + + *wantdpc = false; + + if (!wlc_hw->up || !wlc->macintmask) + return false; + + /* read and clear macintstatus and intstatus registers */ + macintstatus = wlc_intstatus(wlc, true); + + if (macintstatus == 0xffffffff) + WL_ERROR("DEVICEREMOVED detected in the ISR code path\n"); + + /* it is not for us */ + if (macintstatus == 0) + return false; + + *wantdpc = true; + + /* save interrupt status bits */ + ASSERT(wlc->macintstatus == 0); + wlc->macintstatus = macintstatus; + + return true; + +} + +/* process tx completion events for corerev < 5 */ +static bool wlc_bmac_txstatus_corerev4(struct wlc_hw_info *wlc_hw) +{ + struct sk_buff *status_p; + tx_status_t *txs; + struct osl_info *osh; + bool fatal = false; + + WL_TRACE("wl%d: wlc_txstatusrecv\n", wlc_hw->unit); + + osh = wlc_hw->osh; + + while (!fatal && (status_p = dma_rx(wlc_hw->di[RX_TXSTATUS_FIFO]))) { + + txs = (tx_status_t *) status_p->data; + /* MAC uses little endian only */ + ltoh16_buf((void *)txs, sizeof(tx_status_t)); + + /* shift low bits for tx_status_t status compatibility */ + txs->status = (txs->status & ~TXS_COMPAT_MASK) + | (((txs->status & TXS_COMPAT_MASK) << TXS_COMPAT_SHIFT)); + + fatal = wlc_bmac_dotxstatus(wlc_hw, txs, 0); + + pkt_buf_free_skb(osh, status_p, false); + } + + if (fatal) + return true; + + /* post more rbufs */ + dma_rxfill(wlc_hw->di[RX_TXSTATUS_FIFO]); + + return false; +} + +static bool BCMFASTPATH +wlc_bmac_dotxstatus(struct wlc_hw_info *wlc_hw, tx_status_t *txs, u32 s2) +{ + /* discard intermediate indications for ucode with one legitimate case: + * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent + * tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts + * transmission count) + */ + if (!(txs->status & TX_STATUS_AMPDU) + && (txs->status & TX_STATUS_INTERMEDIATE)) { + return false; + } + + return wlc_dotxstatus(wlc_hw->wlc, txs, s2); +} + +/* process tx completion events in BMAC + * Return true if more tx status need to be processed. false otherwise. + */ +static bool BCMFASTPATH +wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal) +{ + bool morepending = false; + struct wlc_info *wlc = wlc_hw->wlc; + + WL_TRACE("wl%d: wlc_bmac_txstatus\n", wlc_hw->unit); + + if (D11REV_IS(wlc_hw->corerev, 4)) { + /* to retire soon */ + *fatal = wlc_bmac_txstatus_corerev4(wlc->hw); + + if (*fatal) + return 0; + } else { + /* corerev >= 5 */ + d11regs_t *regs; + struct osl_info *osh; + tx_status_t txstatus, *txs; + u32 s1, s2; + uint n = 0; + /* Param 'max_tx_num' indicates max. # tx status to process before break out. */ + uint max_tx_num = bound ? wlc->pub->tunables->txsbnd : -1; + + txs = &txstatus; + regs = wlc_hw->regs; + osh = wlc_hw->osh; + while (!(*fatal) + && (s1 = R_REG(osh, ®s->frmtxstatus)) & TXS_V) { + + if (s1 == 0xffffffff) { + WL_ERROR("wl%d: %s: dead chip\n", + wlc_hw->unit, __func__); + ASSERT(s1 != 0xffffffff); + return morepending; + } + + s2 = R_REG(osh, ®s->frmtxstatus2); + + txs->status = s1 & TXS_STATUS_MASK; + txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT; + txs->sequence = s2 & TXS_SEQ_MASK; + txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT; + txs->lasttxtime = 0; + + *fatal = wlc_bmac_dotxstatus(wlc_hw, txs, s2); + + /* !give others some time to run! */ + if (++n >= max_tx_num) + break; + } + + if (*fatal) + return 0; + + if (n >= max_tx_num) + morepending = true; + } + + if (!pktq_empty(&wlc->active_queue->q)) + wlc_send_q(wlc, wlc->active_queue); + + return morepending; +} + +void wlc_suspend_mac_and_wait(struct wlc_info *wlc) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + d11regs_t *regs = wlc_hw->regs; + u32 mc, mi; + struct osl_info *osh; + + WL_TRACE("wl%d: wlc_suspend_mac_and_wait: bandunit %d\n", + wlc_hw->unit, wlc_hw->band->bandunit); + + /* + * Track overlapping suspend requests + */ + wlc_hw->mac_suspend_depth++; + if (wlc_hw->mac_suspend_depth > 1) + return; + + osh = wlc_hw->osh; + + /* force the core awake */ + wlc_ucode_wake_override_set(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND); + + mc = R_REG(osh, ®s->maccontrol); + + if (mc == 0xffffffff) { + WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); + wl_down(wlc->wl); + return; + } + ASSERT(!(mc & MCTL_PSM_JMP_0)); + ASSERT(mc & MCTL_PSM_RUN); + ASSERT(mc & MCTL_EN_MAC); + + mi = R_REG(osh, ®s->macintstatus); + if (mi == 0xffffffff) { + WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); + wl_down(wlc->wl); + return; + } + ASSERT(!(mi & MI_MACSSPNDD)); + + wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, 0); + + SPINWAIT(!(R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD), + WLC_MAX_MAC_SUSPEND); + + if (!(R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD)) { + WL_ERROR("wl%d: wlc_suspend_mac_and_wait: waited %d uS and MI_MACSSPNDD is still not on.\n", + wlc_hw->unit, WLC_MAX_MAC_SUSPEND); + WL_ERROR("wl%d: psmdebug 0x%08x, phydebug 0x%08x, psm_brc 0x%04x\n", + wlc_hw->unit, + R_REG(osh, ®s->psmdebug), + R_REG(osh, ®s->phydebug), + R_REG(osh, ®s->psm_brc)); + } + + mc = R_REG(osh, ®s->maccontrol); + if (mc == 0xffffffff) { + WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); + wl_down(wlc->wl); + return; + } + ASSERT(!(mc & MCTL_PSM_JMP_0)); + ASSERT(mc & MCTL_PSM_RUN); + ASSERT(!(mc & MCTL_EN_MAC)); +} + +void wlc_enable_mac(struct wlc_info *wlc) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + d11regs_t *regs = wlc_hw->regs; + u32 mc, mi; + struct osl_info *osh; + + WL_TRACE("wl%d: wlc_enable_mac: bandunit %d\n", + wlc_hw->unit, wlc->band->bandunit); + + /* + * Track overlapping suspend requests + */ + ASSERT(wlc_hw->mac_suspend_depth > 0); + wlc_hw->mac_suspend_depth--; + if (wlc_hw->mac_suspend_depth > 0) + return; + + osh = wlc_hw->osh; + + mc = R_REG(osh, ®s->maccontrol); + ASSERT(!(mc & MCTL_PSM_JMP_0)); + ASSERT(!(mc & MCTL_EN_MAC)); + ASSERT(mc & MCTL_PSM_RUN); + + wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC); + W_REG(osh, ®s->macintstatus, MI_MACSSPNDD); + + mc = R_REG(osh, ®s->maccontrol); + ASSERT(!(mc & MCTL_PSM_JMP_0)); + ASSERT(mc & MCTL_EN_MAC); + ASSERT(mc & MCTL_PSM_RUN); + + mi = R_REG(osh, ®s->macintstatus); + ASSERT(!(mi & MI_MACSSPNDD)); + + wlc_ucode_wake_override_clear(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND); +} + +void wlc_bmac_ifsctl_edcrs_set(struct wlc_hw_info *wlc_hw, bool abie, bool isht) +{ + if (!(WLCISNPHY(wlc_hw->band) && (D11REV_GE(wlc_hw->corerev, 16)))) + return; + + if (isht) { + if (WLCISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 3)) { + AND_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, + ~IFS_CTL1_EDCRS); + } + } else { + /* enable EDCRS for non-11n association */ + OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, IFS_CTL1_EDCRS); + } + + if (WLCISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3)) { + if (CHSPEC_IS20(wlc_hw->chanspec)) { + /* 20 mhz, use 20U ED only */ + OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, + IFS_CTL1_EDCRS); + AND_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, + ~IFS_CTL1_EDCRS_20L); + AND_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, + ~IFS_CTL1_EDCRS_40); + } else { + /* 40 mhz, use 20U 20L and 40 ED */ + OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, + IFS_CTL1_EDCRS); + OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, + IFS_CTL1_EDCRS_20L); + OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, + IFS_CTL1_EDCRS_40); + } + } +} + +static void wlc_upd_ofdm_pctl1_table(struct wlc_hw_info *wlc_hw) +{ + u8 rate; + u8 rates[8] = { + WLC_RATE_6M, WLC_RATE_9M, WLC_RATE_12M, WLC_RATE_18M, + WLC_RATE_24M, WLC_RATE_36M, WLC_RATE_48M, WLC_RATE_54M + }; + u16 entry_ptr; + u16 pctl1; + uint i; + + if (!WLC_PHY_11N_CAP(wlc_hw->band)) + return; + + /* walk the phy rate table and update the entries */ + for (i = 0; i < ARRAY_SIZE(rates); i++) { + rate = rates[i]; + + entry_ptr = wlc_bmac_ofdm_ratetable_offset(wlc_hw, rate); + + /* read the SHM Rate Table entry OFDM PCTL1 values */ + pctl1 = + wlc_bmac_read_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS); + + /* modify the value */ + pctl1 &= ~PHY_TXC1_MODE_MASK; + pctl1 |= (wlc_hw->hw_stf_ss_opmode << PHY_TXC1_MODE_SHIFT); + + /* Update the SHM Rate Table entry OFDM PCTL1 values */ + wlc_bmac_write_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS, + pctl1); + } +} + +static u16 wlc_bmac_ofdm_ratetable_offset(struct wlc_hw_info *wlc_hw, u8 rate) +{ + uint i; + u8 plcp_rate = 0; + struct plcp_signal_rate_lookup { + u8 rate; + u8 signal_rate; + }; + /* OFDM RATE sub-field of PLCP SIGNAL field, per 802.11 sec 17.3.4.1 */ + const struct plcp_signal_rate_lookup rate_lookup[] = { + {WLC_RATE_6M, 0xB}, + {WLC_RATE_9M, 0xF}, + {WLC_RATE_12M, 0xA}, + {WLC_RATE_18M, 0xE}, + {WLC_RATE_24M, 0x9}, + {WLC_RATE_36M, 0xD}, + {WLC_RATE_48M, 0x8}, + {WLC_RATE_54M, 0xC} + }; + + for (i = 0; i < ARRAY_SIZE(rate_lookup); i++) { + if (rate == rate_lookup[i].rate) { + plcp_rate = rate_lookup[i].signal_rate; + break; + } + } + + /* Find the SHM pointer to the rate table entry by looking in the + * Direct-map Table + */ + return 2 * wlc_bmac_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2)); +} + +void wlc_bmac_band_stf_ss_set(struct wlc_hw_info *wlc_hw, u8 stf_mode) +{ + wlc_hw->hw_stf_ss_opmode = stf_mode; + + if (wlc_hw->clk) + wlc_upd_ofdm_pctl1_table(wlc_hw); +} + +void BCMFASTPATH +wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr, + u32 *tsf_h_ptr) +{ + d11regs_t *regs = wlc_hw->regs; + + /* read the tsf timer low, then high to get an atomic read */ + *tsf_l_ptr = R_REG(wlc_hw->osh, ®s->tsf_timerlow); + *tsf_h_ptr = R_REG(wlc_hw->osh, ®s->tsf_timerhigh); + + return; +} + +bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) +{ + d11regs_t *regs; + u32 w, val; + volatile u16 *reg16; + struct osl_info *osh; + + WL_TRACE("wl%d: validate_chip_access\n", wlc_hw->unit); + + regs = wlc_hw->regs; + osh = wlc_hw->osh; + + /* Validate dchip register access */ + + W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(osh, ®s->objaddr); + w = R_REG(osh, ®s->objdata); + + /* Can we write and read back a 32bit register? */ + W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(osh, ®s->objaddr); + W_REG(osh, ®s->objdata, (u32) 0xaa5555aa); + + W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(osh, ®s->objaddr); + val = R_REG(osh, ®s->objdata); + if (val != (u32) 0xaa5555aa) { + WL_ERROR("wl%d: validate_chip_access: SHM = 0x%x, expected 0xaa5555aa\n", + wlc_hw->unit, val); + return false; + } + + W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(osh, ®s->objaddr); + W_REG(osh, ®s->objdata, (u32) 0x55aaaa55); + + W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(osh, ®s->objaddr); + val = R_REG(osh, ®s->objdata); + if (val != (u32) 0x55aaaa55) { + WL_ERROR("wl%d: validate_chip_access: SHM = 0x%x, expected 0x55aaaa55\n", + wlc_hw->unit, val); + return false; + } + + W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(osh, ®s->objaddr); + W_REG(osh, ®s->objdata, w); + + if (D11REV_LT(wlc_hw->corerev, 11)) { + /* if 32 bit writes are split into 16 bit writes, are they in the correct order + * for our interface, low to high + */ + reg16 = (volatile u16 *)®s->tsf_cfpstart; + + /* write the CFPStart register low half explicitly, starting a buffered write */ + W_REG(osh, reg16, 0xAAAA); + + /* Write a 32 bit value to CFPStart to test the 16 bit split order. + * If the low 16 bits are written first, followed by the high 16 bits then the + * 32 bit value 0xCCCCBBBB should end up in the register. + * If the order is reversed, then the write to the high half will trigger a buffered + * write of 0xCCCCAAAA. + * If the bus is 32 bits, then this is not much of a test, and the reg should + * have the correct value 0xCCCCBBBB. + */ + W_REG(osh, ®s->tsf_cfpstart, 0xCCCCBBBB); + + /* verify with the 16 bit registers that have no side effects */ + val = R_REG(osh, ®s->tsf_cfpstrt_l); + if (val != (uint) 0xBBBB) { + WL_ERROR("wl%d: validate_chip_access: tsf_cfpstrt_l = 0x%x, expected 0x%x\n", + wlc_hw->unit, val, 0xBBBB); + return false; + } + val = R_REG(osh, ®s->tsf_cfpstrt_h); + if (val != (uint) 0xCCCC) { + WL_ERROR("wl%d: validate_chip_access: tsf_cfpstrt_h = 0x%x, expected 0x%x\n", + wlc_hw->unit, val, 0xCCCC); + return false; + } + + } + + /* clear CFPStart */ + W_REG(osh, ®s->tsf_cfpstart, 0); + + w = R_REG(osh, ®s->maccontrol); + if ((w != (MCTL_IHR_EN | MCTL_WAKE)) && + (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) { + WL_ERROR("wl%d: validate_chip_access: maccontrol = 0x%x, expected 0x%x or 0x%x\n", + wlc_hw->unit, w, + (MCTL_IHR_EN | MCTL_WAKE), + (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE)); + return false; + } + + return true; +} + +#define PHYPLL_WAIT_US 100000 + +void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on) +{ + d11regs_t *regs; + struct osl_info *osh; + u32 tmp; + + WL_TRACE("wl%d: wlc_bmac_core_phypll_ctl\n", wlc_hw->unit); + + tmp = 0; + regs = wlc_hw->regs; + osh = wlc_hw->osh; + + if (D11REV_LE(wlc_hw->corerev, 16) || D11REV_IS(wlc_hw->corerev, 20)) + return; + + if (on) { + if ((wlc_hw->sih->chip == BCM4313_CHIP_ID)) { + OR_REG(osh, ®s->clk_ctl_st, + (CCS_ERSRC_REQ_HT | CCS_ERSRC_REQ_D11PLL | + CCS_ERSRC_REQ_PHYPLL)); + SPINWAIT((R_REG(osh, ®s->clk_ctl_st) & + (CCS_ERSRC_AVAIL_HT)) != (CCS_ERSRC_AVAIL_HT), + PHYPLL_WAIT_US); + + tmp = R_REG(osh, ®s->clk_ctl_st); + if ((tmp & (CCS_ERSRC_AVAIL_HT)) != + (CCS_ERSRC_AVAIL_HT)) { + WL_ERROR("%s: turn on PHY PLL failed\n", + __func__); + ASSERT(0); + } + } else { + OR_REG(osh, ®s->clk_ctl_st, + (CCS_ERSRC_REQ_D11PLL | CCS_ERSRC_REQ_PHYPLL)); + SPINWAIT((R_REG(osh, ®s->clk_ctl_st) & + (CCS_ERSRC_AVAIL_D11PLL | + CCS_ERSRC_AVAIL_PHYPLL)) != + (CCS_ERSRC_AVAIL_D11PLL | + CCS_ERSRC_AVAIL_PHYPLL), PHYPLL_WAIT_US); + + tmp = R_REG(osh, ®s->clk_ctl_st); + if ((tmp & + (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) + != + (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) { + WL_ERROR("%s: turn on PHY PLL failed\n", + __func__); + ASSERT(0); + } + } + } else { + /* Since the PLL may be shared, other cores can still be requesting it; + * so we'll deassert the request but not wait for status to comply. + */ + AND_REG(osh, ®s->clk_ctl_st, ~CCS_ERSRC_REQ_PHYPLL); + tmp = R_REG(osh, ®s->clk_ctl_st); + } +} + +void wlc_coredisable(struct wlc_hw_info *wlc_hw) +{ + bool dev_gone; + + WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); + + ASSERT(!wlc_hw->up); + + dev_gone = DEVICEREMOVED(wlc_hw->wlc); + + if (dev_gone) + return; + + if (wlc_hw->noreset) + return; + + /* radio off */ + wlc_phy_switch_radio(wlc_hw->band->pi, OFF); + + /* turn off analog core */ + wlc_phy_anacore(wlc_hw->band->pi, OFF); + + /* turn off PHYPLL to save power */ + wlc_bmac_core_phypll_ctl(wlc_hw, false); + + /* No need to set wlc->pub->radio_active = OFF + * because this function needs down capability and + * radio_active is designed for BCMNODOWN. + */ + + /* remove gpio controls */ + if (wlc_hw->ucode_dbgsel) + si_gpiocontrol(wlc_hw->sih, ~0, 0, GPIO_DRV_PRIORITY); + + wlc_hw->clk = false; + si_core_disable(wlc_hw->sih, 0); + wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); +} + +/* power both the pll and external oscillator on/off */ +void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want) +{ + WL_TRACE("wl%d: wlc_bmac_xtal: want %d\n", wlc_hw->unit, want); + + /* dont power down if plldown is false or we must poll hw radio disable */ + if (!want && wlc_hw->pllreq) + return; + + if (wlc_hw->sih) + si_clkctl_xtal(wlc_hw->sih, XTAL | PLL, want); + + wlc_hw->sbclk = want; + if (!wlc_hw->sbclk) { + wlc_hw->clk = false; + if (wlc_hw->band && wlc_hw->band->pi) + wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); + } +} + +static void wlc_flushqueues(struct wlc_info *wlc) +{ + struct wlc_hw_info *wlc_hw = wlc->hw; + uint i; + + wlc->txpend16165war = 0; + + /* free any posted tx packets */ + for (i = 0; i < NFIFO; i++) + if (wlc_hw->di[i]) { + dma_txreclaim(wlc_hw->di[i], HNDDMA_RANGE_ALL); + TXPKTPENDCLR(wlc, i); + WL_TRACE("wlc_flushqueues: pktpend fifo %d cleared\n", + i); + } + + /* free any posted rx packets */ + dma_rxreclaim(wlc_hw->di[RX_FIFO]); + if (D11REV_IS(wlc_hw->corerev, 4)) + dma_rxreclaim(wlc_hw->di[RX_TXSTATUS_FIFO]); +} + +u16 wlc_bmac_read_shm(struct wlc_hw_info *wlc_hw, uint offset) +{ + return wlc_bmac_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL); +} + +void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v) +{ + wlc_bmac_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL); +} + +/* Set a range of shared memory to a value. + * SHM 'offset' needs to be an even address and + * Buffer length 'len' must be an even number of bytes + */ +void wlc_bmac_set_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v, int len) +{ + int i; + + /* offset and len need to be even */ + ASSERT((offset & 1) == 0); + ASSERT((len & 1) == 0); + + if (len <= 0) + return; + + for (i = 0; i < len; i += 2) { + wlc_bmac_write_objmem(wlc_hw, offset + i, v, OBJADDR_SHM_SEL); + } +} + +static u16 +wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, u32 sel) +{ + d11regs_t *regs = wlc_hw->regs; + volatile u16 *objdata_lo = (volatile u16 *)®s->objdata; + volatile u16 *objdata_hi = objdata_lo + 1; + u16 v; + + ASSERT((offset & 1) == 0); + + W_REG(wlc_hw->osh, ®s->objaddr, sel | (offset >> 2)); + (void)R_REG(wlc_hw->osh, ®s->objaddr); + if (offset & 2) { + v = R_REG(wlc_hw->osh, objdata_hi); + } else { + v = R_REG(wlc_hw->osh, objdata_lo); + } + + return v; +} + +static void +wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset, u16 v, u32 sel) +{ + d11regs_t *regs = wlc_hw->regs; + volatile u16 *objdata_lo = (volatile u16 *)®s->objdata; + volatile u16 *objdata_hi = objdata_lo + 1; + + ASSERT((offset & 1) == 0); + + W_REG(wlc_hw->osh, ®s->objaddr, sel | (offset >> 2)); + (void)R_REG(wlc_hw->osh, ®s->objaddr); + if (offset & 2) { + W_REG(wlc_hw->osh, objdata_hi, v); + } else { + W_REG(wlc_hw->osh, objdata_lo, v); + } +} + +/* Copy a buffer to shared memory of specified type . + * SHM 'offset' needs to be an even address and + * Buffer length 'len' must be an even number of bytes + * 'sel' selects the type of memory + */ +void +wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw, uint offset, const void *buf, + int len, u32 sel) +{ + u16 v; + const u8 *p = (const u8 *)buf; + int i; + + /* offset and len need to be even */ + ASSERT((offset & 1) == 0); + ASSERT((len & 1) == 0); + + if (len <= 0) + return; + + for (i = 0; i < len; i += 2) { + v = p[i] | (p[i + 1] << 8); + wlc_bmac_write_objmem(wlc_hw, offset + i, v, sel); + } +} + +/* Copy a piece of shared memory of specified type to a buffer . + * SHM 'offset' needs to be an even address and + * Buffer length 'len' must be an even number of bytes + * 'sel' selects the type of memory + */ +void +wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset, void *buf, + int len, u32 sel) +{ + u16 v; + u8 *p = (u8 *) buf; + int i; + + /* offset and len need to be even */ + ASSERT((offset & 1) == 0); + ASSERT((len & 1) == 0); + + if (len <= 0) + return; + + for (i = 0; i < len; i += 2) { + v = wlc_bmac_read_objmem(wlc_hw, offset + i, sel); + p[i] = v & 0xFF; + p[i + 1] = (v >> 8) & 0xFF; + } +} + +void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, uint *len) +{ + WL_TRACE("wlc_bmac_copyfrom_vars, nvram vars totlen=%d\n", + wlc_hw->vars_size); + + *buf = wlc_hw->vars; + *len = wlc_hw->vars_size; +} + +void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL, u16 LRL) +{ + wlc_hw->SRL = SRL; + wlc_hw->LRL = LRL; + + /* write retry limit to SCR, shouldn't need to suspend */ + if (wlc_hw->up) { + W_REG(wlc_hw->osh, &wlc_hw->regs->objaddr, + OBJADDR_SCR_SEL | S_DOT11_SRC_LMT); + (void)R_REG(wlc_hw->osh, &wlc_hw->regs->objaddr); + W_REG(wlc_hw->osh, &wlc_hw->regs->objdata, wlc_hw->SRL); + W_REG(wlc_hw->osh, &wlc_hw->regs->objaddr, + OBJADDR_SCR_SEL | S_DOT11_LRC_LMT); + (void)R_REG(wlc_hw->osh, &wlc_hw->regs->objaddr); + W_REG(wlc_hw->osh, &wlc_hw->regs->objdata, wlc_hw->LRL); + } +} + +void wlc_bmac_set_noreset(struct wlc_hw_info *wlc_hw, bool noreset_flag) +{ + wlc_hw->noreset = noreset_flag; +} + +void wlc_bmac_set_ucode_loaded(struct wlc_hw_info *wlc_hw, bool ucode_loaded) +{ + wlc_hw->ucode_loaded = ucode_loaded; +} + +void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, mbool req_bit) +{ + ASSERT(req_bit); + + if (set) { + if (mboolisset(wlc_hw->pllreq, req_bit)) + return; + + mboolset(wlc_hw->pllreq, req_bit); + + if (mboolisset(wlc_hw->pllreq, WLC_PLLREQ_FLIP)) { + if (!wlc_hw->sbclk) { + wlc_bmac_xtal(wlc_hw, ON); + } + } + } else { + if (!mboolisset(wlc_hw->pllreq, req_bit)) + return; + + mboolclr(wlc_hw->pllreq, req_bit); + + if (mboolisset(wlc_hw->pllreq, WLC_PLLREQ_FLIP)) { + if (wlc_hw->sbclk) { + wlc_bmac_xtal(wlc_hw, OFF); + } + } + } + + return; +} + +void wlc_bmac_set_clk(struct wlc_hw_info *wlc_hw, bool on) +{ + if (on) { + /* power up pll and oscillator */ + wlc_bmac_xtal(wlc_hw, ON); + + /* enable core(s), ignore bandlocked + * Leave with the same band selected as we entered + */ + wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); + } else { + /* if already down, must skip the core disable */ + if (wlc_hw->clk) { + /* disable core(s), ignore bandlocked */ + wlc_coredisable(wlc_hw); + } + /* power down pll and oscillator */ + wlc_bmac_xtal(wlc_hw, OFF); + } +} + +/* this will be true for all ai chips */ +bool wlc_bmac_taclear(struct wlc_hw_info *wlc_hw, bool ta_ok) +{ + return true; +} + +/* Lower down relevant GPIOs like LED when going down w/o + * doing PCI config cycles or touching interrupts + */ +void wlc_gpio_fast_deinit(struct wlc_hw_info *wlc_hw) +{ + if ((wlc_hw == NULL) || (wlc_hw->sih == NULL)) + return; + + /* Only chips with internal bus or PCIE cores or certain PCI cores + * are able to switch cores w/o disabling interrupts + */ + if (!((wlc_hw->sih->bustype == SI_BUS) || + ((wlc_hw->sih->bustype == PCI_BUS) && + ((wlc_hw->sih->buscoretype == PCIE_CORE_ID) || + (wlc_hw->sih->buscorerev >= 13))))) + return; + + WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); + return; +} + +bool wlc_bmac_radio_hw(struct wlc_hw_info *wlc_hw, bool enable) +{ + /* Do not access Phy registers if core is not up */ + if (si_iscoreup(wlc_hw->sih) == false) + return false; + + if (enable) { + if (PMUCTL_ENAB(wlc_hw->sih)) { + AND_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, + ~CCS_FORCEHWREQOFF); + si_pmu_radio_enable(wlc_hw->sih, true); + } + + wlc_phy_anacore(wlc_hw->band->pi, ON); + wlc_phy_switch_radio(wlc_hw->band->pi, ON); + + /* resume d11 core */ + wlc_enable_mac(wlc_hw->wlc); + } else { + /* suspend d11 core */ + wlc_suspend_mac_and_wait(wlc_hw->wlc); + + wlc_phy_switch_radio(wlc_hw->band->pi, OFF); + wlc_phy_anacore(wlc_hw->band->pi, OFF); + + if (PMUCTL_ENAB(wlc_hw->sih)) { + si_pmu_radio_enable(wlc_hw->sih, false); + OR_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, + CCS_FORCEHWREQOFF); + } + } + + return true; +} + +u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate) +{ + u16 table_ptr; + u8 phy_rate, index; + + /* get the phy specific rate encoding for the PLCP SIGNAL field */ + /* XXX4321 fixup needed ? */ + if (IS_OFDM(rate)) + table_ptr = M_RT_DIRMAP_A; + else + table_ptr = M_RT_DIRMAP_B; + + /* for a given rate, the LS-nibble of the PLCP SIGNAL field is + * the index into the rate table. + */ + phy_rate = rate_info[rate] & RATE_MASK; + index = phy_rate & 0xf; + + /* Find the SHM pointer to the rate table entry by looking in the + * Direct-map Table + */ + return 2 * wlc_bmac_read_shm(wlc_hw, table_ptr + (index * 2)); +} + +void wlc_bmac_set_txpwr_percent(struct wlc_hw_info *wlc_hw, u8 val) +{ + wlc_phy_txpwr_percent_set(wlc_hw->band->pi, val); +} + +void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail) +{ + wlc_hw->antsel_avail = antsel_avail; +} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h new file mode 100644 index 000000000000..03ce9521d652 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* XXXXX this interface is under wlc.c by design + * http://hwnbu-twiki.broadcom.com/bin/view/Mwgroup/WlBmacDesign + * + * high driver files(e.g. wlc_ampdu.c etc) + * wlc.h/wlc.c + * wlc_bmac.h/wlc_bmac.c + * + * So don't include this in files other than wlc.c, wlc_bmac* wl_rte.c(dongle port) and wl_phy.c + * create wrappers in wlc.c if needed + */ + +/* Revision and other info required from BMAC driver for functioning of high ONLY driver */ +typedef struct wlc_bmac_revinfo { + uint vendorid; /* PCI vendor id */ + uint deviceid; /* device id of chip */ + + uint boardrev; /* version # of particular board */ + uint corerev; /* core revision */ + uint sromrev; /* srom revision */ + uint chiprev; /* chip revision */ + uint chip; /* chip number */ + uint chippkg; /* chip package */ + uint boardtype; /* board type */ + uint boardvendor; /* board vendor */ + uint bustype; /* SB_BUS, PCI_BUS */ + uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */ + uint buscorerev; /* buscore rev */ + u32 issim; /* chip is in simulation or emulation */ + + uint nbands; + + struct band_info { + uint bandunit; /* To match on both sides */ + uint bandtype; /* To match on both sides */ + uint radiorev; + uint phytype; + uint phyrev; + uint anarev; + uint radioid; + bool abgphy_encore; + } band[MAXBANDS]; +} wlc_bmac_revinfo_t; + +/* dup state between BMAC(struct wlc_hw_info) and HIGH(struct wlc_info) + driver */ +typedef struct wlc_bmac_state { + u32 machwcap; /* mac hw capibility */ + u32 preamble_ovr; /* preamble override */ +} wlc_bmac_state_t; + +enum { + IOV_BMAC_DIAG, + IOV_BMAC_SBGPIOTIMERVAL, + IOV_BMAC_SBGPIOOUT, + IOV_BMAC_CCGPIOCTRL, /* CC GPIOCTRL REG */ + IOV_BMAC_CCGPIOOUT, /* CC GPIOOUT REG */ + IOV_BMAC_CCGPIOOUTEN, /* CC GPIOOUTEN REG */ + IOV_BMAC_CCGPIOIN, /* CC GPIOIN REG */ + IOV_BMAC_WPSGPIO, /* WPS push button GPIO pin */ + IOV_BMAC_OTPDUMP, + IOV_BMAC_OTPSTAT, + IOV_BMAC_PCIEASPM, /* obfuscation clkreq/aspm control */ + IOV_BMAC_PCIEADVCORRMASK, /* advanced correctable error mask */ + IOV_BMAC_PCIECLKREQ, /* PCIE 1.1 clockreq enab support */ + IOV_BMAC_PCIELCREG, /* PCIE LCREG */ + IOV_BMAC_SBGPIOTIMERMASK, + IOV_BMAC_RFDISABLEDLY, + IOV_BMAC_PCIEREG, /* PCIE REG */ + IOV_BMAC_PCICFGREG, /* PCI Config register */ + IOV_BMAC_PCIESERDESREG, /* PCIE SERDES REG (dev, 0}offset) */ + IOV_BMAC_PCIEGPIOOUT, /* PCIEOUT REG */ + IOV_BMAC_PCIEGPIOOUTEN, /* PCIEOUTEN REG */ + IOV_BMAC_PCIECLKREQENCTRL, /* clkreqenctrl REG (PCIE REV > 6.0 */ + IOV_BMAC_DMALPBK, + IOV_BMAC_CCREG, + IOV_BMAC_COREREG, + IOV_BMAC_SDCIS, + IOV_BMAC_SDIO_DRIVE, + IOV_BMAC_OTPW, + IOV_BMAC_NVOTPW, + IOV_BMAC_SROM, + IOV_BMAC_SRCRC, + IOV_BMAC_CIS_SOURCE, + IOV_BMAC_CISVAR, + IOV_BMAC_OTPLOCK, + IOV_BMAC_OTP_CHIPID, + IOV_BMAC_CUSTOMVAR1, + IOV_BMAC_BOARDFLAGS, + IOV_BMAC_BOARDFLAGS2, + IOV_BMAC_WPSLED, + IOV_BMAC_NVRAM_SOURCE, + IOV_BMAC_OTP_RAW_READ, + IOV_BMAC_LAST +}; + +typedef enum { + BMAC_DUMP_GPIO_ID, + BMAC_DUMP_SI_ID, + BMAC_DUMP_SIREG_ID, + BMAC_DUMP_SICLK_ID, + BMAC_DUMP_CCREG_ID, + BMAC_DUMP_PCIEREG_ID, + BMAC_DUMP_PHYREG_ID, + BMAC_DUMP_PHYTBL_ID, + BMAC_DUMP_PHYTBL2_ID, + BMAC_DUMP_PHY_RADIOREG_ID, + BMAC_DUMP_LAST +} wlc_bmac_dump_id_t; + +typedef enum { + WLCHW_STATE_ATTACH, + WLCHW_STATE_CLK, + WLCHW_STATE_UP, + WLCHW_STATE_ASSOC, + WLCHW_STATE_LAST +} wlc_bmac_state_id_t; + +extern int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, + uint unit, bool piomode, struct osl_info *osh, + void *regsva, uint bustype, void *btparam); +extern int wlc_bmac_detach(struct wlc_info *wlc); +extern void wlc_bmac_watchdog(void *arg); +extern void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw); + +/* up/down, reset, clk */ +extern void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want); + +extern void wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw, + uint offset, const void *buf, int len, + u32 sel); +extern void wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset, + void *buf, int len, u32 sel); +#define wlc_bmac_copyfrom_shm(wlc_hw, offset, buf, len) \ + wlc_bmac_copyfrom_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL) +#define wlc_bmac_copyto_shm(wlc_hw, offset, buf, len) \ + wlc_bmac_copyto_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL) + +extern void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk); +extern void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on); +extern void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk); +extern void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk); +extern void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags); +extern void wlc_bmac_reset(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, + bool mute); +extern int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw); +extern int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw); +extern int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw); +extern int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags); +extern void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode); + +/* chanspec, ucode interface */ +extern int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, + chanspec_t chanspec, + bool mute, struct txpwr_limits *txpwr); + +extern void wlc_bmac_txfifo(struct wlc_hw_info *wlc_hw, uint fifo, void *p, + bool commit, u16 frameid, u8 txpktpend); +extern int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, + uint *blocks); +extern void wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, + u16 val, int bands); +extern void wlc_bmac_mctrl(struct wlc_hw_info *wlc_hw, u32 mask, u32 val); +extern u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands); +extern int wlc_bmac_xmtfifo_sz_set(struct wlc_hw_info *wlc_hw, uint fifo, + uint blocks); +extern void wlc_bmac_txant_set(struct wlc_hw_info *wlc_hw, u16 phytxant); +extern u16 wlc_bmac_get_txant(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_antsel_type_set(struct wlc_hw_info *wlc_hw, + u8 antsel_type); +extern int wlc_bmac_revinfo_get(struct wlc_hw_info *wlc_hw, + wlc_bmac_revinfo_t *revinfo); +extern int wlc_bmac_state_get(struct wlc_hw_info *wlc_hw, + wlc_bmac_state_t *state); +extern void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v); +extern u16 wlc_bmac_read_shm(struct wlc_hw_info *wlc_hw, uint offset); +extern void wlc_bmac_set_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v, + int len); +extern void wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, + int len, void *buf); +extern void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, + uint *len); + +extern void wlc_bmac_process_ps_switch(struct wlc_hw_info *wlc, + struct ether_addr *ea, s8 ps_on); +extern void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, + u8 *ea); +extern void wlc_bmac_set_hw_etheraddr(struct wlc_hw_info *wlc_hw, + u8 *ea); +extern bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw); + +extern bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot); +extern void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool want, mbool flags); +extern void wlc_bmac_set_deaf(struct wlc_hw_info *wlc_hw, bool user_flag); +extern void wlc_bmac_band_stf_ss_set(struct wlc_hw_info *wlc_hw, u8 stf_mode); + +extern void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw); +extern bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, + uint tx_fifo); +extern void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo); +extern void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo); + +extern void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, + u32 override_bit); +extern void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw, + u32 override_bit); + +extern void wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, + const u8 *addr); +extern void wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, + int match_reg_offset, + const u8 *addr); +extern void wlc_bmac_write_hw_bcntemplates(struct wlc_hw_info *wlc_hw, + void *bcn, int len, bool both); + +extern void wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr, + u32 *tsf_h_ptr); +extern void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin); +extern void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax); +extern void wlc_bmac_set_noreset(struct wlc_hw_info *wlc, bool noreset_flag); +extern void wlc_bmac_set_ucode_loaded(struct wlc_hw_info *wlc, + bool ucode_loaded); + +extern void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL, + u16 LRL); + +extern void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw); + + +/* API for BMAC driver (e.g. wlc_phy.c etc) */ + +extern void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw); +extern void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, + mbool req_bit); +extern void wlc_bmac_set_clk(struct wlc_hw_info *wlc_hw, bool on); +extern bool wlc_bmac_taclear(struct wlc_hw_info *wlc_hw, bool ta_ok); +extern void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw); + +extern void wlc_bmac_dump(struct wlc_hw_info *wlc_hw, struct bcmstrbuf *b, + wlc_bmac_dump_id_t dump_id); +extern void wlc_gpio_fast_deinit(struct wlc_hw_info *wlc_hw); + +extern bool wlc_bmac_radio_hw(struct wlc_hw_info *wlc_hw, bool enable); +extern u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate); + +extern void wlc_bmac_assert_type_set(struct wlc_hw_info *wlc_hw, u32 type); +extern void wlc_bmac_set_txpwr_percent(struct wlc_hw_info *wlc_hw, u8 val); +extern void wlc_bmac_blink_sync(struct wlc_hw_info *wlc_hw, u32 led_pins); +extern void wlc_bmac_ifsctl_edcrs_set(struct wlc_hw_info *wlc_hw, bool abie, + bool isht); + +extern void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h b/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h new file mode 100644 index 000000000000..0bb4a212dd71 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _WLC_BSSCFG_H_ +#define _WLC_BSSCFG_H_ + +#include + +/* Check if a particular BSS config is AP or STA */ +#define BSSCFG_AP(cfg) (0) +#define BSSCFG_STA(cfg) (1) + +#define BSSCFG_IBSS(cfg) (!(cfg)->BSS) + +/* forward declarations */ +typedef struct wlc_bsscfg wlc_bsscfg_t; + +#include + +#define NTXRATE 64 /* # tx MPDUs rate is reported for */ +#define MAXMACLIST 64 /* max # source MAC matches */ +#define BCN_TEMPLATE_COUNT 2 + +/* Iterator for "associated" STA bss configs: + (struct wlc_info *wlc, int idx, wlc_bsscfg_t *cfg) */ +#define FOREACH_AS_STA(wlc, idx, cfg) \ + for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \ + if ((cfg = (wlc)->bsscfg[idx]) && BSSCFG_STA(cfg) && cfg->associated) + +/* As above for all non-NULL BSS configs */ +#define FOREACH_BSS(wlc, idx, cfg) \ + for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \ + if ((cfg = (wlc)->bsscfg[idx])) + +/* BSS configuration state */ +struct wlc_bsscfg { + struct wlc_info *wlc; /* wlc to which this bsscfg belongs to. */ + bool up; /* is this configuration up operational */ + bool enable; /* is this configuration enabled */ + bool associated; /* is BSS in ASSOCIATED state */ + bool BSS; /* infraustructure or adhac */ + bool dtim_programmed; +#ifdef LATER + bool _ap; /* is this configuration an AP */ + struct wlc_if *wlcif; /* virtual interface, NULL for primary bsscfg */ + void *sup; /* pointer to supplicant state */ + s8 sup_type; /* type of supplicant */ + bool sup_enable_wpa; /* supplicant WPA on/off */ + void *authenticator; /* pointer to authenticator state */ + bool sup_auth_pending; /* flag for auth timeout */ +#endif + u8 SSID_len; /* the length of SSID */ + u8 SSID[IEEE80211_MAX_SSID_LEN]; /* SSID string */ + struct scb *bcmc_scb[MAXBANDS]; /* one bcmc_scb per band */ + s8 _idx; /* the index of this bsscfg, + * assigned at wlc_bsscfg_alloc() + */ + /* MAC filter */ + uint nmac; /* # of entries on maclist array */ + int macmode; /* allow/deny stations on maclist array */ + struct ether_addr *maclist; /* list of source MAC addrs to match */ + + /* security */ + u32 wsec; /* wireless security bitvec */ + s16 auth; /* 802.11 authentication: Open, Shared Key, WPA */ + s16 openshared; /* try Open auth first, then Shared Key */ + bool wsec_restrict; /* drop unencrypted packets if wsec is enabled */ + bool eap_restrict; /* restrict data until 802.1X auth succeeds */ + u16 WPA_auth; /* WPA: authenticated key management */ + bool wpa2_preauth; /* default is true, wpa_cap sets value */ + bool wsec_portopen; /* indicates keys are plumbed */ + wsec_iv_t wpa_none_txiv; /* global txiv for WPA_NONE, tkip and aes */ + int wsec_index; /* 0-3: default tx key, -1: not set */ + wsec_key_t *bss_def_keys[WLC_DEFAULT_KEYS]; /* default key storage */ + + /* TKIP countermeasures */ + bool tkip_countermeasures; /* flags TKIP no-assoc period */ + u32 tk_cm_dt; /* detect timer */ + u32 tk_cm_bt; /* blocking timer */ + u32 tk_cm_bt_tmstmp; /* Timestamp when TKIP BT is activated */ + bool tk_cm_activate; /* activate countermeasures after EAPOL-Key sent */ + + u8 BSSID[ETH_ALEN]; /* BSSID (associated) */ + u8 cur_etheraddr[ETH_ALEN]; /* h/w address */ + u16 bcmc_fid; /* the last BCMC FID queued to TX_BCMC_FIFO */ + u16 bcmc_fid_shm; /* the last BCMC FID written to shared mem */ + + u32 flags; /* WLC_BSSCFG flags; see below */ + + u8 *bcn; /* AP beacon */ + uint bcn_len; /* AP beacon length */ + bool ar_disassoc; /* disassociated in associated recreation */ + + int auth_atmptd; /* auth type (open/shared) attempted */ + + pmkid_cand_t pmkid_cand[MAXPMKID]; /* PMKID candidate list */ + uint npmkid_cand; /* num PMKID candidates */ + pmkid_t pmkid[MAXPMKID]; /* PMKID cache */ + uint npmkid; /* num cached PMKIDs */ + + wlc_bss_info_t *target_bss; /* BSS parms during tran. to ASSOCIATED state */ + wlc_bss_info_t *current_bss; /* BSS parms in ASSOCIATED state */ + + /* PM states */ + bool PMawakebcn; /* bcn recvd during current waking state */ + bool PMpending; /* waiting for tx status with PM indicated set */ + bool priorPMstate; /* Detecting PM state transitions */ + bool PSpoll; /* whether there is an outstanding PS-Poll frame */ + + /* BSSID entry in RCMTA, use the wsec key management infrastructure to + * manage the RCMTA entries. + */ + wsec_key_t *rcmta; + + /* 'unique' ID of this bsscfg, assigned at bsscfg allocation */ + u16 ID; + + uint txrspecidx; /* index into tx rate circular buffer */ + ratespec_t txrspec[NTXRATE][2]; /* circular buffer of prev MPDUs tx rates */ +}; + +#define WLC_BSSCFG_11N_DISABLE 0x1000 /* Do not advertise .11n IEs for this BSS */ +#define WLC_BSSCFG_HW_BCN 0x20 /* The BSS is generating beacons in HW */ + +#define HWBCN_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_BCN) != 0) +#define HWPRB_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_PRB) != 0) + +extern void wlc_bsscfg_ID_assign(struct wlc_info *wlc, wlc_bsscfg_t * bsscfg); + +/* Extend N_ENAB to per-BSS */ +#define BSS_N_ENAB(wlc, cfg) \ + (N_ENAB((wlc)->pub) && !((cfg)->flags & WLC_BSSCFG_11N_DISABLE)) + +#define MBSS_BCN_ENAB(cfg) 0 +#define MBSS_PRB_ENAB(cfg) 0 +#define SOFTBCN_ENAB(pub) (0) +#define SOFTPRB_ENAB(pub) (0) +#define wlc_bsscfg_tx_check(a) do { } while (0); + +#endif /* _WLC_BSSCFG_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_cfg.h b/drivers/staging/brcm80211/brcmsmac/wlc_cfg.h new file mode 100644 index 000000000000..3decb7d1a5e5 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_cfg.h @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_cfg_h_ +#define _wlc_cfg_h_ + +#define NBANDS(wlc) ((wlc)->pub->_nbands) +#define NBANDS_PUB(pub) ((pub)->_nbands) +#define NBANDS_HW(hw) ((hw)->_nbands) + +#define IS_SINGLEBAND_5G(device) 0 + +/* **** Core type/rev defaults **** */ +#define D11_DEFAULT 0x0fffffb0 /* Supported D11 revs: 4, 5, 7-27 + * also need to update wlc.h MAXCOREREV + */ + +#define NPHY_DEFAULT 0x000001ff /* Supported nphy revs: + * 0 4321a0 + * 1 4321a1 + * 2 4321b0/b1/c0/c1 + * 3 4322a0 + * 4 4322a1 + * 5 4716a0 + * 6 43222a0, 43224a0 + * 7 43226a0 + * 8 5357a0, 43236a0 + */ + +#define LCNPHY_DEFAULT 0x00000007 /* Supported lcnphy revs: + * 0 4313a0, 4336a0, 4330a0 + * 1 + * 2 4330a0 + */ + +#define SSLPNPHY_DEFAULT 0x0000000f /* Supported sslpnphy revs: + * 0 4329a0/k0 + * 1 4329b0/4329C0 + * 2 4319a0 + * 3 5356a0 + */ + + +/* For undefined values, use defaults */ +#ifndef D11CONF +#define D11CONF D11_DEFAULT +#endif +#ifndef NCONF +#define NCONF NPHY_DEFAULT +#endif +#ifndef LCNCONF +#define LCNCONF LCNPHY_DEFAULT +#endif + +#ifndef SSLPNCONF +#define SSLPNCONF SSLPNPHY_DEFAULT +#endif + +#define BAND2G +#define BAND5G +#define WLANTSEL 1 + +/******************************************************************** + * Phy/Core Configuration. Defines macros to to check core phy/rev * + * compile-time configuration. Defines default core support. * + * ****************************************************************** + */ + +/* Basic macros to check a configuration bitmask */ + +#define CONF_HAS(config, val) ((config) & (1 << (val))) +#define CONF_MSK(config, mask) ((config) & (mask)) +#define MSK_RANGE(low, hi) ((1 << ((hi)+1)) - (1 << (low))) +#define CONF_RANGE(config, low, hi) (CONF_MSK(config, MSK_RANGE(low, high))) + +#define CONF_IS(config, val) ((config) == (1 << (val))) +#define CONF_GE(config, val) ((config) & (0-(1 << (val)))) +#define CONF_GT(config, val) ((config) & (0-2*(1 << (val)))) +#define CONF_LT(config, val) ((config) & ((1 << (val))-1)) +#define CONF_LE(config, val) ((config) & (2*(1 << (val))-1)) + +/* Wrappers for some of the above, specific to config constants */ + +#define NCONF_HAS(val) CONF_HAS(NCONF, val) +#define NCONF_MSK(mask) CONF_MSK(NCONF, mask) +#define NCONF_IS(val) CONF_IS(NCONF, val) +#define NCONF_GE(val) CONF_GE(NCONF, val) +#define NCONF_GT(val) CONF_GT(NCONF, val) +#define NCONF_LT(val) CONF_LT(NCONF, val) +#define NCONF_LE(val) CONF_LE(NCONF, val) + +#define LCNCONF_HAS(val) CONF_HAS(LCNCONF, val) +#define LCNCONF_MSK(mask) CONF_MSK(LCNCONF, mask) +#define LCNCONF_IS(val) CONF_IS(LCNCONF, val) +#define LCNCONF_GE(val) CONF_GE(LCNCONF, val) +#define LCNCONF_GT(val) CONF_GT(LCNCONF, val) +#define LCNCONF_LT(val) CONF_LT(LCNCONF, val) +#define LCNCONF_LE(val) CONF_LE(LCNCONF, val) + +#define D11CONF_HAS(val) CONF_HAS(D11CONF, val) +#define D11CONF_MSK(mask) CONF_MSK(D11CONF, mask) +#define D11CONF_IS(val) CONF_IS(D11CONF, val) +#define D11CONF_GE(val) CONF_GE(D11CONF, val) +#define D11CONF_GT(val) CONF_GT(D11CONF, val) +#define D11CONF_LT(val) CONF_LT(D11CONF, val) +#define D11CONF_LE(val) CONF_LE(D11CONF, val) + +#define PHYCONF_HAS(val) CONF_HAS(PHYTYPE, val) +#define PHYCONF_IS(val) CONF_IS(PHYTYPE, val) + +#define NREV_IS(var, val) (NCONF_HAS(val) && (NCONF_IS(val) || ((var) == (val)))) +#define NREV_GE(var, val) (NCONF_GE(val) && (!NCONF_LT(val) || ((var) >= (val)))) +#define NREV_GT(var, val) (NCONF_GT(val) && (!NCONF_LE(val) || ((var) > (val)))) +#define NREV_LT(var, val) (NCONF_LT(val) && (!NCONF_GE(val) || ((var) < (val)))) +#define NREV_LE(var, val) (NCONF_LE(val) && (!NCONF_GT(val) || ((var) <= (val)))) + +#define LCNREV_IS(var, val) (LCNCONF_HAS(val) && (LCNCONF_IS(val) || ((var) == (val)))) +#define LCNREV_GE(var, val) (LCNCONF_GE(val) && (!LCNCONF_LT(val) || ((var) >= (val)))) +#define LCNREV_GT(var, val) (LCNCONF_GT(val) && (!LCNCONF_LE(val) || ((var) > (val)))) +#define LCNREV_LT(var, val) (LCNCONF_LT(val) && (!LCNCONF_GE(val) || ((var) < (val)))) +#define LCNREV_LE(var, val) (LCNCONF_LE(val) && (!LCNCONF_GT(val) || ((var) <= (val)))) + +#define D11REV_IS(var, val) (D11CONF_HAS(val) && (D11CONF_IS(val) || ((var) == (val)))) +#define D11REV_GE(var, val) (D11CONF_GE(val) && (!D11CONF_LT(val) || ((var) >= (val)))) +#define D11REV_GT(var, val) (D11CONF_GT(val) && (!D11CONF_LE(val) || ((var) > (val)))) +#define D11REV_LT(var, val) (D11CONF_LT(val) && (!D11CONF_GE(val) || ((var) < (val)))) +#define D11REV_LE(var, val) (D11CONF_LE(val) && (!D11CONF_GT(val) || ((var) <= (val)))) + +#define PHYTYPE_IS(var, val) (PHYCONF_HAS(val) && (PHYCONF_IS(val) || ((var) == (val)))) + +/* Finally, early-exit from switch case if anyone wants it... */ + +#define CASECHECK(config, val) if (!(CONF_HAS(config, val))) break +#define CASEMSK(config, mask) if (!(CONF_MSK(config, mask))) break + +#if (D11CONF ^ (D11CONF & D11_DEFAULT)) +#error "Unsupported MAC revision configured" +#endif +#if (NCONF ^ (NCONF & NPHY_DEFAULT)) +#error "Unsupported NPHY revision configured" +#endif +#if (LCNCONF ^ (LCNCONF & LCNPHY_DEFAULT)) +#error "Unsupported LPPHY revision configured" +#endif + +/* *** Consistency checks *** */ +#if !D11CONF +#error "No MAC revisions configured!" +#endif + +#if !NCONF && !LCNCONF && !SSLPNCONF +#error "No PHY configured!" +#endif + +/* Set up PHYTYPE automatically: (depends on PHY_TYPE_X, from d11.h) */ + +#define _PHYCONF_N (1 << PHY_TYPE_N) + +#if LCNCONF +#define _PHYCONF_LCN (1 << PHY_TYPE_LCN) +#else +#define _PHYCONF_LCN 0 +#endif /* LCNCONF */ + +#if SSLPNCONF +#define _PHYCONF_SSLPN (1 << PHY_TYPE_SSN) +#else +#define _PHYCONF_SSLPN 0 +#endif /* SSLPNCONF */ + +#define PHYTYPE (_PHYCONF_N | _PHYCONF_LCN | _PHYCONF_SSLPN) + +/* Utility macro to identify 802.11n (HT) capable PHYs */ +#define PHYTYPE_11N_CAP(phytype) \ + (PHYTYPE_IS(phytype, PHY_TYPE_N) || \ + PHYTYPE_IS(phytype, PHY_TYPE_LCN) || \ + PHYTYPE_IS(phytype, PHY_TYPE_SSN)) + +/* Last but not least: shorter wlc-specific var checks */ +#define WLCISNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_N) +#define WLCISLCNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_LCN) +#define WLCISSSLPNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_SSN) + +#define WLC_PHY_11N_CAP(band) PHYTYPE_11N_CAP((band)->phytype) + +/********************************************************************** + * ------------- End of Core phy/rev configuration. ----------------- * + * ******************************************************************** + */ + +/************************************************* + * Defaults for tunables (e.g. sizing constants) + * + * For each new tunable, add a member to the end + * of wlc_tunables_t in wlc_pub.h to enable + * runtime checks of tunable values. (Directly + * using the macros in code invalidates ROM code) + * + * *********************************************** + */ +#ifndef NTXD +#define NTXD 256 /* Max # of entries in Tx FIFO based on 4kb page size */ +#endif /* NTXD */ +#ifndef NRXD +#define NRXD 256 /* Max # of entries in Rx FIFO based on 4kb page size */ +#endif /* NRXD */ + +#ifndef NRXBUFPOST +#define NRXBUFPOST 32 /* try to keep this # rbufs posted to the chip */ +#endif /* NRXBUFPOST */ + +#ifndef MAXSCB /* station control blocks in cache */ +#define MAXSCB 32 /* Maximum SCBs in cache for STA */ +#endif /* MAXSCB */ + +#ifndef AMPDU_NUM_MPDU +#define AMPDU_NUM_MPDU 16 /* max allowed number of mpdus in an ampdu (2 streams) */ +#endif /* AMPDU_NUM_MPDU */ + +#ifndef AMPDU_NUM_MPDU_3STREAMS +#define AMPDU_NUM_MPDU_3STREAMS 32 /* max allowed number of mpdus in an ampdu for 3+ streams */ +#endif /* AMPDU_NUM_MPDU_3STREAMS */ + +/* Count of packet callback structures. either of following + * 1. Set to the number of SCBs since a STA + * can queue up a rate callback for each IBSS STA it knows about, and an AP can + * queue up an "are you there?" Null Data callback for each associated STA + * 2. controlled by tunable config file + */ +#ifndef MAXPKTCB +#define MAXPKTCB MAXSCB /* Max number of packet callbacks */ +#endif /* MAXPKTCB */ + +#ifndef CTFPOOLSZ +#define CTFPOOLSZ 128 +#endif /* CTFPOOLSZ */ + +/* NetBSD also needs to keep track of this */ +#define WLC_MAX_UCODE_BSS (16) /* Number of BSS handled in ucode bcn/prb */ +#define WLC_MAX_UCODE_BSS4 (4) /* Number of BSS handled in sw bcn/prb */ +#ifndef WLC_MAXBSSCFG +#define WLC_MAXBSSCFG (1) /* max # BSS configs */ +#endif /* WLC_MAXBSSCFG */ + +#ifndef MAXBSS +#define MAXBSS 64 /* max # available networks */ +#endif /* MAXBSS */ + +#ifndef WLC_DATAHIWAT +#define WLC_DATAHIWAT 50 /* data msg txq hiwat mark */ +#endif /* WLC_DATAHIWAT */ + +#ifndef WLC_AMPDUDATAHIWAT +#define WLC_AMPDUDATAHIWAT 255 +#endif /* WLC_AMPDUDATAHIWAT */ + +/* bounded rx loops */ +#ifndef RXBND +#define RXBND 8 /* max # frames to process in wlc_recv() */ +#endif /* RXBND */ +#ifndef TXSBND +#define TXSBND 8 /* max # tx status to process in wlc_txstatus() */ +#endif /* TXSBND */ + +#define BAND_5G(bt) ((bt) == WLC_BAND_5G) +#define BAND_2G(bt) ((bt) == WLC_BAND_2G) + +#define WLBANDINITDATA(_data) _data +#define WLBANDINITFN(_fn) _fn + +#define WLANTSEL_ENAB(wlc) 1 + +#endif /* _wlc_cfg_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c new file mode 100644 index 000000000000..a35c15214880 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c @@ -0,0 +1,1609 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct wlc_cm_band { + u8 locale_flags; /* locale_info_t flags */ + chanvec_t valid_channels; /* List of valid channels in the country */ + const chanvec_t *restricted_channels; /* List of restricted use channels */ + const chanvec_t *radar_channels; /* List of radar sensitive channels */ + u8 PAD[8]; +} wlc_cm_band_t; + +struct wlc_cm_info { + struct wlc_pub *pub; + struct wlc_info *wlc; + char srom_ccode[WLC_CNTRY_BUF_SZ]; /* Country Code in SROM */ + uint srom_regrev; /* Regulatory Rev for the SROM ccode */ + const country_info_t *country; /* current country def */ + char ccode[WLC_CNTRY_BUF_SZ]; /* current internal Country Code */ + uint regrev; /* current Regulatory Revision */ + char country_abbrev[WLC_CNTRY_BUF_SZ]; /* current advertised ccode */ + wlc_cm_band_t bandstate[MAXBANDS]; /* per-band state (one per phy/radio) */ + /* quiet channels currently for radar sensitivity or 11h support */ + chanvec_t quiet_channels; /* channels on which we cannot transmit */ +}; + +static int wlc_channels_init(wlc_cm_info_t *wlc_cm, + const country_info_t *country); +static void wlc_set_country_common(wlc_cm_info_t *wlc_cm, + const char *country_abbrev, + const char *ccode, uint regrev, + const country_info_t *country); +static int wlc_country_aggregate_map(wlc_cm_info_t *wlc_cm, const char *ccode, + char *mapped_ccode, uint *mapped_regrev); +static const country_info_t *wlc_country_lookup_direct(const char *ccode, + uint regrev); +static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm, + const char *ccode, + char *mapped_ccode, + uint *mapped_regrev); +static void wlc_channels_commit(wlc_cm_info_t *wlc_cm); +static bool wlc_japan_ccode(const char *ccode); +static void wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t * + wlc_cm, + struct + txpwr_limits + *txpwr, + u8 + local_constraint_qdbm); +void wlc_locale_add_channels(chanvec_t *target, const chanvec_t *channels); +static const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx); +static const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx); + +/* QDB() macro takes a dB value and converts to a quarter dB value */ +#ifdef QDB +#undef QDB +#endif +#define QDB(n) ((n) * WLC_TXPWR_DB_FACTOR) + +/* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */ + +/* + * Some common channel sets + */ + +/* No channels */ +static const chanvec_t chanvec_none = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* All 2.4 GHz HW channels */ +const chanvec_t chanvec_all_2G = { + {0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* All 5 GHz HW channels */ +const chanvec_t chanvec_all_5G = { + {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x11, 0x11, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x20, 0x22, 0x22, 0x00, 0x00, 0x11, + 0x11, 0x11, 0x11, 0x01} +}; + +/* + * Radar channel sets + */ + +/* No radar */ +#define radar_set_none chanvec_none + +static const chanvec_t radar_set1 = { /* Channels 52 - 64, 100 - 140 */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, /* 52 - 60 */ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, /* 64, 100 - 124 */ + 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 128 - 140 */ + 0x00, 0x00, 0x00, 0x00} +}; + +/* + * Restricted channel sets + */ + +#define restricted_set_none chanvec_none + +/* Channels 34, 38, 42, 46 */ +static const chanvec_t restricted_set_japan_legacy = { + {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* Channels 12, 13 */ +static const chanvec_t restricted_set_2g_short = { + {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* Channel 165 */ +static const chanvec_t restricted_chan_165 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* Channels 36 - 48 & 149 - 165 */ +static const chanvec_t restricted_low_hi = { + {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x22, 0x22, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* Channels 12 - 14 */ +static const chanvec_t restricted_set_12_13_14 = { + {0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +#define LOCALE_CHAN_01_11 (1<<0) +#define LOCALE_CHAN_12_13 (1<<1) +#define LOCALE_CHAN_14 (1<<2) +#define LOCALE_SET_5G_LOW_JP1 (1<<3) /* 34-48, step 2 */ +#define LOCALE_SET_5G_LOW_JP2 (1<<4) /* 34-46, step 4 */ +#define LOCALE_SET_5G_LOW1 (1<<5) /* 36-48, step 4 */ +#define LOCALE_SET_5G_LOW2 (1<<6) /* 52 */ +#define LOCALE_SET_5G_LOW3 (1<<7) /* 56-64, step 4 */ +#define LOCALE_SET_5G_MID1 (1<<8) /* 100-116, step 4 */ +#define LOCALE_SET_5G_MID2 (1<<9) /* 120-124, step 4 */ +#define LOCALE_SET_5G_MID3 (1<<10) /* 128 */ +#define LOCALE_SET_5G_HIGH1 (1<<11) /* 132-140, step 4 */ +#define LOCALE_SET_5G_HIGH2 (1<<12) /* 149-161, step 4 */ +#define LOCALE_SET_5G_HIGH3 (1<<13) /* 165 */ +#define LOCALE_CHAN_52_140_ALL (1<<14) +#define LOCALE_SET_5G_HIGH4 (1<<15) /* 184-216 */ + +#define LOCALE_CHAN_36_64 (LOCALE_SET_5G_LOW1 | LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3) +#define LOCALE_CHAN_52_64 (LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3) +#define LOCALE_CHAN_100_124 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2) +#define LOCALE_CHAN_100_140 \ + (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1) +#define LOCALE_CHAN_149_165 (LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3) +#define LOCALE_CHAN_184_216 LOCALE_SET_5G_HIGH4 + +#define LOCALE_CHAN_01_14 (LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13 | LOCALE_CHAN_14) + +#define LOCALE_RADAR_SET_NONE 0 +#define LOCALE_RADAR_SET_1 1 + +#define LOCALE_RESTRICTED_NONE 0 +#define LOCALE_RESTRICTED_SET_2G_SHORT 1 +#define LOCALE_RESTRICTED_CHAN_165 2 +#define LOCALE_CHAN_ALL_5G 3 +#define LOCALE_RESTRICTED_JAPAN_LEGACY 4 +#define LOCALE_RESTRICTED_11D_2G 5 +#define LOCALE_RESTRICTED_11D_5G 6 +#define LOCALE_RESTRICTED_LOW_HI 7 +#define LOCALE_RESTRICTED_12_13_14 8 + +/* global memory to provide working buffer for expanded locale */ + +static const chanvec_t *g_table_radar_set[] = { + &chanvec_none, + &radar_set1 +}; + +static const chanvec_t *g_table_restricted_chan[] = { + &chanvec_none, /* restricted_set_none */ + &restricted_set_2g_short, + &restricted_chan_165, + &chanvec_all_5G, + &restricted_set_japan_legacy, + &chanvec_all_2G, /* restricted_set_11d_2G */ + &chanvec_all_5G, /* restricted_set_11d_5G */ + &restricted_low_hi, + &restricted_set_12_13_14 +}; + +static const chanvec_t locale_2g_01_11 = { + {0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_2g_12_13 = { + {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_2g_14 = { + {0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_LOW_JP1 = { + {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_LOW_JP2 = { + {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_LOW1 = { + {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_LOW2 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_LOW3 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_MID1 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_MID2 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_MID3 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_HIGH1 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_HIGH2 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x22, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_HIGH3 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_52_140_ALL = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const chanvec_t locale_5g_HIGH4 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x11, 0x11, 0x11, 0x11} +}; + +static const chanvec_t *g_table_locale_base[] = { + &locale_2g_01_11, + &locale_2g_12_13, + &locale_2g_14, + &locale_5g_LOW_JP1, + &locale_5g_LOW_JP2, + &locale_5g_LOW1, + &locale_5g_LOW2, + &locale_5g_LOW3, + &locale_5g_MID1, + &locale_5g_MID2, + &locale_5g_MID3, + &locale_5g_HIGH1, + &locale_5g_HIGH2, + &locale_5g_HIGH3, + &locale_5g_52_140_ALL, + &locale_5g_HIGH4 +}; + +void wlc_locale_add_channels(chanvec_t *target, const chanvec_t *channels) +{ + u8 i; + for (i = 0; i < sizeof(chanvec_t); i++) { + target->vec[i] |= channels->vec[i]; + } +} + +void wlc_locale_get_channels(const locale_info_t *locale, chanvec_t *channels) +{ + u8 i; + + memset(channels, 0, sizeof(chanvec_t)); + + for (i = 0; i < ARRAY_SIZE(g_table_locale_base); i++) { + if (locale->valid_channels & (1 << i)) { + wlc_locale_add_channels(channels, + g_table_locale_base[i]); + } + } +} + +/* + * Locale Definitions - 2.4 GHz + */ +static const locale_info_t locale_i = { /* locale i. channel 1 - 13 */ + LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13, + LOCALE_RADAR_SET_NONE, + LOCALE_RESTRICTED_SET_2G_SHORT, + {QDB(19), QDB(19), QDB(19), + QDB(19), QDB(19), QDB(19)}, + {20, 20, 20, 0}, + WLC_EIRP +}; + +/* + * Locale Definitions - 5 GHz + */ +static const locale_info_t locale_11 = { + /* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */ + LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165, + LOCALE_RADAR_SET_1, + LOCALE_RESTRICTED_NONE, + {QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)}, + {23, 23, 23, 30, 30}, + WLC_EIRP | WLC_DFS_EU +}; + +#define LOCALE_2G_IDX_i 0 +static const locale_info_t *g_locale_2g_table[] = { + &locale_i +}; + +#define LOCALE_5G_IDX_11 0 +static const locale_info_t *g_locale_5g_table[] = { + &locale_11 +}; + +/* + * MIMO Locale Definitions - 2.4 GHz + */ +static const locale_mimo_info_t locale_bn = { + {QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), + QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), + QDB(13), QDB(13), QDB(13)}, + {0, 0, QDB(13), QDB(13), QDB(13), + QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), + QDB(13), 0, 0}, + 0 +}; + +/* locale mimo 2g indexes */ +#define LOCALE_MIMO_IDX_bn 0 + +static const locale_mimo_info_t *g_mimo_2g_table[] = { + &locale_bn +}; + +/* + * MIMO Locale Definitions - 5 GHz + */ +static const locale_mimo_info_t locale_11n = { + { /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)}, + {QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)}, + 0 +}; + +#define LOCALE_MIMO_IDX_11n 0 +static const locale_mimo_info_t *g_mimo_5g_table[] = { + &locale_11n +}; + +#ifdef LC +#undef LC +#endif +#define LC(id) LOCALE_MIMO_IDX_ ## id + +#ifdef LC_2G +#undef LC_2G +#endif +#define LC_2G(id) LOCALE_2G_IDX_ ## id + +#ifdef LC_5G +#undef LC_5G +#endif +#define LC_5G(id) LOCALE_5G_IDX_ ## id + +#define LOCALES(band2, band5, mimo2, mimo5) {LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)} + +static const struct { + char abbrev[WLC_CNTRY_BUF_SZ]; /* country abbreviation */ + country_info_t country; +} cntry_locales[] = { + { + "X2", LOCALES(i, 11, bn, 11n)}, /* Worldwide RoW 2 */ +}; + +#ifdef SUPPORT_40MHZ +/* 20MHz channel info for 40MHz pairing support */ +struct chan20_info { + u8 sb; + u8 adj_sbs; +}; + +/* indicates adjacent channels that are allowed for a 40 Mhz channel and + * those that permitted by the HT + */ +struct chan20_info chan20_info[] = { + /* 11b/11g */ +/* 0 */ {1, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 1 */ {2, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 2 */ {3, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 3 */ {4, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 4 */ {5, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, +/* 5 */ {6, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, +/* 6 */ {7, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, +/* 7 */ {8, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, +/* 8 */ {9, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, +/* 9 */ {10, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 10 */ {11, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 11 */ {12, (CH_LOWER_SB)}, +/* 12 */ {13, (CH_LOWER_SB)}, +/* 13 */ {14, (CH_LOWER_SB)}, + +/* 11a japan high */ +/* 14 */ {34, (CH_UPPER_SB)}, +/* 15 */ {38, (CH_LOWER_SB)}, +/* 16 */ {42, (CH_LOWER_SB)}, +/* 17 */ {46, (CH_LOWER_SB)}, + +/* 11a usa low */ +/* 18 */ {36, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 19 */ {40, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 20 */ {44, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 21 */ {48, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 22 */ {52, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 23 */ {56, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 24 */ {60, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 25 */ {64, (CH_LOWER_SB | CH_EWA_VALID)}, + +/* 11a Europe */ +/* 26 */ {100, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 27 */ {104, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 28 */ {108, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 29 */ {112, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 30 */ {116, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 31 */ {120, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 32 */ {124, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 33 */ {128, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 34 */ {132, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 35 */ {136, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 36 */ {140, (CH_LOWER_SB)}, + +/* 11a usa high, ref5 only */ +/* The 0x80 bit in pdiv means these are REF5, other entries are REF20 */ +/* 37 */ {149, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 38 */ {153, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 39 */ {157, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 40 */ {161, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 41 */ {165, (CH_LOWER_SB)}, + +/* 11a japan */ +/* 42 */ {184, (CH_UPPER_SB)}, +/* 43 */ {188, (CH_LOWER_SB)}, +/* 44 */ {192, (CH_UPPER_SB)}, +/* 45 */ {196, (CH_LOWER_SB)}, +/* 46 */ {200, (CH_UPPER_SB)}, +/* 47 */ {204, (CH_LOWER_SB)}, +/* 48 */ {208, (CH_UPPER_SB)}, +/* 49 */ {212, (CH_LOWER_SB)}, +/* 50 */ {216, (CH_LOWER_SB)} +}; +#endif /* SUPPORT_40MHZ */ + +const locale_info_t *wlc_get_locale_2g(u8 locale_idx) +{ + if (locale_idx >= ARRAY_SIZE(g_locale_2g_table)) { + WL_ERROR("%s: locale 2g index size out of range %d\n", + __func__, locale_idx); + ASSERT(locale_idx < ARRAY_SIZE(g_locale_2g_table)); + return NULL; + } + return g_locale_2g_table[locale_idx]; +} + +const locale_info_t *wlc_get_locale_5g(u8 locale_idx) +{ + if (locale_idx >= ARRAY_SIZE(g_locale_5g_table)) { + WL_ERROR("%s: locale 5g index size out of range %d\n", + __func__, locale_idx); + ASSERT(locale_idx < ARRAY_SIZE(g_locale_5g_table)); + return NULL; + } + return g_locale_5g_table[locale_idx]; +} + +const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx) +{ + if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table)) { + WL_ERROR("%s: mimo 2g index size out of range %d\n", + __func__, locale_idx); + return NULL; + } + return g_mimo_2g_table[locale_idx]; +} + +const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx) +{ + if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table)) { + WL_ERROR("%s: mimo 5g index size out of range %d\n", + __func__, locale_idx); + return NULL; + } + return g_mimo_5g_table[locale_idx]; +} + +wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc) +{ + wlc_cm_info_t *wlc_cm; + char country_abbrev[WLC_CNTRY_BUF_SZ]; + const country_info_t *country; + struct wlc_pub *pub = wlc->pub; + char *ccode; + + WL_TRACE("wl%d: wlc_channel_mgr_attach\n", wlc->pub->unit); + + wlc_cm = kzalloc(sizeof(wlc_cm_info_t), GFP_ATOMIC); + if (wlc_cm == NULL) { + WL_ERROR("wl%d: %s: out of memory", pub->unit, __func__); + return NULL; + } + wlc_cm->pub = pub; + wlc_cm->wlc = wlc; + wlc->cmi = wlc_cm; + + /* store the country code for passing up as a regulatory hint */ + ccode = getvar(wlc->pub->vars, "ccode"); + if (ccode) { + strncpy(wlc->pub->srom_ccode, ccode, WLC_CNTRY_BUF_SZ - 1); + WL_NONE("%s: SROM country code is %c%c\n", + __func__, + wlc->pub->srom_ccode[0], wlc->pub->srom_ccode[1]); + } + + /* internal country information which must match regulatory constraints in firmware */ + memset(country_abbrev, 0, WLC_CNTRY_BUF_SZ); + strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1); + country = wlc_country_lookup(wlc, country_abbrev); + + ASSERT(country != NULL); + + /* save default country for exiting 11d regulatory mode */ + strncpy(wlc->country_default, country_abbrev, WLC_CNTRY_BUF_SZ - 1); + + /* initialize autocountry_default to driver default */ + strncpy(wlc->autocountry_default, "X2", WLC_CNTRY_BUF_SZ - 1); + + wlc_set_countrycode(wlc_cm, country_abbrev); + + return wlc_cm; +} + +void wlc_channel_mgr_detach(wlc_cm_info_t *wlc_cm) +{ + if (wlc_cm) + kfree(wlc_cm); +} + +const char *wlc_channel_country_abbrev(wlc_cm_info_t *wlc_cm) +{ + return wlc_cm->country_abbrev; +} + +u8 wlc_channel_locale_flags(wlc_cm_info_t *wlc_cm) +{ + struct wlc_info *wlc = wlc_cm->wlc; + + return wlc_cm->bandstate[wlc->band->bandunit].locale_flags; +} + +u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, uint bandunit) +{ + return wlc_cm->bandstate[bandunit].locale_flags; +} + +/* return chanvec for a given country code and band */ +bool +wlc_channel_get_chanvec(struct wlc_info *wlc, const char *country_abbrev, + int bandtype, chanvec_t *channels) +{ + const country_info_t *country; + const locale_info_t *locale = NULL; + + country = wlc_country_lookup(wlc, country_abbrev); + if (country == NULL) + return false; + + if (bandtype == WLC_BAND_2G) + locale = wlc_get_locale_2g(country->locale_2G); + else if (bandtype == WLC_BAND_5G) + locale = wlc_get_locale_5g(country->locale_5G); + if (locale == NULL) + return false; + + wlc_locale_get_channels(locale, channels); + return true; +} + +/* set the driver's current country and regulatory information using a country code + * as the source. Lookup built in country information found with the country code. + */ +int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode) +{ + char country_abbrev[WLC_CNTRY_BUF_SZ]; + strncpy(country_abbrev, ccode, WLC_CNTRY_BUF_SZ); + return wlc_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1); +} + +int +wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, + const char *country_abbrev, + const char *ccode, int regrev) +{ + const country_info_t *country; + char mapped_ccode[WLC_CNTRY_BUF_SZ]; + uint mapped_regrev; + + WL_NONE("%s: (country_abbrev \"%s\", ccode \"%s\", regrev %d) SPROM \"%s\"/%u\n", + __func__, country_abbrev, ccode, regrev, + wlc_cm->srom_ccode, wlc_cm->srom_regrev); + + /* if regrev is -1, lookup the mapped country code, + * otherwise use the ccode and regrev directly + */ + if (regrev == -1) { + /* map the country code to a built-in country code, regrev, and country_info */ + country = + wlc_countrycode_map(wlc_cm, ccode, mapped_ccode, + &mapped_regrev); + } else { + /* find the matching built-in country definition */ + ASSERT(0); + country = wlc_country_lookup_direct(ccode, regrev); + strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ); + mapped_regrev = regrev; + } + + if (country == NULL) + return BCME_BADARG; + + /* set the driver state for the country */ + wlc_set_country_common(wlc_cm, country_abbrev, mapped_ccode, + mapped_regrev, country); + + return 0; +} + +/* set the driver's current country and regulatory information using a country code + * as the source. Look up built in country information found with the country code. + */ +static void +wlc_set_country_common(wlc_cm_info_t *wlc_cm, + const char *country_abbrev, + const char *ccode, uint regrev, + const country_info_t *country) +{ + const locale_mimo_info_t *li_mimo; + const locale_info_t *locale; + struct wlc_info *wlc = wlc_cm->wlc; + char prev_country_abbrev[WLC_CNTRY_BUF_SZ]; + + ASSERT(country != NULL); + + /* save current country state */ + wlc_cm->country = country; + + memset(&prev_country_abbrev, 0, WLC_CNTRY_BUF_SZ); + strncpy(prev_country_abbrev, wlc_cm->country_abbrev, + WLC_CNTRY_BUF_SZ - 1); + + strncpy(wlc_cm->country_abbrev, country_abbrev, WLC_CNTRY_BUF_SZ - 1); + strncpy(wlc_cm->ccode, ccode, WLC_CNTRY_BUF_SZ - 1); + wlc_cm->regrev = regrev; + + /* disable/restore nmode based on country regulations */ + li_mimo = wlc_get_mimo_2g(country->locale_mimo_2G); + if (li_mimo && (li_mimo->flags & WLC_NO_MIMO)) { + wlc_set_nmode(wlc, OFF); + wlc->stf->no_cddstbc = true; + } else { + wlc->stf->no_cddstbc = false; + if (N_ENAB(wlc->pub) != wlc->protection->nmode_user) + wlc_set_nmode(wlc, wlc->protection->nmode_user); + } + + wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); + wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); + /* set or restore gmode as required by regulatory */ + locale = wlc_get_locale_2g(country->locale_2G); + if (locale && (locale->flags & WLC_NO_OFDM)) { + wlc_set_gmode(wlc, GMODE_LEGACY_B, false); + } else { + wlc_set_gmode(wlc, wlc->protection->gmode_user, false); + } + + wlc_channels_init(wlc_cm, country); + + return; +} + +/* Lookup a country info structure from a null terminated country code + * The lookup is case sensitive. + */ +const country_info_t *wlc_country_lookup(struct wlc_info *wlc, + const char *ccode) +{ + const country_info_t *country; + char mapped_ccode[WLC_CNTRY_BUF_SZ]; + uint mapped_regrev; + + /* map the country code to a built-in country code, regrev, and country_info struct */ + country = + wlc_countrycode_map(wlc->cmi, ccode, mapped_ccode, &mapped_regrev); + + return country; +} + +static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm, + const char *ccode, + char *mapped_ccode, + uint *mapped_regrev) +{ + struct wlc_info *wlc = wlc_cm->wlc; + const country_info_t *country; + uint srom_regrev = wlc_cm->srom_regrev; + const char *srom_ccode = wlc_cm->srom_ccode; + int mapped; + + /* check for currently supported ccode size */ + if (strlen(ccode) > (WLC_CNTRY_BUF_SZ - 1)) { + WL_ERROR("wl%d: %s: ccode \"%s\" too long for match\n", + wlc->pub->unit, __func__, ccode); + return NULL; + } + + /* default mapping is the given ccode and regrev 0 */ + strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ); + *mapped_regrev = 0; + + /* If the desired country code matches the srom country code, + * then the mapped country is the srom regulatory rev. + * Otherwise look for an aggregate mapping. + */ + if (!strcmp(srom_ccode, ccode)) { + *mapped_regrev = srom_regrev; + mapped = 0; + WL_ERROR("srom_code == ccode %s\n", __func__); + ASSERT(0); + } else { + mapped = + wlc_country_aggregate_map(wlc_cm, ccode, mapped_ccode, + mapped_regrev); + } + + /* find the matching built-in country definition */ + country = wlc_country_lookup_direct(mapped_ccode, *mapped_regrev); + + /* if there is not an exact rev match, default to rev zero */ + if (country == NULL && *mapped_regrev != 0) { + *mapped_regrev = 0; + ASSERT(0); + country = + wlc_country_lookup_direct(mapped_ccode, *mapped_regrev); + } + + return country; +} + +static int +wlc_country_aggregate_map(wlc_cm_info_t *wlc_cm, const char *ccode, + char *mapped_ccode, uint *mapped_regrev) +{ + return false; +} + +/* Lookup a country info structure from a null terminated country + * abbreviation and regrev directly with no translation. + */ +static const country_info_t *wlc_country_lookup_direct(const char *ccode, + uint regrev) +{ + uint size, i; + + /* Should just return 0 for single locale driver. */ + /* Keep it this way in case we add more locales. (for now anyway) */ + + /* all other country def arrays are for regrev == 0, so if regrev is non-zero, fail */ + if (regrev > 0) + return NULL; + + /* find matched table entry from country code */ + size = ARRAY_SIZE(cntry_locales); + for (i = 0; i < size; i++) { + if (strcmp(ccode, cntry_locales[i].abbrev) == 0) { + return &cntry_locales[i].country; + } + } + + WL_ERROR("%s: Returning NULL\n", __func__); + ASSERT(0); + return NULL; +} + +static int +wlc_channels_init(wlc_cm_info_t *wlc_cm, const country_info_t *country) +{ + struct wlc_info *wlc = wlc_cm->wlc; + uint i, j; + struct wlcband *band; + const locale_info_t *li; + chanvec_t sup_chan; + const locale_mimo_info_t *li_mimo; + + band = wlc->band; + for (i = 0; i < NBANDS(wlc); + i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { + + li = BAND_5G(band->bandtype) ? + wlc_get_locale_5g(country->locale_5G) : + wlc_get_locale_2g(country->locale_2G); + ASSERT(li); + wlc_cm->bandstate[band->bandunit].locale_flags = li->flags; + li_mimo = BAND_5G(band->bandtype) ? + wlc_get_mimo_5g(country->locale_mimo_5G) : + wlc_get_mimo_2g(country->locale_mimo_2G); + ASSERT(li_mimo); + + /* merge the mimo non-mimo locale flags */ + wlc_cm->bandstate[band->bandunit].locale_flags |= + li_mimo->flags; + + wlc_cm->bandstate[band->bandunit].restricted_channels = + g_table_restricted_chan[li->restricted_channels]; + wlc_cm->bandstate[band->bandunit].radar_channels = + g_table_radar_set[li->radar_channels]; + + /* set the channel availability, + * masking out the channels that may not be supported on this phy + */ + wlc_phy_chanspec_band_validch(band->pi, band->bandtype, + &sup_chan); + wlc_locale_get_channels(li, + &wlc_cm->bandstate[band->bandunit]. + valid_channels); + for (j = 0; j < sizeof(chanvec_t); j++) + wlc_cm->bandstate[band->bandunit].valid_channels. + vec[j] &= sup_chan.vec[j]; + } + + wlc_quiet_channels_reset(wlc_cm); + wlc_channels_commit(wlc_cm); + + return 0; +} + +/* Update the radio state (enable/disable) and tx power targets + * based on a new set of channel/regulatory information + */ +static void wlc_channels_commit(wlc_cm_info_t *wlc_cm) +{ + struct wlc_info *wlc = wlc_cm->wlc; + uint chan; + struct txpwr_limits txpwr; + + /* search for the existence of any valid channel */ + for (chan = 0; chan < MAXCHANNEL; chan++) { + if (VALID_CHANNEL20_DB(wlc, chan)) { + break; + } + } + if (chan == MAXCHANNEL) + chan = INVCHANNEL; + + /* based on the channel search above, set or clear WL_RADIO_COUNTRY_DISABLE */ + if (chan == INVCHANNEL) { + /* country/locale with no valid channels, set the radio disable bit */ + mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); + WL_ERROR("wl%d: %s: no valid channel for \"%s\" nbands %d bandlocked %d\n", + wlc->pub->unit, __func__, + wlc_cm->country_abbrev, NBANDS(wlc), wlc->bandlocked); + } else + if (mboolisset(wlc->pub->radio_disabled, + WL_RADIO_COUNTRY_DISABLE)) { + /* country/locale with valid channel, clear the radio disable bit */ + mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); + } + + /* Now that the country abbreviation is set, if the radio supports 2G, then + * set channel 14 restrictions based on the new locale. + */ + if (NBANDS(wlc) > 1 || BAND_2G(wlc->band->bandtype)) { + wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi, + wlc_japan(wlc) ? true : + false); + } + + if (wlc->pub->up && chan != INVCHANNEL) { + wlc_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr); + wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, + &txpwr, + WLC_TXPWR_MAX); + wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec); + } +} + +/* reset the quiet channels vector to the union of the restricted and radar channel sets */ +void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm) +{ + struct wlc_info *wlc = wlc_cm->wlc; + uint i, j; + struct wlcband *band; + const chanvec_t *chanvec; + + memset(&wlc_cm->quiet_channels, 0, sizeof(chanvec_t)); + + band = wlc->band; + for (i = 0; i < NBANDS(wlc); + i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { + + /* initialize quiet channels for restricted channels */ + chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels; + for (j = 0; j < sizeof(chanvec_t); j++) + wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j]; + + } +} + +bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec) +{ + return N_ENAB(wlc_cm->wlc->pub) && CHSPEC_IS40(chspec) ? + (isset + (wlc_cm->quiet_channels.vec, + LOWER_20_SB(CHSPEC_CHANNEL(chspec))) + || isset(wlc_cm->quiet_channels.vec, + UPPER_20_SB(CHSPEC_CHANNEL(chspec)))) : isset(wlc_cm-> + quiet_channels. + vec, + CHSPEC_CHANNEL + (chspec)); +} + +/* Is the channel valid for the current locale? (but don't consider channels not + * available due to bandlocking) + */ +bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val) +{ + struct wlc_info *wlc = wlc_cm->wlc; + + return VALID_CHANNEL20(wlc, val) || + (!wlc->bandlocked + && VALID_CHANNEL20_IN_BAND(wlc, OTHERBANDUNIT(wlc), val)); +} + +/* Is the channel valid for the current locale and specified band? */ +bool +wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, uint val) +{ + return ((val < MAXCHANNEL) + && isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val)); +} + +/* Is the channel valid for the current locale and current band? */ +bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val) +{ + struct wlc_info *wlc = wlc_cm->wlc; + + return ((val < MAXCHANNEL) && + isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec, + val)); +} + +/* Is the 40 MHz allowed for the current locale and specified band? */ +bool wlc_valid_40chanspec_in_band(wlc_cm_info_t *wlc_cm, uint bandunit) +{ + struct wlc_info *wlc = wlc_cm->wlc; + + return (((wlc_cm->bandstate[bandunit]. + locale_flags & (WLC_NO_MIMO | WLC_NO_40MHZ)) == 0) + && wlc->bandstate[bandunit]->mimo_cap_40); +} + +static void +wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t *wlc_cm, + struct txpwr_limits *txpwr, + u8 + local_constraint_qdbm) +{ + int j; + + /* CCK Rates */ + for (j = 0; j < WL_TX_POWER_CCK_NUM; j++) { + txpwr->cck[j] = min(txpwr->cck[j], local_constraint_qdbm); + } + + /* 20 MHz Legacy OFDM SISO */ + for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++) { + txpwr->ofdm[j] = min(txpwr->ofdm[j], local_constraint_qdbm); + } + + /* 20 MHz Legacy OFDM CDD */ + for (j = 0; j < WLC_NUM_RATES_OFDM; j++) { + txpwr->ofdm_cdd[j] = + min(txpwr->ofdm_cdd[j], local_constraint_qdbm); + } + + /* 40 MHz Legacy OFDM SISO */ + for (j = 0; j < WLC_NUM_RATES_OFDM; j++) { + txpwr->ofdm_40_siso[j] = + min(txpwr->ofdm_40_siso[j], local_constraint_qdbm); + } + + /* 40 MHz Legacy OFDM CDD */ + for (j = 0; j < WLC_NUM_RATES_OFDM; j++) { + txpwr->ofdm_40_cdd[j] = + min(txpwr->ofdm_40_cdd[j], local_constraint_qdbm); + } + + /* 20MHz MCS 0-7 SISO */ + for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { + txpwr->mcs_20_siso[j] = + min(txpwr->mcs_20_siso[j], local_constraint_qdbm); + } + + /* 20MHz MCS 0-7 CDD */ + for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { + txpwr->mcs_20_cdd[j] = + min(txpwr->mcs_20_cdd[j], local_constraint_qdbm); + } + + /* 20MHz MCS 0-7 STBC */ + for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { + txpwr->mcs_20_stbc[j] = + min(txpwr->mcs_20_stbc[j], local_constraint_qdbm); + } + + /* 20MHz MCS 8-15 MIMO */ + for (j = 0; j < WLC_NUM_RATES_MCS_2_STREAM; j++) + txpwr->mcs_20_mimo[j] = + min(txpwr->mcs_20_mimo[j], local_constraint_qdbm); + + /* 40MHz MCS 0-7 SISO */ + for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { + txpwr->mcs_40_siso[j] = + min(txpwr->mcs_40_siso[j], local_constraint_qdbm); + } + + /* 40MHz MCS 0-7 CDD */ + for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { + txpwr->mcs_40_cdd[j] = + min(txpwr->mcs_40_cdd[j], local_constraint_qdbm); + } + + /* 40MHz MCS 0-7 STBC */ + for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { + txpwr->mcs_40_stbc[j] = + min(txpwr->mcs_40_stbc[j], local_constraint_qdbm); + } + + /* 40MHz MCS 8-15 MIMO */ + for (j = 0; j < WLC_NUM_RATES_MCS_2_STREAM; j++) + txpwr->mcs_40_mimo[j] = + min(txpwr->mcs_40_mimo[j], local_constraint_qdbm); + + /* 40MHz MCS 32 */ + txpwr->mcs32 = min(txpwr->mcs32, local_constraint_qdbm); + +} + +void +wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, + u8 local_constraint_qdbm) +{ + struct wlc_info *wlc = wlc_cm->wlc; + struct txpwr_limits txpwr; + + wlc_channel_reg_limits(wlc_cm, chanspec, &txpwr); + + wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr, + local_constraint_qdbm); + + wlc_bmac_set_chanspec(wlc->hw, chanspec, + (wlc_quiet_chanspec(wlc_cm, chanspec) != 0), + &txpwr); +} + +int +wlc_channel_set_txpower_limit(wlc_cm_info_t *wlc_cm, + u8 local_constraint_qdbm) +{ + struct wlc_info *wlc = wlc_cm->wlc; + struct txpwr_limits txpwr; + + wlc_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr); + + wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr, + local_constraint_qdbm); + + wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec); + + return 0; +} + +#ifdef POWER_DBG +static void wlc_phy_txpower_limits_dump(txpwr_limits_t *txpwr) +{ + int i; + char fraction[4][4] = { " ", ".25", ".5 ", ".75" }; + + printf("CCK "); + for (i = 0; i < WLC_NUM_RATES_CCK; i++) { + printf(" %2d%s", txpwr->cck[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->cck[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("20 MHz OFDM SISO "); + for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { + printf(" %2d%s", txpwr->ofdm[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->ofdm[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("20 MHz OFDM CDD "); + for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { + printf(" %2d%s", txpwr->ofdm_cdd[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->ofdm_cdd[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("40 MHz OFDM SISO "); + for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { + printf(" %2d%s", txpwr->ofdm_40_siso[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->ofdm_40_siso[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("40 MHz OFDM CDD "); + for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { + printf(" %2d%s", txpwr->ofdm_40_cdd[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->ofdm_40_cdd[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("20 MHz MCS0-7 SISO "); + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + printf(" %2d%s", txpwr->mcs_20_siso[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_20_siso[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("20 MHz MCS0-7 CDD "); + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + printf(" %2d%s", txpwr->mcs_20_cdd[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_20_cdd[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("20 MHz MCS0-7 STBC "); + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + printf(" %2d%s", txpwr->mcs_20_stbc[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_20_stbc[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("20 MHz MCS8-15 SDM "); + for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) { + printf(" %2d%s", txpwr->mcs_20_mimo[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_20_mimo[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("40 MHz MCS0-7 SISO "); + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + printf(" %2d%s", txpwr->mcs_40_siso[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_40_siso[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("40 MHz MCS0-7 CDD "); + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + printf(" %2d%s", txpwr->mcs_40_cdd[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_40_cdd[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("40 MHz MCS0-7 STBC "); + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + printf(" %2d%s", txpwr->mcs_40_stbc[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_40_stbc[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("40 MHz MCS8-15 SDM "); + for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) { + printf(" %2d%s", txpwr->mcs_40_mimo[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_40_mimo[i] % WLC_TXPWR_DB_FACTOR]); + } + printf("\n"); + + printf("MCS32 %2d%s\n", + txpwr->mcs32 / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs32 % WLC_TXPWR_DB_FACTOR]); +} +#endif /* POWER_DBG */ + +void +wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, + txpwr_limits_t *txpwr) +{ + struct wlc_info *wlc = wlc_cm->wlc; + uint i; + uint chan; + int maxpwr; + int delta; + const country_info_t *country; + struct wlcband *band; + const locale_info_t *li; + int conducted_max; + int conducted_ofdm_max; + const locale_mimo_info_t *li_mimo; + int maxpwr20, maxpwr40; + int maxpwr_idx; + uint j; + + memset(txpwr, 0, sizeof(txpwr_limits_t)); + + if (!wlc_valid_chanspec_db(wlc_cm, chanspec)) { + country = wlc_country_lookup(wlc, wlc->autocountry_default); + if (country == NULL) + return; + } else { + country = wlc_cm->country; + } + + chan = CHSPEC_CHANNEL(chanspec); + band = wlc->bandstate[CHSPEC_WLCBANDUNIT(chanspec)]; + li = BAND_5G(band->bandtype) ? + wlc_get_locale_5g(country->locale_5G) : + wlc_get_locale_2g(country->locale_2G); + + li_mimo = BAND_5G(band->bandtype) ? + wlc_get_mimo_5g(country->locale_mimo_5G) : + wlc_get_mimo_2g(country->locale_mimo_2G); + + if (li->flags & WLC_EIRP) { + delta = band->antgain; + } else { + delta = 0; + if (band->antgain > QDB(6)) + delta = band->antgain - QDB(6); /* Excess over 6 dB */ + } + + if (li == &locale_i) { + conducted_max = QDB(22); + conducted_ofdm_max = QDB(22); + } + + /* CCK txpwr limits for 2.4G band */ + if (BAND_2G(band->bandtype)) { + maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_CCK(chan)]; + + maxpwr = maxpwr - delta; + maxpwr = max(maxpwr, 0); + maxpwr = min(maxpwr, conducted_max); + + for (i = 0; i < WLC_NUM_RATES_CCK; i++) + txpwr->cck[i] = (u8) maxpwr; + } + + /* OFDM txpwr limits for 2.4G or 5G bands */ + if (BAND_2G(band->bandtype)) { + maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_OFDM(chan)]; + + } else { + maxpwr = li->maxpwr[CHANNEL_POWER_IDX_5G(chan)]; + } + + maxpwr = maxpwr - delta; + maxpwr = max(maxpwr, 0); + maxpwr = min(maxpwr, conducted_ofdm_max); + + /* Keep OFDM lmit below CCK limit */ + if (BAND_2G(band->bandtype)) + maxpwr = min_t(int, maxpwr, txpwr->cck[0]); + + for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { + txpwr->ofdm[i] = (u8) maxpwr; + } + + for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { + /* OFDM 40 MHz SISO has the same power as the corresponding MCS0-7 rate unless + * overriden by the locale specific code. We set this value to 0 as a + * flag (presumably 0 dBm isn't a possibility) and then copy the MCS0-7 value + * to the 40 MHz value if it wasn't explicitly set. + */ + txpwr->ofdm_40_siso[i] = 0; + + txpwr->ofdm_cdd[i] = (u8) maxpwr; + + txpwr->ofdm_40_cdd[i] = 0; + } + + /* MIMO/HT specific limits */ + if (li_mimo->flags & WLC_EIRP) { + delta = band->antgain; + } else { + delta = 0; + if (band->antgain > QDB(6)) + delta = band->antgain - QDB(6); /* Excess over 6 dB */ + } + + if (BAND_2G(band->bandtype)) + maxpwr_idx = (chan - 1); + else + maxpwr_idx = CHANNEL_POWER_IDX_5G(chan); + + maxpwr20 = li_mimo->maxpwr20[maxpwr_idx]; + maxpwr40 = li_mimo->maxpwr40[maxpwr_idx]; + + maxpwr20 = maxpwr20 - delta; + maxpwr20 = max(maxpwr20, 0); + maxpwr40 = maxpwr40 - delta; + maxpwr40 = max(maxpwr40, 0); + + /* Fill in the MCS 0-7 (SISO) rates */ + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + + /* 20 MHz has the same power as the corresponding OFDM rate unless + * overriden by the locale specific code. + */ + txpwr->mcs_20_siso[i] = txpwr->ofdm[i]; + txpwr->mcs_40_siso[i] = 0; + } + + /* Fill in the MCS 0-7 CDD rates */ + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + txpwr->mcs_20_cdd[i] = (u8) maxpwr20; + txpwr->mcs_40_cdd[i] = (u8) maxpwr40; + } + + /* These locales have SISO expressed in the table and override CDD later */ + if (li_mimo == &locale_bn) { + if (li_mimo == &locale_bn) { + maxpwr20 = QDB(16); + maxpwr40 = 0; + + if (chan >= 3 && chan <= 11) { + maxpwr40 = QDB(16); + } + } + + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + txpwr->mcs_20_siso[i] = (u8) maxpwr20; + txpwr->mcs_40_siso[i] = (u8) maxpwr40; + } + } + + /* Fill in the MCS 0-7 STBC rates */ + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + txpwr->mcs_20_stbc[i] = 0; + txpwr->mcs_40_stbc[i] = 0; + } + + /* Fill in the MCS 8-15 SDM rates */ + for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) { + txpwr->mcs_20_mimo[i] = (u8) maxpwr20; + txpwr->mcs_40_mimo[i] = (u8) maxpwr40; + } + + /* Fill in MCS32 */ + txpwr->mcs32 = (u8) maxpwr40; + + for (i = 0, j = 0; i < WLC_NUM_RATES_OFDM; i++, j++) { + if (txpwr->ofdm_40_cdd[i] == 0) + txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j]; + if (i == 0) { + i = i + 1; + if (txpwr->ofdm_40_cdd[i] == 0) + txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j]; + } + } + + /* Copy the 40 MHZ MCS 0-7 CDD value to the 40 MHZ MCS 0-7 SISO value if it wasn't + * provided explicitly. + */ + + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + if (txpwr->mcs_40_siso[i] == 0) + txpwr->mcs_40_siso[i] = txpwr->mcs_40_cdd[i]; + } + + for (i = 0, j = 0; i < WLC_NUM_RATES_OFDM; i++, j++) { + if (txpwr->ofdm_40_siso[i] == 0) + txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j]; + if (i == 0) { + i = i + 1; + if (txpwr->ofdm_40_siso[i] == 0) + txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j]; + } + } + + /* Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding STBC values if they weren't + * provided explicitly. + */ + for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + if (txpwr->mcs_20_stbc[i] == 0) + txpwr->mcs_20_stbc[i] = txpwr->mcs_20_cdd[i]; + + if (txpwr->mcs_40_stbc[i] == 0) + txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i]; + } + +#ifdef POWER_DBG + wlc_phy_txpower_limits_dump(txpwr); +#endif + return; +} + +/* Returns true if currently set country is Japan or variant */ +bool wlc_japan(struct wlc_info *wlc) +{ + return wlc_japan_ccode(wlc->cmi->country_abbrev); +} + +/* JP, J1 - J10 are Japan ccodes */ +static bool wlc_japan_ccode(const char *ccode) +{ + return (ccode[0] == 'J' && + (ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9'))); +} + +/* + * Validate the chanspec for this locale, for 40MHZ we need to also check that the sidebands + * are valid 20MZH channels in this locale and they are also a legal HT combination + */ +static bool +wlc_valid_chanspec_ext(wlc_cm_info_t *wlc_cm, chanspec_t chspec, bool dualband) +{ + struct wlc_info *wlc = wlc_cm->wlc; + u8 channel = CHSPEC_CHANNEL(chspec); + + /* check the chanspec */ + if (wf_chspec_malformed(chspec)) { + WL_ERROR("wl%d: malformed chanspec 0x%x\n", + wlc->pub->unit, chspec); + ASSERT(0); + return false; + } + + if (CHANNEL_BANDUNIT(wlc_cm->wlc, channel) != + CHSPEC_WLCBANDUNIT(chspec)) + return false; + + /* Check a 20Mhz channel */ + if (CHSPEC_IS20(chspec)) { + if (dualband) + return VALID_CHANNEL20_DB(wlc_cm->wlc, channel); + else + return VALID_CHANNEL20(wlc_cm->wlc, channel); + } +#ifdef SUPPORT_40MHZ + /* We know we are now checking a 40MHZ channel, so we should only be here + * for NPHYS + */ + if (WLCISNPHY(wlc->band) || WLCISSSLPNPHY(wlc->band)) { + u8 upper_sideband = 0, idx; + u8 num_ch20_entries = + sizeof(chan20_info) / sizeof(struct chan20_info); + + if (!VALID_40CHANSPEC_IN_BAND(wlc, CHSPEC_WLCBANDUNIT(chspec))) + return false; + + if (dualband) { + if (!VALID_CHANNEL20_DB(wlc, LOWER_20_SB(channel)) || + !VALID_CHANNEL20_DB(wlc, UPPER_20_SB(channel))) + return false; + } else { + if (!VALID_CHANNEL20(wlc, LOWER_20_SB(channel)) || + !VALID_CHANNEL20(wlc, UPPER_20_SB(channel))) + return false; + } + + /* find the lower sideband info in the sideband array */ + for (idx = 0; idx < num_ch20_entries; idx++) { + if (chan20_info[idx].sb == LOWER_20_SB(channel)) + upper_sideband = chan20_info[idx].adj_sbs; + } + /* check that the lower sideband allows an upper sideband */ + if ((upper_sideband & (CH_UPPER_SB | CH_EWA_VALID)) == + (CH_UPPER_SB | CH_EWA_VALID)) + return true; + return false; + } +#endif /* 40 MHZ */ + + return false; +} + +bool wlc_valid_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec) +{ + return wlc_valid_chanspec_ext(wlc_cm, chspec, false); +} + +bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec) +{ + return wlc_valid_chanspec_ext(wlc_cm, chspec, true); +} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.h b/drivers/staging/brcm80211/brcmsmac/wlc_channel.h new file mode 100644 index 000000000000..1f170aff68fd --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_channel.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _WLC_CHANNEL_H_ +#define _WLC_CHANNEL_H_ + +#include + +#define WLC_TXPWR_DB_FACTOR 4 /* conversion for phy txpwr cacluations that use .25 dB units */ + +struct wlc_info; + +/* maxpwr mapping to 5GHz band channels: + * maxpwr[0] - channels [34-48] + * maxpwr[1] - channels [52-60] + * maxpwr[2] - channels [62-64] + * maxpwr[3] - channels [100-140] + * maxpwr[4] - channels [149-165] + */ +#define BAND_5G_PWR_LVLS 5 /* 5 power levels for 5G */ + +/* power level in group of 2.4GHz band channels: + * maxpwr[0] - CCK channels [1] + * maxpwr[1] - CCK channels [2-10] + * maxpwr[2] - CCK channels [11-14] + * maxpwr[3] - OFDM channels [1] + * maxpwr[4] - OFDM channels [2-10] + * maxpwr[5] - OFDM channels [11-14] + */ + +/* macro to get 2.4 GHz channel group index for tx power */ +#define CHANNEL_POWER_IDX_2G_CCK(c) (((c) < 2) ? 0 : (((c) < 11) ? 1 : 2)) /* cck index */ +#define CHANNEL_POWER_IDX_2G_OFDM(c) (((c) < 2) ? 3 : (((c) < 11) ? 4 : 5)) /* ofdm index */ + +/* macro to get 5 GHz channel group index for tx power */ +#define CHANNEL_POWER_IDX_5G(c) \ + (((c) < 52) ? 0 : (((c) < 62) ? 1 : (((c) < 100) ? 2 : (((c) < 149) ? 3 : 4)))) + +#define WLC_MAXPWR_TBL_SIZE 6 /* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */ +#define WLC_MAXPWR_MIMO_TBL_SIZE 14 /* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */ + +/* locale channel and power info. */ +typedef struct { + u32 valid_channels; + u8 radar_channels; /* List of radar sensitive channels */ + u8 restricted_channels; /* List of channels used only if APs are detected */ + s8 maxpwr[WLC_MAXPWR_TBL_SIZE]; /* Max tx pwr in qdBm for each sub-band */ + s8 pub_maxpwr[BAND_5G_PWR_LVLS]; /* Country IE advertised max tx pwr in dBm + * per sub-band + */ + u8 flags; +} locale_info_t; + +/* bits for locale_info flags */ +#define WLC_PEAK_CONDUCTED 0x00 /* Peak for locals */ +#define WLC_EIRP 0x01 /* Flag for EIRP */ +#define WLC_DFS_TPC 0x02 /* Flag for DFS TPC */ +#define WLC_NO_OFDM 0x04 /* Flag for No OFDM */ +#define WLC_NO_40MHZ 0x08 /* Flag for No MIMO 40MHz */ +#define WLC_NO_MIMO 0x10 /* Flag for No MIMO, 20 or 40 MHz */ +#define WLC_RADAR_TYPE_EU 0x20 /* Flag for EU */ +#define WLC_DFS_FCC WLC_DFS_TPC /* Flag for DFS FCC */ +#define WLC_DFS_EU (WLC_DFS_TPC | WLC_RADAR_TYPE_EU) /* Flag for DFS EU */ + +#define ISDFS_EU(fl) (((fl) & WLC_DFS_EU) == WLC_DFS_EU) + +/* locale per-channel tx power limits for MIMO frames + * maxpwr arrays are index by channel for 2.4 GHz limits, and + * by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel) + */ +typedef struct { + s8 maxpwr20[WLC_MAXPWR_MIMO_TBL_SIZE]; /* tx 20 MHz power limits, qdBm units */ + s8 maxpwr40[WLC_MAXPWR_MIMO_TBL_SIZE]; /* tx 40 MHz power limits, qdBm units */ + u8 flags; +} locale_mimo_info_t; + +extern const chanvec_t chanvec_all_2G; +extern const chanvec_t chanvec_all_5G; + +/* + * Country names and abbreviations with locale defined from ISO 3166 + */ +struct country_info { + const u8 locale_2G; /* 2.4G band locale */ + const u8 locale_5G; /* 5G band locale */ + const u8 locale_mimo_2G; /* 2.4G mimo info */ + const u8 locale_mimo_5G; /* 5G mimo info */ +}; + +typedef struct country_info country_info_t; + +typedef struct wlc_cm_info wlc_cm_info_t; + +extern wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc); +extern void wlc_channel_mgr_detach(wlc_cm_info_t *wlc_cm); + +extern int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode); +extern int wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, + const char *country_abbrev, + const char *ccode, int regrev); + +extern const char *wlc_channel_country_abbrev(wlc_cm_info_t *wlc_cm); +extern u8 wlc_channel_locale_flags(wlc_cm_info_t *wlc_cm); +extern u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, + uint bandunit); + +extern void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm); +extern bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec); + +#define VALID_CHANNEL20_DB(wlc, val) wlc_valid_channel20_db((wlc)->cmi, val) +#define VALID_CHANNEL20_IN_BAND(wlc, bandunit, val) \ + wlc_valid_channel20_in_band((wlc)->cmi, bandunit, val) +#define VALID_CHANNEL20(wlc, val) wlc_valid_channel20((wlc)->cmi, val) +#define VALID_40CHANSPEC_IN_BAND(wlc, bandunit) wlc_valid_40chanspec_in_band((wlc)->cmi, bandunit) + +extern bool wlc_valid_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec); +extern bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec); +extern bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val); +extern bool wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, + uint val); +extern bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val); +extern bool wlc_valid_40chanspec_in_band(wlc_cm_info_t *wlc_cm, uint bandunit); + +extern void wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, + chanspec_t chanspec, + struct txpwr_limits *txpwr); +extern void wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm, + chanspec_t chanspec, + u8 local_constraint_qdbm); +extern int wlc_channel_set_txpower_limit(wlc_cm_info_t *wlc_cm, + u8 local_constraint_qdbm); + +extern const country_info_t *wlc_country_lookup(struct wlc_info *wlc, + const char *ccode); +extern void wlc_locale_get_channels(const locale_info_t *locale, + chanvec_t *valid_channels); +extern const locale_info_t *wlc_get_locale_2g(u8 locale_idx); +extern const locale_info_t *wlc_get_locale_5g(u8 locale_idx); +extern bool wlc_japan(struct wlc_info *wlc); + +extern u8 wlc_get_regclass(wlc_cm_info_t *wlc_cm, chanspec_t chanspec); +extern bool wlc_channel_get_chanvec(struct wlc_info *wlc, + const char *country_abbrev, int bandtype, + chanvec_t *channels); + +#endif /* _WLC_CHANNEL_H */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_event.c b/drivers/staging/brcm80211/brcmsmac/wlc_event.c new file mode 100644 index 000000000000..12b156a82ff2 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_event.c @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* Local prototypes */ +static void wlc_timer_cb(void *arg); + +/* Private data structures */ +struct wlc_eventq { + wlc_event_t *head; + wlc_event_t *tail; + struct wlc_info *wlc; + void *wl; + struct wlc_pub *pub; + bool tpending; + bool workpending; + struct wl_timer *timer; + wlc_eventq_cb_t cb; + u8 event_inds_mask[broken_roundup(WLC_E_LAST, NBBY) / NBBY]; +}; + +/* + * Export functions + */ +wlc_eventq_t *wlc_eventq_attach(struct wlc_pub *pub, struct wlc_info *wlc, + void *wl, + wlc_eventq_cb_t cb) +{ + wlc_eventq_t *eq; + + eq = kzalloc(sizeof(wlc_eventq_t), GFP_ATOMIC); + if (eq == NULL) + return NULL; + + eq->cb = cb; + eq->wlc = wlc; + eq->wl = wl; + eq->pub = pub; + + eq->timer = wl_init_timer(eq->wl, wlc_timer_cb, eq, "eventq"); + if (!eq->timer) { + WL_ERROR("wl%d: wlc_eventq_attach: timer failed\n", + pub->unit); + kfree(eq); + return NULL; + } + + return eq; +} + +int wlc_eventq_detach(wlc_eventq_t *eq) +{ + /* Clean up pending events */ + wlc_eventq_down(eq); + + if (eq->timer) { + if (eq->tpending) { + wl_del_timer(eq->wl, eq->timer); + eq->tpending = false; + } + wl_free_timer(eq->wl, eq->timer); + eq->timer = NULL; + } + + ASSERT(wlc_eventq_avail(eq) == false); + kfree(eq); + return 0; +} + +int wlc_eventq_down(wlc_eventq_t *eq) +{ + int callbacks = 0; + if (eq->tpending && !eq->workpending) { + if (!wl_del_timer(eq->wl, eq->timer)) + callbacks++; + + ASSERT(wlc_eventq_avail(eq) == true); + ASSERT(eq->workpending == false); + eq->workpending = true; + if (eq->cb) + eq->cb(eq->wlc); + + ASSERT(eq->workpending == true); + eq->workpending = false; + eq->tpending = false; + } else { + ASSERT(eq->workpending || wlc_eventq_avail(eq) == false); + } + return callbacks; +} + +wlc_event_t *wlc_event_alloc(wlc_eventq_t *eq) +{ + wlc_event_t *e; + + e = kzalloc(sizeof(wlc_event_t), GFP_ATOMIC); + + if (e == NULL) + return NULL; + + return e; +} + +void wlc_event_free(wlc_eventq_t *eq, wlc_event_t *e) +{ + ASSERT(e->data == NULL); + ASSERT(e->next == NULL); + kfree(e); +} + +void wlc_eventq_enq(wlc_eventq_t *eq, wlc_event_t *e) +{ + ASSERT(e->next == NULL); + e->next = NULL; + + if (eq->tail) { + eq->tail->next = e; + eq->tail = e; + } else + eq->head = eq->tail = e; + + if (!eq->tpending) { + eq->tpending = true; + /* Use a zero-delay timer to trigger + * delayed processing of the event. + */ + wl_add_timer(eq->wl, eq->timer, 0, 0); + } +} + +wlc_event_t *wlc_eventq_deq(wlc_eventq_t *eq) +{ + wlc_event_t *e; + + e = eq->head; + if (e) { + eq->head = e->next; + e->next = NULL; + + if (eq->head == NULL) + eq->tail = eq->head; + } + return e; +} + +wlc_event_t *wlc_eventq_next(wlc_eventq_t *eq, wlc_event_t *e) +{ +#ifdef BCMDBG + wlc_event_t *etmp; + + for (etmp = eq->head; etmp; etmp = etmp->next) { + if (etmp == e) + break; + } + ASSERT(etmp != NULL); +#endif + + return e->next; +} + +int wlc_eventq_cnt(wlc_eventq_t *eq) +{ + wlc_event_t *etmp; + int cnt = 0; + + for (etmp = eq->head; etmp; etmp = etmp->next) + cnt++; + + return cnt; +} + +bool wlc_eventq_avail(wlc_eventq_t *eq) +{ + return (eq->head != NULL); +} + +/* + * Local Functions + */ +static void wlc_timer_cb(void *arg) +{ + struct wlc_eventq *eq = (struct wlc_eventq *)arg; + + ASSERT(eq->tpending == true); + ASSERT(wlc_eventq_avail(eq) == true); + ASSERT(eq->workpending == false); + eq->workpending = true; + + if (eq->cb) + eq->cb(eq->wlc); + + ASSERT(wlc_eventq_avail(eq) == false); + ASSERT(eq->tpending == true); + eq->workpending = false; + eq->tpending = false; +} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_event.h b/drivers/staging/brcm80211/brcmsmac/wlc_event.h new file mode 100644 index 000000000000..e75582dcdd93 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_event.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _WLC_EVENT_H_ +#define _WLC_EVENT_H_ + +typedef struct wlc_eventq wlc_eventq_t; + +typedef void (*wlc_eventq_cb_t) (void *arg); + +extern wlc_eventq_t *wlc_eventq_attach(struct wlc_pub *pub, + struct wlc_info *wlc, + void *wl, wlc_eventq_cb_t cb); +extern int wlc_eventq_detach(wlc_eventq_t *eq); +extern int wlc_eventq_down(wlc_eventq_t *eq); +extern void wlc_event_free(wlc_eventq_t *eq, wlc_event_t *e); +extern wlc_event_t *wlc_eventq_next(wlc_eventq_t *eq, wlc_event_t *e); +extern int wlc_eventq_cnt(wlc_eventq_t *eq); +extern bool wlc_eventq_avail(wlc_eventq_t *eq); +extern wlc_event_t *wlc_eventq_deq(wlc_eventq_t *eq); +extern void wlc_eventq_enq(wlc_eventq_t *eq, wlc_event_t *e); +extern wlc_event_t *wlc_event_alloc(wlc_eventq_t *eq); + +extern int wlc_eventq_register_ind(wlc_eventq_t *eq, void *bitvect); +extern int wlc_eventq_query_ind(wlc_eventq_t *eq, void *bitvect); +extern int wlc_eventq_test_ind(wlc_eventq_t *eq, int et); +extern int wlc_eventq_set_ind(wlc_eventq_t *eq, uint et, bool on); +extern void wlc_eventq_flush(wlc_eventq_t *eq); +extern void wlc_assign_event_msg(struct wlc_info *wlc, wl_event_msg_t *msg, + const wlc_event_t *e, u8 *data, + u32 len); + +#ifdef MSGTRACE +extern void wlc_event_sendup_trace(struct wlc_info *wlc, hndrte_dev_t *bus, + u8 *hdr, u16 hdrlen, u8 *buf, + u16 buflen); +#endif + +#endif /* _WLC_EVENT_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_key.h b/drivers/staging/brcm80211/brcmsmac/wlc_key.h new file mode 100644 index 000000000000..3e23d5145919 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_key.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_key_h_ +#define _wlc_key_h_ + +struct scb; +struct wlc_info; +struct wlc_bsscfg; +/* Maximum # of keys that wl driver supports in S/W. + * Keys supported in H/W is less than or equal to WSEC_MAX_KEYS. + */ +#define WSEC_MAX_KEYS 54 /* Max # of keys (50 + 4 default keys) */ +#define WLC_DEFAULT_KEYS 4 /* Default # of keys */ + +#define WSEC_MAX_WOWL_KEYS 5 /* Max keys in WOWL mode (1 + 4 default keys) */ + +#define WPA2_GTK_MAX 3 + +/* +* Max # of keys currently supported: +* +* s/w keys if WSEC_SW(wlc->wsec). +* h/w keys otherwise. +*/ +#define WLC_MAX_WSEC_KEYS(wlc) WSEC_MAX_KEYS + +/* number of 802.11 default (non-paired, group keys) */ +#define WSEC_MAX_DEFAULT_KEYS 4 /* # of default keys */ + +/* Max # of hardware keys supported */ +#define WLC_MAX_WSEC_HW_KEYS(wlc) WSEC_MAX_RCMTA_KEYS + +/* Max # of hardware TKIP MIC keys supported */ +#define WLC_MAX_TKMIC_HW_KEYS(wlc) ((D11REV_GE((wlc)->pub->corerev, 13)) ? \ + WSEC_MAX_TKMIC_ENGINE_KEYS : 0) + +#define WSEC_HW_TKMIC_KEY(wlc, key, bsscfg) \ + (((D11REV_GE((wlc)->pub->corerev, 13)) && ((wlc)->machwcap & MCAP_TKIPMIC)) && \ + (key) && ((key)->algo == CRYPTO_ALGO_TKIP) && \ + !WSEC_SOFTKEY(wlc, key, bsscfg) && \ + WSEC_KEY_INDEX(wlc, key) >= WLC_DEFAULT_KEYS && \ + (WSEC_KEY_INDEX(wlc, key) < WSEC_MAX_TKMIC_ENGINE_KEYS)) + +/* index of key in key table */ +#define WSEC_KEY_INDEX(wlc, key) ((key)->idx) + +#define WSEC_SOFTKEY(wlc, key, bsscfg) (WLC_SW_KEYS(wlc, bsscfg) || \ + WSEC_KEY_INDEX(wlc, key) >= WLC_MAX_WSEC_HW_KEYS(wlc)) + +/* get a key, non-NULL only if key allocated and not clear */ +#define WSEC_KEY(wlc, i) (((wlc)->wsec_keys[i] && (wlc)->wsec_keys[i]->len) ? \ + (wlc)->wsec_keys[i] : NULL) + +#define WSEC_SCB_KEY_VALID(scb) (((scb)->key && (scb)->key->len) ? true : false) + +/* default key */ +#define WSEC_BSS_DEFAULT_KEY(bsscfg) (((bsscfg)->wsec_index == -1) ? \ + (struct wsec_key *)NULL:(bsscfg)->bss_def_keys[(bsscfg)->wsec_index]) + +/* Macros for key management in IBSS mode */ +#define WSEC_IBSS_MAX_PEERS 16 /* Max # of IBSS Peers */ +#define WSEC_IBSS_RCMTA_INDEX(idx) \ + (((idx - WSEC_MAX_DEFAULT_KEYS) % WSEC_IBSS_MAX_PEERS) + WSEC_MAX_DEFAULT_KEYS) + +/* contiguous # key slots for infrastructure mode STA */ +#define WSEC_BSS_STA_KEY_GROUP_SIZE 5 + +typedef struct wsec_iv { + u32 hi; /* upper 32 bits of IV */ + u16 lo; /* lower 16 bits of IV */ +} wsec_iv_t; + +#define WLC_NUMRXIVS 16 /* # rx IVs (one per 802.11e TID) */ + +typedef struct wsec_key { + u8 ea[ETH_ALEN]; /* per station */ + u8 idx; /* key index in wsec_keys array */ + u8 id; /* key ID [0-3] */ + u8 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ + u8 rcmta; /* rcmta entry index, same as idx by default */ + u16 flags; /* misc flags */ + u8 algo_hw; /* cache for hw register */ + u8 aes_mode; /* cache for hw register */ + s8 iv_len; /* IV length */ + s8 icv_len; /* ICV length */ + u32 len; /* key length..don't move this var */ + /* data is 4byte aligned */ + u8 data[DOT11_MAX_KEY_SIZE]; /* key data */ + wsec_iv_t rxiv[WLC_NUMRXIVS]; /* Rx IV (one per TID) */ + wsec_iv_t txiv; /* Tx IV */ + +} wsec_key_t; + +#define broken_roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) +typedef struct { + u8 vec[broken_roundup(WSEC_MAX_KEYS, NBBY) / NBBY]; /* bitvec of wsec_key indexes */ +} wsec_key_vec_t; + +/* For use with wsec_key_t.flags */ + +#define WSEC_BS_UPDATE (1 << 0) /* Indicates hw needs key update on BS switch */ +#define WSEC_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */ +#define WSEC_TKIP_ERROR (1 << 2) /* Provoke deliberate MIC error */ +#define WSEC_REPLAY_ERROR (1 << 3) /* Provoke deliberate replay */ +#define WSEC_IBSS_PEER_GROUP_KEY (1 << 7) /* Flag: group key for a IBSS PEER */ +#define WSEC_ICV_ERROR (1 << 8) /* Provoke deliberate ICV error */ + +#define wlc_key_insert(a, b, c, d, e, f, g, h, i, j) (BCME_ERROR) +#define wlc_key_update(a, b, c) do {} while (0) +#define wlc_key_remove(a, b, c) do {} while (0) +#define wlc_key_remove_all(a, b) do {} while (0) +#define wlc_key_delete(a, b, c) do {} while (0) +#define wlc_scb_key_delete(a, b) do {} while (0) +#define wlc_key_lookup(a, b, c, d, e) (NULL) +#define wlc_key_hw_init_all(a) do {} while (0) +#define wlc_key_hw_init(a, b, c) do {} while (0) +#define wlc_key_hw_wowl_init(a, b, c, d) do {} while (0) +#define wlc_key_sw_wowl_update(a, b, c, d, e) do {} while (0) +#define wlc_key_sw_wowl_create(a, b, c) (BCME_ERROR) +#define wlc_key_iv_update(a, b, c, d, e) do {(void)e; } while (0) +#define wlc_key_iv_init(a, b, c) do {} while (0) +#define wlc_key_set_error(a, b, c) (BCME_ERROR) +#define wlc_key_dump_hw(a, b) (BCME_ERROR) +#define wlc_key_dump_sw(a, b) (BCME_ERROR) +#define wlc_key_defkeyflag(a) (0) +#define wlc_rcmta_add_bssid(a, b) do {} while (0) +#define wlc_rcmta_del_bssid(a, b) do {} while (0) +#define wlc_key_scb_delete(a, b) do {} while (0) + +#endif /* _wlc_key_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c new file mode 100644 index 000000000000..5eb41d64bc23 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -0,0 +1,8479 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "d11ucode_ext.h" +#include +#include +#include + + +/* + * WPA(2) definitions + */ +#define RSN_CAP_4_REPLAY_CNTRS 2 +#define RSN_CAP_16_REPLAY_CNTRS 3 + +#define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS +#define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS + +/* + * buffer length needed for wlc_format_ssid + * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. + */ +#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) + +#define TIMER_INTERVAL_WATCHDOG 1000 /* watchdog timer, in unit of ms */ +#define TIMER_INTERVAL_RADIOCHK 800 /* radio monitor timer, in unit of ms */ + +#ifndef WLC_MPC_MAX_DELAYCNT +#define WLC_MPC_MAX_DELAYCNT 10 /* Max MPC timeout, in unit of watchdog */ +#endif +#define WLC_MPC_MIN_DELAYCNT 1 /* Min MPC timeout, in unit of watchdog */ +#define WLC_MPC_THRESHOLD 3 /* MPC count threshold level */ + +#define BEACON_INTERVAL_DEFAULT 100 /* beacon interval, in unit of 1024TU */ +#define DTIM_INTERVAL_DEFAULT 3 /* DTIM interval, in unit of beacon interval */ + +/* Scale down delays to accommodate QT slow speed */ +#define BEACON_INTERVAL_DEF_QT 20 /* beacon interval, in unit of 1024TU */ +#define DTIM_INTERVAL_DEF_QT 1 /* DTIM interval, in unit of beacon interval */ + +#define TBTT_ALIGN_LEEWAY_US 100 /* min leeway before first TBTT in us */ + +/* + * driver maintains internal 'tick'(wlc->pub->now) which increments in 1s OS timer(soft + * watchdog) it is not a wall clock and won't increment when driver is in "down" state + * this low resolution driver tick can be used for maintenance tasks such as phy + * calibration and scb update + */ + +/* watchdog trigger mode: OSL timer or TBTT */ +#define WLC_WATCHDOG_TBTT(wlc) \ + (wlc->stas_associated > 0 && wlc->PM != PM_OFF && wlc->pub->align_wd_tbtt) + +/* To inform the ucode of the last mcast frame posted so that it can clear moredata bit */ +#define BCMCFID(wlc, fid) wlc_bmac_write_shm((wlc)->hw, M_BCMC_FID, (fid)) + +#define WLC_WAR16165(wlc) (wlc->pub->sih->bustype == PCI_BUS && \ + (!AP_ENAB(wlc->pub)) && (wlc->war16165)) + +/* debug/trace */ +uint wl_msg_level = +#if defined(BCMDBG) + WL_ERROR_VAL; +#else + 0; +#endif /* BCMDBG */ + +/* Find basic rate for a given rate */ +#define WLC_BASIC_RATE(wlc, rspec) (IS_MCS(rspec) ? \ + (wlc)->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK].leg_ofdm] : \ + (wlc)->band->basic_rate[rspec & RSPEC_RATE_MASK]) + +#define FRAMETYPE(r, mimoframe) (IS_MCS(r) ? mimoframe : (IS_CCK(r) ? FT_CCK : FT_OFDM)) + +#define RFDISABLE_DEFAULT 10000000 /* rfdisable delay timer 500 ms, runs of ALP clock */ + +#define WLC_TEMPSENSE_PERIOD 10 /* 10 second timeout */ + +#define SCAN_IN_PROGRESS(x) 0 + +#define EPI_VERSION_NUM 0x054b0b00 + +#ifdef BCMDBG +/* pointer to most recently allocated wl/wlc */ +static struct wlc_info *wlc_info_dbg = (struct wlc_info *) (NULL); +#endif + +/* IOVar table */ + +/* Parameter IDs, for use only internally to wlc -- in the wlc_iovars + * table and by the wlc_doiovar() function. No ordering is imposed: + * the table is keyed by name, and the function uses a switch. + */ +enum { + IOV_MPC = 1, + IOV_QTXPOWER, + IOV_BCN_LI_BCN, /* Beacon listen interval in # of beacons */ + IOV_LAST /* In case of a need to check max ID number */ +}; + +const bcm_iovar_t wlc_iovars[] = { + {"mpc", IOV_MPC, (IOVF_OPEN_ALLOW), IOVT_BOOL, 0}, + {"qtxpower", IOV_QTXPOWER, (IOVF_WHL | IOVF_OPEN_ALLOW), IOVT_UINT32, + 0}, + {"bcn_li_bcn", IOV_BCN_LI_BCN, 0, IOVT_UINT8, 0}, + {NULL, 0, 0, 0, 0} +}; + +const u8 prio2fifo[NUMPRIO] = { + TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */ + TX_AC_BK_FIFO, /* 1 BK AC_BK Background */ + TX_AC_BK_FIFO, /* 2 -- AC_BK Background */ + TX_AC_BE_FIFO, /* 3 EE AC_BE Best Effort */ + TX_AC_VI_FIFO, /* 4 CL AC_VI Video */ + TX_AC_VI_FIFO, /* 5 VI AC_VI Video */ + TX_AC_VO_FIFO, /* 6 VO AC_VO Voice */ + TX_AC_VO_FIFO /* 7 NC AC_VO Voice */ +}; + +/* precedences numbers for wlc queues. These are twice as may levels as + * 802.1D priorities. + * Odd numbers are used for HI priority traffic at same precedence levels + * These constants are used ONLY by wlc_prio2prec_map. Do not use them elsewhere. + */ +#define _WLC_PREC_NONE 0 /* None = - */ +#define _WLC_PREC_BK 2 /* BK - Background */ +#define _WLC_PREC_BE 4 /* BE - Best-effort */ +#define _WLC_PREC_EE 6 /* EE - Excellent-effort */ +#define _WLC_PREC_CL 8 /* CL - Controlled Load */ +#define _WLC_PREC_VI 10 /* Vi - Video */ +#define _WLC_PREC_VO 12 /* Vo - Voice */ +#define _WLC_PREC_NC 14 /* NC - Network Control */ + +/* 802.1D Priority to precedence queue mapping */ +const u8 wlc_prio2prec_map[] = { + _WLC_PREC_BE, /* 0 BE - Best-effort */ + _WLC_PREC_BK, /* 1 BK - Background */ + _WLC_PREC_NONE, /* 2 None = - */ + _WLC_PREC_EE, /* 3 EE - Excellent-effort */ + _WLC_PREC_CL, /* 4 CL - Controlled Load */ + _WLC_PREC_VI, /* 5 Vi - Video */ + _WLC_PREC_VO, /* 6 Vo - Voice */ + _WLC_PREC_NC, /* 7 NC - Network Control */ +}; + +/* Sanity check for tx_prec_map and fifo synchup + * Either there are some packets pending for the fifo, else if fifo is empty then + * all the corresponding precmap bits should be set + */ +#define WLC_TX_FIFO_CHECK(wlc, fifo) (TXPKTPENDGET((wlc), (fifo)) || \ + (TXPKTPENDGET((wlc), (fifo)) == 0 && \ + ((wlc)->tx_prec_map & (wlc)->fifo2prec_map[(fifo)]) == \ + (wlc)->fifo2prec_map[(fifo)])) + +/* TX FIFO number to WME/802.1E Access Category */ +const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE }; + +/* WME/802.1E Access Category to TX FIFO number */ +static const u8 wme_ac2fifo[] = { 1, 0, 2, 3 }; + +static bool in_send_q = false; + +/* Shared memory location index for various AC params */ +#define wme_shmemacindex(ac) wme_ac2fifo[ac] + +#ifdef BCMDBG +static const char *fifo_names[] = { + "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; +const char *aci_names[] = { "AC_BE", "AC_BK", "AC_VI", "AC_VO" }; +#endif + +static const u8 acbitmap2maxprio[] = { + PRIO_8021D_BE, PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_BK, + PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, + PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, + PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO +}; + +/* currently the best mechanism for determining SIFS is the band in use */ +#define SIFS(band) ((band)->bandtype == WLC_BAND_5G ? APHY_SIFS_TIME : BPHY_SIFS_TIME); + +/* value for # replay counters currently supported */ +#define WLC_REPLAY_CNTRS_VALUE WPA_CAP_16_REPLAY_CNTRS + +/* local prototypes */ +static u16 BCMFASTPATH wlc_d11hdrs_mac80211(struct wlc_info *wlc, + struct ieee80211_hw *hw, + struct sk_buff *p, + struct scb *scb, uint frag, + uint nfrags, uint queue, + uint next_frag_len, + wsec_key_t *key, + ratespec_t rspec_override); + +static void wlc_bss_default_init(struct wlc_info *wlc); +static void wlc_ucode_mac_upd(struct wlc_info *wlc); +static ratespec_t mac80211_wlc_set_nrate(struct wlc_info *wlc, + struct wlcband *cur_band, u32 int_val); +static void wlc_tx_prec_map_init(struct wlc_info *wlc); +static void wlc_watchdog(void *arg); +static void wlc_watchdog_by_timer(void *arg); +static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg); +static int wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, + const bcm_iovar_t *vi); +static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc); + +/* send and receive */ +static wlc_txq_info_t *wlc_txq_alloc(struct wlc_info *wlc, + struct osl_info *osh); +static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh, + wlc_txq_info_t *qi); +static void wlc_txflowcontrol_signal(struct wlc_info *wlc, wlc_txq_info_t *qi, + bool on, int prio); +static void wlc_txflowcontrol_reset(struct wlc_info *wlc); +static u16 wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, + uint length); +static void wlc_compute_cck_plcp(ratespec_t rate, uint length, u8 *plcp); +static void wlc_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp); +static void wlc_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp); +static u16 wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, + u8 preamble_type, uint next_frag_len); +static void wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, + d11rxhdr_t *rxh, struct sk_buff *p); +static uint wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t rate, + u8 preamble_type, uint dur); +static uint wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rate, + u8 preamble_type); +static uint wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rate, + u8 preamble_type); +/* interrupt, up/down, band */ +static void wlc_setband(struct wlc_info *wlc, uint bandunit); +static chanspec_t wlc_init_chanspec(struct wlc_info *wlc); +static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec); +static void wlc_bsinit(struct wlc_info *wlc); +static int wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, + bool writeToShm); +static void wlc_radio_hwdisable_upd(struct wlc_info *wlc); +static bool wlc_radio_monitor_start(struct wlc_info *wlc); +static void wlc_radio_timer(void *arg); +static void wlc_radio_enable(struct wlc_info *wlc); +static void wlc_radio_upd(struct wlc_info *wlc); + +/* scan, association, BSS */ +static uint wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rate, + u8 preamble_type); +static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap); +static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val); +static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val); +static void wlc_war16165(struct wlc_info *wlc, bool tx); + +static void wlc_process_eventq(void *arg); +static void wlc_wme_retries_write(struct wlc_info *wlc); +static bool wlc_attach_stf_ant_init(struct wlc_info *wlc); +static uint wlc_attach_module(struct wlc_info *wlc); +static void wlc_detach_module(struct wlc_info *wlc); +static void wlc_timers_deinit(struct wlc_info *wlc); +static void wlc_down_led_upd(struct wlc_info *wlc); +static uint wlc_down_del_timer(struct wlc_info *wlc); +static void wlc_ofdm_rateset_war(struct wlc_info *wlc); +static int _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, + struct wlc_if *wlcif); + +#if defined(BCMDBG) +void wlc_get_rcmta(struct wlc_info *wlc, int idx, u8 *addr) +{ + d11regs_t *regs = wlc->regs; + u32 v32; + struct osl_info *osh; + + WL_TRACE("wl%d: %s\n", WLCWLUNIT(wlc), __func__); + + ASSERT(wlc->pub->corerev > 4); + + osh = wlc->osh; + + W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); + (void)R_REG(osh, ®s->objaddr); + v32 = R_REG(osh, ®s->objdata); + addr[0] = (u8) v32; + addr[1] = (u8) (v32 >> 8); + addr[2] = (u8) (v32 >> 16); + addr[3] = (u8) (v32 >> 24); + W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1))); + (void)R_REG(osh, ®s->objaddr); + v32 = R_REG(osh, (volatile u16 *)®s->objdata); + addr[4] = (u8) v32; + addr[5] = (u8) (v32 >> 8); +} +#endif /* defined(BCMDBG) */ + +/* keep the chip awake if needed */ +bool wlc_stay_awake(struct wlc_info *wlc) +{ + return true; +} + +/* conditions under which the PM bit should be set in outgoing frames and STAY_AWAKE is meaningful + */ +bool wlc_ps_allowed(struct wlc_info *wlc) +{ + int idx; + wlc_bsscfg_t *cfg; + + /* disallow PS when one of the following global conditions meets */ + if (!wlc->pub->associated || !wlc->PMenabled || wlc->PM_override) + return false; + + /* disallow PS when one of these meets when not scanning */ + if (!wlc->PMblocked) { + if (AP_ACTIVE(wlc) || wlc->monitor) + return false; + } + + FOREACH_AS_STA(wlc, idx, cfg) { + /* disallow PS when one of the following bsscfg specific conditions meets */ + if (!cfg->BSS || !WLC_PORTOPEN(cfg)) + return false; + + if (!cfg->dtim_programmed) + return false; + } + + return true; +} + +void wlc_reset(struct wlc_info *wlc) +{ + WL_TRACE("wl%d: wlc_reset\n", wlc->pub->unit); + + wlc->check_for_unaligned_tbtt = false; + + /* slurp up hw mac counters before core reset */ + if (WLC_UPDATE_STATS(wlc)) { + wlc_statsupd(wlc); + + /* reset our snapshot of macstat counters */ + memset((char *)wlc->core->macstat_snapshot, 0, + sizeof(macstat_t)); + } + + wlc_bmac_reset(wlc->hw); + wlc_ampdu_reset(wlc->ampdu); + wlc->txretried = 0; + +} + +void wlc_fatal_error(struct wlc_info *wlc) +{ + WL_ERROR("wl%d: fatal error, reinitializing\n", wlc->pub->unit); + wl_init(wlc->wl); +} + +/* Return the channel the driver should initialize during wlc_init. + * the channel may have to be changed from the currently configured channel + * if other configurations are in conflict (bandlocked, 11n mode disabled, + * invalid channel for current country, etc.) + */ +static chanspec_t wlc_init_chanspec(struct wlc_info *wlc) +{ + chanspec_t chanspec = + 1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE | + WL_CHANSPEC_BAND_2G; + + /* make sure the channel is on the supported band if we are band-restricted */ + if (wlc->bandlocked || NBANDS(wlc) == 1) { + ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit); + } + ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec)); + return chanspec; +} + +struct scb global_scb; + +static void wlc_init_scb(struct wlc_info *wlc, struct scb *scb) +{ + int i; + scb->flags = SCB_WMECAP | SCB_HTCAP; + for (i = 0; i < NUMPRIO; i++) + scb->seqnum[i] = 0; +} + +void wlc_init(struct wlc_info *wlc) +{ + d11regs_t *regs; + chanspec_t chanspec; + int i; + wlc_bsscfg_t *bsscfg; + bool mute = false; + + WL_TRACE("wl%d: wlc_init\n", wlc->pub->unit); + + regs = wlc->regs; + + /* This will happen if a big-hammer was executed. In that case, we want to go back + * to the channel that we were on and not new channel + */ + if (wlc->pub->associated) + chanspec = wlc->home_chanspec; + else + chanspec = wlc_init_chanspec(wlc); + + wlc_bmac_init(wlc->hw, chanspec, mute); + + wlc->seckeys = wlc_bmac_read_shm(wlc->hw, M_SECRXKEYS_PTR) * 2; + if (D11REV_GE(wlc->pub->corerev, 15) && (wlc->machwcap & MCAP_TKIPMIC)) + wlc->tkmickeys = + wlc_bmac_read_shm(wlc->hw, M_TKMICKEYS_PTR) * 2; + + /* update beacon listen interval */ + wlc_bcn_li_upd(wlc); + wlc->bcn_wait_prd = + (u8) (wlc_bmac_read_shm(wlc->hw, M_NOSLPZNATDTIM) >> 10); + ASSERT(wlc->bcn_wait_prd > 0); + + /* the world is new again, so is our reported rate */ + wlc_reprate_init(wlc); + + /* write ethernet address to core */ + FOREACH_BSS(wlc, i, bsscfg) { + wlc_set_mac(bsscfg); + wlc_set_bssid(bsscfg); + } + + /* Update tsf_cfprep if associated and up */ + if (wlc->pub->associated) { + FOREACH_BSS(wlc, i, bsscfg) { + if (bsscfg->up) { + u32 bi; + + /* get beacon period from bsscfg and convert to uS */ + bi = bsscfg->current_bss->beacon_period << 10; + /* update the tsf_cfprep register */ + /* since init path would reset to default value */ + W_REG(wlc->osh, ®s->tsf_cfprep, + (bi << CFPREP_CBI_SHIFT)); + + /* Update maccontrol PM related bits */ + wlc_set_ps_ctrl(wlc); + + break; + } + } + } + + wlc_key_hw_init_all(wlc); + + wlc_bandinit_ordered(wlc, chanspec); + + wlc_init_scb(wlc, &global_scb); + + /* init probe response timeout */ + wlc_write_shm(wlc, M_PRS_MAXTIME, wlc->prb_resp_timeout); + + /* init max burst txop (framebursting) */ + wlc_write_shm(wlc, M_MBURST_TXOP, + (wlc-> + _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP)); + + /* initialize maximum allowed duty cycle */ + wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true); + wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true); + + /* Update some shared memory locations related to max AMPDU size allowed to received */ + wlc_ampdu_shm_upd(wlc->ampdu); + + /* band-specific inits */ + wlc_bsinit(wlc); + + /* Enable EDCF mode (while the MAC is suspended) */ + if (EDCF_ENAB(wlc->pub)) { + OR_REG(wlc->osh, ®s->ifs_ctl, IFS_USEEDCF); + wlc_edcf_setparams(wlc->cfg, false); + } + + /* Init precedence maps for empty FIFOs */ + wlc_tx_prec_map_init(wlc); + + /* read the ucode version if we have not yet done so */ + if (wlc->ucode_rev == 0) { + wlc->ucode_rev = + wlc_read_shm(wlc, M_BOM_REV_MAJOR) << NBITS(u16); + wlc->ucode_rev |= wlc_read_shm(wlc, M_BOM_REV_MINOR); + } + + /* ..now really unleash hell (allow the MAC out of suspend) */ + wlc_enable_mac(wlc); + + /* clear tx flow control */ + wlc_txflowcontrol_reset(wlc); + + /* clear tx data fifo suspends */ + wlc->tx_suspended = false; + + /* enable the RF Disable Delay timer */ + if (D11REV_GE(wlc->pub->corerev, 10)) + W_REG(wlc->osh, &wlc->regs->rfdisabledly, RFDISABLE_DEFAULT); + + /* initialize mpc delay */ + wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; + + /* + * Initialize WME parameters; if they haven't been set by some other + * mechanism (IOVar, etc) then read them from the hardware. + */ + if (WLC_WME_RETRY_SHORT_GET(wlc, 0) == 0) { /* Unintialized; read from HW */ + int ac; + + ASSERT(wlc->clk); + for (ac = 0; ac < AC_COUNT; ac++) { + wlc->wme_retries[ac] = + wlc_read_shm(wlc, M_AC_TXLMT_ADDR(ac)); + } + } +} + +void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc) +{ + wlc->bcnmisc_monitor = promisc; + wlc_mac_bcn_promisc(wlc); +} + +void wlc_mac_bcn_promisc(struct wlc_info *wlc) +{ + if ((AP_ENAB(wlc->pub) && (N_ENAB(wlc->pub) || wlc->band->gmode)) || + wlc->bcnmisc_ibss || wlc->bcnmisc_scan || wlc->bcnmisc_monitor) + wlc_mctrl(wlc, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC); + else + wlc_mctrl(wlc, MCTL_BCNS_PROMISC, 0); +} + +/* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */ +void wlc_mac_promisc(struct wlc_info *wlc) +{ + u32 promisc_bits = 0; + + /* promiscuous mode just sets MCTL_PROMISC + * Note: APs get all BSS traffic without the need to set the MCTL_PROMISC bit + * since all BSS data traffic is directed at the AP + */ + if (PROMISC_ENAB(wlc->pub) && !AP_ENAB(wlc->pub) && !wlc->wet) + promisc_bits |= MCTL_PROMISC; + + /* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL + * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is + * handled in wlc_mac_bcn_promisc() + */ + if (MONITOR_ENAB(wlc)) + promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL; + + wlc_mctrl(wlc, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits); +} + +/* check if hps and wake states of sw and hw are in sync */ +bool wlc_ps_check(struct wlc_info *wlc) +{ + bool res = true; + bool hps, wake; + bool wake_ok; + + if (!AP_ACTIVE(wlc)) { + volatile u32 tmp; + tmp = R_REG(wlc->osh, &wlc->regs->maccontrol); + + /* If deviceremoved is detected, then don't take any action as this can be called + * in any context. Assume that caller will take care of the condition. This is just + * to avoid assert + */ + if (tmp == 0xffffffff) { + WL_ERROR("wl%d: %s: dead chip\n", + wlc->pub->unit, __func__); + return DEVICEREMOVED(wlc); + } + + hps = PS_ALLOWED(wlc); + + if (hps != ((tmp & MCTL_HPS) != 0)) { + int idx; + wlc_bsscfg_t *cfg; + WL_ERROR("wl%d: hps not sync, sw %d, maccontrol 0x%x\n", + wlc->pub->unit, hps, tmp); + FOREACH_BSS(wlc, idx, cfg) { + if (!BSSCFG_STA(cfg)) + continue; + } + + res = false; + } + /* For a monolithic build the wake check can be exact since it looks at wake + * override bits. The MCTL_WAKE bit should match the 'wake' value. + */ + wake = STAY_AWAKE(wlc) || wlc->hw->wake_override; + wake_ok = (wake == ((tmp & MCTL_WAKE) != 0)); + if (hps && !wake_ok) { + WL_ERROR("wl%d: wake not sync, sw %d maccontrol 0x%x\n", + wlc->pub->unit, wake, tmp); + res = false; + } + } + ASSERT(res); + return res; +} + +/* push sw hps and wake state through hardware */ +void wlc_set_ps_ctrl(struct wlc_info *wlc) +{ + u32 v1, v2; + bool hps, wake; + bool awake_before; + + hps = PS_ALLOWED(wlc); + wake = hps ? (STAY_AWAKE(wlc)) : true; + + WL_TRACE("wl%d: wlc_set_ps_ctrl: hps %d wake %d\n", + wlc->pub->unit, hps, wake); + + v1 = R_REG(wlc->osh, &wlc->regs->maccontrol); + v2 = 0; + if (hps) + v2 |= MCTL_HPS; + if (wake) + v2 |= MCTL_WAKE; + + wlc_mctrl(wlc, MCTL_WAKE | MCTL_HPS, v2); + + awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0)); + + if (wake && !awake_before) + wlc_bmac_wait_for_wake(wlc->hw); + +} + +/* + * Write this BSS config's MAC address to core. + * Updates RXE match engine. + */ +int wlc_set_mac(wlc_bsscfg_t *cfg) +{ + int err = 0; + struct wlc_info *wlc = cfg->wlc; + + if (cfg == wlc->cfg) { + /* enter the MAC addr into the RXE match registers */ + wlc_set_addrmatch(wlc, RCM_MAC_OFFSET, cfg->cur_etheraddr); + } + + wlc_ampdu_macaddr_upd(wlc); + + return err; +} + +/* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl). + * Updates RXE match engine. + */ +void wlc_set_bssid(wlc_bsscfg_t *cfg) +{ + struct wlc_info *wlc = cfg->wlc; + + /* if primary config, we need to update BSSID in RXE match registers */ + if (cfg == wlc->cfg) { + wlc_set_addrmatch(wlc, RCM_BSSID_OFFSET, cfg->BSSID); + } +#ifdef SUPPORT_HWKEYS + else if (BSSCFG_STA(cfg) && cfg->BSS) { + wlc_rcmta_add_bssid(wlc, cfg); + } +#endif +} + +/* + * Suspend the the MAC and update the slot timing + * for standard 11b/g (20us slots) or shortslot 11g (9us slots). + */ +void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot) +{ + int idx; + wlc_bsscfg_t *cfg; + + ASSERT(wlc->band->gmode); + + /* use the override if it is set */ + if (wlc->shortslot_override != WLC_SHORTSLOT_AUTO) + shortslot = (wlc->shortslot_override == WLC_SHORTSLOT_ON); + + if (wlc->shortslot == shortslot) + return; + + wlc->shortslot = shortslot; + + /* update the capability based on current shortslot mode */ + FOREACH_BSS(wlc, idx, cfg) { + if (!cfg->associated) + continue; + cfg->current_bss->capability &= + ~WLAN_CAPABILITY_SHORT_SLOT_TIME; + if (wlc->shortslot) + cfg->current_bss->capability |= + WLAN_CAPABILITY_SHORT_SLOT_TIME; + } + + wlc_bmac_set_shortslot(wlc->hw, shortslot); +} + +static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc) +{ + u8 local; + s16 local_max; + + local = WLC_TXPWR_MAX; + if (wlc->pub->associated && + (wf_chspec_ctlchan(wlc->chanspec) == + wf_chspec_ctlchan(wlc->home_chanspec))) { + + /* get the local power constraint if we are on the AP's + * channel [802.11h, 7.3.2.13] + */ + /* Clamp the value between 0 and WLC_TXPWR_MAX w/o overflowing the target */ + local_max = + (wlc->txpwr_local_max - + wlc->txpwr_local_constraint) * WLC_TXPWR_DB_FACTOR; + if (local_max > 0 && local_max < WLC_TXPWR_MAX) + return (u8) local_max; + if (local_max < 0) + return 0; + } + + return local; +} + +/* propagate home chanspec to all bsscfgs in case bsscfg->current_bss->chanspec is referenced */ +void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec) +{ + if (wlc->home_chanspec != chanspec) { + int idx; + wlc_bsscfg_t *cfg; + + wlc->home_chanspec = chanspec; + + FOREACH_BSS(wlc, idx, cfg) { + if (!cfg->associated) + continue; + cfg->target_bss->chanspec = chanspec; + cfg->current_bss->chanspec = chanspec; + } + + } +} + +static void wlc_set_phy_chanspec(struct wlc_info *wlc, chanspec_t chanspec) +{ + /* Save our copy of the chanspec */ + wlc->chanspec = chanspec; + + /* Set the chanspec and power limits for this locale after computing + * any 11h local tx power constraints. + */ + wlc_channel_set_chanspec(wlc->cmi, chanspec, + wlc_local_constraint_qdbm(wlc)); + + if (wlc->stf->ss_algosel_auto) + wlc_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel, + chanspec); + + wlc_stf_ss_update(wlc, wlc->band); + +} + +void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec) +{ + uint bandunit; + bool switchband = false; + chanspec_t old_chanspec = wlc->chanspec; + + if (!wlc_valid_chanspec_db(wlc->cmi, chanspec)) { + WL_ERROR("wl%d: %s: Bad channel %d\n", + wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); + ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec)); + return; + } + + /* Switch bands if necessary */ + if (NBANDS(wlc) > 1) { + bandunit = CHSPEC_WLCBANDUNIT(chanspec); + if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) { + switchband = true; + if (wlc->bandlocked) { + WL_ERROR("wl%d: %s: chspec %d band is locked!\n", + wlc->pub->unit, __func__, + CHSPEC_CHANNEL(chanspec)); + return; + } + /* BMAC_NOTE: should the setband call come after the wlc_bmac_chanspec() ? + * if the setband updates (wlc_bsinit) use low level calls to inspect and + * set state, the state inspected may be from the wrong band, or the + * following wlc_bmac_set_chanspec() may undo the work. + */ + wlc_setband(wlc, bandunit); + } + } + + ASSERT(N_ENAB(wlc->pub) || !CHSPEC_IS40(chanspec)); + + /* sync up phy/radio chanspec */ + wlc_set_phy_chanspec(wlc, chanspec); + + /* init antenna selection */ + if (CHSPEC_WLC_BW(old_chanspec) != CHSPEC_WLC_BW(chanspec)) { + if (WLANTSEL_ENAB(wlc)) + wlc_antsel_init(wlc->asi); + + /* Fix the hardware rateset based on bw. + * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz + */ + wlc_rateset_bw_mcs_filter(&wlc->band->hw_rateset, + wlc->band-> + mimo_cap_40 ? CHSPEC_WLC_BW(chanspec) + : 0); + } + + /* update some mac configuration since chanspec changed */ + wlc_ucode_mac_upd(wlc); +} + +#if defined(BCMDBG) +static int wlc_get_current_txpwr(struct wlc_info *wlc, void *pwr, uint len) +{ + txpwr_limits_t txpwr; + tx_power_t power; + tx_power_legacy_t *old_power = NULL; + int r, c; + uint qdbm; + bool override; + + if (len == sizeof(tx_power_legacy_t)) + old_power = (tx_power_legacy_t *) pwr; + else if (len < sizeof(tx_power_t)) + return BCME_BUFTOOSHORT; + + memset(&power, 0, sizeof(tx_power_t)); + + power.chanspec = WLC_BAND_PI_RADIO_CHANSPEC; + if (wlc->pub->associated) + power.local_chanspec = wlc->home_chanspec; + + /* Return the user target tx power limits for the various rates. Note wlc_phy.c's + * public interface only implements getting and setting a single value for all of + * rates, so we need to fill the array ourselves. + */ + wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override); + for (r = 0; r < WL_TX_POWER_RATES; r++) { + power.user_limit[r] = (u8) qdbm; + } + + power.local_max = wlc->txpwr_local_max * WLC_TXPWR_DB_FACTOR; + power.local_constraint = + wlc->txpwr_local_constraint * WLC_TXPWR_DB_FACTOR; + + power.antgain[0] = wlc->bandstate[BAND_2G_INDEX]->antgain; + power.antgain[1] = wlc->bandstate[BAND_5G_INDEX]->antgain; + + wlc_channel_reg_limits(wlc->cmi, power.chanspec, &txpwr); + +#if WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK +#error "WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK" +#endif + + /* CCK tx power limits */ + for (c = 0, r = WL_TX_POWER_CCK_FIRST; c < WL_TX_POWER_CCK_NUM; + c++, r++) + power.reg_limit[r] = txpwr.cck[c]; + +#if WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM +#error "WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM" +#endif + + /* 20 MHz OFDM SISO tx power limits */ + for (c = 0, r = WL_TX_POWER_OFDM_FIRST; c < WL_TX_POWER_OFDM_NUM; + c++, r++) + power.reg_limit[r] = txpwr.ofdm[c]; + + if (WLC_PHY_11N_CAP(wlc->band)) { + + /* 20 MHz OFDM CDD tx power limits */ + for (c = 0, r = WL_TX_POWER_OFDM20_CDD_FIRST; + c < WL_TX_POWER_OFDM_NUM; c++, r++) + power.reg_limit[r] = txpwr.ofdm_cdd[c]; + + /* 40 MHz OFDM SISO tx power limits */ + for (c = 0, r = WL_TX_POWER_OFDM40_SISO_FIRST; + c < WL_TX_POWER_OFDM_NUM; c++, r++) + power.reg_limit[r] = txpwr.ofdm_40_siso[c]; + + /* 40 MHz OFDM CDD tx power limits */ + for (c = 0, r = WL_TX_POWER_OFDM40_CDD_FIRST; + c < WL_TX_POWER_OFDM_NUM; c++, r++) + power.reg_limit[r] = txpwr.ofdm_40_cdd[c]; + +#if WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM +#error "WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM" +#endif + + /* 20MHz MCS0-7 SISO tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS20_SISO_FIRST; + c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_20_siso[c]; + + /* 20MHz MCS0-7 CDD tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS20_CDD_FIRST; + c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_20_cdd[c]; + + /* 20MHz MCS0-7 STBC tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS20_STBC_FIRST; + c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_20_stbc[c]; + + /* 40MHz MCS0-7 SISO tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS40_SISO_FIRST; + c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_40_siso[c]; + + /* 40MHz MCS0-7 CDD tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS40_CDD_FIRST; + c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_40_cdd[c]; + + /* 40MHz MCS0-7 STBC tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS40_STBC_FIRST; + c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_40_stbc[c]; + +#if WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM +#error "WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM" +#endif + + /* 20MHz MCS8-15 SDM tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS20_SDM_FIRST; + c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_20_mimo[c]; + + /* 40MHz MCS8-15 SDM tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS40_SDM_FIRST; + c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_40_mimo[c]; + + /* MCS 32 */ + power.reg_limit[WL_TX_POWER_MCS_32] = txpwr.mcs32; + } + + wlc_phy_txpower_get_current(wlc->band->pi, &power, + CHSPEC_CHANNEL(power.chanspec)); + + /* copy the tx_power_t struct to the return buffer, + * or convert to a tx_power_legacy_t struct + */ + if (!old_power) { + bcopy(&power, pwr, sizeof(tx_power_t)); + } else { + int band_idx = CHSPEC_IS2G(power.chanspec) ? 0 : 1; + + memset(old_power, 0, sizeof(tx_power_legacy_t)); + + old_power->txpwr_local_max = power.local_max; + old_power->txpwr_local_constraint = power.local_constraint; + if (CHSPEC_IS2G(power.chanspec)) { + old_power->txpwr_chan_reg_max = txpwr.cck[0]; + old_power->txpwr_est_Pout[band_idx] = + power.est_Pout_cck; + old_power->txpwr_est_Pout_gofdm = power.est_Pout[0]; + } else { + old_power->txpwr_chan_reg_max = txpwr.ofdm[0]; + old_power->txpwr_est_Pout[band_idx] = power.est_Pout[0]; + } + old_power->txpwr_antgain[0] = power.antgain[0]; + old_power->txpwr_antgain[1] = power.antgain[1]; + + for (r = 0; r < NUM_PWRCTRL_RATES; r++) { + old_power->txpwr_band_max[r] = power.user_limit[r]; + old_power->txpwr_limit[r] = power.reg_limit[r]; + old_power->txpwr_target[band_idx][r] = power.target[r]; + if (CHSPEC_IS2G(power.chanspec)) + old_power->txpwr_bphy_cck_max[r] = + power.board_limit[r]; + else + old_power->txpwr_aphy_max[r] = + power.board_limit[r]; + } + } + + return 0; +} +#endif /* defined(BCMDBG) */ + +static u32 wlc_watchdog_backup_bi(struct wlc_info *wlc) +{ + u32 bi; + bi = 2 * wlc->cfg->current_bss->dtim_period * + wlc->cfg->current_bss->beacon_period; + if (wlc->bcn_li_dtim) + bi *= wlc->bcn_li_dtim; + else if (wlc->bcn_li_bcn) + /* recalculate bi based on bcn_li_bcn */ + bi = 2 * wlc->bcn_li_bcn * wlc->cfg->current_bss->beacon_period; + + if (bi < 2 * TIMER_INTERVAL_WATCHDOG) + bi = 2 * TIMER_INTERVAL_WATCHDOG; + return bi; +} + +/* Change to run the watchdog either from a periodic timer or from tbtt handler. + * Call watchdog from tbtt handler if tbtt is true, watchdog timer otherwise. + */ +void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt) +{ + /* make sure changing watchdog driver is allowed */ + if (!wlc->pub->up || !wlc->pub->align_wd_tbtt) + return; + if (!tbtt && wlc->WDarmed) { + wl_del_timer(wlc->wl, wlc->wdtimer); + wlc->WDarmed = false; + } + + /* stop watchdog timer and use tbtt interrupt to drive watchdog */ + if (tbtt && wlc->WDarmed) { + wl_del_timer(wlc->wl, wlc->wdtimer); + wlc->WDarmed = false; + wlc->WDlast = OSL_SYSUPTIME(); + } + /* arm watchdog timer and drive the watchdog there */ + else if (!tbtt && !wlc->WDarmed) { + wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, + true); + wlc->WDarmed = true; + } + if (tbtt && !wlc->WDarmed) { + wl_add_timer(wlc->wl, wlc->wdtimer, wlc_watchdog_backup_bi(wlc), + true); + wlc->WDarmed = true; + } +} + +ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, wlc_rateset_t *rs) +{ + ratespec_t lowest_basic_rspec; + uint i; + + /* Use the lowest basic rate */ + lowest_basic_rspec = rs->rates[0] & RATE_MASK; + for (i = 0; i < rs->count; i++) { + if (rs->rates[i] & WLC_RATE_FLAG) { + lowest_basic_rspec = rs->rates[i] & RATE_MASK; + break; + } + } +#if NCONF + /* pick siso/cdd as default for OFDM (note no basic rate MCSs are supported yet) */ + if (IS_OFDM(lowest_basic_rspec)) { + lowest_basic_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT); + } +#endif + + return lowest_basic_rspec; +} + +/* This function changes the phytxctl for beacon based on current beacon ratespec AND txant + * setting as per this table: + * ratespec CCK ant = wlc->stf->txant + * OFDM ant = 3 + */ +void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, ratespec_t bcn_rspec) +{ + u16 phyctl; + u16 phytxant = wlc->stf->phytxant; + u16 mask = PHY_TXC_ANT_MASK; + + /* for non-siso rates or default setting, use the available chains */ + if (WLC_PHY_11N_CAP(wlc->band)) { + phytxant = wlc_stf_phytxchain_sel(wlc, bcn_rspec); + } + + phyctl = wlc_read_shm(wlc, M_BCN_PCTLWD); + phyctl = (phyctl & ~mask) | phytxant; + wlc_write_shm(wlc, M_BCN_PCTLWD, phyctl); +} + +/* centralized protection config change function to simplify debugging, no consistency checking + * this should be called only on changes to avoid overhead in periodic function +*/ +void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val) +{ + WL_TRACE("wlc_protection_upd: idx %d, val %d\n", idx, val); + + switch (idx) { + case WLC_PROT_G_SPEC: + wlc->protection->_g = (bool) val; + break; + case WLC_PROT_G_OVR: + wlc->protection->g_override = (s8) val; + break; + case WLC_PROT_G_USER: + wlc->protection->gmode_user = (u8) val; + break; + case WLC_PROT_OVERLAP: + wlc->protection->overlap = (s8) val; + break; + case WLC_PROT_N_USER: + wlc->protection->nmode_user = (s8) val; + break; + case WLC_PROT_N_CFG: + wlc->protection->n_cfg = (s8) val; + break; + case WLC_PROT_N_CFG_OVR: + wlc->protection->n_cfg_override = (s8) val; + break; + case WLC_PROT_N_NONGF: + wlc->protection->nongf = (bool) val; + break; + case WLC_PROT_N_NONGF_OVR: + wlc->protection->nongf_override = (s8) val; + break; + case WLC_PROT_N_PAM_OVR: + wlc->protection->n_pam_override = (s8) val; + break; + case WLC_PROT_N_OBSS: + wlc->protection->n_obss = (bool) val; + break; + + default: + ASSERT(0); + break; + } + +} + +static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val) +{ + wlc->ht_cap.cap_info &= ~(IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_SGI_40); + wlc->ht_cap.cap_info |= (val & WLC_N_SGI_20) ? + IEEE80211_HT_CAP_SGI_20 : 0; + wlc->ht_cap.cap_info |= (val & WLC_N_SGI_40) ? + IEEE80211_HT_CAP_SGI_40 : 0; + + if (wlc->pub->up) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, true); + } +} + +static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val) +{ + wlc->stf->ldpc = val; + + wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_LDPC_CODING; + if (wlc->stf->ldpc != OFF) + wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_LDPC_CODING; + + if (wlc->pub->up) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, true); + wlc_phy_ldpc_override_set(wlc->band->pi, (val ? true : false)); + } +} + +/* + * ucode, hwmac update + * Channel dependent updates for ucode and hw + */ +static void wlc_ucode_mac_upd(struct wlc_info *wlc) +{ + /* enable or disable any active IBSSs depending on whether or not + * we are on the home channel + */ + if (wlc->home_chanspec == WLC_BAND_PI_RADIO_CHANSPEC) { + if (wlc->pub->associated) { + /* BMAC_NOTE: This is something that should be fixed in ucode inits. + * I think that the ucode inits set up the bcn templates and shm values + * with a bogus beacon. This should not be done in the inits. If ucode needs + * to set up a beacon for testing, the test routines should write it down, + * not expect the inits to populate a bogus beacon. + */ + if (WLC_PHY_11N_CAP(wlc->band)) { + wlc_write_shm(wlc, M_BCN_TXTSF_OFFSET, + wlc->band->bcntsfoff); + } + } + } else { + /* disable an active IBSS if we are not on the home channel */ + } + + /* update the various promisc bits */ + wlc_mac_bcn_promisc(wlc); + wlc_mac_promisc(wlc); +} + +static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec) +{ + wlc_rateset_t default_rateset; + uint parkband; + uint i, band_order[2]; + + WL_TRACE("wl%d: wlc_bandinit_ordered\n", wlc->pub->unit); + /* + * We might have been bandlocked during down and the chip power-cycled (hibernate). + * figure out the right band to park on + */ + if (wlc->bandlocked || NBANDS(wlc) == 1) { + ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit); + + parkband = wlc->band->bandunit; /* updated in wlc_bandlock() */ + band_order[0] = band_order[1] = parkband; + } else { + /* park on the band of the specified chanspec */ + parkband = CHSPEC_WLCBANDUNIT(chanspec); + + /* order so that parkband initialize last */ + band_order[0] = parkband ^ 1; + band_order[1] = parkband; + } + + /* make each band operational, software state init */ + for (i = 0; i < NBANDS(wlc); i++) { + uint j = band_order[i]; + + wlc->band = wlc->bandstate[j]; + + wlc_default_rateset(wlc, &default_rateset); + + /* fill in hw_rate */ + wlc_rateset_filter(&default_rateset, &wlc->band->hw_rateset, + false, WLC_RATES_CCK_OFDM, RATE_MASK, + (bool) N_ENAB(wlc->pub)); + + /* init basic rate lookup */ + wlc_rate_lookup_init(wlc, &default_rateset); + } + + /* sync up phy/radio chanspec */ + wlc_set_phy_chanspec(wlc, chanspec); +} + +/* band-specific init */ +static void WLBANDINITFN(wlc_bsinit) (struct wlc_info *wlc) +{ + WL_TRACE("wl%d: wlc_bsinit: bandunit %d\n", + wlc->pub->unit, wlc->band->bandunit); + + /* write ucode ACK/CTS rate table */ + wlc_set_ratetable(wlc); + + /* update some band specific mac configuration */ + wlc_ucode_mac_upd(wlc); + + /* init antenna selection */ + if (WLANTSEL_ENAB(wlc)) + wlc_antsel_init(wlc->asi); + +} + +/* switch to and initialize new band */ +static void WLBANDINITFN(wlc_setband) (struct wlc_info *wlc, uint bandunit) +{ + int idx; + wlc_bsscfg_t *cfg; + + ASSERT(NBANDS(wlc) > 1); + ASSERT(!wlc->bandlocked); + ASSERT(bandunit != wlc->band->bandunit || wlc->bandinit_pending); + + wlc->band = wlc->bandstate[bandunit]; + + if (!wlc->pub->up) + return; + + /* wait for at least one beacon before entering sleeping state */ + wlc->PMawakebcn = true; + FOREACH_AS_STA(wlc, idx, cfg) + cfg->PMawakebcn = true; + wlc_set_ps_ctrl(wlc); + + /* band-specific initializations */ + wlc_bsinit(wlc); +} + +/* Initialize a WME Parameter Info Element with default STA parameters from WMM Spec, Table 12 */ +void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe) +{ + static const wme_param_ie_t stadef = { + WME_OUI, + WME_TYPE, + WME_SUBTYPE_PARAM_IE, + WME_VER, + 0, + 0, + { + {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA, + HTOL16(EDCF_AC_BE_TXOP_STA)}, + {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA, + HTOL16(EDCF_AC_BK_TXOP_STA)}, + {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA, + HTOL16(EDCF_AC_VI_TXOP_STA)}, + {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA, + HTOL16(EDCF_AC_VO_TXOP_STA)} + } + }; + + ASSERT(sizeof(*pe) == WME_PARAM_IE_LEN); + memcpy(pe, &stadef, sizeof(*pe)); +} + +void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend) +{ + int i; + shm_acparams_t acp_shm; + u16 *shm_entry; + struct ieee80211_tx_queue_params *params = arg; + + ASSERT(wlc); + + /* Only apply params if the core is out of reset and has clocks */ + if (!wlc->clk) { + WL_ERROR("wl%d: %s : no-clock\n", wlc->pub->unit, __func__); + return; + } + + /* + * AP uses AC params from wme_param_ie_ap. + * AP advertises AC params from wme_param_ie. + * STA uses AC params from wme_param_ie. + */ + + wlc->wme_admctl = 0; + + do { + memset((char *)&acp_shm, 0, sizeof(shm_acparams_t)); + /* find out which ac this set of params applies to */ + ASSERT(aci < AC_COUNT); + /* set the admission control policy for this AC */ + /* wlc->wme_admctl |= 1 << aci; *//* should be set ?? seems like off by default */ + + /* fill in shm ac params struct */ + acp_shm.txop = ltoh16(params->txop); + /* convert from units of 32us to us for ucode */ + wlc->edcf_txop[aci & 0x3] = acp_shm.txop = + EDCF_TXOP2USEC(acp_shm.txop); + acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK); + + if (aci == AC_VI && acp_shm.txop == 0 + && acp_shm.aifs < EDCF_AIFSN_MAX) + acp_shm.aifs++; + + if (acp_shm.aifs < EDCF_AIFSN_MIN + || acp_shm.aifs > EDCF_AIFSN_MAX) { + WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n", + wlc->pub->unit, acp_shm.aifs); + continue; + } + + acp_shm.cwmin = params->cw_min; + acp_shm.cwmax = params->cw_max; + acp_shm.cwcur = acp_shm.cwmin; + acp_shm.bslots = + R_REG(wlc->osh, &wlc->regs->tsf_random) & acp_shm.cwcur; + acp_shm.reggap = acp_shm.bslots + acp_shm.aifs; + /* Indicate the new params to the ucode */ + acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO + + wme_shmemacindex(aci) * + M_EDCF_QLEN + + M_EDCF_STATUS_OFF)); + acp_shm.status |= WME_STATUS_NEWAC; + + /* Fill in shm acparam table */ + shm_entry = (u16 *) &acp_shm; + for (i = 0; i < (int)sizeof(shm_acparams_t); i += 2) + wlc_write_shm(wlc, + M_EDCF_QINFO + + wme_shmemacindex(aci) * M_EDCF_QLEN + i, + *shm_entry++); + + } while (0); + + if (suspend) + wlc_suspend_mac_and_wait(wlc); + + if (suspend) + wlc_enable_mac(wlc); + +} + +void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend) +{ + struct wlc_info *wlc = cfg->wlc; + uint aci, i, j; + edcf_acparam_t *edcf_acp; + shm_acparams_t acp_shm; + u16 *shm_entry; + + ASSERT(cfg); + ASSERT(wlc); + + /* Only apply params if the core is out of reset and has clocks */ + if (!wlc->clk) + return; + + /* + * AP uses AC params from wme_param_ie_ap. + * AP advertises AC params from wme_param_ie. + * STA uses AC params from wme_param_ie. + */ + + edcf_acp = (edcf_acparam_t *) &wlc->wme_param_ie.acparam[0]; + + wlc->wme_admctl = 0; + + for (i = 0; i < AC_COUNT; i++, edcf_acp++) { + memset((char *)&acp_shm, 0, sizeof(shm_acparams_t)); + /* find out which ac this set of params applies to */ + aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT; + ASSERT(aci < AC_COUNT); + /* set the admission control policy for this AC */ + if (edcf_acp->ACI & EDCF_ACM_MASK) { + wlc->wme_admctl |= 1 << aci; + } + + /* fill in shm ac params struct */ + acp_shm.txop = ltoh16(edcf_acp->TXOP); + /* convert from units of 32us to us for ucode */ + wlc->edcf_txop[aci] = acp_shm.txop = + EDCF_TXOP2USEC(acp_shm.txop); + acp_shm.aifs = (edcf_acp->ACI & EDCF_AIFSN_MASK); + + if (aci == AC_VI && acp_shm.txop == 0 + && acp_shm.aifs < EDCF_AIFSN_MAX) + acp_shm.aifs++; + + if (acp_shm.aifs < EDCF_AIFSN_MIN + || acp_shm.aifs > EDCF_AIFSN_MAX) { + WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n", + wlc->pub->unit, acp_shm.aifs); + continue; + } + + /* CWmin = 2^(ECWmin) - 1 */ + acp_shm.cwmin = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK); + /* CWmax = 2^(ECWmax) - 1 */ + acp_shm.cwmax = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK) + >> EDCF_ECWMAX_SHIFT); + acp_shm.cwcur = acp_shm.cwmin; + acp_shm.bslots = + R_REG(wlc->osh, &wlc->regs->tsf_random) & acp_shm.cwcur; + acp_shm.reggap = acp_shm.bslots + acp_shm.aifs; + /* Indicate the new params to the ucode */ + acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO + + wme_shmemacindex(aci) * + M_EDCF_QLEN + + M_EDCF_STATUS_OFF)); + acp_shm.status |= WME_STATUS_NEWAC; + + /* Fill in shm acparam table */ + shm_entry = (u16 *) &acp_shm; + for (j = 0; j < (int)sizeof(shm_acparams_t); j += 2) + wlc_write_shm(wlc, + M_EDCF_QINFO + + wme_shmemacindex(aci) * M_EDCF_QLEN + j, + *shm_entry++); + } + + if (suspend) + wlc_suspend_mac_and_wait(wlc); + + if (AP_ENAB(wlc->pub) && WME_ENAB(wlc->pub)) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, false); + } + + if (suspend) + wlc_enable_mac(wlc); + +} + +bool wlc_timers_init(struct wlc_info *wlc, int unit) +{ + wlc->wdtimer = wl_init_timer(wlc->wl, wlc_watchdog_by_timer, + wlc, "watchdog"); + if (!wlc->wdtimer) { + WL_ERROR("wl%d: wl_init_timer for wdtimer failed\n", unit); + goto fail; + } + + wlc->radio_timer = wl_init_timer(wlc->wl, wlc_radio_timer, + wlc, "radio"); + if (!wlc->radio_timer) { + WL_ERROR("wl%d: wl_init_timer for radio_timer failed\n", unit); + goto fail; + } + + return true; + + fail: + return false; +} + +/* + * Initialize wlc_info default values ... + * may get overrides later in this function + */ +void wlc_info_init(struct wlc_info *wlc, int unit) +{ + int i; + /* Assume the device is there until proven otherwise */ + wlc->device_present = true; + + /* set default power output percentage to 100 percent */ + wlc->txpwr_percent = 100; + + /* Save our copy of the chanspec */ + wlc->chanspec = CH20MHZ_CHSPEC(1); + + /* initialize CCK preamble mode to unassociated state */ + wlc->shortpreamble = false; + + wlc->legacy_probe = true; + + /* various 802.11g modes */ + wlc->shortslot = false; + wlc->shortslot_override = WLC_SHORTSLOT_AUTO; + + wlc->barker_overlap_control = true; + wlc->barker_preamble = WLC_BARKER_SHORT_ALLOWED; + wlc->txburst_limit_override = AUTO; + + wlc_protection_upd(wlc, WLC_PROT_G_OVR, WLC_PROTECTION_AUTO); + wlc_protection_upd(wlc, WLC_PROT_G_SPEC, false); + + wlc_protection_upd(wlc, WLC_PROT_N_CFG_OVR, WLC_PROTECTION_AUTO); + wlc_protection_upd(wlc, WLC_PROT_N_CFG, WLC_N_PROTECTION_OFF); + wlc_protection_upd(wlc, WLC_PROT_N_NONGF_OVR, WLC_PROTECTION_AUTO); + wlc_protection_upd(wlc, WLC_PROT_N_NONGF, false); + wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR, AUTO); + + wlc_protection_upd(wlc, WLC_PROT_OVERLAP, WLC_PROTECTION_CTL_OVERLAP); + + /* 802.11g draft 4.0 NonERP elt advertisement */ + wlc->include_legacy_erp = true; + + wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF; + wlc->stf->txant = ANT_TX_DEF; + + wlc->prb_resp_timeout = WLC_PRB_RESP_TIMEOUT; + + wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN; + for (i = 0; i < NFIFO; i++) + wlc->fragthresh[i] = DOT11_DEFAULT_FRAG_LEN; + wlc->RTSThresh = DOT11_DEFAULT_RTS_LEN; + + /* default rate fallback retry limits */ + wlc->SFBL = RETRY_SHORT_FB; + wlc->LFBL = RETRY_LONG_FB; + + /* default mac retry limits */ + wlc->SRL = RETRY_SHORT_DEF; + wlc->LRL = RETRY_LONG_DEF; + + /* init PM state */ + wlc->PM = PM_OFF; /* User's setting of PM mode through IOCTL */ + wlc->PM_override = false; /* Prevents from going to PM if our AP is 'ill' */ + wlc->PMenabled = false; /* Current PM state */ + wlc->PMpending = false; /* Tracks whether STA indicated PM in the last attempt */ + wlc->PMblocked = false; /* To allow blocking going into PM during RM and scans */ + + /* In WMM Auto mode, PM is allowed if association is a UAPSD association */ + wlc->WME_PM_blocked = false; + + /* Init wme queuing method */ + wlc->wme_prec_queuing = false; + + /* Overrides for the core to stay awake under zillion conditions Look for STAY_AWAKE */ + wlc->wake = false; + /* Are we waiting for a response to PS-Poll that we sent */ + wlc->PSpoll = false; + + /* APSD defaults */ + wlc->wme_apsd = true; + wlc->apsd_sta_usp = false; + wlc->apsd_trigger_timeout = 0; /* disable the trigger timer */ + wlc->apsd_trigger_ac = AC_BITMAP_ALL; + + /* Set flag to indicate that hw keys should be used when available. */ + wlc->wsec_swkeys = false; + + /* init the 4 static WEP default keys */ + for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) { + wlc->wsec_keys[i] = wlc->wsec_def_keys[i]; + wlc->wsec_keys[i]->idx = (u8) i; + } + + wlc->_regulatory_domain = false; /* 802.11d */ + + /* WME QoS mode is Auto by default */ + wlc->pub->_wme = AUTO; + +#ifdef BCMSDIODEV_ENABLED + wlc->pub->_priofc = true; /* enable priority flow control for sdio dongle */ +#endif + + wlc->pub->_ampdu = AMPDU_AGG_HOST; + wlc->pub->bcmerror = 0; + wlc->ibss_allowed = true; + wlc->ibss_coalesce_allowed = true; + wlc->pub->_coex = ON; + + /* intialize mpc delay */ + wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; + + wlc->pr80838_war = true; +} + +static bool wlc_state_bmac_sync(struct wlc_info *wlc) +{ + wlc_bmac_state_t state_bmac; + + if (wlc_bmac_state_get(wlc->hw, &state_bmac) != 0) + return false; + + wlc->machwcap = state_bmac.machwcap; + wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR, + (s8) state_bmac.preamble_ovr); + + return true; +} + +static uint wlc_attach_module(struct wlc_info *wlc) +{ + uint err = 0; + uint unit; + unit = wlc->pub->unit; + + wlc->asi = wlc_antsel_attach(wlc, wlc->osh, wlc->pub, wlc->hw); + if (wlc->asi == NULL) { + WL_ERROR("wl%d: wlc_attach: wlc_antsel_attach failed\n", unit); + err = 44; + goto fail; + } + + wlc->ampdu = wlc_ampdu_attach(wlc); + if (wlc->ampdu == NULL) { + WL_ERROR("wl%d: wlc_attach: wlc_ampdu_attach failed\n", unit); + err = 50; + goto fail; + } + + /* Initialize event queue; needed before following calls */ + wlc->eventq = + wlc_eventq_attach(wlc->pub, wlc, wlc->wl, wlc_process_eventq); + if (wlc->eventq == NULL) { + WL_ERROR("wl%d: wlc_attach: wlc_eventq_attachfailed\n", unit); + err = 57; + goto fail; + } + + if ((wlc_stf_attach(wlc) != 0)) { + WL_ERROR("wl%d: wlc_attach: wlc_stf_attach failed\n", unit); + err = 68; + goto fail; + } + fail: + return err; +} + +struct wlc_pub *wlc_pub(void *wlc) +{ + return ((struct wlc_info *) wlc)->pub; +} + +#define CHIP_SUPPORTS_11N(wlc) 1 + +/* + * The common driver entry routine. Error codes should be unique + */ +void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, + struct osl_info *osh, void *regsva, uint bustype, + void *btparam, uint *perr) +{ + struct wlc_info *wlc; + uint err = 0; + uint j; + struct wlc_pub *pub; + wlc_txq_info_t *qi; + uint n_disabled; + + WL_NONE("wl%d: %s: vendor 0x%x device 0x%x\n", + unit, __func__, vendor, device); + + ASSERT(WSEC_MAX_RCMTA_KEYS <= WSEC_MAX_KEYS); + ASSERT(WSEC_MAX_DEFAULT_KEYS == WLC_DEFAULT_KEYS); + + /* some code depends on packed structures */ + ASSERT(sizeof(struct ethhdr) == ETH_HLEN); + ASSERT(sizeof(d11regs_t) == SI_CORE_SIZE); + ASSERT(sizeof(ofdm_phy_hdr_t) == D11_PHY_HDR_LEN); + ASSERT(sizeof(cck_phy_hdr_t) == D11_PHY_HDR_LEN); + ASSERT(sizeof(d11txh_t) == D11_TXH_LEN); + ASSERT(sizeof(d11rxhdr_t) == RXHDR_LEN); + ASSERT(sizeof(struct ieee80211_hdr) == DOT11_A4_HDR_LEN); + ASSERT(sizeof(struct ieee80211_rts) == DOT11_RTS_LEN); + ASSERT(sizeof(tx_status_t) == TXSTATUS_LEN); + ASSERT(sizeof(struct ieee80211_ht_cap) == HT_CAP_IE_LEN); +#ifdef BRCM_FULLMAC + ASSERT(offsetof(wl_scan_params_t, channel_list) == + WL_SCAN_PARAMS_FIXED_SIZE); +#endif + ASSERT(IS_ALIGNED(offsetof(wsec_key_t, data), sizeof(u32))); + ASSERT(ISPOWEROF2(MA_WINDOW_SZ)); + + ASSERT(sizeof(wlc_d11rxhdr_t) <= WL_HWRXOFF); + + /* + * Number of replay counters value used in WPA IE must match # rxivs + * supported in wsec_key_t struct. See 802.11i/D3.0 sect. 7.3.2.17 + * 'RSN Information Element' figure 8 for this mapping. + */ + ASSERT((WPA_CAP_16_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE + && 16 == WLC_NUMRXIVS) + || (WPA_CAP_4_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE + && 4 == WLC_NUMRXIVS)); + + /* allocate struct wlc_info state and its substructures */ + wlc = (struct wlc_info *) wlc_attach_malloc(osh, unit, &err, device); + if (wlc == NULL) + goto fail; + wlc->osh = osh; + pub = wlc->pub; + +#if defined(BCMDBG) + wlc_info_dbg = wlc; +#endif + + wlc->band = wlc->bandstate[0]; + wlc->core = wlc->corestate; + wlc->wl = wl; + pub->unit = unit; + pub->osh = osh; + wlc->btparam = btparam; + pub->_piomode = piomode; + wlc->bandinit_pending = false; + /* By default restrict TKIP associations from 11n STA's */ + wlc->ht_wsec_restriction = WLC_HT_TKIP_RESTRICT; + + /* populate struct wlc_info with default values */ + wlc_info_init(wlc, unit); + + /* update sta/ap related parameters */ + wlc_ap_upd(wlc); + + /* 11n_disable nvram */ + n_disabled = getintvar(pub->vars, "11n_disable"); + + /* register a module (to handle iovars) */ + wlc_module_register(wlc->pub, wlc_iovars, "wlc_iovars", wlc, + wlc_doiovar, NULL, NULL); + + /* low level attach steps(all hw accesses go inside, no more in rest of the attach) */ + err = wlc_bmac_attach(wlc, vendor, device, unit, piomode, osh, regsva, + bustype, btparam); + if (err) + goto fail; + + /* for some states, due to different info pointer(e,g, wlc, wlc_hw) or master/slave split, + * HIGH driver(both monolithic and HIGH_ONLY) needs to sync states FROM BMAC portion driver + */ + if (!wlc_state_bmac_sync(wlc)) { + err = 20; + goto fail; + } + + pub->phy_11ncapable = WLC_PHY_11N_CAP(wlc->band); + + /* propagate *vars* from BMAC driver to high driver */ + wlc_bmac_copyfrom_vars(wlc->hw, &pub->vars, &wlc->vars_size); + + + /* set maximum allowed duty cycle */ + wlc->tx_duty_cycle_ofdm = + (u16) getintvar(pub->vars, "tx_duty_cycle_ofdm"); + wlc->tx_duty_cycle_cck = + (u16) getintvar(pub->vars, "tx_duty_cycle_cck"); + + wlc_stf_phy_chain_calc(wlc); + + /* txchain 1: txant 0, txchain 2: txant 1 */ + if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1)) + wlc->stf->txant = wlc->stf->hw_txchain - 1; + + /* push to BMAC driver */ + wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain, + wlc->stf->hw_rxchain); + + /* pull up some info resulting from the low attach */ + { + int i; + for (i = 0; i < NFIFO; i++) + wlc->core->txavail[i] = wlc->hw->txavail[i]; + } + + wlc_bmac_hw_etheraddr(wlc->hw, wlc->perm_etheraddr); + + bcopy((char *)&wlc->perm_etheraddr, (char *)&pub->cur_etheraddr, + ETH_ALEN); + + for (j = 0; j < NBANDS(wlc); j++) { + /* Use band 1 for single band 11a */ + if (IS_SINGLEBAND_5G(wlc->deviceid)) + j = BAND_5G_INDEX; + + wlc->band = wlc->bandstate[j]; + + if (!wlc_attach_stf_ant_init(wlc)) { + err = 24; + goto fail; + } + + /* default contention windows size limits */ + wlc->band->CWmin = APHY_CWMIN; + wlc->band->CWmax = PHY_CWMAX; + + /* init gmode value */ + if (BAND_2G(wlc->band->bandtype)) { + wlc->band->gmode = GMODE_AUTO; + wlc_protection_upd(wlc, WLC_PROT_G_USER, + wlc->band->gmode); + } + + /* init _n_enab supported mode */ + if (WLC_PHY_11N_CAP(wlc->band) && CHIP_SUPPORTS_11N(wlc)) { + if (n_disabled & WLFEATURE_DISABLE_11N) { + pub->_n_enab = OFF; + wlc_protection_upd(wlc, WLC_PROT_N_USER, OFF); + } else { + pub->_n_enab = SUPPORT_11N; + wlc_protection_upd(wlc, WLC_PROT_N_USER, + ((pub->_n_enab == + SUPPORT_11N) ? WL_11N_2x2 : + WL_11N_3x3)); + } + } + + /* init per-band default rateset, depend on band->gmode */ + wlc_default_rateset(wlc, &wlc->band->defrateset); + + /* fill in hw_rateset (used early by WLC_SET_RATESET) */ + wlc_rateset_filter(&wlc->band->defrateset, + &wlc->band->hw_rateset, false, + WLC_RATES_CCK_OFDM, RATE_MASK, + (bool) N_ENAB(wlc->pub)); + } + + /* update antenna config due to wlc->stf->txant/txchain/ant_rx_ovr change */ + wlc_stf_phy_txant_upd(wlc); + + /* attach each modules */ + err = wlc_attach_module(wlc); + if (err != 0) + goto fail; + + if (!wlc_timers_init(wlc, unit)) { + WL_ERROR("wl%d: %s: wlc_init_timer failed\n", unit, __func__); + err = 32; + goto fail; + } + + /* depend on rateset, gmode */ + wlc->cmi = wlc_channel_mgr_attach(wlc); + if (!wlc->cmi) { + WL_ERROR("wl%d: %s: wlc_channel_mgr_attach failed\n", + unit, __func__); + err = 33; + goto fail; + } + + /* init default when all parameters are ready, i.e. ->rateset */ + wlc_bss_default_init(wlc); + + /* + * Complete the wlc default state initializations.. + */ + + /* allocate our initial queue */ + qi = wlc_txq_alloc(wlc, osh); + if (qi == NULL) { + WL_ERROR("wl%d: %s: failed to malloc tx queue\n", + unit, __func__); + err = 100; + goto fail; + } + wlc->active_queue = qi; + + wlc->bsscfg[0] = wlc->cfg; + wlc->cfg->_idx = 0; + wlc->cfg->wlc = wlc; + pub->txmaxpkts = MAXTXPKTS; + + WLCNTSET(pub->_cnt->version, WL_CNT_T_VERSION); + WLCNTSET(pub->_cnt->length, sizeof(wl_cnt_t)); + + WLCNTSET(pub->_wme_cnt->version, WL_WME_CNT_VERSION); + WLCNTSET(pub->_wme_cnt->length, sizeof(wl_wme_cnt_t)); + + wlc_wme_initparams_sta(wlc, &wlc->wme_param_ie); + + wlc->mimoft = FT_HT; + wlc->ht_cap.cap_info = HT_CAP; + if (HT_ENAB(wlc->pub)) + wlc->stf->ldpc = AUTO; + + wlc->mimo_40txbw = AUTO; + wlc->ofdm_40txbw = AUTO; + wlc->cck_40txbw = AUTO; + wlc_update_mimo_band_bwcap(wlc, WLC_N_BW_20IN2G_40IN5G); + + /* Enable setting the RIFS Mode bit by default in HT Info IE */ + wlc->rifs_advert = AUTO; + + /* Set default values of SGI */ + if (WLC_SGI_CAP_PHY(wlc)) { + wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40)); + wlc->sgi_tx = AUTO; + } else if (WLCISSSLPNPHY(wlc->band)) { + wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40)); + wlc->sgi_tx = AUTO; + } else { + wlc_ht_update_sgi_rx(wlc, 0); + wlc->sgi_tx = OFF; + } + + /* *******nvram 11n config overrides Start ********* */ + + /* apply the sgi override from nvram conf */ + if (n_disabled & WLFEATURE_DISABLE_11N_SGI_TX) + wlc->sgi_tx = OFF; + + if (n_disabled & WLFEATURE_DISABLE_11N_SGI_RX) + wlc_ht_update_sgi_rx(wlc, 0); + + /* apply the stbc override from nvram conf */ + if (n_disabled & WLFEATURE_DISABLE_11N_STBC_TX) { + wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF; + wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF; + wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC; + } + if (n_disabled & WLFEATURE_DISABLE_11N_STBC_RX) + wlc_stf_stbc_rx_set(wlc, HT_CAP_RX_STBC_NO); + + /* apply the GF override from nvram conf */ + if (n_disabled & WLFEATURE_DISABLE_11N_GF) + wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_GRN_FLD; + + /* initialize radio_mpc_disable according to wlc->mpc */ + wlc_radio_mpc_upd(wlc); + + if (WLANTSEL_ENAB(wlc)) { + if ((wlc->pub->sih->chip) == BCM43235_CHIP_ID) { + if ((getintvar(wlc->pub->vars, "aa2g") == 7) || + (getintvar(wlc->pub->vars, "aa5g") == 7)) { + wlc_bmac_antsel_set(wlc->hw, 1); + } + } else { + wlc_bmac_antsel_set(wlc->hw, wlc->asi->antsel_avail); + } + } + + if (perr) + *perr = 0; + + return (void *)wlc; + + fail: + WL_ERROR("wl%d: %s: failed with err %d\n", unit, __func__, err); + if (wlc) + wlc_detach(wlc); + + if (perr) + *perr = err; + return NULL; +} + +static void wlc_attach_antgain_init(struct wlc_info *wlc) +{ + uint unit; + unit = wlc->pub->unit; + + if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) { + /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */ + wlc->band->antgain = 8; + } else if (wlc->band->antgain == -1) { + WL_ERROR("wl%d: %s: Invalid antennas available in srom, using 2dB\n", + unit, __func__); + wlc->band->antgain = 8; + } else { + s8 gain, fract; + /* Older sroms specified gain in whole dbm only. In order + * be able to specify qdbm granularity and remain backward compatible + * the whole dbms are now encoded in only low 6 bits and remaining qdbms + * are encoded in the hi 2 bits. 6 bit signed number ranges from + * -32 - 31. Examples: 0x1 = 1 db, + * 0xc1 = 1.75 db (1 + 3 quarters), + * 0x3f = -1 (-1 + 0 quarters), + * 0x7f = -.75 (-1 in low 6 bits + 1 quarters in hi 2 bits) = -3 qdbm. + * 0xbf = -.50 (-1 in low 6 bits + 2 quarters in hi 2 bits) = -2 qdbm. + */ + gain = wlc->band->antgain & 0x3f; + gain <<= 2; /* Sign extend */ + gain >>= 2; + fract = (wlc->band->antgain & 0xc0) >> 6; + wlc->band->antgain = 4 * gain + fract; + } +} + +static bool wlc_attach_stf_ant_init(struct wlc_info *wlc) +{ + int aa; + uint unit; + char *vars; + int bandtype; + + unit = wlc->pub->unit; + vars = wlc->pub->vars; + bandtype = wlc->band->bandtype; + + /* get antennas available */ + aa = (s8) getintvar(vars, (BAND_5G(bandtype) ? "aa5g" : "aa2g")); + if (aa == 0) + aa = (s8) getintvar(vars, + (BAND_5G(bandtype) ? "aa1" : "aa0")); + if ((aa < 1) || (aa > 15)) { + WL_ERROR("wl%d: %s: Invalid antennas available in srom (0x%x), using 3\n", + unit, __func__, aa); + aa = 3; + } + + /* reset the defaults if we have a single antenna */ + if (aa == 1) { + wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_0; + wlc->stf->txant = ANT_TX_FORCE_0; + } else if (aa == 2) { + wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_1; + wlc->stf->txant = ANT_TX_FORCE_1; + } else { + } + + /* Compute Antenna Gain */ + wlc->band->antgain = + (s8) getintvar(vars, (BAND_5G(bandtype) ? "ag1" : "ag0")); + wlc_attach_antgain_init(wlc); + + return true; +} + + +static void wlc_timers_deinit(struct wlc_info *wlc) +{ + /* free timer state */ + if (wlc->wdtimer) { + wl_free_timer(wlc->wl, wlc->wdtimer); + wlc->wdtimer = NULL; + } + if (wlc->radio_timer) { + wl_free_timer(wlc->wl, wlc->radio_timer); + wlc->radio_timer = NULL; + } +} + +static void wlc_detach_module(struct wlc_info *wlc) +{ + if (wlc->asi) { + wlc_antsel_detach(wlc->asi); + wlc->asi = NULL; + } + + if (wlc->ampdu) { + wlc_ampdu_detach(wlc->ampdu); + wlc->ampdu = NULL; + } + + wlc_stf_detach(wlc); +} + +/* + * Return a count of the number of driver callbacks still pending. + * + * General policy is that wlc_detach can only dealloc/free software states. It can NOT + * touch hardware registers since the d11core may be in reset and clock may not be available. + * One exception is sb register access, which is possible if crystal is turned on + * After "down" state, driver should avoid software timer with the exception of radio_monitor. + */ +uint wlc_detach(struct wlc_info *wlc) +{ + uint i; + uint callbacks = 0; + + if (wlc == NULL) + return 0; + + WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__); + + ASSERT(!wlc->pub->up); + + callbacks += wlc_bmac_detach(wlc); + + /* delete software timers */ + if (!wlc_radio_monitor_stop(wlc)) + callbacks++; + + if (wlc->eventq) { + wlc_eventq_detach(wlc->eventq); + wlc->eventq = NULL; + } + + wlc_channel_mgr_detach(wlc->cmi); + + wlc_timers_deinit(wlc); + + wlc_detach_module(wlc); + + /* free other state */ + + +#ifdef BCMDBG + if (wlc->country_ie_override) { + kfree(wlc->country_ie_override); + wlc->country_ie_override = NULL; + } +#endif /* BCMDBG */ + + { + /* free dumpcb list */ + dumpcb_t *prev, *ptr; + prev = ptr = wlc->dumpcb_head; + while (ptr) { + ptr = prev->next; + kfree(prev); + prev = ptr; + } + wlc->dumpcb_head = NULL; + } + + /* Detach from iovar manager */ + wlc_module_unregister(wlc->pub, "wlc_iovars", wlc); + + while (wlc->tx_queues != NULL) { + wlc_txq_free(wlc, wlc->osh, wlc->tx_queues); + } + + /* + * consistency check: wlc_module_register/wlc_module_unregister calls + * should match therefore nothing should be left here. + */ + for (i = 0; i < WLC_MAXMODULES; i++) + ASSERT(wlc->modulecb[i].name[0] == '\0'); + + wlc_detach_mfree(wlc, wlc->osh); + return callbacks; +} + +/* update state that depends on the current value of "ap" */ +void wlc_ap_upd(struct wlc_info *wlc) +{ + if (AP_ENAB(wlc->pub)) + wlc->PLCPHdr_override = WLC_PLCP_AUTO; /* AP: short not allowed, but not enforced */ + else + wlc->PLCPHdr_override = WLC_PLCP_SHORT; /* STA-BSS; short capable */ + + /* disable vlan_mode on AP since some legacy STAs cannot rx tagged pkts */ + wlc->vlan_mode = AP_ENAB(wlc->pub) ? OFF : AUTO; + + /* fixup mpc */ + wlc->mpc = true; +} + +/* read hwdisable state and propagate to wlc flag */ +static void wlc_radio_hwdisable_upd(struct wlc_info *wlc) +{ + if (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO || wlc->pub->hw_off) + return; + + if (wlc_bmac_radio_read_hwdisabled(wlc->hw)) { + mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); + } else { + mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); + } +} + +/* return true if Minimum Power Consumption should be entered, false otherwise */ +bool wlc_is_non_delay_mpc(struct wlc_info *wlc) +{ + return false; +} + +bool wlc_ismpc(struct wlc_info *wlc) +{ + return (wlc->mpc_delay_off == 0) && (wlc_is_non_delay_mpc(wlc)); +} + +void wlc_radio_mpc_upd(struct wlc_info *wlc) +{ + bool mpc_radio, radio_state; + + /* + * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled + * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio + * monitor also when WL_RADIO_MPC_DISABLE is the only reason that + * the radio is going down. + */ + if (!wlc->mpc) { + if (!wlc->pub->radio_disabled) + return; + mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); + wlc_radio_upd(wlc); + if (!wlc->pub->radio_disabled) + wlc_radio_monitor_stop(wlc); + return; + } + + /* + * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in wlc->pub->radio_disabled + * to go ON, always call radio_upd synchronously + * to go OFF, postpone radio_upd to later when context is safe(e.g. watchdog) + */ + radio_state = + (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF : + ON); + mpc_radio = (wlc_ismpc(wlc) == true) ? OFF : ON; + + if (radio_state == ON && mpc_radio == OFF) + wlc->mpc_delay_off = wlc->mpc_dlycnt; + else if (radio_state == OFF && mpc_radio == ON) { + mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); + wlc_radio_upd(wlc); + if (wlc->mpc_offcnt < WLC_MPC_THRESHOLD) { + wlc->mpc_dlycnt = WLC_MPC_MAX_DELAYCNT; + } else + wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; + wlc->mpc_dur += OSL_SYSUPTIME() - wlc->mpc_laston_ts; + } + /* Below logic is meant to capture the transition from mpc off to mpc on for reasons + * other than wlc->mpc_delay_off keeping the mpc off. In that case reset + * wlc->mpc_delay_off to wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off + */ + if ((wlc->prev_non_delay_mpc == false) && + (wlc_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off) { + wlc->mpc_delay_off = wlc->mpc_dlycnt; + } + wlc->prev_non_delay_mpc = wlc_is_non_delay_mpc(wlc); +} + +/* + * centralized radio disable/enable function, + * invoke radio enable/disable after updating hwradio status + */ +static void wlc_radio_upd(struct wlc_info *wlc) +{ + if (wlc->pub->radio_disabled) + wlc_radio_disable(wlc); + else + wlc_radio_enable(wlc); +} + +/* maintain LED behavior in down state */ +static void wlc_down_led_upd(struct wlc_info *wlc) +{ + ASSERT(!wlc->pub->up); + + /* maintain LEDs while in down state, turn on sbclk if not available yet */ + /* turn on sbclk if necessary */ + if (!AP_ENAB(wlc->pub)) { + wlc_pllreq(wlc, true, WLC_PLLREQ_FLIP); + + wlc_pllreq(wlc, false, WLC_PLLREQ_FLIP); + } +} + +void wlc_radio_disable(struct wlc_info *wlc) +{ + if (!wlc->pub->up) { + wlc_down_led_upd(wlc); + return; + } + + wlc_radio_monitor_start(wlc); + wl_down(wlc->wl); +} + +static void wlc_radio_enable(struct wlc_info *wlc) +{ + if (wlc->pub->up) + return; + + if (DEVICEREMOVED(wlc)) + return; + + if (!wlc->down_override) { /* imposed by wl down/out ioctl */ + wl_up(wlc->wl); + } +} + +/* periodical query hw radio button while driver is "down" */ +static void wlc_radio_timer(void *arg) +{ + struct wlc_info *wlc = (struct wlc_info *) arg; + + if (DEVICEREMOVED(wlc)) { + WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); + wl_down(wlc->wl); + return; + } + + /* cap mpc off count */ + if (wlc->mpc_offcnt < WLC_MPC_MAX_DELAYCNT) + wlc->mpc_offcnt++; + + /* validate all the reasons driver could be down and running this radio_timer */ + ASSERT(wlc->pub->radio_disabled || wlc->down_override); + wlc_radio_hwdisable_upd(wlc); + wlc_radio_upd(wlc); +} + +static bool wlc_radio_monitor_start(struct wlc_info *wlc) +{ + /* Don't start the timer if HWRADIO feature is disabled */ + if (wlc->radio_monitor || (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO)) + return true; + + wlc->radio_monitor = true; + wlc_pllreq(wlc, true, WLC_PLLREQ_RADIO_MON); + wl_add_timer(wlc->wl, wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true); + return true; +} + +bool wlc_radio_monitor_stop(struct wlc_info *wlc) +{ + if (!wlc->radio_monitor) + return true; + + ASSERT((wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO) != + WL_SWFL_NOHWRADIO); + + wlc->radio_monitor = false; + wlc_pllreq(wlc, false, WLC_PLLREQ_RADIO_MON); + return wl_del_timer(wlc->wl, wlc->radio_timer); +} + +/* bring the driver down, but don't reset hardware */ +void wlc_out(struct wlc_info *wlc) +{ + wlc_bmac_set_noreset(wlc->hw, true); + wlc_radio_upd(wlc); + wl_down(wlc->wl); + wlc_bmac_set_noreset(wlc->hw, false); + + /* core clk is true in BMAC driver due to noreset, need to mirror it in HIGH */ + wlc->clk = true; + + /* This will make sure that when 'up' is done + * after 'out' it'll restore hardware (especially gpios) + */ + wlc->pub->hw_up = false; +} + +#if defined(BCMDBG) +/* Verify the sanity of wlc->tx_prec_map. This can be done only by making sure that + * if there is no packet pending for the FIFO, then the corresponding prec bits should be set + * in prec_map. Of course, ignore this rule when block_datafifo is set + */ +static bool wlc_tx_prec_map_verify(struct wlc_info *wlc) +{ + /* For non-WME, both fifos have overlapping prec_map. So it's an error only if both + * fail the check. + */ + if (!EDCF_ENAB(wlc->pub)) { + if (!(WLC_TX_FIFO_CHECK(wlc, TX_DATA_FIFO) || + WLC_TX_FIFO_CHECK(wlc, TX_CTL_FIFO))) + return false; + else + return true; + } + + return WLC_TX_FIFO_CHECK(wlc, TX_AC_BK_FIFO) + && WLC_TX_FIFO_CHECK(wlc, TX_AC_BE_FIFO) + && WLC_TX_FIFO_CHECK(wlc, TX_AC_VI_FIFO) + && WLC_TX_FIFO_CHECK(wlc, TX_AC_VO_FIFO); +} +#endif /* BCMDBG */ + +static void wlc_watchdog_by_timer(void *arg) +{ + struct wlc_info *wlc = (struct wlc_info *) arg; + wlc_watchdog(arg); + if (WLC_WATCHDOG_TBTT(wlc)) { + /* set to normal osl watchdog period */ + wl_del_timer(wlc->wl, wlc->wdtimer); + wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, + true); + } +} + +/* common watchdog code */ +static void wlc_watchdog(void *arg) +{ + struct wlc_info *wlc = (struct wlc_info *) arg; + int i; + wlc_bsscfg_t *cfg; + + WL_TRACE("wl%d: wlc_watchdog\n", wlc->pub->unit); + + if (!wlc->pub->up) + return; + + if (DEVICEREMOVED(wlc)) { + WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); + wl_down(wlc->wl); + return; + } + + /* increment second count */ + wlc->pub->now++; + + /* delay radio disable */ + if (wlc->mpc_delay_off) { + if (--wlc->mpc_delay_off == 0) { + mboolset(wlc->pub->radio_disabled, + WL_RADIO_MPC_DISABLE); + if (wlc->mpc && wlc_ismpc(wlc)) + wlc->mpc_offcnt = 0; + wlc->mpc_laston_ts = OSL_SYSUPTIME(); + } + } + + /* mpc sync */ + wlc_radio_mpc_upd(wlc); + /* radio sync: sw/hw/mpc --> radio_disable/radio_enable */ + wlc_radio_hwdisable_upd(wlc); + wlc_radio_upd(wlc); + /* if ismpc, driver should be in down state if up/down is allowed */ + if (wlc->mpc && wlc_ismpc(wlc)) + ASSERT(!wlc->pub->up); + /* if radio is disable, driver may be down, quit here */ + if (wlc->pub->radio_disabled) + return; + + wlc_bmac_watchdog(wlc); + + /* occasionally sample mac stat counters to detect 16-bit counter wrap */ + if ((WLC_UPDATE_STATS(wlc)) + && (!(wlc->pub->now % SW_TIMER_MAC_STAT_UPD))) + wlc_statsupd(wlc); + + /* Manage TKIP countermeasures timers */ + FOREACH_BSS(wlc, i, cfg) { + if (cfg->tk_cm_dt) { + cfg->tk_cm_dt--; + } + if (cfg->tk_cm_bt) { + cfg->tk_cm_bt--; + } + } + + /* Call any registered watchdog handlers */ + for (i = 0; i < WLC_MAXMODULES; i++) { + if (wlc->modulecb[i].watchdog_fn) + wlc->modulecb[i].watchdog_fn(wlc->modulecb[i].hdl); + } + + if (WLCISNPHY(wlc->band) && !wlc->pub->tempsense_disable && + ((wlc->pub->now - wlc->tempsense_lasttime) >= + WLC_TEMPSENSE_PERIOD)) { + wlc->tempsense_lasttime = wlc->pub->now; + wlc_tempsense_upd(wlc); + } + /* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */ + ASSERT(wlc_bmac_taclear(wlc->hw, true)); + + /* Verify that tx_prec_map and fifos are in sync to avoid lock ups */ + ASSERT(wlc_tx_prec_map_verify(wlc)); + + ASSERT(wlc_ps_check(wlc)); +} + +/* make interface operational */ +int wlc_up(struct wlc_info *wlc) +{ + WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__); + + /* HW is turned off so don't try to access it */ + if (wlc->pub->hw_off || DEVICEREMOVED(wlc)) + return BCME_RADIOOFF; + + if (!wlc->pub->hw_up) { + wlc_bmac_hw_up(wlc->hw); + wlc->pub->hw_up = true; + } + + if ((wlc->pub->boardflags & BFL_FEM) + && (wlc->pub->sih->chip == BCM4313_CHIP_ID)) { + if (wlc->pub->boardrev >= 0x1250 + && (wlc->pub->boardflags & BFL_FEM_BT)) { + wlc_mhf(wlc, MHF5, MHF5_4313_GPIOCTRL, + MHF5_4313_GPIOCTRL, WLC_BAND_ALL); + } else { + wlc_mhf(wlc, MHF4, MHF4_EXTPA_ENABLE, MHF4_EXTPA_ENABLE, + WLC_BAND_ALL); + } + } + + /* + * Need to read the hwradio status here to cover the case where the system + * is loaded with the hw radio disabled. We do not want to bring the driver up in this case. + * if radio is disabled, abort up, lower power, start radio timer and return 0(for NDIS) + * don't call radio_update to avoid looping wlc_up. + * + * wlc_bmac_up_prep() returns either 0 or BCME_RADIOOFF only + */ + if (!wlc->pub->radio_disabled) { + int status = wlc_bmac_up_prep(wlc->hw); + if (status == BCME_RADIOOFF) { + if (!mboolisset + (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) { + int idx; + wlc_bsscfg_t *bsscfg; + mboolset(wlc->pub->radio_disabled, + WL_RADIO_HW_DISABLE); + + FOREACH_BSS(wlc, idx, bsscfg) { + if (!BSSCFG_STA(bsscfg) + || !bsscfg->enable || !bsscfg->BSS) + continue; + WL_ERROR("wl%d.%d: wlc_up: rfdisable -> " "wlc_bsscfg_disable()\n", + wlc->pub->unit, idx); + } + } + } else + ASSERT(!status); + } + + if (wlc->pub->radio_disabled) { + wlc_radio_monitor_start(wlc); + return 0; + } + + /* wlc_bmac_up_prep has done wlc_corereset(). so clk is on, set it */ + wlc->clk = true; + + wlc_radio_monitor_stop(wlc); + + /* Set EDCF hostflags */ + if (EDCF_ENAB(wlc->pub)) { + wlc_mhf(wlc, MHF1, MHF1_EDCF, MHF1_EDCF, WLC_BAND_ALL); + } else { + wlc_mhf(wlc, MHF1, MHF1_EDCF, 0, WLC_BAND_ALL); + } + + if (WLC_WAR16165(wlc)) + wlc_mhf(wlc, MHF2, MHF2_PCISLOWCLKWAR, MHF2_PCISLOWCLKWAR, + WLC_BAND_ALL); + + wl_init(wlc->wl); + wlc->pub->up = true; + + if (wlc->bandinit_pending) { + wlc_suspend_mac_and_wait(wlc); + wlc_set_chanspec(wlc, wlc->default_bss->chanspec); + wlc->bandinit_pending = false; + wlc_enable_mac(wlc); + } + + wlc_bmac_up_finish(wlc->hw); + + /* other software states up after ISR is running */ + /* start APs that were to be brought up but are not up yet */ + /* if (AP_ENAB(wlc->pub)) wlc_restart_ap(wlc->ap); */ + + /* Program the TX wme params with the current settings */ + wlc_wme_retries_write(wlc); + + /* start one second watchdog timer */ + ASSERT(!wlc->WDarmed); + wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true); + wlc->WDarmed = true; + + /* ensure antenna config is up to date */ + wlc_stf_phy_txant_upd(wlc); + /* ensure LDPC config is in sync */ + wlc_ht_update_ldpc(wlc, wlc->stf->ldpc); + + return 0; +} + +/* Initialize the base precedence map for dequeueing from txq based on WME settings */ +static void wlc_tx_prec_map_init(struct wlc_info *wlc) +{ + wlc->tx_prec_map = WLC_PREC_BMP_ALL; + memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16)); + + /* For non-WME, both fifos have overlapping MAXPRIO. So just disable all precedences + * if either is full. + */ + if (!EDCF_ENAB(wlc->pub)) { + wlc->fifo2prec_map[TX_DATA_FIFO] = WLC_PREC_BMP_ALL; + wlc->fifo2prec_map[TX_CTL_FIFO] = WLC_PREC_BMP_ALL; + } else { + wlc->fifo2prec_map[TX_AC_BK_FIFO] = WLC_PREC_BMP_AC_BK; + wlc->fifo2prec_map[TX_AC_BE_FIFO] = WLC_PREC_BMP_AC_BE; + wlc->fifo2prec_map[TX_AC_VI_FIFO] = WLC_PREC_BMP_AC_VI; + wlc->fifo2prec_map[TX_AC_VO_FIFO] = WLC_PREC_BMP_AC_VO; + } +} + +static uint wlc_down_del_timer(struct wlc_info *wlc) +{ + uint callbacks = 0; + + return callbacks; +} + +/* + * Mark the interface nonoperational, stop the software mechanisms, + * disable the hardware, free any transient buffer state. + * Return a count of the number of driver callbacks still pending. + */ +uint wlc_down(struct wlc_info *wlc) +{ + + uint callbacks = 0; + int i; + bool dev_gone = false; + wlc_txq_info_t *qi; + + WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__); + + /* check if we are already in the going down path */ + if (wlc->going_down) { + WL_ERROR("wl%d: %s: Driver going down so return\n", + wlc->pub->unit, __func__); + return 0; + } + if (!wlc->pub->up) + return callbacks; + + /* in between, mpc could try to bring down again.. */ + wlc->going_down = true; + + callbacks += wlc_bmac_down_prep(wlc->hw); + + dev_gone = DEVICEREMOVED(wlc); + + /* Call any registered down handlers */ + for (i = 0; i < WLC_MAXMODULES; i++) { + if (wlc->modulecb[i].down_fn) + callbacks += + wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl); + } + + /* cancel the watchdog timer */ + if (wlc->WDarmed) { + if (!wl_del_timer(wlc->wl, wlc->wdtimer)) + callbacks++; + wlc->WDarmed = false; + } + /* cancel all other timers */ + callbacks += wlc_down_del_timer(wlc); + + /* interrupt must have been blocked */ + ASSERT((wlc->macintmask == 0) || !wlc->pub->up); + + wlc->pub->up = false; + + wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL); + + /* clear txq flow control */ + wlc_txflowcontrol_reset(wlc); + + /* flush tx queues */ + for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { + pktq_flush(wlc->osh, &qi->q, true, NULL, 0); + ASSERT(pktq_empty(&qi->q)); + } + + /* flush event queue. + * Should be the last thing done after all the events are generated + * Just delivers the events synchronously instead of waiting for a timer + */ + callbacks += wlc_eventq_down(wlc->eventq); + + callbacks += wlc_bmac_down_finish(wlc->hw); + + /* wlc_bmac_down_finish has done wlc_coredisable(). so clk is off */ + wlc->clk = false; + + + /* Verify all packets are flushed from the driver */ + if (wlc->osh->pktalloced != 0) { + WL_ERROR("%d packets not freed at wlc_down!!!!!!\n", + wlc->osh->pktalloced); + } +#ifdef BCMDBG + /* Since all the packets should have been freed, + * all callbacks should have been called + */ + for (i = 1; i <= wlc->pub->tunables->maxpktcb; i++) + ASSERT(wlc->pkt_callback[i].fn == NULL); +#endif + wlc->going_down = false; + return callbacks; +} + +/* Set the current gmode configuration */ +int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) +{ + int ret = 0; + uint i; + wlc_rateset_t rs; + /* Default to 54g Auto */ + s8 shortslot = WLC_SHORTSLOT_AUTO; /* Advertise and use shortslot (-1/0/1 Auto/Off/On) */ + bool shortslot_restrict = false; /* Restrict association to stations that support shortslot + */ + bool ignore_bcns = true; /* Ignore legacy beacons on the same channel */ + bool ofdm_basic = false; /* Make 6, 12, and 24 basic rates */ + int preamble = WLC_PLCP_LONG; /* Advertise and use short preambles (-1/0/1 Auto/Off/On) */ + bool preamble_restrict = false; /* Restrict association to stations that support short + * preambles + */ + struct wlcband *band; + + /* if N-support is enabled, allow Gmode set as long as requested + * Gmode is not GMODE_LEGACY_B + */ + if (N_ENAB(wlc->pub) && gmode == GMODE_LEGACY_B) + return BCME_UNSUPPORTED; + + /* verify that we are dealing with 2G band and grab the band pointer */ + if (wlc->band->bandtype == WLC_BAND_2G) + band = wlc->band; + else if ((NBANDS(wlc) > 1) && + (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == WLC_BAND_2G)) + band = wlc->bandstate[OTHERBANDUNIT(wlc)]; + else + return BCME_BADBAND; + + /* Legacy or bust when no OFDM is supported by regulatory */ + if ((wlc_channel_locale_flags_in_band(wlc->cmi, band->bandunit) & + WLC_NO_OFDM) && (gmode != GMODE_LEGACY_B)) + return BCME_RANGE; + + /* update configuration value */ + if (config == true) + wlc_protection_upd(wlc, WLC_PROT_G_USER, gmode); + + /* Clear supported rates filter */ + memset(&wlc->sup_rates_override, 0, sizeof(wlc_rateset_t)); + + /* Clear rateset override */ + memset(&rs, 0, sizeof(wlc_rateset_t)); + + switch (gmode) { + case GMODE_LEGACY_B: + shortslot = WLC_SHORTSLOT_OFF; + wlc_rateset_copy(&gphy_legacy_rates, &rs); + + break; + + case GMODE_LRS: + if (AP_ENAB(wlc->pub)) + wlc_rateset_copy(&cck_rates, &wlc->sup_rates_override); + break; + + case GMODE_AUTO: + /* Accept defaults */ + break; + + case GMODE_ONLY: + ofdm_basic = true; + preamble = WLC_PLCP_SHORT; + preamble_restrict = true; + break; + + case GMODE_PERFORMANCE: + if (AP_ENAB(wlc->pub)) /* Put all rates into the Supported Rates element */ + wlc_rateset_copy(&cck_ofdm_rates, + &wlc->sup_rates_override); + + shortslot = WLC_SHORTSLOT_ON; + shortslot_restrict = true; + ofdm_basic = true; + preamble = WLC_PLCP_SHORT; + preamble_restrict = true; + break; + + default: + /* Error */ + WL_ERROR("wl%d: %s: invalid gmode %d\n", + wlc->pub->unit, __func__, gmode); + return BCME_UNSUPPORTED; + } + + /* + * If we are switching to gmode == GMODE_LEGACY_B, + * clean up rate info that may refer to OFDM rates. + */ + if ((gmode == GMODE_LEGACY_B) && (band->gmode != GMODE_LEGACY_B)) { + band->gmode = gmode; + if (band->rspec_override && !IS_CCK(band->rspec_override)) { + band->rspec_override = 0; + wlc_reprate_init(wlc); + } + if (band->mrspec_override && !IS_CCK(band->mrspec_override)) { + band->mrspec_override = 0; + } + } + + band->gmode = gmode; + + wlc->ignore_bcns = ignore_bcns; + + wlc->shortslot_override = shortslot; + + if (AP_ENAB(wlc->pub)) { + /* wlc->ap->shortslot_restrict = shortslot_restrict; */ + wlc->PLCPHdr_override = + (preamble != + WLC_PLCP_LONG) ? WLC_PLCP_SHORT : WLC_PLCP_AUTO; + } + + if ((AP_ENAB(wlc->pub) && preamble != WLC_PLCP_LONG) + || preamble == WLC_PLCP_SHORT) + wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE; + else + wlc->default_bss->capability &= ~WLAN_CAPABILITY_SHORT_PREAMBLE; + + /* Update shortslot capability bit for AP and IBSS */ + if ((AP_ENAB(wlc->pub) && shortslot == WLC_SHORTSLOT_AUTO) || + shortslot == WLC_SHORTSLOT_ON) + wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_SLOT_TIME; + else + wlc->default_bss->capability &= + ~WLAN_CAPABILITY_SHORT_SLOT_TIME; + + /* Use the default 11g rateset */ + if (!rs.count) + wlc_rateset_copy(&cck_ofdm_rates, &rs); + + if (ofdm_basic) { + for (i = 0; i < rs.count; i++) { + if (rs.rates[i] == WLC_RATE_6M + || rs.rates[i] == WLC_RATE_12M + || rs.rates[i] == WLC_RATE_24M) + rs.rates[i] |= WLC_RATE_FLAG; + } + } + + /* Set default bss rateset */ + wlc->default_bss->rateset.count = rs.count; + bcopy((char *)rs.rates, (char *)wlc->default_bss->rateset.rates, + sizeof(wlc->default_bss->rateset.rates)); + + return ret; +} + +static int wlc_nmode_validate(struct wlc_info *wlc, s32 nmode) +{ + int err = 0; + + switch (nmode) { + + case OFF: + break; + + case AUTO: + case WL_11N_2x2: + case WL_11N_3x3: + if (!(WLC_PHY_11N_CAP(wlc->band))) + err = BCME_BADBAND; + break; + + default: + err = BCME_RANGE; + break; + } + + return err; +} + +int wlc_set_nmode(struct wlc_info *wlc, s32 nmode) +{ + uint i; + int err; + + err = wlc_nmode_validate(wlc, nmode); + ASSERT(err == 0); + if (err) + return err; + + switch (nmode) { + case OFF: + wlc->pub->_n_enab = OFF; + wlc->default_bss->flags &= ~WLC_BSS_HT; + /* delete the mcs rates from the default and hw ratesets */ + wlc_rateset_mcs_clear(&wlc->default_bss->rateset); + for (i = 0; i < NBANDS(wlc); i++) { + memset(wlc->bandstate[i]->hw_rateset.mcs, 0, + MCSSET_LEN); + if (IS_MCS(wlc->band->rspec_override)) { + wlc->bandstate[i]->rspec_override = 0; + wlc_reprate_init(wlc); + } + if (IS_MCS(wlc->band->mrspec_override)) + wlc->bandstate[i]->mrspec_override = 0; + } + break; + + case AUTO: + if (wlc->stf->txstreams == WL_11N_3x3) + nmode = WL_11N_3x3; + else + nmode = WL_11N_2x2; + case WL_11N_2x2: + case WL_11N_3x3: + ASSERT(WLC_PHY_11N_CAP(wlc->band)); + /* force GMODE_AUTO if NMODE is ON */ + wlc_set_gmode(wlc, GMODE_AUTO, true); + if (nmode == WL_11N_3x3) + wlc->pub->_n_enab = SUPPORT_HT; + else + wlc->pub->_n_enab = SUPPORT_11N; + wlc->default_bss->flags |= WLC_BSS_HT; + /* add the mcs rates to the default and hw ratesets */ + wlc_rateset_mcs_build(&wlc->default_bss->rateset, + wlc->stf->txstreams); + for (i = 0; i < NBANDS(wlc); i++) + memcpy(wlc->bandstate[i]->hw_rateset.mcs, + wlc->default_bss->rateset.mcs, MCSSET_LEN); + break; + + default: + ASSERT(0); + break; + } + + return err; +} + +static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg) +{ + wlc_rateset_t rs, new; + uint bandunit; + + bcopy((char *)rs_arg, (char *)&rs, sizeof(wlc_rateset_t)); + + /* check for bad count value */ + if ((rs.count == 0) || (rs.count > WLC_NUMRATES)) + return BCME_BADRATESET; + + /* try the current band */ + bandunit = wlc->band->bandunit; + bcopy((char *)&rs, (char *)&new, sizeof(wlc_rateset_t)); + if (wlc_rate_hwrs_filter_sort_validate + (&new, &wlc->bandstate[bandunit]->hw_rateset, true, + wlc->stf->txstreams)) + goto good; + + /* try the other band */ + if (IS_MBAND_UNLOCKED(wlc)) { + bandunit = OTHERBANDUNIT(wlc); + bcopy((char *)&rs, (char *)&new, sizeof(wlc_rateset_t)); + if (wlc_rate_hwrs_filter_sort_validate(&new, + &wlc-> + bandstate[bandunit]-> + hw_rateset, true, + wlc->stf->txstreams)) + goto good; + } + + return BCME_ERROR; + + good: + /* apply new rateset */ + bcopy((char *)&new, (char *)&wlc->default_bss->rateset, + sizeof(wlc_rateset_t)); + bcopy((char *)&new, (char *)&wlc->bandstate[bandunit]->defrateset, + sizeof(wlc_rateset_t)); + return 0; +} + +/* simplified integer set interface for common ioctl handler */ +int wlc_set(struct wlc_info *wlc, int cmd, int arg) +{ + return wlc_ioctl(wlc, cmd, (void *)&arg, sizeof(arg), NULL); +} + +/* simplified integer get interface for common ioctl handler */ +int wlc_get(struct wlc_info *wlc, int cmd, int *arg) +{ + return wlc_ioctl(wlc, cmd, arg, sizeof(int), NULL); +} + +static void wlc_ofdm_rateset_war(struct wlc_info *wlc) +{ + u8 r; + bool war = false; + + if (wlc->cfg->associated) + r = wlc->cfg->current_bss->rateset.rates[0]; + else + r = wlc->default_bss->rateset.rates[0]; + + wlc_phy_ofdm_rateset_war(wlc->band->pi, war); + + return; +} + +int +wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, + struct wlc_if *wlcif) +{ + return _wlc_ioctl(wlc, cmd, arg, len, wlcif); +} + +/* common ioctl handler. return: 0=ok, -1=error, positive=particular error */ +static int +_wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, + struct wlc_if *wlcif) +{ + int val, *pval; + bool bool_val; + int bcmerror; + d11regs_t *regs; + uint i; + struct scb *nextscb; + bool ta_ok; + uint band; + rw_reg_t *r; + wlc_bsscfg_t *bsscfg; + struct osl_info *osh; + wlc_bss_info_t *current_bss; + + /* update bsscfg pointer */ + bsscfg = NULL; /* XXX: Hack bsscfg to be size one and use this globally */ + current_bss = NULL; + + /* initialize the following to get rid of compiler warning */ + nextscb = NULL; + ta_ok = false; + band = 0; + r = NULL; + + /* If the device is turned off, then it's not "removed" */ + if (!wlc->pub->hw_off && DEVICEREMOVED(wlc)) { + WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); + wl_down(wlc->wl); + return BCME_ERROR; + } + + ASSERT(!(wlc->pub->hw_off && wlc->pub->up)); + + /* default argument is generic integer */ + pval = arg ? (int *)arg:NULL; + + /* This will prevent the misaligned access */ + if (pval && (u32) len >= sizeof(val)) + bcopy(pval, &val, sizeof(val)); + else + val = 0; + + /* bool conversion to avoid duplication below */ + bool_val = val != 0; + + if (cmd != WLC_SET_CHANNEL) + WL_NONE("WLC_IOCTL: cmd %d val 0x%x (%d) len %d\n", + cmd, (uint)val, val, len); + + bcmerror = 0; + regs = wlc->regs; + osh = wlc->osh; + + /* A few commands don't need any arguments; all the others do. */ + switch (cmd) { + case WLC_UP: + case WLC_OUT: + case WLC_DOWN: + case WLC_DISASSOC: + case WLC_RESTART: + case WLC_REBOOT: + case WLC_START_CHANNEL_QA: + case WLC_INIT: + break; + + default: + if ((arg == NULL) || (len <= 0)) { + WL_ERROR("wl%d: %s: Command %d needs arguments\n", + wlc->pub->unit, __func__, cmd); + bcmerror = BCME_BADARG; + goto done; + } + } + + switch (cmd) { + +#if defined(BCMDBG) + case WLC_GET_MSGLEVEL: + *pval = wl_msg_level; + break; + + case WLC_SET_MSGLEVEL: + wl_msg_level = val; + break; +#endif + + case WLC_GET_INSTANCE: + *pval = wlc->pub->unit; + break; + + case WLC_GET_CHANNEL:{ + channel_info_t *ci = (channel_info_t *) arg; + + ASSERT(len > (int)sizeof(ci)); + + ci->hw_channel = + CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC); + ci->target_channel = + CHSPEC_CHANNEL(wlc->default_bss->chanspec); + ci->scan_channel = 0; + + break; + } + + case WLC_SET_CHANNEL:{ + chanspec_t chspec = CH20MHZ_CHSPEC(val); + + if (val < 0 || val > MAXCHANNEL) { + bcmerror = BCME_OUTOFRANGECHAN; + break; + } + + if (!wlc_valid_chanspec_db(wlc->cmi, chspec)) { + bcmerror = BCME_BADCHAN; + break; + } + + if (!wlc->pub->up && IS_MBAND_UNLOCKED(wlc)) { + if (wlc->band->bandunit != + CHSPEC_WLCBANDUNIT(chspec)) + wlc->bandinit_pending = true; + else + wlc->bandinit_pending = false; + } + + wlc->default_bss->chanspec = chspec; + /* wlc_BSSinit() will sanitize the rateset before using it.. */ + if (wlc->pub->up && !wlc->pub->associated && + (WLC_BAND_PI_RADIO_CHANSPEC != chspec)) { + wlc_set_home_chanspec(wlc, chspec); + wlc_suspend_mac_and_wait(wlc); + wlc_set_chanspec(wlc, chspec); + wlc_enable_mac(wlc); + } + break; + } + +#if defined(BCMDBG) + case WLC_GET_UCFLAGS: + if (!wlc->pub->up) { + bcmerror = BCME_NOTUP; + break; + } + + /* optional band is stored in the second integer of incoming buffer */ + band = + (len < + (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; + + /* bcmerror checking */ + bcmerror = wlc_iocregchk(wlc, band); + if (bcmerror) + break; + + if (val >= MHFMAX) { + bcmerror = BCME_RANGE; + break; + } + + *pval = wlc_bmac_mhf_get(wlc->hw, (u8) val, WLC_BAND_AUTO); + break; + + case WLC_SET_UCFLAGS: + if (!wlc->pub->up) { + bcmerror = BCME_NOTUP; + break; + } + + /* optional band is stored in the second integer of incoming buffer */ + band = + (len < + (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; + + /* bcmerror checking */ + bcmerror = wlc_iocregchk(wlc, band); + if (bcmerror) + break; + + i = (u16) val; + if (i >= MHFMAX) { + bcmerror = BCME_RANGE; + break; + } + + wlc_mhf(wlc, (u8) i, 0xffff, (u16) (val >> NBITS(u16)), + WLC_BAND_AUTO); + break; + + case WLC_GET_SHMEM: + ta_ok = true; + + /* optional band is stored in the second integer of incoming buffer */ + band = + (len < + (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; + + /* bcmerror checking */ + bcmerror = wlc_iocregchk(wlc, band); + if (bcmerror) + break; + + if (val & 1) { + bcmerror = BCME_BADADDR; + break; + } + + *pval = wlc_read_shm(wlc, (u16) val); + break; + + case WLC_SET_SHMEM: + ta_ok = true; + + /* optional band is stored in the second integer of incoming buffer */ + band = + (len < + (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; + + /* bcmerror checking */ + bcmerror = wlc_iocregchk(wlc, band); + if (bcmerror) + break; + + if (val & 1) { + bcmerror = BCME_BADADDR; + break; + } + + wlc_write_shm(wlc, (u16) val, + (u16) (val >> NBITS(u16))); + break; + + case WLC_R_REG: /* MAC registers */ + ta_ok = true; + r = (rw_reg_t *) arg; + band = WLC_BAND_AUTO; + + if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + if (len >= (int)sizeof(rw_reg_t)) + band = r->band; + + /* bcmerror checking */ + bcmerror = wlc_iocregchk(wlc, band); + if (bcmerror) + break; + + if ((r->byteoff + r->size) > sizeof(d11regs_t)) { + bcmerror = BCME_BADADDR; + break; + } + if (r->size == sizeof(u32)) + r->val = + R_REG(osh, + (u32 *)((unsigned char *)(unsigned long)regs + + r->byteoff)); + else if (r->size == sizeof(u16)) + r->val = + R_REG(osh, + (u16 *)((unsigned char *)(unsigned long)regs + + r->byteoff)); + else + bcmerror = BCME_BADADDR; + break; + + case WLC_W_REG: + ta_ok = true; + r = (rw_reg_t *) arg; + band = WLC_BAND_AUTO; + + if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + if (len >= (int)sizeof(rw_reg_t)) + band = r->band; + + /* bcmerror checking */ + bcmerror = wlc_iocregchk(wlc, band); + if (bcmerror) + break; + + if (r->byteoff + r->size > sizeof(d11regs_t)) { + bcmerror = BCME_BADADDR; + break; + } + if (r->size == sizeof(u32)) + W_REG(osh, + (u32 *)((unsigned char *)(unsigned long) regs + + r->byteoff), r->val); + else if (r->size == sizeof(u16)) + W_REG(osh, + (u16 *)((unsigned char *)(unsigned long) regs + + r->byteoff), r->val); + else + bcmerror = BCME_BADADDR; + break; +#endif /* BCMDBG */ + + case WLC_GET_TXANT: + *pval = wlc->stf->txant; + break; + + case WLC_SET_TXANT: + bcmerror = wlc_stf_ant_txant_validate(wlc, (s8) val); + if (bcmerror < 0) + break; + + wlc->stf->txant = (s8) val; + + /* if down, we are done */ + if (!wlc->pub->up) + break; + + wlc_suspend_mac_and_wait(wlc); + + wlc_stf_phy_txant_upd(wlc); + wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec); + + wlc_enable_mac(wlc); + + break; + + case WLC_GET_ANTDIV:{ + u8 phy_antdiv; + + /* return configured value if core is down */ + if (!wlc->pub->up) { + *pval = wlc->stf->ant_rx_ovr; + + } else { + if (wlc_phy_ant_rxdiv_get + (wlc->band->pi, &phy_antdiv)) + *pval = (int)phy_antdiv; + else + *pval = (int)wlc->stf->ant_rx_ovr; + } + + break; + } + case WLC_SET_ANTDIV: + /* values are -1=driver default, 0=force0, 1=force1, 2=start1, 3=start0 */ + if ((val < -1) || (val > 3)) { + bcmerror = BCME_RANGE; + break; + } + + if (val == -1) + val = ANT_RX_DIV_DEF; + + wlc->stf->ant_rx_ovr = (u8) val; + wlc_phy_ant_rxdiv_set(wlc->band->pi, (u8) val); + break; + + case WLC_GET_RX_ANT:{ /* get latest used rx antenna */ + u16 rxstatus; + + if (!wlc->pub->up) { + bcmerror = BCME_NOTUP; + break; + } + + rxstatus = R_REG(wlc->osh, &wlc->regs->phyrxstatus0); + if (rxstatus == 0xdead || rxstatus == (u16) -1) { + bcmerror = BCME_ERROR; + break; + } + *pval = (rxstatus & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; + break; + } + +#if defined(BCMDBG) + case WLC_GET_UCANTDIV: + if (!wlc->clk) { + bcmerror = BCME_NOCLK; + break; + } + + *pval = + (wlc_bmac_mhf_get(wlc->hw, MHF1, WLC_BAND_AUTO) & + MHF1_ANTDIV); + break; + + case WLC_SET_UCANTDIV:{ + if (!wlc->pub->up) { + bcmerror = BCME_NOTUP; + break; + } + + /* if multiband, band must be locked */ + if (IS_MBAND_UNLOCKED(wlc)) { + bcmerror = BCME_NOTBANDLOCKED; + break; + } + + /* 4322 supports antdiv in phy, no need to set it to ucode */ + if (WLCISNPHY(wlc->band) + && D11REV_IS(wlc->pub->corerev, 16)) { + WL_ERROR("wl%d: can't set ucantdiv for 4322\n", + wlc->pub->unit); + bcmerror = BCME_UNSUPPORTED; + } else + wlc_mhf(wlc, MHF1, MHF1_ANTDIV, + (val ? MHF1_ANTDIV : 0), WLC_BAND_AUTO); + break; + } +#endif /* defined(BCMDBG) */ + + case WLC_GET_SRL: + *pval = wlc->SRL; + break; + + case WLC_SET_SRL: + if (val >= 1 && val <= RETRY_SHORT_MAX) { + int ac; + wlc->SRL = (u16) val; + + wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); + + for (ac = 0; ac < AC_COUNT; ac++) { + WLC_WME_RETRY_SHORT_SET(wlc, ac, wlc->SRL); + } + wlc_wme_retries_write(wlc); + } else + bcmerror = BCME_RANGE; + break; + + case WLC_GET_LRL: + *pval = wlc->LRL; + break; + + case WLC_SET_LRL: + if (val >= 1 && val <= 255) { + int ac; + wlc->LRL = (u16) val; + + wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); + + for (ac = 0; ac < AC_COUNT; ac++) { + WLC_WME_RETRY_LONG_SET(wlc, ac, wlc->LRL); + } + wlc_wme_retries_write(wlc); + } else + bcmerror = BCME_RANGE; + break; + + case WLC_GET_CWMIN: + *pval = wlc->band->CWmin; + break; + + case WLC_SET_CWMIN: + if (!wlc->clk) { + bcmerror = BCME_NOCLK; + break; + } + + if (val >= 1 && val <= 255) { + wlc_set_cwmin(wlc, (u16) val); + } else + bcmerror = BCME_RANGE; + break; + + case WLC_GET_CWMAX: + *pval = wlc->band->CWmax; + break; + + case WLC_SET_CWMAX: + if (!wlc->clk) { + bcmerror = BCME_NOCLK; + break; + } + + if (val >= 255 && val <= 2047) { + wlc_set_cwmax(wlc, (u16) val); + } else + bcmerror = BCME_RANGE; + break; + + case WLC_GET_RADIO: /* use mask if don't want to expose some internal bits */ + *pval = wlc->pub->radio_disabled; + break; + + case WLC_SET_RADIO:{ /* 32 bits input, higher 16 bits are mask, lower 16 bits are value to + * set + */ + u16 radiomask, radioval; + uint validbits = + WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE; + mbool new = 0; + + radiomask = (val & 0xffff0000) >> 16; + radioval = val & 0x0000ffff; + + if ((radiomask == 0) || (radiomask & ~validbits) + || (radioval & ~validbits) + || ((radioval & ~radiomask) != 0)) { + WL_ERROR("SET_RADIO with wrong bits 0x%x\n", + val); + bcmerror = BCME_RANGE; + break; + } + + new = + (wlc->pub->radio_disabled & ~radiomask) | radioval; + wlc->pub->radio_disabled = new; + + wlc_radio_hwdisable_upd(wlc); + wlc_radio_upd(wlc); + break; + } + + case WLC_GET_PHYTYPE: + *pval = WLC_PHYTYPE(wlc->band->phytype); + break; + +#if defined(BCMDBG) + case WLC_GET_KEY: + if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc))) { + wl_wsec_key_t key; + + wsec_key_t *src_key = wlc->wsec_keys[val]; + + if (len < (int)sizeof(key)) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + memset((char *)&key, 0, sizeof(key)); + if (src_key) { + key.index = src_key->id; + key.len = src_key->len; + bcopy(src_key->data, key.data, key.len); + key.algo = src_key->algo; + if (WSEC_SOFTKEY(wlc, src_key, bsscfg)) + key.flags |= WL_SOFT_KEY; + if (src_key->flags & WSEC_PRIMARY_KEY) + key.flags |= WL_PRIMARY_KEY; + + bcopy(src_key->ea, key.ea, + ETH_ALEN); + } + + bcopy((char *)&key, arg, sizeof(key)); + } else + bcmerror = BCME_BADKEYIDX; + break; +#endif /* defined(BCMDBG) */ + + case WLC_SET_KEY: + bcmerror = + wlc_iovar_op(wlc, "wsec_key", NULL, 0, arg, len, IOV_SET, + wlcif); + break; + + case WLC_GET_KEY_SEQ:{ + wsec_key_t *key; + + if (len < DOT11_WPA_KEY_RSC_LEN) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + /* Return the key's tx iv as an EAPOL sequence counter. + * This will be used to supply the RSC value to a supplicant. + * The format is 8 bytes, with least significant in seq[0]. + */ + + key = WSEC_KEY(wlc, val); + if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc)) && + (key != NULL)) { + u8 seq[DOT11_WPA_KEY_RSC_LEN]; + u16 lo; + u32 hi; + /* group keys in WPA-NONE (IBSS only, AES and TKIP) use a global TXIV */ + if ((bsscfg->WPA_auth & WPA_AUTH_NONE) && + is_zero_ether_addr(key->ea)) { + lo = bsscfg->wpa_none_txiv.lo; + hi = bsscfg->wpa_none_txiv.hi; + } else { + lo = key->txiv.lo; + hi = key->txiv.hi; + } + + /* format the buffer, low to high */ + seq[0] = lo & 0xff; + seq[1] = (lo >> 8) & 0xff; + seq[2] = hi & 0xff; + seq[3] = (hi >> 8) & 0xff; + seq[4] = (hi >> 16) & 0xff; + seq[5] = (hi >> 24) & 0xff; + seq[6] = 0; + seq[7] = 0; + + bcopy((char *)seq, arg, sizeof(seq)); + } else { + bcmerror = BCME_BADKEYIDX; + } + break; + } + + case WLC_GET_CURR_RATESET:{ + wl_rateset_t *ret_rs = (wl_rateset_t *) arg; + wlc_rateset_t *rs; + + if (bsscfg->associated) + rs = ¤t_bss->rateset; + else + rs = &wlc->default_bss->rateset; + + if (len < (int)(rs->count + sizeof(rs->count))) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + /* Copy only legacy rateset section */ + ret_rs->count = rs->count; + bcopy(&rs->rates, &ret_rs->rates, rs->count); + break; + } + + case WLC_GET_RATESET:{ + wlc_rateset_t rs; + wl_rateset_t *ret_rs = (wl_rateset_t *) arg; + + memset(&rs, 0, sizeof(wlc_rateset_t)); + wlc_default_rateset(wlc, (wlc_rateset_t *) &rs); + + if (len < (int)(rs.count + sizeof(rs.count))) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + /* Copy only legacy rateset section */ + ret_rs->count = rs.count; + bcopy(&rs.rates, &ret_rs->rates, rs.count); + break; + } + + case WLC_SET_RATESET:{ + wlc_rateset_t rs; + wl_rateset_t *in_rs = (wl_rateset_t *) arg; + + if (len < (int)(in_rs->count + sizeof(in_rs->count))) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + if (in_rs->count > WLC_NUMRATES) { + bcmerror = BCME_BUFTOOLONG; + break; + } + + memset(&rs, 0, sizeof(wlc_rateset_t)); + + /* Copy only legacy rateset section */ + rs.count = in_rs->count; + bcopy(&in_rs->rates, &rs.rates, rs.count); + + /* merge rateset coming in with the current mcsset */ + if (N_ENAB(wlc->pub)) { + if (bsscfg->associated) + bcopy(¤t_bss->rateset.mcs[0], + rs.mcs, MCSSET_LEN); + else + bcopy(&wlc->default_bss->rateset.mcs[0], + rs.mcs, MCSSET_LEN); + } + + bcmerror = wlc_set_rateset(wlc, &rs); + + if (!bcmerror) + wlc_ofdm_rateset_war(wlc); + + break; + } + + case WLC_GET_BCNPRD: + if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated) + *pval = current_bss->beacon_period; + else + *pval = wlc->default_bss->beacon_period; + break; + + case WLC_SET_BCNPRD: + /* range [1, 0xffff] */ + if (val >= DOT11_MIN_BEACON_PERIOD + && val <= DOT11_MAX_BEACON_PERIOD) { + wlc->default_bss->beacon_period = (u16) val; + } else + bcmerror = BCME_RANGE; + break; + + case WLC_GET_DTIMPRD: + if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated) + *pval = current_bss->dtim_period; + else + *pval = wlc->default_bss->dtim_period; + break; + + case WLC_SET_DTIMPRD: + /* range [1, 0xff] */ + if (val >= DOT11_MIN_DTIM_PERIOD + && val <= DOT11_MAX_DTIM_PERIOD) { + wlc->default_bss->dtim_period = (u8) val; + } else + bcmerror = BCME_RANGE; + break; + +#ifdef SUPPORT_PS + case WLC_GET_PM: + *pval = wlc->PM; + break; + + case WLC_SET_PM: + if ((val >= PM_OFF) && (val <= PM_MAX)) { + wlc->PM = (u8) val; + if (wlc->pub->up) { + } + /* Change watchdog driver to align watchdog with tbtt if possible */ + wlc_watchdog_upd(wlc, PS_ALLOWED(wlc)); + } else + bcmerror = BCME_ERROR; + break; +#endif /* SUPPORT_PS */ + +#ifdef SUPPORT_PS +#ifdef BCMDBG + case WLC_GET_WAKE: + if (AP_ENAB(wlc->pub)) { + bcmerror = BCME_NOTSTA; + break; + } + *pval = wlc->wake; + break; + + case WLC_SET_WAKE: + if (AP_ENAB(wlc->pub)) { + bcmerror = BCME_NOTSTA; + break; + } + + wlc->wake = val ? true : false; + + /* if down, we're done */ + if (!wlc->pub->up) + break; + + /* apply to the mac */ + wlc_set_ps_ctrl(wlc); + break; +#endif /* BCMDBG */ +#endif /* SUPPORT_PS */ + + case WLC_GET_REVINFO: + bcmerror = wlc_get_revision_info(wlc, arg, (uint) len); + break; + + case WLC_GET_AP: + *pval = (int)AP_ENAB(wlc->pub); + break; + + case WLC_GET_ATIM: + if (bsscfg->associated) + *pval = (int)current_bss->atim_window; + else + *pval = (int)wlc->default_bss->atim_window; + break; + + case WLC_SET_ATIM: + wlc->default_bss->atim_window = (u32) val; + break; + + case WLC_GET_PKTCNTS:{ + get_pktcnt_t *pktcnt = (get_pktcnt_t *) pval; + if (WLC_UPDATE_STATS(wlc)) + wlc_statsupd(wlc); + pktcnt->rx_good_pkt = WLCNTVAL(wlc->pub->_cnt->rxframe); + pktcnt->rx_bad_pkt = WLCNTVAL(wlc->pub->_cnt->rxerror); + pktcnt->tx_good_pkt = + WLCNTVAL(wlc->pub->_cnt->txfrmsnt); + pktcnt->tx_bad_pkt = + WLCNTVAL(wlc->pub->_cnt->txerror) + + WLCNTVAL(wlc->pub->_cnt->txfail); + if (len >= (int)sizeof(get_pktcnt_t)) { + /* Be backward compatible - only if buffer is large enough */ + pktcnt->rx_ocast_good_pkt = + WLCNTVAL(wlc->pub->_cnt->rxmfrmocast); + } + break; + } + +#ifdef SUPPORT_HWKEY + case WLC_GET_WSEC: + bcmerror = + wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_GET, + wlcif); + break; + + case WLC_SET_WSEC: + bcmerror = + wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_SET, + wlcif); + break; + + case WLC_GET_WPA_AUTH: + *pval = (int)bsscfg->WPA_auth; + break; + + case WLC_SET_WPA_AUTH: + /* change of WPA_Auth modifies the PS_ALLOWED state */ + if (BSSCFG_STA(bsscfg)) { + bsscfg->WPA_auth = (u16) val; + } else + bsscfg->WPA_auth = (u16) val; + break; +#endif /* SUPPORT_HWKEY */ + + case WLC_GET_BANDLIST: + /* count of number of bands, followed by each band type */ + *pval++ = NBANDS(wlc); + *pval++ = wlc->band->bandtype; + if (NBANDS(wlc) > 1) + *pval++ = wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype; + break; + + case WLC_GET_BAND: + *pval = wlc->bandlocked ? wlc->band->bandtype : WLC_BAND_AUTO; + break; + + case WLC_GET_PHYLIST: + { + unsigned char *cp = arg; + if (len < 3) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + if (WLCISNPHY(wlc->band)) { + *cp++ = 'n'; + } else if (WLCISLCNPHY(wlc->band)) { + *cp++ = 'c'; + } else if (WLCISSSLPNPHY(wlc->band)) { + *cp++ = 's'; + } + *cp = '\0'; + break; + } + + case WLC_GET_SHORTSLOT: + *pval = wlc->shortslot; + break; + + case WLC_GET_SHORTSLOT_OVERRIDE: + *pval = wlc->shortslot_override; + break; + + case WLC_SET_SHORTSLOT_OVERRIDE: + if ((val != WLC_SHORTSLOT_AUTO) && + (val != WLC_SHORTSLOT_OFF) && (val != WLC_SHORTSLOT_ON)) { + bcmerror = BCME_RANGE; + break; + } + + wlc->shortslot_override = (s8) val; + + /* shortslot is an 11g feature, so no more work if we are + * currently on the 5G band + */ + if (BAND_5G(wlc->band->bandtype)) + break; + + if (wlc->pub->up && wlc->pub->associated) { + /* let watchdog or beacon processing update shortslot */ + } else if (wlc->pub->up) { + /* unassociated shortslot is off */ + wlc_switch_shortslot(wlc, false); + } else { + /* driver is down, so just update the wlc_info value */ + if (wlc->shortslot_override == WLC_SHORTSLOT_AUTO) { + wlc->shortslot = false; + } else { + wlc->shortslot = + (wlc->shortslot_override == + WLC_SHORTSLOT_ON); + } + } + + break; + + case WLC_GET_LEGACY_ERP: + *pval = wlc->include_legacy_erp; + break; + + case WLC_SET_LEGACY_ERP: + if (wlc->include_legacy_erp == bool_val) + break; + + wlc->include_legacy_erp = bool_val; + + if (AP_ENAB(wlc->pub) && wlc->clk) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, true); + } + break; + + case WLC_GET_GMODE: + if (wlc->band->bandtype == WLC_BAND_2G) + *pval = wlc->band->gmode; + else if (NBANDS(wlc) > 1) + *pval = wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode; + break; + + case WLC_SET_GMODE: + if (!wlc->pub->associated) + bcmerror = wlc_set_gmode(wlc, (u8) val, true); + else { + bcmerror = BCME_ASSOCIATED; + break; + } + break; + + case WLC_GET_GMODE_PROTECTION: + *pval = wlc->protection->_g; + break; + + case WLC_GET_PROTECTION_CONTROL: + *pval = wlc->protection->overlap; + break; + + case WLC_SET_PROTECTION_CONTROL: + if ((val != WLC_PROTECTION_CTL_OFF) && + (val != WLC_PROTECTION_CTL_LOCAL) && + (val != WLC_PROTECTION_CTL_OVERLAP)) { + bcmerror = BCME_RANGE; + break; + } + + wlc_protection_upd(wlc, WLC_PROT_OVERLAP, (s8) val); + + /* Current g_protection will sync up to the specified control alg in watchdog + * if the driver is up and associated. + * If the driver is down or not associated, the control setting has no effect. + */ + break; + + case WLC_GET_GMODE_PROTECTION_OVERRIDE: + *pval = wlc->protection->g_override; + break; + + case WLC_SET_GMODE_PROTECTION_OVERRIDE: + if ((val != WLC_PROTECTION_AUTO) && + (val != WLC_PROTECTION_OFF) && (val != WLC_PROTECTION_ON)) { + bcmerror = BCME_RANGE; + break; + } + + wlc_protection_upd(wlc, WLC_PROT_G_OVR, (s8) val); + + break; + + case WLC_SET_SUP_RATESET_OVERRIDE:{ + wlc_rateset_t rs, new; + + /* copyin */ + if (len < (int)sizeof(wlc_rateset_t)) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + bcopy((char *)arg, (char *)&rs, sizeof(wlc_rateset_t)); + + /* check for bad count value */ + if (rs.count > WLC_NUMRATES) { + bcmerror = BCME_BADRATESET; /* invalid rateset */ + break; + } + + /* this command is only appropriate for gmode operation */ + if (!(wlc->band->gmode || + ((NBANDS(wlc) > 1) + && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) { + bcmerror = BCME_BADBAND; /* gmode only command when not in gmode */ + break; + } + + /* check for an empty rateset to clear the override */ + if (rs.count == 0) { + memset(&wlc->sup_rates_override, 0, + sizeof(wlc_rateset_t)); + break; + } + + /* validate rateset by comparing pre and post sorted against 11g hw rates */ + wlc_rateset_filter(&rs, &new, false, WLC_RATES_CCK_OFDM, + RATE_MASK, BSS_N_ENAB(wlc, bsscfg)); + wlc_rate_hwrs_filter_sort_validate(&new, + &cck_ofdm_rates, + false, + wlc->stf->txstreams); + if (rs.count != new.count) { + bcmerror = BCME_BADRATESET; /* invalid rateset */ + break; + } + + /* apply new rateset to the override */ + bcopy((char *)&new, (char *)&wlc->sup_rates_override, + sizeof(wlc_rateset_t)); + + /* update bcn and probe resp if needed */ + if (wlc->pub->up && AP_ENAB(wlc->pub) + && wlc->pub->associated) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, true); + } + break; + } + + case WLC_GET_SUP_RATESET_OVERRIDE: + /* this command is only appropriate for gmode operation */ + if (!(wlc->band->gmode || + ((NBANDS(wlc) > 1) + && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) { + bcmerror = BCME_BADBAND; /* gmode only command when not in gmode */ + break; + } + if (len < (int)sizeof(wlc_rateset_t)) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + bcopy((char *)&wlc->sup_rates_override, (char *)arg, + sizeof(wlc_rateset_t)); + + break; + + case WLC_GET_PRB_RESP_TIMEOUT: + *pval = wlc->prb_resp_timeout; + break; + + case WLC_SET_PRB_RESP_TIMEOUT: + if (wlc->pub->up) { + bcmerror = BCME_NOTDOWN; + break; + } + if (val < 0 || val >= 0xFFFF) { + bcmerror = BCME_RANGE; /* bad value */ + break; + } + wlc->prb_resp_timeout = (u16) val; + break; + + case WLC_GET_KEY_PRIMARY:{ + wsec_key_t *key; + + /* treat the 'val' parm as the key id */ + key = WSEC_BSS_DEFAULT_KEY(bsscfg); + if (key != NULL) { + *pval = key->id == val ? true : false; + } else { + bcmerror = BCME_BADKEYIDX; + } + break; + } + + case WLC_SET_KEY_PRIMARY:{ + wsec_key_t *key, *old_key; + + bcmerror = BCME_BADKEYIDX; + + /* treat the 'val' parm as the key id */ + for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) { + key = bsscfg->bss_def_keys[i]; + if (key != NULL && key->id == val) { + old_key = WSEC_BSS_DEFAULT_KEY(bsscfg); + if (old_key != NULL) + old_key->flags &= + ~WSEC_PRIMARY_KEY; + key->flags |= WSEC_PRIMARY_KEY; + bsscfg->wsec_index = i; + bcmerror = BCME_OK; + } + } + break; + } + +#ifdef BCMDBG + case WLC_INIT: + wl_init(wlc->wl); + break; +#endif + + case WLC_SET_VAR: + case WLC_GET_VAR:{ + char *name; + /* validate the name value */ + name = (char *)arg; + for (i = 0; i < (uint) len && *name != '\0'; + i++, name++) + ; + + if (i == (uint) len) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + i++; /* include the null in the string length */ + + if (cmd == WLC_GET_VAR) { + bcmerror = + wlc_iovar_op(wlc, arg, + (void *)((s8 *) arg + i), + len - i, arg, len, IOV_GET, + wlcif); + } else + bcmerror = + wlc_iovar_op(wlc, arg, NULL, 0, + (void *)((s8 *) arg + i), + len - i, IOV_SET, wlcif); + + break; + } + + case WLC_SET_WSEC_PMK: + bcmerror = BCME_UNSUPPORTED; + break; + +#if defined(BCMDBG) + case WLC_CURRENT_PWR: + if (!wlc->pub->up) + bcmerror = BCME_NOTUP; + else + bcmerror = wlc_get_current_txpwr(wlc, arg, len); + break; +#endif + + case WLC_LAST: + WL_ERROR("%s: WLC_LAST\n", __func__); + } + done: + + if (bcmerror) { + if (VALID_BCMERROR(bcmerror)) + wlc->pub->bcmerror = bcmerror; + else { + bcmerror = 0; + } + + } + /* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */ + /* In hw_off condition, IOCTLs that reach here are deemed safe but taclear would + * certainly result in getting -1 for register reads. So skip ta_clear altogether + */ + if (!(wlc->pub->hw_off)) + ASSERT(wlc_bmac_taclear(wlc->hw, ta_ok) || !ta_ok); + + return bcmerror; +} + +#if defined(BCMDBG) +/* consolidated register access ioctl error checking */ +int wlc_iocregchk(struct wlc_info *wlc, uint band) +{ + /* if band is specified, it must be the current band */ + if ((band != WLC_BAND_AUTO) && (band != (uint) wlc->band->bandtype)) + return BCME_BADBAND; + + /* if multiband and band is not specified, band must be locked */ + if ((band == WLC_BAND_AUTO) && IS_MBAND_UNLOCKED(wlc)) + return BCME_NOTBANDLOCKED; + + /* must have core clocks */ + if (!wlc->clk) + return BCME_NOCLK; + + return 0; +} +#endif /* defined(BCMDBG) */ + +#if defined(BCMDBG) +/* For some ioctls, make sure that the pi pointer matches the current phy */ +int wlc_iocpichk(struct wlc_info *wlc, uint phytype) +{ + if (wlc->band->phytype != phytype) + return BCME_BADBAND; + return 0; +} +#endif + +/* Look up the given var name in the given table */ +static const bcm_iovar_t *wlc_iovar_lookup(const bcm_iovar_t *table, + const char *name) +{ + const bcm_iovar_t *vi; + const char *lookup_name; + + /* skip any ':' delimited option prefixes */ + lookup_name = strrchr(name, ':'); + if (lookup_name != NULL) + lookup_name++; + else + lookup_name = name; + + ASSERT(table != NULL); + + for (vi = table; vi->name; vi++) { + if (!strcmp(vi->name, lookup_name)) + return vi; + } + /* ran to end of table */ + + return NULL; /* var name not found */ +} + +/* simplified integer get interface for common WLC_GET_VAR ioctl handler */ +int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg) +{ + return wlc_iovar_op(wlc, name, NULL, 0, arg, sizeof(s32), IOV_GET, + NULL); +} + +/* simplified integer set interface for common WLC_SET_VAR ioctl handler */ +int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg) +{ + return wlc_iovar_op(wlc, name, NULL, 0, (void *)&arg, sizeof(arg), + IOV_SET, NULL); +} + +/* simplified s8 get interface for common WLC_GET_VAR ioctl handler */ +int wlc_iovar_gets8(struct wlc_info *wlc, const char *name, s8 *arg) +{ + int iovar_int; + int err; + + err = + wlc_iovar_op(wlc, name, NULL, 0, &iovar_int, sizeof(iovar_int), + IOV_GET, NULL); + if (!err) + *arg = (s8) iovar_int; + + return err; +} + +/* + * register iovar table, watchdog and down handlers. + * calling function must keep 'iovars' until wlc_module_unregister is called. + * 'iovar' must have the last entry's name field being NULL as terminator. + */ +int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, + const char *name, void *hdl, iovar_fn_t i_fn, + watchdog_fn_t w_fn, down_fn_t d_fn) +{ + struct wlc_info *wlc = (struct wlc_info *) pub->wlc; + int i; + + ASSERT(name != NULL); + ASSERT(i_fn != NULL || w_fn != NULL || d_fn != NULL); + + /* find an empty entry and just add, no duplication check! */ + for (i = 0; i < WLC_MAXMODULES; i++) { + if (wlc->modulecb[i].name[0] == '\0') { + strncpy(wlc->modulecb[i].name, name, + sizeof(wlc->modulecb[i].name) - 1); + wlc->modulecb[i].iovars = iovars; + wlc->modulecb[i].hdl = hdl; + wlc->modulecb[i].iovar_fn = i_fn; + wlc->modulecb[i].watchdog_fn = w_fn; + wlc->modulecb[i].down_fn = d_fn; + return 0; + } + } + + /* it is time to increase the capacity */ + ASSERT(i < WLC_MAXMODULES); + return BCME_NORESOURCE; +} + +/* unregister module callbacks */ +int wlc_module_unregister(struct wlc_pub *pub, const char *name, void *hdl) +{ + struct wlc_info *wlc = (struct wlc_info *) pub->wlc; + int i; + + if (wlc == NULL) + return BCME_NOTFOUND; + + ASSERT(name != NULL); + + for (i = 0; i < WLC_MAXMODULES; i++) { + if (!strcmp(wlc->modulecb[i].name, name) && + (wlc->modulecb[i].hdl == hdl)) { + memset(&wlc->modulecb[i], 0, sizeof(modulecb_t)); + return 0; + } + } + + /* table not found! */ + return BCME_NOTFOUND; +} + +/* Write WME tunable parameters for retransmit/max rate from wlc struct to ucode */ +static void wlc_wme_retries_write(struct wlc_info *wlc) +{ + int ac; + + /* Need clock to do this */ + if (!wlc->clk) + return; + + for (ac = 0; ac < AC_COUNT; ac++) { + wlc_write_shm(wlc, M_AC_TXLMT_ADDR(ac), wlc->wme_retries[ac]); + } +} + +/* Get or set an iovar. The params/p_len pair specifies any additional + * qualifying parameters (e.g. an "element index") for a get, while the + * arg/len pair is the buffer for the value to be set or retrieved. + * Operation (get/set) is specified by the last argument. + * interface context provided by wlcif + * + * All pointers may point into the same buffer. + */ +int +wlc_iovar_op(struct wlc_info *wlc, const char *name, + void *params, int p_len, void *arg, int len, + bool set, struct wlc_if *wlcif) +{ + int err = 0; + int val_size; + const bcm_iovar_t *vi = NULL; + u32 actionid; + int i; + + ASSERT(name != NULL); + + ASSERT(len >= 0); + + /* Get MUST have return space */ + ASSERT(set || (arg && len)); + + ASSERT(!(wlc->pub->hw_off && wlc->pub->up)); + + /* Set does NOT take qualifiers */ + ASSERT(!set || (!params && !p_len)); + + if (!set && (len == sizeof(int)) && + !(IS_ALIGNED((unsigned long)(arg), (uint) sizeof(int)))) { + WL_ERROR("wl%d: %s unaligned get ptr for %s\n", + wlc->pub->unit, __func__, name); + ASSERT(0); + } + + /* find the given iovar name */ + for (i = 0; i < WLC_MAXMODULES; i++) { + if (!wlc->modulecb[i].iovars) + continue; + vi = wlc_iovar_lookup(wlc->modulecb[i].iovars, name); + if (vi) + break; + } + /* iovar name not found */ + if (i >= WLC_MAXMODULES) { + err = BCME_UNSUPPORTED; + goto exit; + } + + /* set up 'params' pointer in case this is a set command so that + * the convenience int and bool code can be common to set and get + */ + if (params == NULL) { + params = arg; + p_len = len; + } + + if (vi->type == IOVT_VOID) + val_size = 0; + else if (vi->type == IOVT_BUFFER) + val_size = len; + else + /* all other types are integer sized */ + val_size = sizeof(int); + + actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); + + /* Do the actual parameter implementation */ + err = wlc->modulecb[i].iovar_fn(wlc->modulecb[i].hdl, vi, actionid, + name, params, p_len, arg, len, val_size, + wlcif); + + exit: + return err; +} + +int +wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, void *arg, int len, + bool set) +{ + struct wlc_info *wlc = (struct wlc_info *) pub->wlc; + int err = 0; + s32 int_val = 0; + + /* check generic condition flags */ + if (set) { + if (((vi->flags & IOVF_SET_DOWN) && wlc->pub->up) || + ((vi->flags & IOVF_SET_UP) && !wlc->pub->up)) { + err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP); + } else if ((vi->flags & IOVF_SET_BAND) + && IS_MBAND_UNLOCKED(wlc)) { + err = BCME_NOTBANDLOCKED; + } else if ((vi->flags & IOVF_SET_CLK) && !wlc->clk) { + err = BCME_NOCLK; + } + } else { + if (((vi->flags & IOVF_GET_DOWN) && wlc->pub->up) || + ((vi->flags & IOVF_GET_UP) && !wlc->pub->up)) { + err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP); + } else if ((vi->flags & IOVF_GET_BAND) + && IS_MBAND_UNLOCKED(wlc)) { + err = BCME_NOTBANDLOCKED; + } else if ((vi->flags & IOVF_GET_CLK) && !wlc->clk) { + err = BCME_NOCLK; + } + } + + if (err) + goto exit; + + /* length check on io buf */ + err = bcm_iovar_lencheck(vi, arg, len, set); + if (err) + goto exit; + + /* On set, check value ranges for integer types */ + if (set) { + switch (vi->type) { + case IOVT_BOOL: + case IOVT_INT8: + case IOVT_INT16: + case IOVT_INT32: + case IOVT_UINT8: + case IOVT_UINT16: + case IOVT_UINT32: + bcopy(arg, &int_val, sizeof(int)); + err = wlc_iovar_rangecheck(wlc, int_val, vi); + break; + } + } + exit: + return err; +} + +/* handler for iovar table wlc_iovars */ +/* + * IMPLEMENTATION NOTE: In order to avoid checking for get/set in each + * iovar case, the switch statement maps the iovar id into separate get + * and set values. If you add a new iovar to the switch you MUST use + * IOV_GVAL and/or IOV_SVAL in the case labels to avoid conflict with + * another case. + * Please use params for additional qualifying parameters. + */ +int +wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, + const char *name, void *params, uint p_len, void *arg, int len, + int val_size, struct wlc_if *wlcif) +{ + struct wlc_info *wlc = hdl; + wlc_bsscfg_t *bsscfg; + int err = 0; + s32 int_val = 0; + s32 int_val2 = 0; + s32 *ret_int_ptr; + bool bool_val; + bool bool_val2; + wlc_bss_info_t *current_bss; + + WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__); + + bsscfg = NULL; + current_bss = NULL; + + err = wlc_iovar_check(wlc->pub, vi, arg, len, IOV_ISSET(actionid)); + if (err != 0) + return err; + + /* convenience int and bool vals for first 8 bytes of buffer */ + if (p_len >= (int)sizeof(int_val)) + bcopy(params, &int_val, sizeof(int_val)); + + if (p_len >= (int)sizeof(int_val) * 2) + bcopy((void *)((unsigned long)params + sizeof(int_val)), &int_val2, + sizeof(int_val)); + + /* convenience int ptr for 4-byte gets (requires int aligned arg) */ + ret_int_ptr = (s32 *) arg; + + bool_val = (int_val != 0) ? true : false; + bool_val2 = (int_val2 != 0) ? true : false; + + WL_TRACE("wl%d: %s: id %d\n", + wlc->pub->unit, __func__, IOV_ID(actionid)); + /* Do the actual parameter implementation */ + switch (actionid) { + + case IOV_GVAL(IOV_QTXPOWER):{ + uint qdbm; + bool override; + + err = wlc_phy_txpower_get(wlc->band->pi, &qdbm, + &override); + if (err != BCME_OK) + return err; + + /* Return qdbm units */ + *ret_int_ptr = + qdbm | (override ? WL_TXPWR_OVERRIDE : 0); + break; + } + + /* As long as override is false, this only sets the *user* targets. + User can twiddle this all he wants with no harm. + wlc_phy_txpower_set() explicitly sets override to false if + not internal or test. + */ + case IOV_SVAL(IOV_QTXPOWER):{ + u8 qdbm; + bool override; + + /* Remove override bit and clip to max qdbm value */ + qdbm = (u8)min_t(u32, (int_val & ~WL_TXPWR_OVERRIDE), 0xff); + /* Extract override setting */ + override = (int_val & WL_TXPWR_OVERRIDE) ? true : false; + err = + wlc_phy_txpower_set(wlc->band->pi, qdbm, override); + break; + } + + case IOV_GVAL(IOV_MPC): + *ret_int_ptr = (s32) wlc->mpc; + break; + + case IOV_SVAL(IOV_MPC): + wlc->mpc = bool_val; + wlc_radio_mpc_upd(wlc); + + break; + + case IOV_GVAL(IOV_BCN_LI_BCN): + *ret_int_ptr = wlc->bcn_li_bcn; + break; + + case IOV_SVAL(IOV_BCN_LI_BCN): + wlc->bcn_li_bcn = (u8) int_val; + if (wlc->pub->up) + wlc_bcn_li_upd(wlc); + break; + + default: + WL_ERROR("wl%d: %s: unsupported\n", wlc->pub->unit, __func__); + err = BCME_UNSUPPORTED; + break; + } + + goto exit; /* avoid unused label warning */ + + exit: + return err; +} + +static int +wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, const bcm_iovar_t *vi) +{ + int err = 0; + u32 min_val = 0; + u32 max_val = 0; + + /* Only ranged integers are checked */ + switch (vi->type) { + case IOVT_INT32: + max_val |= 0x7fffffff; + /* fall through */ + case IOVT_INT16: + max_val |= 0x00007fff; + /* fall through */ + case IOVT_INT8: + max_val |= 0x0000007f; + min_val = ~max_val; + if (vi->flags & IOVF_NTRL) + min_val = 1; + else if (vi->flags & IOVF_WHL) + min_val = 0; + /* Signed values are checked against max_val and min_val */ + if ((s32) val < (s32) min_val + || (s32) val > (s32) max_val) + err = BCME_RANGE; + break; + + case IOVT_UINT32: + max_val |= 0xffffffff; + /* fall through */ + case IOVT_UINT16: + max_val |= 0x0000ffff; + /* fall through */ + case IOVT_UINT8: + max_val |= 0x000000ff; + if (vi->flags & IOVF_NTRL) + min_val = 1; + if ((val < min_val) || (val > max_val)) + err = BCME_RANGE; + break; + } + + return err; +} + +#ifdef BCMDBG +static const char *supr_reason[] = { + "None", "PMQ Entry", "Flush request", + "Previous frag failure", "Channel mismatch", + "Lifetime Expiry", "Underflow" +}; + +static void wlc_print_txs_status(u16 s) +{ + printf("[15:12] %d frame attempts\n", (s & TX_STATUS_FRM_RTX_MASK) >> + TX_STATUS_FRM_RTX_SHIFT); + printf(" [11:8] %d rts attempts\n", (s & TX_STATUS_RTS_RTX_MASK) >> + TX_STATUS_RTS_RTX_SHIFT); + printf(" [7] %d PM mode indicated\n", + ((s & TX_STATUS_PMINDCTD) ? 1 : 0)); + printf(" [6] %d intermediate status\n", + ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0)); + printf(" [5] %d AMPDU\n", (s & TX_STATUS_AMPDU) ? 1 : 0); + printf(" [4:2] %d Frame Suppressed Reason (%s)\n", + ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT), + supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]); + printf(" [1] %d acked\n", ((s & TX_STATUS_ACK_RCV) ? 1 : 0)); +} +#endif /* BCMDBG */ + +void wlc_print_txstatus(tx_status_t *txs) +{ +#if defined(BCMDBG) + u16 s = txs->status; + u16 ackphyrxsh = txs->ackphyrxsh; + + printf("\ntxpkt (MPDU) Complete\n"); + + printf("FrameID: %04x ", txs->frameid); + printf("TxStatus: %04x", s); + printf("\n"); +#ifdef BCMDBG + wlc_print_txs_status(s); +#endif + printf("LastTxTime: %04x ", txs->lasttxtime); + printf("Seq: %04x ", txs->sequence); + printf("PHYTxStatus: %04x ", txs->phyerr); + printf("RxAckRSSI: %04x ", + (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT); + printf("RxAckSQ: %04x", (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); + printf("\n"); +#endif /* defined(BCMDBG) */ +} + +#define MACSTATUPD(name) \ + wlc_ctrupd_cache(macstats.name, &wlc->core->macstat_snapshot->name, &wlc->pub->_cnt->name) + +void wlc_statsupd(struct wlc_info *wlc) +{ + int i; +#ifdef BCMDBG + u16 delta; + u16 rxf0ovfl; + u16 txfunfl[NFIFO]; +#endif /* BCMDBG */ + + /* if driver down, make no sense to update stats */ + if (!wlc->pub->up) + return; + +#ifdef BCMDBG + /* save last rx fifo 0 overflow count */ + rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl; + + /* save last tx fifo underflow count */ + for (i = 0; i < NFIFO; i++) + txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i]; +#endif /* BCMDBG */ + +#ifdef BCMDBG + /* check for rx fifo 0 overflow */ + delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); + if (delta) + WL_ERROR("wl%d: %u rx fifo 0 overflows!\n", + wlc->pub->unit, delta); + + /* check for tx fifo underflows */ + for (i = 0; i < NFIFO; i++) { + delta = + (u16) (wlc->core->macstat_snapshot->txfunfl[i] - + txfunfl[i]); + if (delta) + WL_ERROR("wl%d: %u tx fifo %d underflows!\n", + wlc->pub->unit, delta, i); + } +#endif /* BCMDBG */ + + /* dot11 counter update */ + + WLCNTSET(wlc->pub->_cnt->txrts, + (wlc->pub->_cnt->rxctsucast - + wlc->pub->_cnt->d11cnt_txrts_off)); + WLCNTSET(wlc->pub->_cnt->rxcrc, + (wlc->pub->_cnt->rxbadfcs - wlc->pub->_cnt->d11cnt_rxcrc_off)); + WLCNTSET(wlc->pub->_cnt->txnocts, + ((wlc->pub->_cnt->txrtsfrm - wlc->pub->_cnt->rxctsucast) - + wlc->pub->_cnt->d11cnt_txnocts_off)); + + /* merge counters from dma module */ + for (i = 0; i < NFIFO; i++) { + if (wlc->hw->di[i]) { + WLCNTADD(wlc->pub->_cnt->txnobuf, + (wlc->hw->di[i])->txnobuf); + WLCNTADD(wlc->pub->_cnt->rxnobuf, + (wlc->hw->di[i])->rxnobuf); + WLCNTADD(wlc->pub->_cnt->rxgiant, + (wlc->hw->di[i])->rxgiants); + dma_counterreset(wlc->hw->di[i]); + } + } + + /* + * Aggregate transmit and receive errors that probably resulted + * in the loss of a frame are computed on the fly. + */ + WLCNTSET(wlc->pub->_cnt->txerror, + wlc->pub->_cnt->txnobuf + wlc->pub->_cnt->txnoassoc + + wlc->pub->_cnt->txuflo + wlc->pub->_cnt->txrunt + + wlc->pub->_cnt->dmade + wlc->pub->_cnt->dmada + + wlc->pub->_cnt->dmape); + WLCNTSET(wlc->pub->_cnt->rxerror, + wlc->pub->_cnt->rxoflo + wlc->pub->_cnt->rxnobuf + + wlc->pub->_cnt->rxfragerr + wlc->pub->_cnt->rxrunt + + wlc->pub->_cnt->rxgiant + wlc->pub->_cnt->rxnoscb + + wlc->pub->_cnt->rxbadsrcmac); + for (i = 0; i < NFIFO; i++) + WLCNTADD(wlc->pub->_cnt->rxerror, wlc->pub->_cnt->rxuflo[i]); +} + +bool wlc_chipmatch(u16 vendor, u16 device) +{ + if (vendor != VENDOR_BROADCOM) { + WL_ERROR("wlc_chipmatch: unknown vendor id %04x\n", vendor); + return false; + } + + if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID)) + return true; + + if (device == BCM4313_D11N2G_ID) + return true; + if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID)) + return true; + + WL_ERROR("wlc_chipmatch: unknown device id %04x\n", device); + return false; +} + +#if defined(BCMDBG) +void wlc_print_txdesc(d11txh_t *txh) +{ + u16 mtcl = ltoh16(txh->MacTxControlLow); + u16 mtch = ltoh16(txh->MacTxControlHigh); + u16 mfc = ltoh16(txh->MacFrameControl); + u16 tfest = ltoh16(txh->TxFesTimeNormal); + u16 ptcw = ltoh16(txh->PhyTxControlWord); + u16 ptcw_1 = ltoh16(txh->PhyTxControlWord_1); + u16 ptcw_1_Fbr = ltoh16(txh->PhyTxControlWord_1_Fbr); + u16 ptcw_1_Rts = ltoh16(txh->PhyTxControlWord_1_Rts); + u16 ptcw_1_FbrRts = ltoh16(txh->PhyTxControlWord_1_FbrRts); + u16 mainrates = ltoh16(txh->MainRates); + u16 xtraft = ltoh16(txh->XtraFrameTypes); + u8 *iv = txh->IV; + u8 *ra = txh->TxFrameRA; + u16 tfestfb = ltoh16(txh->TxFesTimeFallback); + u8 *rtspfb = txh->RTSPLCPFallback; + u16 rtsdfb = ltoh16(txh->RTSDurFallback); + u8 *fragpfb = txh->FragPLCPFallback; + u16 fragdfb = ltoh16(txh->FragDurFallback); + u16 mmodelen = ltoh16(txh->MModeLen); + u16 mmodefbrlen = ltoh16(txh->MModeFbrLen); + u16 tfid = ltoh16(txh->TxFrameID); + u16 txs = ltoh16(txh->TxStatus); + u16 mnmpdu = ltoh16(txh->MaxNMpdus); + u16 mabyte = ltoh16(txh->MaxABytes_MRT); + u16 mabyte_f = ltoh16(txh->MaxABytes_FBR); + u16 mmbyte = ltoh16(txh->MinMBytes); + + u8 *rtsph = txh->RTSPhyHeader; + struct ieee80211_rts rts = txh->rts_frame; + char hexbuf[256]; + + /* add plcp header along with txh descriptor */ + prhex("Raw TxDesc + plcp header", (unsigned char *) txh, sizeof(d11txh_t) + 48); + + printf("TxCtlLow: %04x ", mtcl); + printf("TxCtlHigh: %04x ", mtch); + printf("FC: %04x ", mfc); + printf("FES Time: %04x\n", tfest); + printf("PhyCtl: %04x%s ", ptcw, + (ptcw & PHY_TXC_SHORT_HDR) ? " short" : ""); + printf("PhyCtl_1: %04x ", ptcw_1); + printf("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr); + printf("PhyCtl_1_Rts: %04x ", ptcw_1_Rts); + printf("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts); + printf("MainRates: %04x ", mainrates); + printf("XtraFrameTypes: %04x ", xtraft); + printf("\n"); + + bcm_format_hex(hexbuf, iv, sizeof(txh->IV)); + printf("SecIV: %s\n", hexbuf); + bcm_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA)); + printf("RA: %s\n", hexbuf); + + printf("Fb FES Time: %04x ", tfestfb); + bcm_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback)); + printf("RTS PLCP: %s ", hexbuf); + printf("RTS DUR: %04x ", rtsdfb); + bcm_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback)); + printf("PLCP: %s ", hexbuf); + printf("DUR: %04x", fragdfb); + printf("\n"); + + printf("MModeLen: %04x ", mmodelen); + printf("MModeFbrLen: %04x\n", mmodefbrlen); + + printf("FrameID: %04x\n", tfid); + printf("TxStatus: %04x\n", txs); + + printf("MaxNumMpdu: %04x\n", mnmpdu); + printf("MaxAggbyte: %04x\n", mabyte); + printf("MaxAggbyte_fb: %04x\n", mabyte_f); + printf("MinByte: %04x\n", mmbyte); + + bcm_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader)); + printf("RTS PLCP: %s ", hexbuf); + bcm_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame)); + printf("RTS Frame: %s", hexbuf); + printf("\n"); + +} +#endif /* defined(BCMDBG) */ + +#if defined(BCMDBG) +void wlc_print_rxh(d11rxhdr_t *rxh) +{ + u16 len = rxh->RxFrameSize; + u16 phystatus_0 = rxh->PhyRxStatus_0; + u16 phystatus_1 = rxh->PhyRxStatus_1; + u16 phystatus_2 = rxh->PhyRxStatus_2; + u16 phystatus_3 = rxh->PhyRxStatus_3; + u16 macstatus1 = rxh->RxStatus1; + u16 macstatus2 = rxh->RxStatus2; + char flagstr[64]; + char lenbuf[20]; + static const bcm_bit_desc_t macstat_flags[] = { + {RXS_FCSERR, "FCSErr"}, + {RXS_RESPFRAMETX, "Reply"}, + {RXS_PBPRES, "PADDING"}, + {RXS_DECATMPT, "DeCr"}, + {RXS_DECERR, "DeCrErr"}, + {RXS_BCNSENT, "Bcn"}, + {0, NULL} + }; + + prhex("Raw RxDesc", (unsigned char *) rxh, sizeof(d11rxhdr_t)); + + bcm_format_flags(macstat_flags, macstatus1, flagstr, 64); + + snprintf(lenbuf, sizeof(lenbuf), "0x%x", len); + + printf("RxFrameSize: %6s (%d)%s\n", lenbuf, len, + (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : ""); + printf("RxPHYStatus: %04x %04x %04x %04x\n", + phystatus_0, phystatus_1, phystatus_2, phystatus_3); + printf("RxMACStatus: %x %s\n", macstatus1, flagstr); + printf("RXMACaggtype: %x\n", (macstatus2 & RXS_AGGTYPE_MASK)); + printf("RxTSFTime: %04x\n", rxh->RxTSFTime); +} +#endif /* defined(BCMDBG) */ + +#if defined(BCMDBG) +int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len) +{ + uint i, c; + char *p = buf; + char *endp = buf + SSID_FMT_BUF_LEN; + + if (ssid_len > IEEE80211_MAX_SSID_LEN) + ssid_len = IEEE80211_MAX_SSID_LEN; + + for (i = 0; i < ssid_len; i++) { + c = (uint) ssid[i]; + if (c == '\\') { + *p++ = '\\'; + *p++ = '\\'; + } else if (isprint((unsigned char) c)) { + *p++ = (char)c; + } else { + p += snprintf(p, (endp - p), "\\x%02X", c); + } + } + *p = '\0'; + ASSERT(p < endp); + + return (int)(p - buf); +} +#endif /* defined(BCMDBG) */ + +u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate) +{ + return wlc_bmac_rate_shm_offset(wlc->hw, rate); +} + +/* Callback for device removed */ + +/* + * Attempts to queue a packet onto a multiple-precedence queue, + * if necessary evicting a lower precedence packet from the queue. + * + * 'prec' is the precedence number that has already been mapped + * from the packet priority. + * + * Returns true if packet consumed (queued), false if not. + */ +bool BCMFASTPATH +wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, int prec) +{ + return wlc_prec_enq_head(wlc, q, pkt, prec, false); +} + +bool BCMFASTPATH +wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, + int prec, bool head) +{ + struct sk_buff *p; + int eprec = -1; /* precedence to evict from */ + + /* Determine precedence from which to evict packet, if any */ + if (pktq_pfull(q, prec)) + eprec = prec; + else if (pktq_full(q)) { + p = pktq_peek_tail(q, &eprec); + ASSERT(p != NULL); + if (eprec > prec) { + WL_ERROR("%s: Failing: eprec %d > prec %d\n", + __func__, eprec, prec); + return false; + } + } + + /* Evict if needed */ + if (eprec >= 0) { + bool discard_oldest; + + /* Detect queueing to unconfigured precedence */ + ASSERT(!pktq_pempty(q, eprec)); + + discard_oldest = AC_BITMAP_TST(wlc->wme_dp, eprec); + + /* Refuse newer packet unless configured to discard oldest */ + if (eprec == prec && !discard_oldest) { + WL_ERROR("%s: No where to go, prec == %d\n", + __func__, prec); + return false; + } + + /* Evict packet according to discard policy */ + p = discard_oldest ? pktq_pdeq(q, eprec) : pktq_pdeq_tail(q, + eprec); + ASSERT(p != NULL); + + /* Increment wme stats */ + if (WME_ENAB(wlc->pub)) { + WLCNTINCR(wlc->pub->_wme_cnt-> + tx_failed[WME_PRIO2AC(p->priority)].packets); + WLCNTADD(wlc->pub->_wme_cnt-> + tx_failed[WME_PRIO2AC(p->priority)].bytes, + pkttotlen(wlc->osh, p)); + } + + ASSERT(0); + pkt_buf_free_skb(wlc->osh, p, true); + WLCNTINCR(wlc->pub->_cnt->txnobuf); + } + + /* Enqueue */ + if (head) + p = pktq_penq_head(q, prec, pkt); + else + p = pktq_penq(q, prec, pkt); + ASSERT(p != NULL); + + return true; +} + +void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, + uint prec) +{ + struct wlc_info *wlc = (struct wlc_info *) ctx; + wlc_txq_info_t *qi = wlc->active_queue; /* Check me */ + struct pktq *q = &qi->q; + int prio; + + prio = sdu->priority; + + ASSERT(pktq_max(q) >= wlc->pub->tunables->datahiwat); + + if (!wlc_prec_enq(wlc, q, sdu, prec)) { + if (!EDCF_ENAB(wlc->pub) + || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) + WL_ERROR("wl%d: wlc_txq_enq: txq overflow\n", + wlc->pub->unit); + + /* ASSERT(9 == 8); *//* XXX we might hit this condtion in case packet flooding from mac80211 stack */ + pkt_buf_free_skb(wlc->osh, sdu, true); + WLCNTINCR(wlc->pub->_cnt->txnobuf); + } + + /* Check if flow control needs to be turned on after enqueuing the packet + * Don't turn on flow control if EDCF is enabled. Driver would make the decision on what + * to drop instead of relying on stack to make the right decision + */ + if (!EDCF_ENAB(wlc->pub) + || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) { + if (pktq_len(q) >= wlc->pub->tunables->datahiwat) { + wlc_txflowcontrol(wlc, qi, ON, ALLPRIO); + } + } else if (wlc->pub->_priofc) { + if (pktq_plen(q, wlc_prio2prec_map[prio]) >= + wlc->pub->tunables->datahiwat) { + wlc_txflowcontrol(wlc, qi, ON, prio); + } + } +} + +bool BCMFASTPATH +wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, + struct ieee80211_hw *hw) +{ + u8 prio; + uint fifo; + void *pkt; + struct scb *scb = &global_scb; + struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data); + u16 type, fc; + + ASSERT(sdu); + + fc = ltoh16(d11_header->frame_control); + type = (fc & IEEE80211_FCTL_FTYPE); + + /* 802.11 standard requires management traffic to go at highest priority */ + prio = (type == IEEE80211_FTYPE_DATA ? sdu->priority : MAXPRIO); + fifo = prio2fifo[prio]; + + ASSERT((uint) skb_headroom(sdu) >= TXOFF); + ASSERT(!(sdu->cloned)); + ASSERT(!(sdu->next)); + ASSERT(!(sdu->prev)); + ASSERT(fifo < NFIFO); + + pkt = sdu; + if (unlikely + (wlc_d11hdrs_mac80211(wlc, hw, pkt, scb, 0, 1, fifo, 0, NULL, 0))) + return -EINVAL; + wlc_txq_enq(wlc, scb, pkt, WLC_PRIO_TO_PREC(prio)); + wlc_send_q(wlc, wlc->active_queue); + + WLCNTINCR(wlc->pub->_cnt->ieee_tx); + return 0; +} + +void BCMFASTPATH wlc_send_q(struct wlc_info *wlc, wlc_txq_info_t *qi) +{ + struct sk_buff *pkt[DOT11_MAXNUMFRAGS]; + int prec; + u16 prec_map; + int err = 0, i, count; + uint fifo; + struct pktq *q = &qi->q; + struct ieee80211_tx_info *tx_info; + + /* only do work for the active queue */ + if (qi != wlc->active_queue) + return; + + if (in_send_q) + return; + else + in_send_q = true; + + prec_map = wlc->tx_prec_map; + + /* Send all the enq'd pkts that we can. + * Dequeue packets with precedence with empty HW fifo only + */ + while (prec_map && (pkt[0] = pktq_mdeq(q, prec_map, &prec))) { + tx_info = IEEE80211_SKB_CB(pkt[0]); + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { + err = wlc_sendampdu(wlc->ampdu, qi, pkt, prec); + } else { + count = 1; + err = wlc_prep_pdu(wlc, pkt[0], &fifo); + if (!err) { + for (i = 0; i < count; i++) { + wlc_txfifo(wlc, fifo, pkt[i], true, 1); + } + } + } + + if (err == BCME_BUSY) { + pktq_penq_head(q, prec, pkt[0]); + /* If send failed due to any other reason than a change in + * HW FIFO condition, quit. Otherwise, read the new prec_map! + */ + if (prec_map == wlc->tx_prec_map) + break; + prec_map = wlc->tx_prec_map; + } + } + + /* Check if flow control needs to be turned off after sending the packet */ + if (!EDCF_ENAB(wlc->pub) + || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) { + if (wlc_txflowcontrol_prio_isset(wlc, qi, ALLPRIO) + && (pktq_len(q) < wlc->pub->tunables->datahiwat / 2)) { + wlc_txflowcontrol(wlc, qi, OFF, ALLPRIO); + } + } else if (wlc->pub->_priofc) { + int prio; + for (prio = MAXPRIO; prio >= 0; prio--) { + if (wlc_txflowcontrol_prio_isset(wlc, qi, prio) && + (pktq_plen(q, wlc_prio2prec_map[prio]) < + wlc->pub->tunables->datahiwat / 2)) { + wlc_txflowcontrol(wlc, qi, OFF, prio); + } + } + } + in_send_q = false; +} + +/* + * bcmc_fid_generate: + * Generate frame ID for a BCMC packet. The frag field is not used + * for MC frames so is used as part of the sequence number. + */ +static inline u16 +bcmc_fid_generate(struct wlc_info *wlc, wlc_bsscfg_t *bsscfg, d11txh_t *txh) +{ + u16 frameid; + + frameid = ltoh16(txh->TxFrameID) & ~(TXFID_SEQ_MASK | TXFID_QUEUE_MASK); + frameid |= + (((wlc-> + mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) | + TX_BCMC_FIFO; + + return frameid; +} + +void BCMFASTPATH +wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit, + s8 txpktpend) +{ + u16 frameid = INVALIDFID; + d11txh_t *txh; + + ASSERT(fifo < NFIFO); + txh = (d11txh_t *) (p->data); + + /* When a BC/MC frame is being committed to the BCMC fifo via DMA (NOT PIO), update + * ucode or BSS info as appropriate. + */ + if (fifo == TX_BCMC_FIFO) { + frameid = ltoh16(txh->TxFrameID); + + } + + if (WLC_WAR16165(wlc)) + wlc_war16165(wlc, true); + + + /* Bump up pending count for if not using rpc. If rpc is used, this will be handled + * in wlc_bmac_txfifo() + */ + if (commit) { + TXPKTPENDINC(wlc, fifo, txpktpend); + WL_TRACE("wlc_txfifo, pktpend inc %d to %d\n", + txpktpend, TXPKTPENDGET(wlc, fifo)); + } + + /* Commit BCMC sequence number in the SHM frame ID location */ + if (frameid != INVALIDFID) + BCMCFID(wlc, frameid); + + if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) { + WL_ERROR("wlc_txfifo: fatal, toss frames !!!\n"); + } +} + +static u16 +wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, uint length) +{ + u16 usec = 0; + uint mac_rate = RSPEC2RATE(rspec); + uint nsyms; + + if (IS_MCS(rspec)) { + /* not supported yet */ + ASSERT(0); + } else if (IS_OFDM(rspec)) { + /* nsyms = Ceiling(Nbits / (Nbits/sym)) + * + * Nbits = length * 8 + * Nbits/sym = Mbps * 4 = mac_rate * 2 + */ + nsyms = CEIL((length * 8), (mac_rate * 2)); + + /* usec = symbols * usec/symbol */ + usec = (u16) (nsyms * APHY_SYMBOL_TIME); + return usec; + } else { + switch (mac_rate) { + case WLC_RATE_1M: + usec = length << 3; + break; + case WLC_RATE_2M: + usec = length << 2; + break; + case WLC_RATE_5M5: + usec = (length << 4) / 11; + break; + case WLC_RATE_11M: + usec = (length << 3) / 11; + break; + default: + WL_ERROR("wl%d: wlc_compute_airtime: unsupported rspec 0x%x\n", + wlc->pub->unit, rspec); + ASSERT((const char *)"Bad phy_rate" == NULL); + break; + } + } + + return usec; +} + +void BCMFASTPATH +wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rspec, uint length, u8 *plcp) +{ + if (IS_MCS(rspec)) { + wlc_compute_mimo_plcp(rspec, length, plcp); + } else if (IS_OFDM(rspec)) { + wlc_compute_ofdm_plcp(rspec, length, plcp); + } else { + wlc_compute_cck_plcp(rspec, length, plcp); + } + return; +} + +/* Rate: 802.11 rate code, length: PSDU length in octets */ +static void wlc_compute_mimo_plcp(ratespec_t rspec, uint length, u8 *plcp) +{ + u8 mcs = (u8) (rspec & RSPEC_RATE_MASK); + ASSERT(IS_MCS(rspec)); + plcp[0] = mcs; + if (RSPEC_IS40MHZ(rspec) || (mcs == 32)) + plcp[0] |= MIMO_PLCP_40MHZ; + WLC_SET_MIMO_PLCP_LEN(plcp, length); + plcp[3] = RSPEC_MIMOPLCP3(rspec); /* rspec already holds this byte */ + plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */ + plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */ + plcp[5] = 0; +} + +/* Rate: 802.11 rate code, length: PSDU length in octets */ +static void BCMFASTPATH +wlc_compute_ofdm_plcp(ratespec_t rspec, u32 length, u8 *plcp) +{ + u8 rate_signal; + u32 tmp = 0; + int rate = RSPEC2RATE(rspec); + + ASSERT(IS_OFDM(rspec)); + + /* encode rate per 802.11a-1999 sec 17.3.4.1, with lsb transmitted first */ + rate_signal = rate_info[rate] & RATE_MASK; + ASSERT(rate_signal != 0); + + memset(plcp, 0, D11_PHY_HDR_LEN); + D11A_PHY_HDR_SRATE((ofdm_phy_hdr_t *) plcp, rate_signal); + + tmp = (length & 0xfff) << 5; + plcp[2] |= (tmp >> 16) & 0xff; + plcp[1] |= (tmp >> 8) & 0xff; + plcp[0] |= tmp & 0xff; + + return; +} + +/* + * Compute PLCP, but only requires actual rate and length of pkt. + * Rate is given in the driver standard multiple of 500 kbps. + * le is set for 11 Mbps rate if necessary. + * Broken out for PRQ. + */ + +static void wlc_cck_plcp_set(int rate_500, uint length, u8 *plcp) +{ + u16 usec = 0; + u8 le = 0; + + switch (rate_500) { + case WLC_RATE_1M: + usec = length << 3; + break; + case WLC_RATE_2M: + usec = length << 2; + break; + case WLC_RATE_5M5: + usec = (length << 4) / 11; + if ((length << 4) - (usec * 11) > 0) + usec++; + break; + case WLC_RATE_11M: + usec = (length << 3) / 11; + if ((length << 3) - (usec * 11) > 0) { + usec++; + if ((usec * 11) - (length << 3) >= 8) + le = D11B_PLCP_SIGNAL_LE; + } + break; + + default: + WL_ERROR("wlc_cck_plcp_set: unsupported rate %d\n", rate_500); + rate_500 = WLC_RATE_1M; + usec = length << 3; + break; + } + /* PLCP signal byte */ + plcp[0] = rate_500 * 5; /* r (500kbps) * 5 == r (100kbps) */ + /* PLCP service byte */ + plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED); + /* PLCP length u16, little endian */ + plcp[2] = usec & 0xff; + plcp[3] = (usec >> 8) & 0xff; + /* PLCP CRC16 */ + plcp[4] = 0; + plcp[5] = 0; +} + +/* Rate: 802.11 rate code, length: PSDU length in octets */ +static void wlc_compute_cck_plcp(ratespec_t rspec, uint length, u8 *plcp) +{ + int rate = RSPEC2RATE(rspec); + + ASSERT(IS_CCK(rspec)); + + wlc_cck_plcp_set(rate, length, plcp); +} + +/* wlc_compute_frame_dur() + * + * Calculate the 802.11 MAC header DUR field for MPDU + * DUR for a single frame = 1 SIFS + 1 ACK + * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time + * + * rate MPDU rate in unit of 500kbps + * next_frag_len next MPDU length in bytes + * preamble_type use short/GF or long/MM PLCP header + */ +static u16 BCMFASTPATH +wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type, + uint next_frag_len) +{ + u16 dur, sifs; + + sifs = SIFS(wlc->band); + + dur = sifs; + dur += (u16) wlc_calc_ack_time(wlc, rate, preamble_type); + + if (next_frag_len) { + /* Double the current DUR to get 2 SIFS + 2 ACKs */ + dur *= 2; + /* add another SIFS and the frag time */ + dur += sifs; + dur += + (u16) wlc_calc_frame_time(wlc, rate, preamble_type, + next_frag_len); + } + return dur; +} + +/* wlc_compute_rtscts_dur() + * + * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame + * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK + * DUR for CTS-TO-SELF w/ frame = 2 SIFS + next frame time + 1 ACK + * + * cts cts-to-self or rts/cts + * rts_rate rts or cts rate in unit of 500kbps + * rate next MPDU rate in unit of 500kbps + * frame_len next MPDU frame length in bytes + */ +u16 BCMFASTPATH +wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, ratespec_t rts_rate, + ratespec_t frame_rate, u8 rts_preamble_type, + u8 frame_preamble_type, uint frame_len, bool ba) +{ + u16 dur, sifs; + + sifs = SIFS(wlc->band); + + if (!cts_only) { /* RTS/CTS */ + dur = 3 * sifs; + dur += + (u16) wlc_calc_cts_time(wlc, rts_rate, + rts_preamble_type); + } else { /* CTS-TO-SELF */ + dur = 2 * sifs; + } + + dur += + (u16) wlc_calc_frame_time(wlc, frame_rate, frame_preamble_type, + frame_len); + if (ba) + dur += + (u16) wlc_calc_ba_time(wlc, frame_rate, + WLC_SHORT_PREAMBLE); + else + dur += + (u16) wlc_calc_ack_time(wlc, frame_rate, + frame_preamble_type); + return dur; +} + +static bool wlc_phy_rspec_check(struct wlc_info *wlc, u16 bw, ratespec_t rspec) +{ + if (IS_MCS(rspec)) { + uint mcs = rspec & RSPEC_RATE_MASK; + + if (mcs < 8) { + ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM); + } else if ((mcs >= 8) && (mcs <= 23)) { + ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SDM); + } else if (mcs == 32) { + ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM); + ASSERT(bw == PHY_TXC1_BW_40MHZ_DUP); + } + } else if (IS_OFDM(rspec)) { + ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_STBC); + } else { + ASSERT(IS_CCK(rspec)); + + ASSERT((bw == PHY_TXC1_BW_20MHZ) + || (bw == PHY_TXC1_BW_20MHZ_UP)); + ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SISO); + } + + return true; +} + +u16 BCMFASTPATH wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec) +{ + u16 phyctl1 = 0; + u16 bw; + + if (WLCISLCNPHY(wlc->band)) { + bw = PHY_TXC1_BW_20MHZ; + } else { + bw = RSPEC_GET_BW(rspec); + /* 10Mhz is not supported yet */ + if (bw < PHY_TXC1_BW_20MHZ) { + WL_ERROR("wlc_phytxctl1_calc: bw %d is not supported yet, set to 20L\n", + bw); + bw = PHY_TXC1_BW_20MHZ; + } + + wlc_phy_rspec_check(wlc, bw, rspec); + } + + if (IS_MCS(rspec)) { + uint mcs = rspec & RSPEC_RATE_MASK; + + /* bw, stf, coding-type is part of RSPEC_PHYTXBYTE2 returns */ + phyctl1 = RSPEC_PHYTXBYTE2(rspec); + /* set the upper byte of phyctl1 */ + phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8); + } else if (IS_CCK(rspec) && !WLCISLCNPHY(wlc->band) + && !WLCISSSLPNPHY(wlc->band)) { + /* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */ + /* Eventually MIMOPHY would also be converted to this format */ + /* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */ + phyctl1 = (bw | (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT)); + } else { /* legacy OFDM/CCK */ + s16 phycfg; + /* get the phyctl byte from rate phycfg table */ + phycfg = wlc_rate_legacy_phyctl(RSPEC2RATE(rspec)); + if (phycfg == -1) { + WL_ERROR("wlc_phytxctl1_calc: wrong legacy OFDM/CCK rate\n"); + ASSERT(0); + phycfg = 0; + } + /* set the upper byte of phyctl1 */ + phyctl1 = + (bw | (phycfg << 8) | + (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT)); + } + +#ifdef BCMDBG + /* phy clock must support 40Mhz if tx descriptor uses it */ + if ((phyctl1 & PHY_TXC1_BW_MASK) >= PHY_TXC1_BW_40MHZ) { + ASSERT(CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ); + ASSERT(wlc->chanspec == wlc_phy_chanspec_get(wlc->band->pi)); + } +#endif /* BCMDBG */ + return phyctl1; +} + +ratespec_t BCMFASTPATH +wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, bool use_rspec, + u16 mimo_ctlchbw) +{ + ratespec_t rts_rspec = 0; + + if (use_rspec) { + /* use frame rate as rts rate */ + rts_rspec = rspec; + + } else if (wlc->band->gmode && wlc->protection->_g && !IS_CCK(rspec)) { + /* Use 11Mbps as the g protection RTS target rate and fallback. + * Use the WLC_BASIC_RATE() lookup to find the best basic rate under the + * target in case 11 Mbps is not Basic. + * 6 and 9 Mbps are not usually selected by rate selection, but even + * if the OFDM rate we are protecting is 6 or 9 Mbps, 11 is more robust. + */ + rts_rspec = WLC_BASIC_RATE(wlc, WLC_RATE_11M); + } else { + /* calculate RTS rate and fallback rate based on the frame rate + * RTS must be sent at a basic rate since it is a + * control frame, sec 9.6 of 802.11 spec + */ + rts_rspec = WLC_BASIC_RATE(wlc, rspec); + } + + if (WLC_PHY_11N_CAP(wlc->band)) { + /* set rts txbw to correct side band */ + rts_rspec &= ~RSPEC_BW_MASK; + + /* if rspec/rspec_fallback is 40MHz, then send RTS on both 20MHz channel + * (DUP), otherwise send RTS on control channel + */ + if (RSPEC_IS40MHZ(rspec) && !IS_CCK(rts_rspec)) + rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT); + else + rts_rspec |= (mimo_ctlchbw << RSPEC_BW_SHIFT); + + /* pick siso/cdd as default for ofdm */ + if (IS_OFDM(rts_rspec)) { + rts_rspec &= ~RSPEC_STF_MASK; + rts_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT); + } + } + return rts_rspec; +} + +/* + * Add d11txh_t, cck_phy_hdr_t. + * + * 'p' data must start with 802.11 MAC header + * 'p' must allow enough bytes of local headers to be "pushed" onto the packet + * + * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes) + * + */ +static u16 BCMFASTPATH +wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, + struct sk_buff *p, struct scb *scb, uint frag, + uint nfrags, uint queue, uint next_frag_len, + wsec_key_t *key, ratespec_t rspec_override) +{ + struct ieee80211_hdr *h; + d11txh_t *txh; + u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN]; + struct osl_info *osh; + int len, phylen, rts_phylen; + u16 fc, type, frameid, mch, phyctl, xfts, mainrates; + u16 seq = 0, mcl = 0, status = 0; + ratespec_t rspec[2] = { WLC_RATE_1M, WLC_RATE_1M }, rts_rspec[2] = { + WLC_RATE_1M, WLC_RATE_1M}; + bool use_rts = false; + bool use_cts = false; + bool use_rifs = false; + bool short_preamble[2] = { false, false }; + u8 preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE }; + u8 rts_preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE }; + u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN]; + struct ieee80211_rts *rts = NULL; + bool qos; + uint ac; + u32 rate_val[2]; + bool hwtkmic = false; + u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; +#ifdef WLANTSEL +#define ANTCFG_NONE 0xFF + u8 antcfg = ANTCFG_NONE; + u8 fbantcfg = ANTCFG_NONE; +#endif + uint phyctl1_stf = 0; + u16 durid = 0; + struct ieee80211_tx_rate *txrate[2]; + int k; + struct ieee80211_tx_info *tx_info; + bool is_mcs[2]; + u16 mimo_txbw; + u8 mimo_preamble_type; + + frameid = 0; + + ASSERT(queue < NFIFO); + + osh = wlc->osh; + + /* locate 802.11 MAC header */ + h = (struct ieee80211_hdr *)(p->data); + fc = ltoh16(h->frame_control); + type = (fc & IEEE80211_FCTL_FTYPE); + + qos = (type == IEEE80211_FTYPE_DATA && + FC_SUBTYPE_ANY_QOS(fc)); + + /* compute length of frame in bytes for use in PLCP computations */ + len = pkttotlen(osh, p); + phylen = len + FCS_LEN; + + /* If WEP enabled, add room in phylen for the additional bytes of + * ICV which MAC generates. We do NOT add the additional bytes to + * the packet itself, thus phylen = packet length + ICV_LEN + FCS_LEN + * in this case + */ + if (key) { + phylen += key->icv_len; + } + + /* Get tx_info */ + tx_info = IEEE80211_SKB_CB(p); + ASSERT(tx_info); + + /* add PLCP */ + plcp = skb_push(p, D11_PHY_HDR_LEN); + + /* add Broadcom tx descriptor header */ + txh = (d11txh_t *) skb_push(p, D11_TXH_LEN); + memset((char *)txh, 0, D11_TXH_LEN); + + /* setup frameid */ + if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { + /* non-AP STA should never use BCMC queue */ + ASSERT(queue != TX_BCMC_FIFO); + if (queue == TX_BCMC_FIFO) { + WL_ERROR("wl%d: %s: ASSERT queue == TX_BCMC!\n", + WLCWLUNIT(wlc), __func__); + frameid = bcmc_fid_generate(wlc, NULL, txh); + } else { + /* Increment the counter for first fragment */ + if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) { + SCB_SEQNUM(scb, p->priority)++; + } + + /* extract fragment number from frame first */ + seq = ltoh16(seq) & FRAGNUM_MASK; + seq |= (SCB_SEQNUM(scb, p->priority) << SEQNUM_SHIFT); + h->seq_ctrl = htol16(seq); + + frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) | + (queue & TXFID_QUEUE_MASK); + } + } + frameid |= queue & TXFID_QUEUE_MASK; + + /* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */ + if (SCB_PS(scb) || ((fc & FC_KIND_MASK) == FC_BEACON)) + mcl |= TXC_IGNOREPMQ; + + ASSERT(hw->max_rates <= IEEE80211_TX_MAX_RATES); + ASSERT(hw->max_rates == 2); + + txrate[0] = tx_info->control.rates; + txrate[1] = txrate[0] + 1; + + ASSERT(txrate[0]->idx >= 0); + /* if rate control algorithm didn't give us a fallback rate, use the primary rate */ + if (txrate[1]->idx < 0) { + txrate[1] = txrate[0]; + } + + for (k = 0; k < hw->max_rates; k++) { + is_mcs[k] = + txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false; + if (!is_mcs[k]) { + ASSERT(!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)); + if ((txrate[k]->idx >= 0) + && (txrate[k]->idx < + hw->wiphy->bands[tx_info->band]->n_bitrates)) { + rate_val[k] = + hw->wiphy->bands[tx_info->band]-> + bitrates[txrate[k]->idx].hw_value; + short_preamble[k] = + txrate[k]-> + flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ? + true : false; + } else { + ASSERT((txrate[k]->idx >= 0) && + (txrate[k]->idx < + hw->wiphy->bands[tx_info->band]-> + n_bitrates)); + rate_val[k] = WLC_RATE_1M; + } + } else { + rate_val[k] = txrate[k]->idx; + } + /* Currently only support same setting for primay and fallback rates. + * Unify flags for each rate into a single value for the frame + */ + use_rts |= + txrate[k]-> + flags & IEEE80211_TX_RC_USE_RTS_CTS ? true : false; + use_cts |= + txrate[k]-> + flags & IEEE80211_TX_RC_USE_CTS_PROTECT ? true : false; + + if (is_mcs[k]) + rate_val[k] |= NRATE_MCS_INUSE; + + rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band, rate_val[k]); + + /* (1) RATE: determine and validate primary rate and fallback rates */ + if (!RSPEC_ACTIVE(rspec[k])) { + ASSERT(RSPEC_ACTIVE(rspec[k])); + rspec[k] = WLC_RATE_1M; + } else { + if (WLANTSEL_ENAB(wlc) && + !is_multicast_ether_addr(h->addr1)) { + /* set tx antenna config */ + wlc_antsel_antcfg_get(wlc->asi, false, false, 0, + 0, &antcfg, &fbantcfg); + } + } + } + + phyctl1_stf = wlc->stf->ss_opmode; + + if (N_ENAB(wlc->pub)) { + for (k = 0; k < hw->max_rates; k++) { + /* apply siso/cdd to single stream mcs's or ofdm if rspec is auto selected */ + if (((IS_MCS(rspec[k]) && + IS_SINGLE_STREAM(rspec[k] & RSPEC_RATE_MASK)) || + IS_OFDM(rspec[k])) + && ((rspec[k] & RSPEC_OVERRIDE_MCS_ONLY) + || !(rspec[k] & RSPEC_OVERRIDE))) { + rspec[k] &= ~(RSPEC_STF_MASK | RSPEC_STC_MASK); + + /* For SISO MCS use STBC if possible */ + if (IS_MCS(rspec[k]) + && WLC_STF_SS_STBC_TX(wlc, scb)) { + u8 stc; + + ASSERT(WLC_STBC_CAP_PHY(wlc)); + stc = 1; /* Nss for single stream is always 1 */ + rspec[k] |= + (PHY_TXC1_MODE_STBC << + RSPEC_STF_SHIFT) | (stc << + RSPEC_STC_SHIFT); + } else + rspec[k] |= + (phyctl1_stf << RSPEC_STF_SHIFT); + } + + /* Is the phy configured to use 40MHZ frames? If so then pick the desired txbw */ + if (CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ) { + /* default txbw is 20in40 SB */ + mimo_ctlchbw = mimo_txbw = + CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC) + ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; + + if (IS_MCS(rspec[k])) { + /* mcs 32 must be 40b/w DUP */ + if ((rspec[k] & RSPEC_RATE_MASK) == 32) { + mimo_txbw = + PHY_TXC1_BW_40MHZ_DUP; + /* use override */ + } else if (wlc->mimo_40txbw != AUTO) + mimo_txbw = wlc->mimo_40txbw; + /* else check if dst is using 40 Mhz */ + else if (scb->flags & SCB_IS40) + mimo_txbw = PHY_TXC1_BW_40MHZ; + } else if (IS_OFDM(rspec[k])) { + if (wlc->ofdm_40txbw != AUTO) + mimo_txbw = wlc->ofdm_40txbw; + } else { + ASSERT(IS_CCK(rspec[k])); + if (wlc->cck_40txbw != AUTO) + mimo_txbw = wlc->cck_40txbw; + } + } else { + /* mcs32 is 40 b/w only. + * This is possible for probe packets on a STA during SCAN + */ + if ((rspec[k] & RSPEC_RATE_MASK) == 32) { + /* mcs 0 */ + rspec[k] = RSPEC_MIMORATE; + } + mimo_txbw = PHY_TXC1_BW_20MHZ; + } + + /* Set channel width */ + rspec[k] &= ~RSPEC_BW_MASK; + if ((k == 0) || ((k > 0) && IS_MCS(rspec[k]))) + rspec[k] |= (mimo_txbw << RSPEC_BW_SHIFT); + else + rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT); + + /* Set Short GI */ +#ifdef NOSGIYET + if (IS_MCS(rspec[k]) + && (txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI)) + rspec[k] |= RSPEC_SHORT_GI; + else if (!(txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI)) + rspec[k] &= ~RSPEC_SHORT_GI; +#else + rspec[k] &= ~RSPEC_SHORT_GI; +#endif + + mimo_preamble_type = WLC_MM_PREAMBLE; + if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD) + mimo_preamble_type = WLC_GF_PREAMBLE; + + if ((txrate[k]->flags & IEEE80211_TX_RC_MCS) + && (!IS_MCS(rspec[k]))) { + WL_ERROR("wl%d: %s: IEEE80211_TX_RC_MCS != IS_MCS(rspec)\n", + WLCWLUNIT(wlc), __func__); + ASSERT(0 && "Rate mismatch"); + } + + if (IS_MCS(rspec[k])) { + preamble_type[k] = mimo_preamble_type; + + /* if SGI is selected, then forced mm for single stream */ + if ((rspec[k] & RSPEC_SHORT_GI) + && IS_SINGLE_STREAM(rspec[k] & + RSPEC_RATE_MASK)) { + preamble_type[k] = WLC_MM_PREAMBLE; + } + } + + /* mimo bw field MUST now be valid in the rspec (it affects duration calculations) */ + ASSERT(VALID_RATE_DBG(wlc, rspec[0])); + + /* should be better conditionalized */ + if (!IS_MCS(rspec[0]) + && (tx_info->control.rates[0]. + flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)) + preamble_type[k] = WLC_SHORT_PREAMBLE; + + ASSERT(!IS_MCS(rspec[0]) + || WLC_IS_MIMO_PREAMBLE(preamble_type[k])); + } + } else { + for (k = 0; k < hw->max_rates; k++) { + /* Set ctrlchbw as 20Mhz */ + ASSERT(!IS_MCS(rspec[k])); + rspec[k] &= ~RSPEC_BW_MASK; + rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT); + + /* for nphy, stf of ofdm frames must follow policies */ + if (WLCISNPHY(wlc->band) && IS_OFDM(rspec[k])) { + rspec[k] &= ~RSPEC_STF_MASK; + rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT; + } + } + } + + /* Reset these for use with AMPDU's */ + txrate[0]->count = 0; + txrate[1]->count = 0; + + /* (3) PLCP: determine PLCP header and MAC duration, fill d11txh_t */ + wlc_compute_plcp(wlc, rspec[0], phylen, plcp); + wlc_compute_plcp(wlc, rspec[1], phylen, plcp_fallback); + bcopy(plcp_fallback, (char *)&txh->FragPLCPFallback, + sizeof(txh->FragPLCPFallback)); + + /* Length field now put in CCK FBR CRC field */ + if (IS_CCK(rspec[1])) { + txh->FragPLCPFallback[4] = phylen & 0xff; + txh->FragPLCPFallback[5] = (phylen & 0xff00) >> 8; + } + + /* MIMO-RATE: need validation ?? */ + mainrates = + IS_OFDM(rspec[0]) ? D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) plcp) : + plcp[0]; + + /* DUR field for main rate */ + if ((fc != FC_PS_POLL) && + !is_multicast_ether_addr(h->addr1) && !use_rifs) { + durid = + wlc_compute_frame_dur(wlc, rspec[0], preamble_type[0], + next_frag_len); + h->duration_id = htol16(durid); + } else if (use_rifs) { + /* NAV protect to end of next max packet size */ + durid = + (u16) wlc_calc_frame_time(wlc, rspec[0], + preamble_type[0], + DOT11_MAX_FRAG_LEN); + durid += RIFS_11N_TIME; + h->duration_id = htol16(durid); + } + + /* DUR field for fallback rate */ + if (fc == FC_PS_POLL) + txh->FragDurFallback = h->duration_id; + else if (is_multicast_ether_addr(h->addr1) || use_rifs) + txh->FragDurFallback = 0; + else { + durid = wlc_compute_frame_dur(wlc, rspec[1], + preamble_type[1], next_frag_len); + txh->FragDurFallback = htol16(durid); + } + + /* (4) MAC-HDR: MacTxControlLow */ + if (frag == 0) + mcl |= TXC_STARTMSDU; + + if (!is_multicast_ether_addr(h->addr1)) + mcl |= TXC_IMMEDACK; + + if (BAND_5G(wlc->band->bandtype)) + mcl |= TXC_FREQBAND_5G; + + if (CHSPEC_IS40(WLC_BAND_PI_RADIO_CHANSPEC)) + mcl |= TXC_BW_40; + + /* set AMIC bit if using hardware TKIP MIC */ + if (hwtkmic) + mcl |= TXC_AMIC; + + txh->MacTxControlLow = htol16(mcl); + + /* MacTxControlHigh */ + mch = 0; + + /* Set fallback rate preamble type */ + if ((preamble_type[1] == WLC_SHORT_PREAMBLE) || + (preamble_type[1] == WLC_GF_PREAMBLE)) { + ASSERT((preamble_type[1] == WLC_GF_PREAMBLE) || + (!IS_MCS(rspec[1]))); + if (RSPEC2RATE(rspec[1]) != WLC_RATE_1M) + mch |= TXC_PREAMBLE_DATA_FB_SHORT; + } + + /* MacFrameControl */ + bcopy((char *)&h->frame_control, (char *)&txh->MacFrameControl, + sizeof(u16)); + txh->TxFesTimeNormal = htol16(0); + + txh->TxFesTimeFallback = htol16(0); + + /* TxFrameRA */ + bcopy((char *)&h->addr1, (char *)&txh->TxFrameRA, ETH_ALEN); + + /* TxFrameID */ + txh->TxFrameID = htol16(frameid); + + /* TxStatus, Note the case of recreating the first frag of a suppressed frame + * then we may need to reset the retry cnt's via the status reg + */ + txh->TxStatus = htol16(status); + + if (D11REV_GE(wlc->pub->corerev, 16)) { + /* extra fields for ucode AMPDU aggregation, the new fields are added to + * the END of previous structure so that it's compatible in driver. + * In old rev ucode, these fields should be ignored + */ + txh->MaxNMpdus = htol16(0); + txh->MaxABytes_MRT = htol16(0); + txh->MaxABytes_FBR = htol16(0); + txh->MinMBytes = htol16(0); + } + + /* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration, furnish d11txh_t */ + /* RTS PLCP header and RTS frame */ + if (use_rts || use_cts) { + if (use_rts && use_cts) + use_cts = false; + + for (k = 0; k < 2; k++) { + rts_rspec[k] = wlc_rspec_to_rts_rspec(wlc, rspec[k], + false, + mimo_ctlchbw); + } + + if (!IS_OFDM(rts_rspec[0]) && + !((RSPEC2RATE(rts_rspec[0]) == WLC_RATE_1M) || + (wlc->PLCPHdr_override == WLC_PLCP_LONG))) { + rts_preamble_type[0] = WLC_SHORT_PREAMBLE; + mch |= TXC_PREAMBLE_RTS_MAIN_SHORT; + } + + if (!IS_OFDM(rts_rspec[1]) && + !((RSPEC2RATE(rts_rspec[1]) == WLC_RATE_1M) || + (wlc->PLCPHdr_override == WLC_PLCP_LONG))) { + rts_preamble_type[1] = WLC_SHORT_PREAMBLE; + mch |= TXC_PREAMBLE_RTS_FB_SHORT; + } + + /* RTS/CTS additions to MacTxControlLow */ + if (use_cts) { + txh->MacTxControlLow |= htol16(TXC_SENDCTS); + } else { + txh->MacTxControlLow |= htol16(TXC_SENDRTS); + txh->MacTxControlLow |= htol16(TXC_LONGFRAME); + } + + /* RTS PLCP header */ + ASSERT(IS_ALIGNED((unsigned long)txh->RTSPhyHeader, sizeof(u16))); + rts_plcp = txh->RTSPhyHeader; + if (use_cts) + rts_phylen = DOT11_CTS_LEN + FCS_LEN; + else + rts_phylen = DOT11_RTS_LEN + FCS_LEN; + + wlc_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp); + + /* fallback rate version of RTS PLCP header */ + wlc_compute_plcp(wlc, rts_rspec[1], rts_phylen, + rts_plcp_fallback); + bcopy(rts_plcp_fallback, (char *)&txh->RTSPLCPFallback, + sizeof(txh->RTSPLCPFallback)); + + /* RTS frame fields... */ + rts = (struct ieee80211_rts *)&txh->rts_frame; + + durid = wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec[0], + rspec[0], rts_preamble_type[0], + preamble_type[0], phylen, false); + rts->duration = htol16(durid); + /* fallback rate version of RTS DUR field */ + durid = wlc_compute_rtscts_dur(wlc, use_cts, + rts_rspec[1], rspec[1], + rts_preamble_type[1], + preamble_type[1], phylen, false); + txh->RTSDurFallback = htol16(durid); + + if (use_cts) { + rts->frame_control = htol16(FC_CTS); + bcopy((char *)&h->addr2, (char *)&rts->ra, ETH_ALEN); + } else { + rts->frame_control = htol16((u16) FC_RTS); + bcopy((char *)&h->addr1, (char *)&rts->ra, + 2 * ETH_ALEN); + } + + /* mainrate + * low 8 bits: main frag rate/mcs, + * high 8 bits: rts/cts rate/mcs + */ + mainrates |= (IS_OFDM(rts_rspec[0]) ? + D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) rts_plcp) : + rts_plcp[0]) << 8; + } else { + memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN); + memset((char *)&txh->rts_frame, 0, + sizeof(struct ieee80211_rts)); + memset((char *)txh->RTSPLCPFallback, 0, + sizeof(txh->RTSPLCPFallback)); + txh->RTSDurFallback = 0; + } + +#ifdef SUPPORT_40MHZ + /* add null delimiter count */ + if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && IS_MCS(rspec)) { + txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = + wlc_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen); + } +#endif + + /* Now that RTS/RTS FB preamble types are updated, write the final value */ + txh->MacTxControlHigh = htol16(mch); + + /* MainRates (both the rts and frag plcp rates have been calculated now) */ + txh->MainRates = htol16(mainrates); + + /* XtraFrameTypes */ + xfts = FRAMETYPE(rspec[1], wlc->mimoft); + xfts |= (FRAMETYPE(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT); + xfts |= (FRAMETYPE(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT); + xfts |= + CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC) << XFTS_CHANNEL_SHIFT; + txh->XtraFrameTypes = htol16(xfts); + + /* PhyTxControlWord */ + phyctl = FRAMETYPE(rspec[0], wlc->mimoft); + if ((preamble_type[0] == WLC_SHORT_PREAMBLE) || + (preamble_type[0] == WLC_GF_PREAMBLE)) { + ASSERT((preamble_type[0] == WLC_GF_PREAMBLE) + || !IS_MCS(rspec[0])); + if (RSPEC2RATE(rspec[0]) != WLC_RATE_1M) + phyctl |= PHY_TXC_SHORT_HDR; + WLCNTINCR(wlc->pub->_cnt->txprshort); + } + + /* phytxant is properly bit shifted */ + phyctl |= wlc_stf_d11hdrs_phyctl_txant(wlc, rspec[0]); + txh->PhyTxControlWord = htol16(phyctl); + + /* PhyTxControlWord_1 */ + if (WLC_PHY_11N_CAP(wlc->band)) { + u16 phyctl1 = 0; + + phyctl1 = wlc_phytxctl1_calc(wlc, rspec[0]); + txh->PhyTxControlWord_1 = htol16(phyctl1); + phyctl1 = wlc_phytxctl1_calc(wlc, rspec[1]); + txh->PhyTxControlWord_1_Fbr = htol16(phyctl1); + + if (use_rts || use_cts) { + phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[0]); + txh->PhyTxControlWord_1_Rts = htol16(phyctl1); + phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[1]); + txh->PhyTxControlWord_1_FbrRts = htol16(phyctl1); + } + + /* + * For mcs frames, if mixedmode(overloaded with long preamble) is going to be set, + * fill in non-zero MModeLen and/or MModeFbrLen + * it will be unnecessary if they are separated + */ + if (IS_MCS(rspec[0]) && (preamble_type[0] == WLC_MM_PREAMBLE)) { + u16 mmodelen = + wlc_calc_lsig_len(wlc, rspec[0], phylen); + txh->MModeLen = htol16(mmodelen); + } + + if (IS_MCS(rspec[1]) && (preamble_type[1] == WLC_MM_PREAMBLE)) { + u16 mmodefbrlen = + wlc_calc_lsig_len(wlc, rspec[1], phylen); + txh->MModeFbrLen = htol16(mmodefbrlen); + } + } + + if (IS_MCS(rspec[0])) + ASSERT(IS_MCS(rspec[1])); + + ASSERT(!IS_MCS(rspec[0]) || + ((preamble_type[0] == WLC_MM_PREAMBLE) == (txh->MModeLen != 0))); + ASSERT(!IS_MCS(rspec[1]) || + ((preamble_type[1] == WLC_MM_PREAMBLE) == + (txh->MModeFbrLen != 0))); + + ac = wme_fifo2ac[queue]; + if (SCB_WME(scb) && qos && wlc->edcf_txop[ac]) { + uint frag_dur, dur, dur_fallback; + + ASSERT(!is_multicast_ether_addr(h->addr1)); + + /* WME: Update TXOP threshold */ + if ((!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) && (frag == 0)) { + frag_dur = + wlc_calc_frame_time(wlc, rspec[0], preamble_type[0], + phylen); + + if (rts) { + /* 1 RTS or CTS-to-self frame */ + dur = + wlc_calc_cts_time(wlc, rts_rspec[0], + rts_preamble_type[0]); + dur_fallback = + wlc_calc_cts_time(wlc, rts_rspec[1], + rts_preamble_type[1]); + /* (SIFS + CTS) + SIFS + frame + SIFS + ACK */ + dur += ltoh16(rts->duration); + dur_fallback += ltoh16(txh->RTSDurFallback); + } else if (use_rifs) { + dur = frag_dur; + dur_fallback = 0; + } else { + /* frame + SIFS + ACK */ + dur = frag_dur; + dur += + wlc_compute_frame_dur(wlc, rspec[0], + preamble_type[0], 0); + + dur_fallback = + wlc_calc_frame_time(wlc, rspec[1], + preamble_type[1], + phylen); + dur_fallback += + wlc_compute_frame_dur(wlc, rspec[1], + preamble_type[1], 0); + } + /* NEED to set TxFesTimeNormal (hard) */ + txh->TxFesTimeNormal = htol16((u16) dur); + /* NEED to set fallback rate version of TxFesTimeNormal (hard) */ + txh->TxFesTimeFallback = htol16((u16) dur_fallback); + + /* update txop byte threshold (txop minus intraframe overhead) */ + if (wlc->edcf_txop[ac] >= (dur - frag_dur)) { + { + uint newfragthresh; + + newfragthresh = + wlc_calc_frame_len(wlc, rspec[0], + preamble_type[0], + (wlc-> + edcf_txop[ac] - + (dur - + frag_dur))); + /* range bound the fragthreshold */ + if (newfragthresh < DOT11_MIN_FRAG_LEN) + newfragthresh = + DOT11_MIN_FRAG_LEN; + else if (newfragthresh > + wlc->usr_fragthresh) + newfragthresh = + wlc->usr_fragthresh; + /* update the fragthresh and do txc update */ + if (wlc->fragthresh[queue] != + (u16) newfragthresh) { + wlc->fragthresh[queue] = + (u16) newfragthresh; + } + } + } else + WL_ERROR("wl%d: %s txop invalid for rate %d\n", + wlc->pub->unit, fifo_names[queue], + RSPEC2RATE(rspec[0])); + + if (dur > wlc->edcf_txop[ac]) + WL_ERROR("wl%d: %s: %s txop exceeded phylen %d/%d dur %d/%d\n", + wlc->pub->unit, __func__, + fifo_names[queue], + phylen, wlc->fragthresh[queue], + dur, wlc->edcf_txop[ac]); + } + } + + return 0; +} + +void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs) +{ + wlc_bsscfg_t *cfg = wlc->cfg; + + WLCNTINCR(wlc->pub->_cnt->tbtt); + + if (BSSCFG_STA(cfg)) { + /* run watchdog here if the watchdog timer is not armed */ + if (WLC_WATCHDOG_TBTT(wlc)) { + u32 cur, delta; + if (wlc->WDarmed) { + wl_del_timer(wlc->wl, wlc->wdtimer); + wlc->WDarmed = false; + } + + cur = OSL_SYSUPTIME(); + delta = cur > wlc->WDlast ? cur - wlc->WDlast : + (u32) ~0 - wlc->WDlast + cur + 1; + if (delta >= TIMER_INTERVAL_WATCHDOG) { + wlc_watchdog((void *)wlc); + wlc->WDlast = cur; + } + + wl_add_timer(wlc->wl, wlc->wdtimer, + wlc_watchdog_backup_bi(wlc), true); + wlc->WDarmed = true; + } + } + + if (!cfg->BSS) { + /* DirFrmQ is now valid...defer setting until end of ATIM window */ + wlc->qvalid |= MCMD_DIRFRMQVAL; + } +} + +/* GP timer is a freerunning 32 bit counter, decrements at 1 us rate */ +void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us) +{ + ASSERT(wlc->pub->corerev >= 3); /* no gptimer in earlier revs */ + W_REG(wlc->osh, &wlc->regs->gptimer, us); +} + +void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc) +{ + ASSERT(wlc->pub->corerev >= 3); + W_REG(wlc->osh, &wlc->regs->gptimer, 0); +} + +static void wlc_hwtimer_gptimer_cb(struct wlc_info *wlc) +{ + /* when interrupt is generated, the counter is loaded with last value + * written and continue to decrement. So it has to be cleaned first + */ + W_REG(wlc->osh, &wlc->regs->gptimer, 0); +} + +/* + * This fn has all the high level dpc processing from wlc_dpc. + * POLICY: no macinstatus change, no bounding loop. + * All dpc bounding should be handled in BMAC dpc, like txstatus and rxint + */ +void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus) +{ + d11regs_t *regs = wlc->regs; +#ifdef BCMDBG + char flagstr[128]; + static const bcm_bit_desc_t int_flags[] = { + {MI_MACSSPNDD, "MACSSPNDD"}, + {MI_BCNTPL, "BCNTPL"}, + {MI_TBTT, "TBTT"}, + {MI_BCNSUCCESS, "BCNSUCCESS"}, + {MI_BCNCANCLD, "BCNCANCLD"}, + {MI_ATIMWINEND, "ATIMWINEND"}, + {MI_PMQ, "PMQ"}, + {MI_NSPECGEN_0, "NSPECGEN_0"}, + {MI_NSPECGEN_1, "NSPECGEN_1"}, + {MI_MACTXERR, "MACTXERR"}, + {MI_NSPECGEN_3, "NSPECGEN_3"}, + {MI_PHYTXERR, "PHYTXERR"}, + {MI_PME, "PME"}, + {MI_GP0, "GP0"}, + {MI_GP1, "GP1"}, + {MI_DMAINT, "DMAINT"}, + {MI_TXSTOP, "TXSTOP"}, + {MI_CCA, "CCA"}, + {MI_BG_NOISE, "BG_NOISE"}, + {MI_DTIM_TBTT, "DTIM_TBTT"}, + {MI_PRQ, "PRQ"}, + {MI_PWRUP, "PWRUP"}, + {MI_RFDISABLE, "RFDISABLE"}, + {MI_TFS, "TFS"}, + {MI_PHYCHANGED, "PHYCHANGED"}, + {MI_TO, "TO"}, + {0, NULL} + }; + + if (macintstatus & ~(MI_TBTT | MI_TXSTOP)) { + bcm_format_flags(int_flags, macintstatus, flagstr, + sizeof(flagstr)); + WL_TRACE("wl%d: macintstatus 0x%x %s\n", + wlc->pub->unit, macintstatus, flagstr); + } +#endif /* BCMDBG */ + + if (macintstatus & MI_PRQ) { + /* Process probe request FIFO */ + ASSERT(0 && "PRQ Interrupt in non-MBSS"); + } + + /* TBTT indication */ + /* ucode only gives either TBTT or DTIM_TBTT, not both */ + if (macintstatus & (MI_TBTT | MI_DTIM_TBTT)) + wlc_tbtt(wlc, regs); + + if (macintstatus & MI_GP0) { + WL_ERROR("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", + wlc->pub->unit, wlc->pub->now); + + printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", + __func__, wlc->pub->sih->chip, + wlc->pub->sih->chiprev); + + WLCNTINCR(wlc->pub->_cnt->psmwds); + + /* big hammer */ + wl_init(wlc->wl); + } + + /* gptimer timeout */ + if (macintstatus & MI_TO) { + wlc_hwtimer_gptimer_cb(wlc); + } + + if (macintstatus & MI_RFDISABLE) { + WL_ERROR("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n", + wlc->pub->unit, + R_REG(wlc->osh, ®s->phydebug) & PDBG_RFD); + /* delay the cleanup to wl_down in IBSS case */ + if ((R_REG(wlc->osh, ®s->phydebug) & PDBG_RFD)) { + int idx; + wlc_bsscfg_t *bsscfg; + FOREACH_BSS(wlc, idx, bsscfg) { + if (!BSSCFG_STA(bsscfg) || !bsscfg->enable + || !bsscfg->BSS) + continue; + WL_ERROR("wl%d: wlc_dpc: rfdisable -> wlc_bsscfg_disable()\n", + wlc->pub->unit); + } + } + } + + /* send any enq'd tx packets. Just makes sure to jump start tx */ + if (!pktq_empty(&wlc->active_queue->q)) + wlc_send_q(wlc, wlc->active_queue); + + ASSERT(wlc_ps_check(wlc)); +} + +static void *wlc_15420war(struct wlc_info *wlc, uint queue) +{ + struct hnddma_pub *di; + void *p; + + ASSERT(queue < NFIFO); + + if ((D11REV_IS(wlc->pub->corerev, 4)) + || (D11REV_GT(wlc->pub->corerev, 6))) + return NULL; + + di = wlc->hw->di[queue]; + ASSERT(di != NULL); + + /* get next packet, ignoring XmtStatus.Curr */ + p = dma_getnexttxp(di, HNDDMA_RANGE_ALL); + + /* sw block tx dma */ + dma_txblock(di); + + /* if tx ring is now empty, reset and re-init the tx dma channel */ + if (dma_txactive(wlc->hw->di[queue]) == 0) { + WLCNTINCR(wlc->pub->_cnt->txdmawar); + if (!dma_txreset(di)) + WL_ERROR("wl%d: %s: dma_txreset[%d]: cannot stop dma\n", + wlc->pub->unit, __func__, queue); + dma_txinit(di); + } + return p; +} + +static void wlc_war16165(struct wlc_info *wlc, bool tx) +{ + if (tx) { + /* the post-increment is used in STAY_AWAKE macro */ + if (wlc->txpend16165war++ == 0) + wlc_set_ps_ctrl(wlc); + } else { + wlc->txpend16165war--; + if (wlc->txpend16165war == 0) + wlc_set_ps_ctrl(wlc); + } +} + +/* process an individual tx_status_t */ +/* WLC_HIGH_API */ +bool BCMFASTPATH +wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) +{ + struct sk_buff *p; + uint queue; + d11txh_t *txh; + struct scb *scb = NULL; + bool free_pdu; + struct osl_info *osh; + int tx_rts, tx_frame_count, tx_rts_count; + uint totlen, supr_status; + bool lastframe; + struct ieee80211_hdr *h; + u16 fc; + u16 mcl; + struct ieee80211_tx_info *tx_info; + struct ieee80211_tx_rate *txrate; + int i; + + (void)(frm_tx2); /* Compiler reference to avoid unused variable warning */ + + /* discard intermediate indications for ucode with one legitimate case: + * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent + * tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts + * transmission count) + */ + if (!(txs->status & TX_STATUS_AMPDU) + && (txs->status & TX_STATUS_INTERMEDIATE)) { + WLCNTADD(wlc->pub->_cnt->txnoack, + ((txs-> + status & TX_STATUS_FRM_RTX_MASK) >> + TX_STATUS_FRM_RTX_SHIFT)); + WL_ERROR("%s: INTERMEDIATE but not AMPDU\n", __func__); + return false; + } + + osh = wlc->osh; + queue = txs->frameid & TXFID_QUEUE_MASK; + ASSERT(queue < NFIFO); + if (queue >= NFIFO) { + p = NULL; + goto fatal; + } + + p = GETNEXTTXP(wlc, queue); + if (WLC_WAR16165(wlc)) + wlc_war16165(wlc, false); + if (p == NULL) + p = wlc_15420war(wlc, queue); + ASSERT(p != NULL); + if (p == NULL) + goto fatal; + + txh = (d11txh_t *) (p->data); + mcl = ltoh16(txh->MacTxControlLow); + + if (txs->phyerr) { + WL_ERROR("phyerr 0x%x, rate 0x%x\n", + txs->phyerr, txh->MainRates); + wlc_print_txdesc(txh); + wlc_print_txstatus(txs); + } + + ASSERT(txs->frameid == htol16(txh->TxFrameID)); + if (txs->frameid != htol16(txh->TxFrameID)) + goto fatal; + + tx_info = IEEE80211_SKB_CB(p); + h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); + fc = ltoh16(h->frame_control); + + scb = (struct scb *)tx_info->control.sta->drv_priv; + + if (N_ENAB(wlc->pub)) { + u8 *plcp = (u8 *) (txh + 1); + if (PLCP3_ISSGI(plcp[3])) + WLCNTINCR(wlc->pub->_cnt->txmpdu_sgi); + if (PLCP3_ISSTBC(plcp[3])) + WLCNTINCR(wlc->pub->_cnt->txmpdu_stbc); + } + + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { + ASSERT((mcl & TXC_AMPDU_MASK) != TXC_AMPDU_NONE); + wlc_ampdu_dotxstatus(wlc->ampdu, scb, p, txs); + return false; + } + + supr_status = txs->status & TX_STATUS_SUPR_MASK; + if (supr_status == TX_STATUS_SUPR_BADCH) + WL_NONE("%s: Pkt tx suppressed, possibly channel %d\n", + __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec)); + + tx_rts = htol16(txh->MacTxControlLow) & TXC_SENDRTS; + tx_frame_count = + (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT; + tx_rts_count = + (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT; + + lastframe = (fc & IEEE80211_FCTL_MOREFRAGS) == 0; + + if (!lastframe) { + WL_ERROR("Not last frame!\n"); + } else { + u16 sfbl, lfbl; + ieee80211_tx_info_clear_status(tx_info); + if (queue < AC_COUNT) { + sfbl = WLC_WME_RETRY_SFB_GET(wlc, wme_fifo2ac[queue]); + lfbl = WLC_WME_RETRY_LFB_GET(wlc, wme_fifo2ac[queue]); + } else { + sfbl = wlc->SFBL; + lfbl = wlc->LFBL; + } + + txrate = tx_info->status.rates; + /* FIXME: this should use a combination of sfbl, lfbl depending on frame length and RTS setting */ + if ((tx_frame_count > sfbl) && (txrate[1].idx >= 0)) { + /* rate selection requested a fallback rate and we used it */ + txrate->count = lfbl; + txrate[1].count = tx_frame_count - lfbl; + } else { + /* rate selection did not request fallback rate, or we didn't need it */ + txrate->count = tx_frame_count; + /* rc80211_minstrel.c:minstrel_tx_status() expects unused rates to be marked with idx = -1 */ + txrate[1].idx = -1; + txrate[1].count = 0; + } + + /* clear the rest of the rates */ + for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) { + txrate[i].idx = -1; + txrate[i].count = 0; + } + + if (txs->status & TX_STATUS_ACK_RCV) + tx_info->flags |= IEEE80211_TX_STAT_ACK; + } + + totlen = pkttotlen(osh, p); + free_pdu = true; + + wlc_txfifo_complete(wlc, queue, 1); + + if (lastframe) { + p->next = NULL; + p->prev = NULL; + wlc->txretried = 0; + /* remove PLCP & Broadcom tx descriptor header */ + skb_pull(p, D11_PHY_HDR_LEN); + skb_pull(p, D11_TXH_LEN); + ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); + WLCNTINCR(wlc->pub->_cnt->ieee_tx_status); + } else { + WL_ERROR("%s: Not last frame => not calling tx_status\n", + __func__); + } + + return false; + + fatal: + ASSERT(0); + if (p) + pkt_buf_free_skb(osh, p, true); + + return true; + +} + +void BCMFASTPATH +wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend) +{ + TXPKTPENDDEC(wlc, fifo, txpktpend); + WL_TRACE("wlc_txfifo_complete, pktpend dec %d to %d\n", + txpktpend, TXPKTPENDGET(wlc, fifo)); + + /* There is more room; mark precedences related to this FIFO sendable */ + WLC_TX_FIFO_ENAB(wlc, fifo); + ASSERT(TXPKTPENDGET(wlc, fifo) >= 0); + + if (!TXPKTPENDTOT(wlc)) { + if (wlc->block_datafifo & DATA_BLOCK_TX_SUPR) + wlc_bsscfg_tx_check(wlc); + } + + /* Clear MHF2_TXBCMC_NOW flag if BCMC fifo has drained */ + if (AP_ENAB(wlc->pub) && + wlc->bcmcfifo_drain && !TXPKTPENDGET(wlc, TX_BCMC_FIFO)) { + wlc->bcmcfifo_drain = false; + wlc_mhf(wlc, MHF2, MHF2_TXBCMC_NOW, 0, WLC_BAND_AUTO); + } + + /* figure out which bsscfg is being worked on... */ +} + +/* Given the beacon interval in kus, and a 64 bit TSF in us, + * return the offset (in us) of the TSF from the last TBTT + */ +u32 wlc_calc_tbtt_offset(u32 bp, u32 tsf_h, u32 tsf_l) +{ + u32 k, btklo, btkhi, offset; + + /* TBTT is always an even multiple of the beacon_interval, + * so the TBTT less than or equal to the beacon timestamp is + * the beacon timestamp minus the beacon timestamp modulo + * the beacon interval. + * + * TBTT = BT - (BT % BIu) + * = (BTk - (BTk % BP)) * 2^10 + * + * BT = beacon timestamp (usec, 64bits) + * BTk = beacon timestamp (Kusec, 54bits) + * BP = beacon interval (Kusec, 16bits) + * BIu = BP * 2^10 = beacon interval (usec, 26bits) + * + * To keep the calculations in u32s, the modulo operation + * on the high part of BT needs to be done in parts using the + * relations: + * X*Y mod Z = ((X mod Z) * (Y mod Z)) mod Z + * and + * (X + Y) mod Z = ((X mod Z) + (Y mod Z)) mod Z + * + * So, if BTk[n] = u16 n [0,3] of BTk. + * BTk % BP = SUM((BTk[n] * 2^16n) % BP , 0<=n<4) % BP + * and the SUM term can be broken down: + * (BTk[n] * 2^16n) % BP + * (BTk[n] * (2^16n % BP)) % BP + * + * Create a set of power of 2 mod BP constants: + * K[n] = 2^(16n) % BP + * = (K[n-1] * 2^16) % BP + * K[2] = 2^32 % BP = ((2^16 % BP) * 2^16) % BP + * + * BTk % BP = BTk[0-1] % BP + + * (BTk[2] * K[2]) % BP + + * (BTk[3] * K[3]) % BP + * + * Since K[n] < 2^16 and BTk[n] is < 2^16, then BTk[n] * K[n] < 2^32 + */ + + /* BTk = BT >> 10, btklo = BTk[0-3], bkthi = BTk[4-6] */ + btklo = (tsf_h << 22) | (tsf_l >> 10); + btkhi = tsf_h >> 10; + + /* offset = BTk % BP */ + offset = btklo % bp; + + /* K[2] = ((2^16 % BP) * 2^16) % BP */ + k = (u32) (1 << 16) % bp; + k = (u32) (k * 1 << 16) % (u32) bp; + + /* offset += (BTk[2] * K[2]) % BP */ + offset += ((btkhi & 0xffff) * k) % bp; + + /* BTk[3] */ + btkhi = btkhi >> 16; + + /* k[3] = (K[2] * 2^16) % BP */ + k = (k << 16) % bp; + + /* offset += (BTk[3] * K[3]) % BP */ + offset += ((btkhi & 0xffff) * k) % bp; + + offset = offset % bp; + + /* convert offset from kus to us by shifting up 10 bits and + * add in the low 10 bits of tsf that we ignored + */ + offset = (offset << 10) + (tsf_l & 0x3FF); + + return offset; +} + +/* Update beacon listen interval in shared memory */ +void wlc_bcn_li_upd(struct wlc_info *wlc) +{ + if (AP_ENAB(wlc->pub)) + return; + + /* wake up every DTIM is the default */ + if (wlc->bcn_li_dtim == 1) + wlc_write_shm(wlc, M_BCN_LI, 0); + else + wlc_write_shm(wlc, M_BCN_LI, + (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn); +} + +static void +prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, + struct ieee80211_rx_status *rx_status) +{ + u32 tsf_l, tsf_h; + wlc_d11rxhdr_t *wlc_rxh = (wlc_d11rxhdr_t *) rxh; + int preamble; + int channel; + ratespec_t rspec; + unsigned char *plcp; + + wlc_read_tsf(wlc, &tsf_l, &tsf_h); /* mactime */ + rx_status->mactime = tsf_h; + rx_status->mactime <<= 32; + rx_status->mactime |= tsf_l; + rx_status->flag |= RX_FLAG_TSFT; + + channel = WLC_CHAN_CHANNEL(rxh->RxChan); + + /* XXX Channel/badn needs to be filtered against whether we are single/dual band card */ + if (channel > 14) { + rx_status->band = IEEE80211_BAND_5GHZ; + rx_status->freq = ieee80211_ofdm_chan_to_freq( + WF_CHAN_FACTOR_5_G/2, channel); + + } else { + rx_status->band = IEEE80211_BAND_2GHZ; + rx_status->freq = ieee80211_dsss_chan_to_freq(channel); + } + + rx_status->signal = wlc_rxh->rssi; /* signal */ + + /* noise */ + /* qual */ + rx_status->antenna = (rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; /* ant */ + + plcp = p->data; + + rspec = wlc_compute_rspec(rxh, plcp); + if (IS_MCS(rspec)) { + rx_status->rate_idx = rspec & RSPEC_RATE_MASK; + rx_status->flag |= RX_FLAG_HT; + if (RSPEC_IS40MHZ(rspec)) + rx_status->flag |= RX_FLAG_40MHZ; + } else { + switch (RSPEC2RATE(rspec)) { + case WLC_RATE_1M: + rx_status->rate_idx = 0; + break; + case WLC_RATE_2M: + rx_status->rate_idx = 1; + break; + case WLC_RATE_5M5: + rx_status->rate_idx = 2; + break; + case WLC_RATE_11M: + rx_status->rate_idx = 3; + break; + case WLC_RATE_6M: + rx_status->rate_idx = 4; + break; + case WLC_RATE_9M: + rx_status->rate_idx = 5; + break; + case WLC_RATE_12M: + rx_status->rate_idx = 6; + break; + case WLC_RATE_18M: + rx_status->rate_idx = 7; + break; + case WLC_RATE_24M: + rx_status->rate_idx = 8; + break; + case WLC_RATE_36M: + rx_status->rate_idx = 9; + break; + case WLC_RATE_48M: + rx_status->rate_idx = 10; + break; + case WLC_RATE_54M: + rx_status->rate_idx = 11; + break; + default: + WL_ERROR("%s: Unknown rate\n", __func__); + } + + /* Determine short preamble and rate_idx */ + preamble = 0; + if (IS_CCK(rspec)) { + if (rxh->PhyRxStatus_0 & PRXS0_SHORTH) + WL_ERROR("Short CCK\n"); + rx_status->flag |= RX_FLAG_SHORTPRE; + } else if (IS_OFDM(rspec)) { + rx_status->flag |= RX_FLAG_SHORTPRE; + } else { + WL_ERROR("%s: Unknown modulation\n", __func__); + } + } + + if (PLCP3_ISSGI(plcp[3])) + rx_status->flag |= RX_FLAG_SHORT_GI; + + if (rxh->RxStatus1 & RXS_DECERR) { + rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC; + WL_ERROR("%s: RX_FLAG_FAILED_PLCP_CRC\n", __func__); + } + if (rxh->RxStatus1 & RXS_FCSERR) { + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + WL_ERROR("%s: RX_FLAG_FAILED_FCS_CRC\n", __func__); + } +} + +static void +wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, d11rxhdr_t *rxh, + struct sk_buff *p) +{ + int len_mpdu; + struct ieee80211_rx_status rx_status; +#if defined(BCMDBG) + struct sk_buff *skb = p; +#endif /* BCMDBG */ + /* Todo: + * Cache plcp for first MPDU of AMPD and use chacched version for INTERMEDIATE. + * Test for INTERMEDIATE like so: + * if (!(plcp[0] | plcp[1] | plcp[2])) + */ + + memset(&rx_status, 0, sizeof(rx_status)); + prep_mac80211_status(wlc, rxh, p, &rx_status); + + /* mac header+body length, exclude CRC and plcp header */ + len_mpdu = p->len - D11_PHY_HDR_LEN - FCS_LEN; + skb_pull(p, D11_PHY_HDR_LEN); + __skb_trim(p, len_mpdu); + + ASSERT(!(p->next)); + ASSERT(!(p->prev)); + + ASSERT(IS_ALIGNED((unsigned long)skb->data, 2)); + + memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status)); + ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p); + + WLCNTINCR(wlc->pub->_cnt->ieee_rx); + osh->pktalloced--; + return; +} + +void wlc_bss_list_free(struct wlc_info *wlc, wlc_bss_list_t *bss_list) +{ + uint index; + wlc_bss_info_t *bi; + + if (!bss_list) { + WL_ERROR("%s: Attempting to free NULL list\n", __func__); + return; + } + /* inspect all BSS descriptor */ + for (index = 0; index < bss_list->count; index++) { + bi = bss_list->ptrs[index]; + if (bi) { + kfree(bi); + bss_list->ptrs[index] = NULL; + } + } + bss_list->count = 0; +} + +/* Process received frames */ +/* + * Return true if more frames need to be processed. false otherwise. + * Param 'bound' indicates max. # frames to process before break out. + */ +/* WLC_HIGH_API */ +void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) +{ + d11rxhdr_t *rxh; + struct ieee80211_hdr *h; + struct osl_info *osh; + u16 fc; + uint len; + bool is_amsdu; + + WL_TRACE("wl%d: wlc_recv\n", wlc->pub->unit); + + osh = wlc->osh; + + /* frame starts with rxhdr */ + rxh = (d11rxhdr_t *) (p->data); + + /* strip off rxhdr */ + skb_pull(p, wlc->hwrxoff); + + /* fixup rx header endianness */ + ltoh16_buf((void *)rxh, sizeof(d11rxhdr_t)); + + /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ + if (rxh->RxStatus1 & RXS_PBPRES) { + if (p->len < 2) { + WLCNTINCR(wlc->pub->_cnt->rxrunt); + WL_ERROR("wl%d: wlc_recv: rcvd runt of len %d\n", + wlc->pub->unit, p->len); + goto toss; + } + skb_pull(p, 2); + } + + h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN); + len = p->len; + + if (rxh->RxStatus1 & RXS_FCSERR) { + if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) { + WL_ERROR("FCSERR while scanning******* - tossing\n"); + goto toss; + } else { + WL_ERROR("RCSERR!!!\n"); + goto toss; + } + } + + /* check received pkt has at least frame control field */ + if (len >= D11_PHY_HDR_LEN + sizeof(h->frame_control)) { + fc = ltoh16(h->frame_control); + } else { + WLCNTINCR(wlc->pub->_cnt->rxrunt); + goto toss; + } + + is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK; + + /* explicitly test bad src address to avoid sending bad deauth */ + if (!is_amsdu) { + /* CTS and ACK CTL frames are w/o a2 */ + if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA || + (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { + if ((is_zero_ether_addr(h->addr2) || + is_multicast_ether_addr(h->addr2))) { + WL_ERROR("wl%d: %s: dropping a frame with " + "invalid src mac address, a2: %pM\n", + wlc->pub->unit, __func__, h->addr2); + WLCNTINCR(wlc->pub->_cnt->rxbadsrcmac); + goto toss; + } + WLCNTINCR(wlc->pub->_cnt->rxfrag); + } + } + + /* due to sheer numbers, toss out probe reqs for now */ + if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { + if ((fc & FC_KIND_MASK) == FC_PROBE_REQ) + goto toss; + } + + if (is_amsdu) { + WL_ERROR("%s: is_amsdu causing toss\n", __func__); + goto toss; + } + + wlc_recvctl(wlc, osh, rxh, p); + return; + + toss: + pkt_buf_free_skb(osh, p, false); +} + +/* calculate frame duration for Mixed-mode L-SIG spoofing, return + * number of bytes goes in the length field + * + * Formula given by HT PHY Spec v 1.13 + * len = 3(nsyms + nstream + 3) - 3 + */ +u16 BCMFASTPATH +wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, uint mac_len) +{ + uint nsyms, len = 0, kNdps; + + WL_TRACE("wl%d: wlc_calc_lsig_len: rate %d, len%d\n", + wlc->pub->unit, RSPEC2RATE(ratespec), mac_len); + + if (IS_MCS(ratespec)) { + uint mcs = ratespec & RSPEC_RATE_MASK; + /* MCS_TXS(mcs) returns num tx streams - 1 */ + int tot_streams = (MCS_TXS(mcs) + 1) + RSPEC_STC(ratespec); + + ASSERT(WLC_PHY_11N_CAP(wlc->band)); + /* the payload duration calculation matches that of regular ofdm */ + /* 1000Ndbps = kbps * 4 */ + kNdps = + MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec), + RSPEC_ISSGI(ratespec)) * 4; + + if (RSPEC_STC(ratespec) == 0) + /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ + nsyms = + CEIL((APHY_SERVICE_NBITS + 8 * mac_len + + APHY_TAIL_NBITS) * 1000, kNdps); + else + /* STBC needs to have even number of symbols */ + nsyms = + 2 * + CEIL((APHY_SERVICE_NBITS + 8 * mac_len + + APHY_TAIL_NBITS) * 1000, 2 * kNdps); + + nsyms += (tot_streams + 3); /* (+3) account for HT-SIG(2) and HT-STF(1) */ + /* 3 bytes/symbol @ legacy 6Mbps rate */ + len = (3 * nsyms) - 3; /* (-3) excluding service bits and tail bits */ + } + + return (u16) len; +} + +/* calculate frame duration of a given rate and length, return time in usec unit */ +uint BCMFASTPATH +wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, + uint mac_len) +{ + uint nsyms, dur = 0, Ndps, kNdps; + uint rate = RSPEC2RATE(ratespec); + + if (rate == 0) { + ASSERT(0); + WL_ERROR("wl%d: WAR: using rate of 1 mbps\n", wlc->pub->unit); + rate = WLC_RATE_1M; + } + + WL_TRACE("wl%d: wlc_calc_frame_time: rspec 0x%x, preamble_type %d, len%d\n", + wlc->pub->unit, ratespec, preamble_type, mac_len); + + if (IS_MCS(ratespec)) { + uint mcs = ratespec & RSPEC_RATE_MASK; + int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec); + ASSERT(WLC_PHY_11N_CAP(wlc->band)); + ASSERT(WLC_IS_MIMO_PREAMBLE(preamble_type)); + + dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT); + if (preamble_type == WLC_MM_PREAMBLE) + dur += PREN_MM_EXT; + /* 1000Ndbps = kbps * 4 */ + kNdps = + MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec), + RSPEC_ISSGI(ratespec)) * 4; + + if (RSPEC_STC(ratespec) == 0) + /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ + nsyms = + CEIL((APHY_SERVICE_NBITS + 8 * mac_len + + APHY_TAIL_NBITS) * 1000, kNdps); + else + /* STBC needs to have even number of symbols */ + nsyms = + 2 * + CEIL((APHY_SERVICE_NBITS + 8 * mac_len + + APHY_TAIL_NBITS) * 1000, 2 * kNdps); + + dur += APHY_SYMBOL_TIME * nsyms; + if (BAND_2G(wlc->band->bandtype)) + dur += DOT11_OFDM_SIGNAL_EXTENSION; + } else if (IS_OFDM(rate)) { + dur = APHY_PREAMBLE_TIME; + dur += APHY_SIGNAL_TIME; + /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */ + Ndps = rate * 2; + /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ + nsyms = + CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS), + Ndps); + dur += APHY_SYMBOL_TIME * nsyms; + if (BAND_2G(wlc->band->bandtype)) + dur += DOT11_OFDM_SIGNAL_EXTENSION; + } else { + /* calc # bits * 2 so factor of 2 in rate (1/2 mbps) will divide out */ + mac_len = mac_len * 8 * 2; + /* calc ceiling of bits/rate = microseconds of air time */ + dur = (mac_len + rate - 1) / rate; + if (preamble_type & WLC_SHORT_PREAMBLE) + dur += BPHY_PLCP_SHORT_TIME; + else + dur += BPHY_PLCP_TIME; + } + return dur; +} + +/* The opposite of wlc_calc_frame_time */ +static uint +wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, + uint dur) +{ + uint nsyms, mac_len, Ndps, kNdps; + uint rate = RSPEC2RATE(ratespec); + + WL_TRACE("wl%d: wlc_calc_frame_len: rspec 0x%x, preamble_type %d, dur %d\n", + wlc->pub->unit, ratespec, preamble_type, dur); + + if (IS_MCS(ratespec)) { + uint mcs = ratespec & RSPEC_RATE_MASK; + int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec); + ASSERT(WLC_PHY_11N_CAP(wlc->band)); + dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT); + /* payload calculation matches that of regular ofdm */ + if (BAND_2G(wlc->band->bandtype)) + dur -= DOT11_OFDM_SIGNAL_EXTENSION; + /* kNdbps = kbps * 4 */ + kNdps = + MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec), + RSPEC_ISSGI(ratespec)) * 4; + nsyms = dur / APHY_SYMBOL_TIME; + mac_len = + ((nsyms * kNdps) - + ((APHY_SERVICE_NBITS + APHY_TAIL_NBITS) * 1000)) / 8000; + } else if (IS_OFDM(ratespec)) { + dur -= APHY_PREAMBLE_TIME; + dur -= APHY_SIGNAL_TIME; + /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */ + Ndps = rate * 2; + nsyms = dur / APHY_SYMBOL_TIME; + mac_len = + ((nsyms * Ndps) - + (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8; + } else { + if (preamble_type & WLC_SHORT_PREAMBLE) + dur -= BPHY_PLCP_SHORT_TIME; + else + dur -= BPHY_PLCP_TIME; + mac_len = dur * rate; + /* divide out factor of 2 in rate (1/2 mbps) */ + mac_len = mac_len / 8 / 2; + } + return mac_len; +} + +static uint +wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) +{ + WL_TRACE("wl%d: wlc_calc_ba_time: rspec 0x%x, preamble_type %d\n", + wlc->pub->unit, rspec, preamble_type); + /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than + * or equal to the rate of the immediately previous frame in the FES + */ + rspec = WLC_BASIC_RATE(wlc, rspec); + ASSERT(VALID_RATE_DBG(wlc, rspec)); + + /* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */ + return wlc_calc_frame_time(wlc, rspec, preamble_type, + (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN + + FCS_LEN)); +} + +static uint BCMFASTPATH +wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) +{ + uint dur = 0; + + WL_TRACE("wl%d: wlc_calc_ack_time: rspec 0x%x, preamble_type %d\n", + wlc->pub->unit, rspec, preamble_type); + /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than + * or equal to the rate of the immediately previous frame in the FES + */ + rspec = WLC_BASIC_RATE(wlc, rspec); + ASSERT(VALID_RATE_DBG(wlc, rspec)); + + /* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */ + dur = + wlc_calc_frame_time(wlc, rspec, preamble_type, + (DOT11_ACK_LEN + FCS_LEN)); + return dur; +} + +static uint +wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) +{ + WL_TRACE("wl%d: wlc_calc_cts_time: ratespec 0x%x, preamble_type %d\n", + wlc->pub->unit, rspec, preamble_type); + return wlc_calc_ack_time(wlc, rspec, preamble_type); +} + +/* derive wlc->band->basic_rate[] table from 'rateset' */ +void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset) +{ + u8 rate; + u8 mandatory; + u8 cck_basic = 0; + u8 ofdm_basic = 0; + u8 *br = wlc->band->basic_rate; + uint i; + + /* incoming rates are in 500kbps units as in 802.11 Supported Rates */ + memset(br, 0, WLC_MAXRATE + 1); + + /* For each basic rate in the rates list, make an entry in the + * best basic lookup. + */ + for (i = 0; i < rateset->count; i++) { + /* only make an entry for a basic rate */ + if (!(rateset->rates[i] & WLC_RATE_FLAG)) + continue; + + /* mask off basic bit */ + rate = (rateset->rates[i] & RATE_MASK); + + if (rate > WLC_MAXRATE) { + WL_ERROR("wlc_rate_lookup_init: invalid rate 0x%X in rate set\n", + rateset->rates[i]); + continue; + } + + br[rate] = rate; + } + + /* The rate lookup table now has non-zero entries for each + * basic rate, equal to the basic rate: br[basicN] = basicN + * + * To look up the best basic rate corresponding to any + * particular rate, code can use the basic_rate table + * like this + * + * basic_rate = wlc->band->basic_rate[tx_rate] + * + * Make sure there is a best basic rate entry for + * every rate by walking up the table from low rates + * to high, filling in holes in the lookup table + */ + + for (i = 0; i < wlc->band->hw_rateset.count; i++) { + rate = wlc->band->hw_rateset.rates[i]; + ASSERT(rate <= WLC_MAXRATE); + + if (br[rate] != 0) { + /* This rate is a basic rate. + * Keep track of the best basic rate so far by + * modulation type. + */ + if (IS_OFDM(rate)) + ofdm_basic = rate; + else + cck_basic = rate; + + continue; + } + + /* This rate is not a basic rate so figure out the + * best basic rate less than this rate and fill in + * the hole in the table + */ + + br[rate] = IS_OFDM(rate) ? ofdm_basic : cck_basic; + + if (br[rate] != 0) + continue; + + if (IS_OFDM(rate)) { + /* In 11g and 11a, the OFDM mandatory rates are 6, 12, and 24 Mbps */ + if (rate >= WLC_RATE_24M) + mandatory = WLC_RATE_24M; + else if (rate >= WLC_RATE_12M) + mandatory = WLC_RATE_12M; + else + mandatory = WLC_RATE_6M; + } else { + /* In 11b, all the CCK rates are mandatory 1 - 11 Mbps */ + mandatory = rate; + } + + br[rate] = mandatory; + } +} + +static void wlc_write_rate_shm(struct wlc_info *wlc, u8 rate, u8 basic_rate) +{ + u8 phy_rate, index; + u8 basic_phy_rate, basic_index; + u16 dir_table, basic_table; + u16 basic_ptr; + + /* Shared memory address for the table we are reading */ + dir_table = IS_OFDM(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B; + + /* Shared memory address for the table we are writing */ + basic_table = IS_OFDM(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B; + + /* + * for a given rate, the LS-nibble of the PLCP SIGNAL field is + * the index into the rate table. + */ + phy_rate = rate_info[rate] & RATE_MASK; + basic_phy_rate = rate_info[basic_rate] & RATE_MASK; + index = phy_rate & 0xf; + basic_index = basic_phy_rate & 0xf; + + /* Find the SHM pointer to the ACK rate entry by looking in the + * Direct-map Table + */ + basic_ptr = wlc_read_shm(wlc, (dir_table + basic_index * 2)); + + /* Update the SHM BSS-basic-rate-set mapping table with the pointer + * to the correct basic rate for the given incoming rate + */ + wlc_write_shm(wlc, (basic_table + index * 2), basic_ptr); +} + +static const wlc_rateset_t *wlc_rateset_get_hwrs(struct wlc_info *wlc) +{ + const wlc_rateset_t *rs_dflt; + + if (WLC_PHY_11N_CAP(wlc->band)) { + if (BAND_5G(wlc->band->bandtype)) + rs_dflt = &ofdm_mimo_rates; + else + rs_dflt = &cck_ofdm_mimo_rates; + } else if (wlc->band->gmode) + rs_dflt = &cck_ofdm_rates; + else + rs_dflt = &cck_rates; + + return rs_dflt; +} + +void wlc_set_ratetable(struct wlc_info *wlc) +{ + const wlc_rateset_t *rs_dflt; + wlc_rateset_t rs; + u8 rate, basic_rate; + uint i; + + rs_dflt = wlc_rateset_get_hwrs(wlc); + ASSERT(rs_dflt != NULL); + + wlc_rateset_copy(rs_dflt, &rs); + wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams); + + /* walk the phy rate table and update SHM basic rate lookup table */ + for (i = 0; i < rs.count; i++) { + rate = rs.rates[i] & RATE_MASK; + + /* for a given rate WLC_BASIC_RATE returns the rate at + * which a response ACK/CTS should be sent. + */ + basic_rate = WLC_BASIC_RATE(wlc, rate); + if (basic_rate == 0) { + /* This should only happen if we are using a + * restricted rateset. + */ + basic_rate = rs.rates[0] & RATE_MASK; + } + + wlc_write_rate_shm(wlc, rate, basic_rate); + } +} + +/* + * Return true if the specified rate is supported by the specified band. + * WLC_BAND_AUTO indicates the current band. + */ +bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rspec, int band, + bool verbose) +{ + wlc_rateset_t *hw_rateset; + uint i; + + if ((band == WLC_BAND_AUTO) || (band == wlc->band->bandtype)) { + hw_rateset = &wlc->band->hw_rateset; + } else if (NBANDS(wlc) > 1) { + hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset; + } else { + /* other band specified and we are a single band device */ + return false; + } + + /* check if this is a mimo rate */ + if (IS_MCS(rspec)) { + if (!VALID_MCS((rspec & RSPEC_RATE_MASK))) + goto error; + + return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK)); + } + + for (i = 0; i < hw_rateset->count; i++) + if (hw_rateset->rates[i] == RSPEC2RATE(rspec)) + return true; + error: + if (verbose) { + WL_ERROR("wl%d: wlc_valid_rate: rate spec 0x%x not in hw_rateset\n", + wlc->pub->unit, rspec); + } + + return false; +} + +static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap) +{ + uint i; + struct wlcband *band; + + for (i = 0; i < NBANDS(wlc); i++) { + if (IS_SINGLEBAND_5G(wlc->deviceid)) + i = BAND_5G_INDEX; + band = wlc->bandstate[i]; + if (band->bandtype == WLC_BAND_5G) { + if ((bwcap == WLC_N_BW_40ALL) + || (bwcap == WLC_N_BW_20IN2G_40IN5G)) + band->mimo_cap_40 = true; + else + band->mimo_cap_40 = false; + } else { + ASSERT(band->bandtype == WLC_BAND_2G); + if (bwcap == WLC_N_BW_40ALL) + band->mimo_cap_40 = true; + else + band->mimo_cap_40 = false; + } + } + + wlc->mimo_band_bwcap = bwcap; +} + +void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len) +{ + const wlc_rateset_t *rs_dflt; + wlc_rateset_t rs; + u8 rate; + u16 entry_ptr; + u8 plcp[D11_PHY_HDR_LEN]; + u16 dur, sifs; + uint i; + + sifs = SIFS(wlc->band); + + rs_dflt = wlc_rateset_get_hwrs(wlc); + ASSERT(rs_dflt != NULL); + + wlc_rateset_copy(rs_dflt, &rs); + wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams); + + /* walk the phy rate table and update MAC core SHM basic rate table entries */ + for (i = 0; i < rs.count; i++) { + rate = rs.rates[i] & RATE_MASK; + + entry_ptr = wlc_rate_shm_offset(wlc, rate); + + /* Calculate the Probe Response PLCP for the given rate */ + wlc_compute_plcp(wlc, rate, frame_len, plcp); + + /* Calculate the duration of the Probe Response frame plus SIFS for the MAC */ + dur = + (u16) wlc_calc_frame_time(wlc, rate, WLC_LONG_PREAMBLE, + frame_len); + dur += sifs; + + /* Update the SHM Rate Table entry Probe Response values */ + wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS, + (u16) (plcp[0] + (plcp[1] << 8))); + wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS + 2, + (u16) (plcp[2] + (plcp[3] << 8))); + wlc_write_shm(wlc, entry_ptr + M_RT_PRS_DUR_POS, dur); + } +} + +u16 +wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec, + bool short_preamble, bool phydelay) +{ + uint bcntsfoff = 0; + + if (IS_MCS(rspec)) { + WL_ERROR("wl%d: recd beacon with mcs rate; rspec 0x%x\n", + wlc->pub->unit, rspec); + } else if (IS_OFDM(rspec)) { + /* tx delay from MAC through phy to air (2.1 usec) + + * phy header time (preamble + PLCP SIGNAL == 20 usec) + + * PLCP SERVICE + MAC header time (SERVICE + FC + DUR + A1 + A2 + A3 + SEQ == 26 + * bytes at beacon rate) + */ + bcntsfoff += phydelay ? D11A_PHY_TX_DELAY : 0; + bcntsfoff += APHY_PREAMBLE_TIME + APHY_SIGNAL_TIME; + bcntsfoff += + wlc_compute_airtime(wlc, rspec, + APHY_SERVICE_NBITS / 8 + + DOT11_MAC_HDR_LEN); + } else { + /* tx delay from MAC through phy to air (3.4 usec) + + * phy header time (long preamble + PLCP == 192 usec) + + * MAC header time (FC + DUR + A1 + A2 + A3 + SEQ == 24 bytes at beacon rate) + */ + bcntsfoff += phydelay ? D11B_PHY_TX_DELAY : 0; + bcntsfoff += + short_preamble ? D11B_PHY_SPREHDR_TIME : + D11B_PHY_LPREHDR_TIME; + bcntsfoff += wlc_compute_airtime(wlc, rspec, DOT11_MAC_HDR_LEN); + } + return (u16) (bcntsfoff); +} + +/* Max buffering needed for beacon template/prb resp template is 142 bytes. + * + * PLCP header is 6 bytes. + * 802.11 A3 header is 24 bytes. + * Max beacon frame body template length is 112 bytes. + * Max probe resp frame body template length is 110 bytes. + * + * *len on input contains the max length of the packet available. + * + * The *len value is set to the number of bytes in buf used, and starts with the PLCP + * and included up to, but not including, the 4 byte FCS. + */ +static void +wlc_bcn_prb_template(struct wlc_info *wlc, uint type, ratespec_t bcn_rspec, + wlc_bsscfg_t *cfg, u16 *buf, int *len) +{ + static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; + cck_phy_hdr_t *plcp; + struct ieee80211_mgmt *h; + int hdr_len, body_len; + + ASSERT(*len >= 142); + ASSERT(type == FC_BEACON || type == FC_PROBE_RESP); + + if (MBSS_BCN_ENAB(cfg) && type == FC_BEACON) + hdr_len = DOT11_MAC_HDR_LEN; + else + hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN; + body_len = *len - hdr_len; /* calc buffer size provided for frame body */ + + *len = hdr_len + body_len; /* return actual size */ + + /* format PHY and MAC headers */ + memset((char *)buf, 0, hdr_len); + + plcp = (cck_phy_hdr_t *) buf; + + /* PLCP for Probe Response frames are filled in from core's rate table */ + if (type == FC_BEACON && !MBSS_BCN_ENAB(cfg)) { + /* fill in PLCP */ + wlc_compute_plcp(wlc, bcn_rspec, + (DOT11_MAC_HDR_LEN + body_len + FCS_LEN), + (u8 *) plcp); + + } + /* "Regular" and 16 MBSS but not for 4 MBSS */ + /* Update the phytxctl for the beacon based on the rspec */ + if (!SOFTBCN_ENAB(cfg)) + wlc_beacon_phytxctl_txant_upd(wlc, bcn_rspec); + + if (MBSS_BCN_ENAB(cfg) && type == FC_BEACON) + h = (struct ieee80211_mgmt *)&plcp[0]; + else + h = (struct ieee80211_mgmt *)&plcp[1]; + + /* fill in 802.11 header */ + h->frame_control = htol16((u16) type); + + /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */ + /* A1 filled in by MAC for prb resp, broadcast for bcn */ + if (type == FC_BEACON) + bcopy((const char *)ðer_bcast, (char *)&h->da, + ETH_ALEN); + bcopy((char *)&cfg->cur_etheraddr, (char *)&h->sa, ETH_ALEN); + bcopy((char *)&cfg->BSSID, (char *)&h->bssid, ETH_ALEN); + + /* SEQ filled in by MAC */ + + return; +} + +int wlc_get_header_len() +{ + return TXOFF; +} + +/* Update a beacon for a particular BSS + * For MBSS, this updates the software template and sets "latest" to the index of the + * template updated. + * Otherwise, it updates the hardware template. + */ +void wlc_bss_update_beacon(struct wlc_info *wlc, wlc_bsscfg_t *cfg) +{ + int len = BCN_TMPL_LEN; + + /* Clear the soft intmask */ + wlc->defmacintmask &= ~MI_BCNTPL; + + if (!cfg->up) { /* Only allow updates on an UP bss */ + return; + } + + if (MBSS_BCN_ENAB(cfg)) { /* Optimize: Some of if/else could be combined */ + } else if (HWBCN_ENAB(cfg)) { /* Hardware beaconing for this config */ + u16 bcn[BCN_TMPL_LEN / 2]; + u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD; + d11regs_t *regs = wlc->regs; + struct osl_info *osh = NULL; + + osh = wlc->osh; + + /* Check if both templates are in use, if so sched. an interrupt + * that will call back into this routine + */ + if ((R_REG(osh, ®s->maccommand) & both_valid) == both_valid) { + /* clear any previous status */ + W_REG(osh, ®s->macintstatus, MI_BCNTPL); + } + /* Check that after scheduling the interrupt both of the + * templates are still busy. if not clear the int. & remask + */ + if ((R_REG(osh, ®s->maccommand) & both_valid) == both_valid) { + wlc->defmacintmask |= MI_BCNTPL; + return; + } + + wlc->bcn_rspec = + wlc_lowest_basic_rspec(wlc, &cfg->current_bss->rateset); + ASSERT(wlc_valid_rate + (wlc, wlc->bcn_rspec, + CHSPEC_IS2G(cfg->current_bss-> + chanspec) ? WLC_BAND_2G : WLC_BAND_5G, + true)); + + /* update the template and ucode shm */ + wlc_bcn_prb_template(wlc, FC_BEACON, wlc->bcn_rspec, cfg, bcn, + &len); + wlc_write_hw_bcntemplates(wlc, bcn, len, false); + } +} + +/* + * Update all beacons for the system. + */ +void wlc_update_beacon(struct wlc_info *wlc) +{ + int idx; + wlc_bsscfg_t *bsscfg; + + /* update AP or IBSS beacons */ + FOREACH_BSS(wlc, idx, bsscfg) { + if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS)) + wlc_bss_update_beacon(wlc, bsscfg); + } +} + +/* Write ssid into shared memory */ +void wlc_shm_ssid_upd(struct wlc_info *wlc, wlc_bsscfg_t *cfg) +{ + u8 *ssidptr = cfg->SSID; + u16 base = M_SSID; + u8 ssidbuf[IEEE80211_MAX_SSID_LEN]; + + /* padding the ssid with zero and copy it into shm */ + memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN); + bcopy(ssidptr, ssidbuf, cfg->SSID_len); + + wlc_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN); + + if (!MBSS_BCN_ENAB(cfg)) + wlc_write_shm(wlc, M_SSIDLEN, (u16) cfg->SSID_len); +} + +void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend) +{ + int idx; + wlc_bsscfg_t *bsscfg; + + /* update AP or IBSS probe responses */ + FOREACH_BSS(wlc, idx, bsscfg) { + if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS)) + wlc_bss_update_probe_resp(wlc, bsscfg, suspend); + } +} + +void +wlc_bss_update_probe_resp(struct wlc_info *wlc, wlc_bsscfg_t *cfg, bool suspend) +{ + u16 prb_resp[BCN_TMPL_LEN / 2]; + int len = BCN_TMPL_LEN; + + /* write the probe response to hardware, or save in the config structure */ + if (!MBSS_PRB_ENAB(cfg)) { + + /* create the probe response template */ + wlc_bcn_prb_template(wlc, FC_PROBE_RESP, 0, cfg, prb_resp, + &len); + + if (suspend) + wlc_suspend_mac_and_wait(wlc); + + /* write the probe response into the template region */ + wlc_bmac_write_template_ram(wlc->hw, T_PRS_TPL_BASE, + (len + 3) & ~3, prb_resp); + + /* write the length of the probe response frame (+PLCP/-FCS) */ + wlc_write_shm(wlc, M_PRB_RESP_FRM_LEN, (u16) len); + + /* write the SSID and SSID length */ + wlc_shm_ssid_upd(wlc, cfg); + + /* + * Write PLCP headers and durations for probe response frames at all rates. + * Use the actual frame length covered by the PLCP header for the call to + * wlc_mod_prb_rsp_rate_table() by subtracting the PLCP len and adding the FCS. + */ + len += (-D11_PHY_HDR_LEN + FCS_LEN); + wlc_mod_prb_rsp_rate_table(wlc, (u16) len); + + if (suspend) + wlc_enable_mac(wlc); + } else { /* Generating probe resp in sw; update local template */ + ASSERT(0 && "No software probe response support without MBSS"); + } +} + +/* prepares pdu for transmission. returns BCM error codes */ +int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) +{ + struct osl_info *osh; + uint fifo; + d11txh_t *txh; + struct ieee80211_hdr *h; + struct scb *scb; + u16 fc; + + osh = wlc->osh; + + ASSERT(pdu); + txh = (d11txh_t *) (pdu->data); + ASSERT(txh); + h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); + ASSERT(h); + fc = ltoh16(h->frame_control); + + /* get the pkt queue info. This was put at wlc_sendctl or wlc_send for PDU */ + fifo = ltoh16(txh->TxFrameID) & TXFID_QUEUE_MASK; + + scb = NULL; + + *fifop = fifo; + + /* return if insufficient dma resources */ + if (TXAVAIL(wlc, fifo) < MAX_DMA_SEGS) { + /* Mark precedences related to this FIFO, unsendable */ + WLC_TX_FIFO_CLEAR(wlc, fifo); + return BCME_BUSY; + } + + if ((ltoh16(txh->MacFrameControl) & IEEE80211_FCTL_FTYPE) != + IEEE80211_FTYPE_DATA) + WLCNTINCR(wlc->pub->_cnt->txctl); + + return 0; +} + +/* init tx reported rate mechanism */ +void wlc_reprate_init(struct wlc_info *wlc) +{ + int i; + wlc_bsscfg_t *bsscfg; + + FOREACH_BSS(wlc, i, bsscfg) { + wlc_bsscfg_reprate_init(bsscfg); + } +} + +/* per bsscfg init tx reported rate mechanism */ +void wlc_bsscfg_reprate_init(wlc_bsscfg_t *bsscfg) +{ + bsscfg->txrspecidx = 0; + memset((char *)bsscfg->txrspec, 0, sizeof(bsscfg->txrspec)); +} + +/* Retrieve a consolidated set of revision information, + * typically for the WLC_GET_REVINFO ioctl + */ +int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len) +{ + wlc_rev_info_t *rinfo = (wlc_rev_info_t *) buf; + + if (len < WL_REV_INFO_LEGACY_LENGTH) + return BCME_BUFTOOSHORT; + + rinfo->vendorid = wlc->vendorid; + rinfo->deviceid = wlc->deviceid; + rinfo->radiorev = (wlc->band->radiorev << IDCODE_REV_SHIFT) | + (wlc->band->radioid << IDCODE_ID_SHIFT); + rinfo->chiprev = wlc->pub->sih->chiprev; + rinfo->corerev = wlc->pub->corerev; + rinfo->boardid = wlc->pub->sih->boardtype; + rinfo->boardvendor = wlc->pub->sih->boardvendor; + rinfo->boardrev = wlc->pub->boardrev; + rinfo->ucoderev = wlc->ucode_rev; + rinfo->driverrev = EPI_VERSION_NUM; + rinfo->bus = wlc->pub->sih->bustype; + rinfo->chipnum = wlc->pub->sih->chip; + + if (len >= (offsetof(wlc_rev_info_t, chippkg))) { + rinfo->phytype = wlc->band->phytype; + rinfo->phyrev = wlc->band->phyrev; + rinfo->anarev = 0; /* obsolete stuff, suppress */ + } + + if (len >= sizeof(*rinfo)) { + rinfo->chippkg = wlc->pub->sih->chippkg; + } + + return BCME_OK; +} + +void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs) +{ + wlc_rateset_default(rs, NULL, wlc->band->phytype, wlc->band->bandtype, + false, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub), + CHSPEC_WLC_BW(wlc->default_bss->chanspec), + wlc->stf->txstreams); +} + +static void wlc_bss_default_init(struct wlc_info *wlc) +{ + chanspec_t chanspec; + struct wlcband *band; + wlc_bss_info_t *bi = wlc->default_bss; + + /* init default and target BSS with some sane initial values */ + memset((char *)(bi), 0, sizeof(wlc_bss_info_t)); + bi->beacon_period = ISSIM_ENAB(wlc->pub->sih) ? BEACON_INTERVAL_DEF_QT : + BEACON_INTERVAL_DEFAULT; + bi->dtim_period = ISSIM_ENAB(wlc->pub->sih) ? DTIM_INTERVAL_DEF_QT : + DTIM_INTERVAL_DEFAULT; + + /* fill the default channel as the first valid channel + * starting from the 2G channels + */ + chanspec = CH20MHZ_CHSPEC(1); + ASSERT(chanspec != INVCHANSPEC); + + wlc->home_chanspec = bi->chanspec = chanspec; + + /* find the band of our default channel */ + band = wlc->band; + if (NBANDS(wlc) > 1 && band->bandunit != CHSPEC_WLCBANDUNIT(chanspec)) + band = wlc->bandstate[OTHERBANDUNIT(wlc)]; + + /* init bss rates to the band specific default rate set */ + wlc_rateset_default(&bi->rateset, NULL, band->phytype, band->bandtype, + false, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub), + CHSPEC_WLC_BW(chanspec), wlc->stf->txstreams); + + if (N_ENAB(wlc->pub)) + bi->flags |= WLC_BSS_HT; +} + +/* Deferred event processing */ +static void wlc_process_eventq(void *arg) +{ + struct wlc_info *wlc = (struct wlc_info *) arg; + wlc_event_t *etmp; + + while ((etmp = wlc_eventq_deq(wlc->eventq))) { + /* Perform OS specific event processing */ + wl_event(wlc->wl, etmp->event.ifname, etmp); + if (etmp->data) { + kfree(etmp->data); + etmp->data = NULL; + } + wlc_event_free(wlc->eventq, etmp); + } +} + +void +wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, u32 b_low) +{ + if (b_low > *a_low) { + /* low half needs a carry */ + b_high += 1; + } + *a_low -= b_low; + *a_high -= b_high; +} + +static ratespec_t +mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, + u32 int_val) +{ + u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT; + u8 rate = int_val & NRATE_RATE_MASK; + ratespec_t rspec; + bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE); + bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT); + bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY) + == NRATE_OVERRIDE_MCS_ONLY); + int bcmerror = 0; + + if (!ismcs) { + return (ratespec_t) rate; + } + + /* validate the combination of rate/mcs/stf is allowed */ + if (N_ENAB(wlc->pub) && ismcs) { + /* mcs only allowed when nmode */ + if (stf > PHY_TXC1_MODE_SDM) { + WL_ERROR("wl%d: %s: Invalid stf\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + + /* mcs 32 is a special case, DUP mode 40 only */ + if (rate == 32) { + if (!CHSPEC_IS40(wlc->home_chanspec) || + ((stf != PHY_TXC1_MODE_SISO) + && (stf != PHY_TXC1_MODE_CDD))) { + WL_ERROR("wl%d: %s: Invalid mcs 32\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + /* mcs > 7 must use stf SDM */ + } else if (rate > HIGHEST_SINGLE_STREAM_MCS) { + /* mcs > 7 must use stf SDM */ + if (stf != PHY_TXC1_MODE_SDM) { + WL_TRACE("wl%d: %s: enabling SDM mode for mcs %d\n", + WLCWLUNIT(wlc), __func__, rate); + stf = PHY_TXC1_MODE_SDM; + } + } else { + /* MCS 0-7 may use SISO, CDD, and for phy_rev >= 3 STBC */ + if ((stf > PHY_TXC1_MODE_STBC) || + (!WLC_STBC_CAP_PHY(wlc) + && (stf == PHY_TXC1_MODE_STBC))) { + WL_ERROR("wl%d: %s: Invalid STBC\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + } + } else if (IS_OFDM(rate)) { + if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) { + WL_ERROR("wl%d: %s: Invalid OFDM\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + } else if (IS_CCK(rate)) { + if ((cur_band->bandtype != WLC_BAND_2G) + || (stf != PHY_TXC1_MODE_SISO)) { + WL_ERROR("wl%d: %s: Invalid CCK\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + } else { + WL_ERROR("wl%d: %s: Unknown rate type\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + /* make sure multiple antennae are available for non-siso rates */ + if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) { + WL_ERROR("wl%d: %s: SISO antenna but !SISO request\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + + rspec = rate; + if (ismcs) { + rspec |= RSPEC_MIMORATE; + /* For STBC populate the STC field of the ratespec */ + if (stf == PHY_TXC1_MODE_STBC) { + u8 stc; + stc = 1; /* Nss for single stream is always 1 */ + rspec |= (stc << RSPEC_STC_SHIFT); + } + } + + rspec |= (stf << RSPEC_STF_SHIFT); + + if (override_mcs_only) + rspec |= RSPEC_OVERRIDE_MCS_ONLY; + + if (issgi) + rspec |= RSPEC_SHORT_GI; + + if ((rate != 0) + && !wlc_valid_rate(wlc, rspec, cur_band->bandtype, true)) { + return rate; + } + + return rspec; + done: + WL_ERROR("Hoark\n"); + return rate; +} + +/* formula: IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */ +static int +wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, + bool writeToShm) +{ + int idle_busy_ratio_x_16 = 0; + uint offset = + isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM : + M_TX_IDLE_BUSY_RATIO_X_16_CCK; + if (duty_cycle > 100 || duty_cycle < 0) { + WL_ERROR("wl%d: duty cycle value off limit\n", wlc->pub->unit); + return BCME_RANGE; + } + if (duty_cycle) + idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle; + /* Only write to shared memory when wl is up */ + if (writeToShm) + wlc_write_shm(wlc, offset, (u16) idle_busy_ratio_x_16); + + if (isOFDM) + wlc->tx_duty_cycle_ofdm = (u16) duty_cycle; + else + wlc->tx_duty_cycle_cck = (u16) duty_cycle; + + return BCME_OK; +} + +/* Read a single u16 from shared memory. + * SHM 'offset' needs to be an even address + */ +u16 wlc_read_shm(struct wlc_info *wlc, uint offset) +{ + return wlc_bmac_read_shm(wlc->hw, offset); +} + +/* Write a single u16 to shared memory. + * SHM 'offset' needs to be an even address + */ +void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v) +{ + wlc_bmac_write_shm(wlc->hw, offset, v); +} + +/* Set a range of shared memory to a value. + * SHM 'offset' needs to be an even address and + * Range length 'len' must be an even number of bytes + */ +void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len) +{ + /* offset and len need to be even */ + ASSERT((offset & 1) == 0); + ASSERT((len & 1) == 0); + + if (len <= 0) + return; + + wlc_bmac_set_shm(wlc->hw, offset, v, len); +} + +/* Copy a buffer to shared memory. + * SHM 'offset' needs to be an even address and + * Buffer length 'len' must be an even number of bytes + */ +void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, int len) +{ + /* offset and len need to be even */ + ASSERT((offset & 1) == 0); + ASSERT((len & 1) == 0); + + if (len <= 0) + return; + wlc_bmac_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL); + +} + +/* Copy from shared memory to a buffer. + * SHM 'offset' needs to be an even address and + * Buffer length 'len' must be an even number of bytes + */ +void wlc_copyfrom_shm(struct wlc_info *wlc, uint offset, void *buf, int len) +{ + /* offset and len need to be even */ + ASSERT((offset & 1) == 0); + ASSERT((len & 1) == 0); + + if (len <= 0) + return; + + wlc_bmac_copyfrom_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL); +} + +/* wrapper BMAC functions to for HIGH driver access */ +void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val) +{ + wlc_bmac_mctrl(wlc->hw, mask, val); +} + +void wlc_corereset(struct wlc_info *wlc, u32 flags) +{ + wlc_bmac_corereset(wlc->hw, flags); +} + +void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val, int bands) +{ + wlc_bmac_mhf(wlc->hw, idx, mask, val, bands); +} + +u16 wlc_mhf_get(struct wlc_info *wlc, u8 idx, int bands) +{ + return wlc_bmac_mhf_get(wlc->hw, idx, bands); +} + +int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks) +{ + return wlc_bmac_xmtfifo_sz_get(wlc->hw, fifo, blocks); +} + +void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len, + void *buf) +{ + wlc_bmac_write_template_ram(wlc->hw, offset, len, buf); +} + +void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len, + bool both) +{ + wlc_bmac_write_hw_bcntemplates(wlc->hw, bcn, len, both); +} + +void +wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, + const u8 *addr) +{ + wlc_bmac_set_addrmatch(wlc->hw, match_reg_offset, addr); +} + +void wlc_set_rcmta(struct wlc_info *wlc, int idx, const u8 *addr) +{ + wlc_bmac_set_rcmta(wlc->hw, idx, addr); +} + +void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, u32 *tsf_h_ptr) +{ + wlc_bmac_read_tsf(wlc->hw, tsf_l_ptr, tsf_h_ptr); +} + +void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin) +{ + wlc->band->CWmin = newmin; + wlc_bmac_set_cwmin(wlc->hw, newmin); +} + +void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax) +{ + wlc->band->CWmax = newmax; + wlc_bmac_set_cwmax(wlc->hw, newmax); +} + +void wlc_fifoerrors(struct wlc_info *wlc) +{ + + wlc_bmac_fifoerrors(wlc->hw); +} + +/* Search mem rw utilities */ + +void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit) +{ + wlc_bmac_pllreq(wlc->hw, set, req_bit); +} + +void wlc_reset_bmac_done(struct wlc_info *wlc) +{ +} + +void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode) +{ + wlc->ht_cap.cap_info &= ~HT_CAP_MIMO_PS_MASK; + wlc->ht_cap.cap_info |= (mimops_mode << IEEE80211_HT_CAP_SM_PS_SHIFT); + + if (AP_ENAB(wlc->pub) && wlc->clk) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, true); + } +} + +/* check for the particular priority flow control bit being set */ +bool +wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, wlc_txq_info_t *q, int prio) +{ + uint prio_mask; + + if (prio == ALLPRIO) { + prio_mask = TXQ_STOP_FOR_PRIOFC_MASK; + } else { + ASSERT(prio >= 0 && prio <= MAXPRIO); + prio_mask = NBITVAL(prio); + } + + return (q->stopped & prio_mask) == prio_mask; +} + +/* propogate the flow control to all interfaces using the given tx queue */ +void wlc_txflowcontrol(struct wlc_info *wlc, wlc_txq_info_t *qi, + bool on, int prio) +{ + uint prio_bits; + uint cur_bits; + + WL_ERROR("%s: flow control kicks in\n", __func__); + + if (prio == ALLPRIO) { + prio_bits = TXQ_STOP_FOR_PRIOFC_MASK; + } else { + ASSERT(prio >= 0 && prio <= MAXPRIO); + prio_bits = NBITVAL(prio); + } + + cur_bits = qi->stopped & prio_bits; + + /* Check for the case of no change and return early + * Otherwise update the bit and continue + */ + if (on) { + if (cur_bits == prio_bits) { + return; + } + mboolset(qi->stopped, prio_bits); + } else { + if (cur_bits == 0) { + return; + } + mboolclr(qi->stopped, prio_bits); + } + + /* If there is a flow control override we will not change the external + * flow control state. + */ + if (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK) { + return; + } + + wlc_txflowcontrol_signal(wlc, qi, on, prio); +} + +void +wlc_txflowcontrol_override(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, + uint override) +{ + uint prev_override; + + ASSERT(override != 0); + ASSERT((override & TXQ_STOP_FOR_PRIOFC_MASK) == 0); + + prev_override = (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK); + + /* Update the flow control bits and do an early return if there is + * no change in the external flow control state. + */ + if (on) { + mboolset(qi->stopped, override); + /* if there was a previous override bit on, then setting this + * makes no difference. + */ + if (prev_override) { + return; + } + + wlc_txflowcontrol_signal(wlc, qi, ON, ALLPRIO); + } else { + mboolclr(qi->stopped, override); + /* clearing an override bit will only make a difference for + * flow control if it was the only bit set. For any other + * override setting, just return + */ + if (prev_override != override) { + return; + } + + if (qi->stopped == 0) { + wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); + } else { + int prio; + + for (prio = MAXPRIO; prio >= 0; prio--) { + if (!mboolisset(qi->stopped, NBITVAL(prio))) + wlc_txflowcontrol_signal(wlc, qi, OFF, + prio); + } + } + } +} + +static void wlc_txflowcontrol_reset(struct wlc_info *wlc) +{ + wlc_txq_info_t *qi; + + for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { + if (qi->stopped) { + wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); + qi->stopped = 0; + } + } +} + +static void +wlc_txflowcontrol_signal(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, + int prio) +{ + struct wlc_if *wlcif; + + for (wlcif = wlc->wlcif_list; wlcif != NULL; wlcif = wlcif->next) { + if (wlcif->qi == qi && wlcif->flags & WLC_IF_LINKED) + wl_txflowcontrol(wlc->wl, wlcif->wlif, on, prio); + } +} + +static wlc_txq_info_t *wlc_txq_alloc(struct wlc_info *wlc, struct osl_info *osh) +{ + wlc_txq_info_t *qi, *p; + + qi = (wlc_txq_info_t *) wlc_calloc(osh, wlc->pub->unit, + sizeof(wlc_txq_info_t)); + if (qi == NULL) { + return NULL; + } + + /* Have enough room for control packets along with HI watermark */ + /* Also, add room to txq for total psq packets if all the SCBs leave PS mode */ + /* The watermark for flowcontrol to OS packets will remain the same */ + pktq_init(&qi->q, WLC_PREC_COUNT, + (2 * wlc->pub->tunables->datahiwat) + PKTQ_LEN_DEFAULT + + wlc->pub->psq_pkts_total); + + /* add this queue to the the global list */ + p = wlc->tx_queues; + if (p == NULL) { + wlc->tx_queues = qi; + } else { + while (p->next != NULL) + p = p->next; + p->next = qi; + } + + return qi; +} + +static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh, + wlc_txq_info_t *qi) +{ + wlc_txq_info_t *p; + + if (qi == NULL) + return; + + /* remove the queue from the linked list */ + p = wlc->tx_queues; + if (p == qi) + wlc->tx_queues = p->next; + else { + while (p != NULL && p->next != qi) + p = p->next; + ASSERT(p->next == qi); + if (p != NULL) + p->next = p->next->next; + } + + kfree(qi); +} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h new file mode 100644 index 000000000000..f56b58141c09 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h @@ -0,0 +1,989 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_h_ +#define _wlc_h_ + +#include +#include +#include +#include +#include + +#define MA_WINDOW_SZ 8 /* moving average window size */ +#define WL_HWRXOFF 38 /* chip rx buffer offset */ +#define INVCHANNEL 255 /* invalid channel */ +#define MAXCOREREV 28 /* max # supported core revisions (0 .. MAXCOREREV - 1) */ +#define WLC_MAXMODULES 22 /* max # wlc_module_register() calls */ + +/* network protection config */ +#define WLC_PROT_G_SPEC 1 /* SPEC g protection */ +#define WLC_PROT_G_OVR 2 /* SPEC g prot override */ +#define WLC_PROT_G_USER 3 /* gmode specified by user */ +#define WLC_PROT_OVERLAP 4 /* overlap */ +#define WLC_PROT_N_USER 10 /* nmode specified by user */ +#define WLC_PROT_N_CFG 11 /* n protection */ +#define WLC_PROT_N_CFG_OVR 12 /* n protection override */ +#define WLC_PROT_N_NONGF 13 /* non-GF protection */ +#define WLC_PROT_N_NONGF_OVR 14 /* non-GF protection override */ +#define WLC_PROT_N_PAM_OVR 15 /* n preamble override */ +#define WLC_PROT_N_OBSS 16 /* non-HT OBSS present */ + +#define WLC_BITSCNT(x) bcm_bitcount((u8 *)&(x), sizeof(u8)) + +/* Maximum wait time for a MAC suspend */ +#define WLC_MAX_MAC_SUSPEND 83000 /* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */ + +/* Probe Response timeout - responses for probe requests older that this are tossed, zero to disable + */ +#define WLC_PRB_RESP_TIMEOUT 0 /* Disable probe response timeout */ + +/* transmit buffer max headroom for protocol headers */ +#define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN) + +/* For managing scan result lists */ +typedef struct wlc_bss_list { + uint count; + bool beacon; /* set for beacon, cleared for probe response */ + wlc_bss_info_t *ptrs[MAXBSS]; +} wlc_bss_list_t; + +#define SW_TIMER_MAC_STAT_UPD 30 /* periodic MAC stats update */ + +/* Double check that unsupported cores are not enabled */ +#if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV) +#error "Configuration for D11CONF includes unsupported versions." +#endif /* Bad versions */ + +#define VALID_COREREV(corerev) CONF_HAS(D11CONF, corerev) + +/* values for shortslot_override */ +#define WLC_SHORTSLOT_AUTO -1 /* Driver will manage Shortslot setting */ +#define WLC_SHORTSLOT_OFF 0 /* Turn off short slot */ +#define WLC_SHORTSLOT_ON 1 /* Turn on short slot */ + +/* value for short/long and mixmode/greenfield preamble */ + +#define WLC_LONG_PREAMBLE (0) +#define WLC_SHORT_PREAMBLE (1 << 0) +#define WLC_GF_PREAMBLE (1 << 1) +#define WLC_MM_PREAMBLE (1 << 2) +#define WLC_IS_MIMO_PREAMBLE(_pre) (((_pre) == WLC_GF_PREAMBLE) || ((_pre) == WLC_MM_PREAMBLE)) + +/* values for barker_preamble */ +#define WLC_BARKER_SHORT_ALLOWED 0 /* Short pre-amble allowed */ + +/* A fifo is full. Clear precedences related to that FIFO */ +#define WLC_TX_FIFO_CLEAR(wlc, fifo) ((wlc)->tx_prec_map &= ~(wlc)->fifo2prec_map[fifo]) + +/* Fifo is NOT full. Enable precedences for that FIFO */ +#define WLC_TX_FIFO_ENAB(wlc, fifo) ((wlc)->tx_prec_map |= (wlc)->fifo2prec_map[fifo]) + +/* TxFrameID */ +/* seq and frag bits: SEQNUM_SHIFT, FRAGNUM_MASK (802.11.h) */ +/* rate epoch bits: TXFID_RATE_SHIFT, TXFID_RATE_MASK ((wlc_rate.c) */ +#define TXFID_QUEUE_MASK 0x0007 /* Bits 0-2 */ +#define TXFID_SEQ_MASK 0x7FE0 /* Bits 5-15 */ +#define TXFID_SEQ_SHIFT 5 /* Number of bit shifts */ +#define TXFID_RATE_PROBE_MASK 0x8000 /* Bit 15 for rate probe */ +#define TXFID_RATE_MASK 0x0018 /* Mask for bits 3 and 4 */ +#define TXFID_RATE_SHIFT 3 /* Shift 3 bits for rate mask */ + +/* promote boardrev */ +#define BOARDREV_PROMOTABLE 0xFF /* from */ +#define BOARDREV_PROMOTED 1 /* to */ + +/* if wpa is in use then portopen is true when the group key is plumbed otherwise it is always true + */ +#define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) +#define WLC_SW_KEYS(wlc, bsscfg) ((((wlc)->wsec_swkeys) || \ + ((bsscfg)->wsec & WSEC_SWFLAG))) + +#define WLC_PORTOPEN(cfg) \ + (((cfg)->WPA_auth != WPA_AUTH_DISABLED && WSEC_ENABLED((cfg)->wsec)) ? \ + (cfg)->wsec_portopen : true) + +#define PS_ALLOWED(wlc) wlc_ps_allowed(wlc) +#define STAY_AWAKE(wlc) wlc_stay_awake(wlc) + +#define DATA_BLOCK_TX_SUPR (1 << 4) + +/* 802.1D Priority to TX FIFO number for wme */ +extern const u8 prio2fifo[]; + +/* Ucode MCTL_WAKE override bits */ +#define WLC_WAKE_OVERRIDE_CLKCTL 0x01 +#define WLC_WAKE_OVERRIDE_PHYREG 0x02 +#define WLC_WAKE_OVERRIDE_MACSUSPEND 0x04 +#define WLC_WAKE_OVERRIDE_TXFIFO 0x08 +#define WLC_WAKE_OVERRIDE_FORCEFAST 0x10 + +/* stuff pulled in from wlc.c */ + +/* Interrupt bit error summary. Don't include I_RU: we refill DMA at other + * times; and if we run out, constant I_RU interrupts may cause lockup. We + * will still get error counts from rx0ovfl. + */ +#define I_ERRORS (I_PC | I_PD | I_DE | I_RO | I_XU) +/* default software intmasks */ +#define DEF_RXINTMASK (I_RI) /* enable rx int on rxfifo only */ +#define DEF_MACINTMASK (MI_TXSTOP | MI_TBTT | MI_ATIMWINEND | MI_PMQ | \ + MI_PHYTXERR | MI_DMAINT | MI_TFS | MI_BG_NOISE | \ + MI_CCA | MI_TO | MI_GP0 | MI_RFDISABLE | MI_PWRUP) + +#define RETRY_SHORT_DEF 7 /* Default Short retry Limit */ +#define RETRY_SHORT_MAX 255 /* Maximum Short retry Limit */ +#define RETRY_LONG_DEF 4 /* Default Long retry count */ +#define RETRY_SHORT_FB 3 /* Short retry count for fallback rate */ +#define RETRY_LONG_FB 2 /* Long retry count for fallback rate */ + +#define MAXTXPKTS 6 /* max # pkts pending */ + +/* frameburst */ +#define MAXTXFRAMEBURST 8 /* vanilla xpress mode: max frames/burst */ +#define MAXFRAMEBURST_TXOP 10000 /* Frameburst TXOP in usec */ + +/* Per-AC retry limit register definitions; uses bcmdefs.h bitfield macros */ +#define EDCF_SHORT_S 0 +#define EDCF_SFB_S 4 +#define EDCF_LONG_S 8 +#define EDCF_LFB_S 12 +#define EDCF_SHORT_M BITFIELD_MASK(4) +#define EDCF_SFB_M BITFIELD_MASK(4) +#define EDCF_LONG_M BITFIELD_MASK(4) +#define EDCF_LFB_M BITFIELD_MASK(4) + +#define WLC_WME_RETRY_SHORT_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_SHORT) +#define WLC_WME_RETRY_SFB_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_SFB) +#define WLC_WME_RETRY_LONG_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_LONG) +#define WLC_WME_RETRY_LFB_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_LFB) + +#define WLC_WME_RETRY_SHORT_SET(wlc, ac, val) \ + (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SHORT, val)) +#define WLC_WME_RETRY_SFB_SET(wlc, ac, val) \ + (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SFB, val)) +#define WLC_WME_RETRY_LONG_SET(wlc, ac, val) \ + (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LONG, val)) +#define WLC_WME_RETRY_LFB_SET(wlc, ac, val) \ + (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LFB, val)) + +/* PLL requests */ +#define WLC_PLLREQ_SHARED 0x1 /* pll is shared on old chips */ +#define WLC_PLLREQ_RADIO_MON 0x2 /* hold pll for radio monitor register checking */ +#define WLC_PLLREQ_FLIP 0x4 /* hold/release pll for some short operation */ + +/* Do we support this rate? */ +#define VALID_RATE_DBG(wlc, rspec) wlc_valid_rate(wlc, rspec, WLC_BAND_AUTO, true) + +/* + * Macros to check if AP or STA is active. + * AP Active means more than just configured: driver and BSS are "up"; + * that is, we are beaconing/responding as an AP (aps_associated). + * STA Active similarly means the driver is up and a configured STA BSS + * is up: either associated (stas_associated) or trying. + * + * Macro definitions vary as per AP/STA ifdefs, allowing references to + * ifdef'd structure fields and constant values (0) for optimization. + * Make sure to enclose blocks of code such that any routines they + * reference can also be unused and optimized out by the linker. + */ +/* NOTE: References structure fields defined in wlc.h */ +#define AP_ACTIVE(wlc) (0) + +/* + * Detect Card removed. + * Even checking an sbconfig register read will not false trigger when the core is in reset. + * it breaks CF address mechanism. Accessing gphy phyversion will cause SB error if aphy + * is in reset on 4306B0-DB. Need a simple accessible reg with fixed 0/1 pattern + * (some platforms return all 0). + * If clocks are present, call the sb routine which will figure out if the device is removed. + */ +#define DEVICEREMOVED(wlc) \ + ((wlc->hw->clk) ? \ + ((R_REG(wlc->hw->osh, &wlc->hw->regs->maccontrol) & \ + (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN) : \ + (si_deviceremoved(wlc->hw->sih))) + +#define WLCWLUNIT(wlc) ((wlc)->pub->unit) + +typedef struct wlc_protection { + bool _g; /* use g spec protection, driver internal */ + s8 g_override; /* override for use of g spec protection */ + u8 gmode_user; /* user config gmode, operating band->gmode is different */ + s8 overlap; /* Overlap BSS/IBSS protection for both 11g and 11n */ + s8 nmode_user; /* user config nmode, operating pub->nmode is different */ + s8 n_cfg; /* use OFDM protection on MIMO frames */ + s8 n_cfg_override; /* override for use of N protection */ + bool nongf; /* non-GF present protection */ + s8 nongf_override; /* override for use of GF protection */ + s8 n_pam_override; /* override for preamble: MM or GF */ + bool n_obss; /* indicated OBSS Non-HT STA present */ + + uint longpre_detect_timeout; /* #sec until long preamble bcns gone */ + uint barker_detect_timeout; /* #sec until bcns signaling Barker long preamble */ + /* only is gone */ + uint ofdm_ibss_timeout; /* #sec until ofdm IBSS beacons gone */ + uint ofdm_ovlp_timeout; /* #sec until ofdm overlapping BSS bcns gone */ + uint nonerp_ibss_timeout; /* #sec until nonerp IBSS beacons gone */ + uint nonerp_ovlp_timeout; /* #sec until nonerp overlapping BSS bcns gone */ + uint g_ibss_timeout; /* #sec until bcns signaling Use_Protection gone */ + uint n_ibss_timeout; /* #sec until bcns signaling Use_OFDM_Protection gone */ + uint ht20in40_ovlp_timeout; /* #sec until 20MHz overlapping OPMODE gone */ + uint ht20in40_ibss_timeout; /* #sec until 20MHz-only HT station bcns gone */ + uint non_gf_ibss_timeout; /* #sec until non-GF bcns gone */ +} wlc_protection_t; + +/* anything affects the single/dual streams/antenna operation */ +typedef struct wlc_stf { + u8 hw_txchain; /* HW txchain bitmap cfg */ + u8 txchain; /* txchain bitmap being used */ + u8 txstreams; /* number of txchains being used */ + + u8 hw_rxchain; /* HW rxchain bitmap cfg */ + u8 rxchain; /* rxchain bitmap being used */ + u8 rxstreams; /* number of rxchains being used */ + + u8 ant_rx_ovr; /* rx antenna override */ + s8 txant; /* userTx antenna setting */ + u16 phytxant; /* phyTx antenna setting in txheader */ + + u8 ss_opmode; /* singlestream Operational mode, 0:siso; 1:cdd */ + bool ss_algosel_auto; /* if true, use wlc->stf->ss_algo_channel; */ + /* else use wlc->band->stf->ss_mode_band; */ + u16 ss_algo_channel; /* ss based on per-channel algo: 0: SISO, 1: CDD 2: STBC */ + u8 no_cddstbc; /* stf override, 1: no CDD (or STBC) allowed */ + + u8 rxchain_restore_delay; /* delay time to restore default rxchain */ + + s8 ldpc; /* AUTO/ON/OFF ldpc cap supported */ + u8 txcore[MAX_STREAMS_SUPPORTED + 1]; /* bitmap of selected core for each Nsts */ + s8 spatial_policy; +} wlc_stf_t; + +#define WLC_STF_SS_STBC_TX(wlc, scb) \ + (((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) || \ + (SCB_STBC_CAP((scb)) && \ + (wlc)->band->band_stf_stbc_tx == AUTO && \ + isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC)))) + +#define WLC_STBC_CAP_PHY(wlc) (WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3)) + +#define WLC_SGI_CAP_PHY(wlc) ((WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3)) || \ + WLCISLCNPHY(wlc->band)) + +#define WLC_CHAN_PHYTYPE(x) (((x) & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT) +#define WLC_CHAN_CHANNEL(x) (((x) & RXS_CHAN_ID_MASK) >> RXS_CHAN_ID_SHIFT) +#define WLC_RX_CHANNEL(rxh) (WLC_CHAN_CHANNEL((rxh)->RxChan)) + +/* wlc_bss_info flag bit values */ +#define WLC_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */ + +/* Flags used in wlc_txq_info.stopped */ +#define TXQ_STOP_FOR_PRIOFC_MASK 0x000000FF /* per prio flow control bits */ +#define TXQ_STOP_FOR_PKT_DRAIN 0x00000100 /* stop txq enqueue for packet drain */ +#define TXQ_STOP_FOR_AMPDU_FLOW_CNTRL 0x00000200 /* stop txq enqueue for ampdu flow control */ + +#define WLC_HT_WEP_RESTRICT 0x01 /* restrict HT with WEP */ +#define WLC_HT_TKIP_RESTRICT 0x02 /* restrict HT with TKIP */ + +/* + * core state (mac) + */ +struct wlccore { + uint coreidx; /* # sb enumerated core */ + + /* fifo */ + uint *txavail[NFIFO]; /* # tx descriptors available */ + s16 txpktpend[NFIFO]; /* tx admission control */ + + macstat_t *macstat_snapshot; /* mac hw prev read values */ +}; + +/* + * band state (phy+ana+radio) + */ +struct wlcband { + int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */ + uint bandunit; /* bandstate[] index */ + + u16 phytype; /* phytype */ + u16 phyrev; + u16 radioid; + u16 radiorev; + wlc_phy_t *pi; /* pointer to phy specific information */ + bool abgphy_encore; + + u8 gmode; /* currently active gmode (see wlioctl.h) */ + + struct scb *hwrs_scb; /* permanent scb for hw rateset */ + + wlc_rateset_t defrateset; /* band-specific copy of default_bss.rateset */ + + ratespec_t rspec_override; /* 802.11 rate override */ + ratespec_t mrspec_override; /* multicast rate override */ + u8 band_stf_ss_mode; /* Configured STF type, 0:siso; 1:cdd */ + s8 band_stf_stbc_tx; /* STBC TX 0:off; 1:force on; -1:auto */ + wlc_rateset_t hw_rateset; /* rates supported by chip (phy-specific) */ + u8 basic_rate[WLC_MAXRATE + 1]; /* basic rates indexed by rate */ + bool mimo_cap_40; /* 40 MHz cap enabled on this band */ + s8 antgain; /* antenna gain from srom */ + + u16 CWmin; /* The minimum size of contention window, in unit of aSlotTime */ + u16 CWmax; /* The maximum size of contention window, in unit of aSlotTime */ + u16 bcntsfoff; /* beacon tsf offset */ +}; + +/* generic function callback takes just one arg */ +typedef void (*cb_fn_t) (void *); + +/* tx completion callback takes 3 args */ +typedef void (*pkcb_fn_t) (struct wlc_info *wlc, uint txstatus, void *arg); + +typedef struct pkt_cb { + pkcb_fn_t fn; /* function to call when tx frame completes */ + void *arg; /* void arg for fn */ + u8 nextidx; /* index of next call back if threading */ + bool entered; /* recursion check */ +} pkt_cb_t; + + /* module control blocks */ +typedef struct modulecb { + char name[32]; /* module name : NULL indicates empty array member */ + const bcm_iovar_t *iovars; /* iovar table */ + void *hdl; /* handle passed when handler 'doiovar' is called */ + watchdog_fn_t watchdog_fn; /* watchdog handler */ + iovar_fn_t iovar_fn; /* iovar handler */ + down_fn_t down_fn; /* down handler. Note: the int returned + * by the down function is a count of the + * number of timers that could not be + * freed. + */ +} modulecb_t; + + /* dump control blocks */ +typedef struct dumpcb_s { + const char *name; /* dump name */ + dump_fn_t dump_fn; /* 'wl dump' handler */ + void *dump_fn_arg; + struct dumpcb_s *next; +} dumpcb_t; + +/* virtual interface */ +struct wlc_if { + struct wlc_if *next; + u8 type; /* WLC_IFTYPE_BSS or WLC_IFTYPE_WDS */ + u8 index; /* assigned in wl_add_if(), index of the wlif if any, + * not necessarily corresponding to bsscfg._idx or + * AID2PVBMAP(scb). + */ + u8 flags; /* flags for the interface */ + struct wl_if *wlif; /* pointer to wlif */ + struct wlc_txq_info *qi; /* pointer to associated tx queue */ + union { + struct scb *scb; /* pointer to scb if WLC_IFTYPE_WDS */ + struct wlc_bsscfg *bsscfg; /* pointer to bsscfg if WLC_IFTYPE_BSS */ + } u; +}; + +/* flags for the interface */ +#define WLC_IF_LINKED 0x02 /* this interface is linked to a wl_if */ + +typedef struct wlc_hwband { + int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */ + uint bandunit; /* bandstate[] index */ + u16 mhfs[MHFMAX]; /* MHF array shadow */ + u8 bandhw_stf_ss_mode; /* HW configured STF type, 0:siso; 1:cdd */ + u16 CWmin; + u16 CWmax; + u32 core_flags; + + u16 phytype; /* phytype */ + u16 phyrev; + u16 radioid; + u16 radiorev; + wlc_phy_t *pi; /* pointer to phy specific information */ + bool abgphy_encore; +} wlc_hwband_t; + +struct wlc_hw_info { + struct osl_info *osh; /* pointer to os handle */ + bool _piomode; /* true if pio mode */ + struct wlc_info *wlc; + + /* fifo */ + struct hnddma_pub *di[NFIFO]; /* hnddma handles, per fifo */ + + uint unit; /* device instance number */ + + /* version info */ + u16 vendorid; /* PCI vendor id */ + u16 deviceid; /* PCI device id */ + uint corerev; /* core revision */ + u8 sromrev; /* version # of the srom */ + u16 boardrev; /* version # of particular board */ + u32 boardflags; /* Board specific flags from srom */ + u32 boardflags2; /* More board flags if sromrev >= 4 */ + u32 machwcap; /* MAC capabilities (corerev >= 13) */ + u32 machwcap_backup; /* backup of machwcap (corerev >= 13) */ + u16 ucode_dbgsel; /* dbgsel for ucode debug(config gpio) */ + + si_t *sih; /* SB handle (cookie for siutils calls) */ + char *vars; /* "environment" name=value */ + uint vars_size; /* size of vars, free vars on detach */ + d11regs_t *regs; /* pointer to device registers */ + void *physhim; /* phy shim layer handler */ + void *phy_sh; /* pointer to shared phy state */ + wlc_hwband_t *band; /* pointer to active per-band state */ + wlc_hwband_t *bandstate[MAXBANDS]; /* per-band state (one per phy/radio) */ + u16 bmac_phytxant; /* cache of high phytxant state */ + bool shortslot; /* currently using 11g ShortSlot timing */ + u16 SRL; /* 802.11 dot11ShortRetryLimit */ + u16 LRL; /* 802.11 dot11LongRetryLimit */ + u16 SFBL; /* Short Frame Rate Fallback Limit */ + u16 LFBL; /* Long Frame Rate Fallback Limit */ + + bool up; /* d11 hardware up and running */ + uint now; /* # elapsed seconds */ + uint _nbands; /* # bands supported */ + chanspec_t chanspec; /* bmac chanspec shadow */ + + uint *txavail[NFIFO]; /* # tx descriptors available */ + u16 *xmtfifo_sz; /* fifo size in 256B for each xmt fifo */ + + mbool pllreq; /* pll requests to keep PLL on */ + + u8 suspended_fifos; /* Which TX fifo to remain awake for */ + u32 maccontrol; /* Cached value of maccontrol */ + uint mac_suspend_depth; /* current depth of mac_suspend levels */ + u32 wake_override; /* Various conditions to force MAC to WAKE mode */ + u32 mute_override; /* Prevent ucode from sending beacons */ + u8 etheraddr[ETH_ALEN]; /* currently configured ethernet address */ + u32 led_gpio_mask; /* LED GPIO Mask */ + bool noreset; /* true= do not reset hw, used by WLC_OUT */ + bool forcefastclk; /* true if the h/w is forcing the use of fast clk */ + bool clk; /* core is out of reset and has clock */ + bool sbclk; /* sb has clock */ + struct bmac_pmq *bmac_pmq; /* bmac PM states derived from ucode PMQ */ + bool phyclk; /* phy is out of reset and has clock */ + bool dma_lpbk; /* core is in DMA loopback */ + + bool ucode_loaded; /* true after ucode downloaded */ + + + u8 hw_stf_ss_opmode; /* STF single stream operation mode */ + u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic + * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board + */ + u32 antsel_avail; /* + * put struct antsel_info here if more info is + * needed + */ +}; + +/* TX Queue information + * + * Each flow of traffic out of the device has a TX Queue with independent + * flow control. Several interfaces may be associated with a single TX Queue + * if they belong to the same flow of traffic from the device. For multi-channel + * operation there are independent TX Queues for each channel. + */ +typedef struct wlc_txq_info { + struct wlc_txq_info *next; + struct pktq q; + uint stopped; /* tx flow control bits */ +} wlc_txq_info_t; + +/* + * Principal common (os-independent) software data structure. + */ +struct wlc_info { + struct wlc_pub *pub; /* pointer to wlc public state */ + struct osl_info *osh; /* pointer to os handle */ + struct wl_info *wl; /* pointer to os-specific private state */ + d11regs_t *regs; /* pointer to device registers */ + + struct wlc_hw_info *hw; /* HW related state used primarily by BMAC */ + + /* clock */ + int clkreq_override; /* setting for clkreq for PCIE : Auto, 0, 1 */ + u16 fastpwrup_dly; /* time in us needed to bring up d11 fast clock */ + + /* interrupt */ + u32 macintstatus; /* bit channel between isr and dpc */ + u32 macintmask; /* sw runtime master macintmask value */ + u32 defmacintmask; /* default "on" macintmask value */ + + /* up and down */ + bool device_present; /* (removable) device is present */ + + bool clk; /* core is out of reset and has clock */ + + /* multiband */ + struct wlccore *core; /* pointer to active io core */ + struct wlcband *band; /* pointer to active per-band state */ + struct wlccore *corestate; /* per-core state (one per hw core) */ + /* per-band state (one per phy/radio): */ + struct wlcband *bandstate[MAXBANDS]; + + bool war16165; /* PCI slow clock 16165 war flag */ + + bool tx_suspended; /* data fifos need to remain suspended */ + + uint txpend16165war; + + /* packet queue */ + uint qvalid; /* DirFrmQValid and BcMcFrmQValid */ + + /* Regulatory power limits */ + s8 txpwr_local_max; /* regulatory local txpwr max */ + u8 txpwr_local_constraint; /* local power contraint in dB */ + + + struct ampdu_info *ampdu; /* ampdu module handler */ + struct antsel_info *asi; /* antsel module handler */ + wlc_cm_info_t *cmi; /* channel manager module handler */ + + void *btparam; /* bus type specific cookie */ + + uint vars_size; /* size of vars, free vars on detach */ + + u16 vendorid; /* PCI vendor id */ + u16 deviceid; /* PCI device id */ + uint ucode_rev; /* microcode revision */ + + u32 machwcap; /* MAC capabilities, BMAC shadow */ + + u8 perm_etheraddr[ETH_ALEN]; /* original sprom local ethernet address */ + + bool bandlocked; /* disable auto multi-band switching */ + bool bandinit_pending; /* track band init in auto band */ + + bool radio_monitor; /* radio timer is running */ + bool down_override; /* true=down */ + bool going_down; /* down path intermediate variable */ + + bool mpc; /* enable minimum power consumption */ + u8 mpc_dlycnt; /* # of watchdog cnt before turn disable radio */ + u8 mpc_offcnt; /* # of watchdog cnt that radio is disabled */ + u8 mpc_delay_off; /* delay radio disable by # of watchdog cnt */ + u8 prev_non_delay_mpc; /* prev state wlc_is_non_delay_mpc */ + + /* timer */ + struct wl_timer *wdtimer; /* timer for watchdog routine */ + uint fast_timer; /* Periodic timeout for 'fast' timer */ + uint slow_timer; /* Periodic timeout for 'slow' timer */ + uint glacial_timer; /* Periodic timeout for 'glacial' timer */ + uint phycal_mlo; /* last time measurelow calibration was done */ + uint phycal_txpower; /* last time txpower calibration was done */ + + struct wl_timer *radio_timer; /* timer for hw radio button monitor routine */ + struct wl_timer *pspoll_timer; /* periodic pspoll timer */ + + /* promiscuous */ + bool monitor; /* monitor (MPDU sniffing) mode */ + bool bcnmisc_ibss; /* bcns promisc mode override for IBSS */ + bool bcnmisc_scan; /* bcns promisc mode override for scan */ + bool bcnmisc_monitor; /* bcns promisc mode override for monitor */ + + u8 bcn_wait_prd; /* max waiting period (for beacon) in 1024TU */ + + /* driver feature */ + bool _rifs; /* enable per-packet rifs */ + s32 rifs_advert; /* RIFS mode advertisement */ + s8 sgi_tx; /* sgi tx */ + bool wet; /* true if wireless ethernet bridging mode */ + + /* AP-STA synchronization, power save */ + bool check_for_unaligned_tbtt; /* check unaligned tbtt flag */ + bool PM_override; /* no power-save flag, override PM(user input) */ + bool PMenabled; /* current power-management state (CAM or PS) */ + bool PMpending; /* waiting for tx status with PM indicated set */ + bool PMblocked; /* block any PSPolling in PS mode, used to buffer + * AP traffic, also used to indicate in progress + * of scan, rm, etc. off home channel activity. + */ + bool PSpoll; /* whether there is an outstanding PS-Poll frame */ + u8 PM; /* power-management mode (CAM, PS or FASTPS) */ + bool PMawakebcn; /* bcn recvd during current waking state */ + + bool WME_PM_blocked; /* Can STA go to PM when in WME Auto mode */ + bool wake; /* host-specified PS-mode sleep state */ + u8 pspoll_prd; /* pspoll interval in milliseconds */ + u8 bcn_li_bcn; /* beacon listen interval in # beacons */ + u8 bcn_li_dtim; /* beacon listen interval in # dtims */ + + bool WDarmed; /* watchdog timer is armed */ + u32 WDlast; /* last time wlc_watchdog() was called */ + + /* WME */ + ac_bitmap_t wme_dp; /* Discard (oldest first) policy per AC */ + bool wme_apsd; /* enable Advanced Power Save Delivery */ + ac_bitmap_t wme_admctl; /* bit i set if AC i under admission control */ + u16 edcf_txop[AC_COUNT]; /* current txop for each ac */ + wme_param_ie_t wme_param_ie; /* WME parameter info element, which on STA + * contains parameters in use locally, and on + * AP contains parameters advertised to STA + * in beacons and assoc responses. + */ + bool wme_prec_queuing; /* enable/disable non-wme STA prec queuing */ + u16 wme_retries[AC_COUNT]; /* per-AC retry limits */ + + int vlan_mode; /* OK to use 802.1Q Tags (ON, OFF, AUTO) */ + u16 tx_prec_map; /* Precedence map based on HW FIFO space */ + u16 fifo2prec_map[NFIFO]; /* pointer to fifo2_prec map based on WME */ + + /* BSS Configurations */ + wlc_bsscfg_t *bsscfg[WLC_MAXBSSCFG]; /* set of BSS configurations, idx 0 is default and + * always valid + */ + wlc_bsscfg_t *cfg; /* the primary bsscfg (can be AP or STA) */ + u8 stas_associated; /* count of ASSOCIATED STA bsscfgs */ + u8 aps_associated; /* count of UP AP bsscfgs */ + u8 block_datafifo; /* prohibit posting frames to data fifos */ + bool bcmcfifo_drain; /* TX_BCMC_FIFO is set to drain */ + + /* tx queue */ + wlc_txq_info_t *tx_queues; /* common TX Queue list */ + + /* event */ + wlc_eventq_t *eventq; /* event queue for deferred processing */ + + /* security */ + wsec_key_t *wsec_keys[WSEC_MAX_KEYS]; /* dynamic key storage */ + wsec_key_t *wsec_def_keys[WLC_DEFAULT_KEYS]; /* default key storage */ + bool wsec_swkeys; /* indicates that all keys should be + * treated as sw keys (used for debugging) + */ + modulecb_t *modulecb; + dumpcb_t *dumpcb_head; + + u8 mimoft; /* SIGN or 11N */ + u8 mimo_band_bwcap; /* bw cap per band type */ + s8 txburst_limit_override; /* tx burst limit override */ + u16 txburst_limit; /* tx burst limit value */ + s8 cck_40txbw; /* 11N, cck tx b/w override when in 40MHZ mode */ + s8 ofdm_40txbw; /* 11N, ofdm tx b/w override when in 40MHZ mode */ + s8 mimo_40txbw; /* 11N, mimo tx b/w override when in 40MHZ mode */ + /* HT CAP IE being advertised by this node: */ + struct ieee80211_ht_cap ht_cap; + + uint seckeys; /* 54 key table shm address */ + uint tkmickeys; /* 12 TKIP MIC key table shm address */ + + wlc_bss_info_t *default_bss; /* configured BSS parameters */ + + u16 AID; /* association ID */ + u16 counter; /* per-sdu monotonically increasing counter */ + u16 mc_fid_counter; /* BC/MC FIFO frame ID counter */ + + bool ibss_allowed; /* false, all IBSS will be ignored during a scan + * and the driver will not allow the creation of + * an IBSS network + */ + bool ibss_coalesce_allowed; + + char country_default[WLC_CNTRY_BUF_SZ]; /* saved country for leaving 802.11d + * auto-country mode + */ + char autocountry_default[WLC_CNTRY_BUF_SZ]; /* initial country for 802.11d + * auto-country mode + */ +#ifdef BCMDBG + bcm_tlv_t *country_ie_override; /* debug override of announced Country IE */ +#endif + + u16 prb_resp_timeout; /* do not send prb resp if request older than this, + * 0 = disable + */ + + wlc_rateset_t sup_rates_override; /* use only these rates in 11g supported rates if + * specifed + */ + + chanspec_t home_chanspec; /* shared home chanspec */ + + /* PHY parameters */ + chanspec_t chanspec; /* target operational channel */ + u16 usr_fragthresh; /* user configured fragmentation threshold */ + u16 fragthresh[NFIFO]; /* per-fifo fragmentation thresholds */ + u16 RTSThresh; /* 802.11 dot11RTSThreshold */ + u16 SRL; /* 802.11 dot11ShortRetryLimit */ + u16 LRL; /* 802.11 dot11LongRetryLimit */ + u16 SFBL; /* Short Frame Rate Fallback Limit */ + u16 LFBL; /* Long Frame Rate Fallback Limit */ + + /* network config */ + bool shortpreamble; /* currently operating with CCK ShortPreambles */ + bool shortslot; /* currently using 11g ShortSlot timing */ + s8 barker_preamble; /* current Barker Preamble Mode */ + s8 shortslot_override; /* 11g ShortSlot override */ + bool include_legacy_erp; /* include Legacy ERP info elt ID 47 as well as g ID 42 */ + bool barker_overlap_control; /* true: be aware of overlapping BSSs for barker */ + bool ignore_bcns; /* override: ignore non shortslot bcns in a 11g network */ + bool legacy_probe; /* restricts probe requests to CCK rates */ + + wlc_protection_t *protection; + s8 PLCPHdr_override; /* 802.11b Preamble Type override */ + + wlc_stf_t *stf; + + pkt_cb_t *pkt_callback; /* tx completion callback handlers */ + + u32 txretried; /* tx retried number in one msdu */ + + ratespec_t bcn_rspec; /* save bcn ratespec purpose */ + + bool apsd_sta_usp; /* Unscheduled Service Period in progress on STA */ + struct wl_timer *apsd_trigger_timer; /* timer for wme apsd trigger frames */ + u32 apsd_trigger_timeout; /* timeout value for apsd_trigger_timer (in ms) + * 0 == disable + */ + ac_bitmap_t apsd_trigger_ac; /* Permissible Acess Category in which APSD Null + * Trigger frames can be send + */ + u8 htphy_membership; /* HT PHY membership */ + + bool _regulatory_domain; /* 802.11d enabled? */ + + u8 mimops_PM; + + u8 txpwr_percent; /* power output percentage */ + + u8 ht_wsec_restriction; /* the restriction of HT with TKIP or WEP */ + + uint tempsense_lasttime; + + u16 tx_duty_cycle_ofdm; /* maximum allowed duty cycle for OFDM */ + u16 tx_duty_cycle_cck; /* maximum allowed duty cycle for CCK */ + + u16 next_bsscfg_ID; + + struct wlc_if *wlcif_list; /* linked list of wlc_if structs */ + wlc_txq_info_t *active_queue; /* txq for the currently active transmit context */ + u32 mpc_dur; /* total time (ms) in mpc mode except for the + * portion since radio is turned off last time + */ + u32 mpc_laston_ts; /* timestamp (ms) when radio is turned off last + * time + */ + bool pr80838_war; + uint hwrxoff; +}; + +/* antsel module specific state */ +struct antsel_info { + struct wlc_info *wlc; /* pointer to main wlc structure */ + struct wlc_pub *pub; /* pointer to public fn */ + u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic + * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board + */ + u8 antsel_antswitch; /* board level antenna switch type */ + bool antsel_avail; /* Ant selection availability (SROM based) */ + wlc_antselcfg_t antcfg_11n; /* antenna configuration */ + wlc_antselcfg_t antcfg_cur; /* current antenna config (auto) */ +}; + +#define CHANNEL_BANDUNIT(wlc, ch) (((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX) +#define OTHERBANDUNIT(wlc) ((uint)((wlc)->band->bandunit ? BAND_2G_INDEX : BAND_5G_INDEX)) + +#define IS_MBAND_UNLOCKED(wlc) \ + ((NBANDS(wlc) > 1) && !(wlc)->bandlocked) + +#define WLC_BAND_PI_RADIO_CHANSPEC wlc_phy_chanspec_get(wlc->band->pi) + +/* sum the individual fifo tx pending packet counts */ +#define TXPKTPENDTOT(wlc) ((wlc)->core->txpktpend[0] + (wlc)->core->txpktpend[1] + \ + (wlc)->core->txpktpend[2] + (wlc)->core->txpktpend[3]) +#define TXPKTPENDGET(wlc, fifo) ((wlc)->core->txpktpend[(fifo)]) +#define TXPKTPENDINC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] += (val)) +#define TXPKTPENDDEC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] -= (val)) +#define TXPKTPENDCLR(wlc, fifo) ((wlc)->core->txpktpend[(fifo)] = 0) +#define TXAVAIL(wlc, fifo) (*(wlc)->core->txavail[(fifo)]) +#define GETNEXTTXP(wlc, _queue) \ + dma_getnexttxp((wlc)->hw->di[(_queue)], HNDDMA_RANGE_TRANSMITTED) + +#define WLC_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \ + ((len1 == len2) && !memcmp(ssid1, ssid2, len1)) + +extern void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus); +extern void wlc_fatal_error(struct wlc_info *wlc); +extern void wlc_bmac_rpc_watchdog(struct wlc_info *wlc); +extern void wlc_recv(struct wlc_info *wlc, struct sk_buff *p); +extern bool wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2); +extern void wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, + bool commit, s8 txpktpend); +extern void wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend); +extern void wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, + uint prec); +extern void wlc_info_init(struct wlc_info *wlc, int unit); +extern void wlc_print_txstatus(tx_status_t *txs); +extern int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks); +extern void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len, + void *buf); +extern void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len, + bool both); +#if defined(BCMDBG) +extern void wlc_get_rcmta(struct wlc_info *wlc, int idx, + u8 *addr); +#endif +extern void wlc_set_rcmta(struct wlc_info *wlc, int idx, + const u8 *addr); +extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, + const u8 *addr); +extern void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, + u32 *tsf_h_ptr); +extern void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin); +extern void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax); +extern void wlc_fifoerrors(struct wlc_info *wlc); +extern void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit); +extern void wlc_reset_bmac_done(struct wlc_info *wlc); +extern void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val); +extern void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us); +extern void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc); + +#if defined(BCMDBG) +extern void wlc_print_rxh(d11rxhdr_t *rxh); +extern void wlc_print_hdrs(struct wlc_info *wlc, const char *prefix, u8 *frame, + d11txh_t *txh, d11rxhdr_t *rxh, uint len); +extern void wlc_print_txdesc(d11txh_t *txh); +#endif +#if defined(BCMDBG) +extern void wlc_print_dot11_mac_hdr(u8 *buf, int len); +#endif + +extern void wlc_setxband(struct wlc_hw_info *wlc_hw, uint bandunit); +extern void wlc_coredisable(struct wlc_hw_info *wlc_hw); + +extern bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rate, int band, + bool verbose); +extern void wlc_ap_upd(struct wlc_info *wlc); + +/* helper functions */ +extern void wlc_shm_ssid_upd(struct wlc_info *wlc, wlc_bsscfg_t *cfg); +extern int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config); + +extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc); +extern void wlc_mac_bcn_promisc(struct wlc_info *wlc); +extern void wlc_mac_promisc(struct wlc_info *wlc); +extern void wlc_txflowcontrol(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, + int prio); +extern void wlc_txflowcontrol_override(struct wlc_info *wlc, wlc_txq_info_t *qi, + bool on, uint override); +extern bool wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, + wlc_txq_info_t *qi, int prio); +extern void wlc_send_q(struct wlc_info *wlc, wlc_txq_info_t *qi); +extern int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifo); + +extern u16 wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, + uint mac_len); +extern ratespec_t wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, + bool use_rspec, u16 mimo_ctlchbw); +extern u16 wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, + ratespec_t rts_rate, ratespec_t frame_rate, + u8 rts_preamble_type, + u8 frame_preamble_type, uint frame_len, + bool ba); + +extern void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs); + +#if defined(BCMDBG) +extern void wlc_dump_ie(struct wlc_info *wlc, bcm_tlv_t *ie, + struct bcmstrbuf *b); +#endif + +extern bool wlc_ps_check(struct wlc_info *wlc); +extern void wlc_reprate_init(struct wlc_info *wlc); +extern void wlc_bsscfg_reprate_init(wlc_bsscfg_t *bsscfg); +extern void wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, + u32 b_low); +extern u32 wlc_calc_tbtt_offset(u32 bi, u32 tsf_h, u32 tsf_l); + +/* Shared memory access */ +extern void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v); +extern u16 wlc_read_shm(struct wlc_info *wlc, uint offset); +extern void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len); +extern void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, + int len); +extern void wlc_copyfrom_shm(struct wlc_info *wlc, uint offset, void *buf, + int len); + +extern void wlc_update_beacon(struct wlc_info *wlc); +extern void wlc_bss_update_beacon(struct wlc_info *wlc, + struct wlc_bsscfg *bsscfg); + +extern void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend); +extern void wlc_bss_update_probe_resp(struct wlc_info *wlc, wlc_bsscfg_t *cfg, + bool suspend); + +extern bool wlc_ismpc(struct wlc_info *wlc); +extern bool wlc_is_non_delay_mpc(struct wlc_info *wlc); +extern void wlc_radio_mpc_upd(struct wlc_info *wlc); +extern bool wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, + int prec); +extern bool wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, + struct sk_buff *pkt, int prec, bool head); +extern u16 wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec); +extern void wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rate, uint length, + u8 *plcp); +extern uint wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, + u8 preamble_type, uint mac_len); + +extern void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec); + +extern bool wlc_timers_init(struct wlc_info *wlc, int unit); + +extern const bcm_iovar_t wlc_iovars[]; + +extern int wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, + const char *name, void *params, uint p_len, void *arg, + int len, int val_size, struct wlc_if *wlcif); + +#if defined(BCMDBG) +extern void wlc_print_ies(struct wlc_info *wlc, u8 *ies, uint ies_len); +#endif + +extern int wlc_set_nmode(struct wlc_info *wlc, s32 nmode); +extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode); +extern void wlc_mimops_action_ht_send(struct wlc_info *wlc, + wlc_bsscfg_t *bsscfg, u8 mimops_mode); + +extern void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot); +extern void wlc_set_bssid(wlc_bsscfg_t *cfg); +extern void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend); + +extern void wlc_set_ratetable(struct wlc_info *wlc); +extern int wlc_set_mac(wlc_bsscfg_t *cfg); +extern void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, + ratespec_t bcn_rate); +extern void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len); +extern ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, + wlc_rateset_t *rs); +extern u16 wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec, + bool short_preamble, bool phydelay); +extern void wlc_radio_disable(struct wlc_info *wlc); +extern void wlc_bcn_li_upd(struct wlc_info *wlc); + +extern int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len); +extern void wlc_out(struct wlc_info *wlc); +extern void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec); +extern void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt); +extern bool wlc_ps_allowed(struct wlc_info *wlc); +extern bool wlc_stay_awake(struct wlc_info *wlc); +extern void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe); + +extern void wlc_bss_list_free(struct wlc_info *wlc, wlc_bss_list_t *bss_list); +extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode); +#endif /* _wlc_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c new file mode 100644 index 000000000000..8bd4ede4c92a --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This is "two-way" interface, acting as the SHIM layer between WL and PHY layer. + * WL driver can optinally call this translation layer to do some preprocessing, then reach PHY. + * On the PHY->WL driver direction, all calls go through this layer since PHY doesn't have the + * access to wlc_hw pointer. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +/* PHY SHIM module specific state */ +struct wlc_phy_shim_info { + struct wlc_hw_info *wlc_hw; /* pointer to main wlc_hw structure */ + void *wlc; /* pointer to main wlc structure */ + void *wl; /* pointer to os-specific private state */ +}; + +wlc_phy_shim_info_t *wlc_phy_shim_attach(struct wlc_hw_info *wlc_hw, + void *wl, void *wlc) { + wlc_phy_shim_info_t *physhim = NULL; + + physhim = kzalloc(sizeof(wlc_phy_shim_info_t), GFP_ATOMIC); + if (!physhim) { + WL_ERROR("wl%d: wlc_phy_shim_attach: out of mem\n", + wlc_hw->unit); + return NULL; + } + physhim->wlc_hw = wlc_hw; + physhim->wlc = wlc; + physhim->wl = wl; + + return physhim; +} + +void wlc_phy_shim_detach(wlc_phy_shim_info_t *physhim) +{ + if (!physhim) + return; + + kfree(physhim); +} + +struct wlapi_timer *wlapi_init_timer(wlc_phy_shim_info_t *physhim, + void (*fn) (void *arg), void *arg, + const char *name) +{ + return (struct wlapi_timer *)wl_init_timer(physhim->wl, fn, arg, name); +} + +void wlapi_free_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t) +{ + wl_free_timer(physhim->wl, (struct wl_timer *)t); +} + +void +wlapi_add_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t, uint ms, + int periodic) +{ + wl_add_timer(physhim->wl, (struct wl_timer *)t, ms, periodic); +} + +bool wlapi_del_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t) +{ + return wl_del_timer(physhim->wl, (struct wl_timer *)t); +} + +void wlapi_intrson(wlc_phy_shim_info_t *physhim) +{ + wl_intrson(physhim->wl); +} + +u32 wlapi_intrsoff(wlc_phy_shim_info_t *physhim) +{ + return wl_intrsoff(physhim->wl); +} + +void wlapi_intrsrestore(wlc_phy_shim_info_t *physhim, u32 macintmask) +{ + wl_intrsrestore(physhim->wl, macintmask); +} + +void wlapi_bmac_write_shm(wlc_phy_shim_info_t *physhim, uint offset, u16 v) +{ + wlc_bmac_write_shm(physhim->wlc_hw, offset, v); +} + +u16 wlapi_bmac_read_shm(wlc_phy_shim_info_t *physhim, uint offset) +{ + return wlc_bmac_read_shm(physhim->wlc_hw, offset); +} + +void +wlapi_bmac_mhf(wlc_phy_shim_info_t *physhim, u8 idx, u16 mask, + u16 val, int bands) +{ + wlc_bmac_mhf(physhim->wlc_hw, idx, mask, val, bands); +} + +void wlapi_bmac_corereset(wlc_phy_shim_info_t *physhim, u32 flags) +{ + wlc_bmac_corereset(physhim->wlc_hw, flags); +} + +void wlapi_suspend_mac_and_wait(wlc_phy_shim_info_t *physhim) +{ + wlc_suspend_mac_and_wait(physhim->wlc); +} + +void wlapi_switch_macfreq(wlc_phy_shim_info_t *physhim, u8 spurmode) +{ + wlc_bmac_switch_macfreq(physhim->wlc_hw, spurmode); +} + +void wlapi_enable_mac(wlc_phy_shim_info_t *physhim) +{ + wlc_enable_mac(physhim->wlc); +} + +void wlapi_bmac_mctrl(wlc_phy_shim_info_t *physhim, u32 mask, u32 val) +{ + wlc_bmac_mctrl(physhim->wlc_hw, mask, val); +} + +void wlapi_bmac_phy_reset(wlc_phy_shim_info_t *physhim) +{ + wlc_bmac_phy_reset(physhim->wlc_hw); +} + +void wlapi_bmac_bw_set(wlc_phy_shim_info_t *physhim, u16 bw) +{ + wlc_bmac_bw_set(physhim->wlc_hw, bw); +} + +u16 wlapi_bmac_get_txant(wlc_phy_shim_info_t *physhim) +{ + return wlc_bmac_get_txant(physhim->wlc_hw); +} + +void wlapi_bmac_phyclk_fgc(wlc_phy_shim_info_t *physhim, bool clk) +{ + wlc_bmac_phyclk_fgc(physhim->wlc_hw, clk); +} + +void wlapi_bmac_macphyclk_set(wlc_phy_shim_info_t *physhim, bool clk) +{ + wlc_bmac_macphyclk_set(physhim->wlc_hw, clk); +} + +void wlapi_bmac_core_phypll_ctl(wlc_phy_shim_info_t *physhim, bool on) +{ + wlc_bmac_core_phypll_ctl(physhim->wlc_hw, on); +} + +void wlapi_bmac_core_phypll_reset(wlc_phy_shim_info_t *physhim) +{ + wlc_bmac_core_phypll_reset(physhim->wlc_hw); +} + +void wlapi_bmac_ucode_wake_override_phyreg_set(wlc_phy_shim_info_t *physhim) +{ + wlc_ucode_wake_override_set(physhim->wlc_hw, WLC_WAKE_OVERRIDE_PHYREG); +} + +void wlapi_bmac_ucode_wake_override_phyreg_clear(wlc_phy_shim_info_t *physhim) +{ + wlc_ucode_wake_override_clear(physhim->wlc_hw, + WLC_WAKE_OVERRIDE_PHYREG); +} + +void +wlapi_bmac_write_template_ram(wlc_phy_shim_info_t *physhim, int offset, + int len, void *buf) +{ + wlc_bmac_write_template_ram(physhim->wlc_hw, offset, len, buf); +} + +u16 wlapi_bmac_rate_shm_offset(wlc_phy_shim_info_t *physhim, u8 rate) +{ + return wlc_bmac_rate_shm_offset(physhim->wlc_hw, rate); +} + +void wlapi_ucode_sample_init(wlc_phy_shim_info_t *physhim) +{ +} + +void +wlapi_copyfrom_objmem(wlc_phy_shim_info_t *physhim, uint offset, void *buf, + int len, u32 sel) +{ + wlc_bmac_copyfrom_objmem(physhim->wlc_hw, offset, buf, len, sel); +} + +void +wlapi_copyto_objmem(wlc_phy_shim_info_t *physhim, uint offset, const void *buf, + int l, u32 sel) +{ + wlc_bmac_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel); +} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h new file mode 100644 index 000000000000..c151a5d8c693 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_phy_shim_h_ +#define _wlc_phy_shim_h_ + +#define RADAR_TYPE_NONE 0 /* Radar type None */ +#define RADAR_TYPE_ETSI_1 1 /* ETSI 1 Radar type */ +#define RADAR_TYPE_ETSI_2 2 /* ETSI 2 Radar type */ +#define RADAR_TYPE_ETSI_3 3 /* ETSI 3 Radar type */ +#define RADAR_TYPE_ITU_E 4 /* ITU E Radar type */ +#define RADAR_TYPE_ITU_K 5 /* ITU K Radar type */ +#define RADAR_TYPE_UNCLASSIFIED 6 /* Unclassified Radar type */ +#define RADAR_TYPE_BIN5 7 /* long pulse radar type */ +#define RADAR_TYPE_STG2 8 /* staggered-2 radar */ +#define RADAR_TYPE_STG3 9 /* staggered-3 radar */ +#define RADAR_TYPE_FRA 10 /* French radar */ + +/* French radar pulse widths */ +#define FRA_T1_20MHZ 52770 +#define FRA_T2_20MHZ 61538 +#define FRA_T3_20MHZ 66002 +#define FRA_T1_40MHZ 105541 +#define FRA_T2_40MHZ 123077 +#define FRA_T3_40MHZ 132004 +#define FRA_ERR_20MHZ 60 +#define FRA_ERR_40MHZ 120 + +#define ANTSEL_NA 0 /* No boardlevel selection available */ +#define ANTSEL_2x4 1 /* 2x4 boardlevel selection available */ +#define ANTSEL_2x3 2 /* 2x3 CB2 boardlevel selection available */ + +/* Rx Antenna diversity control values */ +#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */ +#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */ +#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */ +#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */ +#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */ +#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */ + +/* Forward declarations */ +struct wlc_hw_info; +typedef struct wlc_phy_shim_info wlc_phy_shim_info_t; + +extern wlc_phy_shim_info_t *wlc_phy_shim_attach(struct wlc_hw_info *wlc_hw, + void *wl, void *wlc); +extern void wlc_phy_shim_detach(wlc_phy_shim_info_t *physhim); + +/* PHY to WL utility functions */ +struct wlapi_timer; +extern struct wlapi_timer *wlapi_init_timer(wlc_phy_shim_info_t *physhim, + void (*fn) (void *arg), void *arg, + const char *name); +extern void wlapi_free_timer(wlc_phy_shim_info_t *physhim, + struct wlapi_timer *t); +extern void wlapi_add_timer(wlc_phy_shim_info_t *physhim, + struct wlapi_timer *t, uint ms, int periodic); +extern bool wlapi_del_timer(wlc_phy_shim_info_t *physhim, + struct wlapi_timer *t); +extern void wlapi_intrson(wlc_phy_shim_info_t *physhim); +extern u32 wlapi_intrsoff(wlc_phy_shim_info_t *physhim); +extern void wlapi_intrsrestore(wlc_phy_shim_info_t *physhim, + u32 macintmask); + +extern void wlapi_bmac_write_shm(wlc_phy_shim_info_t *physhim, uint offset, + u16 v); +extern u16 wlapi_bmac_read_shm(wlc_phy_shim_info_t *physhim, uint offset); +extern void wlapi_bmac_mhf(wlc_phy_shim_info_t *physhim, u8 idx, + u16 mask, u16 val, int bands); +extern void wlapi_bmac_corereset(wlc_phy_shim_info_t *physhim, u32 flags); +extern void wlapi_suspend_mac_and_wait(wlc_phy_shim_info_t *physhim); +extern void wlapi_switch_macfreq(wlc_phy_shim_info_t *physhim, u8 spurmode); +extern void wlapi_enable_mac(wlc_phy_shim_info_t *physhim); +extern void wlapi_bmac_mctrl(wlc_phy_shim_info_t *physhim, u32 mask, + u32 val); +extern void wlapi_bmac_phy_reset(wlc_phy_shim_info_t *physhim); +extern void wlapi_bmac_bw_set(wlc_phy_shim_info_t *physhim, u16 bw); +extern void wlapi_bmac_phyclk_fgc(wlc_phy_shim_info_t *physhim, bool clk); +extern void wlapi_bmac_macphyclk_set(wlc_phy_shim_info_t *physhim, bool clk); +extern void wlapi_bmac_core_phypll_ctl(wlc_phy_shim_info_t *physhim, bool on); +extern void wlapi_bmac_core_phypll_reset(wlc_phy_shim_info_t *physhim); +extern void wlapi_bmac_ucode_wake_override_phyreg_set(wlc_phy_shim_info_t * + physhim); +extern void wlapi_bmac_ucode_wake_override_phyreg_clear(wlc_phy_shim_info_t * + physhim); +extern void wlapi_bmac_write_template_ram(wlc_phy_shim_info_t *physhim, int o, + int len, void *buf); +extern u16 wlapi_bmac_rate_shm_offset(wlc_phy_shim_info_t *physhim, + u8 rate); +extern void wlapi_ucode_sample_init(wlc_phy_shim_info_t *physhim); +extern void wlapi_copyfrom_objmem(wlc_phy_shim_info_t *physhim, uint, + void *buf, int, u32 sel); +extern void wlapi_copyto_objmem(wlc_phy_shim_info_t *physhim, uint, + const void *buf, int, u32); + +extern void wlapi_high_update_phy_mode(wlc_phy_shim_info_t *physhim, + u32 phy_mode); +extern u16 wlapi_bmac_get_txant(wlc_phy_shim_info_t *physhim); +#endif /* _wlc_phy_shim_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h new file mode 100644 index 000000000000..23e99685d548 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h @@ -0,0 +1,624 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_pub_h_ +#define _wlc_pub_h_ + +#include +#include + +#define WLC_NUMRATES 16 /* max # of rates in a rateset */ +#define MAXMULTILIST 32 /* max # multicast addresses */ +#define D11_PHY_HDR_LEN 6 /* Phy header length - 6 bytes */ + +/* phy types */ +#define PHY_TYPE_A 0 /* Phy type A */ +#define PHY_TYPE_G 2 /* Phy type G */ +#define PHY_TYPE_N 4 /* Phy type N */ +#define PHY_TYPE_LP 5 /* Phy type Low Power A/B/G */ +#define PHY_TYPE_SSN 6 /* Phy type Single Stream N */ +#define PHY_TYPE_LCN 8 /* Phy type Single Stream N */ +#define PHY_TYPE_LCNXN 9 /* Phy type 2-stream N */ +#define PHY_TYPE_HT 7 /* Phy type 3-Stream N */ + +/* bw */ +#define WLC_10_MHZ 10 /* 10Mhz nphy channel bandwidth */ +#define WLC_20_MHZ 20 /* 20Mhz nphy channel bandwidth */ +#define WLC_40_MHZ 40 /* 40Mhz nphy channel bandwidth */ + +#define CHSPEC_WLC_BW(chanspec) (CHSPEC_IS40(chanspec) ? WLC_40_MHZ : \ + CHSPEC_IS20(chanspec) ? WLC_20_MHZ : \ + WLC_10_MHZ) + +#define WLC_RSSI_MINVAL -200 /* Low value, e.g. for forcing roam */ +#define WLC_RSSI_NO_SIGNAL -91 /* NDIS RSSI link quality cutoffs */ +#define WLC_RSSI_VERY_LOW -80 /* Very low quality cutoffs */ +#define WLC_RSSI_LOW -70 /* Low quality cutoffs */ +#define WLC_RSSI_GOOD -68 /* Good quality cutoffs */ +#define WLC_RSSI_VERY_GOOD -58 /* Very good quality cutoffs */ +#define WLC_RSSI_EXCELLENT -57 /* Excellent quality cutoffs */ + +#define WLC_PHYTYPE(_x) (_x) /* macro to perform WLC PHY -> D11 PHY TYPE, currently 1:1 */ + +#define MA_WINDOW_SZ 8 /* moving average window size */ + +#define WLC_SNR_INVALID 0 /* invalid SNR value */ + +/* a large TX Power as an init value to factor out of min() calculations, + * keep low enough to fit in an s8, units are .25 dBm + */ +#define WLC_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */ + +/* legacy rx Antenna diversity for SISO rates */ +#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */ +#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */ +#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */ +#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */ +#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */ +#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */ + +/* legacy rx Antenna diversity for SISO rates */ +#define ANT_TX_FORCE_0 0 /* Tx on antenna 0, "legacy term Main" */ +#define ANT_TX_FORCE_1 1 /* Tx on antenna 1, "legacy term Aux" */ +#define ANT_TX_LAST_RX 3 /* Tx on phy's last good Rx antenna */ +#define ANT_TX_DEF 3 /* driver's default tx antenna setting */ + +#define TXCORE_POLICY_ALL 0x1 /* use all available core for transmit */ + +/* Tx Chain values */ +#define TXCHAIN_DEF 0x1 /* def bitmap of txchain */ +#define TXCHAIN_DEF_NPHY 0x3 /* default bitmap of tx chains for nphy */ +#define TXCHAIN_DEF_HTPHY 0x7 /* default bitmap of tx chains for nphy */ +#define RXCHAIN_DEF 0x1 /* def bitmap of rxchain */ +#define RXCHAIN_DEF_NPHY 0x3 /* default bitmap of rx chains for nphy */ +#define RXCHAIN_DEF_HTPHY 0x7 /* default bitmap of rx chains for nphy */ +#define ANTSWITCH_NONE 0 /* no antenna switch */ +#define ANTSWITCH_TYPE_1 1 /* antenna switch on 4321CB2, 2of3 */ +#define ANTSWITCH_TYPE_2 2 /* antenna switch on 4321MPCI, 2of3 */ +#define ANTSWITCH_TYPE_3 3 /* antenna switch on 4322, 2of3 */ + +#define RXBUFSZ PKTBUFSZ +#ifndef AIDMAPSZ +#define AIDMAPSZ (roundup(MAXSCB, NBBY)/NBBY) /* aid bitmap size in bytes */ +#endif /* AIDMAPSZ */ + +typedef struct wlc_tunables { + int ntxd; /* size of tx descriptor table */ + int nrxd; /* size of rx descriptor table */ + int rxbufsz; /* size of rx buffers to post */ + int nrxbufpost; /* # of rx buffers to post */ + int maxscb; /* # of SCBs supported */ + int ampdunummpdu; /* max number of mpdu in an ampdu */ + int maxpktcb; /* max # of packet callbacks */ + int maxucodebss; /* max # of BSS handled in ucode bcn/prb */ + int maxucodebss4; /* max # of BSS handled in sw bcn/prb */ + int maxbss; /* max # of bss info elements in scan list */ + int datahiwat; /* data msg txq hiwat mark */ + int ampdudatahiwat; /* AMPDU msg txq hiwat mark */ + int rxbnd; /* max # of rx bufs to process before deferring to dpc */ + int txsbnd; /* max # tx status to process in wlc_txstatus() */ + int memreserved; /* memory reserved for BMAC's USB dma rx */ +} wlc_tunables_t; + +typedef struct wlc_rateset { + uint count; /* number of rates in rates[] */ + u8 rates[WLC_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */ + u8 htphy_membership; /* HT PHY Membership */ + u8 mcs[MCSSET_LEN]; /* supported mcs index bit map */ +} wlc_rateset_t; + +struct rsn_parms { + u8 flags; /* misc booleans (e.g., supported) */ + u8 multicast; /* multicast cipher */ + u8 ucount; /* count of unicast ciphers */ + u8 unicast[4]; /* unicast ciphers */ + u8 acount; /* count of auth modes */ + u8 auth[4]; /* Authentication modes */ + u8 PAD[4]; /* padding for future growth */ +}; + +/* + * buffer length needed for wlc_format_ssid + * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. + */ +#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) + +#define RSN_FLAGS_SUPPORTED 0x1 /* Flag for rsn_params */ +#define RSN_FLAGS_PREAUTH 0x2 /* Flag for WPA2 rsn_params */ + +/* All the HT-specific default advertised capabilities (including AMPDU) + * should be grouped here at one place + */ +#define AMPDU_DEF_MPDU_DENSITY 6 /* default mpdu density (110 ==> 4us) */ + +/* defaults for the HT (MIMO) bss */ +#define HT_CAP ((HT_CAP_MIMO_PS_OFF << IEEE80211_HT_CAP_SM_PS_SHIFT) |\ + IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_GRN_FLD |\ + HT_CAP_MAX_AMSDU | IEEE80211_HT_CAP_DSSSCCK40) + +/* WLC packet type is a void * */ +typedef void *wlc_pkt_t; + +/* Event data type */ +typedef struct wlc_event { + wl_event_msg_t event; /* encapsulated event */ + struct ether_addr *addr; /* used to keep a trace of the potential present of + * an address in wlc_event_msg_t + */ + int bsscfgidx; /* BSS config when needed */ + struct wl_if *wlif; /* pointer to wlif */ + void *data; /* used to hang additional data on an event */ + struct wlc_event *next; /* enables ordered list of pending events */ +} wlc_event_t; + +/* wlc internal bss_info, wl external one is in wlioctl.h */ +typedef struct wlc_bss_info { + u8 BSSID[ETH_ALEN]; /* network BSSID */ + u16 flags; /* flags for internal attributes */ + u8 SSID_len; /* the length of SSID */ + u8 SSID[32]; /* SSID string */ + s16 RSSI; /* receive signal strength (in dBm) */ + s16 SNR; /* receive signal SNR in dB */ + u16 beacon_period; /* units are Kusec */ + u16 atim_window; /* units are Kusec */ + chanspec_t chanspec; /* Channel num, bw, ctrl_sb and band */ + s8 infra; /* 0=IBSS, 1=infrastructure, 2=unknown */ + wlc_rateset_t rateset; /* supported rates */ + u8 dtim_period; /* DTIM period */ + s8 phy_noise; /* noise right after tx (in dBm) */ + u16 capability; /* Capability information */ + u8 wme_qosinfo; /* QoS Info from WME IE; valid if WLC_BSS_WME flag set */ + struct rsn_parms wpa; + struct rsn_parms wpa2; + u16 qbss_load_aac; /* qbss load available admission capacity */ + /* qbss_load_chan_free <- (0xff - channel_utilization of qbss_load_ie_t) */ + u8 qbss_load_chan_free; /* indicates how free the channel is */ + u8 mcipher; /* multicast cipher */ + u8 wpacfg; /* wpa config index */ +} wlc_bss_info_t; + +/* forward declarations */ +struct wlc_if; + +/* wlc_ioctl error codes */ +#define WLC_ENOIOCTL 1 /* No such Ioctl */ +#define WLC_EINVAL 2 /* Invalid value */ +#define WLC_ETOOSMALL 3 /* Value too small */ +#define WLC_ETOOBIG 4 /* Value too big */ +#define WLC_ERANGE 5 /* Out of range */ +#define WLC_EDOWN 6 /* Down */ +#define WLC_EUP 7 /* Up */ +#define WLC_ENOMEM 8 /* No Memory */ +#define WLC_EBUSY 9 /* Busy */ + +/* IOVar flags for common error checks */ +#define IOVF_MFG (1<<3) /* flag for mfgtest iovars */ +#define IOVF_WHL (1<<4) /* value must be whole (0-max) */ +#define IOVF_NTRL (1<<5) /* value must be natural (1-max) */ + +#define IOVF_SET_UP (1<<6) /* set requires driver be up */ +#define IOVF_SET_DOWN (1<<7) /* set requires driver be down */ +#define IOVF_SET_CLK (1<<8) /* set requires core clock */ +#define IOVF_SET_BAND (1<<9) /* set requires fixed band */ + +#define IOVF_GET_UP (1<<10) /* get requires driver be up */ +#define IOVF_GET_DOWN (1<<11) /* get requires driver be down */ +#define IOVF_GET_CLK (1<<12) /* get requires core clock */ +#define IOVF_GET_BAND (1<<13) /* get requires fixed band */ +#define IOVF_OPEN_ALLOW (1<<14) /* set allowed iovar for opensrc */ + +/* watchdog down and dump callback function proto's */ +typedef int (*watchdog_fn_t) (void *handle); +typedef int (*down_fn_t) (void *handle); +typedef int (*dump_fn_t) (void *handle, struct bcmstrbuf *b); + +/* IOVar handler + * + * handle - a pointer value registered with the function + * vi - iovar_info that was looked up + * actionid - action ID, calculated by IOV_GVAL() and IOV_SVAL() based on varid. + * name - the actual iovar name + * params/plen - parameters and length for a get, input only. + * arg/len - buffer and length for value to be set or retrieved, input or output. + * vsize - value size, valid for integer type only. + * wlcif - interface context (wlc_if pointer) + * + * All pointers may point into the same buffer. + */ +typedef int (*iovar_fn_t) (void *handle, const bcm_iovar_t *vi, + u32 actionid, const char *name, void *params, + uint plen, void *arg, int alen, int vsize, + struct wlc_if *wlcif); + +#define MAC80211_PROMISC_BCNS (1 << 0) +#define MAC80211_SCAN (1 << 1) + +/* + * Public portion of "common" os-independent state structure. + * The wlc handle points at this. + */ +struct wlc_pub { + void *wlc; + + struct ieee80211_hw *ieee_hw; + struct scb *global_scb; + scb_ampdu_t *global_ampdu; + uint mac80211_state; + uint unit; /* device instance number */ + uint corerev; /* core revision */ + struct osl_info *osh; /* pointer to os handle */ + si_t *sih; /* SB handle (cookie for siutils calls) */ + char *vars; /* "environment" name=value */ + bool up; /* interface up and running */ + bool hw_off; /* HW is off */ + wlc_tunables_t *tunables; /* tunables: ntxd, nrxd, maxscb, etc. */ + bool hw_up; /* one time hw up/down(from boot or hibernation) */ + bool _piomode; /* true if pio mode *//* BMAC_NOTE: NEED In both */ + uint _nbands; /* # bands supported */ + uint now; /* # elapsed seconds */ + + bool promisc; /* promiscuous destination address */ + bool delayed_down; /* down delayed */ + bool _ap; /* AP mode enabled */ + bool _apsta; /* simultaneous AP/STA mode enabled */ + bool _assoc_recreate; /* association recreation on up transitions */ + int _wme; /* WME QoS mode */ + u8 _mbss; /* MBSS mode on */ + bool allmulti; /* enable all multicasts */ + bool associated; /* true:part of [I]BSS, false: not */ + /* (union of stas_associated, aps_associated) */ + bool phytest_on; /* whether a PHY test is running */ + bool bf_preempt_4306; /* True to enable 'darwin' mode */ + bool _ampdu; /* ampdu enabled or not */ + bool _cac; /* 802.11e CAC enabled */ + u8 _n_enab; /* bitmap of 11N + HT support */ + bool _n_reqd; /* N support required for clients */ + + s8 _coex; /* 20/40 MHz BSS Management AUTO, ENAB, DISABLE */ + bool _priofc; /* Priority-based flowcontrol */ + + u8 cur_etheraddr[ETH_ALEN]; /* our local ethernet address */ + + u8 *multicast; /* ptr to list of multicast addresses */ + uint nmulticast; /* # enabled multicast addresses */ + + u32 wlfeatureflag; /* Flags to control sw features from registry */ + int psq_pkts_total; /* total num of ps pkts */ + + u16 txmaxpkts; /* max number of large pkts allowed to be pending */ + + /* s/w decryption counters */ + u32 swdecrypt; /* s/w decrypt attempts */ + + int bcmerror; /* last bcm error */ + + mbool radio_disabled; /* bit vector for radio disabled reasons */ + bool radio_active; /* radio on/off state */ + u16 roam_time_thresh; /* Max. # secs. of not hearing beacons + * before roaming. + */ + bool align_wd_tbtt; /* Align watchdog with tbtt indication + * handling. This flag is cleared by default + * and is set by per port code explicitly and + * you need to make sure the OSL_SYSUPTIME() + * is implemented properly in osl of that port + * when it enables this Power Save feature. + */ + + u16 boardrev; /* version # of particular board */ + u8 sromrev; /* version # of the srom */ + char srom_ccode[WLC_CNTRY_BUF_SZ]; /* Country Code in SROM */ + u32 boardflags; /* Board specific flags from srom */ + u32 boardflags2; /* More board flags if sromrev >= 4 */ + bool tempsense_disable; /* disable periodic tempsense check */ + + bool _lmac; /* lmac module included and enabled */ + bool _lmacproto; /* lmac protocol module included and enabled */ + bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */ + bool _ampdumac; /* mac assist ampdu enabled or not */ +}; + +/* wl_monitor rx status per packet */ +typedef struct wl_rxsts { + uint pkterror; /* error flags per pkt */ + uint phytype; /* 802.11 A/B/G ... */ + uint channel; /* channel */ + uint datarate; /* rate in 500kbps */ + uint antenna; /* antenna pkts received on */ + uint pktlength; /* pkt length minus bcm phy hdr */ + u32 mactime; /* time stamp from mac, count per 1us */ + uint sq; /* signal quality */ + s32 signal; /* in dbm */ + s32 noise; /* in dbm */ + uint preamble; /* Unknown, short, long */ + uint encoding; /* Unknown, CCK, PBCC, OFDM */ + uint nfrmtype; /* special 802.11n frames(AMPDU, AMSDU) */ + struct wl_if *wlif; /* wl interface */ +} wl_rxsts_t; + +/* status per error RX pkt */ +#define WL_RXS_CRC_ERROR 0x00000001 /* CRC Error in packet */ +#define WL_RXS_RUNT_ERROR 0x00000002 /* Runt packet */ +#define WL_RXS_ALIGN_ERROR 0x00000004 /* Misaligned packet */ +#define WL_RXS_OVERSIZE_ERROR 0x00000008 /* packet bigger than RX_LENGTH (usually 1518) */ +#define WL_RXS_WEP_ICV_ERROR 0x00000010 /* Integrity Check Value error */ +#define WL_RXS_WEP_ENCRYPTED 0x00000020 /* Encrypted with WEP */ +#define WL_RXS_PLCP_SHORT 0x00000040 /* Short PLCP error */ +#define WL_RXS_DECRYPT_ERR 0x00000080 /* Decryption error */ +#define WL_RXS_OTHER_ERR 0x80000000 /* Other errors */ + +/* phy type */ +#define WL_RXS_PHY_A 0x00000000 /* A phy type */ +#define WL_RXS_PHY_B 0x00000001 /* B phy type */ +#define WL_RXS_PHY_G 0x00000002 /* G phy type */ +#define WL_RXS_PHY_N 0x00000004 /* N phy type */ + +/* encoding */ +#define WL_RXS_ENCODING_CCK 0x00000000 /* CCK encoding */ +#define WL_RXS_ENCODING_OFDM 0x00000001 /* OFDM encoding */ + +/* preamble */ +#define WL_RXS_UNUSED_STUB 0x0 /* stub to match with wlc_ethereal.h */ +#define WL_RXS_PREAMBLE_SHORT 0x00000001 /* Short preamble */ +#define WL_RXS_PREAMBLE_LONG 0x00000002 /* Long preamble */ +#define WL_RXS_PREAMBLE_MIMO_MM 0x00000003 /* MIMO mixed mode preamble */ +#define WL_RXS_PREAMBLE_MIMO_GF 0x00000004 /* MIMO green field preamble */ + +#define WL_RXS_NFRM_AMPDU_FIRST 0x00000001 /* first MPDU in A-MPDU */ +#define WL_RXS_NFRM_AMPDU_SUB 0x00000002 /* subsequent MPDU(s) in A-MPDU */ +#define WL_RXS_NFRM_AMSDU_FIRST 0x00000004 /* first MSDU in A-MSDU */ +#define WL_RXS_NFRM_AMSDU_SUB 0x00000008 /* subsequent MSDU(s) in A-MSDU */ + +/* forward declare and use the struct notation so we don't have to + * have it defined if not necessary. + */ +struct wlc_info; +struct wlc_hw_info; +struct wlc_bsscfg; +struct wlc_if; + +/*********************************************** + * Feature-related macros to optimize out code * + * ********************************************* + */ + +/* AP Support (versus STA) */ +#define AP_ENAB(pub) (0) + +/* Macro to check if APSTA mode enabled */ +#define APSTA_ENAB(pub) (0) + +/* Some useful combinations */ +#define STA_ONLY(pub) (!AP_ENAB(pub)) +#define AP_ONLY(pub) (AP_ENAB(pub) && !APSTA_ENAB(pub)) + +#define ENAB_1x1 0x01 +#define ENAB_2x2 0x02 +#define ENAB_3x3 0x04 +#define ENAB_4x4 0x08 +#define SUPPORT_11N (ENAB_1x1|ENAB_2x2) +#define SUPPORT_HT (ENAB_1x1|ENAB_2x2|ENAB_3x3) +/* WL11N Support */ +#if ((defined(NCONF) && (NCONF != 0)) || (defined(LCNCONF) && (LCNCONF != 0)) || \ + (defined(HTCONF) && (HTCONF != 0)) || (defined(SSLPNCONF) && (SSLPNCONF != 0))) +#define N_ENAB(pub) ((pub)->_n_enab & SUPPORT_11N) +#define N_REQD(pub) ((pub)->_n_reqd) +#else +#define N_ENAB(pub) 0 +#define N_REQD(pub) 0 +#endif + +#if (defined(HTCONF) && (HTCONF != 0)) +#define HT_ENAB(pub) (((pub)->_n_enab & SUPPORT_HT) == SUPPORT_HT) +#else +#define HT_ENAB(pub) 0 +#endif + +#define AMPDU_AGG_HOST 1 +#define AMPDU_ENAB(pub) ((pub)->_ampdu) + +#define EDCF_ENAB(pub) (WME_ENAB(pub)) +#define QOS_ENAB(pub) (WME_ENAB(pub) || N_ENAB(pub)) + +#define MONITOR_ENAB(wlc) ((wlc)->monitor) + +#define PROMISC_ENAB(wlc) ((wlc)->promisc) + +#define WLC_PREC_COUNT 16 /* Max precedence level implemented */ + +/* pri is priority encoded in the packet. This maps the Packet priority to + * enqueue precedence as defined in wlc_prec_map + */ +extern const u8 wlc_prio2prec_map[]; +#define WLC_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7] + +/* This maps priority to one precedence higher - Used by PS-Poll response packets to + * simulate enqueue-at-head operation, but still maintain the order on the queue + */ +#define WLC_PRIO_TO_HI_PREC(pri) min(WLC_PRIO_TO_PREC(pri) + 1, WLC_PREC_COUNT - 1) + +extern const u8 wme_fifo2ac[]; +#define WME_PRIO2AC(prio) wme_fifo2ac[prio2fifo[(prio)]] + +/* Mask to describe all precedence levels */ +#define WLC_PREC_BMP_ALL MAXBITVAL(WLC_PREC_COUNT) + +/* Define a bitmap of precedences comprised by each AC */ +#define WLC_PREC_BMP_AC_BE (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BE)) | \ + NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BE)) | \ + NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_EE)) | \ + NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_EE))) +#define WLC_PREC_BMP_AC_BK (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BK)) | \ + NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BK)) | \ + NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NONE)) | \ + NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NONE))) +#define WLC_PREC_BMP_AC_VI (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_CL)) | \ + NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_CL)) | \ + NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VI)) | \ + NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VI))) +#define WLC_PREC_BMP_AC_VO (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VO)) | \ + NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VO)) | \ + NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NC)) | \ + NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NC))) + +/* WME Support */ +#define WME_ENAB(pub) ((pub)->_wme != OFF) +#define WME_AUTO(wlc) ((wlc)->pub->_wme == AUTO) + +#define WLC_USE_COREFLAGS 0xffffffff /* invalid core flags, use the saved coreflags */ + +#define WLC_UPDATE_STATS(wlc) 0 /* No stats support */ +#define WLCNTINCR(a) /* No stats support */ +#define WLCNTDECR(a) /* No stats support */ +#define WLCNTADD(a, delta) /* No stats support */ +#define WLCNTSET(a, value) /* No stats support */ +#define WLCNTVAL(a) 0 /* No stats support */ + +/* common functions for every port */ +extern void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, + bool piomode, struct osl_info *osh, void *regsva, + uint bustype, void *btparam, uint *perr); +extern uint wlc_detach(struct wlc_info *wlc); +extern int wlc_up(struct wlc_info *wlc); +extern uint wlc_down(struct wlc_info *wlc); + +extern int wlc_set(struct wlc_info *wlc, int cmd, int arg); +extern int wlc_get(struct wlc_info *wlc, int cmd, int *arg); +extern int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg); +extern int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg); +extern bool wlc_chipmatch(u16 vendor, u16 device); +extern void wlc_init(struct wlc_info *wlc); +extern void wlc_reset(struct wlc_info *wlc); + +extern void wlc_intrson(struct wlc_info *wlc); +extern u32 wlc_intrsoff(struct wlc_info *wlc); +extern void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask); +extern bool wlc_intrsupd(struct wlc_info *wlc); +extern bool wlc_isr(struct wlc_info *wlc, bool *wantdpc); +extern bool wlc_dpc(struct wlc_info *wlc, bool bounded); +extern bool wlc_send80211_raw(struct wlc_info *wlc, struct wlc_if *wlcif, + void *p, uint ac); +extern bool wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, + struct ieee80211_hw *hw); +extern int wlc_iovar_op(struct wlc_info *wlc, const char *name, void *params, + int p_len, void *arg, int len, bool set, + struct wlc_if *wlcif); +extern int wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, + struct wlc_if *wlcif); +/* helper functions */ +extern void wlc_statsupd(struct wlc_info *wlc); +extern int wlc_get_header_len(void); +extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc); +extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, + const u8 *addr); +extern void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, + bool suspend); + +extern struct wlc_pub *wlc_pub(void *wlc); + +/* common functions for every port */ +extern int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw); +extern int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw); +extern int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw); +extern int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw); + +extern u32 wlc_reg_read(struct wlc_info *wlc, void *r, uint size); +extern void wlc_reg_write(struct wlc_info *wlc, void *r, u32 v, uint size); +extern void wlc_corereset(struct wlc_info *wlc, u32 flags); +extern void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val, + int bands); +extern u16 wlc_mhf_get(struct wlc_info *wlc, u8 idx, int bands); +extern u32 wlc_delta_txfunfl(struct wlc_info *wlc, int fifo); +extern void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset); +extern void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs); + +/* wlc_phy.c helper functions */ +extern void wlc_set_ps_ctrl(struct wlc_info *wlc); +extern void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val); +extern void wlc_scb_ratesel_init_all(struct wlc_info *wlc); + +/* ioctl */ +extern int wlc_iovar_gets8(struct wlc_info *wlc, const char *name, + s8 *arg); +extern int wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, + void *arg, + int len, bool set); + +extern int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, + const char *name, void *hdl, iovar_fn_t iovar_fn, + watchdog_fn_t watchdog_fn, down_fn_t down_fn); +extern int wlc_module_unregister(struct wlc_pub *pub, const char *name, + void *hdl); +extern void wlc_event_if(struct wlc_info *wlc, struct wlc_bsscfg *cfg, + wlc_event_t *e, const struct ether_addr *addr); +extern void wlc_suspend_mac_and_wait(struct wlc_info *wlc); +extern void wlc_enable_mac(struct wlc_info *wlc); +extern u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate); +extern u32 wlc_get_rspec_history(struct wlc_bsscfg *cfg); +extern u32 wlc_get_current_highest_rate(struct wlc_bsscfg *cfg); + +static inline int wlc_iovar_getuint(struct wlc_info *wlc, const char *name, + uint *arg) +{ + return wlc_iovar_getint(wlc, name, (int *)arg); +} + +static inline int wlc_iovar_getu8(struct wlc_info *wlc, const char *name, + u8 *arg) +{ + return wlc_iovar_gets8(wlc, name, (s8 *) arg); +} + +static inline int wlc_iovar_setuint(struct wlc_info *wlc, const char *name, + uint arg) +{ + return wlc_iovar_setint(wlc, name, (int)arg); +} + +#if defined(BCMDBG) +extern int wlc_iocregchk(struct wlc_info *wlc, uint band); +#endif +#if defined(BCMDBG) +extern int wlc_iocpichk(struct wlc_info *wlc, uint phytype); +#endif + +/* helper functions */ +extern void wlc_getrand(struct wlc_info *wlc, u8 *buf, int len); + +struct scb; +extern void wlc_ps_on(struct wlc_info *wlc, struct scb *scb); +extern void wlc_ps_off(struct wlc_info *wlc, struct scb *scb, bool discard); +extern bool wlc_radio_monitor_stop(struct wlc_info *wlc); + +#if defined(BCMDBG) +extern int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len); +#endif + +extern void wlc_pmkid_build_cand_list(struct wlc_bsscfg *cfg, bool check_SSID); +extern void wlc_pmkid_event(struct wlc_bsscfg *cfg); + +#define MAXBANDS 2 /* Maximum #of bands */ +/* bandstate array indices */ +#define BAND_2G_INDEX 0 /* wlc->bandstate[x] index */ +#define BAND_5G_INDEX 1 /* wlc->bandstate[x] index */ + +#define BAND_2G_NAME "2.4G" +#define BAND_5G_NAME "5G" + +/* BMAC RPC: 7 u32 params: pkttotlen, fifo, commit, fid, txpktpend, pktflag, rpc_id */ +#define WLC_RPCTX_PARAMS 32 + +#endif /* _wlc_pub_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c new file mode 100644 index 000000000000..ab7d0bed3c0a --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c @@ -0,0 +1,501 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Rate info per rate: It tells whether a rate is ofdm or not and its phy_rate value */ +const u8 rate_info[WLC_MAXRATE + 1] = { + /* 0 1 2 3 4 5 6 7 8 9 */ +/* 0 */ 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, +/* 10 */ 0x00, 0x37, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00, +/* 20 */ 0x00, 0x00, 0x6e, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, +/* 30 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, +/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, +/* 50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* 60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* 70 */ 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, +/* 100 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c +}; + +/* rates are in units of Kbps */ +const mcs_info_t mcs_table[MCS_TABLE_SIZE] = { + /* MCS 0: SS 1, MOD: BPSK, CR 1/2 */ + {6500, 13500, CEIL(6500 * 10, 9), CEIL(13500 * 10, 9), 0x00, + WLC_RATE_6M}, + /* MCS 1: SS 1, MOD: QPSK, CR 1/2 */ + {13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x08, + WLC_RATE_12M}, + /* MCS 2: SS 1, MOD: QPSK, CR 3/4 */ + {19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x0A, + WLC_RATE_18M}, + /* MCS 3: SS 1, MOD: 16QAM, CR 1/2 */ + {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x10, + WLC_RATE_24M}, + /* MCS 4: SS 1, MOD: 16QAM, CR 3/4 */ + {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x12, + WLC_RATE_36M}, + /* MCS 5: SS 1, MOD: 64QAM, CR 2/3 */ + {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x19, + WLC_RATE_48M}, + /* MCS 6: SS 1, MOD: 64QAM, CR 3/4 */ + {58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x1A, + WLC_RATE_54M}, + /* MCS 7: SS 1, MOD: 64QAM, CR 5/6 */ + {65000, 135000, CEIL(65000 * 10, 9), CEIL(135000 * 10, 9), 0x1C, + WLC_RATE_54M}, + /* MCS 8: SS 2, MOD: BPSK, CR 1/2 */ + {13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x40, + WLC_RATE_6M}, + /* MCS 9: SS 2, MOD: QPSK, CR 1/2 */ + {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x48, + WLC_RATE_12M}, + /* MCS 10: SS 2, MOD: QPSK, CR 3/4 */ + {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x4A, + WLC_RATE_18M}, + /* MCS 11: SS 2, MOD: 16QAM, CR 1/2 */ + {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x50, + WLC_RATE_24M}, + /* MCS 12: SS 2, MOD: 16QAM, CR 3/4 */ + {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x52, + WLC_RATE_36M}, + /* MCS 13: SS 2, MOD: 64QAM, CR 2/3 */ + {104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0x59, + WLC_RATE_48M}, + /* MCS 14: SS 2, MOD: 64QAM, CR 3/4 */ + {117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x5A, + WLC_RATE_54M}, + /* MCS 15: SS 2, MOD: 64QAM, CR 5/6 */ + {130000, 270000, CEIL(130000 * 10, 9), CEIL(270000 * 10, 9), 0x5C, + WLC_RATE_54M}, + /* MCS 16: SS 3, MOD: BPSK, CR 1/2 */ + {19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x80, + WLC_RATE_6M}, + /* MCS 17: SS 3, MOD: QPSK, CR 1/2 */ + {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x88, + WLC_RATE_12M}, + /* MCS 18: SS 3, MOD: QPSK, CR 3/4 */ + {58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x8A, + WLC_RATE_18M}, + /* MCS 19: SS 3, MOD: 16QAM, CR 1/2 */ + {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x90, + WLC_RATE_24M}, + /* MCS 20: SS 3, MOD: 16QAM, CR 3/4 */ + {117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x92, + WLC_RATE_36M}, + /* MCS 21: SS 3, MOD: 64QAM, CR 2/3 */ + {156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0x99, + WLC_RATE_48M}, + /* MCS 22: SS 3, MOD: 64QAM, CR 3/4 */ + {175500, 364500, CEIL(175500 * 10, 9), CEIL(364500 * 10, 9), 0x9A, + WLC_RATE_54M}, + /* MCS 23: SS 3, MOD: 64QAM, CR 5/6 */ + {195000, 405000, CEIL(195000 * 10, 9), CEIL(405000 * 10, 9), 0x9B, + WLC_RATE_54M}, + /* MCS 24: SS 4, MOD: BPSK, CR 1/2 */ + {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0xC0, + WLC_RATE_6M}, + /* MCS 25: SS 4, MOD: QPSK, CR 1/2 */ + {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0xC8, + WLC_RATE_12M}, + /* MCS 26: SS 4, MOD: QPSK, CR 3/4 */ + {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0xCA, + WLC_RATE_18M}, + /* MCS 27: SS 4, MOD: 16QAM, CR 1/2 */ + {104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0xD0, + WLC_RATE_24M}, + /* MCS 28: SS 4, MOD: 16QAM, CR 3/4 */ + {156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0xD2, + WLC_RATE_36M}, + /* MCS 29: SS 4, MOD: 64QAM, CR 2/3 */ + {208000, 432000, CEIL(208000 * 10, 9), CEIL(432000 * 10, 9), 0xD9, + WLC_RATE_48M}, + /* MCS 30: SS 4, MOD: 64QAM, CR 3/4 */ + {234000, 486000, CEIL(234000 * 10, 9), CEIL(486000 * 10, 9), 0xDA, + WLC_RATE_54M}, + /* MCS 31: SS 4, MOD: 64QAM, CR 5/6 */ + {260000, 540000, CEIL(260000 * 10, 9), CEIL(540000 * 10, 9), 0xDB, + WLC_RATE_54M}, + /* MCS 32: SS 1, MOD: BPSK, CR 1/2 */ + {0, 6000, 0, CEIL(6000 * 10, 9), 0x00, WLC_RATE_6M}, +}; + +/* phycfg for legacy OFDM frames: code rate, modulation scheme, spatial streams + * Number of spatial streams: always 1 + * other fields: refer to table 78 of section 17.3.2.2 of the original .11a standard + */ +typedef struct legacy_phycfg { + u32 rate_ofdm; /* ofdm mac rate */ + u8 tx_phy_ctl3; /* phy ctl byte 3, code rate, modulation type, # of streams */ +} legacy_phycfg_t; + +#define LEGACY_PHYCFG_TABLE_SIZE 12 /* Number of legacy_rate_cfg entries in the table */ + +/* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */ +/* Eventually MIMOPHY would also be converted to this format */ +/* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */ +static const legacy_phycfg_t legacy_phycfg_table[LEGACY_PHYCFG_TABLE_SIZE] = { + {WLC_RATE_1M, 0x00}, /* CCK 1Mbps, data rate 0 */ + {WLC_RATE_2M, 0x08}, /* CCK 2Mbps, data rate 1 */ + {WLC_RATE_5M5, 0x10}, /* CCK 5.5Mbps, data rate 2 */ + {WLC_RATE_11M, 0x18}, /* CCK 11Mbps, data rate 3 */ + {WLC_RATE_6M, 0x00}, /* OFDM 6Mbps, code rate 1/2, BPSK, 1 spatial stream */ + {WLC_RATE_9M, 0x02}, /* OFDM 9Mbps, code rate 3/4, BPSK, 1 spatial stream */ + {WLC_RATE_12M, 0x08}, /* OFDM 12Mbps, code rate 1/2, QPSK, 1 spatial stream */ + {WLC_RATE_18M, 0x0A}, /* OFDM 18Mbps, code rate 3/4, QPSK, 1 spatial stream */ + {WLC_RATE_24M, 0x10}, /* OFDM 24Mbps, code rate 1/2, 16-QAM, 1 spatial stream */ + {WLC_RATE_36M, 0x12}, /* OFDM 36Mbps, code rate 3/4, 16-QAM, 1 spatial stream */ + {WLC_RATE_48M, 0x19}, /* OFDM 48Mbps, code rate 2/3, 64-QAM, 1 spatial stream */ + {WLC_RATE_54M, 0x1A}, /* OFDM 54Mbps, code rate 3/4, 64-QAM, 1 spatial stream */ +}; + +/* Hardware rates (also encodes default basic rates) */ + +const wlc_rateset_t cck_ofdm_mimo_rates = { + 12, + { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */ + 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60, + 0x6c}, + 0x00, + {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +const wlc_rateset_t ofdm_mimo_rates = { + 8, + { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */ + 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c}, + 0x00, + {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* Default ratesets that include MCS32 for 40BW channels */ +const wlc_rateset_t cck_ofdm_40bw_mimo_rates = { + 12, + { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */ + 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60, + 0x6c}, + 0x00, + {0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +const wlc_rateset_t ofdm_40bw_mimo_rates = { + 8, + { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */ + 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c}, + 0x00, + {0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +const wlc_rateset_t cck_ofdm_rates = { + 12, + { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */ + 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60, + 0x6c}, + 0x00, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +const wlc_rateset_t gphy_legacy_rates = { + 4, + { /* 1b, 2b, 5.5b, 11b Mbps */ + 0x82, 0x84, 0x8b, 0x96}, + 0x00, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +const wlc_rateset_t ofdm_rates = { + 8, + { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */ + 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c}, + 0x00, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +const wlc_rateset_t cck_rates = { + 4, + { /* 1b, 2b, 5.5, 11 Mbps */ + 0x82, 0x84, 0x0b, 0x16}, + 0x00, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static bool wlc_rateset_valid(wlc_rateset_t *rs, bool check_brate); + +/* check if rateset is valid. + * if check_brate is true, rateset without a basic rate is considered NOT valid. + */ +static bool wlc_rateset_valid(wlc_rateset_t *rs, bool check_brate) +{ + uint idx; + + if (!rs->count) + return false; + + if (!check_brate) + return true; + + /* error if no basic rates */ + for (idx = 0; idx < rs->count; idx++) { + if (rs->rates[idx] & WLC_RATE_FLAG) + return true; + } + return false; +} + +void wlc_rateset_mcs_upd(wlc_rateset_t *rs, u8 txstreams) +{ + int i; + for (i = txstreams; i < MAX_STREAMS_SUPPORTED; i++) + rs->mcs[i] = 0; +} + +/* filter based on hardware rateset, and sort filtered rateset with basic bit(s) preserved, + * and check if resulting rateset is valid. +*/ +bool +wlc_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs, + const wlc_rateset_t *hw_rs, + bool check_brate, u8 txstreams) +{ + u8 rateset[WLC_MAXRATE + 1]; + u8 r; + uint count; + uint i; + + memset(rateset, 0, sizeof(rateset)); + count = rs->count; + + for (i = 0; i < count; i++) { + /* mask off "basic rate" bit, WLC_RATE_FLAG */ + r = (int)rs->rates[i] & RATE_MASK; + if ((r > WLC_MAXRATE) || (rate_info[r] == 0)) { + continue; + } + rateset[r] = rs->rates[i]; /* preserve basic bit! */ + } + + /* fill out the rates in order, looking at only supported rates */ + count = 0; + for (i = 0; i < hw_rs->count; i++) { + r = hw_rs->rates[i] & RATE_MASK; + ASSERT(r <= WLC_MAXRATE); + if (rateset[r]) + rs->rates[count++] = rateset[r]; + } + + rs->count = count; + + /* only set the mcs rate bit if the equivalent hw mcs bit is set */ + for (i = 0; i < MCSSET_LEN; i++) + rs->mcs[i] = (rs->mcs[i] & hw_rs->mcs[i]); + + if (wlc_rateset_valid(rs, check_brate)) + return true; + else + return false; +} + +/* caluclate the rate of a rx'd frame and return it as a ratespec */ +ratespec_t BCMFASTPATH wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp) +{ + int phy_type; + ratespec_t rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT; + + phy_type = + ((rxh->RxChan & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT); + + if ((phy_type == PHY_TYPE_N) || (phy_type == PHY_TYPE_SSN) || + (phy_type == PHY_TYPE_LCN) || (phy_type == PHY_TYPE_HT)) { + switch (rxh->PhyRxStatus_0 & PRXS0_FT_MASK) { + case PRXS0_CCK: + rspec = + CCK_PHY2MAC_RATE(((cck_phy_hdr_t *) plcp)->signal); + break; + case PRXS0_OFDM: + rspec = + OFDM_PHY2MAC_RATE(((ofdm_phy_hdr_t *) plcp)-> + rlpt[0]); + break; + case PRXS0_PREN: + rspec = (plcp[0] & MIMO_PLCP_MCS_MASK) | RSPEC_MIMORATE; + if (plcp[0] & MIMO_PLCP_40MHZ) { + /* indicate rspec is for 40 MHz mode */ + rspec &= ~RSPEC_BW_MASK; + rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT); + } + break; + case PRXS0_STDN: + /* fallthru */ + default: + /* not supported */ + ASSERT(0); + break; + } + if (PLCP3_ISSGI(plcp[3])) + rspec |= RSPEC_SHORT_GI; + } else + if ((phy_type == PHY_TYPE_A) || (rxh->PhyRxStatus_0 & PRXS0_OFDM)) + rspec = OFDM_PHY2MAC_RATE(((ofdm_phy_hdr_t *) plcp)->rlpt[0]); + else + rspec = CCK_PHY2MAC_RATE(((cck_phy_hdr_t *) plcp)->signal); + + return rspec; +} + +/* copy rateset src to dst as-is (no masking or sorting) */ +void wlc_rateset_copy(const wlc_rateset_t *src, wlc_rateset_t *dst) +{ + bcopy(src, dst, sizeof(wlc_rateset_t)); +} + +/* + * Copy and selectively filter one rateset to another. + * 'basic_only' means only copy basic rates. + * 'rates' indicates cck (11b) and ofdm rates combinations. + * - 0: cck and ofdm + * - 1: cck only + * - 2: ofdm only + * 'xmask' is the copy mask (typically 0x7f or 0xff). + */ +void +wlc_rateset_filter(wlc_rateset_t *src, wlc_rateset_t *dst, bool basic_only, + u8 rates, uint xmask, bool mcsallow) +{ + uint i; + uint r; + uint count; + + count = 0; + for (i = 0; i < src->count; i++) { + r = src->rates[i]; + if (basic_only && !(r & WLC_RATE_FLAG)) + continue; + if ((rates == WLC_RATES_CCK) && IS_OFDM((r & RATE_MASK))) + continue; + if ((rates == WLC_RATES_OFDM) && IS_CCK((r & RATE_MASK))) + continue; + dst->rates[count++] = r & xmask; + } + dst->count = count; + dst->htphy_membership = src->htphy_membership; + + if (mcsallow && rates != WLC_RATES_CCK) + bcopy(&src->mcs[0], &dst->mcs[0], MCSSET_LEN); + else + wlc_rateset_mcs_clear(dst); +} + +/* select rateset for a given phy_type and bandtype and filter it, sort it + * and fill rs_tgt with result + */ +void +wlc_rateset_default(wlc_rateset_t *rs_tgt, const wlc_rateset_t *rs_hw, + uint phy_type, int bandtype, bool cck_only, uint rate_mask, + bool mcsallow, u8 bw, u8 txstreams) +{ + const wlc_rateset_t *rs_dflt; + wlc_rateset_t rs_sel; + if ((PHYTYPE_IS(phy_type, PHY_TYPE_HT)) || + (PHYTYPE_IS(phy_type, PHY_TYPE_N)) || + (PHYTYPE_IS(phy_type, PHY_TYPE_LCN)) || + (PHYTYPE_IS(phy_type, PHY_TYPE_SSN))) { + if (BAND_5G(bandtype)) { + rs_dflt = (bw == WLC_20_MHZ ? + &ofdm_mimo_rates : &ofdm_40bw_mimo_rates); + } else { + rs_dflt = (bw == WLC_20_MHZ ? + &cck_ofdm_mimo_rates : + &cck_ofdm_40bw_mimo_rates); + } + } else if (PHYTYPE_IS(phy_type, PHY_TYPE_LP)) { + rs_dflt = (BAND_5G(bandtype)) ? &ofdm_rates : &cck_ofdm_rates; + } else if (PHYTYPE_IS(phy_type, PHY_TYPE_A)) { + rs_dflt = &ofdm_rates; + } else if (PHYTYPE_IS(phy_type, PHY_TYPE_G)) { + rs_dflt = &cck_ofdm_rates; + } else { + ASSERT(0); /* should not happen */ + rs_dflt = &cck_rates; /* force cck */ + } + + /* if hw rateset is not supplied, assign selected rateset to it */ + if (!rs_hw) + rs_hw = rs_dflt; + + wlc_rateset_copy(rs_dflt, &rs_sel); + wlc_rateset_mcs_upd(&rs_sel, txstreams); + wlc_rateset_filter(&rs_sel, rs_tgt, false, + cck_only ? WLC_RATES_CCK : WLC_RATES_CCK_OFDM, + rate_mask, mcsallow); + wlc_rate_hwrs_filter_sort_validate(rs_tgt, rs_hw, false, + mcsallow ? txstreams : 1); +} + +s16 BCMFASTPATH wlc_rate_legacy_phyctl(uint rate) +{ + uint i; + for (i = 0; i < LEGACY_PHYCFG_TABLE_SIZE; i++) + if (rate == legacy_phycfg_table[i].rate_ofdm) + return legacy_phycfg_table[i].tx_phy_ctl3; + + return -1; +} + +void wlc_rateset_mcs_clear(wlc_rateset_t *rateset) +{ + uint i; + for (i = 0; i < MCSSET_LEN; i++) + rateset->mcs[i] = 0; +} + +void wlc_rateset_mcs_build(wlc_rateset_t *rateset, u8 txstreams) +{ + bcopy(&cck_ofdm_mimo_rates.mcs[0], &rateset->mcs[0], MCSSET_LEN); + wlc_rateset_mcs_upd(rateset, txstreams); +} + +/* Based on bandwidth passed, allow/disallow MCS 32 in the rateset */ +void wlc_rateset_bw_mcs_filter(wlc_rateset_t *rateset, u8 bw) +{ + if (bw == WLC_40_MHZ) + setbit(rateset->mcs, 32); + else + clrbit(rateset->mcs, 32); +} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.h b/drivers/staging/brcm80211/brcmsmac/wlc_rate.h new file mode 100644 index 000000000000..25ba2a423639 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_rate.h @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _WLC_RATE_H_ +#define _WLC_RATE_H_ + +extern const u8 rate_info[]; +extern const struct wlc_rateset cck_ofdm_mimo_rates; +extern const struct wlc_rateset ofdm_mimo_rates; +extern const struct wlc_rateset cck_ofdm_rates; +extern const struct wlc_rateset ofdm_rates; +extern const struct wlc_rateset cck_rates; +extern const struct wlc_rateset gphy_legacy_rates; +extern const struct wlc_rateset wlc_lrs_rates; +extern const struct wlc_rateset rate_limit_1_2; + +typedef struct mcs_info { + u32 phy_rate_20; /* phy rate in kbps [20Mhz] */ + u32 phy_rate_40; /* phy rate in kbps [40Mhz] */ + u32 phy_rate_20_sgi; /* phy rate in kbps [20Mhz] with SGI */ + u32 phy_rate_40_sgi; /* phy rate in kbps [40Mhz] with SGI */ + u8 tx_phy_ctl3; /* phy ctl byte 3, code rate, modulation type, # of streams */ + u8 leg_ofdm; /* matching legacy ofdm rate in 500bkps */ +} mcs_info_t; + +#define WLC_MAXMCS 32 /* max valid mcs index */ +#define MCS_TABLE_SIZE 33 /* Number of mcs entries in the table */ +extern const mcs_info_t mcs_table[]; + +#define MCS_INVALID 0xFF +#define MCS_CR_MASK 0x07 /* Code Rate bit mask */ +#define MCS_MOD_MASK 0x38 /* Modulation bit shift */ +#define MCS_MOD_SHIFT 3 /* MOdulation bit shift */ +#define MCS_TXS_MASK 0xc0 /* num tx streams - 1 bit mask */ +#define MCS_TXS_SHIFT 6 /* num tx streams - 1 bit shift */ +#define MCS_CR(_mcs) (mcs_table[_mcs].tx_phy_ctl3 & MCS_CR_MASK) +#define MCS_MOD(_mcs) ((mcs_table[_mcs].tx_phy_ctl3 & MCS_MOD_MASK) >> MCS_MOD_SHIFT) +#define MCS_TXS(_mcs) ((mcs_table[_mcs].tx_phy_ctl3 & MCS_TXS_MASK) >> MCS_TXS_SHIFT) +#define MCS_RATE(_mcs, _is40, _sgi) (_sgi ? \ + (_is40 ? mcs_table[_mcs].phy_rate_40_sgi : mcs_table[_mcs].phy_rate_20_sgi) : \ + (_is40 ? mcs_table[_mcs].phy_rate_40 : mcs_table[_mcs].phy_rate_20)) +#define VALID_MCS(_mcs) ((_mcs < MCS_TABLE_SIZE)) + +#define WLC_RATE_FLAG 0x80 /* Rate flag: basic or ofdm */ + +/* Macros to use the rate_info table */ +#define RATE_MASK 0x7f /* Rate value mask w/o basic rate flag */ +#define RATE_MASK_FULL 0xff /* Rate value mask with basic rate flag */ + +#define WLC_RATE_500K_TO_BPS(rate) ((rate) * 500000) /* convert 500kbps to bps */ + +/* rate spec : holds rate and mode specific information required to generate a tx frame. */ +/* Legacy CCK and OFDM information is held in the same manner as was done in the past */ +/* (in the lower byte) the upper 3 bytes primarily hold MIMO specific information */ +typedef u32 ratespec_t; + +/* rate spec bit fields */ +#define RSPEC_RATE_MASK 0x0000007F /* Either 500Kbps units or MIMO MCS idx */ +#define RSPEC_MIMORATE 0x08000000 /* mimo MCS is stored in RSPEC_RATE_MASK */ +#define RSPEC_BW_MASK 0x00000700 /* mimo bw mask */ +#define RSPEC_BW_SHIFT 8 /* mimo bw shift */ +#define RSPEC_STF_MASK 0x00003800 /* mimo Space/Time/Frequency mode mask */ +#define RSPEC_STF_SHIFT 11 /* mimo Space/Time/Frequency mode shift */ +#define RSPEC_CT_MASK 0x0000C000 /* mimo coding type mask */ +#define RSPEC_CT_SHIFT 14 /* mimo coding type shift */ +#define RSPEC_STC_MASK 0x00300000 /* mimo num STC streams per PLCP defn. */ +#define RSPEC_STC_SHIFT 20 /* mimo num STC streams per PLCP defn. */ +#define RSPEC_LDPC_CODING 0x00400000 /* mimo bit indicates adv coding in use */ +#define RSPEC_SHORT_GI 0x00800000 /* mimo bit indicates short GI in use */ +#define RSPEC_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */ +#define RSPEC_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicates override rate only */ + +#define WLC_HTPHY 127 /* HT PHY Membership */ + +#define RSPEC_ACTIVE(rspec) (rspec & (RSPEC_RATE_MASK | RSPEC_MIMORATE)) +#define RSPEC2RATE(rspec) ((rspec & RSPEC_MIMORATE) ? \ + MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec)) : \ + (rspec & RSPEC_RATE_MASK)) +/* return rate in unit of 500Kbps -- for internal use in wlc_rate_sel.c */ +#define RSPEC2RATE500K(rspec) ((rspec & RSPEC_MIMORATE) ? \ + MCS_RATE((rspec & RSPEC_RATE_MASK), state->is40bw, RSPEC_ISSGI(rspec))/500 : \ + (rspec & RSPEC_RATE_MASK)) +#define CRSPEC2RATE500K(rspec) ((rspec & RSPEC_MIMORATE) ? \ + MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec))/500 :\ + (rspec & RSPEC_RATE_MASK)) + +#define RSPEC2KBPS(rspec) (IS_MCS(rspec) ? RSPEC2RATE(rspec) : RSPEC2RATE(rspec)*500) +#define RSPEC_PHYTXBYTE2(rspec) ((rspec & 0xff00) >> 8) +#define RSPEC_GET_BW(rspec) ((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT) +#define RSPEC_IS40MHZ(rspec) ((((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT) == \ + PHY_TXC1_BW_40MHZ) || (((rspec & RSPEC_BW_MASK) >> \ + RSPEC_BW_SHIFT) == PHY_TXC1_BW_40MHZ_DUP)) +#define RSPEC_ISSGI(rspec) ((rspec & RSPEC_SHORT_GI) == RSPEC_SHORT_GI) +#define RSPEC_MIMOPLCP3(rspec) ((rspec & 0xf00000) >> 16) +#define PLCP3_ISSGI(plcp) (plcp & (RSPEC_SHORT_GI >> 16)) +#define RSPEC_STC(rspec) ((rspec & RSPEC_STC_MASK) >> RSPEC_STC_SHIFT) +#define RSPEC_STF(rspec) ((rspec & RSPEC_STF_MASK) >> RSPEC_STF_SHIFT) +#define PLCP3_ISSTBC(plcp) ((plcp & (RSPEC_STC_MASK) >> 16) == 0x10) +#define PLCP3_STC_MASK 0x30 +#define PLCP3_STC_SHIFT 4 + +/* Rate info table; takes a legacy rate or ratespec_t */ +#define IS_MCS(r) (r & RSPEC_MIMORATE) +#define IS_OFDM(r) (!IS_MCS(r) && (rate_info[(r) & RSPEC_RATE_MASK] & WLC_RATE_FLAG)) +#define IS_CCK(r) (!IS_MCS(r) && (((r) & RATE_MASK) == WLC_RATE_1M || \ + ((r) & RATE_MASK) == WLC_RATE_2M || \ + ((r) & RATE_MASK) == WLC_RATE_5M5 || ((r) & RATE_MASK) == WLC_RATE_11M)) +#define IS_SINGLE_STREAM(mcs) (((mcs) <= HIGHEST_SINGLE_STREAM_MCS) || ((mcs) == 32)) +#define CCK_RSPEC(cck) ((cck) & RSPEC_RATE_MASK) +#define OFDM_RSPEC(ofdm) (((ofdm) & RSPEC_RATE_MASK) |\ + (PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT)) +#define LEGACY_RSPEC(rate) (IS_CCK(rate) ? CCK_RSPEC(rate) : OFDM_RSPEC(rate)) + +#define MCS_RSPEC(mcs) (((mcs) & RSPEC_RATE_MASK) | RSPEC_MIMORATE | \ + (IS_SINGLE_STREAM(mcs) ? (PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT) : \ + (PHY_TXC1_MODE_SDM << RSPEC_STF_SHIFT))) + +/* Convert encoded rate value in plcp header to numerical rates in 500 KHz increments */ +extern const u8 ofdm_rate_lookup[]; +#define OFDM_PHY2MAC_RATE(rlpt) (ofdm_rate_lookup[rlpt & 0x7]) +#define CCK_PHY2MAC_RATE(signal) (signal/5) + +/* Rates specified in wlc_rateset_filter() */ +#define WLC_RATES_CCK_OFDM 0 +#define WLC_RATES_CCK 1 +#define WLC_RATES_OFDM 2 + +/* use the stuct form instead of typedef to fix dependency problems */ +struct wlc_rateset; + +/* sanitize, and sort a rateset with the basic bit(s) preserved, validate rateset */ +extern bool wlc_rate_hwrs_filter_sort_validate(struct wlc_rateset *rs, + const struct wlc_rateset *hw_rs, + bool check_brate, + u8 txstreams); +/* copy rateset src to dst as-is (no masking or sorting) */ +extern void wlc_rateset_copy(const struct wlc_rateset *src, + struct wlc_rateset *dst); + +/* would be nice to have these documented ... */ +extern ratespec_t wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp); + +extern void wlc_rateset_filter(struct wlc_rateset *src, struct wlc_rateset *dst, + bool basic_only, u8 rates, uint xmask, + bool mcsallow); +extern void wlc_rateset_default(struct wlc_rateset *rs_tgt, + const struct wlc_rateset *rs_hw, uint phy_type, + int bandtype, bool cck_only, uint rate_mask, + bool mcsallow, u8 bw, u8 txstreams); +extern s16 wlc_rate_legacy_phyctl(uint rate); + +extern void wlc_rateset_mcs_upd(struct wlc_rateset *rs, u8 txstreams); +extern void wlc_rateset_mcs_clear(struct wlc_rateset *rateset); +extern void wlc_rateset_mcs_build(struct wlc_rateset *rateset, u8 txstreams); +extern void wlc_rateset_bw_mcs_filter(struct wlc_rateset *rateset, u8 bw); + +#endif /* _WLC_RATE_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_scb.h b/drivers/staging/brcm80211/brcmsmac/wlc_scb.h new file mode 100644 index 000000000000..142b75674444 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_scb.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_scb_h_ +#define _wlc_scb_h_ + +#include + +extern bool wlc_aggregatable(struct wlc_info *wlc, u8 tid); + +#define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */ +/* structure to store per-tid state for the ampdu initiator */ +typedef struct scb_ampdu_tid_ini { + u32 magic; + u8 tx_in_transit; /* number of pending mpdus in transit in driver */ + u8 tid; /* initiator tid for easy lookup */ + u8 txretry[AMPDU_TX_BA_MAX_WSIZE]; /* tx retry count; indexed by seq modulo */ + struct scb *scb; /* backptr for easy lookup */ +} scb_ampdu_tid_ini_t; + +#define AMPDU_MAX_SCB_TID NUMPRIO + +typedef struct scb_ampdu { + struct scb *scb; /* back pointer for easy reference */ + u8 mpdu_density; /* mpdu density */ + u8 max_pdu; /* max pdus allowed in ampdu */ + u8 release; /* # of mpdus released at a time */ + u16 min_len; /* min mpdu len to support the density */ + u32 max_rxlen; /* max ampdu rcv length; 8k, 16k, 32k, 64k */ + struct pktq txq; /* sdu transmit queue pending aggregation */ + + /* This could easily be a ini[] pointer and we keep this info in wl itself instead + * of having mac80211 hold it for us. Also could be made dynamic per tid instead of + * static. + */ + scb_ampdu_tid_ini_t ini[AMPDU_MAX_SCB_TID]; /* initiator info - per tid (NUMPRIO) */ +} scb_ampdu_t; + +#define SCB_MAGIC 0xbeefcafe +#define INI_MAGIC 0xabcd1234 + +/* station control block - one per remote MAC address */ +struct scb { + u32 magic; + u32 flags; /* various bit flags as defined below */ + u32 flags2; /* various bit flags2 as defined below */ + u8 state; /* current state bitfield of auth/assoc process */ + u8 ea[ETH_ALEN]; /* station address */ + void *fragbuf[NUMPRIO]; /* defragmentation buffer per prio */ + uint fragresid[NUMPRIO]; /* #bytes unused in frag buffer per prio */ + + u16 seqctl[NUMPRIO]; /* seqctl of last received frame (for dups) */ + u16 seqctl_nonqos; /* seqctl of last received frame (for dups) for + * non-QoS data and management + */ + u16 seqnum[NUMPRIO]; /* WME: driver maintained sw seqnum per priority */ + + scb_ampdu_t scb_ampdu; /* AMPDU state including per tid info */ +}; + +/* scb flags */ +#define SCB_WMECAP 0x0040 /* may ONLY be set if WME_ENAB(wlc) */ +#define SCB_HTCAP 0x10000 /* HT (MIMO) capable device */ +#define SCB_IS40 0x80000 /* 40MHz capable */ +#define SCB_STBCCAP 0x40000000 /* STBC Capable */ +#define SCB_WME(a) ((a)->flags & SCB_WMECAP)/* implies WME_ENAB */ +#define SCB_SEQNUM(scb, prio) ((scb)->seqnum[(prio)]) +#define SCB_PS(a) NULL +#define SCB_STBC_CAP(a) ((a)->flags & SCB_STBCCAP) +#define SCB_AMPDU(a) true +#endif /* _wlc_scb_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c new file mode 100644 index 000000000000..10c9f447cdf0 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c @@ -0,0 +1,600 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WLC_STF_SS_STBC_RX(wlc) (WLCISNPHY(wlc->band) && \ + NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6)) + +static s8 wlc_stf_stbc_rx_get(struct wlc_info *wlc); +static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val); +static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 val); +static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val); +static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val); + +static void _wlc_stf_phy_txant_upd(struct wlc_info *wlc); +static u16 _wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec); + +#define NSTS_1 1 +#define NSTS_2 2 +#define NSTS_3 3 +#define NSTS_4 4 +const u8 txcore_default[5] = { + (0), /* bitmap of the core enabled */ + (0x01), /* For Nsts = 1, enable core 1 */ + (0x03), /* For Nsts = 2, enable core 1 & 2 */ + (0x07), /* For Nsts = 3, enable core 1, 2 & 3 */ + (0x0f) /* For Nsts = 4, enable all cores */ +}; + +static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val) +{ + ASSERT((val == HT_CAP_RX_STBC_NO) + || (val == HT_CAP_RX_STBC_ONE_STREAM)); + + /* MIMOPHYs rev3-6 cannot receive STBC with only one rx core active */ + if (WLC_STF_SS_STBC_RX(wlc)) { + if ((wlc->stf->rxstreams == 1) && (val != HT_CAP_RX_STBC_NO)) + return; + } + + wlc->ht_cap.cap_info &= ~HT_CAP_RX_STBC_MASK; + wlc->ht_cap.cap_info |= (val << HT_CAP_RX_STBC_SHIFT); + + if (wlc->pub->up) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, true); + } +} + +/* every WLC_TEMPSENSE_PERIOD seconds temperature check to decide whether to turn on/off txchain */ +void wlc_tempsense_upd(struct wlc_info *wlc) +{ + wlc_phy_t *pi = wlc->band->pi; + uint active_chains, txchain; + + /* Check if the chip is too hot. Disable one Tx chain, if it is */ + /* high 4 bits are for Rx chain, low 4 bits are for Tx chain */ + active_chains = wlc_phy_stf_chain_active_get(pi); + txchain = active_chains & 0xf; + + if (wlc->stf->txchain == wlc->stf->hw_txchain) { + if (txchain && (txchain < wlc->stf->hw_txchain)) { + /* turn off 1 tx chain */ + wlc_stf_txchain_set(wlc, txchain, true); + } + } else if (wlc->stf->txchain < wlc->stf->hw_txchain) { + if (txchain == wlc->stf->hw_txchain) { + /* turn back on txchain */ + wlc_stf_txchain_set(wlc, txchain, true); + } + } +} + +void +wlc_stf_ss_algo_channel_get(struct wlc_info *wlc, u16 *ss_algo_channel, + chanspec_t chanspec) +{ + tx_power_t power; + u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id; + + /* Clear previous settings */ + *ss_algo_channel = 0; + + if (!wlc->pub->up) { + *ss_algo_channel = (u16) -1; + return; + } + + wlc_phy_txpower_get_current(wlc->band->pi, &power, + CHSPEC_CHANNEL(chanspec)); + + siso_mcs_id = (CHSPEC_IS40(chanspec)) ? + WL_TX_POWER_MCS40_SISO_FIRST : WL_TX_POWER_MCS20_SISO_FIRST; + cdd_mcs_id = (CHSPEC_IS40(chanspec)) ? + WL_TX_POWER_MCS40_CDD_FIRST : WL_TX_POWER_MCS20_CDD_FIRST; + stbc_mcs_id = (CHSPEC_IS40(chanspec)) ? + WL_TX_POWER_MCS40_STBC_FIRST : WL_TX_POWER_MCS20_STBC_FIRST; + + /* criteria to choose stf mode */ + + /* the "+3dbm (12 0.25db units)" is to account for the fact that with CDD, tx occurs + * on both chains + */ + if (power.target[siso_mcs_id] > (power.target[cdd_mcs_id] + 12)) + setbit(ss_algo_channel, PHY_TXC1_MODE_SISO); + else + setbit(ss_algo_channel, PHY_TXC1_MODE_CDD); + + /* STBC is ORed into to algo channel as STBC requires per-packet SCB capability check + * so cannot be default mode of operation. One of SISO, CDD have to be set + */ + if (power.target[siso_mcs_id] <= (power.target[stbc_mcs_id] + 12)) + setbit(ss_algo_channel, PHY_TXC1_MODE_STBC); +} + +static s8 wlc_stf_stbc_rx_get(struct wlc_info *wlc) +{ + return (wlc->ht_cap.cap_info & HT_CAP_RX_STBC_MASK) + >> HT_CAP_RX_STBC_SHIFT; +} + +static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val) +{ + if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON)) { + return false; + } + + if ((int_val == ON) && (wlc->stf->txstreams == 1)) + return false; + + if ((int_val == OFF) || (wlc->stf->txstreams == 1) + || !WLC_STBC_CAP_PHY(wlc)) + wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC; + else + wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_TX_STBC; + + wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = (s8) int_val; + wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = (s8) int_val; + + return true; +} + +bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val) +{ + if ((int_val != HT_CAP_RX_STBC_NO) + && (int_val != HT_CAP_RX_STBC_ONE_STREAM)) { + return false; + } + + if (WLC_STF_SS_STBC_RX(wlc)) { + if ((int_val != HT_CAP_RX_STBC_NO) + && (wlc->stf->rxstreams == 1)) + return false; + } + + wlc_stf_stbc_rx_ht_update(wlc, int_val); + return true; +} + +static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 core_mask) +{ + WL_TRACE("wl%d: %s: Nsts %d core_mask %x\n", + wlc->pub->unit, __func__, Nsts, core_mask); + + ASSERT((Nsts > 0) && (Nsts <= MAX_STREAMS_SUPPORTED)); + + if (WLC_BITSCNT(core_mask) > wlc->stf->txstreams) { + core_mask = 0; + } + + if ((WLC_BITSCNT(core_mask) == wlc->stf->txstreams) && + ((core_mask & ~wlc->stf->txchain) + || !(core_mask & wlc->stf->txchain))) { + core_mask = wlc->stf->txchain; + } + + ASSERT(!core_mask || Nsts <= WLC_BITSCNT(core_mask)); + + wlc->stf->txcore[Nsts] = core_mask; + /* Nsts = 1..4, txcore index = 1..4 */ + if (Nsts == 1) { + /* Needs to update beacon and ucode generated response + * frames when 1 stream core map changed + */ + wlc->stf->phytxant = core_mask << PHY_TXC_ANT_SHIFT; + wlc_bmac_txant_set(wlc->hw, wlc->stf->phytxant); + if (wlc->clk) { + wlc_suspend_mac_and_wait(wlc); + wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec); + wlc_enable_mac(wlc); + } + } + + return BCME_OK; +} + +static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val) +{ + int i; + u8 core_mask = 0; + + WL_TRACE("wl%d: %s: val %x\n", wlc->pub->unit, __func__, val); + + wlc->stf->spatial_policy = (s8) val; + for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) { + core_mask = (val == MAX_SPATIAL_EXPANSION) ? + wlc->stf->txchain : txcore_default[i]; + wlc_stf_txcore_set(wlc, (u8) i, core_mask); + } + return BCME_OK; +} + +int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force) +{ + u8 txchain = (u8) int_val; + u8 txstreams; + uint i; + + if (wlc->stf->txchain == txchain) + return BCME_OK; + + if ((txchain & ~wlc->stf->hw_txchain) + || !(txchain & wlc->stf->hw_txchain)) + return BCME_RANGE; + + /* if nrate override is configured to be non-SISO STF mode, reject reducing txchain to 1 */ + txstreams = (u8) WLC_BITSCNT(txchain); + if (txstreams > MAX_STREAMS_SUPPORTED) + return BCME_RANGE; + + if (txstreams == 1) { + for (i = 0; i < NBANDS(wlc); i++) + if ((RSPEC_STF(wlc->bandstate[i]->rspec_override) != + PHY_TXC1_MODE_SISO) + || (RSPEC_STF(wlc->bandstate[i]->mrspec_override) != + PHY_TXC1_MODE_SISO)) { + if (!force) + return BCME_ERROR; + + /* over-write the override rspec */ + if (RSPEC_STF(wlc->bandstate[i]->rspec_override) + != PHY_TXC1_MODE_SISO) { + wlc->bandstate[i]->rspec_override = 0; + WL_ERROR("%s(): temp sense override non-SISO rspec_override\n", + __func__); + } + if (RSPEC_STF + (wlc->bandstate[i]->mrspec_override) != + PHY_TXC1_MODE_SISO) { + wlc->bandstate[i]->mrspec_override = 0; + WL_ERROR("%s(): temp sense override non-SISO mrspec_override\n", + __func__); + } + } + } + + wlc->stf->txchain = txchain; + wlc->stf->txstreams = txstreams; + wlc_stf_stbc_tx_set(wlc, wlc->band->band_stf_stbc_tx); + wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); + wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); + wlc->stf->txant = + (wlc->stf->txstreams == 1) ? ANT_TX_FORCE_0 : ANT_TX_DEF; + _wlc_stf_phy_txant_upd(wlc); + + wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, + wlc->stf->rxchain); + + for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) + wlc_stf_txcore_set(wlc, (u8) i, txcore_default[i]); + + return BCME_OK; +} + +int wlc_stf_rxchain_set(struct wlc_info *wlc, s32 int_val) +{ + u8 rxchain_cnt; + u8 rxchain = (u8) int_val; + u8 mimops_mode; + u8 old_rxchain, old_rxchain_cnt; + + if (wlc->stf->rxchain == rxchain) + return BCME_OK; + + if ((rxchain & ~wlc->stf->hw_rxchain) + || !(rxchain & wlc->stf->hw_rxchain)) + return BCME_RANGE; + + rxchain_cnt = (u8) WLC_BITSCNT(rxchain); + if (WLC_STF_SS_STBC_RX(wlc)) { + if ((rxchain_cnt == 1) + && (wlc_stf_stbc_rx_get(wlc) != HT_CAP_RX_STBC_NO)) + return BCME_RANGE; + } + + if (APSTA_ENAB(wlc->pub) && (wlc->pub->associated)) + return BCME_ASSOCIATED; + + old_rxchain = wlc->stf->rxchain; + old_rxchain_cnt = wlc->stf->rxstreams; + + wlc->stf->rxchain = rxchain; + wlc->stf->rxstreams = rxchain_cnt; + + if (rxchain_cnt != old_rxchain_cnt) { + mimops_mode = + (rxchain_cnt == 1) ? HT_CAP_MIMO_PS_ON : HT_CAP_MIMO_PS_OFF; + wlc->mimops_PM = mimops_mode; + if (AP_ENAB(wlc->pub)) { + wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, + wlc->stf->rxchain); + wlc_ht_mimops_cap_update(wlc, mimops_mode); + if (wlc->pub->associated) + wlc_mimops_action_ht_send(wlc, wlc->cfg, + mimops_mode); + return BCME_OK; + } + if (wlc->pub->associated) { + if (mimops_mode == HT_CAP_MIMO_PS_OFF) { + /* if mimops is off, turn on the Rx chain first */ + wlc_phy_stf_chain_set(wlc->band->pi, + wlc->stf->txchain, + wlc->stf->rxchain); + wlc_ht_mimops_cap_update(wlc, mimops_mode); + } + } else { + wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, + wlc->stf->rxchain); + wlc_ht_mimops_cap_update(wlc, mimops_mode); + } + } else if (old_rxchain != rxchain) + wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, + wlc->stf->rxchain); + + return BCME_OK; +} + +/* update wlc->stf->ss_opmode which represents the operational stf_ss mode we're using */ +int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band) +{ + int ret_code = 0; + u8 prev_stf_ss; + u8 upd_stf_ss; + + prev_stf_ss = wlc->stf->ss_opmode; + + /* NOTE: opmode can only be SISO or CDD as STBC is decided on a per-packet basis */ + if (WLC_STBC_CAP_PHY(wlc) && + wlc->stf->ss_algosel_auto + && (wlc->stf->ss_algo_channel != (u16) -1)) { + ASSERT(isset(&wlc->stf->ss_algo_channel, PHY_TXC1_MODE_CDD) + || isset(&wlc->stf->ss_algo_channel, + PHY_TXC1_MODE_SISO)); + upd_stf_ss = (wlc->stf->no_cddstbc || (wlc->stf->txstreams == 1) + || isset(&wlc->stf->ss_algo_channel, + PHY_TXC1_MODE_SISO)) ? PHY_TXC1_MODE_SISO + : PHY_TXC1_MODE_CDD; + } else { + if (wlc->band != band) + return ret_code; + upd_stf_ss = (wlc->stf->no_cddstbc + || (wlc->stf->txstreams == + 1)) ? PHY_TXC1_MODE_SISO : band-> + band_stf_ss_mode; + } + if (prev_stf_ss != upd_stf_ss) { + wlc->stf->ss_opmode = upd_stf_ss; + wlc_bmac_band_stf_ss_set(wlc->hw, upd_stf_ss); + } + + return ret_code; +} + +int wlc_stf_attach(struct wlc_info *wlc) +{ + wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_SISO; + wlc->bandstate[BAND_5G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_CDD; + + if (WLCISNPHY(wlc->band) && + (wlc_phy_txpower_hw_ctrl_get(wlc->band->pi) != PHY_TPC_HW_ON)) + wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = + PHY_TXC1_MODE_CDD; + wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); + wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); + + wlc_stf_stbc_rx_ht_update(wlc, HT_CAP_RX_STBC_NO); + wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF; + wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF; + + if (WLC_STBC_CAP_PHY(wlc)) { + wlc->stf->ss_algosel_auto = true; + wlc->stf->ss_algo_channel = (u16) -1; /* Init the default value */ + } + return 0; +} + +void wlc_stf_detach(struct wlc_info *wlc) +{ +} + +int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val) +{ + int bcmerror = BCME_OK; + + /* when there is only 1 tx_streams, don't allow to change the txant */ + if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1)) + return ((val == wlc->stf->txant) ? bcmerror : BCME_RANGE); + + switch (val) { + case -1: + val = ANT_TX_DEF; + break; + case 0: + val = ANT_TX_FORCE_0; + break; + case 1: + val = ANT_TX_FORCE_1; + break; + case 3: + val = ANT_TX_LAST_RX; + break; + default: + bcmerror = BCME_RANGE; + break; + } + + if (bcmerror == BCME_OK) + wlc->stf->txant = (s8) val; + + return bcmerror; + +} + +/* + * Centralized txant update function. call it whenever wlc->stf->txant and/or wlc->stf->txchain + * change + * + * Antennas are controlled by ucode indirectly, which drives PHY or GPIO to + * achieve various tx/rx antenna selection schemes + * + * legacy phy, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means auto(last rx) + * for NREV<3, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means last rx and + * do tx-antenna selection for SISO transmissions + * for NREV=3, bit 6 and bit _8_ means antenna 0 and 1 respectively, bit6+bit7 means last rx and + * do tx-antenna selection for SISO transmissions + * for NREV>=7, bit 6 and bit 7 mean antenna 0 and 1 respectively, nit6+bit7 means both cores active +*/ +static void _wlc_stf_phy_txant_upd(struct wlc_info *wlc) +{ + s8 txant; + + txant = (s8) wlc->stf->txant; + ASSERT(txant == ANT_TX_FORCE_0 || txant == ANT_TX_FORCE_1 + || txant == ANT_TX_LAST_RX); + + if (WLC_PHY_11N_CAP(wlc->band)) { + if (txant == ANT_TX_FORCE_0) { + wlc->stf->phytxant = PHY_TXC_ANT_0; + } else if (txant == ANT_TX_FORCE_1) { + wlc->stf->phytxant = PHY_TXC_ANT_1; + + if (WLCISNPHY(wlc->band) && + NREV_GE(wlc->band->phyrev, 3) + && NREV_LT(wlc->band->phyrev, 7)) { + wlc->stf->phytxant = PHY_TXC_ANT_2; + } + } else { + if (WLCISLCNPHY(wlc->band) || WLCISSSLPNPHY(wlc->band)) + wlc->stf->phytxant = PHY_TXC_LCNPHY_ANT_LAST; + else { + /* keep this assert to catch out of sync wlc->stf->txcore */ + ASSERT(wlc->stf->txchain > 0); + wlc->stf->phytxant = + wlc->stf->txchain << PHY_TXC_ANT_SHIFT; + } + } + } else { + if (txant == ANT_TX_FORCE_0) + wlc->stf->phytxant = PHY_TXC_OLD_ANT_0; + else if (txant == ANT_TX_FORCE_1) + wlc->stf->phytxant = PHY_TXC_OLD_ANT_1; + else + wlc->stf->phytxant = PHY_TXC_OLD_ANT_LAST; + } + + wlc_bmac_txant_set(wlc->hw, wlc->stf->phytxant); +} + +void wlc_stf_phy_txant_upd(struct wlc_info *wlc) +{ + _wlc_stf_phy_txant_upd(wlc); +} + +void wlc_stf_phy_chain_calc(struct wlc_info *wlc) +{ + /* get available rx/tx chains */ + wlc->stf->hw_txchain = (u8) getintvar(wlc->pub->vars, "txchain"); + wlc->stf->hw_rxchain = (u8) getintvar(wlc->pub->vars, "rxchain"); + + /* these parameter are intended to be used for all PHY types */ + if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) { + if (WLCISNPHY(wlc->band)) { + wlc->stf->hw_txchain = TXCHAIN_DEF_NPHY; + } else { + wlc->stf->hw_txchain = TXCHAIN_DEF; + } + } + + wlc->stf->txchain = wlc->stf->hw_txchain; + wlc->stf->txstreams = (u8) WLC_BITSCNT(wlc->stf->hw_txchain); + + if (wlc->stf->hw_rxchain == 0 || wlc->stf->hw_rxchain == 0xf) { + if (WLCISNPHY(wlc->band)) { + wlc->stf->hw_rxchain = RXCHAIN_DEF_NPHY; + } else { + wlc->stf->hw_rxchain = RXCHAIN_DEF; + } + } + + wlc->stf->rxchain = wlc->stf->hw_rxchain; + wlc->stf->rxstreams = (u8) WLC_BITSCNT(wlc->stf->hw_rxchain); + + /* initialize the txcore table */ + bcopy(txcore_default, wlc->stf->txcore, sizeof(wlc->stf->txcore)); + + /* default spatial_policy */ + wlc->stf->spatial_policy = MIN_SPATIAL_EXPANSION; + wlc_stf_spatial_policy_set(wlc, MIN_SPATIAL_EXPANSION); +} + +static u16 _wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec) +{ + u16 phytxant = wlc->stf->phytxant; + + if (RSPEC_STF(rspec) != PHY_TXC1_MODE_SISO) { + ASSERT(wlc->stf->txstreams > 1); + phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT; + } else if (wlc->stf->txant == ANT_TX_DEF) + phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT; + phytxant &= PHY_TXC_ANT_MASK; + return phytxant; +} + +u16 wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec) +{ + return _wlc_stf_phytxchain_sel(wlc, rspec); +} + +u16 wlc_stf_d11hdrs_phyctl_txant(struct wlc_info *wlc, ratespec_t rspec) +{ + u16 phytxant = wlc->stf->phytxant; + u16 mask = PHY_TXC_ANT_MASK; + + /* for non-siso rates or default setting, use the available chains */ + if (WLCISNPHY(wlc->band)) { + ASSERT(wlc->stf->txchain != 0); + phytxant = _wlc_stf_phytxchain_sel(wlc, rspec); + mask = PHY_TXC_HTANT_MASK; + } + phytxant |= phytxant & mask; + return phytxant; +} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.h b/drivers/staging/brcm80211/brcmsmac/wlc_stf.h new file mode 100644 index 000000000000..8de6382e620d --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_stf.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_stf_h_ +#define _wlc_stf_h_ + +#define MIN_SPATIAL_EXPANSION 0 +#define MAX_SPATIAL_EXPANSION 1 + +extern int wlc_stf_attach(struct wlc_info *wlc); +extern void wlc_stf_detach(struct wlc_info *wlc); + +extern void wlc_tempsense_upd(struct wlc_info *wlc); +extern void wlc_stf_ss_algo_channel_get(struct wlc_info *wlc, + u16 *ss_algo_channel, + chanspec_t chanspec); +extern int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band); +extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc); +extern int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force); +extern int wlc_stf_rxchain_set(struct wlc_info *wlc, s32 int_val); +extern bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val); + +extern int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val); +extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc); +extern void wlc_stf_phy_chain_calc(struct wlc_info *wlc); +extern u16 wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec); +extern u16 wlc_stf_d11hdrs_phyctl_txant(struct wlc_info *wlc, ratespec_t rspec); +extern u16 wlc_stf_spatial_expansion_get(struct wlc_info *wlc, + ratespec_t rspec); +#endif /* _wlc_stf_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_types.h b/drivers/staging/brcm80211/brcmsmac/wlc_types.h new file mode 100644 index 000000000000..df6e04c6ac58 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_types.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_types_h_ +#define _wlc_types_h_ + +/* forward declarations */ + +struct wlc_info; +struct wlc_hw_info; +struct wlc_if; +struct wl_if; +struct ampdu_info; +struct antsel_info; +struct bmac_pmq; + +struct d11init; + +#ifndef _hnddma_pub_ +#define _hnddma_pub_ +struct hnddma_pub; +#endif /* _hnddma_pub_ */ + +#endif /* _wlc_types_h_ */ -- cgit v1.2.3 From c836f77fdba3631e295e3da1718ab53a9038fdf2 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 21 Jan 2011 10:54:52 +0100 Subject: staging: brcm80211: use KBUILD_MODNAME as driver name in registration The driver name was hardcoded and not same as the kernel module file being build. Although there may be no strong requirement to this it may provide increased consistency. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 2 +- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 28ddf1b69aac..29fff596c168 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -149,7 +149,7 @@ static struct platform_driver wifi_device = { .suspend = wifi_suspend, .resume = wifi_resume, .driver = { - .name = "bcm4329_wlan", + .name = KBUILD_MODNAME, } }; diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 6bc6207bab3e..f9ba048837be 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -1184,14 +1184,14 @@ static void wl_remove(struct pci_dev *pdev) } static struct pci_driver wl_pci_driver = { - .name = "brcm80211", - .probe = wl_pci_probe, + .name = KBUILD_MODNAME, + .probe = wl_pci_probe, #ifdef LINUXSTA_PS - .suspend = wl_suspend, - .resume = wl_resume, + .suspend = wl_suspend, + .resume = wl_resume, #endif /* LINUXSTA_PS */ - .remove = __devexit_p(wl_remove), - .id_table = wl_id_table, + .remove = __devexit_p(wl_remove), + .id_table = wl_id_table, }; /** -- cgit v1.2.3 From ed3556d17ce1a3ff2d5eeb9c78a1fbfc3d5b564d Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 21 Jan 2011 11:20:06 +0100 Subject: staging: brcm80211: remove unused function from bcmwifi.c Working through a list of unused functions in the driver tree. This file has following redundant function(s): wf_chspec_ctlchspec Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/bcmwifi.h | 7 ------- drivers/staging/brcm80211/util/bcmwifi.c | 23 ----------------------- 2 files changed, 30 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/bcmwifi.h b/drivers/staging/brcm80211/include/bcmwifi.h index 4978df8660bb..4a0f976afaa4 100644 --- a/drivers/staging/brcm80211/include/bcmwifi.h +++ b/drivers/staging/brcm80211/include/bcmwifi.h @@ -143,13 +143,6 @@ extern bool wf_chspec_malformed(chanspec_t chanspec); */ extern u8 wf_chspec_ctlchan(chanspec_t chspec); -/* - * This function returns the chanspec that control traffic is being sent on, for legacy - * channels this is just the chanspec, for 40MHZ channels it is the upper or lowre 20MHZ - * sideband depending on the chanspec selected - */ -extern chanspec_t wf_chspec_ctlchspec(chanspec_t chspec); - /* * Return the channel number for a given frequency and base frequency. * The returned channel number is relative to the given base frequency. diff --git a/drivers/staging/brcm80211/util/bcmwifi.c b/drivers/staging/brcm80211/util/bcmwifi.c index b22d14b9aef4..3d3e5eaddefe 100644 --- a/drivers/staging/brcm80211/util/bcmwifi.c +++ b/drivers/staging/brcm80211/util/bcmwifi.c @@ -79,29 +79,6 @@ u8 wf_chspec_ctlchan(chanspec_t chspec) return ctl_chan; } -chanspec_t wf_chspec_ctlchspec(chanspec_t chspec) -{ - chanspec_t ctl_chspec = 0; - u8 channel; - - ASSERT(!wf_chspec_malformed(chspec)); - - /* Is there a sideband ? */ - if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) { - return chspec; - } else { - if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) { - channel = UPPER_20_SB(CHSPEC_CHANNEL(chspec)); - } else { - channel = LOWER_20_SB(CHSPEC_CHANNEL(chspec)); - } - ctl_chspec = - channel | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE; - ctl_chspec |= CHSPEC_BAND(chspec); - } - return ctl_chspec; -} - /* * Return the channel number for a given frequency and base frequency. * The returned channel number is relative to the given base frequency. -- cgit v1.2.3 From 072c35ada2fcb3fe925f0c1b3c2793010c3f1f86 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 21 Jan 2011 11:20:07 +0100 Subject: staging: brcm80211: remove unused function from dhd_cdc.c Working through a list of unused functions in the driver tree. This file has following redundant function(s): dhd_proto_fcinfo Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_cdc.c | 20 -------------------- drivers/staging/brcm80211/brcmfmac/dhd_proto.h | 3 --- 2 files changed, 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c index e491da071a74..09461e6f7c81 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c @@ -345,26 +345,6 @@ void dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, struct sk_buff *pktbuf) BDC_SET_IF_IDX(h, ifidx); } -bool dhd_proto_fcinfo(dhd_pub_t *dhd, struct sk_buff *pktbuf, u8 * fcbits) -{ -#ifdef BDC - struct bdc_header *h; - - if (pktbuf->len < BDC_HEADER_LEN) { - DHD_ERROR(("%s: rx data too short (%d < %d)\n", - __func__, pktbuf->len, BDC_HEADER_LEN)); - return BCME_ERROR; - } - - h = (struct bdc_header *)(pktbuf->data); - - *fcbits = h->priority >> BDC_PRIORITY_FC_SHIFT; - if ((h->flags2 & BDC_FLAG2_FC_FLAG) == BDC_FLAG2_FC_FLAG) - return true; -#endif - return false; -} - int dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, struct sk_buff *pktbuf) { #ifdef BDC diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_proto.h b/drivers/staging/brcm80211/brcmfmac/dhd_proto.h index a5309e27b65b..030d5ffb0e83 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_proto.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd_proto.h @@ -46,9 +46,6 @@ extern int dhd_prot_init(dhd_pub_t *dhdp); /* Stop protocol: sync w/dongle state. */ extern void dhd_prot_stop(dhd_pub_t *dhdp); -extern bool dhd_proto_fcinfo(dhd_pub_t *dhd, struct sk_buff *pktbuf, - u8 *fcbits); - /* Add any protocol-specific data header. * Caller must reserve prot_hdrlen prepend space. */ -- cgit v1.2.3 From bea4238e17a7d9f81c982087b2b46646f8ff7cea Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 21 Jan 2011 11:20:08 +0100 Subject: staging: brcm80211: remove unused function from dhd_common.c Working through a list of unused functions in the driver tree. This file has following redundant function(s): dhd_store_conn_status print_buf wl_event_to_host_order Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd.h | 3 -- drivers/staging/brcm80211/brcmfmac/dhd_common.c | 51 ------------------------- 2 files changed, 54 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd.h b/drivers/staging/brcm80211/brcmfmac/dhd.h index 3be1bdb344ae..014a2dea7868 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd.h @@ -308,7 +308,6 @@ extern int dhd_ifname2idx(struct dhd_info *dhd, char *name); extern u8 *dhd_bssidx2bssid(dhd_pub_t *dhd, int idx); extern int wl_host_event(struct dhd_info *dhd, int *idx, void *pktdata, wl_event_msg_t *, void **data_ptr); -extern void wl_event_to_host_order(wl_event_msg_t *evt); extern void dhd_common_init(void); @@ -333,8 +332,6 @@ extern int dhd_bus_devreset(dhd_pub_t *dhdp, u8 flag); extern uint dhd_bus_status(dhd_pub_t *dhdp); extern int dhd_bus_start(dhd_pub_t *dhdp); -extern void print_buf(void *pbuf, int len, int bytes_per_line); - typedef enum cust_gpio_modes { WLAN_RESET_ON, WLAN_RESET_OFF, diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index 1799ee68d097..5165251cfe2f 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -312,21 +312,6 @@ exit: return bcmerror; } -/* Store the status of a connection attempt for later retrieval by an iovar */ -void dhd_store_conn_status(u32 event, u32 status, u32 reason) -{ - /* Do not overwrite a WLC_E_PRUNE with a WLC_E_SET_SSID - * because an encryption/rsn mismatch results in both events, and - * the important information is in the WLC_E_PRUNE. - */ - if (!(event == WLC_E_SET_SSID && status == WLC_E_STATUS_FAIL && - dhd_conn_event == WLC_E_PRUNE)) { - dhd_conn_event = event; - dhd_conn_status = status; - dhd_conn_reason = reason; - } -} - bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, struct sk_buff *pkt, int prec) { @@ -926,42 +911,6 @@ wl_host_event(struct dhd_info *dhd, int *ifidx, void *pktdata, return BCME_OK; } -void wl_event_to_host_order(wl_event_msg_t *evt) -{ - /* Event struct members passed from dongle to host are stored - * in network - * byte order. Convert all members to host-order. - */ - evt->event_type = ntoh32(evt->event_type); - evt->flags = ntoh16(evt->flags); - evt->status = ntoh32(evt->status); - evt->reason = ntoh32(evt->reason); - evt->auth_type = ntoh32(evt->auth_type); - evt->datalen = ntoh32(evt->datalen); - evt->version = ntoh16(evt->version); -} - -void print_buf(void *pbuf, int len, int bytes_per_line) -{ - int i, j = 0; - unsigned char *buf = pbuf; - - if (bytes_per_line == 0) - bytes_per_line = len; - - for (i = 0; i < len; i++) { - printf("%2.2x", *buf++); - j++; - if (j == bytes_per_line) { - printf("\n"); - j = 0; - } else { - printf(":"); - } - } - printf("\n"); -} - /* Convert user's input in hex pattern to byte-size mask */ static int wl_pattern_atoh(char *src, char *dst) { -- cgit v1.2.3 From 4e9dc61ffdcf1ba7dcdbd7d31137f02c5e57873b Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 21 Jan 2011 11:20:09 +0100 Subject: staging: brcm80211: remove unused inline funtion from siutils.h The header file contains a inline function, but it is not used by the driver sources: si_seci_init Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/siutils.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/siutils.h b/drivers/staging/brcm80211/include/siutils.h index a935092d02df..47b6a3090960 100644 --- a/drivers/staging/brcm80211/include/siutils.h +++ b/drivers/staging/brcm80211/include/siutils.h @@ -173,10 +173,6 @@ extern void si_sdio_init(si_t *sih); #define si_eci_init(sih) (0) #define si_eci_notify_bt(sih, type, val) (0) #define si_seci(sih) 0 -static inline void *si_seci_init(si_t *sih, u8 use_seci) -{ - return NULL; -} /* OTP status */ extern bool si_is_otp_disabled(si_t *sih); -- cgit v1.2.3 From fd04e62715d5a5cbdf6b1721276295e81aa54327 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 21 Jan 2011 11:20:10 +0100 Subject: staging: brcm80211: remove unused functions from sbutils.c Cleaning up unused function from the driver sources. This file contained the following unused functioin(s): sb_base sb_taclear sb_serr_clear Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/util/sbutils.c | 111 -------------------------- drivers/staging/brcm80211/util/siutils_priv.h | 2 - 2 files changed, 113 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/util/sbutils.c b/drivers/staging/brcm80211/util/sbutils.c index 63c3ab1866a4..6d63dc1fca11 100644 --- a/drivers/staging/brcm80211/util/sbutils.c +++ b/drivers/staging/brcm80211/util/sbutils.c @@ -368,94 +368,6 @@ static void *_sb_setcoreidx(si_info_t *sii, uint coreidx) return regs; } -/* traverse all cores to find and clear source of serror */ -static void sb_serr_clear(si_info_t *sii) -{ - sbconfig_t *sb; - uint origidx; - uint i, intr_val = 0; - void *corereg = NULL; - - INTR_OFF(sii, intr_val); - origidx = si_coreidx(&sii->pub); - - for (i = 0; i < sii->numcores; i++) { - corereg = sb_setcoreidx(&sii->pub, i); - if (NULL != corereg) { - sb = REGS2SB(corereg); - if ((R_SBREG(sii, &sb->sbtmstatehigh)) & SBTMH_SERR) { - AND_SBREG(sii, &sb->sbtmstatehigh, ~SBTMH_SERR); - SI_ERROR(("sb_serr_clear: SError core 0x%x\n", - sb_coreid(&sii->pub))); - } - } - } - - sb_setcoreidx(&sii->pub, origidx); - INTR_RESTORE(sii, intr_val); -} - -/* - * Check if any inband, outband or timeout errors has happened and clear them. - * Must be called with chip clk on ! - */ -bool sb_taclear(si_t *sih, bool details) -{ - si_info_t *sii; - sbconfig_t *sb; - uint origidx; - uint intr_val = 0; - bool rc = false; - u32 inband = 0, serror = 0, timeout = 0; - void *corereg = NULL; - volatile u32 imstate, tmstate; - - sii = SI_INFO(sih); - - if ((sii->pub.bustype == SDIO_BUS) || - (sii->pub.bustype == SPI_BUS)) { - - INTR_OFF(sii, intr_val); - origidx = si_coreidx(sih); - - corereg = si_setcore(sih, PCMCIA_CORE_ID, 0); - if (NULL == corereg) - corereg = si_setcore(sih, SDIOD_CORE_ID, 0); - if (NULL != corereg) { - sb = REGS2SB(corereg); - - imstate = R_SBREG(sii, &sb->sbimstate); - if ((imstate != 0xffffffff) - && (imstate & (SBIM_IBE | SBIM_TO))) { - AND_SBREG(sii, &sb->sbimstate, - ~(SBIM_IBE | SBIM_TO)); - /* inband = imstate & SBIM_IBE; cmd error */ - timeout = imstate & SBIM_TO; - } - tmstate = R_SBREG(sii, &sb->sbtmstatehigh); - if ((tmstate != 0xffffffff) - && (tmstate & SBTMH_INT_STATUS)) { - sb_serr_clear(sii); - serror = 1; - OR_SBREG(sii, &sb->sbtmstatelow, SBTML_INT_ACK); - AND_SBREG(sii, &sb->sbtmstatelow, - ~SBTML_INT_ACK); - } - } - - sb_setcoreidx(sih, origidx); - INTR_RESTORE(sii, intr_val); - } - - if (inband | timeout | serror) { - rc = true; - SI_ERROR(("sb_taclear: inband 0x%x, serror 0x%x, timeout " - "0x%x!\n", inband, serror, timeout)); - } - - return rc; -} - void sb_core_disable(si_t *sih, u32 bits) { si_info_t *sii; @@ -563,26 +475,3 @@ void sb_core_reset(si_t *sih, u32 bits, u32 resetbits) dummy = R_SBREG(sii, &sb->sbtmstatelow); udelay(1); } - -u32 sb_base(u32 admatch) -{ - u32 base; - uint type; - - type = admatch & SBAM_TYPE_MASK; - ASSERT(type < 3); - - base = 0; - - if (type == 0) { - base = admatch & SBAM_BASE0_MASK; - } else if (type == 1) { - ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ - base = admatch & SBAM_BASE1_MASK; - } else if (type == 2) { - ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ - base = admatch & SBAM_BASE2_MASK; - } - - return base; -} diff --git a/drivers/staging/brcm80211/util/siutils_priv.h b/drivers/staging/brcm80211/util/siutils_priv.h index 028461441481..a03ff617531a 100644 --- a/drivers/staging/brcm80211/util/siutils_priv.h +++ b/drivers/staging/brcm80211/util/siutils_priv.h @@ -25,8 +25,6 @@ extern uint sb_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); extern bool sb_iscoreup(si_t *sih); void *sb_setcoreidx(si_t *sih, uint coreidx); -extern u32 sb_base(u32 admatch); extern void sb_core_reset(si_t *sih, u32 bits, u32 resetbits); extern void sb_core_disable(si_t *sih, u32 bits); -extern bool sb_taclear(si_t *sih, bool details); #endif /* _siutils_priv_h_ */ -- cgit v1.2.3 From f3237e56b995367448f717a0dddcd76e0743bfdb Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 21 Jan 2011 11:20:11 +0100 Subject: staging: brcm80211: remove unused function from wlc_bmac.c Working through a list of unused functions in the driver tree. This file has following redundant function(s): wlc_bmac_set_hw_etheraddr wlc_cur_phy wlc_bmac_revinfo_get wlc_bmac_set_deaf wlc_bmac_xmtfifo_sz_set wlc_bmac_ifsctl_edcrs_set wlc_bmac_set_ucode_loaded wlc_bmac_set_clk wlc_gpio_fast_deinit wlc_bmac_radio_hw wlc_bmac_set_txpwr_percent Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 194 +------------------------- drivers/staging/brcm80211/brcmsmac/wlc_bmac.h | 15 -- 2 files changed, 2 insertions(+), 207 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index e22ce1f79660..80716c544781 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -175,7 +175,7 @@ void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot) { wlc_hw->shortslot = shortslot; - if (BAND_2G(wlc_hw->band->bandtype) && wlc_hw->up) { + if (BAND_2G(wlc_bmac_bandtype(wlc_hw)) && wlc_hw->up) { wlc_suspend_mac_and_wait(wlc_hw->wlc); wlc_bmac_update_slot_timing(wlc_hw, shortslot); wlc_enable_mac(wlc_hw->wlc); @@ -526,45 +526,6 @@ wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, } } -int wlc_bmac_revinfo_get(struct wlc_hw_info *wlc_hw, - wlc_bmac_revinfo_t *revinfo) -{ - si_t *sih = wlc_hw->sih; - uint idx; - - revinfo->vendorid = wlc_hw->vendorid; - revinfo->deviceid = wlc_hw->deviceid; - - revinfo->boardrev = wlc_hw->boardrev; - revinfo->corerev = wlc_hw->corerev; - revinfo->sromrev = wlc_hw->sromrev; - revinfo->chiprev = sih->chiprev; - revinfo->chip = sih->chip; - revinfo->chippkg = sih->chippkg; - revinfo->boardtype = sih->boardtype; - revinfo->boardvendor = sih->boardvendor; - revinfo->bustype = sih->bustype; - revinfo->buscoretype = sih->buscoretype; - revinfo->buscorerev = sih->buscorerev; - revinfo->issim = sih->issim; - - revinfo->nbands = NBANDS_HW(wlc_hw); - - for (idx = 0; idx < NBANDS_HW(wlc_hw); idx++) { - wlc_hwband_t *band = wlc_hw->bandstate[idx]; - revinfo->band[idx].bandunit = band->bandunit; - revinfo->band[idx].bandtype = band->bandtype; - revinfo->band[idx].phytype = band->phytype; - revinfo->band[idx].phyrev = band->phyrev; - revinfo->band[idx].radioid = band->radioid; - revinfo->band[idx].radiorev = band->radiorev; - revinfo->band[idx].abgphy_encore = band->abgphy_encore; - revinfo->band[idx].anarev = 0; - - } - return 0; -} - int wlc_bmac_state_get(struct wlc_hw_info *wlc_hw, wlc_bmac_state_t *state) { state->machwcap = wlc_hw->machwcap; @@ -938,7 +899,7 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, /* Get a phy for this band */ wlc_hw->band->pi = wlc_phy_attach(wlc_hw->phy_sh, - (void *)regs, wlc_hw->band->bandtype, vars); + (void *)regs, wlc_bmac_bandtype(wlc_hw), vars); if (wlc_hw->band->pi == NULL) { WL_ERROR("wl%d: wlc_bmac_attach: wlc_phy_attach failed\n", unit); @@ -1353,23 +1314,11 @@ void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, u8 *ea) bcopy(wlc_hw->etheraddr, ea, ETH_ALEN); } -void wlc_bmac_set_hw_etheraddr(struct wlc_hw_info *wlc_hw, - u8 *ea) -{ - bcopy(ea, wlc_hw->etheraddr, ETH_ALEN); -} - int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw) { return wlc_hw->band->bandtype; } -void *wlc_cur_phy(struct wlc_info *wlc) -{ - struct wlc_hw_info *wlc_hw = wlc->hw; - return (void *)wlc_hw->band->pi; -} - /* control chip clock to save power, enable dynamic clock or force fast clock */ static void wlc_clkctl_clk(struct wlc_hw_info *wlc_hw, uint mode) { @@ -3075,11 +3024,6 @@ void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool on, mbool flags) wlc_ucode_mute_override_clear(wlc_hw); } -void wlc_bmac_set_deaf(struct wlc_hw_info *wlc_hw, bool user_flag) -{ - wlc_phy_set_deaf(wlc_hw->band->pi, user_flag); -} - int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, uint *blocks) { if (fifo >= NFIFO) @@ -3090,17 +3034,6 @@ int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, uint *blocks) return 0; } -int wlc_bmac_xmtfifo_sz_set(struct wlc_hw_info *wlc_hw, uint fifo, uint blocks) -{ - if (fifo >= NFIFO || blocks > 299) - return BCME_RANGE; - - /* BMAC_NOTE, change blocks to u16 */ - wlc_hw->xmtfifo_sz[fifo] = (u16) blocks; - - return 0; -} - /* wlc_bmac_tx_fifo_suspended: * Check the MAC's tx suspend status for a tx fifo. * @@ -3561,42 +3494,6 @@ void wlc_enable_mac(struct wlc_info *wlc) wlc_ucode_wake_override_clear(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND); } -void wlc_bmac_ifsctl_edcrs_set(struct wlc_hw_info *wlc_hw, bool abie, bool isht) -{ - if (!(WLCISNPHY(wlc_hw->band) && (D11REV_GE(wlc_hw->corerev, 16)))) - return; - - if (isht) { - if (WLCISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 3)) { - AND_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - ~IFS_CTL1_EDCRS); - } - } else { - /* enable EDCRS for non-11n association */ - OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, IFS_CTL1_EDCRS); - } - - if (WLCISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3)) { - if (CHSPEC_IS20(wlc_hw->chanspec)) { - /* 20 mhz, use 20U ED only */ - OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - IFS_CTL1_EDCRS); - AND_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - ~IFS_CTL1_EDCRS_20L); - AND_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - ~IFS_CTL1_EDCRS_40); - } else { - /* 40 mhz, use 20U 20L and 40 ED */ - OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - IFS_CTL1_EDCRS); - OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - IFS_CTL1_EDCRS_20L); - OR_REG(wlc_hw->osh, &wlc_hw->regs->ifs_ctl1, - IFS_CTL1_EDCRS_40); - } - } -} - static void wlc_upd_ofdm_pctl1_table(struct wlc_hw_info *wlc_hw) { u8 rate; @@ -4081,11 +3978,6 @@ void wlc_bmac_set_noreset(struct wlc_hw_info *wlc_hw, bool noreset_flag) wlc_hw->noreset = noreset_flag; } -void wlc_bmac_set_ucode_loaded(struct wlc_hw_info *wlc_hw, bool ucode_loaded) -{ - wlc_hw->ucode_loaded = ucode_loaded; -} - void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, mbool req_bit) { ASSERT(req_bit); @@ -4117,89 +4009,12 @@ void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, mbool req_bit) return; } -void wlc_bmac_set_clk(struct wlc_hw_info *wlc_hw, bool on) -{ - if (on) { - /* power up pll and oscillator */ - wlc_bmac_xtal(wlc_hw, ON); - - /* enable core(s), ignore bandlocked - * Leave with the same band selected as we entered - */ - wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); - } else { - /* if already down, must skip the core disable */ - if (wlc_hw->clk) { - /* disable core(s), ignore bandlocked */ - wlc_coredisable(wlc_hw); - } - /* power down pll and oscillator */ - wlc_bmac_xtal(wlc_hw, OFF); - } -} - /* this will be true for all ai chips */ bool wlc_bmac_taclear(struct wlc_hw_info *wlc_hw, bool ta_ok) { return true; } -/* Lower down relevant GPIOs like LED when going down w/o - * doing PCI config cycles or touching interrupts - */ -void wlc_gpio_fast_deinit(struct wlc_hw_info *wlc_hw) -{ - if ((wlc_hw == NULL) || (wlc_hw->sih == NULL)) - return; - - /* Only chips with internal bus or PCIE cores or certain PCI cores - * are able to switch cores w/o disabling interrupts - */ - if (!((wlc_hw->sih->bustype == SI_BUS) || - ((wlc_hw->sih->bustype == PCI_BUS) && - ((wlc_hw->sih->buscoretype == PCIE_CORE_ID) || - (wlc_hw->sih->buscorerev >= 13))))) - return; - - WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); - return; -} - -bool wlc_bmac_radio_hw(struct wlc_hw_info *wlc_hw, bool enable) -{ - /* Do not access Phy registers if core is not up */ - if (si_iscoreup(wlc_hw->sih) == false) - return false; - - if (enable) { - if (PMUCTL_ENAB(wlc_hw->sih)) { - AND_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, - ~CCS_FORCEHWREQOFF); - si_pmu_radio_enable(wlc_hw->sih, true); - } - - wlc_phy_anacore(wlc_hw->band->pi, ON); - wlc_phy_switch_radio(wlc_hw->band->pi, ON); - - /* resume d11 core */ - wlc_enable_mac(wlc_hw->wlc); - } else { - /* suspend d11 core */ - wlc_suspend_mac_and_wait(wlc_hw->wlc); - - wlc_phy_switch_radio(wlc_hw->band->pi, OFF); - wlc_phy_anacore(wlc_hw->band->pi, OFF); - - if (PMUCTL_ENAB(wlc_hw->sih)) { - si_pmu_radio_enable(wlc_hw->sih, false); - OR_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, - CCS_FORCEHWREQOFF); - } - } - - return true; -} - u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate) { u16 table_ptr; @@ -4224,11 +4039,6 @@ u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate) return 2 * wlc_bmac_read_shm(wlc_hw, table_ptr + (index * 2)); } -void wlc_bmac_set_txpwr_percent(struct wlc_hw_info *wlc_hw, u8 val) -{ - wlc_phy_txpwr_percent_set(wlc_hw->band->pi, val); -} - void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail) { wlc_hw->antsel_avail = antsel_avail; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h index 03ce9521d652..49739e631b56 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h @@ -182,14 +182,10 @@ extern void wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, u16 val, int bands); extern void wlc_bmac_mctrl(struct wlc_hw_info *wlc_hw, u32 mask, u32 val); extern u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands); -extern int wlc_bmac_xmtfifo_sz_set(struct wlc_hw_info *wlc_hw, uint fifo, - uint blocks); extern void wlc_bmac_txant_set(struct wlc_hw_info *wlc_hw, u16 phytxant); extern u16 wlc_bmac_get_txant(struct wlc_hw_info *wlc_hw); extern void wlc_bmac_antsel_type_set(struct wlc_hw_info *wlc_hw, u8 antsel_type); -extern int wlc_bmac_revinfo_get(struct wlc_hw_info *wlc_hw, - wlc_bmac_revinfo_t *revinfo); extern int wlc_bmac_state_get(struct wlc_hw_info *wlc_hw, wlc_bmac_state_t *state); extern void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v); @@ -205,14 +201,11 @@ extern void wlc_bmac_process_ps_switch(struct wlc_hw_info *wlc, struct ether_addr *ea, s8 ps_on); extern void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, u8 *ea); -extern void wlc_bmac_set_hw_etheraddr(struct wlc_hw_info *wlc_hw, - u8 *ea); extern bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw); extern bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw); extern void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot); extern void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool want, mbool flags); -extern void wlc_bmac_set_deaf(struct wlc_hw_info *wlc_hw, bool user_flag); extern void wlc_bmac_band_stf_ss_set(struct wlc_hw_info *wlc_hw, u8 stf_mode); extern void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw); @@ -239,8 +232,6 @@ extern void wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr, extern void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin); extern void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax); extern void wlc_bmac_set_noreset(struct wlc_hw_info *wlc, bool noreset_flag); -extern void wlc_bmac_set_ucode_loaded(struct wlc_hw_info *wlc, - bool ucode_loaded); extern void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL, u16 LRL); @@ -253,21 +244,15 @@ extern void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw); extern void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw); extern void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, mbool req_bit); -extern void wlc_bmac_set_clk(struct wlc_hw_info *wlc_hw, bool on); extern bool wlc_bmac_taclear(struct wlc_hw_info *wlc_hw, bool ta_ok); extern void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw); extern void wlc_bmac_dump(struct wlc_hw_info *wlc_hw, struct bcmstrbuf *b, wlc_bmac_dump_id_t dump_id); -extern void wlc_gpio_fast_deinit(struct wlc_hw_info *wlc_hw); -extern bool wlc_bmac_radio_hw(struct wlc_hw_info *wlc_hw, bool enable); extern u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate); extern void wlc_bmac_assert_type_set(struct wlc_hw_info *wlc_hw, u32 type); -extern void wlc_bmac_set_txpwr_percent(struct wlc_hw_info *wlc_hw, u8 val); extern void wlc_bmac_blink_sync(struct wlc_hw_info *wlc_hw, u32 led_pins); -extern void wlc_bmac_ifsctl_edcrs_set(struct wlc_hw_info *wlc_hw, bool abie, - bool isht); extern void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail); -- cgit v1.2.3 From 20de47a5c2d6516a4eebf874cc35ee5432955f8d Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 21 Jan 2011 11:20:12 +0100 Subject: staging: brcm80211: remove unused function from wlc_channel.c Working through a list of unused functions in the driver tree. This file has following redundant function(s): wlc_channel_country_abbrev wlc_channel_locale_flags wlc_channel_get_chanvec wlc_valid_40chanspec_in_band wlc_channel_set_txpower_limit wlc_valid_chanspec Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_channel.c | 67 ------------------------ drivers/staging/brcm80211/brcmsmac/wlc_channel.h | 10 ---- 2 files changed, 77 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c index a35c15214880..2e30d9223052 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c @@ -658,46 +658,11 @@ void wlc_channel_mgr_detach(wlc_cm_info_t *wlc_cm) kfree(wlc_cm); } -const char *wlc_channel_country_abbrev(wlc_cm_info_t *wlc_cm) -{ - return wlc_cm->country_abbrev; -} - -u8 wlc_channel_locale_flags(wlc_cm_info_t *wlc_cm) -{ - struct wlc_info *wlc = wlc_cm->wlc; - - return wlc_cm->bandstate[wlc->band->bandunit].locale_flags; -} - u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, uint bandunit) { return wlc_cm->bandstate[bandunit].locale_flags; } -/* return chanvec for a given country code and band */ -bool -wlc_channel_get_chanvec(struct wlc_info *wlc, const char *country_abbrev, - int bandtype, chanvec_t *channels) -{ - const country_info_t *country; - const locale_info_t *locale = NULL; - - country = wlc_country_lookup(wlc, country_abbrev); - if (country == NULL) - return false; - - if (bandtype == WLC_BAND_2G) - locale = wlc_get_locale_2g(country->locale_2G); - else if (bandtype == WLC_BAND_5G) - locale = wlc_get_locale_5g(country->locale_5G); - if (locale == NULL) - return false; - - wlc_locale_get_channels(locale, channels); - return true; -} - /* set the driver's current country and regulatory information using a country code * as the source. Lookup built in country information found with the country code. */ @@ -1071,16 +1036,6 @@ bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val) val)); } -/* Is the 40 MHz allowed for the current locale and specified band? */ -bool wlc_valid_40chanspec_in_band(wlc_cm_info_t *wlc_cm, uint bandunit) -{ - struct wlc_info *wlc = wlc_cm->wlc; - - return (((wlc_cm->bandstate[bandunit]. - locale_flags & (WLC_NO_MIMO | WLC_NO_40MHZ)) == 0) - && wlc->bandstate[bandunit]->mimo_cap_40); -} - static void wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t *wlc_cm, struct txpwr_limits *txpwr, @@ -1185,23 +1140,6 @@ wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, &txpwr); } -int -wlc_channel_set_txpower_limit(wlc_cm_info_t *wlc_cm, - u8 local_constraint_qdbm) -{ - struct wlc_info *wlc = wlc_cm->wlc; - struct txpwr_limits txpwr; - - wlc_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr); - - wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr, - local_constraint_qdbm); - - wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec); - - return 0; -} - #ifdef POWER_DBG static void wlc_phy_txpower_limits_dump(txpwr_limits_t *txpwr) { @@ -1598,11 +1536,6 @@ wlc_valid_chanspec_ext(wlc_cm_info_t *wlc_cm, chanspec_t chspec, bool dualband) return false; } -bool wlc_valid_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec) -{ - return wlc_valid_chanspec_ext(wlc_cm, chspec, false); -} - bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec) { return wlc_valid_chanspec_ext(wlc_cm, chspec, true); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.h b/drivers/staging/brcm80211/brcmsmac/wlc_channel.h index 1f170aff68fd..d569ec45267c 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_channel.h @@ -112,8 +112,6 @@ extern int wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, const char *country_abbrev, const char *ccode, int regrev); -extern const char *wlc_channel_country_abbrev(wlc_cm_info_t *wlc_cm); -extern u8 wlc_channel_locale_flags(wlc_cm_info_t *wlc_cm); extern u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, uint bandunit); @@ -124,15 +122,12 @@ extern bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec); #define VALID_CHANNEL20_IN_BAND(wlc, bandunit, val) \ wlc_valid_channel20_in_band((wlc)->cmi, bandunit, val) #define VALID_CHANNEL20(wlc, val) wlc_valid_channel20((wlc)->cmi, val) -#define VALID_40CHANSPEC_IN_BAND(wlc, bandunit) wlc_valid_40chanspec_in_band((wlc)->cmi, bandunit) -extern bool wlc_valid_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec); extern bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec); extern bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val); extern bool wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, uint val); extern bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val); -extern bool wlc_valid_40chanspec_in_band(wlc_cm_info_t *wlc_cm, uint bandunit); extern void wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, @@ -140,8 +135,6 @@ extern void wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, extern void wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, u8 local_constraint_qdbm); -extern int wlc_channel_set_txpower_limit(wlc_cm_info_t *wlc_cm, - u8 local_constraint_qdbm); extern const country_info_t *wlc_country_lookup(struct wlc_info *wlc, const char *ccode); @@ -152,8 +145,5 @@ extern const locale_info_t *wlc_get_locale_5g(u8 locale_idx); extern bool wlc_japan(struct wlc_info *wlc); extern u8 wlc_get_regclass(wlc_cm_info_t *wlc_cm, chanspec_t chanspec); -extern bool wlc_channel_get_chanvec(struct wlc_info *wlc, - const char *country_abbrev, int bandtype, - chanvec_t *channels); #endif /* _WLC_CHANNEL_H */ -- cgit v1.2.3 From 377793824d1cc6119d0b84f00d8bae818847e44b Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 21 Jan 2011 11:20:13 +0100 Subject: staging: brcm80211: remove unused function from wlc_event.c Working through a list of unused functions in the driver tree. This file has following redundant function(s): wlc_eventq_next wlc_eventq_cnt Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_event.c | 26 -------------------------- drivers/staging/brcm80211/brcmsmac/wlc_event.h | 2 -- 2 files changed, 28 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_event.c b/drivers/staging/brcm80211/brcmsmac/wlc_event.c index 12b156a82ff2..7926c4104310 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_event.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_event.c @@ -176,32 +176,6 @@ wlc_event_t *wlc_eventq_deq(wlc_eventq_t *eq) return e; } -wlc_event_t *wlc_eventq_next(wlc_eventq_t *eq, wlc_event_t *e) -{ -#ifdef BCMDBG - wlc_event_t *etmp; - - for (etmp = eq->head; etmp; etmp = etmp->next) { - if (etmp == e) - break; - } - ASSERT(etmp != NULL); -#endif - - return e->next; -} - -int wlc_eventq_cnt(wlc_eventq_t *eq) -{ - wlc_event_t *etmp; - int cnt = 0; - - for (etmp = eq->head; etmp; etmp = etmp->next) - cnt++; - - return cnt; -} - bool wlc_eventq_avail(wlc_eventq_t *eq) { return (eq->head != NULL); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_event.h b/drivers/staging/brcm80211/brcmsmac/wlc_event.h index e75582dcdd93..8151ba500681 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_event.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_event.h @@ -27,8 +27,6 @@ extern wlc_eventq_t *wlc_eventq_attach(struct wlc_pub *pub, extern int wlc_eventq_detach(wlc_eventq_t *eq); extern int wlc_eventq_down(wlc_eventq_t *eq); extern void wlc_event_free(wlc_eventq_t *eq, wlc_event_t *e); -extern wlc_event_t *wlc_eventq_next(wlc_eventq_t *eq, wlc_event_t *e); -extern int wlc_eventq_cnt(wlc_eventq_t *eq); extern bool wlc_eventq_avail(wlc_eventq_t *eq); extern wlc_event_t *wlc_eventq_deq(wlc_eventq_t *eq); extern void wlc_eventq_enq(wlc_eventq_t *eq, wlc_event_t *e); -- cgit v1.2.3 From e71e940c2d76860a7a2e8c052a5169d2ef468561 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 21 Jan 2011 11:20:14 +0100 Subject: staging: brcm80211: removed unused inline function from wlc_ampdu.c This file defined an inline function pkt_txh_seqnum() which was not used and as such is removed. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index 8e1011203481..f5ca897c2dea 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -152,15 +152,6 @@ static void wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct sk_buff *p, tx_status_t *txs, u32 frmtxstatus, u32 frmtxstatus2); -static inline u16 pkt_txh_seqnum(struct wlc_info *wlc, struct sk_buff *p) -{ - d11txh_t *txh; - struct ieee80211_hdr *h; - txh = (d11txh_t *) p->data; - h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); - return ltoh16(h->seq_ctrl) >> SEQNUM_SHIFT; -} - struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc) { struct ampdu_info *ampdu; -- cgit v1.2.3 From 93ed8e35e2f7e4951e0ddb75acf9cad60e43f91b Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 21 Jan 2011 11:20:15 +0100 Subject: staging: brcm80211: remove unused function from wlc_stf.c Working through a list of unused functions in the driver tree. This file has following redundant function(s): wlc_stf_stbc_rx_get wlc_stf_rxchain_set Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_stf.c | 70 ---------------------------- drivers/staging/brcm80211/brcmsmac/wlc_stf.h | 1 - 2 files changed, 71 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c index 10c9f447cdf0..a1a1767f1d3a 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c @@ -44,7 +44,6 @@ #define WLC_STF_SS_STBC_RX(wlc) (WLCISNPHY(wlc->band) && \ NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6)) -static s8 wlc_stf_stbc_rx_get(struct wlc_info *wlc); static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val); static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 val); static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val); @@ -151,12 +150,6 @@ wlc_stf_ss_algo_channel_get(struct wlc_info *wlc, u16 *ss_algo_channel, setbit(ss_algo_channel, PHY_TXC1_MODE_STBC); } -static s8 wlc_stf_stbc_rx_get(struct wlc_info *wlc) -{ - return (wlc->ht_cap.cap_info & HT_CAP_RX_STBC_MASK) - >> HT_CAP_RX_STBC_SHIFT; -} - static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val) { if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON)) { @@ -310,69 +303,6 @@ int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force) return BCME_OK; } -int wlc_stf_rxchain_set(struct wlc_info *wlc, s32 int_val) -{ - u8 rxchain_cnt; - u8 rxchain = (u8) int_val; - u8 mimops_mode; - u8 old_rxchain, old_rxchain_cnt; - - if (wlc->stf->rxchain == rxchain) - return BCME_OK; - - if ((rxchain & ~wlc->stf->hw_rxchain) - || !(rxchain & wlc->stf->hw_rxchain)) - return BCME_RANGE; - - rxchain_cnt = (u8) WLC_BITSCNT(rxchain); - if (WLC_STF_SS_STBC_RX(wlc)) { - if ((rxchain_cnt == 1) - && (wlc_stf_stbc_rx_get(wlc) != HT_CAP_RX_STBC_NO)) - return BCME_RANGE; - } - - if (APSTA_ENAB(wlc->pub) && (wlc->pub->associated)) - return BCME_ASSOCIATED; - - old_rxchain = wlc->stf->rxchain; - old_rxchain_cnt = wlc->stf->rxstreams; - - wlc->stf->rxchain = rxchain; - wlc->stf->rxstreams = rxchain_cnt; - - if (rxchain_cnt != old_rxchain_cnt) { - mimops_mode = - (rxchain_cnt == 1) ? HT_CAP_MIMO_PS_ON : HT_CAP_MIMO_PS_OFF; - wlc->mimops_PM = mimops_mode; - if (AP_ENAB(wlc->pub)) { - wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, - wlc->stf->rxchain); - wlc_ht_mimops_cap_update(wlc, mimops_mode); - if (wlc->pub->associated) - wlc_mimops_action_ht_send(wlc, wlc->cfg, - mimops_mode); - return BCME_OK; - } - if (wlc->pub->associated) { - if (mimops_mode == HT_CAP_MIMO_PS_OFF) { - /* if mimops is off, turn on the Rx chain first */ - wlc_phy_stf_chain_set(wlc->band->pi, - wlc->stf->txchain, - wlc->stf->rxchain); - wlc_ht_mimops_cap_update(wlc, mimops_mode); - } - } else { - wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, - wlc->stf->rxchain); - wlc_ht_mimops_cap_update(wlc, mimops_mode); - } - } else if (old_rxchain != rxchain) - wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, - wlc->stf->rxchain); - - return BCME_OK; -} - /* update wlc->stf->ss_opmode which represents the operational stf_ss mode we're using */ int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band) { diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.h b/drivers/staging/brcm80211/brcmsmac/wlc_stf.h index 8de6382e620d..e127862c4449 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_stf.h @@ -30,7 +30,6 @@ extern void wlc_stf_ss_algo_channel_get(struct wlc_info *wlc, extern int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band); extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc); extern int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force); -extern int wlc_stf_rxchain_set(struct wlc_info *wlc, s32 int_val); extern bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val); extern int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val); -- cgit v1.2.3 From 824090ef81800419cd9943548ef2d505efe42a6e Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 21 Jan 2011 11:20:16 +0100 Subject: staging: brcm80211: remove unused type definitions from driver Quite some definitions are not referenced in the drivers sources and clutter up the files so they are removed. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd.h | 11 ++---- drivers/staging/brcm80211/brcmfmac/hndrte_cons.h | 5 +++ drivers/staging/brcm80211/brcmfmac/wl_iw.h | 6 ---- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 30 ---------------- drivers/staging/brcm80211/brcmsmac/wl_mac80211.h | 9 ----- drivers/staging/brcm80211/brcmsmac/wlc_bmac.h | 40 ---------------------- drivers/staging/brcm80211/brcmsmac/wlc_key.h | 3 -- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h | 3 -- drivers/staging/brcm80211/brcmsmac/wlc_pub.h | 3 -- drivers/staging/brcm80211/include/bcmnvram.h | 6 ---- drivers/staging/brcm80211/include/bcmutils.h | 24 ++----------- drivers/staging/brcm80211/include/proto/bcmevent.h | 8 ----- 12 files changed, 9 insertions(+), 139 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd.h b/drivers/staging/brcm80211/brcmfmac/dhd.h index 014a2dea7868..a78b20a0cc79 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd.h @@ -49,13 +49,6 @@ enum dhd_bus_state { DHD_BUS_DATA /* Ready for frame transfers */ }; -enum dhd_prealloc_index { - DHD_PREALLOC_PROT = 0, - DHD_PREALLOC_RXBUF, - DHD_PREALLOC_DATABUF, - DHD_PREALLOC_OSL_BUF -}; - /* Common structure for module and instance linkage */ typedef struct dhd_pub { /* Linkage ponters */ @@ -332,12 +325,12 @@ extern int dhd_bus_devreset(dhd_pub_t *dhdp, u8 flag); extern uint dhd_bus_status(dhd_pub_t *dhdp); extern int dhd_bus_start(dhd_pub_t *dhdp); -typedef enum cust_gpio_modes { +enum cust_gpio_modes { WLAN_RESET_ON, WLAN_RESET_OFF, WLAN_POWER_ON, WLAN_POWER_OFF -} cust_gpio_modes_t; +}; /* * Insmod parameters for debug/test */ diff --git a/drivers/staging/brcm80211/brcmfmac/hndrte_cons.h b/drivers/staging/brcm80211/brcmfmac/hndrte_cons.h index 5caa53fb6552..4df3eecaa83b 100644 --- a/drivers/staging/brcm80211/brcmfmac/hndrte_cons.h +++ b/drivers/staging/brcm80211/brcmfmac/hndrte_cons.h @@ -13,6 +13,8 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifndef _hndrte_cons_h +#define _hndrte_cons_h #define CBUF_LEN (128) @@ -55,3 +57,6 @@ typedef struct { uint cbuf_idx; char cbuf[CBUF_LEN]; } hndrte_cons_t; + +#endif /* _hndrte_cons_h */ + diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.h b/drivers/staging/brcm80211/brcmfmac/wl_iw.h index 08e11fba5248..fe06174cee7d 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.h +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.h @@ -139,10 +139,4 @@ extern int dhd_dev_get_pno_status(struct net_device *dev); #define PNO_TLV_TYPE_TIME 'T' #define PNO_EVENT_UP "PNO_EVENT" -typedef struct cmd_tlv { - char prefix; - char version; - char subver; - char reserved; -} cmd_tlv_t; #endif /* _wl_iw_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index f9ba048837be..65057329c994 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -68,36 +68,6 @@ static int wl_linux_watchdog(void *ctx); static int wl_found; -struct ieee80211_tkip_data { -#define TKIP_KEY_LEN 32 - u8 key[TKIP_KEY_LEN]; - int key_set; - - u32 tx_iv32; - u16 tx_iv16; - u16 tx_ttak[5]; - int tx_phase1_done; - - u32 rx_iv32; - u16 rx_iv16; - u16 rx_ttak[5]; - int rx_phase1_done; - u32 rx_iv32_new; - u16 rx_iv16_new; - - u32 dot11RSNAStatsTKIPReplays; - u32 dot11RSNAStatsTKIPICVErrors; - u32 dot11RSNAStatsTKIPLocalMICFailures; - - int key_idx; - - struct crypto_tfm *tfm_arc4; - struct crypto_tfm *tfm_michael; - - /* scratch buffers for virt_to_page() (crypto API) */ - u8 rx_hdr[16], tx_hdr[16]; -}; - #define WL_DEV_IF(dev) ((struct wl_if *)netdev_priv(dev)) #define WL_INFO(dev) ((struct wl_info *)(WL_DEV_IF(dev)->wl)) static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev); diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h index bb39b7705947..070fa94d9422 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h @@ -37,15 +37,6 @@ typedef struct wl_timer { #endif } wl_timer_t; -/* contortion to call functions at safe time */ -/* In 2.6.20 kernels work functions get passed a pointer to the struct work, so things - * will continue to work as long as the work structure is the first component of the task structure. - */ -typedef struct wl_task { - struct work_struct work; - void *context; -} wl_task_t; - struct wl_if { uint subunit; /* WDS/BSS unit */ struct pci_dev *pci_dev; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h index 49739e631b56..5eabb8e0860e 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h @@ -25,38 +25,6 @@ * create wrappers in wlc.c if needed */ -/* Revision and other info required from BMAC driver for functioning of high ONLY driver */ -typedef struct wlc_bmac_revinfo { - uint vendorid; /* PCI vendor id */ - uint deviceid; /* device id of chip */ - - uint boardrev; /* version # of particular board */ - uint corerev; /* core revision */ - uint sromrev; /* srom revision */ - uint chiprev; /* chip revision */ - uint chip; /* chip number */ - uint chippkg; /* chip package */ - uint boardtype; /* board type */ - uint boardvendor; /* board vendor */ - uint bustype; /* SB_BUS, PCI_BUS */ - uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */ - uint buscorerev; /* buscore rev */ - u32 issim; /* chip is in simulation or emulation */ - - uint nbands; - - struct band_info { - uint bandunit; /* To match on both sides */ - uint bandtype; /* To match on both sides */ - uint radiorev; - uint phytype; - uint phyrev; - uint anarev; - uint radioid; - bool abgphy_encore; - } band[MAXBANDS]; -} wlc_bmac_revinfo_t; - /* dup state between BMAC(struct wlc_hw_info) and HIGH(struct wlc_info) driver */ typedef struct wlc_bmac_state { @@ -123,14 +91,6 @@ typedef enum { BMAC_DUMP_LAST } wlc_bmac_dump_id_t; -typedef enum { - WLCHW_STATE_ATTACH, - WLCHW_STATE_CLK, - WLCHW_STATE_UP, - WLCHW_STATE_ASSOC, - WLCHW_STATE_LAST -} wlc_bmac_state_id_t; - extern int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, bool piomode, struct osl_info *osh, void *regsva, uint bustype, void *btparam); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_key.h b/drivers/staging/brcm80211/brcmsmac/wlc_key.h index 3e23d5145919..4991e9921de3 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_key.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_key.h @@ -106,9 +106,6 @@ typedef struct wsec_key { } wsec_key_t; #define broken_roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) -typedef struct { - u8 vec[broken_roundup(WSEC_MAX_KEYS, NBBY) / NBBY]; /* bitvec of wsec_key indexes */ -} wsec_key_vec_t; /* For use with wsec_key_t.flags */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h index f56b58141c09..5817a49f460e 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h @@ -346,9 +346,6 @@ struct wlcband { u16 bcntsfoff; /* beacon tsf offset */ }; -/* generic function callback takes just one arg */ -typedef void (*cb_fn_t) (void *); - /* tx completion callback takes 3 args */ typedef void (*pkcb_fn_t) (struct wlc_info *wlc, uint txstatus, void *arg); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h index 23e99685d548..e8b252a699f8 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h @@ -149,9 +149,6 @@ struct rsn_parms { IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_GRN_FLD |\ HT_CAP_MAX_AMSDU | IEEE80211_HT_CAP_DSSSCCK40) -/* WLC packet type is a void * */ -typedef void *wlc_pkt_t; - /* Event data type */ typedef struct wlc_event { wl_event_msg_t event; /* encapsulated event */ diff --git a/drivers/staging/brcm80211/include/bcmnvram.h b/drivers/staging/brcm80211/include/bcmnvram.h index 63e31a4749c3..e194131a750e 100644 --- a/drivers/staging/brcm80211/include/bcmnvram.h +++ b/drivers/staging/brcm80211/include/bcmnvram.h @@ -29,12 +29,6 @@ struct nvram_header { u32 config_ncdl; /* ncdl values for memc */ }; -struct nvram_tuple { - char *name; - char *value; - struct nvram_tuple *next; -}; - /* * Get default value for an NVRAM variable */ diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h index a871acd2fd49..8e7f2ea6f2ef 100644 --- a/drivers/staging/brcm80211/include/bcmutils.h +++ b/drivers/staging/brcm80211/include/bcmutils.h @@ -54,12 +54,12 @@ #define PKTQ_MAX_PREC 16 /* Maximum precedence levels */ #endif - typedef struct pktq_prec { + struct pktq_prec { struct sk_buff *head; /* first packet to dequeue */ struct sk_buff *tail; /* last packet to dequeue */ u16 len; /* number of queued packets */ u16 max; /* maximum number of queued packets */ - } pktq_prec_t; + }; /* multi-priority pkt queue */ struct pktq { @@ -71,16 +71,6 @@ struct pktq_prec q[PKTQ_MAX_PREC]; }; -/* simple, non-priority pkt queue */ - struct spktq { - u16 num_prec; /* number of precedences in use (always 1) */ - u16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */ - u16 max; /* total max packets */ - u16 len; /* total number of packets */ - /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */ - struct pktq_prec q[1]; - }; - #define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--) /* fn(pkt, arg). return true if pkt belongs to if */ @@ -491,19 +481,9 @@ extern struct sk_buff *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); extern u16 bcm_qdbm_to_mw(u8 qdbm); extern u8 bcm_mw_to_qdbm(u16 mw); -/* generic datastruct to help dump routines */ - struct fielddesc { - const char *nameandfmt; - u32 offset; - u32 len; - }; - extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size); extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...); - typedef u32(*bcmutl_rdreg_rtn) (void *arg0, uint arg1, - u32 offset); - extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len); extern uint bcm_bitcount(u8 *bitmap, uint bytelength); diff --git a/drivers/staging/brcm80211/include/proto/bcmevent.h b/drivers/staging/brcm80211/include/proto/bcmevent.h index f020e3fbcb33..1b60789aef05 100644 --- a/drivers/staging/brcm80211/include/proto/bcmevent.h +++ b/drivers/staging/brcm80211/include/proto/bcmevent.h @@ -191,14 +191,6 @@ extern const int bcmevent_names_size; #define WLC_E_SUP_SEND_FAIL 13 #define WLC_E_SUP_DEAUTH 14 -typedef struct wl_event_data_if { - u8 ifidx; - u8 opcode; - u8 reserved; - u8 bssidx; - u8 role; -} wl_event_data_if_t; - #define WLC_E_IF_ADD 1 #define WLC_E_IF_DEL 2 #define WLC_E_IF_CHANGE 3 -- cgit v1.2.3 From 88c8a4437b061dd9dae738802a9eddc297a96278 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 21 Jan 2011 09:18:56 -0800 Subject: staging: hv: hv_utils depends on CONNECTOR Don't build hv_utils when CONFIG_CONNECTOR is not enabled. Fixes these build errors: ERROR: "cn_add_callback" [drivers/staging/hv/hv_utils.ko] undefined! ERROR: "cn_del_callback" [drivers/staging/hv/hv_utils.ko] undefined! ERROR: "cn_netlink_send" [drivers/staging/hv/hv_utils.ko] undefined! Signed-off-by: Randy Dunlap Cc: Greg Kroah-Hartman Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/hv/Kconfig b/drivers/staging/hv/Kconfig index 7455c804962a..2780312cc30d 100644 --- a/drivers/staging/hv/Kconfig +++ b/drivers/staging/hv/Kconfig @@ -31,6 +31,7 @@ config HYPERV_NET config HYPERV_UTILS tristate "Microsoft Hyper-V Utilities driver" + depends on CONNECTOR default HYPERV help Select this option to enable the Hyper-V Utilities. -- cgit v1.2.3 From 77d89b08766c878a2594b15d203e513acf952340 Mon Sep 17 00:00:00 2001 From: wwang Date: Fri, 21 Jan 2011 17:39:18 +0800 Subject: staging: add rts_pstor for Realtek PCIE cardreader rts_pstor is used to support Realtek PCI-E card readers, including rts5209, rts5208, Barossa. Signed-off-by: wwang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/rts_pstor/Kconfig | 15 + drivers/staging/rts_pstor/Makefile | 16 + drivers/staging/rts_pstor/TODO | 5 + drivers/staging/rts_pstor/debug.h | 43 + drivers/staging/rts_pstor/general.c | 35 + drivers/staging/rts_pstor/general.h | 31 + drivers/staging/rts_pstor/ms.c | 4244 +++++++++++++++++++++++++ drivers/staging/rts_pstor/ms.h | 225 ++ drivers/staging/rts_pstor/rtsx.c | 1124 +++++++ drivers/staging/rts_pstor/rtsx.h | 183 ++ drivers/staging/rts_pstor/rtsx_card.c | 1257 ++++++++ drivers/staging/rts_pstor/rtsx_card.h | 1095 +++++++ drivers/staging/rts_pstor/rtsx_chip.c | 2337 ++++++++++++++ drivers/staging/rts_pstor/rtsx_chip.h | 989 ++++++ drivers/staging/rts_pstor/rtsx_scsi.c | 3203 +++++++++++++++++++ drivers/staging/rts_pstor/rtsx_scsi.h | 142 + drivers/staging/rts_pstor/rtsx_sys.h | 50 + drivers/staging/rts_pstor/rtsx_transport.c | 914 ++++++ drivers/staging/rts_pstor/rtsx_transport.h | 66 + drivers/staging/rts_pstor/sd.c | 4768 ++++++++++++++++++++++++++++ drivers/staging/rts_pstor/sd.h | 295 ++ drivers/staging/rts_pstor/spi.c | 847 +++++ drivers/staging/rts_pstor/spi.h | 65 + drivers/staging/rts_pstor/trace.h | 118 + drivers/staging/rts_pstor/xd.c | 2140 +++++++++++++ drivers/staging/rts_pstor/xd.h | 188 ++ 28 files changed, 24398 insertions(+) create mode 100644 drivers/staging/rts_pstor/Kconfig create mode 100644 drivers/staging/rts_pstor/Makefile create mode 100644 drivers/staging/rts_pstor/TODO create mode 100644 drivers/staging/rts_pstor/debug.h create mode 100644 drivers/staging/rts_pstor/general.c create mode 100644 drivers/staging/rts_pstor/general.h create mode 100644 drivers/staging/rts_pstor/ms.c create mode 100644 drivers/staging/rts_pstor/ms.h create mode 100644 drivers/staging/rts_pstor/rtsx.c create mode 100644 drivers/staging/rts_pstor/rtsx.h create mode 100644 drivers/staging/rts_pstor/rtsx_card.c create mode 100644 drivers/staging/rts_pstor/rtsx_card.h create mode 100644 drivers/staging/rts_pstor/rtsx_chip.c create mode 100644 drivers/staging/rts_pstor/rtsx_chip.h create mode 100644 drivers/staging/rts_pstor/rtsx_scsi.c create mode 100644 drivers/staging/rts_pstor/rtsx_scsi.h create mode 100644 drivers/staging/rts_pstor/rtsx_sys.h create mode 100644 drivers/staging/rts_pstor/rtsx_transport.c create mode 100644 drivers/staging/rts_pstor/rtsx_transport.h create mode 100644 drivers/staging/rts_pstor/sd.c create mode 100644 drivers/staging/rts_pstor/sd.h create mode 100644 drivers/staging/rts_pstor/spi.c create mode 100644 drivers/staging/rts_pstor/spi.h create mode 100644 drivers/staging/rts_pstor/trace.h create mode 100644 drivers/staging/rts_pstor/xd.c create mode 100644 drivers/staging/rts_pstor/xd.h (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 5c8fcfc42c3e..9a5b7a6a97e4 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -87,6 +87,8 @@ source "drivers/staging/rtl8192e/Kconfig" source "drivers/staging/rtl8712/Kconfig" +source "drivers/staging/rts_pstor/Kconfig" + source "drivers/staging/frontier/Kconfig" source "drivers/staging/pohmelfs/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index d53886317826..2057b89d4d05 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_R8187SE) += rtl8187se/ obj-$(CONFIG_RTL8192U) += rtl8192u/ obj-$(CONFIG_RTL8192E) += rtl8192e/ obj-$(CONFIG_R8712U) += rtl8712/ +obj-$(CONFIG_RTS_PSTOR) += rts_pstor/ obj-$(CONFIG_SPECTRA) += spectra/ obj-$(CONFIG_TRANZPORT) += frontier/ obj-$(CONFIG_POHMELFS) += pohmelfs/ diff --git a/drivers/staging/rts_pstor/Kconfig b/drivers/staging/rts_pstor/Kconfig new file mode 100644 index 000000000000..972becd011f1 --- /dev/null +++ b/drivers/staging/rts_pstor/Kconfig @@ -0,0 +1,15 @@ +config RTS_PSTOR + tristate "RealTek PCI-E Card Reader support" + help + Say Y here to include driver code to support the Realtek + PCI-E card readers. + + If this driver is compiled as a module, it will be named rts_pstor. + +config RTS_PSTOR_DEBUG + bool "Realtek PCI-E Card Reader verbose debug" + depends on RTS_PSTOR + help + Say Y here in order to have the rts_pstor code generate + verbose debugging messages. + diff --git a/drivers/staging/rts_pstor/Makefile b/drivers/staging/rts_pstor/Makefile new file mode 100644 index 000000000000..61609aee0a0f --- /dev/null +++ b/drivers/staging/rts_pstor/Makefile @@ -0,0 +1,16 @@ +EXTRA_CFLAGS := -Idrivers/scsi + +obj-$(CONFIG_RTS_PSTOR) := rts_pstor.o + +rts_pstor-y := \ + rtsx.o \ + rtsx_chip.o \ + rtsx_transport.o \ + rtsx_scsi.o \ + rtsx_card.o \ + general.o \ + sd.o \ + xd.o \ + ms.o \ + spi.o + diff --git a/drivers/staging/rts_pstor/TODO b/drivers/staging/rts_pstor/TODO new file mode 100644 index 000000000000..2f93a7c1b5ad --- /dev/null +++ b/drivers/staging/rts_pstor/TODO @@ -0,0 +1,5 @@ +TODO: +- support more pcie card reader of Realtek family +- use kernel coding style +- checkpatch.pl fixes + diff --git a/drivers/staging/rts_pstor/debug.h b/drivers/staging/rts_pstor/debug.h new file mode 100644 index 000000000000..e1408b0e7ae4 --- /dev/null +++ b/drivers/staging/rts_pstor/debug.h @@ -0,0 +1,43 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __REALTEK_RTSX_DEBUG_H +#define __REALTEK_RTSX_DEBUG_H + +#include + +#define RTSX_STOR "rts_pstor: " + +#if CONFIG_RTS_PSTOR_DEBUG +#define RTSX_DEBUGP(x...) printk(KERN_DEBUG RTSX_STOR x) +#define RTSX_DEBUGPN(x...) printk(KERN_DEBUG x) +#define RTSX_DEBUGPX(x...) printk(x) +#define RTSX_DEBUG(x) x +#else +#define RTSX_DEBUGP(x...) +#define RTSX_DEBUGPN(x...) +#define RTSX_DEBUGPX(x...) +#define RTSX_DEBUG(x) +#endif + +#endif /* __REALTEK_RTSX_DEBUG_H */ diff --git a/drivers/staging/rts_pstor/general.c b/drivers/staging/rts_pstor/general.c new file mode 100644 index 000000000000..056e98d2475c --- /dev/null +++ b/drivers/staging/rts_pstor/general.c @@ -0,0 +1,35 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include "general.h" + +int bit1cnt_long(u32 data) +{ + int i, cnt = 0; + for (i = 0; i < 32; i++) { + if (data & 0x01) + cnt++; + data >>= 1; + } + return cnt; +} + diff --git a/drivers/staging/rts_pstor/general.h b/drivers/staging/rts_pstor/general.h new file mode 100644 index 000000000000..f17930d2e0c4 --- /dev/null +++ b/drivers/staging/rts_pstor/general.h @@ -0,0 +1,31 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __RTSX_GENERAL_H +#define __RTSX_GENERAL_H + +#include "rtsx.h" + +int bit1cnt_long(u32 data); + +#endif /* __RTSX_GENERAL_H */ diff --git a/drivers/staging/rts_pstor/ms.c b/drivers/staging/rts_pstor/ms.c new file mode 100644 index 000000000000..dd5993168598 --- /dev/null +++ b/drivers/staging/rts_pstor/ms.c @@ -0,0 +1,4244 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include +#include +#include + +#include "rtsx.h" +#include "rtsx_transport.h" +#include "rtsx_scsi.h" +#include "rtsx_card.h" +#include "ms.h" + +static inline void ms_set_err_code(struct rtsx_chip *chip, u8 err_code) +{ + struct ms_info *ms_card = &(chip->ms_card); + + ms_card->err_code = err_code; +} + +static inline int ms_check_err_code(struct rtsx_chip *chip, u8 err_code) +{ + struct ms_info *ms_card = &(chip->ms_card); + + return (ms_card->err_code == err_code); +} + +static int ms_parse_err_code(struct rtsx_chip *chip) +{ + TRACE_RET(chip, STATUS_FAIL); +} + +static int ms_transfer_tpc(struct rtsx_chip *chip, u8 trans_mode, u8 tpc, u8 cnt, u8 cfg) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + u8 *ptr; + + RTSX_DEBUGP("ms_transfer_tpc: tpc = 0x%x\n", tpc); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, MS_TRANSFER_START | trans_mode); + rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); + + rtsx_add_cmd(chip, READ_REG_CMD, MS_TRANS_CFG, 0, 0); + + retval = rtsx_send_cmd(chip, MS_CARD, 5000); + if (retval < 0) { + rtsx_clear_ms_error(chip); + ms_set_err_code(chip, MS_TO_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + + ptr = rtsx_get_cmd_data(chip) + 1; + + if (!(tpc & 0x08)) { /* Read Packet */ + if (*ptr & MS_CRC16_ERR) { + ms_set_err_code(chip, MS_CRC16_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + } else { /* Write Packet */ + if (CHK_MSPRO(ms_card) && !(*ptr & 0x80)) { + if (*ptr & (MS_INT_ERR | MS_INT_CMDNK)) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + } + } + + if (*ptr & MS_RDY_TIMEOUT) { + rtsx_clear_ms_error(chip); + ms_set_err_code(chip, MS_TO_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + + return STATUS_SUCCESS; +} + +static int ms_transfer_data(struct rtsx_chip *chip, u8 trans_mode, u8 tpc, u16 sec_cnt, + u8 cfg, int mode_2k, int use_sg, void *buf, int buf_len) +{ + int retval; + u8 val, err_code = 0; + enum dma_data_direction dir; + + if (!buf || !buf_len) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (trans_mode == MS_TM_AUTO_READ) { + dir = DMA_FROM_DEVICE; + err_code = MS_FLASH_READ_ERROR; + } else if (trans_mode == MS_TM_AUTO_WRITE) { + dir = DMA_TO_DEVICE; + err_code = MS_FLASH_WRITE_ERROR; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); + rtsx_add_cmd(chip, WRITE_REG_CMD, + MS_SECTOR_CNT_H, 0xFF, (u8)(sec_cnt >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_L, 0xFF, (u8)sec_cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); + + if (mode_2k) { + rtsx_add_cmd(chip, WRITE_REG_CMD, + MS_CFG, MS_2K_SECTOR_MODE, MS_2K_SECTOR_MODE); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_CFG, MS_2K_SECTOR_MODE, 0); + } + + trans_dma_enable(dir, chip, sec_cnt * 512, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, + MS_TRANSFER, 0xFF, MS_TRANSFER_START | trans_mode); + rtsx_add_cmd(chip, CHECK_REG_CMD, + MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + + retval = rtsx_transfer_data(chip, MS_CARD, buf, buf_len, + use_sg, dir, chip->mspro_timeout); + if (retval < 0) { + ms_set_err_code(chip, err_code); + if (retval == -ETIMEDOUT) { + retval = STATUS_TIMEDOUT; + } else { + retval = STATUS_FAIL; + } + TRACE_RET(chip, retval); + } + + RTSX_READ_REG(chip, MS_TRANS_CFG, &val); + if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT)) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int ms_write_bytes(struct rtsx_chip *chip, + u8 tpc, u8 cnt, u8 cfg, u8 *data, int data_len) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + + if (!data || (data_len < cnt)) { + TRACE_RET(chip, STATUS_ERROR); + } + + rtsx_init_cmd(chip); + + for (i = 0; i < cnt; i++) { + rtsx_add_cmd(chip, WRITE_REG_CMD, + PPBUF_BASE2 + i, 0xFF, data[i]); + } + if (cnt % 2) { + rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2 + i, 0xFF, 0xFF); + } + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); + + rtsx_add_cmd(chip, WRITE_REG_CMD, + MS_TRANSFER, 0xFF, MS_TRANSFER_START | MS_TM_WRITE_BYTES); + rtsx_add_cmd(chip, CHECK_REG_CMD, + MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); + + retval = rtsx_send_cmd(chip, MS_CARD, 5000); + if (retval < 0) { + u8 val = 0; + + rtsx_read_register(chip, MS_TRANS_CFG, &val); + RTSX_DEBUGP("MS_TRANS_CFG: 0x%02x\n", val); + + rtsx_clear_ms_error(chip); + + if (!(tpc & 0x08)) { + if (val & MS_CRC16_ERR) { + ms_set_err_code(chip, MS_CRC16_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + } else { + if (CHK_MSPRO(ms_card) && !(val & 0x80)) { + if (val & (MS_INT_ERR | MS_INT_CMDNK)) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + } + } + + if (val & MS_RDY_TIMEOUT) { + ms_set_err_code(chip, MS_TO_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + + ms_set_err_code(chip, MS_TO_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + + return STATUS_SUCCESS; +} + +static int ms_read_bytes(struct rtsx_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 *data, int data_len) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 *ptr; + + if (!data) { + TRACE_RET(chip, STATUS_ERROR); + } + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, MS_TRANSFER_START | MS_TM_READ_BYTES); + rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); + + for (i = 0; i < data_len - 1; i++) { + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + i, 0, 0); + } + if (data_len % 2) { + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len, 0, 0); + } else { + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len - 1, 0, 0); + } + + retval = rtsx_send_cmd(chip, MS_CARD, 5000); + if (retval < 0) { + u8 val = 0; + + rtsx_read_register(chip, MS_TRANS_CFG, &val); + rtsx_clear_ms_error(chip); + + if (!(tpc & 0x08)) { + if (val & MS_CRC16_ERR) { + ms_set_err_code(chip, MS_CRC16_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + } else { + if (CHK_MSPRO(ms_card) && !(val & 0x80)) { + if (val & (MS_INT_ERR | MS_INT_CMDNK)) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + } + } + + if (val & MS_RDY_TIMEOUT) { + ms_set_err_code(chip, MS_TO_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + + ms_set_err_code(chip, MS_TO_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + + ptr = rtsx_get_cmd_data(chip) + 1; + + for (i = 0; i < data_len; i++) { + data[i] = ptr[i]; + } + + if ((tpc == PRO_READ_SHORT_DATA) && (data_len == 8)) { + RTSX_DEBUGP("Read format progress:\n"); + RTSX_DUMP(ptr, cnt); + } + + return STATUS_SUCCESS; +} + +static int ms_set_rw_reg_addr(struct rtsx_chip *chip, + u8 read_start, u8 read_cnt, u8 write_start, u8 write_cnt) +{ + int retval, i; + u8 data[4]; + + data[0] = read_start; + data[1] = read_cnt; + data[2] = write_start; + data[3] = write_cnt; + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, SET_RW_REG_ADRS, 4, + NO_WAIT_INT, data, 4); + if (retval == STATUS_SUCCESS) + return STATUS_SUCCESS; + rtsx_clear_ms_error(chip); + } + + TRACE_RET(chip, STATUS_FAIL); +} + +static int ms_send_cmd(struct rtsx_chip *chip, u8 cmd, u8 cfg) +{ + u8 data[2]; + + data[0] = cmd; + data[1] = 0; + + return ms_write_bytes(chip, PRO_SET_CMD, 1, cfg, data, 1); +} + +static int ms_set_init_para(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + if (CHK_HG8BIT(ms_card)) { + if (chip->asic_code) { + ms_card->ms_clock = chip->asic_ms_hg_clk; + } else { + ms_card->ms_clock = chip->fpga_ms_hg_clk; + } + } else if (CHK_MSPRO(ms_card) || CHK_MS4BIT(ms_card)) { + if (chip->asic_code) { + ms_card->ms_clock = chip->asic_ms_4bit_clk; + } else { + ms_card->ms_clock = chip->fpga_ms_4bit_clk; + } + } else { + if (chip->asic_code) { + ms_card->ms_clock = chip->asic_ms_1bit_clk; + } else { + ms_card->ms_clock = chip->fpga_ms_1bit_clk; + } + } + + retval = switch_clock(chip, ms_card->ms_clock); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = select_card(chip, MS_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int ms_switch_clock(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + retval = select_card(chip, MS_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = switch_clock(chip, ms_card->ms_clock); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int ms_pull_ctl_disable(struct rtsx_chip *chip) +{ + if (CHECK_PID(chip, 0x5209)) { + RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF, 0x15); + } else if (CHECK_PID(chip, 0x5208)) { + RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, + MS_D1_PD | MS_D2_PD | MS_CLK_PD | MS_D6_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, + MS_D3_PD | MS_D0_PD | MS_BS_PD | XD_D4_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, + MS_D7_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU); + RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, + XD_RDY_PD | SD_D3_PD | SD_D2_PD | XD_ALE_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, + MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF, + MS_D5_PD | MS_D4_PD); + } else if (CHECK_PID(chip, 0x5288)) { + if (CHECK_BARO_PKG(chip, QFN)) { + RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0x4B); + RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x69); + } + } + + return STATUS_SUCCESS; +} + +static int ms_pull_ctl_enable(struct rtsx_chip *chip) +{ + int retval; + + rtsx_init_cmd(chip); + + if (CHECK_PID(chip, 0x5209)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x15); + } else if (CHECK_PID(chip, 0x5208)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, + MS_D1_PD | MS_D2_PD | MS_CLK_NP | MS_D6_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, + MS_D3_PD | MS_D0_PD | MS_BS_NP | XD_D4_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, + MS_D7_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, + XD_RDY_PD | SD_D3_PD | SD_D2_PD | XD_ALE_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, + MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, + MS_D5_PD | MS_D4_PD); + } else if (CHECK_PID(chip, 0x5288)) { + if (CHECK_BARO_PKG(chip, QFN)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, + CARD_PULL_CTL1, 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, + CARD_PULL_CTL2, 0xFF, 0x45); + rtsx_add_cmd(chip, WRITE_REG_CMD, + CARD_PULL_CTL3, 0xFF, 0x4B); + rtsx_add_cmd(chip, WRITE_REG_CMD, + CARD_PULL_CTL4, 0xFF, 0x29); + } + } + + retval = rtsx_send_cmd(chip, MS_CARD, 100); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int ms_prepare_reset(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + u8 oc_mask = 0; + + ms_card->ms_type = 0; + ms_card->check_ms_flow = 0; + ms_card->switch_8bit_fail = 0; + ms_card->delay_write.delay_write_flag = 0; + + ms_card->pro_under_formatting = 0; + + retval = ms_power_off_card3v3(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (!chip->ft2_fast_mode) + wait_timeout(250); + + retval = enable_card_clock(chip, MS_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (chip->asic_code) { + retval = ms_pull_ctl_enable(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + RTSX_WRITE_REG(chip, FPGA_PULL_CTL, FPGA_MS_PULL_CTL_BIT | 0x20, 0); + } + + if (!chip->ft2_fast_mode) { + retval = card_power_on(chip, MS_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + wait_timeout(150); + +#ifdef SUPPORT_OCP + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + oc_mask = MS_OC_NOW | MS_OC_EVER; + } else { + oc_mask = SD_OC_NOW | SD_OC_EVER; + } + if (chip->ocp_stat & oc_mask) { + RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", + chip->ocp_stat); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + } + + RTSX_WRITE_REG(chip, CARD_OE, MS_OUTPUT_EN, MS_OUTPUT_EN); + + if (chip->asic_code) { + RTSX_WRITE_REG(chip, MS_CFG, 0xFF, + SAMPLE_TIME_RISING | PUSH_TIME_DEFAULT | + NO_EXTEND_TOGGLE | MS_BUS_WIDTH_1); + } else { + RTSX_WRITE_REG(chip, MS_CFG, 0xFF, + SAMPLE_TIME_FALLING | PUSH_TIME_DEFAULT | + NO_EXTEND_TOGGLE | MS_BUS_WIDTH_1); + } + RTSX_WRITE_REG(chip, MS_TRANS_CFG, 0xFF, NO_WAIT_INT | NO_AUTO_READ_INT_REG); + RTSX_WRITE_REG(chip, CARD_STOP, MS_STOP | MS_CLR_ERR, MS_STOP | MS_CLR_ERR); + + retval = ms_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int ms_identify_media_type(struct rtsx_chip *chip, int switch_8bit_bus) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 val; + + retval = ms_set_rw_reg_addr(chip, Pro_StatusReg, 6, SystemParm, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, READ_REG, 6, NO_WAIT_INT); + if (retval == STATUS_SUCCESS) { + break; + } + } + if (i == MS_MAX_RETRY_COUNT) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_READ_REG(chip, PPBUF_BASE2 + 2, &val); + RTSX_DEBUGP("Type register: 0x%x\n", val); + if (val != 0x01) { + if (val != 0x02) { + ms_card->check_ms_flow = 1; + } + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_READ_REG(chip, PPBUF_BASE2 + 4, &val); + RTSX_DEBUGP("Category register: 0x%x\n", val); + if (val != 0) { + ms_card->check_ms_flow = 1; + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_READ_REG(chip, PPBUF_BASE2 + 5, &val); + RTSX_DEBUGP("Class register: 0x%x\n", val); + if (val == 0) { + RTSX_READ_REG(chip, PPBUF_BASE2, &val); + if (val & WRT_PRTCT) { + chip->card_wp |= MS_CARD; + } else { + chip->card_wp &= ~MS_CARD; + } + } else if ((val == 0x01) || (val == 0x02) || (val == 0x03)) { + chip->card_wp |= MS_CARD; + } else { + ms_card->check_ms_flow = 1; + TRACE_RET(chip, STATUS_FAIL); + } + + ms_card->ms_type |= TYPE_MSPRO; + + RTSX_READ_REG(chip, PPBUF_BASE2 + 3, &val); + RTSX_DEBUGP("IF Mode register: 0x%x\n", val); + if (val == 0) { + ms_card->ms_type &= 0x0F; + } else if (val == 7) { + if (switch_8bit_bus) { + ms_card->ms_type |= MS_HG; + } else { + ms_card->ms_type &= 0x0F; + } + } else { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int ms_confirm_cpu_startup(struct rtsx_chip *chip) +{ + int retval, i, k; + u8 val; + + /* Confirm CPU StartUp */ + k = 0; + do { + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval == STATUS_SUCCESS) { + break; + } + } + if (i == MS_MAX_RETRY_COUNT) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (k > 100) { + TRACE_RET(chip, STATUS_FAIL); + } + k++; + wait_timeout(100); + } while (!(val & INT_REG_CED)); + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_ERR) { + if (val & INT_REG_CMDNK) { + chip->card_wp |= (MS_CARD); + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } + /* -- end confirm CPU startup */ + + return STATUS_SUCCESS; +} + +static int ms_switch_parallel_bus(struct rtsx_chip *chip) +{ + int retval, i; + u8 data[2]; + + data[0] = PARALLEL_4BIT_IF; + data[1] = 0; + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, WRITE_REG, 1, NO_WAIT_INT, data, 2); + if (retval == STATUS_SUCCESS) + break; + } + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int ms_switch_8bit_bus(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 data[2]; + + data[0] = PARALLEL_8BIT_IF; + data[1] = 0; + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, WRITE_REG, 1, NO_WAIT_INT, data, 2); + if (retval == STATUS_SUCCESS) { + break; + } + } + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, MS_CFG, 0x98, MS_BUS_WIDTH_8 | SAMPLE_TIME_FALLING); + ms_card->ms_type |= MS_8BIT; + retval = ms_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT, 1, NO_WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + +static int ms_pro_reset_flow(struct rtsx_chip *chip, int switch_8bit_bus) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + + for (i = 0; i < 3; i++) { + retval = ms_prepare_reset(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_identify_media_type(chip, switch_8bit_bus); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_confirm_cpu_startup(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_switch_parallel_bus(chip); + if (retval != STATUS_SUCCESS) { + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + continue; + } else { + break; + } + } + + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + /* Switch MS-PRO into Parallel mode */ + RTSX_WRITE_REG(chip, MS_CFG, 0x18, MS_BUS_WIDTH_4); + RTSX_WRITE_REG(chip, MS_CFG, PUSH_TIME_ODD, PUSH_TIME_ODD); + + retval = ms_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + /* If MSPro HG Card, We shall try to switch to 8-bit bus */ + if (CHK_MSHG(ms_card) && chip->support_ms_8bit && switch_8bit_bus) { + retval = ms_switch_8bit_bus(chip); + if (retval != STATUS_SUCCESS) { + ms_card->switch_8bit_fail = 1; + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + +#ifdef XC_POWERCLASS +static int msxc_change_power(struct rtsx_chip *chip, u8 mode) +{ + int retval; + u8 buf[6]; + + ms_cleanup_work(chip); + + retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + buf[0] = 0; + buf[1] = mode; + buf[2] = 0; + buf[3] = 0; + buf[4] = 0; + buf[5] = 0; + + retval = ms_write_bytes(chip, PRO_WRITE_REG , 6, NO_WAIT_INT, buf, 6); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_send_cmd(chip, XC_CHG_POWER, WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_READ_REG(chip, MS_TRANS_CFG, buf); + if (buf[0] & (MS_INT_CMDNK | MS_INT_ERR)) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} +#endif + +static int ms_read_attribute_info(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 val, *buf, class_code, device_type, sub_class, data[16]; + u16 total_blk = 0, blk_size = 0; +#ifdef SUPPORT_MSXC + u32 xc_total_blk = 0, xc_blk_size = 0; +#endif + u32 sys_info_addr = 0, sys_info_size; +#ifdef SUPPORT_PCGL_1P18 + u32 model_name_addr = 0, model_name_size; + int found_sys_info = 0, found_model_name = 0; +#endif + + retval = ms_set_rw_reg_addr(chip, Pro_IntReg, 2, Pro_SystemParm, 7); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (CHK_MS8BIT(ms_card)) { + data[0] = PARALLEL_8BIT_IF; + } else { + data[0] = PARALLEL_4BIT_IF; + } + data[1] = 0; + + data[2] = 0x40; + data[3] = 0; + data[4] = 0; + data[5] = 0; + data[6] = 0; + data[7] = 0; + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, PRO_WRITE_REG, 7, NO_WAIT_INT, data, 8); + if (retval == STATUS_SUCCESS) { + break; + } + } + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + buf = (u8 *)rtsx_alloc_dma_buf(chip, 64 * 512, GFP_KERNEL); + if (buf == NULL) { + TRACE_RET(chip, STATUS_ERROR); + } + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_send_cmd(chip, PRO_READ_ATRB, WAIT_INT); + if (retval != STATUS_SUCCESS) { + continue; + } + retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); + if (retval != STATUS_SUCCESS) { + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + if (!(val & MS_INT_BREQ)) { + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA, + 0x40, WAIT_INT, 0, 0, buf, 64 * 512); + if (retval == STATUS_SUCCESS) { + break; + } else { + rtsx_clear_ms_error(chip); + } + } + if (retval != STATUS_SUCCESS) { + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + + i = 0; + do { + retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); + if (retval != STATUS_SUCCESS) { + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + + if ((val & MS_INT_CED) || !(val & MS_INT_BREQ)) + break; + + retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, PRO_READ_LONG_DATA, 0, WAIT_INT); + if (retval != STATUS_SUCCESS) { + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + + i++; + } while (i < 1024); + + if (retval != STATUS_SUCCESS) { + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + + if ((buf[0] != 0xa5) && (buf[1] != 0xc3)) { + /* Signature code is wrong */ + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + + if ((buf[4] < 1) || (buf[4] > 12)) { + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + + for (i = 0; i < buf[4]; i++) { + int cur_addr_off = 16 + i * 12; + +#ifdef SUPPORT_MSXC + if ((buf[cur_addr_off + 8] == 0x10) || (buf[cur_addr_off + 8] == 0x13)) +#else + if (buf[cur_addr_off + 8] == 0x10) +#endif + { + sys_info_addr = ((u32)buf[cur_addr_off + 0] << 24) | + ((u32)buf[cur_addr_off + 1] << 16) | + ((u32)buf[cur_addr_off + 2] << 8) | buf[cur_addr_off + 3]; + sys_info_size = ((u32)buf[cur_addr_off + 4] << 24) | + ((u32)buf[cur_addr_off + 5] << 16) | + ((u32)buf[cur_addr_off + 6] << 8) | buf[cur_addr_off + 7]; + RTSX_DEBUGP("sys_info_addr = 0x%x, sys_info_size = 0x%x\n", + sys_info_addr, sys_info_size); + if (sys_info_size != 96) { + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + if (sys_info_addr < 0x1A0) { + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + if ((sys_info_size + sys_info_addr) > 0x8000) { + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + +#ifdef SUPPORT_MSXC + if (buf[cur_addr_off + 8] == 0x13) { + ms_card->ms_type |= MS_XC; + } +#endif +#ifdef SUPPORT_PCGL_1P18 + found_sys_info = 1; +#else + break; +#endif + } +#ifdef SUPPORT_PCGL_1P18 + if (buf[cur_addr_off + 8] == 0x15) { + model_name_addr = ((u32)buf[cur_addr_off + 0] << 24) | + ((u32)buf[cur_addr_off + 1] << 16) | + ((u32)buf[cur_addr_off + 2] << 8) | buf[cur_addr_off + 3]; + model_name_size = ((u32)buf[cur_addr_off + 4] << 24) | + ((u32)buf[cur_addr_off + 5] << 16) | + ((u32)buf[cur_addr_off + 6] << 8) | buf[cur_addr_off + 7]; + RTSX_DEBUGP("model_name_addr = 0x%x, model_name_size = 0x%x\n", + model_name_addr, model_name_size); + if (model_name_size != 48) { + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + if (model_name_addr < 0x1A0) { + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + if ((model_name_size + model_name_addr) > 0x8000) { + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + + found_model_name = 1; + } + + if (found_sys_info && found_model_name) + break; +#endif + } + + if (i == buf[4]) { + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + + class_code = buf[sys_info_addr + 0]; + device_type = buf[sys_info_addr + 56]; + sub_class = buf[sys_info_addr + 46]; +#ifdef SUPPORT_MSXC + if (CHK_MSXC(ms_card)) { + xc_total_blk = ((u32)buf[sys_info_addr + 6] << 24) | + ((u32)buf[sys_info_addr + 7] << 16) | + ((u32)buf[sys_info_addr + 8] << 8) | + buf[sys_info_addr + 9]; + xc_blk_size = ((u32)buf[sys_info_addr + 32] << 24) | + ((u32)buf[sys_info_addr + 33] << 16) | + ((u32)buf[sys_info_addr + 34] << 8) | + buf[sys_info_addr + 35]; + RTSX_DEBUGP("xc_total_blk = 0x%x, xc_blk_size = 0x%x\n", xc_total_blk, xc_blk_size); + } else { + total_blk = ((u16)buf[sys_info_addr + 6] << 8) | buf[sys_info_addr + 7]; + blk_size = ((u16)buf[sys_info_addr + 2] << 8) | buf[sys_info_addr + 3]; + RTSX_DEBUGP("total_blk = 0x%x, blk_size = 0x%x\n", total_blk, blk_size); + } +#else + total_blk = ((u16)buf[sys_info_addr + 6] << 8) | buf[sys_info_addr + 7]; + blk_size = ((u16)buf[sys_info_addr + 2] << 8) | buf[sys_info_addr + 3]; + RTSX_DEBUGP("total_blk = 0x%x, blk_size = 0x%x\n", total_blk, blk_size); +#endif + + RTSX_DEBUGP("class_code = 0x%x, device_type = 0x%x, sub_class = 0x%x\n", + class_code, device_type, sub_class); + + memcpy(ms_card->raw_sys_info, buf + sys_info_addr, 96); +#ifdef SUPPORT_PCGL_1P18 + memcpy(ms_card->raw_model_name, buf + model_name_addr, 48); +#endif + + rtsx_free_dma_buf(chip, buf); + +#ifdef SUPPORT_MSXC + if (CHK_MSXC(ms_card)) { + if (class_code != 0x03) { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + if (class_code != 0x02) { + TRACE_RET(chip, STATUS_FAIL); + } + } +#else + if (class_code != 0x02) { + TRACE_RET(chip, STATUS_FAIL); + } +#endif + + if (device_type != 0x00) { + if ((device_type == 0x01) || (device_type == 0x02) || + (device_type == 0x03)) { + chip->card_wp |= MS_CARD; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (sub_class & 0xC0) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_DEBUGP("class_code: 0x%x, device_type: 0x%x, sub_class: 0x%x\n", + class_code, device_type, sub_class); + +#ifdef SUPPORT_MSXC + if (CHK_MSXC(ms_card)) { + chip->capacity[chip->card2lun[MS_CARD]] = + ms_card->capacity = xc_total_blk * xc_blk_size; + } else { + chip->capacity[chip->card2lun[MS_CARD]] = + ms_card->capacity = total_blk * blk_size; + } +#else + chip->capacity[chip->card2lun[MS_CARD]] = ms_card->capacity = total_blk * blk_size; +#endif + + return STATUS_SUCCESS; +} + +#ifdef SUPPORT_MAGIC_GATE +static int mg_set_tpc_para_sub(struct rtsx_chip *chip, int type, u8 mg_entry_num); +#endif + +static int reset_ms_pro(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; +#ifdef XC_POWERCLASS + u8 change_power_class = 2; +#endif + +#ifdef XC_POWERCLASS +Retry: +#endif + retval = ms_pro_reset_flow(chip, 1); + if (retval != STATUS_SUCCESS) { + if (ms_card->switch_8bit_fail) { + retval = ms_pro_reset_flow(chip, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = ms_read_attribute_info(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + +#ifdef XC_POWERCLASS + if (CHK_HG8BIT(ms_card)) { + change_power_class = 0; + } + + if (change_power_class && CHK_MSXC(ms_card)) { + u8 power_class_en = 0x03; + + if (CHECK_PID(chip, 0x5209)) + power_class_en = chip->ms_power_class_en; + + RTSX_DEBUGP("power_class_en = 0x%x\n", power_class_en); + RTSX_DEBUGP("change_power_class = %d\n", change_power_class); + + if (change_power_class) { + power_class_en &= (1 << (change_power_class - 1)); + } else { + power_class_en = 0; + } + + if (power_class_en) { + u8 power_class_mode = (ms_card->raw_sys_info[46] & 0x18) >> 3; + RTSX_DEBUGP("power_class_mode = 0x%x", power_class_mode); + if (change_power_class > power_class_mode) + change_power_class = power_class_mode; + if (change_power_class) { + retval = msxc_change_power(chip, change_power_class); + if (retval != STATUS_SUCCESS) { + change_power_class--; + goto Retry; + } + } + } + } +#endif + +#ifdef SUPPORT_MAGIC_GATE + retval = mg_set_tpc_para_sub(chip, 0, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } +#endif + + if (CHK_HG8BIT(ms_card)) { + chip->card_bus_width[chip->card2lun[MS_CARD]] = 8; + } else { + chip->card_bus_width[chip->card2lun[MS_CARD]] = 4; + } + + return STATUS_SUCCESS; +} + +static int ms_read_status_reg(struct rtsx_chip *chip) +{ + int retval; + u8 val[2]; + + retval = ms_set_rw_reg_addr(chip, StatusReg0, 2, 0, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_read_bytes(chip, READ_REG, 2, NO_WAIT_INT, val, 2); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (val[1] & (STS_UCDT | STS_UCEX | STS_UCFG)) { + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + + +static int ms_read_extra_data(struct rtsx_chip *chip, + u16 block_addr, u8 page_num, u8 *buf, int buf_len) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 val, data[10]; + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (CHK_MS4BIT(ms_card)) { + /* Parallel interface */ + data[0] = 0x88; + } else { + /* Serial interface */ + data[0] = 0x80; + } + data[1] = 0; + data[2] = (u8)(block_addr >> 8); + data[3] = (u8)block_addr; + data[4] = 0x40; + data[5] = page_num; + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) { + TRACE_RET(chip, STATUS_FAIL); + } + + ms_set_err_code(chip, MS_NO_ERROR); + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) { + TRACE_RET(chip, STATUS_FAIL); + } + + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + retval = ms_read_bytes(chip, READ_REG, MS_EXTRA_SIZE, NO_WAIT_INT, data, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (buf && buf_len) { + if (buf_len > MS_EXTRA_SIZE) + buf_len = MS_EXTRA_SIZE; + memcpy(buf, data, buf_len); + } + + return STATUS_SUCCESS; +} + +static int ms_write_extra_data(struct rtsx_chip *chip, + u16 block_addr, u8 page_num, u8 *buf, int buf_len) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 val, data[16]; + + if (!buf || (buf_len < MS_EXTRA_SIZE)) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6 + MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (CHK_MS4BIT(ms_card)) { + data[0] = 0x88; + } else { + data[0] = 0x80; + } + data[1] = 0; + data[2] = (u8)(block_addr >> 8); + data[3] = (u8)block_addr; + data[4] = 0x40; + data[5] = page_num; + + for (i = 6; i < MS_EXTRA_SIZE + 6; i++) { + data[i] = buf[i - 6]; + } + + retval = ms_write_bytes(chip, WRITE_REG , (6+MS_EXTRA_SIZE), NO_WAIT_INT, data, 16); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + + +static int ms_read_page(struct rtsx_chip *chip, u16 block_addr, u8 page_num) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + u8 val, data[6]; + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (CHK_MS4BIT(ms_card)) { + data[0] = 0x88; + } else { + data[0] = 0x80; + } + data[1] = 0; + data[2] = (u8)(block_addr >> 8); + data[3] = (u8)block_addr; + data[4] = 0x20; + data[5] = page_num; + + retval = ms_write_bytes(chip, WRITE_REG , 6, NO_WAIT_INT, data, 6); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + if (!(val & INT_REG_BREQ)) { + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + } + } else { + if (!(val & INT_REG_BREQ)) { + ms_set_err_code(chip, MS_BREQ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, READ_PAGE_DATA, 0, NO_WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR)) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + + +static int ms_set_bad_block(struct rtsx_chip *chip, u16 phy_blk) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + u8 val, data[8], extra[MS_EXTRA_SIZE]; + + retval = ms_read_extra_data(chip, phy_blk, 0, extra, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 7); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + ms_set_err_code(chip, MS_NO_ERROR); + + if (CHK_MS4BIT(ms_card)) { + data[0] = 0x88; + } else { + data[0] = 0x80; + } + data[1] = 0; + data[2] = (u8)(phy_blk >> 8); + data[3] = (u8)phy_blk; + data[4] = 0x80; + data[5] = 0; + data[6] = extra[0] & 0x7F; + data[7] = 0xFF; + + retval = ms_write_bytes(chip, WRITE_REG , 7, NO_WAIT_INT, data, 7); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + + +static int ms_erase_block(struct rtsx_chip *chip, u16 phy_blk) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i = 0; + u8 val, data[6]; + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + ms_set_err_code(chip, MS_NO_ERROR); + + if (CHK_MS4BIT(ms_card)) { + data[0] = 0x88; + } else { + data[0] = 0x80; + } + data[1] = 0; + data[2] = (u8)(phy_blk >> 8); + data[3] = (u8)phy_blk; + data[4] = 0; + data[5] = 0; + + retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + +ERASE_RTY: + retval = ms_send_cmd(chip, BLOCK_ERASE, WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CMDNK) { + if (i < 3) { + i++; + goto ERASE_RTY; + } + + ms_set_err_code(chip, MS_CMD_NK); + ms_set_bad_block(chip, phy_blk); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + + +static void ms_set_page_status(u16 log_blk, u8 type, u8 *extra, int extra_len) +{ + if (!extra || (extra_len < MS_EXTRA_SIZE)) { + return; + } + + memset(extra, 0xFF, MS_EXTRA_SIZE); + + if (type == setPS_NG) { + /* set page status as 1:NG,and block status keep 1:OK */ + extra[0] = 0xB8; + } else { + /* set page status as 0:Data Error,and block status keep 1:OK */ + extra[0] = 0x98; + } + + extra[2] = (u8)(log_blk >> 8); + extra[3] = (u8)log_blk; +} + +static int ms_init_page(struct rtsx_chip *chip, u16 phy_blk, u16 log_blk, u8 start_page, u8 end_page) +{ + int retval; + u8 extra[MS_EXTRA_SIZE], i; + + memset(extra, 0xff, MS_EXTRA_SIZE); + + extra[0] = 0xf8; /* Block, page OK, data erased */ + extra[1] = 0xff; + extra[2] = (u8)(log_blk >> 8); + extra[3] = (u8)log_blk; + + for (i = start_page; i < end_page; i++) { + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_write_extra_data(chip, phy_blk, i, extra, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + +static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, + u16 log_blk, u8 start_page, u8 end_page) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, rty_cnt, uncorrect_flag = 0; + u8 extra[MS_EXTRA_SIZE], val, i, j, data[16]; + + RTSX_DEBUGP("Copy page from 0x%x to 0x%x, logical block is 0x%x\n", + old_blk, new_blk, log_blk); + RTSX_DEBUGP("start_page = %d, end_page = %d\n", start_page, end_page); + + retval = ms_read_extra_data(chip, new_blk, 0, extra, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_READ_REG(chip, PPBUF_BASE2, &val); + + if (val & BUF_FULL) { + retval = ms_send_cmd(chip, CLEAR_BUF, WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (!(val & INT_REG_CED)) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + for (i = start_page; i < end_page; i++) { + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + ms_read_extra_data(chip, old_blk, i, extra, MS_EXTRA_SIZE); + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + ms_set_err_code(chip, MS_NO_ERROR); + + if (CHK_MS4BIT(ms_card)) { + data[0] = 0x88; + } else { + data[0] = 0x80; + } + data[1] = 0; + data[2] = (u8)(old_blk >> 8); + data[3] = (u8)old_blk; + data[4] = 0x20; + data[5] = i; + + retval = ms_write_bytes(chip, WRITE_REG , 6, NO_WAIT_INT, data, 6); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) { + uncorrect_flag = 1; + RTSX_DEBUGP("Uncorrectable error\n"); + } else { + uncorrect_flag = 0; + } + + retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, READ_PAGE_DATA, 0, NO_WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (uncorrect_flag) { + ms_set_page_status(log_blk, setPS_NG, extra, MS_EXTRA_SIZE); + if (i == 0) { + extra[0] &= 0xEF; + } + ms_write_extra_data(chip, old_blk, i, extra, MS_EXTRA_SIZE); + RTSX_DEBUGP("page %d : extra[0] = 0x%x\n", i, extra[0]); + MS_SET_BAD_BLOCK_FLG(ms_card); + + ms_set_page_status(log_blk, setPS_Error, extra, MS_EXTRA_SIZE); + ms_write_extra_data(chip, new_blk, i, extra, MS_EXTRA_SIZE); + continue; + } + + for (rty_cnt = 0; rty_cnt < MS_MAX_RETRY_COUNT; rty_cnt++) { + retval = ms_transfer_tpc(chip, MS_TM_NORMAL_WRITE, + WRITE_PAGE_DATA, 0, NO_WAIT_INT); + if (retval == STATUS_SUCCESS) { + break; + } + } + if (rty_cnt == MS_MAX_RETRY_COUNT) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (!(val & INT_REG_BREQ)) { + ms_set_err_code(chip, MS_BREQ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, + MS_EXTRA_SIZE, SystemParm, (6+MS_EXTRA_SIZE)); + + ms_set_err_code(chip, MS_NO_ERROR); + + if (CHK_MS4BIT(ms_card)) { + data[0] = 0x88; + } else { + data[0] = 0x80; + } + data[1] = 0; + data[2] = (u8)(new_blk >> 8); + data[3] = (u8)new_blk; + data[4] = 0x20; + data[5] = i; + + if ((extra[0] & 0x60) != 0x60) { + data[6] = extra[0]; + } else { + data[6] = 0xF8; + } + data[6 + 1] = 0xFF; + data[6 + 2] = (u8)(log_blk >> 8); + data[6 + 3] = (u8)log_blk; + + for (j = 4; j <= MS_EXTRA_SIZE; j++) { + data[6 + j] = 0xFF; + } + + retval = ms_write_bytes(chip, WRITE_REG, (6 + MS_EXTRA_SIZE), NO_WAIT_INT, data, 16); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (i == 0) { + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 7); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + ms_set_err_code(chip, MS_NO_ERROR); + + if (CHK_MS4BIT(ms_card)) { + data[0] = 0x88; + } else { + data[0] = 0x80; + } + data[1] = 0; + data[2] = (u8)(old_blk >> 8); + data[3] = (u8)old_blk; + data[4] = 0x80; + data[5] = 0; + data[6] = 0xEF; + data[7] = 0xFF; + + retval = ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT, data, 8); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + } + } + + return STATUS_SUCCESS; +} + + +static int reset_ms(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + u16 i, reg_addr, block_size; + u8 val, extra[MS_EXTRA_SIZE], j, *ptr; +#ifndef SUPPORT_MAGIC_GATE + u16 eblock_cnt; +#endif + + retval = ms_prepare_reset(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + ms_card->ms_type |= TYPE_MS; + + retval = ms_send_cmd(chip, MS_RESET, NO_WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_READ_REG(chip, PPBUF_BASE2, &val); + if (val & WRT_PRTCT) { + chip->card_wp |= MS_CARD; + } else { + chip->card_wp &= ~MS_CARD; + } + + i = 0; + +RE_SEARCH: + /* Search Boot Block */ + while (i < (MAX_DEFECTIVE_BLOCK + 2)) { + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_read_extra_data(chip, i, 0, extra, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) { + i++; + continue; + } + + if (extra[0] & BLOCK_OK) { + if (!(extra[1] & NOT_BOOT_BLOCK)) { + ms_card->boot_block = i; + break; + } + } + i++; + } + + if (i == (MAX_DEFECTIVE_BLOCK + 2)) { + RTSX_DEBUGP("No boot block found!"); + TRACE_RET(chip, STATUS_FAIL); + } + + for (j = 0; j < 3; j++) { + retval = ms_read_page(chip, ms_card->boot_block, j); + if (retval != STATUS_SUCCESS) { + if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR)) { + i = ms_card->boot_block + 1; + ms_set_err_code(chip, MS_NO_ERROR); + goto RE_SEARCH; + } + } + } + + retval = ms_read_page(chip, ms_card->boot_block, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + /* Read MS system information as sys_info */ + rtsx_init_cmd(chip); + + for (i = 0; i < 96; i++) { + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 0x1A0 + i, 0, 0); + } + + retval = rtsx_send_cmd(chip, MS_CARD, 100); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + + ptr = rtsx_get_cmd_data(chip); + memcpy(ms_card->raw_sys_info, ptr, 96); + + /* Read useful block contents */ + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, READ_REG_CMD, HEADER_ID0, 0, 0); + rtsx_add_cmd(chip, READ_REG_CMD, HEADER_ID1, 0, 0); + + for (reg_addr = DISABLED_BLOCK0; reg_addr <= DISABLED_BLOCK3; reg_addr++) { + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); + } + + for (reg_addr = BLOCK_SIZE_0; reg_addr <= PAGE_SIZE_1; reg_addr++) { + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); + } + + rtsx_add_cmd(chip, READ_REG_CMD, MS_Device_Type, 0, 0); + rtsx_add_cmd(chip, READ_REG_CMD, MS_4bit_Support, 0, 0); + + retval = rtsx_send_cmd(chip, MS_CARD, 100); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + + ptr = rtsx_get_cmd_data(chip); + + RTSX_DEBUGP("Boot block data:\n"); + RTSX_DUMP(ptr, 16); + + /* Block ID error + * HEADER_ID0, HEADER_ID1 + */ + if (ptr[0] != 0x00 || ptr[1] != 0x01) { + i = ms_card->boot_block + 1; + goto RE_SEARCH; + } + + /* Page size error + * PAGE_SIZE_0, PAGE_SIZE_1 + */ + if (ptr[12] != 0x02 || ptr[13] != 0x00) { + i = ms_card->boot_block + 1; + goto RE_SEARCH; + } + + if ((ptr[14] == 1) || (ptr[14] == 3)) { + chip->card_wp |= MS_CARD; + } + + /* BLOCK_SIZE_0, BLOCK_SIZE_1 */ + block_size = ((u16)ptr[6] << 8) | ptr[7]; + if (block_size == 0x0010) { + /* Block size 16KB */ + ms_card->block_shift = 5; + ms_card->page_off = 0x1F; + } else if (block_size == 0x0008) { + /* Block size 8KB */ + ms_card->block_shift = 4; + ms_card->page_off = 0x0F; + } + + /* BLOCK_COUNT_0, BLOCK_COUNT_1 */ + ms_card->total_block = ((u16)ptr[8] << 8) | ptr[9]; + +#ifdef SUPPORT_MAGIC_GATE + j = ptr[10]; + + if (ms_card->block_shift == 4) { /* 4MB or 8MB */ + if (j < 2) { /* Effective block for 4MB: 0x1F0 */ + ms_card->capacity = 0x1EE0; + } else { /* Effective block for 8MB: 0x3E0 */ + ms_card->capacity = 0x3DE0; + } + } else { /* 16MB, 32MB, 64MB or 128MB */ + if (j < 5) { /* Effective block for 16MB: 0x3E0 */ + ms_card->capacity = 0x7BC0; + } else if (j < 0xA) { /* Effective block for 32MB: 0x7C0 */ + ms_card->capacity = 0xF7C0; + } else if (j < 0x11) { /* Effective block for 64MB: 0xF80 */ + ms_card->capacity = 0x1EF80; + } else { /* Effective block for 128MB: 0x1F00 */ + ms_card->capacity = 0x3DF00; + } + } +#else + /* EBLOCK_COUNT_0, EBLOCK_COUNT_1 */ + eblock_cnt = ((u16)ptr[10] << 8) | ptr[11]; + + ms_card->capacity = ((u32)eblock_cnt - 2) << ms_card->block_shift; +#endif + + chip->capacity[chip->card2lun[MS_CARD]] = ms_card->capacity; + + /* Switch I/F Mode */ + if (ptr[15]) { + retval = ms_set_rw_reg_addr(chip, 0, 0, SystemParm, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, PPBUF_BASE2, 0xFF, 0x88); + RTSX_WRITE_REG(chip, PPBUF_BASE2 + 1, 0xFF, 0); + + retval = ms_transfer_tpc(chip, MS_TM_WRITE_BYTES, WRITE_REG , 1, NO_WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, MS_CFG, 0x58 | MS_NO_CHECK_INT, + MS_BUS_WIDTH_4 | PUSH_TIME_ODD | MS_NO_CHECK_INT); + + ms_card->ms_type |= MS_4BIT; + } + + if (CHK_MS4BIT(ms_card)) { + chip->card_bus_width[chip->card2lun[MS_CARD]] = 4; + } else { + chip->card_bus_width[chip->card2lun[MS_CARD]] = 1; + } + + return STATUS_SUCCESS; +} + +static int ms_init_l2p_tbl(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int size, i, seg_no, retval; + u16 defect_block, reg_addr; + u8 val1, val2; + + ms_card->segment_cnt = ms_card->total_block >> 9; + RTSX_DEBUGP("ms_card->segment_cnt = %d\n", ms_card->segment_cnt); + + size = ms_card->segment_cnt * sizeof(struct zone_entry); + ms_card->segment = (struct zone_entry *)vmalloc(size); + if (ms_card->segment == NULL) { + TRACE_RET(chip, STATUS_FAIL); + } + memset(ms_card->segment, 0, size); + + retval = ms_read_page(chip, ms_card->boot_block, 1); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, INIT_FAIL); + } + + reg_addr = PPBUF_BASE2; + for (i = 0; i < (((ms_card->total_block >> 9) * 10) + 1); i++) { + retval = rtsx_read_register(chip, reg_addr++, &val1); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, INIT_FAIL); + } + retval = rtsx_read_register(chip, reg_addr++, &val2); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, INIT_FAIL); + } + + defect_block = ((u16)val1 << 8) | val2; + if (defect_block == 0xFFFF) { + break; + } + seg_no = defect_block / 512; + ms_card->segment[seg_no].defect_list[ms_card->segment[seg_no].disable_count++] = defect_block; + } + + for (i = 0; i < ms_card->segment_cnt; i++) { + ms_card->segment[i].build_flag = 0; + ms_card->segment[i].l2p_table = NULL; + ms_card->segment[i].free_table = NULL; + ms_card->segment[i].get_index = 0; + ms_card->segment[i].set_index = 0; + ms_card->segment[i].unused_blk_cnt = 0; + + RTSX_DEBUGP("defective block count of segment %d is %d\n", + i, ms_card->segment[i].disable_count); + } + + return STATUS_SUCCESS; + +INIT_FAIL: + if (ms_card->segment) { + vfree(ms_card->segment); + ms_card->segment = NULL; + } + + return STATUS_FAIL; +} + +static u16 ms_get_l2p_tbl(struct rtsx_chip *chip, int seg_no, u16 log_off) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct zone_entry *segment; + + if (ms_card->segment == NULL) + return 0xFFFF; + + segment = &(ms_card->segment[seg_no]); + + if (segment->l2p_table) + return segment->l2p_table[log_off]; + + return 0xFFFF; +} + +static void ms_set_l2p_tbl(struct rtsx_chip *chip, int seg_no, u16 log_off, u16 phy_blk) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct zone_entry *segment; + + if (ms_card->segment == NULL) + return; + + segment = &(ms_card->segment[seg_no]); + if (segment->l2p_table) { + segment->l2p_table[log_off] = phy_blk; + } +} + +static void ms_set_unused_block(struct rtsx_chip *chip, u16 phy_blk) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct zone_entry *segment; + int seg_no; + + seg_no = (int)phy_blk >> 9; + segment = &(ms_card->segment[seg_no]); + + segment->free_table[segment->set_index++] = phy_blk; + if (segment->set_index >= MS_FREE_TABLE_CNT) { + segment->set_index = 0; + } + segment->unused_blk_cnt++; +} + +static u16 ms_get_unused_block(struct rtsx_chip *chip, int seg_no) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct zone_entry *segment; + u16 phy_blk; + + segment = &(ms_card->segment[seg_no]); + + if (segment->unused_blk_cnt <= 0) + return 0xFFFF; + + phy_blk = segment->free_table[segment->get_index]; + segment->free_table[segment->get_index++] = 0xFFFF; + if (segment->get_index >= MS_FREE_TABLE_CNT) { + segment->get_index = 0; + } + segment->unused_blk_cnt--; + + return phy_blk; +} + +static const unsigned short ms_start_idx[] = {0, 494, 990, 1486, 1982, 2478, 2974, 3470, + 3966, 4462, 4958, 5454, 5950, 6446, 6942, 7438, 7934}; + +static int ms_arbitrate_l2p(struct rtsx_chip *chip, u16 phy_blk, u16 log_off, u8 us1, u8 us2) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct zone_entry *segment; + int seg_no; + u16 tmp_blk; + + seg_no = (int)phy_blk >> 9; + segment = &(ms_card->segment[seg_no]); + tmp_blk = segment->l2p_table[log_off]; + + if (us1 != us2) { + if (us1 == 0) { + if (!(chip->card_wp & MS_CARD)) { + ms_erase_block(chip, tmp_blk); + } + ms_set_unused_block(chip, tmp_blk); + segment->l2p_table[log_off] = phy_blk; + } else { + if (!(chip->card_wp & MS_CARD)) { + ms_erase_block(chip, phy_blk); + } + ms_set_unused_block(chip, phy_blk); + } + } else { + if (phy_blk < tmp_blk) { + if (!(chip->card_wp & MS_CARD)) { + ms_erase_block(chip, phy_blk); + } + ms_set_unused_block(chip, phy_blk); + } else { + if (!(chip->card_wp & MS_CARD)) { + ms_erase_block(chip, tmp_blk); + } + ms_set_unused_block(chip, tmp_blk); + segment->l2p_table[log_off] = phy_blk; + } + } + + return STATUS_SUCCESS; +} + +static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct zone_entry *segment; + int retval, table_size, disable_cnt, defect_flag, i; + u16 start, end, phy_blk, log_blk, tmp_blk; + u8 extra[MS_EXTRA_SIZE], us1, us2; + + RTSX_DEBUGP("ms_build_l2p_tbl: %d\n", seg_no); + + if (ms_card->segment == NULL) { + retval = ms_init_l2p_tbl(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, retval); + } + } + + if (ms_card->segment[seg_no].build_flag) { + RTSX_DEBUGP("l2p table of segment %d has been built\n", seg_no); + return STATUS_SUCCESS; + } + + if (seg_no == 0) { + table_size = 494; + } else { + table_size = 496; + } + + segment = &(ms_card->segment[seg_no]); + + if (segment->l2p_table == NULL) { + segment->l2p_table = (u16 *)vmalloc(table_size * 2); + if (segment->l2p_table == NULL) { + TRACE_GOTO(chip, BUILD_FAIL); + } + } + memset((u8 *)(segment->l2p_table), 0xff, table_size * 2); + + if (segment->free_table == NULL) { + segment->free_table = (u16 *)vmalloc(MS_FREE_TABLE_CNT * 2); + if (segment->free_table == NULL) { + TRACE_GOTO(chip, BUILD_FAIL); + } + } + memset((u8 *)(segment->free_table), 0xff, MS_FREE_TABLE_CNT * 2); + + start = (u16)seg_no << 9; + end = (u16)(seg_no + 1) << 9; + + disable_cnt = segment->disable_count; + + segment->get_index = segment->set_index = 0; + segment->unused_blk_cnt = 0; + + for (phy_blk = start; phy_blk < end; phy_blk++) { + if (disable_cnt) { + defect_flag = 0; + for (i = 0; i < segment->disable_count; i++) { + if (phy_blk == segment->defect_list[i]) { + defect_flag = 1; + break; + } + } + if (defect_flag) { + disable_cnt--; + continue; + } + } + + retval = ms_read_extra_data(chip, phy_blk, 0, extra, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) { + RTSX_DEBUGP("read extra data fail\n"); + ms_set_bad_block(chip, phy_blk); + continue; + } + + if (seg_no == ms_card->segment_cnt - 1) { + if (!(extra[1] & NOT_TRANSLATION_TABLE)) { + if (!(chip->card_wp & MS_CARD)) { + retval = ms_erase_block(chip, phy_blk); + if (retval != STATUS_SUCCESS) + continue; + extra[2] = 0xff; + extra[3] = 0xff; + } + } + } + + if (!(extra[0] & BLOCK_OK)) + continue; + if (!(extra[1] & NOT_BOOT_BLOCK)) + continue; + if ((extra[0] & PAGE_OK) != PAGE_OK) + continue; + + log_blk = ((u16)extra[2] << 8) | extra[3]; + + if (log_blk == 0xFFFF) { + if (!(chip->card_wp & MS_CARD)) { + retval = ms_erase_block(chip, phy_blk); + if (retval != STATUS_SUCCESS) + continue; + } + ms_set_unused_block(chip, phy_blk); + continue; + } + + if ((log_blk < ms_start_idx[seg_no]) || + (log_blk >= ms_start_idx[seg_no+1])) { + if (!(chip->card_wp & MS_CARD)) { + retval = ms_erase_block(chip, phy_blk); + if (retval != STATUS_SUCCESS) + continue; + } + ms_set_unused_block(chip, phy_blk); + continue; + } + + if (segment->l2p_table[log_blk - ms_start_idx[seg_no]] == 0xFFFF) { + segment->l2p_table[log_blk - ms_start_idx[seg_no]] = phy_blk; + continue; + } + + us1 = extra[0] & 0x10; + tmp_blk = segment->l2p_table[log_blk - ms_start_idx[seg_no]]; + retval = ms_read_extra_data(chip, tmp_blk, 0, extra, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) + continue; + us2 = extra[0] & 0x10; + + (void)ms_arbitrate_l2p(chip, phy_blk, log_blk-ms_start_idx[seg_no], us1, us2); + continue; + } + + segment->build_flag = 1; + + RTSX_DEBUGP("unused block count: %d\n", segment->unused_blk_cnt); + + /* Logical Address Confirmation Process */ + if (seg_no == ms_card->segment_cnt - 1) { + if (segment->unused_blk_cnt < 2) { + chip->card_wp |= MS_CARD; + } + } else { + if (segment->unused_blk_cnt < 1) { + chip->card_wp |= MS_CARD; + } + } + + if (chip->card_wp & MS_CARD) + return STATUS_SUCCESS; + + for (log_blk = ms_start_idx[seg_no]; log_blk < ms_start_idx[seg_no + 1]; log_blk++) { + if (segment->l2p_table[log_blk-ms_start_idx[seg_no]] == 0xFFFF) { + phy_blk = ms_get_unused_block(chip, seg_no); + if (phy_blk == 0xFFFF) { + chip->card_wp |= MS_CARD; + return STATUS_SUCCESS; + } + retval = ms_init_page(chip, phy_blk, log_blk, 0, 1); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, BUILD_FAIL); + } + segment->l2p_table[log_blk-ms_start_idx[seg_no]] = phy_blk; + if (seg_no == ms_card->segment_cnt - 1) { + if (segment->unused_blk_cnt < 2) { + chip->card_wp |= MS_CARD; + return STATUS_SUCCESS; + } + } else { + if (segment->unused_blk_cnt < 1) { + chip->card_wp |= MS_CARD; + return STATUS_SUCCESS; + } + } + } + } + + /* Make boot block be the first normal block */ + if (seg_no == 0) { + for (log_blk = 0; log_blk < 494; log_blk++) { + tmp_blk = segment->l2p_table[log_blk]; + if (tmp_blk < ms_card->boot_block) { + RTSX_DEBUGP("Boot block is not the first normal block.\n"); + + if (chip->card_wp & MS_CARD) + break; + + phy_blk = ms_get_unused_block(chip, 0); + retval = ms_copy_page(chip, tmp_blk, phy_blk, + log_blk, 0, ms_card->page_off + 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + segment->l2p_table[log_blk] = phy_blk; + + retval = ms_set_bad_block(chip, tmp_blk); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + } + } + + return STATUS_SUCCESS; + +BUILD_FAIL: + segment->build_flag = 0; + if (segment->l2p_table) { + vfree(segment->l2p_table); + segment->l2p_table = NULL; + } + if (segment->free_table) { + vfree(segment->free_table); + segment->free_table = NULL; + } + + return STATUS_FAIL; +} + + +int reset_ms_card(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + memset(ms_card, 0, sizeof(struct ms_info)); + + retval = enable_card_clock(chip, MS_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = select_card(chip, MS_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + ms_card->ms_type = 0; + + retval = reset_ms_pro(chip); + if (retval != STATUS_SUCCESS) { + if (ms_card->check_ms_flow) { + retval = reset_ms(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = ms_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (!CHK_MSPRO(ms_card)) { + /* Build table for the last segment, + * to check if L2P talbe block exist,erasing it + */ + retval = ms_build_l2p_tbl(chip, ms_card->total_block / 512 - 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + RTSX_DEBUGP("ms_card->ms_type = 0x%x\n", ms_card->ms_type); + + return STATUS_SUCCESS; +} + +static int mspro_set_rw_cmd(struct rtsx_chip *chip, u32 start_sec, u16 sec_cnt, u8 cmd) +{ + int retval, i; + u8 data[8]; + + data[0] = cmd; + data[1] = (u8)(sec_cnt >> 8); + data[2] = (u8)sec_cnt; + data[3] = (u8)(start_sec >> 24); + data[4] = (u8)(start_sec >> 16); + data[5] = (u8)(start_sec >> 8); + data[6] = (u8)start_sec; + data[7] = 0; + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, PRO_EX_SET_CMD, 7, WAIT_INT, data, 8); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + + +void mspro_stop_seq_mode(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + RTSX_DEBUGP("--%s--\n", __func__); + + if (ms_card->seq_mode) { + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + return; + + ms_card->seq_mode = 0; + ms_card->total_sec_cnt = 0; + ms_send_cmd(chip, PRO_STOP, WAIT_INT); + + rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); + } +} + +static inline int ms_auto_tune_clock(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + RTSX_DEBUGP("--%s--\n", __func__); + + if (chip->asic_code) { + if (ms_card->ms_clock > 30) { + ms_card->ms_clock -= 20; + } + } else { + if (ms_card->ms_clock == CLK_80) { + ms_card->ms_clock = CLK_60; + } else if (ms_card->ms_clock == CLK_60) { + ms_card->ms_clock = CLK_40; + } + } + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int mspro_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, mode_2k = 0; + u16 count; + u8 val, trans_mode, rw_tpc, rw_cmd; + + ms_set_err_code(chip, MS_NO_ERROR); + + ms_card->cleanup_counter = 0; + + if (CHK_MSHG(ms_card)) { + if ((start_sector % 4) || (sector_cnt % 4)) { + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + rw_tpc = PRO_READ_LONG_DATA; + rw_cmd = PRO_READ_DATA; + } else { + rw_tpc = PRO_WRITE_LONG_DATA; + rw_cmd = PRO_WRITE_DATA; + } + } else { + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + rw_tpc = PRO_READ_QUAD_DATA; + rw_cmd = PRO_READ_2K_DATA; + } else { + rw_tpc = PRO_WRITE_QUAD_DATA; + rw_cmd = PRO_WRITE_2K_DATA; + } + mode_2k = 1; + } + } else { + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + rw_tpc = PRO_READ_LONG_DATA; + rw_cmd = PRO_READ_DATA; + } else { + rw_tpc = PRO_WRITE_LONG_DATA; + rw_cmd = PRO_WRITE_DATA; + } + } + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + trans_mode = MS_TM_AUTO_READ; + } else { + trans_mode = MS_TM_AUTO_WRITE; + } + + RTSX_READ_REG(chip, MS_TRANS_CFG, &val); + + if (ms_card->seq_mode) { + if ((ms_card->pre_dir != srb->sc_data_direction) + || ((ms_card->pre_sec_addr + ms_card->pre_sec_cnt) != start_sector) + || (mode_2k && (ms_card->seq_mode & MODE_512_SEQ)) + || (!mode_2k && (ms_card->seq_mode & MODE_2K_SEQ)) + || !(val & MS_INT_BREQ) + || ((ms_card->total_sec_cnt + sector_cnt) > 0xFE00)) { + ms_card->seq_mode = 0; + ms_card->total_sec_cnt = 0; + if (val & MS_INT_BREQ) { + retval = ms_send_cmd(chip, PRO_STOP, WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); + } + } + } + + if (!ms_card->seq_mode) { + ms_card->total_sec_cnt = 0; + if (sector_cnt >= SEQ_START_CRITERIA) { + if ((ms_card->capacity - start_sector) > 0xFE00) { + count = 0xFE00; + } else { + count = (u16)(ms_card->capacity - start_sector); + } + if (count > sector_cnt) { + if (mode_2k) { + ms_card->seq_mode |= MODE_2K_SEQ; + } else { + ms_card->seq_mode |= MODE_512_SEQ; + } + } + } else { + count = sector_cnt; + } + retval = mspro_set_rw_cmd(chip, start_sector, count, rw_cmd); + if (retval != STATUS_SUCCESS) { + ms_card->seq_mode = 0; + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = ms_transfer_data(chip, trans_mode, rw_tpc, sector_cnt, WAIT_INT, mode_2k, + scsi_sg_count(srb), scsi_sglist(srb), scsi_bufflen(srb)); + if (retval != STATUS_SUCCESS) { + ms_card->seq_mode = 0; + rtsx_read_register(chip, MS_TRANS_CFG, &val); + rtsx_clear_ms_error(chip); + + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + chip->rw_need_retry = 0; + RTSX_DEBUGP("No card exist, exit mspro_rw_multi_sector\n"); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & MS_INT_BREQ) { + ms_send_cmd(chip, PRO_STOP, WAIT_INT); + } + if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) { + RTSX_DEBUGP("MSPro CRC error, tune clock!\n"); + chip->rw_need_retry = 1; + ms_auto_tune_clock(chip); + } + + TRACE_RET(chip, retval); + } + + if (ms_card->seq_mode) { + ms_card->pre_sec_addr = start_sector; + ms_card->pre_sec_cnt = sector_cnt; + ms_card->pre_dir = srb->sc_data_direction; + ms_card->total_sec_cnt += sector_cnt; + } + + return STATUS_SUCCESS; +} + +static int mspro_read_format_progress(struct rtsx_chip *chip, const int short_data_len) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u32 total_progress, cur_progress; + u8 cnt, tmp; + u8 data[8]; + + RTSX_DEBUGP("mspro_read_format_progress, short_data_len = %d\n", short_data_len); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + ms_card->format_status = FORMAT_FAIL; + TRACE_RET(chip, STATUS_FAIL); + } + + retval = rtsx_read_register(chip, MS_TRANS_CFG, &tmp); + if (retval != STATUS_SUCCESS) { + ms_card->format_status = FORMAT_FAIL; + TRACE_RET(chip, STATUS_FAIL); + } + + if (!(tmp & MS_INT_BREQ)) { + if ((tmp & (MS_INT_CED | MS_INT_BREQ | MS_INT_CMDNK | MS_INT_ERR)) == MS_INT_CED) { + ms_card->format_status = FORMAT_SUCCESS; + return STATUS_SUCCESS; + } + ms_card->format_status = FORMAT_FAIL; + TRACE_RET(chip, STATUS_FAIL); + } + + if (short_data_len >= 256) { + cnt = 0; + } else { + cnt = (u8)short_data_len; + } + + retval = rtsx_write_register(chip, MS_CFG, MS_NO_CHECK_INT, MS_NO_CHECK_INT); + if (retval != STATUS_SUCCESS) { + ms_card->format_status = FORMAT_FAIL; + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, cnt, WAIT_INT, data, 8); + if (retval != STATUS_SUCCESS) { + ms_card->format_status = FORMAT_FAIL; + TRACE_RET(chip, STATUS_FAIL); + } + + total_progress = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; + cur_progress = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7]; + + RTSX_DEBUGP("total_progress = %d, cur_progress = %d\n", + total_progress, cur_progress); + + if (total_progress == 0) { + ms_card->progress = 0; + } else { + u64 ulltmp = (u64)cur_progress * (u64)65535; + do_div(ulltmp, total_progress); + ms_card->progress = (u16)ulltmp; + } + RTSX_DEBUGP("progress = %d\n", ms_card->progress); + + for (i = 0; i < 5000; i++) { + retval = rtsx_read_register(chip, MS_TRANS_CFG, &tmp); + if (retval != STATUS_SUCCESS) { + ms_card->format_status = FORMAT_FAIL; + TRACE_RET(chip, STATUS_FAIL); + } + if (tmp & (MS_INT_CED | MS_INT_CMDNK | MS_INT_BREQ | MS_INT_ERR)) { + break; + } + + wait_timeout(1); + } + + retval = rtsx_write_register(chip, MS_CFG, MS_NO_CHECK_INT, 0); + if (retval != STATUS_SUCCESS) { + ms_card->format_status = FORMAT_FAIL; + TRACE_RET(chip, STATUS_FAIL); + } + + if (i == 5000) { + ms_card->format_status = FORMAT_FAIL; + TRACE_RET(chip, STATUS_FAIL); + } + + if (tmp & (MS_INT_CMDNK | MS_INT_ERR)) { + ms_card->format_status = FORMAT_FAIL; + TRACE_RET(chip, STATUS_FAIL); + } + + if (tmp & MS_INT_CED) { + ms_card->format_status = FORMAT_SUCCESS; + ms_card->pro_under_formatting = 0; + } else if (tmp & MS_INT_BREQ) { + ms_card->format_status = FORMAT_IN_PROGRESS; + } else { + ms_card->format_status = FORMAT_FAIL; + ms_card->pro_under_formatting = 0; + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +void mspro_polling_format_status(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int i; + + if (ms_card->pro_under_formatting && (rtsx_get_stat(chip) != RTSX_STAT_SS)) { + rtsx_set_stat(chip, RTSX_STAT_RUN); + + for (i = 0; i < 65535; i++) { + mspro_read_format_progress(chip, MS_SHORT_DATA_LEN); + if (ms_card->format_status != FORMAT_IN_PROGRESS) + break; + } + } + + return; +} + +int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip, int short_data_len, int quick_format) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 buf[8], tmp; + u16 para; + + RTSX_DEBUGP("--%s--\n", __func__); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_set_rw_reg_addr(chip, 0x00, 0x00, Pro_TPCParm, 0x01); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + memset(buf, 0, 2); + switch (short_data_len) { + case 32: + buf[0] = 0; + break; + case 64: + buf[0] = 1; + break; + case 128: + buf[0] = 2; + break; + case 256: + default: + buf[0] = 3; + break; + } + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, PRO_WRITE_REG, 1, NO_WAIT_INT, buf, 2); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (quick_format) { + para = 0x0000; + } else { + para = 0x0001; + } + retval = mspro_set_rw_cmd(chip, 0, para, PRO_FORMAT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_READ_REG(chip, MS_TRANS_CFG, &tmp); + + if (tmp & (MS_INT_CMDNK | MS_INT_ERR)) { + TRACE_RET(chip, STATUS_FAIL); + } + + if ((tmp & (MS_INT_BREQ | MS_INT_CED)) == MS_INT_BREQ) { + ms_card->pro_under_formatting = 1; + ms_card->progress = 0; + ms_card->format_status = FORMAT_IN_PROGRESS; + return STATUS_SUCCESS; + } + + if (tmp & MS_INT_CED) { + ms_card->pro_under_formatting = 0; + ms_card->progress = 0; + ms_card->format_status = FORMAT_SUCCESS; + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_NO_SENSE); + return STATUS_SUCCESS; + } + + TRACE_RET(chip, STATUS_FAIL); +} + + +static int ms_read_multiple_pages(struct rtsx_chip *chip, u16 phy_blk, u16 log_blk, + u8 start_page, u8 end_page, u8 *buf, unsigned int *index, unsigned int *offset) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 extra[MS_EXTRA_SIZE], page_addr, val, trans_cfg, data[6]; + u8 *ptr; + + retval = ms_read_extra_data(chip, phy_blk, start_page, extra, MS_EXTRA_SIZE); + if (retval == STATUS_SUCCESS) { + if ((extra[1] & 0x30) != 0x30) { + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (CHK_MS4BIT(ms_card)) { + data[0] = 0x88; + } else { + data[0] = 0x80; + } + data[1] = 0; + data[2] = (u8)(phy_blk >> 8); + data[3] = (u8)phy_blk; + data[4] = 0; + data[5] = start_page; + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) { + TRACE_RET(chip, STATUS_FAIL); + } + + ms_set_err_code(chip, MS_NO_ERROR); + + retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + ptr = buf; + + for (page_addr = start_page; page_addr < end_page; page_addr++) { + ms_set_err_code(chip, MS_NO_ERROR); + + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + if (val & INT_REG_ERR) { + if (val & INT_REG_BREQ) { + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) { + if (!(chip->card_wp & MS_CARD)) { + reset_ms(chip); + ms_set_page_status(log_blk, setPS_NG, extra, MS_EXTRA_SIZE); + ms_write_extra_data(chip, phy_blk, + page_addr, extra, MS_EXTRA_SIZE); + } + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } else { + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } else { + if (!(val & INT_REG_BREQ)) { + ms_set_err_code(chip, MS_BREQ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (page_addr == (end_page - 1)) { + if (!(val & INT_REG_CED)) { + retval = ms_send_cmd(chip, BLOCK_END, WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + if (!(val & INT_REG_CED)) { + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + + trans_cfg = NO_WAIT_INT; + } else { + trans_cfg = WAIT_INT; + } + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, READ_PAGE_DATA); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, trans_cfg); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); + + trans_dma_enable(DMA_FROM_DEVICE, chip, 512, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, + MS_TRANSFER_START | MS_TM_NORMAL_READ); + rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + + retval = rtsx_transfer_data_partial(chip, MS_CARD, ptr, 512, scsi_sg_count(chip->srb), + index, offset, DMA_FROM_DEVICE, chip->ms_timeout); + if (retval < 0) { + if (retval == -ETIMEDOUT) { + ms_set_err_code(chip, MS_TO_ERROR); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_TIMEDOUT); + } + + retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); + if (retval != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_TO_ERROR); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_TIMEDOUT); + } + if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) { + ms_set_err_code(chip, MS_CRC16_ERROR); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (scsi_sg_count(chip->srb) == 0) + ptr += 512; + } + + return STATUS_SUCCESS; +} + +static int ms_write_multiple_pages(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, + u16 log_blk, u8 start_page, u8 end_page, u8 *buf, + unsigned int *index, unsigned int *offset) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 page_addr, val, data[16]; + u8 *ptr; + + if (!start_page) { + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 7); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (CHK_MS4BIT(ms_card)) { + data[0] = 0x88; + } else { + data[0] = 0x80; + } + data[1] = 0; + data[2] = (u8)(old_blk >> 8); + data[3] = (u8)old_blk; + data[4] = 0x80; + data[5] = 0; + data[6] = 0xEF; + data[7] = 0xFF; + + retval = ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT, data, 8); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT, 1, NO_WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, (6 + MS_EXTRA_SIZE)); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + ms_set_err_code(chip, MS_NO_ERROR); + + if (CHK_MS4BIT(ms_card)) { + data[0] = 0x88; + } else { + data[0] = 0x80; + } + data[1] = 0; + data[2] = (u8)(new_blk >> 8); + data[3] = (u8)new_blk; + if ((end_page - start_page) == 1) { + data[4] = 0x20; + } else { + data[4] = 0; + } + data[5] = start_page; + data[6] = 0xF8; + data[7] = 0xFF; + data[8] = (u8)(log_blk >> 8); + data[9] = (u8)log_blk; + + for (i = 0x0A; i < 0x10; i++) { + data[i] = 0xFF; + } + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, WRITE_REG, 6 + MS_EXTRA_SIZE, NO_WAIT_INT, data, 16); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) { + TRACE_RET(chip, STATUS_FAIL); + } + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + ptr = buf; + for (page_addr = start_page; page_addr < end_page; page_addr++) { + ms_set_err_code(chip, MS_NO_ERROR); + + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + if (val & INT_REG_ERR) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + if (!(val & INT_REG_BREQ)) { + ms_set_err_code(chip, MS_BREQ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + + udelay(30); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, WRITE_PAGE_DATA); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, WAIT_INT); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); + + trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, + MS_TRANSFER_START | MS_TM_NORMAL_WRITE); + rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + + retval = rtsx_transfer_data_partial(chip, MS_CARD, ptr, 512, scsi_sg_count(chip->srb), + index, offset, DMA_TO_DEVICE, chip->ms_timeout); + if (retval < 0) { + ms_set_err_code(chip, MS_TO_ERROR); + rtsx_clear_ms_error(chip); + + if (retval == -ETIMEDOUT) { + TRACE_RET(chip, STATUS_TIMEDOUT); + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if ((end_page - start_page) == 1) { + if (!(val & INT_REG_CED)) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } else { + if (page_addr == (end_page - 1)) { + if (!(val & INT_REG_CED)) { + retval = ms_send_cmd(chip, BLOCK_END, WAIT_INT); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + if ((page_addr == (end_page - 1)) || (page_addr == ms_card->page_off)) { + if (!(val & INT_REG_CED)) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + if (scsi_sg_count(chip->srb) == 0) + ptr += 512; + } + + return STATUS_SUCCESS; +} + + +static int ms_finish_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, + u16 log_blk, u8 page_off) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, seg_no; + + retval = ms_copy_page(chip, old_blk, new_blk, log_blk, + page_off, ms_card->page_off + 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + seg_no = old_blk >> 9; + + if (MS_TST_BAD_BLOCK_FLG(ms_card)) { + MS_CLR_BAD_BLOCK_FLG(ms_card); + ms_set_bad_block(chip, old_blk); + } else { + retval = ms_erase_block(chip, old_blk); + if (retval == STATUS_SUCCESS) { + ms_set_unused_block(chip, old_blk); + } + } + + ms_set_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no], new_blk); + + return STATUS_SUCCESS; +} + +static int ms_prepare_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, + u16 log_blk, u8 start_page) +{ + int retval; + + if (start_page) { + retval = ms_copy_page(chip, old_blk, new_blk, log_blk, 0, start_page); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + +#ifdef MS_DELAY_WRITE +int ms_delay_write(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct ms_delay_write_tag *delay_write = &(ms_card->delay_write); + int retval; + + if (delay_write->delay_write_flag) { + retval = ms_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + delay_write->delay_write_flag = 0; + retval = ms_finish_write(chip, + delay_write->old_phyblock, delay_write->new_phyblock, + delay_write->logblock, delay_write->pageoff); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} +#endif + +static inline void ms_rw_fail(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + } else { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + } +} + +static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt) +{ + struct ms_info *ms_card = &(chip->ms_card); + unsigned int lun = SCSI_LUN(srb); + int retval, seg_no; + unsigned int index = 0, offset = 0; + u16 old_blk = 0, new_blk = 0, log_blk, total_sec_cnt = sector_cnt; + u8 start_page, end_page = 0, page_cnt; + u8 *ptr; +#ifdef MS_DELAY_WRITE + struct ms_delay_write_tag *delay_write = &(ms_card->delay_write); +#endif + + ms_set_err_code(chip, MS_NO_ERROR); + + ms_card->cleanup_counter = 0; + + ptr = (u8 *)scsi_sglist(srb); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + ms_rw_fail(srb, chip); + TRACE_RET(chip, STATUS_FAIL); + } + + log_blk = (u16)(start_sector >> ms_card->block_shift); + start_page = (u8)(start_sector & ms_card->page_off); + + for (seg_no = 0; seg_no < sizeof(ms_start_idx)/2; seg_no++) { + if (log_blk < ms_start_idx[seg_no+1]) + break; + } + + if (ms_card->segment[seg_no].build_flag == 0) { + retval = ms_build_l2p_tbl(chip, seg_no); + if (retval != STATUS_SUCCESS) { + chip->card_fail |= MS_CARD; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (srb->sc_data_direction == DMA_TO_DEVICE) { +#ifdef MS_DELAY_WRITE + if (delay_write->delay_write_flag && + (delay_write->logblock == log_blk) && + (start_page > delay_write->pageoff)) { + delay_write->delay_write_flag = 0; + retval = ms_copy_page(chip, + delay_write->old_phyblock, + delay_write->new_phyblock, log_blk, + delay_write->pageoff, start_page); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + old_blk = delay_write->old_phyblock; + new_blk = delay_write->new_phyblock; + } else if (delay_write->delay_write_flag && + (delay_write->logblock == log_blk) && + (start_page == delay_write->pageoff)) { + delay_write->delay_write_flag = 0; + old_blk = delay_write->old_phyblock; + new_blk = delay_write->new_phyblock; + } else { + retval = ms_delay_write(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + old_blk = ms_get_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no]); + new_blk = ms_get_unused_block(chip, seg_no); + if ((old_blk == 0xFFFF) || (new_blk == 0xFFFF)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_prepare_write(chip, old_blk, new_blk, log_blk, start_page); + if (retval != STATUS_SUCCESS) { + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } +#ifdef MS_DELAY_WRITE + } +#endif + } else { +#ifdef MS_DELAY_WRITE + retval = ms_delay_write(chip); + if (retval != STATUS_SUCCESS) { + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + old_blk = ms_get_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no]); + if (old_blk == 0xFFFF) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + RTSX_DEBUGP("seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n", seg_no, old_blk, new_blk); + + while (total_sec_cnt) { + if ((start_page + total_sec_cnt) > (ms_card->page_off + 1)) { + end_page = ms_card->page_off + 1; + } else { + end_page = start_page + (u8)total_sec_cnt; + } + page_cnt = end_page - start_page; + + RTSX_DEBUGP("start_page = %d, end_page = %d, page_cnt = %d\n", + start_page, end_page, page_cnt); + + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + retval = ms_read_multiple_pages(chip, + old_blk, log_blk, start_page, end_page, + ptr, &index, &offset); + } else { + retval = ms_write_multiple_pages(chip, old_blk, + new_blk, log_blk, start_page, end_page, + ptr, &index, &offset); + } + + if (retval != STATUS_SUCCESS) { + toggle_gpio(chip, 1); + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + ms_rw_fail(srb, chip); + TRACE_RET(chip, STATUS_FAIL); + } + + if (srb->sc_data_direction == DMA_TO_DEVICE) { + if (end_page == (ms_card->page_off + 1)) { + retval = ms_erase_block(chip, old_blk); + if (retval == STATUS_SUCCESS) { + ms_set_unused_block(chip, old_blk); + } + ms_set_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no], new_blk); + } + } + + total_sec_cnt -= page_cnt; + if (scsi_sg_count(srb) == 0) + ptr += page_cnt * 512; + + if (total_sec_cnt == 0) + break; + + log_blk++; + + for (seg_no = 0; seg_no < sizeof(ms_start_idx)/2; seg_no++) { + if (log_blk < ms_start_idx[seg_no+1]) + break; + } + + if (ms_card->segment[seg_no].build_flag == 0) { + retval = ms_build_l2p_tbl(chip, seg_no); + if (retval != STATUS_SUCCESS) { + chip->card_fail |= MS_CARD; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + } + + old_blk = ms_get_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no]); + if (old_blk == 0xFFFF) { + ms_rw_fail(srb, chip); + TRACE_RET(chip, STATUS_FAIL); + } + + if (srb->sc_data_direction == DMA_TO_DEVICE) { + new_blk = ms_get_unused_block(chip, seg_no); + if (new_blk == 0xFFFF) { + ms_rw_fail(srb, chip); + TRACE_RET(chip, STATUS_FAIL); + } + } + + RTSX_DEBUGP("seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n", seg_no, old_blk, new_blk); + + start_page = 0; + } + + if (srb->sc_data_direction == DMA_TO_DEVICE) { + if (end_page < (ms_card->page_off + 1)) { +#ifdef MS_DELAY_WRITE + delay_write->delay_write_flag = 1; + delay_write->old_phyblock = old_blk; + delay_write->new_phyblock = new_blk; + delay_write->logblock = log_blk; + delay_write->pageoff = end_page; +#else + retval = ms_finish_write(chip, old_blk, new_blk, log_blk, end_page); + if (retval != STATUS_SUCCESS) { + if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + + ms_rw_fail(srb, chip); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + } + } + + scsi_set_resid(srb, 0); + + return STATUS_SUCCESS; +} + +int ms_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + if (CHK_MSPRO(ms_card)) { + retval = mspro_rw_multi_sector(srb, chip, start_sector, sector_cnt); + } else { + retval = ms_rw_multi_sector(srb, chip, start_sector, sector_cnt); + } + + return retval; +} + + +void ms_free_l2p_tbl(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int i = 0; + + if (ms_card->segment != NULL) { + for (i = 0; i < ms_card->segment_cnt; i++) { + if (ms_card->segment[i].l2p_table != NULL) { + vfree(ms_card->segment[i].l2p_table); + ms_card->segment[i].l2p_table = NULL; + } + if (ms_card->segment[i].free_table != NULL) { + vfree(ms_card->segment[i].free_table); + ms_card->segment[i].free_table = NULL; + } + } + vfree(ms_card->segment); + ms_card->segment = NULL; + } +} + +#ifdef SUPPORT_MAGIC_GATE + +#ifdef READ_BYTES_WAIT_INT +int ms_poll_int(struct rtsx_chip *chip) +{ + int retval; + u8 val; + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANS_CFG, MS_INT_CED, MS_INT_CED); + + retval = rtsx_send_cmd(chip, MS_CARD, 5000); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + val = *rtsx_get_cmd_data(chip); + if (val & MS_INT_ERR) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} +#endif + +#ifdef MS_SAMPLE_INT_ERR +static int check_ms_err(struct rtsx_chip *chip) +{ + int retval; + u8 val; + + retval = rtsx_read_register(chip, MS_TRANSFER, &val); + if (retval != STATUS_SUCCESS) + return 1; + if (val & MS_TRANSFER_ERR) + return 1; + + retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); + if (retval != STATUS_SUCCESS) + return 1; + + if (val & (MS_INT_ERR | MS_INT_CMDNK)) + return 1; + + return 0; +} +#else +static int check_ms_err(struct rtsx_chip *chip) +{ + int retval; + u8 val; + + retval = rtsx_read_register(chip, MS_TRANSFER, &val); + if (retval != STATUS_SUCCESS) + return 1; + if (val & MS_TRANSFER_ERR) + return 1; + + return 0; +} +#endif + +static int mg_send_ex_cmd(struct rtsx_chip *chip, u8 cmd, u8 entry_num) +{ + int retval, i; + u8 data[8]; + + data[0] = cmd; + data[1] = 0; + data[2] = 0; + data[3] = 0; + data[4] = 0; + data[5] = 0; + data[6] = entry_num; + data[7] = 0; + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_write_bytes(chip, PRO_EX_SET_CMD, 7, WAIT_INT, data, 8); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (check_ms_err(chip)) { + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int mg_set_tpc_para_sub(struct rtsx_chip *chip, int type, u8 mg_entry_num) +{ + int retval; + u8 buf[6]; + + RTSX_DEBUGP("--%s--\n", __func__); + + if (type == 0) { + retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_TPCParm, 1); + } else { + retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6); + } + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + buf[0] = 0; + buf[1] = 0; + if (type == 1) { + buf[2] = 0; + buf[3] = 0; + buf[4] = 0; + buf[5] = mg_entry_num; + } + retval = ms_write_bytes(chip, PRO_WRITE_REG, (type == 0) ? 1 : 6, NO_WAIT_INT, buf, 6); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + int i; + unsigned int lun = SCSI_LUN(srb); + u8 buf1[32], buf2[12]; + + RTSX_DEBUGP("--%s--\n", __func__); + + if (scsi_bufflen(srb) < 12) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, STATUS_FAIL); + } + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = mg_send_ex_cmd(chip, MG_SET_LID, 0); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + TRACE_RET(chip, STATUS_FAIL); + } + + memset(buf1, 0, 32); + rtsx_stor_get_xfer_buf(buf2, min(12, (int)scsi_bufflen(srb)), srb); + for (i = 0; i < 8; i++) { + buf1[8+i] = buf2[4+i]; + } + retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf1, 32); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + TRACE_RET(chip, STATUS_FAIL); + } + if (check_ms_err(chip)) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval = STATUS_FAIL; + int bufflen; + unsigned int lun = SCSI_LUN(srb); + u8 *buf = NULL; + + RTSX_DEBUGP("--%s--\n", __func__); + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + buf = (u8 *)rtsx_alloc_dma_buf(chip, 1540, GFP_KERNEL); + if (!buf) { + TRACE_RET(chip, STATUS_ERROR); + } + + buf[0] = 0x04; + buf[1] = 0x1A; + buf[2] = 0x00; + buf[3] = 0x00; + + retval = mg_send_ex_cmd(chip, MG_GET_LEKB, 0); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_GOTO(chip, GetEKBFinish); + } + + retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA, + 3, WAIT_INT, 0, 0, buf + 4, 1536); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + rtsx_clear_ms_error(chip); + TRACE_GOTO(chip, GetEKBFinish); + } + if (check_ms_err(chip)) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + bufflen = min(1052, (int)scsi_bufflen(srb)); + rtsx_stor_set_xfer_buf(buf, bufflen, srb); + +GetEKBFinish: + if (buf) { + rtsx_free_dma_buf(chip, buf); + } + return retval; +} + +int mg_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + int bufflen; + int i; + unsigned int lun = SCSI_LUN(srb); + u8 buf[32]; + + RTSX_DEBUGP("--%s--\n", __func__); + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = mg_send_ex_cmd(chip, MG_GET_ID, 0); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, buf, 32); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, STATUS_FAIL); + } + if (check_ms_err(chip)) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + memcpy(ms_card->magic_gate_id, buf, 16); + +#ifdef READ_BYTES_WAIT_INT + retval = ms_poll_int(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + + retval = mg_send_ex_cmd(chip, MG_SET_RD, 0); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, STATUS_FAIL); + } + + bufflen = min(12, (int)scsi_bufflen(srb)); + rtsx_stor_get_xfer_buf(buf, bufflen, srb); + + for (i = 0; i < 8; i++) { + buf[i] = buf[4+i]; + } + for (i = 0; i < 24; i++) { + buf[8+i] = 0; + } + retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, + 32, WAIT_INT, buf, 32); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, STATUS_FAIL); + } + if (check_ms_err(chip)) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + ms_card->mg_auth = 0; + + return STATUS_SUCCESS; +} + +int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + int bufflen; + unsigned int lun = SCSI_LUN(srb); + u8 buf1[32], buf2[36]; + + RTSX_DEBUGP("--%s--\n", __func__); + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = mg_send_ex_cmd(chip, MG_MAKE_RMS, 0); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, buf1, 32); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_RET(chip, STATUS_FAIL); + } + if (check_ms_err(chip)) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + buf2[0] = 0x00; + buf2[1] = 0x22; + buf2[2] = 0x00; + buf2[3] = 0x00; + + memcpy(buf2 + 4, ms_card->magic_gate_id, 16); + memcpy(buf2 + 20, buf1, 16); + + bufflen = min(36, (int)scsi_bufflen(srb)); + rtsx_stor_set_xfer_buf(buf2, bufflen, srb); + +#ifdef READ_BYTES_WAIT_INT + retval = ms_poll_int(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + + return STATUS_SUCCESS; +} + +int mg_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + int i; + int bufflen; + unsigned int lun = SCSI_LUN(srb); + u8 buf[32]; + + RTSX_DEBUGP("--%s--\n", __func__); + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = mg_send_ex_cmd(chip, MG_MAKE_KSE, 0); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_RET(chip, STATUS_FAIL); + } + + bufflen = min(12, (int)scsi_bufflen(srb)); + rtsx_stor_get_xfer_buf(buf, bufflen, srb); + + for (i = 0; i < 8; i++) { + buf[i] = buf[4+i]; + } + for (i = 0; i < 24; i++) { + buf[8+i] = 0; + } + retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf, 32); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_RET(chip, STATUS_FAIL); + } + if (check_ms_err(chip)) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + ms_card->mg_auth = 1; + + return STATUS_SUCCESS; +} + +int mg_get_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + int bufflen; + unsigned int lun = SCSI_LUN(srb); + u8 *buf = NULL; + + RTSX_DEBUGP("--%s--\n", __func__); + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + buf = (u8 *)rtsx_alloc_dma_buf(chip, 1028, GFP_KERNEL); + if (!buf) { + TRACE_RET(chip, STATUS_ERROR); + } + + buf[0] = 0x04; + buf[1] = 0x02; + buf[2] = 0x00; + buf[3] = 0x00; + + retval = mg_send_ex_cmd(chip, MG_GET_IBD, ms_card->mg_entry_num); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_GOTO(chip, GetICVFinish); + } + + retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA, + 2, WAIT_INT, 0, 0, buf + 4, 1024); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + rtsx_clear_ms_error(chip); + TRACE_GOTO(chip, GetICVFinish); + } + if (check_ms_err(chip)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + rtsx_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + bufflen = min(1028, (int)scsi_bufflen(srb)); + rtsx_stor_set_xfer_buf(buf, bufflen, srb); + +GetICVFinish: + if (buf) { + rtsx_free_dma_buf(chip, buf); + } + return retval; +} + +int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + int bufflen; +#ifdef MG_SET_ICV_SLOW + int i; +#endif + unsigned int lun = SCSI_LUN(srb); + u8 *buf = NULL; + + RTSX_DEBUGP("--%s--\n", __func__); + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + buf = (u8 *)rtsx_alloc_dma_buf(chip, 1028, GFP_KERNEL); + if (!buf) { + TRACE_RET(chip, STATUS_ERROR); + } + + bufflen = min(1028, (int)scsi_bufflen(srb)); + rtsx_stor_get_xfer_buf(buf, bufflen, srb); + + retval = mg_send_ex_cmd(chip, MG_SET_IBD, ms_card->mg_entry_num); + if (retval != STATUS_SUCCESS) { + if (ms_card->mg_auth == 0) { + if ((buf[5] & 0xC0) != 0) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + } else { + set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); + } + } else { + set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); + } + TRACE_GOTO(chip, SetICVFinish); + } + +#ifdef MG_SET_ICV_SLOW + for (i = 0; i < 2; i++) { + udelay(50); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, PRO_WRITE_LONG_DATA); + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, WAIT_INT); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); + + trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, + MS_TRANSFER_START | MS_TM_NORMAL_WRITE); + rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + + retval = rtsx_transfer_data(chip, MS_CARD, buf + 4 + i*512, 512, 0, DMA_TO_DEVICE, 3000); + if ((retval < 0) || check_ms_err(chip)) { + rtsx_clear_ms_error(chip); + if (ms_card->mg_auth == 0) { + if ((buf[5] & 0xC0) != 0) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + } else { + set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); + } + } else { + set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); + } + retval = STATUS_FAIL; + TRACE_GOTO(chip, SetICVFinish); + } + } +#else + retval = ms_transfer_data(chip, MS_TM_AUTO_WRITE, PRO_WRITE_LONG_DATA, + 2, WAIT_INT, 0, 0, buf + 4, 1024); + if ((retval != STATUS_SUCCESS) || check_ms_err(chip) { + rtsx_clear_ms_error(chip); + if (ms_card->mg_auth == 0) { + if ((buf[5] & 0xC0) != 0) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + } else { + set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); + } + } else { + set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); + } + TRACE_GOTO(chip, SetICVFinish); + } +#endif + +SetICVFinish: + if (buf) { + rtsx_free_dma_buf(chip, buf); + } + return retval; +} + +#endif /* SUPPORT_MAGIC_GATE */ + +void ms_cleanup_work(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + + if (CHK_MSPRO(ms_card)) { + if (ms_card->seq_mode) { + RTSX_DEBUGP("MS Pro: stop transmission\n"); + mspro_stop_seq_mode(chip); + ms_card->cleanup_counter = 0; + } + if (CHK_MSHG(ms_card)) { + rtsx_write_register(chip, MS_CFG, + MS_2K_SECTOR_MODE, 0x00); + } + } +#ifdef MS_DELAY_WRITE + else if ((!CHK_MSPRO(ms_card)) && ms_card->delay_write.delay_write_flag) { + RTSX_DEBUGP("MS: delay write\n"); + ms_delay_write(chip); + ms_card->cleanup_counter = 0; + } +#endif +} + +int ms_power_off_card3v3(struct rtsx_chip *chip) +{ + int retval; + + retval = disable_card_clock(chip, MS_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + if (chip->asic_code) { + retval = ms_pull_ctl_disable(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + RTSX_WRITE_REG(chip, FPGA_PULL_CTL, + FPGA_MS_PULL_CTL_BIT | 0x20, FPGA_MS_PULL_CTL_BIT); + } + RTSX_WRITE_REG(chip, CARD_OE, MS_OUTPUT_EN, 0); + if (!chip->ft2_fast_mode) { + retval = card_power_off(chip, MS_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + +int release_ms_card(struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + RTSX_DEBUGP("release_ms_card\n"); + +#ifdef MS_DELAY_WRITE + ms_card->delay_write.delay_write_flag = 0; +#endif + ms_card->pro_under_formatting = 0; + + chip->card_ready &= ~MS_CARD; + chip->card_fail &= ~MS_CARD; + chip->card_wp &= ~MS_CARD; + + ms_free_l2p_tbl(chip); + + memset(ms_card->raw_sys_info, 0, 96); +#ifdef SUPPORT_PCGL_1P18 + memset(ms_card->raw_model_name, 0, 48); +#endif + + retval = ms_power_off_card3v3(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + diff --git a/drivers/staging/rts_pstor/ms.h b/drivers/staging/rts_pstor/ms.h new file mode 100644 index 000000000000..537019876139 --- /dev/null +++ b/drivers/staging/rts_pstor/ms.h @@ -0,0 +1,225 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __REALTEK_RTSX_MS_H +#define __REALTEK_RTSX_MS_H + +#define MS_DELAY_WRITE + +#define MS_MAX_RETRY_COUNT 3 + +#define MS_EXTRA_SIZE 0x9 + +#define WRT_PRTCT 0x01 + +/* Error Code */ +#define MS_NO_ERROR 0x00 +#define MS_CRC16_ERROR 0x80 +#define MS_TO_ERROR 0x40 +#define MS_NO_CARD 0x20 +#define MS_NO_MEMORY 0x10 +#define MS_CMD_NK 0x08 +#define MS_FLASH_READ_ERROR 0x04 +#define MS_FLASH_WRITE_ERROR 0x02 +#define MS_BREQ_ERROR 0x01 +#define MS_NOT_FOUND 0x03 + +/* Transfer Protocol Command */ +#define READ_PAGE_DATA 0x02 +#define READ_REG 0x04 +#define GET_INT 0x07 +#define WRITE_PAGE_DATA 0x0D +#define WRITE_REG 0x0B +#define SET_RW_REG_ADRS 0x08 +#define SET_CMD 0x0E + +#define PRO_READ_LONG_DATA 0x02 +#define PRO_READ_SHORT_DATA 0x03 +#define PRO_READ_REG 0x04 +#define PRO_READ_QUAD_DATA 0x05 +#define PRO_GET_INT 0x07 +#define PRO_WRITE_LONG_DATA 0x0D +#define PRO_WRITE_SHORT_DATA 0x0C +#define PRO_WRITE_QUAD_DATA 0x0A +#define PRO_WRITE_REG 0x0B +#define PRO_SET_RW_REG_ADRS 0x08 +#define PRO_SET_CMD 0x0E +#define PRO_EX_SET_CMD 0x09 + +#ifdef SUPPORT_MAGIC_GATE + +#define MG_GET_ID 0x40 +#define MG_SET_LID 0x41 +#define MG_GET_LEKB 0x42 +#define MG_SET_RD 0x43 +#define MG_MAKE_RMS 0x44 +#define MG_MAKE_KSE 0x45 +#define MG_SET_IBD 0x46 +#define MG_GET_IBD 0x47 + +#endif + +#ifdef XC_POWERCLASS +#define XC_CHG_POWER 0x16 +#endif + +#define BLOCK_READ 0xAA +#define BLOCK_WRITE 0x55 +#define BLOCK_END 0x33 +#define BLOCK_ERASE 0x99 +#define FLASH_STOP 0xCC + +#define SLEEP 0x5A +#define CLEAR_BUF 0xC3 +#define MS_RESET 0x3C + +#define PRO_READ_DATA 0x20 +#define PRO_WRITE_DATA 0x21 +#define PRO_READ_ATRB 0x24 +#define PRO_STOP 0x25 +#define PRO_ERASE 0x26 +#define PRO_READ_2K_DATA 0x27 +#define PRO_WRITE_2K_DATA 0x28 + +#define PRO_FORMAT 0x10 +#define PRO_SLEEP 0x11 + +#define IntReg 0x01 +#define StatusReg0 0x02 +#define StatusReg1 0x03 + +#define SystemParm 0x10 +#define BlockAdrs 0x11 +#define CMDParm 0x14 +#define PageAdrs 0x15 + +#define OverwriteFlag 0x16 +#define ManagemenFlag 0x17 +#define LogicalAdrs 0x18 +#define ReserveArea 0x1A + +#define Pro_IntReg 0x01 +#define Pro_StatusReg 0x02 +#define Pro_TypeReg 0x04 +#define Pro_IFModeReg 0x05 +#define Pro_CatagoryReg 0x06 +#define Pro_ClassReg 0x07 + + +#define Pro_SystemParm 0x10 +#define Pro_DataCount1 0x11 +#define Pro_DataCount0 0x12 +#define Pro_DataAddr3 0x13 +#define Pro_DataAddr2 0x14 +#define Pro_DataAddr1 0x15 +#define Pro_DataAddr0 0x16 + +#define Pro_TPCParm 0x17 +#define Pro_CMDParm 0x18 + +#define INT_REG_CED 0x80 +#define INT_REG_ERR 0x40 +#define INT_REG_BREQ 0x20 +#define INT_REG_CMDNK 0x01 + +#define BLOCK_BOOT 0xC0 +#define BLOCK_OK 0x80 +#define PAGE_OK 0x60 +#define DATA_COMPL 0x10 + +#define NOT_BOOT_BLOCK 0x4 +#define NOT_TRANSLATION_TABLE 0x8 + +#define HEADER_ID0 PPBUF_BASE2 +#define HEADER_ID1 (PPBUF_BASE2 + 1) +#define DISABLED_BLOCK0 (PPBUF_BASE2 + 0x170 + 4) +#define DISABLED_BLOCK1 (PPBUF_BASE2 + 0x170 + 5) +#define DISABLED_BLOCK2 (PPBUF_BASE2 + 0x170 + 6) +#define DISABLED_BLOCK3 (PPBUF_BASE2 + 0x170 + 7) +#define BLOCK_SIZE_0 (PPBUF_BASE2 + 0x1a0 + 2) +#define BLOCK_SIZE_1 (PPBUF_BASE2 + 0x1a0 + 3) +#define BLOCK_COUNT_0 (PPBUF_BASE2 + 0x1a0 + 4) +#define BLOCK_COUNT_1 (PPBUF_BASE2 + 0x1a0 + 5) +#define EBLOCK_COUNT_0 (PPBUF_BASE2 + 0x1a0 + 6) +#define EBLOCK_COUNT_1 (PPBUF_BASE2 + 0x1a0 + 7) +#define PAGE_SIZE_0 (PPBUF_BASE2 + 0x1a0 + 8) +#define PAGE_SIZE_1 (PPBUF_BASE2 + 0x1a0 + 9) + +#define MS_Device_Type (PPBUF_BASE2 + 0x1D8) + +#define MS_4bit_Support (PPBUF_BASE2 + 0x1D3) + +#define setPS_NG 1 +#define setPS_Error 0 + +#define PARALLEL_8BIT_IF 0x40 +#define PARALLEL_4BIT_IF 0x00 +#define SERIAL_IF 0x80 + +#define BUF_FULL 0x10 +#define BUF_EMPTY 0x20 + +#define MEDIA_BUSY 0x80 +#define FLASH_BUSY 0x40 +#define DATA_ERROR 0x20 +#define STS_UCDT 0x10 +#define EXTRA_ERROR 0x08 +#define STS_UCEX 0x04 +#define FLAG_ERROR 0x02 +#define STS_UCFG 0x01 + +#define MS_SHORT_DATA_LEN 32 + +#define FORMAT_SUCCESS 0 +#define FORMAT_FAIL 1 +#define FORMAT_IN_PROGRESS 2 + +#define MS_SET_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag |= 0x80) +#define MS_CLR_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag &= 0x7F) +#define MS_TST_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag & 0x80) + +void mspro_polling_format_status(struct rtsx_chip *chip); + +void mspro_stop_seq_mode(struct rtsx_chip *chip); +int reset_ms_card(struct rtsx_chip *chip); +int ms_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt); +int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip, int short_data_len, int quick_format); +void ms_free_l2p_tbl(struct rtsx_chip *chip); +void ms_cleanup_work(struct rtsx_chip *chip); +int ms_power_off_card3v3(struct rtsx_chip *chip); +int release_ms_card(struct rtsx_chip *chip); +#ifdef MS_DELAY_WRITE +int ms_delay_write(struct rtsx_chip *chip); +#endif + +#ifdef SUPPORT_MAGIC_GATE +int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int mg_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int mg_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int mg_get_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip); +#endif + +#endif /* __REALTEK_RTSX_MS_H */ diff --git a/drivers/staging/rts_pstor/rtsx.c b/drivers/staging/rts_pstor/rtsx.c new file mode 100644 index 000000000000..9864b1a47116 --- /dev/null +++ b/drivers/staging/rts_pstor/rtsx.c @@ -0,0 +1,1124 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include +#include +#include +#include + +#include "rtsx.h" +#include "rtsx_chip.h" +#include "rtsx_transport.h" +#include "rtsx_scsi.h" +#include "rtsx_card.h" +#include "general.h" + +#include "ms.h" +#include "sd.h" +#include "xd.h" + +#define DRIVER_VERSION "v1.10" + +MODULE_DESCRIPTION("Realtek PCI-Express card reader driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRIVER_VERSION); + +static unsigned int delay_use = 1; +module_param(delay_use, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device"); + +static int ss_en; +module_param(ss_en, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(ss_en, "enable selective suspend"); + +static int ss_interval = 50; +module_param(ss_interval, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(ss_interval, "Interval to enter ss state in seconds"); + +static int auto_delink_en; +module_param(auto_delink_en, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(auto_delink_en, "enable auto delink"); + +static unsigned char aspm_l0s_l1_en; +module_param(aspm_l0s_l1_en, byte, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(aspm_l0s_l1_en, "enable device aspm"); + +static int msi_en; +module_param(msi_en, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(msi_en, "enable msi"); + +/* These are used to make sure the module doesn't unload before all the + * threads have exited. + */ +static atomic_t total_threads = ATOMIC_INIT(0); +static DECLARE_COMPLETION(threads_gone); + +static irqreturn_t rtsx_interrupt(int irq, void *dev_id); + +/*********************************************************************** + * Host functions + ***********************************************************************/ + +static const char *host_info(struct Scsi_Host *host) +{ + return "SCSI emulation for PCI-Express Mass Storage devices"; +} + +static int slave_alloc (struct scsi_device *sdev) +{ + /* + * Set the INQUIRY transfer length to 36. We don't use any of + * the extra data and many devices choke if asked for more or + * less than 36 bytes. + */ + sdev->inquiry_len = 36; + return 0; +} + +static int slave_configure(struct scsi_device *sdev) +{ + /* Scatter-gather buffers (all but the last) must have a length + * divisible by the bulk maxpacket size. Otherwise a data packet + * would end up being short, causing a premature end to the data + * transfer. Since high-speed bulk pipes have a maxpacket size + * of 512, we'll use that as the scsi device queue's DMA alignment + * mask. Guaranteeing proper alignment of the first buffer will + * have the desired effect because, except at the beginning and + * the end, scatter-gather buffers follow page boundaries. */ + blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); + + /* Set the SCSI level to at least 2. We'll leave it at 3 if that's + * what is originally reported. We need this to avoid confusing + * the SCSI layer with devices that report 0 or 1, but need 10-byte + * commands (ala ATAPI devices behind certain bridges, or devices + * which simply have broken INQUIRY data). + * + * NOTE: This means /dev/sg programs (ala cdrecord) will get the + * actual information. This seems to be the preference for + * programs like that. + * + * NOTE: This also means that /proc/scsi/scsi and sysfs may report + * the actual value or the modified one, depending on where the + * data comes from. + */ + if (sdev->scsi_level < SCSI_2) + sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2; + + return 0; +} + + +/*********************************************************************** + * /proc/scsi/ functions + ***********************************************************************/ + +/* we use this macro to help us write into the buffer */ +#undef SPRINTF +#define SPRINTF(args...) \ + do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0) + +static int proc_info (struct Scsi_Host *host, char *buffer, + char **start, off_t offset, int length, int inout) +{ + char *pos = buffer; + + /* if someone is sending us data, just throw it away */ + if (inout) + return length; + + /* print the controller name */ + SPRINTF(" Host scsi%d: %s\n", host->host_no, CR_DRIVER_NAME); + + /* print product, vendor, and driver version strings */ + SPRINTF(" Vendor: Realtek Corp.\n"); + SPRINTF(" Product: PCIE Card Reader\n"); + SPRINTF(" Version: %s\n", DRIVER_VERSION); + + /* + * Calculate start of next buffer, and return value. + */ + *start = buffer + offset; + + if ((pos - buffer) < offset) + return 0; + else if ((pos - buffer - offset) < length) + return pos - buffer - offset; + else + return length; +} + +/* queue a command */ +/* This is always called with scsi_lock(host) held */ +static int queuecommand_lck(struct scsi_cmnd *srb, + void (*done)(struct scsi_cmnd *)) +{ + struct rtsx_dev *dev = host_to_rtsx(srb->device->host); + struct rtsx_chip *chip = dev->chip; + + /* check for state-transition errors */ + if (chip->srb != NULL) { + printk(KERN_ERR "Error in %s: chip->srb = %p\n", + __func__, chip->srb); + return SCSI_MLQUEUE_HOST_BUSY; + } + + /* fail the command if we are disconnecting */ + if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { + printk(KERN_INFO "Fail command during disconnect\n"); + srb->result = DID_NO_CONNECT << 16; + done(srb); + return 0; + } + + /* enqueue the command and wake up the control thread */ + srb->scsi_done = done; + chip->srb = srb; + up(&(dev->sema)); + + return 0; +} + +static DEF_SCSI_QCMD(queuecommand) + +/*********************************************************************** + * Error handling functions + ***********************************************************************/ + +/* Command timeout and abort */ +static int command_abort(struct scsi_cmnd *srb) +{ + struct Scsi_Host *host = srb->device->host; + struct rtsx_dev *dev = host_to_rtsx(host); + struct rtsx_chip *chip = dev->chip; + + printk(KERN_INFO "%s called\n", __func__); + + scsi_lock(host); + + /* Is this command still active? */ + if (chip->srb != srb) { + scsi_unlock(host); + printk(KERN_INFO "-- nothing to abort\n"); + return FAILED; + } + + rtsx_set_stat(chip, RTSX_STAT_ABORT); + + scsi_unlock(host); + + /* Wait for the aborted command to finish */ + wait_for_completion(&dev->notify); + + return SUCCESS; +} + +/* This invokes the transport reset mechanism to reset the state of the + * device */ +static int device_reset(struct scsi_cmnd *srb) +{ + int result = 0; + + printk(KERN_INFO "%s called\n", __func__); + + return result < 0 ? FAILED : SUCCESS; +} + +/* Simulate a SCSI bus reset by resetting the device's USB port. */ +static int bus_reset(struct scsi_cmnd *srb) +{ + int result = 0; + + printk(KERN_INFO "%s called\n", __func__); + + return result < 0 ? FAILED : SUCCESS; +} + + +/* + * this defines our host template, with which we'll allocate hosts + */ + +struct scsi_host_template rtsx_host_template = { + /* basic userland interface stuff */ + .name = CR_DRIVER_NAME, + .proc_name = CR_DRIVER_NAME, + .proc_info = proc_info, + .info = host_info, + + /* command interface -- queued only */ + .queuecommand = queuecommand, + + /* error and abort handlers */ + .eh_abort_handler = command_abort, + .eh_device_reset_handler = device_reset, + .eh_bus_reset_handler = bus_reset, + + /* queue commands only, only one command per LUN */ + .can_queue = 1, + .cmd_per_lun = 1, + + /* unknown initiator id */ + .this_id = -1, + + .slave_alloc = slave_alloc, + .slave_configure = slave_configure, + + /* lots of sg segments can be handled */ + .sg_tablesize = SG_ALL, + + /* limit the total size of a transfer to 120 KB */ + .max_sectors = 240, + + /* merge commands... this seems to help performance, but + * periodically someone should test to see which setting is more + * optimal. + */ + .use_clustering = 1, + + /* emulated HBA */ + .emulated = 1, + + /* we do our own delay after a device or bus reset */ + .skip_settle_delay = 1, + + /* module management */ + .module = THIS_MODULE +}; + + +static int rtsx_acquire_irq(struct rtsx_dev *dev) +{ + struct rtsx_chip *chip = dev->chip; + + printk(KERN_INFO "%s: chip->msi_en = %d, pci->irq = %d\n", + __func__, chip->msi_en, dev->pci->irq); + + if (request_irq(dev->pci->irq, rtsx_interrupt, + chip->msi_en ? 0 : IRQF_SHARED, + CR_DRIVER_NAME, dev)) { + printk(KERN_ERR "rtsx: unable to grab IRQ %d, " + "disabling device\n", dev->pci->irq); + return -1; + } + + dev->irq = dev->pci->irq; + pci_intx(dev->pci, !chip->msi_en); + + return 0; +} + + +int rtsx_read_pci_cfg_byte(u8 bus, u8 dev, u8 func, u8 offset, u8 *val) +{ + struct pci_dev *pdev; + u8 data; + u8 devfn = (dev << 3) | func; + + pdev = pci_get_bus_and_slot(bus, devfn); + if (!dev) + return -1; + + pci_read_config_byte(pdev, offset, &data); + if (val) + *val = data; + + return 0; +} + +#ifdef CONFIG_PM +/* + * power management + */ +static int rtsx_suspend(struct pci_dev *pci, pm_message_t state) +{ + struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); + struct rtsx_chip *chip; + + printk(KERN_INFO "Ready to suspend\n"); + + if (!dev) { + printk(KERN_ERR "Invalid memory\n"); + return 0; + } + + /* lock the device pointers */ + mutex_lock(&(dev->dev_mutex)); + + chip = dev->chip; + + rtsx_do_before_power_down(chip, PM_S3); + + if (dev->irq >= 0) { + synchronize_irq(dev->irq); + free_irq(dev->irq, (void *)dev); + dev->irq = -1; + } + + if (chip->msi_en) + pci_disable_msi(pci); + + pci_save_state(pci); + pci_enable_wake(pci, pci_choose_state(pci, state), 1); + pci_disable_device(pci); + pci_set_power_state(pci, pci_choose_state(pci, state)); + + /* unlock the device pointers */ + mutex_unlock(&dev->dev_mutex); + + return 0; +} + +static int rtsx_resume(struct pci_dev *pci) +{ + struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); + struct rtsx_chip *chip; + + printk(KERN_INFO "Ready to resume\n"); + + if (!dev) { + printk(KERN_ERR "Invalid memory\n"); + return 0; + } + + chip = dev->chip; + + /* lock the device pointers */ + mutex_lock(&(dev->dev_mutex)); + + pci_set_power_state(pci, PCI_D0); + pci_restore_state(pci); + if (pci_enable_device(pci) < 0) { + printk(KERN_ERR "%s: pci_enable_device failed, " + "disabling device\n", CR_DRIVER_NAME); + /* unlock the device pointers */ + mutex_unlock(&dev->dev_mutex); + return -EIO; + } + pci_set_master(pci); + + if (chip->msi_en) { + if (pci_enable_msi(pci) < 0) + chip->msi_en = 0; + } + + if (rtsx_acquire_irq(dev) < 0) { + /* unlock the device pointers */ + mutex_unlock(&dev->dev_mutex); + return -EIO; + } + + rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 0x00); + rtsx_init_chip(chip); + + /* unlock the device pointers */ + mutex_unlock(&dev->dev_mutex); + + return 0; +} +#endif /* CONFIG_PM */ + +void rtsx_shutdown(struct pci_dev *pci) +{ + struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); + struct rtsx_chip *chip; + + printk(KERN_INFO "Ready to shutdown\n"); + + if (!dev) { + printk(KERN_ERR "Invalid memory\n"); + return; + } + + chip = dev->chip; + + rtsx_do_before_power_down(chip, PM_S1); + + if (dev->irq >= 0) { + synchronize_irq(dev->irq); + free_irq(dev->irq, (void *)dev); + dev->irq = -1; + } + + if (chip->msi_en) + pci_disable_msi(pci); + + pci_disable_device(pci); + + return; +} + +static int rtsx_control_thread(void *__dev) +{ + struct rtsx_dev *dev = (struct rtsx_dev *)__dev; + struct rtsx_chip *chip = dev->chip; + struct Scsi_Host *host = rtsx_to_host(dev); + + current->flags |= PF_NOFREEZE; + + for (;;) { + if (down_interruptible(&dev->sema)) + break; + + /* lock the device pointers */ + mutex_lock(&(dev->dev_mutex)); + + /* if the device has disconnected, we are free to exit */ + if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { + printk(KERN_INFO "-- rtsx-control exiting\n"); + mutex_unlock(&dev->dev_mutex); + break; + } + + /* lock access to the state */ + scsi_lock(host); + + /* has the command aborted ? */ + if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) { + chip->srb->result = DID_ABORT << 16; + goto SkipForAbort; + } + + scsi_unlock(host); + + /* reject the command if the direction indicator + * is UNKNOWN + */ + if (chip->srb->sc_data_direction == DMA_BIDIRECTIONAL) { + printk(KERN_ERR "UNKNOWN data direction\n"); + chip->srb->result = DID_ERROR << 16; + } + + /* reject if target != 0 or if LUN is higher than + * the maximum known LUN + */ + else if (chip->srb->device->id) { + printk(KERN_ERR "Bad target number (%d:%d)\n", + chip->srb->device->id, chip->srb->device->lun); + chip->srb->result = DID_BAD_TARGET << 16; + } + + else if (chip->srb->device->lun > chip->max_lun) { + printk(KERN_ERR "Bad LUN (%d:%d)\n", + chip->srb->device->id, chip->srb->device->lun); + chip->srb->result = DID_BAD_TARGET << 16; + } + + /* we've got a command, let's do it! */ + else { + RTSX_DEBUG(scsi_show_command(chip->srb)); + rtsx_invoke_transport(chip->srb, chip); + } + + /* lock access to the state */ + scsi_lock(host); + + /* did the command already complete because of a disconnect? */ + if (!chip->srb) + ; /* nothing to do */ + + /* indicate that the command is done */ + else if (chip->srb->result != DID_ABORT << 16) { + chip->srb->scsi_done(chip->srb); + } else { +SkipForAbort: + printk(KERN_ERR "scsi command aborted\n"); + } + + if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) { + complete(&(dev->notify)); + + rtsx_set_stat(chip, RTSX_STAT_IDLE); + } + + /* finished working on this command */ + chip->srb = NULL; + scsi_unlock(host); + + /* unlock the device pointers */ + mutex_unlock(&dev->dev_mutex); + } /* for (;;) */ + + scsi_host_put(host); + + /* notify the exit routine that we're actually exiting now + * + * complete()/wait_for_completion() is similar to up()/down(), + * except that complete() is safe in the case where the structure + * is getting deleted in a parallel mode of execution (i.e. just + * after the down() -- that's necessary for the thread-shutdown + * case. + * + * complete_and_exit() goes even further than this -- it is safe in + * the case that the thread of the caller is going away (not just + * the structure) -- this is necessary for the module-remove case. + * This is important in preemption kernels, which transfer the flow + * of execution immediately upon a complete(). + */ + complete_and_exit(&threads_gone, 0); +} + + +static int rtsx_polling_thread(void *__dev) +{ + struct rtsx_dev *dev = (struct rtsx_dev *)__dev; + struct rtsx_chip *chip = dev->chip; + struct Scsi_Host *host = rtsx_to_host(dev); + struct sd_info *sd_card = &(chip->sd_card); + struct xd_info *xd_card = &(chip->xd_card); + struct ms_info *ms_card = &(chip->ms_card); + + sd_card->cleanup_counter = 0; + xd_card->cleanup_counter = 0; + ms_card->cleanup_counter = 0; + + /* Wait until SCSI scan finished */ + wait_timeout((delay_use + 5) * 1000); + + for (;;) { + wait_timeout(POLLING_INTERVAL); + + /* lock the device pointers */ + mutex_lock(&(dev->dev_mutex)); + + /* if the device has disconnected, we are free to exit */ + if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { + printk(KERN_INFO "-- rtsx-polling exiting\n"); + mutex_unlock(&dev->dev_mutex); + break; + } + + mutex_unlock(&dev->dev_mutex); + + mspro_polling_format_status(chip); + + /* lock the device pointers */ + mutex_lock(&(dev->dev_mutex)); + + rtsx_polling_func(chip); + + /* unlock the device pointers */ + mutex_unlock(&dev->dev_mutex); + } + + scsi_host_put(host); + complete_and_exit(&threads_gone, 0); +} + +/* + * interrupt handler + */ +static irqreturn_t rtsx_interrupt(int irq, void *dev_id) +{ + struct rtsx_dev *dev = dev_id; + struct rtsx_chip *chip; + int retval; + u32 status; + + if (dev) { + chip = dev->chip; + } else { + return IRQ_NONE; + } + + if (!chip) { + return IRQ_NONE; + } + + spin_lock(&dev->reg_lock); + + retval = rtsx_pre_handle_interrupt(chip); + if (retval == STATUS_FAIL) { + spin_unlock(&dev->reg_lock); + if (chip->int_reg == 0xFFFFFFFF) { + return IRQ_HANDLED; + } else { + return IRQ_NONE; + } + } + + status = chip->int_reg; + + if (dev->check_card_cd) { + if (!(dev->check_card_cd & status)) { + /* card not exist, return TRANS_RESULT_FAIL */ + dev->trans_result = TRANS_RESULT_FAIL; + if (dev->done) + complete(dev->done); + goto Exit; + } + } + + if (status & (NEED_COMPLETE_INT | DELINK_INT)) { + if (status & (TRANS_FAIL_INT | DELINK_INT)) { + if (status & DELINK_INT) { + RTSX_SET_DELINK(chip); + } + dev->trans_result = TRANS_RESULT_FAIL; + if (dev->done) + complete(dev->done); + } else if (status & TRANS_OK_INT) { + dev->trans_result = TRANS_RESULT_OK; + if (dev->done) + complete(dev->done); + } else if (status & DATA_DONE_INT) { + dev->trans_result = TRANS_NOT_READY; + if (dev->done && (dev->trans_state == STATE_TRANS_SG)) + complete(dev->done); + } + } + +Exit: + spin_unlock(&dev->reg_lock); + return IRQ_HANDLED; +} + + +/* Release all our dynamic resources */ +static void rtsx_release_resources(struct rtsx_dev *dev) +{ + printk(KERN_INFO "-- %s\n", __func__); + + if (dev->rtsx_resv_buf) { + dma_free_coherent(&(dev->pci->dev), HOST_CMDS_BUF_LEN, + dev->rtsx_resv_buf, dev->rtsx_resv_buf_addr); + dev->chip->host_cmds_ptr = NULL; + dev->chip->host_sg_tbl_ptr = NULL; + } + + pci_disable_device(dev->pci); + pci_release_regions(dev->pci); + + if (dev->irq > 0) { + free_irq(dev->irq, (void *)dev); + } + if (dev->chip->msi_en) { + pci_disable_msi(dev->pci); + } + + /* Tell the control thread to exit. The SCSI host must + * already have been removed so it won't try to queue + * any more commands. + */ + printk(KERN_INFO "-- sending exit command to thread\n"); + up(&dev->sema); +} + +/* First stage of disconnect processing: stop all commands and remove + * the host */ +static void quiesce_and_remove_host(struct rtsx_dev *dev) +{ + struct Scsi_Host *host = rtsx_to_host(dev); + struct rtsx_chip *chip = dev->chip; + + /* Prevent new transfers, stop the current command, and + * interrupt a SCSI-scan or device-reset delay */ + mutex_lock(&dev->dev_mutex); + scsi_lock(host); + rtsx_set_stat(chip, RTSX_STAT_DISCONNECT); + scsi_unlock(host); + mutex_unlock(&dev->dev_mutex); + wake_up(&dev->delay_wait); + + /* Wait some time to let other threads exist */ + wait_timeout(100); + + /* queuecommand won't accept any new commands and the control + * thread won't execute a previously-queued command. If there + * is such a command pending, complete it with an error. */ + mutex_lock(&dev->dev_mutex); + if (chip->srb) { + chip->srb->result = DID_NO_CONNECT << 16; + scsi_lock(host); + chip->srb->scsi_done(dev->chip->srb); + chip->srb = NULL; + scsi_unlock(host); + } + mutex_unlock(&dev->dev_mutex); + + /* Now we own no commands so it's safe to remove the SCSI host */ + scsi_remove_host(host); +} + +/* Second stage of disconnect processing: deallocate all resources */ +static void release_everything(struct rtsx_dev *dev) +{ + rtsx_release_resources(dev); + + /* Drop our reference to the host; the SCSI core will free it + * when the refcount becomes 0. */ + scsi_host_put(rtsx_to_host(dev)); +} + +/* Thread to carry out delayed SCSI-device scanning */ +static int rtsx_scan_thread(void *__dev) +{ + struct rtsx_dev *dev = (struct rtsx_dev *)__dev; + struct rtsx_chip *chip = dev->chip; + + /* Wait for the timeout to expire or for a disconnect */ + if (delay_use > 0) { + printk(KERN_INFO "%s: waiting for device " + "to settle before scanning\n", CR_DRIVER_NAME); + wait_event_interruptible_timeout(dev->delay_wait, + rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT), + delay_use * HZ); + } + + /* If the device is still connected, perform the scanning */ + if (!rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { + scsi_scan_host(rtsx_to_host(dev)); + printk(KERN_INFO "%s: device scan complete\n", CR_DRIVER_NAME); + + /* Should we unbind if no devices were detected? */ + } + + scsi_host_put(rtsx_to_host(dev)); + complete_and_exit(&threads_gone, 0); +} + +static void rtsx_init_options(struct rtsx_chip *chip) +{ + chip->vendor_id = chip->rtsx->pci->vendor; + chip->product_id = chip->rtsx->pci->device; + chip->adma_mode = 1; + chip->lun_mc = 0; + chip->driver_first_load = 1; +#ifdef HW_AUTO_SWITCH_SD_BUS + chip->sdio_in_charge = 0; +#endif + + chip->mspro_formatter_enable = 1; + chip->ignore_sd = 0; + chip->use_hw_setting = 0; + chip->lun_mode = DEFAULT_SINGLE; + chip->auto_delink_en = auto_delink_en; + chip->ss_en = ss_en; + chip->ss_idle_period = ss_interval * 1000; + chip->remote_wakeup_en = 0; + chip->aspm_l0s_l1_en = aspm_l0s_l1_en; + chip->dynamic_aspm = 1; + chip->fpga_sd_sdr104_clk = CLK_200; + chip->fpga_sd_ddr50_clk = CLK_100; + chip->fpga_sd_sdr50_clk = CLK_100; + chip->fpga_sd_hs_clk = CLK_100; + chip->fpga_mmc_52m_clk = CLK_80; + chip->fpga_ms_hg_clk = CLK_80; + chip->fpga_ms_4bit_clk = CLK_80; + chip->fpga_ms_1bit_clk = CLK_40; + chip->asic_sd_sdr104_clk = 207; + chip->asic_sd_sdr50_clk = 99; + chip->asic_sd_ddr50_clk = 99; + chip->asic_sd_hs_clk = 99; + chip->asic_mmc_52m_clk = 99; + chip->asic_ms_hg_clk = 119; + chip->asic_ms_4bit_clk = 79; + chip->asic_ms_1bit_clk = 39; + chip->ssc_depth_sd_sdr104 = SSC_DEPTH_2M; + chip->ssc_depth_sd_sdr50 = SSC_DEPTH_2M; + chip->ssc_depth_sd_ddr50 = SSC_DEPTH_1M; + chip->ssc_depth_sd_hs = SSC_DEPTH_1M; + chip->ssc_depth_mmc_52m = SSC_DEPTH_1M; + chip->ssc_depth_ms_hg = SSC_DEPTH_1M; + chip->ssc_depth_ms_4bit = SSC_DEPTH_512K; + chip->ssc_depth_low_speed = SSC_DEPTH_512K; + chip->ssc_en = 1; + chip->sd_speed_prior = 0x01040203; + chip->sd_current_prior = 0x00010203; + chip->sd_ctl = SD_PUSH_POINT_AUTO | SD_SAMPLE_POINT_AUTO | SUPPORT_MMC_DDR_MODE; + chip->sd_ddr_tx_phase = 0; + chip->mmc_ddr_tx_phase = 1; + chip->sd_default_tx_phase = 15; + chip->sd_default_rx_phase = 15; + chip->pmos_pwr_on_interval = 200; + chip->sd_voltage_switch_delay = 1000; + + chip->sd_400mA_ocp_thd = 1; + chip->sd_800mA_ocp_thd = 5; + chip->ms_ocp_thd = 2; + + chip->card_drive_sel = 0x55; + chip->sd30_drive_sel_1v8 = 0x03; + chip->sd30_drive_sel_3v3 = 0x01; + + chip->do_delink_before_power_down = 1; + chip->auto_power_down = 1; + chip->polling_config = 0; + + chip->force_clkreq_0 = 1; + chip->ft2_fast_mode = 0; + + chip->sdio_retry_cnt = 1; + + chip->xd_timeout = 2000; + chip->sd_timeout = 10000; + chip->ms_timeout = 2000; + chip->mspro_timeout = 15000; + + chip->power_down_in_ss = 1; + + chip->sdr104_en = 1; + chip->sdr50_en = 1; + chip->ddr50_en = 1; + + chip->delink_stage1_step = 100; + chip->delink_stage2_step = 40; + chip->delink_stage3_step = 20; + + chip->auto_delink_in_L1 = 1; + chip->blink_led = 1; + chip->msi_en = msi_en; + chip->hp_watch_bios_hotplug = 0; + chip->max_payload = 0; + chip->phy_voltage = 0; + + chip->support_ms_8bit = 1; + chip->s3_pwr_off_delay = 1000; +} + +static int __devinit rtsx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) +{ + struct Scsi_Host *host; + struct rtsx_dev *dev; + int err = 0; + struct task_struct *th; + + RTSX_DEBUGP("Realtek PCI-E card reader detected\n"); + + err = pci_enable_device(pci); + if (err < 0) { + printk(KERN_ERR "PCI enable device failed!\n"); + return err; + } + + err = pci_request_regions(pci, CR_DRIVER_NAME); + if (err < 0) { + printk(KERN_ERR "PCI request regions for %s failed!\n", CR_DRIVER_NAME); + pci_disable_device(pci); + return err; + } + + /* + * Ask the SCSI layer to allocate a host structure, with extra + * space at the end for our private rtsx_dev structure. + */ + host = scsi_host_alloc(&rtsx_host_template, sizeof(*dev)); + if (!host) { + printk(KERN_ERR "Unable to allocate the scsi host\n"); + pci_release_regions(pci); + pci_disable_device(pci); + return -ENOMEM; + } + + dev = host_to_rtsx(host); + memset(dev, 0, sizeof(struct rtsx_dev)); + + dev->chip = (struct rtsx_chip *)kmalloc(sizeof(struct rtsx_chip), GFP_KERNEL); + if (dev->chip == NULL) { + goto errout; + } + memset(dev->chip, 0, sizeof(struct rtsx_chip)); + + spin_lock_init(&dev->reg_lock); + mutex_init(&(dev->dev_mutex)); + sema_init(&(dev->sema), 0); + init_completion(&(dev->notify)); + init_waitqueue_head(&dev->delay_wait); + + dev->pci = pci; + dev->irq = -1; + + printk(KERN_INFO "Resource length: 0x%x\n", (unsigned int)pci_resource_len(pci, 0)); + dev->addr = pci_resource_start(pci, 0); + dev->remap_addr = ioremap_nocache(dev->addr, pci_resource_len(pci, 0)); + if (dev->remap_addr == NULL) { + printk(KERN_ERR "ioremap error\n"); + err = -ENXIO; + goto errout; + } + + /* Using "unsigned long" cast here to eliminate gcc warning in 64-bit system */ + printk(KERN_INFO "Original address: 0x%lx, remapped address: 0x%lx\n", + (unsigned long)(dev->addr), (unsigned long)(dev->remap_addr)); + + dev->rtsx_resv_buf = dma_alloc_coherent(&(pci->dev), RTSX_RESV_BUF_LEN, + &(dev->rtsx_resv_buf_addr), GFP_KERNEL); + if (dev->rtsx_resv_buf == NULL) { + printk(KERN_ERR "alloc dma buffer fail\n"); + err = -ENXIO; + goto errout; + } + dev->chip->host_cmds_ptr = dev->rtsx_resv_buf; + dev->chip->host_cmds_addr = dev->rtsx_resv_buf_addr; + dev->chip->host_sg_tbl_ptr = dev->rtsx_resv_buf + HOST_CMDS_BUF_LEN; + dev->chip->host_sg_tbl_addr = dev->rtsx_resv_buf_addr + HOST_CMDS_BUF_LEN; + + dev->chip->rtsx = dev; + + rtsx_init_options(dev->chip); + + printk(KERN_INFO "pci->irq = %d\n", pci->irq); + + if (dev->chip->msi_en) { + if (pci_enable_msi(pci) < 0) + dev->chip->msi_en = 0; + } + + if (rtsx_acquire_irq(dev) < 0) { + err = -EBUSY; + goto errout; + } + + pci_set_master(pci); + synchronize_irq(dev->irq); + + err = scsi_add_host(host, &pci->dev); + if (err) { + printk(KERN_ERR "Unable to add the scsi host\n"); + goto errout; + } + + rtsx_init_chip(dev->chip); + + /* Start up our control thread */ + th = kthread_create(rtsx_control_thread, dev, CR_DRIVER_NAME); + if (IS_ERR(th)) { + printk(KERN_ERR "Unable to start control thread\n"); + err = PTR_ERR(th); + goto errout; + } + + /* Take a reference to the host for the control thread and + * count it among all the threads we have launched. Then + * start it up. */ + scsi_host_get(rtsx_to_host(dev)); + atomic_inc(&total_threads); + wake_up_process(th); + + /* Start up the thread for delayed SCSI-device scanning */ + th = kthread_create(rtsx_scan_thread, dev, "rtsx-scan"); + if (IS_ERR(th)) { + printk(KERN_ERR "Unable to start the device-scanning thread\n"); + quiesce_and_remove_host(dev); + err = PTR_ERR(th); + goto errout; + } + + /* Take a reference to the host for the scanning thread and + * count it among all the threads we have launched. Then + * start it up. */ + scsi_host_get(rtsx_to_host(dev)); + atomic_inc(&total_threads); + wake_up_process(th); + + /* Start up the thread for polling thread */ + th = kthread_create(rtsx_polling_thread, dev, "rtsx-polling"); + if (IS_ERR(th)) { + printk(KERN_ERR "Unable to start the device-polling thread\n"); + quiesce_and_remove_host(dev); + err = PTR_ERR(th); + goto errout; + } + + /* Take a reference to the host for the polling thread and + * count it among all the threads we have launched. Then + * start it up. */ + scsi_host_get(rtsx_to_host(dev)); + atomic_inc(&total_threads); + wake_up_process(th); + + pci_set_drvdata(pci, dev); + + return 0; + + /* We come here if there are any problems */ +errout: + printk(KERN_ERR "rtsx_probe() failed\n"); + release_everything(dev); + + return err; +} + + +static void __devexit rtsx_remove(struct pci_dev *pci) +{ + struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); + + printk(KERN_INFO "rtsx_remove() called\n"); + + quiesce_and_remove_host(dev); + release_everything(dev); + + pci_set_drvdata(pci, NULL); +} + +/* PCI IDs */ +static struct pci_device_id rtsx_ids[] = { + { 0x10EC, 0x5208, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_OTHERS << 16, 0xFF0000 }, + { 0x10EC, 0x5209, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_OTHERS << 16, 0xFF0000 }, + { 0x10EC, 0x5288, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_OTHERS << 16, 0xFF0000 }, + { 0, }, +}; + +MODULE_DEVICE_TABLE(pci, rtsx_ids); + +/* pci_driver definition */ +static struct pci_driver driver = { + .name = CR_DRIVER_NAME, + .id_table = rtsx_ids, + .probe = rtsx_probe, + .remove = __devexit_p(rtsx_remove), +#ifdef CONFIG_PM + .suspend = rtsx_suspend, + .resume = rtsx_resume, +#endif + .shutdown = rtsx_shutdown, +}; + +static int __init rtsx_init(void) +{ + printk(KERN_INFO "Initializing Realtek PCIE storage driver...\n"); + + return pci_register_driver(&driver); +} + +static void __exit rtsx_exit(void) +{ + printk(KERN_INFO "rtsx_exit() called\n"); + + pci_unregister_driver(&driver); + + /* Don't return until all of our control and scanning threads + * have exited. Since each thread signals threads_gone as its + * last act, we have to call wait_for_completion the right number + * of times. + */ + while (atomic_read(&total_threads) > 0) { + wait_for_completion(&threads_gone); + atomic_dec(&total_threads); + } + + printk(KERN_INFO "%s module exit\n", CR_DRIVER_NAME); +} + +module_init(rtsx_init) +module_exit(rtsx_exit) + diff --git a/drivers/staging/rts_pstor/rtsx.h b/drivers/staging/rts_pstor/rtsx.h new file mode 100644 index 000000000000..4d5ddf6fbb5e --- /dev/null +++ b/drivers/staging/rts_pstor/rtsx.h @@ -0,0 +1,183 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __REALTEK_RTSX_H +#define __REALTEK_RTSX_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "debug.h" +#include "trace.h" +#include "general.h" + +#define CR_DRIVER_NAME "rts_pstor" + +#define pci_get_bus_and_slot(bus, devfn) \ + pci_get_domain_bus_and_slot(0, (bus), (devfn)) + +/* + * macros for easy use + */ +#define rtsx_writel(chip, reg, value) \ + iowrite32(value, (chip)->rtsx->remap_addr + reg) +#define rtsx_readl(chip, reg) \ + ioread32((chip)->rtsx->remap_addr + reg) +#define rtsx_writew(chip, reg, value) \ + iowrite16(value, (chip)->rtsx->remap_addr + reg) +#define rtsx_readw(chip, reg) \ + ioread16((chip)->rtsx->remap_addr + reg) +#define rtsx_writeb(chip, reg, value) \ + iowrite8(value, (chip)->rtsx->remap_addr + reg) +#define rtsx_readb(chip, reg) \ + ioread8((chip)->rtsx->remap_addr + reg) + +#define rtsx_read_config_byte(chip, where, val) \ + pci_read_config_byte((chip)->rtsx->pci, where, val) + +#define rtsx_write_config_byte(chip, where, val) \ + pci_write_config_byte((chip)->rtsx->pci, where, val) + +#define wait_timeout_x(task_state, msecs) \ +do { \ + set_current_state((task_state)); \ + schedule_timeout((msecs) * HZ / 1000); \ +} while (0) +#define wait_timeout(msecs) wait_timeout_x(TASK_INTERRUPTIBLE, (msecs)) + + +#define STATE_TRANS_NONE 0 +#define STATE_TRANS_CMD 1 +#define STATE_TRANS_BUF 2 +#define STATE_TRANS_SG 3 + +#define TRANS_NOT_READY 0 +#define TRANS_RESULT_OK 1 +#define TRANS_RESULT_FAIL 2 + +#define SCSI_LUN(srb) ((srb)->device->lun) + +#define rtsx_alloc_dma_buf(chip, size, flag) kmalloc((size), (flag)) +#define rtsx_free_dma_buf(chip, ptr) kfree((ptr)) + +typedef unsigned long DELAY_PARA_T; + +struct rtsx_chip; + +struct rtsx_dev { + struct pci_dev *pci; + + /* pci resources */ + unsigned long addr; + void __iomem *remap_addr; + int irq; + + /* locks */ + spinlock_t reg_lock; + + /* mutual exclusion and synchronization structures */ + struct semaphore sema; /* to sleep thread on */ + struct completion notify; /* thread begin/end */ + wait_queue_head_t delay_wait; /* wait during scan, reset */ + struct mutex dev_mutex; + + /* host reserved buffer */ + void *rtsx_resv_buf; + dma_addr_t rtsx_resv_buf_addr; + + char trans_result; + char trans_state; + + struct completion *done; + /* Whether interrupt handler should care card cd info */ + u32 check_card_cd; + + struct rtsx_chip *chip; +}; + +typedef struct rtsx_dev rtsx_dev_t; + +/* Convert between rtsx_dev and the corresponding Scsi_Host */ +static inline struct Scsi_Host *rtsx_to_host(struct rtsx_dev *dev) +{ + return container_of((void *) dev, struct Scsi_Host, hostdata); +} +static inline struct rtsx_dev *host_to_rtsx(struct Scsi_Host *host) +{ + return (struct rtsx_dev *) host->hostdata; +} + +static inline void get_current_time(u8 *timeval_buf, int buf_len) +{ + struct timeval tv; + + if (!timeval_buf || (buf_len < 8)) + return; + + do_gettimeofday(&tv); + + timeval_buf[0] = (u8)(tv.tv_sec >> 24); + timeval_buf[1] = (u8)(tv.tv_sec >> 16); + timeval_buf[2] = (u8)(tv.tv_sec >> 8); + timeval_buf[3] = (u8)(tv.tv_sec); + timeval_buf[4] = (u8)(tv.tv_usec >> 24); + timeval_buf[5] = (u8)(tv.tv_usec >> 16); + timeval_buf[6] = (u8)(tv.tv_usec >> 8); + timeval_buf[7] = (u8)(tv.tv_usec); +} + +/* The scsi_lock() and scsi_unlock() macros protect the sm_state and the + * single queue element srb for write access */ +#define scsi_unlock(host) spin_unlock_irq(host->host_lock) +#define scsi_lock(host) spin_lock_irq(host->host_lock) + +#define lock_state(chip) spin_lock_irq(&((chip)->rtsx->reg_lock)) +#define unlock_state(chip) spin_unlock_irq(&((chip)->rtsx->reg_lock)) + +/* struct scsi_cmnd transfer buffer access utilities */ +enum xfer_buf_dir {TO_XFER_BUF, FROM_XFER_BUF}; + +int rtsx_read_pci_cfg_byte(u8 bus, u8 dev, u8 func, u8 offset, u8 *val); + +#endif /* __REALTEK_RTSX_H */ diff --git a/drivers/staging/rts_pstor/rtsx_card.c b/drivers/staging/rts_pstor/rtsx_card.c new file mode 100644 index 000000000000..fe4cce0cce29 --- /dev/null +++ b/drivers/staging/rts_pstor/rtsx_card.c @@ -0,0 +1,1257 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include +#include +#include +#include +#include + +#include "rtsx.h" +#include "rtsx_transport.h" +#include "rtsx_scsi.h" +#include "rtsx_card.h" + +#include "rtsx_sys.h" +#include "general.h" + +#include "sd.h" +#include "xd.h" +#include "ms.h" + +void do_remaining_work(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); +#ifdef XD_DELAY_WRITE + struct xd_info *xd_card = &(chip->xd_card); +#endif + struct ms_info *ms_card = &(chip->ms_card); + + if (chip->card_ready & SD_CARD) { + if (sd_card->seq_mode) { + rtsx_set_stat(chip, RTSX_STAT_RUN); + sd_card->cleanup_counter++; + } else { + sd_card->cleanup_counter = 0; + } + } + +#ifdef XD_DELAY_WRITE + if (chip->card_ready & XD_CARD) { + if (xd_card->delay_write.delay_write_flag) { + rtsx_set_stat(chip, RTSX_STAT_RUN); + xd_card->cleanup_counter++; + } else { + xd_card->cleanup_counter = 0; + } + } +#endif + + if (chip->card_ready & MS_CARD) { + if (CHK_MSPRO(ms_card)) { + if (ms_card->seq_mode) { + rtsx_set_stat(chip, RTSX_STAT_RUN); + ms_card->cleanup_counter++; + } else { + ms_card->cleanup_counter = 0; + } + } else { +#ifdef MS_DELAY_WRITE + if (ms_card->delay_write.delay_write_flag) { + rtsx_set_stat(chip, RTSX_STAT_RUN); + ms_card->cleanup_counter++; + } else { + ms_card->cleanup_counter = 0; + } +#endif + } + } + + if (sd_card->cleanup_counter > POLLING_WAIT_CNT) + sd_cleanup_work(chip); + + if (xd_card->cleanup_counter > POLLING_WAIT_CNT) + xd_cleanup_work(chip); + + if (ms_card->cleanup_counter > POLLING_WAIT_CNT) + ms_cleanup_work(chip); +} + +void try_to_switch_sdio_ctrl(struct rtsx_chip *chip) +{ + u8 reg1 = 0, reg2 = 0; + + rtsx_read_register(chip, 0xFF34, ®1); + rtsx_read_register(chip, 0xFF38, ®2); + RTSX_DEBUGP("reg 0xFF34: 0x%x, reg 0xFF38: 0x%x\n", reg1, reg2); + if ((reg1 & 0xC0) && (reg2 & 0xC0)) { + chip->sd_int = 1; + rtsx_write_register(chip, SDIO_CTRL, 0xFF, SDIO_BUS_CTRL | SDIO_CD_CTRL); + rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON); + } +} + +#ifdef SUPPORT_SDIO_ASPM +void dynamic_configure_sdio_aspm(struct rtsx_chip *chip) +{ + u8 buf[12], reg; + int i; + + for (i = 0; i < 12; i++) + rtsx_read_register(chip, 0xFF08 + i, &buf[i]); + rtsx_read_register(chip, 0xFF25, ®); + if ((memcmp(buf, chip->sdio_raw_data, 12) != 0) || (reg & 0x03)) { + chip->sdio_counter = 0; + chip->sdio_idle = 0; + } else { + if (!chip->sdio_idle) { + chip->sdio_counter++; + if (chip->sdio_counter >= SDIO_IDLE_COUNT) { + chip->sdio_counter = 0; + chip->sdio_idle = 1; + } + } + } + memcpy(chip->sdio_raw_data, buf, 12); + + if (chip->sdio_idle) { + if (!chip->sdio_aspm) { + RTSX_DEBUGP("SDIO enter ASPM!\n"); + rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, + 0x30 | (chip->aspm_level[1] << 2)); + chip->sdio_aspm = 1; + } + } else { + if (chip->sdio_aspm) { + RTSX_DEBUGP("SDIO exit ASPM!\n"); + rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, 0x30); + chip->sdio_aspm = 0; + } + } +} +#endif + +void do_reset_sd_card(struct rtsx_chip *chip) +{ + int retval; + + RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__, + chip->sd_reset_counter, chip->card2lun[SD_CARD]); + + if (chip->card2lun[SD_CARD] >= MAX_ALLOWED_LUN_CNT) { + clear_bit(SD_NR, &(chip->need_reset)); + chip->sd_reset_counter = 0; + chip->sd_show_cnt = 0; + return; + } + + chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0; + + rtsx_set_stat(chip, RTSX_STAT_RUN); + rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); + + retval = reset_sd_card(chip); + if (chip->need_release & SD_CARD) + return; + if (retval == STATUS_SUCCESS) { + clear_bit(SD_NR, &(chip->need_reset)); + chip->sd_reset_counter = 0; + chip->sd_show_cnt = 0; + chip->card_ready |= SD_CARD; + chip->card_fail &= ~SD_CARD; + chip->rw_card[chip->card2lun[SD_CARD]] = sd_rw; + } else { + if (chip->sd_io || (chip->sd_reset_counter >= MAX_RESET_CNT)) { + clear_bit(SD_NR, &(chip->need_reset)); + chip->sd_reset_counter = 0; + chip->sd_show_cnt = 0; + } else { + chip->sd_reset_counter++; + } + chip->card_ready &= ~SD_CARD; + chip->card_fail |= SD_CARD; + chip->capacity[chip->card2lun[SD_CARD]] = 0; + chip->rw_card[chip->card2lun[SD_CARD]] = NULL; + + rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0); + if (!chip->ft2_fast_mode) + card_power_off(chip, SD_CARD); + if (chip->sd_io) { + chip->sd_int = 0; + try_to_switch_sdio_ctrl(chip); + } else { + disable_card_clock(chip, SD_CARD); + } + } +} + +void do_reset_xd_card(struct rtsx_chip *chip) +{ + int retval; + + RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__, + chip->xd_reset_counter, chip->card2lun[XD_CARD]); + + if (chip->card2lun[XD_CARD] >= MAX_ALLOWED_LUN_CNT) { + clear_bit(XD_NR, &(chip->need_reset)); + chip->xd_reset_counter = 0; + chip->xd_show_cnt = 0; + return; + } + + chip->rw_fail_cnt[chip->card2lun[XD_CARD]] = 0; + + rtsx_set_stat(chip, RTSX_STAT_RUN); + rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); + + retval = reset_xd_card(chip); + if (chip->need_release & XD_CARD) + return; + if (retval == STATUS_SUCCESS) { + clear_bit(XD_NR, &(chip->need_reset)); + chip->xd_reset_counter = 0; + chip->card_ready |= XD_CARD; + chip->card_fail &= ~XD_CARD; + chip->rw_card[chip->card2lun[XD_CARD]] = xd_rw; + } else { + if (chip->xd_reset_counter >= MAX_RESET_CNT) { + clear_bit(XD_NR, &(chip->need_reset)); + chip->xd_reset_counter = 0; + chip->xd_show_cnt = 0; + } else { + chip->xd_reset_counter++; + } + chip->card_ready &= ~XD_CARD; + chip->card_fail |= XD_CARD; + chip->capacity[chip->card2lun[XD_CARD]] = 0; + chip->rw_card[chip->card2lun[XD_CARD]] = NULL; + + rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0); + if (!chip->ft2_fast_mode) + card_power_off(chip, XD_CARD); + disable_card_clock(chip, XD_CARD); + } +} + +void do_reset_ms_card(struct rtsx_chip *chip) +{ + int retval; + + RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__, + chip->ms_reset_counter, chip->card2lun[MS_CARD]); + + if (chip->card2lun[MS_CARD] >= MAX_ALLOWED_LUN_CNT) { + clear_bit(MS_NR, &(chip->need_reset)); + chip->ms_reset_counter = 0; + chip->ms_show_cnt = 0; + return; + } + + chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0; + + rtsx_set_stat(chip, RTSX_STAT_RUN); + rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); + + retval = reset_ms_card(chip); + if (chip->need_release & MS_CARD) + return; + if (retval == STATUS_SUCCESS) { + clear_bit(MS_NR, &(chip->need_reset)); + chip->ms_reset_counter = 0; + chip->card_ready |= MS_CARD; + chip->card_fail &= ~MS_CARD; + chip->rw_card[chip->card2lun[MS_CARD]] = ms_rw; + } else { + if (chip->ms_reset_counter >= MAX_RESET_CNT) { + clear_bit(MS_NR, &(chip->need_reset)); + chip->ms_reset_counter = 0; + chip->ms_show_cnt = 0; + } else { + chip->ms_reset_counter++; + } + chip->card_ready &= ~MS_CARD; + chip->card_fail |= MS_CARD; + chip->capacity[chip->card2lun[MS_CARD]] = 0; + chip->rw_card[chip->card2lun[MS_CARD]] = NULL; + + rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0); + if (!chip->ft2_fast_mode) + card_power_off(chip, MS_CARD); + disable_card_clock(chip, MS_CARD); + } +} + +void release_sdio(struct rtsx_chip *chip) +{ + if (chip->sd_io) { + rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, + SD_STOP | SD_CLR_ERR); + + if (chip->chip_insert_with_sdio) { + chip->chip_insert_with_sdio = 0; + + if (CHECK_PID(chip, 0x5288)) { + rtsx_write_register(chip, 0xFE5A, 0x08, 0x00); + } else { + rtsx_write_register(chip, 0xFE70, 0x80, 0x00); + } + } + + rtsx_write_register(chip, SDIO_CTRL, SDIO_CD_CTRL, 0); + chip->sd_io = 0; + } +} + +void rtsx_power_off_card(struct rtsx_chip *chip) +{ + if ((chip->card_ready & SD_CARD) || chip->sd_io) { + sd_cleanup_work(chip); + sd_power_off_card3v3(chip); + } + + if (chip->card_ready & XD_CARD) { + xd_cleanup_work(chip); + xd_power_off_card3v3(chip); + } + + if (chip->card_ready & MS_CARD) { + ms_cleanup_work(chip); + ms_power_off_card3v3(chip); + } +} + +void rtsx_release_cards(struct rtsx_chip *chip) +{ + chip->int_reg = rtsx_readl(chip, RTSX_BIPR); + + if ((chip->card_ready & SD_CARD) || chip->sd_io) { + if (chip->int_reg & SD_EXIST) + sd_cleanup_work(chip); + release_sd_card(chip); + } + + if (chip->card_ready & XD_CARD) { + if (chip->int_reg & XD_EXIST) + xd_cleanup_work(chip); + release_xd_card(chip); + } + + if (chip->card_ready & MS_CARD) { + if (chip->int_reg & MS_EXIST) + ms_cleanup_work(chip); + release_ms_card(chip); + } +} + +void rtsx_reset_cards(struct rtsx_chip *chip) +{ + if (!chip->need_reset) + return; + + rtsx_set_stat(chip, RTSX_STAT_RUN); + + rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); + + rtsx_disable_aspm(chip); + + if ((chip->need_reset & SD_CARD) && chip->chip_insert_with_sdio) + clear_bit(SD_NR, &(chip->need_reset)); + + if (chip->need_reset & XD_CARD) { + chip->card_exist |= XD_CARD; + + if (chip->xd_show_cnt >= MAX_SHOW_CNT) { + do_reset_xd_card(chip); + } else { + chip->xd_show_cnt++; + } + } + if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) { + if (chip->card_exist & XD_CARD) { + clear_bit(SD_NR, &(chip->need_reset)); + clear_bit(MS_NR, &(chip->need_reset)); + } + } + if (chip->need_reset & SD_CARD) { + chip->card_exist |= SD_CARD; + + if (chip->sd_show_cnt >= MAX_SHOW_CNT) { + rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); + do_reset_sd_card(chip); + } else { + chip->sd_show_cnt++; + } + } + if (chip->need_reset & MS_CARD) { + chip->card_exist |= MS_CARD; + + if (chip->ms_show_cnt >= MAX_SHOW_CNT) { + do_reset_ms_card(chip); + } else { + chip->ms_show_cnt++; + } + } +} + +void rtsx_reinit_cards(struct rtsx_chip *chip, int reset_chip) +{ + rtsx_set_stat(chip, RTSX_STAT_RUN); + + rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); + + if (reset_chip) + rtsx_reset_chip(chip); + + chip->int_reg = rtsx_readl(chip, RTSX_BIPR); + + if ((chip->int_reg & SD_EXIST) && (chip->need_reinit & SD_CARD)) { + release_sdio(chip); + release_sd_card(chip); + + wait_timeout(100); + + chip->card_exist |= SD_CARD; + do_reset_sd_card(chip); + } + + if ((chip->int_reg & XD_EXIST) && (chip->need_reinit & XD_CARD)) { + release_xd_card(chip); + + wait_timeout(100); + + chip->card_exist |= XD_CARD; + do_reset_xd_card(chip); + } + + if ((chip->int_reg & MS_EXIST) && (chip->need_reinit & MS_CARD)) { + release_ms_card(chip); + + wait_timeout(100); + + chip->card_exist |= MS_CARD; + do_reset_ms_card(chip); + } + + chip->need_reinit = 0; +} + +#ifdef DISABLE_CARD_INT +void card_cd_debounce(struct rtsx_chip *chip, unsigned long *need_reset, unsigned long *need_release) +{ + u8 release_map = 0, reset_map = 0; + + chip->int_reg = rtsx_readl(chip, RTSX_BIPR); + + if (chip->card_exist) { + if (chip->card_exist & XD_CARD) { + if (!(chip->int_reg & XD_EXIST)) + release_map |= XD_CARD; + } else if (chip->card_exist & SD_CARD) { + if (!(chip->int_reg & SD_EXIST)) + release_map |= SD_CARD; + } else if (chip->card_exist & MS_CARD) { + if (!(chip->int_reg & MS_EXIST)) + release_map |= MS_CARD; + } + } else { + if (chip->int_reg & XD_EXIST) { + reset_map |= XD_CARD; + } else if (chip->int_reg & SD_EXIST) { + reset_map |= SD_CARD; + } else if (chip->int_reg & MS_EXIST) { + reset_map |= MS_CARD; + } + } + + if (reset_map) { + int xd_cnt = 0, sd_cnt = 0, ms_cnt = 0; + int i; + + for (i = 0; i < (DEBOUNCE_CNT); i++) { + chip->int_reg = rtsx_readl(chip, RTSX_BIPR); + + if (chip->int_reg & XD_EXIST) { + xd_cnt++; + } else { + xd_cnt = 0; + } + if (chip->int_reg & SD_EXIST) { + sd_cnt++; + } else { + sd_cnt = 0; + } + if (chip->int_reg & MS_EXIST) { + ms_cnt++; + } else { + ms_cnt = 0; + } + wait_timeout(30); + } + + reset_map = 0; + if (!(chip->card_exist & XD_CARD) && (xd_cnt > (DEBOUNCE_CNT-1))) + reset_map |= XD_CARD; + if (!(chip->card_exist & SD_CARD) && (sd_cnt > (DEBOUNCE_CNT-1))) + reset_map |= SD_CARD; + if (!(chip->card_exist & MS_CARD) && (ms_cnt > (DEBOUNCE_CNT-1))) + reset_map |= MS_CARD; + } + + if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) + rtsx_write_register(chip, HOST_SLEEP_STATE, 0xC0, 0x00); + + if (need_reset) + *need_reset = reset_map; + if (need_release) + *need_release = release_map; +} +#endif + +void rtsx_init_cards(struct rtsx_chip *chip) +{ + if (RTSX_TST_DELINK(chip) && (rtsx_get_stat(chip) != RTSX_STAT_SS)) { + RTSX_DEBUGP("Reset chip in polling thread!\n"); + rtsx_reset_chip(chip); + RTSX_CLR_DELINK(chip); + } + +#ifdef DISABLE_CARD_INT + card_cd_debounce(chip, &(chip->need_reset), &(chip->need_release)); +#endif + + if (chip->need_release) { + if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) { + if (chip->int_reg & XD_EXIST) { + clear_bit(SD_NR, &(chip->need_release)); + clear_bit(MS_NR, &(chip->need_release)); + } + } + + if (!(chip->card_exist & SD_CARD) && !chip->sd_io) + clear_bit(SD_NR, &(chip->need_release)); + if (!(chip->card_exist & XD_CARD)) + clear_bit(XD_NR, &(chip->need_release)); + if (!(chip->card_exist & MS_CARD)) + clear_bit(MS_NR, &(chip->need_release)); + + RTSX_DEBUGP("chip->need_release = 0x%x\n", (unsigned int)(chip->need_release)); + +#ifdef SUPPORT_OCP + if (chip->need_release) { + if (CHECK_PID(chip, 0x5209)) { + u8 mask = 0, val = 0; + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + if (chip->ocp_stat & (MS_OC_NOW | MS_OC_EVER)) { + mask |= MS_OCP_INT_CLR | MS_OC_CLR; + val |= MS_OCP_INT_CLR | MS_OC_CLR; + } + } + if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { + mask |= SD_OCP_INT_CLR | SD_OC_CLR; + val |= SD_OCP_INT_CLR | SD_OC_CLR; + } + if (mask) + rtsx_write_register(chip, OCPCTL, mask, val); + } else { + if (chip->ocp_stat & (CARD_OC_NOW | CARD_OC_EVER)) + rtsx_write_register(chip, OCPCLR, + CARD_OC_INT_CLR | CARD_OC_CLR, + CARD_OC_INT_CLR | CARD_OC_CLR); + } + chip->ocp_stat = 0; + } +#endif + if (chip->need_release) { + rtsx_set_stat(chip, RTSX_STAT_RUN); + rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); + } + + if (chip->need_release & SD_CARD) { + clear_bit(SD_NR, &(chip->need_release)); + chip->card_exist &= ~SD_CARD; + chip->card_ejected &= ~SD_CARD; + chip->card_fail &= ~SD_CARD; + CLR_BIT(chip->lun_mc, chip->card2lun[SD_CARD]); + chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0; + rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); + + release_sdio(chip); + release_sd_card(chip); + } + + if (chip->need_release & XD_CARD) { + clear_bit(XD_NR, &(chip->need_release)); + chip->card_exist &= ~XD_CARD; + chip->card_ejected &= ~XD_CARD; + chip->card_fail &= ~XD_CARD; + CLR_BIT(chip->lun_mc, chip->card2lun[XD_CARD]); + chip->rw_fail_cnt[chip->card2lun[XD_CARD]] = 0; + + release_xd_card(chip); + + if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) + rtsx_write_register(chip, HOST_SLEEP_STATE, 0xC0, 0xC0); + } + + if (chip->need_release & MS_CARD) { + clear_bit(MS_NR, &(chip->need_release)); + chip->card_exist &= ~MS_CARD; + chip->card_ejected &= ~MS_CARD; + chip->card_fail &= ~MS_CARD; + CLR_BIT(chip->lun_mc, chip->card2lun[MS_CARD]); + chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0; + + release_ms_card(chip); + } + + RTSX_DEBUGP("chip->card_exist = 0x%x\n", chip->card_exist); + + if (!chip->card_exist) + turn_off_led(chip, LED_GPIO); + } + + if (chip->need_reset) { + RTSX_DEBUGP("chip->need_reset = 0x%x\n", (unsigned int)(chip->need_reset)); + + rtsx_reset_cards(chip); + } + + if (chip->need_reinit) { + RTSX_DEBUGP("chip->need_reinit = 0x%x\n", (unsigned int)(chip->need_reinit)); + + rtsx_reinit_cards(chip, 0); + } +} + +static inline u8 double_depth(u8 depth) +{ + return ((depth > 1) ? (depth - 1) : depth); +} + +int switch_ssc_clock(struct rtsx_chip *chip, int clk) +{ + struct sd_info *sd_card = &(chip->sd_card); + struct ms_info *ms_card = &(chip->ms_card); + int retval; + u8 N = (u8)(clk - 2), min_N, max_N; + u8 mcu_cnt, div, max_div, ssc_depth, ssc_depth_mask; + int sd_vpclk_phase_reset = 0; + + if (chip->cur_clk == clk) + return STATUS_SUCCESS; + + if (CHECK_PID(chip, 0x5209)) { + min_N = 80; + max_N = 208; + max_div = CLK_DIV_8; + } else { + min_N = 60; + max_N = 120; + max_div = CLK_DIV_4; + } + + if (CHECK_PID(chip, 0x5209) && (chip->cur_card == SD_CARD)) { + struct sd_info *sd_card = &(chip->sd_card); + if (CHK_SD30_SPEED(sd_card) || CHK_MMC_DDR52(sd_card)) + sd_vpclk_phase_reset = 1; + } + + RTSX_DEBUGP("Switch SSC clock to %dMHz (cur_clk = %d)\n", clk, chip->cur_clk); + + if ((clk <= 2) || (N > max_N)) { + TRACE_RET(chip, STATUS_FAIL); + } + + mcu_cnt = (u8)(125/clk + 3); + if (CHECK_PID(chip, 0x5209)) { + if (mcu_cnt > 15) + mcu_cnt = 15; + } else { + if (mcu_cnt > 7) + mcu_cnt = 7; + } + + div = CLK_DIV_1; + while ((N < min_N) && (div < max_div)) { + N = (N + 2) * 2 - 2; + div++; + } + RTSX_DEBUGP("N = %d, div = %d\n", N, div); + + if (chip->ssc_en) { + if (CHECK_PID(chip, 0x5209)) { + if (chip->cur_card == SD_CARD) { + if (CHK_SD_SDR104(sd_card)) { + ssc_depth = chip->ssc_depth_sd_sdr104; + } else if (CHK_SD_SDR50(sd_card)) { + ssc_depth = chip->ssc_depth_sd_sdr50; + } else if (CHK_SD_DDR50(sd_card)) { + ssc_depth = double_depth(chip->ssc_depth_sd_ddr50); + } else if (CHK_SD_HS(sd_card)) { + ssc_depth = double_depth(chip->ssc_depth_sd_hs); + } else if (CHK_MMC_52M(sd_card) || CHK_MMC_DDR52(sd_card)) { + ssc_depth = double_depth(chip->ssc_depth_mmc_52m); + } else { + ssc_depth = double_depth(chip->ssc_depth_low_speed); + } + } else if (chip->cur_card == MS_CARD) { + if (CHK_MSPRO(ms_card)) { + if (CHK_HG8BIT(ms_card)) { + ssc_depth = double_depth(chip->ssc_depth_ms_hg); + } else { + ssc_depth = double_depth(chip->ssc_depth_ms_4bit); + } + } else { + if (CHK_MS4BIT(ms_card)) { + ssc_depth = double_depth(chip->ssc_depth_ms_4bit); + } else { + ssc_depth = double_depth(chip->ssc_depth_low_speed); + } + } + } else { + ssc_depth = double_depth(chip->ssc_depth_low_speed); + } + + if (ssc_depth) { + if (div == CLK_DIV_2) { + if (ssc_depth > 1) { + ssc_depth -= 1; + } else { + ssc_depth = SSC_DEPTH_4M; + } + } else if (div == CLK_DIV_4) { + if (ssc_depth > 2) { + ssc_depth -= 2; + } else { + ssc_depth = SSC_DEPTH_4M; + } + } else if (div == CLK_DIV_8) { + if (ssc_depth > 3) { + ssc_depth -= 3; + } else { + ssc_depth = SSC_DEPTH_4M; + } + } + } + } else { + ssc_depth = 0x01; + N -= 2; + } + } else { + ssc_depth = 0; + } + + if (CHECK_PID(chip, 0x5209)) { + ssc_depth_mask = SSC_DEPTH_MASK; + } else { + ssc_depth_mask = 0x03; + } + + RTSX_DEBUGP("ssc_depth = %d\n", ssc_depth); + + rtsx_init_cmd(chip); + rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ); + rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0xFF, (div << 4) | mcu_cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL2, ssc_depth_mask, ssc_depth); + rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, N); + rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB); + if (sd_vpclk_phase_reset) { + rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET); + } + + retval = rtsx_send_cmd(chip, 0, WAIT_TIME); + if (retval < 0) { + TRACE_RET(chip, STATUS_ERROR); + } + + udelay(10); + RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0); + + chip->cur_clk = clk; + + return STATUS_SUCCESS; +} + +int switch_normal_clock(struct rtsx_chip *chip, int clk) +{ + u8 sel, div, mcu_cnt; + int sd_vpclk_phase_reset = 0; + + if (chip->cur_clk == clk) + return STATUS_SUCCESS; + + if (CHECK_PID(chip, 0x5209) && (chip->cur_card == SD_CARD)) { + struct sd_info *sd_card = &(chip->sd_card); + if (CHK_SD30_SPEED(sd_card) || CHK_MMC_DDR52(sd_card)) + sd_vpclk_phase_reset = 1; + } + + switch (clk) { + case CLK_20: + RTSX_DEBUGP("Switch clock to 20MHz\n"); + sel = SSC_80; + div = CLK_DIV_4; + mcu_cnt = 7; + break; + + case CLK_30: + RTSX_DEBUGP("Switch clock to 30MHz\n"); + sel = SSC_120; + div = CLK_DIV_4; + mcu_cnt = 7; + break; + + case CLK_40: + RTSX_DEBUGP("Switch clock to 40MHz\n"); + sel = SSC_80; + div = CLK_DIV_2; + mcu_cnt = 7; + break; + + case CLK_50: + RTSX_DEBUGP("Switch clock to 50MHz\n"); + sel = SSC_100; + div = CLK_DIV_2; + mcu_cnt = 6; + break; + + case CLK_60: + RTSX_DEBUGP("Switch clock to 60MHz\n"); + sel = SSC_120; + div = CLK_DIV_2; + mcu_cnt = 6; + break; + + case CLK_80: + RTSX_DEBUGP("Switch clock to 80MHz\n"); + sel = SSC_80; + div = CLK_DIV_1; + mcu_cnt = 5; + break; + + case CLK_100: + RTSX_DEBUGP("Switch clock to 100MHz\n"); + sel = SSC_100; + div = CLK_DIV_1; + mcu_cnt = 5; + break; + + case CLK_120: + RTSX_DEBUGP("Switch clock to 120MHz\n"); + sel = SSC_120; + div = CLK_DIV_1; + mcu_cnt = 5; + break; + + case CLK_150: + RTSX_DEBUGP("Switch clock to 150MHz\n"); + sel = SSC_150; + div = CLK_DIV_1; + mcu_cnt = 4; + break; + + case CLK_200: + RTSX_DEBUGP("Switch clock to 200MHz\n"); + sel = SSC_200; + div = CLK_DIV_1; + mcu_cnt = 4; + break; + + default: + RTSX_DEBUGP("Try to switch to an illegal clock (%d)\n", clk); + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, CLK_CTL, 0xFF, CLK_LOW_FREQ); + if (sd_vpclk_phase_reset) { + RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); + RTSX_WRITE_REG(chip, SD_VPCLK1_CTL, PHASE_NOT_RESET, 0); + } + RTSX_WRITE_REG(chip, CLK_DIV, 0xFF, (div << 4) | mcu_cnt); + RTSX_WRITE_REG(chip, CLK_SEL, 0xFF, sel); + + if (sd_vpclk_phase_reset) { + udelay(200); + RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET); + RTSX_WRITE_REG(chip, SD_VPCLK1_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET); + udelay(200); + } + RTSX_WRITE_REG(chip, CLK_CTL, 0xFF, 0); + + chip->cur_clk = clk; + + return STATUS_SUCCESS; +} + +void trans_dma_enable(enum dma_data_direction dir, struct rtsx_chip *chip, u32 byte_cnt, u8 pack_size) +{ + if (pack_size > DMA_1024) + pack_size = DMA_512; + + rtsx_add_cmd(chip, WRITE_REG_CMD, IRQSTAT0, DMA_DONE_INT, DMA_DONE_INT); + + rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC3, 0xFF, (u8)(byte_cnt >> 24)); + rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC2, 0xFF, (u8)(byte_cnt >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC1, 0xFF, (u8)(byte_cnt >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC0, 0xFF, (u8)byte_cnt); + + if (dir == DMA_FROM_DEVICE) { + rtsx_add_cmd(chip, WRITE_REG_CMD, DMACTL, 0x03 | DMA_PACK_SIZE_MASK, + DMA_DIR_FROM_CARD | DMA_EN | pack_size); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, DMACTL, 0x03 | DMA_PACK_SIZE_MASK, + DMA_DIR_TO_CARD | DMA_EN | pack_size); + } + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); +} + +int enable_card_clock(struct rtsx_chip *chip, u8 card) +{ + u8 clk_en = 0; + + if (card & XD_CARD) + clk_en |= XD_CLK_EN; + if (card & SD_CARD) + clk_en |= SD_CLK_EN; + if (card & MS_CARD) + clk_en |= MS_CLK_EN; + + RTSX_WRITE_REG(chip, CARD_CLK_EN, clk_en, clk_en); + + return STATUS_SUCCESS; +} + +int disable_card_clock(struct rtsx_chip *chip, u8 card) +{ + u8 clk_en = 0; + + if (card & XD_CARD) + clk_en |= XD_CLK_EN; + if (card & SD_CARD) + clk_en |= SD_CLK_EN; + if (card & MS_CARD) + clk_en |= MS_CLK_EN; + + RTSX_WRITE_REG(chip, CARD_CLK_EN, clk_en, 0); + + return STATUS_SUCCESS; +} + +int card_power_on(struct rtsx_chip *chip, u8 card) +{ + int retval; + u8 mask, val1, val2; + + if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (card == MS_CARD)) { + mask = MS_POWER_MASK; + val1 = MS_PARTIAL_POWER_ON; + val2 = MS_POWER_ON; + } else { + mask = SD_POWER_MASK; + val1 = SD_PARTIAL_POWER_ON; + val2 = SD_POWER_ON; + } + + rtsx_init_cmd(chip); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val1); + if (CHECK_PID(chip, 0x5209) && (card == SD_CARD)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_SUSPEND); + } + retval = rtsx_send_cmd(chip, 0, 100); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + udelay(chip->pmos_pwr_on_interval); + + rtsx_init_cmd(chip); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val2); + if (CHECK_PID(chip, 0x5209) && (card == SD_CARD)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON); + } + retval = rtsx_send_cmd(chip, 0, 100); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int card_power_off(struct rtsx_chip *chip, u8 card) +{ + u8 mask, val; + + if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (card == MS_CARD)) { + mask = MS_POWER_MASK; + val = MS_POWER_OFF; + } else { + mask = SD_POWER_MASK; + val = SD_POWER_OFF; + } + if (CHECK_PID(chip, 0x5209)) { + mask |= PMOS_STRG_MASK; + val |= PMOS_STRG_400mA; + } + + RTSX_WRITE_REG(chip, CARD_PWR_CTL, mask, val); + if (CHECK_PID(chip, 0x5209) && (card == SD_CARD)) { + RTSX_WRITE_REG(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_OFF); + } + + return STATUS_SUCCESS; +} + +int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 sec_addr, u16 sec_cnt) +{ + int retval; + unsigned int lun = SCSI_LUN(srb); + int i; + + if (chip->rw_card[lun] == NULL) { + TRACE_RET(chip, STATUS_FAIL); + } + + for (i = 0; i < 3; i++) { + chip->rw_need_retry = 0; + + retval = chip->rw_card[lun](srb, chip, sec_addr, sec_cnt); + if (retval != STATUS_SUCCESS) { + if (rtsx_check_chip_exist(chip) != STATUS_SUCCESS) { + rtsx_release_chip(chip); + TRACE_RET(chip, STATUS_FAIL); + } + if (detect_card_cd(chip, chip->cur_card) != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + if (!chip->rw_need_retry) { + RTSX_DEBUGP("RW fail, but no need to retry\n"); + break; + } + } else { + chip->rw_need_retry = 0; + break; + } + + RTSX_DEBUGP("Retry RW, (i = %d)\n", i); + } + + return retval; +} + +int card_share_mode(struct rtsx_chip *chip, int card) +{ + u8 mask, value; + + if (CHECK_PID(chip, 0x5209) || CHECK_PID(chip, 0x5208)) { + mask = CARD_SHARE_MASK; + if (card == SD_CARD) { + value = CARD_SHARE_48_SD; + } else if (card == MS_CARD) { + value = CARD_SHARE_48_MS; + } else if (card == XD_CARD) { + value = CARD_SHARE_48_XD; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } else if (CHECK_PID(chip, 0x5288)) { + mask = 0x03; + if (card == SD_CARD) { + value = CARD_SHARE_BAROSSA_SD; + } else if (card == MS_CARD) { + value = CARD_SHARE_BAROSSA_MS; + } else if (card == XD_CARD) { + value = CARD_SHARE_BAROSSA_XD; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, CARD_SHARE_MODE, mask, value); + + return STATUS_SUCCESS; +} + + +int select_card(struct rtsx_chip *chip, int card) +{ + int retval; + + if (chip->cur_card != card) { + u8 mod; + + if (card == SD_CARD) { + mod = SD_MOD_SEL; + } else if (card == MS_CARD) { + mod = MS_MOD_SEL; + } else if (card == XD_CARD) { + mod = XD_MOD_SEL; + } else if (card == SPI_CARD) { + mod = SPI_MOD_SEL; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + RTSX_WRITE_REG(chip, CARD_SELECT, 0x07, mod); + chip->cur_card = card; + + retval = card_share_mode(chip, card); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + +void toggle_gpio(struct rtsx_chip *chip, u8 gpio) +{ + u8 temp_reg; + + rtsx_read_register(chip, CARD_GPIO, &temp_reg); + temp_reg ^= (0x01 << gpio); + rtsx_write_register(chip, CARD_GPIO, 0xFF, temp_reg); +} + +void turn_on_led(struct rtsx_chip *chip, u8 gpio) +{ + if (CHECK_PID(chip, 0x5288)) { + rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), (u8)(1 << gpio)); + } else { + rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), 0); + } +} + +void turn_off_led(struct rtsx_chip *chip, u8 gpio) +{ + if (CHECK_PID(chip, 0x5288)) { + rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), 0); + } else { + rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), (u8)(1 << gpio)); + } +} + +int detect_card_cd(struct rtsx_chip *chip, int card) +{ + u32 card_cd, status; + + if (card == SD_CARD) { + card_cd = SD_EXIST; + } else if (card == MS_CARD) { + card_cd = MS_EXIST; + } else if (card == XD_CARD) { + card_cd = XD_EXIST; + } else { + RTSX_DEBUGP("Wrong card type: 0x%x\n", card); + TRACE_RET(chip, STATUS_FAIL); + } + + status = rtsx_readl(chip, RTSX_BIPR); + if (!(status & card_cd)) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int check_card_exist(struct rtsx_chip *chip, unsigned int lun) +{ + if (chip->card_exist & chip->lun2card[lun]) { + return 1; + } + + return 0; +} + +int check_card_ready(struct rtsx_chip *chip, unsigned int lun) +{ + if (chip->card_ready & chip->lun2card[lun]) { + return 1; + } + + return 0; +} + +int check_card_wp(struct rtsx_chip *chip, unsigned int lun) +{ + if (chip->card_wp & chip->lun2card[lun]) { + return 1; + } + + return 0; +} + +int check_card_fail(struct rtsx_chip *chip, unsigned int lun) +{ + if (chip->card_fail & chip->lun2card[lun]) { + return 1; + } + + return 0; +} + +int check_card_ejected(struct rtsx_chip *chip, unsigned int lun) +{ + if (chip->card_ejected & chip->lun2card[lun]) { + return 1; + } + + return 0; +} + +u8 get_lun_card(struct rtsx_chip *chip, unsigned int lun) +{ + if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) { + return (u8)XD_CARD; + } else if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) { + return (u8)SD_CARD; + } else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) { + return (u8)MS_CARD; + } + + return 0; +} + +void eject_card(struct rtsx_chip *chip, unsigned int lun) +{ + do_remaining_work(chip); + + if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) { + release_sd_card(chip); + chip->card_ejected |= SD_CARD; + chip->card_ready &= ~SD_CARD; + chip->capacity[lun] = 0; + } else if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) { + release_xd_card(chip); + chip->card_ejected |= XD_CARD; + chip->card_ready &= ~XD_CARD; + chip->capacity[lun] = 0; + } else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) { + release_ms_card(chip); + chip->card_ejected |= MS_CARD; + chip->card_ready &= ~MS_CARD; + chip->capacity[lun] = 0; + } +} diff --git a/drivers/staging/rts_pstor/rtsx_card.h b/drivers/staging/rts_pstor/rtsx_card.h new file mode 100644 index 000000000000..5a0e167a15d9 --- /dev/null +++ b/drivers/staging/rts_pstor/rtsx_card.h @@ -0,0 +1,1095 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __REALTEK_RTSX_CARD_H +#define __REALTEK_RTSX_CARD_H + +#include "debug.h" +#include "rtsx.h" +#include "rtsx_chip.h" +#include "rtsx_transport.h" +#include "sd.h" + +#define SSC_POWER_DOWN 0x01 +#define SD_OC_POWER_DOWN 0x02 +#define MS_OC_POWER_DOWN 0x04 +#define ALL_POWER_DOWN 0x07 +#define OC_POWER_DOWN 0x06 + +#define PMOS_STRG_MASK 0x10 +#define PMOS_STRG_800mA 0x10 +#define PMOS_STRG_400mA 0x00 + +#define POWER_OFF 0x03 +#define PARTIAL_POWER_ON 0x01 +#define POWER_ON 0x00 + +#define MS_POWER_OFF 0x0C +#define MS_PARTIAL_POWER_ON 0x04 +#define MS_POWER_ON 0x00 +#define MS_POWER_MASK 0x0C + +#define SD_POWER_OFF 0x03 +#define SD_PARTIAL_POWER_ON 0x01 +#define SD_POWER_ON 0x00 +#define SD_POWER_MASK 0x03 + +#define XD_OUTPUT_EN 0x02 +#define SD_OUTPUT_EN 0x04 +#define MS_OUTPUT_EN 0x08 +#define SPI_OUTPUT_EN 0x10 + +#define CLK_LOW_FREQ 0x01 + +#define CLK_DIV_1 0x01 +#define CLK_DIV_2 0x02 +#define CLK_DIV_4 0x03 +#define CLK_DIV_8 0x04 + +#define SSC_80 0 +#define SSC_100 1 +#define SSC_120 2 +#define SSC_150 3 +#define SSC_200 4 + +#define XD_CLK_EN 0x02 +#define SD_CLK_EN 0x04 +#define MS_CLK_EN 0x08 +#define SPI_CLK_EN 0x10 + +#define XD_MOD_SEL 1 +#define SD_MOD_SEL 2 +#define MS_MOD_SEL 3 +#define SPI_MOD_SEL 4 + +#define CHANGE_CLK 0x01 + +#define SD_CRC7_ERR 0x80 +#define SD_CRC16_ERR 0x40 +#define SD_CRC_WRITE_ERR 0x20 +#define SD_CRC_WRITE_ERR_MASK 0x1C +#define GET_CRC_TIME_OUT 0x02 +#define SD_TUNING_COMPARE_ERR 0x01 + +#define SD_RSP_80CLK_TIMEOUT 0x01 + +#define SD_CLK_TOGGLE_EN 0x80 +#define SD_CLK_FORCE_STOP 0x40 +#define SD_DAT3_STATUS 0x10 +#define SD_DAT2_STATUS 0x08 +#define SD_DAT1_STATUS 0x04 +#define SD_DAT0_STATUS 0x02 +#define SD_CMD_STATUS 0x01 + +#define SD_IO_USING_1V8 0x80 +#define SD_IO_USING_3V3 0x7F +#define TYPE_A_DRIVING 0x00 +#define TYPE_B_DRIVING 0x01 +#define TYPE_C_DRIVING 0x02 +#define TYPE_D_DRIVING 0x03 + +#define DDR_FIX_RX_DAT 0x00 +#define DDR_VAR_RX_DAT 0x80 +#define DDR_FIX_RX_DAT_EDGE 0x00 +#define DDR_FIX_RX_DAT_14_DELAY 0x40 +#define DDR_FIX_RX_CMD 0x00 +#define DDR_VAR_RX_CMD 0x20 +#define DDR_FIX_RX_CMD_POS_EDGE 0x00 +#define DDR_FIX_RX_CMD_14_DELAY 0x10 +#define SD20_RX_POS_EDGE 0x00 +#define SD20_RX_14_DELAY 0x08 +#define SD20_RX_SEL_MASK 0x08 + +#define DDR_FIX_TX_CMD_DAT 0x00 +#define DDR_VAR_TX_CMD_DAT 0x80 +#define DDR_FIX_TX_DAT_14_TSU 0x00 +#define DDR_FIX_TX_DAT_12_TSU 0x40 +#define DDR_FIX_TX_CMD_NEG_EDGE 0x00 +#define DDR_FIX_TX_CMD_14_AHEAD 0x20 +#define SD20_TX_NEG_EDGE 0x00 +#define SD20_TX_14_AHEAD 0x10 +#define SD20_TX_SEL_MASK 0x10 +#define DDR_VAR_SDCLK_POL_SWAP 0x01 + +#define SD_TRANSFER_START 0x80 +#define SD_TRANSFER_END 0x40 +#define SD_STAT_IDLE 0x20 +#define SD_TRANSFER_ERR 0x10 +#define SD_TM_NORMAL_WRITE 0x00 +#define SD_TM_AUTO_WRITE_3 0x01 +#define SD_TM_AUTO_WRITE_4 0x02 +#define SD_TM_AUTO_READ_3 0x05 +#define SD_TM_AUTO_READ_4 0x06 +#define SD_TM_CMD_RSP 0x08 +#define SD_TM_AUTO_WRITE_1 0x09 +#define SD_TM_AUTO_WRITE_2 0x0A +#define SD_TM_NORMAL_READ 0x0C +#define SD_TM_AUTO_READ_1 0x0D +#define SD_TM_AUTO_READ_2 0x0E +#define SD_TM_AUTO_TUNING 0x0F + +#define PHASE_CHANGE 0x80 +#define PHASE_NOT_RESET 0x40 + +#define DCMPS_CHANGE 0x80 +#define DCMPS_CHANGE_DONE 0x40 +#define DCMPS_ERROR 0x20 +#define DCMPS_CURRENT_PHASE 0x1F + +#define SD_CLK_DIVIDE_0 0x00 +#define SD_CLK_DIVIDE_256 0xC0 +#define SD_CLK_DIVIDE_128 0x80 +#define SD_BUS_WIDTH_1 0x00 +#define SD_BUS_WIDTH_4 0x01 +#define SD_BUS_WIDTH_8 0x02 +#define SD_ASYNC_FIFO_NOT_RST 0x10 +#define SD_20_MODE 0x00 +#define SD_DDR_MODE 0x04 +#define SD_30_MODE 0x08 + +#define SD_CLK_DIVIDE_MASK 0xC0 + +#define SD_CMD_IDLE 0x80 + +#define SD_DATA_IDLE 0x80 + +#define DCM_RESET 0x08 +#define DCM_LOCKED 0x04 +#define DCM_208M 0x00 +#define DCM_TX 0x01 +#define DCM_RX 0x02 + +#define DRP_START 0x80 +#define DRP_DONE 0x40 + +#define DRP_WRITE 0x80 +#define DRP_READ 0x00 +#define DCM_WRITE_ADDRESS_50 0x50 +#define DCM_WRITE_ADDRESS_51 0x51 +#define DCM_READ_ADDRESS_00 0x00 +#define DCM_READ_ADDRESS_51 0x51 + +#define SD_CALCULATE_CRC7 0x00 +#define SD_NO_CALCULATE_CRC7 0x80 +#define SD_CHECK_CRC16 0x00 +#define SD_NO_CHECK_CRC16 0x40 +#define SD_NO_CHECK_WAIT_CRC_TO 0x20 +#define SD_WAIT_BUSY_END 0x08 +#define SD_NO_WAIT_BUSY_END 0x00 +#define SD_CHECK_CRC7 0x00 +#define SD_NO_CHECK_CRC7 0x04 +#define SD_RSP_LEN_0 0x00 +#define SD_RSP_LEN_6 0x01 +#define SD_RSP_LEN_17 0x02 +#define SD_RSP_TYPE_R0 0x04 +#define SD_RSP_TYPE_R1 0x01 +#define SD_RSP_TYPE_R1b 0x09 +#define SD_RSP_TYPE_R2 0x02 +#define SD_RSP_TYPE_R3 0x05 +#define SD_RSP_TYPE_R4 0x05 +#define SD_RSP_TYPE_R5 0x01 +#define SD_RSP_TYPE_R6 0x01 +#define SD_RSP_TYPE_R7 0x01 + +#define SD_RSP_80CLK_TIMEOUT_EN 0x01 + +#define SAMPLE_TIME_RISING 0x00 +#define SAMPLE_TIME_FALLING 0x80 +#define PUSH_TIME_DEFAULT 0x00 +#define PUSH_TIME_ODD 0x40 +#define NO_EXTEND_TOGGLE 0x00 +#define EXTEND_TOGGLE_CHK 0x20 +#define MS_BUS_WIDTH_1 0x00 +#define MS_BUS_WIDTH_4 0x10 +#define MS_BUS_WIDTH_8 0x18 +#define MS_2K_SECTOR_MODE 0x04 +#define MS_512_SECTOR_MODE 0x00 +#define MS_TOGGLE_TIMEOUT_EN 0x00 +#define MS_TOGGLE_TIMEOUT_DISEN 0x01 +#define MS_NO_CHECK_INT 0x02 + +#define WAIT_INT 0x80 +#define NO_WAIT_INT 0x00 +#define NO_AUTO_READ_INT_REG 0x00 +#define AUTO_READ_INT_REG 0x40 +#define MS_CRC16_ERR 0x20 +#define MS_RDY_TIMEOUT 0x10 +#define MS_INT_CMDNK 0x08 +#define MS_INT_BREQ 0x04 +#define MS_INT_ERR 0x02 +#define MS_INT_CED 0x01 + +#define MS_TRANSFER_START 0x80 +#define MS_TRANSFER_END 0x40 +#define MS_TRANSFER_ERR 0x20 +#define MS_BS_STATE 0x10 +#define MS_TM_READ_BYTES 0x00 +#define MS_TM_NORMAL_READ 0x01 +#define MS_TM_WRITE_BYTES 0x04 +#define MS_TM_NORMAL_WRITE 0x05 +#define MS_TM_AUTO_READ 0x08 +#define MS_TM_AUTO_WRITE 0x0C + +#define CARD_SHARE_MASK 0x0F +#define CARD_SHARE_MULTI_LUN 0x00 +#define CARD_SHARE_NORMAL 0x00 +#define CARD_SHARE_48_XD 0x02 +#define CARD_SHARE_48_SD 0x04 +#define CARD_SHARE_48_MS 0x08 +#define CARD_SHARE_BAROSSA_XD 0x00 +#define CARD_SHARE_BAROSSA_SD 0x01 +#define CARD_SHARE_BAROSSA_MS 0x02 + +#define MS_DRIVE_8 0x00 +#define MS_DRIVE_4 0x40 +#define MS_DRIVE_12 0x80 +#define SD_DRIVE_8 0x00 +#define SD_DRIVE_4 0x10 +#define SD_DRIVE_12 0x20 +#define XD_DRIVE_8 0x00 +#define XD_DRIVE_4 0x04 +#define XD_DRIVE_12 0x08 + +#define SPI_STOP 0x01 +#define XD_STOP 0x02 +#define SD_STOP 0x04 +#define MS_STOP 0x08 +#define SPI_CLR_ERR 0x10 +#define XD_CLR_ERR 0x20 +#define SD_CLR_ERR 0x40 +#define MS_CLR_ERR 0x80 + +#define CRC_FIX_CLK (0x00 << 0) +#define CRC_VAR_CLK0 (0x01 << 0) +#define CRC_VAR_CLK1 (0x02 << 0) +#define SD30_FIX_CLK (0x00 << 2) +#define SD30_VAR_CLK0 (0x01 << 2) +#define SD30_VAR_CLK1 (0x02 << 2) +#define SAMPLE_FIX_CLK (0x00 << 4) +#define SAMPLE_VAR_CLK0 (0x01 << 4) +#define SAMPLE_VAR_CLK1 (0x02 << 4) + +#define SDIO_VER_20 0x80 +#define SDIO_VER_10 0x00 +#define SDIO_VER_CHG 0x40 +#define SDIO_BUS_AUTO_SWITCH 0x10 + +#define PINGPONG_BUFFER 0x01 +#define RING_BUFFER 0x00 + +#define RB_FLUSH 0x80 + +#define DMA_DONE_INT_EN 0x80 +#define SUSPEND_INT_EN 0x40 +#define LINK_RDY_INT_EN 0x20 +#define LINK_DOWN_INT_EN 0x10 + +#define DMA_DONE_INT 0x80 +#define SUSPEND_INT 0x40 +#define LINK_RDY_INT 0x20 +#define LINK_DOWN_INT 0x10 + +#define MRD_ERR_INT_EN 0x40 +#define MWR_ERR_INT_EN 0x20 +#define SCSI_CMD_INT_EN 0x10 +#define TLP_RCV_INT_EN 0x08 +#define TLP_TRSMT_INT_EN 0x04 +#define MRD_COMPLETE_INT_EN 0x02 +#define MWR_COMPLETE_INT_EN 0x01 + +#define MRD_ERR_INT 0x40 +#define MWR_ERR_INT 0x20 +#define SCSI_CMD_INT 0x10 +#define TLP_RX_INT 0x08 +#define TLP_TX_INT 0x04 +#define MRD_COMPLETE_INT 0x02 +#define MWR_COMPLETE_INT 0x01 + +#define MSG_RX_INT_EN 0x08 +#define MRD_RX_INT_EN 0x04 +#define MWR_RX_INT_EN 0x02 +#define CPLD_RX_INT_EN 0x01 + +#define MSG_RX_INT 0x08 +#define MRD_RX_INT 0x04 +#define MWR_RX_INT 0x02 +#define CPLD_RX_INT 0x01 + +#define MSG_TX_INT_EN 0x08 +#define MRD_TX_INT_EN 0x04 +#define MWR_TX_INT_EN 0x02 +#define CPLD_TX_INT_EN 0x01 + +#define MSG_TX_INT 0x08 +#define MRD_TX_INT 0x04 +#define MWR_TX_INT 0x02 +#define CPLD_TX_INT 0x01 + +#define DMA_RST 0x80 +#define DMA_BUSY 0x04 +#define DMA_DIR_TO_CARD 0x00 +#define DMA_DIR_FROM_CARD 0x02 +#define DMA_EN 0x01 +#define DMA_128 (0 << 4) +#define DMA_256 (1 << 4) +#define DMA_512 (2 << 4) +#define DMA_1024 (3 << 4) +#define DMA_PACK_SIZE_MASK 0x30 + +#define XD_PWR_OFF_DELAY0 0x00 +#define XD_PWR_OFF_DELAY1 0x02 +#define XD_PWR_OFF_DELAY2 0x04 +#define XD_PWR_OFF_DELAY3 0x06 +#define XD_AUTO_PWR_OFF_EN 0xF7 +#define XD_NO_AUTO_PWR_OFF 0x08 + +#define XD_TIME_RWN_1 0x00 +#define XD_TIME_RWN_STEP 0x20 +#define XD_TIME_RW_1 0x00 +#define XD_TIME_RW_STEP 0x04 +#define XD_TIME_SETUP_1 0x00 +#define XD_TIME_SETUP_STEP 0x01 + +#define XD_ECC2_UNCORRECTABLE 0x80 +#define XD_ECC2_ERROR 0x40 +#define XD_ECC1_UNCORRECTABLE 0x20 +#define XD_ECC1_ERROR 0x10 +#define XD_RDY 0x04 +#define XD_CE_EN 0xFD +#define XD_CE_DISEN 0x02 +#define XD_WP_EN 0xFE +#define XD_WP_DISEN 0x01 + +#define XD_TRANSFER_START 0x80 +#define XD_TRANSFER_END 0x40 +#define XD_PPB_EMPTY 0x20 +#define XD_RESET 0x00 +#define XD_ERASE 0x01 +#define XD_READ_STATUS 0x02 +#define XD_READ_ID 0x03 +#define XD_READ_REDUNDANT 0x04 +#define XD_READ_PAGES 0x05 +#define XD_SET_CMD 0x06 +#define XD_NORMAL_READ 0x07 +#define XD_WRITE_PAGES 0x08 +#define XD_NORMAL_WRITE 0x09 +#define XD_WRITE_REDUNDANT 0x0A +#define XD_SET_ADDR 0x0B + +#define XD_PPB_TO_SIE 0x80 +#define XD_TO_PPB_ONLY 0x00 +#define XD_BA_TRANSFORM 0x40 +#define XD_BA_NO_TRANSFORM 0x00 +#define XD_NO_CALC_ECC 0x20 +#define XD_CALC_ECC 0x00 +#define XD_IGNORE_ECC 0x10 +#define XD_CHECK_ECC 0x00 +#define XD_DIRECT_TO_RB 0x08 +#define XD_ADDR_LENGTH_0 0x00 +#define XD_ADDR_LENGTH_1 0x01 +#define XD_ADDR_LENGTH_2 0x02 +#define XD_ADDR_LENGTH_3 0x03 +#define XD_ADDR_LENGTH_4 0x04 + +#define XD_GPG 0xFF +#define XD_BPG 0x00 + +#define XD_GBLK 0xFF +#define XD_LATER_BBLK 0xF0 + +#define XD_ECC2_ALL1 0x80 +#define XD_ECC1_ALL1 0x40 +#define XD_BA2_ALL0 0x20 +#define XD_BA1_ALL0 0x10 +#define XD_BA1_BA2_EQL 0x04 +#define XD_BA2_VALID 0x02 +#define XD_BA1_VALID 0x01 + +#define XD_PGSTS_ZEROBIT_OVER4 0x00 +#define XD_PGSTS_NOT_FF 0x02 +#define XD_AUTO_CHK_DATA_STATUS 0x01 + +#define RSTB_MODE_DETECT 0x80 +#define MODE_OUT_VLD 0x40 +#define MODE_OUT_0_NONE 0x00 +#define MODE_OUT_10_NONE 0x04 +#define MODE_OUT_10_47 0x05 +#define MODE_OUT_10_180 0x06 +#define MODE_OUT_10_680 0x07 +#define MODE_OUT_16_NONE 0x08 +#define MODE_OUT_16_47 0x09 +#define MODE_OUT_16_180 0x0A +#define MODE_OUT_16_680 0x0B +#define MODE_OUT_NONE_NONE 0x0C +#define MODE_OUT_NONE_47 0x0D +#define MODE_OUT_NONE_180 0x0E +#define MODE_OUT_NONE_680 0x0F + +#define CARD_OC_INT_EN 0x20 +#define CARD_DETECT_EN 0x08 + +#define MS_DETECT_EN 0x80 +#define MS_OCP_INT_EN 0x40 +#define MS_OCP_INT_CLR 0x20 +#define MS_OC_CLR 0x10 +#define SD_DETECT_EN 0x08 +#define SD_OCP_INT_EN 0x04 +#define SD_OCP_INT_CLR 0x02 +#define SD_OC_CLR 0x01 + +#define CARD_OCP_DETECT 0x80 +#define CARD_OC_NOW 0x08 +#define CARD_OC_EVER 0x04 + +#define MS_OCP_DETECT 0x80 +#define MS_OC_NOW 0x40 +#define MS_OC_EVER 0x20 +#define SD_OCP_DETECT 0x08 +#define SD_OC_NOW 0x04 +#define SD_OC_EVER 0x02 + +#define CARD_OC_INT_CLR 0x08 +#define CARD_OC_CLR 0x02 + +#define SD_OCP_GLITCH_MASK 0x07 +#define SD_OCP_GLITCH_6_4 0x00 +#define SD_OCP_GLITCH_64 0x01 +#define SD_OCP_GLITCH_640 0x02 +#define SD_OCP_GLITCH_1000 0x03 +#define SD_OCP_GLITCH_2000 0x04 +#define SD_OCP_GLITCH_4000 0x05 +#define SD_OCP_GLITCH_8000 0x06 +#define SD_OCP_GLITCH_10000 0x07 + +#define MS_OCP_GLITCH_MASK 0x70 +#define MS_OCP_GLITCH_6_4 (0x00 << 4) +#define MS_OCP_GLITCH_64 (0x01 << 4) +#define MS_OCP_GLITCH_640 (0x02 << 4) +#define MS_OCP_GLITCH_1000 (0x03 << 4) +#define MS_OCP_GLITCH_2000 (0x04 << 4) +#define MS_OCP_GLITCH_4000 (0x05 << 4) +#define MS_OCP_GLITCH_8000 (0x06 << 4) +#define MS_OCP_GLITCH_10000 (0x07 << 4) + +#define OCP_TIME_60 0x00 +#define OCP_TIME_100 (0x01 << 3) +#define OCP_TIME_200 (0x02 << 3) +#define OCP_TIME_400 (0x03 << 3) +#define OCP_TIME_600 (0x04 << 3) +#define OCP_TIME_800 (0x05 << 3) +#define OCP_TIME_1100 (0x06 << 3) +#define OCP_TIME_MASK 0x38 + +#define MS_OCP_TIME_60 0x00 +#define MS_OCP_TIME_100 (0x01 << 4) +#define MS_OCP_TIME_200 (0x02 << 4) +#define MS_OCP_TIME_400 (0x03 << 4) +#define MS_OCP_TIME_600 (0x04 << 4) +#define MS_OCP_TIME_800 (0x05 << 4) +#define MS_OCP_TIME_1100 (0x06 << 4) +#define MS_OCP_TIME_MASK 0x70 + +#define SD_OCP_TIME_60 0x00 +#define SD_OCP_TIME_100 0x01 +#define SD_OCP_TIME_200 0x02 +#define SD_OCP_TIME_400 0x03 +#define SD_OCP_TIME_600 0x04 +#define SD_OCP_TIME_800 0x05 +#define SD_OCP_TIME_1100 0x06 +#define SD_OCP_TIME_MASK 0x07 + +#define OCP_THD_315_417 0x00 +#define OCP_THD_283_783 (0x01 << 6) +#define OCP_THD_244_946 (0x02 << 6) +#define OCP_THD_191_1080 (0x03 << 6) +#define OCP_THD_MASK 0xC0 + +#define MS_OCP_THD_450 0x00 +#define MS_OCP_THD_550 (0x01 << 4) +#define MS_OCP_THD_650 (0x02 << 4) +#define MS_OCP_THD_750 (0x03 << 4) +#define MS_OCP_THD_850 (0x04 << 4) +#define MS_OCP_THD_950 (0x05 << 4) +#define MS_OCP_THD_1050 (0x06 << 4) +#define MS_OCP_THD_1150 (0x07 << 4) +#define MS_OCP_THD_MASK 0x70 + +#define SD_OCP_THD_450 0x00 +#define SD_OCP_THD_550 0x01 +#define SD_OCP_THD_650 0x02 +#define SD_OCP_THD_750 0x03 +#define SD_OCP_THD_850 0x04 +#define SD_OCP_THD_950 0x05 +#define SD_OCP_THD_1050 0x06 +#define SD_OCP_THD_1150 0x07 +#define SD_OCP_THD_MASK 0x07 + +#define FPGA_MS_PULL_CTL_EN 0xEF +#define FPGA_SD_PULL_CTL_EN 0xF7 +#define FPGA_XD_PULL_CTL_EN1 0xFE +#define FPGA_XD_PULL_CTL_EN2 0xFD +#define FPGA_XD_PULL_CTL_EN3 0xFB + +#define FPGA_MS_PULL_CTL_BIT 0x10 +#define FPGA_SD_PULL_CTL_BIT 0x08 + +#define BLINK_EN 0x08 +#define LED_GPIO0 (0 << 4) +#define LED_GPIO1 (1 << 4) +#define LED_GPIO2 (2 << 4) + +#define SDIO_BUS_CTRL 0x01 +#define SDIO_CD_CTRL 0x02 + +#define SSC_RSTB 0x80 +#define SSC_8X_EN 0x40 +#define SSC_FIX_FRAC 0x20 +#define SSC_SEL_1M 0x00 +#define SSC_SEL_2M 0x08 +#define SSC_SEL_4M 0x10 +#define SSC_SEL_8M 0x18 + +#define SSC_DEPTH_MASK 0x07 +#define SSC_DEPTH_DISALBE 0x00 +#define SSC_DEPTH_4M 0x01 +#define SSC_DEPTH_2M 0x02 +#define SSC_DEPTH_1M 0x03 +#define SSC_DEPTH_512K 0x04 +#define SSC_DEPTH_256K 0x05 +#define SSC_DEPTH_128K 0x06 +#define SSC_DEPTH_64K 0x07 + +#define XD_D3_NP 0x00 +#define XD_D3_PD (0x01 << 6) +#define XD_D3_PU (0x02 << 6) +#define XD_D2_NP 0x00 +#define XD_D2_PD (0x01 << 4) +#define XD_D2_PU (0x02 << 4) +#define XD_D1_NP 0x00 +#define XD_D1_PD (0x01 << 2) +#define XD_D1_PU (0x02 << 2) +#define XD_D0_NP 0x00 +#define XD_D0_PD 0x01 +#define XD_D0_PU 0x02 + +#define SD_D7_NP 0x00 +#define SD_D7_PD (0x01 << 4) +#define SD_DAT7_PU (0x02 << 4) +#define SD_CLK_NP 0x00 +#define SD_CLK_PD (0x01 << 2) +#define SD_CLK_PU (0x02 << 2) +#define SD_D5_NP 0x00 +#define SD_D5_PD 0x01 +#define SD_D5_PU 0x02 + +#define MS_D1_NP 0x00 +#define MS_D1_PD (0x01 << 6) +#define MS_D1_PU (0x02 << 6) +#define MS_D2_NP 0x00 +#define MS_D2_PD (0x01 << 4) +#define MS_D2_PU (0x02 << 4) +#define MS_CLK_NP 0x00 +#define MS_CLK_PD (0x01 << 2) +#define MS_CLK_PU (0x02 << 2) +#define MS_D6_NP 0x00 +#define MS_D6_PD 0x01 +#define MS_D6_PU 0x02 + +#define XD_D7_NP 0x00 +#define XD_D7_PD (0x01 << 6) +#define XD_D7_PU (0x02 << 6) +#define XD_D6_NP 0x00 +#define XD_D6_PD (0x01 << 4) +#define XD_D6_PU (0x02 << 4) +#define XD_D5_NP 0x00 +#define XD_D5_PD (0x01 << 2) +#define XD_D5_PU (0x02 << 2) +#define XD_D4_NP 0x00 +#define XD_D4_PD 0x01 +#define XD_D4_PU 0x02 + +#define SD_D6_NP 0x00 +#define SD_D6_PD (0x01 << 6) +#define SD_D6_PU (0x02 << 6) +#define SD_D0_NP 0x00 +#define SD_D0_PD (0x01 << 4) +#define SD_D0_PU (0x02 << 4) +#define SD_D1_NP 0x00 +#define SD_D1_PD 0x01 +#define SD_D1_PU 0x02 + +#define MS_D3_NP 0x00 +#define MS_D3_PD (0x01 << 6) +#define MS_D3_PU (0x02 << 6) +#define MS_D0_NP 0x00 +#define MS_D0_PD (0x01 << 4) +#define MS_D0_PU (0x02 << 4) +#define MS_BS_NP 0x00 +#define MS_BS_PD (0x01 << 2) +#define MS_BS_PU (0x02 << 2) + +#define XD_WP_NP 0x00 +#define XD_WP_PD (0x01 << 6) +#define XD_WP_PU (0x02 << 6) +#define XD_CE_NP 0x00 +#define XD_CE_PD (0x01 << 3) +#define XD_CE_PU (0x02 << 3) +#define XD_CLE_NP 0x00 +#define XD_CLE_PD (0x01 << 1) +#define XD_CLE_PU (0x02 << 1) +#define XD_CD_PD 0x00 +#define XD_CD_PU 0x01 + +#define SD_D4_NP 0x00 +#define SD_D4_PD (0x01 << 6) +#define SD_D4_PU (0x02 << 6) + +#define MS_D7_NP 0x00 +#define MS_D7_PD (0x01 << 6) +#define MS_D7_PU (0x02 << 6) + +#define XD_RDY_NP 0x00 +#define XD_RDY_PD (0x01 << 6) +#define XD_RDY_PU (0x02 << 6) +#define XD_WE_NP 0x00 +#define XD_WE_PD (0x01 << 4) +#define XD_WE_PU (0x02 << 4) +#define XD_RE_NP 0x00 +#define XD_RE_PD (0x01 << 2) +#define XD_RE_PU (0x02 << 2) +#define XD_ALE_NP 0x00 +#define XD_ALE_PD 0x01 +#define XD_ALE_PU 0x02 + +#define SD_D3_NP 0x00 +#define SD_D3_PD (0x01 << 4) +#define SD_D3_PU (0x02 << 4) +#define SD_D2_NP 0x00 +#define SD_D2_PD (0x01 << 2) +#define SD_D2_PU (0x02 << 2) + +#define MS_INS_PD 0x00 +#define MS_INS_PU (0x01 << 7) +#define SD_WP_NP 0x00 +#define SD_WP_PD (0x01 << 5) +#define SD_WP_PU (0x02 << 5) +#define SD_CD_PD 0x00 +#define SD_CD_PU (0x01 << 4) +#define SD_CMD_NP 0x00 +#define SD_CMD_PD (0x01 << 2) +#define SD_CMD_PU (0x02 << 2) + +#define MS_D5_NP 0x00 +#define MS_D5_PD (0x01 << 2) +#define MS_D5_PU (0x02 << 2) +#define MS_D4_NP 0x00 +#define MS_D4_PD 0x01 +#define MS_D4_PU 0x02 + +#define FORCE_PM_CLOCK 0x10 +#define EN_CLOCK_PM 0x01 + +#define HOST_ENTER_S3 0x02 +#define HOST_ENTER_S1 0x01 + +#define AUX_PWR_DETECTED 0x01 + +#define PHY_DEBUG_MODE 0x01 + +#define SPI_COMMAND_BIT_8 0xE0 +#define SPI_ADDRESS_BIT_24 0x17 +#define SPI_ADDRESS_BIT_32 0x1F + +#define SPI_TRANSFER0_START 0x80 +#define SPI_TRANSFER0_END 0x40 +#define SPI_C_MODE0 0x00 +#define SPI_CA_MODE0 0x01 +#define SPI_CDO_MODE0 0x02 +#define SPI_CDI_MODE0 0x03 +#define SPI_CADO_MODE0 0x04 +#define SPI_CADI_MODE0 0x05 +#define SPI_POLLING_MODE0 0x06 + +#define SPI_TRANSFER1_START 0x80 +#define SPI_TRANSFER1_END 0x40 +#define SPI_DO_MODE1 0x00 +#define SPI_DI_MODE1 0x01 + +#define CS_POLARITY_HIGH 0x40 +#define CS_POLARITY_LOW 0x00 +#define DTO_MSB_FIRST 0x00 +#define DTO_LSB_FIRST 0x20 +#define SPI_MASTER 0x00 +#define SPI_SLAVE 0x10 +#define SPI_MODE0 0x00 +#define SPI_MODE1 0x04 +#define SPI_MODE2 0x08 +#define SPI_MODE3 0x0C +#define SPI_MANUAL 0x00 +#define SPI_HALF_AUTO 0x01 +#define SPI_AUTO 0x02 +#define SPI_EEPROM_AUTO 0x03 + +#define EDO_TIMING_MASK 0x03 +#define SAMPLE_RISING 0x00 +#define SAMPLE_DELAY_HALF 0x01 +#define SAMPLE_DELAY_ONE 0x02 +#define SAPMLE_DELAY_ONE_HALF 0x03 +#define TCS_MASK 0x0C + +#define NOT_BYPASS_SD 0x02 +#define DISABLE_SDIO_FUNC 0x04 +#define SELECT_1LUN 0x08 + +#define PWR_GATE_EN 0x01 +#define LDO3318_PWR_MASK 0x06 +#define LDO_ON 0x00 +#define LDO_SUSPEND 0x04 +#define LDO_OFF 0x06 + +#define SD_CFG1 0xFDA0 +#define SD_CFG2 0xFDA1 +#define SD_CFG3 0xFDA2 +#define SD_STAT1 0xFDA3 +#define SD_STAT2 0xFDA4 +#define SD_BUS_STAT 0xFDA5 +#define SD_PAD_CTL 0xFDA6 +#define SD_SAMPLE_POINT_CTL 0xFDA7 +#define SD_PUSH_POINT_CTL 0xFDA8 +#define SD_CMD0 0xFDA9 +#define SD_CMD1 0xFDAA +#define SD_CMD2 0xFDAB +#define SD_CMD3 0xFDAC +#define SD_CMD4 0xFDAD +#define SD_CMD5 0xFDAE +#define SD_BYTE_CNT_L 0xFDAF +#define SD_BYTE_CNT_H 0xFDB0 +#define SD_BLOCK_CNT_L 0xFDB1 +#define SD_BLOCK_CNT_H 0xFDB2 +#define SD_TRANSFER 0xFDB3 +#define SD_CMD_STATE 0xFDB5 +#define SD_DATA_STATE 0xFDB6 + +#define DCM_DRP_CTL 0xFC23 +#define DCM_DRP_TRIG 0xFC24 +#define DCM_DRP_CFG 0xFC25 +#define DCM_DRP_WR_DATA_L 0xFC26 +#define DCM_DRP_WR_DATA_H 0xFC27 +#define DCM_DRP_RD_DATA_L 0xFC28 +#define DCM_DRP_RD_DATA_H 0xFC29 +#define SD_VPCLK0_CTL 0xFC2A +#define SD_VPCLK1_CTL 0xFC2B +#define SD_DCMPS0_CTL 0xFC2C +#define SD_DCMPS1_CTL 0xFC2D +#define SD_VPTX_CTL SD_VPCLK0_CTL +#define SD_VPRX_CTL SD_VPCLK1_CTL +#define SD_DCMPS_TX_CTL SD_DCMPS0_CTL +#define SD_DCMPS_RX_CTL SD_DCMPS1_CTL + +#define CARD_CLK_SOURCE 0xFC2E + +#define CARD_PWR_CTL 0xFD50 +#define CARD_CLK_SWITCH 0xFD51 +#define CARD_SHARE_MODE 0xFD52 +#define CARD_DRIVE_SEL 0xFD53 +#define CARD_STOP 0xFD54 +#define CARD_OE 0xFD55 +#define CARD_AUTO_BLINK 0xFD56 +#define CARD_GPIO_DIR 0xFD57 +#define CARD_GPIO 0xFD58 + +#define CARD_DATA_SOURCE 0xFD5B +#define CARD_SELECT 0xFD5C +#define SD30_DRIVE_SEL 0xFD5E + +#define CARD_CLK_EN 0xFD69 + +#define SDIO_CTRL 0xFD6B + +#define FPDCTL 0xFC00 +#define PDINFO 0xFC01 + +#define CLK_CTL 0xFC02 +#define CLK_DIV 0xFC03 +#define CLK_SEL 0xFC04 + +#define SSC_DIV_N_0 0xFC0F +#define SSC_DIV_N_1 0xFC10 + +#define RCCTL 0xFC14 + +#define FPGA_PULL_CTL 0xFC1D + +#define CARD_PULL_CTL1 0xFD60 +#define CARD_PULL_CTL2 0xFD61 +#define CARD_PULL_CTL3 0xFD62 +#define CARD_PULL_CTL4 0xFD63 +#define CARD_PULL_CTL5 0xFD64 +#define CARD_PULL_CTL6 0xFD65 + +#define IRQEN0 0xFE20 +#define IRQSTAT0 0xFE21 +#define IRQEN1 0xFE22 +#define IRQSTAT1 0xFE23 +#define TLPRIEN 0xFE24 +#define TLPRISTAT 0xFE25 +#define TLPTIEN 0xFE26 +#define TLPTISTAT 0xFE27 +#define DMATC0 0xFE28 +#define DMATC1 0xFE29 +#define DMATC2 0xFE2A +#define DMATC3 0xFE2B +#define DMACTL 0xFE2C +#define BCTL 0xFE2D +#define RBBC0 0xFE2E +#define RBBC1 0xFE2F +#define RBDAT 0xFE30 +#define RBCTL 0xFE34 +#define CFGADDR0 0xFE35 +#define CFGADDR1 0xFE36 +#define CFGDATA0 0xFE37 +#define CFGDATA1 0xFE38 +#define CFGDATA2 0xFE39 +#define CFGDATA3 0xFE3A +#define CFGRWCTL 0xFE3B +#define PHYRWCTL 0xFE3C +#define PHYDATA0 0xFE3D +#define PHYDATA1 0xFE3E +#define PHYADDR 0xFE3F +#define MSGRXDATA0 0xFE40 +#define MSGRXDATA1 0xFE41 +#define MSGRXDATA2 0xFE42 +#define MSGRXDATA3 0xFE43 +#define MSGTXDATA0 0xFE44 +#define MSGTXDATA1 0xFE45 +#define MSGTXDATA2 0xFE46 +#define MSGTXDATA3 0xFE47 +#define MSGTXCTL 0xFE48 +#define PETXCFG 0xFE49 + +#define CDRESUMECTL 0xFE52 +#define WAKE_SEL_CTL 0xFE54 +#define PME_FORCE_CTL 0xFE56 +#define ASPM_FORCE_CTL 0xFE57 +#define PM_CLK_FORCE_CTL 0xFE58 +#define PERST_GLITCH_WIDTH 0xFE5C +#define CHANGE_LINK_STATE 0xFE5B +#define RESET_LOAD_REG 0xFE5E +#define HOST_SLEEP_STATE 0xFE60 +#define MAIN_PWR_OFF_CTL 0xFE70 /* RTS5208 */ +#define SDIO_CFG 0xFE70 /* RTS5209 */ + +#define NFTS_TX_CTRL 0xFE72 + +#define PWR_GATE_CTRL 0xFE75 +#define PWD_SUSPEND_EN 0xFE76 + +#define EFUSE_CONTENT 0xFE5F + +#define XD_INIT 0xFD10 +#define XD_DTCTL 0xFD11 +#define XD_CTL 0xFD12 +#define XD_TRANSFER 0xFD13 +#define XD_CFG 0xFD14 +#define XD_ADDRESS0 0xFD15 +#define XD_ADDRESS1 0xFD16 +#define XD_ADDRESS2 0xFD17 +#define XD_ADDRESS3 0xFD18 +#define XD_ADDRESS4 0xFD19 +#define XD_DAT 0xFD1A +#define XD_PAGE_CNT 0xFD1B +#define XD_PAGE_STATUS 0xFD1C +#define XD_BLOCK_STATUS 0xFD1D +#define XD_BLOCK_ADDR1_L 0xFD1E +#define XD_BLOCK_ADDR1_H 0xFD1F +#define XD_BLOCK_ADDR2_L 0xFD20 +#define XD_BLOCK_ADDR2_H 0xFD21 +#define XD_BYTE_CNT_L 0xFD22 +#define XD_BYTE_CNT_H 0xFD23 +#define XD_PARITY 0xFD24 +#define XD_ECC_BIT1 0xFD25 +#define XD_ECC_BYTE1 0xFD26 +#define XD_ECC_BIT2 0xFD27 +#define XD_ECC_BYTE2 0xFD28 +#define XD_RESERVED0 0xFD29 +#define XD_RESERVED1 0xFD2A +#define XD_RESERVED2 0xFD2B +#define XD_RESERVED3 0xFD2C +#define XD_CHK_DATA_STATUS 0xFD2D +#define XD_CATCTL 0xFD2E + +#define MS_CFG 0xFD40 +#define MS_TPC 0xFD41 +#define MS_TRANS_CFG 0xFD42 +#define MS_TRANSFER 0xFD43 +#define MS_INT_REG 0xFD44 +#define MS_BYTE_CNT 0xFD45 +#define MS_SECTOR_CNT_L 0xFD46 +#define MS_SECTOR_CNT_H 0xFD47 +#define MS_DBUS_H 0xFD48 + +#define SSC_CTL1 0xFC11 +#define SSC_CTL2 0xFC12 + +#define OCPCTL 0xFC15 +#define OCPSTAT 0xFC16 +#define OCPCLR 0xFC17 /* 5208 */ +#define OCPGLITCH 0xFC17 /* 5209 */ +#define OCPPARA1 0xFC18 +#define OCPPARA2 0xFC19 + +#define EFUSE_OP 0xFC20 +#define EFUSE_CTRL 0xFC21 +#define EFUSE_DATA 0xFC22 + +#define SPI_COMMAND 0xFD80 +#define SPI_ADDR0 0xFD81 +#define SPI_ADDR1 0xFD82 +#define SPI_ADDR2 0xFD83 +#define SPI_ADDR3 0xFD84 +#define SPI_CA_NUMBER 0xFD85 +#define SPI_LENGTH0 0xFD86 +#define SPI_LENGTH1 0xFD87 +#define SPI_DATA 0xFD88 +#define SPI_DATA_NUMBER 0xFD89 +#define SPI_TRANSFER0 0xFD90 +#define SPI_TRANSFER1 0xFD91 +#define SPI_CONTROL 0xFD92 +#define SPI_SIG 0xFD93 +#define SPI_TCTL 0xFD94 +#define SPI_SLAVE_NUM 0xFD95 +#define SPI_CLK_DIVIDER0 0xFD96 +#define SPI_CLK_DIVIDER1 0xFD97 + +#define SRAM_BASE 0xE600 +#define RBUF_BASE 0xF400 +#define PPBUF_BASE1 0xF800 +#define PPBUF_BASE2 0xFA00 +#define IMAGE_FLAG_ADDR0 0xCE80 +#define IMAGE_FLAG_ADDR1 0xCE81 + +#define READ_OP 1 +#define WRITE_OP 2 + +#define LCTLR 0x80 + +#define POLLING_WAIT_CNT 1 +#define IDLE_MAX_COUNT 10 +#define SDIO_IDLE_COUNT 10 + +#define DEBOUNCE_CNT 5 + +void do_remaining_work(struct rtsx_chip *chip); +void try_to_switch_sdio_ctrl(struct rtsx_chip *chip); +void do_reset_sd_card(struct rtsx_chip *chip); +void do_reset_xd_card(struct rtsx_chip *chip); +void do_reset_ms_card(struct rtsx_chip *chip); +void rtsx_power_off_card(struct rtsx_chip *chip); +void rtsx_release_cards(struct rtsx_chip *chip); +void rtsx_reset_cards(struct rtsx_chip *chip); +void rtsx_reinit_cards(struct rtsx_chip *chip, int reset_chip); +void rtsx_init_cards(struct rtsx_chip *chip); +int switch_ssc_clock(struct rtsx_chip *chip, int clk); +int switch_normal_clock(struct rtsx_chip *chip, int clk); +int enable_card_clock(struct rtsx_chip *chip, u8 card); +int disable_card_clock(struct rtsx_chip *chip, u8 card); +int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 sec_addr, u16 sec_cnt); +void trans_dma_enable(enum dma_data_direction dir, struct rtsx_chip *chip, u32 byte_cnt, u8 pack_size); +void toggle_gpio(struct rtsx_chip *chip, u8 gpio); +void turn_on_led(struct rtsx_chip *chip, u8 gpio); +void turn_off_led(struct rtsx_chip *chip, u8 gpio); + +int card_share_mode(struct rtsx_chip *chip, int card); +int select_card(struct rtsx_chip *chip, int card); +int detect_card_cd(struct rtsx_chip *chip, int card); +int check_card_exist(struct rtsx_chip *chip, unsigned int lun); +int check_card_ready(struct rtsx_chip *chip, unsigned int lun); +int check_card_wp(struct rtsx_chip *chip, unsigned int lun); +int check_card_fail(struct rtsx_chip *chip, unsigned int lun); +int check_card_ejected(struct rtsx_chip *chip, unsigned int lun); +void eject_card(struct rtsx_chip *chip, unsigned int lun); +u8 get_lun_card(struct rtsx_chip *chip, unsigned int lun); + +static inline u32 get_card_size(struct rtsx_chip *chip, unsigned int lun) +{ +#ifdef SUPPORT_SD_LOCK + struct sd_info *sd_card = &(chip->sd_card); + + if ((get_lun_card(chip, lun) == SD_CARD) && (sd_card->sd_lock_status & SD_LOCKED)) { + return 0; + } else { + return chip->capacity[lun]; + } +#else + return chip->capacity[lun]; +#endif +} + +static inline int switch_clock(struct rtsx_chip *chip, int clk) +{ + int retval = 0; + + if (chip->asic_code) { + retval = switch_ssc_clock(chip, clk); + } else { + retval = switch_normal_clock(chip, clk); + } + + return retval; +} + +int card_power_on(struct rtsx_chip *chip, u8 card); +int card_power_off(struct rtsx_chip *chip, u8 card); + +static inline int card_power_off_all(struct rtsx_chip *chip) +{ + RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0x0F, 0x0F); + + return STATUS_SUCCESS; +} + +static inline void rtsx_clear_xd_error(struct rtsx_chip *chip) +{ + rtsx_write_register(chip, CARD_STOP, XD_STOP | XD_CLR_ERR, XD_STOP | XD_CLR_ERR); +} + +static inline void rtsx_clear_sd_error(struct rtsx_chip *chip) +{ + rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR); +} + +static inline void rtsx_clear_ms_error(struct rtsx_chip *chip) +{ + rtsx_write_register(chip, CARD_STOP, MS_STOP | MS_CLR_ERR, MS_STOP | MS_CLR_ERR); +} + +static inline void rtsx_clear_spi_error(struct rtsx_chip *chip) +{ + rtsx_write_register(chip, CARD_STOP, SPI_STOP | SPI_CLR_ERR, SPI_STOP | SPI_CLR_ERR); +} + +#ifdef SUPPORT_SDIO_ASPM +void dynamic_configure_sdio_aspm(struct rtsx_chip *chip); +#endif + +#endif /* __REALTEK_RTSX_CARD_H */ diff --git a/drivers/staging/rts_pstor/rtsx_chip.c b/drivers/staging/rts_pstor/rtsx_chip.c new file mode 100644 index 000000000000..a4d8eb2abd53 --- /dev/null +++ b/drivers/staging/rts_pstor/rtsx_chip.c @@ -0,0 +1,2337 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include +#include +#include +#include + +#include "rtsx.h" +#include "rtsx_transport.h" +#include "rtsx_scsi.h" +#include "rtsx_card.h" +#include "rtsx_chip.h" +#include "rtsx_sys.h" +#include "general.h" + +#include "sd.h" +#include "xd.h" +#include "ms.h" + +static void rtsx_calibration(struct rtsx_chip *chip) +{ + rtsx_write_phy_register(chip, 0x1B, 0x135E); + wait_timeout(10); + rtsx_write_phy_register(chip, 0x00, 0x0280); + rtsx_write_phy_register(chip, 0x01, 0x7112); + rtsx_write_phy_register(chip, 0x01, 0x7110); + rtsx_write_phy_register(chip, 0x01, 0x7112); + rtsx_write_phy_register(chip, 0x01, 0x7113); + rtsx_write_phy_register(chip, 0x00, 0x0288); +} + +void rtsx_disable_card_int(struct rtsx_chip *chip) +{ + u32 reg = rtsx_readl(chip, RTSX_BIER); + + reg &= ~(XD_INT_EN | SD_INT_EN | MS_INT_EN); + rtsx_writel(chip, RTSX_BIER, reg); +} + +void rtsx_enable_card_int(struct rtsx_chip *chip) +{ + u32 reg = rtsx_readl(chip, RTSX_BIER); + int i; + + for (i = 0; i <= chip->max_lun; i++) { + if (chip->lun2card[i] & XD_CARD) + reg |= XD_INT_EN; + if (chip->lun2card[i] & SD_CARD) + reg |= SD_INT_EN; + if (chip->lun2card[i] & MS_CARD) + reg |= MS_INT_EN; + } + if (chip->hw_bypass_sd) + reg &= ~((u32)SD_INT_EN); + + rtsx_writel(chip, RTSX_BIER, reg); +} + +void rtsx_enable_bus_int(struct rtsx_chip *chip) +{ + u32 reg = 0; +#ifndef DISABLE_CARD_INT + int i; +#endif + + reg = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN; + +#ifndef DISABLE_CARD_INT + for (i = 0; i <= chip->max_lun; i++) { + RTSX_DEBUGP("lun2card[%d] = 0x%02x\n", i, chip->lun2card[i]); + + if (chip->lun2card[i] & XD_CARD) + reg |= XD_INT_EN; + if (chip->lun2card[i] & SD_CARD) + reg |= SD_INT_EN; + if (chip->lun2card[i] & MS_CARD) + reg |= MS_INT_EN; + } + if (chip->hw_bypass_sd) + reg &= ~((u32)SD_INT_EN); +#endif + + if (chip->ic_version >= IC_VER_C) + reg |= DELINK_INT_EN; +#ifdef SUPPORT_OCP + if (CHECK_PID(chip, 0x5209)) { + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + reg |= MS_OC_INT_EN | SD_OC_INT_EN; + } else { + reg |= SD_OC_INT_EN; + } + } else { + reg |= OC_INT_EN; + } +#endif + if (!chip->adma_mode) + reg |= DATA_DONE_INT_EN; + + /* Enable Bus Interrupt */ + rtsx_writel(chip, RTSX_BIER, reg); + + RTSX_DEBUGP("RTSX_BIER: 0x%08x\n", reg); +} + +void rtsx_disable_bus_int(struct rtsx_chip *chip) +{ + rtsx_writel(chip, RTSX_BIER, 0); +} + +static int rtsx_pre_handle_sdio_old(struct rtsx_chip *chip) +{ + if (chip->ignore_sd && CHK_SDIO_EXIST(chip)) { + if (chip->asic_code) { + RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, + MS_INS_PU | SD_WP_PU | SD_CD_PU | SD_CMD_PU); + } else { + RTSX_WRITE_REG(chip, FPGA_PULL_CTL, 0xFF, FPGA_SD_PULL_CTL_EN); + } + RTSX_WRITE_REG(chip, CARD_SHARE_MODE, 0xFF, CARD_SHARE_48_SD); + + /* Enable SDIO internal clock */ + RTSX_WRITE_REG(chip, 0xFF2C, 0x01, 0x01); + + RTSX_WRITE_REG(chip, SDIO_CTRL, 0xFF, SDIO_BUS_CTRL | SDIO_CD_CTRL); + + chip->sd_int = 1; + chip->sd_io = 1; + } else { + chip->need_reset |= SD_CARD; + } + + return STATUS_SUCCESS; +} + +#ifdef HW_AUTO_SWITCH_SD_BUS +static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip) +{ + u8 tmp; + int sw_bypass_sd = 0; + int retval; + + if (chip->driver_first_load) { + if (CHECK_PID(chip, 0x5288)) { + RTSX_READ_REG(chip, 0xFE5A, &tmp); + if (tmp & 0x08) + sw_bypass_sd = 1; + } else if (CHECK_PID(chip, 0x5208)) { + RTSX_READ_REG(chip, 0xFE70, &tmp); + if (tmp & 0x80) + sw_bypass_sd = 1; + } else if (CHECK_PID(chip, 0x5209)) { + RTSX_READ_REG(chip, SDIO_CFG, &tmp); + if (tmp & SDIO_BUS_AUTO_SWITCH) + sw_bypass_sd = 1; + } + } else { + if (chip->sdio_in_charge) + sw_bypass_sd = 1; + } + RTSX_DEBUGP("chip->sdio_in_charge = %d\n", chip->sdio_in_charge); + RTSX_DEBUGP("chip->driver_first_load = %d\n", chip->driver_first_load); + RTSX_DEBUGP("sw_bypass_sd = %d\n", sw_bypass_sd); + + if (sw_bypass_sd) { + u8 cd_toggle_mask = 0; + + RTSX_READ_REG(chip, TLPTISTAT, &tmp); + if (CHECK_PID(chip, 0x5209)) { + cd_toggle_mask = 0x10; + } else { + cd_toggle_mask = 0x08; + } + if (tmp & cd_toggle_mask) { + /* Disable sdio_bus_auto_switch */ + if (CHECK_PID(chip, 0x5288)) { + RTSX_WRITE_REG(chip, 0xFE5A, 0x08, 0x00); + } else if (CHECK_PID(chip, 0x5208)) { + RTSX_WRITE_REG(chip, 0xFE70, 0x80, 0x00); + } else { + RTSX_WRITE_REG(chip, SDIO_CFG, SDIO_BUS_AUTO_SWITCH, 0); + } + RTSX_WRITE_REG(chip, TLPTISTAT, 0xFF, tmp); + + chip->need_reset |= SD_CARD; + } else { + RTSX_DEBUGP("Chip inserted with SDIO!\n"); + + if (chip->asic_code) { + retval = sd_pull_ctl_enable(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + RTSX_WRITE_REG(chip, FPGA_PULL_CTL, FPGA_SD_PULL_CTL_BIT | 0x20, 0); + } + retval = card_share_mode(chip, SD_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + /* Enable sdio_bus_auto_switch */ + if (CHECK_PID(chip, 0x5288)) { + RTSX_WRITE_REG(chip, 0xFE5A, 0x08, 0x08); + } else if (CHECK_PID(chip, 0x5208)) { + RTSX_WRITE_REG(chip, 0xFE70, 0x80, 0x80); + } else { + RTSX_WRITE_REG(chip, SDIO_CFG, + SDIO_BUS_AUTO_SWITCH, SDIO_BUS_AUTO_SWITCH); + } + chip->chip_insert_with_sdio = 1; + chip->sd_io = 1; + } + } else { + if (CHECK_PID(chip, 0x5209)) { + RTSX_WRITE_REG(chip, TLPTISTAT, 0x10, 0x10); + } else { + RTSX_WRITE_REG(chip, TLPTISTAT, 0x08, 0x08); + } + chip->need_reset |= SD_CARD; + } + + return STATUS_SUCCESS; +} +#endif + +int rtsx_reset_chip(struct rtsx_chip *chip) +{ + int retval; + + rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr); + + rtsx_disable_aspm(chip); + + if (CHECK_PID(chip, 0x5209) && chip->asic_code) { + u16 val; + + /* optimize PHY */ + retval = rtsx_write_phy_register(chip, 0x00, 0xB966); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + retval = rtsx_write_phy_register(chip, 0x01, 0x713F); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + retval = rtsx_write_phy_register(chip, 0x03, 0xA549); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + retval = rtsx_write_phy_register(chip, 0x06, 0xB235); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + retval = rtsx_write_phy_register(chip, 0x07, 0xEF40); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + retval = rtsx_write_phy_register(chip, 0x1E, 0xF8EB); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + retval = rtsx_write_phy_register(chip, 0x19, 0xFE6C); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + wait_timeout(1); + retval = rtsx_write_phy_register(chip, 0x0A, 0x05C0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = rtsx_write_cfg_dw(chip, 1, 0x110, 0xFFFF, 0xFFFF); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = rtsx_read_phy_register(chip, 0x08, &val); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + RTSX_DEBUGP("Read from phy 0x08: 0x%04x\n", val); + + if (chip->phy_voltage) { + chip->phy_voltage &= 0x3F; + RTSX_DEBUGP("chip->phy_voltage = 0x%x\n", chip->phy_voltage); + val &= ~0x3F; + val |= chip->phy_voltage; + RTSX_DEBUGP("Write to phy 0x08: 0x%04x\n", val); + retval = rtsx_write_phy_register(chip, 0x08, val); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + chip->phy_voltage = (u8)(val & 0x3F); + RTSX_DEBUGP("Default, chip->phy_voltage = 0x%x\n", chip->phy_voltage); + } + } + + RTSX_WRITE_REG(chip, HOST_SLEEP_STATE, 0x03, 0x00); + + /* Disable card clock */ + RTSX_WRITE_REG(chip, CARD_CLK_EN, 0x1E, 0); + +#ifdef SUPPORT_OCP + /* SSC power on, OCD power on */ + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, 0); + } else { + RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, MS_OC_POWER_DOWN); + } + if (CHECK_PID(chip, 0x5209)) { + RTSX_WRITE_REG(chip, OCPPARA1, SD_OCP_TIME_MASK | MS_OCP_TIME_MASK, + SD_OCP_TIME_800 | MS_OCP_TIME_800); + RTSX_WRITE_REG(chip, OCPPARA2, SD_OCP_THD_MASK | MS_OCP_THD_MASK, + chip->sd_400mA_ocp_thd | (chip->ms_ocp_thd << 4)); + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + RTSX_WRITE_REG(chip, OCPGLITCH, SD_OCP_GLITCH_MASK | MS_OCP_GLITCH_MASK, + SD_OCP_GLITCH_10000 | MS_OCP_GLITCH_10000); + } else { + RTSX_WRITE_REG(chip, OCPGLITCH, SD_OCP_GLITCH_MASK, SD_OCP_GLITCH_10000); + } + RTSX_WRITE_REG(chip, OCPCTL, 0xFF, + SD_OCP_INT_EN | SD_DETECT_EN | MS_OCP_INT_EN | MS_DETECT_EN); + } else { + RTSX_WRITE_REG(chip, OCPPARA1, OCP_TIME_MASK, OCP_TIME_800); + RTSX_WRITE_REG(chip, OCPPARA2, OCP_THD_MASK, OCP_THD_244_946); + RTSX_WRITE_REG(chip, OCPCTL, 0xFF, CARD_OC_INT_EN | CARD_DETECT_EN); + } +#else + /* OC power down */ + RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, OC_POWER_DOWN); +#endif + + if (!CHECK_PID(chip, 0x5288)) { + RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0xFF, 0x03); + } + + /* Turn off LED */ + RTSX_WRITE_REG(chip, CARD_GPIO, 0xFF, 0x03); + + /* Reset delink mode */ + RTSX_WRITE_REG(chip, CHANGE_LINK_STATE, 0x0A, 0); + + /* Card driving select */ + RTSX_WRITE_REG(chip, CARD_DRIVE_SEL, 0xFF, chip->card_drive_sel); + if (CHECK_PID(chip, 0x5209)) { + RTSX_WRITE_REG(chip, SD30_DRIVE_SEL, 0x07, chip->sd30_drive_sel_3v3); + } + +#ifdef LED_AUTO_BLINK + RTSX_WRITE_REG(chip, CARD_AUTO_BLINK, 0xFF, + LED_BLINK_SPEED | BLINK_EN | LED_GPIO0); +#endif + + if (chip->asic_code) { + /* Enable SSC Clock */ + RTSX_WRITE_REG(chip, SSC_CTL1, 0xFF, SSC_8X_EN | SSC_SEL_4M); + RTSX_WRITE_REG(chip, SSC_CTL2, 0xFF, 0x12); + } + + /* Disable cd_pwr_save (u_force_rst_core_en=0, u_cd_rst_core_en=0) + 0xFE5B + bit[1] u_cd_rst_core_en rst_value = 0 + bit[2] u_force_rst_core_en rst_value = 0 + bit[5] u_mac_phy_rst_n_dbg rst_value = 1 + bit[4] u_non_sticky_rst_n_dbg rst_value = 0 + */ + RTSX_WRITE_REG(chip, CHANGE_LINK_STATE, 0x16, 0x10); + + /* Enable ASPM */ + if (chip->aspm_l0s_l1_en) { + if (chip->dynamic_aspm) { + if (CHK_SDIO_EXIST(chip)) { + if (CHECK_PID(chip, 0x5209)) { + retval = rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF, chip->aspm_l0s_l1_en); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else if (CHECK_PID(chip, 0x5288)) { + retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + } + } else { + if (CHECK_PID(chip, 0x5208)) { + RTSX_WRITE_REG(chip, ASPM_FORCE_CTL, 0xFF, 0x3F); + } + + retval = rtsx_write_config_byte(chip, LCTLR, chip->aspm_l0s_l1_en); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + chip->aspm_level[0] = chip->aspm_l0s_l1_en; + if (CHK_SDIO_EXIST(chip)) { + chip->aspm_level[1] = chip->aspm_l0s_l1_en; + if (CHECK_PID(chip, 0x5288)) { + retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en); + } else { + retval = rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF, chip->aspm_l0s_l1_en); + } + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + chip->aspm_enabled = 1; + } + } else { + if (chip->asic_code && CHECK_PID(chip, 0x5208)) { + retval = rtsx_write_phy_register(chip, 0x07, 0x0129); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + retval = rtsx_write_config_byte(chip, LCTLR, chip->aspm_l0s_l1_en); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = rtsx_write_config_byte(chip, 0x81, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (CHK_SDIO_EXIST(chip)) { + if (CHECK_PID(chip, 0x5288)) { + retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF00, 0x0100); + } else { + retval = rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF00, 0x0100); + } + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (CHECK_PID(chip, 0x5209)) { + retval = rtsx_write_cfg_dw(chip, 0, 0x70C, 0xFF000000, 0x5B); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (CHECK_PID(chip, 0x5288)) { + if (!CHK_SDIO_EXIST(chip)) { + retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFFFF, 0x0103); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + retval = rtsx_write_cfg_dw(chip, 2, 0x84, 0xFF, 0x03); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + RTSX_WRITE_REG(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT); + + RTSX_WRITE_REG(chip, PERST_GLITCH_WIDTH, 0xFF, 0x80); + + if (CHECK_PID(chip, 0x5209)) { + RTSX_WRITE_REG(chip, PWD_SUSPEND_EN, 0xFF, 0xFF); + RTSX_WRITE_REG(chip, PWR_GATE_CTRL, PWR_GATE_EN, PWR_GATE_EN); + } + + /* Enable PCIE interrupt */ + if (chip->asic_code) { + if (CHECK_PID(chip, 0x5208)) { + if (chip->phy_debug_mode) { + RTSX_WRITE_REG(chip, CDRESUMECTL, 0x77, 0); + rtsx_disable_bus_int(chip); + } else { + rtsx_enable_bus_int(chip); + } + + if (chip->ic_version >= IC_VER_D) { + u16 reg; + retval = rtsx_read_phy_register(chip, 0x00, ®); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + reg &= 0xFE7F; + reg |= 0x80; + retval = rtsx_write_phy_register(chip, 0x00, reg); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + retval = rtsx_read_phy_register(chip, 0x1C, ®); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + reg &= 0xFFF7; + retval = rtsx_write_phy_register(chip, 0x1C, reg); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (chip->driver_first_load && (chip->ic_version < IC_VER_C)) { + rtsx_calibration(chip); + } + } else { + rtsx_enable_bus_int(chip); + } + } else { + rtsx_enable_bus_int(chip); + } + +#ifdef HW_INT_WRITE_CLR + if (CHECK_PID(chip, 0x5209)) { + /* Set interrupt write clear */ + RTSX_WRITE_REG(chip, NFTS_TX_CTRL, 0x02, 0); + } +#endif + + chip->need_reset = 0; + + chip->int_reg = rtsx_readl(chip, RTSX_BIPR); +#ifdef HW_INT_WRITE_CLR + if (CHECK_PID(chip, 0x5209)) { + /* Clear interrupt flag */ + rtsx_writel(chip, RTSX_BIPR, chip->int_reg); + } +#endif + if (chip->hw_bypass_sd) + goto NextCard; + RTSX_DEBUGP("In rtsx_reset_chip, chip->int_reg = 0x%x\n", chip->int_reg); + if (chip->int_reg & SD_EXIST) { +#ifdef HW_AUTO_SWITCH_SD_BUS + if (CHECK_PID(chip, 0x5208) && (chip->ic_version < IC_VER_C)) { + retval = rtsx_pre_handle_sdio_old(chip); + } else { + retval = rtsx_pre_handle_sdio_new(chip); + } + RTSX_DEBUGP("chip->need_reset = 0x%x (rtsx_reset_chip)\n", (unsigned int)(chip->need_reset)); +#else /* HW_AUTO_SWITCH_SD_BUS */ + retval = rtsx_pre_handle_sdio_old(chip); +#endif /* HW_AUTO_SWITCH_SD_BUS */ + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + chip->sd_io = 0; + RTSX_WRITE_REG(chip, SDIO_CTRL, SDIO_BUS_CTRL | SDIO_CD_CTRL, 0); + } + +NextCard: + if (chip->int_reg & XD_EXIST) + chip->need_reset |= XD_CARD; + if (chip->int_reg & MS_EXIST) + chip->need_reset |= MS_CARD; + if (chip->int_reg & CARD_EXIST) { + RTSX_WRITE_REG(chip, SSC_CTL1, SSC_RSTB, SSC_RSTB); + } + + RTSX_DEBUGP("In rtsx_init_chip, chip->need_reset = 0x%x\n", (unsigned int)(chip->need_reset)); + + RTSX_WRITE_REG(chip, RCCTL, 0x01, 0x00); + + if (CHECK_PID(chip, 0x5208) || CHECK_PID(chip, 0x5288)) { + /* Turn off main power when entering S3/S4 state */ + RTSX_WRITE_REG(chip, MAIN_PWR_OFF_CTL, 0x03, 0x03); + } + + if (chip->remote_wakeup_en && !chip->auto_delink_en) { + RTSX_WRITE_REG(chip, WAKE_SEL_CTL, 0x07, 0x07); + if (chip->aux_pwr_exist) { + RTSX_WRITE_REG(chip, PME_FORCE_CTL, 0xFF, 0x33); + } + } else { + RTSX_WRITE_REG(chip, WAKE_SEL_CTL, 0x07, 0x04); + RTSX_WRITE_REG(chip, PME_FORCE_CTL, 0xFF, 0x30); + } + + if (CHECK_PID(chip, 0x5208) && (chip->ic_version >= IC_VER_D)) { + RTSX_WRITE_REG(chip, PETXCFG, 0x1C, 0x14); + } else if (CHECK_PID(chip, 0x5209)) { + if (chip->force_clkreq_0) { + RTSX_WRITE_REG(chip, PETXCFG, 0x08, 0x08); + } else { + RTSX_WRITE_REG(chip, PETXCFG, 0x08, 0x00); + } + } + + if (chip->asic_code && CHECK_PID(chip, 0x5208)) { + retval = rtsx_clr_phy_reg_bit(chip, 0x1C, 2); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (chip->ft2_fast_mode) { + RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0xFF, MS_PARTIAL_POWER_ON | SD_PARTIAL_POWER_ON); + udelay(chip->pmos_pwr_on_interval); + RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0xFF, MS_POWER_ON | SD_POWER_ON); + + wait_timeout(200); + } + + /* Reset card */ + rtsx_reset_detected_cards(chip, 0); + + chip->driver_first_load = 0; + + return STATUS_SUCCESS; +} + +static inline int check_sd_speed_prior(u32 sd_speed_prior) +{ + int i, fake_para = 0; + + for (i = 0; i < 4; i++) { + u8 tmp = (u8)(sd_speed_prior >> (i*8)); + if ((tmp < 0x01) || (tmp > 0x04)) { + fake_para = 1; + break; + } + } + + return !fake_para; +} + +static inline int check_sd_current_prior(u32 sd_current_prior) +{ + int i, fake_para = 0; + + for (i = 0; i < 4; i++) { + u8 tmp = (u8)(sd_current_prior >> (i*8)); + if (tmp > 0x03) { + fake_para = 1; + break; + } + } + + return !fake_para; +} + +int rts5209_init(struct rtsx_chip *chip) +{ + int retval; + u32 lval = 0; + u8 val = 0; + + val = rtsx_readb(chip, 0x1C); + if ((val & 0x10) == 0) { + chip->asic_code = 1; + } else { + chip->asic_code = 0; + } + + chip->ic_version = val & 0x0F; + chip->phy_debug_mode = 0; + + chip->aux_pwr_exist = 0; + + chip->ms_power_class_en = 0x03; + + retval = rtsx_read_cfg_dw(chip, 0, 0x724, &lval); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + RTSX_DEBUGP("dw in 0x724: 0x%x\n", lval); + val = (u8)lval; + if (!(val & 0x80)) { + if (val & 0x04) { + SET_SDIO_EXIST(chip); + } else { + CLR_SDIO_EXIST(chip); + } + + if (val & 0x02) { + chip->hw_bypass_sd = 0; + } else { + chip->hw_bypass_sd = 1; + } + } else { + SET_SDIO_EXIST(chip); + chip->hw_bypass_sd = 0; + } + + if (chip->use_hw_setting) { + u8 clk; + + chip->aspm_l0s_l1_en = (val >> 5) & 0x03; + + if (val & 0x08) { + chip->lun_mode = DEFAULT_SINGLE; + } else { + chip->lun_mode = SD_MS_2LUN; + } + + val = (u8)(lval >> 8); + + clk = (val >> 5) & 0x07; + if (clk != 0x07) { + chip->asic_sd_sdr50_clk = 98 - clk * 2; + } + + if (val & 0x10) { + chip->auto_delink_en = 1; + } else { + chip->auto_delink_en = 0; + } + + if (chip->ss_en == 2) { + chip->ss_en = 0; + } else { + if (val & 0x08) { + chip->ss_en = 1; + } else { + chip->ss_en = 0; + } + } + + clk = val & 0x07; + if (clk != 0x07) + chip->asic_ms_hg_clk = (59 - clk) * 2; + + val = (u8)(lval >> 16); + + clk = (val >> 6) & 0x03; + if (clk != 0x03) { + chip->asic_sd_hs_clk = (49 - clk * 2) * 2; + chip->asic_mmc_52m_clk = (49 - clk * 2) * 2; + } + + clk = (val >> 4) & 0x03; + if (clk != 0x03) + chip->asic_sd_ddr50_clk = (48 - clk * 2) * 2; + + if (val & 0x01) { + chip->sdr104_en = 1; + } else { + chip->sdr104_en = 0; + } + if (val & 0x02) { + chip->ddr50_en = 1; + } else { + chip->ddr50_en = 0; + } + if (val & 0x04) { + chip->sdr50_en = 1; + } else { + chip->sdr50_en = 0; + } + + val = (u8)(lval >> 24); + + clk = (val >> 5) & 0x07; + if (clk != 0x07) + chip->asic_sd_sdr104_clk = 206 - clk * 3; + + if (val & 0x10) { + chip->power_down_in_ss = 1; + } else { + chip->power_down_in_ss = 0; + } + + chip->ms_power_class_en = val & 0x03; + } + + if (chip->hp_watch_bios_hotplug && chip->auto_delink_en) { + u8 reg58, reg5b; + + retval = rtsx_read_pci_cfg_byte(0x00, + 0x1C, 0x02, 0x58, ®58); + if (retval < 0) { + return STATUS_SUCCESS; + } + retval = rtsx_read_pci_cfg_byte(0x00, + 0x1C, 0x02, 0x5B, ®5b); + if (retval < 0) { + return STATUS_SUCCESS; + } + + RTSX_DEBUGP("reg58 = 0x%x, reg5b = 0x%x\n", reg58, reg5b); + + if ((reg58 == 0x00) && (reg5b == 0x01)) { + chip->auto_delink_en = 0; + } + } + + return STATUS_SUCCESS; +} + +int rts5208_init(struct rtsx_chip *chip) +{ + int retval; + u16 reg = 0; + u8 val = 0; + + RTSX_WRITE_REG(chip, CLK_SEL, 0x03, 0x03); + RTSX_READ_REG(chip, CLK_SEL, &val); + if (val == 0) { + chip->asic_code = 1; + } else { + chip->asic_code = 0; + } + + if (chip->asic_code) { + retval = rtsx_read_phy_register(chip, 0x1C, ®); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + RTSX_DEBUGP("Value of phy register 0x1C is 0x%x\n", reg); + chip->ic_version = (reg >> 4) & 0x07; + if (reg & PHY_DEBUG_MODE) { + chip->phy_debug_mode = 1; + } else { + chip->phy_debug_mode = 0; + } + } else { + RTSX_READ_REG(chip, 0xFE80, &val); + chip->ic_version = val; + chip->phy_debug_mode = 0; + } + + RTSX_READ_REG(chip, PDINFO, &val); + RTSX_DEBUGP("PDINFO: 0x%x\n", val); + if (val & AUX_PWR_DETECTED) { + chip->aux_pwr_exist = 1; + } else { + chip->aux_pwr_exist = 0; + } + + RTSX_READ_REG(chip, 0xFE50, &val); + if (val & 0x01) { + chip->hw_bypass_sd = 1; + } else { + chip->hw_bypass_sd = 0; + } + + rtsx_read_config_byte(chip, 0x0E, &val); + if (val & 0x80) { + SET_SDIO_EXIST(chip); + } else { + CLR_SDIO_EXIST(chip); + } + + if (chip->use_hw_setting) { + RTSX_READ_REG(chip, CHANGE_LINK_STATE, &val); + if (val & 0x80) { + chip->auto_delink_en = 1; + } else { + chip->auto_delink_en = 0; + } + } + + return STATUS_SUCCESS; +} + +int rts5288_init(struct rtsx_chip *chip) +{ + int retval; + u8 val = 0, max_func; + u32 lval = 0; + + RTSX_WRITE_REG(chip, CLK_SEL, 0x03, 0x03); + RTSX_READ_REG(chip, CLK_SEL, &val); + if (val == 0) { + chip->asic_code = 1; + } else { + chip->asic_code = 0; + } + + chip->ic_version = 0; + chip->phy_debug_mode = 0; + + RTSX_READ_REG(chip, PDINFO, &val); + RTSX_DEBUGP("PDINFO: 0x%x\n", val); + if (val & AUX_PWR_DETECTED) { + chip->aux_pwr_exist = 1; + } else { + chip->aux_pwr_exist = 0; + } + + RTSX_READ_REG(chip, CARD_SHARE_MODE, &val); + RTSX_DEBUGP("CARD_SHARE_MODE: 0x%x\n", val); + if (val & 0x04) { + chip->baro_pkg = QFN; + } else { + chip->baro_pkg = LQFP; + } + + RTSX_READ_REG(chip, 0xFE5A, &val); + if (val & 0x10) { + chip->hw_bypass_sd = 1; + } else { + chip->hw_bypass_sd = 0; + } + + retval = rtsx_read_cfg_dw(chip, 0, 0x718, &lval); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + max_func = (u8)((lval >> 29) & 0x07); + RTSX_DEBUGP("Max function number: %d\n", max_func); + if (max_func == 0x02) { + SET_SDIO_EXIST(chip); + } else { + CLR_SDIO_EXIST(chip); + } + + if (chip->use_hw_setting) { + RTSX_READ_REG(chip, CHANGE_LINK_STATE, &val); + if (val & 0x80) { + chip->auto_delink_en = 1; + } else { + chip->auto_delink_en = 0; + } + + if (CHECK_BARO_PKG(chip, LQFP)) { + chip->lun_mode = SD_MS_1LUN; + } else { + chip->lun_mode = DEFAULT_SINGLE; + } + } + + return STATUS_SUCCESS; +} + +int rtsx_init_chip(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + struct xd_info *xd_card = &(chip->xd_card); + struct ms_info *ms_card = &(chip->ms_card); + int retval; + unsigned int i; + + RTSX_DEBUGP("Vendor ID: 0x%04x, Product ID: 0x%04x\n", + chip->vendor_id, chip->product_id); + + chip->ic_version = 0; + +#ifdef _MSG_TRACE + chip->msg_idx = 0; +#endif + + memset(xd_card, 0, sizeof(struct xd_info)); + memset(sd_card, 0, sizeof(struct sd_info)); + memset(ms_card, 0, sizeof(struct ms_info)); + + chip->xd_reset_counter = 0; + chip->sd_reset_counter = 0; + chip->ms_reset_counter = 0; + + chip->xd_show_cnt = MAX_SHOW_CNT; + chip->sd_show_cnt = MAX_SHOW_CNT; + chip->ms_show_cnt = MAX_SHOW_CNT; + + chip->sd_io = 0; + chip->auto_delink_cnt = 0; + chip->auto_delink_allowed = 1; + rtsx_set_stat(chip, RTSX_STAT_INIT); + + chip->aspm_enabled = 0; + chip->chip_insert_with_sdio = 0; + chip->sdio_aspm = 0; + chip->sdio_idle = 0; + chip->sdio_counter = 0; + chip->cur_card = 0; + chip->phy_debug_mode = 0; + chip->sdio_func_exist = 0; + memset(chip->sdio_raw_data, 0, 12); + + for (i = 0; i < MAX_ALLOWED_LUN_CNT; i++) { + set_sense_type(chip, i, SENSE_TYPE_NO_SENSE); + chip->rw_fail_cnt[i] = 0; + } + + if (!check_sd_speed_prior(chip->sd_speed_prior)) { + chip->sd_speed_prior = 0x01040203; + } + RTSX_DEBUGP("sd_speed_prior = 0x%08x\n", chip->sd_speed_prior); + + if (!check_sd_current_prior(chip->sd_current_prior)) { + chip->sd_current_prior = 0x00010203; + } + RTSX_DEBUGP("sd_current_prior = 0x%08x\n", chip->sd_current_prior); + + if ((chip->sd_ddr_tx_phase > 31) || (chip->sd_ddr_tx_phase < 0)) { + chip->sd_ddr_tx_phase = 0; + } + if ((chip->mmc_ddr_tx_phase > 31) || (chip->mmc_ddr_tx_phase < 0)) { + chip->mmc_ddr_tx_phase = 0; + } + + RTSX_WRITE_REG(chip, FPDCTL, SSC_POWER_DOWN, 0); + wait_timeout(200); + RTSX_WRITE_REG(chip, CLK_DIV, 0x07, 0x07); + RTSX_DEBUGP("chip->use_hw_setting = %d\n", chip->use_hw_setting); + + if (CHECK_PID(chip, 0x5209)) { + retval = rts5209_init(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else if (CHECK_PID(chip, 0x5208)) { + retval = rts5208_init(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else if (CHECK_PID(chip, 0x5288)) { + retval = rts5288_init(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (chip->ss_en == 2) { + chip->ss_en = 0; + } + + RTSX_DEBUGP("chip->asic_code = %d\n", chip->asic_code); + RTSX_DEBUGP("chip->ic_version = 0x%x\n", chip->ic_version); + RTSX_DEBUGP("chip->phy_debug_mode = %d\n", chip->phy_debug_mode); + RTSX_DEBUGP("chip->aux_pwr_exist = %d\n", chip->aux_pwr_exist); + RTSX_DEBUGP("chip->sdio_func_exist = %d\n", chip->sdio_func_exist); + RTSX_DEBUGP("chip->hw_bypass_sd = %d\n", chip->hw_bypass_sd); + RTSX_DEBUGP("chip->aspm_l0s_l1_en = %d\n", chip->aspm_l0s_l1_en); + RTSX_DEBUGP("chip->lun_mode = %d\n", chip->lun_mode); + RTSX_DEBUGP("chip->auto_delink_en = %d\n", chip->auto_delink_en); + RTSX_DEBUGP("chip->ss_en = %d\n", chip->ss_en); + RTSX_DEBUGP("chip->baro_pkg = %d\n", chip->baro_pkg); + + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + chip->card2lun[SD_CARD] = 0; + chip->card2lun[MS_CARD] = 1; + chip->card2lun[XD_CARD] = 0xFF; + chip->lun2card[0] = SD_CARD; + chip->lun2card[1] = MS_CARD; + chip->max_lun = 1; + SET_SDIO_IGNORED(chip); + } else if (CHECK_LUN_MODE(chip, SD_MS_1LUN)) { + chip->card2lun[SD_CARD] = 0; + chip->card2lun[MS_CARD] = 0; + chip->card2lun[XD_CARD] = 0xFF; + chip->lun2card[0] = SD_CARD | MS_CARD; + chip->max_lun = 0; + } else { + chip->card2lun[XD_CARD] = 0; + chip->card2lun[SD_CARD] = 0; + chip->card2lun[MS_CARD] = 0; + chip->lun2card[0] = XD_CARD | SD_CARD | MS_CARD; + chip->max_lun = 0; + } + + retval = rtsx_reset_chip(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +void rtsx_release_chip(struct rtsx_chip *chip) +{ + xd_free_l2p_tbl(chip); + ms_free_l2p_tbl(chip); + chip->card_exist = 0; + chip->card_ready = 0; +} + +#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK) +static inline void rtsx_blink_led(struct rtsx_chip *chip) +{ + if (chip->card_exist && chip->blink_led) { + if (chip->led_toggle_counter < LED_TOGGLE_INTERVAL) { + chip->led_toggle_counter++; + } else { + chip->led_toggle_counter = 0; + toggle_gpio(chip, LED_GPIO); + } + } +} +#endif + +void rtsx_monitor_aspm_config(struct rtsx_chip *chip) +{ + int maybe_support_aspm, reg_changed; + u32 tmp = 0; + u8 reg0 = 0, reg1 = 0; + + maybe_support_aspm = 0; + reg_changed = 0; + rtsx_read_config_byte(chip, LCTLR, ®0); + if (chip->aspm_level[0] != reg0) { + reg_changed = 1; + chip->aspm_level[0] = reg0; + } + if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { + rtsx_read_cfg_dw(chip, 1, 0xC0, &tmp); + reg1 = (u8)tmp; + if (chip->aspm_level[1] != reg1) { + reg_changed = 1; + chip->aspm_level[1] = reg1; + } + + if ((reg0 & 0x03) && (reg1 & 0x03)) { + maybe_support_aspm = 1; + } + } else { + if (reg0 & 0x03) { + maybe_support_aspm = 1; + } + } + + if (reg_changed) { + if (maybe_support_aspm) { + chip->aspm_l0s_l1_en = 0x03; + } + RTSX_DEBUGP("aspm_level[0] = 0x%02x, aspm_level[1] = 0x%02x\n", + chip->aspm_level[0], chip->aspm_level[1]); + + if (chip->aspm_l0s_l1_en) { + chip->aspm_enabled = 1; + } else { + chip->aspm_enabled = 0; + chip->sdio_aspm = 0; + } + rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFF, + 0x30 | chip->aspm_level[0] | (chip->aspm_level[1] << 2)); + } +} + +void rtsx_polling_func(struct rtsx_chip *chip) +{ +#ifdef SUPPORT_SD_LOCK + struct sd_info *sd_card = &(chip->sd_card); +#endif + int ss_allowed; + + if (rtsx_chk_stat(chip, RTSX_STAT_SUSPEND)) + return; + + if (rtsx_chk_stat(chip, RTSX_STAT_DELINK)) + goto Delink_Stage; + + if (chip->polling_config) { + u8 val; + rtsx_read_config_byte(chip, 0, &val); + } + + if (rtsx_chk_stat(chip, RTSX_STAT_SS)) + return; + +#ifdef SUPPORT_OCP + if (chip->ocp_int) { + rtsx_read_register(chip, OCPSTAT, &(chip->ocp_stat)); + + if (CHECK_PID(chip, 0x5209) && + CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + if (chip->ocp_int & SD_OC_INT) + sd_power_off_card3v3(chip); + if (chip->ocp_int & MS_OC_INT) + ms_power_off_card3v3(chip); + } else { + if (chip->card_exist & SD_CARD) { + sd_power_off_card3v3(chip); + } else if (chip->card_exist & MS_CARD) { + ms_power_off_card3v3(chip); + } else if (chip->card_exist & XD_CARD) { + xd_power_off_card3v3(chip); + } + } + + chip->ocp_int = 0; + } +#endif + +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_erase_status) { + if (chip->card_exist & SD_CARD) { + u8 val; + if (CHECK_PID(chip, 0x5209)) { + rtsx_read_register(chip, SD_BUS_STAT, &val); + if (val & SD_DAT0_STATUS) { + sd_card->sd_erase_status = SD_NOT_ERASE; + sd_card->sd_lock_notify = 1; + chip->need_reinit |= SD_CARD; + } + } else { + rtsx_read_register(chip, 0xFD30, &val); + if (val & 0x02) { + sd_card->sd_erase_status = SD_NOT_ERASE; + sd_card->sd_lock_notify = 1; + chip->need_reinit |= SD_CARD; + } + } + } else { + sd_card->sd_erase_status = SD_NOT_ERASE; + } + } +#endif + + rtsx_init_cards(chip); + + if (chip->ss_en) { + ss_allowed = 1; + + if (CHECK_PID(chip, 0x5288)) { + ss_allowed = 0; + } else { + if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { + u32 val; + rtsx_read_cfg_dw(chip, 1, 0x04, &val); + if (val & 0x07) { + ss_allowed = 0; + } + } + } + } else { + ss_allowed = 0; + } + + if (ss_allowed && !chip->sd_io) { + if (rtsx_get_stat(chip) != RTSX_STAT_IDLE) { + chip->ss_counter = 0; + } else { + if (chip->ss_counter < + (chip->ss_idle_period / POLLING_INTERVAL)) { + chip->ss_counter++; + } else { + rtsx_exclusive_enter_ss(chip); + return; + } + } + } + + if (CHECK_PID(chip, 0x5208)) { + rtsx_monitor_aspm_config(chip); + +#ifdef SUPPORT_SDIO_ASPM + if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip) && + chip->aspm_l0s_l1_en && chip->dynamic_aspm) { + if (chip->sd_io) { + dynamic_configure_sdio_aspm(chip); + } else { + if (!chip->sdio_aspm) { + RTSX_DEBUGP("SDIO enter ASPM!\n"); + rtsx_write_register(chip, + ASPM_FORCE_CTL, 0xFC, + 0x30 | (chip->aspm_level[1] << 2)); + chip->sdio_aspm = 1; + } + } + } +#endif + } + + if (chip->idle_counter < IDLE_MAX_COUNT) { + chip->idle_counter++; + } else { + if (rtsx_get_stat(chip) != RTSX_STAT_IDLE) { + RTSX_DEBUGP("Idle state!\n"); + rtsx_set_stat(chip, RTSX_STAT_IDLE); + +#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK) + chip->led_toggle_counter = 0; +#endif + rtsx_force_power_on(chip, SSC_PDCTL); + + turn_off_led(chip, LED_GPIO); + + if (chip->auto_power_down && !chip->card_ready && !chip->sd_io) { + rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); + } + } + } + + switch (rtsx_get_stat(chip)) { + case RTSX_STAT_RUN: +#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK) + rtsx_blink_led(chip); +#endif + do_remaining_work(chip); + break; + + case RTSX_STAT_IDLE: + if (chip->sd_io && !chip->sd_int) { + try_to_switch_sdio_ctrl(chip); + } + rtsx_enable_aspm(chip); + break; + + default: + break; + } + + +#ifdef SUPPORT_OCP + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + #if CONFIG_RTS_PSTOR_DEBUG + if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER | MS_OC_NOW | MS_OC_EVER)) { + RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", chip->ocp_stat); + } + #endif + + if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { + if (chip->card_exist & SD_CARD) { + rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0); + card_power_off(chip, SD_CARD); + chip->card_fail |= SD_CARD; + } + } + if (chip->ocp_stat & (MS_OC_NOW | MS_OC_EVER)) { + if (chip->card_exist & MS_CARD) { + rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0); + card_power_off(chip, MS_CARD); + chip->card_fail |= MS_CARD; + } + } + } else { + if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { + RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", chip->ocp_stat); + if (chip->card_exist & SD_CARD) { + rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0); + chip->card_fail |= SD_CARD; + } else if (chip->card_exist & MS_CARD) { + rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0); + chip->card_fail |= MS_CARD; + } else if (chip->card_exist & XD_CARD) { + rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0); + chip->card_fail |= XD_CARD; + } + card_power_off(chip, SD_CARD); + } + } +#endif + +Delink_Stage: + if (chip->auto_delink_en && chip->auto_delink_allowed && + !chip->card_ready && !chip->card_ejected && !chip->sd_io) { + int enter_L1 = chip->auto_delink_in_L1 && (chip->aspm_l0s_l1_en || chip->ss_en); + int delink_stage1_cnt = chip->delink_stage1_step; + int delink_stage2_cnt = delink_stage1_cnt + chip->delink_stage2_step; + int delink_stage3_cnt = delink_stage2_cnt + chip->delink_stage3_step; + + if (chip->auto_delink_cnt <= delink_stage3_cnt) { + if (chip->auto_delink_cnt == delink_stage1_cnt) { + rtsx_set_stat(chip, RTSX_STAT_DELINK); + + if (chip->asic_code && CHECK_PID(chip, 0x5208)) { + rtsx_set_phy_reg_bit(chip, 0x1C, 2); + } + if (chip->card_exist) { + RTSX_DEBUGP("False card inserted, do force delink\n"); + + if (enter_L1) { + rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1); + } + rtsx_write_register(chip, CHANGE_LINK_STATE, 0x0A, 0x0A); + + if (enter_L1) { + rtsx_enter_L1(chip); + } + + chip->auto_delink_cnt = delink_stage3_cnt + 1; + } else { + RTSX_DEBUGP("No card inserted, do delink\n"); + + if (enter_L1) { + rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1); + } +#ifdef HW_INT_WRITE_CLR + if (CHECK_PID(chip, 0x5209)) { + rtsx_writel(chip, RTSX_BIPR, 0xFFFFFFFF); + RTSX_DEBUGP("RTSX_BIPR: 0x%x\n", rtsx_readl(chip, RTSX_BIPR)); + } +#endif + rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 0x02); + + if (enter_L1) { + rtsx_enter_L1(chip); + } + } + } + + if (chip->auto_delink_cnt == delink_stage2_cnt) { + RTSX_DEBUGP("Try to do force delink\n"); + + if (enter_L1) { + rtsx_exit_L1(chip); + } + + if (chip->asic_code && CHECK_PID(chip, 0x5208)) { + rtsx_set_phy_reg_bit(chip, 0x1C, 2); + } + rtsx_write_register(chip, CHANGE_LINK_STATE, 0x0A, 0x0A); + } + + chip->auto_delink_cnt++; + } + } else { + chip->auto_delink_cnt = 0; + } +} + +void rtsx_undo_delink(struct rtsx_chip *chip) +{ + chip->auto_delink_allowed = 0; + rtsx_write_register(chip, CHANGE_LINK_STATE, 0x0A, 0x00); +} + +/** + * rtsx_stop_cmd - stop command transfer and DMA transfer + * @chip: Realtek's card reader chip + * @card: flash card type + * + * Stop command transfer and DMA transfer. + * This function is called in error handler. + */ +void rtsx_stop_cmd(struct rtsx_chip *chip, int card) +{ + int i; + + for (i = 0; i <= 8; i++) { + int addr = RTSX_HCBAR + i * 4; + u32 reg; + reg = rtsx_readl(chip, addr); + RTSX_DEBUGP("BAR (0x%02x): 0x%08x\n", addr, reg); + } + rtsx_writel(chip, RTSX_HCBCTLR, STOP_CMD); + rtsx_writel(chip, RTSX_HDBCTLR, STOP_DMA); + + for (i = 0; i < 16; i++) { + u16 addr = 0xFE20 + (u16)i; + u8 val; + rtsx_read_register(chip, addr, &val); + RTSX_DEBUGP("0x%04X: 0x%02x\n", addr, val); + } + + rtsx_write_register(chip, DMACTL, 0x80, 0x80); + rtsx_write_register(chip, RBCTL, 0x80, 0x80); +} + +#define MAX_RW_REG_CNT 1024 + +int rtsx_write_register(struct rtsx_chip *chip, u16 addr, u8 mask, u8 data) +{ + int i; + u32 val = 3 << 30; + + val |= (u32)(addr & 0x3FFF) << 16; + val |= (u32)mask << 8; + val |= (u32)data; + + rtsx_writel(chip, RTSX_HAIMR, val); + + for (i = 0; i < MAX_RW_REG_CNT; i++) { + val = rtsx_readl(chip, RTSX_HAIMR); + if ((val & (1 << 31)) == 0) { + if (data != (u8)val) { + TRACE_RET(chip, STATUS_FAIL); + } + return STATUS_SUCCESS; + } + } + + TRACE_RET(chip, STATUS_TIMEDOUT); +} + +int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data) +{ + u32 val = 2 << 30; + int i; + + if (data) { + *data = 0; + } + + val |= (u32)(addr & 0x3FFF) << 16; + + rtsx_writel(chip, RTSX_HAIMR, val); + + for (i = 0; i < MAX_RW_REG_CNT; i++) { + val = rtsx_readl(chip, RTSX_HAIMR); + if ((val & (1 << 31)) == 0) { + break; + } + } + + if (i >= MAX_RW_REG_CNT) { + TRACE_RET(chip, STATUS_TIMEDOUT); + } + + if (data) { + *data = (u8)(val & 0xFF); + } + + return STATUS_SUCCESS; +} + +int rtsx_write_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 mask, u32 val) +{ + u8 mode = 0, tmp; + int i; + + for (i = 0; i < 4; i++) { + if (mask & 0xFF) { + RTSX_WRITE_REG(chip, CFGDATA0 + i, + 0xFF, (u8)(val & mask & 0xFF)); + mode |= (1 << i); + } + mask >>= 8; + val >>= 8; + } + + if (mode) { + RTSX_WRITE_REG(chip, CFGADDR0, 0xFF, (u8)addr); + RTSX_WRITE_REG(chip, CFGADDR1, 0xFF, (u8)(addr >> 8)); + + RTSX_WRITE_REG(chip, CFGRWCTL, 0xFF, + 0x80 | mode | ((func_no & 0x03) << 4)); + + for (i = 0; i < MAX_RW_REG_CNT; i++) { + RTSX_READ_REG(chip, CFGRWCTL, &tmp); + if ((tmp & 0x80) == 0) { + break; + } + } + } + + return STATUS_SUCCESS; +} + +int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val) +{ + int i; + u8 tmp; + u32 data = 0; + + RTSX_WRITE_REG(chip, CFGADDR0, 0xFF, (u8)addr); + RTSX_WRITE_REG(chip, CFGADDR1, 0xFF, (u8)(addr >> 8)); + RTSX_WRITE_REG(chip, CFGRWCTL, 0xFF, 0x80 | ((func_no & 0x03) << 4)); + + for (i = 0; i < MAX_RW_REG_CNT; i++) { + RTSX_READ_REG(chip, CFGRWCTL, &tmp); + if ((tmp & 0x80) == 0) { + break; + } + } + + for (i = 0; i < 4; i++) { + RTSX_READ_REG(chip, CFGDATA0 + i, &tmp); + data |= (u32)tmp << (i * 8); + } + + if (val) { + *val = data; + } + + return STATUS_SUCCESS; +} + +int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, int len) +{ + u32 *data, *mask; + u16 offset = addr % 4; + u16 aligned_addr = addr - offset; + int dw_len, i, j; + int retval; + + RTSX_DEBUGP("%s\n", __func__); + + if (!buf) { + TRACE_RET(chip, STATUS_NOMEM); + } + + if ((len + offset) % 4) { + dw_len = (len + offset) / 4 + 1; + } else { + dw_len = (len + offset) / 4; + } + RTSX_DEBUGP("dw_len = %d\n", dw_len); + + data = (u32 *)vmalloc(dw_len * 4); + if (!data) { + TRACE_RET(chip, STATUS_NOMEM); + } + memset(data, 0, dw_len * 4); + + mask = (u32 *)vmalloc(dw_len * 4); + if (!mask) { + vfree(data); + TRACE_RET(chip, STATUS_NOMEM); + } + memset(mask, 0, dw_len * 4); + + j = 0; + for (i = 0; i < len; i++) { + mask[j] |= 0xFF << (offset * 8); + data[j] |= buf[i] << (offset * 8); + if (++offset == 4) { + j++; + offset = 0; + } + } + + RTSX_DUMP(mask, dw_len * 4); + RTSX_DUMP(data, dw_len * 4); + + for (i = 0; i < dw_len; i++) { + retval = rtsx_write_cfg_dw(chip, func, aligned_addr + i * 4, mask[i], data[i]); + if (retval != STATUS_SUCCESS) { + vfree(data); + vfree(mask); + TRACE_RET(chip, STATUS_FAIL); + } + } + + vfree(data); + vfree(mask); + + return STATUS_SUCCESS; +} + +int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, int len) +{ + u32 *data; + u16 offset = addr % 4; + u16 aligned_addr = addr - offset; + int dw_len, i, j; + int retval; + + RTSX_DEBUGP("%s\n", __func__); + + if ((len + offset) % 4) { + dw_len = (len + offset) / 4 + 1; + } else { + dw_len = (len + offset) / 4; + } + RTSX_DEBUGP("dw_len = %d\n", dw_len); + + data = (u32 *)vmalloc(dw_len * 4); + if (!data) { + TRACE_RET(chip, STATUS_NOMEM); + } + + for (i = 0; i < dw_len; i++) { + retval = rtsx_read_cfg_dw(chip, func, aligned_addr + i * 4, data + i); + if (retval != STATUS_SUCCESS) { + vfree(data); + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (buf) { + j = 0; + + for (i = 0; i < len; i++) { + buf[i] = (u8)(data[j] >> (offset * 8)); + if (++offset == 4) { + j++; + offset = 0; + } + } + } + + vfree(data); + + return STATUS_SUCCESS; +} + +int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val) +{ + int i, finished = 0; + u8 tmp; + + RTSX_WRITE_REG(chip, PHYDATA0, 0xFF, (u8)val); + RTSX_WRITE_REG(chip, PHYDATA1, 0xFF, (u8)(val >> 8)); + RTSX_WRITE_REG(chip, PHYADDR, 0xFF, addr); + RTSX_WRITE_REG(chip, PHYRWCTL, 0xFF, 0x81); + + for (i = 0; i < 100000; i++) { + RTSX_READ_REG(chip, PHYRWCTL, &tmp); + if (!(tmp & 0x80)) { + finished = 1; + break; + } + } + + if (!finished) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int rtsx_read_phy_register(struct rtsx_chip *chip, u8 addr, u16 *val) +{ + int i, finished = 0; + u16 data = 0; + u8 tmp; + + RTSX_WRITE_REG(chip, PHYADDR, 0xFF, addr); + RTSX_WRITE_REG(chip, PHYRWCTL, 0xFF, 0x80); + + for (i = 0; i < 100000; i++) { + RTSX_READ_REG(chip, PHYRWCTL, &tmp); + if (!(tmp & 0x80)) { + finished = 1; + break; + } + } + + if (!finished) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_READ_REG(chip, PHYDATA0, &tmp); + data = tmp; + RTSX_READ_REG(chip, PHYDATA1, &tmp); + data |= (u16)tmp << 8; + + if (val) + *val = data; + + return STATUS_SUCCESS; +} + +int rtsx_read_efuse(struct rtsx_chip *chip, u8 addr, u8 *val) +{ + int i; + u8 data = 0; + + RTSX_WRITE_REG(chip, EFUSE_CTRL, 0xFF, 0x80|addr); + + for (i = 0; i < 100; i++) { + RTSX_READ_REG(chip, EFUSE_CTRL, &data); + if (!(data & 0x80)) + break; + udelay(1); + } + + if (data & 0x80) { + TRACE_RET(chip, STATUS_TIMEDOUT); + } + + RTSX_READ_REG(chip, EFUSE_DATA, &data); + if (val) + *val = data; + + return STATUS_SUCCESS; +} + +int rtsx_write_efuse(struct rtsx_chip *chip, u8 addr, u8 val) +{ + int i, j; + u8 data = 0, tmp = 0xFF; + + for (i = 0; i < 8; i++) { + if (val & (u8)(1 << i)) + continue; + + tmp &= (~(u8)(1 << i)); + RTSX_DEBUGP("Write 0x%x to 0x%x\n", tmp, addr); + + RTSX_WRITE_REG(chip, EFUSE_DATA, 0xFF, tmp); + RTSX_WRITE_REG(chip, EFUSE_CTRL, 0xFF, 0xA0|addr); + + for (j = 0; j < 100; j++) { + RTSX_READ_REG(chip, EFUSE_CTRL, &data); + if (!(data & 0x80)) + break; + wait_timeout(3); + } + + if (data & 0x80) { + TRACE_RET(chip, STATUS_TIMEDOUT); + } + + wait_timeout(5); + } + + return STATUS_SUCCESS; +} + +int rtsx_clr_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit) +{ + int retval; + u16 value; + + retval = rtsx_read_phy_register(chip, reg, &value); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + if (value & (1 << bit)) { + value &= ~(1 << bit); + retval = rtsx_write_phy_register(chip, reg, value); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + +int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit) +{ + int retval; + u16 value; + + retval = rtsx_read_phy_register(chip, reg, &value); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + if (0 == (value & (1 << bit))) { + value |= (1 << bit); + retval = rtsx_write_phy_register(chip, reg, value); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + +int rtsx_check_link_ready(struct rtsx_chip *chip) +{ + u8 val; + + RTSX_READ_REG(chip, IRQSTAT0, &val); + + RTSX_DEBUGP("IRQSTAT0: 0x%x\n", val); + if (val & LINK_RDY_INT) { + RTSX_DEBUGP("Delinked!\n"); + rtsx_write_register(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT); + return STATUS_FAIL; + } + + return STATUS_SUCCESS; +} + +static void rtsx_handle_pm_dstate(struct rtsx_chip *chip, u8 dstate) +{ + u32 ultmp; + + RTSX_DEBUGP("%04x set pm_dstate to %d\n", chip->product_id, dstate); + + if (CHK_SDIO_EXIST(chip)) { + u8 func_no; + + if (CHECK_PID(chip, 0x5288)) { + func_no = 2; + } else { + func_no = 1; + } + rtsx_read_cfg_dw(chip, func_no, 0x84, &ultmp); + RTSX_DEBUGP("pm_dstate of function %d: 0x%x\n", (int)func_no, ultmp); + rtsx_write_cfg_dw(chip, func_no, 0x84, 0xFF, dstate); + } + + rtsx_write_config_byte(chip, 0x44, dstate); + rtsx_write_config_byte(chip, 0x45, 0); +} + +void rtsx_enter_L1(struct rtsx_chip *chip) +{ + rtsx_handle_pm_dstate(chip, 2); +} + +void rtsx_exit_L1(struct rtsx_chip *chip) +{ + rtsx_write_config_byte(chip, 0x44, 0); + rtsx_write_config_byte(chip, 0x45, 0); +} + +void rtsx_enter_ss(struct rtsx_chip *chip) +{ + RTSX_DEBUGP("Enter Selective Suspend State!\n"); + + rtsx_write_register(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT); + + if (chip->power_down_in_ss) { + rtsx_power_off_card(chip); + rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); + } + + if (CHK_SDIO_EXIST(chip)) { + if (CHECK_PID(chip, 0x5288)) { + rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF00, 0x0100); + } else { + rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF00, 0x0100); + } + } + + if (chip->auto_delink_en) { + rtsx_write_register(chip, HOST_SLEEP_STATE, 0x01, 0x01); + } else { + if (!chip->phy_debug_mode) { + u32 tmp; + tmp = rtsx_readl(chip, RTSX_BIER); + tmp |= CARD_INT; + rtsx_writel(chip, RTSX_BIER, tmp); + } + + rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 0); + } + + rtsx_enter_L1(chip); + + RTSX_CLR_DELINK(chip); + rtsx_set_stat(chip, RTSX_STAT_SS); +} + +void rtsx_exit_ss(struct rtsx_chip *chip) +{ + RTSX_DEBUGP("Exit Selective Suspend State!\n"); + + rtsx_exit_L1(chip); + + if (chip->power_down_in_ss) { + rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); + udelay(1000); + } + + if (RTSX_TST_DELINK(chip)) { + chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; + rtsx_reinit_cards(chip, 1); + RTSX_CLR_DELINK(chip); + } else if (chip->power_down_in_ss) { + chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; + rtsx_reinit_cards(chip, 0); + } +} + +int rtsx_pre_handle_interrupt(struct rtsx_chip *chip) +{ + u32 status, int_enable; + int exit_ss = 0; +#ifdef SUPPORT_OCP + u32 ocp_int = 0; + + if (CHECK_PID(chip, 0x5209)) { + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + ocp_int = MS_OC_INT | SD_OC_INT; + } else { + ocp_int = SD_OC_INT; + } + } else { + ocp_int = OC_INT; + } +#endif + + if (chip->ss_en) { + chip->ss_counter = 0; + if (rtsx_get_stat(chip) == RTSX_STAT_SS) { + exit_ss = 1; + rtsx_exit_L1(chip); + rtsx_set_stat(chip, RTSX_STAT_RUN); + } + } + + int_enable = rtsx_readl(chip, RTSX_BIER); + chip->int_reg = rtsx_readl(chip, RTSX_BIPR); + +#ifdef HW_INT_WRITE_CLR + if (CHECK_PID(chip, 0x5209)) { + rtsx_writel(chip, RTSX_BIPR, chip->int_reg); + } +#endif + + if (((chip->int_reg & int_enable) == 0) || (chip->int_reg == 0xFFFFFFFF)) + return STATUS_FAIL; + + if (!chip->msi_en) { + if (CHECK_PID(chip, 0x5209)) { + u8 val; + rtsx_read_config_byte(chip, 0x05, &val); + if (val & 0x04) { + return STATUS_FAIL; + } + } + } + + status = chip->int_reg &= (int_enable | 0x7FFFFF); + + if (status & CARD_INT) { + chip->auto_delink_cnt = 0; + + if (status & SD_INT) { + if (status & SD_EXIST) { + set_bit(SD_NR, &(chip->need_reset)); + } else { + set_bit(SD_NR, &(chip->need_release)); + chip->sd_reset_counter = 0; + chip->sd_show_cnt = 0; + clear_bit(SD_NR, &(chip->need_reset)); + } + } else { + /* If multi-luns, it's possible that + when plugging/unplugging one card + there is another card which still + exists in the slot. In this case, + all existed cards should be reset. + */ + if (exit_ss && (status & SD_EXIST)) + set_bit(SD_NR, &(chip->need_reinit)); + } + if (!CHECK_PID(chip, 0x5288) || CHECK_BARO_PKG(chip, QFN)) { + if (status & XD_INT) { + if (status & XD_EXIST) { + set_bit(XD_NR, &(chip->need_reset)); + } else { + set_bit(XD_NR, &(chip->need_release)); + chip->xd_reset_counter = 0; + chip->xd_show_cnt = 0; + clear_bit(XD_NR, &(chip->need_reset)); + } + } else { + if (exit_ss && (status & XD_EXIST)) + set_bit(XD_NR, &(chip->need_reinit)); + } + } + if (status & MS_INT) { + if (status & MS_EXIST) { + set_bit(MS_NR, &(chip->need_reset)); + } else { + set_bit(MS_NR, &(chip->need_release)); + chip->ms_reset_counter = 0; + chip->ms_show_cnt = 0; + clear_bit(MS_NR, &(chip->need_reset)); + } + } else { + if (exit_ss && (status & MS_EXIST)) + set_bit(MS_NR, &(chip->need_reinit)); + } + } + +#ifdef SUPPORT_OCP + chip->ocp_int = ocp_int & status; +#endif + + if (chip->sd_io) { + if (chip->int_reg & DATA_DONE_INT) + chip->int_reg &= ~(u32)DATA_DONE_INT; + } + + return STATUS_SUCCESS; +} + +void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat) +{ + int retval; + + RTSX_DEBUGP("rtsx_do_before_power_down, pm_stat = %d\n", pm_stat); + + rtsx_set_stat(chip, RTSX_STAT_SUSPEND); + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) + return; + + rtsx_release_cards(chip); + rtsx_disable_bus_int(chip); + turn_off_led(chip, LED_GPIO); + +#ifdef HW_AUTO_SWITCH_SD_BUS + if (chip->sd_io) { + chip->sdio_in_charge = 1; + if (CHECK_PID(chip, 0x5208)) { + rtsx_write_register(chip, TLPTISTAT, 0x08, 0x08); + /* Enable sdio_bus_auto_switch */ + rtsx_write_register(chip, 0xFE70, 0x80, 0x80); + } else if (CHECK_PID(chip, 0x5288)) { + rtsx_write_register(chip, TLPTISTAT, 0x08, 0x08); + /* Enable sdio_bus_auto_switch */ + rtsx_write_register(chip, 0xFE5A, 0x08, 0x08); + } else if (CHECK_PID(chip, 0x5209)) { + rtsx_write_register(chip, TLPTISTAT, 0x10, 0x10); + /* Enable sdio_bus_auto_switch */ + rtsx_write_register(chip, SDIO_CFG, SDIO_BUS_AUTO_SWITCH, SDIO_BUS_AUTO_SWITCH); + } + } +#endif + + if (CHECK_PID(chip, 0x5208) && (chip->ic_version >= IC_VER_D)) { + /* u_force_clkreq_0 */ + rtsx_write_register(chip, PETXCFG, 0x08, 0x08); + } else if (CHECK_PID(chip, 0x5209)) { + /* u_force_clkreq_0 */ + rtsx_write_register(chip, PETXCFG, 0x08, 0x08); + } + + if (pm_stat == PM_S1) { + RTSX_DEBUGP("Host enter S1\n"); + rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, HOST_ENTER_S1); + } else if (pm_stat == PM_S3) { + if (chip->s3_pwr_off_delay > 0) { + wait_timeout(chip->s3_pwr_off_delay); + } + RTSX_DEBUGP("Host enter S3\n"); + rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, HOST_ENTER_S3); + } + + if (chip->do_delink_before_power_down && chip->auto_delink_en) { + rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 2); + } + + rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); + + chip->cur_clk = 0; + chip->cur_card = 0; + chip->card_exist = 0; +} + +void rtsx_enable_aspm(struct rtsx_chip *chip) +{ + if (chip->aspm_l0s_l1_en && chip->dynamic_aspm) { + if (!chip->aspm_enabled) { + RTSX_DEBUGP("Try to enable ASPM\n"); + chip->aspm_enabled = 1; + + if (chip->asic_code && CHECK_PID(chip, 0x5208)) + rtsx_write_phy_register(chip, 0x07, 0); + if (CHECK_PID(chip, 0x5208)) { + rtsx_write_register(chip, ASPM_FORCE_CTL, 0xF3, + 0x30 | chip->aspm_level[0]); + } else { + rtsx_write_config_byte(chip, LCTLR, chip->aspm_l0s_l1_en); + } + + if (CHK_SDIO_EXIST(chip)) { + u16 val = chip->aspm_l0s_l1_en | 0x0100; + if (CHECK_PID(chip, 0x5288)) { + rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFFFF, val); + } else { + rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFFFF, val); + } + } + } + } + + return; +} + +void rtsx_disable_aspm(struct rtsx_chip *chip) +{ + if (CHECK_PID(chip, 0x5208)) + rtsx_monitor_aspm_config(chip); + + if (chip->aspm_l0s_l1_en && chip->dynamic_aspm) { + if (chip->aspm_enabled) { + RTSX_DEBUGP("Try to disable ASPM\n"); + chip->aspm_enabled = 0; + + if (chip->asic_code && CHECK_PID(chip, 0x5208)) + rtsx_write_phy_register(chip, 0x07, 0x0129); + if (CHECK_PID(chip, 0x5208)) { + rtsx_write_register(chip, ASPM_FORCE_CTL, 0xF3, 0x30); + } else { + rtsx_write_config_byte(chip, LCTLR, 0x00); + } + wait_timeout(1); + } + } + + return; +} + +int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) +{ + int retval; + int i, j; + u16 reg_addr; + u8 *ptr; + + if (!buf) { + TRACE_RET(chip, STATUS_ERROR); + } + + ptr = buf; + reg_addr = PPBUF_BASE2; + for (i = 0; i < buf_len/256; i++) { + rtsx_init_cmd(chip); + + for (j = 0; j < 256; j++) + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr++, 0, 0); + + retval = rtsx_send_cmd(chip, 0, 250); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + + memcpy(ptr, rtsx_get_cmd_data(chip), 256); + ptr += 256; + } + + if (buf_len%256) { + rtsx_init_cmd(chip); + + for (j = 0; j < buf_len%256; j++) + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr++, 0, 0); + + retval = rtsx_send_cmd(chip, 0, 250); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + memcpy(ptr, rtsx_get_cmd_data(chip), buf_len%256); + + return STATUS_SUCCESS; +} + +int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) +{ + int retval; + int i, j; + u16 reg_addr; + u8 *ptr; + + if (!buf) { + TRACE_RET(chip, STATUS_ERROR); + } + + ptr = buf; + reg_addr = PPBUF_BASE2; + for (i = 0; i < buf_len/256; i++) { + rtsx_init_cmd(chip); + + for (j = 0; j < 256; j++) { + rtsx_add_cmd(chip, WRITE_REG_CMD, reg_addr++, 0xFF, *ptr); + ptr++; + } + + retval = rtsx_send_cmd(chip, 0, 250); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (buf_len%256) { + rtsx_init_cmd(chip); + + for (j = 0; j < buf_len%256; j++) { + rtsx_add_cmd(chip, WRITE_REG_CMD, reg_addr++, 0xFF, *ptr); + ptr++; + } + + retval = rtsx_send_cmd(chip, 0, 250); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + +int rtsx_check_chip_exist(struct rtsx_chip *chip) +{ + if (rtsx_readl(chip, 0) == 0xFFFFFFFF) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int rtsx_force_power_on(struct rtsx_chip *chip, u8 ctl) +{ + int retval; + u8 mask = 0; + + if (ctl & SSC_PDCTL) + mask |= SSC_POWER_DOWN; + +#ifdef SUPPORT_OCP + if (ctl & OC_PDCTL) { + mask |= SD_OC_POWER_DOWN; + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + mask |= MS_OC_POWER_DOWN; + } + } +#endif + + if (mask) { + retval = rtsx_write_register(chip, FPDCTL, mask, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (CHECK_PID(chip, 0x5288)) + wait_timeout(200); + } + + return STATUS_SUCCESS; +} + +int rtsx_force_power_down(struct rtsx_chip *chip, u8 ctl) +{ + int retval; + u8 mask = 0, val = 0; + + if (ctl & SSC_PDCTL) + mask |= SSC_POWER_DOWN; + +#ifdef SUPPORT_OCP + if (ctl & OC_PDCTL) { + mask |= SD_OC_POWER_DOWN; + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) + mask |= MS_OC_POWER_DOWN; + } +#endif + + if (mask) { + val = mask; + retval = rtsx_write_register(chip, FPDCTL, mask, val); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} diff --git a/drivers/staging/rts_pstor/rtsx_chip.h b/drivers/staging/rts_pstor/rtsx_chip.h new file mode 100644 index 000000000000..713c5eaadacd --- /dev/null +++ b/drivers/staging/rts_pstor/rtsx_chip.h @@ -0,0 +1,989 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __REALTEK_RTSX_CHIP_H +#define __REALTEK_RTSX_CHIP_H + +#include "rtsx.h" + +#define SUPPORT_CPRM +#define SUPPORT_OCP +#define SUPPORT_SDIO_ASPM +#define SUPPORT_MAGIC_GATE +#define SUPPORT_MSXC +#define SUPPORT_SD_LOCK +/* Hardware switch bus_ctl and cd_ctl automatically */ +#define HW_AUTO_SWITCH_SD_BUS +/* Enable hardware interrupt write clear */ +#define HW_INT_WRITE_CLR +/* #define LED_AUTO_BLINK */ +/* #define DISABLE_CARD_INT */ + +#ifdef SUPPORT_MAGIC_GATE + /* Using NORMAL_WRITE instead of AUTO_WRITE to set ICV */ + #define MG_SET_ICV_SLOW + /* HW may miss ERR/CMDNK signal when sampling INT status. */ + #define MS_SAMPLE_INT_ERR + /* HW DO NOT support Wait_INT function during READ_BYTES transfer mode */ + #define READ_BYTES_WAIT_INT +#endif + +#ifdef SUPPORT_MSXC +#define XC_POWERCLASS +#define SUPPORT_PCGL_1P18 +#endif + +#ifndef LED_AUTO_BLINK +#define REGULAR_BLINK +#endif + +#define LED_BLINK_SPEED 5 +#define LED_TOGGLE_INTERVAL 6 +#define GPIO_TOGGLE_THRESHOLD 1024 +#define LED_GPIO 0 + +#define POLLING_INTERVAL 30 + +#define TRACE_ITEM_CNT 64 + +#ifndef STATUS_SUCCESS +#define STATUS_SUCCESS 0 +#endif +#ifndef STATUS_FAIL +#define STATUS_FAIL 1 +#endif +#ifndef STATUS_TIMEDOUT +#define STATUS_TIMEDOUT 2 +#endif +#ifndef STATUS_NOMEM +#define STATUS_NOMEM 3 +#endif +#ifndef STATUS_READ_FAIL +#define STATUS_READ_FAIL 4 +#endif +#ifndef STATUS_WRITE_FAIL +#define STATUS_WRITE_FAIL 5 +#endif +#ifndef STATUS_ERROR +#define STATUS_ERROR 10 +#endif + +#define PM_S1 1 +#define PM_S3 3 + +/* + * Transport return codes + */ + +#define TRANSPORT_GOOD 0 /* Transport good, command good */ +#define TRANSPORT_FAILED 1 /* Transport good, command failed */ +#define TRANSPORT_NO_SENSE 2 /* Command failed, no auto-sense */ +#define TRANSPORT_ERROR 3 /* Transport bad (i.e. device dead) */ + + +/*----------------------------------- + Start-Stop-Unit +-----------------------------------*/ +#define STOP_MEDIUM 0x00 /* access disable */ +#define MAKE_MEDIUM_READY 0x01 /* access enable */ +#define UNLOAD_MEDIUM 0x02 /* unload */ +#define LOAD_MEDIUM 0x03 /* load */ + +/*----------------------------------- + STANDARD_INQUIRY +-----------------------------------*/ +#define QULIFIRE 0x00 +#define AENC_FNC 0x00 +#define TRML_IOP 0x00 +#define REL_ADR 0x00 +#define WBUS_32 0x00 +#define WBUS_16 0x00 +#define SYNC 0x00 +#define LINKED 0x00 +#define CMD_QUE 0x00 +#define SFT_RE 0x00 + +#define VEN_ID_LEN 8 /* Vendor ID Length */ +#define PRDCT_ID_LEN 16 /* Product ID Length */ +#define PRDCT_REV_LEN 4 /* Product LOT Length */ + +/* Dynamic flag definitions: used in set_bit() etc. */ +#define RTSX_FLIDX_TRANS_ACTIVE 18 /* 0x00040000 transfer is active */ +#define RTSX_FLIDX_ABORTING 20 /* 0x00100000 abort is in progress */ +#define RTSX_FLIDX_DISCONNECTING 21 /* 0x00200000 disconnect in progress */ +#define ABORTING_OR_DISCONNECTING ((1UL << US_FLIDX_ABORTING) | \ + (1UL << US_FLIDX_DISCONNECTING)) +#define RTSX_FLIDX_RESETTING 22 /* 0x00400000 device reset in progress */ +#define RTSX_FLIDX_TIMED_OUT 23 /* 0x00800000 SCSI midlayer timed out */ + +#define DRCT_ACCESS_DEV 0x00 /* Direct Access Device */ +#define RMB_DISC 0x80 /* The Device is Removable */ +#define ANSI_SCSI2 0x02 /* Based on ANSI-SCSI2 */ + +#define SCSI 0x00 /* Interface ID */ + +#define WRITE_PROTECTED_MEDIA 0x07 + +/*---- sense key ----*/ +#define ILI 0x20 /* ILI bit is on */ + +#define NO_SENSE 0x00 /* not exist sense key */ +#define RECOVER_ERR 0x01 /* Target/Logical unit is recoverd */ +#define NOT_READY 0x02 /* Logical unit is not ready */ +#define MEDIA_ERR 0x03 /* medium/data error */ +#define HARDWARE_ERR 0x04 /* hardware error */ +#define ILGAL_REQ 0x05 /* CDB/parameter/identify msg error */ +#define UNIT_ATTENTION 0x06 /* unit attention condition occur */ +#define DAT_PRTCT 0x07 /* read/write is desable */ +#define BLNC_CHK 0x08 /* find blank/DOF in read */ + /* write to unblank area */ +#define CPY_ABRT 0x0a /* Copy/Compare/Copy&Verify illgal */ +#define ABRT_CMD 0x0b /* Target make the command in error */ +#define EQUAL 0x0c /* Search Data end with Equal */ +#define VLM_OVRFLW 0x0d /* Some data are left in buffer */ +#define MISCMP 0x0e /* find inequality */ + +#define READ_ERR -1 +#define WRITE_ERR -2 + +#define FIRST_RESET 0x01 +#define USED_EXIST 0x02 + +/*----------------------------------- + SENSE_DATA +-----------------------------------*/ +/*---- valid ----*/ +#define SENSE_VALID 0x80 /* Sense data is valid as SCSI2 */ +#define SENSE_INVALID 0x00 /* Sense data is invalid as SCSI2 */ + +/*---- error code ----*/ +#define CUR_ERR 0x70 /* current error */ +#define DEF_ERR 0x71 /* specific command error */ + +/*---- sense key Infomation ----*/ +#define SNSKEYINFO_LEN 3 /* length of sense key infomation */ + +#define SKSV 0x80 +#define CDB_ILLEGAL 0x40 +#define DAT_ILLEGAL 0x00 +#define BPV 0x08 +#define BIT_ILLEGAL0 0 /* bit0 is illegal */ +#define BIT_ILLEGAL1 1 /* bit1 is illegal */ +#define BIT_ILLEGAL2 2 /* bit2 is illegal */ +#define BIT_ILLEGAL3 3 /* bit3 is illegal */ +#define BIT_ILLEGAL4 4 /* bit4 is illegal */ +#define BIT_ILLEGAL5 5 /* bit5 is illegal */ +#define BIT_ILLEGAL6 6 /* bit6 is illegal */ +#define BIT_ILLEGAL7 7 /* bit7 is illegal */ + +/*---- ASC ----*/ +#define ASC_NO_INFO 0x00 +#define ASC_MISCMP 0x1d +#define ASC_INVLD_CDB 0x24 +#define ASC_INVLD_PARA 0x26 +#define ASC_LU_NOT_READY 0x04 +#define ASC_WRITE_ERR 0x0c +#define ASC_READ_ERR 0x11 +#define ASC_LOAD_EJCT_ERR 0x53 +#define ASC_MEDIA_NOT_PRESENT 0x3A +#define ASC_MEDIA_CHANGED 0x28 +#define ASC_MEDIA_IN_PROCESS 0x04 +#define ASC_WRITE_PROTECT 0x27 +#define ASC_LUN_NOT_SUPPORTED 0x25 + +/*---- ASQC ----*/ +#define ASCQ_NO_INFO 0x00 +#define ASCQ_MEDIA_IN_PROCESS 0x01 +#define ASCQ_MISCMP 0x00 +#define ASCQ_INVLD_CDB 0x00 +#define ASCQ_INVLD_PARA 0x02 +#define ASCQ_LU_NOT_READY 0x02 +#define ASCQ_WRITE_ERR 0x02 +#define ASCQ_READ_ERR 0x00 +#define ASCQ_LOAD_EJCT_ERR 0x00 +#define ASCQ_WRITE_PROTECT 0x00 + + +struct sense_data_t { + unsigned char err_code; /* error code */ + /* bit7 : valid */ + /* (1 : SCSI2) */ + /* (0 : Vendor specific) */ + /* bit6-0 : error code */ + /* (0x70 : current error) */ + /* (0x71 : specific command error) */ + unsigned char seg_no; /* segment No. */ + unsigned char sense_key; /* byte5 : ILI */ + /* bit3-0 : sense key */ + unsigned char info[4]; /* infomation */ + unsigned char ad_sense_len; /* additional sense data length */ + unsigned char cmd_info[4]; /* command specific infomation */ + unsigned char asc; /* ASC */ + unsigned char ascq; /* ASCQ */ + unsigned char rfu; /* FRU */ + unsigned char sns_key_info[3]; /* sense key specific infomation */ +}; + +/* PCI Operation Register Address */ +#define RTSX_HCBAR 0x00 +#define RTSX_HCBCTLR 0x04 +#define RTSX_HDBAR 0x08 +#define RTSX_HDBCTLR 0x0C +#define RTSX_HAIMR 0x10 +#define RTSX_BIPR 0x14 +#define RTSX_BIER 0x18 + +/* Host command buffer control register */ +#define STOP_CMD (0x01 << 28) + +/* Host data buffer control register */ +#define SDMA_MODE 0x00 +#define ADMA_MODE (0x02 << 26) +#define STOP_DMA (0x01 << 28) +#define TRIG_DMA (0x01 << 31) + +/* Bus interrupt pending register */ +#define CMD_DONE_INT (1 << 31) +#define DATA_DONE_INT (1 << 30) +#define TRANS_OK_INT (1 << 29) +#define TRANS_FAIL_INT (1 << 28) +#define XD_INT (1 << 27) +#define MS_INT (1 << 26) +#define SD_INT (1 << 25) +#define GPIO0_INT (1 << 24) +#define OC_INT (1 << 23) +#define SD_WRITE_PROTECT (1 << 19) +#define XD_EXIST (1 << 18) +#define MS_EXIST (1 << 17) +#define SD_EXIST (1 << 16) +#define DELINK_INT GPIO0_INT +#define MS_OC_INT (1 << 23) +#define SD_OC_INT (1 << 22) + +#define CARD_INT (XD_INT | MS_INT | SD_INT) +#define NEED_COMPLETE_INT (DATA_DONE_INT | TRANS_OK_INT | TRANS_FAIL_INT) +#define RTSX_INT (CMD_DONE_INT | NEED_COMPLETE_INT | CARD_INT | GPIO0_INT | OC_INT) + +#define CARD_EXIST (XD_EXIST | MS_EXIST | SD_EXIST) + +/* Bus interrupt enable register */ +#define CMD_DONE_INT_EN (1 << 31) +#define DATA_DONE_INT_EN (1 << 30) +#define TRANS_OK_INT_EN (1 << 29) +#define TRANS_FAIL_INT_EN (1 << 28) +#define XD_INT_EN (1 << 27) +#define MS_INT_EN (1 << 26) +#define SD_INT_EN (1 << 25) +#define GPIO0_INT_EN (1 << 24) +#define OC_INT_EN (1 << 23) +#define DELINK_INT_EN GPIO0_INT_EN +#define MS_OC_INT_EN (1 << 23) +#define SD_OC_INT_EN (1 << 22) + + +#define READ_REG_CMD 0 +#define WRITE_REG_CMD 1 +#define CHECK_REG_CMD 2 + +#define HOST_TO_DEVICE 0 +#define DEVICE_TO_HOST 1 + + +#define RTSX_RESV_BUF_LEN 4096 +#define HOST_CMDS_BUF_LEN 1024 +#define HOST_SG_TBL_BUF_LEN (RTSX_RESV_BUF_LEN - HOST_CMDS_BUF_LEN) + +#define SD_NR 2 +#define MS_NR 3 +#define XD_NR 4 +#define SPI_NR 7 +#define SD_CARD (1 << SD_NR) +#define MS_CARD (1 << MS_NR) +#define XD_CARD (1 << XD_NR) +#define SPI_CARD (1 << SPI_NR) + +#define MAX_ALLOWED_LUN_CNT 8 + +#define XD_FREE_TABLE_CNT 1200 +#define MS_FREE_TABLE_CNT 512 + + +/* Bit Operation */ +#define SET_BIT(data, idx) ((data) |= 1 << (idx)) +#define CLR_BIT(data, idx) ((data) &= ~(1 << (idx))) +#define CHK_BIT(data, idx) ((data) & (1 << (idx))) + +/* SG descriptor */ +#define SG_INT 0x04 +#define SG_END 0x02 +#define SG_VALID 0x01 + +#define SG_NO_OP 0x00 +#define SG_TRANS_DATA (0x02 << 4) +#define SG_LINK_DESC (0x03 << 4) + +struct rtsx_chip; + +typedef int (*card_rw_func)(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 sec_addr, u16 sec_cnt); + +/* Supported Clock */ +enum card_clock {CLK_20 = 1, CLK_30, CLK_40, CLK_50, CLK_60, CLK_80, CLK_100, CLK_120, CLK_150, CLK_200}; + +enum RTSX_STAT {RTSX_STAT_INIT, RTSX_STAT_IDLE, RTSX_STAT_RUN, RTSX_STAT_SS, + RTSX_STAT_DELINK, RTSX_STAT_SUSPEND, RTSX_STAT_ABORT, RTSX_STAT_DISCONNECT}; +enum IC_VER {IC_VER_AB, IC_VER_C = 2, IC_VER_D = 3}; + +#define MAX_RESET_CNT 3 + +/* For MS Card */ +#define MAX_DEFECTIVE_BLOCK 10 + +struct zone_entry { + u16 *l2p_table; + u16 *free_table; + u16 defect_list[MAX_DEFECTIVE_BLOCK]; /* For MS card only */ + int set_index; + int get_index; + int unused_blk_cnt; + int disable_count; + /* To indicate whether the L2P table of this zone has been built. */ + int build_flag; +}; + +#define TYPE_SD 0x0000 +#define TYPE_MMC 0x0001 + +/* TYPE_SD */ +#define SD_HS 0x0100 +#define SD_SDR50 0x0200 +#define SD_DDR50 0x0400 +#define SD_SDR104 0x0800 +#define SD_HCXC 0x1000 + +/* TYPE_MMC */ +#define MMC_26M 0x0100 +#define MMC_52M 0x0200 +#define MMC_4BIT 0x0400 +#define MMC_8BIT 0x0800 +#define MMC_SECTOR_MODE 0x1000 +#define MMC_DDR52 0x2000 + +/* SD card */ +#define CHK_SD(sd_card) (((sd_card)->sd_type & 0xFF) == TYPE_SD) +#define CHK_SD_HS(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_HS)) +#define CHK_SD_SDR50(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_SDR50)) +#define CHK_SD_DDR50(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_DDR50)) +#define CHK_SD_SDR104(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_SDR104)) +#define CHK_SD_HCXC(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_HCXC)) +#define CHK_SD_HC(sd_card) (CHK_SD_HCXC(sd_card) && ((sd_card)->capacity <= 0x4000000)) +#define CHK_SD_XC(sd_card) (CHK_SD_HCXC(sd_card) && ((sd_card)->capacity > 0x4000000)) +#define CHK_SD30_SPEED(sd_card) (CHK_SD_SDR50(sd_card) || CHK_SD_DDR50(sd_card) || CHK_SD_SDR104(sd_card)) + +#define SET_SD(sd_card) ((sd_card)->sd_type = TYPE_SD) +#define SET_SD_HS(sd_card) ((sd_card)->sd_type |= SD_HS) +#define SET_SD_SDR50(sd_card) ((sd_card)->sd_type |= SD_SDR50) +#define SET_SD_DDR50(sd_card) ((sd_card)->sd_type |= SD_DDR50) +#define SET_SD_SDR104(sd_card) ((sd_card)->sd_type |= SD_SDR104) +#define SET_SD_HCXC(sd_card) ((sd_card)->sd_type |= SD_HCXC) + +#define CLR_SD_HS(sd_card) ((sd_card)->sd_type &= ~SD_HS) +#define CLR_SD_SDR50(sd_card) ((sd_card)->sd_type &= ~SD_SDR50) +#define CLR_SD_DDR50(sd_card) ((sd_card)->sd_type &= ~SD_DDR50) +#define CLR_SD_SDR104(sd_card) ((sd_card)->sd_type &= ~SD_SDR104) +#define CLR_SD_HCXC(sd_card) ((sd_card)->sd_type &= ~SD_HCXC) + +/* MMC card */ +#define CHK_MMC(sd_card) (((sd_card)->sd_type & 0xFF) == TYPE_MMC) +#define CHK_MMC_26M(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_26M)) +#define CHK_MMC_52M(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_52M)) +#define CHK_MMC_4BIT(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_4BIT)) +#define CHK_MMC_8BIT(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_8BIT)) +#define CHK_MMC_SECTOR_MODE(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_SECTOR_MODE)) +#define CHK_MMC_DDR52(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_DDR52)) + +#define SET_MMC(sd_card) ((sd_card)->sd_type = TYPE_MMC) +#define SET_MMC_26M(sd_card) ((sd_card)->sd_type |= MMC_26M) +#define SET_MMC_52M(sd_card) ((sd_card)->sd_type |= MMC_52M) +#define SET_MMC_4BIT(sd_card) ((sd_card)->sd_type |= MMC_4BIT) +#define SET_MMC_8BIT(sd_card) ((sd_card)->sd_type |= MMC_8BIT) +#define SET_MMC_SECTOR_MODE(sd_card) ((sd_card)->sd_type |= MMC_SECTOR_MODE) +#define SET_MMC_DDR52(sd_card) ((sd_card)->sd_type |= MMC_DDR52) + +#define CLR_MMC_26M(sd_card) ((sd_card)->sd_type &= ~MMC_26M) +#define CLR_MMC_52M(sd_card) ((sd_card)->sd_type &= ~MMC_52M) +#define CLR_MMC_4BIT(sd_card) ((sd_card)->sd_type &= ~MMC_4BIT) +#define CLR_MMC_8BIT(sd_card) ((sd_card)->sd_type &= ~MMC_8BIT) +#define CLR_MMC_SECTOR_MODE(sd_card) ((sd_card)->sd_type &= ~MMC_SECTOR_MODE) +#define CLR_MMC_DDR52(sd_card) ((sd_card)->sd_type &= ~MMC_DDR52) + +#define CHK_MMC_HS(sd_card) (CHK_MMC_52M(sd_card) && CHK_MMC_26M(sd_card)) +#define CLR_MMC_HS(sd_card) \ +do { \ + CLR_MMC_DDR52(sd_card); \ + CLR_MMC_52M(sd_card); \ + CLR_MMC_26M(sd_card); \ +} while (0) + +#define SD_SUPPORT_CLASS_TEN 0x01 +#define SD_SUPPORT_1V8 0x02 + +#define SD_SET_CLASS_TEN(sd_card) ((sd_card)->sd_setting |= SD_SUPPORT_CLASS_TEN) +#define SD_CHK_CLASS_TEN(sd_card) ((sd_card)->sd_setting & SD_SUPPORT_CLASS_TEN) +#define SD_CLR_CLASS_TEN(sd_card) ((sd_card)->sd_setting &= ~SD_SUPPORT_CLASS_TEN) +#define SD_SET_1V8(sd_card) ((sd_card)->sd_setting |= SD_SUPPORT_1V8) +#define SD_CHK_1V8(sd_card) ((sd_card)->sd_setting & SD_SUPPORT_1V8) +#define SD_CLR_1V8(sd_card) ((sd_card)->sd_setting &= ~SD_SUPPORT_1V8) + +struct sd_info { + u16 sd_type; + u8 err_code; + u8 sd_data_buf_ready; + u32 sd_addr; + u32 capacity; + + u8 raw_csd[16]; + u8 raw_scr[8]; + + /* Sequential RW */ + int seq_mode; + enum dma_data_direction pre_dir; + u32 pre_sec_addr; + u16 pre_sec_cnt; + + int cleanup_counter; + + int sd_clock; + + int mmc_dont_switch_bus; + +#ifdef SUPPORT_CPRM + int sd_pass_thru_en; + int pre_cmd_err; + u8 last_rsp_type; + u8 rsp[17]; +#endif + + u8 func_group1_mask; + u8 func_group2_mask; + u8 func_group3_mask; + u8 func_group4_mask; + + u8 sd_switch_fail; + u8 sd_read_phase; + +#ifdef SUPPORT_SD_LOCK + u8 sd_lock_status; + u8 sd_erase_status; + u8 sd_lock_notify; +#endif + int need_retune; +}; + +struct xd_delay_write_tag { + u32 old_phyblock; + u32 new_phyblock; + u32 logblock; + u8 pageoff; + u8 delay_write_flag; +}; + +struct xd_info { + u8 maker_code; + u8 device_code; + u8 block_shift; + u8 page_off; + u8 addr_cycle; + u16 cis_block; + u8 multi_flag; + u8 err_code; + u32 capacity; + + struct zone_entry *zone; + int zone_cnt; + + struct xd_delay_write_tag delay_write; + int cleanup_counter; + + int xd_clock; +}; + +#define MODE_512_SEQ 0x01 +#define MODE_2K_SEQ 0x02 + +#define TYPE_MS 0x0000 +#define TYPE_MSPRO 0x0001 + +#define MS_4BIT 0x0100 +#define MS_8BIT 0x0200 +#define MS_HG 0x0400 +#define MS_XC 0x0800 + +#define HG8BIT (MS_HG | MS_8BIT) + +#define CHK_MSPRO(ms_card) (((ms_card)->ms_type & 0xFF) == TYPE_MSPRO) +#define CHK_HG8BIT(ms_card) (CHK_MSPRO(ms_card) && (((ms_card)->ms_type & HG8BIT) == HG8BIT)) +#define CHK_MSXC(ms_card) (CHK_MSPRO(ms_card) && ((ms_card)->ms_type & MS_XC)) +#define CHK_MSHG(ms_card) (CHK_MSPRO(ms_card) && ((ms_card)->ms_type & MS_HG)) + +#define CHK_MS8BIT(ms_card) (((ms_card)->ms_type & MS_8BIT)) +#define CHK_MS4BIT(ms_card) (((ms_card)->ms_type & MS_4BIT)) + +struct ms_delay_write_tag { + u16 old_phyblock; + u16 new_phyblock; + u16 logblock; + u8 pageoff; + u8 delay_write_flag; +}; + +struct ms_info { + u16 ms_type; + u8 block_shift; + u8 page_off; + u16 total_block; + u16 boot_block; + u32 capacity; + + u8 check_ms_flow; + u8 switch_8bit_fail; + u8 err_code; + + struct zone_entry *segment; + int segment_cnt; + + int pro_under_formatting; + int format_status; + u16 progress; + u8 raw_sys_info[96]; +#ifdef SUPPORT_PCGL_1P18 + u8 raw_model_name[48]; +#endif + + u8 multi_flag; + + /* Sequential RW */ + u8 seq_mode; + enum dma_data_direction pre_dir; + u32 pre_sec_addr; + u16 pre_sec_cnt; + u32 total_sec_cnt; + + struct ms_delay_write_tag delay_write; + + int cleanup_counter; + + int ms_clock; + +#ifdef SUPPORT_MAGIC_GATE + u8 magic_gate_id[16]; + u8 mg_entry_num; + int mg_auth; /* flag to indicate authentication process */ +#endif +}; + +struct spi_info { + u8 use_clk; + u8 write_en; + u16 clk_div; + u8 err_code; + + int spi_clock; +}; + + +#ifdef _MSG_TRACE +struct trace_msg_t { + u16 line; +#define MSG_FUNC_LEN 64 + char func[MSG_FUNC_LEN]; +#define MSG_FILE_LEN 32 + char file[MSG_FILE_LEN]; +#define TIME_VAL_LEN 16 + u8 timeval_buf[TIME_VAL_LEN]; + u8 valid; +}; +#endif + +/************/ +/* LUN mode */ +/************/ +/* Single LUN, support xD/SD/MS */ +#define DEFAULT_SINGLE 0 +/* 2 LUN mode, support SD/MS */ +#define SD_MS_2LUN 1 +/* Single LUN, but only support SD/MS, for Barossa LQFP */ +#define SD_MS_1LUN 2 + +#define LAST_LUN_MODE 2 + +/* Barossa package */ +#define QFN 0 +#define LQFP 1 + +/******************/ +/* sd_ctl bit map */ +/******************/ +/* SD push point control, bit 0, 1 */ +#define SD_PUSH_POINT_CTL_MASK 0x03 +#define SD_PUSH_POINT_DELAY 0x01 +#define SD_PUSH_POINT_AUTO 0x02 +/* SD sample point control, bit 2, 3 */ +#define SD_SAMPLE_POINT_CTL_MASK 0x0C +#define SD_SAMPLE_POINT_DELAY 0x04 +#define SD_SAMPLE_POINT_AUTO 0x08 +/* SD DDR Tx phase set by user, bit 4 */ +#define SD_DDR_TX_PHASE_SET_BY_USER 0x10 +/* MMC DDR Tx phase set by user, bit 5 */ +#define MMC_DDR_TX_PHASE_SET_BY_USER 0x20 +/* Support MMC DDR mode, bit 6 */ +#define SUPPORT_MMC_DDR_MODE 0x40 +/* Reset MMC at first */ +#define RESET_MMC_FIRST 0x80 + +#define SEQ_START_CRITERIA 0x20 + +/* MS Power Class En */ +#define POWER_CLASS_2_EN 0x02 +#define POWER_CLASS_1_EN 0x01 + +#define MAX_SHOW_CNT 10 +#define MAX_RESET_CNT 3 + +#define SDIO_EXIST 0x01 +#define SDIO_IGNORED 0x02 + +#define CHK_SDIO_EXIST(chip) ((chip)->sdio_func_exist & SDIO_EXIST) +#define SET_SDIO_EXIST(chip) ((chip)->sdio_func_exist |= SDIO_EXIST) +#define CLR_SDIO_EXIST(chip) ((chip)->sdio_func_exist &= ~SDIO_EXIST) + +#define CHK_SDIO_IGNORED(chip) ((chip)->sdio_func_exist & SDIO_IGNORED) +#define SET_SDIO_IGNORED(chip) ((chip)->sdio_func_exist |= SDIO_IGNORED) +#define CLR_SDIO_IGNORED(chip) ((chip)->sdio_func_exist &= ~SDIO_IGNORED) + +struct rtsx_chip { + rtsx_dev_t *rtsx; + + u32 int_reg; /* Bus interrupt pending register */ + char max_lun; + void *context; + + void *host_cmds_ptr; /* host commands buffer pointer */ + dma_addr_t host_cmds_addr; + int ci; /* Command Index */ + + void *host_sg_tbl_ptr; /* SG descriptor table */ + dma_addr_t host_sg_tbl_addr; + int sgi; /* SG entry index */ + + struct scsi_cmnd *srb; /* current srb */ + struct sense_data_t sense_buffer[MAX_ALLOWED_LUN_CNT]; + + int cur_clk; /* current card clock */ + + /* Current accessed card */ + int cur_card; + + unsigned long need_release; /* need release bit map */ + unsigned long need_reset; /* need reset bit map */ + /* Flag to indicate that this card is just resumed from SS state, + * and need released before being resetted + */ + unsigned long need_reinit; + + int rw_need_retry; + +#ifdef SUPPORT_OCP + u32 ocp_int; + u8 ocp_stat; +#endif + + u8 card_exist; /* card exist bit map (physical exist) */ + u8 card_ready; /* card ready bit map (reset successfully) */ + u8 card_fail; /* card reset fail bit map */ + u8 card_ejected; /* card ejected bit map */ + u8 card_wp; /* card write protected bit map */ + + u8 lun_mc; /* flag to indicate whether to answer MediaChange */ + +#ifndef LED_AUTO_BLINK + int led_toggle_counter; +#endif + + int sd_reset_counter; + int xd_reset_counter; + int ms_reset_counter; + + /* card bus width */ + u8 card_bus_width[MAX_ALLOWED_LUN_CNT]; + /* card capacity */ + u32 capacity[MAX_ALLOWED_LUN_CNT]; + /* read/write card function pointer */ + card_rw_func rw_card[MAX_ALLOWED_LUN_CNT]; + /* read/write capacity, used for GPIO Toggle */ + u32 rw_cap[MAX_ALLOWED_LUN_CNT]; + /* card to lun mapping table */ + u8 card2lun[32]; + /* lun to card mapping table */ + u8 lun2card[MAX_ALLOWED_LUN_CNT]; + + int rw_fail_cnt[MAX_ALLOWED_LUN_CNT]; + + int sd_show_cnt; + int xd_show_cnt; + int ms_show_cnt; + + /* card information */ + struct sd_info sd_card; + struct xd_info xd_card; + struct ms_info ms_card; + + struct spi_info spi; + +#ifdef _MSG_TRACE + struct trace_msg_t trace_msg[TRACE_ITEM_CNT]; + int msg_idx; +#endif + + int auto_delink_cnt; + int auto_delink_allowed; + + int aspm_enabled; + + int sdio_aspm; + int sdio_idle; + int sdio_counter; + u8 sdio_raw_data[12]; + + u8 sd_io; + u8 sd_int; + + u8 rtsx_flag; + + int ss_counter; + int idle_counter; + enum RTSX_STAT rtsx_stat; + + u16 vendor_id; + u16 product_id; + u8 ic_version; + + int driver_first_load; + +#ifdef HW_AUTO_SWITCH_SD_BUS + int sdio_in_charge; +#endif + + u8 aspm_level[2]; + + int chip_insert_with_sdio; + + /* Options */ + + int adma_mode; + + int auto_delink_en; + int ss_en; + u8 lun_mode; + u8 aspm_l0s_l1_en; + + int power_down_in_ss; + + int sdr104_en; + int ddr50_en; + int sdr50_en; + + int baro_pkg; + + int asic_code; + int phy_debug_mode; + int hw_bypass_sd; + int sdio_func_exist; + int aux_pwr_exist; + u8 ms_power_class_en; + + int mspro_formatter_enable; + + int remote_wakeup_en; + + int ignore_sd; + int use_hw_setting; + + int ss_idle_period; + + int dynamic_aspm; + + int fpga_sd_sdr104_clk; + int fpga_sd_ddr50_clk; + int fpga_sd_sdr50_clk; + int fpga_sd_hs_clk; + int fpga_mmc_52m_clk; + int fpga_ms_hg_clk; + int fpga_ms_4bit_clk; + int fpga_ms_1bit_clk; + + int asic_sd_sdr104_clk; + int asic_sd_ddr50_clk; + int asic_sd_sdr50_clk; + int asic_sd_hs_clk; + int asic_mmc_52m_clk; + int asic_ms_hg_clk; + int asic_ms_4bit_clk; + int asic_ms_1bit_clk; + + u8 ssc_depth_sd_sdr104; + u8 ssc_depth_sd_ddr50; + u8 ssc_depth_sd_sdr50; + u8 ssc_depth_sd_hs; + u8 ssc_depth_mmc_52m; + u8 ssc_depth_ms_hg; + u8 ssc_depth_ms_4bit; + u8 ssc_depth_low_speed; + + u8 card_drive_sel; + u8 sd30_drive_sel_1v8; + u8 sd30_drive_sel_3v3; + + u8 sd_400mA_ocp_thd; + u8 sd_800mA_ocp_thd; + u8 ms_ocp_thd; + + int ssc_en; + int msi_en; + + int xd_timeout; + int sd_timeout; + int ms_timeout; + int mspro_timeout; + + int auto_power_down; + + int sd_ddr_tx_phase; + int mmc_ddr_tx_phase; + int sd_default_tx_phase; + int sd_default_rx_phase; + + int pmos_pwr_on_interval; + int sd_voltage_switch_delay; + int s3_pwr_off_delay; + + int force_clkreq_0; + int ft2_fast_mode; + + int do_delink_before_power_down; + int polling_config; + int sdio_retry_cnt; + + int delink_stage1_step; + int delink_stage2_step; + int delink_stage3_step; + + int auto_delink_in_L1; + int hp_watch_bios_hotplug; + int support_ms_8bit; + + u8 blink_led; + u8 phy_voltage; + u8 max_payload; + + u32 sd_speed_prior; + u32 sd_current_prior; + u32 sd_ctl; +}; + +#define rtsx_set_stat(chip, stat) \ +do { \ + if ((stat) != RTSX_STAT_IDLE) { \ + (chip)->idle_counter = 0; \ + } \ + (chip)->rtsx_stat = (enum RTSX_STAT)(stat); \ +} while (0) +#define rtsx_get_stat(chip) ((chip)->rtsx_stat) +#define rtsx_chk_stat(chip, stat) ((chip)->rtsx_stat == (stat)) + +#define RTSX_SET_DELINK(chip) ((chip)->rtsx_flag |= 0x01) +#define RTSX_CLR_DELINK(chip) ((chip)->rtsx_flag &= 0xFE) +#define RTSX_TST_DELINK(chip) ((chip)->rtsx_flag & 0x01) + +#define CHECK_PID(chip, pid) ((chip)->product_id == (pid)) +#define CHECK_BARO_PKG(chip, pkg) ((chip)->baro_pkg == (pkg)) +#define CHECK_LUN_MODE(chip, mode) ((chip)->lun_mode == (mode)) + +/* Power down control */ +#define SSC_PDCTL 0x01 +#define OC_PDCTL 0x02 + +int rtsx_force_power_on(struct rtsx_chip *chip, u8 ctl); +int rtsx_force_power_down(struct rtsx_chip *chip, u8 ctl); + +void rtsx_disable_card_int(struct rtsx_chip *chip); +void rtsx_enable_card_int(struct rtsx_chip *chip); +void rtsx_enable_bus_int(struct rtsx_chip *chip); +void rtsx_disable_bus_int(struct rtsx_chip *chip); +int rtsx_reset_chip(struct rtsx_chip *chip); +int rtsx_init_chip(struct rtsx_chip *chip); +void rtsx_release_chip(struct rtsx_chip *chip); +void rtsx_polling_func(struct rtsx_chip *chip); +void rtsx_undo_delink(struct rtsx_chip *chip); +void rtsx_stop_cmd(struct rtsx_chip *chip, int card); +int rtsx_write_register(struct rtsx_chip *chip, u16 addr, u8 mask, u8 data); +int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data); +int rtsx_write_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 mask, u32 val); +int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val); +int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, int len); +int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, int len); +int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val); +int rtsx_read_phy_register(struct rtsx_chip *chip, u8 addr, u16 *val); +int rtsx_read_efuse(struct rtsx_chip *chip, u8 addr, u8 *val); +int rtsx_write_efuse(struct rtsx_chip *chip, u8 addr, u8 val); +int rtsx_clr_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit); +int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit); +int rtsx_check_link_ready(struct rtsx_chip *chip); +void rtsx_enter_ss(struct rtsx_chip *chip); +void rtsx_exit_ss(struct rtsx_chip *chip); +int rtsx_pre_handle_interrupt(struct rtsx_chip *chip); +void rtsx_enter_L1(struct rtsx_chip *chip); +void rtsx_exit_L1(struct rtsx_chip *chip); +void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat); +void rtsx_enable_aspm(struct rtsx_chip *chip); +void rtsx_disable_aspm(struct rtsx_chip *chip); +int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len); +int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len); +int rtsx_check_chip_exist(struct rtsx_chip *chip); + +#define RTSX_WRITE_REG(chip, addr, mask, data) \ +do { \ + int retval = rtsx_write_register((chip), (addr), (mask), (data)); \ + if (retval != STATUS_SUCCESS) { \ + TRACE_RET((chip), retval); \ + } \ +} while (0) + +#define RTSX_READ_REG(chip, addr, data) \ +do { \ + int retval = rtsx_read_register((chip), (addr), (data)); \ + if (retval != STATUS_SUCCESS) { \ + TRACE_RET((chip), retval); \ + } \ +} while (0) + +#endif /* __REALTEK_RTSX_CHIP_H */ diff --git a/drivers/staging/rts_pstor/rtsx_scsi.c b/drivers/staging/rts_pstor/rtsx_scsi.c new file mode 100644 index 000000000000..ce9fc162d6e0 --- /dev/null +++ b/drivers/staging/rts_pstor/rtsx_scsi.c @@ -0,0 +1,3203 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include +#include +#include + +#include "rtsx.h" +#include "rtsx_transport.h" +#include "rtsx_sys.h" +#include "rtsx_card.h" +#include "rtsx_chip.h" +#include "rtsx_scsi.h" +#include "sd.h" +#include "ms.h" +#include "spi.h" + +void scsi_show_command(struct scsi_cmnd *srb) +{ + char *what = NULL; + int i, unknown_cmd = 0; + + switch (srb->cmnd[0]) { + case TEST_UNIT_READY: what = "TEST_UNIT_READY"; break; + case REZERO_UNIT: what = "REZERO_UNIT"; break; + case REQUEST_SENSE: what = "REQUEST_SENSE"; break; + case FORMAT_UNIT: what = "FORMAT_UNIT"; break; + case READ_BLOCK_LIMITS: what = "READ_BLOCK_LIMITS"; break; + case REASSIGN_BLOCKS: what = "REASSIGN_BLOCKS"; break; + case READ_6: what = "READ_6"; break; + case WRITE_6: what = "WRITE_6"; break; + case SEEK_6: what = "SEEK_6"; break; + case READ_REVERSE: what = "READ_REVERSE"; break; + case WRITE_FILEMARKS: what = "WRITE_FILEMARKS"; break; + case SPACE: what = "SPACE"; break; + case INQUIRY: what = "INQUIRY"; break; + case RECOVER_BUFFERED_DATA: what = "RECOVER_BUFFERED_DATA"; break; + case MODE_SELECT: what = "MODE_SELECT"; break; + case RESERVE: what = "RESERVE"; break; + case RELEASE: what = "RELEASE"; break; + case COPY: what = "COPY"; break; + case ERASE: what = "ERASE"; break; + case MODE_SENSE: what = "MODE_SENSE"; break; + case START_STOP: what = "START_STOP"; break; + case RECEIVE_DIAGNOSTIC: what = "RECEIVE_DIAGNOSTIC"; break; + case SEND_DIAGNOSTIC: what = "SEND_DIAGNOSTIC"; break; + case ALLOW_MEDIUM_REMOVAL: what = "ALLOW_MEDIUM_REMOVAL"; break; + case SET_WINDOW: what = "SET_WINDOW"; break; + case READ_CAPACITY: what = "READ_CAPACITY"; break; + case READ_10: what = "READ_10"; break; + case WRITE_10: what = "WRITE_10"; break; + case SEEK_10: what = "SEEK_10"; break; + case WRITE_VERIFY: what = "WRITE_VERIFY"; break; + case VERIFY: what = "VERIFY"; break; + case SEARCH_HIGH: what = "SEARCH_HIGH"; break; + case SEARCH_EQUAL: what = "SEARCH_EQUAL"; break; + case SEARCH_LOW: what = "SEARCH_LOW"; break; + case SET_LIMITS: what = "SET_LIMITS"; break; + case READ_POSITION: what = "READ_POSITION"; break; + case SYNCHRONIZE_CACHE: what = "SYNCHRONIZE_CACHE"; break; + case LOCK_UNLOCK_CACHE: what = "LOCK_UNLOCK_CACHE"; break; + case READ_DEFECT_DATA: what = "READ_DEFECT_DATA"; break; + case MEDIUM_SCAN: what = "MEDIUM_SCAN"; break; + case COMPARE: what = "COMPARE"; break; + case COPY_VERIFY: what = "COPY_VERIFY"; break; + case WRITE_BUFFER: what = "WRITE_BUFFER"; break; + case READ_BUFFER: what = "READ_BUFFER"; break; + case UPDATE_BLOCK: what = "UPDATE_BLOCK"; break; + case READ_LONG: what = "READ_LONG"; break; + case WRITE_LONG: what = "WRITE_LONG"; break; + case CHANGE_DEFINITION: what = "CHANGE_DEFINITION"; break; + case WRITE_SAME: what = "WRITE_SAME"; break; + case GPCMD_READ_SUBCHANNEL: what = "READ SUBCHANNEL"; break; + case READ_TOC: what = "READ_TOC"; break; + case GPCMD_READ_HEADER: what = "READ HEADER"; break; + case GPCMD_PLAY_AUDIO_10: what = "PLAY AUDIO (10)"; break; + case GPCMD_PLAY_AUDIO_MSF: what = "PLAY AUDIO MSF"; break; + case GPCMD_GET_EVENT_STATUS_NOTIFICATION: + what = "GET EVENT/STATUS NOTIFICATION"; break; + case GPCMD_PAUSE_RESUME: what = "PAUSE/RESUME"; break; + case LOG_SELECT: what = "LOG_SELECT"; break; + case LOG_SENSE: what = "LOG_SENSE"; break; + case GPCMD_STOP_PLAY_SCAN: what = "STOP PLAY/SCAN"; break; + case GPCMD_READ_DISC_INFO: what = "READ DISC INFORMATION"; break; + case GPCMD_READ_TRACK_RZONE_INFO: + what = "READ TRACK INFORMATION"; break; + case GPCMD_RESERVE_RZONE_TRACK: what = "RESERVE TRACK"; break; + case GPCMD_SEND_OPC: what = "SEND OPC"; break; + case MODE_SELECT_10: what = "MODE_SELECT_10"; break; + case GPCMD_REPAIR_RZONE_TRACK: what = "REPAIR TRACK"; break; + case 0x59: what = "READ MASTER CUE"; break; + case MODE_SENSE_10: what = "MODE_SENSE_10"; break; + case GPCMD_CLOSE_TRACK: what = "CLOSE TRACK/SESSION"; break; + case 0x5C: what = "READ BUFFER CAPACITY"; break; + case 0x5D: what = "SEND CUE SHEET"; break; + case GPCMD_BLANK: what = "BLANK"; break; + case REPORT_LUNS: what = "REPORT LUNS"; break; + case MOVE_MEDIUM: what = "MOVE_MEDIUM or PLAY AUDIO (12)"; break; + case READ_12: what = "READ_12"; break; + case WRITE_12: what = "WRITE_12"; break; + case WRITE_VERIFY_12: what = "WRITE_VERIFY_12"; break; + case SEARCH_HIGH_12: what = "SEARCH_HIGH_12"; break; + case SEARCH_EQUAL_12: what = "SEARCH_EQUAL_12"; break; + case SEARCH_LOW_12: what = "SEARCH_LOW_12"; break; + case SEND_VOLUME_TAG: what = "SEND_VOLUME_TAG"; break; + case READ_ELEMENT_STATUS: what = "READ_ELEMENT_STATUS"; break; + case GPCMD_READ_CD_MSF: what = "READ CD MSF"; break; + case GPCMD_SCAN: what = "SCAN"; break; + case GPCMD_SET_SPEED: what = "SET CD SPEED"; break; + case GPCMD_MECHANISM_STATUS: what = "MECHANISM STATUS"; break; + case GPCMD_READ_CD: what = "READ CD"; break; + case 0xE1: what = "WRITE CONTINUE"; break; + case WRITE_LONG_2: what = "WRITE_LONG_2"; break; + case VENDOR_CMND: what = "Realtek's vendor command"; break; + default: what = "(unknown command)"; unknown_cmd = 1; break; + } + + if (srb->cmnd[0] != TEST_UNIT_READY) { + RTSX_DEBUGP("Command %s (%d bytes)\n", what, srb->cmd_len); + } + if (unknown_cmd) { + RTSX_DEBUGP(""); + for (i = 0; i < srb->cmd_len && i < 16; i++) + RTSX_DEBUGPN(" %02x", srb->cmnd[i]); + RTSX_DEBUGPN("\n"); + } +} + +void set_sense_type(struct rtsx_chip *chip, unsigned int lun, int sense_type) +{ + switch (sense_type) { + case SENSE_TYPE_MEDIA_CHANGE: + set_sense_data(chip, lun, CUR_ERR, 0x06, 0, 0x28, 0, 0, 0); + break; + + case SENSE_TYPE_MEDIA_NOT_PRESENT: + set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x3A, 0, 0, 0); + break; + + case SENSE_TYPE_MEDIA_LBA_OVER_RANGE: + set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x21, 0, 0, 0); + break; + + case SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT: + set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x25, 0, 0, 0); + break; + + case SENSE_TYPE_MEDIA_WRITE_PROTECT: + set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x27, 0, 0, 0); + break; + + case SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR: + set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x11, 0, 0, 0); + break; + + case SENSE_TYPE_MEDIA_WRITE_ERR: + set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x02, 0, 0); + break; + + case SENSE_TYPE_MEDIA_INVALID_CMD_FIELD: + set_sense_data(chip, lun, CUR_ERR, ILGAL_REQ, 0, + ASC_INVLD_CDB, ASCQ_INVLD_CDB, CDB_ILLEGAL, 1); + break; + + case SENSE_TYPE_FORMAT_IN_PROGRESS: + set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, 0, 0); + break; + + case SENSE_TYPE_FORMAT_CMD_FAILED: + set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x31, 0x01, 0, 0); + break; + +#ifdef SUPPORT_MAGIC_GATE + case SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB: + set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x02, 0, 0); + break; + + case SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN: + set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x00, 0, 0); + break; + + case SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM: + set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x30, 0x00, 0, 0); + break; + + case SENSE_TYPE_MG_WRITE_ERR: + set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x00, 0, 0); + break; +#endif + +#ifdef SUPPORT_SD_LOCK + case SENSE_TYPE_MEDIA_READ_FORBIDDEN: + set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x11, 0x13, 0, 0); + break; +#endif + + case SENSE_TYPE_NO_SENSE: + default: + set_sense_data(chip, lun, CUR_ERR, 0, 0, 0, 0, 0, 0); + break; + } +} + +void set_sense_data(struct rtsx_chip *chip, unsigned int lun, u8 err_code, u8 sense_key, + u32 info, u8 asc, u8 ascq, u8 sns_key_info0, u16 sns_key_info1) +{ + struct sense_data_t *sense = &(chip->sense_buffer[lun]); + + sense->err_code = err_code; + sense->sense_key = sense_key; + sense->info[0] = (u8)(info >> 24); + sense->info[1] = (u8)(info >> 16); + sense->info[2] = (u8)(info >> 8); + sense->info[3] = (u8)info; + + sense->ad_sense_len = sizeof(struct sense_data_t) - 8; + sense->asc = asc; + sense->ascq = ascq; + if (sns_key_info0 != 0) { + sense->sns_key_info[0] = SKSV | sns_key_info0; + sense->sns_key_info[1] = (sns_key_info1 & 0xf0) >> 8; + sense->sns_key_info[2] = sns_key_info1 & 0x0f; + } +} + +static int test_unit_ready(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + return TRANSPORT_FAILED; + } + + if (!(CHK_BIT(chip->lun_mc, lun))) { + SET_BIT(chip->lun_mc, lun); + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + return TRANSPORT_FAILED; + } + +#ifdef SUPPORT_SD_LOCK + if (get_lun_card(chip, SCSI_LUN(srb)) == SD_CARD) { + struct sd_info *sd_card = &(chip->sd_card); + if (sd_card->sd_lock_notify) { + sd_card->sd_lock_notify = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + return TRANSPORT_FAILED; + } else if (sd_card->sd_lock_status & SD_LOCKED) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN); + return TRANSPORT_FAILED; + } + } +#endif + + return TRANSPORT_GOOD; +} + +unsigned char formatter_inquiry_str[20] = { + 'M', 'E', 'M', 'O', 'R', 'Y', 'S', 'T', 'I', 'C', 'K', +#ifdef SUPPORT_MAGIC_GATE + '-', 'M', 'G', /* Byte[47:49] */ +#else + 0x20, 0x20, 0x20, /* Byte[47:49] */ +#endif + +#ifdef SUPPORT_MAGIC_GATE + 0x0B, /* Byte[50]: MG, MS, MSPro, MSXC */ +#else + 0x09, /* Byte[50]: MS, MSPro, MSXC */ +#endif + 0x00, /* Byte[51]: Category Specific Commands */ + 0x00, /* Byte[52]: Access Control and feature */ + 0x20, 0x20, 0x20, /* Byte[53:55] */ +}; + +static int inquiry(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + char *inquiry_default = (char *)"Generic-xD/SD/M.S. 1.00 "; + char *inquiry_sdms = (char *)"Generic-SD/MemoryStick 1.00 "; + char *inquiry_sd = (char *)"Generic-SD/MMC 1.00 "; + char *inquiry_ms = (char *)"Generic-MemoryStick 1.00 "; + char *inquiry_string; + unsigned char sendbytes; + unsigned char *buf; + u8 card = get_lun_card(chip, lun); + int pro_formatter_flag = 0; + unsigned char inquiry_buf[] = { + QULIFIRE|DRCT_ACCESS_DEV, + RMB_DISC|0x0D, + 0x00, + 0x01, + 0x1f, + 0x02, + 0, + REL_ADR|WBUS_32|WBUS_16|SYNC|LINKED|CMD_QUE|SFT_RE, + }; + + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + if (chip->lun2card[lun] == SD_CARD) { + inquiry_string = inquiry_sd; + } else { + inquiry_string = inquiry_ms; + } + } else if (CHECK_LUN_MODE(chip, SD_MS_1LUN)) { + inquiry_string = inquiry_sdms; + } else { + inquiry_string = inquiry_default; + } + + buf = vmalloc(scsi_bufflen(srb)); + if (buf == NULL) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + +#ifdef SUPPORT_MAGIC_GATE + if ((chip->mspro_formatter_enable) && + (chip->lun2card[lun] & MS_CARD)) +#else + if (chip->mspro_formatter_enable) +#endif + { + if (!card || (card == MS_CARD)) { + pro_formatter_flag = 1; + } + } + + if (pro_formatter_flag) { + if (scsi_bufflen(srb) < 56) { + sendbytes = (unsigned char)(scsi_bufflen(srb)); + } else { + sendbytes = 56; + } + } else { + if (scsi_bufflen(srb) < 36) { + sendbytes = (unsigned char)(scsi_bufflen(srb)); + } else { + sendbytes = 36; + } + } + + if (sendbytes > 8) { + memcpy(buf, inquiry_buf, 8); + memcpy(buf + 8, inquiry_string, sendbytes - 8); + if (pro_formatter_flag) { + /* Additional Length */ + buf[4] = 0x33; + } + } else { + memcpy(buf, inquiry_buf, sendbytes); + } + + if (pro_formatter_flag) { + if (sendbytes > 36) { + memcpy(buf + 36, formatter_inquiry_str, sendbytes - 36); + } + } + + scsi_set_resid(srb, 0); + + rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); + vfree(buf); + + return TRANSPORT_GOOD; +} + + +static int start_stop_unit(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + + scsi_set_resid(srb, scsi_bufflen(srb)); + + if (srb->cmnd[1] == 1) + return TRANSPORT_GOOD; + + switch (srb->cmnd[0x4]) { + case STOP_MEDIUM: + /* Media disabled */ + return TRANSPORT_GOOD; + + case UNLOAD_MEDIUM: + /* Media shall be unload */ + if (check_card_ready(chip, lun)) + eject_card(chip, lun); + return TRANSPORT_GOOD; + + case MAKE_MEDIUM_READY: + case LOAD_MEDIUM: + if (check_card_ready(chip, lun)) { + return TRANSPORT_GOOD; + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + break; + } + + TRACE_RET(chip, TRANSPORT_ERROR); +} + + +static int allow_medium_removal(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int prevent; + + prevent = srb->cmnd[4] & 0x1; + + scsi_set_resid(srb, 0); + + if (prevent) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return TRANSPORT_GOOD; +} + + +static int request_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct sense_data_t *sense; + unsigned int lun = SCSI_LUN(srb); + struct ms_info *ms_card = &(chip->ms_card); + unsigned char *tmp, *buf; + + sense = &(chip->sense_buffer[lun]); + + if ((get_lun_card(chip, lun) == MS_CARD) && ms_card->pro_under_formatting) { + if (ms_card->format_status == FORMAT_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + ms_card->pro_under_formatting = 0; + ms_card->progress = 0; + } else if (ms_card->format_status == FORMAT_IN_PROGRESS) { + /* Logical Unit Not Ready Format in Progress */ + set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, + 0, (u16)(ms_card->progress)); + } else { + /* Format Command Failed */ + set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); + ms_card->pro_under_formatting = 0; + ms_card->progress = 0; + } + + rtsx_set_stat(chip, RTSX_STAT_RUN); + } + + buf = vmalloc(scsi_bufflen(srb)); + if (buf == NULL) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + tmp = (unsigned char *)sense; + memcpy(buf, tmp, scsi_bufflen(srb)); + + rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); + vfree(buf); + + scsi_set_resid(srb, 0); + /* Reset Sense Data */ + set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + return TRANSPORT_GOOD; +} + +static void ms_mode_sense(struct rtsx_chip *chip, u8 cmd, + int lun, u8 *buf, int buf_len) +{ + struct ms_info *ms_card = &(chip->ms_card); + int sys_info_offset; + int data_size = buf_len; + int support_format = 0; + int i = 0; + + if (cmd == MODE_SENSE) { + sys_info_offset = 8; + if (data_size > 0x68) { + data_size = 0x68; + } + buf[i++] = 0x67; /* Mode Data Length */ + } else { + sys_info_offset = 12; + if (data_size > 0x6C) { + data_size = 0x6C; + } + buf[i++] = 0x00; /* Mode Data Length (MSB) */ + buf[i++] = 0x6A; /* Mode Data Length (LSB) */ + } + + /* Medium Type Code */ + if (check_card_ready(chip, lun)) { + if (CHK_MSXC(ms_card)) { + support_format = 1; + buf[i++] = 0x40; + } else if (CHK_MSPRO(ms_card)) { + support_format = 1; + buf[i++] = 0x20; + } else { + buf[i++] = 0x10; + } + + /* WP */ + if (check_card_wp(chip, lun)) { + buf[i++] = 0x80; + } else { + buf[i++] = 0x00; + } + } else { + buf[i++] = 0x00; /* MediaType */ + buf[i++] = 0x00; /* WP */ + } + + buf[i++] = 0x00; /* Reserved */ + + if (cmd == MODE_SENSE_10) { + buf[i++] = 0x00; /* Reserved */ + buf[i++] = 0x00; /* Block descriptor length(MSB) */ + buf[i++] = 0x00; /* Block descriptor length(LSB) */ + + /* The Following Data is the content of "Page 0x20" */ + if (data_size >= 9) + buf[i++] = 0x20; /* Page Code */ + if (data_size >= 10) + buf[i++] = 0x62; /* Page Length */ + if (data_size >= 11) + buf[i++] = 0x00; /* No Access Control */ + if (data_size >= 12) { + if (support_format) { + buf[i++] = 0xC0; /* SF, SGM */ + } else { + buf[i++] = 0x00; + } + } + } else { + /* The Following Data is the content of "Page 0x20" */ + if (data_size >= 5) + buf[i++] = 0x20; /* Page Code */ + if (data_size >= 6) + buf[i++] = 0x62; /* Page Length */ + if (data_size >= 7) + buf[i++] = 0x00; /* No Access Control */ + if (data_size >= 8) { + if (support_format) { + buf[i++] = 0xC0; /* SF, SGM */ + } else { + buf[i++] = 0x00; + } + } + } + + if (data_size > sys_info_offset) { + /* 96 Bytes Attribute Data */ + int len = data_size - sys_info_offset; + len = (len < 96) ? len : 96; + + memcpy(buf + sys_info_offset, ms_card->raw_sys_info, len); + } +} + +static int mode_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + unsigned int dataSize; + int status; + int pro_formatter_flag; + unsigned char pageCode, *buf; + u8 card = get_lun_card(chip, lun); + +#ifndef SUPPORT_MAGIC_GATE + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + scsi_set_resid(srb, scsi_bufflen(srb)); + TRACE_RET(chip, TRANSPORT_FAILED); + } +#endif + + pro_formatter_flag = 0; + dataSize = 8; +#ifdef SUPPORT_MAGIC_GATE + if ((chip->lun2card[lun] & MS_CARD)) { + if (!card || (card == MS_CARD)) { + dataSize = 108; + if (chip->mspro_formatter_enable) { + pro_formatter_flag = 1; + } + } + } +#else + if (card == MS_CARD) { + if (chip->mspro_formatter_enable) { + pro_formatter_flag = 1; + dataSize = 108; + } + } +#endif + + buf = kmalloc(dataSize, GFP_KERNEL); + if (buf == NULL) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + pageCode = srb->cmnd[2] & 0x3f; + + if ((pageCode == 0x3F) || (pageCode == 0x1C) || + (pageCode == 0x00) || + (pro_formatter_flag && (pageCode == 0x20))) { + if (srb->cmnd[0] == MODE_SENSE) { + if ((pageCode == 0x3F) || (pageCode == 0x20)) { + ms_mode_sense(chip, srb->cmnd[0], + lun, buf, dataSize); + } else { + dataSize = 4; + buf[0] = 0x03; + buf[1] = 0x00; + if (check_card_wp(chip, lun)) { + buf[2] = 0x80; + } else { + buf[2] = 0x00; + } + buf[3] = 0x00; + } + } else { + if ((pageCode == 0x3F) || (pageCode == 0x20)) { + ms_mode_sense(chip, srb->cmnd[0], + lun, buf, dataSize); + } else { + dataSize = 8; + buf[0] = 0x00; + buf[1] = 0x06; + buf[2] = 0x00; + if (check_card_wp(chip, lun)) { + buf[3] = 0x80; + } else { + buf[3] = 0x00; + } + buf[4] = 0x00; + buf[5] = 0x00; + buf[6] = 0x00; + buf[7] = 0x00; + } + } + status = TRANSPORT_GOOD; + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + scsi_set_resid(srb, scsi_bufflen(srb)); + status = TRANSPORT_FAILED; + } + + if (status == TRANSPORT_GOOD) { + unsigned int len = min(scsi_bufflen(srb), dataSize); + rtsx_stor_set_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + } + kfree(buf); + + return status; +} + +static int read_write(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ +#ifdef SUPPORT_SD_LOCK + struct sd_info *sd_card = &(chip->sd_card); +#endif + unsigned int lun = SCSI_LUN(srb); + int retval; + u32 start_sec; + u16 sec_cnt; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + if (!check_card_ready(chip, lun) || (get_card_size(chip, lun) == 0)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (!(CHK_BIT(chip->lun_mc, lun))) { + SET_BIT(chip->lun_mc, lun); + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + return TRANSPORT_FAILED; + } + +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_erase_status) { + /* Accessing to any card is forbidden + * until the erase procedure of SD is completed + */ + RTSX_DEBUGP("SD card being erased!\n"); + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (get_lun_card(chip, lun) == SD_CARD) { + if (sd_card->sd_lock_status & SD_LOCKED) { + RTSX_DEBUGP("SD card locked!\n"); + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } +#endif + + if ((srb->cmnd[0] == READ_10) || (srb->cmnd[0] == WRITE_10)) { + start_sec = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) | + ((u32)srb->cmnd[4] << 8) | ((u32)srb->cmnd[5]); + sec_cnt = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; + } else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6)) { + start_sec = ((u32)(srb->cmnd[1] & 0x1F) << 16) | + ((u32)srb->cmnd[2] << 8) | ((u32)srb->cmnd[3]); + sec_cnt = srb->cmnd[4]; + } else if ((srb->cmnd[0] == VENDOR_CMND) && (srb->cmnd[1] == SCSI_APP_CMD) && + ((srb->cmnd[2] == PP_READ10) || (srb->cmnd[2] == PP_WRITE10))) { + start_sec = ((u32)srb->cmnd[4] << 24) | ((u32)srb->cmnd[5] << 16) | + ((u32)srb->cmnd[6] << 8) | ((u32)srb->cmnd[7]); + sec_cnt = ((u16)(srb->cmnd[9]) << 8) | srb->cmnd[10]; + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + /* In some test, we will receive a start_sec like 0xFFFFFFFF. + * In this situation, start_sec + sec_cnt will overflow, so we + * need to judge start_sec at first + */ + if ((start_sec > get_card_size(chip, lun)) || + ((start_sec + sec_cnt) > get_card_size(chip, lun))) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LBA_OVER_RANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (sec_cnt == 0) { + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; + } + + if (chip->rw_fail_cnt[lun] == 3) { + RTSX_DEBUGP("read/write fail three times in succession\n"); + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + } + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (srb->sc_data_direction == DMA_TO_DEVICE) { + if (check_card_wp(chip, lun)) { + RTSX_DEBUGP("Write protected card!\n"); + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + if (CHECK_PID(chip, 0x5209) && chip->max_payload) { + u8 val = 0x10 | (chip->max_payload << 5); + retval = rtsx_write_cfg_dw(chip, 0, 0x78, 0xFF, val); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + } + } + + retval = card_rw(srb, chip, start_sec, sec_cnt); + if (retval != STATUS_SUCCESS) { + if (chip->need_release & chip->lun2card[lun]) { + chip->rw_fail_cnt[lun] = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + } else { + chip->rw_fail_cnt[lun]++; + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + } + } + retval = TRANSPORT_FAILED; + TRACE_GOTO(chip, Exit); + } else { + chip->rw_fail_cnt[lun] = 0; + retval = TRANSPORT_GOOD; + } + + scsi_set_resid(srb, 0); + +Exit: + if (srb->sc_data_direction == DMA_TO_DEVICE) { + if (CHECK_PID(chip, 0x5209) && chip->max_payload) { + retval = rtsx_write_cfg_dw(chip, 0, 0x78, 0xFF, 0x10); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + } + } + + return retval; +} + +static int read_format_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned char *buf; + unsigned int lun = SCSI_LUN(srb); + unsigned int buf_len; + u8 card = get_lun_card(chip, lun); + u32 card_size; + int desc_cnt; + int i = 0; + + if (!check_card_ready(chip, lun)) { + if (!chip->mspro_formatter_enable) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + buf_len = (scsi_bufflen(srb) > 12) ? 0x14 : 12; + + buf = kmalloc(buf_len, GFP_KERNEL); + if (buf == NULL) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + buf[i++] = 0; + buf[i++] = 0; + buf[i++] = 0; + + /* Capacity List Length */ + if ((buf_len > 12) && chip->mspro_formatter_enable && + (chip->lun2card[lun] & MS_CARD) && + (!card || (card == MS_CARD))) { + buf[i++] = 0x10; + desc_cnt = 2; + } else { + buf[i++] = 0x08; + desc_cnt = 1; + } + + while (desc_cnt) { + if (check_card_ready(chip, lun)) { + card_size = get_card_size(chip, lun); + buf[i++] = (unsigned char)(card_size >> 24); + buf[i++] = (unsigned char)(card_size >> 16); + buf[i++] = (unsigned char)(card_size >> 8); + buf[i++] = (unsigned char)card_size; + + if (desc_cnt == 2) { + buf[i++] = 2; + } else { + buf[i++] = 0; + } + } else { + buf[i++] = 0xFF; + buf[i++] = 0xFF; + buf[i++] = 0xFF; + buf[i++] = 0xFF; + + if (desc_cnt == 2) { + buf[i++] = 3; + } else { + buf[i++] = 0; + } + } + + buf[i++] = 0x00; + buf[i++] = 0x02; + buf[i++] = 0x00; + + desc_cnt--; + } + + buf_len = min(scsi_bufflen(srb), buf_len); + rtsx_stor_set_xfer_buf(buf, buf_len, srb); + kfree(buf); + + scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); + + return TRANSPORT_GOOD; +} + +static int read_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned char *buf; + unsigned int lun = SCSI_LUN(srb); + u32 card_size; + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (!(CHK_BIT(chip->lun_mc, lun))) { + SET_BIT(chip->lun_mc, lun); + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + return TRANSPORT_FAILED; + } + + buf = kmalloc(8, GFP_KERNEL); + if (buf == NULL) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + card_size = get_card_size(chip, lun); + buf[0] = (unsigned char)((card_size - 1) >> 24); + buf[1] = (unsigned char)((card_size - 1) >> 16); + buf[2] = (unsigned char)((card_size - 1) >> 8); + buf[3] = (unsigned char)(card_size - 1); + + buf[4] = 0x00; + buf[5] = 0x00; + buf[6] = 0x02; + buf[7] = 0x00; + + rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); + kfree(buf); + + scsi_set_resid(srb, 0); + + return TRANSPORT_GOOD; +} + +static int read_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned short len, i; + int retval; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; + + buf = (u8 *)vmalloc(len); + if (!buf) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + for (i = 0; i < len; i++) { + retval = spi_read_eeprom(chip, i, buf + i); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); + rtsx_stor_set_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + vfree(buf); + + return TRANSPORT_GOOD; +} + +static int write_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned short len, i; + int retval; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (len == 511) { + retval = spi_erase_eeprom_chip(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } else { + len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); + buf = (u8 *)vmalloc(len); + if (buf == NULL) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + rtsx_stor_get_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + for (i = 0; i < len; i++) { + retval = spi_write_eeprom(chip, i, buf[i]); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + vfree(buf); + } + + return TRANSPORT_GOOD; +} + +static int read_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned short addr, len, i; + int retval; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = ((u16)srb->cmnd[2] << 8) | srb->cmnd[3]; + len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; + + if (addr < 0xFC00) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + buf = (u8 *)vmalloc(len); + if (!buf) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + for (i = 0; i < len; i++) { + retval = rtsx_read_register(chip, addr + i, buf + i); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); + rtsx_stor_set_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + vfree(buf); + + return TRANSPORT_GOOD; +} + +static int write_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned short addr, len, i; + int retval; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = ((u16)srb->cmnd[2] << 8) | srb->cmnd[3]; + len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; + + if (addr < 0xFC00) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); + buf = (u8 *)vmalloc(len); + if (buf == NULL) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + rtsx_stor_get_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + for (i = 0; i < len; i++) { + retval = rtsx_write_register(chip, addr + i, 0xFF, buf[i]); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + vfree(buf); + + return TRANSPORT_GOOD; +} + +static int get_sd_csd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + unsigned int lun = SCSI_LUN(srb); + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (get_lun_card(chip, lun) != SD_CARD) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + scsi_set_resid(srb, 0); + rtsx_stor_set_xfer_buf(sd_card->raw_csd, scsi_bufflen(srb), srb); + + return TRANSPORT_GOOD; +} + +static int toggle_gpio_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + u8 gpio = srb->cmnd[2]; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + if (gpio > 3) + gpio = 1; + toggle_gpio(chip, gpio); + + return TRANSPORT_GOOD; +} + +#ifdef _MSG_TRACE +static int trace_msg_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned char *ptr, *buf = NULL; + int i, msg_cnt; + u8 clear; + unsigned int buf_len; + + buf_len = 4 + ((2 + MSG_FUNC_LEN + MSG_FILE_LEN + TIME_VAL_LEN) * TRACE_ITEM_CNT); + + if ((scsi_bufflen(srb) < buf_len) || (scsi_sglist(srb) == NULL)) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + clear = srb->cmnd[2]; + + buf = (unsigned char *)vmalloc(scsi_bufflen(srb)); + if (buf == NULL) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + ptr = buf; + + if (chip->trace_msg[chip->msg_idx].valid) { + msg_cnt = TRACE_ITEM_CNT; + } else { + msg_cnt = chip->msg_idx; + } + *(ptr++) = (u8)(msg_cnt >> 24); + *(ptr++) = (u8)(msg_cnt >> 16); + *(ptr++) = (u8)(msg_cnt >> 8); + *(ptr++) = (u8)msg_cnt; + RTSX_DEBUGP("Trace message count is %d\n", msg_cnt); + + for (i = 1; i <= msg_cnt; i++) { + int j, idx; + + idx = chip->msg_idx - i; + if (idx < 0) + idx += TRACE_ITEM_CNT; + + *(ptr++) = (u8)(chip->trace_msg[idx].line >> 8); + *(ptr++) = (u8)(chip->trace_msg[idx].line); + for (j = 0; j < MSG_FUNC_LEN; j++) { + *(ptr++) = chip->trace_msg[idx].func[j]; + } + for (j = 0; j < MSG_FILE_LEN; j++) { + *(ptr++) = chip->trace_msg[idx].file[j]; + } + for (j = 0; j < TIME_VAL_LEN; j++) { + *(ptr++) = chip->trace_msg[idx].timeval_buf[j]; + } + } + + rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); + vfree(buf); + + if (clear) { + chip->msg_idx = 0; + for (i = 0; i < TRACE_ITEM_CNT; i++) + chip->trace_msg[i].valid = 0; + } + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; +} +#endif + +static int read_host_reg(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + u8 addr, buf[4]; + u32 val; + unsigned int len; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = srb->cmnd[4]; + + val = rtsx_readl(chip, addr); + RTSX_DEBUGP("Host register (0x%x): 0x%x\n", addr, val); + + buf[0] = (u8)(val >> 24); + buf[1] = (u8)(val >> 16); + buf[2] = (u8)(val >> 8); + buf[3] = (u8)val; + + len = min(scsi_bufflen(srb), (unsigned int)4); + rtsx_stor_set_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + return TRANSPORT_GOOD; +} + +static int write_host_reg(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + u8 addr, buf[4]; + u32 val; + unsigned int len; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = srb->cmnd[4]; + + len = min(scsi_bufflen(srb), (unsigned int)4); + rtsx_stor_get_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + val = ((u32)buf[0] << 24) | ((u32)buf[1] << 16) | ((u32)buf[2] << 8) | buf[3]; + + rtsx_writel(chip, addr, val); + + return TRANSPORT_GOOD; +} + +static int set_variable(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned lun = SCSI_LUN(srb); + + if (srb->cmnd[3] == 1) { + /* Variable Clock */ + struct xd_info *xd_card = &(chip->xd_card); + struct sd_info *sd_card = &(chip->sd_card); + struct ms_info *ms_card = &(chip->ms_card); + + switch (srb->cmnd[4]) { + case XD_CARD: + xd_card->xd_clock = srb->cmnd[5]; + break; + + case SD_CARD: + sd_card->sd_clock = srb->cmnd[5]; + break; + + case MS_CARD: + ms_card->ms_clock = srb->cmnd[5]; + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } else if (srb->cmnd[3] == 2) { + if (srb->cmnd[4]) { + chip->blink_led = 1; + } else { + int retval; + + chip->blink_led = 0; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + turn_off_led(chip, LED_GPIO); + } + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return TRANSPORT_GOOD; +} + +static int get_variable(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + + if (srb->cmnd[3] == 1) { + struct xd_info *xd_card = &(chip->xd_card); + struct sd_info *sd_card = &(chip->sd_card); + struct ms_info *ms_card = &(chip->ms_card); + u8 tmp; + + switch (srb->cmnd[4]) { + case XD_CARD: + tmp = (u8)(xd_card->xd_clock); + break; + + case SD_CARD: + tmp = (u8)(sd_card->sd_clock); + break; + + case MS_CARD: + tmp = (u8)(ms_card->ms_clock); + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + rtsx_stor_set_xfer_buf(&tmp, 1, srb); + } else if (srb->cmnd[3] == 2) { + u8 tmp = chip->blink_led; + rtsx_stor_set_xfer_buf(&tmp, 1, srb); + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return TRANSPORT_GOOD; +} + +static int dma_access_ring_buffer(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + unsigned int lun = SCSI_LUN(srb); + u16 len; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + len = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; + len = min(len, (u16)scsi_bufflen(srb)); + + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + RTSX_DEBUGP("Read from device\n"); + } else { + RTSX_DEBUGP("Write to device\n"); + } + + retval = rtsx_transfer_data(chip, 0, scsi_sglist(srb), len, + scsi_sg_count(srb), srb->sc_data_direction, 1000); + if (retval < 0) { + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + } + TRACE_RET(chip, TRANSPORT_FAILED); + } + scsi_set_resid(srb, 0); + + return TRANSPORT_GOOD; +} + +static int get_dev_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + struct ms_info *ms_card = &(chip->ms_card); + int buf_len; + unsigned int lun = SCSI_LUN(srb); + u8 card = get_lun_card(chip, lun); + u8 status[32]; +#ifdef SUPPORT_OCP + u8 oc_now_mask = 0, oc_ever_mask = 0; +#endif + + memset(status, 0, 32); + + status[0] = (u8)(chip->product_id); + status[1] = chip->ic_version; + + if (chip->auto_delink_en) { + status[2] = 0x10; + } else { + status[2] = 0x00; + } + + status[3] = 20; + status[4] = 10; + status[5] = 05; + status[6] = 21; + + if (chip->card_wp) { + status[7] = 0x20; + } else { + status[7] = 0x00; + } + +#ifdef SUPPORT_OCP + status[8] = 0; + if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (chip->lun2card[lun] == MS_CARD)) { + oc_now_mask = MS_OC_NOW; + oc_ever_mask = MS_OC_EVER; + } else { + oc_now_mask = SD_OC_NOW; + oc_ever_mask = SD_OC_EVER; + } + + if (chip->ocp_stat & oc_now_mask) { + status[8] |= 0x02; + } + if (chip->ocp_stat & oc_ever_mask) { + status[8] |= 0x01; + } +#endif + + if (card == SD_CARD) { + if (CHK_SD(sd_card)) { + if (CHK_SD_HCXC(sd_card)) { + if (sd_card->capacity > 0x4000000) { + status[0x0E] = 0x02; + } else { + status[0x0E] = 0x01; + } + } else { + status[0x0E] = 0x00; + } + + if (CHK_SD_SDR104(sd_card)) { + status[0x0F] = 0x03; + } else if (CHK_SD_DDR50(sd_card)) { + status[0x0F] = 0x04; + } else if (CHK_SD_SDR50(sd_card)) { + status[0x0F] = 0x02; + } else if (CHK_SD_HS(sd_card)) { + status[0x0F] = 0x01; + } else { + status[0x0F] = 0x00; + } + } else { + if (CHK_MMC_SECTOR_MODE(sd_card)) { + status[0x0E] = 0x01; + } else { + status[0x0E] = 0x00; + } + + if (CHK_MMC_DDR52(sd_card)) { + status[0x0F] = 0x03; + } else if (CHK_MMC_52M(sd_card)) { + status[0x0F] = 0x02; + } else if (CHK_MMC_26M(sd_card)) { + status[0x0F] = 0x01; + } else { + status[0x0F] = 0x00; + } + } + } else if (card == MS_CARD) { + if (CHK_MSPRO(ms_card)) { + if (CHK_MSXC(ms_card)) { + status[0x0E] = 0x01; + } else { + status[0x0E] = 0x00; + } + + if (CHK_HG8BIT(ms_card)) { + status[0x0F] = 0x01; + } else { + status[0x0F] = 0x00; + } + } + } + +#ifdef SUPPORT_SD_LOCK + if (card == SD_CARD) { + status[0x17] = 0x80; + if (sd_card->sd_erase_status) + status[0x17] |= 0x01; + if (sd_card->sd_lock_status & SD_LOCKED) { + status[0x17] |= 0x02; + status[0x07] |= 0x40; + } + if (sd_card->sd_lock_status & SD_PWD_EXIST) + status[0x17] |= 0x04; + } else { + status[0x17] = 0x00; + } + + RTSX_DEBUGP("status[0x17] = 0x%x\n", status[0x17]); +#endif + + status[0x18] = 0x8A; + status[0x1A] = 0x28; +#ifdef SUPPORT_SD_LOCK + status[0x1F] = 0x01; +#endif + + buf_len = min(scsi_bufflen(srb), (unsigned int)sizeof(status)); + rtsx_stor_set_xfer_buf(status, buf_len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); + + return TRANSPORT_GOOD; +} + +static int set_chip_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int phy_debug_mode; + int retval; + u16 reg; + + if (!CHECK_PID(chip, 0x5208)) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + phy_debug_mode = (int)(srb->cmnd[3]); + + if (phy_debug_mode) { + chip->phy_debug_mode = 1; + retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + rtsx_disable_bus_int(chip); + + retval = rtsx_read_phy_register(chip, 0x1C, ®); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + reg |= 0x0001; + retval = rtsx_write_phy_register(chip, 0x1C, reg); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + } else { + chip->phy_debug_mode = 0; + retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0x77); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + rtsx_enable_bus_int(chip); + + retval = rtsx_read_phy_register(chip, 0x1C, ®); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + reg &= 0xFFFE; + retval = rtsx_write_phy_register(chip, 0x1C, reg); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + return TRANSPORT_GOOD; +} + +static int rw_mem_cmd_buf(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval = STATUS_SUCCESS; + unsigned int lun = SCSI_LUN(srb); + u8 cmd_type, mask, value, idx; + u16 addr; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + switch (srb->cmnd[3]) { + case INIT_BATCHCMD: + rtsx_init_cmd(chip); + break; + + case ADD_BATCHCMD: + cmd_type = srb->cmnd[4]; + if (cmd_type > 2) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + addr = (srb->cmnd[5] << 8) | srb->cmnd[6]; + mask = srb->cmnd[7]; + value = srb->cmnd[8]; + rtsx_add_cmd(chip, cmd_type, addr, mask, value); + break; + + case SEND_BATCHCMD: + retval = rtsx_send_cmd(chip, 0, 1000); + break; + + case GET_BATCHRSP: + idx = srb->cmnd[4]; + value = *(rtsx_get_cmd_data(chip) + idx); + if (scsi_bufflen(srb) < 1) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + rtsx_stor_set_xfer_buf(&value, 1, srb); + scsi_set_resid(srb, 0); + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return TRANSPORT_GOOD; +} + +static int suit_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int result; + + switch (srb->cmnd[3]) { + case INIT_BATCHCMD: + case ADD_BATCHCMD: + case SEND_BATCHCMD: + case GET_BATCHRSP: + result = rw_mem_cmd_buf(srb, chip); + break; + default: + result = TRANSPORT_ERROR; + } + + return result; +} + +static int read_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned short addr, len, i; + int retval; + u8 *buf; + u16 val; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; + len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; + + if (len % 2) + len -= len % 2; + + if (len) { + buf = (u8 *)vmalloc(len); + if (!buf) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + for (i = 0; i < len / 2; i++) { + retval = rtsx_read_phy_register(chip, addr + i, &val); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + buf[2*i] = (u8)(val >> 8); + buf[2*i+1] = (u8)val; + } + + len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); + rtsx_stor_set_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + vfree(buf); + } + + return TRANSPORT_GOOD; +} + +static int write_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned short addr, len, i; + int retval; + u8 *buf; + u16 val; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; + len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; + + if (len % 2) + len -= len % 2; + + if (len) { + len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); + + buf = (u8 *)vmalloc(len); + if (buf == NULL) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + rtsx_stor_get_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + for (i = 0; i < len / 2; i++) { + val = ((u16)buf[2*i] << 8) | buf[2*i+1]; + retval = rtsx_write_phy_register(chip, addr + i, val); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + vfree(buf); + } + + return TRANSPORT_GOOD; +} + +static int erase_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned short addr; + int retval; + u8 mode; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + mode = srb->cmnd[3]; + addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; + + if (mode == 0) { + retval = spi_erase_eeprom_chip(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } else if (mode == 1) { + retval = spi_erase_eeprom_byte(chip, addr); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } else { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return TRANSPORT_GOOD; +} + +static int read_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned short addr, len, i; + int retval; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; + len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; + + buf = (u8 *)vmalloc(len); + if (!buf) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + for (i = 0; i < len; i++) { + retval = spi_read_eeprom(chip, addr + i, buf + i); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); + rtsx_stor_set_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + vfree(buf); + + return TRANSPORT_GOOD; +} + +static int write_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned short addr, len, i; + int retval; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; + len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; + + len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); + buf = (u8 *)vmalloc(len); + if (buf == NULL) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + rtsx_stor_get_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + for (i = 0; i < len; i++) { + retval = spi_write_eeprom(chip, addr + i, buf[i]); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + vfree(buf); + + return TRANSPORT_GOOD; +} + +static int read_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + u8 addr, len, i; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = srb->cmnd[4]; + len = srb->cmnd[5]; + + buf = (u8 *)vmalloc(len); + if (!buf) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + for (i = 0; i < len; i++) { + retval = rtsx_read_efuse(chip, addr + i, buf + i); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + len = (u8)min(scsi_bufflen(srb), (unsigned int)len); + rtsx_stor_set_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + vfree(buf); + + return TRANSPORT_GOOD; +} + +static int write_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval, result = TRANSPORT_GOOD; + u16 val; + u8 addr, len, i; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + addr = srb->cmnd[4]; + len = srb->cmnd[5]; + + len = (u8)min(scsi_bufflen(srb), (unsigned int)len); + buf = (u8 *)vmalloc(len); + if (buf == NULL) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + rtsx_stor_get_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + retval = rtsx_force_power_on(chip, SSC_PDCTL); + if (retval != STATUS_SUCCESS) { + vfree(buf); + TRACE_RET(chip, TRANSPORT_ERROR); + } + + if (chip->asic_code) { + retval = rtsx_read_phy_register(chip, 0x08, &val); + if (retval != STATUS_SUCCESS) { + vfree(buf); + TRACE_RET(chip, TRANSPORT_ERROR); + } + + retval = rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_OFF); + if (retval != STATUS_SUCCESS) { + vfree(buf); + TRACE_RET(chip, TRANSPORT_ERROR); + } + + wait_timeout(600); + + retval = rtsx_write_phy_register(chip, 0x08, 0x4C00 | chip->phy_voltage); + if (retval != STATUS_SUCCESS) { + vfree(buf); + TRACE_RET(chip, TRANSPORT_ERROR); + } + + retval = rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON); + if (retval != STATUS_SUCCESS) { + vfree(buf); + TRACE_RET(chip, TRANSPORT_ERROR); + } + + wait_timeout(600); + } + + retval = card_power_on(chip, SPI_CARD); + if (retval != STATUS_SUCCESS) { + vfree(buf); + TRACE_RET(chip, TRANSPORT_ERROR); + } + + wait_timeout(50); + + for (i = 0; i < len; i++) { + retval = rtsx_write_efuse(chip, addr + i, buf[i]); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + result = TRANSPORT_FAILED; + TRACE_GOTO(chip, Exit); + } + } + +Exit: + vfree(buf); + + retval = card_power_off(chip, SPI_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + if (chip->asic_code) { + retval = rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_OFF); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + wait_timeout(600); + + retval = rtsx_write_phy_register(chip, 0x08, val); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + retval = rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + } + + return result; +} + +static int read_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + u8 func, func_max; + u16 addr, len; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + func = srb->cmnd[3]; + addr = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; + len = ((u16)(srb->cmnd[6]) << 8) | srb->cmnd[7]; + + RTSX_DEBUGP("%s: func = %d, addr = 0x%x, len = %d\n", __func__, func, addr, len); + + if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { + func_max = 1; + } else { + func_max = 0; + } + + if (func > func_max) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + buf = (u8 *)vmalloc(len); + if (!buf) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + retval = rtsx_read_cfg_seq(chip, func, addr, buf, len); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + vfree(buf); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + len = (u16)min(scsi_bufflen(srb), (unsigned int)len); + rtsx_stor_set_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + vfree(buf); + + return TRANSPORT_GOOD; +} + +static int write_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + u8 func, func_max; + u16 addr, len; + u8 *buf; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + func = srb->cmnd[3]; + addr = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; + len = ((u16)(srb->cmnd[6]) << 8) | srb->cmnd[7]; + + RTSX_DEBUGP("%s: func = %d, addr = 0x%x\n", __func__, func, addr); + + if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { + func_max = 1; + } else { + func_max = 0; + } + + if (func > func_max) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); + buf = (u8 *)vmalloc(len); + if (!buf) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + rtsx_stor_get_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + retval = rtsx_write_cfg_seq(chip, func, addr, buf, len); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + vfree(buf); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + vfree(buf); + + return TRANSPORT_GOOD; +} + +static int app_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int result; + + switch (srb->cmnd[2]) { + case PP_READ10: + case PP_WRITE10: + result = read_write(srb, chip); + break; + + case READ_HOST_REG: + result = read_host_reg(srb, chip); + break; + + case WRITE_HOST_REG: + result = write_host_reg(srb, chip); + break; + + case GET_VAR: + result = get_variable(srb, chip); + break; + + case SET_VAR: + result = set_variable(srb, chip); + break; + + case DMA_READ: + case DMA_WRITE: + result = dma_access_ring_buffer(srb, chip); + break; + + case READ_PHY: + result = read_phy_register(srb, chip); + break; + + case WRITE_PHY: + result = write_phy_register(srb, chip); + break; + + case ERASE_EEPROM2: + result = erase_eeprom2(srb, chip); + break; + + case READ_EEPROM2: + result = read_eeprom2(srb, chip); + break; + + case WRITE_EEPROM2: + result = write_eeprom2(srb, chip); + break; + + case READ_EFUSE: + result = read_efuse(srb, chip); + break; + + case WRITE_EFUSE: + result = write_efuse(srb, chip); + break; + + case READ_CFG: + result = read_cfg_byte(srb, chip); + break; + + case WRITE_CFG: + result = write_cfg_byte(srb, chip); + break; + + case SET_CHIP_MODE: + result = set_chip_mode(srb, chip); + break; + + case SUIT_CMD: + result = suit_cmd(srb, chip); + break; + + case GET_DEV_STATUS: + result = get_dev_status(srb, chip); + break; + + default: + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return result; +} + + +static int read_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + u8 rtsx_status[16]; + int buf_len; + unsigned int lun = SCSI_LUN(srb); + + rtsx_status[0] = (u8)(chip->vendor_id >> 8); + rtsx_status[1] = (u8)(chip->vendor_id); + + rtsx_status[2] = (u8)(chip->product_id >> 8); + rtsx_status[3] = (u8)(chip->product_id); + + rtsx_status[4] = (u8)lun; + + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + if (chip->lun2card[lun] == SD_CARD) { + rtsx_status[5] = 2; + } else { + rtsx_status[5] = 3; + } + } else { + if (chip->card_exist) { + if (chip->card_exist & XD_CARD) { + rtsx_status[5] = 4; + } else if (chip->card_exist & SD_CARD) { + rtsx_status[5] = 2; + } else if (chip->card_exist & MS_CARD) { + rtsx_status[5] = 3; + } else { + rtsx_status[5] = 7; + } + } else { + rtsx_status[5] = 7; + } + } + + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + rtsx_status[6] = 2; + } else { + rtsx_status[6] = 1; + } + + rtsx_status[7] = (u8)(chip->product_id); + rtsx_status[8] = chip->ic_version; + + if (check_card_exist(chip, lun)) { + rtsx_status[9] = 1; + } else { + rtsx_status[9] = 0; + } + + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + rtsx_status[10] = 0; + } else { + rtsx_status[10] = 1; + } + + if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { + if (chip->lun2card[lun] == SD_CARD) { + rtsx_status[11] = SD_CARD; + } else { + rtsx_status[11] = MS_CARD; + } + } else { + rtsx_status[11] = XD_CARD | SD_CARD | MS_CARD; + } + + if (check_card_ready(chip, lun)) { + rtsx_status[12] = 1; + } else { + rtsx_status[12] = 0; + } + + if (get_lun_card(chip, lun) == XD_CARD) { + rtsx_status[13] = 0x40; + } else if (get_lun_card(chip, lun) == SD_CARD) { + struct sd_info *sd_card = &(chip->sd_card); + + rtsx_status[13] = 0x20; + if (CHK_SD(sd_card)) { + if (CHK_SD_HCXC(sd_card)) + rtsx_status[13] |= 0x04; + if (CHK_SD_HS(sd_card)) + rtsx_status[13] |= 0x02; + } else { + rtsx_status[13] |= 0x08; + if (CHK_MMC_52M(sd_card)) + rtsx_status[13] |= 0x02; + if (CHK_MMC_SECTOR_MODE(sd_card)) + rtsx_status[13] |= 0x04; + } + } else if (get_lun_card(chip, lun) == MS_CARD) { + struct ms_info *ms_card = &(chip->ms_card); + + if (CHK_MSPRO(ms_card)) { + rtsx_status[13] = 0x38; + if (CHK_HG8BIT(ms_card)) + rtsx_status[13] |= 0x04; +#ifdef SUPPORT_MSXC + if (CHK_MSXC(ms_card)) + rtsx_status[13] |= 0x01; +#endif + } else { + rtsx_status[13] = 0x30; + } + } else { + if (CHECK_LUN_MODE(chip, DEFAULT_SINGLE)) { +#ifdef SUPPORT_SDIO + if (chip->sd_io && chip->sd_int) { + rtsx_status[13] = 0x60; + } else { + rtsx_status[13] = 0x70; + } +#else + rtsx_status[13] = 0x70; +#endif + } else { + if (chip->lun2card[lun] == SD_CARD) { + rtsx_status[13] = 0x20; + } else { + rtsx_status[13] = 0x30; + } + } + } + + rtsx_status[14] = 0x78; + if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { + rtsx_status[15] = 0x83; + } else { + rtsx_status[15] = 0x82; + } + + buf_len = min(scsi_bufflen(srb), (unsigned int)sizeof(rtsx_status)); + rtsx_stor_set_xfer_buf(rtsx_status, buf_len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); + + return TRANSPORT_GOOD; +} + +static int get_card_bus_width(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + u8 card, bus_width; + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + card = get_lun_card(chip, lun); + if ((card == SD_CARD) || (card == MS_CARD)) { + bus_width = chip->card_bus_width[lun]; + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + scsi_set_resid(srb, 0); + rtsx_stor_set_xfer_buf(&bus_width, scsi_bufflen(srb), srb); + + return TRANSPORT_GOOD; +} + +static int spi_vendor_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int result; + unsigned int lun = SCSI_LUN(srb); + u8 gpio_dir; + + if (CHECK_PID(chip, 0x5208) && CHECK_PID(chip, 0x5288)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + rtsx_force_power_on(chip, SSC_PDCTL); + + rtsx_read_register(chip, CARD_GPIO_DIR, &gpio_dir); + rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir & 0x06); + + switch (srb->cmnd[2]) { + case SCSI_SPI_GETSTATUS: + result = spi_get_status(srb, chip); + break; + + case SCSI_SPI_SETPARAMETER: + result = spi_set_parameter(srb, chip); + break; + + case SCSI_SPI_READFALSHID: + result = spi_read_flash_id(srb, chip); + break; + + case SCSI_SPI_READFLASH: + result = spi_read_flash(srb, chip); + break; + + case SCSI_SPI_WRITEFLASH: + result = spi_write_flash(srb, chip); + break; + + case SCSI_SPI_WRITEFLASHSTATUS: + result = spi_write_flash_status(srb, chip); + break; + + case SCSI_SPI_ERASEFLASH: + result = spi_erase_flash(srb, chip); + break; + + default: + rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir); + + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir); + + if (result != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return TRANSPORT_GOOD; +} + +static int vendor_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int result; + + switch (srb->cmnd[1]) { + case READ_STATUS: + result = read_status(srb, chip); + break; + + case READ_MEM: + result = read_mem(srb, chip); + break; + + case WRITE_MEM: + result = write_mem(srb, chip); + break; + + case READ_EEPROM: + result = read_eeprom(srb, chip); + break; + + case WRITE_EEPROM: + result = write_eeprom(srb, chip); + break; + + case TOGGLE_GPIO: + result = toggle_gpio_cmd(srb, chip); + break; + + case GET_SD_CSD: + result = get_sd_csd(srb, chip); + break; + + case GET_BUS_WIDTH: + result = get_card_bus_width(srb, chip); + break; + +#ifdef _MSG_TRACE + case TRACE_MSG: + result = trace_msg_cmd(srb, chip); + break; +#endif + + case SCSI_APP_CMD: + result = app_cmd(srb, chip); + break; + + case SPI_VENDOR_COMMAND: + result = spi_vendor_cmd(srb, chip); + break; + + default: + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return result; +} + +#if !defined(LED_AUTO_BLINK) && !defined(REGULAR_BLINK) +void led_shine(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + u16 sec_cnt; + + if ((srb->cmnd[0] == READ_10) || (srb->cmnd[0] == WRITE_10)) { + sec_cnt = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; + } else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6)) { + sec_cnt = srb->cmnd[4]; + } else { + return; + } + + if (chip->rw_cap[lun] >= GPIO_TOGGLE_THRESHOLD) { + toggle_gpio(chip, LED_GPIO); + chip->rw_cap[lun] = 0; + } else { + chip->rw_cap[lun] += sec_cnt; + } +} +#endif + +static int ms_format_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + unsigned int lun = SCSI_LUN(srb); + int retval, quick_format; + + if (get_lun_card(chip, lun) != MS_CARD) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if ((srb->cmnd[3] != 0x4D) || (srb->cmnd[4] != 0x47) || + (srb->cmnd[5] != 0x66) || (srb->cmnd[6] != 0x6D) || + (srb->cmnd[7] != 0x74)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + + if (!check_card_ready(chip, lun) || + (get_card_size(chip, lun) == 0)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + if (srb->cmnd[8] & 0x01) { + quick_format = 0; + } else { + quick_format = 1; + } + + if (!(chip->card_ready & MS_CARD)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (chip->card_wp & MS_CARD) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (!CHK_MSPRO(ms_card)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + retval = mspro_format(srb, chip, MS_SHORT_DATA_LEN, quick_format); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; +} + +#ifdef SUPPORT_PCGL_1P18 +int get_ms_information(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + unsigned int lun = SCSI_LUN(srb); + u8 dev_info_id, data_len; + u8 *buf; + unsigned int buf_len; + int i; + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + if ((get_lun_card(chip, lun) != MS_CARD)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if ((srb->cmnd[2] != 0xB0) || (srb->cmnd[4] != 0x4D) || + (srb->cmnd[5] != 0x53) || (srb->cmnd[6] != 0x49) || + (srb->cmnd[7] != 0x44)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + dev_info_id = srb->cmnd[3]; + if ((CHK_MSXC(ms_card) && (dev_info_id == 0x10)) || + (!CHK_MSXC(ms_card) && (dev_info_id == 0x13)) || + !CHK_MSPRO(ms_card)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (dev_info_id == 0x15) { + buf_len = data_len = 0x3A; + } else { + buf_len = data_len = 0x6A; + } + + buf = (u8 *)kmalloc(buf_len, GFP_KERNEL); + if (!buf) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + i = 0; + /* GET Memory Stick Media Information Response Header */ + buf[i++] = 0x00; /* Data length MSB */ + buf[i++] = data_len; /* Data length LSB */ + /* Device Information Type Code */ + if (CHK_MSXC(ms_card)) { + buf[i++] = 0x03; + } else { + buf[i++] = 0x02; + } + /* SGM bit */ + buf[i++] = 0x01; + /* Reserved */ + buf[i++] = 0x00; + buf[i++] = 0x00; + buf[i++] = 0x00; + /* Number of Device Information */ + buf[i++] = 0x01; + + /* Device Information Body */ + + /* Device Information ID Number */ + buf[i++] = dev_info_id; + /* Device Information Length */ + if (dev_info_id == 0x15) { + data_len = 0x31; + } else { + data_len = 0x61; + } + buf[i++] = 0x00; /* Data length MSB */ + buf[i++] = data_len; /* Data length LSB */ + /* Valid Bit */ + buf[i++] = 0x80; + if ((dev_info_id == 0x10) || (dev_info_id == 0x13)) { + /* System Information */ + memcpy(buf+i, ms_card->raw_sys_info, 96); + } else { + /* Model Name */ + memcpy(buf+i, ms_card->raw_model_name, 48); + } + + rtsx_stor_set_xfer_buf(buf, buf_len, srb); + + if (dev_info_id == 0x15) { + scsi_set_resid(srb, scsi_bufflen(srb)-0x3C); + } else { + scsi_set_resid(srb, scsi_bufflen(srb)-0x6C); + } + + kfree(buf); + return STATUS_SUCCESS; +} +#endif + +static int ms_sp_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval = TRANSPORT_ERROR; + + if (srb->cmnd[2] == MS_FORMAT) { + retval = ms_format_cmnd(srb, chip); + } +#ifdef SUPPORT_PCGL_1P18 + else if (srb->cmnd[2] == GET_MS_INFORMATION) { + retval = get_ms_information(srb, chip); + } +#endif + + return retval; +} + +#ifdef SUPPORT_CPRM +static int sd_extention_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + int result; + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + sd_cleanup_work(chip); + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + if ((get_lun_card(chip, lun) != SD_CARD)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + switch (srb->cmnd[0]) { + case SD_PASS_THRU_MODE: + result = sd_pass_thru_mode(srb, chip); + break; + + case SD_EXECUTE_NO_DATA: + result = sd_execute_no_data(srb, chip); + break; + + case SD_EXECUTE_READ: + result = sd_execute_read_data(srb, chip); + break; + + case SD_EXECUTE_WRITE: + result = sd_execute_write_data(srb, chip); + break; + + case SD_GET_RSP: + result = sd_get_cmd_rsp(srb, chip); + break; + + case SD_HW_RST: + result = sd_hw_rst(srb, chip); + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return result; +} +#endif + +#ifdef SUPPORT_MAGIC_GATE +int mg_report_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + unsigned int lun = SCSI_LUN(srb); + int retval; + u8 key_format; + + RTSX_DEBUGP("--%s--\n", __func__); + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + ms_cleanup_work(chip); + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + if ((get_lun_card(chip, lun) != MS_CARD)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (srb->cmnd[7] != KC_MG_R_PRO) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (!CHK_MSPRO(ms_card)) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + key_format = srb->cmnd[10] & 0x3F; + RTSX_DEBUGP("key_format = 0x%x\n", key_format); + + switch (key_format) { + case KF_GET_LOC_EKB: + if ((scsi_bufflen(srb) == 0x41C) && + (srb->cmnd[8] == 0x04) && + (srb->cmnd[9] == 0x1C)) { + retval = mg_get_local_EKB(srb, chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + case KF_RSP_CHG: + if ((scsi_bufflen(srb) == 0x24) && + (srb->cmnd[8] == 0x00) && + (srb->cmnd[9] == 0x24)) { + retval = mg_get_rsp_chg(srb, chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + case KF_GET_ICV: + ms_card->mg_entry_num = srb->cmnd[5]; + if ((scsi_bufflen(srb) == 0x404) && + (srb->cmnd[8] == 0x04) && + (srb->cmnd[9] == 0x04) && + (srb->cmnd[2] == 0x00) && + (srb->cmnd[3] == 0x00) && + (srb->cmnd[4] == 0x00) && + (srb->cmnd[5] < 32)) { + retval = mg_get_ICV(srb, chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; +} + +int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + unsigned int lun = SCSI_LUN(srb); + int retval; + u8 key_format; + + RTSX_DEBUGP("--%s--\n", __func__); + + rtsx_disable_aspm(chip); + + if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { + rtsx_exit_ss(chip); + wait_timeout(100); + } + rtsx_set_stat(chip, RTSX_STAT_RUN); + + ms_cleanup_work(chip); + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + if (check_card_wp(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + if ((get_lun_card(chip, lun) != MS_CARD)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (srb->cmnd[7] != KC_MG_R_PRO) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (!CHK_MSPRO(ms_card)) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + key_format = srb->cmnd[10] & 0x3F; + RTSX_DEBUGP("key_format = 0x%x\n", key_format); + + switch (key_format) { + case KF_SET_LEAF_ID: + if ((scsi_bufflen(srb) == 0x0C) && + (srb->cmnd[8] == 0x00) && + (srb->cmnd[9] == 0x0C)) { + retval = mg_set_leaf_id(srb, chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + case KF_CHG_HOST: + if ((scsi_bufflen(srb) == 0x0C) && + (srb->cmnd[8] == 0x00) && + (srb->cmnd[9] == 0x0C)) { + retval = mg_chg(srb, chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + case KF_RSP_HOST: + if ((scsi_bufflen(srb) == 0x0C) && + (srb->cmnd[8] == 0x00) && + (srb->cmnd[9] == 0x0C)) { + retval = mg_rsp(srb, chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + case KF_SET_ICV: + ms_card->mg_entry_num = srb->cmnd[5]; + if ((scsi_bufflen(srb) == 0x404) && + (srb->cmnd[8] == 0x04) && + (srb->cmnd[9] == 0x04) && + (srb->cmnd[2] == 0x00) && + (srb->cmnd[3] == 0x00) && + (srb->cmnd[4] == 0x00) && + (srb->cmnd[5] < 32)) { + retval = mg_set_ICV(srb, chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; +} +#endif + +int rtsx_scsi_handler(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ +#ifdef SUPPORT_SD_LOCK + struct sd_info *sd_card = &(chip->sd_card); +#endif + struct ms_info *ms_card = &(chip->ms_card); + unsigned int lun = SCSI_LUN(srb); + int result; + +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_erase_status) { + /* Block all SCSI command except for + * REQUEST_SENSE and rs_ppstatus + */ + if (!((srb->cmnd[0] == VENDOR_CMND) && + (srb->cmnd[1] == SCSI_APP_CMD) && + (srb->cmnd[2] == GET_DEV_STATUS)) && + (srb->cmnd[0] != REQUEST_SENSE)) { + /* Logical Unit Not Ready Format in Progress */ + set_sense_data(chip, lun, CUR_ERR, + 0x02, 0, 0x04, 0x04, 0, 0); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } +#endif + + if ((get_lun_card(chip, lun) == MS_CARD) && + (ms_card->format_status == FORMAT_IN_PROGRESS)) { + if ((srb->cmnd[0] != REQUEST_SENSE) && (srb->cmnd[0] != INQUIRY)) { + /* Logical Unit Not Ready Format in Progress */ + set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, + 0, (u16)(ms_card->progress)); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + switch (srb->cmnd[0]) { + case READ_10: + case WRITE_10: + case READ_6: + case WRITE_6: + result = read_write(srb, chip); +#if !defined(LED_AUTO_BLINK) && !defined(REGULAR_BLINK) + led_shine(srb, chip); +#endif + break; + + case TEST_UNIT_READY: + result = test_unit_ready(srb, chip); + break; + + case INQUIRY: + result = inquiry(srb, chip); + break; + + case READ_CAPACITY: + result = read_capacity(srb, chip); + break; + + case START_STOP: + result = start_stop_unit(srb, chip); + break; + + case ALLOW_MEDIUM_REMOVAL: + result = allow_medium_removal(srb, chip); + break; + + case REQUEST_SENSE: + result = request_sense(srb, chip); + break; + + case MODE_SENSE: + case MODE_SENSE_10: + result = mode_sense(srb, chip); + break; + + case 0x23: + result = read_format_capacity(srb, chip); + break; + + case VENDOR_CMND: + result = vendor_cmnd(srb, chip); + break; + + case MS_SP_CMND: + result = ms_sp_cmnd(srb, chip); + break; + +#ifdef SUPPORT_CPRM + case SD_PASS_THRU_MODE: + case SD_EXECUTE_NO_DATA: + case SD_EXECUTE_READ: + case SD_EXECUTE_WRITE: + case SD_GET_RSP: + case SD_HW_RST: + result = sd_extention_cmnd(srb, chip); + break; +#endif + +#ifdef SUPPORT_MAGIC_GATE + case CMD_MSPRO_MG_RKEY: + result = mg_report_key(srb, chip); + break; + + case CMD_MSPRO_MG_SKEY: + result = mg_send_key(srb, chip); + break; +#endif + + case FORMAT_UNIT: + case MODE_SELECT: + case VERIFY: + result = TRANSPORT_GOOD; + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + result = TRANSPORT_FAILED; + } + + return result; +} diff --git a/drivers/staging/rts_pstor/rtsx_scsi.h b/drivers/staging/rts_pstor/rtsx_scsi.h new file mode 100644 index 000000000000..fac122c1eabd --- /dev/null +++ b/drivers/staging/rts_pstor/rtsx_scsi.h @@ -0,0 +1,142 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __REALTEK_RTSX_SCSI_H +#define __REALTEK_RTSX_SCSI_H + +#include "rtsx.h" +#include "rtsx_chip.h" + +#define MS_SP_CMND 0xFA +#define MS_FORMAT 0xA0 +#define GET_MS_INFORMATION 0xB0 + +#define VENDOR_CMND 0xF0 + +#define READ_STATUS 0x09 + +#define READ_EEPROM 0x04 +#define WRITE_EEPROM 0x05 +#define READ_MEM 0x0D +#define WRITE_MEM 0x0E +#define GET_BUS_WIDTH 0x13 +#define GET_SD_CSD 0x14 +#define TOGGLE_GPIO 0x15 +#define TRACE_MSG 0x18 + +#define SCSI_APP_CMD 0x10 + +#define PP_READ10 0x1A +#define PP_WRITE10 0x0A +#define READ_HOST_REG 0x1D +#define WRITE_HOST_REG 0x0D +#define SET_VAR 0x05 +#define GET_VAR 0x15 +#define DMA_READ 0x16 +#define DMA_WRITE 0x06 +#define GET_DEV_STATUS 0x10 +#define SET_CHIP_MODE 0x27 +#define SUIT_CMD 0xE0 +#define WRITE_PHY 0x07 +#define READ_PHY 0x17 +#define WRITE_EEPROM2 0x03 +#define READ_EEPROM2 0x13 +#define ERASE_EEPROM2 0x23 +#define WRITE_EFUSE 0x04 +#define READ_EFUSE 0x14 +#define WRITE_CFG 0x0E +#define READ_CFG 0x1E + +#define SPI_VENDOR_COMMAND 0x1C + +#define SCSI_SPI_GETSTATUS 0x00 +#define SCSI_SPI_SETPARAMETER 0x01 +#define SCSI_SPI_READFALSHID 0x02 +#define SCSI_SPI_READFLASH 0x03 +#define SCSI_SPI_WRITEFLASH 0x04 +#define SCSI_SPI_WRITEFLASHSTATUS 0x05 +#define SCSI_SPI_ERASEFLASH 0x06 + +#define INIT_BATCHCMD 0x41 +#define ADD_BATCHCMD 0x42 +#define SEND_BATCHCMD 0x43 +#define GET_BATCHRSP 0x44 + +#define CHIP_NORMALMODE 0x00 +#define CHIP_DEBUGMODE 0x01 + +/* SD Pass Through Command Extention */ +#define SD_PASS_THRU_MODE 0xD0 +#define SD_EXECUTE_NO_DATA 0xD1 +#define SD_EXECUTE_READ 0xD2 +#define SD_EXECUTE_WRITE 0xD3 +#define SD_GET_RSP 0xD4 +#define SD_HW_RST 0xD6 + +#ifdef SUPPORT_MAGIC_GATE +#define CMD_MSPRO_MG_RKEY 0xA4 /* Report Key Command */ +#define CMD_MSPRO_MG_SKEY 0xA3 /* Send Key Command */ + +/* CBWCB field: key class */ +#define KC_MG_R_PRO 0xBE /* MG-R PRO*/ + +/* CBWCB field: key format */ +#define KF_SET_LEAF_ID 0x31 /* Set Leaf ID */ +#define KF_GET_LOC_EKB 0x32 /* Get Local EKB */ +#define KF_CHG_HOST 0x33 /* Challenge (host) */ +#define KF_RSP_CHG 0x34 /* Response and Challenge (device) */ +#define KF_RSP_HOST 0x35 /* Response (host) */ +#define KF_GET_ICV 0x36 /* Get ICV */ +#define KF_SET_ICV 0x37 /* SSet ICV */ +#endif + +/* Sense type */ +#define SENSE_TYPE_NO_SENSE 0 +#define SENSE_TYPE_MEDIA_CHANGE 1 +#define SENSE_TYPE_MEDIA_NOT_PRESENT 2 +#define SENSE_TYPE_MEDIA_LBA_OVER_RANGE 3 +#define SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT 4 +#define SENSE_TYPE_MEDIA_WRITE_PROTECT 5 +#define SENSE_TYPE_MEDIA_INVALID_CMD_FIELD 6 +#define SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR 7 +#define SENSE_TYPE_MEDIA_WRITE_ERR 8 +#define SENSE_TYPE_FORMAT_IN_PROGRESS 9 +#define SENSE_TYPE_FORMAT_CMD_FAILED 10 +#ifdef SUPPORT_MAGIC_GATE +#define SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB 0x0b +#define SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN 0x0c +#define SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM 0x0d +#define SENSE_TYPE_MG_WRITE_ERR 0x0e +#endif +#ifdef SUPPORT_SD_LOCK +#define SENSE_TYPE_MEDIA_READ_FORBIDDEN 0x10 /* FOR Locked SD card*/ +#endif + +void scsi_show_command(struct scsi_cmnd *srb); +void set_sense_type(struct rtsx_chip *chip, unsigned int lun, int sense_type); +void set_sense_data(struct rtsx_chip *chip, unsigned int lun, u8 err_code, u8 sense_key, + u32 info, u8 asc, u8 ascq, u8 sns_key_info0, u16 sns_key_info1); +int rtsx_scsi_handler(struct scsi_cmnd *srb, struct rtsx_chip *chip); + +#endif /* __REALTEK_RTSX_SCSI_H */ + diff --git a/drivers/staging/rts_pstor/rtsx_sys.h b/drivers/staging/rts_pstor/rtsx_sys.h new file mode 100644 index 000000000000..8e55a3a8b00a --- /dev/null +++ b/drivers/staging/rts_pstor/rtsx_sys.h @@ -0,0 +1,50 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __RTSX_SYS_H +#define __RTSX_SYS_H + +#include "rtsx.h" +#include "rtsx_chip.h" +#include "rtsx_card.h" + +typedef dma_addr_t ULONG_PTR; + +static inline void rtsx_exclusive_enter_ss(struct rtsx_chip *chip) +{ + struct rtsx_dev *dev = chip->rtsx; + + spin_lock(&(dev->reg_lock)); + rtsx_enter_ss(chip); + spin_unlock(&(dev->reg_lock)); +} + +static inline void rtsx_reset_detected_cards(struct rtsx_chip *chip, int flag) +{ + rtsx_reset_cards(chip); +} + +#define RTSX_MSG_IN_INT(x) + +#endif /* __RTSX_SYS_H */ + diff --git a/drivers/staging/rts_pstor/rtsx_transport.c b/drivers/staging/rts_pstor/rtsx_transport.c new file mode 100644 index 000000000000..e581f15147f2 --- /dev/null +++ b/drivers/staging/rts_pstor/rtsx_transport.c @@ -0,0 +1,914 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include +#include +#include + +#include "rtsx.h" +#include "rtsx_scsi.h" +#include "rtsx_transport.h" +#include "rtsx_chip.h" +#include "rtsx_card.h" +#include "debug.h" + +/*********************************************************************** + * Scatter-gather transfer buffer access routines + ***********************************************************************/ + +/* Copy a buffer of length buflen to/from the srb's transfer buffer. + * (Note: for scatter-gather transfers (srb->use_sg > 0), srb->request_buffer + * points to a list of s-g entries and we ignore srb->request_bufflen. + * For non-scatter-gather transfers, srb->request_buffer points to the + * transfer buffer itself and srb->request_bufflen is the buffer's length.) + * Update the *index and *offset variables so that the next copy will + * pick up from where this one left off. */ + +unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer, + unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index, + unsigned int *offset, enum xfer_buf_dir dir) +{ + unsigned int cnt; + + /* If not using scatter-gather, just transfer the data directly. + * Make certain it will fit in the available buffer space. */ + if (scsi_sg_count(srb) == 0) { + if (*offset >= scsi_bufflen(srb)) + return 0; + cnt = min(buflen, scsi_bufflen(srb) - *offset); + if (dir == TO_XFER_BUF) + memcpy((unsigned char *) scsi_sglist(srb) + *offset, + buffer, cnt); + else + memcpy(buffer, (unsigned char *) scsi_sglist(srb) + + *offset, cnt); + *offset += cnt; + + /* Using scatter-gather. We have to go through the list one entry + * at a time. Each s-g entry contains some number of pages, and + * each page has to be kmap()'ed separately. If the page is already + * in kernel-addressable memory then kmap() will return its address. + * If the page is not directly accessible -- such as a user buffer + * located in high memory -- then kmap() will map it to a temporary + * position in the kernel's virtual address space. */ + } else { + struct scatterlist *sg = + (struct scatterlist *) scsi_sglist(srb) + + *index; + + /* This loop handles a single s-g list entry, which may + * include multiple pages. Find the initial page structure + * and the starting offset within the page, and update + * the *offset and *index values for the next loop. */ + cnt = 0; + while (cnt < buflen && *index < scsi_sg_count(srb)) { + struct page *page = sg_page(sg) + + ((sg->offset + *offset) >> PAGE_SHIFT); + unsigned int poff = + (sg->offset + *offset) & (PAGE_SIZE-1); + unsigned int sglen = sg->length - *offset; + + if (sglen > buflen - cnt) { + + /* Transfer ends within this s-g entry */ + sglen = buflen - cnt; + *offset += sglen; + } else { + + /* Transfer continues to next s-g entry */ + *offset = 0; + ++*index; + ++sg; + } + + /* Transfer the data for all the pages in this + * s-g entry. For each page: call kmap(), do the + * transfer, and call kunmap() immediately after. */ + while (sglen > 0) { + unsigned int plen = min(sglen, (unsigned int) + PAGE_SIZE - poff); + unsigned char *ptr = kmap(page); + + if (dir == TO_XFER_BUF) + memcpy(ptr + poff, buffer + cnt, plen); + else + memcpy(buffer + cnt, ptr + poff, plen); + kunmap(page); + + /* Start at the beginning of the next page */ + poff = 0; + ++page; + cnt += plen; + sglen -= plen; + } + } + } + + /* Return the amount actually transferred */ + return cnt; +} + +/* Store the contents of buffer into srb's transfer buffer and set the +* SCSI residue. */ +void rtsx_stor_set_xfer_buf(unsigned char *buffer, + unsigned int buflen, struct scsi_cmnd *srb) +{ + unsigned int index = 0, offset = 0; + + rtsx_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset, + TO_XFER_BUF); + if (buflen < scsi_bufflen(srb)) + scsi_set_resid(srb, scsi_bufflen(srb) - buflen); +} + +void rtsx_stor_get_xfer_buf(unsigned char *buffer, + unsigned int buflen, struct scsi_cmnd *srb) +{ + unsigned int index = 0, offset = 0; + + rtsx_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset, + FROM_XFER_BUF); + if (buflen < scsi_bufflen(srb)) + scsi_set_resid(srb, scsi_bufflen(srb) - buflen); +} + + +/*********************************************************************** + * Transport routines + ***********************************************************************/ + +/* Invoke the transport and basic error-handling/recovery methods + * + * This is used to send the message to the device and receive the response. + */ +void rtsx_invoke_transport(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int result; + + result = rtsx_scsi_handler(srb, chip); + + /* if the command gets aborted by the higher layers, we need to + * short-circuit all other processing + */ + if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) { + RTSX_DEBUGP("-- command was aborted\n"); + srb->result = DID_ABORT << 16; + goto Handle_Errors; + } + + /* if there is a transport error, reset and don't auto-sense */ + if (result == TRANSPORT_ERROR) { + RTSX_DEBUGP("-- transport indicates error, resetting\n"); + srb->result = DID_ERROR << 16; + goto Handle_Errors; + } + + srb->result = SAM_STAT_GOOD; + + /* + * If we have a failure, we're going to do a REQUEST_SENSE + * automatically. Note that we differentiate between a command + * "failure" and an "error" in the transport mechanism. + */ + if (result == TRANSPORT_FAILED) { + /* set the result so the higher layers expect this data */ + srb->result = SAM_STAT_CHECK_CONDITION; + memcpy(srb->sense_buffer, + (unsigned char *)&(chip->sense_buffer[SCSI_LUN(srb)]), + sizeof(struct sense_data_t)); + } + + return; + + /* Error and abort processing: try to resynchronize with the device + * by issuing a port reset. If that fails, try a class-specific + * device reset. */ +Handle_Errors: + return; +} + +void rtsx_add_cmd(struct rtsx_chip *chip, + u8 cmd_type, u16 reg_addr, u8 mask, u8 data) +{ + u32 *cb = (u32 *)(chip->host_cmds_ptr); + u32 val = 0; + + val |= (u32)(cmd_type & 0x03) << 30; + val |= (u32)(reg_addr & 0x3FFF) << 16; + val |= (u32)mask << 8; + val |= (u32)data; + + spin_lock_irq(&chip->rtsx->reg_lock); + if (chip->ci < (HOST_CMDS_BUF_LEN / 4)) { + cb[(chip->ci)++] = cpu_to_le32(val); + } + spin_unlock_irq(&chip->rtsx->reg_lock); +} + +void rtsx_send_cmd_no_wait(struct rtsx_chip *chip) +{ + u32 val = 1 << 31; + + rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr); + + val |= (u32)(chip->ci * 4) & 0x00FFFFFF; + /* Hardware Auto Response */ + val |= 0x40000000; + rtsx_writel(chip, RTSX_HCBCTLR, val); +} + +int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout) +{ + struct rtsx_dev *rtsx = chip->rtsx; + struct completion trans_done; + u32 val = 1 << 31; + long timeleft; + int err = 0; + + if (card == SD_CARD) { + rtsx->check_card_cd = SD_EXIST; + } else if (card == MS_CARD) { + rtsx->check_card_cd = MS_EXIST; + } else if (card == XD_CARD) { + rtsx->check_card_cd = XD_EXIST; + } else { + rtsx->check_card_cd = 0; + } + + spin_lock_irq(&rtsx->reg_lock); + + /* set up data structures for the wakeup system */ + rtsx->done = &trans_done; + rtsx->trans_result = TRANS_NOT_READY; + init_completion(&trans_done); + rtsx->trans_state = STATE_TRANS_CMD; + + rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr); + + val |= (u32)(chip->ci * 4) & 0x00FFFFFF; + /* Hardware Auto Response */ + val |= 0x40000000; + rtsx_writel(chip, RTSX_HCBCTLR, val); + + spin_unlock_irq(&rtsx->reg_lock); + + /* Wait for TRANS_OK_INT */ + timeleft = wait_for_completion_interruptible_timeout( + &trans_done, timeout * HZ / 1000); + if (timeleft <= 0) { + RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); + err = -ETIMEDOUT; + TRACE_GOTO(chip, finish_send_cmd); + } + + spin_lock_irq(&rtsx->reg_lock); + if (rtsx->trans_result == TRANS_RESULT_FAIL) { + err = -EIO; + } else if (rtsx->trans_result == TRANS_RESULT_OK) { + err = 0; + } + spin_unlock_irq(&rtsx->reg_lock); + +finish_send_cmd: + rtsx->done = NULL; + rtsx->trans_state = STATE_TRANS_NONE; + + if (err < 0) + rtsx_stop_cmd(chip, card); + + return err; +} + +static inline void rtsx_add_sg_tbl( + struct rtsx_chip *chip, u32 addr, u32 len, u8 option) +{ + u64 *sgb = (u64 *)(chip->host_sg_tbl_ptr); + u64 val = 0; + u32 temp_len = 0; + u8 temp_opt = 0; + + do { + if (len > 0x80000) { + temp_len = 0x80000; + temp_opt = option & (~SG_END); + } else { + temp_len = len; + temp_opt = option; + } + val = ((u64)addr << 32) | ((u64)temp_len << 12) | temp_opt; + + if (chip->sgi < (HOST_SG_TBL_BUF_LEN / 8)) + sgb[(chip->sgi)++] = cpu_to_le64(val); + + len -= temp_len; + addr += temp_len; + } while (len); +} + +int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, + struct scatterlist *sg, int num_sg, unsigned int *index, + unsigned int *offset, int size, + enum dma_data_direction dma_dir, int timeout) +{ + struct rtsx_dev *rtsx = chip->rtsx; + struct completion trans_done; + u8 dir; + int sg_cnt, i, resid; + int err = 0; + long timeleft; + u32 val = TRIG_DMA; + + if ((sg == NULL) || (num_sg <= 0) || !offset || !index) + return -EIO; + + if (dma_dir == DMA_TO_DEVICE) { + dir = HOST_TO_DEVICE; + } else if (dma_dir == DMA_FROM_DEVICE) { + dir = DEVICE_TO_HOST; + } else { + return -ENXIO; + } + + if (card == SD_CARD) { + rtsx->check_card_cd = SD_EXIST; + } else if (card == MS_CARD) { + rtsx->check_card_cd = MS_EXIST; + } else if (card == XD_CARD) { + rtsx->check_card_cd = XD_EXIST; + } else { + rtsx->check_card_cd = 0; + } + + spin_lock_irq(&rtsx->reg_lock); + + /* set up data structures for the wakeup system */ + rtsx->done = &trans_done; + + rtsx->trans_state = STATE_TRANS_SG; + rtsx->trans_result = TRANS_NOT_READY; + + spin_unlock_irq(&rtsx->reg_lock); + + sg_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); + + resid = size; + + chip->sgi = 0; + /* Usually the next entry will be @sg@ + 1, but if this sg element + * is part of a chained scatterlist, it could jump to the start of + * a new scatterlist array. So here we use sg_next to move to + * the proper sg + */ + for (i = 0; i < *index; i++) + sg = sg_next(sg); + for (i = *index; i < sg_cnt; i++) { + dma_addr_t addr; + unsigned int len; + u8 option; + + addr = sg_dma_address(sg); + len = sg_dma_len(sg); + + RTSX_DEBUGP("DMA addr: 0x%x, Len: 0x%x\n", + (unsigned int)addr, len); + RTSX_DEBUGP("*index = %d, *offset = %d\n", *index, *offset); + + addr += *offset; + + if ((len - *offset) > resid) { + *offset += resid; + len = resid; + resid = 0; + } else { + resid -= (len - *offset); + len -= *offset; + *offset = 0; + *index = *index + 1; + } + if ((i == (sg_cnt - 1)) || !resid) { + option = SG_VALID | SG_END | SG_TRANS_DATA; + } else { + option = SG_VALID | SG_TRANS_DATA; + } + + rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option); + + if (!resid) + break; + + sg = sg_next(sg); + } + + RTSX_DEBUGP("SG table count = %d\n", chip->sgi); + + val |= (u32)(dir & 0x01) << 29; + val |= ADMA_MODE; + + spin_lock_irq(&rtsx->reg_lock); + + init_completion(&trans_done); + + rtsx_writel(chip, RTSX_HDBAR, chip->host_sg_tbl_addr); + rtsx_writel(chip, RTSX_HDBCTLR, val); + + spin_unlock_irq(&rtsx->reg_lock); + + timeleft = wait_for_completion_interruptible_timeout( + &trans_done, timeout * HZ / 1000); + if (timeleft <= 0) { + RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__); + RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); + err = -ETIMEDOUT; + goto out; + } + + spin_lock_irq(&rtsx->reg_lock); + if (rtsx->trans_result == TRANS_RESULT_FAIL) { + err = -EIO; + spin_unlock_irq(&rtsx->reg_lock); + goto out; + } + spin_unlock_irq(&rtsx->reg_lock); + + /* Wait for TRANS_OK_INT */ + spin_lock_irq(&rtsx->reg_lock); + if (rtsx->trans_result == TRANS_NOT_READY) { + init_completion(&trans_done); + spin_unlock_irq(&rtsx->reg_lock); + timeleft = wait_for_completion_interruptible_timeout( + &trans_done, timeout * HZ / 1000); + if (timeleft <= 0) { + RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__); + RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); + err = -ETIMEDOUT; + goto out; + } + } else { + spin_unlock_irq(&rtsx->reg_lock); + } + + spin_lock_irq(&rtsx->reg_lock); + if (rtsx->trans_result == TRANS_RESULT_FAIL) { + err = -EIO; + } else if (rtsx->trans_result == TRANS_RESULT_OK) { + err = 0; + } + spin_unlock_irq(&rtsx->reg_lock); + +out: + rtsx->done = NULL; + rtsx->trans_state = STATE_TRANS_NONE; + dma_unmap_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); + + if (err < 0) + rtsx_stop_cmd(chip, card); + + return err; +} + +int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, + struct scatterlist *sg, int num_sg, + enum dma_data_direction dma_dir, int timeout) +{ + struct rtsx_dev *rtsx = chip->rtsx; + struct completion trans_done; + u8 dir; + int buf_cnt, i; + int err = 0; + long timeleft; + struct scatterlist *sg_ptr; + + if ((sg == NULL) || (num_sg <= 0)) + return -EIO; + + if (dma_dir == DMA_TO_DEVICE) { + dir = HOST_TO_DEVICE; + } else if (dma_dir == DMA_FROM_DEVICE) { + dir = DEVICE_TO_HOST; + } else { + return -ENXIO; + } + + if (card == SD_CARD) { + rtsx->check_card_cd = SD_EXIST; + } else if (card == MS_CARD) { + rtsx->check_card_cd = MS_EXIST; + } else if (card == XD_CARD) { + rtsx->check_card_cd = XD_EXIST; + } else { + rtsx->check_card_cd = 0; + } + + spin_lock_irq(&rtsx->reg_lock); + + /* set up data structures for the wakeup system */ + rtsx->done = &trans_done; + + rtsx->trans_state = STATE_TRANS_SG; + rtsx->trans_result = TRANS_NOT_READY; + + spin_unlock_irq(&rtsx->reg_lock); + + buf_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); + + sg_ptr = sg; + + for (i = 0; i <= buf_cnt / (HOST_SG_TBL_BUF_LEN / 8); i++) { + u32 val = TRIG_DMA; + int sg_cnt, j; + + if (i == buf_cnt / (HOST_SG_TBL_BUF_LEN / 8)) { + sg_cnt = buf_cnt % (HOST_SG_TBL_BUF_LEN / 8); + } else { + sg_cnt = (HOST_SG_TBL_BUF_LEN / 8); + } + + chip->sgi = 0; + for (j = 0; j < sg_cnt; j++) { + dma_addr_t addr = sg_dma_address(sg_ptr); + unsigned int len = sg_dma_len(sg_ptr); + u8 option; + + RTSX_DEBUGP("DMA addr: 0x%x, Len: 0x%x\n", + (unsigned int)addr, len); + + if (j == (sg_cnt - 1)) { + option = SG_VALID | SG_END | SG_TRANS_DATA; + } else { + option = SG_VALID | SG_TRANS_DATA; + } + + rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option); + + sg_ptr = sg_next(sg_ptr); + } + + RTSX_DEBUGP("SG table count = %d\n", chip->sgi); + + val |= (u32)(dir & 0x01) << 29; + val |= ADMA_MODE; + + spin_lock_irq(&rtsx->reg_lock); + + init_completion(&trans_done); + + rtsx_writel(chip, RTSX_HDBAR, chip->host_sg_tbl_addr); + rtsx_writel(chip, RTSX_HDBCTLR, val); + + spin_unlock_irq(&rtsx->reg_lock); + + timeleft = wait_for_completion_interruptible_timeout( + &trans_done, timeout * HZ / 1000); + if (timeleft <= 0) { + RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__); + RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); + err = -ETIMEDOUT; + goto out; + } + + spin_lock_irq(&rtsx->reg_lock); + if (rtsx->trans_result == TRANS_RESULT_FAIL) { + err = -EIO; + spin_unlock_irq(&rtsx->reg_lock); + goto out; + } + spin_unlock_irq(&rtsx->reg_lock); + + sg_ptr += sg_cnt; + } + + /* Wait for TRANS_OK_INT */ + spin_lock_irq(&rtsx->reg_lock); + if (rtsx->trans_result == TRANS_NOT_READY) { + init_completion(&trans_done); + spin_unlock_irq(&rtsx->reg_lock); + timeleft = wait_for_completion_interruptible_timeout( + &trans_done, timeout * HZ / 1000); + if (timeleft <= 0) { + RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__); + RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); + err = -ETIMEDOUT; + goto out; + } + } else { + spin_unlock_irq(&rtsx->reg_lock); + } + + spin_lock_irq(&rtsx->reg_lock); + if (rtsx->trans_result == TRANS_RESULT_FAIL) { + err = -EIO; + } else if (rtsx->trans_result == TRANS_RESULT_OK) { + err = 0; + } + spin_unlock_irq(&rtsx->reg_lock); + +out: + rtsx->done = NULL; + rtsx->trans_state = STATE_TRANS_NONE; + dma_unmap_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); + + if (err < 0) + rtsx_stop_cmd(chip, card); + + return err; +} + +int rtsx_transfer_buf(struct rtsx_chip *chip, u8 card, void *buf, size_t len, + enum dma_data_direction dma_dir, int timeout) +{ + struct rtsx_dev *rtsx = chip->rtsx; + struct completion trans_done; + dma_addr_t addr; + u8 dir; + int err = 0; + u32 val = (1 << 31); + long timeleft; + + if ((buf == NULL) || (len <= 0)) + return -EIO; + + if (dma_dir == DMA_TO_DEVICE) { + dir = HOST_TO_DEVICE; + } else if (dma_dir == DMA_FROM_DEVICE) { + dir = DEVICE_TO_HOST; + } else { + return -ENXIO; + } + + addr = dma_map_single(&(rtsx->pci->dev), buf, len, dma_dir); + if (!addr) + return -ENOMEM; + + if (card == SD_CARD) { + rtsx->check_card_cd = SD_EXIST; + } else if (card == MS_CARD) { + rtsx->check_card_cd = MS_EXIST; + } else if (card == XD_CARD) { + rtsx->check_card_cd = XD_EXIST; + } else { + rtsx->check_card_cd = 0; + } + + val |= (u32)(dir & 0x01) << 29; + val |= (u32)(len & 0x00FFFFFF); + + spin_lock_irq(&rtsx->reg_lock); + + /* set up data structures for the wakeup system */ + rtsx->done = &trans_done; + + init_completion(&trans_done); + + rtsx->trans_state = STATE_TRANS_BUF; + rtsx->trans_result = TRANS_NOT_READY; + + rtsx_writel(chip, RTSX_HDBAR, addr); + rtsx_writel(chip, RTSX_HDBCTLR, val); + + spin_unlock_irq(&rtsx->reg_lock); + + /* Wait for TRANS_OK_INT */ + timeleft = wait_for_completion_interruptible_timeout( + &trans_done, timeout * HZ / 1000); + if (timeleft <= 0) { + RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__); + RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); + err = -ETIMEDOUT; + goto out; + } + + spin_lock_irq(&rtsx->reg_lock); + if (rtsx->trans_result == TRANS_RESULT_FAIL) { + err = -EIO; + } else if (rtsx->trans_result == TRANS_RESULT_OK) { + err = 0; + } + spin_unlock_irq(&rtsx->reg_lock); + +out: + rtsx->done = NULL; + rtsx->trans_state = STATE_TRANS_NONE; + dma_unmap_single(&(rtsx->pci->dev), addr, len, dma_dir); + + if (err < 0) + rtsx_stop_cmd(chip, card); + + return err; +} + +int rtsx_transfer_sglist(struct rtsx_chip *chip, u8 card, + struct scatterlist *sg, int num_sg, + enum dma_data_direction dma_dir, int timeout) +{ + struct rtsx_dev *rtsx = chip->rtsx; + struct completion trans_done; + u8 dir; + int buf_cnt, i; + int err = 0; + long timeleft; + + if ((sg == NULL) || (num_sg <= 0)) + return -EIO; + + if (dma_dir == DMA_TO_DEVICE) { + dir = HOST_TO_DEVICE; + } else if (dma_dir == DMA_FROM_DEVICE) { + dir = DEVICE_TO_HOST; + } else { + return -ENXIO; + } + + if (card == SD_CARD) { + rtsx->check_card_cd = SD_EXIST; + } else if (card == MS_CARD) { + rtsx->check_card_cd = MS_EXIST; + } else if (card == XD_CARD) { + rtsx->check_card_cd = XD_EXIST; + } else { + rtsx->check_card_cd = 0; + } + + spin_lock_irq(&rtsx->reg_lock); + + /* set up data structures for the wakeup system */ + rtsx->done = &trans_done; + + rtsx->trans_state = STATE_TRANS_SG; + rtsx->trans_result = TRANS_NOT_READY; + + spin_unlock_irq(&rtsx->reg_lock); + + buf_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); + + for (i = 0; i < buf_cnt; i++) { + u32 bier = 0; + u32 val = (1 << 31); + dma_addr_t addr = sg_dma_address(sg + i); + unsigned int len = sg_dma_len(sg + i); + + RTSX_DEBUGP("dma_addr = 0x%x, dma_len = %d\n", + (unsigned int)addr, len); + + val |= (u32)(dir & 0x01) << 29; + val |= (u32)(len & 0x00FFFFFF); + + spin_lock_irq(&rtsx->reg_lock); + + init_completion(&trans_done); + + if (i == (buf_cnt - 1)) { + /* If last transfer, disable data interrupt */ + bier = rtsx_readl(chip, RTSX_BIER); + rtsx_writel(chip, RTSX_BIER, bier & 0xBFFFFFFF); + } + + rtsx_writel(chip, RTSX_HDBAR, addr); + rtsx_writel(chip, RTSX_HDBCTLR, val); + + spin_unlock_irq(&rtsx->reg_lock); + + timeleft = wait_for_completion_interruptible_timeout( + &trans_done, timeout * HZ / 1000); + if (timeleft <= 0) { + RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__); + RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); + err = -ETIMEDOUT; + if (i == (buf_cnt - 1)) + rtsx_writel(chip, RTSX_BIER, bier); + goto out; + } + + spin_lock_irq(&rtsx->reg_lock); + if (rtsx->trans_result == TRANS_RESULT_FAIL) { + err = -EIO; + spin_unlock_irq(&rtsx->reg_lock); + if (i == (buf_cnt - 1)) + rtsx_writel(chip, RTSX_BIER, bier); + goto out; + } + spin_unlock_irq(&rtsx->reg_lock); + + if (i == (buf_cnt - 1)) { + /* If last transfer, enable data interrupt + * after transfer finished + */ + rtsx_writel(chip, RTSX_BIER, bier); + } + } + + /* Wait for TRANS_OK_INT */ + spin_lock_irq(&rtsx->reg_lock); + if (rtsx->trans_result == TRANS_NOT_READY) { + init_completion(&trans_done); + spin_unlock_irq(&rtsx->reg_lock); + timeleft = wait_for_completion_interruptible_timeout( + &trans_done, timeout * HZ / 1000); + if (timeleft <= 0) { + RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__); + RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); + err = -ETIMEDOUT; + goto out; + } + } else { + spin_unlock_irq(&rtsx->reg_lock); + } + + spin_lock_irq(&rtsx->reg_lock); + if (rtsx->trans_result == TRANS_RESULT_FAIL) { + err = -EIO; + } else if (rtsx->trans_result == TRANS_RESULT_OK) { + err = 0; + } + spin_unlock_irq(&rtsx->reg_lock); + +out: + rtsx->done = NULL; + rtsx->trans_state = STATE_TRANS_NONE; + dma_unmap_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); + + if (err < 0) + rtsx_stop_cmd(chip, card); + + return err; +} + +int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card, + void *buf, size_t len, int use_sg, unsigned int *index, + unsigned int *offset, enum dma_data_direction dma_dir, + int timeout) +{ + int err = 0; + + /* don't transfer data during abort processing */ + if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) + return -EIO; + + if (use_sg) { + err = rtsx_transfer_sglist_adma_partial(chip, card, + (struct scatterlist *)buf, use_sg, + index, offset, (int)len, dma_dir, timeout); + } else { + err = rtsx_transfer_buf(chip, card, + buf, len, dma_dir, timeout); + } + + if (err < 0) { + if (RTSX_TST_DELINK(chip)) { + RTSX_CLR_DELINK(chip); + chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; + rtsx_reinit_cards(chip, 1); + } + } + + return err; +} + +int rtsx_transfer_data(struct rtsx_chip *chip, u8 card, void *buf, size_t len, + int use_sg, enum dma_data_direction dma_dir, int timeout) +{ + int err = 0; + + RTSX_DEBUGP("use_sg = %d\n", use_sg); + + /* don't transfer data during abort processing */ + if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) + return -EIO; + + if (use_sg) { + err = rtsx_transfer_sglist_adma(chip, card, + (struct scatterlist *)buf, + use_sg, dma_dir, timeout); + } else { + err = rtsx_transfer_buf(chip, card, buf, len, dma_dir, timeout); + } + + if (err < 0) { + if (RTSX_TST_DELINK(chip)) { + RTSX_CLR_DELINK(chip); + chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; + rtsx_reinit_cards(chip, 1); + } + } + + return err; +} + diff --git a/drivers/staging/rts_pstor/rtsx_transport.h b/drivers/staging/rts_pstor/rtsx_transport.h new file mode 100644 index 000000000000..41f1ea05a8d3 --- /dev/null +++ b/drivers/staging/rts_pstor/rtsx_transport.h @@ -0,0 +1,66 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __REALTEK_RTSX_TRANSPORT_H +#define __REALTEK_RTSX_TRANSPORT_H + +#include "rtsx.h" +#include "rtsx_chip.h" + +#define WAIT_TIME 2000 + +unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer, + unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index, + unsigned int *offset, enum xfer_buf_dir dir); +void rtsx_stor_set_xfer_buf(unsigned char *buffer, + unsigned int buflen, struct scsi_cmnd *srb); +void rtsx_stor_get_xfer_buf(unsigned char *buffer, + unsigned int buflen, struct scsi_cmnd *srb); +void rtsx_invoke_transport(struct scsi_cmnd *srb, struct rtsx_chip *chip); + + +#define rtsx_init_cmd(chip) ((chip)->ci = 0) + +void rtsx_add_cmd(struct rtsx_chip *chip, + u8 cmd_type, u16 reg_addr, u8 mask, u8 data); +void rtsx_send_cmd_no_wait(struct rtsx_chip *chip); +int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout); + +extern inline u8 *rtsx_get_cmd_data(struct rtsx_chip *chip) +{ +#ifdef CMD_USING_SG + return (u8 *)(chip->host_sg_tbl_ptr); +#else + return (u8 *)(chip->host_cmds_ptr); +#endif +} + +int rtsx_transfer_data(struct rtsx_chip *chip, u8 card, void *buf, size_t len, + int use_sg, enum dma_data_direction dma_dir, int timeout); + +int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card, void *buf, size_t len, + int use_sg, unsigned int *index, unsigned int *offset, + enum dma_data_direction dma_dir, int timeout); + +#endif /* __REALTEK_RTSX_TRANSPORT_H */ + diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c new file mode 100644 index 000000000000..945c95f2994f --- /dev/null +++ b/drivers/staging/rts_pstor/sd.c @@ -0,0 +1,4768 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include +#include +#include + +#include "rtsx.h" +#include "rtsx_transport.h" +#include "rtsx_scsi.h" +#include "rtsx_card.h" +#include "sd.h" + +#define SD_MAX_RETRY_COUNT 3 + +u16 REG_SD_CFG1; +u16 REG_SD_CFG2; +u16 REG_SD_CFG3; +u16 REG_SD_STAT1; +u16 REG_SD_STAT2; +u16 REG_SD_BUS_STAT; +u16 REG_SD_PAD_CTL; +u16 REG_SD_SAMPLE_POINT_CTL; +u16 REG_SD_PUSH_POINT_CTL; +u16 REG_SD_CMD0; +u16 REG_SD_CMD1; +u16 REG_SD_CMD2; +u16 REG_SD_CMD3; +u16 REG_SD_CMD4; +u16 REG_SD_CMD5; +u16 REG_SD_BYTE_CNT_L; +u16 REG_SD_BYTE_CNT_H; +u16 REG_SD_BLOCK_CNT_L; +u16 REG_SD_BLOCK_CNT_H; +u16 REG_SD_TRANSFER; +u16 REG_SD_VPCLK0_CTL; +u16 REG_SD_VPCLK1_CTL; +u16 REG_SD_DCMPS0_CTL; +u16 REG_SD_DCMPS1_CTL; + +static inline void sd_set_err_code(struct rtsx_chip *chip, u8 err_code) +{ + struct sd_info *sd_card = &(chip->sd_card); + + sd_card->err_code |= err_code; +} + +static inline void sd_clr_err_code(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + + sd_card->err_code = 0; +} + +static inline int sd_check_err_code(struct rtsx_chip *chip, u8 err_code) +{ + struct sd_info *sd_card = &(chip->sd_card); + + return sd_card->err_code & err_code; +} + +static void sd_init_reg_addr(struct rtsx_chip *chip) +{ + if (CHECK_PID(chip, 0x5209)) { + REG_SD_CFG1 = SD_CFG1; + REG_SD_CFG2 = SD_CFG2; + REG_SD_CFG3 = SD_CFG3; + REG_SD_STAT1 = SD_STAT1; + REG_SD_STAT2 = SD_STAT2; + REG_SD_BUS_STAT = SD_BUS_STAT; + REG_SD_PAD_CTL = SD_PAD_CTL; + REG_SD_SAMPLE_POINT_CTL = SD_SAMPLE_POINT_CTL; + REG_SD_PUSH_POINT_CTL = SD_PUSH_POINT_CTL; + REG_SD_CMD0 = SD_CMD0; + REG_SD_CMD1 = SD_CMD1; + REG_SD_CMD2 = SD_CMD2; + REG_SD_CMD3 = SD_CMD3; + REG_SD_CMD4 = SD_CMD4; + REG_SD_CMD5 = SD_CMD5; + REG_SD_BYTE_CNT_L = SD_BYTE_CNT_L; + REG_SD_BYTE_CNT_H = SD_BYTE_CNT_H; + REG_SD_BLOCK_CNT_L = SD_BLOCK_CNT_L; + REG_SD_BLOCK_CNT_H = SD_BLOCK_CNT_H; + REG_SD_TRANSFER = SD_TRANSFER; + REG_SD_VPCLK0_CTL = SD_VPCLK0_CTL; + REG_SD_VPCLK1_CTL = SD_VPCLK1_CTL; + REG_SD_DCMPS0_CTL = SD_DCMPS0_CTL; + REG_SD_DCMPS1_CTL = SD_DCMPS1_CTL; + } else { + REG_SD_CFG1 = 0xFD31; + REG_SD_CFG2 = 0xFD33; + REG_SD_CFG3 = 0xFD3E; + REG_SD_STAT1 = 0xFD30; + REG_SD_STAT2 = 0; + REG_SD_BUS_STAT = 0; + REG_SD_PAD_CTL = 0; + REG_SD_SAMPLE_POINT_CTL = 0; + REG_SD_PUSH_POINT_CTL = 0; + REG_SD_CMD0 = 0xFD34; + REG_SD_CMD1 = 0xFD35; + REG_SD_CMD2 = 0xFD36; + REG_SD_CMD3 = 0xFD37; + REG_SD_CMD4 = 0xFD38; + REG_SD_CMD5 = 0xFD5A; + REG_SD_BYTE_CNT_L = 0xFD39; + REG_SD_BYTE_CNT_H = 0xFD3A; + REG_SD_BLOCK_CNT_L = 0xFD3B; + REG_SD_BLOCK_CNT_H = 0xFD3C; + REG_SD_TRANSFER = 0xFD32; + REG_SD_VPCLK0_CTL = 0; + REG_SD_VPCLK1_CTL = 0; + REG_SD_DCMPS0_CTL = 0; + REG_SD_DCMPS1_CTL = 0; + } +} + +static int sd_check_data0_status(struct rtsx_chip *chip) +{ + u8 stat; + + if (CHECK_PID(chip, 0x5209)) { + RTSX_READ_REG(chip, REG_SD_BUS_STAT, &stat); + } else { + RTSX_READ_REG(chip, REG_SD_STAT1, &stat); + } + + if (!(stat & SD_DAT0_STATUS)) { + sd_set_err_code(chip, SD_BUSY); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx, + u32 arg, u8 rsp_type, u8 *rsp, int rsp_len) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int timeout = 100; + u16 reg_addr; + u8 *ptr; + int stat_idx = 0; + int rty_cnt = 0; + + sd_clr_err_code(chip); + + RTSX_DEBUGP("SD/MMC CMD %d, arg = 0x%08x\n", cmd_idx, arg); + + if (rsp_type == SD_RSP_TYPE_R1b) + timeout = 3000; + +RTY_SEND_CMD: + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | cmd_idx); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, (u8)(arg >> 24)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, (u8)(arg >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, (u8)(arg >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, (u8)arg); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, + 0x01, PINGPONG_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, + 0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, + SD_TRANSFER_END | SD_STAT_IDLE, SD_TRANSFER_END | SD_STAT_IDLE); + + if (rsp_type == SD_RSP_TYPE_R2) { + for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; reg_addr++) { + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); + } + stat_idx = 16; + } else if (rsp_type != SD_RSP_TYPE_R0) { + for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; reg_addr++) { + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); + } + stat_idx = 5; + } + + rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_STAT1, 0, 0); + + retval = rtsx_send_cmd(chip, SD_CARD, timeout); + if (retval < 0) { + u8 val; + + rtsx_read_register(chip, REG_SD_STAT1, &val); + RTSX_DEBUGP("SD_STAT1: 0x%x\n", val); + + if (CHECK_PID(chip, 0x5209)) { + rtsx_read_register(chip, REG_SD_STAT2, &val); + RTSX_DEBUGP("SD_STAT2: 0x%x\n", val); + + if (val & SD_RSP_80CLK_TIMEOUT) { + rtsx_clear_sd_error(chip); + sd_set_err_code(chip, SD_RSP_TIMEOUT); + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_read_register(chip, REG_SD_BUS_STAT, &val); + RTSX_DEBUGP("SD_BUS_STAT: 0x%x\n", val); + } else { + rtsx_read_register(chip, REG_SD_CFG3, &val); + RTSX_DEBUGP("SD_CFG3: 0x%x\n", val); + } + + if (retval == -ETIMEDOUT) { + if (rsp_type & SD_WAIT_BUSY_END) { + retval = sd_check_data0_status(chip); + if (retval != STATUS_SUCCESS) { + rtsx_clear_sd_error(chip); + TRACE_RET(chip, retval); + } + } else { + sd_set_err_code(chip, SD_TO_ERR); + } + retval = STATUS_TIMEDOUT; + } else { + retval = STATUS_FAIL; + } + rtsx_clear_sd_error(chip); + + TRACE_RET(chip, retval); + } + + if (rsp_type == SD_RSP_TYPE_R0) + return STATUS_SUCCESS; + + ptr = rtsx_get_cmd_data(chip) + 1; + + if ((ptr[0] & 0xC0) != 0) { + sd_set_err_code(chip, SD_STS_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + if (!(rsp_type & SD_NO_CHECK_CRC7)) { + if (ptr[stat_idx] & SD_CRC7_ERR) { + if (cmd_idx == WRITE_MULTIPLE_BLOCK) { + sd_set_err_code(chip, SD_CRC_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + if (rty_cnt < SD_MAX_RETRY_COUNT) { + wait_timeout(20); + rty_cnt++; + goto RTY_SEND_CMD; + } else { + sd_set_err_code(chip, SD_CRC_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + if ((rsp_type == SD_RSP_TYPE_R1) || (rsp_type == SD_RSP_TYPE_R1b)) { + if ((cmd_idx != SEND_RELATIVE_ADDR) && (cmd_idx != SEND_IF_COND)) { + if (cmd_idx != STOP_TRANSMISSION) { + if (ptr[1] & 0x80) { + TRACE_RET(chip, STATUS_FAIL); + } + } +#ifdef SUPPORT_SD_LOCK + if (ptr[1] & 0x7D) +#else + if (ptr[1] & 0x7F) +#endif + { + RTSX_DEBUGP("ptr[1]: 0x%02x\n", ptr[1]); + TRACE_RET(chip, STATUS_FAIL); + } + if (ptr[2] & 0xFF) { + RTSX_DEBUGP("ptr[2]: 0x%02x\n", ptr[2]); + TRACE_RET(chip, STATUS_FAIL); + } + if (ptr[3] & 0x80) { + RTSX_DEBUGP("ptr[3]: 0x%02x\n", ptr[3]); + TRACE_RET(chip, STATUS_FAIL); + } + if (ptr[3] & 0x01) { + sd_card->sd_data_buf_ready = 1; + } else { + sd_card->sd_data_buf_ready = 0; + } + } + } + + if (rsp && rsp_len) + memcpy(rsp, ptr, rsp_len); + + return STATUS_SUCCESS; +} + +static int sd_read_data(struct rtsx_chip *chip, + u8 trans_mode, u8 *cmd, int cmd_len, u16 byte_cnt, + u16 blk_cnt, u8 bus_width, u8 *buf, int buf_len, + int timeout) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i; + + sd_clr_err_code(chip); + + if (!buf) + buf_len = 0; + + if (buf_len > 512) { + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + if (cmd_len) { + RTSX_DEBUGP("SD/MMC CMD %d\n", cmd[0] - 0x40); + for (i = 0; i < (cmd_len < 6 ? cmd_len : 6); i++) { + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0 + i, 0xFF, cmd[i]); + } + } + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, (u8)(byte_cnt >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, (u8)blk_cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, (u8)(blk_cnt >> 8)); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, + SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | + SD_CHECK_CRC7 | SD_RSP_LEN_6); + if (trans_mode != SD_TM_AUTO_TUNING) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); + } + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, trans_mode | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); + + retval = rtsx_send_cmd(chip, SD_CARD, timeout); + if (retval < 0) { + if (retval == -ETIMEDOUT) { + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + } + + TRACE_RET(chip, STATUS_FAIL); + } + + if (buf && buf_len) { + retval = rtsx_read_ppbuf(chip, buf, buf_len); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + +static int sd_write_data(struct rtsx_chip *chip, u8 trans_mode, + u8 *cmd, int cmd_len, u16 byte_cnt, u16 blk_cnt, u8 bus_width, + u8 *buf, int buf_len, int timeout) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i; + + sd_clr_err_code(chip); + + if (!buf) + buf_len = 0; + + if (buf_len > 512) { + /* This function can't write data more than one page */ + TRACE_RET(chip, STATUS_FAIL); + } + + if (buf && buf_len) { + retval = rtsx_write_ppbuf(chip, buf, buf_len); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + rtsx_init_cmd(chip); + + if (cmd_len) { + RTSX_DEBUGP("SD/MMC CMD %d\n", cmd[0] - 0x40); + for (i = 0; i < (cmd_len < 6 ? cmd_len : 6); i++) { + rtsx_add_cmd(chip, WRITE_REG_CMD, + REG_SD_CMD0 + i, 0xFF, cmd[i]); + } + } + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, (u8)(byte_cnt >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, (u8)blk_cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, (u8)(blk_cnt >> 8)); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, + SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | + SD_CHECK_CRC7 | SD_RSP_LEN_6); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, trans_mode | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); + + retval = rtsx_send_cmd(chip, SD_CARD, timeout); + if (retval < 0) { + if (retval == -ETIMEDOUT) { + sd_send_cmd_get_rsp(chip, SEND_STATUS, + sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); + } + + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_check_csd(struct rtsx_chip *chip, char check_wp) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i; + u8 csd_ver, trans_speed; + u8 rsp[16]; + + for (i = 0; i < 6; i++) { + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_send_cmd_get_rsp(chip, SEND_CSD, sd_card->sd_addr, SD_RSP_TYPE_R2, rsp, 16); + if (retval == STATUS_SUCCESS) + break; + } + + if (i == 6) { + TRACE_RET(chip, STATUS_FAIL); + } + + memcpy(sd_card->raw_csd, rsp + 1, 15); + + if (CHECK_PID(chip, 0x5209)) { + RTSX_READ_REG(chip, REG_SD_CMD5, sd_card->raw_csd + 15); + } + + RTSX_DEBUGP("CSD Response:\n"); + RTSX_DUMP(sd_card->raw_csd, 16); + + csd_ver = (rsp[1] & 0xc0) >> 6; + RTSX_DEBUGP("csd_ver = %d\n", csd_ver); + + trans_speed = rsp[4]; + if ((trans_speed & 0x07) == 0x02) { + if ((trans_speed & 0xf8) >= 0x30) { + if (chip->asic_code) { + sd_card->sd_clock = 47; + } else { + sd_card->sd_clock = CLK_50; + } + } else if ((trans_speed & 0xf8) == 0x28) { + if (chip->asic_code) { + sd_card->sd_clock = 39; + } else { + sd_card->sd_clock = CLK_40; + } + } else if ((trans_speed & 0xf8) == 0x20) { + if (chip->asic_code) { + sd_card->sd_clock = 29; + } else { + sd_card->sd_clock = CLK_30; + } + } else if ((trans_speed & 0xf8) >= 0x10) { + if (chip->asic_code) { + sd_card->sd_clock = 23; + } else { + sd_card->sd_clock = CLK_20; + } + } else if ((trans_speed & 0x08) >= 0x08) { + if (chip->asic_code) { + sd_card->sd_clock = 19; + } else { + sd_card->sd_clock = CLK_20; + } + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + TRACE_RET(chip, STATUS_FAIL); + } + + if (CHK_MMC_SECTOR_MODE(sd_card)) { + sd_card->capacity = 0; + } else { + if ((!CHK_SD_HCXC(sd_card)) || (csd_ver == 0)) { + u8 blk_size, c_size_mult; + u16 c_size; + blk_size = rsp[6] & 0x0F; + c_size = ((u16)(rsp[7] & 0x03) << 10) + + ((u16)rsp[8] << 2) + + ((u16)(rsp[9] & 0xC0) >> 6); + c_size_mult = (u8)((rsp[10] & 0x03) << 1); + c_size_mult += (rsp[11] & 0x80) >> 7; + sd_card->capacity = (((u32)(c_size + 1)) * (1 << (c_size_mult + 2))) << (blk_size - 9); + } else { + u32 total_sector = 0; + total_sector = (((u32)rsp[8] & 0x3f) << 16) | + ((u32)rsp[9] << 8) | (u32)rsp[10]; + sd_card->capacity = (total_sector + 1) << 10; + } + } + + if (check_wp) { + if (rsp[15] & 0x30) { + chip->card_wp |= SD_CARD; + } + RTSX_DEBUGP("CSD WP Status: 0x%x\n", rsp[15]); + } + + return STATUS_SUCCESS; +} + +static int sd_set_sample_push_timing(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + + if (CHECK_PID(chip, 0x5209)) { + if (CHK_SD_SDR104(sd_card) || CHK_SD_SDR50(sd_card)) { + RTSX_WRITE_REG(chip, SD_CFG1, 0x0C | SD_ASYNC_FIFO_NOT_RST, + SD_30_MODE | SD_ASYNC_FIFO_NOT_RST); + RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ); + RTSX_WRITE_REG(chip, CARD_CLK_SOURCE, 0xFF, + CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1); + RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0); + } else if (CHK_SD_DDR50(sd_card) || CHK_MMC_DDR52(sd_card)) { + RTSX_WRITE_REG(chip, SD_CFG1, 0x0C | SD_ASYNC_FIFO_NOT_RST, + SD_DDR_MODE | SD_ASYNC_FIFO_NOT_RST); + RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ); + RTSX_WRITE_REG(chip, CARD_CLK_SOURCE, 0xFF, + CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1); + RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0); + RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, DDR_VAR_TX_CMD_DAT, + DDR_VAR_TX_CMD_DAT); + RTSX_WRITE_REG(chip, SD_SAMPLE_POINT_CTL, DDR_VAR_RX_DAT | DDR_VAR_RX_CMD, + DDR_VAR_RX_DAT | DDR_VAR_RX_CMD); + } else { + u8 val = 0; + + RTSX_WRITE_REG(chip, SD_CFG1, 0x0C, SD_20_MODE); + RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ); + RTSX_WRITE_REG(chip, CARD_CLK_SOURCE, 0xFF, + CRC_FIX_CLK | SD30_VAR_CLK0 | SAMPLE_VAR_CLK1); + RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0); + + if ((chip->sd_ctl & SD_PUSH_POINT_CTL_MASK) == SD_PUSH_POINT_AUTO) { + val = SD20_TX_NEG_EDGE; + } else if ((chip->sd_ctl & SD_PUSH_POINT_CTL_MASK) == SD_PUSH_POINT_DELAY) { + val = SD20_TX_14_AHEAD; + } else { + val = SD20_TX_NEG_EDGE; + } + RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, SD20_TX_SEL_MASK, val); + + if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == SD_SAMPLE_POINT_AUTO) { + if (chip->asic_code) { + if (CHK_SD_HS(sd_card) || CHK_MMC_52M(sd_card)) { + val = SD20_RX_14_DELAY; + } else { + val = SD20_RX_POS_EDGE; + } + } else { + val = SD20_RX_14_DELAY; + } + } else if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == SD_SAMPLE_POINT_DELAY) { + val = SD20_RX_14_DELAY; + } else { + val = SD20_RX_POS_EDGE; + } + RTSX_WRITE_REG(chip, SD_SAMPLE_POINT_CTL, SD20_RX_SEL_MASK, val); + } + } else { + u8 val = 0; + + if ((chip->sd_ctl & SD_PUSH_POINT_CTL_MASK) == SD_PUSH_POINT_DELAY) { + val |= 0x10; + } + + if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == SD_SAMPLE_POINT_AUTO) { + if (chip->asic_code) { + if (CHK_SD_HS(sd_card) || CHK_MMC_52M(sd_card)) { + if (val & 0x10) { + val |= 0x04; + } else { + val |= 0x08; + } + } + } else { + if (val & 0x10) { + val |= 0x04; + } else { + val |= 0x08; + } + } + } else if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == SD_SAMPLE_POINT_DELAY) { + if (val & 0x10) { + val |= 0x04; + } else { + val |= 0x08; + } + } + + RTSX_WRITE_REG(chip, REG_SD_CFG1, 0x1C, val); + } + + return STATUS_SUCCESS; +} + +static void sd_choose_proper_clock(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + + if (CHK_SD_SDR104(sd_card)) { + if (chip->asic_code) { + sd_card->sd_clock = chip->asic_sd_sdr104_clk; + } else { + sd_card->sd_clock = chip->fpga_sd_sdr104_clk; + } + } else if (CHK_SD_DDR50(sd_card)) { + if (chip->asic_code) { + sd_card->sd_clock = chip->asic_sd_ddr50_clk; + } else { + sd_card->sd_clock = chip->fpga_sd_ddr50_clk; + } + } else if (CHK_SD_SDR50(sd_card)) { + if (chip->asic_code) { + sd_card->sd_clock = chip->asic_sd_sdr50_clk; + } else { + sd_card->sd_clock = chip->fpga_sd_sdr50_clk; + } + } else if (CHK_SD_HS(sd_card)) { + if (chip->asic_code) { + sd_card->sd_clock = chip->asic_sd_hs_clk; + } else { + sd_card->sd_clock = chip->fpga_sd_hs_clk; + } + } else if (CHK_MMC_52M(sd_card) || CHK_MMC_DDR52(sd_card)) { + if (chip->asic_code) { + sd_card->sd_clock = chip->asic_mmc_52m_clk; + } else { + sd_card->sd_clock = chip->fpga_mmc_52m_clk; + } + } else if (CHK_MMC_26M(sd_card)) { + if (chip->asic_code) { + sd_card->sd_clock = 48; + } else { + sd_card->sd_clock = CLK_50; + } + } +} + +static int sd_set_clock_divider(struct rtsx_chip *chip, u8 clk_div) +{ + u8 mask = 0, val = 0; + + if (CHECK_PID(chip, 0x5209)) { + mask = SD_CLK_DIVIDE_MASK; + val = clk_div; + } else { + mask = 0x60; + if (clk_div == SD_CLK_DIVIDE_0) { + val = 0x00; + } else if (clk_div == SD_CLK_DIVIDE_128) { + val = 0x40; + } else if (clk_div == SD_CLK_DIVIDE_256) { + val = 0x20; + } + } + + RTSX_WRITE_REG(chip, REG_SD_CFG1, mask, val); + + return STATUS_SUCCESS; +} + +static int sd_set_init_para(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + retval = sd_set_sample_push_timing(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + sd_choose_proper_clock(chip); + + retval = switch_clock(chip, sd_card->sd_clock); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int sd_select_card(struct rtsx_chip *chip, int select) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd_idx, cmd_type; + u32 addr; + + if (select) { + cmd_idx = SELECT_CARD; + cmd_type = SD_RSP_TYPE_R1; + addr = sd_card->sd_addr; + } else { + cmd_idx = DESELECT_CARD; + cmd_type = SD_RSP_TYPE_R0; + addr = 0; + } + + retval = sd_send_cmd_get_rsp(chip, cmd_idx, addr, cmd_type, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +#ifdef SUPPORT_SD_LOCK +static int sd_update_lock_status(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 rsp[5]; + + retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, rsp, 5); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (rsp[1] & 0x02) { + sd_card->sd_lock_status |= SD_LOCKED; + } else { + sd_card->sd_lock_status &= ~SD_LOCKED; + } + + RTSX_DEBUGP("sd_card->sd_lock_status = 0x%x\n", sd_card->sd_lock_status); + + if (rsp[1] & 0x01) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} +#endif + +static int sd_wait_state_data_ready(struct rtsx_chip *chip, u8 state, u8 data_ready, int polling_cnt) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval, i; + u8 rsp[5]; + + for (i = 0; i < polling_cnt; i++) { + retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, + sd_card->sd_addr, SD_RSP_TYPE_R1, rsp, 5); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (((rsp[3] & 0x1E) == state) && ((rsp[3] & 0x01) == data_ready)) { + return STATUS_SUCCESS; + } + } + + TRACE_RET(chip, STATUS_FAIL); +} + +static int sd_change_bank_voltage(struct rtsx_chip *chip, u8 voltage) +{ + int retval; + + if (voltage == SD_IO_3V3) { + if (chip->asic_code) { + retval = rtsx_write_phy_register(chip, 0x08, 0x4FC0 | chip->phy_voltage); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + RTSX_WRITE_REG(chip, SD_PAD_CTL, SD_IO_USING_1V8, 0); + } + } else if (voltage == SD_IO_1V8) { + if (chip->asic_code) { + retval = rtsx_write_phy_register(chip, 0x08, 0x4C40 | chip->phy_voltage); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + RTSX_WRITE_REG(chip, SD_PAD_CTL, SD_IO_USING_1V8, SD_IO_USING_1V8); + } + } else { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_voltage_switch(struct rtsx_chip *chip) +{ + int retval; + u8 stat; + + RTSX_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, SD_CLK_TOGGLE_EN); + + retval = sd_send_cmd_get_rsp(chip, VOLTAGE_SWITCH, 0, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + udelay(chip->sd_voltage_switch_delay); + + RTSX_READ_REG(chip, SD_BUS_STAT, &stat); + if (stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | + SD_DAT1_STATUS | SD_DAT0_STATUS)) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, SD_BUS_STAT, 0xFF, SD_CLK_FORCE_STOP); + retval = sd_change_bank_voltage(chip, SD_IO_1V8); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + wait_timeout(50); + + RTSX_WRITE_REG(chip, SD_BUS_STAT, 0xFF, SD_CLK_TOGGLE_EN); + wait_timeout(10); + + RTSX_READ_REG(chip, SD_BUS_STAT, &stat); + if ((stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | + SD_DAT1_STATUS | SD_DAT0_STATUS)) != + (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | + SD_DAT1_STATUS | SD_DAT0_STATUS)) { + RTSX_DEBUGP("SD_BUS_STAT: 0x%x\n", stat); + rtsx_write_register(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); + rtsx_write_register(chip, CARD_CLK_EN, 0xFF, 0); + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); + + return STATUS_SUCCESS; +} + +static int sd_reset_dcm(struct rtsx_chip *chip, u8 tune_dir) +{ + if (tune_dir == TUNE_RX) { + RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_RESET | DCM_RX); + RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_RX); + } else { + RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_RESET | DCM_TX); + RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_TX); + } + + return STATUS_SUCCESS; +} + +static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir) +{ + struct sd_info *sd_card = &(chip->sd_card); + u16 SD_VP_CTL, SD_DCMPS_CTL; + u8 val; + int retval; + int ddr_rx = 0; + + RTSX_DEBUGP("sd_change_phase (sample_point = %d, tune_dir = %d)\n", + sample_point, tune_dir); + + if (tune_dir == TUNE_RX) { + SD_VP_CTL = SD_VPRX_CTL; + SD_DCMPS_CTL = SD_DCMPS_RX_CTL; + if (CHK_SD_DDR50(sd_card)) { + ddr_rx = 1; + } + } else { + SD_VP_CTL = SD_VPTX_CTL; + SD_DCMPS_CTL = SD_DCMPS_TX_CTL; + } + + if (chip->asic_code) { + RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, CHANGE_CLK); + RTSX_WRITE_REG(chip, SD_VP_CTL, 0x1F, sample_point); + RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); + RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET); + RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, 0); + } else { +#if CONFIG_RTS_PSTOR_DEBUG + rtsx_read_register(chip, SD_VP_CTL, &val); + RTSX_DEBUGP("SD_VP_CTL: 0x%x\n", val); + rtsx_read_register(chip, SD_DCMPS_CTL, &val); + RTSX_DEBUGP("SD_DCMPS_CTL: 0x%x\n", val); +#endif + + if (ddr_rx) { + RTSX_WRITE_REG(chip, SD_VP_CTL, PHASE_CHANGE, PHASE_CHANGE); + udelay(50); + RTSX_WRITE_REG(chip, SD_VP_CTL, 0xFF, + PHASE_CHANGE | PHASE_NOT_RESET | sample_point); + } else { + RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, CHANGE_CLK); + udelay(50); + RTSX_WRITE_REG(chip, SD_VP_CTL, 0xFF, + PHASE_NOT_RESET | sample_point); + } + udelay(100); + + rtsx_init_cmd(chip); + rtsx_add_cmd(chip, WRITE_REG_CMD, SD_DCMPS_CTL, DCMPS_CHANGE, DCMPS_CHANGE); + rtsx_add_cmd(chip, CHECK_REG_CMD, SD_DCMPS_CTL, DCMPS_CHANGE_DONE, DCMPS_CHANGE_DONE); + retval = rtsx_send_cmd(chip, SD_CARD, 100); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, Fail); + } + + val = *rtsx_get_cmd_data(chip); + if (val & DCMPS_ERROR) { + TRACE_GOTO(chip, Fail); + } + if ((val & DCMPS_CURRENT_PHASE) != sample_point) { + TRACE_GOTO(chip, Fail); + } + RTSX_WRITE_REG(chip, SD_DCMPS_CTL, DCMPS_CHANGE, 0); + if (ddr_rx) { + RTSX_WRITE_REG(chip, SD_VP_CTL, PHASE_CHANGE, 0); + } else { + RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, 0); + } + udelay(50); + } + + RTSX_WRITE_REG(chip, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0); + + return STATUS_SUCCESS; + +Fail: +#if CONFIG_RTS_PSTOR_DEBUG + rtsx_read_register(chip, SD_VP_CTL, &val); + RTSX_DEBUGP("SD_VP_CTL: 0x%x\n", val); + rtsx_read_register(chip, SD_DCMPS_CTL, &val); + RTSX_DEBUGP("SD_DCMPS_CTL: 0x%x\n", val); +#endif + + rtsx_write_register(chip, SD_DCMPS_CTL, DCMPS_CHANGE, 0); + rtsx_write_register(chip, SD_VP_CTL, PHASE_CHANGE, 0); + wait_timeout(10); + sd_reset_dcm(chip, tune_dir); + return STATUS_FAIL; +} + +static int sd_check_spec(struct rtsx_chip *chip, u8 bus_width) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd[5], buf[8]; + + retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + cmd[0] = 0x40 | SEND_SCR; + cmd[1] = 0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + + retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 8, 1, bus_width, buf, 8, 250); + if (retval != STATUS_SUCCESS) { + rtsx_clear_sd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + memcpy(sd_card->raw_scr, buf, 8); + + if ((buf[0] & 0x0F) == 0) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_query_switch_result(struct rtsx_chip *chip, u8 func_group, u8 func_to_switch, + u8 *buf, int buf_len) +{ + u8 support_mask = 0, query_switch = 0, switch_busy = 0; + int support_offset = 0, query_switch_offset = 0, check_busy_offset = 0; + + if (func_group == SD_FUNC_GROUP_1) { + support_offset = FUNCTION_GROUP1_SUPPORT_OFFSET; + query_switch_offset = FUNCTION_GROUP1_QUERY_SWITCH_OFFSET; + check_busy_offset = FUNCTION_GROUP1_CHECK_BUSY_OFFSET; + + switch (func_to_switch) { + case HS_SUPPORT: + support_mask = HS_SUPPORT_MASK; + query_switch = HS_QUERY_SWITCH_OK; + switch_busy = HS_SWITCH_BUSY; + break; + + case SDR50_SUPPORT: + support_mask = SDR50_SUPPORT_MASK; + query_switch = SDR50_QUERY_SWITCH_OK; + switch_busy = SDR50_SWITCH_BUSY; + break; + + case SDR104_SUPPORT: + support_mask = SDR104_SUPPORT_MASK; + query_switch = SDR104_QUERY_SWITCH_OK; + switch_busy = SDR104_SWITCH_BUSY; + break; + + case DDR50_SUPPORT: + support_mask = DDR50_SUPPORT_MASK; + query_switch = DDR50_QUERY_SWITCH_OK; + switch_busy = DDR50_SWITCH_BUSY; + break; + + default: + TRACE_RET(chip, STATUS_FAIL); + } + } else if (func_group == SD_FUNC_GROUP_3) { + support_offset = FUNCTION_GROUP3_SUPPORT_OFFSET; + query_switch_offset = FUNCTION_GROUP3_QUERY_SWITCH_OFFSET; + check_busy_offset = FUNCTION_GROUP3_CHECK_BUSY_OFFSET; + + switch (func_to_switch) { + case DRIVING_TYPE_A: + support_mask = DRIVING_TYPE_A_MASK; + query_switch = TYPE_A_QUERY_SWITCH_OK; + switch_busy = TYPE_A_SWITCH_BUSY; + break; + + case DRIVING_TYPE_C: + support_mask = DRIVING_TYPE_C_MASK; + query_switch = TYPE_C_QUERY_SWITCH_OK; + switch_busy = TYPE_C_SWITCH_BUSY; + break; + + case DRIVING_TYPE_D: + support_mask = DRIVING_TYPE_D_MASK; + query_switch = TYPE_D_QUERY_SWITCH_OK; + switch_busy = TYPE_D_SWITCH_BUSY; + break; + + default: + TRACE_RET(chip, STATUS_FAIL); + } + } else if (func_group == SD_FUNC_GROUP_4) { + support_offset = FUNCTION_GROUP4_SUPPORT_OFFSET; + query_switch_offset = FUNCTION_GROUP4_QUERY_SWITCH_OFFSET; + check_busy_offset = FUNCTION_GROUP4_CHECK_BUSY_OFFSET; + + switch (func_to_switch) { + case CURRENT_LIMIT_400: + support_mask = CURRENT_LIMIT_400_MASK; + query_switch = CURRENT_LIMIT_400_QUERY_SWITCH_OK; + switch_busy = CURRENT_LIMIT_400_SWITCH_BUSY; + break; + + case CURRENT_LIMIT_600: + support_mask = CURRENT_LIMIT_600_MASK; + query_switch = CURRENT_LIMIT_600_QUERY_SWITCH_OK; + switch_busy = CURRENT_LIMIT_600_SWITCH_BUSY; + break; + + case CURRENT_LIMIT_800: + support_mask = CURRENT_LIMIT_800_MASK; + query_switch = CURRENT_LIMIT_800_QUERY_SWITCH_OK; + switch_busy = CURRENT_LIMIT_800_SWITCH_BUSY; + break; + + default: + TRACE_RET(chip, STATUS_FAIL); + } + } else { + TRACE_RET(chip, STATUS_FAIL); + } + + if (func_group == SD_FUNC_GROUP_1) { + if (!(buf[support_offset] & support_mask) || + ((buf[query_switch_offset] & 0x0F) != query_switch)) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + /* Check 'Busy Status' */ + if ((buf[DATA_STRUCTURE_VER_OFFSET] == 0x01) && + ((buf[check_busy_offset] & switch_busy) == switch_busy)) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_check_switch_mode(struct rtsx_chip *chip, u8 mode, + u8 func_group, u8 func_to_switch, u8 bus_width) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd[5], buf[64]; + + RTSX_DEBUGP("sd_check_switch_mode (mode = %d, func_group = %d, func_to_switch = %d)\n", + mode, func_group, func_to_switch); + + cmd[0] = 0x40 | SWITCH; + cmd[1] = mode; + + if (func_group == SD_FUNC_GROUP_1) { + cmd[2] = 0xFF; + cmd[3] = 0xFF; + cmd[4] = 0xF0 + func_to_switch; + } else if (func_group == SD_FUNC_GROUP_3) { + cmd[2] = 0xFF; + cmd[3] = 0xF0 + func_to_switch; + cmd[4] = 0xFF; + } else if (func_group == SD_FUNC_GROUP_4) { + cmd[2] = 0xFF; + cmd[3] = 0x0F + (func_to_switch << 4); + cmd[4] = 0xFF; + } else { + cmd[1] = SD_CHECK_MODE; + cmd[2] = 0xFF; + cmd[3] = 0xFF; + cmd[4] = 0xFF; + } + + retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 64, 1, bus_width, buf, 64, 250); + if (retval != STATUS_SUCCESS) { + rtsx_clear_sd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_DUMP(buf, 64); + + if (func_group == NO_ARGUMENT) { + sd_card->func_group1_mask = buf[0x0D]; + sd_card->func_group2_mask = buf[0x0B]; + sd_card->func_group3_mask = buf[0x09]; + sd_card->func_group4_mask = buf[0x07]; + + RTSX_DEBUGP("func_group1_mask = 0x%02x\n", buf[0x0D]); + RTSX_DEBUGP("func_group2_mask = 0x%02x\n", buf[0x0B]); + RTSX_DEBUGP("func_group3_mask = 0x%02x\n", buf[0x09]); + RTSX_DEBUGP("func_group4_mask = 0x%02x\n", buf[0x07]); + } else { + /* Maximum current consumption, check whether current is acceptable; + * bit[511:496] = 0x0000 means some error happaned. + */ + u16 cc = ((u16)buf[0] << 8) | buf[1]; + RTSX_DEBUGP("Maximum current consumption: %dmA\n", cc); + if ((cc == 0) || (cc > 800)) { + TRACE_RET(chip, STATUS_FAIL); + } + retval = sd_query_switch_result(chip, func_group, func_to_switch, buf, 64); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if ((cc > 400) || (func_to_switch > CURRENT_LIMIT_400)) { + RTSX_WRITE_REG(chip, OCPPARA2, SD_OCP_THD_MASK, chip->sd_800mA_ocp_thd); + RTSX_WRITE_REG(chip, CARD_PWR_CTL, PMOS_STRG_MASK, PMOS_STRG_800mA); + } + } + + return STATUS_SUCCESS; +} + +static u8 downgrade_switch_mode(u8 func_group, u8 func_to_switch) +{ + if (func_group == SD_FUNC_GROUP_1) { + if (func_to_switch > HS_SUPPORT) { + func_to_switch--; + } + } else if (func_group == SD_FUNC_GROUP_4) { + if (func_to_switch > CURRENT_LIMIT_200) { + func_to_switch--; + } + } + + return func_to_switch; +} + +static int sd_check_switch(struct rtsx_chip *chip, + u8 func_group, u8 func_to_switch, u8 bus_width) +{ + int retval; + int i; + int switch_good = 0; + + for (i = 0; i < 3; i++) { + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_check_switch_mode(chip, SD_CHECK_MODE, func_group, + func_to_switch, bus_width); + if (retval == STATUS_SUCCESS) { + u8 stat; + + retval = sd_check_switch_mode(chip, SD_SWITCH_MODE, + func_group, func_to_switch, bus_width); + if (retval == STATUS_SUCCESS) { + switch_good = 1; + break; + } + + RTSX_READ_REG(chip, SD_STAT1, &stat); + if (stat & SD_CRC16_ERR) { + RTSX_DEBUGP("SD CRC16 error when switching mode\n"); + TRACE_RET(chip, STATUS_FAIL); + } + } + + func_to_switch = downgrade_switch_mode(func_group, func_to_switch); + + wait_timeout(20); + } + + if (!switch_good) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i; + u8 func_to_switch = 0; + + /* Get supported functions */ + retval = sd_check_switch_mode(chip, SD_CHECK_MODE, + NO_ARGUMENT, NO_ARGUMENT, bus_width); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + sd_card->func_group1_mask &= ~(sd_card->sd_switch_fail); + + for (i = 0; i < 4; i++) { + switch ((u8)(chip->sd_speed_prior >> (i*8))) { + case SDR104_SUPPORT: + if ((sd_card->func_group1_mask & SDR104_SUPPORT_MASK) + && chip->sdr104_en) { + func_to_switch = SDR104_SUPPORT; + } + break; + + case DDR50_SUPPORT: + if ((sd_card->func_group1_mask & DDR50_SUPPORT_MASK) + && chip->ddr50_en) { + func_to_switch = DDR50_SUPPORT; + } + break; + + case SDR50_SUPPORT: + if ((sd_card->func_group1_mask & SDR50_SUPPORT_MASK) + && chip->sdr50_en) { + func_to_switch = SDR50_SUPPORT; + } + break; + + case HS_SUPPORT: + if (sd_card->func_group1_mask & HS_SUPPORT_MASK) { + func_to_switch = HS_SUPPORT; + } + break; + + default: + continue; + } + + + if (func_to_switch) { + break; + } + } + RTSX_DEBUGP("SD_FUNC_GROUP_1: func_to_switch = 0x%02x", func_to_switch); + +#ifdef SUPPORT_SD_LOCK + if ((sd_card->sd_lock_status & SD_SDR_RST) + && (DDR50_SUPPORT == func_to_switch) + && (sd_card->func_group1_mask & SDR50_SUPPORT_MASK)) { + func_to_switch = SDR50_SUPPORT; + RTSX_DEBUGP("Using SDR50 instead of DDR50 for SD Lock\n"); + } +#endif + + if (func_to_switch) { + retval = sd_check_switch(chip, SD_FUNC_GROUP_1, func_to_switch, bus_width); + if (retval != STATUS_SUCCESS) { + if (func_to_switch == SDR104_SUPPORT) { + sd_card->sd_switch_fail = SDR104_SUPPORT_MASK; + } else if (func_to_switch == DDR50_SUPPORT) { + sd_card->sd_switch_fail = + SDR104_SUPPORT_MASK | DDR50_SUPPORT_MASK; + } else if (func_to_switch == SDR50_SUPPORT) { + sd_card->sd_switch_fail = + SDR104_SUPPORT_MASK | DDR50_SUPPORT_MASK | + SDR50_SUPPORT_MASK; + } + TRACE_RET(chip, STATUS_FAIL); + } + + if (func_to_switch == SDR104_SUPPORT) { + SET_SD_SDR104(sd_card); + } else if (func_to_switch == DDR50_SUPPORT) { + SET_SD_DDR50(sd_card); + } else if (func_to_switch == SDR50_SUPPORT) { + SET_SD_SDR50(sd_card); + } else { + SET_SD_HS(sd_card); + } + } + + if (CHK_SD_DDR50(sd_card)) { + RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, 0x06, 0x04); + retval = sd_set_sample_push_timing(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + func_to_switch = 0xFF; + + for (i = 0; i < 4; i++) { + switch ((u8)(chip->sd_current_prior >> (i*8))) { + case CURRENT_LIMIT_800: + if (sd_card->func_group4_mask & CURRENT_LIMIT_800_MASK) { + func_to_switch = CURRENT_LIMIT_800; + } + break; + + case CURRENT_LIMIT_600: + if (sd_card->func_group4_mask & CURRENT_LIMIT_600_MASK) { + func_to_switch = CURRENT_LIMIT_600; + } + break; + + case CURRENT_LIMIT_400: + if (sd_card->func_group4_mask & CURRENT_LIMIT_400_MASK) { + func_to_switch = CURRENT_LIMIT_400; + } + break; + + case CURRENT_LIMIT_200: + if (sd_card->func_group4_mask & CURRENT_LIMIT_200_MASK) { + func_to_switch = CURRENT_LIMIT_200; + } + break; + + default: + continue; + } + + if (func_to_switch != 0xFF) { + break; + } + } + + RTSX_DEBUGP("SD_FUNC_GROUP_4: func_to_switch = 0x%02x", func_to_switch); + + if (func_to_switch <= CURRENT_LIMIT_800) { + retval = sd_check_switch(chip, SD_FUNC_GROUP_4, func_to_switch, bus_width); + if (retval != STATUS_SUCCESS) { + if (sd_check_err_code(chip, SD_NO_CARD)) { + TRACE_RET(chip, STATUS_FAIL); + } + } + RTSX_DEBUGP("Switch current limit finished! (%d)\n", retval); + } + + if (CHK_SD_DDR50(sd_card)) { + RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, 0x06, 0); + } + + return STATUS_SUCCESS; +} + +static int sd_wait_data_idle(struct rtsx_chip *chip) +{ + int retval = STATUS_TIMEDOUT; + int i; + u8 val = 0; + + for (i = 0; i < 100; i++) { + RTSX_READ_REG(chip, SD_DATA_STATE, &val); + if (val & SD_DATA_IDLE) { + retval = STATUS_SUCCESS; + break; + } + udelay(100); + } + RTSX_DEBUGP("SD_DATA_STATE: 0x%02x\n", val); + + return retval; +} + +static int sd_sdr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) +{ + int retval; + u8 cmd[5]; + + retval = sd_change_phase(chip, sample_point, TUNE_RX); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + cmd[0] = 0x40 | SEND_TUNING_PATTERN; + cmd[1] = 0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + + retval = sd_read_data(chip, SD_TM_AUTO_TUNING, + cmd, 5, 0x40, 1, SD_BUS_WIDTH_4, NULL, 0, 100); + if (retval != STATUS_SUCCESS) { + (void)sd_wait_data_idle(chip); + + rtsx_clear_sd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_ddr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd[5]; + + retval = sd_change_phase(chip, sample_point, TUNE_RX); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_DEBUGP("sd ddr tuning rx\n"); + + retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + cmd[0] = 0x40 | SD_STATUS; + cmd[1] = 0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + + retval = sd_read_data(chip, SD_TM_NORMAL_READ, + cmd, 5, 64, 1, SD_BUS_WIDTH_4, NULL, 0, 100); + if (retval != STATUS_SUCCESS) { + (void)sd_wait_data_idle(chip); + + rtsx_clear_sd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int mmc_ddr_tunning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd[5], bus_width; + + if (CHK_MMC_8BIT(sd_card)) { + bus_width = SD_BUS_WIDTH_8; + } else if (CHK_MMC_4BIT(sd_card)) { + bus_width = SD_BUS_WIDTH_4; + } else { + bus_width = SD_BUS_WIDTH_1; + } + + retval = sd_change_phase(chip, sample_point, TUNE_RX); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_DEBUGP("mmc ddr tuning rx\n"); + + cmd[0] = 0x40 | SEND_EXT_CSD; + cmd[1] = 0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + + retval = sd_read_data(chip, SD_TM_NORMAL_READ, + cmd, 5, 0x200, 1, bus_width, NULL, 0, 100); + if (retval != STATUS_SUCCESS) { + (void)sd_wait_data_idle(chip); + + rtsx_clear_sd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_sdr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + retval = sd_change_phase(chip, sample_point, TUNE_TX); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, SD_RSP_80CLK_TIMEOUT_EN); + + retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + if (sd_check_err_code(chip, SD_RSP_TIMEOUT)) { + rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); + TRACE_RET(chip, STATUS_FAIL); + } + } + + RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); + + return STATUS_SUCCESS; +} + +static int sd_ddr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd[5], bus_width; + + retval = sd_change_phase(chip, sample_point, TUNE_TX); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (CHK_SD(sd_card)) { + bus_width = SD_BUS_WIDTH_4; + } else { + if (CHK_MMC_8BIT(sd_card)) { + bus_width = SD_BUS_WIDTH_8; + } else if (CHK_MMC_4BIT(sd_card)) { + bus_width = SD_BUS_WIDTH_4; + } else { + bus_width = SD_BUS_WIDTH_1; + } + } + + retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, SD_RSP_80CLK_TIMEOUT_EN); + + cmd[0] = 0x40 | PROGRAM_CSD; + cmd[1] = 0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + + retval = sd_write_data(chip, SD_TM_AUTO_WRITE_2, + cmd, 5, 16, 1, bus_width, sd_card->raw_csd, 16, 100); + if (retval != STATUS_SUCCESS) { + rtsx_clear_sd_error(chip); + rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); + + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); + + return STATUS_SUCCESS; +} + +static u8 sd_search_final_phase(struct rtsx_chip *chip, u32 phase_map, u8 tune_dir) +{ + struct sd_info *sd_card = &(chip->sd_card); + struct timing_phase_path path[MAX_PHASE + 1]; + int i, j, cont_path_cnt; + int new_block, max_len, final_path_idx; + u8 final_phase = 0xFF; + + if (phase_map == 0xFFFFFFFF) { + if (tune_dir == TUNE_RX) { + final_phase = (u8)chip->sd_default_rx_phase; + } else { + final_phase = (u8)chip->sd_default_tx_phase; + } + + goto Search_Finish; + } + + cont_path_cnt = 0; + new_block = 1; + j = 0; + for (i = 0; i < MAX_PHASE + 1; i++) { + if (phase_map & (1 << i)) { + if (new_block) { + new_block = 0; + j = cont_path_cnt++; + path[j].start = i; + path[j].end = i; + } else { + path[j].end = i; + } + } else { + new_block = 1; + if (cont_path_cnt) { + int idx = cont_path_cnt - 1; + path[idx].len = path[idx].end - path[idx].start + 1; + path[idx].mid = path[idx].start + path[idx].len / 2; + } + } + } + + if (cont_path_cnt == 0) { + RTSX_DEBUGP("No continuous phase path\n"); + goto Search_Finish; + } else { + int idx = cont_path_cnt - 1; + path[idx].len = path[idx].end - path[idx].start + 1; + path[idx].mid = path[idx].start + path[idx].len / 2; + } + + if ((path[0].start == 0) && (path[cont_path_cnt - 1].end == MAX_PHASE)) { + path[0].start = path[cont_path_cnt - 1].start - MAX_PHASE - 1; + path[0].len += path[cont_path_cnt - 1].len; + path[0].mid = path[0].start + path[0].len / 2; + if (path[0].mid < 0) { + path[0].mid += MAX_PHASE + 1; + } + cont_path_cnt--; + } + + max_len = 0; + final_phase = 0; + final_path_idx = 0; + for (i = 0; i < cont_path_cnt; i++) { + if (path[i].len > max_len) { + max_len = path[i].len; + final_phase = (u8)path[i].mid; + final_path_idx = i; + } + + RTSX_DEBUGP("path[%d].start = %d\n", i, path[i].start); + RTSX_DEBUGP("path[%d].end = %d\n", i, path[i].end); + RTSX_DEBUGP("path[%d].len = %d\n", i, path[i].len); + RTSX_DEBUGP("path[%d].mid = %d\n", i, path[i].mid); + RTSX_DEBUGP("\n"); + } + + if (tune_dir == TUNE_TX) { + if (CHK_SD_SDR104(sd_card)) { + if (max_len > 15) { + int temp_mid = (max_len - 16) / 2; + int temp_final_phase = + path[final_path_idx].end - (max_len - (6 + temp_mid)); + + if (temp_final_phase < 0) { + final_phase = (u8)(temp_final_phase + MAX_PHASE + 1); + } else { + final_phase = (u8)temp_final_phase; + } + } + } else if (CHK_SD_SDR50(sd_card)) { + if (max_len > 12) { + int temp_mid = (max_len - 13) / 2; + int temp_final_phase = + path[final_path_idx].end - (max_len - (3 + temp_mid)); + + if (temp_final_phase < 0) { + final_phase = (u8)(temp_final_phase + MAX_PHASE + 1); + } else { + final_phase = (u8)temp_final_phase; + } + } + } + } + +Search_Finish: + RTSX_DEBUGP("Final choosen phase: %d\n", final_phase); + return final_phase; +} + +static int sd_tuning_rx(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i, j; + u32 raw_phase_map[3], phase_map; + u8 final_phase; + int (*tuning_cmd)(struct rtsx_chip *chip, u8 sample_point); + + if (CHK_SD(sd_card)) { + if (CHK_SD_DDR50(sd_card)) { + tuning_cmd = sd_ddr_tuning_rx_cmd; + } else { + tuning_cmd = sd_sdr_tuning_rx_cmd; + } + } else { + if (CHK_MMC_DDR52(sd_card)) { + tuning_cmd = mmc_ddr_tunning_rx_cmd; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } + + for (i = 0; i < 3; i++) { + raw_phase_map[i] = 0; + for (j = MAX_PHASE; j >= 0; j--) { + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = tuning_cmd(chip, (u8)j); + if (retval == STATUS_SUCCESS) { + raw_phase_map[i] |= 1 << j; + } + } + } + + phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2]; + for (i = 0; i < 3; i++) { + RTSX_DEBUGP("RX raw_phase_map[%d] = 0x%08x\n", i, raw_phase_map[i]); + } + RTSX_DEBUGP("RX phase_map = 0x%08x\n", phase_map); + + final_phase = sd_search_final_phase(chip, phase_map, TUNE_RX); + if (final_phase == 0xFF) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_change_phase(chip, final_phase, TUNE_RX); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_ddr_pre_tuning_tx(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i; + u32 phase_map; + u8 final_phase; + + RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, SD_RSP_80CLK_TIMEOUT_EN); + + phase_map = 0; + for (i = MAX_PHASE; i >= 0; i--) { + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_NO_CARD); + rtsx_write_register(chip, SD_CFG3, + SD_RSP_80CLK_TIMEOUT_EN, 0); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_change_phase(chip, (u8)i, TUNE_TX); + if (retval != STATUS_SUCCESS) { + continue; + } + + retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + if ((retval == STATUS_SUCCESS) || !sd_check_err_code(chip, SD_RSP_TIMEOUT)) { + phase_map |= 1 << i; + } + } + + RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); + + RTSX_DEBUGP("DDR TX pre tune phase_map = 0x%08x\n", phase_map); + + final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX); + if (final_phase == 0xFF) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_change_phase(chip, final_phase, TUNE_TX); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_DEBUGP("DDR TX pre tune phase: %d\n", (int)final_phase); + + return STATUS_SUCCESS; +} + +static int sd_tuning_tx(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i, j; + u32 raw_phase_map[3], phase_map; + u8 final_phase; + int (*tuning_cmd)(struct rtsx_chip *chip, u8 sample_point); + + if (CHK_SD(sd_card)) { + if (CHK_SD_DDR50(sd_card)) { + tuning_cmd = sd_ddr_tuning_tx_cmd; + } else { + tuning_cmd = sd_sdr_tuning_tx_cmd; + } + } else { + if (CHK_MMC_DDR52(sd_card)) { + tuning_cmd = sd_ddr_tuning_tx_cmd; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } + + for (i = 0; i < 3; i++) { + raw_phase_map[i] = 0; + for (j = MAX_PHASE; j >= 0; j--) { + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_NO_CARD); + rtsx_write_register(chip, SD_CFG3, + SD_RSP_80CLK_TIMEOUT_EN, 0); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = tuning_cmd(chip, (u8)j); + if (retval == STATUS_SUCCESS) { + raw_phase_map[i] |= 1 << j; + } + } + } + + phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2]; + for (i = 0; i < 3; i++) { + RTSX_DEBUGP("TX raw_phase_map[%d] = 0x%08x\n", i, raw_phase_map[i]); + } + RTSX_DEBUGP("TX phase_map = 0x%08x\n", phase_map); + + final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX); + if (final_phase == 0xFF) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_change_phase(chip, final_phase, TUNE_TX); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_sdr_tuning(struct rtsx_chip *chip) +{ + int retval; + + retval = sd_tuning_tx(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_tuning_rx(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_ddr_tuning(struct rtsx_chip *chip) +{ + int retval; + + if (!(chip->sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) { + retval = sd_ddr_pre_tuning_tx(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + retval = sd_change_phase(chip, (u8)chip->sd_ddr_tx_phase, TUNE_TX); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = sd_tuning_rx(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (!(chip->sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) { + retval = sd_tuning_tx(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + +static int mmc_ddr_tuning(struct rtsx_chip *chip) +{ + int retval; + + if (!(chip->sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) { + retval = sd_ddr_pre_tuning_tx(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + retval = sd_change_phase(chip, (u8)chip->mmc_ddr_tx_phase, TUNE_TX); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = sd_tuning_rx(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (!(chip->sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) { + retval = sd_tuning_tx(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + +int sd_switch_clock(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int re_tuning = 0; + + retval = select_card(chip, SD_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (CHECK_PID(chip, 0x5209) && + (CHK_SD30_SPEED(sd_card) || CHK_MMC_DDR52(sd_card))) { + if (sd_card->need_retune && (sd_card->sd_clock != chip->cur_clk)) { + re_tuning = 1; + sd_card->need_retune = 0; + } + } + + retval = switch_clock(chip, sd_card->sd_clock); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (re_tuning) { + if (CHK_SD(sd_card)) { + if (CHK_SD_DDR50(sd_card)) { + retval = sd_ddr_tuning(chip); + } else { + retval = sd_sdr_tuning(chip); + } + } else { + if (CHK_MMC_DDR52(sd_card)) { + retval = mmc_ddr_tuning(chip); + } + } + + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + +static int sd_prepare_reset(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + if (chip->asic_code) { + sd_card->sd_clock = 29; + } else { + sd_card->sd_clock = CLK_30; + } + + chip->sd_io = 0; + + retval = sd_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, retval); + } + + if (CHECK_PID(chip, 0x5209)) { + RTSX_WRITE_REG(chip, REG_SD_CFG1, 0xFF, + SD_CLK_DIVIDE_128 | SD_20_MODE | SD_BUS_WIDTH_1); + RTSX_WRITE_REG(chip, SD_SAMPLE_POINT_CTL, 0xFF, SD20_RX_POS_EDGE); + RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, 0xFF, 0); + } else { + RTSX_WRITE_REG(chip, REG_SD_CFG1, 0xFF, 0x40); + } + + RTSX_WRITE_REG(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR); + + retval = select_card(chip, SD_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_pull_ctl_disable(struct rtsx_chip *chip) +{ + if (CHECK_PID(chip, 0x5209)) { + RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0xD5); + } else if (CHECK_PID(chip, 0x5208)) { + RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, + XD_D3_PD | SD_D7_PD | SD_CLK_PD | SD_D5_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, + SD_D6_PD | SD_D0_PD | SD_D1_PD | XD_D5_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, + SD_D4_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU); + RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, + XD_RDY_PD | SD_D3_PD | SD_D2_PD | XD_ALE_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, + MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF, MS_D5_PD | MS_D4_PD); + } else if (CHECK_PID(chip, 0x5288)) { + if (CHECK_BARO_PKG(chip, QFN)) { + RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0x4B); + RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x69); + } + } + + return STATUS_SUCCESS; +} + +int sd_pull_ctl_enable(struct rtsx_chip *chip) +{ + int retval; + + rtsx_init_cmd(chip); + + if (CHECK_PID(chip, 0x5209)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0xAA); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0xAA); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0xE9); + } else if (CHECK_PID(chip, 0x5208)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, + XD_D3_PD | SD_DAT7_PU | SD_CLK_NP | SD_D5_PU); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, + SD_D6_PU | SD_D0_PU | SD_D1_PU | XD_D5_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, + SD_D4_PU | XD_CE_PD | XD_CLE_PD | XD_CD_PU); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, + XD_RDY_PD | SD_D3_PU | SD_D2_PU | XD_ALE_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, + MS_INS_PU | SD_WP_PU | SD_CD_PU | SD_CMD_PU); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, MS_D5_PD | MS_D4_PD); + } else if (CHECK_PID(chip, 0x5288)) { + if (CHECK_BARO_PKG(chip, QFN)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0xA8); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x5A); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0xAA); + } + } + + retval = rtsx_send_cmd(chip, SD_CARD, 100); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_init_power(struct rtsx_chip *chip) +{ + int retval; + + if (CHECK_PID(chip, 0x5209)) { + RTSX_WRITE_REG(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_OFF); + } + + retval = sd_power_off_card3v3(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (!chip->ft2_fast_mode) { + wait_timeout(250); + } + + retval = enable_card_clock(chip, SD_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (chip->asic_code) { + retval = sd_pull_ctl_enable(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + RTSX_WRITE_REG(chip, FPGA_PULL_CTL, FPGA_SD_PULL_CTL_BIT | 0x20, 0); + } + + if (chip->ft2_fast_mode) { + if (CHECK_PID(chip, 0x5209)) { + RTSX_WRITE_REG(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON); + } + } else { + retval = card_power_on(chip, SD_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + wait_timeout(260); + +#ifdef SUPPORT_OCP + if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { + RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", chip->ocp_stat); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + } + + RTSX_WRITE_REG(chip, CARD_OE, SD_OUTPUT_EN, SD_OUTPUT_EN); + + return STATUS_SUCCESS; +} + +static int sd_dummy_clock(struct rtsx_chip *chip) +{ + if (CHECK_PID(chip, 0x5209)) { + RTSX_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN, SD_CLK_TOGGLE_EN); + wait_timeout(5); + RTSX_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN, 0x00); + } else { + RTSX_WRITE_REG(chip, REG_SD_CFG3, 0x01, 0x01); + wait_timeout(5); + RTSX_WRITE_REG(chip, REG_SD_CFG3, 0x01, 0); + } + + return STATUS_SUCCESS; +} + +static int sd_read_lba0(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd[5], bus_width; + + cmd[0] = 0x40 | READ_SINGLE_BLOCK; + cmd[1] = 0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + + if (CHK_SD(sd_card)) { + bus_width = SD_BUS_WIDTH_4; + } else { + if (CHK_MMC_8BIT(sd_card)) { + bus_width = SD_BUS_WIDTH_8; + } else if (CHK_MMC_4BIT(sd_card)) { + bus_width = SD_BUS_WIDTH_4; + } else { + bus_width = SD_BUS_WIDTH_1; + } + } + + retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, + 5, 512, 1, bus_width, NULL, 0, 100); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_check_wp_state(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u32 val; + u16 sd_card_type; + u8 cmd[5], buf[64]; + + retval = sd_send_cmd_get_rsp(chip, APP_CMD, + sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + cmd[0] = 0x40 | SD_STATUS; + cmd[1] = 0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + + retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 64, 1, SD_BUS_WIDTH_4, buf, 64, 250); + if (retval != STATUS_SUCCESS) { + rtsx_clear_sd_error(chip); + + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_DEBUGP("ACMD13:\n"); + RTSX_DUMP(buf, 64); + + sd_card_type = ((u16)buf[2] << 8) | buf[3]; + RTSX_DEBUGP("sd_card_type = 0x%04x\n", sd_card_type); + if ((sd_card_type == 0x0001) || (sd_card_type == 0x0002)) { + /* ROM card or OTP */ + chip->card_wp |= SD_CARD; + } + + /* Check SD Machanical Write-Protect Switch */ + val = rtsx_readl(chip, RTSX_BIPR); + if (val & SD_WRITE_PROTECT) { + chip->card_wp |= SD_CARD; + } + + return STATUS_SUCCESS; +} + +static int reset_sd(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval, i = 0, j = 0, k = 0, hi_cap_flow = 0; + int sd_dont_switch = 0; + int support_1v8 = 0; + int try_sdio = 1; + u8 rsp[16]; + u8 switch_bus_width; + u32 voltage = 0; + int sd20_mode = 0; + + SET_SD(sd_card); + +Switch_Fail: + + i = 0; + j = 0; + k = 0; + hi_cap_flow = 0; + +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) + goto SD_UNLOCK_ENTRY; +#endif + + retval = sd_prepare_reset(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_dummy_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip) && try_sdio) { + int rty_cnt = 0; + + for (; rty_cnt < chip->sdio_retry_cnt; rty_cnt++) { + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_send_cmd_get_rsp(chip, IO_SEND_OP_COND, 0, SD_RSP_TYPE_R4, rsp, 5); + if (retval == STATUS_SUCCESS) { + int func_num = (rsp[1] >> 4) && 0x07; + if (func_num) { + RTSX_DEBUGP("SD_IO card (Function number: %d)!\n", func_num); + chip->sd_io = 1; + TRACE_RET(chip, STATUS_FAIL); + } + + break; + } + + sd_init_power(chip); + + sd_dummy_clock(chip); + } + + RTSX_DEBUGP("Normal card!\n"); + } + + /* Start Initialization Process of SD Card */ +RTY_SD_RST: + retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + wait_timeout(20); + + retval = sd_send_cmd_get_rsp(chip, SEND_IF_COND, 0x000001AA, SD_RSP_TYPE_R7, rsp, 5); + if (retval == STATUS_SUCCESS) { + if ((rsp[4] == 0xAA) && ((rsp[3] & 0x0f) == 0x01)) { + hi_cap_flow = 1; + if (CHECK_PID(chip, 0x5209)) { + if (sd20_mode) { + voltage = SUPPORT_VOLTAGE | + SUPPORT_HIGH_AND_EXTENDED_CAPACITY; + } else { + voltage = SUPPORT_VOLTAGE | + SUPPORT_HIGH_AND_EXTENDED_CAPACITY | + SUPPORT_MAX_POWER_PERMANCE | SUPPORT_1V8; + } + } else { + voltage = SUPPORT_VOLTAGE | 0x40000000; + } + } + } + + if (!hi_cap_flow) { + voltage = SUPPORT_VOLTAGE; + + retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + wait_timeout(20); + } + + do { + retval = sd_send_cmd_get_rsp(chip, APP_CMD, 0, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + j++; + if (j < 3) { + goto RTY_SD_RST; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = sd_send_cmd_get_rsp(chip, SD_APP_OP_COND, voltage, SD_RSP_TYPE_R3, rsp, 5); + if (retval != STATUS_SUCCESS) { + k++; + if (k < 3) { + goto RTY_SD_RST; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } + + i++; + wait_timeout(20); + } while (!(rsp[1] & 0x80) && (i < 255)); + + if (i == 255) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (hi_cap_flow) { + if (rsp[1] & 0x40) { + SET_SD_HCXC(sd_card); + } else { + CLR_SD_HCXC(sd_card); + } + if (CHECK_PID(chip, 0x5209) && CHK_SD_HCXC(sd_card) && !sd20_mode) { + support_1v8 = (rsp[1] & 0x01) ? 1 : 0; + } else { + support_1v8 = 0; + } + } else { + CLR_SD_HCXC(sd_card); + support_1v8 = 0; + } + RTSX_DEBUGP("support_1v8 = %d\n", support_1v8); + + if (support_1v8) { + retval = sd_voltage_switch(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + for (i = 0; i < 3; i++) { + retval = sd_send_cmd_get_rsp(chip, SEND_RELATIVE_ADDR, 0, SD_RSP_TYPE_R6, rsp, 5); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + sd_card->sd_addr = (u32)rsp[1] << 24; + sd_card->sd_addr += (u32)rsp[2] << 16; + + if (sd_card->sd_addr) { + break; + } + } + + retval = sd_check_csd(chip, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_select_card(chip, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + +#ifdef SUPPORT_SD_LOCK +SD_UNLOCK_ENTRY: + retval = sd_update_lock_status(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (sd_card->sd_lock_status & SD_LOCKED) { + sd_card->sd_lock_status |= (SD_LOCK_1BIT_MODE | SD_PWD_EXIST); + return STATUS_SUCCESS; + } else if (!(sd_card->sd_lock_status & SD_UNLOCK_POW_ON)) { + sd_card->sd_lock_status &= ~SD_PWD_EXIST; + } +#endif + + retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + retval = sd_send_cmd_get_rsp(chip, SET_CLR_CARD_DETECT, 0, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (support_1v8) { + retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + retval = sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + switch_bus_width = SD_BUS_WIDTH_4; + } else { + switch_bus_width = SD_BUS_WIDTH_1; + } + + retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (!(sd_card->raw_csd[4] & 0x40)) + sd_dont_switch = 1; + + if (!sd_dont_switch) { + retval = sd_check_spec(chip, switch_bus_width); + if (retval == STATUS_SUCCESS) { + retval = sd_switch_function(chip, switch_bus_width); + if (retval != STATUS_SUCCESS) { + if (CHECK_PID(chip, 0x5209)) { + sd_change_bank_voltage(chip, SD_IO_3V3); + } + sd_init_power(chip); + sd_dont_switch = 1; + try_sdio = 0; + + goto Switch_Fail; + } + } else { + if (support_1v8) { + if (CHECK_PID(chip, 0x5209)) { + sd_change_bank_voltage(chip, SD_IO_3V3); + } + sd_init_power(chip); + sd_dont_switch = 1; + try_sdio = 0; + + goto Switch_Fail; + } + } + } + + if (!support_1v8) { + retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + retval = sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; +#endif + + if (CHK_SD30_SPEED(sd_card)) { + int read_lba0 = 1; + + RTSX_WRITE_REG(chip, SD30_DRIVE_SEL, 0x07, chip->sd30_drive_sel_1v8); + + retval = sd_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (CHK_SD_DDR50(sd_card)) { + retval = sd_ddr_tuning(chip); + } else { + retval = sd_sdr_tuning(chip); + } + + if (retval != STATUS_SUCCESS) { + if (sd20_mode) { + TRACE_RET(chip, STATUS_FAIL); + } else { + retval = sd_init_power(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + try_sdio = 0; + sd20_mode = 1; + goto Switch_Fail; + } + } + + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); + + if (CHK_SD_DDR50(sd_card)) { + retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); + if (retval != STATUS_SUCCESS) { + read_lba0 = 0; + } + } + + if (read_lba0) { + retval = sd_read_lba0(chip); + if (retval != STATUS_SUCCESS) { + if (sd20_mode) { + TRACE_RET(chip, STATUS_FAIL); + } else { + retval = sd_init_power(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + try_sdio = 0; + sd20_mode = 1; + goto Switch_Fail; + } + } + } + } + + retval = sd_check_wp_state(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; + +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) { + RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_H, 0xFF, 0x02); + RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_L, 0xFF, 0x00); + } +#endif + + return STATUS_SUCCESS; +} + + +static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 buf[8] = {0}, bus_width, *ptr; + u16 byte_cnt; + int len; + + retval = sd_send_cmd_get_rsp(chip, BUSTEST_W, 0, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (width == MMC_8BIT_BUS) { + buf[0] = 0x55; + buf[1] = 0xAA; + len = 8; + byte_cnt = 8; + bus_width = SD_BUS_WIDTH_8; + } else { + buf[0] = 0x5A; + len = 4; + byte_cnt = 4; + bus_width = SD_BUS_WIDTH_4; + } + + if (!CHECK_PID(chip, 0x5209)) { + RTSX_WRITE_REG(chip, REG_SD_CFG3, 0x02, 0x02); + } + + retval = sd_write_data(chip, SD_TM_AUTO_WRITE_3, + NULL, 0, byte_cnt, 1, bus_width, buf, len, 100); + if (retval != STATUS_SUCCESS) { + if (CHECK_PID(chip, 0x5209)) { + u8 val1 = 0, val2 = 0; + rtsx_read_register(chip, REG_SD_STAT1, &val1); + rtsx_read_register(chip, REG_SD_STAT2, &val2); + rtsx_clear_sd_error(chip); + if ((val1 & 0xE0) || val2) { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + rtsx_clear_sd_error(chip); + rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0); + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (!CHECK_PID(chip, 0x5209)) { + RTSX_WRITE_REG(chip, REG_SD_CFG3, 0x02, 0); + } + + RTSX_DEBUGP("SD/MMC CMD %d\n", BUSTEST_R); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | BUSTEST_R); + + if (width == MMC_8BIT_BUS) { + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x08); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x04); + } + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, 1); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, 0); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, + SD_CALCULATE_CRC7 | SD_NO_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | + SD_CHECK_CRC7 | SD_RSP_LEN_6); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, SD_TM_NORMAL_READ | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); + + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2, 0, 0); + if (width == MMC_8BIT_BUS) { + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 1, 0, 0); + } + + retval = rtsx_send_cmd(chip, SD_CARD, 100); + if (retval < 0) { + rtsx_clear_sd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + ptr = rtsx_get_cmd_data(chip) + 1; + + if (width == MMC_8BIT_BUS) { + RTSX_DEBUGP("BUSTEST_R [8bits]: 0x%02x 0x%02x\n", ptr[0], ptr[1]); + if ((ptr[0] == 0xAA) && (ptr[1] == 0x55)) { + u8 rsp[5]; + u32 arg; + + if (CHK_MMC_DDR52(sd_card)) { + arg = 0x03B70600; + } else { + arg = 0x03B70200; + } + retval = sd_send_cmd_get_rsp(chip, SWITCH, arg, SD_RSP_TYPE_R1b, rsp, 5); + if ((retval == STATUS_SUCCESS) && !(rsp[4] & MMC_SWITCH_ERR)) { + return STATUS_SUCCESS; + } + } + } else { + RTSX_DEBUGP("BUSTEST_R [4bits]: 0x%02x\n", ptr[0]); + if (ptr[0] == 0xA5) { + u8 rsp[5]; + u32 arg; + + if (CHK_MMC_DDR52(sd_card)) { + arg = 0x03B70500; + } else { + arg = 0x03B70100; + } + retval = sd_send_cmd_get_rsp(chip, SWITCH, arg, SD_RSP_TYPE_R1b, rsp, 5); + if ((retval == STATUS_SUCCESS) && !(rsp[4] & MMC_SWITCH_ERR)) { + return STATUS_SUCCESS; + } + } + } + + TRACE_RET(chip, STATUS_FAIL); +} + + +static int mmc_switch_timing_bus(struct rtsx_chip *chip, int switch_ddr) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 *ptr, card_type, card_type_mask = 0; + + CLR_MMC_HS(sd_card); + + RTSX_DEBUGP("SD/MMC CMD %d\n", SEND_EXT_CSD); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | SEND_EXT_CSD); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, 0); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 2); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, 1); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, 0); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, + SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | + SD_CHECK_CRC7 | SD_RSP_LEN_6); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, SD_TM_NORMAL_READ | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); + + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 196, 0xFF, 0); + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 212, 0xFF, 0); + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 213, 0xFF, 0); + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 214, 0xFF, 0); + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 215, 0xFF, 0); + + retval = rtsx_send_cmd(chip, SD_CARD, 1000); + if (retval < 0) { + if (retval == -ETIMEDOUT) { + rtsx_clear_sd_error(chip); + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + } + TRACE_RET(chip, STATUS_FAIL); + } + + ptr = rtsx_get_cmd_data(chip); + if (ptr[0] & SD_TRANSFER_ERR) { + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); + TRACE_RET(chip, STATUS_FAIL); + } + + if (CHK_MMC_SECTOR_MODE(sd_card)) { + sd_card->capacity = ((u32)ptr[5] << 24) | ((u32)ptr[4] << 16) | + ((u32)ptr[3] << 8) | ((u32)ptr[2]); + } + + if (CHECK_PID(chip, 0x5209)) { +#ifdef SUPPORT_SD_LOCK + if (!(sd_card->sd_lock_status & SD_SDR_RST) && + (chip->sd_ctl & SUPPORT_MMC_DDR_MODE)) { + card_type_mask = 0x07; + } else { + card_type_mask = 0x03; + } +#else + if (chip->sd_ctl & SUPPORT_MMC_DDR_MODE) { + card_type_mask = 0x07; + } else { + card_type_mask = 0x03; + } +#endif + } else { + card_type_mask = 0x03; + } + card_type = ptr[1] & card_type_mask; + if (card_type) { + u8 rsp[5]; + + if (card_type & 0x04) { + if (switch_ddr) { + SET_MMC_DDR52(sd_card); + } else { + SET_MMC_52M(sd_card); + } + } else if (card_type & 0x02) { + SET_MMC_52M(sd_card); + } else { + SET_MMC_26M(sd_card); + } + + retval = sd_send_cmd_get_rsp(chip, SWITCH, + 0x03B90100, SD_RSP_TYPE_R1b, rsp, 5); + if ((retval != STATUS_SUCCESS) || (rsp[4] & MMC_SWITCH_ERR)) { + CLR_MMC_HS(sd_card); + } + } + + sd_choose_proper_clock(chip); + retval = switch_clock(chip, sd_card->sd_clock); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (mmc_test_switch_bus(chip, MMC_8BIT_BUS) == STATUS_SUCCESS) { + SET_MMC_8BIT(sd_card); + chip->card_bus_width[chip->card2lun[SD_CARD]] = 8; +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; +#endif + } else if (mmc_test_switch_bus(chip, MMC_4BIT_BUS) == STATUS_SUCCESS) { + SET_MMC_4BIT(sd_card); + chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; +#endif + } else { + CLR_MMC_8BIT(sd_card); + CLR_MMC_4BIT(sd_card); + } + + return STATUS_SUCCESS; +} + + +static int reset_mmc(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval, i = 0, j = 0, k = 0; + int switch_ddr = 1; + u8 rsp[16]; + u8 spec_ver = 0; + u32 temp; + +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) + goto MMC_UNLOCK_ENTRY; +#endif + +DDR_TUNING_FAIL: + + retval = sd_prepare_reset(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, retval); + } + + SET_MMC(sd_card); + +RTY_MMC_RST: + retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + do { + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_send_cmd_get_rsp(chip, SEND_OP_COND, + (SUPPORT_VOLTAGE|0x40000000), SD_RSP_TYPE_R3, rsp, 5); + if (retval != STATUS_SUCCESS) { + if (sd_check_err_code(chip, SD_BUSY) || sd_check_err_code(chip, SD_TO_ERR)) { + k++; + if (k < 20) { + sd_clr_err_code(chip); + goto RTY_MMC_RST; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + j++; + if (j < 100) { + sd_clr_err_code(chip); + goto RTY_MMC_RST; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + wait_timeout(20); + i++; + } while (!(rsp[1] & 0x80) && (i < 255)); + + if (i == 255) { + TRACE_RET(chip, STATUS_FAIL); + } + + if ((rsp[1] & 0x60) == 0x40) { + SET_MMC_SECTOR_MODE(sd_card); + } else { + CLR_MMC_SECTOR_MODE(sd_card); + } + + retval = sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + sd_card->sd_addr = 0x00100000; + retval = sd_send_cmd_get_rsp(chip, SET_RELATIVE_ADDR, sd_card->sd_addr, SD_RSP_TYPE_R6, rsp, 5); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_check_csd(chip, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + spec_ver = (sd_card->raw_csd[0] & 0x3C) >> 2; + + retval = sd_select_card(chip, 1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + +#ifdef SUPPORT_SD_LOCK +MMC_UNLOCK_ENTRY: + retval = sd_update_lock_status(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } +#endif + + retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + chip->card_bus_width[chip->card2lun[SD_CARD]] = 1; + + if (!sd_card->mmc_dont_switch_bus) { + if (spec_ver == 4) { + (void)mmc_switch_timing_bus(chip, switch_ddr); + } + + if (CHK_MMC_SECTOR_MODE(sd_card) && (sd_card->capacity == 0)) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (switch_ddr && CHK_MMC_DDR52(sd_card)) { + retval = sd_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = mmc_ddr_tuning(chip); + if (retval != STATUS_SUCCESS) { + retval = sd_init_power(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + switch_ddr = 0; + goto DDR_TUNING_FAIL; + } + + retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); + if (retval == STATUS_SUCCESS) { + retval = sd_read_lba0(chip); + if (retval != STATUS_SUCCESS) { + retval = sd_init_power(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + switch_ddr = 0; + goto DDR_TUNING_FAIL; + } + } + } + } + +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) { + RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_H, 0xFF, 0x02); + RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_L, 0xFF, 0x00); + } +#endif + + temp = rtsx_readl(chip, RTSX_BIPR); + if (temp & SD_WRITE_PROTECT) { + chip->card_wp |= SD_CARD; + } + + return STATUS_SUCCESS; +} + +static void sd_init_type(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + + memset(sd_card, 0, sizeof(struct sd_info)); + + sd_card->sd_type = 0; + sd_card->seq_mode = 0; + sd_card->sd_data_buf_ready = 0; + sd_card->capacity = 0; + sd_card->sd_switch_fail = 0; + sd_card->mmc_dont_switch_bus = 0; + sd_card->need_retune = 0; + +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status = 0; + sd_card->sd_erase_status = 0; +#endif + + chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity = 0; +} + +int reset_sd_card(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + sd_init_reg_addr(chip); + + sd_init_type(chip); + + retval = enable_card_clock(chip, SD_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (chip->ignore_sd && CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { + if (chip->asic_code) { + retval = sd_pull_ctl_enable(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + retval = rtsx_write_register(chip, FPGA_PULL_CTL, + FPGA_SD_PULL_CTL_BIT | 0x20, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + retval = card_share_mode(chip, SD_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + chip->sd_io = 1; + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_init_power(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (chip->sd_ctl & RESET_MMC_FIRST) { + retval = reset_mmc(chip); + if ((retval != STATUS_SUCCESS) && !sd_check_err_code(chip, SD_NO_CARD)) { + retval = reset_sd(chip); + if (retval != STATUS_SUCCESS) { + if (CHECK_PID(chip, 0x5209)) { + retval = sd_change_bank_voltage(chip, SD_IO_3V3); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + } + } + } else { + retval = reset_sd(chip); + if (retval != STATUS_SUCCESS) { + if (sd_check_err_code(chip, SD_NO_CARD)) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (CHECK_PID(chip, 0x5209)) { + retval = sd_change_bank_voltage(chip, SD_IO_3V3); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (!chip->sd_io) { + retval = reset_mmc(chip); + } + } + } + + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_L, 0xFF, 0); + RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_H, 0xFF, 2); + + chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity; + + retval = sd_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_DEBUGP("sd_card->sd_type = 0x%x\n", sd_card->sd_type); + + return STATUS_SUCCESS; +} + +static int reset_mmc_only(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + sd_card->sd_type = 0; + sd_card->seq_mode = 0; + sd_card->sd_data_buf_ready = 0; + sd_card->capacity = 0; + sd_card->sd_switch_fail = 0; + +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status = 0; + sd_card->sd_erase_status = 0; +#endif + + chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity = 0; + + retval = enable_card_clock(chip, SD_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_init_power(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = reset_mmc(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_L, 0xFF, 0); + RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_H, 0xFF, 2); + + chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity; + + retval = sd_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_DEBUGP("In reset_mmc_only, sd_card->sd_type = 0x%x\n", sd_card->sd_type); + + return STATUS_SUCCESS; +} + +#define WAIT_DATA_READY_RTY_CNT 255 + +static int wait_data_buf_ready(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int i, retval; + + for (i = 0; i < WAIT_DATA_READY_RTY_CNT; i++) { + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + sd_card->sd_data_buf_ready = 0; + + retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, + sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (sd_card->sd_data_buf_ready) { + return sd_send_cmd_get_rsp(chip, SEND_STATUS, + sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); + } + } + + sd_set_err_code(chip, SD_TO_ERR); + + TRACE_RET(chip, STATUS_FAIL); +} + +void sd_stop_seq_mode(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + if (sd_card->seq_mode) { + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + return; + } + + retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, + SD_RSP_TYPE_R1b, NULL, 0); + if (retval != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_STS_ERR); + } + retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); + if (retval != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_STS_ERR); + } + sd_card->seq_mode = 0; + + rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); + } +} + +static inline int sd_auto_tune_clock(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + if (chip->asic_code) { + if (sd_card->sd_clock > 30) { + sd_card->sd_clock -= 20; + } + } else { + switch (sd_card->sd_clock) { + case CLK_200: + sd_card->sd_clock = CLK_150; + break; + + case CLK_150: + sd_card->sd_clock = CLK_120; + break; + + case CLK_120: + sd_card->sd_clock = CLK_100; + break; + + case CLK_100: + sd_card->sd_clock = CLK_80; + break; + + case CLK_80: + sd_card->sd_clock = CLK_60; + break; + + case CLK_60: + sd_card->sd_clock = CLK_50; + break; + + default: + break; + } + } + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt) +{ + struct sd_info *sd_card = &(chip->sd_card); + u32 data_addr; + u8 cfg2; + int retval; + + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + RTSX_DEBUGP("sd_rw: Read %d %s from 0x%x\n", sector_cnt, + (sector_cnt > 1) ? "sectors" : "sector", start_sector); + } else { + RTSX_DEBUGP("sd_rw: Write %d %s to 0x%x\n", sector_cnt, + (sector_cnt > 1) ? "sectors" : "sector", start_sector); + } + + sd_card->cleanup_counter = 0; + + if (!(chip->card_ready & SD_CARD)) { + sd_card->seq_mode = 0; + + retval = reset_sd_card(chip); + if (retval == STATUS_SUCCESS) { + chip->card_ready |= SD_CARD; + chip->card_fail &= ~SD_CARD; + } else { + chip->card_ready &= ~SD_CARD; + chip->card_fail |= SD_CARD; + chip->capacity[chip->card2lun[SD_CARD]] = 0; + chip->rw_need_retry = 1; + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (!CHK_SD_HCXC(sd_card) && !CHK_MMC_SECTOR_MODE(sd_card)) { + data_addr = start_sector << 9; + } else { + data_addr = start_sector; + } + + sd_clr_err_code(chip); + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_IO_ERR); + TRACE_GOTO(chip, RW_FAIL); + } + + if (sd_card->seq_mode && ((sd_card->pre_dir != srb->sc_data_direction) + || ((sd_card->pre_sec_addr + sd_card->pre_sec_cnt) != start_sector))) { + if ((sd_card->pre_sec_cnt < 0x80) + && (sd_card->pre_dir == DMA_FROM_DEVICE) + && !CHK_SD30_SPEED(sd_card) + && !CHK_SD_HS(sd_card) + && !CHK_MMC_HS(sd_card)) { + sd_send_cmd_get_rsp(chip, SEND_STATUS, + sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); + } + + retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, + 0, SD_RSP_TYPE_R1b, NULL, 0); + if (retval != STATUS_SUCCESS) { + chip->rw_need_retry = 1; + sd_set_err_code(chip, SD_STS_ERR); + TRACE_GOTO(chip, RW_FAIL); + } + + sd_card->seq_mode = 0; + + retval = rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); + if (retval != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_IO_ERR); + TRACE_GOTO(chip, RW_FAIL); + } + + if ((sd_card->pre_sec_cnt < 0x80) + && !CHK_SD30_SPEED(sd_card) + && !CHK_SD_HS(sd_card) + && !CHK_MMC_HS(sd_card)) { + sd_send_cmd_get_rsp(chip, SEND_STATUS, + sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); + } + } + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x00); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 0x02); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, (u8)sector_cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, (u8)(sector_cnt >> 8)); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); + + if (CHK_MMC_8BIT(sd_card)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_8); + } else if (CHK_MMC_4BIT(sd_card) || CHK_SD(sd_card)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_1); + } + + if (sd_card->seq_mode) { + cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | + SD_NO_CHECK_CRC7 | SD_RSP_LEN_0; + if (CHECK_PID(chip, 0x5209)) { + if (!CHK_SD30_SPEED(sd_card)) { + cfg2 |= SD_NO_CHECK_WAIT_CRC_TO; + } + } + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, cfg2); + + trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512, DMA_512); + + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, + SD_TM_AUTO_READ_3 | SD_TRANSFER_START); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, + SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); + } + + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + } else { + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + RTSX_DEBUGP("SD/MMC CMD %d\n", READ_MULTIPLE_BLOCK); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, + 0x40 | READ_MULTIPLE_BLOCK); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, (u8)(data_addr >> 24)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, (u8)(data_addr >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, (u8)(data_addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, (u8)data_addr); + + cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | + SD_CHECK_CRC7 | SD_RSP_LEN_6; + if (CHECK_PID(chip, 0x5209)) { + if (!CHK_SD30_SPEED(sd_card)) { + cfg2 |= SD_NO_CHECK_WAIT_CRC_TO; + } + } + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, cfg2); + + trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, + SD_TM_AUTO_READ_2 | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, + SD_TRANSFER_END, SD_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + } else { + retval = rtsx_send_cmd(chip, SD_CARD, 50); + if (retval < 0) { + rtsx_clear_sd_error(chip); + + chip->rw_need_retry = 1; + sd_set_err_code(chip, SD_TO_ERR); + TRACE_GOTO(chip, RW_FAIL); + } + + retval = wait_data_buf_ready(chip); + if (retval != STATUS_SUCCESS) { + chip->rw_need_retry = 1; + sd_set_err_code(chip, SD_TO_ERR); + TRACE_GOTO(chip, RW_FAIL); + } + + retval = sd_send_cmd_get_rsp(chip, WRITE_MULTIPLE_BLOCK, + data_addr, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + chip->rw_need_retry = 1; + TRACE_GOTO(chip, RW_FAIL); + } + + rtsx_init_cmd(chip); + + cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | + SD_NO_CHECK_CRC7 | SD_RSP_LEN_0; + if (CHECK_PID(chip, 0x5209)) { + if (!CHK_SD30_SPEED(sd_card)) { + cfg2 |= SD_NO_CHECK_WAIT_CRC_TO; + } + } + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, cfg2); + + trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, + SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, + SD_TRANSFER_END, SD_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + } + + sd_card->seq_mode = 1; + } + + retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb), scsi_bufflen(srb), + scsi_sg_count(srb), srb->sc_data_direction, chip->sd_timeout); + if (retval < 0) { + u8 stat = 0; + int err; + + sd_card->seq_mode = 0; + + if (retval == -ETIMEDOUT) { + err = STATUS_TIMEDOUT; + } else { + err = STATUS_FAIL; + } + + rtsx_read_register(chip, REG_SD_STAT1, &stat); + rtsx_clear_sd_error(chip); + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + chip->rw_need_retry = 0; + RTSX_DEBUGP("No card exist, exit sd_rw\n"); + TRACE_RET(chip, STATUS_FAIL); + } + + chip->rw_need_retry = 1; + + retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, SD_RSP_TYPE_R1b, NULL, 0); + if (retval != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_STS_ERR); + TRACE_GOTO(chip, RW_FAIL); + } + + if (stat & (SD_CRC7_ERR | SD_CRC16_ERR | SD_CRC_WRITE_ERR)) { + RTSX_DEBUGP("SD CRC error, tune clock!\n"); + sd_set_err_code(chip, SD_CRC_ERR); + TRACE_GOTO(chip, RW_FAIL); + } + + if (err == STATUS_TIMEDOUT) { + sd_set_err_code(chip, SD_TO_ERR); + TRACE_GOTO(chip, RW_FAIL); + } + + TRACE_RET(chip, err); + } + + sd_card->pre_sec_addr = start_sector; + sd_card->pre_sec_cnt = sector_cnt; + sd_card->pre_dir = srb->sc_data_direction; + + return STATUS_SUCCESS; + +RW_FAIL: + sd_card->seq_mode = 0; + + if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { + chip->rw_need_retry = 0; + RTSX_DEBUGP("No card exist, exit sd_rw\n"); + TRACE_RET(chip, STATUS_FAIL); + } + + if (sd_check_err_code(chip, SD_CRC_ERR)) { + if (CHK_MMC_4BIT(sd_card) || CHK_MMC_8BIT(sd_card)) { + sd_card->mmc_dont_switch_bus = 1; + reset_mmc_only(chip); + sd_card->mmc_dont_switch_bus = 0; + } else { + sd_card->need_retune = 1; + sd_auto_tune_clock(chip); + } + } else if (sd_check_err_code(chip, SD_TO_ERR | SD_STS_ERR)) { + retval = reset_sd_card(chip); + if (retval != STATUS_SUCCESS) { + chip->card_ready &= ~SD_CARD; + chip->card_fail |= SD_CARD; + chip->capacity[chip->card2lun[SD_CARD]] = 0; + } + } + + TRACE_RET(chip, STATUS_FAIL); +} + +#ifdef SUPPORT_CPRM +int soft_reset_sd_card(struct rtsx_chip *chip) +{ + return reset_sd(chip); +} + +int ext_sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx, + u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, int special_check) +{ + int retval; + int timeout = 100; + u16 reg_addr; + u8 *ptr; + int stat_idx = 0; + int rty_cnt = 0; + + RTSX_DEBUGP("EXT SD/MMC CMD %d\n", cmd_idx); + + if (rsp_type == SD_RSP_TYPE_R1b) { + timeout = 3000; + } + +RTY_SEND_CMD: + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | cmd_idx); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, (u8)(arg >> 24)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, (u8)(arg >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, (u8)(arg >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, (u8)arg); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, + 0x01, PINGPONG_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, + 0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); + + if (rsp_type == SD_RSP_TYPE_R2) { + for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; reg_addr++) { + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); + } + stat_idx = 17; + } else if (rsp_type != SD_RSP_TYPE_R0) { + for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; reg_addr++) { + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); + } + stat_idx = 6; + } + rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_CMD5, 0, 0); + + rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_STAT1, 0, 0); + + retval = rtsx_send_cmd(chip, SD_CARD, timeout); + if (retval < 0) { + if (retval == -ETIMEDOUT) { + rtsx_clear_sd_error(chip); + + if (rsp_type & SD_WAIT_BUSY_END) { + retval = sd_check_data0_status(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, retval); + } + } else { + sd_set_err_code(chip, SD_TO_ERR); + } + } + TRACE_RET(chip, STATUS_FAIL); + } + + if (rsp_type == SD_RSP_TYPE_R0) { + return STATUS_SUCCESS; + } + + ptr = rtsx_get_cmd_data(chip) + 1; + + if ((ptr[0] & 0xC0) != 0) { + sd_set_err_code(chip, SD_STS_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + if (!(rsp_type & SD_NO_CHECK_CRC7)) { + if (ptr[stat_idx] & SD_CRC7_ERR) { + if (cmd_idx == WRITE_MULTIPLE_BLOCK) { + sd_set_err_code(chip, SD_CRC_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + if (rty_cnt < SD_MAX_RETRY_COUNT) { + wait_timeout(20); + rty_cnt++; + goto RTY_SEND_CMD; + } else { + sd_set_err_code(chip, SD_CRC_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + if ((cmd_idx == SELECT_CARD) || (cmd_idx == APP_CMD) || + (cmd_idx == SEND_STATUS) || (cmd_idx == STOP_TRANSMISSION)) { + if ((cmd_idx != STOP_TRANSMISSION) && (special_check == 0)) { + if (ptr[1] & 0x80) { + TRACE_RET(chip, STATUS_FAIL); + } + } +#ifdef SUPPORT_SD_LOCK + if (ptr[1] & 0x7D) +#else + if (ptr[1] & 0x7F) +#endif + { + TRACE_RET(chip, STATUS_FAIL); + } + if (ptr[2] & 0xF8) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (cmd_idx == SELECT_CARD) { + if (rsp_type == SD_RSP_TYPE_R2) { + if ((ptr[3] & 0x1E) != 0x04) { + TRACE_RET(chip, STATUS_FAIL); + } + } else if (rsp_type == SD_RSP_TYPE_R2) { + if ((ptr[3] & 0x1E) != 0x03) { + TRACE_RET(chip, STATUS_FAIL); + } + } + } + } + + if (rsp && rsp_len) { + memcpy(rsp, ptr, rsp_len); + } + + return STATUS_SUCCESS; +} + +int ext_sd_get_rsp(struct rtsx_chip *chip, int len, u8 *rsp, u8 rsp_type) +{ + int retval, rsp_len; + u16 reg_addr; + + if (rsp_type == SD_RSP_TYPE_R0) { + return STATUS_SUCCESS; + } + + rtsx_init_cmd(chip); + + if (rsp_type == SD_RSP_TYPE_R2) { + for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; reg_addr++) { + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0); + } + rsp_len = 17; + } else if (rsp_type != SD_RSP_TYPE_R0) { + for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; reg_addr++) { + rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0); + } + rsp_len = 6; + } + rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_CMD5, 0xFF, 0); + + retval = rtsx_send_cmd(chip, SD_CARD, 100); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (rsp) { + int min_len = (rsp_len < len) ? rsp_len : len; + + memcpy(rsp, rtsx_get_cmd_data(chip), min_len); + + RTSX_DEBUGP("min_len = %d\n", min_len); + RTSX_DEBUGP("Response in cmd buf: 0x%x 0x%x 0x%x 0x%x\n", + rsp[0], rsp[1], rsp[2], rsp[3]); + } + + return STATUS_SUCCESS; +} + +int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + unsigned int lun = SCSI_LUN(srb); + int len; + u8 buf[18] = { + 0x00, + 0x00, + 0x00, + 0x0E, + 0x00, + 0x00, + 0x00, + 0x00, + 0x53, + 0x44, + 0x20, + 0x43, + 0x61, + 0x72, + 0x64, + 0x00, + 0x00, + 0x00, + }; + + sd_card->pre_cmd_err = 0; + + if (!(CHK_BIT(chip->lun_mc, lun))) { + SET_BIT(chip->lun_mc, lun); + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if ((0x53 != srb->cmnd[2]) || (0x44 != srb->cmnd[3]) || (0x20 != srb->cmnd[4]) || + (0x43 != srb->cmnd[5]) || (0x61 != srb->cmnd[6]) || + (0x72 != srb->cmnd[7]) || (0x64 != srb->cmnd[8])) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + switch (srb->cmnd[1] & 0x0F) { + case 0: + sd_card->sd_pass_thru_en = 0; + break; + + case 1: + sd_card->sd_pass_thru_en = 1; + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + buf[5] = (1 == CHK_SD(sd_card)) ? 0x01 : 0x02; + if (chip->card_wp & SD_CARD) { + buf[5] |= 0x80; + } + + buf[6] = (u8)(sd_card->sd_addr >> 16); + buf[7] = (u8)(sd_card->sd_addr >> 24); + + buf[15] = chip->max_lun; + + len = min(18, (int)scsi_bufflen(srb)); + rtsx_stor_set_xfer_buf(buf, len, srb); + + return TRANSPORT_GOOD; +} + +static inline int get_rsp_type(struct scsi_cmnd *srb, u8 *rsp_type, int *rsp_len) +{ + if (!rsp_type || !rsp_len) { + return STATUS_FAIL; + } + + switch (srb->cmnd[10]) { + case 0x03: + *rsp_type = SD_RSP_TYPE_R0; + *rsp_len = 0; + break; + + case 0x04: + *rsp_type = SD_RSP_TYPE_R1; + *rsp_len = 6; + break; + + case 0x05: + *rsp_type = SD_RSP_TYPE_R1b; + *rsp_len = 6; + break; + + case 0x06: + *rsp_type = SD_RSP_TYPE_R2; + *rsp_len = 17; + break; + + case 0x07: + *rsp_type = SD_RSP_TYPE_R3; + *rsp_len = 6; + break; + + default: + return STATUS_FAIL; + } + + return STATUS_SUCCESS; +} + +int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + unsigned int lun = SCSI_LUN(srb); + int retval, rsp_len; + u8 cmd_idx, rsp_type; + u8 standby = 0, acmd = 0; + u32 arg; + + if (!sd_card->sd_pass_thru_en) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (sd_card->pre_cmd_err) { + sd_card->pre_cmd_err = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + cmd_idx = srb->cmnd[2] & 0x3F; + if (srb->cmnd[1] & 0x02) { + standby = 1; + } + if (srb->cmnd[1] & 0x01) { + acmd = 1; + } + + arg = ((u32)srb->cmnd[3] << 24) | ((u32)srb->cmnd[4] << 16) | + ((u32)srb->cmnd[5] << 8) | srb->cmnd[6]; + + retval = get_rsp_type(srb, &rsp_type, &rsp_len); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + sd_card->last_rsp_type = rsp_type; + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + +#ifdef SUPPORT_SD_LOCK + if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { + if (CHK_MMC_8BIT(sd_card)) { + retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_8); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { + retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + } +#else + retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } +#endif + + if (standby) { + retval = sd_select_card(chip, 0); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Cmd_Failed); + } + } + + if (acmd) { + retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Cmd_Failed); + } + } + + retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, + sd_card->rsp, rsp_len, 0); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Cmd_Failed); + } + + if (standby) { + retval = sd_select_card(chip, 1); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Cmd_Failed); + } + } + +#ifdef SUPPORT_SD_LOCK + retval = sd_update_lock_status(chip); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Cmd_Failed); + } +#endif + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; + +SD_Execute_Cmd_Failed: + sd_card->pre_cmd_err = 1; + set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + release_sd_card(chip); + do_reset_sd_card(chip); + if (!(chip->card_ready & SD_CARD)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + } + + TRACE_RET(chip, TRANSPORT_FAILED); +} + +int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + unsigned int lun = SCSI_LUN(srb); + int retval, rsp_len, i; + int cmd13_checkbit = 0, read_err = 0; + u8 cmd_idx, rsp_type, bus_width; + u8 send_cmd12 = 0, standby = 0, acmd = 0; + u32 data_len; + + if (!sd_card->sd_pass_thru_en) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (sd_card->pre_cmd_err) { + sd_card->pre_cmd_err = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + + cmd_idx = srb->cmnd[2] & 0x3F; + if (srb->cmnd[1] & 0x04) { + send_cmd12 = 1; + } + if (srb->cmnd[1] & 0x02) { + standby = 1; + } + if (srb->cmnd[1] & 0x01) { + acmd = 1; + } + + data_len = ((u32)srb->cmnd[7] << 16) | ((u32)srb->cmnd[8] << 8) | srb->cmnd[9]; + + retval = get_rsp_type(srb, &rsp_type, &rsp_len); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + sd_card->last_rsp_type = rsp_type; + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + +#ifdef SUPPORT_SD_LOCK + if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { + if (CHK_MMC_8BIT(sd_card)) { + bus_width = SD_BUS_WIDTH_8; + } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { + bus_width = SD_BUS_WIDTH_4; + } else { + bus_width = SD_BUS_WIDTH_1; + } + } else { + bus_width = SD_BUS_WIDTH_4; + } + RTSX_DEBUGP("bus_width = %d\n", bus_width); +#else + bus_width = SD_BUS_WIDTH_4; +#endif + + if (data_len < 512) { + retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + } + + if (standby) { + retval = sd_select_card(chip, 0); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + } + + if (acmd) { + retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + } + + if (data_len <= 512) { + int min_len; + u8 *buf; + u16 byte_cnt, blk_cnt; + u8 cmd[5]; + + byte_cnt = ((u16)(srb->cmnd[8] & 0x03) << 8) | srb->cmnd[9]; + blk_cnt = 1; + + cmd[0] = 0x40 | cmd_idx; + cmd[1] = srb->cmnd[3]; + cmd[2] = srb->cmnd[4]; + cmd[3] = srb->cmnd[5]; + cmd[4] = srb->cmnd[6]; + + buf = (u8 *)kmalloc(data_len, GFP_KERNEL); + if (buf == NULL) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, byte_cnt, + blk_cnt, bus_width, buf, data_len, 2000); + if (retval != STATUS_SUCCESS) { + read_err = 1; + kfree(buf); + rtsx_clear_sd_error(chip); + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + min_len = min(data_len, scsi_bufflen(srb)); + rtsx_stor_set_xfer_buf(buf, min_len, srb); + + kfree(buf); + } else if (!(data_len & 0x1FF)) { + rtsx_init_cmd(chip); + + trans_dma_enable(DMA_FROM_DEVICE, chip, data_len, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 0x02); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x00); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, + 0xFF, (srb->cmnd[7] & 0xFE) >> 1); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, + 0xFF, (u8)((data_len & 0x0001FE00) >> 9)); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | cmd_idx); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, srb->cmnd[3]); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, srb->cmnd[4]); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, srb->cmnd[5]); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, srb->cmnd[6]); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, + 0xFF, SD_TM_AUTO_READ_2 | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + + retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb), scsi_bufflen(srb), + scsi_sg_count(srb), DMA_FROM_DEVICE, 10000); + if (retval < 0) { + read_err = 1; + rtsx_clear_sd_error(chip); + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + } else { + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + retval = ext_sd_get_rsp(chip, rsp_len, sd_card->rsp, rsp_type); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + if (standby) { + retval = sd_select_card(chip, 1); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + } + + if (send_cmd12) { + retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, + 0, SD_RSP_TYPE_R1b, NULL, 0, 0); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + } + + if (data_len < 512) { + retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + retval = rtsx_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + retval = rtsx_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + } + + if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04)) { + cmd13_checkbit = 1; + } + + for (i = 0; i < 3; i++) { + retval = ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0, cmd13_checkbit); + if (retval == STATUS_SUCCESS) { + break; + } + } + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; + +SD_Execute_Read_Cmd_Failed: + sd_card->pre_cmd_err = 1; + set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + if (read_err) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + } + release_sd_card(chip); + do_reset_sd_card(chip); + if (!(chip->card_ready & SD_CARD)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + } + + TRACE_RET(chip, TRANSPORT_FAILED); +} + +int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + unsigned int lun = SCSI_LUN(srb); + int retval, rsp_len, i; + int cmd13_checkbit = 0, write_err = 0; + u8 cmd_idx, rsp_type; + u8 send_cmd12 = 0, standby = 0, acmd = 0; + u32 data_len, arg; +#ifdef SUPPORT_SD_LOCK + int lock_cmd_fail = 0; + u8 sd_lock_state = 0; + u8 lock_cmd_type = 0; +#endif + + if (!sd_card->sd_pass_thru_en) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (sd_card->pre_cmd_err) { + sd_card->pre_cmd_err = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + + cmd_idx = srb->cmnd[2] & 0x3F; + if (srb->cmnd[1] & 0x04) { + send_cmd12 = 1; + } + if (srb->cmnd[1] & 0x02) { + standby = 1; + } + if (srb->cmnd[1] & 0x01) { + acmd = 1; + } + + data_len = ((u32)srb->cmnd[7] << 16) | ((u32)srb->cmnd[8] << 8) | srb->cmnd[9]; + arg = ((u32)srb->cmnd[3] << 24) | ((u32)srb->cmnd[4] << 16) | + ((u32)srb->cmnd[5] << 8) | srb->cmnd[6]; + +#ifdef SUPPORT_SD_LOCK + if (cmd_idx == LOCK_UNLOCK) { + sd_lock_state = sd_card->sd_lock_status; + sd_lock_state &= SD_LOCKED; + } +#endif + + retval = get_rsp_type(srb, &rsp_type, &rsp_len); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + sd_card->last_rsp_type = rsp_type; + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + +#ifdef SUPPORT_SD_LOCK + if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { + if (CHK_MMC_8BIT(sd_card)) { + retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_8); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { + retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + } +#else + retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, TRANSPORT_FAILED); + } +#endif + + if (data_len < 512) { + retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + } + + if (standby) { + retval = sd_select_card(chip, 0); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + } + + if (acmd) { + retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + } + + retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, + sd_card->rsp, rsp_len, 0); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + + if (data_len <= 512) { + u16 i; + u8 *buf; + + buf = (u8 *)kmalloc(data_len, GFP_KERNEL); + if (buf == NULL) { + TRACE_RET(chip, TRANSPORT_ERROR); + } + + rtsx_stor_get_xfer_buf(buf, data_len, srb); + +#ifdef SUPPORT_SD_LOCK + if (cmd_idx == LOCK_UNLOCK) { + lock_cmd_type = buf[0] & 0x0F; + } +#endif + + if (data_len > 256) { + rtsx_init_cmd(chip); + for (i = 0; i < 256; i++) { + rtsx_add_cmd(chip, WRITE_REG_CMD, + PPBUF_BASE2 + i, 0xFF, buf[i]); + } + retval = rtsx_send_cmd(chip, 0, 250); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + + rtsx_init_cmd(chip); + for (i = 256; i < data_len; i++) { + rtsx_add_cmd(chip, WRITE_REG_CMD, + PPBUF_BASE2 + i, 0xFF, buf[i]); + } + retval = rtsx_send_cmd(chip, 0, 250); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + } else { + rtsx_init_cmd(chip); + for (i = 0; i < data_len; i++) { + rtsx_add_cmd(chip, WRITE_REG_CMD, + PPBUF_BASE2 + i, 0xFF, buf[i]); + } + retval = rtsx_send_cmd(chip, 0, 250); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + } + + kfree(buf); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, srb->cmnd[8] & 0x03); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, srb->cmnd[9]); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, 0x00); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, 0x01); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, + SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); + + retval = rtsx_send_cmd(chip, SD_CARD, 250); + } else if (!(data_len & 0x1FF)) { + rtsx_init_cmd(chip); + + trans_dma_enable(DMA_TO_DEVICE, chip, data_len, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 0x02); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x00); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, + 0xFF, (srb->cmnd[7] & 0xFE) >> 1); + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, + 0xFF, (u8)((data_len & 0x0001FE00) >> 9)); + + rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + + retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb), scsi_bufflen(srb), + scsi_sg_count(srb), DMA_TO_DEVICE, 10000); + + } else { + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + + if (retval < 0) { + write_err = 1; + rtsx_clear_sd_error(chip); + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + +#ifdef SUPPORT_SD_LOCK + if (cmd_idx == LOCK_UNLOCK) { + if (lock_cmd_type == SD_ERASE) { + sd_card->sd_erase_status = SD_UNDER_ERASING; + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; + } + + rtsx_init_cmd(chip); + if (CHECK_PID(chip, 0x5209)) { + rtsx_add_cmd(chip, CHECK_REG_CMD, SD_BUS_STAT, SD_DAT0_STATUS, SD_DAT0_STATUS); + } else { + rtsx_add_cmd(chip, CHECK_REG_CMD, 0xFD30, 0x02, 0x02); + } + rtsx_send_cmd(chip, SD_CARD, 250); + + retval = sd_update_lock_status(chip); + if (retval != STATUS_SUCCESS) { + RTSX_DEBUGP("Lock command fail!\n"); + lock_cmd_fail = 1; + } + } +#endif /* SUPPORT_SD_LOCK */ + + if (standby) { + retval = sd_select_card(chip, 1); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + } + + if (send_cmd12) { + retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, + 0, SD_RSP_TYPE_R1b, NULL, 0, 0); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + } + + if (data_len < 512) { + retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + + retval = rtsx_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + rtsx_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00); + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + } + + if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04)) { + cmd13_checkbit = 1; + } + + for (i = 0; i < 3; i++) { + retval = ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0, cmd13_checkbit); + if (retval == STATUS_SUCCESS) { + break; + } + } + if (retval != STATUS_SUCCESS) { + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + +#ifdef SUPPORT_SD_LOCK + if (cmd_idx == LOCK_UNLOCK) { + if (!lock_cmd_fail) { + RTSX_DEBUGP("lock_cmd_type = 0x%x\n", lock_cmd_type); + if (lock_cmd_type & SD_CLR_PWD) { + sd_card->sd_lock_status &= ~SD_PWD_EXIST; + } + if (lock_cmd_type & SD_SET_PWD) { + sd_card->sd_lock_status |= SD_PWD_EXIST; + } + } + + RTSX_DEBUGP("sd_lock_state = 0x%x, sd_card->sd_lock_status = 0x%x\n", + sd_lock_state, sd_card->sd_lock_status); + if (sd_lock_state ^ (sd_card->sd_lock_status & SD_LOCKED)) { + sd_card->sd_lock_notify = 1; + if (sd_lock_state) { + if (sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) { + sd_card->sd_lock_status |= (SD_UNLOCK_POW_ON | SD_SDR_RST); + if (CHK_SD(sd_card)) { + retval = reset_sd(chip); + if (retval != STATUS_SUCCESS) { + sd_card->sd_lock_status &= ~(SD_UNLOCK_POW_ON | SD_SDR_RST); + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + } + + sd_card->sd_lock_status &= ~(SD_UNLOCK_POW_ON | SD_SDR_RST); + } + } + } + } + + if (lock_cmd_fail) { + scsi_set_resid(srb, 0); + set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + TRACE_RET(chip, TRANSPORT_FAILED); + } +#endif /* SUPPORT_SD_LOCK */ + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; + +SD_Execute_Write_Cmd_Failed: + sd_card->pre_cmd_err = 1; + set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + if (write_err) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + } + release_sd_card(chip); + do_reset_sd_card(chip); + if (!(chip->card_ready & SD_CARD)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + } + + TRACE_RET(chip, TRANSPORT_FAILED); +} + +int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + unsigned int lun = SCSI_LUN(srb); + int count; + u16 data_len; + + if (!sd_card->sd_pass_thru_en) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (sd_card->pre_cmd_err) { + sd_card->pre_cmd_err = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + data_len = ((u16)srb->cmnd[7] << 8) | srb->cmnd[8]; + + if (sd_card->last_rsp_type == SD_RSP_TYPE_R0) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } else if (sd_card->last_rsp_type == SD_RSP_TYPE_R2) { + count = (data_len < 17) ? data_len : 17; + } else { + count = (data_len < 6) ? data_len : 6; + } + rtsx_stor_set_xfer_buf(sd_card->rsp, count, srb); + + RTSX_DEBUGP("Response length: %d\n", data_len); + RTSX_DEBUGP("Response: 0x%x 0x%x 0x%x 0x%x\n", + sd_card->rsp[0], sd_card->rsp[1], sd_card->rsp[2], sd_card->rsp[3]); + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; +} + +int sd_hw_rst(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + unsigned int lun = SCSI_LUN(srb); + int retval; + + if (!sd_card->sd_pass_thru_en) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (sd_card->pre_cmd_err) { + sd_card->pre_cmd_err = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if ((0x53 != srb->cmnd[2]) || (0x44 != srb->cmnd[3]) || (0x20 != srb->cmnd[4]) || + (0x43 != srb->cmnd[5]) || (0x61 != srb->cmnd[6]) || + (0x72 != srb->cmnd[7]) || (0x64 != srb->cmnd[8])) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + switch (srb->cmnd[1] & 0x0F) { + case 0: +#ifdef SUPPORT_SD_LOCK + if (0x64 == srb->cmnd[9]) { + sd_card->sd_lock_status |= SD_SDR_RST; + } +#endif + retval = reset_sd_card(chip); + if (retval != STATUS_SUCCESS) { +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status &= ~SD_SDR_RST; +#endif + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + sd_card->pre_cmd_err = 1; + TRACE_RET(chip, TRANSPORT_FAILED); + } +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status &= ~SD_SDR_RST; +#endif + break; + + case 1: + retval = soft_reset_sd_card(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + sd_card->pre_cmd_err = 1; + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; +} +#endif + +void sd_cleanup_work(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + + if (sd_card->seq_mode) { + RTSX_DEBUGP("SD: stop transmission\n"); + sd_stop_seq_mode(chip); + sd_card->cleanup_counter = 0; + } +} + +int sd_power_off_card3v3(struct rtsx_chip *chip) +{ + int retval; + + retval = disable_card_clock(chip, SD_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, CARD_OE, SD_OUTPUT_EN, 0); + + if (!chip->ft2_fast_mode) { + retval = card_power_off(chip, SD_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + wait_timeout(50); + } + + if (chip->asic_code) { + retval = sd_pull_ctl_disable(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + RTSX_WRITE_REG(chip, FPGA_PULL_CTL, + FPGA_SD_PULL_CTL_BIT | 0x20, FPGA_SD_PULL_CTL_BIT); + } + + return STATUS_SUCCESS; +} + +int release_sd_card(struct rtsx_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + RTSX_DEBUGP("release_sd_card\n"); + + chip->card_ready &= ~SD_CARD; + chip->card_fail &= ~SD_CARD; + chip->card_wp &= ~SD_CARD; + + chip->sd_io = 0; + chip->sd_int = 0; + +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status = 0; + sd_card->sd_erase_status = 0; +#endif + + memset(sd_card->raw_csd, 0, 16); + memset(sd_card->raw_scr, 0, 8); + + retval = sd_power_off_card3v3(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (CHECK_PID(chip, 0x5209)) { + retval = sd_change_bank_voltage(chip, SD_IO_3V3); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (CHK_SD30_SPEED(sd_card)) { + RTSX_WRITE_REG(chip, SD30_DRIVE_SEL, 0x07, chip->sd30_drive_sel_3v3); + } + + RTSX_WRITE_REG(chip, OCPPARA2, SD_OCP_THD_MASK, chip->sd_400mA_ocp_thd); + } + + return STATUS_SUCCESS; +} diff --git a/drivers/staging/rts_pstor/sd.h b/drivers/staging/rts_pstor/sd.h new file mode 100644 index 000000000000..d62e690e963f --- /dev/null +++ b/drivers/staging/rts_pstor/sd.h @@ -0,0 +1,295 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __REALTEK_RTSX_SD_H +#define __REALTEK_RTSX_SD_H + +#include "rtsx_chip.h" + +#define SUPPORT_VOLTAGE 0x003C0000 + +/* Error Code */ +#define SD_NO_ERROR 0x0 +#define SD_CRC_ERR 0x80 +#define SD_TO_ERR 0x40 +#define SD_NO_CARD 0x20 +#define SD_BUSY 0x10 +#define SD_STS_ERR 0x08 +#define SD_RSP_TIMEOUT 0x04 +#define SD_IO_ERR 0x02 + +/* MMC/SD Command Index */ +/* Basic command (class 0) */ +#define GO_IDLE_STATE 0 +#define SEND_OP_COND 1 +#define ALL_SEND_CID 2 +#define SET_RELATIVE_ADDR 3 +#define SEND_RELATIVE_ADDR 3 +#define SET_DSR 4 +#define IO_SEND_OP_COND 5 +#define SWITCH 6 +#define SELECT_CARD 7 +#define DESELECT_CARD 7 +/* CMD8 is "SEND_EXT_CSD" for MMC4.x Spec + * while is "SEND_IF_COND" for SD 2.0 + */ +#define SEND_EXT_CSD 8 +#define SEND_IF_COND 8 + +#define SEND_CSD 9 +#define SEND_CID 10 +#define VOLTAGE_SWITCH 11 +#define READ_DAT_UTIL_STOP 11 +#define STOP_TRANSMISSION 12 +#define SEND_STATUS 13 +#define GO_INACTIVE_STATE 15 + +#define SET_BLOCKLEN 16 +#define READ_SINGLE_BLOCK 17 +#define READ_MULTIPLE_BLOCK 18 +#define SEND_TUNING_PATTERN 19 + +#define BUSTEST_R 14 +#define BUSTEST_W 19 + +#define WRITE_BLOCK 24 +#define WRITE_MULTIPLE_BLOCK 25 +#define PROGRAM_CSD 27 + +#define ERASE_WR_BLK_START 32 +#define ERASE_WR_BLK_END 33 +#define ERASE_CMD 38 + +#define LOCK_UNLOCK 42 +#define IO_RW_DIRECT 52 + +#define APP_CMD 55 +#define GEN_CMD 56 + +#define SET_BUS_WIDTH 6 +#define SD_STATUS 13 +#define SEND_NUM_WR_BLOCKS 22 +#define SET_WR_BLK_ERASE_COUNT 23 +#define SD_APP_OP_COND 41 +#define SET_CLR_CARD_DETECT 42 +#define SEND_SCR 51 + +#define SD_READ_COMPLETE 0x00 +#define SD_READ_TO 0x01 +#define SD_READ_ADVENCE 0x02 + +#define SD_CHECK_MODE 0x00 +#define SD_SWITCH_MODE 0x80 +#define SD_FUNC_GROUP_1 0x01 +#define SD_FUNC_GROUP_2 0x02 +#define SD_FUNC_GROUP_3 0x03 +#define SD_FUNC_GROUP_4 0x04 +#define SD_CHECK_SPEC_V1_1 0xFF + +#define NO_ARGUMENT 0x00 +#define CHECK_PATTERN 0x000000AA +#define VOLTAGE_SUPPLY_RANGE 0x00000100 +#define SUPPORT_HIGH_AND_EXTENDED_CAPACITY 0x40000000 +#define SUPPORT_MAX_POWER_PERMANCE 0x10000000 +#define SUPPORT_1V8 0x01000000 + +#define SWTICH_NO_ERR 0x00 +#define CARD_NOT_EXIST 0x01 +#define SPEC_NOT_SUPPORT 0x02 +#define CHECK_MODE_ERR 0x03 +#define CHECK_NOT_READY 0x04 +#define SWITCH_CRC_ERR 0x05 +#define SWITCH_MODE_ERR 0x06 +#define SWITCH_PASS 0x07 + +#ifdef SUPPORT_SD_LOCK +#define SD_ERASE 0x08 +#define SD_LOCK 0x04 +#define SD_UNLOCK 0x00 +#define SD_CLR_PWD 0x02 +#define SD_SET_PWD 0x01 + +#define SD_PWD_LEN 0x10 + +#define SD_LOCKED 0x80 +#define SD_LOCK_1BIT_MODE 0x40 +#define SD_PWD_EXIST 0x20 +#define SD_UNLOCK_POW_ON 0x01 +#define SD_SDR_RST 0x02 + +#define SD_NOT_ERASE 0x00 +#define SD_UNDER_ERASING 0x01 +#define SD_COMPLETE_ERASE 0x02 + +#define SD_RW_FORBIDDEN 0x0F + +#endif + +#define HS_SUPPORT 0x01 +#define SDR50_SUPPORT 0x02 +#define SDR104_SUPPORT 0x03 +#define DDR50_SUPPORT 0x04 + +#define HS_SUPPORT_MASK 0x02 +#define SDR50_SUPPORT_MASK 0x04 +#define SDR104_SUPPORT_MASK 0x08 +#define DDR50_SUPPORT_MASK 0x10 + +#define HS_QUERY_SWITCH_OK 0x01 +#define SDR50_QUERY_SWITCH_OK 0x02 +#define SDR104_QUERY_SWITCH_OK 0x03 +#define DDR50_QUERY_SWITCH_OK 0x04 + +#define HS_SWITCH_BUSY 0x02 +#define SDR50_SWITCH_BUSY 0x04 +#define SDR104_SWITCH_BUSY 0x08 +#define DDR50_SWITCH_BUSY 0x10 + +#define FUNCTION_GROUP1_SUPPORT_OFFSET 0x0D +#define FUNCTION_GROUP1_QUERY_SWITCH_OFFSET 0x10 +#define FUNCTION_GROUP1_CHECK_BUSY_OFFSET 0x1D + +#define DRIVING_TYPE_A 0x01 +#define DRIVING_TYPE_B 0x00 +#define DRIVING_TYPE_C 0x02 +#define DRIVING_TYPE_D 0x03 + +#define DRIVING_TYPE_A_MASK 0x02 +#define DRIVING_TYPE_B_MASK 0x01 +#define DRIVING_TYPE_C_MASK 0x04 +#define DRIVING_TYPE_D_MASK 0x08 + +#define TYPE_A_QUERY_SWITCH_OK 0x01 +#define TYPE_B_QUERY_SWITCH_OK 0x00 +#define TYPE_C_QUERY_SWITCH_OK 0x02 +#define TYPE_D_QUERY_SWITCH_OK 0x03 + +#define TYPE_A_SWITCH_BUSY 0x02 +#define TYPE_B_SWITCH_BUSY 0x01 +#define TYPE_C_SWITCH_BUSY 0x04 +#define TYPE_D_SWITCH_BUSY 0x08 + +#define FUNCTION_GROUP3_SUPPORT_OFFSET 0x09 +#define FUNCTION_GROUP3_QUERY_SWITCH_OFFSET 0x0F +#define FUNCTION_GROUP3_CHECK_BUSY_OFFSET 0x19 + +#define CURRENT_LIMIT_200 0x00 +#define CURRENT_LIMIT_400 0x01 +#define CURRENT_LIMIT_600 0x02 +#define CURRENT_LIMIT_800 0x03 + +#define CURRENT_LIMIT_200_MASK 0x01 +#define CURRENT_LIMIT_400_MASK 0x02 +#define CURRENT_LIMIT_600_MASK 0x04 +#define CURRENT_LIMIT_800_MASK 0x08 + +#define CURRENT_LIMIT_200_QUERY_SWITCH_OK 0x00 +#define CURRENT_LIMIT_400_QUERY_SWITCH_OK 0x01 +#define CURRENT_LIMIT_600_QUERY_SWITCH_OK 0x02 +#define CURRENT_LIMIT_800_QUERY_SWITCH_OK 0x03 + +#define CURRENT_LIMIT_200_SWITCH_BUSY 0x01 +#define CURRENT_LIMIT_400_SWITCH_BUSY 0x02 +#define CURRENT_LIMIT_600_SWITCH_BUSY 0x04 +#define CURRENT_LIMIT_800_SWITCH_BUSY 0x08 + +#define FUNCTION_GROUP4_SUPPORT_OFFSET 0x07 +#define FUNCTION_GROUP4_QUERY_SWITCH_OFFSET 0x0F +#define FUNCTION_GROUP4_CHECK_BUSY_OFFSET 0x17 + +#define DATA_STRUCTURE_VER_OFFSET 0x11 + +#define MAX_PHASE 31 + +#define MMC_8BIT_BUS 0x0010 +#define MMC_4BIT_BUS 0x0020 + +#define MMC_SWITCH_ERR 0x80 + +#define SD_IO_3V3 0 +#define SD_IO_1V8 1 + +#define TUNE_TX 0x00 +#define TUNE_RX 0x01 + +#define CHANGE_TX 0x00 +#define CHANGE_RX 0x01 + +#define DCM_HIGH_FREQUENCY_MODE 0x00 +#define DCM_LOW_FREQUENCY_MODE 0x01 + +#define DCM_HIGH_FREQUENCY_MODE_SET 0x0C +#define DCM_Low_FREQUENCY_MODE_SET 0x00 + +#define MULTIPLY_BY_1 0x00 +#define MULTIPLY_BY_2 0x01 +#define MULTIPLY_BY_3 0x02 +#define MULTIPLY_BY_4 0x03 +#define MULTIPLY_BY_5 0x04 +#define MULTIPLY_BY_6 0x05 +#define MULTIPLY_BY_7 0x06 +#define MULTIPLY_BY_8 0x07 +#define MULTIPLY_BY_9 0x08 +#define MULTIPLY_BY_10 0x09 + +#define DIVIDE_BY_2 0x01 +#define DIVIDE_BY_3 0x02 +#define DIVIDE_BY_4 0x03 +#define DIVIDE_BY_5 0x04 +#define DIVIDE_BY_6 0x05 +#define DIVIDE_BY_7 0x06 +#define DIVIDE_BY_8 0x07 +#define DIVIDE_BY_9 0x08 +#define DIVIDE_BY_10 0x09 + +struct timing_phase_path { + int start; + int end; + int mid; + int len; +}; + +int sd_select_card(struct rtsx_chip *chip, int select); +int sd_pull_ctl_enable(struct rtsx_chip *chip); +int reset_sd_card(struct rtsx_chip *chip); +int sd_switch_clock(struct rtsx_chip *chip); +void sd_stop_seq_mode(struct rtsx_chip *chip); +int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt); +void sd_cleanup_work(struct rtsx_chip *chip); +int sd_power_off_card3v3(struct rtsx_chip *chip); +int release_sd_card(struct rtsx_chip *chip); +#ifdef SUPPORT_CPRM +int soft_reset_sd_card(struct rtsx_chip *chip); +int ext_sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx, + u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, int special_check); +int ext_sd_get_rsp(struct rtsx_chip *chip, int len, u8 *rsp, u8 rsp_type); + +int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int sd_hw_rst(struct scsi_cmnd *srb, struct rtsx_chip *chip); +#endif + +#endif /* __REALTEK_RTSX_SD_H */ diff --git a/drivers/staging/rts_pstor/spi.c b/drivers/staging/rts_pstor/spi.c new file mode 100644 index 000000000000..84e0af42ca18 --- /dev/null +++ b/drivers/staging/rts_pstor/spi.c @@ -0,0 +1,847 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include +#include +#include + +#include "rtsx.h" +#include "rtsx_transport.h" +#include "rtsx_scsi.h" +#include "rtsx_card.h" +#include "spi.h" + +static inline void spi_set_err_code(struct rtsx_chip *chip, u8 err_code) +{ + struct spi_info *spi = &(chip->spi); + + spi->err_code = err_code; +} + +static int spi_init(struct rtsx_chip *chip) +{ + RTSX_WRITE_REG(chip, SPI_CONTROL, 0xFF, + CS_POLARITY_LOW | DTO_MSB_FIRST | SPI_MASTER | SPI_MODE0 | SPI_AUTO); + RTSX_WRITE_REG(chip, SPI_TCTL, EDO_TIMING_MASK, SAMPLE_DELAY_HALF); + + return STATUS_SUCCESS; +} + +static int spi_set_init_para(struct rtsx_chip *chip) +{ + struct spi_info *spi = &(chip->spi); + int retval; + + RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER1, 0xFF, (u8)(spi->clk_div >> 8)); + RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER0, 0xFF, (u8)(spi->clk_div)); + + retval = switch_clock(chip, spi->spi_clock); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = select_card(chip, SPI_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, CARD_CLK_EN, SPI_CLK_EN, SPI_CLK_EN); + RTSX_WRITE_REG(chip, CARD_OE, SPI_OUTPUT_EN, SPI_OUTPUT_EN); + + wait_timeout(10); + + retval = spi_init(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sf_polling_status(struct rtsx_chip *chip, int msec) +{ + int retval; + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, SPI_RDSR); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_POLLING_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, msec); + if (retval < 0) { + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_BUSY_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sf_enable_write(struct rtsx_chip *chip, u8 ins) +{ + struct spi_info *spi = &(chip->spi); + int retval; + + if (!spi->write_en) + return STATUS_SUCCESS; + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) { + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sf_disable_write(struct rtsx_chip *chip, u8 ins) +{ + struct spi_info *spi = &(chip->spi); + int retval; + + if (!spi->write_en) + return STATUS_SUCCESS; + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) { + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static void sf_program(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr, u16 len) +{ + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, (u8)len); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, (u8)(len >> 8)); + if (addr_mode) { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CADO_MODE0); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CDO_MODE0); + } + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); +} + +static int sf_erase(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr) +{ + int retval; + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); + if (addr_mode) { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0); + } + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) { + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int spi_init_eeprom(struct rtsx_chip *chip) +{ + int retval; + int clk; + + if (chip->asic_code) { + clk = 30; + } else { + clk = CLK_30; + } + + RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER1, 0xFF, 0x00); + RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER0, 0xFF, 0x27); + + retval = switch_clock(chip, clk); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = select_card(chip, SPI_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, CARD_CLK_EN, SPI_CLK_EN, SPI_CLK_EN); + RTSX_WRITE_REG(chip, CARD_OE, SPI_OUTPUT_EN, SPI_OUTPUT_EN); + + wait_timeout(10); + + RTSX_WRITE_REG(chip, SPI_CONTROL, 0xFF, CS_POLARITY_HIGH | SPI_EEPROM_AUTO); + RTSX_WRITE_REG(chip, SPI_TCTL, EDO_TIMING_MASK, SAMPLE_DELAY_HALF); + + return STATUS_SUCCESS; +} + +int spi_eeprom_program_enable(struct rtsx_chip *chip) +{ + int retval; + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x86); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x13); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int spi_erase_eeprom_chip(struct rtsx_chip *chip) +{ + int retval; + + retval = spi_init_eeprom(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = spi_eeprom_program_enable(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x12); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x84); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01); + + return STATUS_SUCCESS; +} + +int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr) +{ + int retval; + + retval = spi_init_eeprom(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = spi_eeprom_program_enable(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x07); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01); + + return STATUS_SUCCESS; +} + + +int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val) +{ + int retval; + u8 data; + + retval = spi_init_eeprom(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x06); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CADI_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + + wait_timeout(5); + RTSX_READ_REG(chip, SPI_DATA, &data); + + if (val) { + *val = data; + } + + RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01); + + return STATUS_SUCCESS; +} + +int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val) +{ + int retval; + + retval = spi_init_eeprom(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = spi_eeprom_program_enable(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x05); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, val); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)addr); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x4E); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01); + + return STATUS_SUCCESS; +} + + +int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct spi_info *spi = &(chip->spi); + + RTSX_DEBUGP("spi_get_status: err_code = 0x%x\n", spi->err_code); + rtsx_stor_set_xfer_buf(&(spi->err_code), min((int)scsi_bufflen(srb), 1), srb); + scsi_set_resid(srb, scsi_bufflen(srb) - 1); + + return STATUS_SUCCESS; +} + +int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + struct spi_info *spi = &(chip->spi); + + spi_set_err_code(chip, SPI_NO_ERR); + + if (chip->asic_code) { + spi->spi_clock = ((u16)(srb->cmnd[8]) << 8) | srb->cmnd[9]; + } else { + spi->spi_clock = srb->cmnd[3]; + } + + spi->clk_div = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; + spi->write_en = srb->cmnd[6]; + + RTSX_DEBUGP("spi_set_parameter: spi_clock = %d, clk_div = %d, write_en = %d\n", + spi->spi_clock, spi->clk_div, spi->write_en); + + return STATUS_SUCCESS; +} + +int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + u16 len; + u8 *buf; + + spi_set_err_code(chip, SPI_NO_ERR); + + len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; + if (len > 512) { + spi_set_err_code(chip, SPI_INVALID_COMMAND); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = spi_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, srb->cmnd[3]); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, srb->cmnd[4]); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, srb->cmnd[5]); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, srb->cmnd[6]); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, srb->cmnd[7]); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, srb->cmnd[8]); + + if (len == 0) { + if (srb->cmnd[9]) { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, + 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, + 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0); + } + } else { + if (srb->cmnd[9]) { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, + 0xFF, SPI_TRANSFER0_START | SPI_CADI_MODE0); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, + 0xFF, SPI_TRANSFER0_START | SPI_CDI_MODE0); + } + } + + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) { + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + if (len) { + buf = (u8 *)kmalloc(len, GFP_KERNEL); + if (!buf) { + TRACE_RET(chip, STATUS_ERROR); + } + + retval = rtsx_read_ppbuf(chip, buf, len); + if (retval != STATUS_SUCCESS) { + spi_set_err_code(chip, SPI_READ_ERR); + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); + scsi_set_resid(srb, 0); + + kfree(buf); + } + + return STATUS_SUCCESS; +} + +int spi_read_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + unsigned int index = 0, offset = 0; + u8 ins, slow_read; + u32 addr; + u16 len; + u8 *buf; + + spi_set_err_code(chip, SPI_NO_ERR); + + ins = srb->cmnd[3]; + addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) << 8) | srb->cmnd[6]; + len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; + slow_read = srb->cmnd[9]; + + retval = spi_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + buf = (u8 *)rtsx_alloc_dma_buf(chip, SF_PAGE_LEN, GFP_KERNEL); + if (buf == NULL) { + TRACE_RET(chip, STATUS_ERROR); + } + + while (len) { + u16 pagelen = SF_PAGE_LEN - (u8)addr; + + if (pagelen > len) { + pagelen = len; + } + + rtsx_init_cmd(chip); + + trans_dma_enable(DMA_FROM_DEVICE, chip, 256, DMA_256); + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); + + if (slow_read) { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)addr); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR3, 0xFF, (u8)(addr >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_32); + } + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, (u8)(pagelen >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, (u8)pagelen); + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CADI_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); + + rtsx_send_cmd_no_wait(chip); + + retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0, DMA_FROM_DEVICE, 10000); + if (retval < 0) { + rtsx_free_dma_buf(chip, buf); + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index, &offset, TO_XFER_BUF); + + addr += pagelen; + len -= pagelen; + } + + scsi_set_resid(srb, 0); + rtsx_free_dma_buf(chip, buf); + + return STATUS_SUCCESS; +} + +int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + u8 ins, program_mode; + u32 addr; + u16 len; + u8 *buf; + unsigned int index = 0, offset = 0; + + spi_set_err_code(chip, SPI_NO_ERR); + + ins = srb->cmnd[3]; + addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) << 8) | srb->cmnd[6]; + len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; + program_mode = srb->cmnd[9]; + + retval = spi_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + if (program_mode == BYTE_PROGRAM) { + buf = rtsx_alloc_dma_buf(chip, 4, GFP_KERNEL); + if (!buf) { + TRACE_RET(chip, STATUS_ERROR); + } + + while (len) { + retval = sf_enable_write(chip, SPI_WREN); + if (retval != STATUS_SUCCESS) { + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset, FROM_XFER_BUF); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, buf[0]); + sf_program(chip, ins, 1, addr, 1); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) { + rtsx_free_dma_buf(chip, buf); + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sf_polling_status(chip, 100); + if (retval != STATUS_SUCCESS) { + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + + addr++; + len--; + } + + rtsx_free_dma_buf(chip, buf); + + } else if (program_mode == AAI_PROGRAM) { + int first_byte = 1; + + retval = sf_enable_write(chip, SPI_WREN); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + buf = rtsx_alloc_dma_buf(chip, 4, GFP_KERNEL); + if (!buf) { + TRACE_RET(chip, STATUS_ERROR); + } + + while (len) { + rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset, FROM_XFER_BUF); + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, buf[0]); + if (first_byte) { + sf_program(chip, ins, 1, addr, 1); + first_byte = 0; + } else { + sf_program(chip, ins, 0, 0, 1); + } + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval < 0) { + rtsx_free_dma_buf(chip, buf); + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sf_polling_status(chip, 100); + if (retval != STATUS_SUCCESS) { + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + + len--; + } + + rtsx_free_dma_buf(chip, buf); + + retval = sf_disable_write(chip, SPI_WRDI); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sf_polling_status(chip, 100); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else if (program_mode == PAGE_PROGRAM) { + buf = rtsx_alloc_dma_buf(chip, SF_PAGE_LEN, GFP_KERNEL); + if (!buf) { + TRACE_RET(chip, STATUS_NOMEM); + } + + while (len) { + u16 pagelen = SF_PAGE_LEN - (u8)addr; + + if (pagelen > len) { + pagelen = len; + } + + retval = sf_enable_write(chip, SPI_WREN); + if (retval != STATUS_SUCCESS) { + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + trans_dma_enable(DMA_TO_DEVICE, chip, 256, DMA_256); + sf_program(chip, ins, 1, addr, pagelen); + + rtsx_send_cmd_no_wait(chip); + + rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index, &offset, FROM_XFER_BUF); + + retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0, DMA_TO_DEVICE, 100); + if (retval < 0) { + rtsx_free_dma_buf(chip, buf); + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sf_polling_status(chip, 100); + if (retval != STATUS_SUCCESS) { + rtsx_free_dma_buf(chip, buf); + TRACE_RET(chip, STATUS_FAIL); + } + + addr += pagelen; + len -= pagelen; + } + + rtsx_free_dma_buf(chip, buf); + } else { + spi_set_err_code(chip, SPI_INVALID_COMMAND); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + u8 ins, erase_mode; + u32 addr; + + spi_set_err_code(chip, SPI_NO_ERR); + + ins = srb->cmnd[3]; + addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) << 8) | srb->cmnd[6]; + erase_mode = srb->cmnd[9]; + + retval = spi_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + if (erase_mode == PAGE_ERASE) { + retval = sf_enable_write(chip, SPI_WREN); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sf_erase(chip, ins, 1, addr); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else if (erase_mode == CHIP_ERASE) { + retval = sf_enable_write(chip, SPI_WREN); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sf_erase(chip, ins, 0, 0); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + spi_set_err_code(chip, SPI_INVALID_COMMAND); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) +{ + int retval; + u8 ins, status, ewsr; + + ins = srb->cmnd[3]; + status = srb->cmnd[4]; + ewsr = srb->cmnd[5]; + + retval = spi_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sf_enable_write(chip, ewsr); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); + + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1); + rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, status); + rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CDO_MODE0); + rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); + + retval = rtsx_send_cmd(chip, 0, 100); + if (retval != STATUS_SUCCESS) { + rtsx_clear_spi_error(chip); + spi_set_err_code(chip, SPI_HW_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + diff --git a/drivers/staging/rts_pstor/spi.h b/drivers/staging/rts_pstor/spi.h new file mode 100644 index 000000000000..b59291f8b201 --- /dev/null +++ b/drivers/staging/rts_pstor/spi.h @@ -0,0 +1,65 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __REALTEK_RTSX_SPI_H +#define __REALTEK_RTSX_SPI_H + +/* SPI operation error */ +#define SPI_NO_ERR 0x00 +#define SPI_HW_ERR 0x01 +#define SPI_INVALID_COMMAND 0x02 +#define SPI_READ_ERR 0x03 +#define SPI_WRITE_ERR 0x04 +#define SPI_ERASE_ERR 0x05 +#define SPI_BUSY_ERR 0x06 + +/* Serial flash instruction */ +#define SPI_READ 0x03 +#define SPI_FAST_READ 0x0B +#define SPI_WREN 0x06 +#define SPI_WRDI 0x04 +#define SPI_RDSR 0x05 + +#define SF_PAGE_LEN 256 + +#define BYTE_PROGRAM 0 +#define AAI_PROGRAM 1 +#define PAGE_PROGRAM 2 + +#define PAGE_ERASE 0 +#define CHIP_ERASE 1 + +int spi_erase_eeprom_chip(struct rtsx_chip *chip); +int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr); +int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val); +int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val); +int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int spi_read_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip); +int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip); + + +#endif /* __REALTEK_RTSX_SPI_H */ diff --git a/drivers/staging/rts_pstor/trace.h b/drivers/staging/rts_pstor/trace.h new file mode 100644 index 000000000000..1b8958948f9e --- /dev/null +++ b/drivers/staging/rts_pstor/trace.h @@ -0,0 +1,118 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __REALTEK_RTSX_TRACE_H +#define __REALTEK_RTSX_TRACE_H + +#define _MSG_TRACE + +#ifdef _MSG_TRACE +static inline char *filename(char *path) +{ + char *ptr; + + if (path == NULL) { + return NULL; + } + + ptr = path; + + while (*ptr != '\0') { + if ((*ptr == '\\') || (*ptr == '/')) { + path = ptr + 1; + } + ptr++; + } + + return path; +} + +#define TRACE_RET(chip, ret) \ +do { \ + char *_file = filename(__FILE__); \ + RTSX_DEBUGP("[%s][%s]:[%d]\n", _file, __func__, __LINE__); \ + (chip)->trace_msg[(chip)->msg_idx].line = (u16)(__LINE__); \ + strncpy((chip)->trace_msg[(chip)->msg_idx].func, __func__, MSG_FUNC_LEN-1); \ + strncpy((chip)->trace_msg[(chip)->msg_idx].file, _file, MSG_FILE_LEN-1); \ + get_current_time((chip)->trace_msg[(chip)->msg_idx].timeval_buf, TIME_VAL_LEN); \ + (chip)->trace_msg[(chip)->msg_idx].valid = 1; \ + (chip)->msg_idx++; \ + if ((chip)->msg_idx >= TRACE_ITEM_CNT) { \ + (chip)->msg_idx = 0; \ + } \ + return ret; \ +} while (0) + +#define TRACE_GOTO(chip, label) \ +do { \ + char *_file = filename(__FILE__); \ + RTSX_DEBUGP("[%s][%s]:[%d]\n", _file, __func__, __LINE__); \ + (chip)->trace_msg[(chip)->msg_idx].line = (u16)(__LINE__); \ + strncpy((chip)->trace_msg[(chip)->msg_idx].func, __func__, MSG_FUNC_LEN-1); \ + strncpy((chip)->trace_msg[(chip)->msg_idx].file, _file, MSG_FILE_LEN-1); \ + get_current_time((chip)->trace_msg[(chip)->msg_idx].timeval_buf, TIME_VAL_LEN); \ + (chip)->trace_msg[(chip)->msg_idx].valid = 1; \ + (chip)->msg_idx++; \ + if ((chip)->msg_idx >= TRACE_ITEM_CNT) { \ + (chip)->msg_idx = 0; \ + } \ + goto label; \ +} while (0) +#else +#define TRACE_RET(chip, ret) return ret +#define TRACE_GOTO(chip, label) goto label +#endif + +#if CONFIG_RTS_PSTOR_DEBUG +static inline void rtsx_dump(u8 *buf, int buf_len) +{ + int i; + u8 tmp[16] = {0}; + u8 *_ptr = buf; + + for (i = 0; i < ((buf_len)/16); i++) { + RTSX_DEBUGP("%02x %02x %02x %02x %02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x %02x\n", + _ptr[0], _ptr[1], _ptr[2], _ptr[3], _ptr[4], _ptr[5], + _ptr[6], _ptr[7], _ptr[8], _ptr[9], _ptr[10], _ptr[11], + _ptr[12], _ptr[13], _ptr[14], _ptr[15]); + _ptr += 16; + } + if ((buf_len) % 16) { + memcpy(tmp, _ptr, (buf_len) % 16); + _ptr = tmp; + RTSX_DEBUGP("%02x %02x %02x %02x %02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x %02x\n", + _ptr[0], _ptr[1], _ptr[2], _ptr[3], _ptr[4], _ptr[5], + _ptr[6], _ptr[7], _ptr[8], _ptr[9], _ptr[10], _ptr[11], + _ptr[12], _ptr[13], _ptr[14], _ptr[15]); + } +} + +#define RTSX_DUMP(buf, buf_len) rtsx_dump((u8 *)(buf), (buf_len)) + +#else +#define RTSX_DUMP(buf, buf_len) +#endif + +#endif /* __REALTEK_RTSX_TRACE_H */ diff --git a/drivers/staging/rts_pstor/xd.c b/drivers/staging/rts_pstor/xd.c new file mode 100644 index 000000000000..f654c8b031c5 --- /dev/null +++ b/drivers/staging/rts_pstor/xd.c @@ -0,0 +1,2140 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include +#include +#include + +#include "rtsx.h" +#include "rtsx_transport.h" +#include "rtsx_scsi.h" +#include "rtsx_card.h" +#include "xd.h" + +static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no); +static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk, u16 logoff, u8 start_page, u8 end_page); + +static inline void xd_set_err_code(struct rtsx_chip *chip, u8 err_code) +{ + struct xd_info *xd_card = &(chip->xd_card); + + xd_card->err_code = err_code; +} + +static inline int xd_check_err_code(struct rtsx_chip *chip, u8 err_code) +{ + struct xd_info *xd_card = &(chip->xd_card); + + return (xd_card->err_code == err_code); +} + +static int xd_set_init_para(struct rtsx_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval; + + if (chip->asic_code) { + xd_card->xd_clock = 47; + } else { + xd_card->xd_clock = CLK_50; + } + + retval = switch_clock(chip, xd_card->xd_clock); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int xd_switch_clock(struct rtsx_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval; + + retval = select_card(chip, XD_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = switch_clock(chip, xd_card->xd_clock); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int xd_read_id(struct rtsx_chip *chip, u8 id_cmd, u8 *id_buf, u8 buf_len) +{ + int retval, i; + u8 *ptr; + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, id_cmd); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_READ_ID); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); + + for (i = 0; i < 4; i++) { + rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_ADDRESS1 + i), 0, 0); + } + + retval = rtsx_send_cmd(chip, XD_CARD, 20); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + + ptr = rtsx_get_cmd_data(chip) + 1; + if (id_buf && buf_len) { + if (buf_len > 4) + buf_len = 4; + memcpy(id_buf, ptr, buf_len); + } + + return STATUS_SUCCESS; +} + +static void xd_assign_phy_addr(struct rtsx_chip *chip, u32 addr, u8 mode) +{ + struct xd_info *xd_card = &(chip->xd_card); + + switch (mode) { + case XD_RW_ADDR: + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1, 0xFF, (u8)addr); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2, 0xFF, (u8)(addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS3, 0xFF, (u8)(addr >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, 0xFF, + xd_card->addr_cycle | XD_CALC_ECC | XD_BA_NO_TRANSFORM); + break; + + case XD_ERASE_ADDR: + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, (u8)addr); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1, 0xFF, (u8)(addr >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2, 0xFF, (u8)(addr >> 16)); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, 0xFF, + (xd_card->addr_cycle - 1) | XD_CALC_ECC | XD_BA_NO_TRANSFORM); + break; + + default: + break; + } +} + +static int xd_read_redundant(struct rtsx_chip *chip, u32 page_addr, u8 *buf, int buf_len) +{ + int retval, i; + + rtsx_init_cmd(chip); + + xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_READ_REDUNDANT); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); + + for (i = 0; i < 6; i++) { + rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_PAGE_STATUS + i), 0, 0); + } + for (i = 0; i < 4; i++) { + rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_RESERVED0 + i), 0, 0); + } + rtsx_add_cmd(chip, READ_REG_CMD, XD_PARITY, 0, 0); + + retval = rtsx_send_cmd(chip, XD_CARD, 500); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (buf && buf_len) { + u8 *ptr = rtsx_get_cmd_data(chip) + 1; + + if (buf_len > 11) + buf_len = 11; + memcpy(buf, ptr, buf_len); + } + + return STATUS_SUCCESS; +} + +static int xd_read_data_from_ppb(struct rtsx_chip *chip, int offset, u8 *buf, int buf_len) +{ + int retval, i; + + if (!buf || (buf_len < 0)) { + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + for (i = 0; i < buf_len; i++) { + rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + offset + i, 0, 0); + } + + retval = rtsx_send_cmd(chip, 0, 250); + if (retval < 0) { + rtsx_clear_xd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + memcpy(buf, rtsx_get_cmd_data(chip), buf_len); + + return STATUS_SUCCESS; +} + +static int xd_read_cis(struct rtsx_chip *chip, u32 page_addr, u8 *buf, int buf_len) +{ + int retval; + u8 reg; + + if (!buf || (buf_len < 10)) { + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_READ_PAGES); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); + + retval = rtsx_send_cmd(chip, XD_CARD, 250); + if (retval == -ETIMEDOUT) { + rtsx_clear_xd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_READ_REG(chip, XD_PAGE_STATUS, ®); + if (reg != XD_GPG) { + rtsx_clear_xd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_READ_REG(chip, XD_CTL, ®); + if (!(reg & XD_ECC1_ERROR) || !(reg & XD_ECC1_UNCORRECTABLE)) { + retval = xd_read_data_from_ppb(chip, 0, buf, buf_len); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + if (reg & XD_ECC1_ERROR) { + u8 ecc_bit, ecc_byte; + + RTSX_READ_REG(chip, XD_ECC_BIT1, &ecc_bit); + RTSX_READ_REG(chip, XD_ECC_BYTE1, &ecc_byte); + + RTSX_DEBUGP("ECC_BIT1 = 0x%x, ECC_BYTE1 = 0x%x\n", ecc_bit, ecc_byte); + if (ecc_byte < buf_len) { + RTSX_DEBUGP("Before correct: 0x%x\n", buf[ecc_byte]); + buf[ecc_byte] ^= (1 << ecc_bit); + RTSX_DEBUGP("After correct: 0x%x\n", buf[ecc_byte]); + } + } + } else if (!(reg & XD_ECC2_ERROR) || !(reg & XD_ECC2_UNCORRECTABLE)) { + rtsx_clear_xd_error(chip); + + retval = xd_read_data_from_ppb(chip, 256, buf, buf_len); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + if (reg & XD_ECC2_ERROR) { + u8 ecc_bit, ecc_byte; + + RTSX_READ_REG(chip, XD_ECC_BIT2, &ecc_bit); + RTSX_READ_REG(chip, XD_ECC_BYTE2, &ecc_byte); + + RTSX_DEBUGP("ECC_BIT2 = 0x%x, ECC_BYTE2 = 0x%x\n", ecc_bit, ecc_byte); + if (ecc_byte < buf_len) { + RTSX_DEBUGP("Before correct: 0x%x\n", buf[ecc_byte]); + buf[ecc_byte] ^= (1 << ecc_bit); + RTSX_DEBUGP("After correct: 0x%x\n", buf[ecc_byte]); + } + } + } else { + rtsx_clear_xd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static void xd_fill_pull_ctl_disable(struct rtsx_chip *chip) +{ + if (CHECK_PID(chip, 0x5209)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0xD5); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x15); + } else if (CHECK_PID(chip, 0x5208)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, + XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, + XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, + XD_WP_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, + XD_RDY_PD | XD_WE_PD | XD_RE_PD | XD_ALE_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, + MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, MS_D5_PD | MS_D4_PD); + } else if (CHECK_PID(chip, 0x5288)) { + if (CHECK_BARO_PKG(chip, QFN)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x4B); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x69); + } + } +} + +static void xd_fill_pull_ctl_stage1_barossa(struct rtsx_chip *chip) +{ + if (CHECK_BARO_PKG(chip, QFN)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x4B); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); + } +} + +static void xd_fill_pull_ctl_enable(struct rtsx_chip *chip) +{ + if (CHECK_PID(chip, 0x5209)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0xAA); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0xD5); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x15); + } else if (CHECK_PID(chip, 0x5208)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, + XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, + XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, + XD_WP_PD | XD_CE_PU | XD_CLE_PD | XD_CD_PU); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, + XD_RDY_PU | XD_WE_PU | XD_RE_PU | XD_ALE_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, + MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, MS_D5_PD | MS_D4_PD); + } else if (CHECK_PID(chip, 0x5288)) { + if (CHECK_BARO_PKG(chip, QFN)) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x53); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0xA9); + } + } +} + +static int xd_pull_ctl_disable(struct rtsx_chip *chip) +{ + if (CHECK_PID(chip, 0x5209)) { + RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0xD5); + RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF, 0x15); + } else if (CHECK_PID(chip, 0x5208)) { + RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, + XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, + XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, + XD_WP_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU); + RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, + XD_RDY_PD | XD_WE_PD | XD_RE_PD | XD_ALE_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, + MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); + RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF, MS_D5_PD | MS_D4_PD); + } else if (CHECK_PID(chip, 0x5288)) { + if (CHECK_BARO_PKG(chip, QFN)) { + RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55); + RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0x4B); + RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x69); + } + } + + return STATUS_SUCCESS; +} + +static void xd_clear_dma_buffer(struct rtsx_chip *chip) +{ + if (CHECK_PID(chip, 0x5209)) { + int retval; + u8 *buf; + + RTSX_DEBUGP("xD ECC error, dummy write!\n"); + + buf = (u8 *)rtsx_alloc_dma_buf(chip, 512, GFP_KERNEL); + if (!buf) { + return; + } + + rtsx_init_cmd(chip); + + trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_SELECT, 0x07, SD_MOD_SEL); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, SD_CLK_EN, SD_CLK_EN); + if (chip->asic_code) { + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0xAA); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, + FPGA_SD_PULL_CTL_BIT, 0); + } + + rtsx_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x00); + rtsx_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 0x02); + rtsx_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1); + rtsx_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x03, SD_BUS_WIDTH_4); + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); + + rtsx_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, + SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); + rtsx_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + + retval = rtsx_transfer_data(chip, SD_CARD, buf, 512, 0, DMA_TO_DEVICE, 100); + if (retval < 0) { + u8 val; + + rtsx_read_register(chip, SD_STAT1, &val); + RTSX_DEBUGP("SD_STAT1: 0x%x\n", val); + + rtsx_read_register(chip, SD_STAT2, &val); + RTSX_DEBUGP("SD_STAT2: 0x%x\n", val); + + rtsx_read_register(chip, SD_BUS_STAT, &val); + RTSX_DEBUGP("SD_BUS_STAT: 0x%x\n", val); + + rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR); + } + + rtsx_free_dma_buf(chip, buf); + + if (chip->asic_code) { + rtsx_write_register(chip, CARD_PULL_CTL2, 0xFF, 0x55); + } else { + rtsx_write_register(chip, FPGA_PULL_CTL, + FPGA_SD_PULL_CTL_BIT, FPGA_SD_PULL_CTL_BIT); + } + rtsx_write_register(chip, CARD_SELECT, 0x07, XD_MOD_SEL); + rtsx_write_register(chip, CARD_CLK_EN, SD_CLK_EN, 0); + } +} + +static int reset_xd(struct rtsx_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval, i, j; + u8 *ptr, id_buf[4], redunt[11]; + + retval = select_card(chip, XD_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, 0xFF, XD_PGSTS_NOT_FF); + if (chip->asic_code) { + if (!CHECK_PID(chip, 0x5288)) { + xd_fill_pull_ctl_disable(chip); + } else { + xd_fill_pull_ctl_stage1_barossa(chip); + } + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, + (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN3) | 0x20); + } + + if (!chip->ft2_fast_mode) { + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_INIT, XD_NO_AUTO_PWR_OFF, 0); + } + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, 0); + + retval = rtsx_send_cmd(chip, XD_CARD, 100); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (!chip->ft2_fast_mode) { + retval = card_power_off(chip, XD_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + wait_timeout(250); + + if (CHECK_PID(chip, 0x5209)) { + RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0xAA); + } + + rtsx_init_cmd(chip); + + if (chip->asic_code) { + xd_fill_pull_ctl_enable(chip); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, + (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN2) | 0x20); + } + + retval = rtsx_send_cmd(chip, XD_CARD, 100); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = card_power_on(chip, XD_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + +#ifdef SUPPORT_OCP + wait_timeout(50); + if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { + RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", chip->ocp_stat); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + } + + rtsx_init_cmd(chip); + + if (chip->ft2_fast_mode) { + if (chip->asic_code) { + xd_fill_pull_ctl_enable(chip); + } else { + rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, + (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN2) | 0x20); + } + } + + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, XD_OUTPUT_EN); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CTL, XD_CE_DISEN, XD_CE_DISEN); + + retval = rtsx_send_cmd(chip, XD_CARD, 100); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (!chip->ft2_fast_mode) { + wait_timeout(200); + } + + retval = xd_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + /* Read ID to check if the timing setting is right */ + for (i = 0; i < 4; i++) { + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DTCTL, 0xFF, + XD_TIME_SETUP_STEP * 3 + XD_TIME_RW_STEP * (2 + i) + XD_TIME_RWN_STEP * i); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CATCTL, 0xFF, + XD_TIME_SETUP_STEP * 3 + XD_TIME_RW_STEP * (4 + i) + XD_TIME_RWN_STEP * (3 + i)); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_RESET); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); + + rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); + rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0); + + retval = rtsx_send_cmd(chip, XD_CARD, 100); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + + ptr = rtsx_get_cmd_data(chip) + 1; + + RTSX_DEBUGP("XD_DAT: 0x%x, XD_CTL: 0x%x\n", ptr[0], ptr[1]); + + if (((ptr[0] & READY_FLAG) != READY_STATE) || !(ptr[1] & XD_RDY)) { + continue; + } + + retval = xd_read_id(chip, READ_ID, id_buf, 4); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_DEBUGP("READ_ID: 0x%x 0x%x 0x%x 0x%x\n", + id_buf[0], id_buf[1], id_buf[2], id_buf[3]); + + xd_card->device_code = id_buf[1]; + + /* Check if the xD card is supported */ + switch (xd_card->device_code) { + case XD_4M_X8_512_1: + case XD_4M_X8_512_2: + xd_card->block_shift = 4; + xd_card->page_off = 0x0F; + xd_card->addr_cycle = 3; + xd_card->zone_cnt = 1; + xd_card->capacity = 8000; + XD_SET_4MB(xd_card); + break; + case XD_8M_X8_512: + xd_card->block_shift = 4; + xd_card->page_off = 0x0F; + xd_card->addr_cycle = 3; + xd_card->zone_cnt = 1; + xd_card->capacity = 16000; + break; + case XD_16M_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 3; + xd_card->zone_cnt = 1; + xd_card->capacity = 32000; + break; + case XD_32M_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 3; + xd_card->zone_cnt = 2; + xd_card->capacity = 64000; + break; + case XD_64M_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 4; + xd_card->zone_cnt = 4; + xd_card->capacity = 128000; + break; + case XD_128M_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 4; + xd_card->zone_cnt = 8; + xd_card->capacity = 256000; + break; + case XD_256M_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 4; + xd_card->zone_cnt = 16; + xd_card->capacity = 512000; + break; + case XD_512M_X8: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 4; + xd_card->zone_cnt = 32; + xd_card->capacity = 1024000; + break; + case xD_1G_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 4; + xd_card->zone_cnt = 64; + xd_card->capacity = 2048000; + break; + case xD_2G_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 4; + xd_card->zone_cnt = 128; + xd_card->capacity = 4096000; + break; + default: + continue; + } + + /* Confirm timing setting */ + for (j = 0; j < 10; j++) { + retval = xd_read_id(chip, READ_ID, id_buf, 4); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (id_buf[1] != xd_card->device_code) + break; + } + + if (j == 10) + break; + } + + if (i == 4) { + xd_card->block_shift = 0; + xd_card->page_off = 0; + xd_card->addr_cycle = 0; + xd_card->capacity = 0; + + TRACE_RET(chip, STATUS_FAIL); + } + + retval = xd_read_id(chip, READ_xD_ID, id_buf, 4); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + RTSX_DEBUGP("READ_xD_ID: 0x%x 0x%x 0x%x 0x%x\n", + id_buf[0], id_buf[1], id_buf[2], id_buf[3]); + if (id_buf[2] != XD_ID_CODE) { + TRACE_RET(chip, STATUS_FAIL); + } + + /* Search CIS block */ + for (i = 0; i < 24; i++) { + u32 page_addr; + + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + page_addr = (u32)i << xd_card->block_shift; + + for (j = 0; j < 3; j++) { + retval = xd_read_redundant(chip, page_addr, redunt, 11); + if (retval == STATUS_SUCCESS) { + break; + } + } + if (j == 3) { + continue; + } + + if (redunt[BLOCK_STATUS] != XD_GBLK) + continue; + + j = 0; + if (redunt[PAGE_STATUS] != XD_GPG) { + for (j = 1; j <= 8; j++) { + retval = xd_read_redundant(chip, page_addr + j, redunt, 11); + if (retval == STATUS_SUCCESS) { + if (redunt[PAGE_STATUS] == XD_GPG) { + break; + } + } + } + + if (j == 9) + break; + } + + /* Check CIS data */ + if ((redunt[BLOCK_STATUS] == XD_GBLK) && (redunt[PARITY] & XD_BA1_ALL0)) { + u8 buf[10]; + + page_addr += j; + + retval = xd_read_cis(chip, page_addr, buf, 10); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if ((buf[0] == 0x01) && (buf[1] == 0x03) && (buf[2] == 0xD9) + && (buf[3] == 0x01) && (buf[4] == 0xFF) + && (buf[5] == 0x18) && (buf[6] == 0x02) + && (buf[7] == 0xDF) && (buf[8] == 0x01) + && (buf[9] == 0x20)) { + xd_card->cis_block = (u16)i; + } + } + + break; + } + + RTSX_DEBUGP("CIS block: 0x%x\n", xd_card->cis_block); + if (xd_card->cis_block == 0xFFFF) { + TRACE_RET(chip, STATUS_FAIL); + } + + chip->capacity[chip->card2lun[XD_CARD]] = xd_card->capacity; + + return STATUS_SUCCESS; +} + +static int xd_check_data_blank(u8 *redunt) +{ + int i; + + for (i = 0; i < 6; i++) { + if (redunt[PAGE_STATUS + i] != 0xFF) + return 0; + } + + if ((redunt[PARITY] & (XD_ECC1_ALL1 | XD_ECC2_ALL1)) != (XD_ECC1_ALL1 | XD_ECC2_ALL1)) { + return 0; + } + + for (i = 0; i < 4; i++) { + if (redunt[RESERVED0 + i] != 0xFF) + return 0; + } + + return 1; +} + +static u16 xd_load_log_block_addr(u8 *redunt) +{ + u16 addr = 0xFFFF; + + if (redunt[PARITY] & XD_BA1_BA2_EQL) { + addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) | redunt[BLOCK_ADDR1_L]; + } else if (redunt[PARITY] & XD_BA1_VALID) { + addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) | redunt[BLOCK_ADDR1_L]; + } else if (redunt[PARITY] & XD_BA2_VALID) { + addr = ((u16)redunt[BLOCK_ADDR2_H] << 8) | redunt[BLOCK_ADDR2_L]; + } + + return addr; +} + +static int xd_init_l2p_tbl(struct rtsx_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int size, i; + + RTSX_DEBUGP("xd_init_l2p_tbl: zone_cnt = %d\n", xd_card->zone_cnt); + + if (xd_card->zone_cnt < 1) { + TRACE_RET(chip, STATUS_FAIL); + } + + size = xd_card->zone_cnt * sizeof(struct zone_entry); + RTSX_DEBUGP("Buffer size for l2p table is %d\n", size); + + xd_card->zone = (struct zone_entry *)vmalloc(size); + if (!xd_card->zone) { + TRACE_RET(chip, STATUS_ERROR); + } + + for (i = 0; i < xd_card->zone_cnt; i++) { + xd_card->zone[i].build_flag = 0; + xd_card->zone[i].l2p_table = NULL; + xd_card->zone[i].free_table = NULL; + xd_card->zone[i].get_index = 0; + xd_card->zone[i].set_index = 0; + xd_card->zone[i].unused_blk_cnt = 0; + } + + return STATUS_SUCCESS; +} + +static inline void free_zone(struct zone_entry *zone) +{ + RTSX_DEBUGP("free_zone\n"); + + if (!zone) + return; + + zone->build_flag = 0; + zone->set_index = 0; + zone->get_index = 0; + zone->unused_blk_cnt = 0; + if (zone->l2p_table) { + vfree(zone->l2p_table); + zone->l2p_table = NULL; + } + if (zone->free_table) { + vfree(zone->free_table); + zone->free_table = NULL; + } +} + +static void xd_set_unused_block(struct rtsx_chip *chip, u32 phy_blk) +{ + struct xd_info *xd_card = &(chip->xd_card); + struct zone_entry *zone; + int zone_no; + + zone_no = (int)phy_blk >> 10; + if (zone_no >= xd_card->zone_cnt) { + RTSX_DEBUGP("Set unused block to invalid zone (zone_no = %d, zone_cnt = %d)\n", + zone_no, xd_card->zone_cnt); + return; + } + zone = &(xd_card->zone[zone_no]); + + if (zone->free_table == NULL) { + if (xd_build_l2p_tbl(chip, zone_no) != STATUS_SUCCESS) { + return; + } + } + + if ((zone->set_index >= XD_FREE_TABLE_CNT) + || (zone->set_index < 0)) { + free_zone(zone); + RTSX_DEBUGP("Set unused block fail, invalid set_index\n"); + return; + } + + RTSX_DEBUGP("Set unused block to index %d\n", zone->set_index); + + zone->free_table[zone->set_index++] = (u16) (phy_blk & 0x3ff); + if (zone->set_index >= XD_FREE_TABLE_CNT) { + zone->set_index = 0; + } + zone->unused_blk_cnt++; +} + +static u32 xd_get_unused_block(struct rtsx_chip *chip, int zone_no) +{ + struct xd_info *xd_card = &(chip->xd_card); + struct zone_entry *zone; + u32 phy_blk; + + if (zone_no >= xd_card->zone_cnt) { + RTSX_DEBUGP("Get unused block from invalid zone (zone_no = %d, zone_cnt = %d)\n", + zone_no, xd_card->zone_cnt); + return BLK_NOT_FOUND; + } + zone = &(xd_card->zone[zone_no]); + + if ((zone->unused_blk_cnt == 0) || (zone->set_index == zone->get_index)) { + free_zone(zone); + RTSX_DEBUGP("Get unused block fail, no unused block available\n"); + return BLK_NOT_FOUND; + } + if ((zone->get_index >= XD_FREE_TABLE_CNT) || (zone->get_index < 0)) { + free_zone(zone); + RTSX_DEBUGP("Get unused block fail, invalid get_index\n"); + return BLK_NOT_FOUND; + } + + RTSX_DEBUGP("Get unused block from index %d\n", zone->get_index); + + phy_blk = zone->free_table[zone->get_index]; + zone->free_table[zone->get_index++] = 0xFFFF; + if (zone->get_index >= XD_FREE_TABLE_CNT) { + zone->get_index = 0; + } + zone->unused_blk_cnt--; + + phy_blk += ((u32)(zone_no) << 10); + return phy_blk; +} + +static void xd_set_l2p_tbl(struct rtsx_chip *chip, int zone_no, u16 log_off, u16 phy_off) +{ + struct xd_info *xd_card = &(chip->xd_card); + struct zone_entry *zone; + + zone = &(xd_card->zone[zone_no]); + zone->l2p_table[log_off] = phy_off; +} + +static u32 xd_get_l2p_tbl(struct rtsx_chip *chip, int zone_no, u16 log_off) +{ + struct xd_info *xd_card = &(chip->xd_card); + struct zone_entry *zone; + int retval; + + zone = &(xd_card->zone[zone_no]); + if (zone->l2p_table[log_off] == 0xFFFF) { + u32 phy_blk = 0; + int i; + +#ifdef XD_DELAY_WRITE + retval = xd_delay_write(chip); + if (retval != STATUS_SUCCESS) { + RTSX_DEBUGP("In xd_get_l2p_tbl, delay write fail!\n"); + return BLK_NOT_FOUND; + } +#endif + + if (zone->unused_blk_cnt <= 0) { + RTSX_DEBUGP("No unused block!\n"); + return BLK_NOT_FOUND; + } + + for (i = 0; i < zone->unused_blk_cnt; i++) { + phy_blk = xd_get_unused_block(chip, zone_no); + if (phy_blk == BLK_NOT_FOUND) { + RTSX_DEBUGP("No unused block available!\n"); + return BLK_NOT_FOUND; + } + + retval = xd_init_page(chip, phy_blk, log_off, 0, xd_card->page_off + 1); + if (retval == STATUS_SUCCESS) + break; + } + if (i >= zone->unused_blk_cnt) { + RTSX_DEBUGP("No good unused block available!\n"); + return BLK_NOT_FOUND; + } + + xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(phy_blk & 0x3FF)); + return phy_blk; + } + + return (u32)zone->l2p_table[log_off] + ((u32)(zone_no) << 10); +} + +int reset_xd_card(struct rtsx_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval; + + memset(xd_card, 0, sizeof(struct xd_info)); + + xd_card->block_shift = 0; + xd_card->page_off = 0; + xd_card->addr_cycle = 0; + xd_card->capacity = 0; + xd_card->zone_cnt = 0; + xd_card->cis_block = 0xFFFF; + xd_card->delay_write.delay_write_flag = 0; + + retval = enable_card_clock(chip, XD_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = reset_xd(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + retval = xd_init_l2p_tbl(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int xd_mark_bad_block(struct rtsx_chip *chip, u32 phy_blk) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval; + u32 page_addr; + u8 reg = 0; + + RTSX_DEBUGP("mark block 0x%x as bad block\n", phy_blk); + + if (phy_blk == BLK_NOT_FOUND) { + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_LATER_BBLK); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, 0xFF); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, 0xFF); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_H, 0xFF, 0xFF); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_L, 0xFF, 0xFF); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED0, 0xFF, 0xFF); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED1, 0xFF, 0xFF); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED2, 0xFF, 0xFF); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED3, 0xFF, 0xFF); + + page_addr = phy_blk << xd_card->block_shift; + + xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, xd_card->page_off + 1); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_WRITE_REDUNDANT); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); + + retval = rtsx_send_cmd(chip, XD_CARD, 500); + if (retval < 0) { + rtsx_clear_xd_error(chip); + rtsx_read_register(chip, XD_DAT, ®); + if (reg & PROGRAM_ERROR) { + xd_set_err_code(chip, XD_PRG_ERROR); + } else { + xd_set_err_code(chip, XD_TO_ERROR); + } + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk, u16 logoff, u8 start_page, u8 end_page) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval; + u32 page_addr; + u8 reg = 0; + + RTSX_DEBUGP("Init block 0x%x\n", phy_blk); + + if (start_page > end_page) { + TRACE_RET(chip, STATUS_FAIL); + } + if (phy_blk == BLK_NOT_FOUND) { + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, 0xFF); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, 0xFF); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, (u8)(logoff >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, (u8)logoff); + + page_addr = (phy_blk << xd_card->block_shift) + start_page; + + xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_BA_TRANSFORM, XD_BA_TRANSFORM); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, (end_page - start_page)); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_WRITE_REDUNDANT); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); + + retval = rtsx_send_cmd(chip, XD_CARD, 500); + if (retval < 0) { + rtsx_clear_xd_error(chip); + rtsx_read_register(chip, XD_DAT, ®); + if (reg & PROGRAM_ERROR) { + xd_mark_bad_block(chip, phy_blk); + xd_set_err_code(chip, XD_PRG_ERROR); + } else { + xd_set_err_code(chip, XD_TO_ERROR); + } + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int xd_copy_page(struct rtsx_chip *chip, u32 old_blk, u32 new_blk, u8 start_page, u8 end_page) +{ + struct xd_info *xd_card = &(chip->xd_card); + u32 old_page, new_page; + u8 i, reg = 0; + int retval; + + RTSX_DEBUGP("Copy page from block 0x%x to block 0x%x\n", old_blk, new_blk); + + if (start_page > end_page) { + TRACE_RET(chip, STATUS_FAIL); + } + + if ((old_blk == BLK_NOT_FOUND) || (new_blk == BLK_NOT_FOUND)) { + TRACE_RET(chip, STATUS_FAIL); + } + + old_page = (old_blk << xd_card->block_shift) + start_page; + new_page = (new_blk << xd_card->block_shift) + start_page; + + XD_CLR_BAD_NEWBLK(xd_card); + + RTSX_WRITE_REG(chip, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); + + for (i = start_page; i < end_page; i++) { + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + rtsx_clear_xd_error(chip); + xd_set_err_code(chip, XD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + xd_assign_phy_addr(chip, old_page, XD_RW_ADDR); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS, 0); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_READ_PAGES); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); + + retval = rtsx_send_cmd(chip, XD_CARD, 500); + if (retval < 0) { + rtsx_clear_xd_error(chip); + reg = 0; + rtsx_read_register(chip, XD_CTL, ®); + if (reg & (XD_ECC1_ERROR | XD_ECC2_ERROR)) { + wait_timeout(100); + + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + xd_set_err_code(chip, XD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + if (((reg & (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) == + (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) + || ((reg & (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE)) == + (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))) { + rtsx_write_register(chip, XD_PAGE_STATUS, 0xFF, XD_BPG); + rtsx_write_register(chip, XD_BLOCK_STATUS, 0xFF, XD_GBLK); + XD_SET_BAD_OLDBLK(xd_card); + RTSX_DEBUGP("old block 0x%x ecc error\n", old_blk); + } + } else { + xd_set_err_code(chip, XD_TO_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (XD_CHK_BAD_OLDBLK(xd_card)) { + rtsx_clear_xd_error(chip); + } + + rtsx_init_cmd(chip); + + xd_assign_phy_addr(chip, new_page, XD_RW_ADDR); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_WRITE_PAGES); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); + + retval = rtsx_send_cmd(chip, XD_CARD, 300); + if (retval < 0) { + rtsx_clear_xd_error(chip); + reg = 0; + rtsx_read_register(chip, XD_DAT, ®); + if (reg & PROGRAM_ERROR) { + xd_mark_bad_block(chip, new_blk); + xd_set_err_code(chip, XD_PRG_ERROR); + XD_SET_BAD_NEWBLK(xd_card); + } else { + xd_set_err_code(chip, XD_TO_ERROR); + } + TRACE_RET(chip, STATUS_FAIL); + } + + old_page++; + new_page++; + } + + return STATUS_SUCCESS; +} + +static int xd_reset_cmd(struct rtsx_chip *chip) +{ + int retval; + u8 *ptr; + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_RESET); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); + rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); + rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0); + + retval = rtsx_send_cmd(chip, XD_CARD, 100); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + + ptr = rtsx_get_cmd_data(chip) + 1; + if (((ptr[0] & READY_FLAG) == READY_STATE) && (ptr[1] & XD_RDY)) { + return STATUS_SUCCESS; + } + + TRACE_RET(chip, STATUS_FAIL); +} + +static int xd_erase_block(struct rtsx_chip *chip, u32 phy_blk) +{ + struct xd_info *xd_card = &(chip->xd_card); + u32 page_addr; + u8 reg = 0, *ptr; + int i, retval; + + if (phy_blk == BLK_NOT_FOUND) { + TRACE_RET(chip, STATUS_FAIL); + } + + page_addr = phy_blk << xd_card->block_shift; + + for (i = 0; i < 3; i++) { + rtsx_init_cmd(chip); + + xd_assign_phy_addr(chip, page_addr, XD_ERASE_ADDR); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_ERASE); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); + rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); + + retval = rtsx_send_cmd(chip, XD_CARD, 250); + if (retval < 0) { + rtsx_clear_xd_error(chip); + rtsx_read_register(chip, XD_DAT, ®); + if (reg & PROGRAM_ERROR) { + xd_mark_bad_block(chip, phy_blk); + xd_set_err_code(chip, XD_PRG_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } else { + xd_set_err_code(chip, XD_ERASE_FAIL); + } + retval = xd_reset_cmd(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + continue; + } + + ptr = rtsx_get_cmd_data(chip) + 1; + if (*ptr & PROGRAM_ERROR) { + xd_mark_bad_block(chip, phy_blk); + xd_set_err_code(chip, XD_PRG_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; + } + + xd_mark_bad_block(chip, phy_blk); + xd_set_err_code(chip, XD_ERASE_FAIL); + TRACE_RET(chip, STATUS_FAIL); +} + + +static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no) +{ + struct xd_info *xd_card = &(chip->xd_card); + struct zone_entry *zone; + int retval; + u32 start, end, i; + u16 max_logoff, cur_fst_page_logoff, cur_lst_page_logoff, ent_lst_page_logoff; + u8 redunt[11]; + + RTSX_DEBUGP("xd_build_l2p_tbl: %d\n", zone_no); + + if (xd_card->zone == NULL) { + retval = xd_init_l2p_tbl(chip); + if (retval != STATUS_SUCCESS) { + return retval; + } + } + + if (xd_card->zone[zone_no].build_flag) { + RTSX_DEBUGP("l2p table of zone %d has been built\n", zone_no); + return STATUS_SUCCESS; + } + + zone = &(xd_card->zone[zone_no]); + + if (zone->l2p_table == NULL) { + zone->l2p_table = (u16 *)vmalloc(2000); + if (zone->l2p_table == NULL) { + TRACE_GOTO(chip, Build_Fail); + } + } + memset((u8 *)(zone->l2p_table), 0xff, 2000); + + if (zone->free_table == NULL) { + zone->free_table = (u16 *)vmalloc(XD_FREE_TABLE_CNT * 2); + if (zone->free_table == NULL) { + TRACE_GOTO(chip, Build_Fail); + } + } + memset((u8 *)(zone->free_table), 0xff, XD_FREE_TABLE_CNT * 2); + + if (zone_no == 0) { + if (xd_card->cis_block == 0xFFFF) { + start = 0; + } else { + start = xd_card->cis_block + 1; + } + if (XD_CHK_4MB(xd_card)) { + end = 0x200; + max_logoff = 499; + } else { + end = 0x400; + max_logoff = 999; + } + } else { + start = (u32)(zone_no) << 10; + end = (u32)(zone_no + 1) << 10; + max_logoff = 999; + } + + RTSX_DEBUGP("start block 0x%x, end block 0x%x\n", start, end); + + zone->set_index = zone->get_index = 0; + zone->unused_blk_cnt = 0; + + for (i = start; i < end; i++) { + u32 page_addr = i << xd_card->block_shift; + u32 phy_block; + + retval = xd_read_redundant(chip, page_addr, redunt, 11); + if (retval != STATUS_SUCCESS) { + continue; + } + + if (redunt[BLOCK_STATUS] != 0xFF) { + RTSX_DEBUGP("bad block\n"); + continue; + } + + if (xd_check_data_blank(redunt)) { + RTSX_DEBUGP("blank block\n"); + xd_set_unused_block(chip, i); + continue; + } + + cur_fst_page_logoff = xd_load_log_block_addr(redunt); + if ((cur_fst_page_logoff == 0xFFFF) || (cur_fst_page_logoff > max_logoff)) { + retval = xd_erase_block(chip, i); + if (retval == STATUS_SUCCESS) { + xd_set_unused_block(chip, i); + } + continue; + } + + if ((zone_no == 0) && (cur_fst_page_logoff == 0) && (redunt[PAGE_STATUS] != XD_GPG)) { + XD_SET_MBR_FAIL(xd_card); + } + + if (zone->l2p_table[cur_fst_page_logoff] == 0xFFFF) { + zone->l2p_table[cur_fst_page_logoff] = (u16)(i & 0x3FF); + continue; + } + + phy_block = zone->l2p_table[cur_fst_page_logoff] + ((u32)((zone_no) << 10)); + + page_addr = ((i + 1) << xd_card->block_shift) - 1; + + retval = xd_read_redundant(chip, page_addr, redunt, 11); + if (retval != STATUS_SUCCESS) { + continue; + } + + cur_lst_page_logoff = xd_load_log_block_addr(redunt); + if (cur_lst_page_logoff == cur_fst_page_logoff) { + int m; + + page_addr = ((phy_block + 1) << xd_card->block_shift) - 1; + + for (m = 0; m < 3; m++) { + retval = xd_read_redundant(chip, page_addr, redunt, 11); + if (retval == STATUS_SUCCESS) + break; + } + + if (m == 3) { + zone->l2p_table[cur_fst_page_logoff] = (u16)(i & 0x3FF); + retval = xd_erase_block(chip, phy_block); + if (retval == STATUS_SUCCESS) { + xd_set_unused_block(chip, phy_block); + } + continue; + } + + ent_lst_page_logoff = xd_load_log_block_addr(redunt); + if (ent_lst_page_logoff != cur_fst_page_logoff) { + zone->l2p_table[cur_fst_page_logoff] = (u16)(i & 0x3FF); + retval = xd_erase_block(chip, phy_block); + if (retval == STATUS_SUCCESS) { + xd_set_unused_block(chip, phy_block); + } + continue; + } else { + retval = xd_erase_block(chip, i); + if (retval == STATUS_SUCCESS) { + xd_set_unused_block(chip, i); + } + } + } else { + retval = xd_erase_block(chip, i); + if (retval == STATUS_SUCCESS) { + xd_set_unused_block(chip, i); + } + } + } + + if (XD_CHK_4MB(xd_card)) { + end = 500; + } else { + end = 1000; + } + + i = 0; + for (start = 0; start < end; start++) { + if (zone->l2p_table[start] == 0xFFFF) { + i++; + } + } + + RTSX_DEBUGP("Block count %d, invalid L2P entry %d\n", end, i); + RTSX_DEBUGP("Total unused block: %d\n", zone->unused_blk_cnt); + + if ((zone->unused_blk_cnt - i) < 1) { + chip->card_wp |= XD_CARD; + } + + zone->build_flag = 1; + + return STATUS_SUCCESS; + +Build_Fail: + if (zone->l2p_table) { + vfree(zone->l2p_table); + zone->l2p_table = NULL; + } + if (zone->free_table) { + vfree(zone->free_table); + zone->free_table = NULL; + } + + return STATUS_FAIL; +} + +static int xd_send_cmd(struct rtsx_chip *chip, u8 cmd) +{ + int retval; + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, cmd); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_SET_CMD); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); + + retval = rtsx_send_cmd(chip, XD_CARD, 200); + if (retval < 0) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int xd_read_multiple_pages(struct rtsx_chip *chip, u32 phy_blk, u32 log_blk, + u8 start_page, u8 end_page, u8 *buf, unsigned int *index, unsigned int *offset) +{ + struct xd_info *xd_card = &(chip->xd_card); + u32 page_addr, new_blk; + u16 log_off; + u8 reg_val, page_cnt; + int zone_no, retval, i; + + if (start_page > end_page) { + TRACE_RET(chip, STATUS_FAIL); + } + + page_cnt = end_page - start_page; + zone_no = (int)(log_blk / 1000); + log_off = (u16)(log_blk % 1000); + + if ((phy_blk & 0x3FF) == 0x3FF) { + for (i = 0; i < 256; i++) { + page_addr = ((u32)i) << xd_card->block_shift; + + retval = xd_read_redundant(chip, page_addr, NULL, 0); + if (retval == STATUS_SUCCESS) + break; + + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + xd_set_err_code(chip, XD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + page_addr = (phy_blk << xd_card->block_shift) + start_page; + + rtsx_init_cmd(chip); + + xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_PPB_TO_SIE, XD_PPB_TO_SIE); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, + XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS); + + trans_dma_enable(chip->srb->sc_data_direction, chip, page_cnt * 512, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_READ_PAGES); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, + XD_TRANSFER_END | XD_PPB_EMPTY, XD_TRANSFER_END | XD_PPB_EMPTY); + + rtsx_send_cmd_no_wait(chip); + + retval = rtsx_transfer_data_partial(chip, XD_CARD, buf, page_cnt * 512, scsi_sg_count(chip->srb), + index, offset, DMA_FROM_DEVICE, chip->xd_timeout); + if (retval < 0) { + rtsx_clear_xd_error(chip); + xd_clear_dma_buffer(chip); + + if (retval == -ETIMEDOUT) { + xd_set_err_code(chip, XD_TO_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } else { + TRACE_GOTO(chip, Fail); + } + } + + return STATUS_SUCCESS; + +Fail: + RTSX_READ_REG(chip, XD_PAGE_STATUS, ®_val); + + if (reg_val != XD_GPG) { + xd_set_err_code(chip, XD_PRG_ERROR); + } + + RTSX_READ_REG(chip, XD_CTL, ®_val); + + if (((reg_val & (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) + == (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) + || ((reg_val & (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE)) + == (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))) { + wait_timeout(100); + + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + xd_set_err_code(chip, XD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + xd_set_err_code(chip, XD_ECC_ERROR); + + new_blk = xd_get_unused_block(chip, zone_no); + if (new_blk == NO_NEW_BLK) { + XD_CLR_BAD_OLDBLK(xd_card); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = xd_copy_page(chip, phy_blk, new_blk, 0, xd_card->page_off + 1); + if (retval != STATUS_SUCCESS) { + if (!XD_CHK_BAD_NEWBLK(xd_card)) { + retval = xd_erase_block(chip, new_blk); + if (retval == STATUS_SUCCESS) { + xd_set_unused_block(chip, new_blk); + } + } else { + XD_CLR_BAD_NEWBLK(xd_card); + } + XD_CLR_BAD_OLDBLK(xd_card); + TRACE_RET(chip, STATUS_FAIL); + } + xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF)); + xd_erase_block(chip, phy_blk); + xd_mark_bad_block(chip, phy_blk); + XD_CLR_BAD_OLDBLK(xd_card); + } + + TRACE_RET(chip, STATUS_FAIL); +} + +static int xd_finish_write(struct rtsx_chip *chip, + u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval, zone_no; + u16 log_off; + + RTSX_DEBUGP("xd_finish_write, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n", + old_blk, new_blk, log_blk); + + if (page_off > xd_card->page_off) { + TRACE_RET(chip, STATUS_FAIL); + } + + zone_no = (int)(log_blk / 1000); + log_off = (u16)(log_blk % 1000); + + if (old_blk == BLK_NOT_FOUND) { + retval = xd_init_page(chip, new_blk, log_off, + page_off, xd_card->page_off + 1); + if (retval != STATUS_SUCCESS) { + retval = xd_erase_block(chip, new_blk); + if (retval == STATUS_SUCCESS) { + xd_set_unused_block(chip, new_blk); + } + TRACE_RET(chip, STATUS_FAIL); + } + } else { + retval = xd_copy_page(chip, old_blk, new_blk, + page_off, xd_card->page_off + 1); + if (retval != STATUS_SUCCESS) { + if (!XD_CHK_BAD_NEWBLK(xd_card)) { + retval = xd_erase_block(chip, new_blk); + if (retval == STATUS_SUCCESS) { + xd_set_unused_block(chip, new_blk); + } + } + XD_CLR_BAD_NEWBLK(xd_card); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = xd_erase_block(chip, old_blk); + if (retval == STATUS_SUCCESS) { + if (XD_CHK_BAD_OLDBLK(xd_card)) { + xd_mark_bad_block(chip, old_blk); + XD_CLR_BAD_OLDBLK(xd_card); + } else { + xd_set_unused_block(chip, old_blk); + } + } else { + xd_set_err_code(chip, XD_NO_ERROR); + XD_CLR_BAD_OLDBLK(xd_card); + } + } + + xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF)); + + return STATUS_SUCCESS; +} + +static int xd_prepare_write(struct rtsx_chip *chip, + u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off) +{ + int retval; + + RTSX_DEBUGP("%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x, page_off = %d\n", + __func__, old_blk, new_blk, log_blk, (int)page_off); + + if (page_off) { + retval = xd_copy_page(chip, old_blk, new_blk, 0, page_off); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + + +static int xd_write_multiple_pages(struct rtsx_chip *chip, u32 old_blk, u32 new_blk, u32 log_blk, + u8 start_page, u8 end_page, u8 *buf, unsigned int *index, unsigned int *offset) +{ + struct xd_info *xd_card = &(chip->xd_card); + u32 page_addr; + int zone_no, retval; + u16 log_off; + u8 page_cnt, reg_val; + + RTSX_DEBUGP("%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n", + __func__, old_blk, new_blk, log_blk); + + if (start_page > end_page) { + TRACE_RET(chip, STATUS_FAIL); + } + + page_cnt = end_page - start_page; + zone_no = (int)(log_blk / 1000); + log_off = (u16)(log_blk % 1000); + + page_addr = (new_blk << xd_card->block_shift) + start_page; + + retval = xd_send_cmd(chip, READ1_1); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + rtsx_init_cmd(chip); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, (u8)(log_off >> 8)); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, (u8)log_off); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_GBLK); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG); + + xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_BA_TRANSFORM, XD_BA_TRANSFORM); + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt); + rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); + + trans_dma_enable(chip->srb->sc_data_direction, chip, page_cnt * 512, DMA_512); + + rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_WRITE_PAGES); + rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); + + rtsx_send_cmd_no_wait(chip); + + retval = rtsx_transfer_data_partial(chip, XD_CARD, buf, page_cnt * 512, scsi_sg_count(chip->srb), + index, offset, DMA_TO_DEVICE, chip->xd_timeout); + if (retval < 0) { + rtsx_clear_xd_error(chip); + + if (retval == -ETIMEDOUT) { + xd_set_err_code(chip, XD_TO_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } else { + TRACE_GOTO(chip, Fail); + } + } + + if (end_page == (xd_card->page_off + 1)) { + xd_card->delay_write.delay_write_flag = 0; + + if (old_blk != BLK_NOT_FOUND) { + retval = xd_erase_block(chip, old_blk); + if (retval == STATUS_SUCCESS) { + if (XD_CHK_BAD_OLDBLK(xd_card)) { + xd_mark_bad_block(chip, old_blk); + XD_CLR_BAD_OLDBLK(xd_card); + } else { + xd_set_unused_block(chip, old_blk); + } + } else { + xd_set_err_code(chip, XD_NO_ERROR); + XD_CLR_BAD_OLDBLK(xd_card); + } + } + xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF)); + } + + return STATUS_SUCCESS; + +Fail: + RTSX_READ_REG(chip, XD_DAT, ®_val); + if (reg_val & PROGRAM_ERROR) { + xd_set_err_code(chip, XD_PRG_ERROR); + xd_mark_bad_block(chip, new_blk); + } + + TRACE_RET(chip, STATUS_FAIL); +} + +#ifdef XD_DELAY_WRITE +int xd_delay_write(struct rtsx_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + struct xd_delay_write_tag *delay_write = &(xd_card->delay_write); + int retval; + + if (delay_write->delay_write_flag) { + RTSX_DEBUGP("xd_delay_write\n"); + retval = xd_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + delay_write->delay_write_flag = 0; + retval = xd_finish_write(chip, + delay_write->old_phyblock, delay_write->new_phyblock, + delay_write->logblock, delay_write->pageoff); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} +#endif + +int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt) +{ + struct xd_info *xd_card = &(chip->xd_card); + unsigned int lun = SCSI_LUN(srb); +#ifdef XD_DELAY_WRITE + struct xd_delay_write_tag *delay_write = &(xd_card->delay_write); +#endif + int retval, zone_no; + unsigned int index = 0, offset = 0; + u32 log_blk, old_blk = 0, new_blk = 0; + u16 log_off, total_sec_cnt = sector_cnt; + u8 start_page, end_page = 0, page_cnt; + u8 *ptr; + + xd_set_err_code(chip, XD_NO_ERROR); + + xd_card->cleanup_counter = 0; + + RTSX_DEBUGP("xd_rw: scsi_sg_count = %d\n", scsi_sg_count(srb)); + + ptr = (u8 *)scsi_sglist(srb); + + retval = xd_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + chip->card_fail |= XD_CARD; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + + log_blk = start_sector >> xd_card->block_shift; + start_page = (u8)start_sector & xd_card->page_off; + zone_no = (int)(log_blk / 1000); + log_off = (u16)(log_blk % 1000); + + if (xd_card->zone[zone_no].build_flag == 0) { + retval = xd_build_l2p_tbl(chip, zone_no); + if (retval != STATUS_SUCCESS) { + chip->card_fail |= XD_CARD; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (srb->sc_data_direction == DMA_TO_DEVICE) { +#ifdef XD_DELAY_WRITE + if (delay_write->delay_write_flag && + (delay_write->logblock == log_blk) && + (start_page > delay_write->pageoff)) { + delay_write->delay_write_flag = 0; + if (delay_write->old_phyblock != BLK_NOT_FOUND) { + retval = xd_copy_page(chip, + delay_write->old_phyblock, + delay_write->new_phyblock, + delay_write->pageoff, start_page); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } + old_blk = delay_write->old_phyblock; + new_blk = delay_write->new_phyblock; + } else if (delay_write->delay_write_flag && + (delay_write->logblock == log_blk) && + (start_page == delay_write->pageoff)) { + delay_write->delay_write_flag = 0; + old_blk = delay_write->old_phyblock; + new_blk = delay_write->new_phyblock; + } else { + retval = xd_delay_write(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); + new_blk = xd_get_unused_block(chip, zone_no); + if ((old_blk == BLK_NOT_FOUND) || (new_blk == BLK_NOT_FOUND)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = xd_prepare_write(chip, old_blk, new_blk, log_blk, start_page); + if (retval != STATUS_SUCCESS) { + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } +#ifdef XD_DELAY_WRITE + } +#endif + } else { +#ifdef XD_DELAY_WRITE + retval = xd_delay_write(chip); + if (retval != STATUS_SUCCESS) { + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + + old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); + if (old_blk == BLK_NOT_FOUND) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + RTSX_DEBUGP("old_blk = 0x%x\n", old_blk); + + while (total_sec_cnt) { + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + chip->card_fail |= XD_CARD; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + + if ((start_page + total_sec_cnt) > (xd_card->page_off + 1)) { + end_page = xd_card->page_off + 1; + } else { + end_page = start_page + (u8)total_sec_cnt; + } + page_cnt = end_page - start_page; + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + retval = xd_read_multiple_pages(chip, old_blk, log_blk, + start_page, end_page, ptr, &index, &offset); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } else { + retval = xd_write_multiple_pages(chip, old_blk, new_blk, log_blk, + start_page, end_page, ptr, &index, &offset); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + total_sec_cnt -= page_cnt; + if (scsi_sg_count(srb) == 0) + ptr += page_cnt * 512; + + if (total_sec_cnt == 0) + break; + + log_blk++; + zone_no = (int)(log_blk / 1000); + log_off = (u16)(log_blk % 1000); + + if (xd_card->zone[zone_no].build_flag == 0) { + retval = xd_build_l2p_tbl(chip, zone_no); + if (retval != STATUS_SUCCESS) { + chip->card_fail |= XD_CARD; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + } + + old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); + if (old_blk == BLK_NOT_FOUND) { + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + } + TRACE_RET(chip, STATUS_FAIL); + } + + if (srb->sc_data_direction == DMA_TO_DEVICE) { + new_blk = xd_get_unused_block(chip, zone_no); + if (new_blk == BLK_NOT_FOUND) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + start_page = 0; + } + + if ((srb->sc_data_direction == DMA_TO_DEVICE) && + (end_page != (xd_card->page_off + 1))) { +#ifdef XD_DELAY_WRITE + delay_write->delay_write_flag = 1; + delay_write->old_phyblock = old_blk; + delay_write->new_phyblock = new_blk; + delay_write->logblock = log_blk; + delay_write->pageoff = end_page; +#else + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + chip->card_fail |= XD_CARD; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = xd_finish_write(chip, old_blk, new_blk, log_blk, end_page); + if (retval != STATUS_SUCCESS) { + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + } + + scsi_set_resid(srb, 0); + + return STATUS_SUCCESS; +} + +void xd_free_l2p_tbl(struct rtsx_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int i = 0; + + if (xd_card->zone != NULL) { + for (i = 0; i < xd_card->zone_cnt; i++) { + if (xd_card->zone[i].l2p_table != NULL) { + vfree(xd_card->zone[i].l2p_table); + xd_card->zone[i].l2p_table = NULL; + } + if (xd_card->zone[i].free_table != NULL) { + vfree(xd_card->zone[i].free_table); + xd_card->zone[i].free_table = NULL; + } + } + vfree(xd_card->zone); + xd_card->zone = NULL; + } +} + +void xd_cleanup_work(struct rtsx_chip *chip) +{ +#ifdef XD_DELAY_WRITE + struct xd_info *xd_card = &(chip->xd_card); + + if (xd_card->delay_write.delay_write_flag) { + RTSX_DEBUGP("xD: delay write\n"); + xd_delay_write(chip); + xd_card->cleanup_counter = 0; + } +#endif +} + +int xd_power_off_card3v3(struct rtsx_chip *chip) +{ + int retval; + + retval = disable_card_clock(chip, XD_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + RTSX_WRITE_REG(chip, CARD_OE, XD_OUTPUT_EN, 0); + + if (!chip->ft2_fast_mode) { + retval = card_power_off(chip, XD_CARD); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + wait_timeout(50); + } + + if (chip->asic_code) { + retval = xd_pull_ctl_disable(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + RTSX_WRITE_REG(chip, FPGA_PULL_CTL, 0xFF, 0xDF); + } + + return STATUS_SUCCESS; +} + +int release_xd_card(struct rtsx_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval; + + RTSX_DEBUGP("release_xd_card\n"); + + chip->card_ready &= ~XD_CARD; + chip->card_fail &= ~XD_CARD; + chip->card_wp &= ~XD_CARD; + + xd_card->delay_write.delay_write_flag = 0; + + xd_free_l2p_tbl(chip); + + retval = xd_power_off_card3v3(chip); + if (retval != STATUS_SUCCESS) { + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} diff --git a/drivers/staging/rts_pstor/xd.h b/drivers/staging/rts_pstor/xd.h new file mode 100644 index 000000000000..cd9fbc1f96de --- /dev/null +++ b/drivers/staging/rts_pstor/xd.h @@ -0,0 +1,188 @@ +/* Driver for Realtek PCI-Express card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __REALTEK_RTSX_XD_H +#define __REALTEK_RTSX_XD_H + +#define XD_DELAY_WRITE + +/* Error Codes */ +#define XD_NO_ERROR 0x00 +#define XD_NO_MEMORY 0x80 +#define XD_PRG_ERROR 0x40 +#define XD_NO_CARD 0x20 +#define XD_READ_FAIL 0x10 +#define XD_ERASE_FAIL 0x08 +#define XD_WRITE_FAIL 0x04 +#define XD_ECC_ERROR 0x02 +#define XD_TO_ERROR 0x01 + +/* XD Commands */ +#define READ1_1 0x00 +#define READ1_2 0x01 +#define READ2 0x50 +#define READ_ID 0x90 +#define RESET 0xff +#define PAGE_PRG_1 0x80 +#define PAGE_PRG_2 0x10 +#define BLK_ERASE_1 0x60 +#define BLK_ERASE_2 0xD0 +#define READ_STS 0x70 +#define READ_xD_ID 0x9A +#define COPY_BACK_512 0x8A +#define COPY_BACK_2K 0x85 +#define READ1_1_2 0x30 +#define READ1_1_3 0x35 +#define CHG_DAT_OUT_1 0x05 +#define RDM_DAT_OUT_1 0x05 +#define CHG_DAT_OUT_2 0xE0 +#define RDM_DAT_OUT_2 0xE0 +#define CHG_DAT_OUT_2 0xE0 +#define CHG_DAT_IN_1 0x85 +#define CACHE_PRG 0x15 + +/* Redundant Area Related */ +#define XD_EXTRA_SIZE 0x10 +#define XD_2K_EXTRA_SIZE 0x40 + +#define NOT_WRITE_PROTECTED 0x80 +#define READY_STATE 0x40 +#define PROGRAM_ERROR 0x01 +#define PROGRAM_ERROR_N_1 0x02 +#define INTERNAL_READY 0x20 +#define READY_FLAG 0x5F + +#define XD_8M_X8_512 0xE6 +#define XD_16M_X8_512 0x73 +#define XD_32M_X8_512 0x75 +#define XD_64M_X8_512 0x76 +#define XD_128M_X8_512 0x79 +#define XD_256M_X8_512 0x71 +#define XD_128M_X8_2048 0xF1 +#define XD_256M_X8_2048 0xDA +#define XD_512M_X8 0xDC +#define XD_128M_X16_2048 0xC1 +#define XD_4M_X8_512_1 0xE3 +#define XD_4M_X8_512_2 0xE5 +#define xD_1G_X8_512 0xD3 +#define xD_2G_X8_512 0xD5 + +#define XD_ID_CODE 0xB5 + +#define VENDOR_BLOCK 0xEFFF +#define CIS_BLOCK 0xDFFF + +#define BLK_NOT_FOUND 0xFFFFFFFF + +#define NO_NEW_BLK 0xFFFFFFFF + +#define PAGE_CORRECTABLE 0x0 +#define PAGE_NOTCORRECTABLE 0x1 + +#define NO_OFFSET 0x0 +#define WITH_OFFSET 0x1 + +#define Sect_Per_Page 4 +#define XD_ADDR_MODE_2C XD_ADDR_MODE_2A + +#define ZONE0_BAD_BLOCK 23 +#define NOT_ZONE0_BAD_BLOCK 24 + +#define XD_RW_ADDR 0x01 +#define XD_ERASE_ADDR 0x02 + +#define XD_PAGE_512(xd_card) \ +do { \ + (xd_card)->block_shift = 5; \ + (xd_card)->page_off = 0x1F; \ +} while (0) + +#define XD_SET_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag |= 0x01) +#define XD_CLR_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag &= ~0x01) +#define XD_CHK_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag & 0x01) + +#define XD_SET_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag |= 0x02) +#define XD_CLR_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag &= ~0x02) +#define XD_CHK_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag & 0x02) + +#define XD_SET_MBR_FAIL(xd_card) ((xd_card)->multi_flag |= 0x04) +#define XD_CLR_MBR_FAIL(xd_card) ((xd_card)->multi_flag &= ~0x04) +#define XD_CHK_MBR_FAIL(xd_card) ((xd_card)->multi_flag & 0x04) + +#define XD_SET_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag |= 0x08) +#define XD_CLR_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag &= ~0x08) +#define XD_CHK_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag & 0x08) + +#define XD_SET_4MB(xd_card) ((xd_card)->multi_flag |= 0x10) +#define XD_CLR_4MB(xd_card) ((xd_card)->multi_flag &= ~0x10) +#define XD_CHK_4MB(xd_card) ((xd_card)->multi_flag & 0x10) + +#define XD_SET_ECC_ERR(xd_card) ((xd_card)->multi_flag |= 0x40) +#define XD_CLR_ECC_ERR(xd_card) ((xd_card)->multi_flag &= ~0x40) +#define XD_CHK_ECC_ERR(xd_card) ((xd_card)->multi_flag & 0x40) + +#define PAGE_STATUS 0 +#define BLOCK_STATUS 1 +#define BLOCK_ADDR1_L 2 +#define BLOCK_ADDR1_H 3 +#define BLOCK_ADDR2_L 4 +#define BLOCK_ADDR2_H 5 +#define RESERVED0 6 +#define RESERVED1 7 +#define RESERVED2 8 +#define RESERVED3 9 +#define PARITY 10 + +#define CIS0_0 0 +#define CIS0_1 1 +#define CIS0_2 2 +#define CIS0_3 3 +#define CIS0_4 4 +#define CIS0_5 5 +#define CIS0_6 6 +#define CIS0_7 7 +#define CIS0_8 8 +#define CIS0_9 9 +#define CIS1_0 256 +#define CIS1_1 (256 + 1) +#define CIS1_2 (256 + 2) +#define CIS1_3 (256 + 3) +#define CIS1_4 (256 + 4) +#define CIS1_5 (256 + 5) +#define CIS1_6 (256 + 6) +#define CIS1_7 (256 + 7) +#define CIS1_8 (256 + 8) +#define CIS1_9 (256 + 9) + +int reset_xd_card(struct rtsx_chip *chip); +#ifdef XD_DELAY_WRITE +int xd_delay_write(struct rtsx_chip *chip); +#endif +int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt); +void xd_free_l2p_tbl(struct rtsx_chip *chip); +void xd_cleanup_work(struct rtsx_chip *chip); +int xd_power_off_card3v3(struct rtsx_chip *chip); +int release_xd_card(struct rtsx_chip *chip); + +#endif /* __REALTEK_RTSX_XD_H */ + -- cgit v1.2.3 From 91caec33e50630fc5d1d4f36e12e1eb74cbc02e4 Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Tue, 4 Jan 2011 12:56:27 -0800 Subject: staging: sep: Add comment to TODO to clean up un-needed debug prints Signed-off-by: Mark Allyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/TODO | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/sep/TODO b/drivers/staging/sep/TODO index 089c2406345e..a89e7d6ad0c9 100644 --- a/drivers/staging/sep/TODO +++ b/drivers/staging/sep/TODO @@ -3,3 +3,4 @@ Todo's so far (from Alan Cox) interfaces - Crypto API 'glue' is still not ready to submit - Clean up unused ioctls - Needs vendor help - Clean up unused fields in ioctl structures - Needs vendor help +- Clean up un-needed debug prints - Started to work on this -- cgit v1.2.3 From dfcfc166fe9c5825c506795a3f29471f9bd410a3 Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Tue, 4 Jan 2011 12:57:16 -0800 Subject: staging: sep: Remove un-needed debug prints Signed-off-by: Mark Allyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 223 ++++----------------------------------- 1 file changed, 20 insertions(+), 203 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index ac5d56943d4b..a1b0bfe5e003 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -107,12 +107,8 @@ static int sep_load_firmware(struct sep_device *sep) sep->resident_size = fw->size; release_firmware(fw); - dev_dbg(&sep->pdev->dev, "resident virtual is %p\n", - sep->resident_addr); dev_dbg(&sep->pdev->dev, "resident bus is %lx\n", (unsigned long)sep->resident_bus); - dev_dbg(&sep->pdev->dev, "resident size is %08zx\n", - sep->resident_size); /* Set addresses for dcache (no loading needed) */ work1 = (unsigned long)sep->resident_bus; @@ -141,12 +137,8 @@ static int sep_load_firmware(struct sep_device *sep) sep->cache_size = fw->size; release_firmware(fw); - dev_dbg(&sep->pdev->dev, "cache virtual is %p\n", - sep->cache_addr); dev_dbg(&sep->pdev->dev, "cache bus is %08lx\n", (unsigned long)sep->cache_bus); - dev_dbg(&sep->pdev->dev, "cache size is %08zx\n", - sep->cache_size); /* Set addresses and load extapp */ sep->extapp_bus = sep->cache_bus + (1024 * 370); @@ -162,12 +154,8 @@ static int sep_load_firmware(struct sep_device *sep) sep->extapp_size = fw->size; release_firmware(fw); - dev_dbg(&sep->pdev->dev, "extapp virtual is %p\n", - sep->extapp_addr); dev_dbg(&sep->pdev->dev, "extapp bus is %08llx\n", (unsigned long long)sep->extapp_bus); - dev_dbg(&sep->pdev->dev, "extapp size is %08zx\n", - sep->extapp_size); return error; } @@ -218,7 +206,6 @@ static int sep_map_and_alloc_shared_area(struct sep_device *sep) */ static void sep_unmap_and_free_shared_area(struct sep_device *sep) { - dev_dbg(&sep->pdev->dev, "shared area unmap and free\n"); dma_free_coherent(&sep->pdev->dev, sep->shared_size, sep->shared_addr, sep->shared_bus); } @@ -257,15 +244,11 @@ static int sep_singleton_open(struct inode *inode_ptr, struct file *file_ptr) file_ptr->private_data = sep; - dev_dbg(&sep->pdev->dev, "Singleton open for pid %d\n", current->pid); - - dev_dbg(&sep->pdev->dev, "calling test and set for singleton 0\n"); if (test_and_set_bit(0, &sep->singleton_access_flag)) { error = -EBUSY; goto end_function; } - dev_dbg(&sep->pdev->dev, "sep_singleton_open end\n"); end_function: return error; } @@ -310,8 +293,6 @@ static int sep_singleton_release(struct inode *inode, struct file *filp) { struct sep_device *sep = filp->private_data; - dev_dbg(&sep->pdev->dev, "Singleton release for pid %d\n", - current->pid); clear_bit(0, &sep->singleton_access_flag); return 0; } @@ -337,7 +318,6 @@ static int sep_request_daemon_open(struct inode *inode, struct file *filp) current->pid); /* There is supposed to be only one request daemon */ - dev_dbg(&sep->pdev->dev, "calling test and set for req_dmon open 0\n"); if (test_and_set_bit(0, &sep->request_daemon_open)) error = -EBUSY; return error; @@ -354,7 +334,7 @@ static int sep_request_daemon_release(struct inode *inode, struct file *filp) { struct sep_device *sep = filp->private_data; - dev_dbg(&sep->pdev->dev, "Reques daemon release for pid %d\n", + dev_dbg(&sep->pdev->dev, "Request daemon release for pid %d\n", current->pid); /* Clear the request_daemon_open flag */ @@ -373,9 +353,6 @@ static int sep_req_daemon_send_reply_command_handler(struct sep_device *sep) { unsigned long lck_flags; - dev_dbg(&sep->pdev->dev, - "sep_req_daemon_send_reply_command_handler start\n"); - sep_dump_message(sep); /* Counters are lockable region */ @@ -393,9 +370,6 @@ static int sep_req_daemon_send_reply_command_handler(struct sep_device *sep) "sep_req_daemon_send_reply send_ct %lx reply_ct %lx\n", sep->send_ct, sep->reply_ct); - dev_dbg(&sep->pdev->dev, - "sep_req_daemon_send_reply_command_handler end\n"); - return 0; } @@ -413,8 +387,6 @@ static int sep_free_dma_table_data_handler(struct sep_device *sep) /* Pointer to the current dma_resource struct */ struct sep_dma_resource *dma; - dev_dbg(&sep->pdev->dev, "sep_free_dma_table_data_handler start\n"); - for (dcb_counter = 0; dcb_counter < sep->nr_dcb_creat; dcb_counter++) { dma = &sep->dma_res_arr[dcb_counter]; @@ -473,7 +445,6 @@ static int sep_free_dma_table_data_handler(struct sep_device *sep) sep->nr_dcb_creat = 0; sep->num_lli_tables_created = 0; - dev_dbg(&sep->pdev->dev, "sep_free_dma_table_data_handler end\n"); return 0; } @@ -492,8 +463,6 @@ static int sep_request_daemon_mmap(struct file *filp, dma_addr_t bus_address; int error = 0; - dev_dbg(&sep->pdev->dev, "daemon mmap start\n"); - if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) { error = -EINVAL; goto end_function; @@ -502,9 +471,6 @@ static int sep_request_daemon_mmap(struct file *filp, /* Get physical address */ bus_address = sep->shared_bus; - dev_dbg(&sep->pdev->dev, "bus_address is %08lx\n", - (unsigned long)bus_address); - if (remap_pfn_range(vma, vma->vm_start, bus_address >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) { @@ -514,7 +480,6 @@ static int sep_request_daemon_mmap(struct file *filp, } end_function: - dev_dbg(&sep->pdev->dev, "daemon mmap end\n"); return error; } @@ -535,8 +500,6 @@ static unsigned int sep_request_daemon_poll(struct file *filp, unsigned long lck_flags; struct sep_device *sep = filp->private_data; - dev_dbg(&sep->pdev->dev, "daemon poll: start\n"); - poll_wait(filp, &sep->event_request_daemon, wait); dev_dbg(&sep->pdev->dev, "daemon poll: send_ct is %lx reply ct is %lx\n", @@ -569,7 +532,6 @@ static unsigned int sep_request_daemon_poll(struct file *filp, mask = 0; } end_function: - dev_dbg(&sep->pdev->dev, "daemon poll: exit\n"); return mask; } @@ -592,7 +554,6 @@ static int sep_release(struct inode *inode, struct file *filp) * clear the in use flags, and then wake up sep_event * so that other processes can do transactions */ - dev_dbg(&sep->pdev->dev, "waking up event and mmap_event\n"); if (sep->pid_doing_transaction == current->pid) { clear_bit(SEP_MMAP_LOCK_BIT, &sep->in_use_flags); clear_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags); @@ -618,8 +579,6 @@ static int sep_mmap(struct file *filp, struct vm_area_struct *vma) struct sep_device *sep = filp->private_data; unsigned long error = 0; - dev_dbg(&sep->pdev->dev, "mmap start\n"); - /* Set the transaction busy (own the device) */ wait_event_interruptible(sep->event, test_and_set_bit(SEP_MMAP_LOCK_BIT, @@ -661,16 +620,12 @@ static int sep_mmap(struct file *filp, struct vm_area_struct *vma) /* Get bus address */ bus_addr = sep->shared_bus; - dev_dbg(&sep->pdev->dev, - "bus_address is %lx\n", (unsigned long)bus_addr); - if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) { dev_warn(&sep->pdev->dev, "remap_page_range failed\n"); error = -EAGAIN; goto end_function_with_error; } - dev_dbg(&sep->pdev->dev, "mmap end\n"); goto end_function; end_function_with_error: @@ -682,7 +637,6 @@ end_function_with_error: /* Raise event for stuck contextes */ - dev_warn(&sep->pdev->dev, "mmap error - waking up event\n"); wake_up(&sep->event); end_function: @@ -706,8 +660,6 @@ static unsigned int sep_poll(struct file *filp, poll_table *wait) struct sep_device *sep = filp->private_data; - dev_dbg(&sep->pdev->dev, "poll: start\n"); - /* Am I the process that owns the transaction? */ mutex_lock(&sep->sep_mutex); if (current->pid != sep->pid_doing_transaction) { @@ -720,7 +672,6 @@ static unsigned int sep_poll(struct file *filp, poll_table *wait) /* Check if send command or send_reply were activated previously */ if (!test_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags)) { - dev_warn(&sep->pdev->dev, "poll; lock bit set\n"); mask = POLLERR; goto end_function; } @@ -777,7 +728,6 @@ static unsigned int sep_poll(struct file *filp, poll_table *wait) } end_function: - dev_dbg(&sep->pdev->dev, "poll: end\n"); return mask; } @@ -806,8 +756,6 @@ static unsigned long sep_set_time(struct sep_device *sep) u32 *time_addr; /* Address of time as seen by the kernel */ - dev_dbg(&sep->pdev->dev, "sep_set_time start\n"); - do_gettimeofday(&time); /* Set value in the SYSTEM MEMORY offset */ @@ -838,8 +786,6 @@ static int sep_set_caller_id_handler(struct sep_device *sep, unsigned long arg) int i; struct caller_id_struct command_args; - dev_dbg(&sep->pdev->dev, "sep_set_caller_id_handler start\n"); - for (i = 0; i < SEP_CALLER_ID_TABLE_NUM_ENTRIES; i++) { if (sep->caller_id_table[i].pid == 0) break; @@ -883,7 +829,6 @@ static int sep_set_caller_id_handler(struct sep_device *sep, unsigned long arg) hash, command_args.callerIdSizeInBytes)) error = -EFAULT; end_function: - dev_dbg(&sep->pdev->dev, "sep_set_caller_id_handler end\n"); return error; } @@ -899,9 +844,6 @@ static int sep_set_current_caller_id(struct sep_device *sep) int i; u32 *hash_buf_ptr; - dev_dbg(&sep->pdev->dev, "sep_set_current_caller_id start\n"); - dev_dbg(&sep->pdev->dev, "current process is %d\n", current->pid); - /* Zero the previous value */ memset(sep->shared_addr + SEP_CALLER_ID_OFFSET_BYTES, 0, SEP_CALLER_ID_HASH_SIZE_IN_BYTES); @@ -923,7 +865,6 @@ static int sep_set_current_caller_id(struct sep_device *sep) for (i = 0; i < SEP_CALLER_ID_HASH_SIZE_IN_WORDS; i++) hash_buf_ptr[i] = cpu_to_le32(hash_buf_ptr[i]); - dev_dbg(&sep->pdev->dev, "sep_set_current_caller_id end\n"); return 0; } @@ -941,8 +882,6 @@ static int sep_send_command_handler(struct sep_device *sep) unsigned long lck_flags; int error = 0; - dev_dbg(&sep->pdev->dev, "sep_send_command_handler start\n"); - if (test_and_set_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags)) { error = -EPROTO; goto end_function; @@ -966,7 +905,6 @@ static int sep_send_command_handler(struct sep_device *sep) sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2); end_function: - dev_dbg(&sep->pdev->dev, "sep_send_command_handler end\n"); return error; } @@ -990,9 +928,6 @@ static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, /* Holds the allocated buffer address in the system memory pool */ u32 *token_addr; - dev_dbg(&sep->pdev->dev, - "sep_allocate_data_pool_memory_handler start\n"); - if (copy_from_user(&command_args, (void __user *)arg, sizeof(struct alloc_struct))) { error = -EFAULT; @@ -1007,33 +942,23 @@ static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, } dev_dbg(&sep->pdev->dev, - "bytes_allocated: %x\n", (int)sep->data_pool_bytes_allocated); + "data pool bytes_allocated: %x\n", (int)sep->data_pool_bytes_allocated); dev_dbg(&sep->pdev->dev, "offset: %x\n", SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES); /* Set the virtual and bus address */ command_args.offset = SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep->data_pool_bytes_allocated; - dev_dbg(&sep->pdev->dev, - "command_args.offset: %x\n", command_args.offset); - /* Place in the shared area that is known by the SEP */ token_addr = (u32 *)(sep->shared_addr + SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES + (sep->num_of_data_allocations)*2*sizeof(u32)); - dev_dbg(&sep->pdev->dev, "allocation offset: %x\n", - SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES); - dev_dbg(&sep->pdev->dev, "data pool token addr is %p\n", token_addr); - token_addr[0] = SEP_DATA_POOL_POINTERS_VAL_TOKEN; token_addr[1] = (u32)sep->shared_bus + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep->data_pool_bytes_allocated; - dev_dbg(&sep->pdev->dev, "data pool token [0] %x\n", token_addr[0]); - dev_dbg(&sep->pdev->dev, "data pool token [1] %x\n", token_addr[1]); - /* Write the memory back to the user space */ error = copy_to_user((void *)arg, (void *)&command_args, sizeof(struct alloc_struct)); @@ -1046,11 +971,6 @@ static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, sep->data_pool_bytes_allocated += command_args.num_bytes; sep->num_of_data_allocations += 1; - dev_dbg(&sep->pdev->dev, "data_allocations %d\n", - sep->num_of_data_allocations); - dev_dbg(&sep->pdev->dev, "bytes allocated %d\n", - (int)sep->data_pool_bytes_allocated); - end_function: dev_dbg(&sep->pdev->dev, "sep_allocate_data_pool_memory_handler end\n"); return error; @@ -1083,8 +1003,7 @@ static int sep_lock_kernel_pages(struct sep_device *sep, /* Map array */ struct sep_dma_map *map_array; - dev_dbg(&sep->pdev->dev, "sep_lock_kernel_pages start\n"); - dev_dbg(&sep->pdev->dev, "kernel_virt_addr is %08lx\n", + dev_dbg(&sep->pdev->dev, "lock kernel pages kernel_virt_addr is %08lx\n", (unsigned long)kernel_virt_addr); dev_dbg(&sep->pdev->dev, "data_size is %x\n", data_size); @@ -1137,7 +1056,6 @@ end_function_with_error: kfree(lli_array); end_function: - dev_dbg(&sep->pdev->dev, "sep_lock_kernel_pages end\n"); return error; } @@ -1179,21 +1097,17 @@ static int sep_lock_user_pages(struct sep_device *sep, /* Direction of the DMA mapping for locked pages */ enum dma_data_direction dir; - dev_dbg(&sep->pdev->dev, "sep_lock_user_pages start\n"); - /* Set start and end pages and num pages */ end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT; start_page = app_virt_addr >> PAGE_SHIFT; num_pages = end_page - start_page + 1; - dev_dbg(&sep->pdev->dev, "app_virt_addr is %x\n", app_virt_addr); + dev_dbg(&sep->pdev->dev, "lock user pages app_virt_addr is %x\n", app_virt_addr); dev_dbg(&sep->pdev->dev, "data_size is %x\n", data_size); dev_dbg(&sep->pdev->dev, "start_page is %x\n", start_page); dev_dbg(&sep->pdev->dev, "end_page is %x\n", end_page); dev_dbg(&sep->pdev->dev, "num_pages is %x\n", num_pages); - dev_dbg(&sep->pdev->dev, "starting page_array malloc\n"); - /* Allocate array of pages structure pointers */ page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC); if (!page_array) { @@ -1216,8 +1130,6 @@ static int sep_lock_user_pages(struct sep_device *sep, goto end_function_with_error2; } - dev_dbg(&sep->pdev->dev, "starting get_user_pages\n"); - /* Convert the application virtual address into a set of physical */ down_read(¤t->mm->mmap_sem); result = get_user_pages(current, current->mm, app_virt_addr, @@ -1324,7 +1236,6 @@ end_function_with_error1: kfree(page_array); end_function: - dev_dbg(&sep->pdev->dev, "sep_lock_user_pages end\n"); return error; } @@ -1395,8 +1306,6 @@ static u32 sep_calculate_lli_table_max_size(struct sep_device *sep, table_data_size -= (SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE - next_table_data_size); - dev_dbg(&sep->pdev->dev, "table data size is %x\n", - table_data_size); end_function: return table_data_size; } @@ -1425,14 +1334,12 @@ static void sep_build_lli_table(struct sep_device *sep, /* Counter of lli array entry */ u32 array_counter; - dev_dbg(&sep->pdev->dev, "sep_build_lli_table start\n"); - /* Init currrent table data size and lli array entry counter */ curr_table_data_size = 0; array_counter = 0; *num_table_entries_ptr = 1; - dev_dbg(&sep->pdev->dev, "table_data_size is %x\n", table_data_size); + dev_dbg(&sep->pdev->dev, "build lli table table_data_size is %x\n", table_data_size); /* Fill the table till table size reaches the needed amount */ while (curr_table_data_size < table_data_size) { @@ -1489,19 +1396,9 @@ static void sep_build_lli_table(struct sep_device *sep, lli_table_ptr->bus_address = 0xffffffff; lli_table_ptr->block_size = 0; - dev_dbg(&sep->pdev->dev, "lli_table_ptr is %p\n", lli_table_ptr); - dev_dbg(&sep->pdev->dev, "lli_table_ptr->bus_address is %08lx\n", - (unsigned long)lli_table_ptr->bus_address); - dev_dbg(&sep->pdev->dev, "lli_table_ptr->block_size is %x\n", - lli_table_ptr->block_size); - /* Set the output parameter */ *num_processed_entries_ptr += array_counter; - dev_dbg(&sep->pdev->dev, "num_processed_entries_ptr is %x\n", - *num_processed_entries_ptr); - - dev_dbg(&sep->pdev->dev, "sep_build_lli_table end\n"); } /** @@ -1631,8 +1528,6 @@ static void sep_prepare_empty_lli_table(struct sep_device *sep, { struct sep_lli_entry *lli_table_ptr; - dev_dbg(&sep->pdev->dev, "sep_prepare_empty_lli_table start\n"); - /* Find the area for new table */ lli_table_ptr = (struct sep_lli_entry *)(sep->shared_addr + @@ -1660,9 +1555,6 @@ static void sep_prepare_empty_lli_table(struct sep_device *sep, /* Update the number of created tables */ sep->num_lli_tables_created++; - - dev_dbg(&sep->pdev->dev, "sep_prepare_empty_lli_table start\n"); - } /** @@ -1709,8 +1601,7 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, /* Next table address */ void *lli_table_alloc_addr = 0; - dev_dbg(&sep->pdev->dev, "sep_prepare_input_dma_table start\n"); - dev_dbg(&sep->pdev->dev, "data_size is %x\n", data_size); + dev_dbg(&sep->pdev->dev, "prepare intput dma table data_size is %x\n", data_size); dev_dbg(&sep->pdev->dev, "block_size is %x\n", block_size); /* Initialize the pages pointers */ @@ -1842,7 +1733,6 @@ end_function_error: kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_page_array); end_function: - dev_dbg(&sep->pdev->dev, "sep_prepare_input_dma_table end\n"); return error; } @@ -1906,8 +1796,6 @@ static int sep_construct_dma_tables_from_lli( /* Number of etnries in the output table */ u32 num_entries_out_table = 0; - dev_dbg(&sep->pdev->dev, "sep_construct_dma_tables_from_lli start\n"); - /* Initiate to point after the message area */ lli_table_alloc_addr = (void *)(sep->shared_addr + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + @@ -1960,11 +1848,11 @@ static int sep_construct_dma_tables_from_lli( &last_table_flag); dev_dbg(&sep->pdev->dev, - "in_table_data_size is %x\n", + "construct tables from lli in_table_data_size is %x\n", in_table_data_size); dev_dbg(&sep->pdev->dev, - "out_table_data_size is %x\n", + "construct tables from lli out_table_data_size is %x\n", out_table_data_size); table_data_size = in_table_data_size; @@ -1986,9 +1874,6 @@ static int sep_construct_dma_tables_from_lli( block_size; } - dev_dbg(&sep->pdev->dev, "table_data_size is %x\n", - table_data_size); - /* Construct input lli table */ sep_build_lli_table(sep, &lli_in_array[current_in_entry], in_lli_table_ptr, @@ -2085,7 +1970,6 @@ static int sep_construct_dma_tables_from_lli( *out_num_entries_ptr, *table_data_size_ptr); - dev_dbg(&sep->pdev->dev, "sep_construct_dma_tables_from_lli end\n"); return 0; } @@ -2127,8 +2011,6 @@ static int sep_prepare_input_output_dma_table(struct sep_device *sep, /* Array of pointers of page */ struct sep_lli_entry *lli_out_array; - dev_dbg(&sep->pdev->dev, "sep_prepare_input_output_dma_table start\n"); - if (data_size == 0) { /* Prepare empty table for input and output */ sep_prepare_empty_lli_table(sep, lli_table_in_ptr, @@ -2184,7 +2066,7 @@ static int sep_prepare_input_output_dma_table(struct sep_device *sep, } } - dev_dbg(&sep->pdev->dev, "sep_in_num_pages is %x\n", + dev_dbg(&sep->pdev->dev, "prep input output dma table sep_in_num_pages is %x\n", sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages); dev_dbg(&sep->pdev->dev, "sep_out_num_pages is %x\n", sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages); @@ -2211,13 +2093,6 @@ static int sep_prepare_input_output_dma_table(struct sep_device *sep, update_dcb_counter: /* Update DCB counter */ sep->nr_dcb_creat++; - /* Fall through - free the lli entry arrays */ - dev_dbg(&sep->pdev->dev, "in_num_entries_ptr is %08x\n", - *in_num_entries_ptr); - dev_dbg(&sep->pdev->dev, "out_num_entries_ptr is %08x\n", - *out_num_entries_ptr); - dev_dbg(&sep->pdev->dev, "table_data_size_ptr is %08x\n", - *table_data_size_ptr); goto end_function; @@ -2233,8 +2108,6 @@ end_function_free_lli_in: kfree(lli_in_array); end_function: - dev_dbg(&sep->pdev->dev, - "sep_prepare_input_output_dma_table end result = %d\n", error); return error; @@ -2281,8 +2154,6 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, /* Data in the first input/output table */ u32 first_data_size = 0; - dev_dbg(&sep->pdev->dev, "prepare_input_output_dma_table_in_dcb start\n"); - if (sep->nr_dcb_creat == SEP_MAX_NUM_SYNC_DMA_OPS) { /* No more DCBs to allocate */ dev_warn(&sep->pdev->dev, "no more DCBs available\n"); @@ -2424,8 +2295,6 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, dcb_table_ptr->output_mlli_data_size = first_data_size; end_function: - dev_dbg(&sep->pdev->dev, - "sep_prepare_input_output_dma_table_in_dcb end\n"); return error; } @@ -2448,16 +2317,13 @@ static int sep_create_sync_dma_tables_handler(struct sep_device *sep, /* Command arguments */ struct bld_syn_tab_struct command_args; - dev_dbg(&sep->pdev->dev, - "sep_create_sync_dma_tables_handler start\n"); - if (copy_from_user(&command_args, (void __user *)arg, sizeof(struct bld_syn_tab_struct))) { error = -EFAULT; goto end_function; } - dev_dbg(&sep->pdev->dev, "app_in_address is %08llx\n", + dev_dbg(&sep->pdev->dev, "create dma table handler app_in_address is %08llx\n", command_args.app_in_address); dev_dbg(&sep->pdev->dev, "app_out_address is %08llx\n", command_args.app_out_address); @@ -2482,7 +2348,6 @@ static int sep_create_sync_dma_tables_handler(struct sep_device *sep, false); end_function: - dev_dbg(&sep->pdev->dev, "sep_create_sync_dma_tables_handler end\n"); return error; } @@ -2504,8 +2369,6 @@ static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, unsigned long pt_hold; void *tail_pt; - dev_dbg(&sep->pdev->dev, "sep_free_dma_tables_and_dcb start\n"); - if (isapplet == true) { /* Set pointer to first DCB table */ dcb_table_ptr = (struct sep_dcblock *) @@ -2538,7 +2401,6 @@ static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, /* Free the output pages, if any */ sep_free_dma_table_data_handler(sep); - dev_dbg(&sep->pdev->dev, "sep_free_dma_tables_and_dcb end\n"); return error; } @@ -2552,8 +2414,6 @@ static int sep_get_static_pool_addr_handler(struct sep_device *sep) { u32 *static_pool_addr = NULL; - dev_dbg(&sep->pdev->dev, "sep_get_static_pool_addr_handler start\n"); - static_pool_addr = (u32 *)(sep->shared_addr + SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES); @@ -2561,11 +2421,9 @@ static int sep_get_static_pool_addr_handler(struct sep_device *sep) static_pool_addr[1] = (u32)sep->shared_bus + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES; - dev_dbg(&sep->pdev->dev, "static pool: physical %x\n", + dev_dbg(&sep->pdev->dev, "static pool segment: physical %x\n", (u32)static_pool_addr[1]); - dev_dbg(&sep->pdev->dev, "sep_get_static_pool_addr_handler end\n"); - return 0; } @@ -2578,8 +2436,6 @@ static int sep_start_handler(struct sep_device *sep) unsigned long reg_val; unsigned long error = 0; - dev_dbg(&sep->pdev->dev, "sep_start_handler start\n"); - /* Wait in polling for message from SEP */ do { reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); @@ -2589,7 +2445,6 @@ static int sep_start_handler(struct sep_device *sep) if (reg_val == 0x1) /* Fatal error - read error status from GPRO */ error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR); - dev_dbg(&sep->pdev->dev, "sep_start_handler end\n"); return error; } @@ -2648,8 +2503,6 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) unsigned long addr_hold; struct init_struct command_args; - dev_dbg(&sep->pdev->dev, "sep_init_handler start\n"); - /* Make sure that we have not initialized already */ reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); @@ -2746,7 +2599,6 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x1); /* Wait for acknowledge */ - dev_dbg(&sep->pdev->dev, "init; waiting for msg response\n"); do { reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); @@ -2760,20 +2612,16 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) dev_warn(&sep->pdev->dev, "init; error is %x\n", error); goto end_function; } - dev_dbg(&sep->pdev->dev, "init; end CC INIT, reg_val is %x\n", reg_val); - /* Signal SEP to zero the GPR3 */ sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x10); /* Wait for response */ - dev_dbg(&sep->pdev->dev, "init; waiting for zero set response\n"); do { reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); } while (reg_val != 0); end_function: - dev_dbg(&sep->pdev->dev, "init is done\n"); return error; } @@ -2785,8 +2633,6 @@ end_function: */ static int sep_end_transaction_handler(struct sep_device *sep) { - dev_dbg(&sep->pdev->dev, "sep_end_transaction_handler start\n"); - /* Clear the data pool pointers Token */ memset((void *)(sep->shared_addr + SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES), @@ -2808,9 +2654,6 @@ static int sep_end_transaction_handler(struct sep_device *sep) /* Raise event for stuck contextes */ wake_up(&sep->event); - dev_dbg(&sep->pdev->dev, "waking up event\n"); - dev_dbg(&sep->pdev->dev, "sep_end_transaction_handler end\n"); - return 0; } @@ -2828,8 +2671,6 @@ static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg) /* Command arguments */ struct build_dcb_struct command_args; - dev_dbg(&sep->pdev->dev, "sep_prepare_dcb_handler start\n"); - /* Get the command arguments */ if (copy_from_user(&command_args, (void __user *)arg, sizeof(struct build_dcb_struct))) { @@ -2837,7 +2678,7 @@ static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg) goto end_function; } - dev_dbg(&sep->pdev->dev, "app_in_address is %08llx\n", + dev_dbg(&sep->pdev->dev, "prep dcb handler app_in_address is %08llx\n", command_args.app_in_address); dev_dbg(&sep->pdev->dev, "app_out_address is %08llx\n", command_args.app_out_address); @@ -2855,7 +2696,6 @@ static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg) command_args.tail_block_size, true, false); end_function: - dev_dbg(&sep->pdev->dev, "sep_prepare_dcb_handler end\n"); return error; } @@ -2871,12 +2711,10 @@ static int sep_free_dcb_handler(struct sep_device *sep) { int error ; - dev_dbg(&sep->pdev->dev, "sep_prepare_dcb_handler start\n"); - dev_dbg(&sep->pdev->dev, "num of DCBs %x\n", sep->nr_dcb_creat); + dev_dbg(&sep->pdev->dev, "free dcbs num of DCBs %x\n", sep->nr_dcb_creat); error = sep_free_dma_tables_and_dcb(sep, false, false); - dev_dbg(&sep->pdev->dev, "sep_free_dcb_handler end\n"); return error; } @@ -2900,8 +2738,6 @@ static int sep_rar_prepare_output_msg_handler(struct sep_device *sep, /* Holds the RAR address in the system memory offset */ u32 *rar_addr; - dev_dbg(&sep->pdev->dev, "sep_rar_prepare_output_msg_handler start\n"); - /* Copy the data */ if (copy_from_user(&command_args, (void __user *)arg, sizeof(command_args))) { @@ -2915,7 +2751,6 @@ static int sep_rar_prepare_output_msg_handler(struct sep_device *sep, rar_buf.info.handle = (u32)command_args.rar_handle; if (rar_handle_to_bus(&rar_buf, 1) != 1) { - dev_dbg(&sep->pdev->dev, "rar_handle_to_bus failure\n"); error = -EFAULT; goto end_function; } @@ -2932,7 +2767,6 @@ static int sep_rar_prepare_output_msg_handler(struct sep_device *sep, rar_addr[1] = rar_bus; end_function: - dev_dbg(&sep->pdev->dev, "sep_rar_prepare_output_msg_handler start\n"); return error; } @@ -2955,11 +2789,7 @@ static int sep_realloc_ext_cache_handler(struct sep_device *sep, /* Copy the physical address to the System Area for the SEP */ system_addr[0] = SEP_EXT_CACHE_ADDR_VAL_TOKEN; - dev_dbg(&sep->pdev->dev, "ext cache init; system addr 0 is %x\n", - system_addr[0]); system_addr[1] = sep->extapp_bus; - dev_dbg(&sep->pdev->dev, "ext cache init; system addr 1 is %x\n", - system_addr[1]); return 0; } @@ -2977,15 +2807,13 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) int error = 0; struct sep_device *sep = filp->private_data; - dev_dbg(&sep->pdev->dev, "ioctl start\n"); - - dev_dbg(&sep->pdev->dev, "cmd is %x\n", cmd); + dev_dbg(&sep->pdev->dev, "ioctl cmd is %x\n", cmd); /* Make sure we own this device */ mutex_lock(&sep->sep_mutex); if ((current->pid != sep->pid_doing_transaction) && (sep->pid_doing_transaction != 0)) { - dev_dbg(&sep->pdev->dev, "ioctl pid is not owner\n"); + dev_warn(&sep->pdev->dev, "ioctl pid is not owner\n"); mutex_unlock(&sep->sep_mutex); error = -EACCES; goto end_function; @@ -3080,8 +2908,7 @@ static long sep_singleton_ioctl(struct file *filp, u32 cmd, unsigned long arg) long error = 0; struct sep_device *sep = filp->private_data; - dev_dbg(&sep->pdev->dev, "singleton_ioctl start\n"); - dev_dbg(&sep->pdev->dev, "cmd is %x\n", cmd); + dev_dbg(&sep->pdev->dev, "singleton ioctl cmd is %x\n", cmd); /* Check that the command is for the SEP device */ if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) { @@ -3093,7 +2920,7 @@ static long sep_singleton_ioctl(struct file *filp, u32 cmd, unsigned long arg) mutex_lock(&sep->sep_mutex); if ((current->pid != sep->pid_doing_transaction) && (sep->pid_doing_transaction != 0)) { - dev_dbg(&sep->pdev->dev, "singleton ioctl pid is not owner\n"); + dev_warn(&sep->pdev->dev, "singleton ioctl pid is not owner\n"); mutex_unlock(&sep->sep_mutex); error = -EACCES; goto end_function; @@ -3113,7 +2940,6 @@ static long sep_singleton_ioctl(struct file *filp, u32 cmd, unsigned long arg) } end_function: - dev_dbg(&sep->pdev->dev, "singleton ioctl end\n"); return error; } @@ -3132,7 +2958,6 @@ static long sep_request_daemon_ioctl(struct file *filp, u32 cmd, long error; struct sep_device *sep = filp->private_data; - dev_dbg(&sep->pdev->dev, "daemon ioctl: start\n"); dev_dbg(&sep->pdev->dev, "daemon ioctl: cmd is %x\n", cmd); /* Check that the command is for SEP device */ @@ -3158,13 +2983,12 @@ static long sep_request_daemon_ioctl(struct file *filp, u32 cmd, error = 0; break; default: - dev_dbg(&sep->pdev->dev, "daemon ioctl: no such IOCTL\n"); + dev_warn(&sep->pdev->dev, "daemon ioctl: no such IOCTL\n"); error = -ENOTTY; } mutex_unlock(&sep->ioctl_mutex); end_function: - dev_dbg(&sep->pdev->dev, "daemon ioctl: end\n"); return error; } @@ -3183,7 +3007,6 @@ static irqreturn_t sep_inthandler(int irq, void *dev_id) /* Read the IRR register to check if this is SEP interrupt */ reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR); - dev_dbg(&sep->pdev->dev, "SEP Interrupt - reg is %08x\n", reg_val); if (reg_val & (0x1 << 13)) { /* Lock and update the counter of reply messages */ @@ -3233,10 +3056,8 @@ static int sep_reconfig_shared_area(struct sep_device *sep) /* use to limit waiting for SEP */ unsigned long end_time; - dev_dbg(&sep->pdev->dev, "reconfig shared area start\n"); - /* Send the new SHARED MESSAGE AREA to the SEP */ - dev_dbg(&sep->pdev->dev, "sending %08llx to sep\n", + dev_dbg(&sep->pdev->dev, "reconfig shared; sending %08llx to sep\n", (unsigned long long)sep->shared_bus); sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus); @@ -3356,7 +3177,6 @@ static int __devinit sep_probe(struct pci_dev *pdev, int error = 0; struct sep_device *sep; - pr_debug("SEP pci probe starting\n"); if (sep_dev != NULL) { dev_warn(&pdev->dev, "only one SEP supported.\n"); return -EBUSY; @@ -3394,7 +3214,7 @@ static int __devinit sep_probe(struct pci_dev *pdev, mutex_init(&sep->sep_mutex); mutex_init(&sep->ioctl_mutex); - dev_dbg(&sep->pdev->dev, "PCI obtained, device being prepared\n"); + dev_dbg(&sep->pdev->dev, "sep probe: PCI obtained, device being prepared\n"); dev_dbg(&sep->pdev->dev, "revision is %d\n", sep->pdev->revision); /* Set up our register area */ @@ -3453,8 +3273,6 @@ static int __devinit sep_probe(struct pci_dev *pdev, (unsigned long long)sep->rar_bus, sep->rar_size); - dev_dbg(&sep->pdev->dev, "about to write IMR and ICR REG_ADDR\n"); - /* Clear ICR register */ sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); @@ -3466,7 +3284,6 @@ static int __devinit sep_probe(struct pci_dev *pdev, sep->reply_ct &= 0x3FFFFFFF; sep->send_ct = sep->reply_ct; - dev_dbg(&sep->pdev->dev, "about to call request_irq\n"); /* Get the interrupt line */ error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED, "sep_driver", sep); -- cgit v1.2.3 From e508edb203352e044dac359fb98579508bf7376c Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Tue, 4 Jan 2011 14:16:59 -0800 Subject: staging: sep: update driver to SEP version 3.4.5 These changes enable the driver to work with SEP version 3.4.5 Major change is to use non DMA access for any data comming from a function that uses the external application service on the SEP. Signed-off-by: Mark Allyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 32 +++++++++++++------------------- drivers/staging/sep/sep_driver_api.h | 4 ++-- drivers/staging/sep/sep_driver_config.h | 4 ++++ 3 files changed, 19 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index a1b0bfe5e003..ee234547c877 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -29,7 +29,6 @@ * 2010.09.14 Upgrade to Medfield * */ -#define DEBUG #include #include #include @@ -2177,22 +2176,6 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, dcb_table_ptr->out_vr_tail_pt = 0; if (isapplet == true) { - tail_size = data_in_size % block_size; - if (tail_size) { - if (data_in_size < tail_block_size) { - dev_warn(&sep->pdev->dev, "data in size smaller than tail block size\n"); - error = -ENOSPC; - goto end_function; - } - if (tail_block_size) - /* - * Case the tail size should be - * bigger than the real block size - */ - tail_size = tail_block_size + - ((data_in_size - - tail_block_size) % block_size); - } /* Check if there is enough data for DMA operation */ if (data_in_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) { @@ -2213,7 +2196,7 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, /* Set the output user-space address for mem2mem op */ if (app_out_address) dcb_table_ptr->out_vr_tail_pt = - (u32)app_out_address; + (aligned_u64)app_out_address; /* * Update both data length parameters in order to avoid @@ -2222,6 +2205,17 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, */ tail_size = 0x0; data_in_size = 0x0; + + } else { + if (!app_out_address) { + tail_size = data_in_size % block_size; + if (!tail_size) { + if (tail_block_size == block_size) + tail_size = block_size; + } + } else { + tail_size = 0; + } } if (tail_size) { if (is_kva == true) { @@ -2243,7 +2237,7 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, * according to tail data size */ dcb_table_ptr->out_vr_tail_pt = - (u32)app_out_address + data_in_size + (aligned_u64)app_out_address + data_in_size - tail_size; /* Save the real tail data size */ diff --git a/drivers/staging/sep/sep_driver_api.h b/drivers/staging/sep/sep_driver_api.h index fbbfa2396555..0f38d619842e 100644 --- a/drivers/staging/sep/sep_driver_api.h +++ b/drivers/staging/sep/sep_driver_api.h @@ -141,11 +141,11 @@ struct sep_dcblock { /* size of data in the first output mlli */ u32 output_mlli_data_size; /* pointer to the output virtual tail */ - u32 out_vr_tail_pt; + aligned_u64 out_vr_tail_pt; /* size of tail data */ u32 tail_data_size; /* input tail data array */ - u8 tail_data[64]; + u8 tail_data[68]; }; struct sep_caller_id_entry { diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h index b18625d2f7f4..d3b9220f3963 100644 --- a/drivers/staging/sep/sep_driver_config.h +++ b/drivers/staging/sep/sep_driver_config.h @@ -76,6 +76,10 @@ held by the proccess (struct file) */ #define SEP_REQUEST_DAEMON_MAPPED 1 #define SEP_REQUEST_DAEMON_UNMAPPED 0 +#define SEP_DEV_NAME "sep_sec_driver" +#define SEP_DEV_SINGLETON "sep_sec_singleton_driver" +#define SEP_DEV_DAEMON "sep_req_daemon_driver" + /*-------------------------------------------------------- SHARED AREA memory total size is 36K it is divided is following: -- cgit v1.2.3 From aa96646daa15d6ac05addc7db7272dd5787c6953 Mon Sep 17 00:00:00 2001 From: roel kluin Date: Mon, 3 Jan 2011 11:59:14 -0800 Subject: staging: spectra: don't read past array in Conv_Spare_Data_Log2Phy_Format() It should decrement or we read past the array Signed-off-by: Roel Kluin Cc: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/spectra/lld_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/spectra/lld_nand.c b/drivers/staging/spectra/lld_nand.c index 2263d3ea5456..0be7adc96b8c 100644 --- a/drivers/staging/spectra/lld_nand.c +++ b/drivers/staging/spectra/lld_nand.c @@ -1400,7 +1400,7 @@ void Conv_Spare_Data_Log2Phy_Format(u8 *data) const u32 PageSpareSize = DeviceInfo.wPageSpareSize; if (enable_ecc) { - for (i = spareFlagBytes - 1; i >= 0; i++) + for (i = spareFlagBytes - 1; i >= 0; i--) data[PageSpareSize - spareFlagBytes + i] = data[i]; } } -- cgit v1.2.3 From b01627c608d97b5246eb7a4b75c40f2a1fb4dc30 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 3 Jan 2011 08:47:40 +0300 Subject: Staging: tm6000: silence Sparse warning "dubious: !x | !y" Bitwise and logical or are the equivalent here, so this doesn't affect runtime, but logical or was intended. The original code causes a warning in Sparse: "warning: dubious: !x | !y" Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tm6000/tm6000-input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/tm6000/tm6000-input.c b/drivers/staging/tm6000/tm6000-input.c index 21e7da40f049..01fcbbe38409 100644 --- a/drivers/staging/tm6000/tm6000-input.c +++ b/drivers/staging/tm6000/tm6000-input.c @@ -374,7 +374,7 @@ int tm6000_ir_init(struct tm6000_core *dev) ir = kzalloc(sizeof(*ir), GFP_KERNEL); rc = rc_allocate_device(); - if (!ir | !rc) + if (!ir || !rc) goto out; /* record handles to ourself */ -- cgit v1.2.3 From 2591418bb18ea597dc34cc369899e11c3d4ecc87 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 3 Jan 2011 08:44:38 +0300 Subject: Staging: tm6000: check usb_alloc_urb() return usb_alloc_urb() can return NULL so check for that and return -ENOMEM if it happens. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tm6000/tm6000-input.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/tm6000/tm6000-input.c b/drivers/staging/tm6000/tm6000-input.c index 01fcbbe38409..dae2f1fdcc5b 100644 --- a/drivers/staging/tm6000/tm6000-input.c +++ b/drivers/staging/tm6000/tm6000-input.c @@ -313,6 +313,8 @@ int tm6000_ir_int_start(struct tm6000_core *dev) return -ENODEV; ir->int_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!ir->int_urb) + return -ENOMEM; pipe = usb_rcvintpipe(dev->udev, dev->int_in.endp->desc.bEndpointAddress -- cgit v1.2.3 From 1b5b4e17e58a0c8ddfd5ad60e65f924fb00b60ef Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 2 Jan 2011 23:14:26 +0100 Subject: staging: keucr: Use memcmp() instead custom StringCmp() and some style cleanups staging: keucr: Use memcmp() instead custom StringCmp() and some style cleanups Signed-off-by: Javier Martinez Canillas Acked-by: Dan Carpenter Reviewed-by: Marcin Slusarz Cc: Al Cho Signed-off-by: Greg Kroah-Hartman --- drivers/staging/keucr/smilsub.c | 50 +++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/keucr/smilsub.c b/drivers/staging/keucr/smilsub.c index ce10cf215f51..81ed0aa1284e 100644 --- a/drivers/staging/keucr/smilsub.c +++ b/drivers/staging/keucr/smilsub.c @@ -1482,54 +1482,40 @@ BYTE _Check_D_DevCode(BYTE dcode) //----- Check_D_ReadError() ---------------------------------------------- int Check_D_ReadError(BYTE *redundant) { - // Driver ECC Check - return(SUCCESS); - if (!StringCmp((char *)(redundant+0x0D),(char *)EccBuf,3)) - if (!StringCmp((char *)(redundant+0x08),(char *)(EccBuf+0x03),3)) - return(SUCCESS); - - return(ERROR); + return SUCCESS; } //----- Check_D_Correct() ---------------------------------------------- int Check_D_Correct(BYTE *buf,BYTE *redundant) { - // Driver ECC Check - return(SUCCESS); - if (StringCmp((char *)(redundant+0x0D),(char *)EccBuf,3)) - if (_Correct_D_SwECC(buf,redundant+0x0D,EccBuf)) - return(ERROR); - - buf+=0x100; - if (StringCmp((char *)(redundant+0x08),(char *)(EccBuf+0x03),3)) - if (_Correct_D_SwECC(buf,redundant+0x08,EccBuf+0x03)) - return(ERROR); - - return(SUCCESS); + return SUCCESS; } //----- Check_D_CISdata() ---------------------------------------------- int Check_D_CISdata(BYTE *buf, BYTE *redundant) { - BYTE cis[]={0x01,0x03,0xD9,0x01,0xFF,0x18,0x02,0xDF,0x01,0x20}; + BYTE cis[] = {0x01, 0x03, 0xD9, 0x01, 0xFF, 0x18, 0x02, + 0xDF, 0x01, 0x20}; + + int cis_len = sizeof(cis); - if (!IsSSFDCCompliance && !IsXDCompliance) - return(SUCCESS); // ثej SUCCESS [Arnold 02-08-23] SSFDC , j SUCCESS + if (!IsSSFDCCompliance && !IsXDCompliance) + return SUCCESS; - if (!StringCmp((char *)(redundant+0x0D),(char *)EccBuf,3)) - return(StringCmp((char *)buf,(char *)cis,10)); + if (!memcmp(redundant + 0x0D, EccBuf, 3)) + return memcmp(buf, cis, cis_len); - if (!_Correct_D_SwECC(buf,redundant+0x0D,EccBuf)) - return(StringCmp((char *)buf,(char *)cis,10)); + if (!_Correct_D_SwECC(buf, redundant + 0x0D, EccBuf)) + return memcmp(buf, cis, cis_len); - buf+=0x100; - if (!StringCmp((char *)(redundant+0x08),(char *)(EccBuf+0x03),3)) - return(StringCmp((char *)buf,(char *)cis,10)); + buf += 0x100; + if (!memcmp(redundant + 0x08, EccBuf + 0x03, 3)) + return memcmp(buf, cis, cis_len); - if (!_Correct_D_SwECC(buf,redundant+0x08,EccBuf+0x03)) - return(StringCmp((char *)buf,(char *)cis,10)); + if (!_Correct_D_SwECC(buf, redundant + 0x08, EccBuf + 0x03)) + return memcmp(buf, cis, cis_len); - return(ERROR); + return ERROR; } //----- Set_D_RightECC() ---------------------------------------------- -- cgit v1.2.3 From f3d5049ccdb57d14712f7cba27b0dd0a860961d7 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 2 Jan 2011 23:14:27 +0100 Subject: staging: keucr: Use memcpy() instead custom StringCopy() and some style cleanups staging: keucr: Use memcpy() instead custom StringCopy() and some style cleanups Signed-off-by: Javier Martinez Canillas Acked-by: Dan Carpenter Reviewed-by: Marcin Slusarz Cc: Al Cho Signed-off-by: Greg Kroah-Hartman --- drivers/staging/keucr/smilecc.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/keucr/smilecc.c b/drivers/staging/keucr/smilecc.c index daf322ac9bf9..5659dea7b701 100644 --- a/drivers/staging/keucr/smilecc.c +++ b/drivers/staging/keucr/smilecc.c @@ -182,13 +182,17 @@ BYTE *buf; BYTE *redundant_ecc; BYTE *calculate_ecc; { - DWORD err; + DWORD err; - err=correct_data(buf,redundant_ecc,*(calculate_ecc+1),*(calculate_ecc),*(calculate_ecc+2)); - if (err==1) StringCopy(calculate_ecc,redundant_ecc,3); - if (err==0 || err==1 || err==2) - return(0); - return(-1); + err = correct_data(buf, redundant_ecc, *(calculate_ecc + 1), + *(calculate_ecc), *(calculate_ecc + 2)); + if (err == 1) + memcpy(calculate_ecc, redundant_ecc, 3); + + if (err == 0 || err == 1 || err == 2) + return 0; + + return -1; } void _Calculate_D_SwECC(buf,ecc) -- cgit v1.2.3 From 1b9f644dfeb638e0146ce54f4e48c87a2841a603 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 2 Jan 2011 23:14:28 +0100 Subject: staging: keucr: Delete StringCmp() and StringCopy custom functions staging: keucr: Delete StringCmp() and StringCopy custom functions Signed-off-by: Javier Martinez Canillas Acked-by: Dan Carpenter Reviewed-by: Marcin Slusarz Cc: Al Cho Signed-off-by: Greg Kroah-Hartman --- drivers/staging/keucr/smilsub.c | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/keucr/smilsub.c b/drivers/staging/keucr/smilsub.c index 81ed0aa1284e..6dbc81de637b 100644 --- a/drivers/staging/keucr/smilsub.c +++ b/drivers/staging/keucr/smilsub.c @@ -1575,25 +1575,6 @@ char Bit_D_CountWord(WORD cdata) return((char)bitcount); } -void StringCopy(char *stringA, char *stringB, int count) -{ - int i; - - for(i=0; i Date: Sun, 2 Jan 2011 23:14:29 +0100 Subject: staging: keucr: Delete use kernel strcmp() & strcpy() from TODO file staging: keucr: Delete use kernel strcmp() & strcpy() from TODO file Signed-off-by: Javier Martinez Canillas Acked-by: Dan Carpenter Reviewed-by: Marcin Slusarz Cc: Al Cho Signed-off-by: Greg Kroah-Hartman --- drivers/staging/keucr/TODO | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/keucr/TODO b/drivers/staging/keucr/TODO index 29f1b10bd2f6..179b7fe05de2 100644 --- a/drivers/staging/keucr/TODO +++ b/drivers/staging/keucr/TODO @@ -7,8 +7,7 @@ TODO: infrastructure instead. - review by the USB developer community - common.h: use kernel swap, le, & be functions - - smcommon.h & smilsub.c: use kernel hweight8(), hweight16(), - strcmp(), & strcpy() + - smcommon.h & smilsub.c: use kernel hweight8(), hweight16() Please send any patches for this driver to Al Cho and Greg Kroah-Hartman . -- cgit v1.2.3 From f1bc434398e8cf400374911357e89a13de366ce7 Mon Sep 17 00:00:00 2001 From: Brice Dubost Date: Fri, 7 Jan 2011 18:49:18 +0100 Subject: staging: comedi : Analog input trigerring modes for cb_pcidas This patch allows the possibility to choose between edgre triggering and level trigerring, for the analog input, on the Measurement Computing PCI-DAS* boards Signed-off-by: Brice Dubost Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas.c | 62 +++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 3275fc50615f..0941643b3869 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -53,6 +53,15 @@ Configuration options: For commands, the scanned channels must be consecutive (i.e. 4-5-6-7, 2-3-4,...), and must all have the same range and aref. + +AI Triggering: + For start_src == TRIG_EXT, the A/D EXTERNAL TRIGGER IN (pin 45) is used. + For 1602 series, the start_arg is interpreted as follows: + start_arg == 0 => gated triger (level high) + start_arg == CR_INVERT => gated triger (level low) + start_arg == CR_EDGE => Rising edge + start_arg == CR_EDGE | CR_INVERT => Falling edge + For the other boards the trigger will be done on rising edge */ /* @@ -135,6 +144,8 @@ analog triggering on 1602 series #define EXT_TRIGGER 0x2 /* external start trigger */ #define ANALOG_TRIGGER 0x3 /* external analog trigger */ #define TRIGGER_MASK 0x3 /* mask of bits that determine start trigger */ +#define TGPOL 0x04 /* invert the edge/level of the external trigger (1602 only) */ +#define TGSEL 0x08 /* if set edge triggered, otherwise level trigerred (1602 only) */ #define TGEN 0x10 /* enable external start trigger */ #define BURSTE 0x20 /* burst mode enable */ #define XTRCL 0x80 /* clear external trigger */ @@ -257,6 +268,8 @@ struct cb_pcidas_board { const struct comedi_lrange *ranges; enum trimpot_model trimpot; unsigned has_dac08:1; + unsigned has_ai_trig_gated:1; /* Tells if the AI trigger can be gated */ + unsigned has_ai_trig_invert:1; /* Tells if the AI trigger can be inverted */ }; static const struct cb_pcidas_board cb_pcidas_boards[] = { @@ -274,6 +287,8 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = { .ranges = &cb_pcidas_ranges, .trimpot = AD8402, .has_dac08 = 1, + .has_ai_trig_gated = 1, + .has_ai_trig_invert = 1, }, { .name = "pci-das1200", @@ -288,6 +303,8 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = { .ranges = &cb_pcidas_ranges, .trimpot = AD7376, .has_dac08 = 0, + .has_ai_trig_gated = 0, + .has_ai_trig_invert = 0, }, { .name = "pci-das1602/12", @@ -303,6 +320,8 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = { .ranges = &cb_pcidas_ranges, .trimpot = AD7376, .has_dac08 = 0, + .has_ai_trig_gated = 1, + .has_ai_trig_invert = 1, }, { .name = "pci-das1200/jr", @@ -317,6 +336,8 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = { .ranges = &cb_pcidas_ranges, .trimpot = AD7376, .has_dac08 = 0, + .has_ai_trig_gated = 0, + .has_ai_trig_invert = 0, }, { .name = "pci-das1602/16/jr", @@ -331,6 +352,8 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = { .ranges = &cb_pcidas_ranges, .trimpot = AD8402, .has_dac08 = 1, + .has_ai_trig_gated = 1, + .has_ai_trig_invert = 1, }, { .name = "pci-das1000", @@ -345,6 +368,8 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = { .ranges = &cb_pcidas_ranges, .trimpot = AD7376, .has_dac08 = 0, + .has_ai_trig_gated = 0, + .has_ai_trig_invert = 0, }, { .name = "pci-das1001", @@ -359,6 +384,8 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = { .ranges = &cb_pcidas_alt_ranges, .trimpot = AD7376, .has_dac08 = 0, + .has_ai_trig_gated = 0, + .has_ai_trig_invert = 0, }, { .name = "pci-das1002", @@ -373,6 +400,8 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = { .ranges = &cb_pcidas_ranges, .trimpot = AD7376, .has_dac08 = 0, + .has_ai_trig_gated = 0, + .has_ai_trig_invert = 0, }, }; @@ -1113,9 +1142,27 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, /* step 3: make sure arguments are trivially compatible */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; + switch (cmd->start_src) { + case TRIG_EXT: + /* External trigger, only CR_EDGE and CR_INVERT flags allowed */ + if ((cmd->start_arg + & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) { + cmd->start_arg &= + ~(CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT)); + err++; + } + if (!thisboard->has_ai_trig_invert && + (cmd->start_arg & CR_INVERT)) { + cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT); + err++; + } + break; + default: + if (cmd->start_arg != 0) { + cmd->start_arg = 0; + err++; + } + break; } if (cmd->scan_begin_src == TRIG_TIMER) { @@ -1270,9 +1317,14 @@ static int cb_pcidas_ai_cmd(struct comedi_device *dev, bits = 0; if (cmd->start_src == TRIG_NOW) bits |= SW_TRIGGER; - else if (cmd->start_src == TRIG_EXT) + else if (cmd->start_src == TRIG_EXT) { bits |= EXT_TRIGGER | TGEN | XTRCL; - else { + if (thisboard->has_ai_trig_invert + && (cmd->start_arg & CR_INVERT)) + bits |= TGPOL; + if (thisboard->has_ai_trig_gated && (cmd->start_arg & CR_EDGE)) + bits |= TGSEL; + } else { comedi_error(dev, "bug!"); return -1; } -- cgit v1.2.3 From 31d5bbf3da8c3c9de5944f2c09cbc7ea5a72bdb4 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 9 Jan 2011 04:16:48 +0000 Subject: vt6656: Use request_firmware() to load firmware The file added to linux-firmware is a copy of the current array which does not have a recognisable header, so no validation is done. Change the firmware version check to accept newer versions. Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/Kconfig | 1 + drivers/staging/vt6656/device.h | 3 + drivers/staging/vt6656/firmware.c | 805 +++----------------------------------- drivers/staging/vt6656/main_usb.c | 3 + 4 files changed, 59 insertions(+), 753 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/Kconfig b/drivers/staging/vt6656/Kconfig index 1055b526c532..a441ba513c40 100644 --- a/drivers/staging/vt6656/Kconfig +++ b/drivers/staging/vt6656/Kconfig @@ -3,6 +3,7 @@ config VT6656 depends on USB && WLAN select WIRELESS_EXT select WEXT_PRIV + select FW_LOADER ---help--- This is a vendor-written driver for VIA VT6656. diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index e8d0b4203cad..f1496ec5dc72 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #ifdef SIOCETHTOOL @@ -421,6 +422,8 @@ typedef struct __device_info { struct net_device* dev; struct net_device_stats stats; + const struct firmware *firmware; + OPTIONS sOpts; struct tasklet_struct CmdWorkItem; diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c index d49ea7029ad7..162541255a02 100644 --- a/drivers/staging/vt6656/firmware.c +++ b/drivers/staging/vt6656/firmware.c @@ -39,6 +39,12 @@ static int msglevel =MSG_LEVEL_INFO; //static int msglevel =MSG_LEVEL_DEBUG; + +#define FIRMWARE_VERSION 0x133 /* version 1.51 */ +#define FIRMWARE_NAME "vntwusb.fw" + +#define FIRMWARE_CHUNK_SIZE 0x400 + /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ @@ -47,724 +53,6 @@ static int msglevel =MSG_LEVEL_INFO; /*--------------------- Export Variables --------------------------*/ -/* - * This is firmware version 1.51 - */ -#define FIRMWARE_VERSION 0x133 - -const BYTE abyFirmware[] = { - -0x02, 0x35, 0x62, 0x02, 0x3B, 0xED, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x3E, 0x21, 0xD2, 0x04, -0x90, 0x06, 0x24, 0x74, 0x08, 0xF0, 0x90, 0x06, 0x21, 0xE0, 0x90, 0x45, 0x39, 0xF0, 0xE0, 0x90, -0x06, 0x21, 0xF0, 0x90, 0x06, 0x10, 0xE0, 0x54, 0x60, 0x60, 0x03, 0x02, 0x1A, 0xE9, 0xA3, 0xE0, -0x12, 0x28, 0x7E, 0x18, 0x15, 0x00, 0x18, 0xF6, 0x01, 0x19, 0xD1, 0x03, 0x16, 0x79, 0x05, 0x12, -0x52, 0x06, 0x17, 0xE5, 0x08, 0x16, 0xAF, 0x09, 0x17, 0x33, 0x0A, 0x17, 0x91, 0x0B, 0x00, 0x00, -0x1A, 0xE1, 0x90, 0x06, 0x17, 0xE0, 0xFE, 0x90, 0x06, 0x16, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x31, -0xF0, 0xED, 0xA3, 0xF0, 0x90, 0x10, 0x3D, 0x74, 0x05, 0xF0, 0x90, 0x06, 0x24, 0x74, 0x08, 0xF0, -0x90, 0x06, 0x13, 0xE0, 0x24, 0xFE, 0x60, 0x47, 0x14, 0x70, 0x03, 0x02, 0x14, 0x79, 0x24, 0xFD, -0x60, 0x25, 0x14, 0x70, 0x03, 0x02, 0x13, 0x9C, 0x24, 0x06, 0x60, 0x03, 0x02, 0x16, 0x54, 0x7B, -0x01, 0x7A, 0x10, 0x79, 0x8B, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x4C, 0xE4, 0xF0, -0xA3, 0x74, 0x12, 0xF0, 0x02, 0x16, 0x5C, 0x7B, 0x01, 0x7A, 0x10, 0x79, 0x81, 0x90, 0x10, 0x46, -0x12, 0x27, 0xBA, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0x74, 0x0A, 0xF0, 0x02, 0x16, 0x5C, 0x7B, -0x01, 0x7A, 0x10, 0x79, 0x51, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x52, 0x74, 0x02, -0xF0, 0x90, 0x10, 0x54, 0xE0, 0xFE, 0x90, 0x10, 0x53, 0xE0, 0xFD, 0xEE, 0x90, 0x10, 0x4C, 0xF0, -0xED, 0xA3, 0xF0, 0x30, 0x06, 0x5A, 0xE0, 0xFD, 0x24, 0x47, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, -0x83, 0xE4, 0xF0, 0x74, 0x48, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x02, 0xF0, -0x74, 0x4E, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x4F, 0x2D, 0xF5, -0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x02, 0xF0, 0x90, 0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10, -0x97, 0xE0, 0xFB, 0xEE, 0xEB, 0xC3, 0x94, 0x20, 0xEE, 0x94, 0x01, 0x40, 0x03, 0x02, 0x16, 0x5C, -0x74, 0x50, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x01, 0xF0, 0x02, 0x16, 0x5C, -0x90, 0x10, 0x4D, 0xE0, 0xFD, 0x24, 0x47, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x40, -0xF0, 0x74, 0x48, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x4E, 0x2D, -0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x40, 0xF0, 0x74, 0x4F, 0x2D, 0xF5, 0x82, 0xE4, -0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x90, 0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10, 0x97, 0xE0, 0xFB, -0xEE, 0xEB, 0xC3, 0x94, 0x20, 0xEE, 0x94, 0x01, 0x40, 0x03, 0x02, 0x16, 0x5C, 0x74, 0x50, 0x2D, -0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x02, 0x16, 0x5C, 0x7B, 0x01, 0x7A, 0x10, -0x79, 0x51, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x52, 0x74, 0x07, 0xF0, 0x90, 0x10, -0x54, 0xE0, 0xFE, 0x90, 0x10, 0x53, 0xE0, 0xFD, 0xEE, 0x90, 0x10, 0x4C, 0xF0, 0xED, 0xA3, 0xF0, -0x30, 0x06, 0x59, 0xE0, 0xFD, 0x24, 0x47, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x40, -0xF0, 0x74, 0x48, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x4E, 0x2D, -0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x40, 0xF0, 0x74, 0x4F, 0x2D, 0xF5, 0x82, 0xE4, -0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x90, 0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10, 0x97, 0xE0, 0xFB, -0xEE, 0xEB, 0xC3, 0x94, 0x20, 0xEE, 0x94, 0x01, 0x40, 0x03, 0x02, 0x16, 0x5C, 0x74, 0x50, 0x2D, -0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x02, 0x16, 0x5C, 0x90, 0x10, 0x4D, 0xE0, -0xFD, 0x24, 0x47, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x48, 0x2D, 0xF5, -0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x02, 0xF0, 0x74, 0x4E, 0x2D, 0xF5, 0x82, 0xE4, 0x34, -0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x4F, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, -0x02, 0xF0, 0x90, 0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10, 0x97, 0xE0, 0xFB, 0xEE, 0xEB, 0xC3, 0x94, -0x20, 0xEE, 0x94, 0x01, 0x40, 0x03, 0x02, 0x16, 0x5C, 0x74, 0x50, 0x2D, 0xF5, 0x82, 0xE4, 0x34, -0x10, 0xF5, 0x83, 0x74, 0x01, 0xF0, 0x02, 0x16, 0x5C, 0x90, 0x06, 0x12, 0xE0, 0x14, 0x60, 0x2F, -0x14, 0x70, 0x03, 0x02, 0x15, 0x34, 0x14, 0x70, 0x03, 0x02, 0x15, 0xD5, 0x24, 0x03, 0x60, 0x03, -0x02, 0x16, 0x4C, 0x7B, 0x01, 0x7A, 0x43, 0x79, 0x1A, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, -0x43, 0x1A, 0xE0, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x02, 0x16, 0x5C, 0x90, -0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10, 0x97, 0xE0, 0xFD, 0xEE, 0xED, 0xC3, 0x94, 0x20, 0xEE, 0x94, -0x01, 0x50, 0x1C, 0x7B, 0x01, 0x7A, 0x10, 0x79, 0x14, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, -0x10, 0x14, 0xE0, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x02, 0x16, 0x5C, 0x90, -0x10, 0x3C, 0xE0, 0xC3, 0x94, 0x01, 0x50, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, -0x90, 0x10, 0x0D, 0xE0, 0x20, 0xE0, 0x1C, 0x7B, 0x01, 0x7A, 0x10, 0x79, 0x14, 0x90, 0x10, 0x46, -0x12, 0x27, 0xBA, 0x90, 0x10, 0x14, 0xE0, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, -0x02, 0x16, 0x5C, 0x90, 0x10, 0x2E, 0x12, 0x27, 0x9A, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, -0x10, 0x2E, 0x12, 0x27, 0x9A, 0x12, 0x26, 0x36, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, -0xF0, 0x02, 0x16, 0x5C, 0x90, 0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10, 0x97, 0xE0, 0xFD, 0xEE, 0xED, -0xC3, 0x94, 0x20, 0xEE, 0x94, 0x01, 0x50, 0x33, 0x90, 0x10, 0x99, 0xE0, 0x70, 0x0C, 0xA3, 0xE0, -0x70, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x10, 0x2E, 0x12, 0x27, 0x9A, -0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x2E, 0x12, 0x27, 0x9A, 0x12, 0x26, 0x36, 0xFF, -0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x02, 0x16, 0x5C, 0x90, 0x10, 0x3C, 0xE0, 0xC3, -0x94, 0x02, 0x50, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x10, 0x0D, 0xE0, -0x20, 0xE0, 0x21, 0x90, 0x10, 0x2E, 0x12, 0x27, 0x9A, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, -0x10, 0x2E, 0x12, 0x27, 0x9A, 0x12, 0x26, 0x36, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, -0xF0, 0x02, 0x16, 0x5C, 0x90, 0x10, 0x31, 0x12, 0x27, 0x9A, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, -0x90, 0x10, 0x31, 0x12, 0x27, 0x9A, 0x12, 0x26, 0x36, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, -0xEF, 0xF0, 0x02, 0x16, 0x5C, 0x90, 0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10, 0x97, 0xE0, 0xFD, 0xEE, -0xED, 0xC3, 0x94, 0x20, 0xEE, 0x94, 0x01, 0x50, 0x32, 0x90, 0x10, 0x99, 0xE0, 0x60, 0x04, 0xA3, -0xE0, 0x70, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x10, 0x31, 0x12, 0x27, -0x9A, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x31, 0x12, 0x27, 0x9A, 0x12, 0x26, 0x36, -0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x80, 0x41, 0x90, 0x10, 0x3C, 0xE0, 0xC3, -0x94, 0x03, 0x50, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x10, 0x31, 0x12, -0x27, 0x9A, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x31, 0x12, 0x27, 0x9A, 0x12, 0x26, -0x36, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x80, 0x10, 0x90, 0x06, 0x22, 0xE0, -0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x45, 0x31, 0xE0, -0xFE, 0xA3, 0xE0, 0xFF, 0xD3, 0x90, 0x10, 0x4D, 0xE0, 0x9F, 0x90, 0x10, 0x4C, 0xE0, 0x9E, 0x40, -0x05, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x02, 0x33, 0xF6, 0x90, 0x06, 0x12, 0xE0, 0x90, 0x10, 0x3E, -0xF0, 0x90, 0x10, 0x3D, 0x74, 0x04, 0xF0, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, -0xF0, 0xA3, 0xF0, 0x90, 0x10, 0x3E, 0xE0, 0xFF, 0x44, 0x80, 0x90, 0x06, 0x06, 0xF0, 0xEF, 0x70, -0x07, 0x90, 0x10, 0x38, 0x74, 0x07, 0xF0, 0x22, 0x90, 0x10, 0x38, 0x74, 0x0F, 0xF0, 0x22, 0x90, -0x06, 0x13, 0xE0, 0xFE, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x35, 0xF0, 0xED, 0xA3, -0xF0, 0x90, 0x45, 0x35, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x64, 0x01, 0x4E, 0x60, 0x0C, 0xEF, 0x4E, -0x60, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x12, 0xE0, 0x90, 0x10, -0x3A, 0xF0, 0x90, 0x10, 0x3D, 0x74, 0x08, 0xF0, 0x90, 0x06, 0x08, 0x74, 0x02, 0xF0, 0xA3, 0x04, -0xF0, 0xA3, 0x74, 0x01, 0xF0, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, -0xF0, 0x90, 0x10, 0x3A, 0xE0, 0x70, 0x0D, 0x90, 0x10, 0x38, 0x74, 0x0F, 0xF0, 0x90, 0x06, 0x07, -0x74, 0x02, 0xF0, 0x22, 0x90, 0x10, 0x38, 0x74, 0x1F, 0xF0, 0x90, 0x06, 0x07, 0xE0, 0x44, 0x1C, -0xF0, 0x90, 0x06, 0x0B, 0x74, 0x70, 0xF0, 0xE4, 0x90, 0x10, 0x34, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, -0xA3, 0xF0, 0x22, 0x90, 0x10, 0x38, 0xE0, 0x64, 0x1F, 0x70, 0x4E, 0x90, 0x06, 0x15, 0xE0, 0xFE, -0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x33, 0xF0, 0xED, 0xA3, 0xF0, 0x90, 0x10, 0x55, -0xE0, 0xFF, 0xC3, 0x90, 0x45, 0x34, 0xE0, 0x9F, 0x90, 0x45, 0x33, 0xE0, 0x94, 0x00, 0x50, 0x21, -0xE4, 0x90, 0x06, 0x60, 0xF0, 0x90, 0x10, 0x3D, 0x74, 0x09, 0xF0, 0xE4, 0x90, 0x10, 0x4C, 0xF0, -0xA3, 0xF0, 0xC2, 0x04, 0x90, 0x06, 0x23, 0x74, 0x81, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, -0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, -0x22, 0x90, 0x06, 0x13, 0xE0, 0xFE, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x35, 0xF0, -0xED, 0xA3, 0xF0, 0x90, 0x06, 0x15, 0xE0, 0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x45, -0x33, 0xF0, 0xED, 0xA3, 0xF0, 0xA3, 0xE0, 0x70, 0x02, 0xA3, 0xE0, 0x70, 0x13, 0x90, 0x10, 0x55, -0xE0, 0xFF, 0xC3, 0x90, 0x45, 0x34, 0xE0, 0x9F, 0x90, 0x45, 0x33, 0xE0, 0x94, 0x00, 0x40, 0x08, -0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, -0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x10, 0x38, 0xE0, 0xB4, 0x1F, 0x08, 0x90, 0x06, 0x60, 0x74, -0x01, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0x06, 0x60, 0xF0, 0x90, 0x10, 0x3D, 0x74, 0x07, 0xF0, 0xE4, -0x90, 0x10, 0x4C, 0xF0, 0xA3, 0xF0, 0xC2, 0x04, 0x90, 0x06, 0x23, 0x74, 0x81, 0xF0, 0xA3, 0x74, -0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x06, 0x10, 0xE0, 0x24, 0x7F, 0x60, 0x14, 0x14, 0x60, 0x4E, -0x24, 0x02, 0x60, 0x03, 0x02, 0x18, 0xD2, 0xE4, 0x90, 0x06, 0x60, 0xF0, 0xA3, 0xF0, 0x02, 0x18, -0xDA, 0x90, 0x06, 0x15, 0xE0, 0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x33, 0xF0, -0xED, 0xA3, 0xF0, 0x90, 0x10, 0x55, 0xE0, 0xFF, 0xC3, 0x90, 0x45, 0x34, 0xE0, 0x9F, 0x90, 0x45, -0x33, 0xE0, 0x94, 0x00, 0x50, 0x07, 0x90, 0x10, 0x38, 0xE0, 0xB4, 0x0F, 0x08, 0x90, 0x06, 0x22, -0xE0, 0x44, 0x08, 0xF0, 0x22, 0xE4, 0x90, 0x06, 0x60, 0xF0, 0xA3, 0xF0, 0x80, 0x6C, 0x90, 0x06, -0x15, 0xE0, 0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x33, 0xF0, 0xED, 0xA3, 0xF0, -0x90, 0x45, 0x33, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x64, 0x81, 0x4E, 0x60, 0x0C, 0xEF, 0x64, 0x82, -0x4E, 0x60, 0x06, 0xEF, 0x64, 0x03, 0x4E, 0x70, 0x0B, 0x90, 0x10, 0x38, 0xE0, 0xB4, 0x0F, 0x0C, -0xEF, 0x4E, 0x60, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x7E, 0x00, 0xEF, 0x54, -0x7F, 0x24, 0x34, 0xF5, 0x82, 0xEE, 0x34, 0x10, 0xF5, 0x83, 0xE0, 0xB4, 0x01, 0x08, 0x90, 0x06, -0x60, 0x74, 0x01, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0x06, 0x60, 0xF0, 0xE4, 0x90, 0x06, 0x61, 0xF0, -0x80, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x10, 0x3D, 0x74, 0x01, 0xF0, -0xE4, 0x90, 0x10, 0x4C, 0xF0, 0xA3, 0xF0, 0xC2, 0x04, 0x90, 0x06, 0x23, 0x74, 0x82, 0xF0, 0xA3, -0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x06, 0x10, 0xE0, 0x24, 0xFE, 0x60, 0x03, 0x02, 0x19, -0xBA, 0x90, 0x06, 0x15, 0xE0, 0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x33, 0xF0, -0xED, 0xA3, 0xF0, 0x90, 0x06, 0x13, 0xE0, 0xFE, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x45, -0x35, 0xF0, 0xED, 0xA3, 0xF0, 0x90, 0x10, 0x38, 0xE0, 0xF9, 0x64, 0x1F, 0x70, 0x76, 0x90, 0x45, -0x33, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x64, 0x81, 0x4E, 0x70, 0x19, 0x90, 0x06, 0x0B, 0xE0, 0x54, -0xFB, 0xF0, 0x7C, 0x00, 0xEF, 0x54, 0x7F, 0x24, 0x34, 0xF5, 0x82, 0xEC, 0x34, 0x10, 0xF5, 0x83, -0xE4, 0xF0, 0x80, 0x6E, 0xEF, 0x64, 0x82, 0x4E, 0x70, 0x1C, 0x90, 0x06, 0x0B, 0xE0, 0x54, 0xFE, -0xF0, 0x7E, 0x00, 0x90, 0x45, 0x34, 0xE0, 0x54, 0x7F, 0x24, 0x34, 0xF5, 0x82, 0xEE, 0x34, 0x10, -0xF5, 0x83, 0xE4, 0xF0, 0x80, 0x4C, 0x90, 0x45, 0x33, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x64, 0x03, -0x4E, 0x70, 0x19, 0x90, 0x06, 0x0B, 0xE0, 0x54, 0xFD, 0xF0, 0x7E, 0x00, 0xEF, 0x54, 0x7F, 0x24, -0x34, 0xF5, 0x82, 0xEE, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x80, 0x26, 0x90, 0x06, 0x22, 0xE0, -0x44, 0x08, 0xF0, 0x22, 0xE9, 0xB4, 0x0F, 0x1A, 0x90, 0x45, 0x33, 0xE0, 0x70, 0x02, 0xA3, 0xE0, -0x60, 0x10, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, -0xF0, 0x22, 0xC2, 0x04, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, -0x22, 0x90, 0x06, 0x10, 0xE0, 0x24, 0xFE, 0x60, 0x44, 0x24, 0x02, 0x60, 0x03, 0x02, 0x1A, 0xCA, -0x90, 0x06, 0x13, 0xE0, 0xFE, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x35, 0xF0, 0xED, -0xA3, 0xF0, 0x90, 0x45, 0x35, 0xE0, 0x70, 0x04, 0xA3, 0xE0, 0x64, 0x02, 0x70, 0x17, 0x90, 0x06, -0x14, 0xE0, 0x70, 0x11, 0x90, 0x10, 0x3D, 0x74, 0x0F, 0xF0, 0x90, 0x06, 0x15, 0xE0, 0x90, 0x10, -0x50, 0xF0, 0x02, 0x1A, 0xD2, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x15, -0xE0, 0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x33, 0xF0, 0xED, 0xA3, 0xF0, 0x90, -0x06, 0x13, 0xE0, 0xFE, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x35, 0xF0, 0xED, 0xA3, -0xF0, 0x90, 0x10, 0x38, 0xE0, 0x64, 0x1F, 0x70, 0x79, 0x90, 0x45, 0x33, 0xE0, 0xFE, 0xA3, 0xE0, -0xFF, 0x64, 0x81, 0x4E, 0x70, 0x1A, 0x90, 0x06, 0x0B, 0xE0, 0x44, 0x04, 0xF0, 0x7C, 0x00, 0xEF, -0x54, 0x7F, 0x24, 0x34, 0xF5, 0x82, 0xEC, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x01, 0xF0, 0x80, 0x62, -0xEF, 0x64, 0x82, 0x4E, 0x70, 0x1D, 0x90, 0x06, 0x0B, 0xE0, 0x44, 0x01, 0xF0, 0x7E, 0x00, 0x90, -0x45, 0x34, 0xE0, 0x54, 0x7F, 0x24, 0x34, 0xF5, 0x82, 0xEE, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x01, -0xF0, 0x80, 0x3F, 0x90, 0x45, 0x33, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x64, 0x03, 0x4E, 0x70, 0x1A, -0x90, 0x06, 0x0B, 0xE0, 0x44, 0x02, 0xF0, 0x7E, 0x00, 0xEF, 0x54, 0x7F, 0x24, 0x34, 0xF5, 0x82, -0xEE, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x01, 0xF0, 0x80, 0x18, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, -0xF0, 0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, -0xF0, 0x22, 0xC2, 0x04, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, -0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x10, 0xE0, 0x64, 0x40, 0x60, -0x03, 0x02, 0x1C, 0xA2, 0xE0, 0x90, 0x43, 0x1E, 0xF0, 0x90, 0x06, 0x11, 0xE0, 0x90, 0x43, 0x1F, -0xF0, 0x90, 0x06, 0x13, 0xE0, 0xFE, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x43, 0x20, 0xF0, -0xED, 0xA3, 0xF0, 0x90, 0x06, 0x15, 0xE0, 0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x43, -0x22, 0xF0, 0xED, 0xA3, 0xF0, 0x90, 0x06, 0x17, 0xE0, 0xFE, 0x90, 0x06, 0x16, 0xE0, 0xFD, 0xEE, -0x90, 0x43, 0x24, 0xF0, 0xED, 0xA3, 0xF0, 0xE4, 0x90, 0x10, 0x44, 0xF0, 0xA3, 0xF0, 0x90, 0x43, -0x24, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x10, 0x42, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x43, 0x1F, -0xE0, 0x12, 0x28, 0x7E, 0x1B, 0x70, 0x00, 0x1B, 0xE6, 0x01, 0x1B, 0x79, 0x07, 0x1B, 0x8F, 0x0B, -0x1B, 0xAF, 0x0C, 0x1B, 0xC9, 0x10, 0x1B, 0xD9, 0x12, 0x1B, 0xFE, 0x13, 0x00, 0x00, 0x1C, 0x6A, -0x90, 0x10, 0x3D, 0x74, 0x0B, 0xF0, 0x02, 0x1C, 0x8E, 0x90, 0x10, 0x3D, 0x74, 0x0B, 0xF0, 0x12, -0x3D, 0x31, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90, -0x10, 0x3D, 0x74, 0x0B, 0xF0, 0x90, 0x43, 0x21, 0xE0, 0xFF, 0x90, 0x45, 0x45, 0xE0, 0xFD, 0x12, -0x39, 0xB4, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90, -0x45, 0x45, 0xE0, 0xFF, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0x12, 0x39, 0x2D, 0x90, 0x06, 0x23, 0x74, -0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x12, 0x3E, 0x03, 0x90, 0x06, 0x23, 0x74, -0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, -0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x10, 0x3D, 0x74, 0x10, 0xF0, 0x90, 0x06, 0x23, 0x74, -0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x12, 0x3D, 0xBA, 0x02, 0x1C, 0x8E, 0x90, 0x06, -0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x90, 0x04, 0x7A, 0xE0, 0x90, 0x45, -0x39, 0xF0, 0xE0, 0x54, 0x7F, 0xF0, 0x44, 0x80, 0xF0, 0x90, 0x04, 0x7A, 0xF0, 0x7D, 0x17, 0x7F, -0x0C, 0x12, 0x3D, 0x00, 0x7D, 0xB9, 0x7F, 0x0D, 0x12, 0x3D, 0x00, 0x90, 0x04, 0x54, 0x74, 0x01, -0xF0, 0xE4, 0x90, 0x04, 0x78, 0xF0, 0xA3, 0xF0, 0x90, 0x06, 0x20, 0x74, 0x20, 0xF0, 0x90, 0x04, -0x59, 0x74, 0x10, 0xF0, 0xE4, 0x90, 0x06, 0x05, 0xF0, 0x90, 0x06, 0x07, 0x74, 0x03, 0xF0, 0x75, -0xA8, 0x81, 0x43, 0x87, 0x01, 0x90, 0x06, 0x20, 0x74, 0x21, 0xF0, 0x90, 0x04, 0x58, 0x74, 0x14, -0xF0, 0xA3, 0x74, 0x50, 0xF0, 0x43, 0xA8, 0x81, 0x80, 0x24, 0x90, 0x10, 0x3D, 0x74, 0x0D, 0xF0, -0x7B, 0x01, 0x7A, 0x43, 0x79, 0x26, 0x90, 0x10, 0x3F, 0x12, 0x27, 0xBA, 0x90, 0x06, 0x17, 0xE0, -0xFE, 0x90, 0x06, 0x16, 0xE0, 0xFD, 0xEE, 0x90, 0x10, 0x42, 0xF0, 0xED, 0xA3, 0xF0, 0xE4, 0x90, -0x06, 0x24, 0xF0, 0x90, 0x06, 0x23, 0x74, 0xC0, 0xF0, 0x90, 0x06, 0x25, 0x74, 0x08, 0xF0, 0xC2, -0x04, 0x22, 0x90, 0x06, 0x10, 0xE0, 0x64, 0xC0, 0x60, 0x03, 0x02, 0x1E, 0x86, 0xE0, 0x90, 0x43, -0x1E, 0xF0, 0x90, 0x06, 0x11, 0xE0, 0x90, 0x43, 0x1F, 0xF0, 0x90, 0x06, 0x13, 0xE0, 0xFE, 0x90, -0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x43, 0x20, 0xF0, 0xED, 0xA3, 0xF0, 0x90, 0x06, 0x15, 0xE0, -0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x43, 0x22, 0xF0, 0xED, 0xA3, 0xF0, 0x90, 0x06, -0x17, 0xE0, 0xFE, 0x90, 0x06, 0x16, 0xE0, 0xFD, 0xEE, 0x90, 0x43, 0x24, 0xF0, 0xED, 0xA3, 0xF0, -0x90, 0x43, 0x24, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x10, 0x4C, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, -0x43, 0x1F, 0xE0, 0x24, 0xFA, 0x70, 0x03, 0x02, 0x1E, 0x58, 0x24, 0x05, 0x60, 0x03, 0x02, 0x1E, -0x6F, 0x90, 0x43, 0x22, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xEE, 0x60, 0x03, 0x02, 0x1E, 0x50, 0xEF, -0x24, 0xFE, 0x70, 0x03, 0x02, 0x1D, 0xCD, 0x14, 0x60, 0x31, 0x14, 0x60, 0x4E, 0x24, 0xFC, 0x70, -0x03, 0x02, 0x1E, 0x1A, 0x24, 0x07, 0x60, 0x03, 0x02, 0x1E, 0x50, 0x7B, 0x01, 0x7A, 0x00, 0x79, -0x00, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x43, 0x20, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, -0x10, 0x47, 0xEE, 0x8F, 0xF0, 0x12, 0x26, 0xB0, 0x02, 0x1E, 0x77, 0x7B, 0x01, 0x7A, 0x04, 0x79, -0x00, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x43, 0x20, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, -0x10, 0x47, 0xEE, 0x8F, 0xF0, 0x12, 0x26, 0xB0, 0x02, 0x1E, 0x77, 0x7B, 0x01, 0x7A, 0x43, 0x79, -0x26, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0xE4, 0x90, 0x45, 0x37, 0xF0, 0xA3, 0xF0, 0x90, 0x43, -0x24, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x90, 0x45, 0x38, 0xE0, 0x9F, 0x90, 0x45, 0x37, 0xE0, -0x9E, 0x40, 0x03, 0x02, 0x1E, 0x77, 0xA3, 0xE0, 0xFF, 0x90, 0x43, 0x21, 0xE0, 0x2F, 0xFF, 0x12, -0x3B, 0x25, 0x90, 0x45, 0x38, 0xE0, 0x24, 0x26, 0xF5, 0x82, 0xE4, 0x34, 0x43, 0xF5, 0x83, 0xEF, -0xF0, 0x90, 0x45, 0x37, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x80, 0xC1, 0x7B, 0x01, 0x7A, -0x43, 0x79, 0x26, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0xE4, 0x90, 0x45, 0x37, 0xF0, 0xA3, 0xF0, -0x90, 0x43, 0x24, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x90, 0x45, 0x38, 0xE0, 0x9F, 0x90, 0x45, -0x37, 0xE0, 0x9E, 0x40, 0x03, 0x02, 0x1E, 0x77, 0xA3, 0xE0, 0xFE, 0x90, 0x43, 0x21, 0xE0, 0x2E, -0xFF, 0x74, 0x26, 0x2E, 0xF9, 0xE4, 0x34, 0x43, 0xFA, 0x7B, 0x01, 0x12, 0x3C, 0xCD, 0x90, 0x45, -0x37, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x80, 0xC6, 0x7B, 0x01, 0x7A, 0x43, 0x79, 0x26, -0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0xD3, 0x90, 0x43, 0x25, 0xE0, 0x94, 0x02, 0x90, 0x43, 0x24, -0xE0, 0x94, 0x00, 0x40, 0x0F, 0xE4, 0xF0, 0xA3, 0x74, 0x02, 0xF0, 0x90, 0x10, 0x4C, 0xE4, 0xF0, -0xA3, 0x74, 0x02, 0xF0, 0x90, 0x43, 0x26, 0x74, 0x33, 0xF0, 0xA3, 0x74, 0x01, 0xF0, 0x80, 0x27, -0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x7B, 0x01, 0x7A, 0x44, 0x79, 0x2E, 0x90, 0x10, -0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0x74, 0x0A, 0xF0, 0x80, 0x08, 0x90, -0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x24, 0x74, 0x08, 0xF0, 0x12, 0x33, 0xF6, -0x90, 0x10, 0x3D, 0x74, 0x0C, 0xF0, 0x22, 0xD2, 0x00, 0x90, 0x43, 0x1F, 0xE0, 0x12, 0x28, 0x7E, -0x1E, 0xAF, 0x04, 0x1F, 0xB1, 0x05, 0x1F, 0xC4, 0x08, 0x20, 0xE2, 0x09, 0x21, 0x37, 0x0A, 0x21, -0xE9, 0x0D, 0x22, 0x7F, 0x0E, 0x22, 0xB1, 0x0F, 0x23, 0x3B, 0x11, 0x00, 0x00, 0x23, 0x4F, 0x90, -0x43, 0x22, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xEE, 0x60, 0x03, 0x02, 0x23, 0x4F, 0xEF, 0x24, 0xFE, -0x70, 0x03, 0x02, 0x1F, 0x7D, 0x14, 0x60, 0x4B, 0x14, 0x70, 0x03, 0x02, 0x1F, 0x51, 0x24, 0x03, -0x60, 0x03, 0x02, 0x23, 0x4F, 0x90, 0x43, 0x21, 0xE0, 0xFF, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, -0x00, 0xF5, 0x83, 0xC0, 0x83, 0xC0, 0x82, 0xE0, 0xFE, 0x90, 0x43, 0x27, 0xE0, 0xF4, 0xFD, 0xEE, -0x5D, 0xD0, 0x82, 0xD0, 0x83, 0xF0, 0x74, 0x00, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x00, 0xF5, 0x83, -0xC0, 0x83, 0xC0, 0x82, 0xE0, 0xFF, 0x90, 0x43, 0x26, 0xE0, 0xFE, 0xEF, 0x4E, 0xD0, 0x82, 0xD0, -0x83, 0xF0, 0x22, 0x90, 0x43, 0x21, 0xE0, 0xFF, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, -0x83, 0xC0, 0x83, 0xC0, 0x82, 0xE0, 0xFE, 0x90, 0x43, 0x27, 0xE0, 0xF4, 0xFD, 0xEE, 0x5D, 0xD0, -0x82, 0xD0, 0x83, 0xF0, 0x74, 0x00, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xC0, 0x83, -0xC0, 0x82, 0xE0, 0xFF, 0x90, 0x43, 0x26, 0xE0, 0xFE, 0xEF, 0x4E, 0xD0, 0x82, 0xD0, 0x83, 0xF0, -0x22, 0x90, 0x43, 0x21, 0xE0, 0xFF, 0x12, 0x3B, 0x25, 0x90, 0x45, 0x37, 0xEF, 0xF0, 0x90, 0x43, -0x27, 0xE0, 0xF4, 0x5F, 0xFF, 0x90, 0x45, 0x37, 0xF0, 0xFE, 0x90, 0x43, 0x21, 0xE0, 0xFF, 0x90, -0x43, 0x26, 0xE0, 0x4E, 0xFD, 0x12, 0x3A, 0x33, 0x72, 0x00, 0x92, 0x00, 0x22, 0x90, 0x43, 0x21, -0xE0, 0xFF, 0x7B, 0x01, 0x7A, 0x45, 0x79, 0x37, 0x12, 0x3C, 0xCD, 0x90, 0x45, 0x37, 0xE0, 0xFF, -0x90, 0x43, 0x27, 0xE0, 0xF4, 0xFE, 0xEF, 0x5E, 0xFF, 0x90, 0x45, 0x37, 0xF0, 0xFE, 0x90, 0x43, -0x21, 0xE0, 0xFF, 0x90, 0x43, 0x26, 0xE0, 0x4E, 0xFD, 0x12, 0x3D, 0x00, 0x72, 0x00, 0x92, 0x00, -0x22, 0x7B, 0x01, 0x7A, 0x44, 0x79, 0x2E, 0x90, 0x45, 0x3B, 0x12, 0x27, 0xBA, 0x7A, 0x43, 0x79, -0x26, 0x02, 0x2A, 0xF6, 0x90, 0x43, 0x21, 0xE0, 0xFD, 0x90, 0x04, 0xBC, 0xF0, 0x90, 0x43, 0x20, -0xE0, 0xFA, 0xA3, 0xE0, 0xFB, 0xEA, 0x90, 0x04, 0xBD, 0xF0, 0x90, 0x43, 0x26, 0xE0, 0x90, 0x04, -0xC0, 0xF0, 0x90, 0x43, 0x27, 0xE0, 0x90, 0x04, 0xC1, 0xF0, 0x90, 0x43, 0x28, 0xE0, 0x90, 0x04, -0xC2, 0xF0, 0x90, 0x43, 0x29, 0xE0, 0x90, 0x04, 0xC3, 0xF0, 0x90, 0x04, 0xBE, 0x74, 0x01, 0xF0, -0xED, 0x04, 0x90, 0x04, 0xBC, 0xF0, 0xEB, 0x24, 0x01, 0xE4, 0x3A, 0xA3, 0xF0, 0x90, 0x43, 0x2A, -0xE0, 0x90, 0x04, 0xC0, 0xF0, 0x90, 0x43, 0x2B, 0xE0, 0x90, 0x04, 0xC1, 0xF0, 0x90, 0x43, 0x2C, -0xE0, 0x90, 0x04, 0xC2, 0xF0, 0x90, 0x43, 0x2D, 0xE0, 0x90, 0x04, 0xC3, 0xF0, 0x90, 0x04, 0xBE, -0x74, 0x01, 0xF0, 0xE4, 0x90, 0x45, 0x35, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x35, 0xE0, 0xFE, 0xA3, -0xE0, 0xFF, 0xC3, 0x94, 0x04, 0xEE, 0x64, 0x80, 0x94, 0x80, 0x40, 0x03, 0x02, 0x23, 0x4F, 0x90, -0x43, 0x21, 0xE0, 0x24, 0x02, 0xFD, 0x90, 0x45, 0x36, 0xE0, 0xF9, 0x2D, 0xFD, 0x90, 0x43, 0x23, -0xE0, 0x25, 0xE0, 0x25, 0xE0, 0x2D, 0x90, 0x04, 0xBC, 0xF0, 0x90, 0x43, 0x21, 0xE0, 0x24, 0x02, -0xFD, 0x90, 0x43, 0x20, 0xE0, 0x34, 0x00, 0xCD, 0x2F, 0xCD, 0x3E, 0xFC, 0x90, 0x43, 0x22, 0xE0, -0xFE, 0xA3, 0xE0, 0x78, 0x02, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0x2D, 0xEC, 0x3E, 0x90, -0x04, 0xBD, 0xF0, 0x75, 0xF0, 0x04, 0xE9, 0x90, 0x43, 0x2E, 0x12, 0x27, 0x8E, 0xE0, 0x90, 0x04, -0xC0, 0xF0, 0x75, 0xF0, 0x04, 0xE9, 0x90, 0x43, 0x2F, 0x12, 0x27, 0x8E, 0xE0, 0x90, 0x04, 0xC1, -0xF0, 0x75, 0xF0, 0x04, 0xE9, 0x90, 0x43, 0x30, 0x12, 0x27, 0x8E, 0xE0, 0x90, 0x04, 0xC2, 0xF0, -0x75, 0xF0, 0x04, 0xE9, 0x90, 0x43, 0x31, 0x12, 0x27, 0x8E, 0xE0, 0x90, 0x04, 0xC3, 0xF0, 0x90, -0x04, 0xBE, 0x74, 0x01, 0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x02, -0x20, 0x3A, 0xE4, 0x90, 0x04, 0xBD, 0xF0, 0x90, 0x04, 0xC0, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, -0xF0, 0x90, 0x45, 0x35, 0xF0, 0xA3, 0xF0, 0x90, 0x43, 0x24, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, -0x90, 0x45, 0x36, 0xE0, 0x9F, 0x90, 0x45, 0x35, 0xE0, 0x9E, 0x40, 0x03, 0x02, 0x23, 0x4F, 0xA3, -0xE0, 0x24, 0x26, 0xF5, 0x82, 0xE4, 0x34, 0x43, 0xF5, 0x83, 0xE0, 0x75, 0xF0, 0x16, 0xA4, 0x24, -0x20, 0x90, 0x04, 0xBC, 0xF0, 0x90, 0x04, 0xBE, 0x74, 0x01, 0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75, -0xF0, 0x01, 0x12, 0x26, 0xB0, 0x80, 0xC0, 0xE4, 0x90, 0x45, 0x35, 0xF0, 0xA3, 0xF0, 0xFD, 0xFC, -0x90, 0x43, 0x24, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x90, 0x45, 0x36, 0xE0, 0x9F, 0x90, 0x45, -0x35, 0xE0, 0x9E, 0x40, 0x03, 0x02, 0x23, 0x4F, 0x90, 0x43, 0x21, 0xE0, 0x2D, 0x90, 0x04, 0xBC, -0xF0, 0x90, 0x43, 0x21, 0xE0, 0x2D, 0x90, 0x43, 0x20, 0xE0, 0x3C, 0x90, 0x04, 0xBD, 0xF0, 0x90, -0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xFE, 0x74, 0x26, 0x25, 0xF0, 0xF5, 0x82, -0x74, 0x43, 0x3E, 0xF5, 0x83, 0xE0, 0x90, 0x04, 0xC0, 0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0, -0x01, 0x12, 0x26, 0xC6, 0xFE, 0x74, 0x26, 0x25, 0xF0, 0xF5, 0x82, 0x74, 0x43, 0x3E, 0xF5, 0x83, -0xE0, 0x90, 0x04, 0xC1, 0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xFE, -0x74, 0x26, 0x25, 0xF0, 0xF5, 0x82, 0x74, 0x43, 0x3E, 0xF5, 0x83, 0xE0, 0x90, 0x04, 0xC2, 0xF0, -0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xFE, 0x74, 0x26, 0x25, 0xF0, 0xF5, -0x82, 0x74, 0x43, 0x3E, 0xF5, 0x83, 0xE0, 0x90, 0x04, 0xC3, 0xF0, 0x90, 0x04, 0xBE, 0x74, 0x01, -0xF0, 0x0D, 0xBD, 0x00, 0x01, 0x0C, 0x02, 0x21, 0x40, 0x90, 0x43, 0x20, 0xE0, 0xFE, 0xA3, 0xE0, -0xFF, 0x64, 0x05, 0x4E, 0x70, 0x40, 0x90, 0x45, 0x35, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x36, 0xE0, -0xFD, 0x24, 0x26, 0xF5, 0x82, 0xE4, 0x34, 0x43, 0xF5, 0x83, 0xE0, 0xFC, 0x74, 0x40, 0x2D, 0xF5, -0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xEC, 0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12, -0x26, 0xB0, 0x90, 0x45, 0x35, 0xE0, 0x70, 0x04, 0xA3, 0xE0, 0x64, 0x08, 0x70, 0xCE, 0x90, 0x04, -0x48, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0xEF, 0x64, 0x06, 0x4E, 0x60, 0x03, 0x02, 0x23, 0x4F, 0x90, -0x45, 0x35, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x36, 0xE0, 0xFF, 0x24, 0x26, 0xF5, 0x82, 0xE4, 0x34, -0x43, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0x38, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xEE, -0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x90, 0x45, 0x35, 0xE0, 0x70, -0x04, 0xA3, 0xE0, 0x64, 0x08, 0x70, 0xCE, 0x90, 0x04, 0x48, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, -0x43, 0x26, 0xE0, 0x90, 0x04, 0x22, 0xF0, 0x90, 0x43, 0x27, 0xE0, 0x90, 0x04, 0x23, 0xF0, 0x90, -0x43, 0x28, 0xE0, 0x90, 0x04, 0x24, 0xF0, 0x90, 0x43, 0x29, 0xE0, 0x90, 0x04, 0x25, 0xF0, 0x90, -0x43, 0x2A, 0xE0, 0x90, 0x04, 0x28, 0xF0, 0x90, 0x43, 0x2B, 0xE0, 0xFD, 0x7F, 0x0A, 0x02, 0x3D, -0x00, 0x90, 0x43, 0x26, 0xE0, 0x90, 0x04, 0x22, 0xF0, 0x90, 0x43, 0x27, 0xE0, 0x90, 0x04, 0x23, -0xF0, 0x90, 0x43, 0x28, 0xE0, 0x90, 0x04, 0x24, 0xF0, 0x90, 0x43, 0x29, 0xE0, 0x90, 0x04, 0x25, -0xF0, 0x90, 0x43, 0x2A, 0xE0, 0x90, 0x04, 0x28, 0xF0, 0x90, 0x43, 0x2B, 0xE0, 0xFD, 0x7F, 0x0A, -0x12, 0x3D, 0x00, 0x90, 0x43, 0x2C, 0xE0, 0xFD, 0x7F, 0x88, 0x12, 0x3D, 0x00, 0x90, 0x04, 0x4C, -0xE0, 0x54, 0xFC, 0xF0, 0xE0, 0xFF, 0x90, 0x43, 0x2D, 0xE0, 0xFE, 0xEF, 0x4E, 0x90, 0x04, 0x4C, -0xF0, 0xE4, 0x90, 0x45, 0x35, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x36, 0xE0, 0xFF, 0x24, 0x2E, 0xF5, -0x82, 0xE4, 0x34, 0x43, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0xDC, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x04, -0xF5, 0x83, 0xEE, 0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x90, 0x45, -0x35, 0xE0, 0x70, 0x04, 0xA3, 0xE0, 0x64, 0x22, 0x70, 0xCE, 0x22, 0x90, 0x43, 0x26, 0xE0, 0xFF, -0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFB, 0xA3, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x12, 0x3C, 0x90, 0x22, -0x90, 0x06, 0x30, 0x74, 0x70, 0xF0, 0x90, 0x06, 0x31, 0x74, 0xA0, 0xF0, 0xE0, 0x90, 0x06, 0x35, -0xF0, 0x90, 0x06, 0x36, 0x74, 0xC0, 0xF0, 0x90, 0x06, 0x37, 0x74, 0x08, 0xF0, 0xE4, 0x90, 0x45, -0x46, 0xF0, 0xA3, 0xF0, 0xC2, 0x05, 0x90, 0x06, 0x20, 0x74, 0x21, 0xF0, 0x90, 0x04, 0x58, 0x74, -0x14, 0xF0, 0xA3, 0x74, 0x50, 0xF0, 0x12, 0x3C, 0x43, 0x75, 0xA8, 0x81, 0x90, 0x06, 0x05, 0x74, -0x04, 0xF0, 0x90, 0x06, 0x0F, 0xE0, 0x30, 0xE4, 0x04, 0xD2, 0x06, 0x80, 0x02, 0xC2, 0x06, 0xE4, -0x90, 0x43, 0x19, 0xF0, 0x20, 0x05, 0x03, 0x02, 0x25, 0xFB, 0xC2, 0x05, 0x90, 0x10, 0x39, 0xE0, -0xFF, 0x20, 0xE5, 0x03, 0x02, 0x24, 0xCD, 0x54, 0xDF, 0xF0, 0x90, 0x06, 0x0E, 0xE0, 0x20, 0xE0, -0x03, 0x02, 0x24, 0x4D, 0x7D, 0x17, 0x7F, 0x0C, 0x12, 0x3D, 0x00, 0x7D, 0xB9, 0x7F, 0x0D, 0x12, -0x3D, 0x00, 0x90, 0x04, 0x54, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x45, 0x2F, 0xF0, 0xA3, 0xF0, 0x90, -0x04, 0x54, 0xE0, 0x30, 0xE0, 0x16, 0x90, 0x45, 0x2F, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, -0x90, 0x45, 0x2F, 0xE0, 0xB4, 0x07, 0xE8, 0xA3, 0xE0, 0xB4, 0xFF, 0xE3, 0xE4, 0x90, 0x04, 0x78, -0xF0, 0xA3, 0x74, 0x11, 0xF0, 0x90, 0x06, 0x0E, 0xE0, 0x54, 0x01, 0xF0, 0x90, 0x06, 0x30, 0x74, -0x70, 0xF0, 0x90, 0x06, 0x31, 0x74, 0xA0, 0xF0, 0xE0, 0x90, 0x06, 0x35, 0xF0, 0x90, 0x06, 0x36, -0x74, 0xC0, 0xF0, 0x90, 0x06, 0x37, 0x74, 0x08, 0xF0, 0x90, 0x06, 0x38, 0x74, 0x03, 0xF0, 0x90, -0x06, 0x01, 0xE0, 0x44, 0x20, 0xF0, 0x90, 0x06, 0x07, 0x74, 0x02, 0xF0, 0x90, 0x10, 0x38, 0x74, -0x07, 0xF0, 0x90, 0x06, 0x0E, 0xE0, 0x30, 0xE1, 0x04, 0xE0, 0x54, 0x02, 0xF0, 0x90, 0x06, 0x0E, -0xE0, 0x30, 0xE3, 0x11, 0xE0, 0x54, 0x08, 0xF0, 0x90, 0x06, 0x0F, 0xE0, 0x30, 0xE4, 0x04, 0xD2, -0x06, 0x80, 0x02, 0xC2, 0x06, 0x90, 0x06, 0x0E, 0xE0, 0x30, 0xE2, 0x0A, 0xE0, 0x54, 0x04, 0xF0, -0x90, 0x04, 0x79, 0x74, 0x11, 0xF0, 0x90, 0x06, 0x0E, 0xE0, 0x30, 0xE1, 0x50, 0xE0, 0x20, 0xE0, -0x4C, 0x7D, 0x17, 0x7F, 0x0C, 0x12, 0x3D, 0x00, 0x7D, 0xB9, 0x7F, 0x0D, 0x12, 0x3D, 0x00, 0x90, -0x04, 0x54, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x04, 0x78, 0xF0, 0xA3, 0xF0, 0x90, 0x06, 0x0E, 0xE0, -0x54, 0x02, 0xF0, 0x90, 0x06, 0x20, 0x74, 0x20, 0xF0, 0xE4, 0x90, 0x04, 0x58, 0xF0, 0x90, 0x06, -0x07, 0x74, 0x03, 0xF0, 0x90, 0x04, 0x7A, 0xE0, 0x90, 0x45, 0x2E, 0xF0, 0xE0, 0x54, 0xF9, 0xF0, -0x44, 0x02, 0xF0, 0x90, 0x04, 0x7A, 0xF0, 0x43, 0xA8, 0x81, 0x43, 0x87, 0x01, 0x90, 0x10, 0x39, -0xE0, 0x30, 0xE0, 0x22, 0x90, 0x06, 0x24, 0xE0, 0x30, 0xE4, 0x05, 0x12, 0x12, 0x0E, 0x80, 0x0F, -0x90, 0x06, 0x24, 0xE0, 0x30, 0xE3, 0x05, 0x12, 0x34, 0xB9, 0x80, 0x03, 0x12, 0x28, 0xF4, 0x90, -0x10, 0x39, 0xE0, 0x54, 0xFE, 0xF0, 0x90, 0x45, 0x46, 0xE0, 0x54, 0x14, 0x70, 0x09, 0xA3, 0xE0, -0xFF, 0x20, 0xE6, 0x03, 0x30, 0xE3, 0x4F, 0x7B, 0x01, 0x7A, 0x06, 0x79, 0x40, 0x12, 0x33, 0x2B, -0x90, 0x45, 0x46, 0xE0, 0xFF, 0x90, 0x06, 0x48, 0xF0, 0x90, 0x45, 0x47, 0xE0, 0x90, 0x06, 0x49, -0xF0, 0x90, 0x04, 0x2C, 0xE0, 0x90, 0x06, 0x4A, 0xF0, 0x90, 0x04, 0x2D, 0xE0, 0x90, 0x06, 0x4B, -0xF0, 0x90, 0x04, 0x2E, 0xE0, 0x90, 0x06, 0x4C, 0xF0, 0x90, 0x04, 0x2F, 0xE0, 0x90, 0x06, 0x4D, -0xF0, 0x90, 0x06, 0x3F, 0x74, 0x01, 0xF0, 0xEF, 0x54, 0xEB, 0x90, 0x45, 0x46, 0xF0, 0xA3, 0xE0, -0x54, 0xBF, 0xF0, 0x54, 0xF7, 0xF0, 0x90, 0x45, 0x47, 0xE0, 0xFF, 0x20, 0xE4, 0x03, 0x02, 0x25, -0xE8, 0x90, 0x04, 0x7A, 0xE0, 0x54, 0xDF, 0xF0, 0xE0, 0x90, 0x45, 0x2E, 0xF0, 0xE0, 0x20, 0xE6, -0x54, 0x90, 0x04, 0x7A, 0xE0, 0x90, 0x45, 0x2E, 0xF0, 0xE0, 0x54, 0x7F, 0xF0, 0x44, 0x80, 0xF0, -0x90, 0x04, 0x7A, 0xF0, 0xEF, 0x54, 0xEF, 0x90, 0x45, 0x47, 0xF0, 0x7D, 0x17, 0x7F, 0x0C, 0x12, -0x3D, 0x00, 0x7D, 0xB9, 0x7F, 0x0D, 0x12, 0x3D, 0x00, 0x90, 0x04, 0x54, 0x74, 0x01, 0xF0, 0xE4, -0x90, 0x04, 0x78, 0xF0, 0xA3, 0xF0, 0x90, 0x06, 0x20, 0x74, 0x20, 0xF0, 0x90, 0x04, 0x59, 0x74, -0x10, 0xF0, 0xE4, 0x90, 0x06, 0x05, 0xF0, 0x90, 0x06, 0x07, 0x74, 0x03, 0xF0, 0x75, 0xA8, 0x81, -0x43, 0x87, 0x01, 0x80, 0x23, 0x90, 0x04, 0x7A, 0xE0, 0x90, 0x45, 0x2E, 0xF0, 0xE0, 0x54, 0x7F, -0xF0, 0x90, 0x04, 0x7A, 0xF0, 0x90, 0x10, 0x38, 0x74, 0x07, 0xF0, 0x90, 0x06, 0x05, 0x74, 0x04, -0xF0, 0x90, 0x45, 0x47, 0xE0, 0x54, 0xEF, 0xF0, 0x90, 0x06, 0x20, 0x74, 0x21, 0xF0, 0x90, 0x04, -0x58, 0x74, 0x14, 0xF0, 0xA3, 0x74, 0x50, 0xF0, 0x43, 0xA8, 0x81, 0x90, 0x43, 0x19, 0xE0, 0x64, -0x01, 0x60, 0x03, 0x02, 0x23, 0xA4, 0xF0, 0x90, 0x06, 0x24, 0xE0, 0x30, 0xE3, 0x03, 0x02, 0x23, -0xA4, 0x90, 0x06, 0x25, 0xE0, 0x54, 0xF7, 0xF0, 0x30, 0x04, 0x07, 0xE4, 0x90, 0x06, 0x23, 0xF0, -0x80, 0x06, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0x90, 0x06, 0x24, 0x74, 0x08, 0xF0, 0x90, 0x06, -0x25, 0xF0, 0x02, 0x23, 0xA4, 0x22, 0xBB, 0x01, 0x06, 0x89, 0x82, 0x8A, 0x83, 0xE0, 0x22, 0x50, -0x02, 0xE7, 0x22, 0xBB, 0xFE, 0x02, 0xE3, 0x22, 0x89, 0x82, 0x8A, 0x83, 0xE4, 0x93, 0x22, 0xBB, -0x01, 0x0C, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE0, 0x22, 0x50, 0x06, -0xE9, 0x25, 0x82, 0xF8, 0xE6, 0x22, 0xBB, 0xFE, 0x06, 0xE9, 0x25, 0x82, 0xF8, 0xE2, 0x22, 0xE5, -0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE4, 0x93, 0x22, 0xBB, 0x01, 0x06, 0x89, -0x82, 0x8A, 0x83, 0xF0, 0x22, 0x50, 0x02, 0xF7, 0x22, 0xBB, 0xFE, 0x01, 0xF3, 0x22, 0xF8, 0xBB, -0x01, 0x0D, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE8, 0xF0, 0x22, 0x50, -0x06, 0xE9, 0x25, 0x82, 0xC8, 0xF6, 0x22, 0xBB, 0xFE, 0x05, 0xE9, 0x25, 0x82, 0xC8, 0xF2, 0x22, -0xC5, 0xF0, 0xF8, 0xA3, 0xE0, 0x28, 0xF0, 0xC5, 0xF0, 0xF8, 0xE5, 0x82, 0x15, 0x82, 0x70, 0x02, -0x15, 0x83, 0xE0, 0x38, 0xF0, 0x22, 0xA3, 0xF8, 0xE0, 0xC5, 0xF0, 0x25, 0xF0, 0xF0, 0xE5, 0x82, -0x15, 0x82, 0x70, 0x02, 0x15, 0x83, 0xE0, 0xC8, 0x38, 0xF0, 0xE8, 0x22, 0xBB, 0x01, 0x10, 0xE5, -0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE0, 0xF5, 0xF0, 0xA3, 0xE0, 0x22, 0x50, -0x09, 0xE9, 0x25, 0x82, 0xF8, 0x86, 0xF0, 0x08, 0xE6, 0x22, 0xBB, 0xFE, 0x0A, 0xE9, 0x25, 0x82, -0xF8, 0xE2, 0xF5, 0xF0, 0x08, 0xE2, 0x22, 0xE5, 0x83, 0x2A, 0xF5, 0x83, 0xE9, 0x93, 0xF5, 0xF0, -0xA3, 0xE9, 0x93, 0x22, 0xBB, 0x01, 0x0D, 0xC5, 0x82, 0x29, 0xC5, 0x82, 0xC5, 0x83, 0x3A, 0xC5, -0x83, 0x02, 0x26, 0xB0, 0x50, 0x11, 0xC5, 0x82, 0x29, 0xF8, 0x08, 0xE5, 0xF0, 0x26, 0xF6, 0x18, -0xF5, 0xF0, 0xE5, 0x82, 0x36, 0xF6, 0x22, 0xBB, 0xFE, 0x11, 0xC5, 0x82, 0x29, 0xF8, 0x08, 0xE2, -0x25, 0xF0, 0xF5, 0xF0, 0xF2, 0x18, 0xE2, 0x35, 0x82, 0xF2, 0x22, 0xF8, 0xE5, 0x82, 0x29, 0xF5, -0x82, 0xE5, 0x83, 0x2A, 0xF5, 0x83, 0x74, 0x01, 0x93, 0x25, 0xF0, 0xF5, 0xF0, 0xE4, 0x93, 0x38, -0x22, 0xF8, 0xBB, 0x01, 0x11, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE8, -0xF0, 0xE5, 0xF0, 0xA3, 0xF0, 0x22, 0x50, 0x09, 0xE9, 0x25, 0x82, 0xC8, 0xF6, 0x08, 0xA6, 0xF0, -0x22, 0xBB, 0xFE, 0x09, 0xE9, 0x25, 0x82, 0xC8, 0xF2, 0xE5, 0xF0, 0x08, 0xF2, 0x22, 0xA4, 0x25, -0x82, 0xF5, 0x82, 0xE5, 0xF0, 0x35, 0x83, 0xF5, 0x83, 0x22, 0xE0, 0xFB, 0xA3, 0xE0, 0xFA, 0xA3, -0xE0, 0xF9, 0x22, 0xF8, 0xE0, 0xFB, 0xA3, 0xA3, 0xE0, 0xF9, 0x25, 0xF0, 0xF0, 0xE5, 0x82, 0x15, -0x82, 0x70, 0x02, 0x15, 0x83, 0xE0, 0xFA, 0x38, 0xF0, 0x22, 0xEB, 0xF0, 0xA3, 0xEA, 0xF0, 0xA3, -0xE9, 0xF0, 0x22, 0xBB, 0x01, 0x0D, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, -0x02, 0x27, 0x9A, 0x50, 0x07, 0xE9, 0x25, 0x82, 0xF8, 0x02, 0x28, 0xA4, 0xBB, 0xFE, 0x07, 0xE9, -0x25, 0x82, 0xF8, 0x02, 0x28, 0xC6, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, -0x02, 0x28, 0xE8, 0xBB, 0x01, 0x0D, 0xC5, 0x82, 0x29, 0xC5, 0x82, 0xC5, 0x83, 0x3A, 0xC5, 0x83, -0x02, 0x27, 0xA3, 0x50, 0x08, 0xF8, 0xE9, 0x25, 0x82, 0xC8, 0x02, 0x28, 0xAD, 0xBB, 0xFE, 0x08, -0xF8, 0xE9, 0x25, 0x82, 0xC8, 0x02, 0x28, 0xCF, 0xC5, 0x82, 0x29, 0xC5, 0x82, 0xC5, 0x83, 0x3A, -0xC5, 0x83, 0x02, 0x28, 0xE8, 0xBB, 0x01, 0x20, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, -0xF5, 0x83, 0xD0, 0xF0, 0xD0, 0xE0, 0xF8, 0xD0, 0xE0, 0xF9, 0xD0, 0xE0, 0xFA, 0xD0, 0xE0, 0xFB, -0xE8, 0xC0, 0xE0, 0xC0, 0xF0, 0x02, 0x27, 0xBA, 0x50, 0x18, 0xE9, 0x25, 0x82, 0xF8, 0xD0, 0x83, -0xD0, 0x82, 0xD0, 0xE0, 0xF9, 0xD0, 0xE0, 0xFA, 0xD0, 0xE0, 0xFB, 0xC0, 0x82, 0xC0, 0x83, 0x02, -0x28, 0xBD, 0xBB, 0xFE, 0x18, 0xE9, 0x25, 0x82, 0xF8, 0xD0, 0x83, 0xD0, 0x82, 0xD0, 0xE0, 0xF9, -0xD0, 0xE0, 0xFA, 0xD0, 0xE0, 0xFB, 0xC0, 0x82, 0xC0, 0x83, 0x02, 0x28, 0xDF, 0x22, 0xD0, 0x83, -0xD0, 0x82, 0xF8, 0xE4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0D, 0xA3, 0xA3, 0x93, 0xF8, -0x74, 0x01, 0x93, 0xF5, 0x82, 0x88, 0x83, 0xE4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xEF, 0xA3, -0xA3, 0xA3, 0x80, 0xDF, 0xE6, 0xFB, 0x08, 0xE6, 0xFA, 0x08, 0xE6, 0xF9, 0x22, 0xFA, 0xE6, 0xFB, -0x08, 0x08, 0xE6, 0xF9, 0x25, 0xF0, 0xF6, 0x18, 0xE6, 0xCA, 0x3A, 0xF6, 0x22, 0xEB, 0xF6, 0x08, -0xEA, 0xF6, 0x08, 0xE9, 0xF6, 0x22, 0xE2, 0xFB, 0x08, 0xE2, 0xFA, 0x08, 0xE2, 0xF9, 0x22, 0xFA, -0xE2, 0xFB, 0x08, 0x08, 0xE2, 0xF9, 0x25, 0xF0, 0xF2, 0x18, 0xE2, 0xCA, 0x3A, 0xF2, 0x22, 0xEB, -0xF2, 0x08, 0xEA, 0xF2, 0x08, 0xE9, 0xF2, 0x22, 0xE4, 0x93, 0xFB, 0x74, 0x01, 0x93, 0xFA, 0x74, -0x02, 0x93, 0xF9, 0x22, 0x90, 0x06, 0x23, 0xE0, 0x54, 0x7F, 0xFF, 0xC3, 0x74, 0x40, 0x9F, 0x90, -0x45, 0x31, 0xF0, 0xE4, 0xA3, 0xF0, 0x90, 0x10, 0x3D, 0xE0, 0x64, 0x0B, 0x60, 0x03, 0x02, 0x2A, -0x60, 0x90, 0x10, 0x44, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x43, 0x21, 0xE0, 0x2F, 0x90, 0x45, -0x34, 0xF0, 0x90, 0x43, 0x20, 0xE0, 0x3E, 0x90, 0x45, 0x33, 0xF0, 0x90, 0x45, 0x31, 0xE0, 0x70, -0x03, 0x02, 0x2A, 0xA6, 0x14, 0xF0, 0x90, 0x43, 0x22, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xEE, 0x60, -0x03, 0x02, 0x2A, 0x57, 0xEF, 0x12, 0x28, 0x7E, 0x29, 0x6A, 0x01, 0x29, 0x94, 0x02, 0x29, 0xB5, -0x03, 0x29, 0xDE, 0x04, 0x29, 0xFE, 0x07, 0x2A, 0x31, 0x09, 0x2A, 0x31, 0x0A, 0x2A, 0x31, 0x0B, -0x2A, 0x31, 0x0C, 0x2A, 0x31, 0x0D, 0x00, 0x00, 0x2A, 0x57, 0x90, 0x45, 0x32, 0xE0, 0x24, 0x60, -0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x45, 0x33, 0xE4, 0x75, 0xF0, 0x01, -0x12, 0x26, 0xC6, 0xFC, 0x74, 0x00, 0x25, 0xF0, 0xF5, 0x82, 0x74, 0x00, 0x3C, 0xF5, 0x83, 0xEF, -0xF0, 0x02, 0x2A, 0x57, 0x90, 0x45, 0x33, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xAF, 0xF0, -0x90, 0x45, 0x32, 0xE0, 0x24, 0x60, 0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xE0, 0xFD, 0x12, -0x3D, 0x00, 0x02, 0x2A, 0x57, 0x90, 0x45, 0x32, 0xE0, 0x24, 0x60, 0xF5, 0x82, 0xE4, 0x34, 0x06, -0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x45, 0x33, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xFC, 0x74, -0x00, 0x25, 0xF0, 0xF5, 0x82, 0x74, 0x04, 0x3C, 0xF5, 0x83, 0xEF, 0xF0, 0x80, 0x79, 0x90, 0x45, -0x33, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xAF, 0xF0, 0x90, 0x45, 0x32, 0xE0, 0x24, 0x60, -0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xE0, 0xFD, 0x12, 0x3A, 0x33, 0x80, 0x59, 0x90, 0x45, -0x32, 0xE0, 0x24, 0x60, 0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xE0, 0xFD, 0x7F, 0xF1, 0x12, -0x3D, 0x00, 0x90, 0x45, 0x34, 0xE0, 0x44, 0x80, 0xFD, 0x7F, 0xF0, 0x12, 0x3D, 0x00, 0x90, 0x45, -0x33, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xAD, 0xF0, 0x7F, 0xF0, 0x12, 0x3D, 0x00, 0x80, -0x26, 0x90, 0x43, 0x22, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x45, 0x33, 0xE4, 0x75, 0xF0, 0x01, -0x12, 0x26, 0xC6, 0xAD, 0xF0, 0x90, 0x45, 0x32, 0xE0, 0x24, 0x60, 0xF5, 0x82, 0xE4, 0x34, 0x06, -0xF5, 0x83, 0xE0, 0xFB, 0x12, 0x3A, 0xAE, 0x90, 0x45, 0x32, 0xE0, 0x04, 0xF0, 0x02, 0x29, 0x2B, -0x90, 0x10, 0x3D, 0xE0, 0xFF, 0xB4, 0x0D, 0x2D, 0x90, 0x45, 0x31, 0xE0, 0x60, 0x38, 0xA3, 0xE0, -0xFE, 0x04, 0xF0, 0x74, 0x60, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xE0, 0xFE, 0x90, -0x10, 0x3F, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3, 0xEE, 0x12, 0x26, 0x7C, 0x90, 0x45, 0x31, -0xE0, 0x14, 0xF0, 0x80, 0xD3, 0xEF, 0xB4, 0x0C, 0x07, 0xC2, 0x8C, 0xE4, 0x90, 0x43, 0x19, 0xF0, -0xE4, 0x90, 0x10, 0x3D, 0xF0, 0x22, 0x30, 0x04, 0x0A, 0xC2, 0x04, 0x90, 0x06, 0x23, 0x74, 0xC0, -0xF0, 0x80, 0x08, 0xD2, 0x04, 0x90, 0x06, 0x23, 0x74, 0x40, 0xF0, 0x90, 0x45, 0x32, 0xE0, 0xFF, -0x90, 0x10, 0x44, 0xE4, 0x8F, 0xF0, 0x12, 0x26, 0xB0, 0x90, 0x10, 0x42, 0xE0, 0xFE, 0xA3, 0xE0, -0xFF, 0xA3, 0xE0, 0xB5, 0x06, 0x19, 0xA3, 0xE0, 0xB5, 0x07, 0x14, 0x90, 0x10, 0x3D, 0xE0, 0xB4, -0x0D, 0x03, 0x12, 0x1E, 0x87, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0x90, -0x06, 0x25, 0x74, 0x08, 0xF0, 0x22, 0x90, 0x45, 0x38, 0x12, 0x27, 0xBA, 0x12, 0x26, 0x36, 0x60, -0x03, 0x02, 0x2B, 0x8F, 0x7F, 0x1C, 0x12, 0x3B, 0x25, 0x90, 0x45, 0x3B, 0x12, 0x27, 0x9A, 0x90, -0x00, 0x08, 0xEF, 0x12, 0x26, 0x8E, 0x7F, 0x1D, 0x12, 0x3B, 0x25, 0x90, 0x45, 0x3B, 0x12, 0x27, -0x9A, 0x90, 0x00, 0x09, 0xEF, 0x12, 0x26, 0x8E, 0x7F, 0x1B, 0x12, 0x3B, 0x25, 0x90, 0x45, 0x3B, -0x12, 0x27, 0x9A, 0x90, 0x00, 0x07, 0xEF, 0x12, 0x26, 0x8E, 0xE9, 0x24, 0x07, 0xF9, 0xE4, 0x3A, -0xFA, 0x12, 0x26, 0x36, 0x54, 0x7F, 0x12, 0x26, 0x7C, 0x90, 0x45, 0x3B, 0x12, 0x27, 0x9A, 0x90, -0x00, 0x07, 0x12, 0x26, 0x4F, 0x90, 0x45, 0x45, 0xF0, 0x90, 0x04, 0x2B, 0x74, 0xFF, 0xF0, 0x12, -0x3C, 0x43, 0x90, 0x45, 0x3B, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x07, 0x12, 0x26, 0x4F, 0xFF, 0x12, -0x3D, 0x62, 0x90, 0x45, 0x3B, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x08, 0x12, 0x26, 0x4F, 0xFD, 0x90, -0x40, 0xC0, 0xF0, 0x90, 0x00, 0x07, 0x12, 0x26, 0x4F, 0xFF, 0x12, 0x39, 0x2D, 0x80, 0x1B, 0x12, -0x3D, 0xE2, 0x90, 0x04, 0x54, 0xE0, 0x54, 0xFB, 0xF0, 0x90, 0x06, 0x38, 0x74, 0x03, 0xF0, 0x12, -0x3D, 0x31, 0x90, 0x04, 0x48, 0x74, 0x02, 0xF0, 0x14, 0xF0, 0xE4, 0xFF, 0xFE, 0x74, 0xC4, 0x2F, -0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE0, 0xFD, 0x90, 0x45, 0x3B, 0x12, 0x27, 0x9A, 0xE9, -0x24, 0x01, 0xF9, 0xE4, 0x3A, 0xFA, 0xE9, 0x2F, 0xF9, 0xEA, 0x3E, 0xFA, 0xED, 0x12, 0x26, 0x7C, -0x0F, 0xBF, 0x00, 0x01, 0x0E, 0xEF, 0x64, 0x06, 0x4E, 0x70, 0xD2, 0x90, 0x45, 0x38, 0x12, 0x27, -0x9A, 0x90, 0x00, 0x01, 0x12, 0x26, 0x4F, 0x60, 0x31, 0xE4, 0xFE, 0xFF, 0x90, 0x45, 0x38, 0x12, -0x27, 0x9A, 0xE9, 0x24, 0x02, 0xF9, 0xE4, 0x3A, 0xFA, 0xE9, 0x2F, 0xF9, 0xEA, 0x3E, 0xFA, 0x12, -0x26, 0x36, 0xFD, 0x74, 0xC4, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xED, 0xF0, 0x0F, -0xBF, 0x00, 0x01, 0x0E, 0xEF, 0x64, 0x06, 0x4E, 0x70, 0xD2, 0x90, 0x45, 0x38, 0x12, 0x27, 0x9A, -0x90, 0x00, 0x08, 0x12, 0x26, 0x4F, 0x90, 0x04, 0x21, 0xF0, 0x90, 0x00, 0x09, 0x12, 0x26, 0x4F, -0x90, 0x04, 0x20, 0xF0, 0x90, 0x04, 0x50, 0xE0, 0x44, 0x82, 0xF0, 0x90, 0x04, 0x54, 0x74, 0x0E, -0xF0, 0x90, 0x45, 0x3B, 0x12, 0x27, 0x9A, 0xE4, 0x12, 0x26, 0x7C, 0xD3, 0x22, 0xAC, 0x07, 0xAA, -0x05, 0xD2, 0x03, 0x90, 0x04, 0x78, 0xE0, 0x54, 0xFE, 0xF0, 0xEC, 0xD3, 0x94, 0x0E, 0x40, 0x03, -0x02, 0x2C, 0xFA, 0xEA, 0x94, 0x0E, 0x50, 0x03, 0x02, 0x2C, 0xFA, 0x90, 0x40, 0xC9, 0xE0, 0xFD, -0x90, 0x40, 0xC8, 0xE0, 0xFB, 0x90, 0x40, 0xC7, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90, -0x40, 0xCC, 0xE0, 0xFD, 0x90, 0x40, 0xCB, 0xE0, 0xFB, 0x90, 0x40, 0xCA, 0x12, 0x3C, 0x89, 0x82, -0x03, 0x92, 0x03, 0x90, 0x40, 0xD2, 0xE0, 0xFD, 0x90, 0x40, 0xD1, 0xE0, 0xFB, 0x90, 0x40, 0xD0, -0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90, 0x40, 0xD8, 0xE0, 0xFD, 0x90, 0x40, 0xD7, 0xE0, -0xFB, 0x90, 0x40, 0xD6, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90, 0x40, 0xE1, 0xE0, 0xFD, -0x90, 0x40, 0xE0, 0xE0, 0xFB, 0x90, 0x40, 0xDF, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90, -0x40, 0xE7, 0xE0, 0xFD, 0x90, 0x40, 0xE6, 0xE0, 0xFB, 0x90, 0x40, 0xE5, 0x12, 0x3C, 0x89, 0x82, -0x03, 0x92, 0x03, 0x90, 0x40, 0xF0, 0xE0, 0xFD, 0x90, 0x40, 0xEF, 0xE0, 0xFB, 0x90, 0x40, 0xEE, -0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x02, 0x2D, 0x98, 0xEC, 0xD3, 0x94, 0x0E, 0x50, 0x03, -0x02, 0x2D, 0x98, 0xEA, 0xD3, 0x94, 0x0E, 0x40, 0x03, 0x02, 0x2D, 0x98, 0x90, 0x42, 0xF1, 0xE0, -0xFD, 0x90, 0x42, 0xF0, 0xE0, 0xFB, 0x90, 0x42, 0xEF, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, -0x90, 0x42, 0xF4, 0xE0, 0xFD, 0x90, 0x42, 0xF3, 0xE0, 0xFB, 0x90, 0x42, 0xF2, 0x12, 0x3C, 0x89, -0x82, 0x03, 0x92, 0x03, 0x90, 0x42, 0xFA, 0xE0, 0xFD, 0x90, 0x42, 0xF9, 0xE0, 0xFB, 0x90, 0x42, -0xF8, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90, 0x43, 0x00, 0xE0, 0xFD, 0x90, 0x42, 0xFF, -0xE0, 0xFB, 0x90, 0x42, 0xFE, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90, 0x43, 0x09, 0xE0, -0xFD, 0x90, 0x43, 0x08, 0xE0, 0xFB, 0x90, 0x43, 0x07, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, -0x90, 0x43, 0x0F, 0xE0, 0xFD, 0x90, 0x43, 0x0E, 0xE0, 0xFB, 0x90, 0x43, 0x0D, 0x12, 0x3C, 0x89, -0x82, 0x03, 0x92, 0x03, 0x90, 0x43, 0x18, 0xE0, 0xFD, 0x90, 0x43, 0x17, 0xE0, 0xFB, 0x90, 0x43, -0x16, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90, 0x04, 0x78, 0xE0, 0x44, 0x01, 0xF0, 0xA2, -0x03, 0x22, 0xAC, 0x07, 0xAA, 0x05, 0xD2, 0x03, 0xEC, 0xD3, 0x94, 0x0E, 0x40, 0x03, 0x02, 0x2E, -0x43, 0xEA, 0x94, 0x0E, 0x50, 0x03, 0x02, 0x2E, 0x43, 0x90, 0x40, 0xC9, 0xE0, 0xFD, 0x90, 0x40, -0xC8, 0xE0, 0xFB, 0x90, 0x40, 0xC7, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, -0x82, 0x03, 0x92, 0x03, 0x90, 0x40, 0xD8, 0xE0, 0xFD, 0x90, 0x40, 0xD7, 0xE0, 0xFB, 0x90, 0x40, -0xD6, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92, 0x03, 0x90, -0x40, 0xDE, 0xE0, 0xFD, 0x90, 0x40, 0xDD, 0xE0, 0xFB, 0x90, 0x40, 0xDC, 0xE0, 0x90, 0x45, 0x44, -0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92, 0x03, 0x90, 0x40, 0xE7, 0xE0, 0xFD, 0x90, -0x40, 0xE6, 0xE0, 0xFB, 0x90, 0x40, 0xE5, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, -0x90, 0x82, 0x03, 0x92, 0x03, 0x90, 0x40, 0xED, 0xE0, 0xFD, 0x90, 0x40, 0xEC, 0xE0, 0xFB, 0x90, -0x40, 0xEB, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92, 0x03, -0x02, 0x2E, 0xDC, 0xEC, 0xD3, 0x94, 0x0E, 0x50, 0x03, 0x02, 0x2E, 0xDC, 0xEA, 0xD3, 0x94, 0x0E, -0x40, 0x03, 0x02, 0x2E, 0xDC, 0x90, 0x42, 0xF1, 0xE0, 0xFD, 0x90, 0x42, 0xF0, 0xE0, 0xFB, 0x90, -0x42, 0xEF, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92, 0x03, -0x90, 0x43, 0x00, 0xE0, 0xFD, 0x90, 0x42, 0xFF, 0xE0, 0xFB, 0x90, 0x42, 0xFE, 0xE0, 0x90, 0x45, -0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92, 0x03, 0x90, 0x43, 0x06, 0xE0, 0xFD, -0x90, 0x43, 0x05, 0xE0, 0xFB, 0x90, 0x43, 0x04, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, -0x3C, 0x90, 0x82, 0x03, 0x92, 0x03, 0x90, 0x43, 0x0F, 0xE0, 0xFD, 0x90, 0x43, 0x0E, 0xE0, 0xFB, -0x90, 0x43, 0x0D, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92, -0x03, 0x90, 0x43, 0x15, 0xE0, 0xFD, 0x90, 0x43, 0x14, 0xE0, 0xFB, 0x90, 0x43, 0x13, 0xE0, 0x90, -0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92, 0x03, 0xA2, 0x03, 0x22, 0x90, -0x45, 0x40, 0xEF, 0xF0, 0xD2, 0x02, 0x90, 0x40, 0xC0, 0xE0, 0xFF, 0x90, 0x45, 0x40, 0xE0, 0xFD, -0x12, 0x2D, 0xA2, 0x82, 0x02, 0x92, 0x02, 0x90, 0x45, 0x40, 0xE0, 0xFC, 0xD3, 0x94, 0x0E, 0x50, -0x10, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0x7B, 0x8A, 0x7D, 0xF1, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x80, -0x3A, 0xEC, 0xD3, 0x94, 0x28, 0x50, 0x10, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0x7B, 0x8B, 0x7D, 0xF1, -0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x80, 0x24, 0xEC, 0xD3, 0x94, 0x33, 0x50, 0x10, 0xE4, 0x90, 0x45, -0x44, 0xF0, 0x7B, 0x8B, 0x7D, 0xB1, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x80, 0x0E, 0xE4, 0x90, 0x45, -0x44, 0xF0, 0x7B, 0x8B, 0x7D, 0x91, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x90, 0x45, 0x40, 0xE0, 0xFF, -0x75, 0xF0, 0x03, 0xA4, 0x24, 0xF0, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFD, 0xEF, -0x75, 0xF0, 0x03, 0xA4, 0x24, 0xEF, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFB, 0xEF, -0x75, 0xF0, 0x03, 0xA4, 0x24, 0xEE, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0x90, 0x45, -0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0x90, 0x45, 0x40, 0xE0, 0xFF, -0x75, 0xF0, 0x03, 0xA4, 0x24, 0x98, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFD, 0xEF, -0x75, 0xF0, 0x03, 0xA4, 0x24, 0x97, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFB, 0xEF, -0x75, 0xF0, 0x03, 0xA4, 0x24, 0x96, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0x90, 0x45, -0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0x90, 0x45, 0x40, 0xE0, 0xFF, -0x75, 0xF0, 0x03, 0xA4, 0x24, 0x40, 0xF5, 0x82, 0xE4, 0x34, 0x42, 0xF5, 0x83, 0xE0, 0xFD, 0xEF, -0x75, 0xF0, 0x03, 0xA4, 0x24, 0x3F, 0xF5, 0x82, 0xE4, 0x34, 0x42, 0xF5, 0x83, 0xE0, 0xFB, 0xEF, -0x75, 0xF0, 0x03, 0xA4, 0x24, 0x3E, 0xF5, 0x82, 0xE4, 0x34, 0x42, 0xF5, 0x83, 0xE0, 0x90, 0x45, -0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0xE4, 0x90, 0x45, 0x44, 0xF0, -0xFB, 0xFD, 0x7F, 0xC8, 0x12, 0x3D, 0x90, 0xA2, 0x02, 0x22, 0xD2, 0x01, 0xE4, 0x90, 0x04, 0x78, -0xF0, 0xA3, 0x74, 0x13, 0xF0, 0x7B, 0x01, 0x7A, 0x45, 0x79, 0x40, 0x7F, 0x0D, 0x12, 0x3C, 0xCD, -0x90, 0x45, 0x40, 0xE0, 0x54, 0xFE, 0xFF, 0xF0, 0xFD, 0x7F, 0x0D, 0x12, 0x3D, 0x00, 0xE4, 0x90, -0x45, 0x3E, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x3E, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x94, 0x10, -0xEE, 0x64, 0x80, 0x94, 0x80, 0x50, 0x57, 0x90, 0x42, 0xEB, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, -0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0xFD, 0x90, 0x42, 0xEA, 0x75, -0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, -0xFB, 0x90, 0x42, 0xE9, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, -0x25, 0x83, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x01, -0x92, 0x01, 0x90, 0x45, 0x3E, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x80, 0x97, 0x90, 0x04, -0x78, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0x96, 0x12, 0x3D, 0x90, -0x90, 0x45, 0x44, 0x74, 0x9A, 0xF0, 0x7B, 0xBA, 0x7D, 0x8F, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, -0x01, 0x92, 0x01, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0x1E, 0x12, 0x3D, 0x90, 0x90, -0x45, 0x44, 0x74, 0x3A, 0xF0, 0x7B, 0xBA, 0x7D, 0x8F, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x01, -0x92, 0x01, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0x1E, 0x12, 0x3D, 0x90, 0x90, 0x43, -0x18, 0xE0, 0xFD, 0x90, 0x43, 0x17, 0xE0, 0xFB, 0x90, 0x43, 0x16, 0xE0, 0x90, 0x45, 0x44, 0xF0, -0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x01, 0x92, 0x01, 0x90, 0x04, 0x79, 0x74, 0x13, 0xF0, 0x90, -0x04, 0x78, 0x74, 0x05, 0xF0, 0x7B, 0x01, 0x7A, 0x45, 0x79, 0x40, 0x7F, 0x0D, 0x12, 0x3C, 0xCD, -0x90, 0x45, 0x40, 0xE0, 0x44, 0x01, 0xFF, 0xF0, 0xFD, 0x7F, 0x0D, 0x12, 0x3D, 0x00, 0x90, 0x04, -0x62, 0x74, 0xC0, 0xF0, 0xA2, 0x01, 0x22, 0xD2, 0x01, 0xE4, 0x90, 0x04, 0x78, 0xF0, 0xA3, 0x74, -0x13, 0xF0, 0xE4, 0x90, 0x45, 0x3E, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x3E, 0xE0, 0xFE, 0xA3, 0xE0, -0xFF, 0xC3, 0x94, 0x0F, 0xEE, 0x64, 0x80, 0x94, 0x80, 0x50, 0x57, 0x90, 0x42, 0xEB, 0x75, 0xF0, -0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0xFD, -0x90, 0x42, 0xEA, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, -0x83, 0xF5, 0x83, 0xE0, 0xFB, 0x90, 0x42, 0xE9, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, -0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, -0x3C, 0x90, 0x82, 0x01, 0x92, 0x01, 0x90, 0x45, 0x3E, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, -0x80, 0x97, 0x90, 0x04, 0x78, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, -0x96, 0x12, 0x3D, 0x90, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0x7B, 0xD8, 0x7D, 0x0F, 0x7F, 0xB9, 0x12, -0x3C, 0x90, 0x82, 0x01, 0x92, 0x01, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0x1E, 0x12, -0x3D, 0x90, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0x7B, 0x78, 0x7D, 0x0F, 0x7F, 0xB9, 0x12, 0x3C, 0x90, -0x82, 0x01, 0x92, 0x01, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0x1E, 0x12, 0x3D, 0x90, -0x90, 0x43, 0x15, 0xE0, 0xFD, 0x90, 0x43, 0x14, 0xE0, 0xFB, 0x90, 0x43, 0x13, 0xE0, 0x90, 0x45, -0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x01, 0x92, 0x01, 0x90, 0x04, 0x78, 0x74, 0x05, -0xF0, 0x90, 0x04, 0x62, 0x74, 0xC0, 0xF0, 0xA2, 0x01, 0x22, 0x90, 0x45, 0x40, 0xEF, 0xF0, 0xD2, -0x02, 0x90, 0x04, 0x78, 0xE0, 0x54, 0xFE, 0xF0, 0x90, 0x45, 0x40, 0xE0, 0xFF, 0x75, 0xF0, 0x03, -0xA4, 0x24, 0xF0, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFD, 0xEF, 0x75, 0xF0, 0x03, -0xA4, 0x24, 0xEF, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFB, 0xEF, 0x75, 0xF0, 0x03, -0xA4, 0x24, 0xEE, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, -0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0x90, 0x45, 0x40, 0xE0, 0xFF, 0x75, 0xF0, 0x03, -0xA4, 0x24, 0x98, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFD, 0xEF, 0x75, 0xF0, 0x03, -0xA4, 0x24, 0x97, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFB, 0xEF, 0x75, 0xF0, 0x03, -0xA4, 0x24, 0x96, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, -0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0x90, 0x45, 0x40, 0xE0, 0xFF, 0x75, 0xF0, 0x03, -0xA4, 0x24, 0x40, 0xF5, 0x82, 0xE4, 0x34, 0x42, 0xF5, 0x83, 0xE0, 0xFD, 0xEF, 0x75, 0xF0, 0x03, -0xA4, 0x24, 0x3F, 0xF5, 0x82, 0xE4, 0x34, 0x42, 0xF5, 0x83, 0xE0, 0xFB, 0xEF, 0x75, 0xF0, 0x03, -0xA4, 0x24, 0x3E, 0xF5, 0x82, 0xE4, 0x34, 0x42, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, -0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0x90, 0x04, 0x78, 0xE0, 0x44, 0x01, 0xF0, 0xE4, -0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0xC8, 0x12, 0x3D, 0x90, 0x90, 0x40, 0xC0, 0xE0, 0xFF, -0x90, 0x45, 0x40, 0xE0, 0xFD, 0x12, 0x2C, 0x4D, 0xA2, 0x02, 0x22, 0x90, 0x45, 0x31, 0x12, 0x27, -0xBA, 0xE4, 0xFF, 0x90, 0x04, 0x48, 0xE0, 0x44, 0x10, 0xF0, 0xE4, 0xFD, 0xFC, 0x90, 0x04, 0x48, -0xE0, 0xFF, 0x30, 0xE4, 0x0B, 0x0D, 0xBD, 0x00, 0x01, 0x0C, 0xBC, 0x07, 0xF0, 0xBD, 0xFF, 0xED, -0xAE, 0x04, 0xAF, 0x05, 0xBE, 0x07, 0x05, 0xBF, 0xFF, 0x02, 0xC3, 0x22, 0x90, 0x04, 0x30, 0xE0, -0xFF, 0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3, 0xEF, 0x12, 0x26, 0x7C, 0x90, -0x04, 0x31, 0xE0, 0xFF, 0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3, 0xEF, 0x12, -0x26, 0x7C, 0x90, 0x04, 0x32, 0xE0, 0xFF, 0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, -0xA3, 0xEF, 0x12, 0x26, 0x7C, 0x90, 0x04, 0x33, 0xE0, 0xFF, 0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0, -0x01, 0x12, 0x27, 0xA3, 0xEF, 0x12, 0x26, 0x7C, 0x90, 0x04, 0x34, 0xE0, 0xFF, 0x90, 0x45, 0x31, -0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3, 0xEF, 0x12, 0x26, 0x7C, 0x90, 0x04, 0x35, 0xE0, 0xFF, -0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3, 0xEF, 0x12, 0x26, 0x7C, 0x90, 0x04, -0x36, 0xE0, 0xFF, 0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3, 0xEF, 0x12, 0x26, -0x7C, 0x90, 0x04, 0x37, 0xE0, 0xFF, 0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3, -0xEF, 0x12, 0x26, 0x7C, 0xD3, 0x22, 0x7B, 0x01, 0x7A, 0x10, 0x79, 0x34, 0x90, 0x45, 0x3A, 0x12, -0x27, 0xBA, 0x90, 0x45, 0x3A, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x12, 0x12, 0x27, 0xC3, 0xC0, 0x03, -0xC0, 0x02, 0xC0, 0x01, 0x90, 0x45, 0x3A, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x15, 0x12, 0x28, 0x25, -0x90, 0x45, 0x3A, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x18, 0x12, 0x26, 0xDC, 0xFF, 0x90, 0x00, 0x1A, -0xE5, 0xF0, 0x8F, 0xF0, 0x12, 0x27, 0x61, 0xE4, 0xFF, 0xEF, 0xC3, 0x94, 0x40, 0x50, 0x44, 0x90, -0x45, 0x3A, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x18, 0x12, 0x26, 0xDC, 0xD3, 0x94, 0x00, 0xE5, 0xF0, -0x94, 0x00, 0x40, 0x2F, 0x90, 0x00, 0x12, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xF3, 0x12, 0x26, -0x36, 0xFE, 0xAD, 0x07, 0x0F, 0x74, 0x60, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xEE, -0xF0, 0x90, 0x45, 0x3A, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x18, 0x74, 0xFF, 0xF5, 0xF0, 0x12, 0x27, -0x14, 0x80, 0xB6, 0xEF, 0x70, 0x17, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xE4, 0xA3, 0xF0, 0x90, -0x10, 0x3D, 0xE0, 0xB4, 0x0C, 0x1C, 0x12, 0x3E, 0x36, 0xD2, 0x8C, 0x80, 0x15, 0x30, 0x04, 0x0B, -0xC2, 0x04, 0xEF, 0x44, 0x80, 0x90, 0x06, 0x23, 0xF0, 0x80, 0x07, 0xD2, 0x04, 0x90, 0x06, 0x23, -0xEF, 0xF0, 0x90, 0x06, 0x25, 0x74, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x25, 0xE0, 0x30, 0xE0, 0x2F, -0x90, 0x10, 0x3D, 0xE0, 0x24, 0xFB, 0x70, 0x1D, 0x90, 0x10, 0x49, 0x12, 0x27, 0x9A, 0x90, 0x10, -0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x4E, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x10, 0x4C, 0xCF, 0xF0, -0xA3, 0xEF, 0xF0, 0x80, 0x07, 0xE4, 0x90, 0x10, 0x4C, 0xF0, 0xA3, 0xF0, 0x02, 0x33, 0xF6, 0x90, -0x10, 0x3D, 0xE0, 0x12, 0x28, 0x7E, 0x35, 0x12, 0x01, 0x35, 0x12, 0x05, 0x35, 0x12, 0x07, 0x35, -0x12, 0x09, 0x35, 0x15, 0x0B, 0x35, 0x12, 0x0C, 0x35, 0x1B, 0x0D, 0x35, 0x21, 0x0F, 0x00, 0x00, -0x35, 0x5C, 0x02, 0x33, 0xF6, 0xE4, 0x90, 0x10, 0x3D, 0xF0, 0x22, 0xE4, 0x90, 0x10, 0x3D, 0xF0, -0x22, 0x90, 0x10, 0x50, 0xE0, 0xFF, 0xB4, 0x01, 0x07, 0x90, 0x06, 0x07, 0x74, 0x20, 0xF0, 0x22, -0xEF, 0xB4, 0x02, 0x07, 0x90, 0x06, 0x07, 0x74, 0x40, 0xF0, 0x22, 0xEF, 0xB4, 0x03, 0x07, 0x90, -0x06, 0x07, 0x74, 0x60, 0xF0, 0x22, 0xEF, 0xB4, 0x04, 0x07, 0x90, 0x06, 0x07, 0x74, 0x80, 0xF0, -0x22, 0xEF, 0xB4, 0x05, 0x0C, 0x90, 0x06, 0x07, 0x74, 0xA0, 0xF0, 0x22, 0xE4, 0x90, 0x10, 0x3D, -0xF0, 0x22, 0x78, 0x7F, 0xE4, 0xF6, 0xD8, 0xFD, 0x75, 0x81, 0x20, 0x02, 0x35, 0xA9, 0x02, 0x23, -0x50, 0xE4, 0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0x40, 0x03, 0xF6, 0x80, 0x01, 0xF2, 0x08, 0xDF, -0xF4, 0x80, 0x29, 0xE4, 0x93, 0xA3, 0xF8, 0x54, 0x07, 0x24, 0x0C, 0xC8, 0xC3, 0x33, 0xC4, 0x54, -0x0F, 0x44, 0x20, 0xC8, 0x83, 0x40, 0x04, 0xF4, 0x56, 0x80, 0x01, 0x46, 0xF6, 0xDF, 0xE4, 0x80, -0x0B, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x3E, 0x45, 0xE4, 0x7E, 0x01, 0x93, -0x60, 0xBC, 0xA3, 0xFF, 0x54, 0x3F, 0x30, 0xE5, 0x09, 0x54, 0x1F, 0xFE, 0xE4, 0x93, 0xA3, 0x60, -0x01, 0x0E, 0xCF, 0x54, 0xC0, 0x25, 0xE0, 0x60, 0xA8, 0x40, 0xB8, 0xE4, 0x93, 0xA3, 0xFA, 0xE4, -0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCA, 0xC5, 0x83, 0xCA, 0xF0, 0xA3, -0xC8, 0xC5, 0x82, 0xC8, 0xCA, 0xC5, 0x83, 0xCA, 0xDF, 0xE9, 0xDE, 0xE7, 0x80, 0xBE, 0xAC, 0x07, -0xD2, 0x02, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xF0, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, -0xE0, 0xFD, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xEF, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, -0xE0, 0xFB, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xEE, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, -0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0xEC, 0x75, -0xF0, 0x03, 0xA4, 0x24, 0x98, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFD, 0xEC, 0x75, -0xF0, 0x03, 0xA4, 0x24, 0x97, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFB, 0xEC, 0x75, -0xF0, 0x03, 0xA4, 0x24, 0x96, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, -0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, -0xFD, 0x7F, 0xC8, 0x12, 0x3D, 0x90, 0xA2, 0x02, 0x22, 0xAC, 0x07, 0xD2, 0x02, 0xEC, 0x75, 0xF0, -0x03, 0xA4, 0x24, 0xF0, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFD, 0xEC, 0x75, 0xF0, -0x03, 0xA4, 0x24, 0xEF, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFB, 0xEC, 0x75, 0xF0, -0x03, 0xA4, 0x24, 0xEE, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, -0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x98, -0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFD, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x97, -0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFB, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x96, -0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, -0x90, 0x82, 0x02, 0x92, 0x02, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0xC8, 0x12, 0x3D, -0x90, 0xA2, 0x02, 0x22, 0xAC, 0x07, 0xD2, 0x02, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xF0, 0xF5, -0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFD, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xEF, 0xF5, -0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFB, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xEE, 0xF5, -0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, -0x82, 0x02, 0x92, 0x02, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x98, 0xF5, 0x82, 0xE4, 0x34, 0x41, -0xF5, 0x83, 0xE0, 0xFD, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x97, 0xF5, 0x82, 0xE4, 0x34, 0x41, -0xF5, 0x83, 0xE0, 0xFB, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x96, 0xF5, 0x82, 0xE4, 0x34, 0x41, -0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, -0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0xC8, 0x12, 0x3D, 0x90, 0xA2, 0x02, 0x22, 0xD2, -0x01, 0xE4, 0x90, 0x04, 0x78, 0xF0, 0xA3, 0x74, 0x1B, 0xF0, 0x90, 0x04, 0x78, 0x74, 0x05, 0xF0, -0xE4, 0x90, 0x45, 0x3E, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x3E, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, -0x94, 0x0B, 0xEE, 0x64, 0x80, 0x94, 0x80, 0x50, 0x57, 0x90, 0x42, 0xEB, 0x75, 0xF0, 0x03, 0xEF, -0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0xFD, 0x90, 0x42, -0xEA, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, -0x83, 0xE0, 0xFB, 0x90, 0x42, 0xE9, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, -0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, -0x82, 0x01, 0x92, 0x01, 0x90, 0x45, 0x3E, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x80, 0x97, -0x90, 0x04, 0x62, 0x74, 0xC0, 0xF0, 0xA2, 0x01, 0x22, 0xD2, 0x01, 0xE4, 0x90, 0x04, 0x78, 0xF0, -0xA3, 0x74, 0x1B, 0xF0, 0x90, 0x04, 0x78, 0x74, 0x05, 0xF0, 0xE4, 0x90, 0x45, 0x3E, 0xF0, 0xA3, -0xF0, 0x90, 0x45, 0x3E, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x94, 0x0D, 0xEE, 0x64, 0x80, 0x94, -0x80, 0x50, 0x57, 0x90, 0x42, 0xEB, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, -0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0xFD, 0x90, 0x42, 0xEA, 0x75, 0xF0, 0x03, 0xEF, 0x12, -0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0xFB, 0x90, 0x42, 0xE9, -0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, -0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x01, 0x92, 0x01, 0x90, 0x45, -0x3E, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x80, 0x97, 0x90, 0x04, 0x62, 0x74, 0xC0, 0xF0, -0xA2, 0x01, 0x22, 0xD2, 0x01, 0xE4, 0x90, 0x04, 0x78, 0xF0, 0xA3, 0x74, 0x1B, 0xF0, 0x90, 0x04, -0x78, 0x74, 0x05, 0xF0, 0xE4, 0x90, 0x45, 0x3E, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x3E, 0xE0, 0xFE, -0xA3, 0xE0, 0xFF, 0xC3, 0x94, 0x0F, 0xEE, 0x64, 0x80, 0x94, 0x80, 0x50, 0x57, 0x90, 0x42, 0xEB, -0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, -0xE0, 0xFD, 0x90, 0x42, 0xEA, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, -0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0xFB, 0x90, 0x42, 0xE9, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, -0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, -0xB9, 0x12, 0x3C, 0x90, 0x82, 0x01, 0x92, 0x01, 0x90, 0x45, 0x3E, 0xE4, 0x75, 0xF0, 0x01, 0x12, -0x26, 0xB0, 0x80, 0x97, 0x90, 0x04, 0x62, 0x74, 0xC0, 0xF0, 0xA2, 0x01, 0x22, 0x90, 0x45, 0x3E, -0xED, 0xF0, 0xD2, 0x01, 0x90, 0x04, 0x57, 0xE0, 0x90, 0x45, 0x3F, 0xF0, 0x90, 0x04, 0x57, 0xE0, -0x54, 0xFE, 0xF0, 0xEF, 0x12, 0x28, 0x7E, 0x39, 0x60, 0x03, 0x39, 0x78, 0x09, 0x39, 0x6C, 0x0A, -0x39, 0x78, 0x0C, 0x39, 0x84, 0x0D, 0x39, 0x60, 0x0E, 0x39, 0x90, 0x0F, 0x00, 0x00, 0x39, 0x9C, -0x90, 0x45, 0x3E, 0xE0, 0xFF, 0x12, 0x35, 0xEE, 0x92, 0x01, 0x80, 0x32, 0x90, 0x45, 0x3E, 0xE0, -0xFF, 0x12, 0x32, 0x3A, 0x92, 0x01, 0x80, 0x26, 0x90, 0x45, 0x3E, 0xE0, 0xFF, 0x12, 0x36, 0x79, -0x92, 0x01, 0x80, 0x1A, 0x90, 0x45, 0x3E, 0xE0, 0xFF, 0x12, 0x37, 0x04, 0x92, 0x01, 0x80, 0x0E, -0x90, 0x45, 0x3E, 0xE0, 0xFF, 0x12, 0x2E, 0xDF, 0x92, 0x01, 0x80, 0x02, 0xC2, 0x01, 0x12, 0x3D, -0xE2, 0x90, 0x45, 0x3F, 0xE0, 0x90, 0x04, 0x57, 0xF0, 0x90, 0x45, 0x3E, 0xE0, 0x90, 0x40, 0xC0, -0xF0, 0xA2, 0x01, 0x22, 0xAC, 0x07, 0xE4, 0x90, 0x45, 0x3A, 0xF0, 0xA3, 0xF0, 0xD2, 0x00, 0x7D, -0x03, 0xEC, 0x70, 0x13, 0x12, 0x3C, 0xC5, 0x90, 0x45, 0x3B, 0xE0, 0x54, 0xF9, 0xFF, 0xF0, 0xFD, -0x7F, 0x09, 0x12, 0x3D, 0x00, 0x80, 0x59, 0xEC, 0xB4, 0x01, 0x16, 0x12, 0x3C, 0xC5, 0x90, 0x45, -0x3B, 0xE0, 0x54, 0xFD, 0xF0, 0x44, 0x04, 0xFF, 0xF0, 0xFD, 0x7F, 0x09, 0x12, 0x3D, 0x00, 0x80, -0x3F, 0xEC, 0xB4, 0x02, 0x1B, 0x7B, 0x01, 0x7A, 0x45, 0x79, 0x3A, 0x7F, 0x0A, 0x12, 0x3C, 0xCD, -0x90, 0x45, 0x3A, 0xE0, 0x54, 0xFC, 0xFF, 0xF0, 0xFD, 0x7F, 0x0A, 0x12, 0x3D, 0x00, 0x80, 0x20, -0xEC, 0xB4, 0x03, 0x1C, 0x7B, 0x01, 0x7A, 0x45, 0x79, 0x3A, 0x7F, 0x0A, 0x12, 0x3C, 0xCD, 0x90, -0x45, 0x3A, 0xE0, 0x54, 0xFE, 0xF0, 0x44, 0x02, 0xFF, 0xF0, 0xFD, 0x7F, 0x0A, 0x12, 0x3D, 0x00, -0xA2, 0x00, 0x22, 0x90, 0x45, 0x38, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x04, 0x0B, 0xE0, 0xF9, -0x54, 0xFB, 0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x09, 0x74, 0x50, 0xF0, 0x90, 0x45, 0x38, 0xE0, -0x90, 0x04, 0x0A, 0xF0, 0x90, 0x45, 0x39, 0xE0, 0x90, 0x04, 0x0E, 0xF0, 0x90, 0x04, 0x08, 0x74, -0x80, 0xF0, 0xE4, 0xFD, 0xFC, 0x90, 0x04, 0x08, 0xE0, 0x90, 0x45, 0x3A, 0xF0, 0xE0, 0x54, 0x03, -0x70, 0x0B, 0x0D, 0xBD, 0x00, 0x01, 0x0C, 0xBC, 0x07, 0xEB, 0xBD, 0xFF, 0xE8, 0xC3, 0xED, 0x94, -0xFF, 0xEC, 0x94, 0x07, 0x50, 0x07, 0x90, 0x45, 0x3A, 0xE0, 0x30, 0xE1, 0x0B, 0x0F, 0xBF, 0x00, -0x01, 0x0E, 0xBE, 0x07, 0xB1, 0xBF, 0xFF, 0xAE, 0xBE, 0x07, 0x0A, 0xBF, 0xFF, 0x07, 0x90, 0x04, -0x0B, 0xE9, 0xF0, 0xC3, 0x22, 0xAF, 0x01, 0x90, 0x04, 0x0B, 0xE9, 0xF0, 0xD3, 0x22, 0x90, 0x45, -0x35, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0xEE, 0x70, 0x56, 0xEF, 0x24, 0xF6, 0x60, 0x1B, 0x14, 0x60, -0x26, 0x14, 0x60, 0x31, 0x14, 0x60, 0x3C, 0x24, 0x04, 0x70, 0x44, 0x7B, 0x01, 0x7A, 0x42, 0x79, -0xE9, 0x90, 0x45, 0x37, 0x12, 0x27, 0xBA, 0x80, 0x36, 0x7B, 0x01, 0x7A, 0x40, 0x79, 0xC1, 0x90, -0x45, 0x37, 0x12, 0x27, 0xBA, 0x80, 0x28, 0x7B, 0x01, 0x7A, 0x40, 0x79, 0xF1, 0x90, 0x45, 0x37, -0x12, 0x27, 0xBA, 0x80, 0x1A, 0x7B, 0x01, 0x7A, 0x41, 0x79, 0x99, 0x90, 0x45, 0x37, 0x12, 0x27, -0xBA, 0x80, 0x0C, 0x7B, 0x01, 0x7A, 0x42, 0x79, 0x41, 0x90, 0x45, 0x37, 0x12, 0x27, 0xBA, 0x90, -0x45, 0x36, 0xE0, 0xFF, 0xA3, 0x12, 0x27, 0x9A, 0x90, 0x45, 0x35, 0xE0, 0xF5, 0x82, 0x75, 0x83, -0x00, 0xEF, 0x02, 0x26, 0x8E, 0x90, 0x45, 0x3F, 0xEF, 0xF0, 0xA3, 0x74, 0xFF, 0xF0, 0x90, 0x04, -0x0B, 0xE0, 0x90, 0x45, 0x41, 0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x09, 0x74, 0x50, 0xF0, 0x90, -0x45, 0x3F, 0xE0, 0x90, 0x04, 0x0A, 0xF0, 0x90, 0x04, 0x08, 0x74, 0x40, 0xF0, 0xE4, 0xFD, 0xFC, -0x90, 0x04, 0x08, 0xE0, 0xF9, 0x54, 0x03, 0x70, 0x0B, 0x0D, 0xBD, 0x00, 0x01, 0x0C, 0xBC, 0x07, -0xEF, 0xBD, 0xFF, 0xEC, 0xC3, 0xED, 0x94, 0xFF, 0xEC, 0x94, 0x07, 0x50, 0x04, 0xE9, 0x30, 0xE1, -0x0B, 0x0F, 0xBF, 0x00, 0x01, 0x0E, 0xBE, 0x07, 0xC0, 0xBF, 0xFF, 0xBD, 0x90, 0x04, 0x0C, 0xE0, -0x90, 0x45, 0x40, 0xF0, 0xA3, 0xE0, 0x90, 0x04, 0x0B, 0xF0, 0x90, 0x45, 0x40, 0xE0, 0xFF, 0x22, -0xE4, 0xFE, 0xEF, 0x30, 0xE5, 0x11, 0xE4, 0xFC, 0xFD, 0x7C, 0x08, 0x90, 0x04, 0xD4, 0xE4, 0xF0, -0xA3, 0xDC, 0xFC, 0x7C, 0x00, 0x7D, 0x08, 0xEF, 0x54, 0xC0, 0x60, 0x12, 0xE4, 0xFC, 0xFD, 0x7C, -0x08, 0x90, 0x04, 0xD4, 0x74, 0xFF, 0xF0, 0xA3, 0xDC, 0xFC, 0x7C, 0x00, 0x7D, 0x08, 0xEF, 0x30, -0xE6, 0x07, 0xEE, 0x44, 0x78, 0xFE, 0x54, 0xFE, 0xFE, 0xEF, 0x54, 0x88, 0x60, 0x04, 0xEE, 0x44, -0x08, 0xFE, 0xEF, 0x30, 0xE4, 0x04, 0xEE, 0x44, 0x10, 0xFE, 0xEF, 0x30, 0xE1, 0x04, 0xEE, 0x44, -0x02, 0xFE, 0x90, 0x04, 0x56, 0xE0, 0xFF, 0x6E, 0x60, 0x02, 0xEE, 0xF0, 0x22, 0xC0, 0xE0, 0xC0, -0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x07, 0xD2, 0x05, 0x53, 0xA8, 0xFE, 0x90, -0x06, 0x20, 0xE4, 0xF0, 0x90, 0x04, 0x58, 0xF0, 0xA3, 0xF0, 0x90, 0x06, 0x21, 0xE0, 0xFF, 0x90, -0x10, 0x39, 0xE0, 0x4F, 0xF0, 0x90, 0x06, 0x21, 0xEF, 0xF0, 0x90, 0x04, 0x5C, 0xE0, 0xFF, 0x90, -0x45, 0x46, 0xE0, 0x4F, 0xF0, 0x90, 0x04, 0x5C, 0xEF, 0xF0, 0xA3, 0xE0, 0xFF, 0x90, 0x45, 0x47, -0xE0, 0x4F, 0xF0, 0x90, 0x04, 0x5D, 0xEF, 0xF0, 0xD0, 0x07, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83, -0xD0, 0xE0, 0x32, 0x90, 0x04, 0x79, 0x74, 0x11, 0xF0, 0x12, 0x3D, 0x31, 0xE4, 0x90, 0x45, 0x3E, -0xF0, 0x90, 0x45, 0x3E, 0xE0, 0xFF, 0xC3, 0x94, 0x06, 0x50, 0x1A, 0x12, 0x3B, 0x25, 0x90, 0x45, -0x3E, 0xE0, 0x24, 0xC4, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x45, 0x3E, -0xE0, 0x04, 0xF0, 0x80, 0xDC, 0x90, 0x04, 0x48, 0x74, 0x02, 0xF0, 0x14, 0xF0, 0x7F, 0x30, 0x12, -0x3B, 0x90, 0x90, 0x04, 0x54, 0x74, 0x02, 0xF0, 0x22, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, -0x90, 0x04, 0x71, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x90, 0x45, 0x44, 0xE0, 0x90, 0x04, 0x73, 0xF0, -0x90, 0x04, 0x70, 0xEF, 0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x70, 0xE0, 0xFD, 0x20, 0xE2, 0x0B, -0x0F, 0xBF, 0x00, 0x01, 0x0E, 0xBE, 0x07, 0xF0, 0xBF, 0xFF, 0xED, 0xBE, 0x07, 0x05, 0xBF, 0xFF, -0x02, 0xC3, 0x22, 0xD3, 0x22, 0x7B, 0x01, 0x7A, 0x45, 0x79, 0x3B, 0x7F, 0x09, 0x90, 0x04, 0x6E, -0xEF, 0xF0, 0x90, 0x04, 0x6C, 0xE0, 0x44, 0x02, 0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x6C, 0xE0, -0xFD, 0x20, 0xE2, 0x0B, 0x0F, 0xBF, 0x00, 0x01, 0x0E, 0xBE, 0x07, 0xF0, 0xBF, 0xFF, 0xED, 0x90, -0x04, 0x6F, 0xE0, 0x12, 0x26, 0x7C, 0xBE, 0x07, 0x05, 0xBF, 0xFF, 0x02, 0xC3, 0x22, 0xD3, 0x22, -0x90, 0x04, 0x6E, 0xEF, 0xF0, 0x90, 0x04, 0x6F, 0xED, 0xF0, 0x90, 0x04, 0x6C, 0xE0, 0x44, 0x01, -0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x6C, 0xE0, 0xFD, 0x20, 0xE2, 0x0B, 0x0F, 0xBF, 0x00, 0x01, -0x0E, 0xBE, 0x07, 0xF0, 0xBF, 0xFF, 0xED, 0xBE, 0x07, 0x05, 0xBF, 0xFF, 0x02, 0xC3, 0x22, 0xD3, -0x22, 0x90, 0x04, 0x54, 0x74, 0x01, 0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x54, 0xE0, 0xFD, 0x30, -0xE0, 0x0B, 0x0F, 0xBF, 0x00, 0x01, 0x0E, 0xBE, 0x07, 0xF0, 0xBF, 0xFF, 0xED, 0xBE, 0x07, 0x05, -0xBF, 0xFF, 0x02, 0xC3, 0x22, 0x90, 0x06, 0x38, 0xE0, 0x44, 0x02, 0xF0, 0xE0, 0x44, 0x01, 0xF0, -0xD3, 0x22, 0xEF, 0x12, 0x28, 0x7E, 0x3D, 0x7F, 0x03, 0x3D, 0x85, 0x09, 0x3D, 0x82, 0x0A, 0x3D, -0x85, 0x0C, 0x3D, 0x88, 0x0D, 0x3D, 0x7F, 0x0E, 0x3D, 0x8B, 0x0F, 0x00, 0x00, 0x3D, 0x8E, 0x02, -0x31, 0x47, 0x02, 0x30, 0x1A, 0x02, 0x37, 0x8F, 0x02, 0x38, 0x19, 0x02, 0x38, 0xA3, 0xC3, 0x22, -0x90, 0x04, 0x1C, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x90, 0x45, 0x44, 0xE0, 0x90, -0x04, 0x1F, 0xF0, 0x90, 0x04, 0x18, 0x74, 0x03, 0xF0, 0x90, 0x04, 0x18, 0xE0, 0xFF, 0x60, 0x04, -0xEF, 0x30, 0xE2, 0xF5, 0xE4, 0x90, 0x04, 0x18, 0xF0, 0x22, 0x7F, 0xFF, 0x90, 0x04, 0x14, 0xE0, -0xFF, 0x14, 0x60, 0x0E, 0x14, 0x60, 0x0F, 0x14, 0x60, 0x10, 0x24, 0x03, 0x70, 0x10, 0x02, 0x0B, -0xBE, 0x22, 0x02, 0x0B, 0xB5, 0x22, 0x02, 0x0B, 0xAE, 0x22, 0x02, 0x0B, 0xEF, 0x22, 0x02, 0x00, -0x00, 0x22, 0xD2, 0x02, 0x7D, 0x40, 0x7F, 0x50, 0x12, 0x3D, 0x00, 0xE4, 0xFD, 0x7F, 0x50, 0x12, -0x3D, 0x00, 0x7D, 0x01, 0x7F, 0x9C, 0x12, 0x3D, 0x00, 0xE4, 0xFD, 0x7F, 0x9C, 0x12, 0x3D, 0x00, -0xA2, 0x02, 0x22, 0x90, 0x04, 0x61, 0xE0, 0x54, 0xFE, 0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x61, -0xE0, 0xFD, 0x20, 0xE5, 0x0B, 0x0F, 0xBF, 0x00, 0x01, 0x0E, 0xBE, 0x07, 0xF0, 0xBF, 0xFF, 0xED, -0x22, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0xC2, 0x8C, 0x90, 0x43, 0x19, 0x74, 0x01, 0xF0, 0xD0, -0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0xC2, 0x8C, 0x75, 0x89, 0x01, 0x75, 0x8C, 0xF9, 0x75, 0x8A, -0x7E, 0x43, 0xA8, 0x02, 0x22, 0x44, 0x43, 0x1A, 0x04, 0x03, 0x09, 0x04, 0x00, -}; - /*--------------------- Export Functions --------------------------*/ @@ -773,50 +61,61 @@ FIRMWAREbDownload( PSDevice pDevice ) { - int NdisStatus; - PBYTE pBuffer = NULL; - WORD wLength; - int ii; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Download firmware\n"); - spin_unlock_irq(&pDevice->lock); - pBuffer = kmalloc(sizeof(abyFirmware), GFP_KERNEL); - if (pBuffer != NULL) { - - for (ii=0;iiDownload firmware\n"); + spin_unlock_irq(&pDevice->lock); + + if (!pDevice->firmware) { + struct device *dev = &pDevice->usb->dev; + int rc; + + rc = request_firmware(&pDevice->firmware, FIRMWARE_NAME, dev); + if (rc) { + dev_err(dev, "firmware file %s request failed (%d)\n", + FIRMWARE_NAME, rc); + goto out; + } + } + fw = pDevice->firmware; + + pBuffer = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL); + if (!pBuffer) + goto out; + + for (ii = 0; ii < fw->size; ii += FIRMWARE_CHUNK_SIZE) { + wLength = min_t(int, fw->size - ii, FIRMWARE_CHUNK_SIZE); + memcpy(pBuffer, fw->data + ii, wLength); + + NdisStatus = CONTROLnsRequestOutAsyn(pDevice, 0, 0x1200+ii, 0x0000, wLength, - &(pBuffer[ii]) + pBuffer ); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Download firmware...%d %zu\n", ii, sizeof(abyFirmware)); - if (NdisStatus != STATUS_SUCCESS) { - if (pBuffer) - kfree(pBuffer); - spin_lock_irq(&pDevice->lock); - return FALSE; - } + DBG_PRT(MSG_LEVEL_DEBUG, + KERN_INFO"Download firmware...%d %zu\n", ii, fw->size); + if (NdisStatus != STATUS_SUCCESS) + goto out; } - } - if (pBuffer) - kfree(pBuffer); + result = TRUE; + +out: + if (pBuffer) + kfree(pBuffer); - spin_lock_irq(&pDevice->lock); - return (TRUE); + spin_lock_irq(&pDevice->lock); + return result; } +MODULE_FIRMWARE(FIRMWARE_NAME); BOOL FIRMWAREbBrach2Sram( @@ -867,7 +166,7 @@ FIRMWAREbCheckVersion( return FALSE; } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Version [%04x]\n", pDevice->wFirmwareVersion); - if (pDevice->wFirmwareVersion != FIRMWARE_VERSION) { + if (pDevice->wFirmwareVersion < FIRMWARE_VERSION) { // branch to loader for download new firmware FIRMWAREbBrach2Sram(pDevice); return FALSE; diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 7cc3d2407d1b..56ce9be5f86a 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1272,6 +1272,9 @@ static void __devexit vt6656_disconnect(struct usb_interface *intf) device_release_WPADEV(device); + if (device->firmware) + release_firmware(device->firmware); + usb_set_intfdata(intf, NULL); usb_put_dev(interface_to_usbdev(intf)); -- cgit v1.2.3 From 0a8692b534e18fcec6eac07551bb37a22659f5c7 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 9 Jan 2011 04:20:04 +0000 Subject: rtl8192u_usb: Remove built-in firmware images These firmware images are already unused. Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U.h | 6 - drivers/staging/rtl8192u/r819xU_firmware.c | 76 +- drivers/staging/rtl8192u/r819xU_firmware_img.c | 2900 ------------------------ drivers/staging/rtl8192u/r819xU_firmware_img.h | 7 - 4 files changed, 25 insertions(+), 2964 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192u/r8192U.h b/drivers/staging/rtl8192u/r8192U.h index 6206f929a655..0205079b13e9 100644 --- a/drivers/staging/rtl8192u/r8192U.h +++ b/drivers/staging/rtl8192u/r8192U.h @@ -461,11 +461,6 @@ typedef enum _desc_packet_type_e{ DESC_PACKET_TYPE_NORMAL = 1, }desc_packet_type_e; -typedef enum _firmware_source{ - FW_SOURCE_IMG_FILE = 0, - FW_SOURCE_HEADER_FILE = 1, //from header file -}firmware_source_e, *pfirmware_source_e; - typedef enum _firmware_status{ FW_STATUS_0_INIT = 0, FW_STATUS_1_MOVE_BOOT_CODE = 1, @@ -1026,7 +1021,6 @@ typedef struct r8192_priv u8 Rf_Mode; //add for Firmware RF -R/W switch prt_firmware pFirmware; rtl819xUsb_loopback_e LoopbackMode; - firmware_source_e firmware_source; u16 EEPROMTxPowerDiff; u8 EEPROMThermalMeter; u8 EEPROMPwDiff; diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c index 49ae1705377b..6766f468639f 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware.c +++ b/drivers/staging/rtl8192u/r819xU_firmware.c @@ -244,13 +244,6 @@ bool init_firmware(struct net_device *dev) struct r8192_priv *priv = ieee80211_priv(dev); bool rt_status = TRUE; - u8 *firmware_img_buf[3] = { &rtl8190_fwboot_array[0], - &rtl8190_fwmain_array[0], - &rtl8190_fwdata_array[0]}; - - u32 firmware_img_len[3] = { sizeof(rtl8190_fwboot_array), - sizeof(rtl8190_fwmain_array), - sizeof(rtl8190_fwdata_array)}; u32 file_length = 0; u8 *mapped_file = NULL; u32 init_step = 0; @@ -284,59 +277,40 @@ bool init_firmware(struct net_device *dev) * Download boot, main, and data image for System reset. * Download data image for firmware reseta */ - priv->firmware_source = FW_SOURCE_IMG_FILE; for(init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; init_step++) { /* * Open Image file, and map file to contineous memory if open file success. * or read image file from array. Default load from IMG file */ if(rst_opt == OPT_SYSTEM_RESET) { - switch(priv->firmware_source) { - case FW_SOURCE_IMG_FILE: - rc = request_firmware(&fw_entry, fw_name[init_step],&priv->udev->dev); - if(rc < 0 ) { - RT_TRACE(COMP_ERR, "request firmware fail!\n"); - goto download_firmware_fail; - } - - if(fw_entry->size > sizeof(pfirmware->firmware_buf)) { - RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n"); - goto download_firmware_fail; - } - - if(init_step != FW_INIT_STEP1_MAIN) { - memcpy(pfirmware->firmware_buf,fw_entry->data,fw_entry->size); - mapped_file = pfirmware->firmware_buf; - file_length = fw_entry->size; - } else { - #ifdef RTL8190P - memcpy(pfirmware->firmware_buf,fw_entry->data,fw_entry->size); - mapped_file = pfirmware->firmware_buf; - file_length = fw_entry->size; - #else - memset(pfirmware->firmware_buf,0,128); - memcpy(&pfirmware->firmware_buf[128],fw_entry->data,fw_entry->size); - mapped_file = pfirmware->firmware_buf; - file_length = fw_entry->size + 128; - #endif - } - pfirmware->firmware_buf_size = file_length; - break; - - case FW_SOURCE_HEADER_FILE: - mapped_file = firmware_img_buf[init_step]; - file_length = firmware_img_len[init_step]; - if(init_step == FW_INIT_STEP2_DATA) { - memcpy(pfirmware->firmware_buf, mapped_file, file_length); - pfirmware->firmware_buf_size = file_length; - } - break; - - default: - break; + rc = request_firmware(&fw_entry, fw_name[init_step],&priv->udev->dev); + if(rc < 0 ) { + RT_TRACE(COMP_ERR, "request firmware fail!\n"); + goto download_firmware_fail; } + if(fw_entry->size > sizeof(pfirmware->firmware_buf)) { + RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n"); + goto download_firmware_fail; + } + if(init_step != FW_INIT_STEP1_MAIN) { + memcpy(pfirmware->firmware_buf,fw_entry->data,fw_entry->size); + mapped_file = pfirmware->firmware_buf; + file_length = fw_entry->size; + } else { +#ifdef RTL8190P + memcpy(pfirmware->firmware_buf,fw_entry->data,fw_entry->size); + mapped_file = pfirmware->firmware_buf; + file_length = fw_entry->size; +#else + memset(pfirmware->firmware_buf,0,128); + memcpy(&pfirmware->firmware_buf[128],fw_entry->data,fw_entry->size); + mapped_file = pfirmware->firmware_buf; + file_length = fw_entry->size + 128; +#endif + } + pfirmware->firmware_buf_size = file_length; }else if(rst_opt == OPT_FIRMWARE_RESET ) { /* we only need to download data.img here */ mapped_file = pfirmware->firmware_buf; diff --git a/drivers/staging/rtl8192u/r819xU_firmware_img.c b/drivers/staging/rtl8192u/r819xU_firmware_img.c index 29b656d7d82b..df0f9d1648ec 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware_img.c +++ b/drivers/staging/rtl8192u/r819xU_firmware_img.c @@ -1,2906 +1,6 @@ /*Created on 2008/ 7/16, 5:31*/ #include -u8 rtl8190_fwboot_array[] = { -0x10,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x3c,0x08,0xbf,0xc0,0x25,0x08,0x00,0x08, -0x3c,0x09,0xb0,0x03,0xad,0x28,0x00,0x20,0x40,0x80,0x68,0x00,0x00,0x00,0x00,0x00, -0x3c,0x0a,0xd0,0x00,0x40,0x8a,0x60,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x01, -0x25,0x08,0xb0,0x50,0x24,0x09,0x00,0x01,0x3c,0x01,0x7f,0xff,0x34,0x21,0xff,0xff, -0x01,0x01,0x50,0x24,0x00,0x09,0x48,0x40,0x35,0x29,0x00,0x01,0x01,0x2a,0x10,0x2b, -0x14,0x40,0xff,0xfc,0x00,0x00,0x00,0x00,0x3c,0x0a,0x00,0x00,0x25,0x4a,0x00,0x00, -0x4c,0x8a,0x00,0x00,0x4c,0x89,0x08,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x01, -0x25,0x08,0xb0,0x50,0x3c,0x01,0x80,0x00,0x01,0x21,0x48,0x25,0x3c,0x0a,0xbf,0xc0, -0x25,0x4a,0x00,0x7c,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0xad,0x00,0x00,0x00, -0x21,0x08,0x00,0x04,0x01,0x09,0x10,0x2b,0x14,0x40,0xff,0xf8,0x00,0x00,0x00,0x00, -0x3c,0x08,0x80,0x01,0x25,0x08,0x7f,0xff,0x24,0x09,0x00,0x01,0x3c,0x01,0x7f,0xff, -0x34,0x21,0xff,0xff,0x01,0x01,0x50,0x24,0x00,0x09,0x48,0x40,0x35,0x29,0x00,0x01, -0x01,0x2a,0x10,0x2b,0x14,0x40,0xff,0xfc,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x01, -0x25,0x4a,0x00,0x00,0x3c,0x01,0x7f,0xff,0x34,0x21,0xff,0xff,0x01,0x41,0x50,0x24, -0x3c,0x09,0x00,0x01,0x35,0x29,0x7f,0xff,0x4c,0x8a,0x20,0x00,0x4c,0x89,0x28,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x08,0x04,0x10, -0x00,0x00,0x00,0x00,0x40,0x88,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x3c,0x08,0xbf,0xc0,0x00,0x00,0x00,0x00,0x8d,0x09,0x00,0x00,0x00,0x00,0x00,0x00, -0x3c,0x0a,0xbf,0xc0,0x25,0x4a,0x01,0x20,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20, -0x3c,0x08,0xb0,0x03,0x8d,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x35,0x29,0x00,0x10, -0xad,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x00,0x25,0x08,0x4b,0x84, -0x01,0x00,0x00,0x08,0x00,0x00,0x00,0x00,}; - -u8 rtl8190_fwmain_array[] = { -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x40,0x04,0x68,0x00,0x40,0x05,0x70,0x00,0x40,0x06,0x40,0x00,0x0c,0x00,0x12,0x94, -0x00,0x00,0x00,0x00,0x40,0x1a,0x68,0x00,0x33,0x5b,0x00,0x3c,0x17,0x60,0x00,0x09, -0x00,0x00,0x00,0x00,0x40,0x1b,0x60,0x00,0x00,0x00,0x00,0x00,0x03,0x5b,0xd0,0x24, -0x40,0x1a,0x70,0x00,0x03,0x40,0x00,0x08,0x42,0x00,0x00,0x10,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0xff,0x34,0x42,0xff,0xff,0x8c,0x43,0x00,0x00, -0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x00,0xd0, -0xac,0x62,0x00,0x00,0x00,0x00,0x20,0x21,0x27,0x85,0x8b,0x60,0x00,0x85,0x18,0x21, -0x24,0x84,0x00,0x01,0x28,0x82,0x00,0x0a,0x14,0x40,0xff,0xfc,0xa0,0x60,0x00,0x00, -0x27,0x82,0x8b,0x6a,0x24,0x04,0x00,0x06,0x24,0x84,0xff,0xff,0xa4,0x40,0x00,0x00, -0x04,0x81,0xff,0xfd,0x24,0x42,0x00,0x02,0x24,0x02,0x00,0x03,0xa3,0x82,0x8b,0x60, -0x24,0x02,0x09,0xc4,0x24,0x03,0x01,0x00,0xa7,0x82,0x8b,0x76,0x24,0x02,0x04,0x00, -0xaf,0x83,0x8b,0x78,0xaf,0x82,0x8b,0x7c,0x24,0x03,0x00,0x0a,0x24,0x02,0x00,0x04, -0x24,0x05,0x00,0x02,0x24,0x04,0x00,0x01,0xa3,0x83,0x8b,0x62,0xa3,0x82,0x8b,0x68, -0x24,0x03,0x00,0x01,0x24,0x02,0x02,0x00,0xa3,0x84,0x8b,0x66,0xa3,0x85,0x8b,0x69, -0xa7,0x82,0x8b,0x6a,0xa7,0x83,0x8b,0x6c,0xa3,0x84,0x8b,0x61,0xa3,0x80,0x8b,0x63, -0xa3,0x80,0x8b,0x64,0xa3,0x80,0x8b,0x65,0xa3,0x85,0x8b,0x67,0x03,0xe0,0x00,0x08, -0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x01,0x84, -0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,0x27,0x84,0x8b,0x88,0x00,0x00,0x10,0x21, -0x24,0x42,0x00,0x01,0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03,0x28,0x43,0x00,0x03, -0xac,0x80,0xff,0xfc,0xa0,0x80,0x00,0x00,0x14,0x60,0xff,0xf9,0x24,0x84,0x00,0x0c, -0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, -0x34,0x63,0x00,0x20,0x24,0x42,0x01,0xc8,0x3c,0x08,0xb0,0x03,0xac,0x62,0x00,0x00, -0x35,0x08,0x00,0x70,0x8d,0x02,0x00,0x00,0x00,0xa0,0x48,0x21,0x00,0x04,0x26,0x00, -0x00,0x02,0x2a,0x43,0x00,0x06,0x36,0x00,0x00,0x07,0x3e,0x00,0x00,0x02,0x12,0x03, -0x29,0x23,0x00,0x03,0x00,0x04,0x56,0x03,0x00,0x06,0x36,0x03,0x00,0x07,0x3e,0x03, -0x30,0x48,0x00,0x01,0x10,0x60,0x00,0x11,0x30,0xa5,0x00,0x07,0x24,0x02,0x00,0x02, -0x00,0x49,0x10,0x23,0x00,0x45,0x10,0x07,0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x66, -0x00,0x00,0x00,0x00,0x8f,0xa2,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x02,0x21,0x43, -0x11,0x00,0x00,0x10,0x00,0x07,0x20,0x0b,0x15,0x20,0x00,0x06,0x24,0x02,0x00,0x01, -0x3c,0x02,0xb0,0x05,0x34,0x42,0x01,0x20,0xa4,0x44,0x00,0x00,0x03,0xe0,0x00,0x08, -0x00,0x00,0x00,0x00,0x11,0x22,0x00,0x04,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05, -0x08,0x00,0x00,0x96,0x34,0x42,0x01,0x24,0x3c,0x02,0xb0,0x05,0x08,0x00,0x00,0x96, -0x34,0x42,0x01,0x22,0x15,0x20,0x00,0x54,0x24,0x02,0x00,0x01,0x3c,0x02,0xb0,0x03, -0x34,0x42,0x00,0x74,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x83,0x8b,0x84, -0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x70,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00, -0x30,0x6b,0x00,0x08,0x11,0x60,0x00,0x18,0x00,0x09,0x28,0x40,0x00,0x00,0x40,0x21, -0x27,0x85,0x8b,0x80,0x8c,0xa3,0x00,0x00,0x8c,0xa2,0x00,0x04,0x00,0x00,0x00,0x00, -0x00,0x62,0x38,0x23,0x00,0x43,0x10,0x2a,0x10,0x40,0x00,0x3d,0x00,0x00,0x00,0x00, -0xac,0xa7,0x00,0x00,0x25,0x02,0x00,0x01,0x00,0x02,0x16,0x00,0x00,0x02,0x46,0x03, -0x29,0x03,0x00,0x03,0x14,0x60,0xff,0xf3,0x24,0xa5,0x00,0x0c,0x3c,0x03,0xb0,0x03, -0x34,0x63,0x00,0x70,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4b,0x10,0x23, -0xa0,0x62,0x00,0x00,0x00,0x09,0x28,0x40,0x00,0xa9,0x10,0x21,0x00,0x02,0x10,0x80, -0x27,0x83,0x8b,0x88,0x00,0x0a,0x20,0x0b,0x00,0x43,0x18,0x21,0x10,0xc0,0x00,0x05, -0x00,0x00,0x38,0x21,0x80,0x62,0x00,0x01,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05, -0x00,0x00,0x00,0x00,0x80,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03, -0x00,0xa9,0x10,0x21,0x24,0x07,0x00,0x01,0x00,0xa9,0x10,0x21,0x00,0x02,0x30,0x80, -0x27,0x82,0x8b,0x88,0xa0,0x67,0x00,0x01,0x00,0xc2,0x38,0x21,0x80,0xe3,0x00,0x01, -0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x07,0x00,0x00,0x00,0x00,0x27,0x83,0x8b,0x80, -0x00,0xc3,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x21, -0xac,0x62,0x00,0x00,0x27,0x85,0x8b,0x84,0x27,0x82,0x8b,0x80,0x00,0xc5,0x28,0x21, -0x00,0xc2,0x10,0x21,0x8c,0x43,0x00,0x00,0x8c,0xa4,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x64,0x18,0x2a,0x14,0x60,0x00,0x03,0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08, -0xa0,0xe2,0x00,0x00,0xa0,0xe0,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, -0x08,0x00,0x00,0xb9,0xac,0xa0,0x00,0x00,0x11,0x22,0x00,0x08,0x00,0x00,0x00,0x00, -0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x7c,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00, -0xaf,0x83,0x8b,0x9c,0x08,0x00,0x00,0xa9,0x3c,0x02,0xb0,0x03,0x3c,0x02,0xb0,0x03, -0x34,0x42,0x00,0x78,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x83,0x8b,0x90, -0x08,0x00,0x00,0xa9,0x3c,0x02,0xb0,0x03,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, -0x34,0x63,0x00,0x20,0x24,0x42,0x04,0x18,0x3c,0x05,0xb0,0x03,0xac,0x62,0x00,0x00, -0x34,0xa5,0x00,0x70,0x8c,0xa2,0x00,0x00,0x90,0x84,0x00,0x08,0x3c,0x06,0xb0,0x03, -0x00,0x02,0x16,0x00,0x2c,0x83,0x00,0x03,0x34,0xc6,0x00,0x72,0x24,0x07,0x00,0x01, -0x10,0x60,0x00,0x11,0x00,0x02,0x2f,0xc2,0x90,0xc2,0x00,0x00,0x00,0x00,0x18,0x21, -0x00,0x02,0x16,0x00,0x10,0xa7,0x00,0x09,0x00,0x02,0x16,0x03,0x14,0x80,0x00,0x0c, -0x30,0x43,0x00,0x03,0x83,0x82,0x8b,0x88,0x00,0x00,0x00,0x00,0x00,0x02,0x10,0x80, -0x00,0x43,0x10,0x21,0x00,0x02,0x16,0x00,0x00,0x02,0x1e,0x03,0x3c,0x02,0xb0,0x03, -0x34,0x42,0x00,0x72,0xa0,0x43,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, -0x30,0x45,0x00,0x05,0x10,0x87,0x00,0x04,0x30,0x43,0x00,0x06,0x93,0x82,0x8b,0xa0, -0x08,0x00,0x01,0x21,0x00,0x43,0x10,0x21,0x83,0x82,0x8b,0x94,0x00,0x00,0x00,0x00, -0x00,0x02,0x10,0x40,0x08,0x00,0x01,0x21,0x00,0x45,0x10,0x21,0x10,0x80,0x00,0x05, -0x00,0x00,0x18,0x21,0x24,0x63,0x00,0x01,0x00,0x64,0x10,0x2b,0x14,0x40,0xff,0xfd, -0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03, -0x3c,0x02,0x80,0x00,0x24,0x42,0x04,0xec,0x3c,0x04,0xb0,0x02,0x34,0x63,0x00,0x20, -0xac,0x62,0x00,0x00,0x34,0x84,0x00,0x08,0x24,0x02,0x00,0x01,0xaf,0x84,0x8b,0xb0, -0xa3,0x82,0x8b,0xc0,0xa7,0x80,0x8b,0xb4,0xa7,0x80,0x8b,0xb6,0xaf,0x80,0x8b,0xb8, -0xaf,0x80,0x8b,0xbc,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03, -0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x05,0x2c,0x3c,0x04,0xb0,0x03, -0xac,0x62,0x00,0x00,0x34,0x84,0x00,0xac,0x80,0xa2,0x00,0x15,0x8c,0x83,0x00,0x00, -0x27,0xbd,0xff,0xf0,0x00,0x43,0x10,0x21,0xac,0x82,0x00,0x00,0x03,0xe0,0x00,0x08, -0x27,0xbd,0x00,0x10,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0x34,0x42,0x00,0x20, -0x24,0x63,0x05,0x64,0x27,0xbd,0xff,0xe0,0xac,0x43,0x00,0x00,0xaf,0xb1,0x00,0x14, -0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x18,0x8f,0x90,0x8b,0xb0,0x0c,0x00,0x02,0x9a, -0x00,0x80,0x88,0x21,0x14,0x40,0x00,0x2a,0x3c,0x02,0x00,0x80,0x16,0x20,0x00,0x02, -0x34,0x42,0x02,0x01,0x24,0x02,0x02,0x01,0xae,0x02,0x00,0x00,0x97,0x84,0x8b,0xb4, -0x97,0x82,0x8b,0xb6,0x3c,0x03,0xb0,0x02,0x00,0x83,0x20,0x21,0x24,0x42,0x00,0x04, -0xa7,0x82,0x8b,0xb6,0xa4,0x82,0x00,0x00,0x8f,0x84,0x8b,0xb8,0x8f,0x82,0x8b,0xb0, -0x93,0x85,0x8b,0x62,0x24,0x84,0x00,0x01,0x24,0x42,0x00,0x04,0x24,0x03,0x8f,0xff, -0x3c,0x07,0xb0,0x06,0x3c,0x06,0xb0,0x03,0x00,0x43,0x10,0x24,0x00,0x85,0x28,0x2a, -0x34,0xe7,0x80,0x18,0xaf,0x82,0x8b,0xb0,0xaf,0x84,0x8b,0xb8,0x10,0xa0,0x00,0x08, -0x34,0xc6,0x01,0x08,0x8f,0x83,0x8b,0xbc,0x8f,0x84,0x8b,0x7c,0x8c,0xc2,0x00,0x00, -0x00,0x64,0x18,0x21,0x00,0x43,0x10,0x2b,0x14,0x40,0x00,0x09,0x00,0x00,0x00,0x00, -0x8c,0xe2,0x00,0x00,0x3c,0x03,0x0f,0x00,0x3c,0x04,0x04,0x00,0x00,0x43,0x10,0x24, -0x10,0x44,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x98,0x00,0x00,0x00,0x00, -0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20, -0x27,0xbd,0xff,0xd8,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0x24,0x63,0x06,0x50, -0xaf,0xb0,0x00,0x10,0x34,0x42,0x00,0x20,0x8f,0x90,0x8b,0xb0,0xac,0x43,0x00,0x00, -0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20, -0x00,0x80,0x88,0x21,0x00,0xa0,0x90,0x21,0x0c,0x00,0x02,0x9a,0x00,0xc0,0x98,0x21, -0x24,0x07,0x8f,0xff,0x14,0x40,0x00,0x19,0x26,0x03,0x00,0x04,0x24,0x02,0x0e,0x03, -0xae,0x02,0x00,0x00,0x00,0x67,0x80,0x24,0x26,0x02,0x00,0x04,0xae,0x11,0x00,0x00, -0x00,0x47,0x80,0x24,0x97,0x86,0x8b,0xb4,0x26,0x03,0x00,0x04,0xae,0x12,0x00,0x00, -0x00,0x67,0x80,0x24,0xae,0x13,0x00,0x00,0x8f,0x84,0x8b,0xb0,0x3c,0x02,0xb0,0x02, -0x97,0x85,0x8b,0xb6,0x00,0xc2,0x30,0x21,0x8f,0x82,0x8b,0xb8,0x24,0x84,0x00,0x10, -0x24,0xa5,0x00,0x10,0x00,0x87,0x20,0x24,0x24,0x42,0x00,0x01,0xa7,0x85,0x8b,0xb6, -0xaf,0x84,0x8b,0xb0,0xaf,0x82,0x8b,0xb8,0xa4,0xc5,0x00,0x00,0x8f,0xbf,0x00,0x20, -0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28, -0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x94,0x82,0x00,0x04,0x00,0x00,0x00,0x00, -0x30,0x42,0xe0,0x00,0x14,0x40,0x00,0x14,0x00,0x00,0x00,0x00,0x90,0x82,0x00,0x02, -0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfc,0x00,0x82,0x28,0x21,0x8c,0xa4,0x00,0x00, -0x3c,0x02,0x00,0x70,0x8c,0xa6,0x00,0x08,0x00,0x82,0x10,0x21,0x2c,0x43,0x00,0x06, -0x10,0x60,0x00,0x09,0x3c,0x03,0x80,0x01,0x00,0x02,0x10,0x80,0x24,0x63,0x01,0xe8, -0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08, -0x00,0x00,0x00,0x00,0xaf,0x86,0x80,0x14,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00, -0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x8c,0xa4,0x00,0x00,0x0c,0x00,0x17,0xb3, -0x00,0x00,0x00,0x00,0x08,0x00,0x01,0xde,0x00,0x00,0x00,0x00,0x0c,0x00,0x24,0xaa, -0x00,0xc0,0x20,0x21,0x08,0x00,0x01,0xde,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03, -0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00,0x8f,0x82,0x80,0x18,0x3c,0x03,0x00,0x0f, -0x34,0x63,0x42,0x40,0x00,0x43,0x10,0x21,0x00,0x82,0x20,0x2b,0x10,0x80,0x00,0x09, -0x24,0x03,0x00,0x05,0x8f,0x82,0x83,0x30,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01, -0xaf,0x82,0x83,0x30,0x10,0x43,0x00,0x03,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, -0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x8c,0x63,0x01,0x08,0x24,0x02,0x00,0x01, -0xa3,0x82,0x80,0x11,0xaf,0x80,0x83,0x30,0xaf,0x83,0x80,0x18,0x08,0x00,0x01,0xfb, -0x00,0x00,0x00,0x00,0x30,0x84,0x00,0xff,0x14,0x80,0x00,0x2f,0x00,0x00,0x00,0x00, -0x8f,0x82,0x80,0x14,0xa3,0x85,0x83,0x63,0x10,0x40,0x00,0x2b,0x2c,0xa2,0x00,0x04, -0x14,0x40,0x00,0x06,0x00,0x05,0x10,0x40,0x24,0xa2,0xff,0xfc,0x2c,0x42,0x00,0x08, -0x10,0x40,0x00,0x09,0x24,0xa2,0xff,0xf0,0x00,0x05,0x10,0x40,0x27,0x84,0x83,0x6c, -0x00,0x44,0x10,0x21,0x94,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01, -0x03,0xe0,0x00,0x08,0xa4,0x43,0x00,0x00,0x2c,0x42,0x00,0x10,0x14,0x40,0x00,0x0a, -0x00,0x05,0x10,0x40,0x24,0xa2,0xff,0xe0,0x2c,0x42,0x00,0x10,0x14,0x40,0x00,0x06, -0x00,0x05,0x10,0x40,0x24,0xa2,0xff,0xd0,0x2c,0x42,0x00,0x10,0x10,0x40,0x00,0x09, -0x24,0xa2,0xff,0xc0,0x00,0x05,0x10,0x40,0x27,0x84,0x83,0x6c,0x00,0x44,0x10,0x21, -0x94,0x43,0xff,0xf8,0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0x03,0xe0,0x00,0x08, -0xa4,0x43,0xff,0xf8,0x2c,0x42,0x00,0x10,0x10,0x40,0x00,0x07,0x00,0x05,0x10,0x40, -0x27,0x84,0x83,0x6c,0x00,0x44,0x10,0x21,0x94,0x43,0xff,0xf8,0x00,0x00,0x00,0x00, -0x24,0x63,0x00,0x01,0xa4,0x43,0xff,0xf8,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, -0x8f,0x86,0x8b,0xb0,0x8f,0x82,0x80,0x14,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10, -0x10,0x40,0x00,0x2a,0x00,0xc0,0x38,0x21,0x24,0x02,0x00,0x07,0x24,0x03,0xff,0x9c, -0xa3,0x82,0x83,0x6b,0xa3,0x83,0x83,0x6a,0x27,0x8a,0x83,0x68,0x00,0x00,0x20,0x21, -0x24,0x09,0x8f,0xff,0x00,0x04,0x10,0x80,0x00,0x4a,0x28,0x21,0x8c,0xa2,0x00,0x00, -0x24,0xe3,0x00,0x04,0x24,0x88,0x00,0x01,0xac,0xe2,0x00,0x00,0x10,0x80,0x00,0x02, -0x00,0x69,0x38,0x24,0xac,0xa0,0x00,0x00,0x31,0x04,0x00,0xff,0x2c,0x82,0x00,0x27, -0x14,0x40,0xff,0xf5,0x00,0x04,0x10,0x80,0x97,0x83,0x8b,0xb6,0x97,0x85,0x8b,0xb4, -0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x9c,0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06, -0xa7,0x83,0x8b,0xb6,0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00, -0x24,0x02,0x8f,0xff,0x24,0xc6,0x00,0x9c,0x3c,0x03,0x0f,0x00,0x00,0xc2,0x30,0x24, -0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00,0xaf,0x86,0x8b,0xb0,0x10,0xa2,0x00,0x03, -0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x98,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x10, -0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x8f,0x86,0x8b,0xb0, -0x27,0xbd,0xff,0xc8,0x24,0x02,0x00,0x08,0x24,0x03,0x00,0x20,0xaf,0xbf,0x00,0x30, -0xa3,0xa2,0x00,0x13,0xa3,0xa3,0x00,0x12,0xa7,0xa4,0x00,0x10,0x00,0xc0,0x28,0x21, -0x27,0xa9,0x00,0x10,0x00,0x00,0x38,0x21,0x24,0x08,0x8f,0xff,0x00,0x07,0x10,0x80, -0x00,0x49,0x10,0x21,0x8c,0x44,0x00,0x00,0x24,0xe3,0x00,0x01,0x30,0x67,0x00,0xff, -0x24,0xa2,0x00,0x04,0x2c,0xe3,0x00,0x08,0xac,0xa4,0x00,0x00,0x14,0x60,0xff,0xf7, -0x00,0x48,0x28,0x24,0x97,0x83,0x8b,0xb6,0x97,0x85,0x8b,0xb4,0x3c,0x02,0xb0,0x02, -0x24,0x63,0x00,0x20,0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06,0xa7,0x83,0x8b,0xb6, -0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff, -0x24,0xc6,0x00,0x20,0x3c,0x03,0x0f,0x00,0x00,0xc2,0x30,0x24,0x00,0xa3,0x28,0x24, -0x3c,0x02,0x04,0x00,0xaf,0x86,0x8b,0xb0,0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00, -0x0c,0x00,0x04,0x98,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x30,0x00,0x00,0x00,0x00, -0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0x93,0x82,0x8b,0xc0,0x00,0x00,0x00,0x00, -0x10,0x40,0x00,0x11,0x24,0x06,0x00,0x01,0x8f,0x82,0x8b,0xb8,0x3c,0x05,0xb0,0x06, -0x3c,0x04,0xb0,0x03,0x34,0xa5,0x80,0x18,0x34,0x84,0x01,0x08,0x14,0x40,0x00,0x09, -0x00,0x00,0x30,0x21,0x97,0x82,0x8b,0xb4,0x8c,0x84,0x00,0x00,0x3c,0x03,0xb0,0x02, -0x00,0x43,0x10,0x21,0xaf,0x84,0x8b,0xbc,0xa7,0x80,0x8b,0xb6,0xac,0x40,0x00,0x00, -0xac,0x40,0x00,0x04,0x8c,0xa2,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0xc0,0x10,0x21, -0x8f,0x86,0x8b,0xb0,0x8f,0x82,0x8b,0xb8,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10, -0x00,0xc0,0x40,0x21,0x14,0x40,0x00,0x0a,0x00,0x40,0x50,0x21,0x00,0x00,0x38,0x21, -0x27,0x89,0x83,0x38,0x24,0xe2,0x00,0x01,0x00,0x07,0x18,0x80,0x30,0x47,0x00,0xff, -0x00,0x69,0x18,0x21,0x2c,0xe2,0x00,0x0a,0x14,0x40,0xff,0xfa,0xac,0x60,0x00,0x00, -0x3c,0x02,0x00,0x80,0x10,0x82,0x00,0x6f,0x00,0x00,0x00,0x00,0x97,0x82,0x83,0x3e, -0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x83,0x3e,0x90,0xa3,0x00,0x15, -0x97,0x82,0x83,0x40,0x00,0x03,0x1e,0x00,0x00,0x03,0x1e,0x03,0x00,0x43,0x10,0x21, -0xa7,0x82,0x83,0x40,0x8c,0xa4,0x00,0x20,0x3c,0x02,0x00,0x60,0x3c,0x03,0x00,0x20, -0x00,0x82,0x20,0x24,0x10,0x83,0x00,0x54,0x00,0x00,0x00,0x00,0x14,0x80,0x00,0x47, -0x00,0x00,0x00,0x00,0x97,0x82,0x83,0x44,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01, -0xa7,0x82,0x83,0x44,0x84,0xa3,0x00,0x06,0x8f,0x82,0x83,0x54,0x00,0x00,0x00,0x00, -0x00,0x43,0x10,0x21,0xaf,0x82,0x83,0x54,0x25,0x42,0x00,0x01,0x28,0x43,0x27,0x10, -0xaf,0x82,0x8b,0xb8,0x10,0x60,0x00,0x09,0x24,0x02,0x00,0x04,0x93,0x83,0x80,0x11, -0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x05,0x24,0x02,0x00,0x04,0x8f,0xbf,0x00,0x10, -0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x24,0x03,0x00,0x28, -0xa3,0x83,0x83,0x3a,0xa3,0x82,0x83,0x3b,0x90,0xa2,0x00,0x18,0x93,0x83,0x83,0x63, -0x00,0x00,0x38,0x21,0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03,0xa7,0x82,0x83,0x4e, -0xa3,0x83,0x83,0x5c,0x27,0x89,0x83,0x38,0x24,0x05,0x8f,0xff,0x00,0x07,0x10,0x80, -0x00,0x49,0x10,0x21,0x8c,0x44,0x00,0x00,0x24,0xe3,0x00,0x01,0x30,0x67,0x00,0xff, -0x25,0x02,0x00,0x04,0x2c,0xe3,0x00,0x0a,0xad,0x04,0x00,0x00,0x14,0x60,0xff,0xf7, -0x00,0x45,0x40,0x24,0x97,0x83,0x8b,0xb6,0x97,0x85,0x8b,0xb4,0x3c,0x02,0xb0,0x02, -0x24,0x63,0x00,0x28,0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06,0xa7,0x83,0x8b,0xb6, -0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff, -0x24,0xc6,0x00,0x28,0x3c,0x03,0x0f,0x00,0x00,0xc2,0x30,0x24,0x00,0xa3,0x28,0x24, -0x3c,0x02,0x04,0x00,0xaf,0x86,0x8b,0xb0,0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00, -0x0c,0x00,0x04,0x98,0x00,0x00,0x00,0x00,0x0c,0x00,0x02,0x38,0x00,0x00,0x00,0x00, -0xa3,0x80,0x80,0x11,0x08,0x00,0x02,0xe7,0x00,0x00,0x00,0x00,0x97,0x82,0x83,0x46, -0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x83,0x46,0x84,0xa3,0x00,0x06, -0x8f,0x82,0x83,0x58,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21,0xaf,0x82,0x83,0x58, -0x08,0x00,0x02,0xdf,0x25,0x42,0x00,0x01,0x97,0x82,0x83,0x42,0x00,0x00,0x00,0x00, -0x24,0x42,0x00,0x01,0xa7,0x82,0x83,0x42,0x84,0xa3,0x00,0x06,0x8f,0x82,0x83,0x50, -0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21,0xaf,0x82,0x83,0x50,0x08,0x00,0x02,0xdf, -0x25,0x42,0x00,0x01,0x97,0x82,0x83,0x3c,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01, -0xa7,0x82,0x83,0x3c,0x08,0x00,0x02,0xc7,0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xd0, -0xaf,0xbf,0x00,0x28,0x8c,0xa3,0x00,0x20,0x8f,0x8a,0x8b,0xb0,0x3c,0x02,0x00,0x10, -0x00,0x62,0x10,0x24,0x00,0xa0,0x38,0x21,0x01,0x40,0x48,0x21,0x10,0x40,0x00,0x3d, -0x00,0x80,0x28,0x21,0x8c,0xe4,0x00,0x1c,0x34,0xa5,0x12,0x06,0xaf,0xa5,0x00,0x10, -0x8c,0x82,0x00,0x08,0x00,0x03,0x1c,0x42,0x30,0x63,0x00,0x30,0x00,0x02,0x13,0x02, -0x30,0x42,0x00,0x40,0x00,0x43,0x10,0x25,0x90,0xe6,0x00,0x10,0x90,0xe4,0x00,0x13, -0x94,0xe8,0x00,0x0c,0x94,0xe3,0x00,0x1a,0x00,0x02,0x16,0x00,0x90,0xe7,0x00,0x12, -0x00,0xa2,0x28,0x25,0x24,0x02,0x12,0x34,0xa7,0xa2,0x00,0x1c,0x24,0x02,0x56,0x78, -0xaf,0xa5,0x00,0x10,0xa3,0xa6,0x00,0x18,0xa3,0xa7,0x00,0x1f,0xa7,0xa3,0x00,0x1a, -0xa3,0xa4,0x00,0x19,0xa7,0xa8,0x00,0x20,0xa7,0xa2,0x00,0x22,0x00,0x00,0x28,0x21, -0x27,0xa7,0x00,0x10,0x24,0x06,0x8f,0xff,0x00,0x05,0x10,0x80,0x00,0x47,0x10,0x21, -0x8c,0x44,0x00,0x00,0x24,0xa3,0x00,0x01,0x30,0x65,0x00,0xff,0x25,0x22,0x00,0x04, -0x2c,0xa3,0x00,0x05,0xad,0x24,0x00,0x00,0x14,0x60,0xff,0xf7,0x00,0x46,0x48,0x24, -0x97,0x83,0x8b,0xb6,0x97,0x85,0x8b,0xb4,0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x14, -0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06,0xa7,0x83,0x8b,0xb6,0x34,0x84,0x80,0x18, -0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff,0x25,0x46,0x00,0x14, -0x3c,0x03,0x0f,0x00,0x00,0xc2,0x50,0x24,0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00, -0xaf,0x8a,0x8b,0xb0,0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x98, -0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x28,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, -0x27,0xbd,0x00,0x30,0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xc8, -0x00,0x04,0x22,0x00,0x34,0xa5,0x00,0x20,0x24,0x42,0x0e,0x04,0x3c,0x03,0xb0,0x00, -0xaf,0xb5,0x00,0x24,0xaf,0xb4,0x00,0x20,0xaf,0xb2,0x00,0x18,0xaf,0xb0,0x00,0x10, -0xaf,0xbf,0x00,0x30,0x00,0x83,0x80,0x21,0xaf,0xb7,0x00,0x2c,0xaf,0xb6,0x00,0x28, -0xaf,0xb3,0x00,0x1c,0xaf,0xb1,0x00,0x14,0xac,0xa2,0x00,0x00,0x8e,0x09,0x00,0x00, -0x00,0x00,0x90,0x21,0x26,0x10,0x00,0x08,0x00,0x09,0xa6,0x02,0x12,0x80,0x00,0x13, -0x00,0x00,0xa8,0x21,0x24,0x13,0x00,0x02,0x3c,0x16,0x00,0xff,0x3c,0x17,0xff,0x00, -0x8e,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x12,0x02,0x24,0x42,0x00,0x02, -0x31,0x25,0x00,0xff,0x10,0xb3,0x00,0x76,0x30,0x51,0x00,0xff,0x24,0x02,0x00,0x03, -0x10,0xa2,0x00,0x18,0x00,0x00,0x00,0x00,0x02,0x51,0x10,0x21,0x30,0x52,0xff,0xff, -0x02,0x54,0x18,0x2b,0x14,0x60,0xff,0xf2,0x02,0x11,0x80,0x21,0x12,0xa0,0x00,0x0a, -0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x18,0x8c,0x43,0x00,0x00,0x3c,0x04,0x0f,0x00, -0x3c,0x02,0x04,0x00,0x00,0x64,0x18,0x24,0x10,0x62,0x00,0x03,0x00,0x00,0x00,0x00, -0x0c,0x00,0x04,0x98,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x30,0x7b,0xb6,0x01,0x7c, -0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08, -0x27,0xbd,0x00,0x38,0x8e,0x09,0x00,0x04,0x24,0x15,0x00,0x01,0x8e,0x06,0x00,0x0c, -0x00,0x09,0x11,0x42,0x00,0x09,0x18,0xc2,0x30,0x48,0x00,0x03,0x00,0x09,0x14,0x02, -0x30,0x6c,0x00,0x03,0x00,0x09,0x26,0x02,0x11,0x15,0x00,0x45,0x30,0x43,0x00,0x0f, -0x29,0x02,0x00,0x02,0x14,0x40,0x00,0x26,0x00,0x00,0x00,0x00,0x11,0x13,0x00,0x0f, -0x00,0x00,0x38,0x21,0x00,0x07,0x22,0x02,0x30,0x84,0xff,0x00,0x3c,0x03,0x00,0xff, -0x00,0x07,0x2e,0x02,0x00,0x07,0x12,0x00,0x00,0x43,0x10,0x24,0x00,0xa4,0x28,0x25, -0x00,0xa2,0x28,0x25,0x00,0x07,0x1e,0x00,0x00,0xa3,0x28,0x25,0x0c,0x00,0x01,0x94, -0x01,0x20,0x20,0x21,0x08,0x00,0x03,0xa7,0x02,0x51,0x10,0x21,0x11,0x95,0x00,0x0f, -0x00,0x00,0x00,0x00,0x11,0x88,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x04,0x10,0x80, -0x27,0x83,0x8b,0x60,0x00,0x43,0x10,0x21,0x8c,0x47,0x00,0x18,0x08,0x00,0x03,0xce, -0x00,0x07,0x22,0x02,0x00,0x04,0x10,0x40,0x27,0x83,0x8b,0x68,0x00,0x43,0x10,0x21, -0x94,0x47,0x00,0x02,0x08,0x00,0x03,0xce,0x00,0x07,0x22,0x02,0x27,0x82,0x8b,0x60, -0x00,0x82,0x10,0x21,0x90,0x47,0x00,0x00,0x08,0x00,0x03,0xce,0x00,0x07,0x22,0x02, -0x15,0x00,0xff,0xdc,0x00,0x00,0x38,0x21,0x10,0x75,0x00,0x05,0x00,0x80,0x38,0x21, -0x00,0x65,0x18,0x26,0x24,0x82,0x01,0x00,0x00,0x00,0x38,0x21,0x00,0x43,0x38,0x0a, -0x24,0x02,0x00,0x01,0x11,0x82,0x00,0x0e,0x3c,0x02,0xb0,0x03,0x24,0x02,0x00,0x02, -0x11,0x82,0x00,0x06,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x00,0xe2,0x10,0x21, -0x8c,0x47,0x00,0x00,0x08,0x00,0x03,0xce,0x00,0x07,0x22,0x02,0x3c,0x02,0xb0,0x03, -0x00,0xe2,0x10,0x21,0x94,0x43,0x00,0x00,0x08,0x00,0x03,0xcd,0x30,0x67,0xff,0xff, -0x00,0xe2,0x10,0x21,0x90,0x43,0x00,0x00,0x08,0x00,0x03,0xcd,0x30,0x67,0x00,0xff, -0x30,0x62,0x00,0x03,0x00,0x02,0x12,0x00,0x11,0x95,0x00,0x07,0x00,0x44,0x38,0x21, -0x11,0x93,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x03,0xff,0x3c,0x02,0xb0,0x0a, -0x08,0x00,0x04,0x04,0x3c,0x02,0xb0,0x0a,0x08,0x00,0x04,0x08,0x3c,0x02,0xb0,0x0a, -0x8e,0x09,0x00,0x04,0x8e,0x02,0x00,0x08,0x8e,0x03,0x00,0x0c,0x00,0x09,0x41,0x42, -0x00,0x02,0x22,0x02,0x00,0x03,0x3a,0x02,0x30,0x84,0xff,0x00,0x30,0xe7,0xff,0x00, -0x00,0x02,0x5e,0x02,0x00,0x02,0x32,0x00,0x00,0x03,0x56,0x02,0x00,0x03,0x2a,0x00, -0x01,0x64,0x58,0x25,0x00,0xd6,0x30,0x24,0x01,0x47,0x50,0x25,0x00,0x02,0x16,0x00, -0x00,0xb6,0x28,0x24,0x00,0x03,0x1e,0x00,0x01,0x66,0x58,0x25,0x01,0x45,0x50,0x25, -0x00,0x57,0x10,0x24,0x00,0x77,0x18,0x24,0x01,0x62,0x38,0x25,0x01,0x43,0x30,0x25, -0x00,0x09,0x10,0xc2,0x00,0x09,0x1c,0x02,0x31,0x08,0x00,0x03,0x30,0x4c,0x00,0x03, -0x30,0x63,0x00,0x0f,0x00,0x09,0x26,0x02,0x00,0xe0,0x58,0x21,0x15,0x00,0x00,0x28, -0x00,0xc0,0x50,0x21,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x06,0x00,0x80,0x28,0x21, -0x24,0x02,0x00,0x03,0x14,0x62,0xff,0x69,0x02,0x51,0x10,0x21,0x24,0x85,0x01,0x00, -0x24,0x02,0x00,0x01,0x11,0x82,0x00,0x15,0x24,0x02,0x00,0x02,0x11,0x82,0x00,0x0a, -0x3c,0x03,0xb0,0x03,0x00,0xa3,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x0a,0x20,0x27, -0x01,0x6a,0x28,0x24,0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,0xac,0x62,0x00,0x00, -0x08,0x00,0x03,0xa7,0x02,0x51,0x10,0x21,0x00,0xa3,0x18,0x21,0x94,0x62,0x00,0x00, -0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24,0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25, -0xa4,0x62,0x00,0x00,0x08,0x00,0x03,0xa7,0x02,0x51,0x10,0x21,0x3c,0x03,0xb0,0x03, -0x00,0xa3,0x18,0x21,0x90,0x62,0x00,0x00,0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24, -0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,0x08,0x00,0x03,0xa6,0xa0,0x62,0x00,0x00, -0x24,0x02,0x00,0x01,0x11,0x02,0x00,0x21,0x00,0x00,0x00,0x00,0x15,0x13,0xff,0x42, -0x00,0x00,0x00,0x00,0x11,0x82,0x00,0x17,0x00,0x00,0x00,0x00,0x11,0x88,0x00,0x0b, -0x00,0x00,0x00,0x00,0x27,0x83,0x8b,0x60,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21, -0x8c,0x82,0x00,0x18,0x00,0x06,0x18,0x27,0x00,0xe6,0x28,0x24,0x00,0x43,0x10,0x24, -0x00,0x45,0x10,0x25,0x08,0x00,0x03,0xa6,0xac,0x82,0x00,0x18,0x27,0x83,0x8b,0x68, -0x00,0x04,0x20,0x40,0x00,0x83,0x20,0x21,0x94,0x82,0x00,0x02,0x00,0x06,0x18,0x27, -0x00,0xe6,0x28,0x24,0x00,0x43,0x10,0x24,0x00,0x45,0x10,0x25,0x08,0x00,0x03,0xa6, -0xa4,0x82,0x00,0x02,0x27,0x83,0x8b,0x60,0x00,0x83,0x18,0x21,0x90,0x62,0x00,0x00, -0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x5c,0x00,0xe6,0x28,0x24,0x30,0x62,0x00,0x07, -0x00,0x02,0x12,0x00,0x11,0x88,0x00,0x0f,0x00,0x44,0x10,0x21,0x11,0x93,0x00,0x07, -0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x0a,0x00,0x43,0x18,0x21,0x8c,0x62,0x00,0x00, -0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x49,0x00,0xe6,0x28,0x24,0x3c,0x03,0xb0,0x0a, -0x00,0x43,0x18,0x21,0x94,0x62,0x00,0x00,0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x52, -0x00,0xe6,0x28,0x24,0x3c,0x03,0xb0,0x0a,0x08,0x00,0x04,0x7f,0x00,0x43,0x18,0x21, -0x97,0x85,0x8b,0xb4,0x3c,0x07,0xb0,0x02,0x3c,0x04,0xb0,0x03,0x3c,0x02,0x80,0x00, -0x00,0xa7,0x28,0x21,0x34,0x84,0x00,0x20,0x24,0x42,0x12,0x60,0x24,0x03,0xff,0x80, -0xac,0x82,0x00,0x00,0xa0,0xa3,0x00,0x07,0x97,0x82,0x8b,0xb6,0x97,0x85,0x8b,0xb4, -0x3c,0x06,0xb0,0x06,0x30,0x42,0xff,0xf8,0x24,0x42,0x00,0x10,0x00,0xa2,0x10,0x21, -0x30,0x42,0x0f,0xff,0x24,0x44,0x00,0x08,0x30,0x84,0x0f,0xff,0x00,0x05,0x28,0xc2, -0x3c,0x03,0x00,0x40,0x00,0xa3,0x28,0x25,0x00,0x87,0x20,0x21,0x34,0xc6,0x80,0x18, -0xac,0xc5,0x00,0x00,0xaf,0x84,0x8b,0xb0,0xa7,0x82,0x8b,0xb4,0xa7,0x80,0x8b,0xb6, -0xaf,0x80,0x8b,0xb8,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff, -0x30,0x84,0x00,0xff,0x24,0x02,0x00,0x01,0x00,0xe0,0x48,0x21,0x30,0xc6,0x00,0xff, -0x8f,0xa7,0x00,0x10,0x10,0x82,0x00,0x07,0x00,0xa0,0x40,0x21,0x24,0x02,0x00,0x03, -0x10,0x82,0x00,0x03,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, -0x24,0xa8,0x01,0x00,0x3c,0x03,0xb0,0x03,0x24,0x02,0x00,0x01,0x00,0x07,0x20,0x27, -0x01,0x27,0x28,0x24,0x10,0xc2,0x00,0x14,0x01,0x03,0x18,0x21,0x24,0x02,0x00,0x02, -0x10,0xc2,0x00,0x09,0x00,0x07,0x50,0x27,0x3c,0x03,0xb0,0x03,0x01,0x03,0x18,0x21, -0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,0x00,0x45,0x10,0x25, -0x08,0x00,0x04,0xe3,0xac,0x62,0x00,0x00,0x3c,0x03,0xb0,0x03,0x01,0x03,0x18,0x21, -0x94,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,0x00,0x45,0x10,0x25, -0x03,0xe0,0x00,0x08,0xa4,0x62,0x00,0x00,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,0xa0,0x62,0x00,0x00,0x03,0xe0,0x00,0x08, -0x00,0x00,0x00,0x00,0x30,0x84,0x00,0x07,0x00,0x04,0x22,0x00,0x30,0xa5,0x00,0xff, -0x00,0x85,0x28,0x21,0x3c,0x02,0xb0,0x0a,0x00,0xa2,0x40,0x21,0x30,0xc6,0x00,0xff, -0x24,0x02,0x00,0x01,0x8f,0xa4,0x00,0x10,0x10,0xc2,0x00,0x14,0x24,0x02,0x00,0x02, -0x00,0x04,0x50,0x27,0x10,0xc2,0x00,0x09,0x00,0xe4,0x48,0x24,0x3c,0x03,0xb0,0x0a, -0x00,0xa3,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24, -0x00,0x49,0x10,0x25,0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00,0x3c,0x03,0xb0,0x0a, -0x00,0xa3,0x18,0x21,0x94,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24, -0x00,0x49,0x10,0x25,0x03,0xe0,0x00,0x08,0xa4,0x62,0x00,0x00,0x91,0x02,0x00,0x00, -0x00,0x04,0x18,0x27,0x00,0xe4,0x20,0x24,0x00,0x43,0x10,0x24,0x00,0x44,0x10,0x25, -0x03,0xe0,0x00,0x08,0xa1,0x02,0x00,0x00,0x30,0xa9,0x00,0xff,0x27,0x83,0x8b,0x60, -0x30,0x85,0x00,0xff,0x24,0x02,0x00,0x01,0x00,0x07,0x50,0x27,0x00,0xc7,0x40,0x24, -0x11,0x22,0x00,0x17,0x00,0xa3,0x18,0x21,0x00,0x05,0x20,0x40,0x27,0x82,0x8b,0x60, -0x00,0x05,0x28,0x80,0x27,0x83,0x8b,0x68,0x00,0x83,0x50,0x21,0x00,0xa2,0x20,0x21, -0x24,0x02,0x00,0x02,0x00,0x07,0x40,0x27,0x11,0x22,0x00,0x07,0x00,0xc7,0x28,0x24, -0x8c,0x82,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x48,0x10,0x24,0x00,0x45,0x10,0x25, -0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x18,0x95,0x42,0x00,0x02,0x00,0x00,0x00,0x00, -0x00,0x48,0x10,0x24,0x00,0x45,0x10,0x25,0x03,0xe0,0x00,0x08,0xa5,0x42,0x00,0x02, -0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,0x00,0x48,0x10,0x25, -0x03,0xe0,0x00,0x08,0xa0,0x62,0x00,0x00,0x00,0x04,0x32,0x02,0x30,0xc6,0xff,0x00, -0x00,0x04,0x16,0x02,0x00,0x04,0x1a,0x00,0x3c,0x05,0x00,0xff,0x00,0x65,0x18,0x24, -0x00,0x46,0x10,0x25,0x00,0x43,0x10,0x25,0x00,0x04,0x26,0x00,0x03,0xe0,0x00,0x08, -0x00,0x44,0x10,0x25,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xe8, -0x34,0x63,0x00,0x20,0x24,0x42,0x14,0xe4,0x3c,0x04,0xb0,0x03,0xaf,0xbf,0x00,0x14, -0xac,0x62,0x00,0x00,0xaf,0xb0,0x00,0x10,0x34,0x84,0x00,0x2c,0x8c,0x83,0x00,0x00, -0xa7,0x80,0xbb,0xf0,0x00,0x03,0x12,0x02,0x00,0x03,0x2d,0x02,0x30,0x42,0x0f,0xff, -0xa3,0x83,0xbb,0xf8,0xa7,0x85,0xbb,0xfc,0xa7,0x82,0xbb,0xfa,0xa7,0x80,0xbb,0xf2, -0xa7,0x80,0xbb,0xf4,0xa7,0x80,0xbb,0xf6,0x0c,0x00,0x06,0xce,0x24,0x04,0x05,0x00, -0x3c,0x05,0x08,0x00,0x00,0x45,0x28,0x25,0x24,0x04,0x05,0x00,0x0c,0x00,0x06,0xc1, -0x00,0x40,0x80,0x21,0x3c,0x02,0xf7,0xff,0x34,0x42,0xff,0xff,0x02,0x02,0x80,0x24, -0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xc1,0x24,0x04,0x05,0x00,0x3c,0x02,0xb0,0x03, -0x3c,0x03,0xb0,0x03,0x34,0x42,0x01,0x08,0x34,0x63,0x01,0x18,0x8c,0x45,0x00,0x00, -0x8c,0x64,0x00,0x00,0x3c,0x02,0x00,0x0f,0x3c,0x03,0x00,0x4c,0x30,0x84,0x02,0x00, -0x34,0x63,0x4b,0x40,0xaf,0x85,0xbc,0x00,0x10,0x80,0x00,0x06,0x34,0x42,0x42,0x40, -0xaf,0x83,0xbc,0x04,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08, -0x27,0xbd,0x00,0x18,0xaf,0x82,0xbc,0x04,0x08,0x00,0x05,0x69,0x00,0x00,0x00,0x00, -0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xc8,0x34,0x63,0x00,0x20, -0x24,0x42,0x15,0xc0,0x30,0x84,0x00,0xff,0xaf,0xbf,0x00,0x30,0xaf,0xb7,0x00,0x2c, -0xaf,0xb6,0x00,0x28,0xaf,0xb5,0x00,0x24,0xaf,0xb4,0x00,0x20,0xaf,0xb3,0x00,0x1c, -0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xac,0x62,0x00,0x00, -0x10,0x80,0x00,0x1c,0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x08,0x00,0x00,0x00,0x00, -0x8f,0xbf,0x00,0x30,0x7b,0xb6,0x01,0x7c,0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc, -0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0xa7,0x80,0xbb,0xf0, -0xa7,0x80,0xbb,0xf2,0xa7,0x80,0xbb,0xf4,0xa7,0x80,0xbb,0xf6,0x0c,0x00,0x06,0xce, -0x24,0x04,0x05,0x00,0x3c,0x05,0x08,0x00,0x00,0x45,0x28,0x25,0x24,0x04,0x05,0x00, -0x0c,0x00,0x06,0xc1,0x00,0x40,0x80,0x21,0x3c,0x05,0xf7,0xff,0x34,0xa5,0xff,0xff, -0x02,0x05,0x28,0x24,0x0c,0x00,0x06,0xc1,0x24,0x04,0x05,0x00,0x08,0x00,0x05,0x84, -0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xce,0x24,0x04,0x05,0xa0,0x24,0x04,0x05,0xa4, -0x0c,0x00,0x06,0xce,0x00,0x02,0xbc,0x02,0x24,0x04,0x05,0xa8,0x00,0x02,0xb4,0x02, -0x0c,0x00,0x06,0xce,0x30,0x55,0xff,0xff,0x00,0x40,0x80,0x21,0x97,0x84,0xbb,0xf0, -0x97,0x82,0xbb,0xf2,0x97,0x83,0xbb,0xf6,0x02,0xe4,0x20,0x23,0x02,0xa2,0x10,0x23, -0x00,0x82,0x20,0x21,0x97,0x82,0xbb,0xf4,0x32,0x14,0xff,0xff,0x02,0x83,0x18,0x23, -0x02,0xc2,0x10,0x23,0x00,0x82,0x20,0x21,0x93,0x82,0xbb,0xf8,0x00,0x83,0x20,0x21, -0x30,0x84,0xff,0xff,0x00,0x82,0x10,0x2b,0x14,0x40,0x00,0xaa,0x00,0x00,0x00,0x00, -0x97,0x82,0xbb,0xfc,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x2b,0x14,0x40,0x00,0x7f, -0x00,0x00,0x00,0x00,0x97,0x82,0xbb,0xfa,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x2b, -0x10,0x40,0x00,0x3a,0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xce,0x24,0x04,0x04,0x50, -0x30,0x51,0x00,0x7f,0x00,0x40,0x80,0x21,0x2e,0x22,0x00,0x32,0x10,0x40,0x00,0x13, -0x24,0x02,0x00,0x20,0x12,0x22,0x00,0x17,0x24,0x02,0xff,0x80,0x02,0x02,0x10,0x24, -0x26,0x31,0x00,0x01,0x00,0x51,0x80,0x25,0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xc1, -0x24,0x04,0x04,0x50,0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xc1,0x24,0x04,0x04,0x58, -0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xc1,0x24,0x04,0x04,0x60,0x02,0x00,0x28,0x21, -0x24,0x04,0x04,0x68,0x0c,0x00,0x06,0xc1,0x00,0x00,0x00,0x00,0xa7,0x97,0xbb,0xf0, -0xa7,0x95,0xbb,0xf2,0xa7,0x96,0xbb,0xf4,0xa7,0x94,0xbb,0xf6,0x08,0x00,0x05,0x84, -0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0, -0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x03, -0x10,0x43,0x00,0x07,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff, -0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x08, -0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x2c,0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff, -0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xc1, -0x24,0x04,0x02,0x2c,0x08,0x00,0x05,0xcb,0x24,0x02,0xff,0x80,0x0c,0x00,0x06,0xce, -0x24,0x04,0x04,0x50,0x30,0x51,0x00,0x7f,0x24,0x02,0x00,0x20,0x16,0x22,0xff,0xdb, -0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x2c,0x34,0x52,0x40,0x00, -0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xce, -0x24,0x04,0x02,0x58,0x24,0x04,0x02,0x5c,0x0c,0x00,0x06,0xce,0x00,0x02,0x9e,0x02, -0x30,0x43,0x00,0xff,0x00,0x13,0x12,0x00,0x00,0x43,0x10,0x25,0x2c,0x43,0x00,0x04, -0x14,0x60,0x00,0x1d,0x2c,0x42,0x00,0x11,0x10,0x40,0x00,0x0b,0x00,0x00,0x00,0x00, -0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,0x02,0x40,0x28,0x21, -0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xc1,0x36,0x52,0x80,0x00,0x02,0x40,0x28,0x21, -0x08,0x00,0x05,0xd9,0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x08, -0x3c,0x04,0x00,0xc0,0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,0x00,0x02,0x15,0x82, -0x24,0x03,0x00,0x02,0x14,0x43,0xff,0xee,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff, -0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x08, -0x08,0x00,0x06,0x15,0x3c,0x02,0xff,0xff,0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x08, -0x00,0x40,0x28,0x21,0x00,0x02,0x15,0x82,0x30,0x42,0x00,0x03,0x24,0x03,0x00,0x03, -0x14,0x43,0xff,0xdf,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24, -0x3c,0x03,0x00,0x80,0x08,0x00,0x06,0x2a,0x00,0x43,0x28,0x25,0x0c,0x00,0x06,0xce, -0x24,0x04,0x04,0x50,0x30,0x51,0x00,0x7f,0x00,0x40,0x80,0x21,0x2e,0x22,0x00,0x32, -0x10,0x40,0xff,0x9a,0x24,0x02,0x00,0x20,0x12,0x22,0x00,0x04,0x24,0x02,0xff,0x80, -0x02,0x02,0x10,0x24,0x08,0x00,0x05,0xcd,0x26,0x31,0x00,0x02,0x0c,0x00,0x06,0xce, -0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0,0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24, -0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x03,0x10,0x43,0x00,0x07,0x00,0x00,0x00,0x00, -0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25, -0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x08,0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x2c, -0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24, -0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x2c,0x08,0x00,0x06,0x44, -0x24,0x02,0xff,0x80,0x0c,0x00,0x06,0xce,0x24,0x04,0x04,0x50,0x00,0x40,0x80,0x21, -0x30,0x51,0x00,0x7f,0x24,0x02,0x00,0x20,0x12,0x22,0x00,0x1d,0x2e,0x22,0x00,0x21, -0x14,0x40,0xff,0x72,0x24,0x02,0xff,0x80,0x02,0x02,0x10,0x24,0x26,0x31,0xff,0xff, -0x00,0x51,0x80,0x25,0x24,0x04,0x04,0x50,0x0c,0x00,0x06,0xc1,0x02,0x00,0x28,0x21, -0x24,0x04,0x04,0x58,0x0c,0x00,0x06,0xc1,0x02,0x00,0x28,0x21,0x24,0x04,0x04,0x60, -0x0c,0x00,0x06,0xc1,0x02,0x00,0x28,0x21,0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xc1, -0x24,0x04,0x04,0x68,0x24,0x02,0x00,0x20,0x16,0x22,0xff,0x60,0x00,0x00,0x00,0x00, -0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x2c,0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff, -0x34,0x42,0x3f,0xff,0x02,0x42,0x10,0x24,0x08,0x00,0x06,0x1b,0x34,0x52,0x80,0x00, -0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x2c,0x34,0x52,0x40,0x00,0x02,0x40,0x28,0x21, -0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x58, -0x24,0x04,0x02,0x5c,0x0c,0x00,0x06,0xce,0x00,0x02,0x9e,0x02,0x30,0x43,0x00,0xff, -0x00,0x13,0x12,0x00,0x00,0x43,0x10,0x25,0x2c,0x43,0x00,0x04,0x14,0x60,0x00,0x20, -0x2c,0x42,0x00,0x11,0x10,0x40,0x00,0x0d,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0xff, -0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,0x02,0x40,0x28,0x21,0x24,0x04,0x02,0x2c, -0x0c,0x00,0x06,0xc1,0x36,0x52,0x80,0x00,0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xc1, -0x24,0x04,0x02,0x2c,0x08,0x00,0x06,0x68,0x2e,0x22,0x00,0x21,0x0c,0x00,0x06,0xce, -0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0,0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24, -0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x02,0x14,0x43,0xff,0xec,0x00,0x00,0x00,0x00, -0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25, -0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x08,0x08,0x00,0x06,0x98,0x3c,0x02,0xff,0xff, -0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x08,0x00,0x40,0x28,0x21,0x00,0x02,0x15,0x82, -0x30,0x42,0x00,0x03,0x24,0x03,0x00,0x03,0x14,0x43,0xff,0xdc,0x3c,0x03,0x00,0x80, -0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x08,0x00,0x06,0xb0, -0x00,0x43,0x28,0x25,0x30,0x83,0x00,0x03,0x00,0x04,0x20,0x40,0x00,0x83,0x20,0x23, -0x3c,0x02,0xb0,0x0a,0x00,0x82,0x20,0x21,0xac,0x85,0x00,0x00,0x00,0x00,0x18,0x21, -0x24,0x63,0x00,0x01,0x2c,0x62,0x00,0x0a,0x14,0x40,0xff,0xfe,0x24,0x63,0x00,0x01, -0x03,0xe0,0x00,0x08,0x24,0x63,0xff,0xff,0x30,0x86,0x00,0x03,0x00,0x04,0x28,0x40, -0x3c,0x03,0xb0,0x0a,0x00,0xa6,0x10,0x23,0x00,0x43,0x10,0x21,0x24,0x04,0xff,0xff, -0xac,0x44,0x10,0x00,0x00,0x00,0x18,0x21,0x24,0x63,0x00,0x01,0x2c,0x62,0x00,0x0a, -0x14,0x40,0xff,0xfe,0x24,0x63,0x00,0x01,0x24,0x63,0xff,0xff,0x00,0xa6,0x18,0x23, -0x3c,0x02,0xb0,0x0a,0x00,0x62,0x18,0x21,0x8c,0x62,0x00,0x00,0x03,0xe0,0x00,0x08, -0x00,0x00,0x00,0x00,0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x1b,0x84, -0x24,0x03,0x00,0x01,0x34,0xa5,0x00,0x20,0x3c,0x06,0xb0,0x03,0xac,0xa2,0x00,0x00, -0x34,0xc6,0x01,0x04,0xa0,0x83,0x00,0x48,0xa0,0x80,0x00,0x04,0xa0,0x80,0x00,0x05, -0xa0,0x80,0x00,0x06,0xa0,0x80,0x00,0x07,0xa0,0x80,0x00,0x08,0xa0,0x80,0x00,0x09, -0xa0,0x80,0x00,0x0a,0xa0,0x80,0x00,0x11,0xa0,0x80,0x00,0x13,0xa0,0x80,0x00,0x49, -0x94,0xc2,0x00,0x00,0xac,0x80,0x00,0x00,0xa0,0x80,0x00,0x4e,0x00,0x02,0x14,0x00, -0x00,0x02,0x14,0x03,0x30,0x43,0x00,0xff,0x30,0x42,0xff,0x00,0xa4,0x82,0x00,0x44, -0xa4,0x83,0x00,0x46,0xac,0x80,0x00,0x24,0xac,0x80,0x00,0x28,0xac,0x80,0x00,0x2c, -0xac,0x80,0x00,0x30,0xac,0x80,0x00,0x34,0xac,0x80,0x00,0x38,0xac,0x80,0x00,0x3c, -0x03,0xe0,0x00,0x08,0xac,0x80,0x00,0x40,0x84,0x83,0x00,0x0c,0x3c,0x07,0xb0,0x03, -0x34,0xe7,0x00,0x20,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, -0x27,0x83,0x8f,0xf4,0x00,0x43,0x10,0x21,0x8c,0x48,0x00,0x18,0x3c,0x02,0x80,0x00, -0x24,0x42,0x1c,0x18,0xac,0xe2,0x00,0x00,0x8d,0x03,0x00,0x08,0x80,0x82,0x00,0x13, -0x00,0x05,0x2c,0x00,0x00,0x03,0x1e,0x02,0x00,0x02,0x12,0x00,0x30,0x63,0x00,0x7e, -0x00,0x62,0x18,0x21,0x00,0x65,0x18,0x21,0x3c,0x02,0xc0,0x00,0x3c,0x05,0xb0,0x05, -0x34,0x42,0x04,0x00,0x24,0x63,0x00,0x01,0x3c,0x07,0xb0,0x05,0x3c,0x08,0xb0,0x05, -0x34,0xa5,0x04,0x20,0xac,0xa3,0x00,0x00,0x00,0xc2,0x30,0x21,0x34,0xe7,0x04,0x24, -0x35,0x08,0x02,0x28,0x24,0x02,0x00,0x01,0x24,0x03,0x00,0x20,0xac,0xe6,0x00,0x00, -0xac,0x82,0x00,0x3c,0x03,0xe0,0x00,0x08,0xa1,0x03,0x00,0x00,0x27,0xbd,0xff,0xa8, -0x00,0x07,0x60,0x80,0x27,0x82,0xb3,0xf0,0xaf,0xbe,0x00,0x50,0xaf,0xb7,0x00,0x4c, -0xaf,0xb5,0x00,0x44,0xaf,0xb4,0x00,0x40,0xaf,0xbf,0x00,0x54,0xaf,0xb6,0x00,0x48, -0xaf,0xb3,0x00,0x3c,0xaf,0xb2,0x00,0x38,0xaf,0xb1,0x00,0x34,0xaf,0xb0,0x00,0x30, -0x01,0x82,0x10,0x21,0x8c,0x43,0x00,0x00,0x00,0xe0,0x70,0x21,0x3c,0x02,0x80,0x00, -0x94,0x73,0x00,0x14,0x3c,0x07,0xb0,0x03,0x34,0xe7,0x00,0x20,0x24,0x42,0x1c,0xac, -0x3c,0x03,0xb0,0x05,0xac,0xe2,0x00,0x00,0x34,0x63,0x01,0x28,0x90,0x67,0x00,0x00, -0x00,0x13,0xa8,0xc0,0x02,0xb3,0x18,0x21,0x27,0x82,0x8f,0xf4,0x00,0x03,0x18,0x80, -0x00,0x62,0x18,0x21,0x00,0x05,0x2c,0x00,0x00,0x07,0x3e,0x00,0x28,0xc2,0x00,0x03, -0x00,0xc0,0xa0,0x21,0x00,0x80,0x78,0x21,0x00,0x05,0xbc,0x03,0x8c,0x68,0x00,0x18, -0x02,0xa0,0x58,0x21,0x10,0x40,0x01,0x81,0x00,0x07,0xf6,0x03,0x00,0xde,0x10,0x07, -0x30,0x5e,0x00,0x01,0x01,0x73,0x10,0x21,0x27,0x83,0x8f,0xf8,0x00,0x02,0x10,0x80, -0x00,0x43,0x10,0x21,0x80,0x4d,0x00,0x06,0x8d,0x03,0x00,0x00,0x8d,0x02,0x00,0x04, -0x8d,0x0a,0x00,0x08,0x8d,0x03,0x00,0x0c,0xaf,0xa2,0x00,0x20,0x11,0xa0,0x01,0x71, -0xaf,0xa3,0x00,0x18,0x27,0x82,0xb3,0xf0,0x01,0x82,0x10,0x21,0x8c,0x44,0x00,0x00, -0x00,0x00,0x00,0x00,0x90,0x83,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x04, -0x14,0x60,0x00,0x12,0x00,0x00,0xb0,0x21,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x46, -0x90,0x43,0x00,0x00,0x2a,0x84,0x00,0x04,0x10,0x80,0x01,0x56,0x30,0x65,0x00,0x01, -0x91,0xe2,0x00,0x09,0x00,0x00,0x00,0x00,0x12,0x82,0x00,0x02,0x00,0x00,0x00,0x00, -0x00,0x00,0x28,0x21,0x14,0xa0,0x00,0x03,0x00,0x00,0x38,0x21,0x13,0xc0,0x00,0x03, -0x38,0xf6,0x00,0x01,0x24,0x07,0x00,0x01,0x38,0xf6,0x00,0x01,0x01,0x73,0x10,0x21, -0x00,0x02,0x30,0x80,0x27,0x83,0x90,0x00,0x00,0xc3,0x48,0x21,0x91,0x25,0x00,0x00, -0x8f,0xa4,0x00,0x20,0x2c,0xa3,0x00,0x04,0x00,0x04,0x11,0xc3,0x30,0x42,0x00,0x01, -0x00,0x03,0xb0,0x0b,0x12,0xc0,0x00,0xd8,0xaf,0xa2,0x00,0x24,0x93,0x90,0xbb,0xda, -0x00,0x0a,0x16,0x42,0x30,0x52,0x00,0x3f,0x2e,0x06,0x00,0x0c,0x10,0xc0,0x00,0xc0, -0x00,0xa0,0x20,0x21,0x2c,0xa2,0x00,0x10,0x14,0x40,0x00,0x04,0x00,0x90,0x10,0x2b, -0x30,0xa2,0x00,0x07,0x24,0x44,0x00,0x04,0x00,0x90,0x10,0x2b,0x10,0x40,0x00,0x0b, -0x01,0x73,0x10,0x21,0x27,0x85,0xbb,0x0c,0x00,0x10,0x10,0x40,0x00,0x50,0x10,0x21, -0x00,0x45,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x18,0x2b, -0x14,0x60,0xff,0xfa,0x00,0x10,0x10,0x40,0x01,0x73,0x10,0x21,0x00,0x02,0x10,0x80, -0x27,0x83,0x8f,0xf8,0x00,0x43,0x10,0x21,0x31,0xa4,0x00,0x01,0x10,0x80,0x00,0xa5, -0xa0,0x50,0x00,0x07,0x3c,0x04,0xb0,0x05,0x34,0x84,0x00,0x08,0x24,0x02,0x00,0x01, -0x3c,0x03,0x80,0x00,0xa1,0xe2,0x00,0x4e,0xac,0x83,0x00,0x00,0x8c,0x85,0x00,0x00, -0x3c,0x02,0x00,0xf0,0x3c,0x03,0x40,0xf0,0x34,0x42,0xf0,0x00,0x34,0x63,0xf0,0x00, -0x24,0x17,0x00,0x0e,0x24,0x13,0x01,0x06,0xac,0x82,0x00,0x00,0xac,0x83,0x00,0x00, -0x27,0x82,0xb3,0xf0,0x01,0x82,0x10,0x21,0x8c,0x43,0x00,0x00,0x24,0x05,0x00,0x01, -0xaf,0xa5,0x00,0x1c,0x90,0x62,0x00,0x16,0x00,0x13,0xa8,0xc0,0x32,0x51,0x00,0x02, -0x34,0x42,0x00,0x04,0xa0,0x62,0x00,0x16,0x8f,0xa3,0x00,0x20,0x8f,0xa4,0x00,0x18, -0x00,0x03,0x13,0x43,0x00,0x04,0x1a,0x02,0x30,0x47,0x00,0x01,0x12,0x20,0x00,0x04, -0x30,0x64,0x07,0xff,0x2e,0x03,0x00,0x04,0x32,0x42,0x00,0x33,0x00,0x43,0x90,0x0b, -0x8f,0xa5,0x00,0x24,0x8f,0xa6,0x00,0x1c,0x00,0x12,0x10,0x40,0x00,0x05,0x19,0xc0, -0x00,0x47,0x10,0x21,0x00,0x06,0x2a,0x80,0x00,0x43,0x10,0x21,0x00,0x10,0x32,0x00, -0x00,0x04,0x24,0x80,0x02,0x65,0x28,0x21,0x00,0xa4,0x28,0x21,0x00,0x46,0x10,0x21, -0x00,0x17,0x1c,0x00,0x3c,0x04,0xc0,0x00,0x00,0x43,0x30,0x21,0x16,0x80,0x00,0x29, -0x00,0xa4,0x28,0x21,0x3c,0x02,0xb0,0x05,0x34,0x42,0x04,0x00,0x3c,0x03,0xb0,0x05, -0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x04,0x34,0x84,0x02,0x28, -0x24,0x02,0x00,0x01,0xac,0x65,0x00,0x00,0xa0,0x82,0x00,0x00,0x3c,0x02,0xb0,0x09, -0x34,0x42,0x01,0x46,0x90,0x44,0x00,0x00,0x91,0xe3,0x00,0x09,0x30,0x86,0x00,0x01, -0x02,0x83,0x18,0x26,0x00,0x03,0x30,0x0b,0x14,0xc0,0x00,0x03,0x00,0x00,0x28,0x21, -0x13,0xc0,0x00,0x03,0x02,0xb3,0x10,0x21,0x24,0x05,0x00,0x01,0x02,0xb3,0x10,0x21, -0x27,0x83,0x8f,0xf8,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x84,0x48,0x00,0x04, -0x00,0xa0,0x30,0x21,0x00,0xe0,0x20,0x21,0x02,0x80,0x28,0x21,0x02,0xc0,0x38,0x21, -0x0c,0x00,0x00,0x72,0xaf,0xa8,0x00,0x10,0x7b,0xbe,0x02,0xbc,0x7b,0xb6,0x02,0x7c, -0x7b,0xb4,0x02,0x3c,0x7b,0xb2,0x01,0xfc,0x7b,0xb0,0x01,0xbc,0x03,0xe0,0x00,0x08, -0x27,0xbd,0x00,0x58,0x24,0x02,0x00,0x01,0x12,0x82,0x00,0x3d,0x3c,0x02,0xb0,0x05, -0x24,0x02,0x00,0x02,0x12,0x82,0x00,0x31,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x03, -0x12,0x82,0x00,0x25,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x10,0x12,0x82,0x00,0x19, -0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x11,0x12,0x82,0x00,0x0d,0x3c,0x02,0xb0,0x05, -0x24,0x02,0x00,0x12,0x16,0x82,0xff,0xd1,0x3c,0x02,0xb0,0x05,0x3c,0x03,0xb0,0x05, -0x34,0x42,0x04,0x20,0x3c,0x04,0xb0,0x05,0x34,0x63,0x04,0x24,0xac,0x46,0x00,0x00, -0x34,0x84,0x02,0x28,0xac,0x65,0x00,0x00,0x08,0x00,0x07,0xe2,0x24,0x02,0x00,0x20, -0x34,0x42,0x04,0x40,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00, -0x34,0x63,0x04,0x44,0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x40,0x08,0x00,0x07,0xe2, -0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x28,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05, -0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x2c,0x34,0x84,0x02,0x28,0x24,0x02,0xff,0x80, -0x08,0x00,0x07,0xe2,0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x18,0x3c,0x03,0xb0,0x05, -0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x1c,0x34,0x84,0x02,0x28, -0x24,0x02,0x00,0x08,0x08,0x00,0x07,0xe2,0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x10, -0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x14, -0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x04,0x08,0x00,0x07,0xe2,0xac,0x65,0x00,0x00, -0x34,0x42,0x04,0x08,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00, -0x34,0x63,0x04,0x0c,0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x02,0x08,0x00,0x07,0xe2, -0xac,0x65,0x00,0x00,0x24,0x17,0x00,0x14,0x08,0x00,0x07,0xb4,0x24,0x13,0x01,0x02, -0x30,0xa2,0x00,0x07,0x24,0x44,0x00,0x0c,0x00,0x90,0x18,0x2b,0x10,0x60,0x00,0x0c, -0x26,0x02,0x00,0x04,0x27,0x85,0xbb,0x0c,0x00,0x10,0x10,0x40,0x00,0x50,0x10,0x21, -0x00,0x45,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x18,0x2b, -0x14,0x60,0xff,0xfa,0x00,0x10,0x10,0x40,0x2e,0x06,0x00,0x0c,0x26,0x02,0x00,0x04, -0x08,0x00,0x07,0x9e,0x00,0x46,0x80,0x0a,0x27,0x82,0xb3,0xf0,0x01,0x82,0x20,0x21, -0x8c,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0xe2,0x00,0x19,0x00,0x00,0x00,0x00, -0x14,0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x27,0x82,0x90,0x10,0x00,0xc2,0x10,0x21, -0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x14,0x00,0x00,0x00,0x00, -0x90,0xe3,0x00,0x16,0x27,0x82,0x8f,0xf8,0x00,0xc2,0x10,0x21,0x34,0x63,0x00,0x20, -0x90,0x50,0x00,0x07,0xa0,0xe3,0x00,0x16,0x8c,0x84,0x00,0x00,0x00,0x0a,0x1e,0x42, -0x24,0x06,0x00,0x01,0x90,0x82,0x00,0x16,0x30,0x71,0x00,0x02,0x30,0x72,0x00,0x3f, -0x30,0x42,0x00,0xfb,0x24,0x17,0x00,0x18,0x24,0x13,0x01,0x03,0x24,0x15,0x08,0x18, -0xaf,0xa6,0x00,0x1c,0x08,0x00,0x07,0xbe,0xa0,0x82,0x00,0x16,0x8d,0x02,0x00,0x04, -0x00,0x0a,0x1c,0x42,0x30,0x42,0x00,0x10,0x14,0x40,0x00,0x15,0x30,0x72,0x00,0x3f, -0x81,0x22,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x11,0x30,0x72,0x00,0x3e, -0x27,0x83,0x90,0x08,0x00,0xc3,0x18,0x21,0x80,0x64,0x00,0x00,0x27,0x83,0xb5,0x68, -0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23, -0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x05,0x90,0x43,0x00,0x04, -0x00,0x00,0x00,0x00,0x00,0x64,0x18,0x24,0x30,0x63,0x00,0x01,0x02,0x43,0x90,0x25, -0x27,0x85,0xb3,0xf0,0x01,0x85,0x28,0x21,0x8c,0xa6,0x00,0x00,0x01,0x73,0x10,0x21, -0x27,0x83,0x90,0x00,0x90,0xc4,0x00,0x16,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21, -0x30,0x84,0x00,0xdf,0x90,0x50,0x00,0x00,0xa0,0xc4,0x00,0x16,0x80,0xc6,0x00,0x12, -0x8c,0xa3,0x00,0x00,0x2d,0xc4,0x00,0x02,0xaf,0xa6,0x00,0x1c,0x90,0x62,0x00,0x16, -0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfb,0x14,0x80,0x00,0x06,0xa0,0x62,0x00,0x16, -0x24,0x02,0x00,0x06,0x11,0xc2,0x00,0x03,0x24,0x02,0x00,0x04,0x15,0xc2,0xff,0x0e, -0x32,0x51,0x00,0x02,0x32,0x51,0x00,0x02,0x2e,0x02,0x00,0x0c,0x14,0x40,0x00,0x0f, -0x00,0x11,0x18,0x2b,0x32,0x02,0x00,0x0f,0x34,0x42,0x00,0x10,0x00,0x03,0x19,0x00, -0x00,0x43,0x18,0x21,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xb8,0xa0,0x43,0x00,0x00, -0x00,0x00,0x20,0x21,0x02,0x00,0x28,0x21,0x0c,0x00,0x02,0x05,0xaf,0xaf,0x00,0x28, -0x8f,0xaf,0x00,0x28,0x08,0x00,0x07,0xbe,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0xb9, -0x32,0x03,0x00,0xff,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x42,0x90,0x62,0x00,0x00, -0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x0f,0x14,0x40,0xfe,0xaa,0x00,0x00,0x00,0x00, -0x91,0xe2,0x00,0x09,0x00,0x00,0x00,0x00,0x02,0x82,0x10,0x26,0x08,0x00,0x07,0x75, -0x00,0x02,0x28,0x0b,0x08,0x00,0x07,0x7b,0x00,0x00,0xb0,0x21,0x24,0x02,0x00,0x10, -0x10,0xc2,0x00,0x08,0x24,0x02,0x00,0x11,0x10,0xc2,0xfe,0x7d,0x00,0x07,0x17,0x83, -0x24,0x02,0x00,0x12,0x14,0xc2,0xfe,0x7b,0x00,0x07,0x17,0x43,0x08,0x00,0x07,0x55, -0x30,0x5e,0x00,0x01,0x08,0x00,0x07,0x55,0x00,0x07,0xf7,0xc2,0x00,0x04,0x10,0x40, -0x27,0x83,0x80,0x1c,0x00,0x43,0x10,0x21,0x00,0x80,0x40,0x21,0x94,0x44,0x00,0x00, -0x2d,0x07,0x00,0x04,0x24,0xc2,0x00,0x03,0x00,0x47,0x30,0x0a,0x00,0x86,0x00,0x18, -0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x23,0x7c, -0xac,0x62,0x00,0x00,0x2d,0x06,0x00,0x10,0x00,0x00,0x20,0x12,0x00,0x04,0x22,0x42, -0x24,0x84,0x00,0x01,0x24,0x83,0x00,0xc0,0x10,0xe0,0x00,0x0b,0x24,0x82,0x00,0x60, -0x00,0x40,0x20,0x21,0x00,0x65,0x20,0x0a,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x00, -0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x00,0x44,0x20,0x04, -0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21,0x24,0x85,0x00,0x28,0x24,0x83,0x00,0x24, -0x31,0x02,0x00,0x08,0x14,0xc0,0xff,0xf4,0x24,0x84,0x00,0x14,0x00,0x60,0x20,0x21, -0x08,0x00,0x08,0xf6,0x00,0xa2,0x20,0x0b,0x27,0xbd,0xff,0xe0,0x3c,0x03,0xb0,0x03, -0x3c,0x02,0x80,0x00,0xaf,0xb0,0x00,0x10,0x24,0x42,0x24,0x18,0x00,0x80,0x80,0x21, -0x34,0x63,0x00,0x20,0x3c,0x04,0xb0,0x03,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14, -0xaf,0xbf,0x00,0x1c,0x83,0xb1,0x00,0x33,0x83,0xa8,0x00,0x37,0x34,0x84,0x01,0x10, -0xac,0x62,0x00,0x00,0x2e,0x02,0x00,0x10,0x00,0xe0,0x90,0x21,0x8c,0x87,0x00,0x00, -0x14,0x40,0x00,0x0c,0x2e,0x02,0x00,0x0c,0x3c,0x02,0x00,0x0f,0x34,0x42,0xf0,0x00, -0x00,0xe2,0x10,0x24,0x14,0x40,0x00,0x37,0x32,0x02,0x00,0x08,0x32,0x02,0x00,0x07, -0x27,0x83,0x80,0xcc,0x00,0x43,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00, -0x2e,0x02,0x00,0x0c,0x14,0x40,0x00,0x03,0x02,0x00,0x20,0x21,0x32,0x02,0x00,0x0f, -0x24,0x44,0x00,0x0c,0x00,0x87,0x10,0x06,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x07, -0x2c,0x82,0x00,0x0c,0x00,0x04,0x10,0x80,0x27,0x83,0xb4,0x40,0x00,0x43,0x10,0x21, -0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x82,0x00,0x0c,0x14,0x40,0x00,0x05, -0x00,0x05,0x10,0x40,0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0x82,0x10,0x21, -0x24,0x44,0x00,0x04,0x15,0x00,0x00,0x02,0x24,0x06,0x00,0x20,0x24,0x06,0x00,0x0e, -0x0c,0x00,0x08,0xdf,0x00,0x00,0x00,0x00,0x00,0x40,0x30,0x21,0x3c,0x02,0xb0,0x03, -0x34,0x42,0x01,0x00,0x90,0x43,0x00,0x00,0x2e,0x04,0x00,0x04,0x24,0x02,0x00,0x10, -0x24,0x05,0x00,0x0a,0x00,0x44,0x28,0x0a,0x30,0x63,0x00,0x01,0x14,0x60,0x00,0x02, -0x00,0x05,0x10,0x40,0x00,0xa0,0x10,0x21,0x30,0x45,0x00,0xff,0x00,0xc5,0x10,0x21, -0x24,0x46,0x00,0x46,0x02,0x26,0x18,0x04,0xa6,0x43,0x00,0x00,0x8f,0xbf,0x00,0x1c, -0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x00,0xc0,0x10,0x21,0x03,0xe0,0x00,0x08, -0x27,0xbd,0x00,0x20,0x10,0x40,0xff,0xcf,0x2e,0x02,0x00,0x0c,0x32,0x02,0x00,0x07, -0x27,0x83,0x80,0xc4,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x00,0x08,0x00,0x09,0x24, -0x02,0x04,0x80,0x23,0x27,0xbd,0xff,0xb8,0x00,0x05,0x38,0x80,0x27,0x82,0xb3,0xf0, -0xaf,0xbe,0x00,0x40,0xaf,0xb6,0x00,0x38,0xaf,0xb3,0x00,0x2c,0xaf,0xbf,0x00,0x44, -0xaf,0xb7,0x00,0x3c,0xaf,0xb5,0x00,0x34,0xaf,0xb4,0x00,0x30,0xaf,0xb2,0x00,0x28, -0xaf,0xb1,0x00,0x24,0xaf,0xb0,0x00,0x20,0x00,0xe2,0x38,0x21,0x8c,0xe6,0x00,0x00, -0xaf,0xa5,0x00,0x4c,0x3c,0x02,0x80,0x00,0x3c,0x05,0xb0,0x03,0x34,0xa5,0x00,0x20, -0x24,0x42,0x25,0x74,0x24,0x03,0x00,0x01,0xac,0xa2,0x00,0x00,0xa0,0xc3,0x00,0x12, -0x8c,0xe5,0x00,0x00,0x94,0xc3,0x00,0x06,0x90,0xa2,0x00,0x16,0xa4,0xc3,0x00,0x14, -0x27,0x83,0x8f,0xf0,0x34,0x42,0x00,0x08,0xa0,0xa2,0x00,0x16,0x8c,0xe8,0x00,0x00, -0xaf,0xa4,0x00,0x48,0x27,0x82,0x8f,0xf4,0x95,0x11,0x00,0x14,0x00,0x00,0x00,0x00, -0x00,0x11,0x98,0xc0,0x02,0x71,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x82,0x10,0x21, -0x8c,0x52,0x00,0x18,0x00,0x83,0x18,0x21,0x84,0x75,0x00,0x06,0x8e,0x45,0x00,0x08, -0x8e,0x46,0x00,0x04,0x8e,0x47,0x00,0x04,0x00,0x05,0x1c,0x82,0x00,0x06,0x31,0x42, -0x27,0x82,0x90,0x00,0x30,0x63,0x00,0x01,0x30,0xc6,0x00,0x01,0x00,0x82,0x20,0x21, -0xa5,0x15,0x00,0x1a,0x00,0x05,0x14,0x42,0xaf,0xa3,0x00,0x18,0xaf,0xa6,0x00,0x1c, -0x30,0xe7,0x00,0x10,0x30,0x56,0x00,0x01,0x80,0x97,0x00,0x06,0x14,0xe0,0x00,0x47, -0x00,0x05,0xf7,0xc2,0x80,0x82,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x44, -0x02,0x71,0x10,0x21,0x93,0x90,0xbb,0xd9,0x00,0x00,0x00,0x00,0x2e,0x02,0x00,0x0c, -0x14,0x40,0x00,0x06,0x02,0x00,0x20,0x21,0x00,0x16,0x10,0x40,0x00,0x43,0x10,0x21, -0x00,0x02,0x11,0x00,0x02,0x02,0x10,0x21,0x24,0x44,0x00,0x04,0x02,0x71,0x10,0x21, -0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0x00,0x80,0x80,0x21, -0xa0,0x44,0x00,0x03,0xa0,0x44,0x00,0x00,0x02,0x00,0x20,0x21,0x02,0xc0,0x28,0x21, -0x0c,0x00,0x08,0xdf,0x02,0xa0,0x30,0x21,0x02,0x71,0x18,0x21,0x00,0x03,0x88,0x80, -0x00,0x40,0xa0,0x21,0x27,0x82,0x90,0x10,0x02,0x22,0x10,0x21,0x8c,0x44,0x00,0x00, -0x26,0xe3,0x00,0x02,0x00,0x03,0x17,0xc2,0x00,0x62,0x18,0x21,0x00,0x04,0x25,0xc2, -0x00,0x03,0x18,0x43,0x30,0x84,0x00,0x01,0x00,0x03,0x18,0x40,0x03,0xc4,0x20,0x24, -0x14,0x80,0x00,0x15,0x02,0x43,0x38,0x21,0x3c,0x08,0xb0,0x03,0x35,0x08,0x00,0x28, -0x8d,0x03,0x00,0x00,0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x48,0x27,0x82,0x8f,0xf8, -0x02,0x22,0x10,0x21,0x24,0x63,0x00,0x01,0x02,0xa0,0x28,0x21,0xa4,0x54,0x00,0x04, -0x00,0xc0,0x38,0x21,0x0c,0x00,0x07,0x2b,0xad,0x03,0x00,0x00,0x7b,0xbe,0x02,0x3c, -0x7b,0xb6,0x01,0xfc,0x7b,0xb4,0x01,0xbc,0x7b,0xb2,0x01,0x7c,0x7b,0xb0,0x01,0x3c, -0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x48,0x8f,0xa2,0x00,0x1c,0x8f,0xa6,0x00,0x18, -0x02,0x00,0x20,0x21,0x02,0xc0,0x28,0x21,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0x06, -0xaf,0xa0,0x00,0x14,0x08,0x00,0x09,0xc2,0x02,0x82,0xa0,0x21,0x02,0x71,0x10,0x21, -0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0x90,0x50,0x00,0x00, -0x08,0x00,0x09,0xae,0xa0,0x50,0x00,0x03,0x27,0xbd,0xff,0xb8,0xaf,0xb1,0x00,0x24, -0x8f,0xb1,0x00,0x5c,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20, -0x24,0x42,0x27,0x98,0xaf,0xbe,0x00,0x40,0xaf,0xb7,0x00,0x3c,0xaf,0xb6,0x00,0x38, -0xaf,0xb5,0x00,0x34,0xaf,0xb4,0x00,0x30,0xaf,0xa5,0x00,0x4c,0x8f,0xb5,0x00,0x58, -0xaf,0xbf,0x00,0x44,0xaf,0xb3,0x00,0x2c,0xaf,0xb2,0x00,0x28,0xaf,0xb0,0x00,0x20, -0x00,0xe0,0xb0,0x21,0xac,0x62,0x00,0x00,0x00,0x80,0xf0,0x21,0x00,0x00,0xb8,0x21, -0x16,0x20,0x00,0x2b,0x00,0x00,0xa0,0x21,0x27,0x85,0xb3,0xf0,0x00,0x07,0x10,0x80, -0x00,0x45,0x10,0x21,0x8c,0x53,0x00,0x00,0x00,0x15,0x18,0x80,0x00,0x65,0x18,0x21, -0x92,0x62,0x00,0x16,0x8c,0x72,0x00,0x00,0x30,0x42,0x00,0x03,0x14,0x40,0x00,0x2d, -0x00,0x00,0x00,0x00,0x92,0x42,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x03, -0x14,0x40,0x00,0x28,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x34,0x00,0x00,0x00,0x00, -0x14,0x40,0x00,0x18,0x02,0x20,0x10,0x21,0x8c,0x82,0x00,0x38,0x00,0x00,0x00,0x00, -0x14,0x40,0x00,0x14,0x02,0x20,0x10,0x21,0x8c,0x82,0x00,0x3c,0x00,0x00,0x00,0x00, -0x14,0x40,0x00,0x0f,0x3c,0x03,0xb0,0x09,0x3c,0x05,0xb0,0x05,0x34,0x63,0x01,0x44, -0x34,0xa5,0x02,0x52,0x94,0x66,0x00,0x00,0x90,0xa2,0x00,0x00,0x8f,0xa3,0x00,0x4c, -0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x06,0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x04, -0x30,0xc6,0xff,0xff,0x2c,0xc2,0x00,0x41,0x10,0x40,0x00,0x09,0x24,0x05,0x00,0x14, -0x02,0x20,0x10,0x21,0x7b,0xbe,0x02,0x3c,0x7b,0xb6,0x01,0xfc,0x7b,0xb4,0x01,0xbc, -0x7b,0xb2,0x01,0x7c,0x7b,0xb0,0x01,0x3c,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x48, -0x0c,0x00,0x07,0x06,0x24,0x06,0x01,0x07,0x24,0x02,0x00,0x01,0x08,0x00,0x0a,0x28, -0xa3,0xc2,0x00,0x11,0x10,0xc0,0x00,0x1c,0x24,0x02,0x00,0x01,0x10,0xc2,0x00,0x17, -0x00,0xc0,0x88,0x21,0x96,0x54,0x00,0x1a,0x02,0xa0,0xb8,0x21,0x12,0x20,0xff,0xed, -0x02,0x20,0x10,0x21,0x27,0x83,0xb3,0xf0,0x00,0x17,0x10,0x80,0x00,0x43,0x10,0x21, -0x8c,0x44,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x28,0x80,0x86,0x00,0x12, -0x8c,0x62,0x00,0x00,0x00,0x14,0x2c,0x00,0x00,0x05,0x2c,0x03,0x00,0x46,0x10,0x21, -0x8f,0xa6,0x00,0x4c,0x02,0xe0,0x38,0x21,0x03,0xc0,0x20,0x21,0x0c,0x00,0x07,0x2b, -0xac,0x62,0x00,0x00,0x08,0x00,0x0a,0x28,0xaf,0xd1,0x00,0x40,0x96,0x74,0x00,0x1a, -0x08,0x00,0x0a,0x3b,0x02,0xc0,0xb8,0x21,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08, -0x8c,0x50,0x00,0x00,0x02,0x60,0x20,0x21,0x0c,0x00,0x1f,0x11,0x02,0x00,0x28,0x21, -0x30,0x42,0x00,0xff,0x02,0x00,0x28,0x21,0x02,0x40,0x20,0x21,0x0c,0x00,0x1f,0x11, -0xaf,0xa2,0x00,0x18,0x8f,0xa4,0x00,0x18,0x00,0x00,0x00,0x00,0x10,0x80,0x00,0xed, -0x30,0x50,0x00,0xff,0x12,0x00,0x00,0x18,0x24,0x11,0x00,0x01,0x96,0x63,0x00,0x14, -0x96,0x44,0x00,0x14,0x27,0x85,0x8f,0xf0,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, -0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x00,0x04,0x18,0xc0,0x8c,0x46,0x00,0x08, -0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x65,0x18,0x21,0x00,0x06,0x17,0x02, -0x24,0x04,0x00,0xff,0x8c,0x63,0x00,0x08,0x10,0x44,0x00,0xd6,0x00,0x03,0x17,0x02, -0x10,0x44,0x00,0xd5,0x3c,0x02,0x80,0x00,0x00,0x66,0x18,0x2b,0x24,0x11,0x00,0x02, -0x24,0x02,0x00,0x01,0x00,0x43,0x88,0x0a,0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x5a, -0x24,0x02,0x00,0x02,0x16,0x22,0xff,0xbd,0x00,0x00,0x00,0x00,0x96,0x49,0x00,0x14, -0x27,0x82,0x8f,0xf4,0x02,0xa0,0xb8,0x21,0x00,0x09,0x50,0xc0,0x01,0x49,0x18,0x21, -0x00,0x03,0x40,0x80,0x01,0x02,0x10,0x21,0x8c,0x43,0x00,0x18,0x00,0x00,0x00,0x00, -0x8c,0x65,0x00,0x08,0x8c,0x62,0x00,0x0c,0x8c,0x62,0x00,0x04,0x00,0x05,0x24,0x42, -0x00,0x05,0x1c,0x82,0x30,0x42,0x00,0x10,0x30,0x66,0x00,0x01,0x14,0x40,0x00,0x41, -0x30,0x87,0x00,0x01,0x27,0x82,0x90,0x08,0x01,0x02,0x10,0x21,0x80,0x44,0x00,0x00, -0x27,0x82,0xb5,0x68,0x00,0x04,0x19,0x00,0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80, -0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x90,0x45,0x00,0x05, -0x27,0x84,0xb4,0x90,0x00,0x64,0x18,0x21,0x90,0x63,0x00,0x00,0x10,0xa0,0x00,0x2b, -0x2c,0x64,0x00,0x0c,0x14,0x80,0x00,0x04,0x00,0x60,0x10,0x21,0x00,0x06,0x11,0x00, -0x00,0x62,0x10,0x21,0x24,0x42,0x00,0x24,0x3c,0x01,0xb0,0x03,0xa0,0x22,0x00,0xb9, -0x14,0x80,0x00,0x06,0x00,0x60,0x28,0x21,0x00,0x07,0x10,0x40,0x00,0x46,0x10,0x21, -0x00,0x02,0x11,0x00,0x00,0x62,0x10,0x21,0x24,0x45,0x00,0x04,0x01,0x49,0x10,0x21, -0x27,0x83,0x90,0x00,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0xa0,0x18,0x21, -0xa0,0x45,0x00,0x03,0xa0,0x45,0x00,0x00,0x24,0x02,0x00,0x08,0x12,0x02,0x00,0x0b, -0x24,0x02,0x00,0x01,0x00,0x60,0x28,0x21,0x02,0x40,0x20,0x21,0x0c,0x00,0x1f,0x8d, -0xaf,0xa2,0x00,0x10,0x30,0x54,0xff,0xff,0x92,0x42,0x00,0x16,0x00,0x00,0x00,0x00, -0x02,0x02,0x10,0x25,0x08,0x00,0x0a,0x3b,0xa2,0x42,0x00,0x16,0x00,0x60,0x28,0x21, -0x02,0x40,0x20,0x21,0x0c,0x00,0x1f,0x3e,0xaf,0xa0,0x00,0x10,0x08,0x00,0x0a,0xbe, -0x30,0x54,0xff,0xff,0x08,0x00,0x0a,0xa6,0x00,0x60,0x10,0x21,0x14,0x80,0xff,0xfd, -0x00,0x00,0x00,0x00,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21,0x08,0x00,0x0a,0xa6, -0x24,0x42,0x00,0x04,0x27,0x82,0x90,0x00,0x01,0x02,0x10,0x21,0x90,0x43,0x00,0x00, -0x08,0x00,0x0a,0xb6,0xa0,0x43,0x00,0x03,0x96,0x69,0x00,0x14,0x02,0xc0,0xb8,0x21, -0x24,0x0b,0x00,0x01,0x00,0x09,0x10,0xc0,0x00,0x49,0x18,0x21,0x00,0x03,0x40,0x80, -0x00,0x40,0x50,0x21,0x27,0x82,0x8f,0xf4,0x01,0x02,0x10,0x21,0x8c,0x43,0x00,0x18, -0x00,0x00,0x00,0x00,0x8c,0x65,0x00,0x08,0x8c,0x62,0x00,0x0c,0x8c,0x62,0x00,0x04, -0x00,0x05,0x24,0x42,0x00,0x05,0x1c,0x82,0x30,0x42,0x00,0x10,0x30,0x66,0x00,0x01, -0x10,0x40,0x00,0x0d,0x30,0x87,0x00,0x01,0x27,0x82,0x90,0x08,0x01,0x02,0x10,0x21, -0x80,0x43,0x00,0x00,0x00,0x00,0x58,0x21,0x00,0x03,0x11,0x00,0x00,0x43,0x10,0x23, -0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x23,0x00,0x02,0x10,0x80,0x27,0x83,0xb5,0x60, -0x00,0x43,0x10,0x21,0xa0,0x40,0x00,0x04,0x11,0x60,0x00,0x4f,0x00,0x00,0x00,0x00, -0x01,0x49,0x10,0x21,0x00,0x02,0x20,0x80,0x27,0x85,0x90,0x00,0x00,0x85,0x10,0x21, -0x80,0x43,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x42,0x01,0x49,0x10,0x21, -0x27,0x82,0x90,0x08,0x00,0x82,0x10,0x21,0x80,0x44,0x00,0x00,0x27,0x82,0xb5,0x68, -0x00,0x04,0x19,0x00,0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x23, -0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x90,0x45,0x00,0x05,0x27,0x84,0xb4,0x90, -0x00,0x64,0x18,0x21,0x90,0x63,0x00,0x00,0x10,0xa0,0x00,0x2c,0x2c,0x64,0x00,0x0c, -0x14,0x80,0x00,0x04,0x00,0x60,0x10,0x21,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21, -0x24,0x42,0x00,0x24,0x3c,0x01,0xb0,0x03,0xa0,0x22,0x00,0xb9,0x14,0x80,0x00,0x06, -0x00,0x60,0x28,0x21,0x00,0x07,0x10,0x40,0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00, -0x00,0x62,0x10,0x21,0x24,0x45,0x00,0x04,0x01,0x49,0x10,0x21,0x27,0x83,0x90,0x00, -0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0xa0,0x18,0x21,0xa0,0x45,0x00,0x03, -0xa0,0x45,0x00,0x00,0x8f,0xa4,0x00,0x18,0x24,0x02,0x00,0x08,0x10,0x82,0x00,0x0c, -0x00,0x60,0x28,0x21,0x24,0x02,0x00,0x01,0x02,0x60,0x20,0x21,0x0c,0x00,0x1f,0x8d, -0xaf,0xa2,0x00,0x10,0x8f,0xa3,0x00,0x18,0x30,0x54,0xff,0xff,0x92,0x62,0x00,0x16, -0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x25,0x08,0x00,0x0a,0x3b,0xa2,0x62,0x00,0x16, -0x02,0x60,0x20,0x21,0x0c,0x00,0x1f,0x3e,0xaf,0xa0,0x00,0x10,0x08,0x00,0x0b,0x2d, -0x00,0x00,0x00,0x00,0x08,0x00,0x0b,0x15,0x00,0x60,0x10,0x21,0x14,0x80,0xff,0xfd, -0x00,0x00,0x00,0x00,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21,0x08,0x00,0x0b,0x15, -0x24,0x42,0x00,0x04,0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x90,0x43,0x00,0x00, -0x08,0x00,0x0b,0x25,0xa0,0x43,0x00,0x03,0x27,0x85,0x90,0x00,0x08,0x00,0x0b,0x41, -0x01,0x49,0x10,0x21,0x3c,0x02,0x80,0x00,0x00,0x62,0x18,0x26,0x08,0x00,0x0a,0x76, -0x00,0xc2,0x30,0x26,0x12,0x00,0xff,0x2d,0x24,0x02,0x00,0x01,0x08,0x00,0x0a,0x7b, -0x24,0x11,0x00,0x02,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd0, -0x24,0x42,0x2d,0x44,0x34,0x63,0x00,0x20,0x3c,0x05,0xb0,0x05,0xaf,0xb3,0x00,0x24, -0xaf,0xb2,0x00,0x20,0xaf,0xb1,0x00,0x1c,0xaf,0xbf,0x00,0x28,0xaf,0xb0,0x00,0x18, -0xac,0x62,0x00,0x00,0x34,0xa5,0x02,0x42,0x90,0xa2,0x00,0x00,0x00,0x80,0x90,0x21, -0x24,0x11,0x00,0x10,0x30,0x53,0x00,0xff,0x24,0x02,0x00,0x10,0x12,0x22,0x00,0xcf, -0x00,0x00,0x18,0x21,0x24,0x02,0x00,0x11,0x12,0x22,0x00,0xc1,0x24,0x02,0x00,0x12, -0x12,0x22,0x00,0xb4,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0xad,0xae,0x43,0x00,0x40, -0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,0x8c,0x44,0x00,0x00,0x3c,0x03,0x00,0x02, -0x34,0x63,0x00,0xff,0x00,0x83,0x80,0x24,0x00,0x10,0x14,0x43,0x10,0x40,0x00,0x05, -0x00,0x00,0x00,0x00,0x8e,0x42,0x00,0x34,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x92, -0x00,0x00,0x00,0x00,0x93,0x83,0x8b,0x61,0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x02, -0x10,0x40,0x00,0x04,0x32,0x10,0x00,0xff,0x00,0x10,0x11,0xc3,0x14,0x40,0x00,0x86, -0x00,0x00,0x00,0x00,0x16,0x00,0x00,0x15,0x02,0x00,0x10,0x21,0x26,0x22,0x00,0x01, -0x30,0x51,0x00,0xff,0x2e,0x23,0x00,0x13,0x14,0x60,0xff,0xdb,0x24,0x03,0x00,0x02, -0x12,0x63,0x00,0x73,0x24,0x02,0x00,0x05,0x2a,0x62,0x00,0x03,0x10,0x40,0x00,0x58, -0x24,0x02,0x00,0x04,0x24,0x02,0x00,0x01,0x12,0x62,0x00,0x4b,0x02,0x40,0x20,0x21, -0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00, -0x30,0x70,0x00,0xff,0x12,0x00,0x00,0x06,0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x28, -0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30, -0x92,0x46,0x00,0x04,0x8e,0x43,0x00,0x24,0x24,0x02,0x00,0x07,0x02,0x40,0x20,0x21, -0x00,0x00,0x28,0x21,0x24,0x07,0x00,0x06,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xe6, -0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x24,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c, -0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xec,0x02,0x00,0x10,0x21, -0x92,0x46,0x00,0x05,0x8e,0x43,0x00,0x28,0x24,0x02,0x00,0x05,0x02,0x40,0x20,0x21, -0x24,0x05,0x00,0x01,0x24,0x07,0x00,0x04,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xe6, -0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x28,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c, -0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xdc,0x02,0x00,0x10,0x21, -0x92,0x46,0x00,0x06,0x8e,0x43,0x00,0x2c,0x24,0x02,0x00,0x03,0x02,0x40,0x20,0x21, -0x24,0x05,0x00,0x02,0x00,0x00,0x38,0x21,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xe6, -0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x2c,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c, -0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xcc,0x02,0x00,0x10,0x21, -0x92,0x46,0x00,0x07,0x8e,0x43,0x00,0x30,0x24,0x02,0x00,0x02,0x02,0x40,0x20,0x21, -0x24,0x05,0x00,0x03,0x24,0x07,0x00,0x01,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xe6, -0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x30,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c, -0x08,0x00,0x0b,0x97,0x30,0x42,0x00,0xff,0x92,0x46,0x00,0x04,0x8e,0x43,0x00,0x24, -0x24,0x02,0x00,0x07,0x00,0x00,0x28,0x21,0x24,0x07,0x00,0x06,0xaf,0xa2,0x00,0x10, -0x0c,0x00,0x09,0xe6,0xaf,0xa3,0x00,0x14,0x08,0x00,0x0b,0x90,0xae,0x42,0x00,0x24, -0x12,0x62,0x00,0x0d,0x24,0x02,0x00,0x03,0x24,0x02,0x00,0x08,0x16,0x62,0xff,0xa8, -0x02,0x40,0x20,0x21,0x92,0x46,0x00,0x07,0x8e,0x42,0x00,0x30,0x24,0x05,0x00,0x03, -0x24,0x07,0x00,0x01,0xaf,0xa3,0x00,0x10,0x0c,0x00,0x09,0xe6,0xaf,0xa2,0x00,0x14, -0x08,0x00,0x0b,0x90,0xae,0x42,0x00,0x30,0x92,0x46,0x00,0x06,0x8e,0x43,0x00,0x2c, -0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x02,0x00,0x00,0x38,0x21,0xaf,0xa2,0x00,0x10, -0x0c,0x00,0x09,0xe6,0xaf,0xa3,0x00,0x14,0x08,0x00,0x0b,0x90,0xae,0x42,0x00,0x2c, -0x92,0x46,0x00,0x05,0x8e,0x43,0x00,0x28,0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x01, -0x24,0x07,0x00,0x04,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xe6,0xaf,0xa3,0x00,0x14, -0x08,0x00,0x0b,0x90,0xae,0x42,0x00,0x28,0x0c,0x00,0x01,0x59,0x24,0x04,0x00,0x01, -0x08,0x00,0x0b,0x81,0x00,0x00,0x00,0x00,0x8f,0x84,0xb4,0x30,0xae,0x40,0x00,0x34, -0x94,0x85,0x00,0x14,0x0c,0x00,0x1b,0x84,0x00,0x00,0x00,0x00,0x93,0x83,0x8b,0x61, -0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x02,0x10,0x40,0xff,0x69,0x00,0x00,0x00,0x00, -0x0c,0x00,0x01,0x59,0x00,0x00,0x20,0x21,0x08,0x00,0x0b,0x79,0x00,0x00,0x00,0x00, -0x02,0x40,0x20,0x21,0x0c,0x00,0x09,0x5d,0x02,0x20,0x28,0x21,0x08,0x00,0x0b,0x6d, -0x3c,0x02,0xb0,0x05,0x8e,0x42,0x00,0x3c,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x4a, -0x00,0x00,0x00,0x00,0x8f,0x82,0xb4,0x38,0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a, -0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x2b,0x08,0x00,0x0b,0x6a,0xae,0x43,0x00,0x3c, -0x8e,0x42,0x00,0x38,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x3d,0x24,0x02,0x00,0x12, -0x8f,0x82,0xb4,0x34,0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a,0x00,0x00,0x00,0x00, -0x00,0x02,0x18,0x2b,0x08,0x00,0x0b,0x6a,0xae,0x43,0x00,0x38,0x8e,0x42,0x00,0x34, -0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x30,0x24,0x02,0x00,0x11,0x8f,0x82,0xb4,0x30, -0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x2b, -0x08,0x00,0x0b,0x6a,0xae,0x43,0x00,0x34,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, -0x27,0xbd,0xff,0xe0,0x34,0x63,0x00,0x20,0x24,0x42,0x30,0xf8,0x3c,0x08,0xb0,0x03, -0xaf,0xb1,0x00,0x14,0xac,0x62,0x00,0x00,0x35,0x08,0x01,0x00,0xaf,0xbf,0x00,0x18, -0xaf,0xb0,0x00,0x10,0x91,0x03,0x00,0x00,0x00,0xa0,0x48,0x21,0x24,0x11,0x00,0x0a, -0x2c,0xa5,0x00,0x04,0x24,0x02,0x00,0x10,0x00,0x45,0x88,0x0a,0x30,0x63,0x00,0x01, -0x00,0xc0,0x28,0x21,0x14,0x60,0x00,0x02,0x00,0x11,0x40,0x40,0x02,0x20,0x40,0x21, -0x84,0x83,0x00,0x0c,0x31,0x11,0x00,0xff,0x01,0x20,0x20,0x21,0x00,0x03,0x10,0xc0, -0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x8f,0xf8,0x00,0x43,0x10,0x21, -0x84,0x43,0x00,0x04,0x24,0x06,0x00,0x0e,0x10,0xe0,0x00,0x06,0x02,0x23,0x80,0x21, -0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08, -0x27,0xbd,0x00,0x20,0x0c,0x00,0x08,0xdf,0x00,0x00,0x00,0x00,0x02,0x11,0x18,0x21, -0x08,0x00,0x0c,0x60,0x00,0x62,0x80,0x21,0x27,0xbd,0xff,0xd0,0xaf,0xbf,0x00,0x28, -0xaf,0xb4,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0xaf,0xb5,0x00,0x24, -0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x84,0x82,0x00,0x0c,0x3c,0x06,0xb0,0x03, -0x34,0xc6,0x00,0x20,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80, -0x27,0x82,0x8f,0xf4,0x00,0x62,0x10,0x21,0x8c,0x55,0x00,0x18,0x3c,0x02,0x80,0x00, -0x24,0x42,0x31,0xa8,0xac,0xc2,0x00,0x00,0x8e,0xb0,0x00,0x08,0x27,0x82,0x8f,0xf8, -0x00,0x62,0x18,0x21,0x90,0x71,0x00,0x07,0x00,0x10,0x86,0x43,0x32,0x10,0x00,0x01, -0x00,0xa0,0x38,0x21,0x02,0x00,0x30,0x21,0x00,0xa0,0x98,0x21,0x02,0x20,0x28,0x21, -0x0c,0x00,0x0c,0x3e,0x00,0x80,0x90,0x21,0x02,0x20,0x20,0x21,0x02,0x00,0x28,0x21, -0x24,0x06,0x00,0x14,0x0c,0x00,0x08,0xdf,0x00,0x40,0xa0,0x21,0x86,0x43,0x00,0x0c, -0x3c,0x09,0xb0,0x09,0x3c,0x08,0xb0,0x09,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, -0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0x80,0x43,0x00,0x06, -0x3c,0x07,0xb0,0x09,0x3c,0x05,0xb0,0x09,0x28,0x62,0x00,0x00,0x24,0x64,0x00,0x03, -0x00,0x82,0x18,0x0b,0x00,0x03,0x18,0x83,0x3c,0x02,0xb0,0x09,0x00,0x03,0x18,0x80, -0x34,0x42,0x01,0x02,0x35,0x29,0x01,0x10,0x35,0x08,0x01,0x14,0x34,0xe7,0x01,0x20, -0x34,0xa5,0x01,0x24,0xa4,0x54,0x00,0x00,0x12,0x60,0x00,0x11,0x02,0xa3,0xa8,0x21, -0x8e,0xa2,0x00,0x0c,0x8e,0xa3,0x00,0x08,0x00,0x02,0x14,0x00,0x00,0x03,0x1c,0x02, -0x00,0x43,0x10,0x21,0xad,0x22,0x00,0x00,0x8e,0xa3,0x00,0x0c,0x00,0x00,0x00,0x00, -0x00,0x03,0x1c,0x02,0xa5,0x03,0x00,0x00,0x8f,0xbf,0x00,0x28,0x7b,0xb4,0x01,0x3c, -0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30, -0x8e,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,0xad,0x22,0x00,0x00,0x8e,0xa4,0x00,0x08, -0x00,0x00,0x00,0x00,0xa5,0x04,0x00,0x00,0x7a,0xa2,0x00,0x7c,0x00,0x00,0x00,0x00, -0x00,0x03,0x1c,0x00,0x00,0x02,0x14,0x02,0x00,0x62,0x18,0x21,0xac,0xe3,0x00,0x00, -0x8e,0xa2,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x02,0x14,0x02,0x08,0x00,0x0c,0xb2, -0xa4,0xa2,0x00,0x00,0x27,0xbd,0xff,0xe0,0xaf,0xb2,0x00,0x18,0xaf,0xb0,0x00,0x10, -0xaf,0xbf,0x00,0x1c,0xaf,0xb1,0x00,0x14,0x84,0x82,0x00,0x0c,0x00,0x80,0x90,0x21, -0x3c,0x05,0xb0,0x03,0x00,0x02,0x20,0xc0,0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80, -0x27,0x82,0x8f,0xf4,0x00,0x82,0x10,0x21,0x8c,0x51,0x00,0x18,0x3c,0x02,0x80,0x00, -0x34,0xa5,0x00,0x20,0x24,0x42,0x33,0x24,0x27,0x83,0x8f,0xf8,0xac,0xa2,0x00,0x00, -0x00,0x83,0x20,0x21,0x3c,0x02,0xb0,0x03,0x90,0x86,0x00,0x07,0x34,0x42,0x01,0x00, -0x8e,0x23,0x00,0x08,0x90,0x44,0x00,0x00,0x2c,0xc5,0x00,0x04,0x24,0x02,0x00,0x10, -0x24,0x10,0x00,0x0a,0x00,0x45,0x80,0x0a,0x00,0x03,0x1e,0x43,0x30,0x84,0x00,0x01, -0x30,0x65,0x00,0x01,0x14,0x80,0x00,0x02,0x00,0x10,0x10,0x40,0x02,0x00,0x10,0x21, -0x00,0xc0,0x20,0x21,0x24,0x06,0x00,0x20,0x0c,0x00,0x08,0xdf,0x30,0x50,0x00,0xff, -0x86,0x44,0x00,0x0c,0x27,0x85,0x90,0x00,0x3c,0x06,0xb0,0x09,0x00,0x04,0x18,0xc0, -0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x65,0x18,0x21,0x80,0x64,0x00,0x06, -0x00,0x50,0x10,0x21,0x34,0xc6,0x01,0x02,0x24,0x85,0x00,0x03,0x28,0x83,0x00,0x00, -0x00,0xa3,0x20,0x0b,0x00,0x04,0x20,0x83,0x00,0x04,0x20,0x80,0xa4,0xc2,0x00,0x00, -0x02,0x24,0x20,0x21,0x8c,0x83,0x00,0x04,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x10, -0xac,0x43,0x00,0x00,0x8c,0x86,0x00,0x08,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x14, -0xa4,0x46,0x00,0x00,0x8c,0x85,0x00,0x0c,0x8c,0x82,0x00,0x08,0x3c,0x06,0xb0,0x09, -0x00,0x05,0x2c,0x00,0x00,0x02,0x14,0x02,0x00,0xa2,0x28,0x21,0x34,0xc6,0x01,0x20, -0xac,0xc5,0x00,0x00,0x8c,0x83,0x00,0x0c,0x3c,0x05,0xb0,0x09,0x34,0xa5,0x01,0x24, -0x00,0x03,0x1c,0x02,0xa4,0xa3,0x00,0x00,0x92,0x42,0x00,0x0a,0x3c,0x03,0xb0,0x09, -0x34,0x63,0x01,0x30,0x00,0x02,0x13,0x00,0x24,0x42,0x00,0x04,0x30,0x42,0xff,0xff, -0xa4,0x62,0x00,0x00,0x86,0x44,0x00,0x0c,0x27,0x83,0x90,0x08,0x8f,0xbf,0x00,0x1c, -0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21, -0x94,0x44,0x00,0x02,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x3c,0x05,0xb0,0x09, -0x34,0xa5,0x01,0x32,0xa4,0xa4,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20, -0x27,0xbd,0xff,0xe0,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0xaf,0xb0,0x00,0x10, -0x34,0x42,0x00,0x20,0x00,0xa0,0x80,0x21,0x24,0x63,0x34,0xb0,0x00,0x05,0x2c,0x43, -0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x18,0xac,0x43,0x00,0x00,0x10,0xa0,0x00,0x05, -0x00,0x80,0x88,0x21,0x8c,0x82,0x00,0x34,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0xb6, -0x00,0x00,0x00,0x00,0x32,0x10,0x00,0xff,0x12,0x00,0x00,0x4c,0x00,0x00,0x10,0x21, -0x24,0x02,0x00,0x08,0x12,0x02,0x00,0xa3,0x2a,0x02,0x00,0x09,0x10,0x40,0x00,0x89, -0x24,0x02,0x00,0x40,0x24,0x04,0x00,0x02,0x12,0x04,0x00,0x79,0x2a,0x02,0x00,0x03, -0x10,0x40,0x00,0x69,0x24,0x02,0x00,0x04,0x24,0x02,0x00,0x01,0x12,0x02,0x00,0x5a, -0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x34,0x42,0x00,0x08,0x3c,0x03,0x80,0x00, -0xa2,0x20,0x00,0x4e,0xac,0x43,0x00,0x00,0x82,0x24,0x00,0x11,0x92,0x27,0x00,0x11, -0x10,0x80,0x00,0x4e,0x00,0x00,0x00,0x00,0x92,0x26,0x00,0x0a,0x24,0x02,0x00,0x12, -0x10,0x46,0x00,0x09,0x30,0xc2,0x00,0xff,0x27,0x83,0xb3,0xf0,0x00,0x02,0x10,0x80, -0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x83,0x00,0x14, -0x00,0x00,0x00,0x00,0xa6,0x23,0x00,0x0c,0x3c,0x02,0xb0,0x09,0x34,0x42,0x00,0x40, -0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x03,0xa2,0x23,0x00,0x10, -0x14,0x60,0x00,0x2b,0x30,0x65,0x00,0x01,0x30,0xc2,0x00,0xff,0x27,0x83,0xb3,0xf0, -0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x82,0x23,0x00,0x12, -0x90,0x82,0x00,0x16,0x00,0x00,0x00,0x00,0x00,0x02,0x11,0x42,0x30,0x42,0x00,0x01, -0x00,0x62,0x18,0x21,0x00,0x03,0x26,0x00,0x14,0x80,0x00,0x18,0xa2,0x23,0x00,0x12, -0x00,0x07,0x16,0x00,0x14,0x40,0x00,0x11,0x24,0x02,0x00,0x01,0x96,0x23,0x00,0x0c, -0x27,0x84,0x90,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, -0x00,0x44,0x10,0x21,0x80,0x45,0x00,0x06,0x00,0x03,0x1a,0x00,0x3c,0x02,0xb0,0x00, -0x00,0x65,0x18,0x21,0x00,0x62,0x18,0x21,0x90,0x64,0x00,0x00,0x90,0x62,0x00,0x04, -0xa2,0x20,0x00,0x15,0xa3,0x80,0x8b,0xc4,0x24,0x02,0x00,0x01,0x8f,0xbf,0x00,0x18, -0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x0c,0x00,0x0c,0xc9, -0x02,0x20,0x20,0x21,0x92,0x27,0x00,0x11,0x08,0x00,0x0d,0x79,0x00,0x07,0x16,0x00, -0x0c,0x00,0x0c,0x6a,0x02,0x20,0x20,0x21,0x86,0x23,0x00,0x0c,0x27,0x84,0x8f,0xf8, -0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x44,0x20,0x21, -0x90,0x85,0x00,0x07,0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0xa2,0x25,0x00,0x13, -0x90,0x83,0x00,0x07,0x08,0x00,0x0d,0x91,0xa0,0x43,0x00,0x02,0x92,0x26,0x00,0x0a, -0x08,0x00,0x0d,0x5a,0x30,0xc2,0x00,0xff,0x8e,0x22,0x00,0x24,0x00,0x00,0x00,0x00, -0x10,0x50,0x00,0x07,0xa2,0x20,0x00,0x08,0x24,0x02,0x00,0x07,0xa2,0x22,0x00,0x0a, -0x92,0x22,0x00,0x27,0xae,0x20,0x00,0x24,0x08,0x00,0x0d,0x4d,0xa2,0x22,0x00,0x04, -0x08,0x00,0x0d,0xab,0x24,0x02,0x00,0x06,0x16,0x02,0xff,0x9b,0x3c,0x02,0xb0,0x05, -0x8e,0x23,0x00,0x2c,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x07,0xa2,0x24,0x00,0x08, -0x24,0x02,0x00,0x03,0xa2,0x22,0x00,0x0a,0x92,0x22,0x00,0x2f,0xae,0x20,0x00,0x2c, -0x08,0x00,0x0d,0x4d,0xa2,0x22,0x00,0x06,0x08,0x00,0x0d,0xba,0xa2,0x20,0x00,0x0a, -0x8e,0x22,0x00,0x28,0x24,0x03,0x00,0x01,0x24,0x04,0x00,0x01,0x10,0x44,0x00,0x07, -0xa2,0x23,0x00,0x08,0x24,0x02,0x00,0x05,0xa2,0x22,0x00,0x0a,0x92,0x22,0x00,0x2b, -0xae,0x20,0x00,0x28,0x08,0x00,0x0d,0x4d,0xa2,0x22,0x00,0x05,0x08,0x00,0x0d,0xc6, -0x24,0x02,0x00,0x04,0x12,0x02,0x00,0x12,0x2a,0x02,0x00,0x41,0x10,0x40,0x00,0x09, -0x24,0x02,0x00,0x80,0x24,0x02,0x00,0x20,0x16,0x02,0xff,0x7b,0x3c,0x02,0xb0,0x05, -0x24,0x02,0x00,0x12,0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x0d,0x4d, -0xae,0x20,0x00,0x3c,0x16,0x02,0xff,0x74,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x10, -0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x0d,0x4d,0xae,0x20,0x00,0x34, -0x24,0x02,0x00,0x11,0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x0d,0x4d, -0xae,0x20,0x00,0x38,0x8e,0x24,0x00,0x30,0x24,0x02,0x00,0x03,0x24,0x03,0x00,0x01, -0x10,0x83,0x00,0x07,0xa2,0x22,0x00,0x08,0x24,0x02,0x00,0x02,0xa2,0x22,0x00,0x0a, -0x92,0x22,0x00,0x33,0xae,0x20,0x00,0x30,0x08,0x00,0x0d,0x4d,0xa2,0x22,0x00,0x07, -0x08,0x00,0x0d,0xec,0xa2,0x24,0x00,0x0a,0x8f,0x84,0xb4,0x30,0xae,0x20,0x00,0x34, -0x94,0x85,0x00,0x14,0x0c,0x00,0x1b,0x84,0x32,0x10,0x00,0xff,0x08,0x00,0x0d,0x3e, -0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x37,0xe4, -0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,0x80,0xa2,0x00,0x15,0x3c,0x06,0xb0,0x05, -0x10,0x40,0x00,0x0a,0x34,0xc6,0x02,0x54,0x83,0x83,0x8b,0xc4,0x00,0x00,0x00,0x00, -0xac,0x83,0x00,0x24,0x8c,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x42, -0x30,0x42,0x00,0x01,0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x28,0x8c,0x82,0x00,0x2c, -0x3c,0x06,0xb0,0x05,0x34,0xc6,0x04,0x50,0x00,0x02,0x18,0x43,0x30,0x63,0x00,0x01, -0x10,0x40,0x00,0x04,0x30,0x45,0x00,0x01,0xac,0x83,0x00,0x28,0x03,0xe0,0x00,0x08, -0xac,0x85,0x00,0x24,0x90,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff, -0x30,0x43,0x00,0x02,0x30,0x42,0x00,0x01,0xac,0x83,0x00,0x28,0x03,0xe0,0x00,0x08, -0xac,0x82,0x00,0x24,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd8, -0x34,0x63,0x00,0x20,0x24,0x42,0x38,0x74,0xac,0x62,0x00,0x00,0xaf,0xb1,0x00,0x1c, -0xaf,0xbf,0x00,0x20,0xaf,0xb0,0x00,0x18,0x90,0xa6,0x00,0x0a,0x27,0x83,0xb3,0xf0, -0x00,0xa0,0x88,0x21,0x00,0x06,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x50,0x00,0x00, -0x80,0xa5,0x00,0x11,0x92,0x03,0x00,0x12,0x10,0xa0,0x00,0x04,0xa2,0x20,0x00,0x15, -0x24,0x02,0x00,0x12,0x10,0xc2,0x00,0xda,0x00,0x00,0x00,0x00,0x82,0x22,0x00,0x12, -0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x67,0x00,0x00,0x00,0x00,0xa2,0x20,0x00,0x12, -0xa2,0x00,0x00,0x19,0x86,0x23,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0, -0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21, -0xa0,0x40,0x00,0x00,0x92,0x03,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0xdf, -0xa2,0x03,0x00,0x16,0x82,0x02,0x00,0x12,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x20, -0x00,0x00,0x00,0x00,0x92,0x23,0x00,0x08,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x45, -0x24,0x02,0x00,0x01,0xa2,0x20,0x00,0x04,0x92,0x08,0x00,0x04,0x00,0x00,0x00,0x00, -0x15,0x00,0x00,0x1e,0x24,0x02,0x00,0x01,0x92,0x07,0x00,0x0a,0xa2,0x02,0x00,0x17, -0x92,0x02,0x00,0x16,0x30,0xe3,0x00,0xff,0x30,0x42,0x00,0xe4,0x10,0x60,0x00,0x03, -0xa2,0x02,0x00,0x16,0x34,0x42,0x00,0x01,0xa2,0x02,0x00,0x16,0x11,0x00,0x00,0x05, -0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02, -0xa2,0x02,0x00,0x16,0x92,0x02,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x08, -0x00,0x00,0x00,0x00,0x96,0x02,0x00,0x06,0x00,0x00,0x00,0x00,0xa6,0x02,0x00,0x14, -0x8f,0xbf,0x00,0x20,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28, -0x96,0x02,0x00,0x00,0x08,0x00,0x0e,0x68,0xa6,0x02,0x00,0x14,0x92,0x07,0x00,0x0a, -0x00,0x00,0x00,0x00,0x14,0xe0,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x0e,0x54, -0xa2,0x00,0x00,0x17,0x96,0x04,0x00,0x00,0x96,0x05,0x00,0x06,0x27,0x86,0x8f,0xf0, -0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21, -0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21, -0x8c,0x66,0x00,0x08,0x8c,0x45,0x00,0x08,0x3c,0x03,0x80,0x00,0x00,0xc3,0x20,0x24, -0x10,0x80,0x00,0x08,0x00,0xa3,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21, -0x10,0x80,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0xa6,0x18,0x2b,0x08,0x00,0x0e,0x54, -0xa2,0x03,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0xa6,0x18,0x2b,0x08,0x00,0x0e,0x88, -0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x05, -0x24,0x02,0x00,0x03,0x14,0x62,0xff,0xb8,0x00,0x00,0x00,0x00,0x08,0x00,0x0e,0x4e, -0xa2,0x20,0x00,0x07,0x08,0x00,0x0e,0x4e,0xa2,0x20,0x00,0x06,0x08,0x00,0x0e,0x4e, -0xa2,0x20,0x00,0x05,0x82,0x22,0x00,0x10,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x69, -0x2c,0x62,0x00,0x02,0x10,0x40,0x00,0x49,0x3c,0x02,0xb0,0x09,0x92,0x25,0x00,0x08, -0x00,0x00,0x00,0x00,0x30,0xa6,0x00,0xff,0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x3b, -0x2c,0xc2,0x00,0x10,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00, -0x24,0x02,0x00,0x01,0x00,0xc2,0x10,0x04,0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24, -0xa0,0x83,0x00,0x00,0x86,0x23,0x00,0x0c,0x96,0x26,0x00,0x0c,0x00,0x03,0x10,0xc0, -0x00,0x43,0x10,0x21,0x00,0x02,0x28,0x80,0x27,0x83,0x8f,0xf4,0x00,0xa3,0x18,0x21, -0x8c,0x64,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04,0x00,0x00,0x00,0x00, -0x30,0x42,0x00,0x10,0x10,0x40,0x00,0x18,0x24,0x07,0x00,0x01,0x93,0x82,0x8b,0x61, -0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x0a,0x24,0x05,0x00,0x24, -0x00,0x06,0x2c,0x00,0x00,0x05,0x2c,0x03,0x0c,0x00,0x1b,0x84,0x02,0x00,0x20,0x21, -0x92,0x02,0x00,0x16,0xa2,0x00,0x00,0x12,0x30,0x42,0x00,0xe7,0x08,0x00,0x0e,0x45, -0xa2,0x02,0x00,0x16,0xf0,0xc5,0x00,0x06,0x00,0x00,0x28,0x12,0x27,0x82,0x8f,0xf0, -0x00,0xa2,0x28,0x21,0x0c,0x00,0x01,0x4b,0x3c,0x04,0x00,0x80,0x96,0x26,0x00,0x0c, -0x08,0x00,0x0e,0xc5,0x00,0x06,0x2c,0x00,0x27,0x83,0x90,0x00,0x27,0x82,0x90,0x08, -0x00,0xa2,0x10,0x21,0x00,0xa3,0x18,0x21,0x90,0x44,0x00,0x00,0x90,0x65,0x00,0x05, -0x93,0x82,0x80,0x10,0x00,0x00,0x30,0x21,0x0c,0x00,0x21,0xf5,0xaf,0xa2,0x00,0x10, -0x96,0x26,0x00,0x0c,0x08,0x00,0x0e,0xbf,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xcd, -0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x30,0xa5,0x00,0x0f, -0x24,0x02,0x00,0x80,0x08,0x00,0x0e,0xae,0x00,0xa2,0x10,0x07,0x86,0x26,0x00,0x0c, -0x3c,0x03,0xb0,0x09,0x34,0x42,0x01,0x72,0x34,0x63,0x01,0x78,0x94,0x47,0x00,0x00, -0x8c,0x65,0x00,0x00,0x00,0x06,0x10,0xc0,0x00,0x46,0x10,0x21,0x3c,0x04,0xb0,0x09, -0xae,0x25,0x00,0x1c,0x34,0x84,0x01,0x7c,0x27,0x83,0x8f,0xf4,0x00,0x02,0x10,0x80, -0x8c,0x85,0x00,0x00,0x00,0x43,0x10,0x21,0x8c,0x43,0x00,0x18,0xae,0x25,0x00,0x20, -0xa6,0x27,0x00,0x18,0x8c,0x66,0x00,0x08,0x02,0x20,0x20,0x21,0x0c,0x00,0x0f,0x15, -0x00,0x00,0x28,0x21,0x86,0x25,0x00,0x18,0x8e,0x26,0x00,0x1c,0x8e,0x27,0x00,0x20, -0x02,0x20,0x20,0x21,0x0c,0x00,0x1c,0x86,0xaf,0xa2,0x00,0x10,0x08,0x00,0x0e,0x45, -0xa2,0x02,0x00,0x12,0x92,0x22,0x00,0x08,0x08,0x00,0x0e,0x45,0xa2,0x22,0x00,0x09, -0xa2,0x20,0x00,0x11,0x80,0x82,0x00,0x50,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x03, -0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0,0xac,0x40,0x00,0x00,0x08,0x00,0x0e,0x45, -0xa0,0x80,0x00,0x50,0x94,0x8a,0x00,0x0c,0x24,0x03,0x00,0x24,0x00,0x80,0x70,0x21, -0x3c,0x02,0x80,0x00,0x3c,0x04,0xb0,0x03,0x24,0x42,0x3c,0x54,0xf1,0x43,0x00,0x06, -0x34,0x84,0x00,0x20,0x00,0x00,0x18,0x12,0x00,0xa0,0x68,0x21,0xac,0x82,0x00,0x00, -0x27,0x85,0x90,0x00,0x27,0x82,0x8f,0xff,0x27,0xbd,0xff,0xf8,0x00,0x62,0x60,0x21, -0x00,0x65,0x58,0x21,0x00,0x00,0xc0,0x21,0x11,0xa0,0x00,0xcc,0x00,0x00,0x78,0x21, -0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, -0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x91,0x87,0x00,0x00,0x80,0x48,0x00,0x04, -0x03,0xa0,0x60,0x21,0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0, -0x00,0x43,0x10,0x21,0x00,0x02,0x48,0x80,0x27,0x83,0x8f,0xf4,0xa3,0xa7,0x00,0x00, -0x01,0x23,0x18,0x21,0x8c,0x64,0x00,0x18,0x25,0x02,0xff,0xff,0x00,0x48,0x40,0x0b, -0x8c,0x83,0x00,0x04,0x2d,0x05,0x00,0x07,0x24,0x02,0x00,0x06,0x30,0x63,0x00,0x08, -0x14,0x60,0x00,0x35,0x00,0x45,0x40,0x0a,0x93,0xa7,0x00,0x00,0x27,0x82,0x90,0x08, -0x01,0x22,0x10,0x21,0x30,0xe3,0x00,0xf0,0x38,0x63,0x00,0x50,0x30,0xe5,0x00,0xff, -0x00,0x05,0x20,0x2b,0x00,0x03,0x18,0x2b,0x00,0x64,0x18,0x24,0x90,0x49,0x00,0x00, -0x10,0x60,0x00,0x16,0x30,0xe4,0x00,0x0f,0x24,0x02,0x00,0x04,0x10,0xa2,0x00,0x9d, -0x00,0x00,0x00,0x00,0x11,0xa0,0x00,0x3a,0x2c,0xa2,0x00,0x0c,0x10,0x40,0x00,0x02, -0x24,0x84,0x00,0x0c,0x00,0xe0,0x20,0x21,0x30,0x84,0x00,0xff,0x00,0x04,0x10,0x40, -0x27,0x83,0xbb,0x0c,0x00,0x44,0x10,0x21,0x00,0x43,0x10,0x21,0x90,0x47,0x00,0x00, -0x00,0x00,0x00,0x00,0x2c,0xe3,0x00,0x0c,0xa3,0xa7,0x00,0x00,0x10,0x60,0x00,0x02, -0x24,0xe2,0x00,0x04,0x00,0xe0,0x10,0x21,0xa3,0xa2,0x00,0x00,0x91,0x65,0x00,0x00, -0x91,0x82,0x00,0x00,0x30,0xa3,0x00,0xff,0x00,0x62,0x10,0x2b,0x10,0x40,0x00,0x0e, -0x2c,0x62,0x00,0x0c,0x14,0x40,0x00,0x03,0x00,0x60,0x20,0x21,0x30,0xa2,0x00,0x0f, -0x24,0x44,0x00,0x0c,0x00,0x04,0x10,0x40,0x00,0x44,0x20,0x21,0x27,0x83,0xbb,0x0c, -0x00,0x83,0x18,0x21,0x90,0x62,0x00,0x02,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x05, -0x00,0x09,0x11,0x00,0xa1,0x85,0x00,0x00,0x93,0xa2,0x00,0x00,0x03,0xe0,0x00,0x08, -0x27,0xbd,0x00,0x08,0x00,0x49,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x23, -0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x27,0x83,0xb4,0x98,0x00,0x43,0x10,0x21, -0x90,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x83,0x00,0x0c,0x14,0x60,0x00,0x06, -0x00,0x80,0x10,0x21,0x00,0x18,0x10,0x40,0x00,0x4f,0x10,0x21,0x00,0x02,0x11,0x00, -0x00,0x82,0x10,0x21,0x24,0x42,0x00,0x04,0x08,0x00,0x0f,0x76,0xa1,0x82,0x00,0x00, -0x8f,0x8d,0x81,0x5c,0x00,0x00,0x00,0x00,0x01,0xa8,0x10,0x21,0x90,0x43,0x00,0x00, -0x00,0x00,0x00,0x00,0x10,0x60,0xff,0xd1,0x00,0x00,0x28,0x21,0x00,0x06,0x74,0x82, -0x30,0xe2,0x00,0xff,0x2c,0x42,0x00,0x0c,0x14,0x40,0x00,0x03,0x00,0xe0,0x10,0x21, -0x30,0xe2,0x00,0x0f,0x24,0x42,0x00,0x0c,0x30,0x44,0x00,0xff,0xa3,0xa2,0x00,0x00, -0x24,0x02,0x00,0x0c,0x10,0x82,0x00,0x0d,0x00,0x09,0x11,0x00,0x00,0x49,0x10,0x23, -0x00,0x02,0x10,0x80,0x00,0x04,0x18,0x40,0x00,0x49,0x10,0x23,0x00,0x64,0x18,0x21, -0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x27,0x84,0xb4,0x98,0x00,0x44,0x10,0x21, -0x90,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0xa3,0xa7,0x00,0x00,0x00,0x0a,0x1c,0x00, -0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, -0x27,0x83,0x8f,0xf4,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x00,0x00,0x00, -0x8c,0x83,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10,0x14,0x60,0x00,0x33, -0x00,0x06,0x14,0x42,0x00,0x09,0x11,0x00,0x00,0x49,0x10,0x23,0x00,0x02,0x10,0x80, -0x00,0x49,0x10,0x23,0x27,0x83,0xb5,0x68,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21, -0x90,0x44,0x00,0x04,0x90,0x43,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x64,0xc0,0x24, -0x93,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0xe2,0x00,0x0f,0x10,0x40,0x00,0x0f, -0x31,0xcf,0x00,0x01,0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0, -0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x84,0x8f,0xf0,0x00,0x44,0x10,0x21, -0x84,0x43,0x00,0x06,0x00,0x00,0x00,0x00,0x28,0x63,0x06,0x41,0x14,0x60,0x00,0x04, -0x30,0xe2,0x00,0xff,0x24,0x07,0x00,0x0f,0xa3,0xa7,0x00,0x00,0x30,0xe2,0x00,0xff, -0x2c,0x42,0x00,0x0c,0x14,0x40,0x00,0x06,0x00,0xe0,0x10,0x21,0x00,0x18,0x10,0x40, -0x00,0x4f,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0x47,0x10,0x21,0x24,0x42,0x00,0x04, -0xa3,0xa2,0x00,0x00,0x00,0x40,0x38,0x21,0x01,0xa8,0x10,0x21,0x90,0x43,0x00,0x00, -0x24,0xa4,0x00,0x01,0x30,0x85,0xff,0xff,0x00,0xa3,0x18,0x2b,0x14,0x60,0xff,0xad, -0x30,0xe2,0x00,0xff,0x08,0x00,0x0f,0x63,0x00,0x00,0x00,0x00,0x08,0x00,0x0f,0xc4, -0x30,0x58,0x00,0x01,0x81,0xc2,0x00,0x48,0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x73, -0x00,0x00,0x00,0x00,0x08,0x00,0x0f,0x51,0x00,0x00,0x00,0x00,0x00,0x0a,0x1c,0x00, -0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, -0x00,0x45,0x10,0x21,0x80,0x48,0x00,0x05,0x91,0x67,0x00,0x00,0x08,0x00,0x0f,0x31, -0x03,0xa0,0x58,0x21,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20, -0x24,0x42,0x3f,0xf4,0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00,0x27,0xbd,0xff,0xc0, -0xaf,0xb7,0x00,0x34,0xaf,0xb6,0x00,0x30,0xaf,0xb5,0x00,0x2c,0xaf,0xb4,0x00,0x28, -0xaf,0xb3,0x00,0x24,0xaf,0xb2,0x00,0x20,0xaf,0xbf,0x00,0x3c,0xaf,0xbe,0x00,0x38, -0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,0x84,0x82,0x00,0x0c,0x27,0x93,0x8f,0xf4, -0x3c,0x05,0xb0,0x03,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80, -0x00,0x73,0x10,0x21,0x8c,0x5e,0x00,0x18,0x3c,0x02,0x80,0x00,0x34,0xa5,0x00,0x20, -0x24,0x42,0x40,0x0c,0xac,0xa2,0x00,0x00,0x8f,0xd0,0x00,0x08,0x27,0x95,0x90,0x00, -0x00,0x75,0x18,0x21,0x00,0x00,0x28,0x21,0x02,0x00,0x30,0x21,0x90,0x71,0x00,0x00, -0x0c,0x00,0x0f,0x15,0x00,0x80,0xb0,0x21,0x00,0x40,0x90,0x21,0x00,0x10,0x14,0x42, -0x30,0x54,0x00,0x01,0x02,0x40,0x20,0x21,0x00,0x10,0x14,0x82,0x02,0x80,0x28,0x21, -0x12,0x51,0x00,0x23,0x00,0x10,0xbf,0xc2,0x86,0xc3,0x00,0x0c,0x30,0x50,0x00,0x01, -0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x55,0x10,0x21, -0xa0,0x52,0x00,0x00,0x86,0xc3,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0, -0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x53,0x30,0x21,0x8c,0xc7,0x00,0x18, -0x27,0x83,0x8f,0xf0,0x00,0x43,0x10,0x21,0x8c,0xe3,0x00,0x04,0x84,0x46,0x00,0x06, -0x00,0x03,0x19,0x42,0x0c,0x00,0x08,0xdf,0x30,0x73,0x00,0x01,0x00,0x40,0x88,0x21, -0x02,0x40,0x20,0x21,0x02,0x80,0x28,0x21,0x16,0xe0,0x00,0x10,0x02,0x00,0x30,0x21, -0x86,0xc2,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21, -0x00,0x03,0x18,0x80,0x27,0x82,0x8f,0xf8,0x00,0x62,0x18,0x21,0xa4,0x71,0x00,0x04, -0x7b,0xbe,0x01,0xfc,0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c, -0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,0x86,0xc3,0x00,0x0c, -0xaf,0xb3,0x00,0x10,0xaf,0xa0,0x00,0x14,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, -0x00,0x02,0x10,0x80,0x00,0x55,0x10,0x21,0x80,0x47,0x00,0x06,0x00,0x00,0x00,0x00, -0x24,0xe7,0x00,0x02,0x00,0x07,0x17,0xc2,0x00,0xe2,0x38,0x21,0x00,0x07,0x38,0x43, -0x00,0x07,0x38,0x40,0x0c,0x00,0x09,0x06,0x03,0xc7,0x38,0x21,0x08,0x00,0x10,0x44, -0x02,0x22,0x88,0x21,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd0, -0x34,0x63,0x00,0x20,0x24,0x42,0x41,0x94,0xaf,0xb2,0x00,0x20,0xac,0x62,0x00,0x00, -0xaf,0xbf,0x00,0x28,0xaf,0xb3,0x00,0x24,0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18, -0x3c,0x02,0xb0,0x03,0x90,0x83,0x00,0x0a,0x34,0x42,0x01,0x04,0x94,0x45,0x00,0x00, -0x00,0x03,0x18,0x80,0x27,0x82,0xb3,0xf0,0x00,0x62,0x18,0x21,0x30,0xa6,0xff,0xff, -0x8c,0x71,0x00,0x00,0x80,0x85,0x00,0x12,0x30,0xc9,0x00,0xff,0x00,0x06,0x32,0x02, -0xa4,0x86,0x00,0x44,0xa4,0x89,0x00,0x46,0x82,0x22,0x00,0x12,0x00,0x80,0x90,0x21, -0x10,0xa0,0x00,0x1b,0xa0,0x80,0x00,0x15,0x00,0xc5,0x10,0x2a,0x10,0x40,0x00,0x14, -0x00,0x00,0x00,0x00,0xa2,0x20,0x00,0x19,0x84,0x83,0x00,0x0c,0x00,0x00,0x00,0x00, -0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10, -0x00,0x43,0x10,0x21,0xa0,0x40,0x00,0x00,0xa0,0x80,0x00,0x12,0x92,0x22,0x00,0x16, -0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xdf,0xa2,0x22,0x00,0x16,0x8f,0xbf,0x00,0x28, -0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30, -0x0c,0x00,0x0f,0xfd,0x00,0x00,0x00,0x00,0x08,0x00,0x10,0x93,0x00,0x00,0x00,0x00, -0x28,0x42,0x00,0x02,0x10,0x40,0x01,0x76,0x00,0x00,0x28,0x21,0x94,0x87,0x00,0x0c, -0x00,0x00,0x00,0x00,0x00,0xe0,0x10,0x21,0x00,0x02,0x14,0x00,0x00,0x02,0x14,0x03, -0x00,0x07,0x24,0x00,0x00,0x04,0x24,0x03,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21, -0x00,0x04,0x28,0xc0,0x00,0xa4,0x28,0x21,0x27,0x82,0x90,0x10,0x00,0x03,0x18,0x80, -0x00,0x62,0x18,0x21,0x00,0x05,0x28,0x80,0x27,0x82,0x8f,0xf8,0x00,0xa2,0x10,0x21, -0x8c,0x68,0x00,0x00,0x80,0x44,0x00,0x06,0x27,0x82,0x90,0x00,0x00,0x08,0x1d,0x02, -0x00,0xa2,0x28,0x21,0x38,0x84,0x00,0x00,0x30,0x63,0x00,0x01,0x01,0x24,0x30,0x0b, -0x80,0xaa,0x00,0x04,0x80,0xa9,0x00,0x05,0x10,0x60,0x00,0x02,0x00,0x08,0x14,0x02, -0x30,0x46,0x00,0x0f,0x15,0x20,0x00,0x28,0x01,0x49,0x10,0x21,0x15,0x40,0x00,0x11, -0x30,0xe3,0xff,0xff,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa8,0x00,0xff, -0x2d,0x02,0x00,0x04,0x10,0x40,0x01,0x46,0x2d,0x02,0x00,0x10,0x3c,0x04,0xb0,0x05, -0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,0x01,0x02,0x10,0x04, -0x00,0x62,0x18,0x25,0xa0,0x83,0x00,0x00,0x96,0x47,0x00,0x0c,0x00,0x00,0x00,0x00, -0x30,0xe3,0xff,0xff,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x27,0x84,0x90,0x00, -0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x80,0x45,0x00,0x06,0x00,0x03,0x1a,0x00, -0x3c,0x04,0xb0,0x00,0x00,0x65,0x18,0x21,0x00,0x64,0x20,0x21,0x94,0x82,0x00,0x00, -0x82,0x43,0x00,0x10,0x00,0x02,0x14,0x00,0x14,0x60,0x00,0x06,0x00,0x02,0x3c,0x03, -0x30,0xe2,0x00,0x04,0x14,0x40,0x00,0x04,0x01,0x49,0x10,0x21,0x34,0xe2,0x08,0x00, -0xa4,0x82,0x00,0x00,0x01,0x49,0x10,0x21,0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03, -0x00,0x46,0x10,0x2a,0x10,0x40,0x00,0x7c,0x00,0x00,0x00,0x00,0x82,0x42,0x00,0x10, -0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,0x86,0x43,0x00,0x0c, -0x25,0x44,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, -0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0xa0,0x44,0x00,0x04,0x92,0x23,0x00,0x16, -0x02,0x40,0x20,0x21,0x30,0x63,0x00,0xfb,0x08,0x00,0x10,0x98,0xa2,0x23,0x00,0x16, -0x86,0x43,0x00,0x0c,0x25,0x24,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, -0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0xa0,0x44,0x00,0x05, -0x86,0x45,0x00,0x0c,0x0c,0x00,0x1f,0x08,0x02,0x20,0x20,0x21,0x10,0x40,0x00,0x5a, -0x00,0x00,0x00,0x00,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa6,0x00,0xff, -0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x4c,0x2c,0xc2,0x00,0x10,0x3c,0x04,0xb0,0x05, -0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,0x00,0xc2,0x10,0x04, -0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24,0xa0,0x83,0x00,0x00,0x92,0x45,0x00,0x08, -0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,0x14,0xa0,0x00,0x33,0x24,0x02,0x00,0x01, -0xa2,0x40,0x00,0x04,0x92,0x22,0x00,0x04,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x0c, -0x24,0x02,0x00,0x01,0xa2,0x22,0x00,0x17,0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00, -0x10,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0x96,0x22,0x00,0x06,0x08,0x00,0x10,0x93, -0xa6,0x22,0x00,0x14,0x96,0x22,0x00,0x00,0x08,0x00,0x10,0x93,0xa6,0x22,0x00,0x14, -0x92,0x22,0x00,0x0a,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,0x00,0x00,0x00,0x00, -0x08,0x00,0x11,0x22,0xa2,0x20,0x00,0x17,0x96,0x24,0x00,0x00,0x96,0x25,0x00,0x06, -0x27,0x86,0x8f,0xf0,0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0, -0x00,0x45,0x10,0x21,0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80, -0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08,0x8c,0x44,0x00,0x08,0x3c,0x03,0x80,0x00, -0x00,0xa3,0x30,0x24,0x10,0xc0,0x00,0x08,0x00,0x83,0x10,0x24,0x10,0x40,0x00,0x04, -0x00,0x00,0x18,0x21,0x10,0xc0,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b, -0x08,0x00,0x11,0x22,0xa2,0x23,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b, -0x08,0x00,0x11,0x45,0x00,0x00,0x00,0x00,0x10,0xa2,0x00,0x09,0x24,0x02,0x00,0x02, -0x10,0xa2,0x00,0x05,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xca,0x00,0x00,0x00,0x00, -0x08,0x00,0x11,0x1d,0xa2,0x40,0x00,0x07,0x08,0x00,0x11,0x1d,0xa2,0x40,0x00,0x06, -0x08,0x00,0x11,0x1d,0xa2,0x40,0x00,0x05,0x14,0x40,0xff,0xbe,0x3c,0x04,0xb0,0x05, -0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80, -0x08,0x00,0x11,0x14,0x00,0xa2,0x10,0x07,0x0c,0x00,0x10,0x03,0x02,0x40,0x20,0x21, -0x08,0x00,0x10,0x93,0x00,0x00,0x00,0x00,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00, -0x30,0xa6,0x00,0xff,0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x99,0x2c,0xc2,0x00,0x10, -0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01, -0x00,0xc2,0x10,0x04,0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24,0xa0,0x83,0x00,0x00, -0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,0x14,0xa0,0x00,0x80, -0x24,0x02,0x00,0x01,0xa2,0x40,0x00,0x04,0x86,0x43,0x00,0x0c,0x27,0x93,0x8f,0xf4, -0x96,0x47,0x00,0x0c,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x28,0x80, -0x00,0xb3,0x18,0x21,0x8c,0x64,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04, -0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x10,0x10,0x40,0x00,0x64,0x00,0x00,0x30,0x21, -0x00,0x07,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, -0x00,0x02,0x10,0x80,0x00,0x53,0x10,0x21,0x8c,0x43,0x00,0x18,0x93,0x82,0x8b,0x61, -0x8c,0x64,0x00,0x04,0x30,0x42,0x00,0x01,0x00,0x04,0x21,0x42,0x14,0x40,0x00,0x4d, -0x30,0x90,0x00,0x01,0x00,0x07,0x2c,0x00,0x00,0x05,0x2c,0x03,0x0c,0x00,0x1b,0x84, -0x02,0x20,0x20,0x21,0x96,0x26,0x00,0x06,0x12,0x00,0x00,0x14,0x30,0xc5,0xff,0xff, -0x02,0x60,0x90,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,0x00,0x02,0x10,0x80, -0x00,0x52,0x18,0x21,0x92,0x22,0x00,0x0a,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0b, -0x02,0x20,0x20,0x21,0x8c,0x63,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x62,0x00,0x04, -0x00,0x00,0x00,0x00,0x00,0x02,0x11,0x42,0x0c,0x00,0x1b,0x84,0x30,0x50,0x00,0x01, -0x96,0x26,0x00,0x06,0x16,0x00,0xff,0xef,0x30,0xc5,0xff,0xff,0x92,0x22,0x00,0x04, -0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x0d,0x24,0x02,0x00,0x01,0xa2,0x22,0x00,0x17, -0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x05,0x00,0x00,0x00,0x00, -0xa6,0x26,0x00,0x14,0x92,0x22,0x00,0x16,0x08,0x00,0x10,0x92,0x30,0x42,0x00,0xc3, -0x96,0x22,0x00,0x00,0x08,0x00,0x11,0xb9,0xa6,0x22,0x00,0x14,0x92,0x22,0x00,0x0a, -0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x11,0xb4, -0xa2,0x20,0x00,0x17,0x96,0x24,0x00,0x00,0x30,0xc5,0xff,0xff,0x00,0x05,0x18,0xc0, -0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x65,0x18,0x21,0x27,0x84,0x8f,0xf0, -0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x00,0x03,0x18,0x80,0x8c,0x45,0x00,0x08, -0x00,0x64,0x18,0x21,0x8c,0x64,0x00,0x08,0x3c,0x02,0x80,0x00,0x00,0xa2,0x38,0x24, -0x10,0xe0,0x00,0x08,0x00,0x82,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21, -0x10,0xe0,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b,0x08,0x00,0x11,0xb4, -0xa2,0x23,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b,0x08,0x00,0x11,0xd8, -0x00,0x00,0x00,0x00,0x24,0x05,0x00,0x24,0xf0,0xe5,0x00,0x06,0x00,0x00,0x28,0x12, -0x27,0x82,0x8f,0xf0,0x00,0xa2,0x28,0x21,0x0c,0x00,0x01,0x4b,0x00,0x00,0x20,0x21, -0x96,0x47,0x00,0x0c,0x08,0x00,0x11,0x96,0x00,0x07,0x2c,0x00,0x27,0x83,0x90,0x00, -0x27,0x82,0x90,0x08,0x00,0xa2,0x10,0x21,0x00,0xa3,0x18,0x21,0x90,0x44,0x00,0x00, -0x90,0x65,0x00,0x05,0x93,0x82,0x80,0x10,0x24,0x07,0x00,0x01,0x0c,0x00,0x21,0xf5, -0xaf,0xa2,0x00,0x10,0x96,0x47,0x00,0x0c,0x08,0x00,0x11,0x89,0x00,0x07,0x1c,0x00, -0x10,0xa2,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x05,0x24,0x02,0x00,0x03, -0x14,0xa2,0xff,0x7d,0x00,0x00,0x00,0x00,0x08,0x00,0x11,0x7a,0xa2,0x40,0x00,0x07, -0x08,0x00,0x11,0x7a,0xa2,0x40,0x00,0x06,0x08,0x00,0x11,0x7a,0xa2,0x40,0x00,0x05, -0x14,0x40,0xff,0x71,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00, -0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,0x08,0x00,0x11,0x71,0x00,0xa2,0x10,0x07, -0x14,0x40,0xfe,0xc3,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00, -0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,0x08,0x00,0x10,0xcc,0x00,0xa2,0x10,0x07, -0x84,0x83,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, -0x00,0x02,0x10,0x80,0x27,0x83,0x8f,0xf4,0x00,0x43,0x10,0x21,0x8c,0x47,0x00,0x18, -0x00,0x00,0x00,0x00,0x8c,0xe6,0x00,0x08,0x0c,0x00,0x0f,0x15,0x00,0x00,0x00,0x00, -0x02,0x40,0x20,0x21,0x00,0x00,0x28,0x21,0x00,0x00,0x30,0x21,0x00,0x00,0x38,0x21, -0x0c,0x00,0x1c,0x86,0xaf,0xa2,0x00,0x10,0x00,0x02,0x1e,0x00,0x14,0x60,0xfe,0x6b, -0xa2,0x22,0x00,0x12,0x92,0x43,0x00,0x08,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x40, -0x24,0x02,0x00,0x01,0xa2,0x40,0x00,0x04,0x92,0x28,0x00,0x04,0x00,0x00,0x00,0x00, -0x15,0x00,0x00,0x19,0x24,0x02,0x00,0x01,0x92,0x27,0x00,0x0a,0xa2,0x22,0x00,0x17, -0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x10,0x00,0x00,0x00,0x00, -0x96,0x22,0x00,0x06,0x00,0x00,0x00,0x00,0xa6,0x22,0x00,0x14,0x92,0x22,0x00,0x16, -0x30,0xe3,0x00,0xff,0x30,0x42,0x00,0xc0,0x10,0x60,0x00,0x03,0xa2,0x22,0x00,0x16, -0x34,0x42,0x00,0x01,0xa2,0x22,0x00,0x16,0x11,0x00,0xfe,0x50,0x00,0x00,0x00,0x00, -0x92,0x22,0x00,0x16,0x08,0x00,0x10,0x92,0x34,0x42,0x00,0x02,0x96,0x22,0x00,0x00, -0x08,0x00,0x12,0x3b,0xa6,0x22,0x00,0x14,0x92,0x27,0x00,0x0a,0x00,0x00,0x00,0x00, -0x14,0xe0,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x12,0x34,0xa2,0x20,0x00,0x17, -0x96,0x24,0x00,0x00,0x96,0x25,0x00,0x06,0x27,0x86,0x8f,0xf0,0x00,0x04,0x18,0xc0, -0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,0x00,0x03,0x18,0x80, -0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08, -0x8c,0x44,0x00,0x08,0x3c,0x03,0x80,0x00,0x00,0xa3,0x30,0x24,0x10,0xc0,0x00,0x08, -0x00,0x83,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21,0x10,0xc0,0x00,0x02, -0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b,0x08,0x00,0x12,0x34,0xa2,0x23,0x00,0x17, -0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b,0x08,0x00,0x12,0x63,0x00,0x00,0x00,0x00, -0x10,0x62,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x05,0x24,0x02,0x00,0x03, -0x14,0x62,0xff,0xbd,0x00,0x00,0x00,0x00,0x08,0x00,0x12,0x2e,0xa2,0x40,0x00,0x07, -0x08,0x00,0x12,0x2e,0xa2,0x40,0x00,0x06,0x08,0x00,0x12,0x2e,0xa2,0x40,0x00,0x05, -0x3c,0x02,0x80,0x00,0x00,0x82,0x30,0x24,0x10,0xc0,0x00,0x08,0x00,0xa2,0x18,0x24, -0x10,0x60,0x00,0x04,0x00,0x00,0x10,0x21,0x10,0xc0,0x00,0x02,0x24,0x02,0x00,0x01, -0x00,0xa4,0x10,0x2b,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x10,0x60,0xff,0xfd, -0x00,0xa4,0x10,0x2b,0x08,0x00,0x12,0x7e,0x00,0x00,0x00,0x00,0x30,0x82,0xff,0xff, -0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x27,0x84,0x90,0x00,0x00,0x03,0x18,0x80, -0x00,0x64,0x18,0x21,0x80,0x66,0x00,0x06,0x00,0x02,0x12,0x00,0x3c,0x03,0xb0,0x00, -0x00,0x46,0x10,0x21,0x00,0x45,0x10,0x21,0x03,0xe0,0x00,0x08,0x00,0x43,0x10,0x21, -0x27,0xbd,0xff,0xe0,0x30,0x82,0x00,0x7c,0x30,0x84,0xff,0x00,0xaf,0xbf,0x00,0x1c, -0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x14,0x40,0x00,0x41, -0x00,0x04,0x22,0x03,0x24,0x02,0x00,0x04,0x3c,0x10,0xb0,0x03,0x8e,0x10,0x00,0x00, -0x10,0x82,0x00,0x32,0x24,0x02,0x00,0x08,0x10,0x82,0x00,0x03,0x32,0x02,0x00,0x20, -0x08,0x00,0x12,0xa4,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x17,0x3c,0x02,0xb0,0x06, -0x34,0x42,0x80,0x24,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x67,0x00,0xff, -0x10,0xe0,0x00,0x23,0x00,0x00,0x88,0x21,0x8f,0x85,0x8f,0xd0,0x00,0x40,0x30,0x21, -0x94,0xa2,0x00,0x08,0x8c,0xc3,0x00,0x00,0x26,0x31,0x00,0x01,0x24,0x42,0x00,0x02, -0x30,0x42,0x01,0xff,0x34,0x63,0x01,0x00,0x02,0x27,0x20,0x2a,0xa4,0xa2,0x00,0x08, -0x14,0x80,0xff,0xf7,0xac,0xc3,0x00,0x00,0x84,0xa3,0x00,0x08,0x3c,0x02,0xb0,0x03, -0x34,0x42,0x00,0x30,0xac,0x43,0x00,0x00,0x27,0x92,0xb3,0xf0,0x24,0x11,0x00,0x12, -0x8e,0x44,0x00,0x00,0x26,0x31,0xff,0xff,0x90,0x82,0x00,0x10,0x00,0x00,0x00,0x00, -0x10,0x40,0x00,0x03,0x26,0x52,0x00,0x04,0x0c,0x00,0x20,0xd0,0x00,0x00,0x00,0x00, -0x06,0x21,0xff,0xf7,0x24,0x02,0xff,0xdf,0x02,0x02,0x80,0x24,0x3c,0x01,0xb0,0x03, -0x0c,0x00,0x13,0x18,0xac,0x30,0x00,0x00,0x08,0x00,0x12,0xa4,0x00,0x00,0x00,0x00, -0x8f,0x85,0x8f,0xd0,0x08,0x00,0x12,0xba,0x00,0x00,0x00,0x00,0x24,0x02,0xff,0x95, -0x3c,0x03,0xb0,0x03,0x02,0x02,0x80,0x24,0x34,0x63,0x00,0x30,0x3c,0x01,0xb0,0x03, -0xac,0x30,0x00,0x00,0x0c,0x00,0x12,0xe1,0xac,0x60,0x00,0x00,0x08,0x00,0x12,0xa4, -0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x50,0x08,0x00,0x12,0xa4, -0xac,0x46,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4b,0x84,0x3c,0x0b,0xb0,0x03, -0xad,0x6a,0x00,0x20,0x3c,0x08,0x80,0x01,0x25,0x08,0x00,0x00,0x3c,0x09,0x80,0x01, -0x25,0x29,0x03,0x1c,0x11,0x09,0x00,0x10,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00, -0x25,0x4a,0x4b,0xac,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0x3c,0x08,0xb0,0x06, -0x35,0x08,0x80,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8d,0x09,0x00,0x00, -0x00,0x00,0x00,0x00,0x31,0x29,0x00,0x01,0x00,0x00,0x00,0x00,0x24,0x01,0x00,0x01, -0x15,0x21,0xff,0xf2,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4b,0xe8, -0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0x3c,0x02,0xb0,0x03,0x8c,0x43,0x00,0x00, -0x00,0x00,0x00,0x00,0x34,0x63,0x00,0x40,0x00,0x00,0x00,0x00,0xac,0x43,0x00,0x00, -0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0x14,0x3c,0x0b,0xb0,0x03, -0xad,0x6a,0x00,0x20,0x3c,0x02,0x80,0x01,0x24,0x42,0x00,0x00,0x3c,0x03,0x80,0x01, -0x24,0x63,0x03,0x1c,0x3c,0x04,0xb0,0x00,0x8c,0x85,0x00,0x00,0x00,0x00,0x00,0x00, -0xac,0x45,0x00,0x00,0x24,0x42,0x00,0x04,0x24,0x84,0x00,0x04,0x00,0x43,0x08,0x2a, -0x14,0x20,0xff,0xf9,0x00,0x00,0x00,0x00,0x0c,0x00,0x13,0x18,0x00,0x00,0x00,0x00, -0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0x60,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20, -0x3c,0x02,0x80,0x01,0x24,0x42,0x03,0x20,0x3c,0x03,0x80,0x01,0x24,0x63,0x3f,0x14, -0xac,0x40,0x00,0x00,0xac,0x40,0x00,0x04,0xac,0x40,0x00,0x08,0xac,0x40,0x00,0x0c, -0x24,0x42,0x00,0x10,0x00,0x43,0x08,0x2a,0x14,0x20,0xff,0xf9,0x00,0x00,0x00,0x00, -0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0xa0,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20, -0x3c,0x1c,0x80,0x01,0x27,0x9c,0x7f,0xf0,0x27,0x9d,0x8b,0xd0,0x00,0x00,0x00,0x00, -0x27,0x9d,0x8f,0xb8,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0xc4,0x3c,0x0b,0xb0,0x03, -0xad,0x6a,0x00,0x20,0x40,0x80,0x68,0x00,0x40,0x08,0x60,0x00,0x00,0x00,0x00,0x00, -0x35,0x08,0xff,0x01,0x40,0x88,0x60,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x15,0x65, -0x00,0x00,0x00,0x00,0x24,0x84,0xf8,0x00,0x30,0x87,0x00,0x03,0x00,0x04,0x30,0x40, -0x00,0xc7,0x20,0x23,0x3c,0x02,0xb0,0x0a,0x27,0xbd,0xff,0xe0,0x24,0x03,0xff,0xff, -0x00,0x82,0x20,0x21,0xaf,0xb1,0x00,0x14,0xac,0x83,0x10,0x00,0xaf,0xbf,0x00,0x18, -0xaf,0xb0,0x00,0x10,0x00,0xa0,0x88,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x10,0x00, -0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0xc7,0x10,0x23,0x3c,0x03,0xb0,0x0a, -0x00,0x43,0x10,0x21,0x8c,0x50,0x00,0x00,0x0c,0x00,0x13,0x95,0x02,0x20,0x20,0x21, -0x02,0x11,0x80,0x24,0x00,0x50,0x80,0x06,0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x18, -0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x27,0xbd,0xff,0xd8, -0xaf,0xb2,0x00,0x18,0x00,0xa0,0x90,0x21,0x24,0x05,0xff,0xff,0xaf,0xb3,0x00,0x1c, -0xaf,0xbf,0x00,0x20,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x00,0xc0,0x98,0x21, -0x12,0x45,0x00,0x23,0x24,0x84,0xf8,0x00,0x30,0x83,0x00,0x03,0x00,0x04,0x10,0x40, -0x00,0x40,0x88,0x21,0x00,0x60,0x20,0x21,0x00,0x43,0x10,0x23,0x3c,0x03,0xb0,0x0a, -0x00,0x43,0x10,0x21,0xac,0x45,0x10,0x00,0x00,0x40,0x18,0x21,0x24,0x05,0x00,0x01, -0x8c,0x62,0x10,0x00,0x00,0x00,0x00,0x00,0x14,0x45,0xff,0xfd,0x3c,0x02,0xb0,0x0a, -0x02,0x24,0x88,0x23,0x02,0x22,0x88,0x21,0x8e,0x30,0x00,0x00,0x0c,0x00,0x13,0x95, -0x02,0x40,0x20,0x21,0x00,0x12,0x18,0x27,0x02,0x03,0x80,0x24,0x00,0x53,0x10,0x04, -0x02,0x02,0x80,0x25,0xae,0x30,0x00,0x00,0x24,0x03,0x00,0x01,0x8e,0x22,0x10,0x00, -0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x20, -0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28, -0x30,0x82,0x00,0x03,0x00,0x04,0x18,0x40,0x00,0x62,0x18,0x23,0x3c,0x04,0xb0,0x0a, -0x00,0x64,0x18,0x21,0xac,0x66,0x00,0x00,0x24,0x04,0x00,0x01,0x8c,0x62,0x10,0x00, -0x00,0x00,0x00,0x00,0x14,0x44,0xff,0xfd,0x00,0x00,0x00,0x00,0x08,0x00,0x13,0x83, -0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x21,0x00,0x64,0x10,0x06,0x30,0x42,0x00,0x01, -0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0x2c,0x62,0x00,0x20, -0x14,0x40,0xff,0xf9,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21, -0x27,0xbd,0xff,0xe0,0x3c,0x03,0xb0,0x05,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14, -0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x1c,0x00,0x80,0x90,0x21,0x00,0xa0,0x80,0x21, -0x00,0xc0,0x88,0x21,0x34,0x63,0x02,0x2e,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00, -0x30,0x42,0x00,0x01,0x14,0x40,0xff,0xfc,0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0xc0, -0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0xc0, -0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x03,0x3c,0x02,0xc0,0x00,0x00,0x10,0x1c,0x00, -0x34,0x42,0x04,0x00,0x3c,0x04,0xb0,0x05,0x3c,0x05,0xb0,0x05,0x24,0x63,0x16,0x09, -0x02,0x22,0x10,0x21,0x34,0x84,0x04,0x20,0x34,0xa5,0x04,0x24,0x3c,0x06,0xb0,0x05, -0xac,0x83,0x00,0x00,0x24,0x07,0x00,0x01,0xac,0xa2,0x00,0x00,0x34,0xc6,0x02,0x28, -0x24,0x02,0x00,0x20,0xae,0x47,0x00,0x3c,0x24,0x04,0x08,0x24,0xa0,0xc2,0x00,0x00, -0x3c,0x05,0x00,0xc0,0xa2,0x47,0x00,0x11,0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x01, -0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0xc0,0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x01, -0x8f,0xbf,0x00,0x1c,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08, -0x27,0xbd,0x00,0x20,0x24,0x02,0x00,0x06,0xac,0x82,0x00,0x0c,0xa0,0x80,0x00,0x50, -0xac,0x80,0x00,0x00,0xac,0x80,0x00,0x04,0xac,0x80,0x00,0x08,0xac,0x80,0x00,0x14, -0xac,0x80,0x00,0x18,0xac,0x80,0x00,0x1c,0xa4,0x80,0x00,0x20,0xac,0x80,0x00,0x24, -0xac,0x80,0x00,0x28,0xac,0x80,0x00,0x2c,0xa0,0x80,0x00,0x30,0xa0,0x80,0x00,0x31, -0xac,0x80,0x00,0x34,0xac,0x80,0x00,0x38,0xa0,0x80,0x00,0x3c,0xac,0x82,0x00,0x10, -0xa0,0x80,0x00,0x44,0xac,0x80,0x00,0x48,0x03,0xe0,0x00,0x08,0xac,0x80,0x00,0x4c, -0x3c,0x04,0xb0,0x06,0x34,0x84,0x80,0x00,0x8c,0x83,0x00,0x00,0x3c,0x02,0x12,0x00, -0x3c,0x05,0xb0,0x03,0x00,0x62,0x18,0x25,0x34,0xa5,0x00,0x8b,0x24,0x02,0xff,0x80, -0xac,0x83,0x00,0x00,0x03,0xe0,0x00,0x08,0xa0,0xa2,0x00,0x00,0x3c,0x04,0xb0,0x03, -0x34,0x84,0x00,0x0b,0x24,0x02,0x00,0x22,0x3c,0x05,0xb0,0x01,0x3c,0x06,0x45,0x67, -0x3c,0x0a,0xb0,0x09,0xa0,0x82,0x00,0x00,0x34,0xa5,0x00,0x04,0x34,0xc6,0x89,0xaa, -0x35,0x4a,0x00,0x04,0x24,0x02,0x01,0x23,0x3c,0x0b,0xb0,0x09,0x3c,0x07,0x01,0x23, -0x3c,0x0c,0xb0,0x09,0x3c,0x01,0xb0,0x01,0xac,0x20,0x00,0x00,0x27,0xbd,0xff,0xe0, -0xac,0xa0,0x00,0x00,0x35,0x6b,0x00,0x08,0x3c,0x01,0xb0,0x09,0xac,0x26,0x00,0x00, -0x34,0xe7,0x45,0x66,0xa5,0x42,0x00,0x00,0x35,0x8c,0x00,0x0c,0x24,0x02,0xcd,0xef, -0x3c,0x0d,0xb0,0x09,0x3c,0x08,0xcd,0xef,0x3c,0x0e,0xb0,0x09,0xad,0x67,0x00,0x00, -0xaf,0xb7,0x00,0x1c,0xa5,0x82,0x00,0x00,0xaf,0xb6,0x00,0x18,0xaf,0xb5,0x00,0x14, -0xaf,0xb4,0x00,0x10,0xaf,0xb3,0x00,0x0c,0xaf,0xb2,0x00,0x08,0xaf,0xb1,0x00,0x04, -0xaf,0xb0,0x00,0x00,0x35,0xad,0x00,0x10,0x35,0x08,0x01,0x22,0x35,0xce,0x00,0x14, -0x24,0x02,0x89,0xab,0x3c,0x0f,0xb0,0x09,0x3c,0x09,0x89,0xab,0x3c,0x10,0xb0,0x09, -0x3c,0x11,0xb0,0x09,0x3c,0x12,0xb0,0x09,0x3c,0x13,0xb0,0x09,0x3c,0x14,0xb0,0x09, -0x3c,0x15,0xb0,0x09,0x3c,0x16,0xb0,0x09,0x3c,0x17,0xb0,0x09,0xad,0xa8,0x00,0x00, -0x24,0x03,0xff,0xff,0xa5,0xc2,0x00,0x00,0x35,0xef,0x00,0x18,0x35,0x29,0xcd,0xee, -0x36,0x10,0x00,0x1c,0x36,0x31,0x00,0x20,0x36,0x52,0x00,0x24,0x36,0x73,0x00,0x28, -0x36,0x94,0x00,0x2c,0x36,0xb5,0x00,0x30,0x36,0xd6,0x00,0x34,0x36,0xf7,0x00,0x38, -0x24,0x02,0x45,0x67,0xad,0xe9,0x00,0x00,0xa6,0x02,0x00,0x00,0xae,0x23,0x00,0x00, -0x8f,0xb0,0x00,0x00,0xa6,0x43,0x00,0x00,0x8f,0xb1,0x00,0x04,0xae,0x63,0x00,0x00, -0x8f,0xb2,0x00,0x08,0xa6,0x83,0x00,0x00,0x8f,0xb3,0x00,0x0c,0xae,0xa3,0x00,0x00, -0x8f,0xb4,0x00,0x10,0xa6,0xc3,0x00,0x00,0x8f,0xb5,0x00,0x14,0xae,0xe3,0x00,0x00, -0x7b,0xb6,0x00,0xfc,0x3c,0x18,0xb0,0x09,0x37,0x18,0x00,0x3c,0xa7,0x03,0x00,0x00, -0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, -0x34,0x63,0x00,0x20,0x24,0x42,0x51,0x38,0xac,0x62,0x00,0x00,0x8c,0x83,0x00,0x34, -0x34,0x02,0xff,0xff,0x00,0x43,0x10,0x2a,0x14,0x40,0x01,0x0b,0x00,0x80,0x30,0x21, -0x8c,0x84,0x00,0x08,0x24,0x02,0x00,0x03,0x10,0x82,0x00,0xfe,0x00,0x00,0x00,0x00, -0x8c,0xc2,0x00,0x2c,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x47,0x24,0x02,0x00,0x06, -0x3c,0x03,0xb0,0x05,0x34,0x63,0x04,0x50,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00, -0x30,0x42,0x00,0xff,0x14,0x40,0x00,0xe4,0xac,0xc2,0x00,0x2c,0x24,0x02,0x00,0x01, -0x10,0x82,0x00,0xe3,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0x82,0x00,0xd1, -0x00,0x00,0x00,0x00,0x8c,0xc7,0x00,0x04,0x24,0x02,0x00,0x02,0x10,0xe2,0x00,0xc7, -0x00,0x00,0x00,0x00,0x8c,0xc2,0x00,0x14,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x09, -0x24,0x02,0x00,0x01,0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60,0x90,0x62,0x00,0x00, -0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0x10,0x40,0x00,0x05,0xac,0xc2,0x00,0x14, -0x24,0x02,0x00,0x01,0xac,0xc2,0x00,0x00,0x03,0xe0,0x00,0x08,0xac,0xc0,0x00,0x14, -0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00, -0x04,0x61,0x00,0x16,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2e,0x90,0x62,0x00,0x00, -0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x10,0x3c,0x02,0xb0,0x05, -0x34,0x42,0x02,0x42,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x0b, -0x00,0x00,0x00,0x00,0x80,0xc2,0x00,0x50,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x07, -0x00,0x00,0x00,0x00,0x14,0x80,0x00,0x05,0x24,0x02,0x00,0x0e,0x24,0x03,0x00,0x01, -0xac,0xc2,0x00,0x00,0x03,0xe0,0x00,0x08,0xa0,0xc3,0x00,0x50,0x80,0xc2,0x00,0x31, -0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0a,0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x18, -0x8c,0x43,0x00,0x00,0x3c,0x04,0xf0,0x00,0x3c,0x02,0x80,0x00,0x00,0x64,0x18,0x24, -0x10,0x62,0x00,0x03,0x24,0x02,0x00,0x09,0x03,0xe0,0x00,0x08,0xac,0xc2,0x00,0x00, -0x8c,0xc2,0x00,0x40,0x00,0x00,0x00,0x00,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00, -0x10,0x60,0x00,0x09,0x3c,0x03,0xb0,0x03,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c, -0x8c,0x43,0x00,0x00,0x3c,0x04,0x00,0x02,0x00,0x64,0x18,0x24,0x14,0x60,0xff,0xf2, -0x24,0x02,0x00,0x10,0x3c,0x03,0xb0,0x03,0x34,0x63,0x02,0x01,0x90,0x62,0x00,0x00, -0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x80,0x10,0x40,0x00,0x0e,0x00,0x00,0x00,0x00, -0x8c,0xc3,0x00,0x0c,0x00,0x00,0x00,0x00,0xac,0xc3,0x00,0x10,0x3c,0x02,0xb0,0x03, -0x90,0x42,0x02,0x01,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x0f,0xac,0xc2,0x00,0x0c, -0x90,0xc3,0x00,0x0f,0x24,0x02,0x00,0x0d,0x3c,0x01,0xb0,0x03,0x08,0x00,0x14,0xa6, -0xa0,0x23,0x02,0x01,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x80,0x90,0x44,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x04,0x1e,0x00,0x00,0x03,0x1e,0x03,0x10,0x60,0x00,0x15, -0xa0,0xc4,0x00,0x44,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x0b,0x24,0x02,0x00,0x02, -0x10,0x62,0x00,0x03,0x24,0x03,0x00,0x0d,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, -0x8c,0xc2,0x00,0x0c,0xac,0xc3,0x00,0x00,0x24,0x03,0x00,0x04,0xac,0xc2,0x00,0x10, -0x03,0xe0,0x00,0x08,0xac,0xc3,0x00,0x0c,0x24,0x02,0x00,0x0d,0xac,0xc2,0x00,0x00, -0x24,0x03,0x00,0x04,0x24,0x02,0x00,0x06,0xac,0xc3,0x00,0x10,0x03,0xe0,0x00,0x08, -0xac,0xc2,0x00,0x0c,0x8c,0xc3,0x00,0x38,0x00,0x00,0x00,0x00,0x2c,0x62,0x00,0x06, -0x10,0x40,0x00,0x2e,0x00,0x03,0x10,0x80,0x3c,0x03,0x80,0x01,0x24,0x63,0x02,0x00, -0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08, -0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xe2,0x00,0x06,0x24,0x02,0x00,0x03, -0x8c,0xa2,0x02,0xbc,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x06,0x3c,0x03,0xb0,0x06, -0x24,0x02,0x00,0x02,0xac,0xc2,0x00,0x00,0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08, -0xac,0xc2,0x00,0x38,0x34,0x63,0x80,0x24,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00, -0x30,0x42,0x00,0xff,0x10,0x40,0x00,0x05,0xac,0xc2,0x00,0x18,0x24,0x02,0x00,0x02, -0xac,0xc2,0x00,0x00,0x08,0x00,0x14,0xfa,0xac,0xc0,0x00,0x18,0x08,0x00,0x14,0xfa, -0xac,0xc0,0x00,0x00,0x24,0x02,0x00,0x02,0x24,0x03,0x00,0x0b,0xac,0xc2,0x00,0x38, -0x03,0xe0,0x00,0x08,0xac,0xc3,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xe2,0x00,0x05, -0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x0c,0xac,0xc2,0x00,0x00,0x08,0x00,0x14,0xfb, -0x24,0x02,0x00,0x04,0x08,0x00,0x15,0x12,0x24,0x02,0x00,0x03,0xac,0xc0,0x00,0x38, -0x03,0xe0,0x00,0x08,0xac,0xc0,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xe2,0x00,0x05, -0x24,0x02,0x00,0x03,0x80,0xc2,0x00,0x30,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x08, -0x24,0x02,0x00,0x04,0xac,0xc2,0x00,0x00,0x93,0x82,0x86,0x3c,0x00,0x00,0x00,0x00, -0x14,0x40,0xff,0xd6,0x24,0x02,0x00,0x05,0x03,0xe0,0x00,0x08,0xac,0xc0,0x00,0x38, -0x08,0x00,0x15,0x22,0xac,0xc0,0x00,0x00,0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x18, -0x8c,0x43,0x00,0x00,0x3c,0x04,0xf0,0x00,0x3c,0x02,0x80,0x00,0x00,0x64,0x18,0x24, -0x10,0x62,0x00,0x03,0x24,0x02,0x00,0x09,0x08,0x00,0x15,0x26,0xac,0xc2,0x00,0x00, -0x24,0x02,0x00,0x05,0x08,0x00,0x15,0x18,0xac,0xc2,0x00,0x38,0x80,0xc2,0x00,0x30, -0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x37,0x24,0x02,0x00,0x04,0x08,0x00,0x14,0xa6, -0x00,0x00,0x00,0x00,0x84,0xc2,0x00,0x20,0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x66, -0x24,0x02,0x00,0x06,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00, -0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21, -0x14,0x40,0xff,0x24,0xa4,0xc3,0x00,0x20,0x08,0x00,0x14,0xa6,0x24,0x02,0x00,0x06, -0x8c,0xc2,0x00,0x1c,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x57,0x24,0x02,0x00,0x05, -0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00, -0x30,0x42,0x00,0xff,0x10,0x40,0xff,0x14,0xac,0xc2,0x00,0x1c,0x08,0x00,0x14,0xa6, -0x24,0x02,0x00,0x05,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x02,0x17,0x42,0x30,0x42,0x00,0x01,0x14,0x40,0xff,0x47,0x24,0x02,0x00,0x06, -0x08,0x00,0x14,0x5c,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x0a,0x03,0xe0,0x00,0x08, -0xac,0x82,0x00,0x00,0x27,0xbd,0xff,0xd8,0xaf,0xb0,0x00,0x10,0x27,0x90,0x86,0x48, -0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0x0c,0x00,0x2b,0xe8, -0xaf,0xb1,0x00,0x14,0xaf,0x90,0x8f,0xd0,0x48,0x02,0x00,0x00,0x0c,0x00,0x13,0xec, -0x00,0x00,0x00,0x00,0x0c,0x00,0x18,0x4e,0x02,0x00,0x20,0x21,0x0c,0x00,0x00,0x34, -0x00,0x00,0x00,0x00,0x0c,0x00,0x13,0xf7,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x68, -0x0c,0x00,0x27,0xc1,0x00,0x00,0x00,0x00,0x93,0x84,0x80,0x10,0x0c,0x00,0x21,0x9a, -0x00,0x00,0x00,0x00,0x27,0x84,0x89,0x08,0x0c,0x00,0x06,0xe1,0x00,0x00,0x00,0x00, -0x0c,0x00,0x01,0x3b,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x10,0x0c,0x00,0x13,0xd5, -0x00,0x00,0x00,0x00,0x27,0x82,0x89,0x3c,0xaf,0x82,0x84,0x50,0x0c,0x00,0x00,0x61, -0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x08,0x3c,0x04,0xb0,0x09, -0x3c,0x05,0xb0,0x09,0x8c,0x66,0x00,0x00,0x34,0x84,0x01,0x68,0x24,0x02,0xc8,0x80, -0x34,0xa5,0x01,0x40,0x24,0x03,0x00,0x0a,0xa4,0x82,0x00,0x00,0xa4,0xa3,0x00,0x00, -0x3c,0x04,0xb0,0x03,0x8c,0x82,0x00,0x00,0x8f,0x87,0x84,0x10,0xaf,0x86,0x84,0x08, -0x34,0x42,0x00,0x20,0xac,0x82,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x58, -0x8c,0x43,0x00,0x00,0x2c,0xe4,0x00,0x11,0x34,0x63,0x01,0x00,0xac,0x43,0x00,0x00, -0x10,0x80,0xff,0xfa,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x00,0x07,0x10,0x80, -0x24,0x63,0x02,0x18,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x68,0x0c,0x00,0x26,0xe5, -0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x10,0x27,0x85,0x86,0x48,0x0c,0x00,0x14,0x4e, -0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x09,0x34,0x42,0x00,0x07,0x3c,0x03,0xb0,0x06, -0x90,0x44,0x00,0x00,0x34,0x63,0x80,0x18,0x8c,0x65,0x00,0x00,0x3c,0x02,0xb0,0x03, -0x34,0x42,0x00,0xec,0x3c,0x03,0xb0,0x03,0x30,0x86,0x00,0xff,0xa0,0x46,0x00,0x00, -0x00,0x05,0x2f,0x02,0x34,0x63,0x00,0xed,0x24,0x02,0x00,0x01,0x10,0xc2,0x00,0x2c, -0xa0,0x65,0x00,0x00,0xa3,0x80,0x81,0x58,0x93,0x83,0x81,0xf1,0x24,0x02,0x00,0x01, -0x10,0x62,0x00,0x08,0x00,0x00,0x00,0x00,0x8f,0x87,0x84,0x10,0x8f,0x82,0x84,0x44, -0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xaf,0x82,0x84,0x44,0x08,0x00,0x15,0x9b, -0x3c,0x02,0xb0,0x03,0x8f,0x87,0x84,0x10,0x00,0x00,0x00,0x00,0x24,0xe2,0xff,0xfc, -0x2c,0x42,0x00,0x03,0x14,0x40,0x00,0x0a,0x3c,0x03,0xb0,0x06,0x93,0x82,0x86,0x3c, -0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x07,0x34,0x63,0x80,0x18,0x27,0x84,0x84,0x68, -0x0c,0x00,0x27,0x75,0x00,0x00,0x00,0x00,0x8f,0x87,0x84,0x10,0x3c,0x03,0xb0,0x06, -0x34,0x63,0x80,0x18,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x02, -0x10,0x40,0xff,0xe6,0x00,0x00,0x00,0x00,0x8f,0x82,0xbc,0x10,0x8f,0x84,0xbc,0x18, -0x3c,0x05,0xb0,0x01,0x00,0x45,0x10,0x21,0xac,0x44,0x00,0x00,0x8f,0x83,0xbc,0x10, -0x8f,0x82,0xbc,0x14,0x00,0x65,0x18,0x21,0x08,0x00,0x15,0xc7,0xac,0x62,0x00,0x04, -0x14,0xa0,0xff,0xd4,0x3c,0x02,0xb0,0x03,0x93,0x83,0x81,0x58,0x34,0x42,0x00,0xee, -0x24,0x63,0x00,0x01,0x30,0x64,0x00,0xff,0x2c,0x84,0x00,0xf1,0xa0,0x43,0x00,0x00, -0xa3,0x83,0x81,0x58,0x14,0x80,0xff,0xcc,0x00,0x00,0x00,0x00,0xaf,0x86,0x84,0x24, -0xa3,0x86,0x86,0x23,0x08,0x00,0x15,0xc1,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x68, -0x0c,0x00,0x29,0x6e,0x00,0x00,0x00,0x00,0xa3,0x82,0x84,0x41,0x8f,0x82,0x84,0x44, -0xaf,0x80,0x84,0x10,0x24,0x42,0x00,0x01,0xaf,0x82,0x84,0x44,0x08,0x00,0x15,0x9a, -0x00,0x00,0x38,0x21,0x27,0x84,0x86,0x48,0x0c,0x00,0x19,0x19,0x00,0x00,0x00,0x00, -0x30,0x42,0x00,0xff,0x14,0x40,0x00,0x05,0x3c,0x03,0xb0,0x05,0xaf,0x80,0x84,0x10, -0xaf,0x80,0x84,0x14,0x08,0x00,0x15,0xc6,0x00,0x00,0x00,0x00,0x34,0x63,0x04,0x50, -0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x3c, -0x14,0x40,0x00,0x20,0x24,0x02,0x00,0x01,0x8f,0x84,0x84,0x18,0x00,0x00,0x00,0x00, -0x10,0x82,0x00,0x20,0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60,0x90,0x62,0x00,0x00, -0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x24,0x14,0x40,0x00,0x15, -0x24,0x02,0x00,0x01,0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x07,0x00,0x00,0x00,0x00, -0x24,0x07,0x00,0x03,0x24,0x02,0x00,0x01,0xaf,0x82,0x84,0x14,0xaf,0x87,0x84,0x10, -0x08,0x00,0x15,0xc6,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e, -0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff, -0x00,0x60,0x10,0x21,0xa7,0x83,0x84,0x30,0x14,0x40,0xff,0xf1,0x00,0x00,0x00,0x00, -0x24,0x02,0x00,0x01,0xaf,0x82,0x84,0x14,0xaf,0x80,0x84,0x10,0x08,0x00,0x15,0xc6, -0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00, -0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x2c,0x14,0x40,0xff,0xf5, -0x24,0x02,0x00,0x01,0x08,0x00,0x16,0x1a,0x3c,0x03,0xb0,0x09,0x27,0x84,0x86,0x48, -0x0c,0x00,0x1a,0xde,0x00,0x00,0x00,0x00,0x83,0x82,0x84,0x40,0x00,0x00,0x00,0x00, -0x14,0x40,0xff,0xec,0x24,0x02,0x00,0x02,0x3c,0x03,0xb0,0x05,0x34,0x63,0x04,0x50, -0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x3c, -0x14,0x40,0xff,0xe4,0x24,0x02,0x00,0x02,0x8f,0x84,0x84,0x18,0x24,0x02,0x00,0x01, -0x10,0x82,0x00,0x12,0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x04,0x00,0x00,0x00,0x00, -0x24,0x07,0x00,0x04,0x08,0x00,0x16,0x26,0x24,0x02,0x00,0x02,0x3c,0x02,0xb0,0x05, -0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01, -0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21,0xa7,0x83,0x84,0x30,0x14,0x40,0xff,0xf4, -0x00,0x00,0x00,0x00,0x08,0x00,0x16,0x35,0x24,0x02,0x00,0x02,0x3c,0x03,0xb0,0x05, -0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff, -0xaf,0x82,0x84,0x2c,0x14,0x40,0xff,0xf7,0x00,0x00,0x00,0x00,0x08,0x00,0x16,0x56, -0x24,0x02,0x00,0x02,0x27,0x84,0x89,0x08,0x0c,0x00,0x0b,0x51,0x00,0x00,0x00,0x00, -0x8f,0x83,0x84,0x14,0xaf,0x82,0x84,0x2c,0x38,0x64,0x00,0x02,0x00,0x04,0x18,0x0a, -0xaf,0x83,0x84,0x14,0x14,0x40,0xff,0xad,0x24,0x07,0x00,0x05,0x8f,0x82,0x89,0x48, -0xaf,0x80,0x84,0x10,0x10,0x40,0x00,0x02,0x24,0x04,0x00,0x01,0xaf,0x84,0x84,0x18, -0x93,0x82,0x89,0x56,0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x43,0x00,0x00,0x00,0x00, -0x3c,0x02,0xb0,0x05,0x34,0x42,0x00,0x08,0x8c,0x43,0x00,0x00,0x3c,0x04,0x20,0x00, -0x00,0x64,0x18,0x24,0x10,0x60,0xff,0x3c,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03, -0x34,0x42,0x00,0xa0,0x8c,0x43,0x00,0x00,0x3c,0x04,0x80,0x00,0xaf,0x80,0x89,0x30, -0x24,0x63,0x00,0x01,0xac,0x43,0x00,0x00,0x3c,0x01,0xb0,0x05,0xac,0x24,0x00,0x08, -0xaf,0x80,0x89,0x2c,0xaf,0x80,0x89,0x34,0xaf,0x80,0x89,0x38,0xaf,0x80,0x89,0x44, -0xaf,0x80,0x89,0x3c,0x08,0x00,0x15,0xc6,0x00,0x00,0x00,0x00,0x83,0x82,0x84,0x60, -0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x02,0x24,0x02,0x00,0x20,0xaf,0x82,0x84,0x2c, -0x8f,0x85,0x84,0x2c,0x27,0x84,0x89,0x08,0x0c,0x00,0x0d,0x2c,0x00,0x00,0x00,0x00, -0x00,0x02,0x1e,0x00,0xa3,0x82,0x84,0x40,0xaf,0x80,0x84,0x2c,0x10,0x60,0xff,0x8e, -0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00, -0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21, -0xa7,0x83,0x84,0x30,0x10,0x40,0x00,0x04,0x24,0x04,0x00,0x02,0xaf,0x84,0x84,0x18, -0x08,0x00,0x16,0x36,0x00,0x00,0x00,0x00,0x08,0x00,0x16,0x27,0x24,0x07,0x00,0x06, -0x27,0x84,0x84,0x10,0x27,0x85,0x89,0x08,0x0c,0x00,0x0d,0xf9,0x00,0x00,0x00,0x00, -0x8f,0x82,0x84,0x34,0xaf,0x80,0x84,0x3c,0x14,0x40,0x00,0x19,0x00,0x40,0x18,0x21, -0x8f,0x82,0x84,0x38,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x15,0x24,0x02,0x00,0x02, -0x8f,0x83,0x84,0x18,0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x0b,0x3c,0x02,0x40,0x00, -0x8f,0x83,0x84,0x14,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x02,0x24,0x07,0x00,0x03, -0x24,0x07,0x00,0x06,0xaf,0x87,0x84,0x10,0x24,0x04,0x00,0x03,0xaf,0x84,0x84,0x18, -0x08,0x00,0x15,0xc6,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x14,0x3c,0x01,0xb0,0x05, -0xac,0x22,0x00,0x00,0xaf,0x80,0x84,0x10,0x08,0x00,0x16,0xcf,0x24,0x04,0x00,0x03, -0x10,0x60,0x00,0x10,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x10,0x27,0x85,0x89,0x08, -0x0c,0x00,0x0e,0x1d,0x00,0x00,0x00,0x00,0x8f,0x83,0x84,0x14,0x24,0x02,0x00,0x01, -0xa3,0x80,0x84,0x40,0xaf,0x80,0x84,0x18,0x10,0x62,0x00,0x02,0x24,0x07,0x00,0x03, -0x24,0x07,0x00,0x04,0xaf,0x87,0x84,0x10,0xaf,0x80,0x84,0x34,0x08,0x00,0x15,0xc6, -0x00,0x00,0x00,0x00,0x83,0x82,0x84,0x60,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x04, -0x00,0x00,0x00,0x00,0x27,0x84,0x89,0x08,0x0c,0x00,0x10,0x65,0x00,0x00,0x00,0x00, -0x8f,0x82,0x84,0x14,0xa3,0x80,0x84,0x40,0xaf,0x80,0x84,0x10,0xaf,0x80,0x84,0x18, -0x14,0x40,0x00,0x03,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0xaf,0x82,0x84,0x14, -0xaf,0x80,0x84,0x38,0x08,0x00,0x15,0xc6,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x10, -0x27,0x85,0x89,0x08,0x0c,0x00,0x0e,0x1d,0x00,0x00,0x00,0x00,0x8f,0x82,0x84,0x14, -0xa3,0x80,0x84,0x40,0xaf,0x80,0x84,0x10,0xaf,0x80,0x84,0x18,0x14,0x40,0xfe,0xc2, -0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0xaf,0x82,0x84,0x14,0x08,0x00,0x15,0xc6, -0x00,0x00,0x00,0x00,0x27,0x84,0x89,0x08,0x0c,0x00,0x10,0x65,0x00,0x00,0x00,0x00, -0x08,0x00,0x16,0xff,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x68,0x0c,0x00,0x2a,0x96, -0x00,0x00,0x00,0x00,0x08,0x00,0x15,0xfe,0x00,0x00,0x00,0x00,0x0c,0x00,0x24,0x66, -0x00,0x00,0x00,0x00,0x0c,0x00,0x27,0x56,0x00,0x00,0x00,0x00,0x0c,0x00,0x18,0x40, -0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x68,0x0c,0x00,0x27,0x64,0x00,0x00,0x00,0x00, -0x93,0x83,0xbc,0x08,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x2b,0x3c,0x02,0xb0,0x03, -0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00,0x8f,0x83,0xbc,0x00,0x8f,0x82,0xbc,0x04, -0x00,0x83,0x18,0x23,0x00,0x43,0x10,0x2b,0x10,0x40,0x00,0x23,0x3c,0x02,0xb0,0x03, -0x24,0x04,0x05,0xa0,0x34,0x42,0x01,0x18,0x8c,0x42,0x00,0x00,0x0c,0x00,0x06,0xce, -0x00,0x00,0x00,0x00,0x24,0x04,0x05,0xa4,0x0c,0x00,0x06,0xce,0x00,0x02,0x84,0x02, -0x30,0x51,0xff,0xff,0x24,0x04,0x05,0xa8,0x00,0x02,0x94,0x02,0x0c,0x00,0x06,0xce, -0x3a,0x10,0xff,0xff,0x3a,0x31,0xff,0xff,0x30,0x42,0xff,0xff,0x2e,0x10,0x00,0x01, -0x2e,0x31,0x00,0x01,0x3a,0x52,0xff,0xff,0x02,0x11,0x80,0x25,0x2e,0x52,0x00,0x01, -0x38,0x42,0xff,0xff,0x02,0x12,0x80,0x25,0x2c,0x42,0x00,0x01,0x02,0x02,0x80,0x25, -0x16,0x00,0x00,0x02,0x24,0x04,0x00,0x02,0x00,0x00,0x20,0x21,0x0c,0x00,0x05,0x70, -0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,0x8c,0x43,0x00,0x00, -0x00,0x00,0x00,0x00,0xaf,0x83,0xbc,0x00,0x0c,0x00,0x01,0xeb,0x00,0x00,0x00,0x00, -0xaf,0x80,0x84,0x10,0xaf,0x80,0x84,0x44,0x08,0x00,0x15,0x9a,0x00,0x00,0x38,0x21, -0x27,0x90,0xb3,0xf0,0x24,0x11,0x00,0x12,0x8e,0x04,0x00,0x00,0x00,0x00,0x00,0x00, -0x90,0x82,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x03,0x00,0x00,0x00,0x00, -0x0c,0x00,0x20,0xd0,0x00,0x00,0x00,0x00,0x26,0x31,0xff,0xff,0x06,0x21,0xff,0xf6, -0x26,0x10,0x00,0x04,0xaf,0x80,0x84,0x10,0x08,0x00,0x15,0xc7,0x00,0x00,0x38,0x21, -0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00,0x8f,0x82,0x84,0x08, -0x00,0x04,0x19,0xc2,0x00,0x02,0x11,0xc2,0x10,0x62,0xff,0xf6,0x00,0x00,0x00,0x00, -0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x02,0x90,0x43,0x00,0x00,0x3c,0x12,0xb0,0x05, -0xaf,0x84,0x84,0x08,0x30,0x63,0x00,0xff,0x00,0x03,0x11,0x40,0x00,0x43,0x10,0x23, -0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0x02,0x99,0x00,0x00,0x00,0x88,0x21, -0x36,0x52,0x02,0x2c,0x27,0x90,0xb3,0xf0,0x8e,0x04,0x00,0x00,0x00,0x00,0x00,0x00, -0x90,0x83,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x03,0x10,0x40,0x00,0x06, -0x30,0x62,0x00,0x1c,0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0x8f,0x85,0x84,0x08, -0x0c,0x00,0x1e,0xb2,0x02,0x60,0x30,0x21,0x8e,0x42,0x00,0x00,0x00,0x00,0x00,0x00, -0x30,0x42,0x00,0xff,0x14,0x40,0xff,0xd7,0x00,0x00,0x00,0x00,0x26,0x31,0x00,0x01, -0x2a,0x22,0x00,0x13,0x14,0x40,0xff,0xec,0x26,0x10,0x00,0x04,0x08,0x00,0x17,0x5d, -0x00,0x00,0x00,0x00,0x8f,0x84,0x84,0x1c,0x27,0x85,0x89,0x08,0x0c,0x00,0x17,0xd3, -0x00,0x00,0x00,0x00,0x8f,0x83,0x84,0x1c,0x24,0x02,0x00,0x04,0x14,0x62,0xfe,0xa2, -0x00,0x00,0x00,0x00,0x08,0x00,0x16,0x27,0x24,0x07,0x00,0x05,0x27,0x84,0x89,0x08, -0x0c,0x00,0x24,0x8d,0x00,0x00,0x00,0x00,0x24,0x07,0x00,0x05,0xaf,0x87,0x84,0x10, -0x08,0x00,0x15,0xc7,0x00,0x00,0x00,0x00,0x8f,0x82,0x89,0x3c,0x00,0x00,0x00,0x00, -0x10,0x40,0x00,0x0d,0x00,0x00,0x00,0x00,0x8f,0x84,0xb4,0x30,0xaf,0x80,0x89,0x3c, -0x94,0x85,0x00,0x14,0x0c,0x00,0x1b,0x84,0x00,0x00,0x00,0x00,0x93,0x82,0x8b,0x61, -0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x02,0x10,0x40,0x00,0x03,0x00,0x00,0x00,0x00, -0x0c,0x00,0x01,0x59,0x00,0x00,0x20,0x21,0x8f,0x84,0xb4,0x30,0x0c,0x00,0x20,0xd0, -0x00,0x00,0x00,0x00,0x08,0x00,0x17,0x5d,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0x90, -0x27,0xbd,0xff,0xe8,0x00,0x80,0x18,0x21,0x34,0x42,0x00,0x01,0x27,0x84,0x89,0x08, -0x10,0x62,0x00,0x05,0xaf,0xbf,0x00,0x10,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00, -0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x06,0xe1,0x00,0x00,0x00,0x00, -0x27,0x84,0x86,0x48,0x0c,0x00,0x18,0x4e,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x10, -0x0c,0x00,0x13,0xd5,0x00,0x00,0x00,0x00,0x08,0x00,0x17,0xba,0x00,0x00,0x00,0x00, -0x8f,0x82,0x89,0x48,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05,0x00,0x00,0x18,0x21, -0x8f,0x82,0x84,0x18,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x02,0x00,0x00,0x00,0x00, -0x24,0x03,0x00,0x01,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,0x27,0xbd,0xff,0xe0, -0x3c,0x06,0xb0,0x03,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x34,0xc6,0x00,0x5f, -0xaf,0xbf,0x00,0x18,0x90,0xc3,0x00,0x00,0x3c,0x07,0xb0,0x03,0x34,0xe7,0x00,0x5d, -0x34,0x63,0x00,0x01,0x3c,0x09,0xb0,0x03,0x24,0x02,0x00,0x01,0xa0,0xc3,0x00,0x00, -0x00,0x80,0x80,0x21,0xa0,0xe2,0x00,0x00,0x00,0xa0,0x88,0x21,0x35,0x29,0x00,0x5e, -0x00,0xe0,0x40,0x21,0x24,0x04,0x00,0x01,0x91,0x22,0x00,0x00,0x91,0x03,0x00,0x00, -0x30,0x42,0x00,0x01,0x14,0x83,0x00,0x03,0x30,0x42,0x00,0x01,0x14,0x40,0xff,0xfa, -0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x04,0x12,0x02,0x00,0x2c,0x24,0x05,0x0f,0x00, -0x24,0x02,0x00,0x06,0x12,0x02,0x00,0x08,0x24,0x05,0x00,0x0f,0x3c,0x02,0xb0,0x03, -0x34,0x42,0x02,0x00,0xa0,0x50,0x00,0x00,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc, -0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x24,0x04,0x0c,0x04,0x0c,0x00,0x13,0x5b, -0x24,0x06,0x00,0x0f,0x24,0x04,0x0d,0x04,0x24,0x05,0x00,0x0f,0x0c,0x00,0x13,0x5b, -0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x80,0x24,0x05,0x1e,0x00,0x0c,0x00,0x13,0x5b, -0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x8c,0x24,0x05,0x0f,0x00,0x0c,0x00,0x13,0x5b, -0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5b, -0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x2c,0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5b, -0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5b, -0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x3c,0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5b, -0x24,0x06,0x00,0x02,0x08,0x00,0x17,0xf4,0x3c,0x02,0xb0,0x03,0x24,0x04,0x08,0x8c, -0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x04,0x24,0x04,0x08,0x80,0x24,0x05,0x1e,0x00, -0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x04,0x24,0x04,0x0c,0x04,0x24,0x05,0x00,0x0f, -0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x04,0x24,0x04,0x0d,0x04,0x24,0x05,0x00,0x0f, -0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x04,0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0x30, -0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x2c,0x3c,0x05,0x00,0x30, -0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0x30, -0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x02,0x3c,0x05,0x00,0x30,0x24,0x06,0x00,0x03, -0x0c,0x00,0x13,0x5b,0x24,0x04,0x08,0x3c,0x02,0x20,0x20,0x21,0x24,0x05,0x00,0x14, -0x0c,0x00,0x13,0xa0,0x24,0x06,0x01,0x07,0x08,0x00,0x17,0xf4,0x3c,0x02,0xb0,0x03, -0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x73,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00, -0x30,0x42,0x00,0x02,0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0xa3,0x80,0x81,0x59, -0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0xa3,0x82,0x81,0x59, -0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, -0x00,0x80,0x70,0x21,0x34,0x63,0x00,0x20,0x24,0x42,0x61,0x38,0x3c,0x04,0xb0,0x03, -0xac,0x62,0x00,0x00,0x34,0x84,0x00,0x30,0xad,0xc0,0x02,0xbc,0xad,0xc0,0x02,0xb8, -0x8c,0x83,0x00,0x00,0x24,0x02,0x00,0xff,0xa5,0xc0,0x00,0x0a,0x00,0x00,0x30,0x21, -0xa7,0x82,0x8f,0xe0,0x27,0x88,0x8f,0xf0,0xa5,0xc3,0x00,0x08,0x3c,0x07,0xb0,0x08, -0x30,0xc2,0xff,0xff,0x00,0x02,0x20,0xc0,0x24,0xc3,0x00,0x01,0x00,0x82,0x10,0x21, -0x00,0x60,0x30,0x21,0x00,0x02,0x10,0x80,0x30,0x63,0xff,0xff,0x00,0x48,0x10,0x21, -0x00,0x87,0x20,0x21,0x28,0xc5,0x00,0xff,0xac,0x83,0x00,0x00,0x14,0xa0,0xff,0xf4, -0xa4,0x43,0x00,0x00,0x3c,0x02,0xb0,0x08,0x34,0x03,0xff,0xff,0x25,0xc4,0x00,0x0c, -0x24,0x0a,0x00,0x02,0x34,0x42,0x07,0xf8,0x3c,0x06,0xb0,0x03,0xa7,0x83,0xb3,0xcc, -0xac,0x43,0x00,0x00,0xaf,0x84,0xb3,0xf0,0x34,0xc6,0x00,0x64,0xa0,0x8a,0x00,0x18, -0x94,0xc5,0x00,0x00,0x8f,0x82,0xb3,0xf0,0x25,0xc4,0x00,0x30,0x24,0x08,0x00,0x03, -0x3c,0x03,0xb0,0x03,0xa0,0x45,0x00,0x21,0x34,0x63,0x00,0x66,0xaf,0x84,0xb3,0xf4, -0xa0,0x88,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xb3,0xf4,0x25,0xc4,0x00,0x54, -0x25,0xc7,0x00,0x78,0xa0,0x45,0x00,0x21,0xaf,0x84,0xb3,0xf8,0xa0,0x88,0x00,0x18, -0x94,0x65,0x00,0x00,0x8f,0x82,0xb3,0xf8,0x25,0xc8,0x00,0x9c,0x24,0x09,0x00,0x01, -0xa0,0x45,0x00,0x21,0xaf,0x87,0xb3,0xfc,0xa0,0xea,0x00,0x18,0x94,0xc4,0x00,0x00, -0x8f,0x82,0xb3,0xfc,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x62,0xa0,0x44,0x00,0x21, -0xaf,0x88,0xb4,0x00,0xa1,0x09,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xb4,0x00, -0x25,0xc4,0x00,0xc0,0x3c,0x06,0xb0,0x03,0xa0,0x45,0x00,0x21,0xaf,0x84,0xb4,0x04, -0xa0,0x89,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xb4,0x04,0x25,0xc4,0x00,0xe4, -0x34,0xc6,0x00,0x60,0xa0,0x45,0x00,0x21,0xaf,0x84,0xb4,0x08,0xa0,0x80,0x00,0x18, -0x94,0xc5,0x00,0x00,0x8f,0x82,0xb4,0x08,0x25,0xc3,0x01,0x08,0x25,0xc7,0x01,0x2c, -0xa0,0x45,0x00,0x21,0xaf,0x83,0xb4,0x0c,0xa0,0x60,0x00,0x18,0x94,0xc8,0x00,0x00, -0x8f,0x82,0xb4,0x0c,0x25,0xc4,0x01,0x50,0x25,0xc5,0x01,0x74,0xa0,0x48,0x00,0x21, -0x25,0xc6,0x01,0x98,0x25,0xc9,0x01,0xbc,0x25,0xca,0x01,0xe0,0x25,0xcb,0x02,0x04, -0x25,0xcc,0x02,0x28,0x25,0xcd,0x02,0x4c,0x24,0x02,0x00,0x10,0x3c,0x03,0xb0,0x03, -0xaf,0x87,0xb4,0x10,0x34,0x63,0x00,0x38,0xa0,0xe0,0x00,0x18,0xaf,0x84,0xb4,0x14, -0xa0,0x80,0x00,0x18,0xaf,0x85,0xb4,0x18,0xa0,0xa0,0x00,0x18,0xaf,0x86,0xb4,0x1c, -0xa0,0xc0,0x00,0x18,0xaf,0x89,0xb4,0x20,0xa1,0x20,0x00,0x18,0xaf,0x8a,0xb4,0x24, -0xa1,0x40,0x00,0x18,0xaf,0x8b,0xb4,0x28,0xa1,0x60,0x00,0x18,0xaf,0x8c,0xb4,0x2c, -0xa1,0x80,0x00,0x18,0xaf,0x8d,0xb4,0x30,0xa1,0xa2,0x00,0x18,0x94,0x64,0x00,0x00, -0x8f,0x82,0xb4,0x30,0x25,0xc5,0x02,0x70,0x3c,0x03,0xb0,0x03,0xa0,0x44,0x00,0x21, -0x24,0x02,0x00,0x11,0xaf,0x85,0xb4,0x34,0x34,0x63,0x00,0x6e,0xa0,0xa2,0x00,0x18, -0x94,0x64,0x00,0x00,0x8f,0x82,0xb4,0x34,0x25,0xc5,0x02,0x94,0x3c,0x03,0xb0,0x03, -0xa0,0x44,0x00,0x21,0x24,0x02,0x00,0x12,0xaf,0x85,0xb4,0x38,0x34,0x63,0x00,0x6c, -0xa0,0xa2,0x00,0x18,0x94,0x64,0x00,0x00,0x8f,0x82,0xb4,0x38,0x24,0x05,0xff,0xff, -0x24,0x07,0x00,0x01,0xa0,0x44,0x00,0x21,0x24,0x06,0x00,0x12,0x27,0x84,0xb3,0xf0, -0x8c,0x82,0x00,0x00,0x24,0xc6,0xff,0xff,0xa0,0x40,0x00,0x04,0x8c,0x83,0x00,0x00, -0xa4,0x45,0x00,0x00,0xa4,0x45,0x00,0x02,0xa0,0x60,0x00,0x0a,0x8c,0x82,0x00,0x00, -0xa4,0x65,0x00,0x06,0xa4,0x65,0x00,0x08,0xa0,0x40,0x00,0x10,0x8c,0x83,0x00,0x00, -0xa4,0x45,0x00,0x0c,0xa4,0x45,0x00,0x0e,0xa0,0x60,0x00,0x12,0x8c,0x82,0x00,0x00, -0x00,0x00,0x00,0x00,0xa0,0x40,0x00,0x16,0x8c,0x83,0x00,0x00,0xa4,0x45,0x00,0x14, -0xa0,0x67,0x00,0x17,0x8c,0x82,0x00,0x00,0x24,0x84,0x00,0x04,0xa0,0x40,0x00,0x20, -0x04,0xc1,0xff,0xe7,0xac,0x40,0x00,0x1c,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, -0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x64,0x00, -0x00,0x05,0x28,0x40,0xac,0x62,0x00,0x00,0x00,0xa6,0x28,0x21,0x2c,0xe2,0x00,0x10, -0x14,0x80,0x00,0x06,0x00,0x00,0x18,0x21,0x10,0x40,0x00,0x02,0x00,0x00,0x00,0x00, -0x00,0xe0,0x18,0x21,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,0x24,0x02,0x00,0x20, -0x10,0xe2,0x00,0x06,0x2c,0xe4,0x00,0x10,0x24,0xa2,0x00,0x01,0x10,0x80,0xff,0xf9, -0x00,0x02,0x11,0x00,0x08,0x00,0x19,0x0d,0x00,0x47,0x18,0x21,0x08,0x00,0x19,0x0d, -0x24,0xa3,0x00,0x50,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xc8, -0x34,0x63,0x00,0x20,0x24,0x42,0x64,0x64,0xaf,0xb2,0x00,0x18,0xaf,0xbf,0x00,0x34, -0xaf,0xbe,0x00,0x30,0xaf,0xb7,0x00,0x2c,0xaf,0xb6,0x00,0x28,0xaf,0xb5,0x00,0x24, -0xaf,0xb4,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10, -0xac,0x62,0x00,0x00,0x8c,0x86,0x02,0xbc,0x00,0x80,0x90,0x21,0x14,0xc0,0x01,0x66, -0x00,0xc0,0x38,0x21,0x84,0x82,0x00,0x08,0x3c,0x03,0xb0,0x06,0x94,0x84,0x00,0x08, -0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x45,0x00,0x00,0x8c,0x43,0x00,0x00, -0x24,0x84,0x00,0x02,0x30,0x84,0x01,0xff,0x30,0xb1,0xff,0xff,0x00,0x03,0x44,0x02, -0xa6,0x44,0x00,0x08,0x14,0xe0,0x00,0x08,0x3c,0x03,0xb0,0x06,0x34,0x63,0x80,0x24, -0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x42,0x01,0x00,0xac,0x62,0x00,0x00, -0x8e,0x46,0x02,0xbc,0x00,0x00,0x00,0x00,0x14,0xc0,0x01,0x4c,0x00,0x11,0x98,0xc0, -0x00,0x11,0x3a,0x00,0x3c,0x04,0xb0,0x00,0x00,0xe4,0x20,0x21,0x8c,0x83,0x00,0x0c, -0x00,0x11,0x98,0xc0,0x02,0x71,0x10,0x21,0x00,0x03,0x1b,0x82,0x30,0x63,0x00,0x1f, -0x00,0x02,0x10,0x80,0x27,0x9e,0x8f,0xf4,0x00,0x5e,0x10,0x21,0x00,0x60,0x30,0x21, -0xac,0x44,0x00,0x18,0xae,0x43,0x02,0xbc,0x14,0xc0,0x00,0x10,0x3c,0x02,0xb0,0x00, -0x00,0x08,0x10,0xc0,0x00,0x48,0x10,0x21,0x27,0x84,0x8f,0xf0,0x00,0x02,0x10,0x80, -0x00,0x44,0x10,0x21,0x94,0x45,0x00,0x00,0x02,0x71,0x18,0x21,0x00,0x03,0x18,0x80, -0x00,0x64,0x18,0x21,0x24,0x02,0xff,0xff,0xa4,0x62,0x00,0x02,0xa4,0x68,0x00,0x04, -0xae,0x51,0x02,0xb8,0xa6,0x45,0x00,0x0a,0x3c,0x02,0xb0,0x00,0x00,0xe2,0x40,0x21, -0x8d,0x16,0x00,0x00,0x8d,0x14,0x00,0x04,0x02,0x71,0x10,0x21,0x00,0x02,0x38,0x80, -0x00,0x14,0x1a,0x02,0x27,0x84,0x90,0x00,0x30,0x63,0x00,0x1f,0x24,0x02,0x00,0x10, -0x00,0xe4,0x20,0x21,0xa6,0x43,0x00,0x06,0x8d,0x10,0x00,0x08,0xa0,0x82,0x00,0x06, -0x86,0x45,0x00,0x06,0x00,0xfe,0x10,0x21,0x24,0x03,0x00,0x13,0x10,0xa3,0x01,0x15, -0xac,0x48,0x00,0x18,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x00,0xa6,0x40,0x00,0x02, -0x3c,0x02,0xb0,0x03,0x90,0x64,0x00,0x00,0x34,0x42,0x01,0x08,0x8c,0x45,0x00,0x00, -0x00,0x10,0x1b,0xc2,0x27,0x82,0x8f,0xf0,0x00,0x04,0x20,0x82,0x00,0xe2,0x10,0x21, -0x30,0x63,0x00,0x01,0xac,0x45,0x00,0x08,0x10,0x60,0x00,0xec,0x30,0x97,0x00,0x01, -0x00,0x10,0x16,0x82,0x30,0x46,0x00,0x01,0x00,0x10,0x12,0x02,0x00,0x10,0x19,0xc2, -0x00,0x10,0x26,0x02,0x00,0x10,0x2e,0x42,0x30,0x47,0x00,0x7f,0x24,0x02,0x00,0x01, -0x30,0x75,0x00,0x01,0x30,0x84,0x00,0x01,0x10,0xc2,0x00,0xd9,0x30,0xa3,0x00,0x01, -0x0c,0x00,0x19,0x00,0x00,0x60,0x28,0x21,0x02,0x71,0x18,0x21,0x00,0x03,0x18,0x80, -0x2c,0x46,0x00,0x54,0x27,0x85,0x90,0x00,0x27,0x84,0x8f,0xf8,0x00,0x06,0x10,0x0a, -0x00,0x65,0x28,0x21,0x26,0xa6,0x00,0x02,0x00,0x64,0x18,0x21,0xa0,0xa2,0x00,0x02, -0xa0,0x66,0x00,0x06,0xa0,0x62,0x00,0x07,0xa0,0xa2,0x00,0x01,0x02,0x71,0x20,0x21, -0x00,0x04,0x20,0x80,0x00,0x9e,0x60,0x21,0x8d,0x85,0x00,0x18,0x00,0x10,0x15,0xc2, -0x30,0x42,0x00,0x01,0x8c,0xa3,0x00,0x0c,0xa6,0x42,0x00,0x00,0x27,0x82,0x90,0x10, -0x00,0x82,0x50,0x21,0xa6,0x56,0x00,0x04,0x8d,0x45,0x00,0x00,0x00,0x03,0x19,0x42, -0x3c,0x02,0xff,0xef,0x34,0x42,0xff,0xff,0x30,0x63,0x00,0x01,0x00,0xa2,0x48,0x24, -0x00,0x03,0x1d,0x00,0x01,0x23,0x48,0x25,0x00,0x09,0x15,0x02,0x26,0xc5,0x00,0x10, -0x00,0x14,0x19,0x82,0x00,0x14,0x25,0x82,0x00,0x10,0x34,0x02,0x00,0x10,0x3c,0x42, -0x00,0x10,0x44,0x82,0x30,0x42,0x00,0x01,0x30,0xb5,0xff,0xff,0x30,0xce,0x00,0x01, -0x30,0xe5,0x00,0x01,0x30,0x6d,0x00,0x01,0x30,0x8b,0x00,0x03,0x32,0x94,0x00,0x07, -0x31,0x06,0x00,0x01,0xad,0x49,0x00,0x00,0x10,0x40,0x00,0x0b,0x32,0x07,0x00,0x7f, -0x8d,0x84,0x00,0x18,0x3c,0x03,0xff,0xf0,0x34,0x63,0xff,0xff,0x8c,0x82,0x00,0x0c, -0x01,0x23,0x18,0x24,0x00,0x02,0x13,0x82,0x30,0x42,0x00,0x0f,0x00,0x02,0x14,0x00, -0x00,0x62,0x18,0x25,0xad,0x43,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xc2,0x00,0x90, -0x00,0x00,0x00,0x00,0x15,0xa0,0x00,0x03,0x00,0x00,0x00,0x00,0x15,0x60,0x00,0x81, -0x24,0x02,0x00,0x01,0x96,0x42,0x00,0x04,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x04, -0xa6,0x42,0x00,0x04,0x0c,0x00,0x19,0x00,0x01,0xc0,0x20,0x21,0x02,0x71,0x18,0x21, -0x00,0x03,0x38,0x80,0x2c,0x45,0x00,0x54,0x27,0x84,0x90,0x00,0x00,0xe4,0x20,0x21, -0x00,0x05,0x10,0x0a,0xa0,0x82,0x00,0x00,0xa0,0x80,0x00,0x04,0xa0,0x80,0x00,0x05, -0x96,0x45,0x00,0x04,0x27,0x82,0x8f,0xf0,0x00,0xe2,0x10,0x21,0xa4,0x45,0x00,0x06, -0x00,0xfe,0x18,0x21,0x92,0x45,0x00,0x01,0x8c,0x66,0x00,0x18,0x27,0x82,0x90,0x10, -0x00,0xe2,0x10,0x21,0xa0,0x40,0x00,0x00,0xa0,0x85,0x00,0x07,0x94,0xc3,0x00,0x10, -0x24,0x02,0x00,0x04,0x30,0x63,0x00,0x0f,0x10,0x62,0x00,0x5e,0x24,0xc6,0x00,0x10, -0x94,0xc3,0x00,0x16,0x27,0x85,0x90,0x08,0x00,0xe5,0x10,0x21,0xa4,0x43,0x00,0x02, -0x94,0xc2,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x4c, -0x02,0x71,0x20,0x21,0x94,0xc2,0x00,0x00,0x24,0x03,0x00,0xa4,0x30,0x42,0x00,0xff, -0x10,0x43,0x00,0x47,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x00,0x24,0x03,0x00,0x88, -0x30,0x42,0x00,0x88,0x10,0x43,0x00,0x3c,0x02,0x71,0x18,0x21,0x27,0x84,0x90,0x10, -0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x21,0x8c,0x62,0x00,0x00,0x3c,0x04,0x00,0x80, -0x00,0x44,0x10,0x25,0xac,0x62,0x00,0x00,0x02,0x71,0x10,0x21,0x00,0x02,0x10,0x80, -0x00,0x45,0x10,0x21,0xa0,0x54,0x00,0x00,0x92,0x43,0x02,0xbf,0x3c,0x02,0xb0,0x03, -0x34,0x42,0x00,0xc3,0xa0,0x43,0x00,0x00,0x8e,0x4b,0x02,0xbc,0x00,0x00,0x00,0x00, -0x11,0x60,0x00,0x1c,0x32,0xa2,0x00,0xff,0x00,0x15,0x1a,0x02,0x30,0x64,0xff,0xff, -0x38,0x42,0x00,0x00,0x24,0x65,0x00,0x01,0x00,0x82,0x28,0x0a,0x02,0x20,0x30,0x21, -0x10,0xa0,0x00,0x12,0x00,0x00,0x38,0x21,0x02,0x71,0x10,0x21,0x00,0x02,0x10,0x80, -0x27,0x83,0x8f,0xf0,0x00,0x43,0x20,0x21,0x24,0xa9,0xff,0xff,0x3c,0x0a,0xb0,0x08, -0x24,0x0c,0xff,0xff,0x00,0x06,0x10,0xc0,0x00,0x4a,0x10,0x21,0x8c,0x43,0x00,0x00, -0x24,0xe8,0x00,0x01,0x10,0xe9,0x00,0x0f,0x30,0x63,0x00,0xff,0x31,0x07,0xff,0xff, -0x00,0xe5,0x10,0x2b,0x14,0x40,0xff,0xf7,0x00,0x60,0x30,0x21,0x25,0x62,0xff,0xff, -0xae,0x42,0x02,0xbc,0x7b,0xbe,0x01,0xbc,0x7b,0xb6,0x01,0x7c,0x7b,0xb4,0x01,0x3c, -0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08, -0x27,0xbd,0x00,0x38,0xa4,0x86,0x00,0x04,0xa4,0x8c,0x00,0x02,0xae,0x51,0x02,0xb8, -0x08,0x00,0x1a,0x2f,0xa6,0x43,0x00,0x0a,0x94,0xc2,0x00,0x18,0x00,0x00,0x00,0x00, -0x30,0x42,0x00,0x60,0x10,0x40,0xff,0xc1,0x02,0x71,0x18,0x21,0x02,0x71,0x20,0x21, -0x27,0x82,0x90,0x10,0x00,0x04,0x20,0x80,0x00,0x82,0x20,0x21,0x8c,0x83,0x00,0x00, -0x3c,0x02,0xff,0x7f,0x34,0x42,0xff,0xff,0x00,0x62,0x18,0x24,0x08,0x00,0x1a,0x0e, -0xac,0x83,0x00,0x00,0x27,0x85,0x90,0x08,0x00,0xe5,0x10,0x21,0x08,0x00,0x19,0xf8, -0xa4,0x40,0x00,0x02,0x11,0x62,0x00,0x07,0x00,0x00,0x00,0x00,0x2d,0x62,0x00,0x02, -0x14,0x40,0xff,0x80,0x00,0x00,0x00,0x00,0x96,0x42,0x00,0x04,0x08,0x00,0x19,0xd8, -0x24,0x42,0x00,0x0c,0x96,0x42,0x00,0x04,0x08,0x00,0x19,0xd8,0x24,0x42,0x00,0x08, -0x16,0xe6,0xff,0x70,0x3c,0x02,0xff,0xfb,0x8d,0x83,0x00,0x18,0x34,0x42,0xff,0xff, -0x02,0x02,0x10,0x24,0xac,0x62,0x00,0x08,0x08,0x00,0x19,0xd1,0x00,0x00,0x30,0x21, -0x16,0xe6,0xff,0x27,0x3c,0x02,0xfb,0xff,0x34,0x42,0xff,0xff,0x02,0x02,0x10,0x24, -0xad,0x02,0x00,0x08,0x08,0x00,0x19,0x90,0x00,0x00,0x30,0x21,0x93,0x88,0xbb,0x04, -0x00,0x10,0x1e,0x42,0x00,0x10,0x26,0x82,0x27,0x82,0x8f,0xf8,0x2d,0x05,0x00,0x0c, -0x00,0xe2,0x48,0x21,0x30,0x63,0x00,0x01,0x30,0x86,0x00,0x01,0x14,0xa0,0x00,0x06, -0x01,0x00,0x38,0x21,0x00,0x03,0x10,0x40,0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00, -0x01,0x02,0x10,0x21,0x24,0x47,0x00,0x04,0x02,0x71,0x10,0x21,0x00,0x02,0x10,0x80, -0x27,0x84,0x90,0x00,0x27,0x83,0x8f,0xf8,0x00,0x44,0x20,0x21,0x00,0x43,0x10,0x21, -0xa1,0x27,0x00,0x07,0xa0,0x40,0x00,0x06,0xa0,0x80,0x00,0x02,0x08,0x00,0x19,0x9f, -0xa0,0x80,0x00,0x01,0x24,0x02,0x00,0x01,0xa6,0x42,0x00,0x02,0x0c,0x00,0x01,0xc4, -0x01,0x00,0x20,0x21,0x08,0x00,0x1a,0x35,0x00,0x00,0x00,0x00,0x27,0x9e,0x8f,0xf4, -0x08,0x00,0x19,0x52,0x00,0x11,0x3a,0x00,0x94,0x91,0x00,0x0a,0x08,0x00,0x19,0x39, -0x00,0x00,0x00,0x00,0x30,0xa9,0xff,0xff,0x00,0x09,0x18,0xc0,0x00,0x69,0x18,0x21, -0x3c,0x06,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x6a,0x54,0x00,0x03,0x18,0x80, -0x34,0xc6,0x00,0x20,0x27,0x85,0x90,0x00,0xac,0xc2,0x00,0x00,0x00,0x65,0x18,0x21, -0x80,0x62,0x00,0x07,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x32,0x24,0x88,0x00,0x06, -0x90,0x82,0x00,0x16,0x00,0x80,0x40,0x21,0x34,0x42,0x00,0x02,0x30,0x43,0x00,0x01, -0x14,0x60,0x00,0x02,0xa0,0x82,0x00,0x16,0xa0,0x80,0x00,0x17,0x95,0x03,0x00,0x02, -0x00,0x00,0x00,0x00,0x10,0x69,0x00,0x22,0x3c,0x02,0x34,0x34,0x91,0x02,0x00,0x04, -0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x06,0x00,0x03,0x20,0xc0,0x24,0x02,0x00,0x01, -0xa1,0x02,0x00,0x04,0xa5,0x09,0x00,0x02,0x03,0xe0,0x00,0x08,0xa5,0x09,0x00,0x00, -0x00,0x83,0x20,0x21,0x27,0x87,0x8f,0xf0,0x00,0x04,0x20,0x80,0x00,0x87,0x20,0x21, -0x94,0x83,0x00,0x04,0x3c,0x02,0xb0,0x08,0x3c,0x06,0xb0,0x03,0x00,0x03,0x28,0xc0, -0x00,0xa3,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0xa2,0x28,0x21,0x3c,0x02,0x80,0x01, -0x24,0x42,0x82,0xe4,0x00,0x67,0x18,0x21,0x34,0xc6,0x00,0x20,0xac,0xc2,0x00,0x00, -0xa4,0x69,0x00,0x00,0xa4,0x89,0x00,0x02,0xac,0xa9,0x00,0x00,0x91,0x02,0x00,0x04, -0xa5,0x09,0x00,0x02,0x24,0x42,0x00,0x01,0x03,0xe0,0x00,0x08,0xa1,0x02,0x00,0x04, -0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0xb0,0x34,0x42,0x34,0x34,0x03,0xe0,0x00,0x08, -0xac,0x62,0x00,0x00,0x90,0x82,0x00,0x16,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x01, -0x30,0x43,0x00,0x02,0x14,0x60,0xff,0xd1,0xa0,0x82,0x00,0x16,0x24,0x02,0x00,0x01, -0x08,0x00,0x1a,0xab,0xa0,0x82,0x00,0x17,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10, -0x00,0x80,0x38,0x21,0x84,0x84,0x00,0x02,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, -0x3c,0x0a,0xb0,0x06,0x34,0x63,0x00,0x20,0x24,0x42,0x6b,0x78,0x3c,0x0b,0xb0,0x08, -0x27,0x89,0x8f,0xf0,0x34,0x0c,0xff,0xff,0x35,0x4a,0x80,0x20,0x10,0x80,0x00,0x30, -0xac,0x62,0x00,0x00,0x97,0x82,0x8f,0xe0,0x94,0xe6,0x02,0xba,0x00,0x02,0x18,0xc0, -0x00,0x6b,0x28,0x21,0xac,0xa6,0x00,0x00,0x8c,0xe4,0x02,0xb8,0x00,0x62,0x18,0x21, -0x00,0x03,0x18,0x80,0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x02,0x10,0x80, -0x00,0x49,0x10,0x21,0x94,0x48,0x00,0x04,0x00,0x69,0x18,0x21,0xa4,0x66,0x00,0x00, -0x00,0x08,0x28,0xc0,0x00,0xab,0x10,0x21,0xac,0x4c,0x00,0x00,0x8c,0xe4,0x02,0xb8, -0x27,0x82,0x8f,0xf4,0x00,0xa8,0x28,0x21,0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21, -0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x8c,0x46,0x00,0x18,0x27,0x84,0x90,0x00, -0x00,0x64,0x18,0x21,0x8c,0xc2,0x00,0x00,0x80,0x67,0x00,0x06,0x00,0x05,0x28,0x80, -0x30,0x42,0xff,0xff,0x00,0x47,0x10,0x21,0x30,0x43,0x00,0xff,0x00,0x03,0x18,0x2b, -0x00,0x02,0x12,0x02,0x00,0x43,0x10,0x21,0x3c,0x04,0x00,0x04,0x00,0xa9,0x28,0x21, -0x00,0x44,0x10,0x25,0xa4,0xac,0x00,0x00,0xad,0x42,0x00,0x00,0xa7,0x88,0x8f,0xe0, -0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18, -0x84,0xe3,0x00,0x06,0x27,0x82,0xb3,0xf0,0x94,0xe5,0x02,0xba,0x00,0x03,0x18,0x80, -0x00,0x62,0x18,0x21,0x8c,0x64,0x00,0x00,0x0c,0x00,0x1a,0x95,0x00,0x00,0x00,0x00, -0x08,0x00,0x1b,0x18,0x00,0x00,0x00,0x00,0x94,0x88,0x00,0x00,0x00,0x80,0x58,0x21, -0x27,0x8a,0x8f,0xf0,0x00,0x08,0x18,0xc0,0x00,0x68,0x18,0x21,0x3c,0x04,0xb0,0x03, -0x00,0x03,0x18,0x80,0x3c,0x02,0x80,0x00,0x00,0x6a,0x18,0x21,0x34,0x84,0x00,0x20, -0x24,0x42,0x6c,0x98,0x30,0xa5,0xff,0xff,0xac,0x82,0x00,0x00,0x94,0x67,0x00,0x02, -0x11,0x05,0x00,0x35,0x24,0x04,0x00,0x01,0x91,0x66,0x00,0x04,0x00,0x00,0x00,0x00, -0x00,0x86,0x10,0x2a,0x10,0x40,0x00,0x10,0x00,0xc0,0x48,0x21,0x3c,0x0d,0xb0,0x03, -0x01,0x40,0x60,0x21,0x35,0xad,0x00,0x20,0x10,0xe5,0x00,0x0d,0x24,0x84,0x00,0x01, -0x00,0x07,0x10,0xc0,0x00,0x47,0x10,0x21,0x00,0x02,0x10,0x80,0x01,0x20,0x30,0x21, -0x00,0x4a,0x10,0x21,0x00,0x86,0x18,0x2a,0x00,0xe0,0x40,0x21,0x94,0x47,0x00,0x02, -0x14,0x60,0xff,0xf5,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x10,0x21, -0x00,0x08,0x20,0xc0,0x00,0x88,0x20,0x21,0x24,0xc2,0xff,0xff,0x00,0x04,0x20,0x80, -0xa1,0x62,0x00,0x04,0x00,0x8c,0x20,0x21,0x94,0x83,0x00,0x04,0x00,0x07,0x10,0xc0, -0x00,0x47,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x4c,0x10,0x21,0x00,0x03,0x28,0xc0, -0x94,0x46,0x00,0x02,0x00,0xa3,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x6c,0x18,0x21, -0xa4,0x66,0x00,0x00,0xa4,0x86,0x00,0x02,0x95,0x64,0x00,0x02,0x3c,0x03,0xb0,0x08, -0x3c,0x02,0x80,0x01,0x00,0xa3,0x28,0x21,0x24,0x42,0x82,0xe4,0xad,0xa2,0x00,0x00, -0x10,0x87,0x00,0x03,0xac,0xa6,0x00,0x00,0x03,0xe0,0x00,0x08,0x24,0x02,0x00,0x01, -0x08,0x00,0x1b,0x66,0xa5,0x68,0x00,0x02,0x91,0x62,0x00,0x04,0xa5,0x67,0x00,0x00, -0x24,0x42,0xff,0xff,0x30,0x43,0x00,0xff,0x14,0x60,0x00,0x03,0xa1,0x62,0x00,0x04, -0x24,0x02,0xff,0xff,0xa5,0x62,0x00,0x02,0x91,0x65,0x00,0x04,0x00,0x00,0x00,0x00, -0x10,0xa0,0xff,0xf1,0x00,0x00,0x00,0x00,0x95,0x66,0x00,0x00,0x34,0x02,0xff,0xff, -0x14,0xc2,0xff,0xed,0x3c,0x03,0xb0,0x03,0x95,0x64,0x00,0x02,0x3c,0x02,0xee,0xee, -0x00,0xa2,0x10,0x25,0x34,0x63,0x00,0xbc,0xac,0x62,0x00,0x00,0x10,0x86,0xff,0xe6, -0xa1,0x60,0x00,0x04,0x24,0x02,0xff,0xff,0x08,0x00,0x1b,0x66,0xa5,0x62,0x00,0x02, -0x00,0x05,0x40,0xc0,0x01,0x05,0x30,0x21,0x27,0xbd,0xff,0xd8,0x00,0x06,0x30,0x80, -0x27,0x82,0x8f,0xf4,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20, -0xaf,0xb3,0x00,0x1c,0xaf,0xb0,0x00,0x10,0x00,0xc2,0x10,0x21,0x8c,0x47,0x00,0x18, -0x00,0xa0,0x90,0x21,0x3c,0x02,0x80,0x00,0x3c,0x05,0xb0,0x03,0x34,0xa5,0x00,0x20, -0x24,0x42,0x6e,0x10,0xac,0xa2,0x00,0x00,0x27,0x83,0x90,0x00,0x00,0xc3,0x30,0x21, -0x8c,0xe2,0x00,0x00,0x80,0xc5,0x00,0x06,0x00,0x80,0x88,0x21,0x30,0x42,0xff,0xff, -0x00,0x45,0x10,0x21,0x30,0x43,0x00,0xff,0x10,0x60,0x00,0x02,0x00,0x02,0x12,0x02, -0x24,0x42,0x00,0x01,0x30,0x53,0x00,0xff,0x01,0x12,0x10,0x21,0x00,0x02,0x10,0x80, -0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0x80,0x44,0x00,0x07,0x00,0x00,0x00,0x00, -0x10,0x80,0x00,0x4b,0x26,0x24,0x00,0x06,0x32,0x50,0xff,0xff,0x02,0x20,0x20,0x21, -0x0c,0x00,0x1b,0x26,0x02,0x00,0x28,0x21,0x92,0x22,0x00,0x10,0x00,0x00,0x00,0x00, -0x14,0x40,0x00,0x2e,0x3c,0x03,0xb0,0x08,0x3c,0x09,0x80,0x01,0x27,0x88,0x8f,0xf0, -0xa6,0x32,0x00,0x0c,0x00,0x10,0x20,0xc0,0x00,0x90,0x20,0x21,0x00,0x04,0x20,0x80, -0x00,0x88,0x20,0x21,0x94,0x82,0x00,0x04,0x3c,0x03,0xb0,0x08,0x3c,0x07,0xb0,0x03, -0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x48,0x10,0x21, -0x00,0xa3,0x28,0x21,0x25,0x26,0x82,0xe4,0x34,0x03,0xff,0xff,0x34,0xe7,0x00,0x20, -0xac,0xe6,0x00,0x00,0xa4,0x83,0x00,0x02,0xa4,0x43,0x00,0x00,0xac,0xa3,0x00,0x00, -0x92,0x22,0x00,0x10,0x92,0x23,0x00,0x0a,0xa6,0x32,0x00,0x0e,0x02,0x62,0x10,0x21, -0x14,0x60,0x00,0x05,0xa2,0x22,0x00,0x10,0x92,0x22,0x00,0x16,0x00,0x00,0x00,0x00, -0x30,0x42,0x00,0xfe,0xa2,0x22,0x00,0x16,0x92,0x22,0x00,0x04,0x00,0x00,0x00,0x00, -0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x92,0x22,0x00,0x16,0x00,0x00,0x00,0x00, -0x30,0x42,0x00,0xfd,0xa2,0x22,0x00,0x16,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc, -0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x96,0x22,0x00,0x0e, -0x27,0x88,0x8f,0xf0,0x00,0x02,0x20,0xc0,0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80, -0x00,0x88,0x20,0x21,0x94,0x82,0x00,0x04,0x3c,0x06,0xb0,0x03,0x3c,0x09,0x80,0x01, -0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0xa3,0x28,0x21, -0x00,0x48,0x10,0x21,0x34,0xc6,0x00,0x20,0x25,0x23,0x82,0xe4,0xac,0xc3,0x00,0x00, -0xa4,0x50,0x00,0x00,0xac,0xb0,0x00,0x00,0x08,0x00,0x1b,0xb5,0xa4,0x90,0x00,0x02, -0x08,0x00,0x1b,0xac,0x32,0x50,0xff,0xff,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, -0x24,0x42,0x6f,0xd8,0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,0x90,0x82,0x00,0x04, -0x97,0xaa,0x00,0x12,0x00,0x80,0x60,0x21,0x30,0xa8,0xff,0xff,0x00,0x4a,0x20,0x23, -0x34,0x09,0xff,0xff,0x30,0xcf,0xff,0xff,0x30,0xee,0xff,0xff,0x11,0x09,0x00,0x73, -0xa1,0x84,0x00,0x04,0x00,0x0e,0xc0,0xc0,0x00,0x08,0x10,0xc0,0x00,0x48,0x10,0x21, -0x03,0x0e,0x20,0x21,0x27,0x8d,0x8f,0xf0,0x00,0x04,0x20,0x80,0x00,0x02,0x10,0x80, -0x00,0x4d,0x10,0x21,0x00,0x8d,0x20,0x21,0x94,0x86,0x00,0x02,0x94,0x43,0x00,0x04, -0x3c,0x19,0x80,0x01,0xa4,0x46,0x00,0x02,0x00,0x03,0x28,0xc0,0x00,0xa3,0x18,0x21, -0x94,0x87,0x00,0x02,0x3c,0x02,0xb0,0x08,0x00,0x03,0x18,0x80,0x00,0xa2,0x28,0x21, -0x00,0x6d,0x18,0x21,0x27,0x22,0x82,0xe4,0x3c,0x01,0xb0,0x03,0xac,0x22,0x00,0x20, -0xa4,0x66,0x00,0x00,0x10,0xe9,0x00,0x57,0xac,0xa6,0x00,0x00,0x01,0xe0,0x30,0x21, -0x11,0x40,0x00,0x1d,0x00,0x00,0x48,0x21,0x01,0x40,0x38,0x21,0x27,0x8b,0x8f,0xf4, -0x27,0x8a,0x90,0x00,0x00,0x06,0x40,0xc0,0x01,0x06,0x18,0x21,0x00,0x03,0x18,0x80, -0x00,0x6b,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x6a,0x18,0x21,0x80,0x65,0x00,0x06, -0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0xff,0xff,0x00,0x45,0x10,0x21, -0x30,0x44,0x00,0xff,0x00,0x02,0x12,0x02,0x01,0x22,0x18,0x21,0x24,0x62,0x00,0x01, -0x14,0x80,0x00,0x02,0x30,0x49,0x00,0xff,0x30,0x69,0x00,0xff,0x01,0x06,0x10,0x21, -0x00,0x02,0x10,0x80,0x00,0x4d,0x10,0x21,0x24,0xe7,0xff,0xff,0x94,0x46,0x00,0x02, -0x14,0xe0,0xff,0xe9,0x00,0x06,0x40,0xc0,0x91,0x82,0x00,0x10,0x00,0x00,0x00,0x00, -0x14,0x40,0x00,0x20,0x3c,0x06,0xb0,0x03,0xa5,0x8f,0x00,0x0c,0x03,0x0e,0x20,0x21, -0x00,0x04,0x20,0x80,0x00,0x8d,0x20,0x21,0x94,0x82,0x00,0x04,0x3c,0x03,0xb0,0x08, -0x3c,0x07,0xb0,0x03,0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80, -0x00,0x4d,0x10,0x21,0x00,0xa3,0x28,0x21,0x27,0x26,0x82,0xe4,0x34,0x03,0xff,0xff, -0x34,0xe7,0x00,0x20,0xac,0xe6,0x00,0x00,0xa4,0x83,0x00,0x02,0xa4,0x43,0x00,0x00, -0xac,0xa3,0x00,0x00,0x91,0x82,0x00,0x10,0x91,0x83,0x00,0x04,0xa5,0x8e,0x00,0x0e, -0x01,0x22,0x10,0x21,0x14,0x60,0x00,0x05,0xa1,0x82,0x00,0x10,0x91,0x82,0x00,0x16, -0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfd,0xa1,0x82,0x00,0x16,0x03,0xe0,0x00,0x08, -0x00,0x00,0x00,0x00,0x95,0x82,0x00,0x0e,0x3c,0x03,0xb0,0x08,0x00,0x02,0x20,0xc0, -0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x8d,0x20,0x21,0x94,0x82,0x00,0x04, -0x34,0xc6,0x00,0x20,0x27,0x27,0x82,0xe4,0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21, -0x00,0x02,0x10,0x80,0x00,0xa3,0x28,0x21,0x00,0x4d,0x10,0x21,0xac,0xc7,0x00,0x00, -0xa4,0x8f,0x00,0x02,0xa4,0x4f,0x00,0x00,0xac,0xaf,0x00,0x00,0x08,0x00,0x1c,0x44, -0x03,0x0e,0x20,0x21,0x08,0x00,0x1c,0x1f,0xa5,0x88,0x00,0x02,0x00,0x0e,0xc0,0xc0, -0x03,0x0e,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x8d,0x8f,0xf0,0x00,0x4d,0x10,0x21, -0x94,0x43,0x00,0x02,0x30,0x84,0x00,0xff,0x14,0x80,0x00,0x05,0xa5,0x83,0x00,0x00, -0x24,0x02,0xff,0xff,0x3c,0x19,0x80,0x01,0x08,0x00,0x1c,0x1f,0xa5,0x82,0x00,0x02, -0x08,0x00,0x1c,0x1f,0x3c,0x19,0x80,0x01,0x3c,0x08,0xb0,0x03,0x3c,0x02,0x80,0x00, -0x27,0xbd,0xff,0x78,0x35,0x08,0x00,0x20,0x24,0x42,0x72,0x18,0xaf,0xb2,0x00,0x68, -0xaf,0xb1,0x00,0x64,0xaf,0xb0,0x00,0x60,0xad,0x02,0x00,0x00,0xaf,0xbf,0x00,0x84, -0xaf,0xbe,0x00,0x80,0xaf,0xb7,0x00,0x7c,0xaf,0xb6,0x00,0x78,0xaf,0xb5,0x00,0x74, -0xaf,0xb4,0x00,0x70,0xaf,0xb3,0x00,0x6c,0xaf,0xa4,0x00,0x88,0x90,0x83,0x00,0x0a, -0x27,0x82,0xb3,0xf0,0xaf,0xa6,0x00,0x90,0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21, -0x8c,0x63,0x00,0x00,0xaf,0xa7,0x00,0x94,0x27,0x86,0x8f,0xf4,0xaf,0xa3,0x00,0x1c, -0x94,0x63,0x00,0x14,0x30,0xb1,0xff,0xff,0x24,0x08,0x00,0x01,0x00,0x03,0x20,0xc0, -0xaf,0xa3,0x00,0x18,0x00,0x83,0x18,0x21,0xaf,0xa4,0x00,0x54,0x00,0x03,0x18,0x80, -0x27,0x84,0x90,0x00,0x00,0x64,0x20,0x21,0x80,0x82,0x00,0x06,0x00,0x66,0x18,0x21, -0x8c,0x66,0x00,0x18,0x24,0x42,0x00,0x02,0x00,0x02,0x1f,0xc2,0x8c,0xc4,0x00,0x08, -0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40,0x00,0x04,0x2f,0xc2, -0x00,0x04,0x1c,0x82,0x00,0xc2,0x38,0x21,0x00,0x04,0x24,0x42,0x8f,0xa2,0x00,0x1c, -0x30,0x63,0x00,0x01,0x30,0x84,0x00,0x01,0xaf,0xa5,0x00,0x3c,0xaf,0xa3,0x00,0x34, -0xaf,0xa4,0x00,0x38,0xaf,0xa0,0x00,0x40,0xaf,0xa0,0x00,0x44,0xaf,0xa0,0x00,0x50, -0xaf,0xa8,0x00,0x20,0x80,0x42,0x00,0x12,0x8f,0xb2,0x00,0x18,0xaf,0xa2,0x00,0x28, -0x8c,0xd0,0x00,0x0c,0x14,0xa0,0x01,0xe4,0x00,0x60,0x30,0x21,0x00,0x10,0x10,0x82, -0x30,0x45,0x00,0x07,0x10,0xa0,0x00,0x11,0xaf,0xa0,0x00,0x30,0x8f,0xa4,0x00,0x98, -0x27,0x82,0x80,0x1c,0x00,0x04,0x18,0x40,0x00,0x62,0x18,0x21,0x24,0xa2,0x00,0x06, -0x8f,0xa5,0x00,0x20,0x94,0x64,0x00,0x00,0x00,0x45,0x10,0x04,0x00,0x44,0x00,0x1a, -0x14,0x80,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d,0x00,0x00,0x10,0x12, -0x24,0x42,0x00,0x20,0x30,0x42,0xff,0xfc,0xaf,0xa2,0x00,0x30,0x8f,0xa3,0x00,0x18, -0x8f,0xa4,0x00,0x28,0x34,0x02,0xff,0xff,0xaf,0xa0,0x00,0x2c,0xaf,0xa2,0x00,0x48, -0xaf,0xa3,0x00,0x4c,0x00,0x60,0xf0,0x21,0x00,0x00,0xb8,0x21,0x18,0x80,0x00,0x48, -0xaf,0xa0,0x00,0x24,0x00,0x11,0x89,0x02,0xaf,0xb1,0x00,0x58,0x00,0x80,0xa8,0x21, -0x00,0x12,0x10,0xc0,0x00,0x52,0x18,0x21,0x00,0x03,0x80,0x80,0x27,0x85,0x8f,0xf0, -0x02,0x40,0x20,0x21,0x00,0x40,0xa0,0x21,0x02,0x05,0x10,0x21,0x94,0x56,0x00,0x02, -0x0c,0x00,0x12,0x87,0x00,0x00,0x28,0x21,0x90,0x42,0x00,0x00,0x24,0x03,0x00,0x08, -0x30,0x42,0x00,0x0c,0x10,0x43,0x01,0x9e,0x24,0x04,0x00,0x01,0x24,0x02,0x00,0x01, -0x10,0x82,0x01,0x7c,0x3c,0x02,0xb0,0x03,0x8f,0xa6,0x00,0x88,0x34,0x42,0x01,0x04, -0x84,0xc5,0x00,0x0c,0x02,0x92,0x18,0x21,0x94,0x46,0x00,0x00,0x00,0x05,0x20,0xc0, -0x00,0x85,0x20,0x21,0x00,0x03,0x18,0x80,0x27,0x82,0x90,0x00,0x27,0x85,0x8f,0xf8, -0x00,0x65,0x28,0x21,0x00,0x62,0x18,0x21,0x80,0x71,0x00,0x05,0x80,0x73,0x00,0x04, -0x8f,0xa3,0x00,0x88,0x30,0xd0,0xff,0xff,0x00,0x10,0x3a,0x03,0x32,0x08,0x00,0xff, -0x27,0x82,0x90,0x10,0x00,0x04,0x20,0x80,0x80,0xa6,0x00,0x06,0x00,0x82,0x20,0x21, -0xa4,0x67,0x00,0x44,0xa4,0x68,0x00,0x46,0x8c,0x84,0x00,0x00,0x38,0xc6,0x00,0x00, -0x01,0x00,0x80,0x21,0x00,0x04,0x15,0x02,0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x03, -0x00,0xe6,0x80,0x0a,0x00,0x04,0x14,0x02,0x30,0x50,0x00,0x0f,0x12,0x20,0x01,0x50, -0x02,0x40,0x20,0x21,0x02,0x71,0x10,0x21,0x00,0x50,0x10,0x2a,0x14,0x40,0x00,0xed, -0x02,0x92,0x10,0x21,0x93,0x82,0x8b,0x61,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01, -0x14,0x40,0x00,0xe0,0x02,0x92,0x28,0x21,0x26,0xe2,0x00,0x01,0x30,0x57,0xff,0xff, -0x02,0x40,0xf0,0x21,0x26,0xb5,0xff,0xff,0x16,0xa0,0xff,0xbd,0x02,0xc0,0x90,0x21, -0x16,0xe0,0x00,0xd0,0x00,0x00,0x00,0x00,0x8f,0xa3,0x00,0x98,0x00,0x00,0x00,0x00, -0x2c,0x62,0x00,0x10,0x10,0x40,0x00,0x2e,0x00,0x00,0x00,0x00,0x8f,0xa4,0x00,0x24, -0x00,0x00,0x00,0x00,0x18,0x80,0x00,0x2a,0x24,0x03,0x00,0x01,0x8f,0xa5,0x00,0x1c, -0x27,0x84,0x8f,0xf4,0x94,0xb2,0x00,0x14,0xa0,0xa3,0x00,0x12,0x8f,0xa6,0x00,0x3c, -0x00,0x12,0x10,0xc0,0x00,0x52,0x10,0x21,0x00,0x02,0x80,0x80,0x27,0x82,0x90,0x00, -0x02,0x02,0x10,0x21,0x80,0x43,0x00,0x06,0x02,0x04,0x20,0x21,0x8c,0x85,0x00,0x18, -0x24,0x63,0x00,0x02,0x00,0x03,0x17,0xc2,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x43, -0x00,0x03,0x18,0x40,0x14,0xc0,0x00,0x0e,0x00,0xa3,0x38,0x21,0x27,0x82,0x8f,0xf0, -0x02,0x02,0x10,0x21,0x94,0x43,0x00,0x06,0x8f,0xa8,0x00,0x1c,0x24,0x02,0x00,0x01, -0xa5,0x03,0x00,0x1a,0x7b,0xbe,0x04,0x3c,0x7b,0xb6,0x03,0xfc,0x7b,0xb4,0x03,0xbc, -0x7b,0xb2,0x03,0x7c,0x7b,0xb0,0x03,0x3c,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x88, -0x8f,0xa4,0x00,0x98,0x8f,0xa5,0x00,0x38,0x8f,0xa6,0x00,0x34,0xaf,0xa0,0x00,0x10, -0x0c,0x00,0x09,0x06,0xaf,0xa0,0x00,0x14,0x08,0x00,0x1d,0x4b,0x00,0x00,0x00,0x00, -0x8f,0xa3,0x00,0x44,0x93,0x82,0x81,0x59,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x61, -0x30,0x69,0x00,0x03,0x8f,0xa4,0x00,0x24,0x8f,0xa5,0x00,0x28,0x00,0x00,0x00,0x00, -0x00,0x85,0x10,0x2a,0x10,0x40,0x00,0x8f,0x00,0x00,0x00,0x00,0x8f,0xa6,0x00,0x1c, -0x00,0x00,0x00,0x00,0x90,0xc4,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x83,0x00,0xff, -0x00,0xa3,0x10,0x2a,0x10,0x40,0x00,0x87,0x00,0x00,0x00,0x00,0x8f,0xa8,0x00,0x24, -0x00,0x00,0x00,0x00,0x11,0x00,0x00,0x83,0x00,0x65,0x10,0x23,0x00,0xa8,0x18,0x23, -0x00,0x62,0x10,0x2a,0x14,0x40,0x00,0x7d,0x30,0x63,0x00,0xff,0x00,0x85,0x10,0x23, -0x30,0x42,0x00,0xff,0xaf,0xa2,0x00,0x50,0x8f,0xa2,0x00,0x50,0x00,0x00,0x00,0x00, -0x10,0x40,0x00,0x73,0x00,0x00,0xa8,0x21,0x27,0x8c,0x8f,0xf0,0x3c,0x0b,0x80,0xff, -0x24,0x10,0x00,0x04,0x27,0x91,0x8f,0xf4,0x35,0x6b,0xff,0xff,0x3c,0x0d,0x7f,0x00, -0x27,0x8e,0x90,0x00,0x01,0x80,0x78,0x21,0x00,0x12,0x30,0xc0,0x00,0xd2,0x10,0x21, -0x00,0x02,0x10,0x80,0x00,0x4c,0x10,0x21,0x94,0x42,0x00,0x06,0x8f,0xa3,0x00,0x2c, -0x8f,0xa4,0x00,0x30,0xaf,0xa2,0x00,0x44,0x8f,0xa5,0x00,0x44,0x30,0x49,0x00,0x03, -0x02,0x09,0x10,0x23,0x30,0x42,0x00,0x03,0x00,0xa2,0x10,0x21,0x8f,0xa8,0x00,0x30, -0x24,0x42,0x00,0x04,0x30,0x42,0xff,0xff,0x00,0x64,0x38,0x21,0x01,0x02,0x28,0x23, -0x00,0x62,0x18,0x21,0x00,0x48,0x10,0x2b,0x10,0x40,0x00,0x52,0x00,0x00,0x20,0x21, -0x30,0xe7,0xff,0xff,0x30,0xa4,0xff,0xff,0xaf,0xa7,0x00,0x2c,0x00,0xd2,0x10,0x21, -0x00,0x02,0x10,0x80,0x00,0x51,0x18,0x21,0x8c,0x65,0x00,0x18,0x00,0x04,0x25,0x40, -0x00,0x8d,0x20,0x24,0x8c,0xa8,0x00,0x04,0x00,0x4e,0x18,0x21,0x00,0x4f,0x50,0x21, -0x01,0x0b,0x40,0x24,0x01,0x04,0x40,0x25,0xac,0xa8,0x00,0x04,0x8f,0xa4,0x00,0x98, -0x8f,0xa2,0x00,0x50,0x26,0xb5,0x00,0x01,0xa0,0x64,0x00,0x00,0x8c,0xa4,0x00,0x08, -0x00,0x00,0x00,0x00,0x04,0x81,0x00,0x0c,0x02,0xa2,0x30,0x2a,0x80,0x62,0x00,0x06, -0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21, -0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40,0x00,0xa2,0x38,0x21,0x8f,0xa5,0x00,0x40, -0x00,0x00,0x00,0x00,0xa4,0xe5,0x00,0x00,0x95,0x52,0x00,0x02,0x14,0xc0,0xff,0xc7, -0x00,0x12,0x30,0xc0,0x8f,0xa4,0x00,0x24,0x8f,0xa5,0x00,0x50,0x8f,0xa6,0x00,0x1c, -0x8f,0xa3,0x00,0x2c,0x00,0x85,0x80,0x21,0xa0,0xd0,0x00,0x12,0x00,0x09,0x10,0x23, -0x30,0x42,0x00,0x03,0x8f,0xa8,0x00,0x88,0x00,0x62,0x10,0x23,0xa4,0xc2,0x00,0x1a, -0x85,0x03,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, -0x00,0x02,0x10,0x80,0x27,0x83,0x8f,0xf4,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x18, -0x00,0x00,0x00,0x00,0x8c,0x83,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10, -0x14,0x60,0xff,0x74,0x02,0x00,0x10,0x21,0x8f,0xa3,0x00,0x54,0x8f,0xa4,0x00,0x18, -0x8f,0xa5,0x00,0x24,0x00,0x64,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x08, -0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x00,0x10,0xa0,0x00,0x03,0x00,0x00,0x30,0x21, -0x08,0x00,0x1d,0x51,0x02,0x00,0x10,0x21,0x93,0x82,0x80,0x10,0x00,0x00,0x28,0x21, -0x00,0x00,0x38,0x21,0x0c,0x00,0x21,0xf5,0xaf,0xa2,0x00,0x10,0x08,0x00,0x1d,0x51, -0x02,0x00,0x10,0x21,0x30,0x63,0xff,0xff,0x08,0x00,0x1d,0xa3,0xaf,0xa3,0x00,0x2c, -0x8f,0xa8,0x00,0x44,0x08,0x00,0x1d,0xc5,0x31,0x09,0x00,0x03,0x08,0x00,0x1d,0x7e, -0xaf,0xa3,0x00,0x50,0x8f,0xa6,0x00,0x44,0xaf,0xa0,0x00,0x50,0x08,0x00,0x1d,0xc5, -0x30,0xc9,0x00,0x03,0x8f,0xa5,0x00,0x48,0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x1c, -0x03,0xc0,0x38,0x21,0x0c,0x00,0x1b,0xf6,0xaf,0xb7,0x00,0x10,0x08,0x00,0x1d,0x2e, -0x00,0x00,0x00,0x00,0x00,0x05,0x28,0x80,0x27,0x82,0x8f,0xf0,0x00,0xa2,0x28,0x21, -0x00,0x00,0x20,0x21,0x0c,0x00,0x01,0x4b,0x00,0x00,0x00,0x00,0x08,0x00,0x1d,0x27, -0x26,0xe2,0x00,0x01,0x00,0x02,0x80,0x80,0x27,0x83,0x90,0x00,0x8f,0xa4,0x00,0x1c, -0x02,0x03,0x18,0x21,0x26,0x31,0x00,0x01,0x02,0x40,0x28,0x21,0x0c,0x00,0x1f,0x08, -0xa0,0x71,0x00,0x05,0x14,0x40,0xff,0x13,0x00,0x00,0x00,0x00,0x16,0xe0,0x00,0x4d, -0x03,0xc0,0x38,0x21,0x8f,0xa4,0x00,0x24,0x8f,0xa5,0x00,0x20,0x24,0x02,0x00,0x01, -0x24,0x84,0x00,0x01,0xaf,0xb2,0x00,0x48,0xaf,0xb6,0x00,0x4c,0x02,0xc0,0xf0,0x21, -0x10,0xa2,0x00,0x41,0xaf,0xa4,0x00,0x24,0x27,0x82,0x8f,0xf0,0x02,0x02,0x10,0x21, -0x94,0x42,0x00,0x06,0x8f,0xa4,0x00,0x30,0xaf,0xa0,0x00,0x20,0xaf,0xa2,0x00,0x44, -0x30,0x49,0x00,0x03,0x8f,0xa8,0x00,0x44,0x00,0x09,0x10,0x23,0x30,0x42,0x00,0x03, -0x01,0x02,0x10,0x21,0x24,0x42,0x00,0x04,0x30,0x42,0xff,0xff,0x00,0x44,0x18,0x2b, -0x10,0x60,0x00,0x2b,0x00,0x00,0x00,0x00,0x8f,0xa5,0x00,0x2c,0x00,0x82,0x10,0x23, -0x00,0xa4,0x18,0x21,0x30,0x63,0xff,0xff,0x30,0x44,0xff,0xff,0xaf,0xa3,0x00,0x2c, -0x02,0x92,0x28,0x21,0x00,0x05,0x28,0x80,0x27,0x82,0x8f,0xf4,0x00,0xa2,0x10,0x21, -0x8c,0x46,0x00,0x18,0x3c,0x03,0x80,0xff,0x3c,0x02,0x7f,0x00,0x8c,0xc8,0x00,0x04, -0x00,0x04,0x25,0x40,0x34,0x63,0xff,0xff,0x00,0x82,0x20,0x24,0x01,0x03,0x40,0x24, -0x01,0x04,0x40,0x25,0xac,0xc8,0x00,0x04,0x8f,0xa8,0x00,0x98,0x27,0x82,0x90,0x00, -0x00,0xa2,0x10,0x21,0xa0,0x48,0x00,0x00,0x8c,0xc4,0x00,0x08,0x00,0x00,0x00,0x00, -0x00,0x04,0x27,0xc2,0x10,0x80,0xfe,0xdb,0xaf,0xa4,0x00,0x3c,0x80,0x42,0x00,0x06, -0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21, -0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40,0x00,0xc2,0x38,0x21,0x8f,0xa2,0x00,0x40, -0x00,0x00,0x00,0x00,0xa4,0xe2,0x00,0x00,0x08,0x00,0x1d,0x2a,0x26,0xb5,0xff,0xff, -0x8f,0xa6,0x00,0x2c,0x00,0x00,0x20,0x21,0x00,0xc2,0x10,0x21,0x30,0x42,0xff,0xff, -0x08,0x00,0x1e,0x38,0xaf,0xa2,0x00,0x2c,0x8f,0xa6,0x00,0x1c,0x08,0x00,0x1e,0x22, -0xa4,0xd2,0x00,0x14,0x8f,0xa5,0x00,0x48,0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x1c, -0x0c,0x00,0x1b,0xf6,0xaf,0xb7,0x00,0x10,0x08,0x00,0x1e,0x19,0x00,0x00,0xb8,0x21, -0x0c,0x00,0x12,0x87,0x00,0x00,0x28,0x21,0x00,0x40,0x18,0x21,0x94,0x42,0x00,0x00, -0x00,0x00,0x00,0x00,0x34,0x42,0x08,0x00,0xa4,0x62,0x00,0x00,0x08,0x00,0x1d,0x1e, -0x02,0x71,0x10,0x21,0x02,0x92,0x18,0x21,0x00,0x03,0x80,0x80,0x27,0x82,0x8f,0xf4, -0x02,0x02,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x83,0x00,0x04, -0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10,0x10,0x60,0x00,0x09,0x24,0x06,0x00,0x01, -0x93,0x82,0x8b,0x61,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x10,0x40,0xfe,0xa2, -0x3c,0x04,0x00,0x80,0x27,0x85,0x8f,0xf0,0x08,0x00,0x1e,0x09,0x02,0x05,0x28,0x21, -0x27,0x83,0x90,0x08,0x27,0x82,0x90,0x00,0x02,0x03,0x18,0x21,0x02,0x02,0x10,0x21, -0x90,0x64,0x00,0x00,0x90,0x45,0x00,0x05,0x93,0x83,0x80,0x10,0x00,0x00,0x38,0x21, -0x0c,0x00,0x21,0xf5,0xaf,0xa3,0x00,0x10,0x08,0x00,0x1e,0x80,0x00,0x00,0x00,0x00, -0x27,0x82,0x90,0x08,0x02,0x02,0x10,0x21,0x94,0x43,0x00,0x02,0x8f,0xa6,0x00,0x58, -0x00,0x03,0x19,0x02,0x00,0x66,0x18,0x23,0x30,0x63,0x0f,0xff,0x28,0x62,0x00,0x20, -0x10,0x40,0x00,0x06,0x28,0x62,0x00,0x40,0x8f,0xa8,0x00,0x90,0x00,0x00,0x00,0x00, -0x00,0x68,0x10,0x06,0x08,0x00,0x1c,0xf7,0x30,0x44,0x00,0x01,0x10,0x40,0x00,0x04, -0x00,0x00,0x00,0x00,0x8f,0xa4,0x00,0x94,0x08,0x00,0x1e,0xa1,0x00,0x64,0x10,0x06, -0x08,0x00,0x1c,0xf7,0x00,0x00,0x20,0x21,0x8f,0xa4,0x00,0x98,0x8f,0xa5,0x00,0x38, -0xaf,0xa0,0x00,0x10,0x0c,0x00,0x09,0x06,0xaf,0xa8,0x00,0x14,0x30,0x42,0xff,0xff, -0x08,0x00,0x1c,0xc7,0xaf,0xa2,0x00,0x40,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00, -0x27,0xbd,0xff,0xe0,0x34,0x42,0x00,0x20,0x24,0x63,0x7a,0xc8,0xaf,0xb1,0x00,0x14, -0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x18,0xac,0x43,0x00,0x00,0x90,0x82,0x00,0x0a, -0x00,0x80,0x80,0x21,0x14,0x40,0x00,0x45,0x00,0x00,0x88,0x21,0x92,0x02,0x00,0x04, -0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x3c,0x00,0x00,0x00,0x00,0x12,0x20,0x00,0x18, -0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16,0x92,0x05,0x00,0x0a,0x30,0x42,0x00,0xfc, -0x10,0xa0,0x00,0x03,0xa2,0x02,0x00,0x16,0x34,0x42,0x00,0x01,0xa2,0x02,0x00,0x16, -0x92,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x83,0x00,0xff,0x10,0x60,0x00,0x05, -0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02, -0xa2,0x02,0x00,0x16,0x10,0x60,0x00,0x0a,0x00,0x00,0x00,0x00,0x14,0xa0,0x00,0x08, -0x00,0x00,0x00,0x00,0x96,0x02,0x00,0x00,0xa2,0x00,0x00,0x17,0xa6,0x02,0x00,0x14, -0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20, -0x14,0x80,0x00,0x05,0x24,0x02,0x00,0x01,0x96,0x03,0x00,0x06,0xa2,0x02,0x00,0x17, -0x08,0x00,0x1e,0xdc,0xa6,0x03,0x00,0x14,0x96,0x04,0x00,0x00,0x96,0x05,0x00,0x06, -0x27,0x86,0x8f,0xf0,0x00,0x04,0x10,0xc0,0x00,0x05,0x18,0xc0,0x00,0x44,0x10,0x21, -0x00,0x65,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21, -0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08,0x8c,0x44,0x00,0x08,0x0c,0x00,0x12,0x78, -0x00,0x00,0x00,0x00,0x30,0x43,0x00,0xff,0x10,0x60,0x00,0x04,0xa2,0x02,0x00,0x17, -0x96,0x02,0x00,0x06,0x08,0x00,0x1e,0xdc,0xa6,0x02,0x00,0x14,0x96,0x02,0x00,0x00, -0x08,0x00,0x1e,0xdc,0xa6,0x02,0x00,0x14,0x96,0x05,0x00,0x00,0x0c,0x00,0x1f,0x08, -0x02,0x00,0x20,0x21,0x08,0x00,0x1e,0xc3,0x02,0x22,0x88,0x21,0x94,0x85,0x00,0x06, -0x0c,0x00,0x1f,0x08,0x00,0x00,0x00,0x00,0x08,0x00,0x1e,0xbf,0x00,0x40,0x88,0x21, -0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x7c,0x20, -0x27,0xbd,0xff,0xf0,0xac,0x62,0x00,0x00,0x00,0x00,0x10,0x21,0x03,0xe0,0x00,0x08, -0x27,0xbd,0x00,0x10,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20, -0x24,0x42,0x7c,0x44,0xac,0x62,0x00,0x00,0x90,0x89,0x00,0x0a,0x00,0x80,0x30,0x21, -0x11,0x20,0x00,0x05,0x00,0xa0,0x50,0x21,0x90,0x82,0x00,0x17,0x00,0x00,0x00,0x00, -0x14,0x40,0x00,0x1b,0x00,0x00,0x00,0x00,0x90,0xc7,0x00,0x04,0x00,0x00,0x00,0x00, -0x10,0xe0,0x00,0x1b,0x00,0x00,0x00,0x00,0x94,0xc8,0x00,0x00,0x27,0x83,0x8f,0xf0, -0x93,0x85,0x8b,0x60,0x00,0x08,0x10,0xc0,0x00,0x48,0x10,0x21,0x00,0x02,0x10,0x80, -0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x08,0x00,0xe5,0x28,0x2b,0x10,0xa0,0x00,0x06, -0x01,0x44,0x18,0x23,0x8f,0x82,0x8b,0x78,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x2b, -0x10,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x24,0x03,0x00,0x10,0xa4,0xc8,0x00,0x14, -0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,0x11,0x20,0x00,0x05,0x00,0x00,0x00,0x00, -0x94,0xc2,0x00,0x06,0x24,0x03,0x00,0x08,0x08,0x00,0x1f,0x34,0xa4,0xc2,0x00,0x14, -0x08,0x00,0x1f,0x34,0x00,0x00,0x18,0x21,0x27,0xbd,0xff,0xc8,0xaf,0xb5,0x00,0x2c, -0xaf,0xb4,0x00,0x28,0xaf,0xb3,0x00,0x24,0xaf,0xb0,0x00,0x18,0xaf,0xbf,0x00,0x30, -0xaf,0xb2,0x00,0x20,0xaf,0xb1,0x00,0x1c,0x94,0x91,0x00,0x06,0x00,0x80,0xa0,0x21, -0x3c,0x02,0x80,0x00,0x3c,0x04,0xb0,0x03,0x00,0x11,0xa8,0xc0,0x34,0x84,0x00,0x20, -0x24,0x42,0x7c,0xf8,0x02,0xb1,0x48,0x21,0xac,0x82,0x00,0x00,0x00,0x09,0x48,0x80, -0x24,0x03,0x00,0x01,0x27,0x82,0x90,0x00,0xa2,0x83,0x00,0x12,0x01,0x22,0x10,0x21, -0x27,0x84,0x8f,0xf4,0x01,0x24,0x20,0x21,0x80,0x48,0x00,0x06,0x8c,0x8a,0x00,0x18, -0x27,0x83,0x90,0x10,0x01,0x23,0x48,0x21,0x8d,0x24,0x00,0x00,0x25,0x08,0x00,0x02, -0x8d,0x42,0x00,0x00,0x8d,0x49,0x00,0x04,0x00,0x08,0x17,0xc2,0x8d,0x43,0x00,0x08, -0x01,0x02,0x40,0x21,0x00,0x04,0x25,0xc2,0x00,0x08,0x40,0x43,0x30,0x84,0x00,0x01, -0x00,0x03,0x1f,0xc2,0x00,0x08,0x40,0x40,0x00,0xe0,0x80,0x21,0x00,0x64,0x18,0x24, -0x00,0x09,0x49,0x42,0x01,0x48,0x10,0x21,0x00,0xa0,0x98,0x21,0x00,0xa0,0x20,0x21, -0x00,0x40,0x38,0x21,0x02,0x00,0x28,0x21,0x14,0x60,0x00,0x19,0x31,0x29,0x00,0x01, -0x94,0x42,0x00,0x00,0x02,0xb1,0x88,0x21,0x02,0x00,0x28,0x21,0x00,0x11,0x88,0x80, -0x27,0x90,0x8f,0xf0,0x02,0x30,0x80,0x21,0x96,0x03,0x00,0x06,0x30,0x52,0xff,0xff, -0x02,0x60,0x20,0x21,0x00,0x60,0x30,0x21,0xa6,0x83,0x00,0x1a,0x27,0x82,0x8f,0xf8, -0x0c,0x00,0x08,0xdf,0x02,0x22,0x88,0x21,0x00,0x52,0x10,0x21,0x96,0x03,0x00,0x06, -0xa6,0x22,0x00,0x04,0x8f,0xbf,0x00,0x30,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c, -0x7b,0xb0,0x00,0xfc,0x00,0x60,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38, -0xaf,0xa9,0x00,0x10,0x0c,0x00,0x09,0x06,0xaf,0xa0,0x00,0x14,0x08,0x00,0x1f,0x72, -0x02,0xb1,0x88,0x21,0x27,0xbd,0xff,0xc0,0xaf,0xbe,0x00,0x38,0xaf,0xb7,0x00,0x34, -0xaf,0xb6,0x00,0x30,0xaf,0xb5,0x00,0x2c,0xaf,0xb3,0x00,0x24,0xaf,0xb1,0x00,0x1c, -0xaf,0xbf,0x00,0x3c,0xaf,0xb4,0x00,0x28,0xaf,0xb2,0x00,0x20,0xaf,0xb0,0x00,0x18, -0x94,0x90,0x00,0x00,0x3c,0x08,0xb0,0x03,0x35,0x08,0x00,0x20,0x00,0x10,0x10,0xc0, -0x00,0x50,0x18,0x21,0x00,0x40,0x88,0x21,0x3c,0x02,0x80,0x00,0x00,0x03,0x48,0x80, -0x24,0x42,0x7e,0x34,0x00,0x80,0x98,0x21,0x27,0x84,0x90,0x00,0x01,0x24,0x20,0x21, -0x93,0xb7,0x00,0x53,0xad,0x02,0x00,0x00,0x80,0x83,0x00,0x06,0x27,0x82,0x8f,0xf4, -0x01,0x22,0x10,0x21,0x8c,0x44,0x00,0x18,0x24,0x63,0x00,0x02,0x00,0x03,0x17,0xc2, -0x8c,0x88,0x00,0x08,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x43,0x00,0x03,0x18,0x40, -0xaf,0xa7,0x00,0x4c,0x2c,0xa2,0x00,0x10,0x00,0xa0,0xa8,0x21,0x00,0x83,0x50,0x21, -0x00,0x08,0x47,0xc2,0x00,0xc0,0x58,0x21,0x00,0x00,0xb0,0x21,0x8c,0x92,0x00,0x0c, -0x14,0x40,0x00,0x13,0x00,0x00,0xf0,0x21,0x92,0x67,0x00,0x04,0x24,0x14,0x00,0x01, -0x12,0x87,0x00,0x10,0x02,0x30,0x10,0x21,0x27,0x83,0x90,0x08,0x01,0x23,0x18,0x21, -0x80,0x64,0x00,0x00,0x27,0x83,0xb5,0x60,0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23, -0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21, -0x90,0x44,0x00,0x04,0x00,0x00,0x00,0x00,0x10,0x80,0x00,0x23,0x00,0x00,0x00,0x00, -0x02,0x30,0x10,0x21,0x00,0x02,0x80,0x80,0x24,0x04,0x00,0x01,0x27,0x83,0x90,0x10, -0xa2,0x64,0x00,0x12,0x02,0x03,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x02,0x15,0xc2,0x30,0x42,0x00,0x01,0x01,0x02,0x10,0x24,0x14,0x40,0x00,0x0e, -0x02,0xa0,0x20,0x21,0x27,0x82,0x8f,0xf0,0x02,0x02,0x10,0x21,0x94,0x43,0x00,0x06, -0x00,0x00,0x00,0x00,0xa6,0x63,0x00,0x1a,0x94,0x42,0x00,0x06,0x7b,0xbe,0x01,0xfc, -0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc, -0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,0x8f,0xa5,0x00,0x4c,0x01,0x60,0x30,0x21, -0x01,0x40,0x38,0x21,0xaf,0xa0,0x00,0x10,0x0c,0x00,0x09,0x06,0xaf,0xa0,0x00,0x14, -0x08,0x00,0x1f,0xd9,0x00,0x00,0x00,0x00,0x27,0x83,0x90,0x10,0x01,0x23,0x18,0x21, -0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x15,0xc2,0x30,0x42,0x00,0x01, -0x01,0x02,0x10,0x24,0x14,0x40,0x00,0xaf,0x00,0xa0,0x20,0x21,0x32,0x4f,0x00,0x03, -0x00,0x12,0x10,0x82,0x25,0xe3,0x00,0x0d,0x30,0x45,0x00,0x07,0x00,0x74,0x78,0x04, -0x10,0xa0,0x00,0x0e,0x00,0x00,0x90,0x21,0x27,0x82,0x80,0x1c,0x00,0x15,0x18,0x40, -0x00,0x62,0x18,0x21,0x94,0x64,0x00,0x00,0x24,0xa2,0x00,0x06,0x00,0x54,0x10,0x04, -0x00,0x44,0x00,0x1a,0x14,0x80,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d, -0x00,0x00,0x10,0x12,0x24,0x42,0x00,0x20,0x30,0x52,0xff,0xfc,0x02,0x30,0x10,0x21, -0x27,0x83,0x90,0x00,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x03, -0x00,0x00,0x00,0x00,0x30,0x83,0x00,0xff,0x2c,0x62,0x00,0x0c,0x14,0x40,0x00,0x04, -0x2c,0x62,0x00,0x19,0x30,0x82,0x00,0x0f,0x24,0x43,0x00,0x0c,0x2c,0x62,0x00,0x19, -0x10,0x40,0x00,0x19,0x24,0x0e,0x00,0x20,0x24,0x62,0xff,0xe9,0x2c,0x42,0x00,0x02, -0x14,0x40,0x00,0x15,0x24,0x0e,0x00,0x10,0x24,0x62,0xff,0xeb,0x2c,0x42,0x00,0x02, -0x14,0x40,0x00,0x11,0x24,0x0e,0x00,0x08,0x24,0x02,0x00,0x14,0x10,0x62,0x00,0x0e, -0x24,0x0e,0x00,0x02,0x24,0x62,0xff,0xef,0x2c,0x42,0x00,0x03,0x14,0x40,0x00,0x0a, -0x24,0x0e,0x00,0x10,0x24,0x62,0xff,0xf1,0x2c,0x42,0x00,0x02,0x14,0x40,0x00,0x06, -0x24,0x0e,0x00,0x08,0x24,0x62,0xff,0xf3,0x2c,0x42,0x00,0x02,0x24,0x0e,0x00,0x04, -0x24,0x03,0x00,0x02,0x00,0x62,0x70,0x0a,0x30,0xe2,0x00,0xff,0x00,0x00,0x48,0x21, -0x00,0x00,0x68,0x21,0x10,0x40,0x00,0x6d,0x00,0x00,0x58,0x21,0x3c,0x14,0x80,0xff, -0x27,0x99,0x8f,0xf0,0x01,0xf2,0xc0,0x23,0x36,0x94,0xff,0xff,0x01,0xc9,0x10,0x2a, -0x14,0x40,0x00,0x64,0x24,0x03,0x00,0x04,0x00,0x10,0x28,0xc0,0x00,0xb0,0x10,0x21, -0x00,0x02,0x10,0x80,0x00,0x59,0x10,0x21,0x94,0x56,0x00,0x06,0x00,0x00,0x00,0x00, -0x32,0xcc,0x00,0x03,0x00,0x6c,0x10,0x23,0x30,0x42,0x00,0x03,0x02,0xc2,0x10,0x21, -0x24,0x42,0x00,0x04,0x30,0x51,0xff,0xff,0x02,0x32,0x18,0x2b,0x10,0x60,0x00,0x4d, -0x01,0xf1,0x10,0x23,0x02,0x51,0x10,0x23,0x01,0x78,0x18,0x2b,0x10,0x60,0x00,0x34, -0x30,0x44,0xff,0xff,0x29,0x22,0x00,0x40,0x10,0x40,0x00,0x31,0x01,0x72,0x18,0x21, -0x25,0x22,0x00,0x01,0x00,0x02,0x16,0x00,0x00,0x02,0x4e,0x03,0x00,0xb0,0x10,0x21, -0x00,0x02,0x30,0x80,0x27,0x82,0x8f,0xf4,0x30,0x6b,0xff,0xff,0x00,0xc2,0x18,0x21, -0x8c,0x67,0x00,0x18,0x00,0x04,0x25,0x40,0x3c,0x03,0x7f,0x00,0x8c,0xe2,0x00,0x04, -0x00,0x83,0x20,0x24,0x27,0x83,0x90,0x00,0x00,0x54,0x10,0x24,0x00,0xc3,0x28,0x21, -0x00,0x44,0x10,0x25,0xac,0xe2,0x00,0x04,0x16,0xe0,0x00,0x02,0xa0,0xb5,0x00,0x00, -0xa0,0xb5,0x00,0x03,0x27,0x84,0x90,0x10,0x00,0xc4,0x18,0x21,0x8c,0x62,0x00,0x00, -0x8c,0xe8,0x00,0x08,0x00,0x02,0x15,0xc2,0x00,0x08,0x47,0xc2,0x30,0x42,0x00,0x01, -0x01,0x02,0x10,0x24,0x10,0x40,0x00,0x0a,0x00,0x00,0x00,0x00,0x80,0xa2,0x00,0x06, -0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21, -0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40,0x00,0xe2,0x50,0x21,0xa5,0x5e,0x00,0x00, -0x92,0x62,0x00,0x04,0x25,0xad,0x00,0x01,0x27,0x84,0x8f,0xf0,0x00,0xc4,0x18,0x21, -0x01,0xa2,0x10,0x2a,0x94,0x70,0x00,0x02,0x14,0x40,0xff,0xb8,0x00,0x00,0x00,0x00, -0x96,0x63,0x00,0x14,0x00,0x0c,0x10,0x23,0xa2,0x69,0x00,0x12,0x30,0x42,0x00,0x03, -0x01,0x62,0x10,0x23,0x00,0x03,0x80,0xc0,0x8f,0xa5,0x00,0x4c,0x30,0x4b,0xff,0xff, -0x02,0x03,0x80,0x21,0x27,0x82,0x8f,0xf8,0x00,0x10,0x80,0x80,0xa6,0x6b,0x00,0x1a, -0x02,0xa0,0x20,0x21,0x01,0x60,0x30,0x21,0x01,0x60,0x88,0x21,0x0c,0x00,0x08,0xdf, -0x02,0x02,0x80,0x21,0x00,0x5e,0x10,0x21,0xa6,0x02,0x00,0x04,0x08,0x00,0x1f,0xdf, -0x02,0x20,0x10,0x21,0x01,0x62,0x10,0x2b,0x10,0x40,0xff,0xe9,0x00,0x00,0x20,0x21, -0x29,0x22,0x00,0x40,0x10,0x40,0xff,0xe6,0x01,0x71,0x18,0x21,0x08,0x00,0x20,0x55, -0x25,0x22,0x00,0x01,0x08,0x00,0x20,0x84,0x32,0xcc,0x00,0x03,0x08,0x00,0x20,0x84, -0x00,0x00,0x60,0x21,0x8f,0xa5,0x00,0x4c,0x01,0x40,0x38,0x21,0xaf,0xa0,0x00,0x10, -0x0c,0x00,0x09,0x06,0xaf,0xb4,0x00,0x14,0x92,0x67,0x00,0x04,0x08,0x00,0x1f,0xf7, -0x30,0x5e,0xff,0xff,0x30,0x84,0xff,0xff,0x00,0x04,0x30,0xc0,0x00,0xc4,0x20,0x21, -0x00,0x04,0x20,0x80,0x27,0x82,0x8f,0xf0,0x3c,0x03,0xb0,0x08,0x30,0xa5,0xff,0xff, -0x00,0x82,0x20,0x21,0x00,0xc3,0x30,0x21,0xac,0xc5,0x00,0x00,0x03,0xe0,0x00,0x08, -0xa4,0x85,0x00,0x00,0x30,0x84,0xff,0xff,0x00,0x04,0x30,0xc0,0x00,0xc4,0x30,0x21, -0x27,0x88,0x8f,0xf0,0x00,0x06,0x30,0x80,0x00,0xc8,0x30,0x21,0x94,0xc3,0x00,0x04, -0x3c,0x02,0xb0,0x08,0x3c,0x07,0xb0,0x03,0x00,0x03,0x20,0xc0,0x00,0x83,0x18,0x21, -0x00,0x03,0x18,0x80,0x00,0x82,0x20,0x21,0x3c,0x02,0x80,0x01,0x30,0xa5,0xff,0xff, -0x00,0x68,0x18,0x21,0x34,0xe7,0x00,0x20,0x24,0x42,0x82,0xe4,0xac,0xe2,0x00,0x00, -0xa4,0xc5,0x00,0x02,0xa4,0x65,0x00,0x00,0x03,0xe0,0x00,0x08,0xac,0x85,0x00,0x00, -0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x34,0x42,0x00,0x20,0x24,0x63,0x83,0x40, -0xac,0x43,0x00,0x00,0x90,0x82,0x00,0x10,0x3c,0x08,0xb0,0x03,0x3c,0x09,0xb0,0x06, -0x27,0x87,0x8f,0xf0,0x3c,0x0d,0xb0,0x08,0x34,0x0e,0xff,0xff,0x35,0x08,0x00,0x62, -0x00,0x80,0x30,0x21,0x24,0x0c,0xff,0xff,0x10,0x40,0x00,0x2c,0x35,0x29,0x80,0x20, -0x97,0x82,0x8f,0xe0,0x94,0x85,0x00,0x0c,0x3c,0x0b,0xb0,0x03,0x00,0x02,0x18,0xc0, -0x00,0x62,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x47,0x10,0x21,0xa4,0x45,0x00,0x00, -0x94,0x84,0x00,0x0e,0x00,0x6d,0x18,0x21,0xac,0x65,0x00,0x00,0x00,0x04,0x10,0xc0, -0x00,0x44,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x47,0x10,0x21,0x94,0x45,0x00,0x04, -0x3c,0x0a,0x77,0x77,0x35,0x6b,0x00,0xb4,0x00,0x05,0x10,0xc0,0x00,0x45,0x18,0x21, -0x00,0x03,0x18,0x80,0x00,0x67,0x18,0x21,0x00,0x4d,0x10,0x21,0xac,0x4e,0x00,0x00, -0xa4,0x6e,0x00,0x00,0x95,0x04,0x00,0x00,0x90,0xc3,0x00,0x10,0x24,0x02,0x00,0xff, -0x00,0x44,0x10,0x23,0x00,0x43,0x10,0x2a,0xa7,0x85,0x8f,0xe0,0x10,0x40,0x00,0x04, -0x35,0x4a,0x88,0x88,0xad,0x6a,0x00,0x00,0x90,0xc3,0x00,0x10,0x00,0x00,0x00,0x00, -0x30,0x63,0x00,0xff,0x3c,0x02,0x00,0x40,0x00,0x62,0x18,0x25,0xad,0x23,0x00,0x00, -0xa4,0xcc,0x00,0x0e,0xa4,0xcc,0x00,0x0c,0xa0,0xc0,0x00,0x10,0x03,0xe0,0x00,0x08, -0x00,0x00,0x00,0x00,0x30,0x84,0xff,0xff,0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21, -0x27,0x89,0x8f,0xf0,0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x21,0x97,0x83,0x8f,0xe0, -0x94,0x4a,0x00,0x04,0x3c,0x02,0xb0,0x08,0x00,0x03,0x38,0xc0,0x00,0x0a,0x40,0xc0, -0x00,0xe3,0x18,0x21,0x01,0x0a,0x28,0x21,0x00,0xe2,0x38,0x21,0x01,0x02,0x40,0x21, -0x00,0x03,0x18,0x80,0x00,0x05,0x28,0x80,0x3c,0x06,0xb0,0x03,0x3c,0x02,0x80,0x01, -0x00,0xa9,0x28,0x21,0x00,0x69,0x18,0x21,0x34,0xc6,0x00,0x20,0x34,0x09,0xff,0xff, -0x24,0x42,0x84,0x34,0xac,0xc2,0x00,0x00,0xa4,0x64,0x00,0x00,0xac,0xe4,0x00,0x00, -0xa4,0xa9,0x00,0x00,0xad,0x09,0x00,0x00,0xa7,0x8a,0x8f,0xe0,0x03,0xe0,0x00,0x08, -0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20, -0x24,0x42,0x84,0xb4,0x3c,0x04,0xb0,0x03,0xac,0x62,0x00,0x00,0x34,0x84,0x01,0x10, -0x8c,0x82,0x00,0x00,0x97,0x83,0x81,0x60,0x30,0x42,0xff,0xff,0x10,0x62,0x00,0x16, -0x24,0x0a,0x00,0x01,0xa7,0x82,0x81,0x60,0xaf,0x80,0xb4,0x40,0x00,0x40,0x28,0x21, -0x24,0x06,0x00,0x01,0x27,0x84,0xb4,0x44,0x25,0x43,0xff,0xff,0x00,0x66,0x10,0x04, -0x00,0xa2,0x10,0x24,0x14,0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x8c,0x83,0xff,0xfc, -0x00,0x00,0x00,0x00,0x00,0x66,0x10,0x04,0x00,0xa2,0x10,0x24,0x38,0x42,0x00,0x00, -0x01,0x42,0x18,0x0a,0x25,0x4a,0x00,0x01,0x2d,0x42,0x00,0x14,0xac,0x83,0x00,0x00, -0x14,0x40,0xff,0xf1,0x24,0x84,0x00,0x04,0x3c,0x0b,0xb0,0x03,0x00,0x00,0x50,0x21, -0x3c,0x0c,0x80,0x00,0x27,0x89,0xb4,0x90,0x35,0x6b,0x01,0x20,0x8d,0x68,0x00,0x00, -0x8d,0x23,0x00,0x04,0x01,0x0c,0x10,0x24,0x00,0x02,0x17,0xc2,0x11,0x03,0x00,0x37, -0xa1,0x22,0x00,0xdc,0xa1,0x20,0x00,0xd5,0xa1,0x20,0x00,0xd6,0x01,0x20,0x30,0x21, -0x00,0x00,0x38,0x21,0x00,0x00,0x28,0x21,0x01,0x20,0x20,0x21,0x00,0xa8,0x10,0x06, -0x30,0x42,0x00,0x01,0x10,0xe0,0x00,0x10,0xa0,0x82,0x00,0x0a,0x90,0x82,0x00,0x07, -0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x31,0x24,0xa2,0xff,0xff,0xa0,0x82,0x00,0x08, -0x90,0x82,0x00,0x0a,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x09,0x00,0x00,0x00,0x00, -0x90,0x83,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0x40,0x00,0x43,0x10,0x21, -0x00,0x46,0x10,0x21,0xa0,0x45,0x00,0x09,0x90,0x82,0x00,0x0a,0x00,0x00,0x00,0x00, -0x10,0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x14,0xe0,0x00,0x04,0x00,0x00,0x00,0x00, -0xa0,0xc5,0x00,0xd5,0x24,0x07,0x00,0x01,0xa0,0x85,0x00,0x08,0xa0,0xc5,0x00,0xd6, -0x24,0xa5,0x00,0x01,0x2c,0xa2,0x00,0x1c,0x14,0x40,0xff,0xe0,0x24,0x84,0x00,0x03, -0x90,0xc4,0x00,0xd5,0x00,0x00,0x28,0x21,0x00,0xa4,0x10,0x2b,0x10,0x40,0x00,0x0b, -0x00,0x00,0x00,0x00,0x00,0xc0,0x18,0x21,0xa0,0x64,0x00,0x08,0x90,0xc2,0x00,0xd5, -0x24,0xa5,0x00,0x01,0xa0,0x62,0x00,0x09,0x90,0xc4,0x00,0xd5,0x00,0x00,0x00,0x00, -0x00,0xa4,0x10,0x2b,0x14,0x40,0xff,0xf8,0x24,0x63,0x00,0x03,0x25,0x4a,0x00,0x01, -0x2d,0x42,0x00,0x08,0xad,0x28,0x00,0x04,0x25,0x6b,0x00,0x04,0x14,0x40,0xff,0xbf, -0x25,0x29,0x00,0xec,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x90,0x82,0x00,0x05, -0x08,0x00,0x21,0x68,0xa0,0x82,0x00,0x08,0x97,0x85,0x8b,0x6a,0x3c,0x03,0xb0,0x03, -0x3c,0x02,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x63,0x00,0x20,0x24,0x42,0x86,0x68, -0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x62,0x00,0x00,0x30,0x90,0x00,0xff, -0x00,0x05,0x28,0x42,0x00,0x00,0x48,0x21,0x27,0x8f,0xb4,0x94,0x00,0x00,0x50,0x21, -0x00,0x00,0x58,0x21,0x27,0x98,0xb5,0x74,0x27,0x99,0xb5,0x70,0x27,0x8e,0xb5,0x6e, -0x27,0x8c,0xb4,0x98,0x27,0x8d,0xb4,0xf0,0x27,0x88,0xb5,0x68,0x00,0x0a,0x18,0x80, -0x01,0x6f,0x10,0x21,0xac,0x40,0x00,0x00,0xac,0x45,0x00,0x58,0x00,0x6e,0x20,0x21, -0x00,0x78,0x10,0x21,0xa1,0x00,0xff,0xfc,0xad,0x00,0x00,0x00,0xa1,0x00,0x00,0x04, -0xa1,0x00,0x00,0x05,0xad,0x00,0xff,0xf8,0x00,0x79,0x18,0x21,0x24,0x06,0x00,0x01, -0x24,0xc6,0xff,0xff,0xa0,0x80,0x00,0x00,0xa4,0x60,0x00,0x00,0xac,0x40,0x00,0x00, -0x24,0x63,0x00,0x02,0x24,0x42,0x00,0x04,0x04,0xc1,0xff,0xf9,0x24,0x84,0x00,0x01, -0x00,0x0a,0x10,0x80,0x00,0x4d,0x20,0x21,0x00,0x00,0x30,0x21,0x00,0x4c,0x18,0x21, -0x27,0x87,0x81,0x64,0x8c,0xe2,0x00,0x00,0x24,0xe7,0x00,0x04,0xac,0x82,0x00,0x00, -0xa0,0x66,0x00,0x00,0xa0,0x66,0x00,0x01,0x24,0xc6,0x00,0x01,0x28,0xc2,0x00,0x1c, -0xa0,0x60,0x00,0x02,0x24,0x84,0x00,0x04,0x14,0x40,0xff,0xf6,0x24,0x63,0x00,0x03, -0x25,0x29,0x00,0x01,0x29,0x22,0x00,0x08,0x25,0x4a,0x00,0x3b,0x25,0x08,0x00,0xec, -0x14,0x40,0xff,0xd6,0x25,0x6b,0x00,0xec,0xa7,0x80,0x81,0x60,0x00,0x00,0x48,0x21, -0x27,0x83,0xb4,0x40,0xac,0x69,0x00,0x00,0x25,0x29,0x00,0x01,0x29,0x22,0x00,0x0c, -0x14,0x40,0xff,0xfc,0x24,0x63,0x00,0x04,0x0c,0x00,0x21,0x2d,0x00,0x00,0x00,0x00, -0x2e,0x04,0x00,0x14,0x27,0x83,0xb4,0x90,0x24,0x09,0x00,0x07,0x10,0x80,0x00,0x0a, -0x00,0x00,0x00,0x00,0x90,0x62,0x00,0xd5,0x25,0x29,0xff,0xff,0xa0,0x62,0x00,0x00, -0x05,0x21,0xff,0xfa,0x24,0x63,0x00,0xec,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10, -0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x90,0x62,0x00,0xd6,0x08,0x00,0x21,0xeb, -0x25,0x29,0xff,0xff,0x30,0x84,0x00,0xff,0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23, -0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x27,0x83,0xb4,0x90, -0x00,0x43,0x60,0x21,0x3c,0x04,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0x84,0x00,0x20, -0x24,0x42,0x87,0xd4,0x30,0xc6,0x00,0xff,0x93,0xa9,0x00,0x13,0x30,0xa5,0x00,0xff, -0x30,0xe7,0x00,0xff,0xac,0x82,0x00,0x00,0x10,0xc0,0x00,0xeb,0x25,0x8f,0x00,0xd0, -0x91,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xfc,0x2c,0x43,0x00,0x18, -0x10,0x60,0x00,0xcf,0x3c,0x03,0x80,0x01,0x00,0x02,0x10,0x80,0x24,0x63,0x02,0x5c, -0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08, -0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x2d,0x10,0x40,0x00,0x14,0x00,0x00,0x00,0x00, -0x10,0xa0,0x00,0x0f,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x09, -0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x06,0x00,0x00,0x00,0x00, -0x8d,0x82,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xd0,0x03,0xe0,0x00,0x08, -0xad,0x82,0x00,0xd0,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,0x24,0x42,0xff,0xe0, -0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,0x24,0x42,0x00,0x01,0x10,0xa0,0x00,0x0f, -0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xf9,0x00,0x00,0x00,0x00, -0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x07,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03, -0x14,0xa2,0xff,0xf0,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23, -0x24,0x42,0xff,0xe8,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0, -0x08,0x00,0x22,0x23,0x24,0x42,0x00,0x02,0x10,0xa0,0xff,0xfc,0x00,0x00,0x00,0x00, -0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xe6,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, -0x10,0xa2,0xff,0xf4,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xef,0x00,0x00,0x00,0x00, -0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,0x24,0x42,0xff,0xf8,0x2d,0x22,0x00,0x19, -0x14,0x40,0xff,0xde,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xec,0x00,0x00,0x00,0x00, -0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xd6,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, -0x10,0xa2,0xff,0xe4,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0xf1,0x00,0x00,0x00,0x00, -0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,0x24,0x42,0xff,0xf0,0x2d,0x22,0x00,0x1b, -0x10,0x40,0xff,0xf1,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xdc,0x00,0x00,0x00,0x00, -0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xc6,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, -0x14,0xa2,0xff,0xce,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23, -0x24,0x42,0xff,0xf4,0x2d,0x22,0x00,0x1e,0x10,0x40,0xff,0xe3,0x00,0x00,0x00,0x00, -0x10,0xa0,0xff,0xce,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xc9, -0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xd6,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x34, -0x24,0x02,0x00,0x03,0x2d,0x22,0x00,0x23,0x10,0x40,0xff,0xd7,0x00,0x00,0x00,0x00, -0x10,0xa0,0xff,0xaf,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xbd, -0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xda,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03, -0x14,0xa2,0xff,0x9f,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x25,0x00,0x00,0x00,0x00, -0x2d,0x22,0x00,0x25,0x10,0x40,0xff,0xc8,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xa0, -0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x06,0x00,0x00,0x00,0x00, -0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x97,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x80, -0x24,0x02,0x00,0x03,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,0x24,0x42,0xff,0xfc, -0x2d,0x22,0x00,0x16,0x14,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xa3, -0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x8d,0x00,0x00,0x00,0x00, -0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x9b,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xa8, -0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,0x24,0x42,0xff,0xfa, -0x10,0xa0,0xff,0x96,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x80, -0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x8e,0x00,0x00,0x00,0x00, -0x08,0x00,0x22,0x48,0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x17,0x14,0x40,0xff,0x9e, -0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x97,0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x19, -0x10,0x40,0xff,0xe2,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x84,0x00,0x00,0x00,0x00, -0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x6e,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, -0x10,0xa2,0xff,0x7c,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x89,0x00,0x00,0x00,0x00, -0x08,0x00,0x22,0x25,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0xb4,0x2d,0x22,0x00,0x1b, -0x2d,0x22,0x00,0x1e,0x10,0x40,0xff,0xde,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x73, -0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x5d,0x00,0x00,0x00,0x00, -0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x6b,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x88, -0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x25,0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x23, -0x14,0x40,0xff,0xf2,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x4e,0x00,0x00,0x00,0x00, -0x08,0x00,0x22,0x4c,0x2d,0x22,0x00,0x25,0x08,0x00,0x22,0x85,0x2d,0x22,0x00,0x27, -0x10,0xa0,0xff,0x5e,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x48, -0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x56,0x24,0x02,0x00,0x03, -0x14,0xa2,0xff,0x63,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x91,0x00,0x00,0x00,0x00, -0x2d,0x22,0x00,0x27,0x14,0x40,0xff,0x8e,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x3e, -0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x29,0x14,0x40,0xff,0x89,0x00,0x00,0x00,0x00, -0x08,0x00,0x22,0x2b,0x00,0x00,0x00,0x00,0x91,0x86,0x00,0x00,0x91,0x83,0x00,0xd4, -0x25,0x8d,0x00,0x5c,0x30,0xc4,0x00,0xff,0x00,0x04,0x10,0x40,0x00,0x44,0x10,0x21, -0x00,0x04,0x50,0x80,0x01,0x82,0x58,0x21,0x01,0x8a,0x40,0x21,0x25,0x78,0x00,0x08, -0x10,0x60,0x00,0x37,0x25,0x0e,0x00,0x60,0x2c,0xa2,0x00,0x03,0x14,0x40,0x00,0x25, -0x00,0x00,0x00,0x00,0x91,0x82,0x00,0xdd,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x1e, -0x00,0x00,0x00,0x00,0x27,0x87,0x81,0x64,0x01,0x47,0x10,0x21,0x8c,0x43,0x00,0x00, -0x00,0x00,0x00,0x00,0xad,0x03,0x00,0x60,0x91,0x62,0x00,0x08,0x00,0x00,0x00,0x00, -0x00,0x40,0x30,0x21,0xa1,0x82,0x00,0x00,0x30,0xc2,0x00,0xff,0x00,0x02,0x10,0x80, -0x00,0x47,0x10,0x21,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x18,0x42, -0xad,0xa3,0x00,0x00,0x91,0x84,0x00,0x00,0x8d,0xc5,0x00,0x00,0x00,0x04,0x20,0x80, -0x00,0x87,0x10,0x21,0x8c,0x43,0x00,0x00,0x00,0x05,0x28,0x40,0x00,0x8c,0x20,0x21, -0x00,0x03,0x18,0x80,0x00,0xa3,0x10,0x2b,0x00,0x62,0x28,0x0a,0xac,0x85,0x00,0x60, -0x03,0xe0,0x00,0x08,0xa1,0x80,0x00,0xd4,0x27,0x87,0x81,0x64,0x08,0x00,0x23,0x0e, -0xa1,0x80,0x00,0xdd,0x27,0x82,0x81,0xd4,0x8d,0x83,0x00,0xd8,0x00,0x82,0x10,0x21, -0x90,0x44,0x00,0x00,0x24,0x63,0x00,0x01,0x00,0x64,0x20,0x2b,0x14,0x80,0xff,0x0d, -0xad,0x83,0x00,0xd8,0x8d,0x02,0x00,0x60,0xa1,0x80,0x00,0xd4,0x00,0x02,0x1f,0xc2, -0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x03,0xe0,0x00,0x08,0xad,0x82,0x00,0x5c, -0x10,0xe0,0x00,0x1a,0x24,0x83,0xff,0xfc,0x2c,0x62,0x00,0x18,0x10,0x40,0x01,0x18, -0x00,0x03,0x10,0x80,0x3c,0x03,0x80,0x01,0x24,0x63,0x02,0xbc,0x00,0x43,0x10,0x21, -0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00, -0x2d,0x22,0x00,0x2d,0x10,0x40,0x00,0x5f,0x00,0x00,0x00,0x00,0x10,0xa0,0x00,0x5a, -0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x54,0x00,0x00,0x00,0x00, -0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x51,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0, -0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xd0,0xad,0x82,0x00,0xd0,0x8d,0xe3,0x00,0x00, -0x8d,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21,0xad,0xa2,0x00,0x00, -0xad,0xe0,0x00,0x00,0x8d,0xa3,0x00,0x00,0x8d,0xc4,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x83,0x10,0x2a,0x10,0x40,0x00,0x22,0x00,0x00,0x00,0x00,0x93,0x05,0x00,0x01, -0x91,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x45,0x00,0x05,0x24,0x02,0x00,0x01, -0xa1,0x85,0x00,0x00,0xa1,0x82,0x00,0xd4,0x03,0xe0,0x00,0x08,0xad,0x80,0x00,0xd8, -0x91,0x82,0x00,0xdd,0x24,0x03,0x00,0x01,0x10,0x43,0x00,0x05,0x00,0x00,0x00,0x00, -0xa1,0x83,0x00,0xd4,0xad,0x80,0x00,0xd8,0x03,0xe0,0x00,0x08,0xa1,0x83,0x00,0xdd, -0x00,0x04,0x17,0xc2,0x00,0x82,0x10,0x21,0x00,0x02,0x10,0x43,0xad,0xa2,0x00,0x00, -0x91,0x83,0x00,0x00,0x27,0x82,0x81,0x64,0x8d,0xc5,0x00,0x00,0x00,0x03,0x18,0x80, -0x00,0x62,0x18,0x21,0x8c,0x64,0x00,0x00,0x00,0x05,0x28,0x40,0x00,0x04,0x18,0x80, -0x00,0xa3,0x10,0x2b,0x00,0x62,0x28,0x0a,0x08,0x00,0x23,0x20,0xad,0xc5,0x00,0x00, -0x97,0x82,0x8b,0x6c,0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x2a,0x10,0x40,0xfe,0xb9, -0x00,0x00,0x00,0x00,0x91,0x82,0x00,0xdd,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x15, -0x00,0x00,0x00,0x00,0x91,0x83,0x00,0x00,0x27,0x82,0x81,0x64,0x00,0x03,0x18,0x80, -0x00,0x62,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x6c,0x18,0x21,0xac,0x64,0x00,0x60, -0x93,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x10,0x80,0x01,0x82,0x10,0x21, -0x24,0x4e,0x00,0x60,0xa1,0x85,0x00,0x00,0x8d,0xc2,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x03,0xe0,0x00,0x08, -0xad,0xa2,0x00,0x00,0x08,0x00,0x23,0x92,0xa1,0x80,0x00,0xdd,0x8d,0x82,0x00,0xd0, -0x08,0x00,0x23,0x4e,0x24,0x42,0xff,0xe0,0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e, -0x24,0x42,0x00,0x01,0x10,0xa0,0x00,0x0d,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, -0x10,0xa2,0xff,0xf9,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xa7, -0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xf0,0x00,0x00,0x00,0x00, -0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e,0x24,0x42,0xff,0xe8,0x8d,0x82,0x00,0xd0, -0x08,0x00,0x23,0x4e,0x24,0x42,0x00,0x02,0x10,0xa0,0xff,0xfc,0x00,0x00,0x00,0x00, -0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xe8,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, -0x10,0xa2,0xff,0x96,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xf1,0x00,0x00,0x00,0x00, -0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e,0x24,0x42,0xff,0xf8,0x2d,0x22,0x00,0x19, -0x14,0x40,0xff,0xe0,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xec,0x00,0x00,0x00,0x00, -0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xd8,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, -0x10,0xa2,0xff,0x86,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0xf1,0x00,0x00,0x00,0x00, -0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e,0x24,0x42,0xff,0xf0,0x2d,0x22,0x00,0x1b, -0x10,0x40,0xff,0xf1,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xdc,0x00,0x00,0x00,0x00, -0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xc8,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, -0x14,0xa2,0xff,0xd0,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e, -0x24,0x42,0xff,0xf4,0x2d,0x22,0x00,0x1e,0x10,0x40,0xff,0xe3,0x00,0x00,0x00,0x00, -0x10,0xa0,0xff,0xce,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x6b, -0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xd6,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0xaa, -0x24,0x02,0x00,0x03,0x2d,0x22,0x00,0x23,0x10,0x40,0xff,0xd7,0x00,0x00,0x00,0x00, -0x10,0xa0,0xff,0xb1,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x5f, -0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xda,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03, -0x14,0xa2,0xff,0x56,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0x9b,0x00,0x00,0x00,0x00, -0x2d,0x22,0x00,0x25,0x10,0x40,0xff,0xc8,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xa2, -0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x06,0x00,0x00,0x00,0x00, -0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x99,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0xf4, -0x24,0x02,0x00,0x03,0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e,0x24,0x42,0xff,0xfc, -0x2d,0x22,0x00,0x16,0x14,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xa3, -0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x8f,0x00,0x00,0x00,0x00, -0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x3d,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xa8, -0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e,0x24,0x42,0xff,0xfa, -0x10,0xa0,0xff,0x96,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x82, -0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x30,0x00,0x00,0x00,0x00, -0x08,0x00,0x23,0xbc,0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x17,0x14,0x40,0xff,0x9e, -0x00,0x00,0x00,0x00,0x08,0x00,0x24,0x0b,0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x19, -0x10,0x40,0xff,0xe2,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x84,0x00,0x00,0x00,0x00, -0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x70,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, -0x10,0xa2,0xff,0x1e,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x89,0x00,0x00,0x00,0x00, -0x08,0x00,0x23,0x9b,0x00,0x00,0x00,0x00,0x08,0x00,0x24,0x28,0x2d,0x22,0x00,0x1b, -0x2d,0x22,0x00,0x1e,0x10,0x40,0xff,0xde,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x73, -0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x5f,0x00,0x00,0x00,0x00, -0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x0d,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x88, -0x00,0x00,0x00,0x00,0x08,0x00,0x23,0x9b,0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x23, -0x14,0x40,0xff,0xf2,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0xc2,0x00,0x00,0x00,0x00, -0x08,0x00,0x23,0xc0,0x2d,0x22,0x00,0x25,0x08,0x00,0x23,0xf9,0x2d,0x22,0x00,0x27, -0x10,0xa0,0xff,0x5e,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x4a, -0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xfe,0xf8,0x24,0x02,0x00,0x03, -0x14,0xa2,0xff,0x63,0x00,0x00,0x00,0x00,0x08,0x00,0x24,0x05,0x00,0x00,0x00,0x00, -0x2d,0x22,0x00,0x27,0x14,0x40,0xff,0x8e,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0xb2, -0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x29,0x14,0x40,0xff,0x89,0x00,0x00,0x00,0x00, -0x08,0x00,0x23,0xa1,0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xe8,0x3c,0x02,0xb0,0x03, -0xaf,0xbf,0x00,0x14,0xaf,0xb0,0x00,0x10,0x34,0x42,0x01,0x18,0x3c,0x03,0xb0,0x03, -0x8c,0x50,0x00,0x00,0x34,0x63,0x01,0x2c,0x90,0x62,0x00,0x00,0x32,0x05,0x00,0x01, -0xa3,0x82,0x80,0x10,0x14,0xa0,0x00,0x14,0x30,0x44,0x00,0xff,0x32,0x02,0x01,0x00, -0x14,0x40,0x00,0x09,0x00,0x00,0x00,0x00,0x32,0x02,0x08,0x00,0x10,0x40,0x00,0x02, -0x24,0x02,0x00,0x01,0xa3,0x82,0xbc,0x08,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10, -0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x05,0x39,0x00,0x00,0x00,0x00, -0x26,0x02,0xff,0x00,0xa3,0x80,0xbc,0x08,0x3c,0x01,0xb0,0x03,0xac,0x22,0x01,0x18, -0x08,0x00,0x24,0x77,0x32,0x02,0x08,0x00,0x0c,0x00,0x21,0x9a,0x00,0x00,0x00,0x00, -0x26,0x02,0xff,0xff,0x3c,0x01,0xb0,0x03,0xac,0x22,0x01,0x18,0x08,0x00,0x24,0x74, -0x32,0x02,0x01,0x00,0x27,0xbd,0xff,0xe0,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0, -0xaf,0xbf,0x00,0x18,0x8c,0x43,0x00,0x00,0x3c,0x02,0x00,0x40,0x24,0x07,0x0f,0xff, -0x00,0x03,0x33,0x02,0x00,0x03,0x2d,0x02,0x00,0x03,0x43,0x02,0x30,0x69,0x0f,0xff, -0x00,0x62,0x18,0x24,0x30,0xa5,0x00,0x03,0x30,0xc6,0x00,0xff,0x10,0x60,0x00,0x08, -0x31,0x08,0x00,0xff,0x01,0x00,0x30,0x21,0x0c,0x00,0x25,0x38,0xaf,0xa9,0x00,0x10, -0x8f,0xbf,0x00,0x18,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20, -0x0c,0x00,0x25,0x8a,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0xd4, -0x08,0x00,0x24,0xa0,0xac,0x62,0x00,0x00,0x27,0xbd,0xff,0xc0,0xaf,0xb6,0x00,0x30, -0xaf,0xb3,0x00,0x24,0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,0xaf,0xbf,0x00,0x3c, -0xaf,0xbe,0x00,0x38,0xaf,0xb7,0x00,0x34,0xaf,0xb5,0x00,0x2c,0xaf,0xb4,0x00,0x28, -0xaf,0xb2,0x00,0x20,0x0c,0x00,0x17,0xc8,0x00,0x80,0x80,0x21,0x00,0x00,0xb0,0x21, -0x00,0x00,0x88,0x21,0x10,0x40,0x00,0x12,0x00,0x00,0x98,0x21,0x3c,0x02,0xb0,0x03, -0x3c,0x03,0xb0,0x03,0x3c,0x04,0xb0,0x03,0x24,0x05,0x00,0x01,0x34,0x42,0x00,0xbc, -0x34,0x63,0x00,0xbb,0x34,0x84,0x00,0xba,0xa4,0x40,0x00,0x00,0xa0,0x65,0x00,0x00, -0xa0,0x85,0x00,0x00,0x7b,0xbe,0x01,0xfc,0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c, -0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40, -0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x47,0x90,0x44,0x00,0x00,0x00,0x10,0x1a,0x02, -0x3c,0x15,0xfd,0xff,0x30,0x84,0x00,0xff,0xa0,0x50,0x00,0x00,0x30,0x74,0x00,0x0f, -0xaf,0xa4,0x00,0x10,0x00,0x00,0x90,0x21,0x3c,0x17,0x02,0x00,0x36,0xb5,0xff,0xff, -0x3c,0x1e,0xb0,0x03,0x0c,0x00,0x06,0xce,0x24,0x04,0x04,0x00,0x00,0x57,0x10,0x25, -0x00,0x40,0x28,0x21,0x0c,0x00,0x06,0xc1,0x24,0x04,0x04,0x00,0x00,0x00,0x80,0x21, -0x0c,0x00,0x26,0x52,0x00,0x00,0x00,0x00,0x26,0x03,0x00,0x01,0x30,0x70,0x00,0xff, -0x10,0x40,0x00,0x47,0x2e,0x03,0x00,0x02,0x14,0x60,0xff,0xf9,0x00,0x00,0x00,0x00, -0x0c,0x00,0x06,0xce,0x24,0x04,0x04,0x00,0x00,0x55,0x10,0x24,0x00,0x40,0x28,0x21, -0x0c,0x00,0x06,0xc1,0x24,0x04,0x04,0x00,0x24,0x02,0x00,0x01,0x12,0x82,0x00,0x38, -0x00,0x00,0x00,0x00,0x12,0x80,0x00,0x36,0x00,0x00,0x00,0x00,0x32,0x22,0x00,0x60, -0x32,0x23,0x0c,0x00,0x00,0x03,0x1a,0x02,0x3c,0x05,0x00,0x60,0x00,0x02,0x11,0x42, -0x02,0x25,0x20,0x24,0x00,0x43,0x10,0x25,0x3c,0x03,0x04,0x00,0x02,0x23,0x28,0x24, -0x00,0x04,0x24,0x42,0x00,0x44,0x10,0x25,0x00,0x05,0x2d,0x02,0x00,0x45,0x88,0x25, -0x12,0x20,0x00,0x05,0x26,0x42,0x00,0x01,0x26,0xc2,0x00,0x01,0x30,0x56,0x00,0xff, -0x02,0x71,0x98,0x21,0x26,0x42,0x00,0x01,0x02,0x5e,0x20,0x21,0x30,0x52,0x00,0xff, -0x2e,0x43,0x00,0x05,0xa0,0x91,0x00,0xd8,0x14,0x60,0xff,0xce,0x3c,0x02,0xb0,0x03, -0x8f,0xa5,0x00,0x10,0x34,0x42,0x01,0x47,0xa0,0x45,0x00,0x00,0x12,0x60,0x00,0x0e, -0x3c,0x02,0xb0,0x03,0x12,0xc0,0x00,0x0d,0x34,0x42,0x00,0xbc,0x00,0x13,0x10,0x40, -0x00,0x53,0x10,0x21,0x00,0x02,0x10,0xc0,0x00,0x53,0x10,0x21,0x00,0x02,0x98,0x80, -0x02,0x76,0x00,0x1b,0x16,0xc0,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d, -0x00,0x00,0x98,0x12,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xbc,0x3c,0x03,0xb0,0x03, -0x3c,0x04,0xb0,0x03,0xa4,0x53,0x00,0x00,0x34,0x63,0x00,0xbb,0x34,0x84,0x00,0xba, -0x24,0x02,0x00,0x01,0xa0,0x60,0x00,0x00,0x08,0x00,0x24,0xc5,0xa0,0x82,0x00,0x00, -0x0c,0x00,0x06,0xce,0x24,0x04,0x04,0xfc,0x08,0x00,0x24,0xf3,0x00,0x40,0x88,0x21, -0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0xbc,0x3c,0x04,0xb0,0x03,0x3c,0x05,0xb0,0x03, -0xa4,0x60,0x00,0x00,0x34,0x84,0x00,0xbb,0x34,0xa5,0x00,0xba,0x24,0x02,0x00,0x02, -0x24,0x03,0x00,0x01,0xa0,0x82,0x00,0x00,0x08,0x00,0x24,0xc5,0xa0,0xa3,0x00,0x00, -0x27,0xbd,0xff,0xd8,0xaf,0xb0,0x00,0x10,0x30,0xd0,0x00,0xff,0x2e,0x02,0x00,0x2e, -0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c, -0x30,0xb1,0x00,0xff,0x14,0x40,0x00,0x06,0x00,0x80,0x90,0x21,0x8f,0xbf,0x00,0x20, -0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28, -0x2e,0x13,0x00,0x10,0x24,0x05,0x00,0x14,0x0c,0x00,0x13,0xa0,0x24,0x06,0x01,0x07, -0x12,0x60,0x00,0x38,0x02,0x00,0x30,0x21,0x8f,0xa2,0x00,0x38,0x30,0xc3,0x00,0x3f, -0x3c,0x04,0xb0,0x09,0x00,0x02,0x14,0x00,0x00,0x43,0x30,0x25,0x34,0x84,0x01,0x60, -0x90,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xfd,0x24,0x02,0x00,0x01, -0x12,0x22,0x00,0x2a,0x2a,0x22,0x00,0x02,0x14,0x40,0x00,0x24,0x24,0x02,0x00,0x02, -0x12,0x22,0x00,0x20,0x24,0x02,0x00,0x03,0x12,0x22,0x00,0x19,0x00,0x00,0x00,0x00, -0x16,0x60,0xff,0xe2,0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x13,0x2a,0x22,0x00,0x02, -0x14,0x40,0x00,0x0d,0x24,0x02,0x00,0x02,0x12,0x22,0x00,0x09,0x24,0x02,0x00,0x03, -0x16,0x22,0xff,0xda,0x00,0x00,0x00,0x00,0x24,0x04,0x08,0x4c,0x24,0x05,0xff,0xff, -0x0c,0x00,0x13,0x5b,0x3c,0x06,0x0c,0xb8,0x08,0x00,0x25,0x43,0x00,0x00,0x00,0x00, -0x08,0x00,0x25,0x6b,0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xd0,0x00,0x00,0x00,0x00, -0x08,0x00,0x25,0x6b,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0x6b,0x24,0x04,0x08,0x44, -0x24,0x04,0x08,0x4c,0x0c,0x00,0x13,0x5b,0x24,0x05,0xff,0xff,0x08,0x00,0x25,0x60, -0x00,0x00,0x00,0x00,0x08,0x00,0x25,0x79,0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xe0, -0x00,0x00,0x00,0x00,0x08,0x00,0x25,0x79,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0x79, -0x24,0x04,0x08,0x44,0x02,0x40,0x20,0x21,0x0c,0x00,0x25,0xca,0x02,0x20,0x28,0x21, -0x08,0x00,0x25,0x4e,0x00,0x40,0x30,0x21,0x27,0xbd,0xff,0xd8,0x2c,0xc2,0x00,0x2e, -0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x20, -0xaf,0xb3,0x00,0x1c,0x00,0xc0,0x80,0x21,0x30,0xb1,0x00,0xff,0x00,0x80,0x90,0x21, -0x14,0x40,0x00,0x07,0x00,0x00,0x18,0x21,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc, -0x7b,0xb0,0x00,0xbc,0x00,0x60,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28, -0x2e,0x13,0x00,0x10,0x24,0x05,0x00,0x14,0x0c,0x00,0x13,0xa0,0x24,0x06,0x01,0x07, -0x12,0x60,0x00,0x24,0x02,0x00,0x30,0x21,0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60, -0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xfd,0x30,0xc5,0x00,0x3f, -0x0c,0x00,0x26,0x07,0x02,0x20,0x20,0x21,0x16,0x60,0x00,0x0a,0x00,0x40,0x80,0x21, -0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x15,0x2a,0x22,0x00,0x02,0x14,0x40,0x00,0x0f, -0x24,0x02,0x00,0x02,0x12,0x22,0x00,0x0b,0x24,0x02,0x00,0x03,0x12,0x22,0x00,0x03, -0x00,0x00,0x00,0x00,0x08,0x00,0x25,0x96,0x02,0x00,0x18,0x21,0x24,0x04,0x08,0x4c, -0x24,0x05,0xff,0xff,0x0c,0x00,0x13,0x5b,0x3c,0x06,0x0c,0xb8,0x08,0x00,0x25,0x96, -0x02,0x00,0x18,0x21,0x08,0x00,0x25,0xb8,0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xf5, -0x00,0x00,0x00,0x00,0x08,0x00,0x25,0xb8,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0xb8, -0x24,0x04,0x08,0x44,0x02,0x40,0x20,0x21,0x0c,0x00,0x25,0xca,0x02,0x20,0x28,0x21, -0x08,0x00,0x25,0xa2,0x00,0x40,0x30,0x21,0x27,0xbd,0xff,0xe8,0x2c,0xc2,0x00,0x1f, -0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0x00,0xc0,0x80,0x21,0x14,0x40,0x00,0x1d, -0x30,0xa5,0x00,0xff,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x18,0x28,0xa2,0x00,0x02, -0x14,0x40,0x00,0x12,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x0e,0x24,0x02,0x00,0x03, -0x10,0xa2,0x00,0x07,0x24,0x04,0x08,0x4c,0x26,0x10,0xff,0xe2,0x02,0x00,0x10,0x21, -0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18, -0x24,0x05,0xff,0xff,0x0c,0x00,0x13,0x5b,0x3c,0x06,0x0d,0xf8,0x08,0x00,0x25,0xdb, -0x26,0x10,0xff,0xe2,0x08,0x00,0x25,0xe0,0x24,0x04,0x08,0x48,0x14,0xa0,0xff,0xf2, -0x24,0x04,0x08,0x40,0x08,0x00,0x25,0xe1,0x24,0x05,0xff,0xff,0x08,0x00,0x25,0xe0, -0x24,0x04,0x08,0x44,0x2c,0xc2,0x00,0x10,0x14,0x40,0xff,0xec,0x24,0x02,0x00,0x01, -0x10,0xa2,0x00,0x14,0x28,0xa2,0x00,0x02,0x14,0x40,0x00,0x0e,0x24,0x02,0x00,0x02, -0x10,0xa2,0x00,0x0a,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x03,0x24,0x04,0x08,0x4c, -0x08,0x00,0x25,0xdb,0x26,0x10,0xff,0xf1,0x24,0x05,0xff,0xff,0x0c,0x00,0x13,0x5b, -0x3c,0x06,0x0d,0xb8,0x08,0x00,0x25,0xdb,0x26,0x10,0xff,0xf1,0x08,0x00,0x25,0xfa, -0x24,0x04,0x08,0x48,0x14,0xa0,0xff,0xf6,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0xfb, -0x24,0x05,0xff,0xff,0x08,0x00,0x25,0xfa,0x24,0x04,0x08,0x44,0x27,0xbd,0xff,0xe8, -0x30,0x84,0x00,0xff,0x24,0x02,0x00,0x01,0x10,0x82,0x00,0x39,0xaf,0xbf,0x00,0x10, -0x28,0x82,0x00,0x02,0x14,0x40,0x00,0x27,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, -0x10,0x82,0x00,0x17,0x00,0xa0,0x30,0x21,0x24,0x02,0x00,0x03,0x10,0x82,0x00,0x05, -0x24,0x04,0x08,0x3c,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, -0x27,0xbd,0x00,0x18,0x0c,0x00,0x13,0x5b,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x3c, -0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5b,0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x3c, -0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x01,0x24,0x04,0x08,0xac, -0x0c,0x00,0x13,0x3d,0x24,0x05,0x0f,0xff,0x08,0x00,0x26,0x15,0x00,0x00,0x00,0x00, -0x24,0x04,0x08,0x34,0x0c,0x00,0x13,0x5b,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x34, -0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5b,0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x34, -0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x01,0x08,0x00,0x26,0x24, -0x24,0x04,0x08,0xa8,0x14,0x80,0xff,0xdf,0x00,0xa0,0x30,0x21,0x24,0x04,0x08,0x24, -0x0c,0x00,0x13,0x5b,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x24,0x3c,0x05,0x80,0x00, -0x0c,0x00,0x13,0x5b,0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x24,0x3c,0x05,0x80,0x00, -0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x01,0x08,0x00,0x26,0x24,0x24,0x04,0x08,0xa0, -0x00,0xa0,0x30,0x21,0x24,0x04,0x08,0x2c,0x0c,0x00,0x13,0x5b,0x3c,0x05,0x3f,0x00, -0x24,0x04,0x08,0x2c,0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5b,0x00,0x00,0x30,0x21, -0x24,0x04,0x08,0x2c,0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x01, -0x08,0x00,0x26,0x24,0x24,0x04,0x08,0xa4,0x3c,0x05,0x00,0x14,0x3c,0x02,0xb0,0x05, -0x34,0x42,0x04,0x20,0x3c,0x06,0xc0,0x00,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05, -0x34,0xa5,0x17,0x09,0xac,0x45,0x00,0x00,0x34,0xc6,0x05,0x07,0x34,0x63,0x04,0x24, -0x34,0x84,0x02,0x28,0x3c,0x07,0xb0,0x05,0x24,0x02,0x00,0x20,0xac,0x66,0x00,0x00, -0x34,0xe7,0x04,0x50,0xa0,0x82,0x00,0x00,0x90,0xe2,0x00,0x00,0x00,0x00,0x00,0x00, -0x30,0x42,0x00,0x03,0x10,0x40,0xff,0xfc,0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08, -0x00,0x00,0x00,0x00,0x93,0x85,0x81,0xf1,0x24,0x02,0x00,0x01,0x14,0xa2,0x00,0x51, -0x00,0x80,0x40,0x21,0x8c,0x89,0x00,0x04,0x3c,0x03,0xb0,0x01,0x01,0x23,0x30,0x21, -0x8c,0xc2,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x08,0x10,0x45,0x00,0x59, -0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x38,0x24,0x03,0x00,0xb4,0x30,0x44,0x00,0xff, -0x10,0x83,0x00,0x61,0x24,0x02,0x00,0xc4,0x10,0x82,0x00,0x54,0x24,0x02,0x00,0x94, -0x10,0x82,0x00,0x45,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x38,0x00,0x00,0x00,0x00, -0x30,0x47,0xff,0xff,0x30,0xe3,0x40,0xff,0x24,0x02,0x40,0x88,0x14,0x62,0x00,0x39, -0x30,0xe3,0x03,0x00,0x24,0x02,0x03,0x00,0x10,0x62,0x00,0x38,0x00,0x00,0x00,0x00, -0x94,0xc2,0x00,0x56,0x00,0x00,0x00,0x00,0x30,0x47,0xff,0xff,0x30,0xe2,0x00,0x80, -0x14,0x40,0x00,0x30,0x3c,0x02,0xb0,0x01,0x01,0x22,0x30,0x21,0x94,0xc3,0x00,0x60, -0x24,0x02,0x00,0x08,0x14,0x43,0x00,0x3b,0x00,0x00,0x00,0x00,0x90,0xc2,0x00,0x62, -0x24,0x03,0x00,0x04,0x00,0x02,0x39,0x02,0x10,0xe3,0x00,0x15,0x24,0x02,0x00,0x06, -0x14,0xe2,0x00,0x34,0x00,0x00,0x00,0x00,0x8d,0x05,0x01,0xac,0x94,0xc4,0x00,0x66, -0x27,0x82,0x89,0x58,0x00,0x05,0x28,0x80,0x30,0x87,0xff,0xff,0x00,0xa2,0x28,0x21, -0x00,0x07,0x1a,0x00,0x8c,0xa4,0x00,0x00,0x00,0x07,0x12,0x02,0x00,0x43,0x10,0x25, -0x24,0x42,0x00,0x5e,0x24,0x03,0xc0,0x00,0x30,0x47,0xff,0xff,0x00,0x83,0x20,0x24, -0x00,0x87,0x20,0x25,0xac,0xa4,0x00,0x00,0x08,0x00,0x26,0xcd,0xad,0x07,0x00,0x10, -0x8d,0x05,0x01,0xac,0x94,0xc4,0x00,0x64,0x27,0x82,0x89,0x58,0x00,0x05,0x28,0x80, -0x30,0x87,0xff,0xff,0x00,0xa2,0x28,0x21,0x00,0x07,0x1a,0x00,0x8c,0xa4,0x00,0x00, -0x00,0x07,0x12,0x02,0x00,0x43,0x10,0x25,0x24,0x42,0x00,0x36,0x3c,0x03,0xff,0xff, -0x30,0x47,0xff,0xff,0x00,0x83,0x20,0x24,0x00,0x87,0x20,0x25,0xac,0xa4,0x00,0x00, -0xad,0x07,0x00,0x10,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x50, -0x08,0x00,0x26,0x8b,0x30,0x47,0xff,0xff,0x8d,0x04,0x01,0xac,0x27,0x83,0x89,0x58, -0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00,0x3c,0x03,0xff,0xff, -0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x2e,0xac,0x82,0x00,0x00,0x24,0x03,0x00,0x2e, -0xad,0x03,0x00,0x10,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8d,0x04,0x01,0xac, -0x27,0x83,0x89,0x58,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00, -0x3c,0x03,0xff,0xff,0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x0e,0x24,0x03,0x00,0x0e, -0x08,0x00,0x26,0xcc,0xac,0x82,0x00,0x00,0x8d,0x04,0x01,0xac,0x27,0x83,0x89,0x58, -0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00,0x3c,0x03,0xff,0xff, -0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x14,0x24,0x03,0x00,0x14,0x08,0x00,0x26,0xcc, -0xac,0x82,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xc6,0x00,0xff, -0x00,0x06,0x48,0x40,0x01,0x26,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x8b,0xbc,0x20, -0x27,0x83,0xbc,0x26,0x00,0x4b,0x40,0x21,0x00,0x43,0x10,0x21,0x94,0x47,0x00,0x00, -0x30,0xa2,0x3f,0xff,0x10,0xe2,0x00,0x29,0x30,0x8a,0xff,0xff,0x95,0x02,0x00,0x02, -0x24,0x03,0x00,0x01,0x00,0x02,0x11,0x82,0x30,0x42,0x00,0x01,0x10,0x43,0x00,0x18, -0x00,0x00,0x00,0x00,0x01,0x26,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x4b,0x30,0x21, -0x94,0xc4,0x00,0x02,0x27,0x83,0xbc,0x26,0x27,0x85,0xbc,0x24,0x00,0x45,0x28,0x21, -0x30,0x84,0xff,0xdf,0x00,0x43,0x10,0x21,0xa4,0xc4,0x00,0x02,0xa4,0x40,0x00,0x00, -0xa4,0xa0,0x00,0x00,0x94,0xc3,0x00,0x02,0x3c,0x04,0xb0,0x01,0x01,0x44,0x20,0x21, -0x30,0x63,0xff,0xbf,0xa4,0xc3,0x00,0x02,0xa0,0xc0,0x00,0x00,0x8c,0x82,0x00,0x04, -0x24,0x03,0xf0,0xff,0x00,0x43,0x10,0x24,0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x04, -0x24,0x02,0xc0,0x00,0x91,0x04,0x00,0x01,0x00,0xa2,0x10,0x24,0x00,0x47,0x28,0x25, -0x3c,0x03,0xb0,0x01,0x24,0x02,0x00,0x02,0x14,0x82,0xff,0xe2,0x01,0x43,0x18,0x21, -0xac,0x65,0x00,0x00,0x08,0x00,0x26,0xfa,0x01,0x26,0x10,0x21,0x08,0x00,0x26,0xfa, -0x01,0x26,0x10,0x21,0x93,0x83,0x81,0xf1,0x24,0x02,0x00,0x01,0x14,0x62,0x00,0x0d, -0x3c,0x02,0xb0,0x01,0x8c,0x84,0x00,0x04,0x3c,0x06,0xb0,0x09,0x00,0x82,0x20,0x21, -0x8c,0x85,0x00,0x08,0x8c,0x83,0x00,0x04,0x3c,0x02,0x01,0x00,0x34,0xc6,0x01,0x00, -0x00,0x62,0x18,0x24,0x14,0x60,0x00,0x05,0x30,0xa5,0x20,0x00,0x24,0x02,0x00,0x06, -0xa0,0xc2,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x09, -0x10,0xa0,0xff,0xfc,0x34,0x63,0x01,0x00,0x24,0x02,0x00,0x0e,0x08,0x00,0x27,0x2d, -0xa0,0x62,0x00,0x00,0x3c,0x02,0xb0,0x01,0x30,0xa5,0xff,0xff,0x00,0xa2,0x28,0x21, -0x8c,0xa3,0x00,0x00,0x3c,0x02,0x10,0x00,0x00,0x80,0x30,0x21,0x00,0x62,0x18,0x24, -0x8c,0xa2,0x00,0x04,0x10,0x60,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0x80,0x00, -0x10,0x40,0x00,0x13,0x00,0x00,0x00,0x00,0x8c,0xc2,0x01,0xa8,0x00,0x00,0x00,0x00, -0x24,0x44,0x00,0x01,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,0x00,0x83,0x10,0x0a, -0x93,0x83,0x81,0xf0,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23, -0x24,0x63,0xff,0xff,0xac,0xc4,0x01,0xa8,0xa3,0x83,0x81,0xf0,0x8c,0xc4,0x01,0xac, -0x8c,0xc2,0x01,0xa8,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x26,0x00,0x02,0x10,0x2b, -0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x73, -0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x04, -0x00,0x00,0x00,0x00,0xa3,0x80,0x81,0xf1,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, -0x24,0x02,0x00,0x01,0xa3,0x82,0x81,0xf1,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, -0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xa8,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00, -0x30,0x62,0x00,0xff,0x00,0x03,0x2e,0x02,0x00,0x02,0x39,0x80,0x2c,0xa2,0x00,0x02, -0x00,0x03,0x34,0x02,0x10,0x40,0x00,0x05,0x00,0x03,0x1a,0x02,0xa4,0x87,0x01,0xd8, -0xa0,0x85,0x01,0xd4,0xa0,0x86,0x01,0xd5,0xa0,0x83,0x01,0xd6,0x03,0xe0,0x00,0x08, -0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04,0x3c,0x05,0xb0,0x01,0x00,0x80,0x50,0x21, -0x00,0x45,0x10,0x21,0x8c,0x43,0x00,0x04,0x24,0x02,0x00,0x05,0x00,0x03,0x1a,0x02, -0x30,0x69,0x00,0x0f,0x11,0x22,0x00,0x0b,0x24,0x02,0x00,0x07,0x11,0x22,0x00,0x09, -0x24,0x02,0x00,0x0a,0x11,0x22,0x00,0x07,0x24,0x02,0x00,0x0b,0x11,0x22,0x00,0x05, -0x24,0x02,0x00,0x01,0x93,0x83,0x81,0xf0,0x3c,0x04,0xb0,0x06,0x10,0x62,0x00,0x03, -0x34,0x84,0x80,0x18,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x02,0x14,0x40,0xff,0xfa,0x00,0x00,0x00,0x00, -0x8d,0x43,0x01,0xa8,0x27,0x82,0x89,0x58,0x00,0x03,0x18,0x80,0x00,0x6a,0x20,0x21, -0x8c,0x87,0x00,0xa8,0x00,0x62,0x18,0x21,0x8c,0x68,0x00,0x00,0x00,0xe5,0x28,0x21, -0x8c,0xa9,0x00,0x00,0x3c,0x02,0xff,0xff,0x27,0x83,0x8a,0x58,0x01,0x22,0x10,0x24, -0x00,0x48,0x10,0x25,0xac,0xa2,0x00,0x00,0x8d,0x44,0x01,0xa8,0x00,0x07,0x30,0xc2, -0x3c,0x02,0x00,0x80,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x00,0x06,0x32,0x00, -0x8c,0xa9,0x00,0x04,0x00,0xc2,0x30,0x25,0x8c,0x82,0x00,0x00,0x3c,0x03,0x80,0x00, -0x01,0x22,0x10,0x25,0x00,0x43,0x10,0x25,0xac,0xa2,0x00,0x04,0xaf,0x87,0xbc,0x10, -0x8c,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x82,0xbc,0x18,0x8c,0xa3,0x00,0x04, -0x3c,0x01,0xb0,0x07,0xac,0x26,0x80,0x18,0x8d,0x42,0x01,0xa8,0xaf,0x83,0xbc,0x14, -0x93,0x85,0x81,0xf0,0x24,0x44,0x00,0x01,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40, -0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x24,0xa5,0xff,0xff, -0x00,0x82,0x20,0x23,0xad,0x44,0x01,0xa8,0xa3,0x85,0x81,0xf0,0x08,0x00,0x27,0x89, -0x00,0x00,0x00,0x00,0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x01,0x24,0x42,0x9f,0x04, -0x34,0xa5,0x00,0x20,0xac,0xa2,0x00,0x00,0x24,0x02,0x00,0x02,0x24,0x03,0x00,0x20, -0xac,0x82,0x00,0x64,0x3c,0x02,0x80,0x01,0xac,0x83,0x00,0x60,0x00,0x80,0x38,0x21, -0xac,0x80,0x00,0x00,0xac,0x80,0x00,0x04,0xac,0x80,0x00,0x08,0xac,0x80,0x00,0x4c, -0xac,0x80,0x00,0x50,0xac,0x80,0x00,0x54,0xac,0x80,0x00,0x0c,0xac,0x80,0x00,0x58, -0xa0,0x80,0x00,0x5c,0x24,0x83,0x00,0x68,0x24,0x42,0xa0,0x14,0x24,0x04,0x00,0x0f, -0x24,0x84,0xff,0xff,0xac,0x62,0x00,0x00,0x04,0x81,0xff,0xfd,0x24,0x63,0x00,0x04, -0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xa8,0xac,0xe0,0x01,0xa8,0xac,0xe0,0x01,0xac, -0xac,0xe0,0x01,0xb0,0xac,0xe0,0x01,0xb4,0xa0,0xe0,0x01,0xb8,0xa0,0xe0,0x01,0xb9, -0xa0,0xe0,0x01,0xba,0xa0,0xe0,0x01,0xc0,0xa0,0xe0,0x01,0xc1,0xac,0xe0,0x01,0xc4, -0xac,0xe0,0x01,0xc8,0xac,0xe0,0x01,0xcc,0xac,0xe0,0x01,0xd0,0x8c,0x44,0x00,0x00, -0x3c,0x02,0x80,0x01,0x24,0x42,0xa0,0xfc,0x30,0x83,0x00,0xff,0x00,0x03,0x19,0x80, -0xa4,0xe3,0x01,0xd8,0xac,0xe2,0x00,0x78,0x3c,0x03,0x80,0x01,0x3c,0x02,0x80,0x01, -0x24,0x63,0xa2,0x88,0x24,0x42,0xa1,0xf4,0xac,0xe3,0x00,0x88,0xac,0xe2,0x00,0x98, -0x3c,0x03,0x80,0x01,0x3c,0x02,0x80,0x01,0x00,0x04,0x2e,0x03,0x00,0x04,0x34,0x03, -0x24,0x63,0xa3,0x30,0x00,0x04,0x22,0x03,0x24,0x42,0xa4,0x74,0xac,0xe3,0x00,0xa0, -0xac,0xe2,0x00,0xa4,0xa0,0xe5,0x01,0xd4,0xa0,0xe6,0x01,0xd5,0x03,0xe0,0x00,0x08, -0xa0,0xe4,0x01,0xd6,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20, -0x24,0x42,0xa0,0x14,0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00,0x3c,0x02,0xb0,0x03, -0x3c,0x03,0x80,0x01,0x34,0x42,0x00,0x20,0x24,0x63,0xa0,0x2c,0xac,0x43,0x00,0x00, -0x8c,0x82,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x11,0x00,0x80,0x28,0x21, -0x8c,0x82,0x00,0x14,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0d,0x00,0x00,0x00,0x00, -0x8c,0x84,0x00,0x10,0x8c,0xa3,0x00,0x14,0x8c,0xa2,0x00,0x04,0x00,0x83,0x20,0x21, -0x00,0x44,0x10,0x21,0x30,0x43,0x00,0xff,0x00,0x03,0x18,0x2b,0x00,0x02,0x12,0x02, -0x00,0x43,0x10,0x21,0x00,0x02,0x12,0x00,0x30,0x42,0x3f,0xff,0xac,0xa2,0x00,0x04, -0xac,0xa0,0x00,0x00,0xac,0xa0,0x00,0x4c,0xac,0xa0,0x00,0x50,0xac,0xa0,0x00,0x54, -0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x0c,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01, -0x34,0x63,0x00,0x20,0x24,0x42,0xa0,0xa8,0xac,0x62,0x00,0x00,0x8c,0x86,0x00,0x04, -0x3c,0x02,0xb0,0x01,0x24,0x03,0x00,0x01,0x00,0xc2,0x10,0x21,0x8c,0x45,0x00,0x00, -0xac,0x83,0x00,0x4c,0x00,0x05,0x14,0x02,0x30,0xa3,0x3f,0xff,0x30,0x42,0x00,0xff, -0xac,0x83,0x00,0x10,0xac,0x82,0x00,0x14,0x8c,0x83,0x00,0x14,0xac,0x85,0x00,0x40, -0x00,0xc3,0x30,0x21,0x03,0xe0,0x00,0x08,0xac,0x86,0x00,0x08,0x3c,0x02,0xb0,0x03, -0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xa0,0xfc, -0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x4c, -0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0a,0x00,0x80,0x80,0x21,0xae,0x00,0x00,0x00, -0xae,0x00,0x00,0x4c,0xae,0x00,0x00,0x50,0xae,0x00,0x00,0x54,0xae,0x00,0x00,0x0c, -0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18, -0x0c,0x00,0x28,0x2a,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0x4c,0xae,0x00,0x00,0x00, -0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20, -0x24,0x63,0xa1,0x60,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00, -0x8c,0x82,0x00,0x4c,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x16,0x00,0x80,0x80,0x21, -0x8e,0x03,0x00,0x08,0x3c,0x02,0xb0,0x01,0x8e,0x04,0x00,0x44,0x00,0x62,0x18,0x21, -0x90,0x65,0x00,0x00,0x24,0x02,0x00,0x01,0xae,0x02,0x00,0x50,0x30,0xa3,0x00,0xff, -0x00,0x03,0x10,0x82,0x00,0x04,0x23,0x02,0x30,0x84,0x00,0x0f,0x30,0x42,0x00,0x03, -0x00,0x03,0x19,0x02,0xae,0x04,0x00,0x34,0xae,0x02,0x00,0x2c,0xae,0x03,0x00,0x30, -0xa2,0x05,0x00,0x48,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08, -0x27,0xbd,0x00,0x18,0x0c,0x00,0x28,0x2a,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0x64, -0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8, -0x34,0x42,0x00,0x20,0x24,0x63,0xa1,0xf4,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14, -0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x50,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x16, -0x00,0x80,0x80,0x21,0x92,0x03,0x00,0x44,0x8e,0x02,0x00,0x40,0x83,0x85,0x8b,0xc4, -0x92,0x04,0x00,0x41,0x30,0x63,0x00,0x01,0x00,0x02,0x16,0x02,0xae,0x04,0x00,0x14, -0x00,0x00,0x30,0x21,0xae,0x02,0x00,0x18,0x10,0xa0,0x00,0x04,0xae,0x03,0x00,0x3c, -0x10,0x60,0x00,0x03,0x24,0x02,0x00,0x01,0x24,0x06,0x00,0x01,0x24,0x02,0x00,0x01, -0xa3,0x86,0x8b,0xc4,0x8f,0xbf,0x00,0x14,0xae,0x02,0x00,0x54,0x8f,0xb0,0x00,0x10, -0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x28,0x58,0x00,0x00,0x00,0x00, -0x08,0x00,0x28,0x89,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01, -0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xa2,0x88,0xaf,0xb0,0x00,0x10, -0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x50,0x00,0x00,0x00,0x00, -0x10,0x40,0x00,0x1b,0x00,0x80,0x80,0x21,0x3c,0x02,0xb0,0x03,0x8c,0x42,0x00,0x00, -0x92,0x04,0x00,0x44,0x8e,0x03,0x00,0x40,0x83,0x86,0x8b,0xc4,0x92,0x05,0x00,0x41, -0x30,0x42,0x08,0x00,0x30,0x84,0x00,0x01,0x00,0x02,0x12,0xc2,0x00,0x03,0x1e,0x02, -0x00,0x82,0x20,0x25,0xae,0x05,0x00,0x14,0x00,0x00,0x38,0x21,0xae,0x03,0x00,0x18, -0x10,0xc0,0x00,0x04,0xae,0x04,0x00,0x3c,0x10,0x80,0x00,0x03,0x24,0x02,0x00,0x01, -0x24,0x07,0x00,0x01,0x24,0x02,0x00,0x01,0xa3,0x87,0x8b,0xc4,0x8f,0xbf,0x00,0x14, -0xae,0x02,0x00,0x54,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18, -0x0c,0x00,0x28,0x58,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0xae,0x00,0x00,0x00,0x00, -0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20, -0x24,0x63,0xa3,0x30,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00, -0x8c,0x82,0x00,0x54,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x42,0x00,0x80,0x80,0x21, -0x8e,0x04,0x00,0x04,0x8e,0x03,0x00,0x44,0x3c,0x02,0x80,0x00,0x3c,0x08,0xb0,0x01, -0x34,0x42,0x00,0x10,0x00,0x88,0x20,0x21,0x00,0x62,0x18,0x25,0xac,0x83,0x00,0x04, -0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x27,0x89,0x89,0x58,0x00,0x48,0x10,0x21, -0x8c,0x45,0x00,0x00,0x00,0x03,0x18,0x80,0x00,0x69,0x18,0x21,0xac,0x65,0x00,0x00, -0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x27,0x87,0x8a,0x58,0x00,0x48,0x10,0x21, -0x8c,0x45,0x00,0x04,0x00,0x03,0x18,0x80,0x00,0x67,0x18,0x21,0xac,0x65,0x00,0x00, -0x8e,0x02,0x01,0xac,0x8e,0x06,0x00,0x04,0x02,0x00,0x20,0x21,0x00,0x02,0x10,0x80, -0x00,0x47,0x38,0x21,0x94,0xe3,0x00,0x02,0x00,0x49,0x10,0x21,0x90,0x45,0x00,0x00, -0x00,0x03,0x1a,0x00,0x00,0xc8,0x30,0x21,0x00,0xa3,0x28,0x25,0x0c,0x00,0x26,0x69, -0xa4,0xc5,0x00,0x2e,0x8e,0x03,0x01,0xac,0x8e,0x07,0x00,0x04,0x3c,0x06,0xb0,0x03, -0x24,0x65,0x00,0x01,0x28,0xa4,0x00,0x00,0x24,0x62,0x00,0x40,0x00,0xa4,0x10,0x0a, -0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x03,0x18,0x80,0x00,0xa2,0x28,0x23, -0x00,0x70,0x18,0x21,0xae,0x05,0x01,0xac,0xac,0x67,0x00,0xa8,0x34,0xc6,0x00,0x30, -0x8c,0xc3,0x00,0x00,0x93,0x82,0x81,0xf0,0x02,0x00,0x20,0x21,0x24,0x63,0x00,0x01, -0x24,0x42,0x00,0x01,0xac,0xc3,0x00,0x00,0xa3,0x82,0x81,0xf0,0x0c,0x00,0x28,0x0b, -0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08, -0x27,0xbd,0x00,0x18,0x0c,0x00,0x28,0xa2,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0xd8, -0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8, -0x34,0x42,0x00,0x20,0x24,0x63,0xa4,0x74,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14, -0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x54,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x42, -0x00,0x80,0x80,0x21,0x8e,0x04,0x00,0x04,0x8e,0x03,0x00,0x44,0x3c,0x02,0x80,0x00, -0x3c,0x08,0xb0,0x01,0x34,0x42,0x00,0x10,0x00,0x88,0x20,0x21,0x00,0x62,0x18,0x25, -0xac,0x83,0x00,0x04,0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x27,0x89,0x89,0x58, -0x00,0x48,0x10,0x21,0x8c,0x45,0x00,0x00,0x00,0x03,0x18,0x80,0x00,0x69,0x18,0x21, -0xac,0x65,0x00,0x00,0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x27,0x87,0x8a,0x58, -0x00,0x48,0x10,0x21,0x8c,0x45,0x00,0x04,0x00,0x03,0x18,0x80,0x00,0x67,0x18,0x21, -0xac,0x65,0x00,0x00,0x8e,0x02,0x01,0xac,0x8e,0x06,0x00,0x04,0x02,0x00,0x20,0x21, -0x00,0x02,0x10,0x80,0x00,0x47,0x38,0x21,0x94,0xe3,0x00,0x02,0x00,0x49,0x10,0x21, -0x90,0x45,0x00,0x00,0x00,0x03,0x1a,0x00,0x00,0xc8,0x30,0x21,0x00,0xa3,0x28,0x25, -0x0c,0x00,0x26,0x69,0xa4,0xc5,0x00,0x2e,0x8e,0x03,0x01,0xac,0x8e,0x07,0x00,0x04, -0x3c,0x06,0xb0,0x03,0x24,0x65,0x00,0x01,0x28,0xa4,0x00,0x00,0x24,0x62,0x00,0x40, -0x00,0xa4,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x03,0x18,0x80, -0x00,0xa2,0x28,0x23,0x00,0x70,0x18,0x21,0xae,0x05,0x01,0xac,0xac,0x67,0x00,0xa8, -0x34,0xc6,0x00,0x30,0x8c,0xc3,0x00,0x00,0x93,0x82,0x81,0xf0,0x02,0x00,0x20,0x21, -0x24,0x63,0x00,0x01,0x24,0x42,0x00,0x01,0xac,0xc3,0x00,0x00,0xa3,0x82,0x81,0xf0, -0x0c,0x00,0x28,0x0b,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10, -0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x28,0xa2,0x00,0x00,0x00,0x00, -0x08,0x00,0x29,0x29,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01, -0x27,0xbd,0xff,0xd8,0x34,0x42,0x00,0x20,0x24,0x63,0xa5,0xb8,0xaf,0xb2,0x00,0x18, -0xac,0x43,0x00,0x00,0x3c,0x12,0xb0,0x03,0x3c,0x02,0x80,0x01,0xaf,0xb4,0x00,0x20, -0xaf,0xb3,0x00,0x1c,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x24, -0x00,0x80,0x80,0x21,0x24,0x54,0xa0,0x14,0x00,0x00,0x88,0x21,0x3c,0x13,0xb0,0x01, -0x36,0x52,0x00,0xef,0x3c,0x02,0xb0,0x09,0x34,0x42,0x00,0x06,0x90,0x43,0x00,0x00, -0x8e,0x04,0x00,0x04,0x92,0x02,0x01,0xbb,0x30,0x69,0x00,0xff,0x00,0x04,0x42,0x02, -0x10,0x40,0x00,0x1e,0x00,0x00,0x38,0x21,0x8e,0x03,0x01,0xa8,0x3c,0x06,0x28,0x38, -0x34,0xc6,0x00,0x20,0x24,0x64,0x00,0x3d,0x28,0x82,0x00,0x00,0x24,0x63,0x00,0x7c, -0x00,0x82,0x18,0x0a,0x00,0x03,0x19,0x83,0x00,0x03,0x19,0x80,0x00,0x83,0x20,0x23, -0x00,0x04,0x10,0x80,0x00,0x50,0x10,0x21,0x8c,0x45,0x00,0xa8,0xae,0x04,0x01,0xac, -0xae,0x04,0x01,0xa8,0x00,0xb3,0x18,0x21,0xae,0x05,0x00,0x04,0xac,0x66,0x00,0x00, -0x8e,0x02,0x00,0x04,0x3c,0x03,0x80,0x00,0x34,0x63,0x4e,0x00,0x00,0x53,0x10,0x21, -0xac,0x43,0x00,0x04,0xa2,0x00,0x01,0xbb,0x93,0x83,0x81,0xf7,0x00,0x00,0x00,0x00, -0x24,0x62,0x00,0x01,0xa3,0x82,0x81,0xf7,0xa2,0x43,0x00,0x00,0x01,0x28,0x10,0x23, -0x24,0x44,0x00,0x40,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x7f,0x00,0x83,0x10,0x0a, -0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x24,0x84,0xff,0xff,0x10,0x44,0x00,0x6b, -0x3c,0x02,0xb0,0x01,0x8e,0x03,0x00,0x04,0x3c,0x04,0x7c,0x00,0x00,0x62,0x18,0x21, -0x8c,0x65,0x00,0x04,0x34,0x84,0x00,0xf0,0x00,0x00,0x30,0x21,0xae,0x05,0x00,0x44, -0x00,0xa4,0x20,0x24,0x8c,0x63,0x00,0x00,0x10,0x80,0x00,0x6b,0x3c,0x02,0xff,0xff, -0x3c,0x09,0xb0,0x03,0x3c,0x05,0x7c,0x00,0x35,0x29,0x00,0x99,0x3c,0x0a,0xb0,0x01, -0x24,0x08,0x00,0x40,0x34,0xa5,0x00,0xf0,0x3c,0x0b,0xff,0xff,0x3c,0x0c,0x28,0x38, -0x16,0x20,0x00,0x06,0x24,0xe7,0x00,0x01,0x93,0x82,0x81,0xf6,0x24,0x11,0x00,0x01, -0x24,0x42,0x00,0x01,0xa1,0x22,0x00,0x00,0xa3,0x82,0x81,0xf6,0x8e,0x02,0x00,0x04, -0x24,0x06,0x00,0x01,0x24,0x42,0x01,0x00,0x30,0x42,0x3f,0xff,0xae,0x02,0x00,0x04, -0x00,0x4a,0x10,0x21,0x8c,0x43,0x00,0x04,0x00,0x00,0x00,0x00,0xae,0x03,0x00,0x44, -0x00,0x65,0x20,0x24,0x8c,0x43,0x00,0x00,0x10,0xe8,0x00,0x2d,0x00,0x00,0x00,0x00, -0x14,0x80,0xff,0xeb,0x00,0x6b,0x10,0x24,0x14,0x4c,0xff,0xe9,0x24,0x02,0x00,0x01, -0x10,0xc2,0x00,0x30,0x3c,0x03,0xb0,0x09,0x8e,0x02,0x00,0x44,0x8e,0x04,0x00,0x60, -0x00,0x02,0x1e,0x42,0x00,0x02,0x12,0x02,0x30,0x42,0x00,0x0f,0x30,0x63,0x00,0x01, -0xae,0x02,0x00,0x00,0x10,0x44,0x00,0x1a,0xae,0x03,0x00,0x58,0x8e,0x02,0x00,0x64, -0x8e,0x04,0x00,0x58,0x00,0x00,0x00,0x00,0x10,0x82,0x00,0x05,0x00,0x00,0x00,0x00, -0xae,0x00,0x00,0x4c,0xae,0x00,0x00,0x50,0xae,0x00,0x00,0x54,0xae,0x00,0x00,0x0c, -0x8e,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0x80,0x00,0x50,0x10,0x21, -0x8c,0x42,0x00,0x68,0x00,0x00,0x00,0x00,0x10,0x54,0x00,0x06,0x00,0x00,0x00,0x00, -0x00,0x40,0xf8,0x09,0x02,0x00,0x20,0x21,0x8e,0x04,0x00,0x58,0x8e,0x03,0x00,0x00, -0x00,0x00,0x00,0x00,0xae,0x03,0x00,0x60,0x08,0x00,0x29,0x81,0xae,0x04,0x00,0x64, -0x8e,0x02,0x00,0x64,0x00,0x00,0x00,0x00,0x14,0x62,0xff,0xe5,0x00,0x00,0x00,0x00, -0x7a,0x02,0x0d,0x7c,0x8f,0xbf,0x00,0x24,0x8f,0xb4,0x00,0x20,0x7b,0xb2,0x00,0xfc, -0x7b,0xb0,0x00,0xbc,0x00,0x43,0x10,0x26,0x00,0x02,0x10,0x2b,0x03,0xe0,0x00,0x08, -0x27,0xbd,0x00,0x28,0x8e,0x04,0x00,0x04,0x34,0x63,0x00,0x06,0x90,0x62,0x00,0x00, -0x00,0x04,0x42,0x02,0x00,0x48,0x10,0x23,0x24,0x44,0x00,0x40,0x28,0x83,0x00,0x00, -0x24,0x42,0x00,0x7f,0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80, -0x00,0x82,0x20,0x23,0x14,0x86,0xff,0xc4,0x00,0x00,0x00,0x00,0x8e,0x03,0x00,0x00, -0x00,0x00,0x00,0x00,0x2c,0x62,0x00,0x03,0x14,0x40,0x00,0x05,0x24,0x02,0x00,0x0d, -0x10,0x62,0x00,0x03,0x24,0x02,0x00,0x01,0x08,0x00,0x2a,0x04,0xa2,0x02,0x00,0x5c, -0x08,0x00,0x2a,0x04,0xa2,0x00,0x00,0x5c,0x00,0x62,0x10,0x24,0x3c,0x03,0x28,0x38, -0x14,0x43,0xff,0x93,0x24,0x02,0x00,0x01,0x08,0x00,0x29,0xdc,0x00,0x00,0x00,0x00, -0x3c,0x02,0xb0,0x01,0x00,0xa2,0x40,0x21,0x00,0xa0,0x48,0x21,0x8d,0x05,0x00,0x00, -0x24,0x02,0xc0,0x00,0x00,0x09,0x38,0xc2,0x00,0xa2,0x28,0x24,0x24,0xc2,0xff,0xff, -0x00,0x07,0x3a,0x00,0x3c,0x0a,0xb0,0x06,0x3c,0x03,0x00,0x80,0x00,0xa6,0x28,0x25, -0x2c,0x42,0x1f,0xff,0x00,0xe3,0x38,0x25,0x35,0x4a,0x80,0x18,0x10,0x40,0x00,0x0e, -0xad,0x05,0x00,0x00,0xaf,0x89,0xbc,0x10,0x8d,0x02,0x00,0x00,0x00,0x00,0x00,0x00, -0xaf,0x82,0xbc,0x18,0x8d,0x03,0x00,0x04,0xad,0x47,0x00,0x00,0xaf,0x83,0xbc,0x14, -0xac,0x80,0x01,0xd0,0xac,0x80,0x01,0xc4,0xa0,0x80,0x01,0xc0,0xa0,0x80,0x01,0xc1, -0xac,0x80,0x01,0xc8,0xac,0x80,0x01,0xcc,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, -0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x8c,0x83,0x01,0xc4,0x00,0x80,0x38,0x21, -0x90,0x84,0x01,0xc0,0x00,0x03,0x18,0x80,0x00,0x67,0x18,0x21,0x8c,0x65,0x00,0xa8, -0x3c,0x02,0xb0,0x01,0x24,0x03,0x00,0x01,0x00,0xa2,0x10,0x21,0x8c,0x42,0x00,0x00, -0x10,0x83,0x00,0x18,0x00,0x02,0x14,0x02,0x8c,0xe9,0x01,0xcc,0x8c,0xea,0x01,0xc8, -0x30,0x46,0x00,0xff,0x01,0x2a,0x18,0x21,0x30,0x64,0x00,0xff,0x00,0x03,0x1a,0x02, -0x24,0x62,0x00,0x01,0x14,0x80,0x00,0x02,0x30,0x48,0x00,0xff,0x30,0x68,0x00,0xff, -0x90,0xe2,0x01,0xc1,0x00,0x00,0x00,0x00,0x00,0x48,0x10,0x23,0x00,0x02,0x12,0x00, -0x00,0x49,0x10,0x21,0x00,0x4a,0x10,0x21,0x00,0x46,0x30,0x23,0x0c,0x00,0x2a,0x2c, -0x00,0xe0,0x20,0x21,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, -0x27,0xbd,0x00,0x18,0x8c,0xe6,0x01,0xc8,0x08,0x00,0x2a,0x6b,0x00,0x00,0x00,0x00, -0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x14,0xaf,0xb0,0x00,0x10,0x8c,0x82,0x01,0xc4, -0x90,0x87,0x01,0xc1,0x00,0x80,0x80,0x21,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21, -0x8c,0x48,0x00,0xa8,0x3c,0x02,0xb0,0x01,0x00,0x07,0x3a,0x00,0x01,0x02,0x10,0x21, -0x8c,0x43,0x00,0x00,0x00,0xe5,0x38,0x21,0x00,0xe6,0x38,0x21,0x00,0x03,0x1c,0x02, -0x30,0x63,0x00,0xff,0x00,0xe3,0x38,0x23,0x01,0x00,0x28,0x21,0x0c,0x00,0x2a,0x2c, -0x00,0xe0,0x30,0x21,0x8e,0x02,0x01,0xa8,0x8f,0xbf,0x00,0x14,0x24,0x44,0x00,0x01, -0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83, -0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23,0xae,0x04,0x01,0xa8,0x8f,0xb0,0x00,0x10, -0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01, -0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xaa,0x58,0xaf,0xb0,0x00,0x10, -0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x90,0x82,0x01,0xd4,0x00,0x00,0x00,0x00, -0x14,0x40,0x00,0x6a,0x00,0x80,0x80,0x21,0x90,0x82,0x01,0xc0,0x00,0x00,0x00,0x00, -0x14,0x40,0x00,0x61,0x00,0x00,0x00,0x00,0x8c,0x83,0x01,0xa8,0x8c,0x82,0x01,0xac, -0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x22,0x00,0x00,0x28,0x21,0x93,0x82,0x81,0xf1, -0x00,0x03,0x30,0x80,0x00,0xc4,0x18,0x21,0x24,0x04,0x00,0x01,0x8c,0x67,0x00,0xa8, -0x10,0x44,0x00,0x20,0x3c,0x04,0xb0,0x01,0xaf,0x87,0xbc,0x10,0x00,0xe4,0x20,0x21, -0x8c,0x86,0x00,0x00,0x00,0x07,0x18,0xc2,0x3c,0x02,0x00,0x80,0xaf,0x86,0xbc,0x18, -0x8c,0x86,0x00,0x04,0x00,0x03,0x1a,0x00,0x3c,0x05,0xb0,0x06,0x00,0x62,0x18,0x25, -0x34,0xa5,0x80,0x18,0xac,0xa3,0x00,0x00,0x8e,0x02,0x01,0xa8,0x8e,0x09,0x01,0xac, -0xaf,0x86,0xbc,0x14,0x24,0x44,0x00,0x01,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40, -0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23, -0x00,0x80,0x30,0x21,0xae,0x04,0x01,0xa8,0x00,0xc9,0x10,0x26,0x00,0x02,0x28,0x2b, -0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x00,0xa0,0x10,0x21,0x03,0xe0,0x00,0x08, -0x27,0xbd,0x00,0x18,0x93,0x82,0x81,0xf0,0x00,0x00,0x00,0x00,0x2c,0x42,0x00,0x02, -0x14,0x40,0xff,0xf7,0x00,0x00,0x28,0x21,0x3c,0x05,0xb0,0x01,0x00,0xe5,0x28,0x21, -0x27,0x83,0x89,0x58,0x00,0xc3,0x18,0x21,0x8c,0xa6,0x00,0x00,0x8c,0x64,0x00,0x00, -0x24,0x02,0xc0,0x00,0x00,0xc2,0x10,0x24,0x00,0x44,0x10,0x25,0xac,0xa2,0x00,0x00, -0x8e,0x03,0x01,0xa8,0x27,0x84,0x8a,0x58,0x8c,0xa6,0x00,0x04,0x00,0x03,0x18,0x80, -0x00,0x64,0x18,0x21,0x8c,0x62,0x00,0x00,0x3c,0x03,0x80,0x00,0x00,0x07,0x20,0xc2, -0x00,0xc2,0x10,0x25,0x00,0x43,0x10,0x25,0xac,0xa2,0x00,0x04,0xaf,0x87,0xbc,0x10, -0x8c,0xa6,0x00,0x00,0x3c,0x02,0x00,0x80,0x00,0x04,0x22,0x00,0x3c,0x03,0xb0,0x06, -0xaf,0x86,0xbc,0x18,0x00,0x82,0x20,0x25,0x34,0x63,0x80,0x18,0x8c,0xa6,0x00,0x04, -0xac,0x64,0x00,0x00,0x8e,0x02,0x01,0xa8,0xaf,0x86,0xbc,0x14,0x24,0x44,0x00,0x01, -0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,0x00,0x83,0x10,0x0a,0x93,0x83,0x81,0xf0, -0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23,0x24,0x63,0xff,0xff, -0xae,0x04,0x01,0xa8,0xa3,0x83,0x81,0xf0,0x8e,0x04,0x01,0xac,0x8e,0x02,0x01,0xa8, -0x08,0x00,0x2a,0xcb,0x00,0x44,0x10,0x26,0x0c,0x00,0x2a,0x4c,0x00,0x00,0x00,0x00, -0x7a,0x02,0x0d,0x7c,0x08,0x00,0x2a,0xcb,0x00,0x43,0x10,0x26,0x8c,0x86,0x01,0xa8, -0x8c,0x89,0x01,0xac,0x00,0x00,0x00,0x00,0x10,0xc9,0x00,0xb4,0x00,0xc0,0x68,0x21, -0x00,0x06,0x10,0x80,0x27,0x83,0x89,0x58,0x00,0x43,0x18,0x21,0x00,0x44,0x10,0x21, -0x8c,0x47,0x00,0xa8,0x94,0x65,0x00,0x02,0x3c,0x02,0xb0,0x01,0x00,0xe2,0x10,0x21, -0x30,0xa5,0x3f,0xff,0xa4,0x45,0x00,0x2c,0x90,0x8a,0x01,0xc0,0x00,0x00,0x00,0x00, -0x11,0x40,0x00,0x0c,0x00,0x07,0x32,0x02,0x8c,0x83,0x01,0xc4,0x90,0x85,0x01,0xc1, -0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x21,0x8c,0x62,0x00,0xa8,0x00,0x00,0x00,0x00, -0x00,0x02,0x12,0x02,0x00,0x45,0x10,0x21,0x30,0x42,0x00,0x3f,0x14,0xc2,0xff,0xde, -0x00,0x00,0x00,0x00,0x3c,0x04,0xb0,0x01,0x00,0xe4,0x40,0x21,0x8d,0x06,0x00,0x00, -0x00,0x0d,0x28,0x80,0x00,0x06,0x14,0x02,0x30,0x4b,0x00,0xff,0x00,0xeb,0x70,0x21, -0x01,0xc4,0x20,0x21,0x90,0x83,0x00,0x00,0x27,0x82,0x89,0x58,0x00,0xa2,0x28,0x21, -0x8c,0xa4,0x00,0x00,0x00,0x03,0x18,0x82,0x30,0x63,0x00,0x03,0x2c,0x62,0x00,0x02, -0x14,0x40,0x00,0x66,0x30,0x8c,0x3f,0xff,0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x61, -0x2d,0x82,0x08,0x00,0x15,0x40,0x00,0x36,0x01,0x6c,0x10,0x21,0x01,0x6c,0x18,0x21, -0x30,0x62,0x00,0xff,0x00,0x02,0x10,0x2b,0x00,0x03,0x1a,0x02,0x3c,0x04,0xb0,0x01, -0x00,0x62,0x18,0x21,0x00,0xe4,0x20,0x21,0x24,0x02,0x00,0x01,0xa2,0x03,0x01,0xc1, -0xa0,0x82,0x00,0x08,0x8e,0x06,0x01,0xa8,0x3c,0x03,0xb0,0x00,0x34,0x63,0xff,0xf4, -0x24,0xc5,0x00,0x01,0x28,0xa4,0x00,0x00,0x24,0xc2,0x00,0x40,0x00,0xa4,0x10,0x0a, -0x01,0xc3,0x18,0x21,0xa4,0x6c,0x00,0x00,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80, -0x92,0x04,0x01,0xc0,0x00,0xa2,0x38,0x23,0x3c,0x03,0xb0,0x03,0xae,0x0b,0x01,0xcc, -0xae,0x0c,0x01,0xc8,0xae,0x06,0x01,0xc4,0xae,0x07,0x01,0xa8,0x34,0x63,0x01,0x08, -0x92,0x05,0x01,0xd6,0x8c,0x66,0x00,0x00,0x24,0x84,0x00,0x01,0x30,0x82,0x00,0xff, -0x00,0x45,0x10,0x2b,0xae,0x06,0x01,0xd0,0x10,0x40,0x00,0x07,0xa2,0x04,0x01,0xc0, -0x92,0x02,0x01,0xd5,0x92,0x03,0x01,0xc1,0x24,0x42,0xff,0xfc,0x00,0x62,0x18,0x2a, -0x14,0x60,0x00,0x08,0x00,0x00,0x00,0x00,0x02,0x00,0x20,0x21,0x0c,0x00,0x2a,0x4c, -0x00,0x00,0x00,0x00,0x8e,0x09,0x01,0xac,0x8e,0x06,0x01,0xa8,0x08,0x00,0x2a,0xcb, -0x00,0xc9,0x10,0x26,0x8e,0x09,0x01,0xac,0x08,0x00,0x2a,0xca,0x00,0xe0,0x30,0x21, -0x30,0x43,0x00,0xff,0x92,0x07,0x01,0xc1,0x00,0x02,0x12,0x02,0x30,0x44,0x00,0xff, -0x38,0x63,0x00,0x00,0x24,0x46,0x00,0x01,0x92,0x05,0x01,0xd5,0x00,0x83,0x30,0x0a, -0x00,0xc7,0x18,0x21,0x00,0xa3,0x10,0x2a,0x14,0x40,0xff,0xeb,0x00,0x00,0x00,0x00, -0x24,0xa2,0xff,0xfc,0x00,0x62,0x10,0x2a,0x10,0x40,0x00,0x07,0x01,0x80,0x28,0x21, -0x92,0x03,0x01,0xd6,0x25,0x42,0x00,0x01,0x00,0x43,0x10,0x2a,0x14,0x40,0x00,0x07, -0x25,0xa4,0x00,0x01,0x01,0x80,0x28,0x21,0x01,0x60,0x30,0x21,0x0c,0x00,0x2a,0x74, -0x02,0x00,0x20,0x21,0x08,0x00,0x2b,0x6d,0x00,0x00,0x00,0x00,0x28,0x83,0x00,0x00, -0x25,0xa2,0x00,0x40,0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80, -0x00,0x82,0x20,0x23,0x00,0xc7,0x18,0x21,0x25,0x42,0x00,0x01,0x00,0x80,0x30,0x21, -0xa2,0x03,0x01,0xc1,0xae,0x0b,0x01,0xcc,0xae,0x0c,0x01,0xc8,0x08,0x00,0x2a,0xc9, -0xa2,0x02,0x01,0xc0,0x14,0x40,0xff,0x9f,0x00,0x00,0x00,0x00,0x15,0x40,0x00,0x14, -0x24,0x02,0xc0,0x00,0x00,0xc2,0x10,0x24,0x00,0x4c,0x10,0x25,0xad,0x02,0x00,0x00, -0xaf,0x87,0xbc,0x10,0x8d,0x05,0x00,0x00,0x00,0x07,0x18,0xc2,0x3c,0x02,0x00,0x80, -0x00,0x03,0x1a,0x00,0x3c,0x04,0xb0,0x06,0xaf,0x85,0xbc,0x18,0x00,0x62,0x18,0x25, -0x34,0x84,0x80,0x18,0x8d,0x05,0x00,0x04,0xac,0x83,0x00,0x00,0x8e,0x02,0x01,0xa8, -0x8e,0x09,0x01,0xac,0xaf,0x85,0xbc,0x14,0x08,0x00,0x2a,0xc2,0x24,0x44,0x00,0x01, -0x01,0x6c,0x10,0x21,0x30,0x45,0x00,0xff,0x92,0x04,0x01,0xc1,0x00,0x02,0x12,0x02, -0x30,0x46,0x00,0xff,0x38,0xa5,0x00,0x00,0x24,0x42,0x00,0x01,0x92,0x03,0x01,0xd5, -0x00,0xc5,0x10,0x0a,0x00,0x82,0x20,0x21,0x00,0x64,0x18,0x2a,0x10,0x60,0xff,0xca, -0x01,0x80,0x28,0x21,0x08,0x00,0x2b,0x6b,0x02,0x00,0x20,0x21,0x90,0x87,0x01,0xc0, -0x00,0x00,0x00,0x00,0x10,0xe0,0xff,0x06,0x00,0x00,0x28,0x21,0x3c,0x02,0xb0,0x03, -0x34,0x42,0x01,0x08,0x94,0x83,0x01,0xd8,0x8c,0x88,0x01,0xd0,0x8c,0x45,0x00,0x00, -0x01,0x03,0x18,0x21,0x00,0xa3,0x10,0x2b,0x10,0x40,0x00,0x0b,0x2c,0xe2,0x00,0x02, -0x00,0xa8,0x10,0x2b,0x10,0x40,0xfe,0xf9,0x00,0xc9,0x10,0x26,0x3c,0x02,0x80,0x00, -0x00,0x62,0x18,0x21,0x00,0xa2,0x10,0x21,0x00,0x43,0x10,0x2b,0x14,0x40,0xfe,0xf3, -0x00,0xc9,0x10,0x26,0x2c,0xe2,0x00,0x02,0x10,0x40,0xff,0x90,0x00,0x00,0x00,0x00, -0x24,0x02,0x00,0x01,0x14,0xe2,0xfe,0xed,0x00,0xc9,0x10,0x26,0x3c,0x03,0xb0,0x06, -0x34,0x63,0x80,0x18,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x02, -0x14,0x40,0xfe,0xe5,0x00,0x00,0x00,0x00,0x08,0x00,0x2b,0x6b,0x00,0x00,0x00,0x00, -0x3c,0x04,0xb0,0x03,0x3c,0x06,0xb0,0x07,0x3c,0x02,0x80,0x01,0x34,0xc6,0x00,0x18, -0x34,0x84,0x00,0x20,0x24,0x42,0xaf,0xa0,0x24,0x03,0xff,0x83,0xac,0x82,0x00,0x00, -0xa0,0xc3,0x00,0x00,0x90,0xc4,0x00,0x00,0x27,0xbd,0xff,0xf8,0x3c,0x03,0xb0,0x07, -0x24,0x02,0xff,0x82,0xa3,0xa4,0x00,0x00,0xa0,0x62,0x00,0x00,0x90,0x64,0x00,0x00, -0x3c,0x02,0xb0,0x07,0x34,0x42,0x00,0x08,0xa3,0xa4,0x00,0x01,0xa0,0x40,0x00,0x00, -0x90,0x43,0x00,0x00,0x24,0x02,0x00,0x03,0x3c,0x05,0xb0,0x07,0xa3,0xa3,0x00,0x00, -0xa0,0xc2,0x00,0x00,0x90,0xc4,0x00,0x00,0x34,0xa5,0x00,0x10,0x24,0x02,0x00,0x06, -0x3c,0x03,0xb0,0x07,0xa3,0xa4,0x00,0x00,0x34,0x63,0x00,0x38,0xa0,0xa2,0x00,0x00, -0x90,0x64,0x00,0x00,0x3c,0x02,0xb0,0x07,0x34,0x42,0x00,0x20,0xa3,0xa4,0x00,0x00, -0xa0,0xa0,0x00,0x00,0x90,0xa3,0x00,0x00,0xaf,0x82,0xbf,0x20,0xa3,0xa3,0x00,0x00, -0xa0,0x40,0x00,0x00,0x90,0x43,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x08, -}; - -u8 rtl8190_fwdata_array[] ={ -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x10,0x00,0x08,0x00, -0x02,0xe9,0x01,0x74,0x02,0xab,0x01,0xc7,0x01,0x55,0x00,0xe4,0x00,0xab,0x00,0x72, -0x00,0x55,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x02,0x76,0x01,0x3b, -0x00,0xd2,0x00,0x9e,0x00,0x69,0x00,0x4f,0x00,0x46,0x00,0x3f,0x01,0x3b,0x00,0x9e, -0x00,0x69,0x00,0x4f,0x00,0x35,0x00,0x27,0x00,0x23,0x00,0x20,0x01,0x2f,0x00,0x98, -0x00,0x65,0x00,0x4c,0x00,0x33,0x00,0x26,0x00,0x22,0x00,0x1e,0x00,0x98,0x00,0x4c, -0x00,0x33,0x00,0x26,0x00,0x19,0x00,0x13,0x00,0x11,0x00,0x0f,0x02,0x39,0x01,0x1c, -0x00,0xbd,0x00,0x8e,0x00,0x5f,0x00,0x47,0x00,0x3f,0x00,0x39,0x01,0x1c,0x00,0x8e, -0x00,0x5f,0x00,0x47,0x00,0x2f,0x00,0x23,0x00,0x20,0x00,0x1c,0x01,0x11,0x00,0x89, -0x00,0x5b,0x00,0x44,0x00,0x2e,0x00,0x22,0x00,0x1e,0x00,0x1b,0x00,0x89,0x00,0x44, -0x00,0x2e,0x00,0x22,0x00,0x17,0x00,0x11,0x00,0x0f,0x00,0x0e,0x02,0xab,0x02,0xab, -0x02,0x66,0x02,0x66,0x07,0x06,0x06,0x06,0x05,0x06,0x07,0x08,0x04,0x06,0x07,0x08, -0x09,0x0a,0x0b,0x0b,0x49,0x6e,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x4c, -0x42,0x4d,0x4f,0x44,0x00,0x00,0x00,0x00,0x54,0x4c,0x42,0x4c,0x5f,0x64,0x61,0x74, -0x61,0x00,0x54,0x4c,0x42,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x64,0x45,0x4c, -0x5f,0x64,0x61,0x74,0x61,0x00,0x41,0x64,0x45,0x53,0x00,0x00,0x00,0x00,0x00,0x00, -0x45,0x78,0x63,0x43,0x6f,0x64,0x65,0x36,0x00,0x00,0x45,0x78,0x63,0x43,0x6f,0x64, -0x65,0x37,0x00,0x00,0x53,0x79,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x70, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x49,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x43,0x70,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4f,0x76,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x0b,0x53, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x2c, -0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x60, -0x00,0x00,0x00,0x90,0x00,0x00,0x00,0xc0,0x00,0x00,0x01,0x20,0x00,0x00,0x01,0x80, -0x00,0x00,0x01,0xb0,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x9c, -0x00,0x00,0x00,0xd0,0x00,0x00,0x01,0x38,0x00,0x00,0x01,0xa0,0x00,0x00,0x01,0xd4, -0x00,0x00,0x02,0x08,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0xd0,0x00,0x00,0x01,0x38, -0x00,0x00,0x01,0xa0,0x00,0x00,0x02,0x6f,0x00,0x00,0x03,0x40,0x00,0x00,0x03,0xa8, -0x00,0x00,0x04,0x10,0x01,0x01,0x01,0x02,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04, -0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x07,0x74,0x80,0x00,0x07,0x88, -0x80,0x00,0x07,0x88,0x80,0x00,0x07,0x78,0x80,0x00,0x07,0x78,0x80,0x00,0x07,0x9c, -0x80,0x00,0x53,0xc4,0x80,0x00,0x54,0x24,0x80,0x00,0x54,0x38,0x80,0x00,0x54,0x5c, -0x80,0x00,0x54,0x68,0x80,0x00,0x54,0xa8,0x80,0x00,0x56,0xa8,0x80,0x00,0x57,0xec, -0x80,0x00,0x58,0x14,0x80,0x00,0x59,0x0c,0x80,0x00,0x59,0xc4,0x80,0x00,0x5a,0x6c, -0x80,0x00,0x5a,0xe0,0x80,0x00,0x5b,0xec,0x80,0x00,0x5c,0x24,0x80,0x00,0x5c,0x38, -0x80,0x00,0x5c,0x4c,0x80,0x00,0x5d,0x40,0x80,0x00,0x5d,0x80,0x80,0x00,0x5e,0x34, -0x80,0x00,0x5e,0x5c,0x80,0x00,0x56,0x68,0x80,0x00,0x5e,0x78,0x80,0x00,0x88,0xf8, -0x80,0x00,0x88,0xf8,0x80,0x00,0x88,0xf8,0x80,0x00,0x89,0x2c,0x80,0x00,0x89,0x6c, -0x80,0x00,0x89,0xa4,0x80,0x00,0x89,0xd4,0x80,0x00,0x8a,0x10,0x80,0x00,0x8a,0x50, -0x80,0x00,0x8a,0xb8,0x80,0x00,0x8a,0xcc,0x80,0x00,0x8b,0x08,0x80,0x00,0x8b,0x10, -0x80,0x00,0x8b,0x4c,0x80,0x00,0x8b,0x60,0x80,0x00,0x8b,0x68,0x80,0x00,0x8b,0x70, -0x80,0x00,0x8b,0x70,0x80,0x00,0x8b,0x70,0x80,0x00,0x8b,0x70,0x80,0x00,0x8a,0x90, -0x80,0x00,0x8b,0xa0,0x80,0x00,0x8b,0xb4,0x80,0x00,0x88,0x54,0x80,0x00,0x8e,0xc8, -0x80,0x00,0x8e,0xc8,0x80,0x00,0x8e,0xc8,0x80,0x00,0x8e,0xfc,0x80,0x00,0x8f,0x3c, -0x80,0x00,0x8f,0x74,0x80,0x00,0x8f,0xa4,0x80,0x00,0x8f,0xe0,0x80,0x00,0x90,0x20, -0x80,0x00,0x90,0x88,0x80,0x00,0x90,0x9c,0x80,0x00,0x90,0xd8,0x80,0x00,0x90,0xe0, -0x80,0x00,0x91,0x1c,0x80,0x00,0x91,0x30,0x80,0x00,0x91,0x38,0x80,0x00,0x91,0x40, -0x80,0x00,0x91,0x40,0x80,0x00,0x91,0x40,0x80,0x00,0x91,0x40,0x80,0x00,0x90,0x60, -0x80,0x00,0x91,0x70,0x80,0x00,0x91,0x84,0x80,0x00,0x8d,0x00,}; - u32 Rtl8192UsbPHY_REGArray[] = { 0x0, }; diff --git a/drivers/staging/rtl8192u/r819xU_firmware_img.h b/drivers/staging/rtl8192u/r819xU_firmware_img.h index d9d9515a1e61..18d0a6b5cbae 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware_img.h +++ b/drivers/staging/rtl8192u/r819xU_firmware_img.h @@ -1,9 +1,6 @@ #ifndef IMG_H #define IMG_H -#define BOOT_ARR_LEN 344 -#define MAIN_ARR_LEN 45136 -#define DATA_ARR_LEN 796 #define MACPHY_Array_PGLength 30 #define PHY_REG_1T2RArrayLength 296 #define AGCTAB_ArrayLength 384 @@ -16,10 +13,6 @@ #define PHY_REGArrayLength 1 -extern u8 rtl8190_fwboot_array[BOOT_ARR_LEN]; -extern u8 rtl8190_fwmain_array[MAIN_ARR_LEN]; -extern u8 rtl8190_fwdata_array[DATA_ARR_LEN]; - extern u32 Rtl8192UsbPHY_REGArray[]; extern u32 Rtl8192UsbPHY_REG_1T2RArray[]; extern u32 Rtl8192UsbRadioA_Array[]; -- cgit v1.2.3 From 18545cfd3623e5cd8960f5155f95e0a9c790a54c Mon Sep 17 00:00:00 2001 From: Mike Thomas Date: Mon, 10 Jan 2011 18:34:41 +0000 Subject: Staging: easycap: Make easycap_debug non-static The parameter easycap_debug appears in macros JOT and JOM and therefore needs to be visible from all source files. The easycap_ prefix should be sufficient to avoid namespace clashes outside the module. Signed-off-by: Mike Thomas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 1 - drivers/staging/easycap/easycap_main.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 8ebf96f8a242..063d44718d8d 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -65,7 +65,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index acc1f56e6f29..22cf02b9e9d5 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -32,7 +32,7 @@ #include "easycap_standard.h" #include "easycap_ioctl.h" -static int easycap_debug; +int easycap_debug; static int easycap_bars; int easycap_gain = 16; module_param_named(debug, easycap_debug, int, S_IRUGO | S_IWUSR); -- cgit v1.2.3 From 6ddc5fb43e47e18d434619e08d41260ff121a7f6 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Wed, 12 Jan 2011 11:41:59 +0100 Subject: Staging: iio: add driver for MAX517/518/519 IIO Driver for Maxim MAX517, MAX518 and MAX519 DAC Signed-off-by: Roland Stigge Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/dac/max517 | 41 ++++ drivers/staging/iio/dac/Kconfig | 10 + drivers/staging/iio/dac/Makefile | 1 + drivers/staging/iio/dac/max517.c | 293 +++++++++++++++++++++++++++ drivers/staging/iio/dac/max517.h | 19 ++ 5 files changed, 364 insertions(+) create mode 100644 drivers/staging/iio/Documentation/dac/max517 create mode 100644 drivers/staging/iio/dac/max517.c create mode 100644 drivers/staging/iio/dac/max517.h (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/dac/max517 b/drivers/staging/iio/Documentation/dac/max517 new file mode 100644 index 000000000000..e60ec2f91a7a --- /dev/null +++ b/drivers/staging/iio/Documentation/dac/max517 @@ -0,0 +1,41 @@ +Kernel driver max517 +==================== + +Supported chips: + * Maxim MAX517, MAX518, MAX519 + Prefix: 'max517' + Datasheet: Publicly available at the Maxim website + http://www.maxim-ic.com/ + +Author: + Roland Stigge + +Description +----------- + +The Maxim MAX517/518/519 is an 8-bit DAC on the I2C bus. The following table +shows the different feature sets of the variants MAX517, MAX518 and MAX519: + +Feature MAX517 MAX518 MAX519 +-------------------------------------------------------------------------- +One output channel X +Two output channels X X +Simultaneous output updates X X +Supply voltage as reference X +Separate reference input X +Reference input for each DAC X + +Via the iio sysfs interface, there are three attributes available: out1_raw, +out2_raw and out12_raw. With out1_raw and out2_raw, the current output values +(0..255) of the DACs can be written to the device. out12_raw can be used to set +both output channel values simultaneously. + +With MAX517, only out1_raw is available. + +Via out1_scale (and where appropriate, out2_scale), the current scaling factor +in mV can be read. + +When the operating system goes to a power down state, the Power Down function +of the chip is activated, reducing the supply current to 4uA. + +On power-up, the device is in 0V-output state. diff --git a/drivers/staging/iio/dac/Kconfig b/drivers/staging/iio/dac/Kconfig index 9191bd23cc08..2120904ae85d 100644 --- a/drivers/staging/iio/dac/Kconfig +++ b/drivers/staging/iio/dac/Kconfig @@ -19,3 +19,13 @@ config AD5446 To compile this driver as a module, choose M here: the module will be called ad5446. + +config MAX517 + tristate "Maxim MAX517/518/519 DAC driver" + depends on I2C && EXPERIMENTAL + help + If you say yes here you get support for the Maxim chips MAX517, + MAX518 and MAX519 (I2C 8-Bit DACs with rail-to-rail outputs). + + This driver can also be built as a module. If so, the module + will be called max517. diff --git a/drivers/staging/iio/dac/Makefile b/drivers/staging/iio/dac/Makefile index 7cf331b4e001..1197aef54abb 100644 --- a/drivers/staging/iio/dac/Makefile +++ b/drivers/staging/iio/dac/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_AD5624R_SPI) += ad5624r_spi.o obj-$(CONFIG_AD5446) += ad5446.o +obj-$(CONFIG_MAX517) += max517.o diff --git a/drivers/staging/iio/dac/max517.c b/drivers/staging/iio/dac/max517.c new file mode 100644 index 000000000000..4974e70f66a0 --- /dev/null +++ b/drivers/staging/iio/dac/max517.c @@ -0,0 +1,293 @@ +/* + * max517.c - Support for Maxim MAX517, MAX518 and MAX519 + * + * Copyright (C) 2010, 2011 Roland Stigge + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "dac.h" + +#include "max517.h" + +#define MAX517_DRV_NAME "max517" + +/* Commands */ +#define COMMAND_CHANNEL0 0x00 +#define COMMAND_CHANNEL1 0x01 /* for MAX518 and MAX519 */ +#define COMMAND_PD 0x08 /* Power Down */ + +enum max517_device_ids { + ID_MAX517, + ID_MAX518, + ID_MAX519, +}; + +struct max517_data { + struct iio_dev *indio_dev; + unsigned short vref_mv[2]; +}; + +/* + * channel: bit 0: channel 1 + * bit 1: channel 2 + * (this way, it's possible to set both channels at once) + */ +static ssize_t max517_set_value(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count, int channel) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 outbuf[4]; /* 1x or 2x command + value */ + int outbuf_size = 0; + int res; + long val; + + res = strict_strtol(buf, 10, &val); + + if (res) + return res; + + if (val < 0 || val > 255) + return -EINVAL; + + if (channel & 1) { + outbuf[outbuf_size++] = COMMAND_CHANNEL0; + outbuf[outbuf_size++] = val; + } + if (channel & 2) { + outbuf[outbuf_size++] = COMMAND_CHANNEL1; + outbuf[outbuf_size++] = val; + } + + /* + * At this point, there are always 1 or 2 two-byte commands in + * outbuf. With 2 commands, the device can set two outputs + * simultaneously, latching the values upon the end of the I2C + * transfer. + */ + + res = i2c_master_send(client, outbuf, outbuf_size); + if (res < 0) + return res; + + return count; +} + +static ssize_t max517_set_value_1(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return max517_set_value(dev, attr, buf, count, 1); +} +static IIO_DEV_ATTR_OUT_RAW(1, max517_set_value_1, 0); + +static ssize_t max517_set_value_2(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return max517_set_value(dev, attr, buf, count, 2); +} +static IIO_DEV_ATTR_OUT_RAW(2, max517_set_value_2, 1); + +static ssize_t max517_set_value_both(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return max517_set_value(dev, attr, buf, count, 3); +} +static IIO_DEVICE_ATTR_NAMED(out1and2_raw, out1&2_raw, S_IWUSR, NULL, + max517_set_value_both, -1); + +static ssize_t max517_show_scale(struct device *dev, + struct device_attribute *attr, + char *buf, int channel) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct max517_data *data = iio_dev_get_devdata(dev_info); + /* Corresponds to Vref / 2^(bits) */ + unsigned int scale_uv = (data->vref_mv[channel - 1] * 1000) >> 8; + + return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000); +} + +static ssize_t max517_show_scale1(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return max517_show_scale(dev, attr, buf, 1); +} +static IIO_DEVICE_ATTR(out1_scale, S_IRUGO, max517_show_scale1, NULL, 0); + +static ssize_t max517_show_scale2(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return max517_show_scale(dev, attr, buf, 2); +} +static IIO_DEVICE_ATTR(out2_scale, S_IRUGO, max517_show_scale2, NULL, 0); + +/* On MAX517 variant, we have two outputs */ +static struct attribute *max517_attributes[] = { + &iio_dev_attr_out1_raw.dev_attr.attr, + &iio_dev_attr_out1_scale.dev_attr.attr, + NULL +}; + +static struct attribute_group max517_attribute_group = { + .attrs = max517_attributes, +}; + +/* On MAX518 and MAX518 variant, we have two outputs */ +static struct attribute *max518_attributes[] = { + &iio_dev_attr_out1_raw.dev_attr.attr, + &iio_dev_attr_out1_scale.dev_attr.attr, + &iio_dev_attr_out2_raw.dev_attr.attr, + &iio_dev_attr_out2_scale.dev_attr.attr, + &iio_dev_attr_out1and2_raw.dev_attr.attr, + NULL +}; + +static struct attribute_group max518_attribute_group = { + .attrs = max518_attributes, +}; + +static int max517_suspend(struct i2c_client *client, pm_message_t mesg) +{ + u8 outbuf = COMMAND_PD; + + return i2c_master_send(client, &outbuf, 1); +} + +static int max517_resume(struct i2c_client *client) +{ + u8 outbuf = 0; + + return i2c_master_send(client, &outbuf, 1); +} + +static int max517_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct max517_data *data; + struct max517_platform_data *platform_data = client->dev.platform_data; + int err; + + data = kzalloc(sizeof(struct max517_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + + data->indio_dev = iio_allocate_device(); + if (data->indio_dev == NULL) { + err = -ENOMEM; + goto exit_free_data; + } + + /* establish that the iio_dev is a child of the i2c device */ + data->indio_dev->dev.parent = &client->dev; + + /* reduced attribute set for MAX517 */ + if (id->driver_data == ID_MAX517) + data->indio_dev->attrs = &max517_attribute_group; + else + data->indio_dev->attrs = &max518_attribute_group; + data->indio_dev->dev_data = (void *)(data); + data->indio_dev->driver_module = THIS_MODULE; + data->indio_dev->modes = INDIO_DIRECT_MODE; + + /* + * Reference voltage on MAX518 and default is 5V, else take vref_mv + * from platform_data + */ + if (id->driver_data == ID_MAX518 || !platform_data) { + data->vref_mv[0] = data->vref_mv[1] = 5000; /* mV */ + } else { + data->vref_mv[0] = platform_data->vref_mv[0]; + data->vref_mv[1] = platform_data->vref_mv[1]; + } + + err = iio_device_register(data->indio_dev); + if (err) + goto exit_free_device; + + dev_info(&client->dev, "DAC registered\n"); + + return 0; + +exit_free_device: + iio_free_device(data->indio_dev); +exit_free_data: + kfree(data); +exit: + return err; +} + +static int max517_remove(struct i2c_client *client) +{ + struct max517_data *data = i2c_get_clientdata(client); + + iio_free_device(data->indio_dev); + kfree(data); + + return 0; +} + +static const struct i2c_device_id max517_id[] = { + { "max517", ID_MAX517 }, + { "max518", ID_MAX518 }, + { "max519", ID_MAX519 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, max517_id); + +static struct i2c_driver max517_driver = { + .driver = { + .name = MAX517_DRV_NAME, + }, + .probe = max517_probe, + .remove = max517_remove, + .suspend = max517_suspend, + .resume = max517_resume, + .id_table = max517_id, +}; + +static int __init max517_init(void) +{ + return i2c_add_driver(&max517_driver); +} + +static void __exit max517_exit(void) +{ + i2c_del_driver(&max517_driver); +} + +MODULE_AUTHOR("Roland Stigge "); +MODULE_DESCRIPTION("MAX517/MAX518/MAX519 8-bit DAC"); +MODULE_LICENSE("GPL"); + +module_init(max517_init); +module_exit(max517_exit); diff --git a/drivers/staging/iio/dac/max517.h b/drivers/staging/iio/dac/max517.h new file mode 100644 index 000000000000..8106cf24642a --- /dev/null +++ b/drivers/staging/iio/dac/max517.h @@ -0,0 +1,19 @@ +/* + * MAX517 DAC driver + * + * Copyright 2011 Roland Stigge + * + * Licensed under the GPL-2 or later. + */ +#ifndef IIO_DAC_MAX517_H_ +#define IIO_DAC_MAX517_H_ + +/* + * TODO: struct max517_platform_data needs to go into include/linux/iio + */ + +struct max517_platform_data { + u16 vref_mv[2]; +}; + +#endif /* IIO_DAC_MAX517_H_ */ -- cgit v1.2.3 From e3dc896b21fbb4d23e2747dbe58bb9156c9e1a99 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 14 Jan 2011 14:54:13 -0600 Subject: staging: r8712u: Fix sparse message Signed-off-by: Larry Finger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_ioctl_linux.c | 1 + drivers/staging/rtl8712/rtl871x_mp_ioctl.c | 2 -- drivers/staging/rtl8712/rtl871x_mp_ioctl.h | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index 685a7b112d4b..0d288c159c1d 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -27,6 +27,7 @@ ******************************************************************************/ #define _RTL871X_IOCTL_LINUX_C_ +#define _RTL871X_MP_IOCTL_C_ #include "osdep_service.h" #include "drv_types.h" diff --git a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c index d60aaa9c4872..5eb461b4a491 100644 --- a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c +++ b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c @@ -26,8 +26,6 @@ * ******************************************************************************/ -#define _RTL871X_MP_IOCTL_C_ - #include "osdep_service.h" #include "drv_types.h" #include "mlme_osdep.h" diff --git a/drivers/staging/rtl8712/rtl871x_mp_ioctl.h b/drivers/staging/rtl8712/rtl871x_mp_ioctl.h index 2225bd15466b..fdd2278936d8 100644 --- a/drivers/staging/rtl8712/rtl871x_mp_ioctl.h +++ b/drivers/staging/rtl8712/rtl871x_mp_ioctl.h @@ -373,7 +373,7 @@ unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv); #ifdef _RTL871X_MP_IOCTL_C_ /* CAUTION!!! */ /* This ifdef _MUST_ be left in!! */ -struct mp_ioctl_handler mp_ioctl_hdl[] = { +static struct mp_ioctl_handler mp_ioctl_hdl[] = { {sizeof(u32), oid_rt_pro_start_test_hdl, OID_RT_PRO_START_TEST},/*0*/ {sizeof(u32), oid_rt_pro_stop_test_hdl, -- cgit v1.2.3 From c84a7028cc4957e39af5ed8b1a3c8acda24a2a89 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 14 Jan 2011 14:54:18 -0600 Subject: staging: r8712u: Switch driver to use external firmware from linux-firmware Signed-off-by: Larry Finger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/TODO | 2 -- drivers/staging/rtl8712/hal_init.c | 22 +++++++++++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/TODO b/drivers/staging/rtl8712/TODO index 2aa5deb3af7b..d8dfe5bfe702 100644 --- a/drivers/staging/rtl8712/TODO +++ b/drivers/staging/rtl8712/TODO @@ -3,8 +3,6 @@ TODO: - switch to use LIB80211 - switch to use MAC80211 - checkpatch.pl fixes - only a few remain -- switch from large inline firmware file to use the firmware interface - and add the file to the linux-firmware package. Please send any patches to Greg Kroah-Hartman , Larry Finger and diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c index 32088a641eba..014fbbcbda27 100644 --- a/drivers/staging/rtl8712/hal_init.c +++ b/drivers/staging/rtl8712/hal_init.c @@ -31,7 +31,6 @@ #include "osdep_service.h" #include "drv_types.h" #include "rtl871x_byteorder.h" -#include "farray.h" #include "usb_osintf.h" #define FWBUFF_ALIGN_SZ 512 @@ -40,11 +39,24 @@ static u32 rtl871x_open_fw(struct _adapter *padapter, void **pphfwfile_hdl, const u8 **ppmappedfw) { - u32 len; + int rc; + const char firmware_file[] = "rtl8712u/rtl8712u.bin"; + const struct firmware **praw = (const struct firmware **) + (pphfwfile_hdl); + struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *) + (&padapter->dvobjpriv); + struct usb_device *pusbdev = pdvobjpriv->pusbdev; - *ppmappedfw = f_array; - len = sizeof(f_array); - return len; + printk(KERN_INFO "r8712u: Loading firmware from \"%s\"\n", + firmware_file); + rc = request_firmware(praw, firmware_file, &pusbdev->dev); + if (rc < 0) { + printk(KERN_ERR "r8712u: Unable to load firmware\n"); + printk(KERN_ERR "r8712u: Install latest linux-firmware\n"); + return 0; + } + *ppmappedfw = (u8 *)((*praw)->data); + return (*praw)->size; } static void fill_fwpriv(struct _adapter *padapter, struct fw_priv *pfwpriv) -- cgit v1.2.3 From b54a28a418b2730bf61554864fee3fb24f79e182 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 14 Jan 2011 15:02:18 -0600 Subject: staging: r8712u: Firmware changes for driver * select FW_LOADER in Kconfig - From: Stefan Lippers-Hollmann * declare MODULE_FIRMWARE for r8712u and change to correct directory * delete 10K line farray.h containing internal firmware Signed-off-by: Larry Finger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/Kconfig | 1 + drivers/staging/rtl8712/farray.h | 10197 ----------------------------------- drivers/staging/rtl8712/hal_init.c | 3 +- 3 files changed, 3 insertions(+), 10198 deletions(-) delete mode 100644 drivers/staging/rtl8712/farray.h (limited to 'drivers') diff --git a/drivers/staging/rtl8712/Kconfig b/drivers/staging/rtl8712/Kconfig index 1e9a230a4db1..041e1e81f315 100644 --- a/drivers/staging/rtl8712/Kconfig +++ b/drivers/staging/rtl8712/Kconfig @@ -3,6 +3,7 @@ config R8712U depends on WLAN && USB select WIRELESS_EXT select WEXT_PRIV + select FW_LOADER default N ---help--- This option adds the Realtek RTL8712 USB device such as the D-Link DWA-130. diff --git a/drivers/staging/rtl8712/farray.h b/drivers/staging/rtl8712/farray.h deleted file mode 100644 index 921777269709..000000000000 --- a/drivers/staging/rtl8712/farray.h +++ /dev/null @@ -1,10197 +0,0 @@ -/* Firmware */ -static const unsigned char f_array[122328] = { -0x12, 0x87, 0xEC, 0x11, 0x30, 0x00, 0x00, 0x00, 0x08, 0xE8, 0x00, 0x00, -0x50, 0xF5, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x98, 0xF3, 0x00, 0x00, -0xF2, 0x00, 0x00, 0x00, 0x05, 0x30, 0x16, 0x53, 0x87, 0x12, 0x12, 0x01, -0x00, 0x00, 0x12, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, -0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x10, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x25, 0xB0, 0x1A, 0x3C, 0x80, 0x03, 0x5A, 0x37, 0x00, 0x80, 0x1B, 0x3C, -0x80, 0x00, 0x7B, 0x37, 0x00, 0x00, 0x5B, 0xAF, 0x25, 0xB0, 0x1A, 0x3C, -0x18, 0x03, 0x5A, 0x37, 0x00, 0x80, 0x1B, 0x3C, 0x80, 0x00, 0x7B, 0x37, -0x00, 0x00, 0x5B, 0xAF, 0x01, 0x80, 0x1A, 0x3C, 0x24, 0xE2, 0x5A, 0x27, -0x08, 0x00, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xA1, 0xAF, 0x08, 0x00, 0xA2, 0xAF, -0x0C, 0x00, 0xA3, 0xAF, 0x10, 0x00, 0xA4, 0xAF, 0x14, 0x00, 0xA5, 0xAF, -0x18, 0x00, 0xA6, 0xAF, 0x1C, 0x00, 0xA7, 0xAF, 0x20, 0x00, 0xA8, 0xAF, -0x24, 0x00, 0xA9, 0xAF, 0x28, 0x00, 0xAA, 0xAF, 0x2C, 0x00, 0xAB, 0xAF, -0x30, 0x00, 0xAC, 0xAF, 0x34, 0x00, 0xAD, 0xAF, 0x38, 0x00, 0xAE, 0xAF, -0x3C, 0x00, 0xAF, 0xAF, 0x12, 0x40, 0x00, 0x00, 0x10, 0x48, 0x00, 0x00, -0x00, 0x70, 0x0A, 0x40, 0x40, 0x00, 0xB0, 0xAF, 0x44, 0x00, 0xB1, 0xAF, -0x48, 0x00, 0xB2, 0xAF, 0x4C, 0x00, 0xB3, 0xAF, 0x50, 0x00, 0xB4, 0xAF, -0x54, 0x00, 0xB5, 0xAF, 0x58, 0x00, 0xB6, 0xAF, 0x5C, 0x00, 0xB7, 0xAF, -0x60, 0x00, 0xB8, 0xAF, 0x64, 0x00, 0xB9, 0xAF, 0x68, 0x00, 0xBC, 0xAF, -0x6C, 0x00, 0xBD, 0xAF, 0x70, 0x00, 0xBE, 0xAF, 0x74, 0x00, 0xBF, 0xAF, -0x78, 0x00, 0xA8, 0xAF, 0x7C, 0x00, 0xA9, 0xAF, 0x80, 0x00, 0xAA, 0xAF, -0x17, 0x38, 0x00, 0x08, 0x21, 0x20, 0xA0, 0x03, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xBD, 0x27, -0x14, 0x00, 0xB1, 0xAF, 0x00, 0x80, 0x02, 0x3C, 0x25, 0xB0, 0x11, 0x3C, -0x18, 0x03, 0x23, 0x36, 0x00, 0x03, 0x42, 0x24, 0x00, 0x00, 0x62, 0xAC, -0x18, 0x00, 0xB2, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x1C, 0x00, 0xBF, 0xAF, -0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x42, 0xB0, 0x02, 0x3C, -0x03, 0x00, 0x47, 0x34, 0x00, 0x00, 0xE3, 0x90, 0x02, 0x80, 0x0A, 0x3C, -0x02, 0x80, 0x0B, 0x3C, 0xFF, 0x00, 0x70, 0x30, 0x00, 0x36, 0x10, 0x00, -0x10, 0x00, 0x02, 0x32, 0x03, 0x36, 0x06, 0x00, 0x17, 0x00, 0x40, 0x10, -0x02, 0x80, 0x12, 0x3C, 0xFC, 0x5C, 0x42, 0x8D, 0x60, 0x1B, 0x44, 0x26, -0x64, 0x37, 0x83, 0x94, 0x01, 0x00, 0x45, 0x24, 0x10, 0x00, 0x02, 0x24, -0xB0, 0x03, 0x29, 0x36, 0x1C, 0x03, 0x28, 0x36, 0x00, 0x00, 0xE2, 0xA0, -0x07, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x68, 0x37, 0x82, 0x94, -0x64, 0x37, 0x80, 0xA4, 0x68, 0x37, 0x80, 0xA4, 0x00, 0x00, 0x03, 0x24, -0x00, 0x00, 0x02, 0xAD, 0x00, 0x00, 0x20, 0xAD, 0x10, 0x5E, 0x62, 0x8D, -0x01, 0x00, 0x63, 0x24, 0xFC, 0x5C, 0x45, 0xAD, 0x01, 0x00, 0x42, 0x24, -0x10, 0x5E, 0x62, 0xAD, 0x64, 0x37, 0x83, 0xA4, 0x29, 0x00, 0xC0, 0x04, -0x42, 0xB0, 0x02, 0x3C, 0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x40, 0x00, 0x02, 0x32, 0x0F, 0x00, 0x40, 0x14, 0x60, 0x1B, 0x44, 0x26, -0xE0, 0x1B, 0x83, 0x94, 0xDC, 0x1B, 0x85, 0x94, 0x1C, 0x00, 0xBF, 0x8F, -0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x80, 0x00, 0x63, 0x30, 0x41, 0xB0, 0x02, 0x3C, 0x25, 0x18, 0x65, 0x00, -0x08, 0x00, 0x42, 0x34, 0x20, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x43, 0xA4, -0x08, 0x00, 0xE0, 0x03, 0xDC, 0x1B, 0x83, 0xA4, 0x42, 0xB0, 0x02, 0x3C, -0x40, 0x00, 0x03, 0x24, 0x03, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0xA0, -0x25, 0x62, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x44, 0x26, -0xE0, 0x1B, 0x83, 0x94, 0xDC, 0x1B, 0x85, 0x94, 0x1C, 0x00, 0xBF, 0x8F, -0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x80, 0x00, 0x63, 0x30, 0x41, 0xB0, 0x02, 0x3C, 0x25, 0x18, 0x65, 0x00, -0x08, 0x00, 0x42, 0x34, 0x20, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x43, 0xA4, -0x08, 0x00, 0xE0, 0x03, 0xDC, 0x1B, 0x83, 0xA4, 0x80, 0xFF, 0x03, 0x24, -0x03, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0xA0, 0x44, 0x22, 0x00, 0x74, -0x00, 0x00, 0x00, 0x00, 0xEF, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0xFF, 0x00, 0x84, 0x30, 0x0B, 0x00, 0x82, 0x2C, 0xFF, 0xFF, 0xE7, 0x30, -0x10, 0x00, 0xA8, 0x93, 0x19, 0x00, 0x40, 0x10, 0x21, 0x18, 0x00, 0x00, -0x02, 0x80, 0x03, 0x3C, 0x80, 0x10, 0x04, 0x00, 0x88, 0xE6, 0x63, 0x24, -0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x44, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0xB0, 0x02, 0x3C, -0x78, 0x00, 0x44, 0x34, 0x07, 0x00, 0xE2, 0x30, 0x00, 0x00, 0x85, 0xAC, -0x04, 0x00, 0x86, 0xAC, 0x04, 0x00, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, -0xF8, 0xFF, 0xE2, 0x30, 0x08, 0x00, 0x42, 0x24, 0xFF, 0xFF, 0x47, 0x30, -0x21, 0x10, 0xE8, 0x00, 0x00, 0x80, 0x03, 0x3C, 0x08, 0x00, 0x82, 0xAC, -0x25, 0x10, 0x43, 0x00, 0x08, 0x00, 0x82, 0xAC, 0x01, 0x00, 0x03, 0x24, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, 0x43, 0xB0, 0x02, 0x3C, -0x2E, 0x01, 0x00, 0x08, 0x6C, 0x00, 0x44, 0x34, 0x43, 0xB0, 0x02, 0x3C, -0x2E, 0x01, 0x00, 0x08, 0x60, 0x00, 0x44, 0x34, 0x43, 0xB0, 0x02, 0x3C, -0x2E, 0x01, 0x00, 0x08, 0x54, 0x00, 0x44, 0x34, 0x43, 0xB0, 0x02, 0x3C, -0x2E, 0x01, 0x00, 0x08, 0x48, 0x00, 0x44, 0x34, 0x43, 0xB0, 0x02, 0x3C, -0x2E, 0x01, 0x00, 0x08, 0x3C, 0x00, 0x44, 0x34, 0x43, 0xB0, 0x02, 0x3C, -0x2E, 0x01, 0x00, 0x08, 0x30, 0x00, 0x44, 0x34, 0x43, 0xB0, 0x02, 0x3C, -0x2E, 0x01, 0x00, 0x08, 0x24, 0x00, 0x44, 0x34, 0x43, 0xB0, 0x02, 0x3C, -0x2E, 0x01, 0x00, 0x08, 0x18, 0x00, 0x44, 0x34, 0x43, 0xB0, 0x02, 0x3C, -0x2E, 0x01, 0x00, 0x08, 0x0C, 0x00, 0x44, 0x34, 0x2E, 0x01, 0x00, 0x08, -0x43, 0xB0, 0x04, 0x3C, 0x00, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, -0x18, 0x03, 0x42, 0x34, 0x6C, 0x05, 0x63, 0x24, 0x00, 0x00, 0x43, 0xAC, -0x01, 0x00, 0x05, 0x24, 0x43, 0xB0, 0x02, 0x3C, 0x04, 0x28, 0x85, 0x00, -0x88, 0x00, 0x44, 0x34, 0x21, 0x10, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, -0xFF, 0xFF, 0x42, 0x30, 0x05, 0x00, 0x43, 0x2C, 0xFD, 0xFF, 0x60, 0x14, -0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x82, 0x94, 0x00, 0x00, 0x00, 0x00, -0xFF, 0xFF, 0x42, 0x30, 0x24, 0x10, 0x45, 0x00, 0xF5, 0xFF, 0x40, 0x1C, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0x25, 0xB0, 0x08, 0x3C, 0x00, 0x80, 0x02, 0x3C, 0xC8, 0xFF, 0xBD, 0x27, -0x18, 0x03, 0x03, 0x35, 0xC8, 0x05, 0x42, 0x24, 0x00, 0x00, 0x62, 0xAC, -0x30, 0x00, 0xB6, 0xAF, 0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, -0x1C, 0x00, 0xB1, 0xAF, 0x34, 0x00, 0xBF, 0xAF, 0x2C, 0x00, 0xB5, 0xAF, -0x20, 0x00, 0xB2, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x0C, 0x00, 0xF2, 0x84, -0x08, 0x00, 0xF5, 0x8C, 0xFF, 0x00, 0xC6, 0x30, 0x00, 0x01, 0x02, 0x24, -0x23, 0x10, 0x46, 0x00, 0xFF, 0xFF, 0x51, 0x30, 0xD0, 0x03, 0x08, 0x35, -0xFF, 0x00, 0x96, 0x30, 0x00, 0x00, 0x12, 0xAD, 0x21, 0xA0, 0xA0, 0x00, -0x21, 0x30, 0xC5, 0x00, 0x00, 0x00, 0x15, 0xAD, 0x21, 0x20, 0xC0, 0x02, -0x21, 0x28, 0xA0, 0x02, 0x21, 0x38, 0x20, 0x02, 0x1E, 0x01, 0x00, 0x0C, -0x10, 0x00, 0xA0, 0xAF, 0x23, 0x18, 0x51, 0x02, 0xFF, 0xFF, 0x82, 0x32, -0x00, 0x94, 0x03, 0x00, 0x03, 0x94, 0x12, 0x00, 0xB4, 0x01, 0x00, 0x08, -0x02, 0x9A, 0x02, 0x00, 0x28, 0xB0, 0x03, 0x3C, 0xC0, 0x10, 0x13, 0x00, -0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x44, 0x90, 0x25, 0xB0, 0x10, 0x3C, -0x20, 0x10, 0x02, 0x3C, 0xFF, 0x00, 0x93, 0x30, 0x00, 0x22, 0x13, 0x00, -0xFF, 0xFF, 0x43, 0x32, 0x01, 0x01, 0x45, 0x2A, 0x21, 0xA0, 0x82, 0x00, -0x21, 0xA8, 0xB1, 0x02, 0xD0, 0x03, 0x02, 0x36, 0x00, 0x01, 0x11, 0x24, -0x0B, 0x88, 0x65, 0x00, 0x21, 0x20, 0xC0, 0x02, 0x00, 0x00, 0x53, 0xAC, -0x5B, 0x01, 0x00, 0x0C, 0xB0, 0x03, 0x10, 0x36, 0x21, 0x30, 0x80, 0x02, -0x21, 0x20, 0xC0, 0x02, 0x21, 0x28, 0xA0, 0x02, 0x21, 0x38, 0x20, 0x02, -0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, 0x23, 0x18, 0x51, 0x02, -0x00, 0x94, 0x03, 0x00, 0x03, 0x94, 0x12, 0x00, 0x00, 0x00, 0x12, 0xAE, -0xE2, 0xFF, 0x40, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0xBF, 0x8F, -0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F, -0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x38, 0x00, 0xBD, 0x27, -0x21, 0x50, 0x80, 0x00, 0x04, 0x00, 0x8D, 0x8C, 0x0C, 0x00, 0x4B, 0x8D, -0x08, 0x00, 0x84, 0x8C, 0xFF, 0xE0, 0x02, 0x3C, 0x10, 0x00, 0x47, 0x8D, -0xFF, 0xFF, 0x42, 0x34, 0x1F, 0x00, 0xA9, 0x31, 0x24, 0x20, 0x82, 0x00, -0x00, 0x1E, 0x09, 0x00, 0x02, 0x14, 0x0B, 0x00, 0x25, 0x40, 0x83, 0x00, -0x21, 0x78, 0xA0, 0x00, 0xB7, 0x00, 0xE0, 0x04, 0x07, 0x00, 0x44, 0x30, -0x00, 0x00, 0x42, 0x95, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0F, 0x42, 0x28, -0xB9, 0x00, 0x40, 0x10, 0xFF, 0xDF, 0x02, 0x3C, 0x02, 0x80, 0x0E, 0x3C, -0x08, 0x00, 0x48, 0xAD, 0x60, 0x1B, 0xC3, 0x25, 0xC6, 0x3D, 0x62, 0x90, -0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x40, 0x14, 0xC0, 0x30, 0x09, 0x00, -0xC6, 0x40, 0x62, 0x90, 0xFF, 0xDF, 0x03, 0x3C, 0xFF, 0xFF, 0x63, 0x34, -0x07, 0x10, 0x82, 0x00, 0x01, 0x00, 0x42, 0x30, 0x24, 0x18, 0x03, 0x01, -0x40, 0x17, 0x02, 0x00, 0x25, 0x40, 0x62, 0x00, 0x08, 0x00, 0x48, 0xAD, -0xC0, 0x30, 0x09, 0x00, 0x21, 0x10, 0xC9, 0x00, 0x80, 0x10, 0x02, 0x00, -0x21, 0x10, 0x49, 0x00, 0x80, 0x10, 0x02, 0x00, 0x60, 0x1B, 0xC9, 0x25, -0x21, 0x28, 0x49, 0x00, 0x08, 0x25, 0xA3, 0x8C, 0x01, 0x00, 0x0C, 0x24, -0x02, 0x13, 0x03, 0x00, 0x01, 0x00, 0x42, 0x30, 0xB5, 0x00, 0x4C, 0x10, -0x42, 0x18, 0x03, 0x00, 0x82, 0x11, 0x08, 0x00, 0x01, 0x00, 0x42, 0x30, -0x06, 0x00, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, 0xC0, 0xFF, 0x02, 0x24, -0x24, 0x10, 0x02, 0x01, 0x04, 0x00, 0x48, 0x34, 0x08, 0x00, 0x48, 0xAD, -0x02, 0x80, 0x02, 0x3C, 0xD1, 0x5C, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, -0x6A, 0x00, 0x60, 0x14, 0x21, 0x20, 0xC9, 0x00, 0xD4, 0x23, 0x83, 0x8C, -0xBF, 0xFF, 0x02, 0x24, 0x24, 0x10, 0xE2, 0x00, 0x40, 0x00, 0x63, 0x30, -0x25, 0x38, 0x43, 0x00, 0x10, 0x00, 0x47, 0xAD, 0xD4, 0x23, 0x83, 0x8C, -0x7F, 0xF8, 0x02, 0x24, 0x24, 0x10, 0xE2, 0x00, 0x80, 0x07, 0x63, 0x30, -0x25, 0x38, 0x43, 0x00, 0x10, 0x00, 0x47, 0xAD, 0xC6, 0x3D, 0x22, 0x91, -0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x40, 0x14, 0x42, 0x17, 0x08, 0x00, -0x01, 0x00, 0x44, 0x30, 0xB1, 0x00, 0x8C, 0x10, 0x02, 0x80, 0x02, 0x3C, -0x60, 0x1B, 0xC4, 0x25, 0x21, 0x20, 0xC4, 0x00, 0xD4, 0x23, 0x83, 0x8C, -0xFF, 0xF7, 0x02, 0x24, 0x24, 0x10, 0xE2, 0x00, 0x00, 0x08, 0x63, 0x30, -0x25, 0x38, 0x43, 0x00, 0x10, 0x00, 0x47, 0xAD, 0xD4, 0x23, 0x83, 0x8C, -0xFF, 0xEF, 0x02, 0x24, 0x24, 0x10, 0xE2, 0x00, 0x00, 0x10, 0x63, 0x30, -0x25, 0x38, 0x43, 0x00, 0x10, 0x00, 0x47, 0xAD, 0x60, 0x1B, 0xC5, 0x25, -0x21, 0x30, 0xC5, 0x00, 0xD4, 0x23, 0xC4, 0x8C, 0xFD, 0xFF, 0x02, 0x3C, -0x02, 0x00, 0x03, 0x3C, 0xFF, 0xFF, 0x42, 0x34, 0x24, 0x20, 0x83, 0x00, -0x24, 0x10, 0xE2, 0x00, 0x25, 0x38, 0x44, 0x00, 0x10, 0x00, 0x47, 0xAD, -0xB0, 0x1B, 0xA3, 0x94, 0xFB, 0xFF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, -0xC2, 0x1B, 0x03, 0x00, 0x24, 0x10, 0xE2, 0x00, 0x80, 0x1C, 0x03, 0x00, -0x25, 0x38, 0x43, 0x00, 0x10, 0x00, 0x47, 0xAD, 0x3B, 0x41, 0xA3, 0x90, -0xE7, 0xFF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, 0x03, 0x00, 0x63, 0x30, -0x24, 0x10, 0xE2, 0x00, 0xC0, 0x1C, 0x03, 0x00, 0x25, 0x38, 0x43, 0x00, -0x10, 0x00, 0x47, 0xAD, 0xD4, 0x23, 0xC4, 0x8C, 0xFF, 0xFD, 0x02, 0x3C, -0x00, 0x02, 0x03, 0x3C, 0xFF, 0xFF, 0x42, 0x34, 0x24, 0x20, 0x83, 0x00, -0x24, 0x10, 0xE2, 0x00, 0x25, 0x38, 0x44, 0x00, 0x10, 0x00, 0x47, 0xAD, -0xB0, 0x1B, 0xA3, 0x94, 0xFF, 0xFB, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, -0xC2, 0x1B, 0x03, 0x00, 0x24, 0x10, 0xE2, 0x00, 0x80, 0x1E, 0x03, 0x00, -0x25, 0x38, 0x43, 0x00, 0x10, 0x00, 0x47, 0xAD, 0x3B, 0x41, 0xA3, 0x90, -0xFF, 0xE7, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, 0x03, 0x00, 0x63, 0x30, -0x24, 0x10, 0xE2, 0x00, 0xC0, 0x1E, 0x03, 0x00, 0x25, 0x38, 0x43, 0x00, -0x10, 0x00, 0x47, 0xAD, 0xD4, 0x23, 0xC3, 0x8C, 0xC0, 0xFF, 0x02, 0x24, -0x24, 0x10, 0xE2, 0x00, 0x3F, 0x00, 0x63, 0x30, 0x25, 0x10, 0x43, 0x00, -0x10, 0x00, 0x42, 0xAD, 0xD8, 0x23, 0xC4, 0x8C, 0x14, 0x00, 0x43, 0x8D, -0xFF, 0xFF, 0x02, 0x3C, 0xFF, 0x7F, 0x42, 0x34, 0x24, 0x18, 0x62, 0x00, -0x00, 0x80, 0x84, 0x30, 0x25, 0x18, 0x64, 0x00, 0x14, 0x00, 0x43, 0xAD, -0xDA, 0x23, 0xC4, 0x94, 0xE0, 0xFF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, -0x1F, 0x00, 0x84, 0x30, 0x24, 0x18, 0x62, 0x00, 0x00, 0x24, 0x04, 0x00, -0x25, 0x18, 0x64, 0x00, 0x14, 0x00, 0x43, 0xAD, 0x02, 0x00, 0x43, 0x91, -0x02, 0x14, 0x0D, 0x00, 0x01, 0x00, 0x42, 0x30, 0x27, 0x00, 0x40, 0x10, -0x21, 0x30, 0x6F, 0x00, 0x60, 0x1B, 0xC4, 0x25, 0xE4, 0x1D, 0x85, 0x94, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xA2, 0x24, 0xE4, 0x1D, 0x82, 0xA4, -0x0C, 0x00, 0x43, 0x8D, 0x00, 0xF0, 0x02, 0x3C, 0xFF, 0x0F, 0xA5, 0x30, -0xFF, 0xFF, 0x42, 0x34, 0x00, 0x24, 0x05, 0x00, 0x24, 0x18, 0x62, 0x00, -0x25, 0x58, 0x83, 0x00, 0x0C, 0x00, 0x4B, 0xAD, 0x16, 0x00, 0xC2, 0x94, -0x00, 0x19, 0x05, 0x00, 0x60, 0x1B, 0xC4, 0x25, 0x0F, 0x00, 0x42, 0x30, -0x25, 0x10, 0x43, 0x00, 0x16, 0x00, 0xC2, 0xA4, 0x00, 0x00, 0x43, 0x95, -0x40, 0x41, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x43, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x40, 0x41, 0x82, 0xAC, 0x14, 0x00, 0x42, 0x8D, -0x00, 0x00, 0x00, 0x00, 0x42, 0x12, 0x02, 0x00, 0x3F, 0x00, 0x42, 0x30, -0x0C, 0x00, 0x42, 0x28, 0x44, 0xFF, 0x40, 0x10, 0xFF, 0xDF, 0x02, 0x3C, -0xFF, 0xFF, 0x42, 0x34, 0x24, 0x40, 0x02, 0x01, 0x00, 0x40, 0x03, 0x3C, -0x25, 0x40, 0x03, 0x01, 0xE3, 0x01, 0x00, 0x08, 0x02, 0x80, 0x0E, 0x3C, -0x60, 0x1B, 0xC3, 0x25, 0xC6, 0x3D, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, -0x1D, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xC2, 0x13, 0x0B, 0x00, -0x0E, 0x00, 0x42, 0x30, 0x21, 0x10, 0x43, 0x00, 0xD4, 0x1D, 0x45, 0x94, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xA3, 0x24, 0xD4, 0x1D, 0x43, 0xA4, -0x0C, 0x00, 0x44, 0x8D, 0x00, 0xF0, 0x02, 0x3C, 0xFF, 0x0F, 0xA5, 0x30, -0xFF, 0xFF, 0x42, 0x34, 0x00, 0x1C, 0x05, 0x00, 0x77, 0x02, 0x00, 0x08, -0x24, 0x20, 0x82, 0x00, 0x7F, 0xFF, 0x02, 0x24, 0x24, 0x10, 0x02, 0x01, -0x80, 0x00, 0x63, 0x30, 0x25, 0x40, 0x43, 0x00, 0x08, 0x00, 0x48, 0xAD, -0x08, 0x25, 0xA3, 0x8C, 0xFF, 0xFF, 0x02, 0x3C, 0xFF, 0x1F, 0x42, 0x34, -0x07, 0x00, 0x63, 0x30, 0x24, 0x10, 0xE2, 0x00, 0x40, 0x1B, 0x03, 0x00, -0x25, 0x38, 0x43, 0x00, 0xF1, 0x01, 0x00, 0x08, 0x10, 0x00, 0x47, 0xAD, -0x02, 0x14, 0x0B, 0x00, 0xFF, 0x0F, 0x45, 0x30, 0x16, 0x00, 0xC2, 0x94, -0x00, 0x19, 0x05, 0x00, 0x60, 0x1B, 0xC4, 0x25, 0x0F, 0x00, 0x42, 0x30, -0x25, 0x10, 0x43, 0x00, 0x16, 0x00, 0xC2, 0xA4, 0x00, 0x00, 0x43, 0x95, -0x40, 0x41, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x43, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x40, 0x41, 0x82, 0xAC, 0xCE, 0x5C, 0x43, 0x90, -0x00, 0x00, 0x00, 0x00, 0x4E, 0xFF, 0x64, 0x14, 0x60, 0x1B, 0xC4, 0x25, -0x3C, 0x41, 0x22, 0x91, 0xFF, 0xF7, 0x03, 0x24, 0x24, 0x18, 0xE3, 0x00, -0x01, 0x00, 0x42, 0x30, 0xC0, 0x12, 0x02, 0x00, 0x25, 0x38, 0x62, 0x00, -0x10, 0x00, 0x47, 0xAD, 0x3D, 0x41, 0x22, 0x91, 0xFF, 0xEF, 0x03, 0x24, -0x24, 0x18, 0xE3, 0x00, 0x01, 0x00, 0x42, 0x30, 0x00, 0x13, 0x02, 0x00, -0x25, 0x38, 0x43, 0x00, 0x1F, 0x02, 0x00, 0x08, 0x10, 0x00, 0x47, 0xAD, -0xD8, 0xFF, 0xBD, 0x27, 0x20, 0x00, 0xB2, 0xAF, 0x18, 0x00, 0xB0, 0xAF, -0x24, 0x00, 0xBF, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, 0x04, 0x00, 0x8B, 0x8C, -0x21, 0x80, 0x80, 0x00, 0x08, 0x00, 0x84, 0x8C, 0x0E, 0x00, 0x07, 0x96, -0xFF, 0xE0, 0x02, 0x3C, 0x10, 0x00, 0x08, 0x8E, 0x1F, 0x00, 0x6A, 0x31, -0xFF, 0xFF, 0x42, 0x34, 0x24, 0x20, 0x82, 0x00, 0x00, 0x1E, 0x0A, 0x00, -0x25, 0x48, 0x83, 0x00, 0x21, 0x90, 0xA0, 0x00, 0x21, 0x60, 0xC0, 0x00, -0xCF, 0x00, 0x00, 0x05, 0x07, 0x00, 0xE7, 0x30, 0x00, 0x00, 0x02, 0x96, -0x00, 0x00, 0x00, 0x00, 0xFD, 0x0F, 0x42, 0x28, 0xD1, 0x00, 0x40, 0x10, -0xFF, 0xDF, 0x02, 0x3C, 0x02, 0x80, 0x11, 0x3C, 0x08, 0x00, 0x09, 0xAE, -0x60, 0x1B, 0x23, 0x26, 0xC6, 0x3D, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, -0x0A, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x40, 0x62, 0x90, -0xFF, 0xDF, 0x03, 0x3C, 0xFF, 0xFF, 0x63, 0x34, 0x07, 0x10, 0xE2, 0x00, -0x01, 0x00, 0x42, 0x30, 0x24, 0x18, 0x23, 0x01, 0x40, 0x17, 0x02, 0x00, -0x25, 0x48, 0x62, 0x00, 0x08, 0x00, 0x09, 0xAE, 0x1C, 0x00, 0x02, 0x8E, -0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x40, 0x04, 0x04, 0x00, 0x03, 0x24, -0xC0, 0x30, 0x0A, 0x00, 0x21, 0x10, 0xCA, 0x00, 0x80, 0x10, 0x02, 0x00, -0x21, 0x10, 0x4A, 0x00, 0x80, 0x10, 0x02, 0x00, 0x60, 0x1B, 0x27, 0x26, -0x21, 0x28, 0x47, 0x00, 0x08, 0x25, 0xA3, 0x8C, 0x01, 0x00, 0x0A, 0x24, -0x02, 0x13, 0x03, 0x00, 0x01, 0x00, 0x42, 0x30, 0xE7, 0x00, 0x4A, 0x10, -0x42, 0x18, 0x03, 0x00, 0x82, 0x11, 0x09, 0x00, 0x01, 0x00, 0x42, 0x30, -0x06, 0x00, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, 0xC0, 0xFF, 0x02, 0x24, -0x24, 0x10, 0x22, 0x01, 0x04, 0x00, 0x49, 0x34, 0x08, 0x00, 0x09, 0xAE, -0x02, 0x80, 0x02, 0x3C, 0xD1, 0x5C, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, -0x6C, 0x00, 0x60, 0x14, 0x21, 0x28, 0xC7, 0x00, 0xD4, 0x23, 0xA4, 0x8C, -0x10, 0x00, 0x02, 0x8E, 0xBF, 0xFF, 0x03, 0x24, 0x40, 0x00, 0x84, 0x30, -0x24, 0x10, 0x43, 0x00, 0x25, 0x40, 0x44, 0x00, 0x10, 0x00, 0x08, 0xAE, -0xD4, 0x23, 0xA3, 0x8C, 0x7F, 0xF8, 0x02, 0x24, 0x24, 0x10, 0x02, 0x01, -0x80, 0x07, 0x63, 0x30, 0x25, 0x40, 0x43, 0x00, 0x10, 0x00, 0x08, 0xAE, -0xC6, 0x3D, 0xE2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x40, 0x14, -0x60, 0x1B, 0x25, 0x26, 0x42, 0x17, 0x09, 0x00, 0x01, 0x00, 0x44, 0x30, -0x08, 0x01, 0x8A, 0x10, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x24, 0x26, -0x21, 0x20, 0xC4, 0x00, 0xD4, 0x23, 0x83, 0x8C, 0xFF, 0xF7, 0x02, 0x24, -0x24, 0x10, 0x02, 0x01, 0x00, 0x08, 0x63, 0x30, 0x25, 0x40, 0x43, 0x00, -0x10, 0x00, 0x08, 0xAE, 0xD4, 0x23, 0x83, 0x8C, 0xFF, 0xEF, 0x02, 0x24, -0x24, 0x10, 0x02, 0x01, 0x00, 0x10, 0x63, 0x30, 0x25, 0x40, 0x43, 0x00, -0x10, 0x00, 0x08, 0xAE, 0x60, 0x1B, 0x25, 0x26, 0x21, 0x30, 0xC5, 0x00, -0xD4, 0x23, 0xC4, 0x8C, 0xFD, 0xFF, 0x02, 0x3C, 0x02, 0x00, 0x03, 0x3C, -0xFF, 0xFF, 0x42, 0x34, 0x24, 0x20, 0x83, 0x00, 0x24, 0x10, 0x02, 0x01, -0x25, 0x40, 0x44, 0x00, 0x10, 0x00, 0x08, 0xAE, 0xB0, 0x1B, 0xA3, 0x94, -0xFB, 0xFF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, 0xC2, 0x1B, 0x03, 0x00, -0x24, 0x10, 0x02, 0x01, 0x80, 0x1C, 0x03, 0x00, 0x25, 0x40, 0x43, 0x00, -0x10, 0x00, 0x08, 0xAE, 0x3B, 0x41, 0xA3, 0x90, 0xE7, 0xFF, 0x02, 0x3C, -0xFF, 0xFF, 0x42, 0x34, 0x03, 0x00, 0x63, 0x30, 0x24, 0x10, 0x02, 0x01, -0xC0, 0x1C, 0x03, 0x00, 0x25, 0x40, 0x43, 0x00, 0x10, 0x00, 0x08, 0xAE, -0xD4, 0x23, 0xC4, 0x8C, 0xFF, 0xFD, 0x02, 0x3C, 0x00, 0x02, 0x03, 0x3C, -0xFF, 0xFF, 0x42, 0x34, 0x24, 0x20, 0x83, 0x00, 0x24, 0x10, 0x02, 0x01, -0x25, 0x40, 0x44, 0x00, 0x10, 0x00, 0x08, 0xAE, 0xB0, 0x1B, 0xA3, 0x94, -0xFF, 0xFB, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, 0xC2, 0x1B, 0x03, 0x00, -0x24, 0x10, 0x02, 0x01, 0x80, 0x1E, 0x03, 0x00, 0x25, 0x40, 0x43, 0x00, -0x10, 0x00, 0x08, 0xAE, 0x3B, 0x41, 0xA3, 0x90, 0xFF, 0xE7, 0x02, 0x3C, -0xFF, 0xFF, 0x42, 0x34, 0x03, 0x00, 0x63, 0x30, 0x24, 0x10, 0x02, 0x01, -0xC0, 0x1E, 0x03, 0x00, 0x25, 0x40, 0x43, 0x00, 0x10, 0x00, 0x08, 0xAE, -0xD4, 0x23, 0xC3, 0x8C, 0xC0, 0xFF, 0x02, 0x24, 0x24, 0x10, 0x02, 0x01, -0x3F, 0x00, 0x63, 0x30, 0x25, 0x10, 0x43, 0x00, 0x10, 0x00, 0x02, 0xAE, -0xD8, 0x23, 0xC4, 0x8C, 0x14, 0x00, 0x03, 0x8E, 0xFF, 0xFF, 0x02, 0x3C, -0xFF, 0x7F, 0x42, 0x34, 0x24, 0x18, 0x62, 0x00, 0x00, 0x80, 0x84, 0x30, -0x25, 0x18, 0x64, 0x00, 0x14, 0x00, 0x03, 0xAE, 0xDA, 0x23, 0xC4, 0x94, -0xE0, 0xFF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, 0x1F, 0x00, 0x84, 0x30, -0x24, 0x18, 0x62, 0x00, 0x00, 0x24, 0x04, 0x00, 0x25, 0x18, 0x64, 0x00, -0x14, 0x00, 0x03, 0xAE, 0x02, 0x00, 0x02, 0x92, 0x02, 0x24, 0x0B, 0x00, -0x02, 0x80, 0x03, 0x3C, 0x21, 0x10, 0x4C, 0x00, 0xFF, 0xFF, 0x42, 0x30, -0x01, 0x00, 0x84, 0x30, 0x36, 0x00, 0x80, 0x10, 0x25, 0x30, 0x43, 0x00, -0x60, 0x1B, 0x24, 0x26, 0xE4, 0x1D, 0x85, 0x94, 0x80, 0x00, 0x07, 0x24, -0x01, 0x00, 0xA2, 0x24, 0xE4, 0x1D, 0x82, 0xA4, 0x0C, 0x00, 0x03, 0x8E, -0x00, 0xF0, 0x02, 0x3C, 0xFF, 0x0F, 0xA5, 0x30, 0xFF, 0xFF, 0x42, 0x34, -0x00, 0x24, 0x05, 0x00, 0x24, 0x18, 0x62, 0x00, 0x25, 0x18, 0x64, 0x00, -0x0C, 0x00, 0x03, 0xAE, 0x16, 0x00, 0xC2, 0x94, 0x00, 0x19, 0x05, 0x00, -0x02, 0x00, 0x04, 0x24, 0x0F, 0x00, 0x42, 0x30, 0x25, 0x10, 0x43, 0x00, -0x16, 0x00, 0xC2, 0xA4, 0x21, 0x28, 0x80, 0x01, 0x21, 0x30, 0x40, 0x02, -0x01, 0x00, 0x02, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF, -0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, 0x00, 0x00, 0x52, 0xAC, -0x5B, 0x01, 0x00, 0x0C, 0x02, 0x00, 0x04, 0x24, 0x60, 0x1B, 0x24, 0x26, -0x00, 0x00, 0x03, 0x96, 0x40, 0x41, 0x82, 0x8C, 0x24, 0x00, 0xBF, 0x8F, -0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x21, 0x10, 0x43, 0x00, 0x28, 0x00, 0xBD, 0x27, 0x08, 0x00, 0xE0, 0x03, -0x40, 0x41, 0x82, 0xAC, 0x14, 0x00, 0x02, 0x8E, 0x00, 0x00, 0x00, 0x00, -0x42, 0x12, 0x02, 0x00, 0x3F, 0x00, 0x42, 0x30, 0x0C, 0x00, 0x42, 0x28, -0x2C, 0xFF, 0x40, 0x10, 0xFF, 0xDF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, -0x24, 0x48, 0x22, 0x01, 0x00, 0x40, 0x03, 0x3C, 0x25, 0x48, 0x23, 0x01, -0xFC, 0x02, 0x00, 0x08, 0x02, 0x80, 0x11, 0x3C, 0x60, 0x1B, 0x23, 0x26, -0xC6, 0x3D, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x40, 0x14, -0x80, 0x00, 0x07, 0x24, 0x0E, 0x00, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, -0x07, 0x00, 0x42, 0x30, 0x40, 0x10, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, -0xD4, 0x1D, 0x45, 0x94, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xA3, 0x24, -0xD4, 0x1D, 0x43, 0xA4, 0x0C, 0x00, 0x04, 0x8E, 0x00, 0xF0, 0x02, 0x3C, -0xFF, 0x0F, 0xA5, 0x30, 0xFF, 0xFF, 0x42, 0x34, 0x00, 0x1C, 0x05, 0x00, -0x24, 0x20, 0x82, 0x00, 0x25, 0x20, 0x83, 0x00, 0x0C, 0x00, 0x04, 0xAE, -0x16, 0x00, 0xC2, 0x94, 0x00, 0x19, 0x05, 0x00, 0x02, 0x00, 0x04, 0x24, -0x0F, 0x00, 0x42, 0x30, 0x25, 0x10, 0x43, 0x00, 0x16, 0x00, 0xC2, 0xA4, -0x21, 0x28, 0x80, 0x01, 0x21, 0x30, 0x40, 0x02, 0x01, 0x00, 0x02, 0x24, -0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF, 0x25, 0xB0, 0x02, 0x3C, -0xB0, 0x03, 0x42, 0x34, 0x00, 0x00, 0x52, 0xAC, 0x5B, 0x01, 0x00, 0x0C, -0x02, 0x00, 0x04, 0x24, 0x60, 0x1B, 0x24, 0x26, 0x00, 0x00, 0x03, 0x96, -0x40, 0x41, 0x82, 0x8C, 0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB2, 0x8F, -0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x43, 0x00, -0x28, 0x00, 0xBD, 0x27, 0x08, 0x00, 0xE0, 0x03, 0x40, 0x41, 0x82, 0xAC, -0x7F, 0xFF, 0x02, 0x24, 0x24, 0x10, 0x22, 0x01, 0x80, 0x00, 0x63, 0x30, -0x25, 0x48, 0x43, 0x00, 0x08, 0x00, 0x09, 0xAE, 0x08, 0x25, 0xA3, 0x8C, -0x10, 0x00, 0x04, 0x8E, 0xFF, 0xFF, 0x02, 0x3C, 0x07, 0x00, 0x63, 0x30, -0xFF, 0x1F, 0x42, 0x34, 0x24, 0x20, 0x82, 0x00, 0x40, 0x1B, 0x03, 0x00, -0x25, 0x40, 0x83, 0x00, 0x0E, 0x03, 0x00, 0x08, 0x10, 0x00, 0x08, 0xAE, -0x1E, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x21, 0x30, 0x50, 0x00, -0x00, 0x00, 0xC4, 0x90, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x82, 0x30, -0x02, 0x29, 0x02, 0x00, 0x3F, 0x00, 0xA3, 0x10, 0x06, 0x00, 0x02, 0x24, -0xF4, 0xFE, 0xA2, 0x14, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x02, 0x96, -0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0xC2, 0xA0, 0x1E, 0x00, 0x03, 0x92, -0x1A, 0x00, 0x02, 0x96, 0x21, 0x18, 0x70, 0x00, 0x03, 0x12, 0x02, 0x00, -0x38, 0x00, 0x62, 0xA0, 0x04, 0x00, 0x0B, 0x8E, 0x08, 0x00, 0x09, 0x8E, -0x02, 0x03, 0x00, 0x08, 0xC0, 0x30, 0x0A, 0x00, 0x0E, 0x00, 0x02, 0x96, -0x02, 0x00, 0x04, 0x24, 0xFF, 0x0F, 0x45, 0x30, 0x16, 0x00, 0xC2, 0x94, -0x00, 0x19, 0x05, 0x00, 0x21, 0x28, 0x80, 0x01, 0x0F, 0x00, 0x42, 0x30, -0x25, 0x10, 0x43, 0x00, 0x16, 0x00, 0xC2, 0xA4, 0x21, 0x30, 0x40, 0x02, -0x01, 0x00, 0x02, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF, -0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, 0x00, 0x00, 0x52, 0xAC, -0x5B, 0x01, 0x00, 0x0C, 0x02, 0x00, 0x04, 0x24, 0x60, 0x1B, 0x24, 0x26, -0x00, 0x00, 0x03, 0x96, 0x40, 0x41, 0x82, 0x8C, 0x24, 0x00, 0xBF, 0x8F, -0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x21, 0x10, 0x43, 0x00, 0x28, 0x00, 0xBD, 0x27, 0x08, 0x00, 0xE0, 0x03, -0x40, 0x41, 0x82, 0xAC, 0xCE, 0x5C, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, -0xF7, 0xFE, 0x64, 0x14, 0x60, 0x1B, 0x24, 0x26, 0x3C, 0x41, 0xE2, 0x90, -0xFF, 0xF7, 0x03, 0x24, 0x24, 0x18, 0x03, 0x01, 0x01, 0x00, 0x42, 0x30, -0xC0, 0x12, 0x02, 0x00, 0x25, 0x40, 0x62, 0x00, 0x10, 0x00, 0x08, 0xAE, -0x3D, 0x41, 0xE2, 0x90, 0xFF, 0xEF, 0x03, 0x24, 0x24, 0x18, 0x03, 0x01, -0x01, 0x00, 0x42, 0x30, 0x00, 0x13, 0x02, 0x00, 0x25, 0x40, 0x43, 0x00, -0x3E, 0x03, 0x00, 0x08, 0x10, 0x00, 0x08, 0xAE, 0x1A, 0x00, 0x05, 0x96, -0x0F, 0x00, 0x84, 0x30, 0x80, 0x20, 0x04, 0x00, 0x21, 0x18, 0xC4, 0x00, -0x11, 0x00, 0x65, 0xA0, 0x1E, 0x00, 0x02, 0x92, 0x1A, 0x00, 0x03, 0x96, -0x21, 0x10, 0x50, 0x00, 0x21, 0x10, 0x44, 0x00, 0x03, 0x1A, 0x03, 0x00, -0x10, 0x00, 0x43, 0xA0, 0x04, 0x00, 0x0B, 0x8E, 0x08, 0x00, 0x09, 0x8E, -0x02, 0x03, 0x00, 0x08, 0xC0, 0x30, 0x0A, 0x00, 0x00, 0x80, 0x03, 0x3C, -0x25, 0xB0, 0x02, 0x3C, 0x64, 0x11, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34, -0x00, 0x00, 0x43, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0xC0, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, 0x2C, 0x00, 0xB5, 0xAF, -0x25, 0xB0, 0x03, 0x3C, 0x60, 0x1B, 0x55, 0x24, 0x00, 0x80, 0x02, 0x3C, -0x38, 0x00, 0xBE, 0xAF, 0x80, 0x11, 0x42, 0x24, 0xB0, 0x03, 0x7E, 0x34, -0x18, 0x03, 0x63, 0x34, 0x00, 0x00, 0x62, 0xAC, 0x3C, 0x00, 0xBF, 0xAF, -0x34, 0x00, 0xB7, 0xAF, 0x30, 0x00, 0xB6, 0xAF, 0x28, 0x00, 0xB4, 0xAF, -0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, -0x96, 0x40, 0x00, 0x0C, 0x18, 0x00, 0xB0, 0xAF, 0x8E, 0x04, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0xAE, 0x08, 0x38, 0x46, 0x8E, -0x21, 0x28, 0x60, 0x02, 0x80, 0x00, 0x07, 0x24, 0x01, 0x00, 0x04, 0x24, -0x01, 0x00, 0x14, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xB4, 0xAF, -0x08, 0x38, 0x43, 0x8E, 0x01, 0x00, 0x04, 0x24, 0x00, 0x00, 0xC3, 0xAE, -0x5B, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x1C, 0x42, 0x92, -0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x40, 0x10, 0x2A, 0xB0, 0x02, 0x3C, -0x09, 0x00, 0x42, 0x34, 0x02, 0x00, 0x03, 0x24, 0x00, 0x00, 0x54, 0xA0, -0x00, 0x00, 0x43, 0xA0, 0xFF, 0x00, 0x03, 0x24, 0x71, 0x00, 0x23, 0x12, -0x00, 0x00, 0x00, 0x00, 0x04, 0x38, 0xA2, 0x8E, 0x70, 0x38, 0xB3, 0x8E, -0x01, 0x00, 0x04, 0x24, 0x00, 0x00, 0xC2, 0xAF, 0x08, 0x38, 0xA2, 0xAE, -0x00, 0x00, 0xD3, 0xAF, 0x5B, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x70, 0x38, 0xA4, 0x8E, 0x74, 0x38, 0xA3, 0x8E, 0x02, 0x80, 0x02, 0x3C, -0xB4, 0xE6, 0x42, 0x24, 0x00, 0x00, 0x52, 0x8C, 0x80, 0x00, 0x84, 0x24, -0xFF, 0x00, 0x62, 0x24, 0x2B, 0x10, 0x44, 0x00, 0x0A, 0x18, 0x82, 0x00, -0x70, 0x38, 0xA3, 0xAE, 0x02, 0x80, 0x03, 0x3C, 0xB8, 0xE6, 0x63, 0x24, -0x70, 0x38, 0x42, 0x8E, 0x00, 0x00, 0x76, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xC2, 0xAE, 0x02, 0x80, 0x17, 0x3C, 0xFF, 0xFF, 0x62, 0x32, -0x25, 0x80, 0x57, 0x00, 0x00, 0x00, 0xD0, 0xAE, 0x0C, 0x00, 0x02, 0x92, -0x21, 0x28, 0x00, 0x00, 0x00, 0x00, 0xC2, 0xAE, 0x02, 0x00, 0x04, 0x92, -0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x93, 0x00, 0xFF, 0xFF, 0x84, 0x30, -0xE0, 0x61, 0x00, 0x0C, 0x25, 0x20, 0x97, 0x00, 0x0C, 0x00, 0x11, 0x92, -0x20, 0x10, 0x02, 0x3C, 0x01, 0x00, 0x04, 0x24, 0x00, 0x1A, 0x11, 0x00, -0x21, 0x18, 0x62, 0x00, 0xFF, 0x00, 0x02, 0x24, 0x21, 0x30, 0x60, 0x00, -0x06, 0x00, 0x22, 0x12, 0x80, 0x00, 0x07, 0x24, 0x70, 0x38, 0x45, 0x8E, -0x04, 0x38, 0x43, 0xAE, 0xA8, 0x37, 0x51, 0xA2, 0x1E, 0x01, 0x00, 0x0C, -0x10, 0x00, 0xA0, 0xAF, 0x04, 0x00, 0x04, 0x8E, 0x08, 0x00, 0x03, 0x8E, -0xFF, 0xE0, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, 0x1F, 0x00, 0x84, 0x30, -0x24, 0x18, 0x62, 0x00, 0x00, 0x26, 0x04, 0x00, 0xFF, 0xDF, 0x02, 0x3C, -0x25, 0x18, 0x64, 0x00, 0xFF, 0xFF, 0x42, 0x34, 0x24, 0x18, 0x62, 0x00, -0x00, 0x40, 0x04, 0x3C, 0x25, 0x18, 0x64, 0x00, 0xC0, 0xFF, 0x05, 0x24, -0x82, 0x11, 0x03, 0x00, 0x24, 0x20, 0x65, 0x00, 0x01, 0x00, 0x42, 0x30, -0xA3, 0xFF, 0x40, 0x10, 0x04, 0x00, 0x84, 0x34, 0x08, 0x00, 0x03, 0xAE, -0x08, 0x38, 0x46, 0x8E, 0x21, 0x28, 0x60, 0x02, 0x80, 0x00, 0x07, 0x24, -0x01, 0x00, 0x04, 0x24, 0x01, 0x00, 0x14, 0x24, 0x1E, 0x01, 0x00, 0x0C, -0x10, 0x00, 0xB4, 0xAF, 0x08, 0x38, 0x43, 0x8E, 0x01, 0x00, 0x04, 0x24, -0x00, 0x00, 0xC3, 0xAE, 0x5B, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x2A, 0x1C, 0x42, 0x92, 0x00, 0x00, 0x00, 0x00, 0xA3, 0xFF, 0x40, 0x14, -0x2A, 0xB0, 0x02, 0x3C, 0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x2A, 0x1C, 0x54, 0xA2, 0x02, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, -0x21, 0x10, 0x53, 0x00, 0xFF, 0xFF, 0x42, 0x30, 0x25, 0x10, 0x57, 0x00, -0x02, 0x00, 0x43, 0x94, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x64, 0x30, -0x00, 0xC0, 0x84, 0x24, 0x2B, 0x1C, 0x43, 0xA2, 0xA3, 0x31, 0x00, 0x0C, -0xFF, 0xFF, 0x84, 0x30, 0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x2A, 0xB0, 0x02, 0x3C, 0x09, 0x00, 0x42, 0x34, 0x02, 0x00, 0x03, 0x24, -0x00, 0x00, 0x54, 0xA0, 0x00, 0x00, 0x43, 0xA0, 0xFF, 0x00, 0x03, 0x24, -0x91, 0xFF, 0x23, 0x16, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x62, 0x24, -0xD0, 0x1B, 0x43, 0x8C, 0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xBE, 0x8F, -0x34, 0x00, 0xB7, 0x8F, 0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, -0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, -0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x00, 0x38, 0x63, 0x34, -0x41, 0xB0, 0x04, 0x3C, 0x40, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x83, 0xAC, -0x08, 0x00, 0xE0, 0x03, 0xD0, 0x1B, 0x43, 0xAC, 0x00, 0x80, 0x03, 0x3C, -0x25, 0xB0, 0x02, 0x3C, 0x4C, 0x14, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34, -0x00, 0x00, 0x43, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0xC0, 0xFF, 0xBD, 0x27, 0x34, 0x00, 0xB7, 0xAF, 0x3C, 0x00, 0xBF, 0xAF, -0x38, 0x00, 0xBE, 0xAF, 0x30, 0x00, 0xB6, 0xAF, 0x2C, 0x00, 0xB5, 0xAF, -0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF, -0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x06, 0x3C, -0xC0, 0x5D, 0xC5, 0x90, 0x00, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, -0x18, 0x03, 0x42, 0x34, 0x68, 0x14, 0x63, 0x24, 0x40, 0x00, 0xA4, 0x30, -0x00, 0x00, 0x43, 0xAC, 0x21, 0xB8, 0x00, 0x00, 0x03, 0x00, 0x80, 0x10, -0x7F, 0x00, 0xA2, 0x30, 0xBF, 0x00, 0xA2, 0x30, 0x01, 0x00, 0x17, 0x24, -0xC0, 0x5D, 0xC2, 0xA0, 0x96, 0x40, 0x00, 0x0C, 0x02, 0x80, 0x1E, 0x3C, -0x25, 0xB0, 0x02, 0x3C, 0x60, 0x1B, 0xD3, 0x27, 0xB0, 0x03, 0x55, 0x34, -0x59, 0x05, 0x00, 0x08, 0x02, 0x80, 0x16, 0x3C, 0x84, 0x37, 0x91, 0xA2, -0x60, 0x1B, 0xC2, 0x27, 0xBC, 0x37, 0x46, 0x8C, 0x28, 0x38, 0x45, 0x8C, -0x03, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C, -0x10, 0x00, 0xA0, 0xAF, 0x60, 0x1B, 0xD4, 0x27, 0xC0, 0x37, 0x85, 0x8E, -0x21, 0x20, 0x00, 0x02, 0xD4, 0x02, 0x00, 0x0C, 0x21, 0x30, 0x40, 0x02, -0x2A, 0xB0, 0x07, 0x3C, 0x0D, 0x00, 0xE2, 0x34, 0x04, 0x00, 0x43, 0x24, -0x0B, 0x10, 0x77, 0x00, 0x01, 0x00, 0x04, 0x24, 0x02, 0x00, 0x03, 0x24, -0x00, 0x00, 0x44, 0xA0, 0x00, 0x00, 0x43, 0xA0, 0x0C, 0x5D, 0xC4, 0x96, -0x25, 0xB0, 0x06, 0x3C, 0x66, 0x03, 0xC5, 0x34, 0x01, 0x00, 0x84, 0x24, -0x0C, 0x5D, 0xC4, 0xA6, 0x0C, 0x5D, 0xC2, 0x96, 0xFF, 0x00, 0x03, 0x24, -0x00, 0x00, 0xA2, 0xA4, 0x2F, 0x00, 0x23, 0x12, 0x00, 0x00, 0x00, 0x00, -0xBC, 0x37, 0x62, 0x8E, 0x28, 0x38, 0x72, 0x8E, 0x03, 0x00, 0x04, 0x24, -0x00, 0x00, 0xA2, 0xAE, 0xC0, 0x37, 0x62, 0xAE, 0x00, 0x00, 0xB2, 0xAE, -0x5B, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x38, 0x64, 0x8E, -0x2C, 0x38, 0x63, 0x8E, 0x02, 0x80, 0x02, 0x3C, 0xBC, 0xE6, 0x42, 0x24, -0x00, 0x00, 0x54, 0x8C, 0x80, 0x00, 0x84, 0x24, 0xFF, 0x00, 0x62, 0x24, -0x2B, 0x10, 0x44, 0x00, 0x0A, 0x18, 0x82, 0x00, 0x28, 0x38, 0x63, 0xAE, -0x28, 0x38, 0x82, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xAE, -0x02, 0x80, 0x03, 0x3C, 0xFF, 0xFF, 0x42, 0x32, 0x25, 0x80, 0x43, 0x00, -0x00, 0x00, 0xB0, 0xAE, 0x0C, 0x00, 0x02, 0x92, 0x01, 0x00, 0x05, 0x24, -0x00, 0x00, 0xA2, 0xAE, 0x02, 0x00, 0x04, 0x92, 0x00, 0x00, 0x00, 0x00, -0x21, 0x20, 0x92, 0x00, 0xFF, 0xFF, 0x84, 0x30, 0xE0, 0x61, 0x00, 0x0C, -0x25, 0x20, 0x83, 0x00, 0x0C, 0x00, 0x11, 0x92, 0x20, 0x10, 0x02, 0x3C, -0xFF, 0x00, 0x03, 0x24, 0x00, 0x22, 0x11, 0x00, 0xC2, 0xFF, 0x23, 0x12, -0x21, 0x20, 0x82, 0x00, 0xB8, 0xFF, 0xE0, 0x16, 0xBC, 0x37, 0x84, 0xAE, -0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, 0x3B, 0x05, 0x00, 0x08, -0x80, 0x37, 0x51, 0xA0, 0x1E, 0x00, 0xE0, 0x12, 0x40, 0x00, 0xE4, 0x34, -0x84, 0x37, 0x83, 0x92, 0x41, 0x00, 0xE4, 0x34, 0xB0, 0x03, 0xC5, 0x34, -0x00, 0x00, 0x83, 0xA0, 0x00, 0x00, 0xA3, 0xAC, 0x96, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x60, 0x1B, 0xC5, 0x27, 0xD0, 0x1B, 0xA4, 0x8C, 0x01, 0x00, 0x02, 0x3C, -0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xBE, 0x8F, 0x34, 0x00, 0xB7, 0x8F, -0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F, -0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x00, 0x80, 0x42, 0x34, 0x25, 0x20, 0x82, 0x00, -0x41, 0xB0, 0x03, 0x3C, 0x40, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x64, 0xAC, -0x08, 0x00, 0xE0, 0x03, 0xD0, 0x1B, 0xA4, 0xAC, 0x80, 0x37, 0x83, 0x92, -0xB0, 0x03, 0xC5, 0x34, 0x00, 0x00, 0x83, 0xA0, 0x00, 0x00, 0xA3, 0xAC, -0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0xC5, 0x27, 0xD0, 0x1B, 0xA4, 0x8C, -0x01, 0x00, 0x02, 0x3C, 0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xBE, 0x8F, -0x34, 0x00, 0xB7, 0x8F, 0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, -0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, -0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x00, 0x80, 0x42, 0x34, -0x25, 0x20, 0x82, 0x00, 0x41, 0xB0, 0x03, 0x3C, 0x40, 0x00, 0xBD, 0x27, -0x00, 0x00, 0x64, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0xD0, 0x1B, 0xA4, 0xAC, -0xC0, 0xFF, 0xBD, 0x27, 0x34, 0x00, 0xB7, 0xAF, 0x3C, 0x00, 0xBF, 0xAF, -0x38, 0x00, 0xBE, 0xAF, 0x30, 0x00, 0xB6, 0xAF, 0x2C, 0x00, 0xB5, 0xAF, -0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF, -0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x06, 0x3C, -0xC0, 0x5D, 0xC5, 0x90, 0x00, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, -0x18, 0x03, 0x42, 0x34, 0x08, 0x17, 0x63, 0x24, 0x10, 0x00, 0xA4, 0x30, -0x00, 0x00, 0x43, 0xAC, 0x21, 0xB8, 0x00, 0x00, 0x03, 0x00, 0x80, 0x10, -0xDF, 0x00, 0xA2, 0x30, 0xEF, 0x00, 0xA2, 0x30, 0x01, 0x00, 0x17, 0x24, -0xC0, 0x5D, 0xC2, 0xA0, 0xC0, 0x5D, 0xC3, 0x90, 0x25, 0xB0, 0x02, 0x3C, -0xB0, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, 0x02, 0x80, 0x1E, 0x3C, -0x00, 0x00, 0x43, 0xAC, 0x21, 0xA8, 0x40, 0x00, 0x96, 0x40, 0x00, 0x0C, -0x60, 0x1B, 0xD3, 0x27, 0x05, 0x06, 0x00, 0x08, 0x02, 0x80, 0x16, 0x3C, -0x8C, 0x37, 0x91, 0xA2, 0x60, 0x1B, 0xC2, 0x27, 0xC8, 0x37, 0x46, 0x8C, -0x34, 0x38, 0x45, 0x8C, 0x04, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24, -0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, 0x60, 0x1B, 0xD4, 0x27, -0xCC, 0x37, 0x85, 0x8E, 0x21, 0x20, 0x00, 0x02, 0xD4, 0x02, 0x00, 0x0C, -0x21, 0x30, 0x40, 0x02, 0x2A, 0xB0, 0x07, 0x3C, 0x15, 0x00, 0xE2, 0x34, -0x04, 0x00, 0x43, 0x24, 0x0B, 0x10, 0x77, 0x00, 0x01, 0x00, 0x04, 0x24, -0x02, 0x00, 0x03, 0x24, 0x00, 0x00, 0x44, 0xA0, 0x00, 0x00, 0x43, 0xA0, -0x0C, 0x5D, 0xC4, 0x96, 0x25, 0xB0, 0x06, 0x3C, 0x66, 0x03, 0xC5, 0x34, -0x01, 0x00, 0x84, 0x24, 0x0C, 0x5D, 0xC4, 0xA6, 0x0C, 0x5D, 0xC2, 0x96, -0xFF, 0x00, 0x03, 0x24, 0x00, 0x00, 0xA2, 0xA4, 0x2F, 0x00, 0x23, 0x12, -0x00, 0x00, 0x00, 0x00, 0xC8, 0x37, 0x62, 0x8E, 0x34, 0x38, 0x72, 0x8E, -0x04, 0x00, 0x04, 0x24, 0x00, 0x00, 0xA2, 0xAE, 0xCC, 0x37, 0x62, 0xAE, -0x00, 0x00, 0xB2, 0xAE, 0x5B, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x34, 0x38, 0x64, 0x8E, 0x38, 0x38, 0x63, 0x8E, 0x02, 0x80, 0x02, 0x3C, -0xC0, 0xE6, 0x42, 0x24, 0x00, 0x00, 0x54, 0x8C, 0x80, 0x00, 0x84, 0x24, -0xFF, 0x00, 0x62, 0x24, 0x2B, 0x10, 0x44, 0x00, 0x0A, 0x18, 0x82, 0x00, -0x34, 0x38, 0x63, 0xAE, 0x34, 0x38, 0x82, 0x8E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xA2, 0xAE, 0x02, 0x80, 0x03, 0x3C, 0xFF, 0xFF, 0x42, 0x32, -0x25, 0x80, 0x43, 0x00, 0x00, 0x00, 0xB0, 0xAE, 0x0C, 0x00, 0x02, 0x92, -0x02, 0x00, 0x05, 0x24, 0x00, 0x00, 0xA2, 0xAE, 0x02, 0x00, 0x04, 0x92, -0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x92, 0x00, 0xFF, 0xFF, 0x84, 0x30, -0xE0, 0x61, 0x00, 0x0C, 0x25, 0x20, 0x83, 0x00, 0x0C, 0x00, 0x11, 0x92, -0x20, 0x10, 0x02, 0x3C, 0xFF, 0x00, 0x03, 0x24, 0x00, 0x22, 0x11, 0x00, -0xC2, 0xFF, 0x23, 0x12, 0x21, 0x20, 0x82, 0x00, 0xB8, 0xFF, 0xE0, 0x16, -0xC8, 0x37, 0x84, 0xAE, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, -0xE7, 0x05, 0x00, 0x08, 0x88, 0x37, 0x51, 0xA0, 0x1D, 0x00, 0xE0, 0x12, -0x42, 0x00, 0xE4, 0x34, 0x8C, 0x37, 0x83, 0x92, 0x43, 0x00, 0xE4, 0x34, -0xB0, 0x03, 0xC5, 0x34, 0x00, 0x00, 0x83, 0xA0, 0x00, 0x00, 0xA3, 0xAC, -0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0xC5, 0x27, 0xD0, 0x1B, 0xA2, 0x8C, -0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xBE, 0x8F, 0x34, 0x00, 0xB7, 0x8F, -0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F, -0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x06, 0x00, 0x03, 0x3C, 0x25, 0x10, 0x43, 0x00, -0x41, 0xB0, 0x04, 0x3C, 0x40, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x82, 0xAC, -0x08, 0x00, 0xE0, 0x03, 0xD0, 0x1B, 0xA2, 0xAC, 0x88, 0x37, 0x83, 0x92, -0xB0, 0x03, 0xC5, 0x34, 0x00, 0x00, 0x83, 0xA0, 0x00, 0x00, 0xA3, 0xAC, -0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0xC5, 0x27, 0xD0, 0x1B, 0xA2, 0x8C, -0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xBE, 0x8F, 0x34, 0x00, 0xB7, 0x8F, -0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F, -0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x06, 0x00, 0x03, 0x3C, 0x25, 0x10, 0x43, 0x00, -0x41, 0xB0, 0x04, 0x3C, 0x40, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x82, 0xAC, -0x08, 0x00, 0xE0, 0x03, 0xD0, 0x1B, 0xA2, 0xAC, 0xC0, 0xFF, 0xBD, 0x27, -0x34, 0x00, 0xB7, 0xAF, 0x3C, 0x00, 0xBF, 0xAF, 0x38, 0x00, 0xBE, 0xAF, -0x30, 0x00, 0xB6, 0xAF, 0x2C, 0x00, 0xB5, 0xAF, 0x28, 0x00, 0xB4, 0xAF, -0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, -0x18, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x06, 0x3C, 0xC0, 0x5D, 0xC5, 0x90, -0x00, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, 0x18, 0x03, 0x42, 0x34, -0xB0, 0x19, 0x63, 0x24, 0x01, 0x00, 0xA4, 0x30, 0x00, 0x00, 0x43, 0xAC, -0x21, 0xB8, 0x00, 0x00, 0x03, 0x00, 0x80, 0x10, 0xF7, 0x00, 0xA2, 0x30, -0xFE, 0x00, 0xA2, 0x30, 0x01, 0x00, 0x17, 0x24, 0xC0, 0x5D, 0xC2, 0xA0, -0xC0, 0x5D, 0xC3, 0x90, 0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, -0x02, 0x80, 0x1E, 0x3C, 0x00, 0x00, 0x43, 0xAC, 0x21, 0xA8, 0x40, 0x00, -0x96, 0x40, 0x00, 0x0C, 0x60, 0x1B, 0xD3, 0x27, 0xAE, 0x06, 0x00, 0x08, -0x02, 0x80, 0x16, 0x3C, 0x9C, 0x37, 0x91, 0xA2, 0x60, 0x1B, 0xC2, 0x27, -0xD4, 0x37, 0x46, 0x8C, 0x40, 0x38, 0x45, 0x8C, 0x05, 0x00, 0x04, 0x24, -0x80, 0x00, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, -0x60, 0x1B, 0xD4, 0x27, 0xD8, 0x37, 0x85, 0x8E, 0x21, 0x20, 0x00, 0x02, -0xD4, 0x02, 0x00, 0x0C, 0x21, 0x30, 0x40, 0x02, 0x2A, 0xB0, 0x07, 0x3C, -0x1D, 0x00, 0xE2, 0x34, 0x04, 0x00, 0x43, 0x24, 0x0B, 0x10, 0x77, 0x00, -0x01, 0x00, 0x04, 0x24, 0x02, 0x00, 0x03, 0x24, 0x00, 0x00, 0x44, 0xA0, -0x00, 0x00, 0x43, 0xA0, 0x0C, 0x5D, 0xC4, 0x96, 0x25, 0xB0, 0x06, 0x3C, -0x66, 0x03, 0xC5, 0x34, 0x01, 0x00, 0x84, 0x24, 0x0C, 0x5D, 0xC4, 0xA6, -0x0C, 0x5D, 0xC2, 0x96, 0xFF, 0x00, 0x03, 0x24, 0x00, 0x00, 0xA2, 0xA4, -0x2F, 0x00, 0x23, 0x12, 0x00, 0x00, 0x00, 0x00, 0xD4, 0x37, 0x62, 0x8E, -0x40, 0x38, 0x72, 0x8E, 0x05, 0x00, 0x04, 0x24, 0x00, 0x00, 0xA2, 0xAE, -0xD8, 0x37, 0x62, 0xAE, 0x00, 0x00, 0xB2, 0xAE, 0x5B, 0x01, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x40, 0x38, 0x64, 0x8E, 0x44, 0x38, 0x63, 0x8E, -0x02, 0x80, 0x02, 0x3C, 0xC4, 0xE6, 0x42, 0x24, 0x00, 0x00, 0x54, 0x8C, -0x80, 0x00, 0x84, 0x24, 0xFF, 0x00, 0x62, 0x24, 0x2B, 0x10, 0x44, 0x00, -0x0A, 0x18, 0x82, 0x00, 0x40, 0x38, 0x63, 0xAE, 0x40, 0x38, 0x82, 0x8E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xAE, 0x02, 0x80, 0x03, 0x3C, -0xFF, 0xFF, 0x42, 0x32, 0x25, 0x80, 0x43, 0x00, 0x00, 0x00, 0xB0, 0xAE, -0x0C, 0x00, 0x02, 0x92, 0x08, 0x00, 0x05, 0x24, 0x00, 0x00, 0xA2, 0xAE, -0x02, 0x00, 0x04, 0x92, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x92, 0x00, -0xFF, 0xFF, 0x84, 0x30, 0xE0, 0x61, 0x00, 0x0C, 0x25, 0x20, 0x83, 0x00, -0x0C, 0x00, 0x11, 0x92, 0x20, 0x10, 0x02, 0x3C, 0xFF, 0x00, 0x03, 0x24, -0x00, 0x22, 0x11, 0x00, 0xC2, 0xFF, 0x23, 0x12, 0x21, 0x20, 0x82, 0x00, -0xB8, 0xFF, 0xE0, 0x16, 0xD4, 0x37, 0x84, 0xAE, 0x02, 0x80, 0x02, 0x3C, -0x60, 0x1B, 0x42, 0x24, 0x90, 0x06, 0x00, 0x08, 0x90, 0x37, 0x51, 0xA0, -0x1D, 0x00, 0xE0, 0x12, 0x44, 0x00, 0xE4, 0x34, 0x9C, 0x37, 0x83, 0x92, -0x45, 0x00, 0xE4, 0x34, 0xB0, 0x03, 0xC5, 0x34, 0x00, 0x00, 0x83, 0xA0, -0x00, 0x00, 0xA3, 0xAC, 0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0xC5, 0x27, -0xD0, 0x1B, 0xA2, 0x8C, 0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xBE, 0x8F, -0x34, 0x00, 0xB7, 0x8F, 0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, -0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, -0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x18, 0x00, 0x03, 0x3C, -0x25, 0x10, 0x43, 0x00, 0x41, 0xB0, 0x04, 0x3C, 0x40, 0x00, 0xBD, 0x27, -0x00, 0x00, 0x82, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0xD0, 0x1B, 0xA2, 0xAC, -0x90, 0x37, 0x83, 0x92, 0xB0, 0x03, 0xC5, 0x34, 0x00, 0x00, 0x83, 0xA0, -0x00, 0x00, 0xA3, 0xAC, 0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0xC5, 0x27, -0xD0, 0x1B, 0xA2, 0x8C, 0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xBE, 0x8F, -0x34, 0x00, 0xB7, 0x8F, 0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, -0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, -0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x18, 0x00, 0x03, 0x3C, -0x25, 0x10, 0x43, 0x00, 0x41, 0xB0, 0x04, 0x3C, 0x40, 0x00, 0xBD, 0x27, -0x00, 0x00, 0x82, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0xD0, 0x1B, 0xA2, 0xAC, -0xC0, 0xFF, 0xBD, 0x27, 0x34, 0x00, 0xB7, 0xAF, 0x3C, 0x00, 0xBF, 0xAF, -0x38, 0x00, 0xBE, 0xAF, 0x30, 0x00, 0xB6, 0xAF, 0x2C, 0x00, 0xB5, 0xAF, -0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF, -0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x06, 0x3C, -0xC0, 0x5D, 0xC5, 0x90, 0x00, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, -0x18, 0x03, 0x42, 0x34, 0x54, 0x1C, 0x63, 0x24, 0x02, 0x00, 0xA4, 0x30, -0x00, 0x00, 0x43, 0xAC, 0x21, 0xB8, 0x00, 0x00, 0x03, 0x00, 0x80, 0x10, -0xFB, 0x00, 0xA2, 0x30, 0xFD, 0x00, 0xA2, 0x30, 0x01, 0x00, 0x17, 0x24, -0xC0, 0x5D, 0xC2, 0xA0, 0xC0, 0x5D, 0xC3, 0x90, 0x25, 0xB0, 0x02, 0x3C, -0xB0, 0x03, 0x42, 0x34, 0x02, 0x80, 0x1E, 0x3C, 0x00, 0x00, 0x43, 0xAC, -0x21, 0xA8, 0x40, 0x00, 0x96, 0x40, 0x00, 0x0C, 0x60, 0x1B, 0xD3, 0x27, -0x57, 0x07, 0x00, 0x08, 0x02, 0x80, 0x16, 0x3C, 0x98, 0x37, 0x91, 0xA2, -0x60, 0x1B, 0xC2, 0x27, 0xE0, 0x37, 0x46, 0x8C, 0x4C, 0x38, 0x45, 0x8C, -0x06, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C, -0x10, 0x00, 0xA0, 0xAF, 0x60, 0x1B, 0xD4, 0x27, 0xE4, 0x37, 0x85, 0x8E, -0x21, 0x20, 0x00, 0x02, 0xD4, 0x02, 0x00, 0x0C, 0x21, 0x30, 0x40, 0x02, -0x2A, 0xB0, 0x07, 0x3C, 0x25, 0x00, 0xE2, 0x34, 0x04, 0x00, 0x43, 0x24, -0x0B, 0x10, 0x77, 0x00, 0x01, 0x00, 0x04, 0x24, 0x02, 0x00, 0x03, 0x24, -0x00, 0x00, 0x44, 0xA0, 0x00, 0x00, 0x43, 0xA0, 0x0C, 0x5D, 0xC4, 0x96, -0x25, 0xB0, 0x06, 0x3C, 0x66, 0x03, 0xC5, 0x34, 0x01, 0x00, 0x84, 0x24, -0x0C, 0x5D, 0xC4, 0xA6, 0x0C, 0x5D, 0xC2, 0x96, 0xFF, 0x00, 0x03, 0x24, -0x00, 0x00, 0xA2, 0xA4, 0x2F, 0x00, 0x23, 0x12, 0x00, 0x00, 0x00, 0x00, -0xE0, 0x37, 0x62, 0x8E, 0x4C, 0x38, 0x72, 0x8E, 0x06, 0x00, 0x04, 0x24, -0x00, 0x00, 0xA2, 0xAE, 0xE4, 0x37, 0x62, 0xAE, 0x00, 0x00, 0xB2, 0xAE, -0x5B, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x38, 0x64, 0x8E, -0x50, 0x38, 0x63, 0x8E, 0x02, 0x80, 0x02, 0x3C, 0xC8, 0xE6, 0x42, 0x24, -0x00, 0x00, 0x54, 0x8C, 0x80, 0x00, 0x84, 0x24, 0xFF, 0x00, 0x62, 0x24, -0x2B, 0x10, 0x44, 0x00, 0x0A, 0x18, 0x82, 0x00, 0x4C, 0x38, 0x63, 0xAE, -0x4C, 0x38, 0x82, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xAE, -0x02, 0x80, 0x03, 0x3C, 0xFF, 0xFF, 0x42, 0x32, 0x25, 0x80, 0x43, 0x00, -0x00, 0x00, 0xB0, 0xAE, 0x0C, 0x00, 0x02, 0x92, 0x04, 0x00, 0x05, 0x24, -0x00, 0x00, 0xA2, 0xAE, 0x02, 0x00, 0x04, 0x92, 0x00, 0x00, 0x00, 0x00, -0x21, 0x20, 0x92, 0x00, 0xFF, 0xFF, 0x84, 0x30, 0xE0, 0x61, 0x00, 0x0C, -0x25, 0x20, 0x83, 0x00, 0x0C, 0x00, 0x11, 0x92, 0x20, 0x10, 0x02, 0x3C, -0xFF, 0x00, 0x03, 0x24, 0x00, 0x22, 0x11, 0x00, 0xC2, 0xFF, 0x23, 0x12, -0x21, 0x20, 0x82, 0x00, 0xB8, 0xFF, 0xE0, 0x16, 0xE0, 0x37, 0x84, 0xAE, -0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, 0x39, 0x07, 0x00, 0x08, -0x94, 0x37, 0x51, 0xA0, 0x1D, 0x00, 0xE0, 0x12, 0x46, 0x00, 0xE4, 0x34, -0x98, 0x37, 0x83, 0x92, 0x47, 0x00, 0xE4, 0x34, 0xB0, 0x03, 0xC5, 0x34, -0x00, 0x00, 0x83, 0xA0, 0x00, 0x00, 0xA3, 0xAC, 0x96, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x60, 0x1B, 0xC5, 0x27, 0xD0, 0x1B, 0xA2, 0x8C, 0x3C, 0x00, 0xBF, 0x8F, -0x38, 0x00, 0xBE, 0x8F, 0x34, 0x00, 0xB7, 0x8F, 0x30, 0x00, 0xB6, 0x8F, -0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, -0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x60, 0x00, 0x03, 0x3C, 0x25, 0x10, 0x43, 0x00, 0x41, 0xB0, 0x04, 0x3C, -0x40, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x82, 0xAC, 0x08, 0x00, 0xE0, 0x03, -0xD0, 0x1B, 0xA2, 0xAC, 0x94, 0x37, 0x83, 0x92, 0xB0, 0x03, 0xC5, 0x34, -0x00, 0x00, 0x83, 0xA0, 0x00, 0x00, 0xA3, 0xAC, 0x96, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x60, 0x1B, 0xC5, 0x27, 0xD0, 0x1B, 0xA2, 0x8C, 0x3C, 0x00, 0xBF, 0x8F, -0x38, 0x00, 0xBE, 0x8F, 0x34, 0x00, 0xB7, 0x8F, 0x30, 0x00, 0xB6, 0x8F, -0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, -0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x60, 0x00, 0x03, 0x3C, 0x25, 0x10, 0x43, 0x00, 0x41, 0xB0, 0x04, 0x3C, -0x40, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x82, 0xAC, 0x08, 0x00, 0xE0, 0x03, -0xD0, 0x1B, 0xA2, 0xAC, 0x00, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, -0xF8, 0x1E, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34, 0xE8, 0xFF, 0xBD, 0x27, -0x00, 0x00, 0x43, 0xAC, 0x10, 0x00, 0xBF, 0xAF, 0x96, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x02, 0x80, 0x05, 0x3C, 0x60, 0x1B, 0xA5, 0x24, 0xD8, 0x1B, 0xA2, 0x8C, -0xD0, 0x1B, 0xA4, 0x8C, 0x00, 0x08, 0x03, 0x3C, 0x10, 0x00, 0xBF, 0x8F, -0x24, 0x10, 0x43, 0x00, 0x25, 0x20, 0x82, 0x00, 0x41, 0xB0, 0x03, 0x3C, -0x18, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x64, 0xAC, 0x08, 0x00, 0xE0, 0x03, -0xD0, 0x1B, 0xA4, 0xAC, 0xC0, 0xFF, 0xBD, 0x27, 0x20, 0x00, 0xB0, 0xAF, -0x00, 0x80, 0x02, 0x3C, 0x25, 0xB0, 0x10, 0x3C, 0x18, 0x03, 0x03, 0x36, -0x58, 0x1F, 0x42, 0x24, 0x00, 0x00, 0x62, 0xAC, 0x34, 0x00, 0xB5, 0xAF, -0x02, 0x80, 0x15, 0x3C, 0x38, 0x00, 0xBF, 0xAF, 0x2C, 0x00, 0xB3, 0xAF, -0x28, 0x00, 0xB2, 0xAF, 0x60, 0x1B, 0xB3, 0x26, 0x24, 0x00, 0xB1, 0xAF, -0x96, 0x40, 0x00, 0x0C, 0x30, 0x00, 0xB4, 0xAF, 0xFC, 0x00, 0x02, 0x36, -0x00, 0x00, 0x45, 0x8C, 0xAC, 0x1B, 0x64, 0x96, 0xCC, 0x38, 0x63, 0x96, -0xC4, 0x38, 0x66, 0x8E, 0x23, 0x28, 0xA4, 0x00, 0x21, 0x10, 0xA3, 0x00, -0x23, 0x88, 0x46, 0x00, 0x23, 0x20, 0x23, 0x02, 0xB0, 0x03, 0x10, 0x36, -0x2B, 0x10, 0x71, 0x00, 0x00, 0x00, 0x03, 0xAE, 0x00, 0x00, 0x11, 0xAE, -0x0B, 0x88, 0x82, 0x00, 0x21, 0x20, 0x20, 0x02, 0x53, 0x21, 0x00, 0x0C, -0xC8, 0x38, 0x65, 0xAE, 0x21, 0x90, 0x40, 0x00, 0x4D, 0x00, 0x40, 0x10, -0x18, 0x00, 0xA4, 0x27, 0x0C, 0x00, 0x51, 0xAC, 0xC4, 0x38, 0x68, 0x8E, -0xC8, 0x38, 0x62, 0x8E, 0x08, 0x00, 0x45, 0x8E, 0x20, 0xBD, 0x03, 0x3C, -0x88, 0x03, 0x63, 0x34, 0x2B, 0x10, 0x48, 0x00, 0x40, 0x10, 0x14, 0x3C, -0x21, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0x27, 0x32, 0x00, 0x00, 0x65, 0xAC, -0x2A, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xAC, 0x1B, 0x66, 0x96, -0x08, 0x00, 0x42, 0x96, 0x40, 0x10, 0x05, 0x3C, 0x21, 0x20, 0x00, 0x00, -0x21, 0x30, 0x06, 0x01, 0x25, 0x28, 0x45, 0x00, 0x1E, 0x01, 0x00, 0x0C, -0x10, 0x00, 0xA0, 0xAF, 0x8A, 0x40, 0x00, 0x0C, 0x18, 0x00, 0xA4, 0x27, -0x02, 0x80, 0x02, 0x3C, 0x88, 0x54, 0x42, 0x24, 0x04, 0x00, 0x43, 0x8C, -0x00, 0x00, 0x42, 0xAE, 0x04, 0x00, 0x52, 0xAC, 0x21, 0x20, 0x00, 0x00, -0x00, 0x00, 0x72, 0xAC, 0x5B, 0x01, 0x00, 0x0C, 0x04, 0x00, 0x43, 0xAE, -0x60, 0x1B, 0xA5, 0x26, 0xC8, 0x38, 0xA6, 0x8C, 0xAC, 0x1B, 0xA3, 0x94, -0x25, 0xB0, 0x02, 0x3C, 0xF8, 0x00, 0x42, 0x34, 0x21, 0x18, 0xC3, 0x00, -0x00, 0x00, 0x43, 0xAC, 0x18, 0x00, 0xA4, 0x27, 0xC4, 0x38, 0xA6, 0xAC, -0x90, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0xBF, 0x8F, 0x34, 0x00, 0xB5, 0x8F, -0x30, 0x00, 0xB4, 0x8F, 0x2C, 0x00, 0xB3, 0x8F, 0x28, 0x00, 0xB2, 0x8F, -0x24, 0x00, 0xB1, 0x8F, 0x20, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x40, 0x00, 0xBD, 0x27, 0xCC, 0x38, 0x70, 0x8E, 0x08, 0x00, 0x45, 0x96, -0xAC, 0x1B, 0x66, 0x96, 0x23, 0x80, 0x08, 0x02, 0xFF, 0xFF, 0x10, 0x32, -0x21, 0x30, 0x06, 0x01, 0x25, 0x28, 0xB4, 0x00, 0x21, 0x38, 0x00, 0x02, -0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, 0x5B, 0x01, 0x00, 0x0C, -0x21, 0x20, 0x00, 0x00, 0x08, 0x00, 0x45, 0x96, 0xAC, 0x1B, 0x62, 0x96, -0x23, 0x38, 0x30, 0x02, 0x25, 0x28, 0xB4, 0x00, 0x21, 0x10, 0x06, 0x3C, -0x21, 0x28, 0xB0, 0x00, 0x21, 0x30, 0x46, 0x00, 0xFF, 0xFF, 0xE7, 0x30, -0x0D, 0x08, 0x00, 0x08, 0x21, 0x20, 0x00, 0x00, 0x8A, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x03, 0x3C, 0xC4, 0x5D, 0x62, 0x8C, -0x18, 0x00, 0xA4, 0x27, 0x08, 0x00, 0x42, 0x34, 0x23, 0x08, 0x00, 0x08, -0xC4, 0x5D, 0x62, 0xAC, 0x25, 0xB0, 0x05, 0x3C, 0x00, 0x80, 0x02, 0x3C, -0xC0, 0xFF, 0xBD, 0x27, 0x18, 0x03, 0xA4, 0x34, 0x38, 0x21, 0x42, 0x24, -0x2A, 0xB0, 0x03, 0x3C, 0x00, 0x00, 0x82, 0xAC, 0x3C, 0x00, 0xBF, 0xAF, -0x38, 0x00, 0xBE, 0xAF, 0x34, 0x00, 0xB7, 0xAF, 0x30, 0x00, 0xB6, 0xAF, -0x2C, 0x00, 0xB5, 0xAF, 0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, -0x20, 0x00, 0xB2, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, -0x2C, 0x00, 0x63, 0x34, 0x00, 0x00, 0x69, 0x8C, 0xFF, 0x00, 0x02, 0x24, -0xFF, 0x00, 0x24, 0x31, 0x48, 0x00, 0x82, 0x10, 0x00, 0x80, 0x22, 0x31, -0x37, 0x00, 0x40, 0x10, 0x00, 0xFF, 0x02, 0x3C, 0x00, 0x80, 0x02, 0x3C, -0x00, 0x00, 0x62, 0xAC, 0xFF, 0x00, 0x02, 0x24, 0x14, 0x00, 0x82, 0x10, -0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x70, 0x24, 0xFF, 0x00, 0x23, 0x31, -0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, -0x7C, 0x38, 0x05, 0x8E, 0x25, 0xB0, 0x02, 0x3C, 0xFF, 0x00, 0x28, 0x31, -0x7C, 0x03, 0x42, 0x34, 0x00, 0x00, 0x48, 0xA4, 0x21, 0x30, 0x60, 0x00, -0x10, 0x38, 0x03, 0xAE, 0xAC, 0x37, 0x09, 0xA2, 0x0A, 0x00, 0x04, 0x24, -0x00, 0x01, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, -0x01, 0x00, 0x03, 0x24, 0x84, 0x38, 0x03, 0xA2, 0x02, 0x80, 0x02, 0x3C, -0x60, 0x1B, 0x50, 0x24, 0x84, 0x38, 0x03, 0x92, 0x01, 0x00, 0x02, 0x24, -0x31, 0x00, 0x62, 0x10, 0x02, 0x80, 0x04, 0x3C, 0x60, 0x1B, 0x90, 0x24, -0x85, 0x38, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x10, -0x00, 0x04, 0x03, 0x3C, 0xD8, 0x1B, 0x02, 0x8E, 0xD0, 0x1B, 0x04, 0x8E, -0x24, 0x10, 0x43, 0x00, 0x25, 0x20, 0x82, 0x00, 0x41, 0xB0, 0x03, 0x3C, -0x00, 0x00, 0x64, 0xAC, 0xD0, 0x1B, 0x04, 0xAE, 0x3C, 0x00, 0xBF, 0x8F, -0x38, 0x00, 0xBE, 0x8F, 0x34, 0x00, 0xB7, 0x8F, 0x30, 0x00, 0xB6, 0x8F, -0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, -0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x40, 0x00, 0xBD, 0x27, 0x24, 0x10, 0x22, 0x01, -0xCB, 0xFF, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24, 0x02, 0x80, 0x02, 0x3C, -0x60, 0x1B, 0x43, 0x24, 0xAC, 0x37, 0x62, 0x90, 0x20, 0xB0, 0x03, 0x3C, -0xB0, 0x03, 0xA4, 0x34, 0x00, 0x12, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, -0x0C, 0x00, 0x49, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0xAC, -0x69, 0x08, 0x00, 0x08, 0xFF, 0x00, 0x24, 0x31, 0x02, 0x80, 0x04, 0x3C, -0x60, 0x1B, 0x82, 0x24, 0x84, 0x38, 0x40, 0xA0, 0x02, 0x80, 0x02, 0x3C, -0x60, 0x1B, 0x50, 0x24, 0x84, 0x38, 0x03, 0x92, 0x01, 0x00, 0x02, 0x24, -0xD1, 0xFF, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, 0x96, 0x40, 0x00, 0x0C, -0x21, 0x88, 0x00, 0x02, 0x25, 0xB0, 0x02, 0x3C, 0x2A, 0xB0, 0x03, 0x3C, -0x2C, 0x00, 0x7E, 0x34, 0x02, 0x80, 0x17, 0x3C, 0xB0, 0x03, 0x56, 0x34, -0x01, 0x00, 0x13, 0x24, 0x21, 0xA0, 0x00, 0x02, 0x21, 0xA8, 0x00, 0x02, -0x7C, 0x38, 0x30, 0x8E, 0x0A, 0x00, 0x04, 0x24, 0x00, 0x00, 0xD0, 0xAE, -0x5B, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C, -0xFF, 0xFF, 0x08, 0x32, 0x25, 0x80, 0x02, 0x01, 0xC2, 0x5C, 0xE3, 0x92, -0x02, 0x00, 0x04, 0x92, 0x02, 0x00, 0x02, 0x24, 0x0F, 0x00, 0x63, 0x30, -0x52, 0x00, 0x62, 0x10, 0x21, 0x38, 0x04, 0x02, 0x20, 0x00, 0x02, 0x24, -0x54, 0x00, 0x82, 0x14, 0x02, 0x80, 0x02, 0x3C, 0x54, 0xF5, 0x47, 0xAC, -0x02, 0x00, 0xE2, 0x90, 0x85, 0x38, 0x84, 0x92, 0x03, 0x00, 0xE3, 0x90, -0xFF, 0x00, 0x52, 0x30, 0x01, 0x00, 0x02, 0x24, 0x21, 0x28, 0xE0, 0x00, -0x7F, 0x00, 0x66, 0x30, 0x08, 0x00, 0xE7, 0x24, 0x57, 0x00, 0x82, 0x10, -0x02, 0x80, 0x09, 0x3C, 0x0E, 0x00, 0x02, 0x24, 0x51, 0x00, 0x42, 0x12, -0x37, 0x00, 0x02, 0x24, 0x4F, 0x00, 0x42, 0x12, 0x10, 0x00, 0x02, 0x24, -0x4E, 0x00, 0x42, 0x12, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x02, 0x3C, -0x38, 0xD7, 0x42, 0x24, 0xC0, 0x18, 0x12, 0x00, 0x21, 0x18, 0x62, 0x00, -0x34, 0xD7, 0x26, 0xA1, 0x04, 0x00, 0x62, 0x8C, 0x02, 0x80, 0x03, 0x3C, -0x21, 0x20, 0xE0, 0x00, 0x09, 0xF8, 0x40, 0x00, 0x4C, 0xF5, 0x62, 0xAC, -0x03, 0x00, 0x40, 0x10, 0x39, 0x00, 0x02, 0x24, 0x3B, 0x00, 0x42, 0x12, -0x00, 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x85, 0x38, 0x33, 0xA2, 0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x39, 0x00, 0x02, 0x24, 0x03, 0x00, 0x42, 0x12, 0x02, 0x00, 0x02, 0x24, -0x01, 0x00, 0xD3, 0xA3, 0x01, 0x00, 0xC2, 0xA3, 0x85, 0x38, 0xA3, 0x92, -0x01, 0x00, 0x02, 0x24, 0x42, 0x00, 0x62, 0x14, 0xFF, 0x00, 0x02, 0x24, -0x0C, 0x00, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x68, 0x30, -0x3E, 0x00, 0x02, 0x11, 0x02, 0x80, 0x02, 0x3C, 0xAC, 0x37, 0xA3, 0xA2, -0xAC, 0x37, 0x22, 0x92, 0x7C, 0x38, 0x25, 0x8E, 0x20, 0x10, 0x03, 0x3C, -0x00, 0x12, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0xC8, 0xAE, -0x21, 0x30, 0x40, 0x00, 0x10, 0x38, 0x22, 0xAE, 0x0A, 0x00, 0x04, 0x24, -0x00, 0x01, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, -0x7C, 0x38, 0x30, 0x8E, 0x0A, 0x00, 0x04, 0x24, 0x00, 0x00, 0xD0, 0xAE, -0x5B, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C, -0xFF, 0xFF, 0x08, 0x32, 0x25, 0x80, 0x02, 0x01, 0xC2, 0x5C, 0xE3, 0x92, -0x02, 0x00, 0x04, 0x92, 0x02, 0x00, 0x02, 0x24, 0x0F, 0x00, 0x63, 0x30, -0xB0, 0xFF, 0x62, 0x14, 0x21, 0x38, 0x04, 0x02, 0x00, 0x00, 0x02, 0x8E, -0x00, 0x0C, 0x03, 0x3C, 0x24, 0x10, 0x43, 0x00, 0xAE, 0xFF, 0x43, 0x10, -0x02, 0x80, 0x02, 0x3C, 0x95, 0x58, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24, -0x7A, 0x37, 0x22, 0x96, 0x85, 0x38, 0x33, 0xA2, 0x01, 0x00, 0x42, 0x24, -0xF5, 0x08, 0x00, 0x08, 0x7A, 0x37, 0x22, 0xA6, 0x9B, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0xF3, 0x08, 0x00, 0x08, 0x85, 0x38, 0x20, 0xA2, -0x02, 0x80, 0x02, 0x3C, 0xE2, 0x08, 0x00, 0x08, 0x25, 0x38, 0x02, 0x01, -0x34, 0xD7, 0x22, 0x91, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x42, 0x30, -0x13, 0x00, 0xC2, 0x10, 0x25, 0xB0, 0x04, 0x3C, 0x6A, 0x37, 0x82, 0x96, -0x1E, 0x03, 0x84, 0x34, 0x10, 0x00, 0x42, 0x34, 0x3B, 0x00, 0x43, 0x2E, -0x00, 0x00, 0x82, 0xA4, 0x9F, 0xFF, 0x60, 0x14, 0x6A, 0x37, 0x82, 0xA6, -0xF6, 0x08, 0x00, 0x08, 0x39, 0x00, 0x02, 0x24, 0x02, 0x80, 0x02, 0x3C, -0xB0, 0x5D, 0x44, 0x8C, 0x25, 0xB0, 0x03, 0x3C, 0xB0, 0x03, 0x63, 0x34, -0x00, 0x00, 0x64, 0xAC, 0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x85, 0x08, 0x00, 0x08, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x00, 0xA5, 0x90, -0x34, 0xD7, 0x27, 0x91, 0x02, 0x80, 0x04, 0x3C, 0xCC, 0xE6, 0x84, 0x24, -0xFF, 0x00, 0xA5, 0x30, 0x13, 0x58, 0x00, 0x0C, 0xFF, 0x00, 0xE7, 0x30, -0xF6, 0x08, 0x00, 0x08, 0x39, 0x00, 0x02, 0x24, 0xC0, 0xFF, 0xBD, 0x27, -0x34, 0x00, 0xB7, 0xAF, 0x02, 0x80, 0x02, 0x3C, 0x21, 0xB8, 0xA0, 0x00, -0xFF, 0xFF, 0xA5, 0x30, 0x25, 0x40, 0xA2, 0x00, 0x20, 0x00, 0xB2, 0xAF, -0x38, 0x00, 0xBF, 0xAF, 0x30, 0x00, 0xB6, 0xAF, 0x2C, 0x00, 0xB5, 0xAF, -0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, -0x18, 0x00, 0xB0, 0xAF, 0x00, 0x00, 0x03, 0x8D, 0xFF, 0xFF, 0xD2, 0x30, -0x08, 0x00, 0x45, 0x26, 0x00, 0xC0, 0x02, 0x24, 0x04, 0x00, 0x06, 0x8D, -0x24, 0x18, 0x62, 0x00, 0xFF, 0x3F, 0xA5, 0x30, 0xF0, 0xFF, 0x02, 0x3C, -0x25, 0x18, 0x65, 0x00, 0xFF, 0xFF, 0x42, 0x34, 0x24, 0x18, 0x62, 0x00, -0x00, 0x80, 0x05, 0x3C, 0x25, 0x18, 0x65, 0x00, 0xFF, 0x01, 0xC6, 0x34, -0x00, 0x00, 0x03, 0xAD, 0x04, 0x00, 0x06, 0xAD, 0x21, 0x48, 0x80, 0x00, -0xFF, 0xFF, 0xE7, 0x30, 0x18, 0x00, 0x06, 0x25, 0x18, 0x00, 0x12, 0xA5, -0x02, 0x00, 0xC7, 0xA0, 0x18, 0x00, 0x03, 0x8D, 0xFF, 0x7F, 0x02, 0x3C, -0xFF, 0xFF, 0x42, 0x34, 0x24, 0x18, 0x62, 0x00, 0x02, 0x80, 0x16, 0x3C, -0x18, 0x00, 0x03, 0xAD, 0x60, 0x1B, 0xC5, 0x26, 0x66, 0x37, 0xA4, 0x90, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x82, 0x24, 0x66, 0x37, 0xA2, 0xA0, -0x18, 0x00, 0x03, 0x8D, 0xFF, 0x80, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, -0x7F, 0x00, 0x84, 0x30, 0x00, 0x26, 0x04, 0x00, 0x24, 0x18, 0x62, 0x00, -0x25, 0x18, 0x64, 0x00, 0x18, 0x00, 0x03, 0xAD, 0x02, 0x80, 0x02, 0x3C, -0xC2, 0x5C, 0x44, 0x90, 0x20, 0x00, 0x43, 0x26, 0xFF, 0xFF, 0x72, 0x30, -0x02, 0x00, 0x84, 0x30, 0x04, 0x00, 0x80, 0x10, 0x21, 0x18, 0x40, 0x02, -0x1F, 0x00, 0x42, 0x32, 0x5C, 0x00, 0x40, 0x10, 0x08, 0x00, 0x42, 0x26, -0xFF, 0xFF, 0x63, 0x30, 0x5D, 0x00, 0x43, 0x12, 0x00, 0x00, 0x00, 0x00, -0x04, 0x00, 0xC2, 0x8C, 0x21, 0x90, 0x60, 0x00, 0x00, 0xC0, 0x04, 0x24, -0x01, 0x00, 0x42, 0x34, 0x04, 0x00, 0xC2, 0xAC, 0x00, 0x00, 0x03, 0x8D, -0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x62, 0x30, 0x08, 0x00, 0x42, 0x24, -0x24, 0x18, 0x64, 0x00, 0xFF, 0x3F, 0x42, 0x30, 0x25, 0x18, 0x62, 0x00, -0x00, 0x00, 0x03, 0xAD, 0x25, 0xB0, 0x02, 0x3C, 0xC0, 0x00, 0x42, 0x34, -0x07, 0x00, 0x43, 0x32, 0x00, 0x00, 0x52, 0xA4, 0x03, 0x00, 0x60, 0x10, -0xF8, 0xFF, 0x53, 0x32, 0x08, 0x00, 0x42, 0x26, 0xF8, 0xFF, 0x53, 0x30, -0x60, 0x1B, 0xD5, 0x26, 0xEC, 0x38, 0xA6, 0x8E, 0xF0, 0x38, 0xB0, 0x8E, -0x21, 0x10, 0xD3, 0x00, 0x2B, 0x10, 0x02, 0x02, 0x32, 0x00, 0x40, 0x10, -0xFF, 0x00, 0x34, 0x31, 0x23, 0x80, 0x06, 0x02, 0x21, 0x28, 0xE0, 0x02, -0xFF, 0xFF, 0x07, 0x32, 0x01, 0x00, 0x11, 0x24, 0x21, 0x20, 0x80, 0x02, -0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xB1, 0xAF, 0x23, 0x18, 0x70, 0x02, -0xFF, 0xFF, 0x72, 0x30, 0x22, 0x10, 0x02, 0x3C, 0x21, 0x10, 0x42, 0x02, -0x21, 0x20, 0x80, 0x02, 0x5B, 0x01, 0x00, 0x0C, 0xEC, 0x38, 0xA2, 0xAE, -0x21, 0x28, 0xF0, 0x02, 0x21, 0x38, 0x40, 0x02, 0x21, 0x20, 0x80, 0x02, -0x22, 0x10, 0x06, 0x3C, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xB1, 0xAF, -0x60, 0x1B, 0xD1, 0x26, 0xEC, 0x38, 0x23, 0x8E, 0x25, 0xB0, 0x10, 0x3C, -0xB0, 0x03, 0x02, 0x36, 0x21, 0x20, 0x80, 0x02, 0x00, 0x00, 0x43, 0xAC, -0x5B, 0x01, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x38, 0x25, 0x8E, -0xEC, 0x00, 0x02, 0x36, 0xBD, 0x00, 0x04, 0x36, 0x00, 0x00, 0x45, 0xAC, -0x00, 0x00, 0x83, 0x90, 0xC2, 0x00, 0x10, 0x36, 0x38, 0x00, 0xBF, 0x8F, -0x10, 0x00, 0x63, 0x34, 0x00, 0x00, 0x83, 0xA0, 0x34, 0x00, 0xB7, 0x8F, -0x00, 0x00, 0x05, 0xA6, 0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, -0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, -0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x01, 0x00, 0x02, 0x24, -0x08, 0x00, 0xE0, 0x03, 0x40, 0x00, 0xBD, 0x27, 0x01, 0x00, 0x02, 0x24, -0x21, 0x28, 0xE0, 0x02, 0x21, 0x20, 0x80, 0x02, 0x21, 0x38, 0x60, 0x02, -0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF, 0xEC, 0x38, 0xA3, 0x8E, -0x00, 0x00, 0x00, 0x00, 0x21, 0x18, 0x73, 0x00, 0xC4, 0x09, 0x00, 0x08, -0xEC, 0x38, 0xA3, 0xAE, 0xFF, 0xFF, 0x43, 0x30, 0xFF, 0xFF, 0x63, 0x30, -0xA5, 0xFF, 0x43, 0x16, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xC2, 0x8C, -0xFE, 0xFF, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, 0xA1, 0x09, 0x00, 0x08, -0x04, 0x00, 0xC2, 0xAC, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF, -0x21, 0x80, 0x80, 0x00, 0x1C, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C, -0x10, 0x00, 0xA4, 0x27, 0x14, 0x00, 0x03, 0x8E, 0x16, 0x00, 0x02, 0x24, -0x21, 0x28, 0x00, 0x00, 0x0A, 0x00, 0x62, 0x10, 0x08, 0x00, 0x06, 0x24, -0x08, 0x00, 0x02, 0x96, 0x02, 0x80, 0x04, 0x3C, 0xEC, 0x54, 0x00, 0x0C, -0x25, 0x20, 0x44, 0x00, 0x08, 0x00, 0x05, 0x8E, 0x0C, 0x00, 0x06, 0x96, -0x14, 0x00, 0x07, 0x96, 0x51, 0x09, 0x00, 0x0C, 0x09, 0x00, 0x04, 0x24, -0x04, 0x00, 0x03, 0x8E, 0x00, 0x00, 0x02, 0x8E, 0x21, 0x20, 0x00, 0x02, -0x00, 0x00, 0x62, 0xAC, 0x04, 0x00, 0x43, 0xAC, 0x00, 0x00, 0x10, 0xAE, -0x74, 0x21, 0x00, 0x0C, 0x04, 0x00, 0x10, 0xAE, 0x90, 0x40, 0x00, 0x0C, -0x10, 0x00, 0xA4, 0x27, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27, -0x18, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0x80, 0x00, 0x1C, 0x00, 0xBF, 0xAF, -0x8A, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x25, 0xB0, 0x02, 0x3C, -0xBF, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, -0x04, 0x00, 0x63, 0x2C, 0x05, 0x00, 0x60, 0x10, 0x02, 0x80, 0x05, 0x3C, -0x90, 0x54, 0xA3, 0x8C, 0x90, 0x54, 0xA2, 0x24, 0x0D, 0x00, 0x62, 0x10, -0x21, 0x20, 0x00, 0x02, 0x90, 0x54, 0xA2, 0x24, 0x04, 0x00, 0x43, 0x8C, -0x00, 0x00, 0x02, 0xAE, 0x04, 0x00, 0x50, 0xAC, 0x00, 0x00, 0x70, 0xAC, -0x04, 0x00, 0x03, 0xAE, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, -0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x20, 0x00, 0xBD, 0x27, 0xF5, 0x09, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x1C, 0x00, 0xBF, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0xD8, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0x80, 0x00, -0x02, 0x80, 0x04, 0x3C, 0x08, 0xE7, 0x84, 0x24, 0x24, 0x00, 0xBF, 0xAF, -0x20, 0x00, 0xB2, 0xAF, 0x13, 0x58, 0x00, 0x0C, 0x1C, 0x00, 0xB1, 0xAF, -0x00, 0x00, 0x04, 0x96, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x83, 0x24, -0x07, 0x00, 0x62, 0x30, 0x6A, 0x00, 0x40, 0x10, 0xC2, 0x10, 0x03, 0x00, -0x28, 0x00, 0x82, 0x24, 0xC2, 0x10, 0x02, 0x00, 0x53, 0x21, 0x00, 0x0C, -0xC0, 0x20, 0x02, 0x00, 0x68, 0x00, 0x40, 0x10, 0x21, 0x88, 0x40, 0x00, -0x02, 0x80, 0x12, 0x3C, 0x02, 0x00, 0x06, 0x92, 0x60, 0x1B, 0x50, 0x26, -0x10, 0x38, 0x05, 0x8E, 0x08, 0x00, 0xC6, 0x24, 0x0A, 0x00, 0x04, 0x24, -0x72, 0x01, 0x00, 0x0C, 0x21, 0x38, 0x40, 0x00, 0xB0, 0x1B, 0x03, 0x96, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62, 0x30, 0x67, 0x00, 0x40, 0x14, -0x01, 0x00, 0x62, 0x30, 0x02, 0x80, 0x02, 0x3C, 0x4B, 0xF5, 0x43, 0x90, -0x60, 0x1B, 0x50, 0x26, 0x10, 0x00, 0xA4, 0x27, 0x02, 0x80, 0x02, 0x3C, -0xE8, 0x39, 0x00, 0xAE, 0x04, 0x3A, 0x00, 0xAE, 0xFC, 0x40, 0x00, 0xAE, -0xBC, 0x40, 0x00, 0xAE, 0xC6, 0x40, 0x00, 0xA2, 0x8A, 0x40, 0x00, 0x0C, -0xC6, 0x5C, 0x43, 0xA0, 0xA3, 0x6A, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x87, 0x6B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x90, 0x40, 0x00, 0x0C, -0x10, 0x00, 0xA4, 0x27, 0x02, 0x80, 0x02, 0x3C, 0xD2, 0x5C, 0x48, 0x90, -0x25, 0xB0, 0x04, 0x3C, 0x2F, 0x00, 0x02, 0x3C, 0xD0, 0x01, 0x85, 0x34, -0x17, 0x32, 0x42, 0x34, 0x00, 0x00, 0xA2, 0xAC, 0x5E, 0x00, 0x03, 0x3C, -0x10, 0x00, 0x02, 0x3C, 0xDC, 0x01, 0x87, 0x34, 0xD4, 0x01, 0x86, 0x34, -0x17, 0x43, 0x63, 0x34, 0x20, 0x53, 0x42, 0x34, 0xD8, 0x01, 0x84, 0x34, -0x00, 0x00, 0xC3, 0xAC, 0x00, 0x00, 0x82, 0xAC, 0x44, 0xA4, 0x03, 0x34, -0x01, 0x00, 0x02, 0x24, 0x00, 0x00, 0xE3, 0xAC, 0x52, 0x00, 0x02, 0x11, -0xFF, 0xF7, 0x03, 0x24, 0xFC, 0x23, 0x02, 0x8E, 0xFF, 0xEF, 0x04, 0x24, -0x24, 0x10, 0x43, 0x00, 0x24, 0x10, 0x44, 0x00, 0xFC, 0x23, 0x02, 0xAE, -0x60, 0x1B, 0x42, 0x8E, 0xDF, 0xFF, 0x03, 0x24, 0xFB, 0xFF, 0x04, 0x24, -0x24, 0x10, 0x43, 0x00, 0x24, 0x10, 0x44, 0x00, 0xFE, 0xFF, 0x03, 0x24, -0x24, 0x10, 0x43, 0x00, 0x50, 0x0C, 0x04, 0x24, 0x60, 0x1B, 0x50, 0x26, -0x30, 0x5C, 0x00, 0x0C, 0x60, 0x1B, 0x42, 0xAE, 0x38, 0x3E, 0x02, 0xA2, -0x30, 0x5C, 0x00, 0x0C, 0x58, 0x0C, 0x04, 0x24, 0x39, 0x3E, 0x02, 0xA2, -0x50, 0x0C, 0x04, 0x24, 0x1A, 0x5C, 0x00, 0x0C, 0x17, 0x00, 0x05, 0x24, -0x17, 0x00, 0x05, 0x24, 0x1A, 0x5C, 0x00, 0x0C, 0x58, 0x0C, 0x04, 0x24, -0x5B, 0x01, 0x00, 0x0C, 0x0A, 0x00, 0x04, 0x24, 0x08, 0x00, 0x22, 0x96, -0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x04, 0x3C, 0x25, 0x28, 0x45, 0x00, -0x74, 0x03, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0xB0, 0x55, 0x84, 0x24, -0x74, 0x21, 0x00, 0x0C, 0x21, 0x20, 0x20, 0x02, 0x98, 0x3A, 0x02, 0x8E, -0x49, 0x4B, 0x00, 0x0C, 0xC4, 0x3D, 0x02, 0xA2, 0x24, 0x00, 0xBF, 0x8F, -0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, -0x53, 0x21, 0x00, 0x0C, 0xC0, 0x20, 0x02, 0x00, 0x9A, 0xFF, 0x40, 0x14, -0x21, 0x88, 0x40, 0x00, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, -0x18, 0xE7, 0x84, 0x24, 0x13, 0x58, 0x00, 0x0C, 0xFC, 0xE6, 0xA5, 0x24, -0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x28, 0x00, 0xBD, 0x27, 0x20, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x87, 0x54, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x05, 0x3C, -0x4C, 0x00, 0xA2, 0x34, 0x00, 0x00, 0x40, 0xA0, 0x48, 0x00, 0xA5, 0x34, -0xB0, 0x1B, 0x03, 0x96, 0x00, 0x00, 0xA4, 0x8C, 0x7B, 0xFF, 0x02, 0x3C, -0xFF, 0xFF, 0x42, 0x34, 0x24, 0x20, 0x82, 0x00, 0xFF, 0xFE, 0x63, 0x30, -0xB0, 0x1B, 0x03, 0xA6, 0x00, 0x00, 0xA4, 0xAC, 0x5F, 0x0A, 0x00, 0x08, -0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0xD3, 0x5C, 0x44, 0x90, -0x02, 0x00, 0x03, 0x24, 0x06, 0x00, 0x83, 0x10, 0xFF, 0xF7, 0x03, 0x24, -0xFC, 0x23, 0x02, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x43, 0x00, -0x89, 0x0A, 0x00, 0x08, 0x00, 0x10, 0x42, 0x34, 0xFC, 0x23, 0x02, 0x8E, -0xFF, 0xEF, 0x03, 0x24, 0x00, 0x08, 0x42, 0x34, 0x89, 0x0A, 0x00, 0x08, -0x24, 0x10, 0x43, 0x00, 0x02, 0x80, 0x04, 0x3C, 0xB4, 0x55, 0x84, 0x24, -0x1C, 0x4F, 0x00, 0x0C, 0x03, 0x00, 0x05, 0x24, 0xC6, 0x0A, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF, -0x00, 0x00, 0x84, 0x90, 0x02, 0x80, 0x06, 0x3C, 0x01, 0x00, 0x02, 0x24, -0xFF, 0x00, 0x83, 0x30, 0x0C, 0x00, 0x62, 0x10, 0x60, 0x1B, 0xC5, 0x24, -0x04, 0x00, 0x02, 0x24, 0x13, 0x00, 0x62, 0x10, 0x60, 0x1B, 0xC2, 0x24, -0xC6, 0x3D, 0x45, 0x90, 0x02, 0x80, 0x04, 0x3C, 0x13, 0x58, 0x00, 0x0C, -0x24, 0xE7, 0x84, 0x24, 0x10, 0x00, 0xBF, 0x8F, 0x21, 0x10, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xC6, 0x3D, 0xA4, 0xA0, -0x60, 0x1B, 0xC2, 0x24, 0xC6, 0x3D, 0x45, 0x90, 0x02, 0x80, 0x04, 0x3C, -0x13, 0x58, 0x00, 0x0C, 0x24, 0xE7, 0x84, 0x24, 0x10, 0x00, 0xBF, 0x8F, -0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, -0x60, 0x1B, 0xC3, 0x24, 0xB0, 0x1B, 0x62, 0x94, 0xC6, 0x3D, 0x64, 0xA0, -0x02, 0x80, 0x04, 0x3C, 0x04, 0x00, 0x42, 0x34, 0xB0, 0x1B, 0x62, 0xA4, -0x60, 0x1B, 0xC2, 0x24, 0xC6, 0x3D, 0x45, 0x90, 0x13, 0x58, 0x00, 0x0C, -0x24, 0xE7, 0x84, 0x24, 0x10, 0x00, 0xBF, 0x8F, 0x21, 0x10, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xD0, 0xFF, 0xBD, 0x27, -0x20, 0x00, 0xB2, 0xAF, 0x02, 0x80, 0x12, 0x3C, 0x24, 0x00, 0xB3, 0xAF, -0x1C, 0x00, 0xB1, 0xAF, 0x2C, 0x00, 0xBF, 0xAF, 0x28, 0x00, 0xB4, 0xAF, -0x18, 0x00, 0xB0, 0xAF, 0x60, 0x1B, 0x51, 0x26, 0xB0, 0x1B, 0x22, 0x96, -0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x42, 0x30, 0x0A, 0x00, 0x40, 0x10, -0x21, 0x98, 0x80, 0x00, 0x2C, 0x00, 0xBF, 0x8F, 0x28, 0x00, 0xB4, 0x8F, -0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x30, 0x00, 0xBD, 0x27, 0x10, 0x00, 0xA4, 0x27, 0x8A, 0x40, 0x00, 0x0C, -0x02, 0x80, 0x14, 0x3C, 0xEE, 0x5D, 0x82, 0x92, 0x00, 0x00, 0x00, 0x00, -0x0F, 0x00, 0x42, 0x30, 0x04, 0x00, 0x42, 0x28, 0x89, 0x00, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, -0x60, 0x1B, 0x42, 0x8E, 0xDF, 0xFF, 0x03, 0x24, 0xFB, 0xFF, 0x04, 0x24, -0x24, 0x10, 0x43, 0x00, 0x24, 0x10, 0x44, 0x00, 0xFE, 0xFF, 0x03, 0x24, -0x24, 0x10, 0x43, 0x00, 0x50, 0x0C, 0x04, 0x24, 0x30, 0x5C, 0x00, 0x0C, -0x60, 0x1B, 0x42, 0xAE, 0x38, 0x3E, 0x22, 0xA2, 0x30, 0x5C, 0x00, 0x0C, -0x58, 0x0C, 0x04, 0x24, 0x39, 0x3E, 0x22, 0xA2, 0x50, 0x0C, 0x04, 0x24, -0x1A, 0x5C, 0x00, 0x0C, 0x17, 0x00, 0x05, 0x24, 0x17, 0x00, 0x05, 0x24, -0x1A, 0x5C, 0x00, 0x0C, 0x58, 0x0C, 0x04, 0x24, 0xB0, 0x1B, 0x22, 0x96, -0x02, 0x80, 0x04, 0x3C, 0x34, 0xE7, 0x84, 0x24, 0x00, 0x10, 0x42, 0x34, -0x13, 0x58, 0x00, 0x0C, 0xB0, 0x1B, 0x22, 0xA6, 0x01, 0x00, 0x02, 0x24, -0x25, 0xB0, 0x03, 0x3C, 0x04, 0x3E, 0x22, 0xAE, 0x4C, 0x00, 0x63, 0x34, -0xB0, 0x1B, 0x22, 0x96, 0x00, 0x00, 0x66, 0x90, 0x08, 0x00, 0x65, 0x8E, -0xC4, 0x3D, 0x27, 0x92, 0xC5, 0x3D, 0x28, 0x92, 0x3B, 0x41, 0x29, 0x92, -0xD0, 0x3D, 0x2A, 0x92, 0xFF, 0x3D, 0x2B, 0x92, 0x00, 0x80, 0x42, 0x30, -0x37, 0x3E, 0x26, 0xA2, 0x0C, 0x3E, 0x25, 0xAE, 0x10, 0x00, 0xA4, 0x27, -0x00, 0x00, 0x60, 0xA0, 0x31, 0x3E, 0x27, 0xA2, 0x32, 0x3E, 0x28, 0xA2, -0x34, 0x3E, 0x22, 0xA6, 0x36, 0x3E, 0x29, 0xA2, 0xC4, 0x3D, 0x2A, 0xA2, -0xC5, 0x3D, 0x2B, 0xA2, 0x3C, 0x3E, 0x20, 0xAE, 0x40, 0x3E, 0x20, 0xAE, -0x8A, 0x40, 0x00, 0x0C, 0x33, 0x3E, 0x20, 0xA2, 0x10, 0x00, 0xA4, 0x27, -0x90, 0x40, 0x00, 0x0C, 0x52, 0x41, 0x20, 0xA2, 0x21, 0x20, 0x00, 0x00, -0x95, 0x0E, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, 0x08, 0x00, 0x66, 0x8E, -0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0xC0, 0x14, 0x0C, 0x00, 0x70, 0x26, -0x00, 0x00, 0x62, 0x8E, 0x21, 0x20, 0x20, 0x02, 0x44, 0x3E, 0x23, 0x26, -0x08, 0x3E, 0x22, 0xAE, 0x3F, 0x00, 0x02, 0x24, 0xFF, 0xFF, 0x42, 0x24, -0x00, 0x00, 0x60, 0xA0, 0xFD, 0xFF, 0x41, 0x04, 0x07, 0x00, 0x63, 0x24, -0xB0, 0x1B, 0x83, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62, 0x30, -0x09, 0x00, 0x40, 0x10, 0x60, 0x1B, 0x50, 0x26, 0x01, 0x00, 0x62, 0x30, -0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x5D, 0x82, 0x92, -0x0C, 0x00, 0x03, 0x24, 0x0F, 0x00, 0x42, 0x30, 0x37, 0x00, 0x43, 0x10, -0x00, 0x00, 0x00, 0x00, 0xC4, 0x3D, 0x04, 0x92, 0x75, 0x0D, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0xC4, 0x3D, 0x04, 0x92, 0x38, 0x0D, 0x00, 0x0C, -0x01, 0x00, 0x05, 0x24, 0x25, 0xB0, 0x04, 0x3C, 0x48, 0x00, 0x84, 0x34, -0x00, 0x00, 0x83, 0x8C, 0x08, 0x3E, 0x05, 0x8E, 0x7B, 0xFF, 0x02, 0x3C, -0xFF, 0xFF, 0x42, 0x34, 0x24, 0x18, 0x62, 0x00, 0x01, 0x00, 0x02, 0x24, -0x00, 0x00, 0x83, 0xAC, 0x0C, 0x00, 0xA2, 0x10, 0x60, 0x1B, 0x43, 0x26, -0x3C, 0x00, 0x02, 0x24, 0x94, 0x39, 0x62, 0xAC, 0x2C, 0x00, 0xBF, 0x8F, -0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, -0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, 0xC4, 0x3D, 0x02, 0x92, -0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x42, 0x2C, 0xF1, 0xFF, 0x40, 0x10, -0x00, 0x00, 0x00, 0x00, 0x12, 0x49, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x60, 0x1B, 0x43, 0x26, 0x3C, 0x00, 0x02, 0x24, 0xA0, 0x0B, 0x00, 0x08, -0x94, 0x39, 0x62, 0xAC, 0x02, 0x80, 0x04, 0x3C, 0x21, 0x28, 0x00, 0x02, -0xF4, 0x54, 0x00, 0x0C, 0x70, 0x59, 0x84, 0x24, 0x02, 0x80, 0x04, 0x3C, -0x44, 0xE7, 0x84, 0x24, 0x13, 0x58, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x02, -0x77, 0x0B, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x24, -0x4B, 0x2E, 0x00, 0x0C, 0x01, 0x00, 0x05, 0x24, 0x36, 0x0B, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x0E, 0x51, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24, -0x8D, 0x0B, 0x00, 0x08, 0x60, 0x1B, 0x50, 0x26, 0xE8, 0xFF, 0xBD, 0x27, -0x10, 0x00, 0xB0, 0xAF, 0x14, 0x00, 0xBF, 0xAF, 0x21, 0x80, 0x80, 0x00, -0x00, 0x00, 0x02, 0x92, 0x02, 0x80, 0x04, 0x3C, 0x21, 0x28, 0x40, 0x00, -0x04, 0x00, 0x42, 0x2C, 0x06, 0x00, 0x40, 0x14, 0x50, 0xE7, 0x84, 0x24, -0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0x13, 0x58, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x92, 0x14, 0x00, 0xBF, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x02, 0x80, 0x02, 0x3C, 0x84, 0x5B, 0x43, 0xAC, -0x18, 0x00, 0xBD, 0x27, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, -0x00, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, 0xD0, 0xFF, 0xBD, 0x27, -0x18, 0x03, 0x42, 0x34, 0x80, 0x2F, 0x63, 0x24, 0x24, 0x00, 0xB3, 0xAF, -0x28, 0x00, 0xBF, 0xAF, 0x20, 0x00, 0xB2, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, -0x18, 0x00, 0xB0, 0xAF, 0x00, 0x00, 0x43, 0xAC, 0x02, 0x80, 0x04, 0x3C, -0xEC, 0x5D, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x40, 0x10, -0x02, 0x80, 0x13, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0x06, 0x5E, 0x43, 0x90, -0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x60, 0x14, 0x01, 0x00, 0x04, 0x24, -0x02, 0x80, 0x02, 0x3C, 0x0F, 0x5E, 0x44, 0xA0, 0x02, 0x80, 0x03, 0x3C, -0xED, 0x5D, 0x64, 0x90, 0x01, 0x00, 0x05, 0x24, 0x4B, 0x2E, 0x00, 0x0C, -0xFF, 0x00, 0x84, 0x30, 0x02, 0x80, 0x02, 0x3C, 0x98, 0x54, 0x43, 0x8C, -0x98, 0x54, 0x42, 0x24, 0xA2, 0x00, 0x62, 0x10, 0x02, 0x80, 0x13, 0x3C, -0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xB0, 0x02, 0x3C, -0x36, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0x90, 0x60, 0x1B, 0x66, 0x26, -0xF4, 0x38, 0xC5, 0x8C, 0xC0, 0x18, 0x03, 0x00, 0x23, 0xB0, 0x04, 0x3C, -0xF0, 0x07, 0x63, 0x30, 0xFF, 0x1F, 0x02, 0x3C, 0x21, 0x18, 0x64, 0x00, -0xFF, 0xFF, 0x42, 0x34, 0x24, 0x20, 0x62, 0x00, 0x23, 0x88, 0x85, 0x00, -0x00, 0x04, 0x22, 0x26, 0x2B, 0x28, 0x85, 0x00, 0x98, 0x38, 0xC3, 0x8C, -0x0B, 0x88, 0x45, 0x00, 0xE1, 0x01, 0x22, 0x2E, 0x94, 0x38, 0xC3, 0xAC, -0xF8, 0x38, 0xC4, 0xAC, 0x9E, 0x38, 0xC0, 0xA4, 0x14, 0x00, 0x40, 0x14, -0x9D, 0x38, 0xC0, 0xA0, 0x20, 0xFE, 0x82, 0x24, 0x20, 0x02, 0x83, 0x24, -0x0A, 0x18, 0x45, 0x00, 0x23, 0x10, 0x02, 0x3C, 0xFF, 0x03, 0x42, 0x34, -0x2B, 0x10, 0x43, 0x00, 0x21, 0x28, 0x60, 0x00, 0x32, 0x00, 0x40, 0x14, -0xF4, 0x38, 0xC3, 0xAC, 0xF8, 0x38, 0xC2, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x2B, 0x18, 0x45, 0x00, 0x23, 0x88, 0x45, 0x00, 0x03, 0x00, 0x60, 0x10, -0xE1, 0x01, 0x22, 0x2E, 0x00, 0x04, 0x31, 0x26, 0xE1, 0x01, 0x22, 0x2E, -0x0E, 0x00, 0x40, 0x10, 0x60, 0x1B, 0x70, 0x26, 0x60, 0x1B, 0x70, 0x26, -0xF8, 0x38, 0x03, 0x8E, 0xF4, 0x38, 0x04, 0x8E, 0x00, 0x00, 0x00, 0x00, -0x2B, 0x10, 0x83, 0x00, 0x2C, 0x00, 0x40, 0x14, 0x2B, 0x10, 0x64, 0x00, -0x56, 0x00, 0x40, 0x14, 0x25, 0xB0, 0x02, 0x3C, 0x80, 0x00, 0x03, 0x24, -0xD0, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, 0x60, 0x1B, 0x70, 0x26, -0xF4, 0x38, 0x03, 0x96, 0x2A, 0xB0, 0x02, 0x3C, 0x35, 0x00, 0x42, 0x34, -0xC2, 0x88, 0x03, 0x00, 0x00, 0x00, 0x51, 0xA0, 0x73, 0x23, 0x00, 0x74, -0x00, 0x00, 0x00, 0x00, 0x9E, 0x38, 0x03, 0x96, 0x25, 0xB0, 0x02, 0x3C, -0xB0, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, 0x9B, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0xD0, 0x1B, 0x02, 0x8E, 0x80, 0x00, 0x03, 0x3C, -0x41, 0xB0, 0x04, 0x3C, 0x25, 0x10, 0x43, 0x00, 0x00, 0x00, 0x82, 0xAC, -0x28, 0x00, 0xBF, 0x8F, 0xD0, 0x1B, 0x02, 0xAE, 0x24, 0x00, 0xB3, 0x8F, -0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, 0x00, 0xFC, 0xA5, 0x24, -0x23, 0x0C, 0x00, 0x08, 0xF4, 0x38, 0xC5, 0xAC, 0x24, 0x2D, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0xA2, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, -0xE2, 0x2C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x0B, 0x00, 0x08, -0x02, 0x80, 0x02, 0x3C, 0x94, 0x38, 0x05, 0x8E, 0x21, 0x30, 0x80, 0x00, -0xFF, 0xFF, 0x27, 0x32, 0x09, 0x00, 0x04, 0x24, 0x1E, 0x01, 0x00, 0x0C, -0x10, 0x00, 0xA0, 0xAF, 0x94, 0x38, 0x03, 0x8E, 0x9E, 0x38, 0x05, 0x96, -0xF4, 0x38, 0x02, 0x8E, 0x21, 0x18, 0x71, 0x00, 0x21, 0x28, 0x25, 0x02, -0x21, 0x10, 0x51, 0x00, 0x09, 0x00, 0x04, 0x24, 0xF4, 0x38, 0x02, 0xAE, -0x94, 0x38, 0x03, 0xAE, 0x5B, 0x01, 0x00, 0x0C, 0x9E, 0x38, 0x05, 0xA6, -0x60, 0x1B, 0x70, 0x26, 0xF4, 0x38, 0x03, 0x96, 0x2A, 0xB0, 0x02, 0x3C, -0x35, 0x00, 0x42, 0x34, 0xC2, 0x88, 0x03, 0x00, 0x00, 0x00, 0x51, 0xA0, -0x73, 0x23, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x9E, 0x38, 0x03, 0x96, -0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, -0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xD0, 0x1B, 0x02, 0x8E, -0x80, 0x00, 0x03, 0x3C, 0x41, 0xB0, 0x04, 0x3C, 0x25, 0x10, 0x43, 0x00, -0x00, 0x00, 0x82, 0xAC, 0x28, 0x00, 0xBF, 0x8F, 0xD0, 0x1B, 0x02, 0xAE, -0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, -0xFC, 0x38, 0x02, 0x8E, 0x94, 0x38, 0x05, 0x8E, 0x21, 0x30, 0x80, 0x00, -0x23, 0x88, 0x44, 0x00, 0xFF, 0xFF, 0x27, 0x32, 0x09, 0x00, 0x04, 0x24, -0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, 0x94, 0x38, 0x03, 0x8E, -0x9E, 0x38, 0x02, 0x96, 0xF8, 0x38, 0x12, 0x96, 0x21, 0x18, 0x71, 0x00, -0x21, 0x10, 0x22, 0x02, 0x23, 0x10, 0x11, 0x3C, 0x94, 0x38, 0x03, 0xAE, -0x9E, 0x38, 0x02, 0xA6, 0x15, 0x00, 0x40, 0x16, 0xF4, 0x38, 0x11, 0xAE, -0x09, 0x00, 0x04, 0x24, 0x5B, 0x01, 0x00, 0x0C, 0x60, 0x1B, 0x70, 0x26, -0x71, 0x0C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2D, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x5C, 0xFF, 0x40, 0x10, 0x60, 0x1B, 0x63, 0x26, -0x2A, 0x1C, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x58, 0xFF, 0x40, 0x10, -0x00, 0x00, 0x00, 0x00, 0x4C, 0x3A, 0x64, 0x94, 0x2A, 0x1C, 0x60, 0xA0, -0x00, 0xC0, 0x84, 0x24, 0xA3, 0x31, 0x00, 0x0C, 0xFF, 0xFF, 0x84, 0x30, -0x01, 0x0C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x5B, 0x01, 0x00, 0x0C, -0x09, 0x00, 0x04, 0x24, 0x94, 0x38, 0x05, 0x8E, 0x09, 0x00, 0x04, 0x24, -0x23, 0x10, 0x06, 0x3C, 0x21, 0x38, 0x40, 0x02, 0x1E, 0x01, 0x00, 0x0C, -0x10, 0x00, 0xA0, 0xAF, 0x94, 0x38, 0x03, 0x8E, 0x9E, 0x38, 0x02, 0x96, -0x21, 0x20, 0x51, 0x02, 0x21, 0x18, 0x72, 0x00, 0x21, 0x10, 0x42, 0x02, -0xF4, 0x38, 0x04, 0xAE, 0x09, 0x00, 0x04, 0x24, 0x94, 0x38, 0x03, 0xAE, -0x9E, 0x0C, 0x00, 0x08, 0x9E, 0x38, 0x02, 0xA6, 0x08, 0x00, 0xE0, 0x03, -0x09, 0x00, 0x02, 0x24, 0xFF, 0x00, 0x86, 0x30, 0x02, 0x80, 0x02, 0x3C, -0x40, 0x00, 0xC3, 0x2C, 0x4A, 0xF5, 0x47, 0x90, 0x00, 0x00, 0x63, 0x38, -0x3F, 0x00, 0x02, 0x24, 0x0A, 0x30, 0x43, 0x00, 0x01, 0x00, 0x02, 0x24, -0x08, 0x0E, 0x04, 0x24, 0x00, 0x7F, 0x05, 0x24, 0x03, 0x00, 0xE2, 0x10, -0x31, 0x00, 0xC3, 0x2C, 0xC1, 0x43, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x30, 0x00, 0x02, 0x24, 0xC1, 0x43, 0x00, 0x08, 0x0A, 0x30, 0x43, 0x00, -0xC0, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x03, 0x3C, 0x38, 0x00, 0xB4, 0xAF, -0x34, 0x00, 0xB3, 0xAF, 0x30, 0x00, 0xB2, 0xAF, 0x2C, 0x00, 0xB1, 0xAF, -0x28, 0x00, 0xB0, 0xAF, 0xA4, 0xE7, 0x62, 0x24, 0x3C, 0x00, 0xBF, 0xAF, -0x0A, 0x00, 0x4A, 0x94, 0x02, 0x00, 0x48, 0x94, 0x06, 0x00, 0x49, 0x94, -0xFF, 0x00, 0x84, 0x30, 0xFF, 0x00, 0xA5, 0x30, 0xA4, 0xE7, 0x6B, 0x94, -0x04, 0x00, 0x4C, 0x94, 0x08, 0x00, 0x4D, 0x94, 0x00, 0x1C, 0x05, 0x00, -0x00, 0x14, 0x04, 0x00, 0x00, 0x3E, 0x05, 0x00, 0x00, 0x36, 0x04, 0x00, -0x25, 0x38, 0xE3, 0x00, 0x25, 0x30, 0xC2, 0x00, 0x00, 0x44, 0x08, 0x00, -0x00, 0x12, 0x05, 0x00, 0x00, 0x4C, 0x09, 0x00, 0x00, 0x54, 0x0A, 0x00, -0x00, 0x1A, 0x04, 0x00, 0x25, 0x38, 0xE2, 0x00, 0x25, 0x40, 0x0B, 0x01, -0x25, 0x48, 0x2C, 0x01, 0x25, 0x50, 0x4D, 0x01, 0x25, 0x30, 0xC3, 0x00, -0x02, 0x80, 0x02, 0x3C, 0x10, 0x00, 0xA8, 0xAF, 0x14, 0x00, 0xA9, 0xAF, -0x18, 0x00, 0xAA, 0xAF, 0x25, 0x98, 0xE5, 0x00, 0x25, 0x90, 0xC4, 0x00, -0x60, 0x1B, 0x54, 0x24, 0x21, 0x80, 0x00, 0x00, 0x10, 0x00, 0xB1, 0x27, -0x02, 0x00, 0x02, 0x2E, 0x32, 0x00, 0x40, 0x10, 0x80, 0x10, 0x10, 0x00, -0x21, 0x10, 0x54, 0x00, 0xF0, 0x1C, 0x43, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x21, 0x40, 0x73, 0x00, 0x21, 0x38, 0x00, 0x00, 0x7F, 0x00, 0x09, 0x24, -0xC0, 0x20, 0x07, 0x00, 0x04, 0x10, 0x89, 0x00, 0x24, 0x10, 0x48, 0x00, -0x06, 0x10, 0x82, 0x00, 0x01, 0x00, 0xE5, 0x24, 0xFF, 0x00, 0x43, 0x30, -0x21, 0x30, 0x27, 0x02, 0x40, 0x00, 0x63, 0x2C, 0xFF, 0x00, 0xA7, 0x30, -0x02, 0x00, 0x60, 0x14, 0x04, 0x00, 0xE4, 0x2C, 0x3F, 0x00, 0x02, 0x24, -0xF3, 0xFF, 0x80, 0x14, 0x10, 0x00, 0xC2, 0xA0, 0x23, 0x00, 0xA6, 0x93, -0x22, 0x00, 0xA2, 0x93, 0x21, 0x00, 0xA5, 0x93, 0x40, 0x18, 0x10, 0x00, -0x00, 0x14, 0x02, 0x00, 0x21, 0x18, 0x71, 0x00, 0x20, 0x00, 0xA7, 0x93, -0x00, 0x36, 0x06, 0x00, 0x25, 0x30, 0xC2, 0x00, 0x00, 0x2A, 0x05, 0x00, -0x00, 0x00, 0x64, 0x94, 0x25, 0x30, 0xC5, 0x00, 0x7F, 0x7F, 0x05, 0x3C, -0x25, 0x30, 0xC7, 0x00, 0xC1, 0x43, 0x00, 0x0C, 0x7F, 0x7F, 0xA5, 0x34, -0x01, 0x00, 0x02, 0x26, 0xFF, 0x00, 0x50, 0x30, 0x06, 0x00, 0x03, 0x2E, -0xD5, 0xFF, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0xBF, 0x8F, -0x38, 0x00, 0xB4, 0x8F, 0x34, 0x00, 0xB3, 0x8F, 0x30, 0x00, 0xB2, 0x8F, -0x2C, 0x00, 0xB1, 0x8F, 0x28, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x40, 0x00, 0xBD, 0x27, 0x21, 0x10, 0x54, 0x00, 0xF0, 0x1C, 0x43, 0x8C, -0x07, 0x0D, 0x00, 0x08, 0x21, 0x40, 0x72, 0x00, 0xD8, 0xFF, 0xBD, 0x27, -0x14, 0x00, 0xB1, 0xAF, 0x20, 0x00, 0xBF, 0xAF, 0x1C, 0x00, 0xB3, 0xAF, -0x18, 0x00, 0xB2, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x02, 0x3C, -0xC6, 0x5C, 0x43, 0x90, 0x02, 0x80, 0x07, 0x3C, 0x60, 0x1B, 0xE2, 0x24, -0xFF, 0x00, 0x91, 0x30, 0x21, 0x20, 0x22, 0x02, 0x20, 0x00, 0x62, 0x30, -0x10, 0x00, 0x63, 0x30, 0x63, 0x1D, 0x93, 0x90, 0x27, 0x00, 0x60, 0x10, -0x00, 0x00, 0x00, 0x00, 0x8D, 0x1D, 0x82, 0x90, 0x7F, 0x1D, 0x83, 0x90, -0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x43, 0x00, 0x00, 0x36, 0x02, 0x00, -0x03, 0x36, 0x06, 0x00, 0xFF, 0x00, 0x70, 0x30, 0x60, 0x1B, 0xE7, 0x24, -0x21, 0x40, 0x27, 0x02, 0xB7, 0x1D, 0x02, 0x91, 0xB0, 0x1B, 0xE3, 0x84, -0x0F, 0x00, 0x05, 0x3C, 0x0F, 0x00, 0x42, 0x30, 0x21, 0x10, 0x50, 0x00, -0x0C, 0x08, 0x04, 0x24, 0x0F, 0x00, 0xC6, 0x30, 0x00, 0xFF, 0xA5, 0x34, -0x06, 0x00, 0x60, 0x04, 0xFF, 0x00, 0x52, 0x30, 0xC5, 0x1D, 0x02, 0x91, -0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x42, 0x30, 0x21, 0x10, 0x50, 0x00, -0xFF, 0x00, 0x50, 0x30, 0xC1, 0x43, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0xC5, 0x0C, 0x00, 0x0C, 0x21, 0x20, 0x60, 0x02, 0x21, 0x20, 0x00, 0x02, -0x21, 0x28, 0x40, 0x02, 0x21, 0x30, 0x20, 0x02, 0x20, 0x00, 0xBF, 0x8F, -0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0xD6, 0x0C, 0x00, 0x08, 0x28, 0x00, 0xBD, 0x27, -0xE0, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xA9, 0x1D, 0x82, 0x90, -0x9B, 0x1D, 0x83, 0x90, 0x4D, 0x0D, 0x00, 0x08, 0x23, 0x10, 0x43, 0x00, -0xE0, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x02, 0x3C, -0x18, 0x00, 0xBF, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0xD1, 0x5C, 0x43, 0x90, -0x01, 0x00, 0x02, 0x24, 0x09, 0x00, 0x62, 0x10, 0xFF, 0x00, 0x90, 0x30, -0x21, 0x30, 0x00, 0x02, 0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x18, 0x00, 0x04, 0x24, 0xFF, 0x03, 0x05, 0x24, -0x83, 0x45, 0x00, 0x08, 0x20, 0x00, 0xBD, 0x27, 0x0F, 0x00, 0x05, 0x3C, -0xFF, 0xFF, 0xA5, 0x34, 0x15, 0x00, 0x04, 0x24, 0x0A, 0x00, 0x03, 0x12, -0xF4, 0xA8, 0x06, 0x34, 0x0F, 0x00, 0x05, 0x3C, 0x0B, 0x00, 0x02, 0x24, -0xFF, 0xFF, 0xA5, 0x34, 0x05, 0x00, 0x02, 0x12, 0xF5, 0xF8, 0x06, 0x34, -0x0F, 0x00, 0x05, 0x3C, 0xF4, 0xF8, 0x06, 0x34, 0x15, 0x00, 0x04, 0x24, -0xFF, 0xFF, 0xA5, 0x34, 0x83, 0x45, 0x00, 0x0C, 0x0F, 0x00, 0x11, 0x3C, -0x02, 0x80, 0x02, 0x3C, 0x48, 0xF5, 0x46, 0x90, 0xFE, 0x00, 0x03, 0x24, -0x15, 0x00, 0x04, 0x24, 0xE3, 0xFF, 0xC3, 0x14, 0xFF, 0xFF, 0x25, 0x36, -0xAC, 0x45, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x46, 0x30, -0x00, 0xFF, 0x23, 0x36, 0x24, 0x10, 0x43, 0x00, 0x01, 0x00, 0xC6, 0x24, -0x25, 0x30, 0x46, 0x00, 0xFF, 0xFF, 0x25, 0x36, 0x83, 0x45, 0x00, 0x0C, -0x15, 0x00, 0x04, 0x24, 0x7F, 0x0D, 0x00, 0x08, 0x21, 0x30, 0x00, 0x02, -0xFC, 0x00, 0x84, 0x30, 0x80, 0x00, 0x02, 0x24, 0x11, 0x00, 0x82, 0x10, -0x06, 0x00, 0x03, 0x24, 0x81, 0x00, 0x82, 0x28, 0x10, 0x00, 0x40, 0x10, -0xB0, 0x00, 0x02, 0x24, 0x20, 0x00, 0x02, 0x24, 0x0B, 0x00, 0x82, 0x10, -0x02, 0x00, 0x03, 0x24, 0x21, 0x00, 0x82, 0x28, 0x15, 0x00, 0x40, 0x10, -0x40, 0x00, 0x02, 0x24, 0x06, 0x00, 0x80, 0x10, 0x21, 0x18, 0x00, 0x00, -0x01, 0x00, 0x03, 0x24, 0x10, 0x00, 0x02, 0x24, 0x02, 0x00, 0x82, 0x10, -0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0x60, 0x00, 0xFD, 0xFF, 0x82, 0x10, 0x09, 0x00, 0x03, 0x24, -0xB1, 0x00, 0x82, 0x28, 0x0F, 0x00, 0x40, 0x10, 0xC8, 0x00, 0x02, 0x24, -0x90, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x82, 0x10, 0x07, 0x00, 0x03, 0x24, -0x08, 0x00, 0x03, 0x24, 0xB9, 0x0D, 0x00, 0x08, 0xA0, 0x00, 0x02, 0x24, -0xF2, 0xFF, 0x82, 0x10, 0x04, 0x00, 0x03, 0x24, 0x41, 0x00, 0x82, 0x28, -0x0F, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x24, -0xB9, 0x0D, 0x00, 0x08, 0x30, 0x00, 0x02, 0x24, 0xEA, 0xFF, 0x82, 0x10, -0x0C, 0x00, 0x03, 0x24, 0xC9, 0x00, 0x82, 0x28, 0x04, 0x00, 0x40, 0x10, -0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x03, 0x24, 0xB9, 0x0D, 0x00, 0x08, -0xC0, 0x00, 0x02, 0x24, 0x0B, 0x00, 0x03, 0x24, 0xB9, 0x0D, 0x00, 0x08, -0xD0, 0x00, 0x02, 0x24, 0x05, 0x00, 0x03, 0x24, 0xB9, 0x0D, 0x00, 0x08, -0x50, 0x00, 0x02, 0x24, 0xD0, 0xFF, 0xBD, 0x27, 0x2C, 0x00, 0xBF, 0xAF, -0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF, -0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x08, 0x00, 0x83, 0x8C, -0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, -0x08, 0x00, 0x90, 0x94, 0x02, 0x80, 0x02, 0x3C, 0x21, 0x90, 0x80, 0x00, -0x25, 0x80, 0x02, 0x02, 0xFF, 0x00, 0xB4, 0x30, 0x21, 0x20, 0x00, 0x02, -0xFF, 0x00, 0xD1, 0x30, 0x21, 0x28, 0x00, 0x00, 0x08, 0x00, 0x06, 0x24, -0xEC, 0x54, 0x00, 0x0C, 0xFF, 0x00, 0xF3, 0x30, 0x04, 0x00, 0x06, 0x8E, -0x08, 0x00, 0x05, 0x8E, 0xFF, 0xDF, 0x02, 0x3C, 0xFF, 0xE0, 0x03, 0x24, -0xFF, 0xFF, 0x42, 0x34, 0x24, 0x30, 0xC3, 0x00, 0x24, 0x28, 0xA2, 0x00, -0x3F, 0xFF, 0x02, 0x3C, 0x10, 0x00, 0x08, 0x8E, 0xFF, 0xFF, 0x42, 0x34, -0x00, 0x12, 0xC6, 0x34, 0x00, 0x40, 0x03, 0x3C, 0x24, 0x30, 0xC2, 0x00, -0x05, 0x00, 0x07, 0x24, 0x04, 0x00, 0x02, 0x24, 0x0B, 0x38, 0x54, 0x00, -0x25, 0x28, 0xA3, 0x00, 0x01, 0x00, 0x84, 0x32, 0x7F, 0xFF, 0x03, 0x24, -0x00, 0x80, 0x02, 0x3C, 0x14, 0x00, 0x09, 0x8E, 0x24, 0x28, 0xA3, 0x00, -0xC0, 0x21, 0x04, 0x00, 0x25, 0x40, 0x02, 0x01, 0x03, 0x00, 0x31, 0x32, -0xFF, 0xE0, 0x02, 0x3C, 0x80, 0x8D, 0x11, 0x00, 0x25, 0x28, 0xA4, 0x00, -0xFF, 0xFF, 0x42, 0x34, 0x0C, 0x00, 0x4A, 0x8E, 0x25, 0x30, 0xD1, 0x00, -0xFF, 0x81, 0x03, 0x24, 0xE0, 0xFF, 0x04, 0x24, 0x24, 0x28, 0xA2, 0x00, -0x3F, 0x00, 0x73, 0x32, 0xFB, 0xFF, 0x02, 0x3C, 0x24, 0x48, 0x23, 0x01, -0x24, 0x30, 0xC4, 0x00, 0x00, 0x1E, 0x07, 0x00, 0x40, 0x9A, 0x13, 0x00, -0xFF, 0xFF, 0x42, 0x34, 0x24, 0x40, 0x02, 0x01, 0x25, 0x48, 0x33, 0x01, -0x25, 0x28, 0xA3, 0x00, 0x25, 0x30, 0xC7, 0x00, 0x20, 0x00, 0x02, 0x24, -0x08, 0x00, 0x05, 0xAE, 0x00, 0x00, 0x0A, 0xA6, 0x02, 0x00, 0x02, 0xA2, -0x10, 0x00, 0x08, 0xAE, 0x14, 0x00, 0x09, 0xAE, 0x04, 0x00, 0x06, 0xAE, -0x8A, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x02, 0x80, 0x02, 0x3C, -0x98, 0x54, 0x42, 0x24, 0x04, 0x00, 0x43, 0x8C, 0x00, 0x00, 0x42, 0xAE, -0x04, 0x00, 0x52, 0xAC, 0x00, 0x00, 0x72, 0xAC, 0x04, 0x00, 0x43, 0xAE, -0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x2C, 0x00, 0xBF, 0x8F, -0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, -0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x30, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF, -0xFF, 0xFF, 0x90, 0x30, 0x10, 0x00, 0xA4, 0x27, 0x20, 0x00, 0xB2, 0xAF, -0x1C, 0x00, 0xB1, 0xAF, 0x24, 0x00, 0xBF, 0xAF, 0xFF, 0x00, 0xB1, 0x30, -0x8A, 0x40, 0x00, 0x0C, 0xFF, 0x00, 0xD2, 0x30, 0x00, 0x80, 0x02, 0x34, -0x20, 0x00, 0x02, 0x12, 0x21, 0x20, 0x20, 0x02, 0x75, 0x0D, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x03, 0x3C, 0x03, 0x02, 0x63, 0x34, -0x00, 0x00, 0x62, 0x90, 0x00, 0x08, 0x04, 0x24, 0x01, 0x00, 0x05, 0x24, -0x04, 0x00, 0x42, 0x34, 0x00, 0x00, 0x62, 0xA0, 0x35, 0x45, 0x00, 0x0C, -0x21, 0x30, 0x00, 0x00, 0x00, 0x09, 0x04, 0x24, 0x01, 0x00, 0x05, 0x24, -0x35, 0x45, 0x00, 0x0C, 0x21, 0x30, 0x00, 0x00, 0x84, 0x08, 0x04, 0x24, -0xFF, 0xFF, 0x05, 0x24, 0x35, 0x45, 0x00, 0x0C, 0x58, 0x00, 0x06, 0x24, -0x18, 0x00, 0x04, 0x24, 0x00, 0x0C, 0x05, 0x24, 0x83, 0x45, 0x00, 0x0C, -0x01, 0x00, 0x06, 0x24, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, -0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, -0x01, 0x00, 0x02, 0x24, 0x02, 0x00, 0x42, 0x12, 0x02, 0x00, 0x24, 0x26, -0xFE, 0xFF, 0x24, 0x26, 0x75, 0x0D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x25, 0xB0, 0x07, 0x3C, 0x03, 0x02, 0xE7, 0x34, 0x00, 0x00, 0xE3, 0x90, -0xFB, 0xFF, 0x02, 0x24, 0x00, 0x08, 0x04, 0x24, 0x24, 0x18, 0x62, 0x00, -0x00, 0x00, 0xE3, 0xA0, 0x01, 0x00, 0x05, 0x24, 0x35, 0x45, 0x00, 0x0C, -0x01, 0x00, 0x06, 0x24, 0x03, 0x00, 0x50, 0x32, 0x00, 0x09, 0x04, 0x24, -0x01, 0x00, 0x05, 0x24, 0x35, 0x45, 0x00, 0x0C, 0x01, 0x00, 0x06, 0x24, -0x42, 0x30, 0x10, 0x00, 0x00, 0x0A, 0x04, 0x24, 0x35, 0x45, 0x00, 0x0C, -0x10, 0x00, 0x05, 0x24, 0x21, 0x30, 0x00, 0x02, 0x00, 0x0D, 0x04, 0x24, -0x35, 0x45, 0x00, 0x0C, 0x00, 0x0C, 0x05, 0x24, 0x84, 0x08, 0x04, 0x24, -0xFF, 0xFF, 0x05, 0x24, 0x35, 0x45, 0x00, 0x0C, 0x18, 0x00, 0x06, 0x24, -0x18, 0x00, 0x04, 0x24, 0x00, 0x0C, 0x05, 0x24, 0x83, 0x45, 0x00, 0x0C, -0x21, 0x30, 0x00, 0x00, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, -0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, -0xD0, 0xFF, 0xBD, 0x27, 0x24, 0x00, 0xB3, 0xAF, 0x02, 0x80, 0x13, 0x3C, -0x20, 0x00, 0xB2, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x60, 0x1B, 0x72, 0x26, -0xFF, 0xFF, 0x90, 0x30, 0x10, 0x00, 0xA4, 0x27, 0x1C, 0x00, 0xB1, 0xAF, -0x28, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C, 0xFF, 0x00, 0xB1, 0x30, -0xB0, 0x1B, 0x42, 0x96, 0x10, 0x00, 0xA4, 0x27, 0x00, 0x80, 0x42, 0x30, -0x11, 0x00, 0x50, 0x10, 0x21, 0x30, 0x20, 0x02, 0xC4, 0x3D, 0x45, 0x92, -0x3C, 0x0E, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x02, 0x00, 0x80, 0x02, 0x34, -0x14, 0x00, 0x02, 0x12, 0x00, 0x80, 0x02, 0x24, 0xB0, 0x1B, 0x42, 0x96, -0x3B, 0x41, 0x51, 0xA2, 0xFF, 0x7F, 0x42, 0x30, 0xB0, 0x1B, 0x42, 0xA6, -0x60, 0x1B, 0x62, 0x26, 0xB0, 0x1B, 0x45, 0x94, 0xC4, 0x3D, 0x44, 0x90, -0x38, 0x0D, 0x00, 0x0C, 0x00, 0x10, 0xA5, 0x30, 0x10, 0x00, 0xA4, 0x27, -0x90, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0xBF, 0x8F, -0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, -0xB0, 0x1B, 0x43, 0x96, 0x3B, 0x41, 0x51, 0xA2, 0x25, 0x18, 0x62, 0x00, -0xB0, 0x0E, 0x00, 0x08, 0xB0, 0x1B, 0x43, 0xA6, 0xE0, 0xFF, 0xBD, 0x27, -0x10, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0x80, 0x00, 0x14, 0x00, 0xB1, 0xAF, -0x18, 0x00, 0xBF, 0xAF, 0x53, 0x21, 0x00, 0x0C, 0x28, 0x00, 0x04, 0x24, -0x02, 0x80, 0x04, 0x3C, 0x21, 0x88, 0x40, 0x00, 0x21, 0x28, 0x00, 0x02, -0x06, 0x00, 0x06, 0x24, 0x15, 0x00, 0x40, 0x10, 0xAC, 0xE8, 0x84, 0x24, -0x08, 0x00, 0x44, 0x94, 0x08, 0x00, 0x02, 0x24, 0x0C, 0x00, 0x22, 0xAE, -0x02, 0x80, 0x02, 0x3C, 0x0C, 0x00, 0x03, 0x24, 0x25, 0x20, 0x82, 0x00, -0x14, 0x00, 0x23, 0xAE, 0xF4, 0x54, 0x00, 0x0C, 0x20, 0x00, 0x84, 0x24, -0x17, 0x0A, 0x00, 0x0C, 0x21, 0x20, 0x20, 0x02, 0x02, 0x80, 0x04, 0x3C, -0x13, 0x58, 0x00, 0x0C, 0x04, 0xE9, 0x84, 0x24, 0x21, 0x10, 0x00, 0x00, -0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x05, 0x3C, -0x13, 0x58, 0x00, 0x0C, 0xEC, 0xE8, 0xA5, 0x24, 0xE0, 0x0E, 0x00, 0x08, -0xFF, 0xFF, 0x02, 0x24, 0xD8, 0xFF, 0xBD, 0x27, 0x1C, 0x00, 0xB3, 0xAF, -0x21, 0x98, 0x80, 0x00, 0x2C, 0x00, 0x04, 0x24, 0x18, 0x00, 0xB2, 0xAF, -0x14, 0x00, 0xB1, 0xAF, 0x21, 0x90, 0xA0, 0x00, 0x20, 0x00, 0xBF, 0xAF, -0x53, 0x21, 0x00, 0x0C, 0x10, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x04, 0x3C, -0x02, 0x80, 0x05, 0x3C, 0x21, 0x88, 0x40, 0x00, 0x28, 0xE9, 0x84, 0x24, -0x21, 0x30, 0x40, 0x02, 0x19, 0x00, 0x40, 0x10, 0x10, 0xE9, 0xA5, 0x24, -0x05, 0x00, 0x65, 0x92, 0x13, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0x30, 0x96, 0x02, 0x80, 0x02, 0x3C, 0x0B, 0x00, 0x03, 0x24, -0x25, 0x80, 0x02, 0x02, 0x20, 0x00, 0x10, 0x26, 0x0C, 0x00, 0x02, 0x24, -0x21, 0x20, 0x00, 0x02, 0x0C, 0x00, 0x22, 0xAE, 0x14, 0x00, 0x23, 0xAE, -0x21, 0x28, 0x60, 0x02, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, -0x08, 0x00, 0x12, 0xAE, 0x21, 0x20, 0x20, 0x02, 0x20, 0x00, 0xBF, 0x8F, -0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x17, 0x0A, 0x00, 0x08, 0x28, 0x00, 0xBD, 0x27, -0x02, 0x80, 0x04, 0x3C, 0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, -0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0xAC, 0xE8, 0x84, 0x24, 0x13, 0x58, 0x00, 0x08, 0x28, 0x00, 0xBD, 0x27, -0xE0, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xBF, 0xAF, -0x10, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x02, 0x3C, 0xEE, 0x5D, 0x43, 0x90, -0x02, 0x80, 0x11, 0x3C, 0x04, 0x00, 0x04, 0x24, 0x0F, 0x00, 0x63, 0x30, -0x04, 0x00, 0x63, 0x28, 0x3A, 0x00, 0x60, 0x14, 0x01, 0x00, 0x05, 0x24, -0x40, 0xDF, 0x23, 0x8E, 0x0F, 0x00, 0x05, 0x3C, 0x02, 0x80, 0x02, 0x3C, -0xFF, 0xFF, 0xA5, 0x34, 0x24, 0x00, 0x04, 0x24, 0x60, 0x00, 0x06, 0x24, -0x12, 0x00, 0x60, 0x14, 0x60, 0x1B, 0x50, 0x24, 0x83, 0x45, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0x05, 0x92, 0xD0, 0x07, 0x02, 0x24, -0x01, 0x00, 0x03, 0x24, 0x0A, 0x10, 0x05, 0x00, 0x3C, 0x3A, 0x02, 0xAE, -0x02, 0x80, 0x02, 0x3C, 0xED, 0x5D, 0x44, 0x90, 0x40, 0xDF, 0x23, 0xAE, -0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x01, 0x00, 0x05, 0x24, 0xFF, 0x00, 0x84, 0x30, 0x4B, 0x2E, 0x00, 0x08, -0x20, 0x00, 0xBD, 0x27, 0x0F, 0x00, 0x05, 0x3C, 0xFF, 0xFF, 0xA5, 0x34, -0xAC, 0x45, 0x00, 0x0C, 0x24, 0x00, 0x04, 0x24, 0x49, 0x41, 0x04, 0x92, -0xFF, 0x00, 0x43, 0x30, 0x00, 0x2C, 0x03, 0x00, 0x0A, 0x00, 0x64, 0x10, -0x4A, 0x41, 0x02, 0xA2, 0x02, 0x80, 0x02, 0x3C, 0x49, 0xF5, 0x44, 0x90, -0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x04, 0x00, 0x12, 0x27, 0x00, 0x74, -0x25, 0x20, 0xA4, 0x00, 0x4A, 0x41, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, -0x49, 0x41, 0x03, 0xA2, 0x48, 0x41, 0x03, 0x92, 0x10, 0x27, 0x02, 0x24, -0x40, 0xDF, 0x20, 0xAE, 0x0A, 0x10, 0x03, 0x00, 0x3C, 0x3A, 0x02, 0xAE, -0x02, 0x80, 0x02, 0x3C, 0xED, 0x5D, 0x44, 0x90, 0x18, 0x00, 0xBF, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x01, 0x00, 0x05, 0x24, -0xFF, 0x00, 0x84, 0x30, 0x4B, 0x2E, 0x00, 0x08, 0x20, 0x00, 0xBD, 0x27, -0x4B, 0x2E, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x0F, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0xC8, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB2, 0xAF, -0x10, 0x00, 0xB0, 0xAF, 0x34, 0x00, 0xBF, 0xAF, 0x30, 0x00, 0xBE, 0xAF, -0x2C, 0x00, 0xB7, 0xAF, 0x28, 0x00, 0xB6, 0xAF, 0x24, 0x00, 0xB5, 0xAF, -0x20, 0x00, 0xB4, 0xAF, 0x1C, 0x00, 0xB3, 0xAF, 0x14, 0x00, 0xB1, 0xAF, -0x21, 0x80, 0x80, 0x00, 0x45, 0x00, 0xA0, 0x14, 0x21, 0x90, 0x00, 0x00, -0x08, 0x00, 0x82, 0x90, 0x02, 0x80, 0x13, 0x3C, 0x60, 0x1B, 0x63, 0x26, -0x0F, 0x00, 0x42, 0x30, 0xC0, 0x40, 0x62, 0xAC, 0x25, 0xB0, 0x02, 0x3C, -0x0A, 0x00, 0x10, 0x26, 0xD0, 0x01, 0x57, 0x34, 0x02, 0x80, 0x14, 0x3C, -0xD8, 0x01, 0x5E, 0x34, 0xDC, 0x01, 0x55, 0x34, 0xD4, 0x01, 0x56, 0x34, -0x03, 0x00, 0x11, 0x24, 0x00, 0x00, 0x06, 0x92, 0x60, 0x1B, 0x62, 0x26, -0xB8, 0x40, 0x47, 0x90, 0x0F, 0x00, 0xC3, 0x30, 0x01, 0x00, 0x05, 0x92, -0x18, 0x00, 0x67, 0x00, 0x03, 0x00, 0x04, 0x92, 0x02, 0x00, 0x02, 0x92, -0x0F, 0x00, 0xA7, 0x30, 0x00, 0x3A, 0x07, 0x00, 0x02, 0x29, 0x05, 0x00, -0x00, 0x22, 0x04, 0x00, 0x25, 0x20, 0x82, 0x00, 0x00, 0x2B, 0x05, 0x00, -0x42, 0x11, 0x06, 0x00, 0x00, 0x24, 0x04, 0x00, 0x03, 0x00, 0x49, 0x30, -0x02, 0x31, 0x06, 0x00, 0x01, 0x00, 0x02, 0x24, 0x01, 0x00, 0xC6, 0x30, -0x12, 0x18, 0x00, 0x00, 0x0A, 0x00, 0x63, 0x24, 0xFF, 0x00, 0x63, 0x30, -0x25, 0x18, 0x67, 0x00, 0x25, 0x18, 0x65, 0x00, 0x30, 0x00, 0x22, 0x11, -0x25, 0x38, 0x64, 0x00, 0x02, 0x00, 0x22, 0x29, 0x3E, 0x00, 0x40, 0x14, -0x02, 0x00, 0x02, 0x24, 0x38, 0x00, 0x22, 0x11, 0x03, 0x00, 0x02, 0x24, -0x40, 0x00, 0x22, 0x11, 0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0x20, 0x01, -0x64, 0xE9, 0x84, 0x26, 0x13, 0x58, 0x00, 0x0C, 0xFF, 0xFF, 0x31, 0x26, -0xD9, 0xFF, 0x21, 0x06, 0x04, 0x00, 0x10, 0x26, 0x25, 0xB0, 0x02, 0x3C, -0xE7, 0x01, 0x42, 0x34, 0x00, 0x00, 0x52, 0xA0, 0x34, 0x00, 0xBF, 0x8F, -0x30, 0x00, 0xBE, 0x8F, 0x2C, 0x00, 0xB7, 0x8F, 0x28, 0x00, 0xB6, 0x8F, -0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, -0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x38, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x13, 0x3C, -0x08, 0x00, 0x83, 0x90, 0x60, 0x1B, 0x62, 0x26, 0xC0, 0x40, 0x44, 0x8C, -0x0F, 0x00, 0x63, 0x30, 0xBB, 0xFF, 0x83, 0x14, 0x00, 0x00, 0x00, 0x00, -0x34, 0x00, 0xBF, 0x8F, 0x30, 0x00, 0xBE, 0x8F, 0x2C, 0x00, 0xB7, 0x8F, -0x28, 0x00, 0xB6, 0x8F, 0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F, -0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x38, 0x00, 0xBD, 0x27, -0x00, 0x00, 0xA7, 0xAE, 0x21, 0x20, 0x00, 0x00, 0x25, 0xB0, 0x08, 0x3C, -0x07, 0x10, 0x92, 0x00, 0x01, 0x00, 0x42, 0x30, 0x01, 0x00, 0x84, 0x24, -0x02, 0x00, 0x40, 0x10, 0x03, 0x00, 0x85, 0x2C, 0xD0, 0x01, 0x07, 0xAD, -0xF9, 0xFF, 0xA0, 0x14, 0x04, 0x00, 0x08, 0x25, 0xA3, 0x0F, 0x00, 0x08, -0x21, 0x28, 0x20, 0x01, 0x0D, 0x00, 0xC0, 0x10, 0x00, 0x00, 0x00, 0x00, -0xA2, 0x0F, 0x00, 0x08, 0x02, 0x00, 0x52, 0x36, 0xC7, 0xFF, 0x20, 0x15, -0x21, 0x28, 0x20, 0x01, 0x0D, 0x00, 0xC0, 0x10, 0x00, 0x00, 0x00, 0x00, -0xA3, 0x0F, 0x00, 0x08, 0x04, 0x00, 0x52, 0x36, 0x06, 0x00, 0xC0, 0x10, -0x00, 0x00, 0x00, 0x00, 0xA2, 0x0F, 0x00, 0x08, 0x01, 0x00, 0x52, 0x36, -0x00, 0x00, 0xC7, 0xAE, 0xA3, 0x0F, 0x00, 0x08, 0x21, 0x28, 0x20, 0x01, -0x00, 0x00, 0xE7, 0xAE, 0xA3, 0x0F, 0x00, 0x08, 0x21, 0x28, 0x20, 0x01, -0x00, 0x00, 0xC7, 0xAF, 0xA3, 0x0F, 0x00, 0x08, 0x21, 0x28, 0x20, 0x01, -0xB8, 0xFF, 0xBD, 0x27, 0x24, 0x00, 0xB1, 0xAF, 0x21, 0x88, 0x80, 0x00, -0x00, 0x01, 0x04, 0x24, 0x2C, 0x00, 0xB3, 0xAF, 0x44, 0x00, 0xBF, 0xAF, -0x40, 0x00, 0xBE, 0xAF, 0x3C, 0x00, 0xB7, 0xAF, 0x38, 0x00, 0xB6, 0xAF, -0x34, 0x00, 0xB5, 0xAF, 0x30, 0x00, 0xB4, 0xAF, 0x28, 0x00, 0xB2, 0xAF, -0x53, 0x21, 0x00, 0x0C, 0x20, 0x00, 0xB0, 0xAF, 0xAC, 0x00, 0x40, 0x10, -0x21, 0x98, 0x40, 0x00, 0x08, 0x00, 0x50, 0x94, 0x02, 0x80, 0x02, 0x3C, -0x21, 0x28, 0x20, 0x02, 0x25, 0x80, 0x02, 0x02, 0x24, 0x00, 0x04, 0x26, -0x20, 0x00, 0x00, 0xA6, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, -0x02, 0x80, 0x05, 0x3C, 0x2A, 0x00, 0x04, 0x26, 0x48, 0x37, 0xA5, 0x24, -0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x05, 0x3C, -0xB4, 0x55, 0xA5, 0x24, 0x06, 0x00, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C, -0x30, 0x00, 0x04, 0x26, 0x20, 0x00, 0x03, 0x96, 0x02, 0x80, 0x02, 0x3C, -0x60, 0x1B, 0x54, 0x24, 0x03, 0xFF, 0x63, 0x30, 0x50, 0x00, 0x63, 0x34, -0x20, 0x00, 0x03, 0xA6, 0xE4, 0x1D, 0x82, 0x96, 0x02, 0x80, 0x03, 0x3C, -0xB0, 0x55, 0x63, 0x24, 0x74, 0x00, 0x72, 0x24, 0xFF, 0x0F, 0x43, 0x30, -0x00, 0x19, 0x03, 0x00, 0x01, 0x00, 0x42, 0x24, 0x02, 0x22, 0x03, 0x00, -0xE4, 0x1D, 0x82, 0xA6, 0x20, 0x00, 0x11, 0x26, 0x20, 0x00, 0x02, 0x24, -0x16, 0x00, 0x23, 0xA2, 0x17, 0x00, 0x24, 0xA2, 0x21, 0x20, 0x40, 0x02, -0xFB, 0x51, 0x00, 0x0C, 0x0C, 0x00, 0x62, 0xAE, 0x40, 0x00, 0x11, 0x26, -0x21, 0x20, 0x20, 0x02, 0x21, 0x28, 0x40, 0x00, 0xF4, 0x54, 0x00, 0x0C, -0x02, 0x00, 0x06, 0x24, 0x0C, 0x00, 0x63, 0x8E, 0x21, 0x20, 0x40, 0x02, -0x42, 0x00, 0x11, 0x26, 0x02, 0x00, 0x63, 0x24, 0x16, 0x52, 0x00, 0x0C, -0x0C, 0x00, 0x63, 0xAE, 0x21, 0x28, 0x40, 0x00, 0x21, 0x20, 0x20, 0x02, -0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x06, 0x24, 0x0C, 0x00, 0x63, 0x8E, -0x02, 0x80, 0x02, 0x3C, 0xB0, 0x55, 0x42, 0x24, 0x02, 0x00, 0x63, 0x24, -0x0C, 0x00, 0x63, 0xAE, 0x0C, 0x00, 0x46, 0x8C, 0x44, 0x00, 0x04, 0x26, -0x0C, 0x00, 0x76, 0x26, 0x60, 0x00, 0x50, 0x24, 0x21, 0x28, 0x00, 0x00, -0x10, 0x00, 0x47, 0x24, 0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB6, 0xAF, -0x21, 0x20, 0x00, 0x02, 0x1B, 0x53, 0x00, 0x0C, 0x21, 0x88, 0x40, 0x00, -0x09, 0x00, 0x43, 0x2C, 0x08, 0x00, 0x06, 0x24, 0x21, 0x20, 0x20, 0x02, -0x0B, 0x30, 0x43, 0x00, 0x21, 0x38, 0x00, 0x02, 0x01, 0x00, 0x05, 0x24, -0x18, 0x00, 0xA3, 0xAF, 0x21, 0xB8, 0x40, 0x00, 0x25, 0x52, 0x00, 0x0C, -0x10, 0x00, 0xB6, 0xAF, 0x21, 0x20, 0x40, 0x00, 0x02, 0x80, 0x02, 0x3C, -0xB0, 0x55, 0x42, 0x24, 0x03, 0x00, 0x05, 0x24, 0x01, 0x00, 0x06, 0x24, -0x48, 0x00, 0x47, 0x24, 0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB6, 0xAF, -0x21, 0x88, 0x40, 0x00, 0xC0, 0x3A, 0x82, 0x8E, 0x0C, 0x00, 0x10, 0x24, -0x2B, 0x10, 0x02, 0x02, 0x3A, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C, -0x26, 0x56, 0x5E, 0x24, 0x68, 0x10, 0x00, 0x08, 0x21, 0xA8, 0x80, 0x02, -0x21, 0x10, 0x12, 0x02, 0x01, 0x00, 0x43, 0x90, 0xC0, 0x3A, 0xA4, 0x8E, -0x21, 0x18, 0x70, 0x00, 0x02, 0x00, 0x70, 0x24, 0x2B, 0x20, 0x04, 0x02, -0x2F, 0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x12, 0x02, -0x00, 0x00, 0x47, 0x90, 0x02, 0x80, 0x14, 0x3C, 0x2D, 0x00, 0x03, 0x24, -0x21, 0x28, 0x1E, 0x02, 0x64, 0x5C, 0x84, 0x26, 0xF1, 0xFF, 0xE3, 0x14, -0x20, 0x00, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x04, 0x41, 0xA3, 0x96, 0x02, 0x80, 0x02, 0x3C, 0xC6, 0x5C, 0x47, 0x90, -0xBD, 0xFF, 0x63, 0x30, 0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x02, 0x3C, -0x0C, 0x00, 0x63, 0x34, 0x01, 0x00, 0xE7, 0x30, 0x44, 0xDF, 0xA5, 0x24, -0x67, 0x5C, 0x44, 0x24, 0x10, 0x00, 0x06, 0x24, 0x06, 0x00, 0xE0, 0x14, -0x04, 0x41, 0xA3, 0xA6, 0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x03, 0x3C, -0x54, 0xDF, 0xA5, 0x24, 0x67, 0x5C, 0x64, 0x24, 0x10, 0x00, 0x06, 0x24, -0xF4, 0x54, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x12, 0x02, -0x01, 0x00, 0x46, 0x90, 0x21, 0x20, 0x20, 0x02, 0x64, 0x5C, 0x87, 0x26, -0x2D, 0x00, 0x05, 0x24, 0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB6, 0xAF, -0x21, 0x88, 0x40, 0x00, 0x21, 0x10, 0x12, 0x02, 0x01, 0x00, 0x43, 0x90, -0xC0, 0x3A, 0xA4, 0x8E, 0x21, 0x18, 0x70, 0x00, 0x02, 0x00, 0x70, 0x24, -0x2B, 0x20, 0x04, 0x02, 0xD4, 0xFF, 0x80, 0x14, 0x21, 0x10, 0x12, 0x02, -0x18, 0x00, 0xA2, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x40, 0x10, -0x21, 0x20, 0x60, 0x02, 0x44, 0x00, 0xBF, 0x8F, 0x40, 0x00, 0xBE, 0x8F, -0x3C, 0x00, 0xB7, 0x8F, 0x38, 0x00, 0xB6, 0x8F, 0x34, 0x00, 0xB5, 0x8F, -0x30, 0x00, 0xB4, 0x8F, 0x2C, 0x00, 0xB3, 0x8F, 0x28, 0x00, 0xB2, 0x8F, -0x24, 0x00, 0xB1, 0x8F, 0x20, 0x00, 0xB0, 0x8F, 0x01, 0x00, 0x05, 0x24, -0x21, 0x30, 0x00, 0x00, 0x21, 0x38, 0x00, 0x00, 0xDF, 0x0D, 0x00, 0x08, -0x48, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, -0x44, 0x00, 0xBF, 0x8F, 0x40, 0x00, 0xBE, 0x8F, 0x3C, 0x00, 0xB7, 0x8F, -0x38, 0x00, 0xB6, 0x8F, 0x34, 0x00, 0xB5, 0x8F, 0x30, 0x00, 0xB4, 0x8F, -0x2C, 0x00, 0xB3, 0x8F, 0x28, 0x00, 0xB2, 0x8F, 0x24, 0x00, 0xB1, 0x8F, -0x20, 0x00, 0xB0, 0x8F, 0x58, 0xE9, 0x84, 0x24, 0xAC, 0xE9, 0xA5, 0x24, -0x13, 0x58, 0x00, 0x08, 0x48, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x03, 0x3C, -0xB0, 0x55, 0x63, 0x24, 0x21, 0x20, 0x20, 0x02, 0xF8, 0xFF, 0xE6, 0x26, -0x68, 0x00, 0x67, 0x24, 0x32, 0x00, 0x05, 0x24, 0x25, 0x52, 0x00, 0x0C, -0x10, 0x00, 0xB6, 0xAF, 0x21, 0x20, 0x60, 0x02, 0x44, 0x00, 0xBF, 0x8F, -0x40, 0x00, 0xBE, 0x8F, 0x3C, 0x00, 0xB7, 0x8F, 0x38, 0x00, 0xB6, 0x8F, -0x34, 0x00, 0xB5, 0x8F, 0x30, 0x00, 0xB4, 0x8F, 0x2C, 0x00, 0xB3, 0x8F, -0x28, 0x00, 0xB2, 0x8F, 0x24, 0x00, 0xB1, 0x8F, 0x20, 0x00, 0xB0, 0x8F, -0x01, 0x00, 0x05, 0x24, 0x21, 0x30, 0x00, 0x00, 0x21, 0x38, 0x00, 0x00, -0xDF, 0x0D, 0x00, 0x08, 0x48, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27, -0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x20, 0x00, 0xBF, 0xAF, -0x02, 0x00, 0x82, 0x90, 0x02, 0x80, 0x03, 0x3C, 0x10, 0x37, 0x65, 0x94, -0x0F, 0x00, 0x42, 0x30, 0x00, 0x00, 0x83, 0x8C, 0xC0, 0x10, 0x02, 0x00, -0x21, 0x20, 0x44, 0x00, 0x00, 0x10, 0xA8, 0x30, 0x02, 0x80, 0x02, 0x3C, -0x00, 0x08, 0xA5, 0x30, 0xB0, 0x55, 0x51, 0x24, 0xFF, 0x3F, 0x63, 0x30, -0x06, 0x00, 0xA0, 0x10, 0x18, 0x00, 0x90, 0x24, 0xE8, 0xFF, 0x67, 0x24, -0x30, 0x00, 0x84, 0x24, 0x21, 0x28, 0x00, 0x00, 0x07, 0x00, 0x00, 0x11, -0x10, 0x00, 0xA6, 0x27, 0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x28, 0x00, 0xBD, 0x27, 0xAB, 0x1A, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0xF7, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x44, 0x24, -0x10, 0x00, 0xA2, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x10, -0x10, 0x00, 0x25, 0x26, 0x0C, 0x00, 0x26, 0x8E, 0x1D, 0x55, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0xED, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x26, 0x53, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x02, 0xEE, 0x0F, 0x00, 0x0C, -0x21, 0x20, 0x40, 0x00, 0xE8, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0xA0, 0xFF, 0xBD, 0x27, 0x58, 0x00, 0xBE, 0xAF, 0x5C, 0x00, 0xBF, 0xAF, -0x54, 0x00, 0xB7, 0xAF, 0x50, 0x00, 0xB6, 0xAF, 0x4C, 0x00, 0xB5, 0xAF, -0x48, 0x00, 0xB4, 0xAF, 0x44, 0x00, 0xB3, 0xAF, 0x40, 0x00, 0xB2, 0xAF, -0x3C, 0x00, 0xB1, 0xAF, 0x38, 0x00, 0xB0, 0xAF, 0x00, 0x00, 0x82, 0x8C, -0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x46, 0x30, 0xE8, 0xFF, 0xC5, 0x24, -0x01, 0x03, 0xA2, 0x2C, 0x16, 0x00, 0x40, 0x14, 0x21, 0xF0, 0x80, 0x00, -0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x63, 0x24, 0x40, 0x3E, 0x62, 0x8C, -0x02, 0x80, 0x04, 0x3C, 0xD0, 0xE9, 0x84, 0x24, 0x01, 0x00, 0x42, 0x24, -0x40, 0x3E, 0x62, 0xAC, 0x13, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x5C, 0x00, 0xBF, 0x8F, 0x58, 0x00, 0xBE, 0x8F, 0x54, 0x00, 0xB7, 0x8F, -0x50, 0x00, 0xB6, 0x8F, 0x4C, 0x00, 0xB5, 0x8F, 0x48, 0x00, 0xB4, 0x8F, -0x44, 0x00, 0xB3, 0x8F, 0x40, 0x00, 0xB2, 0x8F, 0x3C, 0x00, 0xB1, 0x8F, -0x38, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x60, 0x00, 0xBD, 0x27, -0x7C, 0x00, 0xC4, 0x24, 0x5C, 0x00, 0xC6, 0x24, 0x53, 0x21, 0x00, 0x0C, -0x24, 0x00, 0xA6, 0xAF, 0x74, 0x00, 0x40, 0x10, 0x20, 0x00, 0xA2, 0xAF, -0x20, 0x00, 0xA3, 0x8F, 0x24, 0x00, 0xA6, 0x8F, 0x21, 0x28, 0x00, 0x00, -0x08, 0x00, 0x62, 0x94, 0x02, 0x80, 0x03, 0x3C, 0x25, 0x10, 0x43, 0x00, -0x20, 0x00, 0x57, 0x24, 0xE3, 0x54, 0x00, 0x0C, 0x21, 0x20, 0xE0, 0x02, -0x02, 0x80, 0x03, 0x3C, 0xE8, 0xE9, 0x62, 0x24, 0xE8, 0xE9, 0x67, 0x90, -0x01, 0x00, 0x44, 0x90, 0x02, 0x00, 0xC3, 0x93, 0x02, 0x00, 0x45, 0x90, -0x03, 0x00, 0x46, 0x90, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x50, 0x24, -0x00, 0x00, 0xC2, 0x8F, 0x00, 0x22, 0x04, 0x00, 0x0F, 0x00, 0x63, 0x30, -0x25, 0x20, 0x87, 0x00, 0x00, 0x2C, 0x05, 0x00, 0xC0, 0x18, 0x03, 0x00, -0x4B, 0x41, 0x07, 0x92, 0x21, 0x18, 0x7E, 0x00, 0x25, 0x28, 0xA4, 0x00, -0xFF, 0x3F, 0x42, 0x30, 0x00, 0x36, 0x06, 0x00, 0x25, 0x30, 0xC5, 0x00, -0x30, 0x00, 0xA2, 0xAF, 0x22, 0x00, 0x64, 0x24, 0x18, 0x00, 0x62, 0x24, -0x10, 0x00, 0xA6, 0xAF, 0x2C, 0x00, 0xA4, 0xAF, 0x28, 0x00, 0xA2, 0xAF, -0x53, 0x00, 0xE0, 0x14, 0x28, 0x00, 0x76, 0x24, 0x02, 0x80, 0x02, 0x3C, -0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x54, 0x24, 0xA5, 0x59, 0x73, 0x24, -0x21, 0x90, 0x00, 0x00, 0x01, 0x00, 0x15, 0x24, 0x64, 0x11, 0x00, 0x08, -0x21, 0x80, 0x00, 0x00, 0x1D, 0x55, 0x00, 0x0C, 0x01, 0x00, 0x52, 0x26, -0x07, 0x00, 0x10, 0x26, 0x32, 0x00, 0x40, 0x10, 0x40, 0x00, 0x43, 0x2A, -0x0C, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x88, 0x14, 0x02, -0x44, 0x3E, 0x22, 0x92, 0x21, 0x20, 0x13, 0x02, 0x21, 0x28, 0xC0, 0x02, -0xF4, 0xFF, 0x55, 0x10, 0x06, 0x00, 0x06, 0x24, 0x21, 0x20, 0x13, 0x02, -0x21, 0x28, 0xC0, 0x02, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, -0x44, 0x3E, 0x35, 0xA2, 0x30, 0x00, 0xA4, 0x8F, 0x74, 0x00, 0xF4, 0x26, -0x80, 0x00, 0xF3, 0x26, 0x5C, 0x00, 0x83, 0x24, 0xE8, 0xFF, 0x82, 0x24, -0x1C, 0x00, 0xA2, 0xAF, 0x00, 0x00, 0xE3, 0xAE, 0x28, 0x00, 0xA3, 0x8F, -0x1C, 0x00, 0xA2, 0x8F, 0x21, 0x20, 0x80, 0x02, 0x18, 0x00, 0x65, 0x24, -0x21, 0x30, 0x40, 0x00, 0xF4, 0x54, 0x00, 0x0C, 0x70, 0x00, 0xE2, 0xAE, -0x70, 0x00, 0xE7, 0x8E, 0x21, 0x20, 0x60, 0x02, 0x21, 0x28, 0x00, 0x00, -0xF4, 0xFF, 0xE7, 0x24, 0xAB, 0x1A, 0x00, 0x0C, 0x1C, 0x00, 0xA6, 0x27, -0x0F, 0x00, 0x40, 0x10, 0x21, 0x80, 0x40, 0x00, 0x02, 0x80, 0x04, 0x3C, -0x60, 0x1B, 0x91, 0x24, 0x0C, 0x3E, 0x26, 0x8E, 0x00, 0x00, 0x00, 0x00, -0x32, 0x00, 0xC0, 0x18, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xA2, 0x8F, -0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0xC2, 0x10, 0x02, 0x80, 0x04, 0x3C, -0xC0, 0x10, 0x12, 0x00, 0x23, 0x10, 0x52, 0x00, 0x21, 0x10, 0x51, 0x00, -0x44, 0x3E, 0x40, 0xA0, 0x20, 0x00, 0xA4, 0x8F, 0x74, 0x21, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x5C, 0x00, 0xBF, 0x8F, 0x58, 0x00, 0xBE, 0x8F, -0x54, 0x00, 0xB7, 0x8F, 0x50, 0x00, 0xB6, 0x8F, 0x4C, 0x00, 0xB5, 0x8F, -0x48, 0x00, 0xB4, 0x8F, 0x44, 0x00, 0xB3, 0x8F, 0x40, 0x00, 0xB2, 0x8F, -0x3C, 0x00, 0xB1, 0x8F, 0x38, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x60, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, -0xAC, 0xE8, 0x84, 0x24, 0x1B, 0x11, 0x00, 0x08, 0xBC, 0xE9, 0xA5, 0x24, -0x02, 0x80, 0x04, 0x3C, 0xAC, 0x5C, 0x84, 0x24, 0x21, 0x28, 0xC0, 0x02, -0x1D, 0x55, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0xA8, 0xFF, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x8A, 0x40, 0x00, 0x0C, 0x18, 0x00, 0xA4, 0x27, -0x52, 0x41, 0x02, 0x92, 0x18, 0x00, 0xA4, 0x27, 0x01, 0x00, 0x42, 0x24, -0x90, 0x40, 0x00, 0x0C, 0x52, 0x41, 0x02, 0xA2, 0x56, 0x11, 0x00, 0x08, -0x02, 0x80, 0x02, 0x3C, 0x70, 0x59, 0x84, 0x24, 0x1D, 0x55, 0x00, 0x0C, -0x02, 0x00, 0x05, 0x26, 0xD5, 0xFF, 0x40, 0x14, 0xC0, 0x10, 0x12, 0x00, -0x01, 0x00, 0x06, 0x92, 0x00, 0x00, 0x00, 0x00, 0x69, 0x00, 0xC0, 0x14, -0x10, 0x00, 0xE4, 0x26, 0x0C, 0x00, 0xE0, 0xAE, 0x02, 0x00, 0xC2, 0x97, -0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x42, 0x30, 0x04, 0x00, 0x42, 0x28, -0x5E, 0x00, 0x40, 0x10, 0x21, 0x20, 0xC0, 0x03, 0x34, 0x00, 0xE0, 0xAE, -0x60, 0x00, 0xF1, 0x26, 0x21, 0x20, 0x20, 0x02, 0x21, 0x28, 0x00, 0x00, -0xE3, 0x54, 0x00, 0x0C, 0x10, 0x00, 0x06, 0x24, 0x70, 0x00, 0xE7, 0x8E, -0x21, 0x20, 0x60, 0x02, 0x01, 0x00, 0x05, 0x24, 0xF4, 0xFF, 0xE7, 0x24, -0xAB, 0x1A, 0x00, 0x0C, 0x1C, 0x00, 0xA6, 0x27, 0x06, 0x00, 0x40, 0x10, -0x21, 0x90, 0x00, 0x00, 0x1C, 0x00, 0xA6, 0x8F, 0x02, 0x00, 0x45, 0x24, -0xF4, 0x54, 0x00, 0x0C, 0x21, 0x20, 0x20, 0x02, 0x1C, 0x00, 0xB2, 0x8F, -0x70, 0x00, 0xE7, 0x8E, 0x21, 0x20, 0x60, 0x02, 0x32, 0x00, 0x05, 0x24, -0xF4, 0xFF, 0xE7, 0x24, 0xAB, 0x1A, 0x00, 0x0C, 0x1C, 0x00, 0xA6, 0x27, -0x05, 0x00, 0x40, 0x10, 0x21, 0x20, 0xF2, 0x02, 0x1C, 0x00, 0xA6, 0x8F, -0x60, 0x00, 0x84, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x45, 0x24, -0x1C, 0x00, 0xA5, 0x8F, 0x21, 0x20, 0x20, 0x02, 0x61, 0x53, 0x00, 0x0C, -0x21, 0x28, 0xB2, 0x00, 0x21, 0x18, 0x40, 0x00, 0x01, 0x00, 0x02, 0x24, -0x40, 0x00, 0x62, 0x10, 0x03, 0x00, 0x02, 0x24, 0x38, 0x00, 0xE2, 0xAE, -0x70, 0x00, 0xE7, 0x8E, 0x21, 0x20, 0x60, 0x02, 0x03, 0x00, 0x05, 0x24, -0xF4, 0xFF, 0xE7, 0x24, 0xAB, 0x1A, 0x00, 0x0C, 0x1C, 0x00, 0xA6, 0x27, -0x48, 0x00, 0xE0, 0xAE, 0x04, 0x00, 0x40, 0x10, 0x3C, 0x00, 0xE0, 0xAE, -0x02, 0x00, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0xE2, 0xAE, -0xFB, 0x51, 0x00, 0x0C, 0x21, 0x20, 0x80, 0x02, 0x21, 0x28, 0x40, 0x00, -0x40, 0x00, 0xE4, 0x26, 0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x06, 0x24, -0x18, 0x52, 0x00, 0x0C, 0x21, 0x20, 0xE0, 0x02, 0xFF, 0xFF, 0x50, 0x30, -0x01, 0x00, 0x02, 0x32, 0x1A, 0x00, 0x40, 0x10, 0x21, 0x28, 0xC0, 0x02, -0x01, 0x00, 0x02, 0x24, 0x5C, 0x00, 0xE2, 0xAE, 0x2C, 0x00, 0xA5, 0x8F, -0x04, 0x00, 0xE4, 0x26, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, -0x10, 0x00, 0x02, 0x32, 0x13, 0x00, 0x40, 0x10, 0x01, 0x00, 0x02, 0x24, -0x30, 0x00, 0xE2, 0xAE, 0x02, 0x80, 0x03, 0x3C, 0x44, 0x00, 0xE0, 0xAE, -0x60, 0x1B, 0x62, 0x24, 0x3C, 0x3E, 0x43, 0x8C, 0x20, 0x00, 0xA4, 0x8F, -0x01, 0x00, 0x63, 0x24, 0x3C, 0x3E, 0x43, 0xAC, 0x24, 0x00, 0xA3, 0x8F, -0x08, 0x00, 0x02, 0x24, 0x0C, 0x00, 0x83, 0xAC, 0x20, 0x00, 0xA3, 0x8F, -0x17, 0x0A, 0x00, 0x0C, 0x14, 0x00, 0x62, 0xAC, 0x1D, 0x11, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x0A, 0x12, 0x00, 0x08, 0x5C, 0x00, 0xE0, 0xAE, -0x11, 0x12, 0x00, 0x08, 0x30, 0x00, 0xE0, 0xAE, 0xE3, 0x17, 0x00, 0x0C, -0x18, 0x00, 0xC5, 0x27, 0xC8, 0x11, 0x00, 0x08, 0x34, 0x00, 0xE2, 0xAE, -0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x05, 0x26, 0x01, 0x00, 0x03, 0x92, -0xC1, 0x11, 0x00, 0x08, 0x0C, 0x00, 0xE3, 0xAE, 0xEF, 0x11, 0x00, 0x08, -0x38, 0x00, 0xE3, 0xAE, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x44, 0x24, -0xFC, 0x40, 0x83, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x60, 0x10, -0x01, 0x00, 0x05, 0x24, 0xB6, 0x40, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0x42, 0x2C, 0x07, 0x00, 0x40, 0x10, 0x21, 0x28, 0x00, 0x00, -0xC7, 0x3D, 0x83, 0x90, 0x01, 0x00, 0x02, 0x24, 0x03, 0x00, 0x62, 0x10, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, -0x01, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, -0x02, 0x80, 0x04, 0x3C, 0x60, 0x1B, 0x82, 0x24, 0x44, 0x41, 0x45, 0x8C, -0x40, 0x41, 0x46, 0x8C, 0x21, 0x20, 0x40, 0x00, 0x40, 0x18, 0x05, 0x00, -0x40, 0x10, 0x06, 0x00, 0x2B, 0x18, 0x66, 0x00, 0x2B, 0x38, 0x45, 0x00, -0x04, 0x00, 0x60, 0x14, 0x21, 0x28, 0x00, 0x00, 0x01, 0x00, 0x05, 0x24, -0x02, 0x00, 0x02, 0x24, 0x0A, 0x28, 0x47, 0x00, 0x21, 0x10, 0xA0, 0x00, -0x40, 0x41, 0x80, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0x44, 0x41, 0x80, 0xAC, -0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, 0x14, 0x00, 0xBF, 0xAF, -0x43, 0x12, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0x40, 0x00, -0x02, 0x80, 0x02, 0x3C, 0xCE, 0x5C, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, -0x12, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x2F, 0x12, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x24, 0x0D, 0x00, 0x43, 0x10, -0x02, 0x80, 0x02, 0x3C, 0x16, 0x5C, 0x44, 0x90, 0x02, 0x80, 0x02, 0x3C, -0xD4, 0xDD, 0x42, 0x24, 0x40, 0x18, 0x04, 0x00, 0x21, 0x18, 0x64, 0x00, -0x21, 0x18, 0x70, 0x00, 0x80, 0x18, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, -0x00, 0x00, 0x64, 0x8C, 0x25, 0xB0, 0x02, 0x3C, 0xD8, 0x01, 0x42, 0x34, -0x00, 0x00, 0x44, 0xAC, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xE8, 0xFF, 0xBD, 0x27, -0x10, 0x00, 0xB0, 0xAF, 0x14, 0x00, 0xBF, 0xAF, 0x21, 0x80, 0x80, 0x00, -0x02, 0x00, 0x84, 0x90, 0x02, 0x80, 0x05, 0x3C, 0x48, 0x37, 0xA5, 0x24, -0x0F, 0x00, 0x84, 0x30, 0xC0, 0x20, 0x04, 0x00, 0x21, 0x20, 0x90, 0x00, -0x1C, 0x00, 0x84, 0x24, 0x1D, 0x55, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, -0x06, 0x00, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, 0x10, 0x37, 0x43, 0x94, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x63, 0x30, 0x06, 0x00, 0x60, 0x14, -0x21, 0x20, 0x00, 0x02, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, -0x02, 0x11, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xBF, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0x00, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, -0xE0, 0xFF, 0xBD, 0x27, 0x54, 0x4A, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34, -0x18, 0x00, 0xB0, 0xAF, 0x1C, 0x00, 0xBF, 0xAF, 0x00, 0x00, 0x43, 0xAC, -0x02, 0x00, 0x82, 0x90, 0x02, 0x80, 0x05, 0x3C, 0xB4, 0x55, 0xA5, 0x24, -0x0F, 0x00, 0x42, 0x30, 0xC0, 0x10, 0x02, 0x00, 0x21, 0x10, 0x44, 0x00, -0x28, 0x00, 0x44, 0x24, 0x06, 0x00, 0x06, 0x24, 0x1D, 0x55, 0x00, 0x0C, -0x18, 0x00, 0x50, 0x24, 0x06, 0x00, 0x40, 0x10, 0x21, 0x20, 0x00, 0x02, -0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0x39, 0x53, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, 0x48, 0x37, 0x84, 0x24, -0x21, 0x28, 0x40, 0x00, 0x1D, 0x55, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, -0xF3, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x92, -0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x42, 0x30, 0xEE, 0xFF, 0x40, 0x10, -0x10, 0x00, 0xA4, 0x27, 0x8A, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x02, 0x80, 0x02, 0x3C, 0xEC, 0x5D, 0x43, 0x90, 0x05, 0x00, 0x02, 0x24, -0xFF, 0x00, 0x63, 0x30, 0x05, 0x00, 0x62, 0x10, 0x02, 0x80, 0x02, 0x3C, -0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0xA9, 0x12, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x10, 0x37, 0x43, 0x94, 0x02, 0x80, 0x04, 0x3C, -0x00, 0x01, 0x63, 0x30, 0xF8, 0xFF, 0x60, 0x10, 0x01, 0x00, 0x05, 0x24, -0x07, 0x5E, 0x83, 0x90, 0xFB, 0xFF, 0x02, 0x24, 0x24, 0x18, 0x62, 0x00, -0x07, 0x5E, 0x83, 0xA0, 0x02, 0x80, 0x02, 0x3C, 0xED, 0x5D, 0x44, 0x90, -0x4B, 0x2E, 0x00, 0x0C, 0xFF, 0x00, 0x84, 0x30, 0x90, 0x40, 0x00, 0x0C, -0x10, 0x00, 0xA4, 0x27, 0xA9, 0x12, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0xD8, 0xFF, 0xBD, 0x27, 0x28, 0x00, 0xA4, 0xA3, 0x00, 0x01, 0x04, 0x24, -0x18, 0x00, 0xB2, 0xAF, 0x24, 0x00, 0xBF, 0xAF, 0x20, 0x00, 0xB4, 0xAF, -0x1C, 0x00, 0xB3, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, -0x2C, 0x00, 0xA5, 0xA3, 0x53, 0x21, 0x00, 0x0C, 0x30, 0x00, 0xA6, 0xA7, -0xA4, 0x00, 0x40, 0x10, 0x21, 0x90, 0x40, 0x00, 0x30, 0x00, 0xA7, 0x97, -0x28, 0x00, 0xA5, 0x93, 0x2C, 0x00, 0xA6, 0x93, 0x02, 0x80, 0x04, 0x3C, -0x13, 0x58, 0x00, 0x0C, 0xB0, 0xEA, 0x84, 0x24, 0x08, 0x00, 0x50, 0x96, -0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x11, 0x3C, 0x25, 0x80, 0x02, 0x02, -0xB4, 0x55, 0x31, 0x26, 0x21, 0x28, 0x20, 0x02, 0x24, 0x00, 0x04, 0x26, -0x06, 0x00, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0x20, 0x00, 0x00, 0xA6, -0x02, 0x80, 0x05, 0x3C, 0x48, 0x37, 0xA5, 0x24, 0x2A, 0x00, 0x04, 0x26, -0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x21, 0x28, 0x20, 0x02, -0x30, 0x00, 0x04, 0x26, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, -0x20, 0x00, 0x03, 0x96, 0x18, 0x00, 0x02, 0x24, 0x02, 0x80, 0x14, 0x3C, -0x03, 0xFF, 0x63, 0x30, 0xD0, 0x00, 0x63, 0x34, 0x20, 0x00, 0x03, 0xA6, -0x60, 0x1B, 0x93, 0x26, 0x0C, 0x00, 0x42, 0xAE, 0xE4, 0x1D, 0x62, 0x96, -0x20, 0x00, 0x05, 0x26, 0x0C, 0x00, 0x51, 0x26, 0xFF, 0x0F, 0x43, 0x30, -0x00, 0x19, 0x03, 0x00, 0x02, 0x22, 0x03, 0x00, 0x01, 0x00, 0x42, 0x24, -0xE4, 0x1D, 0x62, 0xA6, 0x28, 0x00, 0xA6, 0x27, 0x16, 0x00, 0xA3, 0xA0, -0x17, 0x00, 0xA4, 0xA0, 0x21, 0x38, 0x20, 0x02, 0x38, 0x00, 0x04, 0x26, -0x4C, 0x52, 0x00, 0x0C, 0x01, 0x00, 0x05, 0x24, 0x21, 0x20, 0x40, 0x00, -0x01, 0x00, 0x05, 0x24, 0x2C, 0x00, 0xA6, 0x27, 0x4C, 0x52, 0x00, 0x0C, -0x21, 0x38, 0x20, 0x02, 0x28, 0x00, 0xA3, 0x93, 0x21, 0x20, 0x40, 0x00, -0x03, 0x00, 0x02, 0x24, 0x12, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, -0x60, 0x1B, 0x82, 0x26, 0xB6, 0x40, 0x43, 0x90, 0x04, 0x00, 0x07, 0x24, -0x21, 0x20, 0x40, 0x02, 0x01, 0x00, 0x63, 0x38, 0x0B, 0x38, 0x03, 0x00, -0x21, 0x28, 0x00, 0x00, 0xDF, 0x0D, 0x00, 0x0C, 0x21, 0x30, 0x00, 0x00, -0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, -0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, 0x2C, 0x00, 0xA3, 0x93, -0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x60, 0x14, 0x01, 0x00, 0x02, 0x24, -0xC5, 0x40, 0x63, 0x92, 0x21, 0x80, 0x60, 0x02, 0x01, 0x00, 0x68, 0x24, -0xFF, 0x00, 0x02, 0x31, 0xFD, 0xFF, 0x40, 0x10, 0x21, 0x18, 0x00, 0x01, -0x02, 0x80, 0x06, 0x3C, 0x21, 0x38, 0x20, 0x02, 0xC5, 0x40, 0x08, 0xA2, -0x25, 0x5C, 0xC6, 0x24, 0x4C, 0x52, 0x00, 0x0C, 0x01, 0x00, 0x05, 0x24, -0xC8, 0x40, 0x08, 0x8E, 0x30, 0x00, 0xA4, 0x97, 0xC3, 0xFF, 0x03, 0x24, -0x02, 0x00, 0x08, 0x35, 0x0F, 0x00, 0x84, 0x30, 0x24, 0x40, 0x03, 0x01, -0x80, 0x20, 0x04, 0x00, 0xFF, 0xFF, 0x03, 0x3C, 0x3F, 0x00, 0x63, 0x34, -0x25, 0x40, 0x04, 0x01, 0x24, 0x40, 0x03, 0x01, 0x00, 0x08, 0x08, 0x35, -0x02, 0x80, 0x06, 0x3C, 0x21, 0x38, 0x20, 0x02, 0xC8, 0x40, 0x08, 0xAE, -0x28, 0x5C, 0xC6, 0x24, 0x21, 0x20, 0x40, 0x00, 0x4C, 0x52, 0x00, 0x0C, -0x02, 0x00, 0x05, 0x24, 0x02, 0x80, 0x06, 0x3C, 0x21, 0x38, 0x20, 0x02, -0x2A, 0x5C, 0xC6, 0x24, 0x21, 0x20, 0x40, 0x00, 0x02, 0x00, 0x05, 0x24, -0x4C, 0x52, 0x00, 0x0C, 0xCA, 0x40, 0x00, 0xA6, 0x30, 0x00, 0xA3, 0x97, -0x21, 0x20, 0x40, 0x00, 0x02, 0x80, 0x06, 0x3C, 0x07, 0x00, 0x63, 0x30, -0x40, 0x18, 0x03, 0x00, 0x21, 0x18, 0x70, 0x00, 0xD4, 0x1D, 0x62, 0x94, -0x2C, 0x5C, 0xC6, 0x24, 0x21, 0x38, 0x20, 0x02, 0x00, 0x11, 0x02, 0x00, -0x02, 0x00, 0x05, 0x24, 0x4C, 0x52, 0x00, 0x0C, 0xCC, 0x40, 0x02, 0xA6, -0x22, 0x13, 0x00, 0x08, 0x60, 0x1B, 0x82, 0x26, 0xB5, 0xFF, 0x62, 0x14, -0x02, 0x80, 0x06, 0x3C, 0x21, 0x38, 0x20, 0x02, 0x24, 0x5C, 0xC6, 0x24, -0x4C, 0x52, 0x00, 0x0C, 0x01, 0x00, 0x05, 0x24, 0x21, 0x20, 0x40, 0x00, -0x30, 0x00, 0xA6, 0x27, 0x21, 0x38, 0x20, 0x02, 0x4C, 0x52, 0x00, 0x0C, -0x02, 0x00, 0x05, 0x24, 0xC8, 0x40, 0x68, 0x8E, 0xFF, 0xFF, 0x03, 0x3C, -0x3F, 0x00, 0x63, 0x34, 0x24, 0x40, 0x03, 0x01, 0x00, 0x08, 0x08, 0x35, -0x02, 0x80, 0x06, 0x3C, 0x21, 0x38, 0x20, 0x02, 0x21, 0x20, 0x40, 0x00, -0x28, 0x5C, 0xC6, 0x24, 0x02, 0x00, 0x05, 0x24, 0x4C, 0x52, 0x00, 0x0C, -0xC8, 0x40, 0x68, 0xAE, 0x02, 0x80, 0x06, 0x3C, 0x21, 0x20, 0x40, 0x00, -0x2A, 0x5C, 0xC6, 0x24, 0x21, 0x38, 0x20, 0x02, 0x4C, 0x52, 0x00, 0x0C, -0x02, 0x00, 0x05, 0x24, 0x22, 0x13, 0x00, 0x08, 0x60, 0x1B, 0x82, 0x26, -0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, 0xAC, 0xE8, 0x84, 0x24, -0x13, 0x58, 0x00, 0x0C, 0xA0, 0xEA, 0xA5, 0x24, 0x24, 0x00, 0xBF, 0x8F, -0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x28, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xBF, 0xAF, -0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x00, 0x00, 0x82, 0x90, -0x02, 0x80, 0x11, 0x3C, 0x21, 0x80, 0x80, 0x00, 0x60, 0x1B, 0x31, 0x26, -0x02, 0x80, 0x04, 0x3C, 0x02, 0x00, 0x06, 0x24, 0x01, 0x00, 0x05, 0x26, -0x28, 0x5C, 0x84, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0xC4, 0x40, 0x22, 0xA2, -0x04, 0x00, 0x03, 0x92, 0x03, 0x00, 0x02, 0x92, 0x00, 0x1A, 0x03, 0x00, -0x25, 0x18, 0x62, 0x00, 0xCA, 0x40, 0x23, 0xA6, 0x06, 0x00, 0x02, 0x92, -0x05, 0x00, 0x03, 0x92, 0x00, 0x12, 0x02, 0x00, 0x25, 0x10, 0x43, 0x00, -0xCC, 0x40, 0x22, 0xA6, 0x01, 0x00, 0x05, 0x92, 0x06, 0x00, 0x04, 0x92, -0x05, 0x00, 0x02, 0x92, 0x82, 0x28, 0x05, 0x00, 0x00, 0x22, 0x04, 0x00, -0x25, 0x20, 0x82, 0x00, 0x6A, 0x48, 0x00, 0x0C, 0x0F, 0x00, 0xA5, 0x30, -0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x03, 0x00, 0x04, 0x24, 0x01, 0x00, 0x05, 0x24, 0x21, 0x30, 0x00, 0x00, -0xD9, 0x12, 0x00, 0x08, 0x20, 0x00, 0xBD, 0x27, 0x00, 0x80, 0x03, 0x3C, -0x25, 0xB0, 0x02, 0x3C, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x03, 0x42, 0x34, -0xFC, 0x4E, 0x63, 0x24, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, -0x1C, 0x00, 0xBF, 0xAF, 0x18, 0x00, 0xB2, 0xAF, 0x00, 0x00, 0x43, 0xAC, -0x02, 0x00, 0x82, 0x90, 0x02, 0x80, 0x05, 0x3C, 0xB4, 0x55, 0xA5, 0x24, -0x0F, 0x00, 0x42, 0x30, 0xC0, 0x10, 0x02, 0x00, 0x21, 0x88, 0x44, 0x00, -0x28, 0x00, 0x24, 0x26, 0x06, 0x00, 0x06, 0x24, 0x1D, 0x55, 0x00, 0x0C, -0x18, 0x00, 0x30, 0x26, 0x08, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, -0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x20, 0x00, 0xBD, 0x27, 0x39, 0x53, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x02, -0x02, 0x80, 0x04, 0x3C, 0x48, 0x37, 0x84, 0x24, 0x21, 0x28, 0x40, 0x00, -0x1D, 0x55, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0xF1, 0xFF, 0x40, 0x14, -0x03, 0x00, 0x02, 0x24, 0x30, 0x00, 0x23, 0x92, 0x00, 0x00, 0x00, 0x00, -0xED, 0xFF, 0x62, 0x14, 0x30, 0x00, 0x24, 0x26, 0x02, 0x80, 0x07, 0x3C, -0x60, 0x1B, 0xE5, 0x24, 0xFC, 0x40, 0xA2, 0x8C, 0x00, 0x00, 0x00, 0x00, -0xE7, 0xFF, 0x40, 0x10, 0x01, 0x00, 0x06, 0x24, 0x01, 0x00, 0x83, 0x90, -0x00, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x66, 0x10, 0x02, 0x00, 0x62, 0x28, -0x2E, 0x00, 0x40, 0x14, 0x02, 0x00, 0x02, 0x24, 0xDF, 0xFF, 0x62, 0x14, -0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0x62, 0x30, 0x0A, 0x00, 0x40, 0x14, 0x02, 0x11, 0x03, 0x00, -0xC6, 0x40, 0xA3, 0x90, 0x04, 0x10, 0x46, 0x00, 0x27, 0x10, 0x02, 0x00, -0x24, 0x10, 0x43, 0x00, 0xC6, 0x40, 0xA2, 0xA0, 0x05, 0x00, 0x83, 0x90, -0x04, 0x00, 0x82, 0x90, 0x00, 0x1A, 0x03, 0x00, 0x25, 0x90, 0x62, 0x00, -0xC6, 0x40, 0xA5, 0x90, 0x02, 0x80, 0x04, 0x3C, 0xCC, 0xEA, 0x84, 0x24, -0x13, 0x58, 0x00, 0x0C, 0x21, 0x30, 0x40, 0x02, 0xD5, 0x13, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x82, 0x90, 0x05, 0x00, 0x83, 0x90, -0x03, 0x00, 0x84, 0x90, 0x00, 0x12, 0x02, 0x00, 0x82, 0x18, 0x03, 0x00, -0x25, 0x10, 0x44, 0x00, 0x15, 0x00, 0x40, 0x14, 0x07, 0x00, 0x64, 0x30, -0xC6, 0x40, 0xA3, 0x90, 0x04, 0x10, 0x86, 0x00, 0x25, 0x10, 0x43, 0x00, -0xC6, 0x40, 0xA2, 0xA0, 0x60, 0x1B, 0xE2, 0x24, 0xF8, 0x40, 0x43, 0x90, -0xC6, 0x40, 0x45, 0x90, 0x02, 0x80, 0x04, 0x3C, 0x21, 0x18, 0x62, 0x00, -0xDC, 0xEA, 0x84, 0x24, 0x13, 0x58, 0x00, 0x0C, 0xF0, 0x40, 0x60, 0xA0, -0xD5, 0x13, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xB2, 0xFF, 0x60, 0x14, -0x00, 0x00, 0x00, 0x00, 0x97, 0x13, 0x00, 0x0C, 0x32, 0x00, 0x24, 0x26, -0xD5, 0x13, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x40, 0xA3, 0x90, -0x04, 0x10, 0x86, 0x00, 0x27, 0x10, 0x02, 0x00, 0x17, 0x14, 0x00, 0x08, -0x24, 0x10, 0x43, 0x00, 0xB8, 0xFF, 0xBD, 0x27, 0x38, 0x00, 0xB6, 0xAF, -0xFF, 0xFF, 0x96, 0x30, 0x00, 0x01, 0x04, 0x24, 0x3C, 0x00, 0xB7, 0xAF, -0x28, 0x00, 0xB2, 0xAF, 0x40, 0x00, 0xBF, 0xAF, 0x34, 0x00, 0xB5, 0xAF, -0x30, 0x00, 0xB4, 0xAF, 0x2C, 0x00, 0xB3, 0xAF, 0x24, 0x00, 0xB1, 0xAF, -0x53, 0x21, 0x00, 0x0C, 0x20, 0x00, 0xB0, 0xAF, 0x21, 0x90, 0x40, 0x00, -0x81, 0x00, 0x40, 0x10, 0x21, 0xB8, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, -0x13, 0x58, 0x00, 0x0C, 0xF8, 0xEA, 0x84, 0x24, 0x08, 0x00, 0x50, 0x96, -0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x11, 0x3C, 0x25, 0x80, 0x02, 0x02, -0xB4, 0x55, 0x31, 0x26, 0x24, 0x00, 0x04, 0x26, 0x21, 0x28, 0x20, 0x02, -0x20, 0x00, 0x00, 0xA6, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, -0x02, 0x80, 0x05, 0x3C, 0x2A, 0x00, 0x04, 0x26, 0x48, 0x37, 0xA5, 0x24, -0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x30, 0x00, 0x04, 0x26, -0x21, 0x28, 0x20, 0x02, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, -0x20, 0x00, 0x03, 0x96, 0x18, 0x00, 0x02, 0x24, 0x02, 0x80, 0x15, 0x3C, -0x03, 0xFF, 0x63, 0x30, 0xB0, 0x00, 0x63, 0x34, 0x20, 0x00, 0x03, 0xA6, -0x60, 0x1B, 0xA8, 0x26, 0x0C, 0x00, 0x42, 0xAE, 0xE4, 0x1D, 0x02, 0x95, -0x20, 0x00, 0x14, 0x26, 0x0C, 0x00, 0x51, 0x26, 0xFF, 0x0F, 0x43, 0x30, -0x00, 0x19, 0x03, 0x00, 0x02, 0x22, 0x03, 0x00, 0x01, 0x00, 0x42, 0x24, -0xE4, 0x1D, 0x02, 0xA5, 0x17, 0x00, 0x84, 0xA2, 0x16, 0x00, 0x83, 0xA2, -0x20, 0x40, 0x04, 0x8D, 0x03, 0x00, 0x02, 0x24, 0x31, 0x00, 0x82, 0x10, -0x38, 0x00, 0x10, 0x26, 0x60, 0x1B, 0xB3, 0x26, 0x24, 0x40, 0x62, 0x8E, -0x21, 0x20, 0x00, 0x02, 0x02, 0x00, 0x05, 0x24, 0x01, 0x00, 0x42, 0x38, -0x01, 0x00, 0x42, 0x2C, 0x18, 0x00, 0xA6, 0x27, 0x21, 0x38, 0x20, 0x02, -0x4C, 0x52, 0x00, 0x0C, 0x18, 0x00, 0xA2, 0xA7, 0x20, 0x40, 0x63, 0x8E, -0x21, 0x20, 0x40, 0x00, 0x02, 0x00, 0x05, 0x24, 0x18, 0x00, 0xA6, 0x27, -0x21, 0x38, 0x20, 0x02, 0x4C, 0x52, 0x00, 0x0C, 0x18, 0x00, 0xA3, 0xA7, -0x21, 0x20, 0x40, 0x00, 0x02, 0x00, 0x05, 0x24, 0x18, 0x00, 0xA6, 0x27, -0x21, 0x38, 0x20, 0x02, 0x4C, 0x52, 0x00, 0x0C, 0x18, 0x00, 0xB6, 0xA7, -0x20, 0x40, 0x63, 0x8E, 0x21, 0x80, 0x40, 0x00, 0x03, 0x00, 0x02, 0x24, -0x28, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0xA2, 0x26, -0xB6, 0x40, 0x43, 0x90, 0x04, 0x00, 0x07, 0x24, 0x21, 0x20, 0x40, 0x02, -0x01, 0x00, 0x63, 0x38, 0x21, 0x30, 0xE0, 0x02, 0x0B, 0x38, 0x03, 0x00, -0xDF, 0x0D, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, 0x40, 0x00, 0xBF, 0x8F, -0x3C, 0x00, 0xB7, 0x8F, 0x38, 0x00, 0xB6, 0x8F, 0x34, 0x00, 0xB5, 0x8F, -0x30, 0x00, 0xB4, 0x8F, 0x2C, 0x00, 0xB3, 0x8F, 0x28, 0x00, 0xB2, 0x8F, -0x24, 0x00, 0xB1, 0x8F, 0x20, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x48, 0x00, 0xBD, 0x27, 0xB0, 0x1B, 0x02, 0x95, 0x00, 0x00, 0x00, 0x00, -0x40, 0x00, 0x42, 0x30, 0xCD, 0xFF, 0x40, 0x10, 0x60, 0x1B, 0xB3, 0x26, -0x2C, 0x40, 0x03, 0x8D, 0x30, 0x40, 0x02, 0x8D, 0x21, 0x20, 0x00, 0x02, -0x80, 0x1F, 0x03, 0x00, 0x25, 0x18, 0x43, 0x00, 0x04, 0x00, 0x05, 0x24, -0x01, 0x00, 0x42, 0x24, 0x1C, 0x00, 0xA6, 0x27, 0x21, 0x38, 0x20, 0x02, -0x30, 0x40, 0x02, 0xAD, 0x4C, 0x52, 0x00, 0x0C, 0x1C, 0x00, 0xA3, 0xAF, -0x69, 0x14, 0x00, 0x08, 0x21, 0x80, 0x40, 0x00, 0xB0, 0x1B, 0x62, 0x96, -0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x30, 0xD6, 0xFF, 0x40, 0x10, -0x60, 0x1B, 0xA2, 0x26, 0x02, 0x80, 0x07, 0x3C, 0x21, 0x20, 0x00, 0x02, -0x94, 0x5B, 0xE7, 0x24, 0x10, 0x00, 0x05, 0x24, 0x80, 0x00, 0x06, 0x24, -0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB1, 0xAF, 0x00, 0x00, 0x83, 0x96, -0x01, 0x00, 0x17, 0x24, 0x00, 0x40, 0x63, 0x34, 0x85, 0x14, 0x00, 0x08, -0x00, 0x00, 0x83, 0xA6, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, -0xAC, 0xE8, 0x84, 0x24, 0x13, 0x58, 0x00, 0x0C, 0xEC, 0xEA, 0xA5, 0x24, -0x40, 0x00, 0xBF, 0x8F, 0x3C, 0x00, 0xB7, 0x8F, 0x38, 0x00, 0xB6, 0x8F, -0x34, 0x00, 0xB5, 0x8F, 0x30, 0x00, 0xB4, 0x8F, 0x2C, 0x00, 0xB3, 0x8F, -0x28, 0x00, 0xB2, 0x8F, 0x24, 0x00, 0xB1, 0x8F, 0x20, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x48, 0x00, 0xBD, 0x27, 0xB0, 0xFF, 0xBD, 0x27, -0x38, 0x00, 0xB4, 0xAF, 0x34, 0x00, 0xB3, 0xAF, 0x30, 0x00, 0xB2, 0xAF, -0x2C, 0x00, 0xB1, 0xAF, 0x28, 0x00, 0xB0, 0xAF, 0x48, 0x00, 0xBF, 0xAF, -0x44, 0x00, 0xB7, 0xAF, 0x40, 0x00, 0xB6, 0xAF, 0x3C, 0x00, 0xB5, 0xAF, -0x02, 0x00, 0x82, 0x90, 0x02, 0x80, 0x12, 0x3C, 0x21, 0xA0, 0x80, 0x00, -0x0F, 0x00, 0x42, 0x30, 0xC0, 0x10, 0x02, 0x00, 0x21, 0x80, 0x44, 0x00, -0x28, 0x00, 0x11, 0x26, 0xB4, 0x55, 0x45, 0x26, 0x21, 0x20, 0x20, 0x02, -0x06, 0x00, 0x06, 0x24, 0x1D, 0x55, 0x00, 0x0C, 0x18, 0x00, 0x13, 0x26, -0x9F, 0x00, 0x40, 0x10, 0x21, 0x20, 0x60, 0x02, 0x02, 0x80, 0x15, 0x3C, -0x60, 0x1B, 0xA2, 0x26, 0x4B, 0x41, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, -0x82, 0x00, 0x60, 0x10, 0x3C, 0x00, 0x04, 0x26, 0x60, 0x1B, 0xB0, 0x26, -0xB0, 0x1B, 0x03, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0x30, -0x6D, 0x00, 0x40, 0x14, 0x10, 0x00, 0x62, 0x30, 0x13, 0x00, 0x40, 0x14, -0x10, 0x00, 0x76, 0x26, 0x60, 0x1B, 0xB0, 0x26, 0xB0, 0x1B, 0x02, 0x96, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x30, 0x8F, 0x00, 0x40, 0x14, -0x21, 0x18, 0x00, 0x00, 0x48, 0x00, 0xBF, 0x8F, 0x44, 0x00, 0xB7, 0x8F, -0x40, 0x00, 0xB6, 0x8F, 0x3C, 0x00, 0xB5, 0x8F, 0x38, 0x00, 0xB4, 0x8F, -0x34, 0x00, 0xB3, 0x8F, 0x30, 0x00, 0xB2, 0x8F, 0x2C, 0x00, 0xB1, 0x8F, -0x28, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x50, 0x00, 0xBD, 0x27, 0x21, 0x20, 0xC0, 0x02, 0xB4, 0x55, 0x45, 0x26, -0x1D, 0x55, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0xE9, 0xFF, 0x40, 0x14, -0x07, 0x00, 0x02, 0x24, 0xB6, 0x40, 0x02, 0xA2, 0xE8, 0x39, 0x00, 0xAE, -0x00, 0x00, 0x84, 0x8E, 0x0C, 0x00, 0x12, 0x24, 0xFF, 0x3F, 0x82, 0x30, -0xE8, 0xFF, 0x42, 0x24, 0x2A, 0x10, 0x42, 0x02, 0x9C, 0x00, 0x40, 0x10, -0x21, 0xB8, 0x00, 0x02, 0x1F, 0x15, 0x00, 0x08, 0x21, 0x80, 0x72, 0x02, -0x19, 0x00, 0x03, 0x92, 0xFF, 0x3F, 0x82, 0x30, 0xE8, 0xFF, 0x42, 0x24, -0x21, 0x18, 0x72, 0x00, 0x02, 0x00, 0x72, 0x24, 0x2A, 0x10, 0x42, 0x02, -0x93, 0x00, 0x40, 0x10, 0x60, 0x1B, 0xB0, 0x26, 0x21, 0x80, 0x72, 0x02, -0x18, 0x00, 0x03, 0x92, 0xDD, 0x00, 0x02, 0x24, 0xF4, 0xFF, 0x62, 0x14, -0x1A, 0x00, 0x11, 0x26, 0x02, 0x80, 0x05, 0x3C, 0x64, 0xDE, 0xA5, 0x24, -0x21, 0x20, 0x20, 0x02, 0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24, -0x55, 0x01, 0x40, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x60, 0xDE, 0xA5, 0x24, -0x21, 0x20, 0x20, 0x02, 0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24, -0x4F, 0x01, 0x40, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x54, 0xDE, 0xA5, 0x24, -0x21, 0x20, 0x20, 0x02, 0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24, -0x44, 0x01, 0x40, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x50, 0xDE, 0xA5, 0x24, -0x21, 0x20, 0x20, 0x02, 0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24, -0x3E, 0x01, 0x40, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x4C, 0xDE, 0xA5, 0x24, -0x21, 0x20, 0x20, 0x02, 0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24, -0x38, 0x01, 0x40, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x44, 0xDE, 0xA5, 0x24, -0x21, 0x20, 0x20, 0x02, 0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24, -0x3B, 0x01, 0x40, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x40, 0xDE, 0xA5, 0x24, -0x21, 0x20, 0x20, 0x02, 0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24, -0x53, 0x01, 0x40, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x48, 0xDE, 0xA5, 0x24, -0x21, 0x20, 0x20, 0x02, 0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24, -0x47, 0x01, 0x40, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x21, 0x20, 0x20, 0x02, -0x34, 0xDE, 0xA5, 0x24, 0x1D, 0x55, 0x00, 0x0C, 0x04, 0x00, 0x06, 0x24, -0x2F, 0x01, 0x40, 0x10, 0x02, 0x00, 0x02, 0x24, 0x00, 0x00, 0x84, 0x8E, -0x16, 0x15, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, 0x00, 0x0C, -0x21, 0x20, 0x80, 0x02, 0x21, 0x18, 0x00, 0x00, 0x48, 0x00, 0xBF, 0x8F, -0x44, 0x00, 0xB7, 0x8F, 0x40, 0x00, 0xB6, 0x8F, 0x3C, 0x00, 0xB5, 0x8F, -0x38, 0x00, 0xB4, 0x8F, 0x34, 0x00, 0xB3, 0x8F, 0x30, 0x00, 0xB2, 0x8F, -0x2C, 0x00, 0xB1, 0x8F, 0x28, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x50, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x87, 0x8E, -0x07, 0x00, 0x05, 0x24, 0xFF, 0x3F, 0xE7, 0x30, 0xDC, 0xFF, 0xE7, 0x24, -0xAB, 0x1A, 0x00, 0x0C, 0x20, 0x00, 0xA6, 0x27, 0x78, 0xFF, 0x40, 0x10, -0x21, 0x38, 0x40, 0x00, 0x20, 0x00, 0xA5, 0x8F, 0x00, 0x00, 0x00, 0x00, -0x06, 0x00, 0xA2, 0x28, 0x73, 0xFF, 0x40, 0x14, 0xFD, 0xFF, 0xA5, 0x24, -0x05, 0x00, 0xE4, 0x24, 0xE5, 0x4B, 0x00, 0x0C, 0xFF, 0x00, 0xA5, 0x30, -0x02, 0x80, 0x04, 0x3C, 0xAC, 0x5C, 0x84, 0x24, 0x21, 0x28, 0x20, 0x02, -0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0xEC, 0x14, 0x00, 0x08, -0x60, 0x1B, 0xB0, 0x26, 0xB9, 0x2B, 0x00, 0x0C, 0x21, 0x28, 0x80, 0x02, -0xE6, 0x14, 0x00, 0x08, 0x02, 0x80, 0x15, 0x3C, 0xB4, 0x55, 0x45, 0x26, -0x10, 0x00, 0x64, 0x26, 0x1D, 0x55, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, -0xD4, 0xFF, 0x40, 0x14, 0x21, 0x18, 0x00, 0x00, 0x21, 0x20, 0x80, 0x02, -0xE3, 0x17, 0x00, 0x0C, 0x18, 0x00, 0x85, 0x26, 0x21, 0x20, 0x40, 0x00, -0x8D, 0x17, 0x00, 0x0C, 0x05, 0x00, 0x05, 0x24, 0xB0, 0x1B, 0x03, 0x96, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x62, 0x30, 0x0C, 0x00, 0x40, 0x14, -0x04, 0x00, 0x62, 0x30, 0x4B, 0x00, 0x40, 0x14, 0x60, 0x1B, 0xB0, 0x26, -0xB7, 0x40, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x44, 0x24, -0xFF, 0x00, 0x83, 0x30, 0x15, 0x00, 0x02, 0x24, 0x5D, 0x00, 0x62, 0x10, -0x21, 0x18, 0x00, 0x00, 0xF9, 0x14, 0x00, 0x08, 0xB7, 0x40, 0x04, 0xA2, -0x8A, 0x40, 0x00, 0x0C, 0x24, 0x00, 0xA4, 0x27, 0xE8, 0x1E, 0x03, 0x8E, -0xEC, 0x1E, 0x02, 0x8E, 0x24, 0x00, 0xA4, 0x27, 0x01, 0x00, 0x63, 0x24, -0x01, 0x00, 0x42, 0x24, 0xEC, 0x1E, 0x02, 0xAE, 0x90, 0x40, 0x00, 0x0C, -0xE8, 0x1E, 0x03, 0xAE, 0x9A, 0x15, 0x00, 0x08, 0x60, 0x1B, 0xB0, 0x26, -0x60, 0x1B, 0xB0, 0x26, 0xB6, 0x40, 0x03, 0x92, 0x07, 0x00, 0x02, 0x24, -0x21, 0x00, 0x62, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x04, 0x3C, -0x5C, 0xEB, 0x84, 0x24, 0x13, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x02, 0x80, 0x02, 0x3C, 0xCE, 0x5C, 0x46, 0x90, 0x01, 0x00, 0x03, 0x24, -0x0F, 0x00, 0xC3, 0x10, 0x60, 0x1B, 0xA4, 0x26, 0xD5, 0x4E, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0xBF, 0x8F, 0x44, 0x00, 0xB7, 0x8F, -0x40, 0x00, 0xB6, 0x8F, 0x3C, 0x00, 0xB5, 0x8F, 0x38, 0x00, 0xB4, 0x8F, -0x34, 0x00, 0xB3, 0x8F, 0x30, 0x00, 0xB2, 0x8F, 0x2C, 0x00, 0xB1, 0x8F, -0x28, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x50, 0x00, 0xBD, 0x27, 0xB6, 0x40, 0x83, 0x90, 0x03, 0x00, 0x02, 0x24, -0x2A, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x41, 0x86, 0xA0, -0xD5, 0x4E, 0x00, 0x0C, 0x3C, 0x41, 0x80, 0xA0, 0xBF, 0x15, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x5C, 0xDE, 0xA5, 0x24, 0x21, 0x20, 0xC0, 0x02, -0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24, 0x07, 0x00, 0x40, 0x10, -0x02, 0x80, 0x05, 0x3C, 0x21, 0x20, 0xC0, 0x02, 0x58, 0xDE, 0xA5, 0x24, -0x1D, 0x55, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24, 0xD5, 0xFF, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, 0x70, 0xEB, 0x84, 0x24, -0xB6, 0x15, 0x00, 0x08, 0xB6, 0x40, 0x00, 0xA2, 0x0A, 0x00, 0x76, 0x26, -0x1F, 0x54, 0x00, 0x0C, 0x21, 0x20, 0xC0, 0x02, 0x20, 0x00, 0x10, 0x24, -0x37, 0x00, 0x50, 0x10, 0x21, 0x88, 0x40, 0x00, 0x8A, 0x40, 0x00, 0x0C, -0x24, 0x00, 0xA4, 0x27, 0x40, 0x10, 0x11, 0x00, 0x21, 0x10, 0x51, 0x00, -0x60, 0x1B, 0xA4, 0x26, 0x00, 0x11, 0x02, 0x00, 0x21, 0x10, 0x44, 0x00, -0xF8, 0x1D, 0x43, 0x8C, 0x24, 0x00, 0xA4, 0x27, 0x01, 0x00, 0x63, 0x24, -0x90, 0x40, 0x00, 0x0C, 0xF8, 0x1D, 0x43, 0xAC, 0x60, 0x15, 0x00, 0x08, -0x21, 0x18, 0x00, 0x00, 0x3C, 0x41, 0x86, 0xA0, 0xD5, 0x4E, 0x00, 0x0C, -0x3D, 0x41, 0x80, 0xA0, 0xBF, 0x15, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x55, 0x12, 0x00, 0x0C, 0xB7, 0x40, 0x00, 0xA2, 0x02, 0x80, 0x02, 0x3C, -0xD2, 0x5C, 0x44, 0x90, 0x02, 0x00, 0x03, 0x24, 0x5D, 0xFF, 0x83, 0x14, -0x21, 0x18, 0x00, 0x00, 0x00, 0x00, 0x87, 0x8E, 0x24, 0x00, 0x64, 0x26, -0x2A, 0x00, 0x05, 0x24, 0xFF, 0x3F, 0xE7, 0x30, 0xDC, 0xFF, 0xE7, 0x24, -0xAB, 0x1A, 0x00, 0x0C, 0x20, 0x00, 0xA6, 0x27, 0x54, 0xFF, 0x40, 0x10, -0x21, 0x18, 0x00, 0x00, 0x02, 0x00, 0x44, 0x90, 0x00, 0x00, 0x00, 0x00, -0x02, 0x00, 0x82, 0x30, 0x95, 0x00, 0x40, 0x10, 0x60, 0x1B, 0xA5, 0x26, -0x01, 0x00, 0x82, 0x30, 0x92, 0x00, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, -0xD3, 0x5C, 0x44, 0x90, 0x01, 0x00, 0x03, 0x24, 0x9F, 0x00, 0x83, 0x10, -0x00, 0x00, 0x00, 0x00, 0xFC, 0x23, 0x02, 0x8E, 0xFF, 0xEF, 0x03, 0x24, -0x00, 0x08, 0x42, 0x34, 0x24, 0x10, 0x43, 0x00, 0xFC, 0x23, 0x02, 0xAE, -0x60, 0x15, 0x00, 0x08, 0x21, 0x18, 0x00, 0x00, 0xFF, 0xFF, 0x04, 0x24, -0xC7, 0x53, 0x00, 0x0C, 0x21, 0x28, 0xC0, 0x02, 0xC6, 0xFF, 0x50, 0x10, -0x21, 0x88, 0x40, 0x00, 0x00, 0x00, 0x87, 0x8E, 0x24, 0x00, 0x77, 0x26, -0x21, 0x20, 0xE0, 0x02, 0xFF, 0x3F, 0xE7, 0x30, 0xDC, 0xFF, 0xE7, 0x24, -0x01, 0x00, 0x05, 0x24, 0xAB, 0x1A, 0x00, 0x0C, 0x20, 0x00, 0xA6, 0x27, -0xCB, 0xFE, 0x40, 0x10, 0x21, 0x18, 0x00, 0x00, 0x20, 0x00, 0xA6, 0x8F, -0x02, 0x00, 0x45, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, -0x00, 0x00, 0x87, 0x8E, 0x21, 0x20, 0xE0, 0x02, 0x32, 0x00, 0x05, 0x24, -0xFF, 0x3F, 0xE7, 0x30, 0xDC, 0xFF, 0xE7, 0x24, 0x20, 0x00, 0xB0, 0x8F, -0xAB, 0x1A, 0x00, 0x0C, 0x20, 0x00, 0xA6, 0x27, 0x08, 0x00, 0x40, 0x10, -0x10, 0x00, 0xA4, 0x27, 0x20, 0x00, 0xA6, 0x8F, 0x21, 0x20, 0x90, 0x00, -0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x45, 0x24, 0x20, 0x00, 0xA3, 0x8F, -0x00, 0x00, 0x00, 0x00, 0x21, 0x80, 0x03, 0x02, 0x10, 0x00, 0xA4, 0x27, -0x61, 0x53, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x02, 0x21, 0x28, 0x00, 0x02, -0x10, 0x00, 0xA4, 0x27, 0xA6, 0x53, 0x00, 0x0C, 0x0F, 0x00, 0x53, 0x30, -0x00, 0x00, 0x87, 0x8E, 0x21, 0x20, 0xE0, 0x02, 0x2D, 0x00, 0x05, 0x24, -0xFF, 0x3F, 0xE7, 0x30, 0xDC, 0xFF, 0xE7, 0x24, 0x20, 0x00, 0xA6, 0x27, -0xAB, 0x1A, 0x00, 0x0C, 0x21, 0x90, 0x40, 0x00, 0x11, 0x00, 0x40, 0x10, -0x00, 0x81, 0x11, 0x00, 0x06, 0x00, 0x44, 0x90, 0x05, 0x00, 0x43, 0x90, -0x02, 0x80, 0x02, 0x3C, 0xC6, 0x5C, 0x45, 0x90, 0x00, 0x1B, 0x03, 0x00, -0x00, 0x25, 0x04, 0x00, 0x25, 0x18, 0x64, 0x00, 0x10, 0x00, 0xA5, 0x30, -0x25, 0x90, 0x43, 0x02, 0x02, 0x00, 0xA0, 0x14, 0x0F, 0x00, 0x02, 0x3C, -0xFF, 0x0F, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, 0x24, 0x90, 0x42, 0x02, -0x08, 0x00, 0x73, 0x36, 0x00, 0x81, 0x11, 0x00, 0x25, 0x80, 0x13, 0x02, -0xFF, 0xFF, 0x10, 0x32, 0x02, 0x80, 0x04, 0x3C, 0x21, 0x28, 0x20, 0x02, -0x21, 0x30, 0x00, 0x02, 0x21, 0x38, 0x40, 0x02, 0x13, 0x58, 0x00, 0x0C, -0x8C, 0xEB, 0x84, 0x24, 0x21, 0x20, 0x00, 0x02, 0x63, 0x5E, 0x00, 0x74, -0x21, 0x28, 0x40, 0x02, 0x60, 0x1B, 0xA3, 0x26, 0x3A, 0x41, 0x62, 0x90, -0x21, 0x20, 0xC0, 0x02, 0x21, 0x28, 0x20, 0x02, 0x01, 0x00, 0x42, 0x24, -0xEA, 0x0E, 0x00, 0x0C, 0x3A, 0x41, 0x62, 0xA0, 0xEA, 0x15, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, 0x01, 0x00, 0x02, 0x24, -0xA0, 0xEB, 0x84, 0x24, 0xB6, 0x15, 0x00, 0x08, 0xB6, 0x40, 0xE2, 0xA2, -0x02, 0x80, 0x04, 0x3C, 0xB8, 0xEB, 0x84, 0x24, 0xB6, 0x15, 0x00, 0x08, -0xB6, 0x40, 0xE0, 0xA2, 0x02, 0x80, 0x04, 0x3C, 0x60, 0x1B, 0xA3, 0x26, -0x03, 0x00, 0x02, 0x24, 0xCC, 0xEB, 0x84, 0x24, 0xB6, 0x15, 0x00, 0x08, -0xB6, 0x40, 0x62, 0xA0, 0x1E, 0x00, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, -0x0A, 0x00, 0x62, 0x14, 0x02, 0x80, 0x04, 0x3C, 0x20, 0x00, 0x02, 0x92, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, 0x05, 0x00, 0x40, 0x10, -0x02, 0x80, 0x02, 0x3C, 0xC8, 0xDF, 0x43, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x1A, 0x00, 0x60, 0x14, 0x11, 0x00, 0x03, 0x24, 0x13, 0x58, 0x00, 0x0C, -0xE0, 0xEB, 0x84, 0x24, 0x05, 0x00, 0x02, 0x24, 0xB8, 0x15, 0x00, 0x08, -0xB6, 0x40, 0xE2, 0xA2, 0x02, 0x80, 0x04, 0x3C, 0x60, 0x1B, 0xA3, 0x26, -0x02, 0x00, 0x02, 0x24, 0xF8, 0xEB, 0x84, 0x24, 0xB6, 0x15, 0x00, 0x08, -0xB6, 0x40, 0x62, 0xA0, 0x02, 0x80, 0x04, 0x3C, 0x60, 0x1B, 0xA3, 0x26, -0x04, 0x00, 0x02, 0x24, 0x0C, 0xEC, 0x84, 0x24, 0xB6, 0x15, 0x00, 0x08, -0xB6, 0x40, 0x62, 0xA0, 0xFC, 0x23, 0xA2, 0x8C, 0xFF, 0xEF, 0x03, 0x24, -0xFF, 0xF7, 0x04, 0x24, 0x24, 0x10, 0x43, 0x00, 0x24, 0x10, 0x44, 0x00, -0x21, 0x18, 0x00, 0x00, 0x60, 0x15, 0x00, 0x08, 0xFC, 0x23, 0xA2, 0xAC, -0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0x20, 0xEC, 0x84, 0x24, -0x13, 0x58, 0x00, 0x0C, 0xC6, 0x5C, 0x43, 0xA0, 0x60, 0x1B, 0xA3, 0x26, -0x06, 0x00, 0x02, 0x24, 0xB8, 0x15, 0x00, 0x08, 0xB6, 0x40, 0x62, 0xA0, -0xFC, 0x23, 0x02, 0x8E, 0xFF, 0xF7, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, -0x00, 0x10, 0x42, 0x34, 0x1E, 0x16, 0x00, 0x08, 0xFC, 0x23, 0x02, 0xAE, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27, -0x10, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x10, 0x3C, 0x60, 0x1B, 0x02, 0x26, -0x14, 0x00, 0xBF, 0xAF, 0xB0, 0x1B, 0x43, 0x94, 0x21, 0x28, 0x00, 0x00, -0x00, 0x01, 0x62, 0x30, 0x03, 0x00, 0x40, 0x10, 0x01, 0x00, 0x64, 0x30, -0x06, 0x00, 0x80, 0x14, 0x00, 0x10, 0x62, 0x30, 0x14, 0x00, 0xBF, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0xA0, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0x08, 0x00, 0x40, 0x14, 0x60, 0x1B, 0x04, 0x26, -0x02, 0x80, 0x02, 0x3C, 0xEE, 0x5D, 0x43, 0x90, 0x0C, 0x00, 0x02, 0x24, -0x0F, 0x00, 0x63, 0x30, 0x09, 0x00, 0x62, 0x10, 0x21, 0x20, 0x00, 0x00, -0x60, 0x1B, 0x04, 0x26, 0x60, 0xEA, 0x03, 0x34, 0x04, 0x3A, 0x83, 0xAC, -0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0xA0, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0x0E, 0x51, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x04, 0x26, 0x60, 0xEA, 0x03, 0x34, -0xDB, 0x16, 0x00, 0x08, 0x04, 0x3A, 0x83, 0xAC, 0xD8, 0xFF, 0xBD, 0x27, -0x1C, 0x00, 0xB1, 0xAF, 0x02, 0x80, 0x11, 0x3C, 0x18, 0x00, 0xB0, 0xAF, -0x20, 0x00, 0xBF, 0xAF, 0x60, 0x1B, 0x30, 0x26, 0x04, 0x3E, 0x02, 0x8E, -0x00, 0x10, 0x03, 0x3C, 0x24, 0x10, 0x43, 0x00, 0x12, 0x00, 0x40, 0x10, -0x00, 0x00, 0x00, 0x00, 0x33, 0x3E, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x63, 0x24, 0xFF, 0x00, 0x62, 0x30, 0x21, 0x10, 0x50, 0x00, -0xD0, 0x3D, 0x45, 0x90, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xA4, 0x30, -0x18, 0x00, 0x80, 0x10, 0x33, 0x3E, 0x03, 0xA2, 0xFF, 0x3D, 0x02, 0x92, -0xC4, 0x3D, 0x05, 0xA2, 0x75, 0x0D, 0x00, 0x0C, 0xC5, 0x3D, 0x02, 0xA2, -0xC4, 0x3D, 0x04, 0x92, 0x38, 0x0D, 0x00, 0x0C, 0x01, 0x00, 0x05, 0x24, -0x08, 0x3E, 0x03, 0x8E, 0x01, 0x00, 0x02, 0x24, 0x52, 0x00, 0x62, 0x10, -0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x25, 0x26, 0x04, 0x3E, 0xA4, 0x8C, -0x00, 0x10, 0x02, 0x3C, 0x3C, 0x00, 0x03, 0x24, 0x26, 0x20, 0x82, 0x00, -0x94, 0x39, 0xA3, 0xAC, 0x04, 0x3E, 0xA4, 0xAC, 0x20, 0x00, 0xBF, 0x8F, -0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x28, 0x00, 0xBD, 0x27, 0xB0, 0x1B, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, -0xFF, 0xEF, 0x42, 0x30, 0x00, 0x01, 0x43, 0x30, 0x49, 0x00, 0x60, 0x14, -0xB0, 0x1B, 0x02, 0xA6, 0x31, 0x3E, 0x06, 0x92, 0x37, 0x3E, 0x03, 0x92, -0x32, 0x3E, 0x05, 0x92, 0x25, 0xB0, 0x02, 0x3C, 0x4C, 0x00, 0x42, 0x34, -0x00, 0x00, 0x43, 0xA0, 0xFF, 0x00, 0xC4, 0x30, 0xC5, 0x3D, 0x05, 0xA2, -0x75, 0x0D, 0x00, 0x0C, 0xC4, 0x3D, 0x06, 0xA2, 0xC4, 0x3D, 0x04, 0x92, -0x38, 0x0D, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, 0xB0, 0x1B, 0x03, 0x96, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62, 0x30, 0x09, 0x00, 0x40, 0x10, -0x01, 0x00, 0x62, 0x30, 0x08, 0x00, 0x40, 0x10, 0x60, 0x1B, 0x30, 0x26, -0x02, 0x80, 0x02, 0x3C, 0xEE, 0x5D, 0x43, 0x90, 0x0C, 0x00, 0x02, 0x24, -0x0F, 0x00, 0x63, 0x30, 0x58, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, -0x60, 0x1B, 0x30, 0x26, 0x34, 0x3E, 0x04, 0x96, 0x36, 0x3E, 0x05, 0x92, -0x95, 0x0E, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x11, 0x48, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xA4, 0x27, 0x8A, 0x40, 0x00, 0x0C, -0x04, 0x3E, 0x00, 0xAE, 0xB0, 0x1B, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x42, 0x30, 0x2A, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C, -0xEC, 0x5D, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x60, 0x10, -0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0xEE, 0x5D, 0x62, 0x90, -0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x42, 0x30, 0x04, 0x00, 0x42, 0x28, -0x3A, 0x00, 0x40, 0x14, 0x04, 0x00, 0x04, 0x24, 0x02, 0x80, 0x03, 0x3C, -0x0E, 0x5E, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x0E, 0x5E, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x42, 0x24, 0x0E, 0x5E, 0x62, 0xA0, 0x72, 0x17, 0x00, 0x08, -0x60, 0x1B, 0x30, 0x26, 0xC4, 0x3D, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, -0x0C, 0x00, 0x42, 0x2C, 0xAB, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, -0x12, 0x49, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x07, 0x17, 0x00, 0x08, -0x60, 0x1B, 0x25, 0x26, 0x25, 0xB0, 0x05, 0x3C, 0x48, 0x00, 0xA5, 0x34, -0x00, 0x00, 0xA3, 0x8C, 0x60, 0x1B, 0x24, 0x8E, 0x84, 0x00, 0x02, 0x3C, -0x25, 0x18, 0x62, 0x00, 0x25, 0x00, 0x84, 0x34, 0x00, 0x00, 0xA3, 0xAC, -0x18, 0x17, 0x00, 0x08, 0x60, 0x1B, 0x24, 0xAE, 0x02, 0x80, 0x02, 0x3C, -0x0E, 0x5E, 0x40, 0xA0, 0x02, 0x80, 0x03, 0x3C, 0xED, 0x5D, 0x64, 0x90, -0x01, 0x00, 0x05, 0x24, 0x4B, 0x2E, 0x00, 0x0C, 0xFF, 0x00, 0x84, 0x30, -0x60, 0x1B, 0x30, 0x26, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, -0x52, 0x41, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x96, 0xFF, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x8A, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, -0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, 0x2C, 0x59, 0x84, 0x24, -0xA0, 0xDD, 0xA5, 0x24, 0x34, 0x00, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C, -0x4B, 0x41, 0x00, 0xA2, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, -0x0D, 0x17, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x2E, 0x00, 0x0C, -0x01, 0x00, 0x05, 0x24, 0x4D, 0x17, 0x00, 0x08, 0x02, 0x80, 0x03, 0x3C, -0x0E, 0x51, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x00, 0x33, 0x17, 0x00, 0x08, -0x60, 0x1B, 0x30, 0x26, 0x02, 0x80, 0x09, 0x3C, 0x60, 0x1B, 0x28, 0x25, -0x6C, 0x37, 0x06, 0x8D, 0xFF, 0xFF, 0x02, 0x34, 0x44, 0x00, 0xC2, 0x10, -0x21, 0x38, 0x80, 0x00, 0x2B, 0x10, 0xC7, 0x00, 0x34, 0x00, 0x40, 0x10, -0x02, 0x19, 0x06, 0x00, 0x21, 0x10, 0xC7, 0x00, 0x23, 0x10, 0x43, 0x00, -0x10, 0x00, 0x46, 0x24, 0x6C, 0x37, 0x06, 0xAD, 0x70, 0x37, 0x02, 0xAD, -0x60, 0x1B, 0x26, 0x25, 0x05, 0x00, 0xC4, 0x90, 0xFF, 0xFF, 0x02, 0x34, -0xFF, 0x00, 0x83, 0x30, 0x33, 0x00, 0x62, 0x10, 0x00, 0x11, 0x07, 0x00, -0xFF, 0x00, 0x84, 0x30, 0x2B, 0x10, 0x87, 0x00, 0x20, 0x00, 0x40, 0x10, -0x03, 0x19, 0x04, 0x00, 0x03, 0x11, 0x04, 0x00, 0x21, 0x18, 0x87, 0x00, -0x23, 0x18, 0x62, 0x00, 0x10, 0x00, 0x64, 0x24, 0x05, 0x00, 0xC4, 0xA0, -0x70, 0x37, 0xC3, 0xAC, 0xC0, 0x10, 0x05, 0x00, 0x21, 0x10, 0x45, 0x00, -0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x45, 0x00, 0x60, 0x1B, 0x23, 0x25, -0x80, 0x10, 0x02, 0x00, 0x21, 0x28, 0x43, 0x00, 0xF8, 0x24, 0xA6, 0x8C, -0x00, 0x21, 0x07, 0x00, 0xFF, 0xFF, 0xC2, 0x38, 0x0A, 0x30, 0x82, 0x00, -0x2B, 0x18, 0xC7, 0x00, 0x07, 0x00, 0x60, 0x10, 0x21, 0x10, 0xC7, 0x00, -0x02, 0x19, 0x06, 0x00, 0x23, 0x10, 0x43, 0x00, 0x10, 0x00, 0x46, 0x24, -0xF8, 0x24, 0xA6, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0xFC, 0x24, 0xA2, 0xAC, -0x02, 0x19, 0x06, 0x00, 0x23, 0x10, 0x43, 0x00, 0xF8, 0x24, 0xA2, 0xAC, -0x08, 0x00, 0xE0, 0x03, 0xFC, 0x24, 0xA2, 0xAC, 0x21, 0x10, 0x87, 0x00, -0x23, 0x10, 0x43, 0x00, 0x05, 0x00, 0xC2, 0xA0, 0xAB, 0x17, 0x00, 0x08, -0x70, 0x37, 0xC2, 0xAC, 0x21, 0x10, 0xC7, 0x00, 0x23, 0x10, 0x43, 0x00, -0x6C, 0x37, 0x02, 0xAD, 0x70, 0x37, 0x02, 0xAD, 0x60, 0x1B, 0x26, 0x25, -0x05, 0x00, 0xC4, 0x90, 0xFF, 0xFF, 0x02, 0x34, 0xFF, 0x00, 0x83, 0x30, -0xCF, 0xFF, 0x62, 0x14, 0x00, 0x11, 0x07, 0x00, 0x21, 0x20, 0x40, 0x00, -0xA1, 0x17, 0x00, 0x08, 0x05, 0x00, 0xC2, 0xA0, 0x00, 0x31, 0x04, 0x00, -0x93, 0x17, 0x00, 0x08, 0x6C, 0x37, 0x06, 0xAD, 0x63, 0x00, 0x82, 0x24, -0x77, 0x00, 0x42, 0x2C, 0x00, 0x00, 0x85, 0x28, 0x04, 0x00, 0x40, 0x10, -0x21, 0x18, 0x00, 0x00, 0x64, 0x00, 0x82, 0x24, 0x64, 0x00, 0x03, 0x24, -0x0B, 0x18, 0x45, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, -0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF, 0x0C, 0x00, 0x82, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x42, 0x30, 0x04, 0x00, 0x42, 0x28, -0x08, 0x00, 0x40, 0x14, 0x25, 0xB0, 0x02, 0x3C, 0x00, 0x00, 0xA4, 0x8C, -0x10, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xBD, 0x27, 0x3F, 0x00, 0x84, 0x30, -0x40, 0x20, 0x04, 0x00, 0xD9, 0x17, 0x00, 0x08, 0x96, 0xFF, 0x84, 0x24, -0x24, 0x08, 0x42, 0x34, 0x00, 0x00, 0x43, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x02, 0x63, 0x30, 0x1B, 0x00, 0x60, 0x14, 0x01, 0x00, 0x02, 0x24, -0x05, 0x00, 0xA3, 0x90, 0x00, 0x00, 0x00, 0x00, 0x82, 0x31, 0x03, 0x00, -0x3C, 0x00, 0xC2, 0x10, 0x02, 0x00, 0xC2, 0x28, 0x57, 0x00, 0x40, 0x14, -0x02, 0x00, 0x02, 0x24, 0x46, 0x00, 0xC2, 0x10, 0x03, 0x00, 0x02, 0x24, -0x2E, 0x00, 0xC2, 0x10, 0x3E, 0x00, 0x63, 0x30, 0xD9, 0x17, 0x00, 0x0C, -0x21, 0x20, 0xE0, 0x00, 0x06, 0x00, 0x45, 0x24, 0x65, 0x00, 0xA4, 0x2C, -0x64, 0x00, 0x03, 0x24, 0x0A, 0x28, 0x64, 0x00, 0xDD, 0xFF, 0xA2, 0x24, -0x08, 0x00, 0x42, 0x2C, 0x1F, 0x00, 0x40, 0x10, 0xE5, 0xFF, 0xA2, 0x24, -0xFE, 0xFF, 0xA5, 0x24, 0x10, 0x00, 0xBF, 0x8F, 0x21, 0x10, 0xA0, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0x05, 0x00, 0xA3, 0x90, -0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x66, 0x30, 0x42, 0x31, 0x06, 0x00, -0x25, 0x00, 0xC2, 0x10, 0x02, 0x00, 0xC2, 0x28, 0x36, 0x00, 0x40, 0x14, -0x02, 0x00, 0x02, 0x24, 0x2F, 0x00, 0xC2, 0x10, 0x03, 0x00, 0x02, 0x24, -0xE6, 0xFF, 0xC2, 0x14, 0x1F, 0x00, 0x62, 0x30, 0x40, 0x10, 0x02, 0x00, -0xD8, 0xFF, 0x03, 0x24, 0x23, 0x38, 0x62, 0x00, 0xD9, 0x17, 0x00, 0x0C, -0x21, 0x20, 0xE0, 0x00, 0x06, 0x00, 0x45, 0x24, 0x65, 0x00, 0xA4, 0x2C, -0x64, 0x00, 0x03, 0x24, 0x0A, 0x28, 0x64, 0x00, 0xDD, 0xFF, 0xA2, 0x24, -0x08, 0x00, 0x42, 0x2C, 0xE3, 0xFF, 0x40, 0x14, 0xE5, 0xFF, 0xA2, 0x24, -0x08, 0x00, 0x42, 0x2C, 0x06, 0x00, 0x40, 0x10, 0xF1, 0xFF, 0xA2, 0x24, -0x0E, 0x18, 0x00, 0x08, 0xFA, 0xFF, 0xA5, 0x24, 0xD8, 0xFF, 0x02, 0x24, -0x03, 0x18, 0x00, 0x08, 0x23, 0x38, 0x43, 0x00, 0x0C, 0x00, 0x42, 0x2C, -0x0C, 0x00, 0x40, 0x10, 0xFB, 0xFF, 0xA2, 0x24, 0x0E, 0x18, 0x00, 0x08, -0xF8, 0xFF, 0xA5, 0x24, 0x3E, 0x00, 0x63, 0x30, 0xFE, 0xFF, 0x02, 0x24, -0x03, 0x18, 0x00, 0x08, 0x23, 0x38, 0x43, 0x00, 0x1F, 0x00, 0x62, 0x30, -0x40, 0x10, 0x02, 0x00, 0xFE, 0xFF, 0x03, 0x24, 0x21, 0x18, 0x00, 0x08, -0x23, 0x38, 0x62, 0x00, 0x0A, 0x00, 0x42, 0x2C, 0xCB, 0xFF, 0x40, 0x10, -0x00, 0x00, 0x00, 0x00, 0x0E, 0x18, 0x00, 0x08, 0xFC, 0xFF, 0xA5, 0x24, -0x3E, 0x00, 0x63, 0x30, 0xEC, 0xFF, 0x02, 0x24, 0x03, 0x18, 0x00, 0x08, -0x23, 0x38, 0x43, 0x00, 0x1F, 0x00, 0x62, 0x30, 0x40, 0x10, 0x02, 0x00, -0xEC, 0xFF, 0x03, 0x24, 0x21, 0x18, 0x00, 0x08, 0x23, 0x38, 0x62, 0x00, -0xB3, 0xFF, 0xC0, 0x14, 0x1F, 0x00, 0x62, 0x30, 0x40, 0x10, 0x02, 0x00, -0x0E, 0x00, 0x03, 0x24, 0x21, 0x18, 0x00, 0x08, 0x23, 0x38, 0x62, 0x00, -0xAD, 0xFF, 0xC0, 0x14, 0x3E, 0x00, 0x63, 0x30, 0x0E, 0x00, 0x02, 0x24, -0x03, 0x18, 0x00, 0x08, 0x23, 0x38, 0x43, 0x00, 0x98, 0xFF, 0xBD, 0x27, -0x64, 0x00, 0xBF, 0xAF, 0x60, 0x00, 0xBE, 0xAF, 0x5C, 0x00, 0xB7, 0xAF, -0x58, 0x00, 0xB6, 0xAF, 0x54, 0x00, 0xB5, 0xAF, 0x50, 0x00, 0xB4, 0xAF, -0x4C, 0x00, 0xB3, 0xAF, 0x48, 0x00, 0xB2, 0xAF, 0x44, 0x00, 0xB1, 0xAF, -0x40, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x02, 0x3C, 0x88, 0x54, 0x45, 0x8C, -0x00, 0x80, 0x04, 0x3C, 0x68, 0x61, 0x83, 0x24, 0x88, 0x54, 0x44, 0x24, -0x25, 0xB0, 0x02, 0x3C, 0x18, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, -0x81, 0x00, 0xA4, 0x10, 0x02, 0x80, 0x02, 0x3C, 0xE8, 0xEC, 0x42, 0x24, -0x00, 0x00, 0x5E, 0x8C, 0x02, 0x80, 0x03, 0x3C, 0xEC, 0xEC, 0x63, 0x24, -0x00, 0x00, 0x75, 0x8C, 0x28, 0x39, 0xD6, 0x8F, 0x21, 0xB8, 0x00, 0x00, -0x08, 0x00, 0xC2, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xAE, -0x08, 0x00, 0xC3, 0x96, 0x02, 0x80, 0x02, 0x3C, 0x9E, 0x18, 0x00, 0x08, -0x25, 0xA0, 0x62, 0x00, 0x17, 0x00, 0x25, 0x92, 0x16, 0x00, 0x26, 0x92, -0xC8, 0x3D, 0xC2, 0x97, 0xFF, 0x00, 0xA3, 0x30, 0x00, 0x1A, 0x03, 0x00, -0xFF, 0x00, 0xC4, 0x30, 0x25, 0x18, 0x64, 0x00, 0x14, 0x00, 0x43, 0x10, -0xFF, 0x00, 0xA2, 0x30, 0xFF, 0x00, 0xC3, 0x30, 0x00, 0x12, 0x02, 0x00, -0x25, 0x10, 0x43, 0x00, 0xC8, 0x3D, 0xC2, 0xA7, 0x01, 0x00, 0x24, 0x92, -0x18, 0x00, 0x42, 0x92, 0x00, 0x22, 0x04, 0x00, 0xA8, 0x0D, 0x00, 0x0C, -0x25, 0x20, 0x82, 0x00, 0x40, 0x18, 0x02, 0x00, 0x21, 0x18, 0x62, 0x00, -0x02, 0x80, 0x04, 0x3C, 0x98, 0xDE, 0x82, 0x24, 0x80, 0x18, 0x03, 0x00, -0x21, 0x18, 0x62, 0x00, 0x08, 0x00, 0x62, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x09, 0xF8, 0x40, 0x00, 0x21, 0x20, 0x60, 0x02, 0x0C, 0x00, 0xC2, 0x8E, -0x00, 0x00, 0x00, 0x00, 0x2B, 0x10, 0xE2, 0x02, 0x41, 0x00, 0x40, 0x10, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x8E, 0x02, 0x80, 0x03, 0x3C, -0x48, 0x37, 0x64, 0x24, 0x42, 0x1B, 0x02, 0x00, 0x78, 0x00, 0x63, 0x30, -0x02, 0x2E, 0x02, 0x00, 0xFF, 0x3F, 0x42, 0x30, 0x21, 0x10, 0x43, 0x00, -0x03, 0x00, 0xA5, 0x30, 0x21, 0x10, 0x45, 0x00, 0x18, 0x00, 0x42, 0x24, -0xFF, 0xFF, 0x50, 0x30, 0x7F, 0x00, 0x02, 0x32, 0x21, 0x98, 0x80, 0x02, -0x06, 0x00, 0x06, 0x24, 0x80, 0x00, 0x03, 0x26, 0x00, 0x00, 0xB0, 0xAE, -0x02, 0x00, 0x40, 0x10, 0x80, 0xFF, 0x05, 0x32, 0x80, 0xFF, 0x65, 0x30, -0x00, 0x00, 0xA5, 0xAE, 0x02, 0x00, 0x62, 0x96, 0x21, 0x18, 0xE5, 0x02, -0xFF, 0xFF, 0x77, 0x30, 0x0F, 0x00, 0x42, 0x30, 0x00, 0x00, 0xA2, 0xAE, -0x00, 0x00, 0x63, 0x8E, 0x21, 0xA0, 0x85, 0x02, 0x42, 0x13, 0x03, 0x00, -0x78, 0x00, 0x42, 0x30, 0x02, 0x1E, 0x03, 0x00, 0x03, 0x00, 0x63, 0x30, -0x21, 0x10, 0x53, 0x00, 0x21, 0x90, 0x43, 0x00, 0x1C, 0x00, 0x50, 0x26, -0x18, 0x00, 0x51, 0x26, 0x21, 0x28, 0x00, 0x02, 0x00, 0x00, 0xB1, 0xAE, -0x1D, 0x55, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x03, 0x3C, -0x21, 0x28, 0x00, 0x02, 0x06, 0x00, 0x06, 0x24, 0x0B, 0x00, 0x40, 0x14, -0x90, 0xDE, 0x64, 0x24, 0x01, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00, -0x00, 0x12, 0x02, 0x00, 0x00, 0x08, 0x42, 0x30, 0xAD, 0xFF, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x26, 0x92, 0x17, 0x00, 0x25, 0x92, -0x86, 0x18, 0x00, 0x08, 0xFF, 0x00, 0xA2, 0x30, 0x1D, 0x55, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0xF3, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, -0x0C, 0x00, 0xC2, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x10, 0xE2, 0x02, -0xC1, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x40, 0x00, 0x0C, -0x38, 0x00, 0xA4, 0x27, 0x04, 0x00, 0xC3, 0x8E, 0x00, 0x00, 0xC2, 0x8E, -0x21, 0x20, 0xC0, 0x02, 0x00, 0x00, 0x62, 0xAC, 0x04, 0x00, 0x43, 0xAC, -0x00, 0x00, 0xD6, 0xAE, 0x74, 0x21, 0x00, 0x0C, 0x04, 0x00, 0xD6, 0xAE, -0x90, 0x40, 0x00, 0x0C, 0x38, 0x00, 0xA4, 0x27, 0x02, 0x80, 0x02, 0x3C, -0x88, 0x54, 0x43, 0x8C, 0x88, 0x54, 0x42, 0x24, 0x86, 0xFF, 0x62, 0x14, -0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x03, 0x3C, 0xE8, 0xEC, 0x63, 0x24, -0x00, 0x00, 0x71, 0x8C, 0x25, 0xB0, 0x10, 0x3C, 0x04, 0x01, 0x02, 0x36, -0x00, 0x00, 0x43, 0x8C, 0xDC, 0x38, 0x27, 0x8E, 0x00, 0x00, 0x00, 0x00, -0x77, 0x00, 0xE3, 0x10, 0xE0, 0x38, 0x23, 0xAE, 0x2B, 0x10, 0x67, 0x00, -0x81, 0x00, 0x40, 0x14, 0x2B, 0x10, 0xE3, 0x00, 0xA9, 0x00, 0x40, 0x14, -0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x44, 0x24, 0xB0, 0x38, 0x83, 0x94, -0x02, 0x80, 0x02, 0x3C, 0x21, 0x80, 0x00, 0x00, 0x34, 0x00, 0xE0, 0x1A, -0x25, 0x90, 0x62, 0x00, 0x21, 0x88, 0x80, 0x00, 0x21, 0x18, 0x00, 0x00, -0x01, 0x00, 0x14, 0x24, 0x00, 0xC0, 0x15, 0x3C, 0x0E, 0x19, 0x00, 0x08, -0x03, 0x00, 0x1E, 0x24, 0x80, 0x18, 0x10, 0x00, 0x2A, 0x10, 0x77, 0x00, -0x2A, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x98, 0x72, 0x00, -0x00, 0x00, 0x62, 0x8E, 0x44, 0x41, 0x23, 0x8E, 0x38, 0x00, 0xA4, 0x27, -0xFF, 0x3F, 0x42, 0x30, 0x21, 0x18, 0x62, 0x00, 0x8A, 0x40, 0x00, 0x0C, -0x44, 0x41, 0x23, 0xAE, 0xE8, 0x1E, 0x22, 0x8E, 0xF0, 0x1E, 0x23, 0x8E, -0x38, 0x00, 0xA4, 0x27, 0x01, 0x00, 0x42, 0x24, 0x01, 0x00, 0x63, 0x24, -0xE8, 0x1E, 0x22, 0xAE, 0x90, 0x40, 0x00, 0x0C, 0xF0, 0x1E, 0x23, 0xAE, -0xEC, 0x2C, 0x00, 0x0C, 0x21, 0x20, 0x60, 0x02, 0x00, 0x00, 0x63, 0x8E, -0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x60, 0x14, 0x06, 0x00, 0x02, 0x26, -0x01, 0x00, 0x02, 0x26, 0xFF, 0xFF, 0x50, 0x30, 0x82, 0x16, 0x03, 0x00, -0x01, 0x00, 0x42, 0x30, 0xE1, 0xFF, 0x54, 0x14, 0x02, 0x80, 0x04, 0x3C, -0x60, 0x1B, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x42, 0x11, 0x02, 0x00, -0x01, 0x00, 0x42, 0x30, 0x0C, 0x00, 0x54, 0x10, 0xC2, 0x13, 0x03, 0x00, -0x1E, 0x00, 0x42, 0x30, 0x21, 0x10, 0x50, 0x00, 0xFF, 0xFF, 0x50, 0x30, -0x80, 0x18, 0x10, 0x00, 0x2A, 0x10, 0x77, 0x00, 0xD8, 0xFF, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x74, 0x21, 0x00, 0x0C, 0x21, 0x20, 0xC0, 0x02, -0x75, 0x19, 0x00, 0x08, 0x02, 0x80, 0x03, 0x3C, 0x01, 0x00, 0x22, 0x92, -0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x04, 0x00, 0x63, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x02, 0x14, 0x03, 0x00, -0x0F, 0x00, 0x42, 0x30, 0x11, 0x00, 0x40, 0x14, 0x02, 0x17, 0x03, 0x00, -0x03, 0x00, 0x44, 0x30, 0x07, 0x00, 0x80, 0x10, 0x24, 0x10, 0x75, 0x00, -0x0C, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x9E, 0x10, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, -0x80, 0x28, 0x10, 0x00, 0x21, 0x28, 0xB2, 0x00, 0xE3, 0x17, 0x00, 0x0C, -0x21, 0x20, 0x60, 0x02, 0x21, 0x20, 0x40, 0x00, 0x8D, 0x17, 0x00, 0x0C, -0x21, 0x28, 0x00, 0x00, 0x01, 0x00, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00, -0x7B, 0x00, 0x54, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x23, 0x92, -0x02, 0x00, 0x02, 0x24, 0x63, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, -0x25, 0xB0, 0x02, 0x3C, 0x4C, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0x90, -0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x63, 0x30, 0x08, 0x00, 0x74, 0x10, -0xD0, 0x02, 0x02, 0x24, 0x00, 0x00, 0x63, 0x8E, 0x00, 0x00, 0x00, 0x00, -0xC2, 0x13, 0x03, 0x00, 0x1E, 0x00, 0x42, 0x30, 0x21, 0x10, 0x50, 0x00, -0x33, 0x19, 0x00, 0x08, 0xFF, 0xFF, 0x50, 0x30, 0x6C, 0x37, 0x22, 0xAE, -0x00, 0x00, 0x63, 0x8E, 0x67, 0x19, 0x00, 0x08, 0xC2, 0x13, 0x03, 0x00, -0x00, 0x01, 0x02, 0x36, 0x00, 0x00, 0x47, 0xAC, 0x02, 0x80, 0x02, 0x3C, -0x60, 0x1B, 0x42, 0x24, 0xDC, 0x38, 0x47, 0xAC, 0x02, 0x80, 0x03, 0x3C, -0x08, 0x04, 0x64, 0x24, 0x21, 0x28, 0x00, 0x00, 0x21, 0x30, 0x00, 0x00, -0x76, 0x39, 0x00, 0x0C, 0x21, 0x38, 0x00, 0x00, 0x66, 0x18, 0x00, 0x08, -0x02, 0x80, 0x02, 0x3C, 0xE4, 0x38, 0x22, 0x8E, 0xFF, 0xFF, 0x73, 0x30, -0x23, 0x10, 0x47, 0x00, 0xFF, 0xFF, 0x52, 0x30, 0x21, 0x18, 0x53, 0x02, -0xFF, 0xFF, 0x77, 0x30, 0x53, 0x21, 0x00, 0x0C, 0x21, 0x20, 0xE0, 0x02, -0xEF, 0xFF, 0x40, 0x10, 0x21, 0xB0, 0x40, 0x00, 0x08, 0x00, 0x42, 0x8C, -0xDC, 0x38, 0x26, 0x8E, 0x21, 0x38, 0x40, 0x02, 0x21, 0x18, 0x57, 0x00, -0xAC, 0x38, 0x23, 0xAE, 0x21, 0x28, 0x40, 0x00, 0x08, 0x00, 0x04, 0x24, -0xB0, 0x38, 0x22, 0xAE, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, -0x5B, 0x01, 0x00, 0x0C, 0x08, 0x00, 0x04, 0x24, 0xB0, 0x38, 0x25, 0x8E, -0x24, 0x10, 0x02, 0x3C, 0x00, 0x01, 0x10, 0x36, 0x00, 0x00, 0x02, 0xAE, -0x21, 0x38, 0x60, 0x02, 0x21, 0x28, 0xB2, 0x00, 0x08, 0x00, 0x04, 0x24, -0x24, 0x10, 0x06, 0x3C, 0xDC, 0x38, 0x22, 0xAE, 0x1E, 0x01, 0x00, 0x0C, -0x10, 0x00, 0xA0, 0xAF, 0xE0, 0x38, 0x23, 0x8E, 0x08, 0x00, 0x04, 0x24, -0x5B, 0x01, 0x00, 0x0C, 0xDC, 0x38, 0x23, 0xAE, 0xDC, 0x38, 0x22, 0x8E, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xAE, 0xFE, 0x18, 0x00, 0x08, -0x02, 0x80, 0x02, 0x3C, 0x23, 0x10, 0x67, 0x00, 0xFF, 0xFF, 0x57, 0x30, -0x53, 0x21, 0x00, 0x0C, 0x21, 0x20, 0xE0, 0x02, 0x44, 0x00, 0x40, 0x10, -0x21, 0xB0, 0x40, 0x00, 0x08, 0x00, 0x42, 0x8C, 0xDC, 0x38, 0x26, 0x8E, -0x08, 0x00, 0x04, 0x24, 0x21, 0x18, 0x57, 0x00, 0xAC, 0x38, 0x23, 0xAE, -0x21, 0x28, 0x40, 0x00, 0x21, 0x38, 0xE0, 0x02, 0xB0, 0x38, 0x22, 0xAE, -0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, 0xE0, 0x38, 0x23, 0x8E, -0x08, 0x00, 0x04, 0x24, 0x5B, 0x01, 0x00, 0x0C, 0xDC, 0x38, 0x23, 0xAE, -0xDC, 0x38, 0x23, 0x8E, 0x00, 0x01, 0x02, 0x36, 0x00, 0x00, 0x43, 0xAC, -0xFE, 0x18, 0x00, 0x08, 0x02, 0x80, 0x02, 0x3C, 0x04, 0x00, 0x63, 0x8E, -0x00, 0x00, 0x00, 0x00, 0x02, 0x14, 0x03, 0x00, 0x0F, 0x00, 0x42, 0x30, -0x08, 0x00, 0x42, 0x28, 0x99, 0xFF, 0x40, 0x10, 0x25, 0xB0, 0x02, 0x3C, -0x02, 0x17, 0x03, 0x00, 0x03, 0x00, 0x42, 0x30, 0x94, 0xFF, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x80, 0x28, 0x10, 0x00, 0x21, 0x28, 0xB2, 0x00, -0xE3, 0x17, 0x00, 0x0C, 0x21, 0x20, 0x60, 0x02, 0x21, 0x20, 0x40, 0x00, -0x8D, 0x17, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, 0x5E, 0x19, 0x00, 0x08, -0x25, 0xB0, 0x02, 0x3C, 0x04, 0x00, 0x63, 0x8E, 0x00, 0x00, 0x00, 0x00, -0x02, 0x14, 0x03, 0x00, 0x0F, 0x00, 0x42, 0x30, 0x08, 0x00, 0x42, 0x28, -0x06, 0x00, 0x40, 0x10, 0x24, 0x10, 0x75, 0x00, 0x02, 0x17, 0x03, 0x00, -0x03, 0x00, 0x42, 0x30, 0x0A, 0x00, 0x40, 0x10, 0x80, 0x28, 0x10, 0x00, -0x24, 0x10, 0x75, 0x00, 0x79, 0xFF, 0x40, 0x14, 0x02, 0x17, 0x03, 0x00, -0x03, 0x00, 0x42, 0x30, 0x76, 0xFF, 0x5E, 0x10, 0x00, 0x00, 0x00, 0x00, -0x74, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x28, 0x10, 0x00, -0x21, 0x28, 0xB2, 0x00, 0xE3, 0x17, 0x00, 0x0C, 0x21, 0x20, 0x60, 0x02, -0x21, 0x20, 0x40, 0x00, 0x8D, 0x17, 0x00, 0x0C, 0x05, 0x00, 0x05, 0x24, -0x59, 0x19, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x38, 0x23, 0x8E, -0x00, 0x01, 0x02, 0x36, 0x00, 0x00, 0x43, 0xAC, 0x74, 0x19, 0x00, 0x08, -0xDC, 0x38, 0x23, 0xAE, 0xB8, 0xFF, 0xBD, 0x27, 0x25, 0xB0, 0x03, 0x3C, -0x44, 0x00, 0xBF, 0xAF, 0x40, 0x00, 0xBE, 0xAF, 0x3C, 0x00, 0xB7, 0xAF, -0x38, 0x00, 0xB6, 0xAF, 0x34, 0x00, 0xB5, 0xAF, 0x30, 0x00, 0xB4, 0xAF, -0x2C, 0x00, 0xB3, 0xAF, 0x28, 0x00, 0xB2, 0xAF, 0x24, 0x00, 0xB1, 0xAF, -0x20, 0x00, 0xB0, 0xAF, 0x44, 0x00, 0x63, 0x34, 0x00, 0x00, 0x62, 0x90, -0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x02, 0x00, 0x03, 0x16, 0x02, 0x00, -0x0E, 0x00, 0x40, 0x04, 0x1C, 0x00, 0xA0, 0xAF, 0x21, 0x20, 0x60, 0x00, -0x21, 0x10, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xFF, 0xFF, 0x42, 0x30, -0x64, 0x00, 0x43, 0x2C, 0xFD, 0xFF, 0x60, 0x14, 0x01, 0x00, 0x42, 0x24, -0x00, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x02, 0x00, -0x03, 0x16, 0x02, 0x00, 0xF6, 0xFF, 0x41, 0x04, 0x21, 0x10, 0x00, 0x00, -0x02, 0x80, 0x02, 0x3C, 0x98, 0x54, 0x43, 0x8C, 0x00, 0x80, 0x06, 0x3C, -0xD0, 0x67, 0xC2, 0x24, 0x25, 0xB0, 0x05, 0x3C, 0x02, 0x80, 0x06, 0x3C, -0x18, 0x03, 0xA4, 0x34, 0x98, 0x54, 0xD1, 0x24, 0x00, 0x00, 0x82, 0xAC, -0x4B, 0x00, 0x71, 0x10, 0x01, 0x00, 0x15, 0x24, 0x11, 0x11, 0x02, 0x3C, -0x2A, 0xB0, 0x03, 0x3C, 0x22, 0x22, 0x57, 0x34, 0x02, 0x80, 0x02, 0x3C, -0x21, 0xB0, 0x80, 0x00, 0x06, 0x00, 0x7E, 0x34, 0x05, 0x00, 0x73, 0x34, -0x60, 0x1B, 0x54, 0x24, 0x01, 0x00, 0x12, 0x24, 0x00, 0x00, 0xD7, 0xAE, -0x05, 0x00, 0xA0, 0x12, 0x02, 0x80, 0x03, 0x3C, 0xEC, 0x5D, 0x62, 0x90, -0x00, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x40, 0x14, 0x21, 0xA8, 0x00, 0x00, -0x00, 0x00, 0xC2, 0x97, 0x38, 0x39, 0x90, 0x8E, 0x25, 0xB0, 0x03, 0x3C, -0xB0, 0x03, 0x63, 0x34, 0x00, 0xFF, 0x42, 0x30, 0x00, 0x00, 0x70, 0xAC, -0x0F, 0x00, 0x40, 0x18, 0x02, 0x80, 0x06, 0x3C, 0x02, 0x80, 0x02, 0x3C, -0xF0, 0xEC, 0xC6, 0x24, 0xF4, 0xEC, 0x42, 0x24, 0x00, 0x00, 0xC5, 0x8C, -0x00, 0x00, 0x44, 0x8C, 0x02, 0x80, 0x06, 0x3C, 0xF8, 0xEC, 0xC6, 0x24, -0x00, 0x00, 0xC3, 0x8C, 0x00, 0x00, 0xA4, 0xAC, 0x00, 0x00, 0x62, 0x94, -0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x42, 0x30, 0xFB, 0xFF, 0x40, 0x1C, -0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x03, 0x8E, 0x00, 0x00, 0x00, 0x00, -0x07, 0x00, 0x62, 0x30, 0x60, 0x00, 0x40, 0x14, 0x08, 0x00, 0x62, 0x24, -0xC2, 0x10, 0x03, 0x00, 0x08, 0x00, 0x05, 0x8E, 0xF8, 0x37, 0x86, 0x8E, -0xC0, 0x10, 0x02, 0x00, 0x20, 0x00, 0x42, 0x24, 0xFF, 0xFF, 0x47, 0x30, -0x01, 0x00, 0x04, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xB2, 0xAF, -0x5B, 0x01, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24, 0x02, 0x00, 0x02, 0x24, -0x18, 0x00, 0xA4, 0x27, 0x00, 0x00, 0x72, 0xA2, 0x00, 0x00, 0x62, 0xA2, -0x8A, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x8E, -0x04, 0x00, 0x03, 0x8E, 0x21, 0x20, 0x00, 0x02, 0x00, 0x00, 0x62, 0xAC, -0x04, 0x00, 0x43, 0xAC, 0x00, 0x00, 0x10, 0xAE, 0x74, 0x21, 0x00, 0x0C, -0x04, 0x00, 0x10, 0xAE, 0x90, 0x40, 0x00, 0x0C, 0x18, 0x00, 0xA4, 0x27, -0x00, 0x00, 0x22, 0x8E, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x51, 0x14, -0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xA2, 0x8F, 0x00, 0x00, 0x00, 0x00, -0x07, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, -0xEC, 0x5D, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x40, 0x14, -0x1C, 0x00, 0xA0, 0xAF, 0x02, 0x80, 0x02, 0x3C, 0x08, 0x08, 0x44, 0x24, -0x21, 0x28, 0x00, 0x00, 0x21, 0x30, 0x00, 0x00, 0x76, 0x39, 0x00, 0x0C, -0x21, 0x38, 0x00, 0x00, 0x15, 0x1A, 0x00, 0x08, 0x02, 0x80, 0x02, 0x3C, -0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x06, 0x3C, -0xEE, 0x5D, 0xC2, 0x90, 0x01, 0x00, 0x03, 0x24, 0x0F, 0x00, 0x42, 0x30, -0x04, 0x00, 0x42, 0x28, 0x0F, 0x00, 0x40, 0x14, 0x1C, 0x00, 0xA3, 0xAF, -0x02, 0x80, 0x06, 0x3C, 0xC6, 0x5C, 0xC2, 0x90, 0x00, 0x00, 0x00, 0x00, -0x02, 0x00, 0x42, 0x30, 0x12, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x00, 0x08, 0x04, 0x24, 0x00, 0x02, 0x05, 0x3C, 0xC1, 0x43, 0x00, 0x0C, -0x01, 0x00, 0x06, 0x24, 0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x2F, 0x1A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x24, -0x4B, 0x2E, 0x00, 0x0C, 0x01, 0x00, 0x05, 0x24, 0x02, 0x80, 0x06, 0x3C, -0xC6, 0x5C, 0xC2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x30, -0xF0, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x2D, 0x00, 0x0C, -0x01, 0x00, 0x04, 0x24, 0x8A, 0x1A, 0x00, 0x08, 0x00, 0x08, 0x04, 0x24, -0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x06, 0x3C, -0xED, 0x5D, 0xC4, 0x90, 0x01, 0x00, 0x05, 0x24, 0x4B, 0x2E, 0x00, 0x0C, -0xFF, 0x00, 0x84, 0x30, 0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x73, 0x1A, 0x00, 0x08, 0x02, 0x80, 0x02, 0x3C, 0x4B, 0x1A, 0x00, 0x08, -0xC2, 0x10, 0x02, 0x00, 0x10, 0x00, 0xE0, 0x18, 0x21, 0x18, 0x00, 0x00, -0x00, 0x00, 0xC0, 0xAC, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0x82, 0x90, -0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x45, 0x10, 0x21, 0x18, 0x80, 0x00, -0x01, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x21, 0x18, 0x48, 0x00, -0x02, 0x00, 0x68, 0x24, 0x21, 0x10, 0x82, 0x00, 0x2B, 0x18, 0x07, 0x01, -0xF5, 0xFF, 0x60, 0x14, 0x02, 0x00, 0x44, 0x24, 0x21, 0x18, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, 0x01, 0x00, 0x82, 0x90, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2, 0xAC, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0x60, 0x00, 0x02, 0x80, 0x07, 0x3C, 0x60, 0x1B, 0xE5, 0x24, -0xCE, 0x40, 0xA3, 0x90, 0xFF, 0x00, 0x84, 0x30, 0x80, 0x10, 0x04, 0x00, -0x0C, 0x00, 0x60, 0x14, 0x21, 0x30, 0x45, 0x00, 0xC8, 0x00, 0x02, 0x24, -0x20, 0x3A, 0xA2, 0xAC, 0x01, 0x00, 0x03, 0x24, 0x60, 0x1B, 0xE2, 0x24, -0x04, 0x18, 0x83, 0x00, 0xF8, 0x40, 0xA4, 0xA0, 0xCE, 0x40, 0x44, 0x90, -0x00, 0x00, 0x00, 0x00, 0x25, 0x18, 0x64, 0x00, 0x08, 0x00, 0xE0, 0x03, -0xCE, 0x40, 0x43, 0xA0, 0x20, 0x3A, 0xA3, 0x8C, 0xC8, 0x00, 0x02, 0x24, -0x23, 0x10, 0x43, 0x00, 0xD0, 0x40, 0xC2, 0xAC, 0x01, 0x00, 0x03, 0x24, -0x60, 0x1B, 0xE2, 0x24, 0x04, 0x18, 0x83, 0x00, 0xCE, 0x40, 0x44, 0x90, -0x00, 0x00, 0x00, 0x00, 0x25, 0x18, 0x64, 0x00, 0x08, 0x00, 0xE0, 0x03, -0xCE, 0x40, 0x43, 0xA0, 0xE0, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF, -0x02, 0x80, 0x11, 0x3C, 0x10, 0x00, 0xB0, 0xAF, 0x18, 0x00, 0xBF, 0xAF, -0x60, 0x1B, 0x25, 0x26, 0xF8, 0x40, 0xA6, 0x90, 0x01, 0x00, 0x02, 0x24, -0x04, 0x10, 0xC2, 0x00, 0x06, 0x00, 0x40, 0x14, 0xC9, 0x00, 0x10, 0x24, -0xC6, 0x40, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, -0x23, 0x00, 0x40, 0x14, 0x21, 0x20, 0xC5, 0x00, 0x02, 0x80, 0x02, 0x3C, -0x60, 0x1B, 0x46, 0x24, 0x21, 0x20, 0x00, 0x00, 0xD0, 0x40, 0xC5, 0x24, -0x00, 0x00, 0xA2, 0x8C, 0x04, 0x00, 0xA5, 0x24, 0x05, 0x00, 0x40, 0x10, -0x2B, 0x18, 0x50, 0x00, 0x03, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, -0x21, 0x80, 0x40, 0x00, 0xF8, 0x40, 0xC4, 0xA0, 0x01, 0x00, 0x84, 0x24, -0x08, 0x00, 0x82, 0x2C, 0xF5, 0xFF, 0x40, 0x14, 0xC9, 0x00, 0x02, 0x24, -0x21, 0x00, 0x02, 0x12, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x45, 0x24, -0x07, 0x00, 0x04, 0x24, 0xD0, 0x40, 0xA2, 0x8C, 0xFF, 0xFF, 0x84, 0x24, -0x02, 0x00, 0x40, 0x10, 0x23, 0x18, 0x50, 0x00, 0xD0, 0x40, 0xA3, 0xAC, -0xFA, 0xFF, 0x81, 0x04, 0x04, 0x00, 0xA5, 0x24, 0x60, 0x1B, 0x22, 0x26, -0x20, 0x3A, 0x50, 0xAC, 0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0xF0, 0x40, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x63, 0x24, -0xFF, 0x00, 0x62, 0x30, 0x03, 0x00, 0x42, 0x2C, 0xD8, 0xFF, 0x40, 0x10, -0xF0, 0x40, 0x83, 0xA0, 0x80, 0x18, 0x06, 0x00, 0x21, 0x18, 0x65, 0x00, -0xC8, 0x00, 0x02, 0x24, 0x03, 0x00, 0x04, 0x24, 0x21, 0x28, 0x00, 0x00, -0xD9, 0x12, 0x00, 0x0C, 0xD0, 0x40, 0x62, 0xAC, 0xF2, 0x1A, 0x00, 0x08, -0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x22, 0x26, 0x18, 0x00, 0xBF, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x20, 0x00, 0xBD, 0x27, -0xCE, 0x40, 0x40, 0xA0, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x3A, 0x40, 0xAC, -0xB8, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x08, 0x3C, 0x02, 0x80, 0x0B, 0x3C, -0x02, 0x80, 0x0C, 0x3C, 0x40, 0x00, 0xBF, 0xAF, 0x3C, 0x00, 0xB5, 0xAF, -0x38, 0x00, 0xB4, 0xAF, 0x34, 0x00, 0xB3, 0xAF, 0x30, 0x00, 0xB2, 0xAF, -0x2C, 0x00, 0xB1, 0xAF, 0x28, 0x00, 0xB0, 0xAF, 0xE4, 0xEE, 0x63, 0x25, -0xE0, 0xEE, 0x02, 0x25, 0xE8, 0xEE, 0x84, 0x25, 0x01, 0x00, 0x45, 0x90, -0x01, 0x00, 0x66, 0x90, 0x01, 0x00, 0x87, 0x90, 0xE0, 0xEE, 0x0F, 0x91, -0x02, 0x00, 0x4A, 0x90, 0xE4, 0xEE, 0x6E, 0x91, 0x02, 0x00, 0x69, 0x90, -0xE8, 0xEE, 0x8D, 0x91, 0x02, 0x00, 0x88, 0x90, 0x03, 0x00, 0x4B, 0x90, -0x03, 0x00, 0x6C, 0x90, 0x03, 0x00, 0x82, 0x90, 0x00, 0x2A, 0x05, 0x00, -0x00, 0x32, 0x06, 0x00, 0x00, 0x3A, 0x07, 0x00, 0x25, 0x28, 0xAF, 0x00, -0x25, 0x30, 0xCE, 0x00, 0x25, 0x38, 0xED, 0x00, 0x00, 0x54, 0x0A, 0x00, -0x00, 0x4C, 0x09, 0x00, 0x00, 0x44, 0x08, 0x00, 0x25, 0x50, 0x45, 0x01, -0x25, 0x48, 0x26, 0x01, 0x25, 0x40, 0x07, 0x01, 0x00, 0x5E, 0x0B, 0x00, -0x00, 0x66, 0x0C, 0x00, 0x00, 0x16, 0x02, 0x00, 0x02, 0x80, 0x04, 0x3C, -0x25, 0x58, 0x6A, 0x01, 0x25, 0x60, 0x89, 0x01, 0x25, 0x10, 0x48, 0x00, -0xB0, 0x55, 0x84, 0x24, 0x10, 0x00, 0xAB, 0xAF, 0x18, 0x00, 0xAC, 0xAF, -0x18, 0x52, 0x00, 0x0C, 0x20, 0x00, 0xA2, 0xAF, 0x10, 0x00, 0x42, 0x30, -0x29, 0x00, 0x40, 0x10, 0x21, 0x18, 0x00, 0x00, 0x02, 0x80, 0x13, 0x3C, -0x60, 0x1B, 0x63, 0x26, 0xC0, 0x3A, 0x62, 0x8C, 0x0C, 0x00, 0x10, 0x24, -0x2B, 0x10, 0x02, 0x02, 0x2C, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C, -0x02, 0x80, 0x03, 0x3C, 0x24, 0x56, 0x51, 0x24, 0x2E, 0x56, 0x72, 0x24, -0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0x26, 0x56, 0x54, 0x24, -0x7C, 0x1B, 0x00, 0x08, 0x32, 0x56, 0x75, 0x24, 0xDD, 0x00, 0x02, 0x24, -0x21, 0x20, 0x14, 0x02, 0x2B, 0x00, 0x62, 0x10, 0x10, 0x00, 0xA5, 0x27, -0x21, 0x10, 0x11, 0x02, 0x01, 0x00, 0x43, 0x90, 0x60, 0x1B, 0x64, 0x26, -0xC0, 0x3A, 0x82, 0x8C, 0x21, 0x18, 0x70, 0x00, 0x02, 0x00, 0x70, 0x24, -0x2B, 0x10, 0x02, 0x02, 0x17, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, -0x21, 0x10, 0x11, 0x02, 0x00, 0x00, 0x43, 0x90, 0x30, 0x00, 0x02, 0x24, -0x21, 0x20, 0x12, 0x02, 0x20, 0x00, 0xA5, 0x27, 0xED, 0xFF, 0x62, 0x14, -0x04, 0x00, 0x06, 0x24, 0x1D, 0x55, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0xEE, 0xFF, 0x40, 0x14, 0x21, 0x10, 0x11, 0x02, 0x01, 0x00, 0x03, 0x24, -0x40, 0x00, 0xBF, 0x8F, 0x3C, 0x00, 0xB5, 0x8F, 0x38, 0x00, 0xB4, 0x8F, -0x34, 0x00, 0xB3, 0x8F, 0x30, 0x00, 0xB2, 0x8F, 0x2C, 0x00, 0xB1, 0x8F, -0x28, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x48, 0x00, 0xBD, 0x27, 0x40, 0x00, 0xBF, 0x8F, 0x3C, 0x00, 0xB5, 0x8F, -0x38, 0x00, 0xB4, 0x8F, 0x34, 0x00, 0xB3, 0x8F, 0x30, 0x00, 0xB2, 0x8F, -0x2C, 0x00, 0xB1, 0x8F, 0x28, 0x00, 0xB0, 0x8F, 0x21, 0x18, 0x00, 0x00, -0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x48, 0x00, 0xBD, 0x27, -0x1D, 0x55, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x15, 0x02, -0x18, 0x00, 0xA5, 0x27, 0xD1, 0xFF, 0x40, 0x14, 0x04, 0x00, 0x06, 0x24, -0x1D, 0x55, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xFF, 0x40, 0x14, -0x21, 0x10, 0x11, 0x02, 0x88, 0x1B, 0x00, 0x08, 0x01, 0x00, 0x03, 0x24, -0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x65, 0x24, 0xB0, 0x1B, 0xA2, 0x94, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x34, 0x08, 0x00, 0x40, 0x10, -0x70, 0x17, 0x04, 0x24, 0xB6, 0x40, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00, -0xFB, 0xFF, 0x42, 0x24, 0xFF, 0x00, 0x42, 0x30, 0x02, 0x00, 0x42, 0x2C, -0x0A, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x40, 0xA3, 0x94, -0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x03, 0x00, 0x70, 0x17, 0x62, 0x28, -0x04, 0x00, 0x40, 0x14, 0x70, 0x17, 0x04, 0x24, 0x21, 0x4E, 0x62, 0x28, -0x20, 0x4E, 0x04, 0x24, 0x0B, 0x20, 0x62, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0x80, 0x00, 0x21, 0x38, 0x80, 0x00, 0x08, 0x00, 0xC0, 0x10, -0xFF, 0xFF, 0xC3, 0x24, 0xFF, 0xFF, 0x06, 0x24, 0x00, 0x00, 0xA2, 0x8C, -0xFF, 0xFF, 0x63, 0x24, 0x04, 0x00, 0xA5, 0x24, 0x00, 0x00, 0xE2, 0xAC, -0xFB, 0xFF, 0x66, 0x14, 0x04, 0x00, 0xE7, 0x24, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0x80, 0x00, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, -0x40, 0x32, 0x10, 0xF0, 0x00, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x00, 0xF3, -0x18, 0x4A, 0x2D, 0xF7, 0x19, 0x4B, 0xF9, 0x63, 0x60, 0xDA, 0x00, 0x6A, -0x0C, 0x62, 0x0B, 0xD1, 0x0A, 0xD0, 0x07, 0xD2, 0xC9, 0xF7, 0x1B, 0x6A, -0x4B, 0xEA, 0x40, 0x31, 0x20, 0x31, 0x10, 0xF0, 0x00, 0x6A, 0x00, 0xF4, -0x40, 0x32, 0x10, 0xF3, 0x68, 0x41, 0x2D, 0xF7, 0x19, 0x4A, 0x40, 0xDB, -0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, -0x66, 0xF7, 0x48, 0xAB, 0x01, 0x4A, 0x66, 0xF7, 0x48, 0xCB, 0x00, 0x1C, -0x9B, 0x40, 0x00, 0x65, 0xC0, 0xF0, 0x46, 0x41, 0x40, 0xAA, 0x11, 0x5A, -0x12, 0x61, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x10, 0xF0, -0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, 0xAB, 0xF5, 0x50, 0x9C, 0xCB, 0xF5, -0x68, 0x9D, 0x6D, 0xEA, 0xAB, 0xF5, 0x50, 0xDC, 0x00, 0x6A, 0xCB, 0xF5, -0x48, 0xDD, 0x00, 0x1C, 0x96, 0x40, 0x00, 0x65, 0x70, 0xF3, 0x60, 0x41, -0xE0, 0x9B, 0x06, 0x27, 0x07, 0x92, 0xFF, 0xF7, 0x1F, 0x6C, 0x01, 0x4A, -0x8C, 0xEA, 0x07, 0xD2, 0xFF, 0x6D, 0x01, 0x4D, 0xA0, 0x36, 0xC0, 0x30, -0x4F, 0x40, 0xE3, 0xEA, 0x0D, 0x65, 0x80, 0xF0, 0x1E, 0x60, 0xFF, 0x6A, -0x01, 0x4A, 0x4B, 0xEA, 0x40, 0x35, 0xA0, 0x35, 0xF0, 0xF0, 0x4F, 0x45, -0x62, 0x67, 0x2A, 0x65, 0x00, 0xF3, 0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x34, -0x80, 0x34, 0x47, 0x44, 0xEC, 0xEB, 0x11, 0x4A, 0x4A, 0xEB, 0x80, 0xF0, -0x17, 0x60, 0x63, 0xEA, 0xA0, 0xF0, 0x04, 0x61, 0x01, 0xF6, 0x00, 0x6A, -0x4B, 0xEA, 0x40, 0x35, 0xA0, 0x35, 0x41, 0x45, 0x4A, 0xEB, 0xC0, 0xF0, -0x04, 0x60, 0x63, 0xEA, 0x00, 0xF1, 0x09, 0x61, 0x02, 0xF0, 0x00, 0x6A, -0x4B, 0xEA, 0x40, 0x34, 0x80, 0x34, 0x43, 0x44, 0x4A, 0xEB, 0x40, 0xF1, -0x17, 0x60, 0x63, 0xEA, 0xC0, 0xF1, 0x18, 0x61, 0x8A, 0xEB, 0x00, 0xF3, -0x12, 0x60, 0x63, 0xEC, 0x80, 0xF3, 0x08, 0x61, 0x04, 0xF0, 0x00, 0x6A, -0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x6E, 0xEA, 0xE0, 0xF3, 0x12, 0x22, -0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x00, 0x6B, -0x60, 0xF3, 0x10, 0x4A, 0x60, 0xDA, 0x07, 0xD3, 0xC9, 0xF7, 0x1B, 0x68, -0x0B, 0xE8, 0x00, 0x30, 0x00, 0x30, 0x10, 0xF0, 0x00, 0x6A, 0x00, 0xF4, -0x40, 0x32, 0x10, 0xF3, 0x68, 0x40, 0x2E, 0xF0, 0x19, 0x4A, 0x40, 0xDB, -0x10, 0xF0, 0x02, 0x68, 0x00, 0xF4, 0x00, 0x30, 0x00, 0x1C, 0x9B, 0x40, -0xFF, 0x69, 0x63, 0xF3, 0x00, 0x48, 0x10, 0x10, 0xC9, 0xF7, 0x1B, 0x6D, -0xAB, 0xED, 0xA0, 0x35, 0xA0, 0x35, 0x7F, 0x4D, 0x40, 0x4D, 0x40, 0xA5, -0x2C, 0xEA, 0x04, 0x5A, 0x0F, 0x60, 0x27, 0xF1, 0x90, 0x98, 0x00, 0x1C, -0xF5, 0x09, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, -0x8A, 0xF4, 0x10, 0x4C, 0x00, 0x1C, 0x6A, 0x58, 0x00, 0x65, 0xE6, 0x22, -0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0xEB, 0xF5, 0x4E, 0xA3, -0x0F, 0x6B, 0xFF, 0x6C, 0x6C, 0xEA, 0x02, 0x72, 0x0B, 0x61, 0x10, 0xF0, -0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, 0xEB, 0xF5, 0x4D, 0xA5, 0x8C, 0xEA, -0x6C, 0xEA, 0x01, 0x72, 0x40, 0xF4, 0x00, 0x60, 0x00, 0x1C, 0x96, 0x40, -0x00, 0x65, 0x00, 0x6D, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, -0x02, 0xF0, 0x08, 0x4C, 0xC5, 0x67, 0x00, 0x1C, 0x76, 0x39, 0xE5, 0x67, -0x19, 0x17, 0x07, 0x94, 0x0A, 0xF0, 0x00, 0x5C, 0xA5, 0x61, 0x00, 0x6A, -0x40, 0xDB, 0x07, 0xD2, 0x01, 0x6A, 0x70, 0xF3, 0x64, 0x41, 0x4B, 0xEA, -0x40, 0xDB, 0x9C, 0x17, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, -0x0C, 0xF0, 0x00, 0x6A, 0x63, 0xF3, 0x00, 0x4D, 0x4B, 0xEA, 0x62, 0x9D, -0x40, 0x32, 0x40, 0x32, 0xFF, 0x4A, 0x4C, 0xEB, 0x62, 0xDD, 0x82, 0x17, -0xA0, 0xF0, 0x4C, 0x44, 0x4A, 0xEB, 0x00, 0xF4, 0x17, 0x60, 0x63, 0xEA, -0x39, 0x61, 0xA0, 0xF0, 0x42, 0x44, 0x4A, 0xEB, 0x20, 0xF4, 0x0D, 0x60, -0x63, 0xEA, 0xE0, 0xF0, 0x02, 0x61, 0x47, 0x44, 0x21, 0x4A, 0x4A, 0xEB, -0x40, 0xF4, 0x11, 0x60, 0x63, 0xEA, 0xC0, 0xF1, 0x1D, 0x61, 0x47, 0x44, -0x12, 0x4A, 0x6E, 0xEA, 0x7F, 0xF7, 0x06, 0x2A, 0xC9, 0xF7, 0x1B, 0x6A, -0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x00, 0x6B, 0x60, 0xF3, 0x10, 0x4A, -0x60, 0xDA, 0x00, 0x18, 0x12, 0x27, 0x87, 0x67, 0x59, 0x17, 0x70, 0xF3, -0x44, 0x41, 0xE0, 0x9A, 0x02, 0xF0, 0x00, 0x6A, 0x40, 0x32, 0x40, 0x32, -0xFF, 0x4A, 0x4C, 0xEF, 0xE3, 0xEE, 0x5F, 0xF7, 0x0D, 0x60, 0x0A, 0xF0, -0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x4D, 0xEF, 0x70, 0xF3, -0x48, 0x41, 0xC0, 0x9A, 0xC0, 0xDF, 0x42, 0x17, 0x00, 0xF2, 0x00, 0x6A, -0x4B, 0xEA, 0x40, 0x36, 0xC0, 0x36, 0x47, 0x46, 0x0B, 0x4A, 0x4A, 0xEB, -0xC0, 0xF3, 0x17, 0x60, 0x63, 0xEA, 0xC0, 0xF0, 0x01, 0x61, 0xA0, 0xF0, -0x4F, 0x44, 0x4A, 0xEB, 0x20, 0xF4, 0x15, 0x60, 0x63, 0xEA, 0x60, 0xF1, -0x18, 0x61, 0xA0, 0xF0, 0x4D, 0x44, 0x6E, 0xEA, 0x60, 0xF4, 0x09, 0x22, -0xA0, 0xF0, 0x4E, 0x44, 0x6E, 0xEA, 0x3F, 0xF7, 0x03, 0x2A, 0x1F, 0xF7, -0x00, 0x6A, 0xE2, 0x34, 0x4C, 0xEC, 0x4C, 0xEF, 0x82, 0x34, 0x00, 0x18, -0x3B, 0x5D, 0xE2, 0x35, 0xC9, 0xF7, 0x1B, 0x6B, 0x6B, 0xEB, 0x60, 0x33, -0x60, 0x33, 0x60, 0xF3, 0x14, 0x4B, 0x40, 0xC3, 0x11, 0x17, 0x01, 0xF0, -0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x35, 0xA0, 0x35, 0x47, 0x45, 0x0F, 0x4A, -0x4A, 0xEB, 0xC0, 0xF3, 0x1A, 0x60, 0x63, 0xEA, 0xA0, 0xF0, 0x19, 0x61, -0x01, 0xF4, 0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x4A, 0xEB, -0x00, 0xF4, 0x06, 0x60, 0x63, 0xEA, 0xE0, 0xF1, 0x13, 0x61, 0x01, 0xF5, -0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x6E, 0xEA, 0xFF, 0xF6, -0x11, 0x2A, 0x1F, 0xF7, 0x00, 0x6A, 0xEC, 0xEA, 0x42, 0x30, 0x01, 0xF7, -0x00, 0x6B, 0xE2, 0x32, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, -0x6C, 0xEA, 0x63, 0xF3, 0x00, 0x4D, 0x42, 0x36, 0x28, 0xF1, 0xDB, 0xC5, -0x20, 0xF3, 0x06, 0x26, 0xA3, 0xF3, 0x50, 0xAD, 0x10, 0xF0, 0x00, 0x6B, -0x6B, 0xEB, 0x10, 0xF0, 0x00, 0x6C, 0x6D, 0xEA, 0xA3, 0xF3, 0x50, 0xCD, -0x1E, 0xF0, 0x00, 0x6A, 0x40, 0x32, 0x4C, 0xEF, 0xFF, 0x6A, 0x4C, 0xE8, -0x00, 0xF5, 0xE2, 0x31, 0x4C, 0xEE, 0x00, 0x1C, 0x3C, 0x0E, 0xB0, 0x67, -0x90, 0x67, 0x00, 0x1C, 0x38, 0x0D, 0xB1, 0x67, 0xC9, 0xF7, 0x1B, 0x6A, -0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF3, 0x10, 0x4A, 0x00, 0x6B, -0x60, 0xDA, 0xBA, 0x16, 0x1F, 0xF7, 0x00, 0x6B, 0xE2, 0x32, 0x6C, 0xEA, -0x42, 0x32, 0xEC, 0xEB, 0x06, 0xD2, 0x62, 0x37, 0x80, 0xF3, 0x08, 0x22, -0x01, 0x72, 0x01, 0x6C, 0x01, 0x60, 0x00, 0x6C, 0x00, 0x1C, 0xF0, 0x42, -0x09, 0xD7, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, -0x09, 0x97, 0x70, 0xF3, 0x24, 0x42, 0xC0, 0x99, 0x02, 0xF0, 0x00, 0x68, -0x00, 0x30, 0x87, 0x67, 0xAF, 0x40, 0x00, 0x1C, 0x83, 0x45, 0x09, 0xD7, -0x09, 0x97, 0xAF, 0x40, 0x00, 0x1C, 0xAC, 0x45, 0x87, 0x67, 0x40, 0xD9, -0x91, 0x16, 0xA0, 0xF0, 0x45, 0x44, 0x4A, 0xEB, 0x60, 0xF3, 0x06, 0x60, -0x63, 0xEA, 0x00, 0xF1, 0x0D, 0x61, 0xA0, 0xF0, 0x43, 0x44, 0x6E, 0xEA, -0x40, 0xF1, 0x02, 0x22, 0xA0, 0xF0, 0x44, 0x44, 0x6E, 0xEA, 0x7F, 0xF6, -0x1F, 0x2A, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, -0x00, 0x4B, 0xFF, 0xF7, 0x1F, 0x6A, 0x27, 0xF1, 0x44, 0xDB, 0x74, 0x16, -0x47, 0x46, 0x13, 0x4A, 0x4A, 0xEB, 0x80, 0xF0, 0x16, 0x60, 0x63, 0xEA, -0x00, 0xF1, 0x1B, 0x61, 0x47, 0x46, 0x11, 0x4A, 0x6E, 0xEA, 0xE0, 0xF3, -0x05, 0x22, 0x47, 0x46, 0x12, 0x4A, 0x6E, 0xEA, 0x7F, 0xF6, 0x02, 0x2A, -0x00, 0x1C, 0x9B, 0x40, 0x00, 0x65, 0xC9, 0xF7, 0x1B, 0x6A, 0x10, 0xF0, -0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x4B, 0xEA, 0x63, 0xF3, 0x00, 0x4B, -0x40, 0x32, 0x23, 0xF4, 0x6A, 0xA3, 0x40, 0x32, 0x60, 0xF3, 0x14, 0x4A, -0x60, 0xDA, 0x00, 0x1C, 0x96, 0x40, 0x00, 0x65, 0x4B, 0x16, 0x47, 0x44, -0x4A, 0xEB, 0x80, 0xF3, 0x03, 0x60, 0x63, 0xEA, 0x00, 0xF1, 0x0C, 0x61, -0x47, 0x45, 0x10, 0x4A, 0x6E, 0xEA, 0xC0, 0xF3, 0x11, 0x22, 0x47, 0x45, -0x11, 0x4A, 0x6E, 0xEA, 0x3F, 0xF6, 0x1A, 0x2A, 0x00, 0x1C, 0x2B, 0x20, -0x00, 0x65, 0x36, 0x16, 0x01, 0xF7, 0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x36, -0xC0, 0x36, 0x42, 0x46, 0x4A, 0xEB, 0x3F, 0xF6, 0x0D, 0x60, 0x63, 0xEA, -0x80, 0xF1, 0x04, 0x61, 0x47, 0x44, 0x01, 0x4A, 0x6E, 0xEA, 0xE0, 0xF1, -0x01, 0x22, 0x43, 0x67, 0xCE, 0xEA, 0x3F, 0xF6, 0x01, 0x2A, 0xFF, 0x6A, -0x01, 0x4A, 0x40, 0x32, 0x40, 0x32, 0x80, 0x4A, 0x80, 0x4A, 0x4C, 0xEF, -0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0xE2, 0x33, 0x63, 0xF3, -0x00, 0x4C, 0xA3, 0xF3, 0x7A, 0xCC, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, -0x80, 0x34, 0x80, 0x34, 0x90, 0xF0, 0x44, 0x44, 0x60, 0xCA, 0x90, 0xF0, -0xAA, 0x44, 0x00, 0xF4, 0x00, 0x6A, 0x40, 0xCD, 0x90, 0xF0, 0xA8, 0x44, -0xA0, 0x6A, 0x40, 0xCD, 0xC9, 0xF7, 0x1A, 0x6D, 0xAB, 0xED, 0xA0, 0x35, -0x04, 0x6E, 0x90, 0xF0, 0x46, 0x44, 0xA0, 0x35, 0xC0, 0xCA, 0x47, 0x45, -0x73, 0x4A, 0xC0, 0xC2, 0xFF, 0xF7, 0x1F, 0x6A, 0x4C, 0xEB, 0x74, 0x33, -0xC8, 0x43, 0xC8, 0x4E, 0xB0, 0xF3, 0x40, 0x44, 0xC0, 0xDA, 0x60, 0xF0, -0xDC, 0xCD, 0x40, 0xF0, 0x64, 0xAC, 0x00, 0xF2, 0x01, 0x6A, 0x4B, 0xEA, -0x6C, 0xEA, 0x40, 0xF0, 0x44, 0xCC, 0x40, 0xF0, 0x64, 0xAC, 0x00, 0xF2, -0x00, 0x6A, 0x6D, 0xEA, 0x40, 0xF0, 0x44, 0xCC, 0xD9, 0x15, 0x0F, 0xF7, -0x40, 0x40, 0x4C, 0xEF, 0xE2, 0x37, 0x87, 0x67, 0xFF, 0xF7, 0x1F, 0x6D, -0xAC, 0xEC, 0x01, 0x74, 0x06, 0xD4, 0xA0, 0xF0, 0x18, 0x60, 0x02, 0x54, -0x20, 0xF3, 0x13, 0x61, 0x06, 0x92, 0x03, 0x72, 0xE0, 0xF1, 0x19, 0x60, -0xC9, 0xF7, 0x1B, 0x6A, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, -0x4B, 0xEA, 0x63, 0xF3, 0x00, 0x4B, 0x40, 0x32, 0x23, 0xF4, 0x64, 0xAB, -0x40, 0x32, 0x60, 0xF3, 0x14, 0x4A, 0x60, 0xDA, 0xB5, 0x15, 0x47, 0x46, -0x09, 0x4A, 0x6E, 0xEA, 0xE0, 0xF2, 0x16, 0x22, 0x47, 0x46, 0x0A, 0x4A, -0x6E, 0xEA, 0xBF, 0xF5, 0x0B, 0x2A, 0x00, 0x1C, 0x9B, 0x40, 0x09, 0xD7, -0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x00, 0x6A, 0x63, 0xF3, -0x00, 0x4B, 0x23, 0xF4, 0x4A, 0xC3, 0xFF, 0x6A, 0x01, 0x4A, 0x40, 0x32, -0x40, 0x32, 0x09, 0x97, 0x80, 0x4A, 0x80, 0x4A, 0x4C, 0xEF, 0xE0, 0x34, -0x82, 0x34, 0x00, 0x1C, 0xA3, 0x31, 0x82, 0x34, 0x00, 0x1C, 0x96, 0x40, -0x00, 0x65, 0x8E, 0x15, 0xA0, 0xF0, 0x40, 0x44, 0x6E, 0xEA, 0x80, 0xF0, -0x1B, 0x22, 0xA0, 0xF0, 0x41, 0x44, 0x6E, 0xEA, 0x9F, 0xF5, 0x04, 0x2A, -0xE2, 0x34, 0x1F, 0xF7, 0x00, 0x6A, 0x4C, 0xEC, 0x00, 0x18, 0x11, 0x22, -0x82, 0x34, 0x7C, 0x15, 0xA0, 0xF0, 0x46, 0x44, 0x6E, 0xEA, 0xC0, 0xF2, -0x1B, 0x22, 0xA0, 0xF0, 0x47, 0x44, 0x6E, 0xEA, 0x7F, 0xF5, 0x12, 0x2A, -0x1F, 0xF7, 0x00, 0x6A, 0xE2, 0x33, 0x4C, 0xEF, 0xE2, 0x36, 0x4C, 0xEB, -0x01, 0x76, 0x62, 0x35, 0xA0, 0xF1, 0x17, 0x61, 0xAC, 0x32, 0xA9, 0xE2, -0x48, 0x32, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0xA9, 0xE2, -0xC9, 0xF7, 0x1B, 0x6B, 0x63, 0xF3, 0x00, 0x4C, 0x48, 0x32, 0x6B, 0xEB, -0x89, 0xE2, 0x60, 0x33, 0x04, 0xF5, 0x40, 0x9A, 0x60, 0x33, 0x60, 0xF3, -0x14, 0x4B, 0x40, 0xDB, 0x51, 0x15, 0x47, 0x45, 0x08, 0x4A, 0x6E, 0xEA, -0x71, 0x22, 0x47, 0x45, 0x09, 0x4A, 0x6E, 0xEA, 0x5F, 0xF5, 0x08, 0x2A, -0x1F, 0xF7, 0x00, 0x6A, 0x4C, 0xEF, 0x4A, 0xEF, 0xDF, 0xF6, 0x03, 0x60, -0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, -0x00, 0x6A, 0x27, 0xF1, 0x44, 0xDB, 0x38, 0x15, 0x47, 0x44, 0x0D, 0x4A, -0x6E, 0xEA, 0x69, 0x22, 0x47, 0x44, 0x10, 0x4A, 0x6E, 0xEA, 0x3F, 0xF5, -0x0F, 0x2A, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, -0x60, 0xF3, 0xA8, 0x44, 0x60, 0x9D, 0xFF, 0xF7, 0x1F, 0x6A, 0x60, 0xF3, -0x04, 0x4C, 0x4C, 0xEB, 0x1F, 0xF7, 0x00, 0x6A, 0x4C, 0xEF, 0xE0, 0x32, -0x6D, 0xEA, 0x40, 0xDD, 0x60, 0xA4, 0xFF, 0x6A, 0x6C, 0xEA, 0x40, 0x6B, -0x6D, 0xEA, 0x40, 0xC4, 0x15, 0x15, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, -0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, 0x23, 0xF4, 0x42, 0xAA, 0xFF, 0xF7, -0x1F, 0x6D, 0x70, 0xF3, 0x64, 0x41, 0xAC, 0xEA, 0x40, 0xDB, 0x06, 0x15, -0x01, 0x4A, 0x6E, 0xEA, 0xA0, 0xF0, 0x0D, 0x22, 0x47, 0x45, 0x0E, 0x4A, -0x6E, 0xEA, 0xFF, 0xF4, 0x1D, 0x2A, 0x00, 0x1C, 0xAE, 0x1F, 0x00, 0x65, -0xF9, 0x14, 0x0F, 0xF7, 0x40, 0x40, 0xEC, 0xEA, 0x42, 0x37, 0x2D, 0xE7, -0xC0, 0x9B, 0x70, 0xF3, 0x44, 0x41, 0xC0, 0xDA, 0xC0, 0x9B, 0xEE, 0x14, -0x01, 0xF7, 0x00, 0x6A, 0x4C, 0xEF, 0xE2, 0x32, 0x01, 0x72, 0x01, 0x6C, -0x07, 0x60, 0x02, 0x72, 0x02, 0x6C, 0x04, 0x60, 0x03, 0x72, 0x03, 0x6C, -0x01, 0x60, 0x00, 0x6C, 0x00, 0x18, 0x92, 0x5D, 0x00, 0x65, 0xDC, 0x14, -0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF1, -0x16, 0x4A, 0xFF, 0x6B, 0x60, 0xCA, 0x01, 0x6A, 0x10, 0xF0, 0x02, 0x6B, -0x00, 0xF4, 0x60, 0x33, 0xEB, 0xF4, 0x50, 0xC3, 0xCB, 0x14, 0x0F, 0xF7, -0x40, 0x40, 0xEC, 0xEA, 0xDF, 0xF4, 0x06, 0x22, 0x10, 0xF0, 0x02, 0x6B, -0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x00, 0xF3, 0x44, 0x9B, -0xA9, 0x67, 0x88, 0x67, 0xAC, 0xEA, 0x8D, 0xEA, 0x00, 0xF3, 0x44, 0xDB, -0x1F, 0xF7, 0x00, 0x6C, 0xE2, 0x32, 0x8C, 0xEA, 0x42, 0x32, 0x00, 0xF3, -0x5C, 0xC3, 0x8C, 0xEF, 0xFB, 0x4A, 0x00, 0xF3, 0x5D, 0xC3, 0xE2, 0x32, -0x00, 0xF3, 0x5E, 0xC3, 0xFB, 0x4A, 0x00, 0xF3, 0x5F, 0xC3, 0xA6, 0x14, -0x44, 0x46, 0x6E, 0xEA, 0x6D, 0x22, 0x43, 0x67, 0xAE, 0xEA, 0x9F, 0xF4, -0x1F, 0x2A, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x33, 0x60, 0x33, -0x70, 0xF3, 0x44, 0x43, 0xE0, 0x9A, 0x02, 0xF0, 0x00, 0x6A, 0x40, 0x32, -0x40, 0x32, 0xFF, 0x4A, 0x4C, 0xEF, 0xFF, 0x6A, 0x01, 0x4A, 0x40, 0x32, -0xE3, 0xEA, 0x9F, 0xF4, 0x0B, 0x60, 0x0A, 0xF0, 0x00, 0x6A, 0x4B, 0xEA, -0x40, 0x32, 0x40, 0x32, 0x4D, 0xEF, 0xC0, 0x9F, 0x70, 0xF3, 0x48, 0x43, -0xC0, 0xDA, 0x80, 0x14, 0x41, 0x44, 0x6E, 0xEA, 0x5E, 0x22, 0x42, 0x44, -0x6E, 0xEA, 0x7F, 0xF4, 0x19, 0x2A, 0x1F, 0xF7, 0x00, 0x6B, 0xE2, 0x32, -0x6C, 0xEA, 0x42, 0x32, 0xEC, 0xEB, 0x06, 0xD2, 0x62, 0x37, 0x20, 0xF2, -0x0C, 0x22, 0x01, 0x72, 0x01, 0x6C, 0x01, 0x60, 0x00, 0x6C, 0x00, 0x1C, -0xF0, 0x42, 0x09, 0xD7, 0x09, 0x97, 0x02, 0xF0, 0x00, 0x68, 0x00, 0x30, -0xAF, 0x40, 0x00, 0x1C, 0xAC, 0x45, 0x87, 0x67, 0xFF, 0x48, 0x4C, 0xE8, -0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF3, -0x14, 0x4A, 0x00, 0xDA, 0x55, 0x14, 0xC9, 0xF7, 0x1B, 0x6A, 0x10, 0xF0, -0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x4B, 0xEA, 0x63, 0xF3, 0x00, 0x4B, -0x40, 0x32, 0xC4, 0xF7, 0x7C, 0xAB, 0x40, 0x32, 0x60, 0xF3, 0x14, 0x4A, -0x60, 0xDA, 0x44, 0x14, 0x1F, 0xF7, 0x00, 0x6A, 0xEC, 0xEA, 0x42, 0x37, -0x87, 0x67, 0x04, 0x27, 0x01, 0x77, 0x01, 0x6C, 0x01, 0x60, 0x00, 0x6C, -0x00, 0x1C, 0xF0, 0x42, 0x00, 0x65, 0x36, 0x14, 0x1F, 0xF7, 0x00, 0x6B, -0x47, 0x67, 0x6C, 0xEA, 0x42, 0x32, 0x06, 0xD2, 0xE2, 0x32, 0x6C, 0xEA, -0x42, 0x36, 0x07, 0x5E, 0x3F, 0xF4, 0x0A, 0x60, 0x10, 0xF0, 0x02, 0x6B, -0x00, 0xF4, 0x60, 0x33, 0xC8, 0x32, 0x1D, 0xF7, 0x14, 0x4B, 0x69, 0xE2, -0x40, 0x9A, 0x00, 0xEA, 0x00, 0x65, 0x0F, 0xF7, 0x40, 0x40, 0xEC, 0xEA, -0x42, 0x37, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, -0x70, 0xF3, 0x64, 0x42, 0xC0, 0x9B, 0x49, 0xE7, 0xC0, 0xDA, 0xC0, 0x9A, -0xC0, 0xDB, 0x0E, 0x14, 0x1F, 0xF7, 0x00, 0x6A, 0xEC, 0xEA, 0x42, 0x32, -0xFF, 0x72, 0x71, 0x61, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, -0x40, 0x32, 0x60, 0xF3, 0x04, 0x4A, 0x60, 0xAA, 0x88, 0x67, 0x6D, 0xEC, -0x80, 0xCA, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x06, 0xF0, -0x00, 0x6A, 0x63, 0xF3, 0x00, 0x4C, 0x4B, 0xEA, 0xE0, 0xF2, 0x64, 0x9C, -0x40, 0x32, 0x40, 0x32, 0xFF, 0x4A, 0x4C, 0xEB, 0xE0, 0xF2, 0x64, 0xDC, -0x1F, 0xF7, 0x00, 0x6A, 0x4C, 0xEF, 0x19, 0xF4, 0x00, 0x77, 0xFF, 0xF3, -0x05, 0x61, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x06, 0xF0, -0x00, 0x6A, 0x63, 0xF3, 0x00, 0x4C, 0x4B, 0xEA, 0xE0, 0xF2, 0x64, 0x9C, -0x40, 0x32, 0x40, 0x32, 0xFF, 0x4A, 0x4C, 0xEB, 0x02, 0xF0, 0x00, 0x6A, -0x40, 0x32, 0x40, 0x32, 0x4D, 0xEB, 0xE0, 0xF2, 0x64, 0xDC, 0xDF, 0xF3, -0x0D, 0x10, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0xC9, 0xF7, -0x1B, 0x6A, 0x63, 0xF3, 0x00, 0x4B, 0x4B, 0xEA, 0x23, 0xF4, 0x66, 0xAB, -0x40, 0x32, 0x40, 0x32, 0xFF, 0xF7, 0x1F, 0x6C, 0x60, 0xF3, 0x14, 0x4A, -0x8C, 0xEB, 0x60, 0xDA, 0xBF, 0xF3, 0x18, 0x10, 0xA3, 0xF3, 0x50, 0xAD, -0xEF, 0xF7, 0x1F, 0x6B, 0x86, 0x67, 0x6C, 0xEA, 0xDB, 0x14, 0x02, 0x76, -0x27, 0x61, 0xAC, 0x32, 0xA9, 0xE2, 0x48, 0x32, 0x10, 0xF0, 0x02, 0x6C, -0x00, 0xF4, 0x80, 0x34, 0xA9, 0xE2, 0xC9, 0xF7, 0x1B, 0x6B, 0x63, 0xF3, -0x00, 0x4C, 0x48, 0x32, 0x6B, 0xEB, 0x89, 0xE2, 0x60, 0x33, 0x04, 0xF5, -0x44, 0x9A, 0x60, 0x33, 0x60, 0xF3, 0x14, 0x4B, 0x40, 0xDB, 0x9F, 0xF3, -0x17, 0x10, 0xAA, 0x2A, 0xC9, 0xF7, 0x1B, 0x6B, 0x6B, 0xEB, 0x60, 0x33, -0x60, 0x33, 0x60, 0xF3, 0x04, 0x4B, 0x80, 0xAB, 0xFF, 0x6A, 0x02, 0x4A, -0x4B, 0xEA, 0x8C, 0xEA, 0x40, 0xCB, 0x8B, 0x17, 0x03, 0x76, 0x9F, 0xF3, -0x05, 0x61, 0xAC, 0x32, 0xA9, 0xE2, 0x48, 0x32, 0xA9, 0xE2, 0x10, 0xF0, -0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0xC9, 0xF7, 0x1B, 0x6C, 0x48, 0x32, -0x68, 0xF0, 0x08, 0x4B, 0x8B, 0xEC, 0x69, 0xE2, 0x80, 0x34, 0x40, 0x9A, -0x80, 0x34, 0x60, 0xF3, 0x14, 0x4C, 0x40, 0xDC, 0x7F, 0xF3, 0x0E, 0x10, -0xEB, 0xF5, 0x4D, 0xA5, 0x01, 0x6D, 0x00, 0x1C, 0x4B, 0x2E, 0x4C, 0xEC, -0xBF, 0xF3, 0x18, 0x10, 0x00, 0x18, 0x84, 0x5C, 0x87, 0x67, 0x7F, 0xF3, -0x01, 0x10, 0x00, 0x1C, 0x9B, 0x40, 0x09, 0xD7, 0x09, 0x97, 0x0F, 0xF7, -0x40, 0x40, 0xFF, 0xF7, 0x1F, 0x6D, 0x4C, 0xEF, 0xE2, 0x32, 0x10, 0xF0, -0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0xAC, 0xEA, 0x63, 0xF3, 0x00, 0x4B, -0x23, 0xF4, 0x4B, 0xC3, 0x00, 0x1C, 0x96, 0x40, 0x00, 0x65, 0x5F, 0xF3, -0x09, 0x10, 0x0F, 0xF7, 0x40, 0x40, 0x4C, 0xEF, 0xE2, 0x37, 0x87, 0x67, -0xFF, 0xF7, 0x1F, 0x6D, 0xAC, 0xEC, 0x06, 0xD4, 0x70, 0xF3, 0x04, 0x41, -0xA0, 0x98, 0x00, 0x18, 0x63, 0x5E, 0x00, 0x65, 0xC0, 0x98, 0x06, 0x95, -0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x3D, 0xF7, 0x10, 0x4C, -0x00, 0x1C, 0x13, 0x58, 0x00, 0x65, 0x3F, 0xF3, 0x0D, 0x10, 0x00, 0x1C, -0xFA, 0x1F, 0x00, 0x65, 0x3F, 0xF3, 0x08, 0x10, 0x06, 0x94, 0x7A, 0x14, -0xE2, 0x34, 0x1F, 0xF7, 0x00, 0x6A, 0x4C, 0xEC, 0x00, 0x18, 0x8F, 0x5E, -0x82, 0x34, 0x1F, 0xF3, 0x1D, 0x10, 0x02, 0xF0, 0x00, 0x68, 0x00, 0x30, -0x60, 0x6E, 0xAF, 0x40, 0x00, 0x1C, 0x83, 0x45, 0x24, 0x6C, 0xE0, 0xF3, -0x08, 0x6C, 0x00, 0x1C, 0x2C, 0x1F, 0x00, 0x65, 0x00, 0x1C, 0x9B, 0x40, -0x00, 0x65, 0x24, 0x6C, 0x00, 0x1C, 0xAC, 0x45, 0xAF, 0x40, 0x1F, 0x6E, -0x4C, 0xEE, 0x00, 0x1C, 0x96, 0x40, 0x08, 0xD6, 0x00, 0x1C, 0x5B, 0x1F, -0x64, 0x6C, 0x08, 0x96, 0x70, 0xF3, 0x44, 0x41, 0xC0, 0xC2, 0xFF, 0xF2, -0x1B, 0x10, 0x00, 0x18, 0x75, 0x5D, 0x00, 0x65, 0xFF, 0xF2, 0x16, 0x10, -0x0F, 0xF7, 0x40, 0x40, 0x4C, 0xEF, 0xE2, 0x32, 0x01, 0x6B, 0xA2, 0x67, -0x6C, 0xED, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x46, 0x36, -0x6C, 0xEE, 0xDB, 0xF7, 0xA8, 0xDC, 0x4A, 0x37, 0x10, 0xF0, 0x02, 0x6C, -0x00, 0xF4, 0x80, 0x34, 0x4E, 0x32, 0x6C, 0xEA, 0x6C, 0xEF, 0xCB, 0xF4, -0xD9, 0xC4, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x10, 0xF0, -0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0xDB, 0xF7, 0xE4, 0xDC, 0x63, 0xF3, -0x00, 0x4B, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0xC7, 0xF5, -0x47, 0xC3, 0x5D, 0xF7, 0x0C, 0x4C, 0x00, 0x1C, 0x13, 0x58, 0x04, 0xD2, -0xDF, 0xF2, 0x04, 0x10, 0x00, 0x18, 0xED, 0x60, 0x87, 0x67, 0xBF, 0xF2, -0x1F, 0x10, 0x00, 0x18, 0x92, 0x5C, 0x87, 0x67, 0xBF, 0xF2, 0x1A, 0x10, -0x00, 0x1C, 0x9B, 0x40, 0x09, 0xD7, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, -0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x23, 0xF4, 0x4A, 0xA3, 0x09, 0x97, -0x5F, 0xF4, 0x1D, 0x2A, 0x01, 0x6A, 0x23, 0xF4, 0x4A, 0xC3, 0x0F, 0xF7, -0x40, 0x40, 0x4C, 0xEF, 0xE0, 0x32, 0x42, 0x32, 0x42, 0x32, 0x23, 0xF4, -0x4B, 0xC3, 0x82, 0x67, 0x00, 0x1C, 0xA3, 0x31, 0x06, 0xD2, 0x0A, 0x15, -0x00, 0x18, 0x94, 0x5E, 0x00, 0x65, 0x9F, 0xF2, 0x17, 0x10, 0xDF, 0xF4, -0x0F, 0x2C, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0xC9, 0xF7, -0x1B, 0x6A, 0x63, 0xF3, 0x00, 0x4B, 0x4B, 0xEA, 0x23, 0xF4, 0x60, 0xAB, -0x40, 0x32, 0x40, 0x32, 0xFF, 0xF7, 0x1F, 0x6C, 0x60, 0xF3, 0x14, 0x4A, -0x8C, 0xEB, 0xC7, 0x16, 0x00, 0x1C, 0x9B, 0x40, 0x00, 0x65, 0xC9, 0xF7, -0x1B, 0x6A, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x4B, 0xEA, -0x63, 0xF3, 0x00, 0x4B, 0x40, 0x32, 0x23, 0xF4, 0x6B, 0xA3, 0x40, 0x32, -0x60, 0xF3, 0x14, 0x4A, 0x60, 0xDA, 0x1F, 0x14, 0x00, 0x1C, 0x5C, 0x20, -0x00, 0x65, 0x7F, 0xF2, 0x09, 0x10, 0x06, 0x95, 0x10, 0xF0, 0x02, 0x6B, -0x00, 0xF4, 0x60, 0x33, 0xC9, 0xF7, 0x1B, 0x6C, 0xB0, 0x32, 0x63, 0xF3, -0x00, 0x4B, 0x8B, 0xEC, 0x69, 0xE2, 0x80, 0x34, 0x20, 0xF3, 0x55, 0xA2, -0x80, 0x34, 0x60, 0xF3, 0x14, 0x4C, 0xE5, 0x16, 0x06, 0x93, 0xC9, 0xF7, -0x1B, 0x6C, 0x8B, 0xEC, 0x70, 0x32, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, -0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x69, 0xE2, 0x80, 0x34, 0x20, 0xF3, -0x54, 0xA2, 0x80, 0x34, 0x60, 0xF3, 0x14, 0x4C, 0xD2, 0x16, 0x06, 0x94, -0xD6, 0x15, 0x06, 0x93, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x70, 0x32, -0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, -0x69, 0xE2, 0x80, 0x34, 0x20, 0xF3, 0x56, 0xAA, 0x80, 0x34, 0x60, 0xF3, -0x14, 0x4C, 0xBD, 0x16, 0x06, 0x95, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, -0x60, 0x33, 0xC9, 0xF7, 0x1B, 0x6C, 0xB0, 0x32, 0x63, 0xF3, 0x00, 0x4B, -0x8B, 0xEC, 0x69, 0xE2, 0x80, 0x34, 0x20, 0xF3, 0x52, 0xAA, 0x80, 0x34, -0x60, 0xF3, 0x14, 0x4C, 0xAA, 0x16, 0x06, 0x93, 0xC9, 0xF7, 0x1B, 0x6C, -0x8B, 0xEC, 0x70, 0x32, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, -0x63, 0xF3, 0x00, 0x4B, 0x69, 0xE2, 0x80, 0x34, 0x20, 0xF3, 0x50, 0xAA, -0x80, 0x34, 0x60, 0xF3, 0x14, 0x4C, 0x97, 0x16, 0x06, 0x95, 0x10, 0xF0, -0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0xB0, 0x32, -0xC9, 0xF7, 0x1B, 0x6C, 0x69, 0xE2, 0x8B, 0xEC, 0x20, 0xF3, 0x4C, 0x9A, -0x80, 0x34, 0x80, 0x34, 0x60, 0xF3, 0x14, 0x4C, 0x40, 0xF6, 0x42, 0x32, -0x82, 0x16, 0x06, 0x93, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x70, 0x32, -0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, -0x69, 0xE2, 0x20, 0xF3, 0x4F, 0xA2, 0x80, 0x34, 0x80, 0x34, 0x01, 0x6B, -0x60, 0xF3, 0x14, 0x4C, 0x6C, 0xEA, 0x6D, 0x16, 0x00, 0x80, 0x03, 0x3C, -0x25, 0xB0, 0x02, 0x3C, 0x18, 0x03, 0x42, 0x34, 0xB0, 0x7C, 0x63, 0x24, -0x00, 0x00, 0x43, 0xAC, 0x02, 0x80, 0x05, 0x3C, 0xCC, 0x5D, 0xA5, 0x8C, -0x04, 0x00, 0x02, 0x24, 0x1E, 0x00, 0xA2, 0x10, 0x05, 0x00, 0xA2, 0x2C, -0x10, 0x00, 0x40, 0x10, 0x05, 0x00, 0x02, 0x24, 0x03, 0x00, 0x02, 0x24, -0x08, 0x00, 0xA2, 0x10, 0x00, 0x19, 0x04, 0x00, 0x80, 0x10, 0x04, 0x00, -0x21, 0x10, 0x44, 0x00, 0xC0, 0x10, 0x02, 0x00, 0x23, 0x10, 0x44, 0x00, -0x00, 0x11, 0x02, 0x00, 0x21, 0x10, 0x44, 0x00, 0x40, 0x19, 0x02, 0x00, -0xFF, 0xFF, 0x63, 0x24, 0xFE, 0xFF, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xF3, 0xFF, 0xA2, 0x10, -0x06, 0x00, 0x02, 0x24, 0xF2, 0xFF, 0xA2, 0x14, 0x80, 0x10, 0x04, 0x00, -0x40, 0x11, 0x04, 0x00, 0x23, 0x10, 0x44, 0x00, 0x80, 0x10, 0x02, 0x00, -0x21, 0x10, 0x44, 0x00, 0x00, 0x19, 0x02, 0x00, 0x23, 0x18, 0x62, 0x00, -0x42, 0x1F, 0x00, 0x08, 0x00, 0x19, 0x03, 0x00, 0x80, 0x10, 0x04, 0x00, -0x21, 0x10, 0x44, 0x00, 0xC0, 0x10, 0x02, 0x00, 0x23, 0x10, 0x44, 0x00, -0x00, 0x11, 0x02, 0x00, 0x21, 0x10, 0x44, 0x00, 0x42, 0x1F, 0x00, 0x08, -0x00, 0x19, 0x02, 0x00, 0x00, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, -0x6C, 0x7D, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, -0x02, 0x80, 0x05, 0x3C, 0xCC, 0x5D, 0xA3, 0x8C, 0x05, 0x00, 0x02, 0x24, -0x06, 0x00, 0x62, 0x10, 0x06, 0x00, 0x62, 0x2C, 0x0C, 0x00, 0x40, 0x10, -0x06, 0x00, 0x02, 0x24, 0x04, 0x00, 0x02, 0x24, 0x0E, 0x00, 0x62, 0x10, -0x80, 0x10, 0x04, 0x00, 0x80, 0x10, 0x04, 0x00, 0x21, 0x10, 0x44, 0x00, -0x80, 0x10, 0x02, 0x00, 0xFF, 0xFF, 0x42, 0x24, 0xFE, 0xFF, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0xF7, 0xFF, 0x62, 0x14, 0x00, 0x11, 0x04, 0x00, 0x23, 0x10, 0x44, 0x00, -0x6D, 0x1F, 0x00, 0x08, 0x40, 0x10, 0x02, 0x00, 0x21, 0x10, 0x44, 0x00, -0x6D, 0x1F, 0x00, 0x08, 0x40, 0x10, 0x02, 0x00, 0xFF, 0xFF, 0x85, 0x30, -0x21, 0x30, 0x00, 0x00, 0x25, 0xB0, 0x03, 0x3C, 0x2A, 0xB0, 0x04, 0x3C, -0xB4, 0x00, 0x63, 0x34, 0x01, 0x00, 0xA2, 0x24, 0x31, 0x00, 0x84, 0x34, -0x00, 0x00, 0x65, 0xA0, 0x00, 0x00, 0x85, 0xA0, 0xFF, 0xFF, 0x45, 0x30, -0x12, 0x00, 0xA0, 0x10, 0x01, 0x00, 0x03, 0x24, 0x28, 0xB0, 0x07, 0x3C, -0x8F, 0x1F, 0x00, 0x08, 0xFF, 0xFF, 0x08, 0x24, 0x00, 0x00, 0x83, 0xA0, -0x01, 0x00, 0x63, 0x24, 0xFF, 0xFF, 0x63, 0x30, 0x2B, 0x10, 0xA3, 0x00, -0x09, 0x00, 0x40, 0x14, 0x08, 0x00, 0xC6, 0x24, 0xF9, 0xFF, 0x65, 0x14, -0x21, 0x20, 0xC7, 0x00, 0x01, 0x00, 0x63, 0x24, 0xFF, 0xFF, 0x63, 0x30, -0x2B, 0x10, 0xA3, 0x00, 0x00, 0x00, 0x88, 0xA0, 0xF9, 0xFF, 0x40, 0x10, -0x08, 0x00, 0xC6, 0x24, 0x00, 0x01, 0xA2, 0x2C, 0x13, 0x00, 0x40, 0x10, -0x21, 0x18, 0xA0, 0x00, 0xFF, 0x00, 0x08, 0x24, 0x28, 0xB0, 0x07, 0x3C, -0xA3, 0x1F, 0x00, 0x08, 0xFF, 0xFF, 0x09, 0x24, 0xFF, 0xFF, 0x43, 0x30, -0x00, 0x00, 0xA2, 0xA0, 0x00, 0x01, 0x62, 0x2C, 0x0A, 0x00, 0x40, 0x10, -0x08, 0x00, 0xC6, 0x24, 0x01, 0x00, 0x62, 0x24, 0xF9, 0xFF, 0x68, 0x14, -0x21, 0x28, 0xC7, 0x00, 0x00, 0x01, 0x02, 0x24, 0xFF, 0xFF, 0x43, 0x30, -0x00, 0x01, 0x62, 0x2C, 0x00, 0x00, 0xA9, 0xA0, 0xF8, 0xFF, 0x40, 0x14, -0x08, 0x00, 0xC6, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0xD0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB2, 0xAF, 0x25, 0xB0, 0x12, 0x3C, -0xFF, 0xFF, 0x02, 0x24, 0x28, 0x00, 0xB6, 0xAF, 0x1C, 0x00, 0xB3, 0xAF, -0x42, 0x00, 0x56, 0x36, 0x14, 0x00, 0xB1, 0xAF, 0xFC, 0x77, 0x13, 0x24, -0x40, 0x00, 0x51, 0x36, 0x00, 0x00, 0xC2, 0xA2, 0x10, 0x00, 0xB0, 0xAF, -0x00, 0x00, 0x33, 0xA6, 0xFC, 0x57, 0x10, 0x24, 0x32, 0x00, 0x04, 0x24, -0x2C, 0x00, 0xBF, 0xAF, 0x24, 0x00, 0xB5, 0xAF, 0x5B, 0x1F, 0x00, 0x0C, -0x20, 0x00, 0xB4, 0xAF, 0x00, 0x00, 0x30, 0xA6, 0x5B, 0x1F, 0x00, 0x0C, -0x32, 0x00, 0x04, 0x24, 0xFC, 0x37, 0x02, 0x24, 0x00, 0x00, 0x22, 0xA6, -0x5B, 0x1F, 0x00, 0x0C, 0x32, 0x00, 0x04, 0x24, 0x00, 0x00, 0x33, 0xA6, -0x5B, 0x1F, 0x00, 0x0C, 0x32, 0x00, 0x04, 0x24, 0x00, 0x00, 0x30, 0xA6, -0x5B, 0x1F, 0x00, 0x0C, 0x32, 0x00, 0x04, 0x24, 0x00, 0x10, 0x02, 0x24, -0x00, 0x00, 0x22, 0xA6, 0xD8, 0x00, 0x45, 0x36, 0x00, 0x00, 0xA2, 0x90, -0xA0, 0x00, 0x54, 0x36, 0xA4, 0x00, 0x55, 0x36, 0x7F, 0x00, 0x42, 0x30, -0x00, 0x00, 0xA2, 0xA0, 0xA8, 0x00, 0x53, 0x36, 0x00, 0x80, 0x02, 0x3C, -0xFC, 0x17, 0x03, 0x24, 0x00, 0x00, 0x80, 0xAE, 0x00, 0x00, 0xA0, 0xAE, -0x00, 0x00, 0x62, 0xAE, 0x00, 0x00, 0x23, 0xA6, 0x00, 0x00, 0xA3, 0x90, -0x02, 0x80, 0x10, 0x3C, 0x60, 0x1B, 0x10, 0x26, 0xAA, 0x1B, 0x04, 0x92, -0x80, 0xFF, 0x02, 0x24, 0x25, 0x18, 0x62, 0x00, 0x56, 0x01, 0x52, 0x36, -0xFF, 0x0F, 0x02, 0x24, 0x00, 0x00, 0xA3, 0xA0, 0x00, 0x00, 0x42, 0xA6, -0x7A, 0x1F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x04, 0x8E, -0x14, 0x1C, 0x02, 0x8E, 0x18, 0x1C, 0x03, 0x8E, 0x2C, 0x00, 0xBF, 0x8F, -0x00, 0x00, 0x82, 0xAE, 0x18, 0x00, 0xB2, 0x8F, 0x00, 0x00, 0xA3, 0xAE, -0x20, 0x00, 0xB4, 0x8F, 0x00, 0x00, 0x64, 0xAE, 0x24, 0x00, 0xB5, 0x8F, -0x00, 0x00, 0xC0, 0xA2, 0x1C, 0x00, 0xB3, 0x8F, 0x28, 0x00, 0xB6, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x30, 0x00, 0xBD, 0x27, 0xC8, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF, -0x10, 0x00, 0xA4, 0x27, 0x25, 0xB0, 0x10, 0x3C, 0x34, 0x00, 0xBF, 0xAF, -0x30, 0x00, 0xB6, 0xAF, 0x2C, 0x00, 0xB5, 0xAF, 0x28, 0x00, 0xB4, 0xAF, -0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF, 0x8A, 0x40, 0x00, 0x0C, -0x1C, 0x00, 0xB1, 0xAF, 0x40, 0x00, 0x05, 0x36, 0x00, 0x00, 0xA2, 0x94, -0x24, 0xFA, 0x03, 0x24, 0xA8, 0x00, 0x13, 0x36, 0x24, 0x10, 0x43, 0x00, -0x00, 0x00, 0xA2, 0xA4, 0xA0, 0x00, 0x12, 0x36, 0xA4, 0x00, 0x10, 0x36, -0x00, 0x00, 0x55, 0x8E, 0x00, 0x00, 0x16, 0x8E, 0x00, 0x00, 0x71, 0x8E, -0x00, 0x80, 0x14, 0x3C, 0xFC, 0x37, 0x02, 0x24, 0x00, 0x00, 0x40, 0xAE, -0x21, 0x88, 0x34, 0x02, 0x00, 0x00, 0x00, 0xAE, 0xFD, 0x00, 0x04, 0x24, -0x00, 0x00, 0x74, 0xAE, 0x00, 0x00, 0xA2, 0xA4, 0x7A, 0x1F, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAE, 0x10, 0x00, 0xA4, 0x27, -0x00, 0x00, 0x16, 0xAE, 0x00, 0x00, 0x71, 0xAE, 0x90, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0xBF, 0x8F, 0x30, 0x00, 0xB6, 0x8F, -0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, -0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x38, 0x00, 0xBD, 0x27, 0xC8, 0xFF, 0xBD, 0x27, -0x18, 0x00, 0xB0, 0xAF, 0x10, 0x00, 0xA4, 0x27, 0x25, 0xB0, 0x10, 0x3C, -0x34, 0x00, 0xBF, 0xAF, 0x30, 0x00, 0xB6, 0xAF, 0x2C, 0x00, 0xB5, 0xAF, -0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF, -0x8A, 0x40, 0x00, 0x0C, 0x1C, 0x00, 0xB1, 0xAF, 0x40, 0x00, 0x05, 0x36, -0x00, 0x00, 0xA2, 0x94, 0xAF, 0xFF, 0x03, 0x24, 0xA8, 0x00, 0x13, 0x36, -0x24, 0x10, 0x43, 0x00, 0x00, 0x00, 0xA2, 0xA4, 0xA0, 0x00, 0x12, 0x36, -0xA4, 0x00, 0x10, 0x36, 0x00, 0x00, 0x55, 0x8E, 0x00, 0x00, 0x16, 0x8E, -0x00, 0x00, 0x71, 0x8E, 0x00, 0x80, 0x14, 0x3C, 0xFC, 0x37, 0x02, 0x24, -0x00, 0x00, 0x40, 0xAE, 0x21, 0x88, 0x34, 0x02, 0x00, 0x00, 0x00, 0xAE, -0xFD, 0x00, 0x04, 0x24, 0x00, 0x00, 0x74, 0xAE, 0x00, 0x00, 0xA2, 0xA4, -0x7A, 0x1F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAE, -0x10, 0x00, 0xA4, 0x27, 0x00, 0x00, 0x16, 0xAE, 0x00, 0x00, 0x71, 0xAE, -0x90, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0xBF, 0x8F, -0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F, -0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x38, 0x00, 0xBD, 0x27, -0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C, -0x10, 0x00, 0xA4, 0x27, 0x25, 0xB0, 0x05, 0x3C, 0x40, 0x00, 0xA5, 0x34, -0x00, 0x00, 0xA2, 0x94, 0xD8, 0xFD, 0x03, 0x24, 0x10, 0x00, 0xA4, 0x27, -0x24, 0x10, 0x43, 0x00, 0xFC, 0x37, 0x03, 0x24, 0x00, 0x00, 0xA2, 0xA4, -0x00, 0x00, 0xA3, 0xA4, 0x90, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x18, 0x00, 0xBF, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x20, 0x00, 0xBD, 0x27, 0xD0, 0xFF, 0xBD, 0x27, 0xFF, 0x00, 0x82, 0x30, -0x10, 0x00, 0xA4, 0x27, 0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF, -0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x21, 0x88, 0xC0, 0x00, -0x21, 0x80, 0xE0, 0x00, 0xC0, 0x90, 0x02, 0x00, 0x28, 0x00, 0xBF, 0xAF, -0x8A, 0x40, 0x00, 0x0C, 0xFF, 0xFF, 0xB3, 0x30, 0x25, 0xB0, 0x02, 0x3C, -0x40, 0x02, 0x49, 0x34, 0xF8, 0xFF, 0x10, 0x26, 0x21, 0x30, 0x00, 0x00, -0x01, 0x00, 0x0A, 0x24, 0x44, 0x02, 0x48, 0x34, 0x99, 0x20, 0x00, 0x08, -0x01, 0x80, 0x07, 0x3C, 0x2E, 0x00, 0xCA, 0x10, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x02, 0x92, 0x00, 0x00, 0x04, 0x92, 0x02, 0x00, 0x03, 0x92, -0x03, 0x00, 0x05, 0x92, 0x00, 0x12, 0x02, 0x00, 0x25, 0x20, 0x82, 0x00, -0x00, 0x1C, 0x03, 0x00, 0x25, 0x20, 0x83, 0x00, 0x21, 0x10, 0x46, 0x02, -0x00, 0x2E, 0x05, 0x00, 0x01, 0x00, 0xC6, 0x24, 0x25, 0x20, 0x85, 0x00, -0x25, 0x10, 0x47, 0x00, 0x06, 0x00, 0xC3, 0x2C, 0x00, 0x00, 0x04, 0xAD, -0x04, 0x00, 0x10, 0x26, 0x00, 0x00, 0x22, 0xAD, 0x12, 0x00, 0x60, 0x10, -0x00, 0x00, 0x00, 0x00, 0xEA, 0xFF, 0xC0, 0x14, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x22, 0x92, 0x01, 0x00, 0x23, 0x92, 0x04, 0x00, 0x10, 0x26, -0x00, 0x14, 0x02, 0x00, 0x25, 0x10, 0x62, 0x02, 0x00, 0x1E, 0x03, 0x00, -0x25, 0x20, 0x43, 0x00, 0x21, 0x10, 0x46, 0x02, 0x01, 0x00, 0xC6, 0x24, -0x25, 0x10, 0x47, 0x00, 0x06, 0x00, 0xC3, 0x2C, 0x00, 0x00, 0x04, 0xAD, -0x00, 0x00, 0x22, 0xAD, 0xF0, 0xFF, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, -0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x28, 0x00, 0xBF, 0x8F, -0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, -0x03, 0x00, 0x22, 0x92, 0x02, 0x00, 0x24, 0x92, 0x04, 0x00, 0x23, 0x92, -0x05, 0x00, 0x25, 0x92, 0x8B, 0x20, 0x00, 0x08, 0x00, 0x12, 0x02, 0x00, -0xFF, 0xFF, 0x84, 0x30, 0x42, 0xB0, 0x08, 0x3C, 0x80, 0x10, 0x04, 0x00, -0x21, 0x10, 0x48, 0x00, 0x04, 0x00, 0x46, 0xAC, 0x00, 0x00, 0x07, 0x91, -0x40, 0x18, 0x04, 0x00, 0x03, 0x00, 0x06, 0x24, 0xFF, 0x00, 0xE7, 0x30, -0x04, 0x30, 0x66, 0x00, 0x01, 0x00, 0x02, 0x24, 0x04, 0x10, 0x62, 0x00, -0x25, 0x30, 0xC7, 0x00, 0xFF, 0xFF, 0xA5, 0x30, 0x25, 0x10, 0x47, 0x00, -0x02, 0x00, 0xA0, 0x14, 0xFF, 0x00, 0xC7, 0x30, 0xFF, 0x00, 0x47, 0x30, -0x42, 0xB0, 0x02, 0x3C, 0x00, 0x00, 0x47, 0xA0, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x83, 0x90, 0x01, 0x00, 0x02, 0x24, -0x08, 0x00, 0x86, 0xAC, 0x18, 0x00, 0x85, 0xAC, 0x00, 0x00, 0x84, 0xAC, -0x03, 0x00, 0x62, 0x10, 0x04, 0x00, 0x84, 0xAC, 0x5F, 0x5C, 0x00, 0x08, -0x0C, 0x00, 0x80, 0xAC, 0x0C, 0x00, 0x82, 0x8C, 0x5F, 0x5C, 0x00, 0x08, -0x10, 0x00, 0x82, 0xAC, 0xC8, 0xFF, 0xBD, 0x27, 0x28, 0x00, 0xB6, 0xAF, -0x25, 0xB0, 0x02, 0x3C, 0x02, 0x80, 0x16, 0x3C, 0x2C, 0x00, 0xB7, 0xAF, -0x24, 0x00, 0xB5, 0xAF, 0x20, 0x00, 0xB4, 0xAF, 0x1C, 0x00, 0xB3, 0xAF, -0x18, 0x00, 0xB2, 0xAF, 0x30, 0x00, 0xBF, 0xAF, 0x14, 0x00, 0xB1, 0xAF, -0x10, 0x00, 0xB0, 0xAF, 0x18, 0x03, 0x55, 0x34, 0x01, 0x80, 0x17, 0x3C, -0x02, 0x80, 0x13, 0x3C, 0x02, 0x80, 0x14, 0x3C, 0xD0, 0xDF, 0xD2, 0x26, -0x6C, 0x83, 0xE2, 0x26, 0x00, 0x00, 0xA2, 0xAE, 0xD0, 0xDF, 0xD0, 0x8E, -0x9B, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x5C, 0x71, 0x8E, -0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x00, -0x96, 0x40, 0x00, 0x0C, 0xFC, 0x5C, 0x60, 0xAE, 0x22, 0x00, 0x12, 0x12, -0x08, 0x0C, 0x84, 0x26, 0x14, 0x00, 0x03, 0x92, 0x01, 0x00, 0x02, 0x24, -0x2A, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x60, 0x14, -0x02, 0x00, 0x02, 0x24, 0x0C, 0x00, 0x03, 0x8E, 0x00, 0x00, 0x00, 0x00, -0x2B, 0x10, 0x23, 0x02, 0x1D, 0x00, 0x40, 0x10, 0x23, 0x10, 0x71, 0x00, -0x0C, 0x00, 0x02, 0xAE, 0x00, 0x00, 0x10, 0x8E, 0xF7, 0x20, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, -0x0C, 0x00, 0x03, 0x8E, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x60, 0x10, -0x2B, 0x10, 0x23, 0x02, 0xF5, 0xFF, 0x40, 0x14, 0x23, 0x10, 0x71, 0x00, -0x08, 0x00, 0x02, 0x8E, 0x18, 0x00, 0x04, 0x8E, 0x09, 0xF8, 0x40, 0x00, -0x0C, 0x00, 0x00, 0xAE, 0x00, 0x00, 0x10, 0x8E, 0xF7, 0x20, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x96, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x08, 0x0C, 0x84, 0x26, 0x21, 0x28, 0x00, 0x00, 0x21, 0x30, 0x00, 0x00, -0x76, 0x39, 0x00, 0x0C, 0x21, 0x38, 0x00, 0x00, 0xED, 0x20, 0x00, 0x08, -0x6C, 0x83, 0xE2, 0x26, 0x08, 0x00, 0x02, 0x8E, 0x18, 0x00, 0x04, 0x8E, -0x09, 0xF8, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x21, 0x00, 0x08, -0x0C, 0x00, 0x02, 0xAE, 0x0C, 0x00, 0x03, 0x8E, 0x00, 0x00, 0x00, 0x00, -0x2B, 0x10, 0x23, 0x02, 0xDA, 0xFF, 0x40, 0x14, 0x23, 0x10, 0x71, 0x00, -0x08, 0x00, 0x02, 0x8E, 0x18, 0x00, 0x04, 0x8E, 0x09, 0xF8, 0x40, 0x00, -0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x8E, 0x00, 0x00, 0x00, 0x00, -0x0C, 0x00, 0x03, 0xAE, 0x00, 0x00, 0x10, 0x8E, 0xF7, 0x20, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0xD8, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, -0xC0, 0x54, 0x42, 0x24, 0x18, 0x00, 0xB0, 0xAF, 0xC0, 0x80, 0x04, 0x00, -0x21, 0x80, 0x02, 0x02, 0x1C, 0x00, 0xB1, 0xAF, 0x20, 0x00, 0xBF, 0xAF, -0x8A, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x00, 0x00, 0x02, 0x8E, -0x10, 0x00, 0xA4, 0x27, 0x09, 0x00, 0x50, 0x10, 0x21, 0x88, 0x00, 0x00, -0x04, 0x00, 0x43, 0x8C, 0x21, 0x88, 0x40, 0x00, 0x00, 0x00, 0x42, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xAC, 0x04, 0x00, 0x43, 0xAC, -0x00, 0x00, 0x31, 0xAE, 0x04, 0x00, 0x31, 0xAE, 0x90, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x20, 0x02, 0x20, 0x00, 0xBF, 0x8F, -0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x28, 0x00, 0xBD, 0x27, 0xE8, 0xFF, 0xBD, 0x27, 0x01, 0x01, 0x82, 0x2C, -0x10, 0x00, 0xB0, 0xAF, 0x14, 0x00, 0xBF, 0xAF, 0x21, 0x80, 0x80, 0x00, -0x21, 0x18, 0x00, 0x00, 0x10, 0x00, 0x40, 0x14, 0x01, 0x00, 0x04, 0x24, -0x01, 0x02, 0x02, 0x2E, 0x0D, 0x00, 0x40, 0x14, 0x02, 0x00, 0x04, 0x24, -0x01, 0x08, 0x02, 0x2E, 0x0A, 0x00, 0x40, 0x14, 0x03, 0x00, 0x04, 0x24, -0x01, 0x10, 0x02, 0x2E, 0x06, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0x04, 0x00, 0x04, 0x24, -0x35, 0x21, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xF7, 0xFF, 0x40, 0x10, -0x21, 0x18, 0x40, 0x00, 0x0C, 0x00, 0x50, 0xAC, 0x14, 0x00, 0xBF, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF, -0x21, 0x80, 0x80, 0x00, 0x1C, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C, -0x10, 0x00, 0xA4, 0x27, 0x10, 0x00, 0x03, 0x8E, 0x02, 0x80, 0x02, 0x3C, -0xC0, 0x54, 0x42, 0x24, 0xC0, 0x18, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, -0x00, 0x00, 0x64, 0x8C, 0x02, 0x80, 0x06, 0x3C, 0x02, 0x80, 0x07, 0x3C, -0x00, 0x00, 0x04, 0xAE, 0x04, 0x00, 0x90, 0xAC, 0x04, 0x00, 0x03, 0xAE, -0xC4, 0x5D, 0xC5, 0x8C, 0x10, 0x00, 0xA4, 0x27, 0x05, 0x00, 0xA0, 0x10, -0x00, 0x00, 0x70, 0xAC, 0xB0, 0x5D, 0xE2, 0x8C, 0xC4, 0x5D, 0xC0, 0xAC, -0x25, 0x10, 0x45, 0x00, 0xB0, 0x5D, 0xE2, 0xAC, 0x90, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0xC9, 0xF7, 0x1B, 0x6B, -0x6B, 0xEB, 0x60, 0x33, 0xFF, 0x6A, 0x60, 0x33, 0x4C, 0xEC, 0x60, 0xF1, -0x00, 0x4B, 0xAC, 0xEA, 0x69, 0xE2, 0x80, 0xC2, 0x20, 0xE8, 0x00, 0x65, -0xFF, 0x6A, 0x8C, 0xEA, 0x15, 0x5A, 0x0E, 0x60, 0x01, 0x6B, 0x83, 0x67, -0x84, 0xEA, 0x02, 0xF0, 0x00, 0x6A, 0x40, 0x32, 0xEE, 0xF0, 0x10, 0x4A, -0x8C, 0xEA, 0x05, 0x2A, 0x0F, 0x6A, 0x8C, 0xEA, 0x02, 0x6B, 0x01, 0x2A, -0x00, 0x6B, 0x20, 0xE8, 0x43, 0x67, 0x00, 0x00, 0xFF, 0x63, 0x00, 0xD0, -0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x8C, 0x30, 0x0A, 0x65, -0x89, 0xE0, 0x48, 0x32, 0x89, 0xE2, 0x68, 0x67, 0x63, 0xF3, 0x00, 0x4B, -0x48, 0x32, 0x69, 0xE2, 0x01, 0xD1, 0x00, 0x6B, 0x04, 0xF5, 0x6A, 0xC2, -0x04, 0xF5, 0x6B, 0xC2, 0x04, 0xF5, 0x64, 0x9A, 0x1C, 0x6D, 0x22, 0x67, -0x01, 0x6F, 0xFF, 0x6E, 0x02, 0x10, 0xFF, 0x4D, 0xCC, 0xED, 0x47, 0x67, -0x44, 0xED, 0x6C, 0xEA, 0xFA, 0x22, 0x04, 0xF5, 0xAA, 0xC1, 0x00, 0x6D, -0x1D, 0x5D, 0x13, 0x60, 0x89, 0xE0, 0x48, 0x32, 0x68, 0x67, 0x89, 0xE2, -0x63, 0xF3, 0x00, 0x4B, 0x48, 0x32, 0x79, 0xE2, 0x04, 0xF5, 0x44, 0x9E, -0x01, 0x6B, 0x64, 0xED, 0x6C, 0xEA, 0x09, 0x2A, 0x01, 0x4D, 0xFF, 0x6A, -0x4C, 0xED, 0x1D, 0x5D, 0xED, 0x61, 0x01, 0x91, 0x00, 0x90, 0x20, 0xE8, -0x01, 0x63, 0x01, 0x91, 0x00, 0x90, 0x04, 0xF5, 0xAB, 0xC6, 0x20, 0xE8, -0x01, 0x63, 0x00, 0x00, 0xFB, 0x63, 0x07, 0xD1, 0x10, 0xF0, 0x02, 0x69, -0x00, 0xF4, 0x20, 0x31, 0x00, 0x6A, 0x63, 0xF3, 0x00, 0x49, 0x08, 0x62, -0x06, 0xD0, 0x04, 0xD2, 0x34, 0x10, 0x03, 0x54, 0x62, 0x60, 0x01, 0x74, -0x6E, 0x60, 0x04, 0xF5, 0x88, 0x99, 0x07, 0x6A, 0xFF, 0x6B, 0x82, 0x34, -0x86, 0x34, 0x4C, 0xEC, 0x04, 0x58, 0x6C, 0xEC, 0x12, 0x60, 0x00, 0x18, -0xA1, 0x5C, 0xB0, 0x67, 0xC9, 0xF7, 0x1B, 0x6C, 0x04, 0xF5, 0x60, 0x99, -0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x4C, 0xEB, 0x80, 0xF1, 0x04, 0x4C, -0x08, 0x32, 0x89, 0xE2, 0x04, 0xF5, 0x64, 0xD9, 0x60, 0xDA, 0x00, 0x18, -0xA5, 0x21, 0x04, 0x94, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x04, 0x93, -0x80, 0x34, 0x80, 0x34, 0x60, 0xF1, 0x00, 0x4C, 0x89, 0xE3, 0x40, 0xA2, -0x04, 0x92, 0x7F, 0x49, 0x15, 0x49, 0x01, 0x4A, 0x20, 0x5A, 0x04, 0xD2, -0x48, 0x60, 0x04, 0xF5, 0xA8, 0x99, 0x01, 0x6B, 0xA2, 0x34, 0x92, 0x32, -0x6C, 0xEA, 0xFF, 0x6B, 0x6C, 0xEA, 0xF0, 0x22, 0xE4, 0xF4, 0x78, 0x99, -0xFF, 0x6A, 0x86, 0x34, 0x72, 0x33, 0x4C, 0xEB, 0x7F, 0x6A, 0x4C, 0xEB, -0x07, 0x6A, 0x4C, 0xEC, 0xFF, 0x6A, 0x4C, 0xEC, 0x07, 0x68, 0xAC, 0xE8, -0x02, 0x74, 0x4C, 0xE8, 0xB2, 0x61, 0x38, 0x5B, 0x0A, 0x61, 0x01, 0xF6, -0x01, 0x6A, 0x4B, 0xEA, 0xAC, 0xEA, 0x00, 0xF2, 0x00, 0x6B, 0x6D, 0xEA, -0x04, 0xF5, 0x48, 0xD9, 0xAA, 0x17, 0x14, 0x5B, 0xA8, 0x60, 0x01, 0xF6, -0x01, 0x6A, 0x4B, 0xEA, 0xAC, 0xEA, 0x00, 0xF6, 0x00, 0x6B, 0x6D, 0xEA, -0xF3, 0x17, 0x03, 0x74, 0x9E, 0x61, 0x1A, 0x5B, 0x9C, 0x61, 0x01, 0xF6, -0x01, 0x6A, 0x4B, 0xEA, 0xAC, 0xEA, 0x00, 0xF4, 0x00, 0x6C, 0x8D, 0xEA, -0x04, 0xF5, 0x48, 0xD9, 0x92, 0x17, 0x32, 0x5B, 0x90, 0x60, 0x01, 0xF6, -0x01, 0x6A, 0x4B, 0xEA, 0xAC, 0xEA, 0x00, 0xF4, 0x00, 0x6B, 0x6D, 0xEA, -0xDB, 0x17, 0x08, 0x97, 0x07, 0x91, 0x06, 0x90, 0x00, 0x6A, 0x00, 0xEF, -0x05, 0x63, 0x00, 0x00, 0x20, 0xE8, 0x00, 0x65, 0xA4, 0x67, 0xC9, 0xF7, -0x1B, 0x6C, 0xFC, 0x63, 0x8B, 0xEC, 0x06, 0xD0, 0x80, 0x34, 0xAC, 0x30, -0xA1, 0xE0, 0x80, 0x34, 0x07, 0x62, 0x80, 0xF1, 0x40, 0x44, 0x08, 0x30, -0x40, 0xA2, 0xA1, 0xE0, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, -0x63, 0xF3, 0x00, 0x4A, 0x08, 0x30, 0x41, 0xE0, 0x04, 0xF5, 0x48, 0x98, -0x07, 0x6B, 0x80, 0xF1, 0x04, 0x4C, 0x6C, 0xEA, 0x48, 0x32, 0x89, 0xE2, -0x04, 0xF5, 0x60, 0x98, 0x40, 0x9A, 0x85, 0x67, 0x6C, 0xEA, 0x04, 0xF5, -0x44, 0xD8, 0x00, 0x18, 0xA5, 0x21, 0x04, 0xD5, 0x04, 0x95, 0x04, 0xF5, -0x8A, 0xA0, 0xFF, 0x6A, 0x00, 0x18, 0x93, 0x21, 0x4C, 0xED, 0x07, 0x97, -0x06, 0x90, 0x00, 0xEF, 0x04, 0x63, 0x00, 0x00, 0xFF, 0xF7, 0x1F, 0x6B, -0x8C, 0xEB, 0x00, 0xF2, 0x00, 0x6A, 0x0B, 0x6C, 0x6C, 0xEA, 0x6C, 0xEC, -0x07, 0x6B, 0x0E, 0x2A, 0x0C, 0x5C, 0x0B, 0x60, 0x10, 0xF0, 0x02, 0x6B, -0x00, 0xF4, 0x60, 0x33, 0x88, 0x32, 0x7D, 0xF7, 0x08, 0x4B, 0x69, 0xE2, -0x40, 0x9A, 0x00, 0xEA, 0x00, 0x65, 0x07, 0x6B, 0x20, 0xE8, 0x43, 0x67, -0x06, 0x6B, 0x20, 0xE8, 0x43, 0x67, 0x05, 0x6B, 0x20, 0xE8, 0x43, 0x67, -0x04, 0x6B, 0x20, 0xE8, 0x43, 0x67, 0x03, 0x6B, 0x20, 0xE8, 0x43, 0x67, -0x02, 0x6B, 0x20, 0xE8, 0x43, 0x67, 0x01, 0x6B, 0x20, 0xE8, 0x43, 0x67, -0x00, 0x6B, 0x20, 0xE8, 0x43, 0x67, 0x00, 0x00, 0x10, 0xF0, 0x02, 0x6B, -0x00, 0xF4, 0x60, 0x33, 0xF7, 0x63, 0x63, 0xF3, 0x00, 0x4B, 0x00, 0x6A, -0x0F, 0xD1, 0x23, 0x67, 0x10, 0x62, 0x0E, 0xD0, 0x04, 0xD2, 0x05, 0xD3, -0x06, 0xD3, 0x07, 0xD3, 0x08, 0xD2, 0x09, 0xD2, 0x0A, 0xD2, 0x0B, 0xD2, -0x0C, 0xD2, 0xE4, 0xF4, 0x08, 0x49, 0x48, 0x99, 0x01, 0x6B, 0xFF, 0x6C, -0x42, 0x32, 0x52, 0x32, 0x6C, 0xEA, 0x8C, 0xEA, 0x80, 0xF0, 0x11, 0x22, -0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x04, 0x96, 0x40, 0x32, -0x60, 0xF1, 0x00, 0x4A, 0x49, 0xE6, 0x40, 0xA2, 0xFF, 0x6B, 0x4C, 0xEC, -0x05, 0x92, 0x0C, 0x65, 0x51, 0xE4, 0xC0, 0xF4, 0x4A, 0xA4, 0x6C, 0xEA, -0x61, 0x99, 0x58, 0xEB, 0xE0, 0xF4, 0x47, 0xA4, 0xFF, 0x6B, 0x6C, 0xEA, -0x62, 0x99, 0x12, 0xED, 0x00, 0x65, 0x00, 0x65, 0x58, 0xEB, 0x12, 0xEA, -0x55, 0xE5, 0xFF, 0xF7, 0x4C, 0x99, 0xA3, 0xEA, 0x40, 0xF1, 0x0F, 0x61, -0xAB, 0xE2, 0xFF, 0xF7, 0x4C, 0xD9, 0x61, 0x99, 0x42, 0x99, 0xC8, 0x67, -0xFF, 0xF7, 0xEC, 0x99, 0x55, 0xE3, 0xFF, 0xF7, 0x70, 0x99, 0xFF, 0xF7, -0x54, 0x99, 0x51, 0xE3, 0xFF, 0xF7, 0x7C, 0x99, 0x40, 0x99, 0x41, 0xE3, -0x05, 0x93, 0x69, 0xE6, 0x20, 0xF5, 0x5E, 0xA2, 0xFF, 0x6E, 0xCC, 0xEA, -0xC5, 0x67, 0x0F, 0x25, 0xA3, 0xEA, 0xD8, 0x67, 0x0D, 0x2E, 0x48, 0x67, -0x07, 0x5A, 0x04, 0x61, 0x0C, 0x72, 0x02, 0x60, 0x0D, 0x72, 0x05, 0x61, -0xAC, 0x32, 0xAB, 0xE2, 0x4E, 0x32, 0x83, 0xEA, 0x10, 0x61, 0x79, 0x26, -0x05, 0x92, 0x68, 0x67, 0x68, 0x34, 0x51, 0xE4, 0x06, 0x92, 0x69, 0xE2, -0x44, 0xF5, 0x66, 0xA2, 0xFF, 0x6A, 0x4C, 0xEB, 0x60, 0xF5, 0x40, 0x9C, -0x44, 0xEB, 0xE3, 0xEA, 0x6A, 0x60, 0x01, 0x68, 0x5F, 0x99, 0x70, 0x67, -0x88, 0x67, 0x64, 0xEC, 0x6C, 0xEA, 0x00, 0xF1, 0x1C, 0x22, 0x06, 0x96, -0x95, 0xE6, 0x44, 0xF5, 0x66, 0xA5, 0x04, 0xF5, 0xEC, 0xA5, 0xFF, 0x6E, -0x46, 0x67, 0xCC, 0xEB, 0x0A, 0x6C, 0xEC, 0xEA, 0x84, 0xEB, 0x82, 0xEA, -0x00, 0xF1, 0x0D, 0x60, 0x41, 0x47, 0x04, 0xF5, 0x4C, 0xC5, 0xCC, 0xEA, -0x8E, 0xEA, 0x02, 0x2A, 0x24, 0xF5, 0x09, 0xC5, 0x05, 0x94, 0x68, 0x67, -0x68, 0x32, 0x89, 0xE2, 0xC0, 0xF5, 0x94, 0x9A, 0x60, 0xF5, 0x40, 0x9A, -0x84, 0x33, 0x8D, 0xE3, 0x69, 0xE2, 0x4A, 0x37, 0xFF, 0xF7, 0xEC, 0xD9, -0x05, 0x96, 0x27, 0xF1, 0x44, 0x9E, 0xFF, 0xF7, 0x1F, 0x72, 0xC0, 0xF0, -0x1B, 0x61, 0x00, 0x6B, 0x61, 0xD9, 0x62, 0xD9, 0xFF, 0xF7, 0x70, 0xD9, -0xFF, 0xF7, 0x74, 0xD9, 0xFF, 0xF7, 0x78, 0xD9, 0xFF, 0xF7, 0x7C, 0xD9, -0x60, 0xD9, 0x04, 0x94, 0x0C, 0x96, 0x0B, 0x92, 0x01, 0x4C, 0x0A, 0x93, -0x04, 0xD4, 0x09, 0x94, 0x7F, 0x4E, 0x7F, 0x4A, 0x7F, 0x4B, 0x15, 0x4E, -0x15, 0x4A, 0x15, 0x4B, 0x7F, 0x4C, 0x15, 0x4C, 0x0C, 0xD6, 0x0B, 0xD2, -0x08, 0x96, 0x07, 0x92, 0x0A, 0xD3, 0x06, 0x93, 0x09, 0xD4, 0x04, 0x94, -0x7F, 0x4E, 0x7F, 0x4A, 0x7F, 0x4B, 0x15, 0x4E, 0x15, 0x4A, 0x15, 0x4B, -0x7F, 0x49, 0x20, 0x54, 0x08, 0xD6, 0x07, 0xD2, 0x06, 0xD3, 0x15, 0x49, -0x3F, 0xF7, 0x15, 0x61, 0x10, 0x97, 0x0F, 0x91, 0x0E, 0x90, 0x00, 0xEF, -0x09, 0x63, 0xA0, 0xF0, 0x0E, 0x25, 0xA0, 0xF0, 0x0E, 0x2E, 0xA4, 0x32, -0xA9, 0xE2, 0x4A, 0x32, 0x03, 0xEA, 0xC1, 0x60, 0x06, 0x96, 0x48, 0x67, -0x00, 0x6B, 0x51, 0xE6, 0x04, 0xF5, 0x6C, 0xC4, 0x01, 0x6B, 0x64, 0xEA, -0x5F, 0x99, 0x6F, 0xEB, 0x6C, 0xEA, 0x5F, 0xD9, 0x24, 0xF5, 0x49, 0xA4, -0xFF, 0x6C, 0x8C, 0xEA, 0x01, 0x72, 0x10, 0x60, 0x09, 0x96, 0x10, 0xF0, -0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x00, 0x6D, 0x63, 0xF3, 0x00, 0x4A, -0x4D, 0xE6, 0x85, 0x67, 0xA9, 0xE3, 0x01, 0x4D, 0x1D, 0x55, 0x44, 0xF5, -0x86, 0xC2, 0xFA, 0x61, 0x06, 0x93, 0x88, 0x67, 0x00, 0x6E, 0x89, 0xE3, -0x24, 0xF5, 0xC9, 0xC2, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, -0x9D, 0xF7, 0x18, 0x4A, 0x00, 0x9A, 0x10, 0xF0, 0x02, 0x6F, 0x00, 0xF4, -0xE0, 0x37, 0x10, 0xF0, 0x02, 0x6E, 0x00, 0xF4, 0xC0, 0x36, 0x00, 0x6D, -0x5C, 0xF4, 0x00, 0x4F, 0xDC, 0xF3, 0x0C, 0x4E, 0xA8, 0x32, 0xED, 0xE2, -0x60, 0x9B, 0x11, 0xE2, 0xC9, 0xE2, 0xC0, 0xF5, 0x74, 0xDC, 0x40, 0x9A, -0x01, 0x4D, 0x1D, 0x55, 0x60, 0xF5, 0x40, 0xDC, 0xF3, 0x61, 0x68, 0x67, -0x20, 0x23, 0x07, 0x94, 0xA8, 0x67, 0xFF, 0x4D, 0x04, 0xF5, 0x4B, 0xA4, -0xFF, 0x68, 0x42, 0xED, 0x18, 0x61, 0x08, 0x96, 0x10, 0xF0, 0x02, 0x6B, -0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x69, 0xE6, 0x04, 0xF5, -0x8B, 0xA2, 0x04, 0xF5, 0xC4, 0x9A, 0x01, 0x6F, 0x0C, 0xEC, 0x67, 0x67, -0x64, 0xED, 0x46, 0x67, 0x6C, 0xEA, 0x6E, 0xEA, 0x00, 0xF1, 0x03, 0x22, -0xFF, 0x4D, 0x82, 0xED, 0xF6, 0x60, 0x88, 0x67, 0x10, 0xF0, 0x02, 0x6E, -0x00, 0xF4, 0xC0, 0x36, 0x88, 0x32, 0x63, 0xF3, 0x00, 0x4E, 0xC9, 0xE2, -0xC0, 0xF5, 0x94, 0x9A, 0x60, 0xF5, 0x40, 0x9A, 0x84, 0x33, 0x8D, 0xE3, -0x69, 0xE2, 0x4A, 0x37, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, -0xCB, 0xF4, 0x46, 0xA2, 0xFF, 0x6B, 0x6C, 0xEA, 0x22, 0x72, 0xC0, 0xF0, -0x17, 0x61, 0x88, 0x67, 0x13, 0x74, 0x3F, 0xF7, 0x0D, 0x60, 0x07, 0x96, -0x01, 0x6B, 0x64, 0xEC, 0x64, 0xF5, 0x44, 0x9E, 0xFF, 0xF7, 0xEC, 0xD9, -0x6D, 0xEA, 0x64, 0xF5, 0x44, 0xDE, 0x05, 0x96, 0x27, 0xF1, 0x44, 0x9E, -0xFF, 0xF7, 0x1F, 0x72, 0x3F, 0xF7, 0x05, 0x60, 0x04, 0x95, 0xFF, 0x6A, -0x88, 0x67, 0x00, 0x18, 0x93, 0x21, 0x4C, 0xED, 0x1E, 0x17, 0x00, 0x6B, -0xFF, 0xF7, 0x6C, 0xD9, 0xB0, 0x16, 0x1F, 0xF7, 0x18, 0x26, 0x05, 0x94, -0x68, 0x67, 0x68, 0x32, 0x89, 0xE2, 0xC0, 0xF5, 0x54, 0x9A, 0x43, 0xEF, -0x4E, 0x17, 0x48, 0x67, 0x1C, 0x5A, 0xFF, 0xF6, 0x17, 0x60, 0x06, 0x94, -0x4D, 0xE4, 0x24, 0xF5, 0x49, 0xA3, 0xFF, 0x6C, 0x01, 0x72, 0x53, 0x60, -0x0C, 0x96, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x00, 0x6D, -0x63, 0xF3, 0x00, 0x4A, 0x4D, 0xE6, 0x85, 0x67, 0xA9, 0xE3, 0x01, 0x4D, -0x1D, 0x55, 0x44, 0xF5, 0x86, 0xC2, 0xFA, 0x61, 0x06, 0x93, 0x88, 0x67, -0x00, 0x6E, 0x89, 0xE3, 0x01, 0x6C, 0x04, 0xF5, 0xCC, 0xC2, 0x24, 0xF5, -0xC9, 0xC2, 0x64, 0x67, 0x48, 0x67, 0x64, 0xEA, 0x5F, 0x99, 0x6F, 0xEB, -0x6C, 0xEA, 0x68, 0x67, 0x5F, 0xD9, 0x4E, 0x23, 0x20, 0xF0, 0x42, 0xA1, -0xA8, 0x67, 0x01, 0x4D, 0xA2, 0xEA, 0xFF, 0x68, 0x17, 0x61, 0x0A, 0x93, -0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x63, 0xF3, 0x00, 0x4C, -0x89, 0xE3, 0x04, 0xF5, 0x8A, 0xA2, 0x04, 0xF5, 0xC4, 0x9A, 0x01, 0x6F, -0x0C, 0xEC, 0x67, 0x67, 0x64, 0xED, 0x46, 0x67, 0x6C, 0xEA, 0x6E, 0xEA, -0x6F, 0x22, 0x01, 0x4D, 0xA2, 0xEC, 0xF7, 0x60, 0x10, 0xF0, 0x02, 0x6A, -0x00, 0xF4, 0x40, 0x32, 0xCB, 0xF4, 0x46, 0xA2, 0x22, 0x72, 0xBF, 0xF6, -0x07, 0x61, 0x48, 0x67, 0xEE, 0x4A, 0xFF, 0x6B, 0x6C, 0xEA, 0x02, 0x5A, -0xBF, 0xF6, 0x00, 0x60, 0x18, 0x6E, 0x0E, 0x65, 0x9D, 0x16, 0xC8, 0x67, -0x18, 0x5E, 0x3F, 0x61, 0x44, 0xF5, 0x46, 0xA3, 0x4C, 0xEC, 0x05, 0x5C, -0x03, 0x60, 0x01, 0x4A, 0x44, 0xF5, 0x46, 0xC3, 0x06, 0x93, 0x88, 0x67, -0x00, 0x6E, 0x89, 0xE3, 0x01, 0x6C, 0x04, 0xF5, 0xCC, 0xC2, 0x24, 0xF5, -0xC9, 0xC2, 0x64, 0x67, 0x48, 0x67, 0x64, 0xEA, 0x5F, 0x99, 0x6F, 0xEB, -0x6C, 0xEA, 0x68, 0x67, 0x5F, 0xD9, 0xB2, 0x2B, 0x20, 0xF0, 0x42, 0xA1, -0xA4, 0x67, 0xFF, 0x68, 0xAD, 0x22, 0x0B, 0x94, 0x10, 0xF0, 0x02, 0x6E, -0x00, 0xF4, 0xC0, 0x36, 0x63, 0xF3, 0x00, 0x4E, 0xC9, 0xE4, 0x04, 0xF5, -0x8A, 0xA2, 0xE5, 0x67, 0x04, 0xF5, 0xC4, 0x9A, 0x0C, 0xEC, 0x67, 0x67, -0x64, 0xED, 0x46, 0x67, 0x6C, 0xEA, 0x6E, 0xEA, 0x09, 0x22, 0x01, 0x4D, -0xA2, 0xEC, 0x96, 0x61, 0x67, 0x67, 0x64, 0xED, 0x46, 0x67, 0x6C, 0xEA, -0x6E, 0xEA, 0xF7, 0x2A, 0x0C, 0xED, 0x0D, 0x65, 0x8D, 0x17, 0x48, 0x67, -0x05, 0x5A, 0x05, 0x60, 0x44, 0xF5, 0x46, 0xA3, 0x4C, 0xEC, 0x03, 0x5C, -0xBD, 0x17, 0x44, 0xF5, 0x46, 0xA3, 0x4C, 0xEC, 0x04, 0x5C, 0xB8, 0x17, -0x07, 0x94, 0x48, 0x67, 0x01, 0x6B, 0x64, 0xEA, 0x64, 0xF5, 0x44, 0x9C, -0x6D, 0xEA, 0x64, 0xF5, 0x44, 0xDC, 0x50, 0x16, 0x0C, 0xED, 0x0D, 0x65, -0x91, 0x17, 0x0C, 0xED, 0x0D, 0x65, 0xFD, 0x16, 0xFC, 0x63, 0x10, 0xF0, -0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x05, 0xD1, 0x06, 0x62, 0x04, 0xD0, -0x63, 0xF3, 0x00, 0x4C, 0x87, 0xF0, 0x58, 0x9C, 0x87, 0xF0, 0x7D, 0xA4, -0x65, 0xE2, 0x87, 0xF0, 0x54, 0x9C, 0x43, 0xE9, 0xE0, 0xF0, 0x04, 0x60, -0x04, 0x67, 0x0C, 0x10, 0x10, 0xF0, 0x02, 0x68, 0x00, 0xF4, 0x00, 0x30, -0x63, 0xF3, 0x00, 0x48, 0x87, 0xF0, 0x54, 0x98, 0x10, 0x49, 0x43, 0xE9, -0xC0, 0xF0, 0x16, 0x60, 0x87, 0xF0, 0x5D, 0xA0, 0xFF, 0xF7, 0x1F, 0x6D, -0x2C, 0xED, 0x10, 0x4A, 0x87, 0xF0, 0x5D, 0xC0, 0xEF, 0xF7, 0x1E, 0x6A, -0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, -0x80, 0x34, 0xAA, 0xF2, 0x14, 0x4C, 0x4D, 0xED, 0x00, 0x1C, 0xF4, 0x54, -0x10, 0x6E, 0x46, 0xF7, 0xB8, 0x98, 0x1F, 0x6B, 0x40, 0xF4, 0xA2, 0x34, -0x6C, 0xEC, 0x8C, 0x32, 0x89, 0xE2, 0x48, 0x32, 0x89, 0xE2, 0x48, 0x32, -0x19, 0xE2, 0x04, 0xF5, 0x48, 0x9E, 0x01, 0x6B, 0x42, 0x32, 0x52, 0x32, -0x6C, 0xEA, 0xFF, 0x6B, 0x6C, 0xEA, 0xC8, 0x22, 0xC9, 0xF7, 0x1B, 0x6B, -0x6B, 0xEB, 0x60, 0x33, 0x60, 0x33, 0x60, 0xF1, 0x00, 0x4B, 0x69, 0xE4, -0x40, 0xA2, 0xFF, 0x6B, 0xFF, 0x6F, 0x4C, 0xEB, 0x0B, 0x65, 0x46, 0xF7, -0x74, 0x98, 0x3F, 0x68, 0x80, 0xF5, 0x62, 0x32, 0x0C, 0xEA, 0x05, 0x52, -0x4C, 0xEF, 0x01, 0x61, 0x04, 0x6F, 0xC0, 0xF7, 0x62, 0x32, 0x0E, 0x2A, -0xE4, 0xF4, 0x54, 0x9E, 0x04, 0x6F, 0x01, 0x4A, 0xE4, 0xF4, 0x54, 0xDE, -0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, -0x46, 0xF7, 0xB8, 0x9A, 0xA2, 0x32, 0x52, 0x32, 0x1F, 0x6B, 0x6C, 0xEA, -0x08, 0x52, 0x52, 0x60, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, -0x63, 0xF3, 0x00, 0x4D, 0x46, 0xF7, 0x54, 0x9D, 0x0C, 0xEA, 0x08, 0x67, -0x0E, 0xEA, 0x46, 0x2A, 0x74, 0x27, 0x01, 0x77, 0x05, 0x61, 0xC4, 0xF4, -0x5C, 0x9E, 0x01, 0x4A, 0xC4, 0xF4, 0x5C, 0xDE, 0x02, 0x77, 0x05, 0x61, -0xE4, 0xF4, 0x40, 0x9E, 0x01, 0x4A, 0xE4, 0xF4, 0x40, 0xDE, 0x03, 0x77, -0x05, 0x61, 0xE4, 0xF4, 0x44, 0x9E, 0x01, 0x4A, 0xE4, 0xF4, 0x44, 0xDE, -0x04, 0x77, 0x05, 0x61, 0xE4, 0xF4, 0x48, 0x9E, 0x01, 0x4A, 0xE4, 0xF4, -0x48, 0xDE, 0x10, 0xF0, 0x02, 0x68, 0x00, 0xF4, 0x00, 0x30, 0xA8, 0x67, -0x63, 0xF3, 0x00, 0x48, 0x09, 0xE5, 0xE4, 0xF4, 0x78, 0x9E, 0x00, 0xF5, -0x44, 0xA2, 0xFF, 0x6D, 0x72, 0x33, 0xAC, 0xEA, 0x43, 0xEB, 0x4D, 0x61, -0xE4, 0xF4, 0x4C, 0x9E, 0x08, 0x67, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, -0x60, 0x33, 0x01, 0x4A, 0xE4, 0xF4, 0x4C, 0xDE, 0x08, 0x32, 0x63, 0xF3, -0x00, 0x4B, 0x09, 0xE2, 0x69, 0xE2, 0xE9, 0xE2, 0xA0, 0xF3, 0x68, 0xA2, -0xAC, 0xEB, 0xC4, 0xF4, 0x54, 0x9E, 0x69, 0xE2, 0xC4, 0xF4, 0x54, 0xDE, -0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, -0x08, 0xF0, 0x54, 0x9B, 0x3F, 0xF7, 0x1E, 0x22, 0x05, 0x74, 0x3F, 0xF7, -0x1B, 0x61, 0x46, 0xF7, 0x54, 0x9B, 0xC0, 0xF7, 0x42, 0x32, 0x3F, 0xF7, -0x15, 0x22, 0x00, 0x6A, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, -0x10, 0xF0, 0x02, 0x68, 0x00, 0xF4, 0x00, 0x30, 0x08, 0xF0, 0x54, 0xDB, -0x9D, 0xF7, 0x1C, 0x4C, 0x63, 0xF3, 0x00, 0x48, 0x00, 0x1C, 0x13, 0x58, -0x10, 0x49, 0x87, 0xF0, 0x54, 0x98, 0x43, 0xE9, 0x3F, 0xF7, 0x0A, 0x61, -0x06, 0x97, 0x05, 0x91, 0x04, 0x90, 0x00, 0xEF, 0x04, 0x63, 0xC4, 0xF4, -0x58, 0x9E, 0x01, 0x4A, 0xC4, 0xF4, 0x58, 0xDE, 0x86, 0x17, 0xE4, 0xF4, -0x50, 0x9E, 0xA8, 0x67, 0x10, 0xF0, 0x02, 0x68, 0x00, 0xF4, 0x00, 0x30, -0x01, 0x4A, 0xE4, 0xF4, 0x50, 0xDE, 0xA8, 0x32, 0xA9, 0xE2, 0x63, 0xF3, -0x00, 0x48, 0x09, 0xE2, 0xE9, 0xE2, 0x20, 0xF4, 0x79, 0xA2, 0xFF, 0x6A, -0x4C, 0xEB, 0xB1, 0x17, 0xE0, 0x63, 0x00, 0x6A, 0x3E, 0x62, 0x3D, 0xD1, -0x3C, 0xD0, 0xFC, 0x63, 0x1D, 0xD2, 0x62, 0x67, 0x1D, 0x94, 0x04, 0x05, -0x07, 0x68, 0x94, 0x32, 0xA9, 0xE2, 0x1E, 0xD0, 0x60, 0xDA, 0x1E, 0x94, -0x04, 0x4A, 0xFF, 0x4C, 0x00, 0x54, 0x1E, 0xD4, 0xF9, 0x60, 0x1D, 0x95, -0x01, 0x4D, 0x03, 0x5D, 0x1D, 0xD5, 0xEE, 0x61, 0xC9, 0xF7, 0x1B, 0x6A, -0x4B, 0xEA, 0x40, 0x31, 0x20, 0x31, 0xC0, 0xF2, 0x44, 0x41, 0x1D, 0xD3, -0x60, 0xDA, 0x41, 0x99, 0x01, 0xF7, 0x00, 0x6B, 0x01, 0xF4, 0x84, 0x41, -0x42, 0x32, 0x6C, 0xEA, 0x42, 0x32, 0x00, 0x1C, 0xFA, 0x5B, 0x33, 0xD2, -0x01, 0xF4, 0x88, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x31, 0xD2, 0x9D, 0x67, -0x70, 0x4C, 0x00, 0x1C, 0x8A, 0x40, 0x32, 0xD2, 0x1D, 0x94, 0x10, 0x6D, -0xA4, 0xED, 0x00, 0x1C, 0xAC, 0x45, 0xFF, 0x4D, 0x9D, 0x67, 0x70, 0x4C, -0x00, 0x1C, 0x90, 0x40, 0x1F, 0xD2, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, -0x00, 0x1C, 0xF0, 0x42, 0x01, 0x6C, 0x9D, 0x67, 0x00, 0x1C, 0x8A, 0x40, -0x70, 0x4C, 0x1D, 0x94, 0x10, 0x6D, 0xA4, 0xED, 0x00, 0x1C, 0xAC, 0x45, -0xFF, 0x4D, 0x9D, 0x67, 0x70, 0x4C, 0x00, 0x1C, 0x90, 0x40, 0x20, 0xD2, -0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x00, 0x1C, 0xF0, 0x42, 0x1D, 0x94, -0xE1, 0xF6, 0x80, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xD1, 0xF6, -0x8C, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x21, 0xD2, 0x71, 0xF6, 0x80, 0x41, -0x00, 0x1C, 0xFA, 0x5B, 0x22, 0xD2, 0x71, 0xF6, 0x84, 0x41, 0x00, 0x1C, -0xFA, 0x5B, 0x23, 0xD2, 0x71, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xFA, 0x5B, -0x24, 0xD2, 0x71, 0xF6, 0x8C, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x25, 0xD2, -0x81, 0xF6, 0x80, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x26, 0xD2, 0x81, 0xF6, -0x84, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x27, 0xD2, 0x81, 0xF6, 0x88, 0x41, -0x00, 0x1C, 0xFA, 0x5B, 0x28, 0xD2, 0x81, 0xF6, 0x8C, 0x41, 0x00, 0x1C, -0xFA, 0x5B, 0x29, 0xD2, 0xD1, 0xF6, 0x80, 0x41, 0x00, 0x1C, 0xFA, 0x5B, -0x2A, 0xD2, 0xD1, 0xF6, 0x84, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x2B, 0xD2, -0xD1, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x2C, 0xD2, 0x2D, 0xD2, -0xE7, 0xF7, 0x0E, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA2, 0x67, 0xE1, 0xF6, -0x80, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x36, 0xD2, -0x36, 0x95, 0xD1, 0xF6, 0x8C, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, -0xDD, 0x5B, 0x00, 0x65, 0x36, 0x95, 0x71, 0xF6, 0x80, 0x41, 0xF2, 0xF2, -0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x36, 0x95, 0x71, 0xF6, -0x84, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, -0x36, 0x95, 0x71, 0xF6, 0x88, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, -0xDD, 0x5B, 0x00, 0x65, 0x36, 0x95, 0x71, 0xF6, 0x8C, 0x41, 0xF2, 0xF2, -0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x36, 0x95, 0x81, 0xF6, -0x80, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, -0x36, 0x95, 0x81, 0xF6, 0x84, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, -0xDD, 0x5B, 0x00, 0x65, 0x36, 0x95, 0x81, 0xF6, 0x88, 0x41, 0xF2, 0xF2, -0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x36, 0x95, 0x81, 0xF6, -0x8C, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, -0x36, 0x95, 0xD1, 0xF6, 0x80, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, -0xDD, 0x5B, 0x00, 0x65, 0x36, 0x95, 0xD1, 0xF6, 0x84, 0x41, 0xF2, 0xF2, -0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x36, 0x95, 0xD1, 0xF6, -0x88, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, -0x33, 0x93, 0x01, 0x6A, 0x1D, 0x90, 0x4E, 0xEB, 0x43, 0xEB, 0x58, 0x67, -0x39, 0xD2, 0x0F, 0xF7, 0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x10, 0xF0, -0x00, 0x4A, 0x43, 0xD2, 0x00, 0xF5, 0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x32, -0x40, 0x32, 0x1E, 0xD0, 0x37, 0xD2, 0x11, 0x67, 0x01, 0xF0, 0x00, 0x6A, -0x4B, 0xEA, 0x40, 0x32, 0x00, 0x6B, 0x40, 0x32, 0x1D, 0xD3, 0x38, 0xD2, -0x33, 0x94, 0x60, 0xF1, 0x13, 0x24, 0x39, 0x95, 0xE0, 0xF1, 0x0C, 0x2D, -0xA1, 0xF6, 0x8C, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x05, 0xF0, -0x00, 0x6B, 0x6B, 0xEB, 0x60, 0x33, 0x60, 0x33, 0x4C, 0xEB, 0x01, 0x5B, -0x58, 0x67, 0x91, 0xF6, 0x84, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x35, 0xD2, -0xE0, 0xF3, 0x1F, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x6C, 0xEA, 0x42, 0x32, -0x42, 0x32, 0xB1, 0xF6, 0x84, 0x40, 0x3D, 0xD3, 0x00, 0x1C, 0xFA, 0x5B, -0x2E, 0xD2, 0x3D, 0x94, 0x8C, 0xEA, 0x42, 0x32, 0x42, 0x32, 0x91, 0xF6, -0x8C, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x2F, 0xD2, 0x3D, 0x95, 0xB1, 0xF6, -0x8C, 0x40, 0xAC, 0xEA, 0x42, 0x32, 0x42, 0x32, 0x00, 0x1C, 0xFA, 0x5B, -0x30, 0xD2, 0x3D, 0x93, 0x2E, 0x94, 0x4C, 0xEB, 0x62, 0x32, 0x20, 0xF1, -0x00, 0x74, 0x42, 0x32, 0xA0, 0xF2, 0x15, 0x60, 0x2F, 0x95, 0x20, 0xF1, -0x00, 0x75, 0xA0, 0xF2, 0x10, 0x60, 0x30, 0x93, 0x20, 0x73, 0xA0, 0xF2, -0x0C, 0x60, 0x20, 0x72, 0x01, 0x6B, 0xA0, 0xF2, 0x08, 0x60, 0x2E, 0x94, -0x80, 0x74, 0xA0, 0xF2, 0x02, 0x60, 0x2F, 0x95, 0x80, 0x75, 0x80, 0xF2, -0x1E, 0x60, 0x30, 0x94, 0xE0, 0xF3, 0x00, 0x74, 0x80, 0xF2, 0x19, 0x60, -0xE0, 0xF3, 0x00, 0x72, 0x01, 0x6A, 0x80, 0xF2, 0x14, 0x60, 0x35, 0x95, -0x03, 0x25, 0x02, 0x23, 0x20, 0xF4, 0x19, 0x2A, 0x1D, 0x95, 0x01, 0x4D, -0x0A, 0x5D, 0x1D, 0xD5, 0x97, 0x61, 0x1E, 0x92, 0x01, 0x4A, 0x03, 0x5A, -0x1E, 0xD2, 0x8A, 0x61, 0x04, 0x90, 0x20, 0xF4, 0x09, 0x28, 0x0C, 0x91, -0x03, 0x29, 0x14, 0x92, 0xFF, 0x6C, 0x2B, 0x22, 0x90, 0x67, 0x00, 0x18, -0xA1, 0x5E, 0xB1, 0x67, 0x03, 0x5A, 0x07, 0x60, 0x05, 0x94, 0x00, 0x18, -0xA1, 0x5E, 0x0D, 0x95, 0x03, 0x5A, 0x00, 0x6C, 0x1E, 0x61, 0x14, 0x93, -0x90, 0x67, 0xA3, 0x67, 0x00, 0x18, 0xA1, 0x5E, 0x40, 0xD3, 0x03, 0x5A, -0x07, 0x60, 0x05, 0x94, 0x00, 0x18, 0xA1, 0x5E, 0x15, 0x95, 0x03, 0x5A, -0x00, 0x6C, 0x0F, 0x61, 0x40, 0x95, 0x00, 0x18, 0xA1, 0x5E, 0x91, 0x67, -0x03, 0x5A, 0x40, 0xF2, 0x1E, 0x60, 0x0D, 0x94, 0x00, 0x18, 0xA1, 0x5E, -0x15, 0x95, 0x03, 0x5A, 0x01, 0x6C, 0x40, 0xF2, 0x16, 0x60, 0xFF, 0x74, -0x40, 0xF2, 0x17, 0x60, 0x04, 0x05, 0x94, 0x34, 0x10, 0xF0, 0x02, 0x69, -0x00, 0xF4, 0x20, 0x31, 0xB1, 0xE4, 0x63, 0xF3, 0x00, 0x49, 0x60, 0x9C, -0x43, 0x99, 0x00, 0xF4, 0x00, 0x68, 0xE0, 0xF3, 0x1F, 0x6F, 0x0B, 0xE8, -0xEC, 0xEB, 0x0C, 0xEA, 0x6D, 0xEA, 0x61, 0x9C, 0x02, 0xF0, 0x00, 0x6E, -0xCB, 0xEE, 0xEC, 0xEB, 0xC0, 0x36, 0xE0, 0xF3, 0x1F, 0x4E, 0x60, 0x33, -0x68, 0x33, 0xCC, 0xEA, 0xE7, 0xF7, 0x10, 0x6D, 0x6D, 0xEA, 0xAB, 0xED, -0x62, 0x9C, 0xA0, 0x35, 0xA0, 0x35, 0xFF, 0x4D, 0xEC, 0xEB, 0x00, 0xF5, -0x60, 0x33, 0xAC, 0xEA, 0x6D, 0xEA, 0x43, 0xD9, 0x63, 0x9C, 0x44, 0x99, -0xEC, 0xEB, 0x0C, 0xEA, 0x6D, 0xEA, 0x64, 0x9C, 0xCC, 0xEA, 0xEC, 0xEB, -0x60, 0x33, 0x68, 0x33, 0x6D, 0xEA, 0x65, 0x9C, 0xAC, 0xEA, 0xEC, 0xEB, -0x00, 0xF5, 0x60, 0x33, 0x6D, 0xEA, 0x44, 0xD9, 0x46, 0x9C, 0x10, 0xF0, -0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x4A, 0xC9, -0x47, 0x9C, 0x4B, 0xC9, 0x44, 0x9B, 0x80, 0xF7, 0x42, 0x32, 0x01, 0x72, -0xC0, 0xF2, 0x1E, 0x61, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x31, -0x20, 0x31, 0xE1, 0xF6, 0x80, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x21, 0x95, -0xD1, 0xF6, 0x8C, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x22, 0x95, 0x71, 0xF6, -0x80, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x23, 0x95, 0x71, 0xF6, 0x84, 0x41, -0x00, 0x1C, 0xDD, 0x5B, 0x24, 0x95, 0x71, 0xF6, 0x88, 0x41, 0x00, 0x1C, -0xDD, 0x5B, 0x25, 0x95, 0x71, 0xF6, 0x8C, 0x41, 0x00, 0x1C, 0xDD, 0x5B, -0x26, 0x95, 0x81, 0xF6, 0x80, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x27, 0x95, -0x81, 0xF6, 0x84, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x28, 0x95, 0x81, 0xF6, -0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x29, 0x95, 0x81, 0xF6, 0x8C, 0x41, -0x00, 0x1C, 0xDD, 0x5B, 0x2A, 0x95, 0xD1, 0xF6, 0x80, 0x41, 0x00, 0x1C, -0xDD, 0x5B, 0x2B, 0x95, 0xD1, 0xF6, 0x84, 0x41, 0x00, 0x1C, 0xDD, 0x5B, -0x2C, 0x95, 0x81, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x2D, 0x95, -0x1F, 0x96, 0x10, 0x6D, 0xA4, 0xED, 0xFF, 0x4D, 0x00, 0x1C, 0x83, 0x45, -0x00, 0x6C, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x00, 0x1C, 0xF0, 0x42, -0x01, 0x6C, 0x20, 0x96, 0x10, 0x6D, 0xA4, 0xED, 0xFF, 0x4D, 0x00, 0x1C, -0x83, 0x45, 0x00, 0x6C, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x00, 0x1C, -0xF0, 0x42, 0x00, 0x6C, 0x10, 0x6D, 0xA4, 0xED, 0x1E, 0x6C, 0x00, 0x1C, -0xAC, 0x45, 0xFF, 0x4D, 0x01, 0x6E, 0x22, 0x67, 0x4D, 0xEE, 0x10, 0x6D, -0x03, 0x6A, 0x4B, 0xEA, 0xA4, 0xED, 0x4C, 0xEE, 0xFF, 0x4D, 0x00, 0x1C, -0x83, 0x45, 0x1E, 0x6C, 0x00, 0x1C, 0x2C, 0x1F, 0x03, 0x6C, 0x10, 0x6D, -0x03, 0x6A, 0xD1, 0x67, 0xA4, 0xED, 0x1E, 0x6C, 0xFF, 0x4D, 0x00, 0x1C, -0x83, 0x45, 0x4D, 0xEE, 0x04, 0x63, 0x3E, 0x97, 0x3D, 0x91, 0x3C, 0x90, -0x00, 0xEF, 0x20, 0x63, 0xA0, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x01, 0xF4, -0x84, 0x40, 0x2A, 0xF4, 0x10, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, -0x08, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x7F, 0x4D, 0x01, 0xF4, 0x88, 0x40, -0x00, 0x1C, 0xDD, 0x5B, 0x65, 0x4D, 0x8F, 0xF7, 0x00, 0x6D, 0xAB, 0xED, -0xA0, 0x35, 0x21, 0xF6, 0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0xA0, 0x35, -0x00, 0xF2, 0x14, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x41, 0xF6, 0x80, 0x40, -0x40, 0xF1, 0x08, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x0D, 0xF0, -0x16, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x41, 0xF6, 0x84, 0x40, 0xA0, 0xF4, -0x02, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x41, 0xF6, 0x8C, 0x40, -0xC5, 0xF0, 0x11, 0x6D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x00, 0xF2, -0x14, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x61, 0xF6, 0x80, 0x40, 0x40, 0xF1, -0x0D, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x05, 0xF0, 0x16, 0x6D, -0xA0, 0x35, 0xA0, 0x35, 0x61, 0xF6, 0x84, 0x40, 0xA1, 0xF0, 0x1A, 0x4D, -0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x61, 0xF6, 0x8C, 0x40, 0xC5, 0xF0, -0x11, 0x6D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x37, 0x95, 0x41, 0xF6, -0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x01, 0x4D, 0x38, 0x95, 0x41, 0xF6, -0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x01, 0x4D, 0x00, 0x1C, 0x2C, 0x1F, -0x03, 0x6C, 0xA0, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x01, 0xF4, 0x84, 0x40, -0x2A, 0xF4, 0x13, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x01, 0xF4, -0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0xE4, 0x6D, 0x21, 0xF6, 0x88, 0x40, -0x00, 0x1C, 0xDD, 0x5B, 0x33, 0x95, 0x39, 0x95, 0x1F, 0xF6, 0x14, 0x25, -0x21, 0xF0, 0x80, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xFF, 0x6D, -0x01, 0x4D, 0xAC, 0xEA, 0x42, 0x32, 0x34, 0xD2, 0x02, 0x22, 0x01, 0x6A, -0x34, 0xD2, 0xA0, 0x35, 0xA0, 0x35, 0x21, 0xF0, 0x80, 0x41, 0x3A, 0xD5, -0x00, 0xF1, 0x00, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x3A, 0x95, -0x21, 0xF0, 0x88, 0x41, 0x00, 0xF1, 0x00, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, -0x00, 0x65, 0xA0, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x01, 0xF4, 0x84, 0x41, -0x2A, 0xF4, 0x10, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x08, 0x6D, -0xA0, 0x35, 0xA0, 0x35, 0x7F, 0x4D, 0x01, 0xF4, 0x88, 0x41, 0x00, 0x1C, -0xDD, 0x5B, 0x65, 0x4D, 0x43, 0x93, 0x21, 0xF6, 0x88, 0x41, 0x00, 0x1C, -0xDD, 0x5B, 0x60, 0x35, 0x3A, 0x95, 0x31, 0xF6, 0x80, 0x41, 0x0F, 0xF4, -0x00, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x3A, 0x95, 0x31, 0xF6, -0x84, 0x41, 0x09, 0xF0, 0x00, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, -0x02, 0xF0, 0x01, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x31, 0xF6, 0x88, 0x41, -0x3B, 0xD5, 0x1B, 0xF4, 0x1F, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, -0x3B, 0x95, 0x31, 0xF6, 0x8C, 0x41, 0x11, 0xF4, 0x1F, 0x4D, 0x00, 0x1C, -0xDD, 0x5B, 0x00, 0x65, 0x00, 0xF2, 0x14, 0x6D, 0xA0, 0x35, 0xA0, 0x35, -0x41, 0xF6, 0x80, 0x41, 0x00, 0xF1, 0x02, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, -0x00, 0x65, 0x0D, 0xF0, 0x16, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x41, 0xF6, -0x84, 0x41, 0xC0, 0xF4, 0x07, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, -0x41, 0xF6, 0x8C, 0x41, 0xC5, 0xF0, 0x11, 0x6D, 0x00, 0x1C, 0xDD, 0x5B, -0x00, 0x65, 0x61, 0xF6, 0x8C, 0x41, 0xC5, 0xF0, 0x11, 0x6D, 0x00, 0x1C, -0xDD, 0x5B, 0x00, 0x65, 0x3A, 0x95, 0x51, 0xF6, 0x80, 0x41, 0x0F, 0xF4, -0x00, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x3A, 0x95, 0x51, 0xF6, -0x84, 0x41, 0x09, 0xF0, 0x00, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, -0x3B, 0x95, 0x51, 0xF6, 0x88, 0x41, 0x3B, 0xF4, 0x03, 0x4D, 0x00, 0x1C, -0xDD, 0x5B, 0x00, 0x65, 0x3B, 0x95, 0x51, 0xF6, 0x8C, 0x41, 0x31, 0xF4, -0x03, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x00, 0xF2, 0x14, 0x6D, -0xA0, 0x35, 0xA0, 0x35, 0x61, 0xF6, 0x80, 0x41, 0x00, 0xF1, 0x02, 0x4D, -0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x05, 0xF0, 0x16, 0x6D, 0xA0, 0x35, -0xA0, 0x35, 0x61, 0xF6, 0x84, 0x41, 0x01, 0xF5, 0x07, 0x4D, 0x00, 0x1C, -0xDD, 0x5B, 0x00, 0x65, 0x41, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, -0x37, 0x95, 0x41, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x38, 0x95, -0x00, 0x1C, 0x2C, 0x1F, 0x03, 0x6C, 0x00, 0xF2, 0x00, 0x6A, 0x40, 0x32, -0x40, 0x32, 0xA2, 0x67, 0x41, 0xF6, 0x8C, 0x41, 0xC5, 0xF0, 0x11, 0x4D, -0x00, 0x1C, 0xDD, 0x5B, 0x3C, 0xD2, 0x3C, 0x95, 0x61, 0xF6, 0x8C, 0x41, -0xC5, 0xF0, 0x11, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x41, 0xF6, -0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x37, 0x95, 0x41, 0xF6, 0x88, 0x41, -0x00, 0x1C, 0xDD, 0x5B, 0x38, 0x95, 0x00, 0x1C, 0x2C, 0x1F, 0x03, 0x6C, -0x01, 0xF4, 0x84, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x31, 0x95, 0x01, 0xF4, -0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x32, 0x95, 0x21, 0xF6, 0x88, 0x41, -0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x6D, 0x34, 0x93, 0x1F, 0xF5, 0x1E, 0x2B, -0x21, 0xF0, 0x80, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x3A, 0x95, 0x21, 0xF0, -0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x3A, 0x95, 0x13, 0x15, 0x00, 0x6A, -0x6A, 0x15, 0x00, 0x6B, 0x56, 0x15, 0xFF, 0x6C, 0xFF, 0x74, 0xBF, 0xF5, -0x09, 0x61, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, -0x41, 0xD4, 0x81, 0xF6, 0x14, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, -0xE0, 0xF3, 0x1F, 0x6B, 0x60, 0x31, 0x20, 0x31, 0x2C, 0xEA, 0x42, 0x32, -0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x63, 0xF3, 0x00, 0x4C, -0x42, 0x32, 0x6C, 0xEA, 0x63, 0x9C, 0x00, 0xF4, 0x00, 0x6D, 0xAB, 0xED, -0xAC, 0xEB, 0x4D, 0xEB, 0x63, 0xDC, 0x41, 0x94, 0xE0, 0xF3, 0x1F, 0x68, -0x81, 0xF6, 0x1C, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x2C, 0xEA, -0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x10, 0x6D, 0x63, 0xF3, -0x00, 0x4C, 0x42, 0x32, 0xAB, 0xED, 0x63, 0x9C, 0x42, 0x32, 0xA0, 0x35, -0x0C, 0xEA, 0xA0, 0x35, 0xE0, 0xF3, 0x1F, 0x4D, 0x40, 0x32, 0xAC, 0xEB, -0x48, 0x32, 0x4D, 0xEB, 0x63, 0xDC, 0x41, 0x94, 0xA1, 0xF6, 0x04, 0x4C, -0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x2C, 0xEA, 0x42, 0x32, 0x42, 0x32, -0x0C, 0xEA, 0xE7, 0xF7, 0x10, 0x6C, 0x10, 0xF0, 0x02, 0x68, 0x00, 0xF4, -0x00, 0x30, 0x63, 0xF3, 0x00, 0x48, 0x8B, 0xEC, 0x63, 0x98, 0x80, 0x34, -0x80, 0x34, 0xFF, 0x4C, 0x00, 0xF5, 0x40, 0x32, 0x8C, 0xEB, 0x4D, 0xEB, -0x63, 0xD8, 0x41, 0x94, 0xA1, 0xF6, 0x0C, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, -0x00, 0x65, 0x2C, 0xEA, 0x64, 0x98, 0x42, 0x32, 0x00, 0xF4, 0x00, 0x68, -0xE0, 0xF3, 0x1F, 0x6D, 0x0B, 0xE8, 0x42, 0x32, 0xAC, 0xEA, 0x0C, 0xEB, -0x4D, 0xEB, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, -0x00, 0x4A, 0x64, 0xDA, 0x41, 0x94, 0xE0, 0xF3, 0x1F, 0x68, 0xA1, 0xF6, -0x14, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x2C, 0xEA, 0x42, 0x32, -0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x10, 0x6D, 0x63, 0xF3, -0x00, 0x4C, 0xE0, 0xF3, 0x1F, 0x6B, 0x42, 0x32, 0xAB, 0xED, 0x6C, 0xEA, -0xA0, 0x35, 0x64, 0x9C, 0xA0, 0x35, 0xE0, 0xF3, 0x1F, 0x4D, 0x40, 0x32, -0xAC, 0xEB, 0x48, 0x32, 0x4D, 0xEB, 0x64, 0xDC, 0x41, 0x94, 0xA1, 0xF6, -0x1C, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6C, -0x00, 0xF4, 0x80, 0x34, 0xE7, 0xF7, 0x10, 0x6D, 0x63, 0xF3, 0x00, 0x4C, -0x2C, 0xEA, 0xAB, 0xED, 0x64, 0x9C, 0x42, 0x32, 0xA0, 0x35, 0x42, 0x32, -0xA0, 0x35, 0xFF, 0x4D, 0x0C, 0xEA, 0xAC, 0xEB, 0x00, 0xF5, 0x40, 0x32, -0x4D, 0xEB, 0x64, 0xDC, 0x41, 0x94, 0x10, 0xF0, 0x02, 0x68, 0x00, 0xF4, -0x00, 0x30, 0x63, 0xF3, 0x00, 0x48, 0xC1, 0xF6, 0x04, 0x4C, 0x00, 0x1C, -0xFA, 0x5B, 0x00, 0x65, 0x2C, 0xEA, 0x42, 0x32, 0x42, 0x32, 0x4A, 0xC8, -0x41, 0x94, 0xC1, 0xF6, 0x0C, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, -0x4C, 0xE9, 0x22, 0x32, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, -0x42, 0x32, 0x63, 0xF3, 0x00, 0x4B, 0x4B, 0xC8, 0x44, 0x9B, 0x80, 0xF7, -0x42, 0x32, 0x01, 0x72, 0x3F, 0xF5, 0x02, 0x60, 0xC9, 0xF7, 0x1B, 0x6A, -0x4B, 0xEA, 0x40, 0x31, 0x20, 0x31, 0x81, 0xF4, 0x80, 0x41, 0x00, 0x1C, -0xFA, 0x5B, 0x00, 0x65, 0x82, 0x67, 0x10, 0xF0, 0x02, 0x68, 0x00, 0xF4, -0x00, 0x30, 0x40, 0x6A, 0x4B, 0xEA, 0x63, 0xF3, 0x00, 0x48, 0x40, 0x32, -0xC3, 0x98, 0x40, 0x32, 0x8C, 0xEA, 0xE0, 0xF3, 0x1F, 0x6B, 0x80, 0xF5, -0x42, 0x35, 0xCC, 0xEB, 0x00, 0xF2, 0x00, 0x6A, 0x6C, 0xEA, 0x04, 0x22, -0x00, 0xF4, 0x00, 0x6A, 0x4B, 0xEA, 0x4D, 0xEB, 0xB8, 0xEB, 0xE0, 0xF3, -0x1F, 0x68, 0x12, 0xEA, 0x42, 0x33, 0x0C, 0xEB, 0xC2, 0x30, 0xE0, 0xF3, -0x1F, 0x6A, 0x0A, 0x30, 0x4C, 0xE8, 0x00, 0xF2, 0x00, 0x6A, 0x0C, 0xEA, -0x04, 0x22, 0x00, 0xF4, 0x00, 0x6A, 0x4B, 0xEA, 0x4D, 0xE8, 0xB8, 0xE8, -0xE0, 0xF3, 0x1F, 0x6D, 0x12, 0xEA, 0x42, 0x30, 0x3F, 0x6A, 0x4B, 0xEA, -0xAC, 0xE8, 0x40, 0x32, 0x3F, 0x6D, 0x42, 0xD5, 0x40, 0x32, 0x0C, 0xED, -0x1F, 0xF4, 0x00, 0x4A, 0xA0, 0x35, 0x4C, 0xEC, 0xA0, 0x35, 0x8D, 0xED, -0x81, 0xF4, 0x80, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x6D, 0xED, 0x91, 0xF4, -0x84, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x02, 0xF0, 0x00, 0x6B, -0x60, 0x33, 0x60, 0x33, 0xFF, 0x4B, 0xC0, 0xF3, 0x00, 0x6C, 0x6C, 0xEA, -0x8C, 0xE8, 0x80, 0xF5, 0x00, 0x33, 0xA2, 0x67, 0x91, 0xF4, 0x84, 0x41, -0x00, 0x1C, 0xDD, 0x5B, 0x6D, 0xED, 0x81, 0xF4, 0x88, 0x41, 0x00, 0x1C, -0xFA, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, -0xBD, 0xF7, 0x10, 0x4D, 0x82, 0x67, 0x40, 0x9D, 0x8C, 0xEA, 0x80, 0xF5, -0x42, 0x35, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, -0x00, 0x4A, 0x04, 0x9A, 0xE0, 0xF3, 0x1F, 0x6A, 0x02, 0x33, 0x6A, 0x33, -0x4C, 0xEB, 0x00, 0xF2, 0x00, 0x6A, 0x6C, 0xEA, 0x04, 0x22, 0x00, 0xF4, -0x00, 0x6A, 0x4B, 0xEA, 0x4D, 0xEB, 0xB8, 0xEB, 0x00, 0xF5, 0x02, 0x30, -0x12, 0xEA, 0x42, 0x33, 0xE0, 0xF3, 0x1F, 0x6A, 0x4C, 0xE8, 0x4C, 0xEB, -0x00, 0xF2, 0x00, 0x6A, 0x0C, 0xEA, 0x04, 0x22, 0x00, 0xF4, 0x00, 0x6A, -0x4B, 0xEA, 0x4D, 0xE8, 0xB8, 0xE8, 0xE0, 0xF3, 0x1F, 0x6D, 0x12, 0xEA, -0x42, 0x30, 0xAC, 0xE8, 0x3F, 0x6A, 0x42, 0x95, 0x4B, 0xEA, 0x40, 0x32, -0x0C, 0xED, 0x40, 0x32, 0x1F, 0xF4, 0x00, 0x4A, 0x42, 0xD5, 0xA0, 0x35, -0x4C, 0xEC, 0xA0, 0x35, 0x8D, 0xED, 0x81, 0xF4, 0x88, 0x41, 0x00, 0x1C, -0xDD, 0x5B, 0x6D, 0xED, 0x91, 0xF4, 0x8C, 0x41, 0x00, 0x1C, 0xFA, 0x5B, -0x00, 0x65, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0xBD, 0xF7, -0x14, 0x4B, 0xA0, 0x9B, 0xC0, 0xF3, 0x00, 0x6C, 0x8C, 0xE8, 0x4C, 0xED, -0x80, 0xF5, 0x00, 0x32, 0x91, 0xF4, 0x8C, 0x41, 0x00, 0x1C, 0xDD, 0x5B, -0x4D, 0xED, 0x58, 0x14, 0x0C, 0x91, 0xDF, 0xF3, 0x19, 0x10, 0x1E, 0x93, -0x04, 0x04, 0x74, 0x32, 0x91, 0xE2, 0x3E, 0xD4, 0x91, 0xF6, 0x84, 0x40, -0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF3, 0x1F, 0x6B, 0x60, 0x33, -0x60, 0x33, 0x3E, 0x95, 0x6C, 0xEA, 0x42, 0x32, 0x42, 0x32, 0x3F, 0xD3, -0x91, 0xF6, 0x8C, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x40, 0xDD, 0x3F, 0x93, -0x3E, 0x94, 0x6C, 0xEA, 0x42, 0x32, 0x42, 0x32, 0x41, 0xDC, 0xA1, 0xF6, -0x84, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x3F, 0x95, 0x3E, 0x93, -0xA1, 0xF6, 0x8C, 0x40, 0xAC, 0xEA, 0x42, 0x32, 0x42, 0x32, 0x00, 0x1C, -0xFA, 0x5B, 0x42, 0xDB, 0x3F, 0x94, 0x3E, 0x95, 0x8C, 0xEA, 0x42, 0x32, -0x42, 0x32, 0xB1, 0xF6, 0x84, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x43, 0xDD, -0x3F, 0x93, 0x3E, 0x94, 0x6C, 0xEA, 0x42, 0x32, 0x42, 0x32, 0x44, 0xDC, -0xB1, 0xF6, 0x8C, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x3F, 0x95, -0x3E, 0x93, 0xC1, 0xF6, 0x84, 0x40, 0xAC, 0xEA, 0x42, 0x32, 0x42, 0x32, -0x00, 0x1C, 0xFA, 0x5B, 0x45, 0xDB, 0x3F, 0x94, 0x3E, 0x95, 0x8C, 0xEA, -0x42, 0x32, 0x42, 0x32, 0xC1, 0xF6, 0x8C, 0x40, 0x00, 0x1C, 0xFA, 0x5B, -0x46, 0xDD, 0x3F, 0x93, 0x3E, 0x94, 0x4C, 0xEB, 0x62, 0x32, 0x42, 0x32, -0x47, 0xDC, 0x7F, 0xF3, 0x0E, 0x10, 0x00, 0x00, 0xFB, 0x63, 0x07, 0xD1, -0x0C, 0xF0, 0x00, 0x6A, 0x10, 0xF0, 0x02, 0x69, 0x00, 0xF4, 0x20, 0x31, -0x63, 0xF3, 0x00, 0x49, 0x08, 0x62, 0x0A, 0xD4, 0x06, 0xD0, 0x4B, 0xEA, -0x62, 0x99, 0x40, 0x32, 0x40, 0x32, 0xFF, 0x4A, 0x4C, 0xEB, 0xC9, 0xF7, -0x1B, 0x6C, 0x04, 0xF0, 0x00, 0x6A, 0x40, 0x32, 0x8B, 0xEC, 0x40, 0x32, -0x80, 0x34, 0x4D, 0xEB, 0x80, 0x34, 0x62, 0xD9, 0x04, 0xD4, 0x81, 0xF6, -0x14, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF3, 0x1F, 0x6B, -0x60, 0x30, 0x00, 0x30, 0x0C, 0xEA, 0x42, 0x32, 0x42, 0x32, 0x6C, 0xEA, -0x63, 0x99, 0x00, 0xF4, 0x00, 0x6C, 0x8B, 0xEC, 0x8C, 0xEB, 0x4D, 0xEB, -0x63, 0xD9, 0x04, 0x94, 0x81, 0xF6, 0x1C, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, -0x00, 0x65, 0x0C, 0xEA, 0x42, 0x32, 0x10, 0x6C, 0xE0, 0xF3, 0x1F, 0x6B, -0x42, 0x32, 0x8B, 0xEC, 0x6C, 0xEA, 0x80, 0x34, 0x63, 0x99, 0x80, 0x34, -0xE0, 0xF3, 0x1F, 0x4C, 0x40, 0x32, 0x48, 0x32, 0x8C, 0xEB, 0x4D, 0xEB, -0x63, 0xD9, 0x04, 0x94, 0xA1, 0xF6, 0x04, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, -0x00, 0x65, 0x0C, 0xEA, 0x42, 0x32, 0xE7, 0xF7, 0x10, 0x6C, 0xE0, 0xF3, -0x1F, 0x6B, 0x42, 0x32, 0x8B, 0xEC, 0x6C, 0xEA, 0x80, 0x34, 0x63, 0x99, -0x80, 0x34, 0xFF, 0x4C, 0x00, 0xF5, 0x40, 0x32, 0x8C, 0xEB, 0x4D, 0xEB, -0x63, 0xD9, 0x04, 0x94, 0xA1, 0xF6, 0x0C, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, -0x00, 0x65, 0x0C, 0xEA, 0x42, 0x32, 0xE0, 0xF3, 0x1F, 0x6B, 0x42, 0x32, -0x6C, 0xEA, 0x64, 0x99, 0x00, 0xF4, 0x00, 0x6C, 0x8B, 0xEC, 0x8C, 0xEB, -0x4D, 0xEB, 0x64, 0xD9, 0x04, 0x94, 0xA1, 0xF6, 0x14, 0x4C, 0x00, 0x1C, -0xFA, 0x5B, 0x00, 0x65, 0x0C, 0xEA, 0x42, 0x32, 0x10, 0x6C, 0xE0, 0xF3, -0x1F, 0x6B, 0x42, 0x32, 0x8B, 0xEC, 0x6C, 0xEA, 0x80, 0x34, 0x64, 0x99, -0x80, 0x34, 0xE0, 0xF3, 0x1F, 0x4C, 0x40, 0x32, 0x48, 0x32, 0x8C, 0xEB, -0x4D, 0xEB, 0x64, 0xD9, 0x04, 0x94, 0xA1, 0xF6, 0x1C, 0x4C, 0x00, 0x1C, -0xFA, 0x5B, 0x00, 0x65, 0x0C, 0xEA, 0x42, 0x32, 0xE7, 0xF7, 0x10, 0x6C, -0xE0, 0xF3, 0x1F, 0x6B, 0x42, 0x32, 0x8B, 0xEC, 0x6C, 0xEA, 0x80, 0x34, -0x64, 0x99, 0x80, 0x34, 0xFF, 0x4C, 0x00, 0xF5, 0x40, 0x32, 0x8C, 0xEB, -0x4D, 0xEB, 0x64, 0xD9, 0x04, 0x94, 0xC1, 0xF6, 0x04, 0x4C, 0x00, 0x1C, -0xFA, 0x5B, 0x00, 0x65, 0x0C, 0xEA, 0x42, 0x32, 0x42, 0x32, 0x4A, 0xC9, -0x04, 0x94, 0xC1, 0xF6, 0x0C, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, -0x4C, 0xE8, 0xFF, 0x6A, 0x01, 0x4A, 0x40, 0x32, 0x40, 0x32, 0x0A, 0x93, -0x80, 0x4A, 0x02, 0x30, 0x80, 0x4A, 0x02, 0x30, 0x6C, 0xEA, 0x0B, 0xC9, -0x14, 0x22, 0x1F, 0xF7, 0x00, 0x6A, 0x0A, 0x94, 0x4C, 0xEB, 0x62, 0x33, -0xC0, 0xF2, 0x63, 0xC1, 0x82, 0x33, 0x4C, 0xEB, 0x62, 0x33, 0xC0, 0xF2, -0x67, 0xC1, 0x00, 0x18, 0x0A, 0x5F, 0x00, 0x65, 0x08, 0x97, 0x07, 0x91, -0x06, 0x90, 0x00, 0xEF, 0x05, 0x63, 0x12, 0x6A, 0xC0, 0xF2, 0x43, 0xC1, -0xC0, 0xF2, 0x47, 0xC1, 0x00, 0x18, 0x0A, 0x5F, 0x00, 0x65, 0x08, 0x97, -0x07, 0x91, 0x06, 0x90, 0x00, 0xEF, 0x05, 0x63, 0xC9, 0xF7, 0x1B, 0x6A, -0xFB, 0x63, 0x4B, 0xEA, 0x06, 0xD0, 0x40, 0x30, 0x07, 0xD1, 0x08, 0x62, -0x00, 0x30, 0x40, 0xF0, 0x4C, 0xA0, 0x03, 0x69, 0x4C, 0xE9, 0x10, 0xF0, -0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x62, 0x67, 0x04, 0xD2, 0x63, 0xF3, -0x00, 0x4B, 0xC3, 0xF3, 0x41, 0xA3, 0x2E, 0xEA, 0x1A, 0x22, 0x05, 0x29, -0xE0, 0xF2, 0x66, 0xA3, 0xFF, 0x6A, 0x4C, 0xEB, 0x1A, 0x23, 0x04, 0x92, -0xC9, 0xF7, 0x17, 0x6C, 0x8B, 0xEC, 0x63, 0xF3, 0x00, 0x4A, 0x04, 0xD2, -0xC3, 0xF3, 0x21, 0xC2, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, -0x40, 0x32, 0x76, 0x9A, 0x80, 0x34, 0x80, 0x34, 0x60, 0xDC, 0x57, 0x9A, -0x41, 0xDC, 0x08, 0x97, 0x07, 0x91, 0x06, 0x90, 0x00, 0x6A, 0x00, 0xEF, -0x05, 0x63, 0x51, 0xF4, 0x80, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x1C, 0x6D, -0x51, 0xF4, 0x88, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x1C, 0x6D, 0xDB, 0x17, -0xF9, 0x63, 0x0A, 0xD0, 0xC9, 0xF7, 0x1B, 0x68, 0x0B, 0xE8, 0x00, 0x30, -0x00, 0x30, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x0B, 0xD1, -0xA1, 0xF5, 0x82, 0x40, 0x22, 0x67, 0x63, 0xF3, 0x00, 0x49, 0x0C, 0x62, -0x00, 0x1C, 0xFD, 0x5B, 0x06, 0xD2, 0xC0, 0xF2, 0x58, 0xC9, 0xA1, 0xF5, -0x84, 0x40, 0x00, 0x1C, 0xFD, 0x5B, 0x00, 0x65, 0xC0, 0xF2, 0x5A, 0xC9, -0xA1, 0xF5, 0x86, 0x40, 0x00, 0x1C, 0xFD, 0x5B, 0x00, 0x65, 0xC0, 0xF2, -0x5C, 0xC9, 0xA1, 0xF5, 0x88, 0x40, 0x00, 0x1C, 0xFD, 0x5B, 0x00, 0x65, -0x82, 0x67, 0xC0, 0xF2, 0x7A, 0xA9, 0xC0, 0xF2, 0x5E, 0xC9, 0xC0, 0xF2, -0x58, 0xA9, 0x69, 0xE2, 0xC0, 0xF2, 0x7C, 0xA9, 0x69, 0xE2, 0x51, 0xE4, -0x04, 0xD4, 0x21, 0xF2, 0x8D, 0x40, 0x00, 0x1C, 0x00, 0x5C, 0x00, 0x65, -0x00, 0xF6, 0x40, 0x35, 0x00, 0xF6, 0xA3, 0x35, 0x40, 0x6A, 0xFF, 0x6B, -0x4D, 0xED, 0x6C, 0xED, 0x21, 0xF2, 0x8D, 0x40, 0x00, 0x1C, 0xF0, 0x5B, -0x05, 0xD3, 0x51, 0xF2, 0x8B, 0x40, 0x00, 0x1C, 0x00, 0x5C, 0x00, 0x65, -0x40, 0x32, 0x51, 0xF2, 0x8C, 0x40, 0xE0, 0xF2, 0x44, 0xC9, 0x00, 0x1C, -0x00, 0x5C, 0x00, 0x65, 0xE0, 0xF2, 0x64, 0xA9, 0x61, 0xF4, 0x84, 0x40, -0x75, 0xE2, 0x04, 0x93, 0xFF, 0xF7, 0x1F, 0x6A, 0xE0, 0xF2, 0xA4, 0xC9, -0x4C, 0xED, 0x69, 0xE5, 0xE0, 0xF2, 0x40, 0xD9, 0xFF, 0xF7, 0x1F, 0x6A, -0x00, 0x1C, 0xE6, 0x5B, 0x4C, 0xED, 0x43, 0xA9, 0xFF, 0xF7, 0x1F, 0x6B, -0x6C, 0xEA, 0x10, 0x52, 0x05, 0x60, 0xE0, 0xF2, 0x40, 0x99, 0x1F, 0x5A, -0xA0, 0xF0, 0x1E, 0x61, 0x00, 0x6A, 0xC0, 0xF2, 0x54, 0xC1, 0xC0, 0xF2, -0x55, 0xA1, 0x05, 0x93, 0x01, 0x4A, 0x4C, 0xEB, 0x03, 0x53, 0xA0, 0xF0, -0x0B, 0x60, 0xC0, 0xF2, 0x55, 0xC1, 0x06, 0x94, 0x00, 0x6A, 0x11, 0x6B, -0x63, 0xF3, 0x00, 0x4C, 0x43, 0xCC, 0xE0, 0xF2, 0x44, 0xCC, 0x40, 0x9C, -0x6C, 0xEA, 0x01, 0x72, 0x80, 0xF0, 0x13, 0x61, 0xE0, 0xF2, 0x44, 0x9C, -0x03, 0x6B, 0x00, 0xF7, 0x42, 0x32, 0x6C, 0xEA, 0x80, 0xF0, 0x0B, 0x2A, -0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF0, -0x4C, 0xA2, 0x4C, 0xEB, 0x01, 0x73, 0xA0, 0xF0, 0x04, 0x60, 0x06, 0x94, -0x63, 0xF3, 0x00, 0x4C, 0xE0, 0xF2, 0x46, 0xA4, 0xA0, 0xF0, 0x0B, 0x2A, -0x40, 0x9C, 0x01, 0x6B, 0x56, 0x32, 0x6C, 0xEA, 0xA0, 0xF0, 0x05, 0x22, -0x3E, 0x6A, 0xC0, 0xF2, 0x50, 0xC4, 0x1C, 0x6A, 0xC0, 0xF2, 0x51, 0xC4, -0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF0, -0x6C, 0xA2, 0xFF, 0x6A, 0x6C, 0xEA, 0x03, 0x6B, 0x6C, 0xEA, 0x61, 0x22, -0x66, 0xF7, 0x4C, 0x9C, 0xFF, 0xF7, 0x1F, 0x72, 0x5C, 0x60, 0xE0, 0xF2, -0x40, 0x9C, 0xE0, 0xF3, 0x09, 0x5A, 0x00, 0xF1, 0x03, 0x61, 0xC0, 0xF2, -0x72, 0xA4, 0x00, 0xF6, 0x60, 0x32, 0x00, 0xF6, 0x43, 0x32, 0xFE, 0x4A, -0xFF, 0xF7, 0x1C, 0x52, 0x04, 0x6A, 0x4B, 0xEA, 0x01, 0x61, 0x4E, 0x43, -0xC0, 0xF2, 0x52, 0xC4, 0x06, 0x96, 0x7F, 0x6B, 0x63, 0xF3, 0x00, 0x4E, -0x66, 0xF7, 0x4C, 0x9E, 0xC0, 0xF2, 0x8E, 0xA6, 0x52, 0x32, 0x6C, 0xEA, -0xA7, 0x42, 0xC0, 0xF2, 0x52, 0xA6, 0x03, 0x4D, 0xFF, 0x6B, 0x4B, 0xE5, -0x00, 0xF6, 0x40, 0x35, 0x43, 0x67, 0x00, 0xF6, 0xA3, 0x35, 0x8C, 0xEA, -0xA2, 0xEA, 0xE0, 0xF0, 0x0C, 0x60, 0x00, 0xF6, 0x80, 0x35, 0x00, 0xF6, -0xA3, 0x35, 0x06, 0x92, 0x63, 0xF3, 0x00, 0x4A, 0x06, 0xD2, 0xE0, 0xF2, -0x40, 0x9A, 0x04, 0xF7, 0x11, 0x5A, 0xC0, 0xF0, 0x01, 0x61, 0x32, 0x55, -0xA0, 0xF0, 0x1E, 0x60, 0x32, 0x6D, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, -0x40, 0x32, 0x40, 0x32, 0x21, 0xF4, 0x10, 0x4A, 0x44, 0x6B, 0xC9, 0xF7, -0x1B, 0x68, 0x0B, 0xE8, 0x60, 0xC2, 0x00, 0x30, 0xFF, 0x6A, 0xAC, 0xEA, -0x00, 0x30, 0xA2, 0x67, 0x51, 0xF4, 0x80, 0x40, 0x00, 0x1C, 0xF0, 0x5B, -0x08, 0xD2, 0x08, 0x92, 0x51, 0xF4, 0x88, 0x40, 0x00, 0x1C, 0xF0, 0x5B, -0xA2, 0x67, 0x00, 0x18, 0x08, 0x61, 0x00, 0x65, 0x0C, 0x97, 0x0B, 0x91, -0x0A, 0x90, 0x00, 0x6A, 0x00, 0xEF, 0x07, 0x63, 0x03, 0x6A, 0xC0, 0xF2, -0x55, 0xC1, 0x40, 0x99, 0x08, 0x6B, 0x6D, 0xEA, 0x40, 0xD9, 0x4F, 0x17, -0x00, 0x6A, 0xC0, 0xF2, 0x55, 0xC1, 0xC0, 0xF2, 0x54, 0xA1, 0x05, 0x93, -0x01, 0x4A, 0x4C, 0xEB, 0x03, 0x53, 0x14, 0x61, 0x03, 0x6A, 0xC0, 0xF2, -0x54, 0xC1, 0x40, 0x99, 0x09, 0x6B, 0x6B, 0xEB, 0x6C, 0xEA, 0x40, 0xD9, -0x3C, 0x17, 0xE0, 0xF2, 0x66, 0xA4, 0xFF, 0x6A, 0x4C, 0xEB, 0x5F, 0xF7, -0x16, 0x2B, 0x01, 0x6A, 0x4B, 0xEA, 0xE0, 0xF2, 0x46, 0xC4, 0x51, 0x17, -0xC0, 0xF2, 0x54, 0xC1, 0x2E, 0x17, 0x06, 0x90, 0xFF, 0x6D, 0x63, 0xF3, -0x00, 0x48, 0xE0, 0xF2, 0x46, 0xA0, 0xAA, 0xEA, 0xC6, 0x61, 0xC9, 0xF7, -0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x41, 0xF4, 0x10, 0x4C, -0x00, 0x1C, 0x00, 0x5C, 0x09, 0xD5, 0x09, 0x95, 0x00, 0xF6, 0x40, 0x31, -0x00, 0xF6, 0x23, 0x31, 0x7F, 0x6A, 0xAC, 0xE9, 0x4C, 0xE9, 0xE0, 0xF2, -0x60, 0x98, 0xC0, 0xF2, 0x48, 0xA8, 0xFF, 0xF7, 0x1F, 0x6C, 0x43, 0xEB, -0x38, 0x61, 0xC0, 0xF2, 0x4A, 0xA8, 0x8C, 0xEA, 0x43, 0xEB, 0x07, 0x61, -0xC0, 0xF2, 0x4C, 0xA8, 0x8C, 0xEA, 0x43, 0xEB, 0x69, 0x60, 0x01, 0x49, -0xAC, 0xE9, 0x06, 0x93, 0x63, 0xF3, 0x00, 0x4B, 0xC0, 0xF2, 0x50, 0xA3, -0x23, 0xEA, 0x32, 0x60, 0x22, 0x67, 0x06, 0x93, 0x63, 0xF3, 0x00, 0x4B, -0x06, 0xD3, 0xE0, 0xF2, 0x40, 0x9B, 0x04, 0xF7, 0x11, 0x5A, 0x1D, 0x61, -0x32, 0x69, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, -0x21, 0xF4, 0x10, 0x4A, 0x44, 0x6B, 0xC9, 0xF7, 0x1B, 0x68, 0x0B, 0xE8, -0x00, 0x30, 0x00, 0x30, 0x51, 0xF4, 0x80, 0x40, 0xB1, 0x67, 0x60, 0xC2, -0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, 0x51, 0xF4, 0x88, 0x40, 0x00, 0x1C, -0xF0, 0x5B, 0xB1, 0x67, 0x74, 0x17, 0xFF, 0x49, 0xD1, 0x17, 0x3A, 0x59, -0xE2, 0x61, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, -0x21, 0xF4, 0x10, 0x4A, 0x48, 0x6B, 0xE1, 0x17, 0xC0, 0xF2, 0x71, 0xA3, -0xFF, 0x6A, 0x4C, 0xEB, 0x63, 0xE9, 0xC9, 0x60, 0x23, 0x67, 0xC7, 0x17, -0x3A, 0x55, 0x5F, 0xF7, 0x00, 0x61, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, -0x40, 0x32, 0x40, 0x32, 0x21, 0xF4, 0x10, 0x4A, 0x48, 0x6B, 0x3F, 0x17, -0x80, 0xF1, 0x10, 0x5A, 0x1F, 0xF7, 0x08, 0x60, 0xC0, 0xF2, 0x72, 0xA4, -0x00, 0xF6, 0x60, 0x32, 0x00, 0xF6, 0x43, 0x32, 0x02, 0x4A, 0x0D, 0x52, -0x0C, 0x6A, 0xFF, 0xF6, 0x1B, 0x60, 0x42, 0x43, 0xF9, 0x16, 0xC0, 0xF2, -0x4F, 0xA6, 0x4C, 0xEB, 0x62, 0xED, 0x1F, 0xF7, 0x12, 0x60, 0x00, 0xF6, -0x40, 0x35, 0x0D, 0x17, 0x02, 0x49, 0x96, 0x17, 0xFB, 0x63, 0x06, 0xD0, -0x02, 0xF0, 0x00, 0x68, 0x00, 0x30, 0xAF, 0x40, 0xFF, 0xF0, 0x10, 0x6E, -0x15, 0x6C, 0x08, 0x62, 0x00, 0x1C, 0x83, 0x45, 0x07, 0xD1, 0x00, 0x1C, -0x5B, 0x1F, 0x64, 0x6C, 0x1A, 0x6C, 0x46, 0xF0, 0x16, 0x6E, 0x00, 0x1C, -0x83, 0x45, 0xAF, 0x40, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x10, 0xF0, -0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x04, 0xD2, 0x63, 0xF3, 0x40, 0x9A, -0x01, 0x6B, 0x4E, 0x32, 0x6C, 0xEA, 0x0A, 0x22, 0x10, 0xF0, 0x02, 0x6B, -0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x00, 0xF3, 0x47, 0xA3, -0x01, 0x72, 0x1C, 0x61, 0x04, 0x92, 0x63, 0xF3, 0x20, 0x9A, 0x01, 0x6A, -0x2E, 0x31, 0x4C, 0xE9, 0x09, 0x29, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, -0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x00, 0xF3, 0x47, 0xA3, 0x5A, 0x2A, -0x04, 0x93, 0x08, 0x97, 0x07, 0x91, 0x06, 0x90, 0x63, 0xF3, 0x00, 0x4B, -0x04, 0xD3, 0x04, 0x6A, 0x00, 0xF3, 0x44, 0xC3, 0x00, 0xEF, 0x05, 0x63, -0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x31, 0x24, 0xF2, 0x02, 0x68, -0x20, 0x31, 0x00, 0x30, 0x01, 0xF6, 0x88, 0x41, 0x24, 0xF2, 0x02, 0x6D, -0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x30, 0x01, 0xF6, 0x80, 0x41, 0x24, 0xF2, -0xA2, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x01, 0xF6, 0x84, 0x41, -0x24, 0xF2, 0xA2, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x11, 0xF6, -0x80, 0x41, 0x24, 0xF2, 0xA2, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, -0x11, 0xF6, 0x84, 0x41, 0x24, 0xF2, 0xA2, 0x40, 0x00, 0x1C, 0xDD, 0x5B, -0x00, 0x65, 0x11, 0xF6, 0x88, 0x41, 0x24, 0xF2, 0xA2, 0x40, 0x00, 0x1C, -0xDD, 0x5B, 0x00, 0x65, 0x11, 0xF6, 0x8C, 0x41, 0x24, 0xF2, 0xA2, 0x40, -0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, -0x40, 0x32, 0x01, 0x6B, 0x63, 0xF3, 0x00, 0x4A, 0x00, 0xF3, 0x67, 0xC2, -0x04, 0x93, 0x08, 0x97, 0x07, 0x91, 0x06, 0x90, 0x63, 0xF3, 0x00, 0x4B, -0x04, 0xD3, 0x04, 0x6A, 0x00, 0xF3, 0x44, 0xC3, 0x00, 0xEF, 0x05, 0x63, -0xC9, 0xF7, 0x1B, 0x68, 0x0B, 0xE8, 0x00, 0xF3, 0xB4, 0x9B, 0x00, 0x30, -0x00, 0x30, 0x01, 0xF6, 0x80, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, -0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, -0x00, 0xF3, 0xB4, 0x9A, 0x01, 0xF6, 0x84, 0x40, 0x00, 0x1C, 0xDD, 0x5B, -0x00, 0x65, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, -0x00, 0x4B, 0x00, 0xF3, 0xB8, 0x9B, 0x01, 0xF6, 0x88, 0x40, 0x00, 0x1C, -0xDD, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, -0x63, 0xF3, 0x00, 0x4A, 0x00, 0xF3, 0xB4, 0x9A, 0x11, 0xF6, 0x80, 0x40, -0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, -0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x00, 0xF3, 0xB4, 0x9B, 0x11, 0xF6, -0x84, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6A, -0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, 0x00, 0xF3, 0xB4, 0x9A, -0x11, 0xF6, 0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x10, 0xF0, -0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x00, 0xF3, -0xB4, 0x9B, 0x11, 0xF6, 0x8C, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, -0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, -0x00, 0xF3, 0x27, 0xC2, 0x04, 0x93, 0x08, 0x97, 0x07, 0x91, 0x06, 0x90, -0x63, 0xF3, 0x00, 0x4B, 0x04, 0xD3, 0x04, 0x6A, 0x00, 0xF3, 0x44, 0xC3, -0x00, 0xEF, 0x05, 0x63, 0xFB, 0x63, 0x06, 0xD0, 0x02, 0xF0, 0x00, 0x68, -0x00, 0x30, 0xAF, 0x40, 0xFF, 0xF0, 0x10, 0x6E, 0x15, 0x6C, 0x08, 0x62, -0x00, 0x1C, 0x83, 0x45, 0x07, 0xD1, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, -0x1A, 0x6C, 0x46, 0xF0, 0x16, 0x6E, 0x00, 0x1C, 0x83, 0x45, 0xAF, 0x40, -0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, -0x40, 0x32, 0x05, 0xD2, 0x63, 0xF3, 0x40, 0x9A, 0x01, 0x6B, 0x4E, 0x32, -0x6C, 0xEA, 0x0A, 0x22, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, -0x63, 0xF3, 0x00, 0x4B, 0x00, 0xF3, 0x47, 0xA3, 0x01, 0x72, 0x1D, 0x61, -0x05, 0x92, 0x63, 0xF3, 0x20, 0x9A, 0x01, 0x6A, 0x2E, 0x31, 0x4C, 0xE9, -0x09, 0x29, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, -0x00, 0x4B, 0x00, 0xF3, 0x47, 0xA3, 0x5C, 0x2A, 0x05, 0x92, 0x08, 0x97, -0x07, 0x91, 0x63, 0xF3, 0x00, 0x4A, 0x05, 0xD2, 0x05, 0x93, 0x06, 0x90, -0x01, 0x6A, 0x00, 0xF3, 0x44, 0xC3, 0x00, 0xEF, 0x05, 0x63, 0xC9, 0xF7, -0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x31, 0x24, 0xF2, 0x02, 0x68, 0x20, 0x31, -0x00, 0x30, 0x01, 0xF6, 0x88, 0x41, 0x24, 0xF2, 0x02, 0x6D, 0x00, 0x1C, -0xDD, 0x5B, 0x00, 0x30, 0x01, 0xF6, 0x80, 0x41, 0x24, 0xF2, 0xA2, 0x40, -0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x01, 0xF6, 0x84, 0x41, 0x24, 0xF2, -0xA2, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x11, 0xF6, 0x80, 0x41, -0x24, 0xF2, 0xA2, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x11, 0xF6, -0x84, 0x41, 0x24, 0xF2, 0xA2, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, -0x11, 0xF6, 0x88, 0x41, 0x24, 0xF2, 0xA2, 0x40, 0x00, 0x1C, 0xDD, 0x5B, -0x00, 0x65, 0x11, 0xF6, 0x8C, 0x41, 0x24, 0xF2, 0xA2, 0x40, 0x00, 0x1C, -0xDD, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, -0x01, 0x6B, 0x63, 0xF3, 0x00, 0x4A, 0x00, 0xF3, 0x67, 0xC2, 0x05, 0x92, -0x08, 0x97, 0x07, 0x91, 0x63, 0xF3, 0x00, 0x4A, 0x05, 0xD2, 0x05, 0x93, -0x06, 0x90, 0x01, 0x6A, 0x00, 0xF3, 0x44, 0xC3, 0x00, 0xEF, 0x05, 0x63, -0xC9, 0xF7, 0x1B, 0x68, 0x02, 0xF0, 0x10, 0x6A, 0x0B, 0xE8, 0x40, 0x32, -0x40, 0x32, 0x00, 0x30, 0xA2, 0x67, 0x00, 0x30, 0x01, 0xF6, 0x80, 0x40, -0x02, 0xF0, 0x10, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x04, 0xD2, 0x04, 0x95, -0x01, 0xF6, 0x84, 0x40, 0x02, 0xF0, 0x10, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, -0x00, 0x65, 0x01, 0xF6, 0x88, 0x40, 0x02, 0xF0, 0x10, 0x6D, 0x00, 0x1C, -0xDD, 0x5B, 0x00, 0x65, 0x04, 0x95, 0x11, 0xF6, 0x80, 0x40, 0x02, 0xF0, -0x10, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x04, 0x95, 0x11, 0xF6, -0x84, 0x40, 0x02, 0xF0, 0x10, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, -0x04, 0x95, 0x11, 0xF6, 0x88, 0x40, 0x02, 0xF0, 0x10, 0x4D, 0x00, 0x1C, -0xDD, 0x5B, 0x00, 0x65, 0x04, 0x95, 0x11, 0xF6, 0x8C, 0x40, 0x02, 0xF0, -0x10, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6B, -0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x00, 0xF3, 0x27, 0xC3, -0x05, 0x92, 0x08, 0x97, 0x07, 0x91, 0x63, 0xF3, 0x00, 0x4A, 0x05, 0xD2, -0x05, 0x93, 0x06, 0x90, 0x01, 0x6A, 0x00, 0xF3, 0x44, 0xC3, 0x00, 0xEF, -0x05, 0x63, 0x00, 0x00, 0xFC, 0x63, 0x05, 0xD1, 0x10, 0xF0, 0x02, 0x69, -0x00, 0xF4, 0x20, 0x31, 0x06, 0x62, 0x04, 0xD0, 0x63, 0xF3, 0x00, 0x49, -0x00, 0xF3, 0xCC, 0x99, 0x02, 0xF0, 0x00, 0x68, 0x00, 0x30, 0xAF, 0x40, -0x00, 0x1C, 0x83, 0x45, 0x15, 0x6C, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, -0x00, 0xF3, 0xD0, 0x99, 0x1A, 0x6C, 0x00, 0x1C, 0x83, 0x45, 0xAF, 0x40, -0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x00, 0xF3, 0x44, 0xA1, 0x0E, 0x2A, -0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x01, 0xF6, -0x00, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0x6C, 0x99, -0x6E, 0xEA, 0x36, 0x22, 0xC9, 0xF7, 0x1B, 0x68, 0x0B, 0xE8, 0xE0, 0xF2, -0xA8, 0x99, 0x00, 0x30, 0x00, 0x30, 0x01, 0xF6, 0x88, 0x40, 0x00, 0x1C, -0xDD, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0xAC, 0x99, 0x01, 0xF6, 0x80, 0x40, -0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0xB0, 0x99, 0x01, 0xF6, -0x84, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0xB4, 0x99, -0x11, 0xF6, 0x80, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xE0, 0xF2, -0xB8, 0x99, 0x11, 0xF6, 0x84, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, -0xE0, 0xF2, 0xBC, 0x99, 0x11, 0xF6, 0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B, -0x00, 0x65, 0x00, 0xF3, 0xA0, 0x99, 0x11, 0xF6, 0x8C, 0x40, 0x00, 0x1C, -0xDD, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, -0x06, 0x97, 0x05, 0x91, 0x04, 0x90, 0x63, 0xF3, 0x00, 0x4A, 0x00, 0x6B, -0x00, 0xF3, 0x64, 0xC2, 0x02, 0x6B, 0x00, 0xF3, 0x67, 0xC2, 0x00, 0xEF, -0x04, 0x63, 0x00, 0x00, 0xFC, 0x63, 0x05, 0xD1, 0x10, 0xF0, 0x02, 0x69, -0x00, 0xF4, 0x20, 0x31, 0x06, 0x62, 0x04, 0xD0, 0x63, 0xF3, 0x00, 0x49, -0x00, 0xF3, 0xCC, 0x99, 0x02, 0xF0, 0x00, 0x68, 0x00, 0x30, 0xAF, 0x40, -0x00, 0x1C, 0x83, 0x45, 0x15, 0x6C, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, -0x00, 0xF3, 0xD0, 0x99, 0x1A, 0x6C, 0x00, 0x1C, 0x83, 0x45, 0xAF, 0x40, -0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x00, 0xF3, 0x44, 0xA1, 0x03, 0x72, -0x5B, 0x60, 0xE0, 0xF2, 0xAC, 0x99, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, -0x40, 0x30, 0x00, 0x30, 0x01, 0xF6, 0x80, 0x40, 0x00, 0x1C, 0xDD, 0x5B, -0x00, 0x65, 0xE0, 0xF2, 0xB0, 0x99, 0x01, 0xF6, 0x84, 0x40, 0x00, 0x1C, -0xDD, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0xB4, 0x99, 0x11, 0xF6, 0x80, 0x40, -0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0xB8, 0x99, 0x11, 0xF6, -0x84, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0xBC, 0x99, -0x11, 0xF6, 0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x00, 0xF3, -0xA0, 0x99, 0x11, 0xF6, 0x8C, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, -0x00, 0xF3, 0x48, 0x99, 0xE0, 0xF2, 0x68, 0x99, 0x55, 0xE3, 0x1F, 0xF7, -0x00, 0x6A, 0xAC, 0xEA, 0x07, 0xF7, 0x01, 0x5A, 0x16, 0x60, 0x01, 0xF6, -0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6A, -0x00, 0xF4, 0x40, 0x32, 0x06, 0x97, 0x05, 0x91, 0x04, 0x90, 0x63, 0xF3, -0x00, 0x4A, 0x03, 0x6B, 0x00, 0xF3, 0x64, 0xC2, 0x02, 0x6B, 0x00, 0xF3, -0x67, 0xC2, 0x00, 0xEF, 0x04, 0x63, 0xFF, 0x6A, 0x01, 0x4A, 0x4B, 0xEA, -0x40, 0x32, 0xE0, 0xF0, 0x1F, 0x4A, 0x4C, 0xED, 0x07, 0xF7, 0x00, 0x6A, -0x4D, 0xED, 0xDF, 0x17, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, -0x80, 0x34, 0x01, 0xF6, 0x00, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, -0xE0, 0xF2, 0xAC, 0x99, 0xAA, 0xEA, 0x99, 0x61, 0x10, 0xF0, 0x02, 0x6A, -0x00, 0xF4, 0x40, 0x32, 0x06, 0x97, 0x05, 0x91, 0x04, 0x90, 0x63, 0xF3, -0x00, 0x4A, 0x03, 0x6B, 0x00, 0xF3, 0x64, 0xC2, 0x02, 0x6B, 0x00, 0xF3, -0x67, 0xC2, 0x00, 0xEF, 0x04, 0x63, 0x00, 0x00, 0x10, 0xF0, 0x02, 0x6B, -0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x40, 0x9B, 0x10, 0x6B, 0xFB, 0x63, -0x6D, 0xEA, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, -0x40, 0xDB, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x07, 0xD1, 0x40, 0x31, -0x20, 0x31, 0x51, 0xF4, 0x80, 0x41, 0x08, 0x62, 0x00, 0x1C, 0x00, 0x5C, -0x06, 0xD0, 0x00, 0xF6, 0x40, 0x32, 0x00, 0xF6, 0x43, 0x32, 0x51, 0xF4, -0x80, 0x41, 0x1A, 0x6D, 0x00, 0x1C, 0xF0, 0x5B, 0x04, 0xD2, 0xF1, 0xF0, -0x88, 0x41, 0x00, 0x1C, 0x00, 0x5C, 0x00, 0x65, 0x04, 0x93, 0x00, 0xF6, -0x40, 0x32, 0x00, 0xF6, 0x43, 0x32, 0x49, 0xE3, 0x08, 0x42, 0x9A, 0x48, -0xBF, 0xF7, 0x1B, 0x50, 0x09, 0x61, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, -0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x43, 0xAB, 0x01, 0x4A, 0x43, 0xCB, -0x04, 0x95, 0xFF, 0x6A, 0x51, 0xF4, 0x80, 0x41, 0x00, 0x1C, 0xF0, 0x5B, -0x4C, 0xED, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, -0x40, 0x9B, 0x11, 0x6B, 0x6B, 0xEB, 0x6C, 0xEA, 0x10, 0xF0, 0x02, 0x6B, -0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x40, 0xDB, 0x0B, 0xED, 0xFF, 0x6A, -0x91, 0xF4, 0x82, 0x41, 0x00, 0x1C, 0xF0, 0x5B, 0x4C, 0xED, 0x08, 0x97, -0x07, 0x91, 0x06, 0x90, 0x00, 0x6A, 0x00, 0xEF, 0x05, 0x63, 0x00, 0x00, -0xF9, 0x63, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, -0x00, 0x4B, 0x0C, 0x62, 0x0B, 0xD1, 0x0A, 0xD0, 0x66, 0xF7, 0x4C, 0x9B, -0x52, 0x32, 0x05, 0xD2, 0x05, 0x94, 0x7F, 0x6A, 0x4C, 0xEC, 0x05, 0xD4, -0x00, 0xF3, 0x44, 0xA3, 0x06, 0xD2, 0x40, 0x9B, 0x84, 0x6B, 0x6C, 0xEA, -0x80, 0x72, 0x2A, 0x61, 0x06, 0x93, 0x01, 0x73, 0x02, 0x60, 0x04, 0x73, -0x1B, 0x61, 0x02, 0xF0, 0x00, 0x68, 0x00, 0xF2, 0x00, 0x6E, 0x00, 0x30, -0xC0, 0x36, 0xAF, 0x40, 0xF3, 0xF0, 0x14, 0x4E, 0x00, 0x1C, 0x83, 0x45, -0x15, 0x6C, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0xFF, 0x6E, 0x01, 0x4E, -0xC0, 0x36, 0x1A, 0x6C, 0x46, 0xF0, 0x16, 0x4E, 0x00, 0x1C, 0x83, 0x45, -0xAF, 0x40, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x10, 0xF0, 0x02, 0x6B, -0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x01, 0x6A, 0x4B, 0xEA, -0x00, 0xF3, 0x44, 0xC3, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x30, -0x00, 0x30, 0x40, 0xF0, 0x6C, 0xA0, 0x03, 0x6A, 0x6C, 0xEA, 0x0A, 0x22, -0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x63, 0xF3, 0x40, 0x9C, -0x01, 0x6B, 0x5E, 0x32, 0x6C, 0xEA, 0x7C, 0x22, 0x10, 0xF0, 0x02, 0x6C, -0x00, 0xF4, 0x80, 0x34, 0x63, 0xF3, 0x00, 0x4C, 0x00, 0xF3, 0x44, 0x9C, -0xFF, 0xF7, 0x1F, 0x6B, 0x42, 0x32, 0x6C, 0xEA, 0x16, 0x2A, 0xC9, 0xF7, -0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF1, 0x04, 0x4A, -0x40, 0x9A, 0x0D, 0x72, 0x58, 0x61, 0x46, 0x6A, 0x00, 0xF3, 0x5C, 0xC4, -0x41, 0x6A, 0x00, 0xF3, 0x5D, 0xC4, 0x40, 0x6A, 0x00, 0xF3, 0x5E, 0xC4, -0x3B, 0x6A, 0x00, 0xF3, 0x5F, 0xC4, 0x10, 0xF0, 0x02, 0x69, 0x00, 0xF4, -0x20, 0x31, 0x63, 0xF3, 0x00, 0x49, 0xE4, 0xF4, 0xB8, 0x99, 0xC9, 0xF7, -0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x30, 0xFF, 0x6E, 0xB2, 0x35, 0x00, 0x30, -0xCC, 0xED, 0x61, 0xF4, 0x80, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x08, 0xD6, -0x60, 0x99, 0x84, 0x6A, 0x08, 0x96, 0x6C, 0xEA, 0x84, 0x72, 0x2B, 0x61, -0xE4, 0xF4, 0x58, 0x99, 0xFF, 0xF7, 0x1F, 0x72, 0x26, 0x60, 0x76, 0x32, -0x01, 0x6B, 0x6C, 0xEA, 0x22, 0x22, 0x40, 0xF0, 0x4C, 0xA0, 0x03, 0x6B, -0xCC, 0xEA, 0x6C, 0xEA, 0x1C, 0x22, 0x06, 0x92, 0x6A, 0xEA, 0xA0, 0xF0, -0x13, 0x60, 0x04, 0x52, 0xA0, 0xF0, 0x1B, 0x60, 0xC0, 0xF0, 0x18, 0x22, -0x01, 0x72, 0x11, 0x61, 0x00, 0xF3, 0x5C, 0xA1, 0x05, 0x93, 0xCC, 0xEA, -0x43, 0xEB, 0xC0, 0xF0, 0x0B, 0x60, 0x00, 0xF3, 0x5F, 0xA1, 0x05, 0x94, -0xCC, 0xEA, 0x83, 0xEA, 0xA0, 0xF0, 0x1A, 0x61, 0x00, 0x18, 0x96, 0x29, -0x00, 0x65, 0x0C, 0x97, 0x0B, 0x91, 0x0A, 0x90, 0x00, 0x6A, 0x00, 0xEF, -0x07, 0x63, 0x4A, 0x6A, 0x00, 0xF3, 0x5C, 0xC4, 0x45, 0x6A, 0x00, 0xF3, -0x5D, 0xC4, 0x46, 0x6A, 0x00, 0xF3, 0x5E, 0xC4, 0x40, 0x6A, 0x00, 0xF3, -0x5F, 0xC4, 0xA7, 0x17, 0x01, 0xF6, 0x80, 0x40, 0x00, 0x1C, 0xFA, 0x5B, -0x00, 0x65, 0x0E, 0x2A, 0x11, 0xF6, 0x80, 0x40, 0x00, 0x1C, 0xFA, 0x5B, -0x00, 0x65, 0x27, 0xF7, 0x1F, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x27, 0xF7, -0x1F, 0x4B, 0x6E, 0xEA, 0x7F, 0xF7, 0x10, 0x22, 0x9D, 0x67, 0x00, 0x1C, -0x8A, 0x40, 0x10, 0x4C, 0x10, 0xF0, 0x02, 0x69, 0x00, 0xF4, 0x20, 0x31, -0x01, 0xF6, 0x88, 0x40, 0x63, 0xF3, 0x00, 0x49, 0x00, 0x1C, 0xFA, 0x5B, -0x00, 0x65, 0xE0, 0xF2, 0x48, 0xD9, 0x01, 0xF6, 0x80, 0x40, 0x00, 0x1C, -0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0x4C, 0xD9, 0x01, 0xF6, 0x84, 0x40, -0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0x50, 0xD9, 0x11, 0xF6, -0x80, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF2, 0x54, 0xD9, -0x11, 0xF6, 0x84, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF2, -0x58, 0xD9, 0x11, 0xF6, 0x88, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, -0xE0, 0xF2, 0x5C, 0xD9, 0x11, 0xF6, 0x8C, 0x40, 0x00, 0x1C, 0xFA, 0x5B, -0x00, 0x65, 0x00, 0xF3, 0x40, 0xD9, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, -0x40, 0x32, 0xCB, 0xF4, 0x46, 0xA2, 0xFF, 0x6B, 0x6C, 0xEA, 0x22, 0x72, -0x02, 0x60, 0x92, 0x72, 0x1A, 0x61, 0x01, 0xF0, 0x8D, 0x40, 0x00, 0x1C, -0x00, 0x5C, 0x00, 0x65, 0x0F, 0x6B, 0x4C, 0xEB, 0x0F, 0x6A, 0x6E, 0xEA, -0xFF, 0x6C, 0x8C, 0xEA, 0x08, 0x5B, 0xA1, 0x42, 0x0C, 0x61, 0xA0, 0x34, -0x80, 0x33, 0x00, 0xF6, 0xA0, 0x32, 0x6D, 0xEA, 0x8D, 0xEA, 0xAD, 0xEA, -0xAD, 0xEC, 0x00, 0xF3, 0x54, 0xD9, 0x00, 0xF3, 0x98, 0xD9, 0x9D, 0x67, -0x00, 0x1C, 0x90, 0x40, 0x10, 0x4C, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, -0x60, 0x33, 0x63, 0xF3, 0x40, 0x9B, 0x80, 0x6B, 0x10, 0xF0, 0x02, 0x6C, -0x00, 0xF4, 0x80, 0x34, 0x6D, 0xEA, 0x63, 0xF3, 0x40, 0xDC, 0xFC, 0x16, -0x20, 0xF3, 0x40, 0xA1, 0x05, 0x93, 0xCC, 0xEA, 0x43, 0xEB, 0x5F, 0xF7, -0x1B, 0x60, 0x00, 0x18, 0xD2, 0x29, 0x00, 0x65, 0x5A, 0x17, 0x06, 0x93, -0x04, 0x73, 0x12, 0x60, 0xFF, 0x73, 0x5F, 0xF7, 0x14, 0x61, 0x00, 0xF3, -0x5E, 0xA1, 0x05, 0x94, 0xCC, 0xEA, 0x43, 0xEC, 0x24, 0x61, 0x00, 0xF3, -0x5C, 0xA1, 0xCC, 0xEA, 0x43, 0xEC, 0x0A, 0x60, 0x00, 0x18, 0x1E, 0x29, -0x00, 0x65, 0x45, 0x17, 0x00, 0xF3, 0x5D, 0xA1, 0x05, 0x94, 0xCC, 0xEA, -0x83, 0xEA, 0xF6, 0x60, 0x00, 0x18, 0x9B, 0x28, 0x00, 0x65, 0x3B, 0x17, -0x00, 0xF3, 0x5E, 0xA1, 0x05, 0x93, 0xCC, 0xEA, 0x43, 0xEB, 0xEC, 0x60, -0x20, 0xF3, 0x41, 0xA1, 0x05, 0x94, 0xCC, 0xEA, 0x83, 0xEA, 0x3F, 0xF7, -0x0B, 0x61, 0x00, 0x18, 0xD2, 0x29, 0x00, 0x65, 0x2A, 0x17, 0x20, 0xF3, -0x41, 0xA1, 0x05, 0x93, 0xCC, 0xEA, 0x63, 0xEA, 0xF6, 0x60, 0x20, 0x17, -0xFB, 0x63, 0x10, 0xF0, 0x02, 0x6E, 0x00, 0xF4, 0xC0, 0x36, 0x07, 0xD1, -0x26, 0x67, 0x06, 0xD0, 0x08, 0x62, 0x63, 0xF3, 0x00, 0x49, 0x66, 0xF7, -0x8C, 0x99, 0x7F, 0x6A, 0x92, 0x30, 0x4C, 0xE8, 0xE0, 0xF2, 0x46, 0xA1, -0x0F, 0x2A, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x35, 0xA0, 0x35, -0x40, 0xF0, 0x4C, 0xA5, 0xFF, 0x6B, 0x6C, 0xEA, 0x03, 0x6B, 0x6C, 0xEA, -0x03, 0x22, 0xFF, 0xF7, 0x1F, 0x74, 0x06, 0x61, 0x08, 0x97, 0x07, 0x91, -0x06, 0x90, 0x00, 0x6A, 0x00, 0xEF, 0x05, 0x63, 0x01, 0xF0, 0x80, 0x45, -0x04, 0xD5, 0x00, 0x1C, 0x00, 0x5C, 0x05, 0xD6, 0x01, 0x6B, 0x6C, 0xEA, -0x04, 0x95, 0x05, 0x96, 0x2C, 0x22, 0x4B, 0x58, 0x06, 0x61, 0xC0, 0xF2, -0x53, 0xA1, 0xFF, 0x6C, 0x8C, 0xEA, 0x6A, 0xEA, 0x74, 0x61, 0x48, 0x40, -0xE0, 0x4A, 0xFF, 0x6B, 0x6C, 0xEA, 0x1E, 0x5A, 0x07, 0x60, 0x86, 0x67, -0x63, 0xF3, 0x00, 0x4C, 0xC0, 0xF2, 0x53, 0xA4, 0x6C, 0xEA, 0x43, 0x2A, -0x23, 0x58, 0xD8, 0x60, 0x66, 0x67, 0x63, 0xF3, 0x00, 0x4B, 0xC0, 0xF2, -0x53, 0xA3, 0x02, 0x72, 0xD1, 0x60, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, -0x80, 0x34, 0x02, 0x6A, 0x80, 0x34, 0xC0, 0xF2, 0x53, 0xC3, 0x81, 0xF4, -0x07, 0x4C, 0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x6D, 0xC3, 0x17, 0x4B, 0x58, -0x06, 0x61, 0xC0, 0xF2, 0x53, 0xA1, 0xFF, 0x6C, 0x8C, 0xEA, 0x01, 0x72, -0x40, 0x61, 0x48, 0x40, 0xE0, 0x4A, 0xFF, 0x6B, 0x6C, 0xEA, 0x1E, 0x5A, -0x07, 0x60, 0x86, 0x67, 0x63, 0xF3, 0x00, 0x4C, 0xC0, 0xF2, 0x53, 0xA4, -0x6C, 0xEA, 0x25, 0x2A, 0x23, 0x58, 0xAC, 0x60, 0x66, 0x67, 0x63, 0xF3, -0x00, 0x4B, 0xC0, 0xF2, 0x53, 0xA3, 0x02, 0x72, 0xA5, 0x60, 0xC9, 0xF7, -0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x02, 0x6A, 0x80, 0x34, 0xC0, 0xF2, -0x53, 0xC3, 0x21, 0xF4, 0x10, 0x4C, 0x00, 0x1C, 0xF0, 0x5B, 0x42, 0x6D, -0x97, 0x17, 0x00, 0x6A, 0xC0, 0xF2, 0x53, 0xC4, 0xC9, 0xF7, 0x1B, 0x6C, -0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x81, 0xF4, 0x07, 0x4C, 0x00, 0x1C, -0xF0, 0x5B, 0x20, 0x6D, 0x89, 0x17, 0x00, 0x6A, 0xC0, 0xF2, 0x53, 0xC4, -0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x21, 0xF4, -0x10, 0x4C, 0x00, 0x1C, 0xF0, 0x5B, 0x44, 0x6D, 0x7B, 0x17, 0x31, 0xF4, -0x80, 0x45, 0xC0, 0xF2, 0x73, 0xC1, 0x00, 0x1C, 0xF0, 0x5B, 0x43, 0x6D, -0x73, 0x17, 0x81, 0xF4, 0x87, 0x45, 0xC0, 0xF2, 0x73, 0xC1, 0x00, 0x1C, -0xF0, 0x5B, 0x10, 0x6D, 0x6B, 0x17, 0x00, 0x65, 0xE8, 0xFF, 0xBD, 0x27, -0x10, 0x00, 0xBF, 0xAF, 0x24, 0x63, 0x00, 0x0C, 0x21, 0x38, 0x00, 0x00, -0x10, 0x00, 0xBF, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF, -0x01, 0x80, 0x02, 0x3C, 0x25, 0xB0, 0x10, 0x3C, 0x14, 0xAE, 0x42, 0x24, -0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x03, 0x11, 0x36, 0x10, 0x00, 0xA4, 0x27, -0x00, 0x00, 0x22, 0xAE, 0x20, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C, -0x30, 0x03, 0x10, 0x36, 0x20, 0x80, 0x02, 0x3C, 0x25, 0xB0, 0x05, 0x3C, -0x00, 0x00, 0x02, 0xAE, 0x01, 0x80, 0x02, 0x3C, 0x15, 0xAE, 0x44, 0x24, -0x33, 0x03, 0xA3, 0x34, 0x00, 0x00, 0x24, 0xAE, 0x00, 0x00, 0x62, 0x90, -0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x30, 0xFB, 0xFF, 0x40, 0x10, -0x30, 0x03, 0xA2, 0x34, 0x00, 0x00, 0x46, 0x8C, 0x0F, 0x00, 0x03, 0x3C, -0xFF, 0xFF, 0x63, 0x34, 0x24, 0x30, 0xC3, 0x00, 0x40, 0x11, 0x06, 0x00, -0x23, 0x10, 0x46, 0x00, 0x80, 0x10, 0x02, 0x00, 0x21, 0x10, 0x46, 0x00, -0xAF, 0x0F, 0x05, 0x3C, 0xC0, 0x10, 0x02, 0x00, 0x00, 0xA0, 0xA5, 0x34, -0x1B, 0x00, 0xA2, 0x00, 0x02, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x0D, 0x00, 0x07, 0x00, 0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x63, 0x24, -0xC2, 0x30, 0x06, 0x00, 0x10, 0x00, 0xA4, 0x27, 0x54, 0x41, 0x66, 0xAC, -0x12, 0x28, 0x00, 0x00, 0x90, 0x40, 0x00, 0x0C, 0x58, 0x41, 0x65, 0xAC, -0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, 0xC0, 0xFF, 0xBD, 0x27, -0x2C, 0x00, 0xB5, 0xAF, 0x20, 0x00, 0xB2, 0xAF, 0x21, 0xA8, 0x80, 0x00, -0x02, 0x80, 0x12, 0x3C, 0x10, 0x00, 0xA4, 0x27, 0x38, 0x00, 0xBE, 0xAF, -0x30, 0x00, 0xB6, 0xAF, 0x3C, 0x00, 0xBF, 0xAF, 0x34, 0x00, 0xB7, 0xAF, -0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, -0x18, 0x00, 0xB0, 0xAF, 0x8A, 0x40, 0x00, 0x0C, 0x44, 0x00, 0xA5, 0xAF, -0xEC, 0x5D, 0x42, 0x92, 0x21, 0xF0, 0x00, 0x00, 0xC5, 0x00, 0x40, 0x10, -0x21, 0xB0, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x43, 0x24, -0xB0, 0x1B, 0x62, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x30, -0xBE, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x3E, 0x62, 0x8C, -0x00, 0x00, 0x00, 0x00, 0xBA, 0x00, 0x40, 0x14, 0x02, 0x80, 0x17, 0x3C, -0x0E, 0x5E, 0xE2, 0x92, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x10, -0x02, 0x80, 0x02, 0x3C, 0x0E, 0x5E, 0xE2, 0x92, 0x00, 0x00, 0x00, 0x00, -0xFF, 0xFF, 0x42, 0x24, 0x0E, 0x5E, 0xE2, 0xA2, 0x02, 0x80, 0x02, 0x3C, -0x02, 0x80, 0x03, 0x3C, 0xF2, 0x5D, 0x40, 0xA0, 0x14, 0x5E, 0x60, 0xAC, -0x02, 0x80, 0x03, 0x3C, 0x07, 0x5E, 0x62, 0x90, 0xFD, 0xFF, 0x03, 0x24, -0x42, 0xB0, 0x13, 0x3C, 0x24, 0x10, 0x43, 0x00, 0x02, 0x80, 0x03, 0x3C, -0x07, 0x5E, 0x62, 0xA0, 0x00, 0x00, 0x63, 0x92, 0xEF, 0xFF, 0x02, 0x24, -0x03, 0x00, 0x64, 0x36, 0x24, 0x18, 0x62, 0x00, 0x40, 0x00, 0x02, 0x24, -0x00, 0x00, 0x63, 0xA2, 0x00, 0x00, 0x82, 0xA0, 0x02, 0x80, 0x04, 0x3C, -0xF4, 0x5D, 0x82, 0x94, 0x20, 0x00, 0xA3, 0x96, 0xFF, 0xFF, 0x42, 0x30, -0x0A, 0x00, 0x43, 0x10, 0x02, 0x80, 0x14, 0x3C, 0x25, 0xB0, 0x02, 0x3C, -0x94, 0x00, 0x42, 0x34, 0xF4, 0x5D, 0x83, 0xA4, 0x00, 0x00, 0x43, 0xA4, -0xF4, 0x5D, 0x83, 0x94, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x63, 0x30, -0x80, 0x1A, 0x03, 0x00, 0xF8, 0x5D, 0x83, 0xAE, 0x25, 0xB0, 0x04, 0x3C, -0x84, 0x00, 0x82, 0x34, 0x00, 0x00, 0x50, 0x8C, 0x80, 0x00, 0x84, 0x34, -0x00, 0x00, 0x82, 0x8C, 0x21, 0x18, 0x00, 0x00, 0xF8, 0x5D, 0x86, 0x8E, -0x00, 0x88, 0x10, 0x00, 0x21, 0x80, 0x00, 0x00, 0x25, 0x80, 0x02, 0x02, -0x25, 0x88, 0x23, 0x02, 0x21, 0x20, 0x00, 0x02, 0x7D, 0x2B, 0x00, 0x0C, -0x21, 0x28, 0x20, 0x02, 0xF8, 0x5D, 0x88, 0x8E, 0x02, 0x80, 0x0A, 0x3C, -0xFC, 0x5D, 0x43, 0x95, 0x23, 0x48, 0x02, 0x01, 0x21, 0x20, 0x30, 0x01, -0x21, 0x28, 0x00, 0x00, 0x2B, 0x10, 0x90, 0x00, 0xFF, 0xFF, 0x63, 0x30, -0x21, 0x28, 0xB1, 0x00, 0x80, 0x1A, 0x03, 0x00, 0x21, 0x28, 0xA2, 0x00, -0x21, 0x38, 0x00, 0x00, 0x2B, 0x40, 0x83, 0x00, 0x23, 0x28, 0xA7, 0x00, -0x23, 0x20, 0x83, 0x00, 0x23, 0x28, 0xA8, 0x00, 0x02, 0x80, 0x03, 0x3C, -0x18, 0x5E, 0x64, 0xAC, 0x1C, 0x5E, 0x65, 0xAC, 0xFC, 0x5D, 0x42, 0x95, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x42, 0x30, 0x80, 0x12, 0x02, 0x00, -0x2B, 0x10, 0x49, 0x00, 0x97, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, -0xFC, 0x5D, 0x42, 0x95, 0x00, 0x00, 0x64, 0x92, 0xFB, 0xFF, 0x03, 0x24, -0xFF, 0xFF, 0x42, 0x30, 0x80, 0x12, 0x02, 0x00, 0x24, 0x20, 0x83, 0x00, -0x23, 0x48, 0x22, 0x01, 0x00, 0x00, 0x64, 0xA2, 0x01, 0x00, 0x06, 0x24, -0x04, 0x00, 0x20, 0x11, 0x01, 0x00, 0x04, 0x24, 0x80, 0x10, 0x09, 0x00, -0x21, 0x10, 0x49, 0x00, 0x80, 0x30, 0x02, 0x00, 0xB9, 0x20, 0x00, 0x0C, -0x21, 0x28, 0x00, 0x00, 0x42, 0xB0, 0x02, 0x3C, 0x22, 0x00, 0x03, 0x24, -0x03, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0xA0, 0x44, 0x00, 0xA2, 0x8F, -0x05, 0x00, 0x05, 0x24, 0x24, 0x00, 0xA4, 0x26, 0x00, 0x00, 0x47, 0x8C, -0x14, 0x00, 0xA6, 0x27, 0xFF, 0x3F, 0xE7, 0x30, 0xAB, 0x1A, 0x00, 0x0C, -0xDC, 0xFF, 0xE7, 0x24, 0x2C, 0x00, 0x40, 0x10, 0x21, 0x28, 0x40, 0x00, -0xEC, 0x5D, 0x42, 0x92, 0x02, 0x00, 0x03, 0x24, 0xFF, 0x00, 0x42, 0x30, -0x83, 0x00, 0x43, 0x10, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x00, 0xA2, 0x90, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x04, 0x00, 0xA3, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x62, 0x30, -0x04, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C, 0x01, 0x00, 0x16, 0x24, -0x0B, 0x5E, 0x56, 0xA0, 0x04, 0x00, 0xA3, 0x90, 0x14, 0x00, 0xA7, 0x8F, -0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xE2, 0x28, 0x16, 0x00, 0x40, 0x14, -0xFE, 0x00, 0x66, 0x30, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x43, 0x24, -0x4C, 0x3A, 0x64, 0x94, 0xC0, 0x10, 0x06, 0x00, 0x2A, 0x10, 0x82, 0x00, -0x10, 0x00, 0x40, 0x14, 0x02, 0x80, 0x03, 0x3C, 0x21, 0x10, 0xC7, 0x00, -0xFD, 0xFF, 0x42, 0x24, 0xC0, 0x10, 0x02, 0x00, 0x2A, 0x10, 0x44, 0x00, -0x0A, 0x00, 0x40, 0x14, 0xC2, 0x10, 0x04, 0x00, 0x23, 0x30, 0x46, 0x00, -0x21, 0x18, 0xA6, 0x00, 0x05, 0x00, 0x62, 0x90, 0x07, 0x00, 0x84, 0x30, -0x01, 0x00, 0x03, 0x24, 0x07, 0x10, 0x82, 0x00, 0x01, 0x00, 0x42, 0x30, -0x0B, 0xF0, 0x62, 0x00, 0x02, 0x80, 0x03, 0x3C, 0x07, 0x5E, 0x62, 0x90, -0xEF, 0xFF, 0x03, 0x24, 0x21, 0x20, 0xC0, 0x02, 0x24, 0x10, 0x43, 0x00, -0x02, 0x80, 0x03, 0x3C, 0x07, 0x5E, 0x62, 0xA0, 0xEC, 0x5D, 0x43, 0x92, -0x02, 0x80, 0x02, 0x3C, 0xE0, 0xE4, 0x42, 0x24, 0xFF, 0x00, 0x63, 0x30, -0x80, 0x18, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, 0x00, 0x00, 0x66, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x09, 0xF8, 0xC0, 0x00, 0x21, 0x28, 0xC0, 0x03, -0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x3C, 0x00, 0xBF, 0x8F, -0x38, 0x00, 0xBE, 0x8F, 0x34, 0x00, 0xB7, 0x8F, 0x30, 0x00, 0xB6, 0x8F, -0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, -0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x40, 0x00, 0xBD, 0x27, 0xEC, 0x5D, 0x42, 0x92, -0x00, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x40, 0x14, 0x02, 0x80, 0x03, 0x3C, -0x60, 0x1B, 0x70, 0x24, 0xB0, 0x1B, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x42, 0x30, 0xE9, 0xFF, 0x40, 0x10, 0x05, 0x00, 0x05, 0x24, -0x44, 0x00, 0xA2, 0x8F, 0x24, 0x00, 0xA4, 0x26, 0x00, 0x00, 0x47, 0x8C, -0x14, 0x00, 0xA6, 0x27, 0xFF, 0x3F, 0xE7, 0x30, 0xAB, 0x1A, 0x00, 0x0C, -0xDC, 0xFF, 0xE7, 0x24, 0xE0, 0xFF, 0x40, 0x10, 0x21, 0x28, 0x40, 0x00, -0x14, 0x00, 0xA7, 0x8F, 0x04, 0x00, 0x42, 0x90, 0x04, 0x00, 0xE3, 0x28, -0xDB, 0xFF, 0x60, 0x14, 0xFE, 0x00, 0x46, 0x30, 0x4C, 0x3A, 0x04, 0x96, -0xC0, 0x10, 0x06, 0x00, 0x2A, 0x10, 0x82, 0x00, 0xD6, 0xFF, 0x40, 0x14, -0x21, 0x10, 0xC7, 0x00, 0xFD, 0xFF, 0x42, 0x24, 0xC0, 0x10, 0x02, 0x00, -0x2A, 0x10, 0x44, 0x00, 0xD1, 0xFF, 0x40, 0x14, 0xC2, 0x10, 0x04, 0x00, -0x23, 0x30, 0x46, 0x00, 0x21, 0x18, 0xA6, 0x00, 0x05, 0x00, 0x62, 0x90, -0x07, 0x00, 0x84, 0x30, 0x07, 0x10, 0x82, 0x00, 0x01, 0x00, 0x42, 0x30, -0xC9, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x51, 0x00, 0x0C, -0x21, 0x20, 0x00, 0x00, 0x83, 0x2C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x0E, 0x5E, 0xE2, 0x92, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x0E, 0x5E, 0xE2, 0x92, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x42, 0x24, 0x0E, 0x5E, 0xE2, 0xA2, 0x00, 0x00, 0x62, 0x92, -0xFB, 0xFF, 0x03, 0x24, 0x01, 0x00, 0x06, 0x24, 0x24, 0x10, 0x43, 0x00, -0x00, 0x00, 0x62, 0xA2, 0x32, 0x2C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x03, 0x00, 0xA2, 0x90, 0x02, 0x80, 0x07, 0x3C, 0x09, 0x5E, 0xE2, 0xA0, -0x02, 0x00, 0xA3, 0x90, 0x21, 0x30, 0x80, 0x00, 0x0A, 0x5E, 0x83, 0xA0, -0x0A, 0x5E, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x09, 0x5E, 0xE2, 0x90, 0x00, 0x00, 0x00, 0x00, -0x0A, 0x5E, 0xC2, 0xA0, 0x4C, 0x2C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x0A, 0x5E, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x5E, 0xC2, 0xA0, -0x4C, 0x2C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x24, -0x02, 0x80, 0x02, 0x3C, 0x0D, 0x5E, 0x43, 0xA0, 0xD0, 0x07, 0x04, 0x24, -0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0xDC, 0x5D, 0x44, 0xAC, -0x0C, 0x5E, 0x60, 0xA0, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0xD8, 0xFF, 0xBD, 0x27, 0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, -0x20, 0x00, 0xBF, 0xAF, 0x04, 0x00, 0x82, 0x8C, 0x02, 0x00, 0x03, 0x24, -0x21, 0x80, 0x80, 0x00, 0x02, 0x17, 0x02, 0x00, 0x03, 0x00, 0x42, 0x30, -0x06, 0x00, 0x43, 0x10, 0x02, 0x80, 0x11, 0x3C, 0x20, 0x00, 0xBF, 0x8F, -0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x28, 0x00, 0xBD, 0x27, 0xEC, 0x5D, 0x22, 0x92, 0x00, 0x00, 0x00, 0x00, -0xF8, 0xFF, 0x40, 0x10, 0x10, 0x00, 0xA4, 0x27, 0x8A, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0xEC, 0x5D, 0x23, 0x92, 0x02, 0x80, 0x02, 0x3C, -0xB4, 0xE4, 0x42, 0x24, 0xFF, 0x00, 0x63, 0x30, 0x80, 0x18, 0x03, 0x00, -0x21, 0x18, 0x62, 0x00, 0x00, 0x00, 0x66, 0x8C, 0x00, 0x00, 0x04, 0x8E, -0x04, 0x00, 0x05, 0x8E, 0x09, 0xF8, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0x80, 0x02, 0x3C, 0xEE, 0x5D, 0x43, 0x90, 0x0C, 0x00, 0x02, 0x24, -0xFF, 0x00, 0x63, 0x30, 0x05, 0x00, 0x62, 0x10, 0x10, 0x00, 0xA4, 0x27, -0x90, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xF7, 0x2C, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C, 0x06, 0x5E, 0x43, 0x90, -0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x60, 0x10, 0x02, 0x80, 0x05, 0x3C, -0x0C, 0x5E, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, -0x0C, 0x5E, 0xA2, 0xA0, 0x90, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0xF7, 0x2C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xB0, 0x04, 0x3C, -0x28, 0x00, 0x85, 0x34, 0x02, 0x00, 0x82, 0x94, 0x04, 0x00, 0x84, 0x24, -0x05, 0x00, 0x40, 0x14, 0x2B, 0x18, 0xA4, 0x00, 0xFB, 0xFF, 0x60, 0x10, -0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x25, 0xB0, 0x03, 0x3C, -0xBE, 0x00, 0x63, 0x34, 0x00, 0x00, 0x62, 0x94, 0x08, 0x00, 0xE0, 0x03, -0x01, 0x00, 0x42, 0x2C, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF, -0x24, 0x2D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x03, 0x3C, -0x19, 0x00, 0x40, 0x10, 0x98, 0x54, 0x64, 0x24, 0x98, 0x54, 0x62, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x44, 0x14, 0x02, 0x80, 0x02, 0x3C, -0x0D, 0x5E, 0x43, 0x90, 0x01, 0x00, 0x02, 0x24, 0xFF, 0x00, 0x63, 0x30, -0x10, 0x00, 0x62, 0x10, 0x02, 0x80, 0x03, 0x3C, 0xED, 0x5D, 0x62, 0x90, -0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x42, 0x30, 0x05, 0x00, 0x42, 0x28, -0x0A, 0x00, 0x40, 0x10, 0x01, 0x00, 0x04, 0x24, 0x02, 0x80, 0x02, 0x3C, -0x64, 0x59, 0x43, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x60, 0x14, -0x21, 0x10, 0x80, 0x00, 0x10, 0x00, 0xBF, 0x8F, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0x8F, -0x21, 0x20, 0x00, 0x00, 0x21, 0x10, 0x80, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF, -0x24, 0x2D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x40, 0x10, -0x02, 0x80, 0x02, 0x3C, 0x98, 0x54, 0x43, 0x8C, 0x98, 0x54, 0x42, 0x24, -0x28, 0x00, 0x62, 0x14, 0x02, 0x80, 0x03, 0x3C, 0x05, 0x5E, 0x62, 0x90, -0x01, 0x00, 0x04, 0x24, 0xFF, 0x00, 0x42, 0x30, 0x23, 0x00, 0x44, 0x10, -0x02, 0x80, 0x03, 0x3C, 0xED, 0x5D, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, -0x0F, 0x00, 0x42, 0x30, 0x03, 0x00, 0x42, 0x28, 0x1D, 0x00, 0x40, 0x10, -0x02, 0x80, 0x03, 0x3C, 0x07, 0x5E, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, -0x04, 0x00, 0x42, 0x30, 0x18, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x07, 0x5E, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x42, 0x30, -0x13, 0x00, 0x40, 0x14, 0x02, 0x80, 0x03, 0x3C, 0x0D, 0x5E, 0x62, 0x90, -0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x42, 0x30, 0x0E, 0x00, 0x44, 0x10, -0x02, 0x80, 0x02, 0x3C, 0x0E, 0x5E, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, -0x0A, 0x00, 0x60, 0x14, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, -0x04, 0x3E, 0x43, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x60, 0x14, -0x21, 0x18, 0x00, 0x00, 0x3C, 0x3A, 0x42, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x02, 0x00, 0x40, 0x14, 0x01, 0x00, 0x03, 0x24, 0x21, 0x18, 0x00, 0x00, -0x10, 0x00, 0xBF, 0x8F, 0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF, -0x30, 0x2D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x03, 0x3C, -0x0E, 0x00, 0x40, 0x10, 0x90, 0x54, 0x65, 0x24, 0x90, 0x54, 0x62, 0x8C, -0x02, 0x80, 0x04, 0x3C, 0x88, 0x54, 0x86, 0x24, 0x09, 0x00, 0x45, 0x14, -0x01, 0x00, 0x03, 0x24, 0x88, 0x54, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x05, 0x00, 0x46, 0x14, 0x21, 0x10, 0x60, 0x00, 0x10, 0x00, 0xBF, 0x8F, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, -0x10, 0x00, 0xBF, 0x8F, 0x21, 0x18, 0x00, 0x00, 0x21, 0x10, 0x60, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27, -0x18, 0x00, 0xB0, 0xAF, 0xFF, 0x00, 0x90, 0x30, 0x10, 0x00, 0xA4, 0x27, -0x20, 0x00, 0xB2, 0xAF, 0x24, 0x00, 0xBF, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, -0x8A, 0x40, 0x00, 0x0C, 0x02, 0x80, 0x12, 0x3C, 0x0F, 0x00, 0x00, 0x12, -0x00, 0x00, 0x00, 0x00, 0x3C, 0x5E, 0x43, 0x92, 0x01, 0x00, 0x02, 0x24, -0x04, 0x0C, 0x04, 0x24, 0xFF, 0x00, 0x63, 0x30, 0x2A, 0x00, 0x62, 0x10, -0x80, 0x01, 0x10, 0x3C, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, -0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, -0x3C, 0x5E, 0x43, 0x92, 0x02, 0x00, 0x02, 0x24, 0x21, 0x28, 0x00, 0x00, -0xFF, 0x00, 0x63, 0x30, 0xF3, 0xFF, 0x62, 0x14, 0x44, 0x08, 0x04, 0x24, -0x03, 0x5C, 0x00, 0x0C, 0x7F, 0xFE, 0x10, 0x3C, 0x30, 0x5C, 0x00, 0x0C, -0x04, 0x0C, 0x04, 0x24, 0xFD, 0x00, 0x45, 0x30, 0x1A, 0x5C, 0x00, 0x0C, -0x04, 0x0C, 0x04, 0x24, 0x30, 0x5C, 0x00, 0x0C, 0x04, 0x0D, 0x04, 0x24, -0xFD, 0x00, 0x45, 0x30, 0x1A, 0x5C, 0x00, 0x0C, 0x04, 0x0D, 0x04, 0x24, -0x26, 0x5C, 0x00, 0x0C, 0x70, 0x0E, 0x04, 0x24, 0xFF, 0xFF, 0x10, 0x36, -0x24, 0x28, 0x50, 0x00, 0x03, 0x5C, 0x00, 0x0C, 0x70, 0x0E, 0x04, 0x24, -0x26, 0x5C, 0x00, 0x0C, 0x8C, 0x0E, 0x04, 0x24, 0x24, 0x28, 0x50, 0x00, -0x03, 0x5C, 0x00, 0x0C, 0x8C, 0x0E, 0x04, 0x24, 0x01, 0x00, 0x02, 0x24, -0x3C, 0x5E, 0x42, 0xA2, 0xB9, 0x2D, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x30, 0x5C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x34, -0xFF, 0x00, 0x45, 0x30, 0x1A, 0x5C, 0x00, 0x0C, 0x04, 0x0C, 0x04, 0x24, -0x30, 0x5C, 0x00, 0x0C, 0x04, 0x0D, 0x04, 0x24, 0x02, 0x00, 0x42, 0x34, -0xFF, 0x00, 0x45, 0x30, 0x1A, 0x5C, 0x00, 0x0C, 0x04, 0x0D, 0x04, 0x24, -0x26, 0x5C, 0x00, 0x0C, 0x70, 0x0E, 0x04, 0x24, 0x25, 0x28, 0x50, 0x00, -0x03, 0x5C, 0x00, 0x0C, 0x70, 0x0E, 0x04, 0x24, 0x26, 0x5C, 0x00, 0x0C, -0x8C, 0x0E, 0x04, 0x24, 0x25, 0x28, 0x50, 0x00, 0x03, 0x5C, 0x00, 0x0C, -0x8C, 0x0E, 0x04, 0x24, 0x03, 0x00, 0x05, 0x3C, 0x59, 0x01, 0xA5, 0x34, -0x03, 0x5C, 0x00, 0x0C, 0x44, 0x08, 0x04, 0x24, 0x02, 0x00, 0x02, 0x24, -0x3C, 0x5E, 0x42, 0xA2, 0xB9, 0x2D, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x25, 0xB0, 0x02, 0x3C, 0x42, 0x00, 0x46, 0x34, 0xFC, 0x37, 0x03, 0x24, -0x40, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0xA4, 0x03, 0x08, 0x04, 0x24, -0x03, 0x00, 0x05, 0x24, 0x00, 0x00, 0xC0, 0xA0, 0x1A, 0x5C, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB2, 0xAF, -0x14, 0x00, 0xB1, 0xAF, 0x1C, 0x00, 0xBF, 0xAF, 0x10, 0x00, 0xB0, 0xAF, -0x02, 0x80, 0x02, 0x3C, 0xEC, 0x5D, 0x43, 0x90, 0xFC, 0x57, 0x12, 0x24, -0x0B, 0x00, 0x60, 0x10, 0xFC, 0x77, 0x11, 0x24, 0x02, 0x80, 0x02, 0x3C, -0xC6, 0x5C, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x63, 0x30, -0x2A, 0x00, 0x60, 0x14, 0x21, 0x20, 0x00, 0x00, 0x21, 0x30, 0x00, 0x00, -0x00, 0x02, 0x05, 0x3C, 0xC1, 0x43, 0x00, 0x0C, 0x00, 0x08, 0x04, 0x24, -0x25, 0xB0, 0x03, 0x3C, 0x21, 0x00, 0x65, 0x34, 0x00, 0x00, 0xA2, 0x90, -0x18, 0x00, 0x66, 0x34, 0x40, 0x00, 0x70, 0x34, 0x01, 0x00, 0x42, 0x34, -0x42, 0x00, 0x63, 0x34, 0x00, 0x00, 0xA2, 0xA0, 0xFF, 0xFF, 0x02, 0x24, -0x00, 0x00, 0xC0, 0xA0, 0x64, 0x00, 0x04, 0x24, 0x00, 0x00, 0x62, 0xA0, -0x00, 0x00, 0x12, 0xA6, 0x5B, 0x1F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x11, 0xA6, 0x5B, 0x1F, 0x00, 0x0C, 0x0A, 0x00, 0x04, 0x24, -0x21, 0x28, 0x00, 0x00, 0x1A, 0x5C, 0x00, 0x0C, 0x03, 0x08, 0x04, 0x24, -0x5B, 0x1F, 0x00, 0x0C, 0x0A, 0x00, 0x04, 0x24, 0xFC, 0x37, 0x02, 0x24, -0x00, 0x00, 0x02, 0xA6, 0x5B, 0x1F, 0x00, 0x0C, 0x0A, 0x00, 0x04, 0x24, -0x00, 0x00, 0x11, 0xA6, 0x5B, 0x1F, 0x00, 0x0C, 0x0A, 0x00, 0x04, 0x24, -0x00, 0x00, 0x12, 0xA6, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x20, 0x00, 0xBD, 0x27, 0xA8, 0x2D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x21, 0x30, 0x00, 0x00, 0x00, 0x02, 0x05, 0x3C, 0xC1, 0x43, 0x00, 0x0C, -0x00, 0x08, 0x04, 0x24, 0x1F, 0x2E, 0x00, 0x08, 0x25, 0xB0, 0x03, 0x3C, -0xB8, 0xFF, 0xBD, 0x27, 0x2C, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB0, 0xAF, -0x02, 0x80, 0x13, 0x3C, 0xFF, 0x00, 0x90, 0x30, 0x18, 0x00, 0xA4, 0x27, -0x30, 0x00, 0xB4, 0xAF, 0x28, 0x00, 0xB2, 0xAF, 0x24, 0x00, 0xB1, 0xAF, -0x40, 0x00, 0xBF, 0xAF, 0x3C, 0x00, 0xB7, 0xAF, 0x38, 0x00, 0xB6, 0xAF, -0x34, 0x00, 0xB5, 0xAF, 0x8A, 0x40, 0x00, 0x0C, 0xFF, 0x00, 0xB2, 0x30, -0xEE, 0x5D, 0x62, 0x92, 0x0F, 0x00, 0x11, 0x32, 0x0F, 0x00, 0x42, 0x30, -0x13, 0x00, 0x51, 0x10, 0x21, 0xA0, 0x00, 0x00, 0x04, 0x00, 0x02, 0x32, -0x40, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x5D, 0x62, 0x92, -0x0C, 0x00, 0x03, 0x24, 0x0F, 0x00, 0x42, 0x30, 0x8F, 0x00, 0x43, 0x10, -0x08, 0x00, 0x02, 0x32, 0xEE, 0x5D, 0x62, 0x92, 0x04, 0x00, 0x03, 0x24, -0x0F, 0x00, 0x42, 0x30, 0xD2, 0x01, 0x43, 0x10, 0x00, 0x00, 0x00, 0x00, -0xEE, 0x5D, 0x62, 0x92, 0x02, 0x00, 0x03, 0x24, 0x0F, 0x00, 0x42, 0x30, -0x9B, 0x00, 0x43, 0x10, 0x06, 0x00, 0x02, 0x32, 0x02, 0x80, 0x10, 0x3C, -0xED, 0x5D, 0x03, 0x92, 0xEE, 0x5D, 0x62, 0x92, 0x0F, 0x00, 0x63, 0x30, -0x0F, 0x00, 0x42, 0x30, 0x2A, 0x10, 0x43, 0x00, 0x1C, 0x00, 0x40, 0x14, -0x02, 0x80, 0x12, 0x3C, 0xED, 0x5D, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, -0x40, 0x00, 0x42, 0x30, 0x17, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C, -0xC2, 0x5C, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x43, 0x30, -0x52, 0x00, 0x60, 0x14, 0x04, 0x00, 0x42, 0x30, 0x10, 0x00, 0x40, 0x10, -0x00, 0x00, 0x00, 0x00, 0xEE, 0x5D, 0x43, 0x92, 0x02, 0x80, 0x06, 0x3C, -0x14, 0xE5, 0xC5, 0x90, 0x0F, 0x00, 0x63, 0x30, 0x25, 0xB0, 0x02, 0x3C, -0x25, 0x18, 0x65, 0x00, 0xDD, 0x02, 0x42, 0x34, 0x00, 0x00, 0x43, 0xA0, -0xED, 0x5D, 0x04, 0x92, 0x80, 0xFF, 0x02, 0x24, 0xBF, 0xFF, 0x03, 0x24, -0x26, 0x28, 0xA2, 0x00, 0x24, 0x20, 0x83, 0x00, 0x14, 0xE5, 0xC5, 0xA0, -0xED, 0x5D, 0x04, 0xA2, 0x90, 0x40, 0x00, 0x0C, 0x18, 0x00, 0xA4, 0x27, -0x40, 0x00, 0xBF, 0x8F, 0x3C, 0x00, 0xB7, 0x8F, 0x38, 0x00, 0xB6, 0x8F, -0x34, 0x00, 0xB5, 0x8F, 0x30, 0x00, 0xB4, 0x8F, 0x2C, 0x00, 0xB3, 0x8F, -0x28, 0x00, 0xB2, 0x8F, 0x24, 0x00, 0xB1, 0x8F, 0x20, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x48, 0x00, 0xBD, 0x27, 0xEE, 0x5D, 0x62, 0x92, -0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x42, 0x30, 0x4C, 0x00, 0x40, 0x10, -0x00, 0x00, 0x00, 0x00, 0xEE, 0x5D, 0x62, 0x92, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0x42, 0x30, 0x03, 0x00, 0x40, 0x10, 0x08, 0x00, 0x02, 0x32, -0x1B, 0x00, 0x40, 0x10, 0x02, 0x80, 0x03, 0x3C, 0xEE, 0x5D, 0x62, 0x92, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x42, 0x30, 0x0C, 0x00, 0x40, 0x14, -0x08, 0x00, 0x02, 0x32, 0x0A, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0x40, 0x12, 0x02, 0x80, 0x03, 0x3C, 0x10, 0x37, 0x62, 0x94, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x30, 0x03, 0x00, 0x40, 0x10, -0x00, 0x00, 0x00, 0x00, 0x0E, 0x51, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x00, -0xEE, 0x5D, 0x62, 0x92, 0xF0, 0xFF, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, -0xEE, 0x5D, 0x62, 0xA2, 0xEE, 0x5D, 0x63, 0x92, 0x00, 0x00, 0x00, 0x00, -0x25, 0x18, 0x23, 0x02, 0xEE, 0x5D, 0x63, 0xA2, 0x72, 0x2E, 0x00, 0x08, -0x02, 0x80, 0x10, 0x3C, 0x10, 0x37, 0x62, 0x94, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x42, 0x30, 0xF2, 0xFF, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C, -0x0D, 0x5E, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xFF, 0x60, 0x14, -0x01, 0x00, 0x04, 0x24, 0x0E, 0x51, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0xBD, 0x2E, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x53, 0x21, 0x00, 0x0C, -0x24, 0x00, 0x04, 0x24, 0x76, 0x01, 0x40, 0x10, 0x21, 0x88, 0x40, 0x00, -0x02, 0x80, 0x02, 0x3C, 0xEC, 0x5D, 0x45, 0x90, 0xEE, 0x5D, 0x44, 0x92, -0xED, 0x5D, 0x02, 0x92, 0xBF, 0xFF, 0x03, 0x24, 0x0F, 0x00, 0x84, 0x30, -0x24, 0x10, 0x43, 0x00, 0xED, 0x5D, 0x02, 0xA2, 0x10, 0x00, 0xA5, 0xA3, -0x11, 0x00, 0xA4, 0xA3, 0x08, 0x00, 0x24, 0x96, 0x02, 0x80, 0x02, 0x3C, -0x10, 0x00, 0xA5, 0x27, 0x25, 0x20, 0x82, 0x00, 0x20, 0x00, 0x84, 0x24, -0xC2, 0x1B, 0x00, 0x0C, 0x01, 0x00, 0x06, 0x24, 0x04, 0x00, 0x03, 0x24, -0x17, 0x00, 0x02, 0x24, 0x0C, 0x00, 0x23, 0xAE, 0x14, 0x00, 0x22, 0xAE, -0x17, 0x0A, 0x00, 0x0C, 0x21, 0x20, 0x20, 0x02, 0x94, 0x2E, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0xA6, 0x2E, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x71, 0xFF, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x35, 0x2D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x77, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x5D, 0x62, 0x92, -0xF0, 0xFF, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, 0xEE, 0x5D, 0x62, 0xA2, -0x02, 0x80, 0x03, 0x3C, 0xEE, 0x5D, 0x62, 0x92, 0x10, 0x37, 0x64, 0x94, -0x04, 0x00, 0x42, 0x34, 0x00, 0x01, 0x84, 0x30, 0xEE, 0x5D, 0x62, 0xA2, -0x61, 0xFF, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x51, 0x00, 0x0C, -0x01, 0x00, 0x04, 0x24, 0x67, 0x2E, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x65, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x8F, 0x2D, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x61, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, -0xEE, 0x5D, 0x62, 0x92, 0xF0, 0xFF, 0x03, 0x24, 0x41, 0xB0, 0x04, 0x3C, -0x24, 0x10, 0x43, 0x00, 0xEE, 0x5D, 0x62, 0xA2, 0xEE, 0x5D, 0x63, 0x92, -0x08, 0x00, 0x85, 0x34, 0x82, 0x00, 0x02, 0x24, 0x01, 0x00, 0x63, 0x34, -0x02, 0x80, 0x17, 0x3C, 0xEE, 0x5D, 0x63, 0xA2, 0x00, 0x00, 0x80, 0xAC, -0x00, 0x00, 0xA2, 0xA4, 0x42, 0xB0, 0x04, 0x3C, 0x60, 0x1B, 0xE2, 0x26, -0xB0, 0x1B, 0x45, 0x94, 0x00, 0x00, 0x83, 0x90, 0xBE, 0xFF, 0x02, 0x24, -0x03, 0x00, 0x86, 0x34, 0x24, 0x18, 0x62, 0x00, 0x00, 0x01, 0xA5, 0x30, -0x90, 0xFF, 0x02, 0x24, 0x00, 0x00, 0x83, 0xA0, 0x00, 0x00, 0xC2, 0xA0, -0x38, 0x00, 0xA0, 0x10, 0x25, 0xB0, 0x06, 0x3C, 0x25, 0xB0, 0x04, 0x3C, -0x84, 0x00, 0x82, 0x34, 0x00, 0x00, 0x46, 0x8C, 0x80, 0x00, 0x84, 0x34, -0x00, 0x00, 0x82, 0x8C, 0x02, 0x80, 0x0B, 0x3C, 0x14, 0x5E, 0x64, 0x8D, -0x00, 0x38, 0x06, 0x00, 0x21, 0x30, 0x00, 0x00, 0x25, 0xA0, 0xC2, 0x00, -0x21, 0x18, 0x00, 0x00, 0x02, 0x80, 0x0A, 0x3C, 0x25, 0xA8, 0xE3, 0x00, -0x21, 0x28, 0x00, 0x00, 0x1C, 0x5E, 0x42, 0x8D, 0x21, 0x20, 0x94, 0x00, -0x2B, 0x18, 0x94, 0x00, 0x21, 0x28, 0xB5, 0x00, 0x21, 0x28, 0xA3, 0x00, -0x2B, 0x10, 0xA2, 0x00, 0x24, 0x01, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x1C, 0x5E, 0x42, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x45, 0x10, -0x01, 0x00, 0x05, 0x24, 0x60, 0x1B, 0xE2, 0x26, 0x58, 0x41, 0x43, 0x8C, -0x42, 0xB0, 0x07, 0x3C, 0x00, 0x00, 0xE6, 0x90, 0x18, 0x00, 0x65, 0x00, -0xFB, 0xFF, 0x02, 0x24, 0x24, 0x30, 0xC2, 0x00, 0x00, 0x00, 0xE6, 0xA0, -0x67, 0x46, 0x06, 0x3C, 0xCF, 0xAC, 0xC6, 0x34, 0x01, 0x00, 0x04, 0x24, -0x21, 0x28, 0x00, 0x00, 0x12, 0x18, 0x00, 0x00, 0x82, 0x1A, 0x03, 0x00, -0x40, 0x10, 0x03, 0x00, 0x21, 0x10, 0x43, 0x00, 0xC0, 0x10, 0x02, 0x00, -0x21, 0x10, 0x43, 0x00, 0x80, 0x10, 0x02, 0x00, 0x19, 0x00, 0x46, 0x00, -0x10, 0x30, 0x00, 0x00, 0x23, 0x10, 0x46, 0x00, 0x42, 0x10, 0x02, 0x00, -0x21, 0x30, 0xC2, 0x00, 0x02, 0x33, 0x06, 0x00, 0x01, 0x00, 0x02, 0x24, -0xB9, 0x20, 0x00, 0x0C, 0x0A, 0x30, 0x46, 0x00, 0x25, 0xB0, 0x06, 0x3C, -0xF2, 0x02, 0xC3, 0x34, 0x88, 0xFF, 0x02, 0x24, 0x00, 0x00, 0x62, 0xA0, -0x11, 0x00, 0xC7, 0x34, 0x00, 0x00, 0xE2, 0x90, 0x08, 0x00, 0xC5, 0x34, -0x60, 0x1B, 0xE4, 0x26, 0x01, 0x00, 0x42, 0x34, 0x00, 0x00, 0xE2, 0xA0, -0x00, 0x00, 0xA3, 0x94, 0xB0, 0x1B, 0x82, 0x94, 0xFF, 0xFF, 0x64, 0x30, -0x10, 0x00, 0x84, 0x34, 0x00, 0x00, 0xA4, 0xA4, 0xFB, 0xFF, 0x84, 0x30, -0x00, 0x00, 0xA4, 0xA4, 0x00, 0x01, 0x42, 0x30, 0x02, 0x00, 0x84, 0x34, -0x00, 0x00, 0xA4, 0xA4, 0x04, 0x00, 0x40, 0x10, 0x42, 0xB0, 0x02, 0x3C, -0x22, 0x00, 0x03, 0x24, 0x03, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0xA0, -0xFF, 0xF7, 0x84, 0x30, 0x00, 0x00, 0xA4, 0xA4, 0x28, 0x00, 0xC4, 0x34, -0x00, 0x00, 0x83, 0x94, 0xEF, 0xFE, 0x02, 0x24, 0xFE, 0xFF, 0x08, 0x24, -0x24, 0x18, 0x62, 0x00, 0x00, 0x00, 0x83, 0xA4, 0x00, 0x00, 0x82, 0x94, -0x26, 0x00, 0xC5, 0x34, 0x02, 0x80, 0x03, 0x3C, 0x24, 0x10, 0x48, 0x00, -0x00, 0x00, 0x82, 0xA4, 0xC2, 0x5C, 0x64, 0x90, 0x00, 0x00, 0xA2, 0x94, -0x04, 0x00, 0x84, 0x30, 0x00, 0x24, 0x42, 0x34, 0x00, 0x00, 0xA2, 0xA4, -0x09, 0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x94, -0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x48, 0x00, 0x00, 0x00, 0xA2, 0xA4, -0x00, 0x00, 0xE3, 0x90, 0xFD, 0xFF, 0x02, 0x24, 0x24, 0x18, 0x62, 0x00, -0x00, 0x00, 0xE3, 0xA0, 0x00, 0x68, 0x02, 0x40, 0x00, 0x08, 0x42, 0x30, -0xFD, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x12, 0x3C, -0x11, 0x00, 0x43, 0x36, 0x00, 0x00, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, -0x02, 0x00, 0x42, 0x34, 0x00, 0x00, 0x62, 0xA0, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x44, 0x36, 0x00, 0x00, 0x82, 0x94, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x34, 0x00, 0x00, 0x82, 0xA4, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x94, -0xFF, 0xDB, 0x02, 0x24, 0x28, 0x00, 0x45, 0x36, 0x24, 0x18, 0x62, 0x00, -0x00, 0x00, 0x83, 0xA4, 0x00, 0x00, 0xA2, 0x94, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x42, 0x34, 0x00, 0x00, 0xA2, 0xA4, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x94, 0x00, 0x00, 0x00, 0x00, -0x10, 0x01, 0x42, 0x34, 0x00, 0x00, 0xA2, 0xA4, 0x08, 0x00, 0x51, 0x36, -0x00, 0x00, 0x23, 0x96, 0x60, 0x1B, 0xF6, 0x26, 0xB0, 0x1B, 0xC2, 0x96, -0xFF, 0xFF, 0x70, 0x30, 0x00, 0x18, 0x10, 0x36, 0x00, 0x00, 0x30, 0xA6, -0x00, 0x01, 0x42, 0x30, 0xFD, 0xFF, 0x10, 0x32, 0x00, 0x00, 0x30, 0xA6, -0x05, 0x00, 0x40, 0x10, 0x42, 0xB0, 0x02, 0x3C, 0x00, 0x00, 0x43, 0x90, -0xFB, 0xFF, 0x04, 0x24, 0x24, 0x18, 0x64, 0x00, 0x00, 0x00, 0x43, 0xA0, -0x04, 0x00, 0x10, 0x36, 0x5B, 0x1F, 0x00, 0x0C, 0x32, 0x00, 0x04, 0x24, -0x00, 0x00, 0x30, 0xA6, 0x22, 0x00, 0x02, 0x24, 0xF2, 0x02, 0x43, 0x36, -0xEF, 0xFF, 0x10, 0x32, 0x00, 0x00, 0x30, 0xA6, 0xC8, 0x00, 0x04, 0x24, -0x00, 0x00, 0x62, 0xA0, 0x5B, 0x1F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0xB0, 0x1B, 0xC2, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x30, -0x41, 0x00, 0x40, 0x10, 0x42, 0xB0, 0x06, 0x3C, 0x84, 0x00, 0x42, 0x36, -0x00, 0x00, 0x44, 0x8C, 0x80, 0x00, 0x46, 0x36, 0x00, 0x00, 0xC2, 0x8C, -0x00, 0x28, 0x04, 0x00, 0x21, 0x18, 0x00, 0x00, 0x21, 0x20, 0x00, 0x00, -0x25, 0x30, 0x82, 0x00, 0x25, 0x38, 0xA3, 0x00, 0x58, 0x41, 0xC3, 0x8E, -0x23, 0x28, 0xD4, 0x00, 0x80, 0x12, 0x05, 0x00, 0x1B, 0x00, 0x43, 0x00, -0x02, 0x00, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00, -0x02, 0x80, 0x0B, 0x3C, 0x14, 0x5E, 0x63, 0x8D, 0x12, 0x10, 0x00, 0x00, -0x23, 0x10, 0x45, 0x00, 0x21, 0x10, 0x43, 0x00, 0x14, 0x5E, 0x62, 0xAD, -0x14, 0x5E, 0x63, 0x8D, 0x42, 0xB0, 0x02, 0x3C, 0x03, 0x00, 0x42, 0x34, -0x58, 0x1B, 0x63, 0x24, 0x14, 0x5E, 0x63, 0xAD, 0x00, 0x00, 0x43, 0x90, -0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x63, 0x30, 0x20, 0x00, 0x60, 0x14, -0x00, 0x00, 0x00, 0x00, 0x14, 0x5E, 0x62, 0x8D, 0x02, 0x80, 0x0A, 0x3C, -0x1C, 0x5E, 0x44, 0x8D, 0x21, 0x40, 0x46, 0x00, 0x2B, 0x28, 0x06, 0x01, -0x21, 0x48, 0x67, 0x00, 0x21, 0x48, 0x25, 0x01, 0x2B, 0x20, 0x24, 0x01, -0x59, 0x00, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x5E, 0x42, 0x8D, -0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x49, 0x10, 0x01, 0x00, 0x05, 0x24, -0x42, 0xB0, 0x02, 0x3C, 0x00, 0x00, 0x43, 0x90, 0xFB, 0xFF, 0x04, 0x24, -0x01, 0x00, 0x06, 0x24, 0x24, 0x18, 0x64, 0x00, 0x00, 0x00, 0x43, 0xA0, -0x04, 0x00, 0xA0, 0x10, 0x01, 0x00, 0x04, 0x24, 0x80, 0x10, 0x05, 0x00, -0x21, 0x10, 0x45, 0x00, 0x80, 0x30, 0x02, 0x00, 0xB9, 0x20, 0x00, 0x0C, -0x21, 0x28, 0x00, 0x00, 0x42, 0xB0, 0x02, 0x3C, 0x22, 0x00, 0x03, 0x24, -0x03, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0xA0, 0x42, 0xB0, 0x06, 0x3C, -0x00, 0x00, 0xC2, 0x90, 0x60, 0x1B, 0xE5, 0x26, 0xD0, 0x1B, 0xA8, 0x8C, -0xDC, 0x1B, 0xA7, 0x94, 0x41, 0xB0, 0x03, 0x3C, 0x41, 0x00, 0x42, 0x34, -0x08, 0x00, 0x64, 0x34, 0x00, 0x00, 0xC2, 0xA0, 0x00, 0x00, 0x68, 0xAC, -0x00, 0x00, 0x87, 0xA4, 0xEE, 0x5D, 0x63, 0x92, 0xF0, 0xFF, 0x02, 0x24, -0xDC, 0x1B, 0xA7, 0xA4, 0x24, 0x18, 0x62, 0x00, 0xEE, 0x5D, 0x63, 0xA2, -0xEE, 0x5D, 0x62, 0x92, 0xD0, 0x1B, 0xA8, 0xAC, 0x02, 0x00, 0x42, 0x34, -0xEE, 0x5D, 0x62, 0xA2, 0x72, 0x2E, 0x00, 0x08, 0x02, 0x80, 0x10, 0x3C, -0x59, 0x2D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x31, 0xFE, 0x40, 0x10, -0x00, 0x00, 0x00, 0x00, 0x0A, 0x2E, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0xEE, 0x5D, 0x62, 0x92, 0xF0, 0xFF, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, -0xEE, 0x5D, 0x62, 0xA2, 0xEE, 0x5D, 0x63, 0x92, 0x00, 0x00, 0x00, 0x00, -0x02, 0x00, 0x63, 0x34, 0xEE, 0x5D, 0x63, 0xA2, 0x6C, 0x2E, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x99, 0x99, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, -0x97, 0x99, 0x63, 0x34, 0x18, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, -0x94, 0x2E, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x18, 0x5E, 0x42, 0x8D, -0x00, 0x00, 0x00, 0x00, 0x2B, 0x10, 0x82, 0x00, 0x0C, 0x00, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x18, 0x5E, 0x42, 0x8D, 0x45, 0x2F, 0x00, 0x08, -0x01, 0x00, 0x05, 0x24, 0x18, 0x5E, 0x42, 0x8D, 0x00, 0x00, 0x00, 0x00, -0x2B, 0x10, 0x02, 0x01, 0x0A, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x18, 0x5E, 0x42, 0x8D, 0x16, 0x30, 0x00, 0x08, 0x01, 0x00, 0x05, 0x24, -0x18, 0x5E, 0x42, 0x8D, 0x1C, 0x5E, 0x43, 0x8D, 0x14, 0x5E, 0x64, 0x8D, -0x23, 0x10, 0x54, 0x00, 0x45, 0x2F, 0x00, 0x08, 0x23, 0x28, 0x44, 0x00, -0x18, 0x5E, 0x42, 0x8D, 0x1C, 0x5E, 0x43, 0x8D, 0x14, 0x5E, 0x64, 0x8D, -0x23, 0x10, 0x46, 0x00, 0x16, 0x30, 0x00, 0x08, 0x23, 0x28, 0x44, 0x00, -0x02, 0x80, 0x02, 0x3C, 0xEC, 0x5D, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, -0x07, 0x00, 0x60, 0x10, 0x02, 0x80, 0x02, 0x3C, 0xEE, 0x5D, 0x43, 0x90, -0x04, 0x00, 0x04, 0x24, 0x0F, 0x00, 0x63, 0x30, 0x04, 0x00, 0x63, 0x28, -0x03, 0x00, 0x60, 0x14, 0x01, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0x4B, 0x2E, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x01, 0x80, 0x02, 0x3C, 0x25, 0xB0, 0x03, 0x3C, 0xE0, 0xFF, 0xBD, 0x27, -0xFC, 0xC1, 0x42, 0x24, 0x18, 0x03, 0x63, 0x34, 0x10, 0x00, 0xA4, 0x27, -0x00, 0x00, 0x62, 0xAC, 0x18, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, 0x0C, 0x5E, 0x82, 0x90, -0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x40, 0x10, 0x01, 0x00, 0x05, 0x24, -0x02, 0x80, 0x02, 0x3C, 0xD0, 0x07, 0x03, 0x24, 0x0C, 0x5E, 0x80, 0xA0, -0x10, 0x00, 0xA4, 0x27, 0x90, 0x40, 0x00, 0x0C, 0xDC, 0x5D, 0x43, 0xAC, -0x18, 0x00, 0xBF, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x20, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x03, 0x3C, 0x01, 0x00, 0x04, 0x24, -0x02, 0x80, 0x02, 0x3C, 0x0F, 0x5E, 0x44, 0xA0, 0x02, 0x80, 0x02, 0x3C, -0x0D, 0x5E, 0x60, 0xA0, 0xED, 0x5D, 0x44, 0x90, 0x4B, 0x2E, 0x00, 0x0C, -0xFF, 0x00, 0x84, 0x30, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, -0x18, 0x00, 0xBF, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x20, 0x00, 0xBD, 0x27, 0x42, 0x11, 0x05, 0x00, 0x0F, 0x00, 0x46, 0x30, -0xE8, 0xFF, 0xBD, 0x27, 0x09, 0x00, 0xC3, 0x28, 0x14, 0x00, 0xBF, 0xAF, -0x14, 0x00, 0x60, 0x10, 0x10, 0x00, 0xB0, 0xAF, 0x82, 0x16, 0x05, 0x00, -0x01, 0x00, 0x42, 0x30, 0x14, 0x00, 0x40, 0x10, 0x00, 0xC0, 0x02, 0x3C, -0x24, 0x10, 0xA2, 0x00, 0x43, 0x00, 0x40, 0x14, 0xC2, 0x15, 0x04, 0x00, -0x01, 0x00, 0x42, 0x30, 0x50, 0x00, 0x40, 0x10, 0x02, 0x80, 0x03, 0x3C, -0x0C, 0xE5, 0x63, 0x24, 0x21, 0x18, 0xC3, 0x00, 0x02, 0x80, 0x04, 0x3C, -0x08, 0x5E, 0x85, 0x90, 0x00, 0x00, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, -0x24, 0x10, 0x45, 0x00, 0x47, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, -0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0x24, 0x10, 0xA2, 0x00, 0x1E, 0x00, 0x40, 0x10, -0xC2, 0x15, 0x04, 0x00, 0x02, 0x80, 0x06, 0x3C, 0x07, 0x5E, 0xC2, 0x90, -0xFD, 0xFF, 0x03, 0x24, 0x42, 0xB0, 0x04, 0x3C, 0x24, 0x10, 0x43, 0x00, -0x02, 0x80, 0x03, 0x3C, 0x07, 0x5E, 0xC2, 0xA0, 0x0B, 0x5E, 0x60, 0xA0, -0x00, 0x00, 0x82, 0x90, 0xEF, 0xFF, 0x03, 0x24, 0x03, 0x00, 0x85, 0x34, -0x24, 0x10, 0x43, 0x00, 0x40, 0x00, 0x03, 0x24, 0x00, 0x00, 0x82, 0xA0, -0x00, 0x00, 0xA3, 0xA0, 0x07, 0x5E, 0xC2, 0x90, 0x00, 0x00, 0x00, 0x00, -0x07, 0x00, 0x42, 0x30, 0xE6, 0xFF, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, -0x05, 0x5E, 0x40, 0xA0, 0x02, 0x80, 0x03, 0x3C, 0xED, 0x5D, 0x64, 0x90, -0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x01, 0x00, 0x05, 0x24, -0xFF, 0x00, 0x84, 0x30, 0x4B, 0x2E, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, -0x01, 0x00, 0x42, 0x30, 0x25, 0x00, 0x40, 0x10, 0x02, 0x80, 0x03, 0x3C, -0x0C, 0xE5, 0x63, 0x24, 0x21, 0x18, 0xC3, 0x00, 0x02, 0x80, 0x04, 0x3C, -0x08, 0x5E, 0x85, 0x90, 0x00, 0x00, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, -0x24, 0x10, 0x45, 0x00, 0xE7, 0xFF, 0x40, 0x14, 0x02, 0x80, 0x06, 0x3C, -0x07, 0x5E, 0xC2, 0x90, 0xFE, 0xFF, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, -0x07, 0x5E, 0xC2, 0xA0, 0xD7, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x42, 0xB0, 0x07, 0x3C, 0x00, 0x00, 0xE3, 0x90, 0xEF, 0xFF, 0x02, 0x24, -0x03, 0x00, 0xF0, 0x34, 0x24, 0x18, 0x62, 0x00, 0x40, 0x00, 0x02, 0x24, -0x00, 0x00, 0xE3, 0xA0, 0x02, 0x00, 0x04, 0x24, 0x00, 0x00, 0x02, 0xA2, -0x21, 0x28, 0x00, 0x00, 0xB9, 0x20, 0x00, 0x0C, 0x00, 0xF0, 0x06, 0x34, -0x44, 0x00, 0x02, 0x24, 0x00, 0x00, 0x02, 0xA2, 0xC1, 0x30, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x01, 0x00, 0x04, 0x24, 0xE1, 0x51, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, -0x02, 0x80, 0x06, 0x3C, 0x07, 0x5E, 0xC2, 0x90, 0xFE, 0xFF, 0x03, 0x24, -0x24, 0x10, 0x43, 0x00, 0x07, 0x5E, 0xC2, 0xA0, 0xD7, 0x30, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x82, 0x16, 0x05, 0x00, 0xE8, 0xFF, 0xBD, 0x27, -0x01, 0x00, 0x42, 0x30, 0x14, 0x00, 0xBF, 0xAF, 0x0E, 0x00, 0x40, 0x10, -0x10, 0x00, 0xB0, 0xAF, 0x00, 0xC0, 0x02, 0x3C, 0x24, 0x10, 0xA2, 0x00, -0x37, 0x00, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, 0x06, 0x5E, 0x43, 0x90, -0x02, 0x00, 0x02, 0x24, 0xFF, 0x00, 0x63, 0x30, 0x44, 0x00, 0x62, 0x10, -0x01, 0x00, 0x04, 0x24, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0xE1, 0x51, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, 0x00, 0xC0, 0x02, 0x3C, -0x24, 0x10, 0xA2, 0x00, 0x0E, 0x00, 0x40, 0x14, 0x02, 0x80, 0x06, 0x3C, -0x07, 0x5E, 0xC2, 0x90, 0xFE, 0xFF, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, -0x07, 0x5E, 0xC2, 0xA0, 0x07, 0x5E, 0xC2, 0x90, 0x00, 0x00, 0x00, 0x00, -0x07, 0x00, 0x42, 0x30, 0x18, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C, -0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0x07, 0x5E, 0xC2, 0x90, 0xFD, 0xFF, 0x03, 0x24, -0x42, 0xB0, 0x04, 0x3C, 0x24, 0x10, 0x43, 0x00, 0x02, 0x80, 0x03, 0x3C, -0x07, 0x5E, 0xC2, 0xA0, 0x0B, 0x5E, 0x60, 0xA0, 0x00, 0x00, 0x82, 0x90, -0xEF, 0xFF, 0x03, 0x24, 0x03, 0x00, 0x85, 0x34, 0x24, 0x10, 0x43, 0x00, -0x40, 0x00, 0x03, 0x24, 0x00, 0x00, 0x82, 0xA0, 0x00, 0x00, 0xA3, 0xA0, -0x07, 0x5E, 0xC2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x42, 0x30, -0xEA, 0xFF, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, 0x05, 0x5E, 0x40, 0xA0, -0x02, 0x80, 0x03, 0x3C, 0xED, 0x5D, 0x64, 0x90, 0x14, 0x00, 0xBF, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x01, 0x00, 0x05, 0x24, 0xFF, 0x00, 0x84, 0x30, -0x4B, 0x2E, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, 0x42, 0xB0, 0x07, 0x3C, -0x00, 0x00, 0xE3, 0x90, 0xEF, 0xFF, 0x02, 0x24, 0x03, 0x00, 0xF0, 0x34, -0x24, 0x18, 0x62, 0x00, 0x40, 0x00, 0x02, 0x24, 0x00, 0x00, 0xE3, 0xA0, -0x02, 0x00, 0x04, 0x24, 0x00, 0x00, 0x02, 0xA2, 0x21, 0x28, 0x00, 0x00, -0xB9, 0x20, 0x00, 0x0C, 0x00, 0xF0, 0x06, 0x34, 0x44, 0x00, 0x02, 0x24, -0x00, 0x00, 0x02, 0xA2, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xE2, 0x2C, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x0C, 0x00, 0x04, 0x24, 0x01, 0x00, 0x05, 0x24, 0x4B, 0x2E, 0x00, 0x08, -0x18, 0x00, 0xBD, 0x27, 0x01, 0x80, 0x02, 0x3C, 0x25, 0xB0, 0x03, 0x3C, -0xE8, 0xFF, 0xBD, 0x27, 0xB4, 0xC5, 0x42, 0x24, 0x18, 0x03, 0x63, 0x34, -0x10, 0x00, 0xB0, 0xAF, 0x00, 0x00, 0x62, 0xAC, 0x02, 0x80, 0x10, 0x3C, -0xED, 0x5D, 0x02, 0x92, 0x14, 0x00, 0xBF, 0xAF, 0x0F, 0x00, 0x42, 0x30, -0x03, 0x00, 0x42, 0x28, 0x05, 0x00, 0x40, 0x10, 0x01, 0x00, 0x05, 0x24, -0x59, 0x2D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0x10, -0x01, 0x00, 0x05, 0x24, 0xED, 0x5D, 0x04, 0x92, 0x4B, 0x2E, 0x00, 0x0C, -0xFF, 0x00, 0x84, 0x30, 0x02, 0x80, 0x04, 0x3C, 0x60, 0x1B, 0x84, 0x24, -0xE0, 0x1B, 0x83, 0x94, 0xDC, 0x1B, 0x85, 0x94, 0x14, 0x00, 0xBF, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x02, 0x00, 0x63, 0x30, 0x41, 0xB0, 0x02, 0x3C, -0x25, 0x18, 0x65, 0x00, 0x08, 0x00, 0x42, 0x34, 0x18, 0x00, 0xBD, 0x27, -0x00, 0x00, 0x43, 0xA4, 0x08, 0x00, 0xE0, 0x03, 0xDC, 0x1B, 0x83, 0xA4, -0xE0, 0xFF, 0xBD, 0x27, 0x25, 0xB0, 0x02, 0x3C, 0x01, 0x80, 0x03, 0x3C, -0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, -0x1C, 0x00, 0xBF, 0xAF, 0x18, 0x03, 0x52, 0x34, 0x40, 0xC6, 0x71, 0x24, -0x02, 0x80, 0x10, 0x3C, 0x08, 0x14, 0x04, 0x26, 0x21, 0x28, 0x00, 0x00, -0x21, 0x30, 0x00, 0x00, 0x21, 0x38, 0x00, 0x00, 0x00, 0x00, 0x51, 0xAE, -0x76, 0x39, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x31, 0x00, 0x08, -0x08, 0x14, 0x04, 0x26, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF, -0xFF, 0xFF, 0x90, 0x30, 0x1C, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C, -0x10, 0x00, 0xA4, 0x27, 0x02, 0x80, 0x06, 0x3C, 0x60, 0x1B, 0xCD, 0x24, -0x2A, 0x1C, 0xA2, 0x91, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x40, 0x10, -0x2A, 0xB0, 0x02, 0x3C, 0x25, 0xB0, 0x03, 0x3C, 0x38, 0x02, 0x64, 0x34, -0x80, 0xFF, 0x02, 0x24, 0x00, 0x00, 0x82, 0xA0, 0x34, 0x02, 0x6A, 0x34, -0xD2, 0x01, 0x65, 0x34, 0xD6, 0x01, 0x66, 0x34, 0xDA, 0x01, 0x67, 0x34, -0xDE, 0x01, 0x63, 0x34, 0x00, 0x00, 0xA8, 0x94, 0x00, 0x00, 0xC9, 0x94, -0x00, 0x00, 0xEB, 0x94, 0x00, 0x00, 0x6C, 0x94, 0x00, 0x00, 0x44, 0x95, -0xB0, 0xFE, 0x02, 0x26, 0xFF, 0xFF, 0x50, 0x30, 0x28, 0x1C, 0xA4, 0xA5, -0x00, 0x00, 0xA0, 0xA4, 0x10, 0x00, 0xA4, 0x27, 0x20, 0x1C, 0xA8, 0xA5, -0x00, 0x00, 0xC0, 0xA4, 0x22, 0x1C, 0xA9, 0xA5, 0x00, 0x00, 0xE0, 0xA4, -0x24, 0x1C, 0xAB, 0xA5, 0x00, 0x00, 0x60, 0xA4, 0x00, 0x00, 0x50, 0xA5, -0x90, 0x40, 0x00, 0x0C, 0x26, 0x1C, 0xAC, 0xA5, 0x1C, 0x00, 0xBF, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0x0A, 0x00, 0x45, 0x34, 0x63, 0x00, 0x03, 0x24, 0xFF, 0xFF, 0x04, 0x34, -0x00, 0x00, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x40, 0x10, -0x64, 0x00, 0x02, 0x24, 0xFF, 0xFF, 0x42, 0x24, 0xFF, 0xFF, 0x42, 0x30, -0xFE, 0xFF, 0x40, 0x14, 0xFF, 0xFF, 0x42, 0x24, 0xFF, 0xFF, 0x62, 0x24, -0xFF, 0xFF, 0x43, 0x30, 0xF5, 0xFF, 0x64, 0x14, 0x00, 0x00, 0x00, 0x00, -0x60, 0x1B, 0xC2, 0x24, 0x28, 0x1C, 0x48, 0x94, 0x26, 0x1C, 0x47, 0x94, -0x20, 0x1C, 0x49, 0x94, 0x22, 0x1C, 0x4A, 0x94, 0x24, 0x1C, 0x4B, 0x94, -0x25, 0xB0, 0x03, 0x3C, 0x38, 0x02, 0x6C, 0x34, 0x34, 0x02, 0x62, 0x34, -0xD2, 0x01, 0x64, 0x34, 0xD6, 0x01, 0x65, 0x34, 0xDA, 0x01, 0x66, 0x34, -0xDE, 0x01, 0x63, 0x34, 0x00, 0x00, 0x48, 0xA4, 0x00, 0x00, 0x89, 0xA4, -0x00, 0x00, 0xAA, 0xA4, 0x10, 0x00, 0xA4, 0x27, 0x00, 0x00, 0xCB, 0xA4, -0x00, 0x00, 0x67, 0xA4, 0x00, 0x00, 0x80, 0xA1, 0x90, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0xD0, 0xFF, 0xBD, 0x27, -0x28, 0x00, 0xB4, 0xAF, 0x2C, 0x00, 0xBF, 0xAF, 0x24, 0x00, 0xB3, 0xAF, -0x20, 0x00, 0xB2, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, -0xFF, 0xFF, 0x14, 0x24, 0x02, 0x80, 0x13, 0x3C, 0x41, 0xB0, 0x02, 0x3C, -0x60, 0x1B, 0x63, 0x26, 0x04, 0x00, 0x42, 0x34, 0x00, 0x00, 0x45, 0x8C, -0xD4, 0x1B, 0x64, 0x8C, 0xD0, 0x1B, 0x66, 0x8C, 0x02, 0x80, 0x02, 0x3C, -0xF0, 0x5C, 0x47, 0x90, 0x25, 0xB0, 0x08, 0x3C, 0xB0, 0x03, 0x02, 0x35, -0x25, 0x90, 0x85, 0x00, 0x00, 0x00, 0x52, 0xAC, 0x00, 0x00, 0x46, 0xAC, -0x01, 0x00, 0x02, 0x24, 0x89, 0x03, 0xE2, 0x10, 0xD4, 0x1B, 0x72, 0xAC, -0x60, 0x1B, 0x64, 0x26, 0xD0, 0x1B, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x24, 0x10, 0x52, 0x00, 0x01, 0x00, 0x42, 0x30, 0x0E, 0x00, 0x40, 0x10, -0x60, 0x1B, 0x67, 0x26, 0x25, 0xB0, 0x10, 0x3C, 0xB0, 0x03, 0x02, 0x36, -0x01, 0x00, 0x05, 0x24, 0x00, 0x00, 0x45, 0xAC, 0x04, 0x00, 0x0B, 0x36, -0xD4, 0x1B, 0x83, 0x8C, 0x00, 0x00, 0x69, 0x8D, 0x40, 0x00, 0x02, 0x3C, -0x01, 0x00, 0x63, 0x38, 0x24, 0x10, 0x22, 0x01, 0x26, 0x01, 0x40, 0x10, -0xD4, 0x1B, 0x83, 0xAC, 0x60, 0x1B, 0x67, 0x26, 0xD0, 0x1B, 0xE2, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x52, 0x00, 0x04, 0x00, 0x42, 0x30, -0x14, 0x00, 0x40, 0x10, 0x60, 0x1B, 0x71, 0x26, 0x25, 0xB0, 0x03, 0x3C, -0xB0, 0x03, 0x64, 0x34, 0x04, 0x00, 0x02, 0x24, 0x00, 0x00, 0x82, 0xAC, -0xD4, 0x1B, 0xE2, 0x8C, 0xC4, 0x38, 0xE6, 0x8C, 0xFC, 0x00, 0x63, 0x34, -0xAC, 0x1B, 0xE4, 0x94, 0x00, 0x00, 0x65, 0x8C, 0x04, 0x00, 0x42, 0x38, -0x21, 0x48, 0xC4, 0x00, 0x06, 0x00, 0xA9, 0x10, 0xD4, 0x1B, 0xE2, 0xAC, -0x02, 0x80, 0x03, 0x3C, 0xB0, 0x5D, 0x62, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0x42, 0x34, 0xB0, 0x5D, 0x62, 0xAC, 0x60, 0x1B, 0x71, 0x26, -0xD0, 0x1B, 0x22, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x52, 0x00, -0x08, 0x00, 0x42, 0x30, 0x0A, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, -0xB0, 0x1B, 0x22, 0x96, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x42, 0x30, -0x5D, 0x03, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, 0xD4, 0x1B, 0x22, 0x8E, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x42, 0x38, 0xD4, 0x1B, 0x22, 0xAE, -0x60, 0x1B, 0x70, 0x26, 0xD0, 0x1B, 0x02, 0x8E, 0x00, 0x00, 0x00, 0x00, -0x24, 0x20, 0x52, 0x00, 0x00, 0x08, 0x83, 0x30, 0x06, 0x00, 0x60, 0x10, -0x00, 0x10, 0x82, 0x30, 0xD4, 0x1B, 0x02, 0x8E, 0x00, 0x00, 0x00, 0x00, -0x00, 0x08, 0x42, 0x38, 0xD4, 0x1B, 0x02, 0xAE, 0x00, 0x10, 0x82, 0x30, -0x05, 0x03, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x70, 0x26, -0xD0, 0x1B, 0x03, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x72, 0x00, -0x00, 0x20, 0x42, 0x30, 0xF7, 0x02, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x24, 0x10, 0x72, 0x00, 0x00, 0x80, 0x42, 0x30, 0xB9, 0x01, 0x40, 0x14, -0x01, 0x00, 0x03, 0x3C, 0x60, 0x1B, 0x70, 0x26, 0xD0, 0x1B, 0x02, 0x8E, -0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x52, 0x00, 0x24, 0x10, 0x54, 0x00, -0x24, 0x10, 0x43, 0x00, 0xF1, 0x01, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0xD0, 0x1B, 0x02, 0x8E, 0x02, 0x00, 0x03, 0x3C, 0x24, 0x10, 0x52, 0x00, -0x24, 0x10, 0x43, 0x00, 0x28, 0x02, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x60, 0x1B, 0x70, 0x26, 0xD0, 0x1B, 0x02, 0x8E, 0x04, 0x00, 0x03, 0x3C, -0x24, 0x10, 0x52, 0x00, 0x24, 0x10, 0x54, 0x00, 0x24, 0x10, 0x43, 0x00, -0x62, 0x02, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x70, 0x26, -0xD0, 0x1B, 0x02, 0x8E, 0x08, 0x00, 0x03, 0x3C, 0x24, 0x10, 0x52, 0x00, -0x24, 0x10, 0x43, 0x00, 0x9B, 0x02, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x60, 0x1B, 0x70, 0x26, 0xD0, 0x1B, 0x02, 0x8E, 0x10, 0x00, 0x03, 0x3C, -0x24, 0x10, 0x52, 0x00, 0x24, 0x10, 0x54, 0x00, 0x24, 0x10, 0x43, 0x00, -0x5A, 0x01, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x70, 0x26, -0xD0, 0x1B, 0x02, 0x8E, 0x20, 0x00, 0x03, 0x3C, 0x24, 0x10, 0x52, 0x00, -0x24, 0x10, 0x43, 0x00, 0x18, 0x01, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x60, 0x1B, 0x70, 0x26, 0xD0, 0x1B, 0x02, 0x8E, 0x40, 0x00, 0x03, 0x3C, -0x24, 0x10, 0x52, 0x00, 0x24, 0x10, 0x54, 0x00, 0x24, 0x10, 0x43, 0x00, -0xD6, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x65, 0x26, -0xD0, 0x1B, 0xA2, 0x8C, 0x00, 0x04, 0x03, 0x3C, 0x24, 0x10, 0x52, 0x00, -0x24, 0x10, 0x43, 0x00, 0x3D, 0x00, 0x40, 0x10, 0x60, 0x1B, 0x66, 0x26, -0x2A, 0xB0, 0x02, 0x3C, 0x2C, 0x00, 0x43, 0x34, 0x00, 0x00, 0x69, 0x8C, -0xFF, 0x00, 0x02, 0x24, 0xFF, 0x00, 0x24, 0x31, 0x29, 0x03, 0x82, 0x10, -0x00, 0x80, 0x22, 0x31, 0xF9, 0x02, 0x40, 0x14, 0x00, 0x80, 0x02, 0x3C, -0x00, 0xFF, 0x02, 0x3C, 0x24, 0x10, 0x22, 0x01, 0x0B, 0x00, 0x40, 0x10, -0xFF, 0x00, 0x02, 0x24, 0xAC, 0x37, 0xA2, 0x90, 0x20, 0xB0, 0x03, 0x3C, -0x00, 0x12, 0x02, 0x00, 0x21, 0x10, 0x43, 0x00, 0x0C, 0x00, 0x49, 0x8C, -0x25, 0xB0, 0x03, 0x3C, 0xB0, 0x03, 0x63, 0x34, 0x00, 0x00, 0x69, 0xAC, -0xFF, 0x00, 0x24, 0x31, 0xFF, 0x00, 0x02, 0x24, 0x1B, 0x00, 0x82, 0x10, -0x60, 0x1B, 0x70, 0x26, 0xFF, 0x00, 0x23, 0x31, 0x7C, 0x38, 0x05, 0x8E, -0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, -0x21, 0x30, 0x60, 0x00, 0x10, 0x38, 0x03, 0xAE, 0x0A, 0x00, 0x04, 0x24, -0xAC, 0x37, 0x09, 0xA2, 0x00, 0x01, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C, -0x10, 0x00, 0xA0, 0xAF, 0xD0, 0x1B, 0x05, 0x8E, 0x02, 0x80, 0x06, 0x3C, -0xB0, 0x5D, 0xC4, 0x8C, 0x00, 0x04, 0x02, 0x3C, 0x27, 0x10, 0x02, 0x00, -0x24, 0x28, 0xA2, 0x00, 0x25, 0xB0, 0x02, 0x3C, 0x00, 0x80, 0x84, 0x34, -0xB0, 0x03, 0x42, 0x34, 0x41, 0xB0, 0x03, 0x3C, 0x00, 0x00, 0x44, 0xAC, -0x00, 0x00, 0x65, 0xAC, 0xB0, 0x5D, 0xC4, 0xAC, 0xD0, 0x1B, 0x05, 0xAE, -0x60, 0x1B, 0x65, 0x26, 0xD4, 0x1B, 0xA4, 0x8C, 0x00, 0x04, 0x03, 0x3C, -0x25, 0xB0, 0x02, 0x3C, 0x26, 0x20, 0x83, 0x00, 0xB0, 0x03, 0x42, 0x34, -0x00, 0x00, 0x44, 0xAC, 0xD4, 0x1B, 0xA4, 0xAC, 0x60, 0x1B, 0x66, 0x26, -0xD0, 0x1B, 0xC7, 0x8C, 0x00, 0x08, 0x04, 0x3C, 0x24, 0x28, 0xF2, 0x00, -0x24, 0x10, 0xA4, 0x00, 0x08, 0x00, 0x40, 0x10, 0x80, 0x00, 0x08, 0x3C, -0xD4, 0x1B, 0xC3, 0x8C, 0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, -0x26, 0x18, 0x64, 0x00, 0x00, 0x00, 0x44, 0xAC, 0xD4, 0x1B, 0xC3, 0xAC, -0x80, 0x00, 0x08, 0x3C, 0x24, 0x10, 0xA8, 0x00, 0x21, 0x00, 0x40, 0x10, -0x00, 0x00, 0x00, 0x00, 0xD4, 0x1B, 0xC3, 0x8C, 0x25, 0xB0, 0x09, 0x3C, -0xB0, 0x03, 0x2A, 0x35, 0x2A, 0xB0, 0x02, 0x3C, 0x00, 0x00, 0x43, 0xAD, -0x36, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0x90, 0x23, 0xB0, 0x04, 0x3C, -0xFF, 0x1F, 0x02, 0x3C, 0xC0, 0x18, 0x03, 0x00, 0xF0, 0x07, 0x63, 0x30, -0xF4, 0x38, 0xC5, 0x8C, 0x21, 0x18, 0x64, 0x00, 0xFF, 0xFF, 0x42, 0x34, -0x24, 0x18, 0x62, 0x00, 0xCE, 0x02, 0x65, 0x10, 0xF8, 0x38, 0xC3, 0xAC, -0x02, 0x80, 0x05, 0x3C, 0xB0, 0x5D, 0xA3, 0x8C, 0x27, 0x20, 0x08, 0x00, -0x24, 0x20, 0xE4, 0x00, 0x00, 0x10, 0x63, 0x34, 0x41, 0xB0, 0x02, 0x3C, -0x00, 0x00, 0x43, 0xAD, 0x00, 0x00, 0x44, 0xAC, 0xB0, 0x5D, 0xA3, 0xAC, -0xD0, 0x1B, 0xC4, 0xAC, 0x60, 0x1B, 0x62, 0x26, 0xD4, 0x1B, 0x43, 0x8C, -0x80, 0x00, 0x04, 0x3C, 0x26, 0x18, 0x64, 0x00, 0xD4, 0x1B, 0x43, 0xAC, -0x60, 0x1B, 0x66, 0x26, 0xD0, 0x1B, 0xC3, 0x8C, 0x00, 0x01, 0x05, 0x3C, -0x24, 0x20, 0x72, 0x00, 0x24, 0x10, 0x85, 0x00, 0x06, 0x00, 0x40, 0x10, -0x25, 0xB0, 0x02, 0x3C, 0xD4, 0x1B, 0xC3, 0x8C, 0xB0, 0x03, 0x42, 0x34, -0x26, 0x18, 0x65, 0x00, 0x00, 0x00, 0x45, 0xAC, 0xD4, 0x1B, 0xC3, 0xAC, -0x00, 0x02, 0x05, 0x3C, 0x24, 0x10, 0x85, 0x00, 0x06, 0x00, 0x40, 0x10, -0x25, 0xB0, 0x02, 0x3C, 0xD4, 0x1B, 0xC3, 0x8C, 0xB0, 0x03, 0x42, 0x34, -0x26, 0x18, 0x65, 0x00, 0x00, 0x00, 0x45, 0xAC, 0xD4, 0x1B, 0xC3, 0xAC, -0x00, 0x10, 0x05, 0x3C, 0x24, 0x10, 0x85, 0x00, 0x0C, 0x00, 0x40, 0x10, -0x60, 0x1B, 0x63, 0x26, 0xB0, 0x1B, 0xC3, 0x94, 0x00, 0x00, 0x00, 0x00, -0x04, 0x00, 0x62, 0x30, 0x02, 0x00, 0x40, 0x10, 0x00, 0x08, 0x62, 0x34, -0xB0, 0x1B, 0xC2, 0xA4, 0xD4, 0x1B, 0xC2, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x26, 0x10, 0x45, 0x00, 0xD4, 0x1B, 0xC2, 0xAC, 0x60, 0x1B, 0x63, 0x26, -0xD0, 0x1B, 0x62, 0x8C, 0x00, 0x20, 0x05, 0x3C, 0x24, 0x10, 0x52, 0x00, -0x24, 0x10, 0x45, 0x00, 0x0B, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, -0xB0, 0x1B, 0x64, 0x94, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x82, 0x30, -0x02, 0x00, 0x40, 0x10, 0xFF, 0xF7, 0x82, 0x30, 0xB0, 0x1B, 0x62, 0xA4, -0xD4, 0x1B, 0x62, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x45, 0x00, -0xD4, 0x1B, 0x62, 0xAC, 0x2C, 0x00, 0xBF, 0x8F, 0x28, 0x00, 0xB4, 0x8F, -0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, -0x20, 0xBD, 0x02, 0x3C, 0xEC, 0x02, 0x03, 0x36, 0x4D, 0x00, 0x07, 0x36, -0xF1, 0x02, 0x08, 0x36, 0x08, 0x00, 0x06, 0x24, 0x78, 0x02, 0x42, 0x34, -0x00, 0x00, 0x45, 0xA4, 0x00, 0x00, 0xE0, 0xA0, 0x00, 0x00, 0x06, 0xA1, -0x00, 0x00, 0x60, 0xAC, 0x00, 0x00, 0x62, 0x8C, 0xFF, 0x00, 0x04, 0x3C, -0x00, 0x00, 0xE0, 0xA0, 0xFF, 0x00, 0x49, 0x30, 0x25, 0x48, 0x24, 0x01, -0x00, 0x00, 0x06, 0xA1, 0xF2, 0x02, 0x05, 0x36, 0x00, 0x00, 0x64, 0xAC, -0x0A, 0x00, 0x0A, 0x36, 0x00, 0x00, 0x69, 0xAC, 0x80, 0xFF, 0x03, 0x24, -0x00, 0x00, 0xA0, 0xA0, 0x00, 0x00, 0x43, 0xA1, 0x00, 0x00, 0x62, 0x8D, -0x80, 0x00, 0x03, 0x3C, 0x24, 0x10, 0x43, 0x00, 0x02, 0x00, 0x40, 0x10, -0x84, 0xFF, 0x02, 0x24, 0x00, 0x00, 0x42, 0xA1, 0x2C, 0x1F, 0x00, 0x0C, -0x01, 0x00, 0x04, 0x24, 0x02, 0x00, 0x02, 0x36, 0x00, 0x00, 0x43, 0x94, -0xFF, 0xBF, 0x04, 0x24, 0x24, 0x18, 0x64, 0x00, 0x00, 0x00, 0x43, 0xA4, -0x25, 0x32, 0x00, 0x08, 0x60, 0x1B, 0x67, 0x26, 0x70, 0x30, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x02, 0x3C, 0x2A, 0xB0, 0x06, 0x3C, -0xB0, 0x03, 0x42, 0x34, 0x00, 0x00, 0x54, 0xAC, 0x28, 0x00, 0xC3, 0x34, -0x00, 0x00, 0x69, 0x8C, 0xFF, 0x00, 0x05, 0x24, 0xFF, 0x00, 0x24, 0x31, -0x6D, 0x03, 0x85, 0x10, 0x25, 0xBD, 0x02, 0x3C, 0x00, 0x80, 0x22, 0x31, -0x59, 0x02, 0x40, 0x10, 0x00, 0xFF, 0x02, 0x3C, 0x00, 0x80, 0x02, 0x3C, -0x00, 0x00, 0x62, 0xAC, 0xFF, 0x00, 0x02, 0x24, 0x21, 0x00, 0x82, 0x10, -0xFF, 0x00, 0x23, 0x31, 0x60, 0x1B, 0x70, 0x26, 0x4C, 0x38, 0x05, 0x8E, -0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, -0x21, 0x30, 0x60, 0x00, 0x98, 0x37, 0x09, 0xA2, 0xE0, 0x37, 0x03, 0xAE, -0x06, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C, -0x10, 0x00, 0xA0, 0xAF, 0x02, 0x80, 0x09, 0x3C, 0xC0, 0x5D, 0x27, 0x91, -0x02, 0x80, 0x08, 0x3C, 0xB0, 0x5D, 0x05, 0x8D, 0xD0, 0x1B, 0x06, 0x8E, -0x60, 0x00, 0x02, 0x3C, 0x02, 0x00, 0xE7, 0x34, 0x27, 0x10, 0x02, 0x00, -0x24, 0x30, 0xC2, 0x00, 0x00, 0x08, 0xA5, 0x34, 0x00, 0x26, 0x07, 0x00, -0x25, 0xB0, 0x02, 0x3C, 0x25, 0x20, 0x85, 0x00, 0x80, 0x03, 0x42, 0x34, -0x41, 0xB0, 0x03, 0x3C, 0x00, 0x00, 0x44, 0xAC, 0x00, 0x00, 0x66, 0xAC, -0xB0, 0x5D, 0x05, 0xAD, 0xC0, 0x5D, 0x27, 0xA1, 0xD0, 0x1B, 0x06, 0xAE, -0x60, 0x1B, 0x62, 0x26, 0xD4, 0x1B, 0x43, 0x8C, 0x40, 0x00, 0x04, 0x3C, -0x26, 0x18, 0x64, 0x00, 0x9A, 0x32, 0x00, 0x08, 0xD4, 0x1B, 0x43, 0xAC, -0x70, 0x30, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xB0, 0x05, 0x3C, -0x24, 0x00, 0xA3, 0x34, 0x00, 0x00, 0x69, 0x8C, 0xFF, 0x00, 0x06, 0x24, -0xFF, 0x00, 0x24, 0x31, 0x48, 0x03, 0x86, 0x10, 0x25, 0xB0, 0x02, 0x3C, -0x00, 0x80, 0x22, 0x31, 0x64, 0x02, 0x40, 0x10, 0x00, 0xFF, 0x02, 0x3C, -0x00, 0x80, 0x02, 0x3C, 0x00, 0x00, 0x62, 0xAC, 0xFF, 0x00, 0x02, 0x24, -0x25, 0x00, 0x82, 0x10, 0x60, 0x1B, 0x70, 0x26, 0xFF, 0x00, 0x23, 0x31, -0x4C, 0x38, 0x05, 0x8E, 0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, -0x21, 0x18, 0x62, 0x00, 0x21, 0x30, 0x60, 0x00, 0x94, 0x37, 0x09, 0xA2, -0xE0, 0x37, 0x03, 0xAE, 0x06, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24, -0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, 0x02, 0x80, 0x0A, 0x3C, -0xC0, 0x5D, 0x47, 0x91, 0x02, 0x80, 0x09, 0x3C, 0xB0, 0x5D, 0x25, 0x8D, -0xD0, 0x1B, 0x06, 0x8E, 0x60, 0x00, 0x02, 0x3C, 0x04, 0x00, 0xE7, 0x34, -0x27, 0x10, 0x02, 0x00, 0x24, 0x30, 0xC2, 0x00, 0x00, 0x08, 0xA5, 0x34, -0x25, 0xB0, 0x03, 0x3C, 0x40, 0x00, 0x02, 0x3C, 0x00, 0x26, 0x07, 0x00, -0x26, 0xA0, 0x82, 0x02, 0xB0, 0x03, 0x68, 0x34, 0x25, 0x20, 0x85, 0x00, -0x80, 0x03, 0x63, 0x34, 0x41, 0xB0, 0x02, 0x3C, 0x00, 0x00, 0x64, 0xAC, -0x00, 0x00, 0x46, 0xAC, 0xB0, 0x5D, 0x25, 0xAD, 0xC0, 0x5D, 0x47, 0xA1, -0xD0, 0x1B, 0x06, 0xAE, 0x00, 0x00, 0x14, 0xAD, 0x60, 0x1B, 0x62, 0x26, -0xD4, 0x1B, 0x43, 0x8C, 0x20, 0x00, 0x04, 0x3C, 0x26, 0x18, 0x64, 0x00, -0x92, 0x32, 0x00, 0x08, 0xD4, 0x1B, 0x43, 0xAC, 0x70, 0x30, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x05, 0x3C, 0xB0, 0x03, 0xA2, 0x34, -0x2A, 0xB0, 0x07, 0x3C, 0x00, 0x00, 0x54, 0xAC, 0x20, 0x00, 0xE3, 0x34, -0x00, 0x00, 0x69, 0x8C, 0xFF, 0x00, 0x06, 0x24, 0xFF, 0x00, 0x24, 0x31, -0x07, 0x03, 0x86, 0x10, 0x90, 0x03, 0xA2, 0x34, 0x00, 0x80, 0x22, 0x31, -0x05, 0x02, 0x40, 0x10, 0x00, 0xFF, 0x02, 0x3C, 0x00, 0x80, 0x02, 0x3C, -0x00, 0x00, 0x62, 0xAC, 0xFF, 0x00, 0x02, 0x24, 0x21, 0x00, 0x82, 0x10, -0x60, 0x1B, 0x70, 0x26, 0xFF, 0x00, 0x23, 0x31, 0x40, 0x38, 0x05, 0x8E, -0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, -0x21, 0x30, 0x60, 0x00, 0x9C, 0x37, 0x09, 0xA2, 0xD4, 0x37, 0x03, 0xAE, -0x05, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C, -0x10, 0x00, 0xA0, 0xAF, 0x02, 0x80, 0x09, 0x3C, 0xC0, 0x5D, 0x27, 0x91, -0x02, 0x80, 0x08, 0x3C, 0xB0, 0x5D, 0x05, 0x8D, 0xD0, 0x1B, 0x06, 0x8E, -0x18, 0x00, 0x02, 0x3C, 0x01, 0x00, 0xE7, 0x34, 0x27, 0x10, 0x02, 0x00, -0x24, 0x30, 0xC2, 0x00, 0x00, 0x04, 0xA5, 0x34, 0x00, 0x26, 0x07, 0x00, -0x25, 0xB0, 0x02, 0x3C, 0x25, 0x20, 0x85, 0x00, 0x80, 0x03, 0x42, 0x34, -0x41, 0xB0, 0x03, 0x3C, 0x00, 0x00, 0x44, 0xAC, 0x00, 0x00, 0x66, 0xAC, -0xB0, 0x5D, 0x05, 0xAD, 0xC0, 0x5D, 0x27, 0xA1, 0xD0, 0x1B, 0x06, 0xAE, -0x60, 0x1B, 0x62, 0x26, 0xD4, 0x1B, 0x43, 0x8C, 0x10, 0x00, 0x04, 0x3C, -0x26, 0x18, 0x64, 0x00, 0x8B, 0x32, 0x00, 0x08, 0xD4, 0x1B, 0x43, 0xAC, -0x70, 0x30, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xB0, 0x05, 0x3C, -0x0C, 0x00, 0xA3, 0x34, 0x00, 0x00, 0x69, 0x8C, 0xFF, 0x00, 0x06, 0x24, -0xFF, 0x00, 0x24, 0x31, 0xC6, 0x02, 0x86, 0x10, 0x00, 0x80, 0x22, 0x31, -0x54, 0x02, 0x40, 0x10, 0x00, 0xFF, 0x02, 0x3C, 0x00, 0x80, 0x02, 0x3C, -0x00, 0x00, 0x62, 0xAC, 0xFF, 0x00, 0x02, 0x24, 0x24, 0x00, 0x82, 0x10, -0x60, 0x1B, 0x70, 0x26, 0xFF, 0x00, 0x23, 0x31, 0x28, 0x38, 0x05, 0x8E, -0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, -0x21, 0x30, 0x60, 0x00, 0x80, 0x37, 0x09, 0xA2, 0xBC, 0x37, 0x03, 0xAE, -0x03, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C, -0x10, 0x00, 0xA0, 0xAF, 0x02, 0x80, 0x0A, 0x3C, 0xC0, 0x5D, 0x47, 0x91, -0x02, 0x80, 0x09, 0x3C, 0xB0, 0x5D, 0x25, 0x8D, 0xD0, 0x1B, 0x06, 0x8E, -0x01, 0x00, 0x08, 0x3C, 0x80, 0xFF, 0x02, 0x24, 0x25, 0x38, 0xE2, 0x00, -0x00, 0x80, 0x03, 0x35, 0x00, 0x01, 0xA5, 0x34, 0x27, 0x18, 0x03, 0x00, -0x00, 0x26, 0x07, 0x00, 0x25, 0xB0, 0x02, 0x3C, 0x24, 0x30, 0xC3, 0x00, -0x25, 0x20, 0x85, 0x00, 0x80, 0x03, 0x42, 0x34, 0x41, 0xB0, 0x03, 0x3C, -0x00, 0x00, 0x44, 0xAC, 0x27, 0xA0, 0x08, 0x00, 0x00, 0x00, 0x66, 0xAC, -0xB0, 0x5D, 0x25, 0xAD, 0xC0, 0x5D, 0x47, 0xA1, 0xD0, 0x1B, 0x06, 0xAE, -0x60, 0x1B, 0x63, 0x26, 0xD4, 0x1B, 0x62, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x80, 0x42, 0x38, 0xD4, 0x1B, 0x62, 0xAC, 0x60, 0x1B, 0x70, 0x26, -0xD0, 0x1B, 0x02, 0x8E, 0x01, 0x00, 0x03, 0x3C, 0x24, 0x10, 0x52, 0x00, -0x24, 0x10, 0x54, 0x00, 0x24, 0x10, 0x43, 0x00, 0x11, 0xFE, 0x40, 0x10, -0x00, 0x00, 0x00, 0x00, 0x70, 0x30, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x2A, 0xB0, 0x05, 0x3C, 0x10, 0x00, 0xA3, 0x34, 0x00, 0x00, 0x69, 0x8C, -0xFF, 0x00, 0x06, 0x24, 0xFF, 0x00, 0x24, 0x31, 0x7C, 0x02, 0x86, 0x10, -0x25, 0xB0, 0x02, 0x3C, 0x00, 0x80, 0x22, 0x31, 0xD0, 0x01, 0x40, 0x10, -0x00, 0x80, 0x02, 0x3C, 0x00, 0x00, 0x62, 0xAC, 0xFF, 0x00, 0x02, 0x24, -0x22, 0x00, 0x82, 0x10, 0x60, 0x1B, 0x70, 0x26, 0xFF, 0x00, 0x23, 0x31, -0x28, 0x38, 0x05, 0x8E, 0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, -0x21, 0x18, 0x62, 0x00, 0x21, 0x30, 0x60, 0x00, 0x84, 0x37, 0x09, 0xA2, -0xBC, 0x37, 0x03, 0xAE, 0x03, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24, -0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, 0x02, 0x80, 0x09, 0x3C, -0xC0, 0x5D, 0x27, 0x91, 0x02, 0x80, 0x08, 0x3C, 0xB0, 0x5D, 0x05, 0x8D, -0xD0, 0x1B, 0x06, 0x8E, 0x01, 0x00, 0x02, 0x3C, 0x00, 0x80, 0x42, 0x34, -0x40, 0x00, 0xE7, 0x34, 0x27, 0x10, 0x02, 0x00, 0x24, 0x30, 0xC2, 0x00, -0x00, 0x01, 0xA5, 0x34, 0x00, 0x26, 0x07, 0x00, 0x25, 0xB0, 0x02, 0x3C, -0x25, 0x20, 0x85, 0x00, 0x80, 0x03, 0x42, 0x34, 0x41, 0xB0, 0x03, 0x3C, -0x00, 0x00, 0x44, 0xAC, 0x00, 0x00, 0x66, 0xAC, 0xB0, 0x5D, 0x05, 0xAD, -0xC0, 0x5D, 0x27, 0xA1, 0xD0, 0x1B, 0x06, 0xAE, 0x60, 0x1B, 0x62, 0x26, -0xD4, 0x1B, 0x43, 0x8C, 0x01, 0x00, 0x04, 0x3C, 0x60, 0x1B, 0x70, 0x26, -0x26, 0x18, 0x64, 0x00, 0xD4, 0x1B, 0x43, 0xAC, 0xD0, 0x1B, 0x02, 0x8E, -0x02, 0x00, 0x03, 0x3C, 0x24, 0x10, 0x52, 0x00, 0x24, 0x10, 0x43, 0x00, -0xDB, 0xFD, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x70, 0x30, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x2A, 0xB0, 0x05, 0x3C, 0x14, 0x00, 0xA3, 0x34, -0x00, 0x00, 0x69, 0x8C, 0xFF, 0x00, 0x06, 0x24, 0xFF, 0x00, 0x24, 0x31, -0x64, 0x02, 0x86, 0x10, 0x25, 0xB0, 0x02, 0x3C, 0x00, 0x80, 0x22, 0x31, -0xFA, 0x01, 0x40, 0x10, 0x00, 0xFF, 0x02, 0x3C, 0x00, 0x80, 0x02, 0x3C, -0x00, 0x00, 0x62, 0xAC, 0xFF, 0x00, 0x02, 0x24, 0x25, 0x00, 0x82, 0x10, -0x60, 0x1B, 0x70, 0x26, 0xFF, 0x00, 0x23, 0x31, 0x34, 0x38, 0x05, 0x8E, -0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, -0x21, 0x30, 0x60, 0x00, 0x88, 0x37, 0x09, 0xA2, 0xC8, 0x37, 0x03, 0xAE, -0x04, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C, -0x10, 0x00, 0xA0, 0xAF, 0x02, 0x80, 0x0A, 0x3C, 0xC0, 0x5D, 0x47, 0x91, -0x02, 0x80, 0x09, 0x3C, 0xB0, 0x5D, 0x25, 0x8D, 0xD0, 0x1B, 0x06, 0x8E, -0x06, 0x00, 0x02, 0x3C, 0x20, 0x00, 0xE7, 0x34, 0x27, 0x10, 0x02, 0x00, -0x24, 0x30, 0xC2, 0x00, 0x00, 0x02, 0xA5, 0x34, 0x25, 0xB0, 0x03, 0x3C, -0x04, 0x00, 0x02, 0x3C, 0x00, 0x26, 0x07, 0x00, 0x26, 0xA0, 0x82, 0x02, -0xB0, 0x03, 0x68, 0x34, 0x25, 0x20, 0x85, 0x00, 0x80, 0x03, 0x63, 0x34, -0x41, 0xB0, 0x02, 0x3C, 0x00, 0x00, 0x64, 0xAC, 0x00, 0x00, 0x46, 0xAC, -0xB0, 0x5D, 0x25, 0xAD, 0xC0, 0x5D, 0x47, 0xA1, 0xD0, 0x1B, 0x06, 0xAE, -0x00, 0x00, 0x14, 0xAD, 0x60, 0x1B, 0x62, 0x26, 0xD4, 0x1B, 0x43, 0x8C, -0x02, 0x00, 0x04, 0x3C, 0x60, 0x1B, 0x70, 0x26, 0x26, 0x18, 0x64, 0x00, -0xD4, 0x1B, 0x43, 0xAC, 0xD0, 0x1B, 0x02, 0x8E, 0x04, 0x00, 0x03, 0x3C, -0x24, 0x10, 0x52, 0x00, 0x24, 0x10, 0x54, 0x00, 0x24, 0x10, 0x43, 0x00, -0xA1, 0xFD, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x70, 0x30, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x03, 0x3C, 0xB0, 0x03, 0x62, 0x34, -0x2A, 0xB0, 0x07, 0x3C, 0x00, 0x00, 0x54, 0xAC, 0x18, 0x00, 0xE5, 0x34, -0x00, 0x00, 0xA9, 0x8C, 0xFF, 0x00, 0x06, 0x24, 0xFF, 0x00, 0x24, 0x31, -0x16, 0x02, 0x86, 0x10, 0x04, 0x00, 0x02, 0x24, 0x00, 0x80, 0x22, 0x31, -0xD6, 0x01, 0x40, 0x10, 0x00, 0xFF, 0x02, 0x3C, 0x00, 0x80, 0x02, 0x3C, -0x00, 0x00, 0xA2, 0xAC, 0xFF, 0x00, 0x02, 0x24, 0x21, 0x00, 0x82, 0x10, -0x60, 0x1B, 0x70, 0x26, 0xFF, 0x00, 0x23, 0x31, 0x34, 0x38, 0x05, 0x8E, -0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, -0x21, 0x30, 0x60, 0x00, 0x8C, 0x37, 0x09, 0xA2, 0xC8, 0x37, 0x03, 0xAE, -0x04, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C, -0x10, 0x00, 0xA0, 0xAF, 0x02, 0x80, 0x09, 0x3C, 0xC0, 0x5D, 0x27, 0x91, -0x02, 0x80, 0x08, 0x3C, 0xB0, 0x5D, 0x05, 0x8D, 0xD0, 0x1B, 0x06, 0x8E, -0x06, 0x00, 0x02, 0x3C, 0x10, 0x00, 0xE7, 0x34, 0x27, 0x10, 0x02, 0x00, -0x24, 0x30, 0xC2, 0x00, 0x00, 0x02, 0xA5, 0x34, 0x00, 0x26, 0x07, 0x00, -0x25, 0xB0, 0x02, 0x3C, 0x25, 0x20, 0x85, 0x00, 0x80, 0x03, 0x42, 0x34, -0x41, 0xB0, 0x03, 0x3C, 0x00, 0x00, 0x44, 0xAC, 0x00, 0x00, 0x66, 0xAC, -0xB0, 0x5D, 0x05, 0xAD, 0xC0, 0x5D, 0x27, 0xA1, 0xD0, 0x1B, 0x06, 0xAE, -0x60, 0x1B, 0x62, 0x26, 0xD4, 0x1B, 0x43, 0x8C, 0x04, 0x00, 0x04, 0x3C, -0x60, 0x1B, 0x70, 0x26, 0x26, 0x18, 0x64, 0x00, 0xD4, 0x1B, 0x43, 0xAC, -0xD0, 0x1B, 0x02, 0x8E, 0x08, 0x00, 0x03, 0x3C, 0x24, 0x10, 0x52, 0x00, -0x24, 0x10, 0x43, 0x00, 0x68, 0xFD, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, -0x70, 0x30, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xB0, 0x05, 0x3C, -0x1C, 0x00, 0xA3, 0x34, 0x00, 0x00, 0x69, 0x8C, 0xFF, 0x00, 0x06, 0x24, -0xFF, 0x00, 0x24, 0x31, 0xDD, 0x01, 0x86, 0x10, 0x25, 0xB0, 0x02, 0x3C, -0x00, 0x80, 0x22, 0x31, 0x33, 0x01, 0x40, 0x10, 0x00, 0xFF, 0x02, 0x3C, -0x00, 0x80, 0x02, 0x3C, 0x00, 0x00, 0x62, 0xAC, 0xFF, 0x00, 0x02, 0x24, -0x25, 0x00, 0x82, 0x10, 0x60, 0x1B, 0x70, 0x26, 0xFF, 0x00, 0x23, 0x31, -0x40, 0x38, 0x05, 0x8E, 0x20, 0x10, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, -0x21, 0x18, 0x62, 0x00, 0x21, 0x30, 0x60, 0x00, 0x90, 0x37, 0x09, 0xA2, -0xD4, 0x37, 0x03, 0xAE, 0x05, 0x00, 0x04, 0x24, 0x80, 0x00, 0x07, 0x24, -0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, 0x02, 0x80, 0x0A, 0x3C, -0xC0, 0x5D, 0x47, 0x91, 0x02, 0x80, 0x09, 0x3C, 0xB0, 0x5D, 0x25, 0x8D, -0xD0, 0x1B, 0x06, 0x8E, 0x18, 0x00, 0x02, 0x3C, 0x08, 0x00, 0xE7, 0x34, -0x27, 0x10, 0x02, 0x00, 0x24, 0x30, 0xC2, 0x00, 0x00, 0x04, 0xA5, 0x34, -0x25, 0xB0, 0x03, 0x3C, 0x10, 0x00, 0x02, 0x3C, 0x00, 0x26, 0x07, 0x00, -0x26, 0xA0, 0x82, 0x02, 0xB0, 0x03, 0x68, 0x34, 0x25, 0x20, 0x85, 0x00, -0x80, 0x03, 0x63, 0x34, 0x41, 0xB0, 0x02, 0x3C, 0x00, 0x00, 0x64, 0xAC, -0x00, 0x00, 0x46, 0xAC, 0xB0, 0x5D, 0x25, 0xAD, 0xC0, 0x5D, 0x47, 0xA1, -0xD0, 0x1B, 0x06, 0xAE, 0x00, 0x00, 0x14, 0xAD, 0x60, 0x1B, 0x62, 0x26, -0xD4, 0x1B, 0x43, 0x8C, 0x08, 0x00, 0x04, 0x3C, 0x26, 0x18, 0x64, 0x00, -0x83, 0x32, 0x00, 0x08, 0xD4, 0x1B, 0x43, 0xAC, 0x70, 0x30, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0xD4, 0x1B, 0x02, 0x8E, 0xD0, 0x1B, 0x03, 0x8E, -0x00, 0x20, 0x42, 0x38, 0x62, 0x32, 0x00, 0x08, 0xD4, 0x1B, 0x02, 0xAE, -0x70, 0x30, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xB0, 0x02, 0x3C, -0x08, 0x00, 0x43, 0x34, 0x00, 0x00, 0x69, 0x8C, 0xFF, 0x00, 0x02, 0x24, -0xFF, 0x00, 0x24, 0x31, 0x2C, 0x00, 0x82, 0x10, 0x00, 0x80, 0x22, 0x31, -0x34, 0x01, 0x40, 0x14, 0x00, 0x80, 0x02, 0x3C, 0x00, 0xFF, 0x02, 0x3C, -0x24, 0x10, 0x22, 0x01, 0x0B, 0x00, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24, -0xA8, 0x37, 0x02, 0x92, 0x20, 0xB0, 0x03, 0x3C, 0x00, 0x12, 0x02, 0x00, -0x21, 0x10, 0x43, 0x00, 0x0C, 0x00, 0x49, 0x8C, 0x25, 0xB0, 0x03, 0x3C, -0xB0, 0x03, 0x63, 0x34, 0x00, 0x00, 0x69, 0xAC, 0xFF, 0x00, 0x24, 0x31, -0xFF, 0x00, 0x02, 0x24, 0x1A, 0x00, 0x82, 0x10, 0x60, 0x1B, 0x70, 0x26, -0xFF, 0x00, 0x23, 0x31, 0x70, 0x38, 0x05, 0x8E, 0x20, 0x10, 0x02, 0x3C, -0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, 0x21, 0x30, 0x60, 0x00, -0x04, 0x38, 0x03, 0xAE, 0x01, 0x00, 0x04, 0x24, 0xA8, 0x37, 0x09, 0xA2, -0x80, 0x00, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA0, 0xAF, -0xD0, 0x1B, 0x05, 0x8E, 0x02, 0x80, 0x06, 0x3C, 0xB0, 0x5D, 0xC4, 0x8C, -0xFF, 0xC7, 0x02, 0x24, 0x24, 0x28, 0xA2, 0x00, 0x25, 0xB0, 0x02, 0x3C, -0x10, 0x00, 0x84, 0x34, 0x80, 0x03, 0x42, 0x34, 0x41, 0xB0, 0x03, 0x3C, -0x00, 0x00, 0x44, 0xAC, 0x00, 0x00, 0x65, 0xAC, 0xB0, 0x5D, 0xC4, 0xAC, -0xD0, 0x1B, 0x05, 0xAE, 0x60, 0x1B, 0x63, 0x26, 0xD4, 0x1B, 0x62, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x42, 0x38, 0x5B, 0x32, 0x00, 0x08, -0xD4, 0x1B, 0x62, 0xAC, 0x56, 0x01, 0x02, 0x35, 0x00, 0x00, 0x43, 0x94, -0x00, 0x00, 0x00, 0x00, 0x74, 0xFC, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, -0x7E, 0x58, 0x00, 0x0C, 0x07, 0x00, 0x04, 0x24, 0x12, 0x32, 0x00, 0x08, -0x60, 0x1B, 0x64, 0x26, 0x00, 0x00, 0x62, 0xAC, 0xB8, 0x32, 0x00, 0x08, -0xFF, 0x00, 0x02, 0x24, 0xE4, 0x1D, 0x24, 0x96, 0x58, 0x38, 0x26, 0x96, -0x01, 0x00, 0x84, 0x24, 0x00, 0x19, 0x04, 0x00, 0x25, 0x30, 0xC2, 0x00, -0xF0, 0xFF, 0x63, 0x30, 0x20, 0x00, 0xC5, 0x24, 0x02, 0x12, 0x03, 0x00, -0xE4, 0x1D, 0x24, 0xA6, 0x17, 0x00, 0xA2, 0xA0, 0x16, 0x00, 0xA3, 0xA0, -0x0C, 0x00, 0xC4, 0x8C, 0x00, 0xF0, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, -0xFF, 0x0F, 0x63, 0x30, 0x00, 0x1C, 0x03, 0x00, 0x24, 0x20, 0x82, 0x00, -0x25, 0x20, 0x83, 0x00, 0x0C, 0x00, 0xC4, 0xAC, 0x58, 0x38, 0x25, 0x8E, -0x01, 0x00, 0x10, 0x24, 0x01, 0x00, 0x04, 0x24, 0x31, 0x10, 0x06, 0x3C, -0x00, 0x01, 0x07, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xB0, 0xAF, -0x5B, 0x01, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24, 0x2A, 0xB0, 0x02, 0x3C, -0x01, 0x00, 0x42, 0x34, 0x02, 0x00, 0x03, 0x24, 0x00, 0x00, 0x50, 0xA0, -0x00, 0x00, 0x43, 0xA0, 0xD4, 0x1B, 0x22, 0x8E, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0x42, 0x38, 0x4D, 0x32, 0x00, 0x08, 0xD4, 0x1B, 0x22, 0xAE, -0xD0, 0x03, 0x23, 0x35, 0x80, 0x00, 0x02, 0x24, 0x00, 0x00, 0x62, 0xAC, -0x09, 0x33, 0x00, 0x08, 0x60, 0x1B, 0x62, 0x26, 0x25, 0xB0, 0x02, 0x3C, -0x01, 0x00, 0x03, 0x24, 0x90, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, -0xD5, 0x32, 0x00, 0x08, 0x60, 0x1B, 0x65, 0x26, 0x24, 0x10, 0x22, 0x01, -0xA9, 0xFD, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24, 0x47, 0x00, 0xC6, 0x34, -0x00, 0x00, 0xC2, 0x90, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x44, 0x30, -0x0E, 0x00, 0x85, 0x10, 0x60, 0x1B, 0x62, 0x26, 0x98, 0x37, 0x04, 0xA2, -0x00, 0x00, 0xC2, 0x90, 0xFF, 0x00, 0x83, 0x30, 0xFF, 0x00, 0x44, 0x30, -0x07, 0x00, 0x83, 0x10, 0x21, 0x38, 0x00, 0x02, 0x21, 0x28, 0xC0, 0x00, -0x00, 0x00, 0xA2, 0x90, 0x21, 0x18, 0x80, 0x00, 0xFD, 0xFF, 0x62, 0x14, -0xFF, 0x00, 0x44, 0x30, 0x98, 0x37, 0xE3, 0xA0, 0x60, 0x1B, 0x62, 0x26, -0x98, 0x37, 0x43, 0x90, 0x20, 0xB0, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, -0x21, 0x18, 0x62, 0x00, 0x0C, 0x00, 0x69, 0x8C, 0x25, 0xB0, 0x02, 0x3C, -0xB0, 0x03, 0x42, 0x34, 0xFF, 0x00, 0x24, 0x31, 0x00, 0x00, 0x49, 0xAC, -0x81, 0x33, 0x00, 0x08, 0xFF, 0x00, 0x02, 0x24, 0x24, 0x10, 0x22, 0x01, -0xFD, 0xFD, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24, 0x45, 0x00, 0xE5, 0x34, -0x00, 0x00, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x44, 0x30, -0x0E, 0x00, 0x86, 0x10, 0x60, 0x1B, 0x62, 0x26, 0x9C, 0x37, 0x04, 0xA2, -0x00, 0x00, 0xA2, 0x90, 0xFF, 0x00, 0x83, 0x30, 0xFF, 0x00, 0x44, 0x30, -0x08, 0x00, 0x83, 0x10, 0x60, 0x1B, 0x62, 0x26, 0x21, 0x30, 0x00, 0x02, -0x00, 0x00, 0xA2, 0x90, 0x21, 0x18, 0x80, 0x00, 0xFD, 0xFF, 0x62, 0x14, -0xFF, 0x00, 0x44, 0x30, 0x9C, 0x37, 0xC3, 0xA0, 0x60, 0x1B, 0x62, 0x26, -0x9C, 0x37, 0x43, 0x90, 0x20, 0xB0, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, -0x21, 0x18, 0x62, 0x00, 0x0C, 0x00, 0x69, 0x8C, 0x25, 0xB0, 0x02, 0x3C, -0xB0, 0x03, 0x42, 0x34, 0xFF, 0x00, 0x24, 0x31, 0x00, 0x00, 0x49, 0xAC, -0xF6, 0x33, 0x00, 0x08, 0xFF, 0x00, 0x02, 0x24, 0x24, 0x10, 0x22, 0x01, -0x9E, 0xFD, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24, 0x46, 0x00, 0xA5, 0x34, -0x00, 0x00, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x44, 0x30, -0x0E, 0x00, 0x86, 0x10, 0x60, 0x1B, 0x62, 0x26, 0x94, 0x37, 0x04, 0xA2, -0x00, 0x00, 0xA2, 0x90, 0xFF, 0x00, 0x83, 0x30, 0xFF, 0x00, 0x44, 0x30, -0x08, 0x00, 0x83, 0x10, 0x60, 0x1B, 0x62, 0x26, 0x21, 0x30, 0x00, 0x02, -0x00, 0x00, 0xA2, 0x90, 0x21, 0x18, 0x80, 0x00, 0xFD, 0xFF, 0x62, 0x14, -0xFF, 0x00, 0x44, 0x30, 0x94, 0x37, 0xC3, 0xA0, 0x60, 0x1B, 0x62, 0x26, -0x94, 0x37, 0x43, 0x90, 0x20, 0xB0, 0x02, 0x3C, 0x00, 0x1A, 0x03, 0x00, -0x21, 0x18, 0x62, 0x00, 0x0C, 0x00, 0x69, 0x8C, 0x25, 0xB0, 0x02, 0x3C, -0xB0, 0x03, 0x42, 0x34, 0xFF, 0x00, 0x24, 0x31, 0x00, 0x00, 0x49, 0xAC, -0xB8, 0x33, 0x00, 0x08, 0xFF, 0x00, 0x02, 0x24, 0x00, 0xFF, 0x02, 0x3C, -0x24, 0x10, 0x22, 0x01, 0x30, 0xFE, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24, -0x41, 0x00, 0xA5, 0x34, 0x00, 0x00, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00, -0xFF, 0x00, 0x44, 0x30, 0x0E, 0x00, 0x86, 0x10, 0x60, 0x1B, 0x62, 0x26, -0x84, 0x37, 0x04, 0xA2, 0x00, 0x00, 0xA2, 0x90, 0xFF, 0x00, 0x83, 0x30, -0xFF, 0x00, 0x44, 0x30, 0x08, 0x00, 0x83, 0x10, 0x60, 0x1B, 0x62, 0x26, -0x21, 0x30, 0x00, 0x02, 0x00, 0x00, 0xA2, 0x90, 0x21, 0x18, 0x80, 0x00, -0xFD, 0xFF, 0x62, 0x14, 0xFF, 0x00, 0x44, 0x30, 0x84, 0x37, 0xC3, 0xA0, -0x60, 0x1B, 0x62, 0x26, 0x84, 0x37, 0x43, 0x90, 0x20, 0xB0, 0x02, 0x3C, -0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, 0x0C, 0x00, 0x69, 0x8C, -0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, 0xFF, 0x00, 0x24, 0x31, -0x00, 0x00, 0x49, 0xAC, 0x6C, 0x34, 0x00, 0x08, 0xFF, 0x00, 0x02, 0x24, -0x24, 0x10, 0x22, 0x01, 0xCF, 0xFE, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24, -0x44, 0x00, 0xA5, 0x34, 0x00, 0x00, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00, -0xFF, 0x00, 0x44, 0x30, 0x0E, 0x00, 0x86, 0x10, 0x60, 0x1B, 0x62, 0x26, -0x90, 0x37, 0x04, 0xA2, 0x00, 0x00, 0xA2, 0x90, 0xFF, 0x00, 0x83, 0x30, -0xFF, 0x00, 0x44, 0x30, 0x08, 0x00, 0x83, 0x10, 0x60, 0x1B, 0x62, 0x26, -0x21, 0x30, 0x00, 0x02, 0x00, 0x00, 0xA2, 0x90, 0x21, 0x18, 0x80, 0x00, -0xFD, 0xFF, 0x62, 0x14, 0xFF, 0x00, 0x44, 0x30, 0x90, 0x37, 0xC3, 0xA0, -0x60, 0x1B, 0x62, 0x26, 0x90, 0x37, 0x43, 0x90, 0x20, 0xB0, 0x02, 0x3C, -0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, 0x0C, 0x00, 0x69, 0x8C, -0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, 0xFF, 0x00, 0x24, 0x31, -0x00, 0x00, 0x49, 0xAC, 0x2C, 0x35, 0x00, 0x08, 0xFF, 0x00, 0x02, 0x24, -0x24, 0x10, 0x22, 0x01, 0xAE, 0xFD, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24, -0x40, 0x00, 0xA5, 0x34, 0x00, 0x00, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00, -0xFF, 0x00, 0x44, 0x30, 0x0E, 0x00, 0x86, 0x10, 0x60, 0x1B, 0x62, 0x26, -0x80, 0x37, 0x04, 0xA2, 0x00, 0x00, 0xA2, 0x90, 0xFF, 0x00, 0x83, 0x30, -0xFF, 0x00, 0x44, 0x30, 0x08, 0x00, 0x83, 0x10, 0x60, 0x1B, 0x62, 0x26, -0x21, 0x30, 0x00, 0x02, 0x00, 0x00, 0xA2, 0x90, 0x21, 0x18, 0x80, 0x00, -0xFD, 0xFF, 0x62, 0x14, 0xFF, 0x00, 0x44, 0x30, 0x80, 0x37, 0xC3, 0xA0, -0x60, 0x1B, 0x62, 0x26, 0x80, 0x37, 0x43, 0x90, 0x20, 0xB0, 0x02, 0x3C, -0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, 0x0C, 0x00, 0x69, 0x8C, -0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, 0xFF, 0x00, 0x24, 0x31, -0x00, 0x00, 0x49, 0xAC, 0x2C, 0x34, 0x00, 0x08, 0xFF, 0x00, 0x02, 0x24, -0x00, 0x00, 0x62, 0xAC, 0x78, 0x35, 0x00, 0x08, 0xFF, 0x00, 0x02, 0x24, -0x24, 0x10, 0x22, 0x01, 0x08, 0xFE, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24, -0x42, 0x00, 0xA5, 0x34, 0x00, 0x00, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00, -0xFF, 0x00, 0x44, 0x30, 0x0E, 0x00, 0x86, 0x10, 0x60, 0x1B, 0x62, 0x26, -0x88, 0x37, 0x04, 0xA2, 0x00, 0x00, 0xA2, 0x90, 0xFF, 0x00, 0x83, 0x30, -0xFF, 0x00, 0x44, 0x30, 0x08, 0x00, 0x83, 0x10, 0x60, 0x1B, 0x62, 0x26, -0x21, 0x30, 0x00, 0x02, 0x00, 0x00, 0xA2, 0x90, 0x21, 0x18, 0x80, 0x00, -0xFD, 0xFF, 0x62, 0x14, 0xFF, 0x00, 0x44, 0x30, 0x88, 0x37, 0xC3, 0xA0, -0x60, 0x1B, 0x62, 0x26, 0x88, 0x37, 0x43, 0x90, 0x20, 0xB0, 0x02, 0x3C, -0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, 0x0C, 0x00, 0x69, 0x8C, -0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, 0xFF, 0x00, 0x24, 0x31, -0x00, 0x00, 0x49, 0xAC, 0xAA, 0x34, 0x00, 0x08, 0xFF, 0x00, 0x02, 0x24, -0x24, 0x10, 0x22, 0x01, 0x2C, 0xFE, 0x40, 0x10, 0xFF, 0x00, 0x02, 0x24, -0x43, 0x00, 0xE5, 0x34, 0x00, 0x00, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00, -0xFF, 0x00, 0x44, 0x30, 0x0E, 0x00, 0x86, 0x10, 0x60, 0x1B, 0x62, 0x26, -0x8C, 0x37, 0x04, 0xA2, 0x00, 0x00, 0xA2, 0x90, 0xFF, 0x00, 0x83, 0x30, -0xFF, 0x00, 0x44, 0x30, 0x08, 0x00, 0x83, 0x10, 0x60, 0x1B, 0x62, 0x26, -0x21, 0x30, 0x00, 0x02, 0x00, 0x00, 0xA2, 0x90, 0x21, 0x18, 0x80, 0x00, -0xFD, 0xFF, 0x62, 0x14, 0xFF, 0x00, 0x44, 0x30, 0x8C, 0x37, 0xC3, 0xA0, -0x60, 0x1B, 0x62, 0x26, 0x8C, 0x37, 0x43, 0x90, 0x20, 0xB0, 0x02, 0x3C, -0x00, 0x1A, 0x03, 0x00, 0x21, 0x18, 0x62, 0x00, 0x0C, 0x00, 0x69, 0x8C, -0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x03, 0x42, 0x34, 0xFF, 0x00, 0x24, 0x31, -0x00, 0x00, 0x49, 0xAC, 0xEF, 0x34, 0x00, 0x08, 0xFF, 0x00, 0x02, 0x24, -0x06, 0x00, 0x03, 0x24, 0x90, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, -0x90, 0x34, 0x00, 0x08, 0x60, 0x1B, 0x62, 0x26, 0x01, 0x00, 0x03, 0x24, -0x90, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, 0xA4, 0x33, 0x00, 0x08, -0x60, 0x1B, 0x62, 0x26, 0x25, 0xB0, 0x02, 0x3C, 0x07, 0x00, 0x03, 0x24, -0x90, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, 0x60, 0x1B, 0x63, 0x26, -0xD4, 0x1B, 0x62, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x42, 0x38, -0x56, 0x34, 0x00, 0x08, 0xD4, 0x1B, 0x62, 0xAC, 0x00, 0x00, 0x40, 0xAC, -0x19, 0x34, 0x00, 0x08, 0x60, 0x1B, 0x62, 0x26, 0x02, 0x00, 0x03, 0x24, -0x90, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, 0xDF, 0x33, 0x00, 0x08, -0x60, 0x1B, 0x62, 0x26, 0x90, 0x03, 0x63, 0x34, 0x00, 0x00, 0x62, 0xAC, -0x12, 0x35, 0x00, 0x08, 0x60, 0x1B, 0x62, 0x26, 0x03, 0x00, 0x03, 0x24, -0x90, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, 0x53, 0x35, 0x00, 0x08, -0x60, 0x1B, 0x62, 0x26, 0x05, 0x00, 0x03, 0x24, 0x90, 0x03, 0x42, 0x34, -0x00, 0x00, 0x43, 0xAC, 0xD1, 0x34, 0x00, 0x08, 0x60, 0x1B, 0x62, 0x26, -0xE0, 0xFF, 0xBD, 0x27, 0x1C, 0x00, 0xBF, 0xAF, 0x18, 0x00, 0xB2, 0xAF, -0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x25, 0xB0, 0x0C, 0x3C, -0x01, 0x80, 0x02, 0x3C, 0x18, 0x03, 0x83, 0x35, 0x30, 0xDC, 0x42, 0x24, -0x02, 0x80, 0x12, 0x3C, 0x41, 0xB0, 0x0B, 0x3C, 0x00, 0x00, 0x62, 0xAC, -0x60, 0x1B, 0x4A, 0x26, 0x0A, 0x00, 0x62, 0x35, 0x00, 0x00, 0x44, 0x94, -0xDE, 0x1B, 0x43, 0x95, 0xDC, 0x1B, 0x49, 0x95, 0x25, 0x30, 0x64, 0x00, -0xFF, 0xFF, 0xD0, 0x30, 0x24, 0x10, 0x09, 0x02, 0x02, 0x00, 0x42, 0x30, -0xC2, 0x00, 0x40, 0x10, 0xC0, 0x03, 0x83, 0x35, 0x02, 0x00, 0x02, 0x24, -0x00, 0x00, 0x62, 0xAC, 0x02, 0x80, 0x08, 0x3C, 0xB0, 0x5D, 0x04, 0x8D, -0xDC, 0x02, 0x82, 0x35, 0x00, 0x00, 0x47, 0x90, 0xFD, 0xFF, 0x03, 0x24, -0x00, 0x80, 0x02, 0x3C, 0x24, 0x18, 0x23, 0x01, 0x25, 0x20, 0x82, 0x00, -0x02, 0x00, 0xC6, 0x38, 0x08, 0x00, 0x65, 0x35, 0x02, 0x80, 0x02, 0x3C, -0xED, 0x5D, 0x47, 0xA0, 0xB0, 0x5D, 0x04, 0xAD, 0xDE, 0x1B, 0x46, 0xA5, -0x21, 0x48, 0x60, 0x00, 0x00, 0x00, 0xA3, 0xA4, 0xDC, 0x1B, 0x43, 0xA5, -0x24, 0x38, 0x09, 0x02, 0x04, 0x00, 0xE2, 0x30, 0x0A, 0x00, 0x40, 0x10, -0x08, 0x00, 0xE2, 0x30, 0xDE, 0x1B, 0x43, 0x95, 0x0C, 0x00, 0x64, 0x35, -0xC0, 0x03, 0x85, 0x35, 0x04, 0x00, 0x63, 0x38, 0x04, 0x00, 0x02, 0x24, -0x00, 0x00, 0x86, 0x90, 0x00, 0x00, 0xA2, 0xAC, 0xDE, 0x1B, 0x43, 0xA5, -0x08, 0x00, 0xE2, 0x30, 0x08, 0x00, 0x40, 0x10, 0x10, 0x00, 0xE2, 0x30, -0xDE, 0x1B, 0x42, 0x95, 0xC0, 0x03, 0x84, 0x35, 0x08, 0x00, 0x03, 0x24, -0x08, 0x00, 0x42, 0x38, 0x00, 0x00, 0x83, 0xAC, 0xDE, 0x1B, 0x42, 0xA5, -0x10, 0x00, 0xE2, 0x30, 0x08, 0x00, 0x40, 0x10, 0x20, 0x00, 0xE2, 0x30, -0xDE, 0x1B, 0x42, 0x95, 0xC0, 0x03, 0x84, 0x35, 0x10, 0x00, 0x03, 0x24, -0x10, 0x00, 0x42, 0x38, 0x00, 0x00, 0x83, 0xAC, 0xDE, 0x1B, 0x42, 0xA5, -0x20, 0x00, 0xE2, 0x30, 0x08, 0x00, 0x40, 0x10, 0x80, 0x00, 0xE2, 0x30, -0xDE, 0x1B, 0x42, 0x95, 0xC0, 0x03, 0x84, 0x35, 0x20, 0x00, 0x03, 0x24, -0x20, 0x00, 0x42, 0x38, 0x00, 0x00, 0x83, 0xAC, 0xDE, 0x1B, 0x42, 0xA5, -0x80, 0x00, 0xE2, 0x30, 0x74, 0x00, 0x40, 0x10, 0x60, 0x1B, 0x47, 0x26, -0xC0, 0x03, 0x83, 0x35, 0x80, 0x00, 0x02, 0x24, 0x42, 0xB0, 0x0B, 0x3C, -0x00, 0x00, 0x62, 0xAC, 0x03, 0x00, 0x71, 0x35, 0xDE, 0x1B, 0x42, 0x95, -0x00, 0x00, 0x23, 0x92, 0x80, 0x00, 0x42, 0x38, 0x20, 0x00, 0x63, 0x30, -0x59, 0x00, 0x60, 0x10, 0xDE, 0x1B, 0x42, 0xA5, 0x20, 0x00, 0x02, 0x24, -0x00, 0x00, 0x22, 0xA2, 0x02, 0x80, 0x03, 0x3C, 0x0F, 0x5E, 0x62, 0x90, -0x00, 0x00, 0x00, 0x00, 0x75, 0x00, 0x40, 0x14, 0x21, 0x40, 0x00, 0x00, -0xB0, 0x1B, 0x42, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x30, -0x4E, 0x00, 0x40, 0x10, 0x02, 0x80, 0x06, 0x3C, 0x02, 0x80, 0x07, 0x3C, -0xEC, 0x5D, 0xE2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x40, 0x10, -0x02, 0x80, 0x09, 0x3C, 0x02, 0x80, 0x04, 0x3C, 0xF8, 0x5D, 0x82, 0x8C, -0x18, 0x5E, 0x24, 0x8D, 0x1C, 0x5E, 0x25, 0x8D, 0x21, 0x18, 0x00, 0x00, -0x21, 0x10, 0x44, 0x00, 0x2B, 0x30, 0x44, 0x00, 0x21, 0x18, 0x65, 0x00, -0x21, 0x18, 0x66, 0x00, 0x18, 0x5E, 0x22, 0xAD, 0x1C, 0x5E, 0x23, 0xAD, -0xEC, 0x5D, 0xE4, 0x90, 0x02, 0x00, 0x02, 0x24, 0xFF, 0x00, 0x84, 0x30, -0x07, 0x00, 0x82, 0x10, 0x02, 0x80, 0x04, 0x3C, 0xEC, 0x5D, 0xE2, 0x90, -0x03, 0x00, 0x03, 0x24, 0xFF, 0x00, 0x42, 0x30, 0x5A, 0x00, 0x43, 0x14, -0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x04, 0x3C, 0x0A, 0x5E, 0x82, 0x90, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x42, 0x24, 0x0A, 0x5E, 0x82, 0xA0, -0x0A, 0x5E, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x60, 0x10, -0x02, 0x80, 0x02, 0x3C, 0xF2, 0x5D, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, -0x03, 0x00, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x11, -0x80, 0x00, 0x86, 0x35, 0x0A, 0x5E, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, -0x06, 0x00, 0x40, 0x14, 0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x02, 0x3C, -0x09, 0x5E, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x5E, 0x83, 0xA0, -0x02, 0x80, 0x05, 0x3C, 0x07, 0x5E, 0xA2, 0x90, 0x02, 0x80, 0x03, 0x3C, -0x02, 0x00, 0x04, 0x24, 0x10, 0x00, 0x42, 0x34, 0x07, 0x5E, 0xA2, 0xA0, -0xF1, 0x5D, 0x62, 0x90, 0x21, 0x28, 0x00, 0x00, 0xFF, 0x00, 0x42, 0x30, -0x80, 0x30, 0x02, 0x00, 0x21, 0x30, 0xC2, 0x00, 0xB9, 0x20, 0x00, 0x0C, -0x00, 0x33, 0x06, 0x00, 0x42, 0xB0, 0x02, 0x3C, 0x44, 0x00, 0x04, 0x24, -0x03, 0x00, 0x42, 0x34, 0x00, 0x00, 0x44, 0xA0, 0x02, 0x80, 0x03, 0x3C, -0xEE, 0x5D, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x42, 0x30, -0x04, 0x00, 0x42, 0x28, 0x05, 0x00, 0x40, 0x10, 0x02, 0x80, 0x06, 0x3C, -0x04, 0x00, 0x04, 0x24, 0x4B, 0x2E, 0x00, 0x0C, 0x01, 0x00, 0x05, 0x24, -0x02, 0x80, 0x06, 0x3C, 0xB0, 0x5D, 0xC4, 0x8C, 0x60, 0x1B, 0x47, 0x26, -0xDC, 0x1B, 0xE5, 0x94, 0x10, 0x00, 0x02, 0x3C, 0x25, 0x20, 0x82, 0x00, -0x41, 0xB0, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, 0x7F, 0xFF, 0xA5, 0x30, -0xB0, 0x03, 0x42, 0x34, 0x08, 0x00, 0x63, 0x34, 0x00, 0x00, 0x44, 0xAC, -0x00, 0x00, 0x65, 0xA4, 0xB0, 0x5D, 0xC4, 0xAC, 0xDC, 0x1B, 0xE5, 0xA4, -0x60, 0x1B, 0x47, 0x26, 0xDC, 0x1B, 0xE2, 0x94, 0x00, 0x00, 0x00, 0x00, -0x24, 0x10, 0x50, 0x00, 0x00, 0x30, 0x42, 0x30, 0x06, 0x00, 0x40, 0x10, -0x00, 0x00, 0x00, 0x00, 0xDE, 0x1B, 0xE2, 0x94, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x42, 0x38, 0x00, 0x20, 0x42, 0x34, 0xDE, 0x1B, 0xE2, 0xA4, -0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0x36, 0x37, 0x00, 0x08, 0xDE, 0x1B, 0x46, 0xA5, 0x01, 0x00, 0x08, 0x24, -0x0F, 0x5E, 0x60, 0xA0, 0x72, 0x37, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x07, 0x5E, 0xA2, 0x90, 0x02, 0x80, 0x03, 0x3C, 0x02, 0x00, 0x04, 0x24, -0x10, 0x00, 0x42, 0x34, 0x07, 0x5E, 0xA2, 0xA0, 0xF1, 0x5D, 0x62, 0x90, -0x21, 0x28, 0x00, 0x00, 0xFF, 0x00, 0x42, 0x30, 0x80, 0x30, 0x02, 0x00, -0x21, 0x30, 0xC2, 0x00, 0xB9, 0x20, 0x00, 0x0C, 0x00, 0x33, 0x06, 0x00, -0x44, 0x00, 0x02, 0x24, 0x00, 0x00, 0x22, 0xA2, 0xBA, 0x37, 0x00, 0x08, -0x02, 0x80, 0x03, 0x3C, 0x84, 0x00, 0x84, 0x35, 0x00, 0x00, 0x82, 0x8C, -0x02, 0x80, 0x08, 0x3C, 0x00, 0x00, 0xC4, 0x8C, 0x14, 0x5E, 0x06, 0x8D, -0x21, 0x10, 0x00, 0x00, 0x18, 0x5E, 0x28, 0x8D, 0x1C, 0x5E, 0x29, 0x8D, -0x00, 0x00, 0x65, 0x91, 0x25, 0x10, 0x44, 0x00, 0x21, 0x10, 0x46, 0x00, -0xFB, 0xFF, 0x04, 0x24, 0x24, 0x28, 0xA4, 0x00, 0x23, 0x40, 0x02, 0x01, -0x00, 0x00, 0x65, 0xA1, 0x04, 0x00, 0x00, 0x11, 0x01, 0x00, 0x06, 0x24, -0x80, 0x10, 0x08, 0x00, 0x21, 0x10, 0x48, 0x00, 0x80, 0x30, 0x02, 0x00, -0x01, 0x00, 0x04, 0x24, 0xB9, 0x20, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, -0x42, 0xB0, 0x02, 0x3C, 0x22, 0x00, 0x03, 0x24, 0x03, 0x00, 0x42, 0x34, -0x00, 0x00, 0x43, 0xA0, 0xC4, 0x37, 0x00, 0x08, 0x02, 0x80, 0x06, 0x3C, -0xF0, 0xFF, 0xBD, 0x27, 0x08, 0x00, 0xB2, 0xAF, 0x04, 0x00, 0xB1, 0xAF, -0x00, 0x00, 0xB0, 0xAF, 0x00, 0x40, 0x09, 0x40, 0x00, 0x68, 0x0A, 0x40, -0x00, 0x70, 0x02, 0x40, 0x00, 0x60, 0x0B, 0x40, 0x25, 0xB0, 0x05, 0x3C, -0x18, 0x03, 0xA7, 0x34, 0x00, 0x00, 0xE6, 0x8C, 0x01, 0x80, 0x02, 0x3C, -0x1C, 0x03, 0xA3, 0x34, 0x5C, 0xE0, 0x42, 0x24, 0x00, 0x00, 0x66, 0xAC, -0x00, 0x00, 0xE2, 0xAC, 0x80, 0x00, 0x83, 0x8C, 0x7C, 0x02, 0xA2, 0x34, -0x80, 0x02, 0xA6, 0x34, 0x84, 0x02, 0xA7, 0x34, 0x88, 0x02, 0xA8, 0x34, -0x00, 0x00, 0x43, 0xAC, 0x00, 0x00, 0xC9, 0xAC, 0x00, 0x00, 0xEA, 0xAC, -0x00, 0x00, 0x0B, 0xAD, 0x74, 0x00, 0x83, 0x8C, 0x8C, 0x02, 0xA2, 0x34, -0x90, 0x02, 0xA7, 0x34, 0x00, 0x00, 0x43, 0xAC, 0x08, 0x00, 0x86, 0x8C, -0x94, 0x02, 0xA8, 0x34, 0x98, 0x02, 0xA9, 0x34, 0x00, 0x00, 0xE6, 0xAC, -0x0C, 0x00, 0x82, 0x8C, 0x9C, 0x02, 0xA6, 0x34, 0xA0, 0x02, 0xA7, 0x34, -0x00, 0x00, 0x02, 0xAD, 0x10, 0x00, 0x83, 0x8C, 0xA4, 0x02, 0xA8, 0x34, -0xA8, 0x02, 0xAA, 0x34, 0x00, 0x00, 0x23, 0xAD, 0x14, 0x00, 0x82, 0x8C, -0xAC, 0x02, 0xA9, 0x34, 0xB0, 0x02, 0xAB, 0x34, 0x00, 0x00, 0xC2, 0xAC, -0x18, 0x00, 0x83, 0x8C, 0xB4, 0x02, 0xAC, 0x34, 0xB8, 0x02, 0xAD, 0x34, -0x00, 0x00, 0xE3, 0xAC, 0x1C, 0x00, 0x82, 0x8C, 0xBC, 0x02, 0xA7, 0x34, -0xC0, 0x02, 0xAE, 0x34, 0x00, 0x00, 0x02, 0xAD, 0x20, 0x00, 0x83, 0x8C, -0xC4, 0x02, 0xA8, 0x34, 0xC8, 0x02, 0xAF, 0x34, 0x00, 0x00, 0x43, 0xAD, -0x24, 0x00, 0x82, 0x8C, 0xCC, 0x02, 0xAA, 0x34, 0xD0, 0x02, 0xB0, 0x34, -0x00, 0x00, 0x22, 0xAD, 0x28, 0x00, 0x83, 0x8C, 0xD4, 0x02, 0xA9, 0x34, -0xD8, 0x02, 0xB1, 0x34, 0x00, 0x00, 0x63, 0xAD, 0x2C, 0x00, 0x86, 0x8C, -0x70, 0x02, 0xAB, 0x34, 0x74, 0x02, 0xB2, 0x34, 0x00, 0x00, 0x86, 0xAD, -0x30, 0x00, 0x82, 0x8C, 0x78, 0x02, 0xA6, 0x34, 0x6C, 0x03, 0xAC, 0x34, -0x00, 0x00, 0xA2, 0xAD, 0x34, 0x00, 0x83, 0x8C, 0x02, 0x80, 0x02, 0x3C, -0x00, 0x00, 0xE3, 0xAC, 0x38, 0x00, 0x85, 0x8C, 0xE0, 0xC8, 0x47, 0x8C, -0x00, 0x00, 0xC5, 0xAD, 0x3C, 0x00, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x02, 0xAD, 0x40, 0x00, 0x83, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xE3, 0xAD, 0x44, 0x00, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x42, 0xAD, 0x48, 0x00, 0x83, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x03, 0xAE, 0x4C, 0x00, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x22, 0xAD, 0x50, 0x00, 0x83, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x23, 0xAE, 0x54, 0x00, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x62, 0xAD, 0x58, 0x00, 0x83, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x43, 0xAE, 0x5C, 0x00, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xC2, 0xAC, 0x21, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x82, 0xAD, -0x01, 0x00, 0xE7, 0x24, 0x21, 0x10, 0xE0, 0x00, 0x01, 0x00, 0xE7, 0x24, -0x00, 0x00, 0x82, 0xAD, 0x82, 0x38, 0x00, 0x08, 0x21, 0x10, 0xE0, 0x00, -0x01, 0x80, 0x1B, 0x3C, 0x24, 0xE2, 0x7B, 0x27, 0x25, 0xB0, 0x1A, 0x3C, -0x18, 0x03, 0x5A, 0x27, 0x00, 0x00, 0x5B, 0xAF, 0x21, 0xD8, 0xA0, 0x03, -0x82, 0xDA, 0x1B, 0x00, 0x80, 0xDA, 0x1B, 0x00, 0x08, 0x00, 0x7B, 0x27, -0x04, 0x00, 0x61, 0xAF, 0x08, 0x00, 0x62, 0xAF, 0x0C, 0x00, 0x63, 0xAF, -0x10, 0x00, 0x64, 0xAF, 0x14, 0x00, 0x65, 0xAF, 0x18, 0x00, 0x66, 0xAF, -0x1C, 0x00, 0x67, 0xAF, 0x20, 0x00, 0x68, 0xAF, 0x24, 0x00, 0x69, 0xAF, -0x28, 0x00, 0x6A, 0xAF, 0x2C, 0x00, 0x6B, 0xAF, 0x30, 0x00, 0x6C, 0xAF, -0x34, 0x00, 0x6D, 0xAF, 0x38, 0x00, 0x6E, 0xAF, 0x3C, 0x00, 0x6F, 0xAF, -0x12, 0x40, 0x00, 0x00, 0x10, 0x48, 0x00, 0x00, 0x00, 0x70, 0x0A, 0x40, -0x40, 0x00, 0x70, 0xAF, 0x44, 0x00, 0x71, 0xAF, 0x48, 0x00, 0x72, 0xAF, -0x4C, 0x00, 0x73, 0xAF, 0x50, 0x00, 0x74, 0xAF, 0x54, 0x00, 0x75, 0xAF, -0x58, 0x00, 0x76, 0xAF, 0x5C, 0x00, 0x77, 0xAF, 0x60, 0x00, 0x78, 0xAF, -0x64, 0x00, 0x79, 0xAF, 0x68, 0x00, 0x7C, 0xAF, 0x6C, 0x00, 0x7D, 0xAF, -0x70, 0x00, 0x7E, 0xAF, 0x74, 0x00, 0x7F, 0xAF, 0x78, 0x00, 0x68, 0xAF, -0x7C, 0x00, 0x69, 0xAF, 0x80, 0x00, 0x6A, 0xAF, 0x00, 0x68, 0x1A, 0x40, -0x25, 0xB0, 0x1B, 0x3C, 0x1C, 0x03, 0x7B, 0x37, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x7A, 0xAF, 0x7F, 0x00, 0x5B, 0x33, 0x30, 0x00, 0x60, 0x13, -0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x1B, 0x3C, 0x30, 0x03, 0x7B, 0x37, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7A, 0xAF, 0x00, 0x00, 0x00, 0x00, -0x21, 0xD8, 0xA0, 0x03, 0x82, 0xDA, 0x1B, 0x00, 0x80, 0xDA, 0x1B, 0x00, -0x08, 0x00, 0x7B, 0x27, 0x04, 0x00, 0x61, 0xAF, 0x08, 0x00, 0x62, 0xAF, -0x0C, 0x00, 0x63, 0xAF, 0x10, 0x00, 0x64, 0xAF, 0x14, 0x00, 0x65, 0xAF, -0x18, 0x00, 0x66, 0xAF, 0x1C, 0x00, 0x67, 0xAF, 0x20, 0x00, 0x68, 0xAF, -0x24, 0x00, 0x69, 0xAF, 0x28, 0x00, 0x6A, 0xAF, 0x2C, 0x00, 0x6B, 0xAF, -0x30, 0x00, 0x6C, 0xAF, 0x34, 0x00, 0x6D, 0xAF, 0x38, 0x00, 0x6E, 0xAF, -0x3C, 0x00, 0x6F, 0xAF, 0x12, 0x40, 0x00, 0x00, 0x10, 0x48, 0x00, 0x00, -0x00, 0x70, 0x0A, 0x40, 0x40, 0x00, 0x70, 0xAF, 0x44, 0x00, 0x71, 0xAF, -0x48, 0x00, 0x72, 0xAF, 0x4C, 0x00, 0x73, 0xAF, 0x50, 0x00, 0x74, 0xAF, -0x54, 0x00, 0x75, 0xAF, 0x58, 0x00, 0x76, 0xAF, 0x5C, 0x00, 0x77, 0xAF, -0x60, 0x00, 0x78, 0xAF, 0x64, 0x00, 0x79, 0xAF, 0x68, 0x00, 0x7C, 0xAF, -0x6C, 0x00, 0x7D, 0xAF, 0x70, 0x00, 0x7E, 0xAF, 0x74, 0x00, 0x7F, 0xAF, -0x78, 0x00, 0x68, 0xAF, 0x7C, 0x00, 0x69, 0xAF, 0x80, 0x00, 0x6A, 0xAF, -0x17, 0x38, 0x00, 0x08, 0x21, 0x20, 0x60, 0x03, 0x00, 0x00, 0x00, 0x00, -0x25, 0xB0, 0x08, 0x3C, 0x20, 0x03, 0x08, 0x35, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x1A, 0xAD, 0x00, 0x04, 0x5B, 0x33, 0x0A, 0x00, 0x60, 0x13, -0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x08, 0x3C, 0xE0, 0xC7, 0x08, 0x25, -0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x1B, 0x3C, 0x24, 0x03, 0x7B, 0x37, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0xAF, 0x09, 0xF8, 0x00, 0x01, -0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5B, 0x33, 0x25, 0xB0, 0x08, 0x3C, -0x28, 0x03, 0x08, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xAD, -0x06, 0x00, 0x60, 0x13, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x08, 0x3C, -0x30, 0xDC, 0x08, 0x25, 0x00, 0x00, 0x00, 0x00, 0x09, 0xF8, 0x00, 0x01, -0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x1A, 0x3C, 0xB0, 0x5D, 0x5A, 0x27, -0x04, 0x00, 0x5B, 0x97, 0x25, 0xB0, 0x08, 0x3C, 0x30, 0x03, 0x08, 0x35, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xAD, 0x18, 0x00, 0x60, 0x13, -0x00, 0x00, 0x00, 0x00, 0x08, 0xE8, 0x9B, 0x27, 0x00, 0x00, 0x00, 0x00, -0x04, 0x00, 0x61, 0x8F, 0xFC, 0x03, 0x70, 0x7B, 0x7C, 0x00, 0x62, 0x7B, -0xBC, 0x00, 0x64, 0x7B, 0xFC, 0x00, 0x66, 0x7B, 0x3C, 0x01, 0x68, 0x7B, -0x13, 0x00, 0x00, 0x02, 0x11, 0x00, 0x20, 0x02, 0x7C, 0x01, 0x6A, 0x7B, -0xBC, 0x01, 0x6C, 0x7B, 0xFC, 0x01, 0x6E, 0x7B, 0x3C, 0x02, 0x70, 0x7B, -0x7C, 0x02, 0x72, 0x7B, 0xBC, 0x02, 0x74, 0x7B, 0xFC, 0x02, 0x76, 0x7B, -0x3C, 0x03, 0x78, 0x7B, 0x7C, 0x03, 0x7C, 0x7B, 0xBC, 0x03, 0x7E, 0x7B, -0x80, 0x00, 0x7B, 0x8F, 0x74, 0x39, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x21, 0xD8, 0xA0, 0x03, 0x82, 0xDA, 0x1B, 0x00, 0x80, 0xDA, 0x1B, 0x00, -0x08, 0x00, 0x7B, 0x27, 0x08, 0x00, 0x5B, 0xAF, 0xFC, 0xEB, 0x9D, 0x27, -0x00, 0x00, 0x4A, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x40, 0x11, -0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x08, 0x3C, 0x10, 0x5D, 0x08, 0x25, -0x21, 0x48, 0x00, 0x00, 0x21, 0x58, 0x00, 0x00, 0x01, 0x00, 0x6B, 0x25, -0x1A, 0x00, 0x40, 0x11, 0x24, 0x70, 0x4B, 0x01, 0x14, 0x00, 0xC0, 0x11, -0x01, 0x00, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x44, 0xA3, -0x26, 0x50, 0x4B, 0x01, 0x00, 0x00, 0x4A, 0xAF, 0x80, 0x80, 0x09, 0x00, -0x21, 0x80, 0x08, 0x02, 0x00, 0x00, 0x10, 0x8E, 0x00, 0x00, 0x00, 0x00, -0x09, 0xF8, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x1B, 0x3C, -0xFC, 0xE4, 0x7B, 0x27, 0x25, 0xB0, 0x1A, 0x3C, 0x18, 0x03, 0x5A, 0x27, -0x00, 0x00, 0x5B, 0xAF, 0x02, 0x80, 0x1A, 0x3C, 0xB0, 0x5D, 0x5A, 0x27, -0xE1, 0xFF, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x29, 0x25, -0x40, 0x58, 0x0B, 0x00, 0x37, 0x39, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x02, 0x80, 0x1B, 0x3C, 0xB0, 0x5D, 0x7B, 0x27, 0x21, 0x60, 0x00, 0x00, -0x04, 0x00, 0x6C, 0xA7, 0x08, 0x00, 0x7A, 0x8F, 0x00, 0x00, 0x00, 0x00, -0xF8, 0xFF, 0x5A, 0x27, 0x00, 0x00, 0x5A, 0x8F, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0x5A, 0x27, 0x84, 0x00, 0x44, 0x8F, 0x00, 0x00, 0x00, 0x00, -0xF9, 0xFF, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x41, 0x8F, -0xFC, 0x03, 0x50, 0x7B, 0x7C, 0x00, 0x42, 0x7B, 0xBC, 0x00, 0x44, 0x7B, -0xFC, 0x00, 0x46, 0x7B, 0x3C, 0x01, 0x48, 0x7B, 0x13, 0x00, 0x00, 0x02, -0x11, 0x00, 0x20, 0x02, 0x7C, 0x01, 0x4A, 0x7B, 0xBC, 0x01, 0x4C, 0x7B, -0xFC, 0x01, 0x4E, 0x7B, 0x3C, 0x02, 0x50, 0x7B, 0x7C, 0x02, 0x52, 0x7B, -0xBC, 0x02, 0x54, 0x7B, 0xFC, 0x02, 0x56, 0x7B, 0x3C, 0x03, 0x58, 0x7B, -0x7C, 0x03, 0x5C, 0x7B, 0xBC, 0x03, 0x5E, 0x7B, 0x80, 0x00, 0x5B, 0x8F, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x60, 0x03, 0x10, 0x00, 0x00, 0x42, -0x00, 0x60, 0x05, 0x40, 0x42, 0x28, 0x05, 0x00, 0x40, 0x28, 0x05, 0x00, -0x00, 0x60, 0x85, 0x40, 0x04, 0x00, 0x81, 0xAC, 0x08, 0x00, 0x82, 0xAC, -0x0C, 0x00, 0x83, 0xAC, 0x20, 0x00, 0x88, 0xAC, 0x24, 0x00, 0x89, 0xAC, -0x28, 0x00, 0x8A, 0xAC, 0x2C, 0x00, 0x8B, 0xAC, 0x30, 0x00, 0x8C, 0xAC, -0x34, 0x00, 0x8D, 0xAC, 0x38, 0x00, 0x8E, 0xAC, 0x3C, 0x00, 0x8F, 0xAC, -0x12, 0x40, 0x00, 0x00, 0x10, 0x48, 0x00, 0x00, 0x40, 0x00, 0x90, 0xAC, -0x44, 0x00, 0x91, 0xAC, 0x48, 0x00, 0x92, 0xAC, 0x4C, 0x00, 0x93, 0xAC, -0x50, 0x00, 0x94, 0xAC, 0x54, 0x00, 0x95, 0xAC, 0x58, 0x00, 0x96, 0xAC, -0x5C, 0x00, 0x97, 0xAC, 0x60, 0x00, 0x98, 0xAC, 0x64, 0x00, 0x99, 0xAC, -0x68, 0x00, 0x9C, 0xAC, 0x6C, 0x00, 0x9D, 0xAC, 0x70, 0x00, 0x9E, 0xAC, -0x74, 0x00, 0x9F, 0xAC, 0x78, 0x00, 0x88, 0xAC, 0x7C, 0x00, 0x89, 0xAC, -0x80, 0x00, 0x9F, 0xAC, 0xF8, 0xFF, 0x84, 0x24, 0x00, 0x00, 0x84, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x84, 0x24, 0x84, 0x00, 0x86, 0x8C, -0x00, 0x00, 0x00, 0x00, 0xF9, 0xFF, 0xC0, 0x10, 0x00, 0x00, 0x00, 0x00, -0x21, 0xD8, 0x80, 0x00, 0x01, 0x00, 0xBA, 0x34, 0x04, 0x00, 0x61, 0x8F, -0xFC, 0x03, 0x70, 0x7B, 0x7C, 0x00, 0x62, 0x7B, 0xBC, 0x00, 0x64, 0x7B, -0xFC, 0x00, 0x66, 0x7B, 0x3C, 0x01, 0x68, 0x7B, 0x13, 0x00, 0x00, 0x02, -0x11, 0x00, 0x20, 0x02, 0x7C, 0x01, 0x6A, 0x7B, 0xBC, 0x01, 0x6C, 0x7B, -0xFC, 0x01, 0x6E, 0x7B, 0x3C, 0x02, 0x70, 0x7B, 0x7C, 0x02, 0x72, 0x7B, -0xBC, 0x02, 0x74, 0x7B, 0xFC, 0x02, 0x76, 0x7B, 0x3C, 0x03, 0x78, 0x7B, -0x7C, 0x03, 0x7C, 0x7B, 0xBC, 0x03, 0x7E, 0x7B, 0x80, 0x00, 0x7B, 0x8F, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x60, 0x03, 0x00, 0x60, 0x9A, 0x40, -0x00, 0x60, 0x05, 0x40, 0x42, 0x28, 0x05, 0x00, 0x40, 0x28, 0x05, 0x00, -0x00, 0x60, 0x85, 0x40, 0x04, 0x00, 0x81, 0xAC, 0x08, 0x00, 0x82, 0xAC, -0x0C, 0x00, 0x83, 0xAC, 0x20, 0x00, 0x88, 0xAC, 0x24, 0x00, 0x89, 0xAC, -0x28, 0x00, 0x8A, 0xAC, 0x2C, 0x00, 0x8B, 0xAC, 0x30, 0x00, 0x8C, 0xAC, -0x34, 0x00, 0x8D, 0xAC, 0x38, 0x00, 0x8E, 0xAC, 0x3C, 0x00, 0x8F, 0xAC, -0x12, 0x40, 0x00, 0x00, 0x10, 0x48, 0x00, 0x00, 0x40, 0x00, 0x90, 0xAC, -0x44, 0x00, 0x91, 0xAC, 0x48, 0x00, 0x92, 0xAC, 0x4C, 0x00, 0x93, 0xAC, -0x50, 0x00, 0x94, 0xAC, 0x54, 0x00, 0x94, 0xAC, 0x58, 0x00, 0x96, 0xAC, -0x5C, 0x00, 0x96, 0xAC, 0x60, 0x00, 0x98, 0xAC, 0x64, 0x00, 0x99, 0xAC, -0x68, 0x00, 0x9C, 0xAC, 0x6C, 0x00, 0x9D, 0xAC, 0x70, 0x00, 0x9E, 0xAC, -0x78, 0x00, 0x88, 0xAC, 0x7C, 0x00, 0x89, 0xAC, 0x80, 0x00, 0x9F, 0xAC, -0x84, 0x00, 0x80, 0xAC, 0xF8, 0xFF, 0x84, 0x24, 0x00, 0x00, 0x84, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x84, 0x24, 0x84, 0x00, 0x86, 0x8C, -0xFA, 0xFF, 0xC0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0xD8, 0x80, 0x00, -0x01, 0x00, 0xBA, 0x24, 0x04, 0x00, 0x61, 0x8F, 0xFC, 0x03, 0x70, 0x7B, -0x7C, 0x00, 0x62, 0x7B, 0xBC, 0x00, 0x64, 0x7B, 0xFC, 0x00, 0x66, 0x7B, -0x3C, 0x01, 0x68, 0x7B, 0x13, 0x00, 0x00, 0x02, 0x11, 0x00, 0x20, 0x02, -0x7C, 0x01, 0x6A, 0x7B, 0xBC, 0x01, 0x6C, 0x7B, 0xFC, 0x01, 0x6E, 0x7B, -0x3C, 0x02, 0x70, 0x7B, 0x7C, 0x02, 0x72, 0x7B, 0xBC, 0x02, 0x74, 0x7B, -0xFC, 0x02, 0x76, 0x7B, 0x3C, 0x03, 0x78, 0x7B, 0x7C, 0x03, 0x7C, 0x7B, -0xBC, 0x03, 0x7E, 0x7B, 0x80, 0x00, 0x7B, 0x8F, 0x08, 0x00, 0x60, 0x03, -0x00, 0x60, 0x9A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x23, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x1B, 0x3C, -0x00, 0x00, 0x7B, 0x27, 0x25, 0xB0, 0x1A, 0x3C, 0x18, 0x03, 0x5A, 0x27, -0x00, 0x00, 0x5B, 0xAF, 0x00, 0x00, 0x05, 0x24, 0x03, 0x00, 0xA4, 0x24, -0x00, 0xA0, 0x80, 0x40, 0x00, 0xA0, 0x84, 0x40, 0x01, 0x80, 0x04, 0x3C, -0x40, 0x00, 0x84, 0x24, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x80, 0x1B, 0x3C, 0x40, 0x00, 0x7B, 0x27, 0x25, 0xB0, 0x1A, 0x3C, -0x18, 0x03, 0x5A, 0x27, 0x00, 0x00, 0x5B, 0xAF, 0x02, 0x80, 0x1A, 0x3C, -0x00, 0x00, 0x5A, 0x27, 0xFC, 0x03, 0x5D, 0x27, 0x02, 0x80, 0x1C, 0x3C, -0x00, 0x18, 0x9C, 0x27, 0x00, 0xF0, 0x08, 0x3C, 0x00, 0x0C, 0x08, 0x35, -0x00, 0x60, 0x88, 0x40, 0x02, 0x80, 0x04, 0x3C, 0x00, 0x00, 0x84, 0x24, -0xFF, 0x7F, 0x05, 0x3C, 0xFF, 0xFF, 0xA5, 0x34, 0x24, 0x20, 0x85, 0x00, -0x00, 0x20, 0x84, 0x4C, 0xFF, 0xFF, 0x05, 0x34, 0x21, 0x28, 0xA4, 0x00, -0x00, 0x28, 0x85, 0x4C, 0x02, 0x80, 0x08, 0x3C, 0x00, 0x00, 0x08, 0x25, -0x00, 0x00, 0x00, 0xAD, 0x03, 0x80, 0x09, 0x3C, 0x04, 0xDD, 0x29, 0x25, -0x04, 0x00, 0x08, 0x25, 0xFE, 0xFF, 0x09, 0x15, 0x00, 0x00, 0x00, 0xAD, -0x00, 0x80, 0x04, 0x3C, 0x00, 0x00, 0x84, 0x24, 0xFF, 0x7F, 0x05, 0x3C, -0xFF, 0xFF, 0xA5, 0x34, 0x24, 0x20, 0x85, 0x00, 0x00, 0x00, 0x84, 0x4C, -0xFF, 0xFF, 0x06, 0x34, 0x21, 0x30, 0xC4, 0x00, 0x24, 0x30, 0xC5, 0x00, -0x00, 0x08, 0x86, 0x4C, 0x00, 0xA0, 0x04, 0x40, 0x10, 0x00, 0x84, 0x34, -0x00, 0xA0, 0x84, 0x40, 0x01, 0x80, 0x1B, 0x3C, 0xEC, 0x00, 0x7B, 0x27, -0x25, 0xB0, 0x1A, 0x3C, 0x18, 0x03, 0x5A, 0x27, 0x00, 0x00, 0x5B, 0xAF, -0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x04, 0x3C, 0x44, 0x00, 0x84, 0x34, -0x00, 0x00, 0x85, 0x84, 0x20, 0x00, 0x06, 0x24, 0x25, 0x28, 0xA6, 0x00, -0x00, 0x00, 0x85, 0xA4, 0x01, 0x80, 0x1B, 0x3C, 0x1C, 0x01, 0x7B, 0x27, -0x25, 0xB0, 0x1A, 0x3C, 0x18, 0x03, 0x5A, 0x27, 0x00, 0x00, 0x5B, 0xAF, -0x25, 0xB0, 0x04, 0x3C, 0x44, 0x00, 0x84, 0x34, 0x00, 0x00, 0x85, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xA5, 0x30, 0xFC, 0xFF, 0xA0, 0x10, -0x00, 0x00, 0x00, 0x00, 0xFF, 0x1F, 0x07, 0x3C, 0xFF, 0xFF, 0xE7, 0x34, -0x02, 0x80, 0x05, 0x3C, 0xC0, 0x5C, 0xA5, 0x24, 0xFF, 0xFF, 0xA5, 0x30, -0x40, 0xB0, 0x04, 0x3C, 0x25, 0x28, 0xA4, 0x00, 0x24, 0x28, 0xA7, 0x00, -0x21, 0x30, 0x00, 0x00, 0x43, 0xB0, 0x02, 0x3C, 0x00, 0x80, 0x04, 0x3C, -0x40, 0x00, 0x84, 0x34, 0x00, 0x00, 0x45, 0xAC, 0x04, 0x00, 0x46, 0xAC, -0x08, 0x00, 0x44, 0xAC, 0x5F, 0x67, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x25, 0xB0, 0x02, 0x3C, 0x04, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x64, 0x30, 0x02, 0x1C, 0x03, 0x00, -0x08, 0x00, 0x80, 0x10, 0x0F, 0x00, 0x63, 0x30, 0x01, 0x00, 0x02, 0x24, -0x0C, 0x00, 0x62, 0x10, 0x03, 0x00, 0x02, 0x24, 0x0E, 0x00, 0x62, 0x10, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0x03, 0x00, 0x60, 0x14, 0x02, 0x80, 0x02, 0x3C, 0x08, 0x00, 0xE0, 0x03, -0xC3, 0x5C, 0x40, 0xA0, 0x01, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, -0xC3, 0x5C, 0x43, 0xA0, 0x02, 0x00, 0x03, 0x24, 0x02, 0x80, 0x02, 0x3C, -0x08, 0x00, 0xE0, 0x03, 0xC3, 0x5C, 0x43, 0xA0, 0x04, 0x00, 0x03, 0x24, -0x02, 0x80, 0x02, 0x3C, 0x08, 0x00, 0xE0, 0x03, 0xC3, 0x5C, 0x43, 0xA0, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x02, 0x24, -0xFF, 0xFF, 0x42, 0x24, 0xFF, 0xFF, 0x41, 0x04, 0xFF, 0xFF, 0x42, 0x24, -0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x42, 0x24, 0x00, 0x60, 0x02, 0x40, -0x01, 0x00, 0x41, 0x34, 0x01, 0x00, 0x21, 0x38, 0x00, 0x60, 0x81, 0x40, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x82, 0xAC, 0x00, 0x00, 0x82, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x21, 0x18, 0x40, 0x00, 0x00, 0x60, 0x83, 0x40, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x82, 0xAC, 0x00, 0x60, 0x01, 0x40, -0x01, 0x00, 0x21, 0x34, 0x00, 0x60, 0x81, 0x40, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x01, 0x40, 0x01, 0x00, 0x21, 0x34, -0x01, 0x00, 0x21, 0x38, 0x00, 0x60, 0x81, 0x40, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, -0x84, 0x02, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, -0x04, 0x00, 0x85, 0x8C, 0x00, 0xA0, 0x03, 0x3C, 0x01, 0x00, 0x02, 0x24, -0x25, 0x28, 0xA3, 0x00, 0x00, 0x00, 0xA4, 0x8C, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, -0xB4, 0x02, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, -0x04, 0x00, 0x82, 0x8C, 0x02, 0x00, 0x83, 0x94, 0x00, 0xA0, 0x07, 0x3C, -0x25, 0x28, 0x47, 0x00, 0x00, 0x00, 0xA2, 0x8C, 0x10, 0x00, 0x02, 0x24, -0x13, 0x00, 0x62, 0x10, 0x11, 0x00, 0x66, 0x28, 0x06, 0x00, 0xC0, 0x10, -0x20, 0x00, 0x02, 0x24, 0x08, 0x00, 0x02, 0x24, 0x17, 0x00, 0x62, 0x10, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24, -0xFD, 0xFF, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x83, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0xAC, 0x04, 0x00, 0x82, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x25, 0x10, 0x47, 0x00, 0x00, 0x00, 0x42, 0x8C, -0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0x82, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xA4, 0x04, 0x00, 0x83, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x25, 0x18, 0x67, 0x00, 0x00, 0x00, 0x62, 0x94, -0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0x82, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xA0, 0x04, 0x00, 0x83, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x25, 0x18, 0x67, 0x00, 0x00, 0x00, 0x62, 0x90, -0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24, 0x02, 0x80, 0x02, 0x3C, -0x60, 0x1B, 0x47, 0x24, 0x24, 0x38, 0xE3, 0x90, 0xFF, 0xFF, 0xA5, 0x30, -0x09, 0x00, 0xA3, 0x10, 0x21, 0x20, 0xC0, 0x00, 0x94, 0x38, 0xE2, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xC2, 0xAC, 0x9E, 0x38, 0xE3, 0x94, -0x0E, 0x00, 0x02, 0x24, 0x14, 0x00, 0xC2, 0xAC, 0x17, 0x0A, 0x00, 0x08, -0x0C, 0x00, 0xC3, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0xE0, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF, 0x02, 0x80, 0x11, 0x3C, -0x1C, 0x00, 0xBF, 0xAF, 0x18, 0x00, 0xB2, 0xAF, 0x10, 0x00, 0xB0, 0xAF, -0x60, 0x1B, 0x31, 0x26, 0x7C, 0x38, 0x30, 0x96, 0x02, 0x80, 0x02, 0x3C, -0x01, 0x80, 0x03, 0x3C, 0x25, 0x80, 0x02, 0x02, 0x25, 0xB0, 0x02, 0x3C, -0xB8, 0x03, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34, 0x60, 0x00, 0x04, 0x26, -0x80, 0x00, 0x05, 0x26, 0x00, 0x00, 0x43, 0xAC, 0xC2, 0x1B, 0x00, 0x0C, -0x03, 0x00, 0x06, 0x24, 0x21, 0x20, 0x00, 0x02, 0x21, 0x28, 0x00, 0x00, -0xEC, 0x54, 0x00, 0x0C, 0x08, 0x00, 0x06, 0x24, 0x7C, 0x38, 0x22, 0x8E, -0x0C, 0x00, 0x03, 0x24, 0x0C, 0x00, 0x43, 0xAE, 0x08, 0x00, 0x42, 0xAE, -0x12, 0x00, 0x02, 0x24, 0x14, 0x00, 0x42, 0xAE, 0x21, 0x20, 0x40, 0x02, -0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x17, 0x0A, 0x00, 0x08, 0x20, 0x00, 0xBD, 0x27, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0xD8, 0xFF, 0xBD, 0x27, -0x18, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0x80, 0x00, 0x1C, 0x00, 0xB1, 0xAF, -0x20, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, -0x0D, 0x00, 0x03, 0x92, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x60, 0x14, -0x21, 0x88, 0x00, 0x00, 0x01, 0x00, 0x03, 0x24, 0x02, 0x80, 0x02, 0x3C, -0xF0, 0x5D, 0x43, 0xA0, 0x0C, 0x00, 0x02, 0x92, 0x02, 0x80, 0x05, 0x3C, -0x06, 0x5E, 0xA2, 0xA0, 0x00, 0x00, 0x04, 0x92, 0x05, 0x00, 0x02, 0x24, -0xFF, 0x00, 0x83, 0x30, 0x41, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, -0x03, 0x00, 0x02, 0x24, 0x31, 0x00, 0x62, 0x10, 0xFF, 0x00, 0x84, 0x30, -0x09, 0x00, 0x82, 0x2C, 0x25, 0x00, 0x40, 0x10, 0x02, 0x80, 0x10, 0x3C, -0xEC, 0x5D, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x42, 0x30, -0x21, 0x00, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x99, 0x61, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0xEC, 0x5D, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, -0x37, 0x00, 0x40, 0x10, 0x02, 0x80, 0x03, 0x3C, 0x10, 0x37, 0x62, 0x94, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x30, 0x54, 0x00, 0x40, 0x10, -0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0x0E, 0x5E, 0x62, 0x90, -0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x0E, 0x5E, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, -0x0E, 0x5E, 0x62, 0xA0, 0x02, 0x80, 0x03, 0x3C, 0xEE, 0x5D, 0x62, 0x90, -0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x42, 0x30, 0x04, 0x00, 0x42, 0x28, -0x06, 0x00, 0x40, 0x10, 0x04, 0x00, 0x04, 0x24, 0x4B, 0x2E, 0x00, 0x0C, -0x01, 0x00, 0x05, 0x24, 0x5B, 0x41, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x04, 0x00, 0x11, 0x24, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, -0x21, 0x10, 0x20, 0x02, 0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, -0x0B, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x14, -0x02, 0x80, 0x03, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0x01, 0x00, 0x02, 0x24, -0x09, 0x5E, 0x62, 0xA0, 0x09, 0x5E, 0x63, 0x90, 0x02, 0x80, 0x02, 0x3C, -0x0A, 0x5E, 0x43, 0xA0, 0x00, 0x00, 0x04, 0x92, 0x33, 0x41, 0x00, 0x08, -0xFF, 0x00, 0x84, 0x30, 0x06, 0x5E, 0xA0, 0xA0, 0x0C, 0x00, 0x03, 0x92, -0x02, 0x80, 0x02, 0x3C, 0x04, 0x5E, 0x43, 0xA0, 0x00, 0x00, 0x04, 0x92, -0x30, 0x41, 0x00, 0x08, 0xFF, 0x00, 0x83, 0x30, 0x42, 0xB0, 0x06, 0x3C, -0x00, 0x00, 0xC3, 0x90, 0xEF, 0xFF, 0x02, 0x24, 0x03, 0x00, 0xC7, 0x34, -0x24, 0x18, 0x62, 0x00, 0x40, 0x00, 0x02, 0x24, 0x00, 0x00, 0xC3, 0xA0, -0x0C, 0x00, 0x04, 0x24, 0x00, 0x00, 0xE2, 0xA0, 0x4B, 0x2E, 0x00, 0x0C, -0x01, 0x00, 0x05, 0x24, 0x02, 0x80, 0x03, 0x3C, 0xC6, 0x5C, 0x62, 0x90, -0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x30, 0x15, 0x00, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x24, 0x00, 0x02, 0x05, 0x3C, -0xC1, 0x43, 0x00, 0x0C, 0x01, 0x00, 0x06, 0x24, 0x02, 0x80, 0x02, 0x3C, -0x60, 0x1B, 0x42, 0x24, 0x2A, 0x1C, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, -0xCA, 0xFF, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x3A, 0x44, 0x94, -0x2A, 0x1C, 0x40, 0xA0, 0x00, 0xC0, 0x84, 0x24, 0xA3, 0x31, 0x00, 0x0C, -0xFF, 0xFF, 0x84, 0x30, 0x5B, 0x41, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x0E, 0x5E, 0x40, 0xA0, 0x5B, 0x41, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0xA8, 0x2D, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24, 0x89, 0x41, 0x00, 0x08, -0x00, 0x08, 0x04, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, -0xE0, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF, 0x02, 0x80, 0x11, 0x3C, -0x10, 0x00, 0xB0, 0xAF, 0x60, 0x1B, 0x30, 0x26, 0xB0, 0x1B, 0x07, 0x96, -0x18, 0x00, 0xBF, 0xAF, 0xFF, 0xFF, 0xE3, 0x30, 0x00, 0x01, 0x62, 0x30, -0x0E, 0x00, 0x40, 0x10, 0x01, 0x00, 0x66, 0x30, 0x02, 0x80, 0x04, 0x3C, -0xB4, 0x55, 0x84, 0x24, 0x03, 0x00, 0x05, 0x24, 0x1E, 0x00, 0xC0, 0x14, -0x04, 0x00, 0x62, 0x30, 0x02, 0x00, 0x40, 0x10, 0xFB, 0xF6, 0xE3, 0x30, -0xB0, 0x1B, 0x03, 0xA6, 0x87, 0x54, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x25, 0xB0, 0x02, 0x3C, 0x4C, 0x00, 0x42, 0x34, 0x00, 0x00, 0x40, 0xA0, -0x21, 0x20, 0x00, 0x00, 0x95, 0x0E, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, -0x25, 0xB0, 0x06, 0x3C, 0x48, 0x00, 0xC6, 0x34, 0x00, 0x00, 0xC5, 0x8C, -0x60, 0x1B, 0x24, 0x26, 0x7B, 0xFF, 0x03, 0x3C, 0x18, 0x00, 0xBF, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0xFF, 0xFF, 0x63, 0x34, -0x21, 0x10, 0x00, 0x00, 0x24, 0x28, 0xA3, 0x00, 0x20, 0x00, 0xBD, 0x27, -0x00, 0x00, 0xC5, 0xAC, 0xBC, 0x40, 0x80, 0xAC, 0xE8, 0x39, 0x80, 0xAC, -0x04, 0x3A, 0x80, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0xFC, 0x40, 0x80, 0xAC, -0x1C, 0x4F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x1B, 0x02, 0x96, -0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x42, 0x30, 0x87, 0x54, 0x00, 0x0C, -0xB0, 0x1B, 0x02, 0xA6, 0x25, 0xB0, 0x02, 0x3C, 0x4C, 0x00, 0x42, 0x34, -0x00, 0x00, 0x40, 0xA0, 0xBB, 0x41, 0x00, 0x08, 0x21, 0x20, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF, -0x01, 0x00, 0x83, 0x90, 0x02, 0x80, 0x02, 0x3C, 0x21, 0x38, 0x80, 0x00, -0x8C, 0x5B, 0x43, 0xAC, 0x01, 0x00, 0x84, 0x90, 0x00, 0x00, 0xE2, 0x90, -0x02, 0x80, 0x06, 0x3C, 0xFF, 0x00, 0x85, 0x30, 0x80, 0x10, 0x02, 0x00, -0x25, 0x28, 0xA2, 0x00, 0x88, 0xDE, 0xC6, 0x24, 0xFF, 0x00, 0x84, 0x30, -0x00, 0x80, 0xA5, 0x34, 0x6F, 0x20, 0x00, 0x0C, 0x03, 0x00, 0xE7, 0x24, -0x10, 0x00, 0xBF, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF, -0x02, 0x80, 0x03, 0x3C, 0x1C, 0x00, 0xBF, 0xAF, 0x10, 0x37, 0x62, 0x94, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x43, 0x30, 0x00, 0x01, 0x42, 0x30, -0x04, 0x00, 0x40, 0x10, 0x21, 0x80, 0x80, 0x00, 0x02, 0x80, 0x04, 0x3C, -0x06, 0x00, 0x60, 0x14, 0x60, 0xE7, 0x84, 0x24, 0x1C, 0x00, 0xBF, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x20, 0x00, 0xBD, 0x27, 0x13, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x06, 0x00, 0x07, 0x92, 0x07, 0x00, 0x02, 0x26, 0x21, 0x20, 0x00, 0x02, -0x80, 0x38, 0x07, 0x00, 0x00, 0x80, 0xE7, 0x34, 0x05, 0x00, 0x05, 0x24, -0x21, 0x30, 0x00, 0x00, 0x02, 0x54, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF, -0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27, -0x02, 0x80, 0x02, 0x3C, 0x10, 0x00, 0xB0, 0xAF, 0x14, 0x00, 0xBF, 0xAF, -0x60, 0x1B, 0x45, 0x24, 0xFC, 0x40, 0xA3, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x06, 0x00, 0x60, 0x14, 0x21, 0x80, 0x80, 0x00, 0x14, 0x00, 0xBF, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0xF8, 0x40, 0xA2, 0x90, 0x00, 0x00, 0x00, 0x00, -0x21, 0x10, 0x45, 0x00, 0xF0, 0x40, 0x40, 0xA0, 0x00, 0x00, 0x84, 0x8C, -0xC3, 0x1A, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x8E, -0x03, 0x00, 0x04, 0x24, 0xD9, 0x12, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, -0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x84, 0x90, -0x75, 0x0D, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0xD8, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x10, 0x3C, -0x20, 0x00, 0xB2, 0xAF, 0x60, 0x1B, 0x02, 0x26, 0x24, 0x00, 0xBF, 0xAF, -0x1C, 0x00, 0xB1, 0xAF, 0xB0, 0x1B, 0x45, 0x94, 0x21, 0x90, 0x80, 0x00, -0x02, 0x80, 0x04, 0x3C, 0x13, 0x58, 0x00, 0x0C, 0x80, 0xE7, 0x84, 0x24, -0x00, 0x00, 0x42, 0x96, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x43, 0x24, -0x20, 0x00, 0x42, 0x24, 0xC2, 0x18, 0x03, 0x00, 0xC2, 0x28, 0x02, 0x00, -0x07, 0x00, 0x42, 0x30, 0x02, 0x00, 0x40, 0x14, 0xC0, 0x20, 0x03, 0x00, -0xC0, 0x20, 0x05, 0x00, 0x53, 0x21, 0x00, 0x0C, 0x60, 0x1B, 0x11, 0x26, -0x02, 0x80, 0x05, 0x3C, 0x21, 0x38, 0x40, 0x00, 0x21, 0x80, 0x40, 0x00, -0x0A, 0x00, 0x04, 0x24, 0x22, 0x00, 0x40, 0x10, 0x70, 0xE7, 0xA5, 0x24, -0x02, 0x00, 0x46, 0x92, 0x10, 0x38, 0x25, 0x8E, 0x72, 0x01, 0x00, 0x0C, -0x08, 0x00, 0xC6, 0x24, 0x5B, 0x01, 0x00, 0x0C, 0x0A, 0x00, 0x04, 0x24, -0x08, 0x00, 0x02, 0x96, 0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x04, 0x3C, -0x25, 0x28, 0x45, 0x00, 0x74, 0x03, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C, -0xB0, 0x55, 0x84, 0x24, 0x74, 0x21, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x02, -0x31, 0x46, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x37, 0x26, 0x8E, -0x58, 0x38, 0x25, 0x8E, 0x01, 0x00, 0x04, 0x24, 0x00, 0x01, 0x07, 0x24, -0x01, 0x00, 0x02, 0x24, 0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF, -0x5B, 0x01, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24, 0x24, 0x00, 0xBF, 0x8F, -0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, -0x02, 0x80, 0x04, 0x3C, 0x13, 0x58, 0x00, 0x0C, 0x18, 0xE7, 0x84, 0x24, -0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x28, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x82, 0x90, 0x02, 0x80, 0x03, 0x3C, -0x60, 0x1B, 0x63, 0x24, 0x07, 0x00, 0x40, 0x10, 0x21, 0x20, 0x60, 0x00, -0xD0, 0x07, 0x02, 0x24, 0x3C, 0x3A, 0x62, 0xAC, 0x01, 0x00, 0x03, 0x24, -0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x48, 0x41, 0x83, 0xA0, -0x21, 0x10, 0x00, 0x00, 0x3C, 0x3A, 0x60, 0xAC, 0x08, 0x00, 0xE0, 0x03, -0x48, 0x41, 0x60, 0xA0, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, -0x25, 0xB0, 0x10, 0x3C, 0x21, 0x28, 0x80, 0x00, 0x06, 0x00, 0x06, 0x24, -0x14, 0x00, 0xBF, 0xAF, 0xF4, 0x54, 0x00, 0x0C, 0x50, 0x00, 0x04, 0x36, -0x02, 0x80, 0x04, 0x3C, 0x50, 0x00, 0x05, 0x36, 0x48, 0x37, 0x84, 0x24, -0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x04, 0x3C, -0x13, 0x58, 0x00, 0x0C, 0x94, 0xE7, 0x84, 0x24, 0x14, 0x00, 0xBF, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0x25, 0xB0, 0x05, 0x3C, 0x01, 0x80, 0x03, 0x3C, -0xE8, 0xFF, 0xBD, 0x27, 0x21, 0x30, 0x80, 0x00, 0x18, 0x03, 0xA2, 0x34, -0xC0, 0x0B, 0x63, 0x24, 0x01, 0x00, 0x04, 0x24, 0x14, 0x00, 0xBF, 0xAF, -0x10, 0x00, 0xB0, 0xAF, 0x00, 0x00, 0x43, 0xAC, 0x66, 0x00, 0xC4, 0x10, -0x02, 0x80, 0x02, 0x3C, 0x09, 0x00, 0xC0, 0x10, 0x02, 0x00, 0x02, 0x24, -0x36, 0x00, 0xC2, 0x10, 0x03, 0x00, 0x02, 0x24, 0x8B, 0x00, 0xC2, 0x10, -0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, -0x60, 0x1B, 0x50, 0x24, 0x70, 0x08, 0x02, 0x24, 0x34, 0x1C, 0x02, 0xAE, -0xE0, 0x08, 0x03, 0x24, 0x40, 0x08, 0x02, 0x24, 0x38, 0x1C, 0x03, 0xAE, -0x44, 0x1C, 0x02, 0xAE, 0x78, 0x08, 0x03, 0x24, 0x0C, 0x08, 0x02, 0x24, -0x48, 0x1C, 0x03, 0xAE, 0x4C, 0x1C, 0x02, 0xAE, 0x10, 0x08, 0x03, 0x24, -0x20, 0x08, 0x02, 0x24, 0x50, 0x1C, 0x03, 0xAE, 0x54, 0x1C, 0x02, 0xAE, -0x24, 0x08, 0x03, 0x24, 0x58, 0x08, 0x02, 0x24, 0x58, 0x1C, 0x03, 0xAE, -0x5C, 0x1C, 0x02, 0xAE, 0x50, 0x0C, 0x03, 0x24, 0x54, 0x0C, 0x02, 0x24, -0x60, 0x1C, 0x03, 0xAE, 0x64, 0x1C, 0x02, 0xAE, 0x14, 0x0C, 0x03, 0x24, -0x10, 0x0C, 0x02, 0x24, 0x20, 0x08, 0xA4, 0x34, 0x68, 0x1C, 0x03, 0xAE, -0x60, 0x08, 0x05, 0x24, 0x6C, 0x1C, 0x02, 0xAE, 0x80, 0x0C, 0x03, 0x24, -0x84, 0x0C, 0x02, 0x24, 0x40, 0x1C, 0x05, 0xAE, 0x70, 0x1C, 0x03, 0xAE, -0x74, 0x1C, 0x02, 0xAE, 0x31, 0x1C, 0x00, 0xA2, 0xFA, 0x5B, 0x00, 0x0C, -0x3C, 0x1C, 0x05, 0xAE, 0x00, 0x01, 0x42, 0x30, 0x31, 0x00, 0x40, 0x14, -0xB8, 0x08, 0x02, 0x24, 0xA0, 0x08, 0x02, 0x24, 0x78, 0x1C, 0x02, 0xAE, -0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, -0xA8, 0x08, 0x03, 0x24, 0x78, 0x1C, 0x43, 0xAC, 0x74, 0x08, 0x03, 0x24, -0xE4, 0x08, 0x04, 0x24, 0x34, 0x1C, 0x43, 0xAC, 0x48, 0x08, 0x03, 0x24, -0x38, 0x1C, 0x44, 0xAC, 0x44, 0x1C, 0x43, 0xAC, 0x7C, 0x08, 0x04, 0x24, -0x0C, 0x08, 0x03, 0x24, 0x48, 0x1C, 0x44, 0xAC, 0x4C, 0x1C, 0x43, 0xAC, -0x18, 0x08, 0x04, 0x24, 0x30, 0x08, 0x03, 0x24, 0x50, 0x1C, 0x44, 0xAC, -0x54, 0x1C, 0x43, 0xAC, 0x34, 0x08, 0x04, 0x24, 0x5C, 0x08, 0x03, 0x24, -0x58, 0x1C, 0x44, 0xAC, 0x5C, 0x1C, 0x43, 0xAC, 0x60, 0x0C, 0x04, 0x24, -0x64, 0x0C, 0x03, 0x24, 0x60, 0x1C, 0x44, 0xAC, 0x64, 0x1C, 0x43, 0xAC, -0x24, 0x0C, 0x04, 0x24, 0x20, 0x0C, 0x03, 0x24, 0x68, 0x08, 0x05, 0x24, -0x68, 0x1C, 0x44, 0xAC, 0x6C, 0x1C, 0x43, 0xAC, 0x90, 0x0C, 0x04, 0x24, -0x94, 0x0C, 0x03, 0x24, 0x31, 0x1C, 0x46, 0xA0, 0x40, 0x1C, 0x45, 0xAC, -0x70, 0x1C, 0x44, 0xAC, 0x74, 0x1C, 0x43, 0xAC, 0x3C, 0x1C, 0x45, 0xAC, -0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0x31, 0x43, 0x00, 0x08, 0x78, 0x1C, 0x02, 0xAE, -0x60, 0x1B, 0x50, 0x24, 0x70, 0x08, 0x02, 0x24, 0x34, 0x1C, 0x02, 0xAE, -0xE0, 0x08, 0x03, 0x24, 0x44, 0x08, 0x02, 0x24, 0x38, 0x1C, 0x03, 0xAE, -0x44, 0x1C, 0x02, 0xAE, 0x78, 0x08, 0x03, 0x24, 0x0C, 0x08, 0x02, 0x24, -0x48, 0x1C, 0x03, 0xAE, 0x4C, 0x1C, 0x02, 0xAE, 0x14, 0x08, 0x03, 0x24, -0x28, 0x08, 0x02, 0x24, 0x50, 0x1C, 0x03, 0xAE, 0x54, 0x1C, 0x02, 0xAE, -0x2C, 0x08, 0x03, 0x24, 0x58, 0x08, 0x02, 0x24, 0x58, 0x1C, 0x03, 0xAE, -0x5C, 0x1C, 0x02, 0xAE, 0x58, 0x0C, 0x03, 0x24, 0x5C, 0x0C, 0x02, 0x24, -0x60, 0x1C, 0x03, 0xAE, 0x64, 0x1C, 0x02, 0xAE, 0x1C, 0x0C, 0x03, 0x24, -0x18, 0x0C, 0x02, 0x24, 0x28, 0x08, 0xA4, 0x34, 0x68, 0x1C, 0x03, 0xAE, -0x64, 0x08, 0x05, 0x24, 0x6C, 0x1C, 0x02, 0xAE, 0x88, 0x0C, 0x03, 0x24, -0x8C, 0x0C, 0x02, 0x24, 0x31, 0x1C, 0x06, 0xA2, 0x40, 0x1C, 0x05, 0xAE, -0x70, 0x1C, 0x03, 0xAE, 0x74, 0x1C, 0x02, 0xAE, 0xFA, 0x5B, 0x00, 0x0C, -0x3C, 0x1C, 0x05, 0xAE, 0x00, 0x01, 0x42, 0x30, 0x2B, 0x00, 0x40, 0x14, -0xBC, 0x08, 0x02, 0x24, 0xA4, 0x08, 0x02, 0x24, 0x31, 0x43, 0x00, 0x08, -0x78, 0x1C, 0x02, 0xAE, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, -0xAC, 0x08, 0x03, 0x24, 0x78, 0x1C, 0x43, 0xAC, 0x74, 0x08, 0x03, 0x24, -0xE4, 0x08, 0x04, 0x24, 0x34, 0x1C, 0x43, 0xAC, 0x4C, 0x08, 0x03, 0x24, -0x38, 0x1C, 0x44, 0xAC, 0x44, 0x1C, 0x43, 0xAC, 0x7C, 0x08, 0x04, 0x24, -0x0C, 0x08, 0x03, 0x24, 0x48, 0x1C, 0x44, 0xAC, 0x4C, 0x1C, 0x43, 0xAC, -0x1C, 0x08, 0x04, 0x24, 0x38, 0x08, 0x03, 0x24, 0x50, 0x1C, 0x44, 0xAC, -0x54, 0x1C, 0x43, 0xAC, 0x3C, 0x08, 0x04, 0x24, 0x5C, 0x08, 0x03, 0x24, -0x58, 0x1C, 0x44, 0xAC, 0x5C, 0x1C, 0x43, 0xAC, 0x68, 0x0C, 0x04, 0x24, -0x6C, 0x0C, 0x03, 0x24, 0x60, 0x1C, 0x44, 0xAC, 0x64, 0x1C, 0x43, 0xAC, -0x2C, 0x0C, 0x04, 0x24, 0x28, 0x0C, 0x03, 0x24, 0x6C, 0x08, 0x05, 0x24, -0x68, 0x1C, 0x44, 0xAC, 0x6C, 0x1C, 0x43, 0xAC, 0x98, 0x0C, 0x04, 0x24, -0x9C, 0x0C, 0x03, 0x24, 0x31, 0x1C, 0x46, 0xA0, 0x40, 0x1C, 0x45, 0xAC, -0x70, 0x1C, 0x44, 0xAC, 0x74, 0x1C, 0x43, 0xAC, 0x5B, 0x43, 0x00, 0x08, -0x3C, 0x1C, 0x45, 0xAC, 0x31, 0x43, 0x00, 0x08, 0x78, 0x1C, 0x02, 0xAE, -0xBA, 0x43, 0x00, 0x08, 0x21, 0x18, 0x00, 0x00, 0x20, 0x00, 0x62, 0x2C, -0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x64, 0x00, -0x01, 0x00, 0x42, 0x30, 0xFA, 0xFF, 0x40, 0x10, 0x01, 0x00, 0x63, 0x24, -0xFF, 0xFF, 0x63, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, -0xD8, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF, 0xFF, 0xFF, 0x02, 0x24, -0x21, 0x88, 0xA0, 0x00, 0x1C, 0x00, 0xB3, 0xAF, 0x18, 0x00, 0xB2, 0xAF, -0x20, 0x00, 0xBF, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x21, 0x90, 0xC0, 0x00, -0x21, 0x28, 0xC0, 0x00, 0x0B, 0x00, 0x22, 0x12, 0x21, 0x98, 0x80, 0x00, -0x26, 0x5C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x20, 0x02, -0xB5, 0x43, 0x00, 0x0C, 0x21, 0x80, 0x40, 0x00, 0x27, 0x28, 0x11, 0x00, -0x24, 0x28, 0xB0, 0x00, 0x04, 0x10, 0x52, 0x00, 0x25, 0x28, 0xA2, 0x00, -0x21, 0x20, 0x60, 0x02, 0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, -0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x03, 0x5C, 0x00, 0x08, 0x28, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, -0x21, 0x30, 0x80, 0x00, 0xA4, 0x37, 0x44, 0x8C, 0xC1, 0x43, 0x00, 0x08, -0xFF, 0xFF, 0x05, 0x24, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xBF, 0xAF, -0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x26, 0x5C, 0x00, 0x0C, -0x21, 0x88, 0xA0, 0x00, 0x21, 0x80, 0x40, 0x00, 0xB5, 0x43, 0x00, 0x0C, -0x21, 0x20, 0x20, 0x02, 0x24, 0x80, 0x11, 0x02, 0x06, 0x10, 0x50, 0x00, -0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27, -0x18, 0x00, 0xB2, 0xAF, 0x02, 0x80, 0x12, 0x3C, 0x60, 0x1B, 0x52, 0x26, -0x14, 0x00, 0xB1, 0xAF, 0x21, 0x88, 0x80, 0x00, 0x24, 0x08, 0x04, 0x24, -0x24, 0x00, 0xBF, 0xAF, 0x20, 0x00, 0xB4, 0xAF, 0x1C, 0x00, 0xB3, 0xAF, -0x26, 0x5C, 0x00, 0x0C, 0x10, 0x00, 0xB0, 0xAF, 0x58, 0x1C, 0x44, 0x8E, -0x21, 0xA0, 0x40, 0x00, 0x26, 0x5C, 0x00, 0x0C, 0xC0, 0x8D, 0x11, 0x00, -0xFF, 0x7F, 0x05, 0x3C, 0x7F, 0x80, 0x03, 0x3C, 0xFF, 0xFF, 0xA5, 0x34, -0xFF, 0xFF, 0x63, 0x34, 0x24, 0x28, 0x85, 0x02, 0x24, 0x08, 0x04, 0x24, -0x03, 0x5C, 0x00, 0x0C, 0x24, 0x80, 0x43, 0x00, 0x2C, 0x1F, 0x00, 0x0C, -0x01, 0x00, 0x04, 0x24, 0x00, 0x80, 0x13, 0x3C, 0x58, 0x1C, 0x44, 0x8E, -0x25, 0x80, 0x11, 0x02, 0x25, 0x80, 0x13, 0x02, 0x03, 0x5C, 0x00, 0x0C, -0x21, 0x28, 0x00, 0x02, 0x2C, 0x1F, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24, -0x25, 0x28, 0x93, 0x02, 0x03, 0x5C, 0x00, 0x0C, 0x24, 0x08, 0x04, 0x24, -0x2C, 0x1F, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24, 0x78, 0x1C, 0x44, 0x8E, -0x0F, 0x00, 0x05, 0x3C, 0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB4, 0x8F, -0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0xFF, 0xFF, 0xA5, 0x34, 0xE3, 0x43, 0x00, 0x08, -0x28, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF, -0x02, 0x80, 0x11, 0x3C, 0x10, 0x00, 0xB0, 0xAF, 0x18, 0x00, 0xBF, 0xAF, -0x60, 0x1B, 0x27, 0x26, 0x33, 0x1C, 0xE5, 0x90, 0x01, 0x80, 0x03, 0x3C, -0x25, 0xB0, 0x02, 0x3C, 0x94, 0x10, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34, -0x02, 0x00, 0x06, 0x24, 0x00, 0x00, 0x43, 0xAC, 0x34, 0x00, 0xA6, 0x10, -0x21, 0x80, 0x80, 0x00, 0x03, 0x00, 0x03, 0x24, 0x3A, 0x00, 0xA3, 0x10, -0x2E, 0x00, 0x02, 0x2E, 0x10, 0x00, 0x02, 0x2E, 0x07, 0x00, 0x40, 0x10, -0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x04, 0x32, 0x18, 0x00, 0xBF, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0xF3, 0x43, 0x00, 0x08, -0x20, 0x00, 0xBD, 0x27, 0xFA, 0xFF, 0xA6, 0x14, 0xFF, 0x00, 0x04, 0x32, -0x31, 0x1C, 0xE4, 0x90, 0x01, 0x00, 0x02, 0x24, 0x33, 0x00, 0x82, 0x10, -0x02, 0x00, 0x82, 0x28, 0x38, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x38, 0x00, 0x85, 0x10, 0x60, 0x1B, 0x22, 0x26, 0x2E, 0x00, 0x83, 0x10, -0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x24, 0xE3, 0x43, 0x00, 0x0C, -0xFF, 0xFF, 0x05, 0x24, 0xFF, 0xFC, 0x06, 0x3C, 0xFF, 0xFF, 0xC6, 0x34, -0x24, 0x30, 0x46, 0x00, 0x00, 0x08, 0x04, 0x24, 0xC1, 0x43, 0x00, 0x0C, -0xFF, 0xFF, 0x05, 0x24, 0x60, 0x1B, 0x22, 0x26, 0x31, 0x1C, 0x44, 0x90, -0x01, 0x00, 0x03, 0x24, 0x07, 0x00, 0x83, 0x10, 0x02, 0x00, 0x82, 0x28, -0x2C, 0x00, 0x40, 0x14, 0x02, 0x00, 0x02, 0x24, 0x2C, 0x00, 0x82, 0x10, -0x03, 0x00, 0x02, 0x24, 0xDB, 0xFF, 0x82, 0x14, 0x00, 0x00, 0x00, 0x00, -0x60, 0x1B, 0x22, 0x26, 0x34, 0x1C, 0x44, 0x8C, 0x0F, 0x00, 0x05, 0x3C, -0xC1, 0x43, 0x00, 0x0C, 0x21, 0x30, 0x00, 0x00, 0x3B, 0x44, 0x00, 0x08, -0xFF, 0x00, 0x04, 0x32, 0x25, 0x00, 0x82, 0x2C, 0xCC, 0xFF, 0x40, 0x14, -0x03, 0x00, 0x03, 0x24, 0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x20, 0x00, 0xBD, 0x27, 0xC7, 0xFF, 0x40, 0x14, 0x10, 0x00, 0x02, 0x2E, -0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0x60, 0x1B, 0x22, 0x26, 0x34, 0x1C, 0x44, 0x8C, 0x0F, 0x00, 0x05, 0x3C, -0xC1, 0x43, 0x00, 0x0C, 0x0F, 0x00, 0x06, 0x24, 0x4D, 0x44, 0x00, 0x08, -0x00, 0x08, 0x04, 0x24, 0xCC, 0xFF, 0x80, 0x14, 0x60, 0x1B, 0x22, 0x26, -0x34, 0x1C, 0x44, 0x8C, 0x0F, 0x00, 0x05, 0x24, 0xC1, 0x43, 0x00, 0x0C, -0x0F, 0x00, 0x06, 0x24, 0x4D, 0x44, 0x00, 0x08, 0x00, 0x08, 0x04, 0x24, -0xB2, 0xFF, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x22, 0x26, -0x34, 0x1C, 0x44, 0x8C, 0x0F, 0x00, 0x05, 0x24, 0xC1, 0x43, 0x00, 0x0C, -0x21, 0x30, 0x00, 0x00, 0x3B, 0x44, 0x00, 0x08, 0xFF, 0x00, 0x04, 0x32, -0xE0, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF, 0x02, 0x80, 0x11, 0x3C, -0x60, 0x1B, 0x28, 0x26, 0x33, 0x1C, 0x06, 0x91, 0x01, 0x80, 0x03, 0x3C, -0x25, 0xB0, 0x02, 0x3C, 0x40, 0x12, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34, -0x02, 0x00, 0x07, 0x24, 0x18, 0x00, 0xB2, 0xAF, 0x10, 0x00, 0xB0, 0xAF, -0x1C, 0x00, 0xBF, 0xAF, 0x00, 0x00, 0x43, 0xAC, 0x21, 0x90, 0xA0, 0x00, -0x39, 0x00, 0xC7, 0x10, 0xFF, 0x00, 0x90, 0x30, 0x03, 0x00, 0x03, 0x24, -0x3F, 0x00, 0xC3, 0x10, 0x2E, 0x00, 0x02, 0x2E, 0x10, 0x00, 0x02, 0x2E, -0x0C, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x04, 0x3C, -0xFF, 0xFF, 0x84, 0x34, 0x24, 0x20, 0x44, 0x02, 0x00, 0x15, 0x10, 0x00, -0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x25, 0x20, 0x44, 0x00, 0xDE, 0x43, 0x00, 0x08, -0x20, 0x00, 0xBD, 0x27, 0xF5, 0xFF, 0xC7, 0x14, 0x0F, 0x00, 0x04, 0x3C, -0x31, 0x1C, 0x04, 0x91, 0x01, 0x00, 0x02, 0x24, 0x33, 0x00, 0x82, 0x10, -0x02, 0x00, 0x82, 0x28, 0x38, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x38, 0x00, 0x86, 0x10, 0x60, 0x1B, 0x22, 0x26, 0x2E, 0x00, 0x83, 0x10, -0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x24, 0xE3, 0x43, 0x00, 0x0C, -0xFF, 0xFF, 0x05, 0x24, 0xFF, 0xFC, 0x06, 0x3C, 0xFF, 0xFF, 0xC6, 0x34, -0x24, 0x30, 0x46, 0x00, 0x00, 0x08, 0x04, 0x24, 0xC1, 0x43, 0x00, 0x0C, -0xFF, 0xFF, 0x05, 0x24, 0x60, 0x1B, 0x22, 0x26, 0x31, 0x1C, 0x44, 0x90, -0x01, 0x00, 0x03, 0x24, 0x07, 0x00, 0x83, 0x10, 0x02, 0x00, 0x82, 0x28, -0x2C, 0x00, 0x40, 0x14, 0x02, 0x00, 0x02, 0x24, 0x2C, 0x00, 0x82, 0x10, -0x03, 0x00, 0x02, 0x24, 0xD6, 0xFF, 0x82, 0x14, 0x00, 0x00, 0x00, 0x00, -0x60, 0x1B, 0x22, 0x26, 0x34, 0x1C, 0x44, 0x8C, 0x0F, 0x00, 0x05, 0x3C, -0xC1, 0x43, 0x00, 0x0C, 0x21, 0x30, 0x00, 0x00, 0xA8, 0x44, 0x00, 0x08, -0x0F, 0x00, 0x04, 0x3C, 0x25, 0x00, 0x02, 0x2E, 0xC7, 0xFF, 0x40, 0x14, -0x03, 0x00, 0x03, 0x24, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x20, 0x00, 0xBD, 0x27, 0xC1, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0x60, 0x1B, 0x22, 0x26, 0x34, 0x1C, 0x44, 0x8C, 0x0F, 0x00, 0x05, 0x3C, -0xC1, 0x43, 0x00, 0x0C, 0x0F, 0x00, 0x06, 0x24, 0xBF, 0x44, 0x00, 0x08, -0x00, 0x08, 0x04, 0x24, 0xCC, 0xFF, 0x80, 0x14, 0x60, 0x1B, 0x22, 0x26, -0x34, 0x1C, 0x44, 0x8C, 0x0F, 0x00, 0x05, 0x24, 0xC1, 0x43, 0x00, 0x0C, -0x0F, 0x00, 0x06, 0x24, 0xBF, 0x44, 0x00, 0x08, 0x00, 0x08, 0x04, 0x24, -0xAD, 0xFF, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x22, 0x26, -0x34, 0x1C, 0x44, 0x8C, 0x0F, 0x00, 0x05, 0x24, 0xC1, 0x43, 0x00, 0x0C, -0x21, 0x30, 0x00, 0x00, 0xA8, 0x44, 0x00, 0x08, 0x0F, 0x00, 0x04, 0x3C, -0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0x80, 0x00, -0x14, 0x00, 0xBF, 0xAF, 0xF3, 0x43, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x00, -0x40, 0x01, 0x44, 0x34, 0x21, 0x18, 0x40, 0x00, 0x1F, 0x00, 0x02, 0x2E, -0x00, 0x23, 0x04, 0x00, 0x10, 0x00, 0x40, 0x10, 0x10, 0x00, 0x05, 0x2E, -0x00, 0x01, 0x64, 0x34, 0x06, 0x00, 0xA0, 0x10, 0x00, 0x23, 0x04, 0x00, -0x21, 0x10, 0x00, 0x02, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xDE, 0x43, 0x00, 0x0C, -0xF1, 0xFF, 0x10, 0x26, 0x21, 0x10, 0x00, 0x02, 0x14, 0x00, 0xBF, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, -0xDE, 0x43, 0x00, 0x0C, 0xE2, 0xFF, 0x10, 0x26, 0x21, 0x10, 0x00, 0x02, -0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27, 0x25, 0xB0, 0x02, 0x3C, -0x18, 0x00, 0xBF, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, -0x21, 0x20, 0x82, 0x00, 0x00, 0x00, 0x90, 0x8C, 0x21, 0x88, 0xA0, 0x00, -0xB5, 0x43, 0x00, 0x0C, 0x21, 0x20, 0xA0, 0x00, 0x24, 0x80, 0x11, 0x02, -0x06, 0x10, 0x50, 0x00, 0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0xD8, 0xFF, 0xBD, 0x27, 0x25, 0xB0, 0x02, 0x3C, 0x18, 0x00, 0xB2, 0xAF, -0x21, 0x90, 0x82, 0x00, 0xFF, 0xFF, 0x02, 0x24, 0x1C, 0x00, 0xB3, 0xAF, -0x14, 0x00, 0xB1, 0xAF, 0x20, 0x00, 0xBF, 0xAF, 0x10, 0x00, 0xB0, 0xAF, -0x21, 0x88, 0xA0, 0x00, 0x21, 0x20, 0xA0, 0x00, 0x21, 0x18, 0x40, 0x02, -0x10, 0x00, 0xA2, 0x10, 0x21, 0x98, 0xC0, 0x00, 0x00, 0x00, 0x50, 0x8E, -0xB5, 0x43, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x27, 0x18, 0x11, 0x00, -0x24, 0x18, 0x70, 0x00, 0x04, 0x10, 0x53, 0x00, 0x25, 0x18, 0x62, 0x00, -0x00, 0x00, 0x43, 0xAE, 0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, -0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, 0x20, 0x00, 0xBF, 0x8F, -0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x28, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x66, 0xAC, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x02, 0x3C, -0x21, 0x38, 0x82, 0x00, 0xFF, 0xFF, 0x02, 0x24, 0x27, 0x40, 0x05, 0x00, -0x08, 0x00, 0xA2, 0x10, 0x24, 0x18, 0xC5, 0x00, 0x00, 0x00, 0xE2, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x02, 0x01, 0x25, 0x10, 0x43, 0x00, -0x00, 0x00, 0xE2, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xE6, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0xE0, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, 0xFF, 0xFF, 0x02, 0x24, -0x21, 0x80, 0xA0, 0x00, 0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF, -0x1C, 0x00, 0xBF, 0xAF, 0x21, 0x88, 0xC0, 0x00, 0x21, 0x28, 0xC0, 0x00, -0x08, 0x00, 0x02, 0x12, 0x21, 0x90, 0x80, 0x00, 0x26, 0x5C, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x27, 0x28, 0x10, 0x00, 0x24, 0x28, 0xA2, 0x00, -0x24, 0x10, 0x30, 0x02, 0x25, 0x28, 0xA2, 0x00, 0x21, 0x20, 0x40, 0x02, -0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x03, 0x5C, 0x00, 0x08, 0x20, 0x00, 0xBD, 0x27, -0x01, 0x80, 0x02, 0x3C, 0x25, 0xB0, 0x03, 0x3C, 0xD0, 0xFF, 0xBD, 0x27, -0x0C, 0x16, 0x42, 0x24, 0x18, 0x03, 0x63, 0x34, 0x20, 0x00, 0xB2, 0xAF, -0x00, 0x00, 0x62, 0xAC, 0x21, 0x90, 0x80, 0x00, 0x10, 0x00, 0xA4, 0x27, -0x24, 0x00, 0xB3, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, 0x21, 0x98, 0xC0, 0x00, -0x21, 0x88, 0xA0, 0x00, 0x28, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C, -0x18, 0x00, 0xB0, 0xAF, 0x0F, 0x00, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, -0x21, 0x20, 0x40, 0x02, 0x0A, 0x00, 0x22, 0x12, 0x21, 0x28, 0x60, 0x02, -0x25, 0x44, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x20, 0x02, -0xB5, 0x43, 0x00, 0x0C, 0x21, 0x80, 0x40, 0x00, 0x27, 0x28, 0x11, 0x00, -0x24, 0x28, 0xB0, 0x00, 0x04, 0x10, 0x53, 0x00, 0x25, 0x28, 0xA2, 0x00, -0x90, 0x44, 0x00, 0x0C, 0xFF, 0x00, 0x44, 0x32, 0x90, 0x40, 0x00, 0x0C, -0x10, 0x00, 0xA4, 0x27, 0x28, 0x00, 0xBF, 0x8F, 0x24, 0x00, 0xB3, 0x8F, -0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, 0x01, 0x80, 0x03, 0x3C, -0x25, 0xB0, 0x02, 0x3C, 0xB0, 0x16, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34, -0xE0, 0xFF, 0xBD, 0x27, 0x00, 0x00, 0x43, 0xAC, 0x18, 0x00, 0xBF, 0xAF, -0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x25, 0x44, 0x00, 0x0C, -0x21, 0x88, 0xA0, 0x00, 0x21, 0x80, 0x40, 0x00, 0xB5, 0x43, 0x00, 0x0C, -0x21, 0x20, 0x20, 0x02, 0x24, 0x80, 0x11, 0x02, 0x06, 0x10, 0x50, 0x00, -0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0xD0, 0xFF, 0xBD, 0x27, -0x24, 0x00, 0xB5, 0xAF, 0xFF, 0x00, 0x84, 0x30, 0x21, 0xA8, 0xC0, 0x00, -0x28, 0x00, 0xB6, 0xAF, 0x1C, 0x00, 0xB3, 0xAF, 0x2C, 0x00, 0xBF, 0xAF, -0x20, 0x00, 0xB4, 0xAF, 0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF, -0x10, 0x00, 0xB0, 0xAF, 0x21, 0xB0, 0xA0, 0x00, 0xF0, 0x42, 0x00, 0x0C, -0x21, 0x98, 0x00, 0x00, 0x21, 0x00, 0xA0, 0x16, 0x80, 0x10, 0x13, 0x00, -0xFF, 0x45, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x02, 0x24, -0x23, 0x00, 0x02, 0x12, 0x05, 0x00, 0x04, 0x24, 0xFC, 0x00, 0x02, 0x24, -0x37, 0x00, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0xFB, 0x00, 0x02, 0x24, -0x30, 0x00, 0x02, 0x12, 0x32, 0x00, 0x04, 0x24, 0xFA, 0x00, 0x02, 0x24, -0x2D, 0x00, 0x02, 0x12, 0x05, 0x00, 0x04, 0x24, 0xF9, 0x00, 0x02, 0x24, -0x29, 0x00, 0x02, 0x12, 0x0F, 0x00, 0x05, 0x3C, 0x04, 0x00, 0xD1, 0x8C, -0xFF, 0xFF, 0xA5, 0x34, 0x21, 0x20, 0x00, 0x02, 0x83, 0x45, 0x00, 0x0C, -0x21, 0x30, 0x20, 0x02, 0x2C, 0x1F, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24, -0x19, 0x00, 0x02, 0x24, 0x28, 0x00, 0x02, 0x12, 0x21, 0x90, 0x00, 0x00, -0x02, 0x00, 0x62, 0x26, 0xFF, 0x00, 0x53, 0x30, 0x2B, 0x18, 0x75, 0x02, -0x0F, 0x00, 0x60, 0x10, 0x80, 0x10, 0x13, 0x00, 0x21, 0x30, 0x56, 0x00, -0x00, 0x00, 0xD0, 0x8C, 0xFF, 0x00, 0x02, 0x24, 0x0A, 0x00, 0x02, 0x12, -0xFE, 0x00, 0x02, 0x24, 0xDC, 0xFF, 0x02, 0x16, 0x32, 0x00, 0x04, 0x24, -0x2C, 0x1F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x62, 0x26, -0xFF, 0x00, 0x53, 0x30, 0x2B, 0x18, 0x75, 0x02, 0xF3, 0xFF, 0x60, 0x14, -0x80, 0x10, 0x13, 0x00, 0x2C, 0x00, 0xBF, 0x8F, 0x28, 0x00, 0xB6, 0x8F, -0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, -0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, -0x01, 0x00, 0x04, 0x24, 0x5B, 0x1F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0xED, 0x45, 0x00, 0x08, 0x02, 0x00, 0x62, 0x26, 0x2C, 0x1F, 0x00, 0x0C, -0x01, 0x00, 0x04, 0x24, 0xFB, 0x45, 0x00, 0x08, 0x02, 0x00, 0x62, 0x26, -0x0F, 0x00, 0x14, 0x3C, 0x21, 0x20, 0x00, 0x02, 0xAC, 0x45, 0x00, 0x0C, -0xFF, 0xFF, 0x85, 0x36, 0x21, 0x20, 0x00, 0x02, 0xFF, 0xFF, 0x85, 0x36, -0xD2, 0xFF, 0x51, 0x10, 0x21, 0x30, 0x20, 0x02, 0x83, 0x45, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x2C, 0x1F, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24, -0x01, 0x00, 0x42, 0x26, 0xFF, 0x00, 0x52, 0x30, 0x0A, 0x00, 0x43, 0x2E, -0xF2, 0xFF, 0x60, 0x14, 0x21, 0x20, 0x00, 0x02, 0xF0, 0x42, 0x00, 0x0C, -0x21, 0x20, 0x00, 0x00, 0x2C, 0x00, 0xBF, 0x8F, 0x28, 0x00, 0xB6, 0x8F, -0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, -0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, -0xB0, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, 0x4C, 0x00, 0xBF, 0xAF, -0x48, 0x00, 0xBE, 0xAF, 0x40, 0x00, 0xB6, 0xAF, 0x3C, 0x00, 0xB5, 0xAF, -0x38, 0x00, 0xB4, 0xAF, 0x34, 0x00, 0xB3, 0xAF, 0x30, 0x00, 0xB2, 0xAF, -0x2C, 0x00, 0xB1, 0xAF, 0x28, 0x00, 0xB0, 0xAF, 0x60, 0x1B, 0x55, 0x24, -0x44, 0x00, 0xB7, 0xAF, 0x58, 0x38, 0xA3, 0x96, 0x02, 0x80, 0x02, 0x3C, -0x02, 0x80, 0x05, 0x3C, 0x25, 0x98, 0x62, 0x00, 0x90, 0xDE, 0xA5, 0x24, -0x24, 0x00, 0x64, 0x26, 0x06, 0x00, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C, -0x20, 0x00, 0x60, 0xA6, 0x02, 0x80, 0x05, 0x3C, 0x48, 0x37, 0xA5, 0x24, -0x2A, 0x00, 0x64, 0x26, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, -0x02, 0x80, 0x05, 0x3C, 0xB4, 0x55, 0xA5, 0x24, 0x06, 0x00, 0x06, 0x24, -0xF4, 0x54, 0x00, 0x0C, 0x30, 0x00, 0x64, 0x26, 0x20, 0x00, 0x63, 0x96, -0x02, 0x80, 0x02, 0x3C, 0xB0, 0x55, 0x42, 0x24, 0x03, 0xFF, 0x63, 0x30, -0x80, 0x00, 0x63, 0x34, 0x74, 0x00, 0x54, 0x24, 0x20, 0x00, 0x63, 0xA6, -0x21, 0x20, 0x80, 0x02, 0x20, 0x00, 0x02, 0x24, 0x40, 0x00, 0x72, 0x26, -0xFB, 0x51, 0x00, 0x0C, 0x1C, 0x00, 0xA2, 0xAF, 0x21, 0x28, 0x40, 0x00, -0x21, 0x20, 0x40, 0x02, 0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x06, 0x24, -0x1C, 0x00, 0xA2, 0x8F, 0x21, 0x20, 0x80, 0x02, 0x42, 0x00, 0x72, 0x26, -0x02, 0x00, 0x42, 0x24, 0x16, 0x52, 0x00, 0x0C, 0x1C, 0x00, 0xA2, 0xAF, -0x21, 0x28, 0x40, 0x00, 0x21, 0x20, 0x40, 0x02, 0xF4, 0x54, 0x00, 0x0C, -0x02, 0x00, 0x06, 0x24, 0x02, 0x80, 0x03, 0x3C, 0xB0, 0x55, 0x63, 0x24, -0x1C, 0x00, 0xA2, 0x8F, 0x0C, 0x00, 0x66, 0x8C, 0x60, 0x00, 0x71, 0x24, -0x1C, 0x00, 0xB0, 0x27, 0x10, 0x00, 0x67, 0x24, 0x21, 0x28, 0x00, 0x00, -0x02, 0x00, 0x42, 0x24, 0x44, 0x00, 0x64, 0x26, 0x1C, 0x00, 0xA2, 0xAF, -0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB0, 0xAF, 0x21, 0x20, 0x20, 0x02, -0x1B, 0x53, 0x00, 0x0C, 0x21, 0x90, 0x40, 0x00, 0x21, 0xB0, 0x40, 0x00, -0x08, 0x00, 0x06, 0x24, 0x09, 0x00, 0x42, 0x2C, 0x21, 0x20, 0x40, 0x02, -0x21, 0x38, 0x20, 0x02, 0x0B, 0x30, 0xC2, 0x02, 0x01, 0x00, 0x05, 0x24, -0x20, 0x00, 0xA2, 0xAF, 0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB0, 0xAF, -0x02, 0x80, 0x03, 0x3C, 0xB0, 0x55, 0x63, 0x24, 0x48, 0x00, 0x67, 0x24, -0x21, 0x20, 0x40, 0x00, 0x03, 0x00, 0x05, 0x24, 0x01, 0x00, 0x06, 0x24, -0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB0, 0xAF, 0x21, 0x20, 0x40, 0x00, -0x06, 0x00, 0x05, 0x24, 0x02, 0x00, 0x06, 0x24, 0x18, 0x00, 0xA7, 0x27, -0x18, 0x00, 0xA0, 0xA7, 0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB0, 0xAF, -0x18, 0x00, 0xA5, 0x97, 0x02, 0x80, 0x04, 0x3C, 0x58, 0xE8, 0x84, 0x24, -0x13, 0x58, 0x00, 0x0C, 0x21, 0x90, 0x40, 0x00, 0xC0, 0x3A, 0xA2, 0x8E, -0x0C, 0x00, 0x11, 0x24, 0x2B, 0x10, 0x22, 0x02, 0x3B, 0x00, 0x40, 0x10, -0x21, 0xF0, 0x00, 0x02, 0x02, 0x80, 0x02, 0x3C, 0x21, 0x80, 0x80, 0x02, -0xAA, 0x46, 0x00, 0x08, 0x26, 0x56, 0x57, 0x24, 0x21, 0x10, 0x30, 0x02, -0x01, 0x00, 0x43, 0x90, 0xC0, 0x3A, 0xA4, 0x8E, 0x21, 0x18, 0x71, 0x00, -0x02, 0x00, 0x71, 0x24, 0x2B, 0x20, 0x24, 0x02, 0x2F, 0x00, 0x80, 0x10, -0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x30, 0x02, 0x00, 0x00, 0x47, 0x90, -0x02, 0x80, 0x14, 0x3C, 0x2D, 0x00, 0x03, 0x24, 0x21, 0x28, 0x37, 0x02, -0x64, 0x5C, 0x84, 0x26, 0xF1, 0xFF, 0xE3, 0x14, 0x20, 0x00, 0x06, 0x24, -0xF4, 0x54, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x04, 0x41, 0xA3, 0x96, -0x02, 0x80, 0x02, 0x3C, 0xC6, 0x5C, 0x47, 0x90, 0xBD, 0xFF, 0x63, 0x30, -0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0x0C, 0x00, 0x63, 0x34, -0x01, 0x00, 0xE7, 0x30, 0x44, 0xDF, 0xA5, 0x24, 0x67, 0x5C, 0x44, 0x24, -0x10, 0x00, 0x06, 0x24, 0x06, 0x00, 0xE0, 0x14, 0x04, 0x41, 0xA3, 0xA6, -0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0x54, 0xDF, 0xA5, 0x24, -0x67, 0x5C, 0x64, 0x24, 0x10, 0x00, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x30, 0x02, 0x01, 0x00, 0x46, 0x90, -0x21, 0x20, 0x40, 0x02, 0x64, 0x5C, 0x87, 0x26, 0x2D, 0x00, 0x05, 0x24, -0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xBE, 0xAF, 0x21, 0x90, 0x40, 0x00, -0x21, 0x10, 0x30, 0x02, 0x01, 0x00, 0x43, 0x90, 0xC0, 0x3A, 0xA4, 0x8E, -0x21, 0x18, 0x71, 0x00, 0x02, 0x00, 0x71, 0x24, 0x2B, 0x20, 0x24, 0x02, -0xD4, 0xFF, 0x80, 0x14, 0x21, 0x10, 0x30, 0x02, 0x20, 0x00, 0xA2, 0x8F, -0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x40, 0x10, 0x02, 0x80, 0x03, 0x3C, -0x1C, 0x00, 0xA2, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x42, 0x24, -0x01, 0x01, 0x42, 0x2C, 0x1A, 0x00, 0x40, 0x14, 0x21, 0x20, 0x60, 0x02, -0x4C, 0x00, 0xBF, 0x8F, 0x48, 0x00, 0xBE, 0x8F, 0x44, 0x00, 0xB7, 0x8F, -0x40, 0x00, 0xB6, 0x8F, 0x3C, 0x00, 0xB5, 0x8F, 0x38, 0x00, 0xB4, 0x8F, -0x34, 0x00, 0xB3, 0x8F, 0x30, 0x00, 0xB2, 0x8F, 0x2C, 0x00, 0xB1, 0x8F, -0x28, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x50, 0x00, 0xBD, 0x27, -0xB0, 0x55, 0x63, 0x24, 0x21, 0x20, 0x40, 0x02, 0xF8, 0xFF, 0xC6, 0x26, -0x68, 0x00, 0x67, 0x24, 0x32, 0x00, 0x05, 0x24, 0x25, 0x52, 0x00, 0x0C, -0x10, 0x00, 0xBE, 0xAF, 0x1C, 0x00, 0xA2, 0x8F, 0x00, 0x00, 0x00, 0x00, -0x20, 0x00, 0x42, 0x24, 0x01, 0x01, 0x42, 0x2C, 0xE8, 0xFF, 0x40, 0x10, -0x21, 0x20, 0x60, 0x02, 0x21, 0x28, 0x00, 0x00, 0xEC, 0x54, 0x00, 0x0C, -0x08, 0x00, 0x06, 0x24, 0x08, 0x00, 0x64, 0x8E, 0x04, 0x00, 0x65, 0x8E, -0xFF, 0xDF, 0x02, 0x3C, 0x10, 0x00, 0x66, 0x8E, 0x14, 0x00, 0x67, 0x8E, -0xFF, 0xFF, 0x42, 0x34, 0x1C, 0x00, 0xA8, 0x8F, 0x24, 0x20, 0x82, 0x00, -0x00, 0x40, 0x03, 0x3C, 0xFF, 0xE0, 0x02, 0x24, 0x24, 0x28, 0xA2, 0x00, -0x25, 0x20, 0x83, 0x00, 0x00, 0x80, 0x02, 0x3C, 0xFF, 0x81, 0x03, 0x24, -0x25, 0x30, 0xC2, 0x00, 0x24, 0x38, 0xE3, 0x00, 0x00, 0x10, 0xA5, 0x34, -0x02, 0x80, 0x03, 0x3C, 0x80, 0x00, 0x84, 0x34, 0x20, 0x00, 0x02, 0x24, -0x08, 0x00, 0x64, 0xAE, 0x00, 0x00, 0x68, 0xA6, 0x02, 0x00, 0x62, 0xA2, -0x14, 0x00, 0x67, 0xAE, 0x04, 0x00, 0x65, 0xAE, 0x10, 0x00, 0x66, 0xAE, -0x60, 0x1B, 0x62, 0x24, 0xEC, 0x37, 0x46, 0x8C, 0x58, 0x38, 0x45, 0x8C, -0x01, 0x00, 0x04, 0x24, 0x00, 0x01, 0x07, 0x24, 0x01, 0x00, 0x02, 0x24, -0x1E, 0x01, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF, 0x5B, 0x01, 0x00, 0x0C, -0x01, 0x00, 0x04, 0x24, 0x4C, 0x00, 0xBF, 0x8F, 0x48, 0x00, 0xBE, 0x8F, -0x44, 0x00, 0xB7, 0x8F, 0x40, 0x00, 0xB6, 0x8F, 0x3C, 0x00, 0xB5, 0x8F, -0x38, 0x00, 0xB4, 0x8F, 0x34, 0x00, 0xB3, 0x8F, 0x30, 0x00, 0xB2, 0x8F, -0x2C, 0x00, 0xB1, 0x8F, 0x28, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x50, 0x00, 0xBD, 0x27, 0xA0, 0xFF, 0xBD, 0x27, 0x5C, 0x00, 0xBF, 0xAF, -0x58, 0x00, 0xBE, 0xAF, 0x54, 0x00, 0xB7, 0xAF, 0x50, 0x00, 0xB6, 0xAF, -0x4C, 0x00, 0xB5, 0xAF, 0x48, 0x00, 0xB4, 0xAF, 0x44, 0x00, 0xB3, 0xAF, -0x40, 0x00, 0xB2, 0xAF, 0x3C, 0x00, 0xB1, 0xAF, 0x38, 0x00, 0xB0, 0xAF, -0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x0B, 0x3C, 0x64, 0xE8, 0x82, 0x24, -0x78, 0xE8, 0x63, 0x25, 0x78, 0xE8, 0x6B, 0x91, 0x01, 0x00, 0x45, 0x90, -0x0D, 0x00, 0x48, 0x90, 0x0C, 0x00, 0x58, 0x90, 0x64, 0xE8, 0x97, 0x90, -0x02, 0x00, 0x54, 0x90, 0x0E, 0x00, 0x50, 0x90, 0x01, 0x00, 0x69, 0x90, -0x30, 0x00, 0xAB, 0xAF, 0x03, 0x00, 0x4B, 0x90, 0x04, 0x00, 0x76, 0x90, -0x05, 0x00, 0x6A, 0x90, 0x02, 0x00, 0x6F, 0x90, 0x06, 0x00, 0x64, 0x90, -0x07, 0x00, 0x75, 0x90, 0x03, 0x00, 0x71, 0x90, 0x00, 0x2A, 0x05, 0x00, -0x30, 0x00, 0xA3, 0x8F, 0x00, 0x42, 0x08, 0x00, 0x25, 0x40, 0x18, 0x01, -0x25, 0x28, 0xB7, 0x00, 0x00, 0xA4, 0x14, 0x00, 0x00, 0x84, 0x10, 0x00, -0x25, 0xA0, 0x85, 0x02, 0x25, 0x80, 0x08, 0x02, 0x00, 0x4A, 0x09, 0x00, -0x00, 0x5E, 0x0B, 0x00, 0x02, 0x80, 0x08, 0x3C, 0x05, 0x00, 0x46, 0x90, -0x09, 0x00, 0x47, 0x90, 0x25, 0x48, 0x23, 0x01, 0x00, 0x52, 0x0A, 0x00, -0x60, 0x1B, 0x03, 0x25, 0x25, 0x58, 0x74, 0x01, 0x04, 0x00, 0x5E, 0x90, -0x06, 0x00, 0x53, 0x90, 0x08, 0x00, 0x59, 0x90, 0x0A, 0x00, 0x52, 0x90, -0x07, 0x00, 0x4C, 0x90, 0x0B, 0x00, 0x4D, 0x90, 0x0F, 0x00, 0x4E, 0x90, -0x11, 0x00, 0x58, 0x90, 0x25, 0x50, 0x56, 0x01, 0x10, 0x00, 0x56, 0x90, -0x10, 0x00, 0xAB, 0xAF, 0x06, 0x41, 0x62, 0x90, 0x00, 0x32, 0x06, 0x00, -0x00, 0x3A, 0x07, 0x00, 0x00, 0x7C, 0x0F, 0x00, 0x00, 0x24, 0x04, 0x00, -0x25, 0x30, 0xDE, 0x00, 0x25, 0x38, 0xF9, 0x00, 0x25, 0x20, 0x8A, 0x00, -0x1C, 0x00, 0x43, 0x30, 0x00, 0x9C, 0x13, 0x00, 0x00, 0x94, 0x12, 0x00, -0x25, 0x78, 0xE9, 0x01, 0x00, 0x8E, 0x11, 0x00, 0x00, 0xAE, 0x15, 0x00, -0x25, 0x98, 0x66, 0x02, 0x25, 0x90, 0x47, 0x02, 0x03, 0x00, 0x46, 0x30, -0x25, 0xA8, 0xA4, 0x02, 0x25, 0x88, 0x2F, 0x02, 0x10, 0x00, 0xA7, 0x27, -0x83, 0x18, 0x03, 0x00, 0x02, 0x00, 0xC4, 0x24, 0x28, 0x00, 0xB1, 0xAF, -0x2C, 0x00, 0xB5, 0xAF, 0x21, 0x18, 0xE3, 0x00, 0x01, 0x00, 0x02, 0x24, -0x04, 0x10, 0x82, 0x00, 0x18, 0x00, 0x65, 0x90, 0xFF, 0x00, 0x46, 0x30, -0x00, 0x66, 0x0C, 0x00, 0x00, 0x6E, 0x0D, 0x00, 0x00, 0x76, 0x0E, 0x00, -0x25, 0xB0, 0x02, 0x3C, 0x25, 0x60, 0x93, 0x01, 0x25, 0x68, 0xB2, 0x01, -0x25, 0x70, 0xD0, 0x01, 0x10, 0x00, 0xC4, 0x2C, 0x37, 0x02, 0x42, 0x34, -0x0F, 0x00, 0x03, 0x24, 0x14, 0x00, 0xAC, 0xAF, 0x18, 0x00, 0xAD, 0xAF, -0x1C, 0x00, 0xAE, 0xAF, 0x20, 0x00, 0xB6, 0xA3, 0x21, 0x00, 0xB8, 0xA3, -0x0A, 0x30, 0x64, 0x00, 0x00, 0x00, 0x45, 0xA0, 0x21, 0x28, 0x00, 0x00, -0x21, 0x20, 0xE5, 0x00, 0x00, 0x00, 0x82, 0x90, 0x01, 0x00, 0xA5, 0x24, -0x2B, 0x10, 0xC2, 0x00, 0x02, 0x00, 0x40, 0x10, 0x11, 0x00, 0xA3, 0x2C, -0x00, 0x00, 0x86, 0xA0, 0xF9, 0xFF, 0x60, 0x14, 0x21, 0x20, 0xE5, 0x00, -0x21, 0x30, 0xE0, 0x00, 0x21, 0x28, 0x00, 0x00, 0x25, 0xB0, 0x07, 0x3C, -0x01, 0x00, 0xC2, 0x90, 0x00, 0x00, 0xC3, 0x90, 0x21, 0x20, 0xA7, 0x00, -0x00, 0x11, 0x02, 0x00, 0x25, 0x10, 0x43, 0x00, 0x01, 0x00, 0xA5, 0x24, -0xFF, 0x00, 0x42, 0x30, 0x08, 0x00, 0xA3, 0x2C, 0xA8, 0x01, 0x82, 0xA0, -0xF6, 0xFF, 0x60, 0x14, 0x02, 0x00, 0xC6, 0x24, 0x21, 0x00, 0xA2, 0x93, -0x20, 0x00, 0xA4, 0x93, 0x02, 0x80, 0x03, 0x3C, 0x00, 0x11, 0x02, 0x00, -0xD9, 0x5C, 0x66, 0x90, 0x25, 0x10, 0x44, 0x00, 0xFF, 0x00, 0x42, 0x30, -0xA7, 0x01, 0xE3, 0x34, 0x00, 0x00, 0x62, 0xA0, 0x01, 0x00, 0x02, 0x24, -0x0F, 0x00, 0xC2, 0x10, 0x60, 0x1B, 0x07, 0x25, 0x60, 0x1B, 0x02, 0x25, -0x00, 0x41, 0x40, 0xAC, 0x5C, 0x00, 0xBF, 0x8F, 0x58, 0x00, 0xBE, 0x8F, -0x54, 0x00, 0xB7, 0x8F, 0x50, 0x00, 0xB6, 0x8F, 0x4C, 0x00, 0xB5, 0x8F, -0x48, 0x00, 0xB4, 0x8F, 0x44, 0x00, 0xB3, 0x8F, 0x40, 0x00, 0xB2, 0x8F, -0x3C, 0x00, 0xB1, 0x8F, 0x38, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x60, 0x00, 0xBD, 0x27, 0x04, 0x41, 0xE2, 0x94, 0x00, 0x00, 0x00, 0x00, -0x02, 0x00, 0x42, 0x30, 0xEF, 0xFF, 0x40, 0x10, 0x60, 0x1B, 0x02, 0x25, -0x25, 0x41, 0xE3, 0x90, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x62, 0x30, -0xEA, 0xFF, 0x40, 0x10, 0x60, 0x1B, 0x02, 0x25, 0x03, 0x00, 0x63, 0x30, -0x10, 0x00, 0x66, 0x10, 0x03, 0x00, 0x02, 0x24, 0x07, 0x00, 0x62, 0x10, -0x60, 0x1B, 0x02, 0x25, 0x00, 0x41, 0x40, 0xAC, 0x21, 0x20, 0x00, 0x00, -0x95, 0x0E, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, 0xBE, 0x47, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x34, 0x02, 0x00, 0x05, 0x24, -0x00, 0x41, 0xE6, 0xAC, 0x95, 0x0E, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0xBE, 0x47, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x34, -0x01, 0x00, 0x05, 0x24, 0xE2, 0x47, 0x00, 0x08, 0x00, 0x41, 0xE6, 0xAC, -0xE8, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x06, 0x3C, 0x14, 0x00, 0xBF, 0xAF, -0x10, 0x00, 0xB0, 0xAF, 0xB4, 0x55, 0xC2, 0x24, 0x01, 0x00, 0x44, 0x90, -0xB4, 0x55, 0xC3, 0x90, 0x02, 0x00, 0x45, 0x90, 0x03, 0x00, 0x46, 0x90, -0x05, 0x00, 0x47, 0x90, 0x04, 0x00, 0x48, 0x90, 0x00, 0x22, 0x04, 0x00, -0x25, 0x18, 0x64, 0x00, 0x00, 0x2C, 0x05, 0x00, 0x25, 0xB0, 0x10, 0x3C, -0x25, 0x18, 0x65, 0x00, 0x00, 0x36, 0x06, 0x00, 0x00, 0x3A, 0x07, 0x00, -0x25, 0x18, 0x66, 0x00, 0x58, 0x00, 0x02, 0x36, 0x5C, 0x00, 0x05, 0x36, -0x25, 0x40, 0x07, 0x01, 0x02, 0x80, 0x04, 0x3C, 0x00, 0x00, 0x43, 0xAC, -0xB0, 0x55, 0x84, 0x24, 0x00, 0x00, 0xA8, 0xAC, 0xFD, 0x51, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0x03, 0x36, 0x00, 0x00, 0x62, 0xA4, -0x48, 0x00, 0x10, 0x36, 0x00, 0x00, 0x02, 0x8E, 0x84, 0x00, 0x03, 0x3C, -0x14, 0x00, 0xBF, 0x8F, 0x25, 0x10, 0x43, 0x00, 0x00, 0x00, 0x02, 0xAE, -0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, -0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, 0x14, 0x00, 0xBF, 0xAF, -0x53, 0x21, 0x00, 0x0C, 0x24, 0x00, 0x04, 0x24, 0x21, 0x30, 0x40, 0x00, -0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x50, 0x24, -0x21, 0x20, 0xC0, 0x00, 0x13, 0x00, 0xC0, 0x10, 0x80, 0xE8, 0xA5, 0x24, -0x04, 0x00, 0x02, 0x24, 0x09, 0x00, 0x03, 0x24, 0x0C, 0x00, 0xC2, 0xAC, -0x14, 0x00, 0xC3, 0xAC, 0x08, 0x00, 0xC5, 0x94, 0x3C, 0x3E, 0x03, 0x8E, -0x02, 0x80, 0x02, 0x3C, 0x25, 0x28, 0xA2, 0x00, 0x17, 0x0A, 0x00, 0x0C, -0x20, 0x00, 0xA3, 0xAC, 0x40, 0x3E, 0x06, 0x8E, 0x3C, 0x3E, 0x05, 0x8E, -0x02, 0x80, 0x04, 0x3C, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x94, 0xE8, 0x84, 0x24, 0x13, 0x58, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, -0x02, 0x80, 0x04, 0x3C, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0xAC, 0xE8, 0x84, 0x24, 0x13, 0x58, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, -0xD8, 0xFF, 0xBD, 0x27, 0x1C, 0x00, 0xB3, 0xAF, 0x18, 0x00, 0xB2, 0xAF, -0x14, 0x00, 0xB1, 0xAF, 0x20, 0x00, 0xBF, 0xAF, 0x10, 0x00, 0xB0, 0xAF, -0x02, 0x80, 0x02, 0x3C, 0xB0, 0x55, 0x43, 0x8C, 0x21, 0x90, 0x80, 0x00, -0x3C, 0x00, 0x64, 0x24, 0x53, 0x21, 0x00, 0x0C, 0x1C, 0x00, 0x73, 0x24, -0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x04, 0x3C, 0x21, 0x88, 0x40, 0x00, -0xB0, 0x55, 0xA5, 0x24, 0x74, 0x03, 0x06, 0x24, 0x19, 0x00, 0x40, 0x10, -0xC8, 0xE8, 0x84, 0x24, 0x08, 0x00, 0x50, 0x94, 0x0A, 0x00, 0x02, 0x24, -0x14, 0x00, 0x22, 0xAE, 0x02, 0x80, 0x02, 0x3C, 0x25, 0x80, 0x02, 0x02, -0x0C, 0x00, 0x33, 0xAE, 0x3C, 0x00, 0x04, 0x26, 0xF4, 0x54, 0x00, 0x0C, -0x20, 0x00, 0x10, 0x26, 0x18, 0x00, 0x12, 0xAE, 0x21, 0x20, 0x20, 0x02, -0x17, 0x0A, 0x00, 0x0C, 0x14, 0x00, 0x12, 0xAE, 0x02, 0x80, 0x04, 0x3C, -0x21, 0x28, 0x40, 0x02, 0x21, 0x30, 0x60, 0x02, 0x20, 0x00, 0xBF, 0x8F, -0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0xD8, 0xE8, 0x84, 0x24, 0x13, 0x58, 0x00, 0x08, -0x28, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x06, 0x3C, 0x21, 0x28, 0x60, 0x02, -0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0xB8, 0xE8, 0xC6, 0x24, -0x13, 0x58, 0x00, 0x08, 0x28, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27, -0x18, 0x00, 0xB2, 0xAF, 0xFF, 0xFF, 0x92, 0x30, 0x2A, 0x00, 0x04, 0x24, -0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x1C, 0x00, 0xBF, 0xAF, -0x53, 0x21, 0x00, 0x0C, 0xFF, 0x00, 0xB1, 0x30, 0x02, 0x80, 0x05, 0x3C, -0x21, 0x80, 0x40, 0x00, 0xB4, 0x55, 0xA5, 0x24, 0x13, 0x00, 0x40, 0x10, -0x06, 0x00, 0x06, 0x24, 0x08, 0x00, 0x44, 0x94, 0x0A, 0x00, 0x02, 0x24, -0x0C, 0x00, 0x02, 0xAE, 0x02, 0x80, 0x02, 0x3C, 0x25, 0x20, 0x82, 0x00, -0x20, 0x00, 0x84, 0x24, 0x19, 0x00, 0x03, 0x24, 0x14, 0x00, 0x03, 0xAE, -0x06, 0x00, 0x92, 0xA4, 0xF4, 0x54, 0x00, 0x0C, 0x08, 0x00, 0x91, 0xA0, -0x21, 0x20, 0x00, 0x02, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x17, 0x0A, 0x00, 0x08, -0x20, 0x00, 0xBD, 0x27, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x20, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB2, 0xAF, -0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x24, 0x00, 0xBF, 0xAF, -0x20, 0x00, 0xB4, 0xAF, 0x1C, 0x00, 0xB3, 0xAF, 0x02, 0x00, 0x82, 0x90, -0x02, 0x80, 0x12, 0x3C, 0x60, 0x1B, 0x51, 0x26, 0xB0, 0x1B, 0x25, 0x96, -0x0F, 0x00, 0x42, 0x30, 0xC0, 0x10, 0x02, 0x00, 0x21, 0x80, 0x44, 0x00, -0x00, 0x01, 0xA3, 0x30, 0x04, 0x00, 0x60, 0x10, 0x18, 0x00, 0x04, 0x26, -0x00, 0x10, 0xA2, 0x30, 0x0B, 0x00, 0x40, 0x10, 0x04, 0x00, 0xA2, 0x30, -0x21, 0x18, 0x00, 0x00, 0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB4, 0x8F, -0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x28, 0x00, 0xBD, 0x27, 0xF5, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x39, 0x53, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, -0x48, 0x37, 0x84, 0x24, 0x21, 0x28, 0x40, 0x00, 0x1D, 0x55, 0x00, 0x0C, -0x06, 0x00, 0x06, 0x24, 0xED, 0xFF, 0x40, 0x14, 0x21, 0x18, 0x00, 0x00, -0x02, 0x80, 0x02, 0x3C, 0xB4, 0x55, 0x53, 0x24, 0x22, 0x00, 0x14, 0x26, -0x21, 0x20, 0x80, 0x02, 0x21, 0x28, 0x60, 0x02, 0x1D, 0x55, 0x00, 0x0C, -0x06, 0x00, 0x06, 0x24, 0xE4, 0xFF, 0x40, 0x14, 0x21, 0x18, 0x00, 0x00, -0x28, 0x00, 0x04, 0x26, 0x21, 0x28, 0x60, 0x02, 0x1D, 0x55, 0x00, 0x0C, -0x06, 0x00, 0x06, 0x24, 0xDE, 0xFF, 0x40, 0x14, 0x21, 0x18, 0x00, 0x00, -0x02, 0x80, 0x04, 0x3C, 0x13, 0x58, 0x00, 0x0C, 0x38, 0xE9, 0x84, 0x24, -0xB0, 0x1B, 0x24, 0x96, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x83, 0x30, -0x01, 0x00, 0x62, 0x30, 0x08, 0x00, 0x40, 0x10, 0x00, 0x20, 0x62, 0x30, -0x1B, 0x00, 0x40, 0x10, 0xFF, 0xDE, 0x82, 0x30, 0xB0, 0x1B, 0x22, 0xA6, -0xFE, 0xFF, 0x04, 0x24, 0xCC, 0x39, 0x20, 0xAE, 0x35, 0x48, 0x00, 0x0C, -0xB0, 0x39, 0x20, 0xAE, 0x25, 0xB0, 0x10, 0x3C, 0x60, 0x1B, 0x51, 0x26, -0x4C, 0x00, 0x02, 0x36, 0x00, 0x00, 0x40, 0xA0, 0x48, 0x00, 0x10, 0x36, -0x21, 0x20, 0x00, 0x00, 0x21, 0x28, 0x00, 0x00, 0x95, 0x0E, 0x00, 0x0C, -0x37, 0x3E, 0x20, 0xA2, 0x00, 0x00, 0x03, 0x8E, 0x7B, 0xFF, 0x02, 0x3C, -0xFF, 0xFF, 0x42, 0x34, 0x24, 0x18, 0x62, 0x00, 0x00, 0x00, 0x03, 0xAE, -0xBC, 0x40, 0x20, 0xAE, 0xE8, 0x39, 0x20, 0xAE, 0x04, 0x3A, 0x20, 0xAE, -0x87, 0x54, 0x00, 0x0C, 0xFC, 0x40, 0x20, 0xAE, 0xA5, 0x48, 0x00, 0x08, -0x21, 0x18, 0x00, 0x00, 0xC4, 0x0E, 0x00, 0x0C, 0x21, 0x20, 0x80, 0x02, -0xB5, 0xFF, 0x40, 0x14, 0xFF, 0xFF, 0x03, 0x24, 0xB0, 0x1B, 0x22, 0x96, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x42, 0x30, 0xD8, 0x48, 0x00, 0x08, -0xB0, 0x1B, 0x22, 0xA6, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, -0x02, 0x80, 0x10, 0x3C, 0x60, 0x1B, 0x10, 0x26, 0x02, 0x00, 0x02, 0x24, -0x02, 0x80, 0x04, 0x3C, 0x00, 0x80, 0x06, 0x3C, 0x44, 0x3A, 0x02, 0xA2, -0x90, 0x55, 0x84, 0x24, 0x21, 0x28, 0x00, 0x00, 0x3C, 0x3A, 0x00, 0xAE, -0x14, 0x00, 0xBF, 0xAF, 0xCF, 0x20, 0x00, 0x0C, 0x70, 0x3C, 0xC6, 0x24, -0x02, 0x80, 0x02, 0x3C, 0xD1, 0x5C, 0x44, 0x90, 0x02, 0x80, 0x03, 0x3C, -0x49, 0xF5, 0x65, 0x90, 0x10, 0x27, 0x02, 0x24, 0x0B, 0x10, 0x04, 0x00, -0x01, 0x00, 0x84, 0x2C, 0x3C, 0x3A, 0x02, 0xAE, 0x49, 0x41, 0x05, 0xA2, -0x48, 0x41, 0x04, 0xA2, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xB8, 0xFF, 0xBD, 0x27, -0x00, 0x01, 0x04, 0x24, 0x3C, 0x00, 0xB3, 0xAF, 0x38, 0x00, 0xB2, 0xAF, -0x34, 0x00, 0xB1, 0xAF, 0x40, 0x00, 0xBF, 0xAF, 0x30, 0x00, 0xB0, 0xAF, -0x53, 0x21, 0x00, 0x0C, 0x02, 0x80, 0x13, 0x3C, 0x02, 0x80, 0x04, 0x3C, -0x21, 0x88, 0x40, 0x00, 0x90, 0xDE, 0x65, 0x26, 0x06, 0x00, 0x06, 0x24, -0x0C, 0x00, 0x52, 0x24, 0x4D, 0x00, 0x40, 0x10, 0x58, 0xE9, 0x84, 0x24, -0x08, 0x00, 0x50, 0x94, 0x02, 0x80, 0x02, 0x3C, 0x25, 0x80, 0x02, 0x02, -0x24, 0x00, 0x04, 0x26, 0xF4, 0x54, 0x00, 0x0C, 0x20, 0x00, 0x00, 0xA6, -0x02, 0x80, 0x05, 0x3C, 0x2A, 0x00, 0x04, 0x26, 0x48, 0x37, 0xA5, 0x24, -0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x30, 0x00, 0x04, 0x26, -0x90, 0xDE, 0x65, 0x26, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, -0x20, 0x00, 0x03, 0x96, 0x18, 0x00, 0x02, 0x24, 0x02, 0x80, 0x04, 0x3C, -0x03, 0xFF, 0x63, 0x30, 0x40, 0x00, 0x63, 0x34, 0x20, 0x00, 0x03, 0xA6, -0x60, 0x1B, 0x84, 0x24, 0x0C, 0x00, 0x22, 0xAE, 0xE4, 0x1D, 0x82, 0x94, -0x20, 0x00, 0x06, 0x26, 0x02, 0x80, 0x07, 0x3C, 0xFF, 0x0F, 0x43, 0x30, -0x00, 0x19, 0x03, 0x00, 0x02, 0x2A, 0x03, 0x00, 0x01, 0x00, 0x42, 0x24, -0xE4, 0x1D, 0x82, 0xA4, 0x16, 0x00, 0xC3, 0xA0, 0x17, 0x00, 0xC5, 0xA0, -0x0C, 0x3E, 0x86, 0x8C, 0x70, 0x59, 0xE7, 0x24, 0x38, 0x00, 0x04, 0x26, -0x21, 0x28, 0x00, 0x00, 0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB2, 0xAF, -0x18, 0x00, 0xA4, 0x27, 0x28, 0x00, 0xA5, 0x27, 0x05, 0x53, 0x00, 0x0C, -0x21, 0x80, 0x40, 0x00, 0x28, 0x00, 0xA3, 0x8F, 0x21, 0x20, 0x00, 0x02, -0x18, 0x00, 0xA7, 0x27, 0x09, 0x00, 0x62, 0x28, 0x01, 0x00, 0x05, 0x24, -0x13, 0x00, 0x40, 0x10, 0x08, 0x00, 0x06, 0x24, 0x21, 0x20, 0x00, 0x02, -0x21, 0x30, 0x60, 0x00, 0x01, 0x00, 0x05, 0x24, 0x18, 0x00, 0xA7, 0x27, -0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB2, 0xAF, 0x21, 0x20, 0x20, 0x02, -0x01, 0x00, 0x05, 0x24, 0x21, 0x30, 0x00, 0x00, 0xDF, 0x0D, 0x00, 0x0C, -0x21, 0x38, 0x00, 0x00, 0x40, 0x00, 0xBF, 0x8F, 0x3C, 0x00, 0xB3, 0x8F, -0x38, 0x00, 0xB2, 0x8F, 0x34, 0x00, 0xB1, 0x8F, 0x30, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x48, 0x00, 0xBD, 0x27, 0x25, 0x52, 0x00, 0x0C, -0x10, 0x00, 0xB2, 0xAF, 0x28, 0x00, 0xA6, 0x8F, 0x21, 0x20, 0x40, 0x00, -0x32, 0x00, 0x05, 0x24, 0xF8, 0xFF, 0xC6, 0x24, 0x58, 0x49, 0x00, 0x08, -0x20, 0x00, 0xA7, 0x27, 0x02, 0x80, 0x05, 0x3C, 0x13, 0x58, 0x00, 0x0C, -0x48, 0xE9, 0xA5, 0x24, 0x40, 0x00, 0xBF, 0x8F, 0x3C, 0x00, 0xB3, 0x8F, -0x38, 0x00, 0xB2, 0x8F, 0x34, 0x00, 0xB1, 0x8F, 0x30, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x48, 0x00, 0xBD, 0x27, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0x00, 0x00, 0xA8, 0xFF, 0xBD, 0x27, 0x48, 0x00, 0xB6, 0xAF, -0x3C, 0x00, 0xB3, 0xAF, 0x38, 0x00, 0xB2, 0xAF, 0x30, 0x00, 0xB0, 0xAF, -0x54, 0x00, 0xBF, 0xAF, 0x50, 0x00, 0xBE, 0xAF, 0x4C, 0x00, 0xB7, 0xAF, -0x44, 0x00, 0xB5, 0xAF, 0x40, 0x00, 0xB4, 0xAF, 0x34, 0x00, 0xB1, 0xAF, -0x02, 0x00, 0x82, 0x90, 0x00, 0x00, 0x83, 0x8C, 0x21, 0xB0, 0x00, 0x00, -0x0F, 0x00, 0x42, 0x30, 0xC0, 0x10, 0x02, 0x00, 0x21, 0x80, 0x44, 0x00, -0x18, 0x00, 0x12, 0x26, 0x21, 0x20, 0x40, 0x02, 0x39, 0x53, 0x00, 0x0C, -0xFF, 0x3F, 0x73, 0x30, 0x02, 0x80, 0x04, 0x3C, 0x48, 0x37, 0x84, 0x24, -0x21, 0x28, 0x40, 0x00, 0x1D, 0x55, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, -0x0B, 0x00, 0x40, 0x14, 0x02, 0x80, 0x15, 0x3C, 0x60, 0x1B, 0xB1, 0x26, -0xB0, 0x1B, 0x23, 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x62, 0x30, -0x05, 0x00, 0x40, 0x10, 0x00, 0x10, 0x62, 0x30, 0x03, 0x00, 0x40, 0x14, -0x00, 0x01, 0x62, 0x30, 0x0E, 0x00, 0x40, 0x10, 0x20, 0x00, 0xB4, 0x27, -0x54, 0x00, 0xBF, 0x8F, 0x50, 0x00, 0xBE, 0x8F, 0x4C, 0x00, 0xB7, 0x8F, -0x48, 0x00, 0xB6, 0x8F, 0x44, 0x00, 0xB5, 0x8F, 0x40, 0x00, 0xB4, 0x8F, -0x3C, 0x00, 0xB3, 0x8F, 0x38, 0x00, 0xB2, 0x8F, 0x34, 0x00, 0xB1, 0x8F, -0x30, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x58, 0x00, 0xBD, 0x27, 0x32, 0x00, 0x05, 0x26, 0x21, 0x20, 0x80, 0x02, -0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x06, 0x24, 0x20, 0x00, 0xA5, 0x97, -0x00, 0x00, 0x00, 0x00, 0xB8, 0x00, 0xA0, 0x14, 0x02, 0x80, 0x04, 0x3C, -0x21, 0x20, 0x80, 0x02, 0x34, 0x00, 0x05, 0x26, 0xF4, 0x54, 0x00, 0x0C, -0x02, 0x00, 0x06, 0x24, 0x20, 0x00, 0xA2, 0x97, 0x21, 0x20, 0x80, 0x02, -0x30, 0x00, 0x05, 0x26, 0xFF, 0x3F, 0x42, 0x30, 0x02, 0x00, 0x06, 0x24, -0x4C, 0x3A, 0x22, 0xA6, 0xF4, 0x54, 0x00, 0x0C, 0x28, 0x00, 0xA2, 0xAF, -0x20, 0x00, 0xA3, 0x97, 0x21, 0x40, 0x20, 0x02, 0x00, 0x04, 0x63, 0x30, -0x02, 0x00, 0x60, 0x14, 0x09, 0x00, 0x02, 0x24, 0x14, 0x00, 0x02, 0x24, -0x1E, 0x00, 0x5E, 0x26, 0xE2, 0xFF, 0x77, 0x26, 0x21, 0x20, 0xC0, 0x03, -0x01, 0x00, 0x05, 0x24, 0x24, 0x00, 0xA6, 0x27, 0x21, 0x38, 0xE0, 0x02, -0xAB, 0x1A, 0x00, 0x0C, 0xB8, 0x40, 0x02, 0xA1, 0x9E, 0x00, 0x40, 0x10, -0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0xA6, 0x8F, 0x02, 0x00, 0x45, 0x24, -0xF4, 0x54, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x21, 0x20, 0xC0, 0x03, -0x32, 0x00, 0x05, 0x24, 0x24, 0x00, 0xA6, 0x27, 0x24, 0x00, 0xB4, 0x8F, -0xAB, 0x1A, 0x00, 0x0C, 0x21, 0x38, 0xE0, 0x02, 0x08, 0x00, 0x40, 0x10, -0x10, 0x00, 0xA4, 0x27, 0x24, 0x00, 0xA6, 0x8F, 0x21, 0x20, 0x94, 0x00, -0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x45, 0x24, 0x24, 0x00, 0xA3, 0x8F, -0x00, 0x00, 0x00, 0x00, 0x21, 0xA0, 0x83, 0x02, 0x02, 0x80, 0x02, 0x3C, -0xD2, 0x5C, 0x44, 0x90, 0x02, 0x00, 0x03, 0x24, 0xDA, 0x00, 0x83, 0x10, -0x21, 0x20, 0xC0, 0x03, 0x60, 0x1B, 0xA4, 0x26, 0xBC, 0x40, 0x82, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x40, 0x10, 0x60, 0x1B, 0xB1, 0x26, -0x02, 0x80, 0x02, 0x3C, 0xCE, 0x5C, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, -0x1D, 0x00, 0x60, 0x14, 0x23, 0x10, 0xD2, 0x03, 0x2B, 0x10, 0x53, 0x00, -0x1A, 0x00, 0x40, 0x10, 0x21, 0x80, 0xC0, 0x03, 0x02, 0x80, 0x11, 0x3C, -0x21, 0x20, 0x00, 0x02, 0xDD, 0x00, 0x05, 0x24, 0x24, 0x00, 0xA6, 0x27, -0xAB, 0x1A, 0x00, 0x0C, 0x21, 0x38, 0xE0, 0x02, 0x21, 0x80, 0x40, 0x00, -0x02, 0x00, 0x44, 0x24, 0x68, 0xDE, 0x25, 0x26, 0x03, 0x01, 0x40, 0x10, -0x06, 0x00, 0x06, 0x24, 0x1D, 0x55, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x05, 0x01, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0xA2, 0x8F, -0x00, 0x00, 0x00, 0x00, 0x21, 0x18, 0x02, 0x02, 0x02, 0x00, 0x70, 0x24, -0x23, 0x20, 0x12, 0x02, 0xF8, 0x00, 0x40, 0x10, 0x2B, 0x20, 0x93, 0x00, -0xEB, 0xFF, 0x80, 0x14, 0x21, 0x20, 0x00, 0x02, 0x60, 0x1B, 0xB1, 0x26, -0xFC, 0x40, 0x22, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x40, 0x14, -0x24, 0x00, 0xA6, 0x27, 0xA9, 0x1B, 0x00, 0x0C, 0x60, 0x1B, 0xB2, 0x26, -0xB0, 0x1B, 0x45, 0x96, 0x25, 0xB0, 0x17, 0x3C, 0x02, 0x00, 0x03, 0x24, -0x4C, 0x00, 0xE4, 0x36, 0x00, 0x00, 0x83, 0xA0, 0x00, 0x01, 0xA5, 0x34, -0xE8, 0x39, 0x42, 0xAE, 0x60, 0xEA, 0x02, 0x34, 0x04, 0x3A, 0x42, 0xAE, -0xEA, 0x47, 0x00, 0x0C, 0xB0, 0x1B, 0x45, 0xA6, 0x10, 0x00, 0xA4, 0x27, -0x61, 0x53, 0x00, 0x0C, 0x21, 0x28, 0x80, 0x02, 0x0F, 0x00, 0x50, 0x30, -0x10, 0x00, 0xA4, 0x27, 0x7A, 0x53, 0x00, 0x0C, 0x21, 0x28, 0x80, 0x02, -0x40, 0x02, 0x13, 0x36, 0x21, 0x20, 0x60, 0x02, 0x63, 0x5E, 0x00, 0x74, -0x21, 0x28, 0x40, 0x00, 0x21, 0x28, 0x80, 0x02, 0xA6, 0x53, 0x00, 0x0C, -0x10, 0x00, 0xA4, 0x27, 0x21, 0x88, 0x40, 0x00, 0xFC, 0x40, 0x42, 0x8E, -0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x40, 0x10, 0x50, 0x00, 0x13, 0x36, -0x07, 0x41, 0x42, 0x92, 0x08, 0x41, 0x43, 0x92, 0xB6, 0x40, 0x44, 0x92, -0x00, 0x13, 0x02, 0x00, 0x00, 0x1D, 0x03, 0x00, 0x25, 0x10, 0x43, 0x00, -0x04, 0x00, 0x03, 0x24, 0x9C, 0x00, 0x83, 0x10, 0x25, 0x88, 0x22, 0x02, -0x00, 0x41, 0x43, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x60, 0x14, -0x01, 0x00, 0x02, 0x24, 0x04, 0x41, 0x42, 0x96, 0x00, 0x00, 0x00, 0x00, -0x20, 0x00, 0x42, 0x30, 0x9D, 0x00, 0x40, 0x14, 0x00, 0x10, 0x02, 0x3C, -0x01, 0x00, 0x02, 0x24, 0x94, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, -0x02, 0x80, 0x04, 0x3C, 0x94, 0xE9, 0x84, 0x24, 0x21, 0x28, 0x60, 0x02, -0x21, 0x38, 0xC0, 0x02, 0x13, 0x58, 0x00, 0x0C, 0x21, 0x30, 0x20, 0x02, -0x21, 0x20, 0x60, 0x02, 0x63, 0x5E, 0x00, 0x74, 0x21, 0x28, 0x20, 0x02, -0x60, 0x1B, 0xA2, 0x26, 0xB6, 0x40, 0x43, 0x90, 0xB0, 0x1B, 0x44, 0x94, -0x60, 0x1B, 0xA5, 0x8E, 0xFC, 0xFF, 0x63, 0x24, 0xFF, 0x00, 0x63, 0x30, -0xFF, 0xDF, 0x84, 0x30, 0x03, 0x00, 0x63, 0x2C, 0xB0, 0x1B, 0x44, 0xA4, -0xB0, 0x39, 0x40, 0xAC, 0xCC, 0x39, 0x40, 0xAC, 0x40, 0x41, 0x40, 0xAC, -0x44, 0x41, 0x40, 0xAC, 0x08, 0x00, 0x60, 0x10, 0x25, 0x00, 0xA5, 0x34, -0x28, 0x00, 0xA4, 0x8F, 0xFB, 0xFF, 0x02, 0x24, 0x24, 0x10, 0xA2, 0x00, -0x35, 0x48, 0x00, 0x0C, 0x60, 0x1B, 0xA2, 0xAE, 0xA0, 0x49, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0xA4, 0x8F, 0x35, 0x48, 0x00, 0x0C, -0x60, 0x1B, 0xA5, 0xAE, 0xA0, 0x49, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x13, 0x58, 0x00, 0x0C, 0x78, 0xE9, 0x84, 0x24, 0xFF, 0xFF, 0x02, 0x24, -0x51, 0x4A, 0x00, 0x08, 0x28, 0x00, 0xA2, 0xAF, 0x21, 0x20, 0xC0, 0x03, -0x2D, 0x00, 0x05, 0x24, 0xAB, 0x1A, 0x00, 0x0C, 0x21, 0x38, 0xE0, 0x02, -0x91, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0xAB, 0x8F, -0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x60, 0x19, 0x21, 0x40, 0x00, 0x00, -0x02, 0x00, 0x49, 0x24, 0x21, 0x50, 0x20, 0x02, 0x02, 0x00, 0x0C, 0x24, -0x89, 0x4A, 0x00, 0x08, 0x21, 0x68, 0x20, 0x01, 0x04, 0x41, 0x82, 0x90, -0x00, 0x00, 0x23, 0x91, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x43, 0x00, -0x04, 0x41, 0x82, 0xA0, 0x01, 0x00, 0x08, 0x25, 0x2A, 0x10, 0x0B, 0x01, -0x11, 0x00, 0x40, 0x10, 0x01, 0x00, 0x29, 0x25, 0xF6, 0xFF, 0x0C, 0x15, -0x21, 0x20, 0x0A, 0x01, 0x06, 0x41, 0x43, 0x91, 0x00, 0x00, 0x25, 0x91, -0x02, 0x00, 0xA2, 0x91, 0x1C, 0x00, 0x64, 0x30, 0x1C, 0x00, 0xA5, 0x30, -0x03, 0x00, 0x42, 0x30, 0x03, 0x00, 0x63, 0x30, 0x2A, 0x30, 0x43, 0x00, -0x2A, 0x38, 0xA4, 0x00, 0x0A, 0x10, 0x66, 0x00, 0x0A, 0x20, 0xA7, 0x00, -0x25, 0x10, 0x44, 0x00, 0x85, 0x4A, 0x00, 0x08, 0x06, 0x41, 0x42, 0xA1, -0x02, 0x80, 0x02, 0x3C, 0xC6, 0x5C, 0x43, 0x90, 0x02, 0x80, 0x02, 0x3C, -0x44, 0xDF, 0x47, 0x24, 0x10, 0x00, 0x65, 0x30, 0x02, 0x80, 0x02, 0x3C, -0x02, 0x80, 0x03, 0x3C, 0x54, 0xDF, 0x66, 0x24, 0x60, 0x1B, 0x44, 0x24, -0xAC, 0x4A, 0x00, 0x08, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0x43, 0x90, -0x07, 0x41, 0x82, 0x90, 0x01, 0x00, 0x08, 0x25, 0x24, 0x10, 0x43, 0x00, -0x07, 0x41, 0x82, 0xA0, 0x10, 0x00, 0x02, 0x29, 0x07, 0x00, 0x40, 0x10, -0x01, 0x00, 0x84, 0x24, 0x21, 0x10, 0x07, 0x01, 0xF6, 0xFF, 0xA0, 0x14, -0x21, 0x18, 0x06, 0x01, 0x00, 0x00, 0x63, 0x90, 0xA5, 0x4A, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0xC0, 0x03, 0x21, 0x38, 0xE0, 0x02, -0x3D, 0x00, 0x05, 0x24, 0xAB, 0x1A, 0x00, 0x0C, 0x24, 0x00, 0xA6, 0x27, -0x48, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0xA6, 0x8F, -0x02, 0x80, 0x04, 0x3C, 0x84, 0x5C, 0x84, 0x24, 0xF4, 0x54, 0x00, 0x0C, -0x02, 0x00, 0x45, 0x24, 0x2E, 0x47, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x13, 0x4A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x05, 0x24, -0x24, 0x00, 0xA6, 0x27, 0xAB, 0x1A, 0x00, 0x0C, 0x21, 0x38, 0xE0, 0x02, -0x30, 0x00, 0x40, 0x10, 0x60, 0x1B, 0xA5, 0x26, 0x02, 0x00, 0x42, 0x90, -0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x30, 0x2B, 0x00, 0x40, 0x10, -0x02, 0x80, 0x02, 0x3C, 0xD3, 0x5C, 0x44, 0x90, 0x01, 0x00, 0x03, 0x24, -0x3E, 0x00, 0x83, 0x10, 0x60, 0x1B, 0xA2, 0x26, 0xFC, 0x23, 0x43, 0x8C, -0xFF, 0xEF, 0x04, 0x24, 0x00, 0x08, 0x63, 0x34, 0x24, 0x18, 0x64, 0x00, -0xE9, 0x49, 0x00, 0x08, 0xFC, 0x23, 0x43, 0xAC, 0xF6, 0x01, 0xE2, 0x36, -0x00, 0x00, 0x40, 0xA4, 0x49, 0x4A, 0x00, 0x08, 0x02, 0x80, 0x04, 0x3C, -0x04, 0x41, 0x42, 0x96, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x30, -0x6A, 0xFF, 0x40, 0x10, 0x02, 0x80, 0x04, 0x3C, 0x00, 0x10, 0x02, 0x3C, -0x25, 0x88, 0x22, 0x02, 0x0F, 0x00, 0x08, 0x24, 0x01, 0x00, 0x03, 0x24, -0x0C, 0x00, 0x02, 0x25, 0x04, 0x10, 0x43, 0x00, 0x24, 0x10, 0x51, 0x00, -0x16, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x08, 0x25, -0xFA, 0xFF, 0x01, 0x05, 0x0C, 0x00, 0x02, 0x25, 0x00, 0x12, 0x16, 0x00, -0x00, 0x1B, 0x16, 0x00, 0x25, 0x18, 0x62, 0x00, 0x00, 0x21, 0x16, 0x00, -0x25, 0x18, 0x64, 0x00, 0x25, 0xB0, 0x02, 0x3C, 0x25, 0x18, 0x76, 0x00, -0xF6, 0x01, 0x42, 0x34, 0x00, 0x00, 0x43, 0xA4, 0x49, 0x4A, 0x00, 0x08, -0x02, 0x80, 0x04, 0x3C, 0xFC, 0x23, 0xA2, 0x8C, 0xFF, 0xF7, 0x03, 0x24, -0xFF, 0xEF, 0x04, 0x24, 0x24, 0x10, 0x43, 0x00, 0x24, 0x10, 0x44, 0x00, -0xE9, 0x49, 0x00, 0x08, 0xFC, 0x23, 0xA2, 0xAC, 0xEC, 0x4A, 0x00, 0x08, -0xFF, 0x00, 0x16, 0x31, 0x60, 0x1B, 0xA2, 0x26, 0x13, 0x4A, 0x00, 0x08, -0xFC, 0x40, 0x40, 0xAC, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, -0x0E, 0x4A, 0x00, 0x08, 0xBC, 0x40, 0x40, 0xAC, 0x13, 0x4A, 0x00, 0x08, -0xFC, 0x40, 0x20, 0xAE, 0x21, 0x20, 0x00, 0x02, 0x65, 0x0F, 0x00, 0x0C, -0x21, 0x28, 0x00, 0x00, 0x0F, 0x4A, 0x00, 0x08, 0x60, 0x1B, 0xB1, 0x26, -0xFC, 0x23, 0x43, 0x8C, 0xFF, 0xF7, 0x04, 0x24, 0x24, 0x18, 0x64, 0x00, -0x00, 0x10, 0x63, 0x34, 0xE9, 0x49, 0x00, 0x08, 0xFC, 0x23, 0x43, 0xAC, -0x02, 0x80, 0x04, 0x3C, 0xB0, 0x55, 0x84, 0x24, 0xE0, 0xFF, 0xBD, 0x27, -0x18, 0x00, 0xBF, 0xAF, 0xFB, 0x51, 0x00, 0x0C, 0x74, 0x00, 0x84, 0x24, -0x21, 0x28, 0x40, 0x00, 0x10, 0x00, 0xA4, 0x27, 0xF4, 0x54, 0x00, 0x0C, -0x02, 0x00, 0x06, 0x24, 0x10, 0x00, 0xA2, 0x97, 0x25, 0xB0, 0x04, 0x3C, -0x94, 0x00, 0x85, 0x34, 0x9A, 0x00, 0x87, 0x34, 0x26, 0xB0, 0x06, 0x3C, -0x00, 0x08, 0x03, 0x24, 0x00, 0x00, 0xA2, 0xA4, 0x0A, 0x00, 0x0B, 0x24, -0x00, 0x00, 0xE3, 0xA4, 0x98, 0x00, 0x88, 0x34, 0x96, 0x00, 0x89, 0x34, -0x7A, 0x00, 0xCA, 0x34, 0x50, 0x00, 0x02, 0x24, 0x04, 0x00, 0x03, 0x24, -0x00, 0x00, 0x02, 0xA5, 0x00, 0x00, 0x2B, 0xA5, 0x00, 0x00, 0x43, 0xA1, -0x10, 0x00, 0xA2, 0x97, 0x89, 0x00, 0x83, 0x34, 0x14, 0x00, 0x07, 0x24, -0x40, 0x11, 0x02, 0x00, 0xA0, 0xFF, 0x42, 0x24, 0xFF, 0xFF, 0x42, 0x30, -0x9C, 0x00, 0x85, 0x34, 0x7C, 0x00, 0xC6, 0x34, 0x00, 0x00, 0xC2, 0xA4, -0x44, 0x00, 0x84, 0x34, 0x00, 0x00, 0x67, 0xA0, 0x00, 0x00, 0xAB, 0xA0, -0x00, 0x00, 0x82, 0x94, 0xFF, 0xFD, 0x03, 0x24, 0x18, 0x00, 0xBF, 0x8F, -0x24, 0x10, 0x43, 0x00, 0x00, 0x00, 0x82, 0xA4, 0x00, 0x00, 0x83, 0x94, -0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, 0x00, 0x02, 0x63, 0x34, -0x20, 0x00, 0xBD, 0x27, 0x3A, 0x41, 0x40, 0xA0, 0x00, 0x00, 0x83, 0xA4, -0x08, 0x00, 0xE0, 0x03, 0xB8, 0x40, 0x47, 0xA0, 0xD0, 0xFF, 0xBD, 0x27, -0x10, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x10, 0x3C, 0xB0, 0x55, 0x04, 0x26, -0x28, 0x00, 0xBF, 0xAF, 0x24, 0x00, 0xB5, 0xAF, 0x14, 0x00, 0xB1, 0xAF, -0x20, 0x00, 0xB4, 0xAF, 0x1C, 0x00, 0xB3, 0xAF, 0x18, 0x52, 0x00, 0x0C, -0x18, 0x00, 0xB2, 0xAF, 0xFF, 0xFF, 0x51, 0x30, 0xB0, 0x55, 0x04, 0x26, -0xFD, 0x51, 0x00, 0x0C, 0x02, 0x80, 0x15, 0x3C, 0x60, 0x1B, 0xA3, 0x26, -0x01, 0x00, 0x24, 0x32, 0xB4, 0x40, 0x62, 0xA4, 0x03, 0x00, 0x80, 0x14, -0x02, 0x00, 0x05, 0x24, 0x40, 0x10, 0x11, 0x00, 0x04, 0x00, 0x45, 0x30, -0x02, 0x00, 0x02, 0x24, 0x5F, 0x00, 0xA2, 0x10, 0x60, 0x1B, 0xA2, 0x26, -0x10, 0x00, 0x80, 0x10, 0x02, 0x00, 0x03, 0x24, 0x04, 0x00, 0x02, 0x24, -0x12, 0x00, 0x62, 0x10, 0x60, 0x1B, 0xB3, 0x26, 0x02, 0x80, 0x04, 0x3C, -0x21, 0x28, 0x20, 0x02, 0x28, 0x00, 0xBF, 0x8F, 0x24, 0x00, 0xB5, 0x8F, -0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0xEC, 0xE9, 0x84, 0x24, -0x13, 0x58, 0x00, 0x08, 0x30, 0x00, 0xBD, 0x27, 0x40, 0x10, 0x11, 0x00, -0x04, 0x00, 0x43, 0x30, 0x04, 0x00, 0x02, 0x24, 0xF0, 0xFF, 0x62, 0x14, -0x60, 0x1B, 0xB3, 0x26, 0xB4, 0x40, 0x66, 0x96, 0xC4, 0x3D, 0x65, 0x92, -0x02, 0x80, 0x04, 0x3C, 0xB0, 0x1B, 0x63, 0xA6, 0xFC, 0xE9, 0x84, 0x24, -0x13, 0x58, 0x00, 0x0C, 0x25, 0xB0, 0x10, 0x3C, 0x50, 0x02, 0x03, 0x36, -0x0F, 0x00, 0x02, 0x24, 0x00, 0x00, 0x62, 0xA0, 0x21, 0x28, 0x00, 0x00, -0x95, 0x0E, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x00, 0xC4, 0x3D, 0x64, 0x92, -0x01, 0x00, 0x14, 0x24, 0x75, 0x0D, 0x00, 0x0C, 0x4C, 0x00, 0x10, 0x36, -0x02, 0x80, 0x11, 0x3C, 0x00, 0x00, 0x14, 0xA2, 0xEA, 0x47, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x1B, 0x53, 0x00, 0x0C, 0x10, 0x56, 0x24, 0x26, -0x21, 0x28, 0x40, 0x00, 0x10, 0x56, 0x24, 0x26, 0x61, 0x53, 0x00, 0x0C, -0x21, 0x90, 0x40, 0x00, 0x0F, 0x00, 0x50, 0x30, 0x10, 0x56, 0x24, 0x26, -0x7A, 0x53, 0x00, 0x0C, 0x21, 0x28, 0x40, 0x02, 0x40, 0x02, 0x10, 0x36, -0x02, 0x80, 0x04, 0x3C, 0x21, 0x88, 0x40, 0x00, 0x21, 0x30, 0x40, 0x00, -0x21, 0x28, 0x00, 0x02, 0x13, 0x58, 0x00, 0x0C, 0x2C, 0xEA, 0x84, 0x24, -0x21, 0x20, 0x00, 0x02, 0x63, 0x5E, 0x00, 0x74, 0x21, 0x28, 0x20, 0x02, -0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, 0x37, 0x3A, 0x84, 0x24, -0xB4, 0x55, 0xA5, 0x24, 0x06, 0x00, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C, -0xD6, 0x1E, 0x74, 0xA2, 0x31, 0x46, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x14, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x1B, 0x62, 0x96, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x34, 0xA9, 0x1B, 0x00, 0x0C, -0xB0, 0x1B, 0x62, 0xA6, 0xE8, 0x39, 0x62, 0xAE, 0x35, 0x48, 0x00, 0x0C, -0x01, 0x00, 0x04, 0x24, 0x60, 0x1B, 0xA2, 0x8E, 0x28, 0x00, 0xBF, 0x8F, -0x20, 0x00, 0xB4, 0x8F, 0x21, 0x00, 0x42, 0x34, 0x60, 0x1B, 0xA2, 0xAE, -0x1C, 0x00, 0xB3, 0x8F, 0x24, 0x00, 0xB5, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x30, 0x00, 0xBD, 0x27, 0x24, 0x40, 0x44, 0x8C, 0x01, 0x20, 0x03, 0x24, -0xB0, 0x1B, 0x43, 0xA4, 0x02, 0x00, 0x85, 0x10, 0x0C, 0x00, 0x03, 0x24, -0x0F, 0x00, 0x03, 0x24, 0x25, 0xB0, 0x02, 0x3C, 0x50, 0x02, 0x42, 0x34, -0x00, 0x00, 0x43, 0xA0, 0x60, 0x1B, 0xB0, 0x26, 0xB0, 0x1B, 0x02, 0x96, -0xB4, 0x40, 0x06, 0x96, 0xC4, 0x3D, 0x05, 0x92, 0x10, 0x00, 0x42, 0x34, -0x02, 0x80, 0x04, 0x3C, 0xB0, 0x1B, 0x02, 0xA6, 0x40, 0xEA, 0x84, 0x24, -0x13, 0x58, 0x00, 0x0C, 0x14, 0x40, 0x00, 0xAE, 0x21, 0x28, 0x00, 0x00, -0x95, 0x0E, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x00, 0xC4, 0x3D, 0x04, 0x92, -0x75, 0x0D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xA9, 0x1B, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0xE8, 0x39, 0x02, 0xAE, 0x28, 0x00, 0xBF, 0x8F, -0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, -0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27, -0x20, 0x00, 0xB2, 0xAF, 0x21, 0x90, 0x80, 0x00, 0x10, 0x00, 0xA4, 0x27, -0x24, 0x00, 0xBF, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, -0x8A, 0x40, 0x00, 0x0C, 0xFF, 0x00, 0xB0, 0x30, 0x02, 0x80, 0x02, 0x3C, -0x60, 0x1B, 0x51, 0x24, 0x10, 0x00, 0xA4, 0x27, 0x01, 0x00, 0x02, 0x24, -0x90, 0x40, 0x00, 0x0C, 0x4B, 0x41, 0x22, 0xA2, 0x02, 0x80, 0x04, 0x3C, -0x30, 0x59, 0x84, 0x24, 0x21, 0x28, 0x00, 0x00, 0xE3, 0x54, 0x00, 0x0C, -0x0F, 0x00, 0x06, 0x24, 0x21, 0x40, 0x00, 0x00, 0x18, 0x00, 0x00, 0x12, -0x21, 0x60, 0x00, 0x00, 0x21, 0x68, 0x20, 0x02, 0x21, 0x10, 0x92, 0x01, -0x01, 0x00, 0x49, 0x90, 0x00, 0x00, 0x4A, 0x90, 0x0D, 0x00, 0x20, 0x11, -0x21, 0x30, 0x00, 0x00, 0x21, 0x58, 0xA0, 0x01, 0x01, 0x00, 0xC2, 0x24, -0x21, 0x38, 0x46, 0x01, 0x01, 0x00, 0x03, 0x25, 0xFF, 0x00, 0x46, 0x30, -0x0E, 0x00, 0x02, 0x2D, 0x21, 0x28, 0x0B, 0x01, 0x2B, 0x20, 0xC9, 0x00, -0x08, 0x00, 0x40, 0x10, 0xFF, 0x00, 0x68, 0x30, 0xF6, 0xFF, 0x80, 0x14, -0xD0, 0x3D, 0xA7, 0xA0, 0x03, 0x00, 0x82, 0x25, 0xFF, 0x00, 0x4C, 0x30, -0x2B, 0x18, 0x90, 0x01, 0xEC, 0xFF, 0x60, 0x14, 0x21, 0x10, 0x92, 0x01, -0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27, -0x10, 0x00, 0xBF, 0xAF, 0x90, 0x48, 0x00, 0x0C, 0xFE, 0xFF, 0x05, 0x24, -0x10, 0x00, 0xBF, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF, -0x90, 0x48, 0x00, 0x0C, 0xFF, 0xFF, 0x05, 0x24, 0x10, 0x00, 0xBF, 0x8F, -0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, -0x25, 0xB0, 0x03, 0x3C, 0x01, 0x80, 0x02, 0x3C, 0xB0, 0x03, 0x65, 0x34, -0xAC, 0x30, 0x42, 0x24, 0x18, 0x03, 0x63, 0x34, 0x00, 0x00, 0x62, 0xAC, -0x00, 0x00, 0xA4, 0xAC, 0x00, 0x00, 0x83, 0x8C, 0x21, 0x10, 0x00, 0x00, -0xFF, 0x3F, 0x63, 0x30, 0x00, 0x00, 0xA3, 0xAC, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x06, 0x3C, -0x02, 0x80, 0x08, 0x3C, 0x78, 0x00, 0xBE, 0xAF, 0x7C, 0x00, 0xBF, 0xAF, -0x74, 0x00, 0xB7, 0xAF, 0x70, 0x00, 0xB6, 0xAF, 0x6C, 0x00, 0xB5, 0xAF, -0x68, 0x00, 0xB4, 0xAF, 0x64, 0x00, 0xB3, 0xAF, 0x60, 0x00, 0xB2, 0xAF, -0x5C, 0x00, 0xB1, 0xAF, 0x58, 0x00, 0xB0, 0xAF, 0xE8, 0xE9, 0xC2, 0x24, -0x74, 0xEA, 0x03, 0x25, 0x01, 0x00, 0x44, 0x90, 0x01, 0x00, 0x65, 0x90, -0xE8, 0xE9, 0xCB, 0x90, 0x74, 0xEA, 0x0A, 0x91, 0x02, 0x00, 0x47, 0x90, -0x02, 0x00, 0x66, 0x90, 0x03, 0x00, 0x48, 0x90, 0x03, 0x00, 0x69, 0x90, -0x00, 0x22, 0x04, 0x00, 0x00, 0x2A, 0x05, 0x00, 0x25, 0x20, 0x8B, 0x00, -0x25, 0x28, 0xAA, 0x00, 0x00, 0x3C, 0x07, 0x00, 0x00, 0x34, 0x06, 0x00, -0x25, 0x38, 0xE4, 0x00, 0x25, 0x30, 0xC5, 0x00, 0x00, 0x46, 0x08, 0x00, -0x00, 0x4E, 0x09, 0x00, 0x25, 0x40, 0x07, 0x01, 0x25, 0x48, 0x26, 0x01, -0x00, 0x02, 0x04, 0x24, 0x40, 0x00, 0xA8, 0xAF, 0x53, 0x21, 0x00, 0x0C, -0x48, 0x00, 0xA9, 0xAF, 0xCF, 0x01, 0x40, 0x10, 0x21, 0xF0, 0x40, 0x00, -0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x52, 0x24, 0xC0, 0x3A, 0x45, 0x8E, -0x02, 0x80, 0x04, 0x3C, 0x13, 0x58, 0x00, 0x0C, 0x78, 0xEA, 0x84, 0x24, -0x08, 0x00, 0xD1, 0x97, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x10, 0x3C, -0x25, 0x88, 0x22, 0x02, 0xB4, 0x55, 0x10, 0x26, 0x24, 0x00, 0x24, 0x26, -0x21, 0x28, 0x00, 0x02, 0x20, 0x00, 0x20, 0xA6, 0xF4, 0x54, 0x00, 0x0C, -0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x05, 0x3C, 0x2A, 0x00, 0x24, 0x26, -0x48, 0x37, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, -0x21, 0x28, 0x00, 0x02, 0x06, 0x00, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x0C, -0x30, 0x00, 0x24, 0x26, 0x18, 0x00, 0x03, 0x24, 0x0C, 0x00, 0xC3, 0xAF, -0xE4, 0x1D, 0x42, 0x96, 0x20, 0x00, 0x25, 0x26, 0x38, 0x00, 0x37, 0x26, -0xFF, 0x0F, 0x43, 0x30, 0x00, 0x19, 0x03, 0x00, 0x02, 0x22, 0x03, 0x00, -0x01, 0x00, 0x42, 0x24, 0xE4, 0x1D, 0x42, 0xA6, 0x17, 0x00, 0xA4, 0xA0, -0x02, 0x80, 0x04, 0x3C, 0x16, 0x00, 0xA3, 0xA0, 0x16, 0x52, 0x00, 0x0C, -0x24, 0x56, 0x84, 0x24, 0x21, 0x28, 0x40, 0x00, 0x21, 0x20, 0xE0, 0x02, -0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x06, 0x24, 0x3A, 0x00, 0x24, 0x26, -0x18, 0x00, 0xA5, 0x27, 0x02, 0x00, 0x06, 0x24, 0x03, 0x00, 0x02, 0x24, -0xF4, 0x54, 0x00, 0x0C, 0x18, 0x00, 0xA2, 0xA7, 0x0C, 0x00, 0xC3, 0x8F, -0x02, 0x80, 0x07, 0x3C, 0x3C, 0x00, 0x24, 0x26, 0x04, 0x00, 0x63, 0x24, -0x0C, 0x00, 0xC3, 0xAF, 0x5C, 0x3A, 0x46, 0x8E, 0x0C, 0x00, 0xC3, 0x27, -0xC0, 0x55, 0xE7, 0x24, 0x21, 0x28, 0x00, 0x00, 0x54, 0x00, 0xA3, 0xAF, -0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA3, 0xAF, 0x20, 0x00, 0xA4, 0x27, -0x50, 0x00, 0xA5, 0x27, 0x05, 0x53, 0x00, 0x0C, 0x21, 0xB8, 0x40, 0x00, -0x50, 0x00, 0xA8, 0x8F, 0x21, 0x88, 0x00, 0x00, 0x52, 0x00, 0x00, 0x11, -0x21, 0x80, 0x00, 0x00, 0x21, 0x38, 0x40, 0x02, 0x18, 0x00, 0xA9, 0x27, -0x21, 0x10, 0x31, 0x01, 0x08, 0x00, 0x46, 0x90, 0x21, 0x20, 0x00, 0x00, -0x7F, 0x00, 0xC5, 0x30, 0x21, 0x10, 0x87, 0x00, 0xB0, 0x3A, 0x43, 0x90, -0x01, 0x00, 0x84, 0x24, 0x7F, 0x00, 0x63, 0x30, 0x3D, 0x00, 0xA3, 0x10, -0x0D, 0x00, 0x82, 0x2C, 0xFA, 0xFF, 0x40, 0x14, 0x21, 0x10, 0x87, 0x00, -0x01, 0x00, 0x31, 0x26, 0x2B, 0x10, 0x28, 0x02, 0xF2, 0xFF, 0x40, 0x14, -0x21, 0x10, 0x31, 0x01, 0x09, 0x00, 0x02, 0x2E, 0x3D, 0x00, 0x40, 0x14, -0x21, 0x20, 0xE0, 0x02, 0x54, 0x00, 0xA2, 0x8F, 0x01, 0x00, 0x05, 0x24, -0x08, 0x00, 0x06, 0x24, 0x30, 0x00, 0xA7, 0x27, 0x25, 0x52, 0x00, 0x0C, -0x10, 0x00, 0xA2, 0xAF, 0x54, 0x00, 0xA3, 0x8F, 0x21, 0x20, 0x40, 0x00, -0xF8, 0xFF, 0x06, 0x26, 0x32, 0x00, 0x05, 0x24, 0x38, 0x00, 0xA7, 0x27, -0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA3, 0xAF, 0x21, 0xB8, 0x40, 0x00, -0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x44, 0x24, 0x24, 0x40, 0x83, 0x8C, -0x02, 0x00, 0x02, 0x24, 0x37, 0x00, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, -0xC0, 0x3A, 0x83, 0x8C, 0x0C, 0x00, 0x11, 0x24, 0x2B, 0x10, 0x23, 0x02, -0x32, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C, 0x24, 0x56, 0x46, 0x24, -0x21, 0x20, 0x60, 0x00, 0xE0, 0x4C, 0x00, 0x08, 0x30, 0x00, 0x05, 0x24, -0x01, 0x00, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x51, 0x00, -0x02, 0x00, 0x51, 0x24, 0x2B, 0x18, 0x24, 0x02, 0x27, 0x00, 0x60, 0x10, -0x00, 0x00, 0x00, 0x00, 0x21, 0x18, 0x26, 0x02, 0x00, 0x00, 0x62, 0x90, -0x00, 0x00, 0x00, 0x00, 0xF5, 0xFF, 0x45, 0x14, 0x02, 0x80, 0x07, 0x3C, -0x01, 0x00, 0x66, 0x90, 0x54, 0x00, 0xA2, 0x8F, 0x26, 0x56, 0xE7, 0x24, -0x21, 0x20, 0xE0, 0x02, 0x21, 0x38, 0x27, 0x02, 0x30, 0x00, 0x05, 0x24, -0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF, 0x06, 0x4D, 0x00, 0x08, -0x21, 0xB8, 0x40, 0x00, 0x21, 0x10, 0x30, 0x01, 0x18, 0x00, 0x46, 0xA0, -0x50, 0x00, 0xA8, 0x8F, 0x01, 0x00, 0x31, 0x26, 0x2B, 0x10, 0x28, 0x02, -0xB4, 0xFF, 0x40, 0x14, 0x01, 0x00, 0x10, 0x26, 0xBA, 0x4C, 0x00, 0x08, -0x09, 0x00, 0x02, 0x2E, 0x54, 0x00, 0xA3, 0x8F, 0x21, 0x20, 0xE0, 0x02, -0x21, 0x30, 0x00, 0x02, 0x01, 0x00, 0x05, 0x24, 0x30, 0x00, 0xA7, 0x27, -0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA3, 0xAF, 0x21, 0xB8, 0x40, 0x00, -0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x44, 0x24, 0x24, 0x40, 0x83, 0x8C, -0x02, 0x00, 0x02, 0x24, 0xCB, 0xFF, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, -0x2B, 0x1B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x40, 0x14, -0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x43, 0x24, 0xC0, 0x3A, 0x62, 0x8C, -0x0C, 0x00, 0x11, 0x24, 0x2B, 0x10, 0x22, 0x02, 0x11, 0x00, 0x40, 0x10, -0x02, 0x80, 0x02, 0x3C, 0x21, 0x80, 0x60, 0x00, 0x24, 0x56, 0x52, 0x24, -0x21, 0xA8, 0x60, 0x00, 0x02, 0x80, 0x13, 0x3C, 0x21, 0x20, 0x32, 0x02, -0x00, 0x00, 0x83, 0x90, 0x2D, 0x00, 0x02, 0x24, 0xD6, 0x00, 0x62, 0x10, -0x02, 0x80, 0x05, 0x3C, 0x01, 0x00, 0x82, 0x90, 0xC0, 0x3A, 0x03, 0x8E, -0x21, 0x10, 0x51, 0x00, 0x02, 0x00, 0x51, 0x24, 0x2B, 0x18, 0x23, 0x02, -0xF6, 0xFF, 0x60, 0x14, 0x21, 0x20, 0x32, 0x02, 0x02, 0x80, 0x02, 0x3C, -0x60, 0x1B, 0x44, 0x24, 0x24, 0x40, 0x83, 0x8C, 0x02, 0x00, 0x02, 0x24, -0x86, 0x00, 0x62, 0x10, 0x0C, 0x00, 0x11, 0x24, 0x02, 0x80, 0x02, 0x3C, -0x60, 0x1B, 0x43, 0x24, 0xC0, 0x3A, 0x62, 0x8C, 0x0C, 0x00, 0x11, 0x24, -0x2B, 0x10, 0x22, 0x02, 0x26, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C, -0x24, 0x56, 0x56, 0x24, 0x21, 0xA8, 0x60, 0x00, 0xDD, 0x00, 0x14, 0x24, -0x39, 0x4D, 0x00, 0x08, 0x02, 0x80, 0x13, 0x3C, 0x01, 0x00, 0x02, 0x92, -0xC0, 0x3A, 0xA3, 0x8E, 0x21, 0x10, 0x51, 0x00, 0x02, 0x00, 0x51, 0x24, -0x2B, 0x18, 0x23, 0x02, 0x1B, 0x00, 0x60, 0x10, 0x02, 0x80, 0x03, 0x3C, -0x21, 0x80, 0x36, 0x02, 0x00, 0x00, 0x02, 0x92, 0x02, 0x00, 0x12, 0x26, -0x21, 0x20, 0x40, 0x02, 0x70, 0xDE, 0x65, 0x26, 0xF3, 0xFF, 0x54, 0x14, -0x06, 0x00, 0x06, 0x24, 0x1D, 0x55, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0xEF, 0xFF, 0x40, 0x14, 0x21, 0x20, 0xE0, 0x02, 0x54, 0x00, 0xA2, 0x8F, -0xDD, 0x00, 0x05, 0x24, 0x21, 0x38, 0x40, 0x02, 0x07, 0x00, 0x06, 0x24, -0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF, 0x08, 0x00, 0x04, 0x92, -0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x65, 0x24, 0x21, 0xB8, 0x40, 0x00, -0x01, 0x00, 0x03, 0x24, 0x02, 0x80, 0x02, 0x3C, 0x08, 0x5E, 0x44, 0xA0, -0xBC, 0x40, 0xA3, 0xAC, 0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x64, 0x24, -0xC0, 0x3A, 0x82, 0x8C, 0x0C, 0x00, 0x11, 0x24, 0x2B, 0x10, 0x22, 0x02, -0x20, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, -0x24, 0x56, 0x56, 0x24, 0x26, 0x56, 0x75, 0x24, 0x21, 0xA0, 0x80, 0x00, -0x66, 0x4D, 0x00, 0x08, 0xDD, 0x00, 0x13, 0x24, 0x01, 0x00, 0x02, 0x92, -0xC0, 0x3A, 0x83, 0x8E, 0x21, 0x10, 0x51, 0x00, 0x02, 0x00, 0x51, 0x24, -0x2B, 0x18, 0x23, 0x02, 0x14, 0x00, 0x60, 0x10, 0x02, 0x80, 0x02, 0x3C, -0x21, 0x80, 0x36, 0x02, 0x00, 0x00, 0x02, 0x92, 0x21, 0x90, 0x35, 0x02, -0x21, 0x20, 0x40, 0x02, 0x48, 0x00, 0xA5, 0x27, 0xF3, 0xFF, 0x53, 0x14, -0x04, 0x00, 0x06, 0x24, 0x1D, 0x55, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0xEF, 0xFF, 0x40, 0x14, 0x21, 0x20, 0xE0, 0x02, 0x01, 0x00, 0x06, 0x92, -0x54, 0x00, 0xA2, 0x8F, 0x21, 0x38, 0x40, 0x02, 0xDD, 0x00, 0x05, 0x24, -0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF, 0x21, 0xB8, 0x40, 0x00, -0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x44, 0x24, 0xFC, 0x40, 0x83, 0x8C, -0x01, 0x00, 0x02, 0x24, 0x61, 0x00, 0x62, 0x10, 0x06, 0x00, 0x02, 0x24, -0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x62, 0x24, 0xC0, 0x3A, 0x43, 0x8C, -0x0C, 0x00, 0x11, 0x24, 0x2B, 0x10, 0x23, 0x02, 0x10, 0x00, 0x40, 0x10, -0x02, 0x80, 0x02, 0x3C, 0x24, 0x56, 0x46, 0x24, 0x21, 0x20, 0x60, 0x00, -0x44, 0x00, 0x05, 0x24, 0x21, 0x80, 0x26, 0x02, 0x00, 0x00, 0x02, 0x92, -0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x45, 0x10, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0x51, 0x00, -0x02, 0x00, 0x51, 0x24, 0x2B, 0x18, 0x24, 0x02, 0xF6, 0xFF, 0x60, 0x14, -0x21, 0x80, 0x26, 0x02, 0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x62, 0x24, -0xB6, 0x40, 0x43, 0x90, 0x04, 0x00, 0x07, 0x24, 0x21, 0x20, 0xC0, 0x03, -0x01, 0x00, 0x63, 0x38, 0x0B, 0x38, 0x03, 0x00, 0x21, 0x28, 0x00, 0x00, -0xDF, 0x0D, 0x00, 0x0C, 0x21, 0x30, 0x00, 0x00, 0x21, 0x10, 0x00, 0x00, -0x7C, 0x00, 0xBF, 0x8F, 0x78, 0x00, 0xBE, 0x8F, 0x74, 0x00, 0xB7, 0x8F, -0x70, 0x00, 0xB6, 0x8F, 0x6C, 0x00, 0xB5, 0x8F, 0x68, 0x00, 0xB4, 0x8F, -0x64, 0x00, 0xB3, 0x8F, 0x60, 0x00, 0xB2, 0x8F, 0x5C, 0x00, 0xB1, 0x8F, -0x58, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x80, 0x00, 0xBD, 0x27, -0xC0, 0x3A, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x10, 0x22, 0x02, -0x77, 0xFF, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, -0x24, 0x56, 0x56, 0x24, 0x26, 0x56, 0x75, 0x24, 0x21, 0xA0, 0x80, 0x00, -0xBD, 0x4D, 0x00, 0x08, 0xDD, 0x00, 0x13, 0x24, 0x01, 0x00, 0x02, 0x92, -0xC0, 0x3A, 0x83, 0x8E, 0x21, 0x10, 0x51, 0x00, 0x02, 0x00, 0x51, 0x24, -0x2B, 0x18, 0x23, 0x02, 0x6B, 0xFF, 0x60, 0x10, 0x02, 0x80, 0x02, 0x3C, -0x21, 0x80, 0x36, 0x02, 0x00, 0x00, 0x02, 0x92, 0x21, 0x90, 0x35, 0x02, -0x21, 0x20, 0x40, 0x02, 0x40, 0x00, 0xA5, 0x27, 0xF3, 0xFF, 0x53, 0x14, -0x04, 0x00, 0x06, 0x24, 0x1D, 0x55, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0xEF, 0xFF, 0x40, 0x14, 0x21, 0x20, 0xE0, 0x02, 0x01, 0x00, 0x06, 0x92, -0x54, 0x00, 0xA3, 0x8F, 0x21, 0x38, 0x40, 0x02, 0xDD, 0x00, 0x05, 0x24, -0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA3, 0xAF, 0x26, 0x4D, 0x00, 0x08, -0x21, 0xB8, 0x40, 0x00, 0x02, 0x80, 0x04, 0x3C, 0x13, 0x58, 0x00, 0x0C, -0x8C, 0xEA, 0x84, 0x24, 0x01, 0x00, 0x06, 0x92, 0x54, 0x00, 0xA2, 0x8F, -0x02, 0x80, 0x07, 0x3C, 0x26, 0x56, 0xE7, 0x24, 0x21, 0x38, 0x27, 0x02, -0x21, 0x20, 0xE0, 0x02, 0x44, 0x00, 0x05, 0x24, 0x25, 0x52, 0x00, 0x0C, -0x10, 0x00, 0xA2, 0xAF, 0x95, 0x4D, 0x00, 0x08, 0x02, 0x80, 0x03, 0x3C, -0xB6, 0x40, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x62, 0x10, -0x05, 0x00, 0x02, 0x24, 0x9C, 0xFF, 0x62, 0x14, 0x02, 0x80, 0x03, 0x3C, -0x02, 0x80, 0x07, 0x3C, 0x21, 0x20, 0xE0, 0x02, 0x34, 0xDE, 0xE7, 0x24, -0xDD, 0x00, 0x05, 0x24, 0x06, 0x00, 0x06, 0x24, 0x54, 0x00, 0xA3, 0x8F, -0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA3, 0xAF, 0x7E, 0x4D, 0x00, 0x08, -0x21, 0xB8, 0x40, 0x00, 0x02, 0x80, 0x14, 0x3C, 0x26, 0x56, 0xA5, 0x24, -0x21, 0x28, 0x25, 0x02, 0x64, 0x5C, 0x84, 0x26, 0xF4, 0x54, 0x00, 0x0C, -0x20, 0x00, 0x06, 0x24, 0x02, 0x80, 0x03, 0x3C, 0xD9, 0x5C, 0x62, 0x90, -0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x04, 0x41, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0xBD, 0xFF, 0x42, 0x30, -0x04, 0x41, 0x02, 0xA6, 0x02, 0x80, 0x02, 0x3C, 0xC4, 0xDF, 0x44, 0x8C, -0x04, 0x41, 0xA3, 0x96, 0x20, 0x00, 0x80, 0x10, 0x0C, 0x00, 0x62, 0x34, -0x00, 0x01, 0x42, 0x34, 0x04, 0x41, 0xA2, 0xA6, 0x02, 0x80, 0x03, 0x3C, -0xC6, 0x5C, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, -0x15, 0x00, 0x40, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x05, 0x3C, -0x67, 0x5C, 0x64, 0x26, 0x44, 0xDF, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C, -0x10, 0x00, 0x06, 0x24, 0x21, 0x10, 0x32, 0x02, 0x01, 0x00, 0x46, 0x90, -0x54, 0x00, 0xA3, 0x8F, 0x21, 0x20, 0xE0, 0x02, 0x64, 0x5C, 0x87, 0x26, -0x2D, 0x00, 0x05, 0x24, 0x25, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA3, 0xAF, -0x21, 0xB8, 0x40, 0x00, 0x01, 0x00, 0x02, 0x24, 0x20, 0x4D, 0x00, 0x08, -0xFC, 0x40, 0x02, 0xAE, 0x04, 0x41, 0x02, 0x96, 0xFC, 0x4D, 0x00, 0x08, -0x02, 0x00, 0x42, 0x34, 0x67, 0x5C, 0x64, 0x26, 0x0D, 0x4E, 0x00, 0x08, -0x54, 0xDF, 0xA5, 0x24, 0x04, 0x4E, 0x00, 0x08, 0x04, 0x41, 0xA2, 0xA6, -0x02, 0x80, 0x02, 0x3C, 0x34, 0xDE, 0x42, 0x24, 0x06, 0x00, 0x48, 0x90, -0x02, 0x00, 0x03, 0x24, 0x21, 0x20, 0xE0, 0x02, 0x01, 0x00, 0x08, 0x35, -0x21, 0x38, 0x40, 0x00, 0xDD, 0x00, 0x05, 0x24, 0x07, 0x00, 0x06, 0x24, -0x04, 0x00, 0x43, 0xA0, 0xE9, 0x4D, 0x00, 0x08, 0x06, 0x00, 0x48, 0xA0, -0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, 0xAC, 0xE8, 0x84, 0x24, -0x13, 0x58, 0x00, 0x0C, 0x64, 0xEA, 0xA5, 0x24, 0x9F, 0x4D, 0x00, 0x08, -0xFF, 0xFF, 0x02, 0x24, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, -0xB0, 0x1B, 0x43, 0x94, 0x32, 0x00, 0x04, 0x24, 0xCC, 0x39, 0x44, 0xAC, -0x9F, 0xFE, 0x63, 0x30, 0x80, 0x00, 0x63, 0x34, 0xB0, 0x1B, 0x43, 0xA4, -0x18, 0x40, 0x40, 0xAC, 0x1C, 0x40, 0x40, 0xAC, 0x38, 0x4C, 0x00, 0x08, -0xB0, 0x39, 0x40, 0xAC, 0xE8, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, -0x10, 0x00, 0xB0, 0xAF, 0x14, 0x00, 0xBF, 0xAF, 0x60, 0x1B, 0x50, 0x24, -0x1C, 0x40, 0x03, 0x8E, 0xFE, 0xFF, 0x04, 0x24, 0x01, 0x00, 0x63, 0x24, -0x03, 0x00, 0x62, 0x2C, 0x12, 0x00, 0x40, 0x10, 0x1C, 0x40, 0x03, 0xAE, -0xB0, 0x1B, 0x02, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0x30, -0x05, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xBF, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, -0x38, 0x4C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x03, 0x24, -0xCC, 0x39, 0x03, 0xAE, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xB0, 0x1B, 0x02, 0x96, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xDF, 0x42, 0x30, 0x35, 0x48, 0x00, 0x0C, -0xB0, 0x1B, 0x02, 0xA6, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xD0, 0xFF, 0xBD, 0x27, -0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF, -0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x2C, 0x00, 0xBF, 0xAF, -0x02, 0x00, 0x82, 0x90, 0x02, 0x80, 0x14, 0x3C, 0x60, 0x1B, 0x92, 0x26, -0xB0, 0x1B, 0x43, 0x96, 0x00, 0x00, 0x85, 0x8C, 0x0F, 0x00, 0x42, 0x30, -0xC0, 0x10, 0x02, 0x00, 0x21, 0x80, 0x44, 0x00, 0x01, 0x00, 0x63, 0x30, -0xFF, 0x3F, 0xB3, 0x30, 0x18, 0x00, 0x11, 0x26, 0x0A, 0x00, 0x60, 0x14, -0x21, 0x20, 0x00, 0x00, 0x2C, 0x00, 0xBF, 0x8F, 0x28, 0x00, 0xB4, 0x8F, -0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x80, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x30, 0x00, 0xBD, 0x27, 0x39, 0x53, 0x00, 0x0C, 0x21, 0x20, 0x20, 0x02, -0x02, 0x80, 0x04, 0x3C, 0x48, 0x37, 0x84, 0x24, 0x21, 0x28, 0x40, 0x00, -0x1D, 0x55, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0xEF, 0xFF, 0x40, 0x14, -0x21, 0x20, 0x00, 0x00, 0xB0, 0x1B, 0x42, 0x96, 0x00, 0x00, 0x00, 0x00, -0x00, 0x10, 0x42, 0x30, 0xEA, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x18, 0x00, 0x03, 0x96, 0x04, 0x00, 0x04, 0x24, 0x21, 0x10, 0x80, 0x00, -0x00, 0x40, 0x63, 0x30, 0x0A, 0x10, 0x03, 0x00, 0x21, 0x10, 0x22, 0x02, -0x1C, 0x00, 0x43, 0x94, 0x1A, 0x00, 0x45, 0x94, 0x2F, 0x00, 0x60, 0x14, -0x02, 0x00, 0x02, 0x24, 0x14, 0x00, 0xA2, 0x10, 0x01, 0x00, 0x02, 0x24, -0x0E, 0x00, 0xA4, 0x14, 0x02, 0x80, 0x04, 0x3C, 0x24, 0x40, 0x43, 0x8E, -0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x62, 0x10, 0x60, 0x1B, 0x83, 0x26, -0xB0, 0x1B, 0x62, 0x94, 0xFF, 0xFF, 0x04, 0x24, 0xFF, 0xDF, 0x42, 0x30, -0x7B, 0x4E, 0x00, 0x08, 0xB0, 0x1B, 0x62, 0xA4, 0x36, 0x4E, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x7B, 0x4E, 0x00, 0x08, 0x21, 0x20, 0x00, 0x00, -0x13, 0x58, 0x00, 0x0C, 0x04, 0xEB, 0x84, 0x24, 0xA4, 0x4E, 0x00, 0x08, -0x60, 0x1B, 0x83, 0x26, 0x24, 0x40, 0x43, 0x8E, 0x00, 0x00, 0x00, 0x00, -0xF5, 0xFF, 0x62, 0x14, 0xE2, 0xFF, 0x67, 0x26, 0x36, 0x00, 0x04, 0x26, -0x10, 0x00, 0x05, 0x24, 0xAB, 0x1A, 0x00, 0x0C, 0x10, 0x00, 0xA6, 0x27, -0x16, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xA6, 0x8F, -0x02, 0x80, 0x04, 0x3C, 0x94, 0x5B, 0x84, 0x24, 0xF4, 0x54, 0x00, 0x0C, -0x02, 0x00, 0x45, 0x24, 0xB0, 0x1B, 0x43, 0x96, 0x21, 0x20, 0x00, 0x00, -0x03, 0x00, 0x02, 0x24, 0xDF, 0xFF, 0x63, 0x30, 0x40, 0x00, 0x63, 0x34, -0xB0, 0x1B, 0x43, 0xA6, 0x2D, 0x14, 0x00, 0x0C, 0x20, 0x40, 0x42, 0xAE, -0x7B, 0x4E, 0x00, 0x08, 0x21, 0x20, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, -0x2C, 0xEB, 0x84, 0x24, 0x13, 0x58, 0x00, 0x0C, 0x21, 0x28, 0x60, 0x00, -0xA4, 0x4E, 0x00, 0x08, 0x60, 0x1B, 0x83, 0x26, 0x02, 0x80, 0x04, 0x3C, -0x13, 0x58, 0x00, 0x0C, 0x48, 0xEB, 0x84, 0x24, 0xA4, 0x4E, 0x00, 0x08, -0x60, 0x1B, 0x83, 0x26, 0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x63, 0x24, -0xB0, 0x1B, 0x62, 0x94, 0x01, 0x00, 0x05, 0x24, 0x21, 0x20, 0x00, 0x00, -0xEF, 0xFF, 0x42, 0x30, 0x20, 0x00, 0x42, 0x34, 0xB0, 0x1B, 0x62, 0xA4, -0x32, 0x00, 0x02, 0x24, 0x20, 0x40, 0x65, 0xAC, 0xB0, 0x39, 0x62, 0xAC, -0xCC, 0x39, 0x60, 0xAC, 0x18, 0x40, 0x60, 0xAC, 0x2D, 0x14, 0x00, 0x08, -0x1C, 0x40, 0x60, 0xAC, 0xE8, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x07, 0x3C, -0x14, 0x00, 0xBF, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x60, 0x1B, 0xE6, 0x24, -0x18, 0x40, 0xC2, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x45, 0x24, -0x03, 0x00, 0xA3, 0x2C, 0x0E, 0x00, 0x60, 0x14, 0x60, 0x1B, 0xF0, 0x24, -0x24, 0x40, 0xC3, 0x8C, 0x03, 0x00, 0x02, 0x24, 0x16, 0x00, 0x62, 0x10, -0xFF, 0xFF, 0x04, 0x24, 0xB0, 0x1B, 0xC2, 0x94, 0x18, 0x40, 0xC5, 0xAC, -0xFF, 0xDF, 0x42, 0x30, 0x35, 0x48, 0x00, 0x0C, 0xB0, 0x1B, 0xC2, 0xA4, -0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0xB0, 0x1B, 0x03, 0x96, 0xBF, 0xFF, 0x02, 0x24, -0x18, 0x40, 0xC5, 0xAC, 0x24, 0x10, 0x62, 0x00, 0x80, 0x00, 0x63, 0x30, -0x21, 0x20, 0x00, 0x00, 0x0F, 0x00, 0x60, 0x10, 0x20, 0x00, 0x45, 0x34, -0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0xB0, 0x1B, 0x03, 0x96, 0x01, 0x00, 0x02, 0x24, -0x24, 0x40, 0xC2, 0xAC, 0xBF, 0xFF, 0x02, 0x24, 0x24, 0x10, 0x62, 0x00, -0x80, 0x00, 0x63, 0x30, 0x18, 0x40, 0xC0, 0xAC, 0x21, 0x20, 0x00, 0x00, -0xF3, 0xFF, 0x60, 0x14, 0x20, 0x00, 0x45, 0x34, 0x01, 0x00, 0x02, 0x24, -0x20, 0x40, 0x02, 0xAE, 0x2D, 0x14, 0x00, 0x0C, 0xB0, 0x1B, 0x05, 0xA6, -0x32, 0x00, 0x03, 0x24, 0xB0, 0x39, 0x03, 0xAE, 0x14, 0x00, 0xBF, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, -0xD0, 0xFF, 0xBD, 0x27, 0x20, 0x00, 0xB2, 0xAF, 0x21, 0x90, 0x80, 0x00, -0x00, 0x01, 0x04, 0x24, 0x24, 0x00, 0xB3, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, -0x21, 0x98, 0xA0, 0x00, 0x28, 0x00, 0xBF, 0xAF, 0x53, 0x21, 0x00, 0x0C, -0x18, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, -0x21, 0x88, 0x40, 0x00, 0x58, 0xEC, 0x84, 0x24, 0x38, 0x00, 0x40, 0x10, -0x48, 0xEC, 0xA5, 0x24, 0x13, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0x30, 0x96, 0x02, 0x80, 0x02, 0x3C, 0x21, 0x28, 0x40, 0x02, -0x25, 0x80, 0x02, 0x02, 0x24, 0x00, 0x04, 0x26, 0x20, 0x00, 0x00, 0xA6, -0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x05, 0x3C, -0x2A, 0x00, 0x04, 0x26, 0x48, 0x37, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C, -0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x05, 0x3C, 0x30, 0x00, 0x04, 0x26, -0xB4, 0x55, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, -0x20, 0x00, 0x03, 0x96, 0x18, 0x00, 0x02, 0x24, 0x02, 0x80, 0x05, 0x3C, -0x03, 0xFF, 0x63, 0x30, 0xC0, 0x00, 0x63, 0x34, 0x20, 0x00, 0x03, 0xA6, -0x60, 0x1B, 0xA5, 0x24, 0x0C, 0x00, 0x22, 0xAE, 0xE4, 0x1D, 0xA3, 0x94, -0x20, 0x00, 0x07, 0x26, 0x38, 0x00, 0x04, 0x26, 0xFF, 0x0F, 0x62, 0x30, -0x00, 0x11, 0x02, 0x00, 0x02, 0x32, 0x02, 0x00, 0x01, 0x00, 0x63, 0x24, -0xE4, 0x1D, 0xA3, 0xA4, 0x17, 0x00, 0xE6, 0xA0, 0x16, 0x00, 0xE2, 0xA0, -0x10, 0x00, 0xA6, 0x27, 0x0C, 0x00, 0x27, 0x26, 0x02, 0x00, 0x05, 0x24, -0x4C, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB3, 0xA7, 0x21, 0x20, 0x20, 0x02, -0x21, 0x28, 0x00, 0x00, 0x21, 0x30, 0x00, 0x00, 0xDF, 0x0D, 0x00, 0x0C, -0x21, 0x38, 0x00, 0x00, 0x28, 0x00, 0xBF, 0x8F, 0x24, 0x00, 0xB3, 0x8F, -0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x04, 0x3C, -0x13, 0x58, 0x00, 0x0C, 0xAC, 0xE8, 0x84, 0x24, 0x28, 0x00, 0xBF, 0x8F, -0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, -0xD0, 0xFF, 0xBD, 0x27, 0x1C, 0x00, 0xB1, 0xAF, 0x21, 0x88, 0x80, 0x00, -0x00, 0x01, 0x04, 0x24, 0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF, -0x21, 0x98, 0xA0, 0x00, 0x28, 0x00, 0xBF, 0xAF, 0x53, 0x21, 0x00, 0x0C, -0x18, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, -0x21, 0x90, 0x40, 0x00, 0x78, 0xEC, 0x84, 0x24, 0x3B, 0x00, 0x40, 0x10, -0x68, 0xEC, 0xA5, 0x24, 0x13, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0x50, 0x96, 0x02, 0x80, 0x02, 0x3C, 0x21, 0x28, 0x20, 0x02, -0x25, 0x80, 0x02, 0x02, 0x24, 0x00, 0x04, 0x26, 0x20, 0x00, 0x00, 0xA6, -0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x05, 0x3C, -0x2A, 0x00, 0x04, 0x26, 0x48, 0x37, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C, -0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x05, 0x3C, 0x30, 0x00, 0x04, 0x26, -0xB4, 0x55, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, -0x20, 0x00, 0x03, 0x96, 0x18, 0x00, 0x02, 0x24, 0x02, 0x80, 0x11, 0x3C, -0x03, 0xFF, 0x63, 0x30, 0xA0, 0x00, 0x63, 0x34, 0x20, 0x00, 0x03, 0xA6, -0x60, 0x1B, 0x31, 0x26, 0x0C, 0x00, 0x42, 0xAE, 0xE4, 0x1D, 0x23, 0x96, -0x20, 0x00, 0x06, 0x26, 0x38, 0x00, 0x04, 0x26, 0xFF, 0x0F, 0x62, 0x30, -0x00, 0x11, 0x02, 0x00, 0x02, 0x2A, 0x02, 0x00, 0x01, 0x00, 0x63, 0x24, -0xE4, 0x1D, 0x23, 0xA6, 0x0C, 0x00, 0x47, 0x26, 0x17, 0x00, 0xC5, 0xA0, -0x16, 0x00, 0xC2, 0xA0, 0x02, 0x00, 0x05, 0x24, 0x10, 0x00, 0xA6, 0x27, -0x4C, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xB3, 0xA7, 0xB6, 0x40, 0x23, 0x92, -0x04, 0x00, 0x07, 0x24, 0x21, 0x20, 0x40, 0x02, 0x01, 0x00, 0x63, 0x38, -0x0B, 0x38, 0x03, 0x00, 0x21, 0x28, 0x00, 0x00, 0xDF, 0x0D, 0x00, 0x0C, -0x21, 0x30, 0x00, 0x00, 0x28, 0x00, 0xBF, 0x8F, 0x24, 0x00, 0xB3, 0x8F, -0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x04, 0x3C, -0x13, 0x58, 0x00, 0x0C, 0xAC, 0xE8, 0x84, 0x24, 0x28, 0x00, 0xBF, 0x8F, -0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, -0xC8, 0xFF, 0xBD, 0x27, 0x2C, 0x00, 0xB1, 0xAF, 0xFF, 0xFF, 0x05, 0x24, -0x21, 0x88, 0x80, 0x00, 0x02, 0x00, 0x06, 0x24, 0x10, 0x00, 0xA4, 0x27, -0x34, 0x00, 0xBF, 0xAF, 0x30, 0x00, 0xB2, 0xAF, 0xEC, 0x54, 0x00, 0x0C, -0x28, 0x00, 0xB0, 0xAF, 0x08, 0x00, 0x30, 0x96, 0x02, 0x80, 0x02, 0x3C, -0x21, 0x28, 0x00, 0x00, 0x25, 0x80, 0x02, 0x02, 0x21, 0x20, 0x00, 0x02, -0xEC, 0x54, 0x00, 0x0C, 0x10, 0x00, 0x06, 0x24, 0x20, 0x00, 0x02, 0x96, -0x24, 0x00, 0x04, 0x26, 0x10, 0x00, 0xA5, 0x27, 0x03, 0xFF, 0x42, 0x30, -0xC8, 0x00, 0x42, 0x34, 0x20, 0x00, 0x02, 0xA6, 0xF4, 0x54, 0x00, 0x0C, -0x06, 0x00, 0x06, 0x24, 0x25, 0xB0, 0x03, 0x3C, 0x50, 0x00, 0x62, 0x34, -0x00, 0x00, 0x44, 0x8C, 0x54, 0x00, 0x65, 0x34, 0x58, 0x00, 0x66, 0x34, -0x18, 0x00, 0xA4, 0xAF, 0x00, 0x00, 0xA2, 0x8C, 0x5C, 0x00, 0x63, 0x34, -0x2A, 0x00, 0x04, 0x26, 0x1C, 0x00, 0xA2, 0xAF, 0x00, 0x00, 0xC7, 0x8C, -0x18, 0x00, 0xA5, 0x27, 0x06, 0x00, 0x06, 0x24, 0x20, 0x00, 0xA7, 0xAF, -0x00, 0x00, 0x62, 0x8C, 0x1A, 0x00, 0x12, 0x24, 0xF4, 0x54, 0x00, 0x0C, -0x24, 0x00, 0xA2, 0xAF, 0x30, 0x00, 0x04, 0x26, 0x20, 0x00, 0xA5, 0x27, -0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x13, 0x00, 0x03, 0x24, -0x14, 0x00, 0x23, 0xAE, 0x0C, 0x00, 0x32, 0xAE, 0x08, 0x00, 0x05, 0x8E, -0x04, 0x00, 0x04, 0x8E, 0xFF, 0xDF, 0x02, 0x3C, 0x14, 0x00, 0x06, 0x8E, -0xFF, 0xFF, 0x42, 0x34, 0x10, 0x00, 0x07, 0x8E, 0xFF, 0xE0, 0x03, 0x24, -0x24, 0x28, 0xA2, 0x00, 0x00, 0x40, 0x02, 0x3C, 0x24, 0x20, 0x83, 0x00, -0x25, 0x28, 0xA2, 0x00, 0xFF, 0x81, 0x03, 0x24, 0xFE, 0xFF, 0x02, 0x3C, -0x24, 0x30, 0xC3, 0x00, 0xFF, 0xFF, 0x42, 0x34, 0x00, 0x12, 0x84, 0x34, -0x00, 0x80, 0x03, 0x3C, 0x24, 0x20, 0x82, 0x00, 0x25, 0x38, 0xE3, 0x00, -0x00, 0x26, 0xC6, 0x34, 0x80, 0x00, 0xA5, 0x34, 0x20, 0x00, 0x02, 0x24, -0x00, 0x00, 0x12, 0xA6, 0x10, 0x00, 0x07, 0xAE, 0x02, 0x00, 0x02, 0xA2, -0x14, 0x00, 0x06, 0xAE, 0x04, 0x00, 0x04, 0xAE, 0x08, 0x00, 0x05, 0xAE, -0x34, 0x00, 0xBF, 0x8F, 0x30, 0x00, 0xB2, 0x8F, 0x2C, 0x00, 0xB1, 0x8F, -0x28, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x38, 0x00, 0xBD, 0x27, -0xB0, 0xFF, 0xBD, 0x27, 0x3C, 0x00, 0xB5, 0xAF, 0x34, 0x00, 0xB3, 0xAF, -0xFF, 0xFF, 0xF5, 0x30, 0x25, 0xB0, 0x13, 0x3C, 0x01, 0x80, 0x02, 0x3C, -0x2C, 0x00, 0xB1, 0xAF, 0x18, 0x03, 0x63, 0x36, 0x54, 0x40, 0x42, 0x24, -0x20, 0x00, 0xB1, 0x26, 0x48, 0x00, 0xBE, 0xAF, 0x44, 0x00, 0xB7, 0xAF, -0x38, 0x00, 0xB4, 0xAF, 0x64, 0x00, 0xB7, 0x93, 0x60, 0x00, 0xB4, 0x93, -0x21, 0xF0, 0x80, 0x00, 0x00, 0x00, 0x62, 0xAC, 0x21, 0x20, 0x20, 0x02, -0x40, 0x00, 0xB6, 0xAF, 0x30, 0x00, 0xB2, 0xAF, 0x4C, 0x00, 0xBF, 0xAF, -0x28, 0x00, 0xB0, 0xAF, 0xFF, 0x00, 0xB6, 0x30, 0x53, 0x21, 0x00, 0x0C, -0xFF, 0x00, 0xD2, 0x30, 0x12, 0x00, 0x40, 0x14, 0x24, 0x00, 0xA2, 0xAF, -0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, 0xAC, 0xE8, 0x84, 0x24, -0x13, 0x58, 0x00, 0x0C, 0x88, 0xEC, 0xA5, 0x24, 0x4C, 0x00, 0xBF, 0x8F, -0x48, 0x00, 0xBE, 0x8F, 0x44, 0x00, 0xB7, 0x8F, 0x40, 0x00, 0xB6, 0x8F, -0x3C, 0x00, 0xB5, 0x8F, 0x38, 0x00, 0xB4, 0x8F, 0x34, 0x00, 0xB3, 0x8F, -0x30, 0x00, 0xB2, 0x8F, 0x2C, 0x00, 0xB1, 0x8F, 0x28, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x50, 0x00, 0xBD, 0x27, 0x08, 0x00, 0x43, 0x8C, -0xB0, 0x03, 0x62, 0x36, 0x02, 0x80, 0x10, 0x3C, 0x00, 0x00, 0x43, 0xAC, -0x24, 0x00, 0xA2, 0x8F, 0x21, 0x30, 0x20, 0x02, 0x21, 0x28, 0x00, 0x00, -0x08, 0x00, 0x44, 0x94, 0xE3, 0x54, 0x00, 0x0C, 0x25, 0x20, 0x90, 0x00, -0x24, 0x00, 0xA3, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x62, 0x94, -0x00, 0x00, 0x00, 0x00, 0x25, 0x88, 0x50, 0x00, 0x5C, 0x00, 0x80, 0x16, -0x20, 0x00, 0x30, 0x26, 0x20, 0x00, 0x32, 0xA6, 0x48, 0x00, 0x02, 0x24, -0x7A, 0x00, 0x42, 0x12, 0xC8, 0x00, 0x02, 0x24, 0x79, 0x00, 0x42, 0x12, -0x50, 0x00, 0x62, 0x36, 0x04, 0x00, 0x02, 0x24, 0x56, 0x00, 0xC2, 0x16, -0x21, 0x28, 0xC0, 0x03, 0xA4, 0x00, 0x02, 0x24, 0x9F, 0x00, 0x42, 0x12, -0x02, 0x80, 0x02, 0x3C, 0x24, 0x00, 0xA2, 0x8F, 0x25, 0xB0, 0x10, 0x3C, -0xB0, 0x03, 0x10, 0x36, 0x0C, 0x00, 0x55, 0xAC, 0x24, 0x00, 0xA2, 0x8F, -0x12, 0x00, 0x03, 0x24, 0x21, 0x28, 0x00, 0x00, 0x14, 0x00, 0x43, 0xAC, -0x00, 0x00, 0x15, 0xAE, 0x24, 0x00, 0xA2, 0x8F, 0x08, 0x00, 0x06, 0x24, -0x08, 0x00, 0x43, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xAE, -0x24, 0x00, 0xA2, 0x8F, 0x02, 0x80, 0x03, 0x3C, 0x08, 0x00, 0x44, 0x94, -0x00, 0x00, 0x00, 0x00, 0x25, 0x88, 0x83, 0x00, 0xEC, 0x54, 0x00, 0x0C, -0x21, 0x20, 0x20, 0x02, 0x04, 0x00, 0x25, 0x8E, 0x08, 0x00, 0x24, 0x8E, -0xFF, 0xDF, 0x02, 0x3C, 0xFF, 0xE0, 0x03, 0x24, 0xFF, 0xFF, 0x42, 0x34, -0x14, 0x00, 0x26, 0x8E, 0x24, 0x28, 0xA3, 0x00, 0x24, 0x20, 0x82, 0x00, -0x00, 0x40, 0x02, 0x3C, 0x10, 0x00, 0x27, 0x8E, 0x25, 0x20, 0x82, 0x00, -0xE0, 0xFF, 0x03, 0x24, 0x00, 0x12, 0xA5, 0x34, 0xFF, 0xE0, 0x02, 0x3C, -0x24, 0x28, 0xA3, 0x00, 0xFF, 0xFF, 0x42, 0x34, 0xFF, 0x81, 0x03, 0x24, -0x24, 0x30, 0xC3, 0x00, 0x24, 0x20, 0x82, 0x00, 0x00, 0x05, 0x03, 0x3C, -0x00, 0x80, 0x02, 0x3C, 0x25, 0x38, 0xE2, 0x00, 0x25, 0x20, 0x83, 0x00, -0x05, 0x00, 0xA5, 0x34, 0x20, 0x00, 0x02, 0x24, 0x08, 0x00, 0x24, 0xAE, -0x00, 0x00, 0x35, 0xA6, 0x02, 0x00, 0x22, 0xA2, 0x14, 0x00, 0x26, 0xAE, -0x10, 0x00, 0x27, 0xAE, 0x04, 0x00, 0x25, 0xAE, 0x8A, 0x40, 0x00, 0x0C, -0x20, 0x00, 0xA4, 0x27, 0x02, 0x80, 0x02, 0x3C, 0x24, 0x00, 0xA3, 0x8F, -0x98, 0x54, 0x42, 0x24, 0x04, 0x00, 0x44, 0x8C, 0x00, 0x00, 0x62, 0xAC, -0x04, 0x00, 0x43, 0xAC, 0x24, 0x00, 0xA2, 0x27, 0x00, 0x00, 0x83, 0xAC, -0x04, 0x00, 0x64, 0xAC, 0x20, 0x00, 0xA4, 0x27, 0x00, 0x00, 0x02, 0xAE, -0x90, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x00, 0xBF, 0x8F, -0x48, 0x00, 0xBE, 0x8F, 0x44, 0x00, 0xB7, 0x8F, 0x40, 0x00, 0xB6, 0x8F, -0x3C, 0x00, 0xB5, 0x8F, 0x38, 0x00, 0xB4, 0x8F, 0x34, 0x00, 0xB3, 0x8F, -0x30, 0x00, 0xB2, 0x8F, 0x2C, 0x00, 0xB1, 0x8F, 0x28, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x50, 0x00, 0xBD, 0x27, 0x00, 0x10, 0x42, 0x36, -0x53, 0x50, 0x00, 0x08, 0x20, 0x00, 0x22, 0xA6, 0x04, 0x00, 0x04, 0x26, -0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x05, 0x3C, -0x48, 0x37, 0xA5, 0x24, 0x0A, 0x00, 0x04, 0x26, 0xF4, 0x54, 0x00, 0x0C, -0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x05, 0x3C, 0xB4, 0x55, 0xA5, 0x24, -0x10, 0x00, 0x04, 0x26, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, -0x00, 0x1E, 0x12, 0x00, 0x03, 0x1E, 0x03, 0x00, 0x28, 0x00, 0x60, 0x04, -0x02, 0x80, 0x05, 0x3C, 0x60, 0x1B, 0xA5, 0x24, 0xE4, 0x1D, 0xA6, 0x94, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xC2, 0x24, 0x00, 0x21, 0x06, 0x00, -0xFF, 0xFF, 0x46, 0x30, 0xFF, 0xFF, 0x84, 0x30, 0x00, 0x10, 0xC2, 0x2C, -0x0A, 0x30, 0x02, 0x00, 0x02, 0x1A, 0x04, 0x00, 0x17, 0x00, 0x03, 0xA2, -0x16, 0x00, 0x04, 0xA2, 0x5E, 0x50, 0x00, 0x08, 0xE4, 0x1D, 0xA6, 0xA4, -0x50, 0x00, 0x62, 0x36, 0x00, 0x00, 0x43, 0x8C, 0x54, 0x00, 0x64, 0x36, -0x58, 0x00, 0x65, 0x36, 0x10, 0x00, 0xA3, 0xAF, 0x00, 0x00, 0x82, 0x8C, -0x5C, 0x00, 0x67, 0x36, 0x2A, 0x00, 0x24, 0x26, 0x14, 0x00, 0xA2, 0xAF, -0x00, 0x00, 0xA3, 0x8C, 0x06, 0x00, 0x06, 0x24, 0x10, 0x00, 0xA5, 0x27, -0x18, 0x00, 0xA3, 0xAF, 0x00, 0x00, 0xE2, 0x8C, 0xF4, 0x54, 0x00, 0x0C, -0x1C, 0x00, 0xA2, 0xAF, 0x30, 0x00, 0x24, 0x26, 0x18, 0x00, 0xA5, 0x27, -0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x20, 0x00, 0x23, 0x96, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x63, 0x34, 0x58, 0x50, 0x00, 0x08, -0x20, 0x00, 0x23, 0xA6, 0x02, 0x80, 0x02, 0x3C, 0xFF, 0xFF, 0xE3, 0x32, -0x60, 0x1B, 0x42, 0x24, 0x40, 0x28, 0x17, 0x00, 0x18, 0x00, 0x03, 0xA2, -0x21, 0x28, 0xA2, 0x00, 0x19, 0x00, 0x00, 0xA2, 0xD4, 0x1D, 0xA6, 0x94, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xC2, 0x24, 0x00, 0x21, 0x06, 0x00, -0xFF, 0xFF, 0x46, 0x30, 0xFF, 0xFF, 0x84, 0x30, 0x00, 0x10, 0xC2, 0x2C, -0x0A, 0x30, 0x02, 0x00, 0x02, 0x1A, 0x04, 0x00, 0x17, 0x00, 0x03, 0xA2, -0x16, 0x00, 0x04, 0xA2, 0x5E, 0x50, 0x00, 0x08, 0xD4, 0x1D, 0xA6, 0xA4, -0xAC, 0x55, 0x43, 0x94, 0x02, 0x80, 0x05, 0x3C, 0x04, 0x00, 0x04, 0x26, -0x00, 0xC0, 0x63, 0x24, 0xFF, 0xFF, 0x63, 0x30, 0x02, 0x12, 0x03, 0x00, -0xB4, 0x55, 0xA5, 0x24, 0x03, 0x00, 0x02, 0xA2, 0x02, 0x00, 0x03, 0xA2, -0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x02, 0x80, 0x05, 0x3C, -0x0A, 0x00, 0x04, 0x26, 0x48, 0x37, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C, -0x06, 0x00, 0x06, 0x24, 0x5E, 0x50, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0xFF, 0x00, 0x82, 0x30, 0x02, 0x80, 0x04, 0x3C, 0xE0, 0xFF, 0xBD, 0x27, -0xB4, 0x55, 0x84, 0x24, 0x08, 0x00, 0x05, 0x24, 0x48, 0x00, 0x06, 0x24, -0x18, 0x00, 0x07, 0x24, 0x18, 0x00, 0xBF, 0xAF, 0x10, 0x00, 0xA2, 0xAF, -0x15, 0x50, 0x00, 0x0C, 0x14, 0x00, 0xA0, 0xAF, 0x18, 0x00, 0xBF, 0x8F, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0xC8, 0xFF, 0xBD, 0x27, 0x2C, 0x00, 0xB5, 0xAF, 0x02, 0x80, 0x15, 0x3C, -0x1C, 0x00, 0xB1, 0xAF, 0x34, 0x00, 0xBF, 0xAF, 0x30, 0x00, 0xB6, 0xAF, -0x28, 0x00, 0xB4, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF, -0x18, 0x00, 0xB0, 0xAF, 0x60, 0x1B, 0xB1, 0x26, 0xB0, 0x1B, 0x23, 0x96, -0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x62, 0x30, 0x37, 0x00, 0x40, 0x14, -0x00, 0x01, 0x62, 0x30, 0x2A, 0x00, 0x40, 0x10, 0x00, 0x10, 0x62, 0x30, -0x25, 0x00, 0x40, 0x14, 0x01, 0x00, 0x62, 0x30, 0x45, 0x00, 0x40, 0x14, -0x04, 0x00, 0x62, 0x30, 0x21, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C, -0x21, 0x98, 0x20, 0x02, 0x47, 0x39, 0x56, 0x24, 0x01, 0x00, 0x14, 0x24, -0x20, 0x01, 0x11, 0x24, 0x3E, 0x51, 0x00, 0x08, 0x19, 0x00, 0x12, 0x24, -0xFF, 0xFF, 0x52, 0x26, 0x18, 0x00, 0x40, 0x06, 0x30, 0x00, 0x31, 0x26, -0x21, 0x80, 0x33, 0x02, 0xE6, 0x1D, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, -0xF9, 0xFF, 0x54, 0x14, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x1D, 0x02, 0x8E, -0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x40, 0x14, 0x10, 0x00, 0xA4, 0x27, -0x3A, 0x41, 0x62, 0x92, 0x21, 0x20, 0x36, 0x02, 0xFF, 0xFF, 0x42, 0x24, -0x3A, 0x41, 0x62, 0xA2, 0xC4, 0x0E, 0x00, 0x0C, 0xE6, 0x1D, 0x00, 0xA2, -0x3C, 0x51, 0x00, 0x08, 0xFF, 0xFF, 0x52, 0x26, 0x8A, 0x40, 0x00, 0x0C, -0x10, 0x00, 0xA4, 0x27, 0x10, 0x00, 0xA4, 0x27, 0x14, 0x40, 0x20, 0xAE, -0x90, 0x40, 0x00, 0x0C, 0xE8, 0x1E, 0x20, 0xAE, 0xA9, 0x1B, 0x00, 0x0C, -0x60, 0x1B, 0xB0, 0x26, 0xE8, 0x39, 0x02, 0xAE, 0x34, 0x00, 0xBF, 0x8F, -0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F, -0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x38, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x04, 0x3C, 0x13, 0x58, 0x00, 0x0C, -0x98, 0xEC, 0x84, 0x24, 0xB0, 0x1B, 0x22, 0x96, 0xE8, 0x39, 0x20, 0xAE, -0xFD, 0xFF, 0x04, 0x24, 0xEF, 0xDF, 0x42, 0x30, 0x35, 0x48, 0x00, 0x0C, -0xB0, 0x1B, 0x22, 0xA6, 0x34, 0x00, 0xBF, 0x8F, 0x30, 0x00, 0xB6, 0x8F, -0x2C, 0x00, 0xB5, 0x8F, 0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, -0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x38, 0x00, 0xBD, 0x27, -0xE8, 0x1E, 0x22, 0x8E, 0x00, 0x00, 0x00, 0x00, 0xD5, 0xFF, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x14, 0x40, 0x22, 0x8E, 0x00, 0x00, 0x00, 0x00, -0x18, 0x00, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, 0xEE, 0x5D, 0x43, 0x90, -0x01, 0x00, 0x04, 0x24, 0x0F, 0x00, 0x63, 0x30, 0x05, 0x00, 0x63, 0x28, -0x0E, 0x00, 0x60, 0x10, 0x14, 0x40, 0x24, 0xAE, 0x0E, 0x51, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0xA9, 0x1B, 0x00, 0x0C, 0x60, 0x1B, 0xB0, 0x26, -0x58, 0x51, 0x00, 0x08, 0xE8, 0x39, 0x02, 0xAE, 0x8A, 0x40, 0x00, 0x0C, -0xFF, 0xFF, 0x52, 0x26, 0x10, 0x00, 0xA4, 0x27, 0x90, 0x40, 0x00, 0x0C, -0xF8, 0x1D, 0x00, 0xAE, 0x3C, 0x51, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x0E, 0x51, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x00, 0x87, 0x51, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, 0x13, 0x58, 0x00, 0x0C, -0xB8, 0xEC, 0x84, 0x24, 0x25, 0xB0, 0x06, 0x3C, 0x4C, 0x00, 0xC2, 0x34, -0x00, 0x00, 0x40, 0xA0, 0x48, 0x00, 0xC6, 0x34, 0x00, 0x00, 0xC3, 0x8C, -0xB0, 0x1B, 0x27, 0x96, 0x7B, 0xFF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, -0x24, 0x18, 0x62, 0x00, 0xFE, 0xFE, 0xE7, 0x30, 0x00, 0x00, 0xC3, 0xAC, -0x21, 0x28, 0x00, 0x00, 0xB0, 0x1B, 0x27, 0xA6, 0x21, 0x20, 0x00, 0x00, -0x37, 0x3E, 0x20, 0xA2, 0x95, 0x0E, 0x00, 0x0C, 0xD6, 0x1E, 0x20, 0xA2, -0x02, 0x80, 0x04, 0x3C, 0xC4, 0x0E, 0x00, 0x0C, 0xB4, 0x55, 0x84, 0x24, -0xA9, 0x1B, 0x00, 0x0C, 0x60, 0x1B, 0xB0, 0x26, 0x58, 0x51, 0x00, 0x08, -0xE8, 0x39, 0x02, 0xAE, 0xFF, 0x00, 0x84, 0x30, 0x02, 0x00, 0x02, 0x24, -0x03, 0x00, 0x83, 0x28, 0x0D, 0x00, 0x82, 0x10, 0x21, 0x28, 0x00, 0x00, -0x06, 0x00, 0x60, 0x10, 0x04, 0x00, 0x02, 0x24, 0x01, 0x00, 0x02, 0x24, -0x0B, 0x00, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0xA0, 0x00, 0xFD, 0xFF, 0x82, 0x14, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, -0x04, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, -0x06, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, -0xD8, 0xFF, 0xBD, 0x27, 0x1C, 0x00, 0xB1, 0xAF, 0xFF, 0x00, 0x91, 0x30, -0x02, 0x80, 0x04, 0x3C, 0x18, 0x00, 0xB0, 0xAF, 0xD4, 0xEC, 0x84, 0x24, -0xFF, 0x00, 0xB0, 0x30, 0x20, 0x00, 0xBF, 0xAF, 0x13, 0x58, 0x00, 0x0C, -0x21, 0x28, 0x20, 0x02, 0xB1, 0x51, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x02, -0x02, 0x80, 0x04, 0x3C, 0xB4, 0x55, 0x84, 0x24, 0x08, 0x00, 0x05, 0x24, -0xC8, 0x00, 0x06, 0x24, 0x1A, 0x00, 0x07, 0x24, 0x10, 0x00, 0xB1, 0xAF, -0x15, 0x50, 0x00, 0x0C, 0x14, 0x00, 0xA2, 0xAF, 0x20, 0x00, 0xBF, 0x8F, -0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x28, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x05, 0x3C, -0x1C, 0x00, 0xBF, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x60, 0x1B, 0xA5, 0x24, -0x4C, 0x3A, 0xA2, 0x94, 0x01, 0x00, 0x03, 0x24, 0xFF, 0x00, 0x90, 0x30, -0x00, 0xC0, 0x42, 0x24, 0xFF, 0xFF, 0x44, 0x30, 0xA3, 0x31, 0x00, 0x0C, -0x2A, 0x1C, 0xA3, 0xA0, 0x02, 0x80, 0x04, 0x3C, 0xB4, 0x55, 0x84, 0x24, -0x04, 0x00, 0x05, 0x24, 0xA4, 0x00, 0x06, 0x24, 0x10, 0x00, 0x07, 0x24, -0x10, 0x00, 0xB0, 0xAF, 0x15, 0x50, 0x00, 0x0C, 0x14, 0x00, 0xA0, 0xAF, -0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x20, 0x00, 0xBD, 0x27, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x80, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x08, 0x00, 0x82, 0x24, 0xE0, 0xFF, 0xBD, 0x27, -0x18, 0x00, 0xBF, 0xAF, 0xFB, 0x51, 0x00, 0x0C, 0x74, 0x00, 0x84, 0x24, -0x21, 0x28, 0x40, 0x00, 0x10, 0x00, 0xA4, 0x27, 0xF4, 0x54, 0x00, 0x0C, -0x02, 0x00, 0x06, 0x24, 0x10, 0x00, 0xA2, 0x97, 0x18, 0x00, 0xBF, 0x8F, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xBF, 0xAF, 0xFB, 0x51, 0x00, 0x0C, -0x10, 0x00, 0xA5, 0xA7, 0x21, 0x20, 0x40, 0x00, 0x10, 0x00, 0xA5, 0x27, -0xF4, 0x54, 0x00, 0x0C, 0x02, 0x00, 0x06, 0x24, 0x18, 0x00, 0xBF, 0x8F, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0x08, 0x00, 0xE0, 0x03, 0x0A, 0x00, 0x82, 0x24, 0xE0, 0xFF, 0xBD, 0x27, -0x18, 0x00, 0xBF, 0xAF, 0x16, 0x52, 0x00, 0x0C, 0x74, 0x00, 0x84, 0x24, -0x21, 0x28, 0x40, 0x00, 0x10, 0x00, 0xA4, 0x27, 0xF4, 0x54, 0x00, 0x0C, -0x02, 0x00, 0x06, 0x24, 0x10, 0x00, 0xA2, 0x97, 0x18, 0x00, 0xBF, 0x8F, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0xE0, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0x80, 0x00, -0x00, 0x00, 0x05, 0xA2, 0x01, 0x00, 0x06, 0xA2, 0x18, 0x00, 0xB2, 0xAF, -0x14, 0x00, 0xB1, 0xAF, 0x1C, 0x00, 0xBF, 0xAF, 0x21, 0x88, 0xC0, 0x00, -0x02, 0x00, 0x84, 0x24, 0x30, 0x00, 0xB2, 0x8F, 0x0D, 0x00, 0xC0, 0x14, -0x21, 0x28, 0xE0, 0x00, 0x00, 0x00, 0x43, 0x8E, 0x21, 0x10, 0x11, 0x02, -0x1C, 0x00, 0xBF, 0x8F, 0x21, 0x18, 0x71, 0x00, 0x02, 0x00, 0x63, 0x24, -0x00, 0x00, 0x43, 0xAE, 0x14, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x02, 0x00, 0x42, 0x24, 0x08, 0x00, 0xE0, 0x03, -0x20, 0x00, 0xBD, 0x27, 0xF4, 0x54, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x43, 0x8E, 0x21, 0x10, 0x11, 0x02, 0x1C, 0x00, 0xBF, 0x8F, -0x21, 0x18, 0x71, 0x00, 0x02, 0x00, 0x63, 0x24, 0x00, 0x00, 0x43, 0xAE, -0x14, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x02, 0x00, 0x42, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0xE0, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0xA0, 0x00, -0x18, 0x00, 0xB2, 0xAF, 0x21, 0x28, 0xC0, 0x00, 0x21, 0x90, 0xE0, 0x00, -0x21, 0x30, 0x00, 0x02, 0x1C, 0x00, 0xBF, 0xAF, 0x14, 0x00, 0xB1, 0xAF, -0xF4, 0x54, 0x00, 0x0C, 0x21, 0x88, 0x80, 0x00, 0x00, 0x00, 0x43, 0x8E, -0x21, 0x10, 0x30, 0x02, 0x1C, 0x00, 0xBF, 0x8F, 0x21, 0x18, 0x70, 0x00, -0x00, 0x00, 0x43, 0xAE, 0x14, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0x7F, 0x00, 0x84, 0x30, 0x6D, 0x00, 0x82, 0x2C, 0x0A, 0x00, 0x40, 0x10, -0x21, 0x28, 0x00, 0x00, 0x02, 0x80, 0x03, 0x3C, 0x80, 0x10, 0x04, 0x00, -0xFC, 0xEC, 0x63, 0x24, 0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x44, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, -0x21, 0x28, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, -0x0B, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, -0x0A, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, -0x09, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, -0x08, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, -0x07, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, -0x06, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, -0x03, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, -0x05, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, -0x04, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, -0x02, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, -0x01, 0x00, 0x05, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, -0x7F, 0x00, 0x84, 0x30, 0x0C, 0x00, 0x82, 0x2C, 0x0A, 0x00, 0x40, 0x10, -0x21, 0x18, 0x00, 0x00, 0x02, 0x80, 0x03, 0x3C, 0x80, 0x10, 0x04, 0x00, -0xB0, 0xEE, 0x63, 0x24, 0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x44, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, -0x6C, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, -0x60, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, -0x48, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, -0x30, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, -0x24, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, -0x18, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, -0x12, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, -0x0C, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, -0x16, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, -0x0B, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, -0x04, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, -0x02, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, -0xC8, 0xFF, 0xBD, 0x27, 0x24, 0x00, 0xB5, 0xAF, 0x02, 0x80, 0x15, 0x3C, -0x2C, 0x00, 0xB7, 0xAF, 0x28, 0x00, 0xB6, 0xAF, 0x20, 0x00, 0xB4, 0xAF, -0x1C, 0x00, 0xB3, 0xAF, 0x30, 0x00, 0xBF, 0xAF, 0x18, 0x00, 0xB2, 0xAF, -0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x21, 0xB8, 0x80, 0x00, -0x21, 0xA0, 0x00, 0x00, 0x21, 0x98, 0x00, 0x00, 0x60, 0x1B, 0xB6, 0x26, -0x60, 0x1B, 0xA2, 0x26, 0x21, 0x10, 0x62, 0x02, 0xFB, 0x1B, 0x51, 0x90, -0xFE, 0x00, 0x03, 0x24, 0x1E, 0x00, 0x23, 0x12, 0xFF, 0x00, 0x02, 0x24, -0x21, 0x00, 0x22, 0x12, 0x21, 0x10, 0x80, 0x02, 0x91, 0x52, 0x00, 0x0C, -0x21, 0x20, 0x20, 0x02, 0x21, 0x88, 0x40, 0x00, 0x21, 0x80, 0x00, 0x00, -0x21, 0x90, 0xC0, 0x02, 0x21, 0x10, 0x12, 0x02, 0xEE, 0x1B, 0x44, 0x90, -0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x82, 0x24, 0xFF, 0x00, 0x42, 0x30, -0x02, 0x00, 0x42, 0x2C, 0x05, 0x00, 0x40, 0x14, 0x01, 0x00, 0x10, 0x26, -0x91, 0x52, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x51, 0x10, -0x01, 0x00, 0x03, 0x24, 0x0D, 0x00, 0x02, 0x2A, 0xF3, 0xFF, 0x40, 0x14, -0x21, 0x10, 0x12, 0x02, 0x21, 0x18, 0x00, 0x00, 0x01, 0x00, 0x02, 0x24, -0x14, 0x00, 0x62, 0x10, 0xFF, 0x00, 0x22, 0x32, 0x21, 0x10, 0xF4, 0x02, -0x00, 0x00, 0x51, 0xA0, 0x01, 0x00, 0x94, 0x26, 0x01, 0x00, 0x73, 0x26, -0x0D, 0x00, 0x62, 0x2A, 0xDB, 0xFF, 0x40, 0x14, 0x60, 0x1B, 0xA2, 0x26, -0x21, 0x10, 0x80, 0x02, 0x30, 0x00, 0xBF, 0x8F, 0x2C, 0x00, 0xB7, 0x8F, -0x28, 0x00, 0xB6, 0x8F, 0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F, -0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x38, 0x00, 0xBD, 0x27, -0xF0, 0x52, 0x00, 0x08, 0x80, 0x00, 0x51, 0x34, 0xD0, 0xFF, 0xBD, 0x27, -0x24, 0x00, 0xB1, 0xAF, 0x20, 0x00, 0xB0, 0xAF, 0x21, 0x88, 0x80, 0x00, -0x21, 0x80, 0xA0, 0x00, 0x0D, 0x00, 0x06, 0x24, 0x21, 0x28, 0x00, 0x00, -0x28, 0x00, 0xBF, 0xAF, 0xE3, 0x54, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, -0xC1, 0x52, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x00, 0x00, 0x02, 0xAE, -0x21, 0x20, 0x20, 0x02, 0x10, 0x00, 0xA5, 0x27, 0xF4, 0x54, 0x00, 0x0C, -0x21, 0x30, 0x40, 0x00, 0x28, 0x00, 0xBF, 0x8F, 0x24, 0x00, 0xB1, 0x8F, -0x20, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, -0x21, 0x28, 0x00, 0x00, 0x21, 0x10, 0x85, 0x00, 0x00, 0x00, 0x43, 0x90, -0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x60, 0x10, 0x0D, 0x00, 0xA2, 0x2C, -0xFA, 0xFF, 0x40, 0x14, 0x01, 0x00, 0xA5, 0x24, 0xFF, 0xFF, 0xA5, 0x24, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, 0x00, 0x00, 0x82, 0x94, -0x21, 0x30, 0x80, 0x00, 0x10, 0x00, 0x85, 0x24, 0x42, 0x1A, 0x02, 0x00, -0xC2, 0x11, 0x02, 0x00, 0x02, 0x00, 0x42, 0x30, 0x01, 0x00, 0x63, 0x30, -0x25, 0x18, 0x43, 0x00, 0x01, 0x00, 0x04, 0x24, 0x07, 0x00, 0x64, 0x10, -0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x60, 0x10, 0x0A, 0x00, 0xC5, 0x24, -0x02, 0x00, 0x02, 0x24, 0x02, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, -0x18, 0x00, 0xC5, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xA0, 0x00, -0x00, 0x00, 0x82, 0x94, 0x21, 0x30, 0x80, 0x00, 0x04, 0x00, 0x85, 0x24, -0x42, 0x1A, 0x02, 0x00, 0xC2, 0x11, 0x02, 0x00, 0x02, 0x00, 0x42, 0x30, -0x01, 0x00, 0x63, 0x30, 0x25, 0x18, 0x43, 0x00, 0x01, 0x00, 0x04, 0x24, -0x04, 0x00, 0x64, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x60, 0x10, -0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xC5, 0x24, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0xA0, 0x00, 0x13, 0x00, 0xA0, 0x18, 0x21, 0x30, 0x00, 0x00, -0x02, 0x00, 0x07, 0x24, 0x04, 0x00, 0x08, 0x24, 0x0B, 0x00, 0x09, 0x24, -0x16, 0x00, 0x0A, 0x24, 0x21, 0x10, 0x86, 0x00, 0x00, 0x00, 0x43, 0x90, -0x01, 0x00, 0xC6, 0x24, 0x7F, 0x00, 0x63, 0x30, 0x07, 0x00, 0x67, 0x10, -0x2A, 0x10, 0xC5, 0x00, 0x05, 0x00, 0x68, 0x10, 0x00, 0x00, 0x00, 0x00, -0x03, 0x00, 0x69, 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x6A, 0x14, -0x00, 0x00, 0x00, 0x00, 0xF3, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, -0x14, 0x00, 0xBF, 0xAF, 0x02, 0x80, 0x02, 0x3C, 0x5C, 0x5C, 0x43, 0x8C, -0x08, 0x00, 0x10, 0x24, 0x06, 0x00, 0xA0, 0x14, 0x0A, 0x80, 0x03, 0x00, -0x21, 0x10, 0x00, 0x02, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0x49, 0x53, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x36, 0x01, 0x00, 0x42, 0x38, -0x03, 0x00, 0x04, 0x36, 0x21, 0x80, 0x60, 0x00, 0x0B, 0x80, 0x82, 0x00, -0x21, 0x10, 0x00, 0x02, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27, -0x14, 0x00, 0xB1, 0xAF, 0x0E, 0x00, 0xA3, 0x2C, 0x21, 0x88, 0xA0, 0x00, -0x0D, 0x00, 0x02, 0x24, 0x0A, 0x88, 0x43, 0x00, 0x1C, 0x00, 0xB3, 0xAF, -0x18, 0x00, 0xB2, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x24, 0x00, 0xBF, 0xAF, -0x20, 0x00, 0xB4, 0xAF, 0x21, 0x98, 0x80, 0x00, 0x21, 0x90, 0x00, 0x00, -0x15, 0x00, 0x20, 0x12, 0x21, 0x80, 0x00, 0x00, 0x8E, 0x53, 0x00, 0x08, -0x01, 0x00, 0x14, 0x24, 0x2B, 0x10, 0x11, 0x02, 0x11, 0x00, 0x40, 0x10, -0x21, 0x10, 0x40, 0x02, 0x21, 0x18, 0x70, 0x02, 0x00, 0x00, 0x62, 0x90, -0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x44, 0x30, 0x00, 0x16, 0x02, 0x00, -0x03, 0x16, 0x02, 0x00, 0xF6, 0xFF, 0x41, 0x04, 0x01, 0x00, 0x10, 0x26, -0x61, 0x52, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x04, 0x10, 0x54, 0x00, -0x25, 0x90, 0x42, 0x02, 0x2B, 0x10, 0x11, 0x02, 0xF3, 0xFF, 0x40, 0x14, -0x21, 0x18, 0x70, 0x02, 0x21, 0x10, 0x40, 0x02, 0x24, 0x00, 0xBF, 0x8F, -0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x28, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF, -0x0E, 0x00, 0xA3, 0x2C, 0x21, 0x88, 0xA0, 0x00, 0x0D, 0x00, 0x02, 0x24, -0x0A, 0x88, 0x43, 0x00, 0x20, 0x00, 0xB4, 0xAF, 0x18, 0x00, 0xB2, 0xAF, -0x10, 0x00, 0xB0, 0xAF, 0x24, 0x00, 0xBF, 0xAF, 0x1C, 0x00, 0xB3, 0xAF, -0x21, 0xA0, 0x80, 0x00, 0x21, 0x90, 0x00, 0x00, 0x0A, 0x00, 0x20, 0x12, -0x21, 0x80, 0x00, 0x00, 0x01, 0x00, 0x13, 0x24, 0x21, 0x10, 0x90, 0x02, -0x00, 0x00, 0x44, 0x90, 0x61, 0x52, 0x00, 0x0C, 0x01, 0x00, 0x10, 0x26, -0x04, 0x10, 0x53, 0x00, 0x2B, 0x18, 0x11, 0x02, 0xF9, 0xFF, 0x60, 0x14, -0x25, 0x90, 0x42, 0x02, 0x21, 0x10, 0x40, 0x02, 0x24, 0x00, 0xBF, 0x8F, -0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x28, 0x00, 0xBD, 0x27, 0xE8, 0xFF, 0xBD, 0x27, 0xFF, 0xFF, 0x02, 0x24, -0x10, 0x00, 0xB0, 0xAF, 0x14, 0x00, 0xBF, 0xAF, 0x21, 0x30, 0xA0, 0x00, -0x1B, 0x00, 0x82, 0x10, 0x20, 0x00, 0x10, 0x24, 0x20, 0x00, 0x82, 0x28, -0x06, 0x00, 0x40, 0x14, 0x40, 0x18, 0x04, 0x00, 0x21, 0x10, 0x00, 0x02, -0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0x21, 0x18, 0x64, 0x00, 0x21, 0x80, 0x80, 0x00, -0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x04, 0x3C, 0x00, 0x19, 0x03, 0x00, -0x60, 0x1B, 0x42, 0x24, 0x47, 0x39, 0x84, 0x24, 0x21, 0x20, 0x64, 0x00, -0x21, 0x18, 0x62, 0x00, 0x01, 0x00, 0x02, 0x24, 0x06, 0x00, 0x06, 0x24, -0xF4, 0x54, 0x00, 0x0C, 0xE6, 0x1D, 0x62, 0xA0, 0x21, 0x10, 0x00, 0x02, -0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, -0xF0, 0x00, 0x47, 0x24, 0x05, 0x00, 0x10, 0x24, 0xD6, 0x1E, 0x43, 0x24, -0xF4, 0x53, 0x00, 0x08, 0xF0, 0x00, 0x05, 0x24, 0x01, 0x00, 0x10, 0x26, -0x20, 0x00, 0x02, 0x2E, 0x30, 0x00, 0xA5, 0x24, 0xDE, 0xFF, 0x40, 0x10, -0x30, 0x00, 0xE7, 0x24, 0x00, 0x00, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, -0xF8, 0xFF, 0x40, 0x14, 0x30, 0x00, 0x63, 0x24, 0x02, 0x80, 0x04, 0x3C, -0x47, 0x39, 0x84, 0x24, 0x01, 0x00, 0x02, 0x24, 0x21, 0x20, 0xA4, 0x00, -0xE6, 0x1D, 0xE2, 0xA0, 0x21, 0x28, 0xC0, 0x00, 0xF4, 0x54, 0x00, 0x0C, -0x06, 0x00, 0x06, 0x24, 0xE4, 0x53, 0x00, 0x08, 0x21, 0x10, 0x00, 0x02, -0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF, -0x30, 0x00, 0xB2, 0x8F, 0x21, 0x88, 0x80, 0x00, 0x21, 0x20, 0xA0, 0x00, -0x21, 0x28, 0x20, 0x02, 0x10, 0x00, 0xB0, 0xAF, 0x1C, 0x00, 0xBF, 0xAF, -0xC7, 0x53, 0x00, 0x0C, 0xFF, 0xFF, 0xF0, 0x30, 0x20, 0x00, 0x03, 0x24, -0xFF, 0x00, 0x44, 0x30, 0x21, 0x28, 0x00, 0x02, 0x21, 0x30, 0x20, 0x02, -0x07, 0x00, 0x43, 0x10, 0x21, 0x38, 0x40, 0x02, 0x1C, 0x00, 0xBF, 0x8F, -0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x6F, 0x20, 0x00, 0x08, 0x20, 0x00, 0xBD, 0x27, 0x1C, 0x00, 0xBF, 0x8F, -0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0xD0, 0xFF, 0xBD, 0x27, -0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0x24, 0x00, 0xB5, 0xAF, -0x20, 0x00, 0xB4, 0xAF, 0x1C, 0x00, 0xB3, 0xAF, 0x18, 0x00, 0xB2, 0xAF, -0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0x21, 0xA8, 0x80, 0x00, -0x60, 0x1B, 0x54, 0x24, 0x47, 0x39, 0x73, 0x24, 0x05, 0x00, 0x11, 0x24, -0x01, 0x00, 0x12, 0x24, 0xF0, 0x00, 0x10, 0x24, 0x34, 0x54, 0x00, 0x08, -0x28, 0x00, 0xBF, 0xAF, 0x01, 0x00, 0x31, 0x26, 0x20, 0x00, 0x22, 0x2A, -0x0E, 0x00, 0x40, 0x10, 0x21, 0x10, 0x20, 0x02, 0x21, 0x10, 0x14, 0x02, -0xE6, 0x1D, 0x43, 0x90, 0x21, 0x20, 0x13, 0x02, 0x21, 0x28, 0xA0, 0x02, -0x06, 0x00, 0x06, 0x24, 0xF6, 0xFF, 0x72, 0x14, 0x30, 0x00, 0x10, 0x26, -0x1D, 0x55, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xF3, 0xFF, 0x40, 0x14, -0x01, 0x00, 0x31, 0x26, 0xFF, 0xFF, 0x31, 0x26, 0x21, 0x10, 0x20, 0x02, -0x28, 0x00, 0xBF, 0x8F, 0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F, -0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x30, 0x00, 0xBD, 0x27, -0xD0, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, -0x28, 0x00, 0xB6, 0xAF, 0x24, 0x00, 0xB5, 0xAF, 0x20, 0x00, 0xB4, 0xAF, -0x1C, 0x00, 0xB3, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, -0x21, 0x98, 0x80, 0x00, 0x60, 0x1B, 0x56, 0x24, 0x47, 0x39, 0x75, 0x24, -0x21, 0x88, 0x00, 0x00, 0x01, 0x00, 0x14, 0x24, 0x21, 0x80, 0x00, 0x00, -0x2C, 0x00, 0xBF, 0xAF, 0x60, 0x54, 0x00, 0x08, 0x18, 0x00, 0xB2, 0xAF, -0x01, 0x00, 0x31, 0x26, 0x20, 0x00, 0x22, 0x2A, 0x1E, 0x00, 0x40, 0x10, -0x00, 0x00, 0x00, 0x00, 0x21, 0x90, 0x16, 0x02, 0xE6, 0x1D, 0x42, 0x92, -0x21, 0x20, 0x15, 0x02, 0x21, 0x28, 0x60, 0x02, 0x06, 0x00, 0x06, 0x24, -0xF6, 0xFF, 0x54, 0x14, 0x30, 0x00, 0x10, 0x26, 0x1D, 0x55, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0xF3, 0xFF, 0x40, 0x14, 0x01, 0x00, 0x31, 0x26, -0xFF, 0xFF, 0x31, 0x26, 0x02, 0x80, 0x06, 0x3C, 0x02, 0x80, 0x07, 0x3C, -0xFF, 0x00, 0x24, 0x32, 0xE6, 0x1D, 0x40, 0xA2, 0x2C, 0x00, 0xBF, 0x8F, -0x28, 0x00, 0xB6, 0x8F, 0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F, -0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x88, 0xDE, 0xC6, 0x24, 0x78, 0xDE, 0xE7, 0x24, -0x21, 0x28, 0x00, 0x00, 0x6F, 0x20, 0x00, 0x08, 0x30, 0x00, 0xBD, 0x27, -0x2C, 0x00, 0xBF, 0x8F, 0x28, 0x00, 0xB6, 0x8F, 0x24, 0x00, 0xB5, 0x8F, -0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x30, 0x00, 0xBD, 0x27, 0xC8, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, -0x18, 0x00, 0xB2, 0xAF, 0x60, 0x1B, 0x52, 0x24, 0x30, 0x00, 0xBE, 0xAF, -0x2C, 0x00, 0xB7, 0xAF, 0x28, 0x00, 0xB6, 0xAF, 0x24, 0x00, 0xB5, 0xAF, -0x20, 0x00, 0xB4, 0xAF, 0x1C, 0x00, 0xB3, 0xAF, 0x14, 0x00, 0xB1, 0xAF, -0x10, 0x00, 0xB0, 0xAF, 0x34, 0x00, 0xBF, 0xAF, 0x21, 0x80, 0x00, 0x00, -0x02, 0x80, 0x1E, 0x3C, 0x02, 0x80, 0x17, 0x3C, 0x02, 0x80, 0x16, 0x3C, -0x01, 0x00, 0x13, 0x24, 0xFF, 0xF7, 0x15, 0x24, 0xFF, 0xEF, 0x14, 0x24, -0x21, 0x88, 0x40, 0x02, 0xE6, 0x1D, 0x22, 0x92, 0xC0, 0x48, 0x10, 0x00, -0xD2, 0x5C, 0xC7, 0x93, 0x41, 0x00, 0x53, 0x10, 0x21, 0x30, 0x32, 0x01, -0xD4, 0x23, 0xC2, 0x8C, 0xBF, 0xFF, 0x03, 0x24, 0x24, 0x28, 0x43, 0x00, -0x80, 0x07, 0xA3, 0x34, 0x24, 0x10, 0x75, 0x00, 0x31, 0x00, 0xF3, 0x10, -0x24, 0x10, 0x54, 0x00, 0xD4, 0x23, 0xC2, 0xAC, 0x21, 0x48, 0x32, 0x01, -0xD4, 0x23, 0x23, 0x8D, 0xFD, 0xFF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, -0x24, 0x18, 0x62, 0x00, 0xFB, 0xFF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, -0x24, 0x18, 0x62, 0x00, 0xE7, 0xFF, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, -0x24, 0x18, 0x62, 0x00, 0xFF, 0xFD, 0x02, 0x3C, 0xFF, 0xFF, 0x42, 0x34, -0xD8, 0x23, 0x28, 0x8D, 0x24, 0x18, 0x62, 0x00, 0xFF, 0xFB, 0x02, 0x3C, -0xFF, 0xFF, 0x42, 0x34, 0x24, 0x18, 0x62, 0x00, 0xFF, 0xE7, 0x02, 0x3C, -0xFF, 0xFF, 0x42, 0x34, 0x1F, 0x00, 0x06, 0x3C, 0x00, 0x80, 0x08, 0x35, -0x24, 0x18, 0x62, 0x00, 0x25, 0x40, 0x06, 0x01, 0xFF, 0x00, 0x04, 0x32, -0x21, 0x28, 0x00, 0x00, 0x01, 0x00, 0x10, 0x26, 0x88, 0xDE, 0xE6, 0x26, -0x78, 0xDE, 0xC7, 0x26, 0xD8, 0x23, 0x28, 0xAD, 0x6F, 0x20, 0x00, 0x0C, -0xD4, 0x23, 0x23, 0xAD, 0x20, 0x00, 0x02, 0x2A, 0xD1, 0xFF, 0x40, 0x14, -0x30, 0x00, 0x31, 0x26, 0x34, 0x00, 0xBF, 0x8F, 0x30, 0x00, 0xBE, 0x8F, -0x2C, 0x00, 0xB7, 0x8F, 0x28, 0x00, 0xB6, 0x8F, 0x24, 0x00, 0xB5, 0x8F, -0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x38, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, 0xD3, 0x5C, 0x44, 0x90, -0x24, 0x18, 0x75, 0x00, 0x80, 0x0F, 0xA2, 0x34, 0x00, 0x10, 0x63, 0x34, -0xCA, 0xFF, 0x87, 0x14, 0x24, 0x10, 0x54, 0x00, 0xA9, 0x54, 0x00, 0x08, -0xD4, 0x23, 0xC3, 0xAC, 0xA1, 0x54, 0x00, 0x08, 0xE6, 0x1D, 0x20, 0xA2, -0xE8, 0x54, 0x00, 0x08, 0xFF, 0x00, 0xA5, 0x30, 0x00, 0x00, 0x85, 0xA0, -0xFF, 0xFF, 0xC6, 0x24, 0x01, 0x00, 0x84, 0x24, 0xFC, 0xFF, 0xC0, 0x14, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0x05, 0x00, 0xC0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xAC, -0xFF, 0xFF, 0xC6, 0x24, 0xFD, 0xFF, 0xC0, 0x14, 0x04, 0x00, 0x84, 0x24, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x21, 0x38, 0x80, 0x00, -0x08, 0x00, 0xC0, 0x10, 0xFF, 0xFF, 0xC3, 0x24, 0xFF, 0xFF, 0x06, 0x24, -0x00, 0x00, 0xA2, 0x90, 0xFF, 0xFF, 0x63, 0x24, 0x01, 0x00, 0xA5, 0x24, -0x00, 0x00, 0xE2, 0xA0, 0xFB, 0xFF, 0x66, 0x14, 0x01, 0x00, 0xE7, 0x24, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x80, 0x00, 0x2B, 0x10, 0xA4, 0x00, -0x0D, 0x00, 0x40, 0x14, 0xFF, 0xFF, 0x02, 0x24, 0xFF, 0xFF, 0xC6, 0x24, -0x08, 0x00, 0xC2, 0x10, 0x21, 0x18, 0x80, 0x00, 0xFF, 0xFF, 0x07, 0x24, -0x00, 0x00, 0xA2, 0x90, 0xFF, 0xFF, 0xC6, 0x24, 0x01, 0x00, 0xA5, 0x24, -0x00, 0x00, 0x62, 0xA0, 0xFB, 0xFF, 0xC7, 0x14, 0x01, 0x00, 0x63, 0x24, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x80, 0x00, 0x21, 0x28, 0xA6, 0x00, -0x21, 0x18, 0x86, 0x00, 0xFF, 0xFF, 0xC6, 0x24, 0xFA, 0xFF, 0xC2, 0x10, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x07, 0x24, 0xFF, 0xFF, 0xA5, 0x24, -0x00, 0x00, 0xA2, 0x90, 0xFF, 0xFF, 0x63, 0x24, 0xFF, 0xFF, 0xC6, 0x24, -0xFB, 0xFF, 0xC7, 0x14, 0x00, 0x00, 0x62, 0xA0, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0x80, 0x00, 0x0C, 0x00, 0xC0, 0x10, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x82, 0x90, 0x00, 0x00, 0xA3, 0x90, 0x01, 0x00, 0x84, 0x24, -0x23, 0x10, 0x43, 0x00, 0x00, 0x16, 0x02, 0x00, 0x03, 0x16, 0x02, 0x00, -0x04, 0x00, 0x40, 0x14, 0x01, 0x00, 0xA5, 0x24, 0xFF, 0xFF, 0xC6, 0x24, -0xF6, 0xFF, 0xC0, 0x14, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0xC0, 0x00, 0x33, 0x55, 0x00, 0x08, 0x21, 0x18, 0x86, 0x00, -0x00, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x45, 0x10, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x84, 0x24, 0xFA, 0xFF, 0x83, 0x14, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x80, 0x00, -0x09, 0x00, 0xC0, 0x10, 0xFF, 0xFF, 0xC3, 0x24, 0xFF, 0x00, 0xA5, 0x30, -0xFF, 0xFF, 0x06, 0x24, 0x00, 0x00, 0x82, 0x90, 0xFF, 0xFF, 0x63, 0x24, -0x05, 0x00, 0x45, 0x10, 0x01, 0x00, 0x84, 0x24, 0xFB, 0xFF, 0x66, 0x14, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0xFF, 0xFF, 0x82, 0x24, 0x21, 0x38, 0x00, 0x00, -0x1F, 0x00, 0xC0, 0x10, 0x21, 0x18, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C, -0x40, 0xF4, 0x4B, 0x24, 0x00, 0x00, 0x87, 0x90, 0x00, 0x00, 0xA3, 0x90, -0xFF, 0xFF, 0xC6, 0x24, 0x01, 0x00, 0x84, 0x24, 0x21, 0x10, 0xEB, 0x00, -0x16, 0x00, 0xE0, 0x10, 0x01, 0x00, 0xA5, 0x24, 0x14, 0x00, 0x60, 0x10, -0x21, 0x48, 0x6B, 0x00, 0x10, 0x00, 0xE3, 0x10, 0x20, 0x00, 0xE8, 0x24, -0x00, 0x00, 0x42, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, -0x02, 0x00, 0x40, 0x10, 0x20, 0x00, 0x6A, 0x24, 0xFF, 0x00, 0x07, 0x31, -0x00, 0x00, 0x22, 0x91, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, -0x02, 0x00, 0x40, 0x10, 0xFF, 0x00, 0xE7, 0x30, 0xFF, 0x00, 0x43, 0x31, -0xFF, 0x00, 0x63, 0x30, 0x03, 0x00, 0xE3, 0x14, 0x00, 0x00, 0x00, 0x00, -0xE5, 0xFF, 0xC0, 0x14, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x23, 0x10, 0xE3, 0x00, 0x21, 0x18, 0x80, 0x00, 0x00, 0x00, 0xA2, 0x90, -0x01, 0x00, 0xA5, 0x24, 0x00, 0x00, 0x82, 0xA0, 0xFC, 0xFF, 0x40, 0x14, -0x01, 0x00, 0x84, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, -0x21, 0x38, 0x80, 0x00, 0xFF, 0xFF, 0x03, 0x24, 0xFF, 0xFF, 0xC6, 0x24, -0x06, 0x00, 0xC3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x90, -0x01, 0x00, 0xA5, 0x24, 0x00, 0x00, 0x82, 0xA0, 0xF9, 0xFF, 0x40, 0x14, -0x01, 0x00, 0x84, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xE0, 0x00, -0x00, 0x00, 0x82, 0x80, 0x82, 0x55, 0x00, 0x08, 0x21, 0x18, 0x80, 0x00, -0x01, 0x00, 0x84, 0x24, 0x00, 0x00, 0x82, 0x80, 0x00, 0x00, 0x00, 0x00, -0xFC, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x90, -0x01, 0x00, 0xA5, 0x24, 0x00, 0x00, 0x82, 0xA0, 0xFC, 0xFF, 0x40, 0x14, -0x01, 0x00, 0x84, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, -0x12, 0x00, 0xC0, 0x10, 0x21, 0x18, 0x80, 0x00, 0x00, 0x00, 0x82, 0x80, -0x93, 0x55, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x84, 0x24, -0x00, 0x00, 0x82, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x90, 0x01, 0x00, 0xA5, 0x24, -0x00, 0x00, 0x82, 0xA0, 0x05, 0x00, 0x40, 0x10, 0x01, 0x00, 0x84, 0x24, -0xFF, 0xFF, 0xC6, 0x24, 0xF9, 0xFF, 0xC0, 0x14, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x80, 0xA0, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, -0x00, 0x00, 0x83, 0x90, 0x00, 0x00, 0xA2, 0x90, 0x01, 0x00, 0x84, 0x24, -0x23, 0x10, 0x62, 0x00, 0x00, 0x16, 0x02, 0x00, 0x03, 0x16, 0x02, 0x00, -0x03, 0x00, 0x40, 0x14, 0x01, 0x00, 0xA5, 0x24, 0xF7, 0xFF, 0x60, 0x14, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0x21, 0x10, 0x00, 0x00, 0x0B, 0x00, 0xC0, 0x10, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xA2, 0x90, 0x00, 0x00, 0x83, 0x90, 0xFF, 0xFF, 0xC6, 0x24, -0x23, 0x10, 0x62, 0x00, 0x00, 0x16, 0x02, 0x00, 0x03, 0x16, 0x02, 0x00, -0x03, 0x00, 0x40, 0x14, 0x01, 0x00, 0xA5, 0x24, 0xF5, 0xFF, 0x60, 0x14, -0x01, 0x00, 0x84, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x83, 0x80, 0x00, 0x2E, 0x05, 0x00, 0x21, 0x10, 0x80, 0x00, -0xC4, 0x55, 0x00, 0x08, 0x03, 0x2E, 0x05, 0x00, 0x07, 0x00, 0x60, 0x10, -0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, -0xFB, 0xFF, 0x65, 0x14, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, -0x00, 0x00, 0x82, 0x80, 0xD0, 0x55, 0x00, 0x08, 0x21, 0x18, 0x80, 0x00, -0x01, 0x00, 0x63, 0x24, 0x00, 0x00, 0x62, 0x80, 0x00, 0x00, 0x00, 0x00, -0xFC, 0xFF, 0x40, 0x14, 0x23, 0x10, 0x64, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, -0x21, 0x80, 0xA0, 0x00, 0x14, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xBF, 0xAF, -0x21, 0x88, 0x80, 0x00, 0xCA, 0x55, 0x00, 0x0C, 0x00, 0x86, 0x10, 0x00, -0x21, 0x18, 0x51, 0x00, 0x03, 0x86, 0x10, 0x00, 0x00, 0x00, 0x62, 0x80, -0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x50, 0x10, 0x21, 0x10, 0x60, 0x00, -0xFF, 0xFF, 0x63, 0x24, 0x2B, 0x10, 0x71, 0x00, 0xF9, 0xFF, 0x40, 0x10, -0x21, 0x10, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0x21, 0x30, 0x80, 0x00, -0x0D, 0x00, 0xA0, 0x10, 0xFF, 0xFF, 0xA3, 0x24, 0x00, 0x00, 0x82, 0x80, -0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, -0xFF, 0xFF, 0x05, 0x24, 0xFF, 0xFF, 0x63, 0x24, 0x05, 0x00, 0x65, 0x10, -0x01, 0x00, 0xC6, 0x24, 0x00, 0x00, 0xC2, 0x80, 0x00, 0x00, 0x00, 0x00, -0xFA, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x23, 0x10, 0xC4, 0x00, 0x00, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, -0x19, 0x00, 0x40, 0x10, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0xA9, 0x80, -0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x20, 0x11, 0x21, 0x30, 0xA0, 0x00, -0x00, 0x3E, 0x02, 0x00, 0x03, 0x3E, 0x07, 0x00, 0x21, 0x18, 0x20, 0x01, -0x15, 0x00, 0xE3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xC6, 0x24, -0x00, 0x00, 0xC2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x02, 0x00, -0x03, 0x1E, 0x03, 0x00, 0xF8, 0xFF, 0x60, 0x14, 0x00, 0x16, 0x02, 0x00, -0x03, 0x16, 0x02, 0x00, 0x06, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x84, 0x24, 0x00, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, -0xEB, 0xFF, 0x40, 0x14, 0x01, 0x00, 0x08, 0x25, 0x08, 0x00, 0xE0, 0x03, -0x21, 0x10, 0x00, 0x01, 0x00, 0x00, 0xA2, 0x90, 0x15, 0x56, 0x00, 0x08, -0x00, 0x16, 0x02, 0x00, 0x00, 0x00, 0xC2, 0x90, 0x15, 0x56, 0x00, 0x08, -0x00, 0x16, 0x02, 0x00, 0x00, 0x00, 0x87, 0x90, 0x00, 0x00, 0x00, 0x00, -0x14, 0x00, 0xE0, 0x10, 0x21, 0x10, 0x80, 0x00, 0x00, 0x00, 0xA4, 0x90, -0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x04, 0x00, 0x03, 0x1E, 0x03, 0x00, -0x09, 0x00, 0x60, 0x10, 0x21, 0x30, 0xA0, 0x00, 0x00, 0x3E, 0x07, 0x00, -0x03, 0x3E, 0x07, 0x00, 0x0B, 0x00, 0xE3, 0x10, 0x01, 0x00, 0xC6, 0x24, -0x00, 0x00, 0xC3, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFB, 0xFF, 0x60, 0x14, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0x00, 0x00, 0x47, 0x90, -0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0xE0, 0x14, 0x00, 0x00, 0x00, 0x00, -0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0xE0, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, -0x18, 0x00, 0xBF, 0xAF, 0x21, 0x80, 0x80, 0x00, 0x1D, 0x00, 0x80, 0x10, -0x21, 0x88, 0xA0, 0x00, 0x01, 0x56, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x02, -0x21, 0x80, 0x02, 0x02, 0x00, 0x00, 0x02, 0x82, 0x21, 0x28, 0x20, 0x02, -0x21, 0x20, 0x00, 0x02, 0x22, 0x00, 0x40, 0x10, 0x21, 0x18, 0x00, 0x00, -0x25, 0x56, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x40, 0x10, -0x21, 0x18, 0x40, 0x00, 0x00, 0x00, 0x42, 0x80, 0x00, 0x00, 0x00, 0x00, -0x0A, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C, -0x58, 0xF5, 0x43, 0xAC, 0x21, 0x18, 0x00, 0x02, 0x18, 0x00, 0xBF, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x60, 0xA0, -0x56, 0x56, 0x00, 0x08, 0x01, 0x00, 0x63, 0x24, 0x02, 0x80, 0x02, 0x3C, -0x58, 0xF5, 0x50, 0x8C, 0x00, 0x00, 0x00, 0x00, 0xF3, 0xFF, 0x00, 0x12, -0x21, 0x18, 0x00, 0x00, 0x01, 0x56, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x02, -0x21, 0x80, 0x02, 0x02, 0x00, 0x00, 0x02, 0x82, 0x21, 0x28, 0x20, 0x02, -0x21, 0x20, 0x00, 0x02, 0xE0, 0xFF, 0x40, 0x14, 0x21, 0x18, 0x00, 0x00, -0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x02, 0x80, 0x02, 0x3C, 0x58, 0xF5, 0x40, 0xAC, 0x20, 0x00, 0xBD, 0x27, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, 0xE0, 0xFF, 0xBD, 0x27, -0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x1C, 0x00, 0xBF, 0xAF, -0x10, 0x00, 0xB0, 0xAF, 0x00, 0x00, 0x90, 0x8C, 0x21, 0x90, 0x80, 0x00, -0x21, 0x88, 0xA0, 0x00, 0x21, 0x18, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x12, -0x21, 0x20, 0x00, 0x02, 0x01, 0x56, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x21, 0x80, 0x02, 0x02, 0x00, 0x00, 0x02, 0x82, 0x21, 0x28, 0x20, 0x02, -0x21, 0x20, 0x00, 0x02, 0x07, 0x00, 0x40, 0x10, 0x21, 0x18, 0x00, 0x00, -0x25, 0x56, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x21, 0x18, 0x40, 0x00, -0x09, 0x00, 0x40, 0x14, 0x00, 0x00, 0x42, 0xAE, 0x21, 0x18, 0x00, 0x02, -0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x20, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x42, 0x80, 0x00, 0x00, 0x00, 0x00, -0xF5, 0xFF, 0x40, 0x10, 0x01, 0x00, 0x64, 0x24, 0x00, 0x00, 0x60, 0xA0, -0x8F, 0x56, 0x00, 0x08, 0x00, 0x00, 0x44, 0xAE, 0xD8, 0xFF, 0xBD, 0x27, -0x14, 0x00, 0xB1, 0xAF, 0x21, 0x88, 0x80, 0x00, 0x21, 0x20, 0xA0, 0x00, -0x1C, 0x00, 0xB3, 0xAF, 0x18, 0x00, 0xB2, 0xAF, 0x20, 0x00, 0xBF, 0xAF, -0x10, 0x00, 0xB0, 0xAF, 0xCA, 0x55, 0x00, 0x0C, 0x21, 0x98, 0xA0, 0x00, -0x21, 0x90, 0x40, 0x00, 0x08, 0x00, 0x40, 0x16, 0x21, 0x10, 0x20, 0x02, -0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x28, 0x00, 0xBD, 0x27, 0xCA, 0x55, 0x00, 0x0C, 0x21, 0x20, 0x20, 0x02, -0x21, 0x80, 0x40, 0x00, 0x2A, 0x10, 0x52, 0x00, 0x0A, 0x00, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x20, 0x02, 0x21, 0x28, 0x60, 0x02, -0x21, 0x30, 0x40, 0x02, 0x1D, 0x55, 0x00, 0x0C, 0xFF, 0xFF, 0x10, 0x26, -0x0B, 0x00, 0x40, 0x10, 0x2A, 0x18, 0x12, 0x02, 0xF8, 0xFF, 0x60, 0x10, -0x01, 0x00, 0x31, 0x26, 0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, -0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, -0xAB, 0x56, 0x00, 0x08, 0x21, 0x10, 0x20, 0x02, 0x00, 0x00, 0x87, 0x90, -0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0xE0, 0x10, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xA6, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0xC0, 0x10, -0xDF, 0xFF, 0x02, 0x24, 0x24, 0x18, 0xC2, 0x00, 0x24, 0x10, 0xE2, 0x00, -0x00, 0x16, 0x02, 0x00, 0x00, 0x1E, 0x03, 0x00, 0x03, 0x16, 0x02, 0x00, -0x03, 0x1E, 0x03, 0x00, 0x0A, 0x00, 0x43, 0x10, 0x00, 0x00, 0x00, 0x00, -0xDF, 0xFF, 0x02, 0x24, 0x24, 0x18, 0xC2, 0x00, 0x24, 0x10, 0xE2, 0x00, -0x00, 0x16, 0x02, 0x00, 0x00, 0x1E, 0x03, 0x00, 0x03, 0x1E, 0x03, 0x00, -0x03, 0x16, 0x02, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x23, 0x10, 0x43, 0x00, -0xEE, 0x56, 0x00, 0x08, 0xDF, 0xFF, 0x08, 0x24, 0x00, 0x00, 0xA6, 0x90, -0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x06, 0x01, 0x00, 0x16, 0x02, 0x00, -0xF0, 0xFF, 0xC0, 0x10, 0x03, 0x16, 0x02, 0x00, 0xEF, 0xFF, 0x62, 0x14, -0xDF, 0xFF, 0x02, 0x24, 0x01, 0x00, 0x84, 0x24, 0x00, 0x00, 0x87, 0x90, -0x01, 0x00, 0xA5, 0x24, 0x24, 0x10, 0x07, 0x01, 0x00, 0x1E, 0x02, 0x00, -0xF2, 0xFF, 0xE0, 0x14, 0x03, 0x1E, 0x03, 0x00, 0x00, 0x00, 0xA6, 0x90, -0xDF, 0xFF, 0x02, 0x24, 0x24, 0x18, 0xC2, 0x00, 0x24, 0x10, 0xE2, 0x00, -0x00, 0x16, 0x02, 0x00, 0x00, 0x1E, 0x03, 0x00, 0x03, 0x1E, 0x03, 0x00, -0x03, 0x16, 0x02, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x23, 0x10, 0x43, 0x00, -0xA8, 0xFF, 0xBD, 0x27, 0x44, 0x00, 0xB5, 0xAF, 0x40, 0x00, 0xB4, 0xAF, -0x38, 0x00, 0xB2, 0xAF, 0x34, 0x00, 0xB1, 0xAF, 0x54, 0x00, 0xBF, 0xAF, -0x50, 0x00, 0xBE, 0xAF, 0x4C, 0x00, 0xB7, 0xAF, 0x48, 0x00, 0xB6, 0xAF, -0x3C, 0x00, 0xB3, 0xAF, 0x30, 0x00, 0xB0, 0xAF, 0x21, 0x90, 0xA0, 0x00, -0x00, 0x00, 0xA5, 0x90, 0x21, 0xA0, 0x80, 0x00, 0x21, 0xA8, 0xC0, 0x00, -0x00, 0x26, 0x05, 0x00, 0x03, 0x26, 0x04, 0x00, 0x11, 0x00, 0x80, 0x10, -0x21, 0x88, 0x80, 0x02, 0x25, 0x00, 0x02, 0x24, 0x29, 0x00, 0x82, 0x10, -0x0A, 0x00, 0x02, 0x24, 0x1B, 0x00, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, -0x1E, 0x00, 0x80, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0xA2, -0x01, 0x00, 0x31, 0x26, 0x01, 0x00, 0x52, 0x26, 0x00, 0x00, 0x45, 0x92, -0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x05, 0x00, 0x03, 0x26, 0x04, 0x00, -0xF2, 0xFF, 0x80, 0x14, 0x25, 0x00, 0x02, 0x24, 0x02, 0x00, 0x80, 0x12, -0x23, 0x10, 0x34, 0x02, 0x00, 0x00, 0x20, 0xA2, 0x54, 0x00, 0xBF, 0x8F, -0x50, 0x00, 0xBE, 0x8F, 0x4C, 0x00, 0xB7, 0x8F, 0x48, 0x00, 0xB6, 0x8F, -0x44, 0x00, 0xB5, 0x8F, 0x40, 0x00, 0xB4, 0x8F, 0x3C, 0x00, 0xB3, 0x8F, -0x38, 0x00, 0xB2, 0x8F, 0x34, 0x00, 0xB1, 0x8F, 0x30, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x58, 0x00, 0xBD, 0x27, 0xE7, 0xFF, 0x80, 0x16, -0x00, 0x00, 0x00, 0x00, 0x57, 0x58, 0x00, 0x0C, 0x0D, 0x00, 0x04, 0x24, -0x0A, 0x00, 0x04, 0x24, 0x57, 0x58, 0x00, 0x0C, 0x01, 0x00, 0x52, 0x26, -0x00, 0x00, 0x45, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x05, 0x00, -0x20, 0x57, 0x00, 0x08, 0x03, 0x26, 0x04, 0x00, 0x01, 0x00, 0x52, 0x26, -0x00, 0x00, 0x45, 0x92, 0x73, 0x00, 0x02, 0x24, 0x00, 0x1E, 0x05, 0x00, -0x03, 0x1E, 0x03, 0x00, 0x2C, 0x00, 0x62, 0x10, 0x10, 0x00, 0xB3, 0x27, -0x23, 0x00, 0x02, 0x24, 0x21, 0xF0, 0x60, 0x02, 0x21, 0x38, 0x00, 0x00, -0x34, 0x00, 0x62, 0x10, 0x1C, 0x00, 0x04, 0x24, 0x00, 0x16, 0x05, 0x00, -0x03, 0x16, 0x02, 0x00, 0x68, 0x00, 0x03, 0x24, 0x36, 0x00, 0x43, 0x10, -0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x05, 0x00, 0x03, 0x16, 0x02, 0x00, -0x39, 0x00, 0x43, 0x10, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xA2, 0x34, -0x00, 0x16, 0x02, 0x00, 0x03, 0x16, 0x02, 0x00, 0x78, 0x00, 0x03, 0x24, -0x3C, 0x00, 0x43, 0x10, 0x20, 0x00, 0xA6, 0x30, 0x00, 0x1E, 0x05, 0x00, -0x03, 0x1E, 0x03, 0x00, 0x64, 0x00, 0x02, 0x24, 0x49, 0x00, 0x62, 0x10, -0x40, 0x00, 0x02, 0x24, 0x81, 0x00, 0x62, 0x10, 0x21, 0x00, 0x02, 0x24, -0x92, 0x00, 0x62, 0x10, 0x63, 0x00, 0x02, 0x24, 0xA2, 0x00, 0x62, 0x10, -0x11, 0x00, 0xB3, 0x27, 0x10, 0x00, 0xA5, 0xA3, 0x21, 0x80, 0xC0, 0x03, -0x2B, 0x10, 0x13, 0x02, 0xB4, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, -0x6C, 0x00, 0x80, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x92, -0x01, 0x00, 0x10, 0x26, 0x00, 0x00, 0x22, 0xA2, 0x65, 0x57, 0x00, 0x08, -0x01, 0x00, 0x31, 0x26, 0x00, 0x00, 0xA2, 0x8E, 0x04, 0x00, 0xB5, 0x26, -0x21, 0x80, 0x40, 0x00, 0x00, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, -0xA6, 0xFF, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x80, 0x12, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xA2, 0x01, 0x00, 0x10, 0x26, -0x72, 0x57, 0x00, 0x08, 0x01, 0x00, 0x31, 0x26, 0x01, 0x00, 0x52, 0x26, -0x00, 0x00, 0x45, 0x92, 0x68, 0x00, 0x03, 0x24, 0x00, 0x16, 0x05, 0x00, -0x03, 0x16, 0x02, 0x00, 0xCC, 0xFF, 0x43, 0x14, 0x01, 0x00, 0x07, 0x24, -0x01, 0x00, 0x52, 0x26, 0x00, 0x00, 0x45, 0x92, 0x00, 0x00, 0x00, 0x00, -0x00, 0x16, 0x05, 0x00, 0x03, 0x16, 0x02, 0x00, 0xC9, 0xFF, 0x43, 0x14, -0x0C, 0x00, 0x04, 0x24, 0x01, 0x00, 0x52, 0x26, 0x00, 0x00, 0x45, 0x92, -0x78, 0x00, 0x03, 0x24, 0x20, 0x00, 0xA2, 0x34, 0x00, 0x16, 0x02, 0x00, -0x03, 0x16, 0x02, 0x00, 0xC7, 0xFF, 0x43, 0x14, 0x04, 0x00, 0x04, 0x24, -0x20, 0x00, 0xA6, 0x30, 0x00, 0x00, 0xA5, 0x8E, 0x35, 0x00, 0xE0, 0x14, -0x04, 0x00, 0xB5, 0x26, 0xCD, 0xFF, 0x80, 0x04, 0x02, 0x80, 0x02, 0x3C, -0x0C, 0xEF, 0x42, 0x24, 0x00, 0x00, 0x47, 0x8C, 0x07, 0x10, 0x85, 0x00, -0x0F, 0x00, 0x42, 0x30, 0x21, 0x10, 0x47, 0x00, 0x00, 0x00, 0x43, 0x90, -0xFC, 0xFF, 0x84, 0x24, 0x25, 0x18, 0xC3, 0x00, 0x00, 0x00, 0x63, 0xA2, -0xF8, 0xFF, 0x81, 0x04, 0x01, 0x00, 0x73, 0x26, 0x65, 0x57, 0x00, 0x08, -0x21, 0x80, 0xC0, 0x03, 0x00, 0x00, 0xA2, 0x8E, 0x04, 0x00, 0xB5, 0x26, -0x28, 0x00, 0x40, 0x04, 0x21, 0x28, 0x40, 0x00, 0x21, 0x80, 0x60, 0x02, -0x02, 0x80, 0x02, 0x3C, 0x10, 0xEF, 0x42, 0x24, 0x00, 0x00, 0x46, 0x8C, -0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xA6, 0x00, 0xC3, 0x27, 0x05, 0x00, -0x10, 0x10, 0x00, 0x00, 0x83, 0x10, 0x02, 0x00, 0x23, 0x10, 0x44, 0x00, -0x80, 0x18, 0x02, 0x00, 0x21, 0x18, 0x62, 0x00, 0x40, 0x18, 0x03, 0x00, -0x23, 0x18, 0xA3, 0x00, 0x30, 0x00, 0x63, 0x24, 0x00, 0x00, 0x63, 0xA2, -0x21, 0x28, 0x40, 0x00, 0xF3, 0xFF, 0x40, 0x14, 0x01, 0x00, 0x73, 0x26, -0xC5, 0x57, 0x00, 0x08, 0xFF, 0xFF, 0x63, 0x26, 0x00, 0x00, 0x65, 0x80, -0x00, 0x00, 0x02, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xA0, -0x00, 0x00, 0x05, 0xA2, 0xFF, 0xFF, 0x63, 0x24, 0x01, 0x00, 0x10, 0x26, -0x2B, 0x10, 0x03, 0x02, 0xF7, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x65, 0x57, 0x00, 0x08, 0x21, 0x80, 0xC0, 0x03, 0x58, 0x00, 0xC3, 0x34, -0x30, 0x00, 0x02, 0x24, 0x12, 0x00, 0xB3, 0x27, 0x10, 0x00, 0xA2, 0xA3, -0x96, 0x57, 0x00, 0x08, 0x11, 0x00, 0xA3, 0xA3, 0x2D, 0x00, 0x02, 0x24, -0x23, 0x28, 0x05, 0x00, 0x11, 0x00, 0xB3, 0x27, 0xA9, 0x57, 0x00, 0x08, -0x10, 0x00, 0xA2, 0xA3, 0x00, 0x00, 0x04, 0x82, 0x57, 0x58, 0x00, 0x0C, -0x01, 0x00, 0x10, 0x26, 0x66, 0x57, 0x00, 0x08, 0x2B, 0x10, 0x13, 0x02, -0x00, 0x00, 0x04, 0x82, 0x57, 0x58, 0x00, 0x0C, 0x01, 0x00, 0x10, 0x26, -0x72, 0x57, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x8E, -0x28, 0x00, 0xB0, 0x27, 0x2C, 0x00, 0xA4, 0x27, 0x2B, 0x10, 0x04, 0x02, -0x28, 0x00, 0xA3, 0xAF, 0x0B, 0x00, 0x40, 0x10, 0x04, 0x00, 0xB5, 0x26, -0x21, 0xB8, 0x80, 0x00, 0x02, 0x80, 0x16, 0x3C, 0x00, 0x00, 0x06, 0x92, -0x21, 0x20, 0x60, 0x02, 0x01, 0x00, 0x10, 0x26, 0x08, 0x58, 0x00, 0x0C, -0x00, 0xEF, 0xC5, 0x26, 0x2B, 0x18, 0x17, 0x02, 0xF9, 0xFF, 0x60, 0x14, -0x21, 0x98, 0x62, 0x02, 0x64, 0x57, 0x00, 0x08, 0xFF, 0xFF, 0x73, 0x26, -0x00, 0x00, 0xA2, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x56, 0x24, -0x21, 0x80, 0x40, 0x00, 0x2B, 0x10, 0x56, 0x00, 0xF8, 0xFF, 0x40, 0x10, -0x04, 0x00, 0xB5, 0x26, 0x02, 0x80, 0x17, 0x3C, 0x00, 0x00, 0x06, 0x82, -0x21, 0x20, 0x60, 0x02, 0x01, 0x00, 0x10, 0x26, 0x08, 0x58, 0x00, 0x0C, -0x04, 0xEF, 0xE5, 0x26, 0x2B, 0x18, 0x16, 0x02, 0xF9, 0xFF, 0x60, 0x14, -0x21, 0x98, 0x62, 0x02, 0x64, 0x57, 0x00, 0x08, 0xFF, 0xFF, 0x73, 0x26, -0x00, 0x00, 0xA2, 0x8E, 0x04, 0x00, 0xB5, 0x26, 0x64, 0x57, 0x00, 0x08, -0x10, 0x00, 0xA2, 0xA3, 0xE8, 0xFF, 0xBD, 0x27, 0x20, 0x00, 0xA6, 0xAF, -0x20, 0x00, 0xA6, 0x27, 0x10, 0x00, 0xBF, 0xAF, 0x24, 0x00, 0xA7, 0xAF, -0xFF, 0x56, 0x00, 0x0C, 0x1C, 0x00, 0xA5, 0xAF, 0x10, 0x00, 0xBF, 0x8F, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, -0xE0, 0xFF, 0xBD, 0x27, 0x20, 0x00, 0xA4, 0xAF, 0x10, 0x00, 0xA4, 0x27, -0x1C, 0x00, 0xBF, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x24, 0x00, 0xA5, 0xAF, -0x28, 0x00, 0xA6, 0xAF, 0x8A, 0x40, 0x00, 0x0C, 0x2C, 0x00, 0xA7, 0xAF, -0x53, 0x21, 0x00, 0x0C, 0xA0, 0x00, 0x04, 0x24, 0x1F, 0x00, 0x40, 0x10, -0x21, 0x80, 0x40, 0x00, 0x08, 0x00, 0x44, 0x94, 0x20, 0x00, 0xA5, 0x8F, -0x02, 0x80, 0x02, 0x3C, 0x25, 0x20, 0x82, 0x00, 0x20, 0x00, 0x84, 0x24, -0xFF, 0x56, 0x00, 0x0C, 0x24, 0x00, 0xA6, 0x27, 0x01, 0x00, 0x42, 0x24, -0x13, 0x00, 0x03, 0x24, 0x81, 0x00, 0x44, 0x2C, 0x14, 0x00, 0x03, 0xAE, -0x0A, 0x00, 0x80, 0x14, 0x0C, 0x00, 0x02, 0xAE, 0x9B, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, -0x88, 0x88, 0x63, 0x34, 0x18, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, -0x34, 0x58, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x17, 0x0A, 0x00, 0x0C, -0x21, 0x20, 0x00, 0x02, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, -0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x20, 0x00, 0xBD, 0x27, 0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, -0x99, 0x99, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, 0x99, 0x99, 0x63, 0x34, -0x18, 0x03, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, 0x3A, 0x58, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF, -0x02, 0x80, 0x06, 0x3C, 0x5C, 0xF5, 0xC5, 0x8C, 0x02, 0x80, 0x02, 0x3C, -0x40, 0xF5, 0x42, 0x24, 0x03, 0x00, 0xA3, 0x30, 0x21, 0x18, 0x62, 0x00, -0x00, 0x00, 0x64, 0x80, 0x01, 0x00, 0xA5, 0x24, 0x57, 0x58, 0x00, 0x0C, -0x5C, 0xF5, 0xC5, 0xAC, 0x10, 0x00, 0xBF, 0x8F, 0x08, 0x00, 0x04, 0x24, -0x57, 0x58, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, 0x00, 0x26, 0x04, 0x00, -0x03, 0x26, 0x04, 0x00, 0x00, 0x00, 0x84, 0x48, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x04, 0x00, 0x03, 0x26, 0x04, 0x00, -0xF7, 0xFF, 0x82, 0x24, 0x05, 0x00, 0x42, 0x2C, 0x06, 0x00, 0x40, 0x14, -0x21, 0x18, 0x00, 0x00, 0x20, 0x00, 0x02, 0x24, 0x03, 0x00, 0x82, 0x10, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, -0x01, 0x00, 0x03, 0x24, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x60, 0x00, -0x00, 0x00, 0x82, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x44, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x42, 0x2C, 0xE0, 0xFF, 0xBD, 0x27, -0x18, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0x80, 0x00, 0x1C, 0x00, 0xBF, 0xAF, -0x8A, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x10, 0x00, 0xA4, 0x27, -0x02, 0x80, 0x02, 0x3C, 0xCC, 0x5D, 0x50, 0xAC, 0x90, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0x25, 0xB0, 0x05, 0x3C, -0x01, 0x00, 0x06, 0x24, 0x01, 0x80, 0x02, 0x3C, 0x04, 0x30, 0x86, 0x00, -0xF1, 0x02, 0xA7, 0x34, 0xED, 0x02, 0xA4, 0x34, 0xF8, 0x61, 0x42, 0x24, -0x18, 0x03, 0xA5, 0x34, 0x08, 0x00, 0x03, 0x24, 0x00, 0x00, 0xA2, 0xAC, -0x00, 0x00, 0xE3, 0xA0, 0x00, 0x00, 0x80, 0xA0, 0x00, 0x00, 0x86, 0xA0, -0x00, 0x00, 0x80, 0xA0, 0x00, 0x00, 0x86, 0xA0, 0x00, 0x00, 0x80, 0xA0, -0x00, 0x00, 0x86, 0xA0, 0x00, 0x00, 0x80, 0xA0, 0x00, 0x00, 0x86, 0xA0, -0x00, 0x00, 0x80, 0xA0, 0x00, 0x00, 0xE0, 0xA0, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF, -0xFF, 0xFF, 0x90, 0x30, 0x1C, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C, -0x10, 0x00, 0xA4, 0x27, 0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x63, 0x24, -0x6A, 0x37, 0x62, 0x94, 0x10, 0x00, 0xA4, 0x27, 0x25, 0x80, 0x02, 0x02, -0x25, 0xB0, 0x02, 0x3C, 0x1E, 0x03, 0x42, 0x34, 0x00, 0x00, 0x50, 0xA4, -0x90, 0x40, 0x00, 0x0C, 0x6A, 0x37, 0x70, 0xA4, 0x1C, 0x00, 0xBF, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF, 0xFF, 0xFF, 0x90, 0x30, -0x1C, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, -0x02, 0x80, 0x05, 0x3C, 0x60, 0x1B, 0xA5, 0x24, 0x6A, 0x37, 0xA2, 0x94, -0x78, 0x37, 0xA3, 0x94, 0x27, 0x80, 0x10, 0x00, 0x10, 0x00, 0xA4, 0x27, -0x24, 0x18, 0x03, 0x02, 0x24, 0x80, 0x02, 0x02, 0x25, 0xB0, 0x02, 0x3C, -0x1E, 0x03, 0x42, 0x34, 0x78, 0x37, 0xA3, 0xA4, 0x00, 0x00, 0x50, 0xA4, -0x90, 0x40, 0x00, 0x0C, 0x6A, 0x37, 0xB0, 0xA4, 0x1C, 0x00, 0xBF, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0xC8, 0xFF, 0xBD, 0x27, 0x25, 0xB0, 0x03, 0x3C, 0x1C, 0x00, 0xB3, 0xAF, -0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, -0x34, 0x00, 0xBF, 0xAF, 0x30, 0x00, 0xBE, 0xAF, 0x2C, 0x00, 0xB7, 0xAF, -0x28, 0x00, 0xB6, 0xAF, 0x24, 0x00, 0xB5, 0xAF, 0x20, 0x00, 0xB4, 0xAF, -0x0A, 0x00, 0x67, 0x34, 0x00, 0x00, 0xE2, 0x90, 0xFF, 0xFF, 0xB2, 0x30, -0x21, 0x98, 0xC0, 0x00, 0xFF, 0x00, 0x91, 0x30, 0x20, 0x00, 0x40, 0x12, -0xFF, 0x00, 0x50, 0x30, 0x21, 0xA0, 0xE0, 0x00, 0x0C, 0x00, 0x77, 0x34, -0x0B, 0x00, 0x76, 0x34, 0x21, 0xF0, 0xE0, 0x00, 0xC0, 0xFF, 0x15, 0x24, -0x25, 0x10, 0x15, 0x02, 0xFF, 0x00, 0x50, 0x30, 0x00, 0x00, 0xD1, 0xA2, -0x00, 0x00, 0x90, 0xA2, 0x00, 0x00, 0x82, 0x92, 0x00, 0x00, 0x00, 0x00, -0xFF, 0x00, 0x50, 0x30, 0xC0, 0x00, 0x03, 0x32, 0x07, 0x00, 0x60, 0x10, -0x21, 0x20, 0xC0, 0x03, 0x00, 0x00, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, -0xFF, 0x00, 0x50, 0x30, 0xC0, 0x00, 0x03, 0x32, 0xFB, 0xFF, 0x60, 0x14, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2, 0x8E, 0x04, 0x00, 0x23, 0x26, -0x64, 0x00, 0x04, 0x24, 0x00, 0x00, 0x62, 0xAE, 0x2C, 0x1F, 0x00, 0x0C, -0xFF, 0x00, 0x71, 0x30, 0xFC, 0xFF, 0x42, 0x26, 0xFF, 0xFF, 0x52, 0x30, -0xE7, 0xFF, 0x40, 0x16, 0x04, 0x00, 0x73, 0x26, 0x34, 0x00, 0xBF, 0x8F, -0x30, 0x00, 0xBE, 0x8F, 0x2C, 0x00, 0xB7, 0x8F, 0x28, 0x00, 0xB6, 0x8F, -0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, -0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x38, 0x00, 0xBD, 0x27, 0x25, 0xB0, 0x06, 0x3C, -0x31, 0x00, 0xC2, 0x34, 0xFF, 0xFF, 0x84, 0x30, 0x00, 0x00, 0x44, 0xA0, -0x32, 0x00, 0xC7, 0x34, 0x00, 0x00, 0xE3, 0x90, 0xFC, 0xFF, 0x02, 0x24, -0x02, 0x22, 0x04, 0x00, 0x24, 0x18, 0x62, 0x00, 0x03, 0x00, 0x84, 0x30, -0x25, 0x20, 0x83, 0x00, 0x33, 0x00, 0xC6, 0x34, 0x72, 0x00, 0x02, 0x24, -0x00, 0x00, 0xE4, 0xA0, 0x00, 0x00, 0xC2, 0xA0, 0x00, 0x00, 0xC3, 0x90, -0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x03, 0x00, 0x03, 0x1E, 0x03, 0x00, -0x05, 0x00, 0x61, 0x04, 0x21, 0x10, 0x00, 0x00, 0x23, 0x59, 0x00, 0x08, -0x25, 0xB0, 0x02, 0x3C, 0x11, 0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xC3, 0x90, 0x01, 0x00, 0x42, 0x24, 0xFF, 0x00, 0x42, 0x30, -0x00, 0x1E, 0x03, 0x00, 0x03, 0x1E, 0x03, 0x00, 0xF8, 0xFF, 0x61, 0x04, -0x64, 0x00, 0x44, 0x2C, 0x64, 0x00, 0x44, 0x2C, 0x07, 0x00, 0x80, 0x10, -0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x02, 0x3C, 0x30, 0x00, 0x42, 0x34, -0x00, 0x00, 0x43, 0x90, 0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0xA3, 0xA0, 0xFF, 0xFF, 0x02, 0x24, 0x00, 0x00, 0xA2, 0xA0, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x25, 0xB0, 0x06, 0x3C, -0x31, 0x00, 0xC2, 0x34, 0xFF, 0xFF, 0x84, 0x30, 0x00, 0x00, 0x44, 0xA0, -0x32, 0x00, 0xC3, 0x34, 0x00, 0x00, 0x62, 0x90, 0x02, 0x22, 0x04, 0x00, -0x03, 0x00, 0x84, 0x30, 0x25, 0x20, 0x82, 0x00, 0x00, 0x00, 0x64, 0xA0, -0x33, 0x00, 0xC7, 0x34, 0xFF, 0x00, 0xA5, 0x30, 0x30, 0x00, 0xC6, 0x34, -0xF2, 0xFF, 0x03, 0x24, 0x00, 0x00, 0xC5, 0xA0, 0x00, 0x00, 0xE3, 0xA0, -0x00, 0x00, 0xE2, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x02, 0x00, -0x03, 0x16, 0x02, 0x00, 0x03, 0x00, 0x40, 0x04, 0x21, 0x20, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x01, 0x00, 0x02, 0x24, 0x48, 0x59, 0x00, 0x08, -0x21, 0x30, 0xE0, 0x00, 0x0B, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xC3, 0x90, 0x01, 0x00, 0x82, 0x24, 0xFF, 0x00, 0x44, 0x30, -0x00, 0x1E, 0x03, 0x00, 0x03, 0x1E, 0x03, 0x00, 0xF8, 0xFF, 0x60, 0x04, -0x64, 0x00, 0x82, 0x2C, 0x64, 0x00, 0x82, 0x2C, 0xF1, 0xFF, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, -0xE0, 0xFF, 0xBD, 0x27, 0x25, 0xB0, 0x02, 0x3C, 0x18, 0x00, 0xB0, 0xAF, -0xF8, 0x02, 0x45, 0x34, 0x25, 0xB0, 0x10, 0x3C, 0xFF, 0x00, 0x83, 0x30, -0x01, 0x00, 0x02, 0x24, 0x1C, 0x00, 0xBF, 0xAF, 0x03, 0x00, 0x06, 0x36, -0x0A, 0x00, 0x62, 0x10, 0x0A, 0x00, 0x04, 0x24, 0x00, 0x00, 0xA2, 0x90, -0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0xFE, 0xFF, 0x03, 0x24, -0x24, 0x10, 0x43, 0x00, 0x20, 0x00, 0xBD, 0x27, 0x00, 0x00, 0xA2, 0xA0, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2, 0x90, -0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x42, 0x30, 0x20, 0x00, 0x43, 0x34, -0x20, 0x00, 0x42, 0x30, 0x02, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xC3, 0xA0, 0x2C, 0x1F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x04, 0x36, 0x00, 0x00, 0x82, 0x90, 0xFE, 0xFF, 0x03, 0x24, -0xF8, 0x02, 0x06, 0x36, 0x24, 0x10, 0x43, 0x00, 0x00, 0x00, 0x82, 0xA0, -0x00, 0x00, 0xC3, 0x90, 0x10, 0x00, 0xA5, 0x27, 0x21, 0x20, 0x00, 0x00, -0x03, 0x00, 0x63, 0x34, 0x00, 0x00, 0xC3, 0xA0, 0xFF, 0x58, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0xFF, 0x00, 0x84, 0x30, -0x21, 0x38, 0x00, 0x00, 0x21, 0x28, 0x00, 0x00, 0x01, 0x00, 0xA3, 0x24, -0x07, 0x10, 0xA4, 0x00, 0x01, 0x00, 0x42, 0x30, 0xFF, 0x00, 0x65, 0x30, -0x01, 0x00, 0xE6, 0x24, 0x02, 0x00, 0x40, 0x14, 0x04, 0x00, 0xA3, 0x2C, -0xFF, 0x00, 0xC7, 0x30, 0xF7, 0xFF, 0x60, 0x14, 0x21, 0x10, 0xE0, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x8C, 0x30, -0x21, 0x48, 0x00, 0x00, 0x21, 0x38, 0x00, 0x00, 0x40, 0x10, 0x07, 0x00, -0xFF, 0x00, 0x42, 0x30, 0x21, 0x50, 0x46, 0x00, 0x01, 0x00, 0xE3, 0x24, -0x07, 0x10, 0xEC, 0x00, 0x01, 0x00, 0x42, 0x30, 0xFF, 0x00, 0x67, 0x30, -0x21, 0x58, 0x25, 0x01, 0x01, 0x00, 0x24, 0x25, 0x09, 0x00, 0x40, 0x14, -0x04, 0x00, 0xE8, 0x2C, 0x00, 0x00, 0x63, 0x91, 0xFF, 0x00, 0x89, 0x30, -0x21, 0x20, 0x25, 0x01, 0x00, 0x00, 0x43, 0xA1, 0x00, 0x00, 0x83, 0x90, -0x01, 0x00, 0x22, 0x25, 0xFF, 0x00, 0x49, 0x30, 0x01, 0x00, 0x43, 0xA1, -0xED, 0xFF, 0x00, 0x15, 0x40, 0x10, 0x07, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0xD8, 0xFF, 0xBD, 0x27, 0x20, 0x00, 0xB2, 0xAF, -0x1C, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xB0, 0xAF, 0x24, 0x00, 0xBF, 0xAF, -0x01, 0x00, 0x12, 0x24, 0x21, 0x80, 0x00, 0x00, 0xC5, 0x59, 0x00, 0x08, -0xFF, 0x00, 0x11, 0x24, 0xFF, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x10, 0x00, 0x40, 0x10, 0x00, 0x02, 0x03, 0x2E, 0x0F, 0x00, 0x60, 0x10, -0x21, 0x10, 0x00, 0x02, 0x10, 0x00, 0xA2, 0x93, 0x00, 0x00, 0x00, 0x00, -0x0A, 0x00, 0x51, 0x10, 0x0F, 0x00, 0x44, 0x30, 0x83, 0x59, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x02, 0x00, 0x21, 0x10, 0x50, 0x00, -0x01, 0x00, 0x42, 0x24, 0xFF, 0xFF, 0x50, 0x30, 0x21, 0x20, 0x00, 0x02, -0xEE, 0xFF, 0x40, 0x16, 0x10, 0x00, 0xA5, 0x27, 0x21, 0x10, 0x00, 0x02, -0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, -0xB8, 0xFF, 0xBD, 0x27, 0x3C, 0x00, 0xB7, 0xAF, 0x38, 0x00, 0xB6, 0xAF, -0x34, 0x00, 0xB5, 0xAF, 0x30, 0x00, 0xB4, 0xAF, 0x2C, 0x00, 0xB3, 0xAF, -0x24, 0x00, 0xB1, 0xAF, 0x20, 0x00, 0xB0, 0xAF, 0x44, 0x00, 0xBF, 0xAF, -0x40, 0x00, 0xBE, 0xAF, 0x28, 0x00, 0xB2, 0xAF, 0x21, 0x98, 0xA0, 0x00, -0xFF, 0x00, 0x96, 0x30, 0x01, 0x00, 0x10, 0x24, 0x01, 0x00, 0x17, 0x24, -0x21, 0xA0, 0x00, 0x00, 0x21, 0x88, 0x00, 0x00, 0x21, 0xA8, 0x00, 0x00, -0x04, 0x00, 0xA0, 0x10, 0x21, 0x18, 0x00, 0x00, 0x10, 0x00, 0xC2, 0x2E, -0x0E, 0x00, 0x40, 0x14, 0x21, 0x20, 0xA0, 0x00, 0x44, 0x00, 0xBF, 0x8F, -0x40, 0x00, 0xBE, 0x8F, 0x3C, 0x00, 0xB7, 0x8F, 0x38, 0x00, 0xB6, 0x8F, -0x34, 0x00, 0xB5, 0x8F, 0x30, 0x00, 0xB4, 0x8F, 0x2C, 0x00, 0xB3, 0x8F, -0x28, 0x00, 0xB2, 0x8F, 0x24, 0x00, 0xB1, 0x8F, 0x20, 0x00, 0xB0, 0x8F, -0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x48, 0x00, 0xBD, 0x27, -0x08, 0x00, 0x06, 0x24, 0xE3, 0x54, 0x00, 0x0C, 0xFF, 0x00, 0x05, 0x24, -0x18, 0x00, 0xA4, 0x27, 0xFF, 0x00, 0x05, 0x24, 0xE3, 0x54, 0x00, 0x0C, -0x08, 0x00, 0x06, 0x24, 0x54, 0x59, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24, -0x04, 0x5A, 0x00, 0x08, 0x10, 0x00, 0xBE, 0x27, 0x1C, 0x00, 0x40, 0x14, -0x21, 0x20, 0xA0, 0x02, 0x37, 0x00, 0xE0, 0x12, 0x00, 0x02, 0x22, 0x2E, -0x35, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x32, -0xF8, 0xFF, 0x40, 0x10, 0x20, 0x00, 0x02, 0x32, 0x21, 0x20, 0x20, 0x02, -0xFF, 0x58, 0x00, 0x0C, 0x10, 0x00, 0xA5, 0x27, 0x2D, 0x00, 0x40, 0x10, -0xFF, 0x00, 0x02, 0x24, 0x10, 0x00, 0xB0, 0x93, 0x00, 0x00, 0x00, 0x00, -0x29, 0x00, 0x02, 0x12, 0x0F, 0x00, 0x15, 0x32, 0x83, 0x59, 0x00, 0x0C, -0x21, 0x20, 0xA0, 0x02, 0x02, 0x81, 0x10, 0x00, 0x10, 0x00, 0x16, 0x12, -0x21, 0xA0, 0x40, 0x00, 0x40, 0x10, 0x14, 0x00, 0x21, 0x10, 0x51, 0x00, -0x01, 0x00, 0x42, 0x24, 0xFF, 0xFF, 0x51, 0x30, 0x00, 0x5A, 0x00, 0x08, -0x01, 0x00, 0x10, 0x24, 0x18, 0x00, 0xA5, 0x27, 0x92, 0x59, 0x00, 0x0C, -0x21, 0x30, 0x60, 0x02, 0x40, 0x10, 0x14, 0x00, 0x21, 0x10, 0x51, 0x00, -0x01, 0x00, 0x42, 0x24, 0xFF, 0xFF, 0x51, 0x30, 0x00, 0x5A, 0x00, 0x08, -0x01, 0x00, 0x10, 0x24, 0x40, 0x90, 0x02, 0x00, 0x10, 0x00, 0x40, 0x1A, -0x21, 0x80, 0x00, 0x00, 0x21, 0x20, 0x30, 0x02, 0x01, 0x00, 0x84, 0x24, -0xFF, 0xFF, 0x84, 0x30, 0xFF, 0x58, 0x00, 0x0C, 0x10, 0x00, 0xA5, 0x27, -0x01, 0x00, 0x03, 0x26, 0x21, 0x20, 0xD0, 0x03, 0xFF, 0x00, 0x70, 0x30, -0x04, 0x00, 0x40, 0x10, 0x2A, 0x18, 0x12, 0x02, 0x10, 0x00, 0xA2, 0x93, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x82, 0xA0, 0xF3, 0xFF, 0x60, 0x14, -0x21, 0x20, 0x30, 0x02, 0x00, 0x5A, 0x00, 0x08, 0x20, 0x00, 0x10, 0x24, -0x54, 0x59, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x00, 0x00, 0x00, 0x63, 0x92, -0xFF, 0x00, 0x02, 0x24, 0x0F, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x03, 0x24, 0x44, 0x00, 0xBF, 0x8F, 0x40, 0x00, 0xBE, 0x8F, -0x3C, 0x00, 0xB7, 0x8F, 0x38, 0x00, 0xB6, 0x8F, 0x34, 0x00, 0xB5, 0x8F, -0x30, 0x00, 0xB4, 0x8F, 0x2C, 0x00, 0xB3, 0x8F, 0x28, 0x00, 0xB2, 0x8F, -0x24, 0x00, 0xB1, 0x8F, 0x20, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x48, 0x00, 0xBD, 0x27, 0x01, 0x00, 0x62, 0x92, -0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x43, 0x14, 0x01, 0x00, 0x03, 0x24, -0x02, 0x00, 0x63, 0x92, 0x00, 0x00, 0x00, 0x00, 0xEB, 0xFF, 0x62, 0x14, -0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x62, 0x92, 0x00, 0x00, 0x00, 0x00, -0xE8, 0xFF, 0x43, 0x14, 0x01, 0x00, 0x03, 0x24, 0x04, 0x00, 0x63, 0x92, -0x00, 0x00, 0x00, 0x00, 0xE3, 0xFF, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, -0x05, 0x00, 0x62, 0x92, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFF, 0x43, 0x14, -0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x67, 0x92, 0x00, 0x00, 0x00, 0x00, -0xDC, 0xFF, 0xE2, 0x14, 0x01, 0x00, 0x03, 0x24, 0x07, 0x00, 0x62, 0x92, -0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x47, 0x10, 0x21, 0x18, 0x00, 0x00, -0x3F, 0x5A, 0x00, 0x08, 0x01, 0x00, 0x03, 0x24, 0xC0, 0xFF, 0xBD, 0x27, -0x38, 0x00, 0xBE, 0xAF, 0x30, 0x00, 0xB6, 0xAF, 0x2C, 0x00, 0xB5, 0xAF, -0x21, 0xF0, 0xC0, 0x00, 0xFF, 0x00, 0xB6, 0x30, 0xFF, 0xFF, 0x95, 0x30, -0xFF, 0x00, 0x05, 0x24, 0x10, 0x00, 0xA4, 0x27, 0x08, 0x00, 0x06, 0x24, -0x34, 0x00, 0xB7, 0xAF, 0x24, 0x00, 0xB3, 0xAF, 0x3C, 0x00, 0xBF, 0xAF, -0x28, 0x00, 0xB4, 0xAF, 0x20, 0x00, 0xB2, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, -0x18, 0x00, 0xB0, 0xAF, 0xE3, 0x54, 0x00, 0x0C, 0x0F, 0x00, 0x17, 0x24, -0x21, 0x98, 0x00, 0x00, 0x40, 0x10, 0x13, 0x00, 0xFF, 0x00, 0x52, 0x30, -0x07, 0x10, 0x76, 0x02, 0x01, 0x00, 0x42, 0x30, 0x21, 0xA0, 0x5E, 0x02, -0x21, 0x88, 0xA0, 0x02, 0x21, 0x20, 0xA0, 0x02, 0x13, 0x00, 0x40, 0x10, -0x01, 0x00, 0xA3, 0x26, 0x01, 0x00, 0x62, 0x26, 0xFF, 0x00, 0x53, 0x30, -0x04, 0x00, 0x63, 0x2E, 0xF4, 0xFF, 0x60, 0x14, 0x40, 0x10, 0x13, 0x00, -0x21, 0x10, 0xE0, 0x02, 0x3C, 0x00, 0xBF, 0x8F, 0x38, 0x00, 0xBE, 0x8F, -0x34, 0x00, 0xB7, 0x8F, 0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, -0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, -0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x40, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x85, 0x92, 0xFF, 0xFF, 0x75, 0x30, -0x2C, 0x59, 0x00, 0x0C, 0x21, 0x80, 0xA0, 0x02, 0x01, 0x00, 0x85, 0x92, -0x21, 0x20, 0xA0, 0x02, 0x01, 0x00, 0xA2, 0x26, 0x2C, 0x59, 0x00, 0x0C, -0xFF, 0xFF, 0x55, 0x30, 0x10, 0x00, 0xA3, 0x27, 0x21, 0x90, 0x72, 0x00, -0x21, 0x20, 0x20, 0x02, 0xFF, 0x58, 0x00, 0x0C, 0x21, 0x28, 0x40, 0x02, -0x21, 0x20, 0x00, 0x02, 0xFF, 0x58, 0x00, 0x0C, 0x01, 0x00, 0x45, 0x26, -0x00, 0x00, 0x84, 0x92, 0x00, 0x00, 0x42, 0x92, 0x01, 0x00, 0x03, 0x24, -0x04, 0x18, 0x63, 0x02, 0x03, 0x00, 0x82, 0x10, 0x27, 0x30, 0x03, 0x00, -0x87, 0x5A, 0x00, 0x08, 0x24, 0xB8, 0xD7, 0x00, 0x01, 0x00, 0x83, 0x92, -0x01, 0x00, 0x42, 0x92, 0x00, 0x00, 0x00, 0x00, 0xD2, 0xFF, 0x62, 0x10, -0x01, 0x00, 0x62, 0x26, 0x88, 0x5A, 0x00, 0x08, 0x24, 0xB8, 0xD7, 0x00, -0x98, 0xFF, 0xBD, 0x27, 0x50, 0x00, 0xB4, 0xAF, 0xFF, 0x00, 0x94, 0x30, -0x01, 0x00, 0x04, 0x24, 0x64, 0x00, 0xBF, 0xAF, 0x60, 0x00, 0xBE, 0xAF, -0x5C, 0x00, 0xB7, 0xAF, 0x58, 0x00, 0xB6, 0xAF, 0x4C, 0x00, 0xB3, 0xAF, -0x48, 0x00, 0xB2, 0xAF, 0x44, 0x00, 0xB1, 0xAF, 0x21, 0x98, 0xC0, 0x00, -0xFF, 0x00, 0xB1, 0x30, 0x54, 0x00, 0xB5, 0xAF, 0x54, 0x59, 0x00, 0x0C, -0x40, 0x00, 0xB0, 0xAF, 0xAC, 0x59, 0x00, 0x0C, 0x01, 0x00, 0x16, 0x24, -0x21, 0x18, 0x40, 0x00, 0xFF, 0x01, 0x42, 0x2C, 0x01, 0x00, 0x17, 0x24, -0x01, 0x00, 0x1E, 0x24, 0x21, 0x90, 0x00, 0x00, 0x0E, 0x00, 0x40, 0x14, -0x21, 0x20, 0x00, 0x00, 0x64, 0x00, 0xBF, 0x8F, 0x60, 0x00, 0xBE, 0x8F, -0x5C, 0x00, 0xB7, 0x8F, 0x58, 0x00, 0xB6, 0x8F, 0x54, 0x00, 0xB5, 0x8F, -0x50, 0x00, 0xB4, 0x8F, 0x4C, 0x00, 0xB3, 0x8F, 0x48, 0x00, 0xB2, 0x8F, -0x44, 0x00, 0xB1, 0x8F, 0x40, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x80, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x68, 0x00, 0xBD, 0x27, 0xFF, 0x01, 0x02, 0x24, -0x23, 0x10, 0x43, 0x00, 0x1A, 0x00, 0xA4, 0x27, 0xFF, 0x00, 0x05, 0x24, -0x08, 0x00, 0x06, 0x24, 0xFF, 0xFF, 0x50, 0x30, 0x18, 0x00, 0xB4, 0xA3, -0xE3, 0x54, 0x00, 0x0C, 0x19, 0x00, 0xB1, 0xA3, 0x21, 0x20, 0x20, 0x02, -0x21, 0x28, 0x60, 0x02, 0x92, 0x59, 0x00, 0x0C, 0x1A, 0x00, 0xA6, 0x27, -0x19, 0x00, 0xA4, 0x93, 0x83, 0x59, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x21, 0xA8, 0x40, 0x00, 0xFF, 0xFF, 0x42, 0x30, 0x2B, 0x10, 0x02, 0x02, -0xDF, 0xFF, 0x40, 0x14, 0x21, 0x20, 0x00, 0x00, 0x01, 0x00, 0x02, 0x24, -0x09, 0x00, 0xC2, 0x12, 0x20, 0x00, 0x02, 0x24, 0x22, 0x00, 0xC2, 0x12, -0x00, 0x00, 0x00, 0x00, 0x3B, 0x00, 0xE0, 0x12, 0x00, 0x02, 0x42, 0x2E, -0x39, 0x00, 0x40, 0x10, 0x01, 0x00, 0x02, 0x24, 0xF9, 0xFF, 0xC2, 0x16, -0x20, 0x00, 0x02, 0x24, 0x21, 0x20, 0x40, 0x02, 0x10, 0x00, 0xA5, 0x27, -0xFF, 0x58, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x24, 0x41, 0x00, 0x40, 0x10, -0xFF, 0x00, 0x02, 0x24, 0x10, 0x00, 0xA5, 0x93, 0x00, 0x00, 0x00, 0x00, -0xFF, 0x00, 0xA4, 0x30, 0x3C, 0x00, 0x82, 0x10, 0x0F, 0x00, 0xA3, 0x30, -0x02, 0x11, 0x04, 0x00, 0x21, 0x20, 0x60, 0x00, 0x29, 0x00, 0xA3, 0xA3, -0x28, 0x00, 0xA2, 0xA3, 0x83, 0x59, 0x00, 0x0C, 0x11, 0x00, 0xA5, 0xA3, -0x21, 0x80, 0x40, 0x00, 0x28, 0x00, 0xA3, 0x93, 0x18, 0x00, 0xA2, 0x93, -0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x62, 0x10, 0x40, 0x10, 0x10, 0x00, -0x21, 0x10, 0x52, 0x00, 0x01, 0x00, 0x42, 0x24, 0xF9, 0x5A, 0x00, 0x08, -0xFF, 0xFF, 0x52, 0x30, 0x19, 0x00, 0xA5, 0x93, 0x01, 0x00, 0x44, 0x26, -0xFF, 0xFF, 0x84, 0x30, 0x6A, 0x5A, 0x00, 0x0C, 0x1A, 0x00, 0xA6, 0x27, -0x21, 0x28, 0x40, 0x00, 0x0F, 0x00, 0x43, 0x30, 0x0F, 0x00, 0x02, 0x24, -0x12, 0x00, 0x62, 0x10, 0x40, 0x10, 0x15, 0x00, 0x21, 0x10, 0x52, 0x00, -0x01, 0x00, 0x42, 0x24, 0x21, 0x20, 0xA0, 0x00, 0xFF, 0xFF, 0x52, 0x30, -0x18, 0x00, 0xB4, 0xA3, 0x83, 0x59, 0x00, 0x0C, 0x19, 0x00, 0xA5, 0xA3, -0x21, 0xA8, 0x40, 0x00, 0x02, 0x80, 0x03, 0x3C, 0xCC, 0xDF, 0x62, 0x8C, -0x02, 0x80, 0x04, 0x3C, 0x01, 0x00, 0x16, 0x24, 0x01, 0x00, 0x42, 0x24, -0x04, 0x00, 0x43, 0x28, 0xC6, 0xFF, 0x60, 0x14, 0xCC, 0xDF, 0x82, 0xAC, -0x21, 0xF0, 0x00, 0x00, 0x54, 0x59, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x00, -0x21, 0x20, 0xC0, 0x03, 0x64, 0x00, 0xBF, 0x8F, 0x60, 0x00, 0xBE, 0x8F, -0x5C, 0x00, 0xB7, 0x8F, 0x58, 0x00, 0xB6, 0x8F, 0x54, 0x00, 0xB5, 0x8F, -0x50, 0x00, 0xB4, 0x8F, 0x4C, 0x00, 0xB3, 0x8F, 0x48, 0x00, 0xB2, 0x8F, -0x44, 0x00, 0xB1, 0x8F, 0x40, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x80, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x68, 0x00, 0xBD, 0x27, 0xAC, 0x59, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0xFF, 0x01, 0x03, 0x24, 0x23, 0x18, 0x62, 0x00, -0xFF, 0xFF, 0x70, 0x30, 0xFF, 0xFF, 0xA2, 0x32, 0x2B, 0x10, 0x02, 0x02, -0xE7, 0xFF, 0x40, 0x14, 0x21, 0x20, 0x40, 0x02, 0x18, 0x00, 0xB0, 0x93, -0x19, 0x00, 0xA2, 0x93, 0x00, 0x81, 0x10, 0x00, 0x25, 0x80, 0x02, 0x02, -0xFF, 0x00, 0x10, 0x32, 0x2C, 0x59, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x02, -0x21, 0x20, 0x40, 0x02, 0xFF, 0x58, 0x00, 0x0C, 0x11, 0x00, 0xA5, 0x27, -0x11, 0x00, 0xA3, 0x93, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x64, 0x30, -0x9D, 0xFF, 0x90, 0x10, 0x20, 0x00, 0x16, 0x24, 0xFF, 0x00, 0x02, 0x24, -0xCD, 0xFF, 0x82, 0x10, 0x0F, 0x00, 0x63, 0x30, 0x02, 0x11, 0x04, 0x00, -0x21, 0x20, 0x60, 0x00, 0x29, 0x00, 0xA3, 0xA3, 0x83, 0x59, 0x00, 0x0C, -0x28, 0x00, 0xA2, 0xA3, 0x38, 0x00, 0xA4, 0x27, 0xFF, 0x00, 0x05, 0x24, -0x08, 0x00, 0x06, 0x24, 0xE3, 0x54, 0x00, 0x0C, 0x21, 0x80, 0x40, 0x00, -0x28, 0x00, 0xA4, 0x93, 0xCF, 0x59, 0x00, 0x0C, 0x38, 0x00, 0xA5, 0x27, -0x1F, 0x00, 0x40, 0x14, 0x01, 0x00, 0x44, 0x26, 0x40, 0x10, 0x10, 0x00, -0x21, 0x10, 0x52, 0x00, 0x01, 0x00, 0x42, 0x24, 0x2C, 0x5B, 0x00, 0x08, -0xFF, 0xFF, 0x52, 0x30, 0x40, 0x88, 0x10, 0x00, 0x27, 0x00, 0x20, 0x1A, -0x21, 0x80, 0x00, 0x00, 0xFF, 0x00, 0x16, 0x24, 0x21, 0x20, 0x50, 0x02, -0x01, 0x00, 0x84, 0x24, 0xFF, 0xFF, 0x84, 0x30, 0xFF, 0x58, 0x00, 0x0C, -0x10, 0x00, 0xA5, 0x27, 0x01, 0x00, 0x03, 0x26, 0xFF, 0x00, 0x70, 0x30, -0x05, 0x00, 0x40, 0x10, 0x2A, 0x18, 0x11, 0x02, 0x10, 0x00, 0xA2, 0x93, -0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x56, 0x00, 0x0B, 0x98, 0x02, 0x00, -0xF3, 0xFF, 0x60, 0x14, 0x21, 0x20, 0x50, 0x02, 0x15, 0x00, 0x60, 0x16, -0x21, 0x10, 0x32, 0x02, 0x01, 0x00, 0x42, 0x24, 0xFF, 0xFF, 0x52, 0x30, -0xF9, 0x5A, 0x00, 0x08, 0x01, 0x00, 0x16, 0x24, 0x29, 0x00, 0xA5, 0x93, -0xFF, 0xFF, 0x84, 0x30, 0x6A, 0x5A, 0x00, 0x0C, 0x38, 0x00, 0xA6, 0x27, -0x21, 0x28, 0x40, 0x00, 0x0F, 0x00, 0x43, 0x30, 0x0F, 0x00, 0x02, 0x24, -0xDB, 0xFF, 0x62, 0x10, 0x40, 0x10, 0x10, 0x00, 0x28, 0x00, 0xA4, 0x93, -0xB9, 0x5A, 0x00, 0x0C, 0x38, 0x00, 0xA6, 0x27, 0xAC, 0x59, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x2C, 0x5B, 0x00, 0x08, 0x21, 0x90, 0x40, 0x00, -0x19, 0x00, 0xA3, 0x93, 0x29, 0x00, 0xA6, 0x93, 0x0F, 0x00, 0x13, 0x24, -0x0E, 0x00, 0x10, 0x24, 0x25, 0x18, 0x66, 0x00, 0x01, 0x00, 0x62, 0x30, -0x0A, 0x98, 0x02, 0x02, 0x02, 0x00, 0x64, 0x30, 0xFD, 0x00, 0x62, 0x32, -0x0A, 0x98, 0x44, 0x00, 0x04, 0x00, 0x65, 0x30, 0xFB, 0x00, 0x62, 0x32, -0x0A, 0x98, 0x45, 0x00, 0x08, 0x00, 0x63, 0x30, 0xF7, 0x00, 0x62, 0x32, -0x0A, 0x98, 0x43, 0x00, 0x0F, 0x00, 0x64, 0x32, 0x0F, 0x00, 0x16, 0x24, -0x25, 0x00, 0x96, 0x10, 0x21, 0x28, 0xC0, 0x00, 0x01, 0x00, 0x44, 0x26, -0xFF, 0xFF, 0x84, 0x30, 0x6A, 0x5A, 0x00, 0x0C, 0x1A, 0x00, 0xA6, 0x27, -0x21, 0x28, 0x40, 0x00, 0x0F, 0x00, 0x42, 0x30, 0x03, 0x00, 0x56, 0x10, -0x21, 0x20, 0x80, 0x02, 0xB9, 0x5A, 0x00, 0x0C, 0x38, 0x00, 0xA6, 0x27, -0x19, 0x00, 0xA5, 0x93, 0x00, 0x00, 0x00, 0x00, 0x26, 0x10, 0x65, 0x02, -0x01, 0x00, 0x42, 0x30, 0x0A, 0x80, 0xC2, 0x02, 0x26, 0x18, 0x65, 0x02, -0x02, 0x00, 0x63, 0x30, 0xFD, 0x00, 0x04, 0x32, 0x0B, 0x80, 0x83, 0x00, -0x26, 0x10, 0x65, 0x02, 0x04, 0x00, 0x42, 0x30, 0xFB, 0x00, 0x03, 0x32, -0x0B, 0x80, 0x62, 0x00, 0x26, 0x28, 0x65, 0x02, 0x08, 0x00, 0xA5, 0x30, -0xF7, 0x00, 0x02, 0x32, 0x0B, 0x80, 0x45, 0x00, 0x0F, 0x00, 0x03, 0x32, -0x0D, 0x00, 0x76, 0x10, 0x00, 0x00, 0x00, 0x00, 0xAC, 0x59, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x21, 0x90, 0x40, 0x00, 0x19, 0x00, 0xB0, 0xA3, -0x2C, 0x5B, 0x00, 0x08, 0x18, 0x00, 0xB4, 0xA3, 0x21, 0x10, 0x32, 0x02, -0x01, 0x00, 0x42, 0x24, 0xFF, 0xFF, 0x52, 0x30, 0x01, 0x00, 0x16, 0x24, -0xF9, 0x5A, 0x00, 0x08, 0x18, 0x00, 0xB4, 0xA3, 0x2C, 0x5B, 0x00, 0x08, -0x21, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x85, 0xAC, 0x21, 0x10, 0x00, 0x00, -0x01, 0x00, 0x42, 0x24, 0xFF, 0x00, 0x42, 0x30, 0x06, 0x00, 0x43, 0x2C, -0xFC, 0xFF, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xA5, 0x30, 0x00, 0x00, 0x85, 0xA4, -0x21, 0x10, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xFF, 0x00, 0x42, 0x30, -0x06, 0x00, 0x43, 0x2C, 0xFC, 0xFF, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xA5, 0x30, -0x00, 0x00, 0x85, 0xA0, 0x21, 0x10, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, -0xFF, 0x00, 0x42, 0x30, 0x06, 0x00, 0x43, 0x2C, 0xFC, 0xFF, 0x60, 0x14, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x82, 0x8C, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x82, 0x94, 0x08, 0x00, 0xE0, 0x03, 0xFF, 0xFF, 0x42, 0x30, -0x00, 0x00, 0x82, 0x90, 0x08, 0x00, 0xE0, 0x03, 0xFF, 0x00, 0x42, 0x30, -0x25, 0xB0, 0x02, 0x3C, 0x21, 0x20, 0x82, 0x00, 0x00, 0x00, 0x85, 0xAC, -0x21, 0x10, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xFF, 0x00, 0x42, 0x30, -0x06, 0x00, 0x43, 0x2C, 0xFC, 0xFF, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x02, 0x3C, -0x21, 0x20, 0x82, 0x00, 0xFF, 0xFF, 0xA5, 0x30, 0x00, 0x00, 0x85, 0xA4, -0x21, 0x10, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xFF, 0x00, 0x42, 0x30, -0x06, 0x00, 0x43, 0x2C, 0xFC, 0xFF, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x02, 0x3C, -0x21, 0x20, 0x82, 0x00, 0xFF, 0x00, 0xA5, 0x30, 0x00, 0x00, 0x85, 0xA0, -0x21, 0x10, 0x00, 0x00, 0x01, 0x00, 0x42, 0x24, 0xFF, 0x00, 0x42, 0x30, -0x06, 0x00, 0x43, 0x2C, 0xFC, 0xFF, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x02, 0x3C, -0x21, 0x20, 0x82, 0x00, 0x00, 0x00, 0x82, 0x8C, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0x25, 0xB0, 0x02, 0x3C, 0x21, 0x20, 0x82, 0x00, -0x00, 0x00, 0x82, 0x94, 0x08, 0x00, 0xE0, 0x03, 0xFF, 0xFF, 0x42, 0x30, -0x25, 0xB0, 0x02, 0x3C, 0x21, 0x20, 0x82, 0x00, 0x00, 0x00, 0x82, 0x90, -0x08, 0x00, 0xE0, 0x03, 0xFF, 0x00, 0x42, 0x30, 0x01, 0x80, 0x02, 0x3C, -0x25, 0xB0, 0x03, 0x3C, 0xD4, 0x70, 0x42, 0x24, 0x18, 0x03, 0x63, 0x34, -0x00, 0x00, 0x62, 0xAC, 0x00, 0x00, 0x83, 0x90, 0x30, 0x00, 0x02, 0x24, -0x05, 0x00, 0x62, 0x10, 0x21, 0x20, 0x00, 0x00, 0x31, 0x00, 0x02, 0x24, -0x02, 0x00, 0x62, 0x10, 0x01, 0x00, 0x04, 0x24, 0x07, 0x00, 0x04, 0x24, -0x7E, 0x58, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x02, 0x3C, -0x25, 0xB0, 0x03, 0x3C, 0x10, 0x71, 0x42, 0x24, 0x18, 0x03, 0x63, 0x34, -0x02, 0x80, 0x04, 0x3C, 0x00, 0x00, 0x62, 0xAC, 0x08, 0x00, 0xE0, 0x03, -0xFC, 0x5C, 0x80, 0xAC, 0x42, 0xB0, 0x02, 0x3C, 0x03, 0x00, 0x47, 0x34, -0x00, 0x00, 0xE3, 0x90, 0xFF, 0x00, 0x84, 0x30, 0x04, 0x00, 0x84, 0x24, -0xFF, 0x00, 0x65, 0x30, 0x01, 0x00, 0x02, 0x24, 0x04, 0x30, 0x82, 0x00, -0x07, 0x18, 0x85, 0x00, 0x25, 0xB0, 0x02, 0x3C, 0xE8, 0x03, 0x42, 0x34, -0x01, 0x00, 0x63, 0x30, 0x21, 0x20, 0xC0, 0x00, 0x00, 0x00, 0x45, 0xA0, -0x02, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0xA0, -0x08, 0x00, 0xE0, 0x03, 0x24, 0x10, 0x85, 0x00, 0xE0, 0xFF, 0xBD, 0x27, -0x18, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0x80, 0x00, 0x1C, 0x00, 0xBF, 0xAF, -0x8A, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x02, 0x80, 0x02, 0x3C, -0xD0, 0xDF, 0x42, 0x24, 0x04, 0x00, 0x43, 0x8C, 0x00, 0x00, 0x02, 0xAE, -0x04, 0x00, 0x50, 0xAC, 0x00, 0x00, 0x70, 0xAC, 0x04, 0x00, 0x03, 0xAE, -0x90, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, 0x1C, 0x00, 0xBF, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB0, 0xAF, 0x21, 0x80, 0x80, 0x00, -0x1C, 0x00, 0xBF, 0xAF, 0x8A, 0x40, 0x00, 0x0C, 0x10, 0x00, 0xA4, 0x27, -0x04, 0x00, 0x03, 0x8E, 0x00, 0x00, 0x02, 0x8E, 0x10, 0x00, 0xA4, 0x27, -0x00, 0x00, 0x62, 0xAC, 0x04, 0x00, 0x43, 0xAC, 0x00, 0x00, 0x10, 0xAE, -0x90, 0x40, 0x00, 0x0C, 0x04, 0x00, 0x10, 0xAE, 0x1C, 0x00, 0xBF, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0x1F, 0xF7, 0x00, 0x6A, 0x82, 0x34, 0x4C, 0xEC, 0x82, 0x34, 0x8C, 0x32, -0x89, 0xE2, 0x48, 0x32, 0x89, 0xE2, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, -0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0x48, 0x32, 0x69, 0xE2, 0x04, 0xF5, -0x68, 0x9A, 0x01, 0xF6, 0x01, 0x6C, 0x8B, 0xEC, 0x8C, 0xEB, 0x04, 0xF5, -0x68, 0xDA, 0x20, 0xE8, 0x00, 0x65, 0x00, 0x00, 0x1F, 0xF7, 0x00, 0x6A, -0x82, 0x34, 0x4C, 0xEC, 0x82, 0x34, 0x8C, 0x32, 0x89, 0xE2, 0x48, 0x32, -0x89, 0xE2, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, -0x00, 0x4B, 0x48, 0x32, 0x69, 0xE2, 0x04, 0xF5, 0x68, 0x9A, 0x01, 0xF6, -0x01, 0x6C, 0x8B, 0xEC, 0x8C, 0xEB, 0x00, 0xF2, 0x00, 0x6C, 0x8D, 0xEB, -0x04, 0xF5, 0x68, 0xDA, 0x20, 0xE8, 0x00, 0x65, 0xFF, 0x6B, 0x6C, 0xED, -0x04, 0x5D, 0x6C, 0xEC, 0x69, 0x60, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, -0x40, 0x32, 0xCB, 0xF4, 0x46, 0xA2, 0xEF, 0x4A, 0x6C, 0xEA, 0x02, 0x5A, -0x0C, 0x60, 0x02, 0x74, 0x38, 0x60, 0x03, 0x54, 0x1D, 0x61, 0x03, 0x74, -0x2C, 0x60, 0x04, 0xF0, 0x00, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xE8, -0xFF, 0x4A, 0x02, 0x74, 0x3D, 0x60, 0x03, 0x54, 0x18, 0x61, 0x03, 0x74, -0xF4, 0x61, 0x01, 0x75, 0x43, 0x60, 0x02, 0x55, 0x31, 0x61, 0x02, 0x75, -0x42, 0x60, 0x03, 0x75, 0xEC, 0x61, 0x02, 0xF0, 0x00, 0x6A, 0x40, 0x32, -0x1E, 0xF0, 0x00, 0x4A, 0x20, 0xE8, 0x00, 0x65, 0x01, 0x74, 0xE3, 0x61, -0x02, 0xF0, 0x0F, 0x6A, 0x40, 0x32, 0x20, 0xE8, 0x40, 0x32, 0x01, 0x74, -0xDC, 0x61, 0x03, 0xF7, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x10, 0xF0, -0x00, 0x4A, 0x20, 0xE8, 0x00, 0x65, 0x01, 0x75, 0x1B, 0x60, 0x02, 0x55, -0x08, 0x61, 0x02, 0x75, 0x29, 0x60, 0x03, 0x75, 0xCC, 0x61, 0x02, 0xF0, -0x10, 0x6A, 0x40, 0x32, 0xDE, 0x17, 0xC7, 0x2D, 0x02, 0xF0, 0x10, 0x6A, -0x40, 0x32, 0x40, 0x32, 0x1E, 0xF0, 0x15, 0x4A, 0x20, 0xE8, 0x00, 0x65, -0xBE, 0x2D, 0x02, 0xF0, 0x00, 0x6A, 0xF7, 0x17, 0x03, 0xF7, 0x10, 0x6A, -0x40, 0x32, 0xCD, 0x17, 0x02, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, -0x1E, 0xF0, 0x10, 0x4A, 0x20, 0xE8, 0x00, 0x65, 0x02, 0xF0, 0x00, 0x6A, -0xF8, 0x17, 0x02, 0xF0, 0x00, 0x6A, 0x40, 0x32, 0x1E, 0xF0, 0x05, 0x4A, -0x20, 0xE8, 0x00, 0x65, 0x02, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0xF7, 0x17, -0xFC, 0x63, 0x06, 0xD0, 0x8C, 0x30, 0x81, 0xE0, 0x08, 0x30, 0x81, 0xE0, -0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, -0x08, 0x30, 0x41, 0xE0, 0xC9, 0xF7, 0x1B, 0x6D, 0x04, 0xF0, 0x00, 0x6A, -0x40, 0x32, 0xAB, 0xED, 0x40, 0x32, 0xA0, 0x35, 0xA0, 0x35, 0xFF, 0x4A, -0x04, 0xF5, 0x40, 0xD8, 0x07, 0x62, 0x80, 0xF1, 0x44, 0x45, 0x40, 0x9A, -0x08, 0x6B, 0x6B, 0xEB, 0x04, 0xF5, 0x44, 0xD8, 0x04, 0xF5, 0x48, 0x98, -0xC4, 0x67, 0x6C, 0xEA, 0xFF, 0x6B, 0x02, 0x4B, 0x6B, 0xEB, 0x6C, 0xEA, -0x02, 0xF0, 0x01, 0x6B, 0x6B, 0xEB, 0x6C, 0xEA, 0x04, 0xF5, 0x48, 0xD8, -0x04, 0xD5, 0x00, 0x18, 0xA5, 0x21, 0x05, 0xD6, 0x04, 0x95, 0x05, 0x96, -0x04, 0xF5, 0x4A, 0xA0, 0x60, 0xF1, 0x00, 0x4D, 0xB9, 0xE6, 0x40, 0xC6, -0x00, 0x6A, 0xC4, 0xF4, 0x58, 0xD8, 0xC4, 0xF4, 0x5C, 0xD8, 0xE4, 0xF4, -0x40, 0xD8, 0xE4, 0xF4, 0x44, 0xD8, 0xE4, 0xF4, 0x48, 0xD8, 0xE4, 0xF4, -0x4C, 0xD8, 0xE4, 0xF4, 0x50, 0xD8, 0xE4, 0xF4, 0x54, 0xD8, 0x07, 0x97, -0x06, 0x90, 0x00, 0xEF, 0x04, 0x63, 0x00, 0x00, 0xFF, 0x63, 0x00, 0xD0, -0x04, 0x67, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0xFF, 0x6F, -0x80, 0x34, 0xA0, 0xF1, 0x4F, 0x44, 0xEC, 0xEE, 0x01, 0xD1, 0x59, 0xE6, -0x40, 0xA6, 0xEC, 0xED, 0xC7, 0x67, 0x4C, 0xEE, 0xAC, 0x32, 0xA9, 0xE2, -0x48, 0x32, 0xA9, 0xE2, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, -0x63, 0xF3, 0x00, 0x4B, 0x48, 0x32, 0x69, 0xE2, 0x04, 0xF5, 0x48, 0x9A, -0x07, 0x6B, 0x80, 0xF1, 0x04, 0x4C, 0x6C, 0xEA, 0xEC, 0xEA, 0x48, 0x32, -0xEC, 0xE8, 0x89, 0xE2, 0x00, 0x6D, 0x80, 0x9A, 0x0D, 0x65, 0x70, 0x67, -0x2E, 0x26, 0x32, 0x24, 0x65, 0x67, 0x01, 0x69, 0x51, 0x67, 0x44, 0xEB, -0x8C, 0xEA, 0x36, 0x2A, 0x01, 0x4B, 0xEC, 0xEB, 0x1D, 0x5B, 0xF8, 0x61, -0x6F, 0x40, 0xFF, 0x6A, 0x4C, 0xEB, 0xE8, 0x67, 0xE3, 0xEB, 0x10, 0x61, -0x01, 0x69, 0xE2, 0x67, 0x51, 0x67, 0x44, 0xEB, 0x8C, 0xEA, 0x05, 0x22, -0xCA, 0xED, 0x26, 0x60, 0x01, 0x4D, 0xEC, 0xED, 0x03, 0x67, 0xFF, 0x4B, -0xEC, 0xEB, 0x48, 0x67, 0x43, 0xEB, 0xF2, 0x60, 0xC3, 0xED, 0x70, 0x67, -0x0A, 0x60, 0x68, 0x67, 0xAB, 0xE6, 0x42, 0xEB, 0x00, 0x6B, 0x05, 0x61, -0xE8, 0x67, 0xCB, 0xE7, 0xAD, 0xE2, 0xFF, 0x6A, 0x4C, 0xEB, 0x01, 0x91, -0x00, 0x90, 0x43, 0x67, 0x20, 0xE8, 0x01, 0x63, 0xC3, 0xE8, 0x65, 0x67, -0xF8, 0x61, 0xCF, 0xE0, 0x01, 0x91, 0x00, 0x90, 0xEC, 0xEB, 0x43, 0x67, -0x20, 0xE8, 0x01, 0x63, 0x0B, 0x65, 0xCC, 0x17, 0x70, 0x67, 0xED, 0x17, -0xC9, 0xF7, 0x1B, 0x6E, 0xCB, 0xEE, 0xC0, 0x36, 0xFF, 0x6F, 0xC0, 0x36, -0xEC, 0xEC, 0xFF, 0x63, 0x60, 0xF1, 0x40, 0x46, 0x01, 0xD1, 0x00, 0xD0, -0x49, 0xE4, 0x40, 0xA2, 0x07, 0x67, 0xEC, 0xED, 0x4C, 0xE8, 0xA0, 0xF1, -0x4F, 0x46, 0x55, 0xE5, 0x40, 0xA5, 0x27, 0x67, 0x10, 0xF0, 0x02, 0x6B, -0x00, 0xF4, 0x60, 0x33, 0x4C, 0xE9, 0x8C, 0x32, 0x89, 0xE2, 0x48, 0x32, -0x89, 0xE2, 0x63, 0xF3, 0x00, 0x4B, 0x48, 0x32, 0x69, 0xE2, 0x04, 0xF5, -0x48, 0x9A, 0x07, 0x6B, 0x80, 0xF1, 0x04, 0x4E, 0x6C, 0xEA, 0xEC, 0xEA, -0x48, 0x32, 0xC9, 0xE2, 0x00, 0x6D, 0x80, 0x9A, 0x2D, 0x65, 0x70, 0x67, -0x30, 0x21, 0x34, 0x24, 0x01, 0x6A, 0x65, 0x67, 0x0A, 0x65, 0xC7, 0x67, -0x48, 0x67, 0x44, 0xEB, 0x8C, 0xEA, 0x36, 0x2A, 0x01, 0x4B, 0xCC, 0xEB, -0x1D, 0x5B, 0xF8, 0x61, 0x6F, 0x40, 0xFF, 0x6A, 0x4C, 0xEB, 0xC9, 0x67, -0xC3, 0xEB, 0x10, 0x61, 0x01, 0x6F, 0xC2, 0x67, 0x47, 0x67, 0x44, 0xEB, -0x8C, 0xEA, 0x05, 0x22, 0x2A, 0xED, 0x26, 0x60, 0x01, 0x4D, 0xCC, 0xED, -0x03, 0x67, 0xFF, 0x4B, 0xCC, 0xEB, 0x49, 0x67, 0x43, 0xEB, 0xF2, 0x60, -0x23, 0xED, 0x70, 0x67, 0x0A, 0x60, 0x69, 0x67, 0xAB, 0xE1, 0x42, 0xEB, -0x00, 0x6B, 0x05, 0x61, 0xC9, 0x67, 0x2B, 0xE6, 0xAD, 0xE2, 0xFF, 0x6A, -0x4C, 0xEB, 0x01, 0x91, 0x00, 0x90, 0x43, 0x67, 0x20, 0xE8, 0x01, 0x63, -0x23, 0xE8, 0x65, 0x67, 0xF8, 0x61, 0x2F, 0xE0, 0x01, 0x91, 0x00, 0x90, -0xEC, 0xEB, 0x43, 0x67, 0x20, 0xE8, 0x01, 0x63, 0x2B, 0x65, 0xCC, 0x17, -0x70, 0x67, 0xED, 0x17, 0x10, 0xF0, 0x02, 0x6E, 0x00, 0xF4, 0xC0, 0x36, -0xFB, 0x63, 0x00, 0x6D, 0x63, 0xF3, 0x00, 0x4E, 0x07, 0xD1, 0x06, 0xD0, -0x08, 0x62, 0x05, 0x67, 0x26, 0x67, 0x85, 0x67, 0x04, 0xD5, 0x00, 0x18, -0xDB, 0x5C, 0x05, 0xD6, 0x04, 0xF5, 0x4A, 0xA1, 0xFF, 0x6B, 0x05, 0x96, -0x6C, 0xEA, 0x48, 0x32, 0xC9, 0xE2, 0xC0, 0xF5, 0x74, 0x9A, 0x60, 0xF5, -0x40, 0x9A, 0x4D, 0xE3, 0x66, 0x33, 0xC4, 0xF4, 0x74, 0xD9, 0x04, 0x95, -0x00, 0x6B, 0x69, 0xE1, 0x01, 0x4B, 0x1D, 0x53, 0x04, 0xF5, 0x0C, 0xC2, -0x24, 0xF5, 0x09, 0xC2, 0x44, 0xF5, 0x06, 0xC2, 0xF6, 0x61, 0x00, 0x6A, -0x01, 0x4D, 0x64, 0xF5, 0x44, 0xD9, 0x20, 0x55, 0x7F, 0x49, 0x15, 0x49, -0xD8, 0x61, 0x08, 0x97, 0x07, 0x91, 0x06, 0x90, 0x00, 0xEF, 0x05, 0x63, -0xF8, 0x63, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x07, 0xD2, -0x0E, 0x62, 0x0D, 0xD1, 0x0C, 0xD0, 0x63, 0xF3, 0x00, 0x4A, 0x27, 0xF1, -0x44, 0x9A, 0xFF, 0x6B, 0x6C, 0xEC, 0x6C, 0x65, 0xFF, 0xF7, 0x1F, 0x72, -0x00, 0x6C, 0x05, 0xD4, 0x01, 0x61, 0x05, 0xD3, 0x07, 0x93, 0xFF, 0xF7, -0x1F, 0x6A, 0x8B, 0x67, 0x63, 0xF3, 0x00, 0x4B, 0x27, 0xF1, 0x44, 0xDB, -0x00, 0x6A, 0x04, 0xD2, 0x00, 0xF1, 0x18, 0x24, 0x10, 0xF0, 0x02, 0x6D, -0x00, 0xF4, 0xA0, 0x35, 0x22, 0x67, 0xBC, 0xF3, 0x0C, 0x4D, 0xFF, 0x6E, -0x00, 0xF5, 0x84, 0x43, 0x05, 0x10, 0x01, 0x49, 0x1D, 0x51, 0x60, 0xC4, -0x01, 0x4C, 0x0B, 0x60, 0xA9, 0xE1, 0x60, 0xA2, 0x46, 0x67, 0x6C, 0xEA, -0xF6, 0x22, 0x01, 0x49, 0x4D, 0x43, 0x1D, 0x51, 0x40, 0xC4, 0x01, 0x4C, -0xF5, 0x61, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x10, 0xF0, -0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, -0x80, 0x34, 0x00, 0x69, 0x63, 0xF3, 0x00, 0x4A, 0x5C, 0xF1, 0x04, 0x4B, -0xDC, 0xF0, 0x0C, 0x4C, 0x0A, 0x65, 0x4B, 0x65, 0x2C, 0x65, 0x11, 0x67, -0x48, 0x67, 0x6A, 0x67, 0x00, 0x6D, 0x5D, 0xE0, 0x79, 0xE0, 0xAD, 0xE6, -0x40, 0xA3, 0xB1, 0xE7, 0x01, 0x4D, 0xA0, 0xF3, 0x48, 0xC4, 0x80, 0xF0, -0x51, 0xA3, 0x05, 0x55, 0x20, 0xF4, 0x59, 0xC4, 0xF4, 0x61, 0x48, 0x67, -0x51, 0xE1, 0x49, 0x67, 0x4D, 0xE1, 0x40, 0xA3, 0x01, 0x49, 0x1D, 0x51, -0xC0, 0xF4, 0x4A, 0xC4, 0x5D, 0xA3, 0x05, 0x48, 0xE0, 0xF4, 0x47, 0xC4, -0xE1, 0x61, 0x6B, 0x67, 0x00, 0xF1, 0x0A, 0x23, 0x10, 0xF0, 0x02, 0x6E, -0x00, 0xF4, 0xC0, 0x36, 0x10, 0xF0, 0x02, 0x6F, 0x00, 0xF4, 0xE0, 0x37, -0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, 0x00, 0x69, 0x63, 0xF3, -0x00, 0x4E, 0x5C, 0xF4, 0x00, 0x4F, 0xDC, 0xF3, 0x0C, 0x4D, 0x28, 0x32, -0xED, 0xE2, 0x60, 0x9B, 0xD1, 0xE2, 0xA9, 0xE2, 0xC0, 0xF5, 0x74, 0xDC, -0x40, 0x9A, 0x01, 0x49, 0x04, 0x51, 0x60, 0xF5, 0x40, 0xDC, 0xF3, 0x61, -0x10, 0xF0, 0x02, 0x6F, 0x00, 0xF4, 0xE0, 0x37, 0x10, 0xF0, 0x02, 0x6E, -0x00, 0xF4, 0xC0, 0x36, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, -0x04, 0x69, 0x63, 0xF3, 0x00, 0x4F, 0x5C, 0xF4, 0x00, 0x4E, 0xDC, 0xF3, -0x0C, 0x4D, 0x28, 0x33, 0xC9, 0xE3, 0x40, 0x9A, 0xF1, 0xE3, 0xAD, 0xE3, -0x4A, 0x32, 0xC0, 0xF5, 0x54, 0xDC, 0x40, 0x9B, 0x01, 0x49, 0x1D, 0x51, -0x4A, 0x32, 0x60, 0xF5, 0x40, 0xDC, 0xF1, 0x61, 0x10, 0xF0, 0x02, 0x6C, -0x00, 0xF4, 0x80, 0x34, 0x63, 0xF3, 0x00, 0x4C, 0x00, 0x69, 0x04, 0x67, -0xD1, 0x67, 0xC4, 0xF4, 0x14, 0x48, 0x06, 0xD4, 0x08, 0xD1, 0x09, 0x10, -0x08, 0x94, 0x01, 0x49, 0x7F, 0x48, 0x7F, 0x4C, 0x15, 0x4C, 0x20, 0x51, -0x15, 0x48, 0x08, 0xD4, 0x5E, 0x60, 0x8D, 0x98, 0x01, 0x6B, 0x82, 0x32, -0x52, 0x32, 0x6C, 0xEA, 0xFF, 0x6B, 0x6C, 0xEA, 0xEF, 0x22, 0x07, 0x6A, -0x4C, 0xEC, 0x6C, 0xEC, 0x88, 0x32, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, -0x80, 0x34, 0x80, 0x34, 0x80, 0xF1, 0x04, 0x4C, 0x89, 0xE2, 0x6B, 0x98, -0x40, 0x9A, 0x91, 0x67, 0x6C, 0xEA, 0x4C, 0xD8, 0x00, 0x18, 0xA5, 0x21, -0x0A, 0xD6, 0x20, 0xF0, 0x96, 0xA0, 0xFF, 0x6A, 0xA2, 0x67, 0x4C, 0xEC, -0x00, 0x18, 0x93, 0x21, 0x2C, 0xED, 0x20, 0xF0, 0x56, 0xA0, 0x04, 0x94, -0xFF, 0x6B, 0x6C, 0xEA, 0x43, 0xEC, 0x0A, 0x96, 0x01, 0x60, 0x04, 0xD2, -0xC1, 0xD8, 0xC2, 0xD8, 0xC3, 0xD8, 0xC4, 0xD8, 0xC5, 0xD8, 0xC6, 0xD8, -0xC7, 0xD8, 0xC8, 0xD8, 0x06, 0x93, 0x48, 0x32, 0xA6, 0x67, 0x69, 0xE2, -0xC0, 0xF5, 0x74, 0x9A, 0x60, 0xF5, 0x40, 0x9A, 0x4D, 0xE3, 0x66, 0x33, -0x60, 0xD8, 0x08, 0x92, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, -0x63, 0xF3, 0x00, 0x4B, 0x71, 0xE2, 0x66, 0x67, 0xA9, 0xE4, 0x01, 0x4D, -0x1D, 0x55, 0x04, 0xF5, 0x6C, 0xC2, 0x24, 0xF5, 0x69, 0xC2, 0x44, 0xF5, -0x66, 0xC2, 0xF6, 0x61, 0x64, 0xF5, 0xC4, 0xDC, 0x08, 0x94, 0x01, 0x49, -0x7F, 0x48, 0x7F, 0x4C, 0x15, 0x4C, 0x20, 0x51, 0x15, 0x48, 0x08, 0xD4, -0xA2, 0x61, 0x05, 0x92, 0x06, 0x2A, 0x07, 0x93, 0x63, 0xF3, 0x00, 0x4B, -0x07, 0xD3, 0x27, 0xF1, 0x44, 0xDB, 0x0E, 0x97, 0x0D, 0x91, 0x0C, 0x90, -0x00, 0xEF, 0x08, 0x63, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, -0x22, 0x67, 0xBC, 0xF3, 0x0C, 0x4C, 0x00, 0xF5, 0x04, 0x4B, 0x89, 0xE1, -0x40, 0xA2, 0x01, 0x49, 0x1D, 0x51, 0x40, 0xC3, 0x01, 0x4B, 0xF9, 0x61, -0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x10, 0xF0, 0x02, 0x6C, -0x00, 0xF4, 0x80, 0x34, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, -0x00, 0x69, 0x63, 0xF3, 0x00, 0x4B, 0x7C, 0xF2, 0x08, 0x4C, 0x1C, 0xF1, -0x08, 0x4A, 0x0B, 0x65, 0x4C, 0x65, 0x2A, 0x65, 0x11, 0x67, 0x68, 0x67, -0x8A, 0x67, 0x00, 0x6D, 0x7D, 0xE0, 0x99, 0xE0, 0xAD, 0xE6, 0x40, 0xA3, -0xB1, 0xE7, 0x01, 0x4D, 0xA0, 0xF3, 0x48, 0xC4, 0x80, 0xF0, 0x51, 0xA3, -0x05, 0x55, 0x20, 0xF4, 0x59, 0xC4, 0xF4, 0x61, 0x48, 0x67, 0x51, 0xE1, -0x49, 0x67, 0x4D, 0xE1, 0x40, 0xA3, 0x01, 0x49, 0x1D, 0x51, 0xC0, 0xF4, -0x4A, 0xC4, 0x5D, 0xA3, 0x05, 0x48, 0xE0, 0xF4, 0x47, 0xC4, 0xE1, 0x61, -0x10, 0xF0, 0x02, 0x6F, 0x00, 0xF4, 0xE0, 0x37, 0x10, 0xF0, 0x02, 0x6E, -0x00, 0xF4, 0xC0, 0x36, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, -0x2B, 0x67, 0x63, 0xF3, 0x00, 0x4F, 0x5C, 0xF4, 0x00, 0x4E, 0xDC, 0xF3, -0x0C, 0x4D, 0x28, 0x32, 0xCD, 0xE2, 0x60, 0x9B, 0xF1, 0xE2, 0xA9, 0xE2, -0xC0, 0xF5, 0x74, 0xDC, 0x40, 0x9A, 0x01, 0x49, 0x1D, 0x51, 0x60, 0xF5, -0x40, 0xDC, 0xF3, 0x61, 0x17, 0x17, 0x00, 0x00, 0xFF, 0xF7, 0x1F, 0x6F, -0x8C, 0xEF, 0xE0, 0xF1, 0x10, 0x6E, 0xEC, 0xEE, 0xFB, 0x63, 0xD2, 0x36, -0x06, 0xD0, 0xCC, 0x30, 0xC1, 0xE0, 0x08, 0x30, 0xC1, 0xE0, 0x10, 0xF0, -0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, 0x08, 0x30, -0x41, 0xE0, 0x08, 0x62, 0x07, 0xD1, 0x25, 0x67, 0x04, 0xF5, 0xA8, 0x98, -0x02, 0xF0, 0x00, 0x6A, 0xFF, 0x6B, 0x4D, 0xED, 0x00, 0xF2, 0x00, 0x6A, -0xEC, 0xEA, 0x43, 0x32, 0x02, 0x4B, 0x6B, 0xEB, 0x47, 0x32, 0x6C, 0xED, -0x40, 0x32, 0x4D, 0xED, 0x04, 0xF5, 0x20, 0xD8, 0x04, 0xF5, 0xA8, 0xD8, -0x87, 0x67, 0x04, 0xD5, 0x00, 0x18, 0x2C, 0x22, 0x05, 0xD6, 0x04, 0x95, -0x08, 0x6B, 0x07, 0x6C, 0x6B, 0xEB, 0x8C, 0xEA, 0xAC, 0xEB, 0x4D, 0xEB, -0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x04, 0xF5, 0x68, 0xD8, -0x40, 0x32, 0x8C, 0xEB, 0x80, 0xF1, 0x04, 0x4A, 0x68, 0x33, 0x4D, 0xE3, -0x40, 0x9B, 0x2C, 0xEA, 0x04, 0xF5, 0x44, 0xD8, 0x05, 0x96, 0x00, 0x18, -0xA5, 0x21, 0x86, 0x67, 0x05, 0x96, 0x04, 0xF5, 0x8A, 0xA0, 0x00, 0x18, -0x93, 0x21, 0xA6, 0x67, 0x08, 0x97, 0x07, 0x91, 0x06, 0x90, 0x00, 0xEF, -0x05, 0x63, 0x00, 0x00, 0xFF, 0x6A, 0xFD, 0x63, 0x04, 0x62, 0x00, 0x18, -0xDB, 0x5C, 0x4C, 0xEC, 0x04, 0x97, 0x00, 0xEF, 0x03, 0x63, 0x00, 0x00, -0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x02, 0xF0, 0x00, 0x6D, -0x63, 0xF3, 0x00, 0x4C, 0x1F, 0x6B, 0x04, 0xF5, 0x48, 0x9C, 0xFF, 0x4B, -0x00, 0x53, 0xAD, 0xEA, 0x04, 0xF5, 0x48, 0xDC, 0x7F, 0x4C, 0x15, 0x4C, -0xF6, 0x60, 0x20, 0xE8, 0x00, 0x65, 0x00, 0x65, 0x00, 0x1C, 0xA1, 0x5E, -0x00, 0x65, 0x00, 0x65, 0x83, 0xED, 0xAB, 0xE4, 0x01, 0x61, 0x8B, 0xE5, -0x20, 0xE8, 0x00, 0x65, 0xC9, 0xF7, 0x1B, 0x6A, 0xF9, 0x63, 0x4B, 0xEA, -0x0A, 0xD0, 0x40, 0x30, 0x00, 0x30, 0x01, 0xF5, 0x83, 0x40, 0x0C, 0x62, -0x00, 0x1C, 0x00, 0x5C, 0x0B, 0xD1, 0x05, 0xD2, 0x05, 0x93, 0x70, 0x6A, -0x6C, 0xEA, 0x3A, 0x2A, 0x67, 0x40, 0x3B, 0x4B, 0x01, 0x6A, 0x4B, 0xEA, -0x40, 0xC3, 0x05, 0x93, 0x70, 0x6A, 0x4C, 0xEB, 0x08, 0xD3, 0x3C, 0x2B, -0x9D, 0x67, 0x00, 0x1C, 0x8A, 0x40, 0x10, 0x4C, 0x02, 0xF0, 0x00, 0x6A, -0x40, 0x31, 0xAF, 0x41, 0x00, 0x1C, 0xAC, 0x45, 0x18, 0x6C, 0x9D, 0x67, -0x10, 0x4C, 0x00, 0x1C, 0x90, 0x40, 0x02, 0x67, 0x00, 0x1C, 0x5B, 0x1F, -0x64, 0x6C, 0x10, 0xF0, 0x00, 0x6A, 0xD0, 0x67, 0x4D, 0xEE, 0x18, 0x6C, -0x00, 0x1C, 0x83, 0x45, 0xAF, 0x41, 0x00, 0x1C, 0x2C, 0x1F, 0x03, 0x6C, -0x08, 0x92, 0x6A, 0x2A, 0xC9, 0xF7, 0x1B, 0x6A, 0x7D, 0x67, 0x4B, 0xEA, -0x40, 0x32, 0x20, 0xF0, 0x60, 0xA3, 0x0C, 0x97, 0x0B, 0x91, 0x0A, 0x90, -0x40, 0x32, 0x42, 0x4A, 0x07, 0x63, 0x60, 0xC2, 0x00, 0xEF, 0x00, 0x65, -0x8F, 0x6A, 0xA3, 0x67, 0x01, 0xF5, 0x83, 0x40, 0x00, 0x1C, 0xF0, 0x5B, -0x4C, 0xED, 0x05, 0x93, 0x70, 0x6A, 0x4C, 0xEB, 0x08, 0xD3, 0xC4, 0x23, -0x9D, 0x67, 0x00, 0x1C, 0x8A, 0x40, 0x10, 0x4C, 0x02, 0xF0, 0x00, 0x6D, -0xA0, 0x31, 0xAF, 0x41, 0x00, 0x1C, 0xAC, 0x45, 0x00, 0x6C, 0x9D, 0x67, -0x10, 0x4C, 0x00, 0x1C, 0x90, 0x40, 0x06, 0xD2, 0x00, 0x1C, 0x5B, 0x1F, -0x64, 0x6C, 0x00, 0x1C, 0xF0, 0x42, 0x01, 0x6C, 0x9D, 0x67, 0x00, 0x1C, -0x8A, 0x40, 0x10, 0x4C, 0xAF, 0x41, 0x00, 0x1C, 0xAC, 0x45, 0x00, 0x6C, -0x9D, 0x67, 0x10, 0x4C, 0x00, 0x1C, 0x90, 0x40, 0x07, 0xD2, 0x00, 0x1C, -0x5B, 0x1F, 0x64, 0x6C, 0x00, 0x1C, 0xF0, 0x42, 0x00, 0x6C, 0x01, 0xF1, -0x00, 0x68, 0x06, 0x96, 0x00, 0x30, 0x01, 0x6A, 0xFF, 0x48, 0x40, 0x32, -0x40, 0x32, 0x0C, 0xEE, 0x4D, 0xEE, 0xAF, 0x41, 0x00, 0x1C, 0x83, 0x45, -0x00, 0x6C, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x00, 0x1C, 0xF0, 0x42, -0x01, 0x6C, 0x07, 0x93, 0x01, 0x6E, 0xC0, 0x36, 0x6C, 0xE8, 0xC0, 0x36, -0xAF, 0x41, 0x0D, 0xEE, 0x00, 0x1C, 0x83, 0x45, 0x00, 0x6C, 0x00, 0x1C, -0x5B, 0x1F, 0x64, 0x6C, 0x00, 0x1C, 0xF0, 0x42, 0x00, 0x6C, 0x76, 0x17, -0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x01, 0xF5, -0x03, 0x4C, 0x00, 0x1C, 0xF0, 0x5B, 0x05, 0x95, 0x06, 0x96, 0xAF, 0x41, -0x00, 0x1C, 0x83, 0x45, 0x00, 0x6C, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, -0x00, 0x1C, 0xF0, 0x42, 0x01, 0x6C, 0x07, 0x96, 0xAF, 0x41, 0x00, 0x1C, -0x83, 0x45, 0x00, 0x6C, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, 0x00, 0x1C, -0xF0, 0x42, 0x00, 0x6C, 0x0C, 0x97, 0x0B, 0x91, 0x0A, 0x90, 0x00, 0xEF, -0x07, 0x63, 0x00, 0x00, 0xF8, 0x63, 0x0D, 0xD1, 0x10, 0xF0, 0x02, 0x69, -0x00, 0xF4, 0x20, 0x31, 0x0E, 0x62, 0x0C, 0xD0, 0x63, 0xF3, 0x00, 0x49, -0x03, 0x99, 0x01, 0x6A, 0x80, 0xF7, 0x02, 0x30, 0x4C, 0xE8, 0x08, 0x28, -0x42, 0x99, 0x03, 0x6B, 0x40, 0xF7, 0x42, 0x32, 0x6C, 0xEA, 0x01, 0x72, -0x00, 0xF2, 0x07, 0x60, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, -0x63, 0xF3, 0x00, 0x4D, 0x43, 0x9D, 0x01, 0x6B, 0x80, 0xF7, 0x42, 0x32, -0x6C, 0xEA, 0xE0, 0xF1, 0x14, 0x22, 0x42, 0x9D, 0x03, 0x6B, 0x40, 0xF7, -0x42, 0x32, 0x6C, 0xEA, 0x01, 0x72, 0xE0, 0xF1, 0x0C, 0x61, 0x44, 0x9D, -0x80, 0xF7, 0x42, 0x32, 0x01, 0x72, 0xA0, 0xF2, 0x00, 0x60, 0xC9, 0xF7, -0x1B, 0x6C, 0x8B, 0xEC, 0xC0, 0xF2, 0xA7, 0xA5, 0x80, 0x34, 0x80, 0x34, -0x61, 0xF4, 0x02, 0x4C, 0x00, 0x1C, 0xF0, 0x5B, 0x06, 0xD5, 0x10, 0xF0, -0x02, 0x69, 0x00, 0xF4, 0x20, 0x31, 0x63, 0xF3, 0x00, 0x49, 0xC0, 0xF2, -0x46, 0xA1, 0x07, 0x2A, 0xBD, 0x67, 0xAC, 0xAD, 0x01, 0x6A, 0xC0, 0xF2, -0x46, 0xC1, 0xC0, 0xF2, 0xA4, 0xC9, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, -0x40, 0x30, 0x00, 0x30, 0x01, 0xF5, 0x83, 0x40, 0x00, 0x1C, 0x00, 0x5C, -0x00, 0x65, 0x70, 0x6B, 0x4C, 0xEB, 0x80, 0xF2, 0x16, 0x2B, 0xC0, 0xF2, -0x44, 0xA9, 0x06, 0x93, 0x53, 0xE3, 0x63, 0xEA, 0x07, 0xD4, 0x02, 0x61, -0x6B, 0xE2, 0x07, 0xD2, 0x07, 0x95, 0x03, 0x5D, 0x80, 0xF2, 0x0D, 0x60, -0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0xC9, 0xF7, 0x1B, 0x6C, -0x63, 0xF3, 0x00, 0x4A, 0x8B, 0xEC, 0x80, 0x34, 0xC0, 0xF2, 0xA4, 0xA2, -0x80, 0x34, 0x61, 0xF4, 0x03, 0x4C, 0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, -0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, 0x63, 0xF3, 0x00, 0x4D, -0x9D, 0x67, 0x62, 0x9D, 0x98, 0xA4, 0x3F, 0x6E, 0x24, 0x6A, 0xC0, 0xF2, -0x82, 0xC5, 0x83, 0x67, 0x62, 0x33, 0xCC, 0xEC, 0x62, 0x33, 0xCC, 0xEB, -0x93, 0xE2, 0x20, 0x6A, 0x7B, 0xE2, 0xC0, 0xF2, 0x43, 0xA5, 0x06, 0x95, -0x4F, 0xE5, 0x43, 0xED, 0x07, 0xD3, 0x02, 0x60, 0xAB, 0xE2, 0x07, 0xD2, -0x07, 0x95, 0x60, 0xF1, 0x1C, 0x25, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, -0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, 0xC0, 0xF2, 0x43, 0xA3, 0x06, 0x95, -0x43, 0xED, 0x16, 0x60, 0x07, 0x92, 0x24, 0x68, 0x83, 0xEA, 0x40, 0xF2, -0x18, 0x61, 0x07, 0x94, 0x20, 0x6D, 0x08, 0xD5, 0xC3, 0xEC, 0x24, 0x60, -0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, -0x45, 0xAA, 0x3F, 0x6B, 0x6C, 0xEA, 0x89, 0xE2, 0x08, 0xD2, 0x18, 0x10, -0x42, 0x9B, 0x3F, 0x6B, 0x6C, 0xEA, 0x07, 0x93, 0x43, 0xEB, 0x63, 0xE2, -0x01, 0x61, 0x00, 0x68, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, -0x63, 0xF3, 0x00, 0x4A, 0x45, 0xAA, 0x07, 0x94, 0x3F, 0x6B, 0x6C, 0xEA, -0x43, 0xEC, 0x8B, 0xE2, 0x08, 0xD2, 0x02, 0x61, 0x00, 0x6D, 0x08, 0xD5, -0x06, 0x6A, 0x03, 0xEA, 0x80, 0xF2, 0x06, 0x60, 0x10, 0xF0, 0x02, 0x6B, -0x00, 0xF4, 0x60, 0x33, 0x08, 0x32, 0x63, 0xF3, 0x00, 0x4B, 0x69, 0xE2, -0xA6, 0x9A, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, -0x00, 0x4B, 0xC3, 0x9B, 0xE0, 0xF3, 0x1F, 0x6F, 0x80, 0xF5, 0xA2, 0x35, -0x86, 0x67, 0xEC, 0xEC, 0x40, 0xF2, 0x17, 0x24, 0x00, 0xF2, 0x00, 0x68, -0x44, 0x67, 0x0C, 0xEA, 0x04, 0x22, 0x00, 0xF4, 0x00, 0x6A, 0x4B, 0xEA, -0x4D, 0xEC, 0xB8, 0xEC, 0xC2, 0x33, 0x6A, 0x33, 0xEC, 0xEB, 0x12, 0xEA, -0x42, 0x34, 0x43, 0x67, 0x0C, 0xEA, 0xEC, 0xEC, 0x04, 0x22, 0x00, 0xF4, -0x00, 0x6A, 0x4B, 0xEA, 0x4D, 0xEB, 0xB8, 0xEB, 0xC9, 0xF7, 0x1B, 0x68, -0x0B, 0xE8, 0x80, 0xF5, 0xA0, 0x35, 0x00, 0x30, 0x00, 0x30, 0x12, 0xEA, -0x42, 0x31, 0xEC, 0xE9, 0x3F, 0x6A, 0x2C, 0xEA, 0x40, 0x32, 0x40, 0x32, -0x4D, 0xED, 0x8D, 0xED, 0x81, 0xF4, 0x80, 0x40, 0x00, 0x1C, 0xDD, 0x5B, -0x04, 0xD5, 0x91, 0xF4, 0x84, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, -0x02, 0xF0, 0x00, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0xFF, 0x4D, 0x4C, 0xED, -0xC0, 0xF3, 0x00, 0x6A, 0x4C, 0xE9, 0x80, 0xF5, 0x20, 0x32, 0x4D, 0xED, -0x04, 0xD5, 0x91, 0xF4, 0x84, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, -0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, -0x42, 0x9B, 0xC0, 0xF7, 0x42, 0x32, 0xC0, 0xF1, 0x0A, 0x2A, 0x08, 0x94, -0xC9, 0xF7, 0x1B, 0x68, 0x0B, 0xE8, 0x8C, 0x32, 0x65, 0xE2, 0xA0, 0xF0, -0xAC, 0xA1, 0x00, 0x30, 0x00, 0x30, 0x21, 0xF2, 0x82, 0x40, 0x00, 0x1C, -0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF0, 0xAD, 0xA1, 0x21, 0xF2, 0x83, 0x40, -0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF0, 0xAE, 0xA1, 0x21, 0xF2, -0x84, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF0, 0xAF, 0xA1, -0x21, 0xF2, 0x85, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF0, -0xB0, 0xA1, 0x21, 0xF2, 0x86, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, -0xA0, 0xF0, 0xB1, 0xA1, 0x21, 0xF2, 0x87, 0x40, 0x00, 0x1C, 0xF0, 0x5B, -0x00, 0x65, 0xA0, 0xF0, 0xB2, 0xA1, 0x21, 0xF2, 0x88, 0x40, 0x00, 0x1C, -0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF0, 0xB3, 0xA1, 0x21, 0xF2, 0x89, 0x40, -0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, -0x40, 0x32, 0xCB, 0xF4, 0x46, 0xA2, 0x22, 0x72, 0x03, 0x60, 0x92, 0x72, -0x80, 0xF0, 0x0D, 0x61, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, -0x63, 0xF3, 0x00, 0x4A, 0x42, 0x9A, 0x3F, 0x6B, 0x42, 0x32, 0x6C, 0xEA, -0x24, 0x6B, 0x53, 0xE3, 0x07, 0x92, 0x01, 0x6B, 0x6E, 0xEA, 0x6C, 0xEA, -0x00, 0xF2, 0x0F, 0x22, 0x07, 0x95, 0xA6, 0x33, 0x64, 0x32, 0x69, 0xE2, -0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x07, 0xD2, 0x63, 0xF3, -0x00, 0x4B, 0xC0, 0xF2, 0x43, 0xA3, 0x06, 0x95, 0x43, 0xED, 0xA0, 0xF1, -0x19, 0x60, 0x07, 0x92, 0x24, 0x68, 0x83, 0xEA, 0x06, 0x60, 0x42, 0x9B, -0x3F, 0x6B, 0x42, 0x32, 0x6C, 0xEA, 0x07, 0x93, 0x61, 0xE2, 0x06, 0x6D, -0x03, 0xED, 0xA0, 0xF1, 0x16, 0x60, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, -0x60, 0x33, 0x08, 0x32, 0x63, 0xF3, 0x00, 0x4B, 0x69, 0xE2, 0xA6, 0x9A, -0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x63, 0xF3, 0x00, 0x4B, -0xC4, 0x9B, 0xE0, 0xF3, 0x1F, 0x6F, 0x80, 0xF5, 0xA2, 0x35, 0xC2, 0x34, -0x8A, 0x34, 0xEC, 0xEC, 0xA0, 0xF1, 0x1E, 0x24, 0x00, 0xF2, 0x00, 0x68, -0x44, 0x67, 0x0C, 0xEA, 0x04, 0x22, 0x00, 0xF4, 0x00, 0x6A, 0x4B, 0xEA, -0x4D, 0xEC, 0xB8, 0xEC, 0x00, 0xF5, 0xC2, 0x33, 0xEC, 0xEB, 0x12, 0xEA, -0x42, 0x34, 0x43, 0x67, 0x0C, 0xEA, 0xEC, 0xEC, 0x04, 0x22, 0x00, 0xF4, -0x00, 0x6A, 0x4B, 0xEA, 0x4D, 0xEB, 0xB8, 0xEB, 0xC9, 0xF7, 0x1B, 0x68, -0x0B, 0xE8, 0x80, 0xF5, 0xA0, 0x35, 0x00, 0x30, 0x00, 0x30, 0x12, 0xEA, -0x42, 0x31, 0xEC, 0xE9, 0x3F, 0x6A, 0x2C, 0xEA, 0x40, 0x32, 0x40, 0x32, -0x4D, 0xED, 0x8D, 0xED, 0x81, 0xF4, 0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B, -0x04, 0xD5, 0x91, 0xF4, 0x8C, 0x40, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, -0x02, 0xF0, 0x00, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0xFF, 0x4D, 0x4C, 0xED, -0xC0, 0xF3, 0x00, 0x6A, 0x4C, 0xE9, 0x80, 0xF5, 0x20, 0x32, 0x4D, 0xED, -0x91, 0xF4, 0x8C, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x04, 0xD5, 0x0E, 0x97, -0x0D, 0x91, 0x0C, 0x90, 0x00, 0x6A, 0x00, 0xEF, 0x08, 0x63, 0xC9, 0xF7, -0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x81, 0xF4, 0x00, 0x4C, -0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x08, 0xF0, 0x00, 0x6B, 0x6B, 0xEB, -0x60, 0x33, 0xA2, 0x67, 0x6C, 0xED, 0xD1, 0x67, 0x03, 0x10, 0x01, 0x48, -0x25, 0x58, 0x0E, 0x60, 0x08, 0x32, 0xC9, 0xE2, 0x46, 0x9A, 0x6C, 0xEA, -0xAE, 0xEA, 0xF7, 0x2A, 0x62, 0x9E, 0x40, 0x6C, 0x3F, 0x6A, 0x8B, 0xEC, -0x0C, 0xEA, 0x8C, 0xEB, 0x4D, 0xEB, 0x62, 0xDE, 0x10, 0xF0, 0x02, 0x6A, -0x00, 0xF4, 0x40, 0x32, 0xCB, 0xF4, 0x46, 0xA2, 0x22, 0x72, 0x02, 0x60, -0x92, 0x72, 0x2A, 0x61, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, -0x80, 0x34, 0x81, 0xF4, 0x08, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x68, -0x08, 0xF0, 0x00, 0x6B, 0x6B, 0xEB, 0x60, 0x33, 0xA2, 0x67, 0x10, 0xF0, -0x02, 0x6E, 0x00, 0xF4, 0xC0, 0x36, 0x6C, 0xED, 0x63, 0xF3, 0x00, 0x4E, -0x03, 0x10, 0x01, 0x48, 0x25, 0x58, 0x10, 0x60, 0x08, 0x32, 0xC9, 0xE2, -0x46, 0x9A, 0x6C, 0xEA, 0xAE, 0xEA, 0xF7, 0x2A, 0x62, 0x9E, 0x3F, 0x6A, -0x07, 0xF7, 0x01, 0x6C, 0x0C, 0xEA, 0x8B, 0xEC, 0x40, 0x32, 0x8C, 0xEB, -0x4D, 0xEB, 0x62, 0xDE, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, -0x80, 0x34, 0x21, 0xF2, 0x04, 0x4C, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x68, -0x27, 0xF7, 0x1F, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x27, 0xF7, 0x1F, 0x4B, -0x4C, 0xEB, 0x04, 0xD3, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, -0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x03, 0xF4, 0x0E, 0x4A, -0x03, 0xF5, 0x16, 0x4B, 0x09, 0xD2, 0x0A, 0xD3, 0x0C, 0x10, 0x0A, 0x93, -0x9D, 0x67, 0x10, 0x4C, 0x75, 0xE1, 0x00, 0x1C, 0x1D, 0x55, 0x04, 0x6E, -0xC0, 0xF0, 0x1B, 0x22, 0x01, 0x48, 0x21, 0x58, 0x22, 0x60, 0x09, 0x92, -0x0C, 0x31, 0x9D, 0x67, 0x10, 0x4C, 0x55, 0xE1, 0x00, 0x1C, 0x1D, 0x55, -0x04, 0x6E, 0xEB, 0x2A, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, -0x63, 0xF3, 0x00, 0x4D, 0x07, 0xF7, 0x00, 0x6A, 0x62, 0x9D, 0x4B, 0xEA, -0x40, 0x32, 0xFF, 0x4A, 0x3F, 0x6C, 0x4C, 0xEB, 0x0C, 0xEC, 0x10, 0xF0, -0x00, 0x6A, 0x80, 0x34, 0x40, 0x32, 0x80, 0x34, 0x40, 0x32, 0x8D, 0xEB, -0xFF, 0x4A, 0x4C, 0xEB, 0x62, 0xDD, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, -0x80, 0x34, 0x63, 0xF3, 0x00, 0x4C, 0x63, 0x9C, 0x08, 0xF0, 0x00, 0x6A, -0x40, 0x32, 0x40, 0x32, 0x4D, 0xEB, 0x63, 0xDC, 0x45, 0x15, 0x02, 0xF0, -0x00, 0x68, 0x00, 0x30, 0x60, 0x6E, 0xAF, 0x40, 0x00, 0x1C, 0x83, 0x45, -0x24, 0x6C, 0xE0, 0xF3, 0x08, 0x6C, 0x00, 0x1C, 0x2C, 0x1F, 0x00, 0x65, -0x9D, 0x67, 0x00, 0x1C, 0x8A, 0x40, 0x14, 0x4C, 0xAF, 0x40, 0x00, 0x1C, -0xAC, 0x45, 0x24, 0x6C, 0x1F, 0x6C, 0x4C, 0xEC, 0x06, 0xD4, 0x9D, 0x67, -0x00, 0x1C, 0x90, 0x40, 0x14, 0x4C, 0x00, 0x1C, 0x5B, 0x1F, 0x64, 0x6C, -0x4C, 0x15, 0x61, 0xF4, 0x83, 0x40, 0xCC, 0x6D, 0x82, 0x15, 0x00, 0x18, -0xA4, 0x5E, 0x00, 0x65, 0x7D, 0x67, 0x6C, 0xAB, 0x10, 0xF0, 0x02, 0x6A, -0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, 0xC0, 0xF2, 0x64, 0xCA, -0x65, 0x15, 0x42, 0x9B, 0x3F, 0x6B, 0x6C, 0xEA, 0x07, 0x93, 0x61, 0xE2, -0xA2, 0x15, 0x08, 0x95, 0xC9, 0xF7, 0x1B, 0x68, 0x0B, 0xE8, 0xAC, 0x32, -0x65, 0xE2, 0xA0, 0xF1, 0xB4, 0xA1, 0x00, 0x30, 0x00, 0x30, 0x21, 0xF2, -0x82, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF1, 0xB5, 0xA1, -0x21, 0xF2, 0x83, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF1, -0xB6, 0xA1, 0x21, 0xF2, 0x84, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, -0xA0, 0xF1, 0xB7, 0xA1, 0x21, 0xF2, 0x85, 0x40, 0x00, 0x1C, 0xF0, 0x5B, -0x00, 0x65, 0xA0, 0xF1, 0xB8, 0xA1, 0x21, 0xF2, 0x86, 0x40, 0x00, 0x1C, -0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF1, 0xB9, 0xA1, 0x21, 0xF2, 0x87, 0x40, -0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF1, 0xBA, 0xA1, 0x21, 0xF2, -0x88, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x00, 0x65, 0xA0, 0xF1, 0xBB, 0xA1, -0x21, 0xF2, 0x89, 0x40, 0x35, 0x16, 0x6A, 0x60, 0x08, 0x32, 0xC9, 0xF7, -0x1B, 0x6C, 0x69, 0xE2, 0x8B, 0xEC, 0x80, 0x34, 0xA6, 0x9A, 0x80, 0x34, -0x81, 0xF4, 0x00, 0x4C, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xC9, 0xF7, -0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x81, 0xF4, 0x14, 0x4C, -0x00, 0x6D, 0xD3, 0x15, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, -0x63, 0xF3, 0x00, 0x4A, 0xAC, 0x9A, 0x7B, 0x15, 0x42, 0x9B, 0x07, 0x94, -0x3F, 0x6B, 0x42, 0x32, 0x6C, 0xEA, 0x43, 0xEC, 0x83, 0xE2, 0x5F, 0xF6, -0x08, 0x61, 0x00, 0x68, 0x18, 0x65, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, -0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, 0xAC, 0x9A, 0x4B, 0x16, 0x10, 0xF0, -0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, 0x63, 0xF3, 0x00, 0x4D, 0x07, 0xF7, -0x00, 0x6A, 0x62, 0x9D, 0x4B, 0xEA, 0x3F, 0x6C, 0x40, 0x32, 0xFF, 0x4A, -0x0C, 0xEC, 0x4C, 0xEB, 0x80, 0x34, 0x10, 0xF0, 0x00, 0x6A, 0x4B, 0xEA, -0x80, 0x34, 0x40, 0x32, 0x8D, 0xEB, 0x40, 0x32, 0x4D, 0xEB, 0x30, 0x17, -0x28, 0x60, 0x08, 0x32, 0xC9, 0xF7, 0x1B, 0x6C, 0x69, 0xE2, 0x8B, 0xEC, -0x80, 0x34, 0xA6, 0x9A, 0x80, 0x34, 0x81, 0xF4, 0x08, 0x4C, 0x00, 0x1C, -0xDD, 0x5B, 0x00, 0x65, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, -0x80, 0x34, 0x81, 0xF4, 0x1C, 0x4C, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x6D, -0x6C, 0x16, 0x07, 0x93, 0xFF, 0x4B, 0x66, 0x33, 0x64, 0x32, 0x69, 0xE2, -0x01, 0x4A, 0xEE, 0x15, 0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, -0xAC, 0x9B, 0x80, 0x34, 0x81, 0xF4, 0x00, 0x4C, 0x97, 0x17, 0xC9, 0xF7, -0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0xAC, 0x9B, 0x80, 0x34, 0x81, 0xF4, -0x08, 0x4C, 0xD9, 0x17, 0x82, 0x34, 0x1F, 0xF7, 0x00, 0x6A, 0x4C, 0xEC, -0x82, 0x35, 0x20, 0x5D, 0x1B, 0x60, 0xAC, 0x32, 0xA9, 0xE2, 0x48, 0x32, -0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0xA9, 0xE2, 0x63, 0xF3, -0x00, 0x4B, 0x48, 0x32, 0x69, 0xE2, 0xE4, 0xF4, 0x58, 0x9A, 0xC9, 0xF7, -0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x52, 0x32, 0x7F, 0x6B, -0x60, 0xF3, 0x14, 0x4C, 0x6C, 0xEA, 0x40, 0xDC, 0x20, 0xE8, 0x00, 0x65, -0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0xCA, 0xF2, 0x4C, 0x9A, -0xC9, 0xF7, 0x1B, 0x6C, 0x8B, 0xEC, 0x80, 0x34, 0x80, 0x34, 0x52, 0x32, -0x7F, 0x6B, 0x60, 0xF3, 0x14, 0x4C, 0x6C, 0xEA, 0x40, 0xDC, 0x20, 0xE8, -0x00, 0x65, 0x00, 0x00, 0xFC, 0x63, 0x04, 0xD0, 0xC9, 0xF7, 0x1B, 0x68, -0x0B, 0xE8, 0x00, 0x30, 0x00, 0x30, 0x01, 0xF5, 0x83, 0x40, 0x06, 0x62, -0x00, 0x1C, 0x00, 0x5C, 0x05, 0xD1, 0x08, 0x6D, 0x4D, 0xED, 0xFF, 0x69, -0x01, 0xF5, 0x83, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x2C, 0xED, 0x01, 0xF5, -0x83, 0x40, 0x00, 0x1C, 0x00, 0x5C, 0x00, 0x65, 0xA2, 0x67, 0xF7, 0x6B, -0x01, 0xF5, 0x83, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x6C, 0xED, 0x21, 0xF2, -0x8D, 0x40, 0x00, 0x1C, 0x00, 0x5C, 0x00, 0x65, 0xA2, 0x67, 0x3F, 0x6B, -0x21, 0xF2, 0x8D, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x6C, 0xED, 0x21, 0xF2, -0x8D, 0x40, 0x00, 0x1C, 0x00, 0x5C, 0x00, 0x65, 0x80, 0x6D, 0xAB, 0xED, -0x4D, 0xED, 0x21, 0xF2, 0x8D, 0x40, 0x00, 0x1C, 0xF0, 0x5B, 0x2C, 0xED, -0x06, 0x97, 0x05, 0x91, 0x04, 0x90, 0x00, 0xEF, 0x04, 0x63, 0x00, 0x65, -0x00, 0x1C, 0x2A, 0x61, 0x00, 0x65, 0x00, 0x65, 0x00, 0x1C, 0x2C, 0x61, -0x00, 0x65, 0x00, 0x65, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0x40, 0x32, -0x40, 0x32, 0x30, 0xF2, 0x63, 0x42, 0x90, 0x34, 0x80, 0xC3, 0x20, 0xF2, -0x10, 0x4A, 0x40, 0x9A, 0x02, 0xF0, 0x00, 0x6B, 0x60, 0x33, 0xFF, 0x4B, -0x20, 0xE8, 0x6C, 0xEA, 0xC9, 0xF7, 0x1B, 0x6A, 0x4B, 0xEA, 0xFF, 0x6D, -0x40, 0x32, 0x8C, 0xED, 0x40, 0x32, 0x30, 0xF2, 0x83, 0x42, 0xB0, 0x33, -0x60, 0xC4, 0x20, 0xF2, 0x10, 0x4A, 0x60, 0x9A, 0x02, 0xF0, 0x00, 0x6A, -0x40, 0x32, 0xFF, 0x4A, 0x4C, 0xEB, 0x83, 0x67, 0x05, 0x23, 0x01, 0x6C, -0x84, 0xED, 0xFF, 0xF7, 0x1F, 0x6A, 0x4C, 0xEC, 0x20, 0xE8, 0x44, 0x67, -0xC9, 0xF7, 0x1B, 0x6A, 0xFB, 0x63, 0x4B, 0xEA, 0x07, 0xD1, 0x40, 0x31, -0x08, 0x62, 0x06, 0xD0, 0x20, 0x31, 0x40, 0xF0, 0x4C, 0xA1, 0xFF, 0x6C, -0x8C, 0xEA, 0x02, 0x72, 0x14, 0x61, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, -0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, 0x04, 0xD2, 0x66, 0xF7, 0x56, 0xAA, -0x01, 0x72, 0x09, 0x61, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, -0xEB, 0xF5, 0x4C, 0xA2, 0x04, 0x67, 0x4C, 0xE8, 0x05, 0x20, 0x08, 0x97, -0x07, 0x91, 0x06, 0x90, 0x00, 0xEF, 0x05, 0x63, 0x00, 0x18, 0x2C, 0x61, -0x04, 0x6C, 0x04, 0x94, 0x08, 0xF0, 0x64, 0x9C, 0x4D, 0xE3, 0x08, 0xF0, -0x64, 0xDC, 0x00, 0x18, 0x2C, 0x61, 0x06, 0x6C, 0x04, 0x94, 0x08, 0xF0, -0x68, 0x9C, 0x4D, 0xE3, 0x08, 0xF0, 0x68, 0xDC, 0x00, 0x18, 0x2C, 0x61, -0x07, 0x6C, 0x04, 0x94, 0x08, 0xF0, 0x6C, 0x9C, 0x4D, 0xE3, 0x08, 0xF0, -0x6C, 0xDC, 0x00, 0x18, 0x2C, 0x61, 0x05, 0x6C, 0x04, 0x94, 0x08, 0xF0, -0x70, 0x9C, 0x4D, 0xE3, 0x08, 0xF0, 0x70, 0xDC, 0x00, 0x18, 0x35, 0x61, -0x90, 0x67, 0x04, 0x6C, 0x00, 0x18, 0x35, 0x61, 0x02, 0x67, 0x4D, 0xE8, -0xFF, 0xF7, 0x1F, 0x6A, 0x4C, 0xE8, 0x30, 0xF2, 0x63, 0x41, 0x08, 0x6A, -0x40, 0xC3, 0xC7, 0x28, 0x40, 0xF0, 0x40, 0xA9, 0xFF, 0xF7, 0x1F, 0x6B, -0x6C, 0xEA, 0xFB, 0xF7, 0x1F, 0x6B, 0x6C, 0xEA, 0x04, 0xF0, 0x00, 0x6B, -0x40, 0xF0, 0x40, 0xC9, 0x6D, 0xEA, 0x40, 0xF0, 0x40, 0xC9, 0x04, 0x94, -0xFF, 0xF7, 0x1F, 0x6A, 0x66, 0xF7, 0xB4, 0xAC, 0x01, 0x4D, 0x66, 0xF7, -0xB4, 0xCC, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x7E, 0xF2, -0x08, 0x4C, 0x00, 0x1C, 0x13, 0x58, 0x4C, 0xED, 0xA6, 0x17, 0x00, 0x65, -0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF, 0x85, 0x2B, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xBF, 0x8F, 0x02, 0x80, 0x02, 0x3C, -0xE8, 0x03, 0x03, 0x24, 0x2C, 0x5E, 0x43, 0xAC, 0x18, 0x00, 0xBD, 0x27, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C, -0x02, 0x80, 0x03, 0x3C, 0x0B, 0x5E, 0x40, 0xA0, 0xFF, 0x00, 0x85, 0x30, -0xF2, 0x5D, 0x60, 0xA0, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, -0x05, 0x5E, 0x40, 0xA0, 0x08, 0x00, 0xA4, 0x2C, 0x07, 0x5E, 0x60, 0xA0, -0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0x0F, 0x5E, 0x40, 0xA0, -0xEC, 0x5D, 0x65, 0xA0, 0x2C, 0x00, 0x80, 0x10, 0x02, 0x80, 0x03, 0x3C, -0x80, 0x10, 0x05, 0x00, 0x78, 0xF2, 0x63, 0x24, 0x21, 0x10, 0x43, 0x00, -0x00, 0x00, 0x44, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x80, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x05, 0x3C, 0x60, 0x1B, 0xA5, 0x24, -0xD0, 0x1B, 0xA4, 0x8C, 0x00, 0x70, 0x02, 0x3C, 0x02, 0x00, 0x42, 0x34, -0x25, 0x20, 0x82, 0x00, 0x41, 0xB0, 0x03, 0x3C, 0x00, 0x00, 0x64, 0xAC, -0x08, 0x00, 0xE0, 0x03, 0xD0, 0x1B, 0xA4, 0xAC, 0x02, 0x80, 0x05, 0x3C, -0x60, 0x1B, 0xA5, 0x24, 0xD0, 0x1B, 0xA4, 0x8C, 0x00, 0x70, 0x02, 0x3C, -0x02, 0x00, 0x42, 0x34, 0x27, 0x10, 0x02, 0x00, 0x24, 0x20, 0x82, 0x00, -0x41, 0xB0, 0x03, 0x3C, 0x00, 0x00, 0x64, 0xAC, 0x08, 0x00, 0xE0, 0x03, -0xD0, 0x1B, 0xA4, 0xAC, 0x02, 0x80, 0x05, 0x3C, 0x60, 0x1B, 0xA5, 0x24, -0xD0, 0x1B, 0xA4, 0x8C, 0x00, 0x70, 0x02, 0x3C, 0x27, 0x10, 0x02, 0x00, -0x24, 0x20, 0x82, 0x00, 0x02, 0x80, 0x07, 0x3C, 0x41, 0xB0, 0x02, 0x3C, -0x01, 0x00, 0x03, 0x24, 0x00, 0x00, 0x44, 0xAC, 0x09, 0x5E, 0xE3, 0xA0, -0x09, 0x5E, 0xE6, 0x90, 0x02, 0x80, 0x02, 0x3C, 0xD0, 0x1B, 0xA4, 0xAC, -0x0A, 0x5E, 0x46, 0xA0, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0x02, 0x80, 0x05, 0x3C, 0x60, 0x1B, 0xA5, 0x24, 0xD0, 0x1B, 0xA4, 0x8C, -0x00, 0x70, 0x02, 0x3C, 0x27, 0x10, 0x02, 0x00, 0x24, 0x20, 0x82, 0x00, -0x41, 0xB0, 0x03, 0x3C, 0x00, 0x00, 0x64, 0xAC, 0x08, 0x00, 0xE0, 0x03, -0xD0, 0x1B, 0xA4, 0xAC, 0xE0, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, -0x02, 0x80, 0x10, 0x3C, 0xEC, 0x5D, 0x02, 0x92, 0x18, 0x00, 0xB2, 0xAF, -0x14, 0x00, 0xB1, 0xAF, 0x1C, 0x00, 0xBF, 0xAF, 0x21, 0x90, 0x80, 0x00, -0x1C, 0x00, 0x40, 0x10, 0xFF, 0x00, 0xB1, 0x30, 0x02, 0x80, 0x03, 0x3C, -0xC6, 0x5C, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x30, -0x1C, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x24, -0x00, 0x02, 0x05, 0x3C, 0xC1, 0x43, 0x00, 0x0C, 0x01, 0x00, 0x06, 0x24, -0x02, 0x80, 0x03, 0x3C, 0xEE, 0x5D, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, -0x0F, 0x00, 0x42, 0x30, 0x0C, 0x00, 0x42, 0x28, 0x06, 0x00, 0x40, 0x10, -0x08, 0x00, 0x02, 0x24, 0x00, 0x00, 0x44, 0x96, 0x00, 0x00, 0x00, 0x00, -0x0C, 0x00, 0x83, 0x30, 0x1B, 0x00, 0x62, 0x10, 0x02, 0x80, 0x02, 0x3C, -0xEC, 0x5D, 0x02, 0x92, 0x05, 0x00, 0x03, 0x24, 0xFF, 0x00, 0x42, 0x30, -0x0B, 0x00, 0x43, 0x10, 0x02, 0x80, 0x03, 0x3C, 0x1C, 0x00, 0xBF, 0x8F, -0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, 0xA8, 0x2D, 0x00, 0x0C, -0x01, 0x00, 0x04, 0x24, 0xF1, 0x61, 0x00, 0x08, 0x00, 0x08, 0x04, 0x24, -0x08, 0x5E, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x24, 0x10, 0x22, 0x02, -0xF2, 0xFF, 0x40, 0x10, 0x02, 0x80, 0x03, 0x3C, 0x07, 0x5E, 0x62, 0x90, -0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x42, 0x34, 0x07, 0x5E, 0x62, 0xA0, -0x05, 0x62, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x06, 0x5E, 0x43, 0x90, -0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x60, 0x14, 0x00, 0x10, 0x82, 0x34, -0x00, 0x62, 0x00, 0x08, 0x00, 0x00, 0x42, 0xA6, 0x0C, 0x00, 0x04, 0x24, -0x4B, 0x2E, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, 0x00, 0x62, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF, -0x02, 0x80, 0x03, 0x3C, 0x0B, 0x5E, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, -0x10, 0x00, 0x40, 0x10, 0x02, 0x80, 0x04, 0x3C, 0x0B, 0x5E, 0x60, 0xA0, -0x02, 0x80, 0x04, 0x3C, 0x07, 0x5E, 0x83, 0x90, 0xFD, 0xFF, 0x02, 0x24, -0x24, 0x18, 0x62, 0x00, 0x07, 0x5E, 0x83, 0xA0, 0x07, 0x5E, 0x82, 0x90, -0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x42, 0x30, 0x49, 0x00, 0x40, 0x10, -0x02, 0x80, 0x02, 0x3C, 0x10, 0x00, 0xBF, 0x8F, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0xF2, 0x5D, 0x82, 0x90, -0x02, 0x80, 0x05, 0x3C, 0x01, 0x00, 0x42, 0x24, 0xF2, 0x5D, 0x82, 0xA0, -0x07, 0x5E, 0xA3, 0x90, 0xEF, 0xFF, 0x02, 0x24, 0x24, 0x18, 0x62, 0x00, -0x07, 0x5E, 0xA3, 0xA0, 0xF2, 0x5D, 0x82, 0x90, 0x00, 0x00, 0x00, 0x00, -0x02, 0x00, 0x42, 0x2C, 0x13, 0x00, 0x40, 0x14, 0x25, 0xB0, 0x06, 0x3C, -0x02, 0x80, 0x03, 0x3C, 0x10, 0x37, 0x62, 0x94, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x42, 0x30, 0x3A, 0x00, 0x40, 0x10, 0x02, 0x80, 0x02, 0x3C, -0x02, 0x80, 0x03, 0x3C, 0x0E, 0x5E, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, -0xE5, 0xFF, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x5E, 0x62, 0x90, -0x10, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xBD, 0x27, 0x01, 0x00, 0x42, 0x24, -0x0E, 0x5E, 0x62, 0xA0, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0x84, 0x00, 0xC4, 0x34, 0x80, 0x00, 0xC6, 0x34, 0x00, 0x00, 0x82, 0x8C, -0x00, 0x00, 0xC4, 0x8C, 0x02, 0x80, 0x08, 0x3C, 0x21, 0x10, 0x00, 0x00, -0x14, 0x5E, 0x06, 0x8D, 0x42, 0xB0, 0x0A, 0x3C, 0x25, 0x10, 0x44, 0x00, -0x02, 0x80, 0x04, 0x3C, 0x18, 0x5E, 0x88, 0x8C, 0x1C, 0x5E, 0x89, 0x8C, -0x00, 0x00, 0x45, 0x91, 0x21, 0x10, 0x46, 0x00, 0xFB, 0xFF, 0x04, 0x24, -0x24, 0x28, 0xA4, 0x00, 0x23, 0x40, 0x02, 0x01, 0x00, 0x00, 0x45, 0xA1, -0x04, 0x00, 0x00, 0x11, 0x01, 0x00, 0x06, 0x24, 0x80, 0x10, 0x08, 0x00, -0x21, 0x10, 0x48, 0x00, 0x80, 0x30, 0x02, 0x00, 0x01, 0x00, 0x04, 0x24, -0xB9, 0x20, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, 0x42, 0xB0, 0x02, 0x3C, -0x22, 0x00, 0x04, 0x24, 0x03, 0x00, 0x42, 0x34, 0x00, 0x00, 0x44, 0xA0, -0x02, 0x80, 0x03, 0x3C, 0xED, 0x5D, 0x64, 0x90, 0x10, 0x00, 0xBF, 0x8F, -0x01, 0x00, 0x05, 0x24, 0xFF, 0x00, 0x84, 0x30, 0x4B, 0x2E, 0x00, 0x08, -0x18, 0x00, 0xBD, 0x27, 0x05, 0x5E, 0x40, 0xA0, 0x02, 0x80, 0x03, 0x3C, -0xED, 0x5D, 0x64, 0x90, 0x10, 0x00, 0xBF, 0x8F, 0x01, 0x00, 0x05, 0x24, -0xFF, 0x00, 0x84, 0x30, 0x4B, 0x2E, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, -0x10, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xBD, 0x27, 0x0E, 0x5E, 0x40, 0xA0, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27, -0xFF, 0x00, 0xA5, 0x30, 0x10, 0x00, 0xB0, 0xAF, 0x14, 0x00, 0xBF, 0xAF, -0x18, 0x00, 0xA0, 0x14, 0xFF, 0x00, 0x90, 0x30, 0x35, 0x00, 0x00, 0x12, -0x01, 0x00, 0x05, 0x24, 0x02, 0x80, 0x02, 0x3C, 0x01, 0x00, 0x05, 0x24, -0x05, 0x5E, 0x45, 0xA0, 0x02, 0x80, 0x07, 0x3C, 0x07, 0x5E, 0xE3, 0x90, -0x02, 0x00, 0x04, 0x24, 0x21, 0x28, 0x00, 0x00, 0x02, 0x00, 0x63, 0x34, -0x00, 0xF0, 0x06, 0x34, 0x07, 0x5E, 0xE3, 0xA0, 0xB9, 0x20, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x42, 0xB0, 0x02, 0x3C, 0x44, 0x00, 0x03, 0x24, 0x03, 0x00, 0x42, 0x34, -0x18, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x43, 0xA0, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x24, 0x02, 0x80, 0x02, 0x3C, -0x05, 0x5E, 0x44, 0xA0, 0x02, 0x80, 0x03, 0x3C, 0x08, 0x5E, 0x65, 0x90, -0x0F, 0x00, 0x02, 0x24, 0x02, 0x80, 0x06, 0x3C, 0x0F, 0x00, 0xA5, 0x30, -0x0D, 0x00, 0xA2, 0x10, 0x01, 0x00, 0x04, 0x24, 0x07, 0x5E, 0xC2, 0x90, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x34, 0x07, 0x5E, 0xC2, 0xA0, -0xE1, 0x51, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xDB, 0xFF, 0x00, 0x16, -0x02, 0x80, 0x02, 0x3C, 0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x18, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, -0x04, 0x5E, 0x43, 0x90, 0x01, 0x00, 0x04, 0x24, 0xF6, 0xFF, 0x60, 0x10, -0x01, 0x00, 0x05, 0x24, 0xC8, 0x51, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0xB9, 0x62, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C, -0x05, 0x5E, 0x40, 0xA0, 0x02, 0x80, 0x03, 0x3C, 0xED, 0x5D, 0x64, 0x90, -0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0xFF, 0x00, 0x84, 0x30, -0x4B, 0x2E, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27, -0xFF, 0x00, 0xA5, 0x30, 0x14, 0x00, 0xB1, 0xAF, 0x18, 0x00, 0xBF, 0xAF, -0x10, 0x00, 0xB0, 0xAF, 0x03, 0x00, 0xA0, 0x14, 0xFF, 0x00, 0x91, 0x30, -0x3A, 0x00, 0x20, 0x12, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x10, 0x3C, -0x07, 0x5E, 0x02, 0x92, 0xFB, 0xFF, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, -0x07, 0x5E, 0x02, 0xA2, 0x10, 0x00, 0xA0, 0x14, 0x02, 0x80, 0x03, 0x3C, -0x07, 0x5E, 0x02, 0x92, 0xFE, 0xFF, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, -0x07, 0x5E, 0x02, 0xA2, 0x19, 0x00, 0x20, 0x16, 0x02, 0x80, 0x02, 0x3C, -0x07, 0x5E, 0x02, 0x92, 0xFD, 0xFF, 0x03, 0x24, 0x18, 0x00, 0xBF, 0x8F, -0x24, 0x10, 0x43, 0x00, 0x07, 0x5E, 0x02, 0xA2, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0x01, 0x00, 0x04, 0x24, 0x05, 0x5E, 0x64, 0xA0, 0x07, 0x5E, 0x02, 0x92, -0x02, 0x80, 0x03, 0x3C, 0x01, 0x00, 0x42, 0x34, 0x07, 0x5E, 0x02, 0xA2, -0x06, 0x5E, 0x62, 0x90, 0x02, 0x00, 0x03, 0x24, 0xFF, 0x00, 0x42, 0x30, -0x23, 0x00, 0x43, 0x10, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x51, 0x00, 0x0C, -0x01, 0x00, 0x04, 0x24, 0xE9, 0xFF, 0x20, 0x12, 0x02, 0x80, 0x02, 0x3C, -0x01, 0x00, 0x04, 0x24, 0x05, 0x5E, 0x44, 0xA0, 0x07, 0x5E, 0x03, 0x92, -0x02, 0x00, 0x04, 0x24, 0x21, 0x28, 0x00, 0x00, 0x02, 0x00, 0x63, 0x34, -0x00, 0xF0, 0x06, 0x34, 0x07, 0x5E, 0x03, 0xA2, 0xB9, 0x20, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xBF, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x42, 0xB0, 0x02, 0x3C, 0x44, 0x00, 0x03, 0x24, -0x03, 0x00, 0x42, 0x34, 0x20, 0x00, 0xBD, 0x27, 0x00, 0x00, 0x43, 0xA0, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5E, 0x40, 0xA0, -0x02, 0x80, 0x03, 0x3C, 0xED, 0x5D, 0x64, 0x90, 0x18, 0x00, 0xBF, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x01, 0x00, 0x05, 0x24, -0xFF, 0x00, 0x84, 0x30, 0x4B, 0x2E, 0x00, 0x08, 0x20, 0x00, 0xBD, 0x27, -0xE2, 0x2C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x04, 0x24, -0x4B, 0x2E, 0x00, 0x0C, 0x01, 0x00, 0x05, 0x24, 0xE5, 0x62, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB2, 0xAF, -0x0C, 0x00, 0xB1, 0xAF, 0x08, 0x00, 0xB0, 0xAF, 0x21, 0x40, 0xE0, 0x00, -0x21, 0x90, 0xA0, 0x03, 0x21, 0x60, 0xC0, 0x00, 0x21, 0x78, 0x80, 0x00, -0x45, 0x00, 0xE0, 0x14, 0x21, 0x50, 0xA0, 0x00, 0x2B, 0x10, 0xA6, 0x00, -0x78, 0x00, 0x40, 0x10, 0xFF, 0xFF, 0x02, 0x34, 0x2B, 0x10, 0x46, 0x00, -0x8F, 0x01, 0x40, 0x10, 0x21, 0x28, 0xC0, 0x00, 0xFF, 0x00, 0x02, 0x3C, -0xFF, 0xFF, 0x42, 0x34, 0x10, 0x00, 0x03, 0x24, 0x2B, 0x10, 0x46, 0x00, -0x18, 0x00, 0x04, 0x24, 0x21, 0x30, 0x60, 0x00, 0x0B, 0x30, 0x82, 0x00, -0x02, 0x80, 0x03, 0x3C, 0x06, 0x10, 0xC5, 0x00, 0x98, 0xF2, 0x63, 0x24, -0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x44, 0x90, 0x20, 0x00, 0x02, 0x24, -0x21, 0x20, 0x86, 0x00, 0x23, 0x30, 0x44, 0x00, 0x08, 0x00, 0xC0, 0x10, -0x02, 0x4C, 0x0C, 0x00, 0x23, 0x10, 0x46, 0x00, 0x06, 0x10, 0x4F, 0x00, -0x04, 0x18, 0xCA, 0x00, 0x25, 0x50, 0x62, 0x00, 0x04, 0x60, 0xCC, 0x00, -0x04, 0x78, 0xCF, 0x00, 0x02, 0x4C, 0x0C, 0x00, 0x1B, 0x00, 0x49, 0x01, -0x02, 0x00, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00, -0xFF, 0xFF, 0x87, 0x31, 0x02, 0x24, 0x0F, 0x00, 0x12, 0x18, 0x00, 0x00, -0x10, 0x28, 0x00, 0x00, 0x00, 0x14, 0x05, 0x00, 0x25, 0x28, 0x44, 0x00, -0x18, 0x00, 0x67, 0x00, 0x12, 0x58, 0x00, 0x00, 0x2B, 0x18, 0xAB, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x49, 0x01, 0x02, 0x00, 0x20, 0x15, -0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00, 0x08, 0x00, 0x60, 0x10, -0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0xAC, 0x00, 0x2B, 0x10, 0xAC, 0x00, -0x04, 0x00, 0x40, 0x14, 0x2B, 0x10, 0xAB, 0x00, 0x00, 0x00, 0x42, 0x38, -0x21, 0x18, 0xAC, 0x00, 0x0B, 0x28, 0x62, 0x00, 0x23, 0x28, 0xAB, 0x00, -0x1B, 0x00, 0xA9, 0x00, 0x02, 0x00, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00, -0x0D, 0x00, 0x07, 0x00, 0xFF, 0xFF, 0xE4, 0x31, 0x12, 0x18, 0x00, 0x00, -0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x63, 0x00, 0x08, -0x18, 0x00, 0x67, 0x00, 0x2B, 0x10, 0xA7, 0x00, 0x0A, 0x00, 0x40, 0x10, -0xFF, 0xFF, 0x02, 0x34, 0x10, 0x00, 0xB2, 0x8F, 0x0C, 0x00, 0xB1, 0x8F, -0x08, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x80, 0x00, 0x21, 0x18, 0xA0, 0x00, -0x00, 0x00, 0xA4, 0xAF, 0x04, 0x00, 0xA5, 0xAF, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0x2B, 0x10, 0x47, 0x00, 0xD2, 0x00, 0x40, 0x10, -0x00, 0x01, 0xE3, 0x2C, 0xFF, 0x00, 0x02, 0x3C, 0x10, 0x00, 0x03, 0x24, -0xFF, 0xFF, 0x42, 0x34, 0x2B, 0x10, 0x47, 0x00, 0x18, 0x00, 0x04, 0x24, -0x21, 0x28, 0x60, 0x00, 0x0B, 0x28, 0x82, 0x00, 0x06, 0x10, 0xA8, 0x00, -0x02, 0x80, 0x03, 0x3C, 0x98, 0xF2, 0x63, 0x24, 0x21, 0x10, 0x43, 0x00, -0x00, 0x00, 0x44, 0x90, 0x20, 0x00, 0x02, 0x24, 0x21, 0x20, 0x85, 0x00, -0x23, 0x30, 0x44, 0x00, 0xCE, 0x00, 0xC0, 0x14, 0x23, 0x38, 0x46, 0x00, -0x2B, 0x10, 0x0A, 0x01, 0x04, 0x00, 0x40, 0x14, 0x23, 0x20, 0xEC, 0x01, -0x2B, 0x10, 0xEC, 0x01, 0x05, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, -0x2B, 0x10, 0xE4, 0x01, 0x23, 0x18, 0x48, 0x01, 0x23, 0x50, 0x62, 0x00, -0x21, 0x78, 0x80, 0x00, 0x04, 0x00, 0x40, 0x12, 0x21, 0xC0, 0xE0, 0x01, -0x21, 0xC8, 0x40, 0x01, 0x00, 0x00, 0x58, 0xAE, 0x04, 0x00, 0x59, 0xAE, -0x00, 0x00, 0xA2, 0x8F, 0x04, 0x00, 0xA3, 0x8F, 0x10, 0x00, 0xB2, 0x8F, -0x0C, 0x00, 0xB1, 0x8F, 0x08, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0x53, 0x00, 0xC0, 0x10, 0x01, 0x00, 0x02, 0x24, -0xFF, 0xFF, 0x02, 0x34, 0x2B, 0x10, 0x4C, 0x00, 0x59, 0x00, 0x40, 0x14, -0xFF, 0x00, 0x02, 0x3C, 0x00, 0x01, 0x83, 0x2D, 0x08, 0x00, 0x02, 0x24, -0x21, 0x28, 0x00, 0x00, 0x0A, 0x28, 0x43, 0x00, 0x06, 0x10, 0xAC, 0x00, -0x02, 0x80, 0x03, 0x3C, 0x98, 0xF2, 0x63, 0x24, 0x21, 0x10, 0x43, 0x00, -0x00, 0x00, 0x44, 0x90, 0x20, 0x00, 0x02, 0x24, 0x21, 0x20, 0x85, 0x00, -0x23, 0x30, 0x44, 0x00, 0x5B, 0x00, 0xC0, 0x14, 0x00, 0x00, 0x00, 0x00, -0x23, 0x50, 0x4C, 0x01, 0x02, 0x4C, 0x0C, 0x00, 0xFF, 0xFF, 0x8D, 0x31, -0x1B, 0x00, 0x49, 0x01, 0x02, 0x00, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00, -0x0D, 0x00, 0x07, 0x00, 0x02, 0x24, 0x0F, 0x00, 0x12, 0x18, 0x00, 0x00, -0x10, 0x28, 0x00, 0x00, 0x00, 0x14, 0x05, 0x00, 0x25, 0x28, 0x44, 0x00, -0x18, 0x00, 0x6D, 0x00, 0x12, 0x58, 0x00, 0x00, 0x2B, 0x18, 0xAB, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x49, 0x01, 0x02, 0x00, 0x20, 0x15, -0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00, 0x08, 0x00, 0x60, 0x10, -0x00, 0x00, 0x00, 0x00, 0x21, 0x28, 0xAC, 0x00, 0x2B, 0x10, 0xAC, 0x00, -0x04, 0x00, 0x40, 0x14, 0x2B, 0x10, 0xAB, 0x00, 0x00, 0x00, 0x42, 0x38, -0x21, 0x18, 0xAC, 0x00, 0x0B, 0x28, 0x62, 0x00, 0x23, 0x28, 0xAB, 0x00, -0x1B, 0x00, 0xA9, 0x00, 0x02, 0x00, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00, -0x0D, 0x00, 0x07, 0x00, 0xFF, 0xFF, 0xE4, 0x31, 0x12, 0x18, 0x00, 0x00, -0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x18, 0x00, 0x6D, 0x00, 0x00, 0x14, 0x08, 0x00, 0x12, 0x58, 0x00, 0x00, -0x25, 0x40, 0x44, 0x00, 0x2B, 0x18, 0x0B, 0x01, 0x1B, 0x00, 0xA9, 0x00, -0x02, 0x00, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00, -0x08, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x21, 0x40, 0x0C, 0x01, -0x2B, 0x10, 0x0C, 0x01, 0x04, 0x00, 0x40, 0x14, 0x2B, 0x10, 0x0B, 0x01, -0x21, 0x18, 0x0C, 0x01, 0x00, 0x00, 0x42, 0x38, 0x0B, 0x40, 0x62, 0x00, -0xAB, 0xFF, 0x40, 0x12, 0x23, 0x78, 0x0B, 0x01, 0x06, 0xC0, 0xCF, 0x00, -0x21, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x58, 0xAE, 0xA1, 0x63, 0x00, 0x08, -0x04, 0x00, 0x59, 0xAE, 0x1B, 0x00, 0x47, 0x00, 0x02, 0x00, 0xE0, 0x14, -0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00, 0xFF, 0xFF, 0x02, 0x34, -0x12, 0x60, 0x00, 0x00, 0x2B, 0x10, 0x4C, 0x00, 0xAB, 0xFF, 0x40, 0x10, -0x00, 0x01, 0x83, 0x2D, 0xFF, 0x00, 0x02, 0x3C, 0x10, 0x00, 0x03, 0x24, -0xFF, 0xFF, 0x42, 0x34, 0x2B, 0x10, 0x4C, 0x00, 0x18, 0x00, 0x04, 0x24, -0x21, 0x28, 0x60, 0x00, 0x0B, 0x28, 0x82, 0x00, 0x02, 0x80, 0x03, 0x3C, -0x06, 0x10, 0xAC, 0x00, 0x98, 0xF2, 0x63, 0x24, 0x21, 0x10, 0x43, 0x00, -0x00, 0x00, 0x44, 0x90, 0x20, 0x00, 0x02, 0x24, 0x21, 0x20, 0x85, 0x00, -0x23, 0x30, 0x44, 0x00, 0xA7, 0xFF, 0xC0, 0x10, 0x00, 0x00, 0x00, 0x00, -0x23, 0x38, 0x46, 0x00, 0x04, 0x60, 0xCC, 0x00, 0x06, 0x58, 0xEA, 0x00, -0x02, 0x4C, 0x0C, 0x00, 0x1B, 0x00, 0x69, 0x01, 0x02, 0x00, 0x20, 0x15, -0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00, 0xFF, 0xFF, 0x8D, 0x31, -0x06, 0x18, 0xEF, 0x00, 0x04, 0x10, 0xCA, 0x00, 0x25, 0x50, 0x43, 0x00, -0x02, 0x24, 0x0A, 0x00, 0x12, 0x28, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, -0x00, 0x14, 0x08, 0x00, 0x25, 0x40, 0x44, 0x00, 0x18, 0x00, 0xAD, 0x00, -0x12, 0x28, 0x00, 0x00, 0x2B, 0x18, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, -0x1B, 0x00, 0x69, 0x01, 0x02, 0x00, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00, -0x0D, 0x00, 0x07, 0x00, 0x05, 0x00, 0x60, 0x10, 0x04, 0x78, 0xCF, 0x00, -0x21, 0x40, 0x0C, 0x01, 0x2B, 0x10, 0x0C, 0x01, 0x93, 0x00, 0x40, 0x10, -0x2B, 0x10, 0x05, 0x01, 0x23, 0x40, 0x05, 0x01, 0x1B, 0x00, 0x09, 0x01, -0x02, 0x00, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00, -0xFF, 0xFF, 0x44, 0x31, 0x12, 0x18, 0x00, 0x00, 0x10, 0x58, 0x00, 0x00, -0x00, 0x14, 0x0B, 0x00, 0x25, 0x58, 0x44, 0x00, 0x18, 0x00, 0x6D, 0x00, -0x12, 0x28, 0x00, 0x00, 0x2B, 0x18, 0x65, 0x01, 0x00, 0x00, 0x00, 0x00, -0x1B, 0x00, 0x09, 0x01, 0x02, 0x00, 0x20, 0x15, 0x00, 0x00, 0x00, 0x00, -0x0D, 0x00, 0x07, 0x00, 0x77, 0xFF, 0x60, 0x10, 0x23, 0x50, 0x65, 0x01, -0x21, 0x58, 0x6C, 0x01, 0x2B, 0x10, 0x6C, 0x01, 0x04, 0x00, 0x40, 0x14, -0x2B, 0x10, 0x65, 0x01, 0x00, 0x00, 0x42, 0x38, 0x21, 0x18, 0x6C, 0x01, -0x0B, 0x58, 0x62, 0x00, 0xBF, 0x63, 0x00, 0x08, 0x23, 0x50, 0x65, 0x01, -0x08, 0x00, 0x02, 0x24, 0x21, 0x28, 0x00, 0x00, 0x0A, 0x28, 0x43, 0x00, -0x02, 0x80, 0x03, 0x3C, 0x06, 0x10, 0xA8, 0x00, 0x98, 0xF2, 0x63, 0x24, -0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x44, 0x90, 0x20, 0x00, 0x02, 0x24, -0x21, 0x20, 0x85, 0x00, 0x23, 0x30, 0x44, 0x00, 0x34, 0xFF, 0xC0, 0x10, -0x23, 0x38, 0x46, 0x00, 0x06, 0x10, 0xEC, 0x00, 0x04, 0x18, 0xC8, 0x00, -0x25, 0x40, 0x62, 0x00, 0x06, 0x58, 0xEA, 0x00, 0x02, 0x6C, 0x08, 0x00, -0x1B, 0x00, 0x6D, 0x01, 0x02, 0x00, 0xA0, 0x15, 0x00, 0x00, 0x00, 0x00, -0x0D, 0x00, 0x07, 0x00, 0xFF, 0xFF, 0x11, 0x31, 0x06, 0x10, 0xEF, 0x00, -0x04, 0x18, 0xCA, 0x00, 0x25, 0x50, 0x62, 0x00, 0x02, 0x24, 0x0A, 0x00, -0x04, 0x60, 0xCC, 0x00, 0x12, 0x80, 0x00, 0x00, 0x10, 0x48, 0x00, 0x00, -0x00, 0x14, 0x09, 0x00, 0x25, 0x48, 0x44, 0x00, 0x12, 0x28, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x11, 0x02, -0x12, 0x70, 0x00, 0x00, 0x2B, 0x18, 0x2E, 0x01, 0x00, 0x00, 0x00, 0x00, -0x1B, 0x00, 0x6D, 0x01, 0x02, 0x00, 0xA0, 0x15, 0x00, 0x00, 0x00, 0x00, -0x0D, 0x00, 0x07, 0x00, 0x0A, 0x00, 0x60, 0x10, 0x04, 0x78, 0xCF, 0x00, -0x21, 0x48, 0x28, 0x01, 0x2B, 0x10, 0x28, 0x01, 0x06, 0x00, 0x40, 0x14, -0xFF, 0xFF, 0xB0, 0x24, 0x2B, 0x10, 0x2E, 0x01, 0x03, 0x00, 0x40, 0x10, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x10, 0x26, 0x21, 0x48, 0x28, 0x01, -0x23, 0x48, 0x2E, 0x01, 0x1B, 0x00, 0x2D, 0x01, 0x02, 0x00, 0xA0, 0x15, -0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00, 0xFF, 0xFF, 0x44, 0x31, -0x12, 0x28, 0x00, 0x00, 0x10, 0x58, 0x00, 0x00, 0x00, 0x14, 0x0B, 0x00, -0x25, 0x58, 0x44, 0x00, 0x18, 0x00, 0xB1, 0x00, 0x12, 0x70, 0x00, 0x00, -0x2B, 0x18, 0x6E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x2D, 0x01, -0x02, 0x00, 0xA0, 0x15, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x07, 0x00, -0x0B, 0x00, 0x60, 0x10, 0x00, 0x14, 0x10, 0x00, 0x21, 0x58, 0x68, 0x01, -0x2B, 0x10, 0x68, 0x01, 0x06, 0x00, 0x40, 0x14, 0xFF, 0xFF, 0xA5, 0x24, -0x2B, 0x10, 0x6E, 0x01, 0x04, 0x00, 0x40, 0x10, 0x00, 0x14, 0x10, 0x00, -0xFF, 0xFF, 0xA5, 0x24, 0x21, 0x58, 0x68, 0x01, 0x00, 0x14, 0x10, 0x00, -0x25, 0x10, 0x45, 0x00, 0x23, 0x58, 0x6E, 0x01, 0x19, 0x00, 0x4C, 0x00, -0x10, 0x28, 0x00, 0x00, 0x2B, 0x18, 0x65, 0x01, 0x12, 0x48, 0x00, 0x00, -0x05, 0x00, 0x60, 0x14, 0x23, 0x20, 0x2C, 0x01, 0x07, 0x00, 0xAB, 0x14, -0x2B, 0x10, 0xE9, 0x01, 0x05, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, -0x2B, 0x10, 0x24, 0x01, 0x23, 0x18, 0xA8, 0x00, 0x23, 0x28, 0x62, 0x00, -0x21, 0x48, 0x80, 0x00, 0xEA, 0xFE, 0x40, 0x12, 0x23, 0x18, 0xE9, 0x01, -0x23, 0x20, 0x65, 0x01, 0x2B, 0x10, 0xE3, 0x01, 0x23, 0x50, 0x82, 0x00, -0x04, 0x28, 0xEA, 0x00, 0x06, 0x18, 0xC3, 0x00, 0x25, 0xC0, 0xA3, 0x00, -0x06, 0xC8, 0xCA, 0x00, 0x00, 0x00, 0x58, 0xAE, 0xA1, 0x63, 0x00, 0x08, -0x04, 0x00, 0x59, 0xAE, 0x00, 0x01, 0xC3, 0x2C, 0x08, 0x00, 0x02, 0x24, -0x21, 0x30, 0x00, 0x00, 0x3B, 0x63, 0x00, 0x08, 0x0A, 0x30, 0x43, 0x00, -0x00, 0x00, 0x42, 0x38, 0x21, 0x18, 0x0C, 0x01, 0x35, 0x64, 0x00, 0x08, -0x0B, 0x40, 0x62, 0x00, 0x25, 0xB0, 0x03, 0x3C, 0x4D, 0x00, 0x64, 0x34, -0xF1, 0x02, 0x65, 0x34, 0x08, 0x00, 0x02, 0x24, 0x00, 0x00, 0x80, 0xA0, -0xEC, 0x02, 0x66, 0x34, 0x00, 0x00, 0xA2, 0xA0, 0xF0, 0x02, 0x63, 0x34, -0xFF, 0x00, 0x02, 0x3C, 0x00, 0x00, 0x60, 0xA0, 0x00, 0x00, 0xC2, 0xAC, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x03, 0x3C, -0x25, 0xB0, 0x02, 0x3C, 0x60, 0x93, 0x63, 0x24, 0x18, 0x03, 0x42, 0x34, -0x00, 0x00, 0x43, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0x7F, 0x00, 0x02, 0x3C, 0x0D, 0xB8, 0x44, 0x34, 0x80, 0x04, 0x03, 0x3C, -0x25, 0x20, 0x83, 0x00, 0x00, 0x08, 0x02, 0x3C, 0x25, 0x20, 0x82, 0x00, -0x00, 0x30, 0x03, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, -0x25, 0x20, 0x83, 0x00, 0x41, 0xB0, 0x03, 0x3C, 0x00, 0x00, 0x64, 0xAC, -0xD8, 0x1B, 0x44, 0xAC, 0xD0, 0x1B, 0x44, 0xAC, 0x08, 0x00, 0x63, 0x34, -0x86, 0x00, 0x04, 0x24, 0x00, 0x00, 0x64, 0xA4, 0xDC, 0x1B, 0x44, 0xA4, -0xD4, 0x1B, 0x40, 0xAC, 0xDE, 0x1B, 0x40, 0xA4, 0x08, 0x00, 0xE0, 0x03, -0xE0, 0x1B, 0x44, 0xA4, 0xF5, 0x64, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x42, 0xB0, 0x03, 0x3C, 0x01, 0x00, 0x63, 0x34, 0x02, 0x00, 0x02, 0x24, -0xE8, 0xFF, 0xBD, 0x27, 0x00, 0x00, 0x62, 0xA0, 0x10, 0x00, 0xBF, 0xAF, -0x85, 0x2B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x00, 0x00, -0x01, 0x00, 0x05, 0x24, 0xB9, 0x20, 0x00, 0x0C, 0x00, 0x50, 0x06, 0x24, -0x1F, 0x00, 0x06, 0x3C, 0x10, 0x00, 0xBF, 0x8F, 0x00, 0x40, 0xC6, 0x34, -0x03, 0x00, 0x04, 0x24, 0x01, 0x00, 0x05, 0x24, 0xB9, 0x20, 0x00, 0x08, -0x18, 0x00, 0xBD, 0x27, 0x25, 0xB0, 0x03, 0x3C, 0x02, 0x80, 0x02, 0x3C, -0xC8, 0xFF, 0xBD, 0x27, 0x18, 0x03, 0x64, 0x34, 0x28, 0x94, 0x42, 0x24, -0x00, 0x00, 0x82, 0xAC, 0x30, 0x00, 0xBE, 0xAF, 0x2C, 0x00, 0xB7, 0xAF, -0x28, 0x00, 0xB6, 0xAF, 0x24, 0x00, 0xB5, 0xAF, 0x20, 0x00, 0xB4, 0xAF, -0x1C, 0x00, 0xB3, 0xAF, 0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF, -0x34, 0x00, 0xBF, 0xAF, 0x10, 0x00, 0xB0, 0xAF, 0xB6, 0x00, 0x63, 0x34, -0x00, 0x00, 0x64, 0x90, 0x02, 0x80, 0x03, 0x3C, 0x60, 0x1B, 0x62, 0x24, -0x48, 0x01, 0x03, 0x24, 0x70, 0x37, 0x43, 0xAC, 0x6C, 0x37, 0x43, 0xAC, -0xAB, 0x1B, 0x44, 0xA0, 0xC6, 0x3D, 0x40, 0xA0, 0x66, 0x37, 0x40, 0xA0, -0x84, 0x6C, 0x00, 0x0C, 0x21, 0x98, 0x40, 0x00, 0xFD, 0xFF, 0x02, 0x3C, -0xFB, 0xFF, 0x03, 0x3C, 0x21, 0xA0, 0x60, 0x02, 0xFF, 0xFF, 0x55, 0x34, -0xFF, 0xFF, 0x76, 0x34, 0x21, 0x88, 0x00, 0x00, 0x02, 0x80, 0x1E, 0x3C, -0x02, 0x80, 0x17, 0x3C, 0x21, 0x90, 0x60, 0x02, 0x40, 0x10, 0x11, 0x00, -0x21, 0x10, 0x51, 0x00, 0x00, 0x11, 0x02, 0x00, 0x21, 0x10, 0x53, 0x00, -0xD4, 0x1D, 0x42, 0x24, 0x07, 0x00, 0x03, 0x24, 0xFF, 0xFF, 0x63, 0x24, -0x00, 0x00, 0x40, 0xA4, 0xFD, 0xFF, 0x61, 0x04, 0x02, 0x00, 0x42, 0x24, -0xC0, 0x80, 0x11, 0x00, 0x34, 0x3F, 0xC4, 0x27, 0x21, 0x20, 0x04, 0x02, -0x21, 0x28, 0x00, 0x00, 0x02, 0x00, 0x06, 0x24, 0xE4, 0x1D, 0x40, 0xA6, -0xEC, 0x54, 0x00, 0x0C, 0xE6, 0x1D, 0x40, 0xA2, 0x21, 0x20, 0x13, 0x02, -0xD4, 0x23, 0x83, 0x8C, 0xD2, 0x5C, 0xE7, 0x92, 0xBF, 0xFF, 0x02, 0x24, -0x24, 0x28, 0x62, 0x00, 0x01, 0x00, 0x02, 0x24, 0x63, 0x00, 0xE2, 0x10, -0x80, 0x07, 0xA6, 0x34, 0xFF, 0xF7, 0x03, 0x24, 0x24, 0x10, 0xC3, 0x00, -0xFF, 0xEF, 0x03, 0x24, 0x24, 0x10, 0x43, 0x00, 0xD4, 0x23, 0x82, 0xAC, -0x21, 0x30, 0x14, 0x02, 0xD4, 0x23, 0xC4, 0x8C, 0xE7, 0xFF, 0x02, 0x3C, -0xFF, 0xFF, 0x42, 0x34, 0x24, 0x20, 0x95, 0x00, 0x24, 0x20, 0x96, 0x00, -0xFF, 0xFD, 0x03, 0x3C, 0x24, 0x20, 0x82, 0x00, 0xFF, 0xFF, 0x63, 0x34, -0xFF, 0xFB, 0x02, 0x3C, 0x24, 0x20, 0x83, 0x00, 0xD8, 0x23, 0xC5, 0x8C, -0xFF, 0xFF, 0x42, 0x34, 0xFF, 0xE7, 0x03, 0x3C, 0x24, 0x20, 0x82, 0x00, -0xFF, 0xFF, 0x63, 0x34, 0xFF, 0xFF, 0x02, 0x3C, 0x24, 0x20, 0x83, 0x00, -0xFF, 0x7F, 0x42, 0x34, 0xC0, 0xFF, 0x03, 0x24, 0x24, 0x28, 0xA2, 0x00, -0x24, 0x20, 0x83, 0x00, 0x1F, 0x00, 0x02, 0x3C, 0x01, 0x00, 0x31, 0x26, -0x25, 0x28, 0xA2, 0x00, 0x08, 0x00, 0x84, 0x34, 0x20, 0x00, 0x22, 0x2A, -0xD4, 0x23, 0xC4, 0xAC, 0xD8, 0x23, 0xC5, 0xAC, 0xC3, 0xFF, 0x40, 0x14, -0x30, 0x00, 0x52, 0x26, 0x25, 0xB0, 0x02, 0x3C, 0x10, 0x00, 0x03, 0x24, -0xB0, 0x03, 0x42, 0x34, 0x02, 0x80, 0x04, 0x3C, 0x00, 0x00, 0x43, 0xAC, -0x88, 0x1E, 0x84, 0x24, 0x21, 0x28, 0x00, 0x00, 0xEC, 0x54, 0x00, 0x0C, -0x20, 0x00, 0x06, 0x24, 0x02, 0x80, 0x02, 0x3C, 0xD1, 0x5C, 0x43, 0x90, -0x00, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x60, 0x10, 0x02, 0x80, 0x03, 0x3C, -0x60, 0x1B, 0x62, 0x24, 0x25, 0x03, 0x40, 0xA0, 0xC2, 0x6F, 0x00, 0x74, -0x24, 0x03, 0x40, 0xA0, 0xD8, 0x70, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x47, 0x6C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0xBF, 0x8F, -0x30, 0x00, 0xBE, 0x8F, 0x2C, 0x00, 0xB7, 0x8F, 0x28, 0x00, 0xB6, 0x8F, -0x24, 0x00, 0xB5, 0x8F, 0x20, 0x00, 0xB4, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, -0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x02, 0x80, 0x09, 0x3C, 0x02, 0x80, 0x0A, 0x3C, 0x02, 0x80, 0x0B, 0x3C, -0x02, 0x80, 0x0C, 0x3C, 0x02, 0x80, 0x0D, 0x3C, 0x02, 0x80, 0x0E, 0x3C, -0x02, 0x80, 0x0F, 0x3C, 0x88, 0x54, 0x22, 0x25, 0x90, 0x54, 0x43, 0x25, -0x98, 0x54, 0x64, 0x25, 0xA0, 0x54, 0x85, 0x25, 0xA8, 0x54, 0xA6, 0x25, -0xB0, 0x54, 0xC7, 0x25, 0xB8, 0x54, 0xE8, 0x25, 0x38, 0x00, 0xBD, 0x27, -0x04, 0x00, 0x42, 0xAC, 0x88, 0x54, 0x22, 0xAD, 0x04, 0x00, 0x63, 0xAC, -0x90, 0x54, 0x43, 0xAD, 0x04, 0x00, 0x84, 0xAC, 0x98, 0x54, 0x64, 0xAD, -0x04, 0x00, 0xA5, 0xAC, 0xA0, 0x54, 0x85, 0xAD, 0x04, 0x00, 0xC6, 0xAC, -0xA8, 0x54, 0xA6, 0xAD, 0x04, 0x00, 0xE7, 0xAC, 0xB0, 0x54, 0xC7, 0xAD, -0xB8, 0x54, 0xE8, 0xAD, 0x08, 0x00, 0xE0, 0x03, 0x04, 0x00, 0x08, 0xAD, -0x02, 0x80, 0x02, 0x3C, 0xD3, 0x5C, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, -0x9C, 0xFF, 0x67, 0x14, 0x80, 0x0F, 0xA2, 0x34, 0xFF, 0xF7, 0x03, 0x24, -0x24, 0x10, 0xC3, 0x00, 0x4D, 0x65, 0x00, 0x08, 0x00, 0x10, 0x42, 0x34, -0x7A, 0x6D, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0xAD, 0x6F, 0x00, 0x74, -0x24, 0x39, 0x80, 0xAE, 0x26, 0x70, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, -0x02, 0x80, 0x03, 0x3C, 0xC6, 0x5C, 0x64, 0x90, 0x92, 0x00, 0x02, 0x24, -0x03, 0x00, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x60, 0x70, 0x00, 0x74, -0x00, 0x00, 0x00, 0x00, 0xC1, 0x70, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, -0x7B, 0x65, 0x00, 0x08, 0x02, 0x80, 0x03, 0x3C, 0x02, 0x80, 0x03, 0x3C, -0x25, 0xB0, 0x02, 0x3C, 0xC8, 0xFF, 0xBD, 0x27, 0x14, 0x97, 0x63, 0x24, -0x18, 0x03, 0x42, 0x34, 0x18, 0x00, 0xB0, 0xAF, 0x34, 0x00, 0xBF, 0xAF, -0x30, 0x00, 0xB6, 0xAF, 0x2C, 0x00, 0xB5, 0xAF, 0x28, 0x00, 0xB4, 0xAF, -0x24, 0x00, 0xB3, 0xAF, 0x20, 0x00, 0xB2, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, -0x00, 0x00, 0x43, 0xAC, 0x21, 0x80, 0x00, 0x00, 0x01, 0x00, 0x02, 0x26, -0xFF, 0xFF, 0x50, 0x30, 0x64, 0x00, 0x03, 0x2E, 0xFD, 0xFF, 0x60, 0x14, -0x01, 0x00, 0x02, 0x26, 0x64, 0x40, 0x00, 0x0C, 0x02, 0x80, 0x14, 0x3C, -0x02, 0x80, 0x03, 0x3C, 0xC3, 0x5C, 0x68, 0x90, 0x02, 0x80, 0x02, 0x3C, -0x02, 0x80, 0x03, 0x3C, 0xC0, 0x5C, 0x4B, 0x94, 0xDB, 0x5C, 0x6A, 0x90, -0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0xE2, 0x5C, 0x67, 0x90, -0xD0, 0x5C, 0x49, 0x90, 0xC2, 0x5C, 0x83, 0x92, 0x02, 0x80, 0x0C, 0x3C, -0x02, 0x80, 0x02, 0x3C, 0xDD, 0x5C, 0x46, 0x90, 0xE0, 0x5C, 0x85, 0x91, -0x25, 0xB0, 0x04, 0x3C, 0xB0, 0x03, 0x82, 0x34, 0x00, 0x00, 0x4B, 0xAC, -0x00, 0x00, 0x48, 0xAC, 0x00, 0x00, 0x49, 0xAC, 0x00, 0x00, 0x43, 0xAC, -0x02, 0x80, 0x03, 0x3C, 0x00, 0x00, 0x4A, 0xAC, 0x0A, 0x00, 0x88, 0x34, -0x00, 0x00, 0x46, 0xAC, 0x00, 0x00, 0x45, 0xAC, 0x00, 0x00, 0x47, 0xAC, -0x0C, 0x5D, 0x60, 0xA4, 0x00, 0x00, 0x06, 0x91, 0x02, 0x80, 0x02, 0x3C, -0x0B, 0x00, 0x04, 0x24, 0x02, 0x80, 0x13, 0x3C, 0xCD, 0x5C, 0x44, 0xA0, -0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x65, 0x26, 0x00, 0x70, 0x03, 0x24, -0xF0, 0x5C, 0x40, 0xA0, 0xF0, 0xFF, 0x02, 0x24, 0x01, 0x00, 0x07, 0x24, -0x02, 0x80, 0x16, 0x3C, 0xAC, 0x1B, 0xA3, 0xA4, 0xAA, 0x1B, 0xA2, 0xA0, -0xFF, 0x07, 0x03, 0x24, 0xFF, 0xFF, 0x02, 0x24, 0x20, 0x00, 0xC6, 0x30, -0xE0, 0x5C, 0x87, 0xA1, 0xA8, 0x1B, 0xA7, 0xA0, 0xAE, 0x1B, 0xA3, 0xA4, -0x48, 0xF5, 0xC2, 0xA2, 0x9A, 0x00, 0xC0, 0x10, 0xB0, 0x1B, 0xA0, 0xA4, -0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x42, 0x30, -0x0B, 0x01, 0x40, 0x14, 0x02, 0x80, 0x15, 0x3C, 0x21, 0x80, 0x00, 0x00, -0x21, 0x88, 0x00, 0x00, 0x98, 0xF3, 0xB2, 0x26, 0xFF, 0x00, 0x24, 0x32, -0xCF, 0x59, 0x00, 0x0C, 0x21, 0x28, 0x12, 0x02, 0x08, 0x00, 0x03, 0x26, -0xFF, 0xFF, 0x70, 0x30, 0x01, 0x00, 0x22, 0x26, 0x80, 0x00, 0x03, 0x2E, -0xF8, 0xFF, 0x60, 0x14, 0xFF, 0xFF, 0x51, 0x30, 0xC2, 0x5C, 0x83, 0x92, -0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x62, 0x30, 0xCA, 0x00, 0x40, 0x14, -0x04, 0x00, 0x62, 0x30, 0x83, 0x00, 0x40, 0x10, 0x25, 0xB0, 0x03, 0x3C, -0x25, 0xB0, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, 0x50, 0x00, 0x84, 0x34, -0xE7, 0xF3, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, -0x98, 0xF3, 0xA3, 0x26, 0x7B, 0x00, 0x67, 0x90, 0x00, 0x00, 0x00, 0x00, -0x02, 0x00, 0xE2, 0x2C, 0x04, 0x00, 0x40, 0x14, 0x02, 0x00, 0x0B, 0x24, -0x79, 0x00, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x4B, 0x30, -0x04, 0x00, 0xE2, 0x2C, 0xEC, 0x00, 0x40, 0x10, 0x98, 0xF3, 0xA2, 0x26, -0x60, 0x1B, 0x62, 0x8E, 0xBF, 0xFF, 0x03, 0x24, 0x02, 0x80, 0x12, 0x3C, -0x24, 0x10, 0x43, 0x00, 0x02, 0x80, 0x03, 0x3C, 0x4A, 0xF5, 0x60, 0xA0, -0x60, 0x1B, 0x62, 0xAE, 0x02, 0x80, 0x02, 0x3C, 0xCF, 0x5C, 0x43, 0x90, -0x01, 0x00, 0x02, 0x24, 0x02, 0x00, 0x62, 0x10, 0xFC, 0xFF, 0x08, 0x24, -0x21, 0x40, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, -0x98, 0xF3, 0x4A, 0x24, 0x60, 0x1B, 0x69, 0x24, 0x21, 0x60, 0x00, 0x00, -0x21, 0x80, 0x00, 0x00, 0x01, 0x00, 0x02, 0x26, 0x21, 0x30, 0x30, 0x01, -0x03, 0x00, 0x03, 0x2E, 0x08, 0x00, 0x04, 0x2E, 0xFF, 0xFF, 0x50, 0x30, -0x0E, 0x00, 0x07, 0x2E, 0x04, 0x00, 0x60, 0x14, 0x21, 0x88, 0x00, 0x00, -0x01, 0x00, 0x11, 0x24, 0x02, 0x00, 0x02, 0x24, 0x0A, 0x88, 0x44, 0x00, -0x21, 0x10, 0x51, 0x01, 0x61, 0x00, 0x43, 0x90, 0x55, 0x00, 0x44, 0x90, -0x5B, 0x00, 0x45, 0x90, 0x21, 0x18, 0x03, 0x01, 0x21, 0x20, 0x04, 0x01, -0x21, 0x28, 0x05, 0x01, 0x9C, 0x1D, 0xC3, 0xA0, 0x64, 0x1D, 0xC4, 0xA0, -0xEB, 0xFF, 0xE0, 0x14, 0x80, 0x1D, 0xC5, 0xA0, 0x01, 0x00, 0x8C, 0x25, -0x02, 0x00, 0x82, 0x2D, 0x0E, 0x00, 0x29, 0x25, 0xE5, 0xFF, 0x40, 0x14, -0x03, 0x00, 0x4A, 0x25, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, -0x60, 0x1B, 0x47, 0x24, 0x98, 0xF3, 0x66, 0x24, 0x21, 0x80, 0x00, 0x00, -0x03, 0x00, 0x02, 0x2E, 0x21, 0x20, 0x07, 0x02, 0xD1, 0x00, 0x40, 0x10, -0x08, 0x00, 0x03, 0x2E, 0x71, 0x00, 0xC3, 0x90, 0x6E, 0x00, 0xC2, 0x90, -0x00, 0x00, 0x00, 0x00, 0xC6, 0x1D, 0x82, 0xA0, 0xB8, 0x1D, 0x83, 0xA0, -0x01, 0x00, 0x02, 0x26, 0xFF, 0xFF, 0x50, 0x30, 0x0E, 0x00, 0x03, 0x2E, -0xF4, 0xFF, 0x60, 0x14, 0x03, 0x00, 0x02, 0x2E, 0x03, 0x00, 0x02, 0x24, -0x51, 0x00, 0x62, 0x15, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, -0x98, 0xF3, 0x4E, 0x24, 0xC0, 0xD9, 0x6F, 0x24, 0x21, 0x60, 0x00, 0x00, -0x21, 0x68, 0x00, 0x00, 0x21, 0x10, 0xAE, 0x01, 0x74, 0x00, 0x43, 0x90, -0x21, 0x80, 0x00, 0x00, 0x0F, 0x00, 0x6A, 0x30, 0x02, 0x49, 0x03, 0x00, -0x21, 0x10, 0xB0, 0x01, 0x00, 0x11, 0x02, 0x00, 0x21, 0x58, 0x4F, 0x00, -0x21, 0x38, 0x00, 0x00, 0x21, 0x40, 0x67, 0x01, 0x00, 0x00, 0x03, 0x91, -0x00, 0x31, 0x09, 0x00, 0x01, 0x00, 0xE7, 0x24, 0x02, 0x11, 0x03, 0x00, -0x00, 0x21, 0x02, 0x00, 0x0F, 0x00, 0x63, 0x30, 0x2B, 0x10, 0x49, 0x00, -0x0A, 0x20, 0xC2, 0x00, 0x2B, 0x28, 0x6A, 0x00, 0x00, 0x00, 0xA5, 0x38, -0x25, 0x18, 0x83, 0x00, 0xFF, 0xFF, 0xE7, 0x30, 0x25, 0x20, 0x8A, 0x00, -0x0A, 0x18, 0x85, 0x00, 0x10, 0x00, 0xE2, 0x2C, 0xEF, 0xFF, 0x40, 0x14, -0x00, 0x00, 0x03, 0xA1, 0x01, 0x00, 0x02, 0x26, 0xFF, 0xFF, 0x50, 0x30, -0x03, 0x00, 0x03, 0x2E, 0xE7, 0xFF, 0x60, 0x14, 0x21, 0x10, 0xB0, 0x01, -0x01, 0x00, 0x8C, 0x25, 0x02, 0x00, 0x82, 0x2D, 0xDD, 0xFF, 0x40, 0x14, -0x03, 0x00, 0xAD, 0x25, 0xCC, 0x66, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x25, 0xB0, 0x03, 0x3C, 0x4C, 0x87, 0x02, 0x3C, 0x54, 0x00, 0x65, 0x34, -0x00, 0xE0, 0x42, 0x34, 0x50, 0x00, 0x63, 0x34, 0x00, 0x00, 0x62, 0xAC, -0x12, 0x01, 0x04, 0x24, 0x02, 0x80, 0x02, 0x3C, 0x00, 0x00, 0xA4, 0xAC, -0x60, 0x1B, 0x46, 0x24, 0x21, 0x60, 0x00, 0x00, 0x10, 0x00, 0x05, 0x24, -0x21, 0x80, 0x00, 0x00, 0x01, 0x00, 0x02, 0x26, 0x21, 0x18, 0xD0, 0x00, -0xFF, 0xFF, 0x50, 0x30, 0x0E, 0x00, 0x04, 0x2E, 0x80, 0x1D, 0x65, 0xA0, -0x64, 0x1D, 0x65, 0xA0, 0xF9, 0xFF, 0x80, 0x14, 0x9C, 0x1D, 0x65, 0xA0, -0x01, 0x00, 0x8C, 0x25, 0x02, 0x00, 0x82, 0x2D, 0xF4, 0xFF, 0x40, 0x14, -0x0E, 0x00, 0xC6, 0x24, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x46, 0x24, -0x21, 0x80, 0x00, 0x00, 0x04, 0x00, 0x05, 0x24, 0x01, 0x00, 0x02, 0x26, -0x21, 0x18, 0x06, 0x02, 0xFF, 0xFF, 0x50, 0x30, 0x0E, 0x00, 0x04, 0x2E, -0xC6, 0x1D, 0x60, 0xA0, 0xFA, 0xFF, 0x80, 0x14, 0xB8, 0x1D, 0x65, 0xA0, -0x02, 0x80, 0x12, 0x3C, 0xC6, 0x5C, 0x43, 0x92, 0x01, 0x00, 0x04, 0x24, -0x02, 0x80, 0x02, 0x3C, 0x54, 0x59, 0x00, 0x0C, 0x4B, 0xF5, 0x43, 0xA0, -0x48, 0xF5, 0xC5, 0x26, 0xFF, 0x58, 0x00, 0x0C, 0xFA, 0x01, 0x04, 0x24, -0x54, 0x59, 0x00, 0x0C, 0x21, 0x20, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, -0x25, 0xB0, 0x05, 0x3C, 0x48, 0x37, 0x84, 0x24, 0x50, 0x00, 0xA5, 0x34, -0xF4, 0x54, 0x00, 0x0C, 0x06, 0x00, 0x06, 0x24, 0x60, 0x1B, 0x65, 0x26, -0x01, 0x00, 0x02, 0x24, 0x06, 0x00, 0x03, 0x24, 0x05, 0x00, 0x04, 0x24, -0x33, 0x1C, 0xA2, 0xA0, 0x6F, 0x58, 0x00, 0x0C, 0xC4, 0x3D, 0xA3, 0xA0, -0x34, 0x00, 0xBF, 0x8F, 0x30, 0x00, 0xB6, 0x8F, 0x2C, 0x00, 0xB5, 0x8F, -0x28, 0x00, 0xB4, 0x8F, 0x24, 0x00, 0xB3, 0x8F, 0x20, 0x00, 0xB2, 0x8F, -0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x38, 0x00, 0xBD, 0x27, 0x25, 0xB0, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, -0x50, 0x00, 0x84, 0x34, 0xAA, 0xF3, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C, -0x06, 0x00, 0x06, 0x24, 0x98, 0xF3, 0xA2, 0x92, 0x98, 0xF3, 0xA5, 0x26, -0x01, 0x00, 0xA4, 0x90, 0x21, 0x18, 0x40, 0x00, 0x10, 0x00, 0xA2, 0xA3, -0x29, 0x00, 0x02, 0x24, 0x11, 0x00, 0xA4, 0xA3, 0x50, 0x00, 0xA7, 0x90, -0x4F, 0x00, 0x62, 0x10, 0x02, 0x80, 0x12, 0x3C, 0x98, 0xF3, 0xA6, 0x26, -0x68, 0x00, 0xC2, 0x90, 0x02, 0x80, 0x03, 0x3C, 0x04, 0x00, 0xE4, 0x2C, -0x1F, 0x00, 0x42, 0x30, 0x34, 0x00, 0x80, 0x14, 0x49, 0xF5, 0x62, 0xA0, -0x7A, 0x00, 0xC4, 0x90, 0x60, 0x1B, 0x65, 0x8E, 0x79, 0x00, 0xC6, 0x90, -0x01, 0x00, 0x83, 0x30, 0xBF, 0xFF, 0x02, 0x24, 0x24, 0x28, 0xA2, 0x00, -0x80, 0x19, 0x03, 0x00, 0x04, 0x00, 0x84, 0x30, 0x25, 0x28, 0xA3, 0x00, -0x83, 0x20, 0x04, 0x00, 0x02, 0x80, 0x02, 0x3C, 0x03, 0x00, 0xCB, 0x30, -0x4A, 0xF5, 0x44, 0xA0, 0x60, 0x1B, 0x65, 0xAE, 0x06, 0x00, 0xE2, 0x2C, -0x2C, 0xFF, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, 0x98, 0xF3, 0xA3, 0x26, -0x69, 0x00, 0x62, 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x30, -0x26, 0xFF, 0x40, 0x14, 0x02, 0x80, 0x02, 0x3C, 0x45, 0x66, 0x00, 0x08, -0x21, 0x40, 0x00, 0x00, 0x21, 0x20, 0x00, 0x00, 0x80, 0x00, 0x05, 0x24, -0xC1, 0x58, 0x00, 0x0C, 0x98, 0xF3, 0xA6, 0x26, 0x1F, 0x66, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x7A, 0x00, 0x43, 0x90, 0x69, 0x00, 0x46, 0x90, -0x7D, 0x00, 0x44, 0x90, 0x60, 0x1B, 0x65, 0x8E, 0xBF, 0xFF, 0x02, 0x24, -0x01, 0x00, 0x63, 0x30, 0x24, 0x28, 0xA2, 0x00, 0x01, 0x00, 0xC6, 0x30, -0x04, 0x00, 0x84, 0x30, 0x80, 0x19, 0x03, 0x00, 0x25, 0x28, 0xA3, 0x00, -0x83, 0x20, 0x04, 0x00, 0x02, 0x80, 0x02, 0x3C, 0x01, 0x00, 0xC6, 0x2C, -0x4A, 0xF5, 0x44, 0xA0, 0x60, 0x1B, 0x65, 0xAE, 0x0B, 0xFF, 0xC0, 0x10, -0x02, 0x80, 0x12, 0x3C, 0x45, 0x66, 0x00, 0x08, 0x21, 0x40, 0x00, 0x00, -0x60, 0x1B, 0x62, 0x8E, 0xBF, 0xFF, 0x03, 0x24, 0x02, 0x80, 0x04, 0x3C, -0x24, 0x10, 0x43, 0x00, 0x02, 0x00, 0x0B, 0x24, 0x4A, 0xF5, 0x80, 0xA0, -0x12, 0x67, 0x00, 0x08, 0x60, 0x1B, 0x62, 0xAE, 0x21, 0x28, 0x07, 0x02, -0x06, 0x00, 0x60, 0x10, 0x21, 0x20, 0xA0, 0x00, 0x67, 0x00, 0xC3, 0x90, -0x6F, 0x00, 0xC2, 0x90, 0xB8, 0x1D, 0xA3, 0xA0, 0x74, 0x66, 0x00, 0x08, -0xC6, 0x1D, 0xA2, 0xA0, 0x72, 0x00, 0xC3, 0x90, 0x70, 0x00, 0xC2, 0x90, -0x73, 0x66, 0x00, 0x08, 0xC6, 0x1D, 0x82, 0xA0, 0xFF, 0x00, 0x83, 0x30, -0x81, 0x00, 0x02, 0x24, 0xB0, 0xFF, 0x62, 0x14, 0x98, 0xF3, 0xA6, 0x26, -0x54, 0x00, 0xA3, 0x90, 0x01, 0x00, 0x02, 0x24, 0x09, 0x00, 0x62, 0x10, -0x02, 0x00, 0x02, 0x24, 0x04, 0x00, 0x62, 0x10, 0x11, 0x00, 0x02, 0x24, -0x02, 0x80, 0x12, 0x3C, 0xFE, 0x66, 0x00, 0x08, 0xC6, 0x5C, 0x42, 0xA2, -0x22, 0x00, 0x02, 0x24, 0xFD, 0x66, 0x00, 0x08, 0xC6, 0x5C, 0x42, 0xA2, -0x02, 0x80, 0x12, 0x3C, 0x12, 0x00, 0x02, 0x24, 0xFD, 0x66, 0x00, 0x08, -0xC6, 0x5C, 0x42, 0xA2, 0xD8, 0xFF, 0xBD, 0x27, 0x1C, 0x00, 0xB1, 0xAF, -0x02, 0x80, 0x02, 0x3C, 0x25, 0xB0, 0x11, 0x3C, 0x18, 0x03, 0x23, 0x36, -0x7C, 0x9D, 0x42, 0x24, 0x20, 0x00, 0xB2, 0xAF, 0x02, 0x80, 0x12, 0x3C, -0x00, 0x00, 0x62, 0xAC, 0x18, 0x00, 0xB0, 0xAF, 0x24, 0x00, 0xBF, 0xAF, -0xC5, 0x65, 0x00, 0x0C, 0x60, 0x1B, 0x50, 0x26, 0x08, 0x68, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0xA3, 0x6A, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x87, 0x6B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xEA, 0x6D, 0x00, 0x74, -0x00, 0x00, 0x00, 0x00, 0xEF, 0x6A, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0xC4, 0x3D, 0x04, 0x92, 0x38, 0x0D, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, -0xC4, 0x3D, 0x04, 0x92, 0x75, 0x0D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0xCB, 0x64, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x82, 0x40, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x23, 0x36, 0x00, 0x00, 0x62, 0x94, -0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x42, 0x34, 0x00, 0x00, 0x62, 0xA4, -0x0A, 0x65, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x64, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0xF7, 0x64, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x53, 0x6B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10, 0x6B, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x3C, 0x68, 0x61, 0x84, 0x24, -0x70, 0x6B, 0x00, 0x0C, 0x01, 0x00, 0x05, 0x24, 0x00, 0x80, 0x04, 0x3C, -0xD0, 0x67, 0x84, 0x24, 0x70, 0x6B, 0x00, 0x0C, 0x02, 0x00, 0x05, 0x24, -0x00, 0x80, 0x04, 0x3C, 0x39, 0x6F, 0x84, 0x24, 0x70, 0x6B, 0x00, 0x0C, -0x04, 0x00, 0x05, 0x24, 0x44, 0x5C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x01, 0x80, 0x04, 0x3C, 0x6C, 0x83, 0x84, 0x24, 0x70, 0x6B, 0x00, 0x0C, -0x03, 0x00, 0x05, 0x24, 0x02, 0x80, 0x03, 0x3C, 0xD0, 0x5C, 0x63, 0x90, -0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x60, 0x10, 0x43, 0x00, 0x22, 0x36, -0x07, 0x00, 0x02, 0x24, 0x0C, 0x00, 0x62, 0x10, 0x03, 0x00, 0x02, 0x24, -0x25, 0xB0, 0x04, 0x3C, 0x43, 0x00, 0x85, 0x34, 0x10, 0x02, 0x86, 0x34, -0x10, 0x00, 0x03, 0x24, 0x00, 0x00, 0xA2, 0xA0, 0xD8, 0x00, 0x84, 0x34, -0x00, 0x00, 0xC3, 0xA0, 0x00, 0x00, 0x82, 0x90, 0x80, 0xFF, 0x03, 0x24, -0x25, 0x10, 0x43, 0x00, 0x00, 0x00, 0x82, 0xA0, 0xDF, 0x64, 0x00, 0x0C, -0x25, 0xB0, 0x10, 0x3C, 0x44, 0x00, 0x03, 0x36, 0x00, 0x00, 0x62, 0x94, -0x02, 0x80, 0x04, 0x3C, 0x18, 0xE5, 0x84, 0x24, 0xC0, 0x00, 0x42, 0x34, -0x00, 0x00, 0x62, 0xA4, 0x13, 0x58, 0x00, 0x0C, 0xF2, 0x00, 0x05, 0x24, -0x02, 0x80, 0x02, 0x3C, 0xC3, 0x5C, 0x45, 0x90, 0x02, 0x80, 0x04, 0x3C, -0x13, 0x58, 0x00, 0x0C, 0x5C, 0xE5, 0x84, 0x24, 0x02, 0x80, 0x02, 0x3C, -0x02, 0x80, 0x03, 0x3C, 0xC2, 0x5C, 0x45, 0x90, 0xC7, 0x5C, 0x66, 0x90, -0x02, 0x80, 0x04, 0x3C, 0x13, 0x58, 0x00, 0x0C, 0x6C, 0xE5, 0x84, 0x24, -0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0xC6, 0x5C, 0x45, 0x90, -0x48, 0xF5, 0x66, 0x90, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, -0xCF, 0x5C, 0x47, 0x90, 0x4A, 0xF5, 0x62, 0x90, 0x02, 0x80, 0x04, 0x3C, -0x80, 0xE5, 0x84, 0x24, 0x13, 0x58, 0x00, 0x0C, 0x10, 0x00, 0xA2, 0xAF, -0xFA, 0x5B, 0x00, 0x0C, 0x80, 0x0C, 0x04, 0x36, 0x02, 0x80, 0x03, 0x3C, -0x02, 0x80, 0x04, 0x3C, 0xD1, 0x5C, 0x65, 0x90, 0xCE, 0x5C, 0x86, 0x90, -0x02, 0x80, 0x04, 0x3C, 0x21, 0x38, 0x40, 0x00, 0x13, 0x58, 0x00, 0x0C, -0x9C, 0xE5, 0x84, 0x24, 0x02, 0x80, 0x03, 0x3C, 0x02, 0x80, 0x02, 0x3C, -0xD3, 0x5C, 0x66, 0x90, 0xD2, 0x5C, 0x45, 0x90, 0x02, 0x80, 0x04, 0x3C, -0x13, 0x58, 0x00, 0x0C, 0xB8, 0xE5, 0x84, 0x24, 0x60, 0x1B, 0x42, 0x26, -0x54, 0x41, 0x46, 0x8C, 0x58, 0x41, 0x45, 0x8C, 0x02, 0x80, 0x04, 0x3C, -0x13, 0x58, 0x00, 0x0C, 0xCC, 0xE5, 0x84, 0x24, 0x60, 0x1B, 0x46, 0x8E, -0x02, 0x80, 0x02, 0x3C, 0x49, 0xF5, 0x45, 0x90, 0x82, 0x31, 0x06, 0x00, -0x02, 0x80, 0x04, 0x3C, 0xEC, 0xE5, 0x84, 0x24, 0x13, 0x58, 0x00, 0x0C, -0x01, 0x00, 0xC6, 0x30, 0x02, 0x80, 0x04, 0x3C, 0x08, 0x00, 0x84, 0x24, -0x21, 0x28, 0x00, 0x00, 0x21, 0x30, 0x00, 0x00, 0x76, 0x39, 0x00, 0x0C, -0x21, 0x38, 0x00, 0x00, 0xF5, 0x64, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x24, 0x00, 0xBF, 0x8F, 0x20, 0x00, 0xB2, 0x8F, 0x1C, 0x00, 0xB1, 0x8F, -0x18, 0x00, 0xB0, 0x8F, 0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03, -0x28, 0x00, 0xBD, 0x27, 0xD8, 0x00, 0x24, 0x36, 0x00, 0x00, 0x40, 0xA0, -0xB0, 0x67, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0xB8, 0xFF, 0xBD, 0x27, -0x24, 0x00, 0xB1, 0xAF, 0x44, 0x00, 0xBF, 0xAF, 0x40, 0x00, 0xBE, 0xAF, -0x3C, 0x00, 0xB7, 0xAF, 0x38, 0x00, 0xB6, 0xAF, 0x34, 0x00, 0xB5, 0xAF, -0x30, 0x00, 0xB4, 0xAF, 0x2C, 0x00, 0xB3, 0xAF, 0x28, 0x00, 0xB2, 0xAF, -0x20, 0x00, 0xB0, 0xAF, 0x02, 0x80, 0x02, 0x3C, 0xC2, 0x5C, 0x42, 0x90, -0x25, 0xB0, 0x11, 0x3C, 0x58, 0x00, 0x25, 0x36, 0x10, 0x00, 0xA2, 0xAF, -0x4C, 0x81, 0x02, 0x3C, 0x00, 0xE0, 0x42, 0x34, 0x00, 0x00, 0xA2, 0xAC, -0xFF, 0xFF, 0x04, 0x24, 0x96, 0x01, 0x03, 0x24, 0x28, 0x28, 0x02, 0x24, -0x5C, 0x00, 0x26, 0x36, 0x60, 0x00, 0x27, 0x36, 0x64, 0x00, 0x28, 0x36, -0x8A, 0x00, 0x29, 0x36, 0x00, 0x00, 0xC3, 0xAC, 0x00, 0x00, 0xE4, 0xAC, -0x00, 0x00, 0x04, 0xAD, 0x00, 0x00, 0x22, 0xA5, 0x0E, 0x0E, 0x02, 0x3C, -0x09, 0x00, 0x03, 0x24, 0x0A, 0x0A, 0x42, 0x34, 0x89, 0x00, 0x2A, 0x36, -0x8C, 0x00, 0x2B, 0x36, 0x00, 0x00, 0x43, 0xA1, 0x90, 0x00, 0x2C, 0x36, -0x00, 0x00, 0x62, 0xAD, 0x13, 0x00, 0x03, 0x24, 0x40, 0x00, 0x02, 0x24, -0x91, 0x00, 0x2D, 0x36, 0x00, 0x00, 0x83, 0xA1, 0x92, 0x00, 0x2E, 0x36, -0x00, 0x00, 0xA2, 0xA1, 0x3A, 0x01, 0x03, 0x24, 0x21, 0x00, 0x02, 0x24, -0xB5, 0x00, 0x2F, 0x36, 0x00, 0x00, 0xC3, 0xA5, 0x00, 0x00, 0xE2, 0xA1, -0x10, 0x00, 0xA2, 0x8F, 0x12, 0x00, 0x03, 0x24, 0x87, 0x01, 0x43, 0x10, -0x07, 0x07, 0x02, 0x3C, 0x07, 0x07, 0x42, 0x34, 0xA0, 0x00, 0x24, 0x36, -0x00, 0x00, 0x82, 0xAC, 0xA4, 0x00, 0x25, 0x36, 0x00, 0x07, 0x03, 0x24, -0x00, 0xC0, 0x02, 0x3C, 0xA8, 0x00, 0x26, 0x36, 0x00, 0x00, 0xA3, 0xAC, -0x00, 0xC4, 0x42, 0x34, 0x02, 0x80, 0x03, 0x3C, 0x00, 0x00, 0xC2, 0xAC, -0x60, 0x1B, 0x62, 0x24, 0xAC, 0x1B, 0x45, 0x94, 0xAE, 0x1B, 0x46, 0x94, -0xAA, 0x1B, 0x42, 0x90, 0x02, 0x80, 0x03, 0x3C, 0x21, 0xB0, 0x07, 0x3C, -0x14, 0x00, 0xA2, 0xA3, 0xD1, 0x5C, 0x63, 0x90, 0x20, 0xB0, 0x02, 0x3C, -0xFF, 0xFF, 0x42, 0x34, 0x18, 0x00, 0xA3, 0xAF, 0x23, 0xB0, 0x03, 0x3C, -0xFF, 0xFF, 0x63, 0x34, 0x24, 0xB0, 0x08, 0x3C, 0xFF, 0x1F, 0x04, 0x3C, -0x25, 0xB0, 0x1E, 0x3C, 0xFF, 0xFF, 0x84, 0x34, 0x21, 0x38, 0xA7, 0x00, -0x21, 0x40, 0xC8, 0x00, 0x21, 0x28, 0xA2, 0x00, 0x21, 0x30, 0xC3, 0x00, -0x24, 0x40, 0x04, 0x01, 0x24, 0x28, 0xA4, 0x00, 0x24, 0x38, 0xE4, 0x00, -0x24, 0x30, 0xC4, 0x00, 0x35, 0x00, 0x02, 0x24, 0x20, 0x00, 0xC4, 0x37, -0x00, 0x00, 0x82, 0xA0, 0x22, 0x00, 0x03, 0x24, 0x09, 0x00, 0x02, 0x24, -0x03, 0x05, 0xC9, 0x37, 0x60, 0x05, 0xCA, 0x37, 0xAC, 0x00, 0xCB, 0x37, -0xF8, 0x00, 0xCC, 0x37, 0xB0, 0x00, 0xCD, 0x37, 0x08, 0x01, 0xCE, 0x37, -0xD8, 0x00, 0xCF, 0x37, 0x00, 0x00, 0x23, 0xA1, 0x00, 0x00, 0x42, 0xA1, -0x00, 0x00, 0x65, 0xAD, 0x00, 0x00, 0x87, 0xAD, 0x00, 0x00, 0xA6, 0xAD, -0x00, 0x00, 0xC8, 0xAD, 0x00, 0x00, 0xE0, 0xA1, 0x14, 0x00, 0xA3, 0x93, -0x25, 0xB0, 0x02, 0x3C, 0xB4, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0xA0, -0xB6, 0x00, 0xD1, 0x37, 0x04, 0x00, 0x02, 0x24, 0x25, 0xB0, 0x03, 0x3C, -0x00, 0x00, 0x22, 0xA2, 0xB9, 0x00, 0x63, 0x34, 0xFF, 0xFF, 0x02, 0x24, -0x00, 0x00, 0x62, 0xA0, 0x25, 0xB0, 0x03, 0x3C, 0x0F, 0x00, 0x02, 0x24, -0xBA, 0x00, 0x63, 0x34, 0x00, 0x00, 0x62, 0xA4, 0xDC, 0x00, 0xD4, 0x37, -0xFF, 0xCF, 0x03, 0x24, 0x3F, 0x3F, 0x02, 0x24, 0x16, 0x01, 0xD5, 0x37, -0x00, 0x00, 0x83, 0xAE, 0x00, 0x00, 0xA2, 0xA6, 0x2F, 0x00, 0x02, 0x3C, -0x00, 0x10, 0x03, 0x24, 0x17, 0x32, 0x42, 0x34, 0x18, 0x01, 0xD6, 0x37, -0x1A, 0x01, 0xD7, 0x37, 0xD0, 0x01, 0xD8, 0x37, 0x00, 0x00, 0xC0, 0xA6, -0x00, 0x00, 0xE3, 0xA6, 0x00, 0x00, 0x02, 0xAF, 0x5E, 0x00, 0x03, 0x3C, -0x25, 0xB0, 0x02, 0x3C, 0x17, 0x43, 0x63, 0x34, 0xD4, 0x01, 0x42, 0x34, -0x00, 0x00, 0x43, 0xAC, 0x10, 0x00, 0x02, 0x3C, 0x20, 0x53, 0x42, 0x34, -0xD8, 0x01, 0xDF, 0x37, 0x00, 0x00, 0xE2, 0xAF, 0x25, 0xB0, 0x02, 0x3C, -0x44, 0xA4, 0x03, 0x34, 0xDC, 0x01, 0x42, 0x34, 0x00, 0x00, 0x43, 0xAC, -0x25, 0xB0, 0x03, 0x3C, 0x1A, 0x06, 0x02, 0x24, 0xE0, 0x01, 0x63, 0x34, -0x00, 0x00, 0x62, 0xA4, 0xC2, 0x00, 0x02, 0x3C, 0x30, 0x30, 0x03, 0x24, -0x51, 0x10, 0x42, 0x34, 0xF4, 0x01, 0xD0, 0x37, 0xF8, 0x01, 0xD3, 0x37, -0x00, 0x00, 0x03, 0xA6, 0x00, 0x02, 0xD2, 0x37, 0x00, 0x00, 0x62, 0xAE, -0x26, 0x00, 0x03, 0x24, 0x03, 0x02, 0xD9, 0x37, 0x04, 0x00, 0x02, 0x24, -0x00, 0x00, 0x43, 0xA6, 0x00, 0x00, 0x22, 0xA3, 0x18, 0x00, 0xA3, 0x8F, -0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x60, 0x14, 0x36, 0x02, 0xC2, 0x37, -0x04, 0x00, 0x03, 0x24, 0x00, 0x00, 0x43, 0xA0, 0x02, 0x80, 0x0B, 0x3C, -0xC6, 0x5C, 0x66, 0x91, 0x25, 0xB0, 0x09, 0x3C, 0x34, 0x02, 0x23, 0x35, -0x80, 0x00, 0x02, 0x24, 0x00, 0x00, 0x62, 0xA4, 0x38, 0x02, 0x24, 0x35, -0x37, 0x02, 0x25, 0x35, 0x07, 0x00, 0x02, 0x24, 0x22, 0x00, 0x03, 0x24, -0x00, 0x00, 0x80, 0xA0, 0x00, 0x00, 0xA2, 0xA0, 0xE1, 0x00, 0xC3, 0x10, -0x1B, 0x1B, 0x02, 0x3C, 0x13, 0x13, 0x02, 0x3C, 0x13, 0x13, 0x42, 0x34, -0x60, 0x01, 0x23, 0x35, 0x64, 0x01, 0x24, 0x35, 0x68, 0x01, 0x25, 0x35, -0x7C, 0x01, 0x2A, 0x35, 0x6C, 0x01, 0x26, 0x35, 0x70, 0x01, 0x27, 0x35, -0x74, 0x01, 0x28, 0x35, 0x78, 0x01, 0x29, 0x35, 0x00, 0x00, 0x62, 0xAC, -0x00, 0x00, 0x82, 0xAC, 0x00, 0x00, 0xA2, 0xAC, 0x00, 0x00, 0xC2, 0xAC, -0x00, 0x00, 0xE2, 0xAC, 0x00, 0x00, 0x02, 0xAD, 0x00, 0x00, 0x22, 0xAD, -0x00, 0x00, 0x42, 0xAD, 0xC6, 0x5C, 0x65, 0x91, 0x25, 0xB0, 0x0C, 0x3C, -0x01, 0x00, 0x03, 0x3C, 0x80, 0x01, 0x82, 0x35, 0x08, 0x5F, 0x63, 0x34, -0x22, 0x00, 0x04, 0x24, 0x00, 0x00, 0x43, 0xAC, 0xE0, 0x00, 0xA4, 0x10, -0x0F, 0x1F, 0x02, 0x3C, 0x92, 0x00, 0x02, 0x24, 0xDD, 0x00, 0xA2, 0x10, -0x0F, 0x1F, 0x02, 0x3C, 0x0F, 0x10, 0x02, 0x3C, 0x00, 0xF0, 0x4F, 0x34, -0xF7, 0x01, 0x91, 0x35, 0x15, 0xF0, 0x4D, 0x34, 0x77, 0x00, 0x0E, 0x24, -0x84, 0x01, 0x87, 0x35, 0x88, 0x01, 0x88, 0x35, 0x10, 0xF0, 0x44, 0x34, -0x8C, 0x01, 0x85, 0x35, 0x05, 0xF0, 0x42, 0x34, 0x00, 0x00, 0xED, 0xAC, -0x90, 0x01, 0x83, 0x35, 0x00, 0x00, 0x04, 0xAD, 0x94, 0x01, 0x86, 0x35, -0x00, 0x00, 0xA2, 0xAC, 0xF5, 0x0F, 0x02, 0x24, 0x00, 0x00, 0x6F, 0xAC, -0x98, 0x01, 0x89, 0x35, 0x00, 0x00, 0xC2, 0xAC, 0x9C, 0x01, 0x8A, 0x35, -0xA0, 0x01, 0x8B, 0x35, 0xF0, 0x0F, 0x03, 0x24, 0xF6, 0x01, 0x8C, 0x35, -0x0D, 0x00, 0x02, 0x24, 0x00, 0x00, 0x23, 0xAD, 0x00, 0x00, 0x42, 0xAD, -0x00, 0x00, 0x6D, 0xAD, 0x02, 0x80, 0x02, 0x3C, 0x00, 0x00, 0x8E, 0xA1, -0x00, 0x00, 0x2E, 0xA2, 0xE3, 0x5C, 0x42, 0x90, 0x25, 0xB0, 0x1F, 0x3C, -0xA7, 0x01, 0xE7, 0x37, 0x1C, 0x00, 0xA2, 0xAF, 0xFF, 0xFF, 0x02, 0x24, -0x00, 0x00, 0xE2, 0xA0, 0x05, 0x06, 0x03, 0x3C, 0x25, 0xB0, 0x02, 0x3C, -0x03, 0x04, 0x63, 0x34, 0x0C, 0x00, 0x04, 0x24, 0xFF, 0xFF, 0x05, 0x24, -0x01, 0x02, 0x06, 0x3C, 0xC2, 0x01, 0x42, 0x34, 0xA8, 0x01, 0xE8, 0x37, -0xAC, 0x01, 0xE9, 0x37, 0xB0, 0x01, 0xEA, 0x37, 0xB4, 0x01, 0xEB, 0x37, -0xB8, 0x01, 0xEC, 0x37, 0xBC, 0x01, 0xED, 0x37, 0xC0, 0x01, 0xEE, 0x37, -0xC1, 0x01, 0xEF, 0x37, 0x00, 0x00, 0x05, 0xAD, 0x00, 0x00, 0x25, 0xAD, -0x00, 0x00, 0x46, 0xAD, 0x00, 0x00, 0x63, 0xAD, 0x00, 0x00, 0x86, 0xAD, -0x00, 0x00, 0xA3, 0xAD, 0x00, 0x00, 0xC4, 0xA1, 0x25, 0xB0, 0x03, 0x3C, -0x00, 0x00, 0xE4, 0xA1, 0x00, 0x00, 0x44, 0xA0, 0x25, 0xB0, 0x02, 0x3C, -0x0D, 0x00, 0x17, 0x24, 0x0E, 0x00, 0x18, 0x24, 0xC4, 0x01, 0x63, 0x34, -0xC5, 0x01, 0x42, 0x34, 0xC3, 0x01, 0xF1, 0x37, 0x00, 0x00, 0x37, 0xA2, -0xC6, 0x01, 0xF4, 0x37, 0x00, 0x00, 0x77, 0xA0, 0xC7, 0x01, 0xF5, 0x37, -0x00, 0x00, 0x58, 0xA0, 0x0F, 0x00, 0x02, 0x24, 0x00, 0x00, 0x98, 0xA2, -0x00, 0x00, 0xA2, 0xA2, 0x53, 0x01, 0x02, 0x3C, 0x46, 0x00, 0xF6, 0x37, -0x48, 0x00, 0xFE, 0x37, 0x0E, 0xF0, 0x42, 0x34, 0x00, 0x00, 0xC0, 0xA6, -0x00, 0x00, 0xC2, 0xAF, 0x1C, 0x00, 0xA3, 0x8F, 0x00, 0x00, 0x00, 0x00, -0x09, 0x00, 0x60, 0x10, 0x44, 0x00, 0xF7, 0x37, 0x00, 0x00, 0xE2, 0x8E, -0x00, 0x02, 0x03, 0x3C, 0x25, 0x10, 0x43, 0x00, 0x00, 0x00, 0xE2, 0xAE, -0x00, 0x00, 0xC3, 0x8F, 0x00, 0x04, 0x02, 0x3C, 0x25, 0x18, 0x62, 0x00, -0x00, 0x00, 0xC3, 0xAF, 0x4C, 0x00, 0xE2, 0x37, 0x00, 0x00, 0x40, 0xA0, -0x40, 0x00, 0xE4, 0x37, 0xBC, 0x00, 0x03, 0x24, 0xFC, 0x37, 0x02, 0x24, -0x00, 0x00, 0x83, 0xA4, 0x00, 0x00, 0x82, 0xA4, 0x02, 0x80, 0x02, 0x3C, -0xD8, 0x00, 0xE9, 0x37, 0x60, 0x1B, 0x43, 0x24, 0x00, 0x00, 0x26, 0x91, -0xAA, 0x1B, 0x64, 0x90, 0x2A, 0xB0, 0x05, 0x3C, 0xA0, 0xFF, 0x02, 0x24, -0x26, 0xB0, 0x07, 0x3C, 0x25, 0x30, 0xC2, 0x00, 0x30, 0x00, 0xAD, 0x34, -0x34, 0x00, 0xA8, 0x34, 0x01, 0x00, 0x83, 0x24, 0x38, 0x00, 0xA5, 0x34, -0x20, 0x20, 0x02, 0x24, 0x00, 0x00, 0x26, 0xA1, 0x79, 0x00, 0xEA, 0x34, -0x00, 0x00, 0x03, 0xA1, 0x00, 0x00, 0xA2, 0xA4, 0x40, 0x00, 0x03, 0x24, -0x16, 0x00, 0x02, 0x24, 0x00, 0x00, 0xA3, 0xA1, 0x94, 0x00, 0xEB, 0x37, -0x00, 0x00, 0x42, 0xA1, 0x98, 0x00, 0xEC, 0x37, 0x64, 0x00, 0x03, 0x24, -0x22, 0x00, 0x02, 0x24, 0x00, 0x00, 0x63, 0xA5, 0x7C, 0x00, 0xF4, 0x34, -0x00, 0x00, 0x82, 0xA5, 0x7A, 0x00, 0xE7, 0x34, 0x04, 0x00, 0x03, 0x24, -0x20, 0x0C, 0x02, 0x24, 0x00, 0x00, 0xE3, 0xA0, 0x9C, 0x00, 0xEE, 0x37, -0x00, 0x00, 0x82, 0xA6, 0x9A, 0x00, 0xEF, 0x37, 0x0A, 0x00, 0x03, 0x24, -0xFF, 0x03, 0x02, 0x24, 0x00, 0x00, 0xC3, 0xA1, 0x00, 0x00, 0xE2, 0xA5, -0x25, 0xB0, 0x02, 0x3C, 0x02, 0x00, 0x03, 0x24, 0x96, 0x00, 0x42, 0x34, -0x00, 0x00, 0x43, 0xA4, 0x89, 0x00, 0xF5, 0x37, 0xB7, 0x00, 0xF1, 0x37, -0x20, 0x00, 0x02, 0x24, 0x09, 0x00, 0x03, 0x24, 0x00, 0x00, 0x22, 0xA2, -0x00, 0x00, 0xA3, 0xA2, 0x00, 0x00, 0xE2, 0x96, 0xFF, 0xFD, 0x03, 0x24, -0x04, 0x02, 0x05, 0x24, 0x24, 0x10, 0x43, 0x00, 0x00, 0x00, 0xE2, 0xA6, -0x00, 0x00, 0xE3, 0x96, 0x29, 0xB0, 0x02, 0x3C, 0x40, 0x00, 0x42, 0x34, -0x00, 0x02, 0x63, 0x34, 0x00, 0x00, 0xE3, 0xA6, 0xFF, 0x00, 0x84, 0x30, -0x00, 0x00, 0x45, 0xA4, 0x7A, 0x1F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x44, 0x00, 0xBF, 0x8F, 0x40, 0x00, 0xBE, 0x8F, 0x3C, 0x00, 0xB7, 0x8F, -0x38, 0x00, 0xB6, 0x8F, 0x34, 0x00, 0xB5, 0x8F, 0x30, 0x00, 0xB4, 0x8F, -0x2C, 0x00, 0xB3, 0x8F, 0x28, 0x00, 0xB2, 0x8F, 0x24, 0x00, 0xB1, 0x8F, -0x20, 0x00, 0xB0, 0x8F, 0x01, 0x00, 0x02, 0x24, 0x08, 0x00, 0xE0, 0x03, -0x48, 0x00, 0xBD, 0x27, 0xFF, 0xFF, 0x03, 0x24, 0x00, 0x00, 0x43, 0xA0, -0x02, 0x80, 0x0B, 0x3C, 0xC6, 0x5C, 0x66, 0x91, 0x25, 0xB0, 0x09, 0x3C, -0x34, 0x02, 0x23, 0x35, 0x80, 0x00, 0x02, 0x24, 0x00, 0x00, 0x62, 0xA4, -0x38, 0x02, 0x24, 0x35, 0x37, 0x02, 0x25, 0x35, 0x07, 0x00, 0x02, 0x24, -0x22, 0x00, 0x03, 0x24, 0x00, 0x00, 0x80, 0xA0, 0x00, 0x00, 0xA2, 0xA0, -0x23, 0xFF, 0xC3, 0x14, 0x13, 0x13, 0x02, 0x3C, 0x1B, 0x1B, 0x02, 0x3C, -0x1B, 0x1B, 0x42, 0x34, 0x60, 0x01, 0x23, 0x35, 0x64, 0x01, 0x24, 0x35, -0x68, 0x01, 0x25, 0x35, 0x7C, 0x01, 0x2A, 0x35, 0x6C, 0x01, 0x26, 0x35, -0x70, 0x01, 0x27, 0x35, 0x74, 0x01, 0x28, 0x35, 0x78, 0x01, 0x29, 0x35, -0x00, 0x00, 0x62, 0xAC, 0x00, 0x00, 0x82, 0xAC, 0x00, 0x00, 0xA2, 0xAC, -0x00, 0x00, 0xC2, 0xAC, 0x00, 0x00, 0xE2, 0xAC, 0x00, 0x00, 0x02, 0xAD, -0x00, 0x00, 0x22, 0xAD, 0x00, 0x00, 0x42, 0xAD, 0xC6, 0x5C, 0x65, 0x91, -0x25, 0xB0, 0x0C, 0x3C, 0x01, 0x00, 0x03, 0x3C, 0x80, 0x01, 0x82, 0x35, -0x08, 0x5F, 0x63, 0x34, 0x22, 0x00, 0x04, 0x24, 0x00, 0x00, 0x43, 0xAC, -0x22, 0xFF, 0xA4, 0x14, 0x0F, 0x1F, 0x02, 0x3C, 0x00, 0xF0, 0x4F, 0x34, -0xF7, 0x01, 0x91, 0x35, 0x15, 0xF0, 0x4D, 0x34, 0xE7, 0x68, 0x00, 0x08, -0xFF, 0xFF, 0x0E, 0x24, 0x02, 0x80, 0x02, 0x3C, 0xC7, 0x5C, 0x44, 0x90, -0x06, 0x00, 0x03, 0x24, 0x0C, 0x00, 0x83, 0x10, 0xA0, 0x00, 0x24, 0x36, -0x00, 0x15, 0x02, 0x3C, 0x00, 0x07, 0x42, 0x34, 0x00, 0x00, 0x82, 0xAC, -0x04, 0xE0, 0x02, 0x3C, 0xA4, 0x00, 0x25, 0x36, 0x00, 0x22, 0x03, 0x24, -0xA8, 0x00, 0x26, 0x36, 0x00, 0xAE, 0x42, 0x34, 0x00, 0x00, 0xA3, 0xAC, -0x47, 0x68, 0x00, 0x08, 0x02, 0x80, 0x03, 0x3C, 0x00, 0x15, 0x02, 0x3C, -0x00, 0x07, 0x42, 0x34, 0x00, 0x00, 0x82, 0xAC, 0x04, 0xC0, 0x02, 0x3C, -0xA4, 0x00, 0x25, 0x36, 0x00, 0x22, 0x03, 0x24, 0xA8, 0x00, 0x26, 0x36, -0x00, 0xB0, 0x42, 0x34, 0x00, 0x00, 0xA3, 0xAC, 0x47, 0x68, 0x00, 0x08, -0x02, 0x80, 0x03, 0x3C, 0xE8, 0xFF, 0xBD, 0x27, 0x01, 0x00, 0x06, 0x24, -0xE8, 0x0E, 0x04, 0x24, 0x10, 0x00, 0xBF, 0xAF, 0xC1, 0x43, 0x00, 0x0C, -0x00, 0x10, 0x05, 0x3C, 0x60, 0x08, 0x04, 0x24, 0xE3, 0x43, 0x00, 0x0C, -0xFF, 0xFF, 0x05, 0x24, 0x20, 0x04, 0x06, 0x3C, 0x20, 0x04, 0xC6, 0x34, -0x25, 0x30, 0x46, 0x00, 0x60, 0x08, 0x04, 0x24, 0xC1, 0x43, 0x00, 0x0C, -0xFF, 0xFF, 0x05, 0x24, 0x70, 0x08, 0x04, 0x24, 0x00, 0x04, 0x05, 0x24, -0xC1, 0x43, 0x00, 0x0C, 0x21, 0x30, 0x00, 0x00, 0x00, 0x20, 0x06, 0x3C, -0x80, 0x00, 0xC6, 0x34, 0x80, 0x0C, 0x04, 0x24, 0xC1, 0x43, 0x00, 0x0C, -0xFF, 0xFF, 0x05, 0x24, 0x00, 0x40, 0x06, 0x3C, 0x10, 0x00, 0xBF, 0x8F, -0x00, 0x01, 0xC6, 0x34, 0x88, 0x0C, 0x04, 0x24, 0xFF, 0xFF, 0x05, 0x24, -0xC1, 0x43, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27, -0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x1C, 0x00, 0xBF, 0xAF, -0x10, 0x00, 0xB0, 0xAF, 0x21, 0x90, 0xA0, 0x00, 0x0A, 0x00, 0xA0, 0x10, -0x21, 0x88, 0x00, 0x00, 0x21, 0x80, 0x80, 0x00, 0x00, 0x00, 0x04, 0x8E, -0x04, 0x00, 0x05, 0x8E, 0x02, 0x00, 0x31, 0x26, 0x03, 0x5C, 0x00, 0x0C, -0x08, 0x00, 0x10, 0x26, 0x2B, 0x10, 0x32, 0x02, 0xF9, 0xFF, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x20, 0x00, 0xBD, 0x27, 0xE0, 0xFF, 0xBD, 0x27, 0x18, 0x00, 0xB2, 0xAF, -0x14, 0x00, 0xB1, 0xAF, 0x1C, 0x00, 0xBF, 0xAF, 0x10, 0x00, 0xB0, 0xAF, -0x21, 0x90, 0xA0, 0x00, 0x0B, 0x00, 0xA0, 0x10, 0x21, 0x88, 0x00, 0x00, -0x21, 0x80, 0x80, 0x00, 0x00, 0x00, 0x04, 0x8E, 0x04, 0x00, 0x05, 0x8E, -0x08, 0x00, 0x06, 0x8E, 0x03, 0x00, 0x31, 0x26, 0xC1, 0x43, 0x00, 0x0C, -0x0C, 0x00, 0x10, 0x26, 0x2B, 0x10, 0x32, 0x02, 0xF8, 0xFF, 0x40, 0x14, -0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x20, 0x00, 0xBD, 0x27, 0x21, 0x40, 0x80, 0x00, 0x21, 0x48, 0x00, 0x00, -0x1E, 0x00, 0xA0, 0x10, 0x21, 0x38, 0x00, 0x00, 0x80, 0x30, 0x07, 0x00, -0x21, 0x10, 0xC8, 0x00, 0x00, 0x00, 0x43, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x00, 0xF2, 0x63, 0x24, 0x1D, 0x00, 0x62, 0x2C, 0x12, 0x00, 0x40, 0x10, -0x80, 0x10, 0x03, 0x00, 0x02, 0x80, 0x03, 0x3C, 0x14, 0xE6, 0x63, 0x24, -0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x44, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0xC8, 0x00, -0xC0, 0x18, 0x09, 0x00, 0x23, 0x18, 0x69, 0x00, 0x08, 0x00, 0x44, 0x8C, -0x02, 0x80, 0x02, 0x3C, 0x80, 0x18, 0x03, 0x00, 0x60, 0x1B, 0x42, 0x24, -0x21, 0x18, 0x62, 0x00, 0x04, 0x1D, 0x64, 0xAC, 0x01, 0x00, 0x29, 0x25, -0x03, 0x00, 0xE7, 0x24, 0x2B, 0x10, 0xE5, 0x00, 0xE5, 0xFF, 0x40, 0x14, -0x80, 0x30, 0x07, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, -0x21, 0x10, 0xC8, 0x00, 0xC0, 0x18, 0x09, 0x00, 0x08, 0x00, 0x44, 0x8C, -0x23, 0x18, 0x69, 0x00, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, -0x80, 0x18, 0x03, 0x00, 0x03, 0x00, 0xE7, 0x24, 0x21, 0x18, 0x62, 0x00, -0x2B, 0x10, 0xE5, 0x00, 0xD6, 0xFF, 0x40, 0x14, 0x00, 0x1D, 0x64, 0xAC, -0x4D, 0x6A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0xC8, 0x00, -0xC0, 0x18, 0x09, 0x00, 0x08, 0x00, 0x44, 0x8C, 0x23, 0x18, 0x69, 0x00, -0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, 0x80, 0x18, 0x03, 0x00, -0x03, 0x00, 0xE7, 0x24, 0x21, 0x18, 0x62, 0x00, 0x2B, 0x10, 0xE5, 0x00, -0xC8, 0xFF, 0x40, 0x14, 0xFC, 0x1C, 0x64, 0xAC, 0x4D, 0x6A, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0xC8, 0x00, 0xC0, 0x18, 0x09, 0x00, -0x08, 0x00, 0x44, 0x8C, 0x23, 0x18, 0x69, 0x00, 0x02, 0x80, 0x02, 0x3C, -0x60, 0x1B, 0x42, 0x24, 0x80, 0x18, 0x03, 0x00, 0x03, 0x00, 0xE7, 0x24, -0x21, 0x18, 0x62, 0x00, 0x2B, 0x10, 0xE5, 0x00, 0xBA, 0xFF, 0x40, 0x14, -0xF8, 0x1C, 0x64, 0xAC, 0x4D, 0x6A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x21, 0x10, 0xC8, 0x00, 0xC0, 0x18, 0x09, 0x00, 0x08, 0x00, 0x44, 0x8C, -0x23, 0x18, 0x69, 0x00, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, -0x80, 0x18, 0x03, 0x00, 0x03, 0x00, 0xE7, 0x24, 0x21, 0x18, 0x62, 0x00, -0x2B, 0x10, 0xE5, 0x00, 0xAC, 0xFF, 0x40, 0x14, 0x08, 0x1D, 0x64, 0xAC, -0x4D, 0x6A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0xC8, 0x00, -0xC0, 0x18, 0x09, 0x00, 0x08, 0x00, 0x44, 0x8C, 0x23, 0x18, 0x69, 0x00, -0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, 0x80, 0x18, 0x03, 0x00, -0x03, 0x00, 0xE7, 0x24, 0x21, 0x18, 0x62, 0x00, 0x2B, 0x10, 0xE5, 0x00, -0x9E, 0xFF, 0x40, 0x14, 0xF4, 0x1C, 0x64, 0xAC, 0x4D, 0x6A, 0x00, 0x08, -0x00, 0x00, 0x00, 0x00, 0x21, 0x10, 0xC8, 0x00, 0xC0, 0x18, 0x09, 0x00, -0x08, 0x00, 0x44, 0x8C, 0x23, 0x18, 0x69, 0x00, 0x02, 0x80, 0x02, 0x3C, -0x60, 0x1B, 0x42, 0x24, 0x80, 0x18, 0x03, 0x00, 0x03, 0x00, 0xE7, 0x24, -0x21, 0x18, 0x62, 0x00, 0x2B, 0x10, 0xE5, 0x00, 0x90, 0xFF, 0x40, 0x14, -0xF0, 0x1C, 0x64, 0xAC, 0x4D, 0x6A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x25, 0xB0, 0x02, 0x3C, 0xFC, 0x37, 0x03, 0x24, 0x40, 0x00, 0x42, 0x34, -0x02, 0x80, 0x04, 0x3C, 0x00, 0x00, 0x43, 0xA4, 0xE8, 0xFF, 0xBD, 0x27, -0x5C, 0xD1, 0x84, 0x24, 0x10, 0x00, 0xBF, 0xAF, 0xFD, 0x69, 0x00, 0x0C, -0x74, 0x01, 0x05, 0x24, 0x02, 0x80, 0x02, 0x3C, 0xC6, 0x5C, 0x44, 0x90, -0x12, 0x00, 0x03, 0x24, 0x34, 0x00, 0x83, 0x10, 0x13, 0x00, 0x82, 0x28, -0x17, 0x00, 0x40, 0x14, 0x11, 0x00, 0x02, 0x24, 0x22, 0x00, 0x02, 0x24, -0x36, 0x00, 0x82, 0x10, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x04, 0x3C, -0xE4, 0xCD, 0x84, 0x24, 0x2C, 0x6A, 0x00, 0x0C, 0x54, 0x00, 0x05, 0x24, -0x02, 0x80, 0x02, 0x3C, 0x4A, 0xF5, 0x44, 0x90, 0x01, 0x00, 0x03, 0x24, -0x1A, 0x00, 0x83, 0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, -0xE4, 0xC8, 0x84, 0x24, 0xFD, 0x69, 0x00, 0x0C, 0x40, 0x01, 0x05, 0x24, -0x10, 0x00, 0xBF, 0x8F, 0x84, 0x08, 0x04, 0x24, 0xFF, 0x00, 0x05, 0x24, -0x58, 0x00, 0x06, 0x24, 0x35, 0x45, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, -0xED, 0xFF, 0x82, 0x14, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x04, 0x3C, -0x9C, 0xD0, 0x84, 0x24, 0x14, 0x6A, 0x00, 0x0C, 0x30, 0x00, 0x05, 0x24, -0x02, 0x80, 0x04, 0x3C, 0xE4, 0xCD, 0x84, 0x24, 0x2C, 0x6A, 0x00, 0x0C, -0x54, 0x00, 0x05, 0x24, 0x02, 0x80, 0x02, 0x3C, 0x4A, 0xF5, 0x44, 0x90, -0x01, 0x00, 0x03, 0x24, 0xE8, 0xFF, 0x83, 0x14, 0x00, 0x00, 0x00, 0x00, -0xDE, 0x69, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, -0xE4, 0xC8, 0x84, 0x24, 0xFD, 0x69, 0x00, 0x0C, 0x40, 0x01, 0x05, 0x24, -0x10, 0x00, 0xBF, 0x8F, 0x84, 0x08, 0x04, 0x24, 0xFF, 0x00, 0x05, 0x24, -0x58, 0x00, 0x06, 0x24, 0x35, 0x45, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, -0x02, 0x80, 0x04, 0x3C, 0xE8, 0xCF, 0x84, 0x24, 0x2D, 0x00, 0x05, 0x24, -0x14, 0x6A, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xD1, 0x6A, 0x00, 0x08, -0x02, 0x80, 0x04, 0x3C, 0x34, 0xCF, 0x84, 0x24, 0xE8, 0x6A, 0x00, 0x08, -0x2D, 0x00, 0x05, 0x24, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xB0, 0xAF, -0x50, 0x0C, 0x04, 0x24, 0xFF, 0x00, 0x05, 0x24, 0x02, 0x80, 0x10, 0x3C, -0x14, 0x00, 0xBF, 0xAF, 0x24, 0x45, 0x00, 0x0C, 0x60, 0x1B, 0x10, 0x26, -0x60, 0x1D, 0x02, 0xA2, 0x58, 0x0C, 0x04, 0x24, 0x24, 0x45, 0x00, 0x0C, -0xFF, 0x00, 0x05, 0x24, 0x61, 0x1D, 0x02, 0xA2, 0x60, 0x0C, 0x04, 0x24, -0x24, 0x45, 0x00, 0x0C, 0xFF, 0x00, 0x05, 0x24, 0x62, 0x1D, 0x02, 0xA2, -0x68, 0x0C, 0x04, 0x24, 0x24, 0x45, 0x00, 0x0C, 0xFF, 0x00, 0x05, 0x24, -0x63, 0x1D, 0x02, 0xA2, 0x38, 0x0C, 0x04, 0x24, 0x24, 0x45, 0x00, 0x0C, -0xFF, 0x00, 0x05, 0x24, 0xE8, 0x1C, 0x02, 0xA2, 0x34, 0x0C, 0x04, 0x24, -0x24, 0x45, 0x00, 0x0C, 0xFF, 0xFF, 0x05, 0x24, 0xEC, 0x1C, 0x02, 0xAE, -0x14, 0x00, 0xBF, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x05, 0x3C, -0x02, 0x80, 0x03, 0x3C, 0x38, 0xAD, 0x42, 0x24, 0xB0, 0x5D, 0x60, 0xAC, -0x10, 0x5D, 0xA2, 0xAC, 0x02, 0x80, 0x03, 0x3C, 0x00, 0x80, 0x02, 0x3C, -0xB4, 0x5D, 0x60, 0xA4, 0x10, 0x5D, 0xA4, 0x24, 0x64, 0x11, 0x42, 0x24, -0x02, 0x80, 0x03, 0x3C, 0xB6, 0x5D, 0x60, 0xA4, 0x08, 0x00, 0x82, 0xAC, -0x00, 0x80, 0x03, 0x3C, 0x00, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x06, 0x3C, -0x4C, 0x14, 0x42, 0x24, 0x80, 0x11, 0x63, 0x24, 0xB8, 0x5D, 0xC7, 0x24, -0x14, 0x00, 0x82, 0xAC, 0x10, 0x00, 0x83, 0xAC, 0x02, 0x80, 0x02, 0x3C, -0x02, 0x80, 0x03, 0x3C, 0xB8, 0x5D, 0xC0, 0xAC, 0x04, 0x00, 0xE0, 0xAC, -0xC0, 0x5D, 0x40, 0xA0, 0xC4, 0x5D, 0x60, 0xAC, 0x01, 0x80, 0x02, 0x3C, -0xB4, 0xC5, 0x42, 0x24, 0x7C, 0x00, 0x82, 0xAC, 0x00, 0x80, 0x03, 0x3C, -0x00, 0x80, 0x02, 0x3C, 0x68, 0x14, 0x63, 0x24, 0x08, 0x17, 0x42, 0x24, -0x20, 0x00, 0x83, 0xAC, 0x24, 0x00, 0x82, 0xAC, 0x00, 0x80, 0x03, 0x3C, -0x00, 0x80, 0x02, 0x3C, 0xB0, 0x19, 0x63, 0x24, 0x54, 0x1C, 0x42, 0x24, -0x28, 0x00, 0x83, 0xAC, 0x2C, 0x00, 0x82, 0xAC, 0x00, 0x80, 0x03, 0x3C, -0x01, 0x80, 0x02, 0x3C, 0x80, 0x2F, 0x63, 0x24, 0x10, 0x02, 0x42, 0x24, -0x30, 0x00, 0x83, 0xAC, 0x54, 0x00, 0x82, 0xAC, 0x00, 0x80, 0x03, 0x3C, -0x00, 0x80, 0x02, 0x3C, 0x58, 0x1F, 0x63, 0x24, 0x38, 0x21, 0x42, 0x24, -0x0C, 0x00, 0x83, 0xAC, 0x3C, 0x00, 0x82, 0xAC, 0x00, 0x80, 0x03, 0x3C, -0x00, 0x80, 0x02, 0x3C, 0x00, 0x03, 0x63, 0x24, 0xF8, 0x1E, 0x42, 0x24, -0x50, 0x00, 0x83, 0xAC, 0x08, 0x00, 0xE0, 0x03, 0x40, 0x00, 0x82, 0xAC, -0x25, 0xB0, 0x02, 0x3C, 0x08, 0x00, 0x42, 0x34, 0x00, 0x00, 0x43, 0x8C, -0x08, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x0E, 0x3C, -0x02, 0x80, 0x08, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, -0xF8, 0x03, 0x4D, 0x24, 0x00, 0x18, 0x6C, 0x24, 0x01, 0x00, 0x07, 0x24, -0x00, 0x00, 0xCB, 0x25, 0xFF, 0xFF, 0x0A, 0x24, 0x00, 0x04, 0x09, 0x25, -0x80, 0x1A, 0x07, 0x00, 0x21, 0x10, 0x6B, 0x00, 0x00, 0x00, 0x42, 0xAC, -0x90, 0x00, 0x4A, 0xAC, 0x00, 0x04, 0x04, 0x8D, 0x01, 0x00, 0xE7, 0x24, -0x08, 0x00, 0x45, 0x24, 0x21, 0x18, 0x6D, 0x00, 0x06, 0x00, 0xE6, 0x28, -0x04, 0x00, 0x82, 0xAC, 0x00, 0x00, 0x44, 0xAC, 0x04, 0x00, 0x49, 0xAC, -0x00, 0x04, 0x02, 0xAD, 0x8C, 0x00, 0x40, 0xAC, 0x6C, 0x00, 0xA3, 0xAC, -0xF0, 0xFF, 0xC0, 0x14, 0x68, 0x00, 0xAC, 0xAC, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0xC9, 0xAD, 0x06, 0x00, 0xA2, 0x2C, 0x13, 0x00, 0x40, 0x10, -0xFF, 0xFF, 0x07, 0x24, 0x02, 0x80, 0x02, 0x3C, 0x80, 0x1A, 0x05, 0x00, -0x00, 0x00, 0x42, 0x24, 0x0E, 0x00, 0xA0, 0x10, 0x21, 0x30, 0x62, 0x00, -0x90, 0x00, 0xC3, 0x8C, 0xFF, 0xFF, 0x02, 0x24, 0x0A, 0x00, 0x62, 0x14, -0x00, 0x00, 0x00, 0x00, 0x8C, 0x00, 0xC2, 0x8C, 0x00, 0x00, 0x00, 0x00, -0x06, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x24, -0x88, 0x00, 0xC4, 0xAC, 0x8C, 0x00, 0xC2, 0xAC, 0x90, 0x00, 0xC5, 0xAC, -0x21, 0x38, 0xA0, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0xE0, 0x00, -0xE0, 0xFF, 0xBD, 0x27, 0x02, 0x80, 0x02, 0x3C, 0x1C, 0x00, 0xBF, 0xAF, -0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, -0xC3, 0x5C, 0x46, 0x90, 0x25, 0xB0, 0x07, 0x3C, 0x02, 0x80, 0x02, 0x3C, -0xDB, 0xFF, 0x03, 0x24, 0x18, 0x03, 0xE4, 0x34, 0x27, 0x00, 0xE5, 0x34, -0x1C, 0xAE, 0x42, 0x24, 0x00, 0x00, 0x82, 0xAC, 0x00, 0x00, 0xA3, 0xA0, -0x02, 0x00, 0xC0, 0x10, 0x1B, 0x00, 0xE3, 0x34, 0x1F, 0x00, 0xE3, 0x34, -0x07, 0x00, 0x02, 0x24, 0x00, 0x00, 0x62, 0xA0, 0xF0, 0x42, 0x00, 0x0C, -0x21, 0x20, 0x00, 0x00, 0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x50, 0x24, -0x34, 0x1C, 0x04, 0x8E, 0xE3, 0x43, 0x00, 0x0C, 0x10, 0x00, 0x05, 0x24, -0x40, 0x1C, 0x04, 0x8E, 0x10, 0x00, 0x05, 0x3C, 0x01, 0x00, 0x06, 0x24, -0xC1, 0x43, 0x00, 0x0C, 0x21, 0x90, 0x40, 0x00, 0x3C, 0x1C, 0x04, 0x8E, -0x10, 0x00, 0x05, 0x24, 0xC1, 0x43, 0x00, 0x0C, 0x01, 0x00, 0x06, 0x24, -0x58, 0x1C, 0x04, 0x8E, 0x00, 0x04, 0x05, 0x24, 0xC1, 0x43, 0x00, 0x0C, -0x21, 0x30, 0x00, 0x00, 0x58, 0x1C, 0x04, 0x8E, 0x00, 0x08, 0x05, 0x24, -0xC1, 0x43, 0x00, 0x0C, 0x21, 0x30, 0x00, 0x00, 0x02, 0x80, 0x05, 0x3C, -0x78, 0xDA, 0xA5, 0x24, 0x21, 0x20, 0x00, 0x00, 0xC1, 0x45, 0x00, 0x0C, -0xCA, 0x00, 0x06, 0x24, 0x31, 0x00, 0x40, 0x10, 0x21, 0x18, 0x00, 0x00, -0x02, 0x80, 0x02, 0x3C, 0xCF, 0x5C, 0x43, 0x90, 0x01, 0x00, 0x11, 0x24, -0x53, 0x00, 0x71, 0x10, 0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x02, 0x3C, -0x4A, 0xF5, 0x43, 0x90, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x71, 0x10, -0x02, 0x80, 0x05, 0x3C, 0x34, 0x1C, 0x04, 0x8E, 0x21, 0x30, 0x40, 0x02, -0x10, 0x00, 0x05, 0x24, 0xC1, 0x43, 0x00, 0x0C, 0x02, 0x80, 0x11, 0x3C, -0xC6, 0x5C, 0x23, 0x92, 0x11, 0x00, 0x02, 0x24, 0x2A, 0x00, 0x62, 0x10, -0x00, 0x08, 0x04, 0x24, 0xF0, 0x42, 0x00, 0x0C, 0x01, 0x00, 0x04, 0x24, -0x34, 0x1C, 0x04, 0x8E, 0xE3, 0x43, 0x00, 0x0C, 0x10, 0x00, 0x05, 0x3C, -0x40, 0x1C, 0x04, 0x8E, 0x10, 0x00, 0x05, 0x3C, 0x01, 0x00, 0x06, 0x24, -0xC1, 0x43, 0x00, 0x0C, 0x21, 0x90, 0x40, 0x00, 0x3C, 0x1C, 0x04, 0x8E, -0x10, 0x00, 0x05, 0x24, 0xC1, 0x43, 0x00, 0x0C, 0x01, 0x00, 0x06, 0x24, -0x58, 0x1C, 0x04, 0x8E, 0x00, 0x04, 0x05, 0x24, 0xC1, 0x43, 0x00, 0x0C, -0x21, 0x30, 0x00, 0x00, 0x58, 0x1C, 0x04, 0x8E, 0x00, 0x08, 0x05, 0x24, -0xC1, 0x43, 0x00, 0x0C, 0x21, 0x30, 0x00, 0x00, 0x02, 0x80, 0x05, 0x3C, -0x20, 0xDA, 0xA5, 0x24, 0x01, 0x00, 0x04, 0x24, 0xC1, 0x45, 0x00, 0x0C, -0x16, 0x00, 0x06, 0x24, 0x08, 0x00, 0x40, 0x14, 0x21, 0x18, 0x00, 0x00, -0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, -0x10, 0x00, 0xB0, 0x8F, 0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x20, 0x00, 0xBD, 0x27, 0x34, 0x1C, 0x04, 0x8E, 0x21, 0x30, 0x40, 0x02, -0xC1, 0x43, 0x00, 0x0C, 0x10, 0x00, 0x05, 0x3C, 0x00, 0x08, 0x04, 0x24, -0x00, 0x01, 0x05, 0x3C, 0xC1, 0x43, 0x00, 0x0C, 0x01, 0x00, 0x06, 0x24, -0x00, 0x08, 0x04, 0x24, 0x00, 0x02, 0x05, 0x3C, 0xC1, 0x43, 0x00, 0x0C, -0x01, 0x00, 0x06, 0x24, 0xC6, 0x5C, 0x23, 0x92, 0x11, 0x00, 0x02, 0x24, -0x1D, 0x00, 0x62, 0x10, 0x00, 0x08, 0x04, 0x24, 0xF0, 0x42, 0x00, 0x0C, -0x21, 0x20, 0x00, 0x00, 0x0F, 0x00, 0x05, 0x3C, 0x0C, 0x00, 0x06, 0x3C, -0xFF, 0xFF, 0xA5, 0x34, 0x00, 0xB4, 0xC6, 0x34, 0x83, 0x45, 0x00, 0x0C, -0x08, 0x00, 0x04, 0x24, 0x1C, 0x00, 0xBF, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x01, 0x00, 0x03, 0x24, -0x21, 0x10, 0x60, 0x00, 0x08, 0x00, 0xE0, 0x03, 0x20, 0x00, 0xBD, 0x27, -0x10, 0xD9, 0xA5, 0x24, 0x21, 0x20, 0x00, 0x00, 0xC1, 0x45, 0x00, 0x0C, -0x16, 0x00, 0x06, 0x24, 0xC0, 0x6B, 0x00, 0x08, 0x02, 0x80, 0x02, 0x3C, -0x68, 0xD9, 0xA5, 0x24, 0x21, 0x20, 0x00, 0x00, 0xC1, 0x45, 0x00, 0x0C, -0x16, 0x00, 0x06, 0x24, 0xC4, 0x6B, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, -0x00, 0xFF, 0x05, 0x3C, 0xC1, 0x43, 0x00, 0x0C, 0x03, 0x00, 0x06, 0x24, -0x01, 0x6C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF, -0x02, 0x80, 0x02, 0x3C, 0x25, 0x59, 0x47, 0x90, 0x02, 0x80, 0x04, 0x3C, -0x02, 0x80, 0x05, 0x3C, 0x03, 0x00, 0x03, 0x24, 0x4E, 0x37, 0x84, 0x24, -0xB4, 0xDF, 0xA5, 0x24, 0x0F, 0x00, 0xE3, 0x10, 0x0D, 0x00, 0x06, 0x24, -0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, 0x4E, 0x37, 0x84, 0x24, -0x64, 0xDF, 0xA5, 0x24, 0xF4, 0x54, 0x00, 0x0C, 0x0D, 0x00, 0x06, 0x24, -0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, 0x10, 0x00, 0xBF, 0x8F, -0x5B, 0x37, 0x84, 0x24, 0x74, 0xDF, 0xA5, 0x24, 0x0D, 0x00, 0x06, 0x24, -0xF4, 0x54, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, 0xF4, 0x54, 0x00, 0x0C, -0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, 0x02, 0x80, 0x05, 0x3C, -0x10, 0x00, 0xBF, 0x8F, 0x5B, 0x37, 0x84, 0x24, 0xA4, 0xDF, 0xA5, 0x24, -0x0D, 0x00, 0x06, 0x24, 0xF4, 0x54, 0x00, 0x08, 0x18, 0x00, 0xBD, 0x27, -0xE0, 0xFF, 0xBD, 0x27, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, -0x02, 0x80, 0x05, 0x3C, 0x02, 0x80, 0x10, 0x3C, 0x02, 0x80, 0x11, 0x3C, -0x60, 0x1B, 0x31, 0x26, 0x2C, 0x59, 0x04, 0x26, 0xA0, 0xDD, 0xA5, 0x24, -0x34, 0x00, 0x06, 0x24, 0x18, 0x00, 0xBF, 0xAF, 0xF4, 0x54, 0x00, 0x0C, -0x2C, 0x59, 0x10, 0x26, 0x24, 0x6C, 0x00, 0x0C, 0x00, 0x3E, 0x30, 0xAE, -0x02, 0x00, 0x10, 0x24, 0x02, 0x80, 0x04, 0x3C, 0x00, 0x80, 0x06, 0x3C, -0x9C, 0x39, 0x30, 0xA2, 0xE8, 0x54, 0x84, 0x24, 0x98, 0x5B, 0xC6, 0x24, -0xCF, 0x20, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, -0x01, 0x80, 0x06, 0x3C, 0xB8, 0x39, 0x30, 0xA2, 0x04, 0x55, 0x84, 0x24, -0x90, 0x3B, 0xC6, 0x24, 0xCF, 0x20, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, -0x02, 0x80, 0x04, 0x3C, 0x01, 0x80, 0x06, 0x3C, 0xD4, 0x39, 0x30, 0xA2, -0x20, 0x55, 0x84, 0x24, 0x08, 0x39, 0xC6, 0x24, 0xCF, 0x20, 0x00, 0x0C, -0x21, 0x28, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, 0x01, 0x80, 0x06, 0x3C, -0xF0, 0x39, 0x30, 0xA2, 0x3C, 0x55, 0x84, 0x24, 0x74, 0x44, 0xC6, 0x24, -0xCF, 0x20, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, 0x02, 0x80, 0x04, 0x3C, -0x00, 0x80, 0x06, 0x3C, 0x0C, 0x3A, 0x30, 0xA2, 0x58, 0x55, 0x84, 0x24, -0xFC, 0x5A, 0xC6, 0x24, 0xCF, 0x20, 0x00, 0x0C, 0x21, 0x28, 0x00, 0x00, -0x09, 0x00, 0x02, 0x24, 0xB8, 0x40, 0x22, 0xA2, 0xC7, 0x3D, 0x20, 0xA2, -0x3A, 0x41, 0x20, 0xA2, 0xC8, 0x3D, 0x20, 0xA6, 0x18, 0x00, 0xBF, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x20, 0x00, 0xBD, 0x27, 0x03, 0x80, 0x05, 0x3C, 0x00, 0x80, 0xA5, 0x24, -0xD8, 0xFF, 0xBD, 0x27, 0x40, 0x10, 0x0D, 0x3C, 0xFF, 0xFF, 0xA5, 0x30, -0x02, 0x80, 0x02, 0x3C, 0x60, 0x1B, 0x42, 0x24, 0x20, 0x00, 0xBE, 0xAF, -0x25, 0xF0, 0xAD, 0x00, 0x2C, 0x38, 0x5E, 0xAC, 0x00, 0x01, 0xDE, 0x27, -0x38, 0x38, 0x5E, 0xAC, 0x00, 0x01, 0xDE, 0x27, 0x1C, 0x00, 0xB7, 0xAF, -0x18, 0x00, 0xB6, 0xAF, 0x14, 0x00, 0xB5, 0xAF, 0x10, 0x00, 0xB4, 0xAF, -0x0C, 0x00, 0xB3, 0xAF, 0x08, 0x00, 0xB2, 0xAF, 0x04, 0x00, 0xB1, 0xAF, -0x00, 0x00, 0xB0, 0xAF, 0x44, 0x38, 0x5E, 0xAC, 0x00, 0x01, 0xDE, 0x27, -0x50, 0x38, 0x5E, 0xAC, 0xAA, 0x1B, 0x44, 0x90, 0x00, 0x01, 0xDE, 0x27, -0x5C, 0x38, 0x5E, 0xAC, 0x00, 0x01, 0xDE, 0x27, 0x68, 0x38, 0x5E, 0xAC, -0x20, 0xB0, 0x06, 0x3C, 0x38, 0x38, 0x48, 0x8C, 0x44, 0x38, 0x49, 0x8C, -0x50, 0x38, 0x4A, 0x8C, 0x5C, 0x38, 0x4B, 0x8C, 0x68, 0x38, 0x4C, 0x8C, -0x00, 0x22, 0x04, 0x00, 0x00, 0x01, 0xC7, 0x34, 0xFF, 0x1F, 0x03, 0x3C, -0x00, 0x01, 0xDE, 0x27, 0xFF, 0xFF, 0x63, 0x34, 0x21, 0x38, 0x87, 0x00, -0x21, 0x20, 0x86, 0x00, 0x24, 0x38, 0xE3, 0x00, 0x20, 0x10, 0x06, 0x3C, -0x24, 0x20, 0x83, 0x00, 0x74, 0x38, 0x5E, 0xAC, 0x21, 0x70, 0xC0, 0x03, -0x25, 0x28, 0xAD, 0x00, 0x25, 0xB0, 0x0F, 0x3C, 0x00, 0x01, 0xDE, 0x27, -0x28, 0x38, 0x45, 0xAC, 0x34, 0x38, 0x48, 0xAC, 0x40, 0x38, 0x49, 0xAC, -0x4C, 0x38, 0x4A, 0xAC, 0xEC, 0x37, 0x44, 0xAC, 0x58, 0x38, 0x4B, 0xAC, -0xF8, 0x37, 0x47, 0xAC, 0x64, 0x38, 0x4C, 0xAC, 0xAC, 0x00, 0xE3, 0x35, -0xC0, 0x37, 0x46, 0xAC, 0xBC, 0x37, 0x46, 0xAC, 0xCC, 0x37, 0x46, 0xAC, -0xC8, 0x37, 0x46, 0xAC, 0x80, 0x38, 0x5E, 0xAC, 0xF0, 0x37, 0x44, 0xAC, -0xFC, 0x37, 0x47, 0xAC, 0x70, 0x38, 0x4E, 0xAC, 0xD8, 0x37, 0x46, 0xAC, -0xD4, 0x37, 0x46, 0xAC, 0xE4, 0x37, 0x46, 0xAC, 0xE0, 0x37, 0x46, 0xAC, -0x08, 0x38, 0x46, 0xAC, 0x04, 0x38, 0x46, 0xAC, 0xAC, 0x1B, 0x47, 0x94, -0x00, 0x02, 0xDE, 0x27, 0x00, 0x00, 0x69, 0x8C, 0x21, 0x10, 0x05, 0x3C, -0x98, 0x38, 0x5E, 0xAC, 0xB0, 0x00, 0xE3, 0x35, 0x00, 0x00, 0x79, 0x8C, -0x80, 0x38, 0x54, 0x8C, 0x00, 0x80, 0xA4, 0x34, 0x23, 0x10, 0x0D, 0x3C, -0x22, 0x10, 0x10, 0x3C, 0x02, 0x80, 0x16, 0x3C, 0x02, 0x80, 0x17, 0x3C, -0x02, 0x80, 0x18, 0x3C, 0x02, 0x80, 0x13, 0x3C, 0x23, 0x20, 0x87, 0x00, -0x02, 0x80, 0x03, 0x3C, 0x24, 0x10, 0x07, 0x3C, 0xC0, 0x54, 0x68, 0x24, -0xCC, 0x38, 0x44, 0xAC, 0x21, 0xA8, 0xC0, 0x03, 0xC8, 0x54, 0xCE, 0x26, -0x00, 0x04, 0xDE, 0x27, 0xD0, 0x54, 0xEA, 0x26, 0xD8, 0x54, 0x0B, 0x27, -0xE0, 0x54, 0x6C, 0x26, 0x00, 0x04, 0xB1, 0x35, 0x01, 0x00, 0x29, 0x25, -0x00, 0x40, 0x12, 0x36, 0x00, 0x01, 0xEF, 0x35, 0x01, 0x00, 0x03, 0x24, -0x02, 0x80, 0x04, 0x3C, 0x7C, 0x38, 0x54, 0xAC, 0x85, 0x38, 0x43, 0xA0, -0x94, 0x38, 0x55, 0xAC, 0xFC, 0x38, 0x51, 0xAC, 0xC0, 0x38, 0x49, 0xAC, -0xF0, 0x38, 0x52, 0xAC, 0xE4, 0x38, 0x59, 0xAC, 0x00, 0x00, 0xE7, 0xAD, -0xE0, 0x38, 0x47, 0xAC, 0x00, 0x39, 0x46, 0xAC, 0x14, 0x38, 0x46, 0xAC, -0x10, 0x38, 0x46, 0xAC, 0x9E, 0x38, 0x40, 0xA4, 0x9D, 0x38, 0x40, 0xA0, -0x9C, 0x38, 0x40, 0xA0, 0xF4, 0x38, 0x4D, 0xAC, 0xF8, 0x38, 0x4D, 0xAC, -0xB8, 0x38, 0x45, 0xAC, 0xBC, 0x38, 0x45, 0xAC, 0xC4, 0x38, 0x45, 0xAC, -0xC8, 0x38, 0x45, 0xAC, 0xE8, 0x38, 0x50, 0xAC, 0xEC, 0x38, 0x50, 0xAC, -0xDC, 0x38, 0x47, 0xAC, 0x04, 0x39, 0x46, 0xAC, 0x10, 0x39, 0x5E, 0xAC, -0x0C, 0x39, 0x5E, 0xAC, 0x04, 0x00, 0x4A, 0xAD, 0xC8, 0x54, 0xCE, 0xAE, -0x04, 0x00, 0x6B, 0xAD, 0xD0, 0x54, 0xEA, 0xAE, 0x04, 0x00, 0x8C, 0xAD, -0xD8, 0x54, 0x0B, 0xAF, 0x04, 0x00, 0x08, 0xAD, 0xE0, 0x54, 0x6C, 0xAE, -0xC0, 0x54, 0x88, 0xAC, 0x04, 0x00, 0xCE, 0xAD, 0x02, 0x80, 0x04, 0x3C, -0x18, 0x18, 0x83, 0x24, 0x02, 0x80, 0x05, 0x3C, 0x00, 0x18, 0xA2, 0x24, -0x18, 0x18, 0x83, 0xAC, 0x02, 0x80, 0x04, 0x3C, 0x04, 0x00, 0x02, 0xAD, -0x00, 0x18, 0xA8, 0xAC, 0xC0, 0x54, 0x82, 0xAC, 0x21, 0x48, 0x60, 0x00, -0x08, 0x00, 0x5E, 0xAC, 0x01, 0x00, 0x07, 0x24, 0x04, 0x00, 0x63, 0xAC, -0x00, 0x01, 0xDE, 0x27, 0x04, 0x00, 0x48, 0xAC, 0x10, 0x00, 0x40, 0xAC, -0x21, 0x40, 0x40, 0x00, 0x21, 0x18, 0xC0, 0x01, 0x21, 0x28, 0x00, 0x00, -0x0F, 0x00, 0x06, 0x24, 0x21, 0x20, 0xA9, 0x00, 0x21, 0x10, 0xA8, 0x00, -0xFF, 0xFF, 0xC6, 0x24, 0x20, 0x00, 0x5E, 0xAC, 0x28, 0x00, 0x47, 0xAC, -0x18, 0x00, 0xA5, 0x24, 0x00, 0x00, 0x8E, 0xAC, 0x04, 0x00, 0x83, 0xAC, -0x00, 0x00, 0x64, 0xAC, 0x00, 0x01, 0xDE, 0x27, 0xF5, 0xFF, 0xC1, 0x04, -0x21, 0x18, 0x80, 0x00, 0x02, 0x80, 0x02, 0x3C, 0xD0, 0x54, 0x48, 0x24, -0x02, 0x80, 0x03, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0x04, 0x00, 0x07, 0x8D, -0x98, 0x19, 0x4B, 0x24, 0x04, 0x00, 0xC4, 0xAD, 0x00, 0x18, 0x6A, 0x24, -0x02, 0x00, 0x09, 0x24, 0x21, 0x28, 0x00, 0x00, 0x0F, 0x00, 0x06, 0x24, -0x21, 0x20, 0xAB, 0x00, 0x21, 0x10, 0xAA, 0x00, 0xFF, 0xFF, 0xC6, 0x24, -0xA0, 0x01, 0x5E, 0xAC, 0xA8, 0x01, 0x49, 0xAC, 0x18, 0x00, 0xA5, 0x24, -0x00, 0x00, 0x88, 0xAC, 0x04, 0x00, 0x87, 0xAC, 0x00, 0x00, 0xE4, 0xAC, -0x00, 0x02, 0xDE, 0x27, 0xF5, 0xFF, 0xC1, 0x04, 0x21, 0x38, 0x80, 0x00, -0x02, 0x80, 0x02, 0x3C, 0xD8, 0x54, 0x49, 0x24, 0x02, 0x80, 0x03, 0x3C, -0x02, 0x80, 0x02, 0x3C, 0x04, 0x00, 0x25, 0x8D, 0x18, 0x1B, 0x4B, 0x24, -0x04, 0x00, 0x04, 0xAD, 0x00, 0x18, 0x6A, 0x24, 0x03, 0x00, 0x07, 0x24, -0x21, 0x20, 0x00, 0x00, 0x01, 0x00, 0x06, 0x24, 0x21, 0x40, 0x8B, 0x00, -0x21, 0x10, 0x8A, 0x00, 0xFF, 0xFF, 0xC6, 0x24, 0x20, 0x03, 0x5E, 0xAC, -0x28, 0x03, 0x47, 0xAC, 0x18, 0x00, 0x84, 0x24, 0x00, 0x00, 0x09, 0xAD, -0x04, 0x00, 0x05, 0xAD, 0x00, 0x00, 0xA8, 0xAC, 0x00, 0x08, 0xDE, 0x27, -0xF5, 0xFF, 0xC1, 0x04, 0x21, 0x28, 0x00, 0x01, 0x02, 0x80, 0x05, 0x3C, -0x02, 0x80, 0x03, 0x3C, 0xE0, 0x54, 0xA5, 0x24, 0x00, 0x18, 0x63, 0x24, -0x04, 0x00, 0xA6, 0x8C, 0x1C, 0x00, 0xB7, 0x8F, 0x50, 0x03, 0x7E, 0xAC, -0x18, 0x00, 0xB6, 0x8F, 0x20, 0x00, 0xBE, 0x8F, 0x14, 0x00, 0xB5, 0x8F, -0x10, 0x00, 0xB4, 0x8F, 0x0C, 0x00, 0xB3, 0x8F, 0x08, 0x00, 0xB2, 0x8F, -0x04, 0x00, 0xB1, 0x8F, 0x00, 0x00, 0xB0, 0x8F, 0x02, 0x80, 0x07, 0x3C, -0x48, 0x1B, 0xE4, 0x24, 0x04, 0x00, 0x02, 0x24, 0x28, 0x00, 0xBD, 0x27, -0x04, 0x00, 0x28, 0xAD, 0x04, 0x00, 0xA4, 0xAC, 0x58, 0x03, 0x62, 0xAC, -0x48, 0x1B, 0xE5, 0xAC, 0x04, 0x00, 0x86, 0xAC, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0xC4, 0xAC, 0xFA, 0x63, 0x00, 0x6A, 0x09, 0xD1, 0x0A, 0x62, -0x08, 0xD0, 0x06, 0xD2, 0x7D, 0x67, 0x18, 0xA3, 0x10, 0xF0, 0x02, 0x69, -0x00, 0xF4, 0x20, 0x31, 0x63, 0xF3, 0x00, 0x49, 0x00, 0x18, 0xDB, 0x5C, -0x06, 0x94, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x10, 0xF0, -0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0x5C, 0xF4, 0x00, 0x4A, 0xDC, 0xF3, -0x0C, 0x4B, 0x7B, 0x9B, 0x5B, 0x9A, 0x00, 0x6D, 0x69, 0xE2, 0x46, 0x32, -0xC4, 0xF4, 0x54, 0xD9, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, -0xBC, 0xF3, 0x0C, 0x4A, 0x5B, 0xA2, 0x01, 0xF6, 0x01, 0x6B, 0x6B, 0xEB, -0x50, 0x32, 0xE4, 0xF4, 0x5C, 0xD9, 0xE4, 0xF4, 0x58, 0xD9, 0x04, 0xF5, -0x48, 0x99, 0x6C, 0xEA, 0x00, 0xF2, 0x00, 0x6B, 0x6D, 0xEA, 0x04, 0xF5, -0x48, 0xD9, 0xA9, 0xE1, 0x01, 0x4D, 0x1D, 0x55, 0x04, 0xF5, 0x0C, 0xC2, -0x44, 0xF5, 0x06, 0xC2, 0x24, 0xF5, 0x09, 0xC2, 0xF6, 0x61, 0x00, 0x6A, -0x64, 0xF5, 0x44, 0xD9, 0x06, 0x94, 0x7F, 0x49, 0x15, 0x49, 0x01, 0x4C, -0x20, 0x54, 0x06, 0xD4, 0xBF, 0x61, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, -0xA0, 0x35, 0x10, 0xF0, 0x02, 0x69, 0x00, 0xF4, 0x20, 0x31, 0x10, 0xF0, -0x02, 0x68, 0x00, 0xF4, 0x00, 0x30, 0x10, 0xF0, 0x02, 0x6F, 0x00, 0xF4, -0xE0, 0x37, 0x10, 0xF0, 0x02, 0x6E, 0x00, 0xF4, 0xC0, 0x36, 0x06, 0xD2, -0x63, 0xF3, 0x00, 0x4D, 0x5C, 0xF4, 0x00, 0x49, 0xDC, 0xF3, 0x0C, 0x48, -0xBC, 0xF3, 0x0C, 0x4F, 0x9C, 0xF3, 0x0C, 0x4E, 0x06, 0x93, 0x68, 0x32, -0x2D, 0xE2, 0x60, 0x9B, 0xB1, 0xE2, 0x09, 0xE2, 0xC0, 0xF5, 0x74, 0xDC, -0x40, 0x9A, 0x60, 0xF5, 0x40, 0xDC, 0x06, 0x94, 0xE9, 0xE4, 0x40, 0xA2, -0xAD, 0xE4, 0x00, 0xF5, 0x44, 0xC3, 0xC9, 0xE4, 0x40, 0xA2, 0x01, 0x4C, -0x1D, 0x54, 0x20, 0xF5, 0x5E, 0xC3, 0x06, 0xD4, 0xE7, 0x61, 0x10, 0xF0, -0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, -0x60, 0x33, 0x00, 0x6D, 0x10, 0xF0, 0x02, 0x69, 0x00, 0xF4, 0x20, 0x31, -0x7C, 0xF2, 0x08, 0x4A, 0x1C, 0xF1, 0x08, 0x4B, 0x06, 0xD5, 0x63, 0xF3, -0x00, 0x49, 0x2A, 0x65, 0x0B, 0x65, 0x05, 0x67, 0x89, 0x67, 0x00, 0x6D, -0x3D, 0xE0, 0x99, 0xE0, 0xAD, 0xE6, 0x40, 0xA3, 0xB1, 0xE7, 0x01, 0x4D, -0xA0, 0xF3, 0x48, 0xC4, 0x80, 0xF0, 0x51, 0xA3, 0x05, 0x55, 0x20, 0xF4, -0x59, 0xC4, 0xF4, 0x61, 0x06, 0x95, 0x48, 0x67, 0x05, 0x48, 0x4D, 0xE5, -0x40, 0xA3, 0x31, 0xE5, 0x01, 0x4D, 0xC0, 0xF4, 0x4A, 0xC4, 0x5D, 0xA3, -0x1D, 0x55, 0xE0, 0xF4, 0x47, 0xC4, 0x06, 0xD5, 0xE1, 0x61, 0x9D, 0x67, -0x52, 0x6A, 0x50, 0xC4, 0x41, 0x6A, 0x51, 0xC4, 0x00, 0x6B, 0x4D, 0x6A, -0x52, 0xC4, 0x73, 0xC4, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, -0x7E, 0xF5, 0x00, 0x4C, 0xE0, 0xF3, 0x08, 0x6A, 0x43, 0xDC, 0xBD, 0x67, -0x01, 0x6A, 0x10, 0xF0, 0x01, 0x6E, 0x00, 0xF4, 0xC0, 0x36, 0x54, 0xC4, -0x30, 0xF7, 0x01, 0x4E, 0x00, 0x1C, 0xCF, 0x20, 0x10, 0x4D, 0x0A, 0x97, -0x09, 0x91, 0x08, 0x90, 0x00, 0xEF, 0x06, 0x63, 0xC9, 0xF7, 0x1B, 0x6C, -0xF1, 0x63, 0x8B, 0xEC, 0x1B, 0xD1, 0x80, 0x31, 0x20, 0x31, 0xE1, 0xF6, -0x80, 0x41, 0x1C, 0x62, 0x00, 0x1C, 0xFA, 0x5B, 0x1A, 0xD0, 0xD1, 0xF6, -0x8C, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x07, 0xD2, 0x71, 0xF6, 0x80, 0x41, -0x00, 0x1C, 0xFA, 0x5B, 0x08, 0xD2, 0x71, 0xF6, 0x84, 0x41, 0x00, 0x1C, -0xFA, 0x5B, 0x09, 0xD2, 0x71, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xFA, 0x5B, -0x0A, 0xD2, 0x71, 0xF6, 0x8C, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x0B, 0xD2, -0x81, 0xF6, 0x80, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x0C, 0xD2, 0x81, 0xF6, -0x84, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x0D, 0xD2, 0x81, 0xF6, 0x88, 0x41, -0x00, 0x1C, 0xFA, 0x5B, 0x0E, 0xD2, 0x81, 0xF6, 0x8C, 0x41, 0xE7, 0xF7, -0x0E, 0x68, 0x00, 0x1C, 0xFA, 0x5B, 0x0F, 0xD2, 0xD1, 0xF6, 0x80, 0x41, -0x10, 0xD2, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x30, 0xD1, 0xF6, 0x84, 0x41, -0x00, 0x30, 0x00, 0x1C, 0xFA, 0x5B, 0x11, 0xD2, 0xD1, 0xF6, 0x88, 0x41, -0x00, 0x1C, 0xFA, 0x5B, 0x12, 0xD2, 0xB0, 0x67, 0xE1, 0xF6, 0x80, 0x41, -0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x13, 0xD2, 0xB0, 0x67, -0xD1, 0xF6, 0x8C, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, -0x00, 0x65, 0xB0, 0x67, 0x71, 0xF6, 0x80, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, -0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xB0, 0x67, 0x71, 0xF6, 0x84, 0x41, -0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xB0, 0x67, -0x71, 0xF6, 0x88, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, -0x00, 0x65, 0xB0, 0x67, 0x71, 0xF6, 0x8C, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, -0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xB0, 0x67, 0x81, 0xF6, 0x80, 0x41, -0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xB0, 0x67, -0x81, 0xF6, 0x84, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, -0x00, 0x65, 0xB0, 0x67, 0x81, 0xF6, 0x88, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, -0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xB0, 0x67, 0x81, 0xF6, 0x8C, 0x41, -0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xB0, 0x67, -0xD1, 0xF6, 0x80, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, -0x00, 0x65, 0xB0, 0x67, 0xD1, 0xF6, 0x84, 0x41, 0xF2, 0xF2, 0x1B, 0x4D, -0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0xB0, 0x67, 0xD1, 0xF6, 0x88, 0x41, -0xF2, 0xF2, 0x1B, 0x4D, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x00, 0x6A, -0x04, 0xD2, 0xFF, 0x6A, 0x01, 0x4A, 0x40, 0x30, 0x00, 0xF5, 0x00, 0x6A, -0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x15, 0xD2, 0x01, 0xF0, 0x00, 0x6A, -0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0x00, 0x30, 0x16, 0xD2, 0x21, 0xF0, -0x80, 0x41, 0x00, 0xF1, 0xA0, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, -0x21, 0xF0, 0x88, 0x41, 0x00, 0xF1, 0xA0, 0x40, 0x00, 0x1C, 0xDD, 0x5B, -0x00, 0x65, 0xA0, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x2A, 0xF4, 0x10, 0x4D, -0x01, 0xF4, 0x84, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x00, 0x1C, -0x5B, 0x1F, 0x05, 0x6C, 0x01, 0xF0, 0x00, 0x6D, 0xA0, 0x35, 0x7F, 0x4D, -0x01, 0xF4, 0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x65, 0x4D, 0x00, 0x1C, -0x5B, 0x1F, 0x05, 0x6C, 0x8F, 0xF7, 0x00, 0x6D, 0xAB, 0xED, 0xA0, 0x35, -0x21, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0xA0, 0x35, 0x00, 0x1C, -0x5B, 0x1F, 0x05, 0x6C, 0x00, 0xF2, 0x14, 0x6D, 0xA0, 0x35, 0xA0, 0x35, -0x00, 0xF1, 0x02, 0x4D, 0x41, 0xF6, 0x80, 0x41, 0x00, 0x1C, 0xDD, 0x5B, -0x00, 0x65, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0x0D, 0xF0, 0x16, 0x6D, -0xA0, 0x35, 0xA0, 0x35, 0xC0, 0xF4, 0x02, 0x4D, 0x41, 0xF6, 0x84, 0x41, -0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, -0xC5, 0xF0, 0x11, 0x6D, 0x41, 0xF6, 0x8C, 0x41, 0x00, 0x1C, 0xDD, 0x5B, -0x00, 0x65, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0x00, 0xF2, 0x14, 0x6D, -0xA0, 0x35, 0xA0, 0x35, 0x00, 0xF1, 0x02, 0x4D, 0x61, 0xF6, 0x80, 0x41, -0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, -0x05, 0xF0, 0x16, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0x01, 0xF5, 0x05, 0x4D, -0x61, 0xF6, 0x84, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x65, 0x00, 0x1C, -0x5B, 0x1F, 0x05, 0x6C, 0x41, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, -0x15, 0x95, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0x41, 0xF6, 0x88, 0x41, -0x00, 0x1C, 0xDD, 0x5B, 0x16, 0x95, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, -0x00, 0x1C, 0x2C, 0x1F, 0x02, 0x6C, 0x00, 0xF2, 0x00, 0x6D, 0xA0, 0x35, -0xA0, 0x35, 0xC5, 0xF0, 0x11, 0x4D, 0x61, 0xF6, 0x8C, 0x41, 0x00, 0x1C, -0xDD, 0x5B, 0x00, 0x65, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0x41, 0xF6, -0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x15, 0x95, 0x00, 0x1C, 0x5B, 0x1F, -0x05, 0x6C, 0x41, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x16, 0x95, -0x00, 0x1C, 0x2C, 0x1F, 0x02, 0x6C, 0xA0, 0x6D, 0xA0, 0x35, 0xA0, 0x35, -0x2A, 0xF4, 0x13, 0x4D, 0x01, 0xF4, 0x84, 0x41, 0x00, 0x1C, 0xDD, 0x5B, -0x00, 0x65, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0x01, 0xF4, 0x88, 0x41, -0x00, 0x1C, 0xDD, 0x5B, 0xE4, 0x6D, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, -0x21, 0xF6, 0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x00, 0x6D, 0x21, 0xF0, -0x80, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0xB0, 0x67, 0x21, 0xF0, 0x88, 0x41, -0x00, 0x1C, 0xDD, 0x5B, 0xB0, 0x67, 0xA1, 0xF6, 0x8C, 0x41, 0x00, 0x1C, -0xFA, 0x5B, 0x00, 0x65, 0x05, 0xF0, 0x00, 0x6B, 0x6B, 0xEB, 0x60, 0x33, -0x60, 0x33, 0x4C, 0xEB, 0x51, 0x23, 0x04, 0x95, 0x01, 0x4D, 0x0A, 0x5D, -0x04, 0xD5, 0x3F, 0xF7, 0x04, 0x61, 0xC9, 0xF7, 0x1B, 0x68, 0x0B, 0xE8, -0x00, 0x30, 0x00, 0x30, 0xE1, 0xF6, 0x80, 0x40, 0x00, 0x1C, 0xDD, 0x5B, -0x07, 0x95, 0xD1, 0xF6, 0x8C, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x08, 0x95, -0x71, 0xF6, 0x80, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x09, 0x95, 0x71, 0xF6, -0x84, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x0A, 0x95, 0x71, 0xF6, 0x88, 0x40, -0x00, 0x1C, 0xDD, 0x5B, 0x0B, 0x95, 0x71, 0xF6, 0x8C, 0x40, 0x00, 0x1C, -0xDD, 0x5B, 0x0C, 0x95, 0x81, 0xF6, 0x80, 0x40, 0x00, 0x1C, 0xDD, 0x5B, -0x0D, 0x95, 0x81, 0xF6, 0x84, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x0E, 0x95, -0x81, 0xF6, 0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x0F, 0x95, 0x81, 0xF6, -0x8C, 0x40, 0x00, 0x1C, 0xDD, 0x5B, 0x10, 0x95, 0xD1, 0xF6, 0x80, 0x40, -0x00, 0x1C, 0xDD, 0x5B, 0x11, 0x95, 0xD1, 0xF6, 0x84, 0x40, 0x00, 0x1C, -0xDD, 0x5B, 0x12, 0x95, 0x81, 0xF6, 0x88, 0x40, 0x00, 0x1C, 0xDD, 0x5B, -0x13, 0x95, 0x1C, 0x97, 0x1B, 0x91, 0x1A, 0x90, 0x00, 0xEF, 0x0F, 0x63, -0x81, 0xF4, 0x80, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF3, -0x1F, 0x6B, 0x4C, 0xEB, 0x91, 0xF6, 0x84, 0x41, 0x00, 0x1C, 0xFA, 0x5B, -0x14, 0xD3, 0xE0, 0xF3, 0x1F, 0x6C, 0x80, 0x34, 0x80, 0x34, 0x8C, 0xEA, -0x42, 0x33, 0x14, 0x92, 0x62, 0x33, 0x10, 0xF0, 0x02, 0x6D, 0x00, 0xF4, -0xA0, 0x35, 0x58, 0xEB, 0x63, 0xF3, 0x00, 0x4D, 0x17, 0xD5, 0xE0, 0xF3, -0x1F, 0x6D, 0x07, 0xF7, 0x00, 0x68, 0x12, 0xEC, 0x82, 0x33, 0x17, 0x94, -0xAC, 0xEB, 0x00, 0xF4, 0x00, 0x6D, 0x43, 0x9C, 0xAB, 0xED, 0xAC, 0xEA, -0x6D, 0xEA, 0x43, 0xDC, 0x81, 0xF4, 0x80, 0x41, 0x00, 0x1C, 0xFA, 0x5B, -0x00, 0x30, 0x17, 0x94, 0x00, 0xF4, 0x00, 0x6B, 0x6B, 0xEB, 0x6C, 0xEA, -0x63, 0x9C, 0xE0, 0xF3, 0x1F, 0x6D, 0x81, 0xF4, 0x80, 0x41, 0xAC, 0xEB, -0xA2, 0x67, 0x00, 0x1C, 0xDD, 0x5B, 0x6D, 0xED, 0x00, 0x1C, 0x5B, 0x1F, -0x05, 0x6C, 0x91, 0xF6, 0x8C, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, -0xE0, 0xF3, 0x1F, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x6C, 0xEA, 0x14, 0x93, -0x42, 0x32, 0x42, 0x32, 0x78, 0xEA, 0xE0, 0xF3, 0x1F, 0x6C, 0x80, 0x33, -0x17, 0x94, 0x06, 0xD2, 0x43, 0x9C, 0x12, 0xED, 0xAC, 0xEB, 0x10, 0x6D, -0xAB, 0xED, 0xA0, 0x35, 0xA0, 0x35, 0xE0, 0xF3, 0x1F, 0x4D, 0x68, 0x33, -0xAC, 0xEA, 0x6D, 0xEA, 0x43, 0xDC, 0x81, 0xF4, 0x80, 0x41, 0x00, 0x1C, -0xFA, 0x5B, 0x00, 0x65, 0x3F, 0x6B, 0x6B, 0xEB, 0x17, 0x94, 0x60, 0x33, -0x60, 0x33, 0xFF, 0x4B, 0x6C, 0xEA, 0x63, 0x9C, 0xE0, 0xF3, 0x1F, 0x6D, -0x3F, 0x6C, 0x62, 0x33, 0x6A, 0x33, 0xAC, 0xEB, 0x8C, 0xEB, 0x60, 0x33, -0x60, 0x33, 0xA2, 0x67, 0x81, 0xF4, 0x80, 0x41, 0x00, 0x1C, 0xDD, 0x5B, -0x6D, 0xED, 0x91, 0xF4, 0x84, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, -0x02, 0xF0, 0x00, 0x6D, 0x06, 0x93, 0xA0, 0x35, 0xA0, 0x35, 0xFF, 0x4D, -0xC0, 0xF3, 0x00, 0x6C, 0xAC, 0xEA, 0x8C, 0xEB, 0xA2, 0x67, 0x06, 0xD3, -0x80, 0xF5, 0x60, 0x33, 0x91, 0xF4, 0x84, 0x41, 0x00, 0x1C, 0xDD, 0x5B, -0x6D, 0xED, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0x11, 0xF4, 0x84, 0x41, -0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xA1, 0xF6, 0x84, 0x41, 0x00, 0x1C, -0xFA, 0x5B, 0x05, 0xD2, 0xE0, 0xF3, 0x1F, 0x6D, 0xA0, 0x35, 0xA0, 0x35, -0xAC, 0xEA, 0x42, 0x33, 0x05, 0x92, 0x00, 0xF4, 0x00, 0x6C, 0x8B, 0xEC, -0x62, 0x33, 0x8C, 0xEA, 0x6D, 0xEA, 0x11, 0xF4, 0x84, 0x41, 0xA2, 0x67, -0x00, 0x1C, 0xDD, 0x5B, 0x05, 0xD2, 0xA1, 0xF6, 0x8C, 0x41, 0x00, 0x1C, -0xFA, 0x5B, 0x00, 0x65, 0x01, 0x6B, 0x6B, 0xEB, 0x05, 0x95, 0x60, 0x33, -0x60, 0x33, 0xE0, 0xF3, 0x1F, 0x4B, 0x0C, 0xEA, 0x6C, 0xED, 0x5A, 0x32, -0x05, 0xD5, 0x11, 0xF4, 0x84, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x4D, 0xED, -0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0x81, 0xF4, 0x88, 0x41, 0x00, 0x1C, -0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF3, 0x1F, 0x6C, 0x4C, 0xEC, 0x14, 0xD4, -0xB1, 0xF6, 0x84, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF3, -0x1F, 0x6D, 0xA0, 0x35, 0xA0, 0x35, 0xAC, 0xEA, 0x42, 0x33, 0x62, 0x33, -0x81, 0xF4, 0x88, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x18, 0xD3, 0x18, 0x93, -0x14, 0x94, 0x98, 0xEB, 0xE0, 0xF3, 0x1F, 0x6B, 0x12, 0xED, 0xA2, 0x34, -0x17, 0x95, 0x6C, 0xEC, 0x63, 0x9D, 0x00, 0xF4, 0x00, 0x6D, 0xAB, 0xED, -0xAC, 0xEB, 0x8D, 0xEB, 0x17, 0x94, 0xAC, 0xEA, 0xE0, 0xF3, 0x1F, 0x6D, -0x63, 0xDC, 0xAC, 0xEB, 0xA2, 0x67, 0x81, 0xF4, 0x88, 0x41, 0x00, 0x1C, -0xDD, 0x5B, 0x6D, 0xED, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0xB1, 0xF6, -0x8C, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0xE0, 0xF3, 0x1F, 0x6B, -0x60, 0x33, 0x60, 0x33, 0x6C, 0xEA, 0x14, 0x93, 0x42, 0x32, 0x42, 0x32, -0x78, 0xEA, 0xE0, 0xF3, 0x1F, 0x6C, 0x80, 0x33, 0x17, 0x94, 0x06, 0xD2, -0x43, 0x9C, 0x12, 0xED, 0xAC, 0xEB, 0x10, 0x6D, 0xAB, 0xED, 0xA0, 0x35, -0xA0, 0x35, 0xE0, 0xF3, 0x1F, 0x4D, 0x68, 0x33, 0xAC, 0xEA, 0x6D, 0xEA, -0x43, 0xDC, 0x81, 0xF4, 0x88, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, -0x10, 0xF0, 0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0xBD, 0xF7, 0x18, 0x4B, -0x17, 0x94, 0xA0, 0x9B, 0xE0, 0xF3, 0x1F, 0x6B, 0x4C, 0xED, 0x43, 0x9C, -0x3F, 0x6C, 0x42, 0x32, 0x4A, 0x32, 0x6C, 0xEA, 0x8C, 0xEA, 0x40, 0x32, -0x40, 0x32, 0x81, 0xF4, 0x88, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x4D, 0xED, -0x91, 0xF4, 0x8C, 0x41, 0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x10, 0xF0, -0x02, 0x6B, 0x00, 0xF4, 0x60, 0x33, 0xBD, 0xF7, 0x1C, 0x4B, 0xA0, 0x9B, -0x06, 0x94, 0x4C, 0xED, 0xC0, 0xF3, 0x00, 0x6A, 0x4C, 0xEC, 0x80, 0xF5, -0x80, 0x32, 0x91, 0xF4, 0x8C, 0x41, 0x00, 0x1C, 0xDD, 0x5B, 0x4D, 0xED, -0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0x11, 0xF4, 0x8C, 0x41, 0x00, 0x1C, -0xFA, 0x5B, 0x00, 0x65, 0xC1, 0xF6, 0x84, 0x41, 0x00, 0x1C, 0xFA, 0x5B, -0x05, 0xD2, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0xDD, 0xF7, -0x00, 0x4C, 0x60, 0x9C, 0x05, 0x95, 0x11, 0xF4, 0x8C, 0x41, 0x4C, 0xEB, -0x00, 0xF4, 0x00, 0x6A, 0x4B, 0xEA, 0x62, 0x33, 0x62, 0x33, 0x4C, 0xED, -0x6D, 0xED, 0x00, 0x1C, 0xDD, 0x5B, 0x05, 0xD5, 0xC1, 0xF6, 0x8C, 0x41, -0x00, 0x1C, 0xFA, 0x5B, 0x00, 0x65, 0x01, 0x6C, 0x8B, 0xEC, 0x05, 0x93, -0x80, 0x34, 0x80, 0x34, 0xE0, 0xF3, 0x1F, 0x4C, 0x8C, 0xEB, 0x4C, 0xE8, -0xA3, 0x67, 0x1A, 0x30, 0x11, 0xF4, 0x8C, 0x41, 0x00, 0x1C, 0xDD, 0x5B, -0x0D, 0xED, 0x00, 0x1C, 0x5B, 0x1F, 0x05, 0x6C, 0x1E, 0x16, 0x00, 0x00, -0xFC, 0x63, 0x00, 0x6B, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, -0x9D, 0x67, 0x26, 0xF7, 0x61, 0xC2, 0x42, 0x6A, 0x50, 0xC4, 0x43, 0x6A, -0x51, 0xC4, 0x4E, 0x6A, 0x52, 0xC4, 0x73, 0xC4, 0x10, 0xF0, 0x02, 0x6C, -0x00, 0xF4, 0x80, 0x34, 0x9E, 0xF5, 0x18, 0x4C, 0xC0, 0xF7, 0x10, 0x6A, -0x43, 0xDC, 0xBD, 0x67, 0x01, 0x6A, 0x10, 0xF0, 0x01, 0x6E, 0x00, 0xF4, -0xC0, 0x36, 0x54, 0xC4, 0x13, 0xF6, 0x11, 0x4E, 0x06, 0x62, 0x00, 0x1C, -0xCF, 0x20, 0x10, 0x4D, 0x06, 0x97, 0x00, 0xEF, 0x04, 0x63, 0x00, 0x00, -0xE0, 0x63, 0x3E, 0x62, 0x3C, 0xD0, 0x3D, 0xD1, 0x10, 0xF0, 0x02, 0x6D, -0x00, 0xF4, 0xA0, 0x35, 0xC7, 0x63, 0x04, 0x04, 0xDD, 0xF7, 0x04, 0x4D, -0x00, 0x1C, 0xF4, 0x54, 0x94, 0x6E, 0x9D, 0x67, 0x7F, 0x4C, 0x10, 0xF0, -0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, 0xFF, 0x6E, 0x29, 0x4C, 0x5E, 0xF0, -0x18, 0x4D, 0x00, 0x1C, 0xF4, 0x54, 0x09, 0x4E, 0x9D, 0x67, 0x10, 0xF0, -0x02, 0x6D, 0x00, 0xF4, 0xA0, 0x35, 0xFF, 0x6E, 0xA0, 0xF1, 0x10, 0x4C, -0x7E, 0xF1, 0x00, 0x4D, 0x00, 0x1C, 0xF4, 0x54, 0x09, 0x4E, 0x10, 0xF0, -0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, 0x00, 0x6B, -0x63, 0xC2, 0x00, 0x68, 0xA2, 0x67, 0xFF, 0x6C, 0x08, 0x32, 0x04, 0x06, -0xAD, 0xE2, 0xC9, 0xE2, 0x40, 0x9A, 0x01, 0x48, 0x8C, 0xE8, 0x25, 0x58, -0x46, 0xDB, 0xF6, 0x61, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, -0x63, 0xF3, 0x00, 0x4A, 0x00, 0x68, 0x0A, 0x65, 0xFF, 0x69, 0x0C, 0x32, -0x68, 0x67, 0x04, 0x04, 0x00, 0x6D, 0x7D, 0xE2, 0x99, 0xE2, 0xAD, 0xE6, -0x80, 0xF0, 0x58, 0xA3, 0xB1, 0xE7, 0x01, 0x4D, 0xA0, 0xF0, 0x4C, 0xC4, -0xA0, 0xF1, 0x40, 0xA3, 0x2C, 0xED, 0x08, 0x5D, 0xA0, 0xF1, 0x54, 0xC4, -0xF2, 0x61, 0x01, 0x48, 0x2C, 0xE8, 0x21, 0x58, 0xE8, 0x61, 0xC8, 0x67, -0x1F, 0x6A, 0xA0, 0xF2, 0x5E, 0xC6, 0x00, 0x6F, 0x01, 0x6A, 0x62, 0x9E, -0xA0, 0xF2, 0xFF, 0xC6, 0xC0, 0xF2, 0x40, 0xC6, 0x10, 0xF0, 0x00, 0x6E, -0xC0, 0x36, 0xC0, 0x36, 0xFF, 0x4E, 0x40, 0x6A, 0xCC, 0xEB, 0x4B, 0xEA, -0x4C, 0xEB, 0x0C, 0x6A, 0x4D, 0xEB, 0x07, 0xF7, 0x01, 0x6A, 0x4B, 0xEA, -0x4C, 0xEB, 0x03, 0xF0, 0x00, 0x6A, 0x4D, 0xEB, 0x07, 0xF7, 0x00, 0x6A, -0x4B, 0xEA, 0x08, 0xF0, 0x00, 0x6C, 0x40, 0x32, 0x8B, 0xEC, 0xFF, 0x4A, -0x80, 0x34, 0x4C, 0xEB, 0x4F, 0x44, 0x4C, 0xEB, 0x10, 0xF0, 0x00, 0x6A, -0x4B, 0xEA, 0x40, 0x32, 0xFF, 0x4A, 0x4C, 0xEB, 0x40, 0x6A, 0x4D, 0xEB, -0x08, 0xF0, 0x00, 0x6D, 0x81, 0x6A, 0xAD, 0xEB, 0x4B, 0xEA, 0x4C, 0xEB, -0xFF, 0x6A, 0x01, 0x4A, 0x4B, 0xEA, 0x40, 0x32, 0xEF, 0xF7, 0x1F, 0x4A, -0x4C, 0xEB, 0x0C, 0xF0, 0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, -0xFF, 0x4A, 0x4C, 0xEB, 0x48, 0x67, 0x62, 0xDA, 0xA0, 0x35, 0x63, 0x9A, -0x44, 0x9A, 0x80, 0x34, 0xA0, 0x35, 0xFF, 0x4C, 0xFF, 0x4D, 0xAC, 0xEA, -0x8C, 0xEB, 0x88, 0x67, 0x44, 0xDC, 0x01, 0x6A, 0x4B, 0xEA, 0xC0, 0xF2, -0x42, 0xC4, 0xFF, 0x6A, 0xCC, 0xEB, 0xC0, 0xF2, 0x44, 0xCC, 0x12, 0x6A, -0xC0, 0xF2, 0xE6, 0xC4, 0x63, 0xDC, 0xC0, 0xF2, 0x47, 0xC4, 0x00, 0x1C, -0xF6, 0x48, 0x00, 0x65, 0x39, 0x63, 0x3E, 0x97, 0x3D, 0x91, 0x3C, 0x90, -0x00, 0xEF, 0x20, 0x63, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, -0x63, 0xF3, 0x00, 0x4C, 0xFF, 0xF7, 0x1F, 0x6A, 0x66, 0xF7, 0x4C, 0xDC, -0x01, 0x6A, 0x4B, 0xEA, 0xFC, 0x63, 0x45, 0xC4, 0x1C, 0x6A, 0x06, 0x62, -0xC0, 0xF2, 0x4F, 0xC4, 0xC0, 0xF2, 0x51, 0xC4, 0x0A, 0x6A, 0x3E, 0x6B, -0xC0, 0xF2, 0x52, 0xC4, 0x40, 0x9C, 0xC0, 0xF2, 0x6E, 0xC4, 0xC0, 0xF2, -0x70, 0xC4, 0x02, 0x6B, 0x6B, 0xEB, 0x6C, 0xEA, 0x21, 0x6B, 0x6B, 0xEB, -0x6C, 0xEA, 0x00, 0x6D, 0x40, 0xDC, 0x06, 0xF0, 0x00, 0x6A, 0xE0, 0xF2, -0xA6, 0xC4, 0x4B, 0xEA, 0xE0, 0xF2, 0x64, 0x9C, 0x40, 0x32, 0x40, 0x32, -0xFF, 0x4A, 0x4C, 0xEB, 0x20, 0x6A, 0xC0, 0xF2, 0x57, 0xC4, 0x08, 0xF0, -0x00, 0x6A, 0x4B, 0xEA, 0x40, 0x32, 0x40, 0x32, 0xFF, 0x4A, 0x4C, 0xEB, -0x10, 0xF0, 0x00, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xFF, 0x4A, 0x4C, 0xEB, -0x20, 0x6A, 0xC0, 0xF2, 0x48, 0xCC, 0xFF, 0x6A, 0x01, 0x4A, 0xE0, 0xF2, -0x64, 0xDC, 0xC0, 0xF2, 0x4A, 0xCC, 0x01, 0x6B, 0x00, 0xF2, 0x00, 0x6A, -0xC0, 0xF2, 0xB6, 0xC4, 0xC0, 0xF2, 0xB4, 0xC4, 0xC0, 0xF2, 0xB5, 0xC4, -0xC0, 0xF2, 0x4C, 0xCC, 0x61, 0xC4, 0x44, 0x6A, 0x9D, 0x67, 0x50, 0xC4, -0x49, 0x6A, 0x51, 0xC4, 0x47, 0x6A, 0x52, 0xC4, 0xB3, 0xC4, 0x10, 0xF0, -0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x7E, 0xF5, 0x1C, 0x4C, 0xC0, 0xF7, -0x10, 0x6A, 0xBD, 0x67, 0x10, 0xF0, 0x01, 0x6E, 0x00, 0xF4, 0xC0, 0x36, -0x43, 0xDC, 0x74, 0xC4, 0x93, 0xF6, 0x19, 0x4E, 0x00, 0x1C, 0xCF, 0x20, -0x10, 0x4D, 0x06, 0x97, 0x00, 0xEF, 0x04, 0x63, 0xFA, 0x63, 0x08, 0xD0, -0x10, 0xF0, 0x02, 0x68, 0x00, 0xF4, 0x00, 0x30, 0x63, 0xF3, 0x00, 0x48, -0x40, 0x98, 0x11, 0x6B, 0x6B, 0xEB, 0x6C, 0xEA, 0x09, 0x6B, 0x6B, 0xEB, -0x6C, 0xEA, 0x40, 0xD8, 0x7D, 0x67, 0x44, 0x6A, 0x50, 0xC3, 0x49, 0x6A, -0x09, 0xD1, 0x51, 0xC3, 0x00, 0x69, 0x47, 0x6A, 0x10, 0xF0, 0x02, 0x6C, -0x00, 0xF4, 0x80, 0x34, 0x1E, 0xF6, 0x08, 0x4C, 0x52, 0xC3, 0x33, 0xC3, -0x14, 0x6A, 0x01, 0x6B, 0xBD, 0x67, 0x10, 0xF0, 0x01, 0x6E, 0x00, 0xF4, -0xC0, 0x36, 0x43, 0xDC, 0x74, 0xC4, 0x10, 0x4D, 0x95, 0xF0, 0x05, 0x4E, -0x0A, 0x62, 0x00, 0x1C, 0xCF, 0x20, 0x23, 0xC8, 0x5D, 0x67, 0x47, 0x6B, -0x78, 0xC2, 0x7D, 0x67, 0x3B, 0x6A, 0x59, 0xC3, 0x43, 0x6A, 0x5A, 0xC3, -0x01, 0x6A, 0x4B, 0xEA, 0x00, 0xF3, 0x44, 0xC0, 0xFF, 0x6A, 0x01, 0x4A, -0x3B, 0xC3, 0x4B, 0xEA, 0x00, 0xF3, 0x64, 0x98, 0x40, 0x32, 0x40, 0x32, -0xE0, 0xF0, 0x1F, 0x4A, 0x4C, 0xEB, 0x00, 0xF2, 0x00, 0x6A, 0x40, 0x32, -0xF3, 0xF0, 0x14, 0x4A, 0x00, 0xF3, 0x4C, 0xD8, 0xFF, 0x6A, 0x01, 0x4A, -0x40, 0x32, 0x46, 0xF0, 0x16, 0x4A, 0x00, 0xF3, 0x64, 0xD8, 0x00, 0xF3, -0x50, 0xD8, 0x60, 0x98, 0x02, 0x6A, 0x00, 0xF3, 0x47, 0xC0, 0x05, 0x6A, -0x4B, 0xEA, 0x00, 0x6C, 0x4C, 0xEB, 0x81, 0x6A, 0x00, 0xF3, 0x88, 0xD8, -0x00, 0xF3, 0x94, 0xD8, 0x00, 0xF3, 0x98, 0xD8, 0x4B, 0xEA, 0x10, 0xF0, -0x02, 0x6C, 0x00, 0xF4, 0x80, 0x34, 0x4C, 0xEB, 0xBE, 0xF5, 0x14, 0x4C, -0xC0, 0xF7, 0x10, 0x6A, 0x60, 0xD8, 0xBD, 0x67, 0x43, 0xDC, 0x10, 0xF0, -0x01, 0x6E, 0x00, 0xF4, 0xC0, 0x36, 0x01, 0x6A, 0x54, 0xC4, 0x55, 0xF1, -0x09, 0x4E, 0x00, 0x1C, 0xCF, 0x20, 0x18, 0x4D, 0x4A, 0x6A, 0x00, 0xF3, -0x5C, 0xC0, 0x45, 0x6A, 0x00, 0xF3, 0x5D, 0xC0, 0x46, 0x6A, 0x00, 0xF3, -0x5E, 0xC0, 0x40, 0x6A, 0x00, 0xF3, 0x5F, 0xC0, 0x23, 0x6A, 0x20, 0xF3, -0x40, 0xC0, 0x1E, 0x6A, 0x20, 0xF3, 0x41, 0xC0, 0x0A, 0x97, 0x09, 0x91, -0x08, 0x90, 0x00, 0xEF, 0x06, 0x63, 0x00, 0x00, 0xFC, 0x63, 0x7D, 0x67, -0x3B, 0x6A, 0x50, 0xC3, 0x43, 0x6A, 0x51, 0xC3, 0x36, 0x6A, 0x52, 0xC3, -0x00, 0x6B, 0x5D, 0x67, 0x73, 0xC2, 0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, -0x40, 0x32, 0x63, 0xF3, 0x00, 0x4A, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, -0x80, 0x34, 0xDE, 0xF5, 0x10, 0x4C, 0xC0, 0xF2, 0x73, 0xC2, 0xC0, 0xF7, -0x10, 0x6A, 0x43, 0xDC, 0xBD, 0x67, 0x01, 0x6A, 0x10, 0xF0, 0x01, 0x6E, -0x00, 0xF4, 0xC0, 0x36, 0x54, 0xC4, 0x95, 0xF4, 0x05, 0x4E, 0x06, 0x62, -0x00, 0x1C, 0xCF, 0x20, 0x10, 0x4D, 0x06, 0x97, 0x00, 0xEF, 0x04, 0x63, -0x10, 0xF0, 0x02, 0x6A, 0x00, 0xF4, 0x40, 0x32, 0xFC, 0x63, 0x63, 0xF3, -0x00, 0x4A, 0x01, 0x6D, 0x00, 0x6B, 0x9D, 0x67, 0x66, 0xF7, 0xB6, 0xCA, -0x66, 0xF7, 0x74, 0xCA, 0x52, 0x6A, 0x50, 0xC4, 0x53, 0x6A, 0x51, 0xC4, -0x54, 0x6A, 0x52, 0xC4, 0x73, 0xC4, 0x10, 0xF0, 0x02, 0x6C, 0x00, 0xF4, -0x80, 0x34, 0x3E, 0xF6, 0x04, 0x4C, 0xE0, 0xF1, 0x14, 0x6A, 0xB4, 0xC4, -0x10, 0xF0, 0x02, 0x6E, 0x00, 0xF4, 0xC0, 0x36, 0xBD, 0x67, 0x43, 0xDC, -0x10, 0xF5, 0x0D, 0x4E, 0x06, 0x62, 0x00, 0x1C, 0xCF, 0x20, 0x10, 0x4D, -0x06, 0x97, 0x00, 0xEF, 0x04, 0x63, 0x00, 0x65, 0xD8, 0xFF, 0xBD, 0x27, -0x02, 0x80, 0x03, 0x3C, 0x20, 0x00, 0xBF, 0xAF, 0x1C, 0x00, 0xB1, 0xAF, -0x18, 0x00, 0xB0, 0xAF, 0x74, 0xF2, 0x62, 0x24, 0x02, 0x00, 0x48, 0x90, -0x74, 0xF2, 0x67, 0x94, 0x02, 0x80, 0x02, 0x3C, 0xD0, 0x5D, 0x42, 0x24, -0x02, 0x00, 0x10, 0x24, 0x01, 0x80, 0x06, 0x3C, 0x21, 0x20, 0x40, 0x00, -0x14, 0x00, 0x50, 0xA0, 0x10, 0x00, 0xA5, 0x27, 0xFC, 0xC1, 0xC6, 0x24, -0x02, 0x80, 0x11, 0x3C, 0x20, 0x5E, 0x31, 0x26, 0x10, 0x00, 0xA7, 0xA7, -0x12, 0x00, 0xA8, 0xA3, 0xCF, 0x20, 0x00, 0x0C, 0x13, 0x00, 0xA0, 0xA3, -0x02, 0x80, 0x06, 0x3C, 0x21, 0x20, 0x20, 0x02, 0x10, 0x00, 0xA5, 0x27, -0x14, 0x00, 0x30, 0xA2, 0xCF, 0x20, 0x00, 0x0C, 0x08, 0x86, 0xC6, 0x24, -0x02, 0x80, 0x02, 0x3C, 0xEC, 0x5D, 0x40, 0xA0, 0x0C, 0x00, 0x04, 0x24, -0x02, 0x80, 0x03, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0xED, 0x5D, 0x64, 0xA0, -0xEE, 0x5D, 0x44, 0xA0, 0x02, 0x80, 0x03, 0x3C, 0x02, 0x80, 0x02, 0x3C, -0x04, 0x5E, 0x60, 0xA0, 0x06, 0x5E, 0x40, 0xA0, 0x02, 0x80, 0x03, 0x3C, -0x02, 0x80, 0x02, 0x3C, 0x0C, 0x5E, 0x60, 0xA0, 0x01, 0x00, 0x06, 0x24, -0x0D, 0x5E, 0x40, 0xA0, 0x02, 0x80, 0x03, 0x3C, 0x02, 0x80, 0x02, 0x3C, -0xF0, 0x5D, 0x66, 0xA0, 0x12, 0x00, 0x04, 0x24, 0x0E, 0x5E, 0x40, 0xA0, -0x02, 0x80, 0x03, 0x3C, 0x02, 0x80, 0x02, 0x3C, 0xEF, 0x5D, 0x66, 0xA0, -0xF1, 0x5D, 0x44, 0xA0, 0x02, 0x80, 0x03, 0x3C, 0x0C, 0x00, 0x04, 0x24, -0x02, 0x80, 0x02, 0x3C, 0xF2, 0x5D, 0x60, 0xA0, 0x02, 0x80, 0x05, 0x3C, -0xFC, 0x5D, 0x44, 0xA4, 0x64, 0x00, 0x03, 0x24, 0x02, 0x80, 0x02, 0x3C, -0xF4, 0x5D, 0xA3, 0xA4, 0xC6, 0x5C, 0x43, 0x90, 0xF4, 0x5D, 0xA4, 0x94, -0x02, 0x00, 0x05, 0x24, 0x02, 0x00, 0x63, 0x30, 0x01, 0x00, 0x63, 0x2C, -0xFF, 0xFF, 0x84, 0x30, 0x23, 0x28, 0xA3, 0x00, 0x80, 0x22, 0x04, 0x00, -0x02, 0x80, 0x02, 0x3C, 0xE8, 0x03, 0x03, 0x24, 0xF8, 0x5D, 0x44, 0xAC, -0x0C, 0x00, 0x23, 0xAE, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, -0x00, 0x5E, 0x40, 0xAC, 0x05, 0x5E, 0x60, 0xA0, 0x02, 0x80, 0x02, 0x3C, -0x02, 0x80, 0x03, 0x3C, 0x07, 0x5E, 0x40, 0xA0, 0x0F, 0x5E, 0x60, 0xA0, -0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, 0x3C, 0x5E, 0x45, 0xA0, -0x20, 0x00, 0xBF, 0x8F, 0x08, 0x5E, 0x60, 0xA0, 0x02, 0x80, 0x02, 0x3C, -0x02, 0x80, 0x03, 0x3C, 0x1C, 0x00, 0xB1, 0x8F, 0x18, 0x00, 0xB0, 0x8F, -0x09, 0x5E, 0x46, 0xA0, 0x0A, 0x5E, 0x66, 0xA0, 0x02, 0x80, 0x02, 0x3C, -0x02, 0x80, 0x03, 0x3C, 0x0B, 0x5E, 0x40, 0xA0, 0x21, 0x20, 0x00, 0x00, -0x10, 0x5E, 0x60, 0xAC, 0x02, 0x80, 0x02, 0x3C, 0x02, 0x80, 0x03, 0x3C, -0x21, 0x28, 0x00, 0x00, 0x28, 0x00, 0xBD, 0x27, 0x14, 0x5E, 0x40, 0xAC, -0x18, 0x5E, 0x64, 0xAC, 0x1C, 0x5E, 0x65, 0xAC, 0x08, 0x00, 0xE0, 0x03, -0x00, 0x00, 0x00, 0x00, 0xD8, 0xFF, 0xBD, 0x27, 0x1C, 0x00, 0xB3, 0xAF, -0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, -0x20, 0x00, 0xBF, 0xAF, 0x21, 0x80, 0x80, 0x00, 0x21, 0x98, 0xA0, 0x00, -0x21, 0x88, 0xC0, 0x00, 0x21, 0x90, 0x00, 0x00, 0x00, 0x00, 0x04, 0x82, -0x5C, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x40, 0x14, -0x01, 0x00, 0x10, 0x26, 0xFF, 0xFF, 0x10, 0x26, 0x00, 0x00, 0x04, 0x92, -0x2B, 0x00, 0x02, 0x24, 0x00, 0x1E, 0x04, 0x00, 0x03, 0x1E, 0x03, 0x00, -0x41, 0x00, 0x62, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x24, -0x30, 0x00, 0x22, 0x12, 0x00, 0x1E, 0x04, 0x00, 0x07, 0x00, 0x20, 0x16, -0x21, 0x18, 0x80, 0x00, 0x00, 0x1E, 0x04, 0x00, 0x03, 0x1E, 0x03, 0x00, -0x30, 0x00, 0x02, 0x24, 0x3B, 0x00, 0x62, 0x10, 0x0A, 0x00, 0x11, 0x24, -0x21, 0x18, 0x80, 0x00, 0x00, 0x16, 0x03, 0x00, 0x03, 0x16, 0x02, 0x00, -0x1A, 0x00, 0x40, 0x10, 0xFF, 0x00, 0x64, 0x30, 0xA9, 0xFF, 0x82, 0x24, -0x61, 0x00, 0x83, 0x2C, 0xFF, 0x00, 0x45, 0x30, 0x09, 0x00, 0x60, 0x10, -0x41, 0x00, 0x86, 0x2C, 0xC9, 0xFF, 0x82, 0x24, 0xFF, 0x00, 0x45, 0x30, -0x05, 0x00, 0xC0, 0x10, 0x3A, 0x00, 0x87, 0x2C, 0xD0, 0xFF, 0x82, 0x24, -0x02, 0x00, 0xE0, 0x10, 0xFF, 0x00, 0x05, 0x24, 0xFF, 0x00, 0x45, 0x30, -0x2A, 0x10, 0xB1, 0x00, 0x0A, 0x00, 0x40, 0x10, 0x18, 0x00, 0x51, 0x02, -0x01, 0x00, 0x10, 0x26, 0x12, 0x10, 0x00, 0x00, 0x2B, 0x18, 0x52, 0x00, -0x23, 0x00, 0x60, 0x14, 0x21, 0x90, 0xA2, 0x00, 0x00, 0x00, 0x03, 0x92, -0x00, 0x00, 0x00, 0x00, 0xE8, 0xFF, 0x60, 0x14, 0xFF, 0x00, 0x64, 0x30, -0x02, 0x00, 0x60, 0x12, 0x21, 0x10, 0x40, 0x02, 0x00, 0x00, 0x70, 0xAE, -0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0x08, 0x00, 0xE0, 0x03, -0x28, 0x00, 0xBD, 0x27, 0x03, 0x1E, 0x03, 0x00, 0x30, 0x00, 0x02, 0x24, -0xCE, 0xFF, 0x62, 0x14, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x82, -0x78, 0x00, 0x02, 0x24, 0x03, 0x00, 0x62, 0x10, 0x58, 0x00, 0x02, 0x24, -0xD0, 0xFF, 0x62, 0x14, 0x21, 0x18, 0x80, 0x00, 0x02, 0x00, 0x10, 0x26, -0x00, 0x00, 0x04, 0x92, 0x63, 0x71, 0x00, 0x08, 0x10, 0x00, 0x11, 0x24, -0x01, 0x00, 0x10, 0x26, 0x00, 0x00, 0x04, 0x92, 0x5A, 0x71, 0x00, 0x08, -0x10, 0x00, 0x02, 0x24, 0x8F, 0x71, 0x00, 0x08, 0x08, 0x00, 0x11, 0x24, -0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0xFF, 0xFF, 0x02, 0x24, -0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, 0x21, 0x48, 0x80, 0x00, -0x31, 0x00, 0xC0, 0x14, 0x21, 0x50, 0x00, 0x00, 0x00, 0x00, 0x87, 0x90, -0x30, 0x00, 0x02, 0x24, 0x00, 0x1E, 0x07, 0x00, 0x03, 0x1E, 0x03, 0x00, -0x2E, 0x00, 0x62, 0x10, 0x0A, 0x00, 0x06, 0x24, 0x02, 0x80, 0x02, 0x3C, -0x40, 0xF4, 0x4B, 0x24, 0xFF, 0x00, 0xE8, 0x30, 0x21, 0x10, 0x0B, 0x01, -0x00, 0x00, 0x44, 0x90, 0x00, 0x1E, 0x07, 0x00, 0x03, 0x1E, 0x03, 0x00, -0x44, 0x00, 0x82, 0x30, 0x02, 0x00, 0x87, 0x30, 0xD0, 0xFF, 0x63, 0x24, -0x1A, 0x00, 0x40, 0x10, 0x04, 0x00, 0x84, 0x30, 0x07, 0x00, 0x80, 0x14, -0x2B, 0x10, 0x66, 0x00, 0x21, 0x10, 0x00, 0x01, 0x02, 0x00, 0xE0, 0x10, -0xE0, 0xFF, 0x03, 0x25, 0xFF, 0x00, 0x62, 0x30, 0xC9, 0xFF, 0x43, 0x24, -0x2B, 0x10, 0x66, 0x00, 0x10, 0x00, 0x40, 0x10, 0x18, 0x00, 0x46, 0x01, -0x01, 0x00, 0x29, 0x25, 0x00, 0x00, 0x27, 0x91, 0x00, 0x00, 0x00, 0x00, -0xFF, 0x00, 0xE8, 0x30, 0x12, 0x10, 0x00, 0x00, 0x21, 0x50, 0x43, 0x00, -0x21, 0x10, 0x0B, 0x01, 0x00, 0x00, 0x44, 0x90, 0x00, 0x1E, 0x07, 0x00, -0x03, 0x1E, 0x03, 0x00, 0x44, 0x00, 0x82, 0x30, 0x02, 0x00, 0x87, 0x30, -0xD0, 0xFF, 0x63, 0x24, 0xE8, 0xFF, 0x40, 0x14, 0x04, 0x00, 0x84, 0x30, -0x02, 0x00, 0xA0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA9, 0xAC, -0x08, 0x00, 0xE0, 0x03, 0x21, 0x10, 0x40, 0x01, 0x00, 0x00, 0x87, 0x90, -0xB1, 0x71, 0x00, 0x08, 0x02, 0x80, 0x02, 0x3C, 0x01, 0x00, 0x89, 0x24, -0x00, 0x00, 0x27, 0x91, 0x78, 0x00, 0x02, 0x24, 0x00, 0x1E, 0x07, 0x00, -0x03, 0x1E, 0x03, 0x00, 0xCD, 0xFF, 0x62, 0x14, 0x08, 0x00, 0x06, 0x24, -0x01, 0x00, 0x22, 0x91, 0x02, 0x80, 0x03, 0x3C, 0x40, 0xF4, 0x63, 0x24, -0x21, 0x10, 0x43, 0x00, 0x00, 0x00, 0x44, 0x90, 0x00, 0x00, 0x00, 0x00, -0x44, 0x00, 0x84, 0x30, 0xC5, 0xFF, 0x80, 0x10, 0x02, 0x80, 0x02, 0x3C, -0x01, 0x00, 0x29, 0x25, 0x00, 0x00, 0x27, 0x91, 0xB1, 0x71, 0x00, 0x08, -0x10, 0x00, 0x06, 0x24, 0xE8, 0xFF, 0xBD, 0x27, 0x10, 0x00, 0xBF, 0xAF, -0x00, 0x00, 0x83, 0x80, 0x2D, 0x00, 0x02, 0x24, 0x04, 0x00, 0x62, 0x10, -0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xBF, 0x8F, 0xA7, 0x71, 0x00, 0x08, -0x18, 0x00, 0xBD, 0x27, 0xA7, 0x71, 0x00, 0x0C, 0x01, 0x00, 0x84, 0x24, -0x10, 0x00, 0xBF, 0x8F, 0x23, 0x10, 0x02, 0x00, 0x08, 0x00, 0xE0, 0x03, -0x18, 0x00, 0xBD, 0x27, 0xD8, 0xFF, 0xBD, 0x27, 0x1C, 0x00, 0xB3, 0xAF, -0x18, 0x00, 0xB2, 0xAF, 0x14, 0x00, 0xB1, 0xAF, 0x10, 0x00, 0xB0, 0xAF, -0x20, 0x00, 0xBF, 0xAF, 0x21, 0x80, 0x80, 0x00, 0x21, 0x90, 0xA0, 0x00, -0x21, 0x98, 0xC0, 0x00, 0x21, 0x88, 0x00, 0x00, 0x00, 0x00, 0x04, 0x82, -0x5C, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0x40, 0x14, -0x01, 0x00, 0x10, 0x26, 0xFF, 0xFF, 0x10, 0x26, 0x00, 0x00, 0x03, 0x82, -0x2D, 0x00, 0x02, 0x24, 0x0F, 0x00, 0x62, 0x10, 0x21, 0x20, 0x00, 0x02, -0x21, 0x28, 0x40, 0x02, 0x43, 0x71, 0x00, 0x0C, 0x21, 0x30, 0x60, 0x02, -0x12, 0x00, 0x40, 0x04, 0x21, 0x18, 0x40, 0x00, 0x23, 0x10, 0x02, 0x00, -0x0A, 0x10, 0x71, 0x00, 0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, -0x18, 0x00, 0xB2, 0x8F, 0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, -0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, 0x01, 0x00, 0x10, 0x26, -0x21, 0x20, 0x00, 0x02, 0x21, 0x28, 0x40, 0x02, 0x43, 0x71, 0x00, 0x0C, -0x21, 0x30, 0x60, 0x02, 0xFF, 0xFF, 0x11, 0x24, 0xF0, 0xFF, 0x41, 0x04, -0x21, 0x18, 0x40, 0x00, 0xF0, 0xFF, 0x20, 0x16, 0x00, 0x80, 0x02, 0x3C, -0x20, 0x00, 0xBF, 0x8F, 0x1C, 0x00, 0xB3, 0x8F, 0x18, 0x00, 0xB2, 0x8F, -0x14, 0x00, 0xB1, 0x8F, 0x10, 0x00, 0xB0, 0x8F, 0xFF, 0x7F, 0x02, 0x3C, -0xFF, 0xFF, 0x42, 0x34, 0x08, 0x00, 0xE0, 0x03, 0x28, 0x00, 0xBD, 0x27, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x00, 0x7F, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x01, 0x7F, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x02, 0x7E, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x03, 0x7D, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x04, 0x7C, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x05, 0x7B, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x06, 0x7A, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x07, 0x79, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x08, 0x78, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x09, 0x77, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x76, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x0B, 0x75, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x0C, 0x74, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x0D, 0x73, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x0E, 0x72, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x0F, 0x71, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x10, 0x70, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x11, 0x6F, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x12, 0x6F, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x13, 0x6E, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x14, 0x6D, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x15, 0x6D, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x16, 0x6C, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x17, 0x6B, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x18, 0x6A, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x19, 0x6A, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x1A, 0x69, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x1B, 0x68, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x1C, 0x67, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x1D, 0x66, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x1E, 0x65, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x1F, 0x64, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x20, 0x63, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x21, 0x4C, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x22, 0x4B, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x23, 0x4A, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x24, 0x49, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x25, 0x48, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x26, 0x47, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x27, 0x46, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x28, 0x45, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x29, 0x44, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x2A, 0x2C, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x2B, 0x2B, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x2C, 0x2A, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x2D, 0x29, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x2E, 0x28, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x2F, 0x27, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x30, 0x26, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x31, 0x25, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x32, 0x24, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x33, 0x23, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x34, 0x22, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x35, 0x09, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x36, 0x08, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x37, 0x07, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x38, 0x06, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x39, 0x05, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x3A, 0x04, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x3B, 0x03, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x3C, 0x02, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x3D, 0x01, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x3E, 0x00, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x3F, 0x00, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x40, 0x7F, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x41, 0x7F, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x42, 0x7E, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x43, 0x7D, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x44, 0x7C, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x45, 0x7B, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x46, 0x7A, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x47, 0x79, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x48, 0x78, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x49, 0x77, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x4A, 0x76, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x4B, 0x75, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x4C, 0x74, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x4D, 0x73, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x4E, 0x72, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x4F, 0x71, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x50, 0x70, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x51, 0x6F, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x52, 0x6F, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x53, 0x6E, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x54, 0x6D, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x55, 0x6D, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x56, 0x6C, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x57, 0x6B, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x58, 0x6A, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x59, 0x6A, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x5A, 0x69, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x5B, 0x68, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x5C, 0x67, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x5D, 0x66, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x5E, 0x65, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x5F, 0x64, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x60, 0x63, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x61, 0x4C, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x62, 0x4B, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x63, 0x4A, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x64, 0x49, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x65, 0x48, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x66, 0x47, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x67, 0x46, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x68, 0x45, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x69, 0x44, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x6A, 0x2C, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x6B, 0x2B, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x6C, 0x2A, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x6D, 0x29, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x6E, 0x28, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x6F, 0x27, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x70, 0x26, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x71, 0x25, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x72, 0x24, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x73, 0x23, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x74, 0x22, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x75, 0x09, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x76, 0x08, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x77, 0x07, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x78, 0x06, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x79, 0x05, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x7A, 0x04, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x7B, 0x03, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x7C, 0x02, 0x78, 0x0C, 0x00, 0x00, -0x01, 0x00, 0x7D, 0x01, 0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x7E, 0x00, -0x78, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x7F, 0x00, 0x78, 0x0C, 0x00, 0x00, -0x1E, 0x00, 0x00, 0x30, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x01, 0x30, -0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x02, 0x30, 0x78, 0x0C, 0x00, 0x00, -0x1E, 0x00, 0x03, 0x30, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x04, 0x30, -0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x05, 0x34, 0x78, 0x0C, 0x00, 0x00, -0x1E, 0x00, 0x06, 0x38, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x07, 0x3E, -0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x08, 0x3E, 0x78, 0x0C, 0x00, 0x00, -0x1E, 0x00, 0x09, 0x44, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x0A, 0x46, -0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x0B, 0x48, 0x78, 0x0C, 0x00, 0x00, -0x1E, 0x00, 0x0C, 0x48, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x0D, 0x4E, -0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x0E, 0x56, 0x78, 0x0C, 0x00, 0x00, -0x1E, 0x00, 0x0F, 0x5A, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x10, 0x5E, -0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x11, 0x62, 0x78, 0x0C, 0x00, 0x00, -0x1E, 0x00, 0x12, 0x6C, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x13, 0x72, -0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x14, 0x72, 0x78, 0x0C, 0x00, 0x00, -0x1E, 0x00, 0x15, 0x72, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x16, 0x72, -0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x17, 0x72, 0x78, 0x0C, 0x00, 0x00, -0x1E, 0x00, 0x18, 0x72, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x19, 0x72, -0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x1A, 0x72, 0x78, 0x0C, 0x00, 0x00, -0x1E, 0x00, 0x1B, 0x72, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x1C, 0x72, -0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x1D, 0x72, 0x78, 0x0C, 0x00, 0x00, -0x1E, 0x00, 0x1E, 0x72, 0x78, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x1F, 0x72, -0x00, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0x06, 0x06, 0x04, -0x04, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0x02, 0x02, 0x00, -0x08, 0x0E, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x08, 0x08, 0x04, -0x14, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0x02, 0x02, 0x00, -0x18, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x08, 0x08, 0x04, -0x1C, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0x02, 0x02, 0x00, -0x00, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, -0x04, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, -0x08, 0x0E, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, -0x14, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, -0x18, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, -0x1C, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, -0x00, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, -0x04, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, -0x08, 0x0E, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, -0x14, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, -0x18, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, -0x1C, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, -0x00, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, -0x04, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, -0x08, 0x0E, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x10, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, -0x14, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, -0x18, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, -0x1C, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, -0x04, 0x08, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, -0x24, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xF0, 0x00, 0x04, 0x00, 0x30, 0x00, -0x2C, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xF0, 0x00, 0x04, 0x00, 0x30, 0x00, -0x70, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, -0x64, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, -0x78, 0x08, 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x02, 0x00, 0x02, 0x00, -0x74, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x06, 0x00, 0x00, 0x00, -0x78, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x06, 0x00, 0x00, 0x00, -0x7C, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x06, 0x00, 0x00, 0x00, -0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x06, 0x00, 0x00, 0x00, -0x0C, 0x09, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, -0x04, 0x0C, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, -0x04, 0x0D, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, -0xF4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, -0x34, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x13, 0x00, 0x00, 0x00, -0x04, 0x08, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, -0x24, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xF0, 0x00, 0x04, 0x00, 0x30, 0x00, -0x2C, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xF0, 0x00, 0x02, 0x00, 0x30, 0x00, -0x70, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, -0x64, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x78, 0x08, 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x02, 0x00, 0x00, 0x00, -0x74, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x00, 0x00, 0x00, -0x78, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x00, 0x00, 0x00, -0x7C, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x00, 0x00, 0x00, -0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x00, 0x00, 0x00, -0x0C, 0x09, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, -0x04, 0x0C, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, -0x04, 0x0D, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, -0xF4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x77, 0x77, 0x00, 0x00, -0x34, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0A, 0x00, 0x00, 0x00, -0x44, 0x08, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0x00, -0x04, 0x08, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, -0x24, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xF0, 0x00, 0x04, 0x00, 0x30, 0x00, -0x2C, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xF0, 0x00, 0x02, 0x00, 0x10, 0x00, -0x70, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, -0x64, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x78, 0x08, 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x02, 0x00, 0x00, 0x00, -0x74, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x00, 0x00, 0x00, -0x78, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x00, 0x00, 0x00, -0x7C, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x00, 0x00, 0x00, -0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x00, 0x00, 0x00, -0x0C, 0x09, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, -0x04, 0x0C, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, -0x04, 0x0D, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, -0xF4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x77, 0x77, 0x00, 0x00, -0x34, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0A, 0x00, 0x00, 0x00, -0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x08, 0x00, 0x00, -0x00, 0x00, 0x04, 0x00, 0x04, 0x08, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, -0x08, 0x08, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x0C, 0x08, 0x00, 0x00, -0x0A, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x88, 0x50, 0x00, 0x10, -0x14, 0x08, 0x00, 0x00, 0x10, 0x3D, 0x0C, 0x02, 0x18, 0x08, 0x00, 0x00, -0x85, 0x01, 0x20, 0x00, 0x1C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x24, 0x08, 0x00, 0x00, -0x04, 0x00, 0x39, 0x00, 0x28, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x2C, 0x08, 0x00, 0x00, 0x04, 0x00, 0x39, 0x00, 0x30, 0x08, 0x00, 0x00, -0x04, 0x00, 0x00, 0x00, 0x34, 0x08, 0x00, 0x00, 0x00, 0x02, 0x69, 0x00, -0x38, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3C, 0x08, 0x00, 0x00, -0x00, 0x02, 0x69, 0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, -0x44, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x48, 0x08, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x4C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x50, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x08, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x58, 0x08, 0x00, 0x00, 0x48, 0x48, 0x48, 0x48, -0x5C, 0x08, 0x00, 0x00, 0xA9, 0x65, 0xA9, 0x65, 0x60, 0x08, 0x00, 0x00, -0x30, 0x01, 0x7F, 0x0F, 0x64, 0x08, 0x00, 0x00, 0x30, 0x01, 0x7F, 0x0F, -0x68, 0x08, 0x00, 0x00, 0x30, 0x01, 0x7F, 0x0F, 0x6C, 0x08, 0x00, 0x00, -0x30, 0x01, 0x7F, 0x0F, 0x70, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x03, -0x74, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x78, 0x08, 0x00, 0x00, -0x02, 0x00, 0x02, 0x00, 0x7C, 0x08, 0x00, 0x00, 0x01, 0x02, 0x4F, 0x00, -0x80, 0x08, 0x00, 0x00, 0xC1, 0x0A, 0x30, 0xA8, 0x84, 0x08, 0x00, 0x00, -0x58, 0x00, 0x00, 0x00, 0x88, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, -0x8C, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x90, 0x08, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x94, 0x08, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, -0x98, 0x08, 0x00, 0x00, 0x10, 0x20, 0x30, 0x40, 0x9C, 0x08, 0x00, 0x00, -0x50, 0x60, 0x70, 0x00, 0xB0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xE0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x08, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x33, 0x33, 0x33, 0x30, -0x04, 0x0E, 0x00, 0x00, 0x2F, 0x2E, 0x2D, 0x2A, 0x08, 0x0E, 0x00, 0x00, -0x32, 0x32, 0x00, 0x00, 0x10, 0x0E, 0x00, 0x00, 0x33, 0x33, 0x33, 0x30, -0x14, 0x0E, 0x00, 0x00, 0x2F, 0x2E, 0x2D, 0x2A, 0x18, 0x0E, 0x00, 0x00, -0x33, 0x33, 0x33, 0x30, 0x1C, 0x0E, 0x00, 0x00, 0x2F, 0x2E, 0x2D, 0x2A, -0x30, 0x0E, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x01, 0x34, 0x0E, 0x00, 0x00, -0x00, 0x48, 0x00, 0x01, 0x38, 0x0E, 0x00, 0x00, 0x1F, 0xDC, 0x00, 0x10, -0x3C, 0x0E, 0x00, 0x00, 0x1F, 0x8C, 0x00, 0x10, 0x40, 0x0E, 0x00, 0x00, -0xA0, 0x00, 0x14, 0x02, 0x44, 0x0E, 0x00, 0x00, 0xA0, 0x00, 0x16, 0x28, -0x48, 0x0E, 0x00, 0x00, 0x01, 0x00, 0x00, 0xF8, 0x4C, 0x0E, 0x00, 0x00, -0x10, 0x29, 0x00, 0x00, 0x50, 0x0E, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x01, -0x54, 0x0E, 0x00, 0x00, 0x00, 0x48, 0x00, 0x01, 0x58, 0x0E, 0x00, 0x00, -0x1F, 0xDC, 0x00, 0x10, 0x5C, 0x0E, 0x00, 0x00, 0x1F, 0x8C, 0x00, 0x10, -0x60, 0x0E, 0x00, 0x00, 0xA0, 0x00, 0x14, 0x02, 0x64, 0x0E, 0x00, 0x00, -0xA0, 0x00, 0x16, 0x28, 0x6C, 0x0E, 0x00, 0x00, 0x10, 0x29, 0x00, 0x00, -0x70, 0x0E, 0x00, 0x00, 0xFB, 0x92, 0xED, 0x31, 0x74, 0x0E, 0x00, 0x00, -0xFB, 0x36, 0x15, 0x36, 0x78, 0x0E, 0x00, 0x00, 0xFB, 0x36, 0x15, 0x36, -0x7C, 0x0E, 0x00, 0x00, 0xFB, 0x36, 0x15, 0x36, 0x80, 0x0E, 0x00, 0x00, -0xFB, 0x36, 0x15, 0x36, 0x84, 0x0E, 0x00, 0x00, 0xFB, 0x92, 0x0D, 0x00, -0x88, 0x0E, 0x00, 0x00, 0xFB, 0x92, 0x0D, 0x00, 0x8C, 0x0E, 0x00, 0x00, -0xFB, 0x92, 0xED, 0x31, 0xD0, 0x0E, 0x00, 0x00, 0xFB, 0x92, 0xED, 0x31, -0xD4, 0x0E, 0x00, 0x00, 0xFB, 0x92, 0xED, 0x31, 0xD8, 0x0E, 0x00, 0x00, -0xFB, 0x92, 0x0D, 0x00, 0xDC, 0x0E, 0x00, 0x00, 0xFB, 0x92, 0x0D, 0x00, -0xE0, 0x0E, 0x00, 0x00, 0xFB, 0x92, 0x0D, 0x00, 0xE4, 0x0E, 0x00, 0x00, -0x48, 0x54, 0x5E, 0x01, 0xE8, 0x0E, 0x00, 0x00, 0x48, 0x54, 0x55, 0x21, -0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0x00, 0x00, -0x23, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x0C, 0x09, 0x00, 0x00, 0x13, 0x13, 0x12, 0x01, 0x00, 0x0A, 0x00, 0x00, -0xC8, 0x47, 0xD0, 0x00, 0x04, 0x0A, 0x00, 0x00, 0x08, 0x00, 0xFF, 0x80, -0x08, 0x0A, 0x00, 0x00, 0x00, 0x83, 0xCD, 0x88, 0x0C, 0x0A, 0x00, 0x00, -0x0F, 0x12, 0x62, 0x2E, 0x10, 0x0A, 0x00, 0x00, 0x78, 0xBB, 0x00, 0x95, -0x14, 0x0A, 0x00, 0x00, 0x28, 0x40, 0x14, 0x11, 0x18, 0x0A, 0x00, 0x00, -0x17, 0x11, 0x88, 0x00, 0x1C, 0x0A, 0x00, 0x00, 0x00, 0x0F, 0x14, 0x89, -0x20, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x1A, 0x24, 0x0A, 0x00, 0x00, -0x17, 0x13, 0x0E, 0x09, 0x28, 0x0A, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, -0x2C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x10, 0x00, 0x0C, 0x00, 0x00, -0x40, 0x1D, 0x07, 0x40, 0x04, 0x0C, 0x00, 0x00, 0x33, 0x56, 0xA0, 0x00, -0x08, 0x0C, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, 0x00, -0x6C, 0x6C, 0x6C, 0x6C, 0x10, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, -0x14, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0x18, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x08, 0x1C, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, -0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x24, 0x0C, 0x00, 0x00, -0x00, 0x01, 0x00, 0x40, 0x28, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, -0x2C, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0x30, 0x0C, 0x00, 0x00, -0x44, 0xAC, 0xE9, 0x6D, 0x34, 0x0C, 0x00, 0x00, 0xCF, 0x52, 0x96, 0x46, -0x38, 0x0C, 0x00, 0x00, 0x94, 0x59, 0x79, 0x49, 0x3C, 0x0C, 0x00, 0x00, -0x64, 0x97, 0x97, 0x0A, 0x40, 0x0C, 0x00, 0x00, 0x3F, 0x40, 0x7C, 0x1F, -0x44, 0x0C, 0x00, 0x00, 0xB7, 0x00, 0x01, 0x00, 0x48, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x02, 0xEC, 0x4C, 0x0C, 0x00, 0x00, 0x7F, 0x03, 0x7F, 0x00, -0x50, 0x0C, 0x00, 0x00, 0x20, 0x34, 0x54, 0x69, 0x54, 0x0C, 0x00, 0x00, -0x94, 0x00, 0x3C, 0x43, 0x58, 0x0C, 0x00, 0x00, 0x20, 0x34, 0x54, 0x69, -0x5C, 0x0C, 0x00, 0x00, 0x94, 0x00, 0x3C, 0x43, 0x60, 0x0C, 0x00, 0x00, -0x20, 0x34, 0x54, 0x69, 0x64, 0x0C, 0x00, 0x00, 0x94, 0x00, 0x3C, 0x43, -0x68, 0x0C, 0x00, 0x00, 0x20, 0x34, 0x54, 0x69, 0x6C, 0x0C, 0x00, 0x00, -0x94, 0x00, 0x3C, 0x43, 0x70, 0x0C, 0x00, 0x00, 0x0D, 0x00, 0x7F, 0x2C, -0x74, 0x0C, 0x00, 0x00, 0x5B, 0x17, 0x86, 0x01, 0x78, 0x0C, 0x00, 0x00, -0x1F, 0x00, 0x00, 0x00, 0x7C, 0x0C, 0x00, 0x00, 0x12, 0x16, 0xB9, 0x00, -0x80, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0x84, 0x0C, 0x00, 0x00, -0x00, 0x00, 0xF6, 0x20, 0x88, 0x0C, 0x00, 0x00, 0x80, 0x00, 0x00, 0x20, -0x8C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x90, 0x0C, 0x00, 0x00, -0x00, 0x01, 0x00, 0x40, 0x94, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x98, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0x9C, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xA0, 0x0C, 0x00, 0x00, 0x92, 0x24, 0x49, 0x00, -0xA4, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAC, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xB0, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xB8, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xBC, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xC0, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xC4, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xC8, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xD0, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xD4, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x0C, 0x00, 0x00, -0x27, 0x24, 0xB2, 0x64, 0xDC, 0x0C, 0x00, 0x00, 0x32, 0x69, 0x76, 0x00, -0xE0, 0x0C, 0x00, 0x00, 0x22, 0x22, 0x22, 0x00, 0xE4, 0x0C, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xE8, 0x0C, 0x00, 0x00, 0x02, 0x43, 0x64, 0x37, -0xEC, 0x0C, 0x00, 0x00, 0x0C, 0xD4, 0x97, 0x2F, 0x00, 0x0D, 0x00, 0x00, -0x50, 0x07, 0x00, 0x00, 0x04, 0x0D, 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, -0x08, 0x0D, 0x00, 0x00, 0x7F, 0x90, 0x00, 0x00, 0x0C, 0x0D, 0x00, 0x00, -0x01, 0x00, 0x00, 0x00, 0x10, 0x0D, 0x00, 0x00, 0x33, 0x33, 0x63, 0xA0, -0x14, 0x0D, 0x00, 0x00, 0x63, 0x3C, 0x33, 0x33, 0x18, 0x0D, 0x00, 0x00, -0x6B, 0x5B, 0x8F, 0x6A, 0x1C, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x20, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x0D, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x28, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x2C, 0x0D, 0x00, 0x00, 0x75, 0x99, 0x97, 0xCC, 0x30, 0x0D, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x34, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x38, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x0D, 0x00, 0x00, -0x93, 0x72, 0x02, 0x00, 0x40, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x44, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x0D, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x50, 0x0D, 0x00, 0x00, 0x0A, 0x14, 0x37, 0x64, -0x54, 0x0D, 0x00, 0x00, 0x02, 0xBD, 0x4D, 0x02, 0x58, 0x0D, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x5C, 0x0D, 0x00, 0x00, 0x64, 0x20, 0x03, 0x30, -0x60, 0x0D, 0x00, 0x00, 0x68, 0xDE, 0x53, 0x46, 0x64, 0x0D, 0x00, 0x00, -0x3C, 0x8A, 0x51, 0x00, 0x68, 0x0D, 0x00, 0x00, 0x01, 0x21, 0x00, 0x00, -0x14, 0x0F, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4C, 0x0F, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, -0x40, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, -0x10, 0x00, 0x00, 0x00, 0x84, 0x02, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00, -0xB4, 0x02, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00, 0xC0, 0x08, 0x01, 0x80, -0x10, 0x00, 0x00, 0x00, 0xC8, 0x08, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00, -0xD0, 0x08, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00, 0xD8, 0x08, 0x01, 0x80, -0x10, 0x00, 0x00, 0x00, 0xB0, 0x08, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00, -0xB8, 0x08, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00, 0x10, 0x09, 0x01, 0x80, -0x10, 0x00, 0x00, 0x00, 0x18, 0x09, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00, -0x58, 0x04, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00, 0x50, 0x04, 0x01, 0x80, -0x10, 0x00, 0x00, 0x00, 0x20, 0x09, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00, -0x28, 0x09, 0x01, 0x80, 0x74, 0x03, 0x00, 0x00, 0xF0, 0x28, 0x00, 0x80, -0x04, 0x00, 0x00, 0x00, 0x88, 0x06, 0x01, 0x80, 0x74, 0x03, 0x00, 0x00, -0xF0, 0x28, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00, 0xAC, 0x2B, 0x00, 0x80, -0x30, 0x00, 0x00, 0x00, 0x58, 0x2C, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00, -0x1C, 0x2F, 0x00, 0x80, 0x13, 0x00, 0x00, 0x00, 0x7C, 0x07, 0x01, 0x80, -0x17, 0x00, 0x00, 0x00, 0xD0, 0x07, 0x01, 0x80, 0x06, 0x00, 0x00, 0x00, -0x58, 0x08, 0x01, 0x80, 0x06, 0x00, 0x00, 0x00, 0x60, 0x08, 0x01, 0x80, -0x08, 0x00, 0x00, 0x00, 0x68, 0x08, 0x01, 0x80, 0x0C, 0x00, 0x00, 0x00, -0x70, 0x08, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00, 0x78, 0x08, 0x01, 0x80, -0x0E, 0x00, 0x00, 0x00, 0x80, 0x08, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, -0x88, 0x08, 0x01, 0x80, 0x38, 0x00, 0x00, 0x00, 0x90, 0x08, 0x01, 0x80, -0x04, 0x00, 0x00, 0x00, 0x98, 0x08, 0x01, 0x80, 0x02, 0x00, 0x00, 0x00, -0xA0, 0x08, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00, 0xA8, 0x08, 0x01, 0x80, -0x01, 0x00, 0x00, 0x00, 0xE8, 0x08, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, -0xF0, 0x08, 0x01, 0x80, 0x0C, 0x00, 0x00, 0x00, 0x60, 0x04, 0x01, 0x80, -0x0E, 0x00, 0x00, 0x00, 0x68, 0x04, 0x01, 0x80, 0x0C, 0x00, 0x00, 0x00, -0x80, 0x06, 0x01, 0x80, 0x34, 0x00, 0x00, 0x00, 0xF8, 0x08, 0x01, 0x80, -0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00, -0x30, 0x09, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00, 0x38, 0x09, 0x01, 0x80, -0x04, 0x00, 0x00, 0x00, 0x40, 0x09, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00, -0x08, 0x09, 0x01, 0x80, 0x08, 0x00, 0x00, 0x00, 0xB8, 0x03, 0x01, 0x80, -0x04, 0x00, 0x00, 0x00, 0x48, 0x09, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00, -0xC0, 0x09, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00, 0xCC, 0x09, 0x01, 0x80, -0x04, 0x00, 0x00, 0x00, 0xD4, 0x09, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00, -0xDC, 0x09, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00, 0xE4, 0x09, 0x01, 0x80, -0x04, 0x00, 0x00, 0x00, 0xEC, 0x09, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00, -0xF4, 0x09, 0x01, 0x80, 0x04, 0x00, 0x00, 0x00, 0xFC, 0x09, 0x01, 0x80, -0x04, 0x00, 0x00, 0x00, 0x04, 0x0A, 0x01, 0x80, 0x74, 0x03, 0x00, 0x00, -0x0C, 0x0A, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x30, 0x0B, 0x01, 0x80, -0x10, 0x00, 0x00, 0x00, 0x0C, 0x33, 0x00, 0x80, 0x06, 0x00, 0x00, 0x00, -0x6C, 0x0B, 0x01, 0x80, 0x13, 0x00, 0x00, 0x00, 0xF8, 0x9E, 0x02, 0x00, -0x13, 0x00, 0x00, 0x00, 0xC8, 0x5E, 0x02, 0x00, 0x13, 0x00, 0x00, 0x00, -0xF8, 0x0E, 0x02, 0x00, 0x13, 0x00, 0x00, 0x00, 0xC8, 0xCE, 0x01, 0x00, -0x13, 0x00, 0x00, 0x00, 0xD4, 0x8E, 0x01, 0x00, 0x13, 0x00, 0x00, 0x00, -0xA4, 0x4E, 0x01, 0x00, 0x13, 0x00, 0x00, 0x00, 0xD0, 0x0E, 0x01, 0x00, -0x13, 0x00, 0x00, 0x00, 0xA0, 0xCE, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, -0xD0, 0x86, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xA0, 0x46, 0x00, 0x00, -0x13, 0x00, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, -0xA4, 0x9E, 0x02, 0x00, 0x13, 0x00, 0x00, 0x00, 0x74, 0x5E, 0x02, 0x00, -0x13, 0x00, 0x00, 0x00, 0xA4, 0x0E, 0x02, 0x00, 0x13, 0x00, 0x00, 0x00, -0xD0, 0xCE, 0x01, 0x00, 0x13, 0x00, 0x00, 0x00, 0x40, 0x9F, 0x01, 0x00, -0x13, 0x00, 0x00, 0x00, 0x70, 0x4E, 0x01, 0x00, 0x13, 0x00, 0x00, 0x00, -0xA0, 0x06, 0x01, 0x00, 0x13, 0x00, 0x00, 0x00, 0x70, 0xC6, 0x00, 0x00, -0x13, 0x00, 0x00, 0x00, 0xA0, 0x82, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, -0x70, 0x42, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, -0xAA, 0x88, 0x88, 0x44, 0x44, 0x22, 0x22, 0x00, 0xAA, 0x88, 0x88, 0x44, -0x44, 0x22, 0x22, 0x00, 0xAA, 0x88, 0x88, 0x44, 0x44, 0x22, 0x22, 0x00, -0xAA, 0x88, 0x88, 0x44, 0x44, 0x22, 0x22, 0x00, 0xAA, 0x88, 0x88, 0x44, -0x44, 0x22, 0x22, 0x00, 0xAA, 0x88, 0x88, 0x44, 0x44, 0x22, 0x22, 0x00, -0xAA, 0x88, 0x88, 0x44, 0x44, 0x22, 0x22, 0x00, 0xAA, 0x88, 0x88, 0x44, -0x44, 0x22, 0x22, 0x00, 0xAA, 0x88, 0x88, 0x44, 0x44, 0x22, 0x22, 0x00, -0xAA, 0x88, 0x88, 0x44, 0x44, 0x22, 0x22, 0x00, 0xAA, 0x88, 0x88, 0x44, -0x44, 0x22, 0x22, 0x00, 0xAA, 0x88, 0x88, 0x44, 0x44, 0x22, 0x22, 0x00, -0x00, 0x00, 0x00, 0x00, 0x59, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, -0x41, 0x10, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, -0x05, 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, -0x03, 0xC8, 0x0F, 0x00, 0x13, 0x00, 0x00, 0x00, 0xB0, 0x7C, 0x01, 0x00, -0x13, 0x00, 0x00, 0x00, 0xC0, 0x1C, 0x01, 0x00, 0x13, 0x00, 0x00, 0x00, -0x60, 0xDC, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x60, 0x8C, 0x00, 0x00, -0x13, 0x00, 0x00, 0x00, 0x50, 0x44, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, -0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x01, 0x03, 0x00, -0x01, 0x00, 0x00, 0x00, 0x50, 0x02, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x08, 0x00, -0x11, 0x00, 0x00, 0x00, 0xFC, 0x31, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, -0x0F, 0x00, 0x0C, 0x00, 0x11, 0x00, 0x00, 0x00, 0xF8, 0xF9, 0x03, 0x00, -0x10, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x02, 0x00, 0x11, 0x00, 0x00, 0x00, -0x01, 0x01, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00, 0x3E, 0x09, 0x01, 0x00, -0x14, 0x00, 0x00, 0x00, 0x3E, 0x09, 0x09, 0x00, 0x15, 0x00, 0x00, 0x00, -0xF4, 0x98, 0x01, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0F, 0x00, -0x1A, 0x00, 0x00, 0x00, 0x56, 0x30, 0x01, 0x00, 0x1B, 0x00, 0x00, 0x00, -0x00, 0x00, 0x06, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, -0x1E, 0x00, 0x00, 0x00, 0x59, 0x10, 0x03, 0x00, 0x21, 0x00, 0x00, 0x00, -0x00, 0x40, 0x05, 0x00, 0x22, 0x00, 0x00, 0x00, 0x3C, 0x08, 0x00, 0x00, -0x23, 0x00, 0x00, 0x00, 0x58, 0x15, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, -0x60, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x83, 0x25, 0x02, 0x00, -0x26, 0x00, 0x00, 0x00, 0x00, 0xF2, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, -0xF1, 0xAC, 0x0E, 0x00, 0x28, 0x00, 0x00, 0x00, 0x54, 0xBD, 0x09, 0x00, -0x29, 0x00, 0x00, 0x00, 0x82, 0x45, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, -0x01, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x34, 0x13, 0x02, 0x00, -0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, -0x0A, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, -0x2B, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, -0x33, 0x33, 0x05, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, -0x2A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, -0x08, 0x08, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x33, 0xB3, 0x05, 0x00, -0x2C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, -0x03, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, -0x2B, 0x00, 0x00, 0x00, 0x33, 0x33, 0x06, 0x00, 0x2C, 0x00, 0x00, 0x00, -0x0D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, -0x2B, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, -0x33, 0xB3, 0x06, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, -0x2A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, -0x09, 0x07, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x33, 0x33, 0x05, 0x00, -0x2C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, -0x06, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x09, 0x07, 0x00, 0x00, -0x2B, 0x00, 0x00, 0x00, 0x33, 0xB3, 0x05, 0x00, 0x2C, 0x00, 0x00, 0x00, -0x0D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, -0x2B, 0x00, 0x00, 0x00, 0x09, 0x07, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, -0x33, 0x33, 0x06, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, -0x2A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, -0x09, 0x07, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x33, 0xB3, 0x06, 0x00, -0x2C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, -0x09, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x0A, 0x06, 0x00, 0x00, -0x2B, 0x00, 0x00, 0x00, 0x33, 0x33, 0x05, 0x00, 0x2C, 0x00, 0x00, 0x00, -0x0D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, -0x2B, 0x00, 0x00, 0x00, 0x0A, 0x06, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, -0x33, 0xB3, 0x05, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, -0x2A, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, -0x0A, 0x06, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x33, 0x33, 0x06, 0x00, -0x2C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, -0x0C, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x0A, 0x06, 0x00, 0x00, -0x2B, 0x00, 0x00, 0x00, 0x33, 0xB3, 0x06, 0x00, 0x2C, 0x00, 0x00, 0x00, -0x0D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, -0x2B, 0x00, 0x00, 0x00, 0x0B, 0x05, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, -0x33, 0x33, 0x05, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, -0x2A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, -0x0B, 0x05, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x23, 0x66, 0x06, 0x00, -0x2C, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, -0x00, 0x40, 0x0E, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, -0x31, 0x00, 0x00, 0x00, 0x31, 0x96, 0x0B, 0x00, 0x32, 0x00, 0x00, 0x00, -0x0D, 0x13, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x87, 0x01, 0x00, 0x00, -0x13, 0x00, 0x00, 0x00, 0x6C, 0x9E, 0x01, 0x00, 0x13, 0x00, 0x00, 0x00, -0x94, 0x5E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x01, 0x01, 0x00, -0x18, 0x00, 0x00, 0x00, 0x01, 0xF4, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x5B, 0x10, 0x03, 0x00, -0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x59, 0x01, 0x03, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x04, 0x00, -0x11, 0x00, 0x00, 0x00, 0xF9, 0x03, 0x02, 0x00, 0x6C, 0x09, 0x00, 0x00, -0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, -0x0D, 0x00, 0x00, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, -0x12, 0x12, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, -0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x17, 0x05, 0x03, -0x22, 0x43, 0x5E, 0x00, 0x4F, 0xA4, 0x00, 0x00, 0x4F, 0xA4, 0x00, 0x00, -0x22, 0x43, 0x5E, 0x00, 0x4F, 0xA4, 0x00, 0x00, 0x22, 0x43, 0x5E, 0x00, -0x4F, 0xA4, 0x3E, 0x00, 0x30, 0xA6, 0x00, 0x00, 0x4F, 0xA4, 0x3E, 0x00, -0x2B, 0xA4, 0x5E, 0x00, 0x2B, 0xA4, 0x00, 0x00, 0x2B, 0xA4, 0x5E, 0x00, -0x22, 0xA4, 0x5E, 0x00, 0x4F, 0xA4, 0x00, 0x00, 0x4F, 0xA4, 0x00, 0x00, -0x4F, 0xA4, 0x5E, 0x00, 0x4F, 0xA4, 0x5E, 0x00, 0x4F, 0xA4, 0x5E, 0x00, -0x1C, 0x42, 0x2F, 0x00, 0x4F, 0x64, 0x5E, 0x00, 0x4F, 0xA4, 0x5E, 0x00, -0x4F, 0xA4, 0x5E, 0x00, 0x4F, 0xA4, 0x00, 0x00, 0x4F, 0xA4, 0x5E, 0x00, -0x00, 0xE0, 0x4C, 0x02, 0x01, 0x20, 0x00, 0x00, 0x00, 0xE0, 0x4C, 0x00, -0x00, 0x0C, 0x43, 0x00, 0x00, 0x50, 0x43, 0x00, 0x00, 0x40, 0x96, 0x00, -0x00, 0x05, 0xB5, 0x00, 0x00, 0x0A, 0xF7, 0x00, 0x00, 0x10, 0x18, 0x00, -0x00, 0x21, 0x91, 0x00, 0x00, 0x1C, 0xF0, 0x00, 0x00, 0x13, 0x74, 0x00, -0x00, 0x03, 0x7F, 0x00, 0x00, 0x50, 0xF2, 0x02, 0x01, 0x01, 0x00, 0x00, -0x00, 0x50, 0xF2, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0xE7, 0x01, 0x80, -0xE0, 0x25, 0x01, 0x80, 0x10, 0x00, 0x00, 0x00, 0xBC, 0xE7, 0x01, 0x80, -0xE8, 0x25, 0x01, 0x80, 0x20, 0x00, 0x00, 0x00, 0xC8, 0xE7, 0x01, 0x80, -0xE0, 0x25, 0x01, 0x80, 0x30, 0x00, 0x00, 0x00, 0xD8, 0xE7, 0x01, 0x80, -0xE8, 0x25, 0x01, 0x80, 0x40, 0x00, 0x00, 0x00, 0xE8, 0xE7, 0x01, 0x80, -0x44, 0x43, 0x00, 0x80, 0x50, 0x00, 0x00, 0x00, 0xF4, 0xE7, 0x01, 0x80, -0xD4, 0x49, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x01, 0x80, -0x34, 0x53, 0x00, 0x80, 0x90, 0x00, 0x00, 0x00, 0x0C, 0xE8, 0x01, 0x80, -0x64, 0x30, 0x01, 0x80, 0xA0, 0x00, 0x00, 0x00, 0x14, 0xE8, 0x01, 0x80, -0x6C, 0x30, 0x01, 0x80, 0xB0, 0x00, 0x00, 0x00, 0x20, 0xE8, 0x01, 0x80, -0x9C, 0x39, 0x01, 0x80, 0xC0, 0x00, 0x00, 0x00, 0x28, 0xE8, 0x01, 0x80, -0x8C, 0x30, 0x01, 0x80, 0xD0, 0x00, 0x00, 0x00, 0x34, 0xE8, 0x01, 0x80, -0xFC, 0x4E, 0x00, 0x80, 0xC8, 0x00, 0x00, 0x00, 0x40, 0xE8, 0x01, 0x80, -0x54, 0x4A, 0x00, 0x80, 0x0D, 0x00, 0x00, 0x00, 0x4C, 0xE8, 0x01, 0x80, -0xAC, 0x30, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, -0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0xFF, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0xFF, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, -0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xFF, 0x00, 0x00, 0x00, -0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xFF, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x06, 0x07, 0x08, 0xFF, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, -0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x01, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xD0, 0xDF, 0x01, 0x80, 0xD0, 0xDF, 0x01, 0x80, -0x31, 0x10, 0x10, 0x00, 0x00, 0x30, 0x00, 0x00, 0x31, 0x20, 0x10, 0x00, -0x00, 0x30, 0x00, 0x00, 0x31, 0x28, 0x10, 0x00, 0x00, 0x30, 0x00, 0x00, -0x31, 0x2C, 0x10, 0x10, 0x00, 0x30, 0x00, 0x00, 0x31, 0x2F, 0x10, 0x10, -0x00, 0x30, 0x00, 0x00, 0x31, 0x30, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, -0x31, 0x30, 0x20, 0x10, 0x00, 0x30, 0x00, 0x00, 0x22, 0x20, 0x18, 0x08, -0x00, 0x20, 0x00, 0x00, 0x22, 0x21, 0x14, 0x08, 0x00, 0x20, 0x00, 0x00, -0x22, 0x21, 0x1C, 0x08, 0x00, 0x20, 0x00, 0x00, 0x22, 0x21, 0x20, 0x08, -0x00, 0x20, 0x00, 0x00, 0x22, 0x21, 0x20, 0x10, 0x00, 0x20, 0x00, 0x00, -0x22, 0x21, 0x20, 0x18, 0x00, 0x20, 0x00, 0x00, 0x1A, 0x19, 0x18, 0x10, -0x00, 0x18, 0x00, 0x00, 0x12, 0x11, 0x10, 0x08, 0x00, 0x10, 0x00, 0x00, -0x0A, 0x09, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x02, -0x00, 0x08, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, 0x08, 0x00, 0x00, -0x0A, 0x09, 0x08, 0x06, 0x00, 0x08, 0x00, 0x00, 0x08, 0x07, 0x06, 0x04, -0x00, 0x06, 0x00, 0x00, 0x06, 0x05, 0x04, 0x02, 0x00, 0x04, 0x00, 0x00, -0x06, 0x05, 0x04, 0x03, 0x00, 0x04, 0x00, 0x00, 0x05, 0x04, 0x03, 0x02, -0x00, 0x03, 0x00, 0x00, 0x09, 0x08, 0x07, 0x06, 0x07, 0x06, 0x06, 0x05, -0x05, 0x04, 0x04, 0x03, 0x06, 0x05, 0x05, 0x04, 0x04, 0x03, 0x03, 0x03, -0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x00, 0x09, 0x08, 0x07, -0x06, 0x07, 0x06, 0x06, 0x05, 0x05, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04, -0x03, 0x03, 0x02, 0x02, 0x02, 0x04, 0x03, 0x03, 0x02, 0x02, 0x01, 0x01, -0x01, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -0x08, 0x10, 0x10, 0x20, 0x08, 0x08, 0x08, 0x08, 0x20, 0x20, 0x20, 0x20, -0x08, 0x08, 0x08, 0x08, 0x08, 0x20, 0x20, 0x20, 0x30, 0x08, 0x08, 0x08, -0x08, 0x18, 0x18, 0x18, 0x18, 0x18, 0x20, 0x30, 0x30, 0x10, 0x20, 0x20, -0x20, 0x20, 0x20, 0x30, 0x30, 0x08, 0x10, 0x20, 0x30, 0x30, 0x30, 0x30, -0x30, 0x30, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -0x08, 0x10, 0x10, 0x20, 0x08, 0x08, 0x08, 0x08, 0x08, 0x20, 0x20, 0x20, -0x08, 0x08, 0x08, 0x08, 0x08, 0x20, 0x20, 0x20, 0x20, 0x08, 0x08, 0x08, -0x08, 0x18, 0x18, 0x18, 0x18, 0x18, 0x20, 0x30, 0x30, 0x10, 0x20, 0x20, -0x20, 0x20, 0x20, 0x30, 0x30, 0x08, 0x10, 0x20, 0x30, 0x30, 0x30, 0x30, -0x30, 0x30, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, 0x0A, 0x09, 0x08, -0x04, 0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, -0x0A, 0x09, 0x08, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x0A, 0x09, -0x08, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x00, -0x00, 0x12, 0x11, 0x10, 0x08, 0x00, 0x12, 0x11, 0x10, 0x08, 0x00, 0x22, -0x21, 0x20, 0x18, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x0A, 0x09, 0x08, -0x00, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, -0x22, 0x21, 0x20, 0x18, 0x00, 0x22, 0x21, 0x20, 0x18, 0x00, 0x22, 0x21, -0x1C, 0x08, 0x00, 0x22, 0x20, 0x18, 0x08, 0x00, 0x0A, 0x09, 0x08, 0x02, -0x00, 0x0A, 0x09, 0x08, 0x02, 0x00, 0x0A, 0x09, 0x08, 0x02, 0x00, 0x0A, -0x09, 0x08, 0x02, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x22, 0x21, 0x20, -0x10, 0x00, 0x22, 0x21, 0x20, 0x08, 0x00, 0x22, 0x21, 0x1C, 0x08, 0x00, -0x31, 0x30, 0x18, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, 0x0A, 0x09, -0x08, 0x04, 0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, 0x0A, 0x09, 0x08, 0x04, -0x00, 0x1A, 0x19, 0x18, 0x10, 0x00, 0x1A, 0x19, 0x18, 0x10, 0x00, 0x1A, -0x19, 0x18, 0x10, 0x00, 0x1A, 0x19, 0x18, 0x10, 0x00, 0x1A, 0x19, 0x18, -0x10, 0x00, 0x22, 0x21, 0x20, 0x08, 0x00, 0x31, 0x2C, 0x10, 0x10, 0x00, -0x31, 0x28, 0x10, 0x00, 0x00, 0x12, 0x11, 0x10, 0x08, 0x00, 0x22, 0x21, -0x20, 0x18, 0x00, 0x22, 0x21, 0x20, 0x18, 0x00, 0x22, 0x21, 0x20, 0x08, -0x00, 0x22, 0x21, 0x14, 0x08, 0x00, 0x22, 0x20, 0x18, 0x08, 0x00, 0x31, -0x30, 0x20, 0x10, 0x00, 0x31, 0x2C, 0x10, 0x10, 0x00, 0x0A, 0x09, 0x08, -0x00, 0x00, 0x12, 0x11, 0x10, 0x08, 0x00, 0x22, 0x21, 0x20, 0x18, 0x00, -0x22, 0x21, 0x20, 0x18, 0x00, 0x31, 0x30, 0x20, 0x10, 0x00, 0x31, 0x2F, -0x10, 0x10, 0x00, 0x31, 0x2F, 0x10, 0x10, 0x00, 0x31, 0x10, 0x10, 0x00, -0x00, 0x31, 0x2C, 0x10, 0x10, 0x00, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x04, -0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, 0x0A, -0x09, 0x08, 0x04, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x0A, 0x09, 0x08, -0x00, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, -0x0A, 0x09, 0x08, 0x00, 0x00, 0x12, 0x11, 0x10, 0x08, 0x00, 0x12, 0x11, -0x10, 0x08, 0x00, 0x22, 0x21, 0x20, 0x18, 0x00, 0x0A, 0x09, 0x08, 0x04, -0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, 0x0A, 0x09, 0x08, 0x02, 0x00, 0x0A, -0x09, 0x08, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x22, 0x21, 0x20, -0x18, 0x00, 0x22, 0x21, 0x1C, 0x08, 0x00, 0x22, 0x21, 0x14, 0x08, 0x00, -0x0A, 0x09, 0x08, 0x02, 0x00, 0x0A, 0x09, 0x08, 0x02, 0x00, 0x0A, 0x09, -0x08, 0x02, 0x00, 0x0A, 0x09, 0x08, 0x02, 0x00, 0x0A, 0x09, 0x08, 0x00, -0x00, 0x22, 0x21, 0x20, 0x10, 0x00, 0x22, 0x21, 0x20, 0x08, 0x00, 0x22, -0x21, 0x14, 0x08, 0x00, 0x22, 0x21, 0x14, 0x08, 0x00, 0x0A, 0x09, 0x08, -0x04, 0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, 0x0A, 0x09, 0x08, 0x04, 0x00, -0x0A, 0x09, 0x08, 0x04, 0x00, 0x1A, 0x19, 0x18, 0x10, 0x00, 0x1A, 0x19, -0x18, 0x10, 0x00, 0x1A, 0x19, 0x18, 0x10, 0x00, 0x1A, 0x19, 0x18, 0x10, -0x00, 0x1A, 0x19, 0x18, 0x10, 0x00, 0x22, 0x21, 0x20, 0x08, 0x00, 0x31, -0x2C, 0x10, 0x10, 0x00, 0x31, 0x28, 0x10, 0x00, 0x00, 0x12, 0x11, 0x10, -0x08, 0x00, 0x22, 0x21, 0x20, 0x18, 0x00, 0x22, 0x21, 0x20, 0x18, 0x00, -0x22, 0x21, 0x20, 0x08, 0x00, 0x22, 0x21, 0x14, 0x08, 0x00, 0x22, 0x20, -0x18, 0x08, 0x00, 0x31, 0x30, 0x20, 0x10, 0x00, 0x31, 0x2C, 0x10, 0x10, -0x00, 0x0A, 0x09, 0x08, 0x00, 0x00, 0x12, 0x11, 0x10, 0x08, 0x00, 0x22, -0x21, 0x20, 0x18, 0x00, 0x22, 0x21, 0x20, 0x18, 0x00, 0x31, 0x30, 0x20, -0x10, 0x00, 0x31, 0x2F, 0x10, 0x10, 0x00, 0x31, 0x2F, 0x10, 0x10, 0x00, -0x31, 0x10, 0x10, 0x00, 0x00, 0x31, 0x2C, 0x10, 0x10, 0x00, 0x00, 0x00, -0x01, 0x02, 0x04, 0x08, 0x02, 0x04, 0x08, 0x0C, 0x10, 0x18, 0x20, 0x30, -0x02, 0x04, 0x08, 0x0C, 0x10, 0x18, 0x20, 0x30, 0x06, 0x0C, 0x10, 0x18, -0x24, 0x30, 0x3C, 0x48, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x27, 0x2C, 0x19, 0x1B, 0x1E, 0x20, -0x23, 0x29, 0x2A, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x25, 0x29, 0x2B, 0x2E, -0x2E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, -0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, -0x24, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, -0x60, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, -0xD8, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, -0xA0, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, -0x90, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x30, 0x02, 0x00, 0x00, -0x2C, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, -0xD0, 0x02, 0x00, 0x00, 0x80, 0x0C, 0x00, 0x00, 0x80, 0x0C, 0x00, 0x00, -0x80, 0x0C, 0x00, 0x00, 0xA0, 0x0F, 0x00, 0x00, 0xA0, 0x0F, 0x00, 0x00, -0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, -0x08, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, -0x18, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, -0x48, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, -0x28, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, -0x64, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, -0xF0, 0x00, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, -0xA0, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x68, 0x01, 0x00, 0x00, -0x40, 0x06, 0x00, 0x00, 0x40, 0x06, 0x00, 0x00, 0x40, 0x06, 0x00, 0x00, -0xD0, 0x07, 0x00, 0x00, 0xD0, 0x07, 0x00, 0x00, 0x54, 0x86, 0x01, 0x80, -0x4C, 0xC4, 0x00, 0x80, 0x4C, 0xC4, 0x00, 0x80, 0x4C, 0xC4, 0x00, 0x80, -0x4C, 0xC4, 0x00, 0x80, 0x9C, 0xC2, 0x00, 0x80, 0x5C, 0x86, 0x01, 0x80, -0x54, 0x86, 0x01, 0x80, 0x54, 0x86, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x44, 0x8B, 0x01, 0x80, 0x44, 0x8B, 0x01, 0x80, -0x44, 0x8B, 0x01, 0x80, 0x44, 0x8B, 0x01, 0x80, 0x34, 0x86, 0x01, 0x80, -0x30, 0x8A, 0x01, 0x80, 0x3C, 0x86, 0x01, 0x80, 0x44, 0x86, 0x01, 0x80, -0x4C, 0x86, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x08, 0x04, 0x04, 0x08, 0x02, 0x02, 0x01, 0x01, 0x80, 0x00, 0x00, 0x00, -0x52, 0x54, 0x4C, 0x38, 0x37, 0x31, 0x32, 0x20, 0x46, 0x57, 0x20, 0x76, -0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x30, 0x2E, 0x30, 0x2E, 0x31, -0x23, 0x20, 0xE4, 0xB8, 0x80, 0x20, 0x35, 0xE6, 0x9C, 0x88, 0x20, 0x33, -0x31, 0x20, 0x31, 0x35, 0x3A, 0x32, 0x35, 0x3A, 0x33, 0x39, 0x20, 0x43, -0x53, 0x54, 0x20, 0x32, 0x30, 0x31, 0x30, 0x20, 0x20, 0x53, 0x56, 0x4E, -0x3A, 0x20, 0x25, 0x64, 0x00, 0x00, 0x00, 0x00, 0x43, 0x68, 0x69, 0x70, -0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3A, 0x25, 0x78, 0x00, -0x48, 0x43, 0x49, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x25, 0x78, -0x28, 0x25, 0x78, 0x29, 0x0A, 0x00, 0x00, 0x00, 0x72, 0x66, 0x5F, 0x63, -0x6F, 0x66, 0x69, 0x67, 0x3A, 0x20, 0x25, 0x78, 0x28, 0x25, 0x78, 0x2C, -0x20, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x78, 0x29, 0x0A, 0x00, 0x00, 0x00, -0x6D, 0x70, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x3A, 0x20, 0x25, 0x78, 0x28, -0x25, 0x78, 0x29, 0x2C, 0x20, 0x49, 0x51, 0x4B, 0x3A, 0x20, 0x25, 0x78, -0x0A, 0x00, 0x00, 0x00, 0x76, 0x63, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, -0x3A, 0x20, 0x25, 0x78, 0x28, 0x25, 0x78, 0x29, 0x0A, 0x00, 0x00, 0x00, -0x33, 0x32, 0x6B, 0x20, 0x63, 0x61, 0x6C, 0x69, 0x62, 0x72, 0x61, 0x3A, -0x20, 0x25, 0x64, 0x2C, 0x20, 0x33, 0x32, 0x4B, 0x20, 0x54, 0x53, 0x46, -0x3A, 0x20, 0x25, 0x78, 0x00, 0x00, 0x00, 0x00, 0x74, 0x61, 0x72, 0x67, -0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x72, 0x6D, 0x61, 0x6C, 0x3A, 0x20, -0x25, 0x78, 0x2C, 0x20, 0x20, 0x62, 0x74, 0x5F, 0x63, 0x6F, 0x65, 0x78, -0x69, 0x73, 0x74, 0x3A, 0x20, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x54, 0xAA, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, -0x24, 0xA9, 0x01, 0x80, 0x1C, 0xAA, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, -0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, 0xE4, 0xA9, 0x01, 0x80, -0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, -0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, -0x24, 0xA9, 0x01, 0x80, 0xAC, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, -0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, 0x74, 0xA9, 0x01, 0x80, -0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, -0x3C, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, 0x24, 0xA9, 0x01, 0x80, -0x24, 0xA9, 0x01, 0x80, 0xFC, 0xA8, 0x01, 0x80, 0x64, 0x05, 0x00, 0x80, -0x58, 0x05, 0x00, 0x80, 0x4C, 0x05, 0x00, 0x80, 0x40, 0x05, 0x00, 0x80, -0x34, 0x05, 0x00, 0x80, 0x28, 0x05, 0x00, 0x80, 0x1C, 0x05, 0x00, 0x80, -0x10, 0x05, 0x00, 0x80, 0x04, 0x05, 0x00, 0x80, 0xF8, 0x04, 0x00, 0x80, -0xB0, 0x04, 0x00, 0x80, 0x60, 0x1B, 0x02, 0x80, 0xB0, 0x03, 0x25, 0xB0, -0x60, 0x1B, 0x02, 0x80, 0x60, 0x1B, 0x02, 0x80, 0x60, 0x1B, 0x02, 0x80, -0x60, 0x1B, 0x02, 0x80, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, -0x20, 0x65, 0x6C, 0x65, 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x49, 0x44, 0x3A, -0x20, 0x25, 0x78, 0x2C, 0x20, 0x63, 0x6D, 0x64, 0x20, 0x73, 0x65, 0x71, -0x3D, 0x25, 0x78, 0x2C, 0x20, 0x68, 0x32, 0x64, 0x73, 0x65, 0x71, 0x3D, -0x25, 0x78, 0x0A, 0x00, 0x6A, 0x6F, 0x69, 0x6E, 0x62, 0x73, 0x73, 0x5F, -0x68, 0x64, 0x6C, 0x00, 0x67, 0x65, 0x74, 0x20, 0x6A, 0x6F, 0x69, 0x6E, -0x20, 0x63, 0x6D, 0x64, 0x0A, 0x00, 0x00, 0x00, 0x4E, 0x6F, 0x20, 0x69, -0x72, 0x70, 0x20, 0x25, 0x73, 0x0A, 0x00, 0x00, 0x73, 0x65, 0x74, 0x20, -0x6F, 0x70, 0x6D, 0x6F, 0x64, 0x65, 0x3A, 0x20, 0x25, 0x78, 0x0A, 0x00, -0x67, 0x65, 0x74, 0x20, 0x73, 0x75, 0x72, 0x76, 0x65, 0x79, 0x20, 0x63, -0x6D, 0x64, 0x0A, 0x00, 0x53, 0x53, 0x49, 0x44, 0x3A, 0x20, 0x25, 0x73, -0x0A, 0x00, 0x00, 0x00, 0x73, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x3A, -0x20, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x72, 0x63, 0x76, 0x20, -0x73, 0x65, 0x74, 0x5F, 0x73, 0x74, 0x61, 0x6B, 0x65, 0x79, 0x0A, 0x00, -0x54, 0x78, 0x5F, 0x42, 0x65, 0x61, 0x63, 0x6F, 0x6E, 0x5F, 0x68, 0x64, -0x6C, 0x00, 0x00, 0x00, 0x74, 0x78, 0x20, 0x62, 0x65, 0x61, 0x63, 0x6F, -0x6E, 0x20, 0x63, 0x6D, 0x64, 0x28, 0x25, 0x78, 0x29, 0x0A, 0x00, 0x00, -0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x4D, 0x61, 0x63, 0x41, 0x64, -0x64, 0x72, 0x0A, 0x00, 0x00, 0x0E, 0x04, 0x0E, 0x10, 0x0E, 0x14, 0x0E, -0x18, 0x0E, 0x1C, 0x0E, 0x4F, 0x6E, 0x41, 0x73, 0x73, 0x6F, 0x63, 0x52, -0x65, 0x71, 0x00, 0x00, 0x4F, 0x6E, 0x41, 0x73, 0x73, 0x6F, 0x63, 0x52, -0x73, 0x70, 0x00, 0x00, 0x4F, 0x6E, 0x52, 0x65, 0x41, 0x73, 0x73, 0x6F, -0x63, 0x52, 0x65, 0x71, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x6E, 0x52, 0x65, -0x41, 0x73, 0x73, 0x6F, 0x63, 0x52, 0x73, 0x70, 0x00, 0x00, 0x00, 0x00, -0x4F, 0x6E, 0x50, 0x72, 0x6F, 0x62, 0x65, 0x52, 0x65, 0x71, 0x00, 0x00, -0x4F, 0x6E, 0x50, 0x72, 0x6F, 0x62, 0x65, 0x52, 0x73, 0x70, 0x00, 0x00, -0x4F, 0x6E, 0x42, 0x65, 0x61, 0x63, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x00, -0x4F, 0x6E, 0x41, 0x54, 0x49, 0x4D, 0x00, 0x00, 0x4F, 0x6E, 0x44, 0x69, -0x73, 0x61, 0x73, 0x73, 0x6F, 0x63, 0x00, 0x00, 0x4F, 0x6E, 0x41, 0x75, -0x74, 0x68, 0x00, 0x00, 0x4F, 0x6E, 0x44, 0x65, 0x41, 0x75, 0x74, 0x68, -0x00, 0x00, 0x00, 0x00, 0x4F, 0x6E, 0x41, 0x63, 0x74, 0x69, 0x6F, 0x6E, -0x00, 0x00, 0x00, 0x00, 0x4F, 0x6E, 0x51, 0x6F, 0x73, 0x4E, 0x75, 0x6C, -0x6C, 0x00, 0x00, 0x00, 0x4F, 0x6E, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, -0x69, 0x6F, 0x6E, 0x00, 0x41, 0x54, 0x49, 0x4D, 0x3A, 0x20, 0x25, 0x78, -0x0A, 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x07, 0x07, 0x0D, 0x0D, 0x0D, -0x02, 0x07, 0x07, 0x0D, 0x0D, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, -0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x10, 0x72, 0x65, 0x70, 0x6F, -0x72, 0x74, 0x5F, 0x73, 0x75, 0x72, 0x76, 0x65, 0x79, 0x5F, 0x64, 0x6F, -0x6E, 0x65, 0x00, 0x00, 0x73, 0x75, 0x72, 0x76, 0x65, 0x79, 0x20, 0x64, -0x6F, 0x6E, 0x65, 0x28, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x78, 0x29, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x4E, 0x6F, 0x20, 0x69, 0x72, 0x70, 0x20, 0x25, -0x73, 0x0A, 0x00, 0x00, 0x72, 0x65, 0x70, 0x6F, 0x72, 0x74, 0x5F, 0x6A, -0x6F, 0x69, 0x6E, 0x5F, 0x72, 0x65, 0x73, 0x00, 0x4E, 0x6F, 0x20, 0x69, -0x72, 0x70, 0x28, 0x25, 0x78, 0x29, 0x20, 0x25, 0x73, 0x0A, 0x00, 0x00, -0x6A, 0x6F, 0x69, 0x6E, 0x20, 0x72, 0x65, 0x73, 0x28, 0x25, 0x78, 0x2C, -0x20, 0x25, 0x78, 0x29, 0x0A, 0x00, 0x00, 0x00, 0x72, 0x65, 0x70, 0x6F, -0x72, 0x74, 0x5F, 0x64, 0x65, 0x6C, 0x5F, 0x73, 0x74, 0x61, 0x5F, 0x65, -0x76, 0x65, 0x6E, 0x74, 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6C, 0x20, -0x73, 0x74, 0x61, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x72, 0x65, 0x70, 0x6F, -0x72, 0x74, 0x5F, 0x61, 0x64, 0x64, 0x5F, 0x73, 0x74, 0x61, 0x5F, 0x65, -0x76, 0x65, 0x6E, 0x74, 0x00, 0x00, 0x00, 0x00, 0x61, 0x64, 0x64, 0x20, -0x73, 0x74, 0x61, 0x3A, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x78, 0x0A, 0x00, -0x72, 0x63, 0x76, 0x20, 0x64, 0x69, 0x73, 0x63, 0x6F, 0x6E, 0x6E, 0x65, -0x63, 0x74, 0x0A, 0x00, 0x69, 0x73, 0x73, 0x75, 0x65, 0x5F, 0x70, 0x72, -0x6F, 0x62, 0x65, 0x72, 0x65, 0x71, 0x00, 0x00, 0x4E, 0x6F, 0x20, 0x69, -0x72, 0x70, 0x20, 0x40, 0x25, 0x73, 0x0A, 0x00, 0x57, 0x4D, 0x4D, 0x28, -0x25, 0x78, 0x29, 0x3A, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x78, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x61, 0x73, 0x73, 0x6F, 0x63, 0x20, 0x72, 0x65, -0x6A, 0x65, 0x63, 0x74, 0x2C, 0x20, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, -0x3A, 0x20, 0x25, 0x64, 0x0A, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x63, 0x20, -0x69, 0x64, 0x20, 0x23, 0x35, 0x3A, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x25, -0x78, 0x2C, 0x20, 0x25, 0x78, 0x0A, 0x00, 0x00, 0x69, 0x73, 0x73, 0x75, -0x65, 0x5F, 0x70, 0x72, 0x6F, 0x62, 0x65, 0x72, 0x73, 0x70, 0x00, 0x00, -0x72, 0x65, 0x70, 0x6F, 0x72, 0x74, 0x5F, 0x42, 0x53, 0x53, 0x49, 0x44, -0x5F, 0x69, 0x6E, 0x66, 0x6F, 0x00, 0x00, 0x00, 0x70, 0x61, 0x63, 0x6B, -0x65, 0x74, 0x20, 0x74, 0x6F, 0x6F, 0x20, 0x6C, 0x61, 0x72, 0x67, 0x65, -0x28, 0x25, 0x78, 0x29, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x50, 0xF2, 0x01, -0x69, 0x6E, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x20, 0x63, 0x61, 0x70, 0x3A, -0x25, 0x78, 0x0A, 0x00, 0x49, 0x42, 0x53, 0x53, 0x20, 0x6D, 0x6F, 0x64, -0x65, 0x2C, 0x20, 0x63, 0x75, 0x72, 0x20, 0x63, 0x68, 0x61, 0x6E, 0x6E, -0x65, 0x6C, 0x3A, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x62, 0x63, 0x6E, 0x20, -0x69, 0x6E, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6C, 0x3A, 0x20, 0x25, 0x78, -0x0A, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x63, 0x20, 0x69, 0x64, 0x20, 0x23, -0x34, 0x3A, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x78, 0x0A, 0x00, 0x00, -0x63, 0x75, 0x72, 0x20, 0x63, 0x68, 0x61, 0x6E, 0x6E, 0x65, 0x6C, 0x3A, -0x20, 0x25, 0x78, 0x2C, 0x20, 0x62, 0x63, 0x6E, 0x20, 0x69, 0x6E, 0x74, -0x65, 0x72, 0x76, 0x61, 0x6C, 0x3A, 0x20, 0x25, 0x78, 0x0A, 0x00, 0x00, -0x69, 0x73, 0x73, 0x75, 0x65, 0x5F, 0x61, 0x73, 0x73, 0x6F, 0x63, 0x72, -0x65, 0x71, 0x00, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x69, 0x73, 0x73, 0x75, -0x65, 0x20, 0x61, 0x73, 0x73, 0x6F, 0x63, 0x72, 0x65, 0x71, 0x28, 0x25, -0x78, 0x29, 0x0A, 0x00, 0x5B, 0x57, 0x41, 0x50, 0x49, 0x5D, 0x20, 0x67, -0x65, 0x74, 0x20, 0x77, 0x61, 0x70, 0x69, 0x20, 0x49, 0x45, 0x0A, 0x00, -0x69, 0x73, 0x73, 0x75, 0x65, 0x5F, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, -0x00, 0x00, 0x00, 0x00, 0x69, 0x73, 0x73, 0x75, 0x65, 0x20, 0x61, 0x63, -0x74, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x78, -0x2C, 0x20, 0x25, 0x78, 0x20, 0x0A, 0x00, 0x00, 0x44, 0x45, 0x4C, 0x42, -0x41, 0x3A, 0x20, 0x25, 0x78, 0x28, 0x25, 0x78, 0x29, 0x0A, 0x00, 0x00, -0x41, 0x44, 0x44, 0x42, 0x41, 0x20, 0x52, 0x53, 0x50, 0x3A, 0x20, 0x25, -0x78, 0x0A, 0x00, 0x00, 0x69, 0x73, 0x73, 0x75, 0x65, 0x5F, 0x61, 0x75, -0x74, 0x68, 0x00, 0x00, 0x69, 0x73, 0x73, 0x75, 0x65, 0x20, 0x61, 0x75, -0x74, 0x68, 0x0A, 0x00, 0x63, 0x6C, 0x6E, 0x74, 0x20, 0x61, 0x75, 0x74, -0x68, 0x20, 0x66, 0x61, 0x69, 0x6C, 0x65, 0x64, 0x20, 0x64, 0x75, 0x65, -0x20, 0x74, 0x6F, 0x20, 0x69, 0x6C, 0x6C, 0x65, 0x67, 0x61, 0x6C, 0x20, -0x73, 0x65, 0x71, 0x3D, 0x25, 0x78, 0x0A, 0x00, 0x63, 0x6C, 0x6E, 0x74, -0x20, 0x61, 0x75, 0x74, 0x68, 0x20, 0x66, 0x61, 0x69, 0x6C, 0x2C, 0x20, -0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3A, 0x20, 0x25, 0x64, 0x0A, 0x00, -0x6E, 0x6F, 0x20, 0x63, 0x68, 0x61, 0x6C, 0x6C, 0x65, 0x6E, 0x67, 0x65, -0x20, 0x74, 0x65, 0x78, 0x74, 0x3F, 0x0A, 0x00, 0x6C, 0x69, 0x6E, 0x6B, -0x20, 0x74, 0x6F, 0x20, 0x75, 0x6E, 0x6B, 0x6E, 0x6F, 0x77, 0x6E, 0x20, -0x41, 0x50, 0x0A, 0x00, 0x6C, 0x69, 0x6E, 0x6B, 0x20, 0x74, 0x6F, 0x20, -0x41, 0x74, 0x68, 0x65, 0x72, 0x6F, 0x73, 0x20, 0x41, 0x50, 0x28, 0x4D, -0x41, 0x43, 0x29, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x63, 0x20, -0x69, 0x64, 0x20, 0x23, 0x25, 0x78, 0x3A, 0x20, 0x25, 0x78, 0x2C, 0x20, -0x25, 0x78, 0x0A, 0x00, 0x6C, 0x69, 0x6E, 0x6B, 0x20, 0x74, 0x6F, 0x20, -0x42, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x6F, 0x6D, 0x20, 0x41, 0x50, 0x0A, -0x00, 0x00, 0x00, 0x00, 0x6C, 0x69, 0x6E, 0x6B, 0x20, 0x74, 0x6F, 0x20, -0x41, 0x74, 0x68, 0x65, 0x72, 0x6F, 0x73, 0x20, 0x41, 0x50, 0x0A, 0x00, -0x6C, 0x69, 0x6E, 0x6B, 0x20, 0x74, 0x6F, 0x20, 0x4D, 0x61, 0x72, 0x76, -0x65, 0x6C, 0x6C, 0x20, 0x41, 0x50, 0x0A, 0x00, 0x6C, 0x69, 0x6E, 0x6B, -0x20, 0x74, 0x6F, 0x20, 0x52, 0x65, 0x61, 0x6C, 0x74, 0x65, 0x6B, 0x20, -0x39, 0x36, 0x42, 0x20, 0x41, 0x50, 0x0A, 0x00, 0x6C, 0x69, 0x6E, 0x6B, -0x20, 0x74, 0x6F, 0x20, 0x43, 0x69, 0x73, 0x63, 0x6F, 0x20, 0x41, 0x50, -0x0A, 0x00, 0x00, 0x00, 0x6C, 0x69, 0x6E, 0x6B, 0x20, 0x74, 0x6F, 0x20, -0x52, 0x61, 0x6C, 0x69, 0x6E, 0x6B, 0x20, 0x41, 0x50, 0x0A, 0x00, 0x00, -0x6C, 0x69, 0x6E, 0x6B, 0x20, 0x74, 0x6F, 0x20, 0x52, 0x65, 0x61, 0x6C, -0x74, 0x65, 0x6B, 0x20, 0x39, 0x36, 0x42, 0x20, 0x41, 0x50, 0x20, 0x77, -0x69, 0x74, 0x68, 0x20, 0x76, 0x69, 0x64, 0x65, 0x6F, 0x20, 0x6D, 0x6F, -0x64, 0x65, 0x0A, 0x00, 0x69, 0x73, 0x73, 0x75, 0x65, 0x5F, 0x64, 0x65, -0x61, 0x75, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 0x69, 0x73, 0x73, 0x75, -0x65, 0x5F, 0x64, 0x65, 0x61, 0x75, 0x74, 0x68, 0x0A, 0x00, 0x00, 0x00, -0x69, 0x73, 0x73, 0x75, 0x65, 0x5F, 0x64, 0x69, 0x73, 0x61, 0x73, 0x73, -0x6F, 0x63, 0x00, 0x00, 0x69, 0x73, 0x73, 0x75, 0x65, 0x5F, 0x64, 0x69, -0x73, 0x61, 0x73, 0x73, 0x6F, 0x63, 0x0A, 0x00, 0x69, 0x73, 0x73, 0x75, -0x65, 0x5F, 0x66, 0x72, 0x61, 0x6D, 0x65, 0x5F, 0x6C, 0x65, 0x6E, 0x00, -0x64, 0x69, 0x73, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x20, 0x74, -0x69, 0x6D, 0x65, 0x72, 0x3A, 0x20, 0x6E, 0x6F, 0x20, 0x62, 0x65, 0x61, -0x63, 0x6F, 0x6E, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x64, 0x69, 0x73, 0x63, -0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x28, 0x6E, 0x6F, 0x20, 0x64, 0x61, -0x74, 0x61, 0x20, 0x72, 0x63, 0x76, 0x64, 0x29, 0x0A, 0x00, 0x00, 0x00, -0x69, 0x73, 0x73, 0x75, 0x65, 0x20, 0x51, 0x6F, 0x73, 0x4E, 0x75, 0x6C, -0x6C, 0x28, 0x25, 0x64, 0x29, 0x00, 0x00, 0x00, 0x60, 0x1B, 0x02, 0x80, -0xB0, 0x03, 0x25, 0xB0, 0x18, 0x03, 0x25, 0xB0, 0x44, 0x44, 0x33, 0x33, -0x06, 0x00, 0x2A, 0xB0, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB4, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0x38, 0x4A, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0x2C, 0x4A, 0x01, 0x80, 0x20, 0x4A, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0x14, 0x4A, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0x08, 0x4A, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xFC, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xF0, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xE4, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xD8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xCC, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, 0xB8, 0x49, 0x01, 0x80, -0xB8, 0x49, 0x01, 0x80, 0xC0, 0x49, 0x01, 0x80, 0xF8, 0x4A, 0x01, 0x80, -0xEC, 0x4A, 0x01, 0x80, 0xE0, 0x4A, 0x01, 0x80, 0xD4, 0x4A, 0x01, 0x80, -0xC8, 0x4A, 0x01, 0x80, 0xBC, 0x4A, 0x01, 0x80, 0xB0, 0x4A, 0x01, 0x80, -0xA4, 0x4A, 0x01, 0x80, 0x98, 0x4A, 0x01, 0x80, 0x8C, 0x4A, 0x01, 0x80, -0x80, 0x4A, 0x01, 0x80, 0x74, 0x4A, 0x01, 0x80, 0x00, 0x50, 0xF2, 0x01, -0x00, 0x50, 0xF2, 0x02, 0x00, 0x0F, 0xAC, 0x02, 0x30, 0x31, 0x32, 0x33, -0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, -0x00, 0x00, 0x00, 0x00, 0x25, 0x64, 0x2E, 0x00, 0x25, 0x68, 0x68, 0x58, -0x3A, 0x00, 0x00, 0x00, 0xEC, 0xEE, 0x01, 0x80, 0x67, 0x66, 0x66, 0x66, -0x87, 0x7C, 0x00, 0x80, 0x5D, 0x7C, 0x00, 0x80, 0x37, 0x7C, 0x00, 0x80, -0x11, 0x7C, 0x00, 0x80, 0xC1, 0x7B, 0x00, 0x80, 0x9B, 0x7B, 0x00, 0x80, -0xEB, 0x7B, 0x00, 0x80, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x63, -0x61, 0x6D, 0x20, 0x65, 0x6E, 0x74, 0x72, 0x79, 0x20, 0x28, 0x25, 0x78, -0x2C, 0x20, 0x25, 0x78, 0x29, 0x0A, 0x00, 0x00, 0x2D, 0x3E, 0x28, 0x25, -0x78, 0x2C, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x25, 0x78, 0x2C, 0x20, 0x25, -0x78, 0x29, 0x0A, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, -0xDF, 0x88, 0x00, 0x80, 0xE5, 0x88, 0x00, 0x80, 0xEB, 0x88, 0x00, 0x80, -0xF1, 0x88, 0x00, 0x80, 0xDF, 0x88, 0x00, 0x80, 0xDF, 0x88, 0x00, 0x80, -0xDF, 0x88, 0x00, 0x80, 0xDF, 0x88, 0x00, 0x80, 0xF7, 0x88, 0x00, 0x80, -0xFD, 0x88, 0x00, 0x80, 0x03, 0x89, 0x00, 0x80, 0x09, 0x89, 0x00, 0x80, -0x60, 0x1B, 0x02, 0x80, 0x55, 0x6E, 0x69, 0x20, 0x4F, 0x6B, 0x3A, 0x20, -0x41, 0x50, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xC0, 0xFF, -0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0xFF, 0x03, 0xFE, 0x01, 0x80, 0x7F, -0xE2, 0x01, 0x80, 0x78, 0xC7, 0x01, 0xC0, 0x71, 0xAE, 0x01, 0x80, 0x6B, -0x95, 0x01, 0x40, 0x65, 0x7F, 0x01, 0xC0, 0x5F, 0x69, 0x01, 0x40, 0x5A, -0x55, 0x01, 0x40, 0x55, 0x42, 0x01, 0x80, 0x50, 0x30, 0x01, 0x00, 0x4C, -0x1F, 0x01, 0xC0, 0x47, 0x0F, 0x01, 0xC0, 0x43, 0x00, 0x01, 0x00, 0x40, -0xF2, 0x00, 0x80, 0x3C, 0xE4, 0x00, 0x00, 0x39, 0xD7, 0x00, 0xC0, 0x35, -0xCB, 0x00, 0xC0, 0x32, 0xC0, 0x00, 0x00, 0x30, 0xB5, 0x00, 0x40, 0x2D, -0xAB, 0x00, 0xC0, 0x2A, 0xA2, 0x00, 0x80, 0x28, 0x98, 0x00, 0x00, 0x26, -0x90, 0x00, 0x00, 0x24, 0x88, 0x00, 0x00, 0x22, 0x80, 0x00, 0x00, 0x20, -0x79, 0x00, 0x40, 0x1E, 0x72, 0x00, 0x80, 0x1C, 0x6C, 0x00, 0x00, 0x1B, -0x66, 0x00, 0x80, 0x19, 0x60, 0x00, 0x00, 0x18, 0x5B, 0x00, 0xC0, 0x16, -0x56, 0x00, 0x80, 0x15, 0x51, 0x00, 0x40, 0x14, 0x4C, 0x00, 0x00, 0x13, -0x48, 0x00, 0x00, 0x12, 0x44, 0x00, 0x00, 0x11, 0x40, 0x00, 0x00, 0x10, -0x36, 0x35, 0x2E, 0x25, 0x1C, 0x12, 0x09, 0x04, 0x33, 0x32, 0x2B, 0x23, -0x1A, 0x11, 0x08, 0x04, 0x30, 0x2F, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03, -0x2D, 0x2D, 0x27, 0x1F, 0x18, 0x0F, 0x08, 0x03, 0x2B, 0x2A, 0x25, 0x1E, -0x16, 0x0E, 0x07, 0x03, 0x28, 0x28, 0x22, 0x1C, 0x15, 0x0D, 0x07, 0x03, -0x26, 0x25, 0x21, 0x1B, 0x14, 0x0D, 0x06, 0x03, 0x24, 0x23, 0x1F, 0x19, -0x13, 0x0C, 0x06, 0x03, 0x22, 0x21, 0x1D, 0x18, 0x11, 0x0B, 0x06, 0x02, -0x20, 0x20, 0x1B, 0x16, 0x11, 0x08, 0x05, 0x02, 0x1F, 0x1E, 0x1A, 0x15, -0x10, 0x0A, 0x05, 0x02, 0x1D, 0x1C, 0x18, 0x14, 0x0F, 0x0A, 0x05, 0x02, -0x1B, 0x1A, 0x17, 0x13, 0x0E, 0x09, 0x04, 0x02, 0x1A, 0x19, 0x16, 0x12, -0x0D, 0x09, 0x04, 0x02, 0x18, 0x17, 0x15, 0x11, 0x0C, 0x08, 0x04, 0x02, -0x17, 0x16, 0x13, 0x10, 0x0C, 0x08, 0x04, 0x02, 0x16, 0x15, 0x12, 0x0F, -0x0B, 0x07, 0x04, 0x01, 0x14, 0x14, 0x11, 0x0E, 0x0B, 0x07, 0x03, 0x02, -0x13, 0x13, 0x10, 0x0D, 0x0A, 0x06, 0x03, 0x01, 0x12, 0x12, 0x0F, 0x0C, -0x09, 0x06, 0x03, 0x01, 0x11, 0x11, 0x0F, 0x0C, 0x09, 0x06, 0x03, 0x01, -0x10, 0x10, 0x0E, 0x0B, 0x08, 0x05, 0x03, 0x01, 0x0F, 0x0F, 0x0D, 0x0B, -0x08, 0x05, 0x03, 0x01, 0x0E, 0x0E, 0x0C, 0x0A, 0x08, 0x05, 0x02, 0x01, -0x0D, 0x0D, 0x0C, 0x0A, 0x07, 0x05, 0x02, 0x01, 0x0D, 0x0C, 0x0B, 0x09, -0x07, 0x04, 0x02, 0x01, 0x0C, 0x0C, 0x0A, 0x09, 0x06, 0x04, 0x02, 0x01, -0x0B, 0x0B, 0x0A, 0x08, 0x06, 0x04, 0x02, 0x01, 0x0B, 0x0A, 0x09, 0x08, -0x06, 0x04, 0x02, 0x01, 0x0A, 0x0A, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01, -0x0A, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01, 0x09, 0x09, 0x08, 0x06, -0x05, 0x03, 0x01, 0x01, 0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01, -0x36, 0x35, 0x2E, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x33, 0x32, 0x2B, 0x19, -0x00, 0x00, 0x00, 0x00, 0x30, 0x2F, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00, -0x2D, 0x2D, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x2A, 0x25, 0x15, -0x00, 0x00, 0x00, 0x00, 0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00, -0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 0x24, 0x23, 0x1F, 0x12, -0x00, 0x00, 0x00, 0x00, 0x22, 0x21, 0x1D, 0x11, 0x00, 0x00, 0x00, 0x00, -0x20, 0x20, 0x1B, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x1E, 0x1A, 0x0F, -0x00, 0x00, 0x00, 0x00, 0x1D, 0x1C, 0x18, 0x0E, 0x00, 0x00, 0x00, 0x00, -0x1B, 0x1A, 0x17, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x19, 0x16, 0x0D, -0x00, 0x00, 0x00, 0x00, 0x18, 0x17, 0x15, 0x0C, 0x00, 0x00, 0x00, 0x00, -0x17, 0x16, 0x13, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x16, 0x15, 0x12, 0x0B, -0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x11, 0x0A, 0x00, 0x00, 0x00, 0x00, -0x13, 0x13, 0x10, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x12, 0x12, 0x0F, 0x09, -0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x0F, 0x09, 0x00, 0x00, 0x00, 0x00, -0x10, 0x10, 0x0E, 0x08, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0D, 0x08, -0x00, 0x00, 0x00, 0x00, 0x0E, 0x0E, 0x0C, 0x07, 0x00, 0x00, 0x00, 0x00, -0x0D, 0x0D, 0x0C, 0x07, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0C, 0x0B, 0x06, -0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x0A, 0x06, 0x00, 0x00, 0x00, 0x00, -0x0B, 0x0B, 0x0A, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x0A, 0x09, 0x05, -0x00, 0x00, 0x00, 0x00, 0x0A, 0x0A, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00, -0x0A, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x08, 0x05, -0x00, 0x00, 0x00, 0x00, 0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00, -0x72, 0x65, 0x73, 0x65, 0x74, 0x28, 0x25, 0x78, 0x29, 0x0A, 0x00, 0x00, -0x50, 0x53, 0x00, 0x00, 0xE8, 0x86, 0x01, 0x80, 0x58, 0x87, 0x01, 0x80, -0x14, 0x87, 0x01, 0x80, 0x58, 0x87, 0x01, 0x80, 0x58, 0x87, 0x01, 0x80, -0x58, 0x87, 0x01, 0x80, 0x58, 0x87, 0x01, 0x80, 0xC0, 0x86, 0x01, 0x80, -0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, -0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, -0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, -0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, -0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, -0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, -0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -0x08, 0x28, 0x28, 0x28, 0x28, 0x28, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, -0xA0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, -0x10, 0x10, 0x10, 0x10, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, -0x04, 0x04, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x41, 0x41, 0x41, -0x41, 0x41, 0x41, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, -0x10, 0x10, 0x10, 0x10, 0x10, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x02, -0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, -0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x10, 0x10, 0x10, 0x10, 0x08, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x10, 0x10, 0x10, -0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, -0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, -0x10, 0x10, 0x10, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, -0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, -0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x10, -0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x2D, 0x5C, 0x7C, 0x2F, -0x00, 0x00, 0x00, 0x00, 0x0A, 0xD6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xF0, 0xF4, 0x5E, 0x00, 0xF0, 0xF4, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xE5, 0x5E, 0x00, -0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xB8, 0xA0, 0xFC, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, -}; diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c index 014fbbcbda27..8323c6aa8188 100644 --- a/drivers/staging/rtl8712/hal_init.c +++ b/drivers/staging/rtl8712/hal_init.c @@ -40,7 +40,7 @@ static u32 rtl871x_open_fw(struct _adapter *padapter, void **pphfwfile_hdl, const u8 **ppmappedfw) { int rc; - const char firmware_file[] = "rtl8712u/rtl8712u.bin"; + const char firmware_file[] = "rtlwifi/rtl8712u.bin"; const struct firmware **praw = (const struct firmware **) (pphfwfile_hdl); struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *) @@ -58,6 +58,7 @@ static u32 rtl871x_open_fw(struct _adapter *padapter, void **pphfwfile_hdl, *ppmappedfw = (u8 *)((*praw)->data); return (*praw)->size; } +MODULE_FIRMWARE("rtlwifi/rtl8712u.bin"); static void fill_fwpriv(struct _adapter *padapter, struct fw_priv *pfwpriv) { -- cgit v1.2.3 From a9855917290fc40dbfd67d3ee06c190667d6c5b5 Mon Sep 17 00:00:00 2001 From: Mike Thomas Date: Mon, 10 Jan 2011 18:41:11 +0000 Subject: staging: easycap: add ALSA support This is necessary because some distributions are disabling OSS entirely. Signed-off-by: Mike Thomas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/Kconfig | 2 +- drivers/staging/easycap/Makefile | 11 +- drivers/staging/easycap/easycap.h | 84 +- drivers/staging/easycap/easycap_debug.h | 29 - drivers/staging/easycap/easycap_ioctl.c | 272 ++++--- drivers/staging/easycap/easycap_ioctl.h | 9 + drivers/staging/easycap/easycap_low.c | 17 +- drivers/staging/easycap/easycap_low.h | 34 + drivers/staging/easycap/easycap_main.c | 394 +++++---- drivers/staging/easycap/easycap_main.h | 43 + drivers/staging/easycap/easycap_settings.c | 2 +- drivers/staging/easycap/easycap_settings.h | 34 + drivers/staging/easycap/easycap_sound.c | 1214 ++++++++++++++++++++++++---- drivers/staging/easycap/easycap_sound.h | 14 + drivers/staging/easycap/easycap_standard.h | 27 - drivers/staging/easycap/easycap_testcard.c | 4 +- drivers/staging/easycap/easycap_testcard.h | 34 + 17 files changed, 1673 insertions(+), 551 deletions(-) delete mode 100644 drivers/staging/easycap/easycap_debug.h create mode 100644 drivers/staging/easycap/easycap_low.h create mode 100644 drivers/staging/easycap/easycap_main.h create mode 100644 drivers/staging/easycap/easycap_settings.h delete mode 100644 drivers/staging/easycap/easycap_standard.h create mode 100644 drivers/staging/easycap/easycap_testcard.h (limited to 'drivers') diff --git a/drivers/staging/easycap/Kconfig b/drivers/staging/easycap/Kconfig index bd96f39f2735..eaa8a86e183b 100644 --- a/drivers/staging/easycap/Kconfig +++ b/drivers/staging/easycap/Kconfig @@ -1,6 +1,6 @@ config EASYCAP tristate "EasyCAP USB ID 05e1:0408 support" - depends on USB && VIDEO_DEV + depends on USB && VIDEO_DEV && SND ---help--- This is an integrated audio/video driver for EasyCAP cards with diff --git a/drivers/staging/easycap/Makefile b/drivers/staging/easycap/Makefile index f1f2fbebf8f6..977e1535667d 100644 --- a/drivers/staging/easycap/Makefile +++ b/drivers/staging/easycap/Makefile @@ -1,14 +1,13 @@ +easycap-objs := easycap_main.o easycap_low.o easycap_sound.o \ + easycap_ioctl.o easycap_settings.o easycap_testcard.o -obj-$(CONFIG_EASYCAP) += easycap.o - -easycap-y := easycap_main.o easycap_low.o easycap_sound.o -easycap-y += easycap_ioctl.o easycap_settings.o -easycap-y += easycap_testcard.o +obj-$(CONFIG_EASYCAP) += easycap.o ccflags-y := -Wall -# Impose all or none of the following: ccflags-y += -DEASYCAP_IS_VIDEODEV_CLIENT ccflags-y += -DEASYCAP_NEEDS_V4L2_DEVICE_H ccflags-y += -DEASYCAP_NEEDS_V4L2_FOPS ccflags-y += -DEASYCAP_NEEDS_UNLOCKED_IOCTL +ccflags-y += -DEASYCAP_NEEDS_ALSA +ccflags-y += -DEASYCAP_NEEDS_CARD_CREATE diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 063d44718d8d..111f53c33229 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -34,6 +34,8 @@ * EASYCAP_NEEDS_V4L2_DEVICE_H * EASYCAP_NEEDS_V4L2_FOPS * EASYCAP_NEEDS_UNLOCKED_IOCTL + * EASYCAP_NEEDS_ALSA + * EASYCAP_SILENT * * IF REQUIRED THEY MUST BE EXTERNALLY DEFINED, FOR EXAMPLE AS COMPILER * OPTIONS. @@ -57,9 +59,9 @@ */ /*---------------------------------------------------------------------------*/ #undef EASYCAP_TESTCARD +#if (!defined(EASYCAP_NEEDS_ALSA)) #undef EASYCAP_TESTTONE -#undef NOREADBACK -#undef AUDIOTIME +#endif /*EASYCAP_NEEDS_ALSA*/ /*---------------------------------------------------------------------------*/ #include #include @@ -79,6 +81,16 @@ #include #include +#if defined(EASYCAP_NEEDS_ALSA) +#include +#include +#include +#include +#include +#include +#include +#include +#endif /*EASYCAP_NEEDS_ALSA*/ /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #if defined(EASYCAP_IS_VIDEODEV_CLIENT) #include @@ -112,7 +124,7 @@ #define USB_EASYCAP_VENDOR_ID 0x05e1 #define USB_EASYCAP_PRODUCT_ID 0x0408 -#define EASYCAP_DRIVER_VERSION "0.8.41" +#define EASYCAP_DRIVER_VERSION "0.9.01" #define EASYCAP_DRIVER_DESCRIPTION "easycapdc60" #define USB_SKEL_MINOR_BASE 192 @@ -158,7 +170,8 @@ */ /*---------------------------------------------------------------------------*/ #define AUDIO_ISOC_BUFFER_MANY 16 -#define AUDIO_ISOC_ORDER 3 +#define AUDIO_ISOC_ORDER 1 +#define AUDIO_ISOC_FRAMESPERDESC 32 #define AUDIO_ISOC_BUFFER_SIZE (PAGE_SIZE << AUDIO_ISOC_ORDER) /*---------------------------------------------------------------------------*/ /* @@ -166,6 +179,7 @@ */ /*---------------------------------------------------------------------------*/ #define AUDIO_FRAGMENT_MANY 32 +#define PAGES_PER_AUDIO_FRAGMENT 4 /*---------------------------------------------------------------------------*/ /* * IT IS ESSENTIAL THAT EVEN-NUMBERED STANDARDS ARE 25 FRAMES PER SECOND, @@ -296,6 +310,7 @@ struct easycap { #define TELLTALE "expectedstring" char telltale[16]; int isdongle; +int minor; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #if defined(EASYCAP_IS_VIDEODEV_CLIENT) @@ -328,6 +343,7 @@ int done[FRAME_BUFFER_MANY]; wait_queue_head_t wq_video; wait_queue_head_t wq_audio; +wait_queue_head_t wq_trigger; int input; int polled; @@ -428,6 +444,20 @@ int allocation_video_page; int allocation_video_struct; int registered_video; /*---------------------------------------------------------------------------*/ +/* + * ALSA + */ +/*---------------------------------------------------------------------------*/ +#if defined(EASYCAP_NEEDS_ALSA) +struct snd_pcm_hardware alsa_hardware; +struct snd_card *psnd_card; +struct snd_pcm *psnd_pcm; +struct snd_pcm_substream *psubstream; +int dma_fill; +int dma_next; +int dma_read; +#endif /*EASYCAP_NEEDS_ALSA*/ +/*---------------------------------------------------------------------------*/ /* * SOUND PROPERTIES */ @@ -455,10 +485,10 @@ struct list_head *purb_audio_head; * BUFFER INDICATORS */ /*---------------------------------------------------------------------------*/ -int audio_fill; /* Audio buffer being filled by easysnd_complete(). */ - /* Bumped only by easysnd_complete(). */ -int audio_read; /* Audio buffer page being read by easysnd_read(). */ - /* Set by easysnd_read() to trail audio_fill by */ +int audio_fill; /* Audio buffer being filled by easycap_complete(). */ + /* Bumped only by easycap_complete(). */ +int audio_read; /* Audio buffer page being read by easycap_read(). */ + /* Set by easycap_read() to trail audio_fill by */ /* one fragment. */ /*---------------------------------------------------------------------------*/ /* @@ -532,19 +562,39 @@ int adjust_volume(struct easycap *, int); * AUDIO FUNCTION PROTOTYPES */ /*---------------------------------------------------------------------------*/ -void easysnd_complete(struct urb *); -ssize_t easysnd_read(struct file *, char __user *, size_t, loff_t *); -int easysnd_open(struct inode *, struct file *); -int easysnd_release(struct inode *, struct file *); -long easysnd_ioctl_noinode(struct file *, unsigned int, \ +#if defined(EASYCAP_NEEDS_ALSA) +int easycap_alsa_probe(struct easycap *); + +void easycap_alsa_complete(struct urb *); +int easycap_alsa_open(struct snd_pcm_substream *); +int easycap_alsa_close(struct snd_pcm_substream *); +int easycap_alsa_hw_params(struct snd_pcm_substream *, \ + struct snd_pcm_hw_params *); +int easycap_alsa_vmalloc(struct snd_pcm_substream *, size_t); +int easycap_alsa_hw_free(struct snd_pcm_substream *); +int easycap_alsa_prepare(struct snd_pcm_substream *); +int easycap_alsa_ack(struct snd_pcm_substream *); +int easycap_alsa_trigger(struct snd_pcm_substream *, int); +snd_pcm_uframes_t \ + easycap_alsa_pointer(struct snd_pcm_substream *); +struct page *easycap_alsa_page(struct snd_pcm_substream *, unsigned long); + +#else +void easyoss_complete(struct urb *); +ssize_t easyoss_read(struct file *, char __user *, size_t, loff_t *); +int easyoss_open(struct inode *, struct file *); +int easyoss_release(struct inode *, struct file *); +long easyoss_ioctl_noinode(struct file *, unsigned int, \ unsigned long); -int easysnd_ioctl(struct inode *, struct file *, unsigned int, \ +int easyoss_ioctl(struct inode *, struct file *, unsigned int, \ unsigned long); -unsigned int easysnd_poll(struct file *, poll_table *); -void easysnd_delete(struct kref *); +unsigned int easyoss_poll(struct file *, poll_table *); +void easyoss_delete(struct kref *); +#endif /*EASYCAP_NEEDS_ALSA*/ +int easycap_sound_setup(struct easycap *); int submit_audio_urbs(struct easycap *); int kill_audio_urbs(struct easycap *); -void easysnd_testtone(struct easycap *, int); +void easyoss_testtone(struct easycap *, int); int audio_setup(struct easycap *); /*---------------------------------------------------------------------------*/ /* diff --git a/drivers/staging/easycap/easycap_debug.h b/drivers/staging/easycap/easycap_debug.h deleted file mode 100644 index b6b571843125..000000000000 --- a/drivers/staging/easycap/easycap_debug.h +++ /dev/null @@ -1,29 +0,0 @@ -/***************************************************************************** -* * -* easycap_debug.h * -* * -*****************************************************************************/ -/* - * - * Copyright (C) 2010 R.M. Thomas - * - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * -*/ -/*****************************************************************************/ -extern int easycap_debug; -extern int easycap_gain; -extern struct easycap_dongle easycap_dongle[]; diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 447953a4e80c..20d30334233e 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -27,8 +27,6 @@ #include #include "easycap.h" -#include "easycap_debug.h" -#include "easycap_standard.h" #include "easycap_ioctl.h" /*--------------------------------------------------------------------------*/ @@ -910,7 +908,7 @@ return -ENOENT; * peasycap->audio_interface, \ * peasycap->audio_altsetting_off); * HOWEVER, AFTER THIS COMMAND IS ISSUED ALL SUBSEQUENT URBS RECEIVE STATUS - * -ESHUTDOWN. THE HANDLER ROUTINE easysnd_complete() DECLINES TO RESUBMIT + * -ESHUTDOWN. THE HANDLER ROUTINE easyxxx_complete() DECLINES TO RESUBMIT * THE URB AND THE PIPELINE COLLAPSES IRRETRIEVABLY. BEWARE. */ /*---------------------------------------------------------------------------*/ @@ -991,11 +989,12 @@ if (NULL == p) { } kd = isdongle(peasycap); if (0 <= kd && DONGLE_MANY > kd) { - if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_video)) { - SAY("ERROR: cannot lock easycap_dongle[%i].mutex_video\n", kd); + if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { + SAY("ERROR: cannot lock " \ + "easycapdc60_dongle[%i].mutex_video\n", kd); return -ERESTARTSYS; } - JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd); + JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd); /*---------------------------------------------------------------------------*/ /* * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap, @@ -1007,24 +1006,24 @@ if (0 <= kd && DONGLE_MANY > kd) { return -ERESTARTSYS; if (NULL == file) { SAY("ERROR: file is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; } peasycap = file->private_data; if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { SAY("ERROR: bad peasycap\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } p = peasycap->pusb_device; if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; } } else { @@ -1048,7 +1047,7 @@ case VIDIOC_QUERYCAP: { if (16 <= strlen(EASYCAP_DRIVER_VERSION)) { SAM("ERROR: bad driver version string\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } strcpy(&version[0], EASYCAP_DRIVER_VERSION); @@ -1066,7 +1065,8 @@ case VIDIOC_QUERYCAP: { if (0 != rc) { SAM("ERROR: %i=strict_strtol(%s,.,,)\n", \ rc, p1); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].\ + mutex_video); return -EINVAL; } k[i] = (int)lng; @@ -1097,7 +1097,7 @@ case VIDIOC_QUERYCAP: { } if (0 != copy_to_user((void __user *)arg, &v4l2_capability, \ sizeof(struct v4l2_capability))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } break; @@ -1111,7 +1111,7 @@ case VIDIOC_ENUMINPUT: { if (0 != copy_from_user(&v4l2_input, (void __user *)arg, \ sizeof(struct v4l2_input))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } @@ -1193,14 +1193,14 @@ case VIDIOC_ENUMINPUT: { } default: { JOM(8, "%i=index: exhausts inputs\n", index); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } } if (0 != copy_to_user((void __user *)arg, &v4l2_input, \ sizeof(struct v4l2_input))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } break; @@ -1213,7 +1213,7 @@ case VIDIOC_G_INPUT: { index = (__u32)peasycap->input; JOM(8, "user is told: %i\n", index); if (0 != copy_to_user((void __user *)arg, &index, sizeof(__u32))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } break; @@ -1227,7 +1227,7 @@ case VIDIOC_S_INPUT: JOM(8, "VIDIOC_S_INPUT\n"); if (0 != copy_from_user(&index, (void __user *)arg, sizeof(__u32))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } @@ -1240,7 +1240,7 @@ case VIDIOC_S_INPUT: if ((0 > index) || (INPUT_MANY <= index)) { JOM(8, "ERROR: bad requested input: %i\n", index); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } @@ -1249,7 +1249,7 @@ case VIDIOC_S_INPUT: JOM(8, "newinput(.,%i) OK\n", (int)index); } else { SAM("ERROR: newinput(.,%i) returned %i\n", (int)index, rc); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } break; @@ -1257,7 +1257,7 @@ case VIDIOC_S_INPUT: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_ENUMAUDIO: { JOM(8, "VIDIOC_ENUMAUDIO\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1268,12 +1268,12 @@ case VIDIOC_ENUMAUDOUT: { if (0 != copy_from_user(&v4l2_audioout, (void __user *)arg, \ sizeof(struct v4l2_audioout))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } if (0 != v4l2_audioout.index) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } memset(&v4l2_audioout, 0, sizeof(struct v4l2_audioout)); @@ -1282,7 +1282,7 @@ case VIDIOC_ENUMAUDOUT: { if (0 != copy_to_user((void __user *)arg, &v4l2_audioout, \ sizeof(struct v4l2_audioout))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } break; @@ -1296,7 +1296,7 @@ case VIDIOC_QUERYCTRL: { if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg, \ sizeof(struct v4l2_queryctrl))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } @@ -1313,12 +1313,12 @@ case VIDIOC_QUERYCTRL: { } if (0xFFFFFFFF == easycap_control[i1].id) { JOM(8, "%i=index: exhausts controls\n", i1); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } if (0 != copy_to_user((void __user *)arg, &v4l2_queryctrl, \ sizeof(struct v4l2_queryctrl))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } break; @@ -1326,7 +1326,7 @@ case VIDIOC_QUERYCTRL: { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_QUERYMENU: { JOM(8, "VIDIOC_QUERYMENU unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1337,13 +1337,13 @@ case VIDIOC_G_CTRL: { pv4l2_control = kzalloc(sizeof(struct v4l2_control), GFP_KERNEL); if (!pv4l2_control) { SAM("ERROR: out of memory\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ENOMEM; } if (0 != copy_from_user(pv4l2_control, (void __user *)arg, \ sizeof(struct v4l2_control))) { kfree(pv4l2_control); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } @@ -1385,14 +1385,14 @@ case VIDIOC_G_CTRL: { SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", \ pv4l2_control->id); kfree(pv4l2_control); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } } if (0 != copy_to_user((void __user *)arg, pv4l2_control, \ sizeof(struct v4l2_control))) { kfree(pv4l2_control); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } kfree(pv4l2_control); @@ -1412,7 +1412,7 @@ case VIDIOC_S_CTRL: if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \ sizeof(struct v4l2_control))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } @@ -1463,7 +1463,7 @@ case VIDIOC_S_CTRL: default: { SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", \ v4l2_control.id); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } } @@ -1472,7 +1472,7 @@ case VIDIOC_S_CTRL: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_S_EXT_CTRLS: { JOM(8, "VIDIOC_S_EXT_CTRLS unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1484,7 +1484,7 @@ case VIDIOC_ENUM_FMT: { if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg, \ sizeof(struct v4l2_fmtdesc))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } @@ -1539,13 +1539,13 @@ case VIDIOC_ENUM_FMT: { } default: { JOM(8, "%i=index: exhausts formats\n", index); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } } if (0 != copy_to_user((void __user *)arg, &v4l2_fmtdesc, \ sizeof(struct v4l2_fmtdesc))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } break; @@ -1564,7 +1564,7 @@ case VIDIOC_ENUM_FRAMESIZES: { if (0 != copy_from_user(&v4l2_frmsizeenum, (void __user *)arg, \ sizeof(struct v4l2_frmsizeenum))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } @@ -1616,7 +1616,7 @@ case VIDIOC_ENUM_FRAMESIZES: { } default: { JOM(8, "%i=index: exhausts framesizes\n", index); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } } @@ -1674,14 +1674,14 @@ case VIDIOC_ENUM_FRAMESIZES: { } default: { JOM(8, "%i=index: exhausts framesizes\n", index); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } } } if (0 != copy_to_user((void __user *)arg, &v4l2_frmsizeenum, \ sizeof(struct v4l2_frmsizeenum))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } break; @@ -1710,7 +1710,7 @@ case VIDIOC_ENUM_FRAMEINTERVALS: { if (0 != copy_from_user(&v4l2_frmivalenum, (void __user *)arg, \ sizeof(struct v4l2_frmivalenum))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } @@ -1737,13 +1737,13 @@ case VIDIOC_ENUM_FRAMEINTERVALS: { } default: { JOM(8, "%i=index: exhausts frameintervals\n", index); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } } if (0 != copy_to_user((void __user *)arg, &v4l2_frmivalenum, \ sizeof(struct v4l2_frmivalenum))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } break; @@ -1757,28 +1757,28 @@ case VIDIOC_G_FMT: { pv4l2_format = kzalloc(sizeof(struct v4l2_format), GFP_KERNEL); if (!pv4l2_format) { SAM("ERROR: out of memory\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ENOMEM; } pv4l2_pix_format = kzalloc(sizeof(struct v4l2_pix_format), GFP_KERNEL); if (!pv4l2_pix_format) { SAM("ERROR: out of memory\n"); kfree(pv4l2_format); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ENOMEM; } if (0 != copy_from_user(pv4l2_format, (void __user *)arg, \ sizeof(struct v4l2_format))) { kfree(pv4l2_format); kfree(pv4l2_pix_format); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } if (pv4l2_format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { kfree(pv4l2_format); kfree(pv4l2_pix_format); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } @@ -1794,7 +1794,7 @@ case VIDIOC_G_FMT: { sizeof(struct v4l2_format))) { kfree(pv4l2_format); kfree(pv4l2_pix_format); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } kfree(pv4l2_format); @@ -1819,7 +1819,7 @@ case VIDIOC_S_FMT: { if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \ sizeof(struct v4l2_format))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } @@ -1831,11 +1831,11 @@ case VIDIOC_S_FMT: { try); if (0 > best_format) { if (-EBUSY == best_format) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EBUSY; } JOM(8, "WARNING: adjust_format() returned %i\n", best_format); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ENOENT; } /*...........................................................................*/ @@ -1848,7 +1848,7 @@ case VIDIOC_S_FMT: { if (0 != copy_to_user((void __user *)arg, &v4l2_format, \ sizeof(struct v4l2_format))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } break; @@ -1861,7 +1861,7 @@ case VIDIOC_CROPCAP: { if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg, \ sizeof(struct v4l2_cropcap))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } @@ -1885,7 +1885,7 @@ case VIDIOC_CROPCAP: { if (0 != copy_to_user((void __user *)arg, &v4l2_cropcap, \ sizeof(struct v4l2_cropcap))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } break; @@ -1894,14 +1894,14 @@ case VIDIOC_CROPCAP: { case VIDIOC_G_CROP: case VIDIOC_S_CROP: { JOM(8, "VIDIOC_G_CROP|VIDIOC_S_CROP unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_QUERYSTD: { JOM(8, "VIDIOC_QUERYSTD: " \ "EasyCAP is incapable of detecting standard\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; break; } @@ -1923,7 +1923,7 @@ case VIDIOC_ENUMSTD: { if (0 != copy_from_user(&v4l2_standard, (void __user *)arg, \ sizeof(struct v4l2_standard))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } index = v4l2_standard.index; @@ -1945,7 +1945,7 @@ case VIDIOC_ENUMSTD: { } if (0xFFFF == peasycap_standard->mask) { JOM(8, "%i=index: exhausts standards\n", index); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } JOM(8, "%i=index: %s\n", index, \ @@ -1957,7 +1957,7 @@ case VIDIOC_ENUMSTD: { if (0 != copy_to_user((void __user *)arg, &v4l2_standard, \ sizeof(struct v4l2_standard))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } break; @@ -1972,13 +1972,13 @@ case VIDIOC_G_STD: { if (0 > peasycap->standard_offset) { JOM(8, "%i=peasycap->standard_offset\n", \ peasycap->standard_offset); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EBUSY; } if (0 != copy_from_user(&std_id, (void __user *)arg, \ sizeof(v4l2_std_id))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } @@ -1990,7 +1990,7 @@ case VIDIOC_G_STD: { if (0 != copy_to_user((void __user *)arg, &std_id, \ sizeof(v4l2_std_id))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } break; @@ -2004,7 +2004,7 @@ case VIDIOC_S_STD: { if (0 != copy_from_user(&std_id, (void __user *)arg, \ sizeof(v4l2_std_id))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } @@ -2015,7 +2015,7 @@ case VIDIOC_S_STD: { rc = adjust_standard(peasycap, std_id); if (0 > rc) { JOM(8, "WARNING: adjust_standard() returned %i\n", rc); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ENOENT; } break; @@ -2029,16 +2029,16 @@ case VIDIOC_REQBUFS: { if (0 != copy_from_user(&v4l2_requestbuffers, (void __user *)arg, \ sizeof(struct v4l2_requestbuffers))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } nbuffers = v4l2_requestbuffers.count; @@ -2059,7 +2059,7 @@ case VIDIOC_REQBUFS: { if (0 != copy_to_user((void __user *)arg, &v4l2_requestbuffers, \ sizeof(struct v4l2_requestbuffers))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } break; @@ -2074,18 +2074,18 @@ case VIDIOC_QUERYBUF: { if (peasycap->video_eof) { JOM(8, "returning -EIO because %i=video_eof\n", \ peasycap->video_eof); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EIO; } if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ sizeof(struct v4l2_buffer))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } index = v4l2_buffer.index; @@ -2117,7 +2117,7 @@ case VIDIOC_QUERYBUF: { if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ sizeof(struct v4l2_buffer))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } break; @@ -2130,21 +2130,21 @@ case VIDIOC_QBUF: { if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ sizeof(struct v4l2_buffer))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } if (v4l2_buffer.memory != V4L2_MEMORY_MMAP) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } if (v4l2_buffer.index < 0 || \ (v4l2_buffer.index >= peasycap->frame_buffer_many)) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED; @@ -2154,7 +2154,7 @@ case VIDIOC_QBUF: { if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ sizeof(struct v4l2_buffer))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } @@ -2187,18 +2187,18 @@ case VIDIOC_DQBUF: JOM(8, "returning -EIO because " \ "%i=video_idle %i=video_eof\n", \ peasycap->video_idle, peasycap->video_eof); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EIO; } if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ sizeof(struct v4l2_buffer))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } @@ -2222,7 +2222,7 @@ case VIDIOC_DQBUF: if (!peasycap->video_isoc_streaming) { JOM(16, "returning -EIO because video urbs not streaming\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EIO; } /*---------------------------------------------------------------------------*/ @@ -2239,18 +2239,19 @@ case VIDIOC_DQBUF: if (-EIO == rcdq) { JOM(8, "returning -EIO because " \ "dqbuf() returned -EIO\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].\ + mutex_video); return -EIO; } } while (0 != rcdq); } else { if (peasycap->video_eof) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EIO; } } if (V4L2_BUF_FLAG_DONE != peasycap->done[peasycap->frame_read]) { - SAM("ERROR: V4L2_BUF_FLAG_DONE != 0x%08X\n", \ + JOM(8, "V4L2_BUF_FLAG_DONE != 0x%08X\n", \ peasycap->done[peasycap->frame_read]); } peasycap->polled = 0; @@ -2337,7 +2338,7 @@ case VIDIOC_DQBUF: if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ sizeof(struct v4l2_buffer))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } @@ -2370,7 +2371,7 @@ case VIDIOC_STREAMON: { peasycap->merit[i] = 0; if ((struct usb_device *)NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } submit_video_urbs(peasycap); @@ -2386,7 +2387,7 @@ case VIDIOC_STREAMOFF: { if ((struct usb_device *)NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } @@ -2400,7 +2401,12 @@ case VIDIOC_STREAMOFF: { /*---------------------------------------------------------------------------*/ JOM(8, "calling wake_up on wq_video and wq_audio\n"); wake_up_interruptible(&(peasycap->wq_video)); +#if defined(EASYCAP_NEEDS_ALSA) + if (NULL != peasycap->psubstream) + snd_pcm_period_elapsed(peasycap->psubstream); +#else wake_up_interruptible(&(peasycap->wq_audio)); +#endif /*EASYCAP_NEEDS_ALSA*/ /*---------------------------------------------------------------------------*/ break; } @@ -2412,19 +2418,19 @@ case VIDIOC_G_PARM: { pv4l2_streamparm = kzalloc(sizeof(struct v4l2_streamparm), GFP_KERNEL); if (!pv4l2_streamparm) { SAM("ERROR: out of memory\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ENOMEM; } if (0 != copy_from_user(pv4l2_streamparm, (void __user *)arg, \ sizeof(struct v4l2_streamparm))) { kfree(pv4l2_streamparm); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } if (pv4l2_streamparm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { kfree(pv4l2_streamparm); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } pv4l2_streamparm->parm.capture.capability = 0; @@ -2450,7 +2456,7 @@ case VIDIOC_G_PARM: { if (0 != copy_to_user((void __user *)arg, pv4l2_streamparm, \ sizeof(struct v4l2_streamparm))) { kfree(pv4l2_streamparm); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } kfree(pv4l2_streamparm); @@ -2459,25 +2465,25 @@ case VIDIOC_G_PARM: { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_S_PARM: { JOM(8, "VIDIOC_S_PARM unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_AUDIO: { JOM(8, "VIDIOC_G_AUDIO unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_S_AUDIO: { JOM(8, "VIDIOC_S_AUDIO unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_S_TUNER: { JOM(8, "VIDIOC_S_TUNER unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -2485,45 +2491,46 @@ case VIDIOC_G_FBUF: case VIDIOC_S_FBUF: case VIDIOC_OVERLAY: { JOM(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_TUNER: { JOM(8, "VIDIOC_G_TUNER unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } case VIDIOC_G_FREQUENCY: case VIDIOC_S_FREQUENCY: { JOM(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ default: { JOM(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ENOIOCTLCMD; } } -mutex_unlock(&easycap_dongle[kd].mutex_video); -JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd); +mutex_unlock(&easycapdc60_dongle[kd].mutex_video); +JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd); return 0; } /*****************************************************************************/ +#if !defined(EASYCAP_NEEDS_ALSA) /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \ (defined(EASYCAP_NEEDS_UNLOCKED_IOCTL))) long -easysnd_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) { - return (long)easysnd_ioctl((struct inode *)NULL, file, cmd, arg); +easyoss_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) { + return (long)easyoss_ioctl((struct inode *)NULL, file, cmd, arg); } #endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*---------------------------------------------------------------------------*/ int -easysnd_ioctl(struct inode *inode, struct file *file, +easyoss_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct easycap *peasycap; @@ -2550,11 +2557,12 @@ if (NULL == p) { } kd = isdongle(peasycap); if (0 <= kd && DONGLE_MANY > kd) { - if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_audio)) { - SAY("ERROR: cannot lock easycap_dongle[%i].mutex_audio\n", kd); + if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_audio)) { + SAY("ERROR: cannot lock " + "easycapdc60_dongle[%i].mutex_audio\n", kd); return -ERESTARTSYS; } - JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd); + JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd); /*---------------------------------------------------------------------------*/ /* * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap, @@ -2566,24 +2574,24 @@ if (0 <= kd && DONGLE_MANY > kd) { return -ERESTARTSYS; if (NULL == file) { SAY("ERROR: file is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; } peasycap = file->private_data; if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { SAY("ERROR: bad peasycap\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } p = peasycap->pusb_device; if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; } } else { @@ -2614,7 +2622,7 @@ case SNDCTL_DSP_GETCAPS: { #endif /*UPSAMPLE*/ if (0 != copy_to_user((void __user *)arg, &caps, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } break; @@ -2636,7 +2644,7 @@ case SNDCTL_DSP_GETFMTS: { #endif /*UPSAMPLE*/ if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } break; @@ -2645,7 +2653,7 @@ case SNDCTL_DSP_SETFMT: { int incoming, outgoing; JOM(8, "SNDCTL_DSP_SETFMT\n"); if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } JOM(8, "........... %i=incoming\n", incoming); @@ -2668,10 +2676,10 @@ case SNDCTL_DSP_SETFMT: { JOM(8, " cf. %i=AFMT_U8\n", AFMT_U8); if (0 != copy_to_user((void __user *)arg, &outgoing, \ sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EINVAL ; } break; @@ -2680,7 +2688,7 @@ case SNDCTL_DSP_STEREO: { int incoming; JOM(8, "SNDCTL_DSP_STEREO\n"); if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } JOM(8, "........... %i=incoming\n", incoming); @@ -2698,7 +2706,7 @@ case SNDCTL_DSP_STEREO: { #endif /*UPSAMPLE*/ if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } break; @@ -2707,7 +2715,7 @@ case SNDCTL_DSP_SPEED: { int incoming; JOM(8, "SNDCTL_DSP_SPEED\n"); if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } JOM(8, "........... %i=incoming\n", incoming); @@ -2725,7 +2733,7 @@ case SNDCTL_DSP_SPEED: { #endif /*UPSAMPLE*/ if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } break; @@ -2734,14 +2742,14 @@ case SNDCTL_DSP_GETTRIGGER: { int incoming; JOM(8, "SNDCTL_DSP_GETTRIGGER\n"); if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } JOM(8, "........... %i=incoming\n", incoming); incoming = PCM_ENABLE_INPUT; if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } break; @@ -2750,7 +2758,7 @@ case SNDCTL_DSP_SETTRIGGER: { int incoming; JOM(8, "SNDCTL_DSP_SETTRIGGER\n"); if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } JOM(8, "........... %i=incoming\n", incoming); @@ -2767,13 +2775,13 @@ case SNDCTL_DSP_GETBLKSIZE: { int incoming; JOM(8, "SNDCTL_DSP_GETBLKSIZE\n"); if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } JOM(8, "........... %i=incoming\n", incoming); incoming = peasycap->audio_bytes_per_fragment; if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } break; @@ -2790,7 +2798,7 @@ case SNDCTL_DSP_GETISPACE: { if (0 != copy_to_user((void __user *)arg, &audio_buf_info, \ sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } break; @@ -2802,18 +2810,18 @@ case 0x00005404: case 0x00005405: case 0x00005406: { JOM(8, "SNDCTL_TMR_...: 0x%08X unsupported\n", cmd); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ENOIOCTLCMD; } default: { JOM(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ENOIOCTLCMD; } } -mutex_unlock(&easycap_dongle[kd].mutex_audio); +mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return 0; } +#endif /*EASYCAP_NEEDS_ALSA*/ /*****************************************************************************/ - diff --git a/drivers/staging/easycap/easycap_ioctl.h b/drivers/staging/easycap/easycap_ioctl.h index 210cd627235f..938de375efab 100644 --- a/drivers/staging/easycap/easycap_ioctl.h +++ b/drivers/staging/easycap/easycap_ioctl.h @@ -24,5 +24,14 @@ * */ /*****************************************************************************/ +#if !defined(EASYCAP_IOCTL_H) +#define EASYCAP_IOCTL_H + +extern int easycap_debug; +extern int easycap_gain; +extern struct easycap_dongle easycapdc60_dongle[]; +extern struct easycap_standard easycap_standard[]; extern struct easycap_format easycap_format[]; extern struct v4l2_queryctrl easycap_control[]; + +#endif /*EASYCAP_IOCTL_H*/ diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index 28c4d1e3c02f..b618d4be3e5c 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -39,7 +39,7 @@ /****************************************************************************/ #include "easycap.h" -#include "easycap_debug.h" +#include "easycap_low.h" /*--------------------------------------------------------------------------*/ const struct stk1160config { int reg; int set; } stk1160configPAL[256] = { @@ -1052,9 +1052,18 @@ rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \ (int)50000); JOT(8, "0x%02X=buffer\n", *((__u8 *) &buffer[0])); -if (rc != (int)length) - SAY("ERROR: usb_control_msg returned %i\n", rc); - +if (rc != (int)length) { + switch (rc) { + case -EPIPE: { + SAY("usb_control_msg returned -EPIPE\n"); + break; + } + default: { + SAY("ERROR: usb_control_msg returned %i\n", rc); + break; + } + } +} /*--------------------------------------------------------------------------*/ /* * REGISTER 500: SETTING VALUE TO 0x0094 RESETS AUDIO CONFIGURATION ??? diff --git a/drivers/staging/easycap/easycap_low.h b/drivers/staging/easycap/easycap_low.h new file mode 100644 index 000000000000..d2b69e9c6b30 --- /dev/null +++ b/drivers/staging/easycap/easycap_low.h @@ -0,0 +1,34 @@ +/***************************************************************************** +* * +* easycap_low.h * +* * +*****************************************************************************/ +/* + * + * Copyright (C) 2010 R.M. Thomas + * + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ +/*****************************************************************************/ +#if !defined(EASYCAP_LOW_H) +#define EASYCAP_LOW_H + +extern int easycap_debug; +extern int easycap_gain; +extern struct easycap_dongle easycapdc60_dongle[]; + +#endif /*EASYCAP_LOW_H*/ diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 22cf02b9e9d5..84128cf90007 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -29,30 +29,17 @@ /*****************************************************************************/ #include "easycap.h" -#include "easycap_standard.h" -#include "easycap_ioctl.h" +#include "easycap_main.h" int easycap_debug; -static int easycap_bars; +static int easycap_bars = 1; int easycap_gain = 16; module_param_named(debug, easycap_debug, int, S_IRUGO | S_IWUSR); module_param_named(bars, easycap_bars, int, S_IRUGO | S_IWUSR); module_param_named(gain, easycap_gain, int, S_IRUGO | S_IWUSR); -/*---------------------------------------------------------------------------*/ -/* - * dongle_this IS INDISPENSIBLY static BECAUSE FUNCTION easycap_usb_probe() - * IS CALLED SUCCESSIVELY FOR INTERFACES 0, 1, 2 AND THE POINTER peasycap - * ALLOCATED DURING THE PROBING OF INTERFACE 0 MUST BE REMEMBERED WHEN - * PROBING INTERFACES 1 AND 2. - * - * IOCTL LOCKING IS DONE AT MODULE LEVEL, NOT DEVICE LEVEL. -*/ -/*---------------------------------------------------------------------------*/ - -struct easycap_dongle easycap_dongle[DONGLE_MANY]; -static int dongle_this; -static int dongle_done; +struct easycap_dongle easycapdc60_dongle[DONGLE_MANY]; +static struct mutex mutex_dongle; /*---------------------------------------------------------------------------*/ /* @@ -120,28 +107,6 @@ const struct v4l2_file_operations v4l2_fops = { #endif /*EASYCAP_NEEDS_V4L2_FOPS*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*--------------------------------------------------------------------------*/ -/* - * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE - */ -/*--------------------------------------------------------------------------*/ -const struct file_operations easysnd_fops = { - .owner = THIS_MODULE, - .open = easysnd_open, - .release = easysnd_release, -#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL) - .unlocked_ioctl = easysnd_ioctl_noinode, -#else - .ioctl = easysnd_ioctl, -#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/ - .read = easysnd_read, - .llseek = no_llseek, -}; -struct usb_class_driver easysnd_class = { -.name = "usb/easysnd%d", -.fops = &easysnd_fops, -.minor_base = USB_SKEL_MINOR_BASE, -}; /****************************************************************************/ /*---------------------------------------------------------------------------*/ /* @@ -155,7 +120,7 @@ int k; if (NULL == peasycap) return -2; for (k = 0; k < DONGLE_MANY; k++) { - if (easycap_dongle[k].peasycap == peasycap) { + if (easycapdc60_dongle[k].peasycap == peasycap) { peasycap->isdongle = k; return k; } @@ -1055,9 +1020,10 @@ for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { m++; } } -JOM(4, "easysnd_delete(): isoc audio buffers freed: %i pages\n", \ +JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n", \ m * (0x01 << AUDIO_ISOC_ORDER)); /*---------------------------------------------------------------------------*/ +#if !defined(EASYCAP_NEEDS_ALSA) JOM(4, "freeing audio buffers.\n"); gone = 0; for (k = 0; k < peasycap->audio_buffer_page_many; k++) { @@ -1068,7 +1034,8 @@ for (k = 0; k < peasycap->audio_buffer_page_many; k++) { gone++; } } -JOM(4, "easysnd_delete(): audio buffers freed: %i pages\n", gone); +JOM(4, "easyoss_delete(): audio buffers freed: %i pages\n", gone); +#endif /*!EASYCAP_NEEDS_ALSA*/ /*---------------------------------------------------------------------------*/ JOM(4, "freeing easycap structure.\n"); allocation_video_urb = peasycap->allocation_video_urb; @@ -1081,12 +1048,20 @@ allocation_audio_struct = peasycap->allocation_audio_struct; registered_audio = peasycap->registered_audio; kfree(peasycap); + if (0 <= kd && DONGLE_MANY > kd) { - easycap_dongle[kd].peasycap = (struct easycap *)NULL; - JOT(4, " null-->easycap_dongle[%i].peasycap\n", kd); - allocation_video_struct -= sizeof(struct easycap); + if (mutex_lock_interruptible(&mutex_dongle)) { + SAY("ERROR: cannot down mutex_dongle\n"); + } else { + JOM(4, "locked mutex_dongle\n"); + easycapdc60_dongle[kd].peasycap = (struct easycap *)NULL; + mutex_unlock(&mutex_dongle); + JOM(4, "unlocked mutex_dongle\n"); + JOT(4, " null-->easycapdc60_dongle[%i].peasycap\n", kd); + allocation_video_struct -= sizeof(struct easycap); + } } else { - SAY("ERROR: cannot purge easycap_dongle[].peasycap"); + SAY("ERROR: cannot purge easycapdc60_dongle[].peasycap"); } /*---------------------------------------------------------------------------*/ SAY("%8i= video urbs after all deletions\n", allocation_video_urb); @@ -1131,11 +1106,12 @@ if (NULL == peasycap->pusb_device) { /*---------------------------------------------------------------------------*/ kd = isdongle(peasycap); if (0 <= kd && DONGLE_MANY > kd) { - if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_video)) { - SAY("ERROR: cannot down easycap_dongle[%i].mutex_video\n", kd); + if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { + SAY("ERROR: cannot down " + "easycapdc60_dongle[%i].mutex_video\n", kd); return -ERESTARTSYS; } - JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd); + JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd); /*-------------------------------------------------------------------*/ /* * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER @@ -1147,24 +1123,24 @@ if (0 <= kd && DONGLE_MANY > kd) { return -ERESTARTSYS; if (NULL == file) { SAY("ERROR: file is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; } peasycap = file->private_data; if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { SAY("ERROR: bad peasycap: 0x%08lX\n", \ (unsigned long int) peasycap); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; } if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; } } else @@ -1179,7 +1155,7 @@ if (0 <= kd && DONGLE_MANY > kd) { /*---------------------------------------------------------------------------*/ rc = easycap_dqbuf(peasycap, 0); peasycap->polled = 1; -mutex_unlock(&easycap_dongle[kd].mutex_video); +mutex_unlock(&easycapdc60_dongle[kd].mutex_video); if (0 == rc) return POLLIN | POLLRDNORM; else @@ -3391,20 +3367,13 @@ return; /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* - * - * FIXME - * - * - * THIS FUNCTION ASSUMES THAT, ON EACH AND EVERY OCCASION THAT THE EasyCAP - * IS PHYSICALLY PLUGGED IN, INTERFACE 0 IS PROBED FIRST. - * IF THIS IS NOT TRUE, THERE IS THE POSSIBILITY OF AN Oops. - * - * THIS HAS NEVER BEEN A PROBLEM IN PRACTICE, BUT SOMETHING SEEMS WRONG HERE. + * WHEN THE EasyCAP IS PHYSICALLY PLUGGED IN, THIS FUNCTION IS CALLED THREE + * TIMES, ONCE FOR EACH OF THE THREE INTERFACES. BEWARE. */ /*---------------------------------------------------------------------------*/ int easycap_usb_probe(struct usb_interface *pusb_interface, \ - const struct usb_device_id *id) + const struct usb_device_id *pusb_device_id) { struct usb_device *pusb_device, *pusb_device1; struct usb_host_interface *pusb_host_interface; @@ -3413,6 +3382,7 @@ struct usb_interface_descriptor *pusb_interface_descriptor; struct usb_interface_assoc_descriptor *pusb_interface_assoc_descriptor; struct urb *purb; struct easycap *peasycap; +int ndong; struct data_urb *pdata_urb; size_t wMaxPacketSize; int ISOCwMaxPacketSize; @@ -3434,24 +3404,19 @@ int maxpacketsize; __u16 mask; __s32 value; struct easycap_format *peasycap_format; - -JOT(4, "\n"); - -if (!dongle_done) { - dongle_done = 1; - for (k = 0; k < DONGLE_MANY; k++) { - easycap_dongle[k].peasycap = (struct easycap *)NULL; - mutex_init(&easycap_dongle[k].mutex_video); - mutex_init(&easycap_dongle[k].mutex_audio); - } -} - -peasycap = (struct easycap *)NULL; +/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#if defined(EASYCAP_IS_VIDEODEV_CLIENT) +#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +struct v4l2_device *pv4l2_device; +#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ +#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ if ((struct usb_interface *)NULL == pusb_interface) { SAY("ERROR: pusb_interface is NULL\n"); return -EFAULT; } +peasycap = (struct easycap *)NULL; /*---------------------------------------------------------------------------*/ /* * GET POINTER TO STRUCTURE usb_device @@ -3472,9 +3437,7 @@ if ((unsigned long int)pusb_device1 != (unsigned long int)pusb_device) { JOT(4, "ERROR: pusb_device1 != pusb_device\n"); return -EFAULT; } - JOT(4, "bNumConfigurations=%i\n", pusb_device->descriptor.bNumConfigurations); - /*---------------------------------------------------------------------------*/ pusb_host_interface = pusb_interface->cur_altsetting; if (NULL == pusb_host_interface) { @@ -3553,9 +3516,6 @@ JOT(4, "intf[%i]: pusb_interface_assoc_descriptor is NULL\n", \ * * THE POINTER peasycap TO THE struct easycap IS REMEMBERED WHEN * INTERFACES 1 AND 2 ARE PROBED. - * - * IF TWO EasyCAPs ARE PLUGGED IN NEARLY SIMULTANEOUSLY THERE WILL - * BE TROUBLE. BEWARE. */ /*---------------------------------------------------------------------------*/ if (0 == bInterfaceNumber) { @@ -3580,6 +3540,7 @@ if (0 == bInterfaceNumber) { * PERFORM URGENT INTIALIZATIONS ... */ /*---------------------------------------------------------------------------*/ + peasycap->minor = -1; strcpy(&peasycap->telltale[0], TELLTALE); kref_init(&peasycap->kref); JOM(8, "intf[%i]: after kref_init(..._video) " \ @@ -3588,29 +3549,43 @@ if (0 == bInterfaceNumber) { init_waitqueue_head(&peasycap->wq_video); init_waitqueue_head(&peasycap->wq_audio); + init_waitqueue_head(&peasycap->wq_trigger); - for (dongle_this = 0; dongle_this < DONGLE_MANY; dongle_this++) { - if (NULL == easycap_dongle[dongle_this].peasycap) { - if (0 == mutex_is_locked(&easycap_dongle\ - [dongle_this].mutex_video)) { - if (0 == mutex_is_locked(&easycap_dongle\ - [dongle_this].mutex_audio)) { - easycap_dongle\ - [dongle_this].peasycap = \ - peasycap; - JOM(8, "intf[%i]: peasycap-->easycap" \ + if (mutex_lock_interruptible(&mutex_dongle)) { + SAY("ERROR: cannot down mutex_dongle\n"); + return -ERESTARTSYS; + } else { +/*---------------------------------------------------------------------------*/ + /* + * FOR INTERFACES 1 AND 2 THE POINTER peasycap WILL NEED TO + * TO BE THE SAME AS THAT ALLOCATED NOW FOR INTERFACE 0. + * + * NORMALLY ndong WILL NOT HAVE CHANGED SINCE INTERFACE 0 WAS + * PROBED, BUT THIS MAY NOT BE THE CASE IF, FOR EXAMPLE, TWO + * EASYCAPs ARE PLUGGED IN SIMULTANEOUSLY. + */ +/*---------------------------------------------------------------------------*/ + for (ndong = 0; ndong < DONGLE_MANY; ndong++) { + if ((NULL == easycapdc60_dongle[ndong].peasycap) && \ + (!mutex_is_locked(&easycapdc60_dongle\ + [ndong].mutex_video)) && \ + (!mutex_is_locked(&easycapdc60_dongle\ + [ndong].mutex_audio))) { + easycapdc60_dongle[ndong].peasycap = peasycap; + peasycap->isdongle = ndong; + JOM(8, "intf[%i]: peasycap-->easycap" \ "_dongle[%i].peasycap\n", \ - bInterfaceNumber, dongle_this); - break; - } + bInterfaceNumber, ndong); + break; } } + if (DONGLE_MANY <= ndong) { + SAM("ERROR: too many dongles\n"); + mutex_unlock(&mutex_dongle); + return -ENOMEM; + } + mutex_unlock(&mutex_dongle); } - if (DONGLE_MANY <= dongle_this) { - SAM("ERROR: too many dongles\n"); - return -ENOMEM; - } - peasycap->allocation_video_struct = sizeof(struct easycap); peasycap->allocation_video_page = 0; peasycap->allocation_video_urb = 0; @@ -3778,26 +3753,56 @@ if (0 == bInterfaceNumber) { JOM(4, "finished initialization\n"); } else { /*---------------------------------------------------------------------------*/ - /* - * FOR INTERFACES 1 AND 2 THE POINTER peasycap IS OBTAINED BY ASSUMING - * THAT dongle_this HAS NOT CHANGED SINCE INTERFACE 0 WAS PROBED. IF - * THIS IS NOT THE CASE, FOR EXAMPLE WHEN TWO EASYCAPs ARE PLUGGED IN - * SIMULTANEOUSLY, THERE WILL BE SERIOUS TROUBLE. - */ +/* + * FIXME + * + * IDENTIFY THE APPROPRIATE POINTER peasycap FOR INTERFACES 1 AND 2. + * THE ADDRESS OF peasycap->pusb_device IS RELUCTANTLY USED FOR THIS PURPOSE. + */ /*---------------------------------------------------------------------------*/ - if ((0 > dongle_this) || (DONGLE_MANY <= dongle_this)) { - SAY("ERROR: bad dongle count\n"); - return -EFAULT; + for (ndong = 0; ndong < DONGLE_MANY; ndong++) { + if (pusb_device == easycapdc60_dongle[ndong].peasycap->\ + pusb_device) { + peasycap = easycapdc60_dongle[ndong].peasycap; + JOT(8, "intf[%i]: easycapdc60_dongle[%i].peasycap-->" \ + "peasycap\n", bInterfaceNumber, ndong); + break; + } } - peasycap = easycap_dongle[dongle_this].peasycap; - JOT(8, "intf[%i]: easycap_dongle[%i].peasycap-->peasycap\n", \ - bInterfaceNumber, dongle_this); - - if ((struct easycap *)NULL == peasycap) { + if (DONGLE_MANY <= ndong) { + SAY("ERROR: peasycap is unknown when probing interface %i\n", \ + bInterfaceNumber); + return -ENODEV; + } + if (NULL == peasycap) { SAY("ERROR: peasycap is NULL when probing interface %i\n", \ bInterfaceNumber); - return -EFAULT; + return -ENODEV; } +#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) +# +/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#else +#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +/*---------------------------------------------------------------------------*/ +/* + * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS + * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(), + * REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE. + * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED. +*/ +/*---------------------------------------------------------------------------*/ + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + pv4l2_device = usb_get_intfdata(pusb_interface); + if ((struct v4l2_device *)NULL == pv4l2_device) { + SAY("ERROR: pv4l2_device is NULL\n"); + return -ENODEV; + } + peasycap = (struct easycap *) \ + container_of(pv4l2_device, struct easycap, v4l2_device); + } +#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ +#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ } /*---------------------------------------------------------------------------*/ if ((USB_CLASS_VIDEO == bInterfaceClass) || \ @@ -4368,6 +4373,7 @@ case 0: { } else { (peasycap->registered_video)++; SAM("easycap attached to minor #%d\n", pusb_interface->minor); + peasycap->minor = pusb_interface->minor; break; } /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ @@ -4383,7 +4389,7 @@ case 0: { } /*---------------------------------------------------------------------------*/ /* - * FIXME + * FIXME * * * THIS IS BELIEVED TO BE HARMLESS, BUT MAY WELL BE UNNECESSARY OR WRONG: @@ -4414,9 +4420,11 @@ case 0: { (peasycap->registered_video)++; SAM("registered with videodev: %i=minor\n", \ peasycap->video_device.minor); + peasycap->minor = peasycap->video_device.minor; } #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + break; } /*--------------------------------------------------------------------------*/ @@ -4426,8 +4434,11 @@ case 0: { */ /*--------------------------------------------------------------------------*/ case 1: { +#if defined(EASYCAP_SILENT) + return -ENOENT; +#endif /*EASYCAP_SILENT*/ if (!peasycap) { - SAM("ERROR: peasycap is NULL\n"); + SAM("MISTAKE: peasycap is NULL\n"); return -EFAULT; } /*--------------------------------------------------------------------------*/ @@ -4442,6 +4453,9 @@ case 1: { } /*--------------------------------------------------------------------------*/ case 2: { +#if defined(EASYCAP_SILENT) + return -ENOENT; +#endif /*EASYCAP_SILENT*/ if (!peasycap) { SAM("MISTAKE: peasycap is NULL\n"); return -EFAULT; @@ -4467,14 +4481,14 @@ case 2: { } if (9 == peasycap->audio_isoc_maxframesize) { peasycap->ilk |= 0x02; - SAM("hardware is FOUR-CVBS\n"); + SAM("audio hardware is microphone\n"); peasycap->microphone = true; - peasycap->audio_pages_per_fragment = 4; + peasycap->audio_pages_per_fragment = PAGES_PER_AUDIO_FRAGMENT; } else if (256 == peasycap->audio_isoc_maxframesize) { peasycap->ilk &= ~0x02; - SAM("hardware is CVBS+S-VIDEO\n"); + SAM("audio hardware is AC'97\n"); peasycap->microphone = false; - peasycap->audio_pages_per_fragment = 4; + peasycap->audio_pages_per_fragment = PAGES_PER_AUDIO_FRAGMENT; } else { SAM("hardware is unidentified:\n"); SAM("%i=audio_isoc_maxframesize\n", \ @@ -4496,7 +4510,7 @@ case 2: { JOM(4, "%6i=audio_buffer_page_many\n", \ peasycap->audio_buffer_page_many); - peasycap->audio_isoc_framesperdesc = 128; + peasycap->audio_isoc_framesperdesc = AUDIO_ISOC_FRAMESPERDESC; JOM(4, "%i=audio_isoc_framesperdesc\n", \ peasycap->audio_isoc_framesperdesc); @@ -4548,6 +4562,7 @@ case 2: { INIT_LIST_HEAD(&(peasycap->urb_audio_head)); peasycap->purb_audio_head = &(peasycap->urb_audio_head); +#if !defined(EASYCAP_NEEDS_ALSA) JOM(4, "allocating an audio buffer\n"); JOM(4, ".... scattered over %i pages\n", \ peasycap->audio_buffer_page_many); @@ -4572,6 +4587,7 @@ case 2: { peasycap->audio_fill = 0; peasycap->audio_read = 0; JOM(4, "allocation of audio buffer done: %i pages\n", k); +#endif /*!EASYCAP_NEEDS_ALSA*/ /*---------------------------------------------------------------------------*/ JOM(4, "allocating %i isoc audio buffers of size %i\n", \ AUDIO_ISOC_BUFFER_MANY, peasycap->audio_isoc_buffer_size); @@ -4646,7 +4662,11 @@ case 2: { "peasycap->audio_isoc_buffer[.].pgo;\n"); JOM(4, " purb->transfer_buffer_length = %i;\n", \ peasycap->audio_isoc_buffer_size); - JOM(4, " purb->complete = easysnd_complete;\n"); +#if defined(EASYCAP_NEEDS_ALSA) + JOM(4, " purb->complete = easycap_alsa_complete;\n"); +#else + JOM(4, " purb->complete = easyoss_complete;\n"); +#endif /*EASYCAP_NEEDS_ALSA*/ JOM(4, " purb->context = peasycap;\n"); JOM(4, " purb->start_frame = 0;\n"); JOM(4, " purb->number_of_packets = %i;\n", \ @@ -4669,7 +4689,11 @@ case 2: { purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo; purb->transfer_buffer_length = \ peasycap->audio_isoc_buffer_size; - purb->complete = easysnd_complete; +#if defined(EASYCAP_NEEDS_ALSA) + purb->complete = easycap_alsa_complete; +#else + purb->complete = easyoss_complete; +#endif /*EASYCAP_NEEDS_ALSA*/ purb->context = peasycap; purb->start_frame = 0; purb->number_of_packets = peasycap->audio_isoc_framesperdesc; @@ -4692,9 +4716,24 @@ case 2: { * THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY. */ /*---------------------------------------------------------------------------*/ - rc = usb_register_dev(pusb_interface, &easysnd_class); +#if defined(EASYCAP_NEEDS_ALSA) + JOM(4, "initializing ALSA card\n"); + + rc = easycap_alsa_probe(peasycap); + if (0 != rc) { + err("easycap_alsa_probe() returned %i\n", rc); + return -ENODEV; + } else { + JOM(8, "kref_get() with %i=peasycap->kref.refcount.counter\n",\ + (int)peasycap->kref.refcount.counter); + kref_get(&peasycap->kref); + (peasycap->registered_audio)++; + } + +#else /*EASYCAP_NEEDS_ALSA*/ + rc = usb_register_dev(pusb_interface, &easyoss_class); if (0 != rc) { - err("Not able to get a minor for this device."); + SAY("ERROR: usb_register_dev() failed\n"); usb_set_intfdata(pusb_interface, NULL); return -ENODEV; } else { @@ -4708,7 +4747,9 @@ case 2: { * LET THE USER KNOW WHAT NODE THE AUDIO DEVICE IS ATTACHED TO. */ /*---------------------------------------------------------------------------*/ - SAM("easysnd attached to minor #%d\n", pusb_interface->minor); + SAM("easyoss attached to minor #%d\n", pusb_interface->minor); +#endif /*EASYCAP_NEEDS_ALSA*/ + break; } /*---------------------------------------------------------------------------*/ @@ -4721,7 +4762,7 @@ default: { return -EINVAL; } } -JOM(4, "ends successfully for interface %i\n", \ +SAM("ends successfully for interface %i\n", \ pusb_interface_descriptor->bInterfaceNumber); return 0; } @@ -4730,6 +4771,8 @@ return 0; /* * WHEN THIS FUNCTION IS CALLED THE EasyCAP HAS ALREADY BEEN PHYSICALLY * UNPLUGGED. HENCE peasycap->pusb_device IS NO LONGER VALID. + * + * THIS FUNCTION AFFECTS BOTH OSS AND ALSA. BEWARE. */ /*---------------------------------------------------------------------------*/ void @@ -4881,14 +4924,15 @@ switch (bInterfaceNumber) { case 0: { if (0 <= kd && DONGLE_MANY > kd) { wake_up_interruptible(&peasycap->wq_video); - JOM(4, "about to lock easycap_dongle[%i].mutex_video\n", kd); - if (mutex_lock_interruptible(&easycap_dongle[kd].\ + JOM(4, "about to lock easycapdc60_dongle[%i].mutex_video\n", \ + kd); + if (mutex_lock_interruptible(&easycapdc60_dongle[kd].\ mutex_video)) { - SAY("ERROR: cannot lock easycap_dongle[%i]." \ + SAY("ERROR: cannot lock easycapdc60_dongle[%i]." \ "mutex_video\n", kd); return; } - JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd); + JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd); } else SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); /*---------------------------------------------------------------------------*/ @@ -4907,7 +4951,7 @@ case 0: { if (!peasycap->v4l2_device.name[0]) { SAM("ERROR: peasycap->v4l2_device.name is empty\n"); if (0 <= kd && DONGLE_MANY > kd) - mutex_unlock(&easycap_dongle[kd].mutex_video); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return; } v4l2_device_disconnect(&peasycap->v4l2_device); @@ -4924,34 +4968,47 @@ case 0: { /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ if (0 <= kd && DONGLE_MANY > kd) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd); } break; } case 2: { if (0 <= kd && DONGLE_MANY > kd) { wake_up_interruptible(&peasycap->wq_audio); - JOM(4, "about to lock easycap_dongle[%i].mutex_audio\n", kd); - if (mutex_lock_interruptible(&easycap_dongle[kd].\ + JOM(4, "about to lock easycapdc60_dongle[%i].mutex_audio\n", \ + kd); + if (mutex_lock_interruptible(&easycapdc60_dongle[kd].\ mutex_audio)) { - SAY("ERROR: cannot lock easycap_dongle[%i]." \ + SAY("ERROR: cannot lock easycapdc60_dongle[%i]." \ "mutex_audio\n", kd); return; } - JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd); + JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd); } else SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); +#if defined(EASYCAP_NEEDS_ALSA) - usb_deregister_dev(pusb_interface, &easysnd_class); - (peasycap->registered_audio)--; + + if (0 != snd_card_free(peasycap->psnd_card)) { + SAY("ERROR: snd_card_free() failed\n"); + } else { + peasycap->psnd_card = (struct snd_card *)NULL; + (peasycap->registered_audio)--; + } + + +#else /*EASYCAP_NEEDS_ALSA*/ + usb_deregister_dev(pusb_interface, &easyoss_class); + (peasycap->registered_audio)--; JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber); - SAM("easysnd detached from minor #%d\n", minor); + SAM("easyoss detached from minor #%d\n", minor); +#endif /*EASYCAP_NEEDS_ALSA*/ if (0 <= kd && DONGLE_MANY > kd) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); - JOM(4, "unlocked easycap_dongle[%i].mutex_audio\n", kd); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + JOM(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd); } break; } @@ -4961,6 +5018,7 @@ default: /*---------------------------------------------------------------------------*/ /* * CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap + * (ALSO WHEN ALSA HAS BEEN IN USE) */ /*---------------------------------------------------------------------------*/ if (!peasycap->kref.refcount.counter) { @@ -4970,32 +5028,34 @@ if (!peasycap->kref.refcount.counter) { return; } if (0 <= kd && DONGLE_MANY > kd) { - JOM(4, "about to lock easycap_dongle[%i].mutex_video\n", kd); - if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_video)) { - SAY("ERROR: cannot down easycap_dongle[%i].mutex_video\n", kd); + JOM(4, "about to lock easycapdc60_dongle[%i].mutex_video\n", kd); + if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { + SAY("ERROR: cannot down " + "easycapdc60_dongle[%i].mutex_video\n", kd); SAM("ending unsuccessfully: may cause memory leak\n"); return; } - JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd); - JOM(4, "about to lock easycap_dongle[%i].mutex_audio\n", kd); - if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_audio)) { - SAY("ERROR: cannot down easycap_dongle[%i].mutex_audio\n", kd); - mutex_unlock(&(easycap_dongle[kd].mutex_video)); - JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd); + JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd); + JOM(4, "about to lock easycapdc60_dongle[%i].mutex_audio\n", kd); + if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_audio)) { + SAY("ERROR: cannot down " + "easycapdc60_dongle[%i].mutex_audio\n", kd); + mutex_unlock(&(easycapdc60_dongle[kd].mutex_video)); + JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd); SAM("ending unsuccessfully: may cause memory leak\n"); return; } - JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd); + JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd); } JOM(4, "intf[%i]: %i=peasycap->kref.refcount.counter\n", \ bInterfaceNumber, (int)peasycap->kref.refcount.counter); kref_put(&peasycap->kref, easycap_delete); JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber); if (0 <= kd && DONGLE_MANY > kd) { - mutex_unlock(&(easycap_dongle[kd].mutex_audio)); - JOT(4, "unlocked easycap_dongle[%i].mutex_audio\n", kd); - mutex_unlock(&easycap_dongle[kd].mutex_video); - JOT(4, "unlocked easycap_dongle[%i].mutex_video\n", kd); + mutex_unlock(&(easycapdc60_dongle[kd].mutex_audio)); + JOT(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + JOT(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd); } /*---------------------------------------------------------------------------*/ JOM(4, "ends\n"); @@ -5005,25 +5065,31 @@ return; int __init easycap_module_init(void) { -int result; +int k, rc; SAY("========easycap=======\n"); JOT(4, "begins. %i=debug %i=bars %i=gain\n", easycap_debug, easycap_bars, \ easycap_gain); SAY("version: " EASYCAP_DRIVER_VERSION "\n"); + +mutex_init(&mutex_dongle); +for (k = 0; k < DONGLE_MANY; k++) { + easycapdc60_dongle[k].peasycap = (struct easycap *)NULL; + mutex_init(&easycapdc60_dongle[k].mutex_video); + mutex_init(&easycapdc60_dongle[k].mutex_audio); +} /*---------------------------------------------------------------------------*/ /* * REGISTER THIS DRIVER WITH THE USB SUBSYTEM. */ /*---------------------------------------------------------------------------*/ JOT(4, "registering driver easycap\n"); - -result = usb_register(&easycap_usb_driver); -if (0 != result) - SAY("ERROR: usb_register returned %i\n", result); +rc = usb_register(&easycap_usb_driver); +if (0 != rc) + SAY("ERROR: usb_register returned %i\n", rc); JOT(4, "ends\n"); -return result; +return rc; } /*****************************************************************************/ void __exit diff --git a/drivers/staging/easycap/easycap_main.h b/drivers/staging/easycap/easycap_main.h new file mode 100644 index 000000000000..11fcbbca0f0c --- /dev/null +++ b/drivers/staging/easycap/easycap_main.h @@ -0,0 +1,43 @@ +/***************************************************************************** +* * +* easycap_main.h * +* * +*****************************************************************************/ +/* + * + * Copyright (C) 2010 R.M. Thomas + * + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ +/*****************************************************************************/ +#if !defined(EASYCAP_MAIN_H) +#define EASYCAP_MAIN_H + +extern struct easycap_standard easycap_standard[]; +extern struct easycap_format easycap_format[]; +extern struct v4l2_queryctrl easycap_control[]; +extern struct usb_driver easycap_usb_driver; +#if defined(EASYCAP_NEEDS_ALSA) +extern struct snd_pcm_ops easycap_alsa_ops; +extern struct snd_pcm_hardware easycap_pcm_hardware; +extern struct snd_card *psnd_card; +#else +extern struct usb_class_driver easyoss_class; +extern const struct file_operations easyoss_fops; +#endif /*EASYCAP_NEEDS_ALSA*/ + +#endif /*EASYCAP_MAIN_H*/ diff --git a/drivers/staging/easycap/easycap_settings.c b/drivers/staging/easycap/easycap_settings.c index df3f17d361b1..0a23e2749514 100644 --- a/drivers/staging/easycap/easycap_settings.c +++ b/drivers/staging/easycap/easycap_settings.c @@ -26,7 +26,7 @@ /*****************************************************************************/ #include "easycap.h" -#include "easycap_debug.h" +#include "easycap_settings.h" /*---------------------------------------------------------------------------*/ /* diff --git a/drivers/staging/easycap/easycap_settings.h b/drivers/staging/easycap/easycap_settings.h new file mode 100644 index 000000000000..5fe6f074425b --- /dev/null +++ b/drivers/staging/easycap/easycap_settings.h @@ -0,0 +1,34 @@ +/***************************************************************************** +* * +* easycap_settings.h * +* * +*****************************************************************************/ +/* + * + * Copyright (C) 2010 R.M. Thomas + * + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ +/*****************************************************************************/ +#if !defined(EASYCAP_SETTINGS_H) +#define EASYCAP_SETTINGS_H + +extern int easycap_debug; +extern int easycap_gain; +extern struct easycap_dongle easycapdc60_dongle[]; + +#endif /*EASYCAP_SETTINGS_H*/ diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index 24d8bb4e449e..0507ea19004a 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -29,9 +29,890 @@ /*****************************************************************************/ #include "easycap.h" -#include "easycap_debug.h" #include "easycap_sound.h" +#if defined(EASYCAP_NEEDS_ALSA) +/*--------------------------------------------------------------------------*/ +/* + * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE + */ +/*--------------------------------------------------------------------------*/ +static const struct snd_pcm_hardware alsa_hardware = { + .info = SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000, + .rate_min = 32000, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = PAGE_SIZE * PAGES_PER_AUDIO_FRAGMENT * \ + AUDIO_FRAGMENT_MANY, + .period_bytes_min = PAGE_SIZE * PAGES_PER_AUDIO_FRAGMENT, + .period_bytes_max = PAGE_SIZE * PAGES_PER_AUDIO_FRAGMENT * 2, + .periods_min = AUDIO_FRAGMENT_MANY, + .periods_max = AUDIO_FRAGMENT_MANY * 2, +}; + +static struct snd_pcm_ops easycap_alsa_pcm_ops = { + .open = easycap_alsa_open, + .close = easycap_alsa_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = easycap_alsa_hw_params, + .hw_free = easycap_alsa_hw_free, + .prepare = easycap_alsa_prepare, + .ack = easycap_alsa_ack, + .trigger = easycap_alsa_trigger, + .pointer = easycap_alsa_pointer, + .page = easycap_alsa_page, +}; + +/*****************************************************************************/ +/*---------------------------------------------------------------------------*/ +/* + * THE FUNCTION snd_card_create() HAS THIS_MODULE AS AN ARGUMENT. THIS + * MEANS MODULE easycap. BEWARE. +*/ +/*---------------------------------------------------------------------------*/ +int +easycap_alsa_probe(struct easycap *peasycap) +{ +int rc; +struct snd_card *psnd_card; +struct snd_pcm *psnd_pcm; + +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -ENODEV; +} +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; +} +if (0 > peasycap->minor) { + SAY("ERROR: no minor\n"); + return -ENODEV; +} + +peasycap->alsa_hardware = alsa_hardware; +if (true == peasycap->microphone) { + peasycap->alsa_hardware.rates = SNDRV_PCM_RATE_32000; + peasycap->alsa_hardware.rate_min = 32000; + peasycap->alsa_hardware.rate_max = 32000; +} else { + peasycap->alsa_hardware.rates = SNDRV_PCM_RATE_48000; + peasycap->alsa_hardware.rate_min = 48000; + peasycap->alsa_hardware.rate_max = 48000; +} + +#if defined(EASYCAP_NEEDS_CARD_CREATE) + if (0 != snd_card_create(SNDRV_DEFAULT_IDX1, "easycap_alsa", \ + THIS_MODULE, 0, \ + &psnd_card)) { + SAY("ERROR: Cannot do ALSA snd_card_create()\n"); + return -EFAULT; + } +#else + psnd_card = snd_card_new(SNDRV_DEFAULT_IDX1, "easycap_alsa", \ + THIS_MODULE, 0); + if (NULL == psnd_card) { + SAY("ERROR: Cannot do ALSA snd_card_new()\n"); + return -EFAULT; + } +#endif /*EASYCAP_NEEDS_CARD_CREATE*/ + + sprintf(&psnd_card->id[0], "EasyALSA%i", peasycap->minor); + strcpy(&psnd_card->driver[0], EASYCAP_DRIVER_DESCRIPTION); + strcpy(&psnd_card->shortname[0], "easycap_alsa"); + sprintf(&psnd_card->longname[0], "%s", &psnd_card->shortname[0]); + + psnd_card->dev = &peasycap->pusb_device->dev; + psnd_card->private_data = peasycap; + peasycap->psnd_card = psnd_card; + + rc = snd_pcm_new(psnd_card, "easycap_pcm", 0, 0, 1, &psnd_pcm); + if (0 != rc) { + SAM("ERROR: Cannot do ALSA snd_pcm_new()\n"); + snd_card_free(psnd_card); + return -EFAULT; + } + + snd_pcm_set_ops(psnd_pcm, SNDRV_PCM_STREAM_CAPTURE, \ + &easycap_alsa_pcm_ops); + psnd_pcm->info_flags = 0; + strcpy(&psnd_pcm->name[0], &psnd_card->id[0]); + psnd_pcm->private_data = peasycap; + peasycap->psnd_pcm = psnd_pcm; + peasycap->psubstream = (struct snd_pcm_substream *)NULL; + + rc = snd_card_register(psnd_card); + if (0 != rc) { + SAM("ERROR: Cannot do ALSA snd_card_register()\n"); + snd_card_free(psnd_card); + return -EFAULT; + } else { + ; + SAM("registered %s\n", &psnd_card->id[0]); + } +return 0; +} +/*****************************************************************************/ +/*---------------------------------------------------------------------------*/ +/* + * ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE DAM BUFFER + * PROVIDED peasycap->audio_idle IS ZERO. REGARDLESS OF THIS BEING TRUE, + * IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO. + */ +/*---------------------------------------------------------------------------*/ +void +easycap_alsa_complete(struct urb *purb) +{ +struct easycap *peasycap; +struct snd_pcm_substream *pss; +struct snd_pcm_runtime *prt; +int dma_bytes, fragment_bytes; +int isfragment; +__u8 *p1, *p2; +__s16 s16; +int i, j, more, much, rc; +#if defined(UPSAMPLE) +int k; +__s16 oldaudio, newaudio, delta; +#endif /*UPSAMPLE*/ + +JOT(16, "\n"); + +if (NULL == purb) { + SAY("ERROR: purb is NULL\n"); + return; +} +peasycap = purb->context; +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return; +} +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return; +} +much = 0; +if (peasycap->audio_idle) { + JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n", \ + peasycap->audio_idle, peasycap->audio_isoc_streaming); + if (peasycap->audio_isoc_streaming) + goto resubmit; +} +/*---------------------------------------------------------------------------*/ +pss = peasycap->psubstream; +if (NULL == pss) + goto resubmit; +prt = pss->runtime; +if (NULL == prt) + goto resubmit; +dma_bytes = (int)prt->dma_bytes; +if (0 == dma_bytes) + goto resubmit; +fragment_bytes = 4 * ((int)prt->period_size); +if (0 == fragment_bytes) + goto resubmit; +/* -------------------------------------------------------------------------*/ +if (purb->status) { + if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) { + JOM(16, "urb status -ESHUTDOWN or -ENOENT\n"); + return; + } + SAM("ERROR: non-zero urb status:\n"); + switch (purb->status) { + case -EINPROGRESS: { + SAM("-EINPROGRESS\n"); + break; + } + case -ENOSR: { + SAM("-ENOSR\n"); + break; + } + case -EPIPE: { + SAM("-EPIPE\n"); + break; + } + case -EOVERFLOW: { + SAM("-EOVERFLOW\n"); + break; + } + case -EPROTO: { + SAM("-EPROTO\n"); + break; + } + case -EILSEQ: { + SAM("-EILSEQ\n"); + break; + } + case -ETIMEDOUT: { + SAM("-ETIMEDOUT\n"); + break; + } + case -EMSGSIZE: { + SAM("-EMSGSIZE\n"); + break; + } + case -EOPNOTSUPP: { + SAM("-EOPNOTSUPP\n"); + break; + } + case -EPFNOSUPPORT: { + SAM("-EPFNOSUPPORT\n"); + break; + } + case -EAFNOSUPPORT: { + SAM("-EAFNOSUPPORT\n"); + break; + } + case -EADDRINUSE: { + SAM("-EADDRINUSE\n"); + break; + } + case -EADDRNOTAVAIL: { + SAM("-EADDRNOTAVAIL\n"); + break; + } + case -ENOBUFS: { + SAM("-ENOBUFS\n"); + break; + } + case -EISCONN: { + SAM("-EISCONN\n"); + break; + } + case -ENOTCONN: { + SAM("-ENOTCONN\n"); + break; + } + case -ESHUTDOWN: { + SAM("-ESHUTDOWN\n"); + break; + } + case -ENOENT: { + SAM("-ENOENT\n"); + break; + } + case -ECONNRESET: { + SAM("-ECONNRESET\n"); + break; + } + case -ENOSPC: { + SAM("ENOSPC\n"); + break; + } + default: { + SAM("unknown error: %i\n", purb->status); + break; + } + } + goto resubmit; +} +/*---------------------------------------------------------------------------*/ +/* + * PROCEED HERE WHEN NO ERROR + */ +/*---------------------------------------------------------------------------*/ + +#if defined(UPSAMPLE) +oldaudio = peasycap->oldaudio; +#endif /*UPSAMPLE*/ + +for (i = 0; i < purb->number_of_packets; i++) { + switch (purb->iso_frame_desc[i].status) { + case 0: { + break; + } + case -ENOENT: { + SAM("-ENOENT\n"); + break; + } + case -EINPROGRESS: { + SAM("-EINPROGRESS\n"); + break; + } + case -EPROTO: { + SAM("-EPROTO\n"); + break; + } + case -EILSEQ: { + SAM("-EILSEQ\n"); + break; + } + case -ETIME: { + SAM("-ETIME\n"); + break; + } + case -ETIMEDOUT: { + SAM("-ETIMEDOUT\n"); + break; + } + case -EPIPE: { + SAM("-EPIPE\n"); + break; + } + case -ECOMM: { + SAM("-ECOMM\n"); + break; + } + case -ENOSR: { + SAM("-ENOSR\n"); + break; + } + case -EOVERFLOW: { + SAM("-EOVERFLOW\n"); + break; + } + case -EREMOTEIO: { + SAM("-EREMOTEIO\n"); + break; + } + case -ENODEV: { + SAM("-ENODEV\n"); + break; + } + case -EXDEV: { + SAM("-EXDEV\n"); + break; + } + case -EINVAL: { + SAM("-EINVAL\n"); + break; + } + case -ECONNRESET: { + SAM("-ECONNRESET\n"); + break; + } + case -ENOSPC: { + SAM("-ENOSPC\n"); + break; + } + case -ESHUTDOWN: { + SAM("-ESHUTDOWN\n"); + break; + } + case -EPERM: { + SAM("-EPERM\n"); + break; + } + default: { + SAM("unknown error: %i\n", purb->iso_frame_desc[i].status); + break; + } + } + if (!purb->iso_frame_desc[i].status) { + more = purb->iso_frame_desc[i].actual_length; + if (!more) + peasycap->audio_mt++; + else { + if (peasycap->audio_mt) { + JOM(12, "%4i empty audio urb frames\n", \ + peasycap->audio_mt); + peasycap->audio_mt = 0; + } + + p1 = (__u8 *)(purb->transfer_buffer + \ + purb->iso_frame_desc[i].offset); + +/*---------------------------------------------------------------------------*/ +/* + * COPY more BYTES FROM ISOC BUFFER TO THE DMA BUFFER, + * CONVERTING 8-BIT MONO TO 16-BIT SIGNED LITTLE-ENDIAN SAMPLES IF NECESSARY + */ +/*---------------------------------------------------------------------------*/ + while (more) { + if (0 > more) { + SAM("MISTAKE: more is negative\n"); + return; + } + much = dma_bytes - peasycap->dma_fill; + if (0 > much) { + SAM("MISTAKE: much is negative\n"); + return; + } + if (0 == much) { + peasycap->dma_fill = 0; + peasycap->dma_next = fragment_bytes; + JOM(8, "wrapped dma buffer\n"); + } + if (false == peasycap->microphone) { + if (much > more) + much = more; + memcpy(prt->dma_area + \ + peasycap->dma_fill, \ + p1, much); + p1 += much; + more -= much; + } else { +#if defined(UPSAMPLE) + if (much % 16) + JOM(8, "MISTAKE? much" \ + " is not divisible by 16\n"); + if (much > (16 * \ + more)) + much = 16 * \ + more; + p2 = (__u8 *)(prt->dma_area + \ + peasycap->dma_fill); + + for (j = 0; j < (much/16); j++) { + newaudio = ((int) *p1) - 128; + newaudio = 128 * \ + newaudio; + + delta = (newaudio - oldaudio) \ + / 4; + s16 = oldaudio + delta; + + for (k = 0; k < 4; k++) { + *p2 = (0x00FF & s16); + *(p2 + 1) = (0xFF00 & \ + s16) >> 8; + p2 += 2; + *p2 = (0x00FF & s16); + *(p2 + 1) = (0xFF00 & \ + s16) >> 8; + p2 += 2; + s16 += delta; + } + p1++; + more--; + oldaudio = s16; + } +#else /*!UPSAMPLE*/ + if (much > (2 * more)) + much = 2 * more; + p2 = (__u8 *)(prt->dma_area + \ + peasycap->dma_fill); + + for (j = 0; j < (much / 2); j++) { + s16 = ((int) *p1) - 128; + s16 = 128 * \ + s16; + *p2 = (0x00FF & s16); + *(p2 + 1) = (0xFF00 & s16) >> \ + 8; + p1++; p2 += 2; + more--; + } +#endif /*UPSAMPLE*/ + } + peasycap->dma_fill += much; + if (peasycap->dma_fill >= peasycap->dma_next) { + isfragment = peasycap->dma_fill / \ + fragment_bytes; + if (0 > isfragment) { + SAM("MISTAKE: isfragment is " \ + "negative\n"); + return; + } + peasycap->dma_read = (isfragment \ + - 1) * fragment_bytes; + peasycap->dma_next = (isfragment \ + + 1) * fragment_bytes; + if (dma_bytes < peasycap->dma_next) { + peasycap->dma_next = \ + fragment_bytes; + } + if (0 <= peasycap->dma_read) { + JOM(8, "snd_pcm_period_elap" \ + "sed(), %i=" \ + "isfragment\n", \ + isfragment); + snd_pcm_period_elapsed(pss); + } + } + } + } + } else { + JOM(12, "discarding audio samples because " \ + "%i=purb->iso_frame_desc[i].status\n", \ + purb->iso_frame_desc[i].status); + } + +#if defined(UPSAMPLE) +peasycap->oldaudio = oldaudio; +#endif /*UPSAMPLE*/ + +} +/*---------------------------------------------------------------------------*/ +/* + * RESUBMIT THIS URB + */ +/*---------------------------------------------------------------------------*/ +resubmit: +if (peasycap->audio_isoc_streaming) { + rc = usb_submit_urb(purb, GFP_ATOMIC); + if (0 != rc) { + if ((-ENODEV != rc) && (-ENOENT != rc)) { + SAM("ERROR: while %i=audio_idle, " \ + "usb_submit_urb() failed " \ + "with rc:\n", peasycap->audio_idle); + } + switch (rc) { + case -ENODEV: + case -ENOENT: + break; + case -ENOMEM: { + SAM("-ENOMEM\n"); + break; + } + case -ENXIO: { + SAM("-ENXIO\n"); + break; + } + case -EINVAL: { + SAM("-EINVAL\n"); + break; + } + case -EAGAIN: { + SAM("-EAGAIN\n"); + break; + } + case -EFBIG: { + SAM("-EFBIG\n"); + break; + } + case -EPIPE: { + SAM("-EPIPE\n"); + break; + } + case -EMSGSIZE: { + SAM("-EMSGSIZE\n"); + break; + } + case -ENOSPC: { + SAM("-ENOSPC\n"); + break; + } + case -EPERM: { + SAM("-EPERM\n"); + break; + } + default: { + SAM("unknown error: %i\n", rc); + break; + } + } + if (0 < peasycap->audio_isoc_streaming) + (peasycap->audio_isoc_streaming)--; + } +} +return; +} +/*****************************************************************************/ +int +easycap_alsa_open(struct snd_pcm_substream *pss) +{ +struct snd_pcm *psnd_pcm; +struct snd_card *psnd_card; +struct easycap *peasycap; + +JOT(4, "\n"); +if (NULL == pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; +} +psnd_pcm = pss->pcm; +if (NULL == psnd_pcm) { + SAY("ERROR: psnd_pcm is NULL\n"); + return -EFAULT; +} +psnd_card = psnd_pcm->card; +if (NULL == psnd_card) { + SAY("ERROR: psnd_card is NULL\n"); + return -EFAULT; +} + +peasycap = psnd_card->private_data; +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; +} +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; +} +if (peasycap->psnd_card != psnd_card) { + SAM("ERROR: bad peasycap->psnd_card\n"); + return -EFAULT; +} +if (NULL != peasycap->psubstream) { + SAM("ERROR: bad peasycap->psubstream\n"); + return -EFAULT; +} +pss->private_data = peasycap; +peasycap->psubstream = pss; +pss->runtime->hw = peasycap->alsa_hardware; +pss->runtime->private_data = peasycap; +pss->private_data = peasycap; + +if (0 != easycap_sound_setup(peasycap)) { + JOM(4, "ending unsuccessfully\n"); + return -EFAULT; +} +JOM(4, "ending successfully\n"); +return 0; +} +/*****************************************************************************/ +int +easycap_alsa_close(struct snd_pcm_substream *pss) +{ +struct easycap *peasycap; + +JOT(4, "\n"); +if (NULL == pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; +} +peasycap = snd_pcm_substream_chip(pss); +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; +} +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; +} +pss->private_data = NULL; +peasycap->psubstream = (struct snd_pcm_substream *)NULL; +JOT(4, "ending successfully\n"); +return 0; +} +/*****************************************************************************/ +int +easycap_alsa_hw_params(struct snd_pcm_substream *pss, \ + struct snd_pcm_hw_params *phw) +{ +int rc; + +JOT(4, "%i\n", (params_buffer_bytes(phw))); +if (NULL == pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; +} +rc = easycap_alsa_vmalloc(pss, params_buffer_bytes(phw)); +if (0 != rc) + return rc; +return 0; +} +/*****************************************************************************/ +int +easycap_alsa_vmalloc(struct snd_pcm_substream *pss, size_t sz) +{ +struct snd_pcm_runtime *prt; +JOT(4, "\n"); + +if (NULL == pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; +} +prt = pss->runtime; +if (NULL == prt) { + SAY("ERROR: substream.runtime is NULL\n"); + return -EFAULT; +} +if (prt->dma_area) { + if (prt->dma_bytes > sz) + return 0; + vfree(prt->dma_area); +} +prt->dma_area = vmalloc(sz); +if (NULL == prt->dma_area) + return -ENOMEM; +prt->dma_bytes = sz; +return 0; +} +/*****************************************************************************/ +int +easycap_alsa_hw_free(struct snd_pcm_substream *pss) +{ +struct snd_pcm_runtime *prt; +JOT(4, "\n"); + +if (NULL == pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; +} +prt = pss->runtime; +if (NULL == prt) { + SAY("ERROR: substream.runtime is NULL\n"); + return -EFAULT; +} +if (NULL != prt->dma_area) { + JOT(8, "0x%08lX=prt->dma_area\n", (unsigned long int)prt->dma_area); + vfree(prt->dma_area); + prt->dma_area = NULL; +} else + JOT(8, "dma_area already freed\n"); +return 0; +} +/*****************************************************************************/ +int +easycap_alsa_prepare(struct snd_pcm_substream *pss) +{ +struct easycap *peasycap; +struct snd_pcm_runtime *prt; + +JOT(4, "\n"); +if (NULL == pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; +} +prt = pss->runtime; +peasycap = snd_pcm_substream_chip(pss); +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; +} +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; +} + +JOM(16, "ALSA decides %8i Hz=rate\n", (int)pss->runtime->rate); +JOM(16, "ALSA decides %8i =period_size\n", (int)pss->runtime->period_size); +JOM(16, "ALSA decides %8i =periods\n", (int)pss->runtime->periods); +JOM(16, "ALSA decides %8i =buffer_size\n", (int)pss->runtime->buffer_size); +JOM(16, "ALSA decides %8i =dma_bytes\n", (int)pss->runtime->dma_bytes); +JOM(16, "ALSA decides %8i =boundary\n", (int)pss->runtime->boundary); +JOM(16, "ALSA decides %8i =period_step\n", (int)pss->runtime->period_step); +JOM(16, "ALSA decides %8i =sample_bits\n", (int)pss->runtime->sample_bits); +JOM(16, "ALSA decides %8i =frame_bits\n", (int)pss->runtime->frame_bits); +JOM(16, "ALSA decides %8i =min_align\n", (int)pss->runtime->min_align); +JOM(12, "ALSA decides %8i =hw_ptr_base\n", (int)pss->runtime->hw_ptr_base); +JOM(12, "ALSA decides %8i =hw_ptr_interrupt\n", \ + (int)pss->runtime->hw_ptr_interrupt); +if (prt->dma_bytes != 4 * ((int)prt->period_size) * ((int)prt->periods)) { + SAY("MISTAKE: unexpected ALSA parameters\n"); + return -ENOENT; +} +return 0; +} +/*****************************************************************************/ +int +easycap_alsa_ack(struct snd_pcm_substream *pss) +{ +return 0; +} +/*****************************************************************************/ +int +easycap_alsa_trigger(struct snd_pcm_substream *pss, int cmd) +{ +struct easycap *peasycap; +int retval; + +JOT(4, "%i=cmd cf %i=START %i=STOP\n", cmd, SNDRV_PCM_TRIGGER_START, \ + SNDRV_PCM_TRIGGER_STOP); +if (NULL == pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; +} +peasycap = snd_pcm_substream_chip(pss); +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; +} +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; +} + +switch (cmd) { +case SNDRV_PCM_TRIGGER_START: { + peasycap->audio_idle = 0; + break; +} +case SNDRV_PCM_TRIGGER_STOP: { + peasycap->audio_idle = 1; + break; +} +default: + retval = -EINVAL; +} +return 0; +} +/*****************************************************************************/ +snd_pcm_uframes_t +easycap_alsa_pointer(struct snd_pcm_substream *pss) +{ +struct easycap *peasycap; +snd_pcm_uframes_t offset; + +JOT(16, "\n"); +if (NULL == pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; +} +peasycap = snd_pcm_substream_chip(pss); +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; +} +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; +} +if ((0 != peasycap->audio_eof) || (0 != peasycap->audio_idle)) { + JOM(8, "returning -EIO because " \ + "%i=audio_idle %i=audio_eof\n", \ + peasycap->audio_idle, peasycap->audio_eof); + return -EIO; +} +/*---------------------------------------------------------------------------*/ +if (0 > peasycap->dma_read) { + JOM(8, "returning -EBUSY\n"); + return -EBUSY; +} +offset = ((snd_pcm_uframes_t)peasycap->dma_read)/4; +JOM(8, "ALSA decides %8i =hw_ptr_base\n", (int)pss->runtime->hw_ptr_base); +JOM(8, "ALSA decides %8i =hw_ptr_interrupt\n", \ + (int)pss->runtime->hw_ptr_interrupt); +JOM(8, "%7i=offset %7i=dma_read %7i=dma_next\n", \ + (int)offset, peasycap->dma_read, peasycap->dma_next); +return offset; +} +/*****************************************************************************/ +struct page * +easycap_alsa_page(struct snd_pcm_substream *pss, unsigned long offset) +{ +return vmalloc_to_page(pss->runtime->dma_area + offset); +} +/*****************************************************************************/ + +#else /*!EASYCAP_NEEDS_ALSA*/ + +/*****************************************************************************/ +/**************************** **************************/ +/**************************** Open Sound System **************************/ +/**************************** **************************/ +/*****************************************************************************/ +/*--------------------------------------------------------------------------*/ +/* + * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE + */ +/*--------------------------------------------------------------------------*/ +const struct file_operations easyoss_fops = { + .owner = THIS_MODULE, + .open = easyoss_open, + .release = easyoss_release, +#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL) + .unlocked_ioctl = easyoss_ioctl_noinode, +#else + .ioctl = easyoss_ioctl, +#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/ + .read = easyoss_read, + .llseek = no_llseek, +}; +struct usb_class_driver easyoss_class = { +.name = "usb/easyoss%d", +.fops = &easyoss_fops, +.minor_base = USB_SKEL_MINOR_BASE, +}; /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* @@ -41,7 +922,7 @@ */ /*---------------------------------------------------------------------------*/ void -easysnd_complete(struct urb *purb) +easyoss_complete(struct urb *purb) { struct easycap *peasycap; struct data_buffer *paudio_buffer; @@ -68,27 +949,26 @@ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { SAY("ERROR: bad peasycap\n"); return; } - much = 0; - if (peasycap->audio_idle) { JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n", \ peasycap->audio_idle, peasycap->audio_isoc_streaming); if (peasycap->audio_isoc_streaming) { rc = usb_submit_urb(purb, GFP_ATOMIC); if (0 != rc) { - if (-ENODEV != rc) + if (-ENODEV != rc && -ENOENT != rc) { SAM("ERROR: while %i=audio_idle, " \ "usb_submit_urb() failed with rc:\n", \ peasycap->audio_idle); + } switch (rc) { + case -ENODEV: + case -ENOENT: + break; case -ENOMEM: { SAM("-ENOMEM\n"); break; } - case -ENODEV: { - break; - } case -ENXIO: { SAM("-ENXIO\n"); break; @@ -117,8 +997,12 @@ if (peasycap->audio_idle) { SAM("-ENOSPC\n"); break; } + case -EPERM: { + SAM("-EPERM\n"); + break; + } default: { - SAM("unknown error: 0x%08X\n", rc); + SAM("unknown error: %i\n", rc); break; } } @@ -214,63 +1098,16 @@ if (purb->status) { SAM("ENOSPC\n"); break; } - default: { - SAM("unknown error code 0x%08X\n", purb->status); + case -EPERM: { + SAM("-EPERM\n"); break; } + default: { + SAM("unknown error: %i\n", purb->status); + break; } -/*---------------------------------------------------------------------------*/ -/* - * RESUBMIT THIS URB AFTER AN ERROR - * - * (THIS IS DUPLICATE CODE TO REDUCE INDENTATION OF THE NO-ERROR PATH) - */ -/*---------------------------------------------------------------------------*/ - if (peasycap->audio_isoc_streaming) { - rc = usb_submit_urb(purb, GFP_ATOMIC); - if (0 != rc) { - SAM("ERROR: while %i=audio_idle, usb_submit_urb() " - "failed with rc:\n", peasycap->audio_idle); - switch (rc) { - case -ENOMEM: { - SAM("-ENOMEM\n"); - break; - } - case -ENODEV: { - SAM("-ENODEV\n"); - break; - } - case -ENXIO: { - SAM("-ENXIO\n"); - break; - } - case -EINVAL: { - SAM("-EINVAL\n"); - break; - } - case -EAGAIN: { - SAM("-EAGAIN\n"); - break; - } - case -EFBIG: { - SAM("-EFBIG\n"); - break; - } - case -EPIPE: { - SAM("-EPIPE\n"); - break; - } - case -EMSGSIZE: { - SAM("-EMSGSIZE\n"); - break; - } - default: { - SAM("0x%08X\n", rc); break; - } - } - } } - return; + goto resubmit; } /*---------------------------------------------------------------------------*/ /* @@ -286,6 +1123,10 @@ for (i = 0; i < purb->number_of_packets; i++) { case 0: { break; } + case -ENODEV: { + SAM("-ENODEV\n"); + break; + } case -ENOENT: { SAM("-ENOENT\n"); break; @@ -330,10 +1171,6 @@ for (i = 0; i < purb->number_of_packets; i++) { SAM("-EREMOTEIO\n"); break; } - case -ENODEV: { - SAM("-ENODEV\n"); - break; - } case -EXDEV: { SAM("-EXDEV\n"); break; @@ -354,8 +1191,12 @@ for (i = 0; i < purb->number_of_packets; i++) { SAM("-ESHUTDOWN\n"); break; } + case -EPERM: { + SAM("-EPERM\n"); + break; + } default: { - SAM("unknown error:0x%08X\n", purb->iso_frame_desc[i].status); + SAM("unknown error: %i\n", purb->iso_frame_desc[i].status); break; } } @@ -371,7 +1212,7 @@ for (i = 0; i < purb->number_of_packets; i++) { peasycap->audio_mt++; else { if (peasycap->audio_mt) { - JOM(16, "%4i empty audio urb frames\n", \ + JOM(12, "%4i empty audio urb frames\n", \ peasycap->audio_mt); peasycap->audio_mt = 0; } @@ -390,8 +1231,7 @@ for (i = 0; i < purb->number_of_packets; i++) { /*---------------------------------------------------------------------------*/ while (more) { if (0 > more) { - SAM("easysnd_complete: MISTAKE: " \ - "more is negative\n"); + SAM("MISTAKE: more is negative\n"); return; } if (peasycap->audio_buffer_page_many <= \ @@ -412,7 +1252,7 @@ for (i = 0; i < purb->number_of_packets; i++) { paudio_buffer->pgo)) { #if defined(TESTTONE) - easysnd_testtone(peasycap, \ + easyoss_testtone(peasycap, \ peasycap->audio_fill); #endif /*TESTTONE*/ @@ -424,7 +1264,7 @@ for (i = 0; i < purb->number_of_packets; i++) { peasycap->audio_fill) peasycap->audio_fill = 0; - JOM(12, "bumped peasycap->" \ + JOM(8, "bumped peasycap->" \ "audio_fill to %i\n", \ peasycap->audio_fill); @@ -497,7 +1337,7 @@ for (i = 0; i < purb->number_of_packets; i++) { more--; oldaudio = s16; } -#else +#else /*!UPSAMPLE*/ if (much > (2 * more)) much = 2 * more; p2 = (__u8 *)paudio_buffer->pto; @@ -530,25 +1370,26 @@ peasycap->oldaudio = oldaudio; } /*---------------------------------------------------------------------------*/ /* - * RESUBMIT THIS URB AFTER NO ERROR + * RESUBMIT THIS URB */ /*---------------------------------------------------------------------------*/ +resubmit: if (peasycap->audio_isoc_streaming) { rc = usb_submit_urb(purb, GFP_ATOMIC); if (0 != rc) { - if (-ENODEV != rc) { + if (-ENODEV != rc && -ENOENT != rc) { SAM("ERROR: while %i=audio_idle, " \ - "usb_submit_urb() failed " \ - "with rc:\n", peasycap->audio_idle); + "usb_submit_urb() failed " \ + "with rc:\n", peasycap->audio_idle); } switch (rc) { + case -ENODEV: + case -ENOENT: + break; case -ENOMEM: { SAM("-ENOMEM\n"); break; } - case -ENODEV: { - break; - } case -ENXIO: { SAM("-ENXIO\n"); break; @@ -577,8 +1418,12 @@ if (peasycap->audio_isoc_streaming) { SAM("-ENOSPC\n"); break; } + case -EPERM: { + SAM("-EPERM\n"); + break; + } default: { - SAM("unknown error: 0x%08X\n", rc); + SAM("unknown error: %i\n", rc); break; } } @@ -590,16 +1435,16 @@ return; /*---------------------------------------------------------------------------*/ /* * THE AUDIO URBS ARE SUBMITTED AT THIS EARLY STAGE SO THAT IT IS POSSIBLE TO - * STREAM FROM /dev/easysnd1 WITH SIMPLE PROGRAMS SUCH AS cat WHICH DO NOT + * STREAM FROM /dev/easyoss1 WITH SIMPLE PROGRAMS SUCH AS cat WHICH DO NOT * HAVE AN IOCTL INTERFACE. */ /*---------------------------------------------------------------------------*/ int -easysnd_open(struct inode *inode, struct file *file) +easyoss_open(struct inode *inode, struct file *file) { struct usb_interface *pusb_interface; struct easycap *peasycap; -int subminor, rc; +int subminor; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #if defined(EASYCAP_IS_VIDEODEV_CLIENT) #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) @@ -660,59 +1505,15 @@ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { file->private_data = peasycap; -/*---------------------------------------------------------------------------*/ -/* - * INITIALIZATION - */ -/*---------------------------------------------------------------------------*/ -JOM(4, "starting initialization\n"); - -if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -ENODEV; -} -JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device); - -rc = audio_setup(peasycap); -if (0 <= rc) - JOM(8, "audio_setup() returned %i\n", rc); -else - JOM(8, "easysnd open(): ERROR: audio_setup() returned %i\n", rc); - -if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device has become NULL\n"); - return -ENODEV; -} -/*---------------------------------------------------------------------------*/ -if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device has become NULL\n"); - return -ENODEV; +if (0 != easycap_sound_setup(peasycap)) { + ; + ; } -rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, \ - peasycap->audio_altsetting_on); -JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, \ - peasycap->audio_altsetting_on, rc); - -rc = wakeup_device(peasycap->pusb_device); -if (0 == rc) - JOM(8, "wakeup_device() returned %i\n", rc); -else - JOM(8, "ERROR: wakeup_device() returned %i\n", rc); - -peasycap->audio_eof = 0; -peasycap->audio_idle = 0; - -peasycap->timeval1.tv_sec = 0; -peasycap->timeval1.tv_usec = 0; - -submit_audio_urbs(peasycap); - -JOM(4, "finished initialization\n"); return 0; } /*****************************************************************************/ int -easysnd_release(struct inode *inode, struct file *file) +easyoss_release(struct inode *inode, struct file *file) { struct easycap *peasycap; @@ -736,7 +1537,7 @@ return 0; } /*****************************************************************************/ ssize_t -easysnd_read(struct file *file, char __user *puserspacebuffer, \ +easyoss_read(struct file *file, char __user *puserspacebuffer, \ size_t kount, loff_t *poff) { struct timeval timeval; @@ -760,7 +1561,7 @@ size_t szret; */ /*---------------------------------------------------------------------------*/ -JOT(8, "===== easysnd_read(): kount=%i, *poff=%i\n", (int)kount, (int)(*poff)); +JOT(8, "%5i=kount %5i=*poff\n", (int)kount, (int)(*poff)); if (NULL == file) { SAY("ERROR: file is NULL\n"); @@ -768,7 +1569,7 @@ if (NULL == file) { } peasycap = file->private_data; if (NULL == peasycap) { - SAY("ERROR in easysnd_read(): peasycap is NULL\n"); + SAY("ERROR in easyoss_read(): peasycap is NULL\n"); return -EFAULT; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { @@ -776,16 +1577,17 @@ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { return -EFAULT; } if (NULL == peasycap->pusb_device) { - SAY("ERROR in easysnd_read(): peasycap->pusb_device is NULL\n"); + SAY("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } kd = isdongle(peasycap); if (0 <= kd && DONGLE_MANY > kd) { - if (mutex_lock_interruptible(&(easycap_dongle[kd].mutex_audio))) { - SAY("ERROR: cannot lock easycap_dongle[%i].mutex_audio\n", kd); + if (mutex_lock_interruptible(&(easycapdc60_dongle[kd].mutex_audio))) { + SAY("ERROR: " + "cannot lock easycapdc60_dongle[%i].mutex_audio\n", kd); return -ERESTARTSYS; } - JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd); + JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd); /*---------------------------------------------------------------------------*/ /* * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap, @@ -797,24 +1599,24 @@ if (0 <= kd && DONGLE_MANY > kd) { return -ERESTARTSYS; if (NULL == file) { SAY("ERROR: file is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; } peasycap = file->private_data; if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { SAY("ERROR: bad peasycap: 0x%08lX\n", \ (unsigned long int) peasycap); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; } if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; } } else { @@ -835,13 +1637,13 @@ else if ((0 > peasycap->audio_read) || \ (peasycap->audio_buffer_page_many <= peasycap->audio_read)) { SAM("ERROR: peasycap->audio_read out of range\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; if ((struct data_buffer *)NULL == pdata_buffer) { SAM("ERROR: pdata_buffer is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } JOM(12, "before wait, %i=frag read %i=frag fill\n", \ @@ -853,7 +1655,7 @@ while ((fragment == (peasycap->audio_fill / \ (0 == (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))) { if (file->f_flags & O_NONBLOCK) { JOM(16, "returning -EAGAIN as instructed\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EAGAIN; } rc = wait_event_interruptible(peasycap->wq_audio, \ @@ -863,25 +1665,25 @@ while ((fragment == (peasycap->audio_fill / \ (0 < (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))))); if (0 != rc) { SAM("aborted by signal\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; } if (peasycap->audio_eof) { JOM(8, "returning 0 because %i=audio_eof\n", \ peasycap->audio_eof); kill_audio_urbs(peasycap); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return 0; } if (peasycap->audio_idle) { JOM(16, "returning 0 because %i=audio_idle\n", \ peasycap->audio_idle); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return 0; } if (!peasycap->audio_isoc_streaming) { JOM(16, "returning 0 because audio urbs not streaming\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return 0; } } @@ -889,22 +1691,23 @@ JOM(12, "after wait, %i=frag read %i=frag fill\n", \ (peasycap->audio_read / peasycap->audio_pages_per_fragment), \ (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); szret = (size_t)0; +fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment); while (fragment == (peasycap->audio_read / \ peasycap->audio_pages_per_fragment)) { if (NULL == pdata_buffer->pgo) { SAM("ERROR: pdata_buffer->pgo is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } if (NULL == pdata_buffer->pto) { SAM("ERROR: pdata_buffer->pto is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo); if (0 > kount1) { - SAM("easysnd_read: MISTAKE: kount1 is negative\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + SAM("MISTAKE: kount1 is negative\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; } if (!kount1) { @@ -922,23 +1725,23 @@ while (fragment == (peasycap->audio_read / \ (peasycap->audio_buffer_page_many <= \ peasycap->audio_read)) { SAM("ERROR: peasycap->audio_read out of range\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; if ((struct data_buffer *)NULL == pdata_buffer) { SAM("ERROR: pdata_buffer is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } if (NULL == pdata_buffer->pgo) { SAM("ERROR: pdata_buffer->pgo is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } if (NULL == pdata_buffer->pto) { SAM("ERROR: pdata_buffer->pto is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo); @@ -967,7 +1770,7 @@ while (fragment == (peasycap->audio_read / \ rc = copy_to_user(puserspacebuffer, pdata_buffer->pto, more); if (0 != rc) { SAM("ERROR: copy_to_user() returned %li\n", rc); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } *poff += (loff_t)more; @@ -1029,11 +1832,75 @@ if (!peasycap->timeval1.tv_sec) { JOM(8, "audio streaming at %lli bytes/second\n", sdr.quotient); peasycap->dnbydt = sdr.quotient; +mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); +JOM(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd); JOM(8, "returning %li\n", (long int)szret); -mutex_unlock(&easycap_dongle[kd].mutex_audio); return szret; } /*****************************************************************************/ + +#endif /*!EASYCAP_NEEDS_ALSA*/ + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ +/*---------------------------------------------------------------------------*/ +/* + * COMMON AUDIO INITIALIZATION + */ +/*---------------------------------------------------------------------------*/ +int +easycap_sound_setup(struct easycap *peasycap) +{ +int rc; + +JOM(4, "starting initialization\n"); + +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL.\n"); + return -EFAULT; +} +if ((struct usb_device *)NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -ENODEV; +} +JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device); + +rc = audio_setup(peasycap); +JOM(8, "audio_setup() returned %i\n", rc); + +if ((struct usb_device *)NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device has become NULL\n"); + return -ENODEV; +} +/*---------------------------------------------------------------------------*/ +if ((struct usb_device *)NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device has become NULL\n"); + return -ENODEV; +} +rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, \ + peasycap->audio_altsetting_on); +JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, \ + peasycap->audio_altsetting_on, rc); + +rc = wakeup_device(peasycap->pusb_device); +JOM(8, "wakeup_device() returned %i\n", rc); + +peasycap->audio_eof = 0; +peasycap->audio_idle = 0; + +peasycap->timeval1.tv_sec = 0; +peasycap->timeval1.tv_usec = 0; + +submit_audio_urbs(peasycap); + +JOM(4, "finished initialization\n"); +return 0; +} +/*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* * SUBMIT ALL AUDIO URBS. @@ -1087,7 +1954,11 @@ if (!peasycap->audio_isoc_streaming) { peasycap->audio_isoc_buffer[isbuf].pgo; purb->transfer_buffer_length = \ peasycap->audio_isoc_buffer_size; - purb->complete = easysnd_complete; +#if defined(EASYCAP_NEEDS_ALSA) + purb->complete = easycap_alsa_complete; +#else + purb->complete = easyoss_complete; +#endif /*EASYCAP_NEEDS_ALSA*/ purb->context = peasycap; purb->start_frame = 0; purb->number_of_packets = \ @@ -1109,14 +1980,18 @@ if (!peasycap->audio_isoc_streaming) { SAM("ERROR: usb_submit_urb() failed" \ " for urb with rc:\n"); switch (rc) { - case -ENOMEM: { - SAM("-ENOMEM\n"); - break; - } case -ENODEV: { SAM("-ENODEV\n"); break; } + case -ENOENT: { + SAM("-ENOENT\n"); + break; + } + case -ENOMEM: { + SAM("-ENOMEM\n"); + break; + } case -ENXIO: { SAM("-ENXIO\n"); break; @@ -1145,9 +2020,12 @@ if (!peasycap->audio_isoc_streaming) { nospc++; break; } + case -EPERM: { + SAM("-EPERM\n"); + break; + } default: { - SAM("unknown error code %i\n",\ - rc); + SAM("unknown error: %i\n", rc); break; } } @@ -1179,7 +2057,7 @@ if (!peasycap->audio_isoc_streaming) { } peasycap->audio_isoc_streaming = 0; } else { - peasycap->audio_isoc_streaming = 1; + peasycap->audio_isoc_streaming = m; JOM(4, "submitted %i audio urbs\n", m); } } else diff --git a/drivers/staging/easycap/easycap_sound.h b/drivers/staging/easycap/easycap_sound.h index 491273969023..82104c884105 100644 --- a/drivers/staging/easycap/easycap_sound.h +++ b/drivers/staging/easycap/easycap_sound.h @@ -24,5 +24,19 @@ * */ /*****************************************************************************/ +#if !defined(EASYCAP_SOUND_H) +#define EASYCAP_SOUND_H + +extern int easycap_debug; +extern int easycap_gain; +extern struct easycap_dongle easycapdc60_dongle[]; extern struct easycap *peasycap; extern struct usb_driver easycap_usb_driver; +#if defined(EASYCAP_NEEDS_ALSA) +extern struct snd_pcm_hardware easycap_pcm_hardware; +#else +extern struct usb_class_driver easyoss_class; +extern const struct file_operations easyoss_fops; +#endif /*EASYCAP_NEEDS_ALSA*/ + +#endif /*EASYCAP_SOUND_H*/ diff --git a/drivers/staging/easycap/easycap_standard.h b/drivers/staging/easycap/easycap_standard.h deleted file mode 100644 index cadc8d27a856..000000000000 --- a/drivers/staging/easycap/easycap_standard.h +++ /dev/null @@ -1,27 +0,0 @@ -/***************************************************************************** -* * -* easycap_standard.h * -* * -*****************************************************************************/ -/* - * - * Copyright (C) 2010 R.M. Thomas - * - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * -*/ -/*****************************************************************************/ -extern struct easycap_standard easycap_standard[]; diff --git a/drivers/staging/easycap/easycap_testcard.c b/drivers/staging/easycap/easycap_testcard.c index e27dfe9a9ba3..1089603f2499 100644 --- a/drivers/staging/easycap/easycap_testcard.c +++ b/drivers/staging/easycap/easycap_testcard.c @@ -26,7 +26,7 @@ /*****************************************************************************/ #include "easycap.h" -#include "easycap_debug.h" +#include "easycap_testcard.h" /*****************************************************************************/ #define TESTCARD_BYTESPERLINE (2 * 720) @@ -397,7 +397,7 @@ int tones[2048] = { }; /*****************************************************************************/ void -easysnd_testtone(struct easycap *peasycap, int audio_fill) +easyoss_testtone(struct easycap *peasycap, int audio_fill) { int i1; unsigned char *p2; diff --git a/drivers/staging/easycap/easycap_testcard.h b/drivers/staging/easycap/easycap_testcard.h new file mode 100644 index 000000000000..51591275af2e --- /dev/null +++ b/drivers/staging/easycap/easycap_testcard.h @@ -0,0 +1,34 @@ +/***************************************************************************** +* * +* easycap_testcard.h * +* * +*****************************************************************************/ +/* + * + * Copyright (C) 2010 R.M. Thomas + * + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ +/*****************************************************************************/ +#if !defined(EASYCAP_TESTCARD_H) +#define EASYCAP_TESTCARD_H + +extern int easycap_debug; +extern int easycap_gain; +extern struct easycap_dongle easycapdc60_dongle[]; + +#endif /*EASYCAP_TESTCARD_H*/ -- cgit v1.2.3 From 2a9a05c43294d703e351753da49231c47e0aad0d Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 18 Jan 2011 14:03:23 +0200 Subject: Staging: easycap: fix sparse warnings for module parameters easycap_main.c:34:5: warning: symbol 'easycap_debug' was not declared. Should it be static? easycap_main.c:36:5: warning: symbol 'easycap_gain' was not declared. Should it be static? These two variables actually were declared in several places. The variables are used in several files. I've fixed "easycap_debug" so it gets declared in one place only and included properly. For "easycap_gain" made it static and I created added a ->gain member to the easycap struct. This seems cleaner than using a global variable and later on we may make this controlable via sysfs. Cc:Mike Thomas Signed-off-by: Tomas Winkler Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 4 ++++ drivers/staging/easycap/easycap_ioctl.h | 2 -- drivers/staging/easycap/easycap_low.c | 6 +----- drivers/staging/easycap/easycap_low.h | 2 -- drivers/staging/easycap/easycap_main.c | 7 ++++++- drivers/staging/easycap/easycap_settings.h | 2 -- drivers/staging/easycap/easycap_sound.h | 2 -- drivers/staging/easycap/easycap_testcard.h | 2 -- 8 files changed, 11 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 111f53c33229..1205f5f9f9e8 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -475,6 +475,7 @@ int audio_idle; int audio_eof; int volume; int mute; +s8 gain; struct data_buffer audio_isoc_buffer[AUDIO_ISOC_BUFFER_MANY]; @@ -639,6 +640,8 @@ struct signed_div_result { long long int quotient; unsigned long long int remainder; } signed_div(long long int, long long int); + + /*---------------------------------------------------------------------------*/ /* * MACROS @@ -668,6 +671,7 @@ unsigned long long int remainder; * IMMEDIATELY OBVIOUS FROM A CASUAL READING OF THE SOURCE CODE. BEWARE. */ /*---------------------------------------------------------------------------*/ +extern int easycap_debug; #define SAY(format, args...) do { \ printk(KERN_DEBUG "easycap:: %s: " \ format, __func__, ##args); \ diff --git a/drivers/staging/easycap/easycap_ioctl.h b/drivers/staging/easycap/easycap_ioctl.h index 938de375efab..245386fd26ff 100644 --- a/drivers/staging/easycap/easycap_ioctl.h +++ b/drivers/staging/easycap/easycap_ioctl.h @@ -27,8 +27,6 @@ #if !defined(EASYCAP_IOCTL_H) #define EASYCAP_IOCTL_H -extern int easycap_debug; -extern int easycap_gain; extern struct easycap_dongle easycapdc60_dongle[]; extern struct easycap_standard easycap_standard[]; extern struct easycap_format easycap_format[]; diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index b618d4be3e5c..e9f3a36f50c4 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -1091,11 +1091,7 @@ SAM("0x%04X:0x%04X is audio vendor id\n", id1, id2); * SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN. */ /*---------------------------------------------------------------------------*/ -if (31 < easycap_gain) - easycap_gain = 31; -if (0 > easycap_gain) - easycap_gain = 0; -if (0 != audio_gainset(pusb_device, (__s8)easycap_gain)) +if (0 != audio_gainset(pusb_device, peasycap->gain)) SAY("ERROR: audio_gainset() failed\n"); check_vt(pusb_device); return 0; diff --git a/drivers/staging/easycap/easycap_low.h b/drivers/staging/easycap/easycap_low.h index d2b69e9c6b30..7f3b393dca6e 100644 --- a/drivers/staging/easycap/easycap_low.h +++ b/drivers/staging/easycap/easycap_low.h @@ -27,8 +27,6 @@ #if !defined(EASYCAP_LOW_H) #define EASYCAP_LOW_H -extern int easycap_debug; -extern int easycap_gain; extern struct easycap_dongle easycapdc60_dongle[]; #endif /*EASYCAP_LOW_H*/ diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 84128cf90007..a0b954cfdd75 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -33,7 +33,7 @@ int easycap_debug; static int easycap_bars = 1; -int easycap_gain = 16; +static int easycap_gain = 16; module_param_named(debug, easycap_debug, int, S_IRUGO | S_IWUSR); module_param_named(bars, easycap_bars, int, S_IRUGO | S_IWUSR); module_param_named(gain, easycap_gain, int, S_IRUGO | S_IWUSR); @@ -3412,6 +3412,8 @@ struct v4l2_device *pv4l2_device; #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +/* setup modules params */ + if ((struct usb_interface *)NULL == pusb_interface) { SAY("ERROR: pusb_interface is NULL\n"); return -EFAULT; @@ -3547,6 +3549,9 @@ if (0 == bInterfaceNumber) { "%i=peasycap->kref.refcount.counter\n", \ bInterfaceNumber, peasycap->kref.refcount.counter); + /* module params */ + peasycap->gain = (s8)clamp(easycap_gain, 0, 31); + init_waitqueue_head(&peasycap->wq_video); init_waitqueue_head(&peasycap->wq_audio); init_waitqueue_head(&peasycap->wq_trigger); diff --git a/drivers/staging/easycap/easycap_settings.h b/drivers/staging/easycap/easycap_settings.h index 5fe6f074425b..09b11cbea21e 100644 --- a/drivers/staging/easycap/easycap_settings.h +++ b/drivers/staging/easycap/easycap_settings.h @@ -27,8 +27,6 @@ #if !defined(EASYCAP_SETTINGS_H) #define EASYCAP_SETTINGS_H -extern int easycap_debug; -extern int easycap_gain; extern struct easycap_dongle easycapdc60_dongle[]; #endif /*EASYCAP_SETTINGS_H*/ diff --git a/drivers/staging/easycap/easycap_sound.h b/drivers/staging/easycap/easycap_sound.h index 82104c884105..ffcd6f203cca 100644 --- a/drivers/staging/easycap/easycap_sound.h +++ b/drivers/staging/easycap/easycap_sound.h @@ -27,8 +27,6 @@ #if !defined(EASYCAP_SOUND_H) #define EASYCAP_SOUND_H -extern int easycap_debug; -extern int easycap_gain; extern struct easycap_dongle easycapdc60_dongle[]; extern struct easycap *peasycap; extern struct usb_driver easycap_usb_driver; diff --git a/drivers/staging/easycap/easycap_testcard.h b/drivers/staging/easycap/easycap_testcard.h index 51591275af2e..2a21e7cfd8a5 100644 --- a/drivers/staging/easycap/easycap_testcard.h +++ b/drivers/staging/easycap/easycap_testcard.h @@ -27,8 +27,6 @@ #if !defined(EASYCAP_TESTCARD_H) #define EASYCAP_TESTCARD_H -extern int easycap_debug; -extern int easycap_gain; extern struct easycap_dongle easycapdc60_dongle[]; #endif /*EASYCAP_TESTCARD_H*/ -- cgit v1.2.3 From 1dc6e41825aa270cfc0166beb54afb1c235dc803 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 19 Jan 2011 00:24:06 +0200 Subject: staging: easycap: drop redunant backslashes from the code remove \ from the code where C syntex doesnt require it Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 25 +- drivers/staging/easycap/easycap_ioctl.c | 504 ++++++------- drivers/staging/easycap/easycap_low.c | 218 +++--- drivers/staging/easycap/easycap_main.c | 1122 ++++++++++++++-------------- drivers/staging/easycap/easycap_settings.c | 28 +- drivers/staging/easycap/easycap_sound.c | 266 +++---- 6 files changed, 1081 insertions(+), 1082 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 1205f5f9f9e8..d8e4bb817188 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -384,9 +384,9 @@ int video_eof; int video_junk; struct data_buffer video_isoc_buffer[VIDEO_ISOC_BUFFER_MANY]; -struct data_buffer \ +struct data_buffer field_buffer[FIELD_BUFFER_MANY][(FIELD_BUFFER_SIZE/PAGE_SIZE)]; -struct data_buffer \ +struct data_buffer frame_buffer[FRAME_BUFFER_MANY][(FRAME_BUFFER_SIZE/PAGE_SIZE)]; struct list_head urb_video_head; @@ -518,9 +518,9 @@ struct data_buffer audio_buffer[]; void easycap_complete(struct urb *); int easycap_open(struct inode *, struct file *); int easycap_release(struct inode *, struct file *); -long easycap_ioctl_noinode(struct file *, unsigned int, \ +long easycap_ioctl_noinode(struct file *, unsigned int, unsigned long); -int easycap_ioctl(struct inode *, struct file *, unsigned int, \ +int easycap_ioctl(struct inode *, struct file *, unsigned int, unsigned long); /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #if defined(EASYCAP_IS_VIDEODEV_CLIENT) @@ -532,7 +532,7 @@ int videodev_release(struct video_device *); unsigned int easycap_poll(struct file *, poll_table *); int easycap_mmap(struct file *, struct vm_area_struct *); -int easycap_usb_probe(struct usb_interface *, \ +int easycap_usb_probe(struct usb_interface *, const struct usb_device_id *); void easycap_usb_disconnect(struct usb_interface *); void easycap_delete(struct kref *); @@ -544,14 +544,14 @@ int easycap_dqbuf(struct easycap *, int); int submit_video_urbs(struct easycap *); int kill_video_urbs(struct easycap *); int field2frame(struct easycap *); -int redaub(struct easycap *, void *, void *, \ +int redaub(struct easycap *, void *, void *, int, int, __u8, __u8, bool); void easycap_testcard(struct easycap *, int); int fillin_formats(void); int reset(struct easycap *); int newinput(struct easycap *, int); int adjust_standard(struct easycap *, v4l2_std_id); -int adjust_format(struct easycap *, __u32, __u32, __u32, \ +int adjust_format(struct easycap *, __u32, __u32, __u32, int, bool); int adjust_brightness(struct easycap *, int); int adjust_contrast(struct easycap *, int); @@ -569,15 +569,14 @@ int easycap_alsa_probe(struct easycap *); void easycap_alsa_complete(struct urb *); int easycap_alsa_open(struct snd_pcm_substream *); int easycap_alsa_close(struct snd_pcm_substream *); -int easycap_alsa_hw_params(struct snd_pcm_substream *, \ +int easycap_alsa_hw_params(struct snd_pcm_substream *, struct snd_pcm_hw_params *); int easycap_alsa_vmalloc(struct snd_pcm_substream *, size_t); int easycap_alsa_hw_free(struct snd_pcm_substream *); int easycap_alsa_prepare(struct snd_pcm_substream *); int easycap_alsa_ack(struct snd_pcm_substream *); int easycap_alsa_trigger(struct snd_pcm_substream *, int); -snd_pcm_uframes_t \ - easycap_alsa_pointer(struct snd_pcm_substream *); +snd_pcm_uframes_t easycap_alsa_pointer(struct snd_pcm_substream *); struct page *easycap_alsa_page(struct snd_pcm_substream *, unsigned long); #else @@ -585,9 +584,9 @@ void easyoss_complete(struct urb *); ssize_t easyoss_read(struct file *, char __user *, size_t, loff_t *); int easyoss_open(struct inode *, struct file *); int easyoss_release(struct inode *, struct file *); -long easyoss_ioctl_noinode(struct file *, unsigned int, \ +long easyoss_ioctl_noinode(struct file *, unsigned int, unsigned long); -int easyoss_ioctl(struct inode *, struct file *, unsigned int, \ +int easyoss_ioctl(struct inode *, struct file *, unsigned int, unsigned long); unsigned int easyoss_poll(struct file *, poll_table *); void easyoss_delete(struct kref *); @@ -619,7 +618,7 @@ int ready_saa(struct usb_device *); int merit_saa(struct usb_device *); int check_vt(struct usb_device *); int select_input(struct usb_device *, int, int); -int set_resolution(struct usb_device *, \ +int set_resolution(struct usb_device *, __u16, __u16, __u16, __u16); int read_saa(struct usb_device *, __u16); diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 20d30334233e..af6f04b06955 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -72,13 +72,13 @@ if (0xFFFF == peasycap_standard->mask) { } } if (0xFFFF == peasycap_standard->mask) { - SAM("ERROR: 0x%08X=std_id: standard not found\n", \ + SAM("ERROR: 0x%08X=std_id: standard not found\n", (unsigned int)std_id); return -EINVAL; } -SAM("selected standard: %s\n", \ +SAM("selected standard: %s\n", &(peasycap_standard->v4l2_standard.name[0])); -if (peasycap->standard_offset == \ +if (peasycap->standard_offset == (int)(peasycap_standard - &easycap_standard[0])) { SAM("requested standard already in effect\n"); return 0; @@ -86,17 +86,17 @@ if (peasycap->standard_offset == \ peasycap->standard_offset = (int)(peasycap_standard - &easycap_standard[0]); for (k = 0; k < INPUT_MANY; k++) { if (!peasycap->inputset[k].standard_offset_ok) { - peasycap->inputset[k].standard_offset = \ + peasycap->inputset[k].standard_offset = peasycap->standard_offset; } } if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { - peasycap->inputset[peasycap->input].standard_offset = \ + peasycap->inputset[peasycap->input].standard_offset = peasycap->standard_offset; peasycap->inputset[peasycap->input].standard_offset_ok = 1; } else JOM(8, "%i=peasycap->input\n", peasycap->input); -peasycap->fps = peasycap_standard->v4l2_standard.frameperiod.denominator / \ +peasycap->fps = peasycap_standard->v4l2_standard.frameperiod.denominator / peasycap_standard->v4l2_standard.frameperiod.numerator; switch (peasycap->fps) { case 6: @@ -145,15 +145,15 @@ case NTSC_M_JP: { itwas = (unsigned int)ir; rc = write_saa(peasycap->pusb_device, reg, set); if (0 != rc) - SAM("ERROR: failed to set SAA register " \ + SAM("ERROR: failed to set SAA register " "0x%02X to 0x%02X for JP standard\n", reg, set); else { isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); if (0 > ir) - JOM(8, "SAA register 0x%02X changed " \ + JOM(8, "SAA register 0x%02X changed " "to 0x%02X\n", reg, isnow); else - JOM(8, "SAA register 0x%02X changed " \ + JOM(8, "SAA register 0x%02X changed " "from 0x%02X to 0x%02X\n", reg, itwas, isnow); } @@ -165,15 +165,15 @@ case NTSC_M_JP: { itwas = (unsigned int)ir; rc = write_saa(peasycap->pusb_device, reg, set); if (0 != rc) - SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X " \ + SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X " "for JP standard\n", reg, set); else { isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); if (0 > ir) - JOM(8, "SAA register 0x%02X changed " \ + JOM(8, "SAA register 0x%02X changed " "to 0x%02X\n", reg, isnow); else - JOM(8, "SAA register 0x%02X changed " \ + JOM(8, "SAA register 0x%02X changed " "from 0x%02X to 0x%02X\n", reg, itwas, isnow); } /*--------------------------------------------------------------------------*/ @@ -213,15 +213,15 @@ if (need) { itwas = (unsigned int)ir; rc = write_saa(peasycap->pusb_device, reg, set); if (0 != write_saa(peasycap->pusb_device, reg, set)) { - SAM("ERROR: failed to set SAA register " \ + SAM("ERROR: failed to set SAA register " "0x%02X to 0x%02X for table 42\n", reg, set); } else { isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); if (0 > ir) - JOM(8, "SAA register 0x%02X changed " \ + JOM(8, "SAA register 0x%02X changed " "to 0x%02X\n", reg, isnow); else - JOM(8, "SAA register 0x%02X changed " \ + JOM(8, "SAA register 0x%02X changed " "from 0x%02X to 0x%02X\n", reg, itwas, isnow); } } @@ -233,7 +233,7 @@ if (need) { reg = 0x08; ir = read_saa(peasycap->pusb_device, reg); if (0 > ir) - SAM("ERROR: failed to read SAA register 0x%02X " \ + SAM("ERROR: failed to read SAA register 0x%02X " "so cannot reset\n", reg); else { itwas = (unsigned int)ir; @@ -243,15 +243,15 @@ else { set = itwas & ~0x40 ; rc = write_saa(peasycap->pusb_device, reg, set); if (0 != rc) - SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \ + SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", reg, set); else { isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); if (0 > ir) - JOM(8, "SAA register 0x%02X changed to 0x%02X\n", \ + JOM(8, "SAA register 0x%02X changed to 0x%02X\n", reg, isnow); else - JOM(8, "SAA register 0x%02X changed " \ + JOM(8, "SAA register 0x%02X changed " "from 0x%02X to 0x%02X\n", reg, itwas, isnow); } } @@ -263,7 +263,7 @@ else { reg = 0x40; ir = read_saa(peasycap->pusb_device, reg); if (0 > ir) - SAM("ERROR: failed to read SAA register 0x%02X " \ + SAM("ERROR: failed to read SAA register 0x%02X " "so cannot reset\n", reg); else { itwas = (unsigned int)ir; @@ -273,15 +273,15 @@ else { set = itwas & ~0x80 ; rc = write_saa(peasycap->pusb_device, reg, set); if (0 != rc) - SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \ + SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", reg, set); else { isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); if (0 > ir) - JOM(8, "SAA register 0x%02X changed to 0x%02X\n", \ + JOM(8, "SAA register 0x%02X changed to 0x%02X\n", reg, isnow); else - JOM(8, "SAA register 0x%02X changed " \ + JOM(8, "SAA register 0x%02X changed " "from 0x%02X to 0x%02X\n", reg, itwas, isnow); } } @@ -300,7 +300,7 @@ if (0 > ir) else set = 0x07 ; if (0 != write_saa(peasycap->pusb_device, reg, set)) - SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \ + SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", reg, set); else { isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); @@ -340,7 +340,7 @@ return 0; * ERRORS RETURN A NEGATIVE NUMBER. */ /*--------------------------------------------------------------------------*/ -int adjust_format(struct easycap *peasycap, \ +int adjust_format(struct easycap *peasycap, __u32 width, __u32 height, __u32 pixelformat, int field, bool try) { struct easycap_format *peasycap_format, *peasycap_best_format; @@ -369,7 +369,7 @@ uc = pixelformat; memcpy((void *)pc, (void *)(&uc), 4); bf[4] = 0; mask = 0xFF & easycap_standard[peasycap->standard_offset].mask; -SAM("sought: %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n", \ +SAM("sought: %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n", width, height, pc, pixelformat, field, mask); switch (field) { case V4L2_FIELD_ANY: { @@ -425,18 +425,18 @@ if (V4L2_FIELD_ANY == field) { peasycap_best_format = (struct easycap_format *)NULL; peasycap_format = &easycap_format[0]; while (0 != peasycap_format->v4l2_format.fmt.pix.width) { - JOM(16, ".> %i %i 0x%08X %ix%i\n", \ + JOM(16, ".> %i %i 0x%08X %ix%i\n", peasycap_format->mask & 0x01, peasycap_format->v4l2_format.fmt.pix.field, peasycap_format->v4l2_format.fmt.pix.pixelformat, peasycap_format->v4l2_format.fmt.pix.width, peasycap_format->v4l2_format.fmt.pix.height); - if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && \ - (peasycap_format->v4l2_format.fmt.pix.field == field) && \ - (peasycap_format->v4l2_format.fmt.pix.pixelformat == \ - pixelformat) && \ - (peasycap_format->v4l2_format.fmt.pix.width == width) && \ + if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && + (peasycap_format->v4l2_format.fmt.pix.field == field) && + (peasycap_format->v4l2_format.fmt.pix.pixelformat == + pixelformat) && + (peasycap_format->v4l2_format.fmt.pix.width == width) && (peasycap_format->v4l2_format.fmt.pix.height == height)) { peasycap_best_format = peasycap_format; break; @@ -444,16 +444,16 @@ while (0 != peasycap_format->v4l2_format.fmt.pix.width) { peasycap_format++; } if (0 == peasycap_format->v4l2_format.fmt.pix.width) { - SAM("cannot do: %ix%i with standard mask 0x%02X\n", \ + SAM("cannot do: %ix%i with standard mask 0x%02X\n", width, height, mask); peasycap_format = &easycap_format[0]; best = -1; while (0 != peasycap_format->v4l2_format.fmt.pix.width) { - if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && \ - (peasycap_format->v4l2_format.fmt.pix\ - .field == field) && \ - (peasycap_format->v4l2_format.fmt.pix\ + if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && + (peasycap_format->v4l2_format.fmt.pix + .field == field) && + (peasycap_format->v4l2_format.fmt.pix .pixelformat == pixelformat)) { - miss = abs(peasycap_format->\ + miss = abs(peasycap_format-> v4l2_format.fmt.pix.width - width); if ((best > miss) || (best < 0)) { best = miss; @@ -465,9 +465,9 @@ if (0 == peasycap_format->v4l2_format.fmt.pix.width) { peasycap_format++; } if (-1 == best) { - SAM("cannot do %ix... with standard mask 0x%02X\n", \ + SAM("cannot do %ix... with standard mask 0x%02X\n", width, mask); - SAM("cannot do ...x%i with standard mask 0x%02X\n", \ + SAM("cannot do ...x%i with standard mask 0x%02X\n", height, mask); SAM(" %ix%i unmatched\n", width, height); return peasycap->format_offset; @@ -488,8 +488,8 @@ if (false != try) { SAM("MISTAKE: true==try where is should be false\n"); return -EINVAL; } -SAM("actioning: %ix%i %s\n", \ - peasycap_format->v4l2_format.fmt.pix.width, \ +SAM("actioning: %ix%i %s\n", + peasycap_format->v4l2_format.fmt.pix.width, peasycap_format->v4l2_format.fmt.pix.height, &peasycap_format->name[0]); peasycap->height = peasycap_format->v4l2_format.fmt.pix.height; @@ -500,12 +500,12 @@ peasycap->format_offset = (int)(peasycap_format - &easycap_format[0]); for (k = 0; k < INPUT_MANY; k++) { if (!peasycap->inputset[k].format_offset_ok) { - peasycap->inputset[k].format_offset = \ + peasycap->inputset[k].format_offset = peasycap->format_offset; } } if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { - peasycap->inputset[peasycap->input].format_offset = \ + peasycap->inputset[peasycap->input].format_offset = peasycap->format_offset; peasycap->inputset[peasycap->input].format_offset_ok = 1; } else @@ -534,9 +534,9 @@ if (true == peasycap->decimatepixel) multiplier = 2; else multiplier = 1; -peasycap->videofieldamount = multiplier * peasycap->width * \ +peasycap->videofieldamount = multiplier * peasycap->width * multiplier * peasycap->height; -peasycap->frame_buffer_used = peasycap->bytesperpixel * \ +peasycap->frame_buffer_used = peasycap->bytesperpixel * peasycap->width * peasycap->height; if (peasycap->video_isoc_streaming) { resubmit = true; @@ -549,29 +549,29 @@ if (peasycap->video_isoc_streaming) { */ /*---------------------------------------------------------------------------*/ if (0 == (0x01 & peasycap_format->mask)) { - if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && \ - (576 == \ - peasycap_format->v4l2_format.fmt.pix.height)) || \ - ((360 == \ - peasycap_format->v4l2_format.fmt.pix.width) && \ - (288 == \ + if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && + (576 == + peasycap_format->v4l2_format.fmt.pix.height)) || + ((360 == + peasycap_format->v4l2_format.fmt.pix.width) && + (288 == peasycap_format->v4l2_format.fmt.pix.height))) { if (0 != set_resolution(p, 0x0000, 0x0001, 0x05A0, 0x0121)) { SAM("ERROR: set_resolution() failed\n"); return -EINVAL; } - } else if ((704 == peasycap_format->v4l2_format.fmt.pix.width) && \ + } else if ((704 == peasycap_format->v4l2_format.fmt.pix.width) && (576 == peasycap_format->v4l2_format.fmt.pix.height)) { if (0 != set_resolution(p, 0x0004, 0x0001, 0x0584, 0x0121)) { SAM("ERROR: set_resolution() failed\n"); return -EINVAL; } - } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && \ - (480 == \ - peasycap_format->v4l2_format.fmt.pix.height)) || \ - ((320 == \ - peasycap_format->v4l2_format.fmt.pix.width) && \ - (240 == \ + } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && + (480 == + peasycap_format->v4l2_format.fmt.pix.height)) || + ((320 == + peasycap_format->v4l2_format.fmt.pix.width) && + (240 == peasycap_format->v4l2_format.fmt.pix.height))) { if (0 != set_resolution(p, 0x0014, 0x0020, 0x0514, 0x0110)) { SAM("ERROR: set_resolution() failed\n"); @@ -587,23 +587,23 @@ if (0 == (0x01 & peasycap_format->mask)) { */ /*---------------------------------------------------------------------------*/ } else { - if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && \ - (480 == \ - peasycap_format->v4l2_format.fmt.pix.height)) || \ - ((360 == \ - peasycap_format->v4l2_format.fmt.pix.width) && \ - (240 == \ + if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && + (480 == + peasycap_format->v4l2_format.fmt.pix.height)) || + ((360 == + peasycap_format->v4l2_format.fmt.pix.width) && + (240 == peasycap_format->v4l2_format.fmt.pix.height))) { if (0 != set_resolution(p, 0x0000, 0x0003, 0x05A0, 0x00F3)) { SAM("ERROR: set_resolution() failed\n"); return -EINVAL; } - } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && \ - (480 == \ - peasycap_format->v4l2_format.fmt.pix.height)) || \ - ((320 == \ - peasycap_format->v4l2_format.fmt.pix.width) && \ - (240 == \ + } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && + (480 == + peasycap_format->v4l2_format.fmt.pix.height)) || + ((320 == + peasycap_format->v4l2_format.fmt.pix.width) && + (240 == peasycap_format->v4l2_format.fmt.pix.height))) { if (0 != set_resolution(p, 0x0014, 0x0003, 0x0514, 0x00F3)) { SAM("ERROR: set_resolution() failed\n"); @@ -636,15 +636,15 @@ if ((struct usb_device *)NULL == peasycap->pusb_device) { i1 = 0; while (0xFFFFFFFF != easycap_control[i1].id) { if (V4L2_CID_BRIGHTNESS == easycap_control[i1].id) { - if ((easycap_control[i1].minimum > value) || \ + if ((easycap_control[i1].minimum > value) || (easycap_control[i1].maximum < value)) value = easycap_control[i1].default_value; - if ((easycap_control[i1].minimum <= peasycap->brightness) && \ - (easycap_control[i1].maximum >= \ + if ((easycap_control[i1].minimum <= peasycap->brightness) && + (easycap_control[i1].maximum >= peasycap->brightness)) { if (peasycap->brightness == value) { - SAM("unchanged brightness at 0x%02X\n", \ + SAM("unchanged brightness at 0x%02X\n", value); return 0; } @@ -652,11 +652,11 @@ while (0xFFFFFFFF != easycap_control[i1].id) { peasycap->brightness = value; for (k = 0; k < INPUT_MANY; k++) { if (!peasycap->inputset[k].brightness_ok) - peasycap->inputset[k].brightness = \ + peasycap->inputset[k].brightness = peasycap->brightness; } if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { - peasycap->inputset[peasycap->input].brightness = \ + peasycap->inputset[peasycap->input].brightness = peasycap->brightness; peasycap->inputset[peasycap->input].brightness_ok = 1; } else @@ -666,7 +666,7 @@ while (0xFFFFFFFF != easycap_control[i1].id) { SAM("adjusting brightness to 0x%02X\n", mood); return 0; } else { - SAM("WARNING: failed to adjust brightness " \ + SAM("WARNING: failed to adjust brightness " "to 0x%02X\n", mood); return -ENOENT; } @@ -694,14 +694,14 @@ if ((struct usb_device *)NULL == peasycap->pusb_device) { i1 = 0; while (0xFFFFFFFF != easycap_control[i1].id) { if (V4L2_CID_CONTRAST == easycap_control[i1].id) { - if ((easycap_control[i1].minimum > value) || \ + if ((easycap_control[i1].minimum > value) || (easycap_control[i1].maximum < value)) value = easycap_control[i1].default_value; - if ((easycap_control[i1].minimum <= peasycap->contrast) && \ - (easycap_control[i1].maximum >= \ + if ((easycap_control[i1].minimum <= peasycap->contrast) && + (easycap_control[i1].maximum >= peasycap->contrast)) { if (peasycap->contrast == value) { SAM("unchanged contrast at 0x%02X\n", value); @@ -711,12 +711,12 @@ while (0xFFFFFFFF != easycap_control[i1].id) { peasycap->contrast = value; for (k = 0; k < INPUT_MANY; k++) { if (!peasycap->inputset[k].contrast_ok) { - peasycap->inputset[k].contrast = \ + peasycap->inputset[k].contrast = peasycap->contrast; } } if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { - peasycap->inputset[peasycap->input].contrast = \ + peasycap->inputset[peasycap->input].contrast = peasycap->contrast; peasycap->inputset[peasycap->input].contrast_ok = 1; } else @@ -726,7 +726,7 @@ while (0xFFFFFFFF != easycap_control[i1].id) { SAM("adjusting contrast to 0x%02X\n", mood); return 0; } else { - SAM("WARNING: failed to adjust contrast to " \ + SAM("WARNING: failed to adjust contrast to " "0x%02X\n", mood); return -ENOENT; } @@ -754,16 +754,16 @@ if ((struct usb_device *)NULL == peasycap->pusb_device) { i1 = 0; while (0xFFFFFFFF != easycap_control[i1].id) { if (V4L2_CID_SATURATION == easycap_control[i1].id) { - if ((easycap_control[i1].minimum > value) || \ + if ((easycap_control[i1].minimum > value) || (easycap_control[i1].maximum < value)) value = easycap_control[i1].default_value; - if ((easycap_control[i1].minimum <= peasycap->saturation) && \ - (easycap_control[i1].maximum >= \ + if ((easycap_control[i1].minimum <= peasycap->saturation) && + (easycap_control[i1].maximum >= peasycap->saturation)) { if (peasycap->saturation == value) { - SAM("unchanged saturation at 0x%02X\n", \ + SAM("unchanged saturation at 0x%02X\n", value); return 0; } @@ -771,12 +771,12 @@ while (0xFFFFFFFF != easycap_control[i1].id) { peasycap->saturation = value; for (k = 0; k < INPUT_MANY; k++) { if (!peasycap->inputset[k].saturation_ok) { - peasycap->inputset[k].saturation = \ + peasycap->inputset[k].saturation = peasycap->saturation; } } if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { - peasycap->inputset[peasycap->input].saturation = \ + peasycap->inputset[peasycap->input].saturation = peasycap->saturation; peasycap->inputset[peasycap->input].saturation_ok = 1; } else @@ -786,7 +786,7 @@ while (0xFFFFFFFF != easycap_control[i1].id) { SAM("adjusting saturation to 0x%02X\n", mood); return 0; } else { - SAM("WARNING: failed to adjust saturation to " \ + SAM("WARNING: failed to adjust saturation to " "0x%02X\n", mood); return -ENOENT; } @@ -814,12 +814,12 @@ if ((struct usb_device *)NULL == peasycap->pusb_device) { i1 = 0; while (0xFFFFFFFF != easycap_control[i1].id) { if (V4L2_CID_HUE == easycap_control[i1].id) { - if ((easycap_control[i1].minimum > value) || \ + if ((easycap_control[i1].minimum > value) || (easycap_control[i1].maximum < value)) value = easycap_control[i1].default_value; - if ((easycap_control[i1].minimum <= peasycap->hue) && \ - (easycap_control[i1].maximum >= \ + if ((easycap_control[i1].minimum <= peasycap->hue) && + (easycap_control[i1].maximum >= peasycap->hue)) { if (peasycap->hue == value) { SAM("unchanged hue at 0x%02X\n", value); @@ -832,7 +832,7 @@ while (0xFFFFFFFF != easycap_control[i1].id) { peasycap->inputset[k].hue = peasycap->hue; } if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { - peasycap->inputset[peasycap->input].hue = \ + peasycap->inputset[peasycap->input].hue = peasycap->hue; peasycap->inputset[peasycap->input].hue_ok = 1; } else @@ -870,11 +870,11 @@ if ((struct usb_device *)NULL == peasycap->pusb_device) { i1 = 0; while (0xFFFFFFFF != easycap_control[i1].id) { if (V4L2_CID_AUDIO_VOLUME == easycap_control[i1].id) { - if ((easycap_control[i1].minimum > value) || \ + if ((easycap_control[i1].minimum > value) || (easycap_control[i1].maximum < value)) value = easycap_control[i1].default_value; - if ((easycap_control[i1].minimum <= peasycap->volume) && \ - (easycap_control[i1].maximum >= \ + if ((easycap_control[i1].minimum <= peasycap->volume) && + (easycap_control[i1].maximum >= peasycap->volume)) { if (peasycap->volume == value) { SAM("unchanged volume at 0x%02X\n", value); @@ -882,14 +882,14 @@ while (0xFFFFFFFF != easycap_control[i1].id) { } } peasycap->volume = value; - mood = (16 > peasycap->volume) ? 16 : \ - ((31 < peasycap->volume) ? 31 : \ + mood = (16 > peasycap->volume) ? 16 : + ((31 < peasycap->volume) ? 31 : (__s8) peasycap->volume); if (!audio_gainset(peasycap->pusb_device, mood)) { SAM("adjusting volume to 0x%02X\n", mood); return 0; } else { - SAM("WARNING: failed to adjust volume to " \ + SAM("WARNING: failed to adjust volume to " "0x%2X\n", mood); return -ENOENT; } @@ -904,8 +904,8 @@ return -ENOENT; /*---------------------------------------------------------------------------*/ /* * AN ALTERNATIVE METHOD OF MUTING MIGHT SEEM TO BE: - * usb_set_interface(peasycap->pusb_device, \ - * peasycap->audio_interface, \ + * usb_set_interface(peasycap->pusb_device, + * peasycap->audio_interface, * peasycap->audio_altsetting_off); * HOWEVER, AFTER THIS COMMAND IS ISSUED ALL SUBSEQUENT URBS RECEIVE STATUS * -ESHUTDOWN. THE HANDLER ROUTINE easyxxx_complete() DECLINES TO RESUBMIT @@ -932,13 +932,13 @@ while (0xFFFFFFFF != easycap_control[i1].id) { case 1: { peasycap->audio_idle = 1; peasycap->timeval0.tv_sec = 0; - SAM("adjusting mute: %i=peasycap->audio_idle\n", \ + SAM("adjusting mute: %i=peasycap->audio_idle\n", peasycap->audio_idle); return 0; } default: { peasycap->audio_idle = 0; - SAM("adjusting mute: %i=peasycap->audio_idle\n", \ + SAM("adjusting mute: %i=peasycap->audio_idle\n", peasycap->audio_idle); return 0; } @@ -990,7 +990,7 @@ if (NULL == p) { kd = isdongle(peasycap); if (0 <= kd && DONGLE_MANY > kd) { if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { - SAY("ERROR: cannot lock " \ + SAY("ERROR: cannot lock " "easycapdc60_dongle[%i].mutex_video\n", kd); return -ERESTARTSYS; } @@ -1063,9 +1063,9 @@ case VIDIOC_QUERYCAP: { if (3 > i) { rc = (int) strict_strtol(p1, 10, &lng); if (0 != rc) { - SAM("ERROR: %i=strict_strtol(%s,.,,)\n", \ + SAM("ERROR: %i=strict_strtol(%s,.,,)\n", rc, p1); - mutex_unlock(&easycapdc60_dongle[kd].\ + mutex_unlock(&easycapdc60_dongle[kd]. mutex_video); return -EINVAL; } @@ -1075,27 +1075,27 @@ case VIDIOC_QUERYCAP: { } memset(&v4l2_capability, 0, sizeof(struct v4l2_capability)); - strlcpy(&v4l2_capability.driver[0], "easycap", \ + strlcpy(&v4l2_capability.driver[0], "easycap", sizeof(v4l2_capability.driver)); - v4l2_capability.capabilities = \ - V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | \ + v4l2_capability.capabilities = + V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE; v4l2_capability.version = KERNEL_VERSION(k[0], k[1], k[2]); JOM(8, "v4l2_capability.version=(%i,%i,%i)\n", k[0], k[1], k[2]); - strlcpy(&v4l2_capability.card[0], "EasyCAP DC60", \ + strlcpy(&v4l2_capability.card[0], "EasyCAP DC60", sizeof(v4l2_capability.card)); - if (usb_make_path(peasycap->pusb_device, &v4l2_capability.bus_info[0],\ + if (usb_make_path(peasycap->pusb_device, &v4l2_capability.bus_info[0], sizeof(v4l2_capability.bus_info)) < 0) { - strlcpy(&v4l2_capability.bus_info[0], "EasyCAP bus_info", \ + strlcpy(&v4l2_capability.bus_info[0], "EasyCAP bus_info", sizeof(v4l2_capability.bus_info)); - JOM(8, "%s=v4l2_capability.bus_info\n", \ + JOM(8, "%s=v4l2_capability.bus_info\n", &v4l2_capability.bus_info[0]); } - if (0 != copy_to_user((void __user *)arg, &v4l2_capability, \ + if (0 != copy_to_user((void __user *)arg, &v4l2_capability, sizeof(struct v4l2_capability))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1109,7 +1109,7 @@ case VIDIOC_ENUMINPUT: { JOM(8, "VIDIOC_ENUMINPUT\n"); - if (0 != copy_from_user(&v4l2_input, (void __user *)arg, \ + if (0 != copy_from_user(&v4l2_input, (void __user *)arg, sizeof(struct v4l2_input))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1125,7 +1125,7 @@ case VIDIOC_ENUMINPUT: { v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; v4l2_input.audioset = 0x01; v4l2_input.tuner = 0; - v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ + v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | V4L2_STD_NTSC ; v4l2_input.status = 0; JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); @@ -1137,7 +1137,7 @@ case VIDIOC_ENUMINPUT: { v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; v4l2_input.audioset = 0x01; v4l2_input.tuner = 0; - v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ + v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | V4L2_STD_NTSC ; v4l2_input.status = 0; JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); @@ -1149,7 +1149,7 @@ case VIDIOC_ENUMINPUT: { v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; v4l2_input.audioset = 0x01; v4l2_input.tuner = 0; - v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ + v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | V4L2_STD_NTSC ; v4l2_input.status = 0; JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); @@ -1161,7 +1161,7 @@ case VIDIOC_ENUMINPUT: { v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; v4l2_input.audioset = 0x01; v4l2_input.tuner = 0; - v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ + v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | V4L2_STD_NTSC ; v4l2_input.status = 0; JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); @@ -1173,7 +1173,7 @@ case VIDIOC_ENUMINPUT: { v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; v4l2_input.audioset = 0x01; v4l2_input.tuner = 0; - v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ + v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | V4L2_STD_NTSC ; v4l2_input.status = 0; JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); @@ -1185,7 +1185,7 @@ case VIDIOC_ENUMINPUT: { v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; v4l2_input.audioset = 0x01; v4l2_input.tuner = 0; - v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ + v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | V4L2_STD_NTSC ; v4l2_input.status = 0; JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); @@ -1198,7 +1198,7 @@ case VIDIOC_ENUMINPUT: { } } - if (0 != copy_to_user((void __user *)arg, &v4l2_input, \ + if (0 != copy_to_user((void __user *)arg, &v4l2_input, sizeof(struct v4l2_input))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1266,7 +1266,7 @@ case VIDIOC_ENUMAUDOUT: { JOM(8, "VIDIOC_ENUMAUDOUT\n"); - if (0 != copy_from_user(&v4l2_audioout, (void __user *)arg, \ + if (0 != copy_from_user(&v4l2_audioout, (void __user *)arg, sizeof(struct v4l2_audioout))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1280,7 +1280,7 @@ case VIDIOC_ENUMAUDOUT: { v4l2_audioout.index = 0; strcpy(&v4l2_audioout.name[0], "Soundtrack"); - if (0 != copy_to_user((void __user *)arg, &v4l2_audioout, \ + if (0 != copy_to_user((void __user *)arg, &v4l2_audioout, sizeof(struct v4l2_audioout))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1294,7 +1294,7 @@ case VIDIOC_QUERYCTRL: { JOM(8, "VIDIOC_QUERYCTRL\n"); - if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg, \ + if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg, sizeof(struct v4l2_queryctrl))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1303,9 +1303,9 @@ case VIDIOC_QUERYCTRL: { i1 = 0; while (0xFFFFFFFF != easycap_control[i1].id) { if (easycap_control[i1].id == v4l2_queryctrl.id) { - JOM(8, "VIDIOC_QUERYCTRL %s=easycap_control[%i]" \ + JOM(8, "VIDIOC_QUERYCTRL %s=easycap_control[%i]" ".name\n", &easycap_control[i1].name[0], i1); - memcpy(&v4l2_queryctrl, &easycap_control[i1], \ + memcpy(&v4l2_queryctrl, &easycap_control[i1], sizeof(struct v4l2_queryctrl)); break; } @@ -1316,7 +1316,7 @@ case VIDIOC_QUERYCTRL: { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } - if (0 != copy_to_user((void __user *)arg, &v4l2_queryctrl, \ + if (0 != copy_to_user((void __user *)arg, &v4l2_queryctrl, sizeof(struct v4l2_queryctrl))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1340,7 +1340,7 @@ case VIDIOC_G_CTRL: { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ENOMEM; } - if (0 != copy_from_user(pv4l2_control, (void __user *)arg, \ + if (0 != copy_from_user(pv4l2_control, (void __user *)arg, sizeof(struct v4l2_control))) { kfree(pv4l2_control); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); @@ -1382,14 +1382,14 @@ case VIDIOC_G_CTRL: { break; } default: { - SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", \ + SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", pv4l2_control->id); kfree(pv4l2_control); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } } - if (0 != copy_to_user((void __user *)arg, pv4l2_control, \ + if (0 != copy_to_user((void __user *)arg, pv4l2_control, sizeof(struct v4l2_control))) { kfree(pv4l2_control); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); @@ -1410,7 +1410,7 @@ case VIDIOC_S_CTRL: JOM(8, "VIDIOC_S_CTRL\n"); - if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \ + if (0 != copy_from_user(&v4l2_control, (void __user *)arg, sizeof(struct v4l2_control))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1461,7 +1461,7 @@ case VIDIOC_S_CTRL: break; } default: { - SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", \ + SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", v4l2_control.id); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; @@ -1482,7 +1482,7 @@ case VIDIOC_ENUM_FMT: { JOM(8, "VIDIOC_ENUM_FMT\n"); - if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg, \ + if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg, sizeof(struct v4l2_fmtdesc))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1543,7 +1543,7 @@ case VIDIOC_ENUM_FMT: { return -EINVAL; } } - if (0 != copy_to_user((void __user *)arg, &v4l2_fmtdesc, \ + if (0 != copy_to_user((void __user *)arg, &v4l2_fmtdesc, sizeof(struct v4l2_fmtdesc))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1562,7 +1562,7 @@ case VIDIOC_ENUM_FRAMESIZES: { JOM(8, "VIDIOC_ENUM_FRAMESIZES\n"); - if (0 != copy_from_user(&v4l2_frmsizeenum, (void __user *)arg, \ + if (0 != copy_from_user(&v4l2_frmsizeenum, (void __user *)arg, sizeof(struct v4l2_frmsizeenum))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1577,40 +1577,40 @@ case VIDIOC_ENUM_FRAMESIZES: { case 0: { v4l2_frmsizeenum.discrete.width = 640; v4l2_frmsizeenum.discrete.height = 480; - JOM(8, "%i=index: %ix%i\n", index, \ - (int)(v4l2_frmsizeenum.\ - discrete.width), \ - (int)(v4l2_frmsizeenum.\ + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. discrete.height)); break; } case 1: { v4l2_frmsizeenum.discrete.width = 320; v4l2_frmsizeenum.discrete.height = 240; - JOM(8, "%i=index: %ix%i\n", index, \ - (int)(v4l2_frmsizeenum.\ - discrete.width), \ - (int)(v4l2_frmsizeenum.\ + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. discrete.height)); break; } case 2: { v4l2_frmsizeenum.discrete.width = 720; v4l2_frmsizeenum.discrete.height = 480; - JOM(8, "%i=index: %ix%i\n", index, \ - (int)(v4l2_frmsizeenum.\ - discrete.width), \ - (int)(v4l2_frmsizeenum.\ + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. discrete.height)); break; } case 3: { v4l2_frmsizeenum.discrete.width = 360; v4l2_frmsizeenum.discrete.height = 240; - JOM(8, "%i=index: %ix%i\n", index, \ - (int)(v4l2_frmsizeenum.\ - discrete.width), \ - (int)(v4l2_frmsizeenum.\ + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. discrete.height)); break; } @@ -1625,50 +1625,50 @@ case VIDIOC_ENUM_FRAMESIZES: { case 0: { v4l2_frmsizeenum.discrete.width = 640; v4l2_frmsizeenum.discrete.height = 480; - JOM(8, "%i=index: %ix%i\n", index, \ - (int)(v4l2_frmsizeenum.\ - discrete.width), \ - (int)(v4l2_frmsizeenum.\ + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. discrete.height)); break; } case 1: { v4l2_frmsizeenum.discrete.width = 320; v4l2_frmsizeenum.discrete.height = 240; - JOM(8, "%i=index: %ix%i\n", index, \ - (int)(v4l2_frmsizeenum.\ - discrete.width), \ - (int)(v4l2_frmsizeenum.\ + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. discrete.height)); break; } case 2: { v4l2_frmsizeenum.discrete.width = 704; v4l2_frmsizeenum.discrete.height = 576; - JOM(8, "%i=index: %ix%i\n", index, \ - (int)(v4l2_frmsizeenum.\ - discrete.width), \ - (int)(v4l2_frmsizeenum.\ + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. discrete.height)); break; } case 3: { v4l2_frmsizeenum.discrete.width = 720; v4l2_frmsizeenum.discrete.height = 576; - JOM(8, "%i=index: %ix%i\n", index, \ - (int)(v4l2_frmsizeenum.\ - discrete.width), \ - (int)(v4l2_frmsizeenum.\ + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. discrete.height)); break; } case 4: { v4l2_frmsizeenum.discrete.width = 360; v4l2_frmsizeenum.discrete.height = 288; - JOM(8, "%i=index: %ix%i\n", index, \ - (int)(v4l2_frmsizeenum.\ - discrete.width), \ - (int)(v4l2_frmsizeenum.\ + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. discrete.height)); break; } @@ -1679,7 +1679,7 @@ case VIDIOC_ENUM_FRAMESIZES: { } } } - if (0 != copy_to_user((void __user *)arg, &v4l2_frmsizeenum, \ + if (0 != copy_to_user((void __user *)arg, &v4l2_frmsizeenum, sizeof(struct v4l2_frmsizeenum))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1708,7 +1708,7 @@ case VIDIOC_ENUM_FRAMEINTERVALS: { denominator = 25; } - if (0 != copy_from_user(&v4l2_frmivalenum, (void __user *)arg, \ + if (0 != copy_from_user(&v4l2_frmivalenum, (void __user *)arg, sizeof(struct v4l2_frmivalenum))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1722,16 +1722,16 @@ case VIDIOC_ENUM_FRAMEINTERVALS: { case 0: { v4l2_frmivalenum.discrete.numerator = 1; v4l2_frmivalenum.discrete.denominator = denominator; - JOM(8, "%i=index: %i/%i\n", index, \ - (int)(v4l2_frmivalenum.discrete.numerator), \ + JOM(8, "%i=index: %i/%i\n", index, + (int)(v4l2_frmivalenum.discrete.numerator), (int)(v4l2_frmivalenum.discrete.denominator)); break; } case 1: { v4l2_frmivalenum.discrete.numerator = 1; v4l2_frmivalenum.discrete.denominator = denominator/5; - JOM(8, "%i=index: %i/%i\n", index, \ - (int)(v4l2_frmivalenum.discrete.numerator), \ + JOM(8, "%i=index: %i/%i\n", index, + (int)(v4l2_frmivalenum.discrete.numerator), (int)(v4l2_frmivalenum.discrete.denominator)); break; } @@ -1741,7 +1741,7 @@ case VIDIOC_ENUM_FRAMEINTERVALS: { return -EINVAL; } } - if (0 != copy_to_user((void __user *)arg, &v4l2_frmivalenum, \ + if (0 != copy_to_user((void __user *)arg, &v4l2_frmivalenum, sizeof(struct v4l2_frmivalenum))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1767,7 +1767,7 @@ case VIDIOC_G_FMT: { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ENOMEM; } - if (0 != copy_from_user(pv4l2_format, (void __user *)arg, \ + if (0 != copy_from_user(pv4l2_format, (void __user *)arg, sizeof(struct v4l2_format))) { kfree(pv4l2_format); kfree(pv4l2_pix_format); @@ -1784,13 +1784,13 @@ case VIDIOC_G_FMT: { memset(pv4l2_pix_format, 0, sizeof(struct v4l2_pix_format)); pv4l2_format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - memcpy(&pv4l2_format->fmt.pix, \ - &easycap_format[peasycap->format_offset]\ + memcpy(&pv4l2_format->fmt.pix, + &easycap_format[peasycap->format_offset] .v4l2_format.fmt.pix, sizeof(struct v4l2_pix_format)); - JOM(8, "user is told: %s\n", \ + JOM(8, "user is told: %s\n", &easycap_format[peasycap->format_offset].name[0]); - if (0 != copy_to_user((void __user *)arg, pv4l2_format, \ + if (0 != copy_to_user((void __user *)arg, pv4l2_format, sizeof(struct v4l2_format))) { kfree(pv4l2_format); kfree(pv4l2_pix_format); @@ -1817,17 +1817,17 @@ case VIDIOC_S_FMT: { try = false; } - if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \ + if (0 != copy_from_user(&v4l2_format, (void __user *)arg, sizeof(struct v4l2_format))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } - best_format = adjust_format(peasycap, \ - v4l2_format.fmt.pix.width, \ - v4l2_format.fmt.pix.height, \ - v4l2_format.fmt.pix.pixelformat, \ - v4l2_format.fmt.pix.field, \ + best_format = adjust_format(peasycap, + v4l2_format.fmt.pix.width, + v4l2_format.fmt.pix.height, + v4l2_format.fmt.pix.pixelformat, + v4l2_format.fmt.pix.field, try); if (0 > best_format) { if (-EBUSY == best_format) { @@ -1842,11 +1842,11 @@ case VIDIOC_S_FMT: { memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format)); v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - memcpy(&(v4l2_format.fmt.pix), &(easycap_format[best_format]\ + memcpy(&(v4l2_format.fmt.pix), &(easycap_format[best_format] .v4l2_format.fmt.pix), sizeof(v4l2_pix_format)); JOM(8, "user is told: %s\n", &easycap_format[best_format].name[0]); - if (0 != copy_to_user((void __user *)arg, &v4l2_format, \ + if (0 != copy_to_user((void __user *)arg, &v4l2_format, sizeof(struct v4l2_format))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1859,7 +1859,7 @@ case VIDIOC_CROPCAP: { JOM(8, "VIDIOC_CROPCAP\n"); - if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg, \ + if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg, sizeof(struct v4l2_cropcap))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1883,7 +1883,7 @@ case VIDIOC_CROPCAP: { JOM(8, "user is told: %ix%i\n", peasycap->width, peasycap->height); - if (0 != copy_to_user((void __user *)arg, &v4l2_cropcap, \ + if (0 != copy_to_user((void __user *)arg, &v4l2_cropcap, sizeof(struct v4l2_cropcap))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1899,7 +1899,7 @@ case VIDIOC_S_CROP: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_QUERYSTD: { - JOM(8, "VIDIOC_QUERYSTD: " \ + JOM(8, "VIDIOC_QUERYSTD: " "EasyCAP is incapable of detecting standard\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; @@ -1921,7 +1921,7 @@ case VIDIOC_ENUMSTD: { JOM(8, "VIDIOC_ENUMSTD\n"); - if (0 != copy_from_user(&v4l2_standard, (void __user *)arg, \ + if (0 != copy_from_user(&v4l2_standard, (void __user *)arg, sizeof(struct v4l2_standard))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1929,7 +1929,7 @@ case VIDIOC_ENUMSTD: { index = v4l2_standard.index; last3 = last2; last2 = last1; last1 = last0; last0 = index; - if ((index == last3) && (index == last2) && \ + if ((index == last3) && (index == last2) && (index == last1) && (index == last0)) { index++; last3 = last2; last2 = last1; last1 = last0; last0 = index; @@ -1948,14 +1948,14 @@ case VIDIOC_ENUMSTD: { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } - JOM(8, "%i=index: %s\n", index, \ + JOM(8, "%i=index: %s\n", index, &(peasycap_standard->v4l2_standard.name[0])); - memcpy(&v4l2_standard, &(peasycap_standard->v4l2_standard), \ + memcpy(&v4l2_standard, &(peasycap_standard->v4l2_standard), sizeof(struct v4l2_standard)); v4l2_standard.index = index; - if (0 != copy_to_user((void __user *)arg, &v4l2_standard, \ + if (0 != copy_to_user((void __user *)arg, &v4l2_standard, sizeof(struct v4l2_standard))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1970,13 +1970,13 @@ case VIDIOC_G_STD: { JOM(8, "VIDIOC_G_STD\n"); if (0 > peasycap->standard_offset) { - JOM(8, "%i=peasycap->standard_offset\n", \ + JOM(8, "%i=peasycap->standard_offset\n", peasycap->standard_offset); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EBUSY; } - if (0 != copy_from_user(&std_id, (void __user *)arg, \ + if (0 != copy_from_user(&std_id, (void __user *)arg, sizeof(v4l2_std_id))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -1985,10 +1985,10 @@ case VIDIOC_G_STD: { peasycap_standard = &easycap_standard[peasycap->standard_offset]; std_id = peasycap_standard->v4l2_standard.id; - JOM(8, "user is told: %s\n", \ + JOM(8, "user is told: %s\n", &peasycap_standard->v4l2_standard.name[0]); - if (0 != copy_to_user((void __user *)arg, &std_id, \ + if (0 != copy_to_user((void __user *)arg, &std_id, sizeof(v4l2_std_id))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -2002,14 +2002,14 @@ case VIDIOC_S_STD: { JOM(8, "VIDIOC_S_STD\n"); - if (0 != copy_from_user(&std_id, (void __user *)arg, \ + if (0 != copy_from_user(&std_id, (void __user *)arg, sizeof(v4l2_std_id))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } - JOM(8, "User requests standard: 0x%08X%08X\n", \ - (int)((std_id & (((v4l2_std_id)0xFFFFFFFF) << 32)) >> 32), \ + JOM(8, "User requests standard: 0x%08X%08X\n", + (int)((std_id & (((v4l2_std_id)0xFFFFFFFF) << 32)) >> 32), (int)(std_id & ((v4l2_std_id)0xFFFFFFFF))); rc = adjust_standard(peasycap, std_id); @@ -2027,7 +2027,7 @@ case VIDIOC_REQBUFS: { JOM(8, "VIDIOC_REQBUFS\n"); - if (0 != copy_from_user(&v4l2_requestbuffers, (void __user *)arg, \ + if (0 != copy_from_user(&v4l2_requestbuffers, (void __user *)arg, sizeof(struct v4l2_requestbuffers))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -2048,16 +2048,16 @@ case VIDIOC_REQBUFS: { if (nbuffers > FRAME_BUFFER_MANY) nbuffers = FRAME_BUFFER_MANY; if (v4l2_requestbuffers.count == nbuffers) { - JOM(8, " ... agree to %i buffers\n", \ + JOM(8, " ... agree to %i buffers\n", nbuffers); } else { - JOM(8, " ... insist on %i buffers\n", \ + JOM(8, " ... insist on %i buffers\n", nbuffers); v4l2_requestbuffers.count = nbuffers; } peasycap->frame_buffer_many = nbuffers; - if (0 != copy_to_user((void __user *)arg, &v4l2_requestbuffers, \ + if (0 != copy_to_user((void __user *)arg, &v4l2_requestbuffers, sizeof(struct v4l2_requestbuffers))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -2072,13 +2072,13 @@ case VIDIOC_QUERYBUF: { JOM(8, "VIDIOC_QUERYBUF\n"); if (peasycap->video_eof) { - JOM(8, "returning -EIO because %i=video_eof\n", \ + JOM(8, "returning -EIO because %i=video_eof\n", peasycap->video_eof); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EIO; } - if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ + if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, sizeof(struct v4l2_buffer))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -2095,8 +2095,8 @@ case VIDIOC_QUERYBUF: { v4l2_buffer.index = index; v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v4l2_buffer.bytesused = peasycap->frame_buffer_used; - v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | \ - peasycap->done[index] | \ + v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | + peasycap->done[index] | peasycap->queued[index]; v4l2_buffer.field = V4L2_FIELD_NONE; v4l2_buffer.memory = V4L2_MEMORY_MMAP; @@ -2108,14 +2108,14 @@ case VIDIOC_QUERYBUF: { JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused); JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags); JOM(16, " %10i=field\n", v4l2_buffer.field); - JOM(16, " %10li=timestamp.tv_usec\n", \ + JOM(16, " %10li=timestamp.tv_usec\n", (long)v4l2_buffer.timestamp.tv_usec); JOM(16, " %10i=sequence\n", v4l2_buffer.sequence); JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory); JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset); JOM(16, " %10i=length\n", v4l2_buffer.length); - if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ + if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, sizeof(struct v4l2_buffer))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -2128,7 +2128,7 @@ case VIDIOC_QBUF: { JOM(8, "VIDIOC_QBUF\n"); - if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ + if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, sizeof(struct v4l2_buffer))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -2142,7 +2142,7 @@ case VIDIOC_QBUF: { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } - if (v4l2_buffer.index < 0 || \ + if (v4l2_buffer.index < 0 || (v4l2_buffer.index >= peasycap->frame_buffer_many)) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; @@ -2152,13 +2152,13 @@ case VIDIOC_QBUF: { peasycap->done[v4l2_buffer.index] = 0; peasycap->queued[v4l2_buffer.index] = V4L2_BUF_FLAG_QUEUED; - if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ + if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, sizeof(struct v4l2_buffer))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } - JOM(8, "..... user queueing frame buffer %i\n", \ + JOM(8, "..... user queueing frame buffer %i\n", (int)v4l2_buffer.index); peasycap->frame_lock = 0; @@ -2184,14 +2184,14 @@ case VIDIOC_DQBUF: JOM(8, "VIDIOC_DQBUF\n"); if ((peasycap->video_idle) || (peasycap->video_eof)) { - JOM(8, "returning -EIO because " \ - "%i=video_idle %i=video_eof\n", \ + JOM(8, "returning -EIO because " + "%i=video_idle %i=video_eof\n", peasycap->video_idle, peasycap->video_eof); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EIO; } - if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ + if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, sizeof(struct v4l2_buffer))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -2216,7 +2216,7 @@ case VIDIOC_DQBUF: else if (V4L2_FIELD_ANY == v4l2_buffer.field) JOM(8, "user wants V4L2_FIELD_ANY\n"); else - JOM(8, "user wants V4L2_FIELD_...UNKNOWN: %i\n", \ + JOM(8, "user wants V4L2_FIELD_...UNKNOWN: %i\n", v4l2_buffer.field); } @@ -2237,9 +2237,9 @@ case VIDIOC_DQBUF: do { rcdq = easycap_dqbuf(peasycap, 0); if (-EIO == rcdq) { - JOM(8, "returning -EIO because " \ + JOM(8, "returning -EIO because " "dqbuf() returned -EIO\n"); - mutex_unlock(&easycapdc60_dongle[kd].\ + mutex_unlock(&easycapdc60_dongle[kd]. mutex_video); return -EIO; } @@ -2251,7 +2251,7 @@ case VIDIOC_DQBUF: } } if (V4L2_BUF_FLAG_DONE != peasycap->done[peasycap->frame_read]) { - JOM(8, "V4L2_BUF_FLAG_DONE != 0x%08X\n", \ + JOM(8, "V4L2_BUF_FLAG_DONE != 0x%08X\n", peasycap->done[peasycap->frame_read]); } peasycap->polled = 0; @@ -2264,7 +2264,7 @@ case VIDIOC_DQBUF: for (i = 0; i < 180; i++) j += peasycap->merit[i]; if (90 < j) { - SAM("easycap driver shutting down " \ + SAM("easycap driver shutting down " "on condition blue\n"); peasycap->video_eof = 1; peasycap->audio_eof = 1; } @@ -2303,10 +2303,10 @@ case VIDIOC_DQBUF: timeval2.tv_sec = timeval1.tv_sec + sdr.quotient; } if (!(peasycap->isequence % 500)) { - fudge = ((long long int)(1000000)) * \ - ((long long int)(timeval.tv_sec - \ - timeval2.tv_sec)) + \ - (long long int)(timeval.tv_usec - \ + fudge = ((long long int)(1000000)) * + ((long long int)(timeval.tv_sec - + timeval2.tv_sec)) + + (long long int)(timeval.tv_usec - timeval2.tv_usec); sdr = signed_div(fudge, 1000); sll = sdr.quotient; @@ -2327,16 +2327,16 @@ case VIDIOC_DQBUF: JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused); JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags); JOM(16, " %10i=field\n", v4l2_buffer.field); - JOM(16, " %10li=timestamp.tv_sec\n", \ + JOM(16, " %10li=timestamp.tv_sec\n", (long)v4l2_buffer.timestamp.tv_sec); - JOM(16, " %10li=timestamp.tv_usec\n", \ + JOM(16, " %10li=timestamp.tv_usec\n", (long)v4l2_buffer.timestamp.tv_usec); JOM(16, " %10i=sequence\n", v4l2_buffer.sequence); JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory); JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset); JOM(16, " %10i=length\n", v4l2_buffer.length); - if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ + if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, sizeof(struct v4l2_buffer))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -2344,17 +2344,17 @@ case VIDIOC_DQBUF: input = peasycap->frame_buffer[peasycap->frame_read][0].input; if (0x08 & input) { - JOM(8, "user is offered frame buffer %i, input %i\n", \ + JOM(8, "user is offered frame buffer %i, input %i\n", peasycap->frame_read, (0x07 & input)); } else { - JOM(8, "user is offered frame buffer %i\n", \ + JOM(8, "user is offered frame buffer %i\n", peasycap->frame_read); } peasycap->frame_lock = 1; JOM(8, "%i=peasycap->frame_fill\n", peasycap->frame_fill); if (peasycap->frame_read == peasycap->frame_fill) { if (peasycap->frame_lock) { - JOM(8, "WORRY: filling frame buffer " \ + JOM(8, "WORRY: filling frame buffer " "while offered to user\n"); } } @@ -2421,7 +2421,7 @@ case VIDIOC_G_PARM: { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ENOMEM; } - if (0 != copy_from_user(pv4l2_streamparm, (void __user *)arg, \ + if (0 != copy_from_user(pv4l2_streamparm, (void __user *)arg, sizeof(struct v4l2_streamparm))) { kfree(pv4l2_streamparm); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); @@ -2438,22 +2438,22 @@ case VIDIOC_G_PARM: { pv4l2_streamparm->parm.capture.timeperframe.numerator = 1; if (peasycap->fps) { - pv4l2_streamparm->parm.capture.timeperframe.\ + pv4l2_streamparm->parm.capture.timeperframe. denominator = peasycap->fps; } else { if (true == peasycap->ntsc) { - pv4l2_streamparm->parm.capture.timeperframe.\ + pv4l2_streamparm->parm.capture.timeperframe. denominator = 30; } else { - pv4l2_streamparm->parm.capture.timeperframe.\ + pv4l2_streamparm->parm.capture.timeperframe. denominator = 25; } } - pv4l2_streamparm->parm.capture.readbuffers = \ + pv4l2_streamparm->parm.capture.readbuffers = peasycap->frame_buffer_many; pv4l2_streamparm->parm.capture.extendedmode = 0; - if (0 != copy_to_user((void __user *)arg, pv4l2_streamparm, \ + if (0 != copy_to_user((void __user *)arg, pv4l2_streamparm, sizeof(struct v4l2_streamparm))) { kfree(pv4l2_streamparm); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); @@ -2520,7 +2520,7 @@ return 0; /*****************************************************************************/ #if !defined(EASYCAP_NEEDS_ALSA) /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \ +#if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || (defined(EASYCAP_NEEDS_UNLOCKED_IOCTL))) long easyoss_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) { @@ -2674,7 +2674,7 @@ case SNDCTL_DSP_SETFMT: { JOM(8, "........... %i=outgoing\n", outgoing); JOM(8, " cf. %i=AFMT_S16_LE\n", AFMT_S16_LE); JOM(8, " cf. %i=AFMT_U8\n", AFMT_U8); - if (0 != copy_to_user((void __user *)arg, &outgoing, \ + if (0 != copy_to_user((void __user *)arg, &outgoing, sizeof(int))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; @@ -2762,8 +2762,8 @@ case SNDCTL_DSP_SETTRIGGER: { return -EFAULT; } JOM(8, "........... %i=incoming\n", incoming); - JOM(8, "........... cf 0x%x=PCM_ENABLE_INPUT " \ - "0x%x=PCM_ENABLE_OUTPUT\n", \ + JOM(8, "........... cf 0x%x=PCM_ENABLE_INPUT " + "0x%x=PCM_ENABLE_OUTPUT\n", PCM_ENABLE_INPUT, PCM_ENABLE_OUTPUT); ; ; @@ -2796,7 +2796,7 @@ case SNDCTL_DSP_GETISPACE: { audio_buf_info.fragsize = 0; audio_buf_info.fragstotal = 0; - if (0 != copy_to_user((void __user *)arg, &audio_buf_info, \ + if (0 != copy_to_user((void __user *)arg, &audio_buf_info, sizeof(int))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index e9f3a36f50c4..ea0da6976d4c 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -259,28 +259,28 @@ GET(p, 0x0114, &get4); GET(p, 0x0115, &get5); GET(p, 0x0116, &get6); GET(p, 0x0117, &get7); -JOT(8, "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X\n", \ +JOT(8, "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X\n", get0, get1, get2, get3, get4, get5, get6, get7); -JOT(8, "....cf PAL_720x526: " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X\n", \ +JOT(8, "....cf PAL_720x526: " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X\n", 0x000, 0x000, 0x001, 0x000, 0x5A0, 0x005, 0x121, 0x001); -JOT(8, "....cf PAL_704x526: " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X\n", \ +JOT(8, "....cf PAL_704x526: " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X\n", 0x004, 0x000, 0x001, 0x000, 0x584, 0x005, 0x121, 0x001); -JOT(8, "....cf VGA_640x480: " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X\n", \ +JOT(8, "....cf VGA_640x480: " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X\n", 0x008, 0x000, 0x020, 0x000, 0x508, 0x005, 0x110, 0x001); return 0; } @@ -336,13 +336,13 @@ if (NULL == p) i0 = 0; if (true == ntsc) { while (0xFF != saa7113configNTSC[i0].reg) { - ir = write_saa(p, saa7113configNTSC[i0].reg, \ + ir = write_saa(p, saa7113configNTSC[i0].reg, saa7113configNTSC[i0].set); i0++; } } else { while (0xFF != saa7113configPAL[i0].reg) { - ir = write_saa(p, saa7113configPAL[i0].reg, \ + ir = write_saa(p, saa7113configPAL[i0].reg, saa7113configPAL[i0].set); i0++; } @@ -400,7 +400,7 @@ SET(p, 0x0500, 0x008B); GET(p, 0x0502, &igot); got502 = (0xFF & igot); GET(p, 0x0503, &igot); got503 = (0xFF & igot); -JOT(16, "write_vt(., 0x%04X, 0x%04X): was 0x%04X\n", \ +JOT(16, "write_vt(., 0x%04X, 0x%04X): was 0x%04X\n", reg0, set0, ((got503 << 8) | got502)); set502 = (0x00FF & set0); @@ -485,9 +485,9 @@ if (true == ntsc) { ir = read_saa(p, saa7113configNTSC[i0].reg); if (ir != saa7113configNTSC[i0].set) { - SAY("SAA register 0x%02X has 0x%02X, " \ - "expected 0x%02X\n", \ - saa7113configNTSC[i0].reg, \ + SAY("SAA register 0x%02X has 0x%02X, " + "expected 0x%02X\n", + saa7113configNTSC[i0].reg, ir, saa7113configNTSC[i0].set); rc--; } @@ -502,9 +502,9 @@ if (true == ntsc) { ir = read_saa(p, saa7113configPAL[i0].reg); if (ir != saa7113configPAL[i0].set) { - SAY("SAA register 0x%02X has 0x%02X, " \ - "expected 0x%02X\n", \ - saa7113configPAL[i0].reg, \ + SAY("SAA register 0x%02X has 0x%02X, " + "expected 0x%02X\n", + saa7113configPAL[i0].reg, ir, saa7113configPAL[i0].set); rc--; } @@ -603,23 +603,23 @@ if (true == ntsc) { } ir = read_stk(p, stk1160configNTSC[i0].reg); if (0x100 == stk1160configNTSC[i0].reg) { - if ((ir != (0xFF & stk1160configNTSC[i0].set)) && \ - (ir != (0x80 | (0xFF & \ - stk1160configNTSC[i0].set))) && \ - (0xFFFF != \ + if ((ir != (0xFF & stk1160configNTSC[i0].set)) && + (ir != (0x80 | (0xFF & + stk1160configNTSC[i0].set))) && + (0xFFFF != stk1160configNTSC[i0].set)) { - SAY("STK register 0x%03X has 0x%02X, " \ - "expected 0x%02X\n", \ - stk1160configNTSC[i0].reg, \ + SAY("STK register 0x%03X has 0x%02X, " + "expected 0x%02X\n", + stk1160configNTSC[i0].reg, ir, stk1160configNTSC[i0].set); } i0++; continue; } - if ((ir != (0xFF & stk1160configNTSC[i0].set)) && \ + if ((ir != (0xFF & stk1160configNTSC[i0].set)) && (0xFFFF != stk1160configNTSC[i0].set)) { - SAY("STK register 0x%03X has 0x%02X, " \ - "expected 0x%02X\n", \ - stk1160configNTSC[i0].reg, \ + SAY("STK register 0x%03X has 0x%02X, " + "expected 0x%02X\n", + stk1160configNTSC[i0].reg, ir, stk1160configNTSC[i0].set); } i0++; @@ -634,23 +634,23 @@ if (true == ntsc) { } ir = read_stk(p, stk1160configPAL[i0].reg); if (0x100 == stk1160configPAL[i0].reg) { - if ((ir != (0xFF & stk1160configPAL[i0].set)) && \ - (ir != (0x80 | (0xFF & \ - stk1160configPAL[i0].set))) && \ - (0xFFFF != \ + if ((ir != (0xFF & stk1160configPAL[i0].set)) && + (ir != (0x80 | (0xFF & + stk1160configPAL[i0].set))) && + (0xFFFF != stk1160configPAL[i0].set)) { - SAY("STK register 0x%03X has 0x%02X, " \ - "expected 0x%02X\n", \ - stk1160configPAL[i0].reg, \ + SAY("STK register 0x%03X has 0x%02X, " + "expected 0x%02X\n", + stk1160configPAL[i0].reg, ir, stk1160configPAL[i0].set); } i0++; continue; } - if ((ir != (0xFF & stk1160configPAL[i0].set)) && \ + if ((ir != (0xFF & stk1160configPAL[i0].set)) && (0xFFFF != stk1160configPAL[i0].set)) { - SAY("STK register 0x%03X has 0x%02X, " \ - "expected 0x%02X\n", \ - stk1160configPAL[i0].reg, \ + SAY("STK register 0x%03X has 0x%02X, " + "expected 0x%02X\n", + stk1160configPAL[i0].reg, ir, stk1160configPAL[i0].set); } i0++; @@ -717,7 +717,7 @@ switch (input) { case 0: case 1: { if (0 != write_saa(p, 0x02, 0x80)) { - SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \ + SAY("ERROR: failed to set SAA register 0x02 for input %i\n", input); } SET(p, 0x0000, 0x0098); @@ -726,7 +726,7 @@ case 1: { } case 2: { if (0 != write_saa(p, 0x02, 0x80)) { - SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \ + SAY("ERROR: failed to set SAA register 0x02 for input %i\n", input); } SET(p, 0x0000, 0x0090); @@ -735,7 +735,7 @@ case 2: { } case 3: { if (0 != write_saa(p, 0x02, 0x80)) { - SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \ + SAY("ERROR: failed to set SAA register 0x02 for input %i\n", input); } SET(p, 0x0000, 0x0088); @@ -744,7 +744,7 @@ case 3: { } case 4: { if (0 != write_saa(p, 0x02, 0x80)) { - SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \ + SAY("ERROR: failed to set SAA register 0x02 for input %i\n", input); } SET(p, 0x0000, 0x0080); @@ -757,22 +757,22 @@ case 5: { switch (mode) { case 7: { if (0 != write_saa(p, 0x02, 0x87)) { - SAY("ERROR: failed to set SAA register 0x02 " \ + SAY("ERROR: failed to set SAA register 0x02 " "for input %i\n", input); } if (0 != write_saa(p, 0x05, 0xFF)) { - SAY("ERROR: failed to set SAA register 0x05 " \ + SAY("ERROR: failed to set SAA register 0x05 " "for input %i\n", input); } break; } case 9: { if (0 != write_saa(p, 0x02, 0x89)) { - SAY("ERROR: failed to set SAA register 0x02 " \ + SAY("ERROR: failed to set SAA register 0x02 " "for input %i\n", input); } if (0 != write_saa(p, 0x05, 0x00)) { - SAY("ERROR: failed to set SAA register 0x05 " \ + SAY("ERROR: failed to set SAA register 0x05 " "for input %i\n", input); } break; @@ -783,11 +783,11 @@ case 5: { } } if (0 != write_saa(p, 0x04, 0x00)) { - SAY("ERROR: failed to set SAA register 0x04 for input %i\n", \ + SAY("ERROR: failed to set SAA register 0x04 for input %i\n", input); } if (0 != write_saa(p, 0x09, 0x80)) { - SAY("ERROR: failed to set SAA register 0x09 for input %i\n", \ + SAY("ERROR: failed to set SAA register 0x09 for input %i\n", input); } SET(p, 0x0002, 0x0093); @@ -809,7 +809,7 @@ return 0; } /****************************************************************************/ int -set_resolution(struct usb_device *p, \ +set_resolution(struct usb_device *p, __u16 set0, __u16 set1, __u16 set2, __u16 set3) { __u16 u0x0111, u0x0113, u0x0115, u0x0117; @@ -915,25 +915,25 @@ int rc0, rc1; if (!pusb_device) return -ENODEV; rc1 = 0; igot = 0; -rc0 = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \ - (__u8)0x01, \ - (__u8)(USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE), \ - (__u16)value, \ - (__u16)index, \ - (void *)NULL, \ - (__u16)0, \ +rc0 = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), + (__u8)0x01, + (__u8)(USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE), + (__u16)value, + (__u16)index, + (void *)NULL, + (__u16)0, (int)500); #if defined(NOREADBACK) # #else -rc1 = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), \ - (__u8)0x00, \ - (__u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), \ - (__u16)0x00, \ - (__u16)index, \ - (void *)&igot, \ - (__u16)sizeof(__u16), \ +rc1 = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), + (__u8)0x00, + (__u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), + (__u16)0x00, + (__u16)index, + (void *)&igot, + (__u16)sizeof(__u16), (int)50000); igot = 0xFF & igot; switch (index) { @@ -951,15 +951,15 @@ case 0x205: case 0x350: case 0x351: { if (0 != (0xFF & igot)) { - JOT(8, "unexpected 0x%02X for STK register 0x%03X\n", \ + JOT(8, "unexpected 0x%02X for STK register 0x%03X\n", igot, index); } break; } default: { if ((0xFF & value) != (0xFF & igot)) { - JOT(8, "unexpected 0x%02X != 0x%02X " \ - "for STK register 0x%03X\n", \ + JOT(8, "unexpected 0x%02X != 0x%02X " + "for STK register 0x%03X\n", igot, value, index); } break; @@ -977,13 +977,13 @@ int ir; if (!pusb_device) return -ENODEV; -ir = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), \ - (__u8)0x00, \ - (__u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), \ - (__u16)0x00, \ - (__u16)index, \ - (void *)pvoid, \ - sizeof(__u8), \ +ir = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), + (__u8)0x00, + (__u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), + (__u16)0x00, + (__u16)index, + (void *)pvoid, + sizeof(__u8), (int)50000); return 0xFF & ir; } @@ -993,13 +993,13 @@ wakeup_device(struct usb_device *pusb_device) { if (!pusb_device) return -ENODEV; -return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \ - (__u8)USB_REQ_SET_FEATURE, \ - (__u8)(USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE), \ - USB_DEVICE_REMOTE_WAKEUP, \ - (__u16)0, \ - (void *) NULL, \ - (__u16)0, \ +return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), + (__u8)USB_REQ_SET_FEATURE, + (__u8)(USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE), + USB_DEVICE_REMOTE_WAKEUP, + (__u16)0, + (void *) NULL, + (__u16)0, (int)50000); } /*****************************************************************************/ @@ -1018,7 +1018,7 @@ int rc, id1, id2; */ /*---------------------------------------------------------------------------*/ const __u8 request = 0x01; -const __u8 requesttype = \ +const __u8 requesttype = (__u8)(USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE); const __u16 value_unmute = 0x0200; const __u16 index = 0x0301; @@ -1031,24 +1031,24 @@ pusb_device = peasycap->pusb_device; if (NULL == pusb_device) return -ENODEV; -JOM(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n", \ - requesttype, request, \ - (0x00FF & value_unmute), \ - (0xFF00 & value_unmute) >> 8, \ - (0x00FF & index), \ - (0xFF00 & index) >> 8, \ - (0x00FF & length), \ +JOM(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n", + requesttype, request, + (0x00FF & value_unmute), + (0xFF00 & value_unmute) >> 8, + (0x00FF & index), + (0xFF00 & index) >> 8, + (0x00FF & length), (0xFF00 & length) >> 8); buffer[0] = 0x01; -rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \ - (__u8)request, \ - (__u8)requesttype, \ - (__u16)value_unmute, \ - (__u16)index, \ - (void *)&buffer[0], \ - (__u16)length, \ +rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), + (__u8)request, + (__u8)requesttype, + (__u16)value_unmute, + (__u16)index, + (void *)&buffer[0], + (__u16)length, (int)50000); JOT(8, "0x%02X=buffer\n", *((__u8 *) &buffer[0])); @@ -1209,7 +1209,7 @@ if (0 > igot) { mute = 0x8000 & ((unsigned int)igot); mute = 0; -JOT(8, "0x%04X=(mute|u8|(u8<<8)) for VT1612A register 0x10,...0x18\n", \ +JOT(8, "0x%04X=(mute|u8|(u8<<8)) for VT1612A register 0x10,...0x18\n", mute | u8 | (u8 << 8)); write_vt(pusb_device, 0x0010, (mute | u8 | (u8 << 8))); write_vt(pusb_device, 0x0012, (mute | u8 | (u8 << 8))); @@ -1230,7 +1230,7 @@ if (16 <= loud) else u8 = 0; -JOT(8, "0x%04X=(mute|u8|(u8<<8)) for VT1612A register 0x1C\n", \ +JOT(8, "0x%04X=(mute|u8|(u8<<8)) for VT1612A register 0x1C\n", mute | u8 | (u8 << 8)); write_vt(pusb_device, 0x001C, (mute | u8 | (u8 << 8))); write_vt(pusb_device, 0x001A, 0x0404); diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index a0b954cfdd75..34a1ba663e0b 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -186,7 +186,7 @@ if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } else { - JOM(16, "0x%08lX=peasycap->pusb_device\n", \ + JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device); } file->private_data = peasycap; @@ -272,7 +272,7 @@ else { rate = ready_saa(peasycap->pusb_device); if (0 > rate) { JOM(8, "not ready to capture after %i ms ...\n", PATIENCE); - JOM(8, "... saa register 0x1F has 0x%02X\n", \ + JOM(8, "... saa register 0x1F has 0x%02X\n", read_saa(peasycap->pusb_device, 0x1F)); ntsc = peasycap->ntsc; } else { @@ -323,17 +323,17 @@ if (true == other) { peasycap_standard = &easycap_standard[0]; while (0xFFFF != peasycap_standard->mask) { if (true == ntsc) { - if (NTSC_M == \ + if (NTSC_M == peasycap_standard->v4l2_standard.index) { - peasycap->inputset[input].standard_offset = \ - peasycap_standard - \ + peasycap->inputset[input].standard_offset = + peasycap_standard - &easycap_standard[0]; break; } } else { - if (PAL_BGHIN == \ + if (PAL_BGHIN == peasycap_standard->v4l2_standard.index) { - peasycap->inputset[input].standard_offset = \ + peasycap->inputset[input].standard_offset = peasycap_standard - &easycap_standard[0]; break; @@ -345,7 +345,7 @@ if (true == other) { SAM("ERROR: standard not found\n"); return -EINVAL; } -JOM(8, "%i=peasycap->inputset[%i].standard_offset\n", \ +JOM(8, "%i=peasycap->inputset[%i].standard_offset\n", peasycap->inputset[input].standard_offset, input); } peasycap->format_offset = -8192; @@ -372,12 +372,12 @@ if (0 > peasycap->input) { return -ENOENT; } if (0 > peasycap->standard_offset) { - SAM("MISTAKE: %i=peasycap->standard_offset\n", \ + SAM("MISTAKE: %i=peasycap->standard_offset\n", peasycap->standard_offset); return -ENOENT; } if (0 > peasycap->format_offset) { - SAM("MISTAKE: %i=peasycap->format_offset\n", \ + SAM("MISTAKE: %i=peasycap->format_offset\n", peasycap->format_offset); return -ENOENT; } @@ -458,7 +458,7 @@ if (NULL == peasycap->pusb_device) { return -ENODEV; } rc = usb_set_interface(peasycap->pusb_device, - peasycap->video_interface, \ + peasycap->video_interface, peasycap->video_altsetting_off); if (0 != rc) { SAM("ERROR: usb_set_interface() returned %i\n", rc); @@ -494,24 +494,24 @@ select_input(peasycap->pusb_device, peasycap->input, 9); if (input == peasycap->inputset[input].input) { off = peasycap->inputset[input].standard_offset; if (off != peasycap->standard_offset) { - rc = adjust_standard(peasycap, \ + rc = adjust_standard(peasycap, easycap_standard[off].v4l2_standard.id); if (0 != rc) { SAM("ERROR: adjust_standard() returned %i\n", rc); return -EFAULT; } - JOM(8, "%i=peasycap->standard_offset\n", \ + JOM(8, "%i=peasycap->standard_offset\n", peasycap->standard_offset); } else { - JOM(8, "%i=peasycap->standard_offset unchanged\n", \ + JOM(8, "%i=peasycap->standard_offset unchanged\n", peasycap->standard_offset); } off = peasycap->inputset[input].format_offset; if (off != peasycap->format_offset) { - rc = adjust_format(peasycap, \ - easycap_format[off].v4l2_format.fmt.pix.width, \ - easycap_format[off].v4l2_format.fmt.pix.height, \ - easycap_format[off].v4l2_format.fmt.pix.pixelformat, \ + rc = adjust_format(peasycap, + easycap_format[off].v4l2_format.fmt.pix.width, + easycap_format[off].v4l2_format.fmt.pix.height, + easycap_format[off].v4l2_format.fmt.pix.pixelformat, easycap_format[off].v4l2_format.fmt.pix.field, false); if (0 > rc) { SAM("ERROR: adjust_format() returned %i\n", rc); @@ -519,7 +519,7 @@ if (input == peasycap->inputset[input].input) { } JOM(8, "%i=peasycap->format_offset\n", peasycap->format_offset); } else { - JOM(8, "%i=peasycap->format_offset unchanged\n", \ + JOM(8, "%i=peasycap->format_offset unchanged\n", peasycap->format_offset); } mood = peasycap->inputset[input].brightness; @@ -568,7 +568,7 @@ if (NULL == peasycap->pusb_device) { return -ENODEV; } rc = usb_set_interface(peasycap->pusb_device, - peasycap->video_interface, \ + peasycap->video_interface, peasycap->video_altsetting_on); if (0 != rc) { SAM("ERROR: usb_set_interface() returned %i\n", rc); @@ -623,74 +623,74 @@ if (!peasycap->video_isoc_streaming) { isbuf = pdata_urb->isbuf; purb->interval = 1; purb->dev = peasycap->pusb_device; - purb->pipe = \ - usb_rcvisocpipe(peasycap->pusb_device,\ + purb->pipe = + usb_rcvisocpipe(peasycap->pusb_device, peasycap->video_endpointnumber); purb->transfer_flags = URB_ISO_ASAP; - purb->transfer_buffer = \ + purb->transfer_buffer = peasycap->video_isoc_buffer[isbuf].pgo; - purb->transfer_buffer_length = \ + purb->transfer_buffer_length = peasycap->video_isoc_buffer_size; purb->complete = easycap_complete; purb->context = peasycap; purb->start_frame = 0; - purb->number_of_packets = \ + purb->number_of_packets = peasycap->video_isoc_framesperdesc; - for (j = 0; j < peasycap->\ + for (j = 0; j < peasycap-> video_isoc_framesperdesc; j++) { - purb->iso_frame_desc[j].\ - offset = j * \ - peasycap->\ + purb->iso_frame_desc[j]. + offset = j * + peasycap-> video_isoc_maxframesize; - purb->iso_frame_desc[j].\ - length = peasycap->\ + purb->iso_frame_desc[j]. + length = peasycap-> video_isoc_maxframesize; } rc = usb_submit_urb(purb, GFP_KERNEL); if (0 != rc) { isbad++; - SAM("ERROR: usb_submit_urb() failed " \ + SAM("ERROR: usb_submit_urb() failed " "for urb with rc:\n"); switch (rc) { case -ENOMEM: { - SAM("ERROR: -ENOMEM=" \ + SAM("ERROR: -ENOMEM=" "usb_submit_urb()\n"); break; } case -ENODEV: { - SAM("ERROR: -ENODEV=" \ + SAM("ERROR: -ENODEV=" "usb_submit_urb()\n"); break; } case -ENXIO: { - SAM("ERROR: -ENXIO=" \ + SAM("ERROR: -ENXIO=" "usb_submit_urb()\n"); break; } case -EINVAL: { - SAM("ERROR: -EINVAL=" \ + SAM("ERROR: -EINVAL=" "usb_submit_urb()\n"); break; } case -EAGAIN: { - SAM("ERROR: -EAGAIN=" \ + SAM("ERROR: -EAGAIN=" "usb_submit_urb()\n"); break; } case -EFBIG: { - SAM("ERROR: -EFBIG=" \ + SAM("ERROR: -EFBIG=" "usb_submit_urb()\n"); break; } case -EPIPE: { - SAM("ERROR: -EPIPE=" \ + SAM("ERROR: -EPIPE=" "usb_submit_urb()\n"); break; } case -EMSGSIZE: { - SAM("ERROR: -EMSGSIZE=" \ + SAM("ERROR: -EMSGSIZE=" "usb_submit_urb()\n"); break; } @@ -699,8 +699,8 @@ if (!peasycap->video_isoc_streaming) { break; } default: { - SAM("ERROR: %i=" \ - "usb_submit_urb()\n",\ + SAM("ERROR: %i=" + "usb_submit_urb()\n", rc); break; } @@ -724,7 +724,7 @@ if (!peasycap->video_isoc_streaming) { if (isbad) { JOM(4, "attempting cleanup instead of submitting\n"); list_for_each(plist_head, (peasycap->purb_video_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, \ + pdata_urb = list_entry(plist_head, struct data_urb, list_head); if (NULL != pdata_urb) { purb = pdata_urb->purb; @@ -760,7 +760,7 @@ if (peasycap->video_isoc_streaming) { JOM(4, "killing video urbs\n"); m = 0; list_for_each(plist_head, (peasycap->purb_video_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, \ + pdata_urb = list_entry(plist_head, struct data_urb, list_head); if (NULL != pdata_urb) { if (NULL != pdata_urb->purb) { @@ -775,7 +775,7 @@ if (peasycap->video_isoc_streaming) { return -EFAULT; } } else { - JOM(8, "%i=video_isoc_streaming, no video urbs killed\n", \ + JOM(8, "%i=video_isoc_streaming, no video urbs killed\n", peasycap->video_isoc_streaming); } return 0; @@ -914,7 +914,7 @@ if ((struct list_head *)NULL != peasycap->purb_video_head) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); if ((struct data_urb *)NULL != pdata_urb) { kfree(pdata_urb); pdata_urb = (struct data_urb *)NULL; - peasycap->allocation_video_struct -= \ + peasycap->allocation_video_struct -= sizeof(struct data_urb); m++; } @@ -928,11 +928,11 @@ JOM(4, "freeing video isoc buffers.\n"); m = 0; for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { if ((void *)NULL != peasycap->video_isoc_buffer[k].pgo) { - free_pages((unsigned long)\ - (peasycap->video_isoc_buffer[k].pgo), \ + free_pages((unsigned long) + (peasycap->video_isoc_buffer[k].pgo), VIDEO_ISOC_ORDER); peasycap->video_isoc_buffer[k].pgo = (void *)NULL; - peasycap->allocation_video_page -= \ + peasycap->allocation_video_page -= ((unsigned int)(0x01 << VIDEO_ISOC_ORDER)); m++; } @@ -944,7 +944,7 @@ gone = 0; for (k = 0; k < FIELD_BUFFER_MANY; k++) { for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { if ((void *)NULL != peasycap->field_buffer[k][m].pgo) { - free_page((unsigned long)\ + free_page((unsigned long) (peasycap->field_buffer[k][m].pgo)); peasycap->field_buffer[k][m].pgo = (void *)NULL; peasycap->allocation_video_page -= 1; @@ -959,7 +959,7 @@ gone = 0; for (k = 0; k < FRAME_BUFFER_MANY; k++) { for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { if ((void *)NULL != peasycap->frame_buffer[k][m].pgo) { - free_page((unsigned long)\ + free_page((unsigned long) (peasycap->frame_buffer[k][m].pgo)); peasycap->frame_buffer[k][m].pgo = (void *)NULL; peasycap->allocation_video_page -= 1; @@ -997,7 +997,7 @@ if ((struct list_head *)NULL != peasycap->purb_audio_head) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); if ((struct data_urb *)NULL != pdata_urb) { kfree(pdata_urb); pdata_urb = (struct data_urb *)NULL; - peasycap->allocation_audio_struct -= \ + peasycap->allocation_audio_struct -= sizeof(struct data_urb); m++; } @@ -1011,16 +1011,16 @@ JOM(4, "freeing audio isoc buffers.\n"); m = 0; for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { if ((void *)NULL != peasycap->audio_isoc_buffer[k].pgo) { - free_pages((unsigned long)\ - (peasycap->audio_isoc_buffer[k].pgo), \ + free_pages((unsigned long) + (peasycap->audio_isoc_buffer[k].pgo), AUDIO_ISOC_ORDER); peasycap->audio_isoc_buffer[k].pgo = (void *)NULL; - peasycap->allocation_audio_page -= \ + peasycap->allocation_audio_page -= ((unsigned int)(0x01 << AUDIO_ISOC_ORDER)); m++; } } -JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n", \ +JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n", m * (0x01 << AUDIO_ISOC_ORDER)); /*---------------------------------------------------------------------------*/ #if !defined(EASYCAP_NEEDS_ALSA) @@ -1133,7 +1133,7 @@ if (0 <= kd && DONGLE_MANY > kd) { return -ERESTARTSYS; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", \ + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; @@ -1220,30 +1220,30 @@ if (0 <= input && INPUT_MANY > input) { */ /*---------------------------------------------------------------------------*/ miss = 0; -while ((peasycap->field_read == peasycap->field_fill) || \ - (0 != (0xFF00 & peasycap->field_buffer\ - [peasycap->field_read][0].kount)) || \ - (ifield != (0x00FF & peasycap->field_buffer\ +while ((peasycap->field_read == peasycap->field_fill) || + (0 != (0xFF00 & peasycap->field_buffer + [peasycap->field_read][0].kount)) || + (ifield != (0x00FF & peasycap->field_buffer [peasycap->field_read][0].kount))) { if (mode) return -EAGAIN; - JOM(8, "first wait on wq_video, " \ - "%i=field_read %i=field_fill\n", \ + JOM(8, "first wait on wq_video, " + "%i=field_read %i=field_fill\n", peasycap->field_read, peasycap->field_fill); - if (0 != (wait_event_interruptible(peasycap->wq_video, \ - (peasycap->video_idle || peasycap->video_eof || \ - ((peasycap->field_read != peasycap->field_fill) && \ - (0 == (0xFF00 & peasycap->field_buffer\ - [peasycap->field_read][0].kount)) && \ - (ifield == (0x00FF & peasycap->field_buffer\ + if (0 != (wait_event_interruptible(peasycap->wq_video, + (peasycap->video_idle || peasycap->video_eof || + ((peasycap->field_read != peasycap->field_fill) && + (0 == (0xFF00 & peasycap->field_buffer + [peasycap->field_read][0].kount)) && + (ifield == (0x00FF & peasycap->field_buffer [peasycap->field_read][0].kount))))))) { SAM("aborted by signal\n"); return -EIO; } if (peasycap->video_idle) { - JOM(8, "%i=peasycap->video_idle ... returning -EAGAIN\n", \ + JOM(8, "%i=peasycap->video_idle ... returning -EAGAIN\n", peasycap->video_idle); return -EAGAIN; } @@ -1289,30 +1289,30 @@ if (ifield) else ifield = 1; miss = 0; -while ((peasycap->field_read == peasycap->field_fill) || \ - (0 != (0xFF00 & peasycap->field_buffer\ - [peasycap->field_read][0].kount)) || \ - (ifield != (0x00FF & peasycap->field_buffer\ +while ((peasycap->field_read == peasycap->field_fill) || + (0 != (0xFF00 & peasycap->field_buffer + [peasycap->field_read][0].kount)) || + (ifield != (0x00FF & peasycap->field_buffer [peasycap->field_read][0].kount))) { if (mode) return -EAGAIN; - JOM(8, "second wait on wq_video, " \ - "%i=field_read %i=field_fill\n", \ + JOM(8, "second wait on wq_video, " + "%i=field_read %i=field_fill\n", peasycap->field_read, peasycap->field_fill); - if (0 != (wait_event_interruptible(peasycap->wq_video, \ - (peasycap->video_idle || peasycap->video_eof || \ - ((peasycap->field_read != peasycap->field_fill) && \ - (0 == (0xFF00 & peasycap->field_buffer\ - [peasycap->field_read][0].kount)) && \ - (ifield == (0x00FF & peasycap->field_buffer\ - [peasycap->field_read][0].\ + if (0 != (wait_event_interruptible(peasycap->wq_video, + (peasycap->video_idle || peasycap->video_eof || + ((peasycap->field_read != peasycap->field_fill) && + (0 == (0xFF00 & peasycap->field_buffer + [peasycap->field_read][0].kount)) && + (ifield == (0x00FF & peasycap->field_buffer + [peasycap->field_read][0]. kount))))))) { SAM("aborted by signal\n"); return -EIO; } if (peasycap->video_idle) { - JOM(8, "%i=peasycap->video_idle ... returning -EAGAIN\n", \ + JOM(8, "%i=peasycap->video_idle ... returning -EAGAIN\n", peasycap->video_idle); return -EAGAIN; } @@ -1369,10 +1369,10 @@ if (peasycap->frame_buffer_many <= peasycap->frame_fill) peasycap->frame_fill = 0; if (0x01 & easycap_standard[peasycap->standard_offset].mask) { - peasycap->frame_buffer[peasycap->frame_read][0].kount = \ + peasycap->frame_buffer[peasycap->frame_read][0].kount = V4L2_FIELD_TOP; } else { - peasycap->frame_buffer[peasycap->frame_read][0].kount = \ + peasycap->frame_buffer[peasycap->frame_read][0].kount = V4L2_FIELD_BOTTOM; } @@ -1417,10 +1417,10 @@ if (NULL == peasycap) { badinput = false; input = 0x07 & peasycap->field_buffer[peasycap->field_read][0].input; -JOM(8, "===== parity %i, input 0x%02X, field buffer %i --> " \ - "frame buffer %i\n", \ - peasycap->field_buffer[peasycap->field_read][0].kount,\ - peasycap->field_buffer[peasycap->field_read][0].input,\ +JOM(8, "===== parity %i, input 0x%02X, field buffer %i --> " + "frame buffer %i\n", + peasycap->field_buffer[peasycap->field_read][0].kount, + peasycap->field_buffer[peasycap->field_read][0].input, peasycap->field_read, peasycap->frame_fill); JOM(8, "===== %i=bytesperpixel\n", peasycap->bytesperpixel); if (true == peasycap->offerfields) @@ -1432,7 +1432,7 @@ if (true == peasycap->offerfields) */ /*---------------------------------------------------------------------------*/ if (peasycap->field_read == peasycap->field_fill) { - SAM("ERROR: on entry, still filling field buffer %i\n", \ + SAM("ERROR: on entry, still filling field buffer %i\n", peasycap->field_read); return 0; } @@ -1450,8 +1450,8 @@ offerfields = peasycap->offerfields; bytesperpixel = peasycap->bytesperpixel; decimatepixel = peasycap->decimatepixel; -if ((2 != bytesperpixel) && \ - (3 != bytesperpixel) && \ +if ((2 != bytesperpixel) && + (3 != bytesperpixel) && (4 != bytesperpixel)) { SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel); return -EFAULT; @@ -1462,12 +1462,12 @@ else multiplier = 1; w2 = 2 * multiplier * (peasycap->width); -w3 = bytesperpixel * \ - multiplier * \ +w3 = bytesperpixel * + multiplier * (peasycap->width); -wz = multiplier * \ - (peasycap->height) * \ - multiplier * \ +wz = multiplier * + (peasycap->height) * + multiplier * (peasycap->width); kex = peasycap->field_read; mex = 0; @@ -1481,7 +1481,7 @@ else odd = false; if ((true == odd) && (false == decimatepixel)) { - JOM(8, " initial skipping %4i bytes p.%4i\n", \ + JOM(8, " initial skipping %4i bytes p.%4i\n", w3/multiplier, mad); pad += (w3 / multiplier); rad -= (w3 / multiplier); } @@ -1510,7 +1510,7 @@ while (cz < wz) { return -EFAULT; } - more = (bytesperpixel * \ + more = (bytesperpixel * much) / 2; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ if (1 < bytesperpixel) { @@ -1521,9 +1521,9 @@ while (cz < wz) { ** BREAKAGE. BEWARE. **/ rad2 = rad + bytesperpixel - 1; - much = ((((2 * \ + much = ((((2 * rad2)/bytesperpixel)/2) * 2); - rump = ((bytesperpixel * \ + rump = ((bytesperpixel * much) / 2) - rad; more = rad; } @@ -1531,17 +1531,17 @@ while (cz < wz) { margin = 0; if (much == rex) { mask |= 0x04; - if ((mex + 1) < FIELD_BUFFER_SIZE/ \ + if ((mex + 1) < FIELD_BUFFER_SIZE/ PAGE_SIZE) { - margin = *((__u8 *)(peasycap->\ - field_buffer\ + margin = *((__u8 *)(peasycap-> + field_buffer [kex][mex + 1].pgo)); } else mask |= 0x08; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ } else { - SAM("MISTAKE: %i=bytesperpixel\n", \ + SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel); return -EFAULT; } @@ -1549,14 +1549,14 @@ while (cz < wz) { if (rump) caches++; if (true == badinput) { - JOM(8, "ERROR: 0x%02X=->field_buffer" \ - "[%i][%i].input, " \ - "0x%02X=(0x08|->input)\n", \ - peasycap->field_buffer\ - [kex][mex].input, kex, mex, \ + JOM(8, "ERROR: 0x%02X=->field_buffer" + "[%i][%i].input, " + "0x%02X=(0x08|->input)\n", + peasycap->field_buffer + [kex][mex].input, kex, mex, (0x08|peasycap->input)); } - rc = redaub(peasycap, pad, pex, much, more, \ + rc = redaub(peasycap, pad, pex, much, more, mask, margin, isuy); if (0 > rc) { SAM("ERROR: redaub() failed\n"); @@ -1574,7 +1574,7 @@ while (cz < wz) { mex++; pex = peasycap->field_buffer[kex][mex].pgo; rex = PAGE_SIZE; - if (peasycap->field_buffer[kex][mex].input != \ + if (peasycap->field_buffer[kex][mex].input != (0x08|peasycap->input)) badinput = true; } @@ -1601,7 +1601,7 @@ while (cz < wz) { do { if (!rad) { mad++; - pad = peasycap->frame_buffer\ + pad = peasycap->frame_buffer [kad][mad].pgo; rad = PAGE_SIZE; } @@ -1634,7 +1634,7 @@ while (cz < wz) { return -EFAULT; } - more = (bytesperpixel * \ + more = (bytesperpixel * much) / 4; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ if (1 < bytesperpixel) { @@ -1645,9 +1645,9 @@ while (cz < wz) { ** BREAKAGE. BEWARE. **/ rad2 = rad + bytesperpixel - 1; - much = ((((2 * rad2)/bytesperpixel)/2)\ + much = ((((2 * rad2)/bytesperpixel)/2) * 4); - rump = ((bytesperpixel * \ + rump = ((bytesperpixel * much) / 4) - rad; more = rad; } @@ -1655,10 +1655,10 @@ while (cz < wz) { margin = 0; if (much == rex) { mask |= 0x04; - if ((mex + 1) < FIELD_BUFFER_SIZE/ \ + if ((mex + 1) < FIELD_BUFFER_SIZE/ PAGE_SIZE) { - margin = *((__u8 *)(peasycap->\ - field_buffer\ + margin = *((__u8 *)(peasycap-> + field_buffer [kex][mex + 1].pgo)); } else @@ -1666,7 +1666,7 @@ while (cz < wz) { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ } else { - SAM("MISTAKE: %i=bytesperpixel\n", \ + SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel); return -EFAULT; } @@ -1675,14 +1675,14 @@ while (cz < wz) { caches++; if (true == badinput) { - JOM(8, "ERROR: 0x%02X=->field_buffer" \ - "[%i][%i].input, " \ - "0x%02X=(0x08|->input)\n", \ - peasycap->field_buffer\ - [kex][mex].input, kex, mex, \ + JOM(8, "ERROR: 0x%02X=->field_buffer" + "[%i][%i].input, " + "0x%02X=(0x08|->input)\n", + peasycap->field_buffer + [kex][mex].input, kex, mex, (0x08|peasycap->input)); } - rc = redaub(peasycap, pad, pex, much, more, \ + rc = redaub(peasycap, pad, pex, much, more, mask, margin, isuy); if (0 > rc) { SAM("ERROR: redaub() failed\n"); @@ -1694,7 +1694,7 @@ while (cz < wz) { mex++; pex = peasycap->field_buffer[kex][mex].pgo; rex = PAGE_SIZE; - if (peasycap->field_buffer[kex][mex].input != \ + if (peasycap->field_buffer[kex][mex].input != (0x08|peasycap->input)) badinput = true; } @@ -1723,13 +1723,13 @@ while (cz < wz) { mex++; pex = peasycap->field_buffer[kex][mex].pgo; rex = PAGE_SIZE; - if (peasycap->field_buffer[kex][mex].input != \ + if (peasycap->field_buffer[kex][mex].input != (0x08|peasycap->input)) { - JOM(8, "ERROR: 0x%02X=->field_buffer"\ - "[%i][%i].input, " \ - "0x%02X=(0x08|->input)\n", \ - peasycap->field_buffer\ - [kex][mex].input, kex, mex, \ + JOM(8, "ERROR: 0x%02X=->field_buffer" + "[%i][%i].input, " + "0x%02X=(0x08|->input)\n", + peasycap->field_buffer + [kex][mex].input, kex, mex, (0x08|peasycap->input)); badinput = true; } @@ -1755,21 +1755,21 @@ if (cz != c2) c3 = (mad + 1)*PAGE_SIZE - rad; if (false == decimatepixel) { - if (bytesperpixel * \ - cz != c3) \ - SAM("ERROR: discrepancy %i in bytes written\n", \ - c3 - (bytesperpixel * \ + if (bytesperpixel * + cz != c3) + SAM("ERROR: discrepancy %i in bytes written\n", + c3 - (bytesperpixel * cz)); } else { if (false == odd) { - if (bytesperpixel * \ + if (bytesperpixel * cz != (4 * c3)) - SAM("ERROR: discrepancy %i in bytes written\n", \ - (2*c3)-(bytesperpixel * \ + SAM("ERROR: discrepancy %i in bytes written\n", + (2*c3)-(bytesperpixel * cz)); } else { if (0 != c3) - SAM("ERROR: discrepancy %i " \ + SAM("ERROR: discrepancy %i " "in bytes written\n", c3); } } @@ -1783,7 +1783,7 @@ if (true == odd) JOM(8, "+++++ field2frame(): frame buffer %i is full\n", kad); if (peasycap->field_read == peasycap->field_fill) - SAM("WARNING: on exit, filling field buffer %i\n", \ + SAM("WARNING: on exit, filling field buffer %i\n", peasycap->field_read); /*---------------------------------------------------------------------------*/ /* @@ -1792,9 +1792,9 @@ if (peasycap->field_read == peasycap->field_fill) /*---------------------------------------------------------------------------*/ do_gettimeofday(&timeval); if (peasycap->timeval6.tv_sec) { - below = ((long long int)(1000000)) * \ - ((long long int)(timeval.tv_sec - \ - peasycap->timeval6.tv_sec)) + \ + below = ((long long int)(1000000)) * + ((long long int)(timeval.tv_sec - + peasycap->timeval6.tv_sec)) + (long long int)(timeval.tv_usec - peasycap->timeval6.tv_usec); above = (long long int)1000000; @@ -1802,7 +1802,7 @@ if (peasycap->timeval6.tv_sec) { above = sdr.quotient; remainder = (__u32)sdr.remainder; - JOM(8, "video streaming at %3lli.%03i fields per second\n", above, \ + JOM(8, "video streaming at %3lli.%03i fields per second\n", above, (remainder/1000)); } peasycap->timeval6 = timeval; @@ -1857,7 +1857,7 @@ return sdr; */ /*---------------------------------------------------------------------------*/ int -redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, \ +redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, __u8 mask, __u8 margin, bool isuy) { static __s32 ay[256], bu[256], rv[256], gu[256], gv[256]; @@ -2037,13 +2037,13 @@ case 3: } s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? \ + r = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); s32 = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? \ + g = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? \ + b = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); if ((true == last) && rump) { @@ -2062,7 +2062,7 @@ case 3: break; } default: { - SAM("MISTAKE: %i=rump\n", \ + SAM("MISTAKE: %i=rump\n", bytesperpixel - rump); return -EFAULT; } @@ -2110,13 +2110,13 @@ case 3: } s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? \ + r = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); s32 = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? \ + g = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? \ + b = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); if ((true == last) && rump) { @@ -2135,7 +2135,7 @@ case 3: break; } default: { - SAM("MISTAKE: %i=rump\n", \ + SAM("MISTAKE: %i=rump\n", bytesperpixel - rump); return -EFAULT; } @@ -2185,14 +2185,14 @@ case 3: if (true == isuy) { s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? \ + r = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - \ + s32 = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? \ + g = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? \ + b = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); if ((true == last) && rump) { @@ -2211,8 +2211,8 @@ case 3: break; } default: { - SAM("MISTAKE: " \ - "%i=rump\n", \ + SAM("MISTAKE: " + "%i=rump\n", bytesperpixel - rump); return -EFAULT; } @@ -2261,14 +2261,14 @@ case 3: if (true == isuy) { s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? \ + r = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - \ + s32 = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? \ + g = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? \ + b = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); if ((true == last) && rump) { @@ -2287,8 +2287,8 @@ case 3: break; } default: { - SAM("MISTAKE: " \ - "%i=rump\n", \ + SAM("MISTAKE: " + "%i=rump\n", bytesperpixel - rump); return -EFAULT; } @@ -2342,13 +2342,13 @@ case 4: } s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? \ + r = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); s32 = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? \ + g = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? \ + b = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); if ((true == last) && rump) { @@ -2376,7 +2376,7 @@ case 4: break; } default: { - SAM("MISTAKE: %i=rump\n", \ + SAM("MISTAKE: %i=rump\n", bytesperpixel - rump); return -EFAULT; } @@ -2424,13 +2424,13 @@ case 4: } s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? \ + r = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); s32 = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? \ + g = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? \ + b = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); if ((true == last) && rump) { @@ -2458,7 +2458,7 @@ case 4: break; } default: { - SAM("MISTAKE: %i=rump\n", \ + SAM("MISTAKE: %i=rump\n", bytesperpixel - rump); return -EFAULT; } @@ -2510,14 +2510,14 @@ case 4: if (true == isuy) { s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? \ + r = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - \ + s32 = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? \ + g = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? \ + b = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); if ((true == last) && rump) { @@ -2545,9 +2545,9 @@ case 4: break; } default: { - SAM("MISTAKE: " \ - "%i=rump\n", \ - bytesperpixel - \ + SAM("MISTAKE: " + "%i=rump\n", + bytesperpixel - rump); return -EFAULT; } @@ -2595,14 +2595,14 @@ case 4: if (true == isuy) { s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? \ + r = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - \ + s32 = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? \ + g = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? \ + b = (255 < s32) ? 255 : ((0 > s32) ? 0 : (__u8)s32); if ((true == last) && rump) { @@ -2630,8 +2630,8 @@ case 4: break; } default: { - SAM("MISTAKE: " \ - "%i=rump\n", \ + SAM("MISTAKE: " + "%i=rump\n", bytesperpixel - rump); return -EFAULT; } @@ -2840,16 +2840,16 @@ for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) break; JOM(16, "%2i=urb\n", i); last = peasycap->video_isoc_sequence; -if ((((VIDEO_ISOC_BUFFER_MANY - 1) == last) && \ - (0 != i)) || \ - (((VIDEO_ISOC_BUFFER_MANY - 1) != last) && \ +if ((((VIDEO_ISOC_BUFFER_MANY - 1) == last) && + (0 != i)) || + (((VIDEO_ISOC_BUFFER_MANY - 1) != last) && ((last + 1) != i))) { JOM(16, "ERROR: out-of-order urbs %i,%i ... continuing\n", last, i); } peasycap->video_isoc_sequence = i; if (peasycap->video_idle) { - JOM(16, "%i=video_idle %i=video_isoc_streaming\n", \ + JOM(16, "%i=video_idle %i=video_isoc_streaming\n", peasycap->video_idle, peasycap->video_isoc_streaming); if (peasycap->video_isoc_streaming) { rc = usb_submit_urb(purb, GFP_ATOMIC); @@ -2896,10 +2896,10 @@ if (peasycap->video_idle) { break; } } - if (-ENODEV != rc) \ - SAM("ERROR: while %i=video_idle, " \ - "usb_submit_urb() " \ - "failed with rc:\n", \ + if (-ENODEV != rc) + SAM("ERROR: while %i=video_idle, " + "usb_submit_urb() " + "failed with rc:\n", peasycap->video_idle); } } @@ -2988,7 +2988,7 @@ if (purb->status) { } else { for (i = 0; i < purb->number_of_packets; i++) { if (0 != purb->iso_frame_desc[i].status) { - (peasycap->field_buffer\ + (peasycap->field_buffer [peasycap->field_fill][0].kount) |= 0x8000 ; switch (purb->iso_frame_desc[i].status) { case 0: { @@ -3055,24 +3055,24 @@ if (purb->status) { frameactual = purb->iso_frame_desc[i].actual_length; frameoffset = purb->iso_frame_desc[i].offset; - JOM(16, "frame[%2i]:" \ - "%4i=status " \ - "%4i=actual " \ - "%4i=length " \ - "%5i=offset\n", \ + JOM(16, "frame[%2i]:" + "%4i=status " + "%4i=actual " + "%4i=length " + "%5i=offset\n", i, framestatus, frameactual, framelength, frameoffset); if (!purb->iso_frame_desc[i].status) { more = purb->iso_frame_desc[i].actual_length; - pfield_buffer = &peasycap->field_buffer\ + pfield_buffer = &peasycap->field_buffer [peasycap->field_fill][peasycap->field_page]; - videofieldamount = (peasycap->field_page * \ - PAGE_SIZE) + \ + videofieldamount = (peasycap->field_page * + PAGE_SIZE) + (int)(pfield_buffer->pto - pfield_buffer->pgo); if (4 == more) peasycap->video_mt++; if (4 < more) { if (peasycap->video_mt) { - JOM(8, "%4i empty video urb frames\n", \ + JOM(8, "%4i empty video urb frames\n", peasycap->video_mt); peasycap->video_mt = 0; } @@ -3080,14 +3080,14 @@ if (purb->status) { SAM("ERROR: bad peasycap->field_fill\n"); return; } - if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \ + if (FIELD_BUFFER_SIZE/PAGE_SIZE <= peasycap->field_page) { SAM("ERROR: bad peasycap->field_page\n"); return; } - pfield_buffer = &peasycap->field_buffer\ + pfield_buffer = &peasycap->field_buffer [peasycap->field_fill][peasycap->field_page]; - pu = (__u8 *)(purb->transfer_buffer + \ + pu = (__u8 *)(purb->transfer_buffer + purb->iso_frame_desc[i].offset); if (0x80 & *pu) leap = 8; @@ -3111,124 +3111,124 @@ if (purb->status) { */ /*---------------------------------------------------------------------------*/ if ((8 == more) || override) { - if (videofieldamount > \ + if (videofieldamount > peasycap->videofieldamount) { - if (2 == videofieldamount - \ - peasycap->\ + if (2 == videofieldamount - + peasycap-> videofieldamount) { - (peasycap->field_buffer\ - [peasycap->field_fill]\ + (peasycap->field_buffer + [peasycap->field_fill] [0].kount) |= 0x0100; - peasycap->video_junk += (1 + \ + peasycap->video_junk += (1 + VIDEO_JUNK_TOLERATE); } else - (peasycap->field_buffer\ - [peasycap->field_fill]\ + (peasycap->field_buffer + [peasycap->field_fill] [0].kount) |= 0x4000; - } else if (videofieldamount < \ - peasycap->\ + } else if (videofieldamount < + peasycap-> videofieldamount) { - (peasycap->field_buffer\ - [peasycap->field_fill]\ + (peasycap->field_buffer + [peasycap->field_fill] [0].kount) |= 0x2000; } - bad = 0xFF00 & peasycap->field_buffer\ - [peasycap->field_fill]\ + bad = 0xFF00 & peasycap->field_buffer + [peasycap->field_fill] [0].kount; if (!bad) { (peasycap->video_junk)--; - if (-VIDEO_JUNK_TOLERATE > \ - peasycap->video_junk) \ - peasycap->video_junk =\ + if (-VIDEO_JUNK_TOLERATE > + peasycap->video_junk) + peasycap->video_junk = -VIDEO_JUNK_TOLERATE; - peasycap->field_read = \ - (peasycap->\ + peasycap->field_read = + (peasycap-> field_fill)++; - if (FIELD_BUFFER_MANY <= \ - peasycap->\ + if (FIELD_BUFFER_MANY <= + peasycap-> field_fill) - peasycap->\ + peasycap-> field_fill = 0; peasycap->field_page = 0; - pfield_buffer = &peasycap->\ - field_buffer\ - [peasycap->\ - field_fill]\ - [peasycap->\ + pfield_buffer = &peasycap-> + field_buffer + [peasycap-> + field_fill] + [peasycap-> field_page]; - pfield_buffer->pto = \ + pfield_buffer->pto = pfield_buffer->pgo; - JOM(8, "bumped to: %i="\ - "peasycap->" \ - "field_fill %i="\ - "parity\n", \ - peasycap->field_fill, \ - 0x00FF & \ + JOM(8, "bumped to: %i=" + "peasycap->" + "field_fill %i=" + "parity\n", + peasycap->field_fill, + 0x00FF & pfield_buffer->kount); - JOM(8, "field buffer %i has "\ - "%i bytes fit to be "\ - "read\n", \ - peasycap->field_read, \ + JOM(8, "field buffer %i has " + "%i bytes fit to be " + "read\n", + peasycap->field_read, videofieldamount); - JOM(8, "wakeup call to "\ - "wq_video, " \ - "%i=field_read "\ - "%i=field_fill "\ - "%i=parity\n", \ - peasycap->field_read, \ - peasycap->field_fill, \ - 0x00FF & peasycap->\ - field_buffer\ - [peasycap->\ + JOM(8, "wakeup call to " + "wq_video, " + "%i=field_read " + "%i=field_fill " + "%i=parity\n", + peasycap->field_read, + peasycap->field_fill, + 0x00FF & peasycap-> + field_buffer + [peasycap-> field_read][0].kount); - wake_up_interruptible\ - (&(peasycap->\ + wake_up_interruptible + (&(peasycap-> wq_video)); - do_gettimeofday\ + do_gettimeofday (&peasycap->timeval7); } else { peasycap->video_junk++; - if (bad & 0x0010) \ - peasycap->video_junk += \ + if (bad & 0x0010) + peasycap->video_junk += (1 + VIDEO_JUNK_TOLERATE/2); - JOM(8, "field buffer %i had %i " \ - "bytes, now discarded: "\ - "0x%04X\n", \ - peasycap->field_fill, \ - videofieldamount,\ - (0xFF00 & \ - peasycap->field_buffer\ - [peasycap->field_fill][0].\ + JOM(8, "field buffer %i had %i " + "bytes, now discarded: " + "0x%04X\n", + peasycap->field_fill, + videofieldamount, + (0xFF00 & + peasycap->field_buffer + [peasycap->field_fill][0]. kount)); (peasycap->field_fill)++; - if (FIELD_BUFFER_MANY <= \ + if (FIELD_BUFFER_MANY <= peasycap->field_fill) peasycap->field_fill = 0; peasycap->field_page = 0; - pfield_buffer = \ - &peasycap->field_buffer\ - [peasycap->field_fill]\ + pfield_buffer = + &peasycap->field_buffer + [peasycap->field_fill] [peasycap->field_page]; - pfield_buffer->pto = \ + pfield_buffer->pto = pfield_buffer->pgo; - JOM(8, "bumped to: %i=peasycap->" \ - "field_fill %i=parity\n", \ - peasycap->field_fill, \ + JOM(8, "bumped to: %i=peasycap->" + "field_fill %i=parity\n", + peasycap->field_fill, 0x00FF & pfield_buffer->kount); } if (8 == more) { - JOM(8, "end-of-field: received " \ - "parity byte 0x%02X\n", \ + JOM(8, "end-of-field: received " + "parity byte 0x%02X\n", (0xFF & *pu)); if (0x40 & *pu) pfield_buffer->kount = 0x0000; else pfield_buffer->kount = 0x0001; - pfield_buffer->input = 0x08 | \ + pfield_buffer->input = 0x08 | (0x07 & peasycap->input); - JOM(8, "end-of-field: 0x%02X=kount\n",\ + JOM(8, "end-of-field: 0x%02X=kount\n", 0xFF & pfield_buffer->kount); } } @@ -3244,49 +3244,49 @@ if (purb->status) { SAM("ERROR: bad peasycap->field_fill\n"); return; } - if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \ + if (FIELD_BUFFER_SIZE/PAGE_SIZE <= peasycap->field_page) { SAM("ERROR: bad peasycap->field_page\n"); return; } - pfield_buffer = &peasycap->field_buffer\ + pfield_buffer = &peasycap->field_buffer [peasycap->field_fill][peasycap->field_page]; while (more) { - pfield_buffer = &peasycap->field_buffer\ - [peasycap->field_fill]\ + pfield_buffer = &peasycap->field_buffer + [peasycap->field_fill] [peasycap->field_page]; - if (PAGE_SIZE < (pfield_buffer->pto - \ + if (PAGE_SIZE < (pfield_buffer->pto - pfield_buffer->pgo)) { SAM("ERROR: bad pfield_buffer->pto\n"); return; } - if (PAGE_SIZE == (pfield_buffer->pto - \ + if (PAGE_SIZE == (pfield_buffer->pto - pfield_buffer->pgo)) { (peasycap->field_page)++; - if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \ + if (FIELD_BUFFER_SIZE/PAGE_SIZE <= peasycap->field_page) { - JOM(16, "wrapping peasycap->" \ + JOM(16, "wrapping peasycap->" "field_page\n"); peasycap->field_page = 0; } - pfield_buffer = &peasycap->\ - field_buffer\ - [peasycap->field_fill]\ + pfield_buffer = &peasycap-> + field_buffer + [peasycap->field_fill] [peasycap->field_page]; - pfield_buffer->pto = \ + pfield_buffer->pto = pfield_buffer->pgo; - pfield_buffer->input = 0x08 | \ + pfield_buffer->input = 0x08 | (0x07 & peasycap->input); - if ((peasycap->field_buffer[peasycap->\ - field_fill][0]).\ - input != \ + if ((peasycap->field_buffer[peasycap-> + field_fill][0]). + input != pfield_buffer->input) - (peasycap->field_buffer\ - [peasycap->field_fill]\ + (peasycap->field_buffer + [peasycap->field_fill] [0]).kount |= 0x1000; } - much = PAGE_SIZE - (int)(pfield_buffer->pto - \ + much = PAGE_SIZE - (int)(pfield_buffer->pto - pfield_buffer->pgo); if (much > more) @@ -3355,10 +3355,10 @@ if (peasycap->video_isoc_streaming) { SAM("0x%08X\n", rc); break; } } - if (-ENODEV != rc) \ - SAM("ERROR: while %i=video_idle, " \ - "usb_submit_urb() " \ - "failed with rc:\n", \ + if (-ENODEV != rc) + SAM("ERROR: while %i=video_idle, " + "usb_submit_urb() " + "failed with rc:\n", peasycap->video_idle); } } @@ -3372,7 +3372,7 @@ return; */ /*---------------------------------------------------------------------------*/ int -easycap_usb_probe(struct usb_interface *pusb_interface, \ +easycap_usb_probe(struct usb_interface *pusb_interface, const struct usb_device_id *pusb_device_id) { struct usb_device *pusb_device, *pusb_device1; @@ -3424,7 +3424,7 @@ peasycap = (struct easycap *)NULL; * GET POINTER TO STRUCTURE usb_device */ /*---------------------------------------------------------------------------*/ -pusb_device1 = container_of(pusb_interface->dev.parent, \ +pusb_device1 = container_of(pusb_interface->dev.parent, struct usb_device, dev); if ((struct usb_device *)NULL == pusb_device1) { SAY("ERROR: pusb_device1 is NULL\n"); @@ -3460,23 +3460,23 @@ bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber; bInterfaceClass = pusb_interface_descriptor->bInterfaceClass; bInterfaceSubClass = pusb_interface_descriptor->bInterfaceSubClass; -JOT(4, "intf[%i]: pusb_interface->num_altsetting=%i\n", \ +JOT(4, "intf[%i]: pusb_interface->num_altsetting=%i\n", bInterfaceNumber, pusb_interface->num_altsetting); -JOT(4, "intf[%i]: pusb_interface->cur_altsetting - " \ - "pusb_interface->altsetting=%li\n", bInterfaceNumber, \ - (long int)(pusb_interface->cur_altsetting - \ +JOT(4, "intf[%i]: pusb_interface->cur_altsetting - " + "pusb_interface->altsetting=%li\n", bInterfaceNumber, + (long int)(pusb_interface->cur_altsetting - pusb_interface->altsetting)); switch (bInterfaceClass) { case USB_CLASS_AUDIO: { - JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_AUDIO\n", \ + JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_AUDIO\n", bInterfaceNumber, bInterfaceClass); break; } case USB_CLASS_VIDEO: { - JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VIDEO\n", \ + JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VIDEO\n", bInterfaceNumber, bInterfaceClass); break; } case USB_CLASS_VENDOR_SPEC: { - JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VENDOR_SPEC\n", \ + JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VENDOR_SPEC\n", bInterfaceNumber, bInterfaceClass); break; } default: @@ -3484,15 +3484,15 @@ default: } switch (bInterfaceSubClass) { case 0x01: { - JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOCONTROL\n", \ + JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOCONTROL\n", bInterfaceNumber, bInterfaceSubClass); break; } case 0x02: { - JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOSTREAMING\n", \ + JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOSTREAMING\n", bInterfaceNumber, bInterfaceSubClass); break; } case 0x03: { - JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=MIDISTREAMING\n", \ + JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=MIDISTREAMING\n", bInterfaceNumber, bInterfaceSubClass); break; } default: @@ -3501,12 +3501,12 @@ default: /*---------------------------------------------------------------------------*/ pusb_interface_assoc_descriptor = pusb_interface->intf_assoc; if (NULL != pusb_interface_assoc_descriptor) { - JOT(4, "intf[%i]: bFirstInterface=0x%02X bInterfaceCount=0x%02X\n", \ - bInterfaceNumber, \ - pusb_interface_assoc_descriptor->bFirstInterface, \ + JOT(4, "intf[%i]: bFirstInterface=0x%02X bInterfaceCount=0x%02X\n", + bInterfaceNumber, + pusb_interface_assoc_descriptor->bFirstInterface, pusb_interface_assoc_descriptor->bInterfaceCount); } else { -JOT(4, "intf[%i]: pusb_interface_assoc_descriptor is NULL\n", \ +JOT(4, "intf[%i]: pusb_interface_assoc_descriptor is NULL\n", bInterfaceNumber); } /*---------------------------------------------------------------------------*/ @@ -3529,10 +3529,10 @@ if (0 == bInterfaceNumber) { SAM("allocated 0x%08lX=peasycap\n", (unsigned long int) peasycap); /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #if defined(EASYCAP_IS_VIDEODEV_CLIENT) - SAM("where 0x%08lX=&peasycap->video_device\n", \ + SAM("where 0x%08lX=&peasycap->video_device\n", (unsigned long int) &peasycap->video_device); #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) - SAM("and 0x%08lX=&peasycap->v4l2_device\n", \ + SAM("and 0x%08lX=&peasycap->v4l2_device\n", (unsigned long int) &peasycap->v4l2_device); #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ @@ -3545,8 +3545,8 @@ if (0 == bInterfaceNumber) { peasycap->minor = -1; strcpy(&peasycap->telltale[0], TELLTALE); kref_init(&peasycap->kref); - JOM(8, "intf[%i]: after kref_init(..._video) " \ - "%i=peasycap->kref.refcount.counter\n", \ + JOM(8, "intf[%i]: after kref_init(..._video) " + "%i=peasycap->kref.refcount.counter\n", bInterfaceNumber, peasycap->kref.refcount.counter); /* module params */ @@ -3571,15 +3571,15 @@ if (0 == bInterfaceNumber) { */ /*---------------------------------------------------------------------------*/ for (ndong = 0; ndong < DONGLE_MANY; ndong++) { - if ((NULL == easycapdc60_dongle[ndong].peasycap) && \ - (!mutex_is_locked(&easycapdc60_dongle\ - [ndong].mutex_video)) && \ - (!mutex_is_locked(&easycapdc60_dongle\ + if ((NULL == easycapdc60_dongle[ndong].peasycap) && + (!mutex_is_locked(&easycapdc60_dongle + [ndong].mutex_video)) && + (!mutex_is_locked(&easycapdc60_dongle [ndong].mutex_audio))) { easycapdc60_dongle[ndong].peasycap = peasycap; peasycap->isdongle = ndong; - JOM(8, "intf[%i]: peasycap-->easycap" \ - "_dongle[%i].peasycap\n", \ + JOM(8, "intf[%i]: peasycap-->easycap" + "_dongle[%i].peasycap\n", bInterfaceNumber, ndong); break; } @@ -3660,11 +3660,11 @@ if (0 == bInterfaceNumber) { m = 0; mask = 0; while (0xFFFF != easycap_standard[i].mask) { - if (NTSC_M == easycap_standard[i].\ + if (NTSC_M == easycap_standard[i]. v4l2_standard.index) { m++; for (k = 0; k < INPUT_MANY; k++) { - peasycap->inputset[k].\ + peasycap->inputset[k]. standard_offset = i; } mask = easycap_standard[i].mask; @@ -3676,11 +3676,11 @@ if (0 == bInterfaceNumber) { m = 0; mask = 0; while (0xFFFF != easycap_standard[i].mask) { - if (PAL_BGHIN == easycap_standard[i].\ + if (PAL_BGHIN == easycap_standard[i]. v4l2_standard.index) { m++; for (k = 0; k < INPUT_MANY; k++) { - peasycap->inputset[k].\ + peasycap->inputset[k]. standard_offset = i; } mask = easycap_standard[i].mask; @@ -3690,7 +3690,7 @@ if (0 == bInterfaceNumber) { } if (1 != m) { - SAM("MISTAKE: easycap.inputset[].standard_offset " \ + SAM("MISTAKE: easycap.inputset[].standard_offset " "unpopulated, %i=m\n", m); return -ENOENT; } @@ -3699,17 +3699,17 @@ if (0 == bInterfaceNumber) { i = 0; m = 0; while (0 != peasycap_format->v4l2_format.fmt.pix.width) { - if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && \ - (peasycap_format->\ - v4l2_format.fmt.pix.field == \ - V4L2_FIELD_NONE) && \ - (peasycap_format->\ - v4l2_format.fmt.pix.pixelformat == \ - V4L2_PIX_FMT_UYVY) && \ - (peasycap_format->\ - v4l2_format.fmt.pix.width == \ - 640) && \ - (peasycap_format->\ + if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && + (peasycap_format-> + v4l2_format.fmt.pix.field == + V4L2_FIELD_NONE) && + (peasycap_format-> + v4l2_format.fmt.pix.pixelformat == + V4L2_PIX_FMT_UYVY) && + (peasycap_format-> + v4l2_format.fmt.pix.width == + 640) && + (peasycap_format-> v4l2_format.fmt.pix.height == 480)) { m++; for (k = 0; k < INPUT_MANY; k++) @@ -3748,7 +3748,7 @@ if (0 == bInterfaceNumber) { i++; } if (4 != m) { - SAM("MISTAKE: easycap.inputset[].brightness,... " \ + SAM("MISTAKE: easycap.inputset[].brightness,... " "underpopulated\n"); return -ENOENT; } @@ -3766,21 +3766,21 @@ if (0 == bInterfaceNumber) { */ /*---------------------------------------------------------------------------*/ for (ndong = 0; ndong < DONGLE_MANY; ndong++) { - if (pusb_device == easycapdc60_dongle[ndong].peasycap->\ + if (pusb_device == easycapdc60_dongle[ndong].peasycap-> pusb_device) { peasycap = easycapdc60_dongle[ndong].peasycap; - JOT(8, "intf[%i]: easycapdc60_dongle[%i].peasycap-->" \ + JOT(8, "intf[%i]: easycapdc60_dongle[%i].peasycap-->" "peasycap\n", bInterfaceNumber, ndong); break; } } if (DONGLE_MANY <= ndong) { - SAY("ERROR: peasycap is unknown when probing interface %i\n", \ + SAY("ERROR: peasycap is unknown when probing interface %i\n", bInterfaceNumber); return -ENODEV; } if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL when probing interface %i\n", \ + SAY("ERROR: peasycap is NULL when probing interface %i\n", bInterfaceNumber); return -ENODEV; } @@ -3803,40 +3803,40 @@ if (0 == bInterfaceNumber) { SAY("ERROR: pv4l2_device is NULL\n"); return -ENODEV; } - peasycap = (struct easycap *) \ + peasycap = (struct easycap *) container_of(pv4l2_device, struct easycap, v4l2_device); } #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ } /*---------------------------------------------------------------------------*/ -if ((USB_CLASS_VIDEO == bInterfaceClass) || \ +if ((USB_CLASS_VIDEO == bInterfaceClass) || (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) { if (-1 == peasycap->video_interface) { peasycap->video_interface = bInterfaceNumber; - JOM(4, "setting peasycap->video_interface=%i\n", \ + JOM(4, "setting peasycap->video_interface=%i\n", peasycap->video_interface); } else { if (peasycap->video_interface != bInterfaceNumber) { - SAM("ERROR: attempting to reset " \ + SAM("ERROR: attempting to reset " "peasycap->video_interface\n"); - SAM("...... continuing with " \ - "%i=peasycap->video_interface\n", \ + SAM("...... continuing with " + "%i=peasycap->video_interface\n", peasycap->video_interface); } } -} else if ((USB_CLASS_AUDIO == bInterfaceClass) && \ +} else if ((USB_CLASS_AUDIO == bInterfaceClass) && (0x02 == bInterfaceSubClass)) { if (-1 == peasycap->audio_interface) { peasycap->audio_interface = bInterfaceNumber; - JOM(4, "setting peasycap->audio_interface=%i\n", \ + JOM(4, "setting peasycap->audio_interface=%i\n", peasycap->audio_interface); } else { if (peasycap->audio_interface != bInterfaceNumber) { - SAM("ERROR: attempting to reset " \ + SAM("ERROR: attempting to reset " "peasycap->audio_interface\n"); - SAM("...... continuing with " \ - "%i=peasycap->audio_interface\n", \ + SAM("...... continuing with " + "%i=peasycap->audio_interface\n", peasycap->audio_interface); } } @@ -3856,27 +3856,27 @@ for (i = 0; i < pusb_interface->num_altsetting; i++) { return -EFAULT; } pusb_interface_descriptor = &(pusb_host_interface->desc); - if ((struct usb_interface_descriptor *)NULL == \ + if ((struct usb_interface_descriptor *)NULL == pusb_interface_descriptor) { SAM("ERROR: pusb_interface_descriptor is NULL\n"); return -EFAULT; } - JOM(4, "intf[%i]alt[%i]: desc.bDescriptorType=0x%02X\n", \ + JOM(4, "intf[%i]alt[%i]: desc.bDescriptorType=0x%02X\n", bInterfaceNumber, i, pusb_interface_descriptor->bDescriptorType); - JOM(4, "intf[%i]alt[%i]: desc.bInterfaceNumber=0x%02X\n", \ + JOM(4, "intf[%i]alt[%i]: desc.bInterfaceNumber=0x%02X\n", bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceNumber); - JOM(4, "intf[%i]alt[%i]: desc.bAlternateSetting=0x%02X\n", \ + JOM(4, "intf[%i]alt[%i]: desc.bAlternateSetting=0x%02X\n", bInterfaceNumber, i, pusb_interface_descriptor->bAlternateSetting); - JOM(4, "intf[%i]alt[%i]: desc.bNumEndpoints=0x%02X\n", \ + JOM(4, "intf[%i]alt[%i]: desc.bNumEndpoints=0x%02X\n", bInterfaceNumber, i, pusb_interface_descriptor->bNumEndpoints); - JOM(4, "intf[%i]alt[%i]: desc.bInterfaceClass=0x%02X\n", \ + JOM(4, "intf[%i]alt[%i]: desc.bInterfaceClass=0x%02X\n", bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceClass); - JOM(4, "intf[%i]alt[%i]: desc.bInterfaceSubClass=0x%02X\n", \ + JOM(4, "intf[%i]alt[%i]: desc.bInterfaceSubClass=0x%02X\n", bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceSubClass); - JOM(4, "intf[%i]alt[%i]: desc.bInterfaceProtocol=0x%02X\n", \ + JOM(4, "intf[%i]alt[%i]: desc.bInterfaceProtocol=0x%02X\n", bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceProtocol); - JOM(4, "intf[%i]alt[%i]: desc.iInterface=0x%02X\n", \ + JOM(4, "intf[%i]alt[%i]: desc.iInterface=0x%02X\n", bInterfaceNumber, i, pusb_interface_descriptor->iInterface); ISOCwMaxPacketSize = -1; @@ -3887,7 +3887,7 @@ for (i = 0; i < pusb_interface->num_altsetting; i++) { INTbEndpointAddress = 0; if (0 == pusb_interface_descriptor->bNumEndpoints) - JOM(4, "intf[%i]alt[%i] has no endpoints\n", \ + JOM(4, "intf[%i]alt[%i] has no endpoints\n", bInterfaceNumber, i); /*---------------------------------------------------------------------------*/ for (j = 0; j < pusb_interface_descriptor->bNumEndpoints; j++) { @@ -3900,88 +3900,88 @@ for (i = 0; i < pusb_interface->num_altsetting; i++) { wMaxPacketSize = le16_to_cpu(pepd->wMaxPacketSize); bEndpointAddress = pepd->bEndpointAddress; - JOM(4, "intf[%i]alt[%i]end[%i]: bEndpointAddress=0x%X\n", \ - bInterfaceNumber, i, j, \ + JOM(4, "intf[%i]alt[%i]end[%i]: bEndpointAddress=0x%X\n", + bInterfaceNumber, i, j, pepd->bEndpointAddress); - JOM(4, "intf[%i]alt[%i]end[%i]: bmAttributes=0x%X\n", \ - bInterfaceNumber, i, j, \ + JOM(4, "intf[%i]alt[%i]end[%i]: bmAttributes=0x%X\n", + bInterfaceNumber, i, j, pepd->bmAttributes); - JOM(4, "intf[%i]alt[%i]end[%i]: wMaxPacketSize=%i\n", \ - bInterfaceNumber, i, j, \ + JOM(4, "intf[%i]alt[%i]end[%i]: wMaxPacketSize=%i\n", + bInterfaceNumber, i, j, pepd->wMaxPacketSize); JOM(4, "intf[%i]alt[%i]end[%i]: bInterval=%i\n", - bInterfaceNumber, i, j, \ + bInterfaceNumber, i, j, pepd->bInterval); if (pepd->bEndpointAddress & USB_DIR_IN) { - JOM(4, "intf[%i]alt[%i]end[%i] is an IN endpoint\n",\ + JOM(4, "intf[%i]alt[%i]end[%i] is an IN endpoint\n", bInterfaceNumber, i, j); isin = 1; } else { - JOM(4, "intf[%i]alt[%i]end[%i] is an OUT endpoint\n",\ + JOM(4, "intf[%i]alt[%i]end[%i] is an OUT endpoint\n", bInterfaceNumber, i, j); SAM("ERROR: OUT endpoint unexpected\n"); SAM("...... continuing\n"); isin = 0; } - if ((pepd->bmAttributes & \ - USB_ENDPOINT_XFERTYPE_MASK) == \ + if ((pepd->bmAttributes & + USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC) { - JOM(4, "intf[%i]alt[%i]end[%i] is an ISOC endpoint\n",\ + JOM(4, "intf[%i]alt[%i]end[%i] is an ISOC endpoint\n", bInterfaceNumber, i, j); if (isin) { switch (bInterfaceClass) { case USB_CLASS_VIDEO: case USB_CLASS_VENDOR_SPEC: { if (!peasycap) { - SAM("MISTAKE: " \ + SAM("MISTAKE: " "peasycap is NULL\n"); return -EFAULT; } if (pepd->wMaxPacketSize) { if (8 > isokalt) { okalt[isokalt] = i; - JOM(4,\ - "%i=okalt[%i]\n", \ - okalt[isokalt], \ + JOM(4, + "%i=okalt[%i]\n", + okalt[isokalt], isokalt); - okepn[isokalt] = \ - pepd->\ - bEndpointAddress & \ + okepn[isokalt] = + pepd-> + bEndpointAddress & 0x0F; - JOM(4,\ - "%i=okepn[%i]\n", \ - okepn[isokalt], \ + JOM(4, + "%i=okepn[%i]\n", + okepn[isokalt], isokalt); - okmps[isokalt] = \ - le16_to_cpu(pepd->\ + okmps[isokalt] = + le16_to_cpu(pepd-> wMaxPacketSize); - JOM(4,\ - "%i=okmps[%i]\n", \ - okmps[isokalt], \ + JOM(4, + "%i=okmps[%i]\n", + okmps[isokalt], isokalt); isokalt++; } } else { - if (-1 == peasycap->\ + if (-1 == peasycap-> video_altsetting_off) { - peasycap->\ - video_altsetting_off =\ + peasycap-> + video_altsetting_off = i; - JOM(4, "%i=video_" \ - "altsetting_off " \ - "<====\n", \ - peasycap->\ + JOM(4, "%i=video_" + "altsetting_off " + "<====\n", + peasycap-> video_altsetting_off); } else { - SAM("ERROR: peasycap" \ - "->video_altsetting_" \ + SAM("ERROR: peasycap" + "->video_altsetting_" "off already set\n"); - SAM("...... " \ - "continuing with " \ - "%i=peasycap->video_" \ - "altsetting_off\n", \ - peasycap->\ + SAM("...... " + "continuing with " + "%i=peasycap->video_" + "altsetting_off\n", + peasycap-> video_altsetting_off); } } @@ -3991,55 +3991,55 @@ for (i = 0; i < pusb_interface->num_altsetting; i++) { if (0x02 != bInterfaceSubClass) break; if (!peasycap) { - SAM("MISTAKE: " \ + SAM("MISTAKE: " "peasycap is NULL\n"); return -EFAULT; } if (pepd->wMaxPacketSize) { if (8 > isokalt) { okalt[isokalt] = i ; - JOM(4,\ - "%i=okalt[%i]\n", \ - okalt[isokalt], \ + JOM(4, + "%i=okalt[%i]\n", + okalt[isokalt], isokalt); - okepn[isokalt] = \ - pepd->\ - bEndpointAddress & \ + okepn[isokalt] = + pepd-> + bEndpointAddress & 0x0F; - JOM(4,\ - "%i=okepn[%i]\n", \ - okepn[isokalt], \ + JOM(4, + "%i=okepn[%i]\n", + okepn[isokalt], isokalt); - okmps[isokalt] = \ - le16_to_cpu(pepd->\ + okmps[isokalt] = + le16_to_cpu(pepd-> wMaxPacketSize); - JOM(4,\ - "%i=okmps[%i]\n",\ - okmps[isokalt], \ + JOM(4, + "%i=okmps[%i]\n", + okmps[isokalt], isokalt); isokalt++; } } else { - if (-1 == peasycap->\ + if (-1 == peasycap-> audio_altsetting_off) { - peasycap->\ - audio_altsetting_off =\ + peasycap-> + audio_altsetting_off = i; - JOM(4, "%i=audio_" \ - "altsetting_off " \ - "<====\n", \ - peasycap->\ + JOM(4, "%i=audio_" + "altsetting_off " + "<====\n", + peasycap-> audio_altsetting_off); } else { - SAM("ERROR: peasycap" \ - "->audio_altsetting_" \ + SAM("ERROR: peasycap" + "->audio_altsetting_" "off already set\n"); - SAM("...... " \ - "continuing with " \ - "%i=peasycap->\ - audio_altsetting_" \ + SAM("...... " + "continuing with " + "%i=peasycap->" + "audio_altsetting_" "off\n", - peasycap->\ + peasycap-> audio_altsetting_off); } } @@ -4049,23 +4049,23 @@ for (i = 0; i < pusb_interface->num_altsetting; i++) { break; } } - } else if ((pepd->bmAttributes & \ - USB_ENDPOINT_XFERTYPE_MASK) ==\ + } else if ((pepd->bmAttributes & + USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) { - JOM(4, "intf[%i]alt[%i]end[%i] is a BULK endpoint\n",\ + JOM(4, "intf[%i]alt[%i]end[%i] is a BULK endpoint\n", bInterfaceNumber, i, j); - } else if ((pepd->bmAttributes & \ - USB_ENDPOINT_XFERTYPE_MASK) ==\ + } else if ((pepd->bmAttributes & + USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) { - JOM(4, "intf[%i]alt[%i]end[%i] is an INT endpoint\n",\ + JOM(4, "intf[%i]alt[%i]end[%i] is an INT endpoint\n", bInterfaceNumber, i, j); } else { - JOM(4, "intf[%i]alt[%i]end[%i] is a CTRL endpoint\n",\ + JOM(4, "intf[%i]alt[%i]end[%i] is a CTRL endpoint\n", bInterfaceNumber, i, j); } if (0 == pepd->wMaxPacketSize) { - JOM(4, "intf[%i]alt[%i]end[%i] " \ - "has zero packet size\n", \ + JOM(4, "intf[%i]alt[%i]end[%i] " + "has zero packet size\n", bInterfaceNumber, i, j); } } @@ -4075,7 +4075,7 @@ for (i = 0; i < pusb_interface->num_altsetting; i++) { * PERFORM INITIALIZATION OF THE PROBED INTERFACE */ /*---------------------------------------------------------------------------*/ -JOM(4, "initialization begins for interface %i\n", \ +JOM(4, "initialization begins for interface %i\n", pusb_interface_descriptor->bInterfaceNumber); switch (bInterfaceNumber) { /*---------------------------------------------------------------------------*/ @@ -4093,7 +4093,7 @@ case 0: { return -ENOENT; } else { peasycap->video_altsetting_on = okalt[isokalt - 1]; - JOM(4, "%i=video_altsetting_on <====\n", \ + JOM(4, "%i=video_altsetting_on <====\n", peasycap->video_altsetting_on); } /*---------------------------------------------------------------------------*/ @@ -4107,10 +4107,10 @@ case 0: { if (USB_2_0_MAXPACKETSIZE > maxpacketsize) { peasycap->video_isoc_maxframesize = maxpacketsize; } else { - peasycap->video_isoc_maxframesize = \ + peasycap->video_isoc_maxframesize = USB_2_0_MAXPACKETSIZE; } - JOM(4, "%i=video_isoc_maxframesize\n", \ + JOM(4, "%i=video_isoc_maxframesize\n", peasycap->video_isoc_maxframesize); if (0 >= peasycap->video_isoc_maxframesize) { SAM("ERROR: bad video_isoc_maxframesize\n"); @@ -4118,18 +4118,18 @@ case 0: { return -ENOENT; } peasycap->video_isoc_framesperdesc = VIDEO_ISOC_FRAMESPERDESC; - JOM(4, "%i=video_isoc_framesperdesc\n", \ + JOM(4, "%i=video_isoc_framesperdesc\n", peasycap->video_isoc_framesperdesc); if (0 >= peasycap->video_isoc_framesperdesc) { SAM("ERROR: bad video_isoc_framesperdesc\n"); return -ENOENT; } - peasycap->video_isoc_buffer_size = \ - peasycap->video_isoc_maxframesize * \ + peasycap->video_isoc_buffer_size = + peasycap->video_isoc_maxframesize * peasycap->video_isoc_framesperdesc; - JOM(4, "%i=video_isoc_buffer_size\n", \ + JOM(4, "%i=video_isoc_buffer_size\n", peasycap->video_isoc_buffer_size); - if ((PAGE_SIZE << VIDEO_ISOC_ORDER) < \ + if ((PAGE_SIZE << VIDEO_ISOC_ORDER) < peasycap->video_isoc_buffer_size) { SAM("MISTAKE: peasycap->video_isoc_buffer_size too big\n"); return -EFAULT; @@ -4167,50 +4167,50 @@ case 0: { INIT_LIST_HEAD(&(peasycap->urb_video_head)); peasycap->purb_video_head = &(peasycap->urb_video_head); /*---------------------------------------------------------------------------*/ - JOM(4, "allocating %i frame buffers of size %li\n", \ + JOM(4, "allocating %i frame buffers of size %li\n", FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE); - JOM(4, ".... each scattered over %li pages\n", \ + JOM(4, ".... each scattered over %li pages\n", FRAME_BUFFER_SIZE/PAGE_SIZE); for (k = 0; k < FRAME_BUFFER_MANY; k++) { for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { if ((void *)NULL != peasycap->frame_buffer[k][m].pgo) - SAM("attempting to reallocate frame " \ + SAM("attempting to reallocate frame " " buffers\n"); else { pbuf = (void *)__get_free_page(GFP_KERNEL); if ((void *)NULL == pbuf) { - SAM("ERROR: Could not allocate frame "\ + SAM("ERROR: Could not allocate frame " "buffer %i page %i\n", k, m); return -ENOMEM; } else peasycap->allocation_video_page += 1; peasycap->frame_buffer[k][m].pgo = pbuf; } - peasycap->frame_buffer[k][m].pto = \ + peasycap->frame_buffer[k][m].pto = peasycap->frame_buffer[k][m].pgo; } } peasycap->frame_fill = 0; peasycap->frame_read = 0; - JOM(4, "allocation of frame buffers done: %i pages\n", k * \ + JOM(4, "allocation of frame buffers done: %i pages\n", k * m); /*---------------------------------------------------------------------------*/ - JOM(4, "allocating %i field buffers of size %li\n", \ + JOM(4, "allocating %i field buffers of size %li\n", FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE); - JOM(4, ".... each scattered over %li pages\n", \ + JOM(4, ".... each scattered over %li pages\n", FIELD_BUFFER_SIZE/PAGE_SIZE); for (k = 0; k < FIELD_BUFFER_MANY; k++) { for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { if ((void *)NULL != peasycap->field_buffer[k][m].pgo) { - SAM("ERROR: attempting to reallocate " \ + SAM("ERROR: attempting to reallocate " "field buffers\n"); } else { pbuf = (void *) __get_free_page(GFP_KERNEL); if ((void *)NULL == pbuf) { - SAM("ERROR: Could not allocate field" \ + SAM("ERROR: Could not allocate field" " buffer %i page %i\n", k, m); return -ENOMEM; } @@ -4218,7 +4218,7 @@ case 0: { peasycap->allocation_video_page += 1; peasycap->field_buffer[k][m].pgo = pbuf; } - peasycap->field_buffer[k][m].pto = \ + peasycap->field_buffer[k][m].pto = peasycap->field_buffer[k][m].pgo; } peasycap->field_buffer[k][0].kount = 0x0200; @@ -4226,30 +4226,30 @@ case 0: { peasycap->field_fill = 0; peasycap->field_page = 0; peasycap->field_read = 0; - JOM(4, "allocation of field buffers done: %i pages\n", k * \ + JOM(4, "allocation of field buffers done: %i pages\n", k * m); /*---------------------------------------------------------------------------*/ - JOM(4, "allocating %i isoc video buffers of size %i\n", \ - VIDEO_ISOC_BUFFER_MANY, \ + JOM(4, "allocating %i isoc video buffers of size %i\n", + VIDEO_ISOC_BUFFER_MANY, peasycap->video_isoc_buffer_size); JOM(4, ".... each occupying contiguous memory pages\n"); for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { pbuf = (void *)__get_free_pages(GFP_KERNEL, VIDEO_ISOC_ORDER); if (NULL == pbuf) { - SAM("ERROR: Could not allocate isoc video buffer " \ + SAM("ERROR: Could not allocate isoc video buffer " "%i\n", k); return -ENOMEM; } else - peasycap->allocation_video_page += \ + peasycap->allocation_video_page += ((unsigned int)(0x01 << VIDEO_ISOC_ORDER)); peasycap->video_isoc_buffer[k].pgo = pbuf; - peasycap->video_isoc_buffer[k].pto = pbuf + \ + peasycap->video_isoc_buffer[k].pto = pbuf + peasycap->video_isoc_buffer_size; peasycap->video_isoc_buffer[k].kount = k; } - JOM(4, "allocation of isoc video buffers done: %i pages\n", \ + JOM(4, "allocation of isoc video buffers done: %i pages\n", k * (0x01 << VIDEO_ISOC_ORDER)); /*---------------------------------------------------------------------------*/ /* @@ -4257,18 +4257,18 @@ case 0: { */ /*---------------------------------------------------------------------------*/ JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY); - JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n", \ + JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n", peasycap->video_isoc_framesperdesc); - JOM(4, "using %i=peasycap->video_isoc_maxframesize\n", \ + JOM(4, "using %i=peasycap->video_isoc_maxframesize\n", peasycap->video_isoc_maxframesize); - JOM(4, "using %i=peasycap->video_isoc_buffer_sizen", \ + JOM(4, "using %i=peasycap->video_isoc_buffer_sizen", peasycap->video_isoc_buffer_size); for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { - purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc, \ + purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc, GFP_KERNEL); if (NULL == purb) { - SAM("ERROR: usb_alloc_urb returned NULL for buffer " \ + SAM("ERROR: usb_alloc_urb returned NULL for buffer " "%i\n", k); return -ENOMEM; } else @@ -4279,13 +4279,13 @@ case 0: { SAM("ERROR: Could not allocate struct data_urb.\n"); return -ENOMEM; } else - peasycap->allocation_video_struct += \ + peasycap->allocation_video_struct += sizeof(struct data_urb); pdata_urb->purb = purb; pdata_urb->isbuf = k; pdata_urb->length = 0; - list_add_tail(&(pdata_urb->list_head), \ + list_add_tail(&(pdata_urb->list_head), peasycap->purb_video_head); /*---------------------------------------------------------------------------*/ /* @@ -4296,45 +4296,45 @@ case 0: { JOM(4, "initializing video urbs thus:\n"); JOM(4, " purb->interval = 1;\n"); JOM(4, " purb->dev = peasycap->pusb_device;\n"); - JOM(4, " purb->pipe = usb_rcvisocpipe" \ - "(peasycap->pusb_device,%i);\n", \ + JOM(4, " purb->pipe = usb_rcvisocpipe" + "(peasycap->pusb_device,%i);\n", peasycap->video_endpointnumber); JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n"); - JOM(4, " purb->transfer_buffer = peasycap->" \ + JOM(4, " purb->transfer_buffer = peasycap->" "video_isoc_buffer[.].pgo;\n"); - JOM(4, " purb->transfer_buffer_length = %i;\n", \ + JOM(4, " purb->transfer_buffer_length = %i;\n", peasycap->video_isoc_buffer_size); JOM(4, " purb->complete = easycap_complete;\n"); JOM(4, " purb->context = peasycap;\n"); JOM(4, " purb->start_frame = 0;\n"); - JOM(4, " purb->number_of_packets = %i;\n", \ + JOM(4, " purb->number_of_packets = %i;\n", peasycap->video_isoc_framesperdesc); - JOM(4, " for (j = 0; j < %i; j++)\n", \ + JOM(4, " for (j = 0; j < %i; j++)\n", peasycap->video_isoc_framesperdesc); JOM(4, " {\n"); - JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",\ + JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n", peasycap->video_isoc_maxframesize); - JOM(4, " purb->iso_frame_desc[j].length = %i;\n", \ + JOM(4, " purb->iso_frame_desc[j].length = %i;\n", peasycap->video_isoc_maxframesize); JOM(4, " }\n"); } purb->interval = 1; purb->dev = peasycap->pusb_device; - purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, \ + purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, peasycap->video_endpointnumber); purb->transfer_flags = URB_ISO_ASAP; purb->transfer_buffer = peasycap->video_isoc_buffer[k].pgo; - purb->transfer_buffer_length = \ + purb->transfer_buffer_length = peasycap->video_isoc_buffer_size; purb->complete = easycap_complete; purb->context = peasycap; purb->start_frame = 0; purb->number_of_packets = peasycap->video_isoc_framesperdesc; for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) { - purb->iso_frame_desc[j].offset = j * \ + purb->iso_frame_desc[j].offset = j * peasycap->video_isoc_maxframesize; - purb->iso_frame_desc[j].length = \ + purb->iso_frame_desc[j].length = peasycap->video_isoc_maxframesize; } } @@ -4384,12 +4384,12 @@ case 0: { /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #else #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) - if (0 != (v4l2_device_register(&(pusb_interface->dev), \ + if (0 != (v4l2_device_register(&(pusb_interface->dev), &(peasycap->v4l2_device)))) { SAM("v4l2_device_register() failed\n"); return -ENODEV; } else { - JOM(4, "registered device instance: %s\n", \ + JOM(4, "registered device instance: %s\n", &(peasycap->v4l2_device.name[0])); } /*---------------------------------------------------------------------------*/ @@ -4416,14 +4416,14 @@ case 0: { video_set_drvdata(&(peasycap->video_device), (void *)peasycap); - if (0 != (video_register_device(&(peasycap->video_device), \ + if (0 != (video_register_device(&(peasycap->video_device), VFL_TYPE_GRABBER, -1))) { err("Not able to register with videodev"); videodev_release(&(peasycap->video_device)); return -ENODEV; } else { (peasycap->registered_video)++; - SAM("registered with videodev: %i=minor\n", \ + SAM("registered with videodev: %i=minor\n", peasycap->video_device.minor); peasycap->minor = peasycap->video_device.minor; } @@ -4452,7 +4452,7 @@ case 1: { */ /*--------------------------------------------------------------------------*/ usb_set_intfdata(pusb_interface, peasycap); - JOM(4, "no initialization required for interface %i\n", \ + JOM(4, "no initialization required for interface %i\n", pusb_interface_descriptor->bInterfaceNumber); break; } @@ -4470,7 +4470,7 @@ case 2: { return -ENOENT; } else { peasycap->audio_altsetting_on = okalt[isokalt - 1]; - JOM(4, "%i=audio_altsetting_on <====\n", \ + JOM(4, "%i=audio_altsetting_on <====\n", peasycap->audio_altsetting_on); } @@ -4478,7 +4478,7 @@ case 2: { JOM(4, "%i=audio_endpointnumber\n", peasycap->audio_endpointnumber); peasycap->audio_isoc_maxframesize = okmps[isokalt - 1]; - JOM(4, "%i=audio_isoc_maxframesize\n", \ + JOM(4, "%i=audio_isoc_maxframesize\n", peasycap->audio_isoc_maxframesize); if (0 >= peasycap->audio_isoc_maxframesize) { SAM("ERROR: bad audio_isoc_maxframesize\n"); @@ -4496,42 +4496,42 @@ case 2: { peasycap->audio_pages_per_fragment = PAGES_PER_AUDIO_FRAGMENT; } else { SAM("hardware is unidentified:\n"); - SAM("%i=audio_isoc_maxframesize\n", \ + SAM("%i=audio_isoc_maxframesize\n", peasycap->audio_isoc_maxframesize); return -ENOENT; } - peasycap->audio_bytes_per_fragment = \ - peasycap->audio_pages_per_fragment * \ + peasycap->audio_bytes_per_fragment = + peasycap->audio_pages_per_fragment * PAGE_SIZE ; - peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY * \ + peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY * peasycap->audio_pages_per_fragment); JOM(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY); - JOM(4, "%6i=audio_pages_per_fragment\n", \ + JOM(4, "%6i=audio_pages_per_fragment\n", peasycap->audio_pages_per_fragment); - JOM(4, "%6i=audio_bytes_per_fragment\n", \ + JOM(4, "%6i=audio_bytes_per_fragment\n", peasycap->audio_bytes_per_fragment); - JOM(4, "%6i=audio_buffer_page_many\n", \ + JOM(4, "%6i=audio_buffer_page_many\n", peasycap->audio_buffer_page_many); peasycap->audio_isoc_framesperdesc = AUDIO_ISOC_FRAMESPERDESC; - JOM(4, "%i=audio_isoc_framesperdesc\n", \ + JOM(4, "%i=audio_isoc_framesperdesc\n", peasycap->audio_isoc_framesperdesc); if (0 >= peasycap->audio_isoc_framesperdesc) { SAM("ERROR: bad audio_isoc_framesperdesc\n"); return -ENOENT; } - peasycap->audio_isoc_buffer_size = \ - peasycap->audio_isoc_maxframesize * \ + peasycap->audio_isoc_buffer_size = + peasycap->audio_isoc_maxframesize * peasycap->audio_isoc_framesperdesc; - JOM(4, "%i=audio_isoc_buffer_size\n", \ + JOM(4, "%i=audio_isoc_buffer_size\n", peasycap->audio_isoc_buffer_size); if (AUDIO_ISOC_BUFFER_SIZE < peasycap->audio_isoc_buffer_size) { SAM("MISTAKE: audio_isoc_buffer_size bigger " - "than %li=AUDIO_ISOC_BUFFER_SIZE\n", \ + "than %li=AUDIO_ISOC_BUFFER_SIZE\n", AUDIO_ISOC_BUFFER_SIZE); return -EFAULT; } @@ -4569,7 +4569,7 @@ case 2: { #if !defined(EASYCAP_NEEDS_ALSA) JOM(4, "allocating an audio buffer\n"); - JOM(4, ".... scattered over %i pages\n", \ + JOM(4, ".... scattered over %i pages\n", peasycap->audio_buffer_page_many); for (k = 0; k < peasycap->audio_buffer_page_many; k++) { @@ -4578,7 +4578,7 @@ case 2: { } else { pbuf = (void *) __get_free_page(GFP_KERNEL); if ((void *)NULL == pbuf) { - SAM("ERROR: Could not allocate audio " \ + SAM("ERROR: Could not allocate audio " "buffer page %i\n", k); return -ENOMEM; } else @@ -4594,22 +4594,22 @@ case 2: { JOM(4, "allocation of audio buffer done: %i pages\n", k); #endif /*!EASYCAP_NEEDS_ALSA*/ /*---------------------------------------------------------------------------*/ - JOM(4, "allocating %i isoc audio buffers of size %i\n", \ + JOM(4, "allocating %i isoc audio buffers of size %i\n", AUDIO_ISOC_BUFFER_MANY, peasycap->audio_isoc_buffer_size); JOM(4, ".... each occupying contiguous memory pages\n"); for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { pbuf = (void *)__get_free_pages(GFP_KERNEL, AUDIO_ISOC_ORDER); if (NULL == pbuf) { - SAM("ERROR: Could not allocate isoc audio buffer " \ + SAM("ERROR: Could not allocate isoc audio buffer " "%i\n", k); return -ENOMEM; } else - peasycap->allocation_audio_page += \ + peasycap->allocation_audio_page += ((unsigned int)(0x01 << AUDIO_ISOC_ORDER)); peasycap->audio_isoc_buffer[k].pgo = pbuf; - peasycap->audio_isoc_buffer[k].pto = pbuf + \ + peasycap->audio_isoc_buffer[k].pto = pbuf + peasycap->audio_isoc_buffer_size; peasycap->audio_isoc_buffer[k].kount = k; } @@ -4620,18 +4620,18 @@ case 2: { */ /*---------------------------------------------------------------------------*/ JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY); - JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n", \ + JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n", peasycap->audio_isoc_framesperdesc); - JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n", \ + JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n", peasycap->audio_isoc_maxframesize); - JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n", \ + JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n", peasycap->audio_isoc_buffer_size); for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { - purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc, \ + purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc, GFP_KERNEL); if (NULL == purb) { - SAM("ERROR: usb_alloc_urb returned NULL for buffer " \ + SAM("ERROR: usb_alloc_urb returned NULL for buffer " "%i\n", k); return -ENOMEM; } else @@ -4642,13 +4642,13 @@ case 2: { SAM("ERROR: Could not allocate struct data_urb.\n"); return -ENOMEM; } else - peasycap->allocation_audio_struct += \ + peasycap->allocation_audio_struct += sizeof(struct data_urb); pdata_urb->purb = purb; pdata_urb->isbuf = k; pdata_urb->length = 0; - list_add_tail(&(pdata_urb->list_head), \ + list_add_tail(&(pdata_urb->list_head), peasycap->purb_audio_head); /*---------------------------------------------------------------------------*/ /* @@ -4659,13 +4659,13 @@ case 2: { JOM(4, "initializing audio urbs thus:\n"); JOM(4, " purb->interval = 1;\n"); JOM(4, " purb->dev = peasycap->pusb_device;\n"); - JOM(4, " purb->pipe = usb_rcvisocpipe(peasycap->" \ - "pusb_device,%i);\n", \ + JOM(4, " purb->pipe = usb_rcvisocpipe(peasycap->" + "pusb_device,%i);\n", peasycap->audio_endpointnumber); JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n"); - JOM(4, " purb->transfer_buffer = " \ + JOM(4, " purb->transfer_buffer = " "peasycap->audio_isoc_buffer[.].pgo;\n"); - JOM(4, " purb->transfer_buffer_length = %i;\n", \ + JOM(4, " purb->transfer_buffer_length = %i;\n", peasycap->audio_isoc_buffer_size); #if defined(EASYCAP_NEEDS_ALSA) JOM(4, " purb->complete = easycap_alsa_complete;\n"); @@ -4674,25 +4674,25 @@ case 2: { #endif /*EASYCAP_NEEDS_ALSA*/ JOM(4, " purb->context = peasycap;\n"); JOM(4, " purb->start_frame = 0;\n"); - JOM(4, " purb->number_of_packets = %i;\n", \ + JOM(4, " purb->number_of_packets = %i;\n", peasycap->audio_isoc_framesperdesc); - JOM(4, " for (j = 0; j < %i; j++)\n", \ + JOM(4, " for (j = 0; j < %i; j++)\n", peasycap->audio_isoc_framesperdesc); JOM(4, " {\n"); - JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",\ + JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n", peasycap->audio_isoc_maxframesize); - JOM(4, " purb->iso_frame_desc[j].length = %i;\n", \ + JOM(4, " purb->iso_frame_desc[j].length = %i;\n", peasycap->audio_isoc_maxframesize); JOM(4, " }\n"); } purb->interval = 1; purb->dev = peasycap->pusb_device; - purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, \ + purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, peasycap->audio_endpointnumber); purb->transfer_flags = URB_ISO_ASAP; purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo; - purb->transfer_buffer_length = \ + purb->transfer_buffer_length = peasycap->audio_isoc_buffer_size; #if defined(EASYCAP_NEEDS_ALSA) purb->complete = easycap_alsa_complete; @@ -4703,9 +4703,9 @@ case 2: { purb->start_frame = 0; purb->number_of_packets = peasycap->audio_isoc_framesperdesc; for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) { - purb->iso_frame_desc[j].offset = j * \ + purb->iso_frame_desc[j].offset = j * peasycap->audio_isoc_maxframesize; - purb->iso_frame_desc[j].length = \ + purb->iso_frame_desc[j].length = peasycap->audio_isoc_maxframesize; } } @@ -4729,7 +4729,7 @@ case 2: { err("easycap_alsa_probe() returned %i\n", rc); return -ENODEV; } else { - JOM(8, "kref_get() with %i=peasycap->kref.refcount.counter\n",\ + JOM(8, "kref_get() with %i=peasycap->kref.refcount.counter\n", (int)peasycap->kref.refcount.counter); kref_get(&peasycap->kref); (peasycap->registered_audio)++; @@ -4742,7 +4742,7 @@ case 2: { usb_set_intfdata(pusb_interface, NULL); return -ENODEV; } else { - JOM(8, "kref_get() with %i=peasycap->kref.refcount.counter\n",\ + JOM(8, "kref_get() with %i=peasycap->kref.refcount.counter\n", (int)peasycap->kref.refcount.counter); kref_get(&peasycap->kref); (peasycap->registered_audio)++; @@ -4767,7 +4767,7 @@ default: { return -EINVAL; } } -SAM("ends successfully for interface %i\n", \ +SAM("ends successfully for interface %i\n", pusb_interface_descriptor->bInterfaceNumber); return 0; } @@ -4847,7 +4847,7 @@ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { SAY("ERROR: pv4l2_device is NULL\n"); return; } - peasycap = (struct easycap *) \ + peasycap = (struct easycap *) container_of(pv4l2_device, struct easycap, v4l2_device); } #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ @@ -4876,10 +4876,10 @@ case 0: { m = 0; list_for_each(plist_head, (peasycap->purb_video_head)) { - pdata_urb = list_entry(plist_head, \ + pdata_urb = list_entry(plist_head, struct data_urb, list_head); if ((struct data_urb *)NULL != pdata_urb) { - if ((struct urb *)NULL != \ + if ((struct urb *)NULL != pdata_urb->purb) { usb_kill_urb(pdata_urb->purb); m++; @@ -4895,12 +4895,12 @@ case 2: { if ((struct list_head *)NULL != peasycap->purb_audio_head) { JOM(4, "killing audio urbs\n"); m = 0; - list_for_each(plist_head, \ + list_for_each(plist_head, (peasycap->purb_audio_head)) { - pdata_urb = list_entry(plist_head, \ + pdata_urb = list_entry(plist_head, struct data_urb, list_head); if ((struct data_urb *)NULL != pdata_urb) { - if ((struct urb *)NULL != \ + if ((struct urb *)NULL != pdata_urb->purb) { usb_kill_urb(pdata_urb->purb); m++; @@ -4929,11 +4929,11 @@ switch (bInterfaceNumber) { case 0: { if (0 <= kd && DONGLE_MANY > kd) { wake_up_interruptible(&peasycap->wq_video); - JOM(4, "about to lock easycapdc60_dongle[%i].mutex_video\n", \ + JOM(4, "about to lock easycapdc60_dongle[%i].mutex_video\n", kd); - if (mutex_lock_interruptible(&easycapdc60_dongle[kd].\ + if (mutex_lock_interruptible(&easycapdc60_dongle[kd]. mutex_video)) { - SAY("ERROR: cannot lock easycapdc60_dongle[%i]." \ + SAY("ERROR: cannot lock easycapdc60_dongle[%i]." "mutex_video\n", kd); return; } @@ -4981,11 +4981,11 @@ case 0: { case 2: { if (0 <= kd && DONGLE_MANY > kd) { wake_up_interruptible(&peasycap->wq_audio); - JOM(4, "about to lock easycapdc60_dongle[%i].mutex_audio\n", \ + JOM(4, "about to lock easycapdc60_dongle[%i].mutex_audio\n", kd); - if (mutex_lock_interruptible(&easycapdc60_dongle[kd].\ + if (mutex_lock_interruptible(&easycapdc60_dongle[kd]. mutex_audio)) { - SAY("ERROR: cannot lock easycapdc60_dongle[%i]." \ + SAY("ERROR: cannot lock easycapdc60_dongle[%i]." "mutex_audio\n", kd); return; } @@ -5052,7 +5052,7 @@ if (0 <= kd && DONGLE_MANY > kd) { } JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd); } -JOM(4, "intf[%i]: %i=peasycap->kref.refcount.counter\n", \ +JOM(4, "intf[%i]: %i=peasycap->kref.refcount.counter\n", bInterfaceNumber, (int)peasycap->kref.refcount.counter); kref_put(&peasycap->kref, easycap_delete); JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber); @@ -5073,7 +5073,7 @@ easycap_module_init(void) int k, rc; SAY("========easycap=======\n"); -JOT(4, "begins. %i=debug %i=bars %i=gain\n", easycap_debug, easycap_bars, \ +JOT(4, "begins. %i=debug %i=bars %i=gain\n", easycap_debug, easycap_bars, easycap_gain); SAY("version: " EASYCAP_DRIVER_VERSION "\n"); @@ -5123,7 +5123,7 @@ MODULE_VERSION(EASYCAP_DRIVER_VERSION); #if defined(EASYCAP_DEBUG) MODULE_PARM_DESC(debug, "Debug level: 0(default),1,2,...,9"); #endif /*EASYCAP_DEBUG*/ -MODULE_PARM_DESC(bars, \ +MODULE_PARM_DESC(bars, "Testcard bars on input signal failure: 0=>no, 1=>yes(default)"); MODULE_PARM_DESC(gain, "Audio gain: 0,...,16(default),...31"); /*****************************************************************************/ diff --git a/drivers/staging/easycap/easycap_settings.c b/drivers/staging/easycap/easycap_settings.c index 0a23e2749514..7b2dd6eeb41f 100644 --- a/drivers/staging/easycap/easycap_settings.c +++ b/drivers/staging/easycap/easycap_settings.c @@ -44,7 +44,7 @@ const struct easycap_standard easycap_standard[] = { .mask = 0x00FF & PAL_BGHIN , .v4l2_standard = { .index = PAL_BGHIN, - .id = (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | \ + .id = (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | V4L2_STD_PAL_I | V4L2_STD_PAL_N), .name = "PAL_BGHIN", .frameperiod = {1, 25}, @@ -165,8 +165,8 @@ const struct easycap_standard easycap_standard[] = { .mask = 0x8000 | (0x00FF & PAL_BGHIN_SLOW), .v4l2_standard = { .index = PAL_BGHIN_SLOW, - .id = (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | \ - V4L2_STD_PAL_I | V4L2_STD_PAL_N | \ + .id = (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | + V4L2_STD_PAL_I | V4L2_STD_PAL_N | (((v4l2_std_id)0x01) << 32)), .name = "PAL_BGHIN_SLOW", .frameperiod = {1, 5}, @@ -573,25 +573,25 @@ for (i = 0, n = 0; i < STANDARD_MANY; i++) { strcat(&easycap_format[n].name[0], &name2[0]); strcat(&easycap_format[n].name[0], &name3[0]); strcat(&easycap_format[n].name[0], &name4[0]); - easycap_format[n].mask = \ + easycap_format[n].mask = mask1 | mask2 | mask3 | mask4; - easycap_format[n].v4l2_format\ + easycap_format[n].v4l2_format .type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - easycap_format[n].v4l2_format\ + easycap_format[n].v4l2_format .fmt.pix.width = width; - easycap_format[n].v4l2_format\ + easycap_format[n].v4l2_format .fmt.pix.height = height; - easycap_format[n].v4l2_format\ + easycap_format[n].v4l2_format .fmt.pix.pixelformat = pixelformat; - easycap_format[n].v4l2_format\ + easycap_format[n].v4l2_format .fmt.pix.field = field; - easycap_format[n].v4l2_format\ + easycap_format[n].v4l2_format .fmt.pix.bytesperline = bytesperline; - easycap_format[n].v4l2_format\ + easycap_format[n].v4l2_format .fmt.pix.sizeimage = sizeimage; - easycap_format[n].v4l2_format\ + easycap_format[n].v4l2_format .fmt.pix.colorspace = colorspace; - easycap_format[n].v4l2_format\ + easycap_format[n].v4l2_format .fmt.pix.priv = 0; n++; } @@ -604,7 +604,7 @@ easycap_format[n].mask = 0xFFFF; return n; } /*---------------------------------------------------------------------------*/ -struct v4l2_queryctrl easycap_control[] = \ +struct v4l2_queryctrl easycap_control[] = {{ .id = V4L2_CID_BRIGHTNESS, .type = V4L2_CTRL_TYPE_INTEGER, diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index 0507ea19004a..8d1c0620344d 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -48,7 +48,7 @@ static const struct snd_pcm_hardware alsa_hardware = { .rate_max = 48000, .channels_min = 2, .channels_max = 2, - .buffer_bytes_max = PAGE_SIZE * PAGES_PER_AUDIO_FRAGMENT * \ + .buffer_bytes_max = PAGE_SIZE * PAGES_PER_AUDIO_FRAGMENT * AUDIO_FRAGMENT_MANY, .period_bytes_min = PAGE_SIZE * PAGES_PER_AUDIO_FRAGMENT, .period_bytes_max = PAGE_SIZE * PAGES_PER_AUDIO_FRAGMENT * 2, @@ -108,14 +108,14 @@ if (true == peasycap->microphone) { } #if defined(EASYCAP_NEEDS_CARD_CREATE) - if (0 != snd_card_create(SNDRV_DEFAULT_IDX1, "easycap_alsa", \ - THIS_MODULE, 0, \ + if (0 != snd_card_create(SNDRV_DEFAULT_IDX1, "easycap_alsa", + THIS_MODULE, 0, &psnd_card)) { SAY("ERROR: Cannot do ALSA snd_card_create()\n"); return -EFAULT; } #else - psnd_card = snd_card_new(SNDRV_DEFAULT_IDX1, "easycap_alsa", \ + psnd_card = snd_card_new(SNDRV_DEFAULT_IDX1, "easycap_alsa", THIS_MODULE, 0); if (NULL == psnd_card) { SAY("ERROR: Cannot do ALSA snd_card_new()\n"); @@ -139,7 +139,7 @@ if (true == peasycap->microphone) { return -EFAULT; } - snd_pcm_set_ops(psnd_pcm, SNDRV_PCM_STREAM_CAPTURE, \ + snd_pcm_set_ops(psnd_pcm, SNDRV_PCM_STREAM_CAPTURE, &easycap_alsa_pcm_ops); psnd_pcm->info_flags = 0; strcpy(&psnd_pcm->name[0], &psnd_card->id[0]); @@ -199,7 +199,7 @@ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { } much = 0; if (peasycap->audio_idle) { - JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n", \ + JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n", peasycap->audio_idle, peasycap->audio_isoc_streaming); if (peasycap->audio_isoc_streaming) goto resubmit; @@ -410,12 +410,12 @@ for (i = 0; i < purb->number_of_packets; i++) { peasycap->audio_mt++; else { if (peasycap->audio_mt) { - JOM(12, "%4i empty audio urb frames\n", \ + JOM(12, "%4i empty audio urb frames\n", peasycap->audio_mt); peasycap->audio_mt = 0; } - p1 = (__u8 *)(purb->transfer_buffer + \ + p1 = (__u8 *)(purb->transfer_buffer + purb->iso_frame_desc[i].offset); /*---------------------------------------------------------------------------*/ @@ -442,39 +442,39 @@ for (i = 0; i < purb->number_of_packets; i++) { if (false == peasycap->microphone) { if (much > more) much = more; - memcpy(prt->dma_area + \ - peasycap->dma_fill, \ + memcpy(prt->dma_area + + peasycap->dma_fill, p1, much); p1 += much; more -= much; } else { #if defined(UPSAMPLE) if (much % 16) - JOM(8, "MISTAKE? much" \ + JOM(8, "MISTAKE? much" " is not divisible by 16\n"); - if (much > (16 * \ + if (much > (16 * more)) - much = 16 * \ + much = 16 * more; - p2 = (__u8 *)(prt->dma_area + \ + p2 = (__u8 *)(prt->dma_area + peasycap->dma_fill); for (j = 0; j < (much/16); j++) { newaudio = ((int) *p1) - 128; - newaudio = 128 * \ + newaudio = 128 * newaudio; - delta = (newaudio - oldaudio) \ + delta = (newaudio - oldaudio) / 4; s16 = oldaudio + delta; for (k = 0; k < 4; k++) { *p2 = (0x00FF & s16); - *(p2 + 1) = (0xFF00 & \ + *(p2 + 1) = (0xFF00 & s16) >> 8; p2 += 2; *p2 = (0x00FF & s16); - *(p2 + 1) = (0xFF00 & \ + *(p2 + 1) = (0xFF00 & s16) >> 8; p2 += 2; s16 += delta; @@ -486,15 +486,15 @@ for (i = 0; i < purb->number_of_packets; i++) { #else /*!UPSAMPLE*/ if (much > (2 * more)) much = 2 * more; - p2 = (__u8 *)(prt->dma_area + \ + p2 = (__u8 *)(prt->dma_area + peasycap->dma_fill); for (j = 0; j < (much / 2); j++) { s16 = ((int) *p1) - 128; - s16 = 128 * \ + s16 = 128 * s16; *p2 = (0x00FF & s16); - *(p2 + 1) = (0xFF00 & s16) >> \ + *(p2 + 1) = (0xFF00 & s16) >> 8; p1++; p2 += 2; more--; @@ -503,25 +503,25 @@ for (i = 0; i < purb->number_of_packets; i++) { } peasycap->dma_fill += much; if (peasycap->dma_fill >= peasycap->dma_next) { - isfragment = peasycap->dma_fill / \ + isfragment = peasycap->dma_fill / fragment_bytes; if (0 > isfragment) { - SAM("MISTAKE: isfragment is " \ + SAM("MISTAKE: isfragment is " "negative\n"); return; } - peasycap->dma_read = (isfragment \ + peasycap->dma_read = (isfragment - 1) * fragment_bytes; - peasycap->dma_next = (isfragment \ + peasycap->dma_next = (isfragment + 1) * fragment_bytes; if (dma_bytes < peasycap->dma_next) { - peasycap->dma_next = \ + peasycap->dma_next = fragment_bytes; } if (0 <= peasycap->dma_read) { - JOM(8, "snd_pcm_period_elap" \ - "sed(), %i=" \ - "isfragment\n", \ + JOM(8, "snd_pcm_period_elap" + "sed(), %i=" + "isfragment\n", isfragment); snd_pcm_period_elapsed(pss); } @@ -529,8 +529,8 @@ for (i = 0; i < purb->number_of_packets; i++) { } } } else { - JOM(12, "discarding audio samples because " \ - "%i=purb->iso_frame_desc[i].status\n", \ + JOM(12, "discarding audio samples because " + "%i=purb->iso_frame_desc[i].status\n", purb->iso_frame_desc[i].status); } @@ -549,8 +549,8 @@ if (peasycap->audio_isoc_streaming) { rc = usb_submit_urb(purb, GFP_ATOMIC); if (0 != rc) { if ((-ENODEV != rc) && (-ENOENT != rc)) { - SAM("ERROR: while %i=audio_idle, " \ - "usb_submit_urb() failed " \ + SAM("ERROR: while %i=audio_idle, " + "usb_submit_urb() failed " "with rc:\n", peasycap->audio_idle); } switch (rc) { @@ -685,7 +685,7 @@ return 0; } /*****************************************************************************/ int -easycap_alsa_hw_params(struct snd_pcm_substream *pss, \ +easycap_alsa_hw_params(struct snd_pcm_substream *pss, struct snd_pcm_hw_params *phw) { int rc; @@ -785,7 +785,7 @@ JOM(16, "ALSA decides %8i =sample_bits\n", (int)pss->runtime->sample_bits); JOM(16, "ALSA decides %8i =frame_bits\n", (int)pss->runtime->frame_bits); JOM(16, "ALSA decides %8i =min_align\n", (int)pss->runtime->min_align); JOM(12, "ALSA decides %8i =hw_ptr_base\n", (int)pss->runtime->hw_ptr_base); -JOM(12, "ALSA decides %8i =hw_ptr_interrupt\n", \ +JOM(12, "ALSA decides %8i =hw_ptr_interrupt\n", (int)pss->runtime->hw_ptr_interrupt); if (prt->dma_bytes != 4 * ((int)prt->period_size) * ((int)prt->periods)) { SAY("MISTAKE: unexpected ALSA parameters\n"); @@ -806,7 +806,7 @@ easycap_alsa_trigger(struct snd_pcm_substream *pss, int cmd) struct easycap *peasycap; int retval; -JOT(4, "%i=cmd cf %i=START %i=STOP\n", cmd, SNDRV_PCM_TRIGGER_START, \ +JOT(4, "%i=cmd cf %i=START %i=STOP\n", cmd, SNDRV_PCM_TRIGGER_START, SNDRV_PCM_TRIGGER_STOP); if (NULL == pss) { SAY("ERROR: pss is NULL\n"); @@ -858,8 +858,8 @@ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { return -EFAULT; } if ((0 != peasycap->audio_eof) || (0 != peasycap->audio_idle)) { - JOM(8, "returning -EIO because " \ - "%i=audio_idle %i=audio_eof\n", \ + JOM(8, "returning -EIO because " + "%i=audio_idle %i=audio_eof\n", peasycap->audio_idle, peasycap->audio_eof); return -EIO; } @@ -870,9 +870,9 @@ if (0 > peasycap->dma_read) { } offset = ((snd_pcm_uframes_t)peasycap->dma_read)/4; JOM(8, "ALSA decides %8i =hw_ptr_base\n", (int)pss->runtime->hw_ptr_base); -JOM(8, "ALSA decides %8i =hw_ptr_interrupt\n", \ +JOM(8, "ALSA decides %8i =hw_ptr_interrupt\n", (int)pss->runtime->hw_ptr_interrupt); -JOM(8, "%7i=offset %7i=dma_read %7i=dma_next\n", \ +JOM(8, "%7i=offset %7i=dma_read %7i=dma_next\n", (int)offset, peasycap->dma_read, peasycap->dma_next); return offset; } @@ -951,14 +951,14 @@ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { } much = 0; if (peasycap->audio_idle) { - JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n", \ + JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n", peasycap->audio_idle, peasycap->audio_isoc_streaming); if (peasycap->audio_isoc_streaming) { rc = usb_submit_urb(purb, GFP_ATOMIC); if (0 != rc) { if (-ENODEV != rc && -ENOENT != rc) { - SAM("ERROR: while %i=audio_idle, " \ - "usb_submit_urb() failed with rc:\n", \ + SAM("ERROR: while %i=audio_idle, " + "usb_submit_urb() failed with rc:\n", peasycap->audio_idle); } switch (rc) { @@ -1212,12 +1212,12 @@ for (i = 0; i < purb->number_of_packets; i++) { peasycap->audio_mt++; else { if (peasycap->audio_mt) { - JOM(12, "%4i empty audio urb frames\n", \ + JOM(12, "%4i empty audio urb frames\n", peasycap->audio_mt); peasycap->audio_mt = 0; } - p1 = (__u8 *)(purb->transfer_buffer + \ + p1 = (__u8 *)(purb->transfer_buffer + purb->iso_frame_desc[i].offset); leap = 0; @@ -1234,64 +1234,64 @@ for (i = 0; i < purb->number_of_packets; i++) { SAM("MISTAKE: more is negative\n"); return; } - if (peasycap->audio_buffer_page_many <= \ + if (peasycap->audio_buffer_page_many <= peasycap->audio_fill) { - SAM("ERROR: bad " \ + SAM("ERROR: bad " "peasycap->audio_fill\n"); return; } - paudio_buffer = &peasycap->audio_buffer\ + paudio_buffer = &peasycap->audio_buffer [peasycap->audio_fill]; - if (PAGE_SIZE < (paudio_buffer->pto - \ + if (PAGE_SIZE < (paudio_buffer->pto - paudio_buffer->pgo)) { SAM("ERROR: bad paudio_buffer->pto\n"); return; } - if (PAGE_SIZE == (paudio_buffer->pto - \ + if (PAGE_SIZE == (paudio_buffer->pto - paudio_buffer->pgo)) { #if defined(TESTTONE) - easyoss_testtone(peasycap, \ + easyoss_testtone(peasycap, peasycap->audio_fill); #endif /*TESTTONE*/ - paudio_buffer->pto = \ + paudio_buffer->pto = paudio_buffer->pgo; (peasycap->audio_fill)++; - if (peasycap->\ - audio_buffer_page_many <= \ + if (peasycap-> + audio_buffer_page_many <= peasycap->audio_fill) peasycap->audio_fill = 0; - JOM(8, "bumped peasycap->" \ - "audio_fill to %i\n", \ + JOM(8, "bumped peasycap->" + "audio_fill to %i\n", peasycap->audio_fill); - paudio_buffer = &peasycap->\ - audio_buffer\ + paudio_buffer = &peasycap-> + audio_buffer [peasycap->audio_fill]; - paudio_buffer->pto = \ + paudio_buffer->pto = paudio_buffer->pgo; - if (!(peasycap->audio_fill % \ - peasycap->\ + if (!(peasycap->audio_fill % + peasycap-> audio_pages_per_fragment)) { - JOM(12, "wakeup call on wq_" \ - "audio, %i=frag reading %i" \ - "=fragment fill\n", \ - (peasycap->audio_read / \ - peasycap->\ - audio_pages_per_fragment), \ - (peasycap->audio_fill / \ - peasycap->\ + JOM(12, "wakeup call on wq_" + "audio, %i=frag reading %i" + "=fragment fill\n", + (peasycap->audio_read / + peasycap-> + audio_pages_per_fragment), + (peasycap->audio_fill / + peasycap-> audio_pages_per_fragment)); - wake_up_interruptible\ + wake_up_interruptible (&(peasycap->wq_audio)); } } - much = PAGE_SIZE - (int)(paudio_buffer->pto -\ + much = PAGE_SIZE - (int)(paudio_buffer->pto - paudio_buffer->pgo); if (false == peasycap->microphone) { @@ -1304,30 +1304,30 @@ for (i = 0; i < purb->number_of_packets; i++) { } else { #if defined(UPSAMPLE) if (much % 16) - JOM(8, "MISTAKE? much" \ + JOM(8, "MISTAKE? much" " is not divisible by 16\n"); - if (much > (16 * \ + if (much > (16 * more)) - much = 16 * \ + much = 16 * more; p2 = (__u8 *)paudio_buffer->pto; for (j = 0; j < (much/16); j++) { newaudio = ((int) *p1) - 128; - newaudio = 128 * \ + newaudio = 128 * newaudio; - delta = (newaudio - oldaudio) \ + delta = (newaudio - oldaudio) / 4; s16 = oldaudio + delta; for (k = 0; k < 4; k++) { *p2 = (0x00FF & s16); - *(p2 + 1) = (0xFF00 & \ + *(p2 + 1) = (0xFF00 & s16) >> 8; p2 += 2; *p2 = (0x00FF & s16); - *(p2 + 1) = (0xFF00 & \ + *(p2 + 1) = (0xFF00 & s16) >> 8; p2 += 2; @@ -1344,10 +1344,10 @@ for (i = 0; i < purb->number_of_packets; i++) { for (j = 0; j < (much / 2); j++) { s16 = ((int) *p1) - 128; - s16 = 128 * \ + s16 = 128 * s16; *p2 = (0x00FF & s16); - *(p2 + 1) = (0xFF00 & s16) >> \ + *(p2 + 1) = (0xFF00 & s16) >> 8; p1++; p2 += 2; more--; @@ -1358,8 +1358,8 @@ for (i = 0; i < purb->number_of_packets; i++) { } } } else { - JOM(12, "discarding audio samples because " \ - "%i=purb->iso_frame_desc[i].status\n", \ + JOM(12, "discarding audio samples because " + "%i=purb->iso_frame_desc[i].status\n", purb->iso_frame_desc[i].status); } @@ -1378,8 +1378,8 @@ if (peasycap->audio_isoc_streaming) { rc = usb_submit_urb(purb, GFP_ATOMIC); if (0 != rc) { if (-ENODEV != rc && -ENOENT != rc) { - SAM("ERROR: while %i=audio_idle, " \ - "usb_submit_urb() failed " \ + SAM("ERROR: while %i=audio_idle, " + "usb_submit_urb() failed " "with rc:\n", peasycap->audio_idle); } switch (rc) { @@ -1489,7 +1489,7 @@ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { SAY("ERROR: pv4l2_device is NULL\n"); return -EFAULT; } - peasycap = (struct easycap *) \ + peasycap = (struct easycap *) container_of(pv4l2_device, struct easycap, v4l2_device); } #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ @@ -1537,7 +1537,7 @@ return 0; } /*****************************************************************************/ ssize_t -easyoss_read(struct file *file, char __user *puserspacebuffer, \ +easyoss_read(struct file *file, char __user *puserspacebuffer, size_t kount, loff_t *poff) { struct timeval timeval; @@ -1609,7 +1609,7 @@ if (0 <= kd && DONGLE_MANY > kd) { return -ERESTARTSYS; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", \ + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; @@ -1634,7 +1634,7 @@ if (file->f_flags & O_NONBLOCK) else JOT(8, "BLOCKING kount=%i, *poff=%i\n", (int)kount, (int)(*poff)); -if ((0 > peasycap->audio_read) || \ +if ((0 > peasycap->audio_read) || (peasycap->audio_buffer_page_many <= peasycap->audio_read)) { SAM("ERROR: peasycap->audio_read out of range\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); @@ -1646,22 +1646,22 @@ if ((struct data_buffer *)NULL == pdata_buffer) { mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } -JOM(12, "before wait, %i=frag read %i=frag fill\n", \ - (peasycap->audio_read / peasycap->audio_pages_per_fragment), \ +JOM(12, "before wait, %i=frag read %i=frag fill\n", + (peasycap->audio_read / peasycap->audio_pages_per_fragment), (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment); -while ((fragment == (peasycap->audio_fill / \ - peasycap->audio_pages_per_fragment)) || \ +while ((fragment == (peasycap->audio_fill / + peasycap->audio_pages_per_fragment)) || (0 == (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))) { if (file->f_flags & O_NONBLOCK) { JOM(16, "returning -EAGAIN as instructed\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EAGAIN; } - rc = wait_event_interruptible(peasycap->wq_audio, \ - (peasycap->audio_idle || peasycap->audio_eof || \ - ((fragment != (peasycap->audio_fill / \ - peasycap->audio_pages_per_fragment)) && \ + rc = wait_event_interruptible(peasycap->wq_audio, + (peasycap->audio_idle || peasycap->audio_eof || + ((fragment != (peasycap->audio_fill / + peasycap->audio_pages_per_fragment)) && (0 < (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))))); if (0 != rc) { SAM("aborted by signal\n"); @@ -1669,14 +1669,14 @@ while ((fragment == (peasycap->audio_fill / \ return -ERESTARTSYS; } if (peasycap->audio_eof) { - JOM(8, "returning 0 because %i=audio_eof\n", \ + JOM(8, "returning 0 because %i=audio_eof\n", peasycap->audio_eof); kill_audio_urbs(peasycap); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return 0; } if (peasycap->audio_idle) { - JOM(16, "returning 0 because %i=audio_idle\n", \ + JOM(16, "returning 0 because %i=audio_idle\n", peasycap->audio_idle); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return 0; @@ -1687,12 +1687,12 @@ while ((fragment == (peasycap->audio_fill / \ return 0; } } -JOM(12, "after wait, %i=frag read %i=frag fill\n", \ - (peasycap->audio_read / peasycap->audio_pages_per_fragment), \ +JOM(12, "after wait, %i=frag read %i=frag fill\n", + (peasycap->audio_read / peasycap->audio_pages_per_fragment), (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); szret = (size_t)0; fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment); -while (fragment == (peasycap->audio_read / \ +while (fragment == (peasycap->audio_read / peasycap->audio_pages_per_fragment)) { if (NULL == pdata_buffer->pgo) { SAM("ERROR: pdata_buffer->pgo is NULL\n"); @@ -1714,15 +1714,15 @@ while (fragment == (peasycap->audio_read / \ (peasycap->audio_read)++; if (peasycap->audio_buffer_page_many <= peasycap->audio_read) peasycap->audio_read = 0; - JOM(12, "bumped peasycap->audio_read to %i\n", \ + JOM(12, "bumped peasycap->audio_read to %i\n", peasycap->audio_read); - if (fragment != (peasycap->audio_read / \ + if (fragment != (peasycap->audio_read / peasycap->audio_pages_per_fragment)) break; - if ((0 > peasycap->audio_read) || \ - (peasycap->audio_buffer_page_many <= \ + if ((0 > peasycap->audio_read) || + (peasycap->audio_buffer_page_many <= peasycap->audio_read)) { SAM("ERROR: peasycap->audio_read out of range\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); @@ -1751,7 +1751,7 @@ while (fragment == (peasycap->audio_read / \ more = kount1; if (more > kount) more = kount; - JOM(12, "agreed to send %li bytes from page %i\n", \ + JOM(12, "agreed to send %li bytes from page %i\n", more, peasycap->audio_read); if (!more) break; @@ -1763,7 +1763,7 @@ while (fragment == (peasycap->audio_read / \ /*---------------------------------------------------------------------------*/ p0 = (unsigned char *)pdata_buffer->pgo; l0 = 0; lm = more/2; while (l0 < lm) { - SUMMER(p0, &peasycap->audio_sample, &peasycap->audio_niveau, \ + SUMMER(p0, &peasycap->audio_sample, &peasycap->audio_niveau, &peasycap->audio_square); l0++; p0 += 2; } /*---------------------------------------------------------------------------*/ @@ -1779,11 +1779,11 @@ while (fragment == (peasycap->audio_read / \ puserspacebuffer += more; kount -= (size_t)more; } -JOM(12, "after read, %i=frag read %i=frag fill\n", \ - (peasycap->audio_read / peasycap->audio_pages_per_fragment), \ +JOM(12, "after read, %i=frag read %i=frag fill\n", + (peasycap->audio_read / peasycap->audio_pages_per_fragment), (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); if (kount < 0) { - SAM("MISTAKE: %li=kount %li=szret\n", \ + SAM("MISTAKE: %li=kount %li=szret\n", (long int)kount, (long int)szret); } /*---------------------------------------------------------------------------*/ @@ -1799,7 +1799,7 @@ if (peasycap->audio_sample) { mean = peasycap->audio_niveau; sdr = signed_div(mean, peasycap->audio_sample); - JOM(8, "%8lli=mean %8lli=meansquare after %lli samples, =>\n", \ + JOM(8, "%8lli=mean %8lli=meansquare after %lli samples, =>\n", sdr.quotient, above, peasycap->audio_sample); sdr = signed_div(above, 32768); @@ -1818,9 +1818,9 @@ if (!peasycap->timeval1.tv_sec) { sdr.quotient = 192000; } else { peasycap->audio_bytes += (long long int) szret; - below = ((long long int)(1000000)) * \ - ((long long int)(timeval.tv_sec - \ - peasycap->timeval3.tv_sec)) + \ + below = ((long long int)(1000000)) * + ((long long int)(timeval.tv_sec - + peasycap->timeval3.tv_sec)) + (long long int)(timeval.tv_usec - peasycap->timeval3.tv_usec); above = 1000000 * ((long long int) peasycap->audio_bytes); @@ -1881,9 +1881,9 @@ if ((struct usb_device *)NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device has become NULL\n"); return -ENODEV; } -rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, \ +rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, peasycap->audio_altsetting_on); -JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, \ +JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, peasycap->audio_altsetting_on, rc); rc = wakeup_device(peasycap->pusb_device); @@ -1930,10 +1930,10 @@ if ((struct usb_device *)NULL == peasycap->pusb_device) { if (!peasycap->audio_isoc_streaming) { JOM(4, "initial submission of all audio urbs\n"); rc = usb_set_interface(peasycap->pusb_device, - peasycap->audio_interface, \ + peasycap->audio_interface, peasycap->audio_altsetting_on); - JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", \ - peasycap->audio_interface, \ + JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", + peasycap->audio_interface, peasycap->audio_altsetting_on, rc); isbad = 0; nospc = 0; m = 0; @@ -1946,13 +1946,13 @@ if (!peasycap->audio_isoc_streaming) { purb->interval = 1; purb->dev = peasycap->pusb_device; - purb->pipe = \ - usb_rcvisocpipe(peasycap->pusb_device,\ + purb->pipe = + usb_rcvisocpipe(peasycap->pusb_device, peasycap->audio_endpointnumber); purb->transfer_flags = URB_ISO_ASAP; - purb->transfer_buffer = \ + purb->transfer_buffer = peasycap->audio_isoc_buffer[isbuf].pgo; - purb->transfer_buffer_length = \ + purb->transfer_buffer_length = peasycap->audio_isoc_buffer_size; #if defined(EASYCAP_NEEDS_ALSA) purb->complete = easycap_alsa_complete; @@ -1961,23 +1961,23 @@ if (!peasycap->audio_isoc_streaming) { #endif /*EASYCAP_NEEDS_ALSA*/ purb->context = peasycap; purb->start_frame = 0; - purb->number_of_packets = \ + purb->number_of_packets = peasycap->audio_isoc_framesperdesc; - for (j = 0; j < peasycap->\ - audio_isoc_framesperdesc; \ + for (j = 0; j < peasycap-> + audio_isoc_framesperdesc; j++) { - purb->iso_frame_desc[j].offset = j * \ - peasycap->\ + purb->iso_frame_desc[j].offset = j * + peasycap-> audio_isoc_maxframesize; - purb->iso_frame_desc[j].length = \ - peasycap->\ + purb->iso_frame_desc[j].length = + peasycap-> audio_isoc_maxframesize; } rc = usb_submit_urb(purb, GFP_KERNEL); if (0 != rc) { isbad++; - SAM("ERROR: usb_submit_urb() failed" \ + SAM("ERROR: usb_submit_urb() failed" " for urb with rc:\n"); switch (rc) { case -ENODEV: { @@ -2047,7 +2047,7 @@ if (!peasycap->audio_isoc_streaming) { if (isbad) { JOM(4, "attempting cleanup instead of submitting\n"); list_for_each(plist_head, (peasycap->purb_audio_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, \ + pdata_urb = list_entry(plist_head, struct data_urb, list_head); if (NULL != pdata_urb) { purb = pdata_urb->purb; @@ -2103,7 +2103,7 @@ if (peasycap->audio_isoc_streaming) { return -EFAULT; } } else { - JOM(8, "%i=audio_isoc_streaming, no audio urbs killed\n", \ + JOM(8, "%i=audio_isoc_streaming, no audio urbs killed\n", peasycap->audio_isoc_streaming); } return 0; -- cgit v1.2.3 From 5a858078942a6cb75f1d3ac44e8077bc228f32a8 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 19 Jan 2011 00:24:09 +0200 Subject: staging: easycap: kill EASYCAP_NEEDS_CARD_CREATE for in-tree driver we can use snd_card_create for backports to older kernels this can be easily wrapped Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/Makefile | 1 - drivers/staging/easycap/easycap_sound.c | 9 --------- 2 files changed, 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/Makefile b/drivers/staging/easycap/Makefile index 977e1535667d..226a7795a1db 100644 --- a/drivers/staging/easycap/Makefile +++ b/drivers/staging/easycap/Makefile @@ -9,5 +9,4 @@ ccflags-y += -DEASYCAP_NEEDS_V4L2_DEVICE_H ccflags-y += -DEASYCAP_NEEDS_V4L2_FOPS ccflags-y += -DEASYCAP_NEEDS_UNLOCKED_IOCTL ccflags-y += -DEASYCAP_NEEDS_ALSA -ccflags-y += -DEASYCAP_NEEDS_CARD_CREATE diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index 8d1c0620344d..4bfaf06fb32a 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -107,21 +107,12 @@ if (true == peasycap->microphone) { peasycap->alsa_hardware.rate_max = 48000; } -#if defined(EASYCAP_NEEDS_CARD_CREATE) if (0 != snd_card_create(SNDRV_DEFAULT_IDX1, "easycap_alsa", THIS_MODULE, 0, &psnd_card)) { SAY("ERROR: Cannot do ALSA snd_card_create()\n"); return -EFAULT; } -#else - psnd_card = snd_card_new(SNDRV_DEFAULT_IDX1, "easycap_alsa", - THIS_MODULE, 0); - if (NULL == psnd_card) { - SAY("ERROR: Cannot do ALSA snd_card_new()\n"); - return -EFAULT; - } -#endif /*EASYCAP_NEEDS_CARD_CREATE*/ sprintf(&psnd_card->id[0], "EasyALSA%i", peasycap->minor); strcpy(&psnd_card->driver[0], EASYCAP_DRIVER_DESCRIPTION); -- cgit v1.2.3 From e8b754ee8f71835281bdcea91d0ab37718abadb6 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 19 Jan 2011 00:24:10 +0200 Subject: staging: easycap: replace STRINGIZE with __stringify() Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 2 -- drivers/staging/easycap/easycap_settings.c | 12 ++++++------ 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index d8e4bb817188..337c9bdcfe4d 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -109,8 +109,6 @@ #error "PAGE_SIZE not defined" #endif -#define STRINGIZE_AGAIN(x) #x -#define STRINGIZE(x) STRINGIZE_AGAIN(x) /*---------------------------------------------------------------------------*/ /* VENDOR, PRODUCT: Syntek Semiconductor Co., Ltd * diff --git a/drivers/staging/easycap/easycap_settings.c b/drivers/staging/easycap/easycap_settings.c index 7b2dd6eeb41f..3a81cc26df03 100644 --- a/drivers/staging/easycap/easycap_settings.c +++ b/drivers/staging/easycap/easycap_settings.c @@ -506,39 +506,39 @@ for (i = 0, n = 0; i < STANDARD_MANY; i++) { mask3 = 0x0000; switch (k) { case FMT_UYVY: { - strcpy(&name3[0], "_" STRINGIZE(FMT_UYVY)); + strcpy(&name3[0], "_" __stringify(FMT_UYVY)); pixelformat = V4L2_PIX_FMT_UYVY; mask3 |= (0x02 << 5); break; } case FMT_YUY2: { - strcpy(&name3[0], "_" STRINGIZE(FMT_YUY2)); + strcpy(&name3[0], "_" __stringify(FMT_YUY2)); pixelformat = V4L2_PIX_FMT_YUYV; mask3 |= (0x02 << 5); mask3 |= 0x0100; break; } case FMT_RGB24: { - strcpy(&name3[0], "_" STRINGIZE(FMT_RGB24)); + strcpy(&name3[0], "_" __stringify(FMT_RGB24)); pixelformat = V4L2_PIX_FMT_RGB24; mask3 |= (0x03 << 5); break; } case FMT_RGB32: { - strcpy(&name3[0], "_" STRINGIZE(FMT_RGB32)); + strcpy(&name3[0], "_" __stringify(FMT_RGB32)); pixelformat = V4L2_PIX_FMT_RGB32; mask3 |= (0x04 << 5); break; } case FMT_BGR24: { - strcpy(&name3[0], "_" STRINGIZE(FMT_BGR24)); + strcpy(&name3[0], "_" __stringify(FMT_BGR24)); pixelformat = V4L2_PIX_FMT_BGR24; mask3 |= (0x03 << 5); mask3 |= 0x0100; break; } case FMT_BGR32: { - strcpy(&name3[0], "_" STRINGIZE(FMT_BGR32)); + strcpy(&name3[0], "_" __stringify(FMT_BGR32)); pixelformat = V4L2_PIX_FMT_BGR32; mask3 |= (0x04 << 5); mask3 |= 0x0100; -- cgit v1.2.3 From 56aec8de6ee32cde195ae83ce765583191238860 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Mon, 10 Jan 2011 23:07:16 +0100 Subject: staging/comedi/me4000: fix sparse warning "obsolete struct initializer" This patch fixes the sparse warnings in me4000.c: me4000.c:122:1: warning: obsolete struct initializer, use C99 syntax me4000.c:123:1: warning: obsolete struct initializer, use C99 syntax me4000.c:124:1: warning: obsolete struct initializer, use C99 syntax me4000.c:125:1: warning: obsolete struct initializer, use C99 syntax by converting the struct to use C99 syntax Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me4000.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index e6825c2569a5..75511bae0191 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -119,10 +119,10 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it); static int me4000_detach(struct comedi_device *dev); static struct comedi_driver driver_me4000 = { -driver_name: "me4000", -module : THIS_MODULE, -attach : me4000_attach, -detach : me4000_detach, + .driver_name = "me4000", + .module = THIS_MODULE, + .attach = me4000_attach, + .detach = me4000_detach, }; /*----------------------------------------------------------------------------- -- cgit v1.2.3 From eb8393926688a6ce784c35d26dcde005e769bbdc Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Mon, 10 Jan 2011 23:18:33 +0100 Subject: staging/comedi/icp_multi: fix sparse warning "obsolete struct initializer" This patch fixes the sparse warnings "obsolete struct initializer, use C99 syntax" in icp_multi.c by converting the struct to C99 syntax KernelVersion: linux-next-20110110 Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/icp_multi.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 809d17efd5b3..0bab39b3409b 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -176,13 +176,13 @@ static const struct boardtype boardtypes[] = { #define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype)) static struct comedi_driver driver_icp_multi = { -driver_name: "icp_multi", -module : THIS_MODULE, -attach : icp_multi_attach, -detach : icp_multi_detach, -num_names : n_boardtypes, -board_name : &boardtypes[0].name, -offset : sizeof(struct boardtype), + .driver_name = "icp_multi", + .module = THIS_MODULE, + .attach = icp_multi_attach, + .detach = icp_multi_detach, + .num_names = n_boardtypes, + .board_name = &boardtypes[0].name, + .offset = sizeof(struct boardtype), }; static int __init driver_icp_multi_init_module(void) -- cgit v1.2.3 From 34381c22b0a26ef6663f5fd92574d3f45243cabf Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Mon, 10 Jan 2011 23:28:06 +0100 Subject: staging/vt6655: fix sparse warning "obsolete struct initializer" This patch fixes the sparse warnings "obsolete struct initializer, use C99 syntax" in vt6655/device_main.c by converting the struct to C99 syntax KernelVersion: linux-next-20110110 Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index f5028d9d7d9b..4fbacf8fdf21 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -312,9 +312,9 @@ static int device_notify_reboot(struct notifier_block *, unsigned long event, vo static int viawget_suspend(struct pci_dev *pcid, pm_message_t state); static int viawget_resume(struct pci_dev *pcid); struct notifier_block device_notifier = { - notifier_call: device_notify_reboot, - next: NULL, - priority: 0 + .notifier_call = device_notify_reboot, + .next = NULL, + .priority = 0, }; #endif @@ -3606,13 +3606,13 @@ static int ethtool_ioctl(struct net_device *dev, void *useraddr) MODULE_DEVICE_TABLE(pci, vt6655_pci_id_table); static struct pci_driver device_driver = { - name: DEVICE_NAME, - id_table: vt6655_pci_id_table, - probe: vt6655_probe, - remove: vt6655_remove, + .name = DEVICE_NAME, + .id_table = vt6655_pci_id_table, + .probe = vt6655_probe, + .remove = vt6655_remove, #ifdef CONFIG_PM - suspend: viawget_suspend, - resume: viawget_resume, + .suspend = viawget_suspend, + .resume = viawget_resume, #endif }; -- cgit v1.2.3 From 7bd74cd0e5f56088c0aa873bb6ba0dab0b21a7e1 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 10 Jan 2011 23:23:10 +0100 Subject: Staging: FT1000: remove duplicate inc of linux/slab.h linux/slab.h is included twice in ft1000_dnld.c - remove duplicate. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c index c56f588a790b..b0729fc3c89a 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From f945f1087f1fe20f9c626daa175b677736fc614d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 4 Jan 2011 16:21:59 -0800 Subject: iwlagn: make iwl_rx_handle static It's not used or likely to be needed from other files, so it can be static. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 8b045a401d62..624f174f8664 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -846,7 +846,7 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv) * the appropriate handlers, including command responses, * frame-received notifications, and other notifications. */ -void iwl_rx_handle(struct iwl_priv *priv) +static void iwl_rx_handle(struct iwl_priv *priv) { struct iwl_rx_mem_buffer *rxb; struct iwl_rx_packet *pkt; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 822221a97e80..c30dc4f7a619 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -185,7 +185,6 @@ void iwlagn_rx_reply_rx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); -void iwl_rx_handle(struct iwl_priv *priv); /* tx */ void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); -- cgit v1.2.3 From 7194207ceea7a54c846e0865d2459f4887fe1e0d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 4 Jan 2011 16:22:00 -0800 Subject: iwlagn: add support for waiting for notifications In order to implement waiting for notifications, add a structure that captures the information, and a list of such structures that will be traversed when a command is received from the ucode. Use sparse checking to make sure calls to the prepare/wait/cancel functions are always nested correctly. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 46 ++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.c | 21 ++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.h | 15 ++++++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 33 +++++++++++++++++++++ 4 files changed, 115 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 3dee87e8f55d..29dcda0bde65 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -473,6 +473,11 @@ void iwlagn_rx_handler_setup(struct iwl_priv *priv) priv->rx_handlers[CALIBRATION_COMPLETE_NOTIFICATION] = iwlagn_rx_calib_complete; priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx; + + /* set up notification wait support */ + spin_lock_init(&priv->_agn.notif_wait_lock); + INIT_LIST_HEAD(&priv->_agn.notif_waits); + init_waitqueue_head(&priv->_agn.notif_waitq); } void iwlagn_setup_deferred_work(struct iwl_priv *priv) @@ -2389,3 +2394,44 @@ int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display) } return 0; } + +/* notification wait support */ +void iwlagn_init_notification_wait(struct iwl_priv *priv, + struct iwl_notification_wait *wait_entry, + void (*fn)(struct iwl_priv *priv, + struct iwl_rx_packet *pkt), + u8 cmd) +{ + wait_entry->fn = fn; + wait_entry->cmd = cmd; + wait_entry->triggered = false; + + spin_lock_bh(&priv->_agn.notif_wait_lock); + list_add(&wait_entry->list, &priv->_agn.notif_waits); + spin_unlock_bh(&priv->_agn.notif_wait_lock); +} + +signed long iwlagn_wait_notification(struct iwl_priv *priv, + struct iwl_notification_wait *wait_entry, + unsigned long timeout) +{ + int ret; + + ret = wait_event_timeout(priv->_agn.notif_waitq, + &wait_entry->triggered, + timeout); + + spin_lock_bh(&priv->_agn.notif_wait_lock); + list_del(&wait_entry->list); + spin_unlock_bh(&priv->_agn.notif_wait_lock); + + return ret; +} + +void iwlagn_remove_notification(struct iwl_priv *priv, + struct iwl_notification_wait *wait_entry) +{ + spin_lock_bh(&priv->_agn.notif_wait_lock); + list_del(&wait_entry->list); + spin_unlock_bh(&priv->_agn.notif_wait_lock); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 624f174f8664..97657d04aa68 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -910,6 +910,27 @@ static void iwl_rx_handle(struct iwl_priv *priv) (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && (pkt->hdr.cmd != REPLY_TX); + /* + * Do the notification wait before RX handlers so + * even if the RX handler consumes the RXB we have + * access to it in the notification wait entry. + */ + if (!list_empty(&priv->_agn.notif_waits)) { + struct iwl_notification_wait *w; + + spin_lock(&priv->_agn.notif_wait_lock); + list_for_each_entry(w, &priv->_agn.notif_waits, list) { + if (w->cmd == pkt->hdr.cmd) { + w->triggered = true; + if (w->fn) + w->fn(priv, pkt); + } + } + spin_unlock(&priv->_agn.notif_wait_lock); + + wake_up_all(&priv->_agn.notif_waitq); + } + /* Based on type of command response or notification, * handle those that need handling via function in * rx_handlers table. See iwl_setup_rx_handlers() */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index c30dc4f7a619..74d72ff24d05 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -329,6 +329,21 @@ void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac); int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv); void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv); +/* notification wait support */ +void __acquires(wait_entry) +iwlagn_init_notification_wait(struct iwl_priv *priv, + struct iwl_notification_wait *wait_entry, + void (*fn)(struct iwl_priv *priv, + struct iwl_rx_packet *pkt), + u8 cmd); +signed long __releases(wait_entry) +iwlagn_wait_notification(struct iwl_priv *priv, + struct iwl_notification_wait *wait_entry, + unsigned long timeout); +void __releases(wait_entry) +iwlagn_remove_notification(struct iwl_priv *priv, + struct iwl_notification_wait *wait_entry); + /* mac80211 handlers (for 4965) */ int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb); int iwlagn_mac_start(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 8dda67850af4..2ec680bb8f6d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -34,6 +34,7 @@ #include /* for struct pci_device_id */ #include +#include #include #include "iwl-eeprom.h" @@ -1139,6 +1140,33 @@ struct iwl_force_reset { */ #define IWLAGN_EXT_BEACON_TIME_POS 22 +/** + * struct iwl_notification_wait - notification wait entry + * @list: list head for global list + * @fn: function called with the notification + * @cmd: command ID + * + * This structure is not used directly, to wait for a + * notification declare it on the stack, and call + * iwlagn_init_notification_wait() with appropriate + * parameters. Then do whatever will cause the ucode + * to notify the driver, and to wait for that then + * call iwlagn_wait_notification(). + * + * Each notification is one-shot. If at some point we + * need to support multi-shot notifications (which + * can't be allocated on the stack) we need to modify + * the code for them. + */ +struct iwl_notification_wait { + struct list_head list; + + void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt); + + u8 cmd; + bool triggered; +}; + enum iwl_rxon_context_id { IWL_RXON_CTX_BSS, IWL_RXON_CTX_PAN, @@ -1463,6 +1491,11 @@ struct iwl_priv { struct iwl_bt_notif_statistics delta_statistics_bt; struct iwl_bt_notif_statistics max_delta_bt; #endif + + /* notification wait support */ + struct list_head notif_waits; + spinlock_t notif_wait_lock; + wait_queue_head_t notif_waitq; } _agn; #endif }; -- cgit v1.2.3 From 311dce71b6af263a630717d77bd49cffc0d122a5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 4 Jan 2011 16:22:01 -0800 Subject: iwlagn: properly wait for PAN disable Previously I hacked this with an msleep(300) which was fine since we never had longer PAN time slots, but now that we will have them I need to fix that. Use the new notification wait support to properly wait for the WIPAN deactivation complete signal from the ucode. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 15 ++++++++++++--- drivers/net/wireless/iwlwifi/iwl-commands.h | 1 + drivers/net/wireless/iwlwifi/iwl-hcmd.c | 1 + 3 files changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 6d140bd53291..99e96508b1dc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -52,10 +52,14 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct iwl_rxon_cmd *send) { + struct iwl_notification_wait disable_wait; __le32 old_filter = send->filter_flags; u8 old_dev_type = send->dev_type; int ret; + iwlagn_init_notification_wait(priv, &disable_wait, NULL, + REPLY_WIPAN_DEACTIVATION_COMPLETE); + send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; send->dev_type = RXON_DEV_TYPE_P2P; ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send); @@ -63,11 +67,16 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, send->filter_flags = old_filter; send->dev_type = old_dev_type; - if (ret) + if (ret) { IWL_ERR(priv, "Error disabling PAN (%d)\n", ret); + iwlagn_remove_notification(priv, &disable_wait); + } else { + signed long wait_res; - /* FIXME: WAIT FOR PAN DISABLE */ - msleep(300); + wait_res = iwlagn_wait_notification(priv, &disable_wait, HZ); + if (wait_res == 0) + IWL_ERR(priv, "Timed out waiting for PAN disable\n"); + } return ret; } diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index f893d4a6aa87..abe2479215f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -189,6 +189,7 @@ enum { REPLY_WIPAN_WEPKEY = 0xb8, /* use REPLY_WEPKEY structure */ REPLY_WIPAN_P2P_CHANNEL_SWITCH = 0xb9, REPLY_WIPAN_NOA_NOTIFICATION = 0xbc, + REPLY_WIPAN_DEACTIVATION_COMPLETE = 0xbd, REPLY_MAX = 0xff }; diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index c373b53babea..e4b953d7b7bf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -108,6 +108,7 @@ const char *get_cmd_string(u8 cmd) IWL_CMD(REPLY_WIPAN_WEPKEY); IWL_CMD(REPLY_WIPAN_P2P_CHANNEL_SWITCH); IWL_CMD(REPLY_WIPAN_NOA_NOTIFICATION); + IWL_CMD(REPLY_WIPAN_DEACTIVATION_COMPLETE); default: return "UNKNOWN"; -- cgit v1.2.3 From 2a1a78d240c68b918406cb5b31a375eaf1dc1835 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 4 Jan 2011 16:22:02 -0800 Subject: iwlagn: return error if PAN disable timeout Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 99e96508b1dc..6e80f1070c52 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -74,8 +74,10 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, signed long wait_res; wait_res = iwlagn_wait_notification(priv, &disable_wait, HZ); - if (wait_res == 0) + if (wait_res == 0) { IWL_ERR(priv, "Timed out waiting for PAN disable\n"); + ret = -EIO; + } } return ret; -- cgit v1.2.3 From ea67485ae6894e603984c3b13b8df54ae2c128d8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 4 Jan 2011 16:22:03 -0800 Subject: iwlwifi: fix 4965 notification wait setup The notification wait support code is shared between 4965 and other AGN devices, so 4965 also has to initialize the data structures for it, otherwise it crashes. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 3f1e5f1bf847..d9a7d93def6c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2316,6 +2316,11 @@ static void iwl4965_rx_handler_setup(struct iwl_priv *priv) priv->rx_handlers[REPLY_RX] = iwlagn_rx_reply_rx; /* Tx response */ priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; + + /* set up notification wait support */ + spin_lock_init(&priv->_agn.notif_wait_lock); + INIT_LIST_HEAD(&priv->_agn.notif_waits); + init_waitqueue_head(&priv->_agn.notif_waitq); } static void iwl4965_setup_deferred_work(struct iwl_priv *priv) -- cgit v1.2.3 From 1f427dd913a1bf61f2d124d12a022ca2f1d27f53 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Sun, 9 Jan 2011 23:11:43 -0800 Subject: ath9k: Show some live tx-queue values in debugfs. I thought this might help track down stuck queues, etc. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 3586c43077a7..5075faa618d3 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -589,6 +589,16 @@ static const struct file_operations fops_wiphy = { sc->debug.stats.txstats[WME_AC_VO].elem); \ } while(0) +#define PRX(str, elem) \ +do { \ + len += snprintf(buf + len, size - len, \ + "%s%13u%11u%10u%10u\n", str, \ + (unsigned int)(sc->tx.txq[WME_AC_BE].elem), \ + (unsigned int)(sc->tx.txq[WME_AC_BK].elem), \ + (unsigned int)(sc->tx.txq[WME_AC_VI].elem), \ + (unsigned int)(sc->tx.txq[WME_AC_VO].elem)); \ +} while(0) + static ssize_t read_file_xmit(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -619,6 +629,12 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, PR("TX-Pkts-All: ", tx_pkts_all); PR("TX-Bytes-All: ", tx_bytes_all); + PRX("axq-qnum: ", axq_qnum); + PRX("axq-depth: ", axq_depth); + PRX("axq-stopped ", stopped); + PRX("tx-in-progress ", axq_tx_inprogress); + PRX("pending-frames ", pending_frames); + if (len > size) len = size; -- cgit v1.2.3 From 233536e126056f65a8aac7ff38788d19dbb53299 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Sun, 9 Jan 2011 23:11:44 -0800 Subject: ath9k: Initialize ah->hw Previous code left it NULL. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 767d8b86f1e1..23b299818b18 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -537,6 +537,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, if (!ah) return -ENOMEM; + ah->hw = sc->hw; ah->hw_version.devid = devid; ah->hw_version.subsysid = subsysid; sc->sc_ah = ah; -- cgit v1.2.3 From 2dac4fb97a41af1e6b7ab9f59c837d20838e92da Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Sun, 9 Jan 2011 23:11:45 -0800 Subject: ath9k: Add more information to debugfs xmit file. Should help debug strange tx lockup type issues. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 29 +++++++++++++++++++++++++++-- drivers/net/wireless/ath/ath9k/debug.h | 6 ++++++ drivers/net/wireless/ath/ath9k/mac.c | 8 ++++++++ drivers/net/wireless/ath/ath9k/xmit.c | 1 + 4 files changed, 42 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 5075faa618d3..577bc5a9835b 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -599,13 +599,25 @@ do { \ (unsigned int)(sc->tx.txq[WME_AC_VO].elem)); \ } while(0) +#define PRQLE(str, elem) \ +do { \ + len += snprintf(buf + len, size - len, \ + "%s%13i%11i%10i%10i\n", str, \ + list_empty(&sc->tx.txq[WME_AC_BE].elem), \ + list_empty(&sc->tx.txq[WME_AC_BK].elem), \ + list_empty(&sc->tx.txq[WME_AC_VI].elem), \ + list_empty(&sc->tx.txq[WME_AC_VO].elem)); \ +} while (0) + static ssize_t read_file_xmit(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath_softc *sc = file->private_data; char *buf; - unsigned int len = 0, size = 2048; + unsigned int len = 0, size = 4000; + int i; ssize_t retval = 0; + char tmp[32]; buf = kzalloc(size, GFP_KERNEL); if (buf == NULL) @@ -628,13 +640,26 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, PR("DELIM Underrun: ", delim_underrun); PR("TX-Pkts-All: ", tx_pkts_all); PR("TX-Bytes-All: ", tx_bytes_all); + PR("hw-put-tx-buf: ", puttxbuf); + PR("hw-tx-start: ", txstart); + PR("hw-tx-proc-desc: ", txprocdesc); PRX("axq-qnum: ", axq_qnum); PRX("axq-depth: ", axq_depth); + PRX("axq-ampdu_depth: ", axq_ampdu_depth); PRX("axq-stopped ", stopped); PRX("tx-in-progress ", axq_tx_inprogress); PRX("pending-frames ", pending_frames); - + PRX("txq_headidx: ", txq_headidx); + PRX("txq_tailidx: ", txq_headidx); + + PRQLE("axq_q empty: ", axq_q); + PRQLE("axq_acq empty: ", axq_acq); + PRQLE("txq_fifo_pending: ", txq_fifo_pending); + for (i = 0; i < ATH_TXFIFO_DEPTH; i++) { + snprintf(tmp, sizeof(tmp) - 1, "txq_fifo[%i] empty: ", i); + PRQLE(tmp, txq_fifo[i]); + } if (len > size) len = size; diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 1e5078bd0344..cd2db3fd7b7e 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -102,6 +102,9 @@ struct ath_interrupt_stats { * @desc_cfg_err: Descriptor configuration errors * @data_urn: TX data underrun errors * @delim_urn: TX delimiter underrun errors + * @puttxbuf: Number of times hardware was given txbuf to write. + * @txstart: Number of times hardware was told to start tx. + * @txprocdesc: Number of times tx descriptor was processed */ struct ath_tx_stats { u32 tx_pkts_all; @@ -119,6 +122,9 @@ struct ath_tx_stats { u32 desc_cfg_err; u32 data_underrun; u32 delim_underrun; + u32 puttxbuf; + u32 txstart; + u32 txprocdesc; }; /** diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index c75d40fb86f1..5f2b93441e5c 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -16,6 +16,8 @@ #include "hw.h" #include "hw-ops.h" +#include "debug.h" +#include "ath9k.h" static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah, struct ath9k_tx_queue_info *qi) @@ -50,12 +52,18 @@ EXPORT_SYMBOL(ath9k_hw_gettxbuf); void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp) { + struct ath_wiphy *aphy = ah->hw->priv; + struct ath_softc *sc = aphy->sc; + TX_STAT_INC(q, puttxbuf); REG_WRITE(ah, AR_QTXDP(q), txdp); } EXPORT_SYMBOL(ath9k_hw_puttxbuf); void ath9k_hw_txstart(struct ath_hw *ah, u32 q) { + struct ath_wiphy *aphy = ah->hw->priv; + struct ath_softc *sc = aphy->sc; + TX_STAT_INC(q, txstart); ath_dbg(ath9k_hw_common(ah), ATH_DBG_QUEUE, "Enable TXE on queue: %u\n", q); REG_WRITE(ah, AR_Q_TXE, 1 << q); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index ad569e152d78..aa67d641f140 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -2039,6 +2039,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) spin_unlock_bh(&txq->axq_lock); break; } + TX_STAT_INC(txq->axq_qnum, txprocdesc); /* * Remove ath_buf's of the same transmit unit from txq, -- cgit v1.2.3 From 9244f48d0052ae17b4af70bfc46ad544c4c06a50 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Sun, 9 Jan 2011 23:11:46 -0800 Subject: ath9k: Remove un-used member from ath_node. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 6e22135a96ac..aadb5de9ac76 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -342,7 +342,6 @@ struct ath_vif { __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ enum nl80211_iftype av_opmode; struct ath_buf *av_bcbuf; - struct ath_tx_control av_btxctl; u8 bssid[ETH_ALEN]; /* current BSSID from config_interface */ }; -- cgit v1.2.3 From 082f65368991f6bb7499c379754505cb674708b1 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Sun, 9 Jan 2011 23:11:47 -0800 Subject: ath9k: Ensure xmit makes progress. If the txq->axq_q is empty, the code was breaking out of the tx_processq logic without checking to see if it should transmit other queued AMPDU frames (txq->axq_acq). This patches ensures ath_txq_schedule is called. This needs review. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index aa67d641f140..f6de2271b9d4 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -2005,6 +2005,8 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) spin_lock_bh(&txq->axq_lock); if (list_empty(&txq->axq_q)) { txq->axq_link = NULL; + if (sc->sc_flags & SC_OP_TXAGGR) + ath_txq_schedule(sc, txq); spin_unlock_bh(&txq->axq_lock); break; } -- cgit v1.2.3 From bda8addaed08834956d5695212717893a2e0cb13 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Sun, 9 Jan 2011 23:11:48 -0800 Subject: ath9k: Add counters to distinquish AMPDU enqueues. Show counters for pkts sent directly to hardware and those queued in software. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 3 ++- drivers/net/wireless/ath/ath9k/debug.h | 6 ++++-- drivers/net/wireless/ath/ath9k/xmit.c | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 577bc5a9835b..faf84e499c8f 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -628,7 +628,8 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, PR("MPDUs Queued: ", queued); PR("MPDUs Completed: ", completed); PR("Aggregates: ", a_aggr); - PR("AMPDUs Queued: ", a_queued); + PR("AMPDUs Queued HW:", a_queued_hw); + PR("AMPDUs Queued SW:", a_queued_sw); PR("AMPDUs Completed:", a_completed); PR("AMPDUs Retried: ", a_retries); PR("AMPDUs XRetried: ", a_xretries); diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index cd2db3fd7b7e..980c9fa194b9 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -89,7 +89,8 @@ struct ath_interrupt_stats { * @queued: Total MPDUs (non-aggr) queued * @completed: Total MPDUs (non-aggr) completed * @a_aggr: Total no. of aggregates queued - * @a_queued: Total AMPDUs queued + * @a_queued_hw: Total AMPDUs queued to hardware + * @a_queued_sw: Total AMPDUs queued to software queues * @a_completed: Total AMPDUs completed * @a_retries: No. of AMPDUs retried (SW) * @a_xretries: No. of AMPDUs dropped due to xretries @@ -112,7 +113,8 @@ struct ath_tx_stats { u32 queued; u32 completed; u32 a_aggr; - u32 a_queued; + u32 a_queued_hw; + u32 a_queued_sw; u32 a_completed; u32 a_retries; u32 a_xretries; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index f6de2271b9d4..a83f2c54508c 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1341,7 +1341,6 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, struct list_head bf_head; bf->bf_state.bf_type |= BUF_AMPDU; - TX_STAT_INC(txctl->txq->axq_qnum, a_queued); /* * Do not queue to h/w when any of the following conditions is true: @@ -1357,6 +1356,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, * Add this frame to software queue for scheduling later * for aggregation. */ + TX_STAT_INC(txctl->txq->axq_qnum, a_queued_sw); list_add_tail(&bf->list, &tid->buf_q); ath_tx_queue_tid(txctl->txq, tid); return; @@ -1370,6 +1370,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, ath_tx_addto_baw(sc, tid, fi->seqno); /* Queue to h/w without aggregation */ + TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw); bf->bf_lastbf = bf; ath_buf_set_rate(sc, bf, fi->framelen); ath_tx_txqaddbuf(sc, txctl->txq, &bf_head); -- cgit v1.2.3 From 7f010c93d73847ffc6b74b572fef9a63e305d65e Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Sun, 9 Jan 2011 23:11:49 -0800 Subject: ath9k: Keep track of stations for debugfs. The stations hold the ath_node, which holds the tid and other xmit logic structures. In order to debug stuck xmit logic, we need a way to print out the tid state for the stations. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 7 ++- drivers/net/wireless/ath/ath9k/debug.c | 94 +++++++++++++++++++++++++++++++++- drivers/net/wireless/ath/ath9k/init.c | 4 ++ drivers/net/wireless/ath/ath9k/main.c | 13 +++++ 4 files changed, 115 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index aadb5de9ac76..d4640117fa8c 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -254,7 +254,10 @@ struct ath_atx_tid { }; struct ath_node { - struct ath_common *common; +#ifdef CONFIG_ATH9K_DEBUGFS + struct list_head list; /* for sc->nodes */ + struct ieee80211_sta *sta; /* station struct we're part of */ +#endif struct ath_atx_tid tid[WME_NUM_TID]; struct ath_atx_ac ac[WME_NUM_AC]; u16 maxampdu; @@ -638,6 +641,8 @@ struct ath_softc { #ifdef CONFIG_ATH9K_DEBUGFS struct ath9k_debug debug; + spinlock_t nodes_lock; + struct list_head nodes; /* basically, stations */ #endif struct ath_beacon_config cur_beacon_conf; struct delayed_work tx_complete_work; diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index faf84e499c8f..650f00f59d79 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -587,6 +587,8 @@ static const struct file_operations fops_wiphy = { sc->debug.stats.txstats[WME_AC_BK].elem, \ sc->debug.stats.txstats[WME_AC_VI].elem, \ sc->debug.stats.txstats[WME_AC_VO].elem); \ + if (len >= size) \ + goto done; \ } while(0) #define PRX(str, elem) \ @@ -597,6 +599,8 @@ do { \ (unsigned int)(sc->tx.txq[WME_AC_BK].elem), \ (unsigned int)(sc->tx.txq[WME_AC_VI].elem), \ (unsigned int)(sc->tx.txq[WME_AC_VO].elem)); \ + if (len >= size) \ + goto done; \ } while(0) #define PRQLE(str, elem) \ @@ -607,6 +611,8 @@ do { \ list_empty(&sc->tx.txq[WME_AC_BK].elem), \ list_empty(&sc->tx.txq[WME_AC_VI].elem), \ list_empty(&sc->tx.txq[WME_AC_VO].elem)); \ + if (len >= size) \ + goto done; \ } while (0) static ssize_t read_file_xmit(struct file *file, char __user *user_buf, @@ -614,7 +620,7 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, { struct ath_softc *sc = file->private_data; char *buf; - unsigned int len = 0, size = 4000; + unsigned int len = 0, size = 8000; int i; ssize_t retval = 0; char tmp[32]; @@ -623,7 +629,10 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, if (buf == NULL) return -ENOMEM; - len += sprintf(buf, "%30s %10s%10s%10s\n\n", "BE", "BK", "VI", "VO"); + len += sprintf(buf, "Num-Tx-Queues: %i tx-queues-setup: 0x%x\n" + "%30s %10s%10s%10s\n\n", + ATH9K_NUM_TX_QUEUES, sc->tx.txqsetup, + "BE", "BK", "VI", "VO"); PR("MPDUs Queued: ", queued); PR("MPDUs Completed: ", completed); @@ -644,6 +653,14 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, PR("hw-put-tx-buf: ", puttxbuf); PR("hw-tx-start: ", txstart); PR("hw-tx-proc-desc: ", txprocdesc); + len += snprintf(buf + len, size - len, + "%s%11p%11p%10p%10p\n", "txq-memory-address:", + &(sc->tx.txq[WME_AC_BE]), + &(sc->tx.txq[WME_AC_BK]), + &(sc->tx.txq[WME_AC_VI]), + &(sc->tx.txq[WME_AC_VO])); + if (len >= size) + goto done; PRX("axq-qnum: ", axq_qnum); PRX("axq-depth: ", axq_depth); @@ -661,6 +678,68 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, snprintf(tmp, sizeof(tmp) - 1, "txq_fifo[%i] empty: ", i); PRQLE(tmp, txq_fifo[i]); } + +done: + if (len > size) + len = size; + + retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); + kfree(buf); + + return retval; +} + +static ssize_t read_file_stations(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath_softc *sc = file->private_data; + char *buf; + unsigned int len = 0, size = 64000; + struct ath_node *an = NULL; + ssize_t retval = 0; + int q; + + buf = kzalloc(size, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + + len += snprintf(buf + len, size - len, + "Stations:\n" + " tid: addr sched paused buf_q-empty an ac\n" + " ac: addr sched tid_q-empty txq\n"); + + spin_lock(&sc->nodes_lock); + list_for_each_entry(an, &sc->nodes, list) { + len += snprintf(buf + len, size - len, + "%pM\n", an->sta->addr); + if (len >= size) + goto done; + + for (q = 0; q < WME_NUM_TID; q++) { + struct ath_atx_tid *tid = &(an->tid[q]); + len += snprintf(buf + len, size - len, + " tid: %p %s %s %i %p %p\n", + tid, tid->sched ? "sched" : "idle", + tid->paused ? "paused" : "running", + list_empty(&tid->buf_q), + tid->an, tid->ac); + if (len >= size) + goto done; + } + + for (q = 0; q < WME_NUM_AC; q++) { + struct ath_atx_ac *ac = &(an->ac[q]); + len += snprintf(buf + len, size - len, + " ac: %p %s %i %p\n", + ac, ac->sched ? "sched" : "idle", + list_empty(&ac->tid_q), ac->txq); + if (len >= size) + goto done; + } + } + +done: + spin_unlock(&sc->nodes_lock); if (len > size) len = size; @@ -708,6 +787,13 @@ static const struct file_operations fops_xmit = { .llseek = default_llseek, }; +static const struct file_operations fops_stations = { + .read = read_file_stations, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + static ssize_t read_file_recv(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -945,6 +1031,10 @@ int ath9k_init_debug(struct ath_hw *ah) sc, &fops_xmit)) goto err; + if (!debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, + sc, &fops_stations)) + goto err; + if (!debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_recv)) goto err; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 23b299818b18..59c01ca4379e 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -559,6 +559,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, spin_lock_init(&sc->sc_serial_rw); spin_lock_init(&sc->sc_pm_lock); mutex_init(&sc->mutex); +#ifdef CONFIG_ATH9K_DEBUGFS + spin_lock_init(&sc->nodes_lock); + INIT_LIST_HEAD(&sc->nodes); +#endif tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, (unsigned long)sc); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c03184e7bffe..bed6eb97fac9 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -548,6 +548,12 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) struct ath_hw *ah = sc->sc_ah; an = (struct ath_node *)sta->drv_priv; +#ifdef CONFIG_ATH9K_DEBUGFS + spin_lock(&sc->nodes_lock); + list_add(&an->list, &sc->nodes); + spin_unlock(&sc->nodes_lock); + an->sta = sta; +#endif if ((ah->caps.hw_caps) & ATH9K_HW_CAP_APM) sc->sc_flags |= SC_OP_ENABLE_APM; @@ -563,6 +569,13 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) { struct ath_node *an = (struct ath_node *)sta->drv_priv; +#ifdef CONFIG_ATH9K_DEBUGFS + spin_lock(&sc->nodes_lock); + list_del(&an->list); + spin_unlock(&sc->nodes_lock); + an->sta = NULL; +#endif + if (sc->sc_flags & SC_OP_TXAGGR) ath_tx_node_cleanup(sc, an); } -- cgit v1.2.3 From 71e025a5a630681ad8b37d4426a994d199976ec9 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Sun, 9 Jan 2011 23:11:50 -0800 Subject: ath9k: More xmit queue debugfs information. To try to figure out why xmit logic hangs. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 650f00f59d79..9e009ccd0069 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -679,6 +679,32 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, PRQLE(tmp, txq_fifo[i]); } + /* Print out more detailed queue-info */ + for (i = 0; i <= WME_AC_BK; i++) { + struct ath_txq *txq = &(sc->tx.txq[i]); + struct ath_atx_ac *ac; + struct ath_atx_tid *tid; + if (len >= size) + goto done; + spin_lock_bh(&txq->axq_lock); + if (!list_empty(&txq->axq_acq)) { + ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, + list); + len += snprintf(buf + len, size - len, + "txq[%i] first-ac: %p sched: %i\n", + i, ac, ac->sched); + if (list_empty(&ac->tid_q) || (len >= size)) + goto done_for; + tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, + list); + len += snprintf(buf + len, size - len, + " first-tid: %p sched: %i paused: %i\n", + tid, tid->sched, tid->paused); + } + done_for: + spin_unlock_bh(&txq->axq_lock); + } + done: if (len > size) len = size; -- cgit v1.2.3 From 60f2d1d506195803fa6e1dcf3972637b740fdd60 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Sun, 9 Jan 2011 23:11:52 -0800 Subject: ath9k: Restart xmit logic in xmit watchdog. The system can get into a state where the xmit queue is stopped, but there are no packets pending, so the queue will not be restarted. Add logic to the xmit watchdog to attempt to restart the xmit logic if this situation is detected. Example 'dmesg' output: ath: txq: f4e723e0 axq_qnum: 2, mac80211_qnum: 2 axq_link: f4e996c8 pending frames: 1 axq_acq empty: 1 stopped: 0 axq_depth: 0 Attempting to restart tx logic. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 9 +++- drivers/net/wireless/ath/ath9k/debug.c | 4 +- drivers/net/wireless/ath/ath9k/init.c | 5 ++- drivers/net/wireless/ath/ath9k/xmit.c | 79 +++++++++++++++++++++++----------- 4 files changed, 68 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index d4640117fa8c..dab0271f1c1a 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -184,7 +184,8 @@ enum ATH_AGGR_STATUS { #define ATH_TXFIFO_DEPTH 8 struct ath_txq { - u32 axq_qnum; + int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */ + u32 axq_qnum; /* ath9k hardware queue number */ u32 *axq_link; struct list_head axq_q; spinlock_t axq_lock; @@ -280,6 +281,11 @@ struct ath_tx_control { #define ATH_TX_XRETRY 0x02 #define ATH_TX_BAR 0x04 +/** + * @txq_map: Index is mac80211 queue number. This is + * not necessarily the same as the hardware queue number + * (axq_qnum). + */ struct ath_tx { u16 seq_no; u32 txqsetup; @@ -643,6 +649,7 @@ struct ath_softc { struct ath9k_debug debug; spinlock_t nodes_lock; struct list_head nodes; /* basically, stations */ + unsigned int tx_complete_poll_work_seen; #endif struct ath_beacon_config cur_beacon_conf; struct delayed_work tx_complete_work; diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 9e009ccd0069..b0cb792d38ca 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -629,9 +629,11 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, if (buf == NULL) return -ENOMEM; - len += sprintf(buf, "Num-Tx-Queues: %i tx-queues-setup: 0x%x\n" + len += sprintf(buf, "Num-Tx-Queues: %i tx-queues-setup: 0x%x" + " poll-work-seen: %u\n" "%30s %10s%10s%10s\n\n", ATH9K_NUM_TX_QUEUES, sc->tx.txqsetup, + sc->tx_complete_poll_work_seen, "BE", "BK", "VI", "VO"); PR("MPDUs Queued: ", queued); diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 59c01ca4379e..5279653c90c7 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -442,9 +442,10 @@ static int ath9k_init_queues(struct ath_softc *sc) sc->config.cabqReadytime = ATH_CABQ_READY_TIME; ath_cabq_update(sc); - for (i = 0; i < WME_NUM_AC; i++) + for (i = 0; i < WME_NUM_AC; i++) { sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i); - + sc->tx.txq_map[i]->mac80211_qnum = i; + } return 0; } diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index a83f2c54508c..2ad732d36f86 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -945,7 +945,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) [WME_AC_VI] = ATH_TXQ_AC_VI, [WME_AC_VO] = ATH_TXQ_AC_VO, }; - int qnum, i; + int axq_qnum, i; memset(&qi, 0, sizeof(qi)); qi.tqi_subtype = subtype_txq_to_hwq[subtype]; @@ -979,24 +979,25 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE | TXQ_FLAG_TXDESCINT_ENABLE; } - qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi); - if (qnum == -1) { + axq_qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi); + if (axq_qnum == -1) { /* * NB: don't print a message, this happens * normally on parts with too few tx queues */ return NULL; } - if (qnum >= ARRAY_SIZE(sc->tx.txq)) { + if (axq_qnum >= ARRAY_SIZE(sc->tx.txq)) { ath_err(common, "qnum %u out of range, max %zu!\n", - qnum, ARRAY_SIZE(sc->tx.txq)); - ath9k_hw_releasetxqueue(ah, qnum); + axq_qnum, ARRAY_SIZE(sc->tx.txq)); + ath9k_hw_releasetxqueue(ah, axq_qnum); return NULL; } - if (!ATH_TXQ_SETUP(sc, qnum)) { - struct ath_txq *txq = &sc->tx.txq[qnum]; + if (!ATH_TXQ_SETUP(sc, axq_qnum)) { + struct ath_txq *txq = &sc->tx.txq[axq_qnum]; - txq->axq_qnum = qnum; + txq->axq_qnum = axq_qnum; + txq->mac80211_qnum = -1; txq->axq_link = NULL; INIT_LIST_HEAD(&txq->axq_q); INIT_LIST_HEAD(&txq->axq_acq); @@ -1004,14 +1005,14 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) txq->axq_depth = 0; txq->axq_ampdu_depth = 0; txq->axq_tx_inprogress = false; - sc->tx.txqsetup |= 1<tx.txqsetup |= 1<txq_headidx = txq->txq_tailidx = 0; for (i = 0; i < ATH_TXFIFO_DEPTH; i++) INIT_LIST_HEAD(&txq->txq_fifo[i]); INIT_LIST_HEAD(&txq->txq_fifo_pending); } - return &sc->tx.txq[qnum]; + return &sc->tx.txq[axq_qnum]; } int ath_txq_update(struct ath_softc *sc, int qnum, @@ -1973,17 +1974,16 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; } -static void ath_wake_mac80211_queue(struct ath_softc *sc, int qnum) +/* Has no locking. Must hold spin_lock_bh(&txq->axq_lock) + * before calling this. + */ +static void __ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) { - struct ath_txq *txq; - - txq = sc->tx.txq_map[qnum]; - spin_lock_bh(&txq->axq_lock); - if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) { - if (ath_mac80211_start_queue(sc, qnum)) + if (txq->mac80211_qnum >= 0 && + txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) { + if (ath_mac80211_start_queue(sc, txq->mac80211_qnum)) txq->stopped = 0; } - spin_unlock_bh(&txq->axq_lock); } static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) @@ -2086,10 +2086,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) else ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0); - if (txq == sc->tx.txq_map[qnum]) - ath_wake_mac80211_queue(sc, qnum); - spin_lock_bh(&txq->axq_lock); + __ath_wake_mac80211_queue(sc, txq); + if (sc->sc_flags & SC_OP_TXAGGR) ath_txq_schedule(sc, txq); spin_unlock_bh(&txq->axq_lock); @@ -2103,6 +2102,9 @@ static void ath_tx_complete_poll_work(struct work_struct *work) struct ath_txq *txq; int i; bool needreset = false; +#ifdef CONFIG_ATH9K_DEBUGFS + sc->tx_complete_poll_work_seen++; +#endif for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) if (ATH_TXQ_SETUP(sc, i)) { @@ -2116,6 +2118,34 @@ static void ath_tx_complete_poll_work(struct work_struct *work) } else { txq->axq_tx_inprogress = true; } + } else { + /* If the queue has pending buffers, then it + * should be doing tx work (and have axq_depth). + * Shouldn't get to this state I think..but + * we do. + */ + if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) && + (txq->pending_frames > 0 || + !list_empty(&txq->axq_acq) || + txq->stopped)) { + ath_err(ath9k_hw_common(sc->sc_ah), + "txq: %p axq_qnum: %u," + " mac80211_qnum: %i" + " axq_link: %p" + " pending frames: %i" + " axq_acq empty: %i" + " stopped: %i" + " axq_depth: 0 Attempting to" + " restart tx logic.\n", + txq, txq->axq_qnum, + txq->mac80211_qnum, + txq->axq_link, + txq->pending_frames, + list_empty(&txq->axq_acq), + txq->stopped); + __ath_wake_mac80211_queue(sc, txq); + ath_txq_schedule(sc, txq); + } } spin_unlock_bh(&txq->axq_lock); } @@ -2212,10 +2242,9 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) ath_tx_complete_buf(sc, bf, txq, &bf_head, &txs, txok, 0); - if (txq == sc->tx.txq_map[qnum]) - ath_wake_mac80211_queue(sc, qnum); - spin_lock_bh(&txq->axq_lock); + __ath_wake_mac80211_queue(sc, txq); + if (!list_empty(&txq->txq_fifo_pending)) { INIT_LIST_HEAD(&bf_head); bf = list_first_entry(&txq->txq_fifo_pending, -- cgit v1.2.3 From 59eb21a6504731fc16db4cf9463065dd61093e08 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Mon, 17 Jan 2011 13:37:28 +0900 Subject: cfg80211: Extend channel to frequency mapping for 802.11j Extend channel to frequency mapping for 802.11j Japan 4.9GHz band, according to IEEE802.11 section 17.3.8.3.2 and Annex J. Because there are now overlapping channel numbers in the 2GHz and 5GHz band we can't map from channel to frequency without knowing the band. This is no problem as in most contexts we know the band. In places where we don't know the band (and WEXT compatibility) we assume the 2GHz band for channels below 14. This patch does not implement all channel to frequency mappings defined in 802.11, it's just an extension for 802.11j 20MHz channels. 5MHz and 10MHz channels as well as 802.11y channels have been omitted. The following drivers have been updated to reflect the API changes: iwl-3945, iwl-agn, iwmc3200wifi, libertas, mwl8k, rt2x00, wl1251, wl12xx. The drivers have been compile-tested only. Signed-off-by: Bruno Randolf Signed-off-by: Brian Prodoehl Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945.c | 5 ++-- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 5 ++-- drivers/net/wireless/iwlwifi/iwl-core.c | 3 ++- drivers/net/wireless/iwmc3200wifi/cfg80211.c | 3 ++- drivers/net/wireless/iwmc3200wifi/rx.c | 7 ++++-- drivers/net/wireless/libertas/cfg.c | 6 +++-- drivers/net/wireless/mwl8k.c | 6 +++-- drivers/net/wireless/rt2x00/rt2x00dev.c | 5 +++- drivers/net/wireless/wl1251/rx.c | 3 ++- drivers/net/wireless/wl12xx/rx.c | 2 +- include/net/cfg80211.h | 3 ++- net/mac80211/ibss.c | 3 ++- net/mac80211/mesh.c | 2 +- net/mac80211/mlme.c | 8 ++++--- net/mac80211/scan.c | 3 ++- net/wireless/reg.c | 6 ++--- net/wireless/util.c | 36 +++++++++++++++++----------- net/wireless/wext-compat.c | 5 +++- 18 files changed, 71 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index a9b852be4509..1d9dcd7e3b82 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -594,10 +594,11 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, rx_status.flag = 0; rx_status.mactime = le64_to_cpu(rx_end->timestamp); - rx_status.freq = - ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel)); rx_status.band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; + rx_status.freq = + ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel), + rx_status.band); rx_status.rate_idx = iwl3945_hwrate_to_plcp_idx(rx_hdr->rate); if (rx_status.band == IEEE80211_BAND_5GHZ) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 29dcda0bde65..c7d03874b380 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1162,10 +1162,11 @@ void iwlagn_rx_reply_rx(struct iwl_priv *priv, /* rx_status carries information about the packet to mac80211 */ rx_status.mactime = le64_to_cpu(phy_res->timestamp); - rx_status.freq = - ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel)); rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; + rx_status.freq = + ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel), + rx_status.band); rx_status.rate_idx = iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band); rx_status.flag = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index efbde1f1a8bf..a8d4a936a2e7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -227,7 +227,8 @@ int iwlcore_init_geos(struct iwl_priv *priv) geo_ch = &sband->channels[sband->n_channels++]; geo_ch->center_freq = - ieee80211_channel_to_frequency(ch->channel); + ieee80211_channel_to_frequency(ch->channel, + sband->band); geo_ch->max_power = ch->max_power_avg; geo_ch->max_antenna_gain = 0xff; geo_ch->hw_value = ch->channel; diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c index 5a4982271e96..ed57e4402800 100644 --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c @@ -287,7 +287,8 @@ int iwm_cfg80211_inform_bss(struct iwm_priv *iwm) return -EINVAL; } - freq = ieee80211_channel_to_frequency(umac_bss->channel); + freq = ieee80211_channel_to_frequency(umac_bss->channel, + band->band); channel = ieee80211_get_channel(wiphy, freq); signal = umac_bss->rssi * 100; diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c index a944893ae3ca..9a57cf6a488f 100644 --- a/drivers/net/wireless/iwmc3200wifi/rx.c +++ b/drivers/net/wireless/iwmc3200wifi/rx.c @@ -543,7 +543,10 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf, switch (le32_to_cpu(complete->status)) { case UMAC_ASSOC_COMPLETE_SUCCESS: chan = ieee80211_get_channel(wiphy, - ieee80211_channel_to_frequency(complete->channel)); + ieee80211_channel_to_frequency(complete->channel, + complete->band == UMAC_BAND_2GHZ ? + IEEE80211_BAND_2GHZ : + IEEE80211_BAND_5GHZ)); if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) { /* Associated to a unallowed channel, disassociate. */ __iwm_invalidate_mlme_profile(iwm); @@ -841,7 +844,7 @@ static int iwm_mlme_update_bss_table(struct iwm_priv *iwm, u8 *buf, goto err; } - freq = ieee80211_channel_to_frequency(umac_bss->channel); + freq = ieee80211_channel_to_frequency(umac_bss->channel, band->band); channel = ieee80211_get_channel(wiphy, freq); signal = umac_bss->rssi * 100; diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 698a1f7694ed..30ef0351bfc4 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -607,7 +607,8 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, /* No channel, no luck */ if (chan_no != -1) { struct wiphy *wiphy = priv->wdev->wiphy; - int freq = ieee80211_channel_to_frequency(chan_no); + int freq = ieee80211_channel_to_frequency(chan_no, + IEEE80211_BAND_2GHZ); struct ieee80211_channel *channel = ieee80211_get_channel(wiphy, freq); @@ -1597,7 +1598,8 @@ static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev, lbs_deb_enter(LBS_DEB_CFG80211); survey->channel = ieee80211_get_channel(wiphy, - ieee80211_channel_to_frequency(priv->channel)); + ieee80211_channel_to_frequency(priv->channel, + IEEE80211_BAND_2GHZ)); ret = lbs_get_rssi(priv, &signal, &noise); if (ret == 0) { diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 106b427d0064..af4f2c64f242 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -906,7 +906,8 @@ mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status, } else { status->band = IEEE80211_BAND_2GHZ; } - status->freq = ieee80211_channel_to_frequency(rxd->channel); + status->freq = ieee80211_channel_to_frequency(rxd->channel, + status->band); *qos = rxd->qos_control; @@ -1013,7 +1014,8 @@ mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status, } else { status->band = IEEE80211_BAND_2GHZ; } - status->freq = ieee80211_channel_to_frequency(rxd->channel); + status->freq = ieee80211_channel_to_frequency(rxd->channel, + status->band); *qos = rxd->qos_control; if ((rxd->rx_ctrl & MWL8K_STA_RX_CTRL_DECRYPT_ERROR) && diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 9597a03242cc..31b7db05abd9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -649,7 +649,10 @@ static void rt2x00lib_channel(struct ieee80211_channel *entry, const int channel, const int tx_power, const int value) { - entry->center_freq = ieee80211_channel_to_frequency(channel); + /* XXX: this assumption about the band is wrong for 802.11j */ + entry->band = channel <= 14 ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; + entry->center_freq = ieee80211_channel_to_frequency(channel, + entry->band); entry->hw_value = value; entry->max_power = tx_power; entry->max_antenna_gain = 0xff; diff --git a/drivers/net/wireless/wl1251/rx.c b/drivers/net/wireless/wl1251/rx.c index efa53607d5c9..86eef456d7b2 100644 --- a/drivers/net/wireless/wl1251/rx.c +++ b/drivers/net/wireless/wl1251/rx.c @@ -78,7 +78,8 @@ static void wl1251_rx_status(struct wl1251 *wl, */ wl->noise = desc->rssi - desc->snr / 2; - status->freq = ieee80211_channel_to_frequency(desc->channel); + status->freq = ieee80211_channel_to_frequency(desc->channel, + status->band); status->flag |= RX_FLAG_TSFT; diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c index 682304c30b81..ec8d843d41cf 100644 --- a/drivers/net/wireless/wl12xx/rx.c +++ b/drivers/net/wireless/wl12xx/rx.c @@ -76,7 +76,7 @@ static void wl1271_rx_status(struct wl1271 *wl, */ wl->noise = desc->rssi - (desc->snr >> 1); - status->freq = ieee80211_channel_to_frequency(desc->channel); + status->freq = ieee80211_channel_to_frequency(desc->channel, desc_band); if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) { status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 1322695beb52..679a0494b5f2 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1790,8 +1790,9 @@ static inline void *wdev_priv(struct wireless_dev *wdev) /** * ieee80211_channel_to_frequency - convert channel number to frequency * @chan: channel number + * @band: band, necessary due to channel number overlap */ -extern int ieee80211_channel_to_frequency(int chan); +extern int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band); /** * ieee80211_frequency_to_channel - convert frequency to channel number diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 53c7077ffd4f..775fb63471c4 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -270,7 +270,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, enum ieee80211_band band = rx_status->band; if (elems->ds_params && elems->ds_params_len == 1) - freq = ieee80211_channel_to_frequency(elems->ds_params[0]); + freq = ieee80211_channel_to_frequency(elems->ds_params[0], + band); else freq = rx_status->freq; diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 2563fd1ea998..2a57cc02c618 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -574,7 +574,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, &elems); if (elems.ds_params && elems.ds_params_len == 1) - freq = ieee80211_channel_to_frequency(elems.ds_params[0]); + freq = ieee80211_channel_to_frequency(elems.ds_params[0], band); else freq = rx_status->freq; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index eecbb1fcd2ab..32210695b8b6 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -176,7 +176,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, /* check that channel matches the right operating channel */ if (local->hw.conf.channel->center_freq != - ieee80211_channel_to_frequency(hti->control_chan)) + ieee80211_channel_to_frequency(hti->control_chan, sband->band)) enable_ht = false; if (enable_ht) { @@ -429,7 +429,8 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, container_of((void *)bss, struct cfg80211_bss, priv); struct ieee80211_channel *new_ch; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; - int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num); + int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num, + cbss->channel->band); ASSERT_MGD_MTX(ifmgd); @@ -1519,7 +1520,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, } if (elems->ds_params && elems->ds_params_len == 1) - freq = ieee80211_channel_to_frequency(elems->ds_params[0]); + freq = ieee80211_channel_to_frequency(elems->ds_params[0], + rx_status->band); else freq = rx_status->freq; diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index fb274db77e3c..1ef73be76b25 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -196,7 +196,8 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) ieee802_11_parse_elems(elements, skb->len - baselen, &elems); if (elems.ds_params && elems.ds_params_len == 1) - freq = ieee80211_channel_to_frequency(elems.ds_params[0]); + freq = ieee80211_channel_to_frequency(elems.ds_params[0], + rx_status->band); else freq = rx_status->freq; diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 37693b6ef23a..c565689f0b9f 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1801,9 +1801,9 @@ void regulatory_hint_disconnect(void) static bool freq_is_chan_12_13_14(u16 freq) { - if (freq == ieee80211_channel_to_frequency(12) || - freq == ieee80211_channel_to_frequency(13) || - freq == ieee80211_channel_to_frequency(14)) + if (freq == ieee80211_channel_to_frequency(12, IEEE80211_BAND_2GHZ) || + freq == ieee80211_channel_to_frequency(13, IEEE80211_BAND_2GHZ) || + freq == ieee80211_channel_to_frequency(14, IEEE80211_BAND_2GHZ)) return true; return false; } diff --git a/net/wireless/util.c b/net/wireless/util.c index 7620ae2fcf18..4ed065d8bb51 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -29,29 +29,37 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband, } EXPORT_SYMBOL(ieee80211_get_response_rate); -int ieee80211_channel_to_frequency(int chan) +int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band) { - if (chan < 14) - return 2407 + chan * 5; - - if (chan == 14) - return 2484; - - /* FIXME: 802.11j 17.3.8.3.2 */ - return (chan + 1000) * 5; + /* see 802.11 17.3.8.3.2 and Annex J + * there are overlapping channel numbers in 5GHz and 2GHz bands */ + if (band == IEEE80211_BAND_5GHZ) { + if (chan >= 182 && chan <= 196) + return 4000 + chan * 5; + else + return 5000 + chan * 5; + } else { /* IEEE80211_BAND_2GHZ */ + if (chan == 14) + return 2484; + else if (chan < 14) + return 2407 + chan * 5; + else + return 0; /* not supported */ + } } EXPORT_SYMBOL(ieee80211_channel_to_frequency); int ieee80211_frequency_to_channel(int freq) { + /* see 802.11 17.3.8.3.2 and Annex J */ if (freq == 2484) return 14; - - if (freq < 2484) + else if (freq < 2484) return (freq - 2407) / 5; - - /* FIXME: 802.11j 17.3.8.3.2 */ - return freq/5 - 1000; + else if (freq >= 4910 && freq <= 4980) + return (freq - 4000) / 5; + else + return (freq - 5000) / 5; } EXPORT_SYMBOL(ieee80211_frequency_to_channel); diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 3e5dbd4e4cd5..7f1f4ec49041 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -267,9 +267,12 @@ int cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq) * -EINVAL for impossible things. */ if (freq->e == 0) { + enum ieee80211_band band = IEEE80211_BAND_2GHZ; if (freq->m < 0) return 0; - return ieee80211_channel_to_frequency(freq->m); + if (freq->m > 14) + band = IEEE80211_BAND_5GHZ; + return ieee80211_channel_to_frequency(freq->m, band); } else { int i, div = 1000000; for (i = 0; i < freq->e; i++) -- cgit v1.2.3 From 55f6d0fff64dfee57812e821f846b068a8c2df01 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Mon, 17 Jan 2011 11:54:50 -0800 Subject: ath9k: Add 'misc' file to debugfs, fix queue indexes. Add a misc file to show hardware op-mode, irq setup, number of various types of VIFs and more. Also, previous patches were using the wrong xmit queue indexes. Change to use the internal ath9k indexes instead of the mac80211 queue indexes. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 137 ++++++++++++++++++++++++++++++--- 1 file changed, 125 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index b0cb792d38ca..f0c80ec290d1 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -595,10 +595,10 @@ static const struct file_operations fops_wiphy = { do { \ len += snprintf(buf + len, size - len, \ "%s%13u%11u%10u%10u\n", str, \ - (unsigned int)(sc->tx.txq[WME_AC_BE].elem), \ - (unsigned int)(sc->tx.txq[WME_AC_BK].elem), \ - (unsigned int)(sc->tx.txq[WME_AC_VI].elem), \ - (unsigned int)(sc->tx.txq[WME_AC_VO].elem)); \ + (unsigned int)(sc->tx.txq[ATH_TXQ_AC_BE].elem), \ + (unsigned int)(sc->tx.txq[ATH_TXQ_AC_BK].elem), \ + (unsigned int)(sc->tx.txq[ATH_TXQ_AC_VI].elem), \ + (unsigned int)(sc->tx.txq[ATH_TXQ_AC_VO].elem)); \ if (len >= size) \ goto done; \ } while(0) @@ -607,10 +607,10 @@ do { \ do { \ len += snprintf(buf + len, size - len, \ "%s%13i%11i%10i%10i\n", str, \ - list_empty(&sc->tx.txq[WME_AC_BE].elem), \ - list_empty(&sc->tx.txq[WME_AC_BK].elem), \ - list_empty(&sc->tx.txq[WME_AC_VI].elem), \ - list_empty(&sc->tx.txq[WME_AC_VO].elem)); \ + list_empty(&sc->tx.txq[ATH_TXQ_AC_BE].elem), \ + list_empty(&sc->tx.txq[ATH_TXQ_AC_BK].elem), \ + list_empty(&sc->tx.txq[ATH_TXQ_AC_VI].elem), \ + list_empty(&sc->tx.txq[ATH_TXQ_AC_VO].elem)); \ if (len >= size) \ goto done; \ } while (0) @@ -657,10 +657,10 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, PR("hw-tx-proc-desc: ", txprocdesc); len += snprintf(buf + len, size - len, "%s%11p%11p%10p%10p\n", "txq-memory-address:", - &(sc->tx.txq[WME_AC_BE]), - &(sc->tx.txq[WME_AC_BK]), - &(sc->tx.txq[WME_AC_VI]), - &(sc->tx.txq[WME_AC_VO])); + &(sc->tx.txq[ATH_TXQ_AC_BE]), + &(sc->tx.txq[ATH_TXQ_AC_BK]), + &(sc->tx.txq[ATH_TXQ_AC_VI]), + &(sc->tx.txq[ATH_TXQ_AC_VO])); if (len >= size) goto done; @@ -777,6 +777,108 @@ done: return retval; } +static ssize_t read_file_misc(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath_softc *sc = file->private_data; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_hw *ah = sc->sc_ah; + struct ieee80211_hw *hw = sc->hw; + char *buf; + unsigned int len = 0, size = 8000; + ssize_t retval = 0; + const char *tmp; + unsigned int reg; + struct ath9k_vif_iter_data iter_data; + + ath9k_calculate_iter_data(hw, NULL, &iter_data); + + buf = kzalloc(size, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + + switch (sc->sc_ah->opmode) { + case NL80211_IFTYPE_ADHOC: + tmp = "ADHOC"; + break; + case NL80211_IFTYPE_MESH_POINT: + tmp = "MESH"; + break; + case NL80211_IFTYPE_AP: + tmp = "AP"; + break; + case NL80211_IFTYPE_STATION: + tmp = "STATION"; + break; + default: + tmp = "???"; + break; + } + + len += snprintf(buf + len, size - len, + "curbssid: %pM\n" + "OP-Mode: %s(%i)\n" + "Beacon-Timer-Register: 0x%x\n", + common->curbssid, + tmp, (int)(sc->sc_ah->opmode), + REG_READ(ah, AR_BEACON_PERIOD)); + + reg = REG_READ(ah, AR_TIMER_MODE); + len += snprintf(buf + len, size - len, "Timer-Mode-Register: 0x%x (", + reg); + if (reg & AR_TBTT_TIMER_EN) + len += snprintf(buf + len, size - len, "TBTT "); + if (reg & AR_DBA_TIMER_EN) + len += snprintf(buf + len, size - len, "DBA "); + if (reg & AR_SWBA_TIMER_EN) + len += snprintf(buf + len, size - len, "SWBA "); + if (reg & AR_HCF_TIMER_EN) + len += snprintf(buf + len, size - len, "HCF "); + if (reg & AR_TIM_TIMER_EN) + len += snprintf(buf + len, size - len, "TIM "); + if (reg & AR_DTIM_TIMER_EN) + len += snprintf(buf + len, size - len, "DTIM "); + len += snprintf(buf + len, size - len, ")\n"); + + reg = sc->sc_ah->imask; + len += snprintf(buf + len, size - len, "imask: 0x%x (", reg); + if (reg & ATH9K_INT_SWBA) + len += snprintf(buf + len, size - len, "SWBA "); + if (reg & ATH9K_INT_BMISS) + len += snprintf(buf + len, size - len, "BMISS "); + if (reg & ATH9K_INT_CST) + len += snprintf(buf + len, size - len, "CST "); + if (reg & ATH9K_INT_RX) + len += snprintf(buf + len, size - len, "RX "); + if (reg & ATH9K_INT_RXHP) + len += snprintf(buf + len, size - len, "RXHP "); + if (reg & ATH9K_INT_RXLP) + len += snprintf(buf + len, size - len, "RXLP "); + if (reg & ATH9K_INT_BB_WATCHDOG) + len += snprintf(buf + len, size - len, "BB_WATCHDOG "); + /* there are other IRQs if one wanted to add them. */ + len += snprintf(buf + len, size - len, ")\n"); + + len += snprintf(buf + len, size - len, + "VIF Counts: AP: %i STA: %i MESH: %i WDS: %i" + " ADHOC: %i OTHER: %i nvifs: %hi beacon-vifs: %hi\n", + iter_data.naps, iter_data.nstations, iter_data.nmeshes, + iter_data.nwds, iter_data.nadhocs, iter_data.nothers, + sc->nvifs, sc->nbcnvifs); + + len += snprintf(buf + len, size - len, + "Calculated-BSSID-Mask: %pM\n", + iter_data.mask); + + if (len > size) + len = size; + + retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); + kfree(buf); + + return retval; +} + void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_status *ts) { @@ -822,6 +924,13 @@ static const struct file_operations fops_stations = { .llseek = default_llseek, }; +static const struct file_operations fops_misc = { + .read = read_file_misc, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + static ssize_t read_file_recv(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -1063,6 +1172,10 @@ int ath9k_init_debug(struct ath_hw *ah) sc, &fops_stations)) goto err; + if (!debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, + sc, &fops_misc)) + goto err; + if (!debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_recv)) goto err; -- cgit v1.2.3 From 7755bad9ffe56e0faacb13bc9484ccc0194aaa75 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Tue, 18 Jan 2011 17:30:00 -0800 Subject: ath9k: Try more than one queue when scheduling new aggregate. Try all xmit queues until the hardware buffers are full. Signed-off-by: Ben Greear Acked-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 64 ++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 2ad732d36f86..5f05a3abbf6a 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1222,49 +1222,59 @@ void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq) sc->tx.txqsetup &= ~(1<axq_qnum); } +/* For each axq_acq entry, for each tid, try to schedule packets + * for transmit until ampdu_depth has reached min Q depth. + */ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) { - struct ath_atx_ac *ac; - struct ath_atx_tid *tid, *last; + struct ath_atx_ac *ac, *ac_tmp, *last_ac; + struct ath_atx_tid *tid, *last_tid; if (list_empty(&txq->axq_acq) || txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) return; ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list); - last = list_entry(ac->tid_q.prev, struct ath_atx_tid, list); - list_del(&ac->list); - ac->sched = false; + last_ac = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list); - do { - if (list_empty(&ac->tid_q)) - return; + list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) { + last_tid = list_entry(ac->tid_q.prev, struct ath_atx_tid, list); + list_del(&ac->list); + ac->sched = false; - tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list); - list_del(&tid->list); - tid->sched = false; + while (!list_empty(&ac->tid_q)) { + tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, + list); + list_del(&tid->list); + tid->sched = false; - if (tid->paused) - continue; + if (tid->paused) + continue; - ath_tx_sched_aggr(sc, txq, tid); + ath_tx_sched_aggr(sc, txq, tid); - /* - * add tid to round-robin queue if more frames - * are pending for the tid - */ - if (!list_empty(&tid->buf_q)) - ath_tx_queue_tid(txq, tid); + /* + * add tid to round-robin queue if more frames + * are pending for the tid + */ + if (!list_empty(&tid->buf_q)) + ath_tx_queue_tid(txq, tid); - if (tid == last || txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) - break; - } while (!list_empty(&ac->tid_q)); + if (tid == last_tid || + txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) + break; + } - if (!list_empty(&ac->tid_q)) { - if (!ac->sched) { - ac->sched = true; - list_add_tail(&ac->list, &txq->axq_acq); + if (!list_empty(&ac->tid_q)) { + if (!ac->sched) { + ac->sched = true; + list_add_tail(&ac->list, &txq->axq_acq); + } } + + if (ac == last_ac || + txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) + return; } } -- cgit v1.2.3 From 90c02d72ffbec3804f48c517ecfc72f9440a67b3 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 19 Jan 2011 18:20:36 +0900 Subject: ath5k: Use mac80211 channel mapping function Use mac80211 channel mapping function instead of own homegrown version. Signed-off-by: Bruno Randolf Acked-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 019a74d533a6..c0177587856b 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -241,18 +241,6 @@ static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *re * Channel/mode setup * \********************/ -/* - * Convert IEEE channel number to MHz frequency. - */ -static inline short -ath5k_ieee2mhz(short chan) -{ - if (chan <= 14 || chan >= 27) - return ieee80211chan2mhz(chan); - else - return 2212 + chan * 20; -} - /* * Returns true for the channel numbers used without all_channels modparam. */ @@ -274,6 +262,7 @@ ath5k_copy_channels(struct ath5k_hw *ah, unsigned int max) { unsigned int i, count, size, chfreq, freq, ch; + enum ieee80211_band band; if (!test_bit(mode, ah->ah_modes)) return 0; @@ -283,11 +272,13 @@ ath5k_copy_channels(struct ath5k_hw *ah, /* 1..220, but 2GHz frequencies are filtered by check_channel */ size = 220 ; chfreq = CHANNEL_5GHZ; + band = IEEE80211_BAND_5GHZ; break; case AR5K_MODE_11B: case AR5K_MODE_11G: size = 26; chfreq = CHANNEL_2GHZ; + band = IEEE80211_BAND_2GHZ; break; default: ATH5K_WARN(ah->ah_sc, "bad mode, not copying channels\n"); @@ -296,7 +287,10 @@ ath5k_copy_channels(struct ath5k_hw *ah, for (i = 0, count = 0; i < size && max > 0; i++) { ch = i + 1 ; - freq = ath5k_ieee2mhz(ch); + freq = ieee80211_channel_to_frequency(ch, band); + + if (freq == 0) /* mapping failed - not a standard channel */ + continue; /* Check if channel is supported by the chipset */ if (!ath5k_channel_ok(ah, freq, chfreq)) @@ -307,8 +301,7 @@ ath5k_copy_channels(struct ath5k_hw *ah, /* Write channel info and increment counter */ channels[count].center_freq = freq; - channels[count].band = (chfreq == CHANNEL_2GHZ) ? - IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; + channels[count].band = band; switch (mode) { case AR5K_MODE_11A: case AR5K_MODE_11G: -- cgit v1.2.3 From 0810569076c1f3cf4a82da40211dd0b07b3ad07e Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 19 Jan 2011 18:20:47 +0900 Subject: ath5k: Rename ath5k_copy_channels Rename ath5k_copy_channels() to ath5k_setup_channels() - nothing is copied here. Signed-off-by: Bruno Randolf Acked-by: Bob Copeland Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index c0177587856b..6ff30d3833ee 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -256,7 +256,7 @@ static bool ath5k_is_standard_channel(short chan) } static unsigned int -ath5k_copy_channels(struct ath5k_hw *ah, +ath5k_setup_channels(struct ath5k_hw *ah, struct ieee80211_channel *channels, unsigned int mode, unsigned int max) @@ -357,7 +357,7 @@ ath5k_setup_bands(struct ieee80211_hw *hw) sband->n_bitrates = 12; sband->channels = sc->channels; - sband->n_channels = ath5k_copy_channels(ah, sband->channels, + sband->n_channels = ath5k_setup_channels(ah, sband->channels, AR5K_MODE_11G, max_c); hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; @@ -383,7 +383,7 @@ ath5k_setup_bands(struct ieee80211_hw *hw) } sband->channels = sc->channels; - sband->n_channels = ath5k_copy_channels(ah, sband->channels, + sband->n_channels = ath5k_setup_channels(ah, sband->channels, AR5K_MODE_11B, max_c); hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; @@ -403,7 +403,7 @@ ath5k_setup_bands(struct ieee80211_hw *hw) sband->n_bitrates = 8; sband->channels = &sc->channels[count_c]; - sband->n_channels = ath5k_copy_channels(ah, sband->channels, + sband->n_channels = ath5k_setup_channels(ah, sband->channels, AR5K_MODE_11A, max_c); hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; -- cgit v1.2.3 From 2f644ccfc5a3195290d12b8eedf18a37bba27d98 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 18 Jan 2011 17:44:33 +0000 Subject: staging: comedi: Make INSN_BITS behavior consistent across drivers Most comedi hardware drivers that support the INSN_BITS instruction ignore the base channel (specified by insn->chanspec) and assume it is 0. The base channel is supposed to affect how the mask (in data[0]) and bits (in data[1]) are treated. Bit 0 applies to the base channel, bit 1 applies to base channel plus 1, etc. For subdevices with no more than 32 channels, this patch modifies the chanspec and data before presenting it to the hardware driver, and modifies the data bits read back by the hardware driver (into data[1]). This makes it appear to the hardware driver that the base channel was set to 0. For subdevices with more than 32 channels, the instruction is left unmodified, as it is assumed that the hardware driver takes note of the base channel in this case in order to provide access beyond channel 31. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 093032ba521a..a4ceb29c358e 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -910,9 +910,28 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, case INSN_BITS: if (insn->n != 2) { ret = -EINVAL; - break; + } else { + /* Most drivers ignore the base channel in + * insn->chanspec. Fix this here if + * the subdevice has <= 32 channels. */ + unsigned int shift; + unsigned int orig_mask; + + orig_mask = data[0]; + if (s->n_chan <= 32) { + shift = CR_CHAN(insn->chanspec); + if (shift > 0) { + insn->chanspec = 0; + data[0] <<= shift; + data[1] <<= shift; + } + } else + shift = 0; + ret = s->insn_bits(dev, s, insn, data); + data[0] = orig_mask; + if (shift > 0) + data[1] >>= shift; } - ret = s->insn_bits(dev, s, insn, data); break; case INSN_CONFIG: ret = check_insn_config_length(insn, data); -- cgit v1.2.3 From 01ebd764dab26b3064b0c73ddcf726dd4b41485a Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Mon, 17 Jan 2011 13:08:49 +0300 Subject: staging: cs5535_gpio: check put_user() return code put_user() may fail, if so return -EFAULT. Signed-off-by: Vasiliy Kulikov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/cs5535_gpio/cs5535_gpio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/cs5535_gpio/cs5535_gpio.c b/drivers/staging/cs5535_gpio/cs5535_gpio.c index 0cf1e5fad9ab..b25f9d103b3b 100644 --- a/drivers/staging/cs5535_gpio/cs5535_gpio.c +++ b/drivers/staging/cs5535_gpio/cs5535_gpio.c @@ -146,7 +146,8 @@ static ssize_t cs5535_gpio_read(struct file *file, char __user *buf, /* add a line-feed if there is room */ if ((i == ARRAY_SIZE(rm)) && (count < len)) { - put_user('\n', buf + count); + if (put_user('\n', buf + count)) + return -EFAULT; count++; } -- cgit v1.2.3 From 410e6120a500edcf3fb8239301deabf20a4310db Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 19 Jan 2011 18:20:57 +0900 Subject: ath5k: Add 802.11j 4.9GHz channels to allowed channels Add the 802.11j (20MHz channel width) channels to the allowed channels. This still does not enable 802.11j in ath5k since these frequencies are out of the configured range. A later patch will deal with that. Signed-off-by: Bruno Randolf Acked-by: Bob Copeland Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 6ff30d3833ee..2de8e80bfdc9 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -244,15 +244,21 @@ static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *re /* * Returns true for the channel numbers used without all_channels modparam. */ -static bool ath5k_is_standard_channel(short chan) +static bool ath5k_is_standard_channel(short chan, enum ieee80211_band band) { - return ((chan <= 14) || - /* UNII 1,2 */ - ((chan & 3) == 0 && chan >= 36 && chan <= 64) || + if (band == IEEE80211_BAND_2GHZ && chan <= 14) + return true; + + return /* UNII 1,2 */ + (((chan & 3) == 0 && chan >= 36 && chan <= 64) || /* midband */ ((chan & 3) == 0 && chan >= 100 && chan <= 140) || /* UNII-3 */ - ((chan & 3) == 1 && chan >= 149 && chan <= 165)); + ((chan & 3) == 1 && chan >= 149 && chan <= 165) || + /* 802.11j 5.030-5.080 GHz (20MHz) */ + (chan == 8 || chan == 12 || chan == 16) || + /* 802.11j 4.9GHz (20MHz) */ + (chan == 184 || chan == 188 || chan == 192 || chan == 196)); } static unsigned int @@ -296,7 +302,8 @@ ath5k_setup_channels(struct ath5k_hw *ah, if (!ath5k_channel_ok(ah, freq, chfreq)) continue; - if (!modparam_all_channels && !ath5k_is_standard_channel(ch)) + if (!modparam_all_channels && + !ath5k_is_standard_channel(ch, band)) continue; /* Write channel info and increment counter */ -- cgit v1.2.3 From 75f9569bfc4f3b138d196091b85c91678183520e Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 19 Jan 2011 18:21:02 +0900 Subject: ath5: Remove unused CTL definitions They are unused in ath5k and a more detailled definition is in ath/regd_common.h. Signed-off-by: Bruno Randolf Acked-by: Bob Copeland Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/eeprom.h | 23 ----------------------- 1 file changed, 23 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h index d46f1056f447..6511c27d938e 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.h +++ b/drivers/net/wireless/ath/ath5k/eeprom.h @@ -268,29 +268,6 @@ enum ath5k_ctl_mode { AR5K_CTL_MODE_M = 15, }; -/* Default CTL ids for the 3 main reg domains. - * Atheros only uses these by default but vendors - * can have up to 32 different CTLs for different - * scenarios. Note that theese values are ORed with - * the mode id (above) so we can have up to 24 CTL - * datasets out of these 3 main regdomains. That leaves - * 8 ids that can be used by vendors and since 0x20 is - * missing from HAL sources i guess this is the set of - * custom CTLs vendors can use. */ -#define AR5K_CTL_FCC 0x10 -#define AR5K_CTL_CUSTOM 0x20 -#define AR5K_CTL_ETSI 0x30 -#define AR5K_CTL_MKK 0x40 - -/* Indicates a CTL with only mode set and - * no reg domain mapping, such CTLs are used - * for world roaming domains or simply when - * a reg domain is not set */ -#define AR5K_CTL_NO_REGDOMAIN 0xf0 - -/* Indicates an empty (invalid) CTL */ -#define AR5K_CTL_NO_CTL 0xff - /* Per channel calibration data, used for power table setup */ struct ath5k_chan_pcal_info_rf5111 { /* Power levels in half dbm units -- cgit v1.2.3 From 4b3721ceb3c1f9b032c6eeb108e44692efbcacef Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 19 Jan 2011 18:21:08 +0900 Subject: ath5k: Remove unused sc->curmode sc->curmode is set but never used. Remove it and the helper function. Also the ath5k_rate_update which is refered to in the comment does not exist (any more?) so we don't need to setup the band in that place. Signed-off-by: Bruno Randolf Acked-by: Bob Copeland Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 18 ------------------ drivers/net/wireless/ath/ath5k/base.h | 1 - 2 files changed, 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 2de8e80bfdc9..43db07b9711b 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -445,18 +445,6 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) return ath5k_reset(sc, chan, true); } -static void -ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) -{ - sc->curmode = mode; - - if (mode == AR5K_MODE_11A) { - sc->curband = &sc->sbands[IEEE80211_BAND_5GHZ]; - } else { - sc->curband = &sc->sbands[IEEE80211_BAND_2GHZ]; - } -} - struct ath_vif_iter_data { const u8 *hw_macaddr; u8 mask[ETH_ALEN]; @@ -2778,12 +2766,6 @@ ath5k_init(struct ieee80211_hw *hw) goto err; } - /* NB: setup here so ath5k_rate_update is happy */ - if (test_bit(AR5K_MODE_11A, ah->ah_modes)) - ath5k_setcurmode(sc, AR5K_MODE_11A); - else - ath5k_setcurmode(sc, AR5K_MODE_11B); - /* * Allocate tx+rx descriptors and populate the lists. */ diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 6d511476e4d2..58660e4d274a 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -202,7 +202,6 @@ struct ath5k_softc { #define ATH_STAT_STARTED 4 /* opened & irqs enabled */ unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */ - unsigned int curmode; /* current phy mode */ struct ieee80211_channel *curchan; /* current h/w channel */ u16 nvifs; -- cgit v1.2.3 From 930a7622d618cdf794787938d7cbda5461adb1cb Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 19 Jan 2011 18:21:13 +0900 Subject: ath5k: Remove redundant sc->curband Remove sc->curband because the band is already stored in the current channel. Signed-off-by: Bruno Randolf Acked-by: Bob Copeland Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 11 ++++------- drivers/net/wireless/ath/ath5k/base.h | 2 -- 2 files changed, 4 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 43db07b9711b..217c2a09d979 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -557,7 +557,7 @@ ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix) "hw_rix out of bounds: %x\n", hw_rix)) return 0; - rix = sc->rate_idx[sc->curband->band][hw_rix]; + rix = sc->rate_idx[sc->curchan->band][hw_rix]; if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix)) rix = 0; @@ -1367,7 +1367,7 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb, rxs->flag |= RX_FLAG_TSFT; rxs->freq = sc->curchan->center_freq; - rxs->band = sc->curband->band; + rxs->band = sc->curchan->band; rxs->signal = sc->ah->ah_noise_floor + rs->rs_rssi; @@ -1382,7 +1382,7 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb, rxs->flag |= ath5k_rx_decrypted(sc, skb, rs); if (rxs->rate_idx >= 0 && rs->rs_rate == - sc->curband->bitrates[rxs->rate_idx].hw_value_short) + sc->sbands[sc->curchan->band].bitrates[rxs->rate_idx].hw_value_short) rxs->flag |= RX_FLAG_SHORTPRE; ath5k_debug_dump_skb(sc, skb, "RX ", 0); @@ -2538,7 +2538,6 @@ ath5k_init_hw(struct ath5k_softc *sc) * and then setup of the interrupt mask. */ sc->curchan = sc->hw->conf.channel; - sc->curband = &sc->sbands[sc->curchan->band]; sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB; @@ -2665,10 +2664,8 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, * so we should also free any remaining * tx buffers */ ath5k_drain_tx_buffs(sc); - if (chan) { + if (chan) sc->curchan = chan; - sc->curband = &sc->sbands[chan->band]; - } ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL, skip_pcu); if (ret) { diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 58660e4d274a..8f919dca95f1 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -183,8 +183,6 @@ struct ath5k_softc { enum nl80211_iftype opmode; struct ath5k_hw *ah; /* Atheros HW */ - struct ieee80211_supported_band *curband; - #ifdef CONFIG_ATH5K_DEBUG struct ath5k_dbg_info debug; /* debug info */ #endif /* CONFIG_ATH5K_DEBUG */ -- cgit v1.2.3 From 3ec6080e2e5be05e6f7fbbe5ab20b0eab84e166b Mon Sep 17 00:00:00 2001 From: Ralph Loader Date: Fri, 21 Jan 2011 19:27:53 +1300 Subject: staging: Fix some incorrect use of positive error codes. Use -E... instead of just E... in a few places where negative error codes are expected by a functions callers. These were found by grepping with coccinelle & then inspecting by hand to determine which were bugs. The staging/cxt1e1 driver appears to intentionally use positive E... error codes in some places, and negative -E... error codes in others, making it hard to know which is intended where - very likely I missed some problems in that driver. Signed-off-by: Ralph Loader Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ioctl.c | 10 +++++----- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 2 +- drivers/staging/cxt1e1/linux.c | 2 +- drivers/staging/westbridge/astoria/device/cyasdevice.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index d5f7ac08ab96..0b10376fad2d 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -440,7 +440,7 @@ ar6000_ioctl_set_rssi_threshold(struct net_device *dev, struct ifreq *rq) if (ar->rssi_map[j+1].rssi < ar->rssi_map[j].rssi) { SWAP_THOLD(ar->rssi_map[j+1], ar->rssi_map[j]); } else if (ar->rssi_map[j+1].rssi == ar->rssi_map[j].rssi) { - return EFAULT; + return -EFAULT; } } } @@ -449,7 +449,7 @@ ar6000_ioctl_set_rssi_threshold(struct net_device *dev, struct ifreq *rq) if (ar->rssi_map[j+1].rssi < ar->rssi_map[j].rssi) { SWAP_THOLD(ar->rssi_map[j+1], ar->rssi_map[j]); } else if (ar->rssi_map[j+1].rssi == ar->rssi_map[j].rssi) { - return EFAULT; + return -EFAULT; } } } @@ -2870,7 +2870,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) gpio_output_set_cmd.enable_mask, gpio_output_set_cmd.disable_mask); if (ret != A_OK) { - ret = EIO; + ret = -EIO; } } up(&ar->arSem); @@ -2950,7 +2950,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) gpio_register_cmd.gpioreg_id, gpio_register_cmd.value); if (ret != A_OK) { - ret = EIO; + ret = -EIO; } /* Wait for acknowledgement from Target */ @@ -3041,7 +3041,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } else { ret = ar6000_gpio_intr_ack(dev, gpio_intr_ack_cmd.ack_mask); if (ret != A_OK) { - ret = EIO; + ret = -EIO; } } up(&ar->arSem); diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index 7167d4735e2a..f4b1b4ecab82 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -1368,7 +1368,7 @@ wl_iw_iscan_set_scan(struct net_device *dev, if (g_scan_specified_ssid) { WL_TRACE("%s Specific SCAN already running ignoring BC scan\n", __func__); - return EBUSY; + return -EBUSY; } memset(&ssid, 0, sizeof(ssid)); diff --git a/drivers/staging/cxt1e1/linux.c b/drivers/staging/cxt1e1/linux.c index 0f78f8962751..9ced08f253b3 100644 --- a/drivers/staging/cxt1e1/linux.c +++ b/drivers/staging/cxt1e1/linux.c @@ -548,7 +548,7 @@ do_set_port (struct net_device * ndev, void *data) return -EINVAL; /* get card info */ if (pp.portnum >= ci->max_port) /* sanity check */ - return ENXIO; + return -ENXIO; memcpy (&ci->port[pp.portnum].p, &pp, sizeof (struct sbecom_port_param)); return mkret (c4_set_port (ci, pp.portnum)); diff --git a/drivers/staging/westbridge/astoria/device/cyasdevice.c b/drivers/staging/westbridge/astoria/device/cyasdevice.c index c76e38375010..088973076517 100644 --- a/drivers/staging/westbridge/astoria/device/cyasdevice.c +++ b/drivers/staging/westbridge/astoria/device/cyasdevice.c @@ -389,7 +389,7 @@ EXPORT_SYMBOL(cyasdevice_gethaltag); static int __init cyasdevice_init(void) { if (cyasdevice_initialize() != 0) - return ENODEV; + return -ENODEV; return 0; } -- cgit v1.2.3 From 4ac638b2ce0738183019c9fe72a8cd1259eb2ad1 Mon Sep 17 00:00:00 2001 From: Naveen Kumar Gaddipati Date: Fri, 21 Jan 2011 15:50:16 +0530 Subject: staging: synaptics: Update with the kernel object name of touch device Update with the kernel object name of touch device for getting the regulator of the synaptics rmi4 touch device. Signed-off-by: Naveen Kumar Gaddipati Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c | 6 ++---- drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c index e8f047e86a32..f69d3a34190a 100644 --- a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c +++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c @@ -924,10 +924,8 @@ static int __devinit synaptics_rmi4_probe goto err_input; } - dev_set_name(&client->dev, platformdata->name); - if (platformdata->regulator_en) { - rmi4_data->regulator = regulator_get(&client->dev, "v-touch"); + rmi4_data->regulator = regulator_get(&client->dev, "vdd"); if (IS_ERR(rmi4_data->regulator)) { dev_err(&client->dev, "%s:get regulator failed\n", __func__); @@ -999,7 +997,7 @@ static int __devinit synaptics_rmi4_probe retval = request_threaded_irq(platformdata->irq_number, NULL, synaptics_rmi4_irq, platformdata->irq_type, - platformdata->name, rmi4_data); + DRIVER_NAME, rmi4_data); if (retval) { dev_err(&client->dev, "%s:Unable to get attn irq %d\n", __func__, platformdata->irq_number); diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h index 820ae275fa2b..3686a2ff5964 100644 --- a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h +++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h @@ -39,7 +39,6 @@ * This structure gives platform data for rmi4. */ struct synaptics_rmi4_platform_data { - const char *name; int irq_number; int irq_type; bool x_flip; -- cgit v1.2.3 From e26a755211c72ccfc52faf4e647757a058eb131a Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Thu, 20 Jan 2011 00:13:44 +0300 Subject: Staging: pohmelfs/dir.c: Remove unneeded mutex_unlock() from pohmelfs_rename() I do not see any reason for the mutex_unlock(&inode->i_mutex); in pohmelfs_rename(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/pohmelfs/dir.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/pohmelfs/dir.c b/drivers/staging/pohmelfs/dir.c index 059e9d2ddf6b..9732a9666cc4 100644 --- a/drivers/staging/pohmelfs/dir.c +++ b/drivers/staging/pohmelfs/dir.c @@ -1082,7 +1082,6 @@ err_out_exit: clear_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state); - mutex_unlock(&inode->i_mutex); return err; } -- cgit v1.2.3 From d7e86c3219a1287dd1350a590ee79c8753ff2420 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 20 Jan 2011 21:57:30 +0100 Subject: ath9k: remove a bogus error message When beacons are being added or removed for an interface, ieee80211_beacon_get will sometimes not return a beacon. This is normal and should not result in useless logspam. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 8de591e5b851..ab8c05cf62f3 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -279,10 +279,8 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) /* NB: the beacon data buffer must be 32-bit aligned. */ skb = ieee80211_beacon_get(sc->hw, vif); - if (skb == NULL) { - ath_err(common, "ieee80211_beacon_get failed\n"); + if (skb == NULL) return -ENOMEM; - } tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; sc->beacon.bc_tstamp = le64_to_cpu(tstamp); -- cgit v1.2.3 From 2b1351a30705925ed06b41ec98a6fbaad4ba4d6f Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Fri, 21 Jan 2011 12:19:52 +0900 Subject: ath5k: Simplify loop when setting up channels Simplify confusing code and get rid of an unnecessary variable. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 217c2a09d979..76a4e55265c3 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -267,7 +267,7 @@ ath5k_setup_channels(struct ath5k_hw *ah, unsigned int mode, unsigned int max) { - unsigned int i, count, size, chfreq, freq, ch; + unsigned int count, size, chfreq, freq, ch; enum ieee80211_band band; if (!test_bit(mode, ah->ah_modes)) @@ -291,8 +291,8 @@ ath5k_setup_channels(struct ath5k_hw *ah, return 0; } - for (i = 0, count = 0; i < size && max > 0; i++) { - ch = i + 1 ; + count = 0; + for (ch = 1; ch <= size && count < max; ch++) { freq = ieee80211_channel_to_frequency(ch, band); if (freq == 0) /* mapping failed - not a standard channel */ @@ -319,7 +319,6 @@ ath5k_setup_channels(struct ath5k_hw *ah, } count++; - max--; } return count; -- cgit v1.2.3 From 4a4fdf2e0b9e3534f6ec4f3e7077470bd66924ab Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 21 Jan 2011 18:46:35 +0100 Subject: ath9k_hw: replace magic values in register writes with proper defines Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 24 ++++++++++++------------ drivers/net/wireless/ath/ath9k/ar9003_phy.h | 2 ++ 2 files changed, 14 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 4819747fa4c3..a25655640f48 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3959,19 +3959,19 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray) { #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) /* make sure forced gain is not set */ - REG_WRITE(ah, 0xa458, 0); + REG_WRITE(ah, AR_PHY_TX_FORCED_GAIN, 0); /* Write the OFDM power per rate set */ /* 6 (LSB), 9, 12, 18 (MSB) */ - REG_WRITE(ah, 0xa3c0, + REG_WRITE(ah, AR_PHY_POWER_TX_RATE(0), POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) | POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) | POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) | POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0)); /* 24 (LSB), 36, 48, 54 (MSB) */ - REG_WRITE(ah, 0xa3c4, + REG_WRITE(ah, AR_PHY_POWER_TX_RATE(1), POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) | POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) | POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) | @@ -3980,14 +3980,14 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray) /* Write the CCK power per rate set */ /* 1L (LSB), reserved, 2L, 2S (MSB) */ - REG_WRITE(ah, 0xa3c8, + REG_WRITE(ah, AR_PHY_POWER_TX_RATE(2), POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) | POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) | /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */ POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)); /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */ - REG_WRITE(ah, 0xa3cc, + REG_WRITE(ah, AR_PHY_POWER_TX_RATE(3), POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) | POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) | POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) | @@ -3997,7 +3997,7 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray) /* Write the HT20 power per rate set */ /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */ - REG_WRITE(ah, 0xa3d0, + REG_WRITE(ah, AR_PHY_POWER_TX_RATE(4), POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) | POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) | POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) | @@ -4005,7 +4005,7 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray) ); /* 6 (LSB), 7, 12, 13 (MSB) */ - REG_WRITE(ah, 0xa3d4, + REG_WRITE(ah, AR_PHY_POWER_TX_RATE(5), POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) | POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) | POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) | @@ -4013,7 +4013,7 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray) ); /* 14 (LSB), 15, 20, 21 */ - REG_WRITE(ah, 0xa3e4, + REG_WRITE(ah, AR_PHY_POWER_TX_RATE(9), POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) | POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) | POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) | @@ -4023,7 +4023,7 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray) /* Mixed HT20 and HT40 rates */ /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */ - REG_WRITE(ah, 0xa3e8, + REG_WRITE(ah, AR_PHY_POWER_TX_RATE(10), POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) | POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) | POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) | @@ -4035,7 +4035,7 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray) * correct PAR difference between HT40 and HT20/LEGACY * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */ - REG_WRITE(ah, 0xa3d8, + REG_WRITE(ah, AR_PHY_POWER_TX_RATE(6), POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) | POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) | POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) | @@ -4043,7 +4043,7 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray) ); /* 6 (LSB), 7, 12, 13 (MSB) */ - REG_WRITE(ah, 0xa3dc, + REG_WRITE(ah, AR_PHY_POWER_TX_RATE(7), POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) | POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) | POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) | @@ -4051,7 +4051,7 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray) ); /* 14 (LSB), 15, 20, 21 */ - REG_WRITE(ah, 0xa3ec, + REG_WRITE(ah, AR_PHY_POWER_TX_RATE(11), POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) | POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) | POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) | diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 59bab6bd8a74..8bdda2cf9dd7 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -486,6 +486,8 @@ #define AR_PHY_HEAVYCLIP_40 (AR_SM_BASE + 0x1ac) #define AR_PHY_ILLEGAL_TXRATE (AR_SM_BASE + 0x1b0) +#define AR_PHY_POWER_TX_RATE(_d) (AR_SM_BASE + 0x1c0 + ((_d) << 2)) + #define AR_PHY_PWRTX_MAX (AR_SM_BASE + 0x1f0) #define AR_PHY_POWER_TX_SUB (AR_SM_BASE + 0x1f4) -- cgit v1.2.3 From 5ed540aecc2aae92d5c97b9a9306a5bf88ad5574 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 21 Jan 2011 15:26:39 -0800 Subject: iwlwifi: use mac80211 throughput trigger Instead of keeping track of LED blink speed in the driver, use the new mac80211 trigger and link it up with an LED classdev that we now register. This also allows users more flexibility in how they want to have the LED blink or not. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/Kconfig | 4 + drivers/net/wireless/iwlwifi/iwl-3945-led.c | 27 ---- drivers/net/wireless/iwlwifi/iwl-agn-led.c | 14 +- drivers/net/wireless/iwlwifi/iwl-agn-led.h | 1 + drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 2 - drivers/net/wireless/iwlwifi/iwl-agn.c | 10 +- drivers/net/wireless/iwlwifi/iwl-core.c | 2 - drivers/net/wireless/iwlwifi/iwl-core.h | 14 -- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 25 ---- drivers/net/wireless/iwlwifi/iwl-dev.h | 18 +-- drivers/net/wireless/iwlwifi/iwl-led.c | 201 +++++++++++----------------- drivers/net/wireless/iwlwifi/iwl-led.h | 16 +-- drivers/net/wireless/iwlwifi/iwl-legacy.c | 4 - drivers/net/wireless/iwlwifi/iwl3945-base.c | 8 +- 14 files changed, 106 insertions(+), 240 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index ed424574160e..8994d3072715 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -2,6 +2,10 @@ config IWLWIFI tristate "Intel Wireless Wifi" depends on PCI && MAC80211 select FW_LOADER + select NEW_LEDS + select LEDS_CLASS + select LEDS_TRIGGERS + select MAC80211_LEDS menu "Debugging Options" depends on IWLWIFI diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c index abe2b739c4dc..dc7c3a4167a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c @@ -59,33 +59,6 @@ static int iwl3945_send_led_cmd(struct iwl_priv *priv, return iwl_send_cmd(priv, &cmd); } -/* Set led on command */ -static int iwl3945_led_on(struct iwl_priv *priv) -{ - struct iwl_led_cmd led_cmd = { - .id = IWL_LED_LINK, - .on = IWL_LED_SOLID, - .off = 0, - .interval = IWL_DEF_LED_INTRVL - }; - return iwl3945_send_led_cmd(priv, &led_cmd); -} - -/* Set led off command */ -static int iwl3945_led_off(struct iwl_priv *priv) -{ - struct iwl_led_cmd led_cmd = { - .id = IWL_LED_LINK, - .on = 0, - .off = 0, - .interval = IWL_DEF_LED_INTRVL - }; - IWL_DEBUG_LED(priv, "led off\n"); - return iwl3945_send_led_cmd(priv, &led_cmd); -} - const struct iwl_led_ops iwl3945_led_ops = { .cmd = iwl3945_send_led_cmd, - .on = iwl3945_led_on, - .off = iwl3945_led_off, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.c b/drivers/net/wireless/iwlwifi/iwl-agn-led.c index 1a24946bc203..c1190d965614 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.c @@ -63,23 +63,11 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) } /* Set led register off */ -static int iwl_led_on_reg(struct iwl_priv *priv) +void iwlagn_led_enable(struct iwl_priv *priv) { - IWL_DEBUG_LED(priv, "led on\n"); iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON); - return 0; -} - -/* Set led register off */ -static int iwl_led_off_reg(struct iwl_priv *priv) -{ - IWL_DEBUG_LED(priv, "LED Reg off\n"); - iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_OFF); - return 0; } const struct iwl_led_ops iwlagn_led_ops = { .cmd = iwl_send_led_cmd, - .on = iwl_led_on_reg, - .off = iwl_led_off_reg, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.h b/drivers/net/wireless/iwlwifi/iwl-agn-led.h index a594e4fdc6b8..96f323dc5dd6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.h @@ -28,5 +28,6 @@ #define __iwl_agn_led_h__ extern const struct iwl_led_ops iwlagn_led_ops; +void iwlagn_led_enable(struct iwl_priv *priv); #endif /* __iwl_agn_led_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 6e80f1070c52..f693293b6bd1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -557,12 +557,10 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, if (changes & BSS_CHANGED_ASSOC) { if (bss_conf->assoc) { - iwl_led_associate(priv); priv->timestamp = bss_conf->timestamp; ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; } else { ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_led_disassociate(priv); } } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 97657d04aa68..9240abf425c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -59,6 +59,7 @@ #include "iwl-sta.h" #include "iwl-agn-calib.h" #include "iwl-agn.h" +#include "iwl-agn-led.h" /****************************************************************************** @@ -2741,8 +2742,6 @@ static void iwl_alive_start(struct iwl_priv *priv) /* At this point, the NIC is initialized and operational */ iwl_rf_kill_ct_config(priv); - iwl_leds_init(priv); - IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); wake_up_interruptible(&priv->wait_command_queue); @@ -3234,6 +3233,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->bands[IEEE80211_BAND_5GHZ]; + iwl_leds_init(priv); + ret = ieee80211_register_hw(priv->hw); if (ret) { IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); @@ -3278,7 +3279,7 @@ int iwlagn_mac_start(struct ieee80211_hw *hw) } } - iwl_led_start(priv); + iwlagn_led_enable(priv); out: priv->is_open = 1; @@ -4288,6 +4289,9 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) * we need to set STATUS_EXIT_PENDING bit. */ set_bit(STATUS_EXIT_PENDING, &priv->status); + + iwl_leds_exit(priv); + if (priv->mac80211_registered) { ieee80211_unregister_hw(priv->hw); priv->mac80211_registered = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index a8d4a936a2e7..8e1b8014ddc1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1676,7 +1676,6 @@ void iwl_clear_traffic_stats(struct iwl_priv *priv) { memset(&priv->tx_stats, 0, sizeof(struct traffic_stats)); memset(&priv->rx_stats, 0, sizeof(struct traffic_stats)); - priv->led_tpt = 0; } /* @@ -1769,7 +1768,6 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) stats->data_cnt++; stats->data_bytes += len; } - iwl_leds_background(priv); } EXPORT_SYMBOL(iwl_update_stats); #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index a3474376fdbc..bbc5aa7a7f2f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -227,8 +227,6 @@ struct iwl_lib_ops { struct iwl_led_ops { int (*cmd)(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd); - int (*on)(struct iwl_priv *priv); - int (*off)(struct iwl_priv *priv); }; /* NIC specific ops */ @@ -494,18 +492,6 @@ static inline void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) { - struct traffic_stats *stats; - - if (is_tx) - stats = &priv->tx_stats; - else - stats = &priv->rx_stats; - - if (ieee80211_is_data(fc)) { - /* data */ - stats->data_bytes += len; - } - iwl_leds_background(priv); } #endif /***************************************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 6fe80b5e7a15..7f11a448d518 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -668,29 +668,6 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf, return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } -static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_priv *priv = file->private_data; - int pos = 0; - char buf[256]; - const size_t bufsz = sizeof(buf); - - pos += scnprintf(buf + pos, bufsz - pos, - "allow blinking: %s\n", - (priv->allow_blinking) ? "True" : "False"); - if (priv->allow_blinking) { - pos += scnprintf(buf + pos, bufsz - pos, - "Led blinking rate: %u\n", - priv->last_blink_rate); - pos += scnprintf(buf + pos, bufsz - pos, - "Last blink time: %lu\n", - priv->last_blink_time); - } - - return simple_read_from_buffer(user_buf, count, ppos, buf, pos); -} - static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -856,7 +833,6 @@ DEBUGFS_READ_FILE_OPS(channels); DEBUGFS_READ_FILE_OPS(status); DEBUGFS_READ_WRITE_FILE_OPS(interrupt); DEBUGFS_READ_FILE_OPS(qos); -DEBUGFS_READ_FILE_OPS(led); DEBUGFS_READ_FILE_OPS(thermal_throttling); DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override); @@ -1725,7 +1701,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); - DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR); if (!priv->cfg->base_params->broken_powersave) { DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 2ec680bb8f6d..6dd6508c93b0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -35,6 +35,7 @@ #include /* for struct pci_device_id */ #include #include +#include #include #include "iwl-eeprom.h" @@ -996,7 +997,6 @@ struct reply_agg_tx_error_statistics { u32 unknown; }; -#ifdef CONFIG_IWLWIFI_DEBUGFS /* management statistics */ enum iwl_mgmt_stats { MANAGEMENT_ASSOC_REQ = 0, @@ -1027,16 +1027,13 @@ enum iwl_ctrl_stats { }; struct traffic_stats { +#ifdef CONFIG_IWLWIFI_DEBUGFS u32 mgmt[MANAGEMENT_MAX]; u32 ctrl[CONTROL_MAX]; u32 data_cnt; u64 data_bytes; -}; -#else -struct traffic_stats { - u64 data_bytes; -}; #endif +}; /* * iwl_switch_rxon: "channel switch" structure @@ -1338,11 +1335,6 @@ struct iwl_priv { struct iwl_init_alive_resp card_alive_init; struct iwl_alive_resp card_alive; - unsigned long last_blink_time; - u8 last_blink_rate; - u8 allow_blinking; - u64 led_tpt; - u16 active_rate; u8 start_calib; @@ -1580,6 +1572,10 @@ struct iwl_priv { bool hw_ready; struct iwl_event_log event_log; + + struct led_classdev led; + unsigned long blink_on, blink_off; + bool led_registered; }; /*iwl_priv */ static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id) diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 46ccdf406e8e..074ad2275228 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -48,31 +48,19 @@ module_param(led_mode, int, S_IRUGO); MODULE_PARM_DESC(led_mode, "0=system default, " "1=On(RF On)/Off(RF Off), 2=blinking"); -static const struct { - u16 tpt; /* Mb/s */ - u8 on_time; - u8 off_time; -} blink_tbl[] = -{ - {300, 25, 25}, - {200, 40, 40}, - {100, 55, 55}, - {70, 65, 65}, - {50, 75, 75}, - {20, 85, 85}, - {10, 95, 95}, - {5, 110, 110}, - {1, 130, 130}, - {0, 167, 167}, - /* SOLID_ON */ - {-1, IWL_LED_SOLID, 0} +static const struct ieee80211_tpt_blink iwl_blink[] = { + { .throughput = 0 * 1024 - 1, .blink_time = 334 }, + { .throughput = 1 * 1024 - 1, .blink_time = 260 }, + { .throughput = 5 * 1024 - 1, .blink_time = 220 }, + { .throughput = 10 * 1024 - 1, .blink_time = 190 }, + { .throughput = 20 * 1024 - 1, .blink_time = 170 }, + { .throughput = 50 * 1024 - 1, .blink_time = 150 }, + { .throughput = 70 * 1024 - 1, .blink_time = 130 }, + { .throughput = 100 * 1024 - 1, .blink_time = 110 }, + { .throughput = 200 * 1024 - 1, .blink_time = 80 }, + { .throughput = 300 * 1024 - 1, .blink_time = 50 }, }; -#define IWL_1MB_RATE (128 * 1024) -#define IWL_LED_THRESHOLD (16) -#define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /* exclude SOLID_ON */ -#define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1) - /* * Adjust led blink rate to compensate on a MAC Clock difference on every HW * Led blink rate analysis showed an average deviation of 0% on 3945, @@ -97,133 +85,104 @@ static inline u8 iwl_blink_compensation(struct iwl_priv *priv, } /* Set led pattern command */ -static int iwl_led_pattern(struct iwl_priv *priv, unsigned int idx) +static int iwl_led_cmd(struct iwl_priv *priv, + unsigned long on, + unsigned long off) { struct iwl_led_cmd led_cmd = { .id = IWL_LED_LINK, .interval = IWL_DEF_LED_INTRVL }; + int ret; - BUG_ON(idx > IWL_MAX_BLINK_TBL); + if (!test_bit(STATUS_READY, &priv->status)) + return -EBUSY; - IWL_DEBUG_LED(priv, "Led blink time compensation= %u\n", + if (priv->blink_on == on && priv->blink_off == off) + return 0; + + IWL_DEBUG_LED(priv, "Led blink time compensation=%u\n", priv->cfg->base_params->led_compensation); - led_cmd.on = - iwl_blink_compensation(priv, blink_tbl[idx].on_time, + led_cmd.on = iwl_blink_compensation(priv, on, priv->cfg->base_params->led_compensation); - led_cmd.off = - iwl_blink_compensation(priv, blink_tbl[idx].off_time, + led_cmd.off = iwl_blink_compensation(priv, off, priv->cfg->base_params->led_compensation); - return priv->cfg->ops->led->cmd(priv, &led_cmd); + ret = priv->cfg->ops->led->cmd(priv, &led_cmd); + if (!ret) { + priv->blink_on = on; + priv->blink_off = off; + } + return ret; } -int iwl_led_start(struct iwl_priv *priv) +static void iwl_led_brightness_set(struct led_classdev *led_cdev, + enum led_brightness brightness) { - return priv->cfg->ops->led->on(priv); -} -EXPORT_SYMBOL(iwl_led_start); + struct iwl_priv *priv = container_of(led_cdev, struct iwl_priv, led); + unsigned long on = 0; -int iwl_led_associate(struct iwl_priv *priv) -{ - IWL_DEBUG_LED(priv, "Associated\n"); - if (priv->cfg->led_mode == IWL_LED_BLINK) - priv->allow_blinking = 1; - priv->last_blink_time = jiffies; + if (brightness > 0) + on = IWL_LED_SOLID; - return 0; + iwl_led_cmd(priv, on, 0); } -EXPORT_SYMBOL(iwl_led_associate); -int iwl_led_disassociate(struct iwl_priv *priv) +static int iwl_led_blink_set(struct led_classdev *led_cdev, + unsigned long *delay_on, + unsigned long *delay_off) { - priv->allow_blinking = 0; + struct iwl_priv *priv = container_of(led_cdev, struct iwl_priv, led); - return 0; + return iwl_led_cmd(priv, *delay_on, *delay_off); } -EXPORT_SYMBOL(iwl_led_disassociate); -/* - * calculate blink rate according to last second Tx/Rx activities - */ -static int iwl_get_blink_rate(struct iwl_priv *priv) -{ - int i; - /* count both tx and rx traffic to be able to - * handle traffic in either direction - */ - u64 current_tpt = priv->tx_stats.data_bytes + - priv->rx_stats.data_bytes; - s64 tpt = current_tpt - priv->led_tpt; - - if (tpt < 0) /* wraparound */ - tpt = -tpt; - - IWL_DEBUG_LED(priv, "tpt %lld current_tpt %llu\n", - (long long)tpt, - (unsigned long long)current_tpt); - priv->led_tpt = current_tpt; - - if (!priv->allow_blinking) - i = IWL_MAX_BLINK_TBL; - else - for (i = 0; i < IWL_MAX_BLINK_TBL; i++) - if (tpt > (blink_tbl[i].tpt * IWL_1MB_RATE)) - break; - - IWL_DEBUG_LED(priv, "LED BLINK IDX=%d\n", i); - return i; -} - -/* - * this function called from handler. Since setting Led command can - * happen very frequent we postpone led command to be called from - * REPLY handler so we know ucode is up - */ -void iwl_leds_background(struct iwl_priv *priv) +void iwl_leds_init(struct iwl_priv *priv) { - u8 blink_idx; - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { - priv->last_blink_time = 0; - return; - } - if (iwl_is_rfkill(priv)) { - priv->last_blink_time = 0; - return; + int mode = led_mode; + int ret; + + if (mode == IWL_LED_DEFAULT) + mode = priv->cfg->led_mode; + + priv->led.name = kasprintf(GFP_KERNEL, "%s-led", + wiphy_name(priv->hw->wiphy)); + priv->led.brightness_set = iwl_led_brightness_set; + priv->led.blink_set = iwl_led_blink_set; + priv->led.max_brightness = 1; + + switch (mode) { + case IWL_LED_DEFAULT: + WARN_ON(1); + break; + case IWL_LED_BLINK: + priv->led.default_trigger = + ieee80211_create_tpt_led_trigger(priv->hw, + IEEE80211_TPT_LEDTRIG_FL_CONNECTED, + iwl_blink, ARRAY_SIZE(iwl_blink)); + break; + case IWL_LED_RF_STATE: + priv->led.default_trigger = + ieee80211_get_radio_led_name(priv->hw); + break; } - if (!priv->allow_blinking) { - priv->last_blink_time = 0; - if (priv->last_blink_rate != IWL_SOLID_BLINK_IDX) { - priv->last_blink_rate = IWL_SOLID_BLINK_IDX; - iwl_led_pattern(priv, IWL_SOLID_BLINK_IDX); - } + ret = led_classdev_register(&priv->pci_dev->dev, &priv->led); + if (ret) { + kfree(priv->led.name); return; } - if (!priv->last_blink_time || - !time_after(jiffies, priv->last_blink_time + - msecs_to_jiffies(1000))) - return; - - blink_idx = iwl_get_blink_rate(priv); - /* call only if blink rate change */ - if (blink_idx != priv->last_blink_rate) - iwl_led_pattern(priv, blink_idx); - - priv->last_blink_time = jiffies; - priv->last_blink_rate = blink_idx; + priv->led_registered = true; } -EXPORT_SYMBOL(iwl_leds_background); +EXPORT_SYMBOL(iwl_leds_init); -void iwl_leds_init(struct iwl_priv *priv) +void iwl_leds_exit(struct iwl_priv *priv) { - priv->last_blink_rate = 0; - priv->last_blink_time = 0; - priv->allow_blinking = 0; - if (led_mode != IWL_LED_DEFAULT && - led_mode != priv->cfg->led_mode) - priv->cfg->led_mode = led_mode; + if (!priv->led_registered) + return; + + led_classdev_unregister(&priv->led); + kfree(priv->led.name); } -EXPORT_SYMBOL(iwl_leds_init); +EXPORT_SYMBOL(iwl_leds_exit); diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h index 9079b33486ef..101eef12b3bb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-led.h @@ -31,23 +31,14 @@ struct iwl_priv; #define IWL_LED_SOLID 11 -#define IWL_LED_NAME_LEN 31 #define IWL_DEF_LED_INTRVL cpu_to_le32(1000) #define IWL_LED_ACTIVITY (0<<1) #define IWL_LED_LINK (1<<1) -enum led_type { - IWL_LED_TRG_TX, - IWL_LED_TRG_RX, - IWL_LED_TRG_ASSOC, - IWL_LED_TRG_RADIO, - IWL_LED_TRG_MAX, -}; - /* * LED mode - * IWL_LED_DEFAULT: use system default + * IWL_LED_DEFAULT: use device default * IWL_LED_RF_STATE: turn LED on/off based on RF state * LED ON = RF ON * LED OFF = RF OFF @@ -60,9 +51,6 @@ enum iwl_led_mode { }; void iwl_leds_init(struct iwl_priv *priv); -void iwl_leds_background(struct iwl_priv *priv); -int iwl_led_start(struct iwl_priv *priv); -int iwl_led_associate(struct iwl_priv *priv); -int iwl_led_disassociate(struct iwl_priv *priv); +void iwl_leds_exit(struct iwl_priv *priv); #endif /* __iwl_leds_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.c b/drivers/net/wireless/iwlwifi/iwl-legacy.c index bb1a742a98a0..927fe37a43ab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-legacy.c +++ b/drivers/net/wireless/iwlwifi/iwl-legacy.c @@ -332,7 +332,6 @@ static inline void iwl_set_no_assoc(struct iwl_priv *priv, { struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - iwl_led_disassociate(priv); /* * inform the ucode that there is no longer an * association and that no more packets should be @@ -520,8 +519,6 @@ void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, if (bss_conf->assoc) { priv->timestamp = bss_conf->timestamp; - iwl_led_associate(priv); - if (!iwl_is_rfkill(priv)) priv->cfg->ops->legacy->post_associate(priv); } else @@ -545,7 +542,6 @@ void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN); memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); - iwl_led_associate(priv); priv->cfg->ops->legacy->config_ap(priv); } else iwl_set_no_assoc(priv, vif); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 371abbf60eac..9c986f272c2d 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2540,8 +2540,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv) iwl3945_reg_txpower_periodic(priv); - iwl_leds_init(priv); - IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); set_bit(STATUS_READY, &priv->status); wake_up_interruptible(&priv->wait_command_queue); @@ -3170,8 +3168,6 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw) * no need to poll the killswitch state anymore */ cancel_delayed_work(&priv->_3945.rfkill_poll); - iwl_led_start(priv); - priv->is_open = 1; IWL_DEBUG_MAC80211(priv, "leave\n"); return 0; @@ -3935,6 +3931,8 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->bands[IEEE80211_BAND_5GHZ]; + iwl_leds_init(priv); + ret = ieee80211_register_hw(priv->hw); if (ret) { IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); @@ -4194,6 +4192,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) set_bit(STATUS_EXIT_PENDING, &priv->status); + iwl_leds_exit(priv); + if (priv->mac80211_registered) { ieee80211_unregister_hw(priv->hw); priv->mac80211_registered = 0; -- cgit v1.2.3 From 1956e1ad6292d257219d0f98a53f0a78ef282070 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 8 Jan 2011 10:25:14 -0800 Subject: iwlagn: remove reference to gen2a and gen2b Since 6005, 6030 and 6150 series are offical released, remove the reference to gen2x and use the product number instead. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-6000.c | 52 +++++++++++++++---------------- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 16 ++++++---- 2 files changed, 36 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index af505bcd7ae0..c195674454f4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -67,13 +67,13 @@ #define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode" #define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api) -#define IWL6000G2A_FW_PRE "iwlwifi-6000g2a-" -#define _IWL6000G2A_MODULE_FIRMWARE(api) IWL6000G2A_FW_PRE #api ".ucode" -#define IWL6000G2A_MODULE_FIRMWARE(api) _IWL6000G2A_MODULE_FIRMWARE(api) +#define IWL6005_FW_PRE "iwlwifi-6000g2a-" +#define _IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE #api ".ucode" +#define IWL6005_MODULE_FIRMWARE(api) _IWL6005_MODULE_FIRMWARE(api) -#define IWL6000G2B_FW_PRE "iwlwifi-6000g2b-" -#define _IWL6000G2B_MODULE_FIRMWARE(api) IWL6000G2B_FW_PRE #api ".ucode" -#define IWL6000G2B_MODULE_FIRMWARE(api) _IWL6000G2B_MODULE_FIRMWARE(api) +#define IWL6030_FW_PRE "iwlwifi-6000g2b-" +#define _IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE #api ".ucode" +#define IWL6030_MODULE_FIRMWARE(api) _IWL6030_MODULE_FIRMWARE(api) static void iwl6000_set_ct_threshold(struct iwl_priv *priv) { @@ -90,7 +90,7 @@ static void iwl6050_additional_nic_config(struct iwl_priv *priv) CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); } -static void iwl6050g2_additional_nic_config(struct iwl_priv *priv) +static void iwl6150_additional_nic_config(struct iwl_priv *priv) { /* Indicate calibration version to uCode. */ if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6) @@ -354,7 +354,7 @@ static struct iwl_lib_ops iwl6000_lib = { } }; -static struct iwl_lib_ops iwl6000g2b_lib = { +static struct iwl_lib_ops iwl6030_lib = { .set_hw_params = iwl6000_hw_set_hw_params, .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, @@ -430,8 +430,8 @@ static struct iwl_nic_ops iwl6050_nic_ops = { .additional_nic_config = &iwl6050_additional_nic_config, }; -static struct iwl_nic_ops iwl6050g2_nic_ops = { - .additional_nic_config = &iwl6050g2_additional_nic_config, +static struct iwl_nic_ops iwl6150_nic_ops = { + .additional_nic_config = &iwl6150_additional_nic_config, }; static const struct iwl_ops iwl6000_ops = { @@ -451,17 +451,17 @@ static const struct iwl_ops iwl6050_ops = { .ieee80211_ops = &iwlagn_hw_ops, }; -static const struct iwl_ops iwl6050g2_ops = { +static const struct iwl_ops iwl6150_ops = { .lib = &iwl6000_lib, .hcmd = &iwlagn_hcmd, .utils = &iwlagn_hcmd_utils, .led = &iwlagn_led_ops, - .nic = &iwl6050g2_nic_ops, + .nic = &iwl6150_nic_ops, .ieee80211_ops = &iwlagn_hw_ops, }; -static const struct iwl_ops iwl6000g2b_ops = { - .lib = &iwl6000g2b_lib, +static const struct iwl_ops iwl6030_ops = { + .lib = &iwl6030_lib, .hcmd = &iwlagn_bt_hcmd, .utils = &iwlagn_hcmd_utils, .led = &iwlagn_led_ops, @@ -555,11 +555,11 @@ static struct iwl_bt_params iwl6000_bt_params = { }; #define IWL_DEVICE_6005 \ - .fw_name_pre = IWL6000G2A_FW_PRE, \ + .fw_name_pre = IWL6005_FW_PRE, \ .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ - .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, \ - .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, \ + .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \ + .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ .ops = &iwl6000_ops, \ .mod_params = &iwlagn_mod_params, \ .base_params = &iwl6000_g2_base_params, \ @@ -584,12 +584,12 @@ struct iwl_cfg iwl6005_2bg_cfg = { }; #define IWL_DEVICE_6030 \ - .fw_name_pre = IWL6000G2B_FW_PRE, \ + .fw_name_pre = IWL6030_FW_PRE, \ .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ - .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, \ - .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, \ - .ops = &iwl6000g2b_ops, \ + .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \ + .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ + .ops = &iwl6030_ops, \ .mod_params = &iwlagn_mod_params, \ .base_params = &iwl6000_g2_base_params, \ .bt_params = &iwl6000_bt_params, \ @@ -706,9 +706,9 @@ struct iwl_cfg iwl6150_bgn_cfg = { .fw_name_pre = IWL6050_FW_PRE, .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, - .eeprom_ver = EEPROM_6050G2_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6050G2_TX_POWER_VERSION, - .ops = &iwl6050g2_ops, + .eeprom_ver = EEPROM_6150_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, + .ops = &iwl6150_ops, .mod_params = &iwlagn_mod_params, .base_params = &iwl6050_base_params, .ht_params = &iwl6000_ht_params, @@ -734,5 +734,5 @@ struct iwl_cfg iwl6000_3agn_cfg = { MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL6000G2B_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 9e6f31355eee..4f4cd4fddbf1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -247,13 +247,17 @@ struct iwl_eeprom_enhanced_txpwr { #define EEPROM_6050_TX_POWER_VERSION (4) #define EEPROM_6050_EEPROM_VERSION (0x532) -/* 6x50g2 Specific */ -#define EEPROM_6050G2_TX_POWER_VERSION (6) -#define EEPROM_6050G2_EEPROM_VERSION (0x553) +/* 6150 Specific */ +#define EEPROM_6150_TX_POWER_VERSION (6) +#define EEPROM_6150_EEPROM_VERSION (0x553) -/* 6x00g2 Specific */ -#define EEPROM_6000G2_TX_POWER_VERSION (6) -#define EEPROM_6000G2_EEPROM_VERSION (0x709) +/* 6x05 Specific */ +#define EEPROM_6005_TX_POWER_VERSION (6) +#define EEPROM_6005_EEPROM_VERSION (0x709) + +/* 6x30 Specific */ +#define EEPROM_6030_TX_POWER_VERSION (6) +#define EEPROM_6030_EEPROM_VERSION (0x709) /* OTP */ /* lower blocks contain EEPROM image and calibration data */ -- cgit v1.2.3 From fa57980e402cfe2e3651f1104c23a4517849ec91 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 8 Jan 2011 11:47:54 -0800 Subject: iwlagn: add 2000 series EEPROM version Adding EEPROM version for 2000 series devices Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 4f4cd4fddbf1..98aa8af01192 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -259,6 +259,15 @@ struct iwl_eeprom_enhanced_txpwr { #define EEPROM_6030_TX_POWER_VERSION (6) #define EEPROM_6030_EEPROM_VERSION (0x709) +/* 2x00 Specific */ +#define EEPROM_2000_TX_POWER_VERSION (6) +#define EEPROM_2000_EEPROM_VERSION (0x805) + +/* 6x35 Specific */ +#define EEPROM_6035_TX_POWER_VERSION (6) +#define EEPROM_6035_EEPROM_VERSION (0x753) + + /* OTP */ /* lower blocks contain EEPROM image and calibration data */ #define OTP_LOW_IMAGE_SIZE (2 * 512 * sizeof(u16)) /* 2 KB */ @@ -268,6 +277,7 @@ struct iwl_eeprom_enhanced_txpwr { #define OTP_MAX_LL_ITEMS_1000 (3) /* OTP blocks for 1000 */ #define OTP_MAX_LL_ITEMS_6x00 (4) /* OTP blocks for 6x00 */ #define OTP_MAX_LL_ITEMS_6x50 (7) /* OTP blocks for 6x50 */ +#define OTP_MAX_LL_ITEMS_2x00 (4) /* OTP blocks for 2x00 */ /* 2.4 GHz */ extern const u8 iwl_eeprom_band_1[14]; -- cgit v1.2.3 From c5a5e1853a6d87eb9f58bf8930e267d619dd24f6 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 21 Jan 2011 15:47:21 -0800 Subject: iwlagn: 2000 series devices support Adding 2000 series devices supports, the 2000 series devices has many different SKUs which includes 1x1 and 2x2 devices,also with and without BT combo. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/Makefile | 1 + drivers/net/wireless/iwlwifi/iwl-2000.c | 556 ++++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.h | 11 + 3 files changed, 568 insertions(+) create mode 100644 drivers/net/wireless/iwlwifi/iwl-2000.c (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 93380f97835f..25be742c69c9 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -26,6 +26,7 @@ iwlagn-$(CONFIG_IWL5000) += iwl-agn-rxon.o iwl-agn-hcmd.o iwl-agn-ict.o iwlagn-$(CONFIG_IWL5000) += iwl-5000.o iwlagn-$(CONFIG_IWL5000) += iwl-6000.o iwlagn-$(CONFIG_IWL5000) += iwl-1000.o +iwlagn-$(CONFIG_IWL5000) += iwl-2000.o # 3945 obj-$(CONFIG_IWL3945) += iwl3945.o diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c new file mode 100644 index 000000000000..3c9e1b5724c7 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -0,0 +1,556 @@ +/****************************************************************************** + * + * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iwl-eeprom.h" +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-io.h" +#include "iwl-sta.h" +#include "iwl-agn.h" +#include "iwl-helpers.h" +#include "iwl-agn-hw.h" +#include "iwl-6000-hw.h" +#include "iwl-agn-led.h" +#include "iwl-agn-debugfs.h" + +/* Highest firmware API version supported */ +#define IWL2030_UCODE_API_MAX 5 +#define IWL2000_UCODE_API_MAX 5 +#define IWL200_UCODE_API_MAX 5 + +/* Lowest firmware API version supported */ +#define IWL2030_UCODE_API_MIN 5 +#define IWL2000_UCODE_API_MIN 5 +#define IWL200_UCODE_API_MIN 5 + +#define IWL2030_FW_PRE "iwlwifi-2030-" +#define _IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode" +#define IWL2030_MODULE_FIRMWARE(api) _IWL2030_MODULE_FIRMWARE(api) + +#define IWL2000_FW_PRE "iwlwifi-2000-" +#define _IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode" +#define IWL2000_MODULE_FIRMWARE(api) _IWL2000_MODULE_FIRMWARE(api) + +#define IWL200_FW_PRE "iwlwifi-200-" +#define _IWL200_MODULE_FIRMWARE(api) IWL200_FW_PRE #api ".ucode" +#define IWL200_MODULE_FIRMWARE(api) _IWL200_MODULE_FIRMWARE(api) + +static void iwl2000_set_ct_threshold(struct iwl_priv *priv) +{ + /* want Celsius */ + priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD; + priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD; +} + +/* NIC configuration for 2000 series */ +static void iwl2000_nic_config(struct iwl_priv *priv) +{ + u16 radio_cfg; + + radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); + + /* write radio config values to register */ + if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | + EEPROM_RF_CFG_STEP_MSK(radio_cfg) | + EEPROM_RF_CFG_DASH_MSK(radio_cfg)); + + /* set CSR_HW_CONFIG_REG for uCode use */ + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | + CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); + +} + +static struct iwl_sensitivity_ranges iwl2000_sensitivity = { + .min_nrg_cck = 97, + .max_nrg_cck = 0, /* not used, set to 0 */ + .auto_corr_min_ofdm = 80, + .auto_corr_min_ofdm_mrc = 128, + .auto_corr_min_ofdm_x1 = 105, + .auto_corr_min_ofdm_mrc_x1 = 192, + + .auto_corr_max_ofdm = 145, + .auto_corr_max_ofdm_mrc = 232, + .auto_corr_max_ofdm_x1 = 110, + .auto_corr_max_ofdm_mrc_x1 = 232, + + .auto_corr_min_cck = 125, + .auto_corr_max_cck = 175, + .auto_corr_min_cck_mrc = 160, + .auto_corr_max_cck_mrc = 310, + .nrg_th_cck = 97, + .nrg_th_ofdm = 100, + + .barker_corr_th_min = 190, + .barker_corr_th_min_mrc = 390, + .nrg_th_cca = 62, +}; + +static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) +{ + if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && + priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) + priv->cfg->base_params->num_of_queues = + priv->cfg->mod_params->num_of_queues; + + priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; + priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; + priv->hw_params.scd_bc_tbls_size = + priv->cfg->base_params->num_of_queues * + sizeof(struct iwlagn_scd_bc_tbl); + priv->hw_params.tfd_size = sizeof(struct iwl_tfd); + priv->hw_params.max_stations = IWLAGN_STATION_COUNT; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; + + priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE; + priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE; + + priv->hw_params.max_bsm_size = 0; + priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | + BIT(IEEE80211_BAND_5GHZ); + priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; + + priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); + if (priv->cfg->rx_with_siso_diversity) + priv->hw_params.rx_chains_num = 1; + else + priv->hw_params.rx_chains_num = + num_of_ant(priv->cfg->valid_rx_ant); + priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; + priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; + + iwl2000_set_ct_threshold(priv); + + /* Set initial sensitivity parameters */ + /* Set initial calibration set */ + priv->hw_params.sens = &iwl2000_sensitivity; + priv->hw_params.calib_init_cfg = + BIT(IWL_CALIB_XTAL) | + BIT(IWL_CALIB_LO) | + BIT(IWL_CALIB_TX_IQ) | + BIT(IWL_CALIB_BASE_BAND); + if (priv->cfg->need_dc_calib) + priv->hw_params.calib_rt_cfg |= BIT(IWL_CALIB_CFG_DC_IDX); + if (priv->cfg->need_temp_offset_calib) + priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_TEMP_OFFSET); + + priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; + + return 0; +} + +static int iwl2030_hw_channel_switch(struct iwl_priv *priv, + struct ieee80211_channel_switch *ch_switch) +{ + /* + * MULTI-FIXME + * See iwl_mac_channel_switch. + */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + struct iwl6000_channel_switch_cmd cmd; + const struct iwl_channel_info *ch_info; + u32 switch_time_in_usec, ucode_switch_time; + u16 ch; + u32 tsf_low; + u8 switch_count; + u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); + struct ieee80211_vif *vif = ctx->vif; + struct iwl_host_cmd hcmd = { + .id = REPLY_CHANNEL_SWITCH, + .len = sizeof(cmd), + .flags = CMD_SYNC, + .data = &cmd, + }; + + cmd.band = priv->band == IEEE80211_BAND_2GHZ; + ch = ch_switch->channel->hw_value; + IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", + ctx->active.channel, ch); + cmd.channel = cpu_to_le16(ch); + cmd.rxon_flags = ctx->staging.flags; + cmd.rxon_filter_flags = ctx->staging.filter_flags; + switch_count = ch_switch->count; + tsf_low = ch_switch->timestamp & 0x0ffffffff; + /* + * calculate the ucode channel switch time + * adding TSF as one of the factor for when to switch + */ + if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) { + if (switch_count > ((priv->ucode_beacon_time - tsf_low) / + beacon_interval)) { + switch_count -= (priv->ucode_beacon_time - + tsf_low) / beacon_interval; + } else + switch_count = 0; + } + if (switch_count <= 1) + cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); + else { + switch_time_in_usec = + vif->bss_conf.beacon_int * switch_count * TIME_UNIT; + ucode_switch_time = iwl_usecs_to_beacons(priv, + switch_time_in_usec, + beacon_interval); + cmd.switch_time = iwl_add_beacon_time(priv, + priv->ucode_beacon_time, + ucode_switch_time, + beacon_interval); + } + IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", + cmd.switch_time); + ch_info = iwl_get_channel_info(priv, priv->band, ch); + if (ch_info) + cmd.expect_beacon = is_channel_radar(ch_info); + else { + IWL_ERR(priv, "invalid channel switch from %u to %u\n", + ctx->active.channel, ch); + return -EFAULT; + } + priv->switch_rxon.channel = cmd.channel; + priv->switch_rxon.switch_in_progress = true; + + return iwl_send_cmd_sync(priv, &hcmd); +} + +static struct iwl_lib_ops iwl2000_lib = { + .set_hw_params = iwl2000_hw_set_hw_params, + .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, + .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, + .txq_set_sched = iwlagn_txq_set_sched, + .txq_agg_enable = iwlagn_txq_agg_enable, + .txq_agg_disable = iwlagn_txq_agg_disable, + .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, + .txq_free_tfd = iwl_hw_txq_free_tfd, + .txq_init = iwl_hw_tx_queue_init, + .rx_handler_setup = iwlagn_rx_handler_setup, + .setup_deferred_work = iwlagn_setup_deferred_work, + .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, + .load_ucode = iwlagn_load_ucode, + .dump_nic_event_log = iwl_dump_nic_event_log, + .dump_nic_error_log = iwl_dump_nic_error_log, + .dump_csr = iwl_dump_csr, + .dump_fh = iwl_dump_fh, + .init_alive_start = iwlagn_init_alive_start, + .alive_notify = iwlagn_alive_notify, + .send_tx_power = iwlagn_send_tx_power, + .update_chain_flags = iwl_update_chain_flags, + .set_channel_switch = iwl2030_hw_channel_switch, + .apm_ops = { + .init = iwl_apm_init, + .config = iwl2000_nic_config, + }, + .eeprom_ops = { + .regulatory_bands = { + EEPROM_REG_BAND_1_CHANNELS, + EEPROM_REG_BAND_2_CHANNELS, + EEPROM_REG_BAND_3_CHANNELS, + EEPROM_REG_BAND_4_CHANNELS, + EEPROM_REG_BAND_5_CHANNELS, + EEPROM_6000_REG_BAND_24_HT40_CHANNELS, + EEPROM_REG_BAND_52_HT40_CHANNELS + }, + .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, + .release_semaphore = iwlcore_eeprom_release_semaphore, + .calib_version = iwlagn_eeprom_calib_version, + .query_addr = iwlagn_eeprom_query_addr, + .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, + }, + .isr_ops = { + .isr = iwl_isr_ict, + .free = iwl_free_isr_ict, + .alloc = iwl_alloc_isr_ict, + .reset = iwl_reset_ict, + .disable = iwl_disable_ict, + }, + .temp_ops = { + .temperature = iwlagn_temperature, + }, + .debugfs_ops = { + .rx_stats_read = iwl_ucode_rx_stats_read, + .tx_stats_read = iwl_ucode_tx_stats_read, + .general_stats_read = iwl_ucode_general_stats_read, + .bt_stats_read = iwl_ucode_bt_stats_read, + .reply_tx_error = iwl_reply_tx_error_read, + }, + .check_plcp_health = iwl_good_plcp_health, + .check_ack_health = iwl_good_ack_health, + .txfifo_flush = iwlagn_txfifo_flush, + .dev_txfifo_flush = iwlagn_dev_txfifo_flush, + .tt_ops = { + .lower_power_detection = iwl_tt_is_low_power_state, + .tt_power_mode = iwl_tt_current_power_mode, + .ct_kill_check = iwl_check_for_ct_kill, + } +}; + +static const struct iwl_ops iwl2000_ops = { + .lib = &iwl2000_lib, + .hcmd = &iwlagn_hcmd, + .utils = &iwlagn_hcmd_utils, + .led = &iwlagn_led_ops, + .ieee80211_ops = &iwlagn_hw_ops, +}; + +static const struct iwl_ops iwl2030_ops = { + .lib = &iwl2000_lib, + .hcmd = &iwlagn_bt_hcmd, + .utils = &iwlagn_hcmd_utils, + .led = &iwlagn_led_ops, + .ieee80211_ops = &iwlagn_hw_ops, +}; + +static const struct iwl_ops iwl200_ops = { + .lib = &iwl2000_lib, + .hcmd = &iwlagn_hcmd, + .utils = &iwlagn_hcmd_utils, + .led = &iwlagn_led_ops, + .ieee80211_ops = &iwlagn_hw_ops, +}; + +static const struct iwl_ops iwl230_ops = { + .lib = &iwl2000_lib, + .hcmd = &iwlagn_bt_hcmd, + .utils = &iwlagn_hcmd_utils, + .led = &iwlagn_led_ops, + .ieee80211_ops = &iwlagn_hw_ops, +}; + +static struct iwl_base_params iwl2000_base_params = { + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .num_of_queues = IWLAGN_NUM_QUEUES, + .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .pll_cfg_val = 0, + .set_l0s = true, + .use_bsm = false, + .max_ll_items = OTP_MAX_LL_ITEMS_2x00, + .shadow_ram_support = true, + .led_compensation = 51, + .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .supports_idle = true, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .wd_timeout = IWL_DEF_WD_TIMEOUT, + .max_event_log_size = 512, + .ucode_tracing = true, + .sensitivity_calib_by_driver = true, + .chain_noise_calib_by_driver = true, + .shadow_reg_enable = true, +}; + + +static struct iwl_base_params iwl2030_base_params = { + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .num_of_queues = IWLAGN_NUM_QUEUES, + .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .pll_cfg_val = 0, + .set_l0s = true, + .use_bsm = false, + .max_ll_items = OTP_MAX_LL_ITEMS_2x00, + .shadow_ram_support = true, + .led_compensation = 57, + .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .supports_idle = true, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .wd_timeout = IWL_LONG_WD_TIMEOUT, + .max_event_log_size = 512, + .ucode_tracing = true, + .sensitivity_calib_by_driver = true, + .chain_noise_calib_by_driver = true, + .shadow_reg_enable = true, +}; + +static struct iwl_ht_params iwl2000_ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ +}; + +static struct iwl_bt_params iwl2030_bt_params = { + .bt_statistics = true, + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .advanced_bt_coexist = true, + .agg_time_limit = BT_AGG_THRESHOLD_DEF, + .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, + .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, + .bt_sco_disable = true, +}; + +#define IWL_DEVICE_2000 \ + .fw_name_pre = IWL2000_FW_PRE, \ + .ucode_api_max = IWL2000_UCODE_API_MAX, \ + .ucode_api_min = IWL2000_UCODE_API_MIN, \ + .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ + .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ + .ops = &iwl2000_ops, \ + .mod_params = &iwlagn_mod_params, \ + .base_params = &iwl2000_base_params, \ + .need_dc_calib = true, \ + .need_temp_offset_calib = true, \ + .led_mode = IWL_LED_RF_STATE \ + +struct iwl_cfg iwl2000_2bgn_cfg = { + .name = "2000 Series 2x2 BGN", + IWL_DEVICE_2000, + .ht_params = &iwl2000_ht_params, +}; + +struct iwl_cfg iwl2000_2bg_cfg = { + .name = "2000 Series 2x2 BG", + IWL_DEVICE_2000, +}; + +#define IWL_DEVICE_2030 \ + .fw_name_pre = IWL2030_FW_PRE, \ + .ucode_api_max = IWL2030_UCODE_API_MAX, \ + .ucode_api_min = IWL2030_UCODE_API_MIN, \ + .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ + .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ + .ops = &iwl2030_ops, \ + .mod_params = &iwlagn_mod_params, \ + .base_params = &iwl2030_base_params, \ + .bt_params = &iwl2030_bt_params, \ + .need_dc_calib = true, \ + .need_temp_offset_calib = true, \ + .led_mode = IWL_LED_RF_STATE, \ + .adv_pm = true \ + +struct iwl_cfg iwl2030_2bgn_cfg = { + .name = "2000 Series 2x2 BGN/BT", + IWL_DEVICE_2000, + .ht_params = &iwl2000_ht_params, +}; + +struct iwl_cfg iwl2030_2bg_cfg = { + .name = "2000 Series 2x2 BG/BT", + IWL_DEVICE_2000, +}; + +#define IWL_DEVICE_6035 \ + .fw_name_pre = IWL2030_FW_PRE, \ + .ucode_api_max = IWL2030_UCODE_API_MAX, \ + .ucode_api_min = IWL2030_UCODE_API_MIN, \ + .eeprom_ver = EEPROM_6035_EEPROM_VERSION, \ + .eeprom_calib_ver = EEPROM_6035_TX_POWER_VERSION, \ + .ops = &iwl2030_ops, \ + .mod_params = &iwlagn_mod_params, \ + .base_params = &iwl2030_base_params, \ + .bt_params = &iwl2030_bt_params, \ + .need_dc_calib = true, \ + .need_temp_offset_calib = true, \ + .led_mode = IWL_LED_RF_STATE, \ + .adv_pm = true \ + +struct iwl_cfg iwl6035_2agn_cfg = { + .name = "2000 Series 2x2 AGN/BT", + IWL_DEVICE_6035, + .ht_params = &iwl2000_ht_params, +}; + +struct iwl_cfg iwl6035_2abg_cfg = { + .name = "2000 Series 2x2 ABG/BT", + IWL_DEVICE_6035, +}; + +struct iwl_cfg iwl6035_2bg_cfg = { + .name = "2000 Series 2x2 BG/BT", + IWL_DEVICE_6035, +}; + +#define IWL_DEVICE_200 \ + .fw_name_pre = IWL200_FW_PRE, \ + .ucode_api_max = IWL200_UCODE_API_MAX, \ + .ucode_api_min = IWL200_UCODE_API_MIN, \ + .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ + .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ + .ops = &iwl200_ops, \ + .mod_params = &iwlagn_mod_params, \ + .base_params = &iwl2000_base_params, \ + .need_dc_calib = true, \ + .need_temp_offset_calib = true, \ + .led_mode = IWL_LED_RF_STATE, \ + .adv_pm = true, \ + .rx_with_siso_diversity = true \ + +struct iwl_cfg iwl200_bg_cfg = { + .name = "200 Series 1x1 BG", + IWL_DEVICE_200, +}; + +struct iwl_cfg iwl200_bgn_cfg = { + .name = "200 Series 1x1 BGN", + IWL_DEVICE_200, + .ht_params = &iwl2000_ht_params, +}; + +#define IWL_DEVICE_230 \ + .fw_name_pre = IWL200_FW_PRE, \ + .ucode_api_max = IWL200_UCODE_API_MAX, \ + .ucode_api_min = IWL200_UCODE_API_MIN, \ + .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ + .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ + .ops = &iwl230_ops, \ + .mod_params = &iwlagn_mod_params, \ + .base_params = &iwl2030_base_params, \ + .bt_params = &iwl2030_bt_params, \ + .need_dc_calib = true, \ + .need_temp_offset_calib = true, \ + .led_mode = IWL_LED_RF_STATE, \ + .adv_pm = true, \ + .rx_with_siso_diversity = true \ + +struct iwl_cfg iwl230_bg_cfg = { + .name = "200 Series 1x1 BG/BT", + IWL_DEVICE_230, +}; + +struct iwl_cfg iwl230_bgn_cfg = { + .name = "200 Series 1x1 BGN/BT", + IWL_DEVICE_230, + .ht_params = &iwl2000_ht_params, +}; + +MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL200_MODULE_FIRMWARE(IWL200_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 74d72ff24d05..d00e1ea50a8d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -96,6 +96,17 @@ extern struct iwl_cfg iwl100_bgn_cfg; extern struct iwl_cfg iwl100_bg_cfg; extern struct iwl_cfg iwl130_bgn_cfg; extern struct iwl_cfg iwl130_bg_cfg; +extern struct iwl_cfg iwl2000_2bgn_cfg; +extern struct iwl_cfg iwl2000_2bg_cfg; +extern struct iwl_cfg iwl2030_2bgn_cfg; +extern struct iwl_cfg iwl2030_2bg_cfg; +extern struct iwl_cfg iwl6035_2agn_cfg; +extern struct iwl_cfg iwl6035_2abg_cfg; +extern struct iwl_cfg iwl6035_2bg_cfg; +extern struct iwl_cfg iwl200_bg_cfg; +extern struct iwl_cfg iwl200_bgn_cfg; +extern struct iwl_cfg iwl230_bg_cfg; +extern struct iwl_cfg iwl230_bgn_cfg; extern struct iwl_mod_params iwlagn_mod_params; extern struct iwl_hcmd_ops iwlagn_hcmd; -- cgit v1.2.3 From 04b8e7510015944a6c8198434cee14fb3bbff67a Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 8 Jan 2011 11:47:56 -0800 Subject: iwlagn: add 2000 series pci id Add PCI ID supports for all 2000 series devices Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 43 ++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 9240abf425c7..dad9a63b72be 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4512,6 +4512,49 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)}, {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)}, +/* 2x00 Series */ + {IWL_PCI_DEVICE(0x0890, 0x4022, iwl2000_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0891, 0x4222, iwl2000_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0890, 0x4422, iwl2000_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0890, 0x4026, iwl2000_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0891, 0x4226, iwl2000_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0890, 0x4426, iwl2000_2bg_cfg)}, + +/* 2x30 Series */ + {IWL_PCI_DEVICE(0x0887, 0x4062, iwl2030_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0888, 0x4262, iwl2030_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0887, 0x4462, iwl2030_2bgn_cfg)}, + {IWL_PCI_DEVICE(0x0887, 0x4066, iwl2030_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0888, 0x4266, iwl2030_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0887, 0x4466, iwl2030_2bg_cfg)}, + +/* 6x35 Series */ + {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, + {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4064, iwl6035_2abg_cfg)}, + {IWL_PCI_DEVICE(0x088F, 0x4264, iwl6035_2abg_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4464, iwl6035_2abg_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4066, iwl6035_2bg_cfg)}, + {IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)}, + +/* 200 Series */ + {IWL_PCI_DEVICE(0x0894, 0x0022, iwl200_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0895, 0x0222, iwl200_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0894, 0x0422, iwl200_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0894, 0x0026, iwl200_bg_cfg)}, + {IWL_PCI_DEVICE(0x0895, 0x0226, iwl200_bg_cfg)}, + {IWL_PCI_DEVICE(0x0894, 0x0426, iwl200_bg_cfg)}, + +/* 230 Series */ + {IWL_PCI_DEVICE(0x0892, 0x0062, iwl230_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0893, 0x0262, iwl230_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0892, 0x0462, iwl230_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0892, 0x0066, iwl230_bg_cfg)}, + {IWL_PCI_DEVICE(0x0893, 0x0266, iwl230_bg_cfg)}, + {IWL_PCI_DEVICE(0x0892, 0x0466, iwl230_bg_cfg)}, + #endif /* CONFIG_IWL5000 */ {0} -- cgit v1.2.3 From d380cbceea926795efe5ef434c60ed03859425eb Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 11 Jan 2011 15:54:19 -0800 Subject: iwlagn: add 2000 series to Kconfig Add 2000 series support to Kconfig Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 8994d3072715..442a146e5b3b 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -113,6 +113,7 @@ config IWL5000 Intel 6000 Gen 2 Series Wi-Fi Adapters (6000G2A and 6000G2B) Intel WIreless WiFi Link 6050BGN Gen 2 Adapter Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN) + Intel 2000 Series Wi-Fi Adapters config IWL3945 tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)" -- cgit v1.2.3 From 52d8a50c39e95bce686cb5c5da4dbb2f61ffb92b Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 11 Jan 2011 15:59:49 -0800 Subject: iwlagn: remove Gen2 from Kconfig Remove Gen 2 from Kconfig file since 6005/6030/6150 series of products are released. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 442a146e5b3b..236f9000b895 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -110,8 +110,9 @@ config IWL5000 Intel WiFi Link 1000BGN Intel Wireless WiFi 5150AGN Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN - Intel 6000 Gen 2 Series Wi-Fi Adapters (6000G2A and 6000G2B) - Intel WIreless WiFi Link 6050BGN Gen 2 Adapter + Intel 6005 Series Wi-Fi Adapters + Intel 6030 Series Wi-Fi Adapters + Intel Wireless WiFi Link 6150BGN 2 Adapter Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN) Intel 2000 Series Wi-Fi Adapters -- cgit v1.2.3 From 14a75766f38d44ca715d9e9ccb0a69e065e4a24e Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 10 Jan 2011 14:24:28 -0800 Subject: iwlwifi: remove g2 from csr hw rev Remove refernce of g2 and use offical number for hw rev. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-csr.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index b80bf7dff55b..cb77c0fcf3b8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -300,8 +300,9 @@ #define CSR_HW_REV_TYPE_1000 (0x0000060) #define CSR_HW_REV_TYPE_6x00 (0x0000070) #define CSR_HW_REV_TYPE_6x50 (0x0000080) -#define CSR_HW_REV_TYPE_6x50g2 (0x0000084) -#define CSR_HW_REV_TYPE_6x00g2 (0x00000B0) +#define CSR_HW_REV_TYPE_6150 (0x0000084) +#define CSR_HW_REV_TYPE_6x05 (0x00000B0) +#define CSR_HW_REV_TYPE_6x30 CSR_HW_REV_TYPE_6x05 #define CSR_HW_REV_TYPE_NONE (0x00000F0) /* EEPROM REG */ -- cgit v1.2.3 From fcdf1f73fe913c5f16b7f0547cc3df1b0796689f Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 10 Jan 2011 14:34:38 -0800 Subject: iwlwifi: add hw rev for 2000 series devices 2000 series device has different HW rev, add it Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-csr.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index cb77c0fcf3b8..6c2b2df7ee7e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -290,7 +290,7 @@ /* HW REV */ -#define CSR_HW_REV_TYPE_MSK (0x00000F0) +#define CSR_HW_REV_TYPE_MSK (0x00001F0) #define CSR_HW_REV_TYPE_3945 (0x00000D0) #define CSR_HW_REV_TYPE_4965 (0x0000000) #define CSR_HW_REV_TYPE_5300 (0x0000020) @@ -303,7 +303,12 @@ #define CSR_HW_REV_TYPE_6150 (0x0000084) #define CSR_HW_REV_TYPE_6x05 (0x00000B0) #define CSR_HW_REV_TYPE_6x30 CSR_HW_REV_TYPE_6x05 -#define CSR_HW_REV_TYPE_NONE (0x00000F0) +#define CSR_HW_REV_TYPE_6x35 CSR_HW_REV_TYPE_6x05 +#define CSR_HW_REV_TYPE_2x30 (0x00000C0) +#define CSR_HW_REV_TYPE_2x00 (0x0000100) +#define CSR_HW_REV_TYPE_200 (0x0000110) +#define CSR_HW_REV_TYPE_230 (0x0000120) +#define CSR_HW_REV_TYPE_NONE (0x00001F0) /* EEPROM REG */ #define CSR_EEPROM_REG_READ_VALID_MSK (0x00000001) -- cgit v1.2.3 From 24834d2c8455a6eeee82e007d41d7e05986d134f Mon Sep 17 00:00:00 2001 From: Jay Sternberg Date: Tue, 11 Jan 2011 15:41:00 -0800 Subject: iwlwifi: correct debugfs data dumped from sram the sram data dumped through the debugfs interface would only work properly when dumping data on even u32 boundaries and swap bytes based on endianness on that boundary making byte arrays impossible to read. now addresses are displayed at the start of every line and the data is displayed consistently if dumping 1 byte or 20 and regardless of what is the starting address. if no lenght given, address displayed is u32 in device format Signed-off-by: Jay Sternberg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 81 +++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 7f11a448d518..418c8ac26222 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -207,18 +207,19 @@ static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file, return ret; } -#define BYTE1_MASK 0x000000ff; -#define BYTE2_MASK 0x0000ffff; -#define BYTE3_MASK 0x00ffffff; static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { - u32 val; + u32 val = 0; char *buf; ssize_t ret; - int i; + int i = 0; + bool device_format = false; + int offset = 0; + int len = 0; int pos = 0; + int sram; struct iwl_priv *priv = file->private_data; size_t bufsz; @@ -230,35 +231,62 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, else priv->dbgfs_sram_len = priv->ucode_data.len; } - bufsz = 30 + priv->dbgfs_sram_len * sizeof(char) * 10; + len = priv->dbgfs_sram_len; + + if (len == -4) { + device_format = true; + len = 4; + } + + bufsz = 50 + len * 4; buf = kmalloc(bufsz, GFP_KERNEL); if (!buf) return -ENOMEM; + pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", - priv->dbgfs_sram_len); + len); pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", priv->dbgfs_sram_offset); - for (i = priv->dbgfs_sram_len; i > 0; i -= 4) { - val = iwl_read_targ_mem(priv, priv->dbgfs_sram_offset + \ - priv->dbgfs_sram_len - i); - if (i < 4) { - switch (i) { - case 1: - val &= BYTE1_MASK; - break; - case 2: - val &= BYTE2_MASK; - break; - case 3: - val &= BYTE3_MASK; - break; - } + + /* adjust sram address since reads are only on even u32 boundaries */ + offset = priv->dbgfs_sram_offset & 0x3; + sram = priv->dbgfs_sram_offset & ~0x3; + + /* read the first u32 from sram */ + val = iwl_read_targ_mem(priv, sram); + + for (; len; len--) { + /* put the address at the start of every line */ + if (i == 0) + pos += scnprintf(buf + pos, bufsz - pos, + "%08X: ", sram + offset); + + if (device_format) + pos += scnprintf(buf + pos, bufsz - pos, + "%02x", (val >> (8 * (3 - offset))) & 0xff); + else + pos += scnprintf(buf + pos, bufsz - pos, + "%02x ", (val >> (8 * offset)) & 0xff); + + /* if all bytes processed, read the next u32 from sram */ + if (++offset == 4) { + sram += 4; + offset = 0; + val = iwl_read_targ_mem(priv, sram); } - if (!(i % 16)) + + /* put in extra spaces and split lines for human readability */ + if (++i == 16) { + i = 0; pos += scnprintf(buf + pos, bufsz - pos, "\n"); - pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val); + } else if (!(i & 7)) { + pos += scnprintf(buf + pos, bufsz - pos, " "); + } else if (!(i & 3)) { + pos += scnprintf(buf + pos, bufsz - pos, " "); + } } - pos += scnprintf(buf + pos, bufsz - pos, "\n"); + if (i) + pos += scnprintf(buf + pos, bufsz - pos, "\n"); ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); @@ -282,6 +310,9 @@ static ssize_t iwl_dbgfs_sram_write(struct file *file, if (sscanf(buf, "%x,%x", &offset, &len) == 2) { priv->dbgfs_sram_offset = offset; priv->dbgfs_sram_len = len; + } else if (sscanf(buf, "%x", &offset) == 1) { + priv->dbgfs_sram_offset = offset; + priv->dbgfs_sram_len = -4; } else { priv->dbgfs_sram_offset = 0; priv->dbgfs_sram_len = 0; -- cgit v1.2.3 From 9d4dea7259d2fccf447f20788300121cf1d014bb Mon Sep 17 00:00:00 2001 From: Meenakshi Venkataraman Date: Thu, 13 Jan 2011 11:35:26 -0800 Subject: iwlagn: Enable idle powersave mode in 1000 series The iwlagn powersave algorithm uses the supports_idle parameter to tell the device to save power when it is not associated with an AP and is idle. Enable this feature for the 1000 series of devices. Reported-by: Johannes Berg Signed-off-by: Meenakshi Venkataraman Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index ba78bc8a259f..127723e6319f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -270,6 +270,7 @@ static struct iwl_base_params iwl1000_base_params = { .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, + .supports_idle = true, }; static struct iwl_ht_params iwl1000_ht_params = { .ht_greenfield_support = true, -- cgit v1.2.3 From 9b9190d9688ccf531a3a5dac84d7b9654a08bfc5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 6 Jan 2011 08:07:10 -0800 Subject: iwlwifi: implement remain-on-channel For device supporting PAN/P2P, use the PAN context to implement the remain-on-channel operation using device offloads so that the filters in the device will be programmed correctly -- otherwise we cannot receive any probe request frames during off-channel periods. Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 6 +- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 17 ++++++ drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 9 ++- drivers/net/wireless/iwlwifi/iwl-agn.c | 94 +++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 6 ++ 5 files changed, 130 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 366340f3fb0f..fa6cf2a3326d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -305,7 +305,11 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) cmd.slots[0].type = 0; /* BSS */ cmd.slots[1].type = 1; /* PAN */ - if (ctx_bss->vif && ctx_pan->vif) { + if (priv->_agn.hw_roc_channel) { + /* both contexts must be used for this to happen */ + slot1 = priv->_agn.hw_roc_duration; + slot0 = 20; + } else if (ctx_bss->vif && ctx_pan->vif) { int bcnint = ctx_pan->vif->bss_conf.beacon_int; int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index f693293b6bd1..2a4ff832fbb8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -156,6 +156,23 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) /* always get timestamp with Rx frame */ ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; + if (ctx->ctxid == IWL_RXON_CTX_PAN && priv->_agn.hw_roc_channel) { + struct ieee80211_channel *chan = priv->_agn.hw_roc_channel; + + iwl_set_rxon_channel(priv, chan, ctx); + iwl_set_flags_for_band(priv, ctx, chan->band, NULL); + ctx->staging.filter_flags |= + RXON_FILTER_ASSOC_MSK | + RXON_FILTER_PROMISC_MSK | + RXON_FILTER_CTL2HOST_MSK; + ctx->staging.dev_type = RXON_DEV_TYPE_P2P; + new_assoc = true; + + if (memcmp(&ctx->staging, &ctx->active, + sizeof(ctx->staging)) == 0) + return 0; + } + if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK)) ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 24a11b8f73bc..266490d8a397 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -539,7 +539,14 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) unsigned long flags; bool is_agg = false; - if (info->control.vif) + /* + * If the frame needs to go out off-channel, then + * we'll have put the PAN context to that channel, + * so make the frame go out there. + */ + if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) + ctx = &priv->contexts[IWL_RXON_CTX_PAN]; + else if (info->control.vif) ctx = iwl_rxon_ctx_from_vif(info->control.vif); spin_lock_irqsave(&priv->lock, flags); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index dad9a63b72be..51e5ea4aeb2a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3208,6 +3208,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, hw->wiphy->interface_modes |= ctx->exclusive_interface_modes; } + hw->wiphy->max_remain_on_channel_duration = 1000; + hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS; @@ -3726,6 +3728,95 @@ done: IWL_DEBUG_MAC80211(priv, "leave\n"); } +static void iwlagn_disable_roc(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; + struct ieee80211_channel *chan = ACCESS_ONCE(priv->hw->conf.channel); + + lockdep_assert_held(&priv->mutex); + + if (!ctx->is_active) + return; + + ctx->staging.dev_type = RXON_DEV_TYPE_2STA; + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwl_set_rxon_channel(priv, chan, ctx); + iwl_set_flags_for_band(priv, ctx, chan->band, NULL); + + priv->_agn.hw_roc_channel = NULL; + + iwlagn_commit_rxon(priv, ctx); + + ctx->is_active = false; +} + +static void iwlagn_bg_roc_done(struct work_struct *work) +{ + struct iwl_priv *priv = container_of(work, struct iwl_priv, + _agn.hw_roc_work.work); + + mutex_lock(&priv->mutex); + ieee80211_remain_on_channel_expired(priv->hw); + iwlagn_disable_roc(priv); + mutex_unlock(&priv->mutex); +} + +static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw, + struct ieee80211_channel *channel, + enum nl80211_channel_type channel_type, + int duration) +{ + struct iwl_priv *priv = hw->priv; + int err = 0; + + if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN))) + return -EOPNOTSUPP; + + if (!(priv->contexts[IWL_RXON_CTX_PAN].interface_modes & + BIT(NL80211_IFTYPE_P2P_CLIENT))) + return -EOPNOTSUPP; + + mutex_lock(&priv->mutex); + + if (priv->contexts[IWL_RXON_CTX_PAN].is_active || + test_bit(STATUS_SCAN_HW, &priv->status)) { + err = -EBUSY; + goto out; + } + + priv->contexts[IWL_RXON_CTX_PAN].is_active = true; + priv->_agn.hw_roc_channel = channel; + priv->_agn.hw_roc_chantype = channel_type; + priv->_agn.hw_roc_duration = DIV_ROUND_UP(duration * 1000, 1024); + iwlagn_commit_rxon(priv, &priv->contexts[IWL_RXON_CTX_PAN]); + queue_delayed_work(priv->workqueue, &priv->_agn.hw_roc_work, + msecs_to_jiffies(duration + 20)); + + msleep(20); + ieee80211_ready_on_channel(priv->hw); + + out: + mutex_unlock(&priv->mutex); + + return err; +} + +static int iwl_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) +{ + struct iwl_priv *priv = hw->priv; + + if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN))) + return -EOPNOTSUPP; + + cancel_delayed_work_sync(&priv->_agn.hw_roc_work); + + mutex_lock(&priv->mutex); + iwlagn_disable_roc(priv); + mutex_unlock(&priv->mutex); + + return 0; +} + /***************************************************************************** * * driver setup and teardown @@ -3747,6 +3838,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config); INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); + INIT_DELAYED_WORK(&priv->_agn.hw_roc_work, iwlagn_bg_roc_done); iwl_setup_scan_deferred_work(priv); @@ -3915,6 +4007,8 @@ struct ieee80211_ops iwlagn_hw_ops = { .channel_switch = iwlagn_mac_channel_switch, .flush = iwlagn_mac_flush, .tx_last_beacon = iwl_mac_tx_last_beacon, + .remain_on_channel = iwl_mac_remain_on_channel, + .cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel, }; #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 6dd6508c93b0..6fa1383d72ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1488,6 +1488,12 @@ struct iwl_priv { struct list_head notif_waits; spinlock_t notif_wait_lock; wait_queue_head_t notif_waitq; + + /* remain-on-channel offload support */ + struct ieee80211_channel *hw_roc_channel; + struct delayed_work hw_roc_work; + enum nl80211_channel_type hw_roc_chantype; + int hw_roc_duration; } _agn; #endif }; -- cgit v1.2.3 From 940739196c78576590dd155c1b9d8a705cea2af1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 6 Jan 2011 08:07:11 -0800 Subject: iwlwifi: replace minimum slot time constant There are a number of places where the minimum slot time is hardcoded to 20 TU, add a new constant for that and use it everywhere. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 14 +++++++------- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-commands.h | 5 +++++ 3 files changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index fa6cf2a3326d..41543ad4cb84 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -308,7 +308,7 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) if (priv->_agn.hw_roc_channel) { /* both contexts must be used for this to happen */ slot1 = priv->_agn.hw_roc_duration; - slot0 = 20; + slot0 = IWL_MIN_SLOT_TIME; } else if (ctx_bss->vif && ctx_pan->vif) { int bcnint = ctx_pan->vif->bss_conf.beacon_int; int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1; @@ -334,12 +334,12 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) if (test_bit(STATUS_SCAN_HW, &priv->status) || (!ctx_bss->vif->bss_conf.idle && !ctx_bss->vif->bss_conf.assoc)) { - slot0 = dtim * bcnint * 3 - 20; - slot1 = 20; + slot0 = dtim * bcnint * 3 - IWL_MIN_SLOT_TIME; + slot1 = IWL_MIN_SLOT_TIME; } else if (!ctx_pan->vif->bss_conf.idle && !ctx_pan->vif->bss_conf.assoc) { - slot1 = bcnint * 3 - 20; - slot0 = 20; + slot1 = bcnint * 3 - IWL_MIN_SLOT_TIME; + slot0 = IWL_MIN_SLOT_TIME; } } else if (ctx_pan->vif) { slot0 = 0; @@ -348,8 +348,8 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1); if (test_bit(STATUS_SCAN_HW, &priv->status)) { - slot0 = slot1 * 3 - 20; - slot1 = 20; + slot0 = slot1 * 3 - IWL_MIN_SLOT_TIME; + slot1 = IWL_MIN_SLOT_TIME; } } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 51e5ea4aeb2a..02771ef787fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3792,7 +3792,7 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw, queue_delayed_work(priv->workqueue, &priv->_agn.hw_roc_work, msecs_to_jiffies(duration + 20)); - msleep(20); + msleep(IWL_MIN_SLOT_TIME); /* TU is almost ms */ ieee80211_ready_on_channel(priv->hw); out: diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index abe2479215f0..935b19e2c260 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -4370,6 +4370,11 @@ int iwl_agn_check_rxon_cmd(struct iwl_priv *priv); * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification) */ +/* + * Minimum slot time in TU + */ +#define IWL_MIN_SLOT_TIME 20 + /** * struct iwl_wipan_slot * @width: Time in TU -- cgit v1.2.3 From f35c0c560994226847fa33f0021046a44ab1460f Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 13 Jan 2011 17:09:29 -0800 Subject: iwlwifi: initial P2P support If PAN functionality is present, advertise P2P interface type support and thus support for P2P. However, the support is currently somewhat incomplete -- NoA schedule isn't added to probe responses, and 11b bitrates may be used still, etc. Therefore, make it all optional with a Kconfig option. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/Kconfig | 16 ++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++++ drivers/net/wireless/iwlwifi/iwl-core.c | 5 +++-- 3 files changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 236f9000b895..e1e3b1cf3cff 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -116,6 +116,22 @@ config IWL5000 Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN) Intel 2000 Series Wi-Fi Adapters +config IWL_P2P + bool "iwlwifi experimental P2P support" + depends on IWL5000 + help + This option enables experimental P2P support for some devices + based on microcode support. Since P2P support is still under + development, this option may even enable it for some devices + now that turn out to not support it in the future due to + microcode restrictions. + + To determine if your microcode supports the experimental P2P + offered by this option, check if the driver advertises AP + support when it is loaded. + + Say Y only if you want to experiment with P2P. + config IWL3945 tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)" depends on IWLWIFI diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 02771ef787fd..eb16647cfbe0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4136,6 +4136,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE; priv->contexts[IWL_RXON_CTX_PAN].interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP); +#ifdef CONFIG_IWL_P2P + priv->contexts[IWL_RXON_CTX_PAN].interface_modes |= + BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO); +#endif priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP; priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA; priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 8e1b8014ddc1..a46ad60216a0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1404,9 +1404,10 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; struct iwl_rxon_context *tmp, *ctx = NULL; int err; + enum nl80211_iftype viftype = ieee80211_vif_type_p2p(vif); IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", - vif->type, vif->addr); + viftype, vif->addr); mutex_lock(&priv->mutex); @@ -1430,7 +1431,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) continue; } - if (!(possible_modes & BIT(vif->type))) + if (!(possible_modes & BIT(viftype))) continue; /* have maybe usable context w/o interface */ -- cgit v1.2.3 From 60678b60d78cd268a3aed3044dfbbb85760b2c54 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sun, 19 Dec 2010 21:54:48 +0100 Subject: USB: add helper to convert USB error codes This converts error codes specific to USB to generic error codes that can be returned to user space. Tests showed that it is so small that it is better inlined. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/usb.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index b975450f403e..a9cf484ecae4 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -122,6 +122,19 @@ static inline int is_usb_device_driver(struct device_driver *drv) for_devices; } +/* translate USB error codes to codes user space understands */ +static inline int usb_translate_errors(int error_code) +{ + switch (error_code) { + case 0: + case -ENOMEM: + case -ENODEV: + return error_code; + default: + return -EIO; + } +} + /* for labeling diagnostics */ extern const char *usbcore_name; -- cgit v1.2.3 From 0828376deadb93f2e839900065f536ddc1190e73 Mon Sep 17 00:00:00 2001 From: Tobias Ollmann Date: Sat, 25 Dec 2010 11:17:01 +0100 Subject: USB: Core: Fix minor coding style issues Fixing all coding style issues in buffer.c Signed-off-by: Tobias Ollmann Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/buffer.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index 2c6965484fe8..b0585e623ba9 100644 --- a/drivers/usb/core/buffer.c +++ b/drivers/usb/core/buffer.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include @@ -22,7 +22,7 @@ */ /* FIXME tune these based on pool statistics ... */ -static const size_t pool_max [HCD_BUFFER_POOLS] = { +static const size_t pool_max[HCD_BUFFER_POOLS] = { /* platforms without dma-friendly caches might need to * prevent cacheline sharing... */ @@ -51,7 +51,7 @@ static const size_t pool_max [HCD_BUFFER_POOLS] = { int hcd_buffer_create(struct usb_hcd *hcd) { char name[16]; - int i, size; + int i, size; if (!hcd->self.controller->dma_mask && !(hcd->driver->flags & HCD_LOCAL_MEM)) @@ -64,7 +64,7 @@ int hcd_buffer_create(struct usb_hcd *hcd) snprintf(name, sizeof name, "buffer-%d", size); hcd->pool[i] = dma_pool_create(name, hcd->self.controller, size, size, 0); - if (!hcd->pool [i]) { + if (!hcd->pool[i]) { hcd_buffer_destroy(hcd); return -ENOMEM; } @@ -99,14 +99,14 @@ void hcd_buffer_destroy(struct usb_hcd *hcd) */ void *hcd_buffer_alloc( - struct usb_bus *bus, + struct usb_bus *bus, size_t size, gfp_t mem_flags, dma_addr_t *dma ) { struct usb_hcd *hcd = bus_to_hcd(bus); - int i; + int i; /* some USB hosts just use PIO */ if (!bus->controller->dma_mask && @@ -116,21 +116,21 @@ void *hcd_buffer_alloc( } for (i = 0; i < HCD_BUFFER_POOLS; i++) { - if (size <= pool_max [i]) - return dma_pool_alloc(hcd->pool [i], mem_flags, dma); + if (size <= pool_max[i]) + return dma_pool_alloc(hcd->pool[i], mem_flags, dma); } return dma_alloc_coherent(hcd->self.controller, size, dma, mem_flags); } void hcd_buffer_free( - struct usb_bus *bus, + struct usb_bus *bus, size_t size, - void *addr, + void *addr, dma_addr_t dma ) { struct usb_hcd *hcd = bus_to_hcd(bus); - int i; + int i; if (!addr) return; @@ -142,8 +142,8 @@ void hcd_buffer_free( } for (i = 0; i < HCD_BUFFER_POOLS; i++) { - if (size <= pool_max [i]) { - dma_pool_free(hcd->pool [i], addr, dma); + if (size <= pool_max[i]) { + dma_pool_free(hcd->pool[i], addr, dma); return; } } -- cgit v1.2.3 From 32b801e9fa5e05c179b86802ccb19b3b97d47471 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Fri, 31 Dec 2010 09:40:21 -0800 Subject: USB: wusbcore: rh.c Typo change desciptor to descriptor. Change a typo from "desciptor" to "descriptor". Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/usb/wusbcore/rh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c index a68ad7aa0b59..785772e66ed0 100644 --- a/drivers/usb/wusbcore/rh.c +++ b/drivers/usb/wusbcore/rh.c @@ -156,7 +156,7 @@ int wusbhc_rh_status_data(struct usb_hcd *usb_hcd, char *_buf) EXPORT_SYMBOL_GPL(wusbhc_rh_status_data); /* - * Return the hub's desciptor + * Return the hub's descriptor * * NOTE: almost cut and paste from ehci-hub.c * -- cgit v1.2.3 From ef58d97a30af66b31f6400e49c87b4d64fc1f5bc Mon Sep 17 00:00:00 2001 From: Ferenc Wagner Date: Mon, 10 Jan 2011 19:00:35 +0100 Subject: USB: ehci-dbgp: fix typo in startup message Signed-off-by: Ferenc Wagner Signed-off-by: Greg Kroah-Hartman --- drivers/usb/early/ehci-dbgp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index 94ecdbc758ce..0bc06e2bcfcb 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c @@ -601,7 +601,7 @@ try_again: dbgp_printk("dbgp_bulk_write failed: %d\n", ret); goto err; } - dbgp_printk("small write doned\n"); + dbgp_printk("small write done\n"); dbgp_not_safe = 0; return 0; -- cgit v1.2.3 From 9abff15dd69c6f4ed88ecc8ba089f55e9cf6655e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 3 Jan 2011 14:49:42 +0100 Subject: USB: ueagle-atm: use system_wq instead of dedicated workqueues With cmwq, there's no reason to use separate workqueues. Drop uea_softc->work_q and use system_wq instead. The used work item is sync flushed on driver detach. Signed-off-by: Tejun Heo Cc: Stanislaw Gruszka Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/ueagle-atm.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 99ac70e32556..b268e9fccb47 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -168,7 +168,6 @@ struct uea_softc { union cmv_dsc cmv_dsc; struct work_struct task; - struct workqueue_struct *work_q; u16 pageno; u16 ovl; @@ -1879,7 +1878,7 @@ static int uea_start_reset(struct uea_softc *sc) /* start loading DSP */ sc->pageno = 0; sc->ovl = 0; - queue_work(sc->work_q, &sc->task); + schedule_work(&sc->task); /* wait for modem ready CMV */ ret = wait_cmv_ack(sc); @@ -2091,14 +2090,14 @@ static void uea_schedule_load_page_e1(struct uea_softc *sc, { sc->pageno = intr->e1_bSwapPageNo; sc->ovl = intr->e1_bOvl >> 4 | intr->e1_bOvl << 4; - queue_work(sc->work_q, &sc->task); + schedule_work(&sc->task); } static void uea_schedule_load_page_e4(struct uea_softc *sc, struct intr_pkt *intr) { sc->pageno = intr->e4_bSwapPageNo; - queue_work(sc->work_q, &sc->task); + schedule_work(&sc->task); } /* @@ -2170,13 +2169,6 @@ static int uea_boot(struct uea_softc *sc) init_waitqueue_head(&sc->sync_q); - sc->work_q = create_workqueue("ueagle-dsp"); - if (!sc->work_q) { - uea_err(INS_TO_USBDEV(sc), "cannot allocate workqueue\n"); - uea_leaves(INS_TO_USBDEV(sc)); - return -ENOMEM; - } - if (UEA_CHIP_VERSION(sc) == ADI930) load_XILINX_firmware(sc); @@ -2225,7 +2217,6 @@ err1: sc->urb_int = NULL; kfree(intr); err0: - destroy_workqueue(sc->work_q); uea_leaves(INS_TO_USBDEV(sc)); return -ENOMEM; } @@ -2246,8 +2237,8 @@ static void uea_stop(struct uea_softc *sc) kfree(sc->urb_int->transfer_buffer); usb_free_urb(sc->urb_int); - /* stop any pending boot process, when no one can schedule work */ - destroy_workqueue(sc->work_q); + /* flush the work item, when no one can schedule it */ + flush_work_sync(&sc->task); if (sc->dsp_firm) release_firmware(sc->dsp_firm); -- cgit v1.2.3 From f6c259a39fd7bb8db6661690976a0f05d12b707d Mon Sep 17 00:00:00 2001 From: Daniel Glöckner Date: Tue, 11 Jan 2011 00:42:14 +0100 Subject: USB: ftdi_sio: fix resolution of 2232H baud rate dividers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 2232H high speed baud rates also support fractional baud rate divisors, but when the performing the divisions before the multiplication, the fractional bits are lost. Signed-off-by: Daniel Glöckner Acked-by: Mark Adamson Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index a2668d089260..71a0f99023bd 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -955,7 +955,7 @@ static __u32 ftdi_2232h_baud_base_to_divisor(int baud, int base) int divisor3; /* hi-speed baud rate is 10-bit sampling instead of 16-bit */ - divisor3 = (base / 10 / baud) * 8; + divisor3 = base * 8 / (baud * 10); divisor = divisor3 >> 3; divisor |= (__u32)divfrac[divisor3 & 0x7] << 14; -- cgit v1.2.3 From 50a6cb932d5cccc6a165219f137b87ea596b4cd0 Mon Sep 17 00:00:00 2001 From: wwang Date: Fri, 14 Jan 2011 16:53:34 +0800 Subject: USB: usb_storage: add ums-realtek driver ums_realtek is used to support the power-saving function for Realtek RTS51xx USB card readers. Signed-off-by: wwang Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/Kconfig | 10 + drivers/usb/storage/Makefile | 2 + drivers/usb/storage/realtek_cr.c | 675 ++++++++++++++++++++++++++++++++++ drivers/usb/storage/unusual_realtek.h | 41 +++ drivers/usb/storage/usual-tables.c | 1 + 5 files changed, 729 insertions(+) create mode 100644 drivers/usb/storage/realtek_cr.c create mode 100644 drivers/usb/storage/unusual_realtek.h (limited to 'drivers') diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index 49a489e03716..353aeb44da6a 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -31,6 +31,16 @@ config USB_STORAGE_DEBUG Say Y here in order to have the USB Mass Storage code generate verbose debugging messages. +config USB_STORAGE_REALTEK + tristate "Realtek Card Reader support" + depends on USB_STORAGE + help + Say Y here to include additional code to support the power-saving function + for Realtek RTS51xx USB card readers. + + If this driver is compiled as a module, it will be named ums-realtek. + + config USB_STORAGE_DATAFAB tristate "Datafab Compact Flash Reader support" depends on USB_STORAGE diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index fcf14cdc4a04..0d2de971bd91 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_USB_STORAGE_ISD200) += ums-isd200.o obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += ums-jumpshot.o obj-$(CONFIG_USB_STORAGE_KARMA) += ums-karma.o obj-$(CONFIG_USB_STORAGE_ONETOUCH) += ums-onetouch.o +obj-$(CONFIG_USB_STORAGE_REALTEK) += ums-realtek.o obj-$(CONFIG_USB_STORAGE_SDDR09) += ums-sddr09.o obj-$(CONFIG_USB_STORAGE_SDDR55) += ums-sddr55.o obj-$(CONFIG_USB_STORAGE_USBAT) += ums-usbat.o @@ -42,6 +43,7 @@ ums-isd200-y := isd200.o ums-jumpshot-y := jumpshot.o ums-karma-y := karma.o ums-onetouch-y := onetouch.o +ums-realtek-y := realtek_cr.o ums-sddr09-y := sddr09.o ums-sddr55-y := sddr55.o ums-usbat-y := shuttle_usbat.o diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c new file mode 100644 index 000000000000..c2bebb3731d3 --- /dev/null +++ b/drivers/usb/storage/realtek_cr.c @@ -0,0 +1,675 @@ +/* Driver for Realtek RTS51xx USB card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "usb.h" +#include "transport.h" +#include "protocol.h" +#include "debug.h" + +MODULE_DESCRIPTION("Driver for Realtek USB Card Reader"); +MODULE_AUTHOR("wwang "); +MODULE_LICENSE("GPL"); +MODULE_VERSION("1.03"); + +static int auto_delink_en = 1; +module_param(auto_delink_en, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(auto_delink_en, "enable auto delink"); + +struct rts51x_status { + u16 vid; + u16 pid; + u8 cur_lun; + u8 card_type; + u8 total_lun; + u16 fw_ver; + u8 phy_exist; + u8 multi_flag; + u8 multi_card; + u8 log_exist; + union { + u8 detailed_type1; + u8 detailed_type2; + } detailed_type; + u8 function[2]; +}; + +struct rts51x_chip { + u16 vendor_id; + u16 product_id; + char max_lun; + + struct rts51x_status *status; + int status_len; + + u32 flag; +}; + +/* flag definition */ +#define FLIDX_AUTO_DELINK 0x01 + +#define SCSI_LUN(srb) ((srb)->device->lun) + +/* Bit Operation */ +#define SET_BIT(data, idx) ((data) |= 1 << (idx)) +#define CLR_BIT(data, idx) ((data) &= ~(1 << (idx))) +#define CHK_BIT(data, idx) ((data) & (1 << (idx))) + +#define SET_AUTO_DELINK(chip) ((chip)->flag |= FLIDX_AUTO_DELINK) +#define CLR_AUTO_DELINK(chip) ((chip)->flag &= ~FLIDX_AUTO_DELINK) +#define CHK_AUTO_DELINK(chip) ((chip)->flag & FLIDX_AUTO_DELINK) + +#define RTS51X_GET_VID(chip) ((chip)->vendor_id) +#define RTS51X_GET_PID(chip) ((chip)->product_id) + +#define FW_VERSION(chip) ((chip)->status[0].fw_ver) +#define STATUS_LEN(chip) ((chip)->status_len) + +/* Check card reader function */ +#define SUPPORT_DETAILED_TYPE1(chip) \ + CHK_BIT((chip)->status[0].function[0], 1) +#define SUPPORT_OT(chip) \ + CHK_BIT((chip)->status[0].function[0], 2) +#define SUPPORT_OC(chip) \ + CHK_BIT((chip)->status[0].function[0], 3) +#define SUPPORT_AUTO_DELINK(chip) \ + CHK_BIT((chip)->status[0].function[0], 4) +#define SUPPORT_SDIO(chip) \ + CHK_BIT((chip)->status[0].function[1], 0) +#define SUPPORT_DETAILED_TYPE2(chip) \ + CHK_BIT((chip)->status[0].function[1], 1) + +#define CHECK_PID(chip, pid) (RTS51X_GET_PID(chip) == (pid)) +#define CHECK_FW_VER(chip, fw_ver) (FW_VERSION(chip) == (fw_ver)) +#define CHECK_ID(chip, pid, fw_ver) \ + (CHECK_PID((chip), (pid)) && CHECK_FW_VER((chip), (fw_ver))) + +#define wait_timeout_x(task_state, msecs) \ +do { \ + set_current_state((task_state)); \ + schedule_timeout((msecs) * HZ / 1000); \ +} while (0) + +#define wait_timeout(msecs) \ + wait_timeout_x(TASK_INTERRUPTIBLE, (msecs)) + +static int init_realtek_cr(struct us_data *us); + +/* + * The table of devices + */ +#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ + vendorName, productName, useProtocol, useTransport, \ + initFunction, flags) \ +{\ + USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ + .driver_info = (flags)|(USB_US_TYPE_STOR<<24)\ +} + +struct usb_device_id realtek_cr_ids[] = { +# include "unusual_realtek.h" + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, realtek_cr_ids); + +#undef UNUSUAL_DEV + +/* + * The flags table + */ +#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ + vendor_name, product_name, use_protocol, use_transport, \ + init_function, Flags) \ +{ \ + .vendorName = vendor_name, \ + .productName = product_name, \ + .useProtocol = use_protocol, \ + .useTransport = use_transport, \ + .initFunction = init_function, \ +} + +static struct us_unusual_dev realtek_cr_unusual_dev_list[] = { +# include "unusual_realtek.h" + { } /* Terminating entry */ +}; + +#undef UNUSUAL_DEV + +static int rts51x_bulk_transport(struct us_data *us, u8 lun, + u8 *cmd, int cmd_len, u8 *buf, int buf_len, + enum dma_data_direction dir, int *act_len) +{ + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf; + int result; + unsigned int residue; + unsigned int cswlen; + unsigned int cbwlen = US_BULK_CB_WRAP_LEN; + + /* set up the command wrapper */ + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = cpu_to_le32(buf_len); + bcb->Flags = (dir == DMA_FROM_DEVICE) ? 1 << 7 : 0; + bcb->Tag = ++us->tag; + bcb->Lun = lun; + bcb->Length = cmd_len; + + /* copy the command payload */ + memset(bcb->CDB, 0, sizeof(bcb->CDB)); + memcpy(bcb->CDB, cmd, bcb->Length); + + /* send it to out endpoint */ + result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, + bcb, cbwlen, NULL); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + /* DATA STAGE */ + /* send/receive data payload, if there is any */ + + if (buf && buf_len) { + unsigned int pipe = (dir == DMA_FROM_DEVICE) ? + us->recv_bulk_pipe : us->send_bulk_pipe; + result = usb_stor_bulk_transfer_buf(us, pipe, + buf, buf_len, NULL); + if (result == USB_STOR_XFER_ERROR) + return USB_STOR_TRANSPORT_ERROR; + } + + /* get CSW for device status */ + result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, + bcs, US_BULK_CS_WRAP_LEN, &cswlen); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + /* check bulk status */ + if (bcs->Signature != cpu_to_le32(US_BULK_CS_SIGN)) { + US_DEBUGP("Signature mismatch: got %08X, expecting %08X\n", + le32_to_cpu(bcs->Signature), + US_BULK_CS_SIGN); + return USB_STOR_TRANSPORT_ERROR; + } + + residue = bcs->Residue; + if (bcs->Tag != us->tag) + return USB_STOR_TRANSPORT_ERROR; + + /* try to compute the actual residue, based on how much data + * was really transferred and what the device tells us */ + if (residue) + residue = residue < buf_len ? residue : buf_len; + + if (act_len) + *act_len = buf_len - residue; + + /* based on the status code, we report good or bad */ + switch (bcs->Status) { + case US_BULK_STAT_OK: + /* command good -- note that data could be short */ + return USB_STOR_TRANSPORT_GOOD; + + case US_BULK_STAT_FAIL: + /* command failed */ + return USB_STOR_TRANSPORT_FAILED; + + case US_BULK_STAT_PHASE: + /* phase error -- note that a transport reset will be + * invoked by the invoke_transport() function + */ + return USB_STOR_TRANSPORT_ERROR; + } + + /* we should never get here, but if we do, we're in trouble */ + return USB_STOR_TRANSPORT_ERROR; +} + +/* Determine what the maximum LUN supported is */ +static int rts51x_get_max_lun(struct us_data *us) +{ + int result; + + /* issue the command */ + us->iobuf[0] = 0; + result = usb_stor_control_msg(us, us->recv_ctrl_pipe, + US_BULK_GET_MAX_LUN, + USB_DIR_IN | USB_TYPE_CLASS | + USB_RECIP_INTERFACE, + 0, us->ifnum, us->iobuf, 1, 10*HZ); + + US_DEBUGP("GetMaxLUN command result is %d, data is %d\n", + result, us->iobuf[0]); + + /* if we have a successful request, return the result */ + if (result > 0) + return us->iobuf[0]; + + return 0; +} + +static int rts51x_read_mem(struct us_data *us, u16 addr, u8 *data, u16 len) +{ + int retval; + u8 cmnd[12] = {0}; + + US_DEBUGP("%s, addr = 0x%x, len = %d\n", __func__, addr, len); + + cmnd[0] = 0xF0; + cmnd[1] = 0x0D; + cmnd[2] = (u8)(addr >> 8); + cmnd[3] = (u8)addr; + cmnd[4] = (u8)(len >> 8); + cmnd[5] = (u8)len; + + retval = rts51x_bulk_transport(us, 0, cmnd, 12, + data, len, DMA_FROM_DEVICE, NULL); + if (retval != USB_STOR_TRANSPORT_GOOD) + return -EIO; + + return 0; +} + +static int rts51x_write_mem(struct us_data *us, u16 addr, u8 *data, u16 len) +{ + int retval; + u8 cmnd[12] = {0}; + + US_DEBUGP("%s, addr = 0x%x, len = %d\n", __func__, addr, len); + + cmnd[0] = 0xF0; + cmnd[1] = 0x0E; + cmnd[2] = (u8)(addr >> 8); + cmnd[3] = (u8)addr; + cmnd[4] = (u8)(len >> 8); + cmnd[5] = (u8)len; + + retval = rts51x_bulk_transport(us, 0, cmnd, 12, + data, len, DMA_TO_DEVICE, NULL); + if (retval != USB_STOR_TRANSPORT_GOOD) + return -EIO; + + return 0; +} + +static int rts51x_read_status(struct us_data *us, + u8 lun, u8 *status, int len, int *actlen) +{ + int retval; + u8 cmnd[12] = {0}; + + US_DEBUGP("%s, lun = %d\n", __func__, lun); + + cmnd[0] = 0xF0; + cmnd[1] = 0x09; + + retval = rts51x_bulk_transport(us, lun, cmnd, 12, + status, len, DMA_FROM_DEVICE, actlen); + if (retval != USB_STOR_TRANSPORT_GOOD) + return -EIO; + + return 0; +} + +static int rts51x_check_status(struct us_data *us, u8 lun) +{ + struct rts51x_chip *chip = (struct rts51x_chip *)(us->extra); + int retval; + u8 buf[16]; + + retval = rts51x_read_status(us, lun, buf, 16, &(chip->status_len)); + if (retval < 0) + return -EIO; + + US_DEBUGP("chip->status_len = %d\n", chip->status_len); + + chip->status[lun].vid = ((u16)buf[0] << 8) | buf[1]; + chip->status[lun].pid = ((u16)buf[2] << 8) | buf[3]; + chip->status[lun].cur_lun = buf[4]; + chip->status[lun].card_type = buf[5]; + chip->status[lun].total_lun = buf[6]; + chip->status[lun].fw_ver = ((u16)buf[7] << 8) | buf[8]; + chip->status[lun].phy_exist = buf[9]; + chip->status[lun].multi_flag = buf[10]; + chip->status[lun].multi_card = buf[11]; + chip->status[lun].log_exist = buf[12]; + if (chip->status_len == 16) { + chip->status[lun].detailed_type.detailed_type1 = buf[13]; + chip->status[lun].function[0] = buf[14]; + chip->status[lun].function[1] = buf[15]; + } + + return 0; +} + +static int enable_oscillator(struct us_data *us) +{ + int retval; + u8 value; + + retval = rts51x_read_mem(us, 0xFE77, &value, 1); + if (retval < 0) + return -EIO; + + value |= 0x04; + retval = rts51x_write_mem(us, 0xFE77, &value, 1); + if (retval < 0) + return -EIO; + + retval = rts51x_read_mem(us, 0xFE77, &value, 1); + if (retval < 0) + return -EIO; + + if (!(value & 0x04)) + return -EIO; + + return 0; +} + +static int do_config_autodelink(struct us_data *us, int enable, int force) +{ + int retval; + u8 value; + + retval = rts51x_read_mem(us, 0xFE47, &value, 1); + if (retval < 0) + return -EIO; + + if (enable) { + if (force) + value |= 0x03; + else + value |= 0x01; + } else { + value &= ~0x03; + } + + US_DEBUGP("In %s,set 0xfe47 to 0x%x\n", __func__, value); + + retval = rts51x_write_mem(us, 0xFE47, &value, 1); + if (retval < 0) + return -EIO; + + return 0; +} + +static int config_autodelink_after_power_on(struct us_data *us) +{ + struct rts51x_chip *chip = (struct rts51x_chip *)(us->extra); + int retval; + u8 value; + + if (!CHK_AUTO_DELINK(chip)) + return 0; + + retval = rts51x_read_mem(us, 0xFE47, &value, 1); + if (retval < 0) + return -EIO; + + if (auto_delink_en) { + CLR_BIT(value, 0); + CLR_BIT(value, 1); + SET_BIT(value, 2); + + if (CHECK_ID(chip, 0x0138, 0x3882)) + CLR_BIT(value, 2); + + SET_BIT(value, 7); + + retval = rts51x_write_mem(us, 0xFE47, &value, 1); + if (retval < 0) + return -EIO; + + retval = enable_oscillator(us); + if (retval == 0) + (void)do_config_autodelink(us, 1, 0); + } else { + /* Autodelink controlled by firmware */ + + SET_BIT(value, 2); + + if (CHECK_ID(chip, 0x0138, 0x3882)) + CLR_BIT(value, 2); + + if (CHECK_ID(chip, 0x0159, 0x5889) || + CHECK_ID(chip, 0x0138, 0x3880)) { + CLR_BIT(value, 0); + CLR_BIT(value, 7); + } + + retval = rts51x_write_mem(us, 0xFE47, &value, 1); + if (retval < 0) + return -EIO; + + if (CHECK_ID(chip, 0x0159, 0x5888)) { + value = 0xFF; + retval = rts51x_write_mem(us, 0xFE79, &value, 1); + if (retval < 0) + return -EIO; + + value = 0x01; + retval = rts51x_write_mem(us, 0x48, &value, 1); + if (retval < 0) + return -EIO; + } + } + + return 0; +} + +static int config_autodelink_before_power_down(struct us_data *us) +{ + struct rts51x_chip *chip = (struct rts51x_chip *)(us->extra); + int retval; + u8 value; + + if (!CHK_AUTO_DELINK(chip)) + return 0; + + if (auto_delink_en) { + retval = rts51x_read_mem(us, 0xFE77, &value, 1); + if (retval < 0) + return -EIO; + + SET_BIT(value, 2); + retval = rts51x_write_mem(us, 0xFE77, &value, 1); + if (retval < 0) + return -EIO; + + if (CHECK_ID(chip, 0x0159, 0x5888)) { + value = 0x01; + retval = rts51x_write_mem(us, 0x48, &value, 1); + if (retval < 0) + return -EIO; + } + + retval = rts51x_read_mem(us, 0xFE47, &value, 1); + if (retval < 0) + return -EIO; + + SET_BIT(value, 0); + if (CHECK_ID(chip, 0x0138, 0x3882)) + SET_BIT(value, 2); + retval = rts51x_write_mem(us, 0xFE77, &value, 1); + if (retval < 0) + return -EIO; + } else { + if (CHECK_ID(chip, 0x0159, 0x5889) || + CHECK_ID(chip, 0x0138, 0x3880) || + CHECK_ID(chip, 0x0138, 0x3882)) { + retval = rts51x_read_mem(us, 0xFE47, &value, 1); + if (retval < 0) + return -EIO; + + if (CHECK_ID(chip, 0x0159, 0x5889) || + CHECK_ID(chip, 0x0138, 0x3880)) { + SET_BIT(value, 0); + SET_BIT(value, 7); + } + + if (CHECK_ID(chip, 0x0138, 0x3882)) + SET_BIT(value, 2); + + retval = rts51x_write_mem(us, 0xFE47, &value, 1); + if (retval < 0) + return -EIO; + } + + if (CHECK_ID(chip, 0x0159, 0x5888)) { + value = 0x01; + retval = rts51x_write_mem(us, 0x48, &value, 1); + if (retval < 0) + return -EIO; + } + } + + return 0; +} + +static void realtek_cr_destructor(void *extra) +{ + struct rts51x_chip *chip = (struct rts51x_chip *)extra; + + if (!chip) + return; + + kfree(chip->status); +} + +#ifdef CONFIG_PM +void realtek_pm_hook(struct us_data *us, int pm_state) +{ + if (pm_state == US_SUSPEND) + (void)config_autodelink_before_power_down(us); +} +#endif + +static int init_realtek_cr(struct us_data *us) +{ + struct rts51x_chip *chip; + int size, i, retval; + + chip = kzalloc(sizeof(struct rts51x_chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + us->extra = chip; + us->extra_destructor = realtek_cr_destructor; +#ifdef CONFIG_PM + us->suspend_resume_hook = realtek_pm_hook; +#endif + + us->max_lun = chip->max_lun = rts51x_get_max_lun(us); + + US_DEBUGP("chip->max_lun = %d\n", chip->max_lun); + + size = (chip->max_lun + 1) * sizeof(struct rts51x_status); + chip->status = kzalloc(size, GFP_KERNEL); + if (!chip->status) + goto INIT_FAIL; + + for (i = 0; i <= (int)(chip->max_lun); i++) { + retval = rts51x_check_status(us, (u8)i); + if (retval < 0) + goto INIT_FAIL; + } + + if (CHECK_FW_VER(chip, 0x5888) || CHECK_FW_VER(chip, 0x5889) || + CHECK_FW_VER(chip, 0x5901)) + SET_AUTO_DELINK(chip); + if (STATUS_LEN(chip) == 16) { + if (SUPPORT_AUTO_DELINK(chip)) + SET_AUTO_DELINK(chip); + } + + US_DEBUGP("chip->flag = 0x%x\n", chip->flag); + + (void)config_autodelink_after_power_on(us); + + return 0; + +INIT_FAIL: + if (us->extra) { + kfree(chip->status); + kfree(us->extra); + us->extra = NULL; + } + + return -EIO; +} + +static int realtek_cr_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct us_data *us; + int result; + + US_DEBUGP("Probe Realtek Card Reader!\n"); + + result = usb_stor_probe1(&us, intf, id, + (id - realtek_cr_ids) + realtek_cr_unusual_dev_list); + if (result) + return result; + + result = usb_stor_probe2(us); + return result; +} + +static struct usb_driver realtek_cr_driver = { + .name = "ums-realtek", + .probe = realtek_cr_probe, + .disconnect = usb_stor_disconnect, + .suspend = usb_stor_suspend, + .resume = usb_stor_resume, + .reset_resume = usb_stor_reset_resume, + .pre_reset = usb_stor_pre_reset, + .post_reset = usb_stor_post_reset, + .id_table = realtek_cr_ids, + .soft_unbind = 1, +}; + +static int __init realtek_cr_init(void) +{ + return usb_register(&realtek_cr_driver); +} + +static void __exit realtek_cr_exit(void) +{ + usb_deregister(&realtek_cr_driver); +} + +module_init(realtek_cr_init); +module_exit(realtek_cr_exit); diff --git a/drivers/usb/storage/unusual_realtek.h b/drivers/usb/storage/unusual_realtek.h new file mode 100644 index 000000000000..3236e0328516 --- /dev/null +++ b/drivers/usb/storage/unusual_realtek.h @@ -0,0 +1,41 @@ +/* Driver for Realtek RTS51xx USB card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#if defined(CONFIG_USB_STORAGE_REALTEK) || \ + defined(CONFIG_USB_STORAGE_REALTEK_MODULE) + +UNUSUAL_DEV(0x0bda, 0x0159, 0x0000, 0x9999, + "Realtek", + "USB Card Reader", + USB_SC_SCSI, USB_PR_BULK, init_realtek_cr, 0), + +UNUSUAL_DEV(0x0bda, 0x0158, 0x0000, 0x9999, + "Realtek", + "USB Card Reader", + USB_SC_SCSI, USB_PR_BULK, init_realtek_cr, 0), + +UNUSUAL_DEV(0x0bda, 0x0138, 0x0000, 0x9999, + "Realtek", + "USB Card Reader", + USB_SC_SCSI, USB_PR_BULK, init_realtek_cr, 0), + +#endif /* defined(CONFIG_USB_STORAGE_REALTEK) || ... */ diff --git a/drivers/usb/storage/usual-tables.c b/drivers/usb/storage/usual-tables.c index 468bde7d1971..4293077c01aa 100644 --- a/drivers/usb/storage/usual-tables.c +++ b/drivers/usb/storage/usual-tables.c @@ -85,6 +85,7 @@ static struct ignore_entry ignore_ids[] = { # include "unusual_jumpshot.h" # include "unusual_karma.h" # include "unusual_onetouch.h" +# include "unusual_realtek.h" # include "unusual_sddr09.h" # include "unusual_sddr55.h" # include "unusual_usbat.h" -- cgit v1.2.3 From 084fb206a91f72b22c4e2f41709730a81e3e0de6 Mon Sep 17 00:00:00 2001 From: Martin Fuzzey Date: Sun, 16 Jan 2011 19:17:11 +0100 Subject: USB: usbtest - Add tests to ensure HCDs can accept byte aligned buffers. Add a set of new tests similar to the existing ones but using transfer buffers at an "odd" address [ie offset of +1 from the buffer obtained by kmalloc() or usb_alloc_coherent()] The new tests are: #17 : bulk out (like #1) using kmalloc and DMA mapping by USB core. #18 : bulk in (like #2) using kmalloc and DMA mapping by USB core. #19 : bulk out (like #1) using usb_alloc_coherent() #20 : bulk in (like #2) using usb_alloc_coherent() #21 : control write (like #14) #22 : isochonous out (like #15) #23 : isochonous in (like #16) Signed-off-by: Martin Fuzzey Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usbtest.c | 236 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 212 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index a35b427c0bac..388cc128072a 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -83,6 +83,8 @@ static struct usb_device *testdev_to_usbdev(struct usbtest_dev *test) #define WARNING(tdev, fmt, args...) \ dev_warn(&(tdev)->intf->dev , fmt , ## args) +#define GUARD_BYTE 0xA5 + /*-------------------------------------------------------------------------*/ static int @@ -186,11 +188,12 @@ static void simple_callback(struct urb *urb) complete(urb->context); } -static struct urb *simple_alloc_urb( +static struct urb *usbtest_alloc_urb( struct usb_device *udev, int pipe, - unsigned long bytes -) + unsigned long bytes, + unsigned transfer_flags, + unsigned offset) { struct urb *urb; @@ -201,19 +204,46 @@ static struct urb *simple_alloc_urb( urb->interval = (udev->speed == USB_SPEED_HIGH) ? (INTERRUPT_RATE << 3) : INTERRUPT_RATE; - urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; + urb->transfer_flags = transfer_flags; if (usb_pipein(pipe)) urb->transfer_flags |= URB_SHORT_NOT_OK; - urb->transfer_buffer = usb_alloc_coherent(udev, bytes, GFP_KERNEL, - &urb->transfer_dma); + + if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) + urb->transfer_buffer = usb_alloc_coherent(udev, bytes + offset, + GFP_KERNEL, &urb->transfer_dma); + else + urb->transfer_buffer = kmalloc(bytes + offset, GFP_KERNEL); + if (!urb->transfer_buffer) { usb_free_urb(urb); - urb = NULL; - } else - memset(urb->transfer_buffer, 0, bytes); + return NULL; + } + + /* To test unaligned transfers add an offset and fill the + unused memory with a guard value */ + if (offset) { + memset(urb->transfer_buffer, GUARD_BYTE, offset); + urb->transfer_buffer += offset; + if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) + urb->transfer_dma += offset; + } + + /* For inbound transfers use guard byte so that test fails if + data not correctly copied */ + memset(urb->transfer_buffer, + usb_pipein(urb->pipe) ? GUARD_BYTE : 0, + bytes); return urb; } +static struct urb *simple_alloc_urb( + struct usb_device *udev, + int pipe, + unsigned long bytes) +{ + return usbtest_alloc_urb(udev, pipe, bytes, URB_NO_TRANSFER_DMA_MAP, 0); +} + static unsigned pattern; static unsigned mod_pattern; module_param_named(pattern, mod_pattern, uint, S_IRUGO | S_IWUSR); @@ -238,13 +268,38 @@ static inline void simple_fill_buf(struct urb *urb) } } -static inline int simple_check_buf(struct usbtest_dev *tdev, struct urb *urb) +static inline unsigned buffer_offset(void *buf) +{ + return (unsigned)buf & (ARCH_KMALLOC_MINALIGN - 1); +} + +static int check_guard_bytes(struct usbtest_dev *tdev, struct urb *urb) +{ + u8 *buf = urb->transfer_buffer; + u8 *guard = buf - buffer_offset(buf); + unsigned i; + + for (i = 0; guard < buf; i++, guard++) { + if (*guard != GUARD_BYTE) { + ERROR(tdev, "guard byte[%d] %d (not %d)\n", + i, *guard, GUARD_BYTE); + return -EINVAL; + } + } + return 0; +} + +static int simple_check_buf(struct usbtest_dev *tdev, struct urb *urb) { unsigned i; u8 expected; u8 *buf = urb->transfer_buffer; unsigned len = urb->actual_length; + int ret = check_guard_bytes(tdev, urb); + if (ret) + return ret; + for (i = 0; i < len; i++, buf++) { switch (pattern) { /* all-zeroes has no synchronization issues */ @@ -274,8 +329,16 @@ static inline int simple_check_buf(struct usbtest_dev *tdev, struct urb *urb) static void simple_free_urb(struct urb *urb) { - usb_free_coherent(urb->dev, urb->transfer_buffer_length, - urb->transfer_buffer, urb->transfer_dma); + unsigned offset = buffer_offset(urb->transfer_buffer); + + if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) + usb_free_coherent( + urb->dev, + urb->transfer_buffer_length + offset, + urb->transfer_buffer - offset, + urb->transfer_dma - offset); + else + kfree(urb->transfer_buffer - offset); usb_free_urb(urb); } @@ -1256,7 +1319,7 @@ done: * try whatever we're told to try. */ static int ctrl_out(struct usbtest_dev *dev, - unsigned count, unsigned length, unsigned vary) + unsigned count, unsigned length, unsigned vary, unsigned offset) { unsigned i, j, len; int retval; @@ -1267,10 +1330,11 @@ static int ctrl_out(struct usbtest_dev *dev, if (length < 1 || length > 0xffff || vary >= length) return -EINVAL; - buf = kmalloc(length, GFP_KERNEL); + buf = kmalloc(length + offset, GFP_KERNEL); if (!buf) return -ENOMEM; + buf += offset; udev = testdev_to_usbdev(dev); len = length; retval = 0; @@ -1337,7 +1401,7 @@ static int ctrl_out(struct usbtest_dev *dev, ERROR(dev, "ctrl_out %s failed, code %d, count %d\n", what, retval, i); - kfree(buf); + kfree(buf - offset); return retval; } @@ -1373,6 +1437,8 @@ static void iso_callback(struct urb *urb) ctx->errors += urb->number_of_packets; else if (urb->actual_length != urb->transfer_buffer_length) ctx->errors++; + else if (check_guard_bytes(ctx->dev, urb) != 0) + ctx->errors++; if (urb->status == 0 && ctx->count > (ctx->pending - 1) && !ctx->submit_error) { @@ -1408,7 +1474,8 @@ static struct urb *iso_alloc_urb( struct usb_device *udev, int pipe, struct usb_endpoint_descriptor *desc, - long bytes + long bytes, + unsigned offset ) { struct urb *urb; @@ -1428,13 +1495,24 @@ static struct urb *iso_alloc_urb( urb->number_of_packets = packets; urb->transfer_buffer_length = bytes; - urb->transfer_buffer = usb_alloc_coherent(udev, bytes, GFP_KERNEL, - &urb->transfer_dma); + urb->transfer_buffer = usb_alloc_coherent(udev, bytes + offset, + GFP_KERNEL, + &urb->transfer_dma); if (!urb->transfer_buffer) { usb_free_urb(urb); return NULL; } - memset(urb->transfer_buffer, 0, bytes); + if (offset) { + memset(urb->transfer_buffer, GUARD_BYTE, offset); + urb->transfer_buffer += offset; + urb->transfer_dma += offset; + } + /* For inbound transfers use guard byte so that test fails if + data not correctly copied */ + memset(urb->transfer_buffer, + usb_pipein(urb->pipe) ? GUARD_BYTE : 0, + bytes); + for (i = 0; i < packets; i++) { /* here, only the last packet will be short */ urb->iso_frame_desc[i].length = min((unsigned) bytes, maxp); @@ -1452,7 +1530,7 @@ static struct urb *iso_alloc_urb( static int test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param, - int pipe, struct usb_endpoint_descriptor *desc) + int pipe, struct usb_endpoint_descriptor *desc, unsigned offset) { struct iso_context context; struct usb_device *udev; @@ -1480,7 +1558,7 @@ test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param, for (i = 0; i < param->sglen; i++) { urbs[i] = iso_alloc_urb(udev, pipe, desc, - param->length); + param->length, offset); if (!urbs[i]) { status = -ENOMEM; goto fail; @@ -1542,6 +1620,26 @@ fail: return status; } +static int test_unaligned_bulk( + struct usbtest_dev *tdev, + int pipe, + unsigned length, + int iterations, + unsigned transfer_flags, + const char *label) +{ + int retval; + struct urb *urb = usbtest_alloc_urb( + testdev_to_usbdev(tdev), pipe, length, transfer_flags, 1); + + if (!urb) + return -ENOMEM; + + retval = simple_io(tdev, urb, iterations, 0, 0, label); + simple_free_urb(urb); + return retval; +} + /*-------------------------------------------------------------------------*/ /* We only have this one interface to user space, through usbfs. @@ -1843,7 +1941,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) realworld ? 1 : 0, param->length, param->vary); retval = ctrl_out(dev, param->iterations, - param->length, param->vary); + param->length, param->vary, 0); break; /* iso write tests */ @@ -1856,7 +1954,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) param->sglen, param->length); /* FIRMWARE: iso sink */ retval = test_iso_queue(dev, param, - dev->out_iso_pipe, dev->iso_out); + dev->out_iso_pipe, dev->iso_out, 0); break; /* iso read tests */ @@ -1869,13 +1967,103 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) param->sglen, param->length); /* FIRMWARE: iso source */ retval = test_iso_queue(dev, param, - dev->in_iso_pipe, dev->iso_in); + dev->in_iso_pipe, dev->iso_in, 0); break; /* FIXME unlink from queue (ring with N urbs) */ /* FIXME scatterlist cancel (needs helper thread) */ + /* Tests for bulk I/O using DMA mapping by core and odd address */ + case 17: + if (dev->out_pipe == 0) + break; + dev_info(&intf->dev, + "TEST 17: write odd addr %d bytes %u times core map\n", + param->length, param->iterations); + + retval = test_unaligned_bulk( + dev, dev->out_pipe, + param->length, param->iterations, + 0, "test17"); + break; + + case 18: + if (dev->in_pipe == 0) + break; + dev_info(&intf->dev, + "TEST 18: read odd addr %d bytes %u times core map\n", + param->length, param->iterations); + + retval = test_unaligned_bulk( + dev, dev->in_pipe, + param->length, param->iterations, + 0, "test18"); + break; + + /* Tests for bulk I/O using premapped coherent buffer and odd address */ + case 19: + if (dev->out_pipe == 0) + break; + dev_info(&intf->dev, + "TEST 19: write odd addr %d bytes %u times premapped\n", + param->length, param->iterations); + + retval = test_unaligned_bulk( + dev, dev->out_pipe, + param->length, param->iterations, + URB_NO_TRANSFER_DMA_MAP, "test19"); + break; + + case 20: + if (dev->in_pipe == 0) + break; + dev_info(&intf->dev, + "TEST 20: read odd addr %d bytes %u times premapped\n", + param->length, param->iterations); + + retval = test_unaligned_bulk( + dev, dev->in_pipe, + param->length, param->iterations, + URB_NO_TRANSFER_DMA_MAP, "test20"); + break; + + /* control write tests with unaligned buffer */ + case 21: + if (!dev->info->ctrl_out) + break; + dev_info(&intf->dev, + "TEST 21: %d ep0out odd addr, %d..%d vary %d\n", + param->iterations, + realworld ? 1 : 0, param->length, + param->vary); + retval = ctrl_out(dev, param->iterations, + param->length, param->vary, 1); + break; + + /* unaligned iso tests */ + case 22: + if (dev->out_iso_pipe == 0 || param->sglen == 0) + break; + dev_info(&intf->dev, + "TEST 22: write %d iso odd, %d entries of %d bytes\n", + param->iterations, + param->sglen, param->length); + retval = test_iso_queue(dev, param, + dev->out_iso_pipe, dev->iso_out, 1); + break; + + case 23: + if (dev->in_iso_pipe == 0 || param->sglen == 0) + break; + dev_info(&intf->dev, + "TEST 23: read %d iso odd, %d entries of %d bytes\n", + param->iterations, + param->sglen, param->length); + retval = test_iso_queue(dev, param, + dev->in_iso_pipe, dev->iso_in, 1); + break; + } do_gettimeofday(¶m->duration); param->duration.tv_sec -= start.tv_sec; -- cgit v1.2.3 From 0fe6f1d1f612035d78d8d195bbc3485a341386d5 Mon Sep 17 00:00:00 2001 From: Yuan-Hsin Chen Date: Tue, 18 Jan 2011 14:49:28 +0800 Subject: usb: udc: add Faraday fusb300 driver USB2.0 device controller driver for Faraday fubs300 Signed-off-by: Yuan-Hsin Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/Kconfig | 12 + drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/fusb300_udc.c | 1743 ++++++++++++++++++++++++++++++++++++++ drivers/usb/gadget/fusb300_udc.h | 687 +++++++++++++++ 4 files changed, 2443 insertions(+) create mode 100644 drivers/usb/gadget/fusb300_udc.c create mode 100644 drivers/usb/gadget/fusb300_udc.h (limited to 'drivers') diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 1dc9739277b4..48455397ef61 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -176,6 +176,18 @@ config USB_FSL_USB2 default USB_GADGET select USB_GADGET_SELECTED +config USB_GADGET_FUSB300 + boolean "Faraday FUSB300 USB Peripheral Controller" + select USB_GADGET_DUALSPEED + help + Faraday usb device controller FUSB300 driver + +config USB_FUSB300 + tristate + depends on USB_GADGET_FUSB300 + default USB_GADGET + select USB_GADGET_SELECTED + config USB_GADGET_LH7A40X boolean "LH7A40X" depends on ARCH_LH7A40X diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 55f5e8ae5924..305286e181d5 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_USB_EG20T) += pch_udc.o obj-$(CONFIG_USB_PXA_U2O) += mv_udc.o mv_udc-y := mv_udc_core.o mv_udc_phy.o obj-$(CONFIG_USB_CI13XXX_MSM) += ci13xxx_msm.o +obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o # # USB gadget drivers diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c new file mode 100644 index 000000000000..fd4fd69f5ad6 --- /dev/null +++ b/drivers/usb/gadget/fusb300_udc.c @@ -0,0 +1,1743 @@ +/* + * Fusb300 UDC (USB gadget) + * + * Copyright (C) 2010 Faraday Technology Corp. + * + * Author : Yuan-hsin Chen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include "fusb300_udc.h" + +MODULE_DESCRIPTION("FUSB300 USB gadget driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Yuan Hsin Chen "); +MODULE_ALIAS("platform:fusb300_udc"); + +#define DRIVER_VERSION "20 October 2010" + +static const char udc_name[] = "fusb300_udc"; +static const char * const fusb300_ep_name[] = { + "ep0", "ep1", "ep2", "ep3", "ep4", "ep5", "ep6", "ep7" +}; + +static void done(struct fusb300_ep *ep, struct fusb300_request *req, + int status); + +static void fusb300_enable_bit(struct fusb300 *fusb300, u32 offset, + u32 value) +{ + u32 reg = ioread32(fusb300->reg + offset); + + reg |= value; + iowrite32(reg, fusb300->reg + offset); +} + +static void fusb300_disable_bit(struct fusb300 *fusb300, u32 offset, + u32 value) +{ + u32 reg = ioread32(fusb300->reg + offset); + + reg &= ~value; + iowrite32(reg, fusb300->reg + offset); +} + + +static void fusb300_ep_setting(struct fusb300_ep *ep, + struct fusb300_ep_info info) +{ + ep->epnum = info.epnum; + ep->type = info.type; +} + +static int fusb300_ep_release(struct fusb300_ep *ep) +{ + if (!ep->epnum) + return 0; + ep->epnum = 0; + ep->stall = 0; + ep->wedged = 0; + return 0; +} + +static void fusb300_set_fifo_entry(struct fusb300 *fusb300, + u32 ep) +{ + u32 val = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET1(ep)); + + val &= ~FUSB300_EPSET1_FIFOENTRY_MSK; + val |= FUSB300_EPSET1_FIFOENTRY(FUSB300_FIFO_ENTRY_NUM); + iowrite32(val, fusb300->reg + FUSB300_OFFSET_EPSET1(ep)); +} + +static void fusb300_set_start_entry(struct fusb300 *fusb300, + u8 ep) +{ + u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET1(ep)); + u32 start_entry = fusb300->fifo_entry_num * FUSB300_FIFO_ENTRY_NUM; + + reg &= ~FUSB300_EPSET1_START_ENTRY_MSK ; + reg |= FUSB300_EPSET1_START_ENTRY(start_entry); + iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPSET1(ep)); + if (fusb300->fifo_entry_num == FUSB300_MAX_FIFO_ENTRY) { + fusb300->fifo_entry_num = 0; + fusb300->addrofs = 0; + pr_err("fifo entry is over the maximum number!\n"); + } else + fusb300->fifo_entry_num++; +} + +/* set fusb300_set_start_entry first before fusb300_set_epaddrofs */ +static void fusb300_set_epaddrofs(struct fusb300 *fusb300, + struct fusb300_ep_info info) +{ + u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET2(info.epnum)); + + reg &= ~FUSB300_EPSET2_ADDROFS_MSK; + reg |= FUSB300_EPSET2_ADDROFS(fusb300->addrofs); + iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPSET2(info.epnum)); + fusb300->addrofs += (info.maxpacket + 7) / 8 * FUSB300_FIFO_ENTRY_NUM; +} + +static void ep_fifo_setting(struct fusb300 *fusb300, + struct fusb300_ep_info info) +{ + fusb300_set_fifo_entry(fusb300, info.epnum); + fusb300_set_start_entry(fusb300, info.epnum); + fusb300_set_epaddrofs(fusb300, info); +} + +static void fusb300_set_eptype(struct fusb300 *fusb300, + struct fusb300_ep_info info) +{ + u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET1(info.epnum)); + + reg &= ~FUSB300_EPSET1_TYPE_MSK; + reg |= FUSB300_EPSET1_TYPE(info.type); + iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPSET1(info.epnum)); +} + +static void fusb300_set_epdir(struct fusb300 *fusb300, + struct fusb300_ep_info info) +{ + u32 reg; + + if (!info.dir_in) + return; + reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET1(info.epnum)); + reg &= ~FUSB300_EPSET1_DIR_MSK; + reg |= FUSB300_EPSET1_DIRIN; + iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPSET1(info.epnum)); +} + +static void fusb300_set_ep_active(struct fusb300 *fusb300, + u8 ep) +{ + u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET1(ep)); + + reg |= FUSB300_EPSET1_ACTEN; + iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPSET1(ep)); +} + +static void fusb300_set_epmps(struct fusb300 *fusb300, + struct fusb300_ep_info info) +{ + u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET2(info.epnum)); + + reg &= ~FUSB300_EPSET2_MPS_MSK; + reg |= FUSB300_EPSET2_MPS(info.maxpacket); + iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPSET2(info.epnum)); +} + +static void fusb300_set_interval(struct fusb300 *fusb300, + struct fusb300_ep_info info) +{ + u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET1(info.epnum)); + + reg &= ~FUSB300_EPSET1_INTERVAL(0x7); + reg |= FUSB300_EPSET1_INTERVAL(info.interval); + iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPSET1(info.epnum)); +} + +static void fusb300_set_bwnum(struct fusb300 *fusb300, + struct fusb300_ep_info info) +{ + u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET1(info.epnum)); + + reg &= ~FUSB300_EPSET1_BWNUM(0x3); + reg |= FUSB300_EPSET1_BWNUM(info.bw_num); + iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPSET1(info.epnum)); +} + +static void set_ep_reg(struct fusb300 *fusb300, + struct fusb300_ep_info info) +{ + fusb300_set_eptype(fusb300, info); + fusb300_set_epdir(fusb300, info); + fusb300_set_epmps(fusb300, info); + + if (info.interval) + fusb300_set_interval(fusb300, info); + + if (info.bw_num) + fusb300_set_bwnum(fusb300, info); + + fusb300_set_ep_active(fusb300, info.epnum); +} + +static int config_ep(struct fusb300_ep *ep, + const struct usb_endpoint_descriptor *desc) +{ + struct fusb300 *fusb300 = ep->fusb300; + struct fusb300_ep_info info; + + ep->desc = desc; + + info.interval = 0; + info.addrofs = 0; + info.bw_num = 0; + + info.type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; + info.dir_in = (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ? 1 : 0; + info.maxpacket = le16_to_cpu(desc->wMaxPacketSize); + info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + + if ((info.type == USB_ENDPOINT_XFER_INT) || + (info.type == USB_ENDPOINT_XFER_ISOC)) { + info.interval = desc->bInterval; + if (info.type == USB_ENDPOINT_XFER_ISOC) + info.bw_num = ((desc->wMaxPacketSize & 0x1800) >> 11); + } + + ep_fifo_setting(fusb300, info); + + set_ep_reg(fusb300, info); + + fusb300_ep_setting(ep, info); + + fusb300->ep[info.epnum] = ep; + + return 0; +} + +static int fusb300_enable(struct usb_ep *_ep, + const struct usb_endpoint_descriptor *desc) +{ + struct fusb300_ep *ep; + + ep = container_of(_ep, struct fusb300_ep, ep); + + if (ep->fusb300->reenum) { + ep->fusb300->fifo_entry_num = 0; + ep->fusb300->addrofs = 0; + ep->fusb300->reenum = 0; + } + + return config_ep(ep, desc); +} + +static int fusb300_disable(struct usb_ep *_ep) +{ + struct fusb300_ep *ep; + struct fusb300_request *req; + unsigned long flags; + + ep = container_of(_ep, struct fusb300_ep, ep); + + BUG_ON(!ep); + + while (!list_empty(&ep->queue)) { + req = list_entry(ep->queue.next, struct fusb300_request, queue); + spin_lock_irqsave(&ep->fusb300->lock, flags); + done(ep, req, -ECONNRESET); + spin_unlock_irqrestore(&ep->fusb300->lock, flags); + } + + return fusb300_ep_release(ep); +} + +static struct usb_request *fusb300_alloc_request(struct usb_ep *_ep, + gfp_t gfp_flags) +{ + struct fusb300_request *req; + + req = kzalloc(sizeof(struct fusb300_request), gfp_flags); + if (!req) + return NULL; + INIT_LIST_HEAD(&req->queue); + + return &req->req; +} + +static void fusb300_free_request(struct usb_ep *_ep, struct usb_request *_req) +{ + struct fusb300_request *req; + + req = container_of(_req, struct fusb300_request, req); + kfree(req); +} + +static int enable_fifo_int(struct fusb300_ep *ep) +{ + struct fusb300 *fusb300 = ep->fusb300; + + if (ep->epnum) { + fusb300_enable_bit(fusb300, FUSB300_OFFSET_IGER0, + FUSB300_IGER0_EEPn_FIFO_INT(ep->epnum)); + } else { + pr_err("can't enable_fifo_int ep0\n"); + return -EINVAL; + } + + return 0; +} + +static int disable_fifo_int(struct fusb300_ep *ep) +{ + struct fusb300 *fusb300 = ep->fusb300; + + if (ep->epnum) { + fusb300_disable_bit(fusb300, FUSB300_OFFSET_IGER0, + FUSB300_IGER0_EEPn_FIFO_INT(ep->epnum)); + } else { + pr_err("can't disable_fifo_int ep0\n"); + return -EINVAL; + } + + return 0; +} + +static void fusb300_set_cxlen(struct fusb300 *fusb300, u32 length) +{ + u32 reg; + + reg = ioread32(fusb300->reg + FUSB300_OFFSET_CSR); + reg &= ~FUSB300_CSR_LEN_MSK; + reg |= FUSB300_CSR_LEN(length); + iowrite32(reg, fusb300->reg + FUSB300_OFFSET_CSR); +} + +/* write data to cx fifo */ +static void fusb300_wrcxf(struct fusb300_ep *ep, + struct fusb300_request *req) +{ + int i = 0; + u8 *tmp; + u32 data; + struct fusb300 *fusb300 = ep->fusb300; + u32 length = req->req.length - req->req.actual; + + tmp = req->req.buf + req->req.actual; + + if (length > SS_CTL_MAX_PACKET_SIZE) { + fusb300_set_cxlen(fusb300, SS_CTL_MAX_PACKET_SIZE); + for (i = (SS_CTL_MAX_PACKET_SIZE >> 2); i > 0; i--) { + data = *tmp | *(tmp + 1) << 8 | *(tmp + 2) << 16 | + *(tmp + 3) << 24; + iowrite32(data, fusb300->reg + FUSB300_OFFSET_CXPORT); + tmp += 4; + } + req->req.actual += SS_CTL_MAX_PACKET_SIZE; + } else { /* length is less than max packet size */ + fusb300_set_cxlen(fusb300, length); + for (i = length >> 2; i > 0; i--) { + data = *tmp | *(tmp + 1) << 8 | *(tmp + 2) << 16 | + *(tmp + 3) << 24; + printk(KERN_DEBUG " 0x%x\n", data); + iowrite32(data, fusb300->reg + FUSB300_OFFSET_CXPORT); + tmp = tmp + 4; + } + switch (length % 4) { + case 1: + data = *tmp; + printk(KERN_DEBUG " 0x%x\n", data); + iowrite32(data, fusb300->reg + FUSB300_OFFSET_CXPORT); + break; + case 2: + data = *tmp | *(tmp + 1) << 8; + printk(KERN_DEBUG " 0x%x\n", data); + iowrite32(data, fusb300->reg + FUSB300_OFFSET_CXPORT); + break; + case 3: + data = *tmp | *(tmp + 1) << 8 | *(tmp + 2) << 16; + printk(KERN_DEBUG " 0x%x\n", data); + iowrite32(data, fusb300->reg + FUSB300_OFFSET_CXPORT); + break; + default: + break; + } + req->req.actual += length; + } +} + +static void fusb300_set_epnstall(struct fusb300 *fusb300, u8 ep) +{ + fusb300_enable_bit(fusb300, FUSB300_OFFSET_EPSET0(ep), + FUSB300_EPSET0_STL); +} + +static void fusb300_clear_epnstall(struct fusb300 *fusb300, u8 ep) +{ + u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET0(ep)); + + if (reg & FUSB300_EPSET0_STL) { + printk(KERN_DEBUG "EP%d stall... Clear!!\n", ep); + reg &= ~FUSB300_EPSET0_STL; + iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPSET0(ep)); + } +} + +static void ep0_queue(struct fusb300_ep *ep, struct fusb300_request *req) +{ + if (ep->fusb300->ep0_dir) { /* if IN */ + if (req->req.length) { + fusb300_wrcxf(ep, req); + } else + printk(KERN_DEBUG "%s : req->req.length = 0x%x\n", + __func__, req->req.length); + if ((req->req.length == req->req.actual) || + (req->req.actual < ep->ep.maxpacket)) + done(ep, req, 0); + } else { /* OUT */ + if (!req->req.length) + done(ep, req, 0); + else + fusb300_enable_bit(ep->fusb300, FUSB300_OFFSET_IGER1, + FUSB300_IGER1_CX_OUT_INT); + } +} + +static int fusb300_queue(struct usb_ep *_ep, struct usb_request *_req, + gfp_t gfp_flags) +{ + struct fusb300_ep *ep; + struct fusb300_request *req; + unsigned long flags; + int request = 0; + + ep = container_of(_ep, struct fusb300_ep, ep); + req = container_of(_req, struct fusb300_request, req); + + if (ep->fusb300->gadget.speed == USB_SPEED_UNKNOWN) + return -ESHUTDOWN; + + spin_lock_irqsave(&ep->fusb300->lock, flags); + + if (list_empty(&ep->queue)) + request = 1; + + list_add_tail(&req->queue, &ep->queue); + + req->req.actual = 0; + req->req.status = -EINPROGRESS; + + if (ep->desc == NULL) /* ep0 */ + ep0_queue(ep, req); + else if (request && !ep->stall) + enable_fifo_int(ep); + + spin_unlock_irqrestore(&ep->fusb300->lock, flags); + + return 0; +} + +static int fusb300_dequeue(struct usb_ep *_ep, struct usb_request *_req) +{ + struct fusb300_ep *ep; + struct fusb300_request *req; + unsigned long flags; + + ep = container_of(_ep, struct fusb300_ep, ep); + req = container_of(_req, struct fusb300_request, req); + + spin_lock_irqsave(&ep->fusb300->lock, flags); + if (!list_empty(&ep->queue)) + done(ep, req, -ECONNRESET); + spin_unlock_irqrestore(&ep->fusb300->lock, flags); + + return 0; +} + +static int fusb300_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedge) +{ + struct fusb300_ep *ep; + struct fusb300 *fusb300; + unsigned long flags; + int ret = 0; + + ep = container_of(_ep, struct fusb300_ep, ep); + + fusb300 = ep->fusb300; + + spin_lock_irqsave(&ep->fusb300->lock, flags); + + if (!list_empty(&ep->queue)) { + ret = -EAGAIN; + goto out; + } + + if (value) { + fusb300_set_epnstall(fusb300, ep->epnum); + ep->stall = 1; + if (wedge) + ep->wedged = 1; + } else { + fusb300_clear_epnstall(fusb300, ep->epnum); + ep->stall = 0; + ep->wedged = 0; + } + +out: + spin_unlock_irqrestore(&ep->fusb300->lock, flags); + return ret; +} + +static int fusb300_set_halt(struct usb_ep *_ep, int value) +{ + return fusb300_set_halt_and_wedge(_ep, value, 0); +} + +static int fusb300_set_wedge(struct usb_ep *_ep) +{ + return fusb300_set_halt_and_wedge(_ep, 1, 1); +} + +static void fusb300_fifo_flush(struct usb_ep *_ep) +{ +} + +static struct usb_ep_ops fusb300_ep_ops = { + .enable = fusb300_enable, + .disable = fusb300_disable, + + .alloc_request = fusb300_alloc_request, + .free_request = fusb300_free_request, + + .queue = fusb300_queue, + .dequeue = fusb300_dequeue, + + .set_halt = fusb300_set_halt, + .fifo_flush = fusb300_fifo_flush, + .set_wedge = fusb300_set_wedge, +}; + +/*****************************************************************************/ +static void fusb300_clear_int(struct fusb300 *fusb300, u32 offset, + u32 value) +{ + iowrite32(value, fusb300->reg + offset); +} + +static void fusb300_reset(void) +{ +} + +static void fusb300_set_cxstall(struct fusb300 *fusb300) +{ + fusb300_enable_bit(fusb300, FUSB300_OFFSET_CSR, + FUSB300_CSR_STL); +} + +static void fusb300_set_cxdone(struct fusb300 *fusb300) +{ + fusb300_enable_bit(fusb300, FUSB300_OFFSET_CSR, + FUSB300_CSR_DONE); +} + +/* read data from cx fifo */ +void fusb300_rdcxf(struct fusb300 *fusb300, + u8 *buffer, u32 length) +{ + int i = 0; + u8 *tmp; + u32 data; + + tmp = buffer; + + for (i = (length >> 2); i > 0; i--) { + data = ioread32(fusb300->reg + FUSB300_OFFSET_CXPORT); + printk(KERN_DEBUG " 0x%x\n", data); + *tmp = data & 0xFF; + *(tmp + 1) = (data >> 8) & 0xFF; + *(tmp + 2) = (data >> 16) & 0xFF; + *(tmp + 3) = (data >> 24) & 0xFF; + tmp = tmp + 4; + } + + switch (length % 4) { + case 1: + data = ioread32(fusb300->reg + FUSB300_OFFSET_CXPORT); + printk(KERN_DEBUG " 0x%x\n", data); + *tmp = data & 0xFF; + break; + case 2: + data = ioread32(fusb300->reg + FUSB300_OFFSET_CXPORT); + printk(KERN_DEBUG " 0x%x\n", data); + *tmp = data & 0xFF; + *(tmp + 1) = (data >> 8) & 0xFF; + break; + case 3: + data = ioread32(fusb300->reg + FUSB300_OFFSET_CXPORT); + printk(KERN_DEBUG " 0x%x\n", data); + *tmp = data & 0xFF; + *(tmp + 1) = (data >> 8) & 0xFF; + *(tmp + 2) = (data >> 16) & 0xFF; + break; + default: + break; + } +} + +#if 0 +static void fusb300_dbg_fifo(struct fusb300_ep *ep, + u8 entry, u16 length) +{ + u32 reg; + u32 i = 0; + u32 j = 0; + + reg = ioread32(ep->fusb300->reg + FUSB300_OFFSET_GTM); + reg &= ~(FUSB300_GTM_TST_EP_ENTRY(0xF) | + FUSB300_GTM_TST_EP_NUM(0xF) | FUSB300_GTM_TST_FIFO_DEG); + reg |= (FUSB300_GTM_TST_EP_ENTRY(entry) | + FUSB300_GTM_TST_EP_NUM(ep->epnum) | FUSB300_GTM_TST_FIFO_DEG); + iowrite32(reg, ep->fusb300->reg + FUSB300_OFFSET_GTM); + + for (i = 0; i < (length >> 2); i++) { + if (i * 4 == 1024) + break; + reg = ioread32(ep->fusb300->reg + + FUSB300_OFFSET_BUFDBG_START + i * 4); + printk(KERN_DEBUG" 0x%-8x", reg); + j++; + if ((j % 4) == 0) + printk(KERN_DEBUG "\n"); + } + + if (length % 4) { + reg = ioread32(ep->fusb300->reg + + FUSB300_OFFSET_BUFDBG_START + i * 4); + printk(KERN_DEBUG " 0x%x\n", reg); + } + + if ((j % 4) != 0) + printk(KERN_DEBUG "\n"); + + fusb300_disable_bit(ep->fusb300, FUSB300_OFFSET_GTM, + FUSB300_GTM_TST_FIFO_DEG); +} + +static void fusb300_cmp_dbg_fifo(struct fusb300_ep *ep, + u8 entry, u16 length, u8 *golden) +{ + u32 reg; + u32 i = 0; + u32 golden_value; + u8 *tmp; + + tmp = golden; + + printk(KERN_DEBUG "fusb300_cmp_dbg_fifo (entry %d) : start\n", entry); + + reg = ioread32(ep->fusb300->reg + FUSB300_OFFSET_GTM); + reg &= ~(FUSB300_GTM_TST_EP_ENTRY(0xF) | + FUSB300_GTM_TST_EP_NUM(0xF) | FUSB300_GTM_TST_FIFO_DEG); + reg |= (FUSB300_GTM_TST_EP_ENTRY(entry) | + FUSB300_GTM_TST_EP_NUM(ep->epnum) | FUSB300_GTM_TST_FIFO_DEG); + iowrite32(reg, ep->fusb300->reg + FUSB300_OFFSET_GTM); + + for (i = 0; i < (length >> 2); i++) { + if (i * 4 == 1024) + break; + golden_value = *tmp | *(tmp + 1) << 8 | + *(tmp + 2) << 16 | *(tmp + 3) << 24; + + reg = ioread32(ep->fusb300->reg + + FUSB300_OFFSET_BUFDBG_START + i*4); + + if (reg != golden_value) { + printk(KERN_DEBUG "0x%x : ", (u32)(ep->fusb300->reg + + FUSB300_OFFSET_BUFDBG_START + i*4)); + printk(KERN_DEBUG " golden = 0x%x, reg = 0x%x\n", + golden_value, reg); + } + tmp += 4; + } + + switch (length % 4) { + case 1: + golden_value = *tmp; + case 2: + golden_value = *tmp | *(tmp + 1) << 8; + case 3: + golden_value = *tmp | *(tmp + 1) << 8 | *(tmp + 2) << 16; + default: + break; + + reg = ioread32(ep->fusb300->reg + FUSB300_OFFSET_BUFDBG_START + i*4); + if (reg != golden_value) { + printk(KERN_DEBUG "0x%x:", (u32)(ep->fusb300->reg + + FUSB300_OFFSET_BUFDBG_START + i*4)); + printk(KERN_DEBUG " golden = 0x%x, reg = 0x%x\n", + golden_value, reg); + } + } + + printk(KERN_DEBUG "fusb300_cmp_dbg_fifo : end\n"); + fusb300_disable_bit(ep->fusb300, FUSB300_OFFSET_GTM, + FUSB300_GTM_TST_FIFO_DEG); +} +#endif + +static void fusb300_rdfifo(struct fusb300_ep *ep, + struct fusb300_request *req, + u32 length) +{ + int i = 0; + u8 *tmp; + u32 data, reg; + struct fusb300 *fusb300 = ep->fusb300; + + tmp = req->req.buf + req->req.actual; + req->req.actual += length; + + if (req->req.actual > req->req.length) + printk(KERN_DEBUG "req->req.actual > req->req.length\n"); + + for (i = (length >> 2); i > 0; i--) { + data = ioread32(fusb300->reg + + FUSB300_OFFSET_EPPORT(ep->epnum)); + *tmp = data & 0xFF; + *(tmp + 1) = (data >> 8) & 0xFF; + *(tmp + 2) = (data >> 16) & 0xFF; + *(tmp + 3) = (data >> 24) & 0xFF; + tmp = tmp + 4; + } + + switch (length % 4) { + case 1: + data = ioread32(fusb300->reg + + FUSB300_OFFSET_EPPORT(ep->epnum)); + *tmp = data & 0xFF; + break; + case 2: + data = ioread32(fusb300->reg + + FUSB300_OFFSET_EPPORT(ep->epnum)); + *tmp = data & 0xFF; + *(tmp + 1) = (data >> 8) & 0xFF; + break; + case 3: + data = ioread32(fusb300->reg + + FUSB300_OFFSET_EPPORT(ep->epnum)); + *tmp = data & 0xFF; + *(tmp + 1) = (data >> 8) & 0xFF; + *(tmp + 2) = (data >> 16) & 0xFF; + break; + default: + break; + } + + do { + reg = ioread32(fusb300->reg + FUSB300_OFFSET_IGR1); + reg &= FUSB300_IGR1_SYNF0_EMPTY_INT; + if (i) + printk(KERN_INFO "sync fifo is not empty!\n"); + i++; + } while (!reg); +} + +/* write data to fifo */ +static void fusb300_wrfifo(struct fusb300_ep *ep, + struct fusb300_request *req) +{ + int i = 0; + u8 *tmp; + u32 data, reg; + struct fusb300 *fusb300 = ep->fusb300; + + tmp = req->req.buf; + req->req.actual = req->req.length; + + for (i = (req->req.length >> 2); i > 0; i--) { + data = *tmp | *(tmp + 1) << 8 | + *(tmp + 2) << 16 | *(tmp + 3) << 24; + + iowrite32(data, fusb300->reg + + FUSB300_OFFSET_EPPORT(ep->epnum)); + tmp += 4; + } + + switch (req->req.length % 4) { + case 1: + data = *tmp; + iowrite32(data, fusb300->reg + + FUSB300_OFFSET_EPPORT(ep->epnum)); + break; + case 2: + data = *tmp | *(tmp + 1) << 8; + iowrite32(data, fusb300->reg + + FUSB300_OFFSET_EPPORT(ep->epnum)); + break; + case 3: + data = *tmp | *(tmp + 1) << 8 | *(tmp + 2) << 16; + iowrite32(data, fusb300->reg + + FUSB300_OFFSET_EPPORT(ep->epnum)); + break; + default: + break; + } + + do { + reg = ioread32(fusb300->reg + FUSB300_OFFSET_IGR1); + reg &= FUSB300_IGR1_SYNF0_EMPTY_INT; + if (i) + printk(KERN_INFO"sync fifo is not empty!\n"); + i++; + } while (!reg); +} + +static u8 fusb300_get_epnstall(struct fusb300 *fusb300, u8 ep) +{ + u8 value; + u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET0(ep)); + + value = reg & FUSB300_EPSET0_STL; + + return value; +} + +static u8 fusb300_get_cxstall(struct fusb300 *fusb300) +{ + u8 value; + u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_CSR); + + value = (reg & FUSB300_CSR_STL) >> 1; + + return value; +} + +static void request_error(struct fusb300 *fusb300) +{ + fusb300_set_cxstall(fusb300); + printk(KERN_DEBUG "request error!!\n"); +} + +static void get_status(struct fusb300 *fusb300, struct usb_ctrlrequest *ctrl) +__releases(fusb300->lock) +__acquires(fusb300->lock) +{ + u8 ep; + u16 status = 0; + u16 w_index = ctrl->wIndex; + + switch (ctrl->bRequestType & USB_RECIP_MASK) { + case USB_RECIP_DEVICE: + status = 1 << USB_DEVICE_SELF_POWERED; + break; + case USB_RECIP_INTERFACE: + status = 0; + break; + case USB_RECIP_ENDPOINT: + ep = w_index & USB_ENDPOINT_NUMBER_MASK; + if (ep) { + if (fusb300_get_epnstall(fusb300, ep)) + status = 1 << USB_ENDPOINT_HALT; + } else { + if (fusb300_get_cxstall(fusb300)) + status = 0; + } + break; + + default: + request_error(fusb300); + return; /* exit */ + } + + fusb300->ep0_data = cpu_to_le16(status); + fusb300->ep0_req->buf = &fusb300->ep0_data; + fusb300->ep0_req->length = 2; + + spin_unlock(&fusb300->lock); + fusb300_queue(fusb300->gadget.ep0, fusb300->ep0_req, GFP_KERNEL); + spin_lock(&fusb300->lock); +} + +static void set_feature(struct fusb300 *fusb300, struct usb_ctrlrequest *ctrl) +{ + u8 ep; + + switch (ctrl->bRequestType & USB_RECIP_MASK) { + case USB_RECIP_DEVICE: + fusb300_set_cxdone(fusb300); + break; + case USB_RECIP_INTERFACE: + fusb300_set_cxdone(fusb300); + break; + case USB_RECIP_ENDPOINT: { + u16 w_index = le16_to_cpu(ctrl->wIndex); + + ep = w_index & USB_ENDPOINT_NUMBER_MASK; + if (ep) + fusb300_set_epnstall(fusb300, ep); + else + fusb300_set_cxstall(fusb300); + fusb300_set_cxdone(fusb300); + } + break; + default: + request_error(fusb300); + break; + } +} + +static void fusb300_clear_seqnum(struct fusb300 *fusb300, u8 ep) +{ + fusb300_enable_bit(fusb300, FUSB300_OFFSET_EPSET0(ep), + FUSB300_EPSET0_CLRSEQNUM); +} + +static void clear_feature(struct fusb300 *fusb300, struct usb_ctrlrequest *ctrl) +{ + struct fusb300_ep *ep = + fusb300->ep[ctrl->wIndex & USB_ENDPOINT_NUMBER_MASK]; + + switch (ctrl->bRequestType & USB_RECIP_MASK) { + case USB_RECIP_DEVICE: + fusb300_set_cxdone(fusb300); + break; + case USB_RECIP_INTERFACE: + fusb300_set_cxdone(fusb300); + break; + case USB_RECIP_ENDPOINT: + if (ctrl->wIndex & USB_ENDPOINT_NUMBER_MASK) { + if (ep->wedged) { + fusb300_set_cxdone(fusb300); + break; + } + if (ep->stall) { + ep->stall = 0; + fusb300_clear_seqnum(fusb300, ep->epnum); + fusb300_clear_epnstall(fusb300, ep->epnum); + if (!list_empty(&ep->queue)) + enable_fifo_int(ep); + } + } + fusb300_set_cxdone(fusb300); + break; + default: + request_error(fusb300); + break; + } +} + +static void fusb300_set_dev_addr(struct fusb300 *fusb300, u16 addr) +{ + u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_DAR); + + reg &= ~FUSB300_DAR_DRVADDR_MSK; + reg |= FUSB300_DAR_DRVADDR(addr); + + iowrite32(reg, fusb300->reg + FUSB300_OFFSET_DAR); +} + +static void set_address(struct fusb300 *fusb300, struct usb_ctrlrequest *ctrl) +{ + if (ctrl->wValue >= 0x0100) + request_error(fusb300); + else { + fusb300_set_dev_addr(fusb300, ctrl->wValue); + fusb300_set_cxdone(fusb300); + } +} + +#define UVC_COPY_DESCRIPTORS(mem, src) \ + do { \ + const struct usb_descriptor_header * const *__src; \ + for (__src = src; *__src; ++__src) { \ + memcpy(mem, *__src, (*__src)->bLength); \ + mem += (*__src)->bLength; \ + } \ + } while (0) + +static void fusb300_ep0_complete(struct usb_ep *ep, + struct usb_request *req) +{ +} + +static int setup_packet(struct fusb300 *fusb300, struct usb_ctrlrequest *ctrl) +{ + u8 *p = (u8 *)ctrl; + u8 ret = 0; + u8 i = 0; + + fusb300_rdcxf(fusb300, p, 8); + fusb300->ep0_dir = ctrl->bRequestType & USB_DIR_IN; + fusb300->ep0_length = ctrl->wLength; + + /* check request */ + if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { + switch (ctrl->bRequest) { + case USB_REQ_GET_STATUS: + get_status(fusb300, ctrl); + break; + case USB_REQ_CLEAR_FEATURE: + clear_feature(fusb300, ctrl); + break; + case USB_REQ_SET_FEATURE: + set_feature(fusb300, ctrl); + break; + case USB_REQ_SET_ADDRESS: + set_address(fusb300, ctrl); + break; + case USB_REQ_SET_CONFIGURATION: + fusb300_enable_bit(fusb300, FUSB300_OFFSET_DAR, + FUSB300_DAR_SETCONFG); + /* clear sequence number */ + for (i = 1; i <= FUSB300_MAX_NUM_EP; i++) + fusb300_clear_seqnum(fusb300, i); + fusb300->reenum = 1; + ret = 1; + break; + default: + ret = 1; + break; + } + } else + ret = 1; + + return ret; +} + +static void fusb300_set_ep_bycnt(struct fusb300_ep *ep, u32 bycnt) +{ + struct fusb300 *fusb300 = ep->fusb300; + u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPFFR(ep->epnum)); + + reg &= ~FUSB300_FFR_BYCNT; + reg |= bycnt & FUSB300_FFR_BYCNT; + + iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPFFR(ep->epnum)); +} + +static void done(struct fusb300_ep *ep, struct fusb300_request *req, + int status) +{ + list_del_init(&req->queue); + + /* don't modify queue heads during completion callback */ + if (ep->fusb300->gadget.speed == USB_SPEED_UNKNOWN) + req->req.status = -ESHUTDOWN; + else + req->req.status = status; + + spin_unlock(&ep->fusb300->lock); + req->req.complete(&ep->ep, &req->req); + spin_lock(&ep->fusb300->lock); + + if (ep->epnum) { + disable_fifo_int(ep); + if (!list_empty(&ep->queue)) + enable_fifo_int(ep); + } else + fusb300_set_cxdone(ep->fusb300); +} + +void fusb300_fill_idma_prdtbl(struct fusb300_ep *ep, + struct fusb300_request *req) +{ + u32 value; + u32 reg; + + /* wait SW owner */ + do { + reg = ioread32(ep->fusb300->reg + + FUSB300_OFFSET_EPPRD_W0(ep->epnum)); + reg &= FUSB300_EPPRD0_H; + } while (reg); + + iowrite32((u32) req->req.buf, ep->fusb300->reg + + FUSB300_OFFSET_EPPRD_W1(ep->epnum)); + + value = FUSB300_EPPRD0_BTC(req->req.length) | FUSB300_EPPRD0_H | + FUSB300_EPPRD0_F | FUSB300_EPPRD0_L | FUSB300_EPPRD0_I; + iowrite32(value, ep->fusb300->reg + FUSB300_OFFSET_EPPRD_W0(ep->epnum)); + + iowrite32(0x0, ep->fusb300->reg + FUSB300_OFFSET_EPPRD_W2(ep->epnum)); + + fusb300_enable_bit(ep->fusb300, FUSB300_OFFSET_EPPRDRDY, + FUSB300_EPPRDR_EP_PRD_RDY(ep->epnum)); +} + +static void fusb300_wait_idma_finished(struct fusb300_ep *ep) +{ + u32 reg; + + do { + reg = ioread32(ep->fusb300->reg + FUSB300_OFFSET_IGR1); + if ((reg & FUSB300_IGR1_VBUS_CHG_INT) || + (reg & FUSB300_IGR1_WARM_RST_INT) || + (reg & FUSB300_IGR1_HOT_RST_INT) || + (reg & FUSB300_IGR1_USBRST_INT) + ) + goto IDMA_RESET; + reg = ioread32(ep->fusb300->reg + FUSB300_OFFSET_IGR0); + reg &= FUSB300_IGR0_EPn_PRD_INT(ep->epnum); + } while (!reg); + + fusb300_clear_int(ep->fusb300, FUSB300_OFFSET_IGR0, + FUSB300_IGR0_EPn_PRD_INT(ep->epnum)); +IDMA_RESET: + fusb300_clear_int(ep->fusb300, FUSB300_OFFSET_IGER0, + FUSB300_IGER0_EEPn_PRD_INT(ep->epnum)); +} + +static void fusb300_set_idma(struct fusb300_ep *ep, + struct fusb300_request *req) +{ + dma_addr_t d; + u8 *tmp = NULL; + + d = dma_map_single(NULL, req->req.buf, req->req.length, DMA_TO_DEVICE); + + if (dma_mapping_error(NULL, d)) { + kfree(req->req.buf); + printk(KERN_DEBUG "dma_mapping_error\n"); + } + + dma_sync_single_for_device(NULL, d, req->req.length, DMA_TO_DEVICE); + + fusb300_enable_bit(ep->fusb300, FUSB300_OFFSET_IGER0, + FUSB300_IGER0_EEPn_PRD_INT(ep->epnum)); + + tmp = req->req.buf; + req->req.buf = (u8 *)d; + + fusb300_fill_idma_prdtbl(ep, req); + /* check idma is done */ + fusb300_wait_idma_finished(ep); + + req->req.buf = tmp; + + if (d) + dma_unmap_single(NULL, d, req->req.length, DMA_TO_DEVICE); +} + +static void in_ep_fifo_handler(struct fusb300_ep *ep) +{ + struct fusb300_request *req = list_entry(ep->queue.next, + struct fusb300_request, queue); + + if (req->req.length) { +#if 0 + fusb300_set_ep_bycnt(ep, req->req.length); + fusb300_wrfifo(ep, req); +#else + fusb300_set_idma(ep, req); +#endif + } + done(ep, req, 0); +} + +static void out_ep_fifo_handler(struct fusb300_ep *ep) +{ + struct fusb300 *fusb300 = ep->fusb300; + struct fusb300_request *req = list_entry(ep->queue.next, + struct fusb300_request, queue); + u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPFFR(ep->epnum)); + u32 length = reg & FUSB300_FFR_BYCNT; + + fusb300_rdfifo(ep, req, length); + + /* finish out transfer */ + if ((req->req.length == req->req.actual) || (length < ep->ep.maxpacket)) + done(ep, req, 0); +} + +static void check_device_mode(struct fusb300 *fusb300) +{ + u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_GCR); + + switch (reg & FUSB300_GCR_DEVEN_MSK) { + case FUSB300_GCR_DEVEN_SS: + fusb300->gadget.speed = USB_SPEED_SUPER; + break; + case FUSB300_GCR_DEVEN_HS: + fusb300->gadget.speed = USB_SPEED_HIGH; + break; + case FUSB300_GCR_DEVEN_FS: + fusb300->gadget.speed = USB_SPEED_FULL; + break; + default: + fusb300->gadget.speed = USB_SPEED_UNKNOWN; + break; + } + printk(KERN_INFO "dev_mode = %d\n", (reg & FUSB300_GCR_DEVEN_MSK)); +} + + +static void fusb300_ep0out(struct fusb300 *fusb300) +{ + struct fusb300_ep *ep = fusb300->ep[0]; + u32 reg; + + if (!list_empty(&ep->queue)) { + struct fusb300_request *req; + + req = list_first_entry(&ep->queue, + struct fusb300_request, queue); + if (req->req.length) + fusb300_rdcxf(ep->fusb300, req->req.buf, + req->req.length); + done(ep, req, 0); + reg = ioread32(fusb300->reg + FUSB300_OFFSET_IGER1); + reg &= ~FUSB300_IGER1_CX_OUT_INT; + iowrite32(reg, fusb300->reg + FUSB300_OFFSET_IGER1); + } else + pr_err("%s : empty queue\n", __func__); +} + +static void fusb300_ep0in(struct fusb300 *fusb300) +{ + struct fusb300_request *req; + struct fusb300_ep *ep = fusb300->ep[0]; + + if ((!list_empty(&ep->queue)) && (fusb300->ep0_dir)) { + req = list_entry(ep->queue.next, + struct fusb300_request, queue); + if (req->req.length) + fusb300_wrcxf(ep, req); + if ((req->req.length - req->req.actual) < ep->ep.maxpacket) + done(ep, req, 0); + } else + fusb300_set_cxdone(fusb300); +} + +static void fusb300_grp2_handler(void) +{ +} + +static void fusb300_grp3_handler(void) +{ +} + +static void fusb300_grp4_handler(void) +{ +} + +static void fusb300_grp5_handler(void) +{ +} + +static irqreturn_t fusb300_irq(int irq, void *_fusb300) +{ + struct fusb300 *fusb300 = _fusb300; + u32 int_grp1 = ioread32(fusb300->reg + FUSB300_OFFSET_IGR1); + u32 int_grp1_en = ioread32(fusb300->reg + FUSB300_OFFSET_IGER1); + u32 int_grp0 = ioread32(fusb300->reg + FUSB300_OFFSET_IGR0); + u32 int_grp0_en = ioread32(fusb300->reg + FUSB300_OFFSET_IGER0); + struct usb_ctrlrequest ctrl; + u8 in; + u32 reg; + int i; + + spin_lock(&fusb300->lock); + + int_grp1 &= int_grp1_en; + int_grp0 &= int_grp0_en; + + if (int_grp1 & FUSB300_IGR1_WARM_RST_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_WARM_RST_INT); + printk(KERN_INFO"fusb300_warmreset\n"); + fusb300_reset(); + } + + if (int_grp1 & FUSB300_IGR1_HOT_RST_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_HOT_RST_INT); + printk(KERN_INFO"fusb300_hotreset\n"); + fusb300_reset(); + } + + if (int_grp1 & FUSB300_IGR1_USBRST_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_USBRST_INT); + fusb300_reset(); + } + /* COMABT_INT has a highest priority */ + + if (int_grp1 & FUSB300_IGR1_CX_COMABT_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_CX_COMABT_INT); + printk(KERN_INFO"fusb300_ep0abt\n"); + } + + if (int_grp1 & FUSB300_IGR1_VBUS_CHG_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_VBUS_CHG_INT); + printk(KERN_INFO"fusb300_vbus_change\n"); + } + + if (int_grp1 & FUSB300_IGR1_U3_EXIT_FAIL_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_U3_EXIT_FAIL_INT); + } + + if (int_grp1 & FUSB300_IGR1_U2_EXIT_FAIL_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_U2_EXIT_FAIL_INT); + } + + if (int_grp1 & FUSB300_IGR1_U1_EXIT_FAIL_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_U1_EXIT_FAIL_INT); + } + + if (int_grp1 & FUSB300_IGR1_U2_ENTRY_FAIL_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_U2_ENTRY_FAIL_INT); + } + + if (int_grp1 & FUSB300_IGR1_U1_ENTRY_FAIL_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_U1_ENTRY_FAIL_INT); + } + + if (int_grp1 & FUSB300_IGR1_U3_EXIT_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_U3_EXIT_INT); + printk(KERN_INFO "FUSB300_IGR1_U3_EXIT_INT\n"); + } + + if (int_grp1 & FUSB300_IGR1_U2_EXIT_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_U2_EXIT_INT); + printk(KERN_INFO "FUSB300_IGR1_U2_EXIT_INT\n"); + } + + if (int_grp1 & FUSB300_IGR1_U1_EXIT_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_U1_EXIT_INT); + printk(KERN_INFO "FUSB300_IGR1_U1_EXIT_INT\n"); + } + + if (int_grp1 & FUSB300_IGR1_U3_ENTRY_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_U3_ENTRY_INT); + printk(KERN_INFO "FUSB300_IGR1_U3_ENTRY_INT\n"); + fusb300_enable_bit(fusb300, FUSB300_OFFSET_SSCR1, + FUSB300_SSCR1_GO_U3_DONE); + } + + if (int_grp1 & FUSB300_IGR1_U2_ENTRY_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_U2_ENTRY_INT); + printk(KERN_INFO "FUSB300_IGR1_U2_ENTRY_INT\n"); + } + + if (int_grp1 & FUSB300_IGR1_U1_ENTRY_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_U1_ENTRY_INT); + printk(KERN_INFO "FUSB300_IGR1_U1_ENTRY_INT\n"); + } + + if (int_grp1 & FUSB300_IGR1_RESM_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_RESM_INT); + printk(KERN_INFO "fusb300_resume\n"); + } + + if (int_grp1 & FUSB300_IGR1_SUSP_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_SUSP_INT); + printk(KERN_INFO "fusb300_suspend\n"); + } + + if (int_grp1 & FUSB300_IGR1_HS_LPM_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_HS_LPM_INT); + printk(KERN_INFO "fusb300_HS_LPM_INT\n"); + } + + if (int_grp1 & FUSB300_IGR1_DEV_MODE_CHG_INT) { + fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, + FUSB300_IGR1_DEV_MODE_CHG_INT); + check_device_mode(fusb300); + } + + if (int_grp1 & FUSB300_IGR1_CX_COMFAIL_INT) { + fusb300_set_cxstall(fusb300); + printk(KERN_INFO "fusb300_ep0fail\n"); + } + + if (int_grp1 & FUSB300_IGR1_CX_SETUP_INT) { + printk(KERN_INFO "fusb300_ep0setup\n"); + if (setup_packet(fusb300, &ctrl)) { + spin_unlock(&fusb300->lock); + if (fusb300->driver->setup(&fusb300->gadget, &ctrl) < 0) + fusb300_set_cxstall(fusb300); + spin_lock(&fusb300->lock); + } + } + + if (int_grp1 & FUSB300_IGR1_CX_CMDEND_INT) + printk(KERN_INFO "fusb300_cmdend\n"); + + + if (int_grp1 & FUSB300_IGR1_CX_OUT_INT) { + printk(KERN_INFO "fusb300_cxout\n"); + fusb300_ep0out(fusb300); + } + + if (int_grp1 & FUSB300_IGR1_CX_IN_INT) { + printk(KERN_INFO "fusb300_cxin\n"); + fusb300_ep0in(fusb300); + } + + if (int_grp1 & FUSB300_IGR1_INTGRP5) + fusb300_grp5_handler(); + + if (int_grp1 & FUSB300_IGR1_INTGRP4) + fusb300_grp4_handler(); + + if (int_grp1 & FUSB300_IGR1_INTGRP3) + fusb300_grp3_handler(); + + if (int_grp1 & FUSB300_IGR1_INTGRP2) + fusb300_grp2_handler(); + + if (int_grp0) { + for (i = 1; i < FUSB300_MAX_NUM_EP; i++) { + if (int_grp0 & FUSB300_IGR0_EPn_FIFO_INT(i)) { + reg = ioread32(fusb300->reg + + FUSB300_OFFSET_EPSET1(i)); + in = (reg & FUSB300_EPSET1_DIRIN) ? 1 : 0; + if (in) + in_ep_fifo_handler(fusb300->ep[i]); + else + out_ep_fifo_handler(fusb300->ep[i]); + } + } + } + + spin_unlock(&fusb300->lock); + + return IRQ_HANDLED; +} + +static void fusb300_set_u2_timeout(struct fusb300 *fusb300, + u32 time) +{ + u32 reg; + + reg = ioread32(fusb300->reg + FUSB300_OFFSET_TT); + reg &= ~0xff; + reg |= FUSB300_SSCR2_U2TIMEOUT(time); + + iowrite32(reg, fusb300->reg + FUSB300_OFFSET_TT); +} + +static void fusb300_set_u1_timeout(struct fusb300 *fusb300, + u32 time) +{ + u32 reg; + + reg = ioread32(fusb300->reg + FUSB300_OFFSET_TT); + reg &= ~(0xff << 8); + reg |= FUSB300_SSCR2_U1TIMEOUT(time); + + iowrite32(reg, fusb300->reg + FUSB300_OFFSET_TT); +} + +static void init_controller(struct fusb300 *fusb300) +{ + u32 reg; + u32 mask = 0; + u32 val = 0; + + /* split on */ + mask = val = FUSB300_AHBBCR_S0_SPLIT_ON | FUSB300_AHBBCR_S1_SPLIT_ON; + reg = ioread32(fusb300->reg + FUSB300_OFFSET_AHBCR); + reg &= ~mask; + reg |= val; + iowrite32(reg, fusb300->reg + FUSB300_OFFSET_AHBCR); + + /* enable high-speed LPM */ + mask = val = FUSB300_HSCR_HS_LPM_PERMIT; + reg = ioread32(fusb300->reg + FUSB300_OFFSET_HSCR); + reg &= ~mask; + reg |= val; + iowrite32(reg, fusb300->reg + FUSB300_OFFSET_HSCR); + + /*set u1 u2 timmer*/ + fusb300_set_u2_timeout(fusb300, 0xff); + fusb300_set_u1_timeout(fusb300, 0xff); + + /* enable all grp1 interrupt */ + iowrite32(0xcfffff9f, fusb300->reg + FUSB300_OFFSET_IGER1); +} +/*------------------------------------------------------------------------*/ +static struct fusb300 *the_controller; + +int usb_gadget_probe_driver(struct usb_gadget_driver *driver, + int (*bind)(struct usb_gadget *)) +{ + struct fusb300 *fusb300 = the_controller; + int retval; + + if (!driver + || driver->speed < USB_SPEED_FULL + || !bind + || !driver->setup) + return -EINVAL; + + if (!fusb300) + return -ENODEV; + + if (fusb300->driver) + return -EBUSY; + + /* hook up the driver */ + driver->driver.bus = NULL; + fusb300->driver = driver; + fusb300->gadget.dev.driver = &driver->driver; + + retval = device_add(&fusb300->gadget.dev); + if (retval) { + pr_err("device_add error (%d)\n", retval); + goto error; + } + + retval = bind(&fusb300->gadget); + if (retval) { + pr_err("bind to driver error (%d)\n", retval); + device_del(&fusb300->gadget.dev); + goto error; + } + + return 0; + +error: + fusb300->driver = NULL; + fusb300->gadget.dev.driver = NULL; + + return retval; +} +EXPORT_SYMBOL(usb_gadget_probe_driver); + +int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) +{ + struct fusb300 *fusb300 = the_controller; + + if (driver != fusb300->driver || !driver->unbind) + return -EINVAL; + + driver->unbind(&fusb300->gadget); + fusb300->gadget.dev.driver = NULL; + + init_controller(fusb300); + device_del(&fusb300->gadget.dev); + fusb300->driver = NULL; + + return 0; +} +EXPORT_SYMBOL(usb_gadget_unregister_driver); +/*--------------------------------------------------------------------------*/ + +static int fusb300_udc_pullup(struct usb_gadget *_gadget, int is_active) +{ + return 0; +} + +static struct usb_gadget_ops fusb300_gadget_ops = { + .pullup = fusb300_udc_pullup, +}; + +static int __exit fusb300_remove(struct platform_device *pdev) +{ + struct fusb300 *fusb300 = dev_get_drvdata(&pdev->dev); + + iounmap(fusb300->reg); + free_irq(platform_get_irq(pdev, 0), fusb300); + + fusb300_free_request(&fusb300->ep[0]->ep, fusb300->ep0_req); + kfree(fusb300); + + return 0; +} + +static int __init fusb300_probe(struct platform_device *pdev) +{ + struct resource *res, *ires, *ires1; + void __iomem *reg = NULL; + struct fusb300 *fusb300 = NULL; + struct fusb300_ep *_ep[FUSB300_MAX_NUM_EP]; + int ret = 0; + int i; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = -ENODEV; + pr_err("platform_get_resource error.\n"); + goto clean_up; + } + + ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!ires) { + ret = -ENODEV; + dev_err(&pdev->dev, + "platform_get_resource IORESOURCE_IRQ error.\n"); + goto clean_up; + } + + ires1 = platform_get_resource(pdev, IORESOURCE_IRQ, 1); + if (!ires1) { + ret = -ENODEV; + dev_err(&pdev->dev, + "platform_get_resource IORESOURCE_IRQ 1 error.\n"); + goto clean_up; + } + + reg = ioremap(res->start, resource_size(res)); + if (reg == NULL) { + ret = -ENOMEM; + pr_err("ioremap error.\n"); + goto clean_up; + } + + /* initialize udc */ + fusb300 = kzalloc(sizeof(struct fusb300), GFP_KERNEL); + if (fusb300 == NULL) { + pr_err("kzalloc error\n"); + goto clean_up; + } + + for (i = 0; i < FUSB300_MAX_NUM_EP; i++) { + _ep[i] = kzalloc(sizeof(struct fusb300_ep), GFP_KERNEL); + if (_ep[i] == NULL) { + pr_err("_ep kzalloc error\n"); + goto clean_up; + } + fusb300->ep[i] = _ep[i]; + } + + spin_lock_init(&fusb300->lock); + + dev_set_drvdata(&pdev->dev, fusb300); + + fusb300->gadget.ops = &fusb300_gadget_ops; + + device_initialize(&fusb300->gadget.dev); + + dev_set_name(&fusb300->gadget.dev, "gadget"); + + fusb300->gadget.is_dualspeed = 1; + fusb300->gadget.dev.parent = &pdev->dev; + fusb300->gadget.dev.dma_mask = pdev->dev.dma_mask; + fusb300->gadget.dev.release = pdev->dev.release; + fusb300->gadget.name = udc_name; + fusb300->reg = reg; + + ret = request_irq(ires->start, fusb300_irq, IRQF_DISABLED | IRQF_SHARED, + udc_name, fusb300); + if (ret < 0) { + pr_err("request_irq error (%d)\n", ret); + goto clean_up; + } + + ret = request_irq(ires1->start, fusb300_irq, + IRQF_DISABLED | IRQF_SHARED, udc_name, fusb300); + if (ret < 0) { + pr_err("request_irq1 error (%d)\n", ret); + goto clean_up; + } + + INIT_LIST_HEAD(&fusb300->gadget.ep_list); + + for (i = 0; i < FUSB300_MAX_NUM_EP ; i++) { + struct fusb300_ep *ep = fusb300->ep[i]; + + if (i != 0) { + INIT_LIST_HEAD(&fusb300->ep[i]->ep.ep_list); + list_add_tail(&fusb300->ep[i]->ep.ep_list, + &fusb300->gadget.ep_list); + } + ep->fusb300 = fusb300; + INIT_LIST_HEAD(&ep->queue); + ep->ep.name = fusb300_ep_name[i]; + ep->ep.ops = &fusb300_ep_ops; + ep->ep.maxpacket = HS_BULK_MAX_PACKET_SIZE; + } + fusb300->ep[0]->ep.maxpacket = HS_CTL_MAX_PACKET_SIZE; + fusb300->ep[0]->epnum = 0; + fusb300->gadget.ep0 = &fusb300->ep[0]->ep; + INIT_LIST_HEAD(&fusb300->gadget.ep0->ep_list); + + the_controller = fusb300; + + fusb300->ep0_req = fusb300_alloc_request(&fusb300->ep[0]->ep, + GFP_KERNEL); + if (fusb300->ep0_req == NULL) + goto clean_up3; + + init_controller(fusb300); + dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); + + return 0; + +clean_up3: + free_irq(ires->start, fusb300); + +clean_up: + if (fusb300) { + if (fusb300->ep0_req) + fusb300_free_request(&fusb300->ep[0]->ep, + fusb300->ep0_req); + kfree(fusb300); + } + if (reg) + iounmap(reg); + + return ret; +} + +static struct platform_driver fusb300_driver = { + .remove = __exit_p(fusb300_remove), + .driver = { + .name = (char *) udc_name, + .owner = THIS_MODULE, + }, +}; + +static int __init fusb300_udc_init(void) +{ + return platform_driver_probe(&fusb300_driver, fusb300_probe); +} + +module_init(fusb300_udc_init); + +static void __exit fusb300_udc_cleanup(void) +{ + platform_driver_unregister(&fusb300_driver); +} +module_exit(fusb300_udc_cleanup); diff --git a/drivers/usb/gadget/fusb300_udc.h b/drivers/usb/gadget/fusb300_udc.h new file mode 100644 index 000000000000..f51aa2ef1f90 --- /dev/null +++ b/drivers/usb/gadget/fusb300_udc.h @@ -0,0 +1,687 @@ +/* + * Fusb300 UDC (USB gadget) + * + * Copyright (C) 2010 Faraday Technology Corp. + * + * Author : Yuan-hsin Chen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +#ifndef __FUSB300_UDC_H__ +#define __FUSB300_UDC_H_ + +#include + +#define FUSB300_OFFSET_GCR 0x00 +#define FUSB300_OFFSET_GTM 0x04 +#define FUSB300_OFFSET_DAR 0x08 +#define FUSB300_OFFSET_CSR 0x0C +#define FUSB300_OFFSET_CXPORT 0x10 +#define FUSB300_OFFSET_EPSET0(n) (0x20 + (n - 1) * 0x30) +#define FUSB300_OFFSET_EPSET1(n) (0x24 + (n - 1) * 0x30) +#define FUSB300_OFFSET_EPSET2(n) (0x28 + (n - 1) * 0x30) +#define FUSB300_OFFSET_EPFFR(n) (0x2c + (n - 1) * 0x30) +#define FUSB300_OFFSET_EPSTRID(n) (0x40 + (n - 1) * 0x30) +#define FUSB300_OFFSET_HSPTM 0x300 +#define FUSB300_OFFSET_HSCR 0x304 +#define FUSB300_OFFSET_SSCR0 0x308 +#define FUSB300_OFFSET_SSCR1 0x30C +#define FUSB300_OFFSET_TT 0x310 +#define FUSB300_OFFSET_DEVNOTF 0x314 +#define FUSB300_OFFSET_DNC1 0x318 +#define FUSB300_OFFSET_CS 0x31C +#define FUSB300_OFFSET_SOF 0x324 +#define FUSB300_OFFSET_EFCS 0x328 +#define FUSB300_OFFSET_IGR0 0x400 +#define FUSB300_OFFSET_IGR1 0x404 +#define FUSB300_OFFSET_IGR2 0x408 +#define FUSB300_OFFSET_IGR3 0x40C +#define FUSB300_OFFSET_IGR4 0x410 +#define FUSB300_OFFSET_IGR5 0x414 +#define FUSB300_OFFSET_IGER0 0x420 +#define FUSB300_OFFSET_IGER1 0x424 +#define FUSB300_OFFSET_IGER2 0x428 +#define FUSB300_OFFSET_IGER3 0x42C +#define FUSB300_OFFSET_IGER4 0x430 +#define FUSB300_OFFSET_IGER5 0x434 +#define FUSB300_OFFSET_DMAHMER 0x500 +#define FUSB300_OFFSET_EPPRDRDY 0x504 +#define FUSB300_OFFSET_DMAEPMR 0x508 +#define FUSB300_OFFSET_DMAENR 0x50C +#define FUSB300_OFFSET_DMAAPR 0x510 +#define FUSB300_OFFSET_AHBCR 0x514 +#define FUSB300_OFFSET_EPPRD_W0(n) (0x520 + (n - 1) * 0x10) +#define FUSB300_OFFSET_EPPRD_W1(n) (0x524 + (n - 1) * 0x10) +#define FUSB300_OFFSET_EPPRD_W2(n) (0x528 + (n - 1) * 0x10) +#define FUSB300_OFFSET_EPRD_PTR(n) (0x52C + (n - 1) * 0x10) +#define FUSB300_OFFSET_BUFDBG_START 0x800 +#define FUSB300_OFFSET_BUFDBG_END 0xBFC +#define FUSB300_OFFSET_EPPORT(n) (0x1010 + (n - 1) * 0x10) + +/* + * * Global Control Register (offset = 000H) + * */ +#define FUSB300_GCR_SF_RST (1 << 8) +#define FUSB300_GCR_VBUS_STATUS (1 << 7) +#define FUSB300_GCR_FORCE_HS_SUSP (1 << 6) +#define FUSB300_GCR_SYNC_FIFO1_CLR (1 << 5) +#define FUSB300_GCR_SYNC_FIFO0_CLR (1 << 4) +#define FUSB300_GCR_FIFOCLR (1 << 3) +#define FUSB300_GCR_GLINTEN (1 << 2) +#define FUSB300_GCR_DEVEN_FS 0x3 +#define FUSB300_GCR_DEVEN_HS 0x2 +#define FUSB300_GCR_DEVEN_SS 0x1 +#define FUSB300_GCR_DEVDIS 0x0 +#define FUSB300_GCR_DEVEN_MSK 0x3 + + +/* + * *Global Test Mode (offset = 004H) + * */ +#define FUSB300_GTM_TST_DIS_SOFGEN (1 << 16) +#define FUSB300_GTM_TST_CUR_EP_ENTRY(n) ((n & 0xF) << 12) +#define FUSB300_GTM_TST_EP_ENTRY(n) ((n & 0xF) << 8) +#define FUSB300_GTM_TST_EP_NUM(n) ((n & 0xF) << 4) +#define FUSB300_GTM_TST_FIFO_DEG (1 << 1) +#define FUSB300_GTM_TSTMODE (1 << 0) + +/* + * * Device Address Register (offset = 008H) + * */ +#define FUSB300_DAR_SETCONFG (1 << 7) +#define FUSB300_DAR_DRVADDR(x) (x & 0x7F) +#define FUSB300_DAR_DRVADDR_MSK 0x7F + +/* + * *Control Transfer Configuration and Status Register + * (CX_Config_Status, offset = 00CH) + * */ +#define FUSB300_CSR_LEN(x) ((x & 0xFFFF) << 8) +#define FUSB300_CSR_LEN_MSK (0xFFFF << 8) +#define FUSB300_CSR_EMP (1 << 4) +#define FUSB300_CSR_FUL (1 << 3) +#define FUSB300_CSR_CLR (1 << 2) +#define FUSB300_CSR_STL (1 << 1) +#define FUSB300_CSR_DONE (1 << 0) + +/* + * * EPn Setting 0 (EPn_SET0, offset = 020H+(n-1)*30H, n=1~15 ) + * */ +#define FUSB300_EPSET0_CLRSEQNUM (1 << 2) +#define FUSB300_EPSET0_EPn_TX0BYTE (1 << 1) +#define FUSB300_EPSET0_STL (1 << 0) + +/* + * * EPn Setting 1 (EPn_SET1, offset = 024H+(n-1)*30H, n=1~15) + * */ +#define FUSB300_EPSET1_START_ENTRY(x) ((x & 0xFF) << 24) +#define FUSB300_EPSET1_START_ENTRY_MSK (0xFF << 24) +#define FUSB300_EPSET1_FIFOENTRY(x) ((x & 0x1F) << 12) +#define FUSB300_EPSET1_FIFOENTRY_MSK (0x1f << 12) +#define FUSB300_EPSET1_INTERVAL(x) ((x & 0x7) << 6) +#define FUSB300_EPSET1_BWNUM(x) ((x & 0x3) << 4) +#define FUSB300_EPSET1_TYPEISO (1 << 2) +#define FUSB300_EPSET1_TYPEBLK (2 << 2) +#define FUSB300_EPSET1_TYPEINT (3 << 2) +#define FUSB300_EPSET1_TYPE(x) ((x & 0x3) << 2) +#define FUSB300_EPSET1_TYPE_MSK (0x3 << 2) +#define FUSB300_EPSET1_DIROUT (0 << 1) +#define FUSB300_EPSET1_DIRIN (1 << 1) +#define FUSB300_EPSET1_DIR(x) ((x & 0x1) << 1) +#define FUSB300_EPSET1_DIRIN (1 << 1) +#define FUSB300_EPSET1_DIR_MSK ((0x1) << 1) +#define FUSB300_EPSET1_ACTDIS 0 +#define FUSB300_EPSET1_ACTEN 1 + +/* + * *EPn Setting 2 (EPn_SET2, offset = 028H+(n-1)*30H, n=1~15) + * */ +#define FUSB300_EPSET2_ADDROFS(x) ((x & 0x7FFF) << 16) +#define FUSB300_EPSET2_ADDROFS_MSK (0x7fff << 16) +#define FUSB300_EPSET2_MPS(x) (x & 0x7FF) +#define FUSB300_EPSET2_MPS_MSK 0x7FF + +/* + * * EPn FIFO Register (offset = 2cH+(n-1)*30H) + * */ +#define FUSB300_FFR_RST (1 << 31) +#define FUSB300_FF_FUL (1 << 30) +#define FUSB300_FF_EMPTY (1 << 29) +#define FUSB300_FFR_BYCNT 0x1FFFF + +/* + * *EPn Stream ID (EPn_STR_ID, offset = 040H+(n-1)*30H, n=1~15) + * */ +#define FUSB300_STRID_STREN (1 << 16) +#define FUSB300_STRID_STRID(x) (x & 0xFFFF) + +/* + * *HS PHY Test Mode (offset = 300H) + * */ +#define FUSB300_HSPTM_TSTPKDONE (1 << 4) +#define FUSB300_HSPTM_TSTPKT (1 << 3) +#define FUSB300_HSPTM_TSTSET0NAK (1 << 2) +#define FUSB300_HSPTM_TSTKSTA (1 << 1) +#define FUSB300_HSPTM_TSTJSTA (1 << 0) + +/* + * *HS Control Register (offset = 304H) + * */ +#define FUSB300_HSCR_HS_LPM_PERMIT (1 << 8) +#define FUSB300_HSCR_HS_LPM_RMWKUP (1 << 7) +#define FUSB300_HSCR_CAP_LPM_RMWKUP (1 << 6) +#define FUSB300_HSCR_HS_GOSUSP (1 << 5) +#define FUSB300_HSCR_HS_GORMWKU (1 << 4) +#define FUSB300_HSCR_CAP_RMWKUP (1 << 3) +#define FUSB300_HSCR_IDLECNT_0MS 0 +#define FUSB300_HSCR_IDLECNT_1MS 1 +#define FUSB300_HSCR_IDLECNT_2MS 2 +#define FUSB300_HSCR_IDLECNT_3MS 3 +#define FUSB300_HSCR_IDLECNT_4MS 4 +#define FUSB300_HSCR_IDLECNT_5MS 5 +#define FUSB300_HSCR_IDLECNT_6MS 6 +#define FUSB300_HSCR_IDLECNT_7MS 7 + +/* + * * SS Controller Register 0 (offset = 308H) + * */ +#define FUSB300_SSCR0_MAX_INTERVAL(x) ((x & 0x7) << 4) +#define FUSB300_SSCR0_U2_FUN_EN (1 << 1) +#define FUSB300_SSCR0_U1_FUN_EN (1 << 0) + +/* + * * SS Controller Register 1 (offset = 30CH) + * */ +#define FUSB300_SSCR1_GO_U3_DONE (1 << 8) +#define FUSB300_SSCR1_TXDEEMPH_LEVEL (1 << 7) +#define FUSB300_SSCR1_DIS_SCRMB (1 << 6) +#define FUSB300_SSCR1_FORCE_RECOVERY (1 << 5) +#define FUSB300_SSCR1_U3_WAKEUP_EN (1 << 4) +#define FUSB300_SSCR1_U2_EXIT_EN (1 << 3) +#define FUSB300_SSCR1_U1_EXIT_EN (1 << 2) +#define FUSB300_SSCR1_U2_ENTRY_EN (1 << 1) +#define FUSB300_SSCR1_U1_ENTRY_EN (1 << 0) + +/* + * *SS Controller Register 2 (offset = 310H) + * */ +#define FUSB300_SSCR2_SS_TX_SWING (1 << 25) +#define FUSB300_SSCR2_FORCE_LINKPM_ACCEPT (1 << 24) +#define FUSB300_SSCR2_U2_INACT_TIMEOUT(x) ((x & 0xFF) << 16) +#define FUSB300_SSCR2_U1TIMEOUT(x) ((x & 0xFF) << 8) +#define FUSB300_SSCR2_U2TIMEOUT(x) (x & 0xFF) + +/* + * *SS Device Notification Control (DEV_NOTF, offset = 314H) + * */ +#define FUSB300_DEVNOTF_CONTEXT0(x) ((x & 0xFFFFFF) << 8) +#define FUSB300_DEVNOTF_TYPE_DIS 0 +#define FUSB300_DEVNOTF_TYPE_FUNCWAKE 1 +#define FUSB300_DEVNOTF_TYPE_LTM 2 +#define FUSB300_DEVNOTF_TYPE_BUSINT_ADJMSG 3 + +/* + * *BFM Arbiter Priority Register (BFM_ARB offset = 31CH) + * */ +#define FUSB300_BFMARB_ARB_M1 (1 << 3) +#define FUSB300_BFMARB_ARB_M0 (1 << 2) +#define FUSB300_BFMARB_ARB_S1 (1 << 1) +#define FUSB300_BFMARB_ARB_S0 1 + +/* + * *Vendor Specific IO Control Register (offset = 320H) + * */ +#define FUSB300_VSIC_VCTLOAD_N (1 << 8) +#define FUSB300_VSIC_VCTL(x) (x & 0x3F) + +/* + * *SOF Mask Timer (offset = 324H) + * */ +#define FUSB300_SOF_MASK_TIMER_HS 0x044c +#define FUSB300_SOF_MASK_TIMER_FS 0x2710 + +/* + * *Error Flag and Control Status (offset = 328H) + * */ +#define FUSB300_EFCS_PM_STATE_U3 3 +#define FUSB300_EFCS_PM_STATE_U2 2 +#define FUSB300_EFCS_PM_STATE_U1 1 +#define FUSB300_EFCS_PM_STATE_U0 0 + +/* + * *Interrupt Group 0 Register (offset = 400H) + * */ +#define FUSB300_IGR0_EP15_PRD_INT (1 << 31) +#define FUSB300_IGR0_EP14_PRD_INT (1 << 30) +#define FUSB300_IGR0_EP13_PRD_INT (1 << 29) +#define FUSB300_IGR0_EP12_PRD_INT (1 << 28) +#define FUSB300_IGR0_EP11_PRD_INT (1 << 27) +#define FUSB300_IGR0_EP10_PRD_INT (1 << 26) +#define FUSB300_IGR0_EP9_PRD_INT (1 << 25) +#define FUSB300_IGR0_EP8_PRD_INT (1 << 24) +#define FUSB300_IGR0_EP7_PRD_INT (1 << 23) +#define FUSB300_IGR0_EP6_PRD_INT (1 << 22) +#define FUSB300_IGR0_EP5_PRD_INT (1 << 21) +#define FUSB300_IGR0_EP4_PRD_INT (1 << 20) +#define FUSB300_IGR0_EP3_PRD_INT (1 << 19) +#define FUSB300_IGR0_EP2_PRD_INT (1 << 18) +#define FUSB300_IGR0_EP1_PRD_INT (1 << 17) +#define FUSB300_IGR0_EPn_PRD_INT(n) (1 << (n + 16)) + +#define FUSB300_IGR0_EP15_FIFO_INT (1 << 15) +#define FUSB300_IGR0_EP14_FIFO_INT (1 << 14) +#define FUSB300_IGR0_EP13_FIFO_INT (1 << 13) +#define FUSB300_IGR0_EP12_FIFO_INT (1 << 12) +#define FUSB300_IGR0_EP11_FIFO_INT (1 << 11) +#define FUSB300_IGR0_EP10_FIFO_INT (1 << 10) +#define FUSB300_IGR0_EP9_FIFO_INT (1 << 9) +#define FUSB300_IGR0_EP8_FIFO_INT (1 << 8) +#define FUSB300_IGR0_EP7_FIFO_INT (1 << 7) +#define FUSB300_IGR0_EP6_FIFO_INT (1 << 6) +#define FUSB300_IGR0_EP5_FIFO_INT (1 << 5) +#define FUSB300_IGR0_EP4_FIFO_INT (1 << 4) +#define FUSB300_IGR0_EP3_FIFO_INT (1 << 3) +#define FUSB300_IGR0_EP2_FIFO_INT (1 << 2) +#define FUSB300_IGR0_EP1_FIFO_INT (1 << 1) +#define FUSB300_IGR0_EPn_FIFO_INT(n) (1 << n) + +/* + * *Interrupt Group 1 Register (offset = 404H) + * */ +#define FUSB300_IGR1_INTGRP5 (1 << 31) +#define FUSB300_IGR1_VBUS_CHG_INT (1 << 30) +#define FUSB300_IGR1_SYNF1_EMPTY_INT (1 << 29) +#define FUSB300_IGR1_SYNF0_EMPTY_INT (1 << 28) +#define FUSB300_IGR1_U3_EXIT_FAIL_INT (1 << 27) +#define FUSB300_IGR1_U2_EXIT_FAIL_INT (1 << 26) +#define FUSB300_IGR1_U1_EXIT_FAIL_INT (1 << 25) +#define FUSB300_IGR1_U2_ENTRY_FAIL_INT (1 << 24) +#define FUSB300_IGR1_U1_ENTRY_FAIL_INT (1 << 23) +#define FUSB300_IGR1_U3_EXIT_INT (1 << 22) +#define FUSB300_IGR1_U2_EXIT_INT (1 << 21) +#define FUSB300_IGR1_U1_EXIT_INT (1 << 20) +#define FUSB300_IGR1_U3_ENTRY_INT (1 << 19) +#define FUSB300_IGR1_U2_ENTRY_INT (1 << 18) +#define FUSB300_IGR1_U1_ENTRY_INT (1 << 17) +#define FUSB300_IGR1_HOT_RST_INT (1 << 16) +#define FUSB300_IGR1_WARM_RST_INT (1 << 15) +#define FUSB300_IGR1_RESM_INT (1 << 14) +#define FUSB300_IGR1_SUSP_INT (1 << 13) +#define FUSB300_IGR1_HS_LPM_INT (1 << 12) +#define FUSB300_IGR1_USBRST_INT (1 << 11) +#define FUSB300_IGR1_DEV_MODE_CHG_INT (1 << 9) +#define FUSB300_IGR1_CX_COMABT_INT (1 << 8) +#define FUSB300_IGR1_CX_COMFAIL_INT (1 << 7) +#define FUSB300_IGR1_CX_CMDEND_INT (1 << 6) +#define FUSB300_IGR1_CX_OUT_INT (1 << 5) +#define FUSB300_IGR1_CX_IN_INT (1 << 4) +#define FUSB300_IGR1_CX_SETUP_INT (1 << 3) +#define FUSB300_IGR1_INTGRP4 (1 << 2) +#define FUSB300_IGR1_INTGRP3 (1 << 1) +#define FUSB300_IGR1_INTGRP2 (1 << 0) + +/* + * *Interrupt Group 2 Register (offset = 408H) + * */ +#define FUSB300_IGR2_EP6_STR_ACCEPT_INT (1 << 29) +#define FUSB300_IGR2_EP6_STR_RESUME_INT (1 << 28) +#define FUSB300_IGR2_EP6_STR_REQ_INT (1 << 27) +#define FUSB300_IGR2_EP6_STR_NOTRDY_INT (1 << 26) +#define FUSB300_IGR2_EP6_STR_PRIME_INT (1 << 25) +#define FUSB300_IGR2_EP5_STR_ACCEPT_INT (1 << 24) +#define FUSB300_IGR2_EP5_STR_RESUME_INT (1 << 23) +#define FUSB300_IGR2_EP5_STR_REQ_INT (1 << 22) +#define FUSB300_IGR2_EP5_STR_NOTRDY_INT (1 << 21) +#define FUSB300_IGR2_EP5_STR_PRIME_INT (1 << 20) +#define FUSB300_IGR2_EP4_STR_ACCEPT_INT (1 << 19) +#define FUSB300_IGR2_EP4_STR_RESUME_INT (1 << 18) +#define FUSB300_IGR2_EP4_STR_REQ_INT (1 << 17) +#define FUSB300_IGR2_EP4_STR_NOTRDY_INT (1 << 16) +#define FUSB300_IGR2_EP4_STR_PRIME_INT (1 << 15) +#define FUSB300_IGR2_EP3_STR_ACCEPT_INT (1 << 14) +#define FUSB300_IGR2_EP3_STR_RESUME_INT (1 << 13) +#define FUSB300_IGR2_EP3_STR_REQ_INT (1 << 12) +#define FUSB300_IGR2_EP3_STR_NOTRDY_INT (1 << 11) +#define FUSB300_IGR2_EP3_STR_PRIME_INT (1 << 10) +#define FUSB300_IGR2_EP2_STR_ACCEPT_INT (1 << 9) +#define FUSB300_IGR2_EP2_STR_RESUME_INT (1 << 8) +#define FUSB300_IGR2_EP2_STR_REQ_INT (1 << 7) +#define FUSB300_IGR2_EP2_STR_NOTRDY_INT (1 << 6) +#define FUSB300_IGR2_EP2_STR_PRIME_INT (1 << 5) +#define FUSB300_IGR2_EP1_STR_ACCEPT_INT (1 << 4) +#define FUSB300_IGR2_EP1_STR_RESUME_INT (1 << 3) +#define FUSB300_IGR2_EP1_STR_REQ_INT (1 << 2) +#define FUSB300_IGR2_EP1_STR_NOTRDY_INT (1 << 1) +#define FUSB300_IGR2_EP1_STR_PRIME_INT (1 << 0) + +#define FUSB300_IGR2_EP_STR_ACCEPT_INT(n) (1 << (5 * n - 1)) +#define FUSB300_IGR2_EP_STR_RESUME_INT(n) (1 << (5 * n - 2)) +#define FUSB300_IGR2_EP_STR_REQ_INT(n) (1 << (5 * n - 3)) +#define FUSB300_IGR2_EP_STR_NOTRDY_INT(n) (1 << (5 * n - 4)) +#define FUSB300_IGR2_EP_STR_PRIME_INT(n) (1 << (5 * n - 5)) + +/* + * *Interrupt Group 3 Register (offset = 40CH) + * */ +#define FUSB300_IGR3_EP12_STR_ACCEPT_INT (1 << 29) +#define FUSB300_IGR3_EP12_STR_RESUME_INT (1 << 28) +#define FUSB300_IGR3_EP12_STR_REQ_INT (1 << 27) +#define FUSB300_IGR3_EP12_STR_NOTRDY_INT (1 << 26) +#define FUSB300_IGR3_EP12_STR_PRIME_INT (1 << 25) +#define FUSB300_IGR3_EP11_STR_ACCEPT_INT (1 << 24) +#define FUSB300_IGR3_EP11_STR_RESUME_INT (1 << 23) +#define FUSB300_IGR3_EP11_STR_REQ_INT (1 << 22) +#define FUSB300_IGR3_EP11_STR_NOTRDY_INT (1 << 21) +#define FUSB300_IGR3_EP11_STR_PRIME_INT (1 << 20) +#define FUSB300_IGR3_EP10_STR_ACCEPT_INT (1 << 19) +#define FUSB300_IGR3_EP10_STR_RESUME_INT (1 << 18) +#define FUSB300_IGR3_EP10_STR_REQ_INT (1 << 17) +#define FUSB300_IGR3_EP10_STR_NOTRDY_INT (1 << 16) +#define FUSB300_IGR3_EP10_STR_PRIME_INT (1 << 15) +#define FUSB300_IGR3_EP9_STR_ACCEPT_INT (1 << 14) +#define FUSB300_IGR3_EP9_STR_RESUME_INT (1 << 13) +#define FUSB300_IGR3_EP9_STR_REQ_INT (1 << 12) +#define FUSB300_IGR3_EP9_STR_NOTRDY_INT (1 << 11) +#define FUSB300_IGR3_EP9_STR_PRIME_INT (1 << 10) +#define FUSB300_IGR3_EP8_STR_ACCEPT_INT (1 << 9) +#define FUSB300_IGR3_EP8_STR_RESUME_INT (1 << 8) +#define FUSB300_IGR3_EP8_STR_REQ_INT (1 << 7) +#define FUSB300_IGR3_EP8_STR_NOTRDY_INT (1 << 6) +#define FUSB300_IGR3_EP8_STR_PRIME_INT (1 << 5) +#define FUSB300_IGR3_EP7_STR_ACCEPT_INT (1 << 4) +#define FUSB300_IGR3_EP7_STR_RESUME_INT (1 << 3) +#define FUSB300_IGR3_EP7_STR_REQ_INT (1 << 2) +#define FUSB300_IGR3_EP7_STR_NOTRDY_INT (1 << 1) +#define FUSB300_IGR3_EP7_STR_PRIME_INT (1 << 0) + +#define FUSB300_IGR3_EP_STR_ACCEPT_INT(n) (1 << (5 * (n - 6) - 1)) +#define FUSB300_IGR3_EP_STR_RESUME_INT(n) (1 << (5 * (n - 6) - 2)) +#define FUSB300_IGR3_EP_STR_REQ_INT(n) (1 << (5 * (n - 6) - 3)) +#define FUSB300_IGR3_EP_STR_NOTRDY_INT(n) (1 << (5 * (n - 6) - 4)) +#define FUSB300_IGR3_EP_STR_PRIME_INT(n) (1 << (5 * (n - 6) - 5)) + +/* + * *Interrupt Group 4 Register (offset = 410H) + * */ +#define FUSB300_IGR4_EP15_RX0_INT (1 << 31) +#define FUSB300_IGR4_EP14_RX0_INT (1 << 30) +#define FUSB300_IGR4_EP13_RX0_INT (1 << 29) +#define FUSB300_IGR4_EP12_RX0_INT (1 << 28) +#define FUSB300_IGR4_EP11_RX0_INT (1 << 27) +#define FUSB300_IGR4_EP10_RX0_INT (1 << 26) +#define FUSB300_IGR4_EP9_RX0_INT (1 << 25) +#define FUSB300_IGR4_EP8_RX0_INT (1 << 24) +#define FUSB300_IGR4_EP7_RX0_INT (1 << 23) +#define FUSB300_IGR4_EP6_RX0_INT (1 << 22) +#define FUSB300_IGR4_EP5_RX0_INT (1 << 21) +#define FUSB300_IGR4_EP4_RX0_INT (1 << 20) +#define FUSB300_IGR4_EP3_RX0_INT (1 << 19) +#define FUSB300_IGR4_EP2_RX0_INT (1 << 18) +#define FUSB300_IGR4_EP1_RX0_INT (1 << 17) +#define FUSB300_IGR4_EP_RX0_INT(x) (1 << (x + 16)) +#define FUSB300_IGR4_EP15_STR_ACCEPT_INT (1 << 14) +#define FUSB300_IGR4_EP15_STR_RESUME_INT (1 << 13) +#define FUSB300_IGR4_EP15_STR_REQ_INT (1 << 12) +#define FUSB300_IGR4_EP15_STR_NOTRDY_INT (1 << 11) +#define FUSB300_IGR4_EP15_STR_PRIME_INT (1 << 10) +#define FUSB300_IGR4_EP14_STR_ACCEPT_INT (1 << 9) +#define FUSB300_IGR4_EP14_STR_RESUME_INT (1 << 8) +#define FUSB300_IGR4_EP14_STR_REQ_INT (1 << 7) +#define FUSB300_IGR4_EP14_STR_NOTRDY_INT (1 << 6) +#define FUSB300_IGR4_EP14_STR_PRIME_INT (1 << 5) +#define FUSB300_IGR4_EP13_STR_ACCEPT_INT (1 << 4) +#define FUSB300_IGR4_EP13_STR_RESUME_INT (1 << 3) +#define FUSB300_IGR4_EP13_STR_REQ_INT (1 << 2) +#define FUSB300_IGR4_EP13_STR_NOTRDY_INT (1 << 1) +#define FUSB300_IGR4_EP13_STR_PRIME_INT (1 << 0) + +#define FUSB300_IGR4_EP_STR_ACCEPT_INT(n) (1 << (5 * (n - 12) - 1)) +#define FUSB300_IGR4_EP_STR_RESUME_INT(n) (1 << (5 * (n - 12) - 2)) +#define FUSB300_IGR4_EP_STR_REQ_INT(n) (1 << (5 * (n - 12) - 3)) +#define FUSB300_IGR4_EP_STR_NOTRDY_INT(n) (1 << (5 * (n - 12) - 4)) +#define FUSB300_IGR4_EP_STR_PRIME_INT(n) (1 << (5 * (n - 12) - 5)) + +/* + * *Interrupt Group 5 Register (offset = 414H) + * */ +#define FUSB300_IGR5_EP_STL_INT(n) (1 << n) + +/* + * *Interrupt Enable Group 0 Register (offset = 420H) + * */ +#define FUSB300_IGER0_EEP15_PRD_INT (1 << 31) +#define FUSB300_IGER0_EEP14_PRD_INT (1 << 30) +#define FUSB300_IGER0_EEP13_PRD_INT (1 << 29) +#define FUSB300_IGER0_EEP12_PRD_INT (1 << 28) +#define FUSB300_IGER0_EEP11_PRD_INT (1 << 27) +#define FUSB300_IGER0_EEP10_PRD_INT (1 << 26) +#define FUSB300_IGER0_EEP9_PRD_INT (1 << 25) +#define FUSB300_IGER0_EP8_PRD_INT (1 << 24) +#define FUSB300_IGER0_EEP7_PRD_INT (1 << 23) +#define FUSB300_IGER0_EEP6_PRD_INT (1 << 22) +#define FUSB300_IGER0_EEP5_PRD_INT (1 << 21) +#define FUSB300_IGER0_EEP4_PRD_INT (1 << 20) +#define FUSB300_IGER0_EEP3_PRD_INT (1 << 19) +#define FUSB300_IGER0_EEP2_PRD_INT (1 << 18) +#define FUSB300_IGER0_EEP1_PRD_INT (1 << 17) +#define FUSB300_IGER0_EEPn_PRD_INT(n) (1 << (n + 16)) + +#define FUSB300_IGER0_EEP15_FIFO_INT (1 << 15) +#define FUSB300_IGER0_EEP14_FIFO_INT (1 << 14) +#define FUSB300_IGER0_EEP13_FIFO_INT (1 << 13) +#define FUSB300_IGER0_EEP12_FIFO_INT (1 << 12) +#define FUSB300_IGER0_EEP11_FIFO_INT (1 << 11) +#define FUSB300_IGER0_EEP10_FIFO_INT (1 << 10) +#define FUSB300_IGER0_EEP9_FIFO_INT (1 << 9) +#define FUSB300_IGER0_EEP8_FIFO_INT (1 << 8) +#define FUSB300_IGER0_EEP7_FIFO_INT (1 << 7) +#define FUSB300_IGER0_EEP6_FIFO_INT (1 << 6) +#define FUSB300_IGER0_EEP5_FIFO_INT (1 << 5) +#define FUSB300_IGER0_EEP4_FIFO_INT (1 << 4) +#define FUSB300_IGER0_EEP3_FIFO_INT (1 << 3) +#define FUSB300_IGER0_EEP2_FIFO_INT (1 << 2) +#define FUSB300_IGER0_EEP1_FIFO_INT (1 << 1) +#define FUSB300_IGER0_EEPn_FIFO_INT(n) (1 << n) + +/* + * *Interrupt Enable Group 1 Register (offset = 424H) + * */ +#define FUSB300_IGER1_EINT_GRP5 (1 << 31) +#define FUSB300_IGER1_VBUS_CHG_INT (1 << 30) +#define FUSB300_IGER1_SYNF1_EMPTY_INT (1 << 29) +#define FUSB300_IGER1_SYNF0_EMPTY_INT (1 << 28) +#define FUSB300_IGER1_U3_EXIT_FAIL_INT (1 << 27) +#define FUSB300_IGER1_U2_EXIT_FAIL_INT (1 << 26) +#define FUSB300_IGER1_U1_EXIT_FAIL_INT (1 << 25) +#define FUSB300_IGER1_U2_ENTRY_FAIL_INT (1 << 24) +#define FUSB300_IGER1_U1_ENTRY_FAIL_INT (1 << 23) +#define FUSB300_IGER1_U3_EXIT_INT (1 << 22) +#define FUSB300_IGER1_U2_EXIT_INT (1 << 21) +#define FUSB300_IGER1_U1_EXIT_INT (1 << 20) +#define FUSB300_IGER1_U3_ENTRY_INT (1 << 19) +#define FUSB300_IGER1_U2_ENTRY_INT (1 << 18) +#define FUSB300_IGER1_U1_ENTRY_INT (1 << 17) +#define FUSB300_IGER1_HOT_RST_INT (1 << 16) +#define FUSB300_IGER1_WARM_RST_INT (1 << 15) +#define FUSB300_IGER1_RESM_INT (1 << 14) +#define FUSB300_IGER1_SUSP_INT (1 << 13) +#define FUSB300_IGER1_LPM_INT (1 << 12) +#define FUSB300_IGER1_HS_RST_INT (1 << 11) +#define FUSB300_IGER1_EDEV_MODE_CHG_INT (1 << 9) +#define FUSB300_IGER1_CX_COMABT_INT (1 << 8) +#define FUSB300_IGER1_CX_COMFAIL_INT (1 << 7) +#define FUSB300_IGER1_CX_CMDEND_INT (1 << 6) +#define FUSB300_IGER1_CX_OUT_INT (1 << 5) +#define FUSB300_IGER1_CX_IN_INT (1 << 4) +#define FUSB300_IGER1_CX_SETUP_INT (1 << 3) +#define FUSB300_IGER1_INTGRP4 (1 << 2) +#define FUSB300_IGER1_INTGRP3 (1 << 1) +#define FUSB300_IGER1_INTGRP2 (1 << 0) + +/* + * *Interrupt Enable Group 2 Register (offset = 428H) + * */ +#define FUSB300_IGER2_EEP_STR_ACCEPT_INT(n) (1 << (5 * n - 1)) +#define FUSB300_IGER2_EEP_STR_RESUME_INT(n) (1 << (5 * n - 2)) +#define FUSB300_IGER2_EEP_STR_REQ_INT(n) (1 << (5 * n - 3)) +#define FUSB300_IGER2_EEP_STR_NOTRDY_INT(n) (1 << (5 * n - 4)) +#define FUSB300_IGER2_EEP_STR_PRIME_INT(n) (1 << (5 * n - 5)) + +/* + * *Interrupt Enable Group 3 Register (offset = 42CH) + * */ + +#define FUSB300_IGER3_EEP_STR_ACCEPT_INT(n) (1 << (5 * (n - 6) - 1)) +#define FUSB300_IGER3_EEP_STR_RESUME_INT(n) (1 << (5 * (n - 6) - 2)) +#define FUSB300_IGER3_EEP_STR_REQ_INT(n) (1 << (5 * (n - 6) - 3)) +#define FUSB300_IGER3_EEP_STR_NOTRDY_INT(n) (1 << (5 * (n - 6) - 4)) +#define FUSB300_IGER3_EEP_STR_PRIME_INT(n) (1 << (5 * (n - 6) - 5)) + +/* + * *Interrupt Enable Group 4 Register (offset = 430H) + * */ + +#define FUSB300_IGER4_EEP_RX0_INT(n) (1 << (n + 16)) +#define FUSB300_IGER4_EEP_STR_ACCEPT_INT(n) (1 << (5 * (n - 6) - 1)) +#define FUSB300_IGER4_EEP_STR_RESUME_INT(n) (1 << (5 * (n - 6) - 2)) +#define FUSB300_IGER4_EEP_STR_REQ_INT(n) (1 << (5 * (n - 6) - 3)) +#define FUSB300_IGER4_EEP_STR_NOTRDY_INT(n) (1 << (5 * (n - 6) - 4)) +#define FUSB300_IGER4_EEP_STR_PRIME_INT(n) (1 << (5 * (n - 6) - 5)) + +/* EP PRD Ready (EP_PRD_RDY, offset = 504H) */ + +#define FUSB300_EPPRDR_EP15_PRD_RDY (1 << 15) +#define FUSB300_EPPRDR_EP14_PRD_RDY (1 << 14) +#define FUSB300_EPPRDR_EP13_PRD_RDY (1 << 13) +#define FUSB300_EPPRDR_EP12_PRD_RDY (1 << 12) +#define FUSB300_EPPRDR_EP11_PRD_RDY (1 << 11) +#define FUSB300_EPPRDR_EP10_PRD_RDY (1 << 10) +#define FUSB300_EPPRDR_EP9_PRD_RDY (1 << 9) +#define FUSB300_EPPRDR_EP8_PRD_RDY (1 << 8) +#define FUSB300_EPPRDR_EP7_PRD_RDY (1 << 7) +#define FUSB300_EPPRDR_EP6_PRD_RDY (1 << 6) +#define FUSB300_EPPRDR_EP5_PRD_RDY (1 << 5) +#define FUSB300_EPPRDR_EP4_PRD_RDY (1 << 4) +#define FUSB300_EPPRDR_EP3_PRD_RDY (1 << 3) +#define FUSB300_EPPRDR_EP2_PRD_RDY (1 << 2) +#define FUSB300_EPPRDR_EP1_PRD_RDY (1 << 1) +#define FUSB300_EPPRDR_EP_PRD_RDY(n) (1 << n) + +/* AHB Bus Control Register (offset = 514H) */ +#define FUSB300_AHBBCR_S1_SPLIT_ON (1 << 17) +#define FUSB300_AHBBCR_S0_SPLIT_ON (1 << 16) +#define FUSB300_AHBBCR_S1_1entry (0 << 12) +#define FUSB300_AHBBCR_S1_4entry (3 << 12) +#define FUSB300_AHBBCR_S1_8entry (5 << 12) +#define FUSB300_AHBBCR_S1_16entry (7 << 12) +#define FUSB300_AHBBCR_S0_1entry (0 << 8) +#define FUSB300_AHBBCR_S0_4entry (3 << 8) +#define FUSB300_AHBBCR_S0_8entry (5 << 8) +#define FUSB300_AHBBCR_S0_16entry (7 << 8) +#define FUSB300_AHBBCR_M1_BURST_SINGLE (0 << 4) +#define FUSB300_AHBBCR_M1_BURST_INCR (1 << 4) +#define FUSB300_AHBBCR_M1_BURST_INCR4 (3 << 4) +#define FUSB300_AHBBCR_M1_BURST_INCR8 (5 << 4) +#define FUSB300_AHBBCR_M1_BURST_INCR16 (7 << 4) +#define FUSB300_AHBBCR_M0_BURST_SINGLE 0 +#define FUSB300_AHBBCR_M0_BURST_INCR 1 +#define FUSB300_AHBBCR_M0_BURST_INCR4 3 +#define FUSB300_AHBBCR_M0_BURST_INCR8 5 +#define FUSB300_AHBBCR_M0_BURST_INCR16 7 +#define FUSB300_IGER5_EEP_STL_INT(n) (1 << n) + +/* WORD 0 Data Structure of PRD Table */ +#define FUSB300_EPPRD0_M (1 << 30) +#define FUSB300_EPPRD0_O (1 << 29) +/* The finished prd */ +#define FUSB300_EPPRD0_F (1 << 28) +#define FUSB300_EPPRD0_I (1 << 27) +#define FUSB300_EPPRD0_A (1 << 26) +/* To decide HW point to first prd at next time */ +#define FUSB300_EPPRD0_L (1 << 25) +#define FUSB300_EPPRD0_H (1 << 24) +#define FUSB300_EPPRD0_BTC(n) (n & 0xFFFFFF) + +/*----------------------------------------------------------------------*/ +#define FUSB300_MAX_NUM_EP 16 + +#define FUSB300_FIFO_ENTRY_NUM 8 +#define FUSB300_MAX_FIFO_ENTRY 8 + +#define SS_CTL_MAX_PACKET_SIZE 0x200 +#define SS_BULK_MAX_PACKET_SIZE 0x400 +#define SS_INT_MAX_PACKET_SIZE 0x400 +#define SS_ISO_MAX_PACKET_SIZE 0x400 + +#define HS_BULK_MAX_PACKET_SIZE 0x200 +#define HS_CTL_MAX_PACKET_SIZE 0x40 +#define HS_INT_MAX_PACKET_SIZE 0x400 +#define HS_ISO_MAX_PACKET_SIZE 0x400 + +struct fusb300_ep_info { + u8 epnum; + u8 type; + u8 interval; + u8 dir_in; + u16 maxpacket; + u16 addrofs; + u16 bw_num; +}; + +struct fusb300_request { + + struct usb_request req; + struct list_head queue; +}; + + +struct fusb300_ep { + struct usb_ep ep; + struct fusb300 *fusb300; + + struct list_head queue; + unsigned stall:1; + unsigned wedged:1; + unsigned use_dma:1; + + unsigned char epnum; + unsigned char type; + const struct usb_endpoint_descriptor *desc; +}; + +struct fusb300 { + spinlock_t lock; + void __iomem *reg; + + unsigned long irq_trigger; + + struct usb_gadget gadget; + struct usb_gadget_driver *driver; + + struct fusb300_ep *ep[FUSB300_MAX_NUM_EP]; + + struct usb_request *ep0_req; /* for internal request */ + __le16 ep0_data; + u32 ep0_length; /* for internal request */ + u8 ep0_dir; /* 0/0x80 out/in */ + + u8 fifo_entry_num; /* next start fifo entry */ + u32 addrofs; /* next fifo address offset */ + u8 reenum; /* if re-enumeration */ +}; + +#endif -- cgit v1.2.3 From 5efb94ee144c1c7290652495a0f4f29cae845a62 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Sun, 23 Jan 2011 18:58:29 +1100 Subject: hwrng: pixocell - add support for picoxcell TRNG This driver adds support for the True Random Number Generator in the Picochip PC3X3 and later devices. Signed-off-by: Jamie Iles Acked-by: Matt Mackall Signed-off-by: Herbert Xu --- drivers/char/hw_random/Kconfig | 12 ++ drivers/char/hw_random/Makefile | 1 + drivers/char/hw_random/picoxcell-rng.c | 208 +++++++++++++++++++++++++++++++++ 3 files changed, 221 insertions(+) create mode 100644 drivers/char/hw_random/picoxcell-rng.c (limited to 'drivers') diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index d31483c54883..beecd1cf9b99 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -198,3 +198,15 @@ config HW_RANDOM_NOMADIK module will be called nomadik-rng. If unsure, say Y. + +config HW_RANDOM_PICOXCELL + tristate "Picochip picoXcell true random number generator support" + depends on HW_RANDOM && ARCH_PICOXCELL && PICOXCELL_PC3X3 + ---help--- + This driver provides kernel-side support for the Random Number + Generator hardware found on Picochip PC3x3 and later devices. + + To compile this driver as a module, choose M here: the + module will be called picoxcell-rng. + + If unsure, say Y. diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index 4273308aa1e3..3db4eb8b19c0 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile @@ -19,3 +19,4 @@ obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o +obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o diff --git a/drivers/char/hw_random/picoxcell-rng.c b/drivers/char/hw_random/picoxcell-rng.c new file mode 100644 index 000000000000..990d55a5e3e8 --- /dev/null +++ b/drivers/char/hw_random/picoxcell-rng.c @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2010-2011 Picochip Ltd., Jamie Iles + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * All enquiries to support@picochip.com + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define DATA_REG_OFFSET 0x0200 +#define CSR_REG_OFFSET 0x0278 +#define CSR_OUT_EMPTY_MASK (1 << 24) +#define CSR_FAULT_MASK (1 << 1) +#define TRNG_BLOCK_RESET_MASK (1 << 0) +#define TAI_REG_OFFSET 0x0380 + +/* + * The maximum amount of time in microseconds to spend waiting for data if the + * core wants us to wait. The TRNG should generate 32 bits every 320ns so a + * timeout of 20us seems reasonable. The TRNG does builtin tests of the data + * for randomness so we can't always assume there is data present. + */ +#define PICO_TRNG_TIMEOUT 20 + +static void __iomem *rng_base; +static struct clk *rng_clk; +struct device *rng_dev; + +static inline u32 picoxcell_trng_read_csr(void) +{ + return __raw_readl(rng_base + CSR_REG_OFFSET); +} + +static inline bool picoxcell_trng_is_empty(void) +{ + return picoxcell_trng_read_csr() & CSR_OUT_EMPTY_MASK; +} + +/* + * Take the random number generator out of reset and make sure the interrupts + * are masked. We shouldn't need to get large amounts of random bytes so just + * poll the status register. The hardware generates 32 bits every 320ns so we + * shouldn't have to wait long enough to warrant waiting for an IRQ. + */ +static void picoxcell_trng_start(void) +{ + __raw_writel(0, rng_base + TAI_REG_OFFSET); + __raw_writel(0, rng_base + CSR_REG_OFFSET); +} + +static void picoxcell_trng_reset(void) +{ + __raw_writel(TRNG_BLOCK_RESET_MASK, rng_base + CSR_REG_OFFSET); + __raw_writel(TRNG_BLOCK_RESET_MASK, rng_base + TAI_REG_OFFSET); + picoxcell_trng_start(); +} + +/* + * Get some random data from the random number generator. The hw_random core + * layer provides us with locking. + */ +static int picoxcell_trng_read(struct hwrng *rng, void *buf, size_t max, + bool wait) +{ + int i; + + /* Wait for some data to become available. */ + for (i = 0; i < PICO_TRNG_TIMEOUT && picoxcell_trng_is_empty(); ++i) { + if (!wait) + return 0; + + udelay(1); + } + + if (picoxcell_trng_read_csr() & CSR_FAULT_MASK) { + dev_err(rng_dev, "fault detected, resetting TRNG\n"); + picoxcell_trng_reset(); + return -EIO; + } + + if (i == PICO_TRNG_TIMEOUT) + return 0; + + *(u32 *)buf = __raw_readl(rng_base + DATA_REG_OFFSET); + return sizeof(u32); +} + +static struct hwrng picoxcell_trng = { + .name = "picoxcell", + .read = picoxcell_trng_read, +}; + +static int picoxcell_trng_probe(struct platform_device *pdev) +{ + int ret; + struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + if (!mem) { + dev_warn(&pdev->dev, "no memory resource\n"); + return -ENOMEM; + } + + if (!devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem), + "picoxcell_trng")) { + dev_warn(&pdev->dev, "unable to request io mem\n"); + return -EBUSY; + } + + rng_base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); + if (!rng_base) { + dev_warn(&pdev->dev, "unable to remap io mem\n"); + return -ENOMEM; + } + + rng_clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(rng_clk)) { + dev_warn(&pdev->dev, "no clk\n"); + return PTR_ERR(rng_clk); + } + + ret = clk_enable(rng_clk); + if (ret) { + dev_warn(&pdev->dev, "unable to enable clk\n"); + goto err_enable; + } + + picoxcell_trng_start(); + ret = hwrng_register(&picoxcell_trng); + if (ret) + goto err_register; + + rng_dev = &pdev->dev; + dev_info(&pdev->dev, "pixoxcell random number generator active\n"); + + return 0; + +err_register: + clk_disable(rng_clk); +err_enable: + clk_put(rng_clk); + + return ret; +} + +static int __devexit picoxcell_trng_remove(struct platform_device *pdev) +{ + hwrng_unregister(&picoxcell_trng); + clk_disable(rng_clk); + clk_put(rng_clk); + + return 0; +} + +#ifdef CONFIG_PM +static int picoxcell_trng_suspend(struct device *dev) +{ + clk_disable(rng_clk); + + return 0; +} + +static int picoxcell_trng_resume(struct device *dev) +{ + return clk_enable(rng_clk); +} + +static const struct dev_pm_ops picoxcell_trng_pm_ops = { + .suspend = picoxcell_trng_suspend, + .resume = picoxcell_trng_resume, +}; +#endif /* CONFIG_PM */ + +static struct platform_driver picoxcell_trng_driver = { + .probe = picoxcell_trng_probe, + .remove = __devexit_p(picoxcell_trng_remove), + .driver = { + .name = "picoxcell-trng", + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &picoxcell_trng_pm_ops, +#endif /* CONFIG_PM */ + }, +}; + +static int __init picoxcell_trng_init(void) +{ + return platform_driver_register(&picoxcell_trng_driver); +} +module_init(picoxcell_trng_init); + +static void __exit picoxcell_trng_exit(void) +{ + platform_driver_unregister(&picoxcell_trng_driver); +} +module_exit(picoxcell_trng_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jamie Iles"); +MODULE_DESCRIPTION("Picochip picoXcell TRNG driver"); -- cgit v1.2.3 From 67fd4fcb78a7ced369a6bd8a131ec8c65ebd2bbb Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Fri, 7 Jan 2011 05:12:09 +0000 Subject: e1000e: convert to stats64 Based on the patch provided by Flavio Leitner Provides accurate stats at the time user reads them. v2: fixed whitespace/merging issues (by Jeff Kirsher) v3: fixed namespacing issues (by Bruce Allan) CC: Eric Dumazet Signed-off-by: Jeff Kirsher Tested-by: Jeff Pieper Signed-off-by: Flavio Leitner --- drivers/net/e1000e/e1000.h | 5 ++- drivers/net/e1000e/ethtool.c | 37 ++++++++++++----------- drivers/net/e1000e/netdev.c | 72 +++++++++++++++++++++++++++++++++++--------- 3 files changed, 80 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index e610e1369053..00bf595ebd67 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -364,6 +364,7 @@ struct e1000_adapter { /* structs defined in e1000_hw.h */ struct e1000_hw hw; + spinlock_t stats64_lock; struct e1000_hw_stats stats; struct e1000_phy_info phy_info; struct e1000_phy_stats phy_stats; @@ -494,7 +495,9 @@ extern int e1000e_setup_rx_resources(struct e1000_adapter *adapter); extern int e1000e_setup_tx_resources(struct e1000_adapter *adapter); extern void e1000e_free_rx_resources(struct e1000_adapter *adapter); extern void e1000e_free_tx_resources(struct e1000_adapter *adapter); -extern void e1000e_update_stats(struct e1000_adapter *adapter); +extern struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev, + struct rtnl_link_stats64 + *stats); extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter); extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter); extern void e1000e_get_hw_control(struct e1000_adapter *adapter); diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index fa08b6336cfb..dfa44de9cf0d 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -46,15 +46,15 @@ struct e1000_stats { }; #define E1000_STAT(str, m) { \ - .stat_string = str, \ - .type = E1000_STATS, \ - .sizeof_stat = sizeof(((struct e1000_adapter *)0)->m), \ - .stat_offset = offsetof(struct e1000_adapter, m) } + .stat_string = str, \ + .type = E1000_STATS, \ + .sizeof_stat = sizeof(((struct e1000_adapter *)0)->m), \ + .stat_offset = offsetof(struct e1000_adapter, m) } #define E1000_NETDEV_STAT(str, m) { \ - .stat_string = str, \ - .type = NETDEV_STATS, \ - .sizeof_stat = sizeof(((struct net_device *)0)->m), \ - .stat_offset = offsetof(struct net_device, m) } + .stat_string = str, \ + .type = NETDEV_STATS, \ + .sizeof_stat = sizeof(((struct rtnl_link_stats64 *)0)->m), \ + .stat_offset = offsetof(struct rtnl_link_stats64, m) } static const struct e1000_stats e1000_gstrings_stats[] = { E1000_STAT("rx_packets", stats.gprc), @@ -65,21 +65,21 @@ static const struct e1000_stats e1000_gstrings_stats[] = { E1000_STAT("tx_broadcast", stats.bptc), E1000_STAT("rx_multicast", stats.mprc), E1000_STAT("tx_multicast", stats.mptc), - E1000_NETDEV_STAT("rx_errors", stats.rx_errors), - E1000_NETDEV_STAT("tx_errors", stats.tx_errors), - E1000_NETDEV_STAT("tx_dropped", stats.tx_dropped), + E1000_NETDEV_STAT("rx_errors", rx_errors), + E1000_NETDEV_STAT("tx_errors", tx_errors), + E1000_NETDEV_STAT("tx_dropped", tx_dropped), E1000_STAT("multicast", stats.mprc), E1000_STAT("collisions", stats.colc), - E1000_NETDEV_STAT("rx_length_errors", stats.rx_length_errors), - E1000_NETDEV_STAT("rx_over_errors", stats.rx_over_errors), + E1000_NETDEV_STAT("rx_length_errors", rx_length_errors), + E1000_NETDEV_STAT("rx_over_errors", rx_over_errors), E1000_STAT("rx_crc_errors", stats.crcerrs), - E1000_NETDEV_STAT("rx_frame_errors", stats.rx_frame_errors), + E1000_NETDEV_STAT("rx_frame_errors", rx_frame_errors), E1000_STAT("rx_no_buffer_count", stats.rnbc), E1000_STAT("rx_missed_errors", stats.mpc), E1000_STAT("tx_aborted_errors", stats.ecol), E1000_STAT("tx_carrier_errors", stats.tncrs), - E1000_NETDEV_STAT("tx_fifo_errors", stats.tx_fifo_errors), - E1000_NETDEV_STAT("tx_heartbeat_errors", stats.tx_heartbeat_errors), + E1000_NETDEV_STAT("tx_fifo_errors", tx_fifo_errors), + E1000_NETDEV_STAT("tx_heartbeat_errors", tx_heartbeat_errors), E1000_STAT("tx_window_errors", stats.latecol), E1000_STAT("tx_abort_late_coll", stats.latecol), E1000_STAT("tx_deferred_ok", stats.dc), @@ -1982,14 +1982,15 @@ static void e1000_get_ethtool_stats(struct net_device *netdev, u64 *data) { struct e1000_adapter *adapter = netdev_priv(netdev); + struct rtnl_link_stats64 net_stats; int i; char *p = NULL; - e1000e_update_stats(adapter); + e1000e_get_stats64(netdev, &net_stats); for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { switch (e1000_gstrings_stats[i].type) { case NETDEV_STATS: - p = (char *) netdev + + p = (char *) &net_stats + e1000_gstrings_stats[i].stat_offset; break; case E1000_STATS: diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 1c18f26b0812..1c2f33dd0633 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -900,8 +900,6 @@ next_desc: adapter->total_rx_bytes += total_rx_bytes; adapter->total_rx_packets += total_rx_packets; - netdev->stats.rx_bytes += total_rx_bytes; - netdev->stats.rx_packets += total_rx_packets; return cleaned; } @@ -1057,8 +1055,6 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) } adapter->total_tx_bytes += total_tx_bytes; adapter->total_tx_packets += total_tx_packets; - netdev->stats.tx_bytes += total_tx_bytes; - netdev->stats.tx_packets += total_tx_packets; return count < tx_ring->count; } @@ -1245,8 +1241,6 @@ next_desc: adapter->total_rx_bytes += total_rx_bytes; adapter->total_rx_packets += total_rx_packets; - netdev->stats.rx_bytes += total_rx_bytes; - netdev->stats.rx_packets += total_rx_packets; return cleaned; } @@ -1426,8 +1420,6 @@ next_desc: adapter->total_rx_bytes += total_rx_bytes; adapter->total_rx_packets += total_rx_packets; - netdev->stats.rx_bytes += total_rx_bytes; - netdev->stats.rx_packets += total_rx_packets; return cleaned; } @@ -3338,6 +3330,8 @@ int e1000e_up(struct e1000_adapter *adapter) return 0; } +static void e1000e_update_stats(struct e1000_adapter *adapter); + void e1000e_down(struct e1000_adapter *adapter) { struct net_device *netdev = adapter->netdev; @@ -3372,6 +3366,11 @@ void e1000e_down(struct e1000_adapter *adapter) del_timer_sync(&adapter->phy_info_timer); netif_carrier_off(netdev); + + spin_lock(&adapter->stats64_lock); + e1000e_update_stats(adapter); + spin_unlock(&adapter->stats64_lock); + adapter->link_speed = 0; adapter->link_duplex = 0; @@ -3413,6 +3412,8 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter) adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; + spin_lock_init(&adapter->stats64_lock); + e1000e_set_interrupt_capability(adapter); if (e1000_alloc_queues(adapter)) @@ -3886,7 +3887,7 @@ release: * e1000e_update_stats - Update the board statistics counters * @adapter: board private structure **/ -void e1000e_update_stats(struct e1000_adapter *adapter) +static void e1000e_update_stats(struct e1000_adapter *adapter) { struct net_device *netdev = adapter->netdev; struct e1000_hw *hw = &adapter->hw; @@ -4285,7 +4286,9 @@ static void e1000_watchdog_task(struct work_struct *work) } link_up: + spin_lock(&adapter->stats64_lock); e1000e_update_stats(adapter); + spin_unlock(&adapter->stats64_lock); mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old; adapter->tpt_old = adapter->stats.tpt; @@ -4897,16 +4900,55 @@ static void e1000_reset_task(struct work_struct *work) } /** - * e1000_get_stats - Get System Network Statistics + * e1000_get_stats64 - Get System Network Statistics * @netdev: network interface device structure + * @stats: rtnl_link_stats64 pointer * * Returns the address of the device statistics structure. - * The statistics are actually updated from the timer callback. **/ -static struct net_device_stats *e1000_get_stats(struct net_device *netdev) +struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev, + struct rtnl_link_stats64 *stats) { - /* only return the current stats */ - return &netdev->stats; + struct e1000_adapter *adapter = netdev_priv(netdev); + + memset(stats, 0, sizeof(struct rtnl_link_stats64)); + spin_lock(&adapter->stats64_lock); + e1000e_update_stats(adapter); + /* Fill out the OS statistics structure */ + stats->rx_bytes = adapter->stats.gorc; + stats->rx_packets = adapter->stats.gprc; + stats->tx_bytes = adapter->stats.gotc; + stats->tx_packets = adapter->stats.gptc; + stats->multicast = adapter->stats.mprc; + stats->collisions = adapter->stats.colc; + + /* Rx Errors */ + + /* + * RLEC on some newer hardware can be incorrect so build + * our own version based on RUC and ROC + */ + stats->rx_errors = adapter->stats.rxerrc + + adapter->stats.crcerrs + adapter->stats.algnerrc + + adapter->stats.ruc + adapter->stats.roc + + adapter->stats.cexterr; + stats->rx_length_errors = adapter->stats.ruc + + adapter->stats.roc; + stats->rx_crc_errors = adapter->stats.crcerrs; + stats->rx_frame_errors = adapter->stats.algnerrc; + stats->rx_missed_errors = adapter->stats.mpc; + + /* Tx Errors */ + stats->tx_errors = adapter->stats.ecol + + adapter->stats.latecol; + stats->tx_aborted_errors = adapter->stats.ecol; + stats->tx_window_errors = adapter->stats.latecol; + stats->tx_carrier_errors = adapter->stats.tncrs; + + /* Tx Dropped needs to be maintained elsewhere */ + + spin_unlock(&adapter->stats64_lock); + return stats; } /** @@ -5675,7 +5717,7 @@ static const struct net_device_ops e1000e_netdev_ops = { .ndo_open = e1000_open, .ndo_stop = e1000_close, .ndo_start_xmit = e1000_xmit_frame, - .ndo_get_stats = e1000_get_stats, + .ndo_get_stats64 = e1000e_get_stats64, .ndo_set_multicast_list = e1000_set_multi, .ndo_set_mac_address = e1000_set_mac, .ndo_change_mtu = e1000_change_mtu, -- cgit v1.2.3 From 90da06692532541a38f9857972e1fd6b1cdfb45a Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Thu, 6 Jan 2011 07:02:53 +0000 Subject: e1000e: reduce scope of some variables, remove unnecessary ones Static analysis of the driver code found some variables for which the scope can be reduced, or remove the variable altogether. Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/ethtool.c | 4 +--- drivers/net/e1000e/ich8lan.c | 3 ++- drivers/net/e1000e/lib.c | 4 ++-- drivers/net/e1000e/netdev.c | 45 ++++++++++++++++++++++---------------------- drivers/net/e1000e/phy.c | 8 ++++---- 5 files changed, 31 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index dfa44de9cf0d..323fd12c306b 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -1255,7 +1255,6 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; u32 ctrl_reg = 0; - u32 stat_reg = 0; u16 phy_reg = 0; s32 ret_val = 0; @@ -1363,8 +1362,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) * Set the ILOS bit on the fiber Nic if half duplex link is * detected. */ - stat_reg = er32(STATUS); - if ((stat_reg & E1000_STATUS_FD) == 0) + if ((er32(STATUS) & E1000_STATUS_FD) == 0) ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU); } diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index fb46974cfec1..232b42b7f7ce 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -2104,7 +2104,6 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) { union ich8_hws_flash_status hsfsts; s32 ret_val = -E1000_ERR_NVM; - s32 i = 0; hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); @@ -2140,6 +2139,8 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) ew16flash(ICH_FLASH_HSFSTS, hsfsts.regval); ret_val = 0; } else { + s32 i = 0; + /* * Otherwise poll for sometime so the current * cycle has a chance to end before giving up. diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index 68aa1749bf66..96921de5df2e 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -1978,15 +1978,15 @@ static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; u32 eecd = er32(EECD); - u16 timeout = 0; u8 spi_stat_reg; if (nvm->type == e1000_nvm_eeprom_spi) { + u16 timeout = NVM_MAX_RETRY_SPI; + /* Clear SK and CS */ eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); ew32(EECD, eecd); udelay(1); - timeout = NVM_MAX_RETRY_SPI; /* * Read "Status Register" repeatedly until the LSB is cleared. diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 1c2f33dd0633..5b916b01805f 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -2720,7 +2720,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; u32 rctl, rfctl; - u32 psrctl = 0; u32 pages = 0; /* Workaround Si errata on 82579 - configure jumbo frame flow */ @@ -2819,6 +2818,8 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) adapter->rx_ps_pages = 0; if (adapter->rx_ps_pages) { + u32 psrctl = 0; + /* Configure extra packet-split registers */ rfctl = er32(RFCTL); rfctl |= E1000_RFCTL_EXTEN; @@ -3020,7 +3021,6 @@ static void e1000_set_multi(struct net_device *netdev) struct netdev_hw_addr *ha; u8 *mta_list; u32 rctl; - int i; /* Check for Promiscuous and All Multicast modes */ @@ -3043,12 +3043,13 @@ static void e1000_set_multi(struct net_device *netdev) ew32(RCTL, rctl); if (!netdev_mc_empty(netdev)) { + int i = 0; + mta_list = kmalloc(netdev_mc_count(netdev) * 6, GFP_ATOMIC); if (!mta_list) return; /* prepare a packed array of only addresses. */ - i = 0; netdev_for_each_mc_addr(ha, netdev) memcpy(mta_list + (i++ * ETH_ALEN), ha->addr, ETH_ALEN); @@ -3999,10 +4000,11 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; struct e1000_phy_regs *phy = &adapter->phy_regs; - int ret_val; if ((er32(STATUS) & E1000_STATUS_LU) && (adapter->hw.phy.media_type == e1000_media_type_copper)) { + int ret_val; + ret_val = e1e_rphy(hw, PHY_CONTROL, &phy->bmcr); ret_val |= e1e_rphy(hw, PHY_STATUS, &phy->bmsr); ret_val |= e1e_rphy(hw, PHY_AUTONEG_ADV, &phy->advertise); @@ -4148,7 +4150,6 @@ static void e1000_watchdog_task(struct work_struct *work) struct e1000_ring *tx_ring = adapter->tx_ring; struct e1000_hw *hw = &adapter->hw; u32 link, tctl; - int tx_pending = 0; link = e1000e_has_link(adapter); if ((netif_carrier_ok(netdev)) && link) { @@ -4302,21 +4303,18 @@ link_up: e1000e_update_adaptive(&adapter->hw); - if (!netif_carrier_ok(netdev)) { - tx_pending = (e1000_desc_unused(tx_ring) + 1 < - tx_ring->count); - if (tx_pending) { - /* - * We've lost link, so the controller stops DMA, - * but we've got queued Tx work that's never going - * to get done, so reset controller to flush Tx. - * (Do the reset outside of interrupt context). - */ - adapter->tx_timeout_count++; - schedule_work(&adapter->reset_task); - /* return immediately since reset is imminent */ - return; - } + if (!netif_carrier_ok(netdev) && + (e1000_desc_unused(tx_ring) + 1 < tx_ring->count)) { + /* + * We've lost link, so the controller stops DMA, + * but we've got queued Tx work that's never going + * to get done, so reset controller to flush Tx. + * (Do the reset outside of interrupt context). + */ + adapter->tx_timeout_count++; + schedule_work(&adapter->reset_task); + /* return immediately since reset is imminent */ + return; } /* Simple mode for Interrupt Throttle Rate (ITR) */ @@ -4387,13 +4385,13 @@ static int e1000_tso(struct e1000_adapter *adapter, u32 cmd_length = 0; u16 ipcse = 0, tucse, mss; u8 ipcss, ipcso, tucss, tucso, hdr_len; - int err; if (!skb_is_gso(skb)) return 0; if (skb_header_cloned(skb)) { - err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); + int err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); + if (err) return err; } @@ -5518,9 +5516,10 @@ static irqreturn_t e1000_intr_msix(int irq, void *data) { struct net_device *netdev = data; struct e1000_adapter *adapter = netdev_priv(netdev); - int vector, msix_irq; if (adapter->msix_entries) { + int vector, msix_irq; + vector = 0; msix_irq = adapter->msix_entries[vector].vector; disable_irq(msix_irq); diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 6bea051b134b..6ae31fcfb629 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c @@ -2409,9 +2409,7 @@ static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg) s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data) { s32 ret_val; - u32 page_select = 0; u32 page = offset >> IGP_PAGE_SHIFT; - u32 page_shift = 0; ret_val = hw->phy.ops.acquire(hw); if (ret_val) @@ -2427,6 +2425,8 @@ s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data) hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset); if (offset > MAX_PHY_MULTI_PAGE_REG) { + u32 page_shift, page_select; + /* * Page select is register 31 for phy address 1 and 22 for * phy address 2 and 3. Page select is shifted only for @@ -2468,9 +2468,7 @@ out: s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data) { s32 ret_val; - u32 page_select = 0; u32 page = offset >> IGP_PAGE_SHIFT; - u32 page_shift = 0; ret_val = hw->phy.ops.acquire(hw); if (ret_val) @@ -2486,6 +2484,8 @@ s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data) hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset); if (offset > MAX_PHY_MULTI_PAGE_REG) { + u32 page_shift, page_select; + /* * Page select is register 31 for phy address 1 and 22 for * phy address 2 and 3. Page select is shifted only for -- cgit v1.2.3 From 05b9321405efcca9ab217fb65c91915244ebf526 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 5 Jan 2011 07:10:38 +0000 Subject: e1000e: Use kmemdup rather than duplicating its implementation The semantic patch that makes this output is available in scripts/coccinelle/api/memdup.cocci. More information about semantic patching is available at http://coccinelle.lip6.fr/ Signed-off-by: Bruce Allan Tested-by: Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/ethtool.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 323fd12c306b..daa7fe4b9fdd 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -684,20 +684,13 @@ static int e1000_set_ringparam(struct net_device *netdev, rx_old = adapter->rx_ring; err = -ENOMEM; - tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); + tx_ring = kmemdup(tx_old, sizeof(struct e1000_ring), GFP_KERNEL); if (!tx_ring) goto err_alloc_tx; - /* - * use a memcpy to save any previously configured - * items like napi structs from having to be - * reinitialized - */ - memcpy(tx_ring, tx_old, sizeof(struct e1000_ring)); - rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); + rx_ring = kmemdup(rx_old, sizeof(struct e1000_ring), GFP_KERNEL); if (!rx_ring) goto err_alloc_rx; - memcpy(rx_ring, rx_old, sizeof(struct e1000_ring)); adapter->tx_ring = tx_ring; adapter->rx_ring = rx_ring; -- cgit v1.2.3 From 6493d24f77d8e4fe94913eb504ed9ffebb433402 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Fri, 14 Jan 2011 05:33:46 +0000 Subject: igb: Add support for i340 Quad Port Fiber Adapter This patch enables support for Intel i340 Quad Port Fiber Adapter. Signed-off-by: Carolyn Wyborny Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/igb/e1000_82575.c | 1 + drivers/net/igb/e1000_hw.h | 1 + drivers/net/igb/igb_main.c | 1 + 3 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 0a2368fa6bc6..c1552b6f4a68 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -129,6 +129,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) break; case E1000_DEV_ID_82580_COPPER: case E1000_DEV_ID_82580_FIBER: + case E1000_DEV_ID_82580_QUAD_FIBER: case E1000_DEV_ID_82580_SERDES: case E1000_DEV_ID_82580_SGMII: case E1000_DEV_ID_82580_COPPER_DUAL: diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h index e2638afb8cdc..281324e85980 100644 --- a/drivers/net/igb/e1000_hw.h +++ b/drivers/net/igb/e1000_hw.h @@ -54,6 +54,7 @@ struct e1000_hw; #define E1000_DEV_ID_82580_SERDES 0x1510 #define E1000_DEV_ID_82580_SGMII 0x1511 #define E1000_DEV_ID_82580_COPPER_DUAL 0x1516 +#define E1000_DEV_ID_82580_QUAD_FIBER 0x1527 #define E1000_DEV_ID_DH89XXCC_SGMII 0x0438 #define E1000_DEV_ID_DH89XXCC_SERDES 0x043A #define E1000_DEV_ID_DH89XXCC_BACKPLANE 0x043C diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 58c665b7513d..200cc3209672 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -68,6 +68,7 @@ static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = { { PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_SGMII), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_COPPER), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_FIBER), board_82575 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_QUAD_FIBER), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_SERDES), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_SGMII), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_COPPER_DUAL), board_82575 }, -- cgit v1.2.3 From 82e6923e1862428b755ec306b3dbccf926849314 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 21 Jan 2011 11:04:45 +0000 Subject: ARM: lh7a40x: remove unmaintained platform support lh7a40x has only been receiving updates for updates to generic code. The last involvement from the maintainer according to the git logs was in 2006. As such, it is a maintainence burden with no benefit. This gets rid of two defconfigs. Signed-off-by: Russell King --- Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen | 61 - Documentation/arm/Sharp-LH/CompactFlash | 32 - Documentation/arm/Sharp-LH/IOBarrier | 45 - Documentation/arm/Sharp-LH/KEV7A400 | 8 - Documentation/arm/Sharp-LH/LCDPanels | 59 - Documentation/arm/Sharp-LH/LPD7A400 | 15 - Documentation/arm/Sharp-LH/LPD7A40X | 16 - Documentation/arm/Sharp-LH/SDRAM | 51 - .../arm/Sharp-LH/VectoredInterruptController | 80 - arch/arm/Kconfig | 13 - arch/arm/Makefile | 1 - arch/arm/configs/lpd7a400_defconfig | 68 - arch/arm/configs/lpd7a404_defconfig | 81 - arch/arm/include/asm/setup.h | 6 +- arch/arm/mach-lh7a40x/Kconfig | 74 - arch/arm/mach-lh7a40x/Makefile | 17 - arch/arm/mach-lh7a40x/Makefile.boot | 4 - arch/arm/mach-lh7a40x/arch-kev7a400.c | 118 -- arch/arm/mach-lh7a40x/arch-lpd7a40x.c | 422 ---- arch/arm/mach-lh7a40x/clcd.c | 241 --- arch/arm/mach-lh7a40x/clocks.c | 108 - arch/arm/mach-lh7a40x/common.h | 17 - arch/arm/mach-lh7a40x/include/mach/clocks.h | 18 - arch/arm/mach-lh7a40x/include/mach/constants.h | 91 - arch/arm/mach-lh7a40x/include/mach/debug-macro.S | 37 - arch/arm/mach-lh7a40x/include/mach/dma.h | 86 - arch/arm/mach-lh7a40x/include/mach/entry-macro.S | 149 -- arch/arm/mach-lh7a40x/include/mach/hardware.h | 62 - arch/arm/mach-lh7a40x/include/mach/io.h | 20 - arch/arm/mach-lh7a40x/include/mach/irqs.h | 200 -- arch/arm/mach-lh7a40x/include/mach/memory.h | 28 - arch/arm/mach-lh7a40x/include/mach/registers.h | 224 -- arch/arm/mach-lh7a40x/include/mach/ssp.h | 70 - arch/arm/mach-lh7a40x/include/mach/system.h | 19 - arch/arm/mach-lh7a40x/include/mach/timex.h | 17 - arch/arm/mach-lh7a40x/include/mach/uncompress.h | 38 - arch/arm/mach-lh7a40x/include/mach/vmalloc.h | 10 - arch/arm/mach-lh7a40x/irq-kev7a400.c | 93 - arch/arm/mach-lh7a40x/irq-lh7a400.c | 91 - arch/arm/mach-lh7a40x/irq-lh7a404.c | 175 -- arch/arm/mach-lh7a40x/irq-lpd7a40x.c | 128 -- arch/arm/mach-lh7a40x/lcd-panel.h | 345 ---- arch/arm/mach-lh7a40x/ssp-cpld.c | 343 ---- arch/arm/mach-lh7a40x/time.c | 71 - drivers/net/smc91x.h | 62 - drivers/tty/serial/Kconfig | 23 - drivers/tty/serial/Makefile | 1 - drivers/tty/serial/serial_lh7a40x.c | 682 ------- drivers/usb/Kconfig | 1 - drivers/usb/gadget/Kconfig | 12 - drivers/usb/gadget/Makefile | 1 - drivers/usb/gadget/gadget_chips.h | 8 - drivers/usb/gadget/lh7a40x_udc.c | 2152 -------------------- drivers/usb/gadget/lh7a40x_udc.h | 259 --- drivers/usb/host/ohci-hcd.c | 5 - drivers/usb/host/ohci-lh7a404.c | 252 --- drivers/usb/host/ohci.h | 10 - drivers/video/Kconfig | 63 - 58 files changed, 1 insertion(+), 7382 deletions(-) delete mode 100644 Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen delete mode 100644 Documentation/arm/Sharp-LH/CompactFlash delete mode 100644 Documentation/arm/Sharp-LH/IOBarrier delete mode 100644 Documentation/arm/Sharp-LH/KEV7A400 delete mode 100644 Documentation/arm/Sharp-LH/LCDPanels delete mode 100644 Documentation/arm/Sharp-LH/LPD7A400 delete mode 100644 Documentation/arm/Sharp-LH/LPD7A40X delete mode 100644 Documentation/arm/Sharp-LH/SDRAM delete mode 100644 Documentation/arm/Sharp-LH/VectoredInterruptController delete mode 100644 arch/arm/configs/lpd7a400_defconfig delete mode 100644 arch/arm/configs/lpd7a404_defconfig delete mode 100644 arch/arm/mach-lh7a40x/Kconfig delete mode 100644 arch/arm/mach-lh7a40x/Makefile delete mode 100644 arch/arm/mach-lh7a40x/Makefile.boot delete mode 100644 arch/arm/mach-lh7a40x/arch-kev7a400.c delete mode 100644 arch/arm/mach-lh7a40x/arch-lpd7a40x.c delete mode 100644 arch/arm/mach-lh7a40x/clcd.c delete mode 100644 arch/arm/mach-lh7a40x/clocks.c delete mode 100644 arch/arm/mach-lh7a40x/common.h delete mode 100644 arch/arm/mach-lh7a40x/include/mach/clocks.h delete mode 100644 arch/arm/mach-lh7a40x/include/mach/constants.h delete mode 100644 arch/arm/mach-lh7a40x/include/mach/debug-macro.S delete mode 100644 arch/arm/mach-lh7a40x/include/mach/dma.h delete mode 100644 arch/arm/mach-lh7a40x/include/mach/entry-macro.S delete mode 100644 arch/arm/mach-lh7a40x/include/mach/hardware.h delete mode 100644 arch/arm/mach-lh7a40x/include/mach/io.h delete mode 100644 arch/arm/mach-lh7a40x/include/mach/irqs.h delete mode 100644 arch/arm/mach-lh7a40x/include/mach/memory.h delete mode 100644 arch/arm/mach-lh7a40x/include/mach/registers.h delete mode 100644 arch/arm/mach-lh7a40x/include/mach/ssp.h delete mode 100644 arch/arm/mach-lh7a40x/include/mach/system.h delete mode 100644 arch/arm/mach-lh7a40x/include/mach/timex.h delete mode 100644 arch/arm/mach-lh7a40x/include/mach/uncompress.h delete mode 100644 arch/arm/mach-lh7a40x/include/mach/vmalloc.h delete mode 100644 arch/arm/mach-lh7a40x/irq-kev7a400.c delete mode 100644 arch/arm/mach-lh7a40x/irq-lh7a400.c delete mode 100644 arch/arm/mach-lh7a40x/irq-lh7a404.c delete mode 100644 arch/arm/mach-lh7a40x/irq-lpd7a40x.c delete mode 100644 arch/arm/mach-lh7a40x/lcd-panel.h delete mode 100644 arch/arm/mach-lh7a40x/ssp-cpld.c delete mode 100644 arch/arm/mach-lh7a40x/time.c delete mode 100644 drivers/tty/serial/serial_lh7a40x.c delete mode 100644 drivers/usb/gadget/lh7a40x_udc.c delete mode 100644 drivers/usb/gadget/lh7a40x_udc.h delete mode 100644 drivers/usb/host/ohci-lh7a404.c (limited to 'drivers') diff --git a/Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen b/Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen deleted file mode 100644 index dc460f055647..000000000000 --- a/Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen +++ /dev/null @@ -1,61 +0,0 @@ -README on the ADC/Touchscreen Controller -======================================== - -The LH79524 and LH7A404 include a built-in Analog to Digital -controller (ADC) that is used to process input from a touchscreen. -The driver only implements a four-wire touch panel protocol. - -The touchscreen driver is maintenance free except for the pen-down or -touch threshold. Some resistive displays and board combinations may -require tuning of this threshold. The driver exposes some of its -internal state in the sys filesystem. If the kernel is configured -with it, CONFIG_SYSFS, and sysfs is mounted at /sys, there will be a -directory - - /sys/devices/platform/adc-lh7.0 - -containing these files. - - -r--r--r-- 1 root root 4096 Jan 1 00:00 samples - -rw-r--r-- 1 root root 4096 Jan 1 00:00 threshold - -r--r--r-- 1 root root 4096 Jan 1 00:00 threshold_range - -The threshold is the current touch threshold. It defaults to 750 on -most targets. - - # cat threshold - 750 - -The threshold_range contains the range of valid values for the -threshold. Values outside of this range will be silently ignored. - - # cat threshold_range - 0 1023 - -To change the threshold, write a value to the threshold file. - - # echo 500 > threshold - # cat threshold - 500 - -The samples file contains the most recently sampled values from the -ADC. There are 12. Below are typical of the last sampled values when -the pen has been released. The first two and last two samples are for -detecting whether or not the pen is down. The third through sixth are -X coordinate samples. The seventh through tenth are Y coordinate -samples. - - # cat samples - 1023 1023 0 0 0 0 530 529 530 529 1023 1023 - -To determine a reasonable threshold, press on the touch panel with an -appropriate stylus and read the values from samples. - - # cat samples - 1023 676 92 103 101 102 855 919 922 922 1023 679 - -The first and eleventh samples are discarded. Thus, the important -values are the second and twelfth which are used to determine if the -pen is down. When both are below the threshold, the driver registers -that the pen is down. When either is above the threshold, it -registers then pen is up. diff --git a/Documentation/arm/Sharp-LH/CompactFlash b/Documentation/arm/Sharp-LH/CompactFlash deleted file mode 100644 index 8616d877df9e..000000000000 --- a/Documentation/arm/Sharp-LH/CompactFlash +++ /dev/null @@ -1,32 +0,0 @@ -README on the Compact Flash for Card Engines -============================================ - -There are three challenges in supporting the CF interface of the Card -Engines. First, every IO operation must be followed with IO to -another memory region. Second, the slot is wired for one-to-one -address mapping *and* it is wired for 16 bit access only. Second, the -interrupt request line from the CF device isn't wired. - -The IOBARRIER issue is covered in README.IOBARRIER. This isn't an -onerous problem. Enough said here. - -The addressing issue is solved in the -arch/arm/mach-lh7a40x/ide-lpd7a40x.c file with some awkward -work-arounds. We implement a special SELECT_DRIVE routine that is -called before the IDE driver performs its own SELECT_DRIVE. Our code -recognizes that the SELECT register cannot be modified without also -writing a command. It send an IDLE_IMMEDIATE command on selecting a -drive. The function also prevents drive select to the slave drive -since there can be only one. The awkward part is that the IDE driver, -even though we have a select procedure, also attempts to change the -drive by writing directly the SELECT register. This attempt is -explicitly blocked by the OUTB function--not pretty, but effective. - -The lack of interrupts is a more serious problem. Even though the CF -card is fast when compared to a normal IDE device, we don't know that -the CF is really flash. A user could use one of the very small hard -drives being shipped with a CF interface. The IDE code includes a -check for interfaces that lack an IRQ. In these cases, submitting a -command to the IDE controller is followed by a call to poll for -completion. If the device isn't immediately ready, it schedules a -timer to poll again later. diff --git a/Documentation/arm/Sharp-LH/IOBarrier b/Documentation/arm/Sharp-LH/IOBarrier deleted file mode 100644 index 2e953e228f4d..000000000000 --- a/Documentation/arm/Sharp-LH/IOBarrier +++ /dev/null @@ -1,45 +0,0 @@ -README on the IOBARRIER for CardEngine IO -========================================= - -Due to an unfortunate oversight when the Card Engines were designed, -the signals that control access to some peripherals, most notably the -SMC91C9111 ethernet controller, are not properly handled. - -The symptom is that some back to back IO with the peripheral returns -unreliable data. With the SMC chip, you'll see errors about the bank -register being 'screwed'. - -The cause is that the AEN signal to the SMC chip does not transition -for every memory access. It is driven through the CPLD from the CS7 -line of the CPU's static memory controller which is optimized to -eliminate unnecessary transitions. Yet, the SMC requires a transition -for every write access. The Sharp website has more information about -the effect this power-conserving feature has on peripheral -interfacing. - -The solution is to follow every write access to the SMC chip with an -access to another memory region that will force the CPU to release the -chip select line. It is important to guarantee that this access -forces the CPU off-chip. We map a page of SDRAM as if it were an -uncacheable IO device and read from it after every SMC IO write -operation. - - SMC IO - BARRIER IO - -Only this sequence is important. It does not matter that there is no -BARRIER IO before the access to the SMC chip because the AEN latch -only needs occurs after the SMC IO write cycle. The routines that -implement this work-around make an additional concession which is to -disable interrupts during the IO sequence. Other hardware devices -(the LogicPD CPLD) have registers in the same physical memory -region as the SMC chip. An interrupt might allow an access to one of -those registers while SMC IO is being performed. - -You might be tempted to think that we have to access another device -attached to the static memory controller, but the empirical evidence -indicates that this is not so. Mapping 0x00000000 (flash) and -0xc0000000 (SDRAM) appear to have the same effect. Using SDRAM seems -to be faster. Choosing to access an undecoded memory region is not -desirable as there is no way to know how that chip select will be used -in the future. diff --git a/Documentation/arm/Sharp-LH/KEV7A400 b/Documentation/arm/Sharp-LH/KEV7A400 deleted file mode 100644 index be32b14cd535..000000000000 --- a/Documentation/arm/Sharp-LH/KEV7A400 +++ /dev/null @@ -1,8 +0,0 @@ -README on Implementing Linux for Sharp's KEV7a400 -================================================= - -This product has been discontinued by Sharp. For the time being, the -partially implemented code remains in the kernel. At some point in -the future, either the code will be finished or it will be removed -completely. This depends primarily on how many of the development -boards are in the field. diff --git a/Documentation/arm/Sharp-LH/LCDPanels b/Documentation/arm/Sharp-LH/LCDPanels deleted file mode 100644 index fb1b21c2f2f4..000000000000 --- a/Documentation/arm/Sharp-LH/LCDPanels +++ /dev/null @@ -1,59 +0,0 @@ -README on the LCD Panels -======================== - -Configuration options for several LCD panels, available from Logic PD, -are included in the kernel source. This README will help you -understand the configuration data and give you some guidance for -adding support for other panels if you wish. - - -lcd-panels.h ------------- - -There is no way, at present, to detect which panel is attached to the -system at runtime. Thus the kernel configuration is static. The file -arch/arm/mach-ld7a40x/lcd-panels.h (or similar) defines all of the -panel specific parameters. - -It should be possible for this data to be shared among several device -families. The current layout may be insufficiently general, but it is -amenable to improvement. - - -PIXEL_CLOCK ------------ - -The panel data sheets will give a range of acceptable pixel clocks. -The fundamental LCDCLK input frequency is divided down by a PCD -constant in field '.tim2'. It may happen that it is impossible to set -the pixel clock within this range. A clock which is too slow will -tend to flicker. For the highest quality image, set the clock as high -as possible. - - -MARGINS -------- - -These values may be difficult to glean from the panel data sheet. In -the case of the Sharp panels, the upper margin is explicitly called -out as a specific number of lines from the top of the frame. The -other values may not matter as much as the panels tend to -automatically center the image. - - -Sync Sense ----------- - -The sense of the hsync and vsync pulses may be called out in the data -sheet. On one panel, the sense of these pulses determine the height -of the visible region on the panel. Most of the Sharp panels use -negative sense sync pulses set by the TIM2_IHS and TIM2_IVS bits in -'.tim2'. - - -Pel Layout ----------- - -The Sharp color TFT panels are all configured for 16 bit direct color -modes. The amba-lcd driver sets the pel mode to 565 for 5 bits of -each red and blue and 6 bits of green. diff --git a/Documentation/arm/Sharp-LH/LPD7A400 b/Documentation/arm/Sharp-LH/LPD7A400 deleted file mode 100644 index 3275b453bfdf..000000000000 --- a/Documentation/arm/Sharp-LH/LPD7A400 +++ /dev/null @@ -1,15 +0,0 @@ -README on Implementing Linux for the Logic PD LPD7A400-10 -========================================================= - -- CPLD memory mapping - - The board designers chose to use high address lines for controlling - access to the CPLD registers. It turns out to be a big waste - because we're using an MMU and must map IO space into virtual - memory. The result is that we have to make a mapping for every - register. - -- Serial Console - - It may be OK not to use the serial console option if the user passes - the console device name to the kernel. This deserves some exploration. diff --git a/Documentation/arm/Sharp-LH/LPD7A40X b/Documentation/arm/Sharp-LH/LPD7A40X deleted file mode 100644 index 8c29a27e208f..000000000000 --- a/Documentation/arm/Sharp-LH/LPD7A40X +++ /dev/null @@ -1,16 +0,0 @@ -README on Implementing Linux for the Logic PD LPD7A40X-10 -========================================================= - -- CPLD memory mapping - - The board designers chose to use high address lines for controlling - access to the CPLD registers. It turns out to be a big waste - because we're using an MMU and must map IO space into virtual - memory. The result is that we have to make a mapping for every - register. - -- Serial Console - - It may be OK not to use the serial console option if the user passes - the console device name to the kernel. This deserves some exploration. - diff --git a/Documentation/arm/Sharp-LH/SDRAM b/Documentation/arm/Sharp-LH/SDRAM deleted file mode 100644 index 93ddc23c2faa..000000000000 --- a/Documentation/arm/Sharp-LH/SDRAM +++ /dev/null @@ -1,51 +0,0 @@ -README on the SDRAM Controller for the LH7a40X -============================================== - -The standard configuration for the SDRAM controller generates a sparse -memory array. The precise layout is determined by the SDRAM chips. A -default kernel configuration assembles the discontiguous memory -regions into separate memory nodes via the NUMA (Non-Uniform Memory -Architecture) facilities. In this default configuration, the kernel -is forgiving about the precise layout. As long as it is given an -accurate picture of available memory by the bootloader the kernel will -execute correctly. - -The SDRC supports a mode where some of the chip select lines are -swapped in order to make SDRAM look like a synchronous ROM. Setting -this bit means that the RAM will present as a contiguous array. Some -programmers prefer this to the discontiguous layout. Be aware that -may be a penalty for this feature where some some configurations of -memory are significantly reduced; i.e. 64MiB of RAM appears as only 32 -MiB. - -There are a couple of configuration options to override the default -behavior. When the SROMLL bit is set and memory appears as a -contiguous array, there is no reason to support NUMA. -CONFIG_LH7A40X_CONTIGMEM disables NUMA support. When physical memory -is discontiguous, the memory tables are organized such that there are -two banks per nodes with a small gap between them. This layout wastes -some kernel memory for page tables representing non-existent memory. -CONFIG_LH7A40X_ONE_BANK_PER_NODE optimizes the node tables such that -there are no gaps. These options control the low level organization -of the memory management tables in ways that may prevent the kernel -from booting or may cause the kernel to allocated excessively large -page tables. Be warned. Only change these options if you know what -you are doing. The default behavior is a reasonable compromise that -will suit all users. - --- - -A typical 32MiB system with the default configuration options will -find physical memory managed as follows. - - node 0: 0xc0000000 4MiB - 0xc1000000 4MiB - node 1: 0xc4000000 4MiB - 0xc5000000 4MiB - node 2: 0xc8000000 4MiB - 0xc9000000 4MiB - node 3: 0xcc000000 4MiB - 0xcd000000 4MiB - -Setting CONFIG_LH7A40X_ONE_BANK_PER_NODE will put each bank into a -separate node. diff --git a/Documentation/arm/Sharp-LH/VectoredInterruptController b/Documentation/arm/Sharp-LH/VectoredInterruptController deleted file mode 100644 index 23047e9861ee..000000000000 --- a/Documentation/arm/Sharp-LH/VectoredInterruptController +++ /dev/null @@ -1,80 +0,0 @@ -README on the Vectored Interrupt Controller of the LH7A404 -========================================================== - -The 404 revision of the LH7A40X series comes with two vectored -interrupts controllers. While the kernel does use some of the -features of these devices, it is far from the purpose for which they -were designed. - -When this README was written, the implementation of the VICs was in -flux. It is possible that some details, especially with priorities, -will change. - -The VIC support code is inspired by routines written by Sharp. - - -Priority Control ----------------- - -The significant reason for using the VIC's vectoring is to control -interrupt priorities. There are two tables in -arch/arm/mach-lh7a40x/irq-lh7a404.c that look something like this. - - static unsigned char irq_pri_vic1[] = { IRQ_GPIO3INTR, }; - static unsigned char irq_pri_vic2[] = { - IRQ_T3UI, IRQ_GPIO7INTR, - IRQ_UART1INTR, IRQ_UART2INTR, IRQ_UART3INTR, }; - -The initialization code reads these tables and inserts a vector -address and enable for each indicated IRQ. Vectored interrupts have -higher priority than non-vectored interrupts. So, on VIC1, -IRQ_GPIO3INTR will be served before any other non-FIQ interrupt. Due -to the way that the vectoring works, IRQ_T3UI is the next highest -priority followed by the other vectored interrupts on VIC2. After -that, the non-vectored interrupts are scanned in VIC1 then in VIC2. - - -ISR ---- - -The interrupt service routine macro get_irqnr() in -arch/arm/kernel/entry-armv.S scans the VICs for the next active -interrupt. The vectoring makes this code somewhat larger than it was -before using vectoring (refer to the LH7A400 implementation). In the -case where an interrupt is vectored, the implementation will tend to -be faster than the non-vectored version. However, the worst-case path -is longer. - -It is worth noting that at present, there is no need to read -VIC2_VECTADDR because the register appears to be shared between the -controllers. The code is written such that if this changes, it ought -to still work properly. - - -Vector Addresses ----------------- - -The proper use of the vectoring hardware would jump to the ISR -specified by the vectoring address. Linux isn't structured to take -advantage of this feature, though it might be possible to change -things to support it. - -In this implementation, the vectoring address is used to speed the -search for the active IRQ. The address is coded such that the lowest -6 bits store the IRQ number for vectored interrupts. These numbers -correspond to the bits in the interrupt status registers. IRQ zero is -the lowest interrupt bit in VIC1. IRQ 32 is the lowest interrupt bit -in VIC2. Because zero is a valid IRQ number and because we cannot -detect whether or not there is a valid vectoring address if that -address is zero, the eigth bit (0x100) is set for vectored interrupts. -The address for IRQ 0x18 (VIC2) is 0x118. Only the ninth bit is set -for the default handler on VIC1 and only the tenth bit is set for the -default handler on VIC2. - -In other words. - - 0x000 - no active interrupt - 0x1ii - vectored interrupt 0xii - 0x2xx - unvectored interrupt on VIC1 (xx is don't care) - 0x4xx - unvectored interrupt on VIC2 (xx is don't care) - diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5cff165b7eb0..18a1eb93fd72 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -795,17 +795,6 @@ config ARCH_TCC_926 help Support for Telechips TCC ARM926-based systems. -config ARCH_LH7A40X - bool "Sharp LH7A40X" - select CPU_ARM922T - select ARCH_SPARSEMEM_ENABLE if !LH7A40X_CONTIGMEM - select ARCH_USES_GETTIMEOFFSET - help - Say Y here for systems based on one of the Sharp LH7A40X - System on a Chip processors. These CPUs include an ARM922T - core with a wide array of integrated devices for - hand-held and low-power applications. - config ARCH_U300 bool "ST-Ericsson U300 Series" depends on MMU @@ -922,8 +911,6 @@ source "arch/arm/mach-kirkwood/Kconfig" source "arch/arm/mach-ks8695/Kconfig" -source "arch/arm/mach-lh7a40x/Kconfig" - source "arch/arm/mach-loki/Kconfig" source "arch/arm/mach-lpc32xx/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index c22c1adfedd6..aa18cb9da57b 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -146,7 +146,6 @@ machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood machine-$(CONFIG_ARCH_KS8695) := ks8695 -machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x machine-$(CONFIG_ARCH_LOKI) := loki machine-$(CONFIG_ARCH_LPC32XX) := lpc32xx machine-$(CONFIG_ARCH_MMP) := mmp diff --git a/arch/arm/configs/lpd7a400_defconfig b/arch/arm/configs/lpd7a400_defconfig deleted file mode 100644 index 5a48f171204c..000000000000 --- a/arch/arm/configs/lpd7a400_defconfig +++ /dev/null @@ -1,68 +0,0 @@ -CONFIG_EXPERIMENTAL=y -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_IKCONFIG=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_EXPERT=y -# CONFIG_HOTPLUG is not set -# CONFIG_EPOLL is not set -# CONFIG_IOSCHED_DEADLINE is not set -CONFIG_ARCH_LH7A40X=y -CONFIG_MACH_LPD7A400=y -CONFIG_PREEMPT=y -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_FPE_NWFPE=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -# CONFIG_IPV6 is not set -CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_PHYSMAP=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_IDE=y -CONFIG_SCSI=y -# CONFIG_SCSI_PROC_FS is not set -CONFIG_NETDEVICES=y -CONFIG_NET_ETHERNET=y -CONFIG_SMC91X=y -# CONFIG_INPUT_MOUSEDEV is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -# CONFIG_SERIO is not set -CONFIG_SERIAL_LH7A40X=y -CONFIG_SERIAL_LH7A40X_CONSOLE=y -CONFIG_FB=y -# CONFIG_VGA_CONSOLE is not set -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_MIXER_OSS=y -CONFIG_SND_PCM_OSS=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_JFFS2_FS=y -CONFIG_CRAMFS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -CONFIG_ROOT_NFS=y -CONFIG_PARTITION_ADVANCED=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_KERNEL=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_USER=y -CONFIG_DEBUG_ERRORS=y diff --git a/arch/arm/configs/lpd7a404_defconfig b/arch/arm/configs/lpd7a404_defconfig deleted file mode 100644 index 22d0631de009..000000000000 --- a/arch/arm/configs/lpd7a404_defconfig +++ /dev/null @@ -1,81 +0,0 @@ -CONFIG_EXPERIMENTAL=y -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_IKCONFIG=y -CONFIG_LOG_BUF_SHIFT=16 -CONFIG_EXPERT=y -# CONFIG_HOTPLUG is not set -# CONFIG_EPOLL is not set -CONFIG_SLAB=y -# CONFIG_IOSCHED_DEADLINE is not set -CONFIG_ARCH_LH7A40X=y -CONFIG_MACH_LPD7A404=y -CONFIG_PREEMPT=y -CONFIG_DISCONTIGMEM_MANUAL=y -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_FPE_NWFPE=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -# CONFIG_IPV6 is not set -CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_PHYSMAP=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_IDE=y -CONFIG_SCSI=y -# CONFIG_SCSI_PROC_FS is not set -CONFIG_NETDEVICES=y -CONFIG_NET_ETHERNET=y -CONFIG_SMC91X=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -# CONFIG_SERIO is not set -CONFIG_SERIAL_LH7A40X=y -CONFIG_SERIAL_LH7A40X_CONSOLE=y -CONFIG_FB=y -# CONFIG_VGA_CONSOLE is not set -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_MIXER_OSS=y -CONFIG_SND_PCM_OSS=y -CONFIG_USB=y -CONFIG_USB_DEVICEFS=y -CONFIG_USB_MON=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_STORAGE=y -CONFIG_USB_STORAGE_DEBUG=y -CONFIG_USB_STORAGE_DATAFAB=y -CONFIG_USB_GADGET=y -CONFIG_USB_ZERO=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -CONFIG_INOTIFY=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_JFFS2_FS=y -CONFIG_CRAMFS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -CONFIG_ROOT_NFS=y -CONFIG_PARTITION_ADVANCED=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_KERNEL=y -CONFIG_DEBUG_MUTEXES=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_USER=y -CONFIG_DEBUG_ERRORS=y diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h index f1e5a9bca249..da8b52ec49cf 100644 --- a/arch/arm/include/asm/setup.h +++ b/arch/arm/include/asm/setup.h @@ -192,11 +192,7 @@ static struct tagtable __tagtable_##fn __tag = { tag, fn } /* * Memory map description */ -#ifdef CONFIG_ARCH_LH7A40X -# define NR_BANKS 16 -#else -# define NR_BANKS 8 -#endif +#define NR_BANKS 8 struct membank { unsigned long start; diff --git a/arch/arm/mach-lh7a40x/Kconfig b/arch/arm/mach-lh7a40x/Kconfig deleted file mode 100644 index 9be7466e346c..000000000000 --- a/arch/arm/mach-lh7a40x/Kconfig +++ /dev/null @@ -1,74 +0,0 @@ -if ARCH_LH7A40X - -menu "LH7A40X Implementations" - -config MACH_KEV7A400 - bool "KEV7A400" - select ARCH_LH7A400 - help - Say Y here if you are using the Sharp KEV7A400 development - board. This hardware is discontinued, so I'd be very - surprised if you wanted this option. - -config MACH_LPD7A400 - bool "LPD7A400 Card Engine" - select ARCH_LH7A400 -# select IDE_POLL -# select HAS_TOUCHSCREEN_ADS7843_LH7 - help - Say Y here if you are using Logic Product Development's - LPD7A400 CardEngine. For the time being, the LPD7A400 and - LPD7A404 options are mutually exclusive. - -config MACH_LPD7A404 - bool "LPD7A404 Card Engine" - select ARCH_LH7A404 -# select IDE_POLL -# select HAS_TOUCHSCREEN_ADC_LH7 - help - Say Y here if you are using Logic Product Development's - LPD7A404 CardEngine. For the time being, the LPD7A400 and - LPD7A404 options are mutually exclusive. - -config ARCH_LH7A400 - bool - -config ARCH_LH7A404 - bool - -config LPD7A40X_CPLD_SSP - bool - -config LH7A40X_CONTIGMEM - bool "Disable NUMA/SparseMEM Support" - help - Say Y here if your bootloader sets the SROMLL bit(s) in - the SDRAM controller, organizing memory as a contiguous - array. This option will disable sparse memory support - and force the kernel to manage all memory in one node. - - Setting this option incorrectly may prevent the kernel - from booting. It is OK to leave it N. - - For more information, consult - . - -config LH7A40X_ONE_BANK_PER_NODE - bool "Optimize NUMA Node Tables for Size" - depends on !LH7A40X_CONTIGMEM - help - Say Y here to produce compact memory node tables. By - default pairs of adjacent physical RAM banks are managed - together in a single node, incurring some wasted overhead - in the node tables, however also maintaining compatibility - with systems where physical memory is truly contiguous. - - Setting this option incorrectly may prevent the kernel from - booting. It is OK to leave it N. - - For more information, consult - . - -endmenu - -endif diff --git a/arch/arm/mach-lh7a40x/Makefile b/arch/arm/mach-lh7a40x/Makefile deleted file mode 100644 index 94b8615fb3c3..000000000000 --- a/arch/arm/mach-lh7a40x/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# -# Makefile for the linux kernel. -# - -# Object file lists. - -obj-y := time.o clocks.o -obj-m := -obj-n := -obj- := - -obj-$(CONFIG_MACH_KEV7A400) += arch-kev7a400.o irq-lh7a400.o -obj-$(CONFIG_MACH_LPD7A400) += arch-lpd7a40x.o irq-lh7a400.o -obj-$(CONFIG_MACH_LPD7A404) += arch-lpd7a40x.o irq-lh7a404.o -obj-$(CONFIG_LPD7A40X_CPLD_SSP) += ssp-cpld.o -obj-$(CONFIG_FB_ARMCLCD) += clcd.o - diff --git a/arch/arm/mach-lh7a40x/Makefile.boot b/arch/arm/mach-lh7a40x/Makefile.boot deleted file mode 100644 index af941be076eb..000000000000 --- a/arch/arm/mach-lh7a40x/Makefile.boot +++ /dev/null @@ -1,4 +0,0 @@ - zreladdr-y := 0xc0008000 -params_phys-y := 0xc0000100 -initrd_phys-y := 0xc4000000 - diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c deleted file mode 100644 index 71129c33c7d2..000000000000 --- a/arch/arm/mach-lh7a40x/arch-kev7a400.c +++ /dev/null @@ -1,118 +0,0 @@ -/* arch/arm/mach-lh7a40x/arch-kev7a400.c - * - * Copyright (C) 2004 Logic Product Development - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "common.h" - - /* This function calls the board specific IRQ initialization function. */ - -static struct map_desc kev7a400_io_desc[] __initdata = { - { - .virtual = IO_VIRT, - .pfn = __phys_to_pfn(IO_PHYS), - .length = IO_SIZE, - .type = MT_DEVICE - }, { - .virtual = CPLD_VIRT, - .pfn = __phys_to_pfn(CPLD_PHYS), - .length = CPLD_SIZE, - .type = MT_DEVICE - } -}; - -void __init kev7a400_map_io(void) -{ - iotable_init (kev7a400_io_desc, ARRAY_SIZE (kev7a400_io_desc)); -} - -static u16 CPLD_IRQ_mask; /* Mask for CPLD IRQs, 1 == unmasked */ - -static void kev7a400_ack_cpld_irq(struct irq_data *d) -{ - CPLD_CL_INT = 1 << (d->irq - IRQ_KEV7A400_CPLD); -} - -static void kev7a400_mask_cpld_irq(struct irq_data *d) -{ - CPLD_IRQ_mask &= ~(1 << (d->irq - IRQ_KEV7A400_CPLD)); - CPLD_WR_PB_INT_MASK = CPLD_IRQ_mask; -} - -static void kev7a400_unmask_cpld_irq(struct irq_data *d) -{ - CPLD_IRQ_mask |= 1 << (d->irq - IRQ_KEV7A400_CPLD); - CPLD_WR_PB_INT_MASK = CPLD_IRQ_mask; -} - -static struct irq_chip kev7a400_cpld_chip = { - .name = "CPLD", - .irq_ack = kev7a400_ack_cpld_irq, - .irq_mask = kev7a400_mask_cpld_irq, - .irq_unmask = kev7a400_unmask_cpld_irq, -}; - - -static void kev7a400_cpld_handler (unsigned int irq, struct irq_desc *desc) -{ - u32 mask = CPLD_LATCHED_INTS; - irq = IRQ_KEV7A400_CPLD; - for (; mask; mask >>= 1, ++irq) - if (mask & 1) - generic_handle_irq(irq); -} - -void __init lh7a40x_init_board_irq (void) -{ - int irq; - - for (irq = IRQ_KEV7A400_CPLD; - irq < IRQ_KEV7A400_CPLD + NR_IRQ_BOARD; ++irq) { - set_irq_chip (irq, &kev7a400_cpld_chip); - set_irq_handler (irq, handle_edge_irq); - set_irq_flags (irq, IRQF_VALID); - } - set_irq_chained_handler (IRQ_CPLD, kev7a400_cpld_handler); - - /* Clear all CPLD interrupts */ - CPLD_CL_INT = 0xff; /* CPLD_INTR_MMC_CD | CPLD_INTR_ETH_INT; */ - - GPIO_GPIOINTEN = 0; /* Disable all GPIO interrupts */ - barrier(); - -#if 0 - GPIO_INTTYPE1 - = (GPIO_INTR_PCC1_CD | GPIO_INTR_PCC1_CD); /* Edge trig. */ - GPIO_INTTYPE2 = 0; /* Falling edge & low-level */ - GPIO_GPIOFEOI = 0xff; /* Clear all GPIO interrupts */ - GPIO_GPIOINTEN = 0xff; /* Enable all GPIO interrupts */ - - init_FIQ(); -#endif -} - -MACHINE_START (KEV7A400, "Sharp KEV7a400") - /* Maintainer: Marc Singer */ - .boot_params = 0xc0000100, - .map_io = kev7a400_map_io, - .init_irq = lh7a400_init_irq, - .timer = &lh7a40x_timer, -MACHINE_END diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c deleted file mode 100644 index e735546181ad..000000000000 --- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c +++ /dev/null @@ -1,422 +0,0 @@ -/* arch/arm/mach-lh7a40x/arch-lpd7a40x.c - * - * Copyright (C) 2004 Logic Product Development - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "common.h" - -#define CPLD_INT_NETHERNET (1<<0) -#define CPLD_INTMASK_ETHERNET (1<<2) -#if defined (CONFIG_MACH_LPD7A400) -# define CPLD_INT_NTOUCH (1<<1) -# define CPLD_INTMASK_TOUCH (1<<3) -# define CPLD_INT_PEN (1<<4) -# define CPLD_INTMASK_PEN (1<<4) -# define CPLD_INT_PIRQ (1<<4) -#endif -#define CPLD_INTMASK_CPLD (1<<7) -#define CPLD_INT_CPLD (1<<6) - -#define CPLD_CONTROL_SWINT (1<<7) /* Disable all CPLD IRQs */ -#define CPLD_CONTROL_OCMSK (1<<6) /* Mask USB1 connect IRQ */ -#define CPLD_CONTROL_PDRV (1<<5) /* PCC_nDRV high */ -#define CPLD_CONTROL_USB1C (1<<4) /* USB1 connect IRQ active */ -#define CPLD_CONTROL_USB1P (1<<3) /* USB1 power disable */ -#define CPLD_CONTROL_AWKP (1<<2) /* Auto-wakeup disabled */ -#define CPLD_CONTROL_LCD_ENABLE (1<<1) /* LCD Vee enable */ -#define CPLD_CONTROL_WRLAN_NENABLE (1<<0) /* SMC91x power disable */ - - -static struct resource smc91x_resources[] = { - [0] = { - .start = CPLD00_PHYS, - .end = CPLD00_PHYS + CPLD00_SIZE - 1, /* Only needs 16B */ - .flags = IORESOURCE_MEM, - }, - - [1] = { - .start = IRQ_LPD7A40X_ETH_INT, - .end = IRQ_LPD7A40X_ETH_INT, - .flags = IORESOURCE_IRQ, - }, - -}; - -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; - -static struct resource lh7a40x_usbclient_resources[] = { - [0] = { - .start = USB_PHYS, - .end = (USB_PHYS + PAGE_SIZE), - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_USB, - .end = IRQ_USB, - .flags = IORESOURCE_IRQ, - }, -}; - -static u64 lh7a40x_usbclient_dma_mask = 0xffffffffUL; - -static struct platform_device lh7a40x_usbclient_device = { -// .name = "lh7a40x_udc", - .name = "lh7-udc", - .id = 0, - .dev = { - .dma_mask = &lh7a40x_usbclient_dma_mask, - .coherent_dma_mask = 0xffffffffUL, - }, - .num_resources = ARRAY_SIZE (lh7a40x_usbclient_resources), - .resource = lh7a40x_usbclient_resources, -}; - -#if defined (CONFIG_ARCH_LH7A404) - -static struct resource lh7a404_usbhost_resources [] = { - [0] = { - .start = USBH_PHYS, - .end = (USBH_PHYS + 0xFF), - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_USHINTR, - .end = IRQ_USHINTR, - .flags = IORESOURCE_IRQ, - }, -}; - -static u64 lh7a404_usbhost_dma_mask = 0xffffffffUL; - -static struct platform_device lh7a404_usbhost_device = { - .name = "lh7a404-ohci", - .id = 0, - .dev = { - .dma_mask = &lh7a404_usbhost_dma_mask, - .coherent_dma_mask = 0xffffffffUL, - }, - .num_resources = ARRAY_SIZE (lh7a404_usbhost_resources), - .resource = lh7a404_usbhost_resources, -}; - -#endif - -static struct platform_device* lpd7a40x_devs[] __initdata = { - &smc91x_device, - &lh7a40x_usbclient_device, -#if defined (CONFIG_ARCH_LH7A404) - &lh7a404_usbhost_device, -#endif -}; - -extern void lpd7a400_map_io (void); - -static void __init lpd7a40x_init (void) -{ -#if defined (CONFIG_MACH_LPD7A400) - CPLD_CONTROL |= 0 - | CPLD_CONTROL_SWINT /* Disable software interrupt */ - | CPLD_CONTROL_OCMSK; /* Mask USB1 connection IRQ */ - CPLD_CONTROL &= ~(0 - | CPLD_CONTROL_LCD_ENABLE /* Disable LCD */ - | CPLD_CONTROL_WRLAN_NENABLE /* Enable SMC91x */ - ); -#endif - -#if defined (CONFIG_MACH_LPD7A404) - CPLD_CONTROL &= ~(0 - | CPLD_CONTROL_WRLAN_NENABLE /* Enable SMC91x */ - ); -#endif - - platform_add_devices (lpd7a40x_devs, ARRAY_SIZE (lpd7a40x_devs)); -#if defined (CONFIG_FB_ARMCLCD) - lh7a40x_clcd_init (); -#endif -} - -static void lh7a40x_ack_cpld_irq(struct irq_data *d) -{ - /* CPLD doesn't have ack capability, but some devices may */ - -#if defined (CPLD_INTMASK_TOUCH) - /* The touch control *must* mask the interrupt because the - * interrupt bit is read by the driver to determine if the pen - * is still down. */ - if (d->irq == IRQ_TOUCH) - CPLD_INTERRUPTS |= CPLD_INTMASK_TOUCH; -#endif -} - -static void lh7a40x_mask_cpld_irq(struct irq_data *d) -{ - switch (d->irq) { - case IRQ_LPD7A40X_ETH_INT: - CPLD_INTERRUPTS |= CPLD_INTMASK_ETHERNET; - break; -#if defined (IRQ_TOUCH) - case IRQ_TOUCH: - CPLD_INTERRUPTS |= CPLD_INTMASK_TOUCH; - break; -#endif - } -} - -static void lh7a40x_unmask_cpld_irq(struct irq_data *d) -{ - switch (d->irq) { - case IRQ_LPD7A40X_ETH_INT: - CPLD_INTERRUPTS &= ~CPLD_INTMASK_ETHERNET; - break; -#if defined (IRQ_TOUCH) - case IRQ_TOUCH: - CPLD_INTERRUPTS &= ~CPLD_INTMASK_TOUCH; - break; -#endif - } -} - -static struct irq_chip lpd7a40x_cpld_chip = { - .name = "CPLD", - .irq_ack = lh7a40x_ack_cpld_irq, - .irq_mask = lh7a40x_mask_cpld_irq, - .irq_unmask = lh7a40x_unmask_cpld_irq, -}; - -static void lpd7a40x_cpld_handler (unsigned int irq, struct irq_desc *desc) -{ - unsigned int mask = CPLD_INTERRUPTS; - - desc->irq_data.chip->irq_ack(&desc->irq_data); - - if ((mask & (1<<0)) == 0) /* WLAN */ - generic_handle_irq(IRQ_LPD7A40X_ETH_INT); - -#if defined (IRQ_TOUCH) - if ((mask & (1<<1)) == 0) /* Touch */ - generic_handle_irq(IRQ_TOUCH); -#endif - - /* Level-triggered need this */ - desc->irq_data.chip->irq_unmask(&desc->irq_data); -} - - -void __init lh7a40x_init_board_irq (void) -{ - int irq; - - /* Rev A (v2.8): PF0, PF1, PF2, and PF3 are available IRQs. - PF7 supports the CPLD. - Rev B (v3.4): PF0, PF1, and PF2 are available IRQs. - PF3 supports the CPLD. - (Some) LPD7A404 prerelease boards report a version - number of 0x16, but we force an override since the - hardware is of the newer variety. - */ - - unsigned char cpld_version = CPLD_REVISION; - int pinCPLD = (cpld_version == 0x28) ? 7 : 3; - -#if defined CONFIG_MACH_LPD7A404 - cpld_version = 0x34; /* Coerce LPD7A404 to RevB */ -#endif - - /* First, configure user controlled GPIOF interrupts */ - - GPIO_PFDD &= ~0x0f; /* PF0-3 are inputs */ - GPIO_INTTYPE1 &= ~0x0f; /* PF0-3 are level triggered */ - GPIO_INTTYPE2 &= ~0x0f; /* PF0-3 are active low */ - barrier (); - GPIO_GPIOFINTEN |= 0x0f; /* Enable PF0, PF1, PF2, and PF3 IRQs */ - - /* Then, configure CPLD interrupt */ - - /* Disable all CPLD interrupts */ -#if defined (CONFIG_MACH_LPD7A400) - CPLD_INTERRUPTS = CPLD_INTMASK_TOUCH | CPLD_INTMASK_PEN - | CPLD_INTMASK_ETHERNET; - /* *** FIXME: don't know why we need 7 and 4. 7 is way wrong - and 4 is uncefined. */ - // (1<<7)|(1<<4)|(1<<3)|(1<<2); -#endif -#if defined (CONFIG_MACH_LPD7A404) - CPLD_INTERRUPTS = CPLD_INTMASK_ETHERNET; - /* *** FIXME: don't know why we need 6 and 5, neither is defined. */ - // (1<<6)|(1<<5)|(1<<3); -#endif - GPIO_PFDD &= ~(1 << pinCPLD); /* Make input */ - GPIO_INTTYPE1 &= ~(1 << pinCPLD); /* Level triggered */ - GPIO_INTTYPE2 &= ~(1 << pinCPLD); /* Active low */ - barrier (); - GPIO_GPIOFINTEN |= (1 << pinCPLD); /* Enable */ - - /* Cascade CPLD interrupts */ - - for (irq = IRQ_BOARD_START; - irq < IRQ_BOARD_START + NR_IRQ_BOARD; ++irq) { - set_irq_chip (irq, &lpd7a40x_cpld_chip); - set_irq_handler (irq, handle_level_irq); - set_irq_flags (irq, IRQF_VALID); - } - - set_irq_chained_handler ((cpld_version == 0x28) - ? IRQ_CPLD_V28 - : IRQ_CPLD_V34, - lpd7a40x_cpld_handler); -} - -static struct map_desc lpd7a40x_io_desc[] __initdata = { - { - .virtual = IO_VIRT, - .pfn = __phys_to_pfn(IO_PHYS), - .length = IO_SIZE, - .type = MT_DEVICE - }, - { /* Mapping added to work around chip select problems */ - .virtual = IOBARRIER_VIRT, - .pfn = __phys_to_pfn(IOBARRIER_PHYS), - .length = IOBARRIER_SIZE, - .type = MT_DEVICE - }, - { - .virtual = CF_VIRT, - .pfn = __phys_to_pfn(CF_PHYS), - .length = CF_SIZE, - .type = MT_DEVICE - }, - { - .virtual = CPLD02_VIRT, - .pfn = __phys_to_pfn(CPLD02_PHYS), - .length = CPLD02_SIZE, - .type = MT_DEVICE - }, - { - .virtual = CPLD06_VIRT, - .pfn = __phys_to_pfn(CPLD06_PHYS), - .length = CPLD06_SIZE, - .type = MT_DEVICE - }, - { - .virtual = CPLD08_VIRT, - .pfn = __phys_to_pfn(CPLD08_PHYS), - .length = CPLD08_SIZE, - .type = MT_DEVICE - }, - { - .virtual = CPLD08_VIRT, - .pfn = __phys_to_pfn(CPLD08_PHYS), - .length = CPLD08_SIZE, - .type = MT_DEVICE - }, - { - .virtual = CPLD0A_VIRT, - .pfn = __phys_to_pfn(CPLD0A_PHYS), - .length = CPLD0A_SIZE, - .type = MT_DEVICE - }, - { - .virtual = CPLD0C_VIRT, - .pfn = __phys_to_pfn(CPLD0C_PHYS), - .length = CPLD0C_SIZE, - .type = MT_DEVICE - }, - { - .virtual = CPLD0E_VIRT, - .pfn = __phys_to_pfn(CPLD0E_PHYS), - .length = CPLD0E_SIZE, - .type = MT_DEVICE - }, - { - .virtual = CPLD10_VIRT, - .pfn = __phys_to_pfn(CPLD10_PHYS), - .length = CPLD10_SIZE, - .type = MT_DEVICE - }, - { - .virtual = CPLD12_VIRT, - .pfn = __phys_to_pfn(CPLD12_PHYS), - .length = CPLD12_SIZE, - .type = MT_DEVICE - }, - { - .virtual = CPLD14_VIRT, - .pfn = __phys_to_pfn(CPLD14_PHYS), - .length = CPLD14_SIZE, - .type = MT_DEVICE - }, - { - .virtual = CPLD16_VIRT, - .pfn = __phys_to_pfn(CPLD16_PHYS), - .length = CPLD16_SIZE, - .type = MT_DEVICE - }, - { - .virtual = CPLD18_VIRT, - .pfn = __phys_to_pfn(CPLD18_PHYS), - .length = CPLD18_SIZE, - .type = MT_DEVICE - }, - { - .virtual = CPLD1A_VIRT, - .pfn = __phys_to_pfn(CPLD1A_PHYS), - .length = CPLD1A_SIZE, - .type = MT_DEVICE - }, -}; - -void __init -lpd7a40x_map_io(void) -{ - iotable_init (lpd7a40x_io_desc, ARRAY_SIZE (lpd7a40x_io_desc)); -} - -#ifdef CONFIG_MACH_LPD7A400 - -MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10") - /* Maintainer: Marc Singer */ - .boot_params = 0xc0000100, - .map_io = lpd7a40x_map_io, - .init_irq = lh7a400_init_irq, - .timer = &lh7a40x_timer, - .init_machine = lpd7a40x_init, -MACHINE_END - -#endif - -#ifdef CONFIG_MACH_LPD7A404 - -MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10") - /* Maintainer: Marc Singer */ - .boot_params = 0xc0000100, - .map_io = lpd7a40x_map_io, - .init_irq = lh7a404_init_irq, - .timer = &lh7a40x_timer, - .init_machine = lpd7a40x_init, -MACHINE_END - -#endif diff --git a/arch/arm/mach-lh7a40x/clcd.c b/arch/arm/mach-lh7a40x/clcd.c deleted file mode 100644 index 7fe4fd347c82..000000000000 --- a/arch/arm/mach-lh7a40x/clcd.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * arch/arm/mach-lh7a40x/clcd.c - * - * Copyright (C) 2004 Marc Singer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include - -//#include -//#include - -//#include -#include -#include - -#include -#include -#include -#include - -#define HRTFTC_HRSETUP __REG(HRTFTC_PHYS + 0x00) -#define HRTFTC_HRCON __REG(HRTFTC_PHYS + 0x04) -#define HRTFTC_HRTIMING1 __REG(HRTFTC_PHYS + 0x08) -#define HRTFTC_HRTIMING2 __REG(HRTFTC_PHYS + 0x0c) - -#define ALI_SETUP __REG(ALI_PHYS + 0x00) -#define ALI_CONTROL __REG(ALI_PHYS + 0x04) -#define ALI_TIMING1 __REG(ALI_PHYS + 0x08) -#define ALI_TIMING2 __REG(ALI_PHYS + 0x0c) - -#include "lcd-panel.h" - -static void lh7a40x_clcd_disable (struct clcd_fb *fb) -{ -#if defined (CONFIG_MACH_LPD7A400) - CPLD_CONTROL &= ~(1<<1); /* Disable LCD Vee */ -#endif - -#if defined (CONFIG_MACH_LPD7A404) - GPIO_PCD &= ~(1<<3); /* Disable LCD Vee */ -#endif - -#if defined (CONFIG_ARCH_LH7A400) - HRTFTC_HRSETUP &= ~(1<<13); /* Disable HRTFT controller */ -#endif - -#if defined (CONFIG_ARCH_LH7A404) - ALI_SETUP &= ~(1<<13); /* Disable ALI */ -#endif -} - -static void lh7a40x_clcd_enable (struct clcd_fb *fb) -{ - struct clcd_panel_extra* extra - = (struct clcd_panel_extra*) fb->board_data; - -#if defined (CONFIG_MACH_LPD7A400) - CPLD_CONTROL |= (1<<1); /* Enable LCD Vee */ -#endif - -#if defined (CONFIG_MACH_LPD7A404) - GPIO_PCDD &= ~(1<<3); /* Enable LCD Vee */ - GPIO_PCD |= (1<<3); -#endif - -#if defined (CONFIG_ARCH_LH7A400) - - if (extra) { - HRTFTC_HRSETUP - = (1 << 13) - | ((fb->fb.var.xres - 1) << 4) - | 0xc - | (extra->hrmode ? 1 : 0); - HRTFTC_HRCON - = ((extra->clsen ? 1 : 0) << 1) - | ((extra->spsen ? 1 : 0) << 0); - HRTFTC_HRTIMING1 - = (extra->pcdel << 8) - | (extra->revdel << 4) - | (extra->lpdel << 0); - HRTFTC_HRTIMING2 - = (extra->spldel << 9) - | (extra->pc2del << 0); - } - else - HRTFTC_HRSETUP - = (1 << 13) - | 0xc; -#endif - -#if defined (CONFIG_ARCH_LH7A404) - - if (extra) { - ALI_SETUP - = (1 << 13) - | ((fb->fb.var.xres - 1) << 4) - | 0xc - | (extra->hrmode ? 1 : 0); - ALI_CONTROL - = ((extra->clsen ? 1 : 0) << 1) - | ((extra->spsen ? 1 : 0) << 0); - ALI_TIMING1 - = (extra->pcdel << 8) - | (extra->revdel << 4) - | (extra->lpdel << 0); - ALI_TIMING2 - = (extra->spldel << 9) - | (extra->pc2del << 0); - } - else - ALI_SETUP - = (1 << 13) - | 0xc; -#endif - -} - -#define FRAMESIZE(s) (((s) + PAGE_SIZE - 1)&PAGE_MASK) - -static int lh7a40x_clcd_setup (struct clcd_fb *fb) -{ - dma_addr_t dma; - u32 len = FRAMESIZE (lcd_panel.mode.xres*lcd_panel.mode.yres - *(lcd_panel.bpp/8)); - - fb->panel = &lcd_panel; - - /* Enforce the sync polarity defaults */ - if (!(fb->panel->tim2 & TIM2_IHS)) - fb->fb.var.sync |= FB_SYNC_HOR_HIGH_ACT; - if (!(fb->panel->tim2 & TIM2_IVS)) - fb->fb.var.sync |= FB_SYNC_VERT_HIGH_ACT; - -#if defined (HAS_LCD_PANEL_EXTRA) - fb->board_data = &lcd_panel_extra; -#endif - - fb->fb.screen_base - = dma_alloc_writecombine (&fb->dev->dev, len, - &dma, GFP_KERNEL); - printk ("CLCD: LCD setup fb virt 0x%p phys 0x%p l %x io 0x%p \n", - fb->fb.screen_base, (void*) dma, len, - (void*) io_p2v (CLCDC_PHYS)); - printk ("CLCD: pixclock %d\n", lcd_panel.mode.pixclock); - - if (!fb->fb.screen_base) { - printk(KERN_ERR "CLCD: unable to map framebuffer\n"); - return -ENOMEM; - } - -#if defined (USE_RGB555) - fb->fb.var.green.length = 5; /* Panel uses RGB 5:5:5 */ -#endif - - fb->fb.fix.smem_start = dma; - fb->fb.fix.smem_len = len; - - /* Drive PE4 high to prevent CPLD crash */ - GPIO_PEDD |= (1<<4); - GPIO_PED |= (1<<4); - - GPIO_PINMUX |= (1<<1) | (1<<0); /* LCDVD[15:4] */ - -// fb->fb.fbops->fb_check_var (&fb->fb.var, &fb->fb); -// fb->fb.fbops->fb_set_par (&fb->fb); - - return 0; -} - -static int lh7a40x_clcd_mmap (struct clcd_fb *fb, struct vm_area_struct *vma) -{ - return dma_mmap_writecombine(&fb->dev->dev, vma, - fb->fb.screen_base, - fb->fb.fix.smem_start, - fb->fb.fix.smem_len); -} - -static void lh7a40x_clcd_remove (struct clcd_fb *fb) -{ - dma_free_writecombine (&fb->dev->dev, fb->fb.fix.smem_len, - fb->fb.screen_base, fb->fb.fix.smem_start); -} - -static struct clcd_board clcd_platform_data = { - .name = "lh7a40x FB", - .check = clcdfb_check, - .decode = clcdfb_decode, - .enable = lh7a40x_clcd_enable, - .setup = lh7a40x_clcd_setup, - .mmap = lh7a40x_clcd_mmap, - .remove = lh7a40x_clcd_remove, - .disable = lh7a40x_clcd_disable, -}; - -#define IRQ_CLCDC (IRQ_LCDINTR) - -#define AMBA_DEVICE(name,busid,base,plat,pid) \ -static struct amba_device name##_device = { \ - .dev = { \ - .coherent_dma_mask = ~0, \ - .init_name = busid, \ - .platform_data = plat, \ - }, \ - .res = { \ - .start = base##_PHYS, \ - .end = (base##_PHYS) + (4*1024) - 1, \ - .flags = IORESOURCE_MEM, \ - }, \ - .dma_mask = ~0, \ - .irq = { IRQ_##base, }, \ - /* .dma = base##_DMA,*/ \ - .periphid = pid, \ -} - -AMBA_DEVICE(clcd, "cldc-lh7a40x", CLCDC, &clcd_platform_data, 0x41110); - -static struct amba_device *amba_devs[] __initdata = { - &clcd_device, -}; - -void __init lh7a40x_clcd_init (void) -{ - int i; - int result; - printk ("CLCD: registering amba devices\n"); - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; - result = amba_device_register(d, &iomem_resource); - printk (" %d -> %d\n", i ,result); - } -} diff --git a/arch/arm/mach-lh7a40x/clocks.c b/arch/arm/mach-lh7a40x/clocks.c deleted file mode 100644 index 0651f96653f9..000000000000 --- a/arch/arm/mach-lh7a40x/clocks.c +++ /dev/null @@ -1,108 +0,0 @@ -/* arch/arm/mach-lh7a40x/clocks.c - * - * Copyright (C) 2004 Marc Singer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ -#include -#include -#include -#include -#include - -struct module; - -struct clk { - struct list_head node; - unsigned long rate; - struct module *owner; - const char *name; -}; - -/* ----- */ - -#define MAINDIV1(c) (((c) >> 7) & 0x0f) -#define MAINDIV2(c) (((c) >> 11) & 0x1f) -#define PS(c) (((c) >> 18) & 0x03) -#define PREDIV(c) (((c) >> 2) & 0x1f) -#define HCLKDIV(c) (((c) >> 0) & 0x02) -#define PCLKDIV(c) (((c) >> 16) & 0x03) - -unsigned int fclkfreq_get (void) -{ - unsigned int clkset = CSC_CLKSET; - unsigned int gclk - = XTAL_IN - / (1 << PS(clkset)) - * (MAINDIV1(clkset) + 2) - / (PREDIV(clkset) + 2) - * (MAINDIV2(clkset) + 2) - ; - return gclk; -} - -unsigned int hclkfreq_get (void) -{ - unsigned int clkset = CSC_CLKSET; - unsigned int hclk = fclkfreq_get () / (HCLKDIV(clkset) + 1); - - return hclk; -} - -unsigned int pclkfreq_get (void) -{ - unsigned int clkset = CSC_CLKSET; - int pclkdiv = PCLKDIV(clkset); - unsigned int pclk; - if (pclkdiv == 0x3) - pclkdiv = 0x2; - pclk = hclkfreq_get () / (1 << pclkdiv); - - return pclk; -} - -/* ----- */ - -struct clk *clk_get (struct device *dev, const char *id) -{ - return dev && strcmp(dev_name(dev), "cldc-lh7a40x") == 0 - ? NULL : ERR_PTR(-ENOENT); -} -EXPORT_SYMBOL(clk_get); - -void clk_put (struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_put); - -int clk_enable (struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable (struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate (struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_get_rate); - -long clk_round_rate (struct clk *clk, unsigned long rate) -{ - return rate; -} -EXPORT_SYMBOL(clk_round_rate); - -int clk_set_rate (struct clk *clk, unsigned long rate) -{ - return -EIO; -} -EXPORT_SYMBOL(clk_set_rate); diff --git a/arch/arm/mach-lh7a40x/common.h b/arch/arm/mach-lh7a40x/common.h deleted file mode 100644 index 6ed3f6b6db76..000000000000 --- a/arch/arm/mach-lh7a40x/common.h +++ /dev/null @@ -1,17 +0,0 @@ -/* arch/arm/mach-lh7a40x/common.h - * - * Copyright (C) 2004 Marc Singer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -extern struct sys_timer lh7a40x_timer; - -extern void lh7a400_init_irq (void); -extern void lh7a404_init_irq (void); -extern void lh7a40x_clcd_init (void); -extern void lh7a40x_init_board_irq (void); - diff --git a/arch/arm/mach-lh7a40x/include/mach/clocks.h b/arch/arm/mach-lh7a40x/include/mach/clocks.h deleted file mode 100644 index fe2e0255c084..000000000000 --- a/arch/arm/mach-lh7a40x/include/mach/clocks.h +++ /dev/null @@ -1,18 +0,0 @@ -/* arch/arm/mach-lh7a40x/include/mach/clocks.h - * - * Copyright (C) 2004 Marc Singer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -#ifndef __ASM_ARCH_CLOCKS_H -#define __ASM_ARCH_CLOCKS_H - -unsigned int fclkfreq_get (void); -unsigned int hclkfreq_get (void); -unsigned int pclkfreq_get (void); - -#endif /* _ASM_ARCH_CLOCKS_H */ diff --git a/arch/arm/mach-lh7a40x/include/mach/constants.h b/arch/arm/mach-lh7a40x/include/mach/constants.h deleted file mode 100644 index 55c6edbc2dfd..000000000000 --- a/arch/arm/mach-lh7a40x/include/mach/constants.h +++ /dev/null @@ -1,91 +0,0 @@ -/* arch/arm/mach-lh7a40x/include/mach/constants.h - * - * Copyright (C) 2004 Coastal Environmental Systems - * Copyright (C) 2004 Logic Product Development - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -#ifndef __ASM_ARCH_CONSTANTS_H -#define __ASM_ARCH_CONSTANTS_H - - -/* Addressing constants */ - - /* SoC CPU IO addressing */ -#define IO_PHYS (0x80000000) -#define IO_VIRT (0xf8000000) -#define IO_SIZE (0x0000B000) - -#ifdef CONFIG_MACH_KEV7A400 -# define CPLD_PHYS (0x20000000) -# define CPLD_VIRT (0xf2000000) -# define CPLD_SIZE PAGE_SIZE -#endif - -#if defined (CONFIG_MACH_LPD7A400) || defined (CONFIG_MACH_LPD7A404) - -# define IOBARRIER_PHYS 0x10000000 /* Second bank, fastest timing */ -# define IOBARRIER_VIRT 0xf0000000 -# define IOBARRIER_SIZE PAGE_SIZE - -# define CF_PHYS 0x60200000 -# define CF_VIRT 0xf6020000 -# define CF_SIZE (8*1024) - - /* The IO mappings for the LPD CPLD are, unfortunately, sparse. */ -# define CPLDX_PHYS(x) (0x70000000 | ((x) << 20)) -# define CPLDX_VIRT(x) (0xf7000000 | ((x) << 16)) -# define CPLD00_PHYS CPLDX_PHYS (0x00) /* Wired LAN */ -# define CPLD00_VIRT CPLDX_VIRT (0x00) -# define CPLD00_SIZE PAGE_SIZE -# define CPLD02_PHYS CPLDX_PHYS (0x02) -# define CPLD02_VIRT CPLDX_VIRT (0x02) -# define CPLD02_SIZE PAGE_SIZE -# define CPLD06_PHYS CPLDX_PHYS (0x06) -# define CPLD06_VIRT CPLDX_VIRT (0x06) -# define CPLD06_SIZE PAGE_SIZE -# define CPLD08_PHYS CPLDX_PHYS (0x08) -# define CPLD08_VIRT CPLDX_VIRT (0x08) -# define CPLD08_SIZE PAGE_SIZE -# define CPLD0A_PHYS CPLDX_PHYS (0x0a) -# define CPLD0A_VIRT CPLDX_VIRT (0x0a) -# define CPLD0A_SIZE PAGE_SIZE -# define CPLD0C_PHYS CPLDX_PHYS (0x0c) -# define CPLD0C_VIRT CPLDX_VIRT (0x0c) -# define CPLD0C_SIZE PAGE_SIZE -# define CPLD0E_PHYS CPLDX_PHYS (0x0e) -# define CPLD0E_VIRT CPLDX_VIRT (0x0e) -# define CPLD0E_SIZE PAGE_SIZE -# define CPLD10_PHYS CPLDX_PHYS (0x10) -# define CPLD10_VIRT CPLDX_VIRT (0x10) -# define CPLD10_SIZE PAGE_SIZE -# define CPLD12_PHYS CPLDX_PHYS (0x12) -# define CPLD12_VIRT CPLDX_VIRT (0x12) -# define CPLD12_SIZE PAGE_SIZE -# define CPLD14_PHYS CPLDX_PHYS (0x14) -# define CPLD14_VIRT CPLDX_VIRT (0x14) -# define CPLD14_SIZE PAGE_SIZE -# define CPLD16_PHYS CPLDX_PHYS (0x16) -# define CPLD16_VIRT CPLDX_VIRT (0x16) -# define CPLD16_SIZE PAGE_SIZE -# define CPLD18_PHYS CPLDX_PHYS (0x18) -# define CPLD18_VIRT CPLDX_VIRT (0x18) -# define CPLD18_SIZE PAGE_SIZE -# define CPLD1A_PHYS CPLDX_PHYS (0x1a) -# define CPLD1A_VIRT CPLDX_VIRT (0x1a) -# define CPLD1A_SIZE PAGE_SIZE -#endif - - /* Timing constants */ - -#define XTAL_IN 14745600 /* 14.7456 MHz crystal */ -#define PLL_CLOCK (XTAL_IN * 21) /* 309 MHz PLL clock */ -#define MAX_HCLK_KHZ 100000 /* HCLK max limit ~100MHz */ -#define HCLK (99993600) -//#define HCLK (119808000) - -#endif /* __ASM_ARCH_CONSTANTS_H */ diff --git a/arch/arm/mach-lh7a40x/include/mach/debug-macro.S b/arch/arm/mach-lh7a40x/include/mach/debug-macro.S deleted file mode 100644 index cff33625276f..000000000000 --- a/arch/arm/mach-lh7a40x/include/mach/debug-macro.S +++ /dev/null @@ -1,37 +0,0 @@ -/* arch/arm/mach-lh7a40x/include/mach/debug-macro.S - * - * Debugging macro include header - * - * Copyright (C) 1994-1999 Russell King - * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * -*/ - - @ It is not known if this will be appropriate for every 40x - @ board. - - .macro addruart, rp, rv - mov \rp, #0x00000700 @ offset from base - orr \rv, \rp, #0xf8000000 @ virtual base - orr \rp, \rp, #0x80000000 @ physical base - .endm - - .macro senduart,rd,rx - strb \rd, [\rx] @ DATA - .endm - - .macro busyuart,rd,rx @ spin while busy -1001: ldr \rd, [\rx, #0x10] @ STATUS - tst \rd, #1 << 3 @ BUSY (TX FIFO not empty) - bne 1001b @ yes, spin - .endm - - .macro waituart,rd,rx @ wait for Tx FIFO room -1001: ldrb \rd, [\rx, #0x10] @ STATUS - tst \rd, #1 << 5 @ TXFF (TX FIFO full) - bne 1001b @ yes, spin - .endm diff --git a/arch/arm/mach-lh7a40x/include/mach/dma.h b/arch/arm/mach-lh7a40x/include/mach/dma.h deleted file mode 100644 index baa3f8dbd04b..000000000000 --- a/arch/arm/mach-lh7a40x/include/mach/dma.h +++ /dev/null @@ -1,86 +0,0 @@ -/* arch/arm/mach-lh7a40x/include/mach/dma.h - * - * Copyright (C) 2005 Marc Singer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -typedef enum { - DMA_M2M0 = 0, - DMA_M2M1 = 1, - DMA_M2P0 = 2, /* Tx */ - DMA_M2P1 = 3, /* Rx */ - DMA_M2P2 = 4, /* Tx */ - DMA_M2P3 = 5, /* Rx */ - DMA_M2P4 = 6, /* Tx - AC97 */ - DMA_M2P5 = 7, /* Rx - AC97 */ - DMA_M2P6 = 8, /* Tx */ - DMA_M2P7 = 9, /* Rx */ -} dma_device_t; - -#define DMA_LENGTH_MAX ((64*1024) - 4) /* bytes */ - -#define DMAC_GCA __REG(DMAC_PHYS + 0x2b80) -#define DMAC_GIR __REG(DMAC_PHYS + 0x2bc0) - -#define DMAC_GIR_MMI1 (1<<11) -#define DMAC_GIR_MMI0 (1<<10) -#define DMAC_GIR_MPI8 (1<<9) -#define DMAC_GIR_MPI9 (1<<8) -#define DMAC_GIR_MPI6 (1<<7) -#define DMAC_GIR_MPI7 (1<<6) -#define DMAC_GIR_MPI4 (1<<5) -#define DMAC_GIR_MPI5 (1<<4) -#define DMAC_GIR_MPI2 (1<<3) -#define DMAC_GIR_MPI3 (1<<2) -#define DMAC_GIR_MPI0 (1<<1) -#define DMAC_GIR_MPI1 (1<<0) - -#define DMAC_M2P0 0x0000 -#define DMAC_M2P1 0x0040 -#define DMAC_M2P2 0x0080 -#define DMAC_M2P3 0x00c0 -#define DMAC_M2P4 0x0240 -#define DMAC_M2P5 0x0200 -#define DMAC_M2P6 0x02c0 -#define DMAC_M2P7 0x0280 -#define DMAC_M2P8 0x0340 -#define DMAC_M2P9 0x0300 -#define DMAC_M2M0 0x0100 -#define DMAC_M2M1 0x0140 - -#define DMAC_P_PCONTROL(c) __REG(DMAC_PHYS + (c) + 0x00) -#define DMAC_P_PINTERRUPT(c) __REG(DMAC_PHYS + (c) + 0x04) -#define DMAC_P_PPALLOC(c) __REG(DMAC_PHYS + (c) + 0x08) -#define DMAC_P_PSTATUS(c) __REG(DMAC_PHYS + (c) + 0x0c) -#define DMAC_P_REMAIN(c) __REG(DMAC_PHYS + (c) + 0x14) -#define DMAC_P_MAXCNT0(c) __REG(DMAC_PHYS + (c) + 0x20) -#define DMAC_P_BASE0(c) __REG(DMAC_PHYS + (c) + 0x24) -#define DMAC_P_CURRENT0(c) __REG(DMAC_PHYS + (c) + 0x28) -#define DMAC_P_MAXCNT1(c) __REG(DMAC_PHYS + (c) + 0x30) -#define DMAC_P_BASE1(c) __REG(DMAC_PHYS + (c) + 0x34) -#define DMAC_P_CURRENT1(c) __REG(DMAC_PHYS + (c) + 0x38) - -#define DMAC_PCONTROL_ENABLE (1<<4) - -#define DMAC_PORT_USB 0 -#define DMAC_PORT_SDMMC 1 -#define DMAC_PORT_AC97_1 2 -#define DMAC_PORT_AC97_2 3 -#define DMAC_PORT_AC97_3 4 -#define DMAC_PORT_UART1 6 -#define DMAC_PORT_UART2 7 -#define DMAC_PORT_UART3 8 - -#define DMAC_PSTATUS_CURRSTATE_SHIFT 4 -#define DMAC_PSTATUS_CURRSTATE_MASK 0x3 - -#define DMAC_PSTATUS_NEXTBUF (1<<6) -#define DMAC_PSTATUS_STALLRINT (1<<0) - -#define DMAC_INT_CHE (1<<3) -#define DMAC_INT_NFB (1<<1) -#define DMAC_INT_STALL (1<<0) diff --git a/arch/arm/mach-lh7a40x/include/mach/entry-macro.S b/arch/arm/mach-lh7a40x/include/mach/entry-macro.S deleted file mode 100644 index 069bb4cefff7..000000000000 --- a/arch/arm/mach-lh7a40x/include/mach/entry-macro.S +++ /dev/null @@ -1,149 +0,0 @@ -/* - * arch/arm/mach-lh7a40x/include/mach/entry-macro.S - * - * Low-level IRQ helper macros for LH7A40x platforms - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ -#include -#include - -/* In order to allow there to be support for both of the processor - classes at the same time, we make a hack here that isn't very - pretty. At startup, the link pointed to with the - branch_irq_lh7a400 symbol is replaced with a NOP when the CPU is - detected as a lh7a404. - - *** FIXME: we should clean this up so that there is only one - implementation for each CPU's design. - -*/ - -#if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404) - - .macro disable_fiq - .endm - - .macro get_irqnr_preamble, base, tmp - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - -branch_irq_lh7a400: b 1000f - -@ Implementation of the LH7A404 get_irqnr_and_base. - - mov \irqnr, #0 @ VIC1 irq base - mov \base, #io_p2v(0x80000000) @ APB registers - add \base, \base, #0x8000 - ldr \tmp, [\base, #0x0030] @ VIC1_VECTADDR - tst \tmp, #VA_VECTORED @ Direct vectored - bne 1002f - tst \tmp, #VA_VIC1DEFAULT @ Default vectored VIC1 - ldrne \irqstat, [\base, #0] @ VIC1_IRQSTATUS - bne 1001f - add \base, \base, #(0xa000 - 0x8000) - ldr \tmp, [\base, #0x0030] @ VIC2_VECTADDR - tst \tmp, #VA_VECTORED @ Direct vectored - bne 1002f - ldr \irqstat, [\base, #0] @ VIC2_IRQSTATUS - mov \irqnr, #32 @ VIC2 irq base - -1001: movs \irqstat, \irqstat, lsr #1 @ Shift into carry - bcs 1008f @ Bit set; irq found - add \irqnr, \irqnr, #1 - bne 1001b @ Until no bits - b 1009f @ Nothing? Hmm. -1002: and \irqnr, \tmp, #0x3f @ Mask for valid bits -1008: movs \irqstat, #1 @ Force !Z - str \tmp, [\base, #0x0030] @ Clear vector - b 1009f - -@ Implementation of the LH7A400 get_irqnr_and_base. - -1000: mov \irqnr, #0 - mov \base, #io_p2v(0x80000000) @ APB registers - ldr \irqstat, [\base, #0x500] @ PIC INTSR - -1001: movs \irqstat, \irqstat, lsr #1 @ Shift into carry - bcs 1008f @ Bit set; irq found - add \irqnr, \irqnr, #1 - bne 1001b @ Until no bits - b 1009f @ Nothing? Hmm. -1008: movs \irqstat, #1 @ Force !Z - -1009: - .endm - - - -#elif defined (CONFIG_ARCH_LH7A400) - .macro disable_fiq - .endm - - .macro get_irqnr_preamble, base, tmp - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - mov \irqnr, #0 - mov \base, #io_p2v(0x80000000) @ APB registers - ldr \irqstat, [\base, #0x500] @ PIC INTSR - -1001: movs \irqstat, \irqstat, lsr #1 @ Shift into carry - bcs 1008f @ Bit set; irq found - add \irqnr, \irqnr, #1 - bne 1001b @ Until no bits - b 1009f @ Nothing? Hmm. -1008: movs \irqstat, #1 @ Force !Z -1009: - .endm - -#elif defined(CONFIG_ARCH_LH7A404) - - .macro disable_fiq - .endm - - .macro get_irqnr_preamble, base, tmp - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - mov \irqnr, #0 @ VIC1 irq base - mov \base, #io_p2v(0x80000000) @ APB registers - add \base, \base, #0x8000 - ldr \tmp, [\base, #0x0030] @ VIC1_VECTADDR - tst \tmp, #VA_VECTORED @ Direct vectored - bne 1002f - tst \tmp, #VA_VIC1DEFAULT @ Default vectored VIC1 - ldrne \irqstat, [\base, #0] @ VIC1_IRQSTATUS - bne 1001f - add \base, \base, #(0xa000 - 0x8000) - ldr \tmp, [\base, #0x0030] @ VIC2_VECTADDR - tst \tmp, #VA_VECTORED @ Direct vectored - bne 1002f - ldr \irqstat, [\base, #0] @ VIC2_IRQSTATUS - mov \irqnr, #32 @ VIC2 irq base - -1001: movs \irqstat, \irqstat, lsr #1 @ Shift into carry - bcs 1008f @ Bit set; irq found - add \irqnr, \irqnr, #1 - bne 1001b @ Until no bits - b 1009f @ Nothing? Hmm. -1002: and \irqnr, \tmp, #0x3f @ Mask for valid bits -1008: movs \irqstat, #1 @ Force !Z - str \tmp, [\base, #0x0030] @ Clear vector -1009: - .endm -#endif - - diff --git a/arch/arm/mach-lh7a40x/include/mach/hardware.h b/arch/arm/mach-lh7a40x/include/mach/hardware.h deleted file mode 100644 index 59d2ace35217..000000000000 --- a/arch/arm/mach-lh7a40x/include/mach/hardware.h +++ /dev/null @@ -1,62 +0,0 @@ -/* arch/arm/mach-lh7a40x/include/mach/hardware.h - * - * Copyright (C) 2004 Coastal Environmental Systems - * - * [ Substantially cribbed from arch/arm/mach-pxa/include/mach/hardware.h ] - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -#ifndef __ASM_ARCH_HARDWARE_H -#define __ASM_ARCH_HARDWARE_H - -#include /* Added for the sake of amba-clcd driver */ - -#define io_p2v(x) (0xf0000000 | (((x) & 0xfff00000) >> 4) | ((x) & 0x0000ffff)) -#define io_v2p(x) ( (((x) & 0x0fff0000) << 4) | ((x) & 0x0000ffff)) - -#ifdef __ASSEMBLY__ - -# define __REG(x) io_p2v(x) -# define __PREG(x) io_v2p(x) - -#else - -# if 0 -# define __REG(x) (*((volatile u32 *)io_p2v(x))) -# else -/* - * This __REG() version gives the same results as the one above, except - * that we are fooling gcc somehow so it generates far better and smaller - * assembly code for access to contiguous registers. It's a shame that gcc - * doesn't guess this by itself. - */ -#include -typedef struct { volatile u32 offset[4096]; } __regbase; -# define __REGP(x) ((__regbase *)((x)&~4095))->offset[((x)&4095)>>2] -# define __REG(x) __REGP(io_p2v(x)) -typedef struct { volatile u16 offset[4096]; } __regbase16; -# define __REGP16(x) ((__regbase16 *)((x)&~4095))->offset[((x)&4095)>>1] -# define __REG16(x) __REGP16(io_p2v(x)) -typedef struct { volatile u8 offset[4096]; } __regbase8; -# define __REGP8(x) ((__regbase8 *)((x)&~4095))->offset[(x)&4095] -# define __REG8(x) __REGP8(io_p2v(x)) -#endif - -/* Let's kick gcc's ass again... */ -# define __REG2(x,y) \ - ( __builtin_constant_p(y) ? (__REG((x) + (y))) \ - : (*(volatile u32 *)((u32)&__REG(x) + (y))) ) - -# define __PREG(x) (io_v2p((u32)&(x))) - -#endif - -#define MASK_AND_SET(v,m,s) (v) = ((v)&~(m))|(s) - -#include "registers.h" - -#endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/mach-lh7a40x/include/mach/io.h b/arch/arm/mach-lh7a40x/include/mach/io.h deleted file mode 100644 index 6ece45911cbc..000000000000 --- a/arch/arm/mach-lh7a40x/include/mach/io.h +++ /dev/null @@ -1,20 +0,0 @@ -/* arch/arm/mach-lh7a40x/include/mach/io.h - * - * Copyright (C) 2004 Coastal Environmental Systems - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -#ifndef __ASM_ARCH_IO_H -#define __ASM_ARCH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -/* No ISA or PCI bus on this machine. */ -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#endif /* __ASM_ARCH_IO_H */ diff --git a/arch/arm/mach-lh7a40x/include/mach/irqs.h b/arch/arm/mach-lh7a40x/include/mach/irqs.h deleted file mode 100644 index 0f9b83675935..000000000000 --- a/arch/arm/mach-lh7a40x/include/mach/irqs.h +++ /dev/null @@ -1,200 +0,0 @@ -/* arch/arm/mach-lh7a40x/include/mach/irqs.h - * - * Copyright (C) 2004 Coastal Environmental Systems - * Copyright (C) 2004 Logic Product Development - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -/* It is to be seen whether or not we can build a kernel for more than - * one board. For the time being, these macros assume that we cannot. - * Thus, it is OK to ifdef machine/board specific IRQ assignments. - */ - - -#ifndef __ASM_ARCH_IRQS_H -#define __ASM_ARCH_IRQS_H - - -#define FIQ_START 80 - -#if defined (CONFIG_ARCH_LH7A400) - - /* FIQs */ - -# define IRQ_GPIO0FIQ 0 /* GPIO External FIQ Interrupt on F0 */ -# define IRQ_BLINT 1 /* Battery Low */ -# define IRQ_WEINT 2 /* Watchdog Timer, WDT overflow */ -# define IRQ_MCINT 3 /* Media Change, MEDCHG pin rising */ - - /* IRQs */ - -# define IRQ_CSINT 4 /* Audio Codec (ACI) */ -# define IRQ_GPIO1INTR 5 /* GPIO External IRQ Interrupt on F1 */ -# define IRQ_GPIO2INTR 6 /* GPIO External IRQ Interrupt on F2 */ -# define IRQ_GPIO3INTR 7 /* GPIO External IRQ Interrupt on F3 */ -# define IRQ_T1UI 8 /* Timer 1 underflow */ -# define IRQ_T2UI 9 /* Timer 2 underflow */ -# define IRQ_RTCMI 10 -# define IRQ_TINTR 11 /* Clock State Controller 64 Hz tick (CSC) */ -# define IRQ_UART1INTR 12 -# define IRQ_UART2INTR 13 -# define IRQ_LCDINTR 14 -# define IRQ_SSIEOT 15 /* Synchronous Serial Interface (SSI) */ -# define IRQ_UART3INTR 16 -# define IRQ_SCIINTR 17 /* Smart Card Interface (SCI) */ -# define IRQ_AACINTR 18 /* Advanced Audio Codec (AAC) */ -# define IRQ_MMCINTR 19 /* Multimedia Card (MMC) */ -# define IRQ_USBINTR 20 -# define IRQ_DMAINTR 21 -# define IRQ_T3UI 22 /* Timer 3 underflow */ -# define IRQ_GPIO4INTR 23 /* GPIO External IRQ Interrupt on F4 */ -# define IRQ_GPIO5INTR 24 /* GPIO External IRQ Interrupt on F5 */ -# define IRQ_GPIO6INTR 25 /* GPIO External IRQ Interrupt on F6 */ -# define IRQ_GPIO7INTR 26 /* GPIO External IRQ Interrupt on F7 */ -# define IRQ_BMIINTR 27 /* Battery Monitor Interface (BMI) */ - -# define NR_IRQ_CPU 28 /* IRQs directly recognized by CPU */ - - /* Given IRQ, return GPIO interrupt number 0-7 */ -# define IRQ_TO_GPIO(i) ((i) \ - - (((i) > IRQ_GPIO3INTR) ? IRQ_GPIO4INTR - IRQ_GPIO3INTR - 1 : 0)\ - - (((i) > IRQ_GPIO0INTR) ? IRQ_GPIO1INTR - IRQ_GPIO0INTR - 1 : 0)) - -#endif - -#if defined (CONFIG_ARCH_LH7A404) - -# define IRQ_BROWN 0 /* Brownout */ -# define IRQ_WDTINTR 1 /* Watchdog Timer */ -# define IRQ_COMMRX 2 /* ARM Comm Rx for Debug */ -# define IRQ_COMMTX 3 /* ARM Comm Tx for Debug */ -# define IRQ_T1UI 4 /* Timer 1 underflow */ -# define IRQ_T2UI 5 /* Timer 2 underflow */ -# define IRQ_CSINT 6 /* Codec Interrupt (shared by AAC on 404) */ -# define IRQ_DMAM2P0 7 /* -- DMA Memory to Peripheral */ -# define IRQ_DMAM2P1 8 -# define IRQ_DMAM2P2 9 -# define IRQ_DMAM2P3 10 -# define IRQ_DMAM2P4 11 -# define IRQ_DMAM2P5 12 -# define IRQ_DMAM2P6 13 -# define IRQ_DMAM2P7 14 -# define IRQ_DMAM2P8 15 -# define IRQ_DMAM2P9 16 -# define IRQ_DMAM2M0 17 /* -- DMA Memory to Memory */ -# define IRQ_DMAM2M1 18 -# define IRQ_GPIO0INTR 19 /* -- GPIOF Interrupt */ -# define IRQ_GPIO1INTR 20 -# define IRQ_GPIO2INTR 21 -# define IRQ_GPIO3INTR 22 -# define IRQ_SOFT_V1_23 23 /* -- Unassigned */ -# define IRQ_SOFT_V1_24 24 -# define IRQ_SOFT_V1_25 25 -# define IRQ_SOFT_V1_26 26 -# define IRQ_SOFT_V1_27 27 -# define IRQ_SOFT_V1_28 28 -# define IRQ_SOFT_V1_29 29 -# define IRQ_SOFT_V1_30 30 -# define IRQ_SOFT_V1_31 31 - -# define IRQ_BLINT 32 /* Battery Low */ -# define IRQ_BMIINTR 33 /* Battery Monitor */ -# define IRQ_MCINTR 34 /* Media Change */ -# define IRQ_TINTR 35 /* 64Hz Tick */ -# define IRQ_WEINT 36 /* Watchdog Expired */ -# define IRQ_RTCMI 37 /* Real-time Clock Match */ -# define IRQ_UART1INTR 38 /* UART1 Interrupt (including error) */ -# define IRQ_UART1ERR 39 /* UART1 Error */ -# define IRQ_UART2INTR 40 /* UART2 Interrupt (including error) */ -# define IRQ_UART2ERR 41 /* UART2 Error */ -# define IRQ_UART3INTR 42 /* UART3 Interrupt (including error) */ -# define IRQ_UART3ERR 43 /* UART3 Error */ -# define IRQ_SCIINTR 44 /* Smart Card */ -# define IRQ_TSCINTR 45 /* Touchscreen */ -# define IRQ_KMIINTR 46 /* Keyboard/Mouse (PS/2) */ -# define IRQ_GPIO4INTR 47 /* -- GPIOF Interrupt */ -# define IRQ_GPIO5INTR 48 -# define IRQ_GPIO6INTR 49 -# define IRQ_GPIO7INTR 50 -# define IRQ_T3UI 51 /* Timer 3 underflow */ -# define IRQ_LCDINTR 52 /* LCD Controller */ -# define IRQ_SSPINTR 53 /* Synchronous Serial Port */ -# define IRQ_SDINTR 54 /* Secure Digital Port (MMC) */ -# define IRQ_USBINTR 55 /* USB Device Port */ -# define IRQ_USHINTR 56 /* USB Host Port */ -# define IRQ_SOFT_V2_25 57 /* -- Unassigned */ -# define IRQ_SOFT_V2_26 58 -# define IRQ_SOFT_V2_27 59 -# define IRQ_SOFT_V2_28 60 -# define IRQ_SOFT_V2_29 61 -# define IRQ_SOFT_V2_30 62 -# define IRQ_SOFT_V2_31 63 - -# define NR_IRQ_CPU 64 /* IRQs directly recognized by CPU */ - - /* Given IRQ, return GPIO interrupt number 0-7 */ -# define IRQ_TO_GPIO(i) ((i) \ - - (((i) > IRQ_GPIO3INTR) ? IRQ_GPIO4INTR - IRQ_GPIO3INTR - 1 : 0)\ - - IRQ_GPIO0INTR) - - /* Vector Address constants */ -# define VA_VECTORED 0x100 /* Set for vectored interrupt */ -# define VA_VIC1DEFAULT 0x200 /* Set as default VECTADDR for VIC1 */ -# define VA_VIC2DEFAULT 0x400 /* Set as default VECTADDR for VIC2 */ - -#endif - - /* IRQ aliases */ - -#if !defined (IRQ_GPIO0INTR) -# define IRQ_GPIO0INTR IRQ_GPIO0FIQ -#endif -#define IRQ_TICK IRQ_TINTR -#define IRQ_PCC1_RDY IRQ_GPIO6INTR /* PCCard 1 ready */ -#define IRQ_PCC2_RDY IRQ_GPIO7INTR /* PCCard 2 ready */ -#define IRQ_USB IRQ_USBINTR /* USB device */ - -#ifdef CONFIG_MACH_KEV7A400 -# define IRQ_TS IRQ_GPIOFIQ /* Touchscreen */ -# define IRQ_CPLD IRQ_GPIO1INTR /* CPLD cascade */ -# define IRQ_PCC1_CD IRQ_GPIO_F2 /* PCCard 1 card detect */ -# define IRQ_PCC2_CD IRQ_GPIO_F3 /* PCCard 2 card detect */ -#endif - -#if defined (CONFIG_MACH_LPD7A400) || defined (CONFIG_MACH_LPD7A404) -# define IRQ_CPLD_V28 IRQ_GPIO7INTR /* CPLD cascade through GPIO_PF7 */ -# define IRQ_CPLD_V34 IRQ_GPIO3INTR /* CPLD cascade through GPIO_PF3 */ -#endif - - /* System specific IRQs */ - -#define IRQ_BOARD_START NR_IRQ_CPU - -#ifdef CONFIG_MACH_KEV7A400 -# define IRQ_KEV7A400_CPLD IRQ_BOARD_START -# define NR_IRQ_BOARD 5 -# define IRQ_KEV7A400_MMC_CD IRQ_KEV7A400_CPLD + 0 /* MMC Card Detect */ -# define IRQ_KEV7A400_RI2 IRQ_KEV7A400_CPLD + 1 /* Ring Indicator 2 */ -# define IRQ_KEV7A400_IDE_CF IRQ_KEV7A400_CPLD + 2 /* Compact Flash (?) */ -# define IRQ_KEV7A400_ETH_INT IRQ_KEV7A400_CPLD + 3 /* Ethernet chip */ -# define IRQ_KEV7A400_INT IRQ_KEV7A400_CPLD + 4 -#endif - -#if defined (CONFIG_MACH_LPD7A400) || defined (CONFIG_MACH_LPD7A404) -# define IRQ_LPD7A40X_CPLD IRQ_BOARD_START -# define NR_IRQ_BOARD 2 -# define IRQ_LPD7A40X_ETH_INT IRQ_LPD7A40X_CPLD + 0 /* Ethernet chip */ -# define IRQ_LPD7A400_TS IRQ_LPD7A40X_CPLD + 1 /* Touch screen */ -#endif - -#if defined (CONFIG_MACH_LPD7A400) -# define IRQ_TOUCH IRQ_LPD7A400_TS -#endif - -#define NR_IRQS (NR_IRQ_CPU + NR_IRQ_BOARD) - -#endif diff --git a/arch/arm/mach-lh7a40x/include/mach/memory.h b/arch/arm/mach-lh7a40x/include/mach/memory.h deleted file mode 100644 index edb8f5faf5d5..000000000000 --- a/arch/arm/mach-lh7a40x/include/mach/memory.h +++ /dev/null @@ -1,28 +0,0 @@ -/* arch/arm/mach-lh7a40x/include/mach/memory.h - * - * Copyright (C) 2004 Coastal Environmental Systems - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * - * Refer to for more information. - * - */ - -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -/* - * Physical DRAM offset. - */ -#define PHYS_OFFSET UL(0xc0000000) - -/* - * Sparsemem version of the above - */ -#define MAX_PHYSMEM_BITS 32 -#define SECTION_SIZE_BITS 24 - -#endif diff --git a/arch/arm/mach-lh7a40x/include/mach/registers.h b/arch/arm/mach-lh7a40x/include/mach/registers.h deleted file mode 100644 index ea44396383a7..000000000000 --- a/arch/arm/mach-lh7a40x/include/mach/registers.h +++ /dev/null @@ -1,224 +0,0 @@ -/* arch/arm/mach-lh7a40x/include/mach/registers.h - * - * Copyright (C) 2004 Coastal Environmental Systems - * Copyright (C) 2004 Logic Product Development - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -#include - -#ifndef __ASM_ARCH_REGISTERS_H -#define __ASM_ARCH_REGISTERS_H - - - /* Physical register base addresses */ - -#define AC97C_PHYS (0x80000000) /* AC97 Controller */ -#define MMC_PHYS (0x80000100) /* Multimedia Card Controller */ -#define USB_PHYS (0x80000200) /* USB Client */ -#define SCI_PHYS (0x80000300) /* Secure Card Interface */ -#define CSC_PHYS (0x80000400) /* Clock/State Controller */ -#define INTC_PHYS (0x80000500) /* Interrupt Controller */ -#define UART1_PHYS (0x80000600) /* UART1 Controller */ -#define SIR_PHYS (0x80000600) /* IR Controller, same are UART1 */ -#define UART2_PHYS (0x80000700) /* UART2 Controller */ -#define UART3_PHYS (0x80000800) /* UART3 Controller */ -#define DCDC_PHYS (0x80000900) /* DC to DC Controller */ -#define ACI_PHYS (0x80000a00) /* Audio Codec Interface */ -#define SSP_PHYS (0x80000b00) /* Synchronous ... */ -#define TIMER_PHYS (0x80000c00) /* Timer Controller */ -#define RTC_PHYS (0x80000d00) /* Real-time Clock */ -#define GPIO_PHYS (0x80000e00) /* General Purpose IO */ -#define BMI_PHYS (0x80000f00) /* Battery Monitor Interface */ -#define HRTFTC_PHYS (0x80001000) /* High-res TFT Controller (LH7A400) */ -#define ALI_PHYS (0x80001000) /* Advanced LCD Interface (LH7A404) */ -#define WDT_PHYS (0x80001400) /* Watchdog Timer */ -#define SMC_PHYS (0x80002000) /* Static Memory Controller */ -#define SDRC_PHYS (0x80002400) /* SDRAM Controller */ -#define DMAC_PHYS (0x80002800) /* DMA Controller */ -#define CLCDC_PHYS (0x80003000) /* Color LCD Controller */ - - /* Physical registers of the LH7A404 */ - -#define ADC_PHYS (0x80001300) /* A/D & Touchscreen Controller */ -#define VIC1_PHYS (0x80008000) /* Vectored Interrupt Controller 1 */ -#define USBH_PHYS (0x80009000) /* USB OHCI host controller */ -#define VIC2_PHYS (0x8000a000) /* Vectored Interrupt Controller 2 */ - -/*#define KBD_PHYS (0x80000e00) */ -/*#define LCDICP_PHYS (0x80001000) */ - - - /* Clock/State Controller register */ - -#define CSC_PWRSR __REG(CSC_PHYS + 0x00) /* Reset register & ID */ -#define CSC_PWRCNT __REG(CSC_PHYS + 0x04) /* Power control */ -#define CSC_CLKSET __REG(CSC_PHYS + 0x20) /* Clock speed control */ -#define CSC_USBDRESET __REG(CSC_PHYS + 0x4c) /* USB Device resets */ - -#define CSC_PWRCNT_USBH_EN (1<<28) /* USB Host power enable */ -#define CSC_PWRCNT_DMAC_M2M1_EN (1<<27) -#define CSC_PWRCNT_DMAC_M2M0_EN (1<<26) -#define CSC_PWRCNT_DMAC_M2P8_EN (1<<25) -#define CSC_PWRCNT_DMAC_M2P9_EN (1<<24) -#define CSC_PWRCNT_DMAC_M2P6_EN (1<<23) -#define CSC_PWRCNT_DMAC_M2P7_EN (1<<22) -#define CSC_PWRCNT_DMAC_M2P4_EN (1<<21) -#define CSC_PWRCNT_DMAC_M2P5_EN (1<<20) -#define CSC_PWRCNT_DMAC_M2P2_EN (1<<19) -#define CSC_PWRCNT_DMAC_M2P3_EN (1<<18) -#define CSC_PWRCNT_DMAC_M2P0_EN (1<<17) -#define CSC_PWRCNT_DMAC_M2P1_EN (1<<16) - -#define CSC_PWRSR_CHIPMAN_SHIFT (24) -#define CSC_PWRSR_CHIPMAN_MASK (0xff) -#define CSC_PWRSR_CHIPID_SHIFT (16) -#define CSC_PWRSR_CHIPID_MASK (0xff) - -#define CSC_USBDRESET_APBRESETREG (1<<1) -#define CSC_USBDRESET_IORESETREG (1<<0) - - /* Interrupt Controller registers */ - -#define INTC_INTSR __REG(INTC_PHYS + 0x00) /* Status */ -#define INTC_INTRSR __REG(INTC_PHYS + 0x04) /* Raw Status */ -#define INTC_INTENS __REG(INTC_PHYS + 0x08) /* Enable Set */ -#define INTC_INTENC __REG(INTC_PHYS + 0x0c) /* Enable Clear */ - - - /* Vectored Interrupted Controller registers */ - -#define VIC1_IRQSTATUS __REG(VIC1_PHYS + 0x00) -#define VIC1_FIQSTATUS __REG(VIC1_PHYS + 0x04) -#define VIC1_RAWINTR __REG(VIC1_PHYS + 0x08) -#define VIC1_INTSEL __REG(VIC1_PHYS + 0x0c) -#define VIC1_INTEN __REG(VIC1_PHYS + 0x10) -#define VIC1_INTENCLR __REG(VIC1_PHYS + 0x14) -#define VIC1_SOFTINT __REG(VIC1_PHYS + 0x18) -#define VIC1_SOFTINTCLR __REG(VIC1_PHYS + 0x1c) -#define VIC1_PROTECT __REG(VIC1_PHYS + 0x20) -#define VIC1_VECTADDR __REG(VIC1_PHYS + 0x30) -#define VIC1_NVADDR __REG(VIC1_PHYS + 0x34) -#define VIC1_VAD0 __REG(VIC1_PHYS + 0x100) -#define VIC1_VECTCNTL0 __REG(VIC1_PHYS + 0x200) -#define VIC2_IRQSTATUS __REG(VIC2_PHYS + 0x00) -#define VIC2_FIQSTATUS __REG(VIC2_PHYS + 0x04) -#define VIC2_RAWINTR __REG(VIC2_PHYS + 0x08) -#define VIC2_INTSEL __REG(VIC2_PHYS + 0x0c) -#define VIC2_INTEN __REG(VIC2_PHYS + 0x10) -#define VIC2_INTENCLR __REG(VIC2_PHYS + 0x14) -#define VIC2_SOFTINT __REG(VIC2_PHYS + 0x18) -#define VIC2_SOFTINTCLR __REG(VIC2_PHYS + 0x1c) -#define VIC2_PROTECT __REG(VIC2_PHYS + 0x20) -#define VIC2_VECTADDR __REG(VIC2_PHYS + 0x30) -#define VIC2_NVADDR __REG(VIC2_PHYS + 0x34) -#define VIC2_VAD0 __REG(VIC2_PHYS + 0x100) -#define VIC2_VECTCNTL0 __REG(VIC2_PHYS + 0x200) - -#define VIC_CNTL_ENABLE (0x20) - - /* USB Host registers (Open HCI compatible) */ - -#define USBH_CMDSTATUS __REG(USBH_PHYS + 0x08) - - - /* GPIO registers */ - -#define GPIO_INTTYPE1 __REG(GPIO_PHYS + 0x4c) /* Interrupt Type 1 (Edge) */ -#define GPIO_INTTYPE2 __REG(GPIO_PHYS + 0x50) /* Interrupt Type 2 */ -#define GPIO_GPIOFEOI __REG(GPIO_PHYS + 0x54) /* GPIO End-of-Interrupt */ -#define GPIO_GPIOINTEN __REG(GPIO_PHYS + 0x58) /* GPIO Interrupt Enable */ -#define GPIO_INTSTATUS __REG(GPIO_PHYS + 0x5c) /* GPIO Interrupt Status */ -#define GPIO_PINMUX __REG(GPIO_PHYS + 0x2c) -#define GPIO_PADD __REG(GPIO_PHYS + 0x10) -#define GPIO_PAD __REG(GPIO_PHYS + 0x00) -#define GPIO_PCD __REG(GPIO_PHYS + 0x08) -#define GPIO_PCDD __REG(GPIO_PHYS + 0x18) -#define GPIO_PEDD __REG(GPIO_PHYS + 0x24) -#define GPIO_PED __REG(GPIO_PHYS + 0x20) - - - /* Static Memory Controller registers */ - -#define SMC_BCR0 __REG(SMC_PHYS + 0x00) /* Bank 0 Configuration */ -#define SMC_BCR1 __REG(SMC_PHYS + 0x04) /* Bank 1 Configuration */ -#define SMC_BCR2 __REG(SMC_PHYS + 0x08) /* Bank 2 Configuration */ -#define SMC_BCR3 __REG(SMC_PHYS + 0x0C) /* Bank 3 Configuration */ -#define SMC_BCR6 __REG(SMC_PHYS + 0x18) /* Bank 6 Configuration */ -#define SMC_BCR7 __REG(SMC_PHYS + 0x1c) /* Bank 7 Configuration */ - - -#ifdef CONFIG_MACH_KEV7A400 -# define CPLD_RD_OPT_DIP_SW __REG16(CPLD_PHYS + 0x00) /* Read Option SW */ -# define CPLD_WR_IO_BRD_CTL __REG16(CPLD_PHYS + 0x00) /* Write Control */ -# define CPLD_RD_PB_KEYS __REG16(CPLD_PHYS + 0x02) /* Read Btn Keys */ -# define CPLD_LATCHED_INTS __REG16(CPLD_PHYS + 0x04) /* Read INTR stat. */ -# define CPLD_CL_INT __REG16(CPLD_PHYS + 0x04) /* Clear INTR stat */ -# define CPLD_BOOT_MMC_STATUS __REG16(CPLD_PHYS + 0x06) /* R/O */ -# define CPLD_RD_KPD_ROW_SENSE __REG16(CPLD_PHYS + 0x08) -# define CPLD_WR_PB_INT_MASK __REG16(CPLD_PHYS + 0x08) -# define CPLD_RD_BRD_DISP_SW __REG16(CPLD_PHYS + 0x0a) -# define CPLD_WR_EXT_INT_MASK __REG16(CPLD_PHYS + 0x0a) -# define CPLD_LCD_PWR_CNTL __REG16(CPLD_PHYS + 0x0c) -# define CPLD_SEVEN_SEG __REG16(CPLD_PHYS + 0x0e) /* 7 seg. LED mask */ - -#endif - -#if defined (CONFIG_MACH_LPD7A400) || defined (CONFIG_MACH_LPD7A404) - -# define CPLD_CONTROL __REG16(CPLD02_PHYS) -# define CPLD_SPI_DATA __REG16(CPLD06_PHYS) -# define CPLD_SPI_CONTROL __REG16(CPLD08_PHYS) -# define CPLD_SPI_EEPROM __REG16(CPLD0A_PHYS) -# define CPLD_INTERRUPTS __REG16(CPLD0C_PHYS) /* IRQ mask/status */ -# define CPLD_BOOT_MODE __REG16(CPLD0E_PHYS) -# define CPLD_FLASH __REG16(CPLD10_PHYS) -# define CPLD_POWER_MGMT __REG16(CPLD12_PHYS) -# define CPLD_REVISION __REG16(CPLD14_PHYS) -# define CPLD_GPIO_EXT __REG16(CPLD16_PHYS) -# define CPLD_GPIO_DATA __REG16(CPLD18_PHYS) -# define CPLD_GPIO_DIR __REG16(CPLD1A_PHYS) - -#endif - - /* Timer registers */ - -#define TIMER_LOAD1 __REG(TIMER_PHYS + 0x00) /* Timer 1 initial value */ -#define TIMER_VALUE1 __REG(TIMER_PHYS + 0x04) /* Timer 1 current value */ -#define TIMER_CONTROL1 __REG(TIMER_PHYS + 0x08) /* Timer 1 control word */ -#define TIMER_EOI1 __REG(TIMER_PHYS + 0x0c) /* Timer 1 interrupt clear */ - -#define TIMER_LOAD2 __REG(TIMER_PHYS + 0x20) /* Timer 2 initial value */ -#define TIMER_VALUE2 __REG(TIMER_PHYS + 0x24) /* Timer 2 current value */ -#define TIMER_CONTROL2 __REG(TIMER_PHYS + 0x28) /* Timer 2 control word */ -#define TIMER_EOI2 __REG(TIMER_PHYS + 0x2c) /* Timer 2 interrupt clear */ - -#define TIMER_BUZZCON __REG(TIMER_PHYS + 0x40) /* Buzzer configuration */ - -#define TIMER_LOAD3 __REG(TIMER_PHYS + 0x80) /* Timer 3 initial value */ -#define TIMER_VALUE3 __REG(TIMER_PHYS + 0x84) /* Timer 3 current value */ -#define TIMER_CONTROL3 __REG(TIMER_PHYS + 0x88) /* Timer 3 control word */ -#define TIMER_EOI3 __REG(TIMER_PHYS + 0x8c) /* Timer 3 interrupt clear */ - -#define TIMER_C_ENABLE (1<<7) -#define TIMER_C_PERIODIC (1<<6) -#define TIMER_C_FREERUNNING (0) -#define TIMER_C_2KHZ (0x00) /* 1.986 kHz */ -#define TIMER_C_508KHZ (0x08) - - /* GPIO registers */ - -#define GPIO_PFDD __REG(GPIO_PHYS + 0x34) /* PF direction */ -#define GPIO_INTTYPE1 __REG(GPIO_PHYS + 0x4c) /* IRQ edge or lvl */ -#define GPIO_INTTYPE2 __REG(GPIO_PHYS + 0x50) /* IRQ activ hi/lo */ -#define GPIO_GPIOFEOI __REG(GPIO_PHYS + 0x54) /* GPIOF end of IRQ */ -#define GPIO_GPIOFINTEN __REG(GPIO_PHYS + 0x58) /* GPIOF IRQ enable */ -#define GPIO_INTSTATUS __REG(GPIO_PHYS + 0x5c) /* GPIOF IRQ latch */ -#define GPIO_RAWINTSTATUS __REG(GPIO_PHYS + 0x60) /* GPIOF IRQ raw */ - - -#endif /* _ASM_ARCH_REGISTERS_H */ diff --git a/arch/arm/mach-lh7a40x/include/mach/ssp.h b/arch/arm/mach-lh7a40x/include/mach/ssp.h deleted file mode 100644 index 509916182e34..000000000000 --- a/arch/arm/mach-lh7a40x/include/mach/ssp.h +++ /dev/null @@ -1,70 +0,0 @@ -/* ssp.h - - written by Marc Singer - 6 Dec 2004 - - Copyright (C) 2004 Marc Singer - - ----------- - DESCRIPTION - ----------- - - This SSP header is available throughout the kernel, for this - machine/architecture, because drivers that use it may be dispersed. - - This file was cloned from the 7952x implementation. It would be - better to share them, but we're taking an easier approach for the - time being. - -*/ - -#if !defined (__SSP_H__) -# define __SSP_H__ - -/* ----- Includes */ - -/* ----- Types */ - -struct ssp_driver { - int (*init) (void); - void (*exit) (void); - void (*acquire) (void); - void (*release) (void); - int (*configure) (int device, int mode, int speed, - int frame_size_write, int frame_size_read); - void (*chip_select) (int enable); - void (*set_callbacks) (void* handle, - irqreturn_t (*callback_tx)(void*), - irqreturn_t (*callback_rx)(void*)); - void (*enable) (void); - void (*disable) (void); -// int (*save_state) (void*); -// void (*restore_state) (void*); - int (*read) (void); - int (*write) (u16 data); - int (*write_read) (u16 data); - void (*flush) (void); - void (*write_async) (void* pv, size_t cb); - size_t (*write_pos) (void); -}; - - /* These modes are only available on the LH79524 */ -#define SSP_MODE_SPI (1) -#define SSP_MODE_SSI (2) -#define SSP_MODE_MICROWIRE (3) -#define SSP_MODE_I2S (4) - - /* CPLD SPI devices */ -#define DEVICE_EEPROM 0 /* Configuration eeprom */ -#define DEVICE_MAC 1 /* MAC eeprom (LPD79524) */ -#define DEVICE_CODEC 2 /* Audio codec */ -#define DEVICE_TOUCH 3 /* Touch screen (LPD79520) */ - -/* ----- Globals */ - -/* ----- Prototypes */ - -//extern struct ssp_driver lh79520_i2s_driver; -extern struct ssp_driver lh7a400_cpld_ssp_driver; - -#endif /* __SSP_H__ */ diff --git a/arch/arm/mach-lh7a40x/include/mach/system.h b/arch/arm/mach-lh7a40x/include/mach/system.h deleted file mode 100644 index 45a56d3b93d7..000000000000 --- a/arch/arm/mach-lh7a40x/include/mach/system.h +++ /dev/null @@ -1,19 +0,0 @@ -/* arch/arm/mach-lh7a40x/include/mach/system.h - * - * Copyright (C) 2004 Coastal Environmental Systems - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -static inline void arch_idle(void) -{ - cpu_do_idle (); -} - -static inline void arch_reset(char mode, const char *cmd) -{ - cpu_reset (0); -} diff --git a/arch/arm/mach-lh7a40x/include/mach/timex.h b/arch/arm/mach-lh7a40x/include/mach/timex.h deleted file mode 100644 index 08028cef1b3b..000000000000 --- a/arch/arm/mach-lh7a40x/include/mach/timex.h +++ /dev/null @@ -1,17 +0,0 @@ -/* arch/arm/mach-lh7a40x/include/mach/timex.h - * - * Copyright (C) 2004 Coastal Environmental Systems - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -#include - -#define CLOCK_TICK_RATE (PLL_CLOCK/6/16) - -/* -#define CLOCK_TICK_RATE 3686400 -*/ diff --git a/arch/arm/mach-lh7a40x/include/mach/uncompress.h b/arch/arm/mach-lh7a40x/include/mach/uncompress.h deleted file mode 100644 index 55b80d479eb4..000000000000 --- a/arch/arm/mach-lh7a40x/include/mach/uncompress.h +++ /dev/null @@ -1,38 +0,0 @@ -/* arch/arm/mach-lh7a40x/include/mach/uncompress.h - * - * Copyright (C) 2004 Coastal Environmental Systems - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -#include - -#ifndef UART_R_DATA -# define UART_R_DATA (0x00) -#endif -#ifndef UART_R_STATUS -# define UART_R_STATUS (0x10) -#endif -#define nTxRdy (0x20) /* Not TxReady (literally Tx FIFO full) */ - - /* Access UART with physical addresses before MMU is setup */ -#define UART_STATUS (*(volatile unsigned long*) (UART2_PHYS + UART_R_STATUS)) -#define UART_DATA (*(volatile unsigned long*) (UART2_PHYS + UART_R_DATA)) - -static inline void putc(int ch) -{ - while (UART_STATUS & nTxRdy) - barrier(); - UART_DATA = ch; -} - -static inline void flush(void) -{ -} - - /* NULL functions; we don't presently need them */ -#define arch_decomp_setup() -#define arch_decomp_wdog() diff --git a/arch/arm/mach-lh7a40x/include/mach/vmalloc.h b/arch/arm/mach-lh7a40x/include/mach/vmalloc.h deleted file mode 100644 index d62da7358b16..000000000000 --- a/arch/arm/mach-lh7a40x/include/mach/vmalloc.h +++ /dev/null @@ -1,10 +0,0 @@ -/* arch/arm/mach-lh7a40x/include/mach/vmalloc.h - * - * Copyright (C) 2004 Coastal Environmental Systems - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ -#define VMALLOC_END (0xe8000000UL) diff --git a/arch/arm/mach-lh7a40x/irq-kev7a400.c b/arch/arm/mach-lh7a40x/irq-kev7a400.c deleted file mode 100644 index c7433b3c5812..000000000000 --- a/arch/arm/mach-lh7a40x/irq-kev7a400.c +++ /dev/null @@ -1,93 +0,0 @@ -/* arch/arm/mach-lh7a40x/irq-kev7a400.c - * - * Copyright (C) 2004 Coastal Environmental Systems - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -#include -#include - -#include -#include -#include -#include - -#include "common.h" - - /* KEV7a400 CPLD IRQ handling */ - -static u16 CPLD_IRQ_mask; /* Mask for CPLD IRQs, 1 == unmasked */ - -static void -lh7a400_ack_cpld_irq (u32 irq) -{ - CPLD_CL_INT = 1 << (irq - IRQ_KEV7A400_CPLD); -} - -static void -lh7a400_mask_cpld_irq (u32 irq) -{ - CPLD_IRQ_mask &= ~(1 << (irq - IRQ_KEV7A400_CPLD)); - CPLD_WR_PB_INT_MASK = CPLD_IRQ_mask; -} - -static void -lh7a400_unmask_cpld_irq (u32 irq) -{ - CPLD_IRQ_mask |= 1 << (irq - IRQ_KEV7A400_CPLD); - CPLD_WR_PB_INT_MASK = CPLD_IRQ_mask; -} - -static struct -irq_chip lh7a400_cpld_chip = { - .name = "CPLD", - .ack = lh7a400_ack_cpld_irq, - .mask = lh7a400_mask_cpld_irq, - .unmask = lh7a400_unmask_cpld_irq, -}; - -static void -lh7a400_cpld_handler (unsigned int irq, struct irq_desc *desc) -{ - u32 mask = CPLD_LATCHED_INTS; - irq = IRQ_KEV_7A400_CPLD; - for (; mask; mask >>= 1, ++irq) { - if (mask & 1) - desc[irq].handle (irq, desc); - } -} - - /* IRQ initialization */ - -void __init -lh7a400_init_board_irq (void) -{ - int irq; - - for (irq = IRQ_KEV7A400_CPLD; - irq < IRQ_KEV7A400_CPLD + NR_IRQ_KEV7A400_CPLD; ++irq) { - set_irq_chip (irq, &lh7a400_cpld_chip); - set_irq_handler (irq, handle_edge_irq); - set_irq_flags (irq, IRQF_VALID); - } - set_irq_chained_handler (IRQ_CPLD, kev7a400_cpld_handler); - - /* Clear all CPLD interrupts */ - CPLD_CL_INT = 0xff; /* CPLD_INTR_MMC_CD | CPLD_INTR_ETH_INT; */ - - /* *** FIXME CF enabled in ide-probe.c */ - - GPIO_GPIOINTEN = 0; /* Disable all GPIO interrupts */ - barrier(); - GPIO_INTTYPE1 - = (GPIO_INTR_PCC1_CD | GPIO_INTR_PCC1_CD); /* Edge trig. */ - GPIO_INTTYPE2 = 0; /* Falling edge & low-level */ - GPIO_GPIOFEOI = 0xff; /* Clear all GPIO interrupts */ - GPIO_GPIOINTEN = 0xff; /* Enable all GPIO interrupts */ - - init_FIQ(); -} diff --git a/arch/arm/mach-lh7a40x/irq-lh7a400.c b/arch/arm/mach-lh7a40x/irq-lh7a400.c deleted file mode 100644 index f2e7e655ca35..000000000000 --- a/arch/arm/mach-lh7a40x/irq-lh7a400.c +++ /dev/null @@ -1,91 +0,0 @@ -/* arch/arm/mach-lh7a40x/irq-lh7a400.c - * - * Copyright (C) 2004 Coastal Environmental Systems - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include "common.h" - - /* CPU IRQ handling */ - -static void lh7a400_mask_irq(struct irq_data *d) -{ - INTC_INTENC = (1 << d->irq); -} - -static void lh7a400_unmask_irq(struct irq_data *d) -{ - INTC_INTENS = (1 << d->irq); -} - -static void lh7a400_ack_gpio_irq(struct irq_data *d) -{ - GPIO_GPIOFEOI = (1 << IRQ_TO_GPIO (d->irq)); - INTC_INTENC = (1 << d->irq); -} - -static struct irq_chip lh7a400_internal_chip = { - .name = "MPU", - .irq_ack = lh7a400_mask_irq, /* Level triggering -> mask is ack */ - .irq_mask = lh7a400_mask_irq, - .irq_unmask = lh7a400_unmask_irq, -}; - -static struct irq_chip lh7a400_gpio_chip = { - .name = "GPIO", - .irq_ack = lh7a400_ack_gpio_irq, - .irq_mask = lh7a400_mask_irq, - .irq_unmask = lh7a400_unmask_irq, -}; - - - /* IRQ initialization */ - -void __init lh7a400_init_irq (void) -{ - int irq; - - INTC_INTENC = 0xffffffff; /* Disable all interrupts */ - GPIO_GPIOFINTEN = 0x00; /* Disable all GPIOF interrupts */ - barrier (); - - for (irq = 0; irq < NR_IRQS; ++irq) { - switch (irq) { - case IRQ_GPIO0INTR: - case IRQ_GPIO1INTR: - case IRQ_GPIO2INTR: - case IRQ_GPIO3INTR: - case IRQ_GPIO4INTR: - case IRQ_GPIO5INTR: - case IRQ_GPIO6INTR: - case IRQ_GPIO7INTR: - set_irq_chip (irq, &lh7a400_gpio_chip); - set_irq_handler (irq, handle_level_irq); /* OK default */ - break; - default: - set_irq_chip (irq, &lh7a400_internal_chip); - set_irq_handler (irq, handle_level_irq); - } - set_irq_flags (irq, IRQF_VALID); - } - - lh7a40x_init_board_irq (); - -/* *** FIXME: the LH7a400 does use FIQ interrupts in some cases. For - the time being, these are not initialized. */ - -/* init_FIQ(); */ -} diff --git a/arch/arm/mach-lh7a40x/irq-lh7a404.c b/arch/arm/mach-lh7a40x/irq-lh7a404.c deleted file mode 100644 index 14b173389573..000000000000 --- a/arch/arm/mach-lh7a40x/irq-lh7a404.c +++ /dev/null @@ -1,175 +0,0 @@ -/* arch/arm/mach-lh7a40x/irq-lh7a404.c - * - * Copyright (C) 2004 Logic Product Development - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include "common.h" - -#define USE_PRIORITIES - -/* See Documentation/arm/Sharp-LH/VectoredInterruptController for more - * information on using the vectored interrupt controller's - * prioritizing feature. */ - -static unsigned char irq_pri_vic1[] = { -#if defined (USE_PRIORITIES) - IRQ_GPIO3INTR, /* CPLD */ - IRQ_DMAM2P4, IRQ_DMAM2P5, /* AC97 */ -#endif -}; -static unsigned char irq_pri_vic2[] = { -#if defined (USE_PRIORITIES) - IRQ_T3UI, /* Timer */ - IRQ_GPIO7INTR, /* CPLD */ - IRQ_UART1INTR, IRQ_UART2INTR, IRQ_UART3INTR, - IRQ_LCDINTR, /* LCD */ - IRQ_TSCINTR, /* ADC/Touchscreen */ -#endif -}; - - /* CPU IRQ handling */ - -static void lh7a404_vic1_mask_irq(struct irq_data *d) -{ - VIC1_INTENCLR = (1 << d->irq); -} - -static void lh7a404_vic1_unmask_irq(struct irq_data *d) -{ - VIC1_INTEN = (1 << d->irq); -} - -static void lh7a404_vic2_mask_irq(struct irq_data *d) -{ - VIC2_INTENCLR = (1 << (d->irq - 32)); -} - -static void lh7a404_vic2_unmask_irq(struct irq_data *d) -{ - VIC2_INTEN = (1 << (d->irq - 32)); -} - -static void lh7a404_vic1_ack_gpio_irq(struct irq_data *d) -{ - GPIO_GPIOFEOI = (1 << IRQ_TO_GPIO (d->irq)); - VIC1_INTENCLR = (1 << d->irq); -} - -static void lh7a404_vic2_ack_gpio_irq(struct irq_data *d) -{ - GPIO_GPIOFEOI = (1 << IRQ_TO_GPIO (d->irq)); - VIC2_INTENCLR = (1 << d->irq); -} - -static struct irq_chip lh7a404_vic1_chip = { - .name = "VIC1", - .irq_ack = lh7a404_vic1_mask_irq, /* Because level-triggered */ - .irq_mask = lh7a404_vic1_mask_irq, - .irq_unmask = lh7a404_vic1_unmask_irq, -}; - -static struct irq_chip lh7a404_vic2_chip = { - .name = "VIC2", - .irq_ack = lh7a404_vic2_mask_irq, /* Because level-triggered */ - .irq_mask = lh7a404_vic2_mask_irq, - .irq_unmask = lh7a404_vic2_unmask_irq, -}; - -static struct irq_chip lh7a404_gpio_vic1_chip = { - .name = "GPIO-VIC1", - .irq_ack = lh7a404_vic1_ack_gpio_irq, - .irq_mask = lh7a404_vic1_mask_irq, - .irq_unmask = lh7a404_vic1_unmask_irq, -}; - -static struct irq_chip lh7a404_gpio_vic2_chip = { - .name = "GPIO-VIC2", - .irq_ack = lh7a404_vic2_ack_gpio_irq, - .irq_mask = lh7a404_vic2_mask_irq, - .irq_unmask = lh7a404_vic2_unmask_irq, -}; - - /* IRQ initialization */ - -#if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404) -extern void* branch_irq_lh7a400; -#endif - -void __init lh7a404_init_irq (void) -{ - int irq; - -#if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404) -#define NOP 0xe1a00000 /* mov r0, r0 */ - branch_irq_lh7a400 = NOP; -#endif - - VIC1_INTENCLR = 0xffffffff; - VIC2_INTENCLR = 0xffffffff; - VIC1_INTSEL = 0; /* All IRQs */ - VIC2_INTSEL = 0; /* All IRQs */ - VIC1_NVADDR = VA_VIC1DEFAULT; - VIC2_NVADDR = VA_VIC2DEFAULT; - VIC1_VECTADDR = 0; - VIC2_VECTADDR = 0; - - GPIO_GPIOFINTEN = 0x00; /* Disable all GPIOF interrupts */ - barrier (); - - /* Install prioritized interrupts, if there are any. */ - /* The | 0x20*/ - for (irq = 0; irq < 16; ++irq) { - (&VIC1_VAD0)[irq] - = (irq < ARRAY_SIZE (irq_pri_vic1)) - ? (irq_pri_vic1[irq] | VA_VECTORED) : 0; - (&VIC1_VECTCNTL0)[irq] - = (irq < ARRAY_SIZE (irq_pri_vic1)) - ? (irq_pri_vic1[irq] | VIC_CNTL_ENABLE) : 0; - (&VIC2_VAD0)[irq] - = (irq < ARRAY_SIZE (irq_pri_vic2)) - ? (irq_pri_vic2[irq] | VA_VECTORED) : 0; - (&VIC2_VECTCNTL0)[irq] - = (irq < ARRAY_SIZE (irq_pri_vic2)) - ? (irq_pri_vic2[irq] | VIC_CNTL_ENABLE) : 0; - } - - for (irq = 0; irq < NR_IRQS; ++irq) { - switch (irq) { - case IRQ_GPIO0INTR: - case IRQ_GPIO1INTR: - case IRQ_GPIO2INTR: - case IRQ_GPIO3INTR: - case IRQ_GPIO4INTR: - case IRQ_GPIO5INTR: - case IRQ_GPIO6INTR: - case IRQ_GPIO7INTR: - set_irq_chip (irq, irq < 32 - ? &lh7a404_gpio_vic1_chip - : &lh7a404_gpio_vic2_chip); - set_irq_handler (irq, handle_level_irq); /* OK default */ - break; - default: - set_irq_chip (irq, irq < 32 - ? &lh7a404_vic1_chip - : &lh7a404_vic2_chip); - set_irq_handler (irq, handle_level_irq); - } - set_irq_flags (irq, IRQF_VALID); - } - - lh7a40x_init_board_irq (); -} diff --git a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c deleted file mode 100644 index 1bfdcddcb93e..000000000000 --- a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c +++ /dev/null @@ -1,128 +0,0 @@ -/* arch/arm/mach-lh7a40x/irq-lpd7a40x.c - * - * Copyright (C) 2004 Coastal Environmental Systems - * Copyright (C) 2004 Logic Product Development - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include "common.h" - -static void lh7a40x_ack_cpld_irq(struct irq_data *d) -{ - /* CPLD doesn't have ack capability */ -} - -static void lh7a40x_mask_cpld_irq(struct irq_data *d) -{ - switch (d->irq) { - case IRQ_LPD7A40X_ETH_INT: - CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x4; - break; - case IRQ_LPD7A400_TS: - CPLD_INTERRUPTS = CPLD_INTERRUPTS | 0x8; - break; - } -} - -static void lh7a40x_unmask_cpld_irq(struct irq_data *d) -{ - switch (d->irq) { - case IRQ_LPD7A40X_ETH_INT: - CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x4; - break; - case IRQ_LPD7A400_TS: - CPLD_INTERRUPTS = CPLD_INTERRUPTS & ~ 0x8; - break; - } -} - -static struct irq_chip lh7a40x_cpld_chip = { - .name = "CPLD", - .irq_ack = lh7a40x_ack_cpld_irq, - .irq_mask = lh7a40x_mask_cpld_irq, - .irq_unmask = lh7a40x_unmask_cpld_irq, -}; - -static void lh7a40x_cpld_handler (unsigned int irq, struct irq_desc *desc) -{ - unsigned int mask = CPLD_INTERRUPTS; - - desc->irq_data.chip->ack (irq); - - if ((mask & 0x1) == 0) /* WLAN */ - generic_handle_irq(IRQ_LPD7A40X_ETH_INT); - - if ((mask & 0x2) == 0) /* Touch */ - generic_handle_irq(IRQ_LPD7A400_TS); - - desc->irq_data.chip->unmask (irq); /* Level-triggered need this */ -} - - - /* IRQ initialization */ - -void __init lh7a40x_init_board_irq (void) -{ - int irq; - - /* Rev A (v2.8): PF0, PF1, PF2, and PF3 are available IRQs. - PF7 supports the CPLD. - Rev B (v3.4): PF0, PF1, and PF2 are available IRQs. - PF3 supports the CPLD. - (Some) LPD7A404 prerelease boards report a version - number of 0x16, but we force an override since the - hardware is of the newer variety. - */ - - unsigned char cpld_version = CPLD_REVISION; - int pinCPLD; - -#if defined CONFIG_MACH_LPD7A404 - cpld_version = 0x34; /* Override, for now */ -#endif - pinCPLD = (cpld_version == 0x28) ? 7 : 3; - - /* First, configure user controlled GPIOF interrupts */ - - GPIO_PFDD &= ~0x0f; /* PF0-3 are inputs */ - GPIO_INTTYPE1 &= ~0x0f; /* PF0-3 are level triggered */ - GPIO_INTTYPE2 &= ~0x0f; /* PF0-3 are active low */ - barrier (); - GPIO_GPIOFINTEN |= 0x0f; /* Enable PF0, PF1, PF2, and PF3 IRQs */ - - /* Then, configure CPLD interrupt */ - - CPLD_INTERRUPTS = 0x0c; /* Disable all CPLD interrupts */ - GPIO_PFDD &= ~(1 << pinCPLD); /* Make input */ - GPIO_INTTYPE1 |= (1 << pinCPLD); /* Edge triggered */ - GPIO_INTTYPE2 &= ~(1 << pinCPLD); /* Active low */ - barrier (); - GPIO_GPIOFINTEN |= (1 << pinCPLD); /* Enable */ - - /* Cascade CPLD interrupts */ - - for (irq = IRQ_BOARD_START; - irq < IRQ_BOARD_START + NR_IRQ_BOARD; ++irq) { - set_irq_chip (irq, &lh7a40x_cpld_chip); - set_irq_handler (irq, handle_edge_irq); - set_irq_flags (irq, IRQF_VALID); - } - - set_irq_chained_handler ((cpld_version == 0x28) - ? IRQ_CPLD_V28 - : IRQ_CPLD_V34, - lh7a40x_cpld_handler); -} diff --git a/arch/arm/mach-lh7a40x/lcd-panel.h b/arch/arm/mach-lh7a40x/lcd-panel.h deleted file mode 100644 index a7f5027b2f78..000000000000 --- a/arch/arm/mach-lh7a40x/lcd-panel.h +++ /dev/null @@ -1,345 +0,0 @@ -/* lcd-panel.h - - written by Marc Singer - 18 Jul 2005 - - Copyright (C) 2005 Marc Singer - - ----------- - DESCRIPTION - ----------- - - Only one panel may be defined at a time. - - The pixel clock is calculated to be no greater than the target. - - Each timing value is accompanied by a specification comment. - - UNITS/MIN/TYP/MAX - - Most of the units will be in clocks. - - USE_RGB555 - - Define this macro to configure the AMBA LCD controller to use an - RGB555 encoding for the pels instead of the normal RGB565. - - LPD9520, LPD79524, LPD7A400, LPD7A404-10, LPD7A404-11 - - These boards are best approximated by 555 for all panels. Some - can use an extra low-order bit of blue in bit 16 of the color - value, but we don't have a way to communicate this non-linear - mapping to the kernel. - -*/ - -#if !defined (__LCD_PANEL_H__) -# define __LCD_PANEL_H__ - -#if defined (MACH_LPD79520)\ - || defined (MACH_LPD79524)\ - || defined (MACH_LPD7A400)\ - || defined (MACH_LPD7A404) -# define USE_RGB555 -#endif - -struct clcd_panel_extra { - unsigned int hrmode; - unsigned int clsen; - unsigned int spsen; - unsigned int pcdel; - unsigned int revdel; - unsigned int lpdel; - unsigned int spldel; - unsigned int pc2del; -}; - -#define NS_TO_CLOCK(ns,c) ((((ns)*((c)/1000) + (1000000 - 1))/1000000)) -#define CLOCK_TO_DIV(e,c) (((c) + (e) - 1)/(e)) - -#if defined CONFIG_FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT - - /* Logic Product Development LCD 3.5" QVGA HRTFT -10 */ - /* Sharp PN LQ035Q7DB02 w/HRTFT controller chip */ - -#define PIX_CLOCK_TARGET (6800000) -#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK) -#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER) - -static struct clcd_panel lcd_panel = { - .mode = { - .name = "3.5in QVGA (LQ035Q7DB02)", - .xres = 240, - .yres = 320, - .pixclock = PIX_CLOCK, - .left_margin = 16, - .right_margin = 21, - .upper_margin = 8, // line/8/8/8 - .lower_margin = 5, - .hsync_len = 61, - .vsync_len = NS_TO_CLOCK (60, PIX_CLOCK), - .vmode = FB_VMODE_NONINTERLACED, - }, - .width = -1, - .height = -1, - .tim2 = TIM2_IPC | (PIX_CLOCK_DIVIDER - 2), - .cntl = CNTL_LCDTFT | CNTL_WATERMARK, - .bpp = 16, -}; - -#define HAS_LCD_PANEL_EXTRA - -static struct clcd_panel_extra lcd_panel_extra = { - .hrmode = 1, - .clsen = 1, - .spsen = 1, - .pcdel = 8, - .revdel = 7, - .lpdel = 13, - .spldel = 77, - .pc2del = 208, -}; - -#endif - -#if defined CONFIG_FB_ARMCLCD_SHARP_LQ057Q3DC02 - - /* Logic Product Development LCD 5.7" QVGA -10 */ - /* Sharp PN LQ057Q3DC02 */ - /* QVGA mode, V/Q=LOW */ - -/* From Sharp on 2006.1.3. I believe some of the values are incorrect - * based on the datasheet. - - Timing0 TIMING1 TIMING2 CONTROL - 0x140A0C4C 0x080504EF 0x013F380D 0x00000829 - HBP= 20 VBP= 8 BCD= 0 - HFP= 10 VFP= 5 CPL=319 - HSW= 12 VSW= 1 IOE= 0 - PPL= 19 LPP=239 IPC= 1 - IHS= 1 - IVS= 1 - ACB= 0 - CSEL= 0 - PCD= 13 - - */ - -/* The full horizontal cycle (Th) is clock/360/400/450. */ -/* The full vertical cycle (Tv) is line/251/262/280. */ - -#define PIX_CLOCK_TARGET (6300000) /* -/6.3/7 MHz */ -#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK) -#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER) - -static struct clcd_panel lcd_panel = { - .mode = { - .name = "5.7in QVGA (LQ057Q3DC02)", - .xres = 320, - .yres = 240, - .pixclock = PIX_CLOCK, - .left_margin = 11, - .right_margin = 400-11-320-2, - .upper_margin = 7, // line/7/7/7 - .lower_margin = 262-7-240-2, - .hsync_len = 2, // clk/2/96/200 - .vsync_len = 2, // line/2/-/34 - .vmode = FB_VMODE_NONINTERLACED, - }, - .width = -1, - .height = -1, - .tim2 = TIM2_IHS | TIM2_IVS - | (PIX_CLOCK_DIVIDER - 2), - .cntl = CNTL_LCDTFT | CNTL_WATERMARK, - .bpp = 16, -}; - -#endif - -#if defined CONFIG_FB_ARMCLCD_SHARP_LQ64D343 - - /* Logic Product Development LCD 6.4" VGA -10 */ - /* Sharp PN LQ64D343 */ - -/* The full horizontal cycle (Th) is clock/750/800/900. */ -/* The full vertical cycle (Tv) is line/515/525/560. */ - -#define PIX_CLOCK_TARGET (28330000) -#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK) -#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER) - -static struct clcd_panel lcd_panel = { - .mode = { - .name = "6.4in QVGA (LQ64D343)", - .xres = 640, - .yres = 480, - .pixclock = PIX_CLOCK, - .left_margin = 32, - .right_margin = 800-32-640-96, - .upper_margin = 32, // line/34/34/34 - .lower_margin = 540-32-480-2, - .hsync_len = 96, // clk/2/96/200 - .vsync_len = 2, // line/2/-/34 - .vmode = FB_VMODE_NONINTERLACED, - }, - .width = -1, - .height = -1, - .tim2 = TIM2_IHS | TIM2_IVS - | (PIX_CLOCK_DIVIDER - 2), - .cntl = CNTL_LCDTFT | CNTL_WATERMARK, - .bpp = 16, -}; - -#endif - -#if defined CONFIG_FB_ARMCLCD_SHARP_LQ10D368 - - /* Logic Product Development LCD 10.4" VGA -10 */ - /* Sharp PN LQ10D368 */ - -#define PIX_CLOCK_TARGET (28330000) -#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK) -#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER) - -static struct clcd_panel lcd_panel = { - .mode = { - .name = "10.4in VGA (LQ10D368)", - .xres = 640, - .yres = 480, - .pixclock = PIX_CLOCK, - .left_margin = 21, - .right_margin = 15, - .upper_margin = 34, - .lower_margin = 5, - .hsync_len = 96, - .vsync_len = 16, - .vmode = FB_VMODE_NONINTERLACED, - }, - .width = -1, - .height = -1, - .tim2 = TIM2_IHS | TIM2_IVS - | (PIX_CLOCK_DIVIDER - 2), - .cntl = CNTL_LCDTFT | CNTL_WATERMARK, - .bpp = 16, -}; - -#endif - -#if defined CONFIG_FB_ARMCLCD_SHARP_LQ121S1DG41 - - /* Logic Product Development LCD 12.1" SVGA -10 */ - /* Sharp PN LQ121S1DG41, was LQ121S1DG31 */ - -/* Note that with a 99993900 Hz HCLK, it is not possible to hit the - * target clock frequency range of 35MHz to 42MHz. */ - -/* If the target pixel clock is substantially lower than the panel - * spec, this is done to prevent the LCD display from glitching when - * the CPU is under load. A pixel clock higher than 25MHz - * (empirically determined) will compete with the CPU for bus cycles - * for the Ethernet chip. However, even a pixel clock of 10MHz - * competes with Compact Flash interface during some operations - * (fdisk, e2fsck). And, at that speed the display may have a visible - * flicker. */ - -/* The full horizontal cycle (Th) is clock/832/1056/1395. */ - -#define PIX_CLOCK_TARGET (20000000) -#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK) -#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER) - -static struct clcd_panel lcd_panel = { - .mode = { - .name = "12.1in SVGA (LQ121S1DG41)", - .xres = 800, - .yres = 600, - .pixclock = PIX_CLOCK, - .left_margin = 89, // ns/5/-/(1/PIX_CLOCK)-10 - .right_margin = 1056-800-89-128, - .upper_margin = 23, // line/23/23/23 - .lower_margin = 44, - .hsync_len = 128, // clk/2/128/200 - .vsync_len = 4, // line/2/4/6 - .vmode = FB_VMODE_NONINTERLACED, - }, - .width = -1, - .height = -1, - .tim2 = TIM2_IHS | TIM2_IVS - | (PIX_CLOCK_DIVIDER - 2), - .cntl = CNTL_LCDTFT | CNTL_WATERMARK, - .bpp = 16, -}; - -#endif - -#if defined CONFIG_FB_ARMCLCD_HITACHI - - /* Hitachi*/ - /* Submitted by Michele Da Rold */ - -#define PIX_CLOCK_TARGET (49000000) -#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK) -#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER) - -static struct clcd_panel lcd_panel = { - .mode = { - .name = "Hitachi 800x480", - .xres = 800, - .yres = 480, - .pixclock = PIX_CLOCK, - .left_margin = 88, - .right_margin = 40, - .upper_margin = 32, - .lower_margin = 11, - .hsync_len = 128, - .vsync_len = 2, - .vmode = FB_VMODE_NONINTERLACED, - }, - .width = -1, - .height = -1, - .tim2 = TIM2_IPC | TIM2_IHS | TIM2_IVS - | (PIX_CLOCK_DIVIDER - 2), - .cntl = CNTL_LCDTFT | CNTL_WATERMARK, - .bpp = 16, -}; - -#endif - - -#if defined CONFIG_FB_ARMCLCD_AUO_A070VW01_WIDE - - /* AU Optotronics A070VW01 7.0 Wide Screen color Display*/ - /* Submitted by Michele Da Rold */ - -#define PIX_CLOCK_TARGET (10000000) -#define PIX_CLOCK_DIVIDER CLOCK_TO_DIV (PIX_CLOCK_TARGET, HCLK) -#define PIX_CLOCK (HCLK/PIX_CLOCK_DIVIDER) - -static struct clcd_panel lcd_panel = { - .mode = { - .name = "7.0in Wide (A070VW01)", - .xres = 480, - .yres = 234, - .pixclock = PIX_CLOCK, - .left_margin = 30, - .right_margin = 25, - .upper_margin = 14, - .lower_margin = 12, - .hsync_len = 100, - .vsync_len = 1, - .vmode = FB_VMODE_NONINTERLACED, - }, - .width = -1, - .height = -1, - .tim2 = TIM2_IPC | TIM2_IHS | TIM2_IVS - | (PIX_CLOCK_DIVIDER - 2), - .cntl = CNTL_LCDTFT | CNTL_WATERMARK, - .bpp = 16, -}; - -#endif - -#undef NS_TO_CLOCK -#undef CLOCK_TO_DIV - -#endif /* __LCD_PANEL_H__ */ diff --git a/arch/arm/mach-lh7a40x/ssp-cpld.c b/arch/arm/mach-lh7a40x/ssp-cpld.c deleted file mode 100644 index 2901d49d1484..000000000000 --- a/arch/arm/mach-lh7a40x/ssp-cpld.c +++ /dev/null @@ -1,343 +0,0 @@ -/* arch/arm/mach-lh7a40x/ssp-cpld.c - * - * Copyright (C) 2004,2005 Marc Singer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * SSP/SPI driver for the CardEngine CPLD. - * - */ - -/* NOTES - ----- - - o *** This driver is cribbed from the 7952x implementation. - Some comments may not apply. - - o This driver contains sufficient logic to control either the - serial EEPROMs or the audio codec. It is included in the kernel - to support the codec. The EEPROMs are really the responsibility - of the boot loader and should probably be left alone. - - o The code must be augmented to cope with multiple, simultaneous - clients. - o The audio codec writes to the codec chip whenever playback - starts. - o The touchscreen driver writes to the ads chip every time it - samples. - o The audio codec must write 16 bits, but the touch chip writes - are 8 bits long. - o We need to be able to keep these configurations separate while - simultaneously active. - - */ - -#include -#include -//#include -#include -#include -//#include -#include -#include -#include -#include - -#include -#include - -#include - -//#define TALK - -#if defined (TALK) -#define PRINTK(f...) printk (f) -#else -#define PRINTK(f...) do {} while (0) -#endif - -#if defined (CONFIG_ARCH_LH7A400) -# define CPLD_SPID __REGP16(CPLD06_VIRT) /* SPI data */ -# define CPLD_SPIC __REGP16(CPLD08_VIRT) /* SPI control */ -# define CPLD_SPIC_CS_CODEC (1<<0) -# define CPLD_SPIC_CS_TOUCH (1<<1) -# define CPLD_SPIC_WRITE (0<<2) -# define CPLD_SPIC_READ (1<<2) -# define CPLD_SPIC_DONE (1<<3) /* r/o */ -# define CPLD_SPIC_LOAD (1<<4) -# define CPLD_SPIC_START (1<<4) -# define CPLD_SPIC_LOADED (1<<5) /* r/o */ -#endif - -#define CPLD_SPI __REGP16(CPLD0A_VIRT) /* SPI operation */ -#define CPLD_SPI_CS_EEPROM (1<<3) -#define CPLD_SPI_SCLK (1<<2) -#define CPLD_SPI_TX_SHIFT (1) -#define CPLD_SPI_TX (1< %2d", v & 0x1ff, (v >> 9) & 0x7f); -#endif - PRINTK ("\n"); - - if (ssp_configuration.device == DEVICE_CODEC) - select = CPLD_SPIC_CS_CODEC; - if (ssp_configuration.device == DEVICE_TOUCH) - select = CPLD_SPIC_CS_TOUCH; - if (cwrite) { - for (cwrite = (cwrite + 7)/8; cwrite-- > 0; ) { - CPLD_SPID = (v >> (8*cwrite)) & 0xff; - CPLD_SPIC = select | CPLD_SPIC_LOAD; - while (!(CPLD_SPIC & CPLD_SPIC_LOADED)) - ; - CPLD_SPIC = select; - while (!(CPLD_SPIC & CPLD_SPIC_DONE)) - ; - } - v = 0; - } - if (cread) { - mdelay (2); /* *** FIXME: required by ads7843? */ - v = 0; - for (cread = (cread + 7)/8; cread-- > 0;) { - CPLD_SPID = 0; - CPLD_SPIC = select | CPLD_SPIC_READ - | CPLD_SPIC_START; - while (!(CPLD_SPIC & CPLD_SPIC_LOADED)) - ; - CPLD_SPIC = select | CPLD_SPIC_READ; - while (!(CPLD_SPIC & CPLD_SPIC_DONE)) - ; - v = (v << 8) | CPLD_SPID; - } - } - return v; - } -#endif - - PRINTK ("spi(%d) 0x%04x -> 0x%x\r\n", ssp_configuration.device, - v & 0x1ff, (v >> 9) & 0x7f); - - enable_cs (); - - v <<= CPLD_SPI_TX_SHIFT; /* Correction for position of SPI_TX bit */ - while (cwrite--) { - CPLD_SPI - = (CPLD_SPI & ~CPLD_SPI_TX) - | ((v >> cwrite) & CPLD_SPI_TX); - udelay (T_DIS); - pulse_clock (); - } - - if (cread < 0) { - int delay = 10; - disable_cs (); - udelay (1); - enable_cs (); - - l = -1; - do { - if (CPLD_SPI & CPLD_SPI_RX) { - l = 0; - break; - } - } while (udelay (1), --delay); - } - else - /* We pulse the clock before the data to skip the leading zero. */ - while (cread-- > 0) { - pulse_clock (); - l = (l<<1) - | (((CPLD_SPI & CPLD_SPI_RX) - >> CPLD_SPI_RX_SHIFT) & 0x1); - } - - disable_cs (); - return l; -} - -static int ssp_init (void) -{ - spin_lock_init (&ssp_lock); - memset (&ssp_configuration, 0, sizeof (ssp_configuration)); - return 0; -} - - -/* ssp_chip_select - - drops the chip select line for the CPLD shift-register controlled - devices. It doesn't enable chip - -*/ - -static void ssp_chip_select (int enable) -{ -#if defined (CONFIG_MACH_LPD7A400) - int select; - - if (ssp_configuration.device == DEVICE_CODEC) - select = CPLD_SPIC_CS_CODEC; - else if (ssp_configuration.device == DEVICE_TOUCH) - select = CPLD_SPIC_CS_TOUCH; - else - return; - - if (enable) - CPLD_SPIC = select; - else - CPLD_SPIC = 0; -#endif -} - -static void ssp_acquire (void) -{ - spin_lock (&ssp_lock); -} - -static void ssp_release (void) -{ - ssp_chip_select (0); /* just in case */ - spin_unlock (&ssp_lock); -} - -static int ssp_configure (int device, int mode, int speed, - int frame_size_write, int frame_size_read) -{ - ssp_configuration.device = device; - ssp_configuration.mode = mode; - ssp_configuration.speed = speed; - ssp_configuration.frame_size_write = frame_size_write; - ssp_configuration.frame_size_read = frame_size_read; - - return 0; -} - -static int ssp_read (void) -{ - return execute_spi_command (0, 0, ssp_configuration.frame_size_read); -} - -static int ssp_write (u16 data) -{ - execute_spi_command (data, ssp_configuration.frame_size_write, 0); - return 0; -} - -static int ssp_write_read (u16 data) -{ - return execute_spi_command (data, ssp_configuration.frame_size_write, - ssp_configuration.frame_size_read); -} - -struct ssp_driver lh7a40x_cpld_ssp_driver = { - .init = ssp_init, - .acquire = ssp_acquire, - .release = ssp_release, - .configure = ssp_configure, - .chip_select = ssp_chip_select, - .read = ssp_read, - .write = ssp_write, - .write_read = ssp_write_read, -}; - - -MODULE_AUTHOR("Marc Singer"); -MODULE_DESCRIPTION("LPD7A40X CPLD SPI driver"); -MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-lh7a40x/time.c b/arch/arm/mach-lh7a40x/time.c deleted file mode 100644 index 4601e425bae3..000000000000 --- a/arch/arm/mach-lh7a40x/time.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * arch/arm/mach-lh7a40x/time.c - * - * Copyright (C) 2004 Logic Product Development - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include "common.h" - -#if HZ < 100 -# define TIMER_CONTROL TIMER_CONTROL2 -# define TIMER_LOAD TIMER_LOAD2 -# define TIMER_CONSTANT (508469/HZ) -# define TIMER_MODE (TIMER_C_ENABLE | TIMER_C_PERIODIC | TIMER_C_508KHZ) -# define TIMER_EOI TIMER_EOI2 -# define TIMER_IRQ IRQ_T2UI -#else -# define TIMER_CONTROL TIMER_CONTROL3 -# define TIMER_LOAD TIMER_LOAD3 -# define TIMER_CONSTANT (3686400/HZ) -# define TIMER_MODE (TIMER_C_ENABLE | TIMER_C_PERIODIC) -# define TIMER_EOI TIMER_EOI3 -# define TIMER_IRQ IRQ_T3UI -#endif - -static irqreturn_t -lh7a40x_timer_interrupt(int irq, void *dev_id) -{ - TIMER_EOI = 0; - timer_tick(); - - return IRQ_HANDLED; -} - -static struct irqaction lh7a40x_timer_irq = { - .name = "LHA740x Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = lh7a40x_timer_interrupt, -}; - -static void __init lh7a40x_timer_init (void) -{ - /* Stop/disable all timers */ - TIMER_CONTROL1 = 0; - TIMER_CONTROL2 = 0; - TIMER_CONTROL3 = 0; - - setup_irq (TIMER_IRQ, &lh7a40x_timer_irq); - - TIMER_LOAD = TIMER_CONSTANT; - TIMER_CONTROL = TIMER_MODE; -} - -struct sys_timer lh7a40x_timer = { - .init = &lh7a40x_timer_init, -}; diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index ee747919a766..68d48ab6eacf 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -206,68 +206,6 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) #define RPC_LSA_DEFAULT RPC_LED_TX_RX #define RPC_LSB_DEFAULT RPC_LED_100_10 -#elif defined(CONFIG_MACH_LPD79520) || \ - defined(CONFIG_MACH_LPD7A400) || \ - defined(CONFIG_MACH_LPD7A404) - -/* The LPD7X_IOBARRIER is necessary to overcome a mismatch between the - * way that the CPU handles chip selects and the way that the SMC chip - * expects the chip select to operate. Refer to - * Documentation/arm/Sharp-LH/IOBarrier for details. The read from - * IOBARRIER is a byte, in order that we read the least-common - * denominator. It would be wasteful to read 32 bits from an 8-bit - * accessible region. - * - * There is no explicit protection against interrupts intervening - * between the writew and the IOBARRIER. In SMC ISR there is a - * preamble that performs an IOBARRIER in the extremely unlikely event - * that the driver interrupts itself between a writew to the chip an - * the IOBARRIER that follows *and* the cache is large enough that the - * first off-chip access while handing the interrupt is to the SMC - * chip. Other devices in the same address space as the SMC chip must - * be aware of the potential for trouble and perform a similar - * IOBARRIER on entry to their ISR. - */ - -#include /* IOBARRIER_VIRT */ - -#define SMC_CAN_USE_8BIT 0 -#define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 0 -#define SMC_NOWAIT 0 -#define LPD7X_IOBARRIER readb (IOBARRIER_VIRT) - -#define SMC_inw(a,r)\ - ({ unsigned short v = readw ((void*) ((a) + (r))); LPD7X_IOBARRIER; v; }) -#define SMC_outw(v,a,r) ({ writew ((v), (a) + (r)); LPD7X_IOBARRIER; }) - -#define SMC_insw LPD7_SMC_insw -static inline void LPD7_SMC_insw (unsigned char* a, int r, - unsigned char* p, int l) -{ - unsigned short* ps = (unsigned short*) p; - while (l-- > 0) { - *ps++ = readw (a + r); - LPD7X_IOBARRIER; - } -} - -#define SMC_outsw LPD7_SMC_outsw -static inline void LPD7_SMC_outsw (unsigned char* a, int r, - unsigned char* p, int l) -{ - unsigned short* ps = (unsigned short*) p; - while (l-- > 0) { - writew (*ps++, a + r); - LPD7X_IOBARRIER; - } -} - -#define SMC_INTERRUPT_PREAMBLE LPD7X_IOBARRIER - -#define RPC_LSA_DEFAULT RPC_LED_TX_RX -#define RPC_LSB_DEFAULT RPC_LED_100_10 - #elif defined(CONFIG_ARCH_VERSATILE) #define SMC_CAN_USE_8BIT 1 diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index b1682d7f1d8a..1174d4d90407 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1110,29 +1110,6 @@ config SERIAL_PMACZILOG_CONSOLE on your (Power)Mac as the console, you can do so by answering Y to this option. -config SERIAL_LH7A40X - tristate "Sharp LH7A40X embedded UART support" - depends on ARM && ARCH_LH7A40X - select SERIAL_CORE - help - This enables support for the three on-board UARTs of the - Sharp LH7A40X series CPUs. Choose Y or M. - -config SERIAL_LH7A40X_CONSOLE - bool "Support for console on Sharp LH7A40X serial port" - depends on SERIAL_LH7A40X=y - select SERIAL_CORE_CONSOLE - help - Say Y here if you wish to use one of the serial ports as the - system console--the system console is the device which - receives all kernel messages and warnings and which allows - logins in single user mode. - - Even if you say Y here, the currently visible framebuffer console - (/dev/tty0) will still be used as the default system console, but - you can alter that using a kernel command line, for example - "console=ttyAM1". - config SERIAL_CPM tristate "CPM SCC/SMC serial port support" depends on CPM2 || 8xx diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 8ea92e9c73b0..8e325408b1a6 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -54,7 +54,6 @@ obj-$(CONFIG_SERIAL_68328) += 68328serial.o obj-$(CONFIG_SERIAL_68360) += 68360serial.o obj-$(CONFIG_SERIAL_MCF) += mcf.o obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o -obj-$(CONFIG_SERIAL_LH7A40X) += serial_lh7a40x.o obj-$(CONFIG_SERIAL_DZ) += dz.o obj-$(CONFIG_SERIAL_ZS) += zs.o obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o diff --git a/drivers/tty/serial/serial_lh7a40x.c b/drivers/tty/serial/serial_lh7a40x.c deleted file mode 100644 index ea744707c4d6..000000000000 --- a/drivers/tty/serial/serial_lh7a40x.c +++ /dev/null @@ -1,682 +0,0 @@ -/* drivers/serial/serial_lh7a40x.c - * - * Copyright (C) 2004 Coastal Environmental Systems - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - */ - -/* Driver for Sharp LH7A40X embedded serial ports - * - * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. - * Based on drivers/serial/amba.c, by Deep Blue Solutions Ltd. - * - * --- - * - * This driver supports the embedded UARTs of the Sharp LH7A40X series - * CPUs. While similar to the 16550 and other UART chips, there is - * nothing close to register compatibility. Moreover, some of the - * modem control lines are not available, either in the chip or they - * are lacking in the board-level implementation. - * - * - Use of SIRDIS - * For simplicity, we disable the IR functions of any UART whenever - * we enable it. - * - */ - - -#if defined(CONFIG_SERIAL_LH7A40X_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define DEV_MAJOR 204 -#define DEV_MINOR 16 -#define DEV_NR 3 - -#define ISR_LOOP_LIMIT 256 - -#define UR(p,o) _UR ((p)->membase, o) -#define _UR(b,o) (*((volatile unsigned int*)(((unsigned char*) b) + (o)))) -#define BIT_CLR(p,o,m) UR(p,o) = UR(p,o) & (~(unsigned int)m) -#define BIT_SET(p,o,m) UR(p,o) = UR(p,o) | ( (unsigned int)m) - -#define UART_REG_SIZE 32 - -#define UART_R_DATA (0x00) -#define UART_R_FCON (0x04) -#define UART_R_BRCON (0x08) -#define UART_R_CON (0x0c) -#define UART_R_STATUS (0x10) -#define UART_R_RAWISR (0x14) -#define UART_R_INTEN (0x18) -#define UART_R_ISR (0x1c) - -#define UARTEN (0x01) /* UART enable */ -#define SIRDIS (0x02) /* Serial IR disable (UART1 only) */ - -#define RxEmpty (0x10) -#define TxEmpty (0x80) -#define TxFull (0x20) -#define nRxRdy RxEmpty -#define nTxRdy TxFull -#define TxBusy (0x08) - -#define RxBreak (0x0800) -#define RxOverrunError (0x0400) -#define RxParityError (0x0200) -#define RxFramingError (0x0100) -#define RxError (RxBreak | RxOverrunError | RxParityError | RxFramingError) - -#define DCD (0x04) -#define DSR (0x02) -#define CTS (0x01) - -#define RxInt (0x01) -#define TxInt (0x02) -#define ModemInt (0x04) -#define RxTimeoutInt (0x08) - -#define MSEOI (0x10) - -#define WLEN_8 (0x60) -#define WLEN_7 (0x40) -#define WLEN_6 (0x20) -#define WLEN_5 (0x00) -#define WLEN (0x60) /* Mask for all word-length bits */ -#define STP2 (0x08) -#define PEN (0x02) /* Parity Enable */ -#define EPS (0x04) /* Even Parity Set */ -#define FEN (0x10) /* FIFO Enable */ -#define BRK (0x01) /* Send Break */ - - -struct uart_port_lh7a40x { - struct uart_port port; - unsigned int statusPrev; /* Most recently read modem status */ -}; - -static void lh7a40xuart_stop_tx (struct uart_port* port) -{ - BIT_CLR (port, UART_R_INTEN, TxInt); -} - -static void lh7a40xuart_start_tx (struct uart_port* port) -{ - BIT_SET (port, UART_R_INTEN, TxInt); - - /* *** FIXME: do I need to check for startup of the - transmitter? The old driver did, but AMBA - doesn't . */ -} - -static void lh7a40xuart_stop_rx (struct uart_port* port) -{ - BIT_SET (port, UART_R_INTEN, RxTimeoutInt | RxInt); -} - -static void lh7a40xuart_enable_ms (struct uart_port* port) -{ - BIT_SET (port, UART_R_INTEN, ModemInt); -} - -static void lh7a40xuart_rx_chars (struct uart_port* port) -{ - struct tty_struct* tty = port->state->port.tty; - int cbRxMax = 256; /* (Gross) limit on receive */ - unsigned int data; /* Received data and status */ - unsigned int flag; - - while (!(UR (port, UART_R_STATUS) & nRxRdy) && --cbRxMax) { - data = UR (port, UART_R_DATA); - flag = TTY_NORMAL; - ++port->icount.rx; - - if (unlikely(data & RxError)) { - if (data & RxBreak) { - data &= ~(RxFramingError | RxParityError); - ++port->icount.brk; - if (uart_handle_break (port)) - continue; - } - else if (data & RxParityError) - ++port->icount.parity; - else if (data & RxFramingError) - ++port->icount.frame; - if (data & RxOverrunError) - ++port->icount.overrun; - - /* Mask by termios, leave Rx'd byte */ - data &= port->read_status_mask | 0xff; - - if (data & RxBreak) - flag = TTY_BREAK; - else if (data & RxParityError) - flag = TTY_PARITY; - else if (data & RxFramingError) - flag = TTY_FRAME; - } - - if (uart_handle_sysrq_char (port, (unsigned char) data)) - continue; - - uart_insert_char(port, data, RxOverrunError, data, flag); - } - tty_flip_buffer_push (tty); - return; -} - -static void lh7a40xuart_tx_chars (struct uart_port* port) -{ - struct circ_buf* xmit = &port->state->xmit; - int cbTxMax = port->fifosize; - - if (port->x_char) { - UR (port, UART_R_DATA) = port->x_char; - ++port->icount.tx; - port->x_char = 0; - return; - } - if (uart_circ_empty (xmit) || uart_tx_stopped (port)) { - lh7a40xuart_stop_tx (port); - return; - } - - /* Unlike the AMBA UART, the lh7a40x UART does not guarantee - that at least half of the FIFO is empty. Instead, we check - status for every character. Using the AMBA method causes - the transmitter to drop characters. */ - - do { - UR (port, UART_R_DATA) = xmit->buf[xmit->tail]; - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - ++port->icount.tx; - if (uart_circ_empty(xmit)) - break; - } while (!(UR (port, UART_R_STATUS) & nTxRdy) - && cbTxMax--); - - if (uart_circ_chars_pending (xmit) < WAKEUP_CHARS) - uart_write_wakeup (port); - - if (uart_circ_empty (xmit)) - lh7a40xuart_stop_tx (port); -} - -static void lh7a40xuart_modem_status (struct uart_port* port) -{ - unsigned int status = UR (port, UART_R_STATUS); - unsigned int delta - = status ^ ((struct uart_port_lh7a40x*) port)->statusPrev; - - BIT_SET (port, UART_R_RAWISR, MSEOI); /* Clear modem status intr */ - - if (!delta) /* Only happens if we missed 2 transitions */ - return; - - ((struct uart_port_lh7a40x*) port)->statusPrev = status; - - if (delta & DCD) - uart_handle_dcd_change (port, status & DCD); - - if (delta & DSR) - ++port->icount.dsr; - - if (delta & CTS) - uart_handle_cts_change (port, status & CTS); - - wake_up_interruptible (&port->state->port.delta_msr_wait); -} - -static irqreturn_t lh7a40xuart_int (int irq, void* dev_id) -{ - struct uart_port* port = dev_id; - unsigned int cLoopLimit = ISR_LOOP_LIMIT; - unsigned int isr = UR (port, UART_R_ISR); - - - do { - if (isr & (RxInt | RxTimeoutInt)) - lh7a40xuart_rx_chars(port); - if (isr & ModemInt) - lh7a40xuart_modem_status (port); - if (isr & TxInt) - lh7a40xuart_tx_chars (port); - - if (--cLoopLimit == 0) - break; - - isr = UR (port, UART_R_ISR); - } while (isr & (RxInt | TxInt | RxTimeoutInt)); - - return IRQ_HANDLED; -} - -static unsigned int lh7a40xuart_tx_empty (struct uart_port* port) -{ - return (UR (port, UART_R_STATUS) & TxEmpty) ? TIOCSER_TEMT : 0; -} - -static unsigned int lh7a40xuart_get_mctrl (struct uart_port* port) -{ - unsigned int result = 0; - unsigned int status = UR (port, UART_R_STATUS); - - if (status & DCD) - result |= TIOCM_CAR; - if (status & DSR) - result |= TIOCM_DSR; - if (status & CTS) - result |= TIOCM_CTS; - - return result; -} - -static void lh7a40xuart_set_mctrl (struct uart_port* port, unsigned int mctrl) -{ - /* None of the ports supports DTR. UART1 supports RTS through GPIO. */ - /* Note, kernel appears to be setting DTR and RTS on console. */ - - /* *** FIXME: this deserves more work. There's some work in - tracing all of the IO pins. */ -#if 0 - if( port->mapbase == UART1_PHYS) { - gpioRegs_t *gpio = (gpioRegs_t *)IO_ADDRESS(GPIO_PHYS); - - if (mctrl & TIOCM_RTS) - gpio->pbdr &= ~GPIOB_UART1_RTS; - else - gpio->pbdr |= GPIOB_UART1_RTS; - } -#endif -} - -static void lh7a40xuart_break_ctl (struct uart_port* port, int break_state) -{ - unsigned long flags; - - spin_lock_irqsave(&port->lock, flags); - if (break_state == -1) - BIT_SET (port, UART_R_FCON, BRK); /* Assert break */ - else - BIT_CLR (port, UART_R_FCON, BRK); /* Deassert break */ - spin_unlock_irqrestore(&port->lock, flags); -} - -static int lh7a40xuart_startup (struct uart_port* port) -{ - int retval; - - retval = request_irq (port->irq, lh7a40xuart_int, 0, - "serial_lh7a40x", port); - if (retval) - return retval; - - /* Initial modem control-line settings */ - ((struct uart_port_lh7a40x*) port)->statusPrev - = UR (port, UART_R_STATUS); - - /* There is presently no configuration option to enable IR. - Thus, we always disable it. */ - - BIT_SET (port, UART_R_CON, UARTEN | SIRDIS); - BIT_SET (port, UART_R_INTEN, RxTimeoutInt | RxInt); - - return 0; -} - -static void lh7a40xuart_shutdown (struct uart_port* port) -{ - free_irq (port->irq, port); - BIT_CLR (port, UART_R_FCON, BRK | FEN); - BIT_CLR (port, UART_R_CON, UARTEN); -} - -static void lh7a40xuart_set_termios (struct uart_port* port, - struct ktermios* termios, - struct ktermios* old) -{ - unsigned int con; - unsigned int inten; - unsigned int fcon; - unsigned long flags; - unsigned int baud; - unsigned int quot; - - baud = uart_get_baud_rate (port, termios, old, 8, port->uartclk/16); - quot = uart_get_divisor (port, baud); /* -1 performed elsewhere */ - - switch (termios->c_cflag & CSIZE) { - case CS5: - fcon = WLEN_5; - break; - case CS6: - fcon = WLEN_6; - break; - case CS7: - fcon = WLEN_7; - break; - case CS8: - default: - fcon = WLEN_8; - break; - } - if (termios->c_cflag & CSTOPB) - fcon |= STP2; - if (termios->c_cflag & PARENB) { - fcon |= PEN; - if (!(termios->c_cflag & PARODD)) - fcon |= EPS; - } - if (port->fifosize > 1) - fcon |= FEN; - - spin_lock_irqsave (&port->lock, flags); - - uart_update_timeout (port, termios->c_cflag, baud); - - port->read_status_mask = RxOverrunError; - if (termios->c_iflag & INPCK) - port->read_status_mask |= RxFramingError | RxParityError; - if (termios->c_iflag & (BRKINT | PARMRK)) - port->read_status_mask |= RxBreak; - - /* Figure mask for status we ignore */ - port->ignore_status_mask = 0; - if (termios->c_iflag & IGNPAR) - port->ignore_status_mask |= RxFramingError | RxParityError; - if (termios->c_iflag & IGNBRK) { - port->ignore_status_mask |= RxBreak; - /* Ignore overrun when ignorning parity */ - /* *** FIXME: is this in the right place? */ - if (termios->c_iflag & IGNPAR) - port->ignore_status_mask |= RxOverrunError; - } - - /* Ignore all receive errors when receive disabled */ - if ((termios->c_cflag & CREAD) == 0) - port->ignore_status_mask |= RxError; - - con = UR (port, UART_R_CON); - inten = (UR (port, UART_R_INTEN) & ~ModemInt); - - if (UART_ENABLE_MS (port, termios->c_cflag)) - inten |= ModemInt; - - BIT_CLR (port, UART_R_CON, UARTEN); /* Disable UART */ - UR (port, UART_R_INTEN) = 0; /* Disable interrupts */ - UR (port, UART_R_BRCON) = quot - 1; /* Set baud rate divisor */ - UR (port, UART_R_FCON) = fcon; /* Set FIFO and frame ctrl */ - UR (port, UART_R_INTEN) = inten; /* Enable interrupts */ - UR (port, UART_R_CON) = con; /* Restore UART mode */ - - spin_unlock_irqrestore(&port->lock, flags); -} - -static const char* lh7a40xuart_type (struct uart_port* port) -{ - return port->type == PORT_LH7A40X ? "LH7A40X" : NULL; -} - -static void lh7a40xuart_release_port (struct uart_port* port) -{ - release_mem_region (port->mapbase, UART_REG_SIZE); -} - -static int lh7a40xuart_request_port (struct uart_port* port) -{ - return request_mem_region (port->mapbase, UART_REG_SIZE, - "serial_lh7a40x") != NULL - ? 0 : -EBUSY; -} - -static void lh7a40xuart_config_port (struct uart_port* port, int flags) -{ - if (flags & UART_CONFIG_TYPE) { - port->type = PORT_LH7A40X; - lh7a40xuart_request_port (port); - } -} - -static int lh7a40xuart_verify_port (struct uart_port* port, - struct serial_struct* ser) -{ - int ret = 0; - - if (ser->type != PORT_UNKNOWN && ser->type != PORT_LH7A40X) - ret = -EINVAL; - if (ser->irq < 0 || ser->irq >= nr_irqs) - ret = -EINVAL; - if (ser->baud_base < 9600) /* *** FIXME: is this true? */ - ret = -EINVAL; - return ret; -} - -static struct uart_ops lh7a40x_uart_ops = { - .tx_empty = lh7a40xuart_tx_empty, - .set_mctrl = lh7a40xuart_set_mctrl, - .get_mctrl = lh7a40xuart_get_mctrl, - .stop_tx = lh7a40xuart_stop_tx, - .start_tx = lh7a40xuart_start_tx, - .stop_rx = lh7a40xuart_stop_rx, - .enable_ms = lh7a40xuart_enable_ms, - .break_ctl = lh7a40xuart_break_ctl, - .startup = lh7a40xuart_startup, - .shutdown = lh7a40xuart_shutdown, - .set_termios = lh7a40xuart_set_termios, - .type = lh7a40xuart_type, - .release_port = lh7a40xuart_release_port, - .request_port = lh7a40xuart_request_port, - .config_port = lh7a40xuart_config_port, - .verify_port = lh7a40xuart_verify_port, -}; - -static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = { - { - .port = { - .membase = (void*) io_p2v (UART1_PHYS), - .mapbase = UART1_PHYS, - .iotype = UPIO_MEM, - .irq = IRQ_UART1INTR, - .uartclk = 14745600/2, - .fifosize = 16, - .ops = &lh7a40x_uart_ops, - .flags = UPF_BOOT_AUTOCONF, - .line = 0, - }, - }, - { - .port = { - .membase = (void*) io_p2v (UART2_PHYS), - .mapbase = UART2_PHYS, - .iotype = UPIO_MEM, - .irq = IRQ_UART2INTR, - .uartclk = 14745600/2, - .fifosize = 16, - .ops = &lh7a40x_uart_ops, - .flags = UPF_BOOT_AUTOCONF, - .line = 1, - }, - }, - { - .port = { - .membase = (void*) io_p2v (UART3_PHYS), - .mapbase = UART3_PHYS, - .iotype = UPIO_MEM, - .irq = IRQ_UART3INTR, - .uartclk = 14745600/2, - .fifosize = 16, - .ops = &lh7a40x_uart_ops, - .flags = UPF_BOOT_AUTOCONF, - .line = 2, - }, - }, -}; - -#ifndef CONFIG_SERIAL_LH7A40X_CONSOLE -# define LH7A40X_CONSOLE NULL -#else -# define LH7A40X_CONSOLE &lh7a40x_console - -static void lh7a40xuart_console_putchar(struct uart_port *port, int ch) -{ - while (UR(port, UART_R_STATUS) & nTxRdy) - ; - UR(port, UART_R_DATA) = ch; -} - -static void lh7a40xuart_console_write (struct console* co, - const char* s, - unsigned int count) -{ - struct uart_port* port = &lh7a40x_ports[co->index].port; - unsigned int con = UR (port, UART_R_CON); - unsigned int inten = UR (port, UART_R_INTEN); - - - UR (port, UART_R_INTEN) = 0; /* Disable all interrupts */ - BIT_SET (port, UART_R_CON, UARTEN | SIRDIS); /* Enable UART */ - - uart_console_write(port, s, count, lh7a40xuart_console_putchar); - - /* Wait until all characters are sent */ - while (UR (port, UART_R_STATUS) & TxBusy) - ; - - /* Restore control and interrupt mask */ - UR (port, UART_R_CON) = con; - UR (port, UART_R_INTEN) = inten; -} - -static void __init lh7a40xuart_console_get_options (struct uart_port* port, - int* baud, - int* parity, - int* bits) -{ - if (UR (port, UART_R_CON) & UARTEN) { - unsigned int fcon = UR (port, UART_R_FCON); - unsigned int quot = UR (port, UART_R_BRCON) + 1; - - switch (fcon & (PEN | EPS)) { - default: *parity = 'n'; break; - case PEN: *parity = 'o'; break; - case PEN | EPS: *parity = 'e'; break; - } - - switch (fcon & WLEN) { - default: - case WLEN_8: *bits = 8; break; - case WLEN_7: *bits = 7; break; - case WLEN_6: *bits = 6; break; - case WLEN_5: *bits = 5; break; - } - - *baud = port->uartclk/(16*quot); - } -} - -static int __init lh7a40xuart_console_setup (struct console* co, char* options) -{ - struct uart_port* port; - int baud = 38400; - int bits = 8; - int parity = 'n'; - int flow = 'n'; - - if (co->index >= DEV_NR) /* Bounds check on device number */ - co->index = 0; - port = &lh7a40x_ports[co->index].port; - - if (options) - uart_parse_options (options, &baud, &parity, &bits, &flow); - else - lh7a40xuart_console_get_options (port, &baud, &parity, &bits); - - return uart_set_options (port, co, baud, parity, bits, flow); -} - -static struct uart_driver lh7a40x_reg; -static struct console lh7a40x_console = { - .name = "ttyAM", - .write = lh7a40xuart_console_write, - .device = uart_console_device, - .setup = lh7a40xuart_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, - .data = &lh7a40x_reg, -}; - -static int __init lh7a40xuart_console_init(void) -{ - register_console (&lh7a40x_console); - return 0; -} - -console_initcall (lh7a40xuart_console_init); - -#endif - -static struct uart_driver lh7a40x_reg = { - .owner = THIS_MODULE, - .driver_name = "ttyAM", - .dev_name = "ttyAM", - .major = DEV_MAJOR, - .minor = DEV_MINOR, - .nr = DEV_NR, - .cons = LH7A40X_CONSOLE, -}; - -static int __init lh7a40xuart_init(void) -{ - int ret; - - printk (KERN_INFO "serial: LH7A40X serial driver\n"); - - ret = uart_register_driver (&lh7a40x_reg); - - if (ret == 0) { - int i; - - for (i = 0; i < DEV_NR; i++) { - /* UART3, when used, requires GPIO pin reallocation */ - if (lh7a40x_ports[i].port.mapbase == UART3_PHYS) - GPIO_PINMUX |= 1<<3; - uart_add_one_port (&lh7a40x_reg, - &lh7a40x_ports[i].port); - } - } - return ret; -} - -static void __exit lh7a40xuart_exit(void) -{ - int i; - - for (i = 0; i < DEV_NR; i++) - uart_remove_one_port (&lh7a40x_reg, &lh7a40x_ports[i].port); - - uart_unregister_driver (&lh7a40x_reg); -} - -module_init (lh7a40xuart_init); -module_exit (lh7a40xuart_exit); - -MODULE_AUTHOR ("Marc Singer"); -MODULE_DESCRIPTION ("Sharp LH7A40X serial port driver"); -MODULE_LICENSE ("GPL"); diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index fceea5e4e02f..41b6e51188e4 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -31,7 +31,6 @@ config USB_ARCH_HAS_OHCI # ARM: default y if SA1111 default y if ARCH_OMAP - default y if ARCH_LH7A404 default y if ARCH_S3C2410 default y if PXA27x default y if PXA3xx diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 1dc9739277b4..08a48ae23745 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -176,18 +176,6 @@ config USB_FSL_USB2 default USB_GADGET select USB_GADGET_SELECTED -config USB_GADGET_LH7A40X - boolean "LH7A40X" - depends on ARCH_LH7A40X - help - This driver provides USB Device Controller driver for LH7A40x - -config USB_LH7A40X - tristate - depends on USB_GADGET_LH7A40X - default USB_GADGET - select USB_GADGET_SELECTED - config USB_GADGET_OMAP boolean "OMAP USB Device Controller" depends on ARCH_OMAP diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 55f5e8ae5924..a2f7f9a4f4a8 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_USB_PXA27X) += pxa27x_udc.o obj-$(CONFIG_USB_IMX) += imx_udc.o obj-$(CONFIG_USB_GOKU) += goku_udc.o obj-$(CONFIG_USB_OMAP) += omap_udc.o -obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o obj-$(CONFIG_USB_S3C2410) += s3c2410_udc.o obj-$(CONFIG_USB_AT91) += at91_udc.o obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index 5c2720d64ffa..e896f6359dfe 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h @@ -45,12 +45,6 @@ #define gadget_is_goku(g) 0 #endif -#ifdef CONFIG_USB_GADGET_LH7A40X -#define gadget_is_lh7a40x(g) !strcmp("lh7a40x_udc", (g)->name) -#else -#define gadget_is_lh7a40x(g) 0 -#endif - #ifdef CONFIG_USB_GADGET_OMAP #define gadget_is_omap(g) !strcmp("omap_udc", (g)->name) #else @@ -181,8 +175,6 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) return 0x06; else if (gadget_is_omap(gadget)) return 0x08; - else if (gadget_is_lh7a40x(gadget)) - return 0x09; else if (gadget_is_pxa27x(gadget)) return 0x11; else if (gadget_is_s3c2410(gadget)) diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c deleted file mode 100644 index 6b58bd8ce623..000000000000 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ /dev/null @@ -1,2152 +0,0 @@ -/* - * linux/drivers/usb/gadget/lh7a40x_udc.c - * Sharp LH7A40x on-chip full speed USB device controllers - * - * Copyright (C) 2004 Mikko Lahteenmaki, Nordic ID - * Copyright (C) 2004 Bo Henriksen, Nordic ID - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include - -#include "lh7a40x_udc.h" - -//#define DEBUG printk -//#define DEBUG_EP0 printk -//#define DEBUG_SETUP printk - -#ifndef DEBUG_EP0 -# define DEBUG_EP0(fmt,args...) -#endif -#ifndef DEBUG_SETUP -# define DEBUG_SETUP(fmt,args...) -#endif -#ifndef DEBUG -# define NO_STATES -# define DEBUG(fmt,args...) -#endif - -#define DRIVER_DESC "LH7A40x USB Device Controller" -#define DRIVER_VERSION __DATE__ - -#ifndef _BIT /* FIXME - what happended to _BIT in 2.6.7bk18? */ -#define _BIT(x) (1<<(x)) -#endif - -struct lh7a40x_udc *the_controller; - -static const char driver_name[] = "lh7a40x_udc"; -static const char driver_desc[] = DRIVER_DESC; -static const char ep0name[] = "ep0-control"; - -/* - Local definintions. -*/ - -#ifndef NO_STATES -static char *state_names[] = { - "WAIT_FOR_SETUP", - "DATA_STATE_XMIT", - "DATA_STATE_NEED_ZLP", - "WAIT_FOR_OUT_STATUS", - "DATA_STATE_RECV" -}; -#endif - -/* - Local declarations. -*/ -static int lh7a40x_ep_enable(struct usb_ep *ep, - const struct usb_endpoint_descriptor *); -static int lh7a40x_ep_disable(struct usb_ep *ep); -static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep, gfp_t); -static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *); -static int lh7a40x_queue(struct usb_ep *ep, struct usb_request *, gfp_t); -static int lh7a40x_dequeue(struct usb_ep *ep, struct usb_request *); -static int lh7a40x_set_halt(struct usb_ep *ep, int); -static int lh7a40x_fifo_status(struct usb_ep *ep); -static void lh7a40x_fifo_flush(struct usb_ep *ep); -static void lh7a40x_ep0_kick(struct lh7a40x_udc *dev, struct lh7a40x_ep *ep); -static void lh7a40x_handle_ep0(struct lh7a40x_udc *dev, u32 intr); - -static void done(struct lh7a40x_ep *ep, struct lh7a40x_request *req, - int status); -static void pio_irq_enable(int bEndpointAddress); -static void pio_irq_disable(int bEndpointAddress); -static void stop_activity(struct lh7a40x_udc *dev, - struct usb_gadget_driver *driver); -static void flush(struct lh7a40x_ep *ep); -static void udc_enable(struct lh7a40x_udc *dev); -static void udc_set_address(struct lh7a40x_udc *dev, unsigned char address); - -static struct usb_ep_ops lh7a40x_ep_ops = { - .enable = lh7a40x_ep_enable, - .disable = lh7a40x_ep_disable, - - .alloc_request = lh7a40x_alloc_request, - .free_request = lh7a40x_free_request, - - .queue = lh7a40x_queue, - .dequeue = lh7a40x_dequeue, - - .set_halt = lh7a40x_set_halt, - .fifo_status = lh7a40x_fifo_status, - .fifo_flush = lh7a40x_fifo_flush, -}; - -/* Inline code */ - -static __inline__ int write_packet(struct lh7a40x_ep *ep, - struct lh7a40x_request *req, int max) -{ - u8 *buf; - int length, count; - volatile u32 *fifo = (volatile u32 *)ep->fifo; - - buf = req->req.buf + req->req.actual; - prefetch(buf); - - length = req->req.length - req->req.actual; - length = min(length, max); - req->req.actual += length; - - DEBUG("Write %d (max %d), fifo %p\n", length, max, fifo); - - count = length; - while (count--) { - *fifo = *buf++; - } - - return length; -} - -static __inline__ void usb_set_index(u32 ep) -{ - *(volatile u32 *)io_p2v(USB_INDEX) = ep; -} - -static __inline__ u32 usb_read(u32 port) -{ - return *(volatile u32 *)io_p2v(port); -} - -static __inline__ void usb_write(u32 val, u32 port) -{ - *(volatile u32 *)io_p2v(port) = val; -} - -static __inline__ void usb_set(u32 val, u32 port) -{ - volatile u32 *ioport = (volatile u32 *)io_p2v(port); - u32 after = (*ioport) | val; - *ioport = after; -} - -static __inline__ void usb_clear(u32 val, u32 port) -{ - volatile u32 *ioport = (volatile u32 *)io_p2v(port); - u32 after = (*ioport) & ~val; - *ioport = after; -} - -/*-------------------------------------------------------------------------*/ - -#define GPIO_PORTC_DR (0x80000E08) -#define GPIO_PORTC_DDR (0x80000E18) -#define GPIO_PORTC_PDR (0x80000E70) - -/* get port C pin data register */ -#define get_portc_pdr(bit) ((usb_read(GPIO_PORTC_PDR) & _BIT(bit)) != 0) -/* get port C data direction register */ -#define get_portc_ddr(bit) ((usb_read(GPIO_PORTC_DDR) & _BIT(bit)) != 0) -/* set port C data register */ -#define set_portc_dr(bit, val) (val ? usb_set(_BIT(bit), GPIO_PORTC_DR) : usb_clear(_BIT(bit), GPIO_PORTC_DR)) -/* set port C data direction register */ -#define set_portc_ddr(bit, val) (val ? usb_set(_BIT(bit), GPIO_PORTC_DDR) : usb_clear(_BIT(bit), GPIO_PORTC_DDR)) - -/* - * LPD7A404 GPIO's: - * Port C bit 1 = USB Port 1 Power Enable - * Port C bit 2 = USB Port 1 Data Carrier Detect - */ -#define is_usb_connected() get_portc_pdr(2) - -#ifdef CONFIG_USB_GADGET_DEBUG_FILES - -static const char proc_node_name[] = "driver/udc"; - -static int -udc_proc_read(char *page, char **start, off_t off, int count, - int *eof, void *_dev) -{ - char *buf = page; - struct lh7a40x_udc *dev = _dev; - char *next = buf; - unsigned size = count; - unsigned long flags; - int t; - - if (off != 0) - return 0; - - local_irq_save(flags); - - /* basic device status */ - t = scnprintf(next, size, - DRIVER_DESC "\n" - "%s version: %s\n" - "Gadget driver: %s\n" - "Host: %s\n\n", - driver_name, DRIVER_VERSION, - dev->driver ? dev->driver->driver.name : "(none)", - is_usb_connected()? "full speed" : "disconnected"); - size -= t; - next += t; - - t = scnprintf(next, size, - "GPIO:\n" - " Port C bit 1: %d, dir %d\n" - " Port C bit 2: %d, dir %d\n\n", - get_portc_pdr(1), get_portc_ddr(1), - get_portc_pdr(2), get_portc_ddr(2) - ); - size -= t; - next += t; - - t = scnprintf(next, size, - "DCP pullup: %d\n\n", - (usb_read(USB_PM) & PM_USB_DCP) != 0); - size -= t; - next += t; - - local_irq_restore(flags); - *eof = 1; - return count - size; -} - -#define create_proc_files() create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev) -#define remove_proc_files() remove_proc_entry(proc_node_name, NULL) - -#else /* !CONFIG_USB_GADGET_DEBUG_FILES */ - -#define create_proc_files() do {} while (0) -#define remove_proc_files() do {} while (0) - -#endif /* CONFIG_USB_GADGET_DEBUG_FILES */ - -/* - * udc_disable - disable USB device controller - */ -static void udc_disable(struct lh7a40x_udc *dev) -{ - DEBUG("%s, %p\n", __func__, dev); - - udc_set_address(dev, 0); - - /* Disable interrupts */ - usb_write(0, USB_IN_INT_EN); - usb_write(0, USB_OUT_INT_EN); - usb_write(0, USB_INT_EN); - - /* Disable the USB */ - usb_write(0, USB_PM); - -#ifdef CONFIG_ARCH_LH7A404 - /* Disable USB power */ - set_portc_dr(1, 0); -#endif - - /* if hardware supports it, disconnect from usb */ - /* make_usb_disappear(); */ - - dev->ep0state = WAIT_FOR_SETUP; - dev->gadget.speed = USB_SPEED_UNKNOWN; - dev->usb_address = 0; -} - -/* - * udc_reinit - initialize software state - */ -static void udc_reinit(struct lh7a40x_udc *dev) -{ - u32 i; - - DEBUG("%s, %p\n", __func__, dev); - - /* device/ep0 records init */ - INIT_LIST_HEAD(&dev->gadget.ep_list); - INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); - dev->ep0state = WAIT_FOR_SETUP; - - /* basic endpoint records init */ - for (i = 0; i < UDC_MAX_ENDPOINTS; i++) { - struct lh7a40x_ep *ep = &dev->ep[i]; - - if (i != 0) - list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list); - - ep->desc = 0; - ep->stopped = 0; - INIT_LIST_HEAD(&ep->queue); - ep->pio_irqs = 0; - } - - /* the rest was statically initialized, and is read-only */ -} - -#define BYTES2MAXP(x) (x / 8) -#define MAXP2BYTES(x) (x * 8) - -/* until it's enabled, this UDC should be completely invisible - * to any USB host. - */ -static void udc_enable(struct lh7a40x_udc *dev) -{ - int ep; - - DEBUG("%s, %p\n", __func__, dev); - - dev->gadget.speed = USB_SPEED_UNKNOWN; - -#ifdef CONFIG_ARCH_LH7A404 - /* Set Port C bit 1 & 2 as output */ - set_portc_ddr(1, 1); - set_portc_ddr(2, 1); - - /* Enable USB power */ - set_portc_dr(1, 0); -#endif - - /* - * C.f Chapter 18.1.3.1 Initializing the USB - */ - - /* Disable the USB */ - usb_clear(PM_USB_ENABLE, USB_PM); - - /* Reset APB & I/O sides of the USB */ - usb_set(USB_RESET_APB | USB_RESET_IO, USB_RESET); - mdelay(5); - usb_clear(USB_RESET_APB | USB_RESET_IO, USB_RESET); - - /* Set MAXP values for each */ - for (ep = 0; ep < UDC_MAX_ENDPOINTS; ep++) { - struct lh7a40x_ep *ep_reg = &dev->ep[ep]; - u32 csr; - - usb_set_index(ep); - - switch (ep_reg->ep_type) { - case ep_bulk_in: - case ep_interrupt: - usb_clear(USB_IN_CSR2_USB_DMA_EN | USB_IN_CSR2_AUTO_SET, - ep_reg->csr2); - /* Fall through */ - case ep_control: - usb_write(BYTES2MAXP(ep_maxpacket(ep_reg)), - USB_IN_MAXP); - break; - case ep_bulk_out: - usb_clear(USB_OUT_CSR2_USB_DMA_EN | - USB_OUT_CSR2_AUTO_CLR, ep_reg->csr2); - usb_write(BYTES2MAXP(ep_maxpacket(ep_reg)), - USB_OUT_MAXP); - break; - } - - /* Read & Write CSR1, just in case */ - csr = usb_read(ep_reg->csr1); - usb_write(csr, ep_reg->csr1); - - flush(ep_reg); - } - - /* Disable interrupts */ - usb_write(0, USB_IN_INT_EN); - usb_write(0, USB_OUT_INT_EN); - usb_write(0, USB_INT_EN); - - /* Enable interrupts */ - usb_set(USB_IN_INT_EP0, USB_IN_INT_EN); - usb_set(USB_INT_RESET_INT | USB_INT_RESUME_INT, USB_INT_EN); - /* Dont enable rest of the interrupts */ - /* usb_set(USB_IN_INT_EP3 | USB_IN_INT_EP1 | USB_IN_INT_EP0, USB_IN_INT_EN); - usb_set(USB_OUT_INT_EP2, USB_OUT_INT_EN); */ - - /* Enable SUSPEND */ - usb_set(PM_ENABLE_SUSPEND, USB_PM); - - /* Enable the USB */ - usb_set(PM_USB_ENABLE, USB_PM); - -#ifdef CONFIG_ARCH_LH7A404 - /* NOTE: DOES NOT WORK! */ - /* Let host detect UDC: - * Software must write a 0 to the PMR:DCP_CTRL bit to turn this - * transistor on and pull the USBDP pin HIGH. - */ - /* usb_clear(PM_USB_DCP, USB_PM); - usb_set(PM_USB_DCP, USB_PM); */ -#endif -} - -/* - Register entry point for the peripheral controller driver. -*/ -int usb_gadget_probe_driver(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)) -{ - struct lh7a40x_udc *dev = the_controller; - int retval; - - DEBUG("%s: %s\n", __func__, driver->driver.name); - - if (!driver - || driver->speed != USB_SPEED_FULL - || !bind - || !driver->disconnect - || !driver->setup) - return -EINVAL; - if (!dev) - return -ENODEV; - if (dev->driver) - return -EBUSY; - - /* first hook up the driver ... */ - dev->driver = driver; - dev->gadget.dev.driver = &driver->driver; - - device_add(&dev->gadget.dev); - retval = bind(&dev->gadget); - if (retval) { - printk(KERN_WARNING "%s: bind to driver %s --> error %d\n", - dev->gadget.name, driver->driver.name, retval); - device_del(&dev->gadget.dev); - - dev->driver = 0; - dev->gadget.dev.driver = 0; - return retval; - } - - /* ... then enable host detection and ep0; and we're ready - * for set_configuration as well as eventual disconnect. - * NOTE: this shouldn't power up until later. - */ - printk(KERN_WARNING "%s: registered gadget driver '%s'\n", - dev->gadget.name, driver->driver.name); - - udc_enable(dev); - - return 0; -} -EXPORT_SYMBOL(usb_gadget_probe_driver); - -/* - Unregister entry point for the peripheral controller driver. -*/ -int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) -{ - struct lh7a40x_udc *dev = the_controller; - unsigned long flags; - - if (!dev) - return -ENODEV; - if (!driver || driver != dev->driver || !driver->unbind) - return -EINVAL; - - spin_lock_irqsave(&dev->lock, flags); - dev->driver = 0; - stop_activity(dev, driver); - spin_unlock_irqrestore(&dev->lock, flags); - - driver->unbind(&dev->gadget); - dev->gadget.dev.driver = NULL; - device_del(&dev->gadget.dev); - - udc_disable(dev); - - DEBUG("unregistered gadget driver '%s'\n", driver->driver.name); - return 0; -} - -EXPORT_SYMBOL(usb_gadget_unregister_driver); - -/*-------------------------------------------------------------------------*/ - -/** Write request to FIFO (max write == maxp size) - * Return: 0 = still running, 1 = completed, negative = errno - * NOTE: INDEX register must be set for EP - */ -static int write_fifo(struct lh7a40x_ep *ep, struct lh7a40x_request *req) -{ - u32 max; - u32 csr; - - max = le16_to_cpu(ep->desc->wMaxPacketSize); - - csr = usb_read(ep->csr1); - DEBUG("CSR: %x %d\n", csr, csr & USB_IN_CSR1_FIFO_NOT_EMPTY); - - if (!(csr & USB_IN_CSR1_FIFO_NOT_EMPTY)) { - unsigned count; - int is_last, is_short; - - count = write_packet(ep, req, max); - usb_set(USB_IN_CSR1_IN_PKT_RDY, ep->csr1); - - /* last packet is usually short (or a zlp) */ - if (unlikely(count != max)) - is_last = is_short = 1; - else { - if (likely(req->req.length != req->req.actual) - || req->req.zero) - is_last = 0; - else - is_last = 1; - /* interrupt/iso maxpacket may not fill the fifo */ - is_short = unlikely(max < ep_maxpacket(ep)); - } - - DEBUG("%s: wrote %s %d bytes%s%s %d left %p\n", __func__, - ep->ep.name, count, - is_last ? "/L" : "", is_short ? "/S" : "", - req->req.length - req->req.actual, req); - - /* requests complete when all IN data is in the FIFO */ - if (is_last) { - done(ep, req, 0); - if (list_empty(&ep->queue)) { - pio_irq_disable(ep_index(ep)); - } - return 1; - } - } else { - DEBUG("Hmm.. %d ep FIFO is not empty!\n", ep_index(ep)); - } - - return 0; -} - -/** Read to request from FIFO (max read == bytes in fifo) - * Return: 0 = still running, 1 = completed, negative = errno - * NOTE: INDEX register must be set for EP - */ -static int read_fifo(struct lh7a40x_ep *ep, struct lh7a40x_request *req) -{ - u32 csr; - u8 *buf; - unsigned bufferspace, count, is_short; - volatile u32 *fifo = (volatile u32 *)ep->fifo; - - /* make sure there's a packet in the FIFO. */ - csr = usb_read(ep->csr1); - if (!(csr & USB_OUT_CSR1_OUT_PKT_RDY)) { - DEBUG("%s: Packet NOT ready!\n", __func__); - return -EINVAL; - } - - buf = req->req.buf + req->req.actual; - prefetchw(buf); - bufferspace = req->req.length - req->req.actual; - - /* read all bytes from this packet */ - count = usb_read(USB_OUT_FIFO_WC1); - req->req.actual += min(count, bufferspace); - - is_short = (count < ep->ep.maxpacket); - DEBUG("read %s %02x, %d bytes%s req %p %d/%d\n", - ep->ep.name, csr, count, - is_short ? "/S" : "", req, req->req.actual, req->req.length); - - while (likely(count-- != 0)) { - u8 byte = (u8) (*fifo & 0xff); - - if (unlikely(bufferspace == 0)) { - /* this happens when the driver's buffer - * is smaller than what the host sent. - * discard the extra data. - */ - if (req->req.status != -EOVERFLOW) - printk(KERN_WARNING "%s overflow %d\n", - ep->ep.name, count); - req->req.status = -EOVERFLOW; - } else { - *buf++ = byte; - bufferspace--; - } - } - - usb_clear(USB_OUT_CSR1_OUT_PKT_RDY, ep->csr1); - - /* completion */ - if (is_short || req->req.actual == req->req.length) { - done(ep, req, 0); - usb_set(USB_OUT_CSR1_FIFO_FLUSH, ep->csr1); - - if (list_empty(&ep->queue)) - pio_irq_disable(ep_index(ep)); - return 1; - } - - /* finished that packet. the next one may be waiting... */ - return 0; -} - -/* - * done - retire a request; caller blocked irqs - * INDEX register is preserved to keep same - */ -static void done(struct lh7a40x_ep *ep, struct lh7a40x_request *req, int status) -{ - unsigned int stopped = ep->stopped; - u32 index; - - DEBUG("%s, %p\n", __func__, ep); - list_del_init(&req->queue); - - if (likely(req->req.status == -EINPROGRESS)) - req->req.status = status; - else - status = req->req.status; - - if (status && status != -ESHUTDOWN) - DEBUG("complete %s req %p stat %d len %u/%u\n", - ep->ep.name, &req->req, status, - req->req.actual, req->req.length); - - /* don't modify queue heads during completion callback */ - ep->stopped = 1; - /* Read current index (completion may modify it) */ - index = usb_read(USB_INDEX); - - spin_unlock(&ep->dev->lock); - req->req.complete(&ep->ep, &req->req); - spin_lock(&ep->dev->lock); - - /* Restore index */ - usb_set_index(index); - ep->stopped = stopped; -} - -/** Enable EP interrupt */ -static void pio_irq_enable(int ep) -{ - DEBUG("%s: %d\n", __func__, ep); - - switch (ep) { - case 1: - usb_set(USB_IN_INT_EP1, USB_IN_INT_EN); - break; - case 2: - usb_set(USB_OUT_INT_EP2, USB_OUT_INT_EN); - break; - case 3: - usb_set(USB_IN_INT_EP3, USB_IN_INT_EN); - break; - default: - DEBUG("Unknown endpoint: %d\n", ep); - break; - } -} - -/** Disable EP interrupt */ -static void pio_irq_disable(int ep) -{ - DEBUG("%s: %d\n", __func__, ep); - - switch (ep) { - case 1: - usb_clear(USB_IN_INT_EP1, USB_IN_INT_EN); - break; - case 2: - usb_clear(USB_OUT_INT_EP2, USB_OUT_INT_EN); - break; - case 3: - usb_clear(USB_IN_INT_EP3, USB_IN_INT_EN); - break; - default: - DEBUG("Unknown endpoint: %d\n", ep); - break; - } -} - -/* - * nuke - dequeue ALL requests - */ -void nuke(struct lh7a40x_ep *ep, int status) -{ - struct lh7a40x_request *req; - - DEBUG("%s, %p\n", __func__, ep); - - /* Flush FIFO */ - flush(ep); - - /* called with irqs blocked */ - while (!list_empty(&ep->queue)) { - req = list_entry(ep->queue.next, struct lh7a40x_request, queue); - done(ep, req, status); - } - - /* Disable IRQ if EP is enabled (has descriptor) */ - if (ep->desc) - pio_irq_disable(ep_index(ep)); -} - -/* -void nuke_all(struct lh7a40x_udc *dev) -{ - int n; - for(n=0; nep[n]; - usb_set_index(n); - nuke(ep, 0); - } -}*/ - -/* -static void flush_all(struct lh7a40x_udc *dev) -{ - int n; - for (n = 0; n < UDC_MAX_ENDPOINTS; n++) - { - struct lh7a40x_ep *ep = &dev->ep[n]; - flush(ep); - } -} -*/ - -/** Flush EP - * NOTE: INDEX register must be set before this call - */ -static void flush(struct lh7a40x_ep *ep) -{ - DEBUG("%s, %p\n", __func__, ep); - - switch (ep->ep_type) { - case ep_control: - /* check, by implication c.f. 15.1.2.11 */ - break; - - case ep_bulk_in: - case ep_interrupt: - /* if(csr & USB_IN_CSR1_IN_PKT_RDY) */ - usb_set(USB_IN_CSR1_FIFO_FLUSH, ep->csr1); - break; - - case ep_bulk_out: - /* if(csr & USB_OUT_CSR1_OUT_PKT_RDY) */ - usb_set(USB_OUT_CSR1_FIFO_FLUSH, ep->csr1); - break; - } -} - -/** - * lh7a40x_in_epn - handle IN interrupt - */ -static void lh7a40x_in_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr) -{ - u32 csr; - struct lh7a40x_ep *ep = &dev->ep[ep_idx]; - struct lh7a40x_request *req; - - usb_set_index(ep_idx); - - csr = usb_read(ep->csr1); - DEBUG("%s: %d, csr %x\n", __func__, ep_idx, csr); - - if (csr & USB_IN_CSR1_SENT_STALL) { - DEBUG("USB_IN_CSR1_SENT_STALL\n"); - usb_set(USB_IN_CSR1_SENT_STALL /*|USB_IN_CSR1_SEND_STALL */ , - ep->csr1); - return; - } - - if (!ep->desc) { - DEBUG("%s: NO EP DESC\n", __func__); - return; - } - - if (list_empty(&ep->queue)) - req = 0; - else - req = list_entry(ep->queue.next, struct lh7a40x_request, queue); - - DEBUG("req: %p\n", req); - - if (!req) - return; - - write_fifo(ep, req); -} - -/* ********************************************************************************************* */ -/* Bulk OUT (recv) - */ - -static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr) -{ - struct lh7a40x_ep *ep = &dev->ep[ep_idx]; - struct lh7a40x_request *req; - - DEBUG("%s: %d\n", __func__, ep_idx); - - usb_set_index(ep_idx); - - if (ep->desc) { - u32 csr; - csr = usb_read(ep->csr1); - - while ((csr = - usb_read(ep-> - csr1)) & (USB_OUT_CSR1_OUT_PKT_RDY | - USB_OUT_CSR1_SENT_STALL)) { - DEBUG("%s: %x\n", __func__, csr); - - if (csr & USB_OUT_CSR1_SENT_STALL) { - DEBUG("%s: stall sent, flush fifo\n", - __func__); - /* usb_set(USB_OUT_CSR1_FIFO_FLUSH, ep->csr1); */ - flush(ep); - } else if (csr & USB_OUT_CSR1_OUT_PKT_RDY) { - if (list_empty(&ep->queue)) - req = 0; - else - req = - list_entry(ep->queue.next, - struct lh7a40x_request, - queue); - - if (!req) { - printk(KERN_WARNING - "%s: NULL REQ %d\n", - __func__, ep_idx); - flush(ep); - break; - } else { - read_fifo(ep, req); - } - } - - } - - } else { - /* Throw packet away.. */ - printk(KERN_WARNING "%s: No descriptor?!?\n", __func__); - flush(ep); - } -} - -static void stop_activity(struct lh7a40x_udc *dev, - struct usb_gadget_driver *driver) -{ - int i; - - /* don't disconnect drivers more than once */ - if (dev->gadget.speed == USB_SPEED_UNKNOWN) - driver = 0; - dev->gadget.speed = USB_SPEED_UNKNOWN; - - /* prevent new request submissions, kill any outstanding requests */ - for (i = 0; i < UDC_MAX_ENDPOINTS; i++) { - struct lh7a40x_ep *ep = &dev->ep[i]; - ep->stopped = 1; - - usb_set_index(i); - nuke(ep, -ESHUTDOWN); - } - - /* report disconnect; the driver is already quiesced */ - if (driver) { - spin_unlock(&dev->lock); - driver->disconnect(&dev->gadget); - spin_lock(&dev->lock); - } - - /* re-init driver-visible data structures */ - udc_reinit(dev); -} - -/** Handle USB RESET interrupt - */ -static void lh7a40x_reset_intr(struct lh7a40x_udc *dev) -{ -#if 0 /* def CONFIG_ARCH_LH7A404 */ - /* Does not work always... */ - - DEBUG("%s: %d\n", __func__, dev->usb_address); - - if (!dev->usb_address) { - /*usb_set(USB_RESET_IO, USB_RESET); - mdelay(5); - usb_clear(USB_RESET_IO, USB_RESET); */ - return; - } - /* Put the USB controller into reset. */ - usb_set(USB_RESET_IO, USB_RESET); - - /* Set Device ID to 0 */ - udc_set_address(dev, 0); - - /* Let PLL2 settle down */ - mdelay(5); - - /* Release the USB controller from reset */ - usb_clear(USB_RESET_IO, USB_RESET); - - /* Re-enable UDC */ - udc_enable(dev); - -#endif - dev->gadget.speed = USB_SPEED_FULL; -} - -/* - * lh7a40x usb client interrupt handler. - */ -static irqreturn_t lh7a40x_udc_irq(int irq, void *_dev) -{ - struct lh7a40x_udc *dev = _dev; - - DEBUG("\n\n"); - - spin_lock(&dev->lock); - - for (;;) { - u32 intr_in = usb_read(USB_IN_INT); - u32 intr_out = usb_read(USB_OUT_INT); - u32 intr_int = usb_read(USB_INT); - - /* Test also against enable bits.. (lh7a40x errata).. Sigh.. */ - u32 in_en = usb_read(USB_IN_INT_EN); - u32 out_en = usb_read(USB_OUT_INT_EN); - - if (!intr_out && !intr_in && !intr_int) - break; - - DEBUG("%s (on state %s)\n", __func__, - state_names[dev->ep0state]); - DEBUG("intr_out = %x\n", intr_out); - DEBUG("intr_in = %x\n", intr_in); - DEBUG("intr_int = %x\n", intr_int); - - if (intr_in) { - usb_write(intr_in, USB_IN_INT); - - if ((intr_in & USB_IN_INT_EP1) - && (in_en & USB_IN_INT_EP1)) { - DEBUG("USB_IN_INT_EP1\n"); - lh7a40x_in_epn(dev, 1, intr_in); - } - if ((intr_in & USB_IN_INT_EP3) - && (in_en & USB_IN_INT_EP3)) { - DEBUG("USB_IN_INT_EP3\n"); - lh7a40x_in_epn(dev, 3, intr_in); - } - if (intr_in & USB_IN_INT_EP0) { - DEBUG("USB_IN_INT_EP0 (control)\n"); - lh7a40x_handle_ep0(dev, intr_in); - } - } - - if (intr_out) { - usb_write(intr_out, USB_OUT_INT); - - if ((intr_out & USB_OUT_INT_EP2) - && (out_en & USB_OUT_INT_EP2)) { - DEBUG("USB_OUT_INT_EP2\n"); - lh7a40x_out_epn(dev, 2, intr_out); - } - } - - if (intr_int) { - usb_write(intr_int, USB_INT); - - if (intr_int & USB_INT_RESET_INT) { - lh7a40x_reset_intr(dev); - } - - if (intr_int & USB_INT_RESUME_INT) { - DEBUG("USB resume\n"); - - if (dev->gadget.speed != USB_SPEED_UNKNOWN - && dev->driver - && dev->driver->resume - && is_usb_connected()) { - dev->driver->resume(&dev->gadget); - } - } - - if (intr_int & USB_INT_SUSPEND_INT) { - DEBUG("USB suspend%s\n", - is_usb_connected()? "" : "+disconnect"); - if (!is_usb_connected()) { - stop_activity(dev, dev->driver); - } else if (dev->gadget.speed != - USB_SPEED_UNKNOWN && dev->driver - && dev->driver->suspend) { - dev->driver->suspend(&dev->gadget); - } - } - - } - } - - spin_unlock(&dev->lock); - - return IRQ_HANDLED; -} - -static int lh7a40x_ep_enable(struct usb_ep *_ep, - const struct usb_endpoint_descriptor *desc) -{ - struct lh7a40x_ep *ep; - struct lh7a40x_udc *dev; - unsigned long flags; - - DEBUG("%s, %p\n", __func__, _ep); - - ep = container_of(_ep, struct lh7a40x_ep, ep); - if (!_ep || !desc || ep->desc || _ep->name == ep0name - || desc->bDescriptorType != USB_DT_ENDPOINT - || ep->bEndpointAddress != desc->bEndpointAddress - || ep_maxpacket(ep) < le16_to_cpu(desc->wMaxPacketSize)) { - DEBUG("%s, bad ep or descriptor\n", __func__); - return -EINVAL; - } - - /* xfer types must match, except that interrupt ~= bulk */ - if (ep->bmAttributes != desc->bmAttributes - && ep->bmAttributes != USB_ENDPOINT_XFER_BULK - && desc->bmAttributes != USB_ENDPOINT_XFER_INT) { - DEBUG("%s, %s type mismatch\n", __func__, _ep->name); - return -EINVAL; - } - - /* hardware _could_ do smaller, but driver doesn't */ - if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK - && le16_to_cpu(desc->wMaxPacketSize) != ep_maxpacket(ep)) - || !desc->wMaxPacketSize) { - DEBUG("%s, bad %s maxpacket\n", __func__, _ep->name); - return -ERANGE; - } - - dev = ep->dev; - if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) { - DEBUG("%s, bogus device state\n", __func__); - return -ESHUTDOWN; - } - - spin_lock_irqsave(&ep->dev->lock, flags); - - ep->stopped = 0; - ep->desc = desc; - ep->pio_irqs = 0; - ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize); - - spin_unlock_irqrestore(&ep->dev->lock, flags); - - /* Reset halt state (does flush) */ - lh7a40x_set_halt(_ep, 0); - - DEBUG("%s: enabled %s\n", __func__, _ep->name); - return 0; -} - -/** Disable EP - * NOTE: Sets INDEX register - */ -static int lh7a40x_ep_disable(struct usb_ep *_ep) -{ - struct lh7a40x_ep *ep; - unsigned long flags; - - DEBUG("%s, %p\n", __func__, _ep); - - ep = container_of(_ep, struct lh7a40x_ep, ep); - if (!_ep || !ep->desc) { - DEBUG("%s, %s not enabled\n", __func__, - _ep ? ep->ep.name : NULL); - return -EINVAL; - } - - spin_lock_irqsave(&ep->dev->lock, flags); - - usb_set_index(ep_index(ep)); - - /* Nuke all pending requests (does flush) */ - nuke(ep, -ESHUTDOWN); - - /* Disable ep IRQ */ - pio_irq_disable(ep_index(ep)); - - ep->desc = 0; - ep->stopped = 1; - - spin_unlock_irqrestore(&ep->dev->lock, flags); - - DEBUG("%s: disabled %s\n", __func__, _ep->name); - return 0; -} - -static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep, - gfp_t gfp_flags) -{ - struct lh7a40x_request *req; - - DEBUG("%s, %p\n", __func__, ep); - - req = kzalloc(sizeof(*req), gfp_flags); - if (!req) - return 0; - - INIT_LIST_HEAD(&req->queue); - - return &req->req; -} - -static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *_req) -{ - struct lh7a40x_request *req; - - DEBUG("%s, %p\n", __func__, ep); - - req = container_of(_req, struct lh7a40x_request, req); - WARN_ON(!list_empty(&req->queue)); - kfree(req); -} - -/** Queue one request - * Kickstart transfer if needed - * NOTE: Sets INDEX register - */ -static int lh7a40x_queue(struct usb_ep *_ep, struct usb_request *_req, - gfp_t gfp_flags) -{ - struct lh7a40x_request *req; - struct lh7a40x_ep *ep; - struct lh7a40x_udc *dev; - unsigned long flags; - - DEBUG("\n\n\n%s, %p\n", __func__, _ep); - - req = container_of(_req, struct lh7a40x_request, req); - if (unlikely - (!_req || !_req->complete || !_req->buf - || !list_empty(&req->queue))) { - DEBUG("%s, bad params\n", __func__); - return -EINVAL; - } - - ep = container_of(_ep, struct lh7a40x_ep, ep); - if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) { - DEBUG("%s, bad ep\n", __func__); - return -EINVAL; - } - - dev = ep->dev; - if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) { - DEBUG("%s, bogus device state %p\n", __func__, dev->driver); - return -ESHUTDOWN; - } - - DEBUG("%s queue req %p, len %d buf %p\n", _ep->name, _req, _req->length, - _req->buf); - - spin_lock_irqsave(&dev->lock, flags); - - _req->status = -EINPROGRESS; - _req->actual = 0; - - /* kickstart this i/o queue? */ - DEBUG("Add to %d Q %d %d\n", ep_index(ep), list_empty(&ep->queue), - ep->stopped); - if (list_empty(&ep->queue) && likely(!ep->stopped)) { - u32 csr; - - if (unlikely(ep_index(ep) == 0)) { - /* EP0 */ - list_add_tail(&req->queue, &ep->queue); - lh7a40x_ep0_kick(dev, ep); - req = 0; - } else if (ep_is_in(ep)) { - /* EP1 & EP3 */ - usb_set_index(ep_index(ep)); - csr = usb_read(ep->csr1); - pio_irq_enable(ep_index(ep)); - if ((csr & USB_IN_CSR1_FIFO_NOT_EMPTY) == 0) { - if (write_fifo(ep, req) == 1) - req = 0; - } - } else { - /* EP2 */ - usb_set_index(ep_index(ep)); - csr = usb_read(ep->csr1); - pio_irq_enable(ep_index(ep)); - if (!(csr & USB_OUT_CSR1_FIFO_FULL)) { - if (read_fifo(ep, req) == 1) - req = 0; - } - } - } - - /* pio or dma irq handler advances the queue. */ - if (likely(req != 0)) - list_add_tail(&req->queue, &ep->queue); - - spin_unlock_irqrestore(&dev->lock, flags); - - return 0; -} - -/* dequeue JUST ONE request */ -static int lh7a40x_dequeue(struct usb_ep *_ep, struct usb_request *_req) -{ - struct lh7a40x_ep *ep; - struct lh7a40x_request *req; - unsigned long flags; - - DEBUG("%s, %p\n", __func__, _ep); - - ep = container_of(_ep, struct lh7a40x_ep, ep); - if (!_ep || ep->ep.name == ep0name) - return -EINVAL; - - spin_lock_irqsave(&ep->dev->lock, flags); - - /* make sure it's actually queued on this endpoint */ - list_for_each_entry(req, &ep->queue, queue) { - if (&req->req == _req) - break; - } - if (&req->req != _req) { - spin_unlock_irqrestore(&ep->dev->lock, flags); - return -EINVAL; - } - - done(ep, req, -ECONNRESET); - - spin_unlock_irqrestore(&ep->dev->lock, flags); - return 0; -} - -/** Halt specific EP - * Return 0 if success - * NOTE: Sets INDEX register to EP ! - */ -static int lh7a40x_set_halt(struct usb_ep *_ep, int value) -{ - struct lh7a40x_ep *ep; - unsigned long flags; - - ep = container_of(_ep, struct lh7a40x_ep, ep); - if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) { - DEBUG("%s, bad ep\n", __func__); - return -EINVAL; - } - - usb_set_index(ep_index(ep)); - - DEBUG("%s, ep %d, val %d\n", __func__, ep_index(ep), value); - - spin_lock_irqsave(&ep->dev->lock, flags); - - if (ep_index(ep) == 0) { - /* EP0 */ - usb_set(EP0_SEND_STALL, ep->csr1); - } else if (ep_is_in(ep)) { - u32 csr = usb_read(ep->csr1); - if (value && ((csr & USB_IN_CSR1_FIFO_NOT_EMPTY) - || !list_empty(&ep->queue))) { - /* - * Attempts to halt IN endpoints will fail (returning -EAGAIN) - * if any transfer requests are still queued, or if the controller - * FIFO still holds bytes that the host hasn't collected. - */ - spin_unlock_irqrestore(&ep->dev->lock, flags); - DEBUG - ("Attempt to halt IN endpoint failed (returning -EAGAIN) %d %d\n", - (csr & USB_IN_CSR1_FIFO_NOT_EMPTY), - !list_empty(&ep->queue)); - return -EAGAIN; - } - flush(ep); - if (value) - usb_set(USB_IN_CSR1_SEND_STALL, ep->csr1); - else { - usb_clear(USB_IN_CSR1_SEND_STALL, ep->csr1); - usb_set(USB_IN_CSR1_CLR_DATA_TOGGLE, ep->csr1); - } - - } else { - - flush(ep); - if (value) - usb_set(USB_OUT_CSR1_SEND_STALL, ep->csr1); - else { - usb_clear(USB_OUT_CSR1_SEND_STALL, ep->csr1); - usb_set(USB_OUT_CSR1_CLR_DATA_REG, ep->csr1); - } - } - - if (value) { - ep->stopped = 1; - } else { - ep->stopped = 0; - } - - spin_unlock_irqrestore(&ep->dev->lock, flags); - - DEBUG("%s %s halted\n", _ep->name, value == 0 ? "NOT" : "IS"); - - return 0; -} - -/** Return bytes in EP FIFO - * NOTE: Sets INDEX register to EP - */ -static int lh7a40x_fifo_status(struct usb_ep *_ep) -{ - u32 csr; - int count = 0; - struct lh7a40x_ep *ep; - - ep = container_of(_ep, struct lh7a40x_ep, ep); - if (!_ep) { - DEBUG("%s, bad ep\n", __func__); - return -ENODEV; - } - - DEBUG("%s, %d\n", __func__, ep_index(ep)); - - /* LPD can't report unclaimed bytes from IN fifos */ - if (ep_is_in(ep)) - return -EOPNOTSUPP; - - usb_set_index(ep_index(ep)); - - csr = usb_read(ep->csr1); - if (ep->dev->gadget.speed != USB_SPEED_UNKNOWN || - csr & USB_OUT_CSR1_OUT_PKT_RDY) { - count = usb_read(USB_OUT_FIFO_WC1); - } - - return count; -} - -/** Flush EP FIFO - * NOTE: Sets INDEX register to EP - */ -static void lh7a40x_fifo_flush(struct usb_ep *_ep) -{ - struct lh7a40x_ep *ep; - - ep = container_of(_ep, struct lh7a40x_ep, ep); - if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) { - DEBUG("%s, bad ep\n", __func__); - return; - } - - usb_set_index(ep_index(ep)); - flush(ep); -} - -/****************************************************************/ -/* End Point 0 related functions */ -/****************************************************************/ - -/* return: 0 = still running, 1 = completed, negative = errno */ -static int write_fifo_ep0(struct lh7a40x_ep *ep, struct lh7a40x_request *req) -{ - u32 max; - unsigned count; - int is_last; - - max = ep_maxpacket(ep); - - DEBUG_EP0("%s\n", __func__); - - count = write_packet(ep, req, max); - - /* last packet is usually short (or a zlp) */ - if (unlikely(count != max)) - is_last = 1; - else { - if (likely(req->req.length != req->req.actual) || req->req.zero) - is_last = 0; - else - is_last = 1; - } - - DEBUG_EP0("%s: wrote %s %d bytes%s %d left %p\n", __func__, - ep->ep.name, count, - is_last ? "/L" : "", req->req.length - req->req.actual, req); - - /* requests complete when all IN data is in the FIFO */ - if (is_last) { - done(ep, req, 0); - return 1; - } - - return 0; -} - -static __inline__ int lh7a40x_fifo_read(struct lh7a40x_ep *ep, - unsigned char *cp, int max) -{ - int bytes; - int count = usb_read(USB_OUT_FIFO_WC1); - volatile u32 *fifo = (volatile u32 *)ep->fifo; - - if (count > max) - count = max; - bytes = count; - while (count--) - *cp++ = *fifo & 0xFF; - return bytes; -} - -static __inline__ void lh7a40x_fifo_write(struct lh7a40x_ep *ep, - unsigned char *cp, int count) -{ - volatile u32 *fifo = (volatile u32 *)ep->fifo; - DEBUG_EP0("fifo_write: %d %d\n", ep_index(ep), count); - while (count--) - *fifo = *cp++; -} - -static int read_fifo_ep0(struct lh7a40x_ep *ep, struct lh7a40x_request *req) -{ - u32 csr; - u8 *buf; - unsigned bufferspace, count, is_short; - volatile u32 *fifo = (volatile u32 *)ep->fifo; - - DEBUG_EP0("%s\n", __func__); - - csr = usb_read(USB_EP0_CSR); - if (!(csr & USB_OUT_CSR1_OUT_PKT_RDY)) - return 0; - - buf = req->req.buf + req->req.actual; - prefetchw(buf); - bufferspace = req->req.length - req->req.actual; - - /* read all bytes from this packet */ - if (likely(csr & EP0_OUT_PKT_RDY)) { - count = usb_read(USB_OUT_FIFO_WC1); - req->req.actual += min(count, bufferspace); - } else /* zlp */ - count = 0; - - is_short = (count < ep->ep.maxpacket); - DEBUG_EP0("read %s %02x, %d bytes%s req %p %d/%d\n", - ep->ep.name, csr, count, - is_short ? "/S" : "", req, req->req.actual, req->req.length); - - while (likely(count-- != 0)) { - u8 byte = (u8) (*fifo & 0xff); - - if (unlikely(bufferspace == 0)) { - /* this happens when the driver's buffer - * is smaller than what the host sent. - * discard the extra data. - */ - if (req->req.status != -EOVERFLOW) - DEBUG_EP0("%s overflow %d\n", ep->ep.name, - count); - req->req.status = -EOVERFLOW; - } else { - *buf++ = byte; - bufferspace--; - } - } - - /* completion */ - if (is_short || req->req.actual == req->req.length) { - done(ep, req, 0); - return 1; - } - - /* finished that packet. the next one may be waiting... */ - return 0; -} - -/** - * udc_set_address - set the USB address for this device - * @address: - * - * Called from control endpoint function after it decodes a set address setup packet. - */ -static void udc_set_address(struct lh7a40x_udc *dev, unsigned char address) -{ - DEBUG_EP0("%s: %d\n", __func__, address); - /* c.f. 15.1.2.2 Table 15-4 address will be used after DATA_END is set */ - dev->usb_address = address; - usb_set((address & USB_FA_FUNCTION_ADDR), USB_FA); - usb_set(USB_FA_ADDR_UPDATE | (address & USB_FA_FUNCTION_ADDR), USB_FA); - /* usb_read(USB_FA); */ -} - -/* - * DATA_STATE_RECV (OUT_PKT_RDY) - * - if error - * set EP0_CLR_OUT | EP0_DATA_END | EP0_SEND_STALL bits - * - else - * set EP0_CLR_OUT bit - if last set EP0_DATA_END bit - */ -static void lh7a40x_ep0_out(struct lh7a40x_udc *dev, u32 csr) -{ - struct lh7a40x_request *req; - struct lh7a40x_ep *ep = &dev->ep[0]; - int ret; - - DEBUG_EP0("%s: %x\n", __func__, csr); - - if (list_empty(&ep->queue)) - req = 0; - else - req = list_entry(ep->queue.next, struct lh7a40x_request, queue); - - if (req) { - - if (req->req.length == 0) { - DEBUG_EP0("ZERO LENGTH OUT!\n"); - usb_set((EP0_CLR_OUT | EP0_DATA_END), USB_EP0_CSR); - dev->ep0state = WAIT_FOR_SETUP; - return; - } - ret = read_fifo_ep0(ep, req); - if (ret) { - /* Done! */ - DEBUG_EP0("%s: finished, waiting for status\n", - __func__); - - usb_set((EP0_CLR_OUT | EP0_DATA_END), USB_EP0_CSR); - dev->ep0state = WAIT_FOR_SETUP; - } else { - /* Not done yet.. */ - DEBUG_EP0("%s: not finished\n", __func__); - usb_set(EP0_CLR_OUT, USB_EP0_CSR); - } - } else { - DEBUG_EP0("NO REQ??!\n"); - } -} - -/* - * DATA_STATE_XMIT - */ -static int lh7a40x_ep0_in(struct lh7a40x_udc *dev, u32 csr) -{ - struct lh7a40x_request *req; - struct lh7a40x_ep *ep = &dev->ep[0]; - int ret, need_zlp = 0; - - DEBUG_EP0("%s: %x\n", __func__, csr); - - if (list_empty(&ep->queue)) - req = 0; - else - req = list_entry(ep->queue.next, struct lh7a40x_request, queue); - - if (!req) { - DEBUG_EP0("%s: NULL REQ\n", __func__); - return 0; - } - - if (req->req.length == 0) { - - usb_set((EP0_IN_PKT_RDY | EP0_DATA_END), USB_EP0_CSR); - dev->ep0state = WAIT_FOR_SETUP; - return 1; - } - - if (req->req.length - req->req.actual == EP0_PACKETSIZE) { - /* Next write will end with the packet size, */ - /* so we need Zero-length-packet */ - need_zlp = 1; - } - - ret = write_fifo_ep0(ep, req); - - if (ret == 1 && !need_zlp) { - /* Last packet */ - DEBUG_EP0("%s: finished, waiting for status\n", __func__); - - usb_set((EP0_IN_PKT_RDY | EP0_DATA_END), USB_EP0_CSR); - dev->ep0state = WAIT_FOR_SETUP; - } else { - DEBUG_EP0("%s: not finished\n", __func__); - usb_set(EP0_IN_PKT_RDY, USB_EP0_CSR); - } - - if (need_zlp) { - DEBUG_EP0("%s: Need ZLP!\n", __func__); - usb_set(EP0_IN_PKT_RDY, USB_EP0_CSR); - dev->ep0state = DATA_STATE_NEED_ZLP; - } - - return 1; -} - -static int lh7a40x_handle_get_status(struct lh7a40x_udc *dev, - struct usb_ctrlrequest *ctrl) -{ - struct lh7a40x_ep *ep0 = &dev->ep[0]; - struct lh7a40x_ep *qep; - int reqtype = (ctrl->bRequestType & USB_RECIP_MASK); - u16 val = 0; - - if (reqtype == USB_RECIP_INTERFACE) { - /* This is not supported. - * And according to the USB spec, this one does nothing.. - * Just return 0 - */ - DEBUG_SETUP("GET_STATUS: USB_RECIP_INTERFACE\n"); - } else if (reqtype == USB_RECIP_DEVICE) { - DEBUG_SETUP("GET_STATUS: USB_RECIP_DEVICE\n"); - val |= (1 << 0); /* Self powered */ - /*val |= (1<<1); *//* Remote wakeup */ - } else if (reqtype == USB_RECIP_ENDPOINT) { - int ep_num = (ctrl->wIndex & ~USB_DIR_IN); - - DEBUG_SETUP - ("GET_STATUS: USB_RECIP_ENDPOINT (%d), ctrl->wLength = %d\n", - ep_num, ctrl->wLength); - - if (ctrl->wLength > 2 || ep_num > 3) - return -EOPNOTSUPP; - - qep = &dev->ep[ep_num]; - if (ep_is_in(qep) != ((ctrl->wIndex & USB_DIR_IN) ? 1 : 0) - && ep_index(qep) != 0) { - return -EOPNOTSUPP; - } - - usb_set_index(ep_index(qep)); - - /* Return status on next IN token */ - switch (qep->ep_type) { - case ep_control: - val = - (usb_read(qep->csr1) & EP0_SEND_STALL) == - EP0_SEND_STALL; - break; - case ep_bulk_in: - case ep_interrupt: - val = - (usb_read(qep->csr1) & USB_IN_CSR1_SEND_STALL) == - USB_IN_CSR1_SEND_STALL; - break; - case ep_bulk_out: - val = - (usb_read(qep->csr1) & USB_OUT_CSR1_SEND_STALL) == - USB_OUT_CSR1_SEND_STALL; - break; - } - - /* Back to EP0 index */ - usb_set_index(0); - - DEBUG_SETUP("GET_STATUS, ep: %d (%x), val = %d\n", ep_num, - ctrl->wIndex, val); - } else { - DEBUG_SETUP("Unknown REQ TYPE: %d\n", reqtype); - return -EOPNOTSUPP; - } - - /* Clear "out packet ready" */ - usb_set((EP0_CLR_OUT), USB_EP0_CSR); - /* Put status to FIFO */ - lh7a40x_fifo_write(ep0, (u8 *) & val, sizeof(val)); - /* Issue "In packet ready" */ - usb_set((EP0_IN_PKT_RDY | EP0_DATA_END), USB_EP0_CSR); - - return 0; -} - -/* - * WAIT_FOR_SETUP (OUT_PKT_RDY) - * - read data packet from EP0 FIFO - * - decode command - * - if error - * set EP0_CLR_OUT | EP0_DATA_END | EP0_SEND_STALL bits - * - else - * set EP0_CLR_OUT | EP0_DATA_END bits - */ -static void lh7a40x_ep0_setup(struct lh7a40x_udc *dev, u32 csr) -{ - struct lh7a40x_ep *ep = &dev->ep[0]; - struct usb_ctrlrequest ctrl; - int i, bytes, is_in; - - DEBUG_SETUP("%s: %x\n", __func__, csr); - - /* Nuke all previous transfers */ - nuke(ep, -EPROTO); - - /* read control req from fifo (8 bytes) */ - bytes = lh7a40x_fifo_read(ep, (unsigned char *)&ctrl, 8); - - DEBUG_SETUP("Read CTRL REQ %d bytes\n", bytes); - DEBUG_SETUP("CTRL.bRequestType = %d (is_in %d)\n", ctrl.bRequestType, - ctrl.bRequestType == USB_DIR_IN); - DEBUG_SETUP("CTRL.bRequest = %d\n", ctrl.bRequest); - DEBUG_SETUP("CTRL.wLength = %d\n", ctrl.wLength); - DEBUG_SETUP("CTRL.wValue = %d (%d)\n", ctrl.wValue, ctrl.wValue >> 8); - DEBUG_SETUP("CTRL.wIndex = %d\n", ctrl.wIndex); - - /* Set direction of EP0 */ - if (likely(ctrl.bRequestType & USB_DIR_IN)) { - ep->bEndpointAddress |= USB_DIR_IN; - is_in = 1; - } else { - ep->bEndpointAddress &= ~USB_DIR_IN; - is_in = 0; - } - - dev->req_pending = 1; - - /* Handle some SETUP packets ourselves */ - switch (ctrl.bRequest) { - case USB_REQ_SET_ADDRESS: - if (ctrl.bRequestType != (USB_TYPE_STANDARD | USB_RECIP_DEVICE)) - break; - - DEBUG_SETUP("USB_REQ_SET_ADDRESS (%d)\n", ctrl.wValue); - udc_set_address(dev, ctrl.wValue); - usb_set((EP0_CLR_OUT | EP0_DATA_END), USB_EP0_CSR); - return; - - case USB_REQ_GET_STATUS:{ - if (lh7a40x_handle_get_status(dev, &ctrl) == 0) - return; - - case USB_REQ_CLEAR_FEATURE: - case USB_REQ_SET_FEATURE: - if (ctrl.bRequestType == USB_RECIP_ENDPOINT) { - struct lh7a40x_ep *qep; - int ep_num = (ctrl.wIndex & 0x0f); - - /* Support only HALT feature */ - if (ctrl.wValue != 0 || ctrl.wLength != 0 - || ep_num > 3 || ep_num < 1) - break; - - qep = &dev->ep[ep_num]; - spin_unlock(&dev->lock); - if (ctrl.bRequest == USB_REQ_SET_FEATURE) { - DEBUG_SETUP("SET_FEATURE (%d)\n", - ep_num); - lh7a40x_set_halt(&qep->ep, 1); - } else { - DEBUG_SETUP("CLR_FEATURE (%d)\n", - ep_num); - lh7a40x_set_halt(&qep->ep, 0); - } - spin_lock(&dev->lock); - usb_set_index(0); - - /* Reply with a ZLP on next IN token */ - usb_set((EP0_CLR_OUT | EP0_DATA_END), - USB_EP0_CSR); - return; - } - break; - } - - default: - break; - } - - if (likely(dev->driver)) { - /* device-2-host (IN) or no data setup command, process immediately */ - spin_unlock(&dev->lock); - i = dev->driver->setup(&dev->gadget, &ctrl); - spin_lock(&dev->lock); - - if (i < 0) { - /* setup processing failed, force stall */ - DEBUG_SETUP - (" --> ERROR: gadget setup FAILED (stalling), setup returned %d\n", - i); - usb_set_index(0); - usb_set((EP0_CLR_OUT | EP0_DATA_END | EP0_SEND_STALL), - USB_EP0_CSR); - - /* ep->stopped = 1; */ - dev->ep0state = WAIT_FOR_SETUP; - } - } -} - -/* - * DATA_STATE_NEED_ZLP - */ -static void lh7a40x_ep0_in_zlp(struct lh7a40x_udc *dev, u32 csr) -{ - DEBUG_EP0("%s: %x\n", __func__, csr); - - /* c.f. Table 15-14 */ - usb_set((EP0_IN_PKT_RDY | EP0_DATA_END), USB_EP0_CSR); - dev->ep0state = WAIT_FOR_SETUP; -} - -/* - * handle ep0 interrupt - */ -static void lh7a40x_handle_ep0(struct lh7a40x_udc *dev, u32 intr) -{ - struct lh7a40x_ep *ep = &dev->ep[0]; - u32 csr; - - /* Set index 0 */ - usb_set_index(0); - csr = usb_read(USB_EP0_CSR); - - DEBUG_EP0("%s: csr = %x\n", __func__, csr); - - /* - * For overview of what we should be doing see c.f. Chapter 18.1.2.4 - * We will follow that outline here modified by our own global state - * indication which provides hints as to what we think should be - * happening.. - */ - - /* - * if SENT_STALL is set - * - clear the SENT_STALL bit - */ - if (csr & EP0_SENT_STALL) { - DEBUG_EP0("%s: EP0_SENT_STALL is set: %x\n", __func__, csr); - usb_clear((EP0_SENT_STALL | EP0_SEND_STALL), USB_EP0_CSR); - nuke(ep, -ECONNABORTED); - dev->ep0state = WAIT_FOR_SETUP; - return; - } - - /* - * if a transfer is in progress && IN_PKT_RDY and OUT_PKT_RDY are clear - * - fill EP0 FIFO - * - if last packet - * - set IN_PKT_RDY | DATA_END - * - else - * set IN_PKT_RDY - */ - if (!(csr & (EP0_IN_PKT_RDY | EP0_OUT_PKT_RDY))) { - DEBUG_EP0("%s: IN_PKT_RDY and OUT_PKT_RDY are clear\n", - __func__); - - switch (dev->ep0state) { - case DATA_STATE_XMIT: - DEBUG_EP0("continue with DATA_STATE_XMIT\n"); - lh7a40x_ep0_in(dev, csr); - return; - case DATA_STATE_NEED_ZLP: - DEBUG_EP0("continue with DATA_STATE_NEED_ZLP\n"); - lh7a40x_ep0_in_zlp(dev, csr); - return; - default: - /* Stall? */ - DEBUG_EP0("Odd state!! state = %s\n", - state_names[dev->ep0state]); - dev->ep0state = WAIT_FOR_SETUP; - /* nuke(ep, 0); */ - /* usb_set(EP0_SEND_STALL, ep->csr1); */ - break; - } - } - - /* - * if SETUP_END is set - * - abort the last transfer - * - set SERVICED_SETUP_END_BIT - */ - if (csr & EP0_SETUP_END) { - DEBUG_EP0("%s: EP0_SETUP_END is set: %x\n", __func__, csr); - - usb_set(EP0_CLR_SETUP_END, USB_EP0_CSR); - - nuke(ep, 0); - dev->ep0state = WAIT_FOR_SETUP; - } - - /* - * if EP0_OUT_PKT_RDY is set - * - read data packet from EP0 FIFO - * - decode command - * - if error - * set SERVICED_OUT_PKT_RDY | DATA_END bits | SEND_STALL - * - else - * set SERVICED_OUT_PKT_RDY | DATA_END bits - */ - if (csr & EP0_OUT_PKT_RDY) { - - DEBUG_EP0("%s: EP0_OUT_PKT_RDY is set: %x\n", __func__, - csr); - - switch (dev->ep0state) { - case WAIT_FOR_SETUP: - DEBUG_EP0("WAIT_FOR_SETUP\n"); - lh7a40x_ep0_setup(dev, csr); - break; - - case DATA_STATE_RECV: - DEBUG_EP0("DATA_STATE_RECV\n"); - lh7a40x_ep0_out(dev, csr); - break; - - default: - /* send stall? */ - DEBUG_EP0("strange state!! 2. send stall? state = %d\n", - dev->ep0state); - break; - } - } -} - -static void lh7a40x_ep0_kick(struct lh7a40x_udc *dev, struct lh7a40x_ep *ep) -{ - u32 csr; - - usb_set_index(0); - csr = usb_read(USB_EP0_CSR); - - DEBUG_EP0("%s: %x\n", __func__, csr); - - /* Clear "out packet ready" */ - usb_set(EP0_CLR_OUT, USB_EP0_CSR); - - if (ep_is_in(ep)) { - dev->ep0state = DATA_STATE_XMIT; - lh7a40x_ep0_in(dev, csr); - } else { - dev->ep0state = DATA_STATE_RECV; - lh7a40x_ep0_out(dev, csr); - } -} - -/* --------------------------------------------------------------------------- - * device-scoped parts of the api to the usb controller hardware - * --------------------------------------------------------------------------- - */ - -static int lh7a40x_udc_get_frame(struct usb_gadget *_gadget) -{ - u32 frame1 = usb_read(USB_FRM_NUM1); /* Least significant 8 bits */ - u32 frame2 = usb_read(USB_FRM_NUM2); /* Most significant 3 bits */ - DEBUG("%s, %p\n", __func__, _gadget); - return ((frame2 & 0x07) << 8) | (frame1 & 0xff); -} - -static int lh7a40x_udc_wakeup(struct usb_gadget *_gadget) -{ - /* host may not have enabled remote wakeup */ - /*if ((UDCCS0 & UDCCS0_DRWF) == 0) - return -EHOSTUNREACH; - udc_set_mask_UDCCR(UDCCR_RSM); */ - return -ENOTSUPP; -} - -static const struct usb_gadget_ops lh7a40x_udc_ops = { - .get_frame = lh7a40x_udc_get_frame, - .wakeup = lh7a40x_udc_wakeup, - /* current versions must always be self-powered */ -}; - -static void nop_release(struct device *dev) -{ - DEBUG("%s %s\n", __func__, dev_name(dev)); -} - -static struct lh7a40x_udc memory = { - .usb_address = 0, - - .gadget = { - .ops = &lh7a40x_udc_ops, - .ep0 = &memory.ep[0].ep, - .name = driver_name, - .dev = { - .init_name = "gadget", - .release = nop_release, - }, - }, - - /* control endpoint */ - .ep[0] = { - .ep = { - .name = ep0name, - .ops = &lh7a40x_ep_ops, - .maxpacket = EP0_PACKETSIZE, - }, - .dev = &memory, - - .bEndpointAddress = 0, - .bmAttributes = 0, - - .ep_type = ep_control, - .fifo = io_p2v(USB_EP0_FIFO), - .csr1 = USB_EP0_CSR, - .csr2 = USB_EP0_CSR, - }, - - /* first group of endpoints */ - .ep[1] = { - .ep = { - .name = "ep1in-bulk", - .ops = &lh7a40x_ep_ops, - .maxpacket = 64, - }, - .dev = &memory, - - .bEndpointAddress = USB_DIR_IN | 1, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - - .ep_type = ep_bulk_in, - .fifo = io_p2v(USB_EP1_FIFO), - .csr1 = USB_IN_CSR1, - .csr2 = USB_IN_CSR2, - }, - - .ep[2] = { - .ep = { - .name = "ep2out-bulk", - .ops = &lh7a40x_ep_ops, - .maxpacket = 64, - }, - .dev = &memory, - - .bEndpointAddress = 2, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - - .ep_type = ep_bulk_out, - .fifo = io_p2v(USB_EP2_FIFO), - .csr1 = USB_OUT_CSR1, - .csr2 = USB_OUT_CSR2, - }, - - .ep[3] = { - .ep = { - .name = "ep3in-int", - .ops = &lh7a40x_ep_ops, - .maxpacket = 64, - }, - .dev = &memory, - - .bEndpointAddress = USB_DIR_IN | 3, - .bmAttributes = USB_ENDPOINT_XFER_INT, - - .ep_type = ep_interrupt, - .fifo = io_p2v(USB_EP3_FIFO), - .csr1 = USB_IN_CSR1, - .csr2 = USB_IN_CSR2, - }, -}; - -/* - * probe - binds to the platform device - */ -static int lh7a40x_udc_probe(struct platform_device *pdev) -{ - struct lh7a40x_udc *dev = &memory; - int retval; - - DEBUG("%s: %p\n", __func__, pdev); - - spin_lock_init(&dev->lock); - dev->dev = &pdev->dev; - - device_initialize(&dev->gadget.dev); - dev->gadget.dev.parent = &pdev->dev; - - the_controller = dev; - platform_set_drvdata(pdev, dev); - - udc_disable(dev); - udc_reinit(dev); - - /* irq setup after old hardware state is cleaned up */ - retval = - request_irq(IRQ_USBINTR, lh7a40x_udc_irq, IRQF_DISABLED, driver_name, - dev); - if (retval != 0) { - DEBUG(KERN_ERR "%s: can't get irq %i, err %d\n", driver_name, - IRQ_USBINTR, retval); - return -EBUSY; - } - - create_proc_files(); - - return retval; -} - -static int lh7a40x_udc_remove(struct platform_device *pdev) -{ - struct lh7a40x_udc *dev = platform_get_drvdata(pdev); - - DEBUG("%s: %p\n", __func__, pdev); - - if (dev->driver) - return -EBUSY; - - udc_disable(dev); - remove_proc_files(); - - free_irq(IRQ_USBINTR, dev); - - platform_set_drvdata(pdev, 0); - - the_controller = 0; - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -static struct platform_driver udc_driver = { - .probe = lh7a40x_udc_probe, - .remove = lh7a40x_udc_remove, - /* FIXME power management support */ - /* .suspend = ... disable UDC */ - /* .resume = ... re-enable UDC */ - .driver = { - .name = (char *)driver_name, - .owner = THIS_MODULE, - }, -}; - -static int __init udc_init(void) -{ - DEBUG("%s: %s version %s\n", __func__, driver_name, DRIVER_VERSION); - return platform_driver_register(&udc_driver); -} - -static void __exit udc_exit(void) -{ - platform_driver_unregister(&udc_driver); -} - -module_init(udc_init); -module_exit(udc_exit); - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_AUTHOR("Mikko Lahteenmaki, Bo Henriksen"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:lh7a40x_udc"); diff --git a/drivers/usb/gadget/lh7a40x_udc.h b/drivers/usb/gadget/lh7a40x_udc.h deleted file mode 100644 index ca861203a301..000000000000 --- a/drivers/usb/gadget/lh7a40x_udc.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * linux/drivers/usb/gadget/lh7a40x_udc.h - * Sharp LH7A40x on-chip full speed USB device controllers - * - * Copyright (C) 2004 Mikko Lahteenmaki, Nordic ID - * Copyright (C) 2004 Bo Henriksen, Nordic ID - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __LH7A40X_H_ -#define __LH7A40X_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* - * Memory map - */ - -#define USB_FA 0x80000200 // function address register -#define USB_PM 0x80000204 // power management register - -#define USB_IN_INT 0x80000208 // IN interrupt register bank (EP0-EP3) -#define USB_OUT_INT 0x80000210 // OUT interrupt register bank (EP2) -#define USB_INT 0x80000218 // interrupt register bank - -#define USB_IN_INT_EN 0x8000021C // IN interrupt enable register bank -#define USB_OUT_INT_EN 0x80000224 // OUT interrupt enable register bank -#define USB_INT_EN 0x8000022C // USB interrupt enable register bank - -#define USB_FRM_NUM1 0x80000230 // Frame number1 register -#define USB_FRM_NUM2 0x80000234 // Frame number2 register -#define USB_INDEX 0x80000238 // index register - -#define USB_IN_MAXP 0x80000240 // IN MAXP register -#define USB_IN_CSR1 0x80000244 // IN CSR1 register/EP0 CSR register -#define USB_EP0_CSR 0x80000244 // IN CSR1 register/EP0 CSR register -#define USB_IN_CSR2 0x80000248 // IN CSR2 register -#define USB_OUT_MAXP 0x8000024C // OUT MAXP register - -#define USB_OUT_CSR1 0x80000250 // OUT CSR1 register -#define USB_OUT_CSR2 0x80000254 // OUT CSR2 register -#define USB_OUT_FIFO_WC1 0x80000258 // OUT FIFO write count1 register -#define USB_OUT_FIFO_WC2 0x8000025C // OUT FIFO write count2 register - -#define USB_RESET 0x8000044C // USB reset register - -#define USB_EP0_FIFO 0x80000280 -#define USB_EP1_FIFO 0x80000284 -#define USB_EP2_FIFO 0x80000288 -#define USB_EP3_FIFO 0x8000028c - -/* - * USB reset register - */ -#define USB_RESET_APB (1<<1) //resets USB APB control side WRITE -#define USB_RESET_IO (1<<0) //resets USB IO side WRITE - -/* - * USB function address register - */ -#define USB_FA_ADDR_UPDATE (1<<7) -#define USB_FA_FUNCTION_ADDR (0x7F) - -/* - * Power Management register - */ -#define PM_USB_DCP (1<<5) -#define PM_USB_ENABLE (1<<4) -#define PM_USB_RESET (1<<3) -#define PM_UC_RESUME (1<<2) -#define PM_SUSPEND_MODE (1<<1) -#define PM_ENABLE_SUSPEND (1<<0) - -/* - * IN interrupt register - */ -#define USB_IN_INT_EP3 (1<<3) -#define USB_IN_INT_EP1 (1<<1) -#define USB_IN_INT_EP0 (1<<0) - -/* - * OUT interrupt register - */ -#define USB_OUT_INT_EP2 (1<<2) - -/* - * USB interrupt register - */ -#define USB_INT_RESET_INT (1<<2) -#define USB_INT_RESUME_INT (1<<1) -#define USB_INT_SUSPEND_INT (1<<0) - -/* - * USB interrupt enable register - */ -#define USB_INT_EN_USB_RESET_INTER (1<<2) -#define USB_INT_EN_RESUME_INTER (1<<1) -#define USB_INT_EN_SUSPEND_INTER (1<<0) - -/* - * INCSR1 register - */ -#define USB_IN_CSR1_CLR_DATA_TOGGLE (1<<6) -#define USB_IN_CSR1_SENT_STALL (1<<5) -#define USB_IN_CSR1_SEND_STALL (1<<4) -#define USB_IN_CSR1_FIFO_FLUSH (1<<3) -#define USB_IN_CSR1_FIFO_NOT_EMPTY (1<<1) -#define USB_IN_CSR1_IN_PKT_RDY (1<<0) - -/* - * INCSR2 register - */ -#define USB_IN_CSR2_AUTO_SET (1<<7) -#define USB_IN_CSR2_USB_DMA_EN (1<<4) - -/* - * OUT CSR1 register - */ -#define USB_OUT_CSR1_CLR_DATA_REG (1<<7) -#define USB_OUT_CSR1_SENT_STALL (1<<6) -#define USB_OUT_CSR1_SEND_STALL (1<<5) -#define USB_OUT_CSR1_FIFO_FLUSH (1<<4) -#define USB_OUT_CSR1_FIFO_FULL (1<<1) -#define USB_OUT_CSR1_OUT_PKT_RDY (1<<0) - -/* - * OUT CSR2 register - */ -#define USB_OUT_CSR2_AUTO_CLR (1<<7) -#define USB_OUT_CSR2_USB_DMA_EN (1<<4) - -/* - * EP0 CSR - */ -#define EP0_CLR_SETUP_END (1<<7) /* Clear "Setup Ends" Bit (w) */ -#define EP0_CLR_OUT (1<<6) /* Clear "Out packet ready" Bit (w) */ -#define EP0_SEND_STALL (1<<5) /* Send STALL Handshake (rw) */ -#define EP0_SETUP_END (1<<4) /* Setup Ends (r) */ - -#define EP0_DATA_END (1<<3) /* Data end (rw) */ -#define EP0_SENT_STALL (1<<2) /* Sent Stall Handshake (r) */ -#define EP0_IN_PKT_RDY (1<<1) /* In packet ready (rw) */ -#define EP0_OUT_PKT_RDY (1<<0) /* Out packet ready (r) */ - -/* general CSR */ -#define OUT_PKT_RDY (1<<0) -#define IN_PKT_RDY (1<<0) - -/* - * IN/OUT MAXP register - */ -#define USB_OUT_MAXP_MAXP (0xF) -#define USB_IN_MAXP_MAXP (0xF) - -// Max packet size -//#define EP0_PACKETSIZE 0x10 -#define EP0_PACKETSIZE 0x8 -#define EP0_MAXPACKETSIZE 0x10 - -#define UDC_MAX_ENDPOINTS 4 - -#define WAIT_FOR_SETUP 0 -#define DATA_STATE_XMIT 1 -#define DATA_STATE_NEED_ZLP 2 -#define WAIT_FOR_OUT_STATUS 3 -#define DATA_STATE_RECV 4 - -/* ********************************************************************************************* */ -/* IO - */ - -typedef enum ep_type { - ep_control, ep_bulk_in, ep_bulk_out, ep_interrupt -} ep_type_t; - -struct lh7a40x_ep { - struct usb_ep ep; - struct lh7a40x_udc *dev; - - const struct usb_endpoint_descriptor *desc; - struct list_head queue; - unsigned long pio_irqs; - - u8 stopped; - u8 bEndpointAddress; - u8 bmAttributes; - - ep_type_t ep_type; - u32 fifo; - u32 csr1; - u32 csr2; -}; - -struct lh7a40x_request { - struct usb_request req; - struct list_head queue; -}; - -struct lh7a40x_udc { - struct usb_gadget gadget; - struct usb_gadget_driver *driver; - struct device *dev; - spinlock_t lock; - - int ep0state; - struct lh7a40x_ep ep[UDC_MAX_ENDPOINTS]; - - unsigned char usb_address; - - unsigned req_pending:1, req_std:1, req_config:1; -}; - -extern struct lh7a40x_udc *the_controller; - -#define ep_is_in(EP) (((EP)->bEndpointAddress&USB_DIR_IN)==USB_DIR_IN) -#define ep_index(EP) ((EP)->bEndpointAddress&0xF) -#define ep_maxpacket(EP) ((EP)->ep.maxpacket) - -#endif diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 759a12ff8048..b426c1e8a679 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1023,11 +1023,6 @@ MODULE_LICENSE ("GPL"); #define OMAP3_PLATFORM_DRIVER ohci_hcd_omap3_driver #endif -#ifdef CONFIG_ARCH_LH7A404 -#include "ohci-lh7a404.c" -#define PLATFORM_DRIVER ohci_hcd_lh7a404_driver -#endif - #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) #include "ohci-pxa27x.c" #define PLATFORM_DRIVER ohci_hcd_pxa27x_driver diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c deleted file mode 100644 index 18d39f0463ee..000000000000 --- a/drivers/usb/host/ohci-lh7a404.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * OHCI HCD (Host Controller Driver) for USB. - * - * (C) Copyright 1999 Roman Weissgaerber - * (C) Copyright 2000-2002 David Brownell - * (C) Copyright 2002 Hewlett-Packard Company - * - * Bus Glue for Sharp LH7A404 - * - * Written by Christopher Hoover - * Based on fragments of previous driver by Russell King et al. - * - * Modified for LH7A404 from ohci-sa1111.c - * by Durgesh Pattamatta - * - * This file is licenced under the GPL. - */ - -#include -#include - -#include - - -extern int usb_disabled(void); - -/*-------------------------------------------------------------------------*/ - -static void lh7a404_start_hc(struct platform_device *dev) -{ - printk(KERN_DEBUG "%s: starting LH7A404 OHCI USB Controller\n", - __FILE__); - - /* - * Now, carefully enable the USB clock, and take - * the USB host controller out of reset. - */ - CSC_PWRCNT |= CSC_PWRCNT_USBH_EN; /* Enable clock */ - udelay(1000); - USBH_CMDSTATUS = OHCI_HCR; - - printk(KERN_DEBUG "%s: Clock to USB host has been enabled \n", __FILE__); -} - -static void lh7a404_stop_hc(struct platform_device *dev) -{ - printk(KERN_DEBUG "%s: stopping LH7A404 OHCI USB Controller\n", - __FILE__); - - CSC_PWRCNT &= ~CSC_PWRCNT_USBH_EN; /* Disable clock */ -} - - -/*-------------------------------------------------------------------------*/ - -/* configure so an HC device and id are always provided */ -/* always called with process context; sleeping is OK */ - - -/** - * usb_hcd_lh7a404_probe - initialize LH7A404-based HCDs - * Context: !in_interrupt() - * - * Allocates basic resources for this USB host controller, and - * then invokes the start() method for the HCD associated with it - * through the hotplug entry's driver_data. - * - */ -int usb_hcd_lh7a404_probe (const struct hc_driver *driver, - struct platform_device *dev) -{ - int retval; - struct usb_hcd *hcd; - - if (dev->resource[1].flags != IORESOURCE_IRQ) { - pr_debug("resource[1] is not IORESOURCE_IRQ"); - return -ENOMEM; - } - - hcd = usb_create_hcd(driver, &dev->dev, "lh7a404"); - if (!hcd) - return -ENOMEM; - hcd->rsrc_start = dev->resource[0].start; - hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; - - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { - pr_debug("request_mem_region failed"); - retval = -EBUSY; - goto err1; - } - - hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); - if (!hcd->regs) { - pr_debug("ioremap failed"); - retval = -ENOMEM; - goto err2; - } - - lh7a404_start_hc(dev); - ohci_hcd_init(hcd_to_ohci(hcd)); - - retval = usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED); - if (retval == 0) - return retval; - - lh7a404_stop_hc(dev); - iounmap(hcd->regs); - err2: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - err1: - usb_put_hcd(hcd); - return retval; -} - - -/* may be called without controller electrically present */ -/* may be called with controller, bus, and devices active */ - -/** - * usb_hcd_lh7a404_remove - shutdown processing for LH7A404-based HCDs - * @dev: USB Host Controller being removed - * Context: !in_interrupt() - * - * Reverses the effect of usb_hcd_lh7a404_probe(), first invoking - * the HCD's stop() method. It is always called from a thread - * context, normally "rmmod", "apmd", or something similar. - * - */ -void usb_hcd_lh7a404_remove (struct usb_hcd *hcd, struct platform_device *dev) -{ - usb_remove_hcd(hcd); - lh7a404_stop_hc(dev); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - usb_put_hcd(hcd); -} - -/*-------------------------------------------------------------------------*/ - -static int __devinit -ohci_lh7a404_start (struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci (hcd); - int ret; - - ohci_dbg (ohci, "ohci_lh7a404_start, ohci:%p", ohci); - if ((ret = ohci_init(ohci)) < 0) - return ret; - - if ((ret = ohci_run (ohci)) < 0) { - err ("can't start %s", hcd->self.bus_name); - ohci_stop (hcd); - return ret; - } - return 0; -} - -/*-------------------------------------------------------------------------*/ - -static const struct hc_driver ohci_lh7a404_hc_driver = { - .description = hcd_name, - .product_desc = "LH7A404 OHCI", - .hcd_priv_size = sizeof(struct ohci_hcd), - - /* - * generic hardware linkage - */ - .irq = ohci_irq, - .flags = HCD_USB11 | HCD_MEMORY, - - /* - * basic lifecycle operations - */ - .start = ohci_lh7a404_start, - .stop = ohci_stop, - .shutdown = ohci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ohci_urb_enqueue, - .urb_dequeue = ohci_urb_dequeue, - .endpoint_disable = ohci_endpoint_disable, - - /* - * scheduling support - */ - .get_frame_number = ohci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ohci_hub_status_data, - .hub_control = ohci_hub_control, -#ifdef CONFIG_PM - .bus_suspend = ohci_bus_suspend, - .bus_resume = ohci_bus_resume, -#endif - .start_port_reset = ohci_start_port_reset, -}; - -/*-------------------------------------------------------------------------*/ - -static int ohci_hcd_lh7a404_drv_probe(struct platform_device *pdev) -{ - int ret; - - pr_debug ("In ohci_hcd_lh7a404_drv_probe"); - - if (usb_disabled()) - return -ENODEV; - - ret = usb_hcd_lh7a404_probe(&ohci_lh7a404_hc_driver, pdev); - return ret; -} - -static int ohci_hcd_lh7a404_drv_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_hcd_lh7a404_remove(hcd, pdev); - return 0; -} - /*TBD*/ -/*static int ohci_hcd_lh7a404_drv_suspend(struct platform_device *dev) -{ - struct usb_hcd *hcd = platform_get_drvdata(dev); - - return 0; -} -static int ohci_hcd_lh7a404_drv_resume(struct platform_device *dev) -{ - struct usb_hcd *hcd = platform_get_drvdata(dev); - - - return 0; -} -*/ - -static struct platform_driver ohci_hcd_lh7a404_driver = { - .probe = ohci_hcd_lh7a404_drv_probe, - .remove = ohci_hcd_lh7a404_drv_remove, - .shutdown = usb_hcd_platform_shutdown, - /*.suspend = ohci_hcd_lh7a404_drv_suspend, */ - /*.resume = ohci_hcd_lh7a404_drv_resume, */ - .driver = { - .name = "lh7a404-ohci", - .owner = THIS_MODULE, - }, -}; - -MODULE_ALIAS("platform:lh7a404-ohci"); diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 51facb985c84..04812b42fe6f 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -575,18 +575,8 @@ static inline void _ohci_writel (const struct ohci_hcd *ohci, #endif } -#ifdef CONFIG_ARCH_LH7A404 -/* Marc Singer: at the time this code was written, the LH7A404 - * had a problem reading the USB host registers. This - * implementation of the ohci_readl function performs the read - * twice as a work-around. - */ -#define ohci_readl(o,r) (_ohci_readl(o,r),_ohci_readl(o,r)) -#define ohci_writel(o,v,r) _ohci_writel(o,v,r) -#else #define ohci_readl(o,r) _ohci_readl(o,r) #define ohci_writel(o,v,r) _ohci_writel(o,v,r) -#endif /*-------------------------------------------------------------------------*/ diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 6bafb51bb437..b57bc273b184 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -322,69 +322,6 @@ config FB_ARMCLCD here and read . The module will be called amba-clcd. -choice - - depends on FB_ARMCLCD && (ARCH_LH7A40X || ARCH_LH7952X) - prompt "LCD Panel" - default FB_ARMCLCD_SHARP_LQ035Q7DB02 - -config FB_ARMCLCD_SHARP_LQ035Q7DB02_HRTFT - bool "LogicPD LCD 3.5\" QVGA w/HRTFT IC" - help - This is an implementation of the Sharp LQ035Q7DB02, a 3.5" - color QVGA, HRTFT panel. The LogicPD device includes - an integrated HRTFT controller IC. - The native resolution is 240x320. - -config FB_ARMCLCD_SHARP_LQ057Q3DC02 - bool "LogicPD LCD 5.7\" QVGA" - help - This is an implementation of the Sharp LQ057Q3DC02, a 5.7" - color QVGA, TFT panel. The LogicPD device includes an - The native resolution is 320x240. - -config FB_ARMCLCD_SHARP_LQ64D343 - bool "LogicPD LCD 6.4\" VGA" - help - This is an implementation of the Sharp LQ64D343, a 6.4" - color VGA, TFT panel. The LogicPD device includes an - The native resolution is 640x480. - -config FB_ARMCLCD_SHARP_LQ10D368 - bool "LogicPD LCD 10.4\" VGA" - help - This is an implementation of the Sharp LQ10D368, a 10.4" - color VGA, TFT panel. The LogicPD device includes an - The native resolution is 640x480. - - -config FB_ARMCLCD_SHARP_LQ121S1DG41 - bool "LogicPD LCD 12.1\" SVGA" - help - This is an implementation of the Sharp LQ121S1DG41, a 12.1" - color SVGA, TFT panel. The LogicPD device includes an - The native resolution is 800x600. - - This panel requires a clock rate may be an integer fraction - of the base LCDCLK frequency. The driver will select the - highest frequency available that is lower than the maximum - allowed. The panel may flicker if the clock rate is - slower than the recommended minimum. - -config FB_ARMCLCD_AUO_A070VW01_WIDE - bool "AU Optronics A070VW01 LCD 7.0\" WIDE" - help - This is an implementation of the AU Optronics, a 7.0" - WIDE Color. The native resolution is 234x480. - -config FB_ARMCLCD_HITACHI - bool "Hitachi Wide Screen 800x480" - help - This is an implementation of the Hitachi 800x480. - -endchoice - - config FB_ACORN bool "Acorn VIDC support" depends on (FB = y) && ARM && ARCH_ACORN -- cgit v1.2.3 From 3c2c04a15f5fe5d169fe343c9eb7c1856d3033d3 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 15 Dec 2010 11:47:54 +0200 Subject: wl12xx: remove redundant debugfs_remove_recursive() call Upon rmmod, the /ieee80211/phyX dir is being removed. later, we try to remove /ieee80211/phyX/wl12xx, which might result in NULL dereference. Remove the excessive debugfs_remove_recursive() call. (consequently, there is no more need to save wl->rootdir) Reported-by: Arik Nemtsov Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/debugfs.c | 36 ++++++++++++++++------------------- drivers/net/wireless/wl12xx/wl12xx.h | 1 - 2 files changed, 16 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index ec6077760157..36e7ec1e0c3b 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c @@ -293,12 +293,13 @@ static const struct file_operations gpio_power_ops = { .llseek = default_llseek, }; -static int wl1271_debugfs_add_files(struct wl1271 *wl) +static int wl1271_debugfs_add_files(struct wl1271 *wl, + struct dentry *rootdir) { int ret = 0; struct dentry *entry, *stats; - stats = debugfs_create_dir("fw-statistics", wl->rootdir); + stats = debugfs_create_dir("fw-statistics", rootdir); if (!stats || IS_ERR(stats)) { entry = stats; goto err; @@ -395,13 +396,13 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl) DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data); DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data); - DEBUGFS_ADD(tx_queue_len, wl->rootdir); - DEBUGFS_ADD(retry_count, wl->rootdir); - DEBUGFS_ADD(excessive_retries, wl->rootdir); + DEBUGFS_ADD(tx_queue_len, rootdir); + DEBUGFS_ADD(retry_count, rootdir); + DEBUGFS_ADD(excessive_retries, rootdir); - DEBUGFS_ADD(gpio_power, wl->rootdir); + DEBUGFS_ADD(gpio_power, rootdir); - entry = debugfs_create_x32("debug_level", 0600, wl->rootdir, + entry = debugfs_create_x32("debug_level", 0600, rootdir, &wl12xx_debug_level); if (!entry || IS_ERR(entry)) goto err; @@ -419,7 +420,7 @@ err: void wl1271_debugfs_reset(struct wl1271 *wl) { - if (!wl->rootdir) + if (!wl->stats.fw_stats) return; memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats)); @@ -430,13 +431,13 @@ void wl1271_debugfs_reset(struct wl1271 *wl) int wl1271_debugfs_init(struct wl1271 *wl) { int ret; + struct dentry *rootdir; - wl->rootdir = debugfs_create_dir(KBUILD_MODNAME, - wl->hw->wiphy->debugfsdir); + rootdir = debugfs_create_dir(KBUILD_MODNAME, + wl->hw->wiphy->debugfsdir); - if (IS_ERR(wl->rootdir)) { - ret = PTR_ERR(wl->rootdir); - wl->rootdir = NULL; + if (IS_ERR(rootdir)) { + ret = PTR_ERR(rootdir); goto err; } @@ -450,7 +451,7 @@ int wl1271_debugfs_init(struct wl1271 *wl) wl->stats.fw_stats_update = jiffies; - ret = wl1271_debugfs_add_files(wl); + ret = wl1271_debugfs_add_files(wl, rootdir); if (ret < 0) goto err_file; @@ -462,8 +463,7 @@ err_file: wl->stats.fw_stats = NULL; err_fw: - debugfs_remove_recursive(wl->rootdir); - wl->rootdir = NULL; + debugfs_remove_recursive(rootdir); err: return ret; @@ -473,8 +473,4 @@ void wl1271_debugfs_exit(struct wl1271 *wl) { kfree(wl->stats.fw_stats); wl->stats.fw_stats = NULL; - - debugfs_remove_recursive(wl->rootdir); - wl->rootdir = NULL; - } diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 9050dd9b62d2..c3c30b3abc15 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -378,7 +378,6 @@ struct wl1271 { int last_rssi_event; struct wl1271_stats stats; - struct dentry *rootdir; __le32 buffer_32; u32 buffer_cmd; -- cgit v1.2.3 From 0dd386676497fb3097e6fbb3de6090c948c0df30 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 21 Dec 2010 07:00:13 +0300 Subject: wl12xx: use after free in debug code If debugging is turned on, then wl1271_dump() dereferences a freed variable. Signed-off-by: Dan Carpenter Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c index 46714910f98c..8f7ea2c7d567 100644 --- a/drivers/net/wireless/wl12xx/spi.c +++ b/drivers/net/wireless/wl12xx/spi.c @@ -110,9 +110,9 @@ static void wl1271_spi_reset(struct wl1271 *wl) spi_message_add_tail(&t, &m); spi_sync(wl_to_spi(wl), &m); - kfree(cmd); wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); + kfree(cmd); } static void wl1271_spi_init(struct wl1271 *wl) -- cgit v1.2.3 From 6177eaea277527e48753d050723cd138494c98a8 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 22 Dec 2010 12:38:52 +0100 Subject: wl12xx: fix some sparse warnings Note that wl1271_write32() calls cpu_to_le32() by itself, so calling wl1271_write32(addr, cpu_to_le32(val)) is in fact a bug on BE systems. Fix the following sparse warnings: drivers/net/wireless/wl12xx/cmd.c:662:16: warning: incorrect type in assignment (different base types) drivers/net/wireless/wl12xx/cmd.c:662:16: expected unsigned short [unsigned] [addressable] [usertype] llc_type drivers/net/wireless/wl12xx/cmd.c:662:16: got restricted __be16 [usertype] drivers/net/wireless/wl12xx/cmd.c:674:17: warning: incorrect type in assignment (different base types) drivers/net/wireless/wl12xx/cmd.c:674:17: expected unsigned int [unsigned] [addressable] [usertype] sender_ip drivers/net/wireless/wl12xx/cmd.c:674:17: got restricted __be32 [usertype] ip_addr drivers/net/wireless/wl12xx/rx.c:202:4: warning: incorrect type in argument 3 (different base types) drivers/net/wireless/wl12xx/rx.c:202:4: expected unsigned int [unsigned] [usertype] val drivers/net/wireless/wl12xx/rx.c:202:4: got restricted __le32 [usertype] drivers/net/wireless/wl12xx/acx.c:1247:23: warning: incorrect type in assignment (different base types) drivers/net/wireless/wl12xx/acx.c:1247:23: expected restricted __le32 [usertype] ht_capabilites drivers/net/wireless/wl12xx/acx.c:1247:23: got unsigned long drivers/net/wireless/wl12xx/acx.c:1250:24: warning: invalid assignment: |= drivers/net/wireless/wl12xx/acx.c:1250:24: left side has type restricted __le32 drivers/net/wireless/wl12xx/acx.c:1250:24: right side has type unsigned long drivers/net/wireless/wl12xx/acx.c:1253:24: warning: invalid assignment: |= drivers/net/wireless/wl12xx/acx.c:1253:24: left side has type restricted __le32 drivers/net/wireless/wl12xx/acx.c:1253:24: right side has type unsigned long drivers/net/wireless/wl12xx/acx.c:1256:24: warning: invalid assignment: |= drivers/net/wireless/wl12xx/acx.c:1256:24: left side has type restricted __le32 drivers/net/wireless/wl12xx/acx.c:1256:24: right side has type unsigned long Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 13 +++++++------ drivers/net/wireless/wl12xx/cmd.c | 8 ++++---- drivers/net/wireless/wl12xx/rx.c | 3 +-- drivers/net/wireless/wl12xx/wl12xx_80211.h | 6 +++--- 4 files changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index cc4068d2b4a8..17f6a63fbdea 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -1233,6 +1233,7 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl, struct wl1271_acx_ht_capabilities *acx; u8 mac_address[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; int ret = 0; + u32 ht_capabilites = 0; wl1271_debug(DEBUG_ACX, "acx ht capabilities setting"); @@ -1244,16 +1245,16 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl, /* Allow HT Operation ? */ if (allow_ht_operation) { - acx->ht_capabilites = + ht_capabilites = WL1271_ACX_FW_CAP_HT_OPERATION; if (ht_cap->cap & IEEE80211_HT_CAP_GRN_FLD) - acx->ht_capabilites |= + ht_capabilites |= WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT; if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20) - acx->ht_capabilites |= + ht_capabilites |= WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS; if (ht_cap->cap & IEEE80211_HT_CAP_LSIG_TXOP_PROT) - acx->ht_capabilites |= + ht_capabilites |= WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION; /* get data from A-MPDU parameters field */ @@ -1261,10 +1262,10 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl, acx->ampdu_min_spacing = ht_cap->ampdu_density; memcpy(acx->mac_address, mac_address, ETH_ALEN); - } else { /* HT operations are not allowed */ - acx->ht_capabilites = 0; } + acx->ht_capabilites = cpu_to_le32(ht_capabilites); + ret = wl1271_cmd_configure(wl, ACX_PEER_HT_CAP, acx, sizeof(*acx)); if (ret < 0) { wl1271_warning("acx ht capabilities setting failed: %d", ret); diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 0106628aa5a2..52a6bcd5c309 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -659,15 +659,15 @@ int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, __be32 ip_addr) /* llc layer */ memcpy(tmpl.llc_hdr, rfc1042_header, sizeof(rfc1042_header)); - tmpl.llc_type = htons(ETH_P_ARP); + tmpl.llc_type = cpu_to_be16(ETH_P_ARP); /* arp header */ arp_hdr = &tmpl.arp_hdr; - arp_hdr->ar_hrd = htons(ARPHRD_ETHER); - arp_hdr->ar_pro = htons(ETH_P_IP); + arp_hdr->ar_hrd = cpu_to_be16(ARPHRD_ETHER); + arp_hdr->ar_pro = cpu_to_be16(ETH_P_IP); arp_hdr->ar_hln = ETH_ALEN; arp_hdr->ar_pln = 4; - arp_hdr->ar_op = htons(ARPOP_REPLY); + arp_hdr->ar_op = cpu_to_be16(ARPOP_REPLY); /* arp payload */ memcpy(tmpl.sender_hw, wl->vif->addr, ETH_ALEN); diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c index ec8d843d41cf..c6402529eac8 100644 --- a/drivers/net/wireless/wl12xx/rx.c +++ b/drivers/net/wireless/wl12xx/rx.c @@ -198,6 +198,5 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status) pkt_offset += pkt_length; } } - wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, - cpu_to_le32(wl->rx_counter)); + wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); } diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/wl12xx/wl12xx_80211.h index be21032f4dc1..e2b26fbf68c1 100644 --- a/drivers/net/wireless/wl12xx/wl12xx_80211.h +++ b/drivers/net/wireless/wl12xx/wl12xx_80211.h @@ -138,13 +138,13 @@ struct wl12xx_arp_rsp_template { struct ieee80211_hdr_3addr hdr; u8 llc_hdr[sizeof(rfc1042_header)]; - u16 llc_type; + __be16 llc_type; struct arphdr arp_hdr; u8 sender_hw[ETH_ALEN]; - u32 sender_ip; + __be32 sender_ip; u8 target_hw[ETH_ALEN]; - u32 target_ip; + __be32 target_ip; } __packed; -- cgit v1.2.3 From 1e05a81888318752e9a6d2158a95ddd6442ae117 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sat, 16 Oct 2010 17:44:51 +0200 Subject: wl12xx: Add AP related configuration to conf_drv_settings Rate class configuration has been split up for AP and STA modes. Template related configuration likewise separated. Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 2 +- drivers/net/wireless/wl12xx/cmd.c | 4 ++-- drivers/net/wireless/wl12xx/conf.h | 46 ++++++++++++++++++++++++++++++++++++-- drivers/net/wireless/wl12xx/main.c | 45 +++++++++++++++++++++++++++++++++++-- 4 files changed, 90 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index 17f6a63fbdea..d6885d7c4256 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -754,7 +754,7 @@ int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats) int wl1271_acx_rate_policies(struct wl1271 *wl) { struct acx_rate_policy *acx; - struct conf_tx_rate_class *c = &wl->conf.tx.rc_conf; + struct conf_tx_rate_class *c = &wl->conf.tx.sta_rc_conf; int idx = 0; int ret = 0; diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 52a6bcd5c309..3b7b8f0a200b 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -490,8 +490,8 @@ int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, cmd->len = cpu_to_le16(buf_len); cmd->template_type = template_id; cmd->enabled_rates = cpu_to_le32(rates); - cmd->short_retry_limit = wl->conf.tx.rc_conf.short_retry_limit; - cmd->long_retry_limit = wl->conf.tx.rc_conf.long_retry_limit; + cmd->short_retry_limit = wl->conf.tx.tmpl_short_retry_limit; + cmd->long_retry_limit = wl->conf.tx.tmpl_long_retry_limit; cmd->index = index; if (buf) diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index a16b3616e430..7563ce3a9f66 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h @@ -496,6 +496,26 @@ struct conf_rx_settings { CONF_HW_BIT_RATE_2MBPS) #define CONF_TX_RATE_RETRY_LIMIT 10 +/* + * Rates supported for data packets when operating as AP. Note the absense + * of the 22Mbps rate. There is a FW limitation on 12 rates so we must drop + * one. The rate dropped is not mandatory under any operating mode. + */ +#define CONF_TX_AP_ENABLED_RATES (CONF_HW_BIT_RATE_1MBPS | \ + CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS | \ + CONF_HW_BIT_RATE_6MBPS | CONF_HW_BIT_RATE_9MBPS | \ + CONF_HW_BIT_RATE_11MBPS | CONF_HW_BIT_RATE_12MBPS | \ + CONF_HW_BIT_RATE_18MBPS | CONF_HW_BIT_RATE_24MBPS | \ + CONF_HW_BIT_RATE_36MBPS | CONF_HW_BIT_RATE_48MBPS | \ + CONF_HW_BIT_RATE_54MBPS) + +/* + * Default rates for management traffic when operating in AP mode. This + * should be configured according to the basic rate set of the AP + */ +#define CONF_TX_AP_DEFAULT_MGMT_RATES (CONF_HW_BIT_RATE_1MBPS | \ + CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS) + struct conf_tx_rate_class { /* @@ -636,9 +656,9 @@ struct conf_tx_settings { /* * Configuration for rate classes for TX (currently only one - * rate class supported.) + * rate class supported). Used in non-AP mode. */ - struct conf_tx_rate_class rc_conf; + struct conf_tx_rate_class sta_rc_conf; /* * Configuration for access categories for TX rate control. @@ -646,6 +666,22 @@ struct conf_tx_settings { u8 ac_conf_count; struct conf_tx_ac_category ac_conf[CONF_TX_MAX_AC_COUNT]; + /* + * Configuration for rate classes in AP-mode. These rate classes + * are for the AC TX queues + */ + struct conf_tx_rate_class ap_rc_conf[CONF_TX_MAX_AC_COUNT]; + + /* + * Management TX rate class for AP-mode. + */ + struct conf_tx_rate_class ap_mgmt_conf; + + /* + * Broadcast TX rate class for AP-mode. + */ + struct conf_tx_rate_class ap_bcst_conf; + /* * Configuration for TID parameters. */ @@ -687,6 +723,12 @@ struct conf_tx_settings { * Range: CONF_HW_BIT_RATE_* bit mask */ u32 basic_rate_5; + + /* + * TX retry limits for templates + */ + u8 tmpl_short_retry_limit; + u8 tmpl_long_retry_limit; }; enum { diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 062247ef3ad2..788959a5f0de 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -116,11 +116,11 @@ static struct conf_drv_settings default_conf = { }, .tx = { .tx_energy_detection = 0, - .rc_conf = { + .sta_rc_conf = { .enabled_rates = 0, .short_retry_limit = 10, .long_retry_limit = 10, - .aflags = 0 + .aflags = 0, }, .ac_conf_count = 4, .ac_conf = { @@ -153,6 +153,45 @@ static struct conf_drv_settings default_conf = { .tx_op_limit = 1504, }, }, + .ap_rc_conf = { + [0] = { + .enabled_rates = CONF_TX_AP_ENABLED_RATES, + .short_retry_limit = 10, + .long_retry_limit = 10, + .aflags = 0, + }, + [1] = { + .enabled_rates = CONF_TX_AP_ENABLED_RATES, + .short_retry_limit = 10, + .long_retry_limit = 10, + .aflags = 0, + }, + [2] = { + .enabled_rates = CONF_TX_AP_ENABLED_RATES, + .short_retry_limit = 10, + .long_retry_limit = 10, + .aflags = 0, + }, + [3] = { + .enabled_rates = CONF_TX_AP_ENABLED_RATES, + .short_retry_limit = 10, + .long_retry_limit = 10, + .aflags = 0, + }, + }, + .ap_mgmt_conf = { + .enabled_rates = CONF_TX_AP_DEFAULT_MGMT_RATES, + .short_retry_limit = 10, + .long_retry_limit = 10, + .aflags = 0, + }, + .ap_bcst_conf = { + .enabled_rates = CONF_HW_BIT_RATE_1MBPS, + .short_retry_limit = 10, + .long_retry_limit = 10, + .aflags = 0, + }, + .tid_conf_count = 4, .tid_conf = { [CONF_TX_AC_BE] = { @@ -193,6 +232,8 @@ static struct conf_drv_settings default_conf = { .tx_compl_threshold = 4, .basic_rate = CONF_HW_BIT_RATE_1MBPS, .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS, + .tmpl_short_retry_limit = 10, + .tmpl_long_retry_limit = 10, }, .conn = { .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, -- cgit v1.2.3 From 79b223f4c7ce35fba145c504de12be030cc0007e Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sat, 16 Oct 2010 17:52:59 +0200 Subject: wl12xx: AP mode - AP specific CMD_CONFIGURE sub-commands Add AP max retries and rate policy configuration. Rename STA rate policy configuration function. Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 60 ++++++++++++++++++++++++++++++++++++-- drivers/net/wireless/wl12xx/acx.h | 29 ++++++++++++++++-- drivers/net/wireless/wl12xx/conf.h | 6 ++++ drivers/net/wireless/wl12xx/init.c | 2 +- drivers/net/wireless/wl12xx/main.c | 10 +++---- drivers/net/wireless/wl12xx/tx.c | 2 +- 6 files changed, 98 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index d6885d7c4256..646d278bd944 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -751,9 +751,9 @@ int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats) return 0; } -int wl1271_acx_rate_policies(struct wl1271 *wl) +int wl1271_acx_sta_rate_policies(struct wl1271 *wl) { - struct acx_rate_policy *acx; + struct acx_sta_rate_policy *acx; struct conf_tx_rate_class *c = &wl->conf.tx.sta_rc_conf; int idx = 0; int ret = 0; @@ -794,6 +794,38 @@ out: return ret; } +int wl1271_acx_ap_rate_policy(struct wl1271 *wl, struct conf_tx_rate_class *c, + u8 idx) +{ + struct acx_ap_rate_policy *acx; + int ret = 0; + + wl1271_debug(DEBUG_ACX, "acx ap rate policy"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->rate_policy.enabled_rates = cpu_to_le32(c->enabled_rates); + acx->rate_policy.short_retry_limit = c->short_retry_limit; + acx->rate_policy.long_retry_limit = c->long_retry_limit; + acx->rate_policy.aflags = c->aflags; + + acx->rate_policy_idx = idx; + + ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("Setting of ap rate policy failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max, u8 aifsn, u16 txop) { @@ -1335,3 +1367,27 @@ out: kfree(tsf_info); return ret; } + +int wl1271_acx_max_tx_retry(struct wl1271 *wl) +{ + struct wl1271_acx_max_tx_retry *acx = NULL; + int ret; + + wl1271_debug(DEBUG_ACX, "acx max tx retry"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) + return -ENOMEM; + + acx->max_tx_retry = cpu_to_le16(wl->conf.tx.ap_max_tx_retries); + + ret = wl1271_cmd_configure(wl, ACX_MAX_TX_FAILURE, acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("acx max tx retry failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index 7bd8e4db4a71..62a269d84ebe 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h @@ -747,13 +747,23 @@ struct acx_rate_class { #define ACX_TX_BASIC_RATE 0 #define ACX_TX_AP_FULL_RATE 1 #define ACX_TX_RATE_POLICY_CNT 2 -struct acx_rate_policy { +struct acx_sta_rate_policy { struct acx_header header; __le32 rate_class_cnt; struct acx_rate_class rate_class[CONF_TX_MAX_RATE_CLASSES]; } __packed; + +#define ACX_TX_AP_MODE_MGMT_RATE 4 +#define ACX_TX_AP_MODE_BCST_RATE 5 +struct acx_ap_rate_policy { + struct acx_header header; + + __le32 rate_policy_idx; + struct acx_rate_class rate_policy; +} __packed; + struct acx_ac_cfg { struct acx_header header; u8 ac; @@ -1062,6 +1072,17 @@ struct wl1271_acx_fw_tsf_information { u8 padding[3]; } __packed; +struct wl1271_acx_max_tx_retry { + struct acx_header header; + + /* + * the number of frames transmission failures before + * issuing the aging event. + */ + __le16 max_tx_retry; + u8 padding_1[2]; +} __packed; + enum { ACX_WAKE_UP_CONDITIONS = 0x0002, ACX_MEM_CFG = 0x0003, @@ -1119,6 +1140,7 @@ enum { ACX_HT_BSS_OPERATION = 0x0058, ACX_COEX_ACTIVITY = 0x0059, ACX_SET_DCO_ITRIM_PARAMS = 0x0061, + ACX_MAX_TX_FAILURE = 0x0072, DOT11_RX_MSDU_LIFE_TIME = 0x1004, DOT11_CUR_TX_PWR = 0x100D, DOT11_RX_DOT11_MODE = 0x1012, @@ -1160,7 +1182,9 @@ int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble); int wl1271_acx_cts_protect(struct wl1271 *wl, enum acx_ctsprotect_type ctsprotect); int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats); -int wl1271_acx_rate_policies(struct wl1271 *wl); +int wl1271_acx_sta_rate_policies(struct wl1271 *wl); +int wl1271_acx_ap_rate_policy(struct wl1271 *wl, struct conf_tx_rate_class *c, + u8 idx); int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max, u8 aifsn, u16 txop); int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type, @@ -1186,5 +1210,6 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl, int wl1271_acx_set_ht_information(struct wl1271 *wl, u16 ht_operation_mode); int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); +int wl1271_acx_max_tx_retry(struct wl1271 *wl); #endif /* __WL1271_ACX_H__ */ diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index 7563ce3a9f66..f5c048c9bea4 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h @@ -682,6 +682,12 @@ struct conf_tx_settings { */ struct conf_tx_rate_class ap_bcst_conf; + /* + * AP-mode - allow this number of TX retries to a station before an + * event is triggered from FW. + */ + u16 ap_max_tx_retries; + /* * Configuration for TID parameters. */ diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index 785a5304bfc4..f468d7178a9f 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c @@ -322,7 +322,7 @@ int wl1271_hw_init(struct wl1271 *wl) } /* Configure TX rate classes */ - ret = wl1271_acx_rate_policies(wl); + ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) goto out_free_memmap; diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 788959a5f0de..b40568e89eb4 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -191,7 +191,7 @@ static struct conf_drv_settings default_conf = { .long_retry_limit = 10, .aflags = 0, }, - + .ap_max_tx_retries = 100, .tid_conf_count = 4, .tid_conf = { [CONF_TX_AC_BE] = { @@ -1393,7 +1393,7 @@ static int wl1271_handle_idle(struct wl1271 *wl, bool idle) } wl->rate_set = wl1271_min_rate_get(wl); wl->sta_rate_set = 0; - ret = wl1271_acx_rate_policies(wl); + ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) goto out; ret = wl1271_acx_keep_alive_config( @@ -1468,7 +1468,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) wl1271_set_band_rate(wl); wl->basic_rate = wl1271_min_rate_get(wl); - ret = wl1271_acx_rate_policies(wl); + ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) wl1271_warning("rate policy for update channel " "failed %d", ret); @@ -2017,7 +2017,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates); wl->basic_rate = wl1271_min_rate_get(wl); - ret = wl1271_acx_rate_policies(wl); + ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) goto out_sleep; @@ -2071,7 +2071,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, /* revert back to minimum rates for the current band */ wl1271_set_band_rate(wl); wl->basic_rate = wl1271_min_rate_get(wl); - ret = wl1271_acx_rate_policies(wl); + ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) goto out_sleep; diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index b44c75cd8c1e..0cf210d6aa46 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -303,7 +303,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl) woken_up = true; wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates); - wl1271_acx_rate_policies(wl); + wl1271_acx_sta_rate_policies(wl); } while ((skb = wl1271_skb_dequeue(wl))) { -- cgit v1.2.3 From 203c903cbfbdf23bbb3020b9344dd1ffabcfcb53 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Mon, 25 Oct 2010 11:17:44 +0200 Subject: wl12xx: AP mode - add AP specific event Add STA-remove completion event. Unmask it during boot if operating in AP-mode. Ignore unrelated events in AP-mode. Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/boot.c | 3 +++ drivers/net/wireless/wl12xx/event.c | 7 ++++--- drivers/net/wireless/wl12xx/event.h | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index 4df04f84d7f1..b504367f281f 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c @@ -431,6 +431,9 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl) PSPOLL_DELIVERY_FAILURE_EVENT_ID | SOFT_GEMINI_SENSE_EVENT_ID; + if (wl->bss_type == BSS_TYPE_AP_BSS) + wl->event_mask |= STA_REMOVE_COMPLETE_EVENT_ID; + ret = wl1271_event_unmask(wl); if (ret < 0) { wl1271_error("EVENT mask setting failed"); diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index f9146f5242fb..3376a5de09d7 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c @@ -186,6 +186,7 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) int ret; u32 vector; bool beacon_loss = false; + bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); wl1271_event_mbox_dump(mbox); @@ -218,21 +219,21 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) * BSS_LOSE_EVENT, beacon loss has to be reported to the stack. * */ - if (vector & BSS_LOSE_EVENT_ID) { + if ((vector & BSS_LOSE_EVENT_ID) && !is_ap) { wl1271_info("Beacon loss detected."); /* indicate to the stack, that beacons have been lost */ beacon_loss = true; } - if (vector & PS_REPORT_EVENT_ID) { + if ((vector & PS_REPORT_EVENT_ID) && !is_ap) { wl1271_debug(DEBUG_EVENT, "PS_REPORT_EVENT"); ret = wl1271_event_ps_report(wl, mbox, &beacon_loss); if (ret < 0) return ret; } - if (vector & PSPOLL_DELIVERY_FAILURE_EVENT_ID) + if ((vector & PSPOLL_DELIVERY_FAILURE_EVENT_ID) && !is_ap) wl1271_event_pspoll_delivery_fail(wl); if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) { diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h index 6cce0143adb5..fd955f31cec4 100644 --- a/drivers/net/wireless/wl12xx/event.h +++ b/drivers/net/wireless/wl12xx/event.h @@ -59,6 +59,7 @@ enum { BSS_LOSE_EVENT_ID = BIT(18), REGAINED_BSS_EVENT_ID = BIT(19), ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID = BIT(20), + STA_REMOVE_COMPLETE_EVENT_ID = BIT(21), /* AP */ SOFT_GEMINI_SENSE_EVENT_ID = BIT(22), SOFT_GEMINI_PREDICTION_EVENT_ID = BIT(23), SOFT_GEMINI_AVALANCHE_EVENT_ID = BIT(24), -- cgit v1.2.3 From 98bdaabbbced007c7eb89cd373f9cb1640635b46 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sat, 16 Oct 2010 18:08:58 +0200 Subject: wl12xx: AP-mode high level commands Add commands to start/stop BSS, add/remove STA and configure encryption keys. Split the encryption commands "set key" and "set default key" into AP and STA specific versions. Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/cmd.c | 276 ++++++++++++++++++++++++++++++++++- drivers/net/wireless/wl12xx/cmd.h | 139 +++++++++++++++++- drivers/net/wireless/wl12xx/init.c | 2 +- drivers/net/wireless/wl12xx/main.c | 6 +- drivers/net/wireless/wl12xx/tx.c | 2 +- drivers/net/wireless/wl12xx/wl12xx.h | 8 + 6 files changed, 419 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 3b7b8f0a200b..f9c5ce91cb12 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -36,6 +36,7 @@ #include "wl12xx_80211.h" #include "cmd.h" #include "event.h" +#include "tx.h" #define WL1271_CMD_FAST_POLL_COUNT 50 @@ -702,9 +703,9 @@ int wl1271_build_qos_null_data(struct wl1271 *wl) wl->basic_rate); } -int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id) +int wl1271_cmd_set_sta_default_wep_key(struct wl1271 *wl, u8 id) { - struct wl1271_cmd_set_keys *cmd; + struct wl1271_cmd_set_sta_keys *cmd; int ret = 0; wl1271_debug(DEBUG_CMD, "cmd set_default_wep_key %d", id); @@ -731,11 +732,42 @@ out: return ret; } -int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, +int wl1271_cmd_set_ap_default_wep_key(struct wl1271 *wl, u8 id) +{ + struct wl1271_cmd_set_ap_keys *cmd; + int ret = 0; + + wl1271_debug(DEBUG_CMD, "cmd set_ap_default_wep_key %d", id); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + cmd->hlid = WL1271_AP_BROADCAST_HLID; + cmd->key_id = id; + cmd->lid_key_type = WEP_DEFAULT_LID_TYPE; + cmd->key_action = cpu_to_le16(KEY_SET_ID); + cmd->key_type = KEY_WEP; + + ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_warning("cmd set_ap_default_wep_key failed: %d", ret); + goto out; + } + +out: + kfree(cmd); + + return ret; +} + +int wl1271_cmd_set_sta_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, u8 key_size, const u8 *key, const u8 *addr, u32 tx_seq_32, u16 tx_seq_16) { - struct wl1271_cmd_set_keys *cmd; + struct wl1271_cmd_set_sta_keys *cmd; int ret = 0; cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); @@ -788,6 +820,67 @@ out: return ret; } +int wl1271_cmd_set_ap_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, + u8 key_size, const u8 *key, u8 hlid, u32 tx_seq_32, + u16 tx_seq_16) +{ + struct wl1271_cmd_set_ap_keys *cmd; + int ret = 0; + u8 lid_type; + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) + return -ENOMEM; + + if (hlid == WL1271_AP_BROADCAST_HLID) { + if (key_type == KEY_WEP) + lid_type = WEP_DEFAULT_LID_TYPE; + else + lid_type = BROADCAST_LID_TYPE; + } else { + lid_type = UNICAST_LID_TYPE; + } + + wl1271_debug(DEBUG_CRYPT, "ap key action: %d id: %d lid: %d type: %d" + " hlid: %d", (int)action, (int)id, (int)lid_type, + (int)key_type, (int)hlid); + + cmd->lid_key_type = lid_type; + cmd->hlid = hlid; + cmd->key_action = cpu_to_le16(action); + cmd->key_size = key_size; + cmd->key_type = key_type; + cmd->key_id = id; + cmd->ac_seq_num16[0] = cpu_to_le16(tx_seq_16); + cmd->ac_seq_num32[0] = cpu_to_le32(tx_seq_32); + + if (key_type == KEY_TKIP) { + /* + * We get the key in the following form: + * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes) + * but the target is expecting: + * TKIP - RX MIC - TX MIC + */ + memcpy(cmd->key, key, 16); + memcpy(cmd->key + 16, key + 24, 8); + memcpy(cmd->key + 24, key + 16, 8); + } else { + memcpy(cmd->key, key, key_size); + } + + wl1271_dump(DEBUG_CRYPT, "TARGET AP KEY: ", cmd, sizeof(*cmd)); + + ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_warning("could not set ap keys"); + goto out; + } + +out: + kfree(cmd); + return ret; +} + int wl1271_cmd_disconnect(struct wl1271 *wl) { struct wl1271_cmd_disconnect *cmd; @@ -850,3 +943,178 @@ out_free: out: return ret; } + +int wl1271_cmd_start_bss(struct wl1271 *wl) +{ + struct wl1271_cmd_bss_start *cmd; + struct ieee80211_bss_conf *bss_conf = &wl->vif->bss_conf; + int ret; + + wl1271_debug(DEBUG_CMD, "cmd start bss"); + + /* + * FIXME: We currently do not support hidden SSID. The real SSID + * should be fetched from mac80211 first. + */ + if (wl->ssid_len == 0) { + wl1271_warning("Hidden SSID currently not supported for AP"); + ret = -EINVAL; + goto out; + } + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + memcpy(cmd->bssid, bss_conf->bssid, ETH_ALEN); + + cmd->aging_period = WL1271_AP_DEF_INACTIV_SEC; + cmd->bss_index = WL1271_AP_BSS_INDEX; + cmd->global_hlid = WL1271_AP_GLOBAL_HLID; + cmd->broadcast_hlid = WL1271_AP_BROADCAST_HLID; + cmd->basic_rate_set = cpu_to_le32(wl->basic_rate_set); + cmd->beacon_interval = cpu_to_le16(wl->beacon_int); + cmd->dtim_interval = bss_conf->dtim_period; + cmd->beacon_expiry = WL1271_AP_DEF_BEACON_EXP; + cmd->channel = wl->channel; + cmd->ssid_len = wl->ssid_len; + cmd->ssid_type = SSID_TYPE_PUBLIC; + memcpy(cmd->ssid, wl->ssid, wl->ssid_len); + + switch (wl->band) { + case IEEE80211_BAND_2GHZ: + cmd->band = RADIO_BAND_2_4GHZ; + break; + case IEEE80211_BAND_5GHZ: + cmd->band = RADIO_BAND_5GHZ; + break; + default: + wl1271_warning("bss start - unknown band: %d", (int)wl->band); + cmd->band = RADIO_BAND_2_4GHZ; + break; + } + + ret = wl1271_cmd_send(wl, CMD_BSS_START, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_error("failed to initiate cmd start bss"); + goto out_free; + } + +out_free: + kfree(cmd); + +out: + return ret; +} + +int wl1271_cmd_stop_bss(struct wl1271 *wl) +{ + struct wl1271_cmd_bss_start *cmd; + int ret; + + wl1271_debug(DEBUG_CMD, "cmd stop bss"); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + cmd->bss_index = WL1271_AP_BSS_INDEX; + + ret = wl1271_cmd_send(wl, CMD_BSS_STOP, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_error("failed to initiate cmd stop bss"); + goto out_free; + } + +out_free: + kfree(cmd); + +out: + return ret; +} + +int wl1271_cmd_add_sta(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid) +{ + struct wl1271_cmd_add_sta *cmd; + int ret; + + wl1271_debug(DEBUG_CMD, "cmd add sta %d", (int)hlid); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + /* currently we don't support UAPSD */ + cmd->sp_len = 0; + + memcpy(cmd->addr, sta->addr, ETH_ALEN); + cmd->bss_index = WL1271_AP_BSS_INDEX; + cmd->aid = sta->aid; + cmd->hlid = hlid; + + /* + * FIXME: Does STA support QOS? We need to propagate this info from + * hostapd. Currently not that important since this is only used for + * sending the correct flavor of null-data packet in response to a + * trigger. + */ + cmd->wmm = 0; + + cmd->supported_rates = cpu_to_le32(wl1271_tx_enabled_rates_get(wl, + sta->supp_rates[wl->band])); + + wl1271_debug(DEBUG_CMD, "new sta rates: 0x%x", cmd->supported_rates); + + ret = wl1271_cmd_send(wl, CMD_ADD_STA, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_error("failed to initiate cmd add sta"); + goto out_free; + } + +out_free: + kfree(cmd); + +out: + return ret; +} + +int wl1271_cmd_remove_sta(struct wl1271 *wl, u8 hlid) +{ + struct wl1271_cmd_remove_sta *cmd; + int ret; + + wl1271_debug(DEBUG_CMD, "cmd remove sta %d", (int)hlid); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + cmd->hlid = hlid; + /* We never send a deauth, mac80211 is in charge of this */ + cmd->reason_opcode = 0; + cmd->send_deauth_flag = 0; + + ret = wl1271_cmd_send(wl, CMD_REMOVE_STA, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_error("failed to initiate cmd remove sta"); + goto out_free; + } + + ret = wl1271_cmd_wait_for_event(wl, STA_REMOVE_COMPLETE_EVENT_ID); + if (ret < 0) + wl1271_error("cmd remove sta event completion error"); + +out_free: + kfree(cmd); + +out: + return ret; +} diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h index 2a1d9db7ceb8..072bf3c2f24b 100644 --- a/drivers/net/wireless/wl12xx/cmd.h +++ b/drivers/net/wireless/wl12xx/cmd.h @@ -54,12 +54,20 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, __be32 ip_addr); int wl1271_build_qos_null_data(struct wl1271 *wl); int wl1271_cmd_build_klv_null_data(struct wl1271 *wl); -int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id); -int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, - u8 key_size, const u8 *key, const u8 *addr, - u32 tx_seq_32, u16 tx_seq_16); +int wl1271_cmd_set_sta_default_wep_key(struct wl1271 *wl, u8 id); +int wl1271_cmd_set_ap_default_wep_key(struct wl1271 *wl, u8 id); +int wl1271_cmd_set_sta_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, + u8 key_size, const u8 *key, const u8 *addr, + u32 tx_seq_32, u16 tx_seq_16); +int wl1271_cmd_set_ap_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, + u8 key_size, const u8 *key, u8 hlid, u32 tx_seq_32, + u16 tx_seq_16); int wl1271_cmd_disconnect(struct wl1271 *wl); int wl1271_cmd_set_sta_state(struct wl1271 *wl); +int wl1271_cmd_start_bss(struct wl1271 *wl); +int wl1271_cmd_stop_bss(struct wl1271 *wl); +int wl1271_cmd_add_sta(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid); +int wl1271_cmd_remove_sta(struct wl1271 *wl, u8 hlid); enum wl1271_commands { CMD_INTERROGATE = 1, /*use this to read information elements*/ @@ -98,6 +106,12 @@ enum wl1271_commands { CMD_STOP_PERIODIC_SCAN = 51, CMD_SET_STA_STATE = 52, + /* AP mode commands */ + CMD_BSS_START = 60, + CMD_BSS_STOP = 61, + CMD_ADD_STA = 62, + CMD_REMOVE_STA = 63, + NUM_COMMANDS, MAX_COMMAND_ID = 0xFFFF, }; @@ -289,7 +303,7 @@ enum wl1271_cmd_key_type { /* FIXME: Add description for key-types */ -struct wl1271_cmd_set_keys { +struct wl1271_cmd_set_sta_keys { struct wl1271_cmd_header header; /* Ignored for default WEP key */ @@ -318,6 +332,57 @@ struct wl1271_cmd_set_keys { __le32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY]; } __packed; +enum wl1271_cmd_lid_key_type { + UNICAST_LID_TYPE = 0, + BROADCAST_LID_TYPE = 1, + WEP_DEFAULT_LID_TYPE = 2 +}; + +struct wl1271_cmd_set_ap_keys { + struct wl1271_cmd_header header; + + /* + * Indicates whether the HLID is a unicast key set + * or broadcast key set. A special value 0xFF is + * used to indicate that the HLID is on WEP-default + * (multi-hlids). of type wl1271_cmd_lid_key_type. + */ + u8 hlid; + + /* + * In WEP-default network (hlid == 0xFF) used to + * indicate which network STA/IBSS/AP role should be + * changed + */ + u8 lid_key_type; + + /* + * Key ID - For TKIP and AES key types, this field + * indicates the value that should be inserted into + * the KeyID field of frames transmitted using this + * key entry. For broadcast keys the index use as a + * marker for TX/RX key. + * For WEP default network (HLID=0xFF), this field + * indicates the ID of the key to add or remove. + */ + u8 key_id; + u8 reserved_1; + + /* key_action_e */ + __le16 key_action; + + /* key size in bytes */ + u8 key_size; + + /* key_type_e */ + u8 key_type; + + /* This field holds the security key data to add to the STA table */ + u8 key[MAX_KEY_SIZE]; + __le16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY]; + __le32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY]; +} __packed; + struct wl1271_cmd_test_header { u8 id; u8 padding[3]; @@ -412,4 +477,68 @@ struct wl1271_cmd_set_sta_state { u8 padding[3]; } __packed; +enum wl1271_ssid_type { + SSID_TYPE_PUBLIC = 0, + SSID_TYPE_HIDDEN = 1 +}; + +struct wl1271_cmd_bss_start { + struct wl1271_cmd_header header; + + /* wl1271_ssid_type */ + u8 ssid_type; + u8 ssid_len; + u8 ssid[IW_ESSID_MAX_SIZE]; + u8 padding_1[2]; + + /* Basic rate set */ + __le32 basic_rate_set; + /* Aging period in seconds*/ + __le16 aging_period; + + /* + * This field specifies the time between target beacon + * transmission times (TBTTs), in time units (TUs). + * Valid values are 1 to 1024. + */ + __le16 beacon_interval; + u8 bssid[ETH_ALEN]; + u8 bss_index; + /* Radio band */ + u8 band; + u8 channel; + /* The host link id for the AP's global queue */ + u8 global_hlid; + /* The host link id for the AP's broadcast queue */ + u8 broadcast_hlid; + /* DTIM count */ + u8 dtim_interval; + /* Beacon expiry time in ms */ + u8 beacon_expiry; + u8 padding_2[3]; +} __packed; + +struct wl1271_cmd_add_sta { + struct wl1271_cmd_header header; + + u8 addr[ETH_ALEN]; + u8 hlid; + u8 aid; + u8 psd_type[NUM_ACCESS_CATEGORIES_COPY]; + __le32 supported_rates; + u8 bss_index; + u8 sp_len; + u8 wmm; + u8 padding1; +} __packed; + +struct wl1271_cmd_remove_sta { + struct wl1271_cmd_header header; + + u8 hlid; + u8 reason_opcode; + u8 send_deauth_flag; + u8 padding1; +} __packed; + #endif /* __WL1271_CMD_H__ */ diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index f468d7178a9f..799c36914735 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c @@ -41,7 +41,7 @@ static int wl1271_init_hwenc_config(struct wl1271 *wl) return ret; } - ret = wl1271_cmd_set_default_wep_key(wl, wl->default_key); + ret = wl1271_cmd_set_sta_default_wep_key(wl, wl->default_key); if (ret < 0) { wl1271_warning("couldn't set default key"); return ret; diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index b40568e89eb4..9785b4c43c86 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1712,7 +1712,7 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, switch (cmd) { case SET_KEY: - ret = wl1271_cmd_set_key(wl, KEY_ADD_OR_REPLACE, + ret = wl1271_cmd_set_sta_key(wl, KEY_ADD_OR_REPLACE, key_conf->keyidx, key_type, key_conf->keylen, key_conf->key, addr, tx_seq_32, tx_seq_16); @@ -1723,7 +1723,7 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, /* the default WEP key needs to be configured at least once */ if (key_type == KEY_WEP) { - ret = wl1271_cmd_set_default_wep_key(wl, + ret = wl1271_cmd_set_sta_default_wep_key(wl, wl->default_key); if (ret < 0) goto out_sleep; @@ -1738,7 +1738,7 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (!is_broadcast_ether_addr(addr)) break; - ret = wl1271_cmd_set_key(wl, KEY_REMOVE, + ret = wl1271_cmd_set_sta_key(wl, KEY_REMOVE, key_conf->keyidx, key_type, key_conf->keylen, key_conf->key, addr, 0, 0); diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 0cf210d6aa46..442a7bd956ea 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -170,7 +170,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, /* FIXME: do we have to do this if we're not using WEP? */ if (unlikely(wl->default_key != idx)) { - ret = wl1271_cmd_set_default_wep_key(wl, idx); + ret = wl1271_cmd_set_sta_default_wep_key(wl, idx); if (ret < 0) return ret; wl->default_key = idx; diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index c3c30b3abc15..340153f609c7 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -129,6 +129,14 @@ extern u32 wl12xx_debug_level; #define WL1271_DEFAULT_BEACON_INT 100 #define WL1271_DEFAULT_DTIM_PERIOD 1 +#define WL1271_AP_GLOBAL_HLID 0 +#define WL1271_AP_BROADCAST_HLID 1 +#define WL1271_AP_STA_HLID_START 2 + +#define WL1271_AP_BSS_INDEX 0 +#define WL1271_AP_DEF_INACTIV_SEC 300 +#define WL1271_AP_DEF_BEACON_EXP 20 + #define ACX_TX_DESCRIPTORS 32 #define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE) -- cgit v1.2.3 From 05285cf9b581af05813cfaa60e23227b009b7754 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Fri, 12 Nov 2010 17:15:03 +0200 Subject: wl12xx: AP mode - workaround for FW bug on station remove Sometimes an event indicating station removal is not sent up by firmware. We work around this by always indicating success in when a wait for the event timeouts. Temporary workaround until a FW fix is introduced. Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/cmd.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index f9c5ce91cb12..e28d9cab1185 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -222,7 +222,7 @@ int wl1271_cmd_ext_radio_parms(struct wl1271 *wl) * Poll the mailbox event field until any of the bits in the mask is set or a * timeout occurs (WL1271_EVENT_TIMEOUT in msecs) */ -static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) +static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, u32 mask) { u32 events_vector, event; unsigned long timeout; @@ -231,7 +231,8 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) do { if (time_after(jiffies, timeout)) { - ieee80211_queue_work(wl->hw, &wl->recovery_work); + wl1271_debug(DEBUG_CMD, "timeout waiting for event %d", + (int)mask); return -ETIMEDOUT; } @@ -249,6 +250,19 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) return 0; } +static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) +{ + int ret; + + ret = wl1271_cmd_wait_for_event_or_timeout(wl, mask); + if (ret != 0) { + ieee80211_queue_work(wl->hw, &wl->recovery_work); + return ret; + } + + return 0; +} + int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) { struct wl1271_cmd_join *join; @@ -1108,9 +1122,11 @@ int wl1271_cmd_remove_sta(struct wl1271 *wl, u8 hlid) goto out_free; } - ret = wl1271_cmd_wait_for_event(wl, STA_REMOVE_COMPLETE_EVENT_ID); - if (ret < 0) - wl1271_error("cmd remove sta event completion error"); + /* + * We are ok with a timeout here. The event is sometimes not sent + * due to a firmware bug. + */ + wl1271_cmd_wait_for_event_or_timeout(wl, STA_REMOVE_COMPLETE_EVENT_ID); out_free: kfree(cmd); -- cgit v1.2.3 From e0fe371b74326a85029fe8720506e021fe73905a Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sat, 16 Oct 2010 18:19:53 +0200 Subject: wl12xx: AP mode - init sequence Split HW init sequence into AP/STA specific parts The AP specific init sequence includes configuration of templates, rate classes, power mode, etc. Also unmask AP specific events in the event mbox. Separate the differences between AP and STA init into mode specific functions called from wl1271_hw_init. The first is called after radio configuration and the second after memory configuration. Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/cmd.h | 7 + drivers/net/wireless/wl12xx/init.c | 352 +++++++++++++++++++++++------ drivers/net/wireless/wl12xx/init.h | 2 +- drivers/net/wireless/wl12xx/main.c | 32 +-- drivers/net/wireless/wl12xx/tx.c | 18 ++ drivers/net/wireless/wl12xx/tx.h | 1 + drivers/net/wireless/wl12xx/wl12xx_80211.h | 5 + 7 files changed, 317 insertions(+), 100 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h index 072bf3c2f24b..c9909e09cd9d 100644 --- a/drivers/net/wireless/wl12xx/cmd.h +++ b/drivers/net/wireless/wl12xx/cmd.h @@ -140,6 +140,13 @@ enum cmd_templ { * For CTS-to-self (FastCTS) mechanism * for BT/WLAN coexistence (SoftGemini). */ CMD_TEMPL_ARP_RSP, + + /* AP-mode specific */ + CMD_TEMPL_AP_BEACON = 13, + CMD_TEMPL_AP_PROBE_RESPONSE, + CMD_TEMPL_AP_ARP_RSP, + CMD_TEMPL_DEAUTH_AP, + CMD_TEMPL_MAX = 0xff }; diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index 799c36914735..bdb61232f80c 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c @@ -30,27 +30,9 @@ #include "acx.h" #include "cmd.h" #include "reg.h" +#include "tx.h" -static int wl1271_init_hwenc_config(struct wl1271 *wl) -{ - int ret; - - ret = wl1271_acx_feature_cfg(wl); - if (ret < 0) { - wl1271_warning("couldn't set feature config"); - return ret; - } - - ret = wl1271_cmd_set_sta_default_wep_key(wl, wl->default_key); - if (ret < 0) { - wl1271_warning("couldn't set default key"); - return ret; - } - - return 0; -} - -int wl1271_init_templates_config(struct wl1271 *wl) +int wl1271_sta_init_templates_config(struct wl1271 *wl) { int ret, i; @@ -118,6 +100,132 @@ int wl1271_init_templates_config(struct wl1271 *wl) return 0; } +static int wl1271_ap_init_deauth_template(struct wl1271 *wl) +{ + struct wl12xx_disconn_template *tmpl; + int ret; + + tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL); + if (!tmpl) { + ret = -ENOMEM; + goto out; + } + + tmpl->header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | + IEEE80211_STYPE_DEAUTH); + + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP, + tmpl, sizeof(*tmpl), 0, + wl1271_tx_min_rate_get(wl)); + +out: + kfree(tmpl); + return ret; +} + +static int wl1271_ap_init_null_template(struct wl1271 *wl) +{ + struct ieee80211_hdr_3addr *nullfunc; + int ret; + + nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL); + if (!nullfunc) { + ret = -ENOMEM; + goto out; + } + + nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | + IEEE80211_STYPE_NULLFUNC | + IEEE80211_FCTL_FROMDS); + + /* nullfunc->addr1 is filled by FW */ + + memcpy(nullfunc->addr2, wl->mac_addr, ETH_ALEN); + memcpy(nullfunc->addr3, wl->mac_addr, ETH_ALEN); + + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, nullfunc, + sizeof(*nullfunc), 0, + wl1271_tx_min_rate_get(wl)); + +out: + kfree(nullfunc); + return ret; +} + +static int wl1271_ap_init_qos_null_template(struct wl1271 *wl) +{ + struct ieee80211_qos_hdr *qosnull; + int ret; + + qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL); + if (!qosnull) { + ret = -ENOMEM; + goto out; + } + + qosnull->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | + IEEE80211_STYPE_QOS_NULLFUNC | + IEEE80211_FCTL_FROMDS); + + /* qosnull->addr1 is filled by FW */ + + memcpy(qosnull->addr2, wl->mac_addr, ETH_ALEN); + memcpy(qosnull->addr3, wl->mac_addr, ETH_ALEN); + + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, qosnull, + sizeof(*qosnull), 0, + wl1271_tx_min_rate_get(wl)); + +out: + kfree(qosnull); + return ret; +} + +static int wl1271_ap_init_templates_config(struct wl1271 *wl) +{ + int ret; + + /* + * Put very large empty placeholders for all templates. These + * reserve memory for later. + */ + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_PROBE_RESPONSE, NULL, + sizeof + (struct wl12xx_probe_resp_template), + 0, WL1271_RATE_AUTOMATIC); + if (ret < 0) + return ret; + + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_BEACON, NULL, + sizeof + (struct wl12xx_beacon_template), + 0, WL1271_RATE_AUTOMATIC); + if (ret < 0) + return ret; + + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP, NULL, + sizeof + (struct wl12xx_disconn_template), + 0, WL1271_RATE_AUTOMATIC); + if (ret < 0) + return ret; + + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL, + sizeof(struct wl12xx_null_data_template), + 0, WL1271_RATE_AUTOMATIC); + if (ret < 0) + return ret; + + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL, + sizeof + (struct wl12xx_qos_null_data_template), + 0, WL1271_RATE_AUTOMATIC); + if (ret < 0) + return ret; + + return 0; +} + static int wl1271_init_rx_config(struct wl1271 *wl, u32 config, u32 filter) { int ret; @@ -145,10 +253,6 @@ int wl1271_init_phy_config(struct wl1271 *wl) if (ret < 0) return ret; - ret = wl1271_acx_group_address_tbl(wl, true, NULL, 0); - if (ret < 0) - return ret; - ret = wl1271_acx_service_period_timeout(wl); if (ret < 0) return ret; @@ -213,11 +317,150 @@ static int wl1271_init_beacon_broadcast(struct wl1271 *wl) return 0; } +static int wl1271_sta_hw_init(struct wl1271 *wl) +{ + int ret; + + ret = wl1271_cmd_ext_radio_parms(wl); + if (ret < 0) + return ret; + + ret = wl1271_sta_init_templates_config(wl); + if (ret < 0) + return ret; + + ret = wl1271_acx_group_address_tbl(wl, true, NULL, 0); + if (ret < 0) + return ret; + + /* Initialize connection monitoring thresholds */ + ret = wl1271_acx_conn_monit_params(wl, false); + if (ret < 0) + return ret; + + /* Beacon filtering */ + ret = wl1271_init_beacon_filter(wl); + if (ret < 0) + return ret; + + /* Bluetooth WLAN coexistence */ + ret = wl1271_init_pta(wl); + if (ret < 0) + return ret; + + /* Beacons and broadcast settings */ + ret = wl1271_init_beacon_broadcast(wl); + if (ret < 0) + return ret; + + /* Configure for ELP power saving */ + ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); + if (ret < 0) + return ret; + + /* Configure rssi/snr averaging weights */ + ret = wl1271_acx_rssi_snr_avg_weights(wl); + if (ret < 0) + return ret; + + ret = wl1271_acx_sta_rate_policies(wl); + if (ret < 0) + return ret; + + return 0; +} + +static int wl1271_sta_hw_init_post_mem(struct wl1271 *wl) +{ + int ret, i; + + ret = wl1271_cmd_set_sta_default_wep_key(wl, wl->default_key); + if (ret < 0) { + wl1271_warning("couldn't set default key"); + return ret; + } + + /* disable all keep-alive templates */ + for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { + ret = wl1271_acx_keep_alive_config(wl, i, + ACX_KEEP_ALIVE_TPL_INVALID); + if (ret < 0) + return ret; + } + + /* disable the keep-alive feature */ + ret = wl1271_acx_keep_alive_mode(wl, false); + if (ret < 0) + return ret; + + return 0; +} + +static int wl1271_ap_hw_init(struct wl1271 *wl) +{ + int ret, i; + + ret = wl1271_ap_init_templates_config(wl); + if (ret < 0) + return ret; + + /* Configure for power always on */ + ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); + if (ret < 0) + return ret; + + /* Configure initial TX rate classes */ + for (i = 0; i < wl->conf.tx.ac_conf_count; i++) { + ret = wl1271_acx_ap_rate_policy(wl, + &wl->conf.tx.ap_rc_conf[i], i); + if (ret < 0) + return ret; + } + + ret = wl1271_acx_ap_rate_policy(wl, + &wl->conf.tx.ap_mgmt_conf, + ACX_TX_AP_MODE_MGMT_RATE); + if (ret < 0) + return ret; + + ret = wl1271_acx_ap_rate_policy(wl, + &wl->conf.tx.ap_bcst_conf, + ACX_TX_AP_MODE_BCST_RATE); + if (ret < 0) + return ret; + + ret = wl1271_acx_max_tx_retry(wl); + if (ret < 0) + return ret; + + return 0; +} + +static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl) +{ + int ret; + + ret = wl1271_ap_init_deauth_template(wl); + if (ret < 0) + return ret; + + ret = wl1271_ap_init_null_template(wl); + if (ret < 0) + return ret; + + ret = wl1271_ap_init_qos_null_template(wl); + if (ret < 0) + return ret; + + return 0; +} + int wl1271_hw_init(struct wl1271 *wl) { struct conf_tx_ac_category *conf_ac; struct conf_tx_tid *conf_tid; int ret, i; + bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); ret = wl1271_cmd_general_parms(wl); if (ret < 0) @@ -227,12 +470,12 @@ int wl1271_hw_init(struct wl1271 *wl) if (ret < 0) return ret; - ret = wl1271_cmd_ext_radio_parms(wl); - if (ret < 0) - return ret; + /* Mode specific init */ + if (is_ap) + ret = wl1271_ap_hw_init(wl); + else + ret = wl1271_sta_hw_init(wl); - /* Template settings */ - ret = wl1271_init_templates_config(wl); if (ret < 0) return ret; @@ -259,16 +502,6 @@ int wl1271_hw_init(struct wl1271 *wl) if (ret < 0) goto out_free_memmap; - /* Initialize connection monitoring thresholds */ - ret = wl1271_acx_conn_monit_params(wl, false); - if (ret < 0) - goto out_free_memmap; - - /* Beacon filtering */ - ret = wl1271_init_beacon_filter(wl); - if (ret < 0) - goto out_free_memmap; - /* Configure TX patch complete interrupt behavior */ ret = wl1271_acx_tx_config_options(wl); if (ret < 0) @@ -279,21 +512,11 @@ int wl1271_hw_init(struct wl1271 *wl) if (ret < 0) goto out_free_memmap; - /* Bluetooth WLAN coexistence */ - ret = wl1271_init_pta(wl); - if (ret < 0) - goto out_free_memmap; - /* Energy detection */ ret = wl1271_init_energy_detection(wl); if (ret < 0) goto out_free_memmap; - /* Beacons and boradcast settings */ - ret = wl1271_init_beacon_broadcast(wl); - if (ret < 0) - goto out_free_memmap; - /* Default fragmentation threshold */ ret = wl1271_acx_frag_threshold(wl, wl->conf.tx.frag_threshold); if (ret < 0) @@ -321,23 +544,13 @@ int wl1271_hw_init(struct wl1271 *wl) goto out_free_memmap; } - /* Configure TX rate classes */ - ret = wl1271_acx_sta_rate_policies(wl); - if (ret < 0) - goto out_free_memmap; - /* Enable data path */ ret = wl1271_cmd_data_path(wl, 1); if (ret < 0) goto out_free_memmap; - /* Configure for ELP power saving */ - ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); - if (ret < 0) - goto out_free_memmap; - /* Configure HW encryption */ - ret = wl1271_init_hwenc_config(wl); + ret = wl1271_acx_feature_cfg(wl); if (ret < 0) goto out_free_memmap; @@ -346,21 +559,12 @@ int wl1271_hw_init(struct wl1271 *wl) if (ret < 0) goto out_free_memmap; - /* disable all keep-alive templates */ - for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { - ret = wl1271_acx_keep_alive_config(wl, i, - ACX_KEEP_ALIVE_TPL_INVALID); - if (ret < 0) - goto out_free_memmap; - } + /* Mode specific init - post mem init */ + if (is_ap) + ret = wl1271_ap_hw_init_post_mem(wl); + else + ret = wl1271_sta_hw_init_post_mem(wl); - /* disable the keep-alive feature */ - ret = wl1271_acx_keep_alive_mode(wl, false); - if (ret < 0) - goto out_free_memmap; - - /* Configure rssi/snr averaging weights */ - ret = wl1271_acx_rssi_snr_avg_weights(wl); if (ret < 0) goto out_free_memmap; diff --git a/drivers/net/wireless/wl12xx/init.h b/drivers/net/wireless/wl12xx/init.h index 7762421f8602..3a8bd3f426d2 100644 --- a/drivers/net/wireless/wl12xx/init.h +++ b/drivers/net/wireless/wl12xx/init.h @@ -27,7 +27,7 @@ #include "wl12xx.h" int wl1271_hw_init_power_auth(struct wl1271 *wl); -int wl1271_init_templates_config(struct wl1271 *wl); +int wl1271_sta_init_templates_config(struct wl1271 *wl); int wl1271_init_phy_config(struct wl1271 *wl); int wl1271_init_pta(struct wl1271 *wl); int wl1271_init_energy_detection(struct wl1271 *wl); diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 9785b4c43c86..67f6db4354f0 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -434,7 +434,7 @@ static int wl1271_plt_init(struct wl1271 *wl) if (ret < 0) return ret; - ret = wl1271_init_templates_config(wl); + ret = wl1271_sta_init_templates_config(wl); if (ret < 0) return ret; @@ -1363,24 +1363,6 @@ static void wl1271_set_band_rate(struct wl1271 *wl) wl->basic_rate_set = wl->conf.tx.basic_rate_5; } -static u32 wl1271_min_rate_get(struct wl1271 *wl) -{ - int i; - u32 rate = 0; - - if (!wl->basic_rate_set) { - WARN_ON(1); - wl->basic_rate_set = wl->conf.tx.basic_rate; - } - - for (i = 0; !rate; i++) { - if ((wl->basic_rate_set >> i) & 0x1) - rate = 1 << i; - } - - return rate; -} - static int wl1271_handle_idle(struct wl1271 *wl, bool idle) { int ret; @@ -1391,7 +1373,7 @@ static int wl1271_handle_idle(struct wl1271 *wl, bool idle) if (ret < 0) goto out; } - wl->rate_set = wl1271_min_rate_get(wl); + wl->rate_set = wl1271_tx_min_rate_get(wl); wl->sta_rate_set = 0; ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) @@ -1467,7 +1449,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) wl1271_set_band_rate(wl); - wl->basic_rate = wl1271_min_rate_get(wl); + wl->basic_rate = wl1271_tx_min_rate_get(wl); ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) wl1271_warning("rate policy for update channel " @@ -1927,7 +1909,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, beacon->data, beacon->len, 0, - wl1271_min_rate_get(wl)); + wl1271_tx_min_rate_get(wl)); if (ret < 0) { dev_kfree_skb(beacon); @@ -1943,7 +1925,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, CMD_TEMPL_PROBE_RESPONSE, beacon->data, beacon->len, 0, - wl1271_min_rate_get(wl)); + wl1271_tx_min_rate_get(wl)); dev_kfree_skb(beacon); if (ret < 0) goto out_sleep; @@ -2016,7 +1998,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, rates = bss_conf->basic_rates; wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates); - wl->basic_rate = wl1271_min_rate_get(wl); + wl->basic_rate = wl1271_tx_min_rate_get(wl); ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) goto out_sleep; @@ -2070,7 +2052,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, /* revert back to minimum rates for the current band */ wl1271_set_band_rate(wl); - wl->basic_rate = wl1271_min_rate_get(wl); + wl->basic_rate = wl1271_tx_min_rate_get(wl); ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) goto out_sleep; diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 442a7bd956ea..a93fc4702f35 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -521,3 +521,21 @@ void wl1271_tx_flush(struct wl1271 *wl) wl1271_warning("Unable to flush all TX buffers, timed out."); } + +u32 wl1271_tx_min_rate_get(struct wl1271 *wl) +{ + int i; + u32 rate = 0; + + if (!wl->basic_rate_set) { + WARN_ON(1); + wl->basic_rate_set = wl->conf.tx.basic_rate; + } + + for (i = 0; !rate; i++) { + if ((wl->basic_rate_set >> i) & 0x1) + rate = 1 << i; + } + + return rate; +} diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h index 903e5dc69b7a..5ccd22eaf074 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h @@ -146,5 +146,6 @@ void wl1271_tx_reset(struct wl1271 *wl); void wl1271_tx_flush(struct wl1271 *wl); u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set); +u32 wl1271_tx_min_rate_get(struct wl1271 *wl); #endif diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/wl12xx/wl12xx_80211.h index e2b26fbf68c1..67dcf8f28cd3 100644 --- a/drivers/net/wireless/wl12xx/wl12xx_80211.h +++ b/drivers/net/wireless/wl12xx/wl12xx_80211.h @@ -160,4 +160,9 @@ struct wl12xx_probe_resp_template { struct wl12xx_ie_country country; } __packed; +struct wl12xx_disconn_template { + struct ieee80211_header header; + __le16 disconn_reason; +} __packed; + #endif -- cgit v1.2.3 From ae113b57826b40f1962a6e2417efd757b638e6a9 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sat, 16 Oct 2010 18:45:07 +0200 Subject: wl12xx: AP specific RX filter configuration Set filters according to the mode of operation. Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/boot.c | 4 ++-- drivers/net/wireless/wl12xx/main.c | 7 +++---- drivers/net/wireless/wl12xx/rx.c | 11 +++++++++++ drivers/net/wireless/wl12xx/rx.h | 1 + drivers/net/wireless/wl12xx/wl12xx.h | 13 +++++++++++-- 5 files changed, 28 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index b504367f281f..2b1019f67d27 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c @@ -28,6 +28,7 @@ #include "boot.h" #include "io.h" #include "event.h" +#include "rx.h" static struct wl1271_partition_set part_table[PART_TABLE_LEN] = { [PART_DOWN] = { @@ -598,8 +599,7 @@ int wl1271_boot(struct wl1271 *wl) wl1271_boot_enable_interrupts(wl); /* set the wl1271 default filters */ - wl->rx_config = WL1271_DEFAULT_RX_CONFIG; - wl->rx_filter = WL1271_DEFAULT_RX_FILTER; + wl1271_set_default_filters(wl); wl1271_event_mbox_config(wl); diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 67f6db4354f0..d1075a5ac406 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1227,8 +1227,7 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters) { - wl->rx_config = WL1271_DEFAULT_RX_CONFIG; - wl->rx_filter = WL1271_DEFAULT_RX_FILTER; + wl1271_set_default_filters(wl); /* combine requested filters with current filter config */ filters = wl->filters | filters; @@ -2758,8 +2757,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void) wl->beacon_int = WL1271_DEFAULT_BEACON_INT; wl->default_key = 0; wl->rx_counter = 0; - wl->rx_config = WL1271_DEFAULT_RX_CONFIG; - wl->rx_filter = WL1271_DEFAULT_RX_FILTER; + wl->rx_config = WL1271_DEFAULT_STA_RX_CONFIG; + wl->rx_filter = WL1271_DEFAULT_STA_RX_FILTER; wl->psm_entry_retry = 0; wl->power_level = WL1271_DEFAULT_POWER_LEVEL; wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC; diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c index c6402529eac8..b0c6ddc2a945 100644 --- a/drivers/net/wireless/wl12xx/rx.c +++ b/drivers/net/wireless/wl12xx/rx.c @@ -200,3 +200,14 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status) } wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); } + +void wl1271_set_default_filters(struct wl1271 *wl) +{ + if (wl->bss_type == BSS_TYPE_AP_BSS) { + wl->rx_config = WL1271_DEFAULT_AP_RX_CONFIG; + wl->rx_filter = WL1271_DEFAULT_AP_RX_FILTER; + } else { + wl->rx_config = WL1271_DEFAULT_STA_RX_CONFIG; + wl->rx_filter = WL1271_DEFAULT_STA_RX_FILTER; + } +} diff --git a/drivers/net/wireless/wl12xx/rx.h b/drivers/net/wireless/wl12xx/rx.h index 3abb26fe0364..f695553f31e0 100644 --- a/drivers/net/wireless/wl12xx/rx.h +++ b/drivers/net/wireless/wl12xx/rx.h @@ -117,5 +117,6 @@ struct wl1271_rx_descriptor { void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status); u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); +void wl1271_set_default_filters(struct wl1271 *wl); #endif diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 340153f609c7..4bbdb89f1bcb 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -103,15 +103,24 @@ extern u32 wl12xx_debug_level; true); \ } while (0) -#define WL1271_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN | \ +#define WL1271_DEFAULT_STA_RX_CONFIG (CFG_UNI_FILTER_EN | \ CFG_BSSID_FILTER_EN | \ CFG_MC_FILTER_EN) -#define WL1271_DEFAULT_RX_FILTER (CFG_RX_RCTS_ACK | CFG_RX_PRSP_EN | \ +#define WL1271_DEFAULT_STA_RX_FILTER (CFG_RX_RCTS_ACK | CFG_RX_PRSP_EN | \ CFG_RX_MGMT_EN | CFG_RX_DATA_EN | \ CFG_RX_CTL_EN | CFG_RX_BCN_EN | \ CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN) +#define WL1271_DEFAULT_AP_RX_CONFIG 0 + +#define WL1271_DEFAULT_AP_RX_FILTER (CFG_RX_RCTS_ACK | CFG_RX_PREQ_EN | \ + CFG_RX_MGMT_EN | CFG_RX_DATA_EN | \ + CFG_RX_CTL_EN | CFG_RX_AUTH_EN | \ + CFG_RX_ASSOC_EN) + + + #define WL1271_FW_NAME "wl1271-fw.bin" #define WL1271_NVS_NAME "wl1271-nvs.bin" -- cgit v1.2.3 From beb6c880720073c233633c45792a4bb5d5fedbd5 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sat, 16 Oct 2010 18:53:48 +0200 Subject: wl12xx: Add AP related definitions to HOST-FW interface Change structures in a non-destructive manner. This means no changes in size or location of existing members used by STA. Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/event.h | 7 ++++++- drivers/net/wireless/wl12xx/rx.h | 10 +++++++--- drivers/net/wireless/wl12xx/tx.h | 9 +++++++-- drivers/net/wireless/wl12xx/wl12xx.h | 18 +++++++++++++++++- 4 files changed, 37 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h index fd955f31cec4..1d5ef670d480 100644 --- a/drivers/net/wireless/wl12xx/event.h +++ b/drivers/net/wireless/wl12xx/event.h @@ -116,7 +116,12 @@ struct event_mailbox { u8 scheduled_scan_status; u8 ps_status; - u8 reserved_5[29]; + /* AP FW only */ + u8 hlid_removed; + __le16 sta_aging_status; + __le16 sta_tx_retry_exceeded; + + u8 reserved_5[24]; } __packed; int wl1271_event_unmask(struct wl1271 *wl); diff --git a/drivers/net/wireless/wl12xx/rx.h b/drivers/net/wireless/wl12xx/rx.h index f695553f31e0..8d048b36bbba 100644 --- a/drivers/net/wireless/wl12xx/rx.h +++ b/drivers/net/wireless/wl12xx/rx.h @@ -86,8 +86,9 @@ /* * RX Descriptor status * - * Bits 0-2 - status - * Bits 3-7 - reserved + * Bits 0-2 - error code + * Bits 3-5 - process_id tag (AP mode FW) + * Bits 6-7 - reserved */ #define WL1271_RX_DESC_STATUS_MASK 0x07 @@ -110,7 +111,10 @@ struct wl1271_rx_descriptor { u8 snr; __le32 timestamp; u8 packet_class; - u8 process_id; + union { + u8 process_id; /* STA FW */ + u8 hlid; /* AP FW */ + } __packed; u8 pad_len; u8 reserved; } __packed; diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h index 5ccd22eaf074..05722a560d91 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h @@ -29,6 +29,7 @@ #define TX_HW_BLOCK_SIZE 252 #define TX_HW_MGMT_PKT_LIFETIME_TU 2000 +#define TX_HW_AP_MODE_PKT_LIFETIME_TU 8000 /* The chipset reference driver states, that the "aid" value 1 * is for infra-BSS, but is still always used */ #define TX_HW_DEFAULT_AID 1 @@ -77,8 +78,12 @@ struct wl1271_tx_hw_descr { u8 id; /* The packet TID value (as User-Priority) */ u8 tid; - /* Identifier of the remote STA in IBSS, 1 in infra-BSS */ - u8 aid; + union { + /* STA - Identifier of the remote STA in IBSS, 1 in infra-BSS */ + u8 aid; + /* AP - host link ID (HLID) */ + u8 hlid; + } __packed; u8 reserved; } __packed; diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 4bbdb89f1bcb..2f855443555c 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -195,6 +195,11 @@ struct wl1271_stats { #define NUM_TX_QUEUES 4 #define NUM_RX_PKT_DESC 8 +#define AP_MAX_STATIONS 5 + +/* Broadcast and Global links + links to stations */ +#define AP_MAX_LINKS (AP_MAX_STATIONS + 2) + /* FW status registers */ struct wl1271_fw_status { __le32 intr; @@ -205,7 +210,18 @@ struct wl1271_fw_status { __le32 rx_pkt_descs[NUM_RX_PKT_DESC]; __le32 tx_released_blks[NUM_TX_QUEUES]; __le32 fw_localtime; - __le32 padding[2]; + + /* Next fields valid only in AP FW */ + + /* + * A bitmap (where each bit represents a single HLID) + * to indicate if the station is in PS mode. + */ + __le32 link_ps_bitmap; + + /* Number of freed MBs per HLID */ + u8 tx_lnk_free_blks[AP_MAX_LINKS]; + u8 padding_1[1]; } __packed; struct wl1271_rx_mem_pool_addr { -- cgit v1.2.3 From e78a287ab7eb73d7003b1c54bec4ca94655f62e9 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sat, 16 Oct 2010 19:07:21 +0200 Subject: wl12xx: Configure AP on BSS info change Configure AP-specific beacon and probe response templates. Start the AP when beaconing is enabled. The wl1271_bss_info_changed() function has been split into AP/STA specific handlers. Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 340 ++++++++++++++++++++++++----------- drivers/net/wireless/wl12xx/wl12xx.h | 3 + 2 files changed, 234 insertions(+), 109 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index d1075a5ac406..0f16307137a2 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1843,7 +1843,7 @@ out: return ret; } -static void wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *skb, +static int wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *skb, int offset) { u8 *ptr = skb->data + offset; @@ -1853,89 +1853,206 @@ static void wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *skb, if (ptr[0] == WLAN_EID_SSID) { wl->ssid_len = ptr[1]; memcpy(wl->ssid, ptr+2, wl->ssid_len); - return; + return 0; } ptr += (ptr[1] + 2); } + wl1271_error("No SSID in IEs!\n"); + return -ENOENT; } -static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, +static int wl1271_bss_erp_info_changed(struct wl1271 *wl, struct ieee80211_bss_conf *bss_conf, u32 changed) { - enum wl1271_cmd_ps_mode mode; - struct wl1271 *wl = hw->priv; - struct ieee80211_sta *sta = ieee80211_find_sta(vif, bss_conf->bssid); - bool do_join = false; - bool set_assoc = false; - int ret; + int ret = 0; - wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed"); + if (changed & BSS_CHANGED_ERP_SLOT) { + if (bss_conf->use_short_slot) + ret = wl1271_acx_slot(wl, SLOT_TIME_SHORT); + else + ret = wl1271_acx_slot(wl, SLOT_TIME_LONG); + if (ret < 0) { + wl1271_warning("Set slot time failed %d", ret); + goto out; + } + } - mutex_lock(&wl->mutex); + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + if (bss_conf->use_short_preamble) + wl1271_acx_set_preamble(wl, ACX_PREAMBLE_SHORT); + else + wl1271_acx_set_preamble(wl, ACX_PREAMBLE_LONG); + } - if (unlikely(wl->state == WL1271_STATE_OFF)) - goto out; + if (changed & BSS_CHANGED_ERP_CTS_PROT) { + if (bss_conf->use_cts_prot) + ret = wl1271_acx_cts_protect(wl, CTSPROTECT_ENABLE); + else + ret = wl1271_acx_cts_protect(wl, CTSPROTECT_DISABLE); + if (ret < 0) { + wl1271_warning("Set ctsprotect failed %d", ret); + goto out; + } + } - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; +out: + return ret; +} - if ((changed & BSS_CHANGED_BEACON_INT) && - (wl->bss_type == BSS_TYPE_IBSS)) { - wl1271_debug(DEBUG_ADHOC, "ad-hoc beacon interval updated: %d", +static int wl1271_bss_beacon_info_changed(struct wl1271 *wl, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changed) +{ + bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); + int ret = 0; + + if ((changed & BSS_CHANGED_BEACON_INT)) { + wl1271_debug(DEBUG_MASTER, "beacon interval updated: %d", bss_conf->beacon_int); wl->beacon_int = bss_conf->beacon_int; - do_join = true; } - if ((changed & BSS_CHANGED_BEACON) && - (wl->bss_type == BSS_TYPE_IBSS)) { - struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); + if ((changed & BSS_CHANGED_BEACON)) { + struct ieee80211_hdr *hdr; + int ieoffset = offsetof(struct ieee80211_mgmt, + u.beacon.variable); + struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif); + u16 tmpl_id; + + if (!beacon) + goto out; + + wl1271_debug(DEBUG_MASTER, "beacon updated"); + + ret = wl1271_ssid_set(wl, beacon, ieoffset); + if (ret < 0) { + dev_kfree_skb(beacon); + goto out; + } + tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON : + CMD_TEMPL_BEACON; + ret = wl1271_cmd_template_set(wl, tmpl_id, + beacon->data, + beacon->len, 0, + wl1271_tx_min_rate_get(wl)); + if (ret < 0) { + dev_kfree_skb(beacon); + goto out; + } + + hdr = (struct ieee80211_hdr *) beacon->data; + hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | + IEEE80211_STYPE_PROBE_RESP); + + tmpl_id = is_ap ? CMD_TEMPL_AP_PROBE_RESPONSE : + CMD_TEMPL_PROBE_RESPONSE; + ret = wl1271_cmd_template_set(wl, + tmpl_id, + beacon->data, + beacon->len, 0, + wl1271_tx_min_rate_get(wl)); + dev_kfree_skb(beacon); + if (ret < 0) + goto out; + } + +out: + return ret; +} + +/* AP mode changes */ +static void wl1271_bss_info_changed_ap(struct wl1271 *wl, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changed) +{ + int ret = 0; - wl1271_debug(DEBUG_ADHOC, "ad-hoc beacon updated"); + if ((changed & BSS_CHANGED_BASIC_RATES)) { + u32 rates = bss_conf->basic_rates; + struct conf_tx_rate_class mgmt_rc; - if (beacon) { - struct ieee80211_hdr *hdr; - int ieoffset = offsetof(struct ieee80211_mgmt, - u.beacon.variable); + wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates); + wl->basic_rate = wl1271_tx_min_rate_get(wl); + wl1271_debug(DEBUG_AP, "basic rates: 0x%x", + wl->basic_rate_set); + + /* update the AP management rate policy with the new rates */ + mgmt_rc.enabled_rates = wl->basic_rate_set; + mgmt_rc.long_retry_limit = 10; + mgmt_rc.short_retry_limit = 10; + mgmt_rc.aflags = 0; + ret = wl1271_acx_ap_rate_policy(wl, &mgmt_rc, + ACX_TX_AP_MODE_MGMT_RATE); + if (ret < 0) { + wl1271_error("AP mgmt policy change failed %d", ret); + goto out; + } + } - wl1271_ssid_set(wl, beacon, ieoffset); + ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf, changed); + if (ret < 0) + goto out; - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, - beacon->data, - beacon->len, 0, - wl1271_tx_min_rate_get(wl)); + if ((changed & BSS_CHANGED_BEACON_ENABLED)) { + if (bss_conf->enable_beacon) { + if (!test_bit(WL1271_FLAG_AP_STARTED, &wl->flags)) { + ret = wl1271_cmd_start_bss(wl); + if (ret < 0) + goto out; - if (ret < 0) { - dev_kfree_skb(beacon); - goto out_sleep; + set_bit(WL1271_FLAG_AP_STARTED, &wl->flags); + wl1271_debug(DEBUG_AP, "started AP"); } + } else { + if (test_bit(WL1271_FLAG_AP_STARTED, &wl->flags)) { + ret = wl1271_cmd_stop_bss(wl); + if (ret < 0) + goto out; - hdr = (struct ieee80211_hdr *) beacon->data; - hdr->frame_control = cpu_to_le16( - IEEE80211_FTYPE_MGMT | - IEEE80211_STYPE_PROBE_RESP); + clear_bit(WL1271_FLAG_AP_STARTED, &wl->flags); + wl1271_debug(DEBUG_AP, "stopped AP"); + } + } + } - ret = wl1271_cmd_template_set(wl, - CMD_TEMPL_PROBE_RESPONSE, - beacon->data, - beacon->len, 0, - wl1271_tx_min_rate_get(wl)); - dev_kfree_skb(beacon); - if (ret < 0) - goto out_sleep; + ret = wl1271_bss_erp_info_changed(wl, bss_conf, changed); + if (ret < 0) + goto out; +out: + return; +} - /* Need to update the SSID (for filtering etc) */ - do_join = true; - } +/* STA/IBSS mode changes */ +static void wl1271_bss_info_changed_sta(struct wl1271 *wl, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changed) +{ + bool do_join = false, set_assoc = false; + bool is_ibss = (wl->bss_type == BSS_TYPE_IBSS); + int ret; + struct ieee80211_sta *sta = ieee80211_find_sta(vif, bss_conf->bssid); + + if (is_ibss) { + ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf, + changed); + if (ret < 0) + goto out; } - if ((changed & BSS_CHANGED_BEACON_ENABLED) && - (wl->bss_type == BSS_TYPE_IBSS)) { + if ((changed & BSS_CHANGED_BEACON_INT) && is_ibss) + do_join = true; + + /* Need to update the SSID (for filtering etc) */ + if ((changed & BSS_CHANGED_BEACON) && is_ibss) + do_join = true; + + if ((changed & BSS_CHANGED_BEACON_ENABLED) && is_ibss) { wl1271_debug(DEBUG_ADHOC, "ad-hoc beaconing: %s", bss_conf->enable_beacon ? "enabled" : "disabled"); @@ -1946,7 +2063,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, do_join = true; } - if (changed & BSS_CHANGED_CQM) { + if ((changed & BSS_CHANGED_CQM)) { bool enable = false; if (bss_conf->cqm_rssi_thold) enable = true; @@ -1964,24 +2081,24 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, * and enable the BSSID filter */ memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) { - memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); + memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); - ret = wl1271_cmd_build_null_data(wl); - if (ret < 0) - goto out_sleep; + ret = wl1271_cmd_build_null_data(wl); + if (ret < 0) + goto out; - ret = wl1271_build_qos_null_data(wl); - if (ret < 0) - goto out_sleep; + ret = wl1271_build_qos_null_data(wl); + if (ret < 0) + goto out; - /* filter out all packets not from this BSSID */ - wl1271_configure_filters(wl, 0); + /* filter out all packets not from this BSSID */ + wl1271_configure_filters(wl, 0); - /* Need to update the BSSID (for filtering etc) */ - do_join = true; + /* Need to update the BSSID (for filtering etc) */ + do_join = true; } - if (changed & BSS_CHANGED_ASSOC) { + if ((changed & BSS_CHANGED_ASSOC)) { if (bss_conf->assoc) { u32 rates; int ieoffset; @@ -2000,7 +2117,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, wl->basic_rate = wl1271_tx_min_rate_get(wl); ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) - goto out_sleep; + goto out; /* * with wl1271, we don't need to update the @@ -2010,7 +2127,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, */ ret = wl1271_cmd_build_ps_poll(wl, wl->aid); if (ret < 0) - goto out_sleep; + goto out; /* * Get a template for hardware connection maintenance @@ -2024,17 +2141,19 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, /* enable the connection monitoring feature */ ret = wl1271_acx_conn_monit_params(wl, true); if (ret < 0) - goto out_sleep; + goto out; /* If we want to go in PSM but we're not there yet */ if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) && !test_bit(WL1271_FLAG_PSM, &wl->flags)) { + enum wl1271_cmd_ps_mode mode; + mode = STATION_POWER_SAVE_MODE; ret = wl1271_ps_set_mode(wl, mode, wl->basic_rate, true); if (ret < 0) - goto out_sleep; + goto out; } } else { /* use defaults when not associated */ @@ -2054,7 +2173,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, wl->basic_rate = wl1271_tx_min_rate_get(wl); ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) - goto out_sleep; + goto out; /* disable connection monitor features */ ret = wl1271_acx_conn_monit_params(wl, false); @@ -2062,43 +2181,17 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, /* Disable the keep-alive feature */ ret = wl1271_acx_keep_alive_mode(wl, false); if (ret < 0) - goto out_sleep; + goto out; /* restore the bssid filter and go to dummy bssid */ wl1271_unjoin(wl); wl1271_dummy_join(wl); } - - } - - if (changed & BSS_CHANGED_ERP_SLOT) { - if (bss_conf->use_short_slot) - ret = wl1271_acx_slot(wl, SLOT_TIME_SHORT); - else - ret = wl1271_acx_slot(wl, SLOT_TIME_LONG); - if (ret < 0) { - wl1271_warning("Set slot time failed %d", ret); - goto out_sleep; - } - } - - if (changed & BSS_CHANGED_ERP_PREAMBLE) { - if (bss_conf->use_short_preamble) - wl1271_acx_set_preamble(wl, ACX_PREAMBLE_SHORT); - else - wl1271_acx_set_preamble(wl, ACX_PREAMBLE_LONG); } - if (changed & BSS_CHANGED_ERP_CTS_PROT) { - if (bss_conf->use_cts_prot) - ret = wl1271_acx_cts_protect(wl, CTSPROTECT_ENABLE); - else - ret = wl1271_acx_cts_protect(wl, CTSPROTECT_DISABLE); - if (ret < 0) { - wl1271_warning("Set ctsprotect failed %d", ret); - goto out_sleep; - } - } + ret = wl1271_bss_erp_info_changed(wl, bss_conf, changed); + if (ret < 0) + goto out; /* * Takes care of: New association with HT enable, @@ -2110,13 +2203,13 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true); if (ret < 0) { wl1271_warning("Set ht cap true failed %d", ret); - goto out_sleep; + goto out; } ret = wl1271_acx_set_ht_information(wl, bss_conf->ht_operation_mode); if (ret < 0) { wl1271_warning("Set ht information failed %d", ret); - goto out_sleep; + goto out; } } /* @@ -2127,7 +2220,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, false); if (ret < 0) { wl1271_warning("Set ht cap false failed %d", ret); - goto out_sleep; + goto out; } } @@ -2146,7 +2239,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, ret = wl1271_cmd_build_arp_rsp(wl, addr); if (ret < 0) { wl1271_warning("build arp rsp failed: %d", ret); - goto out_sleep; + goto out; } ret = wl1271_acx_arp_ip_filter(wl, @@ -2157,18 +2250,47 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, ret = wl1271_acx_arp_ip_filter(wl, 0, addr); if (ret < 0) - goto out_sleep; + goto out; } if (do_join) { ret = wl1271_join(wl, set_assoc); if (ret < 0) { wl1271_warning("cmd join failed %d", ret); - goto out_sleep; + goto out; } } -out_sleep: +out: + return; +} + +static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changed) +{ + struct wl1271 *wl = hw->priv; + bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); + int ret; + + wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed 0x%x", + (int)changed); + + mutex_lock(&wl->mutex); + + if (unlikely(wl->state == WL1271_STATE_OFF)) + goto out; + + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + + if (is_ap) + wl1271_bss_info_changed_ap(wl, vif, bss_conf, changed); + else + wl1271_bss_info_changed_sta(wl, vif, bss_conf, changed); + wl1271_ps_elp_sleep(wl); out: diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 2f855443555c..981bb020e535 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -57,6 +57,8 @@ enum { DEBUG_SDIO = BIT(14), DEBUG_FILTERS = BIT(15), DEBUG_ADHOC = BIT(16), + DEBUG_AP = BIT(17), + DEBUG_MASTER = (DEBUG_ADHOC | DEBUG_AP), DEBUG_ALL = ~0, }; @@ -284,6 +286,7 @@ struct wl1271 { #define WL1271_FLAG_PSPOLL_FAILURE (12) #define WL1271_FLAG_STA_STATE_SENT (13) #define WL1271_FLAG_FW_TX_BUSY (14) +#define WL1271_FLAG_AP_STARTED (15) unsigned long flags; struct wl1271_partition_set part; -- cgit v1.2.3 From bee0ffec7766eae8c574cc1b07b739b05ba295c3 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sat, 16 Oct 2010 19:17:02 +0200 Subject: wl12xx: AP mode config in ieee80211_ops.config Separate configuration according to mode. AP has different rate set configuration and no handling of idle-state. Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 52 ++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 0f16307137a2..01f3f0264fb4 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1362,7 +1362,7 @@ static void wl1271_set_band_rate(struct wl1271 *wl) wl->basic_rate_set = wl->conf.tx.basic_rate_5; } -static int wl1271_handle_idle(struct wl1271 *wl, bool idle) +static int wl1271_sta_handle_idle(struct wl1271 *wl, bool idle) { int ret; @@ -1403,14 +1403,17 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) struct wl1271 *wl = hw->priv; struct ieee80211_conf *conf = &hw->conf; int channel, ret = 0; + bool is_ap; channel = ieee80211_frequency_to_channel(conf->channel->center_freq); - wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d %s", + wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d %s" + " changed 0x%x", channel, conf->flags & IEEE80211_CONF_PS ? "on" : "off", conf->power_level, - conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use"); + conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use", + changed); /* * mac80211 will go to idle nearly immediately after transmitting some @@ -1428,6 +1431,8 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) goto out; } + is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); + ret = wl1271_ps_elp_wakeup(wl, false); if (ret < 0) goto out; @@ -1439,31 +1444,34 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) wl->band = conf->channel->band; wl->channel = channel; - /* - * FIXME: the mac80211 should really provide a fixed rate - * to use here. for now, just use the smallest possible rate - * for the band as a fixed rate for association frames and - * other control messages. - */ - if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) - wl1271_set_band_rate(wl); - - wl->basic_rate = wl1271_tx_min_rate_get(wl); - ret = wl1271_acx_sta_rate_policies(wl); - if (ret < 0) - wl1271_warning("rate policy for update channel " - "failed %d", ret); + if (!is_ap) { + /* + * FIXME: the mac80211 should really provide a fixed + * rate to use here. for now, just use the smallest + * possible rate for the band as a fixed rate for + * association frames and other control messages. + */ + if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) + wl1271_set_band_rate(wl); - if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) { - ret = wl1271_join(wl, false); + wl->basic_rate = wl1271_tx_min_rate_get(wl); + ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) - wl1271_warning("cmd join to update channel " + wl1271_warning("rate policy for channel " "failed %d", ret); + + if (test_bit(WL1271_FLAG_JOINED, &wl->flags)) { + ret = wl1271_join(wl, false); + if (ret < 0) + wl1271_warning("cmd join on channel " + "failed %d", ret); + } } } - if (changed & IEEE80211_CONF_CHANGE_IDLE) { - ret = wl1271_handle_idle(wl, conf->flags & IEEE80211_CONF_IDLE); + if (changed & IEEE80211_CONF_CHANGE_IDLE && !is_ap) { + ret = wl1271_sta_handle_idle(wl, + conf->flags & IEEE80211_CONF_IDLE); if (ret < 0) wl1271_warning("idle mode change failed %d", ret); } -- cgit v1.2.3 From 7d0578693107887d52d50b89723be7fa0a41cd36 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sat, 16 Oct 2010 19:25:35 +0200 Subject: wl12xx: AP mode - change filter config Do not configure a group address table in AP mode Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 01f3f0264fb4..8e5d435f63f7 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1578,7 +1578,8 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw, struct wl1271 *wl = hw->priv; int ret; - wl1271_debug(DEBUG_MAC80211, "mac80211 configure filter"); + wl1271_debug(DEBUG_MAC80211, "mac80211 configure filter changed %x" + " total %x", changed, *total); mutex_lock(&wl->mutex); @@ -1592,15 +1593,16 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw, if (ret < 0) goto out; - - if (*total & FIF_ALLMULTI) - ret = wl1271_acx_group_address_tbl(wl, false, NULL, 0); - else if (fp) - ret = wl1271_acx_group_address_tbl(wl, fp->enabled, - fp->mc_list, - fp->mc_list_length); - if (ret < 0) - goto out_sleep; + if (wl->bss_type != BSS_TYPE_AP_BSS) { + if (*total & FIF_ALLMULTI) + ret = wl1271_acx_group_address_tbl(wl, false, NULL, 0); + else if (fp) + ret = wl1271_acx_group_address_tbl(wl, fp->enabled, + fp->mc_list, + fp->mc_list_length); + if (ret < 0) + goto out_sleep; + } /* determine, whether supported filter values have changed */ if (changed == 0) -- cgit v1.2.3 From f84f7d78bbfbbb17faa64bcca5799865074e1e7b Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sat, 16 Oct 2010 20:21:23 +0200 Subject: wl12xx: AP mode - add STA add/remove ops Allocate and free host link IDs (HLIDs) for each link. A per-STA data structure keeps the HLID of each STA. Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 112 +++++++++++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/wl12xx.h | 7 +++ 2 files changed, 119 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 8e5d435f63f7..739fee640528 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1192,6 +1192,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl) wl->flags = 0; wl->vif = NULL; wl->filters = 0; + memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map)); for (i = 0; i < NUM_TX_QUEUES; i++) wl->tx_blocks_freed[i] = 0; @@ -2401,6 +2402,113 @@ static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx, return 0; } +static int wl1271_allocate_hlid(struct wl1271 *wl, + struct ieee80211_sta *sta, + u8 *hlid) +{ + struct wl1271_station *wl_sta; + int id; + + id = find_first_zero_bit(wl->ap_hlid_map, AP_MAX_STATIONS); + if (id >= AP_MAX_STATIONS) { + wl1271_warning("could not allocate HLID - too much stations"); + return -EBUSY; + } + + wl_sta = (struct wl1271_station *)sta->drv_priv; + + __set_bit(id, wl->ap_hlid_map); + wl_sta->hlid = WL1271_AP_STA_HLID_START + id; + *hlid = wl_sta->hlid; + return 0; +} + +static void wl1271_free_hlid(struct wl1271 *wl, u8 hlid) +{ + int id = hlid - WL1271_AP_STA_HLID_START; + + __clear_bit(id, wl->ap_hlid_map); +} + +static int wl1271_op_sta_add(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct wl1271 *wl = hw->priv; + int ret = 0; + u8 hlid; + + mutex_lock(&wl->mutex); + + if (unlikely(wl->state == WL1271_STATE_OFF)) + goto out; + + if (wl->bss_type != BSS_TYPE_AP_BSS) + goto out; + + wl1271_debug(DEBUG_MAC80211, "mac80211 add sta %d", (int)sta->aid); + + ret = wl1271_allocate_hlid(wl, sta, &hlid); + if (ret < 0) + goto out; + + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + + ret = wl1271_cmd_add_sta(wl, sta, hlid); + if (ret < 0) + goto out_sleep; + +out_sleep: + wl1271_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + return ret; +} + +static int wl1271_op_sta_remove(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct wl1271 *wl = hw->priv; + struct wl1271_station *wl_sta; + int ret = 0, id; + + mutex_lock(&wl->mutex); + + if (unlikely(wl->state == WL1271_STATE_OFF)) + goto out; + + if (wl->bss_type != BSS_TYPE_AP_BSS) + goto out; + + wl1271_debug(DEBUG_MAC80211, "mac80211 remove sta %d", (int)sta->aid); + + wl_sta = (struct wl1271_station *)sta->drv_priv; + id = wl_sta->hlid - WL1271_AP_STA_HLID_START; + if (WARN_ON(!test_bit(id, wl->ap_hlid_map))) + goto out; + + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + + ret = wl1271_cmd_remove_sta(wl, wl_sta->hlid); + if (ret < 0) + goto out_sleep; + + wl1271_free_hlid(wl, wl_sta->hlid); + +out_sleep: + wl1271_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + return ret; +} + /* can't be const, mac80211 writes to this */ static struct ieee80211_rate wl1271_rates[] = { { .bitrate = 10, @@ -2647,6 +2755,8 @@ static const struct ieee80211_ops wl1271_ops = { .conf_tx = wl1271_op_conf_tx, .get_tsf = wl1271_op_get_tsf, .get_survey = wl1271_op_get_survey, + .sta_add = wl1271_op_sta_add, + .sta_remove = wl1271_op_sta_remove, CFG80211_TESTMODE_CMD(wl1271_tm_cmd) }; @@ -2840,6 +2950,8 @@ int wl1271_init_ieee80211(struct wl1271 *wl) SET_IEEE80211_DEV(wl->hw, wl1271_wl_to_dev(wl)); + wl->hw->sta_data_size = sizeof(struct wl1271_station); + return 0; } EXPORT_SYMBOL_GPL(wl1271_init_ieee80211); diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 981bb020e535..a87ef8e3cac7 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -435,6 +435,13 @@ struct wl1271 { /* Most recently reported noise in dBm */ s8 noise; + + /* map for HLIDs of associated stations - when operating in AP mode */ + unsigned long ap_hlid_map[BITS_TO_LONGS(AP_MAX_STATIONS)]; +}; + +struct wl1271_station { + u8 hlid; }; int wl1271_plt_start(struct wl1271 *wl); -- cgit v1.2.3 From c6c8a65de6d3aa8daa93beeac390f49a21d0be36 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sat, 16 Oct 2010 20:27:53 +0200 Subject: wl12xx: AP mode - changes in TX path When in AP mode set appropriate HLID and rate policy for each skb. Respond to supported-rates related changes in op_tx only when acting as STA. Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 3 ++- drivers/net/wireless/wl12xx/tx.c | 55 +++++++++++++++++++++++++++++++------- 2 files changed, 48 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 739fee640528..ed5e2fc21ea2 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -943,7 +943,8 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) spin_lock_irqsave(&wl->wl_lock, flags); if (sta && (sta->supp_rates[conf->channel->band] != - (wl->sta_rate_set & HW_BG_RATES_MASK))) { + (wl->sta_rate_set & HW_BG_RATES_MASK)) && + wl->bss_type != BSS_TYPE_AP_BSS) { wl->sta_rate_set = sta->supp_rates[conf->channel->band]; set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags); } diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index a93fc4702f35..3245c240cbdd 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -23,6 +23,7 @@ #include #include +#include #include "wl12xx.h" #include "io.h" @@ -99,7 +100,7 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, { struct timespec ts; struct wl1271_tx_hw_descr *desc; - int pad, ac; + int pad, ac, rate_idx; s64 hosttime; u16 tx_attr; @@ -117,7 +118,11 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, getnstimeofday(&ts); hosttime = (timespec_to_ns(&ts) >> 10); desc->start_time = cpu_to_le32(hosttime - wl->time_offset); - desc->life_time = cpu_to_le16(TX_HW_MGMT_PKT_LIFETIME_TU); + + if (wl->bss_type != BSS_TYPE_AP_BSS) + desc->life_time = cpu_to_le16(TX_HW_MGMT_PKT_LIFETIME_TU); + else + desc->life_time = cpu_to_le16(TX_HW_AP_MODE_PKT_LIFETIME_TU); /* configure the tx attributes */ tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER; @@ -125,7 +130,41 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, /* queue (we use same identifiers for tid's and ac's */ ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); desc->tid = ac; - desc->aid = TX_HW_DEFAULT_AID; + + if (wl->bss_type != BSS_TYPE_AP_BSS) { + desc->aid = TX_HW_DEFAULT_AID; + + /* if the packets are destined for AP (have a STA entry) + send them with AP rate policies, otherwise use default + basic rates */ + if (control->control.sta) + rate_idx = ACX_TX_AP_FULL_RATE; + else + rate_idx = ACX_TX_BASIC_RATE; + } else { + if (control->control.sta) { + struct wl1271_station *wl_sta; + + wl_sta = (struct wl1271_station *) + control->control.sta->drv_priv; + desc->hlid = wl_sta->hlid; + rate_idx = ac; + } else { + struct ieee80211_hdr *hdr; + + hdr = (struct ieee80211_hdr *) + (skb->data + sizeof(*desc)); + if (ieee80211_is_mgmt(hdr->frame_control)) { + desc->hlid = WL1271_AP_GLOBAL_HLID; + rate_idx = ACX_TX_AP_MODE_MGMT_RATE; + } else { + desc->hlid = WL1271_AP_BROADCAST_HLID; + rate_idx = ACX_TX_AP_MODE_BCST_RATE; + } + } + } + + tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY; desc->reserved = 0; /* align the length (and store in terms of words) */ @@ -136,14 +175,12 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, pad = pad - skb->len; tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD; - /* if the packets are destined for AP (have a STA entry) send them - with AP rate policies, otherwise use default basic rates */ - if (control->control.sta) - tx_attr |= ACX_TX_AP_FULL_RATE << TX_HW_ATTR_OFST_RATE_POLICY; - desc->tx_attr = cpu_to_le16(tx_attr); - wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d", pad); + wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d hlid: %d " + "tx_attr: 0x%x len: %d life: %d mem: %d", pad, (int)desc->hlid, + (int)desc->tx_attr, (int)desc->length, (int)desc->life_time, + (int)desc->total_mem_blocks); } /* caller must hold wl->mutex */ -- cgit v1.2.3 From 488fc540472dee7b8c9fc592e4f024aafe8b605f Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sat, 16 Oct 2010 20:33:45 +0200 Subject: wl12xx: AP mode - record TX configuration settings Record TX configuration settings in the "conf" member of our global structure (struct wl1271) if conf_tx is called when the firmware is not loaded. Later on when the firmware is loaded, we apply the tx conf as part of the init sequence. Important for AP mode since conf_tx is called before add_interface (where the firmware is initialized). Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 72 +++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index ed5e2fc21ea2..8b897e337fbb 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2314,42 +2314,66 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue, { struct wl1271 *wl = hw->priv; u8 ps_scheme; - int ret; + int ret = 0; mutex_lock(&wl->mutex); wl1271_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue); - if (unlikely(wl->state == WL1271_STATE_OFF)) { - ret = -EAGAIN; - goto out; - } - - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - - /* the txop is confed in units of 32us by the mac80211, we need us */ - ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue), - params->cw_min, params->cw_max, - params->aifs, params->txop << 5); - if (ret < 0) - goto out_sleep; - if (params->uapsd) ps_scheme = CONF_PS_SCHEME_UPSD_TRIGGER; else ps_scheme = CONF_PS_SCHEME_LEGACY; - ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue), - CONF_CHANNEL_TYPE_EDCF, - wl1271_tx_get_queue(queue), - ps_scheme, CONF_ACK_POLICY_LEGACY, 0, 0); - if (ret < 0) - goto out_sleep; + if (wl->state == WL1271_STATE_OFF) { + /* + * If the state is off, the parameters will be recorded and + * configured on init. This happens in AP-mode. + */ + struct conf_tx_ac_category *conf_ac = + &wl->conf.tx.ac_conf[wl1271_tx_get_queue(queue)]; + struct conf_tx_tid *conf_tid = + &wl->conf.tx.tid_conf[wl1271_tx_get_queue(queue)]; + + conf_ac->ac = wl1271_tx_get_queue(queue); + conf_ac->cw_min = (u8)params->cw_min; + conf_ac->cw_max = params->cw_max; + conf_ac->aifsn = params->aifs; + conf_ac->tx_op_limit = params->txop << 5; + + conf_tid->queue_id = wl1271_tx_get_queue(queue); + conf_tid->channel_type = CONF_CHANNEL_TYPE_EDCF; + conf_tid->tsid = wl1271_tx_get_queue(queue); + conf_tid->ps_scheme = ps_scheme; + conf_tid->ack_policy = CONF_ACK_POLICY_LEGACY; + conf_tid->apsd_conf[0] = 0; + conf_tid->apsd_conf[1] = 0; + } else { + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + + /* + * the txop is confed in units of 32us by the mac80211, + * we need us + */ + ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue), + params->cw_min, params->cw_max, + params->aifs, params->txop << 5); + if (ret < 0) + goto out_sleep; + + ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue), + CONF_CHANNEL_TYPE_EDCF, + wl1271_tx_get_queue(queue), + ps_scheme, CONF_ACK_POLICY_LEGACY, + 0, 0); + if (ret < 0) + goto out_sleep; out_sleep: - wl1271_ps_elp_sleep(wl); + wl1271_ps_elp_sleep(wl); + } out: mutex_unlock(&wl->mutex); -- cgit v1.2.3 From 7f179b468963564aa3faa5729fb3153c08b3d7c1 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sat, 16 Oct 2010 21:39:06 +0200 Subject: wl12xx: AP mode - encryption support Encryption key configuration is different for AP/STA modes. AP encryption keys are recorded when the BSS is not started. On BSS start they are propagated to the AP (in wl1271_ap_init_hwenc). Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/cmd.h | 1 - drivers/net/wireless/wl12xx/main.c | 220 +++++++++++++++++++++++++++++------ drivers/net/wireless/wl12xx/tx.c | 30 ++++- drivers/net/wireless/wl12xx/wl12xx.h | 16 +++ 4 files changed, 223 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h index c9909e09cd9d..751281414006 100644 --- a/drivers/net/wireless/wl12xx/cmd.h +++ b/drivers/net/wireless/wl12xx/cmd.h @@ -291,7 +291,6 @@ struct wl1271_cmd_ps_params { /* HW encryption keys */ #define NUM_ACCESS_CATEGORIES_COPY 4 -#define MAX_KEY_SIZE 32 enum wl1271_cmd_key_action { KEY_ADD_OR_REPLACE = 1, diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 8b897e337fbb..4ca46b2d7f34 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -296,6 +296,7 @@ static struct conf_drv_settings default_conf = { }; static void __wl1271_op_remove_interface(struct wl1271 *wl); +static void wl1271_free_ap_keys(struct wl1271 *wl); static void wl1271_device_release(struct device *dev) @@ -1193,6 +1194,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl) wl->flags = 0; wl->vif = NULL; wl->filters = 0; + wl1271_free_ap_keys(wl); memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map)); for (i = 0; i < NUM_TX_QUEUES; i++) @@ -1627,38 +1629,192 @@ out: kfree(fp); } +static int wl1271_record_ap_key(struct wl1271 *wl, u8 id, u8 key_type, + u8 key_size, const u8 *key, u8 hlid, u32 tx_seq_32, + u16 tx_seq_16) +{ + struct wl1271_ap_key *ap_key; + int i; + + wl1271_debug(DEBUG_CRYPT, "record ap key id %d", (int)id); + + if (key_size > MAX_KEY_SIZE) + return -EINVAL; + + /* + * Find next free entry in ap_keys. Also check we are not replacing + * an existing key. + */ + for (i = 0; i < MAX_NUM_KEYS; i++) { + if (wl->recorded_ap_keys[i] == NULL) + break; + + if (wl->recorded_ap_keys[i]->id == id) { + wl1271_warning("trying to record key replacement"); + return -EINVAL; + } + } + + if (i == MAX_NUM_KEYS) + return -EBUSY; + + ap_key = kzalloc(sizeof(*ap_key), GFP_KERNEL); + if (!ap_key) + return -ENOMEM; + + ap_key->id = id; + ap_key->key_type = key_type; + ap_key->key_size = key_size; + memcpy(ap_key->key, key, key_size); + ap_key->hlid = hlid; + ap_key->tx_seq_32 = tx_seq_32; + ap_key->tx_seq_16 = tx_seq_16; + + wl->recorded_ap_keys[i] = ap_key; + return 0; +} + +static void wl1271_free_ap_keys(struct wl1271 *wl) +{ + int i; + + for (i = 0; i < MAX_NUM_KEYS; i++) { + kfree(wl->recorded_ap_keys[i]); + wl->recorded_ap_keys[i] = NULL; + } +} + +static int wl1271_ap_init_hwenc(struct wl1271 *wl) +{ + int i, ret = 0; + struct wl1271_ap_key *key; + bool wep_key_added = false; + + for (i = 0; i < MAX_NUM_KEYS; i++) { + if (wl->recorded_ap_keys[i] == NULL) + break; + + key = wl->recorded_ap_keys[i]; + ret = wl1271_cmd_set_ap_key(wl, KEY_ADD_OR_REPLACE, + key->id, key->key_type, + key->key_size, key->key, + key->hlid, key->tx_seq_32, + key->tx_seq_16); + if (ret < 0) + goto out; + + if (key->key_type == KEY_WEP) + wep_key_added = true; + } + + if (wep_key_added) { + ret = wl1271_cmd_set_ap_default_wep_key(wl, wl->default_key); + if (ret < 0) + goto out; + } + +out: + wl1271_free_ap_keys(wl); + return ret; +} + +static int wl1271_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, + u8 key_size, const u8 *key, u32 tx_seq_32, + u16 tx_seq_16, struct ieee80211_sta *sta) +{ + int ret; + bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); + + if (is_ap) { + struct wl1271_station *wl_sta; + u8 hlid; + + if (sta) { + wl_sta = (struct wl1271_station *)sta->drv_priv; + hlid = wl_sta->hlid; + } else { + hlid = WL1271_AP_BROADCAST_HLID; + } + + if (!test_bit(WL1271_FLAG_AP_STARTED, &wl->flags)) { + /* + * We do not support removing keys after AP shutdown. + * Pretend we do to make mac80211 happy. + */ + if (action != KEY_ADD_OR_REPLACE) + return 0; + + ret = wl1271_record_ap_key(wl, id, + key_type, key_size, + key, hlid, tx_seq_32, + tx_seq_16); + } else { + ret = wl1271_cmd_set_ap_key(wl, action, + id, key_type, key_size, + key, hlid, tx_seq_32, + tx_seq_16); + } + + if (ret < 0) + return ret; + } else { + const u8 *addr; + static const u8 bcast_addr[ETH_ALEN] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + addr = sta ? sta->addr : bcast_addr; + + if (is_zero_ether_addr(addr)) { + /* We dont support TX only encryption */ + return -EOPNOTSUPP; + } + + /* The wl1271 does not allow to remove unicast keys - they + will be cleared automatically on next CMD_JOIN. Ignore the + request silently, as we dont want the mac80211 to emit + an error message. */ + if (action == KEY_REMOVE && !is_broadcast_ether_addr(addr)) + return 0; + + ret = wl1271_cmd_set_sta_key(wl, action, + id, key_type, key_size, + key, addr, tx_seq_32, + tx_seq_16); + if (ret < 0) + return ret; + + /* the default WEP key needs to be configured at least once */ + if (key_type == KEY_WEP) { + ret = wl1271_cmd_set_sta_default_wep_key(wl, + wl->default_key); + if (ret < 0) + return ret; + } + } + + return 0; +} + static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ieee80211_key_conf *key_conf) { struct wl1271 *wl = hw->priv; - const u8 *addr; int ret; u32 tx_seq_32 = 0; u16 tx_seq_16 = 0; u8 key_type; - static const u8 bcast_addr[ETH_ALEN] = - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - wl1271_debug(DEBUG_MAC80211, "mac80211 set key"); - addr = sta ? sta->addr : bcast_addr; - - wl1271_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd); - wl1271_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN); + wl1271_debug(DEBUG_CRYPT, "CMD: 0x%x sta: %p", cmd, sta); wl1271_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x", key_conf->cipher, key_conf->keyidx, key_conf->keylen, key_conf->flags); wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen); - if (is_zero_ether_addr(addr)) { - /* We dont support TX only encryption */ - ret = -EOPNOTSUPP; - goto out; - } - mutex_lock(&wl->mutex); if (unlikely(wl->state == WL1271_STATE_OFF)) { @@ -1705,36 +1861,21 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, switch (cmd) { case SET_KEY: - ret = wl1271_cmd_set_sta_key(wl, KEY_ADD_OR_REPLACE, - key_conf->keyidx, key_type, - key_conf->keylen, key_conf->key, - addr, tx_seq_32, tx_seq_16); + ret = wl1271_set_key(wl, KEY_ADD_OR_REPLACE, + key_conf->keyidx, key_type, + key_conf->keylen, key_conf->key, + tx_seq_32, tx_seq_16, sta); if (ret < 0) { wl1271_error("Could not add or replace key"); goto out_sleep; } - - /* the default WEP key needs to be configured at least once */ - if (key_type == KEY_WEP) { - ret = wl1271_cmd_set_sta_default_wep_key(wl, - wl->default_key); - if (ret < 0) - goto out_sleep; - } break; case DISABLE_KEY: - /* The wl1271 does not allow to remove unicast keys - they - will be cleared automatically on next CMD_JOIN. Ignore the - request silently, as we dont want the mac80211 to emit - an error message. */ - if (!is_broadcast_ether_addr(addr)) - break; - - ret = wl1271_cmd_set_sta_key(wl, KEY_REMOVE, - key_conf->keyidx, key_type, - key_conf->keylen, key_conf->key, - addr, 0, 0); + ret = wl1271_set_key(wl, KEY_REMOVE, + key_conf->keyidx, key_type, + key_conf->keylen, key_conf->key, + 0, 0, sta); if (ret < 0) { wl1271_error("Could not remove key"); goto out_sleep; @@ -1753,7 +1894,6 @@ out_sleep: out_unlock: mutex_unlock(&wl->mutex); -out: return ret; } @@ -2019,6 +2159,10 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl, set_bit(WL1271_FLAG_AP_STARTED, &wl->flags); wl1271_debug(DEBUG_AP, "started AP"); + + ret = wl1271_ap_init_hwenc(wl); + if (ret < 0) + goto out; } } else { if (test_bit(WL1271_FLAG_AP_STARTED, &wl->flags)) { diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 3245c240cbdd..2347f2552f14 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -31,6 +31,23 @@ #include "ps.h" #include "tx.h" +static int wl1271_set_default_wep_key(struct wl1271 *wl, u8 id) +{ + int ret; + bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); + + if (is_ap) + ret = wl1271_cmd_set_ap_default_wep_key(wl, id); + else + ret = wl1271_cmd_set_sta_default_wep_key(wl, id); + + if (ret < 0) + return ret; + + wl1271_debug(DEBUG_CRYPT, "default wep key idx: %d", (int)id); + return 0; +} + static int wl1271_alloc_tx_id(struct wl1271 *wl, struct sk_buff *skb) { int id; @@ -190,7 +207,6 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, struct ieee80211_tx_info *info; u32 extra = 0; int ret = 0; - u8 idx; u32 total_len; if (!skb) @@ -203,11 +219,15 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, extra = WL1271_TKIP_IV_SPACE; if (info->control.hw_key) { - idx = info->control.hw_key->hw_key_idx; + bool is_wep; + u8 idx = info->control.hw_key->hw_key_idx; + u32 cipher = info->control.hw_key->cipher; + + is_wep = (cipher == WLAN_CIPHER_SUITE_WEP40) || + (cipher == WLAN_CIPHER_SUITE_WEP104); - /* FIXME: do we have to do this if we're not using WEP? */ - if (unlikely(wl->default_key != idx)) { - ret = wl1271_cmd_set_sta_default_wep_key(wl, idx); + if (unlikely(is_wep && wl->default_key != idx)) { + ret = wl1271_set_default_wep_key(wl, idx); if (ret < 0) return ret; wl->default_key = idx; diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index a87ef8e3cac7..6b2c763e4908 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -253,6 +253,19 @@ struct wl1271_if_operations { void (*disable_irq)(struct wl1271 *wl); }; +#define MAX_NUM_KEYS 14 +#define MAX_KEY_SIZE 32 + +struct wl1271_ap_key { + u8 id; + u8 key_type; + u8 key_size; + u8 key[MAX_KEY_SIZE]; + u8 hlid; + u32 tx_seq_32; + u16 tx_seq_16; +}; + struct wl1271 { struct platform_device *plat_dev; struct ieee80211_hw *hw; @@ -438,6 +451,9 @@ struct wl1271 { /* map for HLIDs of associated stations - when operating in AP mode */ unsigned long ap_hlid_map[BITS_TO_LONGS(AP_MAX_STATIONS)]; + + /* recoreded keys for AP-mode - set here before AP startup */ + struct wl1271_ap_key *recorded_ap_keys[MAX_NUM_KEYS]; }; struct wl1271_station { -- cgit v1.2.3 From 166d504ebaed391f1a411c69a5659632249ba711 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sat, 16 Oct 2010 21:44:57 +0200 Subject: wl12xx: AP mode - fetch appropriate firmware for AP AP and STA modes use different firmwares. Differentiate the firmware files by name and fetch the appropriate one when add_interface is called by mac80211. The STA firmware is chosen for PLT mode. Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 33 ++++++++++++++++++++++++++++++--- drivers/net/wireless/wl12xx/wl12xx.h | 3 +++ 2 files changed, 33 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 4ca46b2d7f34..a6de19a4ee0e 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -658,9 +658,26 @@ out: static int wl1271_fetch_firmware(struct wl1271 *wl) { const struct firmware *fw; + const char *fw_name; int ret; - ret = request_firmware(&fw, WL1271_FW_NAME, wl1271_wl_to_dev(wl)); + switch (wl->bss_type) { + case BSS_TYPE_AP_BSS: + fw_name = WL1271_AP_FW_NAME; + break; + case BSS_TYPE_IBSS: + case BSS_TYPE_STA_BSS: + fw_name = WL1271_FW_NAME; + break; + default: + wl1271_error("no compatible firmware for bss_type %d", + wl->bss_type); + return -EINVAL; + } + + wl1271_debug(DEBUG_BOOT, "booting firmware %s", fw_name); + + ret = request_firmware(&fw, fw_name, wl1271_wl_to_dev(wl)); if (ret < 0) { wl1271_error("could not get firmware: %d", ret); @@ -674,6 +691,7 @@ static int wl1271_fetch_firmware(struct wl1271 *wl) goto out; } + vfree(wl->fw); wl->fw_len = fw->size; wl->fw = vmalloc(wl->fw_len); @@ -684,7 +702,7 @@ static int wl1271_fetch_firmware(struct wl1271 *wl) } memcpy(wl->fw, fw->data, wl->fw_len); - + wl->fw_bss_type = wl->bss_type; ret = 0; out: @@ -820,7 +838,8 @@ static int wl1271_chip_wakeup(struct wl1271 *wl) goto out; } - if (wl->fw == NULL) { + /* Make sure the firmware type matches the BSS type */ + if (wl->fw == NULL || wl->fw_bss_type != wl->bss_type) { ret = wl1271_fetch_firmware(wl); if (ret < 0) goto out; @@ -853,6 +872,8 @@ int wl1271_plt_start(struct wl1271 *wl) goto out; } + wl->bss_type = BSS_TYPE_STA_BSS; + while (retries) { retries--; ret = wl1271_chip_wakeup(wl); @@ -1010,6 +1031,9 @@ static int wl1271_op_start(struct ieee80211_hw *hw) * * The MAC address is first known when the corresponding interface * is added. That is where we will initialize the hardware. + * + * In addition, we currently have different firmwares for AP and managed + * operation. We will know which to boot according to interface type. */ return 0; @@ -3183,6 +3207,9 @@ struct ieee80211_hw *wl1271_alloc_hw(void) wl->flags = 0; wl->sg_enabled = true; wl->hw_pg_ver = -1; + wl->bss_type = MAX_BSS_TYPE; + wl->set_bss_type = MAX_BSS_TYPE; + wl->fw_bss_type = MAX_BSS_TYPE; memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); for (i = 0; i < ACX_TX_DESCRIPTORS; i++) diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 6b2c763e4908..f153e4b81c0d 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -124,6 +124,8 @@ extern u32 wl12xx_debug_level; #define WL1271_FW_NAME "wl1271-fw.bin" +#define WL1271_AP_FW_NAME "wl1271-fw-ap.bin" + #define WL1271_NVS_NAME "wl1271-nvs.bin" #define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) @@ -311,6 +313,7 @@ struct wl1271 { u8 *fw; size_t fw_len; + u8 fw_bss_type; struct wl1271_nvs_file *nvs; size_t nvs_len; -- cgit v1.2.3 From 31d26ec6992cc05cfd5e50a59b00b0d64c7bb4aa Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sat, 16 Oct 2010 21:49:52 +0200 Subject: wl12xx: Read MAC address from NVS file on HW startup Try to read the MAC address from the on-disk NVS file. A non-zero MAC address is required to add an AP interface. Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index a6de19a4ee0e..78d615525980 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -3064,6 +3064,18 @@ int wl1271_register_hw(struct wl1271 *wl) if (wl->mac80211_registered) return 0; + ret = wl1271_fetch_nvs(wl); + if (ret == 0) { + u8 *nvs_ptr = (u8 *)wl->nvs->nvs; + + wl->mac_addr[0] = nvs_ptr[11]; + wl->mac_addr[1] = nvs_ptr[10]; + wl->mac_addr[2] = nvs_ptr[6]; + wl->mac_addr[3] = nvs_ptr[5]; + wl->mac_addr[4] = nvs_ptr[4]; + wl->mac_addr[5] = nvs_ptr[3]; + } + SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr); ret = ieee80211_register_hw(wl->hw); -- cgit v1.2.3 From 038d925bcfed8df4d16bab57c2b5a4de6ede7847 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sat, 16 Oct 2010 21:53:24 +0200 Subject: wl12xx: Enable AP-mode Indicate support for the NL80211_IFTYPE_AP interface mode to enable AP mode operation. Disable 11a when operating in AP-mode (unsupported for now). Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/boot.c | 4 +++- drivers/net/wireless/wl12xx/main.c | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index 2b1019f67d27..d7e036f42958 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c @@ -232,7 +232,9 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) */ if (wl->nvs_len == sizeof(struct wl1271_nvs_file) || wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) { - if (wl->nvs->general_params.dual_mode_select) + /* for now 11a is unsupported in AP mode */ + if (wl->bss_type != BSS_TYPE_AP_BSS && + wl->nvs->general_params.dual_mode_select) wl->enable_11a = true; } diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 78d615525980..8a3549162999 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1073,6 +1073,9 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, wl->bss_type = BSS_TYPE_IBSS; wl->set_bss_type = BSS_TYPE_STA_BSS; break; + case NL80211_IFTYPE_AP: + wl->bss_type = BSS_TYPE_AP_BSS; + break; default: ret = -EOPNOTSUPP; goto out; @@ -3136,7 +3139,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl) wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC); + BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP); wl->hw->wiphy->max_scan_ssids = 1; /* * Maximum length of elements in scanning probe request templates -- cgit v1.2.3 From fa287b8f291d79f080182eb353d1c1f4f374ae87 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 26 Dec 2010 09:27:50 +0100 Subject: wl12xx: don't join upon disassociation wl12xx "rejoins" upon every BSS_CHANGED_BSSID notification. However, there is no need to rejoin after disassociation, so just filter out the case when the new bssid is 00:00:00:00:00:00. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 8a3549162999..a3529f56a3d6 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2266,19 +2266,21 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) { memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); - ret = wl1271_cmd_build_null_data(wl); - if (ret < 0) - goto out; + if (!is_zero_ether_addr(wl->bssid)) { + ret = wl1271_cmd_build_null_data(wl); + if (ret < 0) + goto out; - ret = wl1271_build_qos_null_data(wl); - if (ret < 0) - goto out; + ret = wl1271_build_qos_null_data(wl); + if (ret < 0) + goto out; - /* filter out all packets not from this BSSID */ - wl1271_configure_filters(wl, 0); + /* filter out all packets not from this BSSID */ + wl1271_configure_filters(wl, 0); - /* Need to update the BSSID (for filtering etc) */ - do_join = true; + /* Need to update the BSSID (for filtering etc) */ + do_join = true; + } } if ((changed & BSS_CHANGED_ASSOC)) { -- cgit v1.2.3 From a8aaaf53d5f22f7f60ca5af26fc85c2940575c37 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Tue, 11 Jan 2011 18:25:18 +0100 Subject: wl12xx: don't modify the global supported band structures When 11a is not supported, we were modifying the global structure that contains the bands supported by the driver. This causes problems when having more one wl12xx device in the same system because they all use the same global. This also causes problems when the wl12xx_sdio module is removed and the wl12xx module remains. Fix this problem by copying the band structure into the wl12xx instance. Reported-by: Arik Nemtsov Reported-by: Johannes Berg Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 16 ++++++++++++++-- drivers/net/wireless/wl12xx/wl12xx.h | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index a3529f56a3d6..588e10ee282c 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -3150,8 +3150,20 @@ int wl1271_init_ieee80211(struct wl1271 *wl) */ wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE - sizeof(struct ieee80211_header); - wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz; - wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz; + + /* + * We keep local copies of the band structs because we need to + * modify them on a per-device basis. + */ + memcpy(&wl->bands[IEEE80211_BAND_2GHZ], &wl1271_band_2ghz, + sizeof(wl1271_band_2ghz)); + memcpy(&wl->bands[IEEE80211_BAND_5GHZ], &wl1271_band_5ghz, + sizeof(wl1271_band_5ghz)); + + wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = + &wl->bands[IEEE80211_BAND_2GHZ]; + wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = + &wl->bands[IEEE80211_BAND_5GHZ]; wl->hw->queues = 4; wl->hw->max_rates = 1; diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index f153e4b81c0d..ca727e0c4ce9 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -457,6 +457,9 @@ struct wl1271 { /* recoreded keys for AP-mode - set here before AP startup */ struct wl1271_ap_key *recorded_ap_keys[MAX_NUM_KEYS]; + + /* bands supported by this instance of wl12xx */ + struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; }; struct wl1271_station { -- cgit v1.2.3 From 2d6e4e76d1e73886cb087142e70e2beaabb94b79 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Tue, 11 Jan 2011 19:07:21 +0100 Subject: wl12xx: lock the RCU when accessing sta via ieee80211_find_sta() We were calling ieee80211_find_sta() and the sta returned by it without locking the RCU, which is required by mac80211. Fix this and reorganize slightly the area of the code where the sta is used. Reported-by: Jonathan DE CESCO Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 60 +++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 588e10ee282c..2192e4cf62f4 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2219,7 +2219,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, bool do_join = false, set_assoc = false; bool is_ibss = (wl->bss_type == BSS_TYPE_IBSS); int ret; - struct ieee80211_sta *sta = ieee80211_find_sta(vif, bss_conf->bssid); + struct ieee80211_sta *sta; if (is_ibss) { ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf, @@ -2378,36 +2378,42 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, if (ret < 0) goto out; - /* - * Takes care of: New association with HT enable, - * HT information change in beacon. - */ - if (sta && - (changed & BSS_CHANGED_HT) && - (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { - ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true); - if (ret < 0) { - wl1271_warning("Set ht cap true failed %d", ret); - goto out; - } + rcu_read_lock(); + sta = ieee80211_find_sta(vif, bss_conf->bssid); + if (sta) { + /* handle new association with HT and HT information change */ + if ((changed & BSS_CHANGED_HT) && + (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { + ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, + true); + if (ret < 0) { + wl1271_warning("Set ht cap true failed %d", + ret); + rcu_read_unlock(); + goto out; + } ret = wl1271_acx_set_ht_information(wl, - bss_conf->ht_operation_mode); - if (ret < 0) { - wl1271_warning("Set ht information failed %d", ret); - goto out; + bss_conf->ht_operation_mode); + if (ret < 0) { + wl1271_warning("Set ht information failed %d", + ret); + rcu_read_unlock(); + goto out; + } } - } - /* - * Takes care of: New association without HT, - * Disassociation. - */ - else if (sta && (changed & BSS_CHANGED_ASSOC)) { - ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, false); - if (ret < 0) { - wl1271_warning("Set ht cap false failed %d", ret); - goto out; + /* handle new association without HT and disassociation */ + else if (changed & BSS_CHANGED_ASSOC) { + ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, + false); + if (ret < 0) { + wl1271_warning("Set ht cap false failed %d", + ret); + rcu_read_unlock(); + goto out; + } } } + rcu_read_unlock(); if (changed & BSS_CHANGED_ARP_FILTER) { __be32 addr = bss_conf->arp_addr_list[0]; -- cgit v1.2.3 From 491bbd6bdddafb49d0d6a9258d53441aee4bb622 Mon Sep 17 00:00:00 2001 From: Guy Eilam Date: Wed, 12 Jan 2011 10:33:29 +0100 Subject: wl12xx: change debug_level module param sysfs permissions changed the visibility of the debug_level module parameter in the filesystem to be readable and writable to the root user. It is now accessible under /sys/module/wl12xx/parameters removed the debug_level debugfs file that was created under /sys/kernel/debug/... Signed-off-by: Guy Eilam Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/debugfs.c | 5 ----- drivers/net/wireless/wl12xx/main.c | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index 36e7ec1e0c3b..dc3ca0031817 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c @@ -402,11 +402,6 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl, DEBUGFS_ADD(gpio_power, rootdir); - entry = debugfs_create_x32("debug_level", 0600, rootdir, - &wl12xx_debug_level); - if (!entry || IS_ERR(entry)) - goto err; - return 0; err: diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 2192e4cf62f4..907655504983 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -3334,9 +3334,9 @@ int wl1271_free_hw(struct wl1271 *wl) } EXPORT_SYMBOL_GPL(wl1271_free_hw); -u32 wl12xx_debug_level; +u32 wl12xx_debug_level = DEBUG_NONE; EXPORT_SYMBOL_GPL(wl12xx_debug_level); -module_param_named(debug_level, wl12xx_debug_level, uint, DEBUG_NONE); +module_param_named(debug_level, wl12xx_debug_level, uint, S_IRUSR | S_IWUSR); MODULE_PARM_DESC(debug_level, "wl12xx debugging level"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 4c9cfa780643dc3f609366b85fec2444a67cad64 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 12 Jan 2011 14:27:03 +0100 Subject: wl12xx: add hw configuration for max supported AMDPU size The wl12xx chips do the AMDPU aggregation work in the firmware, but it supports a maximum of 8 frames per block. Configure the mac80211 hw structure accordingly. Signed-off-by: Luciano Coelho Tested-by: Juuso Oikarinen --- drivers/net/wireless/wl12xx/main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 907655504983..77f6ac6466b2 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -3180,6 +3180,8 @@ int wl1271_init_ieee80211(struct wl1271 *wl) wl->hw->sta_data_size = sizeof(struct wl1271_station); + wl->hw->max_rx_aggregation_subframes = 8; + return 0; } EXPORT_SYMBOL_GPL(wl1271_init_ieee80211); -- cgit v1.2.3 From 1d4801f2689dc2618fdb5e83d4cb7743747491ed Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 16 Jan 2011 10:07:10 +0100 Subject: wl12xx: fix some endianess bugs pointed out by sparse warnings: CHECK drivers/net/wireless/wl12xx/cmd.c drivers/net/wireless/wl12xx/cmd.c:987:20: warning: incorrect type in assignment (different base types) drivers/net/wireless/wl12xx/cmd.c:987:20: expected restricted __le16 [usertype] aging_period drivers/net/wireless/wl12xx/cmd.c:987:20: got int CHECK drivers/net/wireless/wl12xx/tx.c drivers/net/wireless/wl12xx/tx.c:197:2: warning: cast from restricted __le16 drivers/net/wireless/wl12xx/tx.c:197:2: warning: cast from restricted __le16 drivers/net/wireless/wl12xx/tx.c:197:2: warning: cast from restricted __le16 CHECK drivers/net/wireless/wl12xx/acx.c drivers/net/wireless/wl12xx/acx.c:816:23: warning: incorrect type in assignment (different base types) drivers/net/wireless/wl12xx/acx.c:816:23: expected restricted __le32 [usertype] rate_policy_idx drivers/net/wireless/wl12xx/acx.c:816:23: got unsigned char [unsigned] [usertype] idx Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 2 +- drivers/net/wireless/wl12xx/cmd.c | 2 +- drivers/net/wireless/wl12xx/tx.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index 646d278bd944..679bb37f0ca4 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -813,7 +813,7 @@ int wl1271_acx_ap_rate_policy(struct wl1271 *wl, struct conf_tx_rate_class *c, acx->rate_policy.long_retry_limit = c->long_retry_limit; acx->rate_policy.aflags = c->aflags; - acx->rate_policy_idx = idx; + acx->rate_policy_idx = cpu_to_le32(idx); ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); if (ret < 0) { diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index e28d9cab1185..1bb8be5e805b 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -984,7 +984,7 @@ int wl1271_cmd_start_bss(struct wl1271 *wl) memcpy(cmd->bssid, bss_conf->bssid, ETH_ALEN); - cmd->aging_period = WL1271_AP_DEF_INACTIV_SEC; + cmd->aging_period = cpu_to_le16(WL1271_AP_DEF_INACTIV_SEC); cmd->bss_index = WL1271_AP_BSS_INDEX; cmd->global_hlid = WL1271_AP_GLOBAL_HLID; cmd->broadcast_hlid = WL1271_AP_BROADCAST_HLID; diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 2347f2552f14..3507c81c7500 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -195,9 +195,9 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, desc->tx_attr = cpu_to_le16(tx_attr); wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d hlid: %d " - "tx_attr: 0x%x len: %d life: %d mem: %d", pad, (int)desc->hlid, - (int)desc->tx_attr, (int)desc->length, (int)desc->life_time, - (int)desc->total_mem_blocks); + "tx_attr: 0x%x len: %d life: %d mem: %d", pad, desc->hlid, + le16_to_cpu(desc->tx_attr), le16_to_cpu(desc->length), + le16_to_cpu(desc->life_time), desc->total_mem_blocks); } /* caller must hold wl->mutex */ -- cgit v1.2.3 From 4ae3fa87854862d1724bf8f2f1e1b9b088fa53d7 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Fri, 14 Jan 2011 12:48:46 +0100 Subject: wl12xx: Cleanup PLT mode when module is removed PLT mode start/stop is controlled from userspace. When removing module, the PLT mode state is however not checked, and not cleared. There is the possibility of some unwanted state to left linger and there is even the possiblity of a kernel crash if for instance IRQ work is running when the module is removed. Fix this by stopping PLT mode on module removal, if still running. Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 77f6ac6466b2..9a1d2ff35c2d 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -917,12 +917,10 @@ out: return ret; } -int wl1271_plt_stop(struct wl1271 *wl) +int __wl1271_plt_stop(struct wl1271 *wl) { int ret = 0; - mutex_lock(&wl->mutex); - wl1271_notice("power down"); if (wl->state != WL1271_STATE_PLT) { @@ -938,12 +936,21 @@ int wl1271_plt_stop(struct wl1271 *wl) wl->state = WL1271_STATE_OFF; wl->rx_counter = 0; -out: mutex_unlock(&wl->mutex); - cancel_work_sync(&wl->irq_work); cancel_work_sync(&wl->recovery_work); + mutex_lock(&wl->mutex); +out: + return ret; +} + +int wl1271_plt_stop(struct wl1271 *wl) +{ + int ret; + mutex_lock(&wl->mutex); + ret = __wl1271_plt_stop(wl); + mutex_unlock(&wl->mutex); return ret; } @@ -3109,6 +3116,9 @@ EXPORT_SYMBOL_GPL(wl1271_register_hw); void wl1271_unregister_hw(struct wl1271 *wl) { + if (wl->state == WL1271_STATE_PLT) + __wl1271_plt_stop(wl); + unregister_netdevice_notifier(&wl1271_dev_notifier); ieee80211_unregister_hw(wl->hw); wl->mac80211_registered = false; -- cgit v1.2.3 From d75387ca62b92d837c2a1e626d0d3705a9011228 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Mon, 17 Jan 2011 10:16:00 +0100 Subject: wl12xx: add missing MODULE_FIRMWARE statment for AP-mode FW In wl12xx cards AP-mode requires a separate FW file. Add this file to the module info. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/sdio.c | 1 + drivers/net/wireless/wl12xx/spi.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 93cbb8d5aba9..d5e874825069 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -345,3 +345,4 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Luciano Coelho "); MODULE_AUTHOR("Juuso Oikarinen "); MODULE_FIRMWARE(WL1271_FW_NAME); +MODULE_FIRMWARE(WL1271_AP_FW_NAME); diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c index 8f7ea2c7d567..0132dad756c4 100644 --- a/drivers/net/wireless/wl12xx/spi.c +++ b/drivers/net/wireless/wl12xx/spi.c @@ -495,4 +495,5 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Luciano Coelho "); MODULE_AUTHOR("Juuso Oikarinen "); MODULE_FIRMWARE(WL1271_FW_NAME); +MODULE_FIRMWARE(WL1271_AP_FW_NAME); MODULE_ALIAS("spi:wl1271"); -- cgit v1.2.3 From 6c89b7b2f856a2b67f53313ddfa3af4ab52bae28 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 18 Jan 2011 20:39:52 +0100 Subject: wl12xx: Add channel 14 to list of supported 2ghz channels Channel 14 is only supported in Japan (JP country code in regdb). The FW limits tranmissions to CCK only on this channel. Tested in both STA and AP modes to work correctly. Signed-off-by: Arik Nemtsov Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 9a1d2ff35c2d..48194629c00b 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2778,6 +2778,7 @@ static struct ieee80211_channel wl1271_channels[] = { { .hw_value = 11, .center_freq = 2462, .max_power = 25 }, { .hw_value = 12, .center_freq = 2467, .max_power = 25 }, { .hw_value = 13, .center_freq = 2472, .max_power = 25 }, + { .hw_value = 14, .center_freq = 2484, .max_power = 25 }, }; /* mapping to indexes for wl1271_rates */ -- cgit v1.2.3 From 4b7fac77b4c1badac84df3dcbdf07199d94cb1c3 Mon Sep 17 00:00:00 2001 From: "Levi, Shahar" Date: Sun, 23 Jan 2011 07:27:22 +0100 Subject: wl12xx: BA initiator support Add 80211n BA initiator session support wl1271 driver. Include BA supported FW version auto detection mechanism. BA initiator session management included in FW independently. Signed-off-by: Shahar Levi Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 51 ++++++++++++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/acx.h | 41 +++++++++++++++++++++++++++-- drivers/net/wireless/wl12xx/boot.c | 24 ++++++++++++++--- drivers/net/wireless/wl12xx/conf.h | 6 +++++ drivers/net/wireless/wl12xx/init.c | 42 +++++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/main.c | 12 ++++++--- drivers/net/wireless/wl12xx/wl12xx.h | 17 +++++++++++- 7 files changed, 183 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index 679bb37f0ca4..0b9cacc74903 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -1342,6 +1342,57 @@ out: return ret; } +/* Configure BA session initiator/receiver parameters setting in the FW. */ +int wl1271_acx_set_ba_session(struct wl1271 *wl, + enum ieee80211_back_parties direction, + u8 tid_index, u8 policy) +{ + struct wl1271_acx_ba_session_policy *acx; + int ret; + + wl1271_debug(DEBUG_ACX, "acx ba session setting"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + /* ANY role */ + acx->role_id = 0xff; + acx->tid = tid_index; + acx->enable = policy; + acx->ba_direction = direction; + + switch (direction) { + case WLAN_BACK_INITIATOR: + acx->win_size = wl->conf.ht.tx_ba_win_size; + acx->inactivity_timeout = wl->conf.ht.inactivity_timeout; + break; + case WLAN_BACK_RECIPIENT: + acx->win_size = RX_BA_WIN_SIZE; + acx->inactivity_timeout = 0; + break; + default: + wl1271_error("Incorrect acx command id=%x\n", direction); + ret = -EINVAL; + goto out; + } + + ret = wl1271_cmd_configure(wl, + ACX_BA_SESSION_POLICY_CFG, + acx, + sizeof(*acx)); + if (ret < 0) { + wl1271_warning("acx ba session setting failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime) { struct wl1271_acx_fw_tsf_information *tsf_info; diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index 62a269d84ebe..f643e60a566b 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h @@ -1061,6 +1061,40 @@ struct wl1271_acx_ht_information { u8 padding[3]; } __packed; +#define RX_BA_WIN_SIZE 8 + +struct wl1271_acx_ba_session_policy { + struct acx_header header; + /* + * Specifies role Id, Range 0-7, 0xFF means ANY role. + * Future use. For now this field is irrelevant + */ + u8 role_id; + /* + * Specifies Link Id, Range 0-31, 0xFF means ANY Link Id. + * Not applicable if Role Id is set to ANY. + */ + u8 link_id; + + u8 tid; + + u8 enable; + + /* Windows size in number of packets */ + u16 win_size; + + /* + * As initiator inactivity timeout in time units(TU) of 1024us. + * As receiver reserved + */ + u16 inactivity_timeout; + + /* Initiator = 1/Receiver = 0 */ + u8 ba_direction; + + u8 padding[3]; +} __packed; + struct wl1271_acx_fw_tsf_information { struct acx_header header; @@ -1134,8 +1168,8 @@ enum { ACX_RSSI_SNR_WEIGHTS = 0x0052, ACX_KEEP_ALIVE_MODE = 0x0053, ACX_SET_KEEP_ALIVE_CONFIG = 0x0054, - ACX_BA_SESSION_RESPONDER_POLICY = 0x0055, - ACX_BA_SESSION_INITIATOR_POLICY = 0x0056, + ACX_BA_SESSION_POLICY_CFG = 0x0055, + ACX_BA_SESSION_RX_SETUP = 0x0056, ACX_PEER_HT_CAP = 0x0057, ACX_HT_BSS_OPERATION = 0x0058, ACX_COEX_ACTIVITY = 0x0059, @@ -1209,6 +1243,9 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl, bool allow_ht_operation); int wl1271_acx_set_ht_information(struct wl1271 *wl, u16 ht_operation_mode); +int wl1271_acx_set_ba_session(struct wl1271 *wl, + enum ieee80211_back_parties direction, + u8 tid_index, u8 policy); int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); int wl1271_acx_max_tx_retry(struct wl1271 *wl); diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index d7e036f42958..1ffbad67d2d8 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c @@ -101,6 +101,22 @@ static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag) wl1271_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl); } +static void wl1271_parse_fw_ver(struct wl1271 *wl) +{ + int ret; + + ret = sscanf(wl->chip.fw_ver_str + 4, "%u.%u.%u.%u.%u", + &wl->chip.fw_ver[0], &wl->chip.fw_ver[1], + &wl->chip.fw_ver[2], &wl->chip.fw_ver[3], + &wl->chip.fw_ver[4]); + + if (ret != 5) { + wl1271_warning("fw version incorrect value"); + memset(wl->chip.fw_ver, 0, sizeof(wl->chip.fw_ver)); + return; + } +} + static void wl1271_boot_fw_version(struct wl1271 *wl) { struct wl1271_static_data static_data; @@ -108,11 +124,13 @@ static void wl1271_boot_fw_version(struct wl1271 *wl) wl1271_read(wl, wl->cmd_box_addr, &static_data, sizeof(static_data), false); - strncpy(wl->chip.fw_ver, static_data.fw_version, - sizeof(wl->chip.fw_ver)); + strncpy(wl->chip.fw_ver_str, static_data.fw_version, + sizeof(wl->chip.fw_ver_str)); /* make sure the string is NULL-terminated */ - wl->chip.fw_ver[sizeof(wl->chip.fw_ver) - 1] = '\0'; + wl->chip.fw_ver_str[sizeof(wl->chip.fw_ver_str) - 1] = '\0'; + + wl1271_parse_fw_ver(wl); } static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index f5c048c9bea4..135d837cefb1 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h @@ -1138,6 +1138,11 @@ struct conf_rf_settings { u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5]; }; +struct conf_ht_setting { + u16 tx_ba_win_size; + u16 inactivity_timeout; +}; + struct conf_drv_settings { struct conf_sg_settings sg; struct conf_rx_settings rx; @@ -1148,6 +1153,7 @@ struct conf_drv_settings { struct conf_roam_trigger_settings roam_trigger; struct conf_scan_settings scan; struct conf_rf_settings rf; + struct conf_ht_setting ht; }; #endif diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index bdb61232f80c..2348eadc0de1 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c @@ -455,6 +455,43 @@ static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl) return 0; } +static void wl1271_check_ba_support(struct wl1271 *wl) +{ + /* validate FW cose ver x.x.x.50-60.x */ + if ((wl->chip.fw_ver[3] >= WL12XX_BA_SUPPORT_FW_COST_VER2_START) && + (wl->chip.fw_ver[3] < WL12XX_BA_SUPPORT_FW_COST_VER2_END)) { + wl->ba_support = true; + return; + } + + wl->ba_support = false; +} + +static int wl1271_set_ba_policies(struct wl1271 *wl) +{ + u8 tid_index; + u8 ret = 0; + + /* Reset the BA RX indicators */ + wl->ba_allowed = true; + wl->ba_rx_bitmap = 0; + + /* validate that FW support BA */ + wl1271_check_ba_support(wl); + + if (wl->ba_support) + /* 802.11n initiator BA session setting */ + for (tid_index = 0; tid_index < CONF_TX_MAX_TID_COUNT; + ++tid_index) { + ret = wl1271_acx_set_ba_session(wl, WLAN_BACK_INITIATOR, + tid_index, true); + if (ret < 0) + break; + } + + return ret; +} + int wl1271_hw_init(struct wl1271 *wl) { struct conf_tx_ac_category *conf_ac; @@ -568,6 +605,11 @@ int wl1271_hw_init(struct wl1271 *wl) if (ret < 0) goto out_free_memmap; + /* Configure initiator BA sessions policies */ + ret = wl1271_set_ba_policies(wl); + if (ret < 0) + goto out_free_memmap; + return 0; out_free_memmap: diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 48194629c00b..01ca666b6c2d 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -274,7 +274,7 @@ static struct conf_drv_settings default_conf = { .avg_weight_rssi_beacon = 20, .avg_weight_rssi_data = 10, .avg_weight_snr_beacon = 20, - .avg_weight_snr_data = 10 + .avg_weight_snr_data = 10, }, .scan = { .min_dwell_time_active = 7500, @@ -293,6 +293,10 @@ static struct conf_drv_settings default_conf = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, }, + .ht = { + .tx_ba_win_size = 64, + .inactivity_timeout = 10000, + }, }; static void __wl1271_op_remove_interface(struct wl1271 *wl); @@ -890,7 +894,7 @@ int wl1271_plt_start(struct wl1271 *wl) wl->state = WL1271_STATE_PLT; wl1271_notice("firmware booted in PLT mode (%s)", - wl->chip.fw_ver); + wl->chip.fw_ver_str); goto out; irq_disable: @@ -1138,11 +1142,11 @@ power_off: wl->vif = vif; wl->state = WL1271_STATE_ON; - wl1271_info("firmware booted (%s)", wl->chip.fw_ver); + wl1271_info("firmware booted (%s)", wl->chip.fw_ver_str); /* update hw/fw version info in wiphy struct */ wiphy->hw_version = wl->chip.id; - strncpy(wiphy->fw_version, wl->chip.fw_ver, + strncpy(wiphy->fw_version, wl->chip.fw_ver_str, sizeof(wiphy->fw_version)); /* diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index ca727e0c4ce9..e0bac79cd516 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -38,6 +38,13 @@ #define DRIVER_NAME "wl1271" #define DRIVER_PREFIX DRIVER_NAME ": " +/* + * FW versions support BA 11n + * versions marks x.x.x.50-60.x + */ +#define WL12XX_BA_SUPPORT_FW_COST_VER2_START 50 +#define WL12XX_BA_SUPPORT_FW_COST_VER2_END 60 + enum { DEBUG_NONE = 0, DEBUG_IRQ = BIT(0), @@ -182,10 +189,13 @@ struct wl1271_partition_set { struct wl1271; +#define WL12XX_NUM_FW_VER 5 + /* FIXME: I'm not sure about this structure name */ struct wl1271_chip { u32 id; - char fw_ver[21]; + char fw_ver_str[ETHTOOL_BUSINFO_LEN]; + unsigned int fw_ver[WL12XX_NUM_FW_VER]; }; struct wl1271_stats { @@ -460,6 +470,11 @@ struct wl1271 { /* bands supported by this instance of wl12xx */ struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; + + /* RX BA constraint value */ + bool ba_support; + u8 ba_allowed; + u8 ba_rx_bitmap; }; struct wl1271_station { -- cgit v1.2.3 From bbba3e6832ad3e974fb593a98abe03f8b60fc7f3 Mon Sep 17 00:00:00 2001 From: "Levi, Shahar" Date: Sun, 23 Jan 2011 07:27:23 +0100 Subject: wl12xx: BA receiver support Add new ampdu_action ops to support receiver BA. The BA initiator session management in FW independently. Signed-off-by: Shahar Levi Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 34 ++++++++++++++++++++ drivers/net/wireless/wl12xx/acx.h | 25 +++++++++++++-- drivers/net/wireless/wl12xx/init.c | 1 - drivers/net/wireless/wl12xx/main.c | 60 ++++++++++++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/wl12xx.h | 1 - 5 files changed, 117 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index 0b9cacc74903..afdc601aa7ea 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -1393,6 +1393,40 @@ out: return ret; } +/* setup BA session receiver setting in the FW. */ +int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn, + bool enable) +{ + struct wl1271_acx_ba_receiver_setup *acx; + int ret; + + wl1271_debug(DEBUG_ACX, "acx ba receiver session setting"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + /* Single link for now */ + acx->link_id = 1; + acx->tid = tid_index; + acx->enable = enable; + acx->win_size = 0; + acx->ssn = ssn; + + ret = wl1271_cmd_configure(wl, ACX_BA_SESSION_RX_SETUP, acx, + sizeof(*acx)); + if (ret < 0) { + wl1271_warning("acx ba receiver session failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime) { struct wl1271_acx_fw_tsf_information *tsf_info; diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index f643e60a566b..4bbaf04f434e 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h @@ -1095,6 +1095,25 @@ struct wl1271_acx_ba_session_policy { u8 padding[3]; } __packed; +struct wl1271_acx_ba_receiver_setup { + struct acx_header header; + + /* Specifies Link Id, Range 0-31, 0xFF means ANY Link Id */ + u8 link_id; + + u8 tid; + + u8 enable; + + u8 padding[1]; + + /* Windows size in number of packets */ + u16 win_size; + + /* BA session starting sequence number. RANGE 0-FFF */ + u16 ssn; +} __packed; + struct wl1271_acx_fw_tsf_information { struct acx_header header; @@ -1244,8 +1263,10 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl, int wl1271_acx_set_ht_information(struct wl1271 *wl, u16 ht_operation_mode); int wl1271_acx_set_ba_session(struct wl1271 *wl, - enum ieee80211_back_parties direction, - u8 tid_index, u8 policy); + enum ieee80211_back_parties direction, + u8 tid_index, u8 policy); +int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn, + bool enable); int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); int wl1271_acx_max_tx_retry(struct wl1271 *wl); diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index 2348eadc0de1..70b3dc88a219 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c @@ -473,7 +473,6 @@ static int wl1271_set_ba_policies(struct wl1271 *wl) u8 ret = 0; /* Reset the BA RX indicators */ - wl->ba_allowed = true; wl->ba_rx_bitmap = 0; /* validate that FW support BA */ diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 01ca666b6c2d..eda2f3d8edf1 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2724,6 +2724,65 @@ out: return ret; } +int wl1271_op_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + enum ieee80211_ampdu_mlme_action action, + struct ieee80211_sta *sta, u16 tid, u16 *ssn) +{ + struct wl1271 *wl = hw->priv; + int ret; + + mutex_lock(&wl->mutex); + + if (unlikely(wl->state == WL1271_STATE_OFF)) { + ret = -EAGAIN; + goto out; + } + + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + + switch (action) { + case IEEE80211_AMPDU_RX_START: + if (wl->ba_support) { + ret = wl1271_acx_set_ba_receiver_session(wl, tid, *ssn, + true); + if (!ret) + wl->ba_rx_bitmap |= BIT(tid); + } else { + ret = -ENOTSUPP; + } + break; + + case IEEE80211_AMPDU_RX_STOP: + ret = wl1271_acx_set_ba_receiver_session(wl, tid, 0, false); + if (!ret) + wl->ba_rx_bitmap &= ~BIT(tid); + break; + + /* + * The BA initiator session management in FW independently. + * Falling break here on purpose for all TX APDU commands. + */ + case IEEE80211_AMPDU_TX_START: + case IEEE80211_AMPDU_TX_STOP: + case IEEE80211_AMPDU_TX_OPERATIONAL: + ret = -EINVAL; + break; + + default: + wl1271_error("Incorrect ampdu action id=%x\n", action); + ret = -EINVAL; + } + + wl1271_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + + return ret; +} + /* can't be const, mac80211 writes to this */ static struct ieee80211_rate wl1271_rates[] = { { .bitrate = 10, @@ -2973,6 +3032,7 @@ static const struct ieee80211_ops wl1271_ops = { .get_survey = wl1271_op_get_survey, .sta_add = wl1271_op_sta_add, .sta_remove = wl1271_op_sta_remove, + .ampdu_action = wl1271_op_ampdu_action, CFG80211_TESTMODE_CMD(wl1271_tm_cmd) }; diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index e0bac79cd516..d1de13fe7d9a 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -473,7 +473,6 @@ struct wl1271 { /* RX BA constraint value */ bool ba_support; - u8 ba_allowed; u8 ba_rx_bitmap; }; -- cgit v1.2.3 From 8e2de74e781e696636e8b4cd08084d2b310d44d9 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 23 Jan 2011 11:25:27 +0100 Subject: wl12xx: wrong values are returned in gpio_power_write() Return values were assigned to incorrect var / weren't assigned. fix it, and defer mutex_lock after the sanity checks. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/debugfs.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index dc3ca0031817..bebfa28a171a 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c @@ -261,27 +261,25 @@ static ssize_t gpio_power_write(struct file *file, unsigned long value; int ret; - mutex_lock(&wl->mutex); - len = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, len)) { - ret = -EFAULT; - goto out; + return -EFAULT; } buf[len] = '\0'; ret = strict_strtoul(buf, 0, &value); if (ret < 0) { wl1271_warning("illegal value in gpio_power"); - goto out; + return -EINVAL; } + mutex_lock(&wl->mutex); + if (value) wl1271_power_on(wl); else wl1271_power_off(wl); -out: mutex_unlock(&wl->mutex); return count; } -- cgit v1.2.3 From ea45b2cbf56a4e93e9c5a68b85794e6d79f69fce Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Mon, 24 Jan 2011 07:01:54 +0100 Subject: wl12xx: Increase scan channel dwell time for passive scans The passive scan channel dwell time currently used is 30-60TU. A typical beacon interval for AP's is 100TU. This leads to a ~30% worst-case probability of finding an AP via passive scanning. For 5GHz bands for DFS frequencies passive scanning is the only scanning option. Hence for these, the probability of finding an AP is very low. To fix this, increase the passive channel scan dwell times (also the early leave value, as 5GHz channels are still typically very silent.) Use a value of 100TU, because that covers most typical AP configurations. Based on testing the probability of finding an AP (100TU beacon interval) on a single scan round are as follows (based on 100 iterations): dwell min/max (TU) | probability ---------------------+------------ 30/60 | 35% 60/60 | 56% 80/80 | 77% 100/100 | 100% Total scan times now and after the change: Region | Before (s) | After (s) -------+------------+---------- 00 | 0.77 | 1.48 FI | 0.95 | 2.01 US | 0.91 | 1.76 Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/conf.h | 18 +++++++++--------- drivers/net/wireless/wl12xx/main.c | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index 135d837cefb1..fd1dac9ab4db 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h @@ -1084,30 +1084,30 @@ struct conf_scan_settings { /* * The minimum time to wait on each channel for active scans * - * Range: 0 - 65536 tu + * Range: u32 tu/1000 */ - u16 min_dwell_time_active; + u32 min_dwell_time_active; /* * The maximum time to wait on each channel for active scans * - * Range: 0 - 65536 tu + * Range: u32 tu/1000 */ - u16 max_dwell_time_active; + u32 max_dwell_time_active; /* - * The maximum time to wait on each channel for passive scans + * The minimum time to wait on each channel for passive scans * - * Range: 0 - 65536 tu + * Range: u32 tu/1000 */ - u16 min_dwell_time_passive; + u32 min_dwell_time_passive; /* * The maximum time to wait on each channel for passive scans * - * Range: 0 - 65536 tu + * Range: u32 tu/1000 */ - u16 max_dwell_time_passive; + u32 max_dwell_time_passive; /* * Number of probe requests to transmit on each active scan channel diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index eda2f3d8edf1..e535e79e269d 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -279,8 +279,8 @@ static struct conf_drv_settings default_conf = { .scan = { .min_dwell_time_active = 7500, .max_dwell_time_active = 30000, - .min_dwell_time_passive = 30000, - .max_dwell_time_passive = 60000, + .min_dwell_time_passive = 100000, + .max_dwell_time_passive = 100000, .num_probe_reqs = 2, }, .rf = { -- cgit v1.2.3 From e5e2f24b3eec67a7a35d43654a997f98ca21aff2 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Mon, 24 Jan 2011 19:19:03 +0100 Subject: wl12xx: disable auto-arp The auto-arp feature sometimes has unexpected side effects (e.g. firmware crashes, no ARP replies, etc.) disable it until it will be solved. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index e535e79e269d..dfab21e2e5dc 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2445,8 +2445,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, } ret = wl1271_acx_arp_ip_filter(wl, - (ACX_ARP_FILTER_ARP_FILTERING | - ACX_ARP_FILTER_AUTO_ARP), + ACX_ARP_FILTER_ARP_FILTERING, addr); } else ret = wl1271_acx_arp_ip_filter(wl, 0, addr); -- cgit v1.2.3 From dc04b462dd87574f7c7da0bb98f444f32e6c5e44 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 24 Jan 2011 23:12:26 +0900 Subject: staging: rtl8192e: Remove unused DMESGE/W macros Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index aaf600d8fe22..f0ae553f9e94 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -94,12 +94,8 @@ #if 0 //we need to use RT_TRACE instead DMESG as RT_TRACE will clearly show debug level wb. #define DMESG(x,a...) printk(KERN_INFO RTL819xE_MODULE_NAME ": " x "\n", ## a) -#define DMESGW(x,a...) printk(KERN_WARNING RTL819xE_MODULE_NAME ": WW:" x "\n", ## a) -#define DMESGE(x,a...) printk(KERN_WARNING RTL819xE_MODULE_NAME ": EE:" x "\n", ## a) #else #define DMESG(x,a...) -#define DMESGW(x,a...) -#define DMESGE(x,a...) extern u32 rt_global_debug_component; #define RT_TRACE(component, x, args...) \ do { if(rt_global_debug_component & component) \ -- cgit v1.2.3 From 318f591f086ec091bd1d4cdeed3b130625ff2242 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 24 Jan 2011 23:12:48 +0900 Subject: staging: rtl8192e: Delete commented out code Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_dm.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index 0f7bc5234902..75c243664062 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -189,21 +189,6 @@ void dm_CheckRxAggregation(struct net_device *dev) { unsigned long curTxOkCnt = 0; unsigned long curRxOkCnt = 0; -/* - if (pHalData->bForcedUsbRxAggr) { - if (pHalData->ForcedUsbRxAggrInfo == 0) { - if (pHalData->bCurrentRxAggrEnable) { - Adapter->HalFunc.HalUsbRxAggrHandler(Adapter, FALSE); - } - } else { - if (!pHalData->bCurrentRxAggrEnable || (pHalData->ForcedUsbRxAggrInfo != pHalData->LastUsbRxAggrInfoSetting)) { - Adapter->HalFunc.HalUsbRxAggrHandler(Adapter, TRUE); - } - } - return; - } - -*/ curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; -- cgit v1.2.3 From 09ca1dfdccd72d156422169bd970d77a8b88e94c Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 24 Jan 2011 23:13:23 +0900 Subject: staging: rtl8192e: Convert txbbgain_table to a table Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 2 +- drivers/staging/rtl8192e/r8192E_dm.c | 117 ++++++++++++----------------------- 2 files changed, 42 insertions(+), 77 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index f0ae553f9e94..3cf362815f42 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1261,7 +1261,7 @@ typedef struct r8192_priv rate_adaptive rate_adaptive; //Add by amy for TX power tracking //2008/05/15 Mars OPEN/CLOSE TX POWER TRACKING - txbbgain_struct txbbgain_table[TxBBGainTableLength]; + const txbbgain_struct * txbbgain_table; u8 txpower_count;//For 6 sec do tracking again bool btxpower_trackingInit; u8 OFDM_index; diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index 75c243664062..05e483419ff7 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -974,86 +974,51 @@ void dm_txpower_trackingcallback(struct work_struct *work) } +static const txbbgain_struct rtl8192_txbbgain_table[] = { + { 12, 0x7f8001fe }, + { 11, 0x788001e2 }, + { 10, 0x71c001c7 }, + { 9, 0x6b8001ae }, + { 8, 0x65400195 }, + { 7, 0x5fc0017f }, + { 6, 0x5a400169 }, + { 5, 0x55400155 }, + { 4, 0x50800142 }, + { 3, 0x4c000130 }, + { 2, 0x47c0011f }, + { 1, 0x43c0010f }, + { 0, 0x40000100 }, + { -1, 0x3c8000f2 }, + { -2, 0x390000e4 }, + { -3, 0x35c000d7 }, + { -4, 0x32c000cb }, + { -5, 0x300000c0 }, + { -6, 0x2d4000b5 }, + { -7, 0x2ac000ab }, + { -8, 0x288000a2 }, + { -9, 0x26000098 }, + { -10, 0x24000090 }, + { -11, 0x22000088 }, + { -12, 0x20000080 }, + { -13, 0x1a00006c }, + { -14, 0x1c800072 }, + { -15, 0x18000060 }, + { -16, 0x19800066 }, + { -17, 0x15800056 }, + { -18, 0x26c0005b }, + { -19, 0x14400051 }, + { -20, 0x24400051 }, + { -21, 0x1300004c }, + { -22, 0x12000048 }, + { -23, 0x11000044 }, + { -24, 0x10000040 }, +}; + static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev) { - struct r8192_priv *priv = ieee80211_priv(dev); - //Initial the Tx BB index and mapping value - priv->txbbgain_table[0].txbb_iq_amplifygain = 12; - priv->txbbgain_table[0].txbbgain_value=0x7f8001fe; - priv->txbbgain_table[1].txbb_iq_amplifygain = 11; - priv->txbbgain_table[1].txbbgain_value=0x788001e2; - priv->txbbgain_table[2].txbb_iq_amplifygain = 10; - priv->txbbgain_table[2].txbbgain_value=0x71c001c7; - priv->txbbgain_table[3].txbb_iq_amplifygain = 9; - priv->txbbgain_table[3].txbbgain_value=0x6b8001ae; - priv->txbbgain_table[4].txbb_iq_amplifygain = 8; - priv->txbbgain_table[4].txbbgain_value=0x65400195; - priv->txbbgain_table[5].txbb_iq_amplifygain = 7; - priv->txbbgain_table[5].txbbgain_value=0x5fc0017f; - priv->txbbgain_table[6].txbb_iq_amplifygain = 6; - priv->txbbgain_table[6].txbbgain_value=0x5a400169; - priv->txbbgain_table[7].txbb_iq_amplifygain = 5; - priv->txbbgain_table[7].txbbgain_value=0x55400155; - priv->txbbgain_table[8].txbb_iq_amplifygain = 4; - priv->txbbgain_table[8].txbbgain_value=0x50800142; - priv->txbbgain_table[9].txbb_iq_amplifygain = 3; - priv->txbbgain_table[9].txbbgain_value=0x4c000130; - priv->txbbgain_table[10].txbb_iq_amplifygain = 2; - priv->txbbgain_table[10].txbbgain_value=0x47c0011f; - priv->txbbgain_table[11].txbb_iq_amplifygain = 1; - priv->txbbgain_table[11].txbbgain_value=0x43c0010f; - priv->txbbgain_table[12].txbb_iq_amplifygain = 0; - priv->txbbgain_table[12].txbbgain_value=0x40000100; - priv->txbbgain_table[13].txbb_iq_amplifygain = -1; - priv->txbbgain_table[13].txbbgain_value=0x3c8000f2; - priv->txbbgain_table[14].txbb_iq_amplifygain = -2; - priv->txbbgain_table[14].txbbgain_value=0x390000e4; - priv->txbbgain_table[15].txbb_iq_amplifygain = -3; - priv->txbbgain_table[15].txbbgain_value=0x35c000d7; - priv->txbbgain_table[16].txbb_iq_amplifygain = -4; - priv->txbbgain_table[16].txbbgain_value=0x32c000cb; - priv->txbbgain_table[17].txbb_iq_amplifygain = -5; - priv->txbbgain_table[17].txbbgain_value=0x300000c0; - priv->txbbgain_table[18].txbb_iq_amplifygain = -6; - priv->txbbgain_table[18].txbbgain_value=0x2d4000b5; - priv->txbbgain_table[19].txbb_iq_amplifygain = -7; - priv->txbbgain_table[19].txbbgain_value=0x2ac000ab; - priv->txbbgain_table[20].txbb_iq_amplifygain = -8; - priv->txbbgain_table[20].txbbgain_value=0x288000a2; - priv->txbbgain_table[21].txbb_iq_amplifygain = -9; - priv->txbbgain_table[21].txbbgain_value=0x26000098; - priv->txbbgain_table[22].txbb_iq_amplifygain = -10; - priv->txbbgain_table[22].txbbgain_value=0x24000090; - priv->txbbgain_table[23].txbb_iq_amplifygain = -11; - priv->txbbgain_table[23].txbbgain_value=0x22000088; - priv->txbbgain_table[24].txbb_iq_amplifygain = -12; - priv->txbbgain_table[24].txbbgain_value=0x20000080; - priv->txbbgain_table[25].txbb_iq_amplifygain = -13; - priv->txbbgain_table[25].txbbgain_value=0x1a00006c; - priv->txbbgain_table[26].txbb_iq_amplifygain = -14; - priv->txbbgain_table[26].txbbgain_value=0x1c800072; - priv->txbbgain_table[27].txbb_iq_amplifygain = -15; - priv->txbbgain_table[27].txbbgain_value=0x18000060; - priv->txbbgain_table[28].txbb_iq_amplifygain = -16; - priv->txbbgain_table[28].txbbgain_value=0x19800066; - priv->txbbgain_table[29].txbb_iq_amplifygain = -17; - priv->txbbgain_table[29].txbbgain_value=0x15800056; - priv->txbbgain_table[30].txbb_iq_amplifygain = -18; - priv->txbbgain_table[30].txbbgain_value=0x26c0005b; - priv->txbbgain_table[31].txbb_iq_amplifygain = -19; - priv->txbbgain_table[31].txbbgain_value=0x14400051; - priv->txbbgain_table[32].txbb_iq_amplifygain = -20; - priv->txbbgain_table[32].txbbgain_value=0x24400051; - priv->txbbgain_table[33].txbb_iq_amplifygain = -21; - priv->txbbgain_table[33].txbbgain_value=0x1300004c; - priv->txbbgain_table[34].txbb_iq_amplifygain = -22; - priv->txbbgain_table[34].txbbgain_value=0x12000048; - priv->txbbgain_table[35].txbb_iq_amplifygain = -23; - priv->txbbgain_table[35].txbbgain_value=0x11000044; - priv->txbbgain_table[36].txbb_iq_amplifygain = -24; - priv->txbbgain_table[36].txbbgain_value=0x10000040; + priv->txbbgain_table = rtl8192_txbbgain_table; //ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29 //This Table is for CH1~CH13 -- cgit v1.2.3 From da1f21ff794a1d607939d19cd7136803d897bfa4 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 24 Jan 2011 23:13:47 +0900 Subject: staging: rtl8192e: Convert cck_txbbgain_table to a table Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 2 +- drivers/staging/rtl8192e/r8192E_dm.c | 240 +++++------------------------------ 2 files changed, 33 insertions(+), 209 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 3cf362815f42..f3af413a547d 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1269,7 +1269,7 @@ typedef struct r8192_priv u8 Record_CCK_20Mindex; u8 Record_CCK_40Mindex; //2007/09/10 Mars Add CCK TX Power Tracking - ccktxbbgain_struct cck_txbbgain_table[CCKTxBBGainTableLength]; + const ccktxbbgain_struct *cck_txbbgain_table; ccktxbbgain_struct cck_txbbgain_ch14_table[CCKTxBBGainTableLength]; u8 rfa_txpowertrackingindex; u8 rfa_txpowertrackingindex_real; diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index 05e483419ff7..f99f49ea5f42 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -1014,220 +1014,44 @@ static const txbbgain_struct rtl8192_txbbgain_table[] = { { -24, 0x10000040 }, }; +/* + * ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29 + * This Table is for CH1~CH13 + */ +static const ccktxbbgain_struct rtl8192_cck_txbbgain_table[] = { + {{ 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04 }}, + {{ 0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04 }}, + {{ 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03 }}, + {{ 0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03 }}, + {{ 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03 }}, + {{ 0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03 }}, + {{ 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03 }}, + {{ 0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03 }}, + {{ 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02 }}, + {{ 0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02 }}, + {{ 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02 }}, + {{ 0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02 }}, + {{ 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02 }}, + {{ 0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02 }}, + {{ 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02 }}, + {{ 0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02 }}, + {{ 0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01 }}, + {{ 0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02 }}, + {{ 0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01 }}, + {{ 0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01 }}, + {{ 0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01 }}, + {{ 0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01 }}, + {{ 0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01 }}, +}; + + static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); priv->txbbgain_table = rtl8192_txbbgain_table; - //ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29 - //This Table is for CH1~CH13 - priv->cck_txbbgain_table[0].ccktxbb_valuearray[0] = 0x36; - priv->cck_txbbgain_table[0].ccktxbb_valuearray[1] = 0x35; - priv->cck_txbbgain_table[0].ccktxbb_valuearray[2] = 0x2e; - priv->cck_txbbgain_table[0].ccktxbb_valuearray[3] = 0x25; - priv->cck_txbbgain_table[0].ccktxbb_valuearray[4] = 0x1c; - priv->cck_txbbgain_table[0].ccktxbb_valuearray[5] = 0x12; - priv->cck_txbbgain_table[0].ccktxbb_valuearray[6] = 0x09; - priv->cck_txbbgain_table[0].ccktxbb_valuearray[7] = 0x04; - - priv->cck_txbbgain_table[1].ccktxbb_valuearray[0] = 0x33; - priv->cck_txbbgain_table[1].ccktxbb_valuearray[1] = 0x32; - priv->cck_txbbgain_table[1].ccktxbb_valuearray[2] = 0x2b; - priv->cck_txbbgain_table[1].ccktxbb_valuearray[3] = 0x23; - priv->cck_txbbgain_table[1].ccktxbb_valuearray[4] = 0x1a; - priv->cck_txbbgain_table[1].ccktxbb_valuearray[5] = 0x11; - priv->cck_txbbgain_table[1].ccktxbb_valuearray[6] = 0x08; - priv->cck_txbbgain_table[1].ccktxbb_valuearray[7] = 0x04; - - priv->cck_txbbgain_table[2].ccktxbb_valuearray[0] = 0x30; - priv->cck_txbbgain_table[2].ccktxbb_valuearray[1] = 0x2f; - priv->cck_txbbgain_table[2].ccktxbb_valuearray[2] = 0x29; - priv->cck_txbbgain_table[2].ccktxbb_valuearray[3] = 0x21; - priv->cck_txbbgain_table[2].ccktxbb_valuearray[4] = 0x19; - priv->cck_txbbgain_table[2].ccktxbb_valuearray[5] = 0x10; - priv->cck_txbbgain_table[2].ccktxbb_valuearray[6] = 0x08; - priv->cck_txbbgain_table[2].ccktxbb_valuearray[7] = 0x03; - - priv->cck_txbbgain_table[3].ccktxbb_valuearray[0] = 0x2d; - priv->cck_txbbgain_table[3].ccktxbb_valuearray[1] = 0x2d; - priv->cck_txbbgain_table[3].ccktxbb_valuearray[2] = 0x27; - priv->cck_txbbgain_table[3].ccktxbb_valuearray[3] = 0x1f; - priv->cck_txbbgain_table[3].ccktxbb_valuearray[4] = 0x18; - priv->cck_txbbgain_table[3].ccktxbb_valuearray[5] = 0x0f; - priv->cck_txbbgain_table[3].ccktxbb_valuearray[6] = 0x08; - priv->cck_txbbgain_table[3].ccktxbb_valuearray[7] = 0x03; - - priv->cck_txbbgain_table[4].ccktxbb_valuearray[0] = 0x2b; - priv->cck_txbbgain_table[4].ccktxbb_valuearray[1] = 0x2a; - priv->cck_txbbgain_table[4].ccktxbb_valuearray[2] = 0x25; - priv->cck_txbbgain_table[4].ccktxbb_valuearray[3] = 0x1e; - priv->cck_txbbgain_table[4].ccktxbb_valuearray[4] = 0x16; - priv->cck_txbbgain_table[4].ccktxbb_valuearray[5] = 0x0e; - priv->cck_txbbgain_table[4].ccktxbb_valuearray[6] = 0x07; - priv->cck_txbbgain_table[4].ccktxbb_valuearray[7] = 0x03; - - priv->cck_txbbgain_table[5].ccktxbb_valuearray[0] = 0x28; - priv->cck_txbbgain_table[5].ccktxbb_valuearray[1] = 0x28; - priv->cck_txbbgain_table[5].ccktxbb_valuearray[2] = 0x22; - priv->cck_txbbgain_table[5].ccktxbb_valuearray[3] = 0x1c; - priv->cck_txbbgain_table[5].ccktxbb_valuearray[4] = 0x15; - priv->cck_txbbgain_table[5].ccktxbb_valuearray[5] = 0x0d; - priv->cck_txbbgain_table[5].ccktxbb_valuearray[6] = 0x07; - priv->cck_txbbgain_table[5].ccktxbb_valuearray[7] = 0x03; - - priv->cck_txbbgain_table[6].ccktxbb_valuearray[0] = 0x26; - priv->cck_txbbgain_table[6].ccktxbb_valuearray[1] = 0x25; - priv->cck_txbbgain_table[6].ccktxbb_valuearray[2] = 0x21; - priv->cck_txbbgain_table[6].ccktxbb_valuearray[3] = 0x1b; - priv->cck_txbbgain_table[6].ccktxbb_valuearray[4] = 0x14; - priv->cck_txbbgain_table[6].ccktxbb_valuearray[5] = 0x0d; - priv->cck_txbbgain_table[6].ccktxbb_valuearray[6] = 0x06; - priv->cck_txbbgain_table[6].ccktxbb_valuearray[7] = 0x03; - - priv->cck_txbbgain_table[7].ccktxbb_valuearray[0] = 0x24; - priv->cck_txbbgain_table[7].ccktxbb_valuearray[1] = 0x23; - priv->cck_txbbgain_table[7].ccktxbb_valuearray[2] = 0x1f; - priv->cck_txbbgain_table[7].ccktxbb_valuearray[3] = 0x19; - priv->cck_txbbgain_table[7].ccktxbb_valuearray[4] = 0x13; - priv->cck_txbbgain_table[7].ccktxbb_valuearray[5] = 0x0c; - priv->cck_txbbgain_table[7].ccktxbb_valuearray[6] = 0x06; - priv->cck_txbbgain_table[7].ccktxbb_valuearray[7] = 0x03; - - priv->cck_txbbgain_table[8].ccktxbb_valuearray[0] = 0x22; - priv->cck_txbbgain_table[8].ccktxbb_valuearray[1] = 0x21; - priv->cck_txbbgain_table[8].ccktxbb_valuearray[2] = 0x1d; - priv->cck_txbbgain_table[8].ccktxbb_valuearray[3] = 0x18; - priv->cck_txbbgain_table[8].ccktxbb_valuearray[4] = 0x11; - priv->cck_txbbgain_table[8].ccktxbb_valuearray[5] = 0x0b; - priv->cck_txbbgain_table[8].ccktxbb_valuearray[6] = 0x06; - priv->cck_txbbgain_table[8].ccktxbb_valuearray[7] = 0x02; - - priv->cck_txbbgain_table[9].ccktxbb_valuearray[0] = 0x20; - priv->cck_txbbgain_table[9].ccktxbb_valuearray[1] = 0x20; - priv->cck_txbbgain_table[9].ccktxbb_valuearray[2] = 0x1b; - priv->cck_txbbgain_table[9].ccktxbb_valuearray[3] = 0x16; - priv->cck_txbbgain_table[9].ccktxbb_valuearray[4] = 0x11; - priv->cck_txbbgain_table[9].ccktxbb_valuearray[5] = 0x08; - priv->cck_txbbgain_table[9].ccktxbb_valuearray[6] = 0x05; - priv->cck_txbbgain_table[9].ccktxbb_valuearray[7] = 0x02; - - priv->cck_txbbgain_table[10].ccktxbb_valuearray[0] = 0x1f; - priv->cck_txbbgain_table[10].ccktxbb_valuearray[1] = 0x1e; - priv->cck_txbbgain_table[10].ccktxbb_valuearray[2] = 0x1a; - priv->cck_txbbgain_table[10].ccktxbb_valuearray[3] = 0x15; - priv->cck_txbbgain_table[10].ccktxbb_valuearray[4] = 0x10; - priv->cck_txbbgain_table[10].ccktxbb_valuearray[5] = 0x0a; - priv->cck_txbbgain_table[10].ccktxbb_valuearray[6] = 0x05; - priv->cck_txbbgain_table[10].ccktxbb_valuearray[7] = 0x02; - - priv->cck_txbbgain_table[11].ccktxbb_valuearray[0] = 0x1d; - priv->cck_txbbgain_table[11].ccktxbb_valuearray[1] = 0x1c; - priv->cck_txbbgain_table[11].ccktxbb_valuearray[2] = 0x18; - priv->cck_txbbgain_table[11].ccktxbb_valuearray[3] = 0x14; - priv->cck_txbbgain_table[11].ccktxbb_valuearray[4] = 0x0f; - priv->cck_txbbgain_table[11].ccktxbb_valuearray[5] = 0x0a; - priv->cck_txbbgain_table[11].ccktxbb_valuearray[6] = 0x05; - priv->cck_txbbgain_table[11].ccktxbb_valuearray[7] = 0x02; - - priv->cck_txbbgain_table[12].ccktxbb_valuearray[0] = 0x1b; - priv->cck_txbbgain_table[12].ccktxbb_valuearray[1] = 0x1a; - priv->cck_txbbgain_table[12].ccktxbb_valuearray[2] = 0x17; - priv->cck_txbbgain_table[12].ccktxbb_valuearray[3] = 0x13; - priv->cck_txbbgain_table[12].ccktxbb_valuearray[4] = 0x0e; - priv->cck_txbbgain_table[12].ccktxbb_valuearray[5] = 0x09; - priv->cck_txbbgain_table[12].ccktxbb_valuearray[6] = 0x04; - priv->cck_txbbgain_table[12].ccktxbb_valuearray[7] = 0x02; - - priv->cck_txbbgain_table[13].ccktxbb_valuearray[0] = 0x1a; - priv->cck_txbbgain_table[13].ccktxbb_valuearray[1] = 0x19; - priv->cck_txbbgain_table[13].ccktxbb_valuearray[2] = 0x16; - priv->cck_txbbgain_table[13].ccktxbb_valuearray[3] = 0x12; - priv->cck_txbbgain_table[13].ccktxbb_valuearray[4] = 0x0d; - priv->cck_txbbgain_table[13].ccktxbb_valuearray[5] = 0x09; - priv->cck_txbbgain_table[13].ccktxbb_valuearray[6] = 0x04; - priv->cck_txbbgain_table[13].ccktxbb_valuearray[7] = 0x02; - - priv->cck_txbbgain_table[14].ccktxbb_valuearray[0] = 0x18; - priv->cck_txbbgain_table[14].ccktxbb_valuearray[1] = 0x17; - priv->cck_txbbgain_table[14].ccktxbb_valuearray[2] = 0x15; - priv->cck_txbbgain_table[14].ccktxbb_valuearray[3] = 0x11; - priv->cck_txbbgain_table[14].ccktxbb_valuearray[4] = 0x0c; - priv->cck_txbbgain_table[14].ccktxbb_valuearray[5] = 0x08; - priv->cck_txbbgain_table[14].ccktxbb_valuearray[6] = 0x04; - priv->cck_txbbgain_table[14].ccktxbb_valuearray[7] = 0x02; - - priv->cck_txbbgain_table[15].ccktxbb_valuearray[0] = 0x17; - priv->cck_txbbgain_table[15].ccktxbb_valuearray[1] = 0x16; - priv->cck_txbbgain_table[15].ccktxbb_valuearray[2] = 0x13; - priv->cck_txbbgain_table[15].ccktxbb_valuearray[3] = 0x10; - priv->cck_txbbgain_table[15].ccktxbb_valuearray[4] = 0x0c; - priv->cck_txbbgain_table[15].ccktxbb_valuearray[5] = 0x08; - priv->cck_txbbgain_table[15].ccktxbb_valuearray[6] = 0x04; - priv->cck_txbbgain_table[15].ccktxbb_valuearray[7] = 0x02; - - priv->cck_txbbgain_table[16].ccktxbb_valuearray[0] = 0x16; - priv->cck_txbbgain_table[16].ccktxbb_valuearray[1] = 0x15; - priv->cck_txbbgain_table[16].ccktxbb_valuearray[2] = 0x12; - priv->cck_txbbgain_table[16].ccktxbb_valuearray[3] = 0x0f; - priv->cck_txbbgain_table[16].ccktxbb_valuearray[4] = 0x0b; - priv->cck_txbbgain_table[16].ccktxbb_valuearray[5] = 0x07; - priv->cck_txbbgain_table[16].ccktxbb_valuearray[6] = 0x04; - priv->cck_txbbgain_table[16].ccktxbb_valuearray[7] = 0x01; - - priv->cck_txbbgain_table[17].ccktxbb_valuearray[0] = 0x14; - priv->cck_txbbgain_table[17].ccktxbb_valuearray[1] = 0x14; - priv->cck_txbbgain_table[17].ccktxbb_valuearray[2] = 0x11; - priv->cck_txbbgain_table[17].ccktxbb_valuearray[3] = 0x0e; - priv->cck_txbbgain_table[17].ccktxbb_valuearray[4] = 0x0b; - priv->cck_txbbgain_table[17].ccktxbb_valuearray[5] = 0x07; - priv->cck_txbbgain_table[17].ccktxbb_valuearray[6] = 0x03; - priv->cck_txbbgain_table[17].ccktxbb_valuearray[7] = 0x02; - - priv->cck_txbbgain_table[18].ccktxbb_valuearray[0] = 0x13; - priv->cck_txbbgain_table[18].ccktxbb_valuearray[1] = 0x13; - priv->cck_txbbgain_table[18].ccktxbb_valuearray[2] = 0x10; - priv->cck_txbbgain_table[18].ccktxbb_valuearray[3] = 0x0d; - priv->cck_txbbgain_table[18].ccktxbb_valuearray[4] = 0x0a; - priv->cck_txbbgain_table[18].ccktxbb_valuearray[5] = 0x06; - priv->cck_txbbgain_table[18].ccktxbb_valuearray[6] = 0x03; - priv->cck_txbbgain_table[18].ccktxbb_valuearray[7] = 0x01; - - priv->cck_txbbgain_table[19].ccktxbb_valuearray[0] = 0x12; - priv->cck_txbbgain_table[19].ccktxbb_valuearray[1] = 0x12; - priv->cck_txbbgain_table[19].ccktxbb_valuearray[2] = 0x0f; - priv->cck_txbbgain_table[19].ccktxbb_valuearray[3] = 0x0c; - priv->cck_txbbgain_table[19].ccktxbb_valuearray[4] = 0x09; - priv->cck_txbbgain_table[19].ccktxbb_valuearray[5] = 0x06; - priv->cck_txbbgain_table[19].ccktxbb_valuearray[6] = 0x03; - priv->cck_txbbgain_table[19].ccktxbb_valuearray[7] = 0x01; - - priv->cck_txbbgain_table[20].ccktxbb_valuearray[0] = 0x11; - priv->cck_txbbgain_table[20].ccktxbb_valuearray[1] = 0x11; - priv->cck_txbbgain_table[20].ccktxbb_valuearray[2] = 0x0f; - priv->cck_txbbgain_table[20].ccktxbb_valuearray[3] = 0x0c; - priv->cck_txbbgain_table[20].ccktxbb_valuearray[4] = 0x09; - priv->cck_txbbgain_table[20].ccktxbb_valuearray[5] = 0x06; - priv->cck_txbbgain_table[20].ccktxbb_valuearray[6] = 0x03; - priv->cck_txbbgain_table[20].ccktxbb_valuearray[7] = 0x01; - - priv->cck_txbbgain_table[21].ccktxbb_valuearray[0] = 0x10; - priv->cck_txbbgain_table[21].ccktxbb_valuearray[1] = 0x10; - priv->cck_txbbgain_table[21].ccktxbb_valuearray[2] = 0x0e; - priv->cck_txbbgain_table[21].ccktxbb_valuearray[3] = 0x0b; - priv->cck_txbbgain_table[21].ccktxbb_valuearray[4] = 0x08; - priv->cck_txbbgain_table[21].ccktxbb_valuearray[5] = 0x05; - priv->cck_txbbgain_table[21].ccktxbb_valuearray[6] = 0x03; - priv->cck_txbbgain_table[21].ccktxbb_valuearray[7] = 0x01; - - priv->cck_txbbgain_table[22].ccktxbb_valuearray[0] = 0x0f; - priv->cck_txbbgain_table[22].ccktxbb_valuearray[1] = 0x0f; - priv->cck_txbbgain_table[22].ccktxbb_valuearray[2] = 0x0d; - priv->cck_txbbgain_table[22].ccktxbb_valuearray[3] = 0x0b; - priv->cck_txbbgain_table[22].ccktxbb_valuearray[4] = 0x08; - priv->cck_txbbgain_table[22].ccktxbb_valuearray[5] = 0x05; - priv->cck_txbbgain_table[22].ccktxbb_valuearray[6] = 0x03; - priv->cck_txbbgain_table[22].ccktxbb_valuearray[7] = 0x01; + priv->cck_txbbgain_table = rtl8192_cck_txbbgain_table; //ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29 //This Table is for CH14 -- cgit v1.2.3 From bf2c9de43e9288bc4091c29745d8d09d23d3aa12 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 24 Jan 2011 23:14:16 +0900 Subject: staging: rtl8192e: Convert cck_txbbgain_ch14_table to a table Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 2 +- drivers/staging/rtl8192e/r8192E_dm.c | 240 +++++------------------------------ 2 files changed, 31 insertions(+), 211 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index f3af413a547d..798a35537206 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1270,7 +1270,7 @@ typedef struct r8192_priv u8 Record_CCK_40Mindex; //2007/09/10 Mars Add CCK TX Power Tracking const ccktxbbgain_struct *cck_txbbgain_table; - ccktxbbgain_struct cck_txbbgain_ch14_table[CCKTxBBGainTableLength]; + const ccktxbbgain_struct *cck_txbbgain_ch14_table; u8 rfa_txpowertrackingindex; u8 rfa_txpowertrackingindex_real; u8 rfa_txpowertracking_default; diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index f99f49ea5f42..319cf59c8503 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -1044,223 +1044,43 @@ static const ccktxbbgain_struct rtl8192_cck_txbbgain_table[] = { {{ 0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01 }}, }; +/* + * ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29 + * This Table is for CH14 + */ +static const ccktxbbgain_struct rtl8192_cck_txbbgain_ch14_table[] = { + {{ 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x2d, 0x2d, 0x27, 0x17, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x28, 0x28, 0x22, 0x14, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00 }}, + {{ 0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00 }}, +}; static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); priv->txbbgain_table = rtl8192_txbbgain_table; - priv->cck_txbbgain_table = rtl8192_cck_txbbgain_table; - - //ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29 - //This Table is for CH14 - priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[0] = 0x36; - priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[1] = 0x35; - priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[2] = 0x2e; - priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[3] = 0x1b; - priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[0] = 0x33; - priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[1] = 0x32; - priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[2] = 0x2b; - priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[3] = 0x19; - priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[0] = 0x30; - priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[1] = 0x2f; - priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[2] = 0x29; - priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[3] = 0x18; - priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[0] = 0x2d; - priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[1] = 0x2d; - priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[2] = 0x27; - priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[3] = 0x17; - priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[0] = 0x2b; - priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[1] = 0x2a; - priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[2] = 0x25; - priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[3] = 0x15; - priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[0] = 0x28; - priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[1] = 0x28; - priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[2] = 0x22; - priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[3] = 0x14; - priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[0] = 0x26; - priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[1] = 0x25; - priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[2] = 0x21; - priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[3] = 0x13; - priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[0] = 0x24; - priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[1] = 0x23; - priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[2] = 0x1f; - priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[3] = 0x12; - priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[0] = 0x22; - priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[1] = 0x21; - priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[2] = 0x1d; - priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[3] = 0x11; - priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[0] = 0x20; - priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[1] = 0x20; - priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[2] = 0x1b; - priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[3] = 0x10; - priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[0] = 0x1f; - priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[1] = 0x1e; - priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[2] = 0x1a; - priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[3] = 0x0f; - priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[0] = 0x1d; - priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[1] = 0x1c; - priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[2] = 0x18; - priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[3] = 0x0e; - priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[0] = 0x1b; - priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[1] = 0x1a; - priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[2] = 0x17; - priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[3] = 0x0e; - priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[0] = 0x1a; - priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[1] = 0x19; - priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[2] = 0x16; - priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[3] = 0x0d; - priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[0] = 0x18; - priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[1] = 0x17; - priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[2] = 0x15; - priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[3] = 0x0c; - priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[0] = 0x17; - priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[1] = 0x16; - priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[2] = 0x13; - priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[3] = 0x0b; - priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[0] = 0x16; - priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[1] = 0x15; - priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[2] = 0x12; - priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[3] = 0x0b; - priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[0] = 0x14; - priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[1] = 0x14; - priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[2] = 0x11; - priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[3] = 0x0a; - priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[0] = 0x13; - priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[1] = 0x13; - priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[2] = 0x10; - priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[3] = 0x0a; - priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[0] = 0x12; - priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[1] = 0x12; - priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[2] = 0x0f; - priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[3] = 0x09; - priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[0] = 0x11; - priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[1] = 0x11; - priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[2] = 0x0f; - priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[3] = 0x09; - priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[0] = 0x10; - priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[1] = 0x10; - priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[2] = 0x0e; - priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[3] = 0x08; - priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[7] = 0x00; - - priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[0] = 0x0f; - priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[1] = 0x0f; - priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[2] = 0x0d; - priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[3] = 0x08; - priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[4] = 0x00; - priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[5] = 0x00; - priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[6] = 0x00; - priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[7] = 0x00; + priv->cck_txbbgain_ch14_table = rtl8192_cck_txbbgain_ch14_table; priv->btxpower_tracking = TRUE; priv->txpower_count = 0; -- cgit v1.2.3 From c8881632daf373f5544a3f64d70cd9b3da47aa89 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 24 Jan 2011 23:15:03 +0900 Subject: staging: rtl8192e: Tidy up function header comments Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8192e/ieee80211/rtl819x_BAProc.c | 202 ++++++--------------- 1 file changed, 52 insertions(+), 150 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c index 389b9353690f..2bfa48c8ab71 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c @@ -1,18 +1,16 @@ -/******************************************************************************************************************************** - * This file is created to process BA Action Frame. According to 802.11 spec, there are 3 BA action types at all. And as BA is - * related to TS, this part need some struture defined in QOS side code. Also TX RX is going to be resturctured, so how to send - * ADDBAREQ ADDBARSP and DELBA packet is still on consideration. Temporarily use MANAGE QUEUE instead of Normal Queue. - * WB 2008-05-27 - * *****************************************************************************************************************************/ +/* + * This file is created to process BA Action Frame. According to 802.11 spec, + * there are 3 BA action types at all. And as BA is related to TS, this part + * need some struture defined in QOS side code. Also TX RX is going to be + * resturctured, so how to send ADDBAREQ ADDBARSP and DELBA packet is still + * on consideration. Temporarily use MANAGE QUEUE instead of Normal Queue. + */ #include "ieee80211.h" #include "rtl819x_BA.h" -/******************************************************************************************************************** - *function: Activate BA entry. And if Time is nozero, start timer. - * input: PBA_RECORD pBA //BA entry to be enabled - * u16 Time //indicate time delay. - * output: none -********************************************************************************************************************/ +/* + * Activate BA entry. And if Time is nozero, start timer. + */ void ActivateBAEntry(struct ieee80211_device* ieee, PBA_RECORD pBA, u16 Time) { pBA->bValid = true; @@ -20,23 +18,18 @@ void ActivateBAEntry(struct ieee80211_device* ieee, PBA_RECORD pBA, u16 Time) mod_timer(&pBA->Timer, jiffies + MSECS(Time)); } -/******************************************************************************************************************** - *function: deactivate BA entry, including its timer. - * input: PBA_RECORD pBA //BA entry to be disabled - * output: none -********************************************************************************************************************/ +/* + * deactivate BA entry, including its timer. + */ void DeActivateBAEntry( struct ieee80211_device* ieee, PBA_RECORD pBA) { pBA->bValid = false; del_timer_sync(&pBA->Timer); } -/******************************************************************************************************************** - *function: deactivete BA entry in Tx Ts, and send DELBA. - * input: - * PTX_TS_RECORD pTxTs //Tx Ts which is to deactivate BA entry. - * output: none - * notice: As PTX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME -********************************************************************************************************************/ + +/* + * deactivete BA entry in Tx Ts, and send DELBA. + */ u8 TxTsDeleteBA( struct ieee80211_device* ieee, PTX_TS_RECORD pTxTs) { PBA_RECORD pAdmittedBa = &pTxTs->TxAdmittedBARecord; //These two BA entries must exist in TS structure @@ -60,13 +53,9 @@ u8 TxTsDeleteBA( struct ieee80211_device* ieee, PTX_TS_RECORD pTxTs) return bSendDELBA; } -/******************************************************************************************************************** - *function: deactivete BA entry in Tx Ts, and send DELBA. - * input: - * PRX_TS_RECORD pRxTs //Rx Ts which is to deactivate BA entry. - * output: none - * notice: As PRX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME, same with above -********************************************************************************************************************/ +/* + * deactivete BA entry in Tx Ts, and send DELBA. + */ u8 RxTsDeleteBA( struct ieee80211_device* ieee, PRX_TS_RECORD pRxTs) { PBA_RECORD pBa = &pRxTs->RxAdmittedBARecord; @@ -81,12 +70,9 @@ u8 RxTsDeleteBA( struct ieee80211_device* ieee, PRX_TS_RECORD pRxTs) return bSendDELBA; } -/******************************************************************************************************************** - *function: reset BA entry - * input: - * PBA_RECORD pBA //entry to be reset - * output: none -********************************************************************************************************************/ +/* + * reset BA entry + */ void ResetBaEntry( PBA_RECORD pBA) { pBA->bValid = false; @@ -95,16 +81,11 @@ void ResetBaEntry( PBA_RECORD pBA) pBA->DialogToken = 0; pBA->BaStartSeqCtrl.ShortData = 0; } -//These functions need porting here or not? -/******************************************************************************************************************************* - *function: construct ADDBAREQ and ADDBARSP frame here together. - * input: u8* Dst //ADDBA frame's destination - * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA. - * u16 StatusCode //status code in RSP and I will use it to indicate whether it's RSP or REQ(will I?) - * u8 type //indicate whether it's RSP(ACT_ADDBARSP) ow REQ(ACT_ADDBAREQ) - * output: none - * return: sk_buff* skb //return constructed skb to xmit -*******************************************************************************************************************************/ + +/* + * construct ADDBAREQ and ADDBARSP frame here together. + * return constructed skb to xmit + */ static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, PBA_RECORD pBA, u16 StatusCode, u8 type) { struct sk_buff *skb = NULL; @@ -174,58 +155,9 @@ static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, P //return NULL; } -#if 0 //I try to merge ADDBA_REQ and ADDBA_RSP frames together.. -/******************************************************************************************************************** - *function: construct ADDBAREQ frame - * input: u8* dst //ADDBARsp frame's destination - * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA_RSP. - * u16 StatusCode //status code. - * output: none - * return: sk_buff* skb //return constructed skb to xmit -********************************************************************************************************************/ -static struct sk_buff* ieee80211_ADDBA_Rsp( IN struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, u16 StatusCode) -{ - OCTET_STRING osADDBAFrame, tmp; - - FillOctetString(osADDBAFrame, Buffer, 0); - *pLength = 0; - - ConstructMaFrameHdr( - Adapter, - Addr, - ACT_CAT_BA, - ACT_ADDBARSP, - &osADDBAFrame ); - - // Dialog Token - FillOctetString(tmp, &pBA->DialogToken, 1); - PacketAppendData(&osADDBAFrame, tmp); - - // Status Code - FillOctetString(tmp, &StatusCode, 2); - PacketAppendData(&osADDBAFrame, tmp); - - // BA Parameter Set - FillOctetString(tmp, &pBA->BaParamSet, 2); - PacketAppendData(&osADDBAFrame, tmp); - - // BA Timeout Value - FillOctetString(tmp, &pBA->BaTimeoutValue, 2); - PacketAppendData(&osADDBAFrame, tmp); - - *pLength = osADDBAFrame.Length; -} -#endif - -/******************************************************************************************************************** - *function: construct DELBA frame - * input: u8* dst //DELBA frame's destination - * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA - * TR_SELECT TxRxSelect //TX RX direction - * u16 ReasonCode //status code. - * output: none - * return: sk_buff* skb //return constructed skb to xmit -********************************************************************************************************************/ +/* + * construct DELBA frame + */ static struct sk_buff* ieee80211_DELBA( struct ieee80211_device* ieee, u8* dst, @@ -286,13 +218,11 @@ static struct sk_buff* ieee80211_DELBA( return skb; } -/******************************************************************************************************************** - *function: send ADDBAReq frame out - * input: u8* dst //ADDBAReq frame's destination - * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA - * output: none - * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does -********************************************************************************************************************/ +/* + * send ADDBAReq frame out + * If any possible, please hide pBA in ieee. + * And temporarily use Manage Queue as softmac_mgmt_xmit() usually does + */ void ieee80211_send_ADDBAReq(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA) { struct sk_buff *skb = NULL; @@ -311,14 +241,11 @@ void ieee80211_send_ADDBAReq(struct ieee80211_device* ieee, u8* dst, PBA_RECORD } } -/******************************************************************************************************************** - *function: send ADDBARSP frame out - * input: u8* dst //DELBA frame's destination - * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA - * u16 StatusCode //RSP StatusCode - * output: none - * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does -********************************************************************************************************************/ +/* + * send ADDBARSP frame out + * If any possible, please hide pBA in ieee. + * And temporarily use Manage Queue as softmac_mgmt_xmit() usually does + */ void ieee80211_send_ADDBARsp(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, u16 StatusCode) { struct sk_buff *skb = NULL; @@ -333,16 +260,12 @@ void ieee80211_send_ADDBARsp(struct ieee80211_device* ieee, u8* dst, PBA_RECORD IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__); } } -/******************************************************************************************************************** - *function: send ADDBARSP frame out - * input: u8* dst //DELBA frame's destination - * PBA_RECORD pBA //BA_RECORD entry which stores the necessary information for BA - * TR_SELECT TxRxSelect //TX or RX - * u16 ReasonCode //DEL ReasonCode - * output: none - * notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does -********************************************************************************************************************/ +/* + * send ADDBARSP frame out + * If any possible, please hide pBA in ieee. + * And temporarily use Manage Queue as softmac_mgmt_xmit() usually does + */ void ieee80211_send_DELBA(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, TR_SELECT TxRxSelect, u16 ReasonCode) { struct sk_buff *skb = NULL; @@ -359,12 +282,6 @@ void ieee80211_send_DELBA(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA return ; } -/******************************************************************************************************************** - *function: RX ADDBAReq - * input: struct sk_buff * skb //incoming ADDBAReq skb. - * return: 0(pass), other(fail) - * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support. -********************************************************************************************************************/ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb) { struct ieee80211_hdr_3addr* req = NULL; @@ -459,12 +376,6 @@ OnADDBAReq_Fail: } -/******************************************************************************************************************** - *function: RX ADDBARSP - * input: struct sk_buff * skb //incoming ADDBAReq skb. - * return: 0(pass), other(fail) - * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support. -********************************************************************************************************************/ int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb) { struct ieee80211_hdr_3addr* rsp = NULL; @@ -592,12 +503,6 @@ OnADDBARsp_Reject: } -/******************************************************************************************************************** - *function: RX DELBA - * input: struct sk_buff * skb //incoming ADDBAReq skb. - * return: 0(pass), other(fail) - * notice: As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support. -********************************************************************************************************************/ int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb) { struct ieee80211_hdr_3addr* delba = NULL; @@ -669,9 +574,7 @@ int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb) return 0; } -// -// ADDBA initiate. This can only be called by TX side. -// +/* ADDBA initiate. This can only be called by TX side. */ void TsInitAddBA( struct ieee80211_device* ieee, @@ -730,12 +633,11 @@ TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SE DELBA_REASON_END_BA ); } } -/******************************************************************************************************************** - *function: BA setup timer - * input: unsigned long data //acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer - * return: NULL - * notice: -********************************************************************************************************************/ + +/* + * BA setup timer + * acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer + */ void BaSetupTimeOut(unsigned long data) { PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data; -- cgit v1.2.3 From 85c876e412c18d95cd430598255f829e64ae9141 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 24 Jan 2011 23:15:40 +0900 Subject: staging: rtl8192e: Delete dead code in ieee80211 lib Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- .../rtl8192e/ieee80211/ieee80211_crypt_tkip.c | 24 --- .../rtl8192e/ieee80211/ieee80211_crypt_wep.c | 1 - .../staging/rtl8192e/ieee80211/ieee80211_module.c | 2 +- drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c | 194 ++----------------- .../staging/rtl8192e/ieee80211/ieee80211_softmac.c | 214 +-------------------- .../rtl8192e/ieee80211/ieee80211_softmac_wx.c | 31 +-- drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c | 46 +---- drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c | 6 +- 8 files changed, 30 insertions(+), 488 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c index 2ad9501801b4..b32b7e67f688 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c @@ -324,18 +324,6 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) hdr = (struct ieee80211_hdr_4addr *) skb->data; -#if 0 -printk("@@ tkey\n"); -printk("%x|", ((u32*)tkey->key)[0]); -printk("%x|", ((u32*)tkey->key)[1]); -printk("%x|", ((u32*)tkey->key)[2]); -printk("%x|", ((u32*)tkey->key)[3]); -printk("%x|", ((u32*)tkey->key)[4]); -printk("%x|", ((u32*)tkey->key)[5]); -printk("%x|", ((u32*)tkey->key)[6]); -printk("%x\n", ((u32*)tkey->key)[7]); -#endif - if (!tcb_desc->bHwSec) { if (!tkey->tx_phase1_done) { @@ -512,18 +500,6 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) skb_pull(skb, 8); skb_trim(skb, skb->len - 4); -//john's test -#ifdef JOHN_DUMP -if( ((u16*)skb->data)[0] & 0x4000){ - printk("@@ rx decrypted skb->data"); - int i; - for(i=0;ilen;i++){ - if( (i%24)==0 ) printk("\n"); - printk("%2x ", ((u8*)skb->data)[i]); - } - printk("\n"); -} -#endif /*JOHN_DUMP*/ return keyidx; } diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c index 5dc976498aae..e6264727d94d 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c @@ -9,7 +9,6 @@ * more details. */ -//#include #include #include #include diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c index 08bfdb1a4c6e..67bcd41e66b1 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c @@ -222,7 +222,7 @@ void free_ieee80211(struct net_device *dev) #ifdef CONFIG_IEEE80211_DEBUG u32 ieee80211_debug_level = 0; -static int debug = \ +static int debug = /* IEEE80211_DL_INFO | */ /* IEEE80211_DL_WX | */ /* IEEE80211_DL_SCAN | */ diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c index 4db6944cb6dc..e2eac7cadf4f 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c @@ -22,7 +22,6 @@ #include -//#include #include #include #include @@ -225,7 +224,6 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb, rx_stats->len = skb->len; ieee80211_rx_mgt(ieee,(struct ieee80211_hdr_4addr *)skb->data,rx_stats); - //if ((ieee->state == IEEE80211_LINKED) && (memcmp(hdr->addr3, ieee->current_network.bssid, ETH_ALEN))) if ((memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN)))//use ADDR1 to perform address matching for Management frames { dev_kfree_skb_any(skb); @@ -243,9 +241,6 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb, printk(KERN_DEBUG "%s: Master mode not yet suppported.\n", ieee->dev->name); return 0; -/* - hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr_4addr *) - skb->data);*/ } if (ieee->hostapd && type == IEEE80211_TYPE_MGMT) { @@ -308,7 +303,6 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee, if (skb->len < 24) return 0; -#if 1 if (ieee->hwsec_active) { cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE); @@ -317,7 +311,6 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee, if(ieee->need_sw_enc) tcb_desc->bHwSec = 0; } -#endif hdr = (struct ieee80211_hdr_4addr *) skb->data; fc = le16_to_cpu(hdr->frame_ctl); @@ -339,7 +332,6 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee, return 0; /* check for port access entity Ethernet type */ -// pos = skb->data + 24; pos = skb->data + hdrlen; ethertype = (pos[6] << 8) | pos[7]; if (ethertype == ETH_P_PAE) @@ -358,13 +350,13 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb, if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL) return 0; -#if 1 + if (ieee->hwsec_active) { cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE); tcb_desc->bHwSec = 1; } -#endif + hdr = (struct ieee80211_hdr_4addr *) skb->data; hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); @@ -474,14 +466,13 @@ static int is_duplicate_packet(struct ieee80211_device *ieee, struct ieee_ibss_seq *entry = NULL; u8 *mac = header->addr2; int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE; - //for (pos = (head)->next; pos != (head); pos = pos->next) - //__list_for_each(p, &ieee->ibss_mac_hash[index]) { + list_for_each(p, &ieee->ibss_mac_hash[index]) { entry = list_entry(p, struct ieee_ibss_seq, list); if (!memcmp(entry->mac, mac, ETH_ALEN)) break; } - // if (memcmp(entry->mac, mac, ETH_ALEN)){ + if (p == &ieee->ibss_mac_hash[index]) { entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC); if (!entry) { @@ -537,7 +528,7 @@ AddReorderEntry( ) { struct list_head *pList = &pTS->RxPendingPktList; -#if 1 + while(pList->next != &pTS->RxPendingPktList) { if( SN_LESS(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)list_entry(pList->next,RX_REORDER_ENTRY,List))->SeqNum) ) @@ -553,7 +544,7 @@ AddReorderEntry( break; } } -#endif + pReorderEntry->List.next = pList->next; pReorderEntry->List.next->prev = &pReorderEntry->List; pReorderEntry->List.prev = pList; @@ -566,8 +557,7 @@ void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_ { u8 i = 0 , j=0; u16 ethertype; -// if(index > 1) -// IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): hahahahhhh, We indicate packet from reorder list, index is %u\n",__FUNCTION__,index); + for(j = 0; jsrc, ETH_ALEN); memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN); } - //stats->rx_packets++; - //stats->rx_bytes += sub_skb->len; /* Indicat the packets to upper layer */ if (sub_skb) { @@ -603,7 +591,6 @@ void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_ memset(sub_skb->cb, 0, sizeof(sub_skb->cb)); sub_skb->dev = ieee->dev; sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */ - //skb->ip_summed = CHECKSUM_UNNECESSARY; /* 802.11 crc not sufficient */ ieee->last_rx_ps_time = jiffies; netif_rx(sub_skb); } @@ -627,10 +614,7 @@ void RxReorderIndicatePacket( struct ieee80211_device *ieee, u8 index = 0; bool bMatchWinStart = false, bPktInBuf = false; IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): Seq is %d,pTS->RxIndicateSeq is %d, WinSize is %d\n",__FUNCTION__,SeqNum,pTS->RxIndicateSeq,WinSize); -#if 0 - if(!list_empty(&ieee->RxReorder_Unused_List)) - IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): ieee->RxReorder_Unused_List is nut NULL\n"); -#endif + /* Rx Reorder initialize condition.*/ if(pTS->RxIndicateSeq == 0xffff) { pTS->RxIndicateSeq = SeqNum; @@ -686,7 +670,6 @@ void RxReorderIndicatePacket( struct ieee80211_device *ieee, index = 1; } else { /* Current packet is going to be inserted into pending list.*/ - //IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): We RX no ordered packed, insert to orderd list\n",__FUNCTION__); if(!list_empty(&ieee->RxReorder_Unused_List)) { pReorderEntry = (PRX_REORDER_ENTRY)list_entry(ieee->RxReorder_Unused_List.next,RX_REORDER_ENTRY,List); list_del_init(&pReorderEntry->List); @@ -694,9 +677,7 @@ void RxReorderIndicatePacket( struct ieee80211_device *ieee, /* Make a reorder entry and insert into a the packet list.*/ pReorderEntry->SeqNum = SeqNum; pReorderEntry->prxb = prxb; - // IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): pREorderEntry->SeqNum is %d\n",__FUNCTION__,pReorderEntry->SeqNum); -#if 1 if(!AddReorderEntry(pTS, pReorderEntry)) { IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, pTS->RxIndicateSeq, SeqNum); @@ -713,7 +694,6 @@ void RxReorderIndicatePacket( struct ieee80211_device *ieee, IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum); } -#endif } else { /* @@ -781,21 +761,13 @@ void RxReorderIndicatePacket( struct ieee80211_device *ieee, bPktInBuf = false; } -#if 1 if(bPktInBuf && pTS->RxTimeoutIndicateSeq==0xffff) { // Set new pending timer. IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): SET rx timeout timer\n", __FUNCTION__); pTS->RxTimeoutIndicateSeq = pTS->RxIndicateSeq; -#if 0 - if(timer_pending(&pTS->RxPktPendingTimer)) - del_timer_sync(&pTS->RxPktPendingTimer); - pTS->RxPktPendingTimer.expires = jiffies + MSECS(pHTInfo->RxReorderPendingTime); - add_timer(&pTS->RxPktPendingTimer); -#else + mod_timer(&pTS->RxPktPendingTimer, jiffies + MSECS(pHTInfo->RxReorderPendingTime)); -#endif } -#endif } u8 parse_subframe(struct ieee80211_device* ieee,struct sk_buff *skb, @@ -862,11 +834,6 @@ u8 parse_subframe(struct ieee80211_device* ieee,struct sk_buff *skb, nSubframe_Length = (nSubframe_Length>>8) + (nSubframe_Length<<8); if(skb->len<(ETHERNET_HEADER_SIZE + nSubframe_Length)) { -#if 0//cosa - RT_ASSERT( - (nRemain_Length>=(ETHERNET_HEADER_SIZE + nSubframe_Length)), - ("ParseSubframe(): A-MSDU subframe parse error!! Subframe Length: %d\n", nSubframe_Length) ); -#endif printk("%s: A-MSDU parse error!! pRfd->nTotalSubframe : %d\n",\ __FUNCTION__,rxb->nr_subframes); printk("%s: A-MSDU parse error!! Subframe Length: %d\n",__FUNCTION__, nSubframe_Length); @@ -924,7 +891,6 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, { struct net_device *dev = ieee->dev; struct ieee80211_hdr_4addr *hdr; - //struct ieee80211_hdr_3addrqos *hdr; size_t hdrlen; u16 fc, type, stype, sc; @@ -937,7 +903,6 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, u16 SeqNum = 0; PRX_TS_RECORD pTS = NULL; bool unicast_packet = false; - //bool bIsAggregateFrame = false; //added by amy for reorder #ifdef NOT_YET struct net_device *wds = NULL; @@ -947,7 +912,6 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, int from_assoc_ap = 0; void *sta = NULL; #endif -// u16 qos_ctl = 0; u8 dst[ETH_ALEN]; u8 src[ETH_ALEN]; u8 bssid[ETH_ALEN]; @@ -982,7 +946,6 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, rx_stats->bContainHTC = 1; } - //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len); #ifdef NOT_YET #if WIRELESS_EXT > 15 /* Put this code here so that we avoid duplicating it in all @@ -1061,19 +1024,7 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, else { PRX_TS_RECORD pRxTS = NULL; - #if 0 - struct ieee80211_hdr_3addr *hdr; - u16 fc; - hdr = (struct ieee80211_hdr_3addr *)skb->data; - fc = le16_to_cpu(hdr->frame_ctl); - u8 tmp = (fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS); - - u8 tid = (*((u8*)skb->data + (((fc& IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))?30:24)))&0xf; - printk("====================>fc:%x, tid:%d, tmp:%d\n", fc, tid, tmp); - //u8 tid = (u8)((frameqos*)(buf + ((fc & IEEE80211_FCTL_TODS)&&(fc & IEEE80211_FCTL_FROMDS))? 30 : 24))->field.tid; - #endif - //IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): QOS ENABLE AND RECEIVE QOS DATA , we will get Ts, tid:%d\n",__FUNCTION__, tid); -#if 1 + if(GetTs( ieee, (PTS_COMMON_INFO*) &pRxTS, @@ -1083,7 +1034,6 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, true)) { - // IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): pRxTS->RxLastFragNum is %d,frag is %d,pRxTS->RxLastSeqNum is %d,seq is %d\n",__FUNCTION__,pRxTS->RxLastFragNum,frag,pRxTS->RxLastSeqNum,WLAN_GET_SEQ_SEQ(sc)); if( (fc & (1<<11)) && (frag == pRxTS->RxLastFragNum) && (WLAN_GET_SEQ_SEQ(sc) == pRxTS->RxLastSeqNum) ) @@ -1102,24 +1052,9 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, goto rx_dropped; } } -#endif - if (type == IEEE80211_FTYPE_MGMT) { - #if 0 - if ( stype == IEEE80211_STYPE_AUTH && - fc & IEEE80211_FCTL_WEP && ieee->host_decrypt && - (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0) - { - printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth " - "from %pM\n", dev->name, - hdr->addr2); - /* TODO: could inform hostapd about this so that it - * could send auth failure report */ - goto rx_dropped; - } - #endif + if (type == IEEE80211_FTYPE_MGMT) { - //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len); if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype)) goto rx_dropped; else @@ -1192,7 +1127,6 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, } } #endif - //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len); /* Nullfunc frames may have PS-bit set, so they must be passed to * hostap_handle_sta_rx() before being dropped here. */ if (stype != IEEE80211_STYPE_DATA && @@ -1354,13 +1288,7 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, hdr->addr2); goto rx_dropped; } -/* - if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { - printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n"); - } -*/ //added by amy for reorder -#if 1 if(ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data) && !is_multicast_ether_addr(hdr->addr1) && !is_broadcast_ether_addr(hdr->addr1)) { @@ -1372,11 +1300,11 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, ieee->bis_any_nonbepkts = true; } } -#endif + //added by amy for reorder /* skb: hdr + (possible reassembled) full plaintext payload */ payload = skb->data + hdrlen; - //ethertype = (payload[6] << 8) | payload[7]; + rxb = kmalloc(sizeof(struct ieee80211_rxb), GFP_ATOMIC); if(rxb == NULL) { @@ -1407,7 +1335,6 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, ieee->LinkDetectInfo.NumRxUnicastOkInPeriod++; // 2009.03.03 Leave DC mode immediately when detect high traffic - // DbgPrint("ending Seq %d\n", Frame_SeqNum(pduOS)); if((ieee->state == IEEE80211_LINKED) /*&& !MgntInitAdapterInProgress(pMgntInfo)*/) { if( ((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod +ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) || @@ -1460,7 +1387,6 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, memset(sub_skb->cb, 0, sizeof(sub_skb->cb)); sub_skb->dev = dev; sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */ - //skb->ip_summed = CHECKSUM_UNNECESSARY; /* 802.11 crc not sufficient */ netif_rx(sub_skb); } } @@ -1593,8 +1519,6 @@ static int ieee80211_qos_convert_ac_to_parameters(struct int i; struct ieee80211_qos_ac_parameter *ac_params; u8 aci; - //u8 cw_min; - //u8 cw_max; for (i = 0; i < QOS_QUEUE_NUM; i++) { ac_params = &(param_elm->ac_params_record[i]); @@ -1745,7 +1669,6 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, u16 tmp_htinfo_len=0; u16 ht_realtek_agg_len=0; u8 ht_realtek_agg_buf[MAX_IE_LEN]; -// u16 broadcom_len = 0; #ifdef CONFIG_IEEE80211_DEBUG char rates_str[64]; char *p; @@ -1862,12 +1785,8 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, network->dtim_period = info_element->data[1]; if(ieee->state != IEEE80211_LINKED) break; -#if 0 - network->last_dtim_sta_time[0] = stats->mac_time[0]; -#else //we use jiffies for legacy Power save network->last_dtim_sta_time[0] = jiffies; -#endif network->last_dtim_sta_time[1] = stats->mac_time[1]; network->dtim_data = IEEE80211_DTIM_VALID; @@ -2004,8 +1923,6 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, } - //if(tmp_htcap_len !=0 || tmp_htinfo_len != 0) - { if((info_element->len >= 3 && info_element->data[0] == 0x00 && info_element->data[1] == 0x05 && @@ -2022,17 +1939,7 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, network->broadcom_cap_exist = true; } - } -#if 0 - if (tmp_htcap_len !=0) - { - u16 cap_ext = ((PHT_CAPABILITY_ELE)&info_element->data[0])->ExtHTCapInfo; - if ((cap_ext & 0x0c00) == 0x0c00) - { - network->ralink_cap_exist = true; - } - } -#endif + if(info_element->len >= 3 && info_element->data[0] == 0x00 && info_element->data[1] == 0x0c && @@ -2211,45 +2118,7 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, ieee80211_extract_country_ie(ieee, info_element, network, network->bssid);//addr2 is same as addr3 when from an AP break; #endif -/* TODO */ -#if 0 - /* 802.11h */ - case MFIE_TYPE_POWER_CONSTRAINT: - network->power_constraint = info_element->data[0]; - network->flags |= NETWORK_HAS_POWER_CONSTRAINT; - break; - case MFIE_TYPE_CSA: - network->power_constraint = info_element->data[0]; - network->flags |= NETWORK_HAS_CSA; - break; - - case MFIE_TYPE_QUIET: - network->quiet.count = info_element->data[0]; - network->quiet.period = info_element->data[1]; - network->quiet.duration = info_element->data[2]; - network->quiet.offset = info_element->data[3]; - network->flags |= NETWORK_HAS_QUIET; - break; - - case MFIE_TYPE_IBSS_DFS: - if (network->ibss_dfs) - break; - network->ibss_dfs = kmemdup(info_element->data, - info_element->len, - GFP_ATOMIC); - if (!network->ibss_dfs) - return 1; - network->flags |= NETWORK_HAS_IBSS_DFS; - break; - - case MFIE_TYPE_TPC_REPORT: - network->tpc_report.transmit_power = - info_element->data[0]; - network->tpc_report.link_margin = info_element->data[1]; - network->flags |= NETWORK_HAS_TPC_REPORT; - break; -#endif default: IEEE80211_DEBUG_MGMT ("Unsupported info element: %s (%d)\n", @@ -2324,11 +2193,6 @@ static inline u8 ieee80211_SignalStrengthTranslate( { RetSS = CurrSS; } - //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS)); - - // Step 2. Smoothing. - - //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS)); return RetSS; } @@ -2350,11 +2214,6 @@ static inline int ieee80211_network_init( struct ieee80211_network *network, struct ieee80211_rx_stats *stats) { -#ifdef CONFIG_IEEE80211_DEBUG - //char rates_str[64]; - //char *p; -#endif - network->qos_data.active = 0; network->qos_data.supported = 0; network->qos_data.param_count = 0; @@ -2391,7 +2250,6 @@ static inline int ieee80211_network_init( memset(network->CountryIeBuf, 0, MAX_IE_LEN); #endif //Initialize HT parameters - //ieee80211_ht_initialize(&network->bssht); HTInitializeBssDesc(&network->bssht); if (stats->freq == IEEE80211_52GHZ_BAND) { /* for A band (No DS info) */ @@ -2434,11 +2292,8 @@ static inline int ieee80211_network_init( if (ieee80211_is_empty_essid(network->ssid, network->ssid_len)) network->flags |= NETWORK_EMPTY_ESSID; -#if 1 stats->signal = 30 + (stats->SignalStrength * 70) / 100; - //stats->signal = ieee80211_SignalStrengthTranslate(stats->signal); stats->noise = ieee80211_translate_todbm((u8)(100-stats->signal)) -25; -#endif memcpy(&network->stats, stats, sizeof(network->stats)); @@ -2452,11 +2307,9 @@ static inline int is_same_network(struct ieee80211_network *src, * and the capability field (in particular IBSS and BSS) all match. * We treat all with the same BSSID and channel * as one network */ - return //((src->ssid_len == dst->ssid_len) && - (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && + return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && (src->channel == dst->channel) && !memcmp(src->bssid, dst->bssid, ETH_ALEN) && - //!memcmp(src->ssid, dst->ssid, src->ssid_len) && (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && ((src->capability & WLAN_CAPABILITY_IBSS) == (dst->capability & WLAN_CAPABILITY_IBSS)) && @@ -2521,9 +2374,7 @@ static inline void update_network(struct ieee80211_network *dst, dst->last_scanned = jiffies; /* qos related parameters */ - //qos_active = src->qos_data.active; qos_active = dst->qos_data.active; - //old_param = dst->qos_data.old_param_count; old_param = dst->qos_data.param_count; if(dst->flags & NETWORK_HAS_QOS_MASK){ //not update QOS paramter in beacon, as most AP will set all these parameter to 0.//WB @@ -2547,7 +2398,6 @@ static inline void update_network(struct ieee80211_network *dst, dst->qos_data.old_param_count = old_param; /* dst->last_associate is not overwritten */ -#if 1 dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame. if(src->wmm_param[0].ac_aci_acm_aifsn|| \ src->wmm_param[1].ac_aci_acm_aifsn|| \ @@ -2555,10 +2405,6 @@ static inline void update_network(struct ieee80211_network *dst, src->wmm_param[3].ac_aci_acm_aifsn) { memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN); } - //dst->QoS_Enable = src->QoS_Enable; -#else - dst->QoS_Enable = 1;//for Rtl8187 simulation -#endif #ifdef THOMAS_TURBO dst->Turbo_Enable = src->Turbo_Enable; #endif @@ -2599,7 +2445,6 @@ static inline void ieee80211_process_probe_response( #endif unsigned long flags; short renew; - //u8 wmm_info; memset(&network, 0, sizeof(struct ieee80211_network)); IEEE80211_DEBUG_SCAN( @@ -2801,15 +2646,6 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee, struct ieee80211_hdr_4addr *header, struct ieee80211_rx_stats *stats) { -#if 0 - if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED && - ieee->iw_mode == IW_MODE_INFRA && - ieee->state == IEEE80211_LINKED)) - { - tasklet_schedule(&ieee->ps_task); - } -#endif - if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP && WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON) ieee->last_rx_ps_time = jiffies; diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index 32e5d0aca6c4..c92e8f6c6c3c 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -163,8 +163,6 @@ void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb) */ ieee->mgmt_queue_head = nh; ieee->mgmt_queue_ring[nh] = skb; - - //return 0; } struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee) @@ -208,16 +206,6 @@ u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee) rate = 0x02; } - /* - // Data rate of ProbeReq is already decided. Annie, 2005-03-31 - if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) ) - { - if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A) - rate = 0x0c; - else - rate = 0x02; - } - */ return rate; } @@ -255,9 +243,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee ieee->seq_ctrl[0]++; /* avoid watchdog triggers */ - // ieee->dev->trans_start = jiffies; ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate); - //dev_kfree_skb_any(skb);//edit by thomas } spin_unlock_irqrestore(&ieee->lock, flags); @@ -283,7 +269,6 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb); } else { ieee->softmac_hard_start_xmit(skb,ieee->dev); - //dev_kfree_skb_any(skb);//edit by thomas } spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags); } @@ -312,7 +297,6 @@ inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *i ieee->seq_ctrl[0]++; /* avoid watchdog triggers */ - // ieee->dev->trans_start = jiffies; ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate); }else{ @@ -327,7 +311,6 @@ inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *i ieee->softmac_hard_start_xmit(skb,ieee->dev); } - //dev_kfree_skb_any(skb);//edit by thomas } inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee) @@ -374,24 +357,17 @@ void ieee80211_send_beacon(struct ieee80211_device *ieee) struct sk_buff *skb; if(!ieee->ieee_up) return; - //unsigned long flags; + skb = ieee80211_get_beacon_(ieee); if (skb){ softmac_mgmt_xmit(skb, ieee); ieee->softmac_stats.tx_beacons++; - //dev_kfree_skb_any(skb);//edit by thomas } -// ieee->beacon_timer.expires = jiffies + -// (MSECS( ieee->current_network.beacon_interval -5)); - //spin_lock_irqsave(&ieee->beacon_lock,flags); if(ieee->beacon_txing && ieee->ieee_up){ -// if(!timer_pending(&ieee->beacon_timer)) -// add_timer(&ieee->beacon_timer); mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5))); } - //spin_unlock_irqrestore(&ieee->beacon_lock,flags); } @@ -415,7 +391,6 @@ void ieee80211_send_probe(struct ieee80211_device *ieee) if (skb){ softmac_mgmt_xmit(skb, ieee); ieee->softmac_stats.tx_probe_rq++; - //dev_kfree_skb_any(skb);//edit by thomas } } @@ -610,12 +585,7 @@ void ieee80211_start_send_beacons(struct ieee80211_device *ieee) void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee) { -// unsigned long flags; - - //ieee->sync_scan_hurryup = 1; - down(&ieee->scan_sem); -// spin_lock_irqsave(&ieee->lock, flags); if (ieee->scanning == 1){ ieee->scanning = 0; @@ -623,7 +593,6 @@ void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee) cancel_delayed_work(&ieee->softmac_scan_wq); } -// spin_unlock_irqrestore(&ieee->lock, flags); up(&ieee->scan_sem); } @@ -706,7 +675,6 @@ inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *be memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN); - //auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY; if(ieee->auth_mode == 0) auth->algorithm = WLAN_AUTH_OPEN; else if(ieee->auth_mode == 1) @@ -756,23 +724,10 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d else atim_len = 0; -#if 1 if(ieee80211_is_54g(ieee->current_network)) erp_len = 3; else erp_len = 0; -#else - if((ieee->current_network.mode == IEEE_G) - ||( ieee->current_network.mode == IEEE_N_24G && ieee->pHTInfo->bCurSuppCCK)) { - erp_len = 3; - erpinfo_content = 0; - if(ieee->current_network.buseprotection) - erpinfo_content |= ERP_UseProtection; - } - else - erp_len = 0; -#endif - crypt = ieee->crypt[ieee->tx_keyidx]; @@ -780,7 +735,7 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len)); //HT ralated element -#if 1 + tmp_ht_cap_buf =(u8*) &(ieee->pHTInfo->SelfHTCap); tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap); tmp_ht_info_buf =(u8*) &(ieee->pHTInfo->SelfHTInfo); @@ -795,7 +750,7 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer); HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len); } -#endif + beacon_size = sizeof(struct ieee80211_probe_response)+2+ ssid_len +3 //channel @@ -804,10 +759,6 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d +atim_len +erp_len +wpa_ie_len - // +tmp_ht_cap_len - // +tmp_ht_info_len - // +tmp_generic_ie_len -// +wmm_len+2 +ieee->tx_headroom; skb = dev_alloc_skb(beacon_size); if (!skb) @@ -830,10 +781,6 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT)); crypt = ieee->crypt[ieee->tx_keyidx]; -#if 0 - encrypt = ieee->host_encrypt && crypt && crypt->ops && - (0 == strcmp(crypt->ops->name, "WEP")); -#endif if (encrypt) beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); @@ -861,7 +808,6 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d u16 val16; *(tag++) = MFIE_TYPE_IBSS_SET; *(tag++) = 2; - //*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window); val16 = cpu_to_le16(ieee->current_network.atim_window); memcpy((u8 *)tag, (u8 *)&val16, 2); tag+=2; @@ -872,14 +818,6 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d *(tag++) = 1; *(tag++) = erpinfo_content; } -#if 0 - //Include High Throuput capability - - *(tag++) = MFIE_TYPE_HT_CAP; - *(tag++) = tmp_ht_cap_len - 2; - memcpy(tag, tmp_ht_cap_buf, tmp_ht_cap_len - 2); - tag += tmp_ht_cap_len - 2; -#endif if(rate_ex_len){ *(tag++) = MFIE_TYPE_RATES_EX; *(tag++) = rate_ex_len-2; @@ -887,14 +825,6 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d tag+=rate_ex_len-2; } -#if 0 - //Include High Throuput info - - *(tag++) = MFIE_TYPE_HT_INFO; - *(tag++) = tmp_ht_info_len - 2; - memcpy(tag, tmp_ht_info_buf, tmp_ht_info_len -2); - tag += tmp_ht_info_len - 2; -#endif if (wpa_ie_len) { if (ieee->iw_mode == IW_MODE_ADHOC) @@ -905,29 +835,6 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d tag += wpa_ie_len; } -#if 0 - // - // Construct Realtek Proprietary Aggregation mode (Set AMPDU Factor to 2, 32k) - // - if(pHTInfo->bRegRT2RTAggregation) - { - (*tag++) = 0xdd; - (*tag++) = tmp_generic_ie_len - 2; - memcpy(tag,tmp_generic_ie_buf,tmp_generic_ie_len -2); - tag += tmp_generic_ie_len -2; - - } -#endif -#if 0 - if(ieee->qos_support) - { - (*tag++) = 0xdd; - (*tag++) = wmm_len; - memcpy(tag,QosOui,wmm_len); - tag += wmm_len; - } -#endif - //skb->dev = ieee->dev; return skb; } @@ -1106,16 +1013,8 @@ void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest) inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee) { struct sk_buff *skb; - //unsigned long flags; - struct ieee80211_assoc_request_frame *hdr; - u8 *tag;//,*rsn_ie; - //short info_addr = 0; - //int i; - //u16 suite_count = 0; - //u8 suit_select = 0; - //unsigned int wpa_len = beacon->wpa_ie_len; - //for HT + u8 *tag; u8* ht_cap_buf = NULL; u8 ht_cap_len=0; u8* realtek_ie_buf=NULL; @@ -1399,7 +1298,6 @@ void ieee80211_associate_step1(struct ieee80211_device *ieee) ieee->associate_timer.expires = jiffies + (HZ / 2); add_timer(&ieee->associate_timer); } - //dev_kfree_skb_any(skb);//edit by thomas } } @@ -1408,7 +1306,6 @@ void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, u8 *c; struct sk_buff *skb; struct ieee80211_network *beacon = &ieee->current_network; -// int hlen = sizeof(struct ieee80211_authentication); ieee->associate_seq++; ieee->softmac_stats.tx_auth_rq++; @@ -1428,11 +1325,6 @@ void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, softmac_mgmt_xmit(skb, ieee); mod_timer(&ieee->associate_timer, jiffies + (HZ/2)); -#if 0 - ieee->associate_timer.expires = jiffies + (HZ / 2); - add_timer(&ieee->associate_timer); -#endif - //dev_kfree_skb_any(skb);//edit by thomas } kfree(challenge); } @@ -1453,11 +1345,6 @@ void ieee80211_associate_step2(struct ieee80211_device *ieee) else{ softmac_mgmt_xmit(skb, ieee); mod_timer(&ieee->associate_timer, jiffies + (HZ/2)); -#if 0 - ieee->associate_timer.expires = jiffies + (HZ / 2); - add_timer(&ieee->associate_timer); -#endif - //dev_kfree_skb_any(skb);//edit by thomas } } void ieee80211_associate_complete_wq(struct work_struct *work) @@ -1483,7 +1370,6 @@ void ieee80211_associate_complete_wq(struct work_struct *work) { printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT); memset(ieee->dot11HTOperationalRateSet, 0, 16); - //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); } ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500); // To prevent the immediately calling watch_dog after association. @@ -1510,30 +1396,9 @@ void ieee80211_associate_complete_wq(struct work_struct *work) void ieee80211_associate_complete(struct ieee80211_device *ieee) { -// int i; -// struct net_device* dev = ieee->dev; del_timer_sync(&ieee->associate_timer); -#if 0 - for(i = 0; i < 6; i++) { - ieee->seq_ctrl[i] = 0; - } -#endif ieee->state = IEEE80211_LINKED; -#if 0 - if (ieee->pHTInfo->bCurrentHTSupport) - { - printk("Successfully associated, ht enabled\n"); - queue_work(ieee->wq, &ieee->ht_onAssRsp); - } - else - { - printk("Successfully associated, ht not enabled\n"); - memset(ieee->dot11HTOperationalRateSet, 0, 16); - HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); - } -#endif - //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet); queue_work(ieee->wq, &ieee->associate_complete_wq); } @@ -1553,7 +1418,6 @@ void ieee80211_associate_procedure_wq(struct work_struct *work) ieee80211_stop_scan(ieee); printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel); - //ieee->set_chan(ieee->dev, ieee->current_network.channel); HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); #ifdef ENABLE_IPS @@ -1598,8 +1462,8 @@ inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee * This could be obtained by beacons or, if the network does not * broadcast it, it can be put manually. */ - apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 ); - ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0'; + apset = ieee->wap_set; + ssidset = ieee->ssid_set; ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0'); apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0); ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\ @@ -1633,18 +1497,15 @@ inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee } printk(KERN_INFO"Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d\n",ieee->current_network.ssid,ieee->current_network.channel, ieee->current_network.qos_data.supported, ieee->pHTInfo->bEnableHT, ieee->current_network.bssht.bdSupportHT); - //ieee->pHTInfo->IOTAction = 0; HTResetIOTSetting(ieee->pHTInfo); if (ieee->iw_mode == IW_MODE_INFRA){ /* Join the network for the first time */ ieee->AsocRetryCount = 0; //for HT by amy 080514 if((ieee->current_network.qos_data.supported == 1) && - // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT)) ieee->current_network.bssht.bdSupportHT) /*WB, 2008.09.09:bCurrentHTSupport and bEnableHT two flags are going to put together to check whether we are in HT now, so needn't to check bEnableHT flags here. That's is to say we will set to HT support whenever joined AP has the ability to support HT. And whether we are in HT or not, please check bCurrentHTSupport&&bEnableHT now please.*/ { - // ieee->pHTInfo->bCurrentHTSupport = true; HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network)); } else @@ -1666,7 +1527,6 @@ inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee printk(KERN_INFO"Using B rates\n"); } memset(ieee->dot11HTOperationalRateSet, 0, 16); - //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); ieee->state = IEEE80211_LINKED; } @@ -1773,7 +1633,6 @@ static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, tag++; /* point to the next tag */ } - //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src)); if (ssidlen == 0) return 1; if (!ssid) return 1; /* ssid not found in tagged param */ @@ -1831,11 +1690,8 @@ ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb) { u8 dest[ETH_ALEN]; - //IEEE80211DMESG("Rx probe"); ieee->softmac_stats.rx_probe_rq++; - //DMESG("Dest is "MACSTR, MAC2STR(dest)); if (probe_rq_parse(ieee, skb, dest)){ - //IEEE80211DMESG("Was for me!"); ieee->softmac_stats.tx_probe_rs++; ieee80211_resp_to_probe(ieee, dest); } @@ -1846,23 +1702,18 @@ ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb) { u8 dest[ETH_ALEN]; int status; - //IEEE80211DMESG("Rx probe"); ieee->softmac_stats.rx_auth_rq++; status = auth_rq_parse(skb, dest); if (status != -1) { ieee80211_resp_to_auth(ieee, status, dest); } - //DMESG("Dest is "MACSTR, MAC2STR(dest)); - } static inline void ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb) { - u8 dest[ETH_ALEN]; - //unsigned long flags; ieee->softmac_stats.rx_ass_rq++; if (assoc_rq_parse(skb,dest) != -1){ @@ -1870,12 +1721,6 @@ ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb) } printk(KERN_INFO"New client associated: %pM\n", dest); - //FIXME - #if 0 - spin_lock_irqsave(&ieee->lock,flags); - add_associate(ieee,dest); - spin_unlock_irqrestore(&ieee->lock,flags); - #endif } @@ -1939,7 +1784,6 @@ short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *ti if(pPSC->LPSAwakeIntvl == 0) pPSC->LPSAwakeIntvl = 1; - //pNdisCommon->RegLPSMaxIntvl /// 0x0 - eFastPs, 0xFF -DTIM, 0xNN - 0xNN * BeaconIntvl if(pPSC->RegMaxLPSAwakeIntvl == 0) // Default (0x0 - eFastPs, 0xFF -DTIM, 0xNN - 0xNN * BeaconIntvl) MaxPeriod = 1; // 1 Beacon interval else if(pPSC->RegMaxLPSAwakeIntvl == 0xFF) // DTIM @@ -1962,12 +1806,11 @@ short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *ti if(pPSC->LPSAwakeIntvl > ieee->current_network.tim.tim_count) LPSAwakeIntvl_tmp = count + (pPSC->LPSAwakeIntvl - count) -((pPSC->LPSAwakeIntvl-count)%period); else - LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl;//ieee->current_network.tim.tim_count;//pPSC->LPSAwakeIntvl; + LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl; } *time_l = ieee->current_network.last_dtim_sta_time[0] + MSECS(ieee->current_network.beacon_interval * LPSAwakeIntvl_tmp); - // * ieee->current_network.dtim_period) * 1000; } } @@ -2124,7 +1967,7 @@ void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb struct ieee80211_hdr* header = (struct ieee80211_hdr*)skb->data; u8* act = ieee80211_get_payload(header); u8 tmp = 0; -// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len); + if (act == NULL) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n"); @@ -2143,8 +1986,6 @@ void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb ieee80211_rx_DELBA(ieee, skb); break; default: -// if (net_ratelimit()) -// IEEE80211_DEBUG(IEEE80211_DL_BA, "unknown action frame(%d)\n", tmp); break; } return; @@ -2161,23 +2002,10 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, int chlen=0; int aid; struct ieee80211_assoc_response_frame *assoc_resp; -// struct ieee80211_info_element *info_element; bool bSupportNmode = true, bHalfSupportNmode = false; //default support N mode, disable halfNmode if(!ieee->proto_started) return 0; -#if 0 - printk("%d, %d, %d, %d\n", ieee->sta_sleep, ieee->ps, ieee->iw_mode, ieee->state); - if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED && - ieee->iw_mode == IW_MODE_INFRA && - ieee->state == IEEE80211_LINKED)) - - tasklet_schedule(&ieee->ps_task); - - if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP && - WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON) - ieee->last_rx_ps_time = jiffies; -#endif switch (WLAN_FC_GET_STYPE(header->frame_ctl)) { @@ -2332,8 +2160,6 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, ieee->softmac_stats.reassoc++; ieee->is_roaming = true; ieee80211_disassociate(ieee); - // notify_wx_assoc_event(ieee); - //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); RemovePeerTS(ieee, header->addr2); queue_work(ieee->wq, &ieee->associate_procedure_wq); } @@ -2346,7 +2172,6 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, break; } - //dev_kfree_skb_any(skb); return 0; } @@ -2382,13 +2207,11 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device * ieee80211_sta_wakeup(ieee,0); /* update the tx status */ -// ieee->stats.tx_bytes += txb->payload_size; -// ieee->stats.tx_packets++; tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); if(tcb_desc->bMulticast) { ieee->stats.multicast++; } -#if 1 + /* if xmit available, just xmit it immediately, else just insert it to the wait queue */ for(i = 0; i < txb->nr_frags; i++) { #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE @@ -2402,7 +2225,6 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device * /* as for the completion function, it does not need * to check it any more. * */ - //ieee80211_rtl_stop_queue(ieee); #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]); #else @@ -2412,15 +2234,11 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device * ieee->softmac_data_hard_start_xmit( txb->fragments[i], ieee->dev,ieee->rate); - //ieee->stats.tx_packets++; - //ieee->stats.tx_bytes += txb->fragments[i]->len; - //ieee->dev->trans_start = jiffies; } } -#endif + ieee80211_txb_free(txb); -//exit: spin_unlock_irqrestore(&ieee->lock,flags); } @@ -2439,9 +2257,7 @@ void ieee80211_resume_tx(struct ieee80211_device *ieee) ieee->softmac_data_hard_start_xmit( ieee->tx_pending.txb->fragments[i], ieee->dev,ieee->rate); - //(i+1)tx_pending.txb->nr_frags); ieee->stats.tx_packets++; - // ieee->dev->trans_start = jiffies; } } @@ -2491,7 +2307,6 @@ void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee) ieee->seq_ctrl[0]++; ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate); - //dev_kfree_skb_any(skb);//edit by thomas } } if (!ieee->queue_stop && ieee->tx_pending.txb) @@ -2509,16 +2324,11 @@ exit : void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee) { - //unsigned long flags; - //spin_lock_irqsave(&ieee->lock,flags); - if (! netif_queue_stopped(ieee->dev)){ netif_stop_queue(ieee->dev); ieee->softmac_stats.swtxstop++; } ieee->queue_stop = 1; - //spin_unlock_irqrestore(&ieee->lock,flags); - } @@ -2601,7 +2411,6 @@ void ieee80211_start_ibss_wq(struct work_struct *work) #ifdef ENABLE_DOT11D //if creating an ad-hoc, set its channel to 10 temporarily--this is the requirement for ASUS, not 11D, so disable 11d. -// if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK)) if (ieee->state == IEEE80211_NOLINK) ieee->current_network.channel = 6; #endif @@ -2750,7 +2559,6 @@ void ieee80211_disassociate(struct ieee80211_device *ieee) #endif ieee->is_set_key = false; ieee->link_change(ieee->dev); - //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); if (ieee->state == IEEE80211_LINKED || ieee->state == IEEE80211_ASSOCIATING) { ieee->state = IEEE80211_NOLINK; @@ -3145,8 +2953,6 @@ static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value) if (ieee->set_security) ieee->set_security(ieee->dev, &sec); - //else - // ret = -EOPNOTSUPP; return ret; } diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c index 5cc74be87463..1456387795bb 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c @@ -98,8 +98,6 @@ int ieee80211_wx_get_freq(struct ieee80211_device *ieee, //NM 0.7.0 will not accept channel any more. fwrq->m = ieee80211_wlan_frequencies[ieee->current_network.channel-1] * 100000; fwrq->e = 1; -// fwrq->m = ieee->current_network.channel; -// fwrq->e = 0; return 0; } @@ -233,23 +231,8 @@ int ieee80211_wx_get_rate(struct ieee80211_device *ieee, union iwreq_data *wrqu, char *extra) { u32 tmp_rate; -#if 0 - printk("===>mode:%d, halfNmode:%d\n", ieee->mode, ieee->bHalfWirelessN24GMode); - if (ieee->mode & (IEEE_A | IEEE_B | IEEE_G)) - tmp_rate = ieee->rate; - else if (ieee->mode & IEEE_N_5G) - tmp_rate = 580; - else if (ieee->mode & IEEE_N_24G) - { - if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) - tmp_rate = HTHalfMcsToDataRate(ieee, 15); - else - tmp_rate = HTMcsToDataRate(ieee, 15); - } -#else tmp_rate = TxCountToDataRate(ieee, ieee->softmac_stats.CurrentShowTxate); -#endif wrqu->bitrate.value = tmp_rate * 500000; return 0; @@ -531,16 +514,15 @@ int ieee80211_wx_set_power(struct ieee80211_device *ieee, union iwreq_data *wrqu, char *extra) { int ret = 0; -#if 1 + if( (!ieee->sta_wake_up) || - // (!ieee->ps_request_tx_ack) || (!ieee->enter_sleep_state) || (!ieee->ps_is_queue_empty)){ return -1; } -#endif + down(&ieee->wx_sem); if (wrqu->power.disabled){ @@ -548,16 +530,11 @@ int ieee80211_wx_set_power(struct ieee80211_device *ieee, goto exit; } if (wrqu->power.flags & IW_POWER_TIMEOUT) { - //ieee->ps_period = wrqu->power.value / 1000; ieee->ps_timeout = wrqu->power.value / 1000; } if (wrqu->power.flags & IW_POWER_PERIOD) { - - //ieee->ps_timeout = wrqu->power.value / 1000; ieee->ps_period = wrqu->power.value / 1000; - //wrq->value / 1024; - } switch (wrqu->power.flags & IW_POWER_MODE) { case IW_POWER_UNICAST_R: @@ -571,7 +548,6 @@ int ieee80211_wx_set_power(struct ieee80211_device *ieee, break; case IW_POWER_ON: - // ieee->ps = IEEE80211_PS_DISABLED; break; default: @@ -605,11 +581,8 @@ int ieee80211_wx_get_power(struct ieee80211_device *ieee, wrqu->power.flags = IW_POWER_TIMEOUT; wrqu->power.value = ieee->ps_timeout * 1000; } else { -// ret = -EOPNOTSUPP; -// goto exit; wrqu->power.flags = IW_POWER_PERIOD; wrqu->power.value = ieee->ps_period * 1000; -//ieee->current_network.dtim_period * ieee->current_network.beacon_interval * 1024; } if ((ieee->ps & (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST)) == (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST)) diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c index b26b5a8b5f6b..17535a23c57b 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c @@ -32,7 +32,6 @@ ******************************************************************************/ #include -//#include #include #include #include @@ -232,14 +231,8 @@ int ieee80211_encrypt_fragment( void ieee80211_txb_free(struct ieee80211_txb *txb) { - //int i; if (unlikely(!txb)) return; -#if 0 - for (i = 0; i < txb->nr_frags; i++) - if (txb->fragments[i]) - dev_kfree_skb_any(txb->fragments[i]); -#endif kfree(txb); } @@ -678,22 +671,11 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data+14); if (IPPROTO_UDP == ip->protocol) {//FIXME windows is 11 but here UDP in linux kernel is 17. struct udphdr *udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2)); - //if(((ntohs(udp->source) == 68) && (ntohs(udp->dest) == 67)) || - /// ((ntohs(udp->source) == 67) && (ntohs(udp->dest) == 68))) { if(((((u8 *)udp)[1] == 68) && (((u8 *)udp)[3] == 67)) || ((((u8 *)udp)[1] == 67) && (((u8 *)udp)[3] == 68))) { // 68 : UDP BOOTP client // 67 : UDP BOOTP server printk("DHCP pkt src port:%d, dest port:%d!!\n", ((u8 *)udp)[1],((u8 *)udp)[3]); - // Use low rate to send DHCP packet. - //if(pMgntInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom) - //{ - // tcb_desc->DataRate = MgntQuery_TxRateExcludeCCKRates(ieee);//0xc;//ofdm 6m - // tcb_desc->bTxDisableRateFallBack = false; - //} - //else - //pTcb->DataRate = Adapter->MgntInfo.LowestBasicRate; - //RTPRINT(FDM, WA_IOT, ("DHCP TranslateHeader(), pTcb->DataRate = 0x%x\n", pTcb->DataRate)); bdhcp = true; #ifdef _RTL8192_EXT_PATCH_ @@ -708,15 +690,6 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) bdhcp = true; ieee->LPSDelayCnt = ieee->current_network.tim.tim_count; - //if(pMgntInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom) - //{ - // tcb_desc->DataRate = MgntQuery_TxRateExcludeCCKRates(Adapter->MgntInfo.mBrates);//0xc;//ofdm 6m - // tcb_desc->bTxDisableRateFallBack = FALSE; - //} - //else - // tcb_desc->DataRate = Adapter->MgntInfo.LowestBasicRate; - //RTPRINT(FDM, WA_IOT, ("ARP TranslateHeader(), pTcb->DataRate = 0x%x\n", pTcb->DataRate)); - } } @@ -736,7 +709,6 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) fc = IEEE80211_FTYPE_DATA; - //if(ieee->current_network.QoS_Enable) if(qos_actived) fc |= IEEE80211_STYPE_QOS_DATA; else @@ -771,7 +743,6 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) qos_ctl = 0; } - //if (ieee->current_network.QoS_Enable) if(qos_actived) { hdr_len = IEEE80211_3ADDR_LEN + 2; @@ -817,7 +788,6 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) txb->encrypted = encrypt; txb->payload_size = bytes; - //if (ieee->current_network.QoS_Enable) if(qos_actived) { txb->queue_index = UP2AC(skb->priority); @@ -864,7 +834,7 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) /* The last fragment takes the remaining length */ bytes = bytes_last_frag; } - //if(ieee->current_network.QoS_Enable) + if(qos_actived) { // add 1 only indicate to corresponding seq number control 2006/7/12 @@ -930,7 +900,6 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) //WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place. if (txb) { -#if 1 cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); tcb_desc->bTxEnableFwCalcDur = 1; if (is_multicast_ether_addr(header.addr1)) @@ -941,20 +910,11 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) if ( tcb_desc->bMulticast || tcb_desc->bBroadcast) tcb_desc->data_rate = ieee->basic_rate; else - //tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate); tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate); if(bdhcp == true){ - // Use low rate to send DHCP packet. - //if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom) { - // tcb_desc->data_rate = MGN_1M;//MgntQuery_TxRateExcludeCCKRates(ieee);//0xc;//ofdm 6m - // tcb_desc->bTxDisableRateFallBack = false; - //} - //else - { tcb_desc->data_rate = MGN_1M; tcb_desc->bTxDisableRateFallBack = 1; - } tcb_desc->RATRIndex = 7; tcb_desc->bTxUseDriverAssingedRate = 1; @@ -968,9 +928,6 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) ieee80211_query_BandwidthMode(ieee, tcb_desc); ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]); ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1); -// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, txb->fragments[0]->data, txb->fragments[0]->len); - //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, tcb_desc, sizeof(cb_desc)); -#endif } spin_unlock_irqrestore(&ieee->lock, flags); dev_kfree_skb_any(skb); @@ -997,4 +954,3 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) } -//EXPORT_SYMBOL(ieee80211_txb_free); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c index 368f669ded81..cac340e5238a 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c @@ -36,11 +36,7 @@ #include #include "ieee80211.h" -#if 0 -static const char *ieee80211_modes[] = { - "?", "a", "b", "ab", "g", "ag", "bg", "abg" -}; -#endif + struct modes_unit { char *mode_string; int mode_size; -- cgit v1.2.3 From ea9dc54ed9efc32f0cf2c6eb18898cfd8a1bb96e Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 24 Jan 2011 23:16:10 +0900 Subject: staging: rtl8192e: Remove unused struct members Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 16 ---------------- drivers/staging/rtl8192e/r8192E_core.c | 4 ---- drivers/staging/rtl8192e/r819xE_phy.c | 2 -- 3 files changed, 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 798a35537206..a93b0eeaf90f 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -986,12 +986,10 @@ typedef struct r8192_priv short hw_plcp_len; short plcp_preamble_mode; u8 ScanDelay; - spinlock_t irq_lock; spinlock_t irq_th_lock; spinlock_t tx_lock; spinlock_t rf_ps_lock; struct mutex mutex; - spinlock_t rf_lock; //used to lock rf write operation added by wb spinlock_t ps_lock; u32 irq_mask; @@ -1021,25 +1019,11 @@ typedef struct r8192_priv struct rtl8192_tx_ring tx_ring[MAX_TX_QUEUE_COUNT]; int txringcount; //{ - int txbuffsize; - int txfwbuffersize; //struct tx_pendingbuf txnp_pending; //struct tasklet_struct irq_tx_tasklet; struct tasklet_struct irq_rx_tasklet; struct tasklet_struct irq_tx_tasklet; struct tasklet_struct irq_prepare_beacon_tasklet; - struct buffer *txmapbufs; - struct buffer *txbkpbufs; - struct buffer *txbepbufs; - struct buffer *txvipbufs; - struct buffer *txvopbufs; - struct buffer *txcmdbufs; - struct buffer *txmapbufstail; - struct buffer *txbkpbufstail; - struct buffer *txbepbufstail; - struct buffer *txvipbufstail; - struct buffer *txvopbufstail; - struct buffer *txcmdbufstail; /* adhoc/master mode stuff */ ptx_ring txbeaconringtail; dma_addr_t txbeaconringdma; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 044e226fe9ab..80a0e1f0ecbf 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -2150,8 +2150,6 @@ static void rtl8192_init_priv_variable(struct net_device* dev) priv->bHwRadioOff = false; priv->being_init_adapter = false; - priv->txbuffsize = 1600;//1024; - priv->txfwbuffersize = 4096; priv->txringcount = 64;//32; //priv->txbeaconcount = priv->txringcount; priv->txbeaconcount = 2; @@ -2301,11 +2299,9 @@ static void rtl8192_init_priv_variable(struct net_device* dev) static void rtl8192_init_priv_lock(struct r8192_priv* priv) { spin_lock_init(&priv->tx_lock); - spin_lock_init(&priv->irq_lock);//added by thomas spin_lock_init(&priv->irq_th_lock); spin_lock_init(&priv->rf_ps_lock); spin_lock_init(&priv->ps_lock); - //spin_lock_init(&priv->rf_lock); sema_init(&priv->wx_sem,1); sema_init(&priv->rf_sem,1); mutex_init(&priv->mutex); diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c index 50cd0e52b921..f75c907fd002 100644 --- a/drivers/staging/rtl8192e/r819xE_phy.c +++ b/drivers/staging/rtl8192e/r819xE_phy.c @@ -1727,7 +1727,6 @@ void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 if(priv->ieee80211->eRFPowerState != eRfOn && !priv->being_init_adapter) return; #endif - //spin_lock_irqsave(&priv->rf_lock, flags); //down(&priv->rf_sem); RT_TRACE(COMP_PHY, "FW RF CTRL is not ready now\n"); @@ -1757,7 +1756,6 @@ void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 }else rtl8192_phy_RFSerialWrite(dev, eRFPath, RegAddr, Data); } - //spin_unlock_irqrestore(&priv->rf_lock, flags); //up(&priv->rf_sem); } -- cgit v1.2.3 From 73dbd9f3a4d3c47f514fda5997322f2cbb8219e3 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 24 Jan 2011 23:16:30 +0900 Subject: staging: rtl8192e: Remove unused code to detect struct tx rings Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 24 -------------- drivers/staging/rtl8192e/r8192E_core.c | 57 ---------------------------------- 2 files changed, 81 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index a93b0eeaf90f..2fa25adff987 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1031,30 +1031,6 @@ typedef struct r8192_priv int txbeaconcount; struct buffer *txbeaconbufs; struct buffer *txbeaconbufstail; - ptx_ring txmapring; - ptx_ring txbkpring; - ptx_ring txbepring; - ptx_ring txvipring; - ptx_ring txvopring; - ptx_ring txcmdring; - ptx_ring txmapringtail; - ptx_ring txbkpringtail; - ptx_ring txbepringtail; - ptx_ring txvipringtail; - ptx_ring txvopringtail; - ptx_ring txcmdringtail; - ptx_ring txmapringhead; - ptx_ring txbkpringhead; - ptx_ring txbepringhead; - ptx_ring txvipringhead; - ptx_ring txvopringhead; - ptx_ring txcmdringhead; - dma_addr_t txmapringdma; - dma_addr_t txbkpringdma; - dma_addr_t txbepringdma; - dma_addr_t txvipringdma; - dma_addr_t txvopringdma; - dma_addr_t txcmdringdma; // u8 chtxpwr[15]; //channels from 1 to 14, 0 not used // u8 chtxpwr_ofdm[15]; //channels from 1 to 14, 0 not used // u8 cck_txpwr_base; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 80a0e1f0ecbf..cf5d82840af4 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -3555,8 +3555,6 @@ static RESET_TYPE TxCheckStuck(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); - u8 QueueID; - ptx_ring head=NULL,tail=NULL,txring = NULL; u8 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE; bool bCheckFwTxCnt = false; @@ -3577,61 +3575,6 @@ TxCheckStuck(struct net_device *dev) break; } - // - // Check whether specific tcb has been queued for a specific time - // - for(QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++) - { - - - if(QueueID == TXCMD_QUEUE) - continue; - - switch(QueueID) { - case MGNT_QUEUE: - tail=priv->txmapringtail; - head=priv->txmapringhead; - break; - - case BK_QUEUE: - tail=priv->txbkpringtail; - head=priv->txbkpringhead; - break; - - case BE_QUEUE: - tail=priv->txbepringtail; - head=priv->txbepringhead; - break; - - case VI_QUEUE: - tail=priv->txvipringtail; - head=priv->txvipringhead; - break; - - case VO_QUEUE: - tail=priv->txvopringtail; - head=priv->txvopringhead; - break; - - default: - tail=head=NULL; - break; - } - - if(tail == head) - continue; - else - { - txring = head; - if(txring == NULL) - { - RT_TRACE(COMP_ERR,"%s():txring is NULL , BUG!\n",__FUNCTION__); - continue; - } - txring->nStuckCount++; - bCheckFwTxCnt = TRUE; - } - } #if 1 if(bCheckFwTxCnt) { -- cgit v1.2.3 From 79694ebbe04b08262ef307da73b5c6736938eb8c Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 24 Jan 2011 23:18:22 +0900 Subject: staging: rtl8192e: Remove unused members from r8192_priv Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 16 ---------------- drivers/staging/rtl8192e/r8192E_core.c | 10 ---------- drivers/staging/rtl8192e/r8192E_wx.c | 2 -- 3 files changed, 28 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 2fa25adff987..064ae0c1e257 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -966,7 +966,6 @@ typedef struct r8192_priv u16 eeprom_ChannelPlan; RT_CUSTOMER_ID CustomerID; LED_STRATEGY_8190 LedStrategy; - //bool bDcut; u8 IC_Cut; int irq; short irq_enabled; @@ -980,12 +979,6 @@ typedef struct r8192_priv u8 Rf_Mode; short card_8192; /* O: rtl8192, 1:rtl8185 V B/C, 2:rtl8185 V D */ u8 card_8192_version; /* if TCR reports card V B/C this discriminates */ -// short phy_ver; /* meaningful for rtl8225 1:A 2:B 3:C */ - short enable_gpio0; - enum card_type {PCI,MINIPCI,CARDBUS,USB/*rtl8187*/}card_type; - short hw_plcp_len; - short plcp_preamble_mode; - u8 ScanDelay; spinlock_t irq_th_lock; spinlock_t tx_lock; spinlock_t rf_ps_lock; @@ -997,8 +990,6 @@ typedef struct r8192_priv // struct net_device *dev; //comment this out. short chan; short sens; - short max_sens; - u32 rx_prevlen; /*RX stuff*/ rx_desc_819x_pci *rx_ring; dma_addr_t rx_ring_dma; @@ -1024,13 +1015,6 @@ typedef struct r8192_priv struct tasklet_struct irq_rx_tasklet; struct tasklet_struct irq_tx_tasklet; struct tasklet_struct irq_prepare_beacon_tasklet; - /* adhoc/master mode stuff */ - ptx_ring txbeaconringtail; - dma_addr_t txbeaconringdma; - ptx_ring txbeaconring; - int txbeaconcount; - struct buffer *txbeaconbufs; - struct buffer *txbeaconbufstail; // u8 chtxpwr[15]; //channels from 1 to 14, 0 not used // u8 chtxpwr_ofdm[15]; //channels from 1 to 14, 0 not used // u8 cck_txpwr_base; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index cf5d82840af4..441b50b6a6df 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -2151,8 +2151,6 @@ static void rtl8192_init_priv_variable(struct net_device* dev) priv->being_init_adapter = false; priv->txringcount = 64;//32; - //priv->txbeaconcount = priv->txringcount; - priv->txbeaconcount = 2; priv->rxbuffersize = 9100;//2048;//1024; priv->rxringcount = MAX_RX_COUNT;//64; priv->irq_enabled=0; @@ -2180,7 +2178,6 @@ static void rtl8192_init_priv_variable(struct net_device* dev) priv->rfa_txpowertrackingindex = 0; priv->rfc_txpowertrackingindex = 0; priv->CckPwEnl = 6; - priv->ScanDelay = 50;//for Scan TODO //added by amy for silent reset priv->ResetProgress = RESET_TYPE_NORESET; priv->bForcedSilentReset = 0; @@ -2257,13 +2254,11 @@ static void rtl8192_init_priv_variable(struct net_device* dev) priv->ieee80211->SetHwRegHandler = rtl8192e_SetHwReg; priv->ieee80211->rtllib_ap_sec_type = rtl8192e_ap_sec_type; - priv->card_type = USB; { priv->ShortRetryLimit = 0x30; priv->LongRetryLimit = 0x30; } priv->EarlyRxThreshold = 7; - priv->enable_gpio0 = 0; priv->TransmitConfig = 0; @@ -2773,7 +2768,6 @@ static void rtl8192_read_eeprom_info(struct net_device* dev) priv->ChannelPlan); break; case EEPROM_CID_Nettronix: - priv->ScanDelay = 100; //cosa add for scan priv->CustomerID = RT_CID_Nettronix; break; case EEPROM_CID_Pronet: @@ -6041,10 +6035,6 @@ static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev) } - - - // free_beacon_desc_ring(dev,priv->txbeaconcount); - #ifdef CONFIG_RTL8180_IO_MAP if( dev->base_addr != 0 ){ diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c index 5ae65164af5c..15b08013aae0 100644 --- a/drivers/staging/rtl8192e/r8192E_wx.c +++ b/drivers/staging/rtl8192e/r8192E_wx.c @@ -301,8 +301,6 @@ static int rtl8180_wx_get_range(struct net_device *dev, // range->old_num_channels; // range->old_num_frequency; // range->old_freq[6]; /* Filler to keep "version" at the same offset */ - if(priv->rf_set_sens != NULL) - range->sensitivity = priv->max_sens; /* signal level threshold range */ range->max_qual.qual = 100; /* TODO: Find real max RSSI and stick here */ -- cgit v1.2.3 From 1538ec93d5e0b53f5452abd17650e7fedb1c4698 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 24 Jan 2011 23:18:57 +0900 Subject: staging: rtl8192e: Remove dead code Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 64 +++++++-------------------------------- 1 file changed, 11 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 064ae0c1e257..59d14a34446a 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -958,7 +958,7 @@ struct rtl8192_tx_ring { typedef struct r8192_priv { struct pci_dev *pdev; - //added for maintain info from eeprom + /* maintain info from eeprom */ short epromtype; u16 eeprom_vid; u16 eeprom_did; @@ -986,11 +986,9 @@ typedef struct r8192_priv spinlock_t ps_lock; u32 irq_mask; -// short irq_enabled; -// struct net_device *dev; //comment this out. short chan; short sens; -/*RX stuff*/ + /* RX stuff */ rx_desc_819x_pci *rx_ring; dma_addr_t rx_ring_dma; unsigned int rx_idx; @@ -998,7 +996,6 @@ typedef struct r8192_priv int rxringcount; u16 rxbuffersize; - struct sk_buff *rx_skb; u32 *rxring; u32 *rxringtail; @@ -1006,74 +1003,35 @@ typedef struct r8192_priv struct buffer *rxbuffer; struct buffer *rxbufferhead; short rx_skb_complete; -/*TX stuff*/ + /* TX stuff */ struct rtl8192_tx_ring tx_ring[MAX_TX_QUEUE_COUNT]; int txringcount; -//{ - //struct tx_pendingbuf txnp_pending; - //struct tasklet_struct irq_tx_tasklet; + struct tasklet_struct irq_rx_tasklet; struct tasklet_struct irq_tx_tasklet; struct tasklet_struct irq_prepare_beacon_tasklet; - // u8 chtxpwr[15]; //channels from 1 to 14, 0 not used -// u8 chtxpwr_ofdm[15]; //channels from 1 to 14, 0 not used -// u8 cck_txpwr_base; -// u8 ofdm_txpwr_base; -// u8 challow[15]; //channels from 1 to 14, 0 not used + short up; short crcmon; //if 1 allow bad crc frame reception in monitor mode -// short prism_hdr; - -// struct timer_list scan_timer; - /*short scanpending; - short stopscan;*/ -// spinlock_t scan_lock; -// u8 active_probe; - //u8 active_scan_num; struct semaphore wx_sem; struct semaphore rf_sem; //used to lock rf write operation added by wb, modified by david -// short hw_wep; - -// short digphy; -// short antb; -// short diversity; -// u8 cs_treshold; -// short rcr_csense; - u8 rf_type; //0 means 1T2R, 1 means 2T4R + u8 rf_type; /* 0 means 1T2R, 1 means 2T4R */ RT_RF_TYPE_819xU rf_chip; -// u32 key0[4]; short (*rf_set_sens)(struct net_device *dev,short sens); u8 (*rf_set_chan)(struct net_device *dev,u8 ch); void (*rf_close)(struct net_device *dev); void (*rf_init)(struct net_device *dev); - //short rate; short promisc; - /*stats*/ + /* stats */ struct Stats stats; struct iw_statistics wstats; struct proc_dir_entry *dir_dev; - /*RX stuff*/ -// u32 *rxring; -// u32 *rxringtail; -// dma_addr_t rxringdma; - -#ifdef THOMAS_BEACON - u32 *oldaddr; -#endif -#ifdef THOMAS_TASKLET - atomic_t irt_counter;//count for irq_rx_tasklet -#endif -#ifdef JACKSON_NEW_RX - struct sk_buff **pp_rxskb; - int rx_inx; -#endif - -/* modified by davad for Rx process */ - struct sk_buff_head rx_queue; - struct sk_buff_head skb_queue; - struct work_struct qos_activate; + /* RX stuff */ + struct sk_buff_head rx_queue; + struct sk_buff_head skb_queue; + struct work_struct qos_activate; short tx_urb_index; atomic_t tx_pending[0x10];//UART_PRIORITY+1 -- cgit v1.2.3 From 395aa640a19a2381daa21c6c0e882c1075c629de Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 24 Jan 2011 23:19:25 +0900 Subject: staging: rtl8192e: Remove more unused struct members Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 20 -------------------- drivers/staging/rtl8192e/r8192E_core.c | 15 ++------------- 2 files changed, 2 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 59d14a34446a..b9fe886e9c9b 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1029,36 +1029,22 @@ typedef struct r8192_priv struct proc_dir_entry *dir_dev; /* RX stuff */ - struct sk_buff_head rx_queue; struct sk_buff_head skb_queue; struct work_struct qos_activate; - short tx_urb_index; - atomic_t tx_pending[0x10];//UART_PRIORITY+1 - - struct urb *rxurb_task; //2 Tx Related variables u16 ShortRetryLimit; u16 LongRetryLimit; - u32 TransmitConfig; - u8 RegCWinMin; // For turbo mode CW adaptive. Added by Annie, 2005-10-27. u32 LastRxDescTSFHigh; u32 LastRxDescTSFLow; //2 Rx Related variables - u16 EarlyRxThreshold; u32 ReceiveConfig; - u8 AcmControl; - - u8 RFProgType; u8 retry_data; u8 retry_rts; - u16 rts; - - struct ChnlAccessSetting ChannelAccessSetting; struct work_struct reset_wq; @@ -1074,23 +1060,17 @@ typedef struct r8192_priv /*Firmware*/ prt_firmware pFirmware; rtl819x_loopback_e LoopbackMode; - firmware_source_e firmware_source; bool AutoloadFailFlag; - u16 EEPROMTxPowerDiff; u16 EEPROMAntPwDiff; // Antenna gain offset from B/C/D to A u8 EEPROMThermalMeter; - u8 EEPROMPwDiff; u8 EEPROMCrystalCap; - u8 EEPROM_Def_Ver; u8 EEPROMTxPowerLevelCCK[14];// CCK channel 1~14 // The following definition is for eeprom 93c56 u8 EEPROMRfACCKChnl1TxPwLevel[3]; //RF-A CCK Tx Power Level at channel 7 u8 EEPROMRfAOfdmChnlTxPwLevel[3];//RF-A CCK Tx Power Level at [0],[1],[2] = channel 1,7,13 u8 EEPROMRfCCCKChnl1TxPwLevel[3]; //RF-C CCK Tx Power Level at channel 7 u8 EEPROMRfCOfdmChnlTxPwLevel[3];//RF-C CCK Tx Power Level at [0],[1],[2] = channel 1,7,13 - u8 EEPROMTxPowerLevelCCK_V1[3]; u8 EEPROMTxPowerLevelOFDM24G[14]; // OFDM 2.4G channel 1~14 - u8 EEPROMTxPowerLevelOFDM5G[24]; // OFDM 5G u8 EEPROMLegacyHTTxPowerDiff; // Legacy to HT rate power diff bool bTXPowerDataReadFromEEPORM; /*channel plan*/ diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 441b50b6a6df..eb7e0e18c2c5 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -596,10 +596,6 @@ static int proc_get_stats_tx(char *page, char **start, netif_queue_stopped(dev), priv->stats.txoverflow, // priv->stats.txbeacon, -// atomic_read(&(priv->tx_pending[VI_QUEUE])), -// atomic_read(&(priv->tx_pending[VO_QUEUE])), -// atomic_read(&(priv->tx_pending[BE_QUEUE])), -// atomic_read(&(priv->tx_pending[BK_QUEUE])), // read_nic_byte(dev, TXFIFOCOUNT), // priv->stats.txvidrop, // priv->stats.txvodrop, @@ -2254,13 +2250,8 @@ static void rtl8192_init_priv_variable(struct net_device* dev) priv->ieee80211->SetHwRegHandler = rtl8192e_SetHwReg; priv->ieee80211->rtllib_ap_sec_type = rtl8192e_ap_sec_type; - { - priv->ShortRetryLimit = 0x30; - priv->LongRetryLimit = 0x30; - } - priv->EarlyRxThreshold = 7; - - priv->TransmitConfig = 0; + priv->ShortRetryLimit = 0x30; + priv->LongRetryLimit = 0x30; priv->ReceiveConfig = RCR_ADD3 | RCR_AMF | RCR_ADF | //accept management/data @@ -2274,11 +2265,9 @@ static void rtl8192_init_priv_variable(struct net_device* dev) IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | IMR_RDU | IMR_RXFOVW | IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER); - priv->AcmControl = 0; priv->pFirmware = vzalloc(sizeof(rt_firmware)); /* rx related queue */ - skb_queue_head_init(&priv->rx_queue); skb_queue_head_init(&priv->skb_queue); /* Tx related queue */ -- cgit v1.2.3 From 0157a2b93298d20f3caf3046a030d52756e335d1 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 24 Jan 2011 23:19:48 +0900 Subject: staging: rtl8192e: Remove member that's always false Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8190_rtl8256.c | 1 - drivers/staging/rtl8192e/r8192E.h | 1 - drivers/staging/rtl8192e/r8192E_core.c | 17 +---------------- 3 files changed, 1 insertion(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index e2abfd7fd246..642f3bfe2755 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -503,7 +503,6 @@ SetRFPowerState8190( do { InitializeCount--; - priv->RegRfOff = false; rtstatus = NicIFEnableNIC(dev); }while( (rtstatus != true) &&(InitializeCount >0) ); diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index b9fe886e9c9b..720faf1939d6 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1077,7 +1077,6 @@ typedef struct r8192_priv u16 RegChannelPlan; // Channel Plan specifed by user, 15: following setting of EEPROM, 0-14: default channel plan index specified by user. u16 ChannelPlan; /*PS related*/ - bool RegRfOff; // Rf off action for power save u8 bHwRfOffAction; //0:No action, 1:By GPIO, 2:By Disable /*PHY related*/ diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index eb7e0e18c2c5..20f20414827a 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -2180,7 +2180,6 @@ static void rtl8192_init_priv_variable(struct net_device* dev) priv->bDisableNormalResetCheck = false; priv->force_reset = false; //added by amy for power save - priv->RegRfOff = 0; priv->ieee80211->RfOffReason = 0; priv->RFChangeInProgress = false; priv->bHwRfOffAction = 0; @@ -3024,10 +3023,6 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) // For any kind of InitializeAdapter process, we shall use system now!! priv->pFirmware->firmware_status = FW_STATUS_0_INIT; - // Set to eRfoff in order not to count receive count. - if(priv->RegRfOff == TRUE) - priv->ieee80211->eRFPowerState = eRfOff; - // //3 //Config CPUReset Register //3// @@ -3289,17 +3284,7 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) #ifdef ENABLE_IPS { - if(priv->RegRfOff == TRUE) - { // User disable RF via registry. - RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RegRfOff ----------\n",__FUNCTION__); - MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW); -#if 0//cosa, ask SD3 willis and he doesn't know what is this for - // Those action will be discard in MgntActSet_RF_State because off the same state - for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) - PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0); -#endif - } - else if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS) + if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS) { // H/W or S/W RF OFF before sleep. RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason); MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason); -- cgit v1.2.3 From a2c900bd8aedb9e0f68b6c71e63a9f8c4044c3f4 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 24 Jan 2011 23:20:13 +0900 Subject: staging: rtl8192e: Delete dead code from header Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 174 ++------------------------------------ 1 file changed, 6 insertions(+), 168 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 720faf1939d6..41acd9eb21b7 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -20,7 +20,6 @@ #include #include -//#include #include #include #include @@ -28,7 +27,6 @@ #include #include #include -//#include #include #include #include //for rtnl_lock() @@ -130,9 +128,9 @@ do { if(rt_global_debug_component & component) \ #define COMP_EVENTS BIT19 // Event handling #define COMP_RF BIT20 // For RF. -//1!!!!!!!!!!!!!!!!!!!!!!!!!!! -//1//1Attention Please!!!<11n or 8190 specific code should be put below this line> -//1!!!!!!!!!!!!!!!!!!!!!!!!!!! + +/* 11n or 8190 specific code should be put below this line */ + #define COMP_FIRMWARE BIT21 //for firmware downloading #define COMP_HT BIT22 // For 802.11n HT related information. by Emily 2006-8-11 @@ -354,8 +352,6 @@ typedef struct _rx_fwinfo_819x_pci{ #define MAX_FIRMWARE_INFORMATION_SIZE 32 /*2006/04/30 by Emily forRTL8190*/ #define MAX_802_11_HEADER_LENGTH (40 + MAX_FIRMWARE_INFORMATION_SIZE) #define ENCRYPTION_MAX_OVERHEAD 128 -//#define USB_HWDESC_HEADER_LEN sizeof(tx_desc_819x_usb) -//#define TX_PACKET_SHIFT_BYTES (USB_HWDESC_HEADER_LEN + sizeof(tx_fwinfo_819x_usb)) #define MAX_FRAGMENT_COUNT 8 #define MAX_TRANSMIT_BUFFER_SIZE (1600+(MAX_802_11_HEADER_LENGTH+ENCRYPTION_MAX_OVERHEAD)*MAX_FRAGMENT_COUNT) @@ -401,7 +397,7 @@ typedef struct _rt_firmware{ u8 firmware_buf[MAX_FW_INIT_STEP][RTL8190_MAX_FIRMWARE_CODE_SIZE]; u16 firmware_buf_size[MAX_FW_INIT_STEP]; }rt_firmware, *prt_firmware; -//+by amy 080507 + #define MAX_RECEIVE_BUFFER_SIZE 9100 // Add this to 9100 bytes to receive A-MSDU from RT-AP /* Firmware Queue Layout */ @@ -427,55 +423,12 @@ typedef struct _rt_firmware{ #define RSVD_FW_QUEUE_PAGE_BCN_SHIFT 0x00 #define RSVD_FW_QUEUE_PAGE_PUB_SHIFT 0x08 -//8187B Security -//#define RWCAM 0xA0 // Software read/write CAM config -//#define WCAMI 0xA4 // Software write CAM input content -//#define RCAMO 0xA8 // Output value from CAM according to 0xa0 setting #define DCAM 0xAC // Debug CAM Interface #define AESMSK_FC 0xB2 // AES Mask register for frame control (0xB2~0xB3). Added by Annie, 2006-03-06. #define CAM_CONTENT_COUNT 8 -//#define CFG_DEFAULT_KEY BIT5 #define CFG_VALID BIT15 -#if 0 -//---------------------------------------------------------------------------- -// 8187B WPA Config Register (offset 0xb0, 1 byte) -//---------------------------------------------------------------------------- -#define SCR_UseDK 0x01 -#define SCR_TxSecEnable 0x02 -#define SCR_RxSecEnable 0x04 - -//---------------------------------------------------------------------------- -// 8187B CAM Config Setting (offset 0xb0, 1 byte) -//---------------------------------------------------------------------------- -#define CAM_VALID 0x8000 -#define CAM_NOTVALID 0x0000 -#define CAM_USEDK 0x0020 - - -#define CAM_NONE 0x0 -#define CAM_WEP40 0x01 -#define CAM_TKIP 0x02 -#define CAM_AES 0x04 -#define CAM_WEP104 0x05 - -//#define CAM_SIZE 16 -#define TOTAL_CAM_ENTRY 16 -#define CAM_ENTRY_LEN_IN_DW 6 // 6, unit: in u4byte. Added by Annie, 2006-05-25. -#define CAM_ENTRY_LEN_IN_BYTE (CAM_ENTRY_LEN_IN_DW*sizeof(u32)) // 24, unit: in u1byte. Added by Annie, 2006-05-25. - -#define CAM_CONFIG_USEDK 1 -#define CAM_CONFIG_NO_USEDK 0 - -#define CAM_WRITE 0x00010000 -#define CAM_READ 0x00000000 -#define CAM_POLLINIG 0x80000000 - -//================================================================= -//================================================================= - -#endif #define EPROM_93c46 0 #define EPROM_93c56 1 @@ -523,17 +476,6 @@ typedef struct rtl_reg_debug{ unsigned char buf[0xff]; }rtl_reg_debug; -#if 0 - -typedef struct tx_pendingbuf -{ - struct ieee80211_txb *txb; - short ispending; - short descfrag; -} tx_pendigbuf; - -#endif - typedef struct _rt_9x_tx_rate_history { u32 cck[4]; u32 ofdm[8]; @@ -565,10 +507,6 @@ typedef struct Stats { unsigned long txrdu; unsigned long rxrdu; - //unsigned long rxnolast; - //unsigned long rxnodata; -// unsigned long rxreset; -// unsigned long rxnopointer; unsigned long rxok; unsigned long rxframgment; unsigned long rxcmdpkt[4]; //08/05/08 amy rx cmd element txfeedback/bcn report/cfg set/query @@ -591,18 +529,12 @@ typedef struct Stats unsigned long txnperr; unsigned long txnpdrop; unsigned long txresumed; -// unsigned long rxerr; unsigned long rxoverflow; unsigned long rxint; unsigned long txnpokint; -// unsigned long txhpokint; -// unsigned long txhperr; unsigned long ints; unsigned long shints; unsigned long txoverflow; -// unsigned long rxdmafail; -// unsigned long txbeacon; -// unsigned long txbeaconerr; unsigned long txlpokint; unsigned long txlpdrop; unsigned long txlperr; @@ -663,8 +595,6 @@ typedef struct Stats u32 Slide_Beacon_Total; //cosa add for beacon rssi RT_SMOOTH_DATA_4RF cck_adc_pwdb; u32 CurrentShowTxate; - - } Stats; @@ -673,8 +603,6 @@ typedef struct Stats #define HAL_PRIME_CHNL_OFFSET_LOWER 1 #define HAL_PRIME_CHNL_OFFSET_UPPER 2 -//+by amy 080507 - typedef struct ChnlAccessSetting { u16 SIFS_Timer; u16 DIFS_Timer; @@ -795,9 +723,7 @@ typedef enum _RT_CUSTOMER_ID RT_CID_COREGA = 14, }RT_CUSTOMER_ID, *PRT_CUSTOMER_ID; -//================================================================================ -// LED customization. -//================================================================================ +/* LED customization. */ typedef enum _LED_STRATEGY_8190{ SW_LED_MODE0, // SW control 1 LED via GPIO0. It is default option. @@ -1048,7 +974,6 @@ typedef struct r8192_priv struct work_struct reset_wq; -/**********************************************************/ //for rtl819xPci // Data Rate Config. Added by Annie, 2006-04-13. u16 basic_rate; @@ -1227,95 +1152,10 @@ typedef struct r8192_priv struct workqueue_struct *priv_wq; }r8192_priv; -// for rtl8187 -// now mirging to rtl8187B -/* -typedef enum{ - LOW_PRIORITY = 0x02, - NORM_PRIORITY - } priority_t; -*/ -//for rtl8187B -#if 0 -typedef enum{ - BULK_PRIORITY = 0x01, - //RSVD0, - //RSVD1, - LOW_PRIORITY, - NORM_PRIORITY, - VO_PRIORITY, - VI_PRIORITY, //0x05 - BE_PRIORITY, - BK_PRIORITY, - CMD_PRIORITY,//0x8 - RSVD3, - BEACON_PRIORITY, //0x0A - HIGH_PRIORITY, - MANAGE_PRIORITY, - RSVD4, - RSVD5, - UART_PRIORITY //0x0F -} priority_t; -#endif typedef enum{ NIC_8192E = 1, - } nic_t; - - -#if 0 //defined in Qos.h -//typedef u32 AC_CODING; -#define AC0_BE 0 // ACI: 0x00 // Best Effort -#define AC1_BK 1 // ACI: 0x01 // Background -#define AC2_VI 2 // ACI: 0x10 // Video -#define AC3_VO 3 // ACI: 0x11 // Voice -#define AC_MAX 4 // Max: define total number; Should not to be used as a real enum. - -// -// ECWmin/ECWmax field. -// Ref: WMM spec 2.2.2: WME Parameter Element, p.13. -// -typedef union _ECW{ - u8 charData; - struct - { - u8 ECWmin:4; - u8 ECWmax:4; - }f; // Field -}ECW, *PECW; - -// -// ACI/AIFSN Field. -// Ref: WMM spec 2.2.2: WME Parameter Element, p.12. -// -typedef union _ACI_AIFSN{ - u8 charData; - - struct - { - u8 AIFSN:4; - u8 ACM:1; - u8 ACI:2; - u8 Reserved:1; - }f; // Field -}ACI_AIFSN, *PACI_AIFSN; +} nic_t; -// -// AC Parameters Record Format. -// Ref: WMM spec 2.2.2: WME Parameter Element, p.12. -// -typedef union _AC_PARAM{ - u32 longData; - u8 charData[4]; - - struct - { - ACI_AIFSN AciAifsn; - ECW Ecw; - u16 TXOPLimit; - }f; // Field -}AC_PARAM, *PAC_PARAM; - -#endif bool init_firmware(struct net_device *dev); short rtl8192_tx(struct net_device *dev, struct sk_buff* skb); u32 read_cam(struct net_device *dev, u8 addr); @@ -1334,7 +1174,6 @@ void rtl8192_rx_enable(struct net_device *); void rtl8192_tx_enable(struct net_device *); void rtl8192_disassociate(struct net_device *dev); -//void fix_rx_fifo(struct net_device *dev); void rtl8185_set_rf_pins_enable(struct net_device *dev,u32 a); void rtl8192_set_anaparam(struct net_device *dev,u32 a); @@ -1349,7 +1188,6 @@ void write_phy_cck(struct net_device *dev, u8 adr, u32 data); void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data); void rtl8185_tx_antenna(struct net_device *dev, u8 ant); void rtl8187_set_rxconf(struct net_device *dev); -//short check_nic_enough_desc(struct net_device *dev, priority_t priority); void CamResetAllEntry(struct net_device* dev); void EnableHWSecurityConfig8192(struct net_device *dev); void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent ); -- cgit v1.2.3 From 08dcd4166ed86608f76d25a2da038ede8d31f25d Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 24 Jan 2011 23:20:40 +0900 Subject: staging: rtl8192e: Delete dead code Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 72 ---------------------------------- 1 file changed, 72 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 20f20414827a..3563fb93b7eb 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1237,16 +1237,6 @@ void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb) entry->TxBuffAddr = cpu_to_le32(mapping); entry->OWN = 1; -#ifdef JOHN_DUMP_TXDESC - { int i; - tx_desc_819x_pci *entry1 = &ring->desc[0]; - unsigned int *ptr= (unsigned int *)entry1; - printk(":\n"); - for (i = 0; i < 8; i++) - printk("%8x ", ptr[i]); - printk("\n"); - } -#endif __skb_queue_tail(&ring->queue, skb); spin_unlock_irqrestore(&priv->irq_th_lock,flags); @@ -1931,8 +1921,6 @@ static void rtl8192_refresh_supportrate(struct r8192_priv* priv) if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G) { memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16); - //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16); - //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16); } else memset(ieee->Regdot11HTOperationalRateSet, 0, 16); @@ -1964,7 +1952,6 @@ static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode) struct r8192_priv *priv = ieee80211_priv(dev); u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev); -#if 1 if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0)) { if(bSupportMode & WIRELESS_MODE_N_24G) @@ -1992,9 +1979,6 @@ static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode) wireless_mode = WIRELESS_MODE_B; } } -#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA - ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting ); -#endif priv->ieee80211->mode = wireless_mode; if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G)) @@ -2003,8 +1987,6 @@ static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode) priv->ieee80211->pHTInfo->bEnableHT = 0; RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode); rtl8192_refresh_supportrate(priv); -#endif - } static bool GetHalfNmodeSupportByAPs819xPci(struct net_device* dev) @@ -4836,17 +4818,6 @@ static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct { // if previous packet is not aggregated packet bcheck = true; - }else - { -//remve for that we don't use AMPDU to calculate PWDB,because the reported PWDB of some AP is fault. -#if 0 - // if previous packet is aggregated packet, and current packet - // (1) is not AMPDU - // (2) is the first packet of one AMPDU - // that means the previous packet is the last one aggregated packet - if( !pcurrent_stats->bIsAMPDU || pcurrent_stats->bFirstMPDU) - bcheck = true; -#endif } if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX) @@ -4883,25 +4854,7 @@ static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct // Check RSSI // priv->stats.num_process_phyinfo++; -#if 0 - /* record the general signal strength to the sliding window. */ - if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX) - { - slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX; - last_rssi = priv->stats.slide_signal_strength[slide_rssi_index]; - priv->stats.slide_rssi_total -= last_rssi; - } - priv->stats.slide_rssi_total += pprevious_stats->SignalStrength; - priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength; - if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX) - slide_rssi_index = 0; - - // <1> Showed on UI for user, in dbm - tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics; - priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val); - -#endif // <2> Showed on UI for engineering // hardware does not provide rssi information for each rf path in CCK if(!pprevious_stats->bIsCCK && pprevious_stats->bPacketToSelf) @@ -5383,9 +5336,6 @@ static void rtl8192_query_rxphystatus( rx_evmX /= 2; //dbm evm = rtl819x_evm_dbtopercentage(rx_evmX); -#if 0 - EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100 -#endif if(bpacket_match_bssid) { if(i==0) // Fill value in RFD, Get the first spatial stream only @@ -5513,12 +5463,6 @@ static void rtl8192_tx_resume(struct net_device *dev) skb = skb_dequeue(&ieee->skb_waitQ[queue_index]); /* 2. tx the packet directly */ ieee->softmac_data_hard_start_xmit(skb,dev,0/* rate useless now*/); - #if 0 - if(queue_index!=MGNT_QUEUE) { - ieee->stats.tx_packets++; - ieee->stats.tx_bytes += skb->len; - } - #endif } } } @@ -5860,16 +5804,6 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, priv->irq = 0; dev->netdev_ops = &rtl8192_netdev_ops; -#if 0 - dev->open = rtl8192_open; - dev->stop = rtl8192_close; - //dev->hard_start_xmit = rtl8192_8023_hard_start_xmit; - dev->tx_timeout = tx_timeout; - //dev->wireless_handlers = &r8192_wx_handlers_def; - dev->do_ioctl = rtl8192_ioctl; - dev->set_multicast_list = r8192_set_multicast; - dev->set_mac_address = r8192_set_mac_adr; -#endif //DMESG("Oops: i'm coming\n"); #if WIRELESS_EXT >= 12 @@ -6100,9 +6034,6 @@ static irqreturn_t rtl8192_interrupt(int irq, void *netdev) } priv->stats.ints++; -#ifdef DEBUG_IRQ - DMESG("NIC irq %x",inta); -#endif if (!netif_running(dev)) goto out_unlock; @@ -6132,9 +6063,6 @@ static irqreturn_t rtl8192_interrupt(int irq, void *netdev) } if (inta & IMR_ROK) { -#ifdef DEBUG_RX - DMESG("Frame arrived !"); -#endif priv->stats.rxint++; tasklet_schedule(&priv->irq_rx_tasklet); } -- cgit v1.2.3 From 3059f2decfa2994834874c153552df418e98b960 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 24 Jan 2011 23:21:17 +0900 Subject: staging: rtl8192e: Delete unused and write-only struct members Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 14 +------- drivers/staging/rtl8192e/r8192E_core.c | 66 ++-------------------------------- 2 files changed, 3 insertions(+), 77 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 41acd9eb21b7..00dc37003795 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -505,26 +505,14 @@ typedef enum _tag_TxCmd_Config_Index{ typedef struct Stats { - unsigned long txrdu; unsigned long rxrdu; unsigned long rxok; - unsigned long rxframgment; unsigned long rxcmdpkt[4]; //08/05/08 amy rx cmd element txfeedback/bcn report/cfg set/query - unsigned long rxurberr; - unsigned long rxstaterr; - unsigned long rxcrcerrmin;//crc error (0-500) - unsigned long rxcrcerrmid;//crc error (500-1000) - unsigned long rxcrcerrmax;//crc error (>1000) + unsigned long rxurberr; /* remove */ unsigned long received_rate_histogram[4][32]; //0: Total, 1:OK, 2:CRC, 3:ICV, 2007 07 03 cosa unsigned long received_preamble_GI[2][32]; //0: Long preamble/GI, 1:Short preamble/GI unsigned long rx_AMPDUsize_histogram[5]; // level: (<4K), (4K~8K), (8K~16K), (16K~32K), (32K~64K) unsigned long rx_AMPDUnum_histogram[5]; // level: (<5), (5~10), (10~20), (20~40), (>40) - unsigned long numpacket_matchbssid; // debug use only. - unsigned long numpacket_toself; // debug use only. - unsigned long num_process_phyinfo; // debug use only. - unsigned long numqry_phystatus; - unsigned long numqry_phystatusCCK; - unsigned long numqry_phystatusHT; unsigned long received_bwtype[5]; //0: 20M, 1: funn40M, 2: upper20M, 3: lower20M, 4: duplicate unsigned long txnperr; unsigned long txnpdrop; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 3563fb93b7eb..dcd2fc60b86b 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -547,67 +547,29 @@ static int proc_get_stats_tx(char *page, char **start, len += snprintf(page + len, count - len, "TX VI priority ok int: %lu\n" -// "TX VI priority error int: %lu\n" "TX VO priority ok int: %lu\n" -// "TX VO priority error int: %lu\n" "TX BE priority ok int: %lu\n" -// "TX BE priority error int: %lu\n" "TX BK priority ok int: %lu\n" -// "TX BK priority error int: %lu\n" "TX MANAGE priority ok int: %lu\n" -// "TX MANAGE priority error int: %lu\n" "TX BEACON priority ok int: %lu\n" "TX BEACON priority error int: %lu\n" "TX CMDPKT priority ok int: %lu\n" -// "TX high priority ok int: %lu\n" -// "TX high priority failed error int: %lu\n" -// "TX queue resume: %lu\n" "TX queue stopped?: %d\n" "TX fifo overflow: %lu\n" -// "TX beacon: %lu\n" -// "TX VI queue: %d\n" -// "TX VO queue: %d\n" -// "TX BE queue: %d\n" -// "TX BK queue: %d\n" -// "TX HW queue: %d\n" -// "TX VI dropped: %lu\n" -// "TX VO dropped: %lu\n" -// "TX BE dropped: %lu\n" -// "TX BK dropped: %lu\n" "TX total data packets %lu\n" "TX total data bytes :%lu\n", -// "TX beacon aborted: %lu\n", priv->stats.txviokint, -// priv->stats.txvierr, priv->stats.txvookint, -// priv->stats.txvoerr, priv->stats.txbeokint, -// priv->stats.txbeerr, priv->stats.txbkokint, -// priv->stats.txbkerr, priv->stats.txmanageokint, -// priv->stats.txmanageerr, priv->stats.txbeaconokint, priv->stats.txbeaconerr, priv->stats.txcmdpktokint, -// priv->stats.txhpokint, -// priv->stats.txhperr, -// priv->stats.txresumed, netif_queue_stopped(dev), priv->stats.txoverflow, -// priv->stats.txbeacon, -// read_nic_byte(dev, TXFIFOCOUNT), -// priv->stats.txvidrop, -// priv->stats.txvodrop, priv->ieee80211->stats.tx_packets, - priv->ieee80211->stats.tx_bytes - - -// priv->stats.txbedrop, -// priv->stats.txbkdrop - // priv->stats.txdatapkt -// priv->stats.txbeaconerr - ); + priv->ieee80211->stats.tx_bytes); *eof = 1; return len; @@ -4850,11 +4812,6 @@ static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct rtl8190_process_cck_rxpathsel(priv,pprevious_stats); - // - // Check RSSI - // - priv->stats.num_process_phyinfo++; - // <2> Showed on UI for engineering // hardware does not provide rssi information for each rf path in CCK if(!pprevious_stats->bIsCCK && pprevious_stats->bPacketToSelf) @@ -5126,8 +5083,6 @@ static void rtl8192_query_rxphystatus( static u8 check_reg824 = 0; static u32 reg824_bit9 = 0; - priv->stats.numqry_phystatus++; - is_cck_rate = rx_hal_is_cck_rate(pdrvinfo); // Record it for next packet processing @@ -5173,7 +5128,6 @@ static void rtl8192_query_rxphystatus( u8 tmp_pwdb; char cck_adc_pwdb[4]; #endif - priv->stats.numqry_phystatusCCK++; #ifdef RTL8190P //Only 90P 2T4R need to check if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable && bpacket_match_bssid) @@ -5265,7 +5219,6 @@ static void rtl8192_query_rxphystatus( } else { - priv->stats.numqry_phystatusHT++; // // (1)Get RSSI for HT rate // @@ -5429,13 +5382,7 @@ static void TranslateRxSignalStuff819xpci(struct net_device *dev, } #endif - if(bpacket_match_bssid) - { - priv->stats.numpacket_matchbssid++; - } - if(bpacket_toself){ - priv->stats.numpacket_toself++; - } + // // Process PHY information for previous packet (RSSI/PWDB/EVM) // @@ -5572,15 +5519,6 @@ static void rtl8192_rx(struct net_device *dev) if(stats.bHwError) { stats.bShift = false; - - if(pdesc->CRC32) { - if (pdesc->Length <500) - priv->stats.rxcrcerrmin++; - else if (pdesc->Length >1000) - priv->stats.rxcrcerrmax++; - else - priv->stats.rxcrcerrmid++; - } goto done; } else { prx_fwinfo_819x_pci pDrvInfo = NULL; -- cgit v1.2.3 From 941f0d5db47394a1eee3e90465027ed328454918 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 24 Jan 2011 23:21:42 +0900 Subject: staging: rtl8192e: Remove unused types and defines Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 00dc37003795..09850a68a8b6 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -43,7 +43,7 @@ #define RTL819xE_MODULE_NAME "rtl819xE" -//added for HW security, john.0629 + #define FALSE 0 #define TRUE 1 #define MAX_KEY_LEN 61 @@ -295,11 +295,6 @@ typedef struct _tx_fwinfo_819x_pci { //u32 Reserved; }tx_fwinfo_819x_pci, *ptx_fwinfo_819x_pci; -typedef struct rtl8192_rx_info { - struct urb *urb; - struct net_device *dev; - u8 out_pipe; -}rtl8192_rx_info ; typedef struct _rx_desc_819x_pci{ //DOWRD 0 u16 Length:14; @@ -370,11 +365,6 @@ typedef enum _desc_packet_type_e{ DESC_PACKET_TYPE_NORMAL = 1, }desc_packet_type_e; -typedef enum _firmware_source{ - FW_SOURCE_IMG_FILE = 0, - FW_SOURCE_HEADER_FILE = 1, //from header file -}firmware_source_e, *pfirmware_source_e; - typedef enum _firmware_status{ FW_STATUS_0_INIT = 0, FW_STATUS_1_MOVE_BOOT_CODE = 1, @@ -384,11 +374,6 @@ typedef enum _firmware_status{ FW_STATUS_5_READY = 5, }firmware_status_e; -typedef struct _rt_firmare_seg_container { - u16 seg_size; - u8 *seg_ptr; -}fw_seg_container, *pfw_seg_container; - typedef struct _rt_firmware{ firmware_status_e firmware_status; u16 cmdpacket_frag_thresold; @@ -435,12 +420,9 @@ typedef struct _rt_firmware{ #define DEFAULT_FRAG_THRESHOLD 2342U #define MIN_FRAG_THRESHOLD 256U #define DEFAULT_BEACONINTERVAL 0x64U -#define DEFAULT_BEACON_ESSID "Rtl819xU" -#define DEFAULT_SSID "" #define DEFAULT_RETRY_RTS 7 #define DEFAULT_RETRY_DATA 7 -#define PRISM_HDR_SIZE 64 #define PHY_RSSI_SLID_WIN_MAX 100 @@ -465,17 +447,6 @@ typedef struct buffer } buffer; -typedef struct rtl_reg_debug{ - unsigned int cmd; - struct { - unsigned char type; - unsigned char addr; - unsigned char page; - unsigned char length; - } head; - unsigned char buf[0xff]; -}rtl_reg_debug; - typedef struct _rt_9x_tx_rate_history { u32 cck[4]; u32 ofdm[8]; -- cgit v1.2.3 From 8cbe7ae6c1fd33419cba0c210a5f2c6b586b8d35 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 24 Jan 2011 23:22:21 +0900 Subject: staging: rtl8192e: Remove unused members from struct Stats Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 46 +---------------- drivers/staging/rtl8192e/r8192E_core.c | 51 ------------------ drivers/staging/rtl8192e/r8192E_dm.c | 6 --- drivers/staging/rtl8192e/r819xE_cmdpkt.c | 89 ++------------------------------ 4 files changed, 4 insertions(+), 188 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 09850a68a8b6..5f85872e39a2 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -481,79 +481,35 @@ typedef struct Stats unsigned long rxcmdpkt[4]; //08/05/08 amy rx cmd element txfeedback/bcn report/cfg set/query unsigned long rxurberr; /* remove */ unsigned long received_rate_histogram[4][32]; //0: Total, 1:OK, 2:CRC, 3:ICV, 2007 07 03 cosa - unsigned long received_preamble_GI[2][32]; //0: Long preamble/GI, 1:Short preamble/GI - unsigned long rx_AMPDUsize_histogram[5]; // level: (<4K), (4K~8K), (8K~16K), (16K~32K), (32K~64K) - unsigned long rx_AMPDUnum_histogram[5]; // level: (<5), (5~10), (10~20), (20~40), (>40) - unsigned long received_bwtype[5]; //0: 20M, 1: funn40M, 2: upper20M, 3: lower20M, 4: duplicate - unsigned long txnperr; - unsigned long txnpdrop; - unsigned long txresumed; unsigned long rxoverflow; unsigned long rxint; - unsigned long txnpokint; - unsigned long ints; - unsigned long shints; unsigned long txoverflow; - unsigned long txlpokint; - unsigned long txlpdrop; - unsigned long txlperr; unsigned long txbeokint; - unsigned long txbedrop; - unsigned long txbeerr; unsigned long txbkokint; - unsigned long txbkdrop; - unsigned long txbkerr; unsigned long txviokint; - unsigned long txvidrop; - unsigned long txvierr; unsigned long txvookint; - unsigned long txvodrop; - unsigned long txvoerr; unsigned long txbeaconokint; - unsigned long txbeacondrop; unsigned long txbeaconerr; unsigned long txmanageokint; - unsigned long txmanagedrop; - unsigned long txmanageerr; unsigned long txcmdpktokint; - unsigned long txdatapkt; unsigned long txfeedback; unsigned long txfeedbackok; unsigned long txoktotal; - unsigned long txokbytestotal; - unsigned long txokinperiod; - unsigned long txmulticast; - unsigned long txbytesmulticast; - unsigned long txbroadcast; - unsigned long txbytesbroadcast; unsigned long txunicast; unsigned long txbytesunicast; unsigned long rxbytesunicast; - unsigned long txfeedbackfail; - unsigned long txerrtotal; unsigned long txerrbytestotal; - unsigned long txerrmulticast; - unsigned long txerrbroadcast; - unsigned long txerrunicast; - unsigned long txretrycount; - unsigned long txfeedbackretry; - u8 last_packet_rate; + unsigned long slide_signal_strength[100]; unsigned long slide_evm[100]; unsigned long slide_rssi_total; // For recording sliding window's RSSI value unsigned long slide_evm_total; // For recording sliding window's EVM value long signal_strength; // Transformed, in dbm. Beautified signal strength for UI, not correct. - long signal_quality; - long last_signal_strength_inpercent; - long recv_signal_power; // Correct smoothed ss in Dbm, only used in driver to report real power now. u8 rx_rssi_percentage[4]; u8 rx_evm_percentage[2]; - long rxSNRdB[4]; - rt_tx_rahis_t txrate; u32 Slide_Beacon_pwdb[100]; //cosa add for beacon rssi u32 Slide_Beacon_Total; //cosa add for beacon rssi RT_SMOOTH_DATA_4RF cck_adc_pwdb; - u32 CurrentShowTxate; } Stats; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index dcd2fc60b86b..a465f3770baa 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1348,10 +1348,6 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff* skb) if (uni_addr) priv->stats.txbytesunicast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI); - else if (multi_addr) - priv->stats.txbytesmulticast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI); - else - priv->stats.txbytesbroadcast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI); /* fill tx firmware */ pTxFwInfo = (PTX_FWINFO_8190PCI)skb->data; @@ -4648,41 +4644,6 @@ static long rtl819x_translate_todbm(u8 signal_strength_index)// 0-100 index. return signal_power; } -/* - * Update Rx signal related information in the packet reeived - * to RxStats. User application can query RxStats to realize - * current Rx signal status. - * - * In normal operation, user only care about the information of the BSS - * and we shall invoke this function if the packet received is from the BSS. - */ -static void -rtl819x_update_rxsignalstatistics8190pci( - struct r8192_priv * priv, - struct ieee80211_rx_stats * pprevious_stats - ) -{ - int weighting = 0; - - //2 Update Rx Statistics (such as signal strength and signal quality). - - // Initila state - if(priv->stats.recv_signal_power == 0) - priv->stats.recv_signal_power = pprevious_stats->RecvSignalPower; - - // To avoid the past result restricting the statistics sensitivity, weight the current power (5/6) to speed up the - // reaction of smoothed Signal Power. - if(pprevious_stats->RecvSignalPower > priv->stats.recv_signal_power) - weighting = 5; - else if(pprevious_stats->RecvSignalPower < priv->stats.recv_signal_power) - weighting = (-5); - // - // We need more correct power of received packets and the "SignalStrength" of RxStats have been beautified or translated, - // so we record the correct power in Dbm here. By Bruce, 2008-03-07. - // - priv->stats.recv_signal_power = (priv->stats.recv_signal_power * 5 + pprevious_stats->RecvSignalPower + weighting) / 6; -} - static void rtl8190_process_cck_rxpathsel( struct r8192_priv * priv, @@ -4910,7 +4871,6 @@ static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6; } #endif - rtl819x_update_rxsignalstatistics8190pci(priv,pprevious_stats); } // @@ -4937,9 +4897,7 @@ static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct // <1> Showed on UI for user, in percentage. tmp_val = priv->stats.slide_evm_total/slide_evm_statistics; - priv->stats.signal_quality = tmp_val; //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality. - priv->stats.last_signal_strength_inpercent = tmp_val; } // <2> Showed on UI for engineering @@ -5242,7 +5200,6 @@ static void rtl8192_query_rxphystatus( tmp_rxsnr = pofdm_buf->rxsnr_X[i]; rx_snrX = (char)(tmp_rxsnr); rx_snrX /= 2; - priv->stats.rxSNRdB[i] = (long)rx_snrX; /* Translate DBM to percentage. */ RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]); @@ -5301,10 +5258,6 @@ static void rtl8192_query_rxphystatus( /* record rx statistics for debug */ rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg; prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg; - if(pdrvinfo->BW) //40M channel - priv->stats.received_bwtype[1+prxsc->rxsc]++; - else //20M channel - priv->stats.received_bwtype[0]++; } //UI BSS List signal strength(in percentage), make it good looking, from 0~100. @@ -5481,7 +5434,6 @@ static void UpdateReceivedRateHistogramStatistics8190( case MGN_MCS15: rateIndex = 27; break; default: rateIndex = 28; break; } - priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++; priv->stats.received_rate_histogram[0][rateIndex]++; //total priv->stats.received_rate_histogram[rcvType][rateIndex]++; } @@ -5957,7 +5909,6 @@ static irqreturn_t rtl8192_interrupt(int irq, void *netdev) inta = read_nic_dword(dev, ISR); /* & priv->IntrMask; */ write_nic_dword(dev, ISR, inta); /* reset int situation */ - priv->stats.shints++; if (!inta) { /* * most probably we can safely return IRQ_NONE, @@ -5971,8 +5922,6 @@ static irqreturn_t rtl8192_interrupt(int irq, void *netdev) goto out_unlock; } - priv->stats.ints++; - if (!netif_running(dev)) goto out_unlock; diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index 319cf59c8503..08275b3cde39 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -3196,15 +3196,9 @@ static void dm_check_txrateandretrycount(struct net_device * dev) { struct r8192_priv *priv = ieee80211_priv(dev); struct ieee80211_device* ieee = priv->ieee80211; - //for 11n tx rate -// priv->stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg); - ieee->softmac_stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg); - //printk("=============>tx_rate_reg:%x\n", ieee->softmac_stats.CurrentShowTxate); //for initial tx rate -// priv->stats.last_packet_rate = read_nic_byte(dev, Initial_Tx_Rate_Reg); ieee->softmac_stats.last_packet_rate = read_nic_byte(dev ,Initial_Tx_Rate_Reg); //for tx tx retry count -// priv->stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg); ieee->softmac_stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg); } diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.c b/drivers/staging/rtl8192e/r819xE_cmdpkt.c index 135439d12428..e841e1665fe8 100644 --- a/drivers/staging/rtl8192e/r819xE_cmdpkt.c +++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.c @@ -160,52 +160,15 @@ cmpk_count_txstatistic( feedback info. */ if (pstx_fb->tok) { - priv->stats.txfeedbackok++; priv->stats.txoktotal++; - priv->stats.txokbytestotal += pstx_fb->pkt_length; - priv->stats.txokinperiod++; /* We can not make sure broadcast/multicast or unicast mode. */ - if (pstx_fb->pkt_type == PACKET_MULTICAST) - { - priv->stats.txmulticast++; - priv->stats.txbytesmulticast += pstx_fb->pkt_length; - } - else if (pstx_fb->pkt_type == PACKET_BROADCAST) - { - priv->stats.txbroadcast++; - priv->stats.txbytesbroadcast += pstx_fb->pkt_length; - } - else - { + if (pstx_fb->pkt_type != PACKET_MULTICAST && + pstx_fb->pkt_type != PACKET_BROADCAST) { priv->stats.txunicast++; priv->stats.txbytesunicast += pstx_fb->pkt_length; } } - else - { - priv->stats.txfeedbackfail++; - priv->stats.txerrtotal++; - priv->stats.txerrbytestotal += pstx_fb->pkt_length; - - /* We can not make sure broadcast/multicast or unicast mode. */ - if (pstx_fb->pkt_type == PACKET_MULTICAST) - { - priv->stats.txerrmulticast++; - } - else if (pstx_fb->pkt_type == PACKET_BROADCAST) - { - priv->stats.txerrbroadcast++; - } - else - { - priv->stats.txerrunicast++; - } - } - - priv->stats.txretrycount += pstx_fb->retry_cnt; - priv->stats.txfeedbackretry += pstx_fb->retry_cnt; - } @@ -403,29 +366,9 @@ static void cmpk_count_tx_status( struct net_device *dev, priv->stats.txfeedbackok += pstx_status->txok; priv->stats.txoktotal += pstx_status->txok; - priv->stats.txfeedbackfail += pstx_status->txfail; - priv->stats.txerrtotal += pstx_status->txfail; - - priv->stats.txretrycount += pstx_status->txretry; - priv->stats.txfeedbackretry += pstx_status->txretry; - - //pAdapter->TxStats.NumTxOkBytesTotal += psTx_FB->pkt_length; - //pAdapter->TxStats.NumTxErrBytesTotal += psTx_FB->pkt_length; - //pAdapter->MgntInfo.LinkDetectInfo.NumTxOkInPeriod++; - - priv->stats.txmulticast += pstx_status->txmcok; - priv->stats.txbroadcast += pstx_status->txbcok; priv->stats.txunicast += pstx_status->txucok; - priv->stats.txerrmulticast += pstx_status->txmcfail; - priv->stats.txerrbroadcast += pstx_status->txbcfail; - priv->stats.txerrunicast += pstx_status->txucfail; - - priv->stats.txbytesmulticast += pstx_status->txmclength; - priv->stats.txbytesbroadcast += pstx_status->txbclength; priv->stats.txbytesunicast += pstx_status->txuclength; - - priv->stats.last_packet_rate = pstx_status->rate; } @@ -454,13 +397,9 @@ cmpk_handle_tx_rate_history( struct net_device *dev, u8* pmsg) { - cmpk_tx_rahis_t *ptxrate; -// RT_RF_POWER_STATE rtState; - u8 i, j; + u8 i; u16 length = sizeof(cmpk_tx_rahis_t); u32 *ptemp; - struct r8192_priv *priv = ieee80211_priv(dev); - #ifdef ENABLE_PS pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); @@ -488,28 +427,6 @@ cmpk_handle_tx_rate_history( temp2 = ptemp[i]>>16; ptemp[i] = (temp1<<16)|temp2; } - - ptxrate = (cmpk_tx_rahis_t *)pmsg; - - if (ptxrate == NULL ) - { - return; - } - - for (i = 0; i < 16; i++) - { - // Collect CCK rate packet num - if (i < 4) - priv->stats.txrate.cck[i] += ptxrate->cck[i]; - - // Collect OFDM rate packet num - if (i< 8) - priv->stats.txrate.ofdm[i] += ptxrate->ofdm[i]; - - for (j = 0; j < 4; j++) - priv->stats.txrate.ht_mcs[j][i] += ptxrate->ht_mcs[j][i]; - } - } -- cgit v1.2.3 From dbf4805ee6a850e941110b0df1e96049287ecf75 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 23 Jan 2011 01:13:52 +0200 Subject: staging: easycap: fix sparse warnings 'Should it be static' easycap_main.c:41:23: warning: symbol 'easycapdc60_dongle' was not declared. Should it be static? easycap_main.c:49:22: warning: symbol 'easycap_usb_device_id_table' was not declared. Should it be static? easycap_main.c:69:30: warning: symbol 'easycap_fops' was not declared. Should it be static? easycap_main.c:82:29: warning: symbol 'easycap_vm_ops' was not declared. Should it be static? easycap_main.c:87:25: warning: symbol 'easycap_class' was not declared. Should it be static? easycap_main.c:95:35: warning: symbol 'v4l2_fops' was not declared. Should it be static? easycap_main.c:5071:1: warning: symbol 'easycap_module_init' was not declared. Should it be static? easycap_main.c:5101:1: warning: symbol 'easycap_module_exit' was not declared. Should it be static? easycap_low.c:45:50: warning: symbol 'stk1160configPAL' was not declared. Should it be static? easycap_low.c:87:28: warning: symbol 'stk1160configNTSC' was not declared. Should it be static? easycap_low.c:129:50: warning: symbol 'saa7113configPAL' was not declared. Should it be static? easycap_low.c:187:28: warning: symbol 'saa7113configNTSC' was not declared. Should it be static? easycap_ioctl.c:915:5: warning: symbol 'adjust_mute' was not declared. Should it be static? easycap_settings.c:42:31: warning: symbol 'easycap_standard' was not declared. Should it be static? easycap_settings.c:312:23: warning: symbol 'easycap_format' was not declared. Should it be static? easycap_settings.c:607:23: warning: symbol 'easycap_control' was not declared. Should it be static? Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_ioctl.c | 2 +- drivers/staging/easycap/easycap_low.c | 14 ++++++++++---- drivers/staging/easycap/easycap_main.c | 16 +++++++--------- drivers/staging/easycap/easycap_main.h | 1 + drivers/staging/easycap/easycap_settings.h | 3 +++ 5 files changed, 22 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index af6f04b06955..535a62b96e14 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -912,7 +912,7 @@ return -ENOENT; * THE URB AND THE PIPELINE COLLAPSES IRRETRIEVABLY. BEWARE. */ /*---------------------------------------------------------------------------*/ -int adjust_mute(struct easycap *peasycap, int value) +static int adjust_mute(struct easycap *peasycap, int value) { int i1; diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index ea0da6976d4c..ca48654573da 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -42,7 +42,10 @@ #include "easycap_low.h" /*--------------------------------------------------------------------------*/ -const struct stk1160config { int reg; int set; } stk1160configPAL[256] = { +static const struct stk1160config { + int reg; + int set; +} stk1160configPAL[256] = { {0x000, 0x0098}, {0x002, 0x0093}, @@ -84,7 +87,7 @@ const struct stk1160config { int reg; int set; } stk1160configPAL[256] = { {0xFFF, 0xFFFF} }; /*--------------------------------------------------------------------------*/ -const struct stk1160config stk1160configNTSC[256] = { +static const struct stk1160config stk1160configNTSC[256] = { {0x000, 0x0098}, {0x002, 0x0093}, @@ -126,7 +129,10 @@ const struct stk1160config stk1160configNTSC[256] = { {0xFFF, 0xFFFF} }; /*--------------------------------------------------------------------------*/ -const struct saa7113config { int reg; int set; } saa7113configPAL[256] = { +static const struct saa7113config{ + int reg; + int set; +} saa7113configPAL[256] = { {0x01, 0x08}, #if defined(ANTIALIAS) {0x02, 0xC0}, @@ -184,7 +190,7 @@ const struct saa7113config { int reg; int set; } saa7113configPAL[256] = { {0xFF, 0xFF} }; /*--------------------------------------------------------------------------*/ -const struct saa7113config saa7113configNTSC[256] = { +static const struct saa7113config saa7113configNTSC[256] = { {0x01, 0x08}, #if defined(ANTIALIAS) {0x02, 0xC0}, diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 34a1ba663e0b..a13418125ef1 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -46,7 +46,7 @@ static struct mutex mutex_dongle; * PARAMETERS APPLICABLE TO ENTIRE DRIVER, I.E. BOTH VIDEO AND AUDIO */ /*---------------------------------------------------------------------------*/ -struct usb_device_id easycap_usb_device_id_table[] = { +static struct usb_device_id easycap_usb_device_id_table[] = { { USB_DEVICE(USB_EASYCAP_VENDOR_ID, USB_EASYCAP_PRODUCT_ID) }, { } }; @@ -66,7 +66,7 @@ struct usb_driver easycap_usb_driver = { * THIS IS THE CASE FOR OpenSUSE. */ /*---------------------------------------------------------------------------*/ -const struct file_operations easycap_fops = { +static const struct file_operations easycap_fops = { .owner = THIS_MODULE, .open = easycap_open, .release = easycap_release, @@ -79,12 +79,12 @@ const struct file_operations easycap_fops = { .mmap = easycap_mmap, .llseek = no_llseek, }; -struct vm_operations_struct easycap_vm_ops = { +static const struct vm_operations_struct easycap_vm_ops = { .open = easycap_vma_open, .close = easycap_vma_close, .fault = easycap_vma_fault, }; -struct usb_class_driver easycap_class = { +static const struct usb_class_driver easycap_class = { .name = "usb/easycap%d", .fops = &easycap_fops, .minor_base = USB_SKEL_MINOR_BASE, @@ -92,7 +92,7 @@ struct usb_class_driver easycap_class = { /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #if defined(EASYCAP_IS_VIDEODEV_CLIENT) #if defined(EASYCAP_NEEDS_V4L2_FOPS) -const struct v4l2_file_operations v4l2_fops = { +static const struct v4l2_file_operations v4l2_fops = { .owner = THIS_MODULE, .open = easycap_open_noinode, .release = easycap_release_noinode, @@ -5067,8 +5067,7 @@ JOM(4, "ends\n"); return; } /*****************************************************************************/ -int __init -easycap_module_init(void) +static int __init easycap_module_init(void) { int k, rc; @@ -5097,8 +5096,7 @@ JOT(4, "ends\n"); return rc; } /*****************************************************************************/ -void __exit -easycap_module_exit(void) +static void __exit easycap_module_exit(void) { JOT(4, "begins\n"); diff --git a/drivers/staging/easycap/easycap_main.h b/drivers/staging/easycap/easycap_main.h index 11fcbbca0f0c..4c8577c92e43 100644 --- a/drivers/staging/easycap/easycap_main.h +++ b/drivers/staging/easycap/easycap_main.h @@ -31,6 +31,7 @@ extern struct easycap_standard easycap_standard[]; extern struct easycap_format easycap_format[]; extern struct v4l2_queryctrl easycap_control[]; extern struct usb_driver easycap_usb_driver; +extern struct easycap_dongle easycapdc60_dongle[]; #if defined(EASYCAP_NEEDS_ALSA) extern struct snd_pcm_ops easycap_alsa_ops; extern struct snd_pcm_hardware easycap_pcm_hardware; diff --git a/drivers/staging/easycap/easycap_settings.h b/drivers/staging/easycap/easycap_settings.h index 09b11cbea21e..fa13f5831f57 100644 --- a/drivers/staging/easycap/easycap_settings.h +++ b/drivers/staging/easycap/easycap_settings.h @@ -27,6 +27,9 @@ #if !defined(EASYCAP_SETTINGS_H) #define EASYCAP_SETTINGS_H +extern const struct easycap_standard easycap_standard[]; +extern struct v4l2_queryctrl easycap_control[]; +extern struct easycap_format easycap_format[]; extern struct easycap_dongle easycapdc60_dongle[]; #endif /*EASYCAP_SETTINGS_H*/ -- cgit v1.2.3 From d9e2d5962b083646cc9c218bfd358d07ae3b5925 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 23 Jan 2011 01:13:53 +0200 Subject: staging: easycap: fix sparse warnings :conversion of int to enum easycap_settings.c:587:58: warning: conversion of easycap_settings.c:587:58: unsigned int to easycap_settings.c:587:58: int enum v4l2_field easycap_settings.c:593:63: warning: conversion of easycap_settings.c:593:63: unsigned int to easycap_settings.c:593:63: int enum v4l2_colorspace Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_settings.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_settings.c b/drivers/staging/easycap/easycap_settings.c index 3a81cc26df03..3a5295738c1c 100644 --- a/drivers/staging/easycap/easycap_settings.c +++ b/drivers/staging/easycap/easycap_settings.c @@ -316,10 +316,10 @@ fillin_formats(void) { int i, j, k, m, n; __u32 width, height, pixelformat, bytesperline, sizeimage; -__u32 field, colorspace; +enum v4l2_field field; +enum v4l2_colorspace colorspace; __u16 mask1, mask2, mask3, mask4; char name1[32], name2[32], name3[32], name4[32]; - for (i = 0, n = 0; i < STANDARD_MANY; i++) { mask1 = 0x0000; switch (i) { -- cgit v1.2.3 From b4f63e9a0f1ca7c6df1f77fdabd4905f4639e8c6 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 23 Jan 2011 01:13:54 +0200 Subject: staging: easycap: remove redunant headers place all globals to easycap.h, which is included by all c-files easycap_standard: fix declaration vs. definiton conflict Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 19 +++++++++++++ drivers/staging/easycap/easycap_ioctl.c | 1 - drivers/staging/easycap/easycap_ioctl.h | 35 ------------------------ drivers/staging/easycap/easycap_low.c | 1 - drivers/staging/easycap/easycap_low.h | 32 ---------------------- drivers/staging/easycap/easycap_main.c | 1 - drivers/staging/easycap/easycap_main.h | 44 ------------------------------ drivers/staging/easycap/easycap_settings.c | 1 - drivers/staging/easycap/easycap_settings.h | 35 ------------------------ drivers/staging/easycap/easycap_sound.c | 1 - drivers/staging/easycap/easycap_sound.h | 40 --------------------------- drivers/staging/easycap/easycap_testcard.c | 1 - drivers/staging/easycap/easycap_testcard.h | 32 ---------------------- 13 files changed, 19 insertions(+), 224 deletions(-) delete mode 100644 drivers/staging/easycap/easycap_ioctl.h delete mode 100644 drivers/staging/easycap/easycap_low.h delete mode 100644 drivers/staging/easycap/easycap_main.h delete mode 100644 drivers/staging/easycap/easycap_settings.h delete mode 100644 drivers/staging/easycap/easycap_sound.h delete mode 100644 drivers/staging/easycap/easycap_testcard.h (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 337c9bdcfe4d..26bb25f7fe7c 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -727,4 +727,23 @@ extern int easycap_debug; } while (0) /*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/* globals + */ +/*---------------------------------------------------------------------------*/ + +extern const struct easycap_standard easycap_standard[]; +extern struct easycap_format easycap_format[]; +extern struct v4l2_queryctrl easycap_control[]; +extern struct usb_driver easycap_usb_driver; +extern struct easycap_dongle easycapdc60_dongle[]; +#if defined(EASYCAP_NEEDS_ALSA) +extern struct snd_pcm_ops easycap_alsa_ops; +extern struct snd_pcm_hardware easycap_pcm_hardware; +extern struct snd_card *psnd_card; +#else +extern struct usb_class_driver easyoss_class; +extern const struct file_operations easyoss_fops; +#endif /*EASYCAP_NEEDS_ALSA*/ + #endif /*EASYCAP_H*/ diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 535a62b96e14..bb2ee315c0ec 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -27,7 +27,6 @@ #include #include "easycap.h" -#include "easycap_ioctl.h" /*--------------------------------------------------------------------------*/ /* diff --git a/drivers/staging/easycap/easycap_ioctl.h b/drivers/staging/easycap/easycap_ioctl.h deleted file mode 100644 index 245386fd26ff..000000000000 --- a/drivers/staging/easycap/easycap_ioctl.h +++ /dev/null @@ -1,35 +0,0 @@ -/***************************************************************************** -* * -* easycap_ioctl.h * -* * -*****************************************************************************/ -/* - * - * Copyright (C) 2010 R.M. Thomas - * - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * -*/ -/*****************************************************************************/ -#if !defined(EASYCAP_IOCTL_H) -#define EASYCAP_IOCTL_H - -extern struct easycap_dongle easycapdc60_dongle[]; -extern struct easycap_standard easycap_standard[]; -extern struct easycap_format easycap_format[]; -extern struct v4l2_queryctrl easycap_control[]; - -#endif /*EASYCAP_IOCTL_H*/ diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index ca48654573da..6ab335a1e6d6 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -39,7 +39,6 @@ /****************************************************************************/ #include "easycap.h" -#include "easycap_low.h" /*--------------------------------------------------------------------------*/ static const struct stk1160config { diff --git a/drivers/staging/easycap/easycap_low.h b/drivers/staging/easycap/easycap_low.h deleted file mode 100644 index 7f3b393dca6e..000000000000 --- a/drivers/staging/easycap/easycap_low.h +++ /dev/null @@ -1,32 +0,0 @@ -/***************************************************************************** -* * -* easycap_low.h * -* * -*****************************************************************************/ -/* - * - * Copyright (C) 2010 R.M. Thomas - * - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * -*/ -/*****************************************************************************/ -#if !defined(EASYCAP_LOW_H) -#define EASYCAP_LOW_H - -extern struct easycap_dongle easycapdc60_dongle[]; - -#endif /*EASYCAP_LOW_H*/ diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index a13418125ef1..b15493e9da93 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -29,7 +29,6 @@ /*****************************************************************************/ #include "easycap.h" -#include "easycap_main.h" int easycap_debug; static int easycap_bars = 1; diff --git a/drivers/staging/easycap/easycap_main.h b/drivers/staging/easycap/easycap_main.h deleted file mode 100644 index 4c8577c92e43..000000000000 --- a/drivers/staging/easycap/easycap_main.h +++ /dev/null @@ -1,44 +0,0 @@ -/***************************************************************************** -* * -* easycap_main.h * -* * -*****************************************************************************/ -/* - * - * Copyright (C) 2010 R.M. Thomas - * - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * -*/ -/*****************************************************************************/ -#if !defined(EASYCAP_MAIN_H) -#define EASYCAP_MAIN_H - -extern struct easycap_standard easycap_standard[]; -extern struct easycap_format easycap_format[]; -extern struct v4l2_queryctrl easycap_control[]; -extern struct usb_driver easycap_usb_driver; -extern struct easycap_dongle easycapdc60_dongle[]; -#if defined(EASYCAP_NEEDS_ALSA) -extern struct snd_pcm_ops easycap_alsa_ops; -extern struct snd_pcm_hardware easycap_pcm_hardware; -extern struct snd_card *psnd_card; -#else -extern struct usb_class_driver easyoss_class; -extern const struct file_operations easyoss_fops; -#endif /*EASYCAP_NEEDS_ALSA*/ - -#endif /*EASYCAP_MAIN_H*/ diff --git a/drivers/staging/easycap/easycap_settings.c b/drivers/staging/easycap/easycap_settings.c index 3a5295738c1c..6ae1a73099fd 100644 --- a/drivers/staging/easycap/easycap_settings.c +++ b/drivers/staging/easycap/easycap_settings.c @@ -26,7 +26,6 @@ /*****************************************************************************/ #include "easycap.h" -#include "easycap_settings.h" /*---------------------------------------------------------------------------*/ /* diff --git a/drivers/staging/easycap/easycap_settings.h b/drivers/staging/easycap/easycap_settings.h deleted file mode 100644 index fa13f5831f57..000000000000 --- a/drivers/staging/easycap/easycap_settings.h +++ /dev/null @@ -1,35 +0,0 @@ -/***************************************************************************** -* * -* easycap_settings.h * -* * -*****************************************************************************/ -/* - * - * Copyright (C) 2010 R.M. Thomas - * - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * -*/ -/*****************************************************************************/ -#if !defined(EASYCAP_SETTINGS_H) -#define EASYCAP_SETTINGS_H - -extern const struct easycap_standard easycap_standard[]; -extern struct v4l2_queryctrl easycap_control[]; -extern struct easycap_format easycap_format[]; -extern struct easycap_dongle easycapdc60_dongle[]; - -#endif /*EASYCAP_SETTINGS_H*/ diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index 4bfaf06fb32a..d539e2886a2b 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -29,7 +29,6 @@ /*****************************************************************************/ #include "easycap.h" -#include "easycap_sound.h" #if defined(EASYCAP_NEEDS_ALSA) /*--------------------------------------------------------------------------*/ diff --git a/drivers/staging/easycap/easycap_sound.h b/drivers/staging/easycap/easycap_sound.h deleted file mode 100644 index ffcd6f203cca..000000000000 --- a/drivers/staging/easycap/easycap_sound.h +++ /dev/null @@ -1,40 +0,0 @@ -/***************************************************************************** -* * -* easycap_sound.h * -* * -*****************************************************************************/ -/* - * - * Copyright (C) 2010 R.M. Thomas - * - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * -*/ -/*****************************************************************************/ -#if !defined(EASYCAP_SOUND_H) -#define EASYCAP_SOUND_H - -extern struct easycap_dongle easycapdc60_dongle[]; -extern struct easycap *peasycap; -extern struct usb_driver easycap_usb_driver; -#if defined(EASYCAP_NEEDS_ALSA) -extern struct snd_pcm_hardware easycap_pcm_hardware; -#else -extern struct usb_class_driver easyoss_class; -extern const struct file_operations easyoss_fops; -#endif /*EASYCAP_NEEDS_ALSA*/ - -#endif /*EASYCAP_SOUND_H*/ diff --git a/drivers/staging/easycap/easycap_testcard.c b/drivers/staging/easycap/easycap_testcard.c index 1089603f2499..0f8336b6510f 100644 --- a/drivers/staging/easycap/easycap_testcard.c +++ b/drivers/staging/easycap/easycap_testcard.c @@ -26,7 +26,6 @@ /*****************************************************************************/ #include "easycap.h" -#include "easycap_testcard.h" /*****************************************************************************/ #define TESTCARD_BYTESPERLINE (2 * 720) diff --git a/drivers/staging/easycap/easycap_testcard.h b/drivers/staging/easycap/easycap_testcard.h deleted file mode 100644 index 2a21e7cfd8a5..000000000000 --- a/drivers/staging/easycap/easycap_testcard.h +++ /dev/null @@ -1,32 +0,0 @@ -/***************************************************************************** -* * -* easycap_testcard.h * -* * -*****************************************************************************/ -/* - * - * Copyright (C) 2010 R.M. Thomas - * - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * -*/ -/*****************************************************************************/ -#if !defined(EASYCAP_TESTCARD_H) -#define EASYCAP_TESTCARD_H - -extern struct easycap_dongle easycapdc60_dongle[]; - -#endif /*EASYCAP_TESTCARD_H*/ -- cgit v1.2.3 From 3dbab7331209d5d85c448675053d3e9e7a4bcd41 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 23 Jan 2011 01:13:55 +0200 Subject: staging: easycap: use #ifndef __EASYCAP_H_ for header inclusion protection use common #ifndef __EASYCAP_H_ instead of if (!defined(EASYCAP_H)) for protecting header from double inclusion Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 26bb25f7fe7c..360653cf7c7f 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -42,8 +42,8 @@ */ /*---------------------------------------------------------------------------*/ -#if (!defined(EASYCAP_H)) -#define EASYCAP_H +#ifndef __EASYCAP_H__ +#define __EASYCAP_H__ /*---------------------------------------------------------------------------*/ /* @@ -746,4 +746,4 @@ extern struct usb_class_driver easyoss_class; extern const struct file_operations easyoss_fops; #endif /*EASYCAP_NEEDS_ALSA*/ -#endif /*EASYCAP_H*/ +#endif /* !__EASYCAP_H__ */ -- cgit v1.2.3 From 02149cf7c7fd1ece5ada28f5a95914f4348df44f Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 23 Jan 2011 01:13:56 +0200 Subject: staging: easycap: group module parameters handling 1. For readability group module parameters handling on one place 2. Introduce kernel config option EASY_DEBUG Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/Kconfig | 12 ++++++++++++ drivers/staging/easycap/easycap.h | 6 +++--- drivers/staging/easycap/easycap_main.c | 29 ++++++++++++++++------------- 3 files changed, 31 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/Kconfig b/drivers/staging/easycap/Kconfig index eaa8a86e183b..4c1ad7e8b5ab 100644 --- a/drivers/staging/easycap/Kconfig +++ b/drivers/staging/easycap/Kconfig @@ -15,3 +15,15 @@ config EASYCAP To compile this driver as a module, choose M here: the module will be called easycap +config EASYCAP_DEBUG + bool "Enable EasyCAP driver debugging" + depends on EASYCAP + + ---help--- + This option enables debug printouts + + To enable debug, pass the debug level to the debug module + parameter: + + modprobe easycap debug=[0..9] + diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 360653cf7c7f..8a04bad1e1eb 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -668,7 +668,6 @@ unsigned long long int remainder; * IMMEDIATELY OBVIOUS FROM A CASUAL READING OF THE SOURCE CODE. BEWARE. */ /*---------------------------------------------------------------------------*/ -extern int easycap_debug; #define SAY(format, args...) do { \ printk(KERN_DEBUG "easycap:: %s: " \ format, __func__, ##args); \ @@ -678,7 +677,8 @@ extern int easycap_debug; format, peasycap->isdongle, __func__, ##args);\ } while (0) -#if defined(EASYCAP_DEBUG) +#ifdef CONFIG_EASYCAP_DEBUG +extern int easycap_debug; #define JOT(n, format, args...) do { \ if (n <= easycap_debug) { \ printk(KERN_DEBUG "easycap:: %s: " \ @@ -695,7 +695,7 @@ extern int easycap_debug; #else #define JOT(n, format, args...) do {} while (0) #define JOM(n, format, args...) do {} while (0) -#endif /*EASYCAP_DEBUG*/ +#endif /* CONFIG_EASYCAP_DEBUG */ #define MICROSECONDS(X, Y) \ ((1000000*((long long int)(X.tv_sec - Y.tv_sec))) + \ diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index b15493e9da93..9218410d182a 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -30,13 +30,26 @@ #include "easycap.h" + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("R.M. Thomas "); +MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION); +MODULE_VERSION(EASYCAP_DRIVER_VERSION); + +#ifdef CONFIG_EASYCAP_DEBUG int easycap_debug; -static int easycap_bars = 1; -static int easycap_gain = 16; module_param_named(debug, easycap_debug, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Debug level: 0(default),1,2,...,9"); +#endif /* CONFIG_EASYCAP_DEBUG */ + +static int easycap_bars = 1; module_param_named(bars, easycap_bars, int, S_IRUGO | S_IWUSR); -module_param_named(gain, easycap_gain, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(bars, + "Testcard bars on input signal failure: 0=>no, 1=>yes(default)"); +static int easycap_gain = 16; +module_param_named(gain, easycap_gain, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(gain, "Audio gain: 0,...,16(default),...31"); struct easycap_dongle easycapdc60_dongle[DONGLE_MANY]; static struct mutex mutex_dongle; @@ -5113,14 +5126,4 @@ JOT(4, "ends\n"); module_init(easycap_module_init); module_exit(easycap_module_exit); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("R.M. Thomas "); -MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION); -MODULE_VERSION(EASYCAP_DRIVER_VERSION); -#if defined(EASYCAP_DEBUG) -MODULE_PARM_DESC(debug, "Debug level: 0(default),1,2,...,9"); -#endif /*EASYCAP_DEBUG*/ -MODULE_PARM_DESC(bars, - "Testcard bars on input signal failure: 0=>no, 1=>yes(default)"); -MODULE_PARM_DESC(gain, "Audio gain: 0,...,16(default),...31"); /*****************************************************************************/ -- cgit v1.2.3 From d090bf57492bde9cb6281246c92963476c40b512 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 23 Jan 2011 01:13:57 +0200 Subject: staging: easycap: make functions local to easycap_main.c static 1. remove declarations from the header file 2. rearange code in main.c to reduce number of forward declarations Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 27 +--- drivers/staging/easycap/easycap_main.c | 262 +++++++++++++++------------------ 2 files changed, 122 insertions(+), 167 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 8a04bad1e1eb..f98ac6e1bb49 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -512,32 +512,10 @@ struct data_buffer audio_buffer[]; /* * VIDEO FUNCTION PROTOTYPES */ -/*---------------------------------------------------------------------------*/ -void easycap_complete(struct urb *); -int easycap_open(struct inode *, struct file *); -int easycap_release(struct inode *, struct file *); -long easycap_ioctl_noinode(struct file *, unsigned int, - unsigned long); -int easycap_ioctl(struct inode *, struct file *, unsigned int, - unsigned long); -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) -int easycap_open_noinode(struct file *); -int easycap_release_noinode(struct file *); -int videodev_release(struct video_device *); -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +long easycap_ioctl_noinode(struct file *, unsigned int, unsigned long); +int easycap_ioctl(struct inode *, struct file *, unsigned int, unsigned long); -unsigned int easycap_poll(struct file *, poll_table *); -int easycap_mmap(struct file *, struct vm_area_struct *); -int easycap_usb_probe(struct usb_interface *, - const struct usb_device_id *); -void easycap_usb_disconnect(struct usb_interface *); -void easycap_delete(struct kref *); - -void easycap_vma_open(struct vm_area_struct *); -void easycap_vma_close(struct vm_area_struct *); -int easycap_vma_fault(struct vm_area_struct *, struct vm_fault *); int easycap_dqbuf(struct easycap *, int); int submit_video_urbs(struct easycap *); int kill_video_urbs(struct easycap *); @@ -546,7 +524,6 @@ int redaub(struct easycap *, void *, void *, int, int, __u8, __u8, bool); void easycap_testcard(struct easycap *, int); int fillin_formats(void); -int reset(struct easycap *); int newinput(struct easycap *, int); int adjust_standard(struct easycap *, v4l2_std_id); int adjust_format(struct easycap *, __u32, __u32, __u32, diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 9218410d182a..85a26e3d54fb 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -50,25 +50,14 @@ MODULE_PARM_DESC(bars, static int easycap_gain = 16; module_param_named(gain, easycap_gain, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(gain, "Audio gain: 0,...,16(default),...31"); + + + struct easycap_dongle easycapdc60_dongle[DONGLE_MANY]; static struct mutex mutex_dongle; +static void easycap_complete(struct urb *purb); +static int reset(struct easycap *peasycap); -/*---------------------------------------------------------------------------*/ -/* - * PARAMETERS APPLICABLE TO ENTIRE DRIVER, I.E. BOTH VIDEO AND AUDIO - */ -/*---------------------------------------------------------------------------*/ -static struct usb_device_id easycap_usb_device_id_table[] = { -{ USB_DEVICE(USB_EASYCAP_VENDOR_ID, USB_EASYCAP_PRODUCT_ID) }, -{ } -}; -MODULE_DEVICE_TABLE(usb, easycap_usb_device_id_table); -struct usb_driver easycap_usb_driver = { -.name = "easycap", -.id_table = easycap_usb_device_id_table, -.probe = easycap_usb_probe, -.disconnect = easycap_usb_disconnect, -}; /*---------------------------------------------------------------------------*/ /* * PARAMETERS USED WHEN REGISTERING THE VIDEO INTERFACE @@ -78,46 +67,6 @@ struct usb_driver easycap_usb_driver = { * THIS IS THE CASE FOR OpenSUSE. */ /*---------------------------------------------------------------------------*/ -static const struct file_operations easycap_fops = { - .owner = THIS_MODULE, - .open = easycap_open, - .release = easycap_release, -#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL) - .unlocked_ioctl = easycap_ioctl_noinode, -#else - .ioctl = easycap_ioctl, -#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/ - .poll = easycap_poll, - .mmap = easycap_mmap, - .llseek = no_llseek, -}; -static const struct vm_operations_struct easycap_vm_ops = { - .open = easycap_vma_open, - .close = easycap_vma_close, - .fault = easycap_vma_fault, -}; -static const struct usb_class_driver easycap_class = { - .name = "usb/easycap%d", - .fops = &easycap_fops, - .minor_base = USB_SKEL_MINOR_BASE, -}; -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) -#if defined(EASYCAP_NEEDS_V4L2_FOPS) -static const struct v4l2_file_operations v4l2_fops = { - .owner = THIS_MODULE, - .open = easycap_open_noinode, - .release = easycap_release_noinode, -#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL) - .unlocked_ioctl = easycap_ioctl_noinode, -#else - .ioctl = easycap_ioctl, -#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/ - .poll = easycap_poll, - .mmap = easycap_mmap, -}; -#endif /*EASYCAP_NEEDS_V4L2_FOPS*/ -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /****************************************************************************/ /*---------------------------------------------------------------------------*/ @@ -139,18 +88,8 @@ for (k = 0; k < DONGLE_MANY; k++) { } return -1; } -/*****************************************************************************/ -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) -int -easycap_open_noinode(struct file *file) -{ -return easycap_open((struct inode *)NULL, file); -} -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -int -easycap_open(struct inode *inode, struct file *file) +static int easycap_open(struct inode *inode, struct file *file) { #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) struct usb_interface *pusb_interface; @@ -221,6 +160,7 @@ if (0 != rc) { } return 0; } + /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* @@ -230,8 +170,7 @@ return 0; * A BAD VIDEO FRAME SIZE. */ /*---------------------------------------------------------------------------*/ -int -reset(struct easycap *peasycap) +static int reset(struct easycap *peasycap) { struct easycap_standard const *peasycap_standard; int i, rc, input, rate; @@ -602,8 +541,7 @@ peasycap->video_junk = 0; return 0; } /*****************************************************************************/ -int -submit_video_urbs(struct easycap *peasycap) +int submit_video_urbs(struct easycap *peasycap) { struct data_urb *pdata_urb; struct urb *purb; @@ -793,18 +731,9 @@ if (peasycap->video_isoc_streaming) { return 0; } /****************************************************************************/ -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) -int -easycap_release_noinode(struct file *file) -{ -return easycap_release((struct inode *)NULL, file); -} -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*--------------------------------------------------------------------------*/ -int -easycap_release(struct inode *inode, struct file *file) +static int easycap_release(struct inode *inode, struct file *file) { #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) struct easycap *peasycap; @@ -834,11 +763,17 @@ JOM(4, "ending successfully\n"); return 0; } -/****************************************************************************/ -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #if defined(EASYCAP_IS_VIDEODEV_CLIENT) -int -videodev_release(struct video_device *pvideo_device) +static int easycap_open_noinode(struct file *file) +{ + return easycap_open(NULL, file); +} + +static int easycap_release_noinode(struct file *file) +{ + return easycap_release(NULL, file); +} +static int videodev_release(struct video_device *pvideo_device) { struct easycap *peasycap; @@ -873,8 +808,7 @@ return 0; * peasycap->pusb_device IS NO LONGER VALID. */ /*---------------------------------------------------------------------------*/ -void -easycap_delete(struct kref *pkref) +static void easycap_delete(struct kref *pkref) { int k, m, gone, kd; int allocation_video_urb, allocation_video_page, allocation_video_struct; @@ -1089,7 +1023,7 @@ JOT(4, "ending.\n"); return; } /*****************************************************************************/ -unsigned int easycap_poll(struct file *file, poll_table *wait) +static unsigned int easycap_poll(struct file *file, poll_table *wait) { struct easycap *peasycap; int rc, kd; @@ -2678,21 +2612,8 @@ return 0; * SEE CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGES 430-434 */ /*---------------------------------------------------------------------------*/ -int easycap_mmap(struct file *file, struct vm_area_struct *pvma) -{ - -JOT(8, "\n"); - -pvma->vm_ops = &easycap_vm_ops; -pvma->vm_flags |= VM_RESERVED; -if (NULL != file) - pvma->vm_private_data = file->private_data; -easycap_vma_open(pvma); -return 0; -} /*****************************************************************************/ -void -easycap_vma_open(struct vm_area_struct *pvma) +static void easycap_vma_open(struct vm_area_struct *pvma) { struct easycap *peasycap; @@ -2710,8 +2631,7 @@ JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); return; } /*****************************************************************************/ -void -easycap_vma_close(struct vm_area_struct *pvma) +static void easycap_vma_close(struct vm_area_struct *pvma) { struct easycap *peasycap; @@ -2729,8 +2649,7 @@ JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); return; } /*****************************************************************************/ -int -easycap_vma_fault(struct vm_area_struct *pvma, struct vm_fault *pvmf) +static int easycap_vma_fault(struct vm_area_struct *pvma, struct vm_fault *pvmf) { int k, m, retcode; void *pbuf; @@ -2793,6 +2712,24 @@ if (NULL == page) { } return retcode; } + +static const struct vm_operations_struct easycap_vm_ops = { + .open = easycap_vma_open, + .close = easycap_vma_close, + .fault = easycap_vma_fault, +}; + +static int easycap_mmap(struct file *file, struct vm_area_struct *pvma) +{ + JOT(8, "\n"); + + pvma->vm_ops = &easycap_vm_ops; + pvma->vm_flags |= VM_RESERVED; + if (NULL != file) + pvma->vm_private_data = file->private_data; + easycap_vma_open(pvma); + return 0; +} /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* @@ -2820,8 +2757,7 @@ return retcode; * 0 != (kount & 0x0100) => BUFFER HAS TWO EXTRA BYTES - WHY? */ /*---------------------------------------------------------------------------*/ -void -easycap_complete(struct urb *purb) +static void easycap_complete(struct urb *purb) { struct easycap *peasycap; struct data_buffer *pfield_buffer; @@ -3376,6 +3312,41 @@ if (peasycap->video_isoc_streaming) { } return; } +static const struct file_operations easycap_fops = { + .owner = THIS_MODULE, + .open = easycap_open, + .release = easycap_release, +#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL) + .unlocked_ioctl = easycap_ioctl_noinode, +#else + .ioctl = easycap_ioctl, +#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/ + .poll = easycap_poll, + .mmap = easycap_mmap, + .llseek = no_llseek, +}; +static const struct usb_class_driver easycap_class = { + .name = "usb/easycap%d", + .fops = &easycap_fops, + .minor_base = USB_SKEL_MINOR_BASE, +}; +/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#if defined(EASYCAP_IS_VIDEODEV_CLIENT) +#if defined(EASYCAP_NEEDS_V4L2_FOPS) +static const struct v4l2_file_operations v4l2_fops = { + .owner = THIS_MODULE, + .open = easycap_open_noinode, + .release = easycap_release_noinode, +#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL) + .unlocked_ioctl = easycap_ioctl_noinode, +#else + .ioctl = easycap_ioctl, +#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/ + .poll = easycap_poll, + .mmap = easycap_mmap, +}; +#endif /*EASYCAP_NEEDS_V4L2_FOPS*/ +#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* @@ -3383,9 +3354,8 @@ return; * TIMES, ONCE FOR EACH OF THE THREE INTERFACES. BEWARE. */ /*---------------------------------------------------------------------------*/ -int -easycap_usb_probe(struct usb_interface *pusb_interface, - const struct usb_device_id *pusb_device_id) +static int easycap_usb_probe(struct usb_interface *pusb_interface, + const struct usb_device_id *pusb_device_id) { struct usb_device *pusb_device, *pusb_device1; struct usb_host_interface *pusb_host_interface; @@ -4792,8 +4762,7 @@ return 0; * THIS FUNCTION AFFECTS BOTH OSS AND ALSA. BEWARE. */ /*---------------------------------------------------------------------------*/ -void -easycap_usb_disconnect(struct usb_interface *pusb_interface) +static void easycap_usb_disconnect(struct usb_interface *pusb_interface) { struct usb_host_interface *pusb_host_interface; struct usb_interface_descriptor *pusb_interface_descriptor; @@ -5079,47 +5048,56 @@ JOM(4, "ends\n"); return; } /*****************************************************************************/ -static int __init easycap_module_init(void) -{ -int k, rc; - -SAY("========easycap=======\n"); -JOT(4, "begins. %i=debug %i=bars %i=gain\n", easycap_debug, easycap_bars, - easycap_gain); -SAY("version: " EASYCAP_DRIVER_VERSION "\n"); -mutex_init(&mutex_dongle); -for (k = 0; k < DONGLE_MANY; k++) { - easycapdc60_dongle[k].peasycap = (struct easycap *)NULL; - mutex_init(&easycapdc60_dongle[k].mutex_video); - mutex_init(&easycapdc60_dongle[k].mutex_audio); -} /*---------------------------------------------------------------------------*/ /* - * REGISTER THIS DRIVER WITH THE USB SUBSYTEM. + * PARAMETERS APPLICABLE TO ENTIRE DRIVER, I.E. BOTH VIDEO AND AUDIO */ /*---------------------------------------------------------------------------*/ -JOT(4, "registering driver easycap\n"); -rc = usb_register(&easycap_usb_driver); -if (0 != rc) - SAY("ERROR: usb_register returned %i\n", rc); +static struct usb_device_id easycap_usb_device_id_table[] = { + {USB_DEVICE(USB_EASYCAP_VENDOR_ID, USB_EASYCAP_PRODUCT_ID)}, + { } +}; + +MODULE_DEVICE_TABLE(usb, easycap_usb_device_id_table); +struct usb_driver easycap_usb_driver = { + .name = "easycap", + .id_table = easycap_usb_device_id_table, + .probe = easycap_usb_probe, + .disconnect = easycap_usb_disconnect, +}; -JOT(4, "ends\n"); -return rc; +static int __init easycap_module_init(void) +{ + int k, rc; + + SAY("========easycap=======\n"); + JOT(4, "begins. %i=debug %i=bars %i=gain\n", + easycap_debug, easycap_bars, easycap_gain); + SAY("version: " EASYCAP_DRIVER_VERSION "\n"); + + mutex_init(&mutex_dongle); + for (k = 0; k < DONGLE_MANY; k++) { + easycapdc60_dongle[k].peasycap = (struct easycap *)NULL; + mutex_init(&easycapdc60_dongle[k].mutex_video); + mutex_init(&easycapdc60_dongle[k].mutex_audio); + } + JOT(4, "registering driver easycap\n"); + rc = usb_register(&easycap_usb_driver); + if (0 != rc) + SAY("ERROR: usb_register returned %i\n", rc); + + JOT(4, "ends\n"); + return rc; } /*****************************************************************************/ static void __exit easycap_module_exit(void) { -JOT(4, "begins\n"); + JOT(4, "begins\n"); -/*---------------------------------------------------------------------------*/ -/* - * DEREGISTER THIS DRIVER WITH THE USB SUBSYTEM. - */ -/*---------------------------------------------------------------------------*/ -usb_deregister(&easycap_usb_driver); + usb_deregister(&easycap_usb_driver); -JOT(4, "ends\n"); + JOT(4, "ends\n"); } /*****************************************************************************/ -- cgit v1.2.3 From 03389996e086fe61216692f0a2bb445051082902 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 23 Jan 2011 01:13:58 +0200 Subject: staging: easycap: easycap.h use indentation for first level replace struct { int a; } with more readable struct { int a; } Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 373 +++++++++++++++++++------------------- 1 file changed, 186 insertions(+), 187 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index f98ac6e1bb49..2f49d4af2f5b 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -218,28 +218,28 @@ */ /*---------------------------------------------------------------------------*/ enum { -AT_720x576, -AT_704x576, -AT_640x480, -AT_720x480, -AT_360x288, -AT_320x240, -AT_360x240, -RESOLUTION_MANY + AT_720x576, + AT_704x576, + AT_640x480, + AT_720x480, + AT_360x288, + AT_320x240, + AT_360x240, + RESOLUTION_MANY }; enum { -FMT_UYVY, -FMT_YUY2, -FMT_RGB24, -FMT_RGB32, -FMT_BGR24, -FMT_BGR32, -PIXELFORMAT_MANY + FMT_UYVY, + FMT_YUY2, + FMT_RGB24, + FMT_RGB32, + FMT_BGR24, + FMT_BGR32, + PIXELFORMAT_MANY }; enum { -FIELD_NONE, -FIELD_INTERLACED, -INTERLACE_MANY + FIELD_NONE, + FIELD_INTERLACED, + INTERLACE_MANY }; #define SETTINGS_MANY (STANDARD_MANY * \ RESOLUTION_MANY * \ @@ -252,50 +252,50 @@ INTERLACE_MANY */ /*---------------------------------------------------------------------------*/ struct easycap_dongle { -struct easycap *peasycap; -struct mutex mutex_video; -struct mutex mutex_audio; + struct easycap *peasycap; + struct mutex mutex_video; + struct mutex mutex_audio; }; /*---------------------------------------------------------------------------*/ struct data_buffer { -struct list_head list_head; -void *pgo; -void *pto; -__u16 kount; -__u16 input; + struct list_head list_head; + void *pgo; + void *pto; + __u16 kount; + __u16 input; }; /*---------------------------------------------------------------------------*/ struct data_urb { -struct list_head list_head; -struct urb *purb; -int isbuf; -int length; + struct list_head list_head; + struct urb *purb; + int isbuf; + int length; }; /*---------------------------------------------------------------------------*/ struct easycap_standard { -__u16 mask; + __u16 mask; struct v4l2_standard v4l2_standard; }; struct easycap_format { -__u16 mask; -char name[128]; + __u16 mask; + char name[128]; struct v4l2_format v4l2_format; }; struct inputset { -int input; -int input_ok; -int standard_offset; -int standard_offset_ok; -int format_offset; -int format_offset_ok; -int brightness; -int brightness_ok; -int contrast; -int contrast_ok; -int saturation; -int saturation_ok; -int hue; -int hue_ok; + int input; + int input_ok; + int standard_offset; + int standard_offset_ok; + int format_offset; + int format_offset_ok; + int brightness; + int brightness_ok; + int contrast; + int contrast_ok; + int saturation; + int saturation_ok; + int hue; + int hue_ok; }; /*---------------------------------------------------------------------------*/ /* @@ -306,187 +306,186 @@ int hue_ok; /*---------------------------------------------------------------------------*/ struct easycap { #define TELLTALE "expectedstring" -char telltale[16]; -int isdongle; -int minor; + char telltale[16]; + int isdongle; + int minor; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #if defined(EASYCAP_IS_VIDEODEV_CLIENT) -struct video_device video_device; + struct video_device video_device; #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) -struct v4l2_device v4l2_device; + struct v4l2_device v4l2_device; #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -int status; -unsigned int audio_pages_per_fragment; -unsigned int audio_bytes_per_fragment; -unsigned int audio_buffer_page_many; + int status; + unsigned int audio_pages_per_fragment; + unsigned int audio_bytes_per_fragment; + unsigned int audio_buffer_page_many; #define UPSAMPLE #if defined(UPSAMPLE) __s16 oldaudio; #endif /*UPSAMPLE*/ -int ilk; -bool microphone; - -struct usb_device *pusb_device; -struct usb_interface *pusb_interface; - -struct kref kref; - -int queued[FRAME_BUFFER_MANY]; -int done[FRAME_BUFFER_MANY]; - -wait_queue_head_t wq_video; -wait_queue_head_t wq_audio; -wait_queue_head_t wq_trigger; - -int input; -int polled; -int standard_offset; -int format_offset; -struct inputset inputset[INPUT_MANY]; - -bool ntsc; -int fps; -int usec; -int tolerate; -int skip; -int skipped; -int lost[INPUT_MANY]; -int merit[180]; - -struct timeval timeval0; -struct timeval timeval1; -struct timeval timeval2; -struct timeval timeval3; -struct timeval timeval6; -struct timeval timeval7; -struct timeval timeval8; -long long int dnbydt; - -int video_interface; -int video_altsetting_on; -int video_altsetting_off; -int video_endpointnumber; -int video_isoc_maxframesize; -int video_isoc_buffer_size; -int video_isoc_framesperdesc; - -int video_isoc_streaming; -int video_isoc_sequence; -int video_idle; -int video_eof; -int video_junk; - -struct data_buffer video_isoc_buffer[VIDEO_ISOC_BUFFER_MANY]; -struct data_buffer - field_buffer[FIELD_BUFFER_MANY][(FIELD_BUFFER_SIZE/PAGE_SIZE)]; -struct data_buffer - frame_buffer[FRAME_BUFFER_MANY][(FRAME_BUFFER_SIZE/PAGE_SIZE)]; - -struct list_head urb_video_head; -struct list_head *purb_video_head; - -__u8 cache[8]; -__u8 *pcache; -int video_mt; -int audio_mt; -long long audio_bytes; -__u32 isequence; - -int vma_many; - + int ilk; + bool microphone; + + struct usb_device *pusb_device; + struct usb_interface *pusb_interface; + + struct kref kref; + + int queued[FRAME_BUFFER_MANY]; + int done[FRAME_BUFFER_MANY]; + + wait_queue_head_t wq_video; + wait_queue_head_t wq_audio; + wait_queue_head_t wq_trigger; + + int input; + int polled; + int standard_offset; + int format_offset; + struct inputset inputset[INPUT_MANY]; + + bool ntsc; + int fps; + int usec; + int tolerate; + int skip; + int skipped; + int lost[INPUT_MANY]; + int merit[180]; + + struct timeval timeval0; + struct timeval timeval1; + struct timeval timeval2; + struct timeval timeval3; + struct timeval timeval6; + struct timeval timeval7; + struct timeval timeval8; + long long int dnbydt; + + int video_interface; + int video_altsetting_on; + int video_altsetting_off; + int video_endpointnumber; + int video_isoc_maxframesize; + int video_isoc_buffer_size; + int video_isoc_framesperdesc; + + int video_isoc_streaming; + int video_isoc_sequence; + int video_idle; + int video_eof; + int video_junk; + + struct data_buffer video_isoc_buffer[VIDEO_ISOC_BUFFER_MANY]; + struct data_buffer field_buffer[FIELD_BUFFER_MANY] + [(FIELD_BUFFER_SIZE/PAGE_SIZE)]; + struct data_buffer frame_buffer[FRAME_BUFFER_MANY] + [(FRAME_BUFFER_SIZE/PAGE_SIZE)]; + + struct list_head urb_video_head; + struct list_head *purb_video_head; + + __u8 cache[8]; + __u8 *pcache; + int video_mt; + int audio_mt; + long long audio_bytes; + __u32 isequence; + + int vma_many; /*---------------------------------------------------------------------------*/ /* * BUFFER INDICATORS */ /*---------------------------------------------------------------------------*/ -int field_fill; /* Field buffer being filled by easycap_complete(). */ + int field_fill; /* Field buffer being filled by easycap_complete(). */ /* Bumped only by easycap_complete(). */ -int field_page; /* Page of field buffer page being filled by */ + int field_page; /* Page of field buffer page being filled by */ /* easycap_complete(). */ -int field_read; /* Field buffer to be read by field2frame(). */ + int field_read; /* Field buffer to be read by field2frame(). */ /* Bumped only by easycap_complete(). */ -int frame_fill; /* Frame buffer being filled by field2frame(). */ + int frame_fill; /* Frame buffer being filled by field2frame(). */ /* Bumped only by easycap_dqbuf() when */ /* field2frame() has created a complete frame. */ -int frame_read; /* Frame buffer offered to user by DQBUF. */ + int frame_read; /* Frame buffer offered to user by DQBUF. */ /* Set only by easycap_dqbuf() to trail frame_fill.*/ -int frame_lock; /* Flag set to 1 by DQBUF and cleared by QBUF */ + int frame_lock; /* Flag set to 1 by DQBUF and cleared by QBUF */ /*---------------------------------------------------------------------------*/ /* * IMAGE PROPERTIES */ /*---------------------------------------------------------------------------*/ -__u32 pixelformat; -int width; -int height; -int bytesperpixel; -bool byteswaporder; -bool decimatepixel; -bool offerfields; -int frame_buffer_used; -int frame_buffer_many; -int videofieldamount; - -int brightness; -int contrast; -int saturation; -int hue; - -int allocation_video_urb; -int allocation_video_page; -int allocation_video_struct; -int registered_video; + __u32 pixelformat; + int width; + int height; + int bytesperpixel; + bool byteswaporder; + bool decimatepixel; + bool offerfields; + int frame_buffer_used; + int frame_buffer_many; + int videofieldamount; + + int brightness; + int contrast; + int saturation; + int hue; + + int allocation_video_urb; + int allocation_video_page; + int allocation_video_struct; + int registered_video; /*---------------------------------------------------------------------------*/ /* * ALSA */ /*---------------------------------------------------------------------------*/ #if defined(EASYCAP_NEEDS_ALSA) -struct snd_pcm_hardware alsa_hardware; -struct snd_card *psnd_card; -struct snd_pcm *psnd_pcm; -struct snd_pcm_substream *psubstream; -int dma_fill; -int dma_next; -int dma_read; + struct snd_pcm_hardware alsa_hardware; + struct snd_card *psnd_card; + struct snd_pcm *psnd_pcm; + struct snd_pcm_substream *psubstream; + int dma_fill; + int dma_next; + int dma_read; #endif /*EASYCAP_NEEDS_ALSA*/ /*---------------------------------------------------------------------------*/ /* * SOUND PROPERTIES */ /*---------------------------------------------------------------------------*/ -int audio_interface; -int audio_altsetting_on; -int audio_altsetting_off; -int audio_endpointnumber; -int audio_isoc_maxframesize; -int audio_isoc_buffer_size; -int audio_isoc_framesperdesc; + int audio_interface; + int audio_altsetting_on; + int audio_altsetting_off; + int audio_endpointnumber; + int audio_isoc_maxframesize; + int audio_isoc_buffer_size; + int audio_isoc_framesperdesc; -int audio_isoc_streaming; -int audio_idle; -int audio_eof; -int volume; -int mute; -s8 gain; + int audio_isoc_streaming; + int audio_idle; + int audio_eof; + int volume; + int mute; + s8 gain; -struct data_buffer audio_isoc_buffer[AUDIO_ISOC_BUFFER_MANY]; + struct data_buffer audio_isoc_buffer[AUDIO_ISOC_BUFFER_MANY]; -struct list_head urb_audio_head; -struct list_head *purb_audio_head; + struct list_head urb_audio_head; + struct list_head *purb_audio_head; /*---------------------------------------------------------------------------*/ /* * BUFFER INDICATORS */ /*---------------------------------------------------------------------------*/ -int audio_fill; /* Audio buffer being filled by easycap_complete(). */ + int audio_fill; /* Audio buffer being filled by easycap_complete(). */ /* Bumped only by easycap_complete(). */ -int audio_read; /* Audio buffer page being read by easycap_read(). */ + int audio_read; /* Audio buffer page being read by easycap_read(). */ /* Set by easycap_read() to trail audio_fill by */ /* one fragment. */ /*---------------------------------------------------------------------------*/ @@ -495,18 +494,18 @@ int audio_read; /* Audio buffer page being read by easycap_read(). */ */ /*---------------------------------------------------------------------------*/ -int audio_buffer_many; + int audio_buffer_many; -int allocation_audio_urb; -int allocation_audio_page; -int allocation_audio_struct; -int registered_audio; + int allocation_audio_urb; + int allocation_audio_page; + int allocation_audio_struct; + int registered_audio; -long long int audio_sample; -long long int audio_niveau; -long long int audio_square; + long long int audio_sample; + long long int audio_niveau; + long long int audio_square; -struct data_buffer audio_buffer[]; + struct data_buffer audio_buffer[]; }; /*---------------------------------------------------------------------------*/ /* -- cgit v1.2.3 From c659c38b2796578638548b77ef626d93609ec8ac Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 21 Jan 2011 10:59:30 +0000 Subject: tlan: Code cleanup: checkpatch.pl is relatively happy now. - Remove CamelCase. - Convert hexadecimals to lower case. - Remove useless comments. Tlan driver contained a name of the function at the end of it in a comment. Remove those comments. - Remove local typedefs. Use real types instead of typedefs in code. - Resolve space issues and reindent. - One warning remain, it's a case where printing a single line involves a number of printk()s. Signed-off-by: Sakari Ailus Signed-off-by: David S. Miller --- drivers/net/tlan.c | 3703 ++++++++++++++++++++++++++-------------------------- drivers/net/tlan.h | 192 +-- 2 files changed, 1967 insertions(+), 1928 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index f8e463cd8ecc..57380b1b3b60 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -63,45 +63,45 @@ * - Other minor stuff * * v1.4 Feb 10, 2000 - Updated with more changes required after Dave's - * network cleanup in 2.3.43pre7 (Tigran & myself) - * - Minor stuff. + * network cleanup in 2.3.43pre7 (Tigran & myself) + * - Minor stuff. * - * v1.5 March 22, 2000 - Fixed another timer bug that would hang the driver - * if no cable/link were present. + * v1.5 March 22, 2000 - Fixed another timer bug that would hang the + * driver if no cable/link were present. * - Cosmetic changes. * - TODO: Port completely to new PCI/DMA API - * Auto-Neg fallback. - * - * v1.6 April 04, 2000 - Fixed driver support for kernel-parameters. Haven't - * tested it though, as the kernel support is currently - * broken (2.3.99p4p3). - * - Updated tlan.txt accordingly. - * - Adjusted minimum/maximum frame length. - * - There is now a TLAN website up at - * http://hp.sourceforge.net/ - * - * v1.7 April 07, 2000 - Started to implement custom ioctls. Driver now - * reports PHY information when used with Donald - * Beckers userspace MII diagnostics utility. - * - * v1.8 April 23, 2000 - Fixed support for forced speed/duplex settings. - * - Added link information to Auto-Neg and forced - * modes. When NIC operates with auto-neg the driver - * will report Link speed & duplex modes as well as - * link partner abilities. When forced link is used, - * the driver will report status of the established - * link. - * Please read tlan.txt for additional information. - * - Removed call to check_region(), and used - * return value of request_region() instead. + * Auto-Neg fallback. + * + * v1.6 April 04, 2000 - Fixed driver support for kernel-parameters. + * Haven't tested it though, as the kernel support + * is currently broken (2.3.99p4p3). + * - Updated tlan.txt accordingly. + * - Adjusted minimum/maximum frame length. + * - There is now a TLAN website up at + * http://hp.sourceforge.net/ + * + * v1.7 April 07, 2000 - Started to implement custom ioctls. Driver now + * reports PHY information when used with Donald + * Beckers userspace MII diagnostics utility. + * + * v1.8 April 23, 2000 - Fixed support for forced speed/duplex settings. + * - Added link information to Auto-Neg and forced + * modes. When NIC operates with auto-neg the driver + * will report Link speed & duplex modes as well as + * link partner abilities. When forced link is used, + * the driver will report status of the established + * link. + * Please read tlan.txt for additional information. + * - Removed call to check_region(), and used + * return value of request_region() instead. * * v1.8a May 28, 2000 - Minor updates. * * v1.9 July 25, 2000 - Fixed a few remaining Full-Duplex issues. - * - Updated with timer fixes from Andrew Morton. - * - Fixed module race in TLan_Open. - * - Added routine to monitor PHY status. - * - Added activity led support for Proliant devices. + * - Updated with timer fixes from Andrew Morton. + * - Fixed module race in TLan_Open. + * - Added routine to monitor PHY status. + * - Added activity led support for Proliant devices. * * v1.10 Aug 30, 2000 - Added support for EISA based tlan controllers * like the Compaq NetFlex3/E. @@ -111,8 +111,8 @@ * hardware probe is done with kernel API and * TLan_EisaProbe. * - Adjusted debug information for probing. - * - Fixed bug that would cause general debug information - * to be printed after driver removal. + * - Fixed bug that would cause general debug + * information to be printed after driver removal. * - Added transmit timeout handling. * - Fixed OOM return values in tlan_probe. * - Fixed possible mem leak in tlan_exit @@ -136,8 +136,8 @@ * * v1.12 Oct 12, 2000 - Minor fixes (memleak, init, etc.) * - * v1.13 Nov 28, 2000 - Stop flooding console with auto-neg issues - * when link can't be established. + * v1.13 Nov 28, 2000 - Stop flooding console with auto-neg issues + * when link can't be established. * - Added the bbuf option as a kernel parameter. * - Fixed ioaddr probe bug. * - Fixed stupid deadlock with MII interrupts. @@ -147,28 +147,29 @@ * TLAN v1.0 silicon. This needs to be investigated * further. * - * v1.14 Dec 16, 2000 - Added support for servicing multiple frames per. - * interrupt. Thanks goes to - * Adam Keys - * Denis Beaudoin - * for providing the patch. - * - Fixed auto-neg output when using multiple - * adapters. - * - Converted to use new taskq interface. + * v1.14 Dec 16, 2000 - Added support for servicing multiple frames per. + * interrupt. Thanks goes to + * Adam Keys + * Denis Beaudoin + * for providing the patch. + * - Fixed auto-neg output when using multiple + * adapters. + * - Converted to use new taskq interface. * - * v1.14a Jan 6, 2001 - Minor adjustments (spinlocks, etc.) + * v1.14a Jan 6, 2001 - Minor adjustments (spinlocks, etc.) * * Samuel Chessman New Maintainer! * * v1.15 Apr 4, 2002 - Correct operation when aui=1 to be - * 10T half duplex no loopback - * Thanks to Gunnar Eikman + * 10T half duplex no loopback + * Thanks to Gunnar Eikman * * Sakari Ailus : * * v1.15a Dec 15 2008 - Remove bbuf support, it doesn't work anyway. + * v1.16 Jan 6 2011 - Make checkpatch.pl happy. * - *******************************************************************************/ + ******************************************************************************/ #include #include @@ -185,13 +186,11 @@ #include "tlan.h" -typedef u32 (TLanIntVectorFunc)( struct net_device *, u16 ); - /* For removing EISA devices */ -static struct net_device *TLan_Eisa_Devices; +static struct net_device *tlan_eisa_devices; -static int TLanDevicesInstalled; +static int tlan_devices_installed; /* Set speed, duplex and aui settings */ static int aui[MAX_TLAN_BOARDS]; @@ -202,7 +201,8 @@ module_param_array(aui, int, NULL, 0); module_param_array(duplex, int, NULL, 0); module_param_array(speed, int, NULL, 0); MODULE_PARM_DESC(aui, "ThunderLAN use AUI port(s) (0-1)"); -MODULE_PARM_DESC(duplex, "ThunderLAN duplex setting(s) (0-default, 1-half, 2-full)"); +MODULE_PARM_DESC(duplex, + "ThunderLAN duplex setting(s) (0-default, 1-half, 2-full)"); MODULE_PARM_DESC(speed, "ThunderLAN port speen setting(s) (0,10,100)"); MODULE_AUTHOR("Maintainer: Samuel Chessman "); @@ -218,139 +218,144 @@ static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "ThunderLAN debug mask"); -static const char TLanSignature[] = "TLAN"; -static const char tlan_banner[] = "ThunderLAN driver v1.15a\n"; +static const char tlan_signature[] = "TLAN"; +static const char tlan_banner[] = "ThunderLAN driver v1.16\n"; static int tlan_have_pci; static int tlan_have_eisa; -static const char *media[] = { - "10BaseT-HD ", "10BaseT-FD ","100baseTx-HD ", - "100baseTx-FD", "100baseT4", NULL +static const char * const media[] = { + "10BaseT-HD", "10BaseT-FD", "100baseTx-HD", + "100BaseTx-FD", "100BaseT4", NULL }; static struct board { - const char *deviceLabel; - u32 flags; - u16 addrOfs; + const char *device_label; + u32 flags; + u16 addr_ofs; } board_info[] = { { "Compaq Netelligent 10 T PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, - { "Compaq Netelligent 10/100 TX PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, + { "Compaq Netelligent 10/100 TX PCI UTP", + TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, { "Compaq Integrated NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 }, { "Compaq NetFlex-3/P", TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 }, { "Compaq NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 }, { "Compaq Netelligent Integrated 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, - { "Compaq Netelligent Dual 10/100 TX PCI UTP", TLAN_ADAPTER_NONE, 0x83 }, - { "Compaq Netelligent 10/100 TX Embedded UTP", TLAN_ADAPTER_NONE, 0x83 }, + { "Compaq Netelligent Dual 10/100 TX PCI UTP", + TLAN_ADAPTER_NONE, 0x83 }, + { "Compaq Netelligent 10/100 TX Embedded UTP", + TLAN_ADAPTER_NONE, 0x83 }, { "Olicom OC-2183/2185", TLAN_ADAPTER_USE_INTERN_10, 0x83 }, - { "Olicom OC-2325", TLAN_ADAPTER_UNMANAGED_PHY, 0xF8 }, - { "Olicom OC-2326", TLAN_ADAPTER_USE_INTERN_10, 0xF8 }, + { "Olicom OC-2325", TLAN_ADAPTER_UNMANAGED_PHY, 0xf8 }, + { "Olicom OC-2326", TLAN_ADAPTER_USE_INTERN_10, 0xf8 }, { "Compaq Netelligent 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, - { "Compaq Netelligent 10 T/2 PCI UTP/Coax", TLAN_ADAPTER_NONE, 0x83 }, + { "Compaq Netelligent 10 T/2 PCI UTP/coax", TLAN_ADAPTER_NONE, 0x83 }, { "Compaq NetFlex-3/E", - TLAN_ADAPTER_ACTIVITY_LED | /* EISA card */ + TLAN_ADAPTER_ACTIVITY_LED | /* EISA card */ TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 }, - { "Compaq NetFlex-3/E", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, /* EISA card */ + { "Compaq NetFlex-3/E", + TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, /* EISA card */ }; static DEFINE_PCI_DEVICE_TABLE(tlan_pci_tbl) = { { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL10, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3I, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_THUNDER, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3B, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100PI, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 }, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 }, { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100D, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 }, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 }, { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100I, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 }, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 }, { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2183, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2325, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 }, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 }, { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2326, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 }, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 }, { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_100_WS_5100, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 }, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 }, { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_T2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 }, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 }, { 0,} }; MODULE_DEVICE_TABLE(pci, tlan_pci_tbl); -static void TLan_EisaProbe( void ); -static void TLan_Eisa_Cleanup( void ); -static int TLan_Init( struct net_device * ); -static int TLan_Open( struct net_device *dev ); -static netdev_tx_t TLan_StartTx( struct sk_buff *, struct net_device *); -static irqreturn_t TLan_HandleInterrupt( int, void *); -static int TLan_Close( struct net_device *); -static struct net_device_stats *TLan_GetStats( struct net_device *); -static void TLan_SetMulticastList( struct net_device *); -static int TLan_ioctl( struct net_device *dev, struct ifreq *rq, int cmd); -static int TLan_probe1( struct pci_dev *pdev, long ioaddr, - int irq, int rev, const struct pci_device_id *ent); -static void TLan_tx_timeout( struct net_device *dev); -static void TLan_tx_timeout_work(struct work_struct *work); -static int tlan_init_one( struct pci_dev *pdev, const struct pci_device_id *ent); - -static u32 TLan_HandleTxEOF( struct net_device *, u16 ); -static u32 TLan_HandleStatOverflow( struct net_device *, u16 ); -static u32 TLan_HandleRxEOF( struct net_device *, u16 ); -static u32 TLan_HandleDummy( struct net_device *, u16 ); -static u32 TLan_HandleTxEOC( struct net_device *, u16 ); -static u32 TLan_HandleStatusCheck( struct net_device *, u16 ); -static u32 TLan_HandleRxEOC( struct net_device *, u16 ); - -static void TLan_Timer( unsigned long ); - -static void TLan_ResetLists( struct net_device * ); -static void TLan_FreeLists( struct net_device * ); -static void TLan_PrintDio( u16 ); -static void TLan_PrintList( TLanList *, char *, int ); -static void TLan_ReadAndClearStats( struct net_device *, int ); -static void TLan_ResetAdapter( struct net_device * ); -static void TLan_FinishReset( struct net_device * ); -static void TLan_SetMac( struct net_device *, int areg, char *mac ); - -static void TLan_PhyPrint( struct net_device * ); -static void TLan_PhyDetect( struct net_device * ); -static void TLan_PhyPowerDown( struct net_device * ); -static void TLan_PhyPowerUp( struct net_device * ); -static void TLan_PhyReset( struct net_device * ); -static void TLan_PhyStartLink( struct net_device * ); -static void TLan_PhyFinishAutoNeg( struct net_device * ); +static void tlan_eisa_probe(void); +static void tlan_eisa_cleanup(void); +static int tlan_init(struct net_device *); +static int tlan_open(struct net_device *dev); +static netdev_tx_t tlan_start_tx(struct sk_buff *, struct net_device *); +static irqreturn_t tlan_handle_interrupt(int, void *); +static int tlan_close(struct net_device *); +static struct net_device_stats *tlan_get_stats(struct net_device *); +static void tlan_set_multicast_list(struct net_device *); +static int tlan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static int tlan_probe1(struct pci_dev *pdev, long ioaddr, + int irq, int rev, const struct pci_device_id *ent); +static void tlan_tx_timeout(struct net_device *dev); +static void tlan_tx_timeout_work(struct work_struct *work); +static int tlan_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent); + +static u32 tlan_handle_tx_eof(struct net_device *, u16); +static u32 tlan_handle_stat_overflow(struct net_device *, u16); +static u32 tlan_handle_rx_eof(struct net_device *, u16); +static u32 tlan_handle_dummy(struct net_device *, u16); +static u32 tlan_handle_tx_eoc(struct net_device *, u16); +static u32 tlan_handle_status_check(struct net_device *, u16); +static u32 tlan_handle_rx_eoc(struct net_device *, u16); + +static void tlan_timer(unsigned long); + +static void tlan_reset_lists(struct net_device *); +static void tlan_free_lists(struct net_device *); +static void tlan_print_dio(u16); +static void tlan_print_list(struct tlan_list *, char *, int); +static void tlan_read_and_clear_stats(struct net_device *, int); +static void tlan_reset_adapter(struct net_device *); +static void tlan_finish_reset(struct net_device *); +static void tlan_set_mac(struct net_device *, int areg, char *mac); + +static void tlan_phy_print(struct net_device *); +static void tlan_phy_detect(struct net_device *); +static void tlan_phy_power_down(struct net_device *); +static void tlan_phy_power_up(struct net_device *); +static void tlan_phy_reset(struct net_device *); +static void tlan_phy_start_link(struct net_device *); +static void tlan_phy_finish_auto_neg(struct net_device *); #ifdef MONITOR -static void TLan_PhyMonitor( struct net_device * ); +static void tlan_phy_monitor(struct net_device *); #endif /* -static int TLan_PhyNop( struct net_device * ); -static int TLan_PhyInternalCheck( struct net_device * ); -static int TLan_PhyInternalService( struct net_device * ); -static int TLan_PhyDp83840aCheck( struct net_device * ); + static int tlan_phy_nop(struct net_device *); + static int tlan_phy_internal_check(struct net_device *); + static int tlan_phy_internal_service(struct net_device *); + static int tlan_phy_dp83840a_check(struct net_device *); */ -static bool TLan_MiiReadReg( struct net_device *, u16, u16, u16 * ); -static void TLan_MiiSendData( u16, u32, unsigned ); -static void TLan_MiiSync( u16 ); -static void TLan_MiiWriteReg( struct net_device *, u16, u16, u16 ); +static bool tlan_mii_read_reg(struct net_device *, u16, u16, u16 *); +static void tlan_mii_send_data(u16, u32, unsigned); +static void tlan_mii_sync(u16); +static void tlan_mii_write_reg(struct net_device *, u16, u16, u16); -static void TLan_EeSendStart( u16 ); -static int TLan_EeSendByte( u16, u8, int ); -static void TLan_EeReceiveByte( u16, u8 *, int ); -static int TLan_EeReadByte( struct net_device *, u8, u8 * ); +static void tlan_ee_send_start(u16); +static int tlan_ee_send_byte(u16, u8, int); +static void tlan_ee_receive_byte(u16, u8 *, int); +static int tlan_ee_read_byte(struct net_device *, u8, u8 *); static inline void -TLan_StoreSKB( struct tlan_list_tag *tag, struct sk_buff *skb) +tlan_store_skb(struct tlan_list *tag, struct sk_buff *skb) { unsigned long addr = (unsigned long)skb; tag->buffer[9].address = addr; @@ -358,7 +363,7 @@ TLan_StoreSKB( struct tlan_list_tag *tag, struct sk_buff *skb) } static inline struct sk_buff * -TLan_GetSKB( const struct tlan_list_tag *tag) +tlan_get_skb(const struct tlan_list *tag) { unsigned long addr; @@ -367,50 +372,50 @@ TLan_GetSKB( const struct tlan_list_tag *tag) return (struct sk_buff *) addr; } - -static TLanIntVectorFunc *TLanIntVector[TLAN_INT_NUMBER_OF_INTS] = { +static u32 +(*tlan_int_vector[TLAN_INT_NUMBER_OF_INTS])(struct net_device *, u16) = { NULL, - TLan_HandleTxEOF, - TLan_HandleStatOverflow, - TLan_HandleRxEOF, - TLan_HandleDummy, - TLan_HandleTxEOC, - TLan_HandleStatusCheck, - TLan_HandleRxEOC + tlan_handle_tx_eof, + tlan_handle_stat_overflow, + tlan_handle_rx_eof, + tlan_handle_dummy, + tlan_handle_tx_eoc, + tlan_handle_status_check, + tlan_handle_rx_eoc }; static inline void -TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type ) +tlan_set_timer(struct net_device *dev, u32 ticks, u32 type) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); unsigned long flags = 0; if (!in_irq()) spin_lock_irqsave(&priv->lock, flags); - if ( priv->timer.function != NULL && - priv->timerType != TLAN_TIMER_ACTIVITY ) { + if (priv->timer.function != NULL && + priv->timer_type != TLAN_TIMER_ACTIVITY) { if (!in_irq()) spin_unlock_irqrestore(&priv->lock, flags); return; } - priv->timer.function = TLan_Timer; + priv->timer.function = tlan_timer; if (!in_irq()) spin_unlock_irqrestore(&priv->lock, flags); priv->timer.data = (unsigned long) dev; - priv->timerSetAt = jiffies; - priv->timerType = type; + priv->timer_set_at = jiffies; + priv->timer_type = type; mod_timer(&priv->timer, jiffies + ticks); -} /* TLan_SetTimer */ +} /***************************************************************************** ****************************************************************************** - ThunderLAN Driver Primary Functions +ThunderLAN driver primary functions - These functions are more or less common to all Linux network drivers. +these functions are more or less common to all linux network drivers. ****************************************************************************** *****************************************************************************/ @@ -419,42 +424,42 @@ TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type ) - /*************************************************************** - * tlan_remove_one - * - * Returns: - * Nothing - * Parms: - * None - * - * Goes through the TLanDevices list and frees the device - * structs and memory associated with each device (lists - * and buffers). It also ureserves the IO port regions - * associated with this device. - * - **************************************************************/ +/*************************************************************** + * tlan_remove_one + * + * Returns: + * Nothing + * Parms: + * None + * + * Goes through the TLanDevices list and frees the device + * structs and memory associated with each device (lists + * and buffers). It also ureserves the IO port regions + * associated with this device. + * + **************************************************************/ -static void __devexit tlan_remove_one( struct pci_dev *pdev) +static void __devexit tlan_remove_one(struct pci_dev *pdev) { - struct net_device *dev = pci_get_drvdata( pdev ); - TLanPrivateInfo *priv = netdev_priv(dev); + struct net_device *dev = pci_get_drvdata(pdev); + struct tlan_priv *priv = netdev_priv(dev); - unregister_netdev( dev ); + unregister_netdev(dev); - if ( priv->dmaStorage ) { - pci_free_consistent(priv->pciDev, - priv->dmaSize, priv->dmaStorage, - priv->dmaStorageDMA ); + if (priv->dma_storage) { + pci_free_consistent(priv->pci_dev, + priv->dma_size, priv->dma_storage, + priv->dma_storage_dma); } #ifdef CONFIG_PCI pci_release_regions(pdev); #endif - free_netdev( dev ); + free_netdev(dev); - pci_set_drvdata( pdev, NULL ); + pci_set_drvdata(pdev, NULL); } static struct pci_driver tlan_driver = { @@ -482,13 +487,13 @@ static int __init tlan_probe(void) } TLAN_DBG(TLAN_DEBUG_PROBE, "Starting EISA Probe....\n"); - TLan_EisaProbe(); + tlan_eisa_probe(); printk(KERN_INFO "TLAN: %d device%s installed, PCI: %d EISA: %d\n", - TLanDevicesInstalled, TLanDevicesInstalled == 1 ? "" : "s", - tlan_have_pci, tlan_have_eisa); + tlan_devices_installed, tlan_devices_installed == 1 ? "" : "s", + tlan_have_pci, tlan_have_eisa); - if (TLanDevicesInstalled == 0) { + if (tlan_devices_installed == 0) { rc = -ENODEV; goto err_out_pci_unreg; } @@ -501,39 +506,39 @@ err_out_pci_free: } -static int __devinit tlan_init_one( struct pci_dev *pdev, - const struct pci_device_id *ent) +static int __devinit tlan_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) { - return TLan_probe1( pdev, -1, -1, 0, ent); + return tlan_probe1(pdev, -1, -1, 0, ent); } /* - *************************************************************** - * tlan_probe1 - * - * Returns: - * 0 on success, error code on error - * Parms: - * none - * - * The name is lower case to fit in with all the rest of - * the netcard_probe names. This function looks for - * another TLan based adapter, setting it up with the - * allocated device struct if one is found. - * tlan_probe has been ported to the new net API and - * now allocates its own device structure. This function - * is also used by modules. - * - **************************************************************/ - -static int __devinit TLan_probe1(struct pci_dev *pdev, +*************************************************************** +* tlan_probe1 +* +* Returns: +* 0 on success, error code on error +* Parms: +* none +* +* The name is lower case to fit in with all the rest of +* the netcard_probe names. This function looks for +* another TLan based adapter, setting it up with the +* allocated device struct if one is found. +* tlan_probe has been ported to the new net API and +* now allocates its own device structure. This function +* is also used by modules. +* +**************************************************************/ + +static int __devinit tlan_probe1(struct pci_dev *pdev, long ioaddr, int irq, int rev, - const struct pci_device_id *ent ) + const struct pci_device_id *ent) { struct net_device *dev; - TLanPrivateInfo *priv; + struct tlan_priv *priv; u16 device_id; int reg, rc = -ENODEV; @@ -543,7 +548,7 @@ static int __devinit TLan_probe1(struct pci_dev *pdev, if (rc) return rc; - rc = pci_request_regions(pdev, TLanSignature); + rc = pci_request_regions(pdev, tlan_signature); if (rc) { printk(KERN_ERR "TLAN: Could not reserve IO regions\n"); goto err_out; @@ -551,7 +556,7 @@ static int __devinit TLan_probe1(struct pci_dev *pdev, } #endif /* CONFIG_PCI */ - dev = alloc_etherdev(sizeof(TLanPrivateInfo)); + dev = alloc_etherdev(sizeof(struct tlan_priv)); if (dev == NULL) { printk(KERN_ERR "TLAN: Could not allocate memory for device.\n"); rc = -ENOMEM; @@ -561,26 +566,28 @@ static int __devinit TLan_probe1(struct pci_dev *pdev, priv = netdev_priv(dev); - priv->pciDev = pdev; + priv->pci_dev = pdev; priv->dev = dev; /* Is this a PCI device? */ if (pdev) { - u32 pci_io_base = 0; + u32 pci_io_base = 0; priv->adapter = &board_info[ent->driver_data]; rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (rc) { - printk(KERN_ERR "TLAN: No suitable PCI mapping available.\n"); + printk(KERN_ERR + "TLAN: No suitable PCI mapping available.\n"); goto err_out_free_dev; } - for ( reg= 0; reg <= 5; reg ++ ) { + for (reg = 0; reg <= 5; reg++) { if (pci_resource_flags(pdev, reg) & IORESOURCE_IO) { pci_io_base = pci_resource_start(pdev, reg); - TLAN_DBG( TLAN_DEBUG_GNRL, "IO mapping is available at %x.\n", - pci_io_base); + TLAN_DBG(TLAN_DEBUG_GNRL, + "IO mapping is available at %x.\n", + pci_io_base); break; } } @@ -592,7 +599,7 @@ static int __devinit TLan_probe1(struct pci_dev *pdev, dev->base_addr = pci_io_base; dev->irq = pdev->irq; - priv->adapterRev = pdev->revision; + priv->adapter_rev = pdev->revision; pci_set_master(pdev); pci_set_drvdata(pdev, dev); @@ -602,11 +609,11 @@ static int __devinit TLan_probe1(struct pci_dev *pdev, device_id = inw(ioaddr + EISA_ID2); priv->is_eisa = 1; if (device_id == 0x20F1) { - priv->adapter = &board_info[13]; /* NetFlex-3/E */ - priv->adapterRev = 23; /* TLAN 2.3 */ + priv->adapter = &board_info[13]; /* NetFlex-3/E */ + priv->adapter_rev = 23; /* TLAN 2.3 */ } else { priv->adapter = &board_info[14]; - priv->adapterRev = 10; /* TLAN 1.0 */ + priv->adapter_rev = 10; /* TLAN 1.0 */ } dev->base_addr = ioaddr; dev->irq = irq; @@ -620,11 +627,11 @@ static int __devinit TLan_probe1(struct pci_dev *pdev, priv->speed = ((dev->mem_start & 0x18) == 0x18) ? 0 : (dev->mem_start & 0x18) >> 3; - if (priv->speed == 0x1) { + if (priv->speed == 0x1) priv->speed = TLAN_SPEED_10; - } else if (priv->speed == 0x2) { + else if (priv->speed == 0x2) priv->speed = TLAN_SPEED_100; - } + debug = priv->debug = dev->mem_end; } else { priv->aui = aui[boards_found]; @@ -635,11 +642,11 @@ static int __devinit TLan_probe1(struct pci_dev *pdev, /* This will be used when we get an adapter error from * within our irq handler */ - INIT_WORK(&priv->tlan_tqueue, TLan_tx_timeout_work); + INIT_WORK(&priv->tlan_tqueue, tlan_tx_timeout_work); spin_lock_init(&priv->lock); - rc = TLan_Init(dev); + rc = tlan_init(dev); if (rc) { printk(KERN_ERR "TLAN: Could not set up device.\n"); goto err_out_free_dev; @@ -652,29 +659,29 @@ static int __devinit TLan_probe1(struct pci_dev *pdev, } - TLanDevicesInstalled++; + tlan_devices_installed++; boards_found++; /* pdev is NULL if this is an EISA device */ if (pdev) tlan_have_pci++; else { - priv->nextDevice = TLan_Eisa_Devices; - TLan_Eisa_Devices = dev; + priv->next_device = tlan_eisa_devices; + tlan_eisa_devices = dev; tlan_have_eisa++; } printk(KERN_INFO "TLAN: %s irq=%2d, io=%04x, %s, Rev. %d\n", - dev->name, - (int) dev->irq, - (int) dev->base_addr, - priv->adapter->deviceLabel, - priv->adapterRev); + dev->name, + (int) dev->irq, + (int) dev->base_addr, + priv->adapter->device_label, + priv->adapter_rev); return 0; err_out_uninit: - pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage, - priv->dmaStorageDMA ); + pci_free_consistent(priv->pci_dev, priv->dma_size, priv->dma_storage, + priv->dma_storage_dma); err_out_free_dev: free_netdev(dev); err_out_regions: @@ -689,22 +696,23 @@ err_out: } -static void TLan_Eisa_Cleanup(void) +static void tlan_eisa_cleanup(void) { struct net_device *dev; - TLanPrivateInfo *priv; + struct tlan_priv *priv; - while( tlan_have_eisa ) { - dev = TLan_Eisa_Devices; + while (tlan_have_eisa) { + dev = tlan_eisa_devices; priv = netdev_priv(dev); - if (priv->dmaStorage) { - pci_free_consistent(priv->pciDev, priv->dmaSize, - priv->dmaStorage, priv->dmaStorageDMA ); + if (priv->dma_storage) { + pci_free_consistent(priv->pci_dev, priv->dma_size, + priv->dma_storage, + priv->dma_storage_dma); } - release_region( dev->base_addr, 0x10); - unregister_netdev( dev ); - TLan_Eisa_Devices = priv->nextDevice; - free_netdev( dev ); + release_region(dev->base_addr, 0x10); + unregister_netdev(dev); + tlan_eisa_devices = priv->next_device; + free_netdev(dev); tlan_have_eisa--; } } @@ -715,7 +723,7 @@ static void __exit tlan_exit(void) pci_unregister_driver(&tlan_driver); if (tlan_have_eisa) - TLan_Eisa_Cleanup(); + tlan_eisa_cleanup(); } @@ -726,24 +734,24 @@ module_exit(tlan_exit); - /************************************************************** - * TLan_EisaProbe - * - * Returns: 0 on success, 1 otherwise - * - * Parms: None - * - * - * This functions probes for EISA devices and calls - * TLan_probe1 when one is found. - * - *************************************************************/ +/************************************************************** + * tlan_eisa_probe + * + * Returns: 0 on success, 1 otherwise + * + * Parms: None + * + * + * This functions probes for EISA devices and calls + * TLan_probe1 when one is found. + * + *************************************************************/ -static void __init TLan_EisaProbe (void) +static void __init tlan_eisa_probe(void) { - long ioaddr; - int rc = -ENODEV; - int irq; + long ioaddr; + int rc = -ENODEV; + int irq; u16 device_id; if (!EISA_bus) { @@ -754,15 +762,16 @@ static void __init TLan_EisaProbe (void) /* Loop through all slots of the EISA bus */ for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) { - TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n", - (int) ioaddr + 0xC80, inw(ioaddr + EISA_ID)); - TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n", - (int) ioaddr + 0xC82, inw(ioaddr + EISA_ID2)); + TLAN_DBG(TLAN_DEBUG_PROBE, "EISA_ID 0x%4x: 0x%4x\n", + (int) ioaddr + 0xc80, inw(ioaddr + EISA_ID)); + TLAN_DBG(TLAN_DEBUG_PROBE, "EISA_ID 0x%4x: 0x%4x\n", + (int) ioaddr + 0xc82, inw(ioaddr + EISA_ID2)); - TLAN_DBG(TLAN_DEBUG_PROBE, "Probing for EISA adapter at IO: 0x%4x : ", - (int) ioaddr); - if (request_region(ioaddr, 0x10, TLanSignature) == NULL) + TLAN_DBG(TLAN_DEBUG_PROBE, + "Probing for EISA adapter at IO: 0x%4x : ", + (int) ioaddr); + if (request_region(ioaddr, 0x10, tlan_signature) == NULL) goto out; if (inw(ioaddr + EISA_ID) != 0x110E) { @@ -772,180 +781,186 @@ static void __init TLan_EisaProbe (void) device_id = inw(ioaddr + EISA_ID2); if (device_id != 0x20F1 && device_id != 0x40F1) { - release_region (ioaddr, 0x10); + release_region(ioaddr, 0x10); goto out; } - if (inb(ioaddr + EISA_CR) != 0x1) { /* Check if adapter is enabled */ - release_region (ioaddr, 0x10); + /* check if adapter is enabled */ + if (inb(ioaddr + EISA_CR) != 0x1) { + release_region(ioaddr, 0x10); goto out2; } if (debug == 0x10) - printk("Found one\n"); + printk(KERN_INFO "Found one\n"); /* Get irq from board */ - switch (inb(ioaddr + 0xCC0)) { - case(0x10): - irq=5; - break; - case(0x20): - irq=9; - break; - case(0x40): - irq=10; - break; - case(0x80): - irq=11; - break; - default: - goto out; + switch (inb(ioaddr + 0xcc0)) { + case(0x10): + irq = 5; + break; + case(0x20): + irq = 9; + break; + case(0x40): + irq = 10; + break; + case(0x80): + irq = 11; + break; + default: + goto out; } /* Setup the newly found eisa adapter */ - rc = TLan_probe1( NULL, ioaddr, irq, - 12, NULL); + rc = tlan_probe1(NULL, ioaddr, irq, + 12, NULL); continue; - out: - if (debug == 0x10) - printk("None found\n"); - continue; +out: + if (debug == 0x10) + printk(KERN_INFO "None found\n"); + continue; - out2: if (debug == 0x10) - printk("Card found but it is not enabled, skipping\n"); - continue; +out2: + if (debug == 0x10) + printk(KERN_INFO "Card found but it is not enabled, skipping\n"); + continue; } -} /* TLan_EisaProbe */ +} #ifdef CONFIG_NET_POLL_CONTROLLER -static void TLan_Poll(struct net_device *dev) +static void tlan_poll(struct net_device *dev) { disable_irq(dev->irq); - TLan_HandleInterrupt(dev->irq, dev); + tlan_handle_interrupt(dev->irq, dev); enable_irq(dev->irq); } #endif -static const struct net_device_ops TLan_netdev_ops = { - .ndo_open = TLan_Open, - .ndo_stop = TLan_Close, - .ndo_start_xmit = TLan_StartTx, - .ndo_tx_timeout = TLan_tx_timeout, - .ndo_get_stats = TLan_GetStats, - .ndo_set_multicast_list = TLan_SetMulticastList, - .ndo_do_ioctl = TLan_ioctl, +static const struct net_device_ops tlan_netdev_ops = { + .ndo_open = tlan_open, + .ndo_stop = tlan_close, + .ndo_start_xmit = tlan_start_tx, + .ndo_tx_timeout = tlan_tx_timeout, + .ndo_get_stats = tlan_get_stats, + .ndo_set_multicast_list = tlan_set_multicast_list, + .ndo_do_ioctl = tlan_ioctl, .ndo_change_mtu = eth_change_mtu, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, #ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = TLan_Poll, + .ndo_poll_controller = tlan_poll, #endif }; - /*************************************************************** - * TLan_Init - * - * Returns: - * 0 on success, error code otherwise. - * Parms: - * dev The structure of the device to be - * init'ed. - * - * This function completes the initialization of the - * device structure and driver. It reserves the IO - * addresses, allocates memory for the lists and bounce - * buffers, retrieves the MAC address from the eeprom - * and assignes the device's methods. - * - **************************************************************/ - -static int TLan_Init( struct net_device *dev ) +/*************************************************************** + * tlan_init + * + * Returns: + * 0 on success, error code otherwise. + * Parms: + * dev The structure of the device to be + * init'ed. + * + * This function completes the initialization of the + * device structure and driver. It reserves the IO + * addresses, allocates memory for the lists and bounce + * buffers, retrieves the MAC address from the eeprom + * and assignes the device's methods. + * + **************************************************************/ + +static int tlan_init(struct net_device *dev) { int dma_size; - int err; + int err; int i; - TLanPrivateInfo *priv; + struct tlan_priv *priv; priv = netdev_priv(dev); - dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS ) - * ( sizeof(TLanList) ); - priv->dmaStorage = pci_alloc_consistent(priv->pciDev, - dma_size, &priv->dmaStorageDMA); - priv->dmaSize = dma_size; - - if ( priv->dmaStorage == NULL ) { - printk(KERN_ERR "TLAN: Could not allocate lists and buffers for %s.\n", - dev->name ); + dma_size = (TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS) + * (sizeof(struct tlan_list)); + priv->dma_storage = pci_alloc_consistent(priv->pci_dev, + dma_size, + &priv->dma_storage_dma); + priv->dma_size = dma_size; + + if (priv->dma_storage == NULL) { + printk(KERN_ERR + "TLAN: Could not allocate lists and buffers for %s.\n", + dev->name); return -ENOMEM; } - memset( priv->dmaStorage, 0, dma_size ); - priv->rxList = (TLanList *) ALIGN((unsigned long)priv->dmaStorage, 8); - priv->rxListDMA = ALIGN(priv->dmaStorageDMA, 8); - priv->txList = priv->rxList + TLAN_NUM_RX_LISTS; - priv->txListDMA = priv->rxListDMA + sizeof(TLanList) * TLAN_NUM_RX_LISTS; + memset(priv->dma_storage, 0, dma_size); + priv->rx_list = (struct tlan_list *) + ALIGN((unsigned long)priv->dma_storage, 8); + priv->rx_list_dma = ALIGN(priv->dma_storage_dma, 8); + priv->tx_list = priv->rx_list + TLAN_NUM_RX_LISTS; + priv->tx_list_dma = + priv->rx_list_dma + sizeof(struct tlan_list)*TLAN_NUM_RX_LISTS; err = 0; - for ( i = 0; i < 6 ; i++ ) - err |= TLan_EeReadByte( dev, - (u8) priv->adapter->addrOfs + i, - (u8 *) &dev->dev_addr[i] ); - if ( err ) { + for (i = 0; i < 6 ; i++) + err |= tlan_ee_read_byte(dev, + (u8) priv->adapter->addr_ofs + i, + (u8 *) &dev->dev_addr[i]); + if (err) { printk(KERN_ERR "TLAN: %s: Error reading MAC from eeprom: %d\n", - dev->name, - err ); + dev->name, + err); } dev->addr_len = 6; netif_carrier_off(dev); /* Device methods */ - dev->netdev_ops = &TLan_netdev_ops; + dev->netdev_ops = &tlan_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; return 0; -} /* TLan_Init */ +} - /*************************************************************** - * TLan_Open - * - * Returns: - * 0 on success, error code otherwise. - * Parms: - * dev Structure of device to be opened. - * - * This routine puts the driver and TLAN adapter in a - * state where it is ready to send and receive packets. - * It allocates the IRQ, resets and brings the adapter - * out of reset, and allows interrupts. It also delays - * the startup for autonegotiation or sends a Rx GO - * command to the adapter, as appropriate. - * - **************************************************************/ +/*************************************************************** + * tlan_open + * + * Returns: + * 0 on success, error code otherwise. + * Parms: + * dev Structure of device to be opened. + * + * This routine puts the driver and TLAN adapter in a + * state where it is ready to send and receive packets. + * It allocates the IRQ, resets and brings the adapter + * out of reset, and allows interrupts. It also delays + * the startup for autonegotiation or sends a Rx GO + * command to the adapter, as appropriate. + * + **************************************************************/ -static int TLan_Open( struct net_device *dev ) +static int tlan_open(struct net_device *dev) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); int err; - priv->tlanRev = TLan_DioRead8( dev->base_addr, TLAN_DEF_REVISION ); - err = request_irq( dev->irq, TLan_HandleInterrupt, IRQF_SHARED, - dev->name, dev ); + priv->tlan_rev = tlan_dio_read8(dev->base_addr, TLAN_DEF_REVISION); + err = request_irq(dev->irq, tlan_handle_interrupt, IRQF_SHARED, + dev->name, dev); - if ( err ) { + if (err) { pr_err("TLAN: Cannot open %s because IRQ %d is already in use.\n", - dev->name, dev->irq ); + dev->name, dev->irq); return err; } @@ -953,145 +968,145 @@ static int TLan_Open( struct net_device *dev ) netif_start_queue(dev); /* NOTE: It might not be necessary to read the stats before a - reset if you don't care what the values are. + reset if you don't care what the values are. */ - TLan_ResetLists( dev ); - TLan_ReadAndClearStats( dev, TLAN_IGNORE ); - TLan_ResetAdapter( dev ); + tlan_reset_lists(dev); + tlan_read_and_clear_stats(dev, TLAN_IGNORE); + tlan_reset_adapter(dev); - TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Opened. TLAN Chip Rev: %x\n", - dev->name, priv->tlanRev ); + TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Opened. TLAN Chip Rev: %x\n", + dev->name, priv->tlan_rev); return 0; -} /* TLan_Open */ +} - /************************************************************** - * TLan_ioctl - * - * Returns: - * 0 on success, error code otherwise - * Params: - * dev structure of device to receive ioctl. - * - * rq ifreq structure to hold userspace data. - * - * cmd ioctl command. - * - * - *************************************************************/ +/************************************************************** + * tlan_ioctl + * + * Returns: + * 0 on success, error code otherwise + * Params: + * dev structure of device to receive ioctl. + * + * rq ifreq structure to hold userspace data. + * + * cmd ioctl command. + * + * + *************************************************************/ -static int TLan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +static int tlan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); struct mii_ioctl_data *data = if_mii(rq); - u32 phy = priv->phy[priv->phyNum]; + u32 phy = priv->phy[priv->phy_num]; - if (!priv->phyOnline) + if (!priv->phy_online) return -EAGAIN; - switch(cmd) { - case SIOCGMIIPHY: /* Get address of MII PHY in use. */ - data->phy_id = phy; + switch (cmd) { + case SIOCGMIIPHY: /* get address of MII PHY in use. */ + data->phy_id = phy; - case SIOCGMIIREG: /* Read MII PHY register. */ - TLan_MiiReadReg(dev, data->phy_id & 0x1f, - data->reg_num & 0x1f, &data->val_out); - return 0; + case SIOCGMIIREG: /* read MII PHY register. */ + tlan_mii_read_reg(dev, data->phy_id & 0x1f, + data->reg_num & 0x1f, &data->val_out); + return 0; - case SIOCSMIIREG: /* Write MII PHY register. */ - TLan_MiiWriteReg(dev, data->phy_id & 0x1f, - data->reg_num & 0x1f, data->val_in); - return 0; - default: - return -EOPNOTSUPP; + case SIOCSMIIREG: /* write MII PHY register. */ + tlan_mii_write_reg(dev, data->phy_id & 0x1f, + data->reg_num & 0x1f, data->val_in); + return 0; + default: + return -EOPNOTSUPP; } -} /* tlan_ioctl */ +} - /*************************************************************** - * TLan_tx_timeout - * - * Returns: nothing - * - * Params: - * dev structure of device which timed out - * during transmit. - * - **************************************************************/ +/*************************************************************** + * tlan_tx_timeout + * + * Returns: nothing + * + * Params: + * dev structure of device which timed out + * during transmit. + * + **************************************************************/ -static void TLan_tx_timeout(struct net_device *dev) +static void tlan_tx_timeout(struct net_device *dev) { - TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Transmit timed out.\n", dev->name); + TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Transmit timed out.\n", dev->name); /* Ok so we timed out, lets see what we can do about it...*/ - TLan_FreeLists( dev ); - TLan_ResetLists( dev ); - TLan_ReadAndClearStats( dev, TLAN_IGNORE ); - TLan_ResetAdapter( dev ); + tlan_free_lists(dev); + tlan_reset_lists(dev); + tlan_read_and_clear_stats(dev, TLAN_IGNORE); + tlan_reset_adapter(dev); dev->trans_start = jiffies; /* prevent tx timeout */ - netif_wake_queue( dev ); + netif_wake_queue(dev); } - /*************************************************************** - * TLan_tx_timeout_work - * - * Returns: nothing - * - * Params: - * work work item of device which timed out - * - **************************************************************/ +/*************************************************************** + * tlan_tx_timeout_work + * + * Returns: nothing + * + * Params: + * work work item of device which timed out + * + **************************************************************/ -static void TLan_tx_timeout_work(struct work_struct *work) +static void tlan_tx_timeout_work(struct work_struct *work) { - TLanPrivateInfo *priv = - container_of(work, TLanPrivateInfo, tlan_tqueue); + struct tlan_priv *priv = + container_of(work, struct tlan_priv, tlan_tqueue); - TLan_tx_timeout(priv->dev); + tlan_tx_timeout(priv->dev); } - /*************************************************************** - * TLan_StartTx - * - * Returns: - * 0 on success, non-zero on failure. - * Parms: - * skb A pointer to the sk_buff containing the - * frame to be sent. - * dev The device to send the data on. - * - * This function adds a frame to the Tx list to be sent - * ASAP. First it verifies that the adapter is ready and - * there is room in the queue. Then it sets up the next - * available list, copies the frame to the corresponding - * buffer. If the adapter Tx channel is idle, it gives - * the adapter a Tx Go command on the list, otherwise it - * sets the forward address of the previous list to point - * to this one. Then it frees the sk_buff. - * - **************************************************************/ - -static netdev_tx_t TLan_StartTx( struct sk_buff *skb, struct net_device *dev ) +/*************************************************************** + * tlan_start_tx + * + * Returns: + * 0 on success, non-zero on failure. + * Parms: + * skb A pointer to the sk_buff containing the + * frame to be sent. + * dev The device to send the data on. + * + * This function adds a frame to the Tx list to be sent + * ASAP. First it verifies that the adapter is ready and + * there is room in the queue. Then it sets up the next + * available list, copies the frame to the corresponding + * buffer. If the adapter Tx channel is idle, it gives + * the adapter a Tx Go command on the list, otherwise it + * sets the forward address of the previous list to point + * to this one. Then it frees the sk_buff. + * + **************************************************************/ + +static netdev_tx_t tlan_start_tx(struct sk_buff *skb, struct net_device *dev) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); dma_addr_t tail_list_phys; - TLanList *tail_list; + struct tlan_list *tail_list; unsigned long flags; unsigned int txlen; - if ( ! priv->phyOnline ) { - TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s PHY is not ready\n", - dev->name ); + if (!priv->phy_online) { + TLAN_DBG(TLAN_DEBUG_TX, "TRANSMIT: %s PHY is not ready\n", + dev->name); dev_kfree_skb_any(skb); return NETDEV_TX_OK; } @@ -1100,218 +1115,221 @@ static netdev_tx_t TLan_StartTx( struct sk_buff *skb, struct net_device *dev ) return NETDEV_TX_OK; txlen = max(skb->len, (unsigned int)TLAN_MIN_FRAME_SIZE); - tail_list = priv->txList + priv->txTail; - tail_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txTail; + tail_list = priv->tx_list + priv->tx_tail; + tail_list_phys = + priv->tx_list_dma + sizeof(struct tlan_list)*priv->tx_tail; - if ( tail_list->cStat != TLAN_CSTAT_UNUSED ) { - TLAN_DBG( TLAN_DEBUG_TX, - "TRANSMIT: %s is busy (Head=%d Tail=%d)\n", - dev->name, priv->txHead, priv->txTail ); + if (tail_list->c_stat != TLAN_CSTAT_UNUSED) { + TLAN_DBG(TLAN_DEBUG_TX, + "TRANSMIT: %s is busy (Head=%d Tail=%d)\n", + dev->name, priv->tx_head, priv->tx_tail); netif_stop_queue(dev); - priv->txBusyCount++; + priv->tx_busy_count++; return NETDEV_TX_BUSY; } tail_list->forward = 0; - tail_list->buffer[0].address = pci_map_single(priv->pciDev, + tail_list->buffer[0].address = pci_map_single(priv->pci_dev, skb->data, txlen, PCI_DMA_TODEVICE); - TLan_StoreSKB(tail_list, skb); + tlan_store_skb(tail_list, skb); - tail_list->frameSize = (u16) txlen; + tail_list->frame_size = (u16) txlen; tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) txlen; tail_list->buffer[1].count = 0; tail_list->buffer[1].address = 0; spin_lock_irqsave(&priv->lock, flags); - tail_list->cStat = TLAN_CSTAT_READY; - if ( ! priv->txInProgress ) { - priv->txInProgress = 1; - TLAN_DBG( TLAN_DEBUG_TX, - "TRANSMIT: Starting TX on buffer %d\n", priv->txTail ); - outl( tail_list_phys, dev->base_addr + TLAN_CH_PARM ); - outl( TLAN_HC_GO, dev->base_addr + TLAN_HOST_CMD ); + tail_list->c_stat = TLAN_CSTAT_READY; + if (!priv->tx_in_progress) { + priv->tx_in_progress = 1; + TLAN_DBG(TLAN_DEBUG_TX, + "TRANSMIT: Starting TX on buffer %d\n", + priv->tx_tail); + outl(tail_list_phys, dev->base_addr + TLAN_CH_PARM); + outl(TLAN_HC_GO, dev->base_addr + TLAN_HOST_CMD); } else { - TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Adding buffer %d to TX channel\n", - priv->txTail ); - if ( priv->txTail == 0 ) { - ( priv->txList + ( TLAN_NUM_TX_LISTS - 1 ) )->forward + TLAN_DBG(TLAN_DEBUG_TX, + "TRANSMIT: Adding buffer %d to TX channel\n", + priv->tx_tail); + if (priv->tx_tail == 0) { + (priv->tx_list + (TLAN_NUM_TX_LISTS - 1))->forward = tail_list_phys; } else { - ( priv->txList + ( priv->txTail - 1 ) )->forward + (priv->tx_list + (priv->tx_tail - 1))->forward = tail_list_phys; } } spin_unlock_irqrestore(&priv->lock, flags); - CIRC_INC( priv->txTail, TLAN_NUM_TX_LISTS ); + CIRC_INC(priv->tx_tail, TLAN_NUM_TX_LISTS); return NETDEV_TX_OK; -} /* TLan_StartTx */ +} - /*************************************************************** - * TLan_HandleInterrupt - * - * Returns: - * Nothing - * Parms: - * irq The line on which the interrupt - * occurred. - * dev_id A pointer to the device assigned to - * this irq line. - * - * This function handles an interrupt generated by its - * assigned TLAN adapter. The function deactivates - * interrupts on its adapter, records the type of - * interrupt, executes the appropriate subhandler, and - * acknowdges the interrupt to the adapter (thus - * re-enabling adapter interrupts. - * - **************************************************************/ +/*************************************************************** + * tlan_handle_interrupt + * + * Returns: + * Nothing + * Parms: + * irq The line on which the interrupt + * occurred. + * dev_id A pointer to the device assigned to + * this irq line. + * + * This function handles an interrupt generated by its + * assigned TLAN adapter. The function deactivates + * interrupts on its adapter, records the type of + * interrupt, executes the appropriate subhandler, and + * acknowdges the interrupt to the adapter (thus + * re-enabling adapter interrupts. + * + **************************************************************/ -static irqreturn_t TLan_HandleInterrupt(int irq, void *dev_id) +static irqreturn_t tlan_handle_interrupt(int irq, void *dev_id) { struct net_device *dev = dev_id; - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); u16 host_int; u16 type; spin_lock(&priv->lock); - host_int = inw( dev->base_addr + TLAN_HOST_INT ); - type = ( host_int & TLAN_HI_IT_MASK ) >> 2; - if ( type ) { + host_int = inw(dev->base_addr + TLAN_HOST_INT); + type = (host_int & TLAN_HI_IT_MASK) >> 2; + if (type) { u32 ack; u32 host_cmd; - outw( host_int, dev->base_addr + TLAN_HOST_INT ); - ack = TLanIntVector[type]( dev, host_int ); + outw(host_int, dev->base_addr + TLAN_HOST_INT); + ack = tlan_int_vector[type](dev, host_int); - if ( ack ) { - host_cmd = TLAN_HC_ACK | ack | ( type << 18 ); - outl( host_cmd, dev->base_addr + TLAN_HOST_CMD ); + if (ack) { + host_cmd = TLAN_HC_ACK | ack | (type << 18); + outl(host_cmd, dev->base_addr + TLAN_HOST_CMD); } } spin_unlock(&priv->lock); return IRQ_RETVAL(type); -} /* TLan_HandleInterrupts */ +} - /*************************************************************** - * TLan_Close - * - * Returns: - * An error code. - * Parms: - * dev The device structure of the device to - * close. - * - * This function shuts down the adapter. It records any - * stats, puts the adapter into reset state, deactivates - * its time as needed, and frees the irq it is using. - * - **************************************************************/ +/*************************************************************** + * tlan_close + * + * Returns: + * An error code. + * Parms: + * dev The device structure of the device to + * close. + * + * This function shuts down the adapter. It records any + * stats, puts the adapter into reset state, deactivates + * its time as needed, and frees the irq it is using. + * + **************************************************************/ -static int TLan_Close(struct net_device *dev) +static int tlan_close(struct net_device *dev) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); netif_stop_queue(dev); priv->neg_be_verbose = 0; - TLan_ReadAndClearStats( dev, TLAN_RECORD ); - outl( TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD ); - if ( priv->timer.function != NULL ) { - del_timer_sync( &priv->timer ); + tlan_read_and_clear_stats(dev, TLAN_RECORD); + outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD); + if (priv->timer.function != NULL) { + del_timer_sync(&priv->timer); priv->timer.function = NULL; } - free_irq( dev->irq, dev ); - TLan_FreeLists( dev ); - TLAN_DBG( TLAN_DEBUG_GNRL, "Device %s closed.\n", dev->name ); + free_irq(dev->irq, dev); + tlan_free_lists(dev); + TLAN_DBG(TLAN_DEBUG_GNRL, "Device %s closed.\n", dev->name); return 0; -} /* TLan_Close */ +} - /*************************************************************** - * TLan_GetStats - * - * Returns: - * A pointer to the device's statistics structure. - * Parms: - * dev The device structure to return the - * stats for. - * - * This function updates the devices statistics by reading - * the TLAN chip's onboard registers. Then it returns the - * address of the statistics structure. - * - **************************************************************/ +/*************************************************************** + * tlan_get_stats + * + * Returns: + * A pointer to the device's statistics structure. + * Parms: + * dev The device structure to return the + * stats for. + * + * This function updates the devices statistics by reading + * the TLAN chip's onboard registers. Then it returns the + * address of the statistics structure. + * + **************************************************************/ -static struct net_device_stats *TLan_GetStats( struct net_device *dev ) +static struct net_device_stats *tlan_get_stats(struct net_device *dev) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); int i; /* Should only read stats if open ? */ - TLan_ReadAndClearStats( dev, TLAN_RECORD ); + tlan_read_and_clear_stats(dev, TLAN_RECORD); - TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: %s EOC count = %d\n", dev->name, - priv->rxEocCount ); - TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s Busy count = %d\n", dev->name, - priv->txBusyCount ); - if ( debug & TLAN_DEBUG_GNRL ) { - TLan_PrintDio( dev->base_addr ); - TLan_PhyPrint( dev ); + TLAN_DBG(TLAN_DEBUG_RX, "RECEIVE: %s EOC count = %d\n", dev->name, + priv->rx_eoc_count); + TLAN_DBG(TLAN_DEBUG_TX, "TRANSMIT: %s Busy count = %d\n", dev->name, + priv->tx_busy_count); + if (debug & TLAN_DEBUG_GNRL) { + tlan_print_dio(dev->base_addr); + tlan_phy_print(dev); } - if ( debug & TLAN_DEBUG_LIST ) { - for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ ) - TLan_PrintList( priv->rxList + i, "RX", i ); - for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ ) - TLan_PrintList( priv->txList + i, "TX", i ); + if (debug & TLAN_DEBUG_LIST) { + for (i = 0; i < TLAN_NUM_RX_LISTS; i++) + tlan_print_list(priv->rx_list + i, "RX", i); + for (i = 0; i < TLAN_NUM_TX_LISTS; i++) + tlan_print_list(priv->tx_list + i, "TX", i); } return &dev->stats; -} /* TLan_GetStats */ +} - /*************************************************************** - * TLan_SetMulticastList - * - * Returns: - * Nothing - * Parms: - * dev The device structure to set the - * multicast list for. - * - * This function sets the TLAN adaptor to various receive - * modes. If the IFF_PROMISC flag is set, promiscuous - * mode is acitviated. Otherwise, promiscuous mode is - * turned off. If the IFF_ALLMULTI flag is set, then - * the hash table is set to receive all group addresses. - * Otherwise, the first three multicast addresses are - * stored in AREG_1-3, and the rest are selected via the - * hash table, as necessary. - * - **************************************************************/ +/*************************************************************** + * tlan_set_multicast_list + * + * Returns: + * Nothing + * Parms: + * dev The device structure to set the + * multicast list for. + * + * This function sets the TLAN adaptor to various receive + * modes. If the IFF_PROMISC flag is set, promiscuous + * mode is acitviated. Otherwise, promiscuous mode is + * turned off. If the IFF_ALLMULTI flag is set, then + * the hash table is set to receive all group addresses. + * Otherwise, the first three multicast addresses are + * stored in AREG_1-3, and the rest are selected via the + * hash table, as necessary. + * + **************************************************************/ -static void TLan_SetMulticastList( struct net_device *dev ) +static void tlan_set_multicast_list(struct net_device *dev) { struct netdev_hw_addr *ha; u32 hash1 = 0; @@ -1320,53 +1338,56 @@ static void TLan_SetMulticastList( struct net_device *dev ) u32 offset; u8 tmp; - if ( dev->flags & IFF_PROMISC ) { - tmp = TLan_DioRead8( dev->base_addr, TLAN_NET_CMD ); - TLan_DioWrite8( dev->base_addr, - TLAN_NET_CMD, tmp | TLAN_NET_CMD_CAF ); + if (dev->flags & IFF_PROMISC) { + tmp = tlan_dio_read8(dev->base_addr, TLAN_NET_CMD); + tlan_dio_write8(dev->base_addr, + TLAN_NET_CMD, tmp | TLAN_NET_CMD_CAF); } else { - tmp = TLan_DioRead8( dev->base_addr, TLAN_NET_CMD ); - TLan_DioWrite8( dev->base_addr, - TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF ); - if ( dev->flags & IFF_ALLMULTI ) { - for ( i = 0; i < 3; i++ ) - TLan_SetMac( dev, i + 1, NULL ); - TLan_DioWrite32( dev->base_addr, TLAN_HASH_1, 0xFFFFFFFF ); - TLan_DioWrite32( dev->base_addr, TLAN_HASH_2, 0xFFFFFFFF ); + tmp = tlan_dio_read8(dev->base_addr, TLAN_NET_CMD); + tlan_dio_write8(dev->base_addr, + TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF); + if (dev->flags & IFF_ALLMULTI) { + for (i = 0; i < 3; i++) + tlan_set_mac(dev, i + 1, NULL); + tlan_dio_write32(dev->base_addr, TLAN_HASH_1, + 0xffffffff); + tlan_dio_write32(dev->base_addr, TLAN_HASH_2, + 0xffffffff); } else { i = 0; netdev_for_each_mc_addr(ha, dev) { - if ( i < 3 ) { - TLan_SetMac( dev, i + 1, + if (i < 3) { + tlan_set_mac(dev, i + 1, (char *) &ha->addr); } else { - offset = TLan_HashFunc((u8 *)&ha->addr); - if ( offset < 32 ) - hash1 |= ( 1 << offset ); + offset = + tlan_hash_func((u8 *)&ha->addr); + if (offset < 32) + hash1 |= (1 << offset); else - hash2 |= ( 1 << ( offset - 32 ) ); + hash2 |= (1 << (offset - 32)); } i++; } - for ( ; i < 3; i++ ) - TLan_SetMac( dev, i + 1, NULL ); - TLan_DioWrite32( dev->base_addr, TLAN_HASH_1, hash1 ); - TLan_DioWrite32( dev->base_addr, TLAN_HASH_2, hash2 ); + for ( ; i < 3; i++) + tlan_set_mac(dev, i + 1, NULL); + tlan_dio_write32(dev->base_addr, TLAN_HASH_1, hash1); + tlan_dio_write32(dev->base_addr, TLAN_HASH_2, hash2); } } -} /* TLan_SetMulticastList */ +} /***************************************************************************** ****************************************************************************** - ThunderLAN Driver Interrupt Vectors and Table +ThunderLAN driver interrupt vectors and table - Please see Chap. 4, "Interrupt Handling" of the "ThunderLAN - Programmer's Guide" for more informations on handling interrupts - generated by TLAN based adapters. +please see chap. 4, "Interrupt Handling" of the "ThunderLAN +Programmer's Guide" for more informations on handling interrupts +generated by TLAN based adapters. ****************************************************************************** *****************************************************************************/ @@ -1374,46 +1395,48 @@ static void TLan_SetMulticastList( struct net_device *dev ) - /*************************************************************** - * TLan_HandleTxEOF - * - * Returns: - * 1 - * Parms: - * dev Device assigned the IRQ that was - * raised. - * host_int The contents of the HOST_INT - * port. - * - * This function handles Tx EOF interrupts which are raised - * by the adapter when it has completed sending the - * contents of a buffer. If detemines which list/buffer - * was completed and resets it. If the buffer was the last - * in the channel (EOC), then the function checks to see if - * another buffer is ready to send, and if so, sends a Tx - * Go command. Finally, the driver activates/continues the - * activity LED. - * - **************************************************************/ - -static u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int ) +/*************************************************************** + * tlan_handle_tx_eof + * + * Returns: + * 1 + * Parms: + * dev Device assigned the IRQ that was + * raised. + * host_int The contents of the HOST_INT + * port. + * + * This function handles Tx EOF interrupts which are raised + * by the adapter when it has completed sending the + * contents of a buffer. If detemines which list/buffer + * was completed and resets it. If the buffer was the last + * in the channel (EOC), then the function checks to see if + * another buffer is ready to send, and if so, sends a Tx + * Go command. Finally, the driver activates/continues the + * activity LED. + * + **************************************************************/ + +static u32 tlan_handle_tx_eof(struct net_device *dev, u16 host_int) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); int eoc = 0; - TLanList *head_list; + struct tlan_list *head_list; dma_addr_t head_list_phys; u32 ack = 0; - u16 tmpCStat; + u16 tmp_c_stat; - TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOF (Head=%d Tail=%d)\n", - priv->txHead, priv->txTail ); - head_list = priv->txList + priv->txHead; + TLAN_DBG(TLAN_DEBUG_TX, + "TRANSMIT: Handling TX EOF (Head=%d Tail=%d)\n", + priv->tx_head, priv->tx_tail); + head_list = priv->tx_list + priv->tx_head; - while (((tmpCStat = head_list->cStat ) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) { - struct sk_buff *skb = TLan_GetSKB(head_list); + while (((tmp_c_stat = head_list->c_stat) & TLAN_CSTAT_FRM_CMP) + && (ack < 255)) { + struct sk_buff *skb = tlan_get_skb(head_list); ack++; - pci_unmap_single(priv->pciDev, head_list->buffer[0].address, + pci_unmap_single(priv->pci_dev, head_list->buffer[0].address, max(skb->len, (unsigned int)TLAN_MIN_FRAME_SIZE), PCI_DMA_TODEVICE); @@ -1421,304 +1444,311 @@ static u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int ) head_list->buffer[8].address = 0; head_list->buffer[9].address = 0; - if ( tmpCStat & TLAN_CSTAT_EOC ) + if (tmp_c_stat & TLAN_CSTAT_EOC) eoc = 1; - dev->stats.tx_bytes += head_list->frameSize; + dev->stats.tx_bytes += head_list->frame_size; - head_list->cStat = TLAN_CSTAT_UNUSED; + head_list->c_stat = TLAN_CSTAT_UNUSED; netif_start_queue(dev); - CIRC_INC( priv->txHead, TLAN_NUM_TX_LISTS ); - head_list = priv->txList + priv->txHead; + CIRC_INC(priv->tx_head, TLAN_NUM_TX_LISTS); + head_list = priv->tx_list + priv->tx_head; } if (!ack) - printk(KERN_INFO "TLAN: Received interrupt for uncompleted TX frame.\n"); - - if ( eoc ) { - TLAN_DBG( TLAN_DEBUG_TX, - "TRANSMIT: Handling TX EOC (Head=%d Tail=%d)\n", - priv->txHead, priv->txTail ); - head_list = priv->txList + priv->txHead; - head_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txHead; - if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) { - outl(head_list_phys, dev->base_addr + TLAN_CH_PARM ); + printk(KERN_INFO + "TLAN: Received interrupt for uncompleted TX frame.\n"); + + if (eoc) { + TLAN_DBG(TLAN_DEBUG_TX, + "TRANSMIT: handling TX EOC (Head=%d Tail=%d)\n", + priv->tx_head, priv->tx_tail); + head_list = priv->tx_list + priv->tx_head; + head_list_phys = priv->tx_list_dma + + sizeof(struct tlan_list)*priv->tx_head; + if (head_list->c_stat & TLAN_CSTAT_READY) { + outl(head_list_phys, dev->base_addr + TLAN_CH_PARM); ack |= TLAN_HC_GO; } else { - priv->txInProgress = 0; + priv->tx_in_progress = 0; } } - if ( priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED ) { - TLan_DioWrite8( dev->base_addr, - TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT ); - if ( priv->timer.function == NULL ) { - priv->timer.function = TLan_Timer; - priv->timer.data = (unsigned long) dev; - priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY; - priv->timerSetAt = jiffies; - priv->timerType = TLAN_TIMER_ACTIVITY; - add_timer(&priv->timer); - } else if ( priv->timerType == TLAN_TIMER_ACTIVITY ) { - priv->timerSetAt = jiffies; + if (priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED) { + tlan_dio_write8(dev->base_addr, + TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT); + if (priv->timer.function == NULL) { + priv->timer.function = tlan_timer; + priv->timer.data = (unsigned long) dev; + priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY; + priv->timer_set_at = jiffies; + priv->timer_type = TLAN_TIMER_ACTIVITY; + add_timer(&priv->timer); + } else if (priv->timer_type == TLAN_TIMER_ACTIVITY) { + priv->timer_set_at = jiffies; } } return ack; -} /* TLan_HandleTxEOF */ +} - /*************************************************************** - * TLan_HandleStatOverflow - * - * Returns: - * 1 - * Parms: - * dev Device assigned the IRQ that was - * raised. - * host_int The contents of the HOST_INT - * port. - * - * This function handles the Statistics Overflow interrupt - * which means that one or more of the TLAN statistics - * registers has reached 1/2 capacity and needs to be read. - * - **************************************************************/ +/*************************************************************** + * TLan_HandleStatOverflow + * + * Returns: + * 1 + * Parms: + * dev Device assigned the IRQ that was + * raised. + * host_int The contents of the HOST_INT + * port. + * + * This function handles the Statistics Overflow interrupt + * which means that one or more of the TLAN statistics + * registers has reached 1/2 capacity and needs to be read. + * + **************************************************************/ -static u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int ) +static u32 tlan_handle_stat_overflow(struct net_device *dev, u16 host_int) { - TLan_ReadAndClearStats( dev, TLAN_RECORD ); + tlan_read_and_clear_stats(dev, TLAN_RECORD); return 1; -} /* TLan_HandleStatOverflow */ - - - - - /*************************************************************** - * TLan_HandleRxEOF - * - * Returns: - * 1 - * Parms: - * dev Device assigned the IRQ that was - * raised. - * host_int The contents of the HOST_INT - * port. - * - * This function handles the Rx EOF interrupt which - * indicates a frame has been received by the adapter from - * the net and the frame has been transferred to memory. - * The function determines the bounce buffer the frame has - * been loaded into, creates a new sk_buff big enough to - * hold the frame, and sends it to protocol stack. It - * then resets the used buffer and appends it to the end - * of the list. If the frame was the last in the Rx - * channel (EOC), the function restarts the receive channel - * by sending an Rx Go command to the adapter. Then it - * activates/continues the activity LED. - * - **************************************************************/ - -static u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int ) +} + + + + +/*************************************************************** + * TLan_HandleRxEOF + * + * Returns: + * 1 + * Parms: + * dev Device assigned the IRQ that was + * raised. + * host_int The contents of the HOST_INT + * port. + * + * This function handles the Rx EOF interrupt which + * indicates a frame has been received by the adapter from + * the net and the frame has been transferred to memory. + * The function determines the bounce buffer the frame has + * been loaded into, creates a new sk_buff big enough to + * hold the frame, and sends it to protocol stack. It + * then resets the used buffer and appends it to the end + * of the list. If the frame was the last in the Rx + * channel (EOC), the function restarts the receive channel + * by sending an Rx Go command to the adapter. Then it + * activates/continues the activity LED. + * + **************************************************************/ + +static u32 tlan_handle_rx_eof(struct net_device *dev, u16 host_int) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); u32 ack = 0; int eoc = 0; - TLanList *head_list; + struct tlan_list *head_list; struct sk_buff *skb; - TLanList *tail_list; - u16 tmpCStat; + struct tlan_list *tail_list; + u16 tmp_c_stat; dma_addr_t head_list_phys; - TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOF (Head=%d Tail=%d)\n", - priv->rxHead, priv->rxTail ); - head_list = priv->rxList + priv->rxHead; - head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead; + TLAN_DBG(TLAN_DEBUG_RX, "RECEIVE: handling RX EOF (Head=%d Tail=%d)\n", + priv->rx_head, priv->rx_tail); + head_list = priv->rx_list + priv->rx_head; + head_list_phys = + priv->rx_list_dma + sizeof(struct tlan_list)*priv->rx_head; - while (((tmpCStat = head_list->cStat) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) { - dma_addr_t frameDma = head_list->buffer[0].address; - u32 frameSize = head_list->frameSize; + while (((tmp_c_stat = head_list->c_stat) & TLAN_CSTAT_FRM_CMP) + && (ack < 255)) { + dma_addr_t frame_dma = head_list->buffer[0].address; + u32 frame_size = head_list->frame_size; struct sk_buff *new_skb; ack++; - if (tmpCStat & TLAN_CSTAT_EOC) + if (tmp_c_stat & TLAN_CSTAT_EOC) eoc = 1; new_skb = netdev_alloc_skb_ip_align(dev, TLAN_MAX_FRAME_SIZE + 5); - if ( !new_skb ) + if (!new_skb) goto drop_and_reuse; - skb = TLan_GetSKB(head_list); - pci_unmap_single(priv->pciDev, frameDma, + skb = tlan_get_skb(head_list); + pci_unmap_single(priv->pci_dev, frame_dma, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE); - skb_put( skb, frameSize ); + skb_put(skb, frame_size); - dev->stats.rx_bytes += frameSize; + dev->stats.rx_bytes += frame_size; - skb->protocol = eth_type_trans( skb, dev ); - netif_rx( skb ); + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); - head_list->buffer[0].address = pci_map_single(priv->pciDev, - new_skb->data, - TLAN_MAX_FRAME_SIZE, - PCI_DMA_FROMDEVICE); + head_list->buffer[0].address = + pci_map_single(priv->pci_dev, new_skb->data, + TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE); - TLan_StoreSKB(head_list, new_skb); + tlan_store_skb(head_list, new_skb); drop_and_reuse: head_list->forward = 0; - head_list->cStat = 0; - tail_list = priv->rxList + priv->rxTail; + head_list->c_stat = 0; + tail_list = priv->rx_list + priv->rx_tail; tail_list->forward = head_list_phys; - CIRC_INC( priv->rxHead, TLAN_NUM_RX_LISTS ); - CIRC_INC( priv->rxTail, TLAN_NUM_RX_LISTS ); - head_list = priv->rxList + priv->rxHead; - head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead; + CIRC_INC(priv->rx_head, TLAN_NUM_RX_LISTS); + CIRC_INC(priv->rx_tail, TLAN_NUM_RX_LISTS); + head_list = priv->rx_list + priv->rx_head; + head_list_phys = priv->rx_list_dma + + sizeof(struct tlan_list)*priv->rx_head; } if (!ack) - printk(KERN_INFO "TLAN: Received interrupt for uncompleted RX frame.\n"); - - - if ( eoc ) { - TLAN_DBG( TLAN_DEBUG_RX, - "RECEIVE: Handling RX EOC (Head=%d Tail=%d)\n", - priv->rxHead, priv->rxTail ); - head_list = priv->rxList + priv->rxHead; - head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead; - outl(head_list_phys, dev->base_addr + TLAN_CH_PARM ); + printk(KERN_INFO + "TLAN: Received interrupt for uncompleted RX frame.\n"); + + + if (eoc) { + TLAN_DBG(TLAN_DEBUG_RX, + "RECEIVE: handling RX EOC (Head=%d Tail=%d)\n", + priv->rx_head, priv->rx_tail); + head_list = priv->rx_list + priv->rx_head; + head_list_phys = priv->rx_list_dma + + sizeof(struct tlan_list)*priv->rx_head; + outl(head_list_phys, dev->base_addr + TLAN_CH_PARM); ack |= TLAN_HC_GO | TLAN_HC_RT; - priv->rxEocCount++; + priv->rx_eoc_count++; } - if ( priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED ) { - TLan_DioWrite8( dev->base_addr, - TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT ); - if ( priv->timer.function == NULL ) { - priv->timer.function = TLan_Timer; + if (priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED) { + tlan_dio_write8(dev->base_addr, + TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT); + if (priv->timer.function == NULL) { + priv->timer.function = tlan_timer; priv->timer.data = (unsigned long) dev; priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY; - priv->timerSetAt = jiffies; - priv->timerType = TLAN_TIMER_ACTIVITY; + priv->timer_set_at = jiffies; + priv->timer_type = TLAN_TIMER_ACTIVITY; add_timer(&priv->timer); - } else if ( priv->timerType == TLAN_TIMER_ACTIVITY ) { - priv->timerSetAt = jiffies; + } else if (priv->timer_type == TLAN_TIMER_ACTIVITY) { + priv->timer_set_at = jiffies; } } return ack; -} /* TLan_HandleRxEOF */ +} - /*************************************************************** - * TLan_HandleDummy - * - * Returns: - * 1 - * Parms: - * dev Device assigned the IRQ that was - * raised. - * host_int The contents of the HOST_INT - * port. - * - * This function handles the Dummy interrupt, which is - * raised whenever a test interrupt is generated by setting - * the Req_Int bit of HOST_CMD to 1. - * - **************************************************************/ +/*************************************************************** + * tlan_handle_dummy + * + * Returns: + * 1 + * Parms: + * dev Device assigned the IRQ that was + * raised. + * host_int The contents of the HOST_INT + * port. + * + * This function handles the Dummy interrupt, which is + * raised whenever a test interrupt is generated by setting + * the Req_Int bit of HOST_CMD to 1. + * + **************************************************************/ -static u32 TLan_HandleDummy( struct net_device *dev, u16 host_int ) +static u32 tlan_handle_dummy(struct net_device *dev, u16 host_int) { - printk( "TLAN: Test interrupt on %s.\n", dev->name ); + pr_info("TLAN: Test interrupt on %s.\n", dev->name); return 1; -} /* TLan_HandleDummy */ +} - /*************************************************************** - * TLan_HandleTxEOC - * - * Returns: - * 1 - * Parms: - * dev Device assigned the IRQ that was - * raised. - * host_int The contents of the HOST_INT - * port. - * - * This driver is structured to determine EOC occurrences by - * reading the CSTAT member of the list structure. Tx EOC - * interrupts are disabled via the DIO INTDIS register. - * However, TLAN chips before revision 3.0 didn't have this - * functionality, so process EOC events if this is the - * case. - * - **************************************************************/ +/*************************************************************** + * tlan_handle_tx_eoc + * + * Returns: + * 1 + * Parms: + * dev Device assigned the IRQ that was + * raised. + * host_int The contents of the HOST_INT + * port. + * + * This driver is structured to determine EOC occurrences by + * reading the CSTAT member of the list structure. Tx EOC + * interrupts are disabled via the DIO INTDIS register. + * However, TLAN chips before revision 3.0 didn't have this + * functionality, so process EOC events if this is the + * case. + * + **************************************************************/ -static u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int ) +static u32 tlan_handle_tx_eoc(struct net_device *dev, u16 host_int) { - TLanPrivateInfo *priv = netdev_priv(dev); - TLanList *head_list; + struct tlan_priv *priv = netdev_priv(dev); + struct tlan_list *head_list; dma_addr_t head_list_phys; u32 ack = 1; host_int = 0; - if ( priv->tlanRev < 0x30 ) { - TLAN_DBG( TLAN_DEBUG_TX, - "TRANSMIT: Handling TX EOC (Head=%d Tail=%d) -- IRQ\n", - priv->txHead, priv->txTail ); - head_list = priv->txList + priv->txHead; - head_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txHead; - if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) { + if (priv->tlan_rev < 0x30) { + TLAN_DBG(TLAN_DEBUG_TX, + "TRANSMIT: handling TX EOC (Head=%d Tail=%d) -- IRQ\n", + priv->tx_head, priv->tx_tail); + head_list = priv->tx_list + priv->tx_head; + head_list_phys = priv->tx_list_dma + + sizeof(struct tlan_list)*priv->tx_head; + if (head_list->c_stat & TLAN_CSTAT_READY) { netif_stop_queue(dev); - outl( head_list_phys, dev->base_addr + TLAN_CH_PARM ); + outl(head_list_phys, dev->base_addr + TLAN_CH_PARM); ack |= TLAN_HC_GO; } else { - priv->txInProgress = 0; + priv->tx_in_progress = 0; } } return ack; -} /* TLan_HandleTxEOC */ +} - /*************************************************************** - * TLan_HandleStatusCheck - * - * Returns: - * 0 if Adapter check, 1 if Network Status check. - * Parms: - * dev Device assigned the IRQ that was - * raised. - * host_int The contents of the HOST_INT - * port. - * - * This function handles Adapter Check/Network Status - * interrupts generated by the adapter. It checks the - * vector in the HOST_INT register to determine if it is - * an Adapter Check interrupt. If so, it resets the - * adapter. Otherwise it clears the status registers - * and services the PHY. - * - **************************************************************/ +/*************************************************************** + * tlan_handle_status_check + * + * Returns: + * 0 if Adapter check, 1 if Network Status check. + * Parms: + * dev Device assigned the IRQ that was + * raised. + * host_int The contents of the HOST_INT + * port. + * + * This function handles Adapter Check/Network Status + * interrupts generated by the adapter. It checks the + * vector in the HOST_INT register to determine if it is + * an Adapter Check interrupt. If so, it resets the + * adapter. Otherwise it clears the status registers + * and services the PHY. + * + **************************************************************/ -static u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int ) +static u32 tlan_handle_status_check(struct net_device *dev, u16 host_int) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); u32 ack; u32 error; u8 net_sts; @@ -1727,92 +1757,94 @@ static u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int ) u16 tlphy_sts; ack = 1; - if ( host_int & TLAN_HI_IV_MASK ) { - netif_stop_queue( dev ); - error = inl( dev->base_addr + TLAN_CH_PARM ); - printk( "TLAN: %s: Adaptor Error = 0x%x\n", dev->name, error ); - TLan_ReadAndClearStats( dev, TLAN_RECORD ); - outl( TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD ); + if (host_int & TLAN_HI_IV_MASK) { + netif_stop_queue(dev); + error = inl(dev->base_addr + TLAN_CH_PARM); + pr_info("TLAN: %s: Adaptor Error = 0x%x\n", dev->name, error); + tlan_read_and_clear_stats(dev, TLAN_RECORD); + outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD); schedule_work(&priv->tlan_tqueue); netif_wake_queue(dev); ack = 0; } else { - TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Status Check\n", dev->name ); - phy = priv->phy[priv->phyNum]; - - net_sts = TLan_DioRead8( dev->base_addr, TLAN_NET_STS ); - if ( net_sts ) { - TLan_DioWrite8( dev->base_addr, TLAN_NET_STS, net_sts ); - TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Net_Sts = %x\n", - dev->name, (unsigned) net_sts ); + TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Status Check\n", dev->name); + phy = priv->phy[priv->phy_num]; + + net_sts = tlan_dio_read8(dev->base_addr, TLAN_NET_STS); + if (net_sts) { + tlan_dio_write8(dev->base_addr, TLAN_NET_STS, net_sts); + TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Net_Sts = %x\n", + dev->name, (unsigned) net_sts); } - if ( ( net_sts & TLAN_NET_STS_MIRQ ) && ( priv->phyNum == 0 ) ) { - TLan_MiiReadReg( dev, phy, TLAN_TLPHY_STS, &tlphy_sts ); - TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl ); - if ( ! ( tlphy_sts & TLAN_TS_POLOK ) && - ! ( tlphy_ctl & TLAN_TC_SWAPOL ) ) { - tlphy_ctl |= TLAN_TC_SWAPOL; - TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl); - } else if ( ( tlphy_sts & TLAN_TS_POLOK ) && - ( tlphy_ctl & TLAN_TC_SWAPOL ) ) { - tlphy_ctl &= ~TLAN_TC_SWAPOL; - TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl); - } - - if (debug) { - TLan_PhyPrint( dev ); + if ((net_sts & TLAN_NET_STS_MIRQ) && (priv->phy_num == 0)) { + tlan_mii_read_reg(dev, phy, TLAN_TLPHY_STS, &tlphy_sts); + tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl); + if (!(tlphy_sts & TLAN_TS_POLOK) && + !(tlphy_ctl & TLAN_TC_SWAPOL)) { + tlphy_ctl |= TLAN_TC_SWAPOL; + tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL, + tlphy_ctl); + } else if ((tlphy_sts & TLAN_TS_POLOK) && + (tlphy_ctl & TLAN_TC_SWAPOL)) { + tlphy_ctl &= ~TLAN_TC_SWAPOL; + tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL, + tlphy_ctl); } + + if (debug) + tlan_phy_print(dev); } } return ack; -} /* TLan_HandleStatusCheck */ +} - /*************************************************************** - * TLan_HandleRxEOC - * - * Returns: - * 1 - * Parms: - * dev Device assigned the IRQ that was - * raised. - * host_int The contents of the HOST_INT - * port. - * - * This driver is structured to determine EOC occurrences by - * reading the CSTAT member of the list structure. Rx EOC - * interrupts are disabled via the DIO INTDIS register. - * However, TLAN chips before revision 3.0 didn't have this - * CSTAT member or a INTDIS register, so if this chip is - * pre-3.0, process EOC interrupts normally. - * - **************************************************************/ +/*************************************************************** + * tlan_handle_rx_eoc + * + * Returns: + * 1 + * Parms: + * dev Device assigned the IRQ that was + * raised. + * host_int The contents of the HOST_INT + * port. + * + * This driver is structured to determine EOC occurrences by + * reading the CSTAT member of the list structure. Rx EOC + * interrupts are disabled via the DIO INTDIS register. + * However, TLAN chips before revision 3.0 didn't have this + * CSTAT member or a INTDIS register, so if this chip is + * pre-3.0, process EOC interrupts normally. + * + **************************************************************/ -static u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int ) +static u32 tlan_handle_rx_eoc(struct net_device *dev, u16 host_int) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); dma_addr_t head_list_phys; u32 ack = 1; - if ( priv->tlanRev < 0x30 ) { - TLAN_DBG( TLAN_DEBUG_RX, - "RECEIVE: Handling RX EOC (Head=%d Tail=%d) -- IRQ\n", - priv->rxHead, priv->rxTail ); - head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead; - outl( head_list_phys, dev->base_addr + TLAN_CH_PARM ); + if (priv->tlan_rev < 0x30) { + TLAN_DBG(TLAN_DEBUG_RX, + "RECEIVE: Handling RX EOC (head=%d tail=%d) -- IRQ\n", + priv->rx_head, priv->rx_tail); + head_list_phys = priv->rx_list_dma + + sizeof(struct tlan_list)*priv->rx_head; + outl(head_list_phys, dev->base_addr + TLAN_CH_PARM); ack |= TLAN_HC_GO | TLAN_HC_RT; - priv->rxEocCount++; + priv->rx_eoc_count++; } return ack; -} /* TLan_HandleRxEOC */ +} @@ -1820,98 +1852,98 @@ static u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int ) /***************************************************************************** ****************************************************************************** - ThunderLAN Driver Timer Function +ThunderLAN driver timer function ****************************************************************************** *****************************************************************************/ - /*************************************************************** - * TLan_Timer - * - * Returns: - * Nothing - * Parms: - * data A value given to add timer when - * add_timer was called. - * - * This function handles timed functionality for the - * TLAN driver. The two current timer uses are for - * delaying for autonegotionation and driving the ACT LED. - * - Autonegotiation requires being allowed about - * 2 1/2 seconds before attempting to transmit a - * packet. It would be a very bad thing to hang - * the kernel this long, so the driver doesn't - * allow transmission 'til after this time, for - * certain PHYs. It would be much nicer if all - * PHYs were interrupt-capable like the internal - * PHY. - * - The ACT LED, which shows adapter activity, is - * driven by the driver, and so must be left on - * for a short period to power up the LED so it - * can be seen. This delay can be changed by - * changing the TLAN_TIMER_ACT_DELAY in tlan.h, - * if desired. 100 ms produces a slightly - * sluggish response. - * - **************************************************************/ - -static void TLan_Timer( unsigned long data ) +/*************************************************************** + * tlan_timer + * + * Returns: + * Nothing + * Parms: + * data A value given to add timer when + * add_timer was called. + * + * This function handles timed functionality for the + * TLAN driver. The two current timer uses are for + * delaying for autonegotionation and driving the ACT LED. + * - Autonegotiation requires being allowed about + * 2 1/2 seconds before attempting to transmit a + * packet. It would be a very bad thing to hang + * the kernel this long, so the driver doesn't + * allow transmission 'til after this time, for + * certain PHYs. It would be much nicer if all + * PHYs were interrupt-capable like the internal + * PHY. + * - The ACT LED, which shows adapter activity, is + * driven by the driver, and so must be left on + * for a short period to power up the LED so it + * can be seen. This delay can be changed by + * changing the TLAN_TIMER_ACT_DELAY in tlan.h, + * if desired. 100 ms produces a slightly + * sluggish response. + * + **************************************************************/ + +static void tlan_timer(unsigned long data) { struct net_device *dev = (struct net_device *) data; - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); u32 elapsed; unsigned long flags = 0; priv->timer.function = NULL; - switch ( priv->timerType ) { + switch (priv->timer_type) { #ifdef MONITOR - case TLAN_TIMER_LINK_BEAT: - TLan_PhyMonitor( dev ); - break; + case TLAN_TIMER_LINK_BEAT: + tlan_phy_monitor(dev); + break; #endif - case TLAN_TIMER_PHY_PDOWN: - TLan_PhyPowerDown( dev ); - break; - case TLAN_TIMER_PHY_PUP: - TLan_PhyPowerUp( dev ); - break; - case TLAN_TIMER_PHY_RESET: - TLan_PhyReset( dev ); - break; - case TLAN_TIMER_PHY_START_LINK: - TLan_PhyStartLink( dev ); - break; - case TLAN_TIMER_PHY_FINISH_AN: - TLan_PhyFinishAutoNeg( dev ); - break; - case TLAN_TIMER_FINISH_RESET: - TLan_FinishReset( dev ); - break; - case TLAN_TIMER_ACTIVITY: - spin_lock_irqsave(&priv->lock, flags); - if ( priv->timer.function == NULL ) { - elapsed = jiffies - priv->timerSetAt; - if ( elapsed >= TLAN_TIMER_ACT_DELAY ) { - TLan_DioWrite8( dev->base_addr, - TLAN_LED_REG, TLAN_LED_LINK ); - } else { - priv->timer.function = TLan_Timer; - priv->timer.expires = priv->timerSetAt - + TLAN_TIMER_ACT_DELAY; - spin_unlock_irqrestore(&priv->lock, flags); - add_timer( &priv->timer ); - break; - } + case TLAN_TIMER_PHY_PDOWN: + tlan_phy_power_down(dev); + break; + case TLAN_TIMER_PHY_PUP: + tlan_phy_power_up(dev); + break; + case TLAN_TIMER_PHY_RESET: + tlan_phy_reset(dev); + break; + case TLAN_TIMER_PHY_START_LINK: + tlan_phy_start_link(dev); + break; + case TLAN_TIMER_PHY_FINISH_AN: + tlan_phy_finish_auto_neg(dev); + break; + case TLAN_TIMER_FINISH_RESET: + tlan_finish_reset(dev); + break; + case TLAN_TIMER_ACTIVITY: + spin_lock_irqsave(&priv->lock, flags); + if (priv->timer.function == NULL) { + elapsed = jiffies - priv->timer_set_at; + if (elapsed >= TLAN_TIMER_ACT_DELAY) { + tlan_dio_write8(dev->base_addr, + TLAN_LED_REG, TLAN_LED_LINK); + } else { + priv->timer.function = tlan_timer; + priv->timer.expires = priv->timer_set_at + + TLAN_TIMER_ACT_DELAY; + spin_unlock_irqrestore(&priv->lock, flags); + add_timer(&priv->timer); + break; } - spin_unlock_irqrestore(&priv->lock, flags); - break; - default: - break; + } + spin_unlock_irqrestore(&priv->lock, flags); + break; + default: + break; } -} /* TLan_Timer */ +} @@ -1919,39 +1951,39 @@ static void TLan_Timer( unsigned long data ) /***************************************************************************** ****************************************************************************** - ThunderLAN Driver Adapter Related Routines +ThunderLAN driver adapter related routines ****************************************************************************** *****************************************************************************/ - /*************************************************************** - * TLan_ResetLists - * - * Returns: - * Nothing - * Parms: - * dev The device structure with the list - * stuctures to be reset. - * - * This routine sets the variables associated with managing - * the TLAN lists to their initial values. - * - **************************************************************/ - -static void TLan_ResetLists( struct net_device *dev ) +/*************************************************************** + * tlan_reset_lists + * + * Returns: + * Nothing + * Parms: + * dev The device structure with the list + * stuctures to be reset. + * + * This routine sets the variables associated with managing + * the TLAN lists to their initial values. + * + **************************************************************/ + +static void tlan_reset_lists(struct net_device *dev) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); int i; - TLanList *list; + struct tlan_list *list; dma_addr_t list_phys; struct sk_buff *skb; - priv->txHead = 0; - priv->txTail = 0; - for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ ) { - list = priv->txList + i; - list->cStat = TLAN_CSTAT_UNUSED; + priv->tx_head = 0; + priv->tx_tail = 0; + for (i = 0; i < TLAN_NUM_TX_LISTS; i++) { + list = priv->tx_list + i; + list->c_stat = TLAN_CSTAT_UNUSED; list->buffer[0].address = 0; list->buffer[2].count = 0; list->buffer[2].address = 0; @@ -1959,169 +1991,169 @@ static void TLan_ResetLists( struct net_device *dev ) list->buffer[9].address = 0; } - priv->rxHead = 0; - priv->rxTail = TLAN_NUM_RX_LISTS - 1; - for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ ) { - list = priv->rxList + i; - list_phys = priv->rxListDMA + sizeof(TLanList) * i; - list->cStat = TLAN_CSTAT_READY; - list->frameSize = TLAN_MAX_FRAME_SIZE; + priv->rx_head = 0; + priv->rx_tail = TLAN_NUM_RX_LISTS - 1; + for (i = 0; i < TLAN_NUM_RX_LISTS; i++) { + list = priv->rx_list + i; + list_phys = priv->rx_list_dma + sizeof(struct tlan_list)*i; + list->c_stat = TLAN_CSTAT_READY; + list->frame_size = TLAN_MAX_FRAME_SIZE; list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER; skb = netdev_alloc_skb_ip_align(dev, TLAN_MAX_FRAME_SIZE + 5); - if ( !skb ) { - pr_err("TLAN: out of memory for received data.\n" ); + if (!skb) { + pr_err("TLAN: out of memory for received data.\n"); break; } - list->buffer[0].address = pci_map_single(priv->pciDev, + list->buffer[0].address = pci_map_single(priv->pci_dev, skb->data, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE); - TLan_StoreSKB(list, skb); + tlan_store_skb(list, skb); list->buffer[1].count = 0; list->buffer[1].address = 0; - list->forward = list_phys + sizeof(TLanList); + list->forward = list_phys + sizeof(struct tlan_list); } /* in case ran out of memory early, clear bits */ while (i < TLAN_NUM_RX_LISTS) { - TLan_StoreSKB(priv->rxList + i, NULL); + tlan_store_skb(priv->rx_list + i, NULL); ++i; } list->forward = 0; -} /* TLan_ResetLists */ +} -static void TLan_FreeLists( struct net_device *dev ) +static void tlan_free_lists(struct net_device *dev) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); int i; - TLanList *list; + struct tlan_list *list; struct sk_buff *skb; - for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ ) { - list = priv->txList + i; - skb = TLan_GetSKB(list); - if ( skb ) { + for (i = 0; i < TLAN_NUM_TX_LISTS; i++) { + list = priv->tx_list + i; + skb = tlan_get_skb(list); + if (skb) { pci_unmap_single( - priv->pciDev, + priv->pci_dev, list->buffer[0].address, max(skb->len, (unsigned int)TLAN_MIN_FRAME_SIZE), PCI_DMA_TODEVICE); - dev_kfree_skb_any( skb ); + dev_kfree_skb_any(skb); list->buffer[8].address = 0; list->buffer[9].address = 0; } } - for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ ) { - list = priv->rxList + i; - skb = TLan_GetSKB(list); - if ( skb ) { - pci_unmap_single(priv->pciDev, + for (i = 0; i < TLAN_NUM_RX_LISTS; i++) { + list = priv->rx_list + i; + skb = tlan_get_skb(list); + if (skb) { + pci_unmap_single(priv->pci_dev, list->buffer[0].address, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE); - dev_kfree_skb_any( skb ); + dev_kfree_skb_any(skb); list->buffer[8].address = 0; list->buffer[9].address = 0; } } -} /* TLan_FreeLists */ +} - /*************************************************************** - * TLan_PrintDio - * - * Returns: - * Nothing - * Parms: - * io_base Base IO port of the device of - * which to print DIO registers. - * - * This function prints out all the internal (DIO) - * registers of a TLAN chip. - * - **************************************************************/ +/*************************************************************** + * tlan_print_dio + * + * Returns: + * Nothing + * Parms: + * io_base Base IO port of the device of + * which to print DIO registers. + * + * This function prints out all the internal (DIO) + * registers of a TLAN chip. + * + **************************************************************/ -static void TLan_PrintDio( u16 io_base ) +static void tlan_print_dio(u16 io_base) { u32 data0, data1; int i; - printk( "TLAN: Contents of internal registers for io base 0x%04hx.\n", - io_base ); - printk( "TLAN: Off. +0 +4\n" ); - for ( i = 0; i < 0x4C; i+= 8 ) { - data0 = TLan_DioRead32( io_base, i ); - data1 = TLan_DioRead32( io_base, i + 0x4 ); - printk( "TLAN: 0x%02x 0x%08x 0x%08x\n", i, data0, data1 ); + pr_info("TLAN: Contents of internal registers for io base 0x%04hx.\n", + io_base); + pr_info("TLAN: Off. +0 +4\n"); + for (i = 0; i < 0x4C; i += 8) { + data0 = tlan_dio_read32(io_base, i); + data1 = tlan_dio_read32(io_base, i + 0x4); + pr_info("TLAN: 0x%02x 0x%08x 0x%08x\n", i, data0, data1); } -} /* TLan_PrintDio */ +} - /*************************************************************** - * TLan_PrintList - * - * Returns: - * Nothing - * Parms: - * list A pointer to the TLanList structure to - * be printed. - * type A string to designate type of list, - * "Rx" or "Tx". - * num The index of the list. - * - * This function prints out the contents of the list - * pointed to by the list parameter. - * - **************************************************************/ +/*************************************************************** + * TLan_PrintList + * + * Returns: + * Nothing + * Parms: + * list A pointer to the struct tlan_list structure to + * be printed. + * type A string to designate type of list, + * "Rx" or "Tx". + * num The index of the list. + * + * This function prints out the contents of the list + * pointed to by the list parameter. + * + **************************************************************/ -static void TLan_PrintList( TLanList *list, char *type, int num) +static void tlan_print_list(struct tlan_list *list, char *type, int num) { int i; - printk( "TLAN: %s List %d at %p\n", type, num, list ); - printk( "TLAN: Forward = 0x%08x\n", list->forward ); - printk( "TLAN: CSTAT = 0x%04hx\n", list->cStat ); - printk( "TLAN: Frame Size = 0x%04hx\n", list->frameSize ); - /* for ( i = 0; i < 10; i++ ) { */ - for ( i = 0; i < 2; i++ ) { - printk( "TLAN: Buffer[%d].count, addr = 0x%08x, 0x%08x\n", - i, list->buffer[i].count, list->buffer[i].address ); + pr_info("TLAN: %s List %d at %p\n", type, num, list); + pr_info("TLAN: Forward = 0x%08x\n", list->forward); + pr_info("TLAN: CSTAT = 0x%04hx\n", list->c_stat); + pr_info("TLAN: Frame Size = 0x%04hx\n", list->frame_size); + /* for (i = 0; i < 10; i++) { */ + for (i = 0; i < 2; i++) { + pr_info("TLAN: Buffer[%d].count, addr = 0x%08x, 0x%08x\n", + i, list->buffer[i].count, list->buffer[i].address); } -} /* TLan_PrintList */ +} - /*************************************************************** - * TLan_ReadAndClearStats - * - * Returns: - * Nothing - * Parms: - * dev Pointer to device structure of adapter - * to which to read stats. - * record Flag indicating whether to add - * - * This functions reads all the internal status registers - * of the TLAN chip, which clears them as a side effect. - * It then either adds the values to the device's status - * struct, or discards them, depending on whether record - * is TLAN_RECORD (!=0) or TLAN_IGNORE (==0). - * - **************************************************************/ +/*************************************************************** + * tlan_read_and_clear_stats + * + * Returns: + * Nothing + * Parms: + * dev Pointer to device structure of adapter + * to which to read stats. + * record Flag indicating whether to add + * + * This functions reads all the internal status registers + * of the TLAN chip, which clears them as a side effect. + * It then either adds the values to the device's status + * struct, or discards them, depending on whether record + * is TLAN_RECORD (!=0) or TLAN_IGNORE (==0). + * + **************************************************************/ -static void TLan_ReadAndClearStats( struct net_device *dev, int record ) +static void tlan_read_and_clear_stats(struct net_device *dev, int record) { u32 tx_good, tx_under; u32 rx_good, rx_over; @@ -2129,41 +2161,42 @@ static void TLan_ReadAndClearStats( struct net_device *dev, int record ) u32 multi_col, single_col; u32 excess_col, late_col, loss; - outw( TLAN_GOOD_TX_FRMS, dev->base_addr + TLAN_DIO_ADR ); - tx_good = inb( dev->base_addr + TLAN_DIO_DATA ); - tx_good += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8; - tx_good += inb( dev->base_addr + TLAN_DIO_DATA + 2 ) << 16; - tx_under = inb( dev->base_addr + TLAN_DIO_DATA + 3 ); - - outw( TLAN_GOOD_RX_FRMS, dev->base_addr + TLAN_DIO_ADR ); - rx_good = inb( dev->base_addr + TLAN_DIO_DATA ); - rx_good += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8; - rx_good += inb( dev->base_addr + TLAN_DIO_DATA + 2 ) << 16; - rx_over = inb( dev->base_addr + TLAN_DIO_DATA + 3 ); - - outw( TLAN_DEFERRED_TX, dev->base_addr + TLAN_DIO_ADR ); - def_tx = inb( dev->base_addr + TLAN_DIO_DATA ); - def_tx += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8; - crc = inb( dev->base_addr + TLAN_DIO_DATA + 2 ); - code = inb( dev->base_addr + TLAN_DIO_DATA + 3 ); - - outw( TLAN_MULTICOL_FRMS, dev->base_addr + TLAN_DIO_ADR ); - multi_col = inb( dev->base_addr + TLAN_DIO_DATA ); - multi_col += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8; - single_col = inb( dev->base_addr + TLAN_DIO_DATA + 2 ); - single_col += inb( dev->base_addr + TLAN_DIO_DATA + 3 ) << 8; - - outw( TLAN_EXCESSCOL_FRMS, dev->base_addr + TLAN_DIO_ADR ); - excess_col = inb( dev->base_addr + TLAN_DIO_DATA ); - late_col = inb( dev->base_addr + TLAN_DIO_DATA + 1 ); - loss = inb( dev->base_addr + TLAN_DIO_DATA + 2 ); - - if ( record ) { + outw(TLAN_GOOD_TX_FRMS, dev->base_addr + TLAN_DIO_ADR); + tx_good = inb(dev->base_addr + TLAN_DIO_DATA); + tx_good += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8; + tx_good += inb(dev->base_addr + TLAN_DIO_DATA + 2) << 16; + tx_under = inb(dev->base_addr + TLAN_DIO_DATA + 3); + + outw(TLAN_GOOD_RX_FRMS, dev->base_addr + TLAN_DIO_ADR); + rx_good = inb(dev->base_addr + TLAN_DIO_DATA); + rx_good += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8; + rx_good += inb(dev->base_addr + TLAN_DIO_DATA + 2) << 16; + rx_over = inb(dev->base_addr + TLAN_DIO_DATA + 3); + + outw(TLAN_DEFERRED_TX, dev->base_addr + TLAN_DIO_ADR); + def_tx = inb(dev->base_addr + TLAN_DIO_DATA); + def_tx += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8; + crc = inb(dev->base_addr + TLAN_DIO_DATA + 2); + code = inb(dev->base_addr + TLAN_DIO_DATA + 3); + + outw(TLAN_MULTICOL_FRMS, dev->base_addr + TLAN_DIO_ADR); + multi_col = inb(dev->base_addr + TLAN_DIO_DATA); + multi_col += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8; + single_col = inb(dev->base_addr + TLAN_DIO_DATA + 2); + single_col += inb(dev->base_addr + TLAN_DIO_DATA + 3) << 8; + + outw(TLAN_EXCESSCOL_FRMS, dev->base_addr + TLAN_DIO_ADR); + excess_col = inb(dev->base_addr + TLAN_DIO_DATA); + late_col = inb(dev->base_addr + TLAN_DIO_DATA + 1); + loss = inb(dev->base_addr + TLAN_DIO_DATA + 2); + + if (record) { dev->stats.rx_packets += rx_good; dev->stats.rx_errors += rx_over + crc + code; dev->stats.tx_packets += tx_good; dev->stats.tx_errors += tx_under + loss; - dev->stats.collisions += multi_col + single_col + excess_col + late_col; + dev->stats.collisions += multi_col + + single_col + excess_col + late_col; dev->stats.rx_over_errors += rx_over; dev->stats.rx_crc_errors += crc; @@ -2173,39 +2206,39 @@ static void TLan_ReadAndClearStats( struct net_device *dev, int record ) dev->stats.tx_carrier_errors += loss; } -} /* TLan_ReadAndClearStats */ +} - /*************************************************************** - * TLan_Reset - * - * Returns: - * 0 - * Parms: - * dev Pointer to device structure of adapter - * to be reset. - * - * This function resets the adapter and it's physical - * device. See Chap. 3, pp. 9-10 of the "ThunderLAN - * Programmer's Guide" for details. The routine tries to - * implement what is detailed there, though adjustments - * have been made. - * - **************************************************************/ +/*************************************************************** + * TLan_Reset + * + * Returns: + * 0 + * Parms: + * dev Pointer to device structure of adapter + * to be reset. + * + * This function resets the adapter and it's physical + * device. See Chap. 3, pp. 9-10 of the "ThunderLAN + * Programmer's Guide" for details. The routine tries to + * implement what is detailed there, though adjustments + * have been made. + * + **************************************************************/ static void -TLan_ResetAdapter( struct net_device *dev ) +tlan_reset_adapter(struct net_device *dev) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); int i; u32 addr; u32 data; u8 data8; - priv->tlanFullDuplex = false; - priv->phyOnline=0; + priv->tlan_full_duplex = false; + priv->phy_online = 0; netif_carrier_off(dev); /* 1. Assert reset bit. */ @@ -2216,7 +2249,7 @@ TLan_ResetAdapter( struct net_device *dev ) udelay(1000); -/* 2. Turn off interrupts. ( Probably isn't necessary ) */ +/* 2. Turn off interrupts. (Probably isn't necessary) */ data = inl(dev->base_addr + TLAN_HOST_CMD); data |= TLAN_HC_INT_OFF; @@ -2224,207 +2257,208 @@ TLan_ResetAdapter( struct net_device *dev ) /* 3. Clear AREGs and HASHs. */ - for ( i = TLAN_AREG_0; i <= TLAN_HASH_2; i += 4 ) { - TLan_DioWrite32( dev->base_addr, (u16) i, 0 ); - } + for (i = TLAN_AREG_0; i <= TLAN_HASH_2; i += 4) + tlan_dio_write32(dev->base_addr, (u16) i, 0); /* 4. Setup NetConfig register. */ data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN; - TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, (u16) data ); + tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, (u16) data); /* 5. Load Ld_Tmr and Ld_Thr in HOST_CMD. */ - outl( TLAN_HC_LD_TMR | 0x3f, dev->base_addr + TLAN_HOST_CMD ); - outl( TLAN_HC_LD_THR | 0x9, dev->base_addr + TLAN_HOST_CMD ); + outl(TLAN_HC_LD_TMR | 0x3f, dev->base_addr + TLAN_HOST_CMD); + outl(TLAN_HC_LD_THR | 0x9, dev->base_addr + TLAN_HOST_CMD); /* 6. Unreset the MII by setting NMRST (in NetSio) to 1. */ - outw( TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR ); + outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR); addr = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO; - TLan_SetBit( TLAN_NET_SIO_NMRST, addr ); + tlan_set_bit(TLAN_NET_SIO_NMRST, addr); /* 7. Setup the remaining registers. */ - if ( priv->tlanRev >= 0x30 ) { + if (priv->tlan_rev >= 0x30) { data8 = TLAN_ID_TX_EOC | TLAN_ID_RX_EOC; - TLan_DioWrite8( dev->base_addr, TLAN_INT_DIS, data8 ); + tlan_dio_write8(dev->base_addr, TLAN_INT_DIS, data8); } - TLan_PhyDetect( dev ); + tlan_phy_detect(dev); data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN; - if ( priv->adapter->flags & TLAN_ADAPTER_BIT_RATE_PHY ) { + if (priv->adapter->flags & TLAN_ADAPTER_BIT_RATE_PHY) { data |= TLAN_NET_CFG_BIT; - if ( priv->aui == 1 ) { - TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x0a ); - } else if ( priv->duplex == TLAN_DUPLEX_FULL ) { - TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x00 ); - priv->tlanFullDuplex = true; + if (priv->aui == 1) { + tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x0a); + } else if (priv->duplex == TLAN_DUPLEX_FULL) { + tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x00); + priv->tlan_full_duplex = true; } else { - TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x08 ); + tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x08); } } - if ( priv->phyNum == 0 ) { + if (priv->phy_num == 0) data |= TLAN_NET_CFG_PHY_EN; - } - TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, (u16) data ); + tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, (u16) data); - if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) { - TLan_FinishReset( dev ); - } else { - TLan_PhyPowerDown( dev ); - } + if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) + tlan_finish_reset(dev); + else + tlan_phy_power_down(dev); -} /* TLan_ResetAdapter */ +} static void -TLan_FinishReset( struct net_device *dev ) +tlan_finish_reset(struct net_device *dev) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); u8 data; u32 phy; u8 sio; u16 status; u16 partner; u16 tlphy_ctl; - u16 tlphy_par; + u16 tlphy_par; u16 tlphy_id1, tlphy_id2; - int i; + int i; - phy = priv->phy[priv->phyNum]; + phy = priv->phy[priv->phy_num]; data = TLAN_NET_CMD_NRESET | TLAN_NET_CMD_NWRAP; - if ( priv->tlanFullDuplex ) { + if (priv->tlan_full_duplex) data |= TLAN_NET_CMD_DUPLEX; - } - TLan_DioWrite8( dev->base_addr, TLAN_NET_CMD, data ); + tlan_dio_write8(dev->base_addr, TLAN_NET_CMD, data); data = TLAN_NET_MASK_MASK4 | TLAN_NET_MASK_MASK5; - if ( priv->phyNum == 0 ) { + if (priv->phy_num == 0) data |= TLAN_NET_MASK_MASK7; - } - TLan_DioWrite8( dev->base_addr, TLAN_NET_MASK, data ); - TLan_DioWrite16( dev->base_addr, TLAN_MAX_RX, ((1536)+7)&~7 ); - TLan_MiiReadReg( dev, phy, MII_GEN_ID_HI, &tlphy_id1 ); - TLan_MiiReadReg( dev, phy, MII_GEN_ID_LO, &tlphy_id2 ); + tlan_dio_write8(dev->base_addr, TLAN_NET_MASK, data); + tlan_dio_write16(dev->base_addr, TLAN_MAX_RX, ((1536)+7)&~7); + tlan_mii_read_reg(dev, phy, MII_GEN_ID_HI, &tlphy_id1); + tlan_mii_read_reg(dev, phy, MII_GEN_ID_LO, &tlphy_id2); - if ( ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) || - ( priv->aui ) ) { + if ((priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) || + (priv->aui)) { status = MII_GS_LINK; - printk( "TLAN: %s: Link forced.\n", dev->name ); + pr_info("TLAN: %s: Link forced.\n", dev->name); } else { - TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status ); - udelay( 1000 ); - TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status ); - if ( (status & MII_GS_LINK) && - /* We only support link info on Nat.Sem. PHY's */ - (tlphy_id1 == NAT_SEM_ID1) && - (tlphy_id2 == NAT_SEM_ID2) ) { - TLan_MiiReadReg( dev, phy, MII_AN_LPA, &partner ); - TLan_MiiReadReg( dev, phy, TLAN_TLPHY_PAR, &tlphy_par ); - - printk( "TLAN: %s: Link active with ", dev->name ); + tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status); + udelay(1000); + tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status); + if ((status & MII_GS_LINK) && + /* We only support link info on Nat.Sem. PHY's */ + (tlphy_id1 == NAT_SEM_ID1) && + (tlphy_id2 == NAT_SEM_ID2)) { + tlan_mii_read_reg(dev, phy, MII_AN_LPA, &partner); + tlan_mii_read_reg(dev, phy, TLAN_TLPHY_PAR, &tlphy_par); + + pr_info("TLAN: %s: Link active with ", dev->name); if (!(tlphy_par & TLAN_PHY_AN_EN_STAT)) { - printk( "forced 10%sMbps %s-Duplex\n", - tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0", - tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half"); + pr_info("forced 10%sMbps %s-Duplex\n", + tlphy_par & TLAN_PHY_SPEED_100 + ? "" : "0", + tlphy_par & TLAN_PHY_DUPLEX_FULL + ? "Full" : "Half"); } else { - printk( "AutoNegotiation enabled, at 10%sMbps %s-Duplex\n", - tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0", - tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half"); - printk("TLAN: Partner capability: "); - for (i = 5; i <= 10; i++) - if (partner & (1<base_addr, TLAN_LED_REG, TLAN_LED_LINK ); + tlan_dio_write8(dev->base_addr, TLAN_LED_REG, + TLAN_LED_LINK); #ifdef MONITOR /* We have link beat..for now anyway */ - priv->link = 1; - /*Enabling link beat monitoring */ - TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_LINK_BEAT ); + priv->link = 1; + /*Enabling link beat monitoring */ + tlan_set_timer(dev, (10*HZ), TLAN_TIMER_LINK_BEAT); #endif } else if (status & MII_GS_LINK) { - printk( "TLAN: %s: Link active\n", dev->name ); - TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK ); + pr_info("TLAN: %s: Link active\n", dev->name); + tlan_dio_write8(dev->base_addr, TLAN_LED_REG, + TLAN_LED_LINK); } } - if ( priv->phyNum == 0 ) { - TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl ); - tlphy_ctl |= TLAN_TC_INTEN; - TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl ); - sio = TLan_DioRead8( dev->base_addr, TLAN_NET_SIO ); - sio |= TLAN_NET_SIO_MINTEN; - TLan_DioWrite8( dev->base_addr, TLAN_NET_SIO, sio ); - } - - if ( status & MII_GS_LINK ) { - TLan_SetMac( dev, 0, dev->dev_addr ); - priv->phyOnline = 1; - outb( ( TLAN_HC_INT_ON >> 8 ), dev->base_addr + TLAN_HOST_CMD + 1 ); - if ( debug >= 1 && debug != TLAN_DEBUG_PROBE ) { - outb( ( TLAN_HC_REQ_INT >> 8 ), dev->base_addr + TLAN_HOST_CMD + 1 ); - } - outl( priv->rxListDMA, dev->base_addr + TLAN_CH_PARM ); - outl( TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD ); + if (priv->phy_num == 0) { + tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl); + tlphy_ctl |= TLAN_TC_INTEN; + tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL, tlphy_ctl); + sio = tlan_dio_read8(dev->base_addr, TLAN_NET_SIO); + sio |= TLAN_NET_SIO_MINTEN; + tlan_dio_write8(dev->base_addr, TLAN_NET_SIO, sio); + } + + if (status & MII_GS_LINK) { + tlan_set_mac(dev, 0, dev->dev_addr); + priv->phy_online = 1; + outb((TLAN_HC_INT_ON >> 8), dev->base_addr + TLAN_HOST_CMD + 1); + if (debug >= 1 && debug != TLAN_DEBUG_PROBE) + outb((TLAN_HC_REQ_INT >> 8), + dev->base_addr + TLAN_HOST_CMD + 1); + outl(priv->rx_list_dma, dev->base_addr + TLAN_CH_PARM); + outl(TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD); netif_carrier_on(dev); } else { - printk( "TLAN: %s: Link inactive, will retry in 10 secs...\n", - dev->name ); - TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_FINISH_RESET ); + pr_info("TLAN: %s: Link inactive, will retry in 10 secs...\n", + dev->name); + tlan_set_timer(dev, (10*HZ), TLAN_TIMER_FINISH_RESET); return; } - TLan_SetMulticastList(dev); + tlan_set_multicast_list(dev); -} /* TLan_FinishReset */ +} - /*************************************************************** - * TLan_SetMac - * - * Returns: - * Nothing - * Parms: - * dev Pointer to device structure of adapter - * on which to change the AREG. - * areg The AREG to set the address in (0 - 3). - * mac A pointer to an array of chars. Each - * element stores one byte of the address. - * IE, it isn't in ascii. - * - * This function transfers a MAC address to one of the - * TLAN AREGs (address registers). The TLAN chip locks - * the register on writing to offset 0 and unlocks the - * register after writing to offset 5. If NULL is passed - * in mac, then the AREG is filled with 0's. - * - **************************************************************/ +/*************************************************************** + * tlan_set_mac + * + * Returns: + * Nothing + * Parms: + * dev Pointer to device structure of adapter + * on which to change the AREG. + * areg The AREG to set the address in (0 - 3). + * mac A pointer to an array of chars. Each + * element stores one byte of the address. + * IE, it isn't in ascii. + * + * This function transfers a MAC address to one of the + * TLAN AREGs (address registers). The TLAN chip locks + * the register on writing to offset 0 and unlocks the + * register after writing to offset 5. If NULL is passed + * in mac, then the AREG is filled with 0's. + * + **************************************************************/ -static void TLan_SetMac( struct net_device *dev, int areg, char *mac ) +static void tlan_set_mac(struct net_device *dev, int areg, char *mac) { int i; areg *= 6; - if ( mac != NULL ) { - for ( i = 0; i < 6; i++ ) - TLan_DioWrite8( dev->base_addr, - TLAN_AREG_0 + areg + i, mac[i] ); + if (mac != NULL) { + for (i = 0; i < 6; i++) + tlan_dio_write8(dev->base_addr, + TLAN_AREG_0 + areg + i, mac[i]); } else { - for ( i = 0; i < 6; i++ ) - TLan_DioWrite8( dev->base_addr, - TLAN_AREG_0 + areg + i, 0 ); + for (i = 0; i < 6; i++) + tlan_dio_write8(dev->base_addr, + TLAN_AREG_0 + areg + i, 0); } -} /* TLan_SetMac */ +} @@ -2432,205 +2466,202 @@ static void TLan_SetMac( struct net_device *dev, int areg, char *mac ) /***************************************************************************** ****************************************************************************** - ThunderLAN Driver PHY Layer Routines +ThunderLAN driver PHY layer routines ****************************************************************************** *****************************************************************************/ - /********************************************************************* - * TLan_PhyPrint - * - * Returns: - * Nothing - * Parms: - * dev A pointer to the device structure of the - * TLAN device having the PHYs to be detailed. - * - * This function prints the registers a PHY (aka transceiver). - * - ********************************************************************/ +/********************************************************************* + * tlan_phy_print + * + * Returns: + * Nothing + * Parms: + * dev A pointer to the device structure of the + * TLAN device having the PHYs to be detailed. + * + * This function prints the registers a PHY (aka transceiver). + * + ********************************************************************/ -static void TLan_PhyPrint( struct net_device *dev ) +static void tlan_phy_print(struct net_device *dev) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); u16 i, data0, data1, data2, data3, phy; - phy = priv->phy[priv->phyNum]; - - if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) { - printk( "TLAN: Device %s, Unmanaged PHY.\n", dev->name ); - } else if ( phy <= TLAN_PHY_MAX_ADDR ) { - printk( "TLAN: Device %s, PHY 0x%02x.\n", dev->name, phy ); - printk( "TLAN: Off. +0 +1 +2 +3\n" ); - for ( i = 0; i < 0x20; i+= 4 ) { - printk( "TLAN: 0x%02x", i ); - TLan_MiiReadReg( dev, phy, i, &data0 ); - printk( " 0x%04hx", data0 ); - TLan_MiiReadReg( dev, phy, i + 1, &data1 ); - printk( " 0x%04hx", data1 ); - TLan_MiiReadReg( dev, phy, i + 2, &data2 ); - printk( " 0x%04hx", data2 ); - TLan_MiiReadReg( dev, phy, i + 3, &data3 ); - printk( " 0x%04hx\n", data3 ); + phy = priv->phy[priv->phy_num]; + + if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) { + pr_info("TLAN: Device %s, Unmanaged PHY.\n", dev->name); + } else if (phy <= TLAN_PHY_MAX_ADDR) { + pr_info("TLAN: Device %s, PHY 0x%02x.\n", dev->name, phy); + pr_info("TLAN: Off. +0 +1 +2 +3\n"); + for (i = 0; i < 0x20; i += 4) { + pr_info("TLAN: 0x%02x", i); + tlan_mii_read_reg(dev, phy, i, &data0); + printk(" 0x%04hx", data0); + tlan_mii_read_reg(dev, phy, i + 1, &data1); + printk(" 0x%04hx", data1); + tlan_mii_read_reg(dev, phy, i + 2, &data2); + printk(" 0x%04hx", data2); + tlan_mii_read_reg(dev, phy, i + 3, &data3); + printk(" 0x%04hx\n", data3); } } else { - printk( "TLAN: Device %s, Invalid PHY.\n", dev->name ); + pr_info("TLAN: Device %s, Invalid PHY.\n", dev->name); } -} /* TLan_PhyPrint */ +} - /********************************************************************* - * TLan_PhyDetect - * - * Returns: - * Nothing - * Parms: - * dev A pointer to the device structure of the adapter - * for which the PHY needs determined. - * - * So far I've found that adapters which have external PHYs - * may also use the internal PHY for part of the functionality. - * (eg, AUI/Thinnet). This function finds out if this TLAN - * chip has an internal PHY, and then finds the first external - * PHY (starting from address 0) if it exists). - * - ********************************************************************/ +/********************************************************************* + * tlan_phy_detect + * + * Returns: + * Nothing + * Parms: + * dev A pointer to the device structure of the adapter + * for which the PHY needs determined. + * + * So far I've found that adapters which have external PHYs + * may also use the internal PHY for part of the functionality. + * (eg, AUI/Thinnet). This function finds out if this TLAN + * chip has an internal PHY, and then finds the first external + * PHY (starting from address 0) if it exists). + * + ********************************************************************/ -static void TLan_PhyDetect( struct net_device *dev ) +static void tlan_phy_detect(struct net_device *dev) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); u16 control; u16 hi; u16 lo; u32 phy; - if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) { - priv->phyNum = 0xFFFF; + if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) { + priv->phy_num = 0xffff; return; } - TLan_MiiReadReg( dev, TLAN_PHY_MAX_ADDR, MII_GEN_ID_HI, &hi ); + tlan_mii_read_reg(dev, TLAN_PHY_MAX_ADDR, MII_GEN_ID_HI, &hi); - if ( hi != 0xFFFF ) { + if (hi != 0xffff) priv->phy[0] = TLAN_PHY_MAX_ADDR; - } else { + else priv->phy[0] = TLAN_PHY_NONE; - } priv->phy[1] = TLAN_PHY_NONE; - for ( phy = 0; phy <= TLAN_PHY_MAX_ADDR; phy++ ) { - TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &control ); - TLan_MiiReadReg( dev, phy, MII_GEN_ID_HI, &hi ); - TLan_MiiReadReg( dev, phy, MII_GEN_ID_LO, &lo ); - if ( ( control != 0xFFFF ) || - ( hi != 0xFFFF ) || ( lo != 0xFFFF ) ) { - TLAN_DBG( TLAN_DEBUG_GNRL, - "PHY found at %02x %04x %04x %04x\n", - phy, control, hi, lo ); - if ( ( priv->phy[1] == TLAN_PHY_NONE ) && - ( phy != TLAN_PHY_MAX_ADDR ) ) { + for (phy = 0; phy <= TLAN_PHY_MAX_ADDR; phy++) { + tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &control); + tlan_mii_read_reg(dev, phy, MII_GEN_ID_HI, &hi); + tlan_mii_read_reg(dev, phy, MII_GEN_ID_LO, &lo); + if ((control != 0xffff) || + (hi != 0xffff) || (lo != 0xffff)) { + TLAN_DBG(TLAN_DEBUG_GNRL, + "PHY found at %02x %04x %04x %04x\n", + phy, control, hi, lo); + if ((priv->phy[1] == TLAN_PHY_NONE) && + (phy != TLAN_PHY_MAX_ADDR)) { priv->phy[1] = phy; } } } - if ( priv->phy[1] != TLAN_PHY_NONE ) { - priv->phyNum = 1; - } else if ( priv->phy[0] != TLAN_PHY_NONE ) { - priv->phyNum = 0; - } else { - printk( "TLAN: Cannot initialize device, no PHY was found!\n" ); - } + if (priv->phy[1] != TLAN_PHY_NONE) + priv->phy_num = 1; + else if (priv->phy[0] != TLAN_PHY_NONE) + priv->phy_num = 0; + else + pr_info("TLAN: Cannot initialize device, no PHY was found!\n"); -} /* TLan_PhyDetect */ +} -static void TLan_PhyPowerDown( struct net_device *dev ) +static void tlan_phy_power_down(struct net_device *dev) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); u16 value; - TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Powering down PHY(s).\n", dev->name ); + TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Powering down PHY(s).\n", dev->name); value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE; - TLan_MiiSync( dev->base_addr ); - TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value ); - if ( ( priv->phyNum == 0 ) && - ( priv->phy[1] != TLAN_PHY_NONE ) && - ( ! ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) ) ) { - TLan_MiiSync( dev->base_addr ); - TLan_MiiWriteReg( dev, priv->phy[1], MII_GEN_CTL, value ); + tlan_mii_sync(dev->base_addr); + tlan_mii_write_reg(dev, priv->phy[priv->phy_num], MII_GEN_CTL, value); + if ((priv->phy_num == 0) && + (priv->phy[1] != TLAN_PHY_NONE) && + (!(priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10))) { + tlan_mii_sync(dev->base_addr); + tlan_mii_write_reg(dev, priv->phy[1], MII_GEN_CTL, value); } /* Wait for 50 ms and powerup * This is abitrary. It is intended to make sure the * transceiver settles. */ - TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_PUP ); + tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_PUP); -} /* TLan_PhyPowerDown */ +} -static void TLan_PhyPowerUp( struct net_device *dev ) +static void tlan_phy_power_up(struct net_device *dev) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); u16 value; - TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Powering up PHY.\n", dev->name ); - TLan_MiiSync( dev->base_addr ); + TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Powering up PHY.\n", dev->name); + tlan_mii_sync(dev->base_addr); value = MII_GC_LOOPBK; - TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value ); - TLan_MiiSync(dev->base_addr); + tlan_mii_write_reg(dev, priv->phy[priv->phy_num], MII_GEN_CTL, value); + tlan_mii_sync(dev->base_addr); /* Wait for 500 ms and reset the * transceiver. The TLAN docs say both 50 ms and * 500 ms, so do the longer, just in case. */ - TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_RESET ); + tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_RESET); -} /* TLan_PhyPowerUp */ +} -static void TLan_PhyReset( struct net_device *dev ) +static void tlan_phy_reset(struct net_device *dev) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); u16 phy; u16 value; - phy = priv->phy[priv->phyNum]; + phy = priv->phy[priv->phy_num]; - TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Reseting PHY.\n", dev->name ); - TLan_MiiSync( dev->base_addr ); + TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Reseting PHY.\n", dev->name); + tlan_mii_sync(dev->base_addr); value = MII_GC_LOOPBK | MII_GC_RESET; - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, value ); - TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &value ); - while ( value & MII_GC_RESET ) { - TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &value ); - } + tlan_mii_write_reg(dev, phy, MII_GEN_CTL, value); + tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value); + while (value & MII_GC_RESET) + tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value); /* Wait for 500 ms and initialize. * I don't remember why I wait this long. * I've changed this to 50ms, as it seems long enough. */ - TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_START_LINK ); + tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_START_LINK); -} /* TLan_PhyReset */ +} -static void TLan_PhyStartLink( struct net_device *dev ) +static void tlan_phy_start_link(struct net_device *dev) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); u16 ability; u16 control; u16 data; @@ -2638,86 +2669,88 @@ static void TLan_PhyStartLink( struct net_device *dev ) u16 status; u16 tctl; - phy = priv->phy[priv->phyNum]; - TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Trying to activate link.\n", dev->name ); - TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status ); - TLan_MiiReadReg( dev, phy, MII_GEN_STS, &ability ); + phy = priv->phy[priv->phy_num]; + TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Trying to activate link.\n", dev->name); + tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status); + tlan_mii_read_reg(dev, phy, MII_GEN_STS, &ability); - if ( ( status & MII_GS_AUTONEG ) && - ( ! priv->aui ) ) { + if ((status & MII_GS_AUTONEG) && + (!priv->aui)) { ability = status >> 11; - if ( priv->speed == TLAN_SPEED_10 && - priv->duplex == TLAN_DUPLEX_HALF) { - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0000); - } else if ( priv->speed == TLAN_SPEED_10 && - priv->duplex == TLAN_DUPLEX_FULL) { - priv->tlanFullDuplex = true; - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0100); - } else if ( priv->speed == TLAN_SPEED_100 && - priv->duplex == TLAN_DUPLEX_HALF) { - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2000); - } else if ( priv->speed == TLAN_SPEED_100 && - priv->duplex == TLAN_DUPLEX_FULL) { - priv->tlanFullDuplex = true; - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2100); + if (priv->speed == TLAN_SPEED_10 && + priv->duplex == TLAN_DUPLEX_HALF) { + tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x0000); + } else if (priv->speed == TLAN_SPEED_10 && + priv->duplex == TLAN_DUPLEX_FULL) { + priv->tlan_full_duplex = true; + tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x0100); + } else if (priv->speed == TLAN_SPEED_100 && + priv->duplex == TLAN_DUPLEX_HALF) { + tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x2000); + } else if (priv->speed == TLAN_SPEED_100 && + priv->duplex == TLAN_DUPLEX_FULL) { + priv->tlan_full_duplex = true; + tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x2100); } else { /* Set Auto-Neg advertisement */ - TLan_MiiWriteReg( dev, phy, MII_AN_ADV, (ability << 5) | 1); + tlan_mii_write_reg(dev, phy, MII_AN_ADV, + (ability << 5) | 1); /* Enablee Auto-Neg */ - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1000 ); + tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x1000); /* Restart Auto-Neg */ - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1200 ); + tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x1200); /* Wait for 4 sec for autonegotiation - * to complete. The max spec time is less than this - * but the card need additional time to start AN. - * .5 sec should be plenty extra. - */ - printk( "TLAN: %s: Starting autonegotiation.\n", dev->name ); - TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN ); + * to complete. The max spec time is less than this + * but the card need additional time to start AN. + * .5 sec should be plenty extra. + */ + pr_info("TLAN: %s: Starting autonegotiation.\n", + dev->name); + tlan_set_timer(dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN); return; } } - if ( ( priv->aui ) && ( priv->phyNum != 0 ) ) { - priv->phyNum = 0; - data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN; - TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, data ); - TLan_SetTimer( dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN ); + if ((priv->aui) && (priv->phy_num != 0)) { + priv->phy_num = 0; + data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN + | TLAN_NET_CFG_PHY_EN; + tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, data); + tlan_set_timer(dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN); return; - } else if ( priv->phyNum == 0 ) { + } else if (priv->phy_num == 0) { control = 0; - TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tctl ); - if ( priv->aui ) { - tctl |= TLAN_TC_AUISEL; + tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tctl); + if (priv->aui) { + tctl |= TLAN_TC_AUISEL; } else { - tctl &= ~TLAN_TC_AUISEL; - if ( priv->duplex == TLAN_DUPLEX_FULL ) { + tctl &= ~TLAN_TC_AUISEL; + if (priv->duplex == TLAN_DUPLEX_FULL) { control |= MII_GC_DUPLEX; - priv->tlanFullDuplex = true; + priv->tlan_full_duplex = true; } - if ( priv->speed == TLAN_SPEED_100 ) { + if (priv->speed == TLAN_SPEED_100) control |= MII_GC_SPEEDSEL; - } } - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, control ); - TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tctl ); + tlan_mii_write_reg(dev, phy, MII_GEN_CTL, control); + tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL, tctl); } /* Wait for 2 sec to give the transceiver time * to establish link. */ - TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_FINISH_RESET ); + tlan_set_timer(dev, (4*HZ), TLAN_TIMER_FINISH_RESET); -} /* TLan_PhyStartLink */ +} -static void TLan_PhyFinishAutoNeg( struct net_device *dev ) +static void tlan_phy_finish_auto_neg(struct net_device *dev) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); u16 an_adv; u16 an_lpa; u16 data; @@ -2725,115 +2758,118 @@ static void TLan_PhyFinishAutoNeg( struct net_device *dev ) u16 phy; u16 status; - phy = priv->phy[priv->phyNum]; + phy = priv->phy[priv->phy_num]; - TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status ); - udelay( 1000 ); - TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status ); + tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status); + udelay(1000); + tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status); - if ( ! ( status & MII_GS_AUTOCMPLT ) ) { + if (!(status & MII_GS_AUTOCMPLT)) { /* Wait for 8 sec to give the process * more time. Perhaps we should fail after a while. */ - if (!priv->neg_be_verbose++) { - pr_info("TLAN: Giving autonegotiation more time.\n"); - pr_info("TLAN: Please check that your adapter has\n"); - pr_info("TLAN: been properly connected to a HUB or Switch.\n"); - pr_info("TLAN: Trying to establish link in the background...\n"); - } - TLan_SetTimer( dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN ); + if (!priv->neg_be_verbose++) { + pr_info("TLAN: Giving autonegotiation more time.\n"); + pr_info("TLAN: Please check that your adapter has\n"); + pr_info("TLAN: been properly connected to a HUB or Switch.\n"); + pr_info("TLAN: Trying to establish link in the background...\n"); + } + tlan_set_timer(dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN); return; } - printk( "TLAN: %s: Autonegotiation complete.\n", dev->name ); - TLan_MiiReadReg( dev, phy, MII_AN_ADV, &an_adv ); - TLan_MiiReadReg( dev, phy, MII_AN_LPA, &an_lpa ); + pr_info("TLAN: %s: Autonegotiation complete.\n", dev->name); + tlan_mii_read_reg(dev, phy, MII_AN_ADV, &an_adv); + tlan_mii_read_reg(dev, phy, MII_AN_LPA, &an_lpa); mode = an_adv & an_lpa & 0x03E0; - if ( mode & 0x0100 ) { - priv->tlanFullDuplex = true; - } else if ( ! ( mode & 0x0080 ) && ( mode & 0x0040 ) ) { - priv->tlanFullDuplex = true; - } - - if ( ( ! ( mode & 0x0180 ) ) && - ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) && - ( priv->phyNum != 0 ) ) { - priv->phyNum = 0; - data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN; - TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, data ); - TLan_SetTimer( dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN ); + if (mode & 0x0100) + priv->tlan_full_duplex = true; + else if (!(mode & 0x0080) && (mode & 0x0040)) + priv->tlan_full_duplex = true; + + if ((!(mode & 0x0180)) && + (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10) && + (priv->phy_num != 0)) { + priv->phy_num = 0; + data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN + | TLAN_NET_CFG_PHY_EN; + tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, data); + tlan_set_timer(dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN); return; } - if ( priv->phyNum == 0 ) { - if ( ( priv->duplex == TLAN_DUPLEX_FULL ) || - ( an_adv & an_lpa & 0x0040 ) ) { - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, - MII_GC_AUTOENB | MII_GC_DUPLEX ); - pr_info("TLAN: Starting internal PHY with FULL-DUPLEX\n" ); + if (priv->phy_num == 0) { + if ((priv->duplex == TLAN_DUPLEX_FULL) || + (an_adv & an_lpa & 0x0040)) { + tlan_mii_write_reg(dev, phy, MII_GEN_CTL, + MII_GC_AUTOENB | MII_GC_DUPLEX); + pr_info("TLAN: Starting internal PHY with FULL-DUPLEX\n"); } else { - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB ); - pr_info( "TLAN: Starting internal PHY with HALF-DUPLEX\n" ); + tlan_mii_write_reg(dev, phy, MII_GEN_CTL, + MII_GC_AUTOENB); + pr_info("TLAN: Starting internal PHY with HALF-DUPLEX\n"); } } /* Wait for 100 ms. No reason in partiticular. */ - TLan_SetTimer( dev, (HZ/10), TLAN_TIMER_FINISH_RESET ); + tlan_set_timer(dev, (HZ/10), TLAN_TIMER_FINISH_RESET); -} /* TLan_PhyFinishAutoNeg */ +} #ifdef MONITOR - /********************************************************************* - * - * TLan_phyMonitor - * - * Returns: - * None - * - * Params: - * dev The device structure of this device. - * - * - * This function monitors PHY condition by reading the status - * register via the MII bus. This can be used to give info - * about link changes (up/down), and possible switch to alternate - * media. - * - * ******************************************************************/ - -void TLan_PhyMonitor( struct net_device *dev ) +/********************************************************************* + * + * tlan_phy_monitor + * + * Returns: + * None + * + * Params: + * dev The device structure of this device. + * + * + * This function monitors PHY condition by reading the status + * register via the MII bus. This can be used to give info + * about link changes (up/down), and possible switch to alternate + * media. + * + *******************************************************************/ + +void tlan_phy_monitor(struct net_device *dev) { - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); u16 phy; u16 phy_status; - phy = priv->phy[priv->phyNum]; + phy = priv->phy[priv->phy_num]; - /* Get PHY status register */ - TLan_MiiReadReg( dev, phy, MII_GEN_STS, &phy_status ); + /* Get PHY status register */ + tlan_mii_read_reg(dev, phy, MII_GEN_STS, &phy_status); - /* Check if link has been lost */ - if (!(phy_status & MII_GS_LINK)) { - if (priv->link) { - priv->link = 0; - printk(KERN_DEBUG "TLAN: %s has lost link\n", dev->name); - netif_carrier_off(dev); - TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT ); - return; + /* Check if link has been lost */ + if (!(phy_status & MII_GS_LINK)) { + if (priv->link) { + priv->link = 0; + printk(KERN_DEBUG "TLAN: %s has lost link\n", + dev->name); + netif_carrier_off(dev); + tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT); + return; } } - /* Link restablished? */ - if ((phy_status & MII_GS_LINK) && !priv->link) { - priv->link = 1; - printk(KERN_DEBUG "TLAN: %s has reestablished link\n", dev->name); + /* Link restablished? */ + if ((phy_status & MII_GS_LINK) && !priv->link) { + priv->link = 1; + printk(KERN_DEBUG "TLAN: %s has reestablished link\n", + dev->name); netif_carrier_on(dev); - } + } /* Setup a new monitor */ - TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT ); + tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT); } #endif /* MONITOR */ @@ -2842,47 +2878,48 @@ void TLan_PhyMonitor( struct net_device *dev ) /***************************************************************************** ****************************************************************************** - ThunderLAN Driver MII Routines +ThunderLAN driver MII routines - These routines are based on the information in Chap. 2 of the - "ThunderLAN Programmer's Guide", pp. 15-24. +these routines are based on the information in chap. 2 of the +"ThunderLAN Programmer's Guide", pp. 15-24. ****************************************************************************** *****************************************************************************/ - /*************************************************************** - * TLan_MiiReadReg - * - * Returns: - * false if ack received ok - * true if no ack received or other error - * - * Parms: - * dev The device structure containing - * The io address and interrupt count - * for this device. - * phy The address of the PHY to be queried. - * reg The register whose contents are to be - * retrieved. - * val A pointer to a variable to store the - * retrieved value. - * - * This function uses the TLAN's MII bus to retrieve the contents - * of a given register on a PHY. It sends the appropriate info - * and then reads the 16-bit register value from the MII bus via - * the TLAN SIO register. - * - **************************************************************/ - -static bool TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val ) +/*************************************************************** + * tlan_mii_read_reg + * + * Returns: + * false if ack received ok + * true if no ack received or other error + * + * Parms: + * dev The device structure containing + * The io address and interrupt count + * for this device. + * phy The address of the PHY to be queried. + * reg The register whose contents are to be + * retrieved. + * val A pointer to a variable to store the + * retrieved value. + * + * This function uses the TLAN's MII bus to retrieve the contents + * of a given register on a PHY. It sends the appropriate info + * and then reads the 16-bit register value from the MII bus via + * the TLAN SIO register. + * + **************************************************************/ + +static bool +tlan_mii_read_reg(struct net_device *dev, u16 phy, u16 reg, u16 *val) { u8 nack; u16 sio, tmp; - u32 i; + u32 i; bool err; int minten; - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); unsigned long flags = 0; err = false; @@ -2892,48 +2929,48 @@ static bool TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val if (!in_irq()) spin_lock_irqsave(&priv->lock, flags); - TLan_MiiSync(dev->base_addr); + tlan_mii_sync(dev->base_addr); - minten = TLan_GetBit( TLAN_NET_SIO_MINTEN, sio ); - if ( minten ) - TLan_ClearBit(TLAN_NET_SIO_MINTEN, sio); + minten = tlan_get_bit(TLAN_NET_SIO_MINTEN, sio); + if (minten) + tlan_clear_bit(TLAN_NET_SIO_MINTEN, sio); - TLan_MiiSendData( dev->base_addr, 0x1, 2 ); /* Start ( 01b ) */ - TLan_MiiSendData( dev->base_addr, 0x2, 2 ); /* Read ( 10b ) */ - TLan_MiiSendData( dev->base_addr, phy, 5 ); /* Device # */ - TLan_MiiSendData( dev->base_addr, reg, 5 ); /* Register # */ + tlan_mii_send_data(dev->base_addr, 0x1, 2); /* start (01b) */ + tlan_mii_send_data(dev->base_addr, 0x2, 2); /* read (10b) */ + tlan_mii_send_data(dev->base_addr, phy, 5); /* device # */ + tlan_mii_send_data(dev->base_addr, reg, 5); /* register # */ - TLan_ClearBit(TLAN_NET_SIO_MTXEN, sio); /* Change direction */ + tlan_clear_bit(TLAN_NET_SIO_MTXEN, sio); /* change direction */ - TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Clock Idle bit */ - TLan_SetBit(TLAN_NET_SIO_MCLK, sio); - TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Wait 300ns */ + tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* clock idle bit */ + tlan_set_bit(TLAN_NET_SIO_MCLK, sio); + tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* wait 300ns */ - nack = TLan_GetBit(TLAN_NET_SIO_MDATA, sio); /* Check for ACK */ - TLan_SetBit(TLAN_NET_SIO_MCLK, sio); /* Finish ACK */ - if (nack) { /* No ACK, so fake it */ + nack = tlan_get_bit(TLAN_NET_SIO_MDATA, sio); /* check for ACK */ + tlan_set_bit(TLAN_NET_SIO_MCLK, sio); /* finish ACK */ + if (nack) { /* no ACK, so fake it */ for (i = 0; i < 16; i++) { - TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); - TLan_SetBit(TLAN_NET_SIO_MCLK, sio); + tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); + tlan_set_bit(TLAN_NET_SIO_MCLK, sio); } tmp = 0xffff; err = true; } else { /* ACK, so read data */ for (tmp = 0, i = 0x8000; i; i >>= 1) { - TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); - if (TLan_GetBit(TLAN_NET_SIO_MDATA, sio)) + tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); + if (tlan_get_bit(TLAN_NET_SIO_MDATA, sio)) tmp |= i; - TLan_SetBit(TLAN_NET_SIO_MCLK, sio); + tlan_set_bit(TLAN_NET_SIO_MCLK, sio); } } - TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Idle cycle */ - TLan_SetBit(TLAN_NET_SIO_MCLK, sio); + tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* idle cycle */ + tlan_set_bit(TLAN_NET_SIO_MCLK, sio); - if ( minten ) - TLan_SetBit(TLAN_NET_SIO_MINTEN, sio); + if (minten) + tlan_set_bit(TLAN_NET_SIO_MINTEN, sio); *val = tmp; @@ -2942,116 +2979,117 @@ static bool TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val return err; -} /* TLan_MiiReadReg */ +} - /*************************************************************** - * TLan_MiiSendData - * - * Returns: - * Nothing - * Parms: - * base_port The base IO port of the adapter in - * question. - * dev The address of the PHY to be queried. - * data The value to be placed on the MII bus. - * num_bits The number of bits in data that are to - * be placed on the MII bus. - * - * This function sends on sequence of bits on the MII - * configuration bus. - * - **************************************************************/ +/*************************************************************** + * tlan_mii_send_data + * + * Returns: + * Nothing + * Parms: + * base_port The base IO port of the adapter in + * question. + * dev The address of the PHY to be queried. + * data The value to be placed on the MII bus. + * num_bits The number of bits in data that are to + * be placed on the MII bus. + * + * This function sends on sequence of bits on the MII + * configuration bus. + * + **************************************************************/ -static void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits ) +static void tlan_mii_send_data(u16 base_port, u32 data, unsigned num_bits) { u16 sio; u32 i; - if ( num_bits == 0 ) + if (num_bits == 0) return; - outw( TLAN_NET_SIO, base_port + TLAN_DIO_ADR ); + outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR); sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO; - TLan_SetBit( TLAN_NET_SIO_MTXEN, sio ); + tlan_set_bit(TLAN_NET_SIO_MTXEN, sio); - for ( i = ( 0x1 << ( num_bits - 1 ) ); i; i >>= 1 ) { - TLan_ClearBit( TLAN_NET_SIO_MCLK, sio ); - (void) TLan_GetBit( TLAN_NET_SIO_MCLK, sio ); - if ( data & i ) - TLan_SetBit( TLAN_NET_SIO_MDATA, sio ); + for (i = (0x1 << (num_bits - 1)); i; i >>= 1) { + tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); + (void) tlan_get_bit(TLAN_NET_SIO_MCLK, sio); + if (data & i) + tlan_set_bit(TLAN_NET_SIO_MDATA, sio); else - TLan_ClearBit( TLAN_NET_SIO_MDATA, sio ); - TLan_SetBit( TLAN_NET_SIO_MCLK, sio ); - (void) TLan_GetBit( TLAN_NET_SIO_MCLK, sio ); + tlan_clear_bit(TLAN_NET_SIO_MDATA, sio); + tlan_set_bit(TLAN_NET_SIO_MCLK, sio); + (void) tlan_get_bit(TLAN_NET_SIO_MCLK, sio); } -} /* TLan_MiiSendData */ +} - /*************************************************************** - * TLan_MiiSync - * - * Returns: - * Nothing - * Parms: - * base_port The base IO port of the adapter in - * question. - * - * This functions syncs all PHYs in terms of the MII configuration - * bus. - * - **************************************************************/ +/*************************************************************** + * TLan_MiiSync + * + * Returns: + * Nothing + * Parms: + * base_port The base IO port of the adapter in + * question. + * + * This functions syncs all PHYs in terms of the MII configuration + * bus. + * + **************************************************************/ -static void TLan_MiiSync( u16 base_port ) +static void tlan_mii_sync(u16 base_port) { int i; u16 sio; - outw( TLAN_NET_SIO, base_port + TLAN_DIO_ADR ); + outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR); sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO; - TLan_ClearBit( TLAN_NET_SIO_MTXEN, sio ); - for ( i = 0; i < 32; i++ ) { - TLan_ClearBit( TLAN_NET_SIO_MCLK, sio ); - TLan_SetBit( TLAN_NET_SIO_MCLK, sio ); + tlan_clear_bit(TLAN_NET_SIO_MTXEN, sio); + for (i = 0; i < 32; i++) { + tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); + tlan_set_bit(TLAN_NET_SIO_MCLK, sio); } -} /* TLan_MiiSync */ +} - /*************************************************************** - * TLan_MiiWriteReg - * - * Returns: - * Nothing - * Parms: - * dev The device structure for the device - * to write to. - * phy The address of the PHY to be written to. - * reg The register whose contents are to be - * written. - * val The value to be written to the register. - * - * This function uses the TLAN's MII bus to write the contents of a - * given register on a PHY. It sends the appropriate info and then - * writes the 16-bit register value from the MII configuration bus - * via the TLAN SIO register. - * - **************************************************************/ +/*************************************************************** + * tlan_mii_write_reg + * + * Returns: + * Nothing + * Parms: + * dev The device structure for the device + * to write to. + * phy The address of the PHY to be written to. + * reg The register whose contents are to be + * written. + * val The value to be written to the register. + * + * This function uses the TLAN's MII bus to write the contents of a + * given register on a PHY. It sends the appropriate info and then + * writes the 16-bit register value from the MII configuration bus + * via the TLAN SIO register. + * + **************************************************************/ -static void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val ) +static void +tlan_mii_write_reg(struct net_device *dev, u16 phy, u16 reg, u16 val) { u16 sio; int minten; unsigned long flags = 0; - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR); sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO; @@ -3059,30 +3097,30 @@ static void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val if (!in_irq()) spin_lock_irqsave(&priv->lock, flags); - TLan_MiiSync( dev->base_addr ); + tlan_mii_sync(dev->base_addr); - minten = TLan_GetBit( TLAN_NET_SIO_MINTEN, sio ); - if ( minten ) - TLan_ClearBit( TLAN_NET_SIO_MINTEN, sio ); + minten = tlan_get_bit(TLAN_NET_SIO_MINTEN, sio); + if (minten) + tlan_clear_bit(TLAN_NET_SIO_MINTEN, sio); - TLan_MiiSendData( dev->base_addr, 0x1, 2 ); /* Start ( 01b ) */ - TLan_MiiSendData( dev->base_addr, 0x1, 2 ); /* Write ( 01b ) */ - TLan_MiiSendData( dev->base_addr, phy, 5 ); /* Device # */ - TLan_MiiSendData( dev->base_addr, reg, 5 ); /* Register # */ + tlan_mii_send_data(dev->base_addr, 0x1, 2); /* start (01b) */ + tlan_mii_send_data(dev->base_addr, 0x1, 2); /* write (01b) */ + tlan_mii_send_data(dev->base_addr, phy, 5); /* device # */ + tlan_mii_send_data(dev->base_addr, reg, 5); /* register # */ - TLan_MiiSendData( dev->base_addr, 0x2, 2 ); /* Send ACK */ - TLan_MiiSendData( dev->base_addr, val, 16 ); /* Send Data */ + tlan_mii_send_data(dev->base_addr, 0x2, 2); /* send ACK */ + tlan_mii_send_data(dev->base_addr, val, 16); /* send data */ - TLan_ClearBit( TLAN_NET_SIO_MCLK, sio ); /* Idle cycle */ - TLan_SetBit( TLAN_NET_SIO_MCLK, sio ); + tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* idle cycle */ + tlan_set_bit(TLAN_NET_SIO_MCLK, sio); - if ( minten ) - TLan_SetBit( TLAN_NET_SIO_MINTEN, sio ); + if (minten) + tlan_set_bit(TLAN_NET_SIO_MINTEN, sio); if (!in_irq()) spin_unlock_irqrestore(&priv->lock, flags); -} /* TLan_MiiWriteReg */ +} @@ -3090,229 +3128,226 @@ static void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val /***************************************************************************** ****************************************************************************** - ThunderLAN Driver Eeprom routines +ThunderLAN driver eeprom routines - The Compaq Netelligent 10 and 10/100 cards use a Microchip 24C02A - EEPROM. These functions are based on information in Microchip's - data sheet. I don't know how well this functions will work with - other EEPROMs. +the Compaq netelligent 10 and 10/100 cards use a microchip 24C02A +EEPROM. these functions are based on information in microchip's +data sheet. I don't know how well this functions will work with +other Eeproms. ****************************************************************************** *****************************************************************************/ - /*************************************************************** - * TLan_EeSendStart - * - * Returns: - * Nothing - * Parms: - * io_base The IO port base address for the - * TLAN device with the EEPROM to - * use. - * - * This function sends a start cycle to an EEPROM attached - * to a TLAN chip. - * - **************************************************************/ - -static void TLan_EeSendStart( u16 io_base ) +/*************************************************************** + * tlan_ee_send_start + * + * Returns: + * Nothing + * Parms: + * io_base The IO port base address for the + * TLAN device with the EEPROM to + * use. + * + * This function sends a start cycle to an EEPROM attached + * to a TLAN chip. + * + **************************************************************/ + +static void tlan_ee_send_start(u16 io_base) { u16 sio; - outw( TLAN_NET_SIO, io_base + TLAN_DIO_ADR ); + outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR); sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO; - TLan_SetBit( TLAN_NET_SIO_ECLOK, sio ); - TLan_SetBit( TLAN_NET_SIO_EDATA, sio ); - TLan_SetBit( TLAN_NET_SIO_ETXEN, sio ); - TLan_ClearBit( TLAN_NET_SIO_EDATA, sio ); - TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio ); - -} /* TLan_EeSendStart */ - - - - - /*************************************************************** - * TLan_EeSendByte - * - * Returns: - * If the correct ack was received, 0, otherwise 1 - * Parms: io_base The IO port base address for the - * TLAN device with the EEPROM to - * use. - * data The 8 bits of information to - * send to the EEPROM. - * stop If TLAN_EEPROM_STOP is passed, a - * stop cycle is sent after the - * byte is sent after the ack is - * read. - * - * This function sends a byte on the serial EEPROM line, - * driving the clock to send each bit. The function then - * reverses transmission direction and reads an acknowledge - * bit. - * - **************************************************************/ - -static int TLan_EeSendByte( u16 io_base, u8 data, int stop ) + tlan_set_bit(TLAN_NET_SIO_ECLOK, sio); + tlan_set_bit(TLAN_NET_SIO_EDATA, sio); + tlan_set_bit(TLAN_NET_SIO_ETXEN, sio); + tlan_clear_bit(TLAN_NET_SIO_EDATA, sio); + tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio); + +} + + + + +/*************************************************************** + * tlan_ee_send_byte + * + * Returns: + * If the correct ack was received, 0, otherwise 1 + * Parms: io_base The IO port base address for the + * TLAN device with the EEPROM to + * use. + * data The 8 bits of information to + * send to the EEPROM. + * stop If TLAN_EEPROM_STOP is passed, a + * stop cycle is sent after the + * byte is sent after the ack is + * read. + * + * This function sends a byte on the serial EEPROM line, + * driving the clock to send each bit. The function then + * reverses transmission direction and reads an acknowledge + * bit. + * + **************************************************************/ + +static int tlan_ee_send_byte(u16 io_base, u8 data, int stop) { int err; u8 place; u16 sio; - outw( TLAN_NET_SIO, io_base + TLAN_DIO_ADR ); + outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR); sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO; /* Assume clock is low, tx is enabled; */ - for ( place = 0x80; place != 0; place >>= 1 ) { - if ( place & data ) - TLan_SetBit( TLAN_NET_SIO_EDATA, sio ); + for (place = 0x80; place != 0; place >>= 1) { + if (place & data) + tlan_set_bit(TLAN_NET_SIO_EDATA, sio); else - TLan_ClearBit( TLAN_NET_SIO_EDATA, sio ); - TLan_SetBit( TLAN_NET_SIO_ECLOK, sio ); - TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio ); + tlan_clear_bit(TLAN_NET_SIO_EDATA, sio); + tlan_set_bit(TLAN_NET_SIO_ECLOK, sio); + tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio); } - TLan_ClearBit( TLAN_NET_SIO_ETXEN, sio ); - TLan_SetBit( TLAN_NET_SIO_ECLOK, sio ); - err = TLan_GetBit( TLAN_NET_SIO_EDATA, sio ); - TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio ); - TLan_SetBit( TLAN_NET_SIO_ETXEN, sio ); + tlan_clear_bit(TLAN_NET_SIO_ETXEN, sio); + tlan_set_bit(TLAN_NET_SIO_ECLOK, sio); + err = tlan_get_bit(TLAN_NET_SIO_EDATA, sio); + tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio); + tlan_set_bit(TLAN_NET_SIO_ETXEN, sio); - if ( ( ! err ) && stop ) { + if ((!err) && stop) { /* STOP, raise data while clock is high */ - TLan_ClearBit( TLAN_NET_SIO_EDATA, sio ); - TLan_SetBit( TLAN_NET_SIO_ECLOK, sio ); - TLan_SetBit( TLAN_NET_SIO_EDATA, sio ); + tlan_clear_bit(TLAN_NET_SIO_EDATA, sio); + tlan_set_bit(TLAN_NET_SIO_ECLOK, sio); + tlan_set_bit(TLAN_NET_SIO_EDATA, sio); } return err; -} /* TLan_EeSendByte */ - - - - - /*************************************************************** - * TLan_EeReceiveByte - * - * Returns: - * Nothing - * Parms: - * io_base The IO port base address for the - * TLAN device with the EEPROM to - * use. - * data An address to a char to hold the - * data sent from the EEPROM. - * stop If TLAN_EEPROM_STOP is passed, a - * stop cycle is sent after the - * byte is received, and no ack is - * sent. - * - * This function receives 8 bits of data from the EEPROM - * over the serial link. It then sends and ack bit, or no - * ack and a stop bit. This function is used to retrieve - * data after the address of a byte in the EEPROM has been - * sent. - * - **************************************************************/ - -static void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop ) +} + + + + +/*************************************************************** + * tlan_ee_receive_byte + * + * Returns: + * Nothing + * Parms: + * io_base The IO port base address for the + * TLAN device with the EEPROM to + * use. + * data An address to a char to hold the + * data sent from the EEPROM. + * stop If TLAN_EEPROM_STOP is passed, a + * stop cycle is sent after the + * byte is received, and no ack is + * sent. + * + * This function receives 8 bits of data from the EEPROM + * over the serial link. It then sends and ack bit, or no + * ack and a stop bit. This function is used to retrieve + * data after the address of a byte in the EEPROM has been + * sent. + * + **************************************************************/ + +static void tlan_ee_receive_byte(u16 io_base, u8 *data, int stop) { u8 place; u16 sio; - outw( TLAN_NET_SIO, io_base + TLAN_DIO_ADR ); + outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR); sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO; *data = 0; /* Assume clock is low, tx is enabled; */ - TLan_ClearBit( TLAN_NET_SIO_ETXEN, sio ); - for ( place = 0x80; place; place >>= 1 ) { - TLan_SetBit( TLAN_NET_SIO_ECLOK, sio ); - if ( TLan_GetBit( TLAN_NET_SIO_EDATA, sio ) ) + tlan_clear_bit(TLAN_NET_SIO_ETXEN, sio); + for (place = 0x80; place; place >>= 1) { + tlan_set_bit(TLAN_NET_SIO_ECLOK, sio); + if (tlan_get_bit(TLAN_NET_SIO_EDATA, sio)) *data |= place; - TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio ); + tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio); } - TLan_SetBit( TLAN_NET_SIO_ETXEN, sio ); - if ( ! stop ) { - TLan_ClearBit( TLAN_NET_SIO_EDATA, sio ); /* Ack = 0 */ - TLan_SetBit( TLAN_NET_SIO_ECLOK, sio ); - TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio ); + tlan_set_bit(TLAN_NET_SIO_ETXEN, sio); + if (!stop) { + tlan_clear_bit(TLAN_NET_SIO_EDATA, sio); /* ack = 0 */ + tlan_set_bit(TLAN_NET_SIO_ECLOK, sio); + tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio); } else { - TLan_SetBit( TLAN_NET_SIO_EDATA, sio ); /* No ack = 1 (?) */ - TLan_SetBit( TLAN_NET_SIO_ECLOK, sio ); - TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio ); + tlan_set_bit(TLAN_NET_SIO_EDATA, sio); /* no ack = 1 (?) */ + tlan_set_bit(TLAN_NET_SIO_ECLOK, sio); + tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio); /* STOP, raise data while clock is high */ - TLan_ClearBit( TLAN_NET_SIO_EDATA, sio ); - TLan_SetBit( TLAN_NET_SIO_ECLOK, sio ); - TLan_SetBit( TLAN_NET_SIO_EDATA, sio ); - } - -} /* TLan_EeReceiveByte */ - - - - - /*************************************************************** - * TLan_EeReadByte - * - * Returns: - * No error = 0, else, the stage at which the error - * occurred. - * Parms: - * io_base The IO port base address for the - * TLAN device with the EEPROM to - * use. - * ee_addr The address of the byte in the - * EEPROM whose contents are to be - * retrieved. - * data An address to a char to hold the - * data obtained from the EEPROM. - * - * This function reads a byte of information from an byte - * cell in the EEPROM. - * - **************************************************************/ - -static int TLan_EeReadByte( struct net_device *dev, u8 ee_addr, u8 *data ) + tlan_clear_bit(TLAN_NET_SIO_EDATA, sio); + tlan_set_bit(TLAN_NET_SIO_ECLOK, sio); + tlan_set_bit(TLAN_NET_SIO_EDATA, sio); + } + +} + + + + +/*************************************************************** + * tlan_ee_read_byte + * + * Returns: + * No error = 0, else, the stage at which the error + * occurred. + * Parms: + * io_base The IO port base address for the + * TLAN device with the EEPROM to + * use. + * ee_addr The address of the byte in the + * EEPROM whose contents are to be + * retrieved. + * data An address to a char to hold the + * data obtained from the EEPROM. + * + * This function reads a byte of information from an byte + * cell in the EEPROM. + * + **************************************************************/ + +static int tlan_ee_read_byte(struct net_device *dev, u8 ee_addr, u8 *data) { int err; - TLanPrivateInfo *priv = netdev_priv(dev); + struct tlan_priv *priv = netdev_priv(dev); unsigned long flags = 0; - int ret=0; + int ret = 0; spin_lock_irqsave(&priv->lock, flags); - TLan_EeSendStart( dev->base_addr ); - err = TLan_EeSendByte( dev->base_addr, 0xA0, TLAN_EEPROM_ACK ); - if (err) - { - ret=1; + tlan_ee_send_start(dev->base_addr); + err = tlan_ee_send_byte(dev->base_addr, 0xa0, TLAN_EEPROM_ACK); + if (err) { + ret = 1; goto fail; } - err = TLan_EeSendByte( dev->base_addr, ee_addr, TLAN_EEPROM_ACK ); - if (err) - { - ret=2; + err = tlan_ee_send_byte(dev->base_addr, ee_addr, TLAN_EEPROM_ACK); + if (err) { + ret = 2; goto fail; } - TLan_EeSendStart( dev->base_addr ); - err = TLan_EeSendByte( dev->base_addr, 0xA1, TLAN_EEPROM_ACK ); - if (err) - { - ret=3; + tlan_ee_send_start(dev->base_addr); + err = tlan_ee_send_byte(dev->base_addr, 0xa1, TLAN_EEPROM_ACK); + if (err) { + ret = 3; goto fail; } - TLan_EeReceiveByte( dev->base_addr, data, TLAN_EEPROM_STOP ); + tlan_ee_receive_byte(dev->base_addr, data, TLAN_EEPROM_STOP); fail: spin_unlock_irqrestore(&priv->lock, flags); return ret; -} /* TLan_EeReadByte */ +} diff --git a/drivers/net/tlan.h b/drivers/net/tlan.h index 3315ced774e2..5fc98a8e4889 100644 --- a/drivers/net/tlan.h +++ b/drivers/net/tlan.h @@ -20,8 +20,8 @@ ********************************************************************/ -#include -#include +#include +#include #include @@ -40,8 +40,11 @@ #define TLAN_IGNORE 0 #define TLAN_RECORD 1 -#define TLAN_DBG(lvl, format, args...) \ - do { if (debug&lvl) printk(KERN_DEBUG "TLAN: " format, ##args ); } while(0) +#define TLAN_DBG(lvl, format, args...) \ + do { \ + if (debug&lvl) \ + printk(KERN_DEBUG "TLAN: " format, ##args); \ + } while (0) #define TLAN_DEBUG_GNRL 0x0001 #define TLAN_DEBUG_TX 0x0002 @@ -50,7 +53,8 @@ #define TLAN_DEBUG_PROBE 0x0010 #define TX_TIMEOUT (10*HZ) /* We need time for auto-neg */ -#define MAX_TLAN_BOARDS 8 /* Max number of boards installed at a time */ +#define MAX_TLAN_BOARDS 8 /* Max number of boards installed + at a time */ /***************************************************************** @@ -70,13 +74,13 @@ #define PCI_DEVICE_ID_OLICOM_OC2326 0x0014 #endif -typedef struct tlan_adapter_entry { - u16 vendorId; - u16 deviceId; - char *deviceLabel; +struct tlan_adapter_entry { + u16 vendor_id; + u16 device_id; + char *device_label; u32 flags; - u16 addrOfs; -} TLanAdapterEntry; + u16 addr_ofs; +}; #define TLAN_ADAPTER_NONE 0x00000000 #define TLAN_ADAPTER_UNMANAGED_PHY 0x00000001 @@ -129,18 +133,18 @@ typedef struct tlan_adapter_entry { #define TLAN_CSTAT_DP_PR 0x0100 -typedef struct tlan_buffer_ref_tag { +struct tlan_buffer { u32 count; u32 address; -} TLanBufferRef; +}; -typedef struct tlan_list_tag { +struct tlan_list { u32 forward; - u16 cStat; - u16 frameSize; - TLanBufferRef buffer[TLAN_BUFFERS_PER_LIST]; -} TLanList; + u16 c_stat; + u16 frame_size; + struct tlan_buffer buffer[TLAN_BUFFERS_PER_LIST]; +}; typedef u8 TLanBuffer[TLAN_MAX_FRAME_SIZE]; @@ -164,49 +168,49 @@ typedef u8 TLanBuffer[TLAN_MAX_FRAME_SIZE]; * ****************************************************************/ -typedef struct tlan_private_tag { - struct net_device *nextDevice; - struct pci_dev *pciDev; +struct tlan_priv { + struct net_device *next_device; + struct pci_dev *pci_dev; struct net_device *dev; - void *dmaStorage; - dma_addr_t dmaStorageDMA; - unsigned int dmaSize; - u8 *padBuffer; - TLanList *rxList; - dma_addr_t rxListDMA; - u8 *rxBuffer; - dma_addr_t rxBufferDMA; - u32 rxHead; - u32 rxTail; - u32 rxEocCount; - TLanList *txList; - dma_addr_t txListDMA; - u8 *txBuffer; - dma_addr_t txBufferDMA; - u32 txHead; - u32 txInProgress; - u32 txTail; - u32 txBusyCount; - u32 phyOnline; - u32 timerSetAt; - u32 timerType; + void *dma_storage; + dma_addr_t dma_storage_dma; + unsigned int dma_size; + u8 *pad_buffer; + struct tlan_list *rx_list; + dma_addr_t rx_list_dma; + u8 *rx_buffer; + dma_addr_t rx_buffer_dma; + u32 rx_head; + u32 rx_tail; + u32 rx_eoc_count; + struct tlan_list *tx_list; + dma_addr_t tx_list_dma; + u8 *tx_buffer; + dma_addr_t tx_buffer_dma; + u32 tx_head; + u32 tx_in_progress; + u32 tx_tail; + u32 tx_busy_count; + u32 phy_online; + u32 timer_set_at; + u32 timer_type; struct timer_list timer; struct board *adapter; - u32 adapterRev; + u32 adapter_rev; u32 aui; u32 debug; u32 duplex; u32 phy[2]; - u32 phyNum; + u32 phy_num; u32 speed; - u8 tlanRev; - u8 tlanFullDuplex; + u8 tlan_rev; + u8 tlan_full_duplex; spinlock_t lock; u8 link; u8 is_eisa; struct work_struct tlan_tqueue; u8 neg_be_verbose; -} TLanPrivateInfo; +}; @@ -247,7 +251,7 @@ typedef struct tlan_private_tag { ****************************************************************/ #define TLAN_HOST_CMD 0x00 -#define TLAN_HC_GO 0x80000000 +#define TLAN_HC_GO 0x80000000 #define TLAN_HC_STOP 0x40000000 #define TLAN_HC_ACK 0x20000000 #define TLAN_HC_CS_MASK 0x1FE00000 @@ -283,7 +287,7 @@ typedef struct tlan_private_tag { #define TLAN_NET_CMD_TRFRAM 0x02 #define TLAN_NET_CMD_TXPACE 0x01 #define TLAN_NET_SIO 0x01 -#define TLAN_NET_SIO_MINTEN 0x80 +#define TLAN_NET_SIO_MINTEN 0x80 #define TLAN_NET_SIO_ECLOK 0x40 #define TLAN_NET_SIO_ETXEN 0x20 #define TLAN_NET_SIO_EDATA 0x10 @@ -304,7 +308,7 @@ typedef struct tlan_private_tag { #define TLAN_NET_MASK_MASK4 0x10 #define TLAN_NET_MASK_RSRVD 0x0F #define TLAN_NET_CONFIG 0x04 -#define TLAN_NET_CFG_RCLK 0x8000 +#define TLAN_NET_CFG_RCLK 0x8000 #define TLAN_NET_CFG_TCLK 0x4000 #define TLAN_NET_CFG_BIT 0x2000 #define TLAN_NET_CFG_RXCRC 0x1000 @@ -372,7 +376,7 @@ typedef struct tlan_private_tag { /* Generic MII/PHY Registers */ #define MII_GEN_CTL 0x00 -#define MII_GC_RESET 0x8000 +#define MII_GC_RESET 0x8000 #define MII_GC_LOOPBK 0x4000 #define MII_GC_SPEEDSEL 0x2000 #define MII_GC_AUTOENB 0x1000 @@ -397,9 +401,9 @@ typedef struct tlan_private_tag { #define MII_GS_EXTCAP 0x0001 #define MII_GEN_ID_HI 0x02 #define MII_GEN_ID_LO 0x03 -#define MII_GIL_OUI 0xFC00 -#define MII_GIL_MODEL 0x03F0 -#define MII_GIL_REVISION 0x000F +#define MII_GIL_OUI 0xFC00 +#define MII_GIL_MODEL 0x03F0 +#define MII_GIL_REVISION 0x000F #define MII_AN_ADV 0x04 #define MII_AN_LPA 0x05 #define MII_AN_EXP 0x06 @@ -408,7 +412,7 @@ typedef struct tlan_private_tag { #define TLAN_TLPHY_ID 0x10 #define TLAN_TLPHY_CTL 0x11 -#define TLAN_TC_IGLINK 0x8000 +#define TLAN_TC_IGLINK 0x8000 #define TLAN_TC_SWAPOL 0x4000 #define TLAN_TC_AUISEL 0x2000 #define TLAN_TC_SQEEN 0x1000 @@ -435,41 +439,41 @@ typedef struct tlan_private_tag { #define LEVEL1_ID1 0x7810 #define LEVEL1_ID2 0x0000 -#define CIRC_INC( a, b ) if ( ++a >= b ) a = 0 +#define CIRC_INC(a, b) if (++a >= b) a = 0 /* Routines to access internal registers. */ -static inline u8 TLan_DioRead8(u16 base_addr, u16 internal_addr) +static inline u8 tlan_dio_read8(u16 base_addr, u16 internal_addr) { outw(internal_addr, base_addr + TLAN_DIO_ADR); return inb((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x3)); -} /* TLan_DioRead8 */ +} -static inline u16 TLan_DioRead16(u16 base_addr, u16 internal_addr) +static inline u16 tlan_dio_read16(u16 base_addr, u16 internal_addr) { outw(internal_addr, base_addr + TLAN_DIO_ADR); return inw((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x2)); -} /* TLan_DioRead16 */ +} -static inline u32 TLan_DioRead32(u16 base_addr, u16 internal_addr) +static inline u32 tlan_dio_read32(u16 base_addr, u16 internal_addr) { outw(internal_addr, base_addr + TLAN_DIO_ADR); return inl(base_addr + TLAN_DIO_DATA); -} /* TLan_DioRead32 */ +} -static inline void TLan_DioWrite8(u16 base_addr, u16 internal_addr, u8 data) +static inline void tlan_dio_write8(u16 base_addr, u16 internal_addr, u8 data) { outw(internal_addr, base_addr + TLAN_DIO_ADR); outb(data, base_addr + TLAN_DIO_DATA + (internal_addr & 0x3)); @@ -479,7 +483,7 @@ static inline void TLan_DioWrite8(u16 base_addr, u16 internal_addr, u8 data) -static inline void TLan_DioWrite16(u16 base_addr, u16 internal_addr, u16 data) +static inline void tlan_dio_write16(u16 base_addr, u16 internal_addr, u16 data) { outw(internal_addr, base_addr + TLAN_DIO_ADR); outw(data, base_addr + TLAN_DIO_DATA + (internal_addr & 0x2)); @@ -489,16 +493,16 @@ static inline void TLan_DioWrite16(u16 base_addr, u16 internal_addr, u16 data) -static inline void TLan_DioWrite32(u16 base_addr, u16 internal_addr, u32 data) +static inline void tlan_dio_write32(u16 base_addr, u16 internal_addr, u32 data) { outw(internal_addr, base_addr + TLAN_DIO_ADR); outl(data, base_addr + TLAN_DIO_DATA + (internal_addr & 0x2)); } -#define TLan_ClearBit( bit, port ) outb_p(inb_p(port) & ~bit, port) -#define TLan_GetBit( bit, port ) ((int) (inb_p(port) & bit)) -#define TLan_SetBit( bit, port ) outb_p(inb_p(port) | bit, port) +#define tlan_clear_bit(bit, port) outb_p(inb_p(port) & ~bit, port) +#define tlan_get_bit(bit, port) ((int) (inb_p(port) & bit)) +#define tlan_set_bit(bit, port) outb_p(inb_p(port) | bit, port) /* * given 6 bytes, view them as 8 6-bit numbers and return the XOR of those @@ -506,37 +510,37 @@ static inline void TLan_DioWrite32(u16 base_addr, u16 internal_addr, u32 data) * * The original code was: * - * u32 xor( u32 a, u32 b ) { return ( ( a && ! b ) || ( ! a && b ) ); } + * u32 xor(u32 a, u32 b) { return ((a && !b ) || (! a && b )); } * - * #define XOR8( a, b, c, d, e, f, g, h ) \ - * xor( a, xor( b, xor( c, xor( d, xor( e, xor( f, xor( g, h ) ) ) ) ) ) ) - * #define DA( a, bit ) ( ( (u8) a[bit/8] ) & ( (u8) ( 1 << bit%8 ) ) ) + * #define XOR8(a, b, c, d, e, f, g, h) \ + * xor(a, xor(b, xor(c, xor(d, xor(e, xor(f, xor(g, h)) ) ) ) ) ) + * #define DA(a, bit) (( (u8) a[bit/8] ) & ( (u8) (1 << bit%8)) ) * - * hash = XOR8( DA(a,0), DA(a, 6), DA(a,12), DA(a,18), DA(a,24), - * DA(a,30), DA(a,36), DA(a,42) ); - * hash |= XOR8( DA(a,1), DA(a, 7), DA(a,13), DA(a,19), DA(a,25), - * DA(a,31), DA(a,37), DA(a,43) ) << 1; - * hash |= XOR8( DA(a,2), DA(a, 8), DA(a,14), DA(a,20), DA(a,26), - * DA(a,32), DA(a,38), DA(a,44) ) << 2; - * hash |= XOR8( DA(a,3), DA(a, 9), DA(a,15), DA(a,21), DA(a,27), - * DA(a,33), DA(a,39), DA(a,45) ) << 3; - * hash |= XOR8( DA(a,4), DA(a,10), DA(a,16), DA(a,22), DA(a,28), - * DA(a,34), DA(a,40), DA(a,46) ) << 4; - * hash |= XOR8( DA(a,5), DA(a,11), DA(a,17), DA(a,23), DA(a,29), - * DA(a,35), DA(a,41), DA(a,47) ) << 5; + * hash = XOR8(DA(a,0), DA(a, 6), DA(a,12), DA(a,18), DA(a,24), + * DA(a,30), DA(a,36), DA(a,42)); + * hash |= XOR8(DA(a,1), DA(a, 7), DA(a,13), DA(a,19), DA(a,25), + * DA(a,31), DA(a,37), DA(a,43)) << 1; + * hash |= XOR8(DA(a,2), DA(a, 8), DA(a,14), DA(a,20), DA(a,26), + * DA(a,32), DA(a,38), DA(a,44)) << 2; + * hash |= XOR8(DA(a,3), DA(a, 9), DA(a,15), DA(a,21), DA(a,27), + * DA(a,33), DA(a,39), DA(a,45)) << 3; + * hash |= XOR8(DA(a,4), DA(a,10), DA(a,16), DA(a,22), DA(a,28), + * DA(a,34), DA(a,40), DA(a,46)) << 4; + * hash |= XOR8(DA(a,5), DA(a,11), DA(a,17), DA(a,23), DA(a,29), + * DA(a,35), DA(a,41), DA(a,47)) << 5; * */ -static inline u32 TLan_HashFunc( const u8 *a ) +static inline u32 tlan_hash_func(const u8 *a) { - u8 hash; + u8 hash; - hash = (a[0]^a[3]); /* & 077 */ - hash ^= ((a[0]^a[3])>>6); /* & 003 */ - hash ^= ((a[1]^a[4])<<2); /* & 074 */ - hash ^= ((a[1]^a[4])>>4); /* & 017 */ - hash ^= ((a[2]^a[5])<<4); /* & 060 */ - hash ^= ((a[2]^a[5])>>2); /* & 077 */ + hash = (a[0]^a[3]); /* & 077 */ + hash ^= ((a[0]^a[3])>>6); /* & 003 */ + hash ^= ((a[1]^a[4])<<2); /* & 074 */ + hash ^= ((a[1]^a[4])>>4); /* & 017 */ + hash ^= ((a[2]^a[5])<<4); /* & 060 */ + hash ^= ((a[2]^a[5])>>2); /* & 077 */ - return hash & 077; + return hash & 077; } #endif -- cgit v1.2.3 From fa6d5d4f2b0df1e9b613b7b5926805b8a4306d44 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 21 Jan 2011 10:59:31 +0000 Subject: tlan: add suspend/resume support Add suspend/resume support to tlan driver. This allows not unloading the driver over suspend/resume. Also, start (or now, wake) the queue after resetting the adapter --- not the other way around. Signed-off-by: Sakari Ailus Signed-off-by: David S. Miller --- drivers/net/tlan.c | 88 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index 57380b1b3b60..0678e7e71f19 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -168,6 +168,7 @@ * * v1.15a Dec 15 2008 - Remove bbuf support, it doesn't work anyway. * v1.16 Jan 6 2011 - Make checkpatch.pl happy. + * v1.17 Jan 6 2011 - Add suspend/resume support. * ******************************************************************************/ @@ -219,7 +220,7 @@ module_param(debug, int, 0); MODULE_PARM_DESC(debug, "ThunderLAN debug mask"); static const char tlan_signature[] = "TLAN"; -static const char tlan_banner[] = "ThunderLAN driver v1.16\n"; +static const char tlan_banner[] = "ThunderLAN driver v1.17\n"; static int tlan_have_pci; static int tlan_have_eisa; @@ -462,11 +463,79 @@ static void __devexit tlan_remove_one(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); } +static void tlan_start(struct net_device *dev) +{ + tlan_reset_lists(dev); + /* NOTE: It might not be necessary to read the stats before a + reset if you don't care what the values are. + */ + tlan_read_and_clear_stats(dev, TLAN_IGNORE); + tlan_reset_adapter(dev); + netif_wake_queue(dev); +} + +static void tlan_stop(struct net_device *dev) +{ + struct tlan_priv *priv = netdev_priv(dev); + + tlan_read_and_clear_stats(dev, TLAN_RECORD); + outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD); + /* Reset and power down phy */ + tlan_reset_adapter(dev); + if (priv->timer.function != NULL) { + del_timer_sync(&priv->timer); + priv->timer.function = NULL; + } +} + +#ifdef CONFIG_PM + +static int tlan_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct net_device *dev = pci_get_drvdata(pdev); + + if (netif_running(dev)) + tlan_stop(dev); + + netif_device_detach(dev); + pci_save_state(pdev); + pci_disable_device(pdev); + pci_wake_from_d3(pdev, false); + pci_set_power_state(pdev, PCI_D3hot); + + return 0; +} + +static int tlan_resume(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + pci_enable_wake(pdev, 0, 0); + netif_device_attach(dev); + + if (netif_running(dev)) + tlan_start(dev); + + return 0; +} + +#else /* CONFIG_PM */ + +#define tlan_suspend NULL +#define tlan_resume NULL + +#endif /* CONFIG_PM */ + + static struct pci_driver tlan_driver = { .name = "tlan", .id_table = tlan_pci_tbl, .probe = tlan_init_one, .remove = __devexit_p(tlan_remove_one), + .suspend = tlan_suspend, + .resume = tlan_resume, }; static int __init tlan_probe(void) @@ -965,14 +1034,8 @@ static int tlan_open(struct net_device *dev) } init_timer(&priv->timer); - netif_start_queue(dev); - /* NOTE: It might not be necessary to read the stats before a - reset if you don't care what the values are. - */ - tlan_reset_lists(dev); - tlan_read_and_clear_stats(dev, TLAN_IGNORE); - tlan_reset_adapter(dev); + tlan_start(dev); TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Opened. TLAN Chip Rev: %x\n", dev->name, priv->tlan_rev); @@ -1243,15 +1306,8 @@ static int tlan_close(struct net_device *dev) { struct tlan_priv *priv = netdev_priv(dev); - netif_stop_queue(dev); priv->neg_be_verbose = 0; - - tlan_read_and_clear_stats(dev, TLAN_RECORD); - outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD); - if (priv->timer.function != NULL) { - del_timer_sync(&priv->timer); - priv->timer.function = NULL; - } + tlan_stop(dev); free_irq(dev->irq, dev); tlan_free_lists(dev); -- cgit v1.2.3 From 2505c5483137aa630806df9cd08a82d1cac72cc9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 24 Jan 2011 15:11:02 -0800 Subject: typhoon: Kill references to UTS_RELEASE This makes the driver get rebuilt every single time you type 'make' which is beyond rediculious. I hereby declare this driver to have version "1.0" Signed-off-by: David S. Miller --- drivers/net/typhoon.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index a3c46f6a15e7..7fa5ec2de942 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -123,12 +123,11 @@ static const int multicast_filter_limit = 32; #include #include #include -#include #include "typhoon.h" MODULE_AUTHOR("David Dillow "); -MODULE_VERSION(UTS_RELEASE); +MODULE_VERSION("1.0"); MODULE_LICENSE("GPL"); MODULE_FIRMWARE(FIRMWARE_NAME); MODULE_DESCRIPTION("3Com Typhoon Family (3C990, 3CR990, and variants)"); -- cgit v1.2.3 From e86ba1162f1f6d292d4901c8716a233632c3a783 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 24 Jan 2011 13:27:00 +0200 Subject: staging/easycap: fix missing backslash in ifdef statement the backslash was removed by mistake in the patch 'staging:easycap: drop redundant backslashes from the code' this breaks compilation only when EASYCAP_NEEDS_ALSA is not set Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index bb2ee315c0ec..43891039e7bf 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -2519,7 +2519,7 @@ return 0; /*****************************************************************************/ #if !defined(EASYCAP_NEEDS_ALSA) /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || +#if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \ (defined(EASYCAP_NEEDS_UNLOCKED_IOCTL))) long easyoss_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) { -- cgit v1.2.3 From 482cd2d8d85517b6444d646ae7874e0bb935746b Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 24 Jan 2011 13:27:01 +0200 Subject: staging/easycap: easycap.h ident correctly signed_div_result indent level 1 by tabs Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 2f49d4af2f5b..21355ccc8e9f 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -610,8 +610,8 @@ int regget(struct usb_device *, __u16, void *); int isdongle(struct easycap *); /*---------------------------------------------------------------------------*/ struct signed_div_result { -long long int quotient; -unsigned long long int remainder; + long long int quotient; + unsigned long long int remainder; } signed_div(long long int, long long int); -- cgit v1.2.3 From 5c0c6c395ea8ad2f831c0717f67f957ba84550ad Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 24 Jan 2011 13:27:02 +0200 Subject: staging/easycap: implement strerror function Replace long switch statements that just print out errno with strerror function. It reduces around 700 lines from the code. The function should be probably dropped at all but leave for now to not break currently expected debug output. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 2 + drivers/staging/easycap/easycap_main.c | 323 ++++--------------- drivers/staging/easycap/easycap_sound.c | 555 ++------------------------------ 3 files changed, 87 insertions(+), 793 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 21355ccc8e9f..d751e752a57c 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -644,6 +644,8 @@ struct signed_div_result { * IMMEDIATELY OBVIOUS FROM A CASUAL READING OF THE SOURCE CODE. BEWARE. */ /*---------------------------------------------------------------------------*/ +const char *strerror(int err); + #define SAY(format, args...) do { \ printk(KERN_DEBUG "easycap:: %s: " \ format, __func__, ##args); \ diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 85a26e3d54fb..cc1460b64b1e 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -58,6 +58,48 @@ static struct mutex mutex_dongle; static void easycap_complete(struct urb *purb); static int reset(struct easycap *peasycap); +const char *strerror(int err) +{ +#define ERRNOSTR(_e) case _e: return # _e + switch (err) { + case 0: return "OK"; + ERRNOSTR(ENOMEM); + ERRNOSTR(ENODEV); + ERRNOSTR(ENXIO); + ERRNOSTR(EINVAL); + ERRNOSTR(EAGAIN); + ERRNOSTR(EFBIG); + ERRNOSTR(EPIPE); + ERRNOSTR(EMSGSIZE); + ERRNOSTR(ENOSPC); + ERRNOSTR(EINPROGRESS); + ERRNOSTR(ENOSR); + ERRNOSTR(EOVERFLOW); + ERRNOSTR(EPROTO); + ERRNOSTR(EILSEQ); + ERRNOSTR(ETIMEDOUT); + ERRNOSTR(EOPNOTSUPP); + ERRNOSTR(EPFNOSUPPORT); + ERRNOSTR(EAFNOSUPPORT); + ERRNOSTR(EADDRINUSE); + ERRNOSTR(EADDRNOTAVAIL); + ERRNOSTR(ENOBUFS); + ERRNOSTR(EISCONN); + ERRNOSTR(ENOTCONN); + ERRNOSTR(ESHUTDOWN); + ERRNOSTR(ENOENT); + ERRNOSTR(ECONNRESET); + ERRNOSTR(ETIME); + ERRNOSTR(ECOMM); + ERRNOSTR(EREMOTEIO); + ERRNOSTR(EXDEV); + ERRNOSTR(EPERM); + default: return "unknown"; + } + +#undef ERRNOSTR +} + /*---------------------------------------------------------------------------*/ /* * PARAMETERS USED WHEN REGISTERING THE VIDEO INTERFACE @@ -599,72 +641,23 @@ if (!peasycap->video_isoc_streaming) { } rc = usb_submit_urb(purb, GFP_KERNEL); - if (0 != rc) { + if (rc) { isbad++; SAM("ERROR: usb_submit_urb() failed " - "for urb with rc:\n"); - switch (rc) { - case -ENOMEM: { - SAM("ERROR: -ENOMEM=" - "usb_submit_urb()\n"); - break; - } - case -ENODEV: { - SAM("ERROR: -ENODEV=" - "usb_submit_urb()\n"); - break; - } - case -ENXIO: { - SAM("ERROR: -ENXIO=" - "usb_submit_urb()\n"); - break; - } - case -EINVAL: { - SAM("ERROR: -EINVAL=" - "usb_submit_urb()\n"); - break; - } - case -EAGAIN: { - SAM("ERROR: -EAGAIN=" - "usb_submit_urb()\n"); - break; - } - case -EFBIG: { - SAM("ERROR: -EFBIG=" - "usb_submit_urb()\n"); - break; - } - case -EPIPE: { - SAM("ERROR: -EPIPE=" - "usb_submit_urb()\n"); - break; - } - case -EMSGSIZE: { - SAM("ERROR: -EMSGSIZE=" - "usb_submit_urb()\n"); - break; - } - case -ENOSPC: { + "for urb with rc:-%s\n", + strerror(rc)); + if (rc == -ENOSPC) nospc++; - break; - } - default: { - SAM("ERROR: %i=" - "usb_submit_urb()\n", - rc); - break; - } - } } else { m++; } - } else { - isbad++; - } } else { - isbad++; + isbad++; } + } else { + isbad++; } + } if (nospc) { SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc); SAM("..... possibly inadequate USB bandwidth\n"); @@ -2801,49 +2794,8 @@ if (peasycap->video_idle) { peasycap->video_idle, peasycap->video_isoc_streaming); if (peasycap->video_isoc_streaming) { rc = usb_submit_urb(purb, GFP_ATOMIC); - if (0 != rc) { - switch (rc) { - case -ENOMEM: { - SAM("ENOMEM\n"); - break; - } - case -ENODEV: { - SAM("ENODEV\n"); - break; - } - case -ENXIO: { - SAM("ENXIO\n"); - break; - } - case -EINVAL: { - SAM("EINVAL\n"); - break; - } - case -EAGAIN: { - SAM("EAGAIN\n"); - break; - } - case -EFBIG: { - SAM("EFBIG\n"); - break; - } - case -EPIPE: { - SAM("EPIPE\n"); - break; - } - case -EMSGSIZE: { - SAM("EMSGSIZE\n"); - break; - } - case -ENOSPC: { - SAM("ENOSPC\n"); - break; - } - default: { - SAM("0x%08X\n", rc); - break; - } - } + if (rc) { + SAM("%s:%d ENOMEM\n", strerror(rc), rc); if (-ENODEV != rc) SAM("ERROR: while %i=video_idle, " "usb_submit_urb() " @@ -2866,137 +2818,17 @@ if (purb->status) { } (peasycap->field_buffer[peasycap->field_fill][0].kount) |= 0x8000 ; - SAM("ERROR: bad urb status:\n"); - switch (purb->status) { - case -EINPROGRESS: { - SAM("-EINPROGRESS\n"); break; - } - case -ENOSR: { - SAM("-ENOSR\n"); break; - } - case -EPIPE: { - SAM("-EPIPE\n"); break; - } - case -EOVERFLOW: { - SAM("-EOVERFLOW\n"); break; - } - case -EPROTO: { - SAM("-EPROTO\n"); break; - } - case -EILSEQ: { - SAM("-EILSEQ\n"); break; - } - case -ETIMEDOUT: { - SAM("-ETIMEDOUT\n"); break; - } - case -EMSGSIZE: { - SAM("-EMSGSIZE\n"); break; - } - case -EOPNOTSUPP: { - SAM("-EOPNOTSUPP\n"); break; - } - case -EPFNOSUPPORT: { - SAM("-EPFNOSUPPORT\n"); break; - } - case -EAFNOSUPPORT: { - SAM("-EAFNOSUPPORT\n"); break; - } - case -EADDRINUSE: { - SAM("-EADDRINUSE\n"); break; - } - case -EADDRNOTAVAIL: { - SAM("-EADDRNOTAVAIL\n"); break; - } - case -ENOBUFS: { - SAM("-ENOBUFS\n"); break; - } - case -EISCONN: { - SAM("-EISCONN\n"); break; - } - case -ENOTCONN: { - SAM("-ENOTCONN\n"); break; - } - case -ESHUTDOWN: { - SAM("-ESHUTDOWN\n"); break; - } - case -ENOENT: { - SAM("-ENOENT\n"); break; - } - case -ECONNRESET: { - SAM("-ECONNRESET\n"); break; - } - case -ENOSPC: { - SAM("ENOSPC\n"); break; - } - default: { - SAM("unknown error code 0x%08X\n", purb->status); break; - } - } + SAM("ERROR: bad urb status -%s: %d\n", + strerror(purb->status), purb->status); /*---------------------------------------------------------------------------*/ } else { for (i = 0; i < purb->number_of_packets; i++) { if (0 != purb->iso_frame_desc[i].status) { (peasycap->field_buffer [peasycap->field_fill][0].kount) |= 0x8000 ; - switch (purb->iso_frame_desc[i].status) { - case 0: { - strcpy(&errbuf[0], "OK"); break; - } - case -ENOENT: { - strcpy(&errbuf[0], "-ENOENT"); break; - } - case -EINPROGRESS: { - strcpy(&errbuf[0], "-EINPROGRESS"); break; - } - case -EPROTO: { - strcpy(&errbuf[0], "-EPROTO"); break; - } - case -EILSEQ: { - strcpy(&errbuf[0], "-EILSEQ"); break; - } - case -ETIME: { - strcpy(&errbuf[0], "-ETIME"); break; - } - case -ETIMEDOUT: { - strcpy(&errbuf[0], "-ETIMEDOUT"); break; - } - case -EPIPE: { - strcpy(&errbuf[0], "-EPIPE"); break; - } - case -ECOMM: { - strcpy(&errbuf[0], "-ECOMM"); break; - } - case -ENOSR: { - strcpy(&errbuf[0], "-ENOSR"); break; - } - case -EOVERFLOW: { - strcpy(&errbuf[0], "-EOVERFLOW"); break; - } - case -EREMOTEIO: { - strcpy(&errbuf[0], "-EREMOTEIO"); break; - } - case -ENODEV: { - strcpy(&errbuf[0], "-ENODEV"); break; - } - case -EXDEV: { - strcpy(&errbuf[0], "-EXDEV"); break; - } - case -EINVAL: { - strcpy(&errbuf[0], "-EINVAL"); break; - } - case -ECONNRESET: { - strcpy(&errbuf[0], "-ECONNRESET"); break; - } - case -ENOSPC: { - SAM("ENOSPC\n"); break; - } - case -ESHUTDOWN: { - strcpy(&errbuf[0], "-ESHUTDOWN"); break; - } - default: { - strcpy(&errbuf[0], "unknown error"); break; - } - } + /* FIXME: 1. missing '-' check boundaries */ + strcpy(&errbuf[0], + strerror(purb->iso_frame_desc[i].status)); } framestatus = purb->iso_frame_desc[i].status; framelength = purb->iso_frame_desc[i].length; @@ -3270,44 +3102,13 @@ if (VIDEO_ISOC_BUFFER_MANY <= peasycap->video_junk) { } if (peasycap->video_isoc_streaming) { rc = usb_submit_urb(purb, GFP_ATOMIC); - if (0 != rc) { - switch (rc) { - case -ENOMEM: { - SAM("ENOMEM\n"); break; - } - case -ENODEV: { - SAM("ENODEV\n"); break; - } - case -ENXIO: { - SAM("ENXIO\n"); break; - } - case -EINVAL: { - SAM("EINVAL\n"); break; - } - case -EAGAIN: { - SAM("EAGAIN\n"); break; - } - case -EFBIG: { - SAM("EFBIG\n"); break; - } - case -EPIPE: { - SAM("EPIPE\n"); break; - } - case -EMSGSIZE: { - SAM("EMSGSIZE\n"); break; - } - case -ENOSPC: { - SAM("ENOSPC\n"); break; - } - default: { - SAM("0x%08X\n", rc); break; - } - } + if (rc) { + SAM("%s: %d\n", strerror(rc), rc); if (-ENODEV != rc) SAM("ERROR: while %i=video_idle, " - "usb_submit_urb() " - "failed with rc:\n", - peasycap->video_idle); + "usb_submit_urb() " + "failed with rc:\n", + peasycap->video_idle); } } return; diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index d539e2886a2b..05d9eed6eb04 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -213,93 +213,8 @@ if (purb->status) { JOM(16, "urb status -ESHUTDOWN or -ENOENT\n"); return; } - SAM("ERROR: non-zero urb status:\n"); - switch (purb->status) { - case -EINPROGRESS: { - SAM("-EINPROGRESS\n"); - break; - } - case -ENOSR: { - SAM("-ENOSR\n"); - break; - } - case -EPIPE: { - SAM("-EPIPE\n"); - break; - } - case -EOVERFLOW: { - SAM("-EOVERFLOW\n"); - break; - } - case -EPROTO: { - SAM("-EPROTO\n"); - break; - } - case -EILSEQ: { - SAM("-EILSEQ\n"); - break; - } - case -ETIMEDOUT: { - SAM("-ETIMEDOUT\n"); - break; - } - case -EMSGSIZE: { - SAM("-EMSGSIZE\n"); - break; - } - case -EOPNOTSUPP: { - SAM("-EOPNOTSUPP\n"); - break; - } - case -EPFNOSUPPORT: { - SAM("-EPFNOSUPPORT\n"); - break; - } - case -EAFNOSUPPORT: { - SAM("-EAFNOSUPPORT\n"); - break; - } - case -EADDRINUSE: { - SAM("-EADDRINUSE\n"); - break; - } - case -EADDRNOTAVAIL: { - SAM("-EADDRNOTAVAIL\n"); - break; - } - case -ENOBUFS: { - SAM("-ENOBUFS\n"); - break; - } - case -EISCONN: { - SAM("-EISCONN\n"); - break; - } - case -ENOTCONN: { - SAM("-ENOTCONN\n"); - break; - } - case -ESHUTDOWN: { - SAM("-ESHUTDOWN\n"); - break; - } - case -ENOENT: { - SAM("-ENOENT\n"); - break; - } - case -ECONNRESET: { - SAM("-ECONNRESET\n"); - break; - } - case -ENOSPC: { - SAM("ENOSPC\n"); - break; - } - default: { - SAM("unknown error: %i\n", purb->status); - break; - } - } + SAM("ERROR: non-zero urb status: -%s: %d\n", + strerror(purb->status), purb->status); goto resubmit; } /*---------------------------------------------------------------------------*/ @@ -313,86 +228,10 @@ oldaudio = peasycap->oldaudio; #endif /*UPSAMPLE*/ for (i = 0; i < purb->number_of_packets; i++) { - switch (purb->iso_frame_desc[i].status) { - case 0: { - break; - } - case -ENOENT: { - SAM("-ENOENT\n"); - break; - } - case -EINPROGRESS: { - SAM("-EINPROGRESS\n"); - break; - } - case -EPROTO: { - SAM("-EPROTO\n"); - break; - } - case -EILSEQ: { - SAM("-EILSEQ\n"); - break; - } - case -ETIME: { - SAM("-ETIME\n"); - break; - } - case -ETIMEDOUT: { - SAM("-ETIMEDOUT\n"); - break; - } - case -EPIPE: { - SAM("-EPIPE\n"); - break; - } - case -ECOMM: { - SAM("-ECOMM\n"); - break; - } - case -ENOSR: { - SAM("-ENOSR\n"); - break; - } - case -EOVERFLOW: { - SAM("-EOVERFLOW\n"); - break; - } - case -EREMOTEIO: { - SAM("-EREMOTEIO\n"); - break; - } - case -ENODEV: { - SAM("-ENODEV\n"); - break; - } - case -EXDEV: { - SAM("-EXDEV\n"); - break; - } - case -EINVAL: { - SAM("-EINVAL\n"); - break; - } - case -ECONNRESET: { - SAM("-ECONNRESET\n"); - break; - } - case -ENOSPC: { - SAM("-ENOSPC\n"); - break; - } - case -ESHUTDOWN: { - SAM("-ESHUTDOWN\n"); - break; - } - case -EPERM: { - SAM("-EPERM\n"); - break; - } - default: { - SAM("unknown error: %i\n", purb->iso_frame_desc[i].status); - break; - } + if (purb->iso_frame_desc[i].status < 0) { + SAM("-%s: %d\n", + strerror(purb->iso_frame_desc[i].status), + purb->iso_frame_desc[i].status); } if (!purb->iso_frame_desc[i].status) { more = purb->iso_frame_desc[i].actual_length; @@ -537,56 +376,12 @@ peasycap->oldaudio = oldaudio; resubmit: if (peasycap->audio_isoc_streaming) { rc = usb_submit_urb(purb, GFP_ATOMIC); - if (0 != rc) { + if (rc) { if ((-ENODEV != rc) && (-ENOENT != rc)) { SAM("ERROR: while %i=audio_idle, " "usb_submit_urb() failed " - "with rc:\n", peasycap->audio_idle); - } - switch (rc) { - case -ENODEV: - case -ENOENT: - break; - case -ENOMEM: { - SAM("-ENOMEM\n"); - break; - } - case -ENXIO: { - SAM("-ENXIO\n"); - break; - } - case -EINVAL: { - SAM("-EINVAL\n"); - break; - } - case -EAGAIN: { - SAM("-EAGAIN\n"); - break; - } - case -EFBIG: { - SAM("-EFBIG\n"); - break; - } - case -EPIPE: { - SAM("-EPIPE\n"); - break; - } - case -EMSGSIZE: { - SAM("-EMSGSIZE\n"); - break; - } - case -ENOSPC: { - SAM("-ENOSPC\n"); - break; - } - case -EPERM: { - SAM("-EPERM\n"); - break; - } - default: { - SAM("unknown error: %i\n", rc); - break; - } + "with rc: -%s :%d\n", peasycap->audio_idle, + strerror(rc), rc); } if (0 < peasycap->audio_isoc_streaming) (peasycap->audio_isoc_streaming)--; @@ -945,56 +740,12 @@ if (peasycap->audio_idle) { peasycap->audio_idle, peasycap->audio_isoc_streaming); if (peasycap->audio_isoc_streaming) { rc = usb_submit_urb(purb, GFP_ATOMIC); - if (0 != rc) { + if (rc) { if (-ENODEV != rc && -ENOENT != rc) { SAM("ERROR: while %i=audio_idle, " - "usb_submit_urb() failed with rc:\n", - peasycap->audio_idle); - } - switch (rc) { - case -ENODEV: - case -ENOENT: - break; - case -ENOMEM: { - SAM("-ENOMEM\n"); - break; - } - case -ENXIO: { - SAM("-ENXIO\n"); - break; - } - case -EINVAL: { - SAM("-EINVAL\n"); - break; - } - case -EAGAIN: { - SAM("-EAGAIN\n"); - break; - } - case -EFBIG: { - SAM("-EFBIG\n"); - break; - } - case -EPIPE: { - SAM("-EPIPE\n"); - break; - } - case -EMSGSIZE: { - SAM("-EMSGSIZE\n"); - break; - } - case -ENOSPC: { - SAM("-ENOSPC\n"); - break; - } - case -EPERM: { - SAM("-EPERM\n"); - break; - } - default: { - SAM("unknown error: %i\n", rc); - break; - } + "usb_submit_urb() failed with rc: -%s: %d\n", + peasycap->audio_idle, + strerror(rc), rc); } } } @@ -1006,97 +757,8 @@ if (purb->status) { JOM(16, "urb status -ESHUTDOWN or -ENOENT\n"); return; } - SAM("ERROR: non-zero urb status:\n"); - switch (purb->status) { - case -EINPROGRESS: { - SAM("-EINPROGRESS\n"); - break; - } - case -ENOSR: { - SAM("-ENOSR\n"); - break; - } - case -EPIPE: { - SAM("-EPIPE\n"); - break; - } - case -EOVERFLOW: { - SAM("-EOVERFLOW\n"); - break; - } - case -EPROTO: { - SAM("-EPROTO\n"); - break; - } - case -EILSEQ: { - SAM("-EILSEQ\n"); - break; - } - case -ETIMEDOUT: { - SAM("-ETIMEDOUT\n"); - break; - } - case -EMSGSIZE: { - SAM("-EMSGSIZE\n"); - break; - } - case -EOPNOTSUPP: { - SAM("-EOPNOTSUPP\n"); - break; - } - case -EPFNOSUPPORT: { - SAM("-EPFNOSUPPORT\n"); - break; - } - case -EAFNOSUPPORT: { - SAM("-EAFNOSUPPORT\n"); - break; - } - case -EADDRINUSE: { - SAM("-EADDRINUSE\n"); - break; - } - case -EADDRNOTAVAIL: { - SAM("-EADDRNOTAVAIL\n"); - break; - } - case -ENOBUFS: { - SAM("-ENOBUFS\n"); - break; - } - case -EISCONN: { - SAM("-EISCONN\n"); - break; - } - case -ENOTCONN: { - SAM("-ENOTCONN\n"); - break; - } - case -ESHUTDOWN: { - SAM("-ESHUTDOWN\n"); - break; - } - case -ENOENT: { - SAM("-ENOENT\n"); - break; - } - case -ECONNRESET: { - SAM("-ECONNRESET\n"); - break; - } - case -ENOSPC: { - SAM("ENOSPC\n"); - break; - } - case -EPERM: { - SAM("-EPERM\n"); - break; - } - default: { - SAM("unknown error: %i\n", purb->status); - break; - } - } + SAM("ERROR: non-zero urb status: -%s: %d\n", + strerror(purb->status), purb->status); goto resubmit; } /*---------------------------------------------------------------------------*/ @@ -1109,88 +771,10 @@ oldaudio = peasycap->oldaudio; #endif /*UPSAMPLE*/ for (i = 0; i < purb->number_of_packets; i++) { - switch (purb->iso_frame_desc[i].status) { - case 0: { - break; - } - case -ENODEV: { - SAM("-ENODEV\n"); - break; - } - case -ENOENT: { - SAM("-ENOENT\n"); - break; - } - case -EINPROGRESS: { - SAM("-EINPROGRESS\n"); - break; - } - case -EPROTO: { - SAM("-EPROTO\n"); - break; - } - case -EILSEQ: { - SAM("-EILSEQ\n"); - break; - } - case -ETIME: { - SAM("-ETIME\n"); - break; - } - case -ETIMEDOUT: { - SAM("-ETIMEDOUT\n"); - break; - } - case -EPIPE: { - SAM("-EPIPE\n"); - break; - } - case -ECOMM: { - SAM("-ECOMM\n"); - break; - } - case -ENOSR: { - SAM("-ENOSR\n"); - break; - } - case -EOVERFLOW: { - SAM("-EOVERFLOW\n"); - break; - } - case -EREMOTEIO: { - SAM("-EREMOTEIO\n"); - break; - } - case -EXDEV: { - SAM("-EXDEV\n"); - break; - } - case -EINVAL: { - SAM("-EINVAL\n"); - break; - } - case -ECONNRESET: { - SAM("-ECONNRESET\n"); - break; - } - case -ENOSPC: { - SAM("-ENOSPC\n"); - break; - } - case -ESHUTDOWN: { - SAM("-ESHUTDOWN\n"); - break; - } - case -EPERM: { - SAM("-EPERM\n"); - break; - } - default: { - SAM("unknown error: %i\n", purb->iso_frame_desc[i].status); - break; - } - } if (!purb->iso_frame_desc[i].status) { + + SAM("-%s\n", strerror(purb->iso_frame_desc[i].status)); + more = purb->iso_frame_desc[i].actual_length; #if defined(TESTTONE) @@ -1370,52 +954,8 @@ if (peasycap->audio_isoc_streaming) { if (-ENODEV != rc && -ENOENT != rc) { SAM("ERROR: while %i=audio_idle, " "usb_submit_urb() failed " - "with rc:\n", peasycap->audio_idle); - } - switch (rc) { - case -ENODEV: - case -ENOENT: - break; - case -ENOMEM: { - SAM("-ENOMEM\n"); - break; - } - case -ENXIO: { - SAM("-ENXIO\n"); - break; - } - case -EINVAL: { - SAM("-EINVAL\n"); - break; - } - case -EAGAIN: { - SAM("-EAGAIN\n"); - break; - } - case -EFBIG: { - SAM("-EFBIG\n"); - break; - } - case -EPIPE: { - SAM("-EPIPE\n"); - break; - } - case -EMSGSIZE: { - SAM("-EMSGSIZE\n"); - break; - } - case -ENOSPC: { - SAM("-ENOSPC\n"); - break; - } - case -EPERM: { - SAM("-EPERM\n"); - break; - } - default: { - SAM("unknown error: %i\n", rc); - break; - } + "with rc: -%s: %d\n", peasycap->audio_idle, + strerror(rc), rc); } } } @@ -1965,60 +1505,11 @@ if (!peasycap->audio_isoc_streaming) { } rc = usb_submit_urb(purb, GFP_KERNEL); - if (0 != rc) { + if (rc) { isbad++; SAM("ERROR: usb_submit_urb() failed" - " for urb with rc:\n"); - switch (rc) { - case -ENODEV: { - SAM("-ENODEV\n"); - break; - } - case -ENOENT: { - SAM("-ENOENT\n"); - break; - } - case -ENOMEM: { - SAM("-ENOMEM\n"); - break; - } - case -ENXIO: { - SAM("-ENXIO\n"); - break; - } - case -EINVAL: { - SAM("-EINVAL\n"); - break; - } - case -EAGAIN: { - SAM("-EAGAIN\n"); - break; - } - case -EFBIG: { - SAM("-EFBIG\n"); - break; - } - case -EPIPE: { - SAM("-EPIPE\n"); - break; - } - case -EMSGSIZE: { - SAM("-EMSGSIZE\n"); - break; - } - case -ENOSPC: { - nospc++; - break; - } - case -EPERM: { - SAM("-EPERM\n"); - break; - } - default: { - SAM("unknown error: %i\n", rc); - break; - } - } + " for urb with rc: -%s: %d\n", + strerror(rc), rc); } else { m++; } -- cgit v1.2.3 From 04ed3e741d0f133e02bed7fa5c98edba128f90e7 Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Mon, 24 Jan 2011 15:32:47 -0800 Subject: net: change netdev->features to u32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Quoting Ben Hutchings: we presumably won't be defining features that can only be enabled on 64-bit architectures. Occurences found by `grep -r` on net/, drivers/net, include/ [ Move features and vlan_features next to each other in struct netdev, as per Eric Dumazet's suggestion -DaveM ] Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 2 +- drivers/net/bonding/bond_main.c | 4 ++-- drivers/net/myri10ge/myri10ge.c | 4 ++-- drivers/net/sfc/ethtool.c | 4 ++-- drivers/net/sfc/net_driver.h | 2 +- drivers/net/tun.c | 2 +- include/linux/netdevice.h | 24 ++++++++++++------------ include/linux/skbuff.h | 2 +- include/net/protocol.h | 4 ++-- include/net/tcp.h | 2 +- include/net/udp.h | 2 +- net/8021q/vlan.c | 2 +- net/bridge/br_if.c | 2 +- net/bridge/br_private.h | 2 +- net/core/dev.c | 15 +++++++-------- net/core/ethtool.c | 2 +- net/core/net-sysfs.c | 2 +- net/core/skbuff.c | 4 ++-- net/ipv4/af_inet.c | 2 +- net/ipv4/tcp.c | 2 +- net/ipv4/udp.c | 2 +- net/ipv6/af_inet6.c | 2 +- net/ipv6/udp.c | 2 +- 23 files changed, 45 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index df99edf3464a..cab96fa4cd3a 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -8312,7 +8312,7 @@ static const struct net_device_ops bnx2_netdev_ops = { #endif }; -static void inline vlan_features_add(struct net_device *dev, unsigned long flags) +static void inline vlan_features_add(struct net_device *dev, u32 flags) { dev->vlan_features |= flags; } diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 163e0b06eaa5..7047b406b8ba 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1372,8 +1372,8 @@ static int bond_compute_features(struct bonding *bond) { struct slave *slave; struct net_device *bond_dev = bond->dev; - unsigned long features = bond_dev->features; - unsigned long vlan_features = 0; + u32 features = bond_dev->features; + u32 vlan_features = 0; unsigned short max_hard_header_len = max((u16)ETH_HLEN, bond_dev->hard_header_len); int i; diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index ea5cfe2c3a04..a7f2eed9a08a 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -253,7 +253,7 @@ struct myri10ge_priv { unsigned long serial_number; int vendor_specific_offset; int fw_multicast_support; - unsigned long features; + u32 features; u32 max_tso6; u32 read_dma; u32 write_dma; @@ -1776,7 +1776,7 @@ static int myri10ge_set_rx_csum(struct net_device *netdev, u32 csum_enabled) static int myri10ge_set_tso(struct net_device *netdev, u32 tso_enabled) { struct myri10ge_priv *mgp = netdev_priv(netdev); - unsigned long flags = mgp->features & (NETIF_F_TSO6 | NETIF_F_TSO); + u32 flags = mgp->features & (NETIF_F_TSO6 | NETIF_F_TSO); if (tso_enabled) netdev->features |= flags; diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 0e8bb19ed60d..713969accdbd 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -502,7 +502,7 @@ static void efx_ethtool_get_stats(struct net_device *net_dev, static int efx_ethtool_set_tso(struct net_device *net_dev, u32 enable) { struct efx_nic *efx __attribute__ ((unused)) = netdev_priv(net_dev); - unsigned long features; + u32 features; features = NETIF_F_TSO; if (efx->type->offload_features & NETIF_F_V6_CSUM) @@ -519,7 +519,7 @@ static int efx_ethtool_set_tso(struct net_device *net_dev, u32 enable) static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable) { struct efx_nic *efx = netdev_priv(net_dev); - unsigned long features = efx->type->offload_features & NETIF_F_ALL_CSUM; + u32 features = efx->type->offload_features & NETIF_F_ALL_CSUM; if (enable) net_dev->features |= features; diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 28df8665256a..c65270241d2d 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -906,7 +906,7 @@ struct efx_nic_type { unsigned int phys_addr_channels; unsigned int tx_dc_base; unsigned int rx_dc_base; - unsigned long offload_features; + u32 offload_features; u32 reset_world_flags; }; diff --git a/drivers/net/tun.c b/drivers/net/tun.c index b100bd50a0d7..55786a0efc41 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1142,7 +1142,7 @@ static int tun_get_iff(struct net *net, struct tun_struct *tun, * privs required. */ static int set_offload(struct net_device *dev, unsigned long arg) { - unsigned int old_features, features; + u32 old_features, features; old_features = dev->features; /* Unset features, set them as we chew on the arg. */ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index a335f2022690..0de3c59720fa 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -914,7 +914,11 @@ struct net_device { struct list_head unreg_list; /* Net device features */ - unsigned long features; + u32 features; + + /* VLAN feature mask */ + u32 vlan_features; + #define NETIF_F_SG 1 /* Scatter/gather IO. */ #define NETIF_F_IP_CSUM 2 /* Can checksum TCP/UDP over IPv4. */ #define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */ @@ -1176,9 +1180,6 @@ struct net_device { /* rtnetlink link ops */ const struct rtnl_link_ops *rtnl_link_ops; - /* VLAN feature mask */ - unsigned long vlan_features; - /* for setting kernel sock attribute on TCP connection setup */ #define GSO_MAX_SIZE 65536 unsigned int gso_max_size; @@ -1401,7 +1402,7 @@ struct packet_type { struct packet_type *, struct net_device *); struct sk_buff *(*gso_segment)(struct sk_buff *skb, - int features); + u32 features); int (*gso_send_check)(struct sk_buff *skb); struct sk_buff **(*gro_receive)(struct sk_buff **head, struct sk_buff *skb); @@ -2370,7 +2371,7 @@ extern int netdev_tstamp_prequeue; extern int weight_p; extern int netdev_set_master(struct net_device *dev, struct net_device *master); extern int skb_checksum_help(struct sk_buff *skb); -extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features); +extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, u32 features); #ifdef CONFIG_BUG extern void netdev_rx_csum_fault(struct net_device *dev); #else @@ -2397,22 +2398,21 @@ extern char *netdev_drivername(const struct net_device *dev, char *buffer, int l extern void linkwatch_run_queue(void); -unsigned long netdev_increment_features(unsigned long all, unsigned long one, - unsigned long mask); -unsigned long netdev_fix_features(unsigned long features, const char *name); +u32 netdev_increment_features(u32 all, u32 one, u32 mask); +u32 netdev_fix_features(u32 features, const char *name); void netif_stacked_transfer_operstate(const struct net_device *rootdev, struct net_device *dev); -int netif_skb_features(struct sk_buff *skb); +u32 netif_skb_features(struct sk_buff *skb); -static inline int net_gso_ok(int features, int gso_type) +static inline int net_gso_ok(u32 features, int gso_type) { int feature = gso_type << NETIF_F_GSO_SHIFT; return (features & feature) == feature; } -static inline int skb_gso_ok(struct sk_buff *skb, int features) +static inline int skb_gso_ok(struct sk_buff *skb, u32 features) { return net_gso_ok(features, skb_shinfo(skb)->gso_type) && (!skb_has_frag_list(skb) || (features & NETIF_F_FRAGLIST)); diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 6e946da9d1d6..31f02d0b46a7 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1877,7 +1877,7 @@ extern void skb_split(struct sk_buff *skb, extern int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen); -extern struct sk_buff *skb_segment(struct sk_buff *skb, int features); +extern struct sk_buff *skb_segment(struct sk_buff *skb, u32 features); static inline void *skb_header_pointer(const struct sk_buff *skb, int offset, int len, void *buffer) diff --git a/include/net/protocol.h b/include/net/protocol.h index dc07495bce4c..6f7eb800974a 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -38,7 +38,7 @@ struct net_protocol { void (*err_handler)(struct sk_buff *skb, u32 info); int (*gso_send_check)(struct sk_buff *skb); struct sk_buff *(*gso_segment)(struct sk_buff *skb, - int features); + u32 features); struct sk_buff **(*gro_receive)(struct sk_buff **head, struct sk_buff *skb); int (*gro_complete)(struct sk_buff *skb); @@ -57,7 +57,7 @@ struct inet6_protocol { int (*gso_send_check)(struct sk_buff *skb); struct sk_buff *(*gso_segment)(struct sk_buff *skb, - int features); + u32 features); struct sk_buff **(*gro_receive)(struct sk_buff **head, struct sk_buff *skb); int (*gro_complete)(struct sk_buff *skb); diff --git a/include/net/tcp.h b/include/net/tcp.h index 38509f047382..917911165e3b 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1404,7 +1404,7 @@ extern struct request_sock_ops tcp6_request_sock_ops; extern void tcp_v4_destroy_sock(struct sock *sk); extern int tcp_v4_gso_send_check(struct sk_buff *skb); -extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features); +extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, u32 features); extern struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb); extern struct sk_buff **tcp4_gro_receive(struct sk_buff **head, diff --git a/include/net/udp.h b/include/net/udp.h index bb967dd59bf7..e82f3a8c0f8f 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -245,5 +245,5 @@ extern void udp4_proc_exit(void); extern void udp_init(void); extern int udp4_ufo_send_check(struct sk_buff *skb); -extern struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, int features); +extern struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, u32 features); #endif /* _UDP_H */ diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 6e64f7c6a2e9..7850412f52b7 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -327,7 +327,7 @@ static void vlan_sync_address(struct net_device *dev, static void vlan_transfer_features(struct net_device *dev, struct net_device *vlandev) { - unsigned long old_features = vlandev->features; + u32 old_features = vlandev->features; vlandev->features &= ~dev->vlan_features; vlandev->features |= dev->features & dev->vlan_features; diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index d9d1e2bac1d6..52ce4a30f8b3 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -365,7 +365,7 @@ int br_min_mtu(const struct net_bridge *br) void br_features_recompute(struct net_bridge *br) { struct net_bridge_port *p; - unsigned long features, mask; + u32 features, mask; features = mask = br->feature_mask; if (list_empty(&br->port_list)) diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 84aac7734bfc..9f22898c5359 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -182,7 +182,7 @@ struct net_bridge struct br_cpu_netstats __percpu *stats; spinlock_t hash_lock; struct hlist_head hash[BR_HASH_SIZE]; - unsigned long feature_mask; + u32 feature_mask; #ifdef CONFIG_BRIDGE_NETFILTER struct rtable fake_rtable; bool nf_call_iptables; diff --git a/net/core/dev.c b/net/core/dev.c index ad3741898584..7103f89fde0c 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1858,7 +1858,7 @@ EXPORT_SYMBOL(skb_checksum_help); * It may return NULL if the skb requires no segmentation. This is * only possible when GSO is used for verifying header integrity. */ -struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) +struct sk_buff *skb_gso_segment(struct sk_buff *skb, u32 features) { struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); struct packet_type *ptype; @@ -2046,7 +2046,7 @@ static bool can_checksum_protocol(unsigned long features, __be16 protocol) protocol == htons(ETH_P_FCOE))); } -static int harmonize_features(struct sk_buff *skb, __be16 protocol, int features) +static u32 harmonize_features(struct sk_buff *skb, __be16 protocol, u32 features) { if (!can_checksum_protocol(features, protocol)) { features &= ~NETIF_F_ALL_CSUM; @@ -2058,10 +2058,10 @@ static int harmonize_features(struct sk_buff *skb, __be16 protocol, int features return features; } -int netif_skb_features(struct sk_buff *skb) +u32 netif_skb_features(struct sk_buff *skb) { __be16 protocol = skb->protocol; - int features = skb->dev->features; + u32 features = skb->dev->features; if (protocol == htons(ETH_P_8021Q)) { struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; @@ -2106,7 +2106,7 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, int rc = NETDEV_TX_OK; if (likely(!skb->next)) { - int features; + u32 features; /* * If device doesnt need skb->dst, release it right now while @@ -5213,7 +5213,7 @@ static void rollback_registered(struct net_device *dev) rollback_registered_many(&single); } -unsigned long netdev_fix_features(unsigned long features, const char *name) +u32 netdev_fix_features(u32 features, const char *name) { /* Fix illegal checksum combinations */ if ((features & NETIF_F_HW_CSUM) && @@ -6143,8 +6143,7 @@ static int dev_cpu_callback(struct notifier_block *nfb, * @one to the master device with current feature set @all. Will not * enable anything that is off in @mask. Returns the new feature set. */ -unsigned long netdev_increment_features(unsigned long all, unsigned long one, - unsigned long mask) +u32 netdev_increment_features(u32 all, u32 one, u32 mask) { /* If device needs checksumming, downgrade to it. */ if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM)) diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 17741782a345..bd1af99e1122 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -1458,7 +1458,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) void __user *useraddr = ifr->ifr_data; u32 ethcmd; int rc; - unsigned long old_features; + u32 old_features; if (!dev || !netif_device_present(dev)) return -ENODEV; diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index e23c01be5a5b..81367ccf3306 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -99,7 +99,7 @@ NETDEVICE_SHOW(addr_assign_type, fmt_dec); NETDEVICE_SHOW(addr_len, fmt_dec); NETDEVICE_SHOW(iflink, fmt_dec); NETDEVICE_SHOW(ifindex, fmt_dec); -NETDEVICE_SHOW(features, fmt_long_hex); +NETDEVICE_SHOW(features, fmt_hex); NETDEVICE_SHOW(type, fmt_dec); NETDEVICE_SHOW(link_mode, fmt_dec); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index d31bb36ae0dc..436c4c439240 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -2497,7 +2497,7 @@ EXPORT_SYMBOL_GPL(skb_pull_rcsum); * a pointer to the first in a list of new skbs for the segments. * In case of error it returns ERR_PTR(err). */ -struct sk_buff *skb_segment(struct sk_buff *skb, int features) +struct sk_buff *skb_segment(struct sk_buff *skb, u32 features) { struct sk_buff *segs = NULL; struct sk_buff *tail = NULL; @@ -2507,7 +2507,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features) unsigned int offset = doffset; unsigned int headroom; unsigned int len; - int sg = features & NETIF_F_SG; + int sg = !!(features & NETIF_F_SG); int nfrags = skb_shinfo(skb)->nr_frags; int err = -ENOMEM; int i = 0; diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index f2b61107df6c..e5e2d9d64abb 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1215,7 +1215,7 @@ out: return err; } -static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features) +static struct sk_buff *inet_gso_segment(struct sk_buff *skb, u32 features) { struct sk_buff *segs = ERR_PTR(-EINVAL); struct iphdr *iph; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 6c11eece262c..f9867d2dbef4 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2653,7 +2653,7 @@ int compat_tcp_getsockopt(struct sock *sk, int level, int optname, EXPORT_SYMBOL(compat_tcp_getsockopt); #endif -struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features) +struct sk_buff *tcp_tso_segment(struct sk_buff *skb, u32 features) { struct sk_buff *segs = ERR_PTR(-EINVAL); struct tcphdr *th; diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 8157b17959ee..d37baaa1dbe3 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -2199,7 +2199,7 @@ int udp4_ufo_send_check(struct sk_buff *skb) return 0; } -struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, int features) +struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, u32 features) { struct sk_buff *segs = ERR_PTR(-EINVAL); unsigned int mss; diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 978e80e2c4a8..3194aa909872 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -772,7 +772,7 @@ out: return err; } -static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features) +static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, u32 features) { struct sk_buff *segs = ERR_PTR(-EINVAL); struct ipv6hdr *ipv6h; diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 9a009c66c8a3..a419a787eb69 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1299,7 +1299,7 @@ static int udp6_ufo_send_check(struct sk_buff *skb) return 0; } -static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, int features) +static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, u32 features) { struct sk_buff *segs = ERR_PTR(-EINVAL); unsigned int mss; -- cgit v1.2.3 From 0edbc24c5dc7fba0dce193f7d4b7faf2ad211ba4 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 24 Jan 2011 17:08:20 +0200 Subject: staging/easycap: make OSS compilation optional instead of ALSA OSS is deprecated yet currently it is reported to be more stable therefore we keep it but make it optional Revert the conditional compilation: add CONFIG_EASYCAP_OSS and kill EASYCAP_NEEDS_ALSA move oss-only code from easycap_sound.c to easycap_sound_oss.c Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/Kconfig | 14 +- drivers/staging/easycap/Makefile | 10 +- drivers/staging/easycap/easycap.h | 25 +- drivers/staging/easycap/easycap_ioctl.c | 4 +- drivers/staging/easycap/easycap_main.c | 36 +- drivers/staging/easycap/easycap_sound.c | 712 +-------------------------- drivers/staging/easycap/easycap_sound_oss.c | 730 ++++++++++++++++++++++++++++ 7 files changed, 789 insertions(+), 742 deletions(-) create mode 100644 drivers/staging/easycap/easycap_sound_oss.c (limited to 'drivers') diff --git a/drivers/staging/easycap/Kconfig b/drivers/staging/easycap/Kconfig index 4c1ad7e8b5ab..5072cf8a5da0 100644 --- a/drivers/staging/easycap/Kconfig +++ b/drivers/staging/easycap/Kconfig @@ -1,6 +1,6 @@ config EASYCAP tristate "EasyCAP USB ID 05e1:0408 support" - depends on USB && VIDEO_DEV && SND + depends on USB && VIDEO_DEV && SOUND ---help--- This is an integrated audio/video driver for EasyCAP cards with @@ -15,6 +15,18 @@ config EASYCAP To compile this driver as a module, choose M here: the module will be called easycap +config EASYCAP_OSS + bool "OSS (DEPRECATED)" + depends on EASYCAP && SOUND_OSS_CORE + + ---help--- + Say 'Y' if you prefer Open Sound System (OSS) interface + + This will disable Advanced Linux Sound Architecture (ALSA) binding. + + Once binding to ALSA interface will be stable this option will be + removed. + config EASYCAP_DEBUG bool "Enable EasyCAP driver debugging" depends on EASYCAP diff --git a/drivers/staging/easycap/Makefile b/drivers/staging/easycap/Makefile index 226a7795a1db..a01ca11ec1e4 100644 --- a/drivers/staging/easycap/Makefile +++ b/drivers/staging/easycap/Makefile @@ -1,5 +1,10 @@ -easycap-objs := easycap_main.o easycap_low.o easycap_sound.o \ - easycap_ioctl.o easycap_settings.o easycap_testcard.o +easycap-objs := easycap_main.o +easycap-objs += easycap_low.o +easycap-objs += easycap_ioctl.o +easycap-objs += easycap_settings.o +easycap-objs += easycap_testcard.o +easycap-objs += easycap_sound.o +easycap-$(CONFIG_EASYCAP_OSS) += easycap_sound_oss.o obj-$(CONFIG_EASYCAP) += easycap.o @@ -8,5 +13,4 @@ ccflags-y += -DEASYCAP_IS_VIDEODEV_CLIENT ccflags-y += -DEASYCAP_NEEDS_V4L2_DEVICE_H ccflags-y += -DEASYCAP_NEEDS_V4L2_FOPS ccflags-y += -DEASYCAP_NEEDS_UNLOCKED_IOCTL -ccflags-y += -DEASYCAP_NEEDS_ALSA diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index d751e752a57c..55ff0d571cfd 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -59,9 +59,9 @@ */ /*---------------------------------------------------------------------------*/ #undef EASYCAP_TESTCARD -#if (!defined(EASYCAP_NEEDS_ALSA)) +#ifdef CONFIG_EASYCAP_OSS #undef EASYCAP_TESTTONE -#endif /*EASYCAP_NEEDS_ALSA*/ +#endif /* CONFIG_EASYCAP_OSS */ /*---------------------------------------------------------------------------*/ #include #include @@ -81,7 +81,7 @@ #include #include -#if defined(EASYCAP_NEEDS_ALSA) +#ifndef CONFIG_EASYCAP_OSS #include #include #include @@ -90,7 +90,7 @@ #include #include #include -#endif /*EASYCAP_NEEDS_ALSA*/ +#endif /* !CONFIG_EASYCAP_OSS */ /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #if defined(EASYCAP_IS_VIDEODEV_CLIENT) #include @@ -445,7 +445,7 @@ __s16 oldaudio; * ALSA */ /*---------------------------------------------------------------------------*/ -#if defined(EASYCAP_NEEDS_ALSA) +#ifndef CONFIG_EASYCAP_OSS struct snd_pcm_hardware alsa_hardware; struct snd_card *psnd_card; struct snd_pcm *psnd_pcm; @@ -453,7 +453,7 @@ __s16 oldaudio; int dma_fill; int dma_next; int dma_read; -#endif /*EASYCAP_NEEDS_ALSA*/ +#endif /* !CONFIG_EASYCAP_OSS */ /*---------------------------------------------------------------------------*/ /* * SOUND PROPERTIES @@ -537,7 +537,7 @@ int adjust_volume(struct easycap *, int); * AUDIO FUNCTION PROTOTYPES */ /*---------------------------------------------------------------------------*/ -#if defined(EASYCAP_NEEDS_ALSA) +#ifndef CONFIG_EASYCAP_OSS int easycap_alsa_probe(struct easycap *); void easycap_alsa_complete(struct urb *); @@ -553,7 +553,7 @@ int easycap_alsa_trigger(struct snd_pcm_substream *, int); snd_pcm_uframes_t easycap_alsa_pointer(struct snd_pcm_substream *); struct page *easycap_alsa_page(struct snd_pcm_substream *, unsigned long); -#else +#else /* CONFIG_EASYCAP_OSS */ void easyoss_complete(struct urb *); ssize_t easyoss_read(struct file *, char __user *, size_t, loff_t *); int easyoss_open(struct inode *, struct file *); @@ -564,7 +564,8 @@ int easyoss_ioctl(struct inode *, struct file *, unsigned int, unsigned long); unsigned int easyoss_poll(struct file *, poll_table *); void easyoss_delete(struct kref *); -#endif /*EASYCAP_NEEDS_ALSA*/ +#endif /* !CONFIG_EASYCAP_OSS */ + int easycap_sound_setup(struct easycap *); int submit_audio_urbs(struct easycap *); int kill_audio_urbs(struct easycap *); @@ -715,13 +716,13 @@ extern struct easycap_format easycap_format[]; extern struct v4l2_queryctrl easycap_control[]; extern struct usb_driver easycap_usb_driver; extern struct easycap_dongle easycapdc60_dongle[]; -#if defined(EASYCAP_NEEDS_ALSA) +#ifndef CONFIG_EASYCAP_OSS extern struct snd_pcm_ops easycap_alsa_ops; extern struct snd_pcm_hardware easycap_pcm_hardware; extern struct snd_card *psnd_card; -#else +#else /* CONFIG_EASYCAP_OSS */ extern struct usb_class_driver easyoss_class; extern const struct file_operations easyoss_fops; -#endif /*EASYCAP_NEEDS_ALSA*/ +#endif /* !CONFIG_EASYCAP_OSS */ #endif /* !__EASYCAP_H__ */ diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 43891039e7bf..6995163aba9e 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -2517,7 +2517,7 @@ JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd); return 0; } /*****************************************************************************/ -#if !defined(EASYCAP_NEEDS_ALSA) +#ifdef CONFIG_EASYCAP_OSS /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \ (defined(EASYCAP_NEEDS_UNLOCKED_IOCTL))) @@ -2821,6 +2821,6 @@ default: { mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return 0; } -#endif /*EASYCAP_NEEDS_ALSA*/ +#endif /* CONFIG_EASYCAP_OSS */ /*****************************************************************************/ diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index cc1460b64b1e..d1d7a4831571 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -962,7 +962,7 @@ for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n", m * (0x01 << AUDIO_ISOC_ORDER)); /*---------------------------------------------------------------------------*/ -#if !defined(EASYCAP_NEEDS_ALSA) +#ifdef CONFIG_EASYCAP_OSS JOM(4, "freeing audio buffers.\n"); gone = 0; for (k = 0; k < peasycap->audio_buffer_page_many; k++) { @@ -974,7 +974,7 @@ for (k = 0; k < peasycap->audio_buffer_page_many; k++) { } } JOM(4, "easyoss_delete(): audio buffers freed: %i pages\n", gone); -#endif /*!EASYCAP_NEEDS_ALSA*/ +#endif /* CONFIG_EASYCAP_OSS */ /*---------------------------------------------------------------------------*/ JOM(4, "freeing easycap structure.\n"); allocation_video_urb = peasycap->allocation_video_urb; @@ -4350,7 +4350,7 @@ case 2: { INIT_LIST_HEAD(&(peasycap->urb_audio_head)); peasycap->purb_audio_head = &(peasycap->urb_audio_head); -#if !defined(EASYCAP_NEEDS_ALSA) +#ifdef CONFIG_EASYCAP_OSS JOM(4, "allocating an audio buffer\n"); JOM(4, ".... scattered over %i pages\n", peasycap->audio_buffer_page_many); @@ -4375,7 +4375,7 @@ case 2: { peasycap->audio_fill = 0; peasycap->audio_read = 0; JOM(4, "allocation of audio buffer done: %i pages\n", k); -#endif /*!EASYCAP_NEEDS_ALSA*/ +#endif /* CONFIG_EASYCAP_OSS */ /*---------------------------------------------------------------------------*/ JOM(4, "allocating %i isoc audio buffers of size %i\n", AUDIO_ISOC_BUFFER_MANY, peasycap->audio_isoc_buffer_size); @@ -4450,11 +4450,11 @@ case 2: { "peasycap->audio_isoc_buffer[.].pgo;\n"); JOM(4, " purb->transfer_buffer_length = %i;\n", peasycap->audio_isoc_buffer_size); -#if defined(EASYCAP_NEEDS_ALSA) - JOM(4, " purb->complete = easycap_alsa_complete;\n"); -#else +#ifdef CONFIG_EASYCAP_OSS JOM(4, " purb->complete = easyoss_complete;\n"); -#endif /*EASYCAP_NEEDS_ALSA*/ +#else /* CONFIG_EASYCAP_OSS */ + JOM(4, " purb->complete = easycap_alsa_complete;\n"); +#endif /* CONFIG_EASYCAP_OSS */ JOM(4, " purb->context = peasycap;\n"); JOM(4, " purb->start_frame = 0;\n"); JOM(4, " purb->number_of_packets = %i;\n", @@ -4477,11 +4477,11 @@ case 2: { purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo; purb->transfer_buffer_length = peasycap->audio_isoc_buffer_size; -#if defined(EASYCAP_NEEDS_ALSA) - purb->complete = easycap_alsa_complete; -#else +#ifdef CONFIG_EASYCAP_OSS purb->complete = easyoss_complete; -#endif /*EASYCAP_NEEDS_ALSA*/ +#else /* CONFIG_EASYCAP_OSS */ + purb->complete = easycap_alsa_complete; +#endif /* CONFIG_EASYCAP_OSS */ purb->context = peasycap; purb->start_frame = 0; purb->number_of_packets = peasycap->audio_isoc_framesperdesc; @@ -4504,7 +4504,7 @@ case 2: { * THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY. */ /*---------------------------------------------------------------------------*/ -#if defined(EASYCAP_NEEDS_ALSA) +#ifndef CONFIG_EASYCAP_OSS JOM(4, "initializing ALSA card\n"); rc = easycap_alsa_probe(peasycap); @@ -4518,7 +4518,7 @@ case 2: { (peasycap->registered_audio)++; } -#else /*EASYCAP_NEEDS_ALSA*/ +#else /* CONFIG_EASYCAP_OSS */ rc = usb_register_dev(pusb_interface, &easyoss_class); if (0 != rc) { SAY("ERROR: usb_register_dev() failed\n"); @@ -4536,7 +4536,7 @@ case 2: { */ /*---------------------------------------------------------------------------*/ SAM("easyoss attached to minor #%d\n", pusb_interface->minor); -#endif /*EASYCAP_NEEDS_ALSA*/ +#endif /* CONFIG_EASYCAP_OSS */ break; } @@ -4774,7 +4774,7 @@ case 2: { JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd); } else SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); -#if defined(EASYCAP_NEEDS_ALSA) +#ifndef CONFIG_EASYCAP_OSS @@ -4786,12 +4786,12 @@ case 2: { } -#else /*EASYCAP_NEEDS_ALSA*/ +#else /* CONFIG_EASYCAP_OSS */ usb_deregister_dev(pusb_interface, &easyoss_class); (peasycap->registered_audio)--; JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber); SAM("easyoss detached from minor #%d\n", minor); -#endif /*EASYCAP_NEEDS_ALSA*/ +#endif /* CONFIG_EASYCAP_OSS */ if (0 <= kd && DONGLE_MANY > kd) { mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index 05d9eed6eb04..07dd7aa95ea5 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -30,7 +30,7 @@ #include "easycap.h" -#if defined(EASYCAP_NEEDS_ALSA) +#ifndef CONFIG_EASYCAP_OSS /*--------------------------------------------------------------------------*/ /* * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE @@ -669,707 +669,7 @@ return vmalloc_to_page(pss->runtime->dma_area + offset); } /*****************************************************************************/ -#else /*!EASYCAP_NEEDS_ALSA*/ - -/*****************************************************************************/ -/**************************** **************************/ -/**************************** Open Sound System **************************/ -/**************************** **************************/ -/*****************************************************************************/ -/*--------------------------------------------------------------------------*/ -/* - * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE - */ -/*--------------------------------------------------------------------------*/ -const struct file_operations easyoss_fops = { - .owner = THIS_MODULE, - .open = easyoss_open, - .release = easyoss_release, -#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL) - .unlocked_ioctl = easyoss_ioctl_noinode, -#else - .ioctl = easyoss_ioctl, -#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/ - .read = easyoss_read, - .llseek = no_llseek, -}; -struct usb_class_driver easyoss_class = { -.name = "usb/easyoss%d", -.fops = &easyoss_fops, -.minor_base = USB_SKEL_MINOR_BASE, -}; -/*****************************************************************************/ -/*---------------------------------------------------------------------------*/ -/* - * ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE AUDIO BUFFERS - * PROVIDED peasycap->audio_idle IS ZERO. REGARDLESS OF THIS BEING TRUE, - * IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO. - */ -/*---------------------------------------------------------------------------*/ -void -easyoss_complete(struct urb *purb) -{ -struct easycap *peasycap; -struct data_buffer *paudio_buffer; -__u8 *p1, *p2; -__s16 s16; -int i, j, more, much, leap, rc; -#if defined(UPSAMPLE) -int k; -__s16 oldaudio, newaudio, delta; -#endif /*UPSAMPLE*/ - -JOT(16, "\n"); - -if (NULL == purb) { - SAY("ERROR: purb is NULL\n"); - return; -} -peasycap = purb->context; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return; -} -much = 0; -if (peasycap->audio_idle) { - JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n", - peasycap->audio_idle, peasycap->audio_isoc_streaming); - if (peasycap->audio_isoc_streaming) { - rc = usb_submit_urb(purb, GFP_ATOMIC); - if (rc) { - if (-ENODEV != rc && -ENOENT != rc) { - SAM("ERROR: while %i=audio_idle, " - "usb_submit_urb() failed with rc: -%s: %d\n", - peasycap->audio_idle, - strerror(rc), rc); - } - } - } -return; -} -/*---------------------------------------------------------------------------*/ -if (purb->status) { - if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) { - JOM(16, "urb status -ESHUTDOWN or -ENOENT\n"); - return; - } - SAM("ERROR: non-zero urb status: -%s: %d\n", - strerror(purb->status), purb->status); - goto resubmit; -} -/*---------------------------------------------------------------------------*/ -/* - * PROCEED HERE WHEN NO ERROR - */ -/*---------------------------------------------------------------------------*/ -#if defined(UPSAMPLE) -oldaudio = peasycap->oldaudio; -#endif /*UPSAMPLE*/ - -for (i = 0; i < purb->number_of_packets; i++) { - if (!purb->iso_frame_desc[i].status) { - - SAM("-%s\n", strerror(purb->iso_frame_desc[i].status)); - - more = purb->iso_frame_desc[i].actual_length; - -#if defined(TESTTONE) - if (!more) - more = purb->iso_frame_desc[i].length; -#endif - - if (!more) - peasycap->audio_mt++; - else { - if (peasycap->audio_mt) { - JOM(12, "%4i empty audio urb frames\n", - peasycap->audio_mt); - peasycap->audio_mt = 0; - } - - p1 = (__u8 *)(purb->transfer_buffer + - purb->iso_frame_desc[i].offset); - - leap = 0; - p1 += leap; - more -= leap; -/*---------------------------------------------------------------------------*/ -/* - * COPY more BYTES FROM ISOC BUFFER TO AUDIO BUFFER, - * CONVERTING 8-BIT MONO TO 16-BIT SIGNED LITTLE-ENDIAN SAMPLES IF NECESSARY - */ -/*---------------------------------------------------------------------------*/ - while (more) { - if (0 > more) { - SAM("MISTAKE: more is negative\n"); - return; - } - if (peasycap->audio_buffer_page_many <= - peasycap->audio_fill) { - SAM("ERROR: bad " - "peasycap->audio_fill\n"); - return; - } - - paudio_buffer = &peasycap->audio_buffer - [peasycap->audio_fill]; - if (PAGE_SIZE < (paudio_buffer->pto - - paudio_buffer->pgo)) { - SAM("ERROR: bad paudio_buffer->pto\n"); - return; - } - if (PAGE_SIZE == (paudio_buffer->pto - - paudio_buffer->pgo)) { - -#if defined(TESTTONE) - easyoss_testtone(peasycap, - peasycap->audio_fill); -#endif /*TESTTONE*/ - - paudio_buffer->pto = - paudio_buffer->pgo; - (peasycap->audio_fill)++; - if (peasycap-> - audio_buffer_page_many <= - peasycap->audio_fill) - peasycap->audio_fill = 0; - - JOM(8, "bumped peasycap->" - "audio_fill to %i\n", - peasycap->audio_fill); - - paudio_buffer = &peasycap-> - audio_buffer - [peasycap->audio_fill]; - paudio_buffer->pto = - paudio_buffer->pgo; - - if (!(peasycap->audio_fill % - peasycap-> - audio_pages_per_fragment)) { - JOM(12, "wakeup call on wq_" - "audio, %i=frag reading %i" - "=fragment fill\n", - (peasycap->audio_read / - peasycap-> - audio_pages_per_fragment), - (peasycap->audio_fill / - peasycap-> - audio_pages_per_fragment)); - wake_up_interruptible - (&(peasycap->wq_audio)); - } - } - - much = PAGE_SIZE - (int)(paudio_buffer->pto - - paudio_buffer->pgo); - - if (false == peasycap->microphone) { - if (much > more) - much = more; - - memcpy(paudio_buffer->pto, p1, much); - p1 += much; - more -= much; - } else { -#if defined(UPSAMPLE) - if (much % 16) - JOM(8, "MISTAKE? much" - " is not divisible by 16\n"); - if (much > (16 * - more)) - much = 16 * - more; - p2 = (__u8 *)paudio_buffer->pto; - - for (j = 0; j < (much/16); j++) { - newaudio = ((int) *p1) - 128; - newaudio = 128 * - newaudio; - - delta = (newaudio - oldaudio) - / 4; - s16 = oldaudio + delta; - - for (k = 0; k < 4; k++) { - *p2 = (0x00FF & s16); - *(p2 + 1) = (0xFF00 & - s16) >> 8; - p2 += 2; - *p2 = (0x00FF & s16); - *(p2 + 1) = (0xFF00 & - s16) >> 8; - p2 += 2; - - s16 += delta; - } - p1++; - more--; - oldaudio = s16; - } -#else /*!UPSAMPLE*/ - if (much > (2 * more)) - much = 2 * more; - p2 = (__u8 *)paudio_buffer->pto; - - for (j = 0; j < (much / 2); j++) { - s16 = ((int) *p1) - 128; - s16 = 128 * - s16; - *p2 = (0x00FF & s16); - *(p2 + 1) = (0xFF00 & s16) >> - 8; - p1++; p2 += 2; - more--; - } -#endif /*UPSAMPLE*/ - } - (paudio_buffer->pto) += much; - } - } - } else { - JOM(12, "discarding audio samples because " - "%i=purb->iso_frame_desc[i].status\n", - purb->iso_frame_desc[i].status); - } - -#if defined(UPSAMPLE) -peasycap->oldaudio = oldaudio; -#endif /*UPSAMPLE*/ - -} -/*---------------------------------------------------------------------------*/ -/* - * RESUBMIT THIS URB - */ -/*---------------------------------------------------------------------------*/ -resubmit: -if (peasycap->audio_isoc_streaming) { - rc = usb_submit_urb(purb, GFP_ATOMIC); - if (0 != rc) { - if (-ENODEV != rc && -ENOENT != rc) { - SAM("ERROR: while %i=audio_idle, " - "usb_submit_urb() failed " - "with rc: -%s: %d\n", peasycap->audio_idle, - strerror(rc), rc); - } - } -} -return; -} -/*****************************************************************************/ -/*---------------------------------------------------------------------------*/ -/* - * THE AUDIO URBS ARE SUBMITTED AT THIS EARLY STAGE SO THAT IT IS POSSIBLE TO - * STREAM FROM /dev/easyoss1 WITH SIMPLE PROGRAMS SUCH AS cat WHICH DO NOT - * HAVE AN IOCTL INTERFACE. - */ -/*---------------------------------------------------------------------------*/ -int -easyoss_open(struct inode *inode, struct file *file) -{ -struct usb_interface *pusb_interface; -struct easycap *peasycap; -int subminor; -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) -struct v4l2_device *pv4l2_device; -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -JOT(4, "begins\n"); - -subminor = iminor(inode); - -pusb_interface = usb_find_interface(&easycap_usb_driver, subminor); -if (NULL == pusb_interface) { - SAY("ERROR: pusb_interface is NULL\n"); - SAY("ending unsuccessfully\n"); - return -1; -} -peasycap = usb_get_intfdata(pusb_interface); -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - SAY("ending unsuccessfully\n"); - return -1; -} -/*---------------------------------------------------------------------------*/ -#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) -# -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#else -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) -/*---------------------------------------------------------------------------*/ -/* - * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS - * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(), - * REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE. - * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED. -*/ -/*---------------------------------------------------------------------------*/ -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - pv4l2_device = usb_get_intfdata(pusb_interface); - if ((struct v4l2_device *)NULL == pv4l2_device) { - SAY("ERROR: pv4l2_device is NULL\n"); - return -EFAULT; - } - peasycap = (struct easycap *) - container_of(pv4l2_device, struct easycap, v4l2_device); -} -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ -# -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*---------------------------------------------------------------------------*/ -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); - return -EFAULT; -} -/*---------------------------------------------------------------------------*/ - -file->private_data = peasycap; - -if (0 != easycap_sound_setup(peasycap)) { - ; - ; -} -return 0; -} -/*****************************************************************************/ -int -easyoss_release(struct inode *inode, struct file *file) -{ -struct easycap *peasycap; - -JOT(4, "begins\n"); - -peasycap = file->private_data; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL.\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); - return -EFAULT; -} -if (0 != kill_audio_urbs(peasycap)) { - SAM("ERROR: kill_audio_urbs() failed\n"); - return -EFAULT; -} -JOM(4, "ending successfully\n"); -return 0; -} -/*****************************************************************************/ -ssize_t -easyoss_read(struct file *file, char __user *puserspacebuffer, - size_t kount, loff_t *poff) -{ -struct timeval timeval; -long long int above, below, mean; -struct signed_div_result sdr; -unsigned char *p0; -long int kount1, more, rc, l0, lm; -int fragment, kd; -struct easycap *peasycap; -struct data_buffer *pdata_buffer; -size_t szret; - -/*---------------------------------------------------------------------------*/ -/* - * DO A BLOCKING READ TO TRANSFER DATA TO USER SPACE. - * - ****************************************************************************** - ***** N.B. IF THIS FUNCTION RETURNS 0, NOTHING IS SEEN IN USER SPACE. ****** - ***** THIS CONDITION SIGNIFIES END-OF-FILE. ****** - ****************************************************************************** - */ -/*---------------------------------------------------------------------------*/ - -JOT(8, "%5i=kount %5i=*poff\n", (int)kount, (int)(*poff)); - -if (NULL == file) { - SAY("ERROR: file is NULL\n"); - return -ERESTARTSYS; -} -peasycap = file->private_data; -if (NULL == peasycap) { - SAY("ERROR in easyoss_read(): peasycap is NULL\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -kd = isdongle(peasycap); -if (0 <= kd && DONGLE_MANY > kd) { - if (mutex_lock_interruptible(&(easycapdc60_dongle[kd].mutex_audio))) { - SAY("ERROR: " - "cannot lock easycapdc60_dongle[%i].mutex_audio\n", kd); - return -ERESTARTSYS; - } - JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd); -/*---------------------------------------------------------------------------*/ -/* - * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap, - * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. - * IF NECESSARY, BAIL OUT. -*/ -/*---------------------------------------------------------------------------*/ - if (kd != isdongle(peasycap)) - return -ERESTARTSYS; - if (NULL == file) { - SAY("ERROR: file is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } - peasycap = file->private_data; - if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", - (unsigned long int) peasycap); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } - if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } -} else { -/*---------------------------------------------------------------------------*/ -/* - * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE - * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT. -*/ -/*---------------------------------------------------------------------------*/ - return -ERESTARTSYS; -} -/*---------------------------------------------------------------------------*/ -if (file->f_flags & O_NONBLOCK) - JOT(16, "NONBLOCK kount=%i, *poff=%i\n", (int)kount, (int)(*poff)); -else - JOT(8, "BLOCKING kount=%i, *poff=%i\n", (int)kount, (int)(*poff)); - -if ((0 > peasycap->audio_read) || - (peasycap->audio_buffer_page_many <= peasycap->audio_read)) { - SAM("ERROR: peasycap->audio_read out of range\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; -} -pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; -if ((struct data_buffer *)NULL == pdata_buffer) { - SAM("ERROR: pdata_buffer is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; -} -JOM(12, "before wait, %i=frag read %i=frag fill\n", - (peasycap->audio_read / peasycap->audio_pages_per_fragment), - (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); -fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment); -while ((fragment == (peasycap->audio_fill / - peasycap->audio_pages_per_fragment)) || - (0 == (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))) { - if (file->f_flags & O_NONBLOCK) { - JOM(16, "returning -EAGAIN as instructed\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EAGAIN; - } - rc = wait_event_interruptible(peasycap->wq_audio, - (peasycap->audio_idle || peasycap->audio_eof || - ((fragment != (peasycap->audio_fill / - peasycap->audio_pages_per_fragment)) && - (0 < (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))))); - if (0 != rc) { - SAM("aborted by signal\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } - if (peasycap->audio_eof) { - JOM(8, "returning 0 because %i=audio_eof\n", - peasycap->audio_eof); - kill_audio_urbs(peasycap); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return 0; - } - if (peasycap->audio_idle) { - JOM(16, "returning 0 because %i=audio_idle\n", - peasycap->audio_idle); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return 0; - } - if (!peasycap->audio_isoc_streaming) { - JOM(16, "returning 0 because audio urbs not streaming\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return 0; - } -} -JOM(12, "after wait, %i=frag read %i=frag fill\n", - (peasycap->audio_read / peasycap->audio_pages_per_fragment), - (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); -szret = (size_t)0; -fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment); -while (fragment == (peasycap->audio_read / - peasycap->audio_pages_per_fragment)) { - if (NULL == pdata_buffer->pgo) { - SAM("ERROR: pdata_buffer->pgo is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - if (NULL == pdata_buffer->pto) { - SAM("ERROR: pdata_buffer->pto is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo); - if (0 > kount1) { - SAM("MISTAKE: kount1 is negative\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } - if (!kount1) { - (peasycap->audio_read)++; - if (peasycap->audio_buffer_page_many <= peasycap->audio_read) - peasycap->audio_read = 0; - JOM(12, "bumped peasycap->audio_read to %i\n", - peasycap->audio_read); - - if (fragment != (peasycap->audio_read / - peasycap->audio_pages_per_fragment)) - break; - - if ((0 > peasycap->audio_read) || - (peasycap->audio_buffer_page_many <= - peasycap->audio_read)) { - SAM("ERROR: peasycap->audio_read out of range\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; - if ((struct data_buffer *)NULL == pdata_buffer) { - SAM("ERROR: pdata_buffer is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - if (NULL == pdata_buffer->pgo) { - SAM("ERROR: pdata_buffer->pgo is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - if (NULL == pdata_buffer->pto) { - SAM("ERROR: pdata_buffer->pto is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo); - } - JOM(12, "ready to send %li bytes\n", (long int) kount1); - JOM(12, "still to send %li bytes\n", (long int) kount); - more = kount1; - if (more > kount) - more = kount; - JOM(12, "agreed to send %li bytes from page %i\n", - more, peasycap->audio_read); - if (!more) - break; - -/*---------------------------------------------------------------------------*/ -/* - * ACCUMULATE DYNAMIC-RANGE INFORMATION - */ -/*---------------------------------------------------------------------------*/ - p0 = (unsigned char *)pdata_buffer->pgo; l0 = 0; lm = more/2; - while (l0 < lm) { - SUMMER(p0, &peasycap->audio_sample, &peasycap->audio_niveau, - &peasycap->audio_square); l0++; p0 += 2; - } -/*---------------------------------------------------------------------------*/ - rc = copy_to_user(puserspacebuffer, pdata_buffer->pto, more); - if (0 != rc) { - SAM("ERROR: copy_to_user() returned %li\n", rc); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - *poff += (loff_t)more; - szret += (size_t)more; - pdata_buffer->pto += more; - puserspacebuffer += more; - kount -= (size_t)more; -} -JOM(12, "after read, %i=frag read %i=frag fill\n", - (peasycap->audio_read / peasycap->audio_pages_per_fragment), - (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); -if (kount < 0) { - SAM("MISTAKE: %li=kount %li=szret\n", - (long int)kount, (long int)szret); -} -/*---------------------------------------------------------------------------*/ -/* - * CALCULATE DYNAMIC RANGE FOR (VAPOURWARE) AUTOMATIC VOLUME CONTROL - */ -/*---------------------------------------------------------------------------*/ -if (peasycap->audio_sample) { - below = peasycap->audio_sample; - above = peasycap->audio_square; - sdr = signed_div(above, below); - above = sdr.quotient; - mean = peasycap->audio_niveau; - sdr = signed_div(mean, peasycap->audio_sample); - - JOM(8, "%8lli=mean %8lli=meansquare after %lli samples, =>\n", - sdr.quotient, above, peasycap->audio_sample); - - sdr = signed_div(above, 32768); - JOM(8, "audio dynamic range is roughly %lli\n", sdr.quotient); -} -/*---------------------------------------------------------------------------*/ -/* - * UPDATE THE AUDIO CLOCK - */ -/*---------------------------------------------------------------------------*/ -do_gettimeofday(&timeval); -if (!peasycap->timeval1.tv_sec) { - peasycap->audio_bytes = 0; - peasycap->timeval3 = timeval; - peasycap->timeval1 = peasycap->timeval3; - sdr.quotient = 192000; -} else { - peasycap->audio_bytes += (long long int) szret; - below = ((long long int)(1000000)) * - ((long long int)(timeval.tv_sec - - peasycap->timeval3.tv_sec)) + - (long long int)(timeval.tv_usec - peasycap->timeval3.tv_usec); - above = 1000000 * ((long long int) peasycap->audio_bytes); - - if (below) - sdr = signed_div(above, below); - else - sdr.quotient = 192000; -} -JOM(8, "audio streaming at %lli bytes/second\n", sdr.quotient); -peasycap->dnbydt = sdr.quotient; - -mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); -JOM(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd); -JOM(8, "returning %li\n", (long int)szret); -return szret; -} -/*****************************************************************************/ - -#endif /*!EASYCAP_NEEDS_ALSA*/ +#endif /*! CONFIG_EASYCAP_OSS */ /*****************************************************************************/ /*****************************************************************************/ @@ -1484,11 +784,11 @@ if (!peasycap->audio_isoc_streaming) { peasycap->audio_isoc_buffer[isbuf].pgo; purb->transfer_buffer_length = peasycap->audio_isoc_buffer_size; -#if defined(EASYCAP_NEEDS_ALSA) - purb->complete = easycap_alsa_complete; -#else +#ifdef CONFIG_EASYCAP_OSS purb->complete = easyoss_complete; -#endif /*EASYCAP_NEEDS_ALSA*/ +#else /* CONFIG_EASYCAP_OSS */ + purb->complete = easycap_alsa_complete; +#endif /* CONFIG_EASYCAP_OSS */ purb->context = peasycap; purb->start_frame = 0; purb->number_of_packets = diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c new file mode 100644 index 000000000000..3f85cc3b060b --- /dev/null +++ b/drivers/staging/easycap/easycap_sound_oss.c @@ -0,0 +1,730 @@ +/****************************************************************************** +* * +* easycap_sound.c * +* * +* Audio driver for EasyCAP USB2.0 Video Capture Device DC60 * +* * +* * +******************************************************************************/ +/* + * + * Copyright (C) 2010 R.M. Thomas + * + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ +/*****************************************************************************/ + +#include "easycap.h" + +/*****************************************************************************/ +/**************************** **************************/ +/**************************** Open Sound System **************************/ +/**************************** **************************/ +/*****************************************************************************/ +/*--------------------------------------------------------------------------*/ +/* + * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE + */ +/*--------------------------------------------------------------------------*/ +const struct file_operations easyoss_fops = { + .owner = THIS_MODULE, + .open = easyoss_open, + .release = easyoss_release, +#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL) + .unlocked_ioctl = easyoss_ioctl_noinode, +#else + .ioctl = easyoss_ioctl, +#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/ + .read = easyoss_read, + .llseek = no_llseek, +}; +struct usb_class_driver easyoss_class = { +.name = "usb/easyoss%d", +.fops = &easyoss_fops, +.minor_base = USB_SKEL_MINOR_BASE, +}; +/*****************************************************************************/ +/*---------------------------------------------------------------------------*/ +/* + * ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE AUDIO BUFFERS + * PROVIDED peasycap->audio_idle IS ZERO. REGARDLESS OF THIS BEING TRUE, + * IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO. + */ +/*---------------------------------------------------------------------------*/ +void +easyoss_complete(struct urb *purb) +{ +struct easycap *peasycap; +struct data_buffer *paudio_buffer; +__u8 *p1, *p2; +__s16 s16; +int i, j, more, much, leap, rc; +#if defined(UPSAMPLE) +int k; +__s16 oldaudio, newaudio, delta; +#endif /*UPSAMPLE*/ + +JOT(16, "\n"); + +if (NULL == purb) { + SAY("ERROR: purb is NULL\n"); + return; +} +peasycap = purb->context; +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return; +} +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return; +} +much = 0; +if (peasycap->audio_idle) { + JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n", + peasycap->audio_idle, peasycap->audio_isoc_streaming); + if (peasycap->audio_isoc_streaming) { + rc = usb_submit_urb(purb, GFP_ATOMIC); + if (rc) { + if (-ENODEV != rc && -ENOENT != rc) { + SAM("ERROR: while %i=audio_idle, " + "usb_submit_urb() failed with rc: -%s: %d\n", + peasycap->audio_idle, + strerror(rc), rc); + } + } + } +return; +} +/*---------------------------------------------------------------------------*/ +if (purb->status) { + if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) { + JOM(16, "urb status -ESHUTDOWN or -ENOENT\n"); + return; + } + SAM("ERROR: non-zero urb status: -%s: %d\n", + strerror(purb->status), purb->status); + goto resubmit; +} +/*---------------------------------------------------------------------------*/ +/* + * PROCEED HERE WHEN NO ERROR + */ +/*---------------------------------------------------------------------------*/ +#if defined(UPSAMPLE) +oldaudio = peasycap->oldaudio; +#endif /*UPSAMPLE*/ + +for (i = 0; i < purb->number_of_packets; i++) { + if (!purb->iso_frame_desc[i].status) { + + SAM("-%s\n", strerror(purb->iso_frame_desc[i].status)); + + more = purb->iso_frame_desc[i].actual_length; + +#if defined(TESTTONE) + if (!more) + more = purb->iso_frame_desc[i].length; +#endif + + if (!more) + peasycap->audio_mt++; + else { + if (peasycap->audio_mt) { + JOM(12, "%4i empty audio urb frames\n", + peasycap->audio_mt); + peasycap->audio_mt = 0; + } + + p1 = (__u8 *)(purb->transfer_buffer + + purb->iso_frame_desc[i].offset); + + leap = 0; + p1 += leap; + more -= leap; +/*---------------------------------------------------------------------------*/ +/* + * COPY more BYTES FROM ISOC BUFFER TO AUDIO BUFFER, + * CONVERTING 8-BIT MONO TO 16-BIT SIGNED LITTLE-ENDIAN SAMPLES IF NECESSARY + */ +/*---------------------------------------------------------------------------*/ + while (more) { + if (0 > more) { + SAM("MISTAKE: more is negative\n"); + return; + } + if (peasycap->audio_buffer_page_many <= + peasycap->audio_fill) { + SAM("ERROR: bad " + "peasycap->audio_fill\n"); + return; + } + + paudio_buffer = &peasycap->audio_buffer + [peasycap->audio_fill]; + if (PAGE_SIZE < (paudio_buffer->pto - + paudio_buffer->pgo)) { + SAM("ERROR: bad paudio_buffer->pto\n"); + return; + } + if (PAGE_SIZE == (paudio_buffer->pto - + paudio_buffer->pgo)) { + +#if defined(TESTTONE) + easyoss_testtone(peasycap, + peasycap->audio_fill); +#endif /*TESTTONE*/ + + paudio_buffer->pto = + paudio_buffer->pgo; + (peasycap->audio_fill)++; + if (peasycap-> + audio_buffer_page_many <= + peasycap->audio_fill) + peasycap->audio_fill = 0; + + JOM(8, "bumped peasycap->" + "audio_fill to %i\n", + peasycap->audio_fill); + + paudio_buffer = &peasycap-> + audio_buffer + [peasycap->audio_fill]; + paudio_buffer->pto = + paudio_buffer->pgo; + + if (!(peasycap->audio_fill % + peasycap-> + audio_pages_per_fragment)) { + JOM(12, "wakeup call on wq_" + "audio, %i=frag reading %i" + "=fragment fill\n", + (peasycap->audio_read / + peasycap-> + audio_pages_per_fragment), + (peasycap->audio_fill / + peasycap-> + audio_pages_per_fragment)); + wake_up_interruptible + (&(peasycap->wq_audio)); + } + } + + much = PAGE_SIZE - (int)(paudio_buffer->pto - + paudio_buffer->pgo); + + if (false == peasycap->microphone) { + if (much > more) + much = more; + + memcpy(paudio_buffer->pto, p1, much); + p1 += much; + more -= much; + } else { +#if defined(UPSAMPLE) + if (much % 16) + JOM(8, "MISTAKE? much" + " is not divisible by 16\n"); + if (much > (16 * + more)) + much = 16 * + more; + p2 = (__u8 *)paudio_buffer->pto; + + for (j = 0; j < (much/16); j++) { + newaudio = ((int) *p1) - 128; + newaudio = 128 * + newaudio; + + delta = (newaudio - oldaudio) + / 4; + s16 = oldaudio + delta; + + for (k = 0; k < 4; k++) { + *p2 = (0x00FF & s16); + *(p2 + 1) = (0xFF00 & + s16) >> 8; + p2 += 2; + *p2 = (0x00FF & s16); + *(p2 + 1) = (0xFF00 & + s16) >> 8; + p2 += 2; + + s16 += delta; + } + p1++; + more--; + oldaudio = s16; + } +#else /*!UPSAMPLE*/ + if (much > (2 * more)) + much = 2 * more; + p2 = (__u8 *)paudio_buffer->pto; + + for (j = 0; j < (much / 2); j++) { + s16 = ((int) *p1) - 128; + s16 = 128 * + s16; + *p2 = (0x00FF & s16); + *(p2 + 1) = (0xFF00 & s16) >> + 8; + p1++; p2 += 2; + more--; + } +#endif /*UPSAMPLE*/ + } + (paudio_buffer->pto) += much; + } + } + } else { + JOM(12, "discarding audio samples because " + "%i=purb->iso_frame_desc[i].status\n", + purb->iso_frame_desc[i].status); + } + +#if defined(UPSAMPLE) +peasycap->oldaudio = oldaudio; +#endif /*UPSAMPLE*/ + +} +/*---------------------------------------------------------------------------*/ +/* + * RESUBMIT THIS URB + */ +/*---------------------------------------------------------------------------*/ +resubmit: +if (peasycap->audio_isoc_streaming) { + rc = usb_submit_urb(purb, GFP_ATOMIC); + if (0 != rc) { + if (-ENODEV != rc && -ENOENT != rc) { + SAM("ERROR: while %i=audio_idle, " + "usb_submit_urb() failed " + "with rc: -%s: %d\n", peasycap->audio_idle, + strerror(rc), rc); + } + } +} +return; +} +/*****************************************************************************/ +/*---------------------------------------------------------------------------*/ +/* + * THE AUDIO URBS ARE SUBMITTED AT THIS EARLY STAGE SO THAT IT IS POSSIBLE TO + * STREAM FROM /dev/easyoss1 WITH SIMPLE PROGRAMS SUCH AS cat WHICH DO NOT + * HAVE AN IOCTL INTERFACE. + */ +/*---------------------------------------------------------------------------*/ +int +easyoss_open(struct inode *inode, struct file *file) +{ +struct usb_interface *pusb_interface; +struct easycap *peasycap; +int subminor; +/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#if defined(EASYCAP_IS_VIDEODEV_CLIENT) +#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +struct v4l2_device *pv4l2_device; +#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ +#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + +JOT(4, "begins\n"); + +subminor = iminor(inode); + +pusb_interface = usb_find_interface(&easycap_usb_driver, subminor); +if (NULL == pusb_interface) { + SAY("ERROR: pusb_interface is NULL\n"); + SAY("ending unsuccessfully\n"); + return -1; +} +peasycap = usb_get_intfdata(pusb_interface); +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + SAY("ending unsuccessfully\n"); + return -1; +} +/*---------------------------------------------------------------------------*/ +#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) +# +/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#else +#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +/*---------------------------------------------------------------------------*/ +/* + * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS + * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(), + * REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE. + * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED. +*/ +/*---------------------------------------------------------------------------*/ +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + pv4l2_device = usb_get_intfdata(pusb_interface); + if ((struct v4l2_device *)NULL == pv4l2_device) { + SAY("ERROR: pv4l2_device is NULL\n"); + return -EFAULT; + } + peasycap = (struct easycap *) + container_of(pv4l2_device, struct easycap, v4l2_device); +} +#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ +# +#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +/*---------------------------------------------------------------------------*/ +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + return -EFAULT; +} +/*---------------------------------------------------------------------------*/ + +file->private_data = peasycap; + +if (0 != easycap_sound_setup(peasycap)) { + ; + ; +} +return 0; +} +/*****************************************************************************/ +int +easyoss_release(struct inode *inode, struct file *file) +{ +struct easycap *peasycap; + +JOT(4, "begins\n"); + +peasycap = file->private_data; +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL.\n"); + return -EFAULT; +} +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + return -EFAULT; +} +if (0 != kill_audio_urbs(peasycap)) { + SAM("ERROR: kill_audio_urbs() failed\n"); + return -EFAULT; +} +JOM(4, "ending successfully\n"); +return 0; +} +/*****************************************************************************/ +ssize_t +easyoss_read(struct file *file, char __user *puserspacebuffer, + size_t kount, loff_t *poff) +{ +struct timeval timeval; +long long int above, below, mean; +struct signed_div_result sdr; +unsigned char *p0; +long int kount1, more, rc, l0, lm; +int fragment, kd; +struct easycap *peasycap; +struct data_buffer *pdata_buffer; +size_t szret; + +/*---------------------------------------------------------------------------*/ +/* + * DO A BLOCKING READ TO TRANSFER DATA TO USER SPACE. + * + ****************************************************************************** + ***** N.B. IF THIS FUNCTION RETURNS 0, NOTHING IS SEEN IN USER SPACE. ****** + ***** THIS CONDITION SIGNIFIES END-OF-FILE. ****** + ****************************************************************************** + */ +/*---------------------------------------------------------------------------*/ + +JOT(8, "%5i=kount %5i=*poff\n", (int)kount, (int)(*poff)); + +if (NULL == file) { + SAY("ERROR: file is NULL\n"); + return -ERESTARTSYS; +} +peasycap = file->private_data; +if (NULL == peasycap) { + SAY("ERROR in easyoss_read(): peasycap is NULL\n"); + return -EFAULT; +} +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + return -EFAULT; +} +if (NULL == peasycap->pusb_device) { + SAY("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; +} +kd = isdongle(peasycap); +if (0 <= kd && DONGLE_MANY > kd) { + if (mutex_lock_interruptible(&(easycapdc60_dongle[kd].mutex_audio))) { + SAY("ERROR: " + "cannot lock easycapdc60_dongle[%i].mutex_audio\n", kd); + return -ERESTARTSYS; + } + JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd); +/*---------------------------------------------------------------------------*/ +/* + * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap, + * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. + * IF NECESSARY, BAIL OUT. +*/ +/*---------------------------------------------------------------------------*/ + if (kd != isdongle(peasycap)) + return -ERESTARTSYS; + if (NULL == file) { + SAY("ERROR: file is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + peasycap = file->private_data; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: 0x%08lX\n", + (unsigned long int) peasycap); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } +} else { +/*---------------------------------------------------------------------------*/ +/* + * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE + * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT. +*/ +/*---------------------------------------------------------------------------*/ + return -ERESTARTSYS; +} +/*---------------------------------------------------------------------------*/ +if (file->f_flags & O_NONBLOCK) + JOT(16, "NONBLOCK kount=%i, *poff=%i\n", (int)kount, (int)(*poff)); +else + JOT(8, "BLOCKING kount=%i, *poff=%i\n", (int)kount, (int)(*poff)); + +if ((0 > peasycap->audio_read) || + (peasycap->audio_buffer_page_many <= peasycap->audio_read)) { + SAM("ERROR: peasycap->audio_read out of range\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; +} +pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; +if ((struct data_buffer *)NULL == pdata_buffer) { + SAM("ERROR: pdata_buffer is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; +} +JOM(12, "before wait, %i=frag read %i=frag fill\n", + (peasycap->audio_read / peasycap->audio_pages_per_fragment), + (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); +fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment); +while ((fragment == (peasycap->audio_fill / + peasycap->audio_pages_per_fragment)) || + (0 == (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))) { + if (file->f_flags & O_NONBLOCK) { + JOM(16, "returning -EAGAIN as instructed\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EAGAIN; + } + rc = wait_event_interruptible(peasycap->wq_audio, + (peasycap->audio_idle || peasycap->audio_eof || + ((fragment != (peasycap->audio_fill / + peasycap->audio_pages_per_fragment)) && + (0 < (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))))); + if (0 != rc) { + SAM("aborted by signal\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + if (peasycap->audio_eof) { + JOM(8, "returning 0 because %i=audio_eof\n", + peasycap->audio_eof); + kill_audio_urbs(peasycap); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return 0; + } + if (peasycap->audio_idle) { + JOM(16, "returning 0 because %i=audio_idle\n", + peasycap->audio_idle); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return 0; + } + if (!peasycap->audio_isoc_streaming) { + JOM(16, "returning 0 because audio urbs not streaming\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return 0; + } +} +JOM(12, "after wait, %i=frag read %i=frag fill\n", + (peasycap->audio_read / peasycap->audio_pages_per_fragment), + (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); +szret = (size_t)0; +fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment); +while (fragment == (peasycap->audio_read / + peasycap->audio_pages_per_fragment)) { + if (NULL == pdata_buffer->pgo) { + SAM("ERROR: pdata_buffer->pgo is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + if (NULL == pdata_buffer->pto) { + SAM("ERROR: pdata_buffer->pto is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo); + if (0 > kount1) { + SAM("MISTAKE: kount1 is negative\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + if (!kount1) { + (peasycap->audio_read)++; + if (peasycap->audio_buffer_page_many <= peasycap->audio_read) + peasycap->audio_read = 0; + JOM(12, "bumped peasycap->audio_read to %i\n", + peasycap->audio_read); + + if (fragment != (peasycap->audio_read / + peasycap->audio_pages_per_fragment)) + break; + + if ((0 > peasycap->audio_read) || + (peasycap->audio_buffer_page_many <= + peasycap->audio_read)) { + SAM("ERROR: peasycap->audio_read out of range\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; + if ((struct data_buffer *)NULL == pdata_buffer) { + SAM("ERROR: pdata_buffer is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + if (NULL == pdata_buffer->pgo) { + SAM("ERROR: pdata_buffer->pgo is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + if (NULL == pdata_buffer->pto) { + SAM("ERROR: pdata_buffer->pto is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo); + } + JOM(12, "ready to send %li bytes\n", (long int) kount1); + JOM(12, "still to send %li bytes\n", (long int) kount); + more = kount1; + if (more > kount) + more = kount; + JOM(12, "agreed to send %li bytes from page %i\n", + more, peasycap->audio_read); + if (!more) + break; + +/*---------------------------------------------------------------------------*/ +/* + * ACCUMULATE DYNAMIC-RANGE INFORMATION + */ +/*---------------------------------------------------------------------------*/ + p0 = (unsigned char *)pdata_buffer->pgo; l0 = 0; lm = more/2; + while (l0 < lm) { + SUMMER(p0, &peasycap->audio_sample, &peasycap->audio_niveau, + &peasycap->audio_square); l0++; p0 += 2; + } +/*---------------------------------------------------------------------------*/ + rc = copy_to_user(puserspacebuffer, pdata_buffer->pto, more); + if (0 != rc) { + SAM("ERROR: copy_to_user() returned %li\n", rc); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + *poff += (loff_t)more; + szret += (size_t)more; + pdata_buffer->pto += more; + puserspacebuffer += more; + kount -= (size_t)more; +} +JOM(12, "after read, %i=frag read %i=frag fill\n", + (peasycap->audio_read / peasycap->audio_pages_per_fragment), + (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); +if (kount < 0) { + SAM("MISTAKE: %li=kount %li=szret\n", + (long int)kount, (long int)szret); +} +/*---------------------------------------------------------------------------*/ +/* + * CALCULATE DYNAMIC RANGE FOR (VAPOURWARE) AUTOMATIC VOLUME CONTROL + */ +/*---------------------------------------------------------------------------*/ +if (peasycap->audio_sample) { + below = peasycap->audio_sample; + above = peasycap->audio_square; + sdr = signed_div(above, below); + above = sdr.quotient; + mean = peasycap->audio_niveau; + sdr = signed_div(mean, peasycap->audio_sample); + + JOM(8, "%8lli=mean %8lli=meansquare after %lli samples, =>\n", + sdr.quotient, above, peasycap->audio_sample); + + sdr = signed_div(above, 32768); + JOM(8, "audio dynamic range is roughly %lli\n", sdr.quotient); +} +/*---------------------------------------------------------------------------*/ +/* + * UPDATE THE AUDIO CLOCK + */ +/*---------------------------------------------------------------------------*/ +do_gettimeofday(&timeval); +if (!peasycap->timeval1.tv_sec) { + peasycap->audio_bytes = 0; + peasycap->timeval3 = timeval; + peasycap->timeval1 = peasycap->timeval3; + sdr.quotient = 192000; +} else { + peasycap->audio_bytes += (long long int) szret; + below = ((long long int)(1000000)) * + ((long long int)(timeval.tv_sec - + peasycap->timeval3.tv_sec)) + + (long long int)(timeval.tv_usec - peasycap->timeval3.tv_usec); + above = 1000000 * ((long long int) peasycap->audio_bytes); + + if (below) + sdr = signed_div(above, below); + else + sdr.quotient = 192000; +} +JOM(8, "audio streaming at %lli bytes/second\n", sdr.quotient); +peasycap->dnbydt = sdr.quotient; + +mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); +JOM(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd); +JOM(8, "returning %li\n", (long int)szret); +return szret; +} +/*****************************************************************************/ + -- cgit v1.2.3 From 1945f939b6b3d2ea7a0ac143f85fd288a50e0516 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 24 Jan 2011 17:08:21 +0200 Subject: staging/easycap: make oss ops function static in sound_oss.c 1. make oss ops function static 2. move around code so to avid forward declarations 3. move OSS ioclts from ioctl.c to sound_oss.c Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 10 +- drivers/staging/easycap/easycap_ioctl.c | 307 ------------------------ drivers/staging/easycap/easycap_sound_oss.c | 350 ++++++++++++++++++++++++++-- 3 files changed, 327 insertions(+), 340 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 55ff0d571cfd..63722b1578d8 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -555,15 +555,7 @@ struct page *easycap_alsa_page(struct snd_pcm_substream *, unsigned long); #else /* CONFIG_EASYCAP_OSS */ void easyoss_complete(struct urb *); -ssize_t easyoss_read(struct file *, char __user *, size_t, loff_t *); -int easyoss_open(struct inode *, struct file *); -int easyoss_release(struct inode *, struct file *); -long easyoss_ioctl_noinode(struct file *, unsigned int, - unsigned long); -int easyoss_ioctl(struct inode *, struct file *, unsigned int, - unsigned long); -unsigned int easyoss_poll(struct file *, poll_table *); -void easyoss_delete(struct kref *); + #endif /* !CONFIG_EASYCAP_OSS */ int easycap_sound_setup(struct easycap *); diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 6995163aba9e..222192457364 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -2517,310 +2517,3 @@ JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd); return 0; } /*****************************************************************************/ -#ifdef CONFIG_EASYCAP_OSS -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \ - (defined(EASYCAP_NEEDS_UNLOCKED_IOCTL))) -long -easyoss_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) { - return (long)easyoss_ioctl((struct inode *)NULL, file, cmd, arg); -} -#endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*---------------------------------------------------------------------------*/ -int -easyoss_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ -struct easycap *peasycap; -struct usb_device *p; -int kd; - -if (NULL == file) { - SAY("ERROR: file is NULL\n"); - return -ERESTARTSYS; -} -peasycap = file->private_data; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL.\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; -} -p = peasycap->pusb_device; -if (NULL == p) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -kd = isdongle(peasycap); -if (0 <= kd && DONGLE_MANY > kd) { - if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_audio)) { - SAY("ERROR: cannot lock " - "easycapdc60_dongle[%i].mutex_audio\n", kd); - return -ERESTARTSYS; - } - JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd); -/*---------------------------------------------------------------------------*/ -/* - * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap, - * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. - * IF NECESSARY, BAIL OUT. -*/ -/*---------------------------------------------------------------------------*/ - if (kd != isdongle(peasycap)) - return -ERESTARTSYS; - if (NULL == file) { - SAY("ERROR: file is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } - peasycap = file->private_data; - if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - p = peasycap->pusb_device; - if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } -} else { -/*---------------------------------------------------------------------------*/ -/* - * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE - * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT. -*/ -/*---------------------------------------------------------------------------*/ - return -ERESTARTSYS; -} -/*---------------------------------------------------------------------------*/ -switch (cmd) { -case SNDCTL_DSP_GETCAPS: { - int caps; - JOM(8, "SNDCTL_DSP_GETCAPS\n"); - -#if defined(UPSAMPLE) - if (true == peasycap->microphone) - caps = 0x04400000; - else - caps = 0x04400000; -#else - if (true == peasycap->microphone) - caps = 0x02400000; - else - caps = 0x04400000; -#endif /*UPSAMPLE*/ - - if (0 != copy_to_user((void __user *)arg, &caps, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - break; -} -case SNDCTL_DSP_GETFMTS: { - int incoming; - JOM(8, "SNDCTL_DSP_GETFMTS\n"); - -#if defined(UPSAMPLE) - if (true == peasycap->microphone) - incoming = AFMT_S16_LE; - else - incoming = AFMT_S16_LE; -#else - if (true == peasycap->microphone) - incoming = AFMT_S16_LE; - else - incoming = AFMT_S16_LE; -#endif /*UPSAMPLE*/ - - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - break; -} -case SNDCTL_DSP_SETFMT: { - int incoming, outgoing; - JOM(8, "SNDCTL_DSP_SETFMT\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - JOM(8, "........... %i=incoming\n", incoming); - -#if defined(UPSAMPLE) - if (true == peasycap->microphone) - outgoing = AFMT_S16_LE; - else - outgoing = AFMT_S16_LE; -#else - if (true == peasycap->microphone) - outgoing = AFMT_S16_LE; - else - outgoing = AFMT_S16_LE; -#endif /*UPSAMPLE*/ - - if (incoming != outgoing) { - JOM(8, "........... %i=outgoing\n", outgoing); - JOM(8, " cf. %i=AFMT_S16_LE\n", AFMT_S16_LE); - JOM(8, " cf. %i=AFMT_U8\n", AFMT_U8); - if (0 != copy_to_user((void __user *)arg, &outgoing, - sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EINVAL ; - } - break; -} -case SNDCTL_DSP_STEREO: { - int incoming; - JOM(8, "SNDCTL_DSP_STEREO\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - JOM(8, "........... %i=incoming\n", incoming); - -#if defined(UPSAMPLE) - if (true == peasycap->microphone) - incoming = 1; - else - incoming = 1; -#else - if (true == peasycap->microphone) - incoming = 0; - else - incoming = 1; -#endif /*UPSAMPLE*/ - - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - break; -} -case SNDCTL_DSP_SPEED: { - int incoming; - JOM(8, "SNDCTL_DSP_SPEED\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - JOM(8, "........... %i=incoming\n", incoming); - -#if defined(UPSAMPLE) - if (true == peasycap->microphone) - incoming = 32000; - else - incoming = 48000; -#else - if (true == peasycap->microphone) - incoming = 8000; - else - incoming = 48000; -#endif /*UPSAMPLE*/ - - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - break; -} -case SNDCTL_DSP_GETTRIGGER: { - int incoming; - JOM(8, "SNDCTL_DSP_GETTRIGGER\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - JOM(8, "........... %i=incoming\n", incoming); - - incoming = PCM_ENABLE_INPUT; - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - break; -} -case SNDCTL_DSP_SETTRIGGER: { - int incoming; - JOM(8, "SNDCTL_DSP_SETTRIGGER\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - JOM(8, "........... %i=incoming\n", incoming); - JOM(8, "........... cf 0x%x=PCM_ENABLE_INPUT " - "0x%x=PCM_ENABLE_OUTPUT\n", - PCM_ENABLE_INPUT, PCM_ENABLE_OUTPUT); - ; - ; - ; - ; - break; -} -case SNDCTL_DSP_GETBLKSIZE: { - int incoming; - JOM(8, "SNDCTL_DSP_GETBLKSIZE\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - JOM(8, "........... %i=incoming\n", incoming); - incoming = peasycap->audio_bytes_per_fragment; - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - break; -} -case SNDCTL_DSP_GETISPACE: { - struct audio_buf_info audio_buf_info; - - JOM(8, "SNDCTL_DSP_GETISPACE\n"); - - audio_buf_info.bytes = peasycap->audio_bytes_per_fragment; - audio_buf_info.fragments = 1; - audio_buf_info.fragsize = 0; - audio_buf_info.fragstotal = 0; - - if (0 != copy_to_user((void __user *)arg, &audio_buf_info, - sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - break; -} -case 0x00005401: -case 0x00005402: -case 0x00005403: -case 0x00005404: -case 0x00005405: -case 0x00005406: { - JOM(8, "SNDCTL_TMR_...: 0x%08X unsupported\n", cmd); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ENOIOCTLCMD; -} -default: { - JOM(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ENOIOCTLCMD; -} -} -mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); -return 0; -} -#endif /* CONFIG_EASYCAP_OSS */ -/*****************************************************************************/ - diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c index 3f85cc3b060b..028981421710 100644 --- a/drivers/staging/easycap/easycap_sound_oss.c +++ b/drivers/staging/easycap/easycap_sound_oss.c @@ -40,23 +40,6 @@ * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE */ /*--------------------------------------------------------------------------*/ -const struct file_operations easyoss_fops = { - .owner = THIS_MODULE, - .open = easyoss_open, - .release = easyoss_release, -#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL) - .unlocked_ioctl = easyoss_ioctl_noinode, -#else - .ioctl = easyoss_ioctl, -#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/ - .read = easyoss_read, - .llseek = no_llseek, -}; -struct usb_class_driver easyoss_class = { -.name = "usb/easyoss%d", -.fops = &easyoss_fops, -.minor_base = USB_SKEL_MINOR_BASE, -}; /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* @@ -328,8 +311,7 @@ return; * HAVE AN IOCTL INTERFACE. */ /*---------------------------------------------------------------------------*/ -int -easyoss_open(struct inode *inode, struct file *file) +static int easyoss_open(struct inode *inode, struct file *file) { struct usb_interface *pusb_interface; struct easycap *peasycap; @@ -401,8 +383,7 @@ if (0 != easycap_sound_setup(peasycap)) { return 0; } /*****************************************************************************/ -int -easyoss_release(struct inode *inode, struct file *file) +static int easyoss_release(struct inode *inode, struct file *file) { struct easycap *peasycap; @@ -425,9 +406,8 @@ JOM(4, "ending successfully\n"); return 0; } /*****************************************************************************/ -ssize_t -easyoss_read(struct file *file, char __user *puserspacebuffer, - size_t kount, loff_t *poff) +static ssize_t easyoss_read(struct file *file, char __user *puserspacebuffer, + size_t kount, loff_t *poff) { struct timeval timeval; long long int above, below, mean; @@ -725,6 +705,328 @@ mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); JOM(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd); JOM(8, "returning %li\n", (long int)szret); return szret; + +} +/*---------------------------------------------------------------------------*/ +static int easyoss_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ +struct easycap *peasycap; +struct usb_device *p; +int kd; + +if (NULL == file) { + SAY("ERROR: file is NULL\n"); + return -ERESTARTSYS; +} +peasycap = file->private_data; +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL.\n"); + return -EFAULT; +} +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; +} +p = peasycap->pusb_device; +if (NULL == p) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; +} +kd = isdongle(peasycap); +if (0 <= kd && DONGLE_MANY > kd) { + if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_audio)) { + SAY("ERROR: cannot lock " + "easycapdc60_dongle[%i].mutex_audio\n", kd); + return -ERESTARTSYS; + } + JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd); +/*---------------------------------------------------------------------------*/ +/* + * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap, + * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. + * IF NECESSARY, BAIL OUT. +*/ +/*---------------------------------------------------------------------------*/ + if (kd != isdongle(peasycap)) + return -ERESTARTSYS; + if (NULL == file) { + SAY("ERROR: file is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + peasycap = file->private_data; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + p = peasycap->pusb_device; + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } +} else { +/*---------------------------------------------------------------------------*/ +/* + * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE + * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT. +*/ +/*---------------------------------------------------------------------------*/ + return -ERESTARTSYS; +} +/*---------------------------------------------------------------------------*/ +switch (cmd) { +case SNDCTL_DSP_GETCAPS: { + int caps; + JOM(8, "SNDCTL_DSP_GETCAPS\n"); + +#if defined(UPSAMPLE) + if (true == peasycap->microphone) + caps = 0x04400000; + else + caps = 0x04400000; +#else + if (true == peasycap->microphone) + caps = 0x02400000; + else + caps = 0x04400000; +#endif /*UPSAMPLE*/ + + if (0 != copy_to_user((void __user *)arg, &caps, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; +} +case SNDCTL_DSP_GETFMTS: { + int incoming; + JOM(8, "SNDCTL_DSP_GETFMTS\n"); + +#if defined(UPSAMPLE) + if (true == peasycap->microphone) + incoming = AFMT_S16_LE; + else + incoming = AFMT_S16_LE; +#else + if (true == peasycap->microphone) + incoming = AFMT_S16_LE; + else + incoming = AFMT_S16_LE; +#endif /*UPSAMPLE*/ + + if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; } +case SNDCTL_DSP_SETFMT: { + int incoming, outgoing; + JOM(8, "SNDCTL_DSP_SETFMT\n"); + if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + JOM(8, "........... %i=incoming\n", incoming); + +#if defined(UPSAMPLE) + if (true == peasycap->microphone) + outgoing = AFMT_S16_LE; + else + outgoing = AFMT_S16_LE; +#else + if (true == peasycap->microphone) + outgoing = AFMT_S16_LE; + else + outgoing = AFMT_S16_LE; +#endif /*UPSAMPLE*/ + + if (incoming != outgoing) { + JOM(8, "........... %i=outgoing\n", outgoing); + JOM(8, " cf. %i=AFMT_S16_LE\n", AFMT_S16_LE); + JOM(8, " cf. %i=AFMT_U8\n", AFMT_U8); + if (0 != copy_to_user((void __user *)arg, &outgoing, + sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EINVAL ; + } + break; +} +case SNDCTL_DSP_STEREO: { + int incoming; + JOM(8, "SNDCTL_DSP_STEREO\n"); + if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + JOM(8, "........... %i=incoming\n", incoming); + +#if defined(UPSAMPLE) + if (true == peasycap->microphone) + incoming = 1; + else + incoming = 1; +#else + if (true == peasycap->microphone) + incoming = 0; + else + incoming = 1; +#endif /*UPSAMPLE*/ + + if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; +} +case SNDCTL_DSP_SPEED: { + int incoming; + JOM(8, "SNDCTL_DSP_SPEED\n"); + if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + JOM(8, "........... %i=incoming\n", incoming); + +#if defined(UPSAMPLE) + if (true == peasycap->microphone) + incoming = 32000; + else + incoming = 48000; +#else + if (true == peasycap->microphone) + incoming = 8000; + else + incoming = 48000; +#endif /*UPSAMPLE*/ + + if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; +} +case SNDCTL_DSP_GETTRIGGER: { + int incoming; + JOM(8, "SNDCTL_DSP_GETTRIGGER\n"); + if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + JOM(8, "........... %i=incoming\n", incoming); + + incoming = PCM_ENABLE_INPUT; + if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; +} +case SNDCTL_DSP_SETTRIGGER: { + int incoming; + JOM(8, "SNDCTL_DSP_SETTRIGGER\n"); + if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + JOM(8, "........... %i=incoming\n", incoming); + JOM(8, "........... cf 0x%x=PCM_ENABLE_INPUT " + "0x%x=PCM_ENABLE_OUTPUT\n", + PCM_ENABLE_INPUT, PCM_ENABLE_OUTPUT); + ; + ; + ; + ; + break; +} +case SNDCTL_DSP_GETBLKSIZE: { + int incoming; + JOM(8, "SNDCTL_DSP_GETBLKSIZE\n"); + if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + JOM(8, "........... %i=incoming\n", incoming); + incoming = peasycap->audio_bytes_per_fragment; + if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; +} +case SNDCTL_DSP_GETISPACE: { + struct audio_buf_info audio_buf_info; + + JOM(8, "SNDCTL_DSP_GETISPACE\n"); + + audio_buf_info.bytes = peasycap->audio_bytes_per_fragment; + audio_buf_info.fragments = 1; + audio_buf_info.fragsize = 0; + audio_buf_info.fragstotal = 0; + + if (0 != copy_to_user((void __user *)arg, &audio_buf_info, + sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; +} +case 0x00005401: +case 0x00005402: +case 0x00005403: +case 0x00005404: +case 0x00005405: +case 0x00005406: { + JOM(8, "SNDCTL_TMR_...: 0x%08X unsupported\n", cmd); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ENOIOCTLCMD; +} +default: { + JOM(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ENOIOCTLCMD; +} +} +mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); +return 0; +} +/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \ + (defined(EASYCAP_NEEDS_UNLOCKED_IOCTL))) +static long easyoss_ioctl_noinode(struct file *file, + unsigned int cmd, unsigned long arg) +{ + return (long)easyoss_ioctl((struct inode *)NULL, file, cmd, arg); +} +#endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/ +/*****************************************************************************/ + +const struct file_operations easyoss_fops = { + .owner = THIS_MODULE, + .open = easyoss_open, + .release = easyoss_release, +#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL) + .unlocked_ioctl = easyoss_ioctl_noinode, +#else + .ioctl = easyoss_ioctl, +#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/ + .read = easyoss_read, + .llseek = no_llseek, +}; +struct usb_class_driver easyoss_class = { + .name = "usb/easyoss%d", + .fops = &easyoss_fops, + .minor_base = USB_SKEL_MINOR_BASE, +}; /*****************************************************************************/ -- cgit v1.2.3 From 68e4ccaab251656290241c1f2653093cd3a1b225 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 24 Jan 2011 17:08:22 +0200 Subject: staging/easycap: make ALSA ops function static in sound.c 1. make also ops function static 2. move around code so to avid forward declarations Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 14 -- drivers/staging/easycap/easycap_sound.c | 249 +++++++++++++++----------------- 2 files changed, 120 insertions(+), 143 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 63722b1578d8..2479fc21e838 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -539,23 +539,9 @@ int adjust_volume(struct easycap *, int); /*---------------------------------------------------------------------------*/ #ifndef CONFIG_EASYCAP_OSS int easycap_alsa_probe(struct easycap *); - void easycap_alsa_complete(struct urb *); -int easycap_alsa_open(struct snd_pcm_substream *); -int easycap_alsa_close(struct snd_pcm_substream *); -int easycap_alsa_hw_params(struct snd_pcm_substream *, - struct snd_pcm_hw_params *); -int easycap_alsa_vmalloc(struct snd_pcm_substream *, size_t); -int easycap_alsa_hw_free(struct snd_pcm_substream *); -int easycap_alsa_prepare(struct snd_pcm_substream *); -int easycap_alsa_ack(struct snd_pcm_substream *); -int easycap_alsa_trigger(struct snd_pcm_substream *, int); -snd_pcm_uframes_t easycap_alsa_pointer(struct snd_pcm_substream *); -struct page *easycap_alsa_page(struct snd_pcm_substream *, unsigned long); - #else /* CONFIG_EASYCAP_OSS */ void easyoss_complete(struct urb *); - #endif /* !CONFIG_EASYCAP_OSS */ int easycap_sound_setup(struct easycap *); diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index 07dd7aa95ea5..4d25c97a3b2d 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -55,99 +55,7 @@ static const struct snd_pcm_hardware alsa_hardware = { .periods_max = AUDIO_FRAGMENT_MANY * 2, }; -static struct snd_pcm_ops easycap_alsa_pcm_ops = { - .open = easycap_alsa_open, - .close = easycap_alsa_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = easycap_alsa_hw_params, - .hw_free = easycap_alsa_hw_free, - .prepare = easycap_alsa_prepare, - .ack = easycap_alsa_ack, - .trigger = easycap_alsa_trigger, - .pointer = easycap_alsa_pointer, - .page = easycap_alsa_page, -}; -/*****************************************************************************/ -/*---------------------------------------------------------------------------*/ -/* - * THE FUNCTION snd_card_create() HAS THIS_MODULE AS AN ARGUMENT. THIS - * MEANS MODULE easycap. BEWARE. -*/ -/*---------------------------------------------------------------------------*/ -int -easycap_alsa_probe(struct easycap *peasycap) -{ -int rc; -struct snd_card *psnd_card; -struct snd_pcm *psnd_pcm; - -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -ENODEV; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; -} -if (0 > peasycap->minor) { - SAY("ERROR: no minor\n"); - return -ENODEV; -} - -peasycap->alsa_hardware = alsa_hardware; -if (true == peasycap->microphone) { - peasycap->alsa_hardware.rates = SNDRV_PCM_RATE_32000; - peasycap->alsa_hardware.rate_min = 32000; - peasycap->alsa_hardware.rate_max = 32000; -} else { - peasycap->alsa_hardware.rates = SNDRV_PCM_RATE_48000; - peasycap->alsa_hardware.rate_min = 48000; - peasycap->alsa_hardware.rate_max = 48000; -} - - if (0 != snd_card_create(SNDRV_DEFAULT_IDX1, "easycap_alsa", - THIS_MODULE, 0, - &psnd_card)) { - SAY("ERROR: Cannot do ALSA snd_card_create()\n"); - return -EFAULT; - } - - sprintf(&psnd_card->id[0], "EasyALSA%i", peasycap->minor); - strcpy(&psnd_card->driver[0], EASYCAP_DRIVER_DESCRIPTION); - strcpy(&psnd_card->shortname[0], "easycap_alsa"); - sprintf(&psnd_card->longname[0], "%s", &psnd_card->shortname[0]); - - psnd_card->dev = &peasycap->pusb_device->dev; - psnd_card->private_data = peasycap; - peasycap->psnd_card = psnd_card; - - rc = snd_pcm_new(psnd_card, "easycap_pcm", 0, 0, 1, &psnd_pcm); - if (0 != rc) { - SAM("ERROR: Cannot do ALSA snd_pcm_new()\n"); - snd_card_free(psnd_card); - return -EFAULT; - } - - snd_pcm_set_ops(psnd_pcm, SNDRV_PCM_STREAM_CAPTURE, - &easycap_alsa_pcm_ops); - psnd_pcm->info_flags = 0; - strcpy(&psnd_pcm->name[0], &psnd_card->id[0]); - psnd_pcm->private_data = peasycap; - peasycap->psnd_pcm = psnd_pcm; - peasycap->psubstream = (struct snd_pcm_substream *)NULL; - - rc = snd_card_register(psnd_card); - if (0 != rc) { - SAM("ERROR: Cannot do ALSA snd_card_register()\n"); - snd_card_free(psnd_card); - return -EFAULT; - } else { - ; - SAM("registered %s\n", &psnd_card->id[0]); - } -return 0; -} /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* @@ -390,8 +298,7 @@ if (peasycap->audio_isoc_streaming) { return; } /*****************************************************************************/ -int -easycap_alsa_open(struct snd_pcm_substream *pss) +static int easycap_alsa_open(struct snd_pcm_substream *pss) { struct snd_pcm *psnd_pcm; struct snd_card *psnd_card; @@ -444,8 +351,7 @@ JOM(4, "ending successfully\n"); return 0; } /*****************************************************************************/ -int -easycap_alsa_close(struct snd_pcm_substream *pss) +static int easycap_alsa_close(struct snd_pcm_substream *pss) { struct easycap *peasycap; @@ -469,25 +375,7 @@ JOT(4, "ending successfully\n"); return 0; } /*****************************************************************************/ -int -easycap_alsa_hw_params(struct snd_pcm_substream *pss, - struct snd_pcm_hw_params *phw) -{ -int rc; - -JOT(4, "%i\n", (params_buffer_bytes(phw))); -if (NULL == pss) { - SAY("ERROR: pss is NULL\n"); - return -EFAULT; -} -rc = easycap_alsa_vmalloc(pss, params_buffer_bytes(phw)); -if (0 != rc) - return rc; -return 0; -} -/*****************************************************************************/ -int -easycap_alsa_vmalloc(struct snd_pcm_substream *pss, size_t sz) +static int easycap_alsa_vmalloc(struct snd_pcm_substream *pss, size_t sz) { struct snd_pcm_runtime *prt; JOT(4, "\n"); @@ -513,8 +401,23 @@ prt->dma_bytes = sz; return 0; } /*****************************************************************************/ -int -easycap_alsa_hw_free(struct snd_pcm_substream *pss) +static int easycap_alsa_hw_params(struct snd_pcm_substream *pss, + struct snd_pcm_hw_params *phw) +{ +int rc; + +JOT(4, "%i\n", (params_buffer_bytes(phw))); +if (NULL == pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; +} +rc = easycap_alsa_vmalloc(pss, params_buffer_bytes(phw)); +if (0 != rc) + return rc; +return 0; +} +/*****************************************************************************/ +static int easycap_alsa_hw_free(struct snd_pcm_substream *pss) { struct snd_pcm_runtime *prt; JOT(4, "\n"); @@ -537,8 +440,7 @@ if (NULL != prt->dma_area) { return 0; } /*****************************************************************************/ -int -easycap_alsa_prepare(struct snd_pcm_substream *pss) +static int easycap_alsa_prepare(struct snd_pcm_substream *pss) { struct easycap *peasycap; struct snd_pcm_runtime *prt; @@ -579,14 +481,12 @@ if (prt->dma_bytes != 4 * ((int)prt->period_size) * ((int)prt->periods)) { return 0; } /*****************************************************************************/ -int -easycap_alsa_ack(struct snd_pcm_substream *pss) +static int easycap_alsa_ack(struct snd_pcm_substream *pss) { -return 0; + return 0; } /*****************************************************************************/ -int -easycap_alsa_trigger(struct snd_pcm_substream *pss, int cmd) +static int easycap_alsa_trigger(struct snd_pcm_substream *pss, int cmd) { struct easycap *peasycap; int retval; @@ -622,8 +522,7 @@ default: return 0; } /*****************************************************************************/ -snd_pcm_uframes_t -easycap_alsa_pointer(struct snd_pcm_substream *pss) +static snd_pcm_uframes_t easycap_alsa_pointer(struct snd_pcm_substream *pss) { struct easycap *peasycap; snd_pcm_uframes_t offset; @@ -662,13 +561,105 @@ JOM(8, "%7i=offset %7i=dma_read %7i=dma_next\n", return offset; } /*****************************************************************************/ -struct page * -easycap_alsa_page(struct snd_pcm_substream *pss, unsigned long offset) +static struct page *easycap_alsa_page(struct snd_pcm_substream *pss, + unsigned long offset) { -return vmalloc_to_page(pss->runtime->dma_area + offset); + return vmalloc_to_page(pss->runtime->dma_area + offset); } /*****************************************************************************/ +static struct snd_pcm_ops easycap_alsa_pcm_ops = { + .open = easycap_alsa_open, + .close = easycap_alsa_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = easycap_alsa_hw_params, + .hw_free = easycap_alsa_hw_free, + .prepare = easycap_alsa_prepare, + .ack = easycap_alsa_ack, + .trigger = easycap_alsa_trigger, + .pointer = easycap_alsa_pointer, + .page = easycap_alsa_page, +}; + +/*****************************************************************************/ +/*---------------------------------------------------------------------------*/ +/* + * THE FUNCTION snd_card_create() HAS THIS_MODULE AS AN ARGUMENT. THIS + * MEANS MODULE easycap. BEWARE. +*/ +/*---------------------------------------------------------------------------*/ +int easycap_alsa_probe(struct easycap *peasycap) +{ +int rc; +struct snd_card *psnd_card; +struct snd_pcm *psnd_pcm; + +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -ENODEV; +} +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; +} +if (0 > peasycap->minor) { + SAY("ERROR: no minor\n"); + return -ENODEV; +} + +peasycap->alsa_hardware = alsa_hardware; +if (true == peasycap->microphone) { + peasycap->alsa_hardware.rates = SNDRV_PCM_RATE_32000; + peasycap->alsa_hardware.rate_min = 32000; + peasycap->alsa_hardware.rate_max = 32000; +} else { + peasycap->alsa_hardware.rates = SNDRV_PCM_RATE_48000; + peasycap->alsa_hardware.rate_min = 48000; + peasycap->alsa_hardware.rate_max = 48000; +} + + if (0 != snd_card_create(SNDRV_DEFAULT_IDX1, "easycap_alsa", + THIS_MODULE, 0, + &psnd_card)) { + SAY("ERROR: Cannot do ALSA snd_card_create()\n"); + return -EFAULT; + } + + sprintf(&psnd_card->id[0], "EasyALSA%i", peasycap->minor); + strcpy(&psnd_card->driver[0], EASYCAP_DRIVER_DESCRIPTION); + strcpy(&psnd_card->shortname[0], "easycap_alsa"); + sprintf(&psnd_card->longname[0], "%s", &psnd_card->shortname[0]); + + psnd_card->dev = &peasycap->pusb_device->dev; + psnd_card->private_data = peasycap; + peasycap->psnd_card = psnd_card; + + rc = snd_pcm_new(psnd_card, "easycap_pcm", 0, 0, 1, &psnd_pcm); + if (0 != rc) { + SAM("ERROR: Cannot do ALSA snd_pcm_new()\n"); + snd_card_free(psnd_card); + return -EFAULT; + } + + snd_pcm_set_ops(psnd_pcm, SNDRV_PCM_STREAM_CAPTURE, + &easycap_alsa_pcm_ops); + psnd_pcm->info_flags = 0; + strcpy(&psnd_pcm->name[0], &psnd_card->id[0]); + psnd_pcm->private_data = peasycap; + peasycap->psnd_pcm = psnd_pcm; + peasycap->psubstream = (struct snd_pcm_substream *)NULL; + + rc = snd_card_register(psnd_card); + if (0 != rc) { + SAM("ERROR: Cannot do ALSA snd_card_register()\n"); + snd_card_free(psnd_card); + return -EFAULT; + } else { + ; + SAM("registered %s\n", &psnd_card->id[0]); + } +return 0; +} #endif /*! CONFIG_EASYCAP_OSS */ /*****************************************************************************/ -- cgit v1.2.3 From acd1130e8793fb150fb522da8ec51675839eb4b1 Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Mon, 24 Jan 2011 15:45:15 -0800 Subject: net: reduce and unify printk level in netdev_fix_features() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduce printk() levels to KERN_INFO in netdev_fix_features() as this will be used by ethtool and might spam dmesg unnecessarily. This converts the function to use netdev_info() instead of plain printk(). As a side effect, bonding and bridge devices will now log dropped features on every slave device change. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 4 ++-- include/linux/netdevice.h | 2 +- net/bridge/br_if.c | 2 +- net/core/dev.c | 33 ++++++++++++--------------------- 4 files changed, 16 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 7047b406b8ba..1df9f0ea9184 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1400,8 +1400,8 @@ static int bond_compute_features(struct bonding *bond) done: features |= (bond_dev->features & BOND_VLAN_FEATURES); - bond_dev->features = netdev_fix_features(features, NULL); - bond_dev->vlan_features = netdev_fix_features(vlan_features, NULL); + bond_dev->features = netdev_fix_features(bond_dev, features); + bond_dev->vlan_features = netdev_fix_features(bond_dev, vlan_features); bond_dev->hard_header_len = max_hard_header_len; return 0; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 0de3c59720fa..8858422c5c5d 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2399,7 +2399,7 @@ extern char *netdev_drivername(const struct net_device *dev, char *buffer, int l extern void linkwatch_run_queue(void); u32 netdev_increment_features(u32 all, u32 one, u32 mask); -u32 netdev_fix_features(u32 features, const char *name); +u32 netdev_fix_features(struct net_device *dev, u32 features); void netif_stacked_transfer_operstate(const struct net_device *rootdev, struct net_device *dev); diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 52ce4a30f8b3..2a6801d8b728 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -379,7 +379,7 @@ void br_features_recompute(struct net_bridge *br) } done: - br->dev->features = netdev_fix_features(features, NULL); + br->dev->features = netdev_fix_features(br->dev, features); } /* called with RTNL */ diff --git a/net/core/dev.c b/net/core/dev.c index 7103f89fde0c..1b4c07fe295f 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5213,58 +5213,49 @@ static void rollback_registered(struct net_device *dev) rollback_registered_many(&single); } -u32 netdev_fix_features(u32 features, const char *name) +u32 netdev_fix_features(struct net_device *dev, u32 features) { /* Fix illegal checksum combinations */ if ((features & NETIF_F_HW_CSUM) && (features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { - if (name) - printk(KERN_NOTICE "%s: mixed HW and IP checksum settings.\n", - name); + netdev_info(dev, "mixed HW and IP checksum settings.\n"); features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM); } if ((features & NETIF_F_NO_CSUM) && (features & (NETIF_F_HW_CSUM|NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { - if (name) - printk(KERN_NOTICE "%s: mixed no checksumming and other settings.\n", - name); + netdev_info(dev, "mixed no checksumming and other settings.\n"); features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM|NETIF_F_HW_CSUM); } /* Fix illegal SG+CSUM combinations. */ if ((features & NETIF_F_SG) && !(features & NETIF_F_ALL_CSUM)) { - if (name) - printk(KERN_NOTICE "%s: Dropping NETIF_F_SG since no " - "checksum feature.\n", name); + netdev_info(dev, + "Dropping NETIF_F_SG since no checksum feature.\n"); features &= ~NETIF_F_SG; } /* TSO requires that SG is present as well. */ if ((features & NETIF_F_TSO) && !(features & NETIF_F_SG)) { - if (name) - printk(KERN_NOTICE "%s: Dropping NETIF_F_TSO since no " - "SG feature.\n", name); + netdev_info(dev, "Dropping NETIF_F_TSO since no SG feature.\n"); features &= ~NETIF_F_TSO; } + /* UFO needs SG and checksumming */ if (features & NETIF_F_UFO) { /* maybe split UFO into V4 and V6? */ if (!((features & NETIF_F_GEN_CSUM) || (features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM)) == (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { - if (name) - printk(KERN_ERR "%s: Dropping NETIF_F_UFO " - "since no checksum offload features.\n", - name); + netdev_info(dev, + "Dropping NETIF_F_UFO since no checksum offload features.\n"); features &= ~NETIF_F_UFO; } if (!(features & NETIF_F_SG)) { - if (name) - printk(KERN_ERR "%s: Dropping NETIF_F_UFO " - "since no NETIF_F_SG feature.\n", name); + netdev_info(dev, + "Dropping NETIF_F_UFO since no NETIF_F_SG feature.\n"); features &= ~NETIF_F_UFO; } } @@ -5407,7 +5398,7 @@ int register_netdevice(struct net_device *dev) if (dev->iflink == -1) dev->iflink = dev->ifindex; - dev->features = netdev_fix_features(dev->features, dev->name); + dev->features = netdev_fix_features(dev, dev->features); /* Enable software GSO if SG is supported. */ if (dev->features & NETIF_F_SG) -- cgit v1.2.3 From 84c49d8c3e4abefb0a41a77b25aa37ebe8d6b743 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Mon, 24 Jan 2011 05:45:46 +0000 Subject: veth: remove unneeded ifname code from veth_newlink() The code is not needed because tb[IFLA_IFNAME] is already processed in rtnl_newlink(). Remove this redundancy. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/veth.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/veth.c b/drivers/net/veth.c index cc83fa71c3ff..105d7f0630cc 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -403,17 +403,6 @@ static int veth_newlink(struct net *src_net, struct net_device *dev, if (tb[IFLA_ADDRESS] == NULL) random_ether_addr(dev->dev_addr); - if (tb[IFLA_IFNAME]) - nla_strlcpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ); - else - snprintf(dev->name, IFNAMSIZ, DRV_NAME "%%d"); - - if (strchr(dev->name, '%')) { - err = dev_alloc_name(dev, dev->name); - if (err < 0) - goto err_alloc_name; - } - err = register_netdevice(dev); if (err < 0) goto err_register_dev; @@ -433,7 +422,6 @@ static int veth_newlink(struct net *src_net, struct net_device *dev, err_register_dev: /* nothing to do */ -err_alloc_name: err_configure_peer: unregister_netdevice(peer); return err; -- cgit v1.2.3 From 6e4e2d9b7428c4e9f26d7c2779ead8172b01ebf0 Mon Sep 17 00:00:00 2001 From: "L. Alberto Giménez" Date: Sun, 23 Jan 2011 01:07:20 +0100 Subject: Staging: rt2860: wpa.h: Fix space after unary '*' operator. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix checkpatch error raised by the use of spaces between the '*' operator and the corresponding variable name. Signed-off-by: L. Alberto Giménez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/wpa.h | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/wpa.h b/drivers/staging/rt2860/wpa.h index 116fc2caa886..a7796d330b71 100644 --- a/drivers/staging/rt2860/wpa.h +++ b/drivers/staging/rt2860/wpa.h @@ -369,19 +369,15 @@ struct PACKED rt_rsn_capability { /*======================================== The prototype is defined in cmm_wpa.c ========================================*/ -BOOLEAN WpaMsgTypeSubst(u8 EAPType, int * MsgType); +BOOLEAN WpaMsgTypeSubst(u8 EAPType, int *MsgType); -void PRF(u8 * key, - int key_len, - u8 * prefix, - int prefix_len, - u8 * data, int data_len, u8 * output, int len); +void PRF(u8 *key, int key_len, u8 *prefix, int prefix_len, + u8 *data, int data_len, u8 *output, int len); int PasswordHash(char *password, unsigned char *ssid, int ssidlength, unsigned char *output); -u8 *GetSuiteFromRSNIE(u8 *rsnie, - u32 rsnie_len, u8 type, u8 * count); +u8 *GetSuiteFromRSNIE(u8 *rsnie, u32 rsnie_len, u8 type, u8 *count); void WpaShowAllsuite(u8 *rsnie, u32 rsnie_len); -- cgit v1.2.3 From f5041dac6ba543a98bf550ae94923fc8e9d4fc13 Mon Sep 17 00:00:00 2001 From: "L. Alberto Giménez" Date: Sun, 23 Jan 2011 01:07:19 +0100 Subject: Staging: rt2860: rt_linux.h: Fix space after unary '*' operator. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix checkpatch error raised by the use of spaces between the '*' operator and the corresponding variable name. Signed-off-by: L. Alberto Giménez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/rt_linux.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/rt_linux.h b/drivers/staging/rt2860/rt_linux.h index 92ff5438e777..3efb88fdffc1 100644 --- a/drivers/staging/rt2860/rt_linux.h +++ b/drivers/staging/rt2860/rt_linux.h @@ -102,8 +102,8 @@ extern const struct iw_handler_def rt28xx_iw_handler_def; /*********************************************************************************** * OS Specific definitions and data structures ***********************************************************************************/ -typedef int (*HARD_START_XMIT_FUNC) (struct sk_buff * skb, - struct net_device * net_dev); +typedef int (*HARD_START_XMIT_FUNC) (struct sk_buff *skb, + struct net_device *net_dev); #ifdef RTMP_MAC_PCI #ifndef PCI_DEVICE @@ -366,7 +366,7 @@ typedef void (*TIMER_FUNCTION) (unsigned long); #define ONE_TICK 1 -static inline void NdisGetSystemUpTime(unsigned long * time) +static inline void NdisGetSystemUpTime(unsigned long *time) { *time = jiffies; } @@ -815,7 +815,7 @@ void linux_pci_unmap_single(struct rt_rtmp_adapter *pAd, dma_addr_t dma_addr, /*********************************************************************************** * Other function prototypes definitions ***********************************************************************************/ -void RTMP_GetCurrentSystemTime(LARGE_INTEGER * time); +void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time); int rt28xx_packet_xmit(struct sk_buff *skb); #ifdef RTMP_MAC_PCI @@ -827,8 +827,8 @@ IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance); int rt28xx_sta_ioctl(struct net_device *net_dev, IN OUT struct ifreq *rq, int cmd); -extern int ra_mtd_write(int num, loff_t to, size_t len, const u_char * buf); -extern int ra_mtd_read(int num, loff_t from, size_t len, u_char * buf); +extern int ra_mtd_write(int num, loff_t to, size_t len, const u_char *buf); +extern int ra_mtd_read(int num, loff_t from, size_t len, u_char *buf); #define GET_PAD_FROM_NET_DEV(_pAd, _net_dev) (_pAd) = (struct rt_rtmp_adapter *)(_net_dev)->ml_priv; -- cgit v1.2.3 From 5673db40e28732431b1d3c6433638408f913142e Mon Sep 17 00:00:00 2001 From: "L. Alberto Giménez" Date: Sun, 23 Jan 2011 01:07:18 +0100 Subject: Staging: rt2860: rt_linux.c: Fix space after unary '*' operator. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix checkpatch error raised by the use of spaces between the '*' operator and the corresponding variable name. Signed-off-by: L. Alberto Giménez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/rt_linux.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c index 728864e18a18..b3f836de332b 100644 --- a/drivers/staging/rt2860/rt_linux.c +++ b/drivers/staging/rt2860/rt_linux.c @@ -118,8 +118,7 @@ void RTMP_OS_Mod_Timer(struct timer_list *pTimer, mod_timer(pTimer, jiffies + timeout); } -void RTMP_OS_Del_Timer(struct timer_list *pTimer, - OUT BOOLEAN * pCancelled) +void RTMP_OS_Del_Timer(struct timer_list *pTimer, OUT BOOLEAN *pCancelled) { if (timer_pending(pTimer)) { *pCancelled = del_timer_sync(pTimer); -- cgit v1.2.3 From dc7b202a4ee6cb686e2bbef80c84443f43ec91bd Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 24 Jan 2011 11:44:29 +0100 Subject: staging/ste_rmi4: Remove obsolete cleanup for clientdata A few new i2c-drivers came into the kernel which clear the clientdata-pointer on exit or error. This is obsolete meanwhile, the core will do it. Signed-off-by: Wolfram Sang Cc: Naveen Kumar Gaddipati Cc: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c index f69d3a34190a..fa1ee9d11888 100644 --- a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c +++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c @@ -987,7 +987,7 @@ static int __devinit synaptics_rmi4_probe retval = input_register_device(rmi4_data->input_dev); if (retval) { dev_err(&client->dev, "%s:input register failed\n", __func__); - goto err_input_register; + goto err_query_dev; } /* Clear interrupts */ @@ -1009,8 +1009,6 @@ static int __devinit synaptics_rmi4_probe err_request_irq: free_irq(platformdata->irq_number, rmi4_data); input_unregister_device(rmi4_data->input_dev); -err_input_register: - i2c_set_clientdata(client, NULL); err_query_dev: if (platformdata->regulator_en) { regulator_disable(rmi4_data->regulator); -- cgit v1.2.3 From 7d7854b4da52a1e40a41d26048f7940e4eb7193b Mon Sep 17 00:00:00 2001 From: Nitin Gupta Date: Sat, 22 Jan 2011 07:36:15 -0500 Subject: Staging: zram: simplify zram_make_request zram_read() and zram_write() always return zero, so make them return void to simplify the code. Signed-off-by: Nitin Gupta Signed-off-by: Jerome Marchand Acked-by: Jeff Moyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/zram_drv.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 01d6dd952581..5ed4e75dc218 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -200,7 +200,7 @@ static void handle_uncompressed_page(struct zram *zram, flush_dcache_page(page); } -static int zram_read(struct zram *zram, struct bio *bio) +static void zram_read(struct zram *zram, struct bio *bio) { int i; @@ -209,7 +209,7 @@ static int zram_read(struct zram *zram, struct bio *bio) if (unlikely(!zram->init_done)) { bio_endio(bio, -ENXIO); - return 0; + return; } zram_stat64_inc(zram, &zram->stats.num_reads); @@ -271,14 +271,13 @@ static int zram_read(struct zram *zram, struct bio *bio) set_bit(BIO_UPTODATE, &bio->bi_flags); bio_endio(bio, 0); - return 0; + return; out: bio_io_error(bio); - return 0; } -static int zram_write(struct zram *zram, struct bio *bio) +static void zram_write(struct zram *zram, struct bio *bio) { int i, ret; u32 index; @@ -402,11 +401,10 @@ memstore: set_bit(BIO_UPTODATE, &bio->bi_flags); bio_endio(bio, 0); - return 0; + return; out: bio_io_error(bio); - return 0; } /* @@ -431,7 +429,6 @@ static inline int valid_io_request(struct zram *zram, struct bio *bio) */ static int zram_make_request(struct request_queue *queue, struct bio *bio) { - int ret = 0; struct zram *zram = queue->queuedata; if (!valid_io_request(zram, bio)) { @@ -442,15 +439,15 @@ static int zram_make_request(struct request_queue *queue, struct bio *bio) switch (bio_data_dir(bio)) { case READ: - ret = zram_read(zram, bio); + zram_read(zram, bio); break; case WRITE: - ret = zram_write(zram, bio); + zram_write(zram, bio); break; } - return ret; + return 0; } void zram_reset_device(struct zram *zram) -- cgit v1.2.3 From ead1256410cb5a79fd3615ba70ba56779c5d21e2 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sun, 23 Jan 2011 08:30:38 +0100 Subject: staging: brcm80211: assure common sources are truly common Common code for brcm80211 drivers was resulting in different compiled object files for the drivers due to compilation flags. This has been aligned so that they are resulting in same object files. Kconfig now allows both drivers to be build simultaneously. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/Kconfig | 14 +++++++------- drivers/staging/brcm80211/Makefile | 5 +++-- drivers/staging/brcm80211/brcmfmac/Makefile | 9 ++++++--- drivers/staging/brcm80211/brcmsmac/Makefile | 3 +-- drivers/staging/brcm80211/util/aiutils.c | 4 ---- drivers/staging/brcm80211/util/bcmutils.c | 1 + drivers/staging/brcm80211/util/hnddma.c | 1 + drivers/staging/brcm80211/util/hndpmu.c | 14 ++++++++------ 8 files changed, 27 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/Kconfig b/drivers/staging/brcm80211/Kconfig index 3208352465af..b6f86354b69f 100644 --- a/drivers/staging/brcm80211/Kconfig +++ b/drivers/staging/brcm80211/Kconfig @@ -2,12 +2,6 @@ menuconfig BRCM80211 tristate "Broadcom IEEE802.11n WLAN drivers" depends on WLAN -choice - prompt "Broadcom IEEE802.11n driver style" - depends on BRCM80211 - help - Select the appropriate driver style from the list below. - config BRCMSMAC bool "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver" depends on PCI @@ -30,4 +24,10 @@ config BRCMFMAC Broadcom IEEE802.11n FullMAC chipsets. This driver uses the kernel's wireless extensions subsystem. If you choose to build a module, it'll be called brcmfmac.ko. -endchoice + +config BRCMDBG + bool "Broadcom driver debug functions" + default n + depends on BRCM80211 + ---help--- + Selecting this enables additional code for debug purposes. diff --git a/drivers/staging/brcm80211/Makefile b/drivers/staging/brcm80211/Makefile index 5caaea597d50..b6d9afc3669d 100644 --- a/drivers/staging/brcm80211/Makefile +++ b/drivers/staging/brcm80211/Makefile @@ -15,8 +15,9 @@ # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# one and only common flag -subdir-ccflags-y := -DBCMDBG +# common flags +subdir-ccflags-y := -DBCMDMA32 +subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG -DBCMDBG_ASSERT obj-$(CONFIG_BRCMFMAC) += brcmfmac/ obj-$(CONFIG_BRCMSMAC) += brcmsmac/ diff --git a/drivers/staging/brcm80211/brcmfmac/Makefile b/drivers/staging/brcm80211/brcmfmac/Makefile index b3931b03f8d7..aa7f72d33b3f 100644 --- a/drivers/staging/brcm80211/brcmfmac/Makefile +++ b/drivers/staging/brcm80211/brcmfmac/Makefile @@ -22,7 +22,6 @@ ccflags-y := \ -DBCMSDIO \ -DBDC \ -DBRCM_FULLMAC \ - -DDHD_DEBUG \ -DDHD_FIRSTREAD=64 \ -DDHD_SCHED \ -DDHD_SDALIGN=64 \ @@ -31,8 +30,12 @@ ccflags-y := \ -DMMC_SDIO_ABORT \ -DPKT_FILTER_SUPPORT \ -DSHOW_EVENTS \ - -DTOE \ - -Idrivers/staging/brcm80211/brcmfmac \ + -DTOE + +ccflags-$(CONFIG_BRCMDBG) += -DDHD_DEBUG + +ccflags-y += \ + -Idrivers/staging/brcm80211/brcmfmac \ -Idrivers/staging/brcm80211/include \ -Idrivers/staging/brcm80211/util diff --git a/drivers/staging/brcm80211/brcmsmac/Makefile b/drivers/staging/brcm80211/brcmsmac/Makefile index ea297023c614..5da39be0f769 100644 --- a/drivers/staging/brcm80211/brcmsmac/Makefile +++ b/drivers/staging/brcm80211/brcmsmac/Makefile @@ -15,14 +15,13 @@ # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -ccflags-y := \ +ccflags-y := \ -DWLC_HIGH \ -DWLC_LOW \ -DSTA \ -DWME \ -DWL11N \ -DDBAND \ - -DBCMDMA32 \ -DBCMNVRAMR \ -Idrivers/staging/brcm80211/brcmsmac \ -Idrivers/staging/brcm80211/brcmsmac/phy \ diff --git a/drivers/staging/brcm80211/util/aiutils.c b/drivers/staging/brcm80211/util/aiutils.c index b6e7a9e97379..e4842c12ccf7 100644 --- a/drivers/staging/brcm80211/util/aiutils.c +++ b/drivers/staging/brcm80211/util/aiutils.c @@ -131,10 +131,8 @@ void ai_scan(si_t *sih, void *regs, uint devid) eromptr = regs; break; -#ifdef BCMSDIO case SPI_BUS: case SDIO_BUS: -#endif /* BCMSDIO */ eromptr = (u32 *)(unsigned long)erombase; break; @@ -355,10 +353,8 @@ void *ai_setcoreidx(si_t *sih, uint coreidx) pci_write_config_dword(sii->osh->pdev, PCI_BAR0_WIN2, wrap); break; -#ifdef BCMSDIO case SPI_BUS: case SDIO_BUS: -#endif /* BCMSDIO */ sii->curmap = regs = (void *)(unsigned long)addr; sii->curwrap = (void *)(unsigned long)wrap; break; diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index 258fd90d9152..a6ffb14323a0 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -214,6 +214,7 @@ void pktq_flush(struct osl_info *osh, struct pktq *pq, bool dir) ASSERT(pq->len == 0); } #else /* !BRCM_FULLMAC */ +/* TODO: can we remove callback for softmac? */ void pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, bool dir, ifpkt_cb_t fn, int arg) diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index d08869239d5b..92b2c8074aab 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -2329,6 +2329,7 @@ static int BCMFASTPATH dma64_txfast(dma_info_t *di, struct sk_buff *p0, data = p->data; len = p->len; #ifdef BCM_DMAPAD + /* TODO: when is this used? */ len += PKTDMAPAD(di->osh, p); #endif /* BCM_DMAPAD */ next = p->next; diff --git a/drivers/staging/brcm80211/util/hndpmu.c b/drivers/staging/brcm80211/util/hndpmu.c index 49d19a121f7b..c8af68f39bd4 100644 --- a/drivers/staging/brcm80211/util/hndpmu.c +++ b/drivers/staging/brcm80211/util/hndpmu.c @@ -32,6 +32,10 @@ #ifdef BCMDBG #define PMU_MSG(args) printf args + +/* debug-only definitions */ +/* #define BCMDBG_FORCEHT */ +/* #define CHIPC_UART_ALWAYS_ON */ #else #define PMU_MSG(args) #endif /* BCMDBG */ @@ -1466,6 +1470,7 @@ si_pmu1_cpuclk0(si_t *sih, struct osl_info *osh, chipcregs_t *cc) m1div = (tmp & PMU1_PLL0_PC1_M1DIV_MASK) >> PMU1_PLL0_PC1_M1DIV_SHIFT; #ifdef BCMDBG + /* TODO: seems more like a workaround */ /* Read p2div/p1div from pllcontrol[0] */ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); tmp = R_REG(osh, &cc->pllcontrol_data); @@ -1550,6 +1555,7 @@ void si_pmu_pll_init(si_t *sih, struct osl_info *osh, uint xtalfreq) } #ifdef BCMDBG_FORCEHT + /* TODO: when is this flag used? what does it do? */ OR_REG(osh, &cc->clk_ctl_st, CCS_FORCEHT); #endif @@ -2504,12 +2510,7 @@ bool si_pmu_is_otp_powered(si_t *sih, struct osl_info *osh) return st; } -void -#if defined(BCMDBG) -si_pmu_sprom_enable(si_t *sih, struct osl_info *osh, bool enable) -#else -si_pmu_sprom_enable(si_t *sih, struct osl_info *osh, bool enable) -#endif +void si_pmu_sprom_enable(si_t *sih, struct osl_info *osh, bool enable) { chipcregs_t *cc; uint origidx; @@ -2531,6 +2532,7 @@ void si_pmu_chip_init(si_t *sih, struct osl_info *osh) ASSERT(sih->cccaps & CC_CAP_PMU); #ifdef CHIPC_UART_ALWAYS_ON + /* TODO: are these special for debugging purposes? */ si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, clk_ctl_st), CCS_FORCEALP, CCS_FORCEALP); #endif /* CHIPC_UART_ALWAYS_ON */ -- cgit v1.2.3 From f5c28f2538f1b23db493be262468a9a2e8bb97b2 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 25 Jan 2011 19:07:55 +0800 Subject: Revert "staging: brcm80211: assure common sources are truly common" This reverts commit ead1256410cb5a79fd3615ba70ba56779c5d21e2 as it broke the build when building with multiple threads at the same time. Cc: Brett Rudley Cc: Henry Ptasinski Cc: Roland Vossen Cc: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/Kconfig | 14 +++++++------- drivers/staging/brcm80211/Makefile | 5 ++--- drivers/staging/brcm80211/brcmfmac/Makefile | 9 +++------ drivers/staging/brcm80211/brcmsmac/Makefile | 3 ++- drivers/staging/brcm80211/util/aiutils.c | 4 ++++ drivers/staging/brcm80211/util/bcmutils.c | 1 - drivers/staging/brcm80211/util/hnddma.c | 1 - drivers/staging/brcm80211/util/hndpmu.c | 14 ++++++-------- 8 files changed, 24 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/Kconfig b/drivers/staging/brcm80211/Kconfig index b6f86354b69f..3208352465af 100644 --- a/drivers/staging/brcm80211/Kconfig +++ b/drivers/staging/brcm80211/Kconfig @@ -2,6 +2,12 @@ menuconfig BRCM80211 tristate "Broadcom IEEE802.11n WLAN drivers" depends on WLAN +choice + prompt "Broadcom IEEE802.11n driver style" + depends on BRCM80211 + help + Select the appropriate driver style from the list below. + config BRCMSMAC bool "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver" depends on PCI @@ -24,10 +30,4 @@ config BRCMFMAC Broadcom IEEE802.11n FullMAC chipsets. This driver uses the kernel's wireless extensions subsystem. If you choose to build a module, it'll be called brcmfmac.ko. - -config BRCMDBG - bool "Broadcom driver debug functions" - default n - depends on BRCM80211 - ---help--- - Selecting this enables additional code for debug purposes. +endchoice diff --git a/drivers/staging/brcm80211/Makefile b/drivers/staging/brcm80211/Makefile index b6d9afc3669d..5caaea597d50 100644 --- a/drivers/staging/brcm80211/Makefile +++ b/drivers/staging/brcm80211/Makefile @@ -15,9 +15,8 @@ # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# common flags -subdir-ccflags-y := -DBCMDMA32 -subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG -DBCMDBG_ASSERT +# one and only common flag +subdir-ccflags-y := -DBCMDBG obj-$(CONFIG_BRCMFMAC) += brcmfmac/ obj-$(CONFIG_BRCMSMAC) += brcmsmac/ diff --git a/drivers/staging/brcm80211/brcmfmac/Makefile b/drivers/staging/brcm80211/brcmfmac/Makefile index aa7f72d33b3f..b3931b03f8d7 100644 --- a/drivers/staging/brcm80211/brcmfmac/Makefile +++ b/drivers/staging/brcm80211/brcmfmac/Makefile @@ -22,6 +22,7 @@ ccflags-y := \ -DBCMSDIO \ -DBDC \ -DBRCM_FULLMAC \ + -DDHD_DEBUG \ -DDHD_FIRSTREAD=64 \ -DDHD_SCHED \ -DDHD_SDALIGN=64 \ @@ -30,12 +31,8 @@ ccflags-y := \ -DMMC_SDIO_ABORT \ -DPKT_FILTER_SUPPORT \ -DSHOW_EVENTS \ - -DTOE - -ccflags-$(CONFIG_BRCMDBG) += -DDHD_DEBUG - -ccflags-y += \ - -Idrivers/staging/brcm80211/brcmfmac \ + -DTOE \ + -Idrivers/staging/brcm80211/brcmfmac \ -Idrivers/staging/brcm80211/include \ -Idrivers/staging/brcm80211/util diff --git a/drivers/staging/brcm80211/brcmsmac/Makefile b/drivers/staging/brcm80211/brcmsmac/Makefile index 5da39be0f769..ea297023c614 100644 --- a/drivers/staging/brcm80211/brcmsmac/Makefile +++ b/drivers/staging/brcm80211/brcmsmac/Makefile @@ -15,13 +15,14 @@ # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -ccflags-y := \ +ccflags-y := \ -DWLC_HIGH \ -DWLC_LOW \ -DSTA \ -DWME \ -DWL11N \ -DDBAND \ + -DBCMDMA32 \ -DBCMNVRAMR \ -Idrivers/staging/brcm80211/brcmsmac \ -Idrivers/staging/brcm80211/brcmsmac/phy \ diff --git a/drivers/staging/brcm80211/util/aiutils.c b/drivers/staging/brcm80211/util/aiutils.c index e4842c12ccf7..b6e7a9e97379 100644 --- a/drivers/staging/brcm80211/util/aiutils.c +++ b/drivers/staging/brcm80211/util/aiutils.c @@ -131,8 +131,10 @@ void ai_scan(si_t *sih, void *regs, uint devid) eromptr = regs; break; +#ifdef BCMSDIO case SPI_BUS: case SDIO_BUS: +#endif /* BCMSDIO */ eromptr = (u32 *)(unsigned long)erombase; break; @@ -353,8 +355,10 @@ void *ai_setcoreidx(si_t *sih, uint coreidx) pci_write_config_dword(sii->osh->pdev, PCI_BAR0_WIN2, wrap); break; +#ifdef BCMSDIO case SPI_BUS: case SDIO_BUS: +#endif /* BCMSDIO */ sii->curmap = regs = (void *)(unsigned long)addr; sii->curwrap = (void *)(unsigned long)wrap; break; diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index a6ffb14323a0..258fd90d9152 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -214,7 +214,6 @@ void pktq_flush(struct osl_info *osh, struct pktq *pq, bool dir) ASSERT(pq->len == 0); } #else /* !BRCM_FULLMAC */ -/* TODO: can we remove callback for softmac? */ void pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, bool dir, ifpkt_cb_t fn, int arg) diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 92b2c8074aab..d08869239d5b 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -2329,7 +2329,6 @@ static int BCMFASTPATH dma64_txfast(dma_info_t *di, struct sk_buff *p0, data = p->data; len = p->len; #ifdef BCM_DMAPAD - /* TODO: when is this used? */ len += PKTDMAPAD(di->osh, p); #endif /* BCM_DMAPAD */ next = p->next; diff --git a/drivers/staging/brcm80211/util/hndpmu.c b/drivers/staging/brcm80211/util/hndpmu.c index c8af68f39bd4..49d19a121f7b 100644 --- a/drivers/staging/brcm80211/util/hndpmu.c +++ b/drivers/staging/brcm80211/util/hndpmu.c @@ -32,10 +32,6 @@ #ifdef BCMDBG #define PMU_MSG(args) printf args - -/* debug-only definitions */ -/* #define BCMDBG_FORCEHT */ -/* #define CHIPC_UART_ALWAYS_ON */ #else #define PMU_MSG(args) #endif /* BCMDBG */ @@ -1470,7 +1466,6 @@ si_pmu1_cpuclk0(si_t *sih, struct osl_info *osh, chipcregs_t *cc) m1div = (tmp & PMU1_PLL0_PC1_M1DIV_MASK) >> PMU1_PLL0_PC1_M1DIV_SHIFT; #ifdef BCMDBG - /* TODO: seems more like a workaround */ /* Read p2div/p1div from pllcontrol[0] */ W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); tmp = R_REG(osh, &cc->pllcontrol_data); @@ -1555,7 +1550,6 @@ void si_pmu_pll_init(si_t *sih, struct osl_info *osh, uint xtalfreq) } #ifdef BCMDBG_FORCEHT - /* TODO: when is this flag used? what does it do? */ OR_REG(osh, &cc->clk_ctl_st, CCS_FORCEHT); #endif @@ -2510,7 +2504,12 @@ bool si_pmu_is_otp_powered(si_t *sih, struct osl_info *osh) return st; } -void si_pmu_sprom_enable(si_t *sih, struct osl_info *osh, bool enable) +void +#if defined(BCMDBG) +si_pmu_sprom_enable(si_t *sih, struct osl_info *osh, bool enable) +#else +si_pmu_sprom_enable(si_t *sih, struct osl_info *osh, bool enable) +#endif { chipcregs_t *cc; uint origidx; @@ -2532,7 +2531,6 @@ void si_pmu_chip_init(si_t *sih, struct osl_info *osh) ASSERT(sih->cccaps & CC_CAP_PMU); #ifdef CHIPC_UART_ALWAYS_ON - /* TODO: are these special for debugging purposes? */ si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, clk_ctl_st), CCS_FORCEALP, CCS_FORCEALP); #endif /* CHIPC_UART_ALWAYS_ON */ -- cgit v1.2.3 From ada609ee2ac2e03bd8abb07f9b3e92cd2e650f19 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 25 Jan 2011 14:35:54 +0100 Subject: workqueue: use WQ_MEM_RECLAIM instead of WQ_RESCUER WQ_RESCUER is now an internal flag and should only be used in the workqueue implementation proper. Use WQ_MEM_RECLAIM instead. This doesn't introduce any functional difference. Signed-off-by: Tejun Heo Cc: dm-devel@redhat.com Cc: Neil Brown --- drivers/md/md.c | 2 +- fs/nfs/inode.c | 2 +- net/sunrpc/sched.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index b76cfc89e1b5..6352e84fd512 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -7321,7 +7321,7 @@ static int __init md_init(void) { int ret = -ENOMEM; - md_wq = alloc_workqueue("md", WQ_RESCUER, 0); + md_wq = alloc_workqueue("md", WQ_MEM_RECLAIM, 0); if (!md_wq) goto err_wq; diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index d8512423ba72..0855acdfe706 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1505,7 +1505,7 @@ static int nfsiod_start(void) { struct workqueue_struct *wq; dprintk("RPC: creating workqueue nfsiod\n"); - wq = alloc_workqueue("nfsiod", WQ_RESCUER, 0); + wq = alloc_workqueue("nfsiod", WQ_MEM_RECLAIM, 0); if (wq == NULL) return -ENOMEM; nfsiod_workqueue = wq; diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 243fc09b164e..2841cc6bcfda 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -908,7 +908,7 @@ static int rpciod_start(void) * Create the rpciod thread and wait for it to start. */ dprintk("RPC: creating workqueue rpciod\n"); - wq = alloc_workqueue("rpciod", WQ_RESCUER, 0); + wq = alloc_workqueue("rpciod", WQ_MEM_RECLAIM, 0); rpciod_workqueue = wq; return rpciod_workqueue != NULL; } -- cgit v1.2.3 From 672bda337060fa2ff99866a6ebfa3ae036f8b23b Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 25 Jan 2011 11:03:25 +0000 Subject: bonding: fix return value of couple of store functions count is incorrectly returned even in case of fail. Return ret instead. Signed-off-by: Jiri Pirko Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_sysfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 8fd0174c5380..72bb0f6cc9bf 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -1198,7 +1198,7 @@ static ssize_t bonding_store_carrier(struct device *d, bond->dev->name, new_value); } out: - return count; + return ret; } static DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR, bonding_show_carrier, bonding_store_carrier); @@ -1595,7 +1595,7 @@ static ssize_t bonding_store_slaves_active(struct device *d, } } out: - return count; + return ret; } static DEVICE_ATTR(all_slaves_active, S_IRUGO | S_IWUSR, bonding_show_slaves_active, bonding_store_slaves_active); -- cgit v1.2.3 From ac45c12dfb3f727a5a7a3332ed9c11b4a5ab287e Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Wed, 22 Dec 2010 21:14:20 +0530 Subject: ath9k_hw: Fix incorrect macversion and macrev checks There are few places where we are checking for macversion and revsions before RTC is powered ON. However we are reading the macversion and revisions only after RTC is powered ON and so both macversion and revisions are actully zero and this leads to incorrect srev checks Incorrect srev checks can cause registers to be configured wrongly and can cause unexpected behavior. Fixing this seems to address the ASPM issue that we have observed. The laptop becomes very slow and hangs mostly with ASPM L1 enabled without this fix. fix this by reading the macversion and revisisons even before we start using them. There is no reason why should we delay reading this info until RTC is powered on as this is just a register information. Cc: Stable Kernel Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 1afb8bb85756..c0838c216aab 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -492,6 +492,8 @@ static int __ath9k_hw_init(struct ath_hw *ah) if (ah->hw_version.devid == AR5416_AR9100_DEVID) ah->hw_version.macVersion = AR_SREV_VERSION_9100; + ath9k_hw_read_revisions(ah); + if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { ath_err(common, "Couldn't reset chip\n"); return -EIO; @@ -1079,8 +1081,6 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) return false; } - ath9k_hw_read_revisions(ah); - return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM); } -- cgit v1.2.3 From 0a8d7cb0c8182df7a28ad719780071178c386f0f Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Wed, 22 Dec 2010 19:17:18 +0530 Subject: ath9k_hw: read and backup AR_WA register value even before chip reset on. We need to read and backup AR_WA register value permanently and reading this after the chip is awakened results in this register being zeroed out. This seems to fix the ASPM with L1 enabled issue that we have observed. The laptop becomes very slow and hangs mostly with ASPM L1 enabled without this fix. Cc: Stable Kernel Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index c0838c216aab..bc92b4579b27 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -494,6 +494,15 @@ static int __ath9k_hw_init(struct ath_hw *ah) ath9k_hw_read_revisions(ah); + /* + * Read back AR_WA into a permanent copy and set bits 14 and 17. + * We need to do this to avoid RMW of this register. We cannot + * read the reg when chip is asleep. + */ + ah->WARegVal = REG_READ(ah, AR_WA); + ah->WARegVal |= (AR_WA_D3_L1_DISABLE | + AR_WA_ASPM_TIMER_BASED_DISABLE); + if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { ath_err(common, "Couldn't reset chip\n"); return -EIO; @@ -562,14 +571,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) ath9k_hw_init_mode_regs(ah); - /* - * Read back AR_WA into a permanent copy and set bits 14 and 17. - * We need to do this to avoid RMW of this register. We cannot - * read the reg when chip is asleep. - */ - ah->WARegVal = REG_READ(ah, AR_WA); - ah->WARegVal |= (AR_WA_D3_L1_DISABLE | - AR_WA_ASPM_TIMER_BASED_DISABLE); if (ah->is_pciexpress) ath9k_hw_configpcipowersave(ah, 0, 0); -- cgit v1.2.3 From 97d9c3a354f9eb6b8bfe4bf672bdbe9ff76956e6 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 19 Jan 2011 18:20:52 +0900 Subject: ath5k: ath5k_setup_channels cleanup and whitespace Remove useless test_bit - it's not going to happen because of the way this function is called only when that bit is set. And fix some whitespace. Signed-off-by: Bruno Randolf Acked-by: Bob Copeland Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 76a4e55265c3..8611f24cdf6a 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -262,21 +262,16 @@ static bool ath5k_is_standard_channel(short chan, enum ieee80211_band band) } static unsigned int -ath5k_setup_channels(struct ath5k_hw *ah, - struct ieee80211_channel *channels, - unsigned int mode, - unsigned int max) +ath5k_setup_channels(struct ath5k_hw *ah, struct ieee80211_channel *channels, + unsigned int mode, unsigned int max) { unsigned int count, size, chfreq, freq, ch; enum ieee80211_band band; - if (!test_bit(mode, ah->ah_modes)) - return 0; - switch (mode) { case AR5K_MODE_11A: /* 1..220, but 2GHz frequencies are filtered by check_channel */ - size = 220 ; + size = 220; chfreq = CHANNEL_5GHZ; band = IEEE80211_BAND_5GHZ; break; -- cgit v1.2.3 From b4495ed88b782febddfa5bb99c87d75724520ecf Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 25 Jan 2011 15:58:47 +0000 Subject: tg3: Revise 5719 internal FIFO overflow solution Commit cf79003d598b1f82a4caa0564107283b4f560e14, entitled "tg3: Fix 5719 internal FIFO overflow problem", proposed a way to solve an internal FIFO overflow problem. We have since discovered a slightly better way to solve the problem. This patch changes the code so that the problem is contained closer to the problem source. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 46 ++++++++-------------------------------------- drivers/net/tg3.h | 4 ++++ 2 files changed, 12 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 7841a8f69998..b944cc64a409 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8227,8 +8227,12 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) { val = tr32(TG3_RDMA_RSRVCTRL_REG); if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { - val &= ~TG3_RDMA_RSRVCTRL_TXMRGN_MASK; - val |= TG3_RDMA_RSRVCTRL_TXMRGN_320B; + val &= ~(TG3_RDMA_RSRVCTRL_TXMRGN_MASK | + TG3_RDMA_RSRVCTRL_FIFO_LWM_MASK | + TG3_RDMA_RSRVCTRL_FIFO_HWM_MASK); + val |= TG3_RDMA_RSRVCTRL_TXMRGN_320B | + TG3_RDMA_RSRVCTRL_FIFO_LWM_1_5K | + TG3_RDMA_RSRVCTRL_FIFO_HWM_1_5K; } tw32(TG3_RDMA_RSRVCTRL_REG, val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX); @@ -13394,42 +13398,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS; tp->pcie_readrq = 4096; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { - u16 word; - - pci_read_config_word(tp->pdev, - tp->pcie_cap + PCI_EXP_LNKSTA, - &word); - switch (word & PCI_EXP_LNKSTA_CLS) { - case PCI_EXP_LNKSTA_CLS_2_5GB: - word &= PCI_EXP_LNKSTA_NLW; - word >>= PCI_EXP_LNKSTA_NLW_SHIFT; - switch (word) { - case 2: - tp->pcie_readrq = 2048; - break; - case 4: - tp->pcie_readrq = 1024; - break; - } - break; - - case PCI_EXP_LNKSTA_CLS_5_0GB: - word &= PCI_EXP_LNKSTA_NLW; - word >>= PCI_EXP_LNKSTA_NLW_SHIFT; - switch (word) { - case 1: - tp->pcie_readrq = 2048; - break; - case 2: - tp->pcie_readrq = 1024; - break; - case 4: - tp->pcie_readrq = 512; - break; - } - } - } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + tp->pcie_readrq = 2048; pcie_set_readrq(tp->pdev, tp->pcie_readrq); diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index d62c8d937c82..0a0987aeb32e 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1333,6 +1333,10 @@ #define TG3_RDMA_RSRVCTRL_REG 0x00004900 #define TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX 0x00000004 +#define TG3_RDMA_RSRVCTRL_FIFO_LWM_1_5K 0x00000c00 +#define TG3_RDMA_RSRVCTRL_FIFO_LWM_MASK 0x00000ff0 +#define TG3_RDMA_RSRVCTRL_FIFO_HWM_1_5K 0x000c0000 +#define TG3_RDMA_RSRVCTRL_FIFO_HWM_MASK 0x000ff000 #define TG3_RDMA_RSRVCTRL_TXMRGN_320B 0x28000000 #define TG3_RDMA_RSRVCTRL_TXMRGN_MASK 0xffe00000 /* 0x4904 --> 0x4910 unused */ -- cgit v1.2.3 From 4d163b75e979833979cc401ae433cb1d7743d57e Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 25 Jan 2011 15:58:48 +0000 Subject: tg3: Fix 5719 A0 tx completion bug The 5719 A0 has a bug that manifests itself as if the chipset were reordering memory writes. The best known way to solve this problem is to turn off LSO and jumbo frames. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 12 ++++++++---- drivers/net/tg3.h | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index b944cc64a409..d6d081716af0 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8108,8 +8108,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) /* Program the jumbo buffer descriptor ring control * blocks on those devices that have them. */ - if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) && - !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) { + if (tp->pci_chip_rev_id == CHIPREV_ID_5719_A0 || + ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) && + !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))) { /* Setup replenish threshold. */ tw32(RCVBDI_JUMBO_THRESH, tp->rx_jumbo_pending / 8); @@ -13329,7 +13330,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) } /* Determine TSO capabilities */ - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) + if (tp->pci_chip_rev_id == CHIPREV_ID_5719_A0) + ; /* Do nothing. HW bug. */ + else if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) tp->tg3_flags2 |= TG3_FLG2_HW_TSO_3; else if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) @@ -13380,7 +13383,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->tg3_flags3 |= TG3_FLG3_40BIT_DMA_LIMIT_BUG; } - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) + if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) && + tp->pci_chip_rev_id != CHIPREV_ID_5719_A0) tp->tg3_flags3 |= TG3_FLG3_USE_JUMBO_BDFLAG; if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) || diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 0a0987aeb32e..52ae6441af75 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -141,6 +141,7 @@ #define CHIPREV_ID_57780_A1 0x57780001 #define CHIPREV_ID_5717_A0 0x05717000 #define CHIPREV_ID_57765_A0 0x57785000 +#define CHIPREV_ID_5719_A0 0x05719000 #define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12) #define ASIC_REV_5700 0x07 #define ASIC_REV_5701 0x00 -- cgit v1.2.3 From bf933c802763b2beb1a1d4977f00af1a78c4fb70 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 25 Jan 2011 15:58:49 +0000 Subject: tg3: Use new VLAN code This patch pivots the tg3 driver to the new VLAN infrastructure. All references to vlgrp have been removed. The driver still attempts to disable VLAN tag stripping if CONFIG_VLAN_8021Q or CONFIG_VLAN_8021Q_MODULE is not defined. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 95 ++++++------------------------------------------------- drivers/net/tg3.h | 3 -- 2 files changed, 10 insertions(+), 88 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index d6d081716af0..d4b29f424085 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -60,12 +60,6 @@ #define BAR_0 0 #define BAR_2 2 -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -#define TG3_VLAN_TAG_USED 1 -#else -#define TG3_VLAN_TAG_USED 0 -#endif - #include "tg3.h" #define DRV_MODULE_NAME "tg3" @@ -134,9 +128,6 @@ TG3_TX_RING_SIZE) #define NEXT_TX(N) (((N) + 1) & (TG3_TX_RING_SIZE - 1)) -#define TG3_RX_DMA_ALIGN 16 -#define TG3_RX_HEADROOM ALIGN(VLAN_HLEN, TG3_RX_DMA_ALIGN) - #define TG3_DMA_BYTE_ENAB 64 #define TG3_RX_STD_DMA_SZ 1536 @@ -4722,8 +4713,6 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) struct sk_buff *skb; dma_addr_t dma_addr; u32 opaque_key, desc_idx, *post_ptr; - bool hw_vlan __maybe_unused = false; - u16 vtag __maybe_unused = 0; desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; @@ -4782,12 +4771,12 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) tg3_recycle_rx(tnapi, tpr, opaque_key, desc_idx, *post_ptr); - copy_skb = netdev_alloc_skb(tp->dev, len + VLAN_HLEN + + copy_skb = netdev_alloc_skb(tp->dev, len + TG3_RAW_IP_ALIGN); if (copy_skb == NULL) goto drop_it_no_recycle; - skb_reserve(copy_skb, TG3_RAW_IP_ALIGN + VLAN_HLEN); + skb_reserve(copy_skb, TG3_RAW_IP_ALIGN); skb_put(copy_skb, len); pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); skb_copy_from_linear_data(skb, copy_skb->data, len); @@ -4814,30 +4803,11 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) } if (desc->type_flags & RXD_FLAG_VLAN && - !(tp->rx_mode & RX_MODE_KEEP_VLAN_TAG)) { - vtag = desc->err_vlan & RXD_VLAN_MASK; -#if TG3_VLAN_TAG_USED - if (tp->vlgrp) - hw_vlan = true; - else -#endif - { - struct vlan_ethhdr *ve = (struct vlan_ethhdr *) - __skb_push(skb, VLAN_HLEN); - - memmove(ve, skb->data + VLAN_HLEN, - ETH_ALEN * 2); - ve->h_vlan_proto = htons(ETH_P_8021Q); - ve->h_vlan_TCI = htons(vtag); - } - } + !(tp->rx_mode & RX_MODE_KEEP_VLAN_TAG)) + __vlan_hwaccel_put_tag(skb, + desc->err_vlan & RXD_VLAN_MASK); -#if TG3_VLAN_TAG_USED - if (hw_vlan) - vlan_gro_receive(&tnapi->napi, tp->vlgrp, vtag, skb); - else -#endif - napi_gro_receive(&tnapi->napi, skb); + napi_gro_receive(&tnapi->napi, skb); received++; budget--; @@ -5740,11 +5710,9 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, base_flags |= TXD_FLAG_TCPUDP_CSUM; } -#if TG3_VLAN_TAG_USED if (vlan_tx_tag_present(skb)) base_flags |= (TXD_FLAG_VLAN | (vlan_tx_tag_get(skb) << 16)); -#endif len = skb_headlen(skb); @@ -5986,11 +5954,10 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb, } } } -#if TG3_VLAN_TAG_USED + if (vlan_tx_tag_present(skb)) base_flags |= (TXD_FLAG_VLAN | (vlan_tx_tag_get(skb) << 16)); -#endif if ((tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) && !mss && skb->len > VLAN_ETH_FRAME_LEN) @@ -9537,17 +9504,10 @@ static void __tg3_set_rx_mode(struct net_device *dev) rx_mode = tp->rx_mode & ~(RX_MODE_PROMISC | RX_MODE_KEEP_VLAN_TAG); +#if !defined(CONFIG_VLAN_8021Q) && !defined(CONFIG_VLAN_8021Q_MODULE) /* When ASF is in use, we always keep the RX_MODE_KEEP_VLAN_TAG * flag clear. */ -#if TG3_VLAN_TAG_USED - if (!tp->vlgrp && - !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) - rx_mode |= RX_MODE_KEEP_VLAN_TAG; -#else - /* By definition, VLAN is disabled always in this - * case. - */ if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) rx_mode |= RX_MODE_KEEP_VLAN_TAG; #endif @@ -11235,31 +11195,6 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return -EOPNOTSUPP; } -#if TG3_VLAN_TAG_USED -static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -{ - struct tg3 *tp = netdev_priv(dev); - - if (!netif_running(dev)) { - tp->vlgrp = grp; - return; - } - - tg3_netif_stop(tp); - - tg3_full_lock(tp, 0); - - tp->vlgrp = grp; - - /* Update RX_MODE_KEEP_VLAN_TAG bit in RX_MODE register. */ - __tg3_set_rx_mode(dev); - - tg3_netif_start(tp); - - tg3_full_unlock(tp); -} -#endif - static int tg3_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) { struct tg3 *tp = netdev_priv(dev); @@ -13071,9 +13006,7 @@ static struct pci_dev * __devinit tg3_find_peer(struct tg3 *); static void inline vlan_features_add(struct net_device *dev, unsigned long flags) { -#if TG3_VLAN_TAG_USED dev->vlan_features |= flags; -#endif } static inline u32 tg3_rx_ret_ring_size(struct tg3 *tp) @@ -13835,11 +13768,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) else tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES; - tp->rx_offset = NET_IP_ALIGN + TG3_RX_HEADROOM; + tp->rx_offset = NET_IP_ALIGN; tp->rx_copy_thresh = TG3_RX_COPY_THRESHOLD; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 && (tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) { - tp->rx_offset -= NET_IP_ALIGN; + tp->rx_offset = 0; #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS tp->rx_copy_thresh = ~(u16)0; #endif @@ -14603,9 +14536,6 @@ static const struct net_device_ops tg3_netdev_ops = { .ndo_do_ioctl = tg3_ioctl, .ndo_tx_timeout = tg3_tx_timeout, .ndo_change_mtu = tg3_change_mtu, -#if TG3_VLAN_TAG_USED - .ndo_vlan_rx_register = tg3_vlan_rx_register, -#endif #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = tg3_poll_controller, #endif @@ -14622,9 +14552,6 @@ static const struct net_device_ops tg3_netdev_ops_dma_bug = { .ndo_do_ioctl = tg3_ioctl, .ndo_tx_timeout = tg3_tx_timeout, .ndo_change_mtu = tg3_change_mtu, -#if TG3_VLAN_TAG_USED - .ndo_vlan_rx_register = tg3_vlan_rx_register, -#endif #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = tg3_poll_controller, #endif @@ -14674,9 +14601,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, SET_NETDEV_DEV(dev, &pdev->dev); -#if TG3_VLAN_TAG_USED dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; -#endif tp = netdev_priv(dev); tp->pdev = pdev; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 52ae6441af75..fc8ecdd7c859 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2813,9 +2813,6 @@ struct tg3 { u32 rx_std_max_post; u32 rx_offset; u32 rx_pkt_map_sz; -#if TG3_VLAN_TAG_USED - struct vlan_group *vlgrp; -#endif /* begin "everything else" cacheline(s) section */ -- cgit v1.2.3 From 0583d52114b19ea06d03dd2cf762a7737c265400 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 25 Jan 2011 15:58:50 +0000 Subject: tg3: Disable multivec mode for 1 MSIX vector For single vector MSI-X allocations, we do not want to enable multivector modes. This patch makes the necessary corrections. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index d4b29f424085..b2a16b4e3caf 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8322,7 +8322,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); udelay(100); - if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX) { + if ((tp->tg3_flags2 & TG3_FLG2_USING_MSIX) && + tp->irq_cnt > 1) { val = tr32(MSGINT_MODE); val |= MSGINT_MODE_MULTIVEC_EN | MSGINT_MODE_ENABLE; tw32(MSGINT_MODE, val); @@ -9062,7 +9063,8 @@ static void tg3_ints_init(struct tg3 *tp) if (tp->tg3_flags2 & TG3_FLG2_USING_MSI_OR_MSIX) { u32 msi_mode = tr32(MSGINT_MODE); - if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX) + if ((tp->tg3_flags2 & TG3_FLG2_USING_MSIX) && + tp->irq_cnt > 1) msi_mode |= MSGINT_MODE_MULTIVEC_EN; tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE); } -- cgit v1.2.3 From f746a3136a61ae535c5d0b49a9418fa21edc61b5 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 25 Jan 2011 15:58:51 +0000 Subject: tg3: Restrict phy ioctl access If management firmware is present and the device is down, the firmware will assume control of the phy. If a phy access were allowed from the host, it will collide with firmware phy accesses, resulting in unpredictable behavior. This patch fixes the problem by disallowing phy accesses during the problematic condition. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index b2a16b4e3caf..370c67a9d08a 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -11165,7 +11165,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) break; /* We have no PHY */ - if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) + if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) || + ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) && + !netif_running(dev))) return -EAGAIN; spin_lock_bh(&tp->lock); @@ -11181,7 +11183,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) break; /* We have no PHY */ - if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) + if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) || + ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) && + !netif_running(dev))) return -EAGAIN; spin_lock_bh(&tp->lock); -- cgit v1.2.3 From 49692ca1e686970bac5726c3fd925427bb3ae89d Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 25 Jan 2011 15:58:52 +0000 Subject: tg3: Fix loopback tests The half-duplex bit in the MAC MODE register will be set during the loopback test if the external link is in half-duplex mode. This will cause the loopback test to fail on newer devices. This patch turns the half-duplex bit off for the test. Also, newer devices fail the internal phy loopback test because the phy link takes a little while to come up. This patch adds code to wait for the link before proceeding with the test. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 370c67a9d08a..9c5690366f37 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10845,8 +10845,9 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) return 0; - mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | - MAC_MODE_PORT_INT_LPBACK; + mac_mode = tp->mac_mode & + ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX); + mac_mode |= MAC_MODE_PORT_INT_LPBACK; if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) mac_mode |= MAC_MODE_LINK_POLARITY; if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY) @@ -10868,7 +10869,8 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) tg3_writephy(tp, MII_BMCR, val); udelay(40); - mac_mode = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK; + mac_mode = tp->mac_mode & + ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX); if (tp->phy_flags & TG3_PHYFLG_IS_FET) { tg3_writephy(tp, MII_TG3_FET_PTEST, MII_TG3_FET_PTEST_FRC_TX_LINK | @@ -10896,6 +10898,13 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) MII_TG3_EXT_CTRL_LNK3_LED_MODE); } tw32(MAC_MODE, mac_mode); + + /* Wait for link */ + for (i = 0; i < 100; i++) { + if (tr32(MAC_TX_STATUS) & TX_STATUS_LINK_UP) + break; + mdelay(1); + } } else { return -EINVAL; } -- cgit v1.2.3 From aba49f2421d5287692aee961ab4ce2981fdf4939 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 25 Jan 2011 15:58:53 +0000 Subject: tg3: Disable MAC loopback test for CPMU devices On CPMU devices, the MAC loopback test does not test any important paths the phy loopback test doesn't also test. The phy loopback test is the more comprehensive test. This patch disables the MAC loopback test for these devices. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 9c5690366f37..f52466d2ece3 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10840,9 +10840,11 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) if (loopback_mode == TG3_MAC_LOOPBACK) { /* HW errata - mac loopback fails in some cases on 5780. * Normal traffic and PHY loopback are not affected by - * errata. + * errata. Also, the MAC loopback test is deprecated for + * all newer ASIC revisions. */ - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 || + (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT)) return 0; mac_mode = tp->mac_mode & -- cgit v1.2.3 From ab78904608bd6e421b81420e4d2f7d5bae9d4660 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 25 Jan 2011 15:58:54 +0000 Subject: tg3: Disable EEE during loopback tests EEE interferes with the hardware's ability to loop a packet back to the host. This patch disables the feature for the duration of the test. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index f52466d2ece3..c333481deb1f 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -11013,14 +11013,19 @@ out: static int tg3_test_loopback(struct tg3 *tp) { int err = 0; - u32 cpmuctrl = 0; + u32 eee_cap, cpmuctrl = 0; if (!netif_running(tp->dev)) return TG3_LOOPBACK_FAILED; + eee_cap = tp->phy_flags & TG3_PHYFLG_EEE_CAP; + tp->phy_flags &= ~TG3_PHYFLG_EEE_CAP; + err = tg3_reset_hw(tp, 1); - if (err) - return TG3_LOOPBACK_FAILED; + if (err) { + err = TG3_LOOPBACK_FAILED; + goto done; + } /* Turn off gphy autopowerdown. */ if (tp->phy_flags & TG3_PHYFLG_ENABLE_APD) @@ -11040,8 +11045,10 @@ static int tg3_test_loopback(struct tg3 *tp) udelay(10); } - if (status != CPMU_MUTEX_GNT_DRIVER) - return TG3_LOOPBACK_FAILED; + if (status != CPMU_MUTEX_GNT_DRIVER) { + err = TG3_LOOPBACK_FAILED; + goto done; + } /* Turn off link-based power management. */ cpmuctrl = tr32(TG3_CPMU_CTRL); @@ -11070,6 +11077,9 @@ static int tg3_test_loopback(struct tg3 *tp) if (tp->phy_flags & TG3_PHYFLG_ENABLE_APD) tg3_phy_toggle_apd(tp, true); +done: + tp->phy_flags |= eee_cap; + return err; } -- cgit v1.2.3 From 21a00ab270f95d32e502d92f166dd75c518d3c5f Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 25 Jan 2011 15:58:55 +0000 Subject: tg3: Fix EEE interoperability issue This patch fixes a problem where EEE will fail to work in certain environments. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 42 +++++++++++++++++++++++++++++++++++------- drivers/net/tg3.h | 4 ++++ 2 files changed, 39 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index c333481deb1f..f2b6257b9ef6 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -1776,9 +1776,29 @@ static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up) tg3_phy_cl45_read(tp, MDIO_MMD_AN, TG3_CL45_D7_EEERES_STAT, &val); - if (val == TG3_CL45_D7_EEERES_STAT_LP_1000T || - val == TG3_CL45_D7_EEERES_STAT_LP_100TX) + switch (val) { + case TG3_CL45_D7_EEERES_STAT_LP_1000T: + switch (GET_ASIC_REV(tp->pci_chip_rev_id)) { + case ASIC_REV_5717: + case ASIC_REV_5719: + case ASIC_REV_57765: + /* Enable SM_DSP clock and tx 6dB coding. */ + val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL | + MII_TG3_AUXCTL_ACTL_SMDSP_ENA | + MII_TG3_AUXCTL_ACTL_TX_6DB; + tg3_writephy(tp, MII_TG3_AUX_CTRL, val); + + tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0000); + + /* Turn off SM_DSP clock. */ + val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL | + MII_TG3_AUXCTL_ACTL_TX_6DB; + tg3_writephy(tp, MII_TG3_AUX_CTRL, val); + } + /* Fallthrough */ + case TG3_CL45_D7_EEERES_STAT_LP_100TX: tp->setlpicnt = 2; + } } if (!tp->setlpicnt) { @@ -2968,11 +2988,19 @@ static void tg3_phy_copper_begin(struct tg3 *tp) MII_TG3_AUXCTL_ACTL_TX_6DB; tg3_writephy(tp, MII_TG3_AUX_CTRL, val); - if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) && - !tg3_phydsp_read(tp, MII_TG3_DSP_CH34TP2, &val)) - tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2, - val | MII_TG3_DSP_CH34TP2_HIBW01); + switch (GET_ASIC_REV(tp->pci_chip_rev_id)) { + case ASIC_REV_5717: + case ASIC_REV_57765: + if (!tg3_phydsp_read(tp, MII_TG3_DSP_CH34TP2, &val)) + tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2, val | + MII_TG3_DSP_CH34TP2_HIBW01); + /* Fall through */ + case ASIC_REV_5719: + val = MII_TG3_DSP_TAP26_ALNOKO | + MII_TG3_DSP_TAP26_RMRXSTO | + MII_TG3_DSP_TAP26_OPCSINPT; + tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val); + } val = 0; if (tp->link_config.autoneg == AUTONEG_ENABLE) { diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index fc8ecdd7c859..1dbe5eca6fed 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2113,6 +2113,10 @@ #define MII_TG3_DSP_TAP1 0x0001 #define MII_TG3_DSP_TAP1_AGCTGT_DFLT 0x0007 +#define MII_TG3_DSP_TAP26 0x001a +#define MII_TG3_DSP_TAP26_ALNOKO 0x0001 +#define MII_TG3_DSP_TAP26_RMRXSTO 0x0002 +#define MII_TG3_DSP_TAP26_OPCSINPT 0x0004 #define MII_TG3_DSP_AADJ1CH0 0x001f #define MII_TG3_DSP_CH34TP2 0x4022 #define MII_TG3_DSP_CH34TP2_HIBW01 0x0010 -- cgit v1.2.3 From d7f2ab20432441c7d4e41cd1745aafc17d712672 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 25 Jan 2011 15:58:56 +0000 Subject: tg3: Fix eee preprocessor naming This patch fixes a preprocessor naming bug for one of the EEE registers. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 2 +- drivers/net/tg3.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index f2b6257b9ef6..64bba302afd5 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7829,7 +7829,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) TG3_CPMU_DBTMR1_LNKIDLE_2047US); tw32_f(TG3_CPMU_EEE_DBTMR2, - TG3_CPMU_DBTMR1_APE_TX_2047US | + TG3_CPMU_DBTMR2_APE_TX_2047US | TG3_CPMU_DBTMR2_TXIDXEQ_2047US); } diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 1dbe5eca6fed..716fc0008af1 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1106,7 +1106,7 @@ #define TG3_CPMU_DBTMR1_PCIEXIT_2047US 0x07ff0000 #define TG3_CPMU_DBTMR1_LNKIDLE_2047US 0x000070ff #define TG3_CPMU_EEE_DBTMR2 0x000036b8 -#define TG3_CPMU_DBTMR1_APE_TX_2047US 0x07ff0000 +#define TG3_CPMU_DBTMR2_APE_TX_2047US 0x07ff0000 #define TG3_CPMU_DBTMR2_TXIDXEQ_2047US 0x000070ff #define TG3_CPMU_EEE_LNKIDL_CTRL 0x000036bc #define TG3_CPMU_EEE_LNKIDL_PCIE_NL0 0x01000000 -- cgit v1.2.3 From b86fb2cfe82fc4a555f0841f5f8ca4db303ed092 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 25 Jan 2011 15:58:57 +0000 Subject: tg3: Update copyrights and update version to 3.117 This patch updates copyrights and updates the tg3 version to 3.117. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 6 +++--- drivers/net/tg3.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 64bba302afd5..cc069528b322 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -4,7 +4,7 @@ * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com) * Copyright (C) 2004 Sun Microsystems Inc. - * Copyright (C) 2005-2010 Broadcom Corporation. + * Copyright (C) 2005-2011 Broadcom Corporation. * * Firmware is: * Derived from proprietary unpublished source code, @@ -64,10 +64,10 @@ #define DRV_MODULE_NAME "tg3" #define TG3_MAJ_NUM 3 -#define TG3_MIN_NUM 116 +#define TG3_MIN_NUM 117 #define DRV_MODULE_VERSION \ __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) -#define DRV_MODULE_RELDATE "December 3, 2010" +#define DRV_MODULE_RELDATE "January 25, 2011" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 716fc0008af1..73884b69b749 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -4,7 +4,7 @@ * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com) * Copyright (C) 2001 Jeff Garzik (jgarzik@pobox.com) * Copyright (C) 2004 Sun Microsystems Inc. - * Copyright (C) 2007-2010 Broadcom Corporation. + * Copyright (C) 2007-2011 Broadcom Corporation. */ #ifndef _T3_H -- cgit v1.2.3 From 682a1694115ec1c8fcd794c35b80354166978207 Mon Sep 17 00:00:00 2001 From: Thomas Chou Date: Tue, 25 Jan 2011 19:22:05 +0000 Subject: smc91x: add devicetree support Signed-off-by: Thomas Chou Reviewed-by: Grant Likely Signed-off-by: David S. Miller --- drivers/net/smc91x.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index 726df611ee17..43654a3bb0ec 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -81,6 +81,7 @@ static const char version[] = #include #include #include +#include #include #include @@ -2394,6 +2395,15 @@ static int smc_drv_resume(struct device *dev) return 0; } +#ifdef CONFIG_OF +static const struct of_device_id smc91x_match[] = { + { .compatible = "smsc,lan91c94", }, + { .compatible = "smsc,lan91c111", }, + {}, +} +MODULE_DEVICE_TABLE(of, smc91x_match); +#endif + static struct dev_pm_ops smc_drv_pm_ops = { .suspend = smc_drv_suspend, .resume = smc_drv_resume, @@ -2406,6 +2416,9 @@ static struct platform_driver smc_driver = { .name = CARDNAME, .owner = THIS_MODULE, .pm = &smc_drv_pm_ops, +#ifdef CONFIG_OF + .of_match_table = smc91x_match, +#endif }, }; -- cgit v1.2.3 From af109f2e323e9dc6aeb49962e3bc0237ce653cb9 Mon Sep 17 00:00:00 2001 From: Sutharsan Ramamoorthy Date: Tue, 25 Jan 2011 21:11:50 -0800 Subject: Staging: Westbridge: fix EXPORT_SYMBOL errors reported by checkpatch.pl This patch fixes errors reported by checkpatch.pl in westbridge device controller driver in the staging tree. File containing EXPORT_SYMBOL() macros for all the APIs exported by the westbridge software has been removed. EXPORT_SYMBOL() macros are added after the corresponding function definitions. Signed-off-by: Sutharsan Ramamoorthy Signed-off-by: Greg Kroah-Hartman --- .../staging/westbridge/astoria/api/src/cyasmisc.c | 20 +++- .../staging/westbridge/astoria/api/src/cyasmtp.c | 8 ++ .../westbridge/astoria/api/src/cyasstorage.c | 33 +++++- .../staging/westbridge/astoria/api/src/cyasusb.c | 33 +++++- .../westbridge/astoria/device/cyandevice_export.h | 132 --------------------- .../staging/westbridge/astoria/device/cyasdevice.c | 3 - 6 files changed, 80 insertions(+), 149 deletions(-) delete mode 100644 drivers/staging/westbridge/astoria/device/cyandevice_export.h (limited to 'drivers') diff --git a/drivers/staging/westbridge/astoria/api/src/cyasmisc.c b/drivers/staging/westbridge/astoria/api/src/cyasmisc.c index 10a52a1ac6fb..7852410b0a4c 100644 --- a/drivers/staging/westbridge/astoria/api/src/cyasmisc.c +++ b/drivers/staging/westbridge/astoria/api/src/cyasmisc.c @@ -926,6 +926,8 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_misc_get_firmware_version); + static cy_as_return_status_t my_handle_response_read_m_c_u_register(cy_as_device *dev_p, cy_as_ll_request_response *req_p, @@ -1115,7 +1117,7 @@ destroy: return ret; } - +EXPORT_SYMBOL(cy_as_misc_read_m_c_u_register); cy_as_return_status_t cy_as_misc_write_m_c_u_register(cy_as_device_handle handle, @@ -1336,6 +1338,7 @@ cy_as_misc_reset(cy_as_device_handle handle, return ret; } +EXPORT_SYMBOL(cy_as_misc_reset); static cy_as_return_status_t get_unallocated_resource(cy_as_device *dev_p, cy_as_resource_type resource) @@ -1508,6 +1511,8 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_misc_acquire_resource); + cy_as_return_status_t cy_as_misc_release_resource(cy_as_device_handle handle, cy_as_resource_type resource) @@ -1560,6 +1565,7 @@ cy_as_misc_release_resource(cy_as_device_handle handle, return CY_AS_ERROR_SUCCESS; } +EXPORT_SYMBOL(cy_as_misc_release_resource); cy_as_return_status_t cy_as_misc_set_trace_level(cy_as_device_handle handle, @@ -1718,6 +1724,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_misc_heart_beat_control); static cy_as_return_status_t my_set_sd_clock_freq( @@ -1805,6 +1812,7 @@ cy_as_misc_set_low_speed_sd_freq( return my_set_sd_clock_freq(dev_p, 0, (uint8_t)setting, cb, client); } +EXPORT_SYMBOL(cy_as_misc_set_low_speed_sd_freq); cy_as_return_status_t cy_as_misc_set_high_speed_sd_freq( @@ -1830,6 +1838,7 @@ cy_as_misc_set_high_speed_sd_freq( return my_set_sd_clock_freq(dev_p, 1, (uint8_t)setting, cb, client); } +EXPORT_SYMBOL(cy_as_misc_set_high_speed_sd_freq); cy_as_return_status_t cy_as_misc_get_gpio_value(cy_as_device_handle handle, @@ -1921,7 +1930,7 @@ destroy: return ret; } - +EXPORT_SYMBOL(cy_as_misc_get_gpio_value); cy_as_return_status_t cy_as_misc_set_gpio_value(cy_as_device_handle handle, @@ -2020,6 +2029,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_misc_set_gpio_value); static cy_as_return_status_t my_enter_standby(cy_as_device *dev_p, cy_bool pin) @@ -2213,6 +2223,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_misc_enter_standby); cy_as_return_status_t cy_as_misc_enter_standby_e_x_u(cy_as_device_handle handle, @@ -2425,6 +2436,7 @@ try_wakeup_again: return ret; } +EXPORT_SYMBOL(cy_as_misc_leave_standby); cy_as_return_status_t cy_as_misc_register_callback( @@ -2526,7 +2538,7 @@ destroy: return ret; } - +EXPORT_SYMBOL(cy_as_misc_storage_changed); cy_as_return_status_t cy_as_misc_enter_suspend( @@ -2634,6 +2646,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_misc_enter_suspend); cy_as_return_status_t cy_as_misc_leave_suspend( @@ -2704,6 +2717,7 @@ cy_as_misc_leave_suspend( return ret; } +EXPORT_SYMBOL(cy_as_misc_leave_suspend); cy_as_return_status_t cy_as_misc_reserve_l_n_a_boot_area(cy_as_device_handle handle, diff --git a/drivers/staging/westbridge/astoria/api/src/cyasmtp.c b/drivers/staging/westbridge/astoria/api/src/cyasmtp.c index d5a8e45010dc..368984633874 100644 --- a/drivers/staging/westbridge/astoria/api/src/cyasmtp.c +++ b/drivers/staging/westbridge/astoria/api/src/cyasmtp.c @@ -402,6 +402,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_mtp_start); static cy_as_return_status_t my_handle_response_mtp_stop(cy_as_device *dev_p, @@ -744,6 +745,7 @@ cy_as_mtp_init_send_object(cy_as_device_handle handle, client, CY_RQT_INIT_SEND_OBJECT); } +EXPORT_SYMBOL(cy_as_mtp_init_send_object); cy_as_return_status_t cy_as_mtp_init_get_object(cy_as_device_handle handle, @@ -763,6 +765,7 @@ cy_as_mtp_init_get_object(cy_as_device_handle handle, transaction_id, cb, client, CY_RQT_INIT_GET_OBJECT); } +EXPORT_SYMBOL(cy_as_mtp_init_get_object); static cy_as_return_status_t my_handle_response_cancel_send_object(cy_as_device *dev_p, @@ -850,6 +853,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_mtp_cancel_send_object); static cy_as_return_status_t my_handle_response_cancel_get_object(cy_as_device *dev_p, @@ -937,6 +941,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_mtp_cancel_get_object); cy_as_return_status_t cy_as_mtp_send_block_table(cy_as_device_handle handle, @@ -1058,6 +1063,7 @@ cy_as_mtp_storage_only_start(cy_as_device_handle handle) dev_p->is_storage_only_mode = cy_true; return CY_AS_ERROR_SUCCESS; } +EXPORT_SYMBOL(cy_as_mtp_storage_only_start); cy_as_return_status_t cy_as_mtp_storage_only_stop(cy_as_device_handle handle, @@ -1126,3 +1132,5 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_mtp_storage_only_stop); + diff --git a/drivers/staging/westbridge/astoria/api/src/cyasstorage.c b/drivers/staging/westbridge/astoria/api/src/cyasstorage.c index 083d869e57c6..2451404b88d4 100644 --- a/drivers/staging/westbridge/astoria/api/src/cyasstorage.c +++ b/drivers/staging/westbridge/astoria/api/src/cyasstorage.c @@ -522,7 +522,7 @@ destroy: return ret; } - +EXPORT_SYMBOL(cy_as_storage_start); static cy_as_return_status_t my_handle_response_storage_stop(cy_as_device *dev_p, @@ -632,6 +632,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_storage_stop); cy_as_return_status_t cy_as_storage_register_callback(cy_as_device_handle handle, @@ -655,7 +656,7 @@ cy_as_storage_register_callback(cy_as_device_handle handle, return CY_AS_ERROR_SUCCESS; } - +EXPORT_SYMBOL(cy_as_storage_register_callback); static cy_as_return_status_t @@ -783,6 +784,7 @@ cy_as_storage_claim(cy_as_device_handle handle, return my_storage_claim(dev_p, NULL, bus, device, CY_AS_REQUEST_RESPONSE_MS, cb, client); } +EXPORT_SYMBOL(cy_as_storage_claim); static cy_as_return_status_t my_handle_response_storage_release(cy_as_device *dev_p, @@ -911,6 +913,7 @@ cy_as_storage_release(cy_as_device_handle handle, return my_storage_release(dev_p, NULL, bus, device, CY_AS_REQUEST_RESPONSE_MS, cb, client); } +EXPORT_SYMBOL(cy_as_storage_release); static cy_as_return_status_t my_handle_response_storage_query_bus(cy_as_device *dev_p, @@ -1059,6 +1062,7 @@ cy_as_storage_query_bus(cy_as_device_handle handle, return my_storage_query_bus(dev_p, bus, cy_as_media_max_media_value, CY_AS_REQUEST_RESPONSE_MS, count, cb, client); } +EXPORT_SYMBOL(cy_as_storage_query_bus); cy_as_return_status_t cy_as_storage_query_media(cy_as_device_handle handle, @@ -1086,6 +1090,7 @@ cy_as_storage_query_media(cy_as_device_handle handle, return my_storage_query_bus(dev_p, bus, type, CY_AS_REQUEST_RESPONSE_EX, count, cb, client); } +EXPORT_SYMBOL(cy_as_storage_query_media); static cy_as_return_status_t my_handle_response_storage_query_device(cy_as_device *dev_p, @@ -1260,6 +1265,7 @@ cy_as_storage_query_device(cy_as_device_handle handle, CY_AS_REQUEST_RESPONSE_MS, data_p->bus, data_p->device, cb, client); } +EXPORT_SYMBOL(cy_as_storage_query_device); static cy_as_return_status_t my_handle_response_storage_query_unit(cy_as_device *dev_p, @@ -1434,7 +1440,7 @@ cy_as_storage_query_unit(cy_as_device_handle handle, return my_storage_query_unit(dev_p, data_p, CY_AS_REQUEST_RESPONSE_MS, data_p->bus, data_p->device, data_p->unit, cb, client); } - +EXPORT_SYMBOL(cy_as_storage_query_unit); static cy_as_return_status_t cy_as_get_block_size(cy_as_device *dev_p, @@ -1615,6 +1621,7 @@ cy_as_storage_device_control(cy_as_device_handle handle, return my_storage_device_control(dev_p, bus, device, card_detect_en, write_prot_en, config_detect, cb, client); } +EXPORT_SYMBOL(cy_as_storage_device_control); static void cy_as_async_storage_callback(cy_as_device *dev_p, @@ -2069,6 +2076,7 @@ cy_as_storage_read(cy_as_device_handle handle, CY_RQT_READ_BLOCK, bus, device, unit, block, data_p, num_blocks); } +EXPORT_SYMBOL(cy_as_storage_read); cy_as_return_status_t cy_as_storage_write(cy_as_device_handle handle, @@ -2089,7 +2097,7 @@ cy_as_storage_write(cy_as_device_handle handle, CY_RQT_WRITE_BLOCK, bus, device, unit, block, data_p, num_blocks); } - +EXPORT_SYMBOL(cy_as_storage_write); cy_as_return_status_t cy_as_storage_read_async(cy_as_device_handle handle, @@ -2110,6 +2118,7 @@ cy_as_storage_read_async(cy_as_device_handle handle, CY_AS_REQUEST_RESPONSE_MS, bus, device, unit, block, data_p, num_blocks, NULL, callback); } +EXPORT_SYMBOL(cy_as_storage_read_async); cy_as_return_status_t cy_as_storage_write_async(cy_as_device_handle handle, @@ -2133,7 +2142,7 @@ cy_as_storage_write_async(cy_as_device_handle handle, CY_AS_REQUEST_RESPONSE_MS, bus, device, unit, block, data_p, num_blocks, NULL, callback); } - +EXPORT_SYMBOL(cy_as_storage_write_async); static void my_storage_cancel_callback( @@ -2196,6 +2205,7 @@ cy_as_storage_cancel_async(cy_as_device_handle handle) return CY_AS_ERROR_SUCCESS; } +EXPORT_SYMBOL(cy_as_storage_cancel_async); /* * This function does all the API side clean-up associated with @@ -2374,6 +2384,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_storage_sd_register_read); cy_as_return_status_t cy_as_storage_create_p_partition( @@ -2450,6 +2461,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_storage_create_p_partition); cy_as_return_status_t cy_as_storage_remove_p_partition( @@ -2519,6 +2531,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_storage_remove_p_partition); static cy_as_return_status_t my_handle_response_get_transfer_amount(cy_as_device *dev_p, @@ -2621,6 +2634,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_storage_get_transfer_amount); cy_as_return_status_t cy_as_storage_erase( @@ -2722,6 +2736,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_storage_erase); static void cy_as_storage_func_callback(cy_as_device *dev_p, @@ -3005,6 +3020,7 @@ cy_as_sdio_direct_read( return cy_as_sdio_direct_io(handle, bus, device, n_function_no, address, misc_buf, 0x00, cy_false, data_p); } +EXPORT_SYMBOL(cy_as_sdio_direct_read); cy_as_return_status_t cy_as_sdio_direct_write( @@ -3020,6 +3036,7 @@ cy_as_sdio_direct_write( return cy_as_sdio_direct_io(handle, bus, device, n_function_no, address, misc_buf, argument, cy_true, data_p); } +EXPORT_SYMBOL(cy_as_sdio_direct_write); /*Cmd53 IO*/ cy_as_return_status_t @@ -3403,6 +3420,7 @@ cy_as_sdio_extended_read( n_function_no, address, misc_buf, argument, cy_false, data_p, callback); } +EXPORT_SYMBOL(cy_as_sdio_extended_read); /* CMD53 Extended Write*/ cy_as_return_status_t @@ -3426,7 +3444,7 @@ cy_as_sdio_extended_write( n_function_no, address, misc_buf, argument, cy_true, data_p, callback); } - +EXPORT_SYMBOL(cy_as_sdio_extended_write); /* Read the CIS info tuples for the given function and Tuple ID*/ cy_as_return_status_t @@ -3617,6 +3635,7 @@ destroy: cy_as_ll_destroy_response(dev_p, reply_p); return ret; } +EXPORT_SYMBOL(cy_as_sdio_query_card); /*Reset SDIO card. */ cy_as_return_status_t @@ -3767,6 +3786,7 @@ destroy: cy_as_ll_destroy_response(dev_p, reply_p); return ret; } +EXPORT_SYMBOL(cy_as_sdio_init_function); /*Query individual functions. */ cy_as_return_status_t @@ -4066,6 +4086,7 @@ cy_as_sdio_set_blocksize( bus, n_function_no, blocksize); return ret; } +EXPORT_SYMBOL(cy_as_sdio_set_blocksize); /* Deinitialize an SDIO function*/ cy_as_return_status_t diff --git a/drivers/staging/westbridge/astoria/api/src/cyasusb.c b/drivers/staging/westbridge/astoria/api/src/cyasusb.c index 7777d9a60a52..d9cb7d49ae7d 100644 --- a/drivers/staging/westbridge/astoria/api/src/cyasusb.c +++ b/drivers/staging/westbridge/astoria/api/src/cyasusb.c @@ -800,6 +800,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_usb_start); void cy_as_usb_reset(cy_as_device *dev_p) @@ -977,6 +978,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_usb_stop); /* * This function registers a callback to be called when @@ -1004,7 +1006,7 @@ cy_as_usb_register_callback(cy_as_device_handle handle, dev_p->usb_event_cb_ms = callback; return CY_AS_ERROR_SUCCESS; } - +EXPORT_SYMBOL(cy_as_usb_register_callback); static cy_as_return_status_t my_handle_response_no_data(cy_as_device *dev_p, @@ -1124,6 +1126,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_usb_connect); static cy_as_return_status_t my_handle_response_disconnect(cy_as_device *dev_p, @@ -1222,6 +1225,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_usb_disconnect); static cy_as_return_status_t my_handle_response_set_enum_config(cy_as_device *dev_p, @@ -1437,7 +1441,7 @@ cy_as_usb_set_enum_config(cy_as_device_handle handle, client ); } - +EXPORT_SYMBOL(cy_as_usb_set_enum_config); static cy_as_return_status_t my_handle_response_get_enum_config(cy_as_device *dev_p, @@ -1622,7 +1626,7 @@ cy_as_usb_get_enum_config(cy_as_device_handle handle, return my_usb_get_enum_config(handle, CY_AS_REQUEST_RESPONSE_MS, config_p, cb, client); } - +EXPORT_SYMBOL(cy_as_usb_get_enum_config); /* * This method sets the USB descriptor for a given entity. @@ -1705,6 +1709,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_usb_set_descriptor); /* * This method clears all descriptors that were previously @@ -1771,6 +1776,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_usb_clear_descriptors); static cy_as_return_status_t my_handle_response_get_descriptor(cy_as_device *dev_p, @@ -1881,6 +1887,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_usb_get_descriptor); cy_as_return_status_t cy_as_usb_set_physical_configuration(cy_as_device_handle handle, @@ -1910,6 +1917,7 @@ cy_as_usb_set_physical_configuration(cy_as_device_handle handle, return CY_AS_ERROR_SUCCESS; } +EXPORT_SYMBOL(cy_as_usb_set_physical_configuration); static cy_bool is_physical_valid(uint8_t config, cy_as_end_point_number_t ep) @@ -2027,6 +2035,7 @@ cy_as_usb_set_end_point_config(cy_as_device_handle handle, return cy_as_dma_enable_end_point(dev_p, ep, config_p->enabled, (cy_as_dma_direction)config_p->dir); } +EXPORT_SYMBOL(cy_as_usb_set_end_point_config); cy_as_return_status_t cy_as_usb_get_end_point_config(cy_as_device_handle handle, @@ -2053,6 +2062,7 @@ cy_as_usb_get_end_point_config(cy_as_device_handle handle, return CY_AS_ERROR_SUCCESS; } +EXPORT_SYMBOL(cy_as_usb_get_end_point_config); /* * Commit the configuration of the various endpoints to the hardware. @@ -2180,6 +2190,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_usb_commit_config); static void sync_request_callback(cy_as_device *dev_p, @@ -2381,6 +2392,7 @@ cy_as_usb_read_data(cy_as_device_handle handle, return ret; } +EXPORT_SYMBOL(cy_as_usb_read_data); cy_as_return_status_t cy_as_usb_read_data_async(cy_as_device_handle handle, @@ -2459,6 +2471,7 @@ cy_as_usb_read_data_async(cy_as_device_handle handle, } return ret; } +EXPORT_SYMBOL(cy_as_usb_read_data_async); cy_as_return_status_t cy_as_usb_write_data(cy_as_device_handle handle, @@ -2571,6 +2584,7 @@ cy_as_usb_write_data(cy_as_device_handle handle, ret = dev_p->usb_error; return ret; } +EXPORT_SYMBOL(cy_as_usb_write_data); static void mtp_write_callback( @@ -2736,6 +2750,7 @@ cy_as_usb_write_data_async(cy_as_device_handle handle, return CY_AS_ERROR_SUCCESS; } +EXPORT_SYMBOL(cy_as_usb_write_data_async); static void my_usb_cancel_async_callback( @@ -2827,6 +2842,7 @@ cy_as_usb_cancel_async(cy_as_device_handle handle, return CY_AS_ERROR_SUCCESS; } +EXPORT_SYMBOL(cy_as_usb_cancel_async); static void cy_as_usb_ack_callback( @@ -3212,7 +3228,7 @@ cy_as_usb_set_nak(cy_as_device_handle handle, return cy_as_usb_nak_stall_request(handle, ep, CY_RQT_ENDPOINT_SET_NAK, cy_true, 0, cb, client); } - +EXPORT_SYMBOL(cy_as_usb_set_nak); cy_as_return_status_t cy_as_usb_clear_nak(cy_as_device_handle handle, @@ -3238,6 +3254,7 @@ cy_as_usb_clear_nak(cy_as_device_handle handle, return cy_as_usb_nak_stall_request(handle, ep, CY_RQT_ENDPOINT_SET_NAK, cy_false, 0, cb, client); } +EXPORT_SYMBOL(cy_as_usb_clear_nak); cy_as_return_status_t cy_as_usb_get_nak(cy_as_device_handle handle, @@ -3265,7 +3282,7 @@ cy_as_usb_get_nak(cy_as_device_handle handle, CY_RQT_GET_ENDPOINT_NAK, CY_RESP_ENDPOINT_NAK, nak_p, cb, client); } - +EXPORT_SYMBOL(cy_as_usb_get_nak); cy_as_return_status_t cy_as_usb_set_stall(cy_as_device_handle handle, @@ -3291,6 +3308,7 @@ cy_as_usb_set_stall(cy_as_device_handle handle, return cy_as_usb_nak_stall_request(handle, ep, CY_RQT_STALL_ENDPOINT, cy_true, 0, cb, client); } +EXPORT_SYMBOL(cy_as_usb_set_stall); cy_as_return_status_t cy_as_usb_clear_stall(cy_as_device_handle handle, @@ -3316,6 +3334,7 @@ cy_as_usb_clear_stall(cy_as_device_handle handle, return cy_as_usb_nak_stall_request(handle, ep, CY_RQT_STALL_ENDPOINT, cy_false, 0, cb, client); } +EXPORT_SYMBOL(cy_as_usb_clear_stall); cy_as_return_status_t cy_as_usb_get_stall(cy_as_device_handle handle, @@ -3342,6 +3361,7 @@ cy_as_usb_get_stall(cy_as_device_handle handle, return cy_as_usb_get_nak_stall(handle, ep, CY_RQT_GET_STALL, CY_RESP_ENDPOINT_STALL, stall_p, cb, client); } +EXPORT_SYMBOL(cy_as_usb_get_stall); cy_as_return_status_t cy_as_usb_signal_remote_wakeup(cy_as_device_handle handle, @@ -3405,6 +3425,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_usb_signal_remote_wakeup); cy_as_return_status_t cy_as_usb_set_m_s_report_threshold(cy_as_device_handle handle, @@ -3482,6 +3503,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_usb_set_m_s_report_threshold); cy_as_return_status_t cy_as_usb_select_m_s_partitions( @@ -3563,6 +3585,7 @@ destroy: return ret; } +EXPORT_SYMBOL(cy_as_usb_select_m_s_partitions); static void cy_as_usb_func_callback( diff --git a/drivers/staging/westbridge/astoria/device/cyandevice_export.h b/drivers/staging/westbridge/astoria/device/cyandevice_export.h deleted file mode 100644 index acb4e07e850c..000000000000 --- a/drivers/staging/westbridge/astoria/device/cyandevice_export.h +++ /dev/null @@ -1,132 +0,0 @@ -/* -## cyandevice_export.h - Linux Antioch device driver file -## -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## This program is free software; you can redistribute it and/or -## modify it under the terms of the GNU General Public License -## as published by the Free Software Foundation; either version 2 -## of the License, or (at your option) any later version. -## -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 51 Franklin Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -/* - * Export Misc APIs that can be used from the other driver modules. - * The APIs to create a device handle and download firmware are not exported - * because they are expected to be used only by this kernel module. - */ -EXPORT_SYMBOL(cy_as_misc_get_firmware_version); -EXPORT_SYMBOL(cy_as_misc_read_m_c_u_register); -EXPORT_SYMBOL(cy_as_misc_reset); -EXPORT_SYMBOL(cy_as_misc_acquire_resource); -EXPORT_SYMBOL(cy_as_misc_release_resource); -EXPORT_SYMBOL(cy_as_misc_enter_standby); -EXPORT_SYMBOL(cy_as_misc_leave_standby); -EXPORT_SYMBOL(cy_as_misc_enter_suspend); -EXPORT_SYMBOL(cy_as_misc_leave_suspend); -EXPORT_SYMBOL(cy_as_misc_storage_changed); -EXPORT_SYMBOL(cy_as_misc_heart_beat_control); -EXPORT_SYMBOL(cy_as_misc_get_gpio_value); -EXPORT_SYMBOL(cy_as_misc_set_gpio_value); -EXPORT_SYMBOL(cy_as_misc_set_low_speed_sd_freq); -EXPORT_SYMBOL(cy_as_misc_set_high_speed_sd_freq); - -/* - * Export the USB APIs that can be used by the dependent kernel modules. - */ -EXPORT_SYMBOL(cy_as_usb_set_end_point_config); -EXPORT_SYMBOL(cy_as_usb_read_data_async); -EXPORT_SYMBOL(cy_as_usb_write_data_async); -EXPORT_SYMBOL(cy_as_usb_cancel_async); -EXPORT_SYMBOL(cy_as_usb_set_stall); -EXPORT_SYMBOL(cy_as_usb_clear_stall); -EXPORT_SYMBOL(cy_as_usb_connect); -EXPORT_SYMBOL(cy_as_usb_disconnect); -EXPORT_SYMBOL(cy_as_usb_start); -EXPORT_SYMBOL(cy_as_usb_stop); -EXPORT_SYMBOL(cy_as_usb_set_enum_config); -EXPORT_SYMBOL(cy_as_usb_get_enum_config); -EXPORT_SYMBOL(cy_as_usb_set_physical_configuration); -EXPORT_SYMBOL(cy_as_usb_register_callback); -EXPORT_SYMBOL(cy_as_usb_commit_config); -EXPORT_SYMBOL(cy_as_usb_set_descriptor); -EXPORT_SYMBOL(cy_as_usb_clear_descriptors); -EXPORT_SYMBOL(cy_as_usb_get_descriptor); -EXPORT_SYMBOL(cy_as_usb_get_end_point_config); -EXPORT_SYMBOL(cy_as_usb_read_data); -EXPORT_SYMBOL(cy_as_usb_write_data); -EXPORT_SYMBOL(cy_as_usb_get_stall); -EXPORT_SYMBOL(cy_as_usb_set_nak); -EXPORT_SYMBOL(cy_as_usb_clear_nak); -EXPORT_SYMBOL(cy_as_usb_get_nak); -EXPORT_SYMBOL(cy_as_usb_signal_remote_wakeup); -EXPORT_SYMBOL(cy_as_usb_set_m_s_report_threshold); -EXPORT_SYMBOL(cy_as_usb_select_m_s_partitions); - -/* - * Export all Storage APIs that can be used by dependent kernel modules. - */ -EXPORT_SYMBOL(cy_as_storage_start); -EXPORT_SYMBOL(cy_as_storage_stop); -EXPORT_SYMBOL(cy_as_storage_register_callback); -EXPORT_SYMBOL(cy_as_storage_query_bus); -EXPORT_SYMBOL(cy_as_storage_query_media); -EXPORT_SYMBOL(cy_as_storage_query_device); -EXPORT_SYMBOL(cy_as_storage_query_unit); -EXPORT_SYMBOL(cy_as_storage_device_control); -EXPORT_SYMBOL(cy_as_storage_claim); -EXPORT_SYMBOL(cy_as_storage_release); -EXPORT_SYMBOL(cy_as_storage_read); -EXPORT_SYMBOL(cy_as_storage_write); -EXPORT_SYMBOL(cy_as_storage_read_async); -EXPORT_SYMBOL(cy_as_storage_write_async); -EXPORT_SYMBOL(cy_as_storage_cancel_async); -EXPORT_SYMBOL(cy_as_storage_sd_register_read); -EXPORT_SYMBOL(cy_as_storage_create_p_partition); -EXPORT_SYMBOL(cy_as_storage_remove_p_partition); -EXPORT_SYMBOL(cy_as_storage_get_transfer_amount); -EXPORT_SYMBOL(cy_as_storage_erase); - -EXPORT_SYMBOL(cy_as_sdio_query_card); -EXPORT_SYMBOL(cy_as_sdio_init_function); -EXPORT_SYMBOL(cy_as_sdio_set_blocksize); -EXPORT_SYMBOL(cy_as_sdio_direct_read); -EXPORT_SYMBOL(cy_as_sdio_direct_write); -EXPORT_SYMBOL(cy_as_sdio_extended_read); -EXPORT_SYMBOL(cy_as_sdio_extended_write); - -EXPORT_SYMBOL(cy_as_hal_alloc); -EXPORT_SYMBOL(cy_as_hal_free); -EXPORT_SYMBOL(cy_as_hal_sleep); -EXPORT_SYMBOL(cy_as_hal_create_sleep_channel); -EXPORT_SYMBOL(cy_as_hal_destroy_sleep_channel); -EXPORT_SYMBOL(cy_as_hal_sleep_on); -EXPORT_SYMBOL(cy_as_hal_wake); -EXPORT_SYMBOL(cy_as_hal_mem_set); - -EXPORT_SYMBOL(cy_as_mtp_storage_only_start); -EXPORT_SYMBOL(cy_as_mtp_storage_only_stop); -EXPORT_SYMBOL(cy_as_mtp_start); -EXPORT_SYMBOL(cy_as_mtp_init_send_object); -EXPORT_SYMBOL(cy_as_mtp_init_get_object); -EXPORT_SYMBOL(cy_as_mtp_cancel_send_object); -EXPORT_SYMBOL(cy_as_mtp_cancel_get_object); - -#ifdef __CY_ASTORIA_SCM_KERNEL_HAL__ -/* Functions in the SCM kernel HAL implementation only. */ -EXPORT_SYMBOL(cy_as_hal_enable_scatter_list); -EXPORT_SYMBOL(cy_as_hal_disable_scatter_list); -#endif - -/*[]*/ diff --git a/drivers/staging/westbridge/astoria/device/cyasdevice.c b/drivers/staging/westbridge/astoria/device/cyasdevice.c index 088973076517..5ca3d41a932d 100644 --- a/drivers/staging/westbridge/astoria/device/cyasdevice.c +++ b/drivers/staging/westbridge/astoria/device/cyasdevice.c @@ -40,9 +40,6 @@ #include "../include/linux/westbridge/cyashal.h" #include "../include/linux/westbridge/cyasregs.h" -/* API exports include file */ -#include "cyandevice_export.h" - typedef struct cyasdevice { /* Handle to the Antioch device */ cy_as_device_handle dev_handle; -- cgit v1.2.3 From bcb6d9161d1720cf68c7f4de0630e91cb95ee60c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 26 Jan 2011 12:12:50 +0100 Subject: wireless/ipw2x00: use system_wq instead of dedicated workqueues With cmwq, there's no reason to use separate workqueues in ipw2x00 drivers. Drop them and use system_wq instead. All used work items are sync canceled on driver detach. Signed-off-by: Tejun Heo Acked-by: "John W. Linville" Cc: linux-wireless@vger.kernel.org --- drivers/net/wireless/ipw2x00/ipw2100.c | 70 +++++------- drivers/net/wireless/ipw2x00/ipw2100.h | 1 - drivers/net/wireless/ipw2x00/ipw2200.c | 196 +++++++++++++++------------------ drivers/net/wireless/ipw2x00/ipw2200.h | 2 - 4 files changed, 118 insertions(+), 151 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 61915f371416..471a52a2f8d4 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -706,11 +706,10 @@ static void schedule_reset(struct ipw2100_priv *priv) netif_stop_queue(priv->net_dev); priv->status |= STATUS_RESET_PENDING; if (priv->reset_backoff) - queue_delayed_work(priv->workqueue, &priv->reset_work, - priv->reset_backoff * HZ); + schedule_delayed_work(&priv->reset_work, + priv->reset_backoff * HZ); else - queue_delayed_work(priv->workqueue, &priv->reset_work, - 0); + schedule_delayed_work(&priv->reset_work, 0); if (priv->reset_backoff < MAX_RESET_BACKOFF) priv->reset_backoff++; @@ -1474,7 +1473,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv) if (priv->stop_hang_check) { priv->stop_hang_check = 0; - queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2); + schedule_delayed_work(&priv->hang_check, HZ / 2); } fail_up: @@ -1808,8 +1807,8 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred) if (priv->stop_rf_kill) { priv->stop_rf_kill = 0; - queue_delayed_work(priv->workqueue, &priv->rf_kill, - round_jiffies_relative(HZ)); + schedule_delayed_work(&priv->rf_kill, + round_jiffies_relative(HZ)); } deferred = 1; @@ -2086,7 +2085,7 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status) priv->status |= STATUS_ASSOCIATING; priv->connect_start = get_seconds(); - queue_delayed_work(priv->workqueue, &priv->wx_event_work, HZ / 10); + schedule_delayed_work(&priv->wx_event_work, HZ / 10); } static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid, @@ -2166,9 +2165,9 @@ static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status) return; if (priv->status & STATUS_SECURITY_UPDATED) - queue_delayed_work(priv->workqueue, &priv->security_work, 0); + schedule_delayed_work(&priv->security_work, 0); - queue_delayed_work(priv->workqueue, &priv->wx_event_work, 0); + schedule_delayed_work(&priv->wx_event_work, 0); } static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status) @@ -2183,8 +2182,7 @@ static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status) /* Make sure the RF Kill check timer is running */ priv->stop_rf_kill = 0; cancel_delayed_work(&priv->rf_kill); - queue_delayed_work(priv->workqueue, &priv->rf_kill, - round_jiffies_relative(HZ)); + schedule_delayed_work(&priv->rf_kill, round_jiffies_relative(HZ)); } static void send_scan_event(void *data) @@ -2219,13 +2217,12 @@ static void isr_scan_complete(struct ipw2100_priv *priv, u32 status) /* Only userspace-requested scan completion events go out immediately */ if (!priv->user_requested_scan) { if (!delayed_work_pending(&priv->scan_event_later)) - queue_delayed_work(priv->workqueue, - &priv->scan_event_later, - round_jiffies_relative(msecs_to_jiffies(4000))); + schedule_delayed_work(&priv->scan_event_later, + round_jiffies_relative(msecs_to_jiffies(4000))); } else { priv->user_requested_scan = 0; cancel_delayed_work(&priv->scan_event_later); - queue_work(priv->workqueue, &priv->scan_event_now); + schedule_work(&priv->scan_event_now); } } @@ -4329,8 +4326,8 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio) /* Make sure the RF_KILL check timer is running */ priv->stop_rf_kill = 0; cancel_delayed_work(&priv->rf_kill); - queue_delayed_work(priv->workqueue, &priv->rf_kill, - round_jiffies_relative(HZ)); + schedule_delayed_work(&priv->rf_kill, + round_jiffies_relative(HZ)); } else schedule_reset(priv); } @@ -4461,20 +4458,17 @@ static void bd_queue_initialize(struct ipw2100_priv *priv, IPW_DEBUG_INFO("exit\n"); } -static void ipw2100_kill_workqueue(struct ipw2100_priv *priv) +static void ipw2100_kill_works(struct ipw2100_priv *priv) { - if (priv->workqueue) { - priv->stop_rf_kill = 1; - priv->stop_hang_check = 1; - cancel_delayed_work(&priv->reset_work); - cancel_delayed_work(&priv->security_work); - cancel_delayed_work(&priv->wx_event_work); - cancel_delayed_work(&priv->hang_check); - cancel_delayed_work(&priv->rf_kill); - cancel_delayed_work(&priv->scan_event_later); - destroy_workqueue(priv->workqueue); - priv->workqueue = NULL; - } + priv->stop_rf_kill = 1; + priv->stop_hang_check = 1; + cancel_delayed_work_sync(&priv->reset_work); + cancel_delayed_work_sync(&priv->security_work); + cancel_delayed_work_sync(&priv->wx_event_work); + cancel_delayed_work_sync(&priv->hang_check); + cancel_delayed_work_sync(&priv->rf_kill); + cancel_work_sync(&priv->scan_event_now); + cancel_delayed_work_sync(&priv->scan_event_later); } static int ipw2100_tx_allocate(struct ipw2100_priv *priv) @@ -6046,7 +6040,7 @@ static void ipw2100_hang_check(struct work_struct *work) priv->last_rtc = rtc; if (!priv->stop_hang_check) - queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2); + schedule_delayed_work(&priv->hang_check, HZ / 2); spin_unlock_irqrestore(&priv->low_lock, flags); } @@ -6062,8 +6056,8 @@ static void ipw2100_rf_kill(struct work_struct *work) if (rf_kill_active(priv)) { IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n"); if (!priv->stop_rf_kill) - queue_delayed_work(priv->workqueue, &priv->rf_kill, - round_jiffies_relative(HZ)); + schedule_delayed_work(&priv->rf_kill, + round_jiffies_relative(HZ)); goto exit_unlock; } @@ -6209,8 +6203,6 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev, INIT_LIST_HEAD(&priv->fw_pend_list); INIT_STAT(&priv->fw_pend_stat); - priv->workqueue = create_workqueue(DRV_NAME); - INIT_DELAYED_WORK(&priv->reset_work, ipw2100_reset_adapter); INIT_DELAYED_WORK(&priv->security_work, ipw2100_security_work); INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work); @@ -6410,7 +6402,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, if (dev->irq) free_irq(dev->irq, priv); - ipw2100_kill_workqueue(priv); + ipw2100_kill_works(priv); /* These are safe to call even if they weren't allocated */ ipw2100_queues_free(priv); @@ -6460,9 +6452,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev) * first, then close() will crash. */ unregister_netdev(dev); - /* ipw2100_down will ensure that there is no more pending work - * in the workqueue's, so we can safely remove them now. */ - ipw2100_kill_workqueue(priv); + ipw2100_kill_works(priv); ipw2100_queues_free(priv); diff --git a/drivers/net/wireless/ipw2x00/ipw2100.h b/drivers/net/wireless/ipw2x00/ipw2100.h index 838002b4881e..99cba968aa58 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.h +++ b/drivers/net/wireless/ipw2x00/ipw2100.h @@ -580,7 +580,6 @@ struct ipw2100_priv { struct tasklet_struct irq_tasklet; - struct workqueue_struct *workqueue; struct delayed_work reset_work; struct delayed_work security_work; struct delayed_work wx_event_work; diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index ae438ed80c2f..160881f234cc 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -894,9 +894,8 @@ static void ipw_led_link_on(struct ipw_priv *priv) /* If we aren't associated, schedule turning the LED off */ if (!(priv->status & STATUS_ASSOCIATED)) - queue_delayed_work(priv->workqueue, - &priv->led_link_off, - LD_TIME_LINK_ON); + schedule_delayed_work(&priv->led_link_off, + LD_TIME_LINK_ON); } spin_unlock_irqrestore(&priv->lock, flags); @@ -939,8 +938,8 @@ static void ipw_led_link_off(struct ipw_priv *priv) * turning the LED on (blink while unassociated) */ if (!(priv->status & STATUS_RF_KILL_MASK) && !(priv->status & STATUS_ASSOCIATED)) - queue_delayed_work(priv->workqueue, &priv->led_link_on, - LD_TIME_LINK_OFF); + schedule_delayed_work(&priv->led_link_on, + LD_TIME_LINK_OFF); } @@ -980,13 +979,11 @@ static void __ipw_led_activity_on(struct ipw_priv *priv) priv->status |= STATUS_LED_ACT_ON; cancel_delayed_work(&priv->led_act_off); - queue_delayed_work(priv->workqueue, &priv->led_act_off, - LD_TIME_ACT_ON); + schedule_delayed_work(&priv->led_act_off, LD_TIME_ACT_ON); } else { /* Reschedule LED off for full time period */ cancel_delayed_work(&priv->led_act_off); - queue_delayed_work(priv->workqueue, &priv->led_act_off, - LD_TIME_ACT_ON); + schedule_delayed_work(&priv->led_act_off, LD_TIME_ACT_ON); } } @@ -1795,13 +1792,11 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio) if (disable_radio) { priv->status |= STATUS_RF_KILL_SW; - if (priv->workqueue) { - cancel_delayed_work(&priv->request_scan); - cancel_delayed_work(&priv->request_direct_scan); - cancel_delayed_work(&priv->request_passive_scan); - cancel_delayed_work(&priv->scan_event); - } - queue_work(priv->workqueue, &priv->down); + cancel_delayed_work(&priv->request_scan); + cancel_delayed_work(&priv->request_direct_scan); + cancel_delayed_work(&priv->request_passive_scan); + cancel_delayed_work(&priv->scan_event); + schedule_work(&priv->down); } else { priv->status &= ~STATUS_RF_KILL_SW; if (rf_kill_active(priv)) { @@ -1809,10 +1804,10 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio) "disabled by HW switch\n"); /* Make sure the RF_KILL check timer is running */ cancel_delayed_work(&priv->rf_kill); - queue_delayed_work(priv->workqueue, &priv->rf_kill, - round_jiffies_relative(2 * HZ)); + schedule_delayed_work(&priv->rf_kill, + round_jiffies_relative(2 * HZ)); } else - queue_work(priv->workqueue, &priv->up); + schedule_work(&priv->up); } return 1; @@ -2063,7 +2058,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) cancel_delayed_work(&priv->request_passive_scan); cancel_delayed_work(&priv->scan_event); schedule_work(&priv->link_down); - queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ); + schedule_delayed_work(&priv->rf_kill, 2 * HZ); handled |= IPW_INTA_BIT_RF_KILL_DONE; } @@ -2103,7 +2098,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) priv->status &= ~STATUS_HCMD_ACTIVE; wake_up_interruptible(&priv->wait_command_queue); - queue_work(priv->workqueue, &priv->adapter_restart); + schedule_work(&priv->adapter_restart); handled |= IPW_INTA_BIT_FATAL_ERROR; } @@ -2323,11 +2318,6 @@ static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac) return ipw_send_cmd_pdu(priv, IPW_CMD_ADAPTER_ADDRESS, ETH_ALEN, mac); } -/* - * NOTE: This must be executed from our workqueue as it results in udelay - * being called which may corrupt the keyboard if executed on default - * workqueue - */ static void ipw_adapter_restart(void *adapter) { struct ipw_priv *priv = adapter; @@ -2368,13 +2358,13 @@ static void ipw_scan_check(void *data) IPW_DEBUG_SCAN("Scan completion watchdog resetting " "adapter after (%dms).\n", jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG)); - queue_work(priv->workqueue, &priv->adapter_restart); + schedule_work(&priv->adapter_restart); } else if (priv->status & STATUS_SCANNING) { IPW_DEBUG_SCAN("Scan completion watchdog aborting scan " "after (%dms).\n", jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG)); ipw_abort_scan(priv); - queue_delayed_work(priv->workqueue, &priv->scan_check, HZ); + schedule_delayed_work(&priv->scan_check, HZ); } } @@ -3943,7 +3933,7 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet) if (priv->status & STATUS_ASSOCIATING) { IPW_DEBUG_ASSOC("Disassociating while associating.\n"); - queue_work(priv->workqueue, &priv->disassociate); + schedule_work(&priv->disassociate); return; } @@ -4360,8 +4350,7 @@ static void ipw_gather_stats(struct ipw_priv *priv) priv->quality = quality; - queue_delayed_work(priv->workqueue, &priv->gather_stats, - IPW_STATS_INTERVAL); + schedule_delayed_work(&priv->gather_stats, IPW_STATS_INTERVAL); } static void ipw_bg_gather_stats(struct work_struct *work) @@ -4396,10 +4385,10 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv, IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | IPW_DL_STATE, "Aborting scan with missed beacon.\n"); - queue_work(priv->workqueue, &priv->abort_scan); + schedule_work(&priv->abort_scan); } - queue_work(priv->workqueue, &priv->disassociate); + schedule_work(&priv->disassociate); return; } @@ -4425,8 +4414,7 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv, if (!(priv->status & STATUS_ROAMING)) { priv->status |= STATUS_ROAMING; if (!(priv->status & STATUS_SCANNING)) - queue_delayed_work(priv->workqueue, - &priv->request_scan, 0); + schedule_delayed_work(&priv->request_scan, 0); } return; } @@ -4439,7 +4427,7 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv, * channels..) */ IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | IPW_DL_STATE, "Aborting scan with missed beacon.\n"); - queue_work(priv->workqueue, &priv->abort_scan); + schedule_work(&priv->abort_scan); } IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count); @@ -4462,8 +4450,8 @@ static void handle_scan_event(struct ipw_priv *priv) /* Only userspace-requested scan completion events go out immediately */ if (!priv->user_requested_scan) { if (!delayed_work_pending(&priv->scan_event)) - queue_delayed_work(priv->workqueue, &priv->scan_event, - round_jiffies_relative(msecs_to_jiffies(4000))); + schedule_delayed_work(&priv->scan_event, + round_jiffies_relative(msecs_to_jiffies(4000))); } else { union iwreq_data wrqu; @@ -4516,20 +4504,17 @@ static void ipw_rx_notification(struct ipw_priv *priv, IPW_DEBUG_ASSOC ("queueing adhoc check\n"); - queue_delayed_work(priv-> - workqueue, - &priv-> - adhoc_check, - le16_to_cpu(priv-> - assoc_request. - beacon_interval)); + schedule_delayed_work( + &priv->adhoc_check, + le16_to_cpu(priv-> + assoc_request. + beacon_interval)); break; } priv->status &= ~STATUS_ASSOCIATING; priv->status |= STATUS_ASSOCIATED; - queue_work(priv->workqueue, - &priv->system_config); + schedule_work(&priv->system_config); #ifdef CONFIG_IPW2200_QOS #define IPW_GET_PACKET_STYPE(x) WLAN_FC_GET_STYPE( \ @@ -4792,43 +4777,37 @@ static void ipw_rx_notification(struct ipw_priv *priv, #ifdef CONFIG_IPW2200_MONITOR if (priv->ieee->iw_mode == IW_MODE_MONITOR) { priv->status |= STATUS_SCAN_FORCED; - queue_delayed_work(priv->workqueue, - &priv->request_scan, 0); + schedule_delayed_work(&priv->request_scan, 0); break; } priv->status &= ~STATUS_SCAN_FORCED; #endif /* CONFIG_IPW2200_MONITOR */ /* Do queued direct scans first */ - if (priv->status & STATUS_DIRECT_SCAN_PENDING) { - queue_delayed_work(priv->workqueue, - &priv->request_direct_scan, 0); - } + if (priv->status & STATUS_DIRECT_SCAN_PENDING) + schedule_delayed_work(&priv->request_direct_scan, 0); if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING | STATUS_ROAMING | STATUS_DISASSOCIATING))) - queue_work(priv->workqueue, &priv->associate); + schedule_work(&priv->associate); else if (priv->status & STATUS_ROAMING) { if (x->status == SCAN_COMPLETED_STATUS_COMPLETE) /* If a scan completed and we are in roam mode, then * the scan that completed was the one requested as a * result of entering roam... so, schedule the * roam work */ - queue_work(priv->workqueue, - &priv->roam); + schedule_work(&priv->roam); else /* Don't schedule if we aborted the scan */ priv->status &= ~STATUS_ROAMING; } else if (priv->status & STATUS_SCAN_PENDING) - queue_delayed_work(priv->workqueue, - &priv->request_scan, 0); + schedule_delayed_work(&priv->request_scan, 0); else if (priv->config & CFG_BACKGROUND_SCAN && priv->status & STATUS_ASSOCIATED) - queue_delayed_work(priv->workqueue, - &priv->request_scan, - round_jiffies_relative(HZ)); + schedule_delayed_work(&priv->request_scan, + round_jiffies_relative(HZ)); /* Send an empty event to user space. * We don't send the received data on the event because @@ -5192,7 +5171,7 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv) /* If the pre-allocated buffer pool is dropping low, schedule to * refill it */ if (rxq->free_count <= RX_LOW_WATERMARK) - queue_work(priv->workqueue, &priv->rx_replenish); + schedule_work(&priv->rx_replenish); /* If we've added more space for the firmware to place data, tell it */ if (write != rxq->write) @@ -6133,8 +6112,8 @@ static void ipw_adhoc_check(void *data) return; } - queue_delayed_work(priv->workqueue, &priv->adhoc_check, - le16_to_cpu(priv->assoc_request.beacon_interval)); + schedule_delayed_work(&priv->adhoc_check, + le16_to_cpu(priv->assoc_request.beacon_interval)); } static void ipw_bg_adhoc_check(struct work_struct *work) @@ -6523,8 +6502,7 @@ send_request: } else priv->status &= ~STATUS_SCAN_PENDING; - queue_delayed_work(priv->workqueue, &priv->scan_check, - IPW_SCAN_CHECK_WATCHDOG); + schedule_delayed_work(&priv->scan_check, IPW_SCAN_CHECK_WATCHDOG); done: mutex_unlock(&priv->mutex); return err; @@ -6994,8 +6972,7 @@ static int ipw_qos_handle_probe_response(struct ipw_priv *priv, !memcmp(network->ssid, priv->assoc_network->ssid, network->ssid_len)) { - queue_work(priv->workqueue, - &priv->merge_networks); + schedule_work(&priv->merge_networks); } } @@ -7663,7 +7640,7 @@ static int ipw_associate(void *data) if (priv->status & STATUS_DISASSOCIATING) { IPW_DEBUG_ASSOC("Not attempting association (in " "disassociating)\n "); - queue_work(priv->workqueue, &priv->associate); + schedule_work(&priv->associate); return 0; } @@ -7731,12 +7708,10 @@ static int ipw_associate(void *data) if (!(priv->status & STATUS_SCANNING)) { if (!(priv->config & CFG_SPEED_SCAN)) - queue_delayed_work(priv->workqueue, - &priv->request_scan, - SCAN_INTERVAL); + schedule_delayed_work(&priv->request_scan, + SCAN_INTERVAL); else - queue_delayed_work(priv->workqueue, - &priv->request_scan, 0); + schedule_delayed_work(&priv->request_scan, 0); } return 0; @@ -8899,7 +8874,7 @@ static int ipw_wx_set_mode(struct net_device *dev, priv->ieee->iw_mode = wrqu->mode; - queue_work(priv->workqueue, &priv->adapter_restart); + schedule_work(&priv->adapter_restart); mutex_unlock(&priv->mutex); return err; } @@ -9598,7 +9573,7 @@ static int ipw_wx_set_scan(struct net_device *dev, IPW_DEBUG_WX("Start scan\n"); - queue_delayed_work(priv->workqueue, work, 0); + schedule_delayed_work(work, 0); return 0; } @@ -9937,7 +9912,7 @@ static int ipw_wx_set_monitor(struct net_device *dev, #else priv->net_dev->type = ARPHRD_IEEE80211; #endif - queue_work(priv->workqueue, &priv->adapter_restart); + schedule_work(&priv->adapter_restart); } ipw_set_channel(priv, parms[1]); @@ -9947,7 +9922,7 @@ static int ipw_wx_set_monitor(struct net_device *dev, return 0; } priv->net_dev->type = ARPHRD_ETHER; - queue_work(priv->workqueue, &priv->adapter_restart); + schedule_work(&priv->adapter_restart); } mutex_unlock(&priv->mutex); return 0; @@ -9961,7 +9936,7 @@ static int ipw_wx_reset(struct net_device *dev, { struct ipw_priv *priv = libipw_priv(dev); IPW_DEBUG_WX("RESET\n"); - queue_work(priv->workqueue, &priv->adapter_restart); + schedule_work(&priv->adapter_restart); return 0; } @@ -10551,7 +10526,7 @@ static int ipw_net_set_mac_address(struct net_device *dev, void *p) memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN); printk(KERN_INFO "%s: Setting MAC to %pM\n", priv->net_dev->name, priv->mac_addr); - queue_work(priv->workqueue, &priv->adapter_restart); + schedule_work(&priv->adapter_restart); mutex_unlock(&priv->mutex); return 0; } @@ -10684,9 +10659,7 @@ static void ipw_rf_kill(void *adapter) if (rf_kill_active(priv)) { IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n"); - if (priv->workqueue) - queue_delayed_work(priv->workqueue, - &priv->rf_kill, 2 * HZ); + schedule_delayed_work(&priv->rf_kill, 2 * HZ); goto exit_unlock; } @@ -10697,7 +10670,7 @@ static void ipw_rf_kill(void *adapter) "device\n"); /* we can not do an adapter restart while inside an irq lock */ - queue_work(priv->workqueue, &priv->adapter_restart); + schedule_work(&priv->adapter_restart); } else IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still " "enabled\n"); @@ -10735,7 +10708,7 @@ static void ipw_link_up(struct ipw_priv *priv) notify_wx_assoc_event(priv); if (priv->config & CFG_BACKGROUND_SCAN) - queue_delayed_work(priv->workqueue, &priv->request_scan, HZ); + schedule_delayed_work(&priv->request_scan, HZ); } static void ipw_bg_link_up(struct work_struct *work) @@ -10764,7 +10737,7 @@ static void ipw_link_down(struct ipw_priv *priv) if (!(priv->status & STATUS_EXIT_PENDING)) { /* Queue up another scan... */ - queue_delayed_work(priv->workqueue, &priv->request_scan, 0); + schedule_delayed_work(&priv->request_scan, 0); } else cancel_delayed_work(&priv->scan_event); } @@ -10782,7 +10755,6 @@ static int __devinit ipw_setup_deferred_work(struct ipw_priv *priv) { int ret = 0; - priv->workqueue = create_workqueue(DRV_NAME); init_waitqueue_head(&priv->wait_command_queue); init_waitqueue_head(&priv->wait_state); @@ -11339,8 +11311,7 @@ static int ipw_up(struct ipw_priv *priv) IPW_WARNING("Radio Frequency Kill Switch is On:\n" "Kill switch must be turned off for " "wireless networking to work.\n"); - queue_delayed_work(priv->workqueue, &priv->rf_kill, - 2 * HZ); + schedule_delayed_work(&priv->rf_kill, 2 * HZ); return 0; } @@ -11350,8 +11321,7 @@ static int ipw_up(struct ipw_priv *priv) /* If configure to try and auto-associate, kick * off a scan. */ - queue_delayed_work(priv->workqueue, - &priv->request_scan, 0); + schedule_delayed_work(&priv->request_scan, 0); return 0; } @@ -11817,7 +11787,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev, err = request_irq(pdev->irq, ipw_isr, IRQF_SHARED, DRV_NAME, priv); if (err) { IPW_ERROR("Error allocating IRQ %d\n", pdev->irq); - goto out_destroy_workqueue; + goto out_iounmap; } SET_NETDEV_DEV(net_dev, &pdev->dev); @@ -11885,9 +11855,6 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev, sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group); out_release_irq: free_irq(pdev->irq, priv); - out_destroy_workqueue: - destroy_workqueue(priv->workqueue); - priv->workqueue = NULL; out_iounmap: iounmap(priv->hw_base); out_pci_release_regions: @@ -11930,18 +11897,31 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev) kfree(priv->cmdlog); priv->cmdlog = NULL; } - /* ipw_down will ensure that there is no more pending work - * in the workqueue's, so we can safely remove them now. */ - cancel_delayed_work(&priv->adhoc_check); - cancel_delayed_work(&priv->gather_stats); - cancel_delayed_work(&priv->request_scan); - cancel_delayed_work(&priv->request_direct_scan); - cancel_delayed_work(&priv->request_passive_scan); - cancel_delayed_work(&priv->scan_event); - cancel_delayed_work(&priv->rf_kill); - cancel_delayed_work(&priv->scan_check); - destroy_workqueue(priv->workqueue); - priv->workqueue = NULL; + + /* make sure all works are inactive */ + cancel_delayed_work_sync(&priv->adhoc_check); + cancel_work_sync(&priv->associate); + cancel_work_sync(&priv->disassociate); + cancel_work_sync(&priv->system_config); + cancel_work_sync(&priv->rx_replenish); + cancel_work_sync(&priv->adapter_restart); + cancel_delayed_work_sync(&priv->rf_kill); + cancel_work_sync(&priv->up); + cancel_work_sync(&priv->down); + cancel_delayed_work_sync(&priv->request_scan); + cancel_delayed_work_sync(&priv->request_direct_scan); + cancel_delayed_work_sync(&priv->request_passive_scan); + cancel_delayed_work_sync(&priv->scan_event); + cancel_delayed_work_sync(&priv->gather_stats); + cancel_work_sync(&priv->abort_scan); + cancel_work_sync(&priv->roam); + cancel_delayed_work_sync(&priv->scan_check); + cancel_work_sync(&priv->link_up); + cancel_work_sync(&priv->link_down); + cancel_delayed_work_sync(&priv->led_link_on); + cancel_delayed_work_sync(&priv->led_link_off); + cancel_delayed_work_sync(&priv->led_act_off); + cancel_work_sync(&priv->merge_networks); /* Free MAC hash list for ADHOC */ for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) { @@ -12029,7 +12009,7 @@ static int ipw_pci_resume(struct pci_dev *pdev) priv->suspend_time = get_seconds() - priv->suspend_at; /* Bring the device back up */ - queue_work(priv->workqueue, &priv->up); + schedule_work(&priv->up); return 0; } diff --git a/drivers/net/wireless/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h index d7d049c7a4fa..0441445b8bfa 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.h +++ b/drivers/net/wireless/ipw2x00/ipw2200.h @@ -1299,8 +1299,6 @@ struct ipw_priv { u8 direct_scan_ssid[IW_ESSID_MAX_SIZE]; u8 direct_scan_ssid_len; - struct workqueue_struct *workqueue; - struct delayed_work adhoc_check; struct work_struct associate; struct work_struct disassociate; -- cgit v1.2.3 From 57df5573a56322e6895451f759c19e875252817d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 26 Jan 2011 12:12:50 +0100 Subject: cpufreq: use system_wq instead of dedicated workqueues With cmwq, there's no reason for cpufreq drivers to use separate workqueues. Remove the dedicated workqueues from cpufreq_conservative and cpufreq_ondemand and use system_wq instead. The work items are already sync canceled on stop, so it's already guaranteed that no work is running on module exit. Signed-off-by: Tejun Heo Acked-by: Dave Jones Cc: cpufreq@vger.kernel.org --- drivers/cpufreq/cpufreq_conservative.c | 22 +++------------------- drivers/cpufreq/cpufreq_ondemand.c | 20 +++----------------- 2 files changed, 6 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 526bfbf69611..94284c8473b1 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -81,8 +81,6 @@ static unsigned int dbs_enable; /* number of CPUs using this policy */ */ static DEFINE_MUTEX(dbs_mutex); -static struct workqueue_struct *kconservative_wq; - static struct dbs_tuners { unsigned int sampling_rate; unsigned int sampling_down_factor; @@ -560,7 +558,7 @@ static void do_dbs_timer(struct work_struct *work) dbs_check_cpu(dbs_info); - queue_delayed_work_on(cpu, kconservative_wq, &dbs_info->work, delay); + schedule_delayed_work_on(cpu, &dbs_info->work, delay); mutex_unlock(&dbs_info->timer_mutex); } @@ -572,8 +570,7 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) dbs_info->enable = 1; INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); - queue_delayed_work_on(dbs_info->cpu, kconservative_wq, &dbs_info->work, - delay); + schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work, delay); } static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) @@ -716,25 +713,12 @@ struct cpufreq_governor cpufreq_gov_conservative = { static int __init cpufreq_gov_dbs_init(void) { - int err; - - kconservative_wq = create_workqueue("kconservative"); - if (!kconservative_wq) { - printk(KERN_ERR "Creation of kconservative failed\n"); - return -EFAULT; - } - - err = cpufreq_register_governor(&cpufreq_gov_conservative); - if (err) - destroy_workqueue(kconservative_wq); - - return err; + return cpufreq_register_governor(&cpufreq_gov_conservative); } static void __exit cpufreq_gov_dbs_exit(void) { cpufreq_unregister_governor(&cpufreq_gov_conservative); - destroy_workqueue(kconservative_wq); } diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index c631f27a3dcc..58aa85ea5ec6 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -104,8 +104,6 @@ static unsigned int dbs_enable; /* number of CPUs using this policy */ */ static DEFINE_MUTEX(dbs_mutex); -static struct workqueue_struct *kondemand_wq; - static struct dbs_tuners { unsigned int sampling_rate; unsigned int up_threshold; @@ -667,7 +665,7 @@ static void do_dbs_timer(struct work_struct *work) __cpufreq_driver_target(dbs_info->cur_policy, dbs_info->freq_lo, CPUFREQ_RELATION_H); } - queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay); + schedule_delayed_work_on(cpu, &dbs_info->work, delay); mutex_unlock(&dbs_info->timer_mutex); } @@ -681,8 +679,7 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) dbs_info->sample_type = DBS_NORMAL_SAMPLE; INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); - queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work, - delay); + schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work, delay); } static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) @@ -814,7 +811,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, static int __init cpufreq_gov_dbs_init(void) { - int err; cputime64_t wall; u64 idle_time; int cpu = get_cpu(); @@ -838,22 +834,12 @@ static int __init cpufreq_gov_dbs_init(void) MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10); } - kondemand_wq = create_workqueue("kondemand"); - if (!kondemand_wq) { - printk(KERN_ERR "Creation of kondemand failed\n"); - return -EFAULT; - } - err = cpufreq_register_governor(&cpufreq_gov_ondemand); - if (err) - destroy_workqueue(kondemand_wq); - - return err; + return cpufreq_register_governor(&cpufreq_gov_ondemand); } static void __exit cpufreq_gov_dbs_exit(void) { cpufreq_unregister_governor(&cpufreq_gov_ondemand); - destroy_workqueue(kondemand_wq); } -- cgit v1.2.3 From 1c1e8646963e319132b4cf551fbfd10b364d0aed Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 26 Jan 2011 12:12:50 +0100 Subject: input/tps6507x-ts: use system_wq instead of dedicated workqueue With cmwq, there's no reason to use a separate workqueue. Drop tps6507x_ts->wq and use system_wq instead. Signed-off-by: Tejun Heo Acked-by: Todd Fischer Acked-by: Dmitry Torokhov Cc: linux-input@vger.kernel.org Cc: Dan Carpenter --- drivers/input/touchscreen/tps6507x-ts.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c index c8c136cf7bbc..43031492d733 100644 --- a/drivers/input/touchscreen/tps6507x-ts.c +++ b/drivers/input/touchscreen/tps6507x-ts.c @@ -43,7 +43,6 @@ struct tps6507x_ts { struct input_dev *input_dev; struct device *dev; char phys[32]; - struct workqueue_struct *wq; struct delayed_work work; unsigned polling; /* polling is active */ struct ts_event tc; @@ -220,8 +219,8 @@ done: poll = 1; if (poll) { - schd = queue_delayed_work(tsc->wq, &tsc->work, - msecs_to_jiffies(tsc->poll_period)); + schd = schedule_delayed_work(&tsc->work, + msecs_to_jiffies(tsc->poll_period)); if (schd) tsc->polling = 1; else { @@ -303,7 +302,6 @@ static int tps6507x_ts_probe(struct platform_device *pdev) tsc->input_dev = input_dev; INIT_DELAYED_WORK(&tsc->work, tps6507x_ts_handler); - tsc->wq = create_workqueue("TPS6507x Touchscreen"); if (init_data) { tsc->poll_period = init_data->poll_period; @@ -325,8 +323,8 @@ static int tps6507x_ts_probe(struct platform_device *pdev) if (error) goto err2; - schd = queue_delayed_work(tsc->wq, &tsc->work, - msecs_to_jiffies(tsc->poll_period)); + schd = schedule_delayed_work(&tsc->work, + msecs_to_jiffies(tsc->poll_period)); if (schd) tsc->polling = 1; @@ -341,7 +339,6 @@ static int tps6507x_ts_probe(struct platform_device *pdev) err2: cancel_delayed_work_sync(&tsc->work); - destroy_workqueue(tsc->wq); input_free_device(input_dev); err1: kfree(tsc); @@ -357,7 +354,6 @@ static int __devexit tps6507x_ts_remove(struct platform_device *pdev) struct input_dev *input_dev = tsc->input_dev; cancel_delayed_work_sync(&tsc->work); - destroy_workqueue(tsc->wq); input_unregister_device(input_dev); -- cgit v1.2.3 From 509e7861d8a5e26bb07b5a3a13e2b9e442283631 Mon Sep 17 00:00:00 2001 From: "Cho, Yu-Chen" Date: Wed, 26 Jan 2011 17:10:59 +0800 Subject: Bluetooth: add Atheros BT AR9285 fw supported Add the btusb.c blacklist [03f0:311d] for Atheros AR9285 Malbec BT and add to ath3k.c ath3-1.fw (md5:1211fa34c09e10ba48381586b7c3883d) supported this device. Signed-off-by: Cho, Yu-Chen Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/ath3k.c | 2 ++ drivers/bluetooth/btusb.c | 3 +++ 2 files changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index a126e614601f..333c21289d97 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -39,6 +39,8 @@ static struct usb_device_id ath3k_table[] = { /* Atheros AR3011 with sflash firmware*/ { USB_DEVICE(0x0CF3, 0x3002) }, + /* Atheros AR9285 Malbec with sflash firmware */ + { USB_DEVICE(0x03F0, 0x311D) }, { } /* Terminating entry */ }; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 1da773f899a2..4cefa91e6c34 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -102,6 +102,9 @@ static struct usb_device_id blacklist_table[] = { /* Atheros 3011 with sflash firmware */ { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, + /* Atheros AR9285 Malbec with sflash firmware */ + { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, + /* Broadcom BCM2035 */ { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, -- cgit v1.2.3 From 436d0d985383a2ede326f8ec5117d185690dc3f3 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Fri, 21 Jan 2011 14:03:24 +0530 Subject: ath9k: clean up enums and unused macros Remove unused macros and cleanup buffer_type enumeration Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 7 +++---- drivers/net/wireless/ath/ath9k/xmit.c | 2 -- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index dab0271f1c1a..6636f3c6dcf9 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -95,9 +95,9 @@ struct ath_config { * @BUF_XRETRY: To denote excessive retries of the buffer */ enum buffer_type { - BUF_AMPDU = BIT(2), - BUF_AGGR = BIT(3), - BUF_XRETRY = BIT(5), + BUF_AMPDU = BIT(0), + BUF_AGGR = BIT(1), + BUF_XRETRY = BIT(2), }; #define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU) @@ -137,7 +137,6 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \ WME_AC_VO) -#define ADDBA_EXCHANGE_ATTEMPTS 10 #define ATH_AGGR_DELIM_SZ 4 #define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ /* number of delimiters for encryption padding */ diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 5f05a3abbf6a..6fcf1d708843 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -19,7 +19,6 @@ #define BITS_PER_BYTE 8 #define OFDM_PLCP_BITS 22 -#define HT_RC_2_MCS(_rc) ((_rc) & 0x1f) #define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1) #define L_STF 8 #define L_LTF 8 @@ -32,7 +31,6 @@ #define NUM_SYMBOLS_PER_USEC(_usec) (_usec >> 2) #define NUM_SYMBOLS_PER_USEC_HALFGI(_usec) (((_usec*5)-4)/18) -#define OFDM_SIFS_TIME 16 static u16 bits_per_symbol[][2] = { /* 20MHz 40MHz */ -- cgit v1.2.3 From 9e09b5c96caf3f201f1dcb31539d6a6b2c36d0f9 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 22 Jan 2011 22:46:49 +0100 Subject: carl9170: update fw/hw headers This patch syncs up the header files with the project's main firmware carl9170fw.git. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/fwcmd.h | 1 + drivers/net/wireless/ath/carl9170/fwdesc.h | 28 ++++++++++++++++++++++------ drivers/net/wireless/ath/carl9170/hw.h | 25 +++++++++++++++++++++++++ drivers/net/wireless/ath/carl9170/version.h | 8 ++++---- drivers/net/wireless/ath/carl9170/wlan.h | 20 +++++++++++++++++++- 5 files changed, 71 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h index 3680dfc70f46..30449d21b762 100644 --- a/drivers/net/wireless/ath/carl9170/fwcmd.h +++ b/drivers/net/wireless/ath/carl9170/fwcmd.h @@ -167,6 +167,7 @@ struct carl9170_rx_filter_cmd { #define CARL9170_RX_FILTER_CTL_BACKR 0x20 #define CARL9170_RX_FILTER_MGMT 0x40 #define CARL9170_RX_FILTER_DATA 0x80 +#define CARL9170_RX_FILTER_EVERYTHING (~0) struct carl9170_bcn_ctrl_cmd { __le32 vif_id; diff --git a/drivers/net/wireless/ath/carl9170/fwdesc.h b/drivers/net/wireless/ath/carl9170/fwdesc.h index 71f3821f6058..921066822dd5 100644 --- a/drivers/net/wireless/ath/carl9170/fwdesc.h +++ b/drivers/net/wireless/ath/carl9170/fwdesc.h @@ -69,6 +69,9 @@ enum carl9170fw_feature_list { /* Firmware RX filter | CARL9170_CMD_RX_FILTER */ CARL9170FW_RX_FILTER, + /* Wake up on WLAN */ + CARL9170FW_WOL, + /* KEEP LAST */ __CARL9170FW_FEATURE_NUM }; @@ -78,6 +81,7 @@ enum carl9170fw_feature_list { #define FIX_MAGIC "FIX\0" #define DBG_MAGIC "DBG\0" #define CHK_MAGIC "CHK\0" +#define TXSQ_MAGIC "TXSQ" #define LAST_MAGIC "LAST" #define CARL9170FW_SET_DAY(d) (((d) - 1) % 31) @@ -88,8 +92,10 @@ enum carl9170fw_feature_list { #define CARL9170FW_GET_MONTH(m) ((((m) / 31) % 12) + 1) #define CARL9170FW_GET_YEAR(y) ((y) / 372 + 10) +#define CARL9170FW_MAGIC_SIZE 4 + struct carl9170fw_desc_head { - u8 magic[4]; + u8 magic[CARL9170FW_MAGIC_SIZE]; __le16 length; u8 min_ver; u8 cur_ver; @@ -170,6 +176,16 @@ struct carl9170fw_chk_desc { #define CARL9170FW_CHK_DESC_SIZE \ (sizeof(struct carl9170fw_chk_desc)) +#define CARL9170FW_TXSQ_DESC_MIN_VER 1 +#define CARL9170FW_TXSQ_DESC_CUR_VER 1 +struct carl9170fw_txsq_desc { + struct carl9170fw_desc_head head; + + __le32 seq_table_addr; +} __packed; +#define CARL9170FW_TXSQ_DESC_SIZE \ + (sizeof(struct carl9170fw_txsq_desc)) + #define CARL9170FW_LAST_DESC_MIN_VER 1 #define CARL9170FW_LAST_DESC_CUR_VER 2 struct carl9170fw_last_desc { @@ -189,8 +205,8 @@ struct carl9170fw_last_desc { } static inline void carl9170fw_fill_desc(struct carl9170fw_desc_head *head, - u8 magic[4], __le16 length, - u8 min_ver, u8 cur_ver) + u8 magic[CARL9170FW_MAGIC_SIZE], + __le16 length, u8 min_ver, u8 cur_ver) { head->magic[0] = magic[0]; head->magic[1] = magic[1]; @@ -204,7 +220,7 @@ static inline void carl9170fw_fill_desc(struct carl9170fw_desc_head *head, #define carl9170fw_for_each_hdr(desc, fw_desc) \ for (desc = fw_desc; \ - memcmp(desc->magic, LAST_MAGIC, 4) && \ + memcmp(desc->magic, LAST_MAGIC, CARL9170FW_MAGIC_SIZE) && \ le16_to_cpu(desc->length) >= CARL9170FW_DESC_HEAD_SIZE && \ le16_to_cpu(desc->length) < CARL9170FW_DESC_MAX_LENGTH; \ desc = (void *)((unsigned long)desc + le16_to_cpu(desc->length))) @@ -218,8 +234,8 @@ static inline bool carl9170fw_supports(__le32 list, u8 feature) } static inline bool carl9170fw_desc_cmp(const struct carl9170fw_desc_head *head, - const u8 descid[4], u16 min_len, - u8 compatible_revision) + const u8 descid[CARL9170FW_MAGIC_SIZE], + u16 min_len, u8 compatible_revision) { if (descid[0] == head->magic[0] && descid[1] == head->magic[1] && descid[2] == head->magic[2] && descid[3] == head->magic[3] && diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h index e85df6edfed3..4e30762dd903 100644 --- a/drivers/net/wireless/ath/carl9170/hw.h +++ b/drivers/net/wireless/ath/carl9170/hw.h @@ -463,6 +463,8 @@ #define AR9170_PWR_REG_CHIP_REVISION (AR9170_PWR_REG_BASE + 0x010) #define AR9170_PWR_REG_PLL_ADDAC (AR9170_PWR_REG_BASE + 0x014) +#define AR9170_PWR_PLL_ADDAC_DIV_S 2 +#define AR9170_PWR_PLL_ADDAC_DIV 0xffc #define AR9170_PWR_REG_WATCH_DOG_MAGIC (AR9170_PWR_REG_BASE + 0x020) /* Faraday USB Controller */ @@ -471,6 +473,9 @@ #define AR9170_USB_REG_MAIN_CTRL (AR9170_USB_REG_BASE + 0x000) #define AR9170_USB_MAIN_CTRL_REMOTE_WAKEUP BIT(0) #define AR9170_USB_MAIN_CTRL_ENABLE_GLOBAL_INT BIT(2) +#define AR9170_USB_MAIN_CTRL_GO_TO_SUSPEND BIT(3) +#define AR9170_USB_MAIN_CTRL_RESET BIT(4) +#define AR9170_USB_MAIN_CTRL_CHIP_ENABLE BIT(5) #define AR9170_USB_MAIN_CTRL_HIGHSPEED BIT(6) #define AR9170_USB_REG_DEVICE_ADDRESS (AR9170_USB_REG_BASE + 0x001) @@ -499,6 +504,13 @@ #define AR9170_USB_REG_INTR_GROUP (AR9170_USB_REG_BASE + 0x020) #define AR9170_USB_REG_INTR_SOURCE_0 (AR9170_USB_REG_BASE + 0x021) +#define AR9170_USB_INTR_SRC0_SETUP BIT(0) +#define AR9170_USB_INTR_SRC0_IN BIT(1) +#define AR9170_USB_INTR_SRC0_OUT BIT(2) +#define AR9170_USB_INTR_SRC0_FAIL BIT(3) /* ??? */ +#define AR9170_USB_INTR_SRC0_END BIT(4) /* ??? */ +#define AR9170_USB_INTR_SRC0_ABORT BIT(7) + #define AR9170_USB_REG_INTR_SOURCE_1 (AR9170_USB_REG_BASE + 0x022) #define AR9170_USB_REG_INTR_SOURCE_2 (AR9170_USB_REG_BASE + 0x023) #define AR9170_USB_REG_INTR_SOURCE_3 (AR9170_USB_REG_BASE + 0x024) @@ -506,6 +518,15 @@ #define AR9170_USB_REG_INTR_SOURCE_5 (AR9170_USB_REG_BASE + 0x026) #define AR9170_USB_REG_INTR_SOURCE_6 (AR9170_USB_REG_BASE + 0x027) #define AR9170_USB_REG_INTR_SOURCE_7 (AR9170_USB_REG_BASE + 0x028) +#define AR9170_USB_INTR_SRC7_USB_RESET BIT(1) +#define AR9170_USB_INTR_SRC7_USB_SUSPEND BIT(2) +#define AR9170_USB_INTR_SRC7_USB_RESUME BIT(3) +#define AR9170_USB_INTR_SRC7_ISO_SEQ_ERR BIT(4) +#define AR9170_USB_INTR_SRC7_ISO_SEQ_ABORT BIT(5) +#define AR9170_USB_INTR_SRC7_TX0BYTE BIT(6) +#define AR9170_USB_INTR_SRC7_RX0BYTE BIT(7) + +#define AR9170_USB_REG_IDLE_COUNT (AR9170_USB_REG_BASE + 0x02f) #define AR9170_USB_REG_EP_MAP (AR9170_USB_REG_BASE + 0x030) #define AR9170_USB_REG_EP1_MAP (AR9170_USB_REG_BASE + 0x030) @@ -581,6 +602,10 @@ #define AR9170_USB_REG_MAX_AGG_UPLOAD (AR9170_USB_REG_BASE + 0x110) #define AR9170_USB_REG_UPLOAD_TIME_CTL (AR9170_USB_REG_BASE + 0x114) + +#define AR9170_USB_REG_WAKE_UP (AR9170_USB_REG_BASE + 0x120) +#define AR9170_USB_WAKE_UP_WAKE BIT(0) + #define AR9170_USB_REG_CBUS_CTRL (AR9170_USB_REG_BASE + 0x1f0) #define AR9170_USB_CBUS_CTRL_BUFFER_END (BIT(1)) diff --git a/drivers/net/wireless/ath/carl9170/version.h b/drivers/net/wireless/ath/carl9170/version.h index ee0f84f2a2f6..15095c035169 100644 --- a/drivers/net/wireless/ath/carl9170/version.h +++ b/drivers/net/wireless/ath/carl9170/version.h @@ -1,7 +1,7 @@ #ifndef __CARL9170_SHARED_VERSION_H #define __CARL9170_SHARED_VERSION_H -#define CARL9170FW_VERSION_YEAR 10 -#define CARL9170FW_VERSION_MONTH 10 -#define CARL9170FW_VERSION_DAY 29 -#define CARL9170FW_VERSION_GIT "1.9.0" +#define CARL9170FW_VERSION_YEAR 11 +#define CARL9170FW_VERSION_MONTH 1 +#define CARL9170FW_VERSION_DAY 22 +#define CARL9170FW_VERSION_GIT "1.9.2" #endif /* __CARL9170_SHARED_VERSION_H */ diff --git a/drivers/net/wireless/ath/carl9170/wlan.h b/drivers/net/wireless/ath/carl9170/wlan.h index 24d63b583b6b..9e1324b67e08 100644 --- a/drivers/net/wireless/ath/carl9170/wlan.h +++ b/drivers/net/wireless/ath/carl9170/wlan.h @@ -251,7 +251,7 @@ struct carl9170_tx_superdesc { u8 ampdu_commit_factor:1; u8 ampdu_unused_bit:1; u8 queue:2; - u8 reserved:1; + u8 assign_seq:1; u8 vif_id:3; u8 fill_in_tsf:1; u8 cab:1; @@ -299,6 +299,7 @@ struct _ar9170_tx_hwdesc { #define CARL9170_TX_SUPER_MISC_QUEUE 0x3 #define CARL9170_TX_SUPER_MISC_QUEUE_S 0 +#define CARL9170_TX_SUPER_MISC_ASSIGN_SEQ 0x4 #define CARL9170_TX_SUPER_MISC_VIF_ID 0x38 #define CARL9170_TX_SUPER_MISC_VIF_ID_S 3 #define CARL9170_TX_SUPER_MISC_FILL_IN_TSF 0x40 @@ -413,6 +414,23 @@ enum ar9170_txq { __AR9170_NUM_TXQ, }; +/* + * This is an workaround for several undocumented bugs. + * Don't mess with the QoS/AC <-> HW Queue map, if you don't + * know what you are doing. + * + * Known problems [hardware]: + * * The MAC does not aggregate frames on anything other + * than the first HW queue. + * * when an AMPDU is placed [in the first hw queue] and + * additional frames are already queued on a different + * hw queue, the MAC will ALWAYS freeze. + * + * In a nutshell: The hardware can either do QoS or + * Aggregation but not both at the same time. As a + * result, this makes the device pretty much useless + * for any serious 802.11n setup. + */ static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 2, 1, 0, 3 }; #define AR9170_TXQ_DEPTH 32 -- cgit v1.2.3 From c42d6cf25d648d95387d8a881aa0cab657470726 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 23 Jan 2011 00:10:01 +0100 Subject: carl9170: enable wake-on-lan feature testing Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/fw.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index 546b4e4ec5ea..a4e5b4458c00 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c @@ -264,6 +264,9 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) FIF_PROMISC_IN_BSS; } + if (SUPP(CARL9170FW_WOL)) + device_set_wakeup_enable(&ar->udev->dev, true); + ar->fw.vif_num = otus_desc->vif_num; ar->fw.cmd_bufs = otus_desc->cmd_bufs; ar->fw.address = le32_to_cpu(otus_desc->fw_address); -- cgit v1.2.3 From aa32452dcff1f95976fb28b5a28ecc93f47d0472 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 23 Jan 2011 00:18:28 +0100 Subject: carl9170: utilize fw seq counter for mgmt/non-QoS data frames "mac80211 will properly assign sequence numbers to QoS-data frames but cannot do so correctly for non-QoS-data and management frames because beacons need them from that counter as well and mac80211 cannot guarantee proper sequencing." Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/carl9170.h | 1 + drivers/net/wireless/ath/carl9170/fw.c | 12 ++++++++++++ drivers/net/wireless/ath/carl9170/main.c | 7 +++++++ drivers/net/wireless/ath/carl9170/tx.c | 3 +++ 4 files changed, 23 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index d07ff7f2fd92..420d437f9580 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -283,6 +283,7 @@ struct ar9170 { unsigned int mem_blocks; unsigned int mem_block_size; unsigned int rx_size; + unsigned int tx_seq_table; } fw; /* reset / stuck frames/queue detection */ diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index a4e5b4458c00..9517ede9e2df 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c @@ -150,6 +150,7 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) const struct carl9170fw_otus_desc *otus_desc; const struct carl9170fw_chk_desc *chk_desc; const struct carl9170fw_last_desc *last_desc; + const struct carl9170fw_txsq_desc *txsq_desc; last_desc = carl9170_fw_find_desc(ar, LAST_MAGIC, sizeof(*last_desc), CARL9170FW_LAST_DESC_CUR_VER); @@ -299,6 +300,17 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) } } + txsq_desc = carl9170_fw_find_desc(ar, TXSQ_MAGIC, + sizeof(*txsq_desc), CARL9170FW_TXSQ_DESC_CUR_VER); + + if (txsq_desc) { + ar->fw.tx_seq_table = le32_to_cpu(txsq_desc->seq_table_addr); + if (!valid_cpu_addr(ar->fw.tx_seq_table)) + return -EINVAL; + } else { + ar->fw.tx_seq_table = 0; + } + #undef SUPPORTED return 0; } diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index ecfb80b059d1..ede3d7e5a048 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -662,6 +662,13 @@ init: goto unlock; } + if (ar->fw.tx_seq_table) { + err = carl9170_write_reg(ar, ar->fw.tx_seq_table + vif_id * 4, + 0); + if (err) + goto unlock; + } + unlock: if (err && (vif_id >= 0)) { vif_priv->active = false; diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index 6cc58e052d10..6f41e21d3a1c 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -862,6 +862,9 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) if (unlikely(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)) txc->s.misc |= CARL9170_TX_SUPER_MISC_CAB; + if (unlikely(info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)) + txc->s.misc |= CARL9170_TX_SUPER_MISC_ASSIGN_SEQ; + if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) txc->s.misc |= CARL9170_TX_SUPER_MISC_FILL_IN_TSF; -- cgit v1.2.3 From 8d8d3fdc0d42be0ba75be227465773a54bb48a0b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 24 Jan 2011 19:11:54 +0100 Subject: ath9k: fix misplaced debug code The commit 'ath9k: Add more information to debugfs xmit file.' added more debug counters to ath9k and also added some lines of code to ath9k_hw. Since ath9k_hw is also used by ath9k_htc, its code must not depend on ath9k data structures. In this case it was not fatal, but it's still wrong, so the code needs to be moved back to ath9k. Signed-off-by: Felix Fietkau Cc: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/mac.c | 8 -------- drivers/net/wireless/ath/ath9k/xmit.c | 3 +++ 2 files changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 5f2b93441e5c..c75d40fb86f1 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -16,8 +16,6 @@ #include "hw.h" #include "hw-ops.h" -#include "debug.h" -#include "ath9k.h" static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah, struct ath9k_tx_queue_info *qi) @@ -52,18 +50,12 @@ EXPORT_SYMBOL(ath9k_hw_gettxbuf); void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp) { - struct ath_wiphy *aphy = ah->hw->priv; - struct ath_softc *sc = aphy->sc; - TX_STAT_INC(q, puttxbuf); REG_WRITE(ah, AR_QTXDP(q), txdp); } EXPORT_SYMBOL(ath9k_hw_puttxbuf); void ath9k_hw_txstart(struct ath_hw *ah, u32 q) { - struct ath_wiphy *aphy = ah->hw->priv; - struct ath_softc *sc = aphy->sc; - TX_STAT_INC(q, txstart); ath_dbg(ath9k_hw_common(ah), ATH_DBG_QUEUE, "Enable TXE on queue: %u\n", q); REG_WRITE(ah, AR_Q_TXE, 1 << q); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 6fcf1d708843..fe0b6b3ec697 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1316,6 +1316,7 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, INIT_LIST_HEAD(&txq->txq_fifo[txq->txq_headidx]); list_splice_init(head, &txq->txq_fifo[txq->txq_headidx]); INCR(txq->txq_headidx, ATH_TXFIFO_DEPTH); + TX_STAT_INC(txq->axq_qnum, puttxbuf); ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n", txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); @@ -1323,6 +1324,7 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, list_splice_tail_init(head, &txq->axq_q); if (txq->axq_link == NULL) { + TX_STAT_INC(txq->axq_qnum, puttxbuf); ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n", txq->axq_qnum, ito64(bf->bf_daddr), @@ -1336,6 +1338,7 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, } ath9k_hw_get_desc_link(ah, bf->bf_lastbf->bf_desc, &txq->axq_link); + TX_STAT_INC(txq->axq_qnum, txstart); ath9k_hw_txstart(ah, txq->axq_qnum); } txq->axq_depth++; -- cgit v1.2.3 From 13707f9e5e46342b7b16c58be91ad93a476c3ffd Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 26 Jan 2011 19:28:23 +0000 Subject: drivers/net: remove some rcu sparse warnings Add missing __rcu annotations and helpers. minor : Fix some rcu_dereference() calls in macvtap Signed-off-by: Eric Dumazet Acked-by: Arnd Bergmann Acked-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 6 ++++-- drivers/net/bnx2.h | 2 +- drivers/net/bnx2x/bnx2x.h | 2 +- drivers/net/bnx2x/bnx2x_main.c | 3 ++- drivers/net/cnic.c | 27 ++++++++++++++++++--------- drivers/net/cnic.h | 2 +- drivers/net/hamradio/bpqether.c | 5 +++-- drivers/net/macvtap.c | 18 ++++++++++-------- 8 files changed, 40 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 3dbaf58f681b..2a961b7f7e17 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -435,7 +435,8 @@ bnx2_cnic_stop(struct bnx2 *bp) struct cnic_ctl_info info; mutex_lock(&bp->cnic_lock); - c_ops = bp->cnic_ops; + c_ops = rcu_dereference_protected(bp->cnic_ops, + lockdep_is_held(&bp->cnic_lock)); if (c_ops) { info.cmd = CNIC_CTL_STOP_CMD; c_ops->cnic_ctl(bp->cnic_data, &info); @@ -450,7 +451,8 @@ bnx2_cnic_start(struct bnx2 *bp) struct cnic_ctl_info info; mutex_lock(&bp->cnic_lock); - c_ops = bp->cnic_ops; + c_ops = rcu_dereference_protected(bp->cnic_ops, + lockdep_is_held(&bp->cnic_lock)); if (c_ops) { if (!(bp->flags & BNX2_FLAG_USING_MSIX)) { struct bnx2_napi *bnapi = &bp->bnx2_napi[0]; diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index f459fb2f9add..0132ea959995 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -6759,7 +6759,7 @@ struct bnx2 { u32 tx_wake_thresh; #ifdef BCM_CNIC - struct cnic_ops *cnic_ops; + struct cnic_ops __rcu *cnic_ops; void *cnic_data; #endif diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 8e4183717d91..dfdb9b51ae53 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1110,7 +1110,7 @@ struct bnx2x { #define BNX2X_CNIC_FLAG_MAC_SET 1 void *t2; dma_addr_t t2_mapping; - struct cnic_ops *cnic_ops; + struct cnic_ops __rcu *cnic_ops; void *cnic_data; u32 cnic_tag; struct cnic_eth_dev cnic_eth_dev; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 8cdcf5b39d1e..a2a1bc43a1d2 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -9862,7 +9862,8 @@ static int bnx2x_cnic_ctl_send(struct bnx2x *bp, struct cnic_ctl_info *ctl) int rc = 0; mutex_lock(&bp->cnic_mutex); - c_ops = bp->cnic_ops; + c_ops = rcu_dereference_protected(bp->cnic_ops, + lockdep_is_held(&bp->cnic_mutex)); if (c_ops) rc = c_ops->cnic_ctl(bp->cnic_data, ctl); mutex_unlock(&bp->cnic_mutex); diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 7ff170cbc7dc..c82049635139 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -65,7 +65,14 @@ static LIST_HEAD(cnic_udev_list); static DEFINE_RWLOCK(cnic_dev_lock); static DEFINE_MUTEX(cnic_lock); -static struct cnic_ulp_ops *cnic_ulp_tbl[MAX_CNIC_ULP_TYPE]; +static struct cnic_ulp_ops __rcu *cnic_ulp_tbl[MAX_CNIC_ULP_TYPE]; + +/* helper function, assuming cnic_lock is held */ +static inline struct cnic_ulp_ops *cnic_ulp_tbl_prot(int type) +{ + return rcu_dereference_protected(cnic_ulp_tbl[type], + lockdep_is_held(&cnic_lock)); +} static int cnic_service_bnx2(void *, void *); static int cnic_service_bnx2x(void *, void *); @@ -435,7 +442,7 @@ int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops) return -EINVAL; } mutex_lock(&cnic_lock); - if (cnic_ulp_tbl[ulp_type]) { + if (cnic_ulp_tbl_prot(ulp_type)) { pr_err("%s: Type %d has already been registered\n", __func__, ulp_type); mutex_unlock(&cnic_lock); @@ -478,7 +485,7 @@ int cnic_unregister_driver(int ulp_type) return -EINVAL; } mutex_lock(&cnic_lock); - ulp_ops = cnic_ulp_tbl[ulp_type]; + ulp_ops = cnic_ulp_tbl_prot(ulp_type); if (!ulp_ops) { pr_err("%s: Type %d has not been registered\n", __func__, ulp_type); @@ -529,7 +536,7 @@ static int cnic_register_device(struct cnic_dev *dev, int ulp_type, return -EINVAL; } mutex_lock(&cnic_lock); - if (cnic_ulp_tbl[ulp_type] == NULL) { + if (cnic_ulp_tbl_prot(ulp_type) == NULL) { pr_err("%s: Driver with type %d has not been registered\n", __func__, ulp_type); mutex_unlock(&cnic_lock); @@ -544,7 +551,7 @@ static int cnic_register_device(struct cnic_dev *dev, int ulp_type, clear_bit(ULP_F_START, &cp->ulp_flags[ulp_type]); cp->ulp_handle[ulp_type] = ulp_ctx; - ulp_ops = cnic_ulp_tbl[ulp_type]; + ulp_ops = cnic_ulp_tbl_prot(ulp_type); rcu_assign_pointer(cp->ulp_ops[ulp_type], ulp_ops); cnic_hold(dev); @@ -2953,7 +2960,8 @@ static void cnic_ulp_stop(struct cnic_dev *dev) struct cnic_ulp_ops *ulp_ops; mutex_lock(&cnic_lock); - ulp_ops = cp->ulp_ops[if_type]; + ulp_ops = rcu_dereference_protected(cp->ulp_ops[if_type], + lockdep_is_held(&cnic_lock)); if (!ulp_ops) { mutex_unlock(&cnic_lock); continue; @@ -2977,7 +2985,8 @@ static void cnic_ulp_start(struct cnic_dev *dev) struct cnic_ulp_ops *ulp_ops; mutex_lock(&cnic_lock); - ulp_ops = cp->ulp_ops[if_type]; + ulp_ops = rcu_dereference_protected(cp->ulp_ops[if_type], + lockdep_is_held(&cnic_lock)); if (!ulp_ops || !ulp_ops->cnic_start) { mutex_unlock(&cnic_lock); continue; @@ -3041,7 +3050,7 @@ static void cnic_ulp_init(struct cnic_dev *dev) struct cnic_ulp_ops *ulp_ops; mutex_lock(&cnic_lock); - ulp_ops = cnic_ulp_tbl[i]; + ulp_ops = cnic_ulp_tbl_prot(i); if (!ulp_ops || !ulp_ops->cnic_init) { mutex_unlock(&cnic_lock); continue; @@ -3065,7 +3074,7 @@ static void cnic_ulp_exit(struct cnic_dev *dev) struct cnic_ulp_ops *ulp_ops; mutex_lock(&cnic_lock); - ulp_ops = cnic_ulp_tbl[i]; + ulp_ops = cnic_ulp_tbl_prot(i); if (!ulp_ops || !ulp_ops->cnic_exit) { mutex_unlock(&cnic_lock); continue; diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index b328f6c924c3..4456260c653c 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -220,7 +220,7 @@ struct cnic_local { #define ULP_F_INIT 0 #define ULP_F_START 1 #define ULP_F_CALL_PENDING 2 - struct cnic_ulp_ops *ulp_ops[MAX_CNIC_ULP_TYPE]; + struct cnic_ulp_ops __rcu *ulp_ops[MAX_CNIC_ULP_TYPE]; unsigned long cnic_local_flags; #define CNIC_LCL_FL_KWQ_INIT 0x0 diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index ac1d323c5eb5..8931168d3e74 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c @@ -400,13 +400,14 @@ static void *bpq_seq_start(struct seq_file *seq, loff_t *pos) static void *bpq_seq_next(struct seq_file *seq, void *v, loff_t *pos) { struct list_head *p; + struct bpqdev *bpqdev = v; ++*pos; if (v == SEQ_START_TOKEN) - p = rcu_dereference(bpq_devices.next); + p = rcu_dereference(list_next_rcu(&bpq_devices)); else - p = rcu_dereference(((struct bpqdev *)v)->bpq_list.next); + p = rcu_dereference(list_next_rcu(&bpqdev->bpq_list)); return (p == &bpq_devices) ? NULL : list_entry(p, struct bpqdev, bpq_list); diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 5933621ac3ff..2300e4599520 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -39,7 +39,7 @@ struct macvtap_queue { struct socket sock; struct socket_wq wq; int vnet_hdr_sz; - struct macvlan_dev *vlan; + struct macvlan_dev __rcu *vlan; struct file *file; unsigned int flags; }; @@ -141,7 +141,8 @@ static void macvtap_put_queue(struct macvtap_queue *q) struct macvlan_dev *vlan; spin_lock(&macvtap_lock); - vlan = rcu_dereference(q->vlan); + vlan = rcu_dereference_protected(q->vlan, + lockdep_is_held(&macvtap_lock)); if (vlan) { int index = get_slot(vlan, q); @@ -219,7 +220,8 @@ static void macvtap_del_queues(struct net_device *dev) /* macvtap_put_queue can free some slots, so go through all slots */ spin_lock(&macvtap_lock); for (i = 0; i < MAX_MACVTAP_QUEUES && vlan->numvtaps; i++) { - q = rcu_dereference(vlan->taps[i]); + q = rcu_dereference_protected(vlan->taps[i], + lockdep_is_held(&macvtap_lock)); if (q) { qlist[j++] = q; rcu_assign_pointer(vlan->taps[i], NULL); @@ -569,7 +571,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, } rcu_read_lock_bh(); - vlan = rcu_dereference(q->vlan); + vlan = rcu_dereference_bh(q->vlan); if (vlan) macvlan_start_xmit(skb, vlan->dev); else @@ -583,7 +585,7 @@ err_kfree: err: rcu_read_lock_bh(); - vlan = rcu_dereference(q->vlan); + vlan = rcu_dereference_bh(q->vlan); if (vlan) vlan->dev->stats.tx_dropped++; rcu_read_unlock_bh(); @@ -631,7 +633,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, ret = skb_copy_datagram_const_iovec(skb, 0, iv, vnet_hdr_len, len); rcu_read_lock_bh(); - vlan = rcu_dereference(q->vlan); + vlan = rcu_dereference_bh(q->vlan); if (vlan) macvlan_count_rx(vlan, len, ret == 0, 0); rcu_read_unlock_bh(); @@ -727,7 +729,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd, case TUNGETIFF: rcu_read_lock_bh(); - vlan = rcu_dereference(q->vlan); + vlan = rcu_dereference_bh(q->vlan); if (vlan) dev_hold(vlan->dev); rcu_read_unlock_bh(); @@ -736,7 +738,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd, return -ENOLINK; ret = 0; - if (copy_to_user(&ifr->ifr_name, q->vlan->dev->name, IFNAMSIZ) || + if (copy_to_user(&ifr->ifr_name, vlan->dev->name, IFNAMSIZ) || put_user(q->flags, &ifr->ifr_flags)) ret = -EFAULT; dev_put(vlan->dev); -- cgit v1.2.3 From aae7c47311659e5150b740d61c4be418198239fa Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Thu, 27 Jan 2011 09:54:12 +0000 Subject: sungem: Use net_device's internal stats Use net_device_stats instance from the struct net_device. Signed-off-by: Denis Kirjanov Signed-off-by: David S. Miller --- drivers/net/sungem.c | 58 ++++++++++++++++++++++++++-------------------------- drivers/net/sungem.h | 1 - 2 files changed, 29 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 1c5408f83937..c1a344829b54 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -320,28 +320,28 @@ static int gem_txmac_interrupt(struct net_device *dev, struct gem *gp, u32 gem_s if (txmac_stat & MAC_TXSTAT_URUN) { netdev_err(dev, "TX MAC xmit underrun\n"); - gp->net_stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; } if (txmac_stat & MAC_TXSTAT_MPE) { netdev_err(dev, "TX MAC max packet size error\n"); - gp->net_stats.tx_errors++; + dev->stats.tx_errors++; } /* The rest are all cases of one of the 16-bit TX * counters expiring. */ if (txmac_stat & MAC_TXSTAT_NCE) - gp->net_stats.collisions += 0x10000; + dev->stats.collisions += 0x10000; if (txmac_stat & MAC_TXSTAT_ECE) { - gp->net_stats.tx_aborted_errors += 0x10000; - gp->net_stats.collisions += 0x10000; + dev->stats.tx_aborted_errors += 0x10000; + dev->stats.collisions += 0x10000; } if (txmac_stat & MAC_TXSTAT_LCE) { - gp->net_stats.tx_aborted_errors += 0x10000; - gp->net_stats.collisions += 0x10000; + dev->stats.tx_aborted_errors += 0x10000; + dev->stats.collisions += 0x10000; } /* We do not keep track of MAC_TXSTAT_FCE and @@ -469,20 +469,20 @@ static int gem_rxmac_interrupt(struct net_device *dev, struct gem *gp, u32 gem_s u32 smac = readl(gp->regs + MAC_SMACHINE); netdev_err(dev, "RX MAC fifo overflow smac[%08x]\n", smac); - gp->net_stats.rx_over_errors++; - gp->net_stats.rx_fifo_errors++; + dev->stats.rx_over_errors++; + dev->stats.rx_fifo_errors++; ret = gem_rxmac_reset(gp); } if (rxmac_stat & MAC_RXSTAT_ACE) - gp->net_stats.rx_frame_errors += 0x10000; + dev->stats.rx_frame_errors += 0x10000; if (rxmac_stat & MAC_RXSTAT_CCE) - gp->net_stats.rx_crc_errors += 0x10000; + dev->stats.rx_crc_errors += 0x10000; if (rxmac_stat & MAC_RXSTAT_LCE) - gp->net_stats.rx_length_errors += 0x10000; + dev->stats.rx_length_errors += 0x10000; /* We do not track MAC_RXSTAT_FCE and MAC_RXSTAT_VCE * events. @@ -594,7 +594,7 @@ static int gem_abnormal_irq(struct net_device *dev, struct gem *gp, u32 gem_stat if (netif_msg_rx_err(gp)) printk(KERN_DEBUG "%s: no buffer for rx frame\n", gp->dev->name); - gp->net_stats.rx_dropped++; + dev->stats.rx_dropped++; } if (gem_status & GREG_STAT_RXTAGERR) { @@ -602,7 +602,7 @@ static int gem_abnormal_irq(struct net_device *dev, struct gem *gp, u32 gem_stat if (netif_msg_rx_err(gp)) printk(KERN_DEBUG "%s: corrupt rx tag framing\n", gp->dev->name); - gp->net_stats.rx_errors++; + dev->stats.rx_errors++; goto do_reset; } @@ -684,7 +684,7 @@ static __inline__ void gem_tx(struct net_device *dev, struct gem *gp, u32 gem_st break; } gp->tx_skbs[entry] = NULL; - gp->net_stats.tx_bytes += skb->len; + dev->stats.tx_bytes += skb->len; for (frag = 0; frag <= skb_shinfo(skb)->nr_frags; frag++) { txd = &gp->init_block->txd[entry]; @@ -696,7 +696,7 @@ static __inline__ void gem_tx(struct net_device *dev, struct gem *gp, u32 gem_st entry = NEXT_TX(entry); } - gp->net_stats.tx_packets++; + dev->stats.tx_packets++; dev_kfree_skb_irq(skb); } gp->tx_old = entry; @@ -738,6 +738,7 @@ static __inline__ void gem_post_rxds(struct gem *gp, int limit) static int gem_rx(struct gem *gp, int work_to_do) { + struct net_device *dev = gp->dev; int entry, drops, work_done = 0; u32 done; __sum16 csum; @@ -782,15 +783,15 @@ static int gem_rx(struct gem *gp, int work_to_do) len = (status & RXDCTRL_BUFSZ) >> 16; if ((len < ETH_ZLEN) || (status & RXDCTRL_BAD)) { - gp->net_stats.rx_errors++; + dev->stats.rx_errors++; if (len < ETH_ZLEN) - gp->net_stats.rx_length_errors++; + dev->stats.rx_length_errors++; if (len & RXDCTRL_BAD) - gp->net_stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; /* We'll just return it to GEM. */ drop_it: - gp->net_stats.rx_dropped++; + dev->stats.rx_dropped++; goto next; } @@ -843,8 +844,8 @@ static int gem_rx(struct gem *gp, int work_to_do) netif_receive_skb(skb); - gp->net_stats.rx_packets++; - gp->net_stats.rx_bytes += len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += len; next: entry = NEXT_RX(entry); @@ -2472,7 +2473,6 @@ static int gem_resume(struct pci_dev *pdev) static struct net_device_stats *gem_get_stats(struct net_device *dev) { struct gem *gp = netdev_priv(dev); - struct net_device_stats *stats = &gp->net_stats; spin_lock_irq(&gp->lock); spin_lock(&gp->tx_lock); @@ -2481,17 +2481,17 @@ static struct net_device_stats *gem_get_stats(struct net_device *dev) * so we shield against this */ if (gp->running) { - stats->rx_crc_errors += readl(gp->regs + MAC_FCSERR); + dev->stats.rx_crc_errors += readl(gp->regs + MAC_FCSERR); writel(0, gp->regs + MAC_FCSERR); - stats->rx_frame_errors += readl(gp->regs + MAC_AERR); + dev->stats.rx_frame_errors += readl(gp->regs + MAC_AERR); writel(0, gp->regs + MAC_AERR); - stats->rx_length_errors += readl(gp->regs + MAC_LERR); + dev->stats.rx_length_errors += readl(gp->regs + MAC_LERR); writel(0, gp->regs + MAC_LERR); - stats->tx_aborted_errors += readl(gp->regs + MAC_ECOLL); - stats->collisions += + dev->stats.tx_aborted_errors += readl(gp->regs + MAC_ECOLL); + dev->stats.collisions += (readl(gp->regs + MAC_ECOLL) + readl(gp->regs + MAC_LCOLL)); writel(0, gp->regs + MAC_ECOLL); @@ -2501,7 +2501,7 @@ static struct net_device_stats *gem_get_stats(struct net_device *dev) spin_unlock(&gp->tx_lock); spin_unlock_irq(&gp->lock); - return &gp->net_stats; + return &dev->stats; } static int gem_set_mac_address(struct net_device *dev, void *addr) diff --git a/drivers/net/sungem.h b/drivers/net/sungem.h index 19905460def6..ede017872367 100644 --- a/drivers/net/sungem.h +++ b/drivers/net/sungem.h @@ -994,7 +994,6 @@ struct gem { u32 status; struct napi_struct napi; - struct net_device_stats net_stats; int tx_fifo_sz; int rx_fifo_sz; -- cgit v1.2.3 From 92460412367c00e97f99babdb898d0930ce604fc Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 24 Jan 2011 19:23:14 +0100 Subject: ath9k: clean up the code that wakes the mac80211 queues Instead of spreading ath_wake_mac80211_queue() calls over multiple places in the tx path that process the tx queue for completion, call it only where the pending frames counter gets decremented, eliminating some redundant checks. To prevent queue draining from waking the queues prematurely (e.g. during a hardware reset), reset the queue stop state when draining all queues, as the caller in main.c will run ieee80211_wake_queues(hw) anyway. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 2 ++ drivers/net/wireless/ath/ath9k/xmit.c | 39 ++++++++++++++--------------------- 2 files changed, 18 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index bed6eb97fac9..2b27c81b06c8 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -295,6 +295,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, } ps_restore: + ieee80211_wake_queues(hw); + spin_unlock_bh(&sc->sc_pcu_lock); ath9k_ps_restore(sc); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index fe0b6b3ec697..3445389a49ef 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1207,8 +1207,17 @@ bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) ath_err(common, "Failed to stop TX DMA!\n"); for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { - if (ATH_TXQ_SETUP(sc, i)) - ath_draintxq(sc, &sc->tx.txq[i], retry_tx); + if (!ATH_TXQ_SETUP(sc, i)) + continue; + + /* + * The caller will resume queues with ieee80211_wake_queues. + * Mark the queue as not stopped to prevent ath_tx_complete + * from waking the queue too early. + */ + txq = &sc->tx.txq[i]; + txq->stopped = false; + ath_draintxq(sc, txq, retry_tx); } return !npend; @@ -1876,6 +1885,11 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, spin_lock_bh(&txq->axq_lock); if (WARN_ON(--txq->pending_frames < 0)) txq->pending_frames = 0; + + if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) { + if (ath_mac80211_start_queue(sc, q)) + txq->stopped = 0; + } spin_unlock_bh(&txq->axq_lock); } @@ -1985,18 +1999,6 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; } -/* Has no locking. Must hold spin_lock_bh(&txq->axq_lock) - * before calling this. - */ -static void __ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) -{ - if (txq->mac80211_qnum >= 0 && - txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) { - if (ath_mac80211_start_queue(sc, txq->mac80211_qnum)) - txq->stopped = 0; - } -} - static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) { struct ath_hw *ah = sc->sc_ah; @@ -2007,7 +2009,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) struct ath_tx_status ts; int txok; int status; - int qnum; ath_dbg(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), @@ -2089,8 +2090,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) ath_tx_rc_status(bf, &ts, 1, txok ? 0 : 1, txok, true); } - qnum = skb_get_queue_mapping(bf->bf_mpdu); - if (bf_isampdu(bf)) ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok, true); @@ -2098,7 +2097,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0); spin_lock_bh(&txq->axq_lock); - __ath_wake_mac80211_queue(sc, txq); if (sc->sc_flags & SC_OP_TXAGGR) ath_txq_schedule(sc, txq); @@ -2154,7 +2152,6 @@ static void ath_tx_complete_poll_work(struct work_struct *work) txq->pending_frames, list_empty(&txq->axq_acq), txq->stopped); - __ath_wake_mac80211_queue(sc, txq); ath_txq_schedule(sc, txq); } } @@ -2198,7 +2195,6 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) struct list_head bf_head; int status; int txok; - int qnum; for (;;) { status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs); @@ -2244,8 +2240,6 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) ath_tx_rc_status(bf, &txs, 1, txok ? 0 : 1, txok, true); } - qnum = skb_get_queue_mapping(bf->bf_mpdu); - if (bf_isampdu(bf)) ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok, true); @@ -2254,7 +2248,6 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) &txs, txok, 0); spin_lock_bh(&txq->axq_lock); - __ath_wake_mac80211_queue(sc, txq); if (!list_empty(&txq->txq_fifo_pending)) { INIT_LIST_HEAD(&bf_head); -- cgit v1.2.3 From 34302397e5b980ce561366b63504e9d82948e8b8 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 24 Jan 2011 19:23:15 +0100 Subject: ath9k: remove the virtual wiphy debugfs interface It does not make much sense to keep the current virtual wiphy implementation any longer - it adds significant complexity, has very few users and is still very experimental. At some point in time, it will be replaced by a proper implementation in mac80211. By making the code easier to read and maintain, removing virtual wiphy support helps with fixing the remaining driver issues and adding further improvements. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 137 +-------------------------------- 1 file changed, 4 insertions(+), 133 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index f0c80ec290d1..f517c0cd5517 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -381,41 +381,21 @@ static const struct file_operations fops_interrupt = { .llseek = default_llseek, }; -static const char * ath_wiphy_state_str(enum ath_wiphy_state state) -{ - switch (state) { - case ATH_WIPHY_INACTIVE: - return "INACTIVE"; - case ATH_WIPHY_ACTIVE: - return "ACTIVE"; - case ATH_WIPHY_PAUSING: - return "PAUSING"; - case ATH_WIPHY_PAUSED: - return "PAUSED"; - case ATH_WIPHY_SCAN: - return "SCAN"; - } - return "?"; -} - static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath_softc *sc = file->private_data; - struct ath_wiphy *aphy = sc->pri_wiphy; - struct ieee80211_channel *chan = aphy->hw->conf.channel; + struct ieee80211_channel *chan = sc->hw->conf.channel; char buf[512]; unsigned int len = 0; - int i; u8 addr[ETH_ALEN]; u32 tmp; len += snprintf(buf + len, sizeof(buf) - len, - "primary: %s (%s chan=%d ht=%d)\n", - wiphy_name(sc->pri_wiphy->hw->wiphy), - ath_wiphy_state_str(sc->pri_wiphy->state), + "%s (chan=%d ht=%d)\n", + wiphy_name(sc->hw->wiphy), ieee80211_frequency_to_channel(chan->center_freq), - aphy->chan_is_ht); + conf_is_ht(&sc->hw->conf)); put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr); put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4); @@ -457,123 +437,14 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, else len += snprintf(buf + len, sizeof(buf) - len, "\n"); - /* Put variable-length stuff down here, and check for overflows. */ - for (i = 0; i < sc->num_sec_wiphy; i++) { - struct ath_wiphy *aphy_tmp = sc->sec_wiphy[i]; - if (aphy_tmp == NULL) - continue; - chan = aphy_tmp->hw->conf.channel; - len += snprintf(buf + len, sizeof(buf) - len, - "secondary: %s (%s chan=%d ht=%d)\n", - wiphy_name(aphy_tmp->hw->wiphy), - ath_wiphy_state_str(aphy_tmp->state), - ieee80211_frequency_to_channel(chan->center_freq), - aphy_tmp->chan_is_ht); - } if (len > sizeof(buf)) len = sizeof(buf); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } -static struct ath_wiphy * get_wiphy(struct ath_softc *sc, const char *name) -{ - int i; - if (strcmp(name, wiphy_name(sc->pri_wiphy->hw->wiphy)) == 0) - return sc->pri_wiphy; - for (i = 0; i < sc->num_sec_wiphy; i++) { - struct ath_wiphy *aphy = sc->sec_wiphy[i]; - if (aphy && strcmp(name, wiphy_name(aphy->hw->wiphy)) == 0) - return aphy; - } - return NULL; -} - -static int del_wiphy(struct ath_softc *sc, const char *name) -{ - struct ath_wiphy *aphy = get_wiphy(sc, name); - if (!aphy) - return -ENOENT; - return ath9k_wiphy_del(aphy); -} - -static int pause_wiphy(struct ath_softc *sc, const char *name) -{ - struct ath_wiphy *aphy = get_wiphy(sc, name); - if (!aphy) - return -ENOENT; - return ath9k_wiphy_pause(aphy); -} - -static int unpause_wiphy(struct ath_softc *sc, const char *name) -{ - struct ath_wiphy *aphy = get_wiphy(sc, name); - if (!aphy) - return -ENOENT; - return ath9k_wiphy_unpause(aphy); -} - -static int select_wiphy(struct ath_softc *sc, const char *name) -{ - struct ath_wiphy *aphy = get_wiphy(sc, name); - if (!aphy) - return -ENOENT; - return ath9k_wiphy_select(aphy); -} - -static int schedule_wiphy(struct ath_softc *sc, const char *msec) -{ - ath9k_wiphy_set_scheduler(sc, simple_strtoul(msec, NULL, 0)); - return 0; -} - -static ssize_t write_file_wiphy(struct file *file, const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath_softc *sc = file->private_data; - char buf[50]; - size_t len; - - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) - return -EFAULT; - buf[len] = '\0'; - if (len > 0 && buf[len - 1] == '\n') - buf[len - 1] = '\0'; - - if (strncmp(buf, "add", 3) == 0) { - int res = ath9k_wiphy_add(sc); - if (res < 0) - return res; - } else if (strncmp(buf, "del=", 4) == 0) { - int res = del_wiphy(sc, buf + 4); - if (res < 0) - return res; - } else if (strncmp(buf, "pause=", 6) == 0) { - int res = pause_wiphy(sc, buf + 6); - if (res < 0) - return res; - } else if (strncmp(buf, "unpause=", 8) == 0) { - int res = unpause_wiphy(sc, buf + 8); - if (res < 0) - return res; - } else if (strncmp(buf, "select=", 7) == 0) { - int res = select_wiphy(sc, buf + 7); - if (res < 0) - return res; - } else if (strncmp(buf, "schedule=", 9) == 0) { - int res = schedule_wiphy(sc, buf + 9); - if (res < 0) - return res; - } else - return -EOPNOTSUPP; - - return count; -} - static const struct file_operations fops_wiphy = { .read = read_file_wiphy, - .write = write_file_wiphy, .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, -- cgit v1.2.3 From 7545daf498c43e548506212310e6c75382d2731d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 24 Jan 2011 19:23:16 +0100 Subject: ath9k: remove support for virtual wiphys Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/Makefile | 1 - drivers/net/wireless/ath/ath9k/ahb.c | 1 - drivers/net/wireless/ath/ath9k/ath9k.h | 41 -- drivers/net/wireless/ath/ath9k/beacon.c | 9 +- drivers/net/wireless/ath/ath9k/init.c | 19 +- drivers/net/wireless/ath/ath9k/main.c | 141 +------ drivers/net/wireless/ath/ath9k/pci.c | 2 - drivers/net/wireless/ath/ath9k/recv.c | 63 +-- drivers/net/wireless/ath/ath9k/virtual.c | 669 ------------------------------- drivers/net/wireless/ath/ath9k/xmit.c | 28 +- 10 files changed, 23 insertions(+), 951 deletions(-) delete mode 100644 drivers/net/wireless/ath/ath9k/virtual.c (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index aca01621c205..4d66ca8042eb 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile @@ -4,7 +4,6 @@ ath9k-y += beacon.o \ main.o \ recv.o \ xmit.o \ - virtual.o \ ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o ath9k-$(CONFIG_PCI) += pci.o diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 25a6e4417cdb..72f430e956ec 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c @@ -107,7 +107,6 @@ static int ath_ahb_probe(struct platform_device *pdev) sc = (struct ath_softc *) (aphy + 1); aphy->sc = sc; aphy->hw = hw; - sc->pri_wiphy = aphy; sc->hw = hw; sc->dev = &pdev->dev; sc->mem = mem; diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 6636f3c6dcf9..6204f7b46f43 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -388,7 +388,6 @@ struct ath_beacon { u32 ast_be_xmit; u64 bc_tstamp; struct ieee80211_vif *bslot[ATH_BCBUF]; - struct ath_wiphy *bslot_aphy[ATH_BCBUF]; int slottime; int slotupdate; struct ath9k_tx_queue_info beacon_qi; @@ -585,20 +584,8 @@ struct ath_softc { struct ieee80211_hw *hw; struct device *dev; - spinlock_t wiphy_lock; /* spinlock to protect ath_wiphy data */ - struct ath_wiphy *pri_wiphy; - struct ath_wiphy **sec_wiphy; /* secondary wiphys (virtual radios); may - * have NULL entries */ - int num_sec_wiphy; /* number of sec_wiphy pointers in the array */ int chan_idx; int chan_is_ht; - struct ath_wiphy *next_wiphy; - struct work_struct chan_work; - int wiphy_select_failures; - unsigned long wiphy_select_first_fail; - struct delayed_work wiphy_work; - unsigned long wiphy_scheduler_int; - int wiphy_scheduler_index; struct survey_info *cur_survey; struct survey_info survey[ATH9K_NUM_CHANNELS]; @@ -665,16 +652,6 @@ struct ath_wiphy { struct ath_softc *sc; /* shared for all virtual wiphys */ struct ieee80211_hw *hw; struct ath9k_hw_cal_data caldata; - enum ath_wiphy_state { - ATH_WIPHY_INACTIVE, - ATH_WIPHY_ACTIVE, - ATH_WIPHY_PAUSING, - ATH_WIPHY_PAUSED, - ATH_WIPHY_SCAN, - } state; - bool idle; - int chan_idx; - int chan_is_ht; int last_rssi; }; @@ -731,24 +708,6 @@ void ath9k_ps_restore(struct ath_softc *sc); u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate); void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif); -int ath9k_wiphy_add(struct ath_softc *sc); -int ath9k_wiphy_del(struct ath_wiphy *aphy); -void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, int ftype); -int ath9k_wiphy_pause(struct ath_wiphy *aphy); -int ath9k_wiphy_unpause(struct ath_wiphy *aphy); -int ath9k_wiphy_select(struct ath_wiphy *aphy); -void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int); -void ath9k_wiphy_chan_work(struct work_struct *work); -bool ath9k_wiphy_started(struct ath_softc *sc); -void ath9k_wiphy_pause_all_forced(struct ath_softc *sc, - struct ath_wiphy *selected); -bool ath9k_wiphy_scanning(struct ath_softc *sc); -void ath9k_wiphy_work(struct work_struct *work); -bool ath9k_all_wiphys_idle(struct ath_softc *sc); -void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle); - -void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue); -bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); void ath_start_rfkill_poll(struct ath_softc *sc); extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index ab8c05cf62f3..77c8e70db0a0 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -142,9 +142,6 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, struct ieee80211_tx_info *info; int cabq_depth; - if (aphy->state != ATH_WIPHY_ACTIVE) - return NULL; - avp = (void *)vif->drv_priv; cabq = sc->beacon.cabq; @@ -261,7 +258,6 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) } BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL); sc->beacon.bslot[avp->av_bslot] = vif; - sc->beacon.bslot_aphy[avp->av_bslot] = aphy; sc->nbcnvifs++; } } @@ -332,7 +328,6 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp) if (avp->av_bslot != -1) { sc->beacon.bslot[avp->av_bslot] = NULL; - sc->beacon.bslot_aphy[avp->av_bslot] = NULL; sc->nbcnvifs--; } @@ -358,7 +353,6 @@ void ath_beacon_tasklet(unsigned long data) struct ath_common *common = ath9k_hw_common(ah); struct ath_buf *bf = NULL; struct ieee80211_vif *vif; - struct ath_wiphy *aphy; int slot; u32 bfaddr, bc = 0, tsftu; u64 tsf; @@ -416,7 +410,6 @@ void ath_beacon_tasklet(unsigned long data) */ slot = ATH_BCBUF - slot - 1; vif = sc->beacon.bslot[slot]; - aphy = sc->beacon.bslot_aphy[slot]; ath_dbg(common, ATH_DBG_BEACON, "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", @@ -424,7 +417,7 @@ void ath_beacon_tasklet(unsigned long data) bfaddr = 0; if (vif) { - bf = ath_beacon_generate(aphy->hw, vif); + bf = ath_beacon_generate(sc->hw, vif); if (bf != NULL) { bfaddr = bf->bf_daddr; bc = 1; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 5279653c90c7..88ff39940e92 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -517,10 +517,8 @@ static void ath9k_init_misc(struct ath_softc *sc) sc->beacon.slottime = ATH9K_SLOT_TIME_9; - for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { + for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) sc->beacon.bslot[i] = NULL; - sc->beacon.bslot_aphy[i] = NULL; - } if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT; @@ -556,7 +554,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, common->btcoex_enabled = ath9k_btcoex_enable == 1; spin_lock_init(&common->cc_lock); - spin_lock_init(&sc->wiphy_lock); spin_lock_init(&sc->sc_serial_rw); spin_lock_init(&sc->sc_pm_lock); mutex_init(&sc->mutex); @@ -762,9 +759,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, INIT_WORK(&sc->hw_check_work, ath_hw_check); INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); - INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); - INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); - sc->wiphy_scheduler_int = msecs_to_jiffies(500); aphy->last_rssi = ATH_RSSI_DUMMY_MARKER; ath_init_leds(sc); @@ -823,28 +817,17 @@ static void ath9k_deinit_softc(struct ath_softc *sc) void ath9k_deinit_device(struct ath_softc *sc) { struct ieee80211_hw *hw = sc->hw; - int i = 0; ath9k_ps_wakeup(sc); wiphy_rfkill_stop_polling(sc->hw->wiphy); ath_deinit_leds(sc); - for (i = 0; i < sc->num_sec_wiphy; i++) { - struct ath_wiphy *aphy = sc->sec_wiphy[i]; - if (aphy == NULL) - continue; - sc->sec_wiphy[i] = NULL; - ieee80211_unregister_hw(aphy->hw); - ieee80211_free_hw(aphy->hw); - } - ieee80211_unregister_hw(hw); pm_qos_remove_request(&sc->pm_qos_req); ath_rx_cleanup(sc); ath_tx_cleanup(sc); ath9k_deinit_softc(sc); - kfree(sc->sec_wiphy); } void ath_descdma_cleanup(struct ath_softc *sc, diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 2b27c81b06c8..2d9951080864 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1089,29 +1089,7 @@ static int ath9k_start(struct ieee80211_hw *hw) mutex_lock(&sc->mutex); - if (ath9k_wiphy_started(sc)) { - if (sc->chan_idx == curchan->hw_value) { - /* - * Already on the operational channel, the new wiphy - * can be marked active. - */ - aphy->state = ATH_WIPHY_ACTIVE; - ieee80211_wake_queues(hw); - } else { - /* - * Another wiphy is on another channel, start the new - * wiphy in paused state. - */ - aphy->state = ATH_WIPHY_PAUSED; - ieee80211_stop_queues(hw); - } - mutex_unlock(&sc->mutex); - return 0; - } - aphy->state = ATH_WIPHY_ACTIVE; - /* setup initial channel */ - sc->chan_idx = curchan->hw_value; init_channel = ath_get_curchannel(sc, hw); @@ -1221,13 +1199,6 @@ static int ath9k_tx(struct ieee80211_hw *hw, struct ath_tx_control txctl; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { - ath_dbg(common, ATH_DBG_XMIT, - "ath9k: %s: TX in unexpected wiphy state %d\n", - wiphy_name(hw->wiphy), aphy->state); - goto exit; - } - if (sc->ps_enabled) { /* * mac80211 does not set PM field for normal data frames, so we @@ -1290,12 +1261,9 @@ static void ath9k_stop(struct ieee80211_hw *hw) struct ath_softc *sc = aphy->sc; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); - int i; mutex_lock(&sc->mutex); - aphy->state = ATH_WIPHY_INACTIVE; - if (led_blink) cancel_delayed_work_sync(&sc->ath_led_blink_work); @@ -1303,27 +1271,12 @@ static void ath9k_stop(struct ieee80211_hw *hw) cancel_work_sync(&sc->paprd_work); cancel_work_sync(&sc->hw_check_work); - for (i = 0; i < sc->num_sec_wiphy; i++) { - if (sc->sec_wiphy[i]) - break; - } - - if (i == sc->num_sec_wiphy) { - cancel_delayed_work_sync(&sc->wiphy_work); - cancel_work_sync(&sc->chan_work); - } - if (sc->sc_flags & SC_OP_INVALID) { ath_dbg(common, ATH_DBG_ANY, "Device not present\n"); mutex_unlock(&sc->mutex); return; } - if (ath9k_wiphy_started(sc)) { - mutex_unlock(&sc->mutex); - return; /* another wiphy still in use */ - } - /* Ensure HW is awake when we try to shut it down. */ ath9k_ps_wakeup(sc); @@ -1355,7 +1308,6 @@ static void ath9k_stop(struct ieee80211_hw *hw) ath9k_ps_restore(sc); sc->ps_idle = true; - ath9k_set_wiphy_idle(aphy, true); ath_radio_disable(sc, hw); sc->sc_flags |= SC_OP_INVALID; @@ -1445,7 +1397,6 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, struct ath_softc *sc = aphy->sc; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); - int i; /* * Use the hardware MAC address as reference, the hardware uses it @@ -1459,16 +1410,8 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, ath9k_vif_iter(iter_data, vif->addr, vif); /* Get list of all active MAC addresses */ - spin_lock_bh(&sc->wiphy_lock); ieee80211_iterate_active_interfaces_atomic(sc->hw, ath9k_vif_iter, iter_data); - for (i = 0; i < sc->num_sec_wiphy; i++) { - if (sc->sec_wiphy[i] == NULL) - continue; - ieee80211_iterate_active_interfaces_atomic( - sc->sec_wiphy[i]->hw, ath9k_vif_iter, iter_data); - } - spin_unlock_bh(&sc->wiphy_lock); } /* Called with sc->mutex held. */ @@ -1722,7 +1665,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct ieee80211_conf *conf = &hw->conf; - bool disable_radio; + bool disable_radio = false; mutex_lock(&sc->mutex); @@ -1733,29 +1676,13 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) * the end. */ if (changed & IEEE80211_CONF_CHANGE_IDLE) { - bool enable_radio; - bool all_wiphys_idle; - bool idle = !!(conf->flags & IEEE80211_CONF_IDLE); - - spin_lock_bh(&sc->wiphy_lock); - all_wiphys_idle = ath9k_all_wiphys_idle(sc); - ath9k_set_wiphy_idle(aphy, idle); - - enable_radio = (!idle && all_wiphys_idle); - - /* - * After we unlock here its possible another wiphy - * can be re-renabled so to account for that we will - * only disable the radio toward the end of this routine - * if by then all wiphys are still idle. - */ - spin_unlock_bh(&sc->wiphy_lock); - - if (enable_radio) { - sc->ps_idle = false; + sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); + if (!sc->ps_idle) { ath_radio_enable(sc, hw); ath_dbg(common, ATH_DBG_CONFIG, "not-idle: enabling radio\n"); + } else { + disable_radio = true; } } @@ -1796,24 +1723,11 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) if (ah->curchan) old_pos = ah->curchan - &ah->channels[0]; - aphy->chan_idx = pos; - aphy->chan_is_ht = conf_is_ht(conf); if (hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) sc->sc_flags |= SC_OP_OFFCHANNEL; else sc->sc_flags &= ~SC_OP_OFFCHANNEL; - if (aphy->state == ATH_WIPHY_SCAN || - aphy->state == ATH_WIPHY_ACTIVE) - ath9k_wiphy_pause_all_forced(sc, aphy); - else { - /* - * Do not change operational channel based on a paused - * wiphy changes. - */ - goto skip_chan_change; - } - ath_dbg(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", curchan->center_freq); @@ -1860,19 +1774,13 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) ath_update_survey_nf(sc, old_pos); } -skip_chan_change: if (changed & IEEE80211_CONF_CHANGE_POWER) { sc->config.txpowlimit = 2 * conf->power_level; ath_update_txpow(sc); } - spin_lock_bh(&sc->wiphy_lock); - disable_radio = ath9k_all_wiphys_idle(sc); - spin_unlock_bh(&sc->wiphy_lock); - if (disable_radio) { ath_dbg(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); - sc->ps_idle = true; ath_radio_disable(sc, hw); } @@ -2263,43 +2171,6 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx, return 0; } -static void ath9k_sw_scan_start(struct ieee80211_hw *hw) -{ - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; - - mutex_lock(&sc->mutex); - if (ath9k_wiphy_scanning(sc)) { - /* - * There is a race here in mac80211 but fixing it requires - * we revisit how we handle the scan complete callback. - * After mac80211 fixes we will not have configured hardware - * to the home channel nor would we have configured the RX - * filter yet. - */ - mutex_unlock(&sc->mutex); - return; - } - - aphy->state = ATH_WIPHY_SCAN; - ath9k_wiphy_pause_all_forced(sc, aphy); - mutex_unlock(&sc->mutex); -} - -/* - * XXX: this requires a revisit after the driver - * scan_complete gets moved to another place/removed in mac80211. - */ -static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) -{ - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; - - mutex_lock(&sc->mutex); - aphy->state = ATH_WIPHY_ACTIVE; - mutex_unlock(&sc->mutex); -} - static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) { struct ath_wiphy *aphy = hw->priv; @@ -2331,8 +2202,6 @@ struct ieee80211_ops ath9k_ops = { .reset_tsf = ath9k_reset_tsf, .ampdu_action = ath9k_ampdu_action, .get_survey = ath9k_get_survey, - .sw_scan_start = ath9k_sw_scan_start, - .sw_scan_complete = ath9k_sw_scan_complete, .rfkill_poll = ath9k_rfkill_poll_state, .set_coverage_class = ath9k_set_coverage_class, }; diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 78ef1f13386f..1f60b8c47d2f 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -213,7 +213,6 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) sc = (struct ath_softc *) (aphy + 1); aphy->sc = sc; aphy->hw = hw; - sc->pri_wiphy = aphy; sc->hw = hw; sc->dev = &pdev->dev; sc->mem = mem; @@ -320,7 +319,6 @@ static int ath_pci_resume(struct device *device) ath9k_ps_restore(sc); sc->ps_idle = true; - ath9k_set_wiphy_idle(aphy, true); ath_radio_disable(sc, hw); return 0; diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 116f0582af24..c84a675c6912 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -34,27 +34,6 @@ static inline bool ath9k_check_auto_sleep(struct ath_softc *sc) (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP); } -static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc, - struct ieee80211_hdr *hdr) -{ - struct ieee80211_hw *hw = sc->pri_wiphy->hw; - int i; - - spin_lock_bh(&sc->wiphy_lock); - for (i = 0; i < sc->num_sec_wiphy; i++) { - struct ath_wiphy *aphy = sc->sec_wiphy[i]; - if (aphy == NULL) - continue; - if (compare_ether_addr(hdr->addr1, aphy->hw->wiphy->perm_addr) - == 0) { - hw = aphy->hw; - break; - } - } - spin_unlock_bh(&sc->wiphy_lock); - return hw; -} - /* * Setup and link descriptors. * @@ -463,8 +442,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) if (conf_is_ht(&sc->hw->conf)) rfilt |= ATH9K_RX_FILTER_COMP_BAR; - if (sc->sec_wiphy || (sc->nvifs > 1) || - (sc->rx.rxfilter & FIF_OTHER_BSS)) { + if (sc->nvifs > 1 || (sc->rx.rxfilter & FIF_OTHER_BSS)) { /* The following may also be needed for other older chips */ if (sc->sc_ah->hw_version.macVersion == AR_SREV_VERSION_9160) rfilt |= ATH9K_RX_FILTER_PROM; @@ -668,37 +646,6 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb) } } -static void ath_rx_send_to_mac80211(struct ieee80211_hw *hw, - struct ath_softc *sc, struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr; - - hdr = (struct ieee80211_hdr *)skb->data; - - /* Send the frame to mac80211 */ - if (is_multicast_ether_addr(hdr->addr1)) { - int i; - /* - * Deliver broadcast/multicast frames to all suitable - * virtual wiphys. - */ - /* TODO: filter based on channel configuration */ - for (i = 0; i < sc->num_sec_wiphy; i++) { - struct ath_wiphy *aphy = sc->sec_wiphy[i]; - struct sk_buff *nskb; - if (aphy == NULL) - continue; - nskb = skb_copy(skb, GFP_ATOMIC); - if (!nskb) - continue; - ieee80211_rx(aphy->hw, nskb); - } - ieee80211_rx(sc->hw, skb); - } else - /* Deliver unicast frames based on receiver address */ - ieee80211_rx(hw, skb); -} - static bool ath_edma_get_buffers(struct ath_softc *sc, enum ath9k_rx_qtype qtype) { @@ -1644,7 +1591,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) * virtual wiphy so to account for that we iterate over the active * wiphys and find the appropriate wiphy and therefore hw. */ - struct ieee80211_hw *hw = NULL; + struct ieee80211_hw *hw = sc->hw; struct ieee80211_hdr *hdr; int retval; bool decrypt_error = false; @@ -1689,8 +1636,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) hdr = (struct ieee80211_hdr *) (skb->data + rx_status_len); rxs = IEEE80211_SKB_RXCB(skb); - hw = ath_get_virt_hw(sc, hdr); - ath_debug_stat_rx(sc, &rs); /* @@ -1748,7 +1693,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) bf->bf_mpdu = NULL; bf->bf_buf_addr = 0; ath_err(common, "dma_mapping_error() on RX\n"); - ath_rx_send_to_mac80211(hw, sc, skb); + ieee80211_rx(hw, skb); break; } @@ -1775,7 +1720,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) ath_ant_comb_scan(sc, &rs); - ath_rx_send_to_mac80211(hw, sc, skb); + ieee80211_rx(hw, skb); requeue: if (edma) { diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c deleted file mode 100644 index d205c66cd972..000000000000 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ /dev/null @@ -1,669 +0,0 @@ -/* - * Copyright (c) 2008-2009 Atheros Communications Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include - -#include "ath9k.h" - -int ath9k_wiphy_add(struct ath_softc *sc) -{ - int i, error; - struct ath_wiphy *aphy; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); - struct ieee80211_hw *hw; - u8 addr[ETH_ALEN]; - - hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy), &ath9k_ops); - if (hw == NULL) - return -ENOMEM; - - spin_lock_bh(&sc->wiphy_lock); - for (i = 0; i < sc->num_sec_wiphy; i++) { - if (sc->sec_wiphy[i] == NULL) - break; - } - - if (i == sc->num_sec_wiphy) { - /* No empty slot available; increase array length */ - struct ath_wiphy **n; - n = krealloc(sc->sec_wiphy, - (sc->num_sec_wiphy + 1) * - sizeof(struct ath_wiphy *), - GFP_ATOMIC); - if (n == NULL) { - spin_unlock_bh(&sc->wiphy_lock); - ieee80211_free_hw(hw); - return -ENOMEM; - } - n[i] = NULL; - sc->sec_wiphy = n; - sc->num_sec_wiphy++; - } - - SET_IEEE80211_DEV(hw, sc->dev); - - aphy = hw->priv; - aphy->sc = sc; - aphy->hw = hw; - sc->sec_wiphy[i] = aphy; - aphy->last_rssi = ATH_RSSI_DUMMY_MARKER; - spin_unlock_bh(&sc->wiphy_lock); - - memcpy(addr, common->macaddr, ETH_ALEN); - addr[0] |= 0x02; /* Locally managed address */ - /* - * XOR virtual wiphy index into the least significant bits to generate - * a different MAC address for each virtual wiphy. - */ - addr[5] ^= i & 0xff; - addr[4] ^= (i & 0xff00) >> 8; - addr[3] ^= (i & 0xff0000) >> 16; - - SET_IEEE80211_PERM_ADDR(hw, addr); - - ath9k_set_hw_capab(sc, hw); - - error = ieee80211_register_hw(hw); - - if (error == 0) { - /* Make sure wiphy scheduler is started (if enabled) */ - ath9k_wiphy_set_scheduler(sc, sc->wiphy_scheduler_int); - } - - return error; -} - -int ath9k_wiphy_del(struct ath_wiphy *aphy) -{ - struct ath_softc *sc = aphy->sc; - int i; - - spin_lock_bh(&sc->wiphy_lock); - for (i = 0; i < sc->num_sec_wiphy; i++) { - if (aphy == sc->sec_wiphy[i]) { - sc->sec_wiphy[i] = NULL; - spin_unlock_bh(&sc->wiphy_lock); - ieee80211_unregister_hw(aphy->hw); - ieee80211_free_hw(aphy->hw); - return 0; - } - } - spin_unlock_bh(&sc->wiphy_lock); - return -ENOENT; -} - -static int ath9k_send_nullfunc(struct ath_wiphy *aphy, - struct ieee80211_vif *vif, const u8 *bssid, - int ps) -{ - struct ath_softc *sc = aphy->sc; - struct ath_tx_control txctl; - struct sk_buff *skb; - struct ieee80211_hdr *hdr; - __le16 fc; - struct ieee80211_tx_info *info; - - skb = dev_alloc_skb(24); - if (skb == NULL) - return -ENOMEM; - hdr = (struct ieee80211_hdr *) skb_put(skb, 24); - memset(hdr, 0, 24); - fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC | - IEEE80211_FCTL_TODS); - if (ps) - fc |= cpu_to_le16(IEEE80211_FCTL_PM); - hdr->frame_control = fc; - memcpy(hdr->addr1, bssid, ETH_ALEN); - memcpy(hdr->addr2, aphy->hw->wiphy->perm_addr, ETH_ALEN); - memcpy(hdr->addr3, bssid, ETH_ALEN); - - info = IEEE80211_SKB_CB(skb); - memset(info, 0, sizeof(*info)); - info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS; - info->control.vif = vif; - info->control.rates[0].idx = 0; - info->control.rates[0].count = 4; - info->control.rates[1].idx = -1; - - memset(&txctl, 0, sizeof(struct ath_tx_control)); - txctl.txq = sc->tx.txq_map[WME_AC_VO]; - txctl.frame_type = ps ? ATH9K_IFT_PAUSE : ATH9K_IFT_UNPAUSE; - - if (ath_tx_start(aphy->hw, skb, &txctl) != 0) - goto exit; - - return 0; -exit: - dev_kfree_skb_any(skb); - return -1; -} - -static bool __ath9k_wiphy_pausing(struct ath_softc *sc) -{ - int i; - if (sc->pri_wiphy->state == ATH_WIPHY_PAUSING) - return true; - for (i = 0; i < sc->num_sec_wiphy; i++) { - if (sc->sec_wiphy[i] && - sc->sec_wiphy[i]->state == ATH_WIPHY_PAUSING) - return true; - } - return false; -} - -static bool ath9k_wiphy_pausing(struct ath_softc *sc) -{ - bool ret; - spin_lock_bh(&sc->wiphy_lock); - ret = __ath9k_wiphy_pausing(sc); - spin_unlock_bh(&sc->wiphy_lock); - return ret; -} - -static bool __ath9k_wiphy_scanning(struct ath_softc *sc) -{ - int i; - if (sc->pri_wiphy->state == ATH_WIPHY_SCAN) - return true; - for (i = 0; i < sc->num_sec_wiphy; i++) { - if (sc->sec_wiphy[i] && - sc->sec_wiphy[i]->state == ATH_WIPHY_SCAN) - return true; - } - return false; -} - -bool ath9k_wiphy_scanning(struct ath_softc *sc) -{ - bool ret; - spin_lock_bh(&sc->wiphy_lock); - ret = __ath9k_wiphy_scanning(sc); - spin_unlock_bh(&sc->wiphy_lock); - return ret; -} - -static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy); - -/* caller must hold wiphy_lock */ -static void __ath9k_wiphy_unpause_ch(struct ath_wiphy *aphy) -{ - if (aphy == NULL) - return; - if (aphy->chan_idx != aphy->sc->chan_idx) - return; /* wiphy not on the selected channel */ - __ath9k_wiphy_unpause(aphy); -} - -static void ath9k_wiphy_unpause_channel(struct ath_softc *sc) -{ - int i; - spin_lock_bh(&sc->wiphy_lock); - __ath9k_wiphy_unpause_ch(sc->pri_wiphy); - for (i = 0; i < sc->num_sec_wiphy; i++) - __ath9k_wiphy_unpause_ch(sc->sec_wiphy[i]); - spin_unlock_bh(&sc->wiphy_lock); -} - -void ath9k_wiphy_chan_work(struct work_struct *work) -{ - struct ath_softc *sc = container_of(work, struct ath_softc, chan_work); - struct ath_common *common = ath9k_hw_common(sc->sc_ah); - struct ath_wiphy *aphy = sc->next_wiphy; - - if (aphy == NULL) - return; - - /* - * All pending interfaces paused; ready to change - * channels. - */ - - /* Change channels */ - mutex_lock(&sc->mutex); - /* XXX: remove me eventually */ - ath9k_update_ichannel(sc, aphy->hw, - &sc->sc_ah->channels[sc->chan_idx]); - - /* sync hw configuration for hw code */ - common->hw = aphy->hw; - - if (ath_set_channel(sc, aphy->hw, - &sc->sc_ah->channels[sc->chan_idx]) < 0) { - printk(KERN_DEBUG "ath9k: Failed to set channel for new " - "virtual wiphy\n"); - mutex_unlock(&sc->mutex); - return; - } - mutex_unlock(&sc->mutex); - - ath9k_wiphy_unpause_channel(sc); -} - -/* - * ath9k version of ieee80211_tx_status() for TX frames that are generated - * internally in the driver. - */ -void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, int ftype) -{ - struct ath_wiphy *aphy = hw->priv; - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); - - if (ftype == ATH9K_IFT_PAUSE && aphy->state == ATH_WIPHY_PAUSING) { - if (!(tx_info->flags & IEEE80211_TX_STAT_ACK)) { - printk(KERN_DEBUG "ath9k: %s: no ACK for pause " - "frame\n", wiphy_name(hw->wiphy)); - /* - * The AP did not reply; ignore this to allow us to - * continue. - */ - } - aphy->state = ATH_WIPHY_PAUSED; - if (!ath9k_wiphy_pausing(aphy->sc)) { - /* - * Drop from tasklet to work to allow mutex for channel - * change. - */ - ieee80211_queue_work(aphy->sc->hw, - &aphy->sc->chan_work); - } - } - - dev_kfree_skb(skb); -} - -static void ath9k_mark_paused(struct ath_wiphy *aphy) -{ - struct ath_softc *sc = aphy->sc; - aphy->state = ATH_WIPHY_PAUSED; - if (!__ath9k_wiphy_pausing(sc)) - ieee80211_queue_work(sc->hw, &sc->chan_work); -} - -static void ath9k_pause_iter(void *data, u8 *mac, struct ieee80211_vif *vif) -{ - struct ath_wiphy *aphy = data; - struct ath_vif *avp = (void *) vif->drv_priv; - - switch (vif->type) { - case NL80211_IFTYPE_STATION: - if (!vif->bss_conf.assoc) { - ath9k_mark_paused(aphy); - break; - } - /* TODO: could avoid this if already in PS mode */ - if (ath9k_send_nullfunc(aphy, vif, avp->bssid, 1)) { - printk(KERN_DEBUG "%s: failed to send PS nullfunc\n", - __func__); - ath9k_mark_paused(aphy); - } - break; - case NL80211_IFTYPE_AP: - /* Beacon transmission is paused by aphy->state change */ - ath9k_mark_paused(aphy); - break; - default: - break; - } -} - -/* caller must hold wiphy_lock */ -static int __ath9k_wiphy_pause(struct ath_wiphy *aphy) -{ - ieee80211_stop_queues(aphy->hw); - aphy->state = ATH_WIPHY_PAUSING; - /* - * TODO: handle PAUSING->PAUSED for the case where there are multiple - * active vifs (now we do it on the first vif getting ready; should be - * on the last) - */ - ieee80211_iterate_active_interfaces_atomic(aphy->hw, ath9k_pause_iter, - aphy); - return 0; -} - -int ath9k_wiphy_pause(struct ath_wiphy *aphy) -{ - int ret; - spin_lock_bh(&aphy->sc->wiphy_lock); - ret = __ath9k_wiphy_pause(aphy); - spin_unlock_bh(&aphy->sc->wiphy_lock); - return ret; -} - -static void ath9k_unpause_iter(void *data, u8 *mac, struct ieee80211_vif *vif) -{ - struct ath_wiphy *aphy = data; - struct ath_vif *avp = (void *) vif->drv_priv; - - switch (vif->type) { - case NL80211_IFTYPE_STATION: - if (!vif->bss_conf.assoc) - break; - ath9k_send_nullfunc(aphy, vif, avp->bssid, 0); - break; - case NL80211_IFTYPE_AP: - /* Beacon transmission is re-enabled by aphy->state change */ - break; - default: - break; - } -} - -/* caller must hold wiphy_lock */ -static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy) -{ - ieee80211_iterate_active_interfaces_atomic(aphy->hw, - ath9k_unpause_iter, aphy); - aphy->state = ATH_WIPHY_ACTIVE; - ieee80211_wake_queues(aphy->hw); - return 0; -} - -int ath9k_wiphy_unpause(struct ath_wiphy *aphy) -{ - int ret; - spin_lock_bh(&aphy->sc->wiphy_lock); - ret = __ath9k_wiphy_unpause(aphy); - spin_unlock_bh(&aphy->sc->wiphy_lock); - return ret; -} - -static void __ath9k_wiphy_mark_all_paused(struct ath_softc *sc) -{ - int i; - if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) - sc->pri_wiphy->state = ATH_WIPHY_PAUSED; - for (i = 0; i < sc->num_sec_wiphy; i++) { - if (sc->sec_wiphy[i] && - sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE) - sc->sec_wiphy[i]->state = ATH_WIPHY_PAUSED; - } -} - -/* caller must hold wiphy_lock */ -static void __ath9k_wiphy_pause_all(struct ath_softc *sc) -{ - int i; - if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) - __ath9k_wiphy_pause(sc->pri_wiphy); - for (i = 0; i < sc->num_sec_wiphy; i++) { - if (sc->sec_wiphy[i] && - sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE) - __ath9k_wiphy_pause(sc->sec_wiphy[i]); - } -} - -int ath9k_wiphy_select(struct ath_wiphy *aphy) -{ - struct ath_softc *sc = aphy->sc; - bool now; - - spin_lock_bh(&sc->wiphy_lock); - if (__ath9k_wiphy_scanning(sc)) { - /* - * For now, we are using mac80211 sw scan and it expects to - * have full control over channel changes, so avoid wiphy - * scheduling during a scan. This could be optimized if the - * scanning control were moved into the driver. - */ - spin_unlock_bh(&sc->wiphy_lock); - return -EBUSY; - } - if (__ath9k_wiphy_pausing(sc)) { - if (sc->wiphy_select_failures == 0) - sc->wiphy_select_first_fail = jiffies; - sc->wiphy_select_failures++; - if (time_after(jiffies, sc->wiphy_select_first_fail + HZ / 2)) - { - printk(KERN_DEBUG "ath9k: Previous wiphy select timed " - "out; disable/enable hw to recover\n"); - __ath9k_wiphy_mark_all_paused(sc); - /* - * TODO: this workaround to fix hardware is unlikely to - * be specific to virtual wiphy changes. It can happen - * on normal channel change, too, and as such, this - * should really be made more generic. For example, - * tricker radio disable/enable on GTT interrupt burst - * (say, 10 GTT interrupts received without any TX - * frame being completed) - */ - spin_unlock_bh(&sc->wiphy_lock); - ath_radio_disable(sc, aphy->hw); - ath_radio_enable(sc, aphy->hw); - /* Only the primary wiphy hw is used for queuing work */ - ieee80211_queue_work(aphy->sc->hw, - &aphy->sc->chan_work); - return -EBUSY; /* previous select still in progress */ - } - spin_unlock_bh(&sc->wiphy_lock); - return -EBUSY; /* previous select still in progress */ - } - sc->wiphy_select_failures = 0; - - /* Store the new channel */ - sc->chan_idx = aphy->chan_idx; - sc->chan_is_ht = aphy->chan_is_ht; - sc->next_wiphy = aphy; - - __ath9k_wiphy_pause_all(sc); - now = !__ath9k_wiphy_pausing(aphy->sc); - spin_unlock_bh(&sc->wiphy_lock); - - if (now) { - /* Ready to request channel change immediately */ - ieee80211_queue_work(aphy->sc->hw, &aphy->sc->chan_work); - } - - /* - * wiphys will be unpaused in ath9k_tx_status() once channel has been - * changed if any wiphy needs time to become paused. - */ - - return 0; -} - -bool ath9k_wiphy_started(struct ath_softc *sc) -{ - int i; - spin_lock_bh(&sc->wiphy_lock); - if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) { - spin_unlock_bh(&sc->wiphy_lock); - return true; - } - for (i = 0; i < sc->num_sec_wiphy; i++) { - if (sc->sec_wiphy[i] && - sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE) { - spin_unlock_bh(&sc->wiphy_lock); - return true; - } - } - spin_unlock_bh(&sc->wiphy_lock); - return false; -} - -static void ath9k_wiphy_pause_chan(struct ath_wiphy *aphy, - struct ath_wiphy *selected) -{ - if (selected->state == ATH_WIPHY_SCAN) { - if (aphy == selected) - return; - /* - * Pause all other wiphys for the duration of the scan even if - * they are on the current channel now. - */ - } else if (aphy->chan_idx == selected->chan_idx) - return; - aphy->state = ATH_WIPHY_PAUSED; - ieee80211_stop_queues(aphy->hw); -} - -void ath9k_wiphy_pause_all_forced(struct ath_softc *sc, - struct ath_wiphy *selected) -{ - int i; - spin_lock_bh(&sc->wiphy_lock); - if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) - ath9k_wiphy_pause_chan(sc->pri_wiphy, selected); - for (i = 0; i < sc->num_sec_wiphy; i++) { - if (sc->sec_wiphy[i] && - sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE) - ath9k_wiphy_pause_chan(sc->sec_wiphy[i], selected); - } - spin_unlock_bh(&sc->wiphy_lock); -} - -void ath9k_wiphy_work(struct work_struct *work) -{ - struct ath_softc *sc = container_of(work, struct ath_softc, - wiphy_work.work); - struct ath_wiphy *aphy = NULL; - bool first = true; - - spin_lock_bh(&sc->wiphy_lock); - - if (sc->wiphy_scheduler_int == 0) { - /* wiphy scheduler is disabled */ - spin_unlock_bh(&sc->wiphy_lock); - return; - } - -try_again: - sc->wiphy_scheduler_index++; - while (sc->wiphy_scheduler_index <= sc->num_sec_wiphy) { - aphy = sc->sec_wiphy[sc->wiphy_scheduler_index - 1]; - if (aphy && aphy->state != ATH_WIPHY_INACTIVE) - break; - - sc->wiphy_scheduler_index++; - aphy = NULL; - } - if (aphy == NULL) { - sc->wiphy_scheduler_index = 0; - if (sc->pri_wiphy->state == ATH_WIPHY_INACTIVE) { - if (first) { - first = false; - goto try_again; - } - /* No wiphy is ready to be scheduled */ - } else - aphy = sc->pri_wiphy; - } - - spin_unlock_bh(&sc->wiphy_lock); - - if (aphy && - aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN && - ath9k_wiphy_select(aphy)) { - printk(KERN_DEBUG "ath9k: Failed to schedule virtual wiphy " - "change\n"); - } - - ieee80211_queue_delayed_work(sc->hw, - &sc->wiphy_work, - sc->wiphy_scheduler_int); -} - -void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int) -{ - cancel_delayed_work_sync(&sc->wiphy_work); - sc->wiphy_scheduler_int = msecs_to_jiffies(msec_int); - if (sc->wiphy_scheduler_int) - ieee80211_queue_delayed_work(sc->hw, &sc->wiphy_work, - sc->wiphy_scheduler_int); -} - -/* caller must hold wiphy_lock */ -bool ath9k_all_wiphys_idle(struct ath_softc *sc) -{ - unsigned int i; - if (!sc->pri_wiphy->idle) - return false; - for (i = 0; i < sc->num_sec_wiphy; i++) { - struct ath_wiphy *aphy = sc->sec_wiphy[i]; - if (!aphy) - continue; - if (!aphy->idle) - return false; - } - return true; -} - -/* caller must hold wiphy_lock */ -void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle) -{ - struct ath_softc *sc = aphy->sc; - - aphy->idle = idle; - ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, - "Marking %s as %sidle\n", - wiphy_name(aphy->hw->wiphy), idle ? "" : "not-"); -} -/* Only bother starting a queue on an active virtual wiphy */ -bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue) -{ - struct ieee80211_hw *hw = sc->pri_wiphy->hw; - unsigned int i; - bool txq_started = false; - - spin_lock_bh(&sc->wiphy_lock); - - /* Start the primary wiphy */ - if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) { - ieee80211_wake_queue(hw, skb_queue); - txq_started = true; - goto unlock; - } - - /* Now start the secondary wiphy queues */ - for (i = 0; i < sc->num_sec_wiphy; i++) { - struct ath_wiphy *aphy = sc->sec_wiphy[i]; - if (!aphy) - continue; - if (aphy->state != ATH_WIPHY_ACTIVE) - continue; - - hw = aphy->hw; - ieee80211_wake_queue(hw, skb_queue); - txq_started = true; - break; - } - -unlock: - spin_unlock_bh(&sc->wiphy_lock); - return txq_started; -} - -/* Go ahead and propagate information to all virtual wiphys, it won't hurt */ -void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue) -{ - struct ieee80211_hw *hw = sc->pri_wiphy->hw; - unsigned int i; - - spin_lock_bh(&sc->wiphy_lock); - - /* Stop the primary wiphy */ - ieee80211_stop_queue(hw, skb_queue); - - /* Now stop the secondary wiphy queues */ - for (i = 0; i < sc->num_sec_wiphy; i++) { - struct ath_wiphy *aphy = sc->sec_wiphy[i]; - if (!aphy) - continue; - hw = aphy->hw; - ieee80211_stop_queue(hw, skb_queue); - } - spin_unlock_bh(&sc->wiphy_lock); -} diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 3445389a49ef..07fdfa314759 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1819,7 +1819,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, spin_lock_bh(&txq->axq_lock); if (txq == sc->tx.txq_map[q] && ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { - ath_mac80211_stop_queue(sc, q); + ieee80211_stop_queue(sc->hw, q); txq->stopped = 1; } spin_unlock_bh(&txq->axq_lock); @@ -1877,24 +1877,20 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, PS_WAIT_FOR_TX_ACK)); } - if (unlikely(ftype)) - ath9k_tx_status(hw, skb, ftype); - else { - q = skb_get_queue_mapping(skb); - if (txq == sc->tx.txq_map[q]) { - spin_lock_bh(&txq->axq_lock); - if (WARN_ON(--txq->pending_frames < 0)) - txq->pending_frames = 0; + q = skb_get_queue_mapping(skb); + if (txq == sc->tx.txq_map[q]) { + spin_lock_bh(&txq->axq_lock); + if (WARN_ON(--txq->pending_frames < 0)) + txq->pending_frames = 0; - if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) { - if (ath_mac80211_start_queue(sc, q)) - txq->stopped = 0; - } - spin_unlock_bh(&txq->axq_lock); + if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) { + ieee80211_wake_queue(sc->hw, q); + txq->stopped = 0; } - - ieee80211_tx_status(hw, skb); + spin_unlock_bh(&txq->axq_lock); } + + ieee80211_tx_status(hw, skb); } static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, -- cgit v1.2.3 From 0cdd5c60e4538d02414144e0682941a4eb20ffa8 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 24 Jan 2011 19:23:17 +0100 Subject: ath9k: remove the bf->aphy field Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 3 +-- drivers/net/wireless/ath/ath9k/xmit.c | 38 ++++++++++++++-------------------- 2 files changed, 17 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 6204f7b46f43..01306a3c4475 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -32,6 +32,7 @@ */ struct ath_node; +struct ath_wiphy; /* Macro to expand scalars to 64-bit objects */ @@ -233,7 +234,6 @@ struct ath_buf { bool bf_stale; u16 bf_flags; struct ath_buf_state bf_state; - struct ath_wiphy *aphy; }; struct ath_atx_tid { @@ -563,7 +563,6 @@ struct ath_ant_comb { #define PS_WAIT_FOR_TX_ACK BIT(3) #define PS_BEACON_SYNC BIT(4) -struct ath_wiphy; struct ath_rate_table; struct ath9k_vif_iter_data { diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 07fdfa314759..d7e3f8c0602e 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -55,8 +55,9 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, struct list_head *head); static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len); -static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, - int nframes, int nbad, int txok, bool update_rc); +static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, + struct ath_tx_status *ts, int nframes, int nbad, + int txok, bool update_rc); static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, int seqno); @@ -295,7 +296,6 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) ATH_TXBUF_RESET(tbf); - tbf->aphy = bf->aphy; tbf->bf_mpdu = bf->bf_mpdu; tbf->bf_buf_addr = bf->bf_buf_addr; memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len); @@ -343,7 +343,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, struct ath_node *an = NULL; struct sk_buff *skb; struct ieee80211_sta *sta; - struct ieee80211_hw *hw; + struct ieee80211_hw *hw = sc->hw; struct ieee80211_hdr *hdr; struct ieee80211_tx_info *tx_info; struct ath_atx_tid *tid = NULL; @@ -362,7 +362,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, hdr = (struct ieee80211_hdr *)skb->data; tx_info = IEEE80211_SKB_CB(skb); - hw = bf->aphy->hw; memcpy(rates, tx_info->control.rates, sizeof(rates)); @@ -381,7 +380,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, !bf->bf_stale || bf_next != NULL) list_move_tail(&bf->list, &bf_head); - ath_tx_rc_status(bf, ts, 1, 1, 0, false); + ath_tx_rc_status(sc, bf, ts, 1, 1, 0, false); ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, 0, 0); @@ -487,10 +486,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { memcpy(tx_info->control.rates, rates, sizeof(rates)); - ath_tx_rc_status(bf, ts, nframes, nbad, txok, true); + ath_tx_rc_status(sc, bf, ts, nframes, nbad, txok, true); rc_update = false; } else { - ath_tx_rc_status(bf, ts, nframes, nbad, txok, false); + ath_tx_rc_status(sc, bf, ts, nframes, nbad, txok, false); } ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, @@ -514,7 +513,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, bf->bf_state.bf_type |= BUF_XRETRY; - ath_tx_rc_status(bf, ts, nframes, + ath_tx_rc_status(sc, bf, ts, nframes, nbad, 0, false); ath_tx_complete_buf(sc, bf, txq, &bf_head, @@ -1680,7 +1679,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, ATH_TXBUF_RESET(bf); - bf->aphy = aphy; bf->bf_flags = setup_tx_flags(skb); bf->bf_mpdu = skb; @@ -1834,8 +1832,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, /*****************/ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, - struct ath_wiphy *aphy, int tx_flags, int ftype, - struct ath_txq *txq) + int tx_flags, int ftype, struct ath_txq *txq) { struct ieee80211_hw *hw = sc->hw; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); @@ -1845,9 +1842,6 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, ath_dbg(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); - if (aphy) - hw = aphy->hw; - if (tx_flags & ATH_TX_BAR) tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; @@ -1921,7 +1915,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, complete(&sc->paprd_complete); } else { ath_debug_stat_tx(sc, bf, ts); - ath_tx_complete(sc, skb, bf->aphy, tx_flags, + ath_tx_complete(sc, skb, tx_flags, bf->bf_state.bfs_ftype, txq); } /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't @@ -1937,14 +1931,14 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, spin_unlock_irqrestore(&sc->tx.txbuflock, flags); } -static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, - int nframes, int nbad, int txok, bool update_rc) +static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, + struct ath_tx_status *ts, int nframes, int nbad, + int txok, bool update_rc) { struct sk_buff *skb = bf->bf_mpdu; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); - struct ieee80211_hw *hw = bf->aphy->hw; - struct ath_softc *sc = bf->aphy->sc; + struct ieee80211_hw *hw = sc->hw; struct ath_hw *ah = sc->sc_ah; u8 i, tx_rateindex; @@ -2083,7 +2077,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) */ if (ts.ts_status & ATH9K_TXERR_XRETRY) bf->bf_state.bf_type |= BUF_XRETRY; - ath_tx_rc_status(bf, &ts, 1, txok ? 0 : 1, txok, true); + ath_tx_rc_status(sc, bf, &ts, 1, txok ? 0 : 1, txok, true); } if (bf_isampdu(bf)) @@ -2233,7 +2227,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) if (!bf_isampdu(bf)) { if (txs.ts_status & ATH9K_TXERR_XRETRY) bf->bf_state.bf_type |= BUF_XRETRY; - ath_tx_rc_status(bf, &txs, 1, txok ? 0 : 1, txok, true); + ath_tx_rc_status(sc, bf, &txs, 1, txok ? 0 : 1, txok, true); } if (bf_isampdu(bf)) -- cgit v1.2.3 From 9ac58615d93c8a28b1c649a90a5e2ede4dfd368a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 24 Jan 2011 19:23:18 +0100 Subject: ath9k: fold struct ath_wiphy into struct ath_softc Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ahb.c | 12 ++--- drivers/net/wireless/ath/ath9k/ath9k.h | 13 ++---- drivers/net/wireless/ath/ath9k/beacon.c | 9 ++-- drivers/net/wireless/ath/ath9k/gpio.c | 3 +- drivers/net/wireless/ath/ath9k/init.c | 6 +-- drivers/net/wireless/ath/ath9k/main.c | 78 ++++++++++++--------------------- drivers/net/wireless/ath/ath9k/pci.c | 18 +++----- drivers/net/wireless/ath/ath9k/rc.c | 3 +- drivers/net/wireless/ath/ath9k/recv.c | 6 +-- drivers/net/wireless/ath/ath9k/xmit.c | 9 ++-- 10 files changed, 52 insertions(+), 105 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 72f430e956ec..993672105963 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c @@ -54,7 +54,6 @@ static struct ath_bus_ops ath_ahb_bus_ops = { static int ath_ahb_probe(struct platform_device *pdev) { void __iomem *mem; - struct ath_wiphy *aphy; struct ath_softc *sc; struct ieee80211_hw *hw; struct resource *res; @@ -92,8 +91,7 @@ static int ath_ahb_probe(struct platform_device *pdev) irq = res->start; - hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) + - sizeof(struct ath_softc), &ath9k_ops); + hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops); if (hw == NULL) { dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); ret = -ENOMEM; @@ -103,10 +101,7 @@ static int ath_ahb_probe(struct platform_device *pdev) SET_IEEE80211_DEV(hw, &pdev->dev); platform_set_drvdata(pdev, hw); - aphy = hw->priv; - sc = (struct ath_softc *) (aphy + 1); - aphy->sc = sc; - aphy->hw = hw; + sc = hw->priv; sc->hw = hw; sc->dev = &pdev->dev; sc->mem = mem; @@ -150,8 +145,7 @@ static int ath_ahb_remove(struct platform_device *pdev) struct ieee80211_hw *hw = platform_get_drvdata(pdev); if (hw) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; void __iomem *mem = sc->mem; ath9k_deinit_device(sc); diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 01306a3c4475..75d54a53865f 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -32,7 +32,6 @@ */ struct ath_node; -struct ath_wiphy; /* Macro to expand scalars to 64-bit objects */ @@ -398,7 +397,7 @@ struct ath_beacon { void ath_beacon_tasklet(unsigned long data); void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif); -int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif); +int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif); void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp); int ath_beaconq_config(struct ath_softc *sc); @@ -628,6 +627,9 @@ struct ath_softc { int led_on_cnt; int led_off_cnt; + struct ath9k_hw_cal_data caldata; + int last_rssi; + int beacon_interval; #ifdef CONFIG_ATH9K_DEBUGFS @@ -647,13 +649,6 @@ struct ath_softc { struct pm_qos_request_list pm_qos_req; }; -struct ath_wiphy { - struct ath_softc *sc; /* shared for all virtual wiphys */ - struct ieee80211_hw *hw; - struct ath9k_hw_cal_data caldata; - int last_rssi; -}; - void ath9k_tasklet(unsigned long data); int ath_reset(struct ath_softc *sc, bool retry_tx); int ath_cabq_update(struct ath_softc *); diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 77c8e70db0a0..87ba44c06692 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -112,8 +112,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_tx_control txctl; @@ -132,8 +131,7 @@ static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_buf *bf; struct ath_vif *avp; @@ -222,9 +220,8 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, return bf; } -int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) +int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif) { - struct ath_softc *sc = aphy->sc; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_vif *avp; struct ath_buf *bf; diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 133764069246..fb4f17a5183d 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -201,8 +201,7 @@ static bool ath_is_rfkill_set(struct ath_softc *sc) void ath9k_rfkill_poll_state(struct ieee80211_hw *hw) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; bool blocked = !!ath_is_rfkill_set(sc); wiphy_rfkill_set_hw_state(hw->wiphy, blocked); diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 88ff39940e92..c1e159219065 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -254,8 +254,7 @@ static int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) { struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah); return ath_reg_notifier_apply(wiphy, request, reg); @@ -704,7 +703,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, const struct ath_bus_ops *bus_ops) { struct ieee80211_hw *hw = sc->hw; - struct ath_wiphy *aphy = hw->priv; struct ath_common *common; struct ath_hw *ah; int error = 0; @@ -759,7 +757,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, INIT_WORK(&sc->hw_check_work, ath_hw_check); INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); - aphy->last_rssi = ATH_RSSI_DUMMY_MARKER; + sc->last_rssi = ATH_RSSI_DUMMY_MARKER; ath_init_leds(sc); ath_start_rfkill_poll(sc); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 2d9951080864..422be2675a06 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -215,7 +215,6 @@ static void ath_update_survey_stats(struct ath_softc *sc) int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, struct ath9k_channel *hchan) { - struct ath_wiphy *aphy = hw->priv; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct ieee80211_conf *conf = &common->hw->conf; @@ -262,7 +261,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, fastcc = false; if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) - caldata = &aphy->caldata; + caldata = &sc->caldata; ath_dbg(common, ATH_DBG_CONFIG, "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n", @@ -854,7 +853,6 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf) { - struct ath_wiphy *aphy = hw->priv; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); @@ -878,7 +876,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, ath_beacon_config(sc, vif); /* Reset rssi stats */ - aphy->last_rssi = ATH_RSSI_DUMMY_MARKER; + sc->last_rssi = ATH_RSSI_DUMMY_MARKER; sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; sc->sc_flags |= SC_OP_ANI_RUN; @@ -1075,8 +1073,7 @@ void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, static int ath9k_start(struct ieee80211_hw *hw) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct ieee80211_channel *curchan = hw->conf.channel; @@ -1193,8 +1190,7 @@ mutex_unlock: static int ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_tx_control txctl; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; @@ -1257,8 +1253,7 @@ exit: static void ath9k_stop(struct ieee80211_hw *hw) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); @@ -1393,8 +1388,7 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ath9k_vif_iter_data *iter_data) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); @@ -1418,8 +1412,7 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct ath9k_vif_iter_data iter_data; @@ -1475,8 +1468,7 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; ath9k_calculate_summary_state(hw, vif); @@ -1489,7 +1481,7 @@ static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw, * in the info_changed method and set up beacons properly * there. */ - error = ath_beacon_alloc(aphy, vif); + error = ath_beacon_alloc(sc, vif); if (error) ath9k_reclaim_beacon(sc, vif); else @@ -1501,8 +1493,7 @@ static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw, static int ath9k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct ath_vif *avp = (void *)vif->drv_priv; @@ -1562,8 +1553,7 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, enum nl80211_iftype new_type, bool p2p) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ath_common *common = ath9k_hw_common(sc->sc_ah); int ret = 0; @@ -1605,8 +1595,7 @@ out: static void ath9k_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ath_common *common = ath9k_hw_common(sc->sc_ah); ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n"); @@ -1660,8 +1649,7 @@ static void ath9k_disable_ps(struct ath_softc *sc) static int ath9k_config(struct ieee80211_hw *hw, u32 changed) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct ieee80211_conf *conf = &hw->conf; @@ -1805,8 +1793,7 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, unsigned int *total_flags, u64 multicast) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; u32 rfilt; changed_flags &= SUPPORTED_FILTERS; @@ -1826,8 +1813,7 @@ static int ath9k_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; ath_node_attach(sc, sta); @@ -1838,8 +1824,7 @@ static int ath9k_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; ath_node_detach(sc, sta); @@ -1849,8 +1834,7 @@ static int ath9k_sta_remove(struct ieee80211_hw *hw, static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_txq *txq; struct ath9k_tx_queue_info qi; @@ -1894,8 +1878,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, struct ieee80211_sta *sta, struct ieee80211_key_conf *key) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ath_common *common = ath9k_hw_common(sc->sc_ah); int ret = 0; @@ -1939,8 +1922,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_bss_conf *bss_conf, u32 changed) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct ath_vif *avp = (void *)vif->drv_priv; @@ -1970,7 +1952,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, if ((changed & BSS_CHANGED_BEACON) || ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) { ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); - error = ath_beacon_alloc(aphy, vif); + error = ath_beacon_alloc(sc, vif); if (!error) ath_beacon_config(sc, vif); } @@ -2007,7 +1989,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, if (vif->type == NL80211_IFTYPE_AP) { sc->sc_flags |= SC_OP_TSF_RESET; ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); - error = ath_beacon_alloc(aphy, vif); + error = ath_beacon_alloc(sc, vif); if (!error) ath_beacon_config(sc, vif); } else { @@ -2045,9 +2027,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, static u64 ath9k_get_tsf(struct ieee80211_hw *hw) { + struct ath_softc *sc = hw->priv; u64 tsf; - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; mutex_lock(&sc->mutex); ath9k_ps_wakeup(sc); @@ -2060,8 +2041,7 @@ static u64 ath9k_get_tsf(struct ieee80211_hw *hw) static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; mutex_lock(&sc->mutex); ath9k_ps_wakeup(sc); @@ -2072,8 +2052,7 @@ static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf) static void ath9k_reset_tsf(struct ieee80211_hw *hw) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; mutex_lock(&sc->mutex); @@ -2090,8 +2069,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; int ret = 0; local_bh_disable(); @@ -2136,8 +2114,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, static int ath9k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ieee80211_supported_band *sband; struct ieee80211_channel *chan; @@ -2173,8 +2150,7 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx, static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; mutex_lock(&sc->mutex); diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 1f60b8c47d2f..e83128c50f7b 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -126,7 +126,6 @@ static const struct ath_bus_ops ath_pci_bus_ops = { static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { void __iomem *mem; - struct ath_wiphy *aphy; struct ath_softc *sc; struct ieee80211_hw *hw; u8 csz; @@ -198,8 +197,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_iomap; } - hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) + - sizeof(struct ath_softc), &ath9k_ops); + hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops); if (!hw) { dev_err(&pdev->dev, "No memory for ieee80211_hw\n"); ret = -ENOMEM; @@ -209,10 +207,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) SET_IEEE80211_DEV(hw, &pdev->dev); pci_set_drvdata(pdev, hw); - aphy = hw->priv; - sc = (struct ath_softc *) (aphy + 1); - aphy->sc = sc; - aphy->hw = hw; + sc = hw->priv; sc->hw = hw; sc->dev = &pdev->dev; sc->mem = mem; @@ -259,8 +254,7 @@ err_dma: static void ath_pci_remove(struct pci_dev *pdev) { struct ieee80211_hw *hw = pci_get_drvdata(pdev); - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; void __iomem *mem = sc->mem; if (!is_ath9k_unloaded) @@ -280,8 +274,7 @@ static int ath_pci_suspend(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); struct ieee80211_hw *hw = pci_get_drvdata(pdev); - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); @@ -292,8 +285,7 @@ static int ath_pci_resume(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); struct ieee80211_hw *hw = pci_get_drvdata(pdev); - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; u32 val; /* diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index e45147820eae..960d717ca7c2 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1560,8 +1560,7 @@ static void ath_rate_add_sta_debugfs(void *priv, void *priv_sta, static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) { - struct ath_wiphy *aphy = hw->priv; - return aphy->sc; + return hw->priv; } static void ath_rate_free(void *priv) diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index c84a675c6912..b2b12a293c70 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -927,7 +927,7 @@ static void ath9k_process_rssi(struct ath_common *common, struct ieee80211_hdr *hdr, struct ath_rx_status *rx_stats) { - struct ath_wiphy *aphy = hw->priv; + struct ath_softc *sc = hw->priv; struct ath_hw *ah = common->ah; int last_rssi; __le16 fc; @@ -947,9 +947,9 @@ static void ath9k_process_rssi(struct ath_common *common, } if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && !rx_stats->rs_moreaggr) - ATH_RSSI_LPF(aphy->last_rssi, rx_stats->rs_rssi); + ATH_RSSI_LPF(sc->last_rssi, rx_stats->rs_rssi); - last_rssi = aphy->last_rssi; + last_rssi = sc->last_rssi; if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) rx_stats->rs_rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index d7e3f8c0602e..dd919488077d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1443,8 +1443,7 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, int framelen) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_sta *sta = tx_info->control.sta; struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; @@ -1662,8 +1661,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_txq *txq, struct sk_buff *skb) { - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_frame_info *fi = get_frame_info(skb); @@ -1764,8 +1762,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_sta *sta = info->control.sta; - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; + struct ath_softc *sc = hw->priv; struct ath_txq *txq = txctl->txq; struct ath_buf *bf; int padpos, padsize; -- cgit v1.2.3 From 5bec3e5ade813ee4bdbab03af1bb6f85859272ea Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 24 Jan 2011 21:29:25 +0100 Subject: ath9k: fix tx queue index confusion in debugfs code Various places printing tx queue information used various different ways to get a tx queue index for printing statistics. Most of these ways were wrong. ATH_TXQ_AC_* cannot be used as an index for sc->tx.txq, because it is only used internally for queue assignment. One place used WME_AC_* as a queue index for sc->debug.stats.txstats, however this array uses the ath9k_hw queue number as well. Fix all of this by always using the ath9k_hw queue number as an index, and always looking it up by going through sc->tx.txq_map. Signed-off-by: Felix Fietkau Cc: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 37 +++++++++++++++++----------------- drivers/net/wireless/ath/ath9k/debug.h | 2 +- drivers/net/wireless/ath/ath9k/xmit.c | 2 +- 3 files changed, 21 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index f517c0cd5517..9cdc41b0ec44 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -450,14 +450,15 @@ static const struct file_operations fops_wiphy = { .llseek = default_llseek, }; +#define PR_QNUM(_n) sc->tx.txq_map[_n]->axq_qnum #define PR(str, elem) \ do { \ len += snprintf(buf + len, size - len, \ "%s%13u%11u%10u%10u\n", str, \ - sc->debug.stats.txstats[WME_AC_BE].elem, \ - sc->debug.stats.txstats[WME_AC_BK].elem, \ - sc->debug.stats.txstats[WME_AC_VI].elem, \ - sc->debug.stats.txstats[WME_AC_VO].elem); \ + sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].elem, \ + sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].elem, \ + sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].elem, \ + sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].elem); \ if (len >= size) \ goto done; \ } while(0) @@ -466,10 +467,10 @@ static const struct file_operations fops_wiphy = { do { \ len += snprintf(buf + len, size - len, \ "%s%13u%11u%10u%10u\n", str, \ - (unsigned int)(sc->tx.txq[ATH_TXQ_AC_BE].elem), \ - (unsigned int)(sc->tx.txq[ATH_TXQ_AC_BK].elem), \ - (unsigned int)(sc->tx.txq[ATH_TXQ_AC_VI].elem), \ - (unsigned int)(sc->tx.txq[ATH_TXQ_AC_VO].elem)); \ + (unsigned int)(sc->tx.txq_map[WME_AC_BE]->elem), \ + (unsigned int)(sc->tx.txq_map[WME_AC_BK]->elem), \ + (unsigned int)(sc->tx.txq_map[WME_AC_VI]->elem), \ + (unsigned int)(sc->tx.txq_map[WME_AC_VO]->elem)); \ if (len >= size) \ goto done; \ } while(0) @@ -478,10 +479,10 @@ do { \ do { \ len += snprintf(buf + len, size - len, \ "%s%13i%11i%10i%10i\n", str, \ - list_empty(&sc->tx.txq[ATH_TXQ_AC_BE].elem), \ - list_empty(&sc->tx.txq[ATH_TXQ_AC_BK].elem), \ - list_empty(&sc->tx.txq[ATH_TXQ_AC_VI].elem), \ - list_empty(&sc->tx.txq[ATH_TXQ_AC_VO].elem)); \ + list_empty(&sc->tx.txq_map[WME_AC_BE]->elem), \ + list_empty(&sc->tx.txq_map[WME_AC_BK]->elem), \ + list_empty(&sc->tx.txq_map[WME_AC_VI]->elem), \ + list_empty(&sc->tx.txq_map[WME_AC_VO]->elem)); \ if (len >= size) \ goto done; \ } while (0) @@ -528,10 +529,10 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, PR("hw-tx-proc-desc: ", txprocdesc); len += snprintf(buf + len, size - len, "%s%11p%11p%10p%10p\n", "txq-memory-address:", - &(sc->tx.txq[ATH_TXQ_AC_BE]), - &(sc->tx.txq[ATH_TXQ_AC_BK]), - &(sc->tx.txq[ATH_TXQ_AC_VI]), - &(sc->tx.txq[ATH_TXQ_AC_VO])); + &(sc->tx.txq_map[WME_AC_BE]), + &(sc->tx.txq_map[WME_AC_BK]), + &(sc->tx.txq_map[WME_AC_VI]), + &(sc->tx.txq_map[WME_AC_VO])); if (len >= size) goto done; @@ -751,9 +752,9 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, } void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, - struct ath_tx_status *ts) + struct ath_tx_status *ts, struct ath_txq *txq) { - int qnum = skb_get_queue_mapping(bf->bf_mpdu); + int qnum = txq->axq_qnum; TX_STAT_INC(qnum, tx_pkts_all); sc->debug.stats.txstats[qnum].tx_bytes_all += bf->bf_mpdu->len; diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 980c9fa194b9..1bdc6d4ceb17 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -175,7 +175,7 @@ int ath9k_init_debug(struct ath_hw *ah); void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, - struct ath_tx_status *ts); + struct ath_tx_status *ts, struct ath_txq *txq); void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs); #else diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index dd919488077d..879365e9b1c9 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1911,7 +1911,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, else complete(&sc->paprd_complete); } else { - ath_debug_stat_tx(sc, bf, ts); + ath_debug_stat_tx(sc, bf, ts, txq); ath_tx_complete(sc, skb, tx_flags, bf->bf_state.bfs_ftype, txq); } -- cgit v1.2.3 From 20a904904dc69d4b4de26c146af33eb00f05ab92 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 25 Jan 2011 13:15:28 +0900 Subject: ath5k: Use local variable for capabilities Shorten some lines and make code more readable. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/caps.c | 39 ++++++++++++++++------------------- 1 file changed, 18 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c index 31cad80e9b01..39baee17d0da 100644 --- a/drivers/net/wireless/ath/ath5k/caps.c +++ b/drivers/net/wireless/ath/ath5k/caps.c @@ -32,23 +32,24 @@ */ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) { + struct ath5k_capabilities *caps = &ah->ah_capabilities; u16 ee_header; /* Capabilities stored in the EEPROM */ - ee_header = ah->ah_capabilities.cap_eeprom.ee_header; + ee_header = caps->cap_eeprom.ee_header; if (ah->ah_version == AR5K_AR5210) { /* * Set radio capabilities * (The AR5110 only supports the middle 5GHz band) */ - ah->ah_capabilities.cap_range.range_5ghz_min = 5120; - ah->ah_capabilities.cap_range.range_5ghz_max = 5430; - ah->ah_capabilities.cap_range.range_2ghz_min = 0; - ah->ah_capabilities.cap_range.range_2ghz_max = 0; + caps->cap_range.range_5ghz_min = 5120; + caps->cap_range.range_5ghz_max = 5430; + caps->cap_range.range_2ghz_min = 0; + caps->cap_range.range_2ghz_max = 0; /* Set supported modes */ - __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode); + __set_bit(AR5K_MODE_11A, caps->cap_mode); } else { /* * XXX The tranceiver supports frequencies from 4920 to 6100GHz @@ -67,12 +68,11 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) if (AR5K_EEPROM_HDR_11A(ee_header)) { /* 4920 */ - ah->ah_capabilities.cap_range.range_5ghz_min = 5005; - ah->ah_capabilities.cap_range.range_5ghz_max = 6100; + caps->cap_range.range_5ghz_min = 5005; + caps->cap_range.range_5ghz_max = 6100; /* Set supported modes */ - __set_bit(AR5K_MODE_11A, - ah->ah_capabilities.cap_mode); + __set_bit(AR5K_MODE_11A, caps->cap_mode); } /* Enable 802.11b if a 2GHz capable radio (2111/5112) is @@ -81,32 +81,29 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) (AR5K_EEPROM_HDR_11G(ee_header) && ah->ah_version != AR5K_AR5211)) { /* 2312 */ - ah->ah_capabilities.cap_range.range_2ghz_min = 2412; - ah->ah_capabilities.cap_range.range_2ghz_max = 2732; + caps->cap_range.range_2ghz_min = 2412; + caps->cap_range.range_2ghz_max = 2732; if (AR5K_EEPROM_HDR_11B(ee_header)) - __set_bit(AR5K_MODE_11B, - ah->ah_capabilities.cap_mode); + __set_bit(AR5K_MODE_11B, caps->cap_mode); if (AR5K_EEPROM_HDR_11G(ee_header) && ah->ah_version != AR5K_AR5211) - __set_bit(AR5K_MODE_11G, - ah->ah_capabilities.cap_mode); + __set_bit(AR5K_MODE_11G, caps->cap_mode); } } /* Set number of supported TX queues */ if (ah->ah_version == AR5K_AR5210) - ah->ah_capabilities.cap_queues.q_tx_num = - AR5K_NUM_TX_QUEUES_NOQCU; + caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES_NOQCU; else - ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES; + caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES; /* newer hardware has PHY error counters */ if (ah->ah_mac_srev >= AR5K_SREV_AR5213A) - ah->ah_capabilities.cap_has_phyerr_counters = true; + caps->cap_has_phyerr_counters = true; else - ah->ah_capabilities.cap_has_phyerr_counters = false; + caps->cap_has_phyerr_counters = false; return 0; } -- cgit v1.2.3 From 5719efdde1d0ae8670b96eb8748d1a0dc6a37be2 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 25 Jan 2011 13:15:33 +0900 Subject: ath: Add function to check if 4.9GHz channels are allowed This adds a helper function to ath/regd.c which can be asked if 4.9GHz channels are allowed for a given regulatory domain code. This keeps the knowledge of regdomains and defines like MKK9_MKKC in one place. I'm passing the regdomain code instead of the ath_regulatory structure because this needs to be called quite early in the driver inititalization where ath_regulatory is not available yet in ath5k. I'm using MKK9_MKKC only because this is the regdomain in the 802.11j enabled sample cards we got from our vendor. I found some hints in HAL code that this is used by Atheros to indicate 4.9GHz channels support and that there might be other domain codes as well, but as I don't have any documentation I'm just putting in what I need right now. It can be extended later. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/regd.c | 7 +++++++ drivers/net/wireless/ath/regd.h | 1 + 2 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 2b14775e6bc6..f828f294ba89 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -158,6 +158,13 @@ ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg) } } +bool ath_is_49ghz_allowed(u16 regdomain) +{ + /* possibly more */ + return regdomain == MKK9_MKKC; +} +EXPORT_SYMBOL(ath_is_49ghz_allowed); + /* Frequency is one where radar detection is required */ static bool ath_is_radar_freq(u16 center_freq) { diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h index 345dd9721b41..172f63f671cf 100644 --- a/drivers/net/wireless/ath/regd.h +++ b/drivers/net/wireless/ath/regd.h @@ -250,6 +250,7 @@ enum CountryCode { }; bool ath_is_world_regd(struct ath_regulatory *reg); +bool ath_is_49ghz_allowed(u16 redomain); int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy, int (*reg_notifier)(struct wiphy *wiphy, struct regulatory_request *request)); -- cgit v1.2.3 From ead3dcff31111c3dc1205a383190614f045d94aa Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 25 Jan 2011 13:15:38 +0900 Subject: ath5k: Enable 802.11j 4.9GHz frequencies This enables 4.9GHz frequencies in ath5k if they are allowed as indicated by the regulatory domain code. Currently this is MKK9_MKKC (0xfe). Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/caps.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c index 39baee17d0da..f77e8a703c5c 100644 --- a/drivers/net/wireless/ath/ath5k/caps.c +++ b/drivers/net/wireless/ath/ath5k/caps.c @@ -57,9 +57,8 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) * XXX current ieee80211 implementation because the IEEE * XXX channel mapping does not support negative channel * XXX numbers (2312MHz is channel -19). Of course, this - * XXX doesn't matter because these channels are out of range - * XXX but some regulation domains like MKK (Japan) will - * XXX support frequencies somewhere around 4.8GHz. + * XXX doesn't matter because these channels are out of the + * XXX legal range. */ /* @@ -67,8 +66,10 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) */ if (AR5K_EEPROM_HDR_11A(ee_header)) { - /* 4920 */ - caps->cap_range.range_5ghz_min = 5005; + if (ath_is_49ghz_allowed(caps->cap_eeprom.ee_regdomain)) + caps->cap_range.range_5ghz_min = 4920; + else + caps->cap_range.range_5ghz_min = 5005; caps->cap_range.range_5ghz_max = 6100; /* Set supported modes */ -- cgit v1.2.3 From b453175d932c8ff42146992a1dac243104783902 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 25 Jan 2011 13:15:43 +0900 Subject: ath9k: Remove unused IEEE80211_WEP_NKID IEEE80211_WEP_NKID is not used in ath9k any more since the key handling code has been moved to ath/. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 - drivers/net/wireless/ath/ath9k/common.h | 2 -- 2 files changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 75d54a53865f..dd9a7d740c98 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -534,7 +534,6 @@ struct ath_ant_comb { #define ATH_CABQ_READY_TIME 80 /* % of beacon interval */ #define ATH_MAX_SW_RETRIES 10 #define ATH_CHAN_MAX 255 -#define IEEE80211_WEP_NKID 4 /* number of key ids */ #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ #define ATH_RATE_DUMMY_MARKER 0 diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index a126bddebb0a..4c7020b3a5a0 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h @@ -23,8 +23,6 @@ /* Common header for Atheros 802.11n base driver cores */ -#define IEEE80211_WEP_NKID 4 - #define WME_NUM_TID 16 #define WME_BA_BMP_SIZE 64 #define WME_MAX_BA WME_BA_BMP_SIZE -- cgit v1.2.3 From 0e4722524d5134dedd514d34991f02f2c1de23b4 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Mon, 24 Jan 2011 23:32:55 -0500 Subject: ath5k: use tracing for packet tx/rx dump This adds a few tracepoints to ath5k driver transmit and receive callbacks in order to record packet traffic. We record the entire packet in the trace buffer so that the data can be extracted with trace-cmd and external plugins. Compared to the previous debugging calls, this approach removes an out-of-line function call from the tx and rx paths in the compiled-in-but-disabled case, while improving the ability to process the logged data. A new option, CONFIG_ATH5K_TRACER, is added so that one may disable the tracepoints completely. Signed-off-by: Bob Copeland Acked-by: Bruno Randolf Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/Kconfig | 11 ++++ drivers/net/wireless/ath/ath5k/base.c | 16 +++-- drivers/net/wireless/ath/ath5k/trace.h | 107 +++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+), 6 deletions(-) create mode 100644 drivers/net/wireless/ath/ath5k/trace.h (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig index e0793319389d..e18a9aa7b6ca 100644 --- a/drivers/net/wireless/ath/ath5k/Kconfig +++ b/drivers/net/wireless/ath/ath5k/Kconfig @@ -40,6 +40,17 @@ config ATH5K_DEBUG modprobe ath5k debug=0x00000400 +config ATH5K_TRACER + bool "Atheros 5xxx tracer" + depends on ATH5K + depends on EVENT_TRACING + ---help--- + Say Y here to enable tracepoints for the ath5k driver + using the kernel tracing infrastructure. Select this + option if you are interested in debugging the driver. + + If unsure, say N. + config ATH5K_AHB bool "Atheros 5xxx AHB bus support" depends on (ATHEROS_AR231X && !PCI) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 8611f24cdf6a..c0927d7b7c6b 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -61,6 +61,9 @@ #include "debug.h" #include "ani.h" +#define CREATE_TRACE_POINTS +#include "trace.h" + int ath5k_modparam_nohwcrypt; module_param_named(nohwcrypt, ath5k_modparam_nohwcrypt, bool, S_IRUGO); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); @@ -1379,7 +1382,7 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb, sc->sbands[sc->curchan->band].bitrates[rxs->rate_idx].hw_value_short) rxs->flag |= RX_FLAG_SHORTPRE; - ath5k_debug_dump_skb(sc, skb, "RX ", 0); + trace_ath5k_rx(sc, skb); ath5k_update_beacon_rssi(sc, skb, rs->rs_rssi); @@ -1524,7 +1527,7 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, unsigned long flags; int padsize; - ath5k_debug_dump_skb(sc, skb, "TX ", 1); + trace_ath5k_tx(sc, skb, txq); /* * The hardware expects the header padded to 4 byte boundaries. @@ -1573,7 +1576,7 @@ drop_packet: static void ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, - struct ath5k_tx_status *ts) + struct ath5k_txq *txq, struct ath5k_tx_status *ts) { struct ieee80211_tx_info *info; int i; @@ -1625,6 +1628,7 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, else sc->stats.antenna_tx[0]++; /* invalid */ + trace_ath5k_tx_complete(sc, skb, txq, ts); ieee80211_tx_status(sc->hw, skb); } @@ -1661,7 +1665,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) dma_unmap_single(sc->dev, bf->skbaddr, skb->len, DMA_TO_DEVICE); - ath5k_tx_frame_completed(sc, skb, &ts); + ath5k_tx_frame_completed(sc, skb, txq, &ts); } /* @@ -1803,8 +1807,6 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) goto out; } - ath5k_debug_dump_skb(sc, skb, "BC ", 1); - ath5k_txbuf_free_skb(sc, avf->bbuf); avf->bbuf->skb = skb; ret = ath5k_beacon_setup(sc, avf->bbuf); @@ -1899,6 +1901,8 @@ ath5k_beacon_send(struct ath5k_softc *sc) sc->opmode == NL80211_IFTYPE_MESH_POINT) ath5k_beacon_update(sc->hw, vif); + trace_ath5k_tx(sc, bf->skb, &sc->txqs[sc->bhalq]); + ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); ath5k_hw_start_tx_dma(ah, sc->bhalq); ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", diff --git a/drivers/net/wireless/ath/ath5k/trace.h b/drivers/net/wireless/ath/ath5k/trace.h new file mode 100644 index 000000000000..2de68adb6240 --- /dev/null +++ b/drivers/net/wireless/ath/ath5k/trace.h @@ -0,0 +1,107 @@ +#if !defined(__TRACE_ATH5K_H) || defined(TRACE_HEADER_MULTI_READ) +#define __TRACE_ATH5K_H + +#include +#include "base.h" + +#ifndef CONFIG_ATH5K_TRACER +#undef TRACE_EVENT +#define TRACE_EVENT(name, proto, ...) \ +static inline void trace_ ## name(proto) {} +#endif + +struct sk_buff; + +#define PRIV_ENTRY __field(struct ath5k_softc *, priv) +#define PRIV_ASSIGN __entry->priv = priv + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM ath5k + +TRACE_EVENT(ath5k_rx, + TP_PROTO(struct ath5k_softc *priv, struct sk_buff *skb), + TP_ARGS(priv, skb), + TP_STRUCT__entry( + PRIV_ENTRY + __field(unsigned long, skbaddr) + __dynamic_array(u8, frame, skb->len) + ), + TP_fast_assign( + PRIV_ASSIGN; + __entry->skbaddr = (unsigned long) skb; + memcpy(__get_dynamic_array(frame), skb->data, skb->len); + ), + TP_printk( + "[%p] RX skb=%lx", __entry->priv, __entry->skbaddr + ) +); + +TRACE_EVENT(ath5k_tx, + TP_PROTO(struct ath5k_softc *priv, struct sk_buff *skb, + struct ath5k_txq *q), + + TP_ARGS(priv, skb, q), + + TP_STRUCT__entry( + PRIV_ENTRY + __field(unsigned long, skbaddr) + __field(u8, qnum) + __dynamic_array(u8, frame, skb->len) + ), + + TP_fast_assign( + PRIV_ASSIGN; + __entry->skbaddr = (unsigned long) skb; + __entry->qnum = (u8) q->qnum; + memcpy(__get_dynamic_array(frame), skb->data, skb->len); + ), + + TP_printk( + "[%p] TX skb=%lx q=%d", __entry->priv, __entry->skbaddr, + __entry->qnum + ) +); + +TRACE_EVENT(ath5k_tx_complete, + TP_PROTO(struct ath5k_softc *priv, struct sk_buff *skb, + struct ath5k_txq *q, struct ath5k_tx_status *ts), + + TP_ARGS(priv, skb, q, ts), + + TP_STRUCT__entry( + PRIV_ENTRY + __field(unsigned long, skbaddr) + __field(u8, qnum) + __field(u8, ts_status) + __field(s8, ts_rssi) + __field(u8, ts_antenna) + ), + + TP_fast_assign( + PRIV_ASSIGN; + __entry->skbaddr = (unsigned long) skb; + __entry->qnum = (u8) q->qnum; + __entry->ts_status = ts->ts_status; + __entry->ts_rssi = ts->ts_rssi; + __entry->ts_antenna = ts->ts_antenna; + ), + + TP_printk( + "[%p] TX end skb=%lx q=%d stat=%x rssi=%d ant=%x", + __entry->priv, __entry->skbaddr, __entry->qnum, + __entry->ts_status, __entry->ts_rssi, __entry->ts_antenna + ) +); + +#endif /* __TRACE_ATH5K_H */ + +#ifdef CONFIG_ATH5K_TRACER + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH ../../drivers/net/wireless/ath/ath5k +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE trace + +#include + +#endif -- cgit v1.2.3 From 53e3b6e29eeda568fbe6c1e32d35cb56eea94415 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Mon, 24 Jan 2011 23:32:56 -0500 Subject: ath5k: remove debug_dump_skb() functions Now that rx and tx dumps go through the tracing infrastructure, we no longer need to keep these routines around. Signed-off-by: Bob Copeland Acked-by: Bruno Randolf Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/debug.c | 20 -------------------- drivers/net/wireless/ath/ath5k/debug.h | 10 ---------- 2 files changed, 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index d2f84d76bb07..0230f30e9e9a 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -308,8 +308,6 @@ static const struct { { ATH5K_DEBUG_CALIBRATE, "calib", "periodic calibration" }, { ATH5K_DEBUG_TXPOWER, "txpower", "transmit power setting" }, { ATH5K_DEBUG_LED, "led", "LED management" }, - { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" }, - { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, { ATH5K_DEBUG_DMA, "dma", "dma start/stop" }, { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" }, @@ -1035,24 +1033,6 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) spin_unlock_bh(&sc->rxbuflock); } -void -ath5k_debug_dump_skb(struct ath5k_softc *sc, - struct sk_buff *skb, const char *prefix, int tx) -{ - char buf[16]; - - if (likely(!((tx && (sc->debug.level & ATH5K_DEBUG_DUMP_TX)) || - (!tx && (sc->debug.level & ATH5K_DEBUG_DUMP_RX))))) - return; - - snprintf(buf, sizeof(buf), "%s %s", wiphy_name(sc->hw->wiphy), prefix); - - print_hex_dump_bytes(buf, DUMP_PREFIX_NONE, skb->data, - min(200U, skb->len)); - - printk(KERN_DEBUG "\n"); -} - void ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) { diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h index 3e34428d5126..b0355aef68d3 100644 --- a/drivers/net/wireless/ath/ath5k/debug.h +++ b/drivers/net/wireless/ath/ath5k/debug.h @@ -116,8 +116,6 @@ enum ath5k_debug_level { ATH5K_DEBUG_CALIBRATE = 0x00000020, ATH5K_DEBUG_TXPOWER = 0x00000040, ATH5K_DEBUG_LED = 0x00000080, - ATH5K_DEBUG_DUMP_RX = 0x00000100, - ATH5K_DEBUG_DUMP_TX = 0x00000200, ATH5K_DEBUG_DUMPBANDS = 0x00000400, ATH5K_DEBUG_DMA = 0x00000800, ATH5K_DEBUG_ANI = 0x00002000, @@ -151,10 +149,6 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah); void ath5k_debug_dump_bands(struct ath5k_softc *sc); -void -ath5k_debug_dump_skb(struct ath5k_softc *sc, - struct sk_buff *skb, const char *prefix, int tx); - void ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf); @@ -181,10 +175,6 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {} static inline void ath5k_debug_dump_bands(struct ath5k_softc *sc) {} -static inline void -ath5k_debug_dump_skb(struct ath5k_softc *sc, - struct sk_buff *skb, const char *prefix, int tx) {} - static inline void ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) {} -- cgit v1.2.3 From 00e0003e0969517c5a447ac3173442dfbdb0613b Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 26 Jan 2011 21:59:05 +0530 Subject: ath9k_hw: Fix opmode initialization Commit "ath9k_hw: Relocate Opmode initialization" moved the opmode initialization before the STA_ID1 register was programmed with defaults. This changed the original behaviour because the re-programming code doesn't take into account the existing value in the register. Both ath9k and ath9k_htc were not affected by this change because the opmode is re-initialized after every reset, when RX is started. Revert to the original behavior, except keep it outside the REGWRITE block. This would help remove extraneous opmode calls in the driver core. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index bc92b4579b27..48d121c24eb7 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1346,8 +1346,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ath9k_hw_spur_mitigate_freq(ah, chan); ah->eep_ops->set_board_values(ah, chan); - ath9k_hw_set_operating_mode(ah, ah->opmode); - ENABLE_REGWRITE_BUFFER(ah); REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); @@ -1365,6 +1363,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, REGWRITE_BUFFER_FLUSH(ah); + ath9k_hw_set_operating_mode(ah, ah->opmode); + r = ath9k_hw_rf_set_freq(ah, chan); if (r) return r; -- cgit v1.2.3 From 4d9067405c21e8596087d929f3d858d0aa5002ff Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 26 Jan 2011 21:59:18 +0530 Subject: ath9k_hw: Fix INI fixup Commit "ath9k_hw: move AR9280 PCI EEPROM fix to eeprom_def.c" changed the behavior of INI overriding which is needed only for PCI cards. Revert to the original check. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/eeprom_def.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index c9318ff40964..fccd87df7300 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -247,9 +247,9 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) } /* Enable fixup for AR_AN_TOP2 if necessary */ - if (AR_SREV_9280_20_OR_LATER(ah) && - (eep->baseEepHeader.version & 0xff) > 0x0a && - eep->baseEepHeader.pwdclkind == 0) + if ((ah->hw_version.devid == AR9280_DEVID_PCI) && + ((eep->baseEepHeader.version & 0xff) > 0x0a) && + (eep->baseEepHeader.pwdclkind == 0)) ah->need_an_top2_fixup = 1; if ((common->bus_ops->ath_bus_type == ATH_USB) && -- cgit v1.2.3 From 0d95521ea74735826cb2e28bebf6a07392c75bfa Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 26 Jan 2011 18:23:27 +0100 Subject: ath9k: use split rx buffers to get rid of order-1 skb allocations With this change, less CPU time is spent trying to look for consecutive pages for rx skbs. This also reduces the socket memory required for IP/UDP reassembly. Only two buffers per frame are supported. Frames spanning more buffers will be dropped, but the buffer size is enough to handle the required AMSDU size. Signed-off-by: Jouni Malinen Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 + drivers/net/wireless/ath/ath9k/main.c | 5 ++ drivers/net/wireless/ath/ath9k/recv.c | 88 ++++++++++++++++++++++++---------- 3 files changed, 71 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index dd9a7d740c98..73db9576af57 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -310,6 +310,8 @@ struct ath_rx { struct ath_descdma rxdma; struct ath_buf *rx_bufptr; struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX]; + + struct sk_buff *frag; }; int ath_startrecv(struct ath_softc *sc); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 422be2675a06..23c016a81bcf 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1294,6 +1294,11 @@ static void ath9k_stop(struct ieee80211_hw *hw) } else sc->rx.rxlink = NULL; + if (sc->rx.frag) { + dev_kfree_skb_any(sc->rx.frag); + sc->rx.frag = NULL; + } + /* disable HAL and put h/w to sleep */ ath9k_hw_disable(ah); ath9k_hw_configpcipowersave(ah, 1, 1); diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index b2b12a293c70..daf171d2f610 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -209,11 +209,6 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs) int error = 0, i; u32 size; - - common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN + - ah->caps.rx_status_len, - min(common->cachelsz, (u16)64)); - ath9k_hw_set_rx_bufsize(ah, common->rx_bufsize - ah->caps.rx_status_len); @@ -300,12 +295,12 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) sc->sc_flags &= ~SC_OP_RXFLUSH; spin_lock_init(&sc->rx.rxbuflock); + common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 + + sc->sc_ah->caps.rx_status_len; + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { return ath_rx_edma_init(sc, nbufs); } else { - common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN, - min(common->cachelsz, (u16)64)); - ath_dbg(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", common->cachelsz, common->rx_bufsize); @@ -815,15 +810,9 @@ static bool ath9k_rx_accept(struct ath_common *common, if (rx_stats->rs_datalen > (common->rx_bufsize - rx_status_len)) return false; - /* - * rs_more indicates chained descriptors which can be used - * to link buffers together for a sort of scatter-gather - * operation. - * reject the frame, we don't support scatter-gather yet and - * the frame is probably corrupt anyway - */ + /* Only use error bits from the last fragment */ if (rx_stats->rs_more) - return false; + return true; /* * The rx_stats->rs_status will not be set until the end of the @@ -981,6 +970,10 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common, if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) return -EINVAL; + /* Only use status info from the last fragment */ + if (rx_stats->rs_more) + return 0; + ath9k_process_rssi(common, hw, hdr, rx_stats); if (ath9k_process_rate(common, hw, rx_stats, rx_status)) @@ -1582,7 +1575,7 @@ div_comb_done: int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) { struct ath_buf *bf; - struct sk_buff *skb = NULL, *requeue_skb; + struct sk_buff *skb = NULL, *requeue_skb, *hdr_skb; struct ieee80211_rx_status *rxs; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); @@ -1633,8 +1626,17 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) if (!skb) continue; - hdr = (struct ieee80211_hdr *) (skb->data + rx_status_len); - rxs = IEEE80211_SKB_RXCB(skb); + /* + * Take frame header from the first fragment and RX status from + * the last one. + */ + if (sc->rx.frag) + hdr_skb = sc->rx.frag; + else + hdr_skb = skb; + + hdr = (struct ieee80211_hdr *) (hdr_skb->data + rx_status_len); + rxs = IEEE80211_SKB_RXCB(hdr_skb); ath_debug_stat_rx(sc, &rs); @@ -1643,12 +1645,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) * chain it back at the queue without processing it. */ if (flush) - goto requeue; + goto requeue_drop_frag; retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs, rxs, &decrypt_error); if (retval) - goto requeue; + goto requeue_drop_frag; rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; if (rs.rs_tstamp > tsf_lower && @@ -1668,7 +1670,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) * skb and put it at the tail of the sc->rx.rxbuf list for * processing. */ if (!requeue_skb) - goto requeue; + goto requeue_drop_frag; /* Unmap the frame */ dma_unmap_single(sc->dev, bf->bf_buf_addr, @@ -1679,8 +1681,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) if (ah->caps.rx_status_len) skb_pull(skb, ah->caps.rx_status_len); - ath9k_rx_skb_postprocess(common, skb, &rs, - rxs, decrypt_error); + if (!rs.rs_more) + ath9k_rx_skb_postprocess(common, hdr_skb, &rs, + rxs, decrypt_error); /* We will now give hardware our shiny new allocated skb */ bf->bf_mpdu = requeue_skb; @@ -1697,6 +1700,38 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) break; } + if (rs.rs_more) { + /* + * rs_more indicates chained descriptors which can be + * used to link buffers together for a sort of + * scatter-gather operation. + */ + if (sc->rx.frag) { + /* too many fragments - cannot handle frame */ + dev_kfree_skb_any(sc->rx.frag); + dev_kfree_skb_any(skb); + skb = NULL; + } + sc->rx.frag = skb; + goto requeue; + } + + if (sc->rx.frag) { + int space = skb->len - skb_tailroom(hdr_skb); + + sc->rx.frag = NULL; + + if (pskb_expand_head(hdr_skb, 0, space, GFP_ATOMIC) < 0) { + dev_kfree_skb(skb); + goto requeue_drop_frag; + } + + skb_copy_from_linear_data(skb, skb_put(hdr_skb, skb->len), + skb->len); + dev_kfree_skb_any(skb); + skb = hdr_skb; + } + /* * change the default rx antenna if rx diversity chooses the * other antenna 3 times in a row. @@ -1722,6 +1757,11 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) ieee80211_rx(hw, skb); +requeue_drop_frag: + if (sc->rx.frag) { + dev_kfree_skb_any(sc->rx.frag); + sc->rx.frag = NULL; + } requeue: if (edma) { list_add_tail(&bf->list, &sc->rx.rxbuf); -- cgit v1.2.3 From 74f7635930bb157b2e83d38a68177a2b28138ead Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 26 Jan 2011 23:49:06 +0530 Subject: ath9k_hw: Add RX filters The HW has separate filter masks for compressed/uncompressed BlockAcks and BlockAckRequests. Add them. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/mac.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 7512f97e8f49..04d58ae923bb 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -639,6 +639,8 @@ enum ath9k_rx_filter { ATH9K_RX_FILTER_PHYERR = 0x00000100, ATH9K_RX_FILTER_MYBEACON = 0x00000200, ATH9K_RX_FILTER_COMP_BAR = 0x00000400, + ATH9K_RX_FILTER_COMP_BA = 0x00000800, + ATH9K_RX_FILTER_UNCOMP_BA_BAR = 0x00001000, ATH9K_RX_FILTER_PSPOLL = 0x00004000, ATH9K_RX_FILTER_PHYRADAR = 0x00002000, ATH9K_RX_FILTER_MCAST_BCAST_ALL = 0x00008000, -- cgit v1.2.3 From b141581923ab4904052174e3b4eb17cc3ce8632c Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Thu, 27 Jan 2011 14:45:07 +0530 Subject: ath9k_hw: Add a function to read sqsum_dvc. Add a function to observe the delta VC of BB_PLL. For a good chip, the sqsum_dvc is below 2000. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 13 +++++++++++++ drivers/net/wireless/ath/ath9k/hw.h | 1 + drivers/net/wireless/ath/ath9k/reg.h | 6 ++++++ 3 files changed, 20 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 48d121c24eb7..0e64d7666057 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -668,6 +668,19 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) REGWRITE_BUFFER_FLUSH(ah); } +unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) +{ + REG_WRITE(ah, PLL3, (REG_READ(ah, PLL3) & ~(PLL3_DO_MEAS_MASK))); + udelay(100); + REG_WRITE(ah, PLL3, (REG_READ(ah, PLL3) | PLL3_DO_MEAS_MASK)); + + while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) + udelay(100); + + return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3; +} +EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); + static void ath9k_hw_init_pll(struct ath_hw *ah, struct ath9k_channel *chan) { diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index c2b3515deea1..8c688a12cba8 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -928,6 +928,7 @@ void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); void ath9k_hw_reset_tsf(struct ath_hw *ah); void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); void ath9k_hw_init_global_settings(struct ath_hw *ah); +unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah); void ath9k_hw_set11nmac2040(struct ath_hw *ah); void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 4df5659c6c16..264aea7919ee 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -1129,6 +1129,12 @@ enum { #define AR_RTC_PLL_CLKSEL 0x00000300 #define AR_RTC_PLL_CLKSEL_S 8 +#define PLL3 0x16188 +#define PLL3_DO_MEAS_MASK 0x40000000 +#define PLL4 0x1618c +#define PLL4_MEAS_DONE 0x8 +#define SQSUM_DVC_MASK 0x007ffff8 + #define AR_RTC_RESET \ ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0040) : 0x7040) #define AR_RTC_RESET_EN (0x00000001) -- cgit v1.2.3 From 181fb18daaf88a20175b0da70024563b0b7c0666 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Thu, 27 Jan 2011 14:45:08 +0530 Subject: ath9k: Fix a PLL hang issue observed with AR9485. When this PLL hang issue is seen, both Rx and Tx fail to work. The sqsum_dvc needs to be below 2000 for a good chip. During this issue the sqsum_dvc value is beyond 80000 and only a full reset can solve this problem. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/main.c | 3 +++ drivers/net/wireless/ath/ath9k/xmit.c | 23 +++++++++++++++++++++++ 3 files changed, 27 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 73db9576af57..a23e9a884693 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -641,6 +641,7 @@ struct ath_softc { #endif struct ath_beacon_config cur_beacon_conf; struct delayed_work tx_complete_work; + struct delayed_work hw_pll_work; struct ath_btcoex btcoex; struct ath_descdma txsdma; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 23c016a81bcf..0663a32d81d2 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -230,6 +230,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, cancel_work_sync(&sc->paprd_work); cancel_work_sync(&sc->hw_check_work); cancel_delayed_work_sync(&sc->tx_complete_work); + cancel_delayed_work_sync(&sc->hw_pll_work); ath9k_ps_wakeup(sc); @@ -290,6 +291,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, if (sc->sc_flags & SC_OP_BEACONS) ath_beacon_config(sc, NULL); ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); + ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2); ath_start_ani(common); } @@ -1263,6 +1265,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) cancel_delayed_work_sync(&sc->ath_led_blink_work); cancel_delayed_work_sync(&sc->tx_complete_work); + cancel_delayed_work_sync(&sc->hw_pll_work); cancel_work_sync(&sc->paprd_work); cancel_work_sync(&sc->hw_check_work); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 879365e9b1c9..10a3dbefaa09 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -2091,6 +2091,28 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) } } +static void ath_hw_pll_work(struct work_struct *work) +{ + struct ath_softc *sc = container_of(work, struct ath_softc, + hw_pll_work.work); + static int count; + + if (AR_SREV_9485(sc->sc_ah)) { + if (ar9003_get_pll_sqsum_dvc(sc->sc_ah) >= 0x40000) { + count++; + + if (count == 3) { + /* Rx is hung for more than 500ms. Reset it */ + ath_reset(sc, true); + count = 0; + } + } else + count = 0; + + ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); + } +} + static void ath_tx_complete_poll_work(struct work_struct *work) { struct ath_softc *sc = container_of(work, struct ath_softc, @@ -2312,6 +2334,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) } INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); + INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { error = ath_tx_edma_init(sc); -- cgit v1.2.3 From 22983c301f01b297a6f85de4757108c6b0eac792 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Thu, 27 Jan 2011 14:45:09 +0530 Subject: ath9k_hw: DDR_PLL and BB_PLL need correct setting. Updates from the analog team for AR9485 chipsets to set DDR_PLL2 and DDR_PLL3. Also program the BB_PLL ki and kd value. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 26 +++++++++++++++++++++++++- drivers/net/wireless/ath/ath9k/reg.h | 11 +++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 0e64d7666057..ca6f10b8947a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -681,13 +681,37 @@ unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) } EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); +#define DPLL2_KD_VAL 0x3D +#define DPLL2_KI_VAL 0x06 +#define DPLL3_PHASE_SHIFT_VAL 0x1 + static void ath9k_hw_init_pll(struct ath_hw *ah, struct ath9k_channel *chan) { u32 pll; - if (AR_SREV_9485(ah)) + if (AR_SREV_9485(ah)) { REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); + REG_WRITE(ah, AR_CH0_DDR_DPLL2, 0x19e82f01); + + REG_RMW_FIELD(ah, AR_CH0_DDR_DPLL3, + AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); + + REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); + udelay(100); + + REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); + + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, + AR_CH0_DPLL2_KD, DPLL2_KD_VAL); + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, + AR_CH0_DPLL2_KI, DPLL2_KI_VAL); + + REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, + AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); + REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c); + udelay(110); + } pll = ath9k_hw_compute_pll_control(ah, chan); diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 264aea7919ee..b262e98709de 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -1083,6 +1083,17 @@ enum { #define AR_ENT_OTP 0x40d8 #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 #define AR_ENT_OTP_MPSD 0x00800000 +#define AR_CH0_BB_DPLL2 0x16184 +#define AR_CH0_BB_DPLL3 0x16188 +#define AR_CH0_DDR_DPLL2 0x16244 +#define AR_CH0_DDR_DPLL3 0x16248 +#define AR_CH0_DPLL2_KD 0x03F80000 +#define AR_CH0_DPLL2_KD_S 19 +#define AR_CH0_DPLL2_KI 0x3C000000 +#define AR_CH0_DPLL2_KI_S 26 +#define AR_CH0_DPLL3_PHASE_SHIFT 0x3F800000 +#define AR_CH0_DPLL3_PHASE_SHIFT_S 23 +#define AR_PHY_CCA_NOM_VAL_2GHZ -118 #define AR_RTC_9300_PLL_DIV 0x000003ff #define AR_RTC_9300_PLL_DIV_S 0 -- cgit v1.2.3 From bdd62c067d596e2469b243af9887f46e5d47d971 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Thu, 27 Jan 2011 14:45:10 +0530 Subject: ath9k: Fix a locking related issue. Spin_lock has been tried to be acquired twice from ath9k_tasklet to ath_reset which resulted in a machine freeze. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 10a3dbefaa09..d211aa7f1a3b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -563,8 +563,11 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, rcu_read_unlock(); - if (needreset) + if (needreset) { + spin_unlock_bh(&sc->sc_pcu_lock); ath_reset(sc, false); + spin_lock_bh(&sc->sc_pcu_lock); + } } static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, -- cgit v1.2.3 From ebefce3d13f8b5a871337ff7c3821ee140c1ea8a Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Thu, 27 Jan 2011 14:45:11 +0530 Subject: ath9k_hw: Update PMU setting to improve ripple issue for AR9485. Change from the systems team to update PMU setting for AR9485 version of chipsets. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index a25655640f48..4a9271802991 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3673,7 +3673,7 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) return; reg_pmu_set = (5 << 1) | (7 << 4) | (1 << 8) | - (7 << 14) | (6 << 17) | (1 << 20) | + (2 << 14) | (6 << 17) | (1 << 20) | (3 << 24) | (1 << 28); REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set); -- cgit v1.2.3 From de87f736e3573ccf5e8c5b45966812b7d65c0b85 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 28 Jan 2011 11:35:43 +0530 Subject: ath9k: use common API to avoid code duplication Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 - drivers/net/wireless/ath/ath9k/main.c | 72 ++-------------------------------- 2 files changed, 3 insertions(+), 71 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index a23e9a884693..bd85e311c51b 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -672,8 +672,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, const struct ath_bus_ops *bus_ops); void ath9k_deinit_device(struct ath_softc *sc); void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); -void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, - struct ath9k_channel *ichan); int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, struct ath9k_channel *hchan); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 0663a32d81d2..91af57c48581 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -73,7 +73,7 @@ static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc, chan_idx = curchan->hw_value; channel = &sc->sc_ah->channels[chan_idx]; - ath9k_update_ichannel(sc, hw, channel); + ath9k_cmn_update_ichannel(channel, curchan, hw->conf.channel_type); return channel; } @@ -808,48 +808,6 @@ chip_reset: #undef SCHED_INTR } -static u32 ath_get_extchanmode(struct ath_softc *sc, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type) -{ - u32 chanmode = 0; - - switch (chan->band) { - case IEEE80211_BAND_2GHZ: - switch(channel_type) { - case NL80211_CHAN_NO_HT: - case NL80211_CHAN_HT20: - chanmode = CHANNEL_G_HT20; - break; - case NL80211_CHAN_HT40PLUS: - chanmode = CHANNEL_G_HT40PLUS; - break; - case NL80211_CHAN_HT40MINUS: - chanmode = CHANNEL_G_HT40MINUS; - break; - } - break; - case IEEE80211_BAND_5GHZ: - switch(channel_type) { - case NL80211_CHAN_NO_HT: - case NL80211_CHAN_HT20: - chanmode = CHANNEL_A_HT20; - break; - case NL80211_CHAN_HT40PLUS: - chanmode = CHANNEL_A_HT40PLUS; - break; - case NL80211_CHAN_HT40MINUS: - chanmode = CHANNEL_A_HT40MINUS; - break; - } - break; - default: - break; - } - - return chanmode; -} - static void ath9k_bss_assoc_info(struct ath_softc *sc, struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -1045,30 +1003,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) return r; } -/* XXX: Remove me once we don't depend on ath9k_channel for all - * this redundant data */ -void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, - struct ath9k_channel *ichan) -{ - struct ieee80211_channel *chan = hw->conf.channel; - struct ieee80211_conf *conf = &hw->conf; - - ichan->channel = chan->center_freq; - ichan->chan = chan; - - if (chan->band == IEEE80211_BAND_2GHZ) { - ichan->chanmode = CHANNEL_G; - ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_G; - } else { - ichan->chanmode = CHANNEL_A; - ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM; - } - - if (conf_is_ht(conf)) - ichan->chanmode = ath_get_extchanmode(sc, chan, - conf->channel_type); -} - /**********************/ /* mac80211 callbacks */ /**********************/ @@ -1727,8 +1661,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) ath_dbg(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", curchan->center_freq); - /* XXX: remove me eventualy */ - ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]); + ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos], + curchan, conf->channel_type); /* update survey stats for the old channel before switching */ spin_lock_irqsave(&common->cc_lock, flags); -- cgit v1.2.3 From 76a9f6fd9adc5ce62b4ea36a099bb1458d4cb7a6 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Fri, 28 Jan 2011 16:52:11 +0900 Subject: ath5k: Fix short and long retry configuration The register definition for retry configuration on AR5212 was wrong, and simply copied over from AR5210. Update the register definitions from the documentation. Let the short and long retries be configured from mac80211 and use the standard values of 7 and 4 by default. Also we need to make sure we don't export more retries than we are configured for to mac80211 (and the rate module) in hw->max_rate_tries. Also clean up the code by removing unused defines and variables and drop the different values for "station retries" - if these need to be different it can be handled tru ah_retry_long/short. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 18 +++++------ drivers/net/wireless/ath/ath5k/attach.c | 4 +-- drivers/net/wireless/ath/ath5k/base.c | 3 +- drivers/net/wireless/ath/ath5k/mac80211-ops.c | 9 ++++++ drivers/net/wireless/ath/ath5k/qcu.c | 46 ++++++++++----------------- drivers/net/wireless/ath/ath5k/reg.h | 15 ++++----- 6 files changed, 44 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 407e39c2b10b..e43175a89d67 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -210,14 +210,9 @@ /* Initial values */ #define AR5K_INIT_CYCRSSI_THR1 2 -/* Tx retry limits */ -#define AR5K_INIT_SH_RETRY 10 -#define AR5K_INIT_LG_RETRY AR5K_INIT_SH_RETRY -/* For station mode */ -#define AR5K_INIT_SSH_RETRY 32 -#define AR5K_INIT_SLG_RETRY AR5K_INIT_SSH_RETRY -#define AR5K_INIT_TX_RETRY 10 - +/* Tx retry limit defaults from standard */ +#define AR5K_INIT_RETRY_SHORT 7 +#define AR5K_INIT_RETRY_LONG 4 /* Slot time */ #define AR5K_INIT_SLOT_TIME_TURBO 6 @@ -1057,7 +1052,9 @@ struct ath5k_hw { #define ah_modes ah_capabilities.cap_mode #define ah_ee_version ah_capabilities.cap_eeprom.ee_version - u32 ah_limit_tx_retries; + u8 ah_retry_long; + u8 ah_retry_short; + u8 ah_coverage_class; bool ah_ack_bitrate_high; u8 ah_bwmode; @@ -1067,7 +1064,6 @@ struct ath5k_hw { u8 ah_ant_mode; u8 ah_tx_ant; u8 ah_def_ant; - bool ah_software_retry; struct ath5k_capabilities ah_capabilities; @@ -1250,6 +1246,8 @@ int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, struct ath5k_txq_info *queue_info); +void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah, + unsigned int queue); u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue); void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue); int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue); diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index cdac5cff0177..c71fdbb4c439 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -118,8 +118,8 @@ int ath5k_hw_init(struct ath5k_softc *sc) ah->ah_bwmode = AR5K_BWMODE_DEFAULT; ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; ah->ah_imr = 0; - ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; - ah->ah_software_retry = false; + ah->ah_retry_short = AR5K_INIT_RETRY_SHORT; + ah->ah_retry_long = AR5K_INIT_RETRY_LONG; ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT; ah->ah_noise_floor = -95; /* until first NF calibration is run */ sc->ani_state.ani_mode = ATH5K_ANI_MODE_AUTO; diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index c0927d7b7c6b..e9e7af6e4b62 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2399,7 +2399,8 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops) /* set up multi-rate retry capabilities */ if (sc->ah->ah_version == AR5K_AR5212) { hw->max_rates = 4; - hw->max_rate_tries = 11; + hw->max_rate_tries = max(AR5K_INIT_RETRY_SHORT, + AR5K_INIT_RETRY_LONG); } hw->vif_data_size = sizeof(struct ath5k_vif); diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index d76d68c99f72..36a51995a7bc 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -226,6 +226,7 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed) struct ath5k_hw *ah = sc->ah; struct ieee80211_conf *conf = &hw->conf; int ret = 0; + int i; mutex_lock(&sc->lock); @@ -243,6 +244,14 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed) ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2)); } + if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { + ah->ah_retry_long = conf->long_frame_max_tx_count; + ah->ah_retry_short = conf->short_frame_max_tx_count; + + for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) + ath5k_hw_set_tx_retry_limits(ah, i); + } + /* TODO: * 1) Move this on config_interface and handle each case * separately eg. when we have only one STA vif, use diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 2c9c9e793d4e..3343fb9e4940 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -228,24 +228,9 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, /* * Set tx retry limits on DCU */ -static void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah, - unsigned int queue) +void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah, + unsigned int queue) { - u32 retry_lg, retry_sh; - - /* - * Calculate and set retry limits - */ - if (ah->ah_software_retry) { - /* XXX Need to test this */ - retry_lg = ah->ah_limit_tx_retries; - retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ? - AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg; - } else { - retry_lg = AR5K_INIT_LG_RETRY; - retry_sh = AR5K_INIT_SH_RETRY; - } - /* Single data queue on AR5210 */ if (ah->ah_version == AR5K_AR5210) { struct ath5k_txq_info *tq = &ah->ah_txq[queue]; @@ -255,25 +240,26 @@ static void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah, ath5k_hw_reg_write(ah, (tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S) - | AR5K_REG_SM(AR5K_INIT_SLG_RETRY, - AR5K_NODCU_RETRY_LMT_SLG_RETRY) - | AR5K_REG_SM(AR5K_INIT_SSH_RETRY, - AR5K_NODCU_RETRY_LMT_SSH_RETRY) - | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY) - | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY), + | AR5K_REG_SM(ah->ah_retry_long, + AR5K_NODCU_RETRY_LMT_SLG_RETRY) + | AR5K_REG_SM(ah->ah_retry_short, + AR5K_NODCU_RETRY_LMT_SSH_RETRY) + | AR5K_REG_SM(ah->ah_retry_long, + AR5K_NODCU_RETRY_LMT_LG_RETRY) + | AR5K_REG_SM(ah->ah_retry_short, + AR5K_NODCU_RETRY_LMT_SH_RETRY), AR5K_NODCU_RETRY_LMT); /* DCU on AR5211+ */ } else { ath5k_hw_reg_write(ah, - AR5K_REG_SM(AR5K_INIT_SLG_RETRY, - AR5K_DCU_RETRY_LMT_SLG_RETRY) | - AR5K_REG_SM(AR5K_INIT_SSH_RETRY, - AR5K_DCU_RETRY_LMT_SSH_RETRY) | - AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) | - AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY), + AR5K_REG_SM(ah->ah_retry_long, + AR5K_DCU_RETRY_LMT_RTS) + | AR5K_REG_SM(ah->ah_retry_long, + AR5K_DCU_RETRY_LMT_STA_RTS) + | AR5K_REG_SM(max(ah->ah_retry_long, ah->ah_retry_short), + AR5K_DCU_RETRY_LMT_STA_DATA), AR5K_QUEUE_DFS_RETRY_LIMIT(queue)); } - return; } /** diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index fd14b9103951..e1c9abd8c879 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h @@ -686,16 +686,15 @@ /* * DCU retry limit registers + * all these fields don't allow zero values */ #define AR5K_DCU_RETRY_LMT_BASE 0x1080 /* Register Address -Queue0 DCU_RETRY_LMT */ -#define AR5K_DCU_RETRY_LMT_SH_RETRY 0x0000000f /* Short retry limit mask */ -#define AR5K_DCU_RETRY_LMT_SH_RETRY_S 0 -#define AR5K_DCU_RETRY_LMT_LG_RETRY 0x000000f0 /* Long retry limit mask */ -#define AR5K_DCU_RETRY_LMT_LG_RETRY_S 4 -#define AR5K_DCU_RETRY_LMT_SSH_RETRY 0x00003f00 /* Station short retry limit mask (?) */ -#define AR5K_DCU_RETRY_LMT_SSH_RETRY_S 8 -#define AR5K_DCU_RETRY_LMT_SLG_RETRY 0x000fc000 /* Station long retry limit mask (?) */ -#define AR5K_DCU_RETRY_LMT_SLG_RETRY_S 14 +#define AR5K_DCU_RETRY_LMT_RTS 0x0000000f /* RTS failure limit. Transmission fails if no CTS is received for this number of times */ +#define AR5K_DCU_RETRY_LMT_RTS_S 0 +#define AR5K_DCU_RETRY_LMT_STA_RTS 0x00003f00 /* STA RTS failure limit. If exceeded CW reset */ +#define AR5K_DCU_RETRY_LMT_STA_RTS_S 8 +#define AR5K_DCU_RETRY_LMT_STA_DATA 0x000fc000 /* STA data failure limit. If exceeded CW reset. */ +#define AR5K_DCU_RETRY_LMT_STA_DATA_S 14 #define AR5K_QUEUE_DFS_RETRY_LIMIT(_q) AR5K_QUEUE_REG(AR5K_DCU_RETRY_LMT_BASE, _q) /* -- cgit v1.2.3 From f844a709a7d8f8be61a571afc31dfaca9e779621 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 28 Jan 2011 16:47:44 +0100 Subject: iwlwifi: do not set tx power when channel is changing Mac80211 can request for tx power and channel change in one ->config call. If that happens, *_send_tx_power functions will try to setup tx power for old channel, what can be not correct because we already change the band. I.e error "Failed to get channel info for channel 140 [0]", can be printed frequently when operating in software scanning mode. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945.c | 2 +- drivers/net/wireless/iwlwifi/iwl-4965.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 5 ++--- drivers/net/wireless/iwlwifi/iwl-core.c | 13 ++++++++++--- 4 files changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 1d9dcd7e3b82..294221b06813 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -1890,7 +1890,7 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) /* If we issue a new RXON command which required a tune then we must * send a new TXPOWER command or we won't be able to Tx any frames */ - rc = priv->cfg->ops->lib->send_tx_power(priv); + rc = iwl_set_tx_power(priv, priv->tx_power_next, true); if (rc) { IWL_ERR(priv, "Error setting Tx power (%d).\n", rc); return rc; diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index d9a7d93def6c..053240642b50 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -1571,7 +1571,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c /* If we issue a new RXON command which required a tune then we must * send a new TXPOWER command or we won't be able to Tx any frames */ - ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); + ret = iwl_set_tx_power(priv, priv->tx_power_next, true); if (ret) { IWL_ERR(priv, "Error sending TX power (%d)\n", ret); return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 2a4ff832fbb8..6c2adc58d654 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -316,10 +316,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) * If we issue a new RXON command which required a tune then we must * send a new TXPOWER command or we won't be able to Tx any frames. * - * FIXME: which RXON requires a tune? Can we optimise this out in - * some cases? + * It's expected we set power here if channel is changing. */ - ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); + ret = iwl_set_tx_power(priv, priv->tx_power_next, true); if (ret) { IWL_ERR(priv, "Error sending TX power (%d)\n", ret); return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index a46ad60216a0..92724cbf18ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1162,6 +1162,8 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) { int ret; s8 prev_tx_power; + bool defer; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; lockdep_assert_held(&priv->mutex); @@ -1189,10 +1191,15 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) if (!iwl_is_ready_rf(priv)) return -EIO; - /* scan complete use tx_power_next, need to be updated */ + /* scan complete and commit_rxon use tx_power_next value, + * it always need to be updated for newest request */ priv->tx_power_next = tx_power; - if (test_bit(STATUS_SCANNING, &priv->status) && !force) { - IWL_DEBUG_INFO(priv, "Deferring tx power set while scanning\n"); + + /* do not set tx power when scanning or channel changing */ + defer = test_bit(STATUS_SCANNING, &priv->status) || + memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)); + if (defer && !force) { + IWL_DEBUG_INFO(priv, "Deferring tx power set\n"); return 0; } -- cgit v1.2.3 From 5a5289dfa5f79168bd477bba2353da90786c83d6 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 28 Jan 2011 16:47:45 +0100 Subject: iwl3945: set STATUS_READY before commit_rxon Similar change as we already do for agn, need to avoid "Error setting Tx power (-5)" message when loading module. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl3945-base.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 9c986f272c2d..55837d607534 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2535,13 +2535,14 @@ static void iwl3945_alive_start(struct iwl_priv *priv) /* Configure Bluetooth device coexistence support */ priv->cfg->ops->hcmd->send_bt_config(priv); + set_bit(STATUS_READY, &priv->status); + /* Configure the adapter for unassociated operation */ iwl3945_commit_rxon(priv, ctx); iwl3945_reg_txpower_periodic(priv); IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); - set_bit(STATUS_READY, &priv->status); wake_up_interruptible(&priv->wait_command_queue); return; -- cgit v1.2.3 From a839cf6955fb6cb731235c310cb0c72c1a2fecbe Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 28 Jan 2011 16:47:46 +0100 Subject: iwlwifi: remove unneeded __packed struct iwl_queue is not part of firmware interface, so __packed is not needed. Remove it since is may affect performance. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 6fa1383d72ec..b5f21e041953 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -138,7 +138,7 @@ struct iwl_queue { * space more than this */ int high_mark; /* high watermark, stop queue if free * space less than this */ -} __packed; +}; /* One for each TFD */ struct iwl_tx_info { -- cgit v1.2.3 From 88e58fc5d940c3463c7070a2a7a8a0ce65af3fdc Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 28 Jan 2011 16:47:47 +0100 Subject: iwlwifi: introduce iwl_advanced_bt_coexist() We use priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist conditional in few places, merge it into one function. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.h | 6 ++++++ drivers/net/wireless/iwlwifi/iwl-debugfs.c | 2 +- drivers/net/wireless/iwlwifi/iwl-power.c | 6 ++---- drivers/net/wireless/iwlwifi/iwl-scan.c | 3 +-- 4 files changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index bbc5aa7a7f2f..705711a01b17 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -741,6 +741,12 @@ static inline const struct ieee80211_supported_band *iwl_get_hw_mode( return priv->hw->wiphy->bands[band]; } +static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) +{ + return priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist; +} + extern bool bt_coex_active; extern bool bt_siso_mode; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 418c8ac26222..bde16acb08ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1771,7 +1771,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR); - if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) + if (iwl_advanced_bt_coexist(priv)) DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); if (priv->cfg->base_params->sensitivity_calib_by_driver) DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 1eec18d909d8..25f7d474f346 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -226,8 +226,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, else cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist) { + if (iwl_advanced_bt_coexist(priv)) { if (!priv->cfg->bt_params->bt_sco_disable) cmd->flags |= IWL_POWER_BT_SCO_ENA; else @@ -313,8 +312,7 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv, else cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist) { + if (iwl_advanced_bt_coexist(priv)) { if (!priv->cfg->bt_params->bt_sco_disable) cmd->flags |= IWL_POWER_BT_SCO_ENA; else diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 12d9363d0afe..08f1bea8b652 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -257,8 +257,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, queue_work(priv->workqueue, &priv->scan_completed); if (priv->iw_mode != NL80211_IFTYPE_ADHOC && - priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist && + iwl_advanced_bt_coexist(priv) && priv->bt_status != scan_notif->bt_status) { if (scan_notif->bt_status) { /* BT on */ -- cgit v1.2.3 From 8c9f514b38bb01f0af09f880fe8b3cd5342d2401 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 28 Jan 2011 16:47:48 +0100 Subject: iwlwifi: remove unneeded disable_hw_scan check We never set STATUS_SCANNING in softwre scanning mode, disable_hw_scan check is unneeded. Correct debug message while at it. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-legacy.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.c b/drivers/net/wireless/iwlwifi/iwl-legacy.c index 927fe37a43ab..e1ace3ce30b3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-legacy.c +++ b/drivers/net/wireless/iwlwifi/iwl-legacy.c @@ -85,10 +85,9 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed) IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", channel->hw_value, changed); - if (unlikely(!priv->cfg->mod_params->disable_hw_scan && - test_bit(STATUS_SCANNING, &priv->status))) { + if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) { scan_active = 1; - IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); + IWL_DEBUG_MAC80211(priv, "scan active\n"); } if (changed & (IEEE80211_CONF_CHANGE_SMPS | -- cgit v1.2.3 From 9f60e7ee4206507c7f248d06e3b4a8a59ed33308 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 28 Jan 2011 16:47:51 +0100 Subject: iwlwifi: introduce iwl_bt_statistics We use priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics conditional in few places, merge it into one function. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 9 +++------ drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c | 12 ++++-------- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 15 +++++---------- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 +-- drivers/net/wireless/iwlwifi/iwl-core.h | 5 +++++ drivers/net/wireless/iwlwifi/iwl-debugfs.c | 2 +- 6 files changed, 19 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index d16bb5ede014..9006293e740c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -631,8 +631,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp) } spin_lock_irqsave(&priv->lock, flags); - if (priv->cfg->bt_params && - priv->cfg->bt_params->bt_statistics) { + if (iwl_bt_statistics(priv)) { rx_info = &(((struct iwl_bt_notif_statistics *)resp)-> rx.general.common); ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm); @@ -897,8 +896,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) } spin_lock_irqsave(&priv->lock, flags); - if (priv->cfg->bt_params && - priv->cfg->bt_params->bt_statistics) { + if (iwl_bt_statistics(priv)) { rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)-> rx.general.common); } else { @@ -913,8 +911,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK); rxon_chnum = le16_to_cpu(ctx->staging.channel); - if (priv->cfg->bt_params && - priv->cfg->bt_params->bt_statistics) { + if (iwl_bt_statistics(priv)) { stat_band24 = !!(((struct iwl_bt_notif_statistics *) stat_resp)->flag & STATISTICS_REPLY_FLG_BAND_24G_MSK); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c index a6dbd8983dac..b500aaae53ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c @@ -39,8 +39,7 @@ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) int p = 0; u32 flag; - if (priv->cfg->bt_params && - priv->cfg->bt_params->bt_statistics) + if (iwl_bt_statistics(priv)) flag = le32_to_cpu(priv->_agn.statistics_bt.flag); else flag = le32_to_cpu(priv->_agn.statistics.flag); @@ -89,8 +88,7 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, * the last statistics notification from uCode * might not reflect the current uCode activity */ - if (priv->cfg->bt_params && - priv->cfg->bt_params->bt_statistics) { + if (iwl_bt_statistics(priv)) { ofdm = &priv->_agn.statistics_bt.rx.ofdm; cck = &priv->_agn.statistics_bt.rx.cck; general = &priv->_agn.statistics_bt.rx.general.common; @@ -536,8 +534,7 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, * the last statistics notification from uCode * might not reflect the current uCode activity */ - if (priv->cfg->bt_params && - priv->cfg->bt_params->bt_statistics) { + if (iwl_bt_statistics(priv)) { tx = &priv->_agn.statistics_bt.tx; accum_tx = &priv->_agn.accum_statistics_bt.tx; delta_tx = &priv->_agn.delta_statistics_bt.tx; @@ -737,8 +734,7 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, * the last statistics notification from uCode * might not reflect the current uCode activity */ - if (priv->cfg->bt_params && - priv->cfg->bt_params->bt_statistics) { + if (iwl_bt_statistics(priv)) { general = &priv->_agn.statistics_bt.general.common; dbg = &priv->_agn.statistics_bt.general.common.dbg; div = &priv->_agn.statistics_bt.general.common.div; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index bbd40b7dd597..b192ca842f0a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -73,8 +73,7 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv) int bcn_silence_a, bcn_silence_b, bcn_silence_c; int last_rx_noise; - if (priv->cfg->bt_params && - priv->cfg->bt_params->bt_statistics) + if (iwl_bt_statistics(priv)) rx_info = &(priv->_agn.statistics_bt.rx.general.common); else rx_info = &(priv->_agn.statistics.rx.general); @@ -125,8 +124,7 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv, struct statistics_general_common *general, *accum_general; struct statistics_tx *tx, *accum_tx; - if (priv->cfg->bt_params && - priv->cfg->bt_params->bt_statistics) { + if (iwl_bt_statistics(priv)) { prev_stats = (__le32 *)&priv->_agn.statistics_bt; accum_stats = (u32 *)&priv->_agn.accum_statistics_bt; size = sizeof(struct iwl_bt_notif_statistics); @@ -207,8 +205,7 @@ bool iwl_good_plcp_health(struct iwl_priv *priv, struct statistics_rx_phy *ofdm; struct statistics_rx_ht_phy *ofdm_ht; - if (priv->cfg->bt_params && - priv->cfg->bt_params->bt_statistics) { + if (iwl_bt_statistics(priv)) { ofdm = &pkt->u.stats_bt.rx.ofdm; ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht; combined_plcp_delta = @@ -265,8 +262,7 @@ void iwl_rx_statistics(struct iwl_priv *priv, int change; struct iwl_rx_packet *pkt = rxb_addr(rxb); - if (priv->cfg->bt_params && - priv->cfg->bt_params->bt_statistics) { + if (iwl_bt_statistics(priv)) { IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", (int)sizeof(struct iwl_bt_notif_statistics), @@ -304,8 +300,7 @@ void iwl_rx_statistics(struct iwl_priv *priv, iwl_recover_from_statistics(priv, pkt); - if (priv->cfg->bt_params && - priv->cfg->bt_params->bt_statistics) + if (iwl_bt_statistics(priv)) memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt, sizeof(priv->_agn.statistics_bt)); else diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index eb16647cfbe0..646ccb2430b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3077,8 +3077,7 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) } if (priv->start_calib) { - if (priv->cfg->bt_params && - priv->cfg->bt_params->bt_statistics) { + if (iwl_bt_statistics(priv)) { iwl_chain_noise_calibration(priv, (void *)&priv->_agn.statistics_bt); iwl_sensitivity_calibration(priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 705711a01b17..c83fcc60ccc5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -747,6 +747,11 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) priv->cfg->bt_params->advanced_bt_coexist; } +static inline bool iwl_bt_statistics(struct iwl_priv *priv) +{ + return priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics; +} + extern bool bt_coex_active; extern bool bt_siso_mode; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index bde16acb08ca..bdcb74279f1e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1765,7 +1765,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); if (priv->cfg->base_params->ucode_tracing) DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); - if (priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics) + if (iwl_bt_statistics(priv)) DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); -- cgit v1.2.3 From 3bf63e59e577cbecd41334c866f501c4cc5d54c5 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 28 Jan 2011 17:52:49 +0100 Subject: ath9k: fix compile error in non-debug ath_debug_stat_tx() stub "ath9k: fix tx queue index confusion in debugfs code" changed the debug function but not the stub. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 1bdc6d4ceb17..59338de0ce19 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -192,7 +192,8 @@ static inline void ath_debug_stat_interrupt(struct ath_softc *sc, static inline void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, - struct ath_tx_status *ts) + struct ath_tx_status *ts, + struct ath_txq *txq) { } -- cgit v1.2.3 From 3e50191d981082345572f1e80b463eb9c05989a0 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Sat, 29 Jan 2011 15:57:32 +1100 Subject: crypto: omap-aes - don't treat NULL clk as an error clk_get() returns a struct clk cookie to the driver and some platforms may return NULL if they only support a single clock. clk_get() has only failed if it returns a ERR_PTR() encoded pointer. Signed-off-by: Jamie Iles Reviewed-and-tested-by: Tobias Karnat Signed-off-by: Herbert Xu --- drivers/crypto/omap-aes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c index add2a1a72ba4..5b970d9e9956 100644 --- a/drivers/crypto/omap-aes.c +++ b/drivers/crypto/omap-aes.c @@ -839,9 +839,9 @@ static int omap_aes_probe(struct platform_device *pdev) /* Initializing the clock */ dd->iclk = clk_get(dev, "ick"); - if (!dd->iclk) { + if (IS_ERR(dd->iclk)) { dev_err(dev, "clock intialization failed.\n"); - err = -ENODEV; + err = PTR_ERR(dd->iclk); goto err_res; } -- cgit v1.2.3 From 36be070ac600d023ada2ec107ee925f5ac5f902b Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Sat, 29 Jan 2011 16:01:02 +1100 Subject: crypto: omap-sham - don't treat NULL clk as an error clk_get() returns a struct clk cookie to the driver and some platforms may return NULL if they only support a single clock. clk_get() has only failed if it returns a ERR_PTR() encoded pointer. Signed-off-by: Jamie Iles Reviewed-by: Aaro Koskinen Reviewed-by: Dmitry Kasatkin Signed-off-by: Herbert Xu --- drivers/crypto/omap-sham.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index 2e71123516e0..465cde3e4f60 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -1206,9 +1206,9 @@ static int __devinit omap_sham_probe(struct platform_device *pdev) /* Initializing the clock */ dd->iclk = clk_get(dev, "ick"); - if (!dd->iclk) { + if (IS_ERR(dd->iclk)) { dev_err(dev, "clock intialization failed.\n"); - err = -ENODEV; + err = PTR_ERR(dd->iclk); goto clk_err; } -- cgit v1.2.3 From 6866fd3b7289a283741752b73e0e09f410b7639d Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 12 Jan 2011 11:18:14 +0100 Subject: dmaengine i.MX SDMA: Fix firmware loading When loading the microcode to the SDMA engine we have to use the ram_code_start_addr found in the firmware image. The copy in the sdma engine is not initialized correctly. This is broken since: 5b28aa3 dmaengine i.MX SDMA: Allow to run without firmware Signed-off-by: Sascha Hauer Signed-off-by: Dan Williams --- drivers/dma/imx-sdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index d5a5d4d9c19b..75df8b937413 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -1135,7 +1135,7 @@ static int __init sdma_get_firmware(struct sdma_engine *sdma, /* download the RAM image for SDMA */ sdma_load_script(sdma, ram_code, header->ram_code_size, - sdma->script_addrs->ram_code_start_addr); + addr->ram_code_start_addr); clk_disable(sdma->clk); sdma_add_scripts(sdma, addr); -- cgit v1.2.3 From 939fd4f077269dd863cd630a3b3195a20acf7d02 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 19 Jan 2011 19:13:06 +0800 Subject: dmaengine: imx-sdma: propagate error in sdma_probe() instead of returning 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Shawn Guo Acked-by: Uwe Kleine-König Signed-off-by: Dan Williams --- drivers/dma/imx-sdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 75df8b937413..1dbaf61eea2d 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -1348,7 +1348,7 @@ err_clk: err_request_region: err_irq: kfree(sdma); - return 0; + return ret; } static int __exit sdma_remove(struct platform_device *pdev) -- cgit v1.2.3 From d718f4ebddcb0bebdbf771a6672756b666e5c31b Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Mon, 17 Jan 2011 22:39:24 +0800 Subject: dmaengine: imx-sdma: fix inconsistent naming in sdma_assign_cookie() Variable name sdma and sdmac are consistently used as the pointer to sdma_engine and sdma_channel respectively throughout the file. The patch fixes the inconsistency seen in function sdma_assign_cookie(). Signed-off-by: Shawn Guo Signed-off-by: Dan Williams --- drivers/dma/imx-sdma.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 1dbaf61eea2d..e89fd1033df9 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -770,15 +770,15 @@ static void sdma_enable_channel(struct sdma_engine *sdma, int channel) __raw_writel(1 << channel, sdma->regs + SDMA_H_START); } -static dma_cookie_t sdma_assign_cookie(struct sdma_channel *sdma) +static dma_cookie_t sdma_assign_cookie(struct sdma_channel *sdmac) { - dma_cookie_t cookie = sdma->chan.cookie; + dma_cookie_t cookie = sdmac->chan.cookie; if (++cookie < 0) cookie = 1; - sdma->chan.cookie = cookie; - sdma->desc.cookie = cookie; + sdmac->chan.cookie = cookie; + sdmac->desc.cookie = cookie; return cookie; } -- cgit v1.2.3 From fb526210b2b961b5d590b89fd8f45c0ca5769688 Mon Sep 17 00:00:00 2001 From: Russell King - ARM Linux Date: Thu, 27 Jan 2011 12:32:53 +0000 Subject: DMA: PL08x: fix infinite wait when terminating transfers If we try to pause a channel when terminating a transfer, we could end up spinning for it to become inactive indefinitely, and can result in an uninterruptible wait requiring a reset to recover from. Terminating a transfer is supposed to take effect immediately, but may result in data loss. To make this clear, rename the function to pl08x_terminate_phy_chan(). Also, make sure it is always consistently called - with the spinlock held and IRQs disabled, and ensure that the TC and ERR interrupt status is always cleared. Signed-off-by: Russell King Acked-by: Linus Walleij Signed-off-by: Dan Williams --- drivers/dma/amba-pl08x.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index 297f48b0cba9..8321a3997c95 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c @@ -267,19 +267,24 @@ static void pl08x_resume_phy_chan(struct pl08x_phy_chan *ch) } -/* Stops the channel */ -static void pl08x_stop_phy_chan(struct pl08x_phy_chan *ch) +/* + * pl08x_terminate_phy_chan() stops the channel, clears the FIFO and + * clears any pending interrupt status. This should not be used for + * an on-going transfer, but as a method of shutting down a channel + * (eg, when it's no longer used) or terminating a transfer. + */ +static void pl08x_terminate_phy_chan(struct pl08x_driver_data *pl08x, + struct pl08x_phy_chan *ch) { - u32 val; + u32 val = readl(ch->base + PL080_CH_CONFIG); - pl08x_pause_phy_chan(ch); + val &= ~(PL080_CONFIG_ENABLE | PL080_CONFIG_ERR_IRQ_MASK | + PL080_CONFIG_TC_IRQ_MASK); - /* Disable channel */ - val = readl(ch->base + PL080_CH_CONFIG); - val &= ~PL080_CONFIG_ENABLE; - val &= ~PL080_CONFIG_ERR_IRQ_MASK; - val &= ~PL080_CONFIG_TC_IRQ_MASK; writel(val, ch->base + PL080_CH_CONFIG); + + writel(1 << ch->id, pl08x->base + PL080_ERR_CLEAR); + writel(1 << ch->id, pl08x->base + PL080_TC_CLEAR); } static inline u32 get_bytes_in_cctl(u32 cctl) @@ -404,13 +409,12 @@ static inline void pl08x_put_phy_channel(struct pl08x_driver_data *pl08x, { unsigned long flags; + spin_lock_irqsave(&ch->lock, flags); + /* Stop the channel and clear its interrupts */ - pl08x_stop_phy_chan(ch); - writel((1 << ch->id), pl08x->base + PL080_ERR_CLEAR); - writel((1 << ch->id), pl08x->base + PL080_TC_CLEAR); + pl08x_terminate_phy_chan(pl08x, ch); /* Mark it as free */ - spin_lock_irqsave(&ch->lock, flags); ch->serving = NULL; spin_unlock_irqrestore(&ch->lock, flags); } @@ -1449,7 +1453,7 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, plchan->state = PL08X_CHAN_IDLE; if (plchan->phychan) { - pl08x_stop_phy_chan(plchan->phychan); + pl08x_terminate_phy_chan(pl08x, plchan->phychan); /* * Mark physical channel as free and free any slave -- cgit v1.2.3 From 8179661694595eb3a4f2ff9bb0b73acbb7d2f4a9 Mon Sep 17 00:00:00 2001 From: Russell King - ARM Linux Date: Thu, 27 Jan 2011 12:37:44 +0000 Subject: DMA: PL08x: fix channel pausing to timeout rather than lockup If a transfer is initiated from memory to a peripheral, then data is fetched and the channel is marked busy. This busy status persists until the HALT bit is set and the queued data has been transfered to the peripheral. Waiting indefinitely after setting the HALT bit results in system lockups. Timeout this operation, and print an error when this happens. Signed-off-by: Russell King Acked-by: Linus Walleij Signed-off-by: Dan Williams --- drivers/dma/amba-pl08x.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index 8321a3997c95..07bca4970e50 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c @@ -79,6 +79,7 @@ #include #include #include +#include #include #include #include @@ -235,16 +236,19 @@ static void pl08x_start_txd(struct pl08x_dma_chan *plchan, } /* - * Overall DMAC remains enabled always. + * Pause the channel by setting the HALT bit. * - * Disabling individual channels could lose data. + * For M->P transfers, pause the DMAC first and then stop the peripheral - + * the FIFO can only drain if the peripheral is still requesting data. + * (note: this can still timeout if the DMAC FIFO never drains of data.) * - * Disable the peripheral DMA after disabling the DMAC in order to allow - * the DMAC FIFO to drain, and hence allow the channel to show inactive + * For P->M transfers, disable the peripheral first to stop it filling + * the DMAC FIFO, and then pause the DMAC. */ static void pl08x_pause_phy_chan(struct pl08x_phy_chan *ch) { u32 val; + int timeout; /* Set the HALT bit and wait for the FIFO to drain */ val = readl(ch->base + PL080_CH_CONFIG); @@ -252,8 +256,13 @@ static void pl08x_pause_phy_chan(struct pl08x_phy_chan *ch) writel(val, ch->base + PL080_CH_CONFIG); /* Wait for channel inactive */ - while (pl08x_phy_channel_busy(ch)) - cpu_relax(); + for (timeout = 1000; timeout; timeout--) { + if (!pl08x_phy_channel_busy(ch)) + break; + udelay(1); + } + if (pl08x_phy_channel_busy(ch)) + pr_err("pl08x: channel%u timeout waiting for pause\n", ch->id); } static void pl08x_resume_phy_chan(struct pl08x_phy_chan *ch) -- cgit v1.2.3 From b9b3f82f94b52ebb0bbdf6cd77ccc5e8ee3f53b5 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 12 Jan 2011 12:12:31 +0100 Subject: dmaengine i.MX sdma: set maximum segment size for our device Signed-off-by: Sascha Hauer --- drivers/dma/imx-sdma.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index d5a5d4d9c19b..c50305043f15 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -301,6 +301,7 @@ struct sdma_firmware_header { struct sdma_engine { struct device *dev; + struct device_dma_parameters dma_parms; struct sdma_channel channel[MAX_DMA_CHANNELS]; struct sdma_channel_control *channel_control; void __iomem *regs; @@ -1317,6 +1318,8 @@ static int __init sdma_probe(struct platform_device *pdev) sdma->dma_device.device_prep_dma_cyclic = sdma_prep_dma_cyclic; sdma->dma_device.device_control = sdma_control; sdma->dma_device.device_issue_pending = sdma_issue_pending; + sdma->dma_device.dev->dma_parms = &sdma->dma_parms; + dma_set_max_seg_size(sdma->dma_device.dev, 65535); ret = dma_async_device_register(&sdma->dma_device); if (ret) { -- cgit v1.2.3 From 1fa81c270da4d8dffa84fcca448654a10ed0a5dc Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 12 Jan 2011 13:02:28 +0100 Subject: dmaengine i.MX sdma: check sg entries for valid addresses and lengths This patch lets sdma_prep_slave_sg fail if the entries of an sg list do not start on multiples of the word size or if the lengths are not multiple of the word size. Also, catch the previously unhandled DMA_SLAVE_BUSWIDTH_8_BYTES and DMA_SLAVE_BUSWIDTH_UNDEFINED cases. Signed-off-by: Sascha Hauer --- drivers/dma/imx-sdma.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index c50305043f15..8707723e36da 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -925,10 +925,24 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( ret = -EINVAL; goto err_out; } - if (sdmac->word_size == DMA_SLAVE_BUSWIDTH_4_BYTES) + + switch (sdmac->word_size) { + case DMA_SLAVE_BUSWIDTH_4_BYTES: bd->mode.command = 0; - else - bd->mode.command = sdmac->word_size; + if (count & 3 || sg->dma_address & 3) + return NULL; + break; + case DMA_SLAVE_BUSWIDTH_2_BYTES: + bd->mode.command = 2; + if (count & 1 || sg->dma_address & 1) + return NULL; + break; + case DMA_SLAVE_BUSWIDTH_1_BYTE: + bd->mode.command = 1; + break; + default: + return NULL; + } param = BD_DONE | BD_EXTD | BD_CONT; -- cgit v1.2.3 From 7a0e9b2557902bdca563a5eb1bbac87560bd7d20 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 31 Jan 2011 10:19:53 +0100 Subject: dmaengine i.MX SDMA: do not initialize chan_id field This is bogus as the dmaengine core will overwrite this field. Signed-off-by: Sascha Hauer --- drivers/dma/imx-sdma.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 8707723e36da..3e848ee9a18a 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -1307,7 +1307,6 @@ static int __init sdma_probe(struct platform_device *pdev) dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask); sdmac->chan.device = &sdma->dma_device; - sdmac->chan.chan_id = i; sdmac->channel = i; /* Add the channel to the DMAC list */ -- cgit v1.2.3 From 7214a8b14f63a1603401124bc150e17b145aa476 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 31 Jan 2011 10:21:35 +0100 Subject: dmaengine i.MX SDMA: initialize dma capabilities outside channel loop The capabilities are device specific fields, not channel specific fields. Signed-off-by: Sascha Hauer --- drivers/dma/imx-sdma.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 3e848ee9a18a..eb250681804b 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -1295,6 +1295,9 @@ static int __init sdma_probe(struct platform_device *pdev) sdma->version = pdata->sdma_version; + dma_cap_set(DMA_SLAVE, sdma->dma_device.cap_mask); + dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask); + INIT_LIST_HEAD(&sdma->dma_device.channels); /* Initialize channel parameters */ for (i = 0; i < MAX_DMA_CHANNELS; i++) { @@ -1303,9 +1306,6 @@ static int __init sdma_probe(struct platform_device *pdev) sdmac->sdma = sdma; spin_lock_init(&sdmac->lock); - dma_cap_set(DMA_SLAVE, sdma->dma_device.cap_mask); - dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask); - sdmac->chan.device = &sdma->dma_device; sdmac->channel = i; -- cgit v1.2.3 From 23889c6352ab4a842a30221bb412ff49954b2fb3 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 31 Jan 2011 10:56:58 +0100 Subject: dmaengine i.MX SDMA: reserve channel 0 by not registering it We need channel 0 of the sdma engine for internal purposes. We accomplished this by calling dma_request_channel() in the probe function. This does not work when multiple dma engines are present which is the case when IPU support for i.MX31/35 is compiled in. So instead of registering channel 0 and reserving it afterwards simply do not register it in the first place. With this the dmaengine channel counting does not match sdma channel counting anymore, so we have to use sdma channel counting in the driver. Signed-off-by: Sascha Hauer --- drivers/dma/imx-sdma.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index eb250681804b..1eb3f0077403 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -230,7 +230,7 @@ struct sdma_engine; * struct sdma_channel - housekeeping for a SDMA channel * * @sdma pointer to the SDMA engine for this channel - * @channel the channel number, matches dmaengine chan_id + * @channel the channel number, matches dmaengine chan_id + 1 * @direction transfer type. Needed for setting SDMA script * @peripheral_type Peripheral type. Needed for setting SDMA script * @event_id0 aka dma request line @@ -799,7 +799,7 @@ static dma_cookie_t sdma_tx_submit(struct dma_async_tx_descriptor *tx) cookie = sdma_assign_cookie(sdmac); - sdma_enable_channel(sdma, tx->chan->chan_id); + sdma_enable_channel(sdma, sdmac->channel); spin_unlock_irq(&sdmac->lock); @@ -812,10 +812,6 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan) struct imx_dma_data *data = chan->private; int prio, ret; - /* No need to execute this for internal channel 0 */ - if (chan->chan_id == 0) - return 0; - if (!data) return -EINVAL; @@ -880,7 +876,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( struct sdma_channel *sdmac = to_sdma_chan(chan); struct sdma_engine *sdma = sdmac->sdma; int ret, i, count; - int channel = chan->chan_id; + int channel = sdmac->channel; struct scatterlist *sg; if (sdmac->status == DMA_IN_PROGRESS) @@ -978,7 +974,7 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( struct sdma_channel *sdmac = to_sdma_chan(chan); struct sdma_engine *sdma = sdmac->sdma; int num_periods = buf_len / period_len; - int channel = chan->chan_id; + int channel = sdmac->channel; int ret, i = 0, buf = 0; dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel); @@ -1252,7 +1248,6 @@ static int __init sdma_probe(struct platform_device *pdev) struct resource *iores; struct sdma_platform_data *pdata = pdev->dev.platform_data; int i; - dma_cap_mask_t mask; struct sdma_engine *sdma; sdma = kzalloc(sizeof(*sdma), GFP_KERNEL); @@ -1309,8 +1304,14 @@ static int __init sdma_probe(struct platform_device *pdev) sdmac->chan.device = &sdma->dma_device; sdmac->channel = i; - /* Add the channel to the DMAC list */ - list_add_tail(&sdmac->chan.device_node, &sdma->dma_device.channels); + /* + * Add the channel to the DMAC list. Do not add channel 0 though + * because we need it internally in the SDMA driver. This also means + * that channel 0 in dmaengine counting matches sdma channel 1. + */ + if (i) + list_add_tail(&sdmac->chan.device_node, + &sdma->dma_device.channels); } ret = sdma_init(sdma); @@ -1340,13 +1341,6 @@ static int __init sdma_probe(struct platform_device *pdev) goto err_init; } - /* request channel 0. This is an internal control channel - * to the SDMA engine and not available to clients. - */ - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - dma_request_channel(mask, NULL, NULL); - dev_info(sdma->dev, "initialized\n"); return 0; -- cgit v1.2.3 From 1e070a60997f5bbaadd498c34380e2aa110336cf Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 12 Jan 2011 13:14:37 +0100 Subject: dmaengine i.MX dma: set maximum segment size for our device Signed-off-by: Sascha Hauer --- drivers/dma/imx-dma.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index e53d438142bb..a46e1d9fa3e4 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c @@ -49,6 +49,7 @@ struct imxdma_channel { struct imxdma_engine { struct device *dev; + struct device_dma_parameters dma_parms; struct dma_device dma_device; struct imxdma_channel channel[MAX_DMA_CHANNELS]; }; @@ -370,6 +371,9 @@ static int __init imxdma_probe(struct platform_device *pdev) platform_set_drvdata(pdev, imxdma); + imxdma->dma_device.dev->dma_parms = &imxdma->dma_parms; + dma_set_max_seg_size(imxdma->dma_device.dev, 0xffffff); + ret = dma_async_device_register(&imxdma->dma_device); if (ret) { dev_err(&pdev->dev, "unable to register\n"); -- cgit v1.2.3 From d07102a1bb0e759ce4571df30c62998ef5d8a8d3 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 12 Jan 2011 14:13:23 +0100 Subject: dmaengine i.MX dma: check sg entries for valid addresses and lengths Signed-off-by: Sascha Hauer --- drivers/dma/imx-dma.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index a46e1d9fa3e4..a1eac99a5fa1 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c @@ -243,6 +243,21 @@ static struct dma_async_tx_descriptor *imxdma_prep_slave_sg( else dmamode = DMA_MODE_WRITE; + switch (imxdmac->word_size) { + case DMA_SLAVE_BUSWIDTH_4_BYTES: + if (sgl->length & 3 || sgl->dma_address & 3) + return NULL; + break; + case DMA_SLAVE_BUSWIDTH_2_BYTES: + if (sgl->length & 1 || sgl->dma_address & 1) + return NULL; + break; + case DMA_SLAVE_BUSWIDTH_1_BYTE: + break; + default: + return NULL; + } + ret = imx_dma_setup_sg(imxdmac->imxdma_channel, sgl, sg_len, dma_length, imxdmac->per_address, dmamode); if (ret) -- cgit v1.2.3 From 97a43dfe84119528ec2576129b91d619219ab716 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 31 Jan 2011 11:35:44 +0100 Subject: dmaengine i.MX DMA: do not initialize chan_id field Signed-off-by: Sascha Hauer --- drivers/dma/imx-dma.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index a1eac99a5fa1..82627087b550 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c @@ -366,7 +366,6 @@ static int __init imxdma_probe(struct platform_device *pdev) dma_cap_set(DMA_CYCLIC, imxdma->dma_device.cap_mask); imxdmac->chan.device = &imxdma->dma_device; - imxdmac->chan.chan_id = i; imxdmac->channel = i; /* Add the channel to the DMAC list */ -- cgit v1.2.3 From f8a356ff96a9070156f863e4f7716e2a0eb8c995 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 31 Jan 2011 11:35:59 +0100 Subject: dmaengine i.MX dma: initialize dma capabilities outside channel loop The capabilities are device specific fields, not channel specific fields. Signed-off-by: Sascha Hauer --- drivers/dma/imx-dma.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index 82627087b550..e18eaabe92b9 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c @@ -345,6 +345,9 @@ static int __init imxdma_probe(struct platform_device *pdev) INIT_LIST_HEAD(&imxdma->dma_device.channels); + dma_cap_set(DMA_SLAVE, imxdma->dma_device.cap_mask); + dma_cap_set(DMA_CYCLIC, imxdma->dma_device.cap_mask); + /* Initialize channel parameters */ for (i = 0; i < MAX_DMA_CHANNELS; i++) { struct imxdma_channel *imxdmac = &imxdma->channel[i]; @@ -362,9 +365,6 @@ static int __init imxdma_probe(struct platform_device *pdev) imxdmac->imxdma = imxdma; spin_lock_init(&imxdmac->lock); - dma_cap_set(DMA_SLAVE, imxdma->dma_device.cap_mask); - dma_cap_set(DMA_CYCLIC, imxdma->dma_device.cap_mask); - imxdmac->chan.device = &imxdma->dma_device; imxdmac->channel = i; -- cgit v1.2.3 From 1797c33f0edcdcc9a483c06233a203786666a97f Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 20 Jan 2011 05:50:35 +0800 Subject: dmaengine: imx-sdma: remove IMX_DMA_SG_LOOP handling in sdma_prep_slave_sg() This is a leftover from the time that the driver did not have sdma_prep_dma_cyclic callback and implemented sound dma as a looped sg chain. And it can be removed now. Signed-off-by: Shawn Guo Signed-off-by: Sascha Hauer --- drivers/dma/imx-sdma.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index d5a5d4d9c19b..cf8cc0b8e7f7 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -931,12 +931,6 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( param = BD_DONE | BD_EXTD | BD_CONT; - if (sdmac->flags & IMX_DMA_SG_LOOP) { - param |= BD_INTR; - if (i + 1 == sg_len) - param |= BD_WRAP; - } - if (i + 1 == sg_len) param |= BD_INTR; -- cgit v1.2.3 From 4b2ce9ddb370c4eb573540611c347d78ac4b54a0 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 20 Jan 2011 05:50:36 +0800 Subject: dmaengine: imx-sdma: set sdmac->status to DMA_ERROR in err_out of sdma_prep_slave_sg() sdma_prep_dma_cyclic() sets sdmac->status to DMA_ERROR in err_out, and sdma_prep_slave_sg() needs to do the same. Otherwise, sdmac->status stays at DMA_IN_PROGRESS, which will make the function return immediately next time it gets called. Signed-off-by: Shawn Guo Signed-off-by: Sascha Hauer --- drivers/dma/imx-sdma.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index cf8cc0b8e7f7..6fc04d85be6b 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -947,6 +947,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( return &sdmac->desc; err_out: + sdmac->status = DMA_ERROR; return NULL; } -- cgit v1.2.3 From 8a9659114c7be6f88253618252881ea6fe0588b4 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 20 Jan 2011 05:50:37 +0800 Subject: dmaengine: imx-sdma: return sdmac->status in sdma_tx_status() The sdmac->status was designed to reflect the status of the tx, so simply return it in sdma_tx_status(). Then dma client can call dma_async_is_tx_complete() to know the status of the tx. Signed-off-by: Shawn Guo Signed-off-by: Sascha Hauer --- drivers/dma/imx-sdma.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 6fc04d85be6b..f331ae0f7ec3 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -1061,14 +1061,12 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan, { struct sdma_channel *sdmac = to_sdma_chan(chan); dma_cookie_t last_used; - enum dma_status ret; last_used = chan->cookie; - ret = dma_async_is_complete(cookie, sdmac->last_completed, last_used); dma_set_tx_state(txstate, sdmac->last_completed, last_used, 0); - return ret; + return sdmac->status; } static void sdma_issue_pending(struct dma_chan *chan) -- cgit v1.2.3 From 1e9cebb42de57f1243261939c77ab5b0f9bcf311 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 20 Jan 2011 05:50:38 +0800 Subject: dmaengine: imx-sdma: correct sdmac->status in sdma_handle_channel_loop() sdma_handle_channel_loop() is the handler of cyclic tx. One period success does not really mean the success of the tx. Instead of DMA_SUCCESS, DMA_IN_PROGRESS should be the one to tell. Signed-off-by: Shawn Guo Signed-off-by: Sascha Hauer --- drivers/dma/imx-sdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index f331ae0f7ec3..cf93d1737f1e 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -449,7 +449,7 @@ static void sdma_handle_channel_loop(struct sdma_channel *sdmac) if (bd->mode.status & BD_RROR) sdmac->status = DMA_ERROR; else - sdmac->status = DMA_SUCCESS; + sdmac->status = DMA_IN_PROGRESS; bd->mode.status |= BD_DONE; sdmac->buf_tail++; -- cgit v1.2.3 From 341b9419a8c0a4cdb75773c576870f1eb655516d Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 20 Jan 2011 05:50:39 +0800 Subject: dmaengine: imx-sdma: fix up param for the last BD in sdma_prep_slave_sg() As per the reference manual, bit "L" should be set while bit "C" should be cleared for the last buffer descriptor in the non-cyclic chain, so that sdma can stop trying to find the next BD and end the transfer. In case of sdma_prep_slave_sg(), BD_LAST needs to be set and BD_CONT be cleared for the last BD. Signed-off-by: Shawn Guo Signed-off-by: Sascha Hauer --- drivers/dma/imx-sdma.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index cf93d1737f1e..4535f98b3553 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -931,8 +931,11 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( param = BD_DONE | BD_EXTD | BD_CONT; - if (i + 1 == sg_len) + if (i + 1 == sg_len) { param |= BD_INTR; + param |= BD_LAST; + param &= ~BD_CONT; + } dev_dbg(sdma->dev, "entry %d: count: %d dma: 0x%08x %s%s\n", i, count, sg->dma_address, -- cgit v1.2.3 From b955fba29b2082bba8cb94a959a8ec0a375aec8f Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Mon, 31 Jan 2011 13:25:29 +0530 Subject: ath9k: Fix memory leak due to failed PAPRD frames free the skb's when the Tx of PAPRD frames fails and also add a debug message indicating that. Signed-off-by: Mohammed Shafi Shajakhan Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 568f7be2ec75..9040c2ff1909 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -325,6 +325,8 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int { struct ieee80211_hw *hw = sc->hw; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); struct ath_tx_control txctl; int time_left; @@ -342,8 +344,12 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int init_completion(&sc->paprd_complete); sc->paprd_pending = true; txctl.paprd = BIT(chain); - if (ath_tx_start(hw, skb, &txctl) != 0) + + if (ath_tx_start(hw, skb, &txctl) != 0) { + ath_dbg(common, ATH_DBG_XMIT, "PAPRD TX failed\n"); + dev_kfree_skb_any(skb); return false; + } time_left = wait_for_completion_timeout(&sc->paprd_complete, msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); -- cgit v1.2.3 From d828cd5a95e532636dbc495e4b94b625ab9abdad Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 28 Jan 2011 16:47:49 +0100 Subject: iwl3945: do not use agn specific IWL_RATE_COUNT Only use IWL_RATE_COUNT_3945 in 3945 code. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945.c | 5 ++--- drivers/net/wireless/iwlwifi/iwl-agn-rs.h | 1 + drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 294221b06813..58213e72d107 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -762,8 +762,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, /* We need to figure out how to get the sta->supp_rates while * in this running context */ - rate_mask = IWL_RATES_MASK; - + rate_mask = IWL_RATES_MASK_3945; /* Set retry limit on DATA packets and Probe Responses*/ if (ieee80211_is_probe_resp(fc)) @@ -1650,7 +1649,7 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv) ref_temp); /* set tx power value for all rates, OFDM and CCK */ - for (rate_index = 0; rate_index < IWL_RATE_COUNT; + for (rate_index = 0; rate_index < IWL_RATE_COUNT_3945; rate_index++) { int power_idx = ch_info->power_info[rate_index].base_power_index; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index 75e50d33ecb3..184828c72b31 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h @@ -213,6 +213,7 @@ enum { IWL_CCK_BASIC_RATES_MASK) #define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1) +#define IWL_RATES_MASK_3945 ((1 << IWL_RATE_COUNT_3945) - 1) #define IWL_INVALID_VALUE -1 diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 55837d607534..2945acd955f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2517,7 +2517,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv) ieee80211_wake_queues(priv->hw); - priv->active_rate = IWL_RATES_MASK; + priv->active_rate = IWL_RATES_MASK_3945; iwl_power_update_mode(priv, true); -- cgit v1.2.3 From 69cf36a4523be026bc16743c5c989c5e82edb7d9 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sun, 30 Jan 2011 13:16:03 +0100 Subject: rt2x00: Refactor beacon code to make use of start- and stop_queue This patch allows to dynamically remove beaconing interfaces without shutting beaconing down on all interfaces. The only place to start and stop beaconing are now the start- and stop_queue callbacks. Hence, we can remove some register writes during interface bring up (config_intf) and only write the correct sync mode to the register there. When multiple beaconing interfaces are present we should enable beaconing as soon as mac80211 enables beaconing on at least one of them. The beacon queue gets stopped when the last beaconing interface was stopped by mac80211. Therefore, introduce another interface counter to keep track ot the number of enabled beaconing interfaces and start or stop the beacon queue accordingly. To allow single interfaces to stop beaconing, add a new driver callback clear_beacon to clear a single interface's beacon without affecting the other interfaces. Don't overload the clear_entry callback for clearing beacons as that would introduce additional overhead (check for each TX queue) into the clear_entry callback which is used on the drivers TX/RX hotpaths. Furthermore, the write beacon callback doesn't need to enable beaconing anymore but since beaconing should be disabled while a new beacon is written or cleared we still disable beacon generation and enable it afterwards again in the driver specific callbacks. However, beacon related interrupts should not be disabled/enabled here, that's solely done from the start- and stop queue callbacks. It would be nice to stop the beacon queue just before the beacon update and enable it afterwards in rt2x00queue itself instead of the current implementation that relies on the driver doing the right thing. However, since start- and stop_queue are mutex protected we cannot use them for atomic beacon updates. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 4 -- drivers/net/wireless/rt2x00/rt2500pci.c | 4 -- drivers/net/wireless/rt2x00/rt2500usb.c | 2 - drivers/net/wireless/rt2x00/rt2800lib.c | 67 +++++++++++++++++-------------- drivers/net/wireless/rt2x00/rt2800lib.h | 1 + drivers/net/wireless/rt2x00/rt2800pci.c | 9 +++++ drivers/net/wireless/rt2x00/rt2800usb.c | 1 + drivers/net/wireless/rt2x00/rt2x00.h | 4 ++ drivers/net/wireless/rt2x00/rt2x00dev.c | 4 +- drivers/net/wireless/rt2x00/rt2x00lib.h | 12 ++++-- drivers/net/wireless/rt2x00/rt2x00mac.c | 41 +++++++++++++++++-- drivers/net/wireless/rt2x00/rt2x00queue.c | 38 +++++++++++++----- drivers/net/wireless/rt2x00/rt61pci.c | 41 ++++++++++++------- drivers/net/wireless/rt2x00/rt73usb.c | 42 ++++++++++++------- 14 files changed, 185 insertions(+), 85 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 54ca49ad3472..cb28e1b2f1e2 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -305,9 +305,7 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, * Enable synchronisation. */ rt2x00pci_register_read(rt2x00dev, CSR14, ®); - rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); - rt2x00_set_field32(®, CSR14_TBCN, 1); rt2x00pci_register_write(rt2x00dev, CSR14, reg); } @@ -1183,8 +1181,6 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, /* * Enable beaconing again. */ - rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); - rt2x00_set_field32(®, CSR14_TBCN, 1); rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); rt2x00pci_register_write(rt2x00dev, CSR14, reg); } diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index a9ff26a27724..5225ae1899fe 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -311,9 +311,7 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, * Enable synchronisation. */ rt2x00pci_register_read(rt2x00dev, CSR14, ®); - rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); - rt2x00_set_field32(®, CSR14_TBCN, 1); rt2x00pci_register_write(rt2x00dev, CSR14, reg); } @@ -1337,8 +1335,6 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, /* * Enable beaconing again. */ - rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); - rt2x00_set_field32(®, CSR14_TBCN, 1); rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); rt2x00pci_register_write(rt2x00dev, CSR14, reg); } diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 6b3b1de46792..157516e0aab7 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -478,9 +478,7 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev, rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); - rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, conf->sync); - rt2x00_set_field16(®, TXRX_CSR19_TBCN, 1); rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); } diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index f8ba01cbc6dd..4753fb1b0aaf 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -818,8 +818,6 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) /* * Enable beaconing again. */ - rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); - rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); @@ -831,8 +829,8 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) } EXPORT_SYMBOL_GPL(rt2800_write_beacon); -static inline void rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev, - unsigned int beacon_base) +static inline void rt2800_clear_beacon_register(struct rt2x00_dev *rt2x00dev, + unsigned int beacon_base) { int i; @@ -845,6 +843,33 @@ static inline void rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev, rt2800_register_write(rt2x00dev, beacon_base + i, 0); } +void rt2800_clear_beacon(struct queue_entry *entry) +{ + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + u32 reg; + + /* + * Disable beaconing while we are reloading the beacon data, + * otherwise we might be sending out invalid data. + */ + rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); + rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + + /* + * Clear beacon. + */ + rt2800_clear_beacon_register(rt2x00dev, + HW_BEACON_OFFSET(entry->entry_idx)); + + /* + * Enabled beaconing again. + */ + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); + rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); +} +EXPORT_SYMBOL_GPL(rt2800_clear_beacon); + #ifdef CONFIG_RT2X00_LIB_DEBUGFS const struct rt2x00debug rt2800_rt2x00debug = { .owner = THIS_MODULE, @@ -1154,30 +1179,12 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, bool update_bssid = false; if (flags & CONFIG_UPDATE_TYPE) { - /* - * Clear current synchronisation setup. - */ - rt2800_clear_beacon(rt2x00dev, - HW_BEACON_OFFSET(intf->beacon->entry_idx)); /* * Enable synchronisation. */ rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); - rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); rt2x00_set_field32(®, BCN_TIME_CFG_TSF_SYNC, conf->sync); - rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, - (conf->sync == TSF_SYNC_ADHOC || - conf->sync == TSF_SYNC_AP_NONE)); rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); - - /* - * Enable pre tbtt interrupt for beaconing modes - */ - rt2800_register_read(rt2x00dev, INT_TIMER_EN, ®); - rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, - (conf->sync == TSF_SYNC_AP_NONE)); - rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg); - } if (flags & CONFIG_UPDATE_MAC) { @@ -2187,14 +2194,14 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) /* * Clear all beacons */ - rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE0); - rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE1); - rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE2); - rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE3); - rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE4); - rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE5); - rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE6); - rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE7); + rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE0); + rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE1); + rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE2); + rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE3); + rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE4); + rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE5); + rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE6); + rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE7); if (rt2x00_is_usb(rt2x00dev)) { rt2800_register_read(rt2x00dev, US_CYC_CNT, ®); diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index 3efafb78ff77..0c92d86a36f4 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h @@ -156,6 +156,7 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev); void rt2800_txdone_entry(struct queue_entry *entry, u32 status); void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); +void rt2800_clear_beacon(struct queue_entry *entry); extern const struct rt2x00debug rt2800_rt2x00debug; diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index bfc2fc5c1c22..54e37e08c114 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -205,6 +205,10 @@ static void rt2800pci_start_queue(struct data_queue *queue) rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + + rt2800_register_read(rt2x00dev, INT_TIMER_EN, ®); + rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 1); + rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg); break; default: break; @@ -250,6 +254,10 @@ static void rt2800pci_stop_queue(struct data_queue *queue) rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + + rt2800_register_read(rt2x00dev, INT_TIMER_EN, ®); + rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 0); + rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg); break; default: break; @@ -974,6 +982,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { .write_tx_desc = rt2800pci_write_tx_desc, .write_tx_data = rt2800_write_tx_data, .write_beacon = rt2800_write_beacon, + .clear_beacon = rt2800_clear_beacon, .fill_rxdone = rt2800pci_fill_rxdone, .config_shared_key = rt2800_config_shared_key, .config_pairwise_key = rt2800_config_pairwise_key, diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index b97a4a54ff4c..3ebe473f8551 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -633,6 +633,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { .write_tx_desc = rt2800usb_write_tx_desc, .write_tx_data = rt2800usb_write_tx_data, .write_beacon = rt2800_write_beacon, + .clear_beacon = rt2800_clear_beacon, .get_tx_data_len = rt2800usb_get_tx_data_len, .fill_rxdone = rt2800usb_fill_rxdone, .config_shared_key = rt2800_config_shared_key, diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 84aaf393da43..985982bb65e2 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -368,6 +368,7 @@ struct rt2x00_intf { * dedicated beacon entry. */ struct queue_entry *beacon; + bool enable_beacon; /* * Actions that needed rescheduling. @@ -573,6 +574,7 @@ struct rt2x00lib_ops { struct txentry_desc *txdesc); void (*write_beacon) (struct queue_entry *entry, struct txentry_desc *txdesc); + void (*clear_beacon) (struct queue_entry *entry); int (*get_tx_data_len) (struct queue_entry *entry); /* @@ -788,10 +790,12 @@ struct rt2x00_dev { * - Open ap interface count. * - Open sta interface count. * - Association count. + * - Beaconing enabled count. */ unsigned int intf_ap_count; unsigned int intf_sta_count; unsigned int intf_associated; + unsigned int intf_beaconing; /* * Link quality diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 31b7db05abd9..2c6503878059 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -121,7 +121,7 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, return; if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags)) - rt2x00queue_update_beacon(rt2x00dev, vif, true); + rt2x00queue_update_beacon(rt2x00dev, vif); } static void rt2x00lib_intf_scheduled(struct work_struct *work) @@ -174,7 +174,7 @@ static void rt2x00lib_beaconupdate_iter(void *data, u8 *mac, vif->type != NL80211_IFTYPE_WDS) return; - rt2x00queue_update_beacon(rt2x00dev, vif, true); + rt2x00queue_update_beacon(rt2x00dev, vif); } void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index a105c500627b..6c6a8f15870e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -160,11 +160,17 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, * rt2x00queue_update_beacon - Send new beacon from mac80211 to hardware * @rt2x00dev: Pointer to &struct rt2x00_dev. * @vif: Interface for which the beacon should be updated. - * @enable_beacon: Enable beaconing */ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, - struct ieee80211_vif *vif, - const bool enable_beacon); + struct ieee80211_vif *vif); + +/** + * rt2x00queue_clear_beacon - Clear beacon in hardware + * @rt2x00dev: Pointer to &struct rt2x00_dev. + * @vif: Interface for which the beacon should be updated. + */ +int rt2x00queue_clear_beacon(struct rt2x00_dev *rt2x00dev, + struct ieee80211_vif *vif); /** * rt2x00queue_index_inc - Index incrementation function diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index f3da051df39e..7d3316724bb4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -619,9 +619,44 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, /* * Update the beacon. */ - if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) - rt2x00queue_update_beacon(rt2x00dev, vif, - bss_conf->enable_beacon); + if (changes & BSS_CHANGED_BEACON) + rt2x00queue_update_beacon(rt2x00dev, vif); + + /* + * Start/stop beaconing. + */ + if (changes & BSS_CHANGED_BEACON_ENABLED) { + if (!bss_conf->enable_beacon && intf->enable_beacon) { + rt2x00queue_clear_beacon(rt2x00dev, vif); + rt2x00dev->intf_beaconing--; + intf->enable_beacon = false; + + if (rt2x00dev->intf_beaconing == 0) { + /* + * Last beaconing interface disabled + * -> stop beacon queue. + */ + mutex_lock(&intf->beacon_skb_mutex); + rt2x00queue_stop_queue(rt2x00dev->bcn); + mutex_unlock(&intf->beacon_skb_mutex); + } + + + } else if (bss_conf->enable_beacon && !intf->enable_beacon) { + rt2x00dev->intf_beaconing++; + intf->enable_beacon = true; + + if (rt2x00dev->intf_beaconing == 1) { + /* + * First beaconing interface enabled + * -> start beacon queue. + */ + mutex_lock(&intf->beacon_skb_mutex); + rt2x00queue_start_queue(rt2x00dev->bcn); + mutex_unlock(&intf->beacon_skb_mutex); + } + } + } /* * When the association status has changed we must reset the link diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index ca82b3a91697..24bcdb47a465 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -566,9 +566,35 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, return 0; } +int rt2x00queue_clear_beacon(struct rt2x00_dev *rt2x00dev, + struct ieee80211_vif *vif) +{ + struct rt2x00_intf *intf = vif_to_intf(vif); + + if (unlikely(!intf->beacon)) + return -ENOBUFS; + + mutex_lock(&intf->beacon_skb_mutex); + + /* + * Clean up the beacon skb. + */ + rt2x00queue_free_skb(intf->beacon); + + /* + * Clear beacon (single bssid devices don't need to clear the beacon + * since the beacon queue will get stopped anyway). + */ + if (rt2x00dev->ops->lib->clear_beacon) + rt2x00dev->ops->lib->clear_beacon(intf->beacon); + + mutex_unlock(&intf->beacon_skb_mutex); + + return 0; +} + int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, - struct ieee80211_vif *vif, - const bool enable_beacon) + struct ieee80211_vif *vif) { struct rt2x00_intf *intf = vif_to_intf(vif); struct skb_frame_desc *skbdesc; @@ -584,12 +610,6 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, */ rt2x00queue_free_skb(intf->beacon); - if (!enable_beacon) { - rt2x00queue_stop_queue(intf->beacon->queue); - mutex_unlock(&intf->beacon_skb_mutex); - return 0; - } - intf->beacon->skb = ieee80211_beacon_get(rt2x00dev->hw, vif); if (!intf->beacon->skb) { mutex_unlock(&intf->beacon_skb_mutex); @@ -611,7 +631,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, skbdesc->entry = intf->beacon; /* - * Send beacon to hardware and enable beacon genaration.. + * Send beacon to hardware. */ rt2x00dev->ops->lib->write_beacon(intf->beacon, &txdesc); diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 8de44dd401e0..f14cc452eb0c 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -551,26 +551,14 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00intf_conf *conf, const unsigned int flags) { - unsigned int beacon_base; u32 reg; if (flags & CONFIG_UPDATE_TYPE) { - /* - * Clear current synchronisation setup. - * For the Beacon base registers, we only need to clear - * the first byte since that byte contains the VALID and OWNER - * bits which (when set to 0) will invalidate the entire beacon. - */ - beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); - rt2x00pci_register_write(rt2x00dev, beacon_base, 0); - /* * Enable synchronisation. */ rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); - rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); - rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); } @@ -2002,8 +1990,6 @@ static void rt61pci_write_beacon(struct queue_entry *entry, */ rt2x00pci_register_write(rt2x00dev, TXRX_CSR10, 0x00001008); - rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); - rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); @@ -2014,6 +2000,32 @@ static void rt61pci_write_beacon(struct queue_entry *entry, entry->skb = NULL; } +static void rt61pci_clear_beacon(struct queue_entry *entry) +{ + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + u32 reg; + + /* + * Disable beaconing while we are reloading the beacon data, + * otherwise we might be sending out invalid data. + */ + rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); + rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); + rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); + + /* + * Clear beacon. + */ + rt2x00pci_register_write(rt2x00dev, + HW_BEACON_OFFSET(entry->entry_idx), 0); + + /* + * Enable beaconing again. + */ + rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); + rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); +} + /* * RX control handlers */ @@ -2903,6 +2915,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { .stop_queue = rt61pci_stop_queue, .write_tx_desc = rt61pci_write_tx_desc, .write_beacon = rt61pci_write_beacon, + .clear_beacon = rt61pci_clear_beacon, .fill_rxdone = rt61pci_fill_rxdone, .config_shared_key = rt61pci_config_shared_key, .config_pairwise_key = rt61pci_config_pairwise_key, diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 029be3c6c030..330353ec5c96 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -502,26 +502,14 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00intf_conf *conf, const unsigned int flags) { - unsigned int beacon_base; u32 reg; if (flags & CONFIG_UPDATE_TYPE) { - /* - * Clear current synchronisation setup. - * For the Beacon base registers we only need to clear - * the first byte since that byte contains the VALID and OWNER - * bits which (when set to 0) will invalidate the entire beacon. - */ - beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); - rt2x00usb_register_write(rt2x00dev, beacon_base, 0); - /* * Enable synchronisation. */ rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); - rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); - rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); } @@ -1590,8 +1578,6 @@ static void rt73usb_write_beacon(struct queue_entry *entry, */ rt2x00usb_register_write(rt2x00dev, TXRX_CSR10, 0x00001008); - rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); - rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); @@ -1602,6 +1588,33 @@ static void rt73usb_write_beacon(struct queue_entry *entry, entry->skb = NULL; } +static void rt73usb_clear_beacon(struct queue_entry *entry) +{ + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + unsigned int beacon_base; + u32 reg; + + /* + * Disable beaconing while we are reloading the beacon data, + * otherwise we might be sending out invalid data. + */ + rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); + rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); + rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); + + /* + * Clear beacon. + */ + beacon_base = HW_BEACON_OFFSET(entry->entry_idx); + rt2x00usb_register_write(rt2x00dev, beacon_base, 0); + + /* + * Enable beaconing again. + */ + rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); + rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); +} + static int rt73usb_get_tx_data_len(struct queue_entry *entry) { int length; @@ -2313,6 +2326,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { .flush_queue = rt2x00usb_flush_queue, .write_tx_desc = rt73usb_write_tx_desc, .write_beacon = rt73usb_write_beacon, + .clear_beacon = rt73usb_clear_beacon, .get_tx_data_len = rt73usb_get_tx_data_len, .fill_rxdone = rt73usb_fill_rxdone, .config_shared_key = rt73usb_config_shared_key, -- cgit v1.2.3 From 8414ff07ac8802e282683812514ef5b0ea133cb8 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sun, 30 Jan 2011 13:16:28 +0100 Subject: rt2x00: Introduce beacon_update_locked that requires caller locking Introduce a beacon_update_locked function that does not acquire the according beacon mutex to allow beacon updates from atomic context. The caller has to take care of synchronization. No functional changes. Just preparation for beacon updates from tasklet context. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00lib.h | 12 +++++++++++- drivers/net/wireless/rt2x00/rt2x00queue.c | 24 ++++++++++++++++-------- 2 files changed, 27 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 6c6a8f15870e..2d94cbaf5f4a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -157,13 +157,23 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, bool local); /** - * rt2x00queue_update_beacon - Send new beacon from mac80211 to hardware + * rt2x00queue_update_beacon - Send new beacon from mac80211 + * to hardware. Handles locking by itself (mutex). * @rt2x00dev: Pointer to &struct rt2x00_dev. * @vif: Interface for which the beacon should be updated. */ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, struct ieee80211_vif *vif); +/** + * rt2x00queue_update_beacon_locked - Send new beacon from mac80211 + * to hardware. Caller needs to ensure locking. + * @rt2x00dev: Pointer to &struct rt2x00_dev. + * @vif: Interface for which the beacon should be updated. + */ +int rt2x00queue_update_beacon_locked(struct rt2x00_dev *rt2x00dev, + struct ieee80211_vif *vif); + /** * rt2x00queue_clear_beacon - Clear beacon in hardware * @rt2x00dev: Pointer to &struct rt2x00_dev. diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 24bcdb47a465..7d7fbe0315af 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -593,8 +593,8 @@ int rt2x00queue_clear_beacon(struct rt2x00_dev *rt2x00dev, return 0; } -int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, - struct ieee80211_vif *vif) +int rt2x00queue_update_beacon_locked(struct rt2x00_dev *rt2x00dev, + struct ieee80211_vif *vif) { struct rt2x00_intf *intf = vif_to_intf(vif); struct skb_frame_desc *skbdesc; @@ -603,18 +603,14 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, if (unlikely(!intf->beacon)) return -ENOBUFS; - mutex_lock(&intf->beacon_skb_mutex); - /* * Clean up the beacon skb. */ rt2x00queue_free_skb(intf->beacon); intf->beacon->skb = ieee80211_beacon_get(rt2x00dev->hw, vif); - if (!intf->beacon->skb) { - mutex_unlock(&intf->beacon_skb_mutex); + if (!intf->beacon->skb) return -ENOMEM; - } /* * Copy all TX descriptor information into txdesc, @@ -635,9 +631,21 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, */ rt2x00dev->ops->lib->write_beacon(intf->beacon, &txdesc); + return 0; + +} + +int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, + struct ieee80211_vif *vif) +{ + struct rt2x00_intf *intf = vif_to_intf(vif); + int ret; + + mutex_lock(&intf->beacon_skb_mutex); + ret = rt2x00queue_update_beacon_locked(rt2x00dev, vif); mutex_unlock(&intf->beacon_skb_mutex); - return 0; + return ret; } void rt2x00queue_for_each_entry(struct data_queue *queue, -- cgit v1.2.3 From 1dae8d342e842cb9971f44d7b68580c7b9f26174 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sun, 30 Jan 2011 13:16:52 +0100 Subject: rt2x00: Limit beacon updates in bss_info_changed to USB devices Currently there are two places that trigger a beacon update on PCI devices. The bss_info_changed callback and the periodic update triggered by the TBTT or PRETBTT interrupt. Since the next TBTT or PRETBTT interrupt will periodically fetch an updated beacon remove the update_beacon call in the bss_info_changed callback for PCI devices. In the worst case it will take one beacon interval longer to fetch the new beacon then before. For devices that have a PRETBTT interrupt there should be no change at all. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00mac.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 7d3316724bb4..6a66021d8f65 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -617,9 +617,10 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, bss_conf->bssid); /* - * Update the beacon. + * Update the beacon. This is only required on USB devices. PCI + * devices fetch beacons periodically. */ - if (changes & BSS_CHANGED_BEACON) + if (changes & BSS_CHANGED_BEACON && rt2x00_is_usb(rt2x00dev)) rt2x00queue_update_beacon(rt2x00dev, vif); /* -- cgit v1.2.3 From 8d59c4e993427df37fb8bfc3470c298194a68e7a Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sun, 30 Jan 2011 13:17:29 +0100 Subject: rt2x00: Make periodic beacon updates for PCI devices atomic Allow the beacondone and pretbtt functions to update the beacon from atomic context by using the beacon update functions with caller locking. This is a preparation for moving the periodic beacon handling into tasklets that require atomic context. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 2c6503878059..50b379a6c9ee 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -174,7 +174,13 @@ static void rt2x00lib_beaconupdate_iter(void *data, u8 *mac, vif->type != NL80211_IFTYPE_WDS) return; - rt2x00queue_update_beacon(rt2x00dev, vif); + /* + * Update the beacon without locking. This is safe on PCI devices + * as they only update the beacon periodically here. This should + * never be called for USB devices. + */ + WARN_ON(rt2x00_is_usb(rt2x00dev)); + rt2x00queue_update_beacon_locked(rt2x00dev, vif); } void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) @@ -183,9 +189,9 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) return; /* send buffered bc/mc frames out for every bssid */ - ieee80211_iterate_active_interfaces(rt2x00dev->hw, - rt2x00lib_bc_buffer_iter, - rt2x00dev); + ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, + rt2x00lib_bc_buffer_iter, + rt2x00dev); /* * Devices with pre tbtt interrupt don't need to update the beacon * here as they will fetch the next beacon directly prior to @@ -195,9 +201,9 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) return; /* fetch next beacon */ - ieee80211_iterate_active_interfaces(rt2x00dev->hw, - rt2x00lib_beaconupdate_iter, - rt2x00dev); + ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, + rt2x00lib_beaconupdate_iter, + rt2x00dev); } EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); @@ -207,9 +213,9 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev) return; /* fetch next beacon */ - ieee80211_iterate_active_interfaces(rt2x00dev->hw, - rt2x00lib_beaconupdate_iter, - rt2x00dev); + ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, + rt2x00lib_beaconupdate_iter, + rt2x00dev); } EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); -- cgit v1.2.3 From c5c65761839e3d85cc620cc1c85db8d4a7173f53 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sun, 30 Jan 2011 13:17:52 +0100 Subject: rt2x00: Introduce tasklets for interrupt handling No functional changes, just preparation for moving interrupt handling to tasklets. The tasklets are disabled by default. Drivers making use of them need to enable the tasklets when the device state is set to IRQ_ON. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 13 +++++++++++++ drivers/net/wireless/rt2x00/rt2x00dev.c | 21 +++++++++++++++++++++ 2 files changed, 34 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 985982bb65e2..696513113d9f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -520,6 +520,10 @@ struct rt2x00lib_ops { * TX status tasklet handler. */ void (*txstatus_tasklet) (unsigned long data); + void (*pretbtt_tasklet) (unsigned long data); + void (*tbtt_tasklet) (unsigned long data); + void (*rxdone_tasklet) (unsigned long data); + void (*autowake_tasklet) (unsigned long data); /* * Device init handlers. @@ -905,6 +909,15 @@ struct rt2x00_dev { * Tasklet for processing tx status reports (rt2800pci). */ struct tasklet_struct txstatus_tasklet; + struct tasklet_struct pretbtt_tasklet; + struct tasklet_struct tbtt_tasklet; + struct tasklet_struct rxdone_tasklet; + struct tasklet_struct autowake_tasklet; + + /* + * Protect the interrupt mask register. + */ + spinlock_t irqmask_lock; }; /* diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 50b379a6c9ee..7d4dece64c1a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -830,6 +830,26 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) } + /* + * Initialize tasklets if used by the driver. Tasklets are + * disabled until the interrupts are turned on. The driver + * has to handle that. + */ +#define RT2X00_TASKLET_INIT(taskletname) \ + if (rt2x00dev->ops->lib->taskletname) { \ + tasklet_init(&rt2x00dev->taskletname, \ + rt2x00dev->ops->lib->taskletname, \ + (unsigned long)rt2x00dev); \ + tasklet_disable(&rt2x00dev->taskletname); \ + } + + RT2X00_TASKLET_INIT(pretbtt_tasklet); + RT2X00_TASKLET_INIT(tbtt_tasklet); + RT2X00_TASKLET_INIT(rxdone_tasklet); + RT2X00_TASKLET_INIT(autowake_tasklet); + +#undef RT2X00_TASKLET_INIT + /* * Register HW. */ @@ -958,6 +978,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) { int retval = -ENOMEM; + spin_lock_init(&rt2x00dev->irqmask_lock); mutex_init(&rt2x00dev->csr_mutex); set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); -- cgit v1.2.3 From c8e15a1e2c93880160f31ed2e6b02c1322f7f48d Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sun, 30 Jan 2011 13:18:13 +0100 Subject: rt2x00: Disable txstatus tasklet by default Enable the txstatus tasklet when interrupts are enabled and disable it together with the interrupts. Also make the txstatus tasklet useful even without the tx status FIFO and make use of the generic rt2x00 tasklet initialization macro. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 5 ++++- drivers/net/wireless/rt2x00/rt2x00dev.c | 8 +------- 2 files changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 54e37e08c114..e4d97ad25bf4 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -416,7 +416,10 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, if (state == STATE_RADIO_IRQ_ON) { rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, ®); rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, reg); - } + + tasklet_enable(&rt2x00dev->txstatus_tasklet); + } else if (state == STATE_RADIO_IRQ_OFF) + tasklet_disable(&rt2x00dev->txstatus_tasklet); rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); rt2x00_set_field32(®, INT_MASK_CSR_RXDELAYINT, 0); diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 7d4dece64c1a..5812a4e05c7f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -821,13 +821,6 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) GFP_KERNEL); if (status) return status; - - /* tasklet for processing the tx status reports. */ - if (rt2x00dev->ops->lib->txstatus_tasklet) - tasklet_init(&rt2x00dev->txstatus_tasklet, - rt2x00dev->ops->lib->txstatus_tasklet, - (unsigned long)rt2x00dev); - } /* @@ -843,6 +836,7 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) tasklet_disable(&rt2x00dev->taskletname); \ } + RT2X00_TASKLET_INIT(txstatus_tasklet); RT2X00_TASKLET_INIT(pretbtt_tasklet); RT2X00_TASKLET_INIT(tbtt_tasklet); RT2X00_TASKLET_INIT(rxdone_tasklet); -- cgit v1.2.3 From a9d61e9e779579c66c0d4c8af203d51dbca1473c Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sun, 30 Jan 2011 13:18:38 +0100 Subject: rt2x00: Convert rt2800pci to use tasklets Fix interrupt processing on slow machines by using individual tasklets for each different device interrupt. This ensures that while a RX or TX status tasklet is scheduled only the according device interrupt is masked and other interrupts such as TBTT can still be processed. Also, this allows us to use tasklet_hi_schedule for TBTT and PRETBTT processing which is required to not send out beacons with a wrong DTIM count (due to delayed periodic beacon updates). Furthermore, this improves the latency between the TBTT and sending out buffered multi- and broadcast traffic. As a nice bonus, the interrupt handling overhead is reduced such that rt2800pci gains around 25% more throuhput on a rt3052 MIPS board. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 173 +++++++++++++++++++++----------- 1 file changed, 114 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index e4d97ad25bf4..31483c79a457 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -200,6 +200,13 @@ static void rt2800pci_start_queue(struct data_queue *queue) rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); break; case QID_BEACON: + /* + * Allow beacon tasklets to be scheduled for periodic + * beacon updates. + */ + tasklet_enable(&rt2x00dev->tbtt_tasklet); + tasklet_enable(&rt2x00dev->pretbtt_tasklet); + rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); @@ -258,6 +265,12 @@ static void rt2800pci_stop_queue(struct data_queue *queue) rt2800_register_read(rt2x00dev, INT_TIMER_EN, ®); rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 0); rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg); + + /* + * Wait for tbtt tasklets to finish. + */ + tasklet_disable(&rt2x00dev->tbtt_tasklet); + tasklet_disable(&rt2x00dev->pretbtt_tasklet); break; default: break; @@ -408,6 +421,7 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, int mask = (state == STATE_RADIO_IRQ_ON) || (state == STATE_RADIO_IRQ_ON_ISR); u32 reg; + unsigned long flags; /* * When interrupts are being enabled, the interrupt registers @@ -417,10 +431,16 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, ®); rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, reg); + /* + * Enable tasklets. The beacon related tasklets are + * enabled when the beacon queue is started. + */ tasklet_enable(&rt2x00dev->txstatus_tasklet); - } else if (state == STATE_RADIO_IRQ_OFF) - tasklet_disable(&rt2x00dev->txstatus_tasklet); + tasklet_enable(&rt2x00dev->rxdone_tasklet); + tasklet_enable(&rt2x00dev->autowake_tasklet); + } + spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); rt2x00_set_field32(®, INT_MASK_CSR_RXDELAYINT, 0); rt2x00_set_field32(®, INT_MASK_CSR_TXDELAYINT, 0); @@ -441,6 +461,17 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, INT_MASK_CSR_RX_COHERENT, 0); rt2x00_set_field32(®, INT_MASK_CSR_TX_COHERENT, 0); rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); + spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + + if (state == STATE_RADIO_IRQ_OFF) { + /* + * Ensure that all tasklets are finished before + * disabling the interrupts. + */ + tasklet_disable(&rt2x00dev->txstatus_tasklet); + tasklet_disable(&rt2x00dev->rxdone_tasklet); + tasklet_disable(&rt2x00dev->autowake_tasklet); + } } static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) @@ -721,45 +752,60 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) } } -static void rt2800pci_txstatus_tasklet(unsigned long data) -{ - rt2800pci_txdone((struct rt2x00_dev *)data); -} - -static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance) +static void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, + struct rt2x00_field32 irq_field) { - struct rt2x00_dev *rt2x00dev = dev_instance; - u32 reg = rt2x00dev->irqvalue[0]; + unsigned long flags; + u32 reg; /* - * 1 - Pre TBTT interrupt. + * Enable a single interrupt. The interrupt mask register + * access needs locking. */ - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT)) - rt2x00lib_pretbtt(rt2x00dev); + spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); + rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); + rt2x00_set_field32(®, irq_field, 1); + rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); + spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); +} - /* - * 2 - Beacondone interrupt. - */ - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TBTT)) - rt2x00lib_beacondone(rt2x00dev); +static void rt2800pci_txstatus_tasklet(unsigned long data) +{ + rt2800pci_txdone((struct rt2x00_dev *)data); /* - * 3 - Rx ring done interrupt. + * No need to enable the tx status interrupt here as we always + * leave it enabled to minimize the possibility of a tx status + * register overflow. See comment in interrupt handler. */ - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_RX_DONE)) - rt2x00pci_rxdone(rt2x00dev); +} - /* - * 4 - Auto wakeup interrupt. - */ - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) - rt2800pci_wakeup(rt2x00dev); +static void rt2800pci_pretbtt_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + rt2x00lib_pretbtt(rt2x00dev); + rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_PRE_TBTT); +} - /* Enable interrupts again. */ - rt2x00dev->ops->lib->set_device_state(rt2x00dev, - STATE_RADIO_IRQ_ON_ISR); +static void rt2800pci_tbtt_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + rt2x00lib_beacondone(rt2x00dev); + rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_TBTT); +} - return IRQ_HANDLED; +static void rt2800pci_rxdone_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + rt2x00pci_rxdone(rt2x00dev); + rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RX_DONE); +} + +static void rt2800pci_autowake_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + rt2800pci_wakeup(rt2x00dev); + rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_AUTO_WAKEUP); } static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) @@ -805,8 +851,8 @@ static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) { struct rt2x00_dev *rt2x00dev = dev_instance; - u32 reg; - irqreturn_t ret = IRQ_HANDLED; + u32 reg, mask; + unsigned long flags; /* Read status and ACK all interrupts */ rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, ®); @@ -818,38 +864,44 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) return IRQ_HANDLED; - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) - rt2800pci_txstatus_interrupt(rt2x00dev); + /* + * Since INT_MASK_CSR and INT_SOURCE_CSR use the same bits + * for interrupts and interrupt masks we can just use the value of + * INT_SOURCE_CSR to create the interrupt mask. + */ + mask = ~reg; - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT) || - rt2x00_get_field32(reg, INT_SOURCE_CSR_TBTT) || - rt2x00_get_field32(reg, INT_SOURCE_CSR_RX_DONE) || - rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) { + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) { + rt2800pci_txstatus_interrupt(rt2x00dev); /* - * All other interrupts are handled in the interrupt thread. - * Store irqvalue for use in the interrupt thread. + * Never disable the TX_FIFO_STATUS interrupt. */ - rt2x00dev->irqvalue[0] = reg; + rt2x00_set_field32(&mask, INT_MASK_CSR_TX_FIFO_STATUS, 1); + } - /* - * Disable interrupts, will be enabled again in the - * interrupt thread. - */ - rt2x00dev->ops->lib->set_device_state(rt2x00dev, - STATE_RADIO_IRQ_OFF_ISR); + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT)) + tasklet_hi_schedule(&rt2x00dev->pretbtt_tasklet); - /* - * Leave the TX_FIFO_STATUS interrupt enabled to not lose any - * tx status reports. - */ - rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); - rt2x00_set_field32(®, INT_MASK_CSR_TX_FIFO_STATUS, 1); - rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TBTT)) + tasklet_hi_schedule(&rt2x00dev->tbtt_tasklet); - ret = IRQ_WAKE_THREAD; - } + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_RX_DONE)) + tasklet_schedule(&rt2x00dev->rxdone_tasklet); - return ret; + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) + tasklet_schedule(&rt2x00dev->autowake_tasklet); + + /* + * Disable all interrupts for which a tasklet was scheduled right now, + * the tasklet will reenable the appropriate interrupts. + */ + spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); + rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); + reg &= mask; + rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); + spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + + return IRQ_HANDLED; } /* @@ -964,8 +1016,11 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = { static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { .irq_handler = rt2800pci_interrupt, - .irq_handler_thread = rt2800pci_interrupt_thread, - .txstatus_tasklet = rt2800pci_txstatus_tasklet, + .txstatus_tasklet = rt2800pci_txstatus_tasklet, + .pretbtt_tasklet = rt2800pci_pretbtt_tasklet, + .tbtt_tasklet = rt2800pci_tbtt_tasklet, + .rxdone_tasklet = rt2800pci_rxdone_tasklet, + .autowake_tasklet = rt2800pci_autowake_tasklet, .probe_hw = rt2800pci_probe_hw, .get_firmware_name = rt2800pci_get_firmware_name, .check_firmware = rt2800_check_firmware, -- cgit v1.2.3 From 5846a550b5838ea7fe8e280caff159a5ddb5c7e1 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sun, 30 Jan 2011 13:19:08 +0100 Subject: rt2x00: Convert rt61pci to use tasklets Fix interrupt processing on slow machines by using individual tasklets for each different device interrupt. This ensures that while a RX or TX status tasklet is scheduled only the according device interrupt is masked and other interrupts such as TBTT can still be processed. Also, this allows us to use tasklet_hi_schedule for TBTT processing which is required to not send out beacons with a wrong DTIM count (due to delayed periodic beacon updates). Furthermore, this improves the latency between the TBTT and sending out buffered multi- and broadcast traffic. As a nice bonus, the interrupt handling overhead should be much lower. Compile-tested only. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt61pci.c | 175 +++++++++++++++++++++++++--------- 1 file changed, 130 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index f14cc452eb0c..351055d4b89b 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1142,6 +1142,11 @@ static void rt61pci_start_queue(struct data_queue *queue) rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); break; case QID_BEACON: + /* + * Allow the tbtt tasklet to be scheduled. + */ + tasklet_enable(&rt2x00dev->tbtt_tasklet); + rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); @@ -1221,6 +1226,11 @@ static void rt61pci_stop_queue(struct data_queue *queue) rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); + + /* + * Wait for possibly running tbtt tasklets. + */ + tasklet_disable(&rt2x00dev->tbtt_tasklet); break; default: break; @@ -1710,6 +1720,7 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, int mask = (state == STATE_RADIO_IRQ_OFF) || (state == STATE_RADIO_IRQ_OFF_ISR); u32 reg; + unsigned long flags; /* * When interrupts are being enabled, the interrupt registers @@ -1721,12 +1732,21 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, ®); rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg); + + /* + * Enable tasklets. + */ + tasklet_enable(&rt2x00dev->txstatus_tasklet); + tasklet_enable(&rt2x00dev->rxdone_tasklet); + tasklet_enable(&rt2x00dev->autowake_tasklet); } /* * Only toggle the interrupts bits we are going to use. * Non-checked interrupt bits are disabled by default. */ + spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); + rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); rt2x00_set_field32(®, INT_MASK_CSR_TXDONE, mask); rt2x00_set_field32(®, INT_MASK_CSR_RXDONE, mask); @@ -1746,6 +1766,17 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, MCU_INT_MASK_CSR_7, mask); rt2x00_set_field32(®, MCU_INT_MASK_CSR_TWAKEUP, mask); rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); + + spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + + if (state == STATE_RADIO_IRQ_OFF) { + /* + * Ensure that all tasklets are finished. + */ + tasklet_disable(&rt2x00dev->txstatus_tasklet); + tasklet_disable(&rt2x00dev->rxdone_tasklet); + tasklet_disable(&rt2x00dev->autowake_tasklet); + } } static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev) @@ -2223,61 +2254,80 @@ static void rt61pci_wakeup(struct rt2x00_dev *rt2x00dev) rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); } -static irqreturn_t rt61pci_interrupt_thread(int irq, void *dev_instance) +static void rt61pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, + struct rt2x00_field32 irq_field) { - struct rt2x00_dev *rt2x00dev = dev_instance; - u32 reg = rt2x00dev->irqvalue[0]; - u32 reg_mcu = rt2x00dev->irqvalue[1]; + unsigned long flags; + u32 reg; /* - * Handle interrupts, walk through all bits - * and run the tasks, the bits are checked in order of - * priority. + * Enable a single interrupt. The interrupt mask register + * access needs locking. */ + spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); - /* - * 1 - Rx ring done interrupt. - */ - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_RXDONE)) - rt2x00pci_rxdone(rt2x00dev); + rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); + rt2x00_set_field32(®, irq_field, 0); + rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); - /* - * 2 - Tx ring done interrupt. - */ - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TXDONE)) - rt61pci_txdone(rt2x00dev); + spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); +} - /* - * 3 - Handle MCU command done. - */ - if (reg_mcu) - rt2x00pci_register_write(rt2x00dev, - M2H_CMD_DONE_CSR, 0xffffffff); +static void rt61pci_enable_mcu_interrupt(struct rt2x00_dev *rt2x00dev, + struct rt2x00_field32 irq_field) +{ + unsigned long flags; + u32 reg; /* - * 4 - MCU Autowakeup interrupt. + * Enable a single MCU interrupt. The interrupt mask register + * access needs locking. */ - if (rt2x00_get_field32(reg_mcu, MCU_INT_SOURCE_CSR_TWAKEUP)) - rt61pci_wakeup(rt2x00dev); + spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); - /* - * 5 - Beacon done interrupt. - */ - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_BEACON_DONE)) - rt2x00lib_beacondone(rt2x00dev); + rt2x00pci_register_read(rt2x00dev, MCU_INT_MASK_CSR, ®); + rt2x00_set_field32(®, irq_field, 0); + rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); - /* Enable interrupts again. */ - rt2x00dev->ops->lib->set_device_state(rt2x00dev, - STATE_RADIO_IRQ_ON_ISR); - return IRQ_HANDLED; + spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); } +static void rt61pci_txstatus_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + rt61pci_txdone(rt2x00dev); + rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_TXDONE); +} + +static void rt61pci_tbtt_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + rt2x00lib_beacondone(rt2x00dev); + rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_BEACON_DONE); +} + +static void rt61pci_rxdone_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + rt2x00pci_rxdone(rt2x00dev); + rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RXDONE); +} + +static void rt61pci_autowake_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + rt61pci_wakeup(rt2x00dev); + rt2x00pci_register_write(rt2x00dev, + M2H_CMD_DONE_CSR, 0xffffffff); + rt61pci_enable_mcu_interrupt(rt2x00dev, MCU_INT_MASK_CSR_TWAKEUP); +} static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) { struct rt2x00_dev *rt2x00dev = dev_instance; - u32 reg_mcu; - u32 reg; + u32 reg_mcu, mask_mcu; + u32 reg, mask; + unsigned long flags; /* * Get the interrupt sources & saved to local variable. @@ -2295,14 +2345,46 @@ static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) return IRQ_HANDLED; - /* Store irqvalues for use in the interrupt thread. */ - rt2x00dev->irqvalue[0] = reg; - rt2x00dev->irqvalue[1] = reg_mcu; + /* + * Schedule tasklets for interrupt handling. + */ + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_RXDONE)) + tasklet_schedule(&rt2x00dev->rxdone_tasklet); + + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TXDONE)) + tasklet_schedule(&rt2x00dev->txstatus_tasklet); + + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_BEACON_DONE)) + tasklet_hi_schedule(&rt2x00dev->tbtt_tasklet); + + if (rt2x00_get_field32(reg_mcu, MCU_INT_SOURCE_CSR_TWAKEUP)) + tasklet_schedule(&rt2x00dev->autowake_tasklet); + + /* + * Since INT_MASK_CSR and INT_SOURCE_CSR use the same bits + * for interrupts and interrupt masks we can just use the value of + * INT_SOURCE_CSR to create the interrupt mask. + */ + mask = reg; + mask_mcu = reg_mcu; + + /* + * Disable all interrupts for which a tasklet was scheduled right now, + * the tasklet will reenable the appropriate interrupts. + */ + spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); + + rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); + reg |= mask; + rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); - /* Disable interrupts, will be enabled again in the interrupt thread. */ - rt2x00dev->ops->lib->set_device_state(rt2x00dev, - STATE_RADIO_IRQ_OFF_ISR); - return IRQ_WAKE_THREAD; + rt2x00pci_register_read(rt2x00dev, MCU_INT_MASK_CSR, ®); + reg |= mask_mcu; + rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); + + spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + + return IRQ_HANDLED; } /* @@ -2896,7 +2978,10 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { .irq_handler = rt61pci_interrupt, - .irq_handler_thread = rt61pci_interrupt_thread, + .txstatus_tasklet = rt61pci_txstatus_tasklet, + .tbtt_tasklet = rt61pci_tbtt_tasklet, + .rxdone_tasklet = rt61pci_rxdone_tasklet, + .autowake_tasklet = rt61pci_autowake_tasklet, .probe_hw = rt61pci_probe_hw, .get_firmware_name = rt61pci_get_firmware_name, .check_firmware = rt61pci_check_firmware, -- cgit v1.2.3 From 16222a0d06f5032d7e8bc7c65e8bf299e21f413a Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sun, 30 Jan 2011 13:19:37 +0100 Subject: rt2x00: Convert rt2500pci interrupt handling to use tasklets Fix interrupt processing on slow machines by using individual tasklets for each different device interrupt. This ensures that while a RX or TX status tasklet is scheduled only the according device interrupt is masked and other interrupts such as TBTT can still be processed. Also, this allows us to use tasklet_hi_schedule for TBTT processing which is required to not send out beacons with a wrong DTIM count (due to delayed periodic beacon updates). Furthermore, this improves the latency between the TBTT and sending out buffered multi- and broadcast traffic. As a nice bonus, the interrupt handling overhead should be much lower. Compile-tested only. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500pci.c | 150 +++++++++++++++++++++++--------- 1 file changed, 111 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 5225ae1899fe..7daa483c3742 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -735,6 +735,11 @@ static void rt2500pci_start_queue(struct data_queue *queue) rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); break; case QID_BEACON: + /* + * Allow the tbtt tasklet to be scheduled. + */ + tasklet_enable(&rt2x00dev->tbtt_tasklet); + rt2x00pci_register_read(rt2x00dev, CSR14, ®); rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); rt2x00_set_field32(®, CSR14_TBCN, 1); @@ -796,6 +801,11 @@ static void rt2500pci_stop_queue(struct data_queue *queue) rt2x00_set_field32(®, CSR14_TBCN, 0); rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); rt2x00pci_register_write(rt2x00dev, CSR14, reg); + + /* + * Wait for possibly running tbtt tasklets. + */ + tasklet_disable(&rt2x00dev->tbtt_tasklet); break; default: break; @@ -1119,6 +1129,7 @@ static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev, int mask = (state == STATE_RADIO_IRQ_OFF) || (state == STATE_RADIO_IRQ_OFF_ISR); u32 reg; + unsigned long flags; /* * When interrupts are being enabled, the interrupt registers @@ -1127,12 +1138,20 @@ static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev, if (state == STATE_RADIO_IRQ_ON) { rt2x00pci_register_read(rt2x00dev, CSR7, ®); rt2x00pci_register_write(rt2x00dev, CSR7, reg); + + /* + * Enable tasklets. + */ + tasklet_enable(&rt2x00dev->txstatus_tasklet); + tasklet_enable(&rt2x00dev->rxdone_tasklet); } /* * Only toggle the interrupts bits we are going to use. * Non-checked interrupt bits are disabled by default. */ + spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); + rt2x00pci_register_read(rt2x00dev, CSR8, ®); rt2x00_set_field32(®, CSR8_TBCN_EXPIRE, mask); rt2x00_set_field32(®, CSR8_TXDONE_TXRING, mask); @@ -1140,6 +1159,16 @@ static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, mask); rt2x00_set_field32(®, CSR8_RXDONE, mask); rt2x00pci_register_write(rt2x00dev, CSR8, reg); + + spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + + if (state == STATE_RADIO_IRQ_OFF) { + /* + * Ensure that all tasklets are finished. + */ + tasklet_disable(&rt2x00dev->txstatus_tasklet); + tasklet_disable(&rt2x00dev->rxdone_tasklet); + } } static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev) @@ -1418,58 +1447,71 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, } } -static irqreturn_t rt2500pci_interrupt_thread(int irq, void *dev_instance) +static void rt2500pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, + struct rt2x00_field32 irq_field) { - struct rt2x00_dev *rt2x00dev = dev_instance; - u32 reg = rt2x00dev->irqvalue[0]; + unsigned long flags; + u32 reg; /* - * Handle interrupts, walk through all bits - * and run the tasks, the bits are checked in order of - * priority. + * Enable a single interrupt. The interrupt mask register + * access needs locking. */ + spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); - /* - * 1 - Beacon timer expired interrupt. - */ - if (rt2x00_get_field32(reg, CSR7_TBCN_EXPIRE)) - rt2x00lib_beacondone(rt2x00dev); + rt2x00pci_register_read(rt2x00dev, CSR8, ®); + rt2x00_set_field32(®, irq_field, 0); + rt2x00pci_register_write(rt2x00dev, CSR8, reg); - /* - * 2 - Rx ring done interrupt. - */ - if (rt2x00_get_field32(reg, CSR7_RXDONE)) - rt2x00pci_rxdone(rt2x00dev); + spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); +} - /* - * 3 - Atim ring transmit done interrupt. - */ - if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) - rt2500pci_txdone(rt2x00dev, QID_ATIM); +static void rt2500pci_txstatus_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + u32 reg; + unsigned long flags; /* - * 4 - Priority ring transmit done interrupt. + * Handle all tx queues. */ - if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING)) - rt2500pci_txdone(rt2x00dev, QID_AC_VO); + rt2500pci_txdone(rt2x00dev, QID_ATIM); + rt2500pci_txdone(rt2x00dev, QID_AC_VO); + rt2500pci_txdone(rt2x00dev, QID_AC_VI); /* - * 5 - Tx ring transmit done interrupt. + * Enable all TXDONE interrupts again. */ - if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) - rt2500pci_txdone(rt2x00dev, QID_AC_VI); + spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); - /* Enable interrupts again. */ - rt2x00dev->ops->lib->set_device_state(rt2x00dev, - STATE_RADIO_IRQ_ON_ISR); + rt2x00pci_register_read(rt2x00dev, CSR8, ®); + rt2x00_set_field32(®, CSR8_TXDONE_TXRING, 0); + rt2x00_set_field32(®, CSR8_TXDONE_ATIMRING, 0); + rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, 0); + rt2x00pci_register_write(rt2x00dev, CSR8, reg); - return IRQ_HANDLED; + spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); +} + +static void rt2500pci_tbtt_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + rt2x00lib_beacondone(rt2x00dev); + rt2500pci_enable_interrupt(rt2x00dev, CSR8_TBCN_EXPIRE); +} + +static void rt2500pci_rxdone_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + rt2x00pci_rxdone(rt2x00dev); + rt2500pci_enable_interrupt(rt2x00dev, CSR8_RXDONE); } static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) { struct rt2x00_dev *rt2x00dev = dev_instance; - u32 reg; + u32 reg, mask; + unsigned long flags; /* * Get the interrupt sources & saved to local variable. @@ -1484,14 +1526,42 @@ static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) return IRQ_HANDLED; - /* Store irqvalues for use in the interrupt thread. */ - rt2x00dev->irqvalue[0] = reg; + mask = reg; + + /* + * Schedule tasklets for interrupt handling. + */ + if (rt2x00_get_field32(reg, CSR7_TBCN_EXPIRE)) + tasklet_hi_schedule(&rt2x00dev->tbtt_tasklet); + + if (rt2x00_get_field32(reg, CSR7_RXDONE)) + tasklet_schedule(&rt2x00dev->rxdone_tasklet); + + if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING) || + rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING) || + rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) { + tasklet_schedule(&rt2x00dev->txstatus_tasklet); + /* + * Mask out all txdone interrupts. + */ + rt2x00_set_field32(&mask, CSR8_TXDONE_TXRING, 1); + rt2x00_set_field32(&mask, CSR8_TXDONE_ATIMRING, 1); + rt2x00_set_field32(&mask, CSR8_TXDONE_PRIORING, 1); + } + + /* + * Disable all interrupts for which a tasklet was scheduled right now, + * the tasklet will reenable the appropriate interrupts. + */ + spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); - /* Disable interrupts, will be enabled again in the interrupt thread. */ - rt2x00dev->ops->lib->set_device_state(rt2x00dev, - STATE_RADIO_IRQ_OFF_ISR); + rt2x00pci_register_read(rt2x00dev, CSR8, ®); + reg |= mask; + rt2x00pci_register_write(rt2x00dev, CSR8, reg); + + spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); - return IRQ_WAKE_THREAD; + return IRQ_HANDLED; } /* @@ -1948,7 +2018,9 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = { static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { .irq_handler = rt2500pci_interrupt, - .irq_handler_thread = rt2500pci_interrupt_thread, + .txstatus_tasklet = rt2500pci_txstatus_tasklet, + .tbtt_tasklet = rt2500pci_tbtt_tasklet, + .rxdone_tasklet = rt2500pci_rxdone_tasklet, .probe_hw = rt2500pci_probe_hw, .initialize = rt2x00pci_initialize, .uninitialize = rt2x00pci_uninitialize, -- cgit v1.2.3 From bcf3cfd047d599cd0e6758c422bd7a4835c00d4a Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sun, 30 Jan 2011 13:20:05 +0100 Subject: rt2x00: Convert rt2400pci interrupt handling to use tasklets Fix interrupt processing on slow machines by using individual tasklets for each different device interrupt. This ensures that while a RX or TX status tasklet is scheduled only the according device interrupt is masked and other interrupts such as TBTT can still be processed. Also, this allows us to use tasklet_hi_schedule for TBTT processing which is required to not send out beacons with a wrong DTIM count (due to delayed periodic beacon updates). Furthermore, this improves the latency between the TBTT and sending out buffered multi- and broadcast traffic. As a nice bonus, the interrupt handling overhead should be much lower. Compile-tested only. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 154 ++++++++++++++++++++++++-------- 1 file changed, 115 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index cb28e1b2f1e2..b324917106e6 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -645,6 +645,11 @@ static void rt2400pci_start_queue(struct data_queue *queue) rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); break; case QID_BEACON: + /* + * Allow the tbtt tasklet to be scheduled. + */ + tasklet_enable(&rt2x00dev->tbtt_tasklet); + rt2x00pci_register_read(rt2x00dev, CSR14, ®); rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); rt2x00_set_field32(®, CSR14_TBCN, 1); @@ -706,6 +711,11 @@ static void rt2400pci_stop_queue(struct data_queue *queue) rt2x00_set_field32(®, CSR14_TBCN, 0); rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); rt2x00pci_register_write(rt2x00dev, CSR14, reg); + + /* + * Wait for possibly running tbtt tasklets. + */ + tasklet_disable(&rt2x00dev->tbtt_tasklet); break; default: break; @@ -964,6 +974,7 @@ static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev, int mask = (state == STATE_RADIO_IRQ_OFF) || (state == STATE_RADIO_IRQ_OFF_ISR); u32 reg; + unsigned long flags; /* * When interrupts are being enabled, the interrupt registers @@ -972,12 +983,20 @@ static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev, if (state == STATE_RADIO_IRQ_ON) { rt2x00pci_register_read(rt2x00dev, CSR7, ®); rt2x00pci_register_write(rt2x00dev, CSR7, reg); + + /* + * Enable tasklets. + */ + tasklet_enable(&rt2x00dev->txstatus_tasklet); + tasklet_enable(&rt2x00dev->rxdone_tasklet); } /* * Only toggle the interrupts bits we are going to use. * Non-checked interrupt bits are disabled by default. */ + spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); + rt2x00pci_register_read(rt2x00dev, CSR8, ®); rt2x00_set_field32(®, CSR8_TBCN_EXPIRE, mask); rt2x00_set_field32(®, CSR8_TXDONE_TXRING, mask); @@ -985,6 +1004,17 @@ static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, mask); rt2x00_set_field32(®, CSR8_RXDONE, mask); rt2x00pci_register_write(rt2x00dev, CSR8, reg); + + spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + + if (state == STATE_RADIO_IRQ_OFF) { + /* + * Ensure that all tasklets are finished before + * disabling the interrupts. + */ + tasklet_disable(&rt2x00dev->txstatus_tasklet); + tasklet_disable(&rt2x00dev->rxdone_tasklet); + } } static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev) @@ -1285,57 +1315,71 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, } } -static irqreturn_t rt2400pci_interrupt_thread(int irq, void *dev_instance) +static void rt2400pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, + struct rt2x00_field32 irq_field) { - struct rt2x00_dev *rt2x00dev = dev_instance; - u32 reg = rt2x00dev->irqvalue[0]; + unsigned long flags; + u32 reg; /* - * Handle interrupts, walk through all bits - * and run the tasks, the bits are checked in order of - * priority. + * Enable a single interrupt. The interrupt mask register + * access needs locking. */ + spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); - /* - * 1 - Beacon timer expired interrupt. - */ - if (rt2x00_get_field32(reg, CSR7_TBCN_EXPIRE)) - rt2x00lib_beacondone(rt2x00dev); + rt2x00pci_register_read(rt2x00dev, CSR8, ®); + rt2x00_set_field32(®, irq_field, 0); + rt2x00pci_register_write(rt2x00dev, CSR8, reg); - /* - * 2 - Rx ring done interrupt. - */ - if (rt2x00_get_field32(reg, CSR7_RXDONE)) - rt2x00pci_rxdone(rt2x00dev); + spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); +} - /* - * 3 - Atim ring transmit done interrupt. - */ - if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) - rt2400pci_txdone(rt2x00dev, QID_ATIM); +static void rt2400pci_txstatus_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + u32 reg; + unsigned long flags; /* - * 4 - Priority ring transmit done interrupt. + * Handle all tx queues. */ - if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING)) - rt2400pci_txdone(rt2x00dev, QID_AC_VO); + rt2400pci_txdone(rt2x00dev, QID_ATIM); + rt2400pci_txdone(rt2x00dev, QID_AC_VO); + rt2400pci_txdone(rt2x00dev, QID_AC_VI); /* - * 5 - Tx ring transmit done interrupt. + * Enable all TXDONE interrupts again. */ - if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) - rt2400pci_txdone(rt2x00dev, QID_AC_VI); + spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); - /* Enable interrupts again. */ - rt2x00dev->ops->lib->set_device_state(rt2x00dev, - STATE_RADIO_IRQ_ON_ISR); - return IRQ_HANDLED; + rt2x00pci_register_read(rt2x00dev, CSR8, ®); + rt2x00_set_field32(®, CSR8_TXDONE_TXRING, 0); + rt2x00_set_field32(®, CSR8_TXDONE_ATIMRING, 0); + rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, 0); + rt2x00pci_register_write(rt2x00dev, CSR8, reg); + + spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); +} + +static void rt2400pci_tbtt_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + rt2x00lib_beacondone(rt2x00dev); + rt2400pci_enable_interrupt(rt2x00dev, CSR8_TBCN_EXPIRE); +} + +static void rt2400pci_rxdone_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + rt2x00pci_rxdone(rt2x00dev); + rt2400pci_enable_interrupt(rt2x00dev, CSR8_RXDONE); } static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) { struct rt2x00_dev *rt2x00dev = dev_instance; - u32 reg; + u32 reg, mask; + unsigned long flags; /* * Get the interrupt sources & saved to local variable. @@ -1350,14 +1394,44 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) return IRQ_HANDLED; - /* Store irqvalues for use in the interrupt thread. */ - rt2x00dev->irqvalue[0] = reg; + mask = reg; + + /* + * Schedule tasklets for interrupt handling. + */ + if (rt2x00_get_field32(reg, CSR7_TBCN_EXPIRE)) + tasklet_hi_schedule(&rt2x00dev->tbtt_tasklet); + + if (rt2x00_get_field32(reg, CSR7_RXDONE)) + tasklet_schedule(&rt2x00dev->rxdone_tasklet); + + if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING) || + rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING) || + rt2x00_get_field32(reg, CSR7_TXDONE_TXRING)) { + tasklet_schedule(&rt2x00dev->txstatus_tasklet); + /* + * Mask out all txdone interrupts. + */ + rt2x00_set_field32(&mask, CSR8_TXDONE_TXRING, 1); + rt2x00_set_field32(&mask, CSR8_TXDONE_ATIMRING, 1); + rt2x00_set_field32(&mask, CSR8_TXDONE_PRIORING, 1); + } - /* Disable interrupts, will be enabled again in the interrupt thread. */ - rt2x00dev->ops->lib->set_device_state(rt2x00dev, - STATE_RADIO_IRQ_OFF_ISR); + /* + * Disable all interrupts for which a tasklet was scheduled right now, + * the tasklet will reenable the appropriate interrupts. + */ + spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); - return IRQ_WAKE_THREAD; + rt2x00pci_register_read(rt2x00dev, CSR8, ®); + reg |= mask; + rt2x00pci_register_write(rt2x00dev, CSR8, reg); + + spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + + + + return IRQ_HANDLED; } /* @@ -1651,7 +1725,9 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = { static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { .irq_handler = rt2400pci_interrupt, - .irq_handler_thread = rt2400pci_interrupt_thread, + .txstatus_tasklet = rt2400pci_txstatus_tasklet, + .tbtt_tasklet = rt2400pci_tbtt_tasklet, + .rxdone_tasklet = rt2400pci_rxdone_tasklet, .probe_hw = rt2400pci_probe_hw, .initialize = rt2x00pci_initialize, .uninitialize = rt2x00pci_uninitialize, -- cgit v1.2.3 From e88399bcdb71f2cdb195410151edf9c04980adbd Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sun, 30 Jan 2011 13:20:29 +0100 Subject: rt2x00: Remove interrupt thread registration No driver uses interrupt threads anymore. Remove the remaining interrupt thread artifacts. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 11 ----------- drivers/net/wireless/rt2x00/rt2x00pci.c | 7 +++---- 2 files changed, 3 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 696513113d9f..7661e4f60ddc 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -511,11 +511,6 @@ struct rt2x00lib_ops { */ irq_handler_t irq_handler; - /* - * Threaded Interrupt handlers. - */ - irq_handler_t irq_handler_thread; - /* * TX status tasklet handler. */ @@ -894,12 +889,6 @@ struct rt2x00_dev { */ const struct firmware *fw; - /* - * Interrupt values, stored between interrupt service routine - * and interrupt thread routine. - */ - u32 irqvalue[2]; - /* * FIFO for storing tx status reports between isr and tasklet. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index ace0b668c04e..4dd82b0b0520 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -160,10 +160,9 @@ int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) /* * Register interrupt handler. */ - status = request_threaded_irq(rt2x00dev->irq, - rt2x00dev->ops->lib->irq_handler, - rt2x00dev->ops->lib->irq_handler_thread, - IRQF_SHARED, rt2x00dev->name, rt2x00dev); + status = request_irq(rt2x00dev->irq, + rt2x00dev->ops->lib->irq_handler, + IRQF_SHARED, rt2x00dev->name, rt2x00dev); if (status) { ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n", rt2x00dev->irq, status); -- cgit v1.2.3 From b550911abc0db069bb157f9769ffb7cf22c6c868 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sun, 30 Jan 2011 13:20:52 +0100 Subject: rt2x00: Remove STATE_RADIO_IRQ_OFF_ISR and STATE_RADIO_IRQ_ON_ISR Remove STATE_RADIO_IRQ_OFF_ISR and STATE_RADIO_IRQ_ON_ISR as they are not used anymore. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 5 +---- drivers/net/wireless/rt2x00/rt2500pci.c | 5 +---- drivers/net/wireless/rt2x00/rt2500usb.c | 2 -- drivers/net/wireless/rt2x00/rt2800pci.c | 5 +---- drivers/net/wireless/rt2x00/rt2800usb.c | 2 -- drivers/net/wireless/rt2x00/rt2x00reg.h | 2 -- drivers/net/wireless/rt2x00/rt61pci.c | 5 +---- drivers/net/wireless/rt2x00/rt73usb.c | 2 -- 8 files changed, 4 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index b324917106e6..5c88fdc136a4 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -971,8 +971,7 @@ static int rt2400pci_init_bbp(struct rt2x00_dev *rt2x00dev) static void rt2400pci_toggle_irq(struct rt2x00_dev *rt2x00dev, enum dev_state state) { - int mask = (state == STATE_RADIO_IRQ_OFF) || - (state == STATE_RADIO_IRQ_OFF_ISR); + int mask = (state == STATE_RADIO_IRQ_OFF); u32 reg; unsigned long flags; @@ -1087,9 +1086,7 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2400pci_disable_radio(rt2x00dev); break; case STATE_RADIO_IRQ_ON: - case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: - case STATE_RADIO_IRQ_OFF_ISR: rt2400pci_toggle_irq(rt2x00dev, state); break; case STATE_DEEP_SLEEP: diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 7daa483c3742..3ef1fb4185c0 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1126,8 +1126,7 @@ static int rt2500pci_init_bbp(struct rt2x00_dev *rt2x00dev) static void rt2500pci_toggle_irq(struct rt2x00_dev *rt2x00dev, enum dev_state state) { - int mask = (state == STATE_RADIO_IRQ_OFF) || - (state == STATE_RADIO_IRQ_OFF_ISR); + int mask = (state == STATE_RADIO_IRQ_OFF); u32 reg; unsigned long flags; @@ -1241,9 +1240,7 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2500pci_disable_radio(rt2x00dev); break; case STATE_RADIO_IRQ_ON: - case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: - case STATE_RADIO_IRQ_OFF_ISR: rt2500pci_toggle_irq(rt2x00dev, state); break; case STATE_DEEP_SLEEP: diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 157516e0aab7..01f385d5846c 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1054,9 +1054,7 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt2500usb_disable_radio(rt2x00dev); break; case STATE_RADIO_IRQ_ON: - case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: - case STATE_RADIO_IRQ_OFF_ISR: /* No support, but no error either */ break; case STATE_DEEP_SLEEP: diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 31483c79a457..208ea5e966ed 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -418,8 +418,7 @@ static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev) static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, enum dev_state state) { - int mask = (state == STATE_RADIO_IRQ_ON) || - (state == STATE_RADIO_IRQ_ON_ISR); + int mask = (state == STATE_RADIO_IRQ_ON); u32 reg; unsigned long flags; @@ -564,9 +563,7 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt2800pci_set_state(rt2x00dev, STATE_SLEEP); break; case STATE_RADIO_IRQ_ON: - case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: - case STATE_RADIO_IRQ_OFF_ISR: rt2800pci_toggle_irq(rt2x00dev, state); break; case STATE_DEEP_SLEEP: diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 3ebe473f8551..3d2a944814bc 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -253,9 +253,7 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt2800usb_set_state(rt2x00dev, STATE_SLEEP); break; case STATE_RADIO_IRQ_ON: - case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: - case STATE_RADIO_IRQ_OFF_ISR: /* No support, but no error either */ break; case STATE_DEEP_SLEEP: diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h index e8259ae48ced..6f867eec49cc 100644 --- a/drivers/net/wireless/rt2x00/rt2x00reg.h +++ b/drivers/net/wireless/rt2x00/rt2x00reg.h @@ -85,8 +85,6 @@ enum dev_state { STATE_RADIO_OFF, STATE_RADIO_IRQ_ON, STATE_RADIO_IRQ_OFF, - STATE_RADIO_IRQ_ON_ISR, - STATE_RADIO_IRQ_OFF_ISR, }; /* diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 351055d4b89b..3afafabda080 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1717,8 +1717,7 @@ static int rt61pci_init_bbp(struct rt2x00_dev *rt2x00dev) static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, enum dev_state state) { - int mask = (state == STATE_RADIO_IRQ_OFF) || - (state == STATE_RADIO_IRQ_OFF_ISR); + int mask = (state == STATE_RADIO_IRQ_OFF); u32 reg; unsigned long flags; @@ -1852,9 +1851,7 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, rt61pci_disable_radio(rt2x00dev); break; case STATE_RADIO_IRQ_ON: - case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: - case STATE_RADIO_IRQ_OFF_ISR: rt61pci_toggle_irq(rt2x00dev, state); break; case STATE_DEEP_SLEEP: diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 330353ec5c96..aa9c61c7f376 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1428,9 +1428,7 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, rt73usb_disable_radio(rt2x00dev); break; case STATE_RADIO_IRQ_ON: - case STATE_RADIO_IRQ_ON_ISR: case STATE_RADIO_IRQ_OFF: - case STATE_RADIO_IRQ_OFF_ISR: /* No support, but no error either */ break; case STATE_DEEP_SLEEP: -- cgit v1.2.3 From c6fcc0e5f72ef6ad61e1d58cf99e27661ee206e4 Mon Sep 17 00:00:00 2001 From: RA-Jay Hung Date: Sun, 30 Jan 2011 13:21:22 +0100 Subject: rt2x00: Correct initial value of US_CYC_CNT register for pcie interface CLOCK CYCLE: Clock cycle count in 1us PCI:0x21, PCIE:0x7d, USB:0x1e Signed-off-by: RA-Jay Hung Acked-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 4 ++++ drivers/net/wireless/rt2x00/rt2800lib.c | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index c7e615cebac1..ec8159ce0ee8 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -372,8 +372,12 @@ /* * US_CYC_CNT + * BT_MODE_EN: Bluetooth mode enable + * CLOCK CYCLE: Clock cycle count in 1us. + * PCI:0x21, PCIE:0x7d, USB:0x1e */ #define US_CYC_CNT 0x02a4 +#define US_CYC_CNT_BT_MODE_EN FIELD32(0x00000100) #define US_CYC_CNT_CLOCK_CYCLE FIELD32(0x000000ff) /* diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 4753fb1b0aaf..4c34fceaec11 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2207,6 +2207,10 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_read(rt2x00dev, US_CYC_CNT, ®); rt2x00_set_field32(®, US_CYC_CNT_CLOCK_CYCLE, 30); rt2800_register_write(rt2x00dev, US_CYC_CNT, reg); + } else if (rt2x00_is_pcie(rt2x00dev)) { + rt2800_register_read(rt2x00dev, US_CYC_CNT, ®); + rt2x00_set_field32(®, US_CYC_CNT_CLOCK_CYCLE, 125); + rt2800_register_write(rt2x00dev, US_CYC_CNT, reg); } rt2800_register_read(rt2x00dev, HT_FBK_CFG0, ®); -- cgit v1.2.3 From f5a9987dfbe219ffc361ebf126e1797db4abbcfe Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Sun, 30 Jan 2011 13:22:03 +0100 Subject: Trivial typo fix in comment Fixing a trivial comment typo. Signed-off-by: Mark Einon Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 5c88fdc136a4..2725f3c4442e 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -46,7 +46,7 @@ * These indirect registers work with busy bits, * and we will try maximal REGISTER_BUSY_COUNT times to access * the register while taking a REGISTER_BUSY_DELAY us delay - * between each attampt. When the busy bit is still set at that time, + * between each attempt. When the busy bit is still set at that time, * the access attempt is considered to have failed, * and we will print an error. */ -- cgit v1.2.3 From 21957c31f6b388c7feaac59e56f765b5cc41377d Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Sun, 30 Jan 2011 13:22:22 +0100 Subject: rt2x00: trivial: add \n to WARNING message Acked-by: Gertjan van Wingerde Signed-off-by: Johannes Stezenbach Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 7d7fbe0315af..fa17c83b9685 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -913,7 +913,7 @@ void rt2x00queue_flush_queue(struct data_queue *queue, bool drop) * The queue flush has failed... */ if (unlikely(!rt2x00queue_empty(queue))) - WARNING(queue->rt2x00dev, "Queue %d failed to flush", queue->qid); + WARNING(queue->rt2x00dev, "Queue %d failed to flush\n", queue->qid); /* * Restore the queue to the previous status -- cgit v1.2.3 From a45f369d477c0e1b15b77c7b09ccfa043097e9ab Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Sun, 30 Jan 2011 13:22:41 +0100 Subject: rt2x00: Fix WPA TKIP Michael MIC failures. As reported and found by Johannes Stezenbach: rt2800{pci,usb} do not report the Michael MIC in RXed frames, but do check the Michael MIC in hardware. Therefore we have to report to mac80211 that the received frame does not include the Michael MIC. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 6 ++++++ drivers/net/wireless/rt2x00/rt2800usb.c | 6 ++++++ 2 files changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 208ea5e966ed..8f4dfc3d8023 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -675,6 +675,12 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry, */ rxdesc->flags |= RX_FLAG_IV_STRIPPED; + /* + * The hardware has already checked the Michael Mic and has + * stripped it from the frame. Signal this to mac80211. + */ + rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; + if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) rxdesc->flags |= RX_FLAG_DECRYPTED; else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 3d2a944814bc..5d91561e0de7 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -484,6 +484,12 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, */ rxdesc->flags |= RX_FLAG_IV_STRIPPED; + /* + * The hardware has already checked the Michael Mic and has + * stripped it from the frame. Signal this to mac80211. + */ + rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; + if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) rxdesc->flags |= RX_FLAG_DECRYPTED; else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) -- cgit v1.2.3 From 10026f77b3555af13e43b8de0a91ad94cd2119d7 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Sun, 30 Jan 2011 13:23:03 +0100 Subject: rt2x00: Copy the MAC address to the WCID entry properly. Use the specific mac field of the wcid_entry structure to copy the MAC address to, instead of just overwriting the structure. Previous code resulted in the same, but this form is cleaner. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 4c34fceaec11..c9bf074342ba 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1030,7 +1030,7 @@ static void rt2800_config_wcid_attr(struct rt2x00_dev *rt2x00dev, memset(&wcid_entry, 0, sizeof(wcid_entry)); if (crypto->cmd == SET_KEY) - memcpy(&wcid_entry, crypto->address, ETH_ALEN); + memcpy(wcid_entry.mac, crypto->address, ETH_ALEN); rt2800_register_multiwrite(rt2x00dev, offset, &wcid_entry, sizeof(wcid_entry)); } -- cgit v1.2.3 From a0aff623ca8bc8779e6c3a394772d70d8a65dee9 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Sun, 30 Jan 2011 13:23:22 +0100 Subject: rt2x00: Fix FIXME comments in rt61pci and rt73usb on Michael MIC. Both rt61pci and rt73usb check the Michael MIC in hardware and strip the Michael MIC from received frames. This is perfectly allowed by mac80211 as long as this is properly reported to mac80211. Both these drivers reported the Michael MIC handling properly to mac80211, but still contained a FIXME comment on this, which is not needed to be handled, since mac80211 doesn't really need the Michael MIC in this case. Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt61pci.c | 5 ++--- drivers/net/wireless/rt2x00/rt73usb.c | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 3afafabda080..dd2164d4d57b 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2118,9 +2118,8 @@ static void rt61pci_fill_rxdone(struct queue_entry *entry, rxdesc->flags |= RX_FLAG_IV_STRIPPED; /* - * FIXME: Legacy driver indicates that the frame does - * contain the Michael Mic. Unfortunately, in rt2x00 - * the MIC seems to be missing completely... + * The hardware has already checked the Michael Mic and has + * stripped it from the frame. Signal this to mac80211. */ rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index aa9c61c7f376..5ff72deea8d4 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1709,9 +1709,8 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry, rxdesc->flags |= RX_FLAG_IV_STRIPPED; /* - * FIXME: Legacy driver indicates that the frame does - * contain the Michael Mic. Unfortunately, in rt2x00 - * the MIC seems to be missing completely... + * The hardware has already checked the Michael Mic and has + * stripped it from the frame. Signal this to mac80211. */ rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; -- cgit v1.2.3 From e1f4e808bb7a884d6563553c2c94cbdd901a16c7 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sun, 30 Jan 2011 13:23:42 +0100 Subject: rt2x00: Kill all tasklets during device removal During device removal all pending work and tasklets must be guaranteed to be halted. So far only the txstatus_tasklet was killed. Signed-off-by: Ivo van Doorn Acked-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 5812a4e05c7f..e7162852ec34 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1067,6 +1067,10 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) * Kill the tx status tasklet. */ tasklet_kill(&rt2x00dev->txstatus_tasklet); + tasklet_kill(&rt2x00dev->pretbtt_tasklet); + tasklet_kill(&rt2x00dev->tbtt_tasklet); + tasklet_kill(&rt2x00dev->rxdone_tasklet); + tasklet_kill(&rt2x00dev->autowake_tasklet); /* * Uninitialize device. -- cgit v1.2.3 From 0439f5367c8d8bb2ebaca8d7329f51f3148b2fb2 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sun, 30 Jan 2011 13:24:05 +0100 Subject: rt2x00: Move TX/RX work into dedicated workqueue The TX/RX work structures must be able to run independently of other workqueues. This is because mac80211 might use the flush() callback function from various context, which depends on the TX/RX work to complete while the main thread is blocked (until the the TX queues are empty). This should reduce the number of 'Queue %d failed to flush' warnings. Signed-off-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 7 +++++++ drivers/net/wireless/rt2x00/rt2x00dev.c | 10 +++++++++- drivers/net/wireless/rt2x00/rt2x00link.c | 7 +++++-- drivers/net/wireless/rt2x00/rt2x00usb.c | 8 ++++---- 4 files changed, 25 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 7661e4f60ddc..39bc2faf1793 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -860,6 +860,13 @@ struct rt2x00_dev { */ struct ieee80211_low_level_stats low_level_stats; + /** + * Work queue for all work which should not be placed + * on the mac80211 workqueue (because of dependencies + * between various work structures). + */ + struct workqueue_struct *workqueue; + /* * Scheduled work. * NOTE: intf_work will use ieee80211_iterate_active_interfaces() diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index e7162852ec34..9de9dbe94399 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -997,8 +997,15 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) BIT(NL80211_IFTYPE_WDS); /* - * Initialize configuration work. + * Initialize work. */ + rt2x00dev->workqueue = + alloc_ordered_workqueue(wiphy_name(rt2x00dev->hw->wiphy), 0); + if (!rt2x00dev->workqueue) { + retval = -ENOMEM; + goto exit; + } + INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); /* @@ -1057,6 +1064,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) cancel_work_sync(&rt2x00dev->intf_work); cancel_work_sync(&rt2x00dev->rxdone_work); cancel_work_sync(&rt2x00dev->txdone_work); + destroy_workqueue(rt2x00dev->workqueue); /* * Free the tx status fifo. diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index bfda60eaf4ef..c975b0a12e95 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c @@ -417,7 +417,8 @@ void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev) !test_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags)) return; - schedule_delayed_work(&link->watchdog_work, WATCHDOG_INTERVAL); + ieee80211_queue_delayed_work(rt2x00dev->hw, + &link->watchdog_work, WATCHDOG_INTERVAL); } void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev) @@ -441,7 +442,9 @@ static void rt2x00link_watchdog(struct work_struct *work) rt2x00dev->ops->lib->watchdog(rt2x00dev); if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) - schedule_delayed_work(&link->watchdog_work, WATCHDOG_INTERVAL); + ieee80211_queue_delayed_work(rt2x00dev->hw, + &link->watchdog_work, + WATCHDOG_INTERVAL); } void rt2x00link_register(struct rt2x00_dev *rt2x00dev) diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 1a9937d5aff6..fbe735f5b352 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -227,7 +227,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) * Schedule the delayed work for reading the TX status * from the device. */ - ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work); + queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); } static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) @@ -320,7 +320,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) * Schedule the delayed work for reading the RX status * from the device. */ - ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work); + queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work); } static void rt2x00usb_kick_rx_entry(struct queue_entry *entry) @@ -429,7 +429,7 @@ void rt2x00usb_flush_queue(struct data_queue *queue) * Schedule the completion handler manually, when this * worker function runs, it should cleanup the queue. */ - ieee80211_queue_work(queue->rt2x00dev->hw, completion); + queue_work(queue->rt2x00dev->workqueue, completion); /* * Wait for a little while to give the driver @@ -453,7 +453,7 @@ static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) WARNING(queue->rt2x00dev, "TX queue %d status timed out," " invoke forced tx handler\n", queue->qid); - ieee80211_queue_work(queue->rt2x00dev->hw, &queue->rt2x00dev->txdone_work); + queue_work(queue->rt2x00dev->workqueue, &queue->rt2x00dev->txdone_work); } void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) -- cgit v1.2.3 From 5a3a0352f39c81dfa5c30a190ad04d115616c3e6 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 31 Jan 2011 13:01:35 +0100 Subject: iwlwifi: correct frequency settings After commit 59eb21a6504731fc16db4cf9463065dd61093e08 "cfg80211: Extend channel to frequency mapping for 802.11j" we use uninitialized sband->band when assign channel frequencies, what results that 5GHz channels have erroneous (zero) center_freq value. Patch fixes problem and simplifies code a bit. Signed-off-by: Stanislaw Gruszka Reviewed-by: Johannes Berg Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 92724cbf18ca..4ad89389a0a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -219,16 +219,12 @@ int iwlcore_init_geos(struct iwl_priv *priv) if (!is_channel_valid(ch)) continue; - if (is_channel_a_band(ch)) - sband = &priv->bands[IEEE80211_BAND_5GHZ]; - else - sband = &priv->bands[IEEE80211_BAND_2GHZ]; + sband = &priv->bands[ch->band]; geo_ch = &sband->channels[sband->n_channels++]; geo_ch->center_freq = - ieee80211_channel_to_frequency(ch->channel, - sband->band); + ieee80211_channel_to_frequency(ch->channel, ch->band); geo_ch->max_power = ch->max_power_avg; geo_ch->max_antenna_gain = 0xff; geo_ch->hw_value = ch->channel; -- cgit v1.2.3 From 7c3ee9e3fd065e878a2dbaec9d417441c59799be Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Mon, 31 Jan 2011 09:41:52 +0200 Subject: wl12xx: fix warning due to missing arg in ampdu_action Commit 0b01f030d38e00650e2db42da083d8647aad40a5 added a new argument to the ampdu_action operation. The ampdu_action operation in the wl12xx driver currently doesn't have that argument and this generates a warning. This happened during merging of the latest mac80211 patches with the wl12xx BA patches. CC [M] drivers/net/wireless/wl12xx/main.o drivers/net/wireless/wl12xx/main.c:3035: warning: initialization from incompatible pointer type The wl12xx driver doesn't need to do anything about the buf_size argument since the AMPDU TX is fully handled by the firmware. Signed-off-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index dfab21e2e5dc..254b7daccee1 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2724,8 +2724,9 @@ out: } int wl1271_op_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn) + enum ieee80211_ampdu_mlme_action action, + struct ieee80211_sta *sta, u16 tid, u16 *ssn, + u8 buf_size) { struct wl1271 *wl = hw->priv; int ret; -- cgit v1.2.3 From 10480b056662dc9595850598f0bbc5a16a4884f4 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 14 Jan 2011 17:48:06 -0800 Subject: iwlwifi: check ucode loading error and restart Driver check alive message from ucode, if it is not ok, then need to restart the loading process. instead of checking multiple places for failure, only need to check in once place when receive alive message from uCode. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-4965.c | 8 -------- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 8 -------- drivers/net/wireless/iwlwifi/iwl-agn.c | 15 ++++++--------- 3 files changed, 6 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 7c14eb31d954..ace0b98d91ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -251,14 +251,6 @@ static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv) */ static void iwl4965_init_alive_start(struct iwl_priv *priv) { - /* Check alive response for "valid" sign from uCode */ - if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { - /* We had an error bringing up the hardware, so take it - * all the way back down so we can try again */ - IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n"); - goto restart; - } - /* Bootstrap uCode has loaded initialize uCode ... verify inst image. * This is a paranoid check, because we would not have gotten the * "initialize" alive if code weren't properly loaded. */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 24dabcd2a36c..d807e5e2b718 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -308,14 +308,6 @@ void iwlagn_init_alive_start(struct iwl_priv *priv) { int ret = 0; - /* Check alive response for "valid" sign from uCode */ - if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { - /* We had an error bringing up the hardware, so take it - * all the way back down so we can try again */ - IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n"); - goto restart; - } - /* initialize uCode was loaded... verify inst image. * This is a paranoid check, because we would not have gotten the * "initialize" alive if code weren't properly loaded. */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 646ccb2430b4..3e586d3c7d0f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -462,8 +462,12 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv, if (palive->is_valid == UCODE_VALID_OK) queue_delayed_work(priv->workqueue, pwork, msecs_to_jiffies(5)); - else - IWL_WARN(priv, "uCode did not respond OK.\n"); + else { + IWL_WARN(priv, "%s uCode did not respond OK.\n", + (palive->ver_subtype == INITIALIZE_SUBTYPE) ? + "init" : "runtime"); + queue_work(priv->workqueue, &priv->restart); + } } static void iwl_bg_beacon_update(struct work_struct *work) @@ -2648,13 +2652,6 @@ static void iwl_alive_start(struct iwl_priv *priv) IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); - if (priv->card_alive.is_valid != UCODE_VALID_OK) { - /* We had an error bringing up the hardware, so take it - * all the way back down so we can try again */ - IWL_DEBUG_INFO(priv, "Alive failed.\n"); - goto restart; - } - /* Initialize uCode has loaded Runtime uCode ... verify inst image. * This is a paranoid check, because we would not have gotten the * "runtime" alive if code weren't properly loaded. */ -- cgit v1.2.3 From 7fc11e9bbe3436e8110febf0da5c58bcb4342ede Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 15 Jan 2011 09:16:59 -0800 Subject: iwlagn: adjust rate table Minor adjustment for rate scale table Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 75fcd30a7c13..20d01a312a07 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -179,31 +179,31 @@ static s32 expected_tpt_legacy[IWL_RATE_COUNT] = { }; static s32 expected_tpt_siso20MHz[4][IWL_RATE_COUNT] = { - {0, 0, 0, 0, 42, 0, 76, 102, 124, 158, 183, 193, 202}, /* Norm */ - {0, 0, 0, 0, 46, 0, 82, 110, 132, 167, 192, 202, 210}, /* SGI */ - {0, 0, 0, 0, 48, 0, 93, 135, 176, 251, 319, 351, 381}, /* AGG */ - {0, 0, 0, 0, 53, 0, 102, 149, 193, 275, 348, 381, 413}, /* AGG+SGI */ + {0, 0, 0, 0, 42, 0, 76, 102, 124, 159, 183, 193, 202}, /* Norm */ + {0, 0, 0, 0, 46, 0, 82, 110, 132, 168, 192, 202, 210}, /* SGI */ + {0, 0, 0, 0, 47, 0, 91, 133, 171, 242, 305, 334, 362}, /* AGG */ + {0, 0, 0, 0, 52, 0, 101, 145, 187, 264, 330, 361, 390}, /* AGG+SGI */ }; static s32 expected_tpt_siso40MHz[4][IWL_RATE_COUNT] = { {0, 0, 0, 0, 77, 0, 127, 160, 184, 220, 242, 250, 257}, /* Norm */ {0, 0, 0, 0, 83, 0, 135, 169, 193, 229, 250, 257, 264}, /* SGI */ - {0, 0, 0, 0, 96, 0, 182, 259, 328, 451, 553, 598, 640}, /* AGG */ - {0, 0, 0, 0, 106, 0, 199, 282, 357, 487, 593, 640, 683}, /* AGG+SGI */ + {0, 0, 0, 0, 94, 0, 177, 249, 313, 423, 512, 550, 586}, /* AGG */ + {0, 0, 0, 0, 104, 0, 193, 270, 338, 454, 545, 584, 620}, /* AGG+SGI */ }; static s32 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = { - {0, 0, 0, 0, 74, 0, 123, 155, 179, 213, 235, 243, 250}, /* Norm */ - {0, 0, 0, 0, 81, 0, 131, 164, 187, 221, 242, 250, 256}, /* SGI */ - {0, 0, 0, 0, 92, 0, 175, 250, 317, 436, 534, 578, 619}, /* AGG */ - {0, 0, 0, 0, 102, 0, 192, 273, 344, 470, 573, 619, 660}, /* AGG+SGI*/ + {0, 0, 0, 0, 74, 0, 123, 155, 179, 214, 236, 244, 251}, /* Norm */ + {0, 0, 0, 0, 81, 0, 131, 164, 188, 223, 243, 251, 257}, /* SGI */ + {0, 0, 0, 0, 89, 0, 167, 235, 296, 402, 488, 526, 560}, /* AGG */ + {0, 0, 0, 0, 97, 0, 182, 255, 320, 431, 520, 558, 593}, /* AGG+SGI*/ }; static s32 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = { {0, 0, 0, 0, 123, 0, 182, 214, 235, 264, 279, 285, 289}, /* Norm */ {0, 0, 0, 0, 131, 0, 191, 222, 242, 270, 284, 289, 293}, /* SGI */ - {0, 0, 0, 0, 180, 0, 327, 446, 545, 708, 828, 878, 922}, /* AGG */ - {0, 0, 0, 0, 197, 0, 355, 481, 584, 752, 872, 922, 966}, /* AGG+SGI */ + {0, 0, 0, 0, 171, 0, 305, 410, 496, 634, 731, 771, 805}, /* AGG */ + {0, 0, 0, 0, 186, 0, 329, 439, 527, 667, 764, 803, 838}, /* AGG+SGI */ }; static s32 expected_tpt_mimo3_20MHz[4][IWL_RATE_COUNT] = { -- cgit v1.2.3 From 52e6b85fe07ed1d2b5c76fd42ce1d77f1a190c72 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 18 Jan 2011 08:58:48 -0800 Subject: iwlagn: add IQ inversion support for 2000 series devices The I/Q swapping is extremely important and should be dealt with extra care. It will affects OFDM and CCK differently. For 6000/6005/6030 series devices, the I/Q were swapped, and for 2000 series devices, it is in non-swapped status (but its swapped with respected to 6000/6005/6030). so the CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER register need to be set to support the correct behavior. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-2000.c | 10 ++++++++-- drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-csr.h | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 3c9e1b5724c7..ac5996f40e78 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -97,6 +97,10 @@ static void iwl2000_nic_config(struct iwl_priv *priv) CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); + if (priv->cfg->iq_invert) + iwl_set_bit(priv, CSR_GP_DRIVER_REG, + CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); + } static struct iwl_sensitivity_ranges iwl2000_sensitivity = { @@ -428,7 +432,8 @@ static struct iwl_bt_params iwl2030_bt_params = { .base_params = &iwl2000_base_params, \ .need_dc_calib = true, \ .need_temp_offset_calib = true, \ - .led_mode = IWL_LED_RF_STATE \ + .led_mode = IWL_LED_RF_STATE, \ + .iq_invert = true \ struct iwl_cfg iwl2000_2bgn_cfg = { .name = "2000 Series 2x2 BGN", @@ -454,7 +459,8 @@ struct iwl_cfg iwl2000_2bg_cfg = { .need_dc_calib = true, \ .need_temp_offset_calib = true, \ .led_mode = IWL_LED_RF_STATE, \ - .adv_pm = true \ + .adv_pm = true, \ + .iq_invert = true \ struct iwl_cfg iwl2030_2bgn_cfg = { .name = "2000 Series 2x2 BGN/BT", diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index c83fcc60ccc5..b57e739e5bbb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -364,6 +364,7 @@ struct iwl_ht_params { * @adv_pm: advance power management * @rx_with_siso_diversity: 1x1 device with rx antenna diversity * @internal_wimax_coex: internal wifi/wimax combo device + * @iq_invert: I/Q inversion * * We enable the driver to be backward compatible wrt API version. The * driver specifies which APIs it supports (with @ucode_api_max being the @@ -413,6 +414,7 @@ struct iwl_cfg { const bool adv_pm; const bool rx_with_siso_diversity; const bool internal_wimax_coex; + const bool iq_invert; }; /*************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 6c2b2df7ee7e..f52bc040bcbf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -382,6 +382,8 @@ #define CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6 (0x00000004) #define CSR_GP_DRIVER_REG_BIT_6050_1x2 (0x00000008) +#define CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER (0x00000080) + /* GIO Chicken Bits (PCI Express bus link power management) */ #define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000) #define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER (0x20000000) -- cgit v1.2.3 From 9dc2153315650eae220898668b6aa56a25c130be Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 17 Jan 2011 11:05:52 -0800 Subject: iwlwifi: always support idle mode for agn devices For agn devices, always support idle mode which help power consumption in idle unassociated state. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 - drivers/net/wireless/iwlwifi/iwl-2000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-6000.c | 3 --- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - drivers/net/wireless/iwlwifi/iwl-power.c | 3 +-- 5 files changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 127723e6319f..ba78bc8a259f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -270,7 +270,6 @@ static struct iwl_base_params iwl1000_base_params = { .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, - .supports_idle = true, }; static struct iwl_ht_params iwl1000_ht_params = { .ht_greenfield_support = true, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index ac5996f40e78..8d637e778c65 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -368,7 +368,6 @@ static struct iwl_base_params iwl2000_base_params = { .shadow_ram_support = true, .led_compensation = 51, .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, .adv_thermal_throttle = true, .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, @@ -393,7 +392,6 @@ static struct iwl_base_params iwl2030_base_params = { .shadow_ram_support = true, .led_compensation = 57, .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, .adv_thermal_throttle = true, .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index c195674454f4..aa32b1e05dff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -479,7 +479,6 @@ static struct iwl_base_params iwl6000_base_params = { .shadow_ram_support = true, .led_compensation = 51, .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, .adv_thermal_throttle = true, .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, @@ -503,7 +502,6 @@ static struct iwl_base_params iwl6050_base_params = { .shadow_ram_support = true, .led_compensation = 51, .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, .adv_thermal_throttle = true, .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, @@ -526,7 +524,6 @@ static struct iwl_base_params iwl6000_g2_base_params = { .shadow_ram_support = true, .led_compensation = 57, .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, .adv_thermal_throttle = true, .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index b57e739e5bbb..e0ec17079dc0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -305,7 +305,6 @@ struct iwl_base_params { u16 led_compensation; const bool broken_powersave; int chain_noise_num_beacons; - const bool supports_idle; bool adv_thermal_throttle; bool support_ct_kill_exit; const bool support_wimax_coexist; diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 25f7d474f346..1d1bf3234d8d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -356,8 +356,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, if (priv->cfg->base_params->broken_powersave) iwl_power_sleep_cam_cmd(priv, cmd); - else if (priv->cfg->base_params->supports_idle && - priv->hw->conf.flags & IEEE80211_CONF_IDLE) + else if (priv->hw->conf.flags & IEEE80211_CONF_IDLE) iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); else if (priv->cfg->ops->lib->tt_ops.lower_power_detection && priv->cfg->ops->lib->tt_ops.tt_power_mode && -- cgit v1.2.3 From 274102a8a2a4a0b67c401b75a96694db76cfc701 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 18 Jan 2011 04:44:03 -0800 Subject: iwlwifi: support RSN IBSS In order to support RSN IBSS, we need to (ok actually maybe it's just easiest to) disable group key programming so that any group-addressed frames will be decrypted in software which handles the per-station keys for this easily. We could keep the encryption in the device, but that takes more work and seems unnecessary. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 11 ++++++++++- drivers/net/wireless/iwlwifi/iwl3945-base.c | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 3e586d3c7d0f..de84d1f802ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3207,7 +3207,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, hw->wiphy->max_remain_on_channel_duration = 1000; hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | - WIPHY_FLAG_DISABLE_BEACON_HINTS; + WIPHY_FLAG_DISABLE_BEACON_HINTS | + WIPHY_FLAG_IBSS_RSN; /* * For now, disable PS by default because it affects @@ -3359,6 +3360,14 @@ int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return -EOPNOTSUPP; } + /* + * To support IBSS RSN, don't program group keys in IBSS, the + * hardware will then not attempt to decrypt the frames. + */ + if (vif->type == NL80211_IFTYPE_ADHOC && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) + return -EOPNOTSUPP; + sta_id = iwl_sta_id_or_broadcast(priv, vif_priv->ctx, sta); if (sta_id == IWL_INVALID_STATION) return -EINVAL; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 2945acd955f0..76fae81ddc4b 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3286,6 +3286,14 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return -EOPNOTSUPP; } + /* + * To support IBSS RSN, don't program group keys in IBSS, the + * hardware will then not attempt to decrypt the frames. + */ + if (vif->type == NL80211_IFTYPE_ADHOC && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) + return -EOPNOTSUPP; + static_key = !iwl_is_associated(priv, IWL_RXON_CTX_BSS); if (!static_key) { @@ -3915,7 +3923,8 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) priv->contexts[IWL_RXON_CTX_BSS].interface_modes; hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | - WIPHY_FLAG_DISABLE_BEACON_HINTS; + WIPHY_FLAG_DISABLE_BEACON_HINTS | + WIPHY_FLAG_IBSS_RSN; hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; /* we create the 802.11 header and a zero-length SSID element */ -- cgit v1.2.3 From 9b7688328422b88a7a15dc0dc123ad9ab1a6e22d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 19 Jan 2011 02:54:18 -0800 Subject: iwlwifi: advertise max aggregate size Allow peers to size their reorder buffer more accurately by advertising that we'll never send aggregates longer than the default (31). Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index de84d1f802ec..dcc4b2d55988 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3188,6 +3188,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, IEEE80211_HW_SPECTRUM_MGMT | IEEE80211_HW_REPORTS_TX_ACK_STATUS; + hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF; + if (!priv->cfg->base_params->broken_powersave) hw->flags |= IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; -- cgit v1.2.3 From 7b09068721b1a1bbba9372d0293c21d2425b14de Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 19 Jan 2011 02:53:54 -0800 Subject: iwlwifi: use maximum aggregation size Use the values from the peer to set up the ucode for the right maximum number of subframes in an aggregate. Since the ucode only tracks this per station, use the minimum across all aggregation sessions with this peer. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 5 ++++- drivers/net/wireless/iwlwifi/iwl-agn.c | 32 ++++++++++++++++++++++++++----- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + 3 files changed, 32 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 20d01a312a07..d03b4734c892 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -2890,6 +2890,8 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, u8 ant_toggle_cnt = 0; u8 use_ht_possible = 1; u8 valid_tx_ant = 0; + struct iwl_station_priv *sta_priv = + container_of(lq_sta, struct iwl_station_priv, lq_sta); struct iwl_link_quality_cmd *lq_cmd = &lq_sta->lq; /* Override starting rate (index 0) if needed for debug purposes */ @@ -3008,7 +3010,8 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, repeat_rate--; } - lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; + lq_cmd->agg_params.agg_frame_cnt_limit = + sta_priv->max_agg_bufsize ?: LINK_QUAL_AGG_FRAME_LIMIT_DEF; lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; lq_cmd->agg_params.agg_time_limit = diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index dcc4b2d55988..cf285f53ad1d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3429,6 +3429,7 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, { struct iwl_priv *priv = hw->priv; int ret = -EINVAL; + struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", sta->addr, tid); @@ -3483,11 +3484,28 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, } break; case IEEE80211_AMPDU_TX_OPERATIONAL: + /* + * If the limit is 0, then it wasn't initialised yet, + * use the default. We can do that since we take the + * minimum below, and we don't want to go above our + * default due to hardware restrictions. + */ + if (sta_priv->max_agg_bufsize == 0) + sta_priv->max_agg_bufsize = + LINK_QUAL_AGG_FRAME_LIMIT_DEF; + + /* + * Even though in theory the peer could have different + * aggregation reorder buffer sizes for different sessions, + * our ucode doesn't allow for that and has a global limit + * for each station. Therefore, use the minimum of all the + * aggregation sessions and our default value. + */ + sta_priv->max_agg_bufsize = + min(sta_priv->max_agg_bufsize, buf_size); + if (priv->cfg->ht_params && priv->cfg->ht_params->use_rts_for_aggregation) { - struct iwl_station_priv *sta_priv = - (void *) sta->drv_priv; - /* * switch to RTS/CTS if it is the prefer protection * method for HT traffic @@ -3495,9 +3513,13 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, sta_priv->lq_sta.lq.general_params.flags |= LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; - iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), - &sta_priv->lq_sta.lq, CMD_ASYNC, false); } + + sta_priv->lq_sta.lq.agg_params.agg_frame_cnt_limit = + sta_priv->max_agg_bufsize; + + iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), + &sta_priv->lq_sta.lq, CMD_ASYNC, false); ret = 0; break; } diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index b5f21e041953..c56b797e1a1a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -509,6 +509,7 @@ struct iwl_station_priv { atomic_t pending_frames; bool client; bool asleep; + u8 max_agg_bufsize; }; /** -- cgit v1.2.3 From 241887a2d3b725fd0f87113bb7c4a51b5c6a2d06 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 19 Jan 2011 11:11:22 -0800 Subject: iwlwifi: fix beacon notification parsing The beacon notification changed between 4965 and agn because the embedded TX response changed, but iwlwifi was never updated to know about this. Update it now so the IBSS manager status will be tracked correctly. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-4965.c | 24 ++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.c | 16 ++++++++-------- drivers/net/wireless/iwlwifi/iwl-commands.h | 7 +++++++ 3 files changed, 39 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index ace0b98d91ae..8998ed134d1a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2266,6 +2266,29 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, spin_unlock_irqrestore(&priv->sta_lock, flags); } +static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl4965_beacon_notif *beacon = (void *)pkt->u.raw; +#ifdef CONFIG_IWLWIFI_DEBUG + u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); + + IWL_DEBUG_RX(priv, "beacon status %#x, retries:%d ibssmgr:%d " + "tsf:0x%.8x%.8x rate:%d\n", + le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK, + beacon->beacon_notify_hdr.failure_frame, + le32_to_cpu(beacon->ibss_mgr_status), + le32_to_cpu(beacon->high_tsf), + le32_to_cpu(beacon->low_tsf), rate); +#endif + + priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); + + if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) + queue_work(priv->workqueue, &priv->beacon_update); +} + static int iwl4965_calc_rssi(struct iwl_priv *priv, struct iwl_rx_phy_res *rx_resp) { @@ -2308,6 +2331,7 @@ static void iwl4965_rx_handler_setup(struct iwl_priv *priv) priv->rx_handlers[REPLY_RX] = iwlagn_rx_reply_rx; /* Tx response */ priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; + priv->rx_handlers[BEACON_NOTIFICATION] = iwl4965_rx_beacon_notif; /* set up notification wait support */ spin_lock_init(&priv->_agn.notif_wait_lock); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index cf285f53ad1d..d62e59249667 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -704,18 +704,18 @@ static void iwl_bg_ucode_trace(unsigned long data) } } -static void iwl_rx_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwlagn_rx_beacon_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl4965_beacon_notif *beacon = - (struct iwl4965_beacon_notif *)pkt->u.raw; + struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw; #ifdef CONFIG_IWLWIFI_DEBUG + u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status); u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); - IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d " - "tsf %d %d rate %d\n", - le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK, + IWL_DEBUG_RX(priv, "beacon status %#x, retries:%d ibssmgr:%d " + "tsf:0x%.8x%.8x rate:%d\n", + status & TX_STATUS_MSK, beacon->beacon_notify_hdr.failure_frame, le32_to_cpu(beacon->ibss_mgr_status), le32_to_cpu(beacon->high_tsf), @@ -818,7 +818,7 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv) priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = iwl_rx_pm_debug_statistics_notif; - priv->rx_handlers[BEACON_NOTIFICATION] = iwl_rx_beacon_notif; + priv->rx_handlers[BEACON_NOTIFICATION] = iwlagn_rx_beacon_notif; /* * The same handler is used for both the REPLY to a discrete diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 935b19e2c260..c3ab6ba5b45a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -3083,6 +3083,13 @@ struct iwl4965_beacon_notif { __le32 ibss_mgr_status; } __packed; +struct iwlagn_beacon_notif { + struct iwlagn_tx_resp beacon_notify_hdr; + __le32 low_tsf; + __le32 high_tsf; + __le32 ibss_mgr_status; +} __packed; + /* * REPLY_TX_BEACON = 0x91 (command, has simple generic response) */ -- cgit v1.2.3 From 96234cc84e0cce55421e981a865a4817db24ba4a Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 24 Jan 2011 11:44:42 -0800 Subject: iwlagn: use 2030 macro for 2030 devices For 2030 series of devices, 2030 macro need to be used. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-2000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 8d637e778c65..3c5dd36ff417 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -462,13 +462,13 @@ struct iwl_cfg iwl2000_2bg_cfg = { struct iwl_cfg iwl2030_2bgn_cfg = { .name = "2000 Series 2x2 BGN/BT", - IWL_DEVICE_2000, + IWL_DEVICE_2030, .ht_params = &iwl2000_ht_params, }; struct iwl_cfg iwl2030_2bg_cfg = { .name = "2000 Series 2x2 BG/BT", - IWL_DEVICE_2000, + IWL_DEVICE_2030, }; #define IWL_DEVICE_6035 \ -- cgit v1.2.3 From 187bc4f6b2f81e1c8f6b1e9d5dee3e8e9018ebbf Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 27 Jan 2011 13:01:33 -0800 Subject: iwlagn: remove unsupported BT SCO command During the period of BT coex changes, REPLY_BT_COEX_SCO host command is no longer needed to support SCO/eSCO type of traffic. delete it. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 24 ------------------------ drivers/net/wireless/iwlwifi/iwl-agn.c | 5 +---- drivers/net/wireless/iwlwifi/iwl-commands.h | 1 - drivers/net/wireless/iwlwifi/iwl-debugfs.c | 7 +++---- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - 5 files changed, 4 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index c7d03874b380..600f41745b99 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1863,21 +1863,6 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, sizeof(bt_cmd), &bt_cmd)) IWL_ERR(priv, "failed to send BT Coex Config\n"); - /* - * When we are doing a restart, need to also reconfigure BT - * SCO to the device. If not doing a restart, bt_sco_active - * will always be false, so there's no need to have an extra - * variable to check for it. - */ - if (priv->bt_sco_active) { - struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 }; - - if (priv->bt_sco_active) - sco_cmd.flags |= IWLAGN_BT_SCO_ACTIVE; - if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_SCO, - sizeof(sco_cmd), &sco_cmd)) - IWL_ERR(priv, "failed to send BT SCO command\n"); - } } static void iwlagn_bt_traffic_change_work(struct work_struct *work) @@ -2069,15 +2054,6 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, queue_work(priv->workqueue, &priv->bt_traffic_change_work); } - if (priv->bt_sco_active != - (uart_msg->frame3 & BT_UART_MSG_FRAME3SCOESCO_MSK)) { - priv->bt_sco_active = uart_msg->frame3 & - BT_UART_MSG_FRAME3SCOESCO_MSK; - if (priv->bt_sco_active) - sco_cmd.flags |= IWLAGN_BT_SCO_ACTIVE; - iwl_send_cmd_pdu_async(priv, REPLY_BT_COEX_SCO, - sizeof(sco_cmd), &sco_cmd, NULL); - } } iwlagn_set_kill_msk(priv, uart_msg); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d62e59249667..a5daf6447178 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2780,7 +2780,6 @@ static void __iwl_down(struct iwl_priv *priv) priv->cfg->bt_params->bt_init_traffic_load; else priv->bt_traffic_load = 0; - priv->bt_sco_active = false; priv->bt_full_concurrent = false; priv->bt_ci_compliance = 0; @@ -3099,7 +3098,7 @@ static void iwl_bg_restart(struct work_struct *data) if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { struct iwl_rxon_context *ctx; - bool bt_sco, bt_full_concurrent; + bool bt_full_concurrent; u8 bt_ci_compliance; u8 bt_load; u8 bt_status; @@ -3118,7 +3117,6 @@ static void iwl_bg_restart(struct work_struct *data) * re-configure the hw when we reconfigure the BT * command. */ - bt_sco = priv->bt_sco_active; bt_full_concurrent = priv->bt_full_concurrent; bt_ci_compliance = priv->bt_ci_compliance; bt_load = priv->bt_traffic_load; @@ -3126,7 +3124,6 @@ static void iwl_bg_restart(struct work_struct *data) __iwl_down(priv); - priv->bt_sco_active = bt_sco; priv->bt_full_concurrent = bt_full_concurrent; priv->bt_ci_compliance = bt_ci_compliance; priv->bt_traffic_load = bt_load; diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index c3ab6ba5b45a..0a1d4aeb36aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -178,7 +178,6 @@ enum { REPLY_BT_COEX_PRIO_TABLE = 0xcc, REPLY_BT_COEX_PROT_ENV = 0xcd, REPLY_BT_COEX_PROFILE_NOTIF = 0xce, - REPLY_BT_COEX_SCO = 0xcf, /* PAN commands */ REPLY_WIPAN_PARAMS = 0xb2, diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index bdcb74279f1e..bc7a965c18f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1587,10 +1587,9 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file, "last traffic notif: %d\n", priv->bt_status ? "On" : "Off", priv->last_bt_traffic_load); pos += scnprintf(buf + pos, bufsz - pos, "ch_announcement: %d, " - "sco_active: %d, kill_ack_mask: %x, " - "kill_cts_mask: %x\n", - priv->bt_ch_announce, priv->bt_sco_active, - priv->kill_ack_mask, priv->kill_cts_mask); + "kill_ack_mask: %x, kill_cts_mask: %x\n", + priv->bt_ch_announce, priv->kill_ack_mask, + priv->kill_cts_mask); pos += scnprintf(buf + pos, bufsz - pos, "bluetooth traffic load: "); switch (priv->bt_traffic_load) { diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index c56b797e1a1a..ecfbef402781 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1504,7 +1504,6 @@ struct iwl_priv { u8 bt_status; u8 bt_traffic_load, last_bt_traffic_load; bool bt_ch_announce; - bool bt_sco_active; bool bt_full_concurrent; bool bt_ant_couple_ok; __le32 kill_ack_mask; -- cgit v1.2.3 From c52bf9b73ad1086fbf7f8b5fdd0acdc66637e80b Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 29 Jan 2011 08:13:27 -0800 Subject: iiwlagn: remove unused parameter sco_cmd is not being used, remove it Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 600f41745b99..d4ba3357b628 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -2023,7 +2023,6 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, unsigned long flags; struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; - struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 }; struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); -- cgit v1.2.3 From cd88ccee1da3626d1c40dfcff8617b2c83271365 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Mon, 31 Jan 2011 04:21:34 +0000 Subject: bnx2x: Fix line indentation This patch contains cosmetic changes only to fix code alignment, and update copyright comment year Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 1226 +++++++++++++++++++--------------------- drivers/net/bnx2x/bnx2x_link.h | 29 +- 2 files changed, 607 insertions(+), 648 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index dd1210fddfff..e992d40e2462 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -1,4 +1,4 @@ -/* Copyright 2008-2009 Broadcom Corporation +/* Copyright 2008-2011 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -28,12 +28,13 @@ /********************************************************/ #define ETH_HLEN 14 -#define ETH_OVREHEAD (ETH_HLEN + 8 + 8)/* 16 for CRC + VLAN + LLC */ +/* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */ +#define ETH_OVREHEAD (ETH_HLEN + 8 + 8) #define ETH_MIN_PACKET_SIZE 60 #define ETH_MAX_PACKET_SIZE 1500 #define ETH_MAX_JUMBO_PACKET_SIZE 9600 #define MDIO_ACCESS_TIMEOUT 1000 -#define BMAC_CONTROL_RX_ENABLE 2 +#define BMAC_CONTROL_RX_ENABLE 2 /***********************************************************/ /* Shortcut definitions */ @@ -79,7 +80,7 @@ #define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37 #define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73 -#define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM +#define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM #define AUTONEG_PARALLEL \ SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION #define AUTONEG_SGMII_FIBER_AUTODET \ @@ -112,10 +113,10 @@ #define GP_STATUS_10G_KX4 \ MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4 -#define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD -#define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD +#define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD +#define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD -#define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4 +#define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4 #define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD #define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD #define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD @@ -123,18 +124,18 @@ #define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD #define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD -#define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD -#define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD -#define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD -#define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD +#define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD +#define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD +#define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD +#define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD #define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD #define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD -#define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD -#define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD -#define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD -#define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD -#define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD -#define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD +#define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD +#define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD +#define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD +#define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD +#define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD +#define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD #define PHY_XGXS_FLAG 0x1 #define PHY_SGMII_FLAG 0x2 @@ -142,7 +143,7 @@ /* */ #define SFP_EEPROM_CON_TYPE_ADDR 0x2 - #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 + #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21 @@ -153,15 +154,15 @@ #define SFP_EEPROM_FC_TX_TECH_ADDR 0x8 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4 - #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8 + #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8 -#define SFP_EEPROM_OPTIONS_ADDR 0x40 +#define SFP_EEPROM_OPTIONS_ADDR 0x40 #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1 -#define SFP_EEPROM_OPTIONS_SIZE 2 +#define SFP_EEPROM_OPTIONS_SIZE 2 -#define EDC_MODE_LINEAR 0x0022 -#define EDC_MODE_LIMITING 0x0044 -#define EDC_MODE_PASSIVE_DAC 0x0055 +#define EDC_MODE_LINEAR 0x0022 +#define EDC_MODE_LIMITING 0x0044 +#define EDC_MODE_PASSIVE_DAC 0x0055 #define ETS_BW_LIMIT_CREDIT_UPPER_BOUND (0x5000) @@ -329,8 +330,7 @@ void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw, if ((0 == total_bw) || (0 == cos0_bw) || (0 == cos1_bw)) { - DP(NETIF_MSG_LINK, - "bnx2x_ets_bw_limit: Total BW can't be zero\n"); + DP(NETIF_MSG_LINK, "Total BW can't be zero\n"); return; } @@ -471,7 +471,7 @@ void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars, /* MAC/PBF section */ /******************************************************************/ static void bnx2x_emac_init(struct link_params *params, - struct link_vars *vars) + struct link_vars *vars) { /* reset and unreset the emac core */ struct bnx2x *bp = params->bp; @@ -481,10 +481,10 @@ static void bnx2x_emac_init(struct link_params *params, u16 timeout; REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, - (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port)); + (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port)); udelay(5); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, - (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port)); + (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port)); /* init emac - use read-modify-write */ /* self clear reset */ @@ -515,7 +515,7 @@ static void bnx2x_emac_init(struct link_params *params, } static u8 bnx2x_emac_enable(struct link_params *params, - struct link_vars *vars, u8 lb) + struct link_vars *vars, u8 lb) { struct bnx2x *bp = params->bp; u8 port = params->port; @@ -531,8 +531,7 @@ static u8 bnx2x_emac_enable(struct link_params *params, if (CHIP_REV_IS_EMUL(bp)) { /* Use lane 1 (of lanes 0-3) */ REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1); - REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + - port*4, 1); + REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1); } /* for fpga */ else @@ -542,40 +541,35 @@ static u8 bnx2x_emac_enable(struct link_params *params, DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n"); REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1); - REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, - 0); + REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0); } else /* ASIC */ if (vars->phy_flags & PHY_XGXS_FLAG) { u32 ser_lane = ((params->lane_config & - PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> - PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); + PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> + PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); DP(NETIF_MSG_LINK, "XGXS\n"); /* select the master lanes (out of 0-3) */ - REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + - port*4, ser_lane); + REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, ser_lane); /* select XGXS */ - REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + - port*4, 1); + REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1); } else { /* SerDes */ DP(NETIF_MSG_LINK, "SerDes\n"); /* select SerDes */ - REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + - port*4, 0); + REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0); } bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE, - EMAC_RX_MODE_RESET); + EMAC_RX_MODE_RESET); bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE, - EMAC_TX_MODE_RESET); + EMAC_TX_MODE_RESET); if (CHIP_REV_IS_SLOW(bp)) { /* config GMII mode */ val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); - EMAC_WR(bp, EMAC_REG_EMAC_MODE, - (val | EMAC_MODE_PORT_GMII)); + EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_PORT_GMII)); } else { /* ASIC */ /* pause enable/disable */ bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE, @@ -668,9 +662,8 @@ static u8 bnx2x_emac_enable(struct link_params *params, if (CHIP_REV_IS_EMUL(bp)) { /* take the BigMac out of reset */ - REG_WR(bp, - GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); /* enable access for bmac registers */ REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1); @@ -731,8 +724,7 @@ static void bnx2x_update_pfc_bmac2(struct link_params *params, val |= (1<<5); wb_data[0] = val; wb_data[1] = 0; - REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, - wb_data, 2); + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2); udelay(30); /* Tx control */ @@ -781,7 +773,7 @@ static void bnx2x_update_pfc_bmac2(struct link_params *params, wb_data[0] = val; wb_data[1] = 0; REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL, - wb_data, 2); + wb_data, 2); /* mac control */ val = 0x3; /* Enable RX and TX */ @@ -795,8 +787,7 @@ static void bnx2x_update_pfc_bmac2(struct link_params *params, wb_data[0] = val; wb_data[1] = 0; - REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, - wb_data, 2); + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2); } static void bnx2x_update_pfc_brb(struct link_params *params, @@ -1035,7 +1026,7 @@ void bnx2x_update_pfc(struct link_params *params, static u8 bnx2x_bmac1_enable(struct link_params *params, struct link_vars *vars, - u8 is_lb) + u8 is_lb) { struct bnx2x *bp = params->bp; u8 port = params->port; @@ -1049,9 +1040,8 @@ static u8 bnx2x_bmac1_enable(struct link_params *params, /* XGXS control */ wb_data[0] = 0x3c; wb_data[1] = 0; - REG_WR_DMAE(bp, bmac_addr + - BIGMAC_REGISTER_BMAC_XGXS_CONTROL, - wb_data, 2); + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL, + wb_data, 2); /* tx MAC SA */ wb_data[0] = ((params->mac_addr[2] << 24) | @@ -1060,8 +1050,7 @@ static u8 bnx2x_bmac1_enable(struct link_params *params, params->mac_addr[5]); wb_data[1] = ((params->mac_addr[0] << 8) | params->mac_addr[1]); - REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, - wb_data, 2); + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2); /* mac control */ val = 0x3; @@ -1071,28 +1060,24 @@ static u8 bnx2x_bmac1_enable(struct link_params *params, } wb_data[0] = val; wb_data[1] = 0; - REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, - wb_data, 2); + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2); /* set rx mtu */ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; wb_data[1] = 0; - REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, - wb_data, 2); + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2); bnx2x_update_pfc_bmac1(params, vars); /* set tx mtu */ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; wb_data[1] = 0; - REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, - wb_data, 2); + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2); /* set cnt max size */ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; wb_data[1] = 0; - REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, - wb_data, 2); + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2); /* configure safc */ wb_data[0] = 0x1000200; @@ -1103,8 +1088,7 @@ static u8 bnx2x_bmac1_enable(struct link_params *params, if (CHIP_REV_IS_EMUL(bp)) { wb_data[0] = 0xf000; wb_data[1] = 0; - REG_WR_DMAE(bp, - bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD, + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD, wb_data, 2); } @@ -1126,16 +1110,14 @@ static u8 bnx2x_bmac2_enable(struct link_params *params, wb_data[0] = 0; wb_data[1] = 0; - REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, - wb_data, 2); + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2); udelay(30); /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */ wb_data[0] = 0x3c; wb_data[1] = 0; - REG_WR_DMAE(bp, bmac_addr + - BIGMAC2_REGISTER_BMAC_XGXS_CONTROL, - wb_data, 2); + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL, + wb_data, 2); udelay(30); @@ -1147,7 +1129,7 @@ static u8 bnx2x_bmac2_enable(struct link_params *params, wb_data[1] = ((params->mac_addr[0] << 8) | params->mac_addr[1]); REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR, - wb_data, 2); + wb_data, 2); udelay(30); @@ -1155,27 +1137,24 @@ static u8 bnx2x_bmac2_enable(struct link_params *params, wb_data[0] = 0x1000200; wb_data[1] = 0; REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS, - wb_data, 2); + wb_data, 2); udelay(30); /* set rx mtu */ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; wb_data[1] = 0; - REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, - wb_data, 2); + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2); udelay(30); /* set tx mtu */ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; wb_data[1] = 0; - REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, - wb_data, 2); + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2); udelay(30); /* set cnt max size */ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2; wb_data[1] = 0; - REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, - wb_data, 2); + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2); udelay(30); bnx2x_update_pfc_bmac2(params, vars, is_lb); @@ -1191,11 +1170,11 @@ static u8 bnx2x_bmac_enable(struct link_params *params, u32 val; /* reset and unreset the BigMac */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); msleep(1); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); /* enable access for bmac registers */ REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1); @@ -1230,15 +1209,14 @@ static void bnx2x_update_mng(struct link_params *params, u32 link_status) struct bnx2x *bp = params->bp; REG_WR(bp, params->shmem_base + - offsetof(struct shmem_region, - port_mb[params->port].link_status), - link_status); + offsetof(struct shmem_region, + port_mb[params->port].link_status), link_status); } static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port) { u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM : - NIG_REG_INGRESS_BMAC0_MEM; + NIG_REG_INGRESS_BMAC0_MEM; u32 wb_data[2]; u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4); @@ -1250,12 +1228,12 @@ static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port) if (CHIP_IS_E2(bp)) { /* Clear Rx Enable bit in BMAC_CONTROL register */ REG_RD_DMAE(bp, bmac_addr + - BIGMAC2_REGISTER_BMAC_CONTROL, - wb_data, 2); + BIGMAC2_REGISTER_BMAC_CONTROL, + wb_data, 2); wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE; REG_WR_DMAE(bp, bmac_addr + - BIGMAC2_REGISTER_BMAC_CONTROL, - wb_data, 2); + BIGMAC2_REGISTER_BMAC_CONTROL, + wb_data, 2); } else { /* Clear Rx Enable bit in BMAC_CONTROL register */ REG_RD_DMAE(bp, bmac_addr + @@ -1271,7 +1249,7 @@ static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port) } static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl, - u32 line_speed) + u32 line_speed) { struct bnx2x *bp = params->bp; u8 port = params->port; @@ -1308,7 +1286,7 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl, /* update threshold */ REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0); /* update init credit */ - init_crd = 778; /* (800-18-4) */ + init_crd = 778; /* (800-18-4) */ } else { u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE + @@ -1414,8 +1392,7 @@ u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, for (i = 0; i < 50; i++) { udelay(10); - tmp = REG_RD(bp, phy->mdio_ctrl + - EMAC_REG_EMAC_MDIO_COMM); + tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { udelay(5); break; @@ -1435,7 +1412,7 @@ u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, udelay(10); tmp = REG_RD(bp, phy->mdio_ctrl + - EMAC_REG_EMAC_MDIO_COMM); + EMAC_REG_EMAC_MDIO_COMM); if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { udelay(5); break; @@ -1466,7 +1443,7 @@ u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); val = saved_mode & ~((EMAC_MDIO_MODE_AUTO_POLL | - EMAC_MDIO_MODE_CLOCK_CNT)); + EMAC_MDIO_MODE_CLOCK_CNT)); val |= (EMAC_MDIO_MODE_CLAUSE_45 | (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT)); REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val); @@ -1505,7 +1482,7 @@ u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, udelay(10); val = REG_RD(bp, phy->mdio_ctrl + - EMAC_REG_EMAC_MDIO_COMM); + EMAC_REG_EMAC_MDIO_COMM); if (!(val & EMAC_MDIO_COMM_START_BUSY)) { *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA); break; @@ -1576,16 +1553,15 @@ static void bnx2x_set_aer_mmd_xgxs(struct link_params *params, aer_val = 0x3800 + offset - 1; else aer_val = 0x3800 + offset; - CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_AER_BLOCK, - MDIO_AER_BLOCK_AER_REG, aer_val); + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_AER_BLOCK, + MDIO_AER_BLOCK_AER_REG, aer_val); } static void bnx2x_set_aer_mmd_serdes(struct bnx2x *bp, struct bnx2x_phy *phy) { CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_AER_BLOCK, - MDIO_AER_BLOCK_AER_REG, 0x3800); + MDIO_REG_BANK_AER_BLOCK, + MDIO_AER_BLOCK_AER_REG, 0x3800); } /******************************************************************/ @@ -1621,9 +1597,8 @@ static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port) bnx2x_set_serdes_access(bp, port); - REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + - port*0x10, - DEFAULT_PHY_DEV_ADDR); + REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + port*0x10, + DEFAULT_PHY_DEV_ADDR); } static void bnx2x_xgxs_deassert(struct link_params *params) @@ -1641,23 +1616,22 @@ static void bnx2x_xgxs_deassert(struct link_params *params) udelay(500); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + - port*0x18, 0); + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + port*0x18, 0); REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, - params->phy[INT_PHY].def_md_devad); + params->phy[INT_PHY].def_md_devad); } void bnx2x_link_status_update(struct link_params *params, - struct link_vars *vars) + struct link_vars *vars) { struct bnx2x *bp = params->bp; u8 link_10g; u8 port = params->port; vars->link_status = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, - port_mb[port].link_status)); + offsetof(struct shmem_region, + port_mb[port].link_status)); vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP); @@ -1667,7 +1641,7 @@ void bnx2x_link_status_update(struct link_params *params, vars->phy_link_up = 1; vars->duplex = DUPLEX_FULL; switch (vars->link_status & - LINK_STATUS_SPEED_AND_DUPLEX_MASK) { + LINK_STATUS_SPEED_AND_DUPLEX_MASK) { case LINK_10THD: vars->duplex = DUPLEX_HALF; /* fall thru */ @@ -1779,20 +1753,20 @@ static void bnx2x_set_master_ln(struct link_params *params, { struct bnx2x *bp = params->bp; u16 new_master_ln, ser_lane; - ser_lane = ((params->lane_config & + ser_lane = ((params->lane_config & PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> - PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); + PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); /* set the master_ln for AN */ CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_XGXS_BLOCK2, - MDIO_XGXS_BLOCK2_TEST_MODE_LANE, - &new_master_ln); + MDIO_REG_BANK_XGXS_BLOCK2, + MDIO_XGXS_BLOCK2_TEST_MODE_LANE, + &new_master_ln); CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_XGXS_BLOCK2 , - MDIO_XGXS_BLOCK2_TEST_MODE_LANE, - (new_master_ln | ser_lane)); + MDIO_REG_BANK_XGXS_BLOCK2 , + MDIO_XGXS_BLOCK2_TEST_MODE_LANE, + (new_master_ln | ser_lane)); } static u8 bnx2x_reset_unicore(struct link_params *params, @@ -1804,15 +1778,15 @@ static u8 bnx2x_reset_unicore(struct link_params *params, u16 i; CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control); + MDIO_REG_BANK_COMBO_IEEE0, + MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control); /* reset the unicore */ CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_MII_CONTROL, - (mii_control | - MDIO_COMBO_IEEO_MII_CONTROL_RESET)); + MDIO_REG_BANK_COMBO_IEEE0, + MDIO_COMBO_IEEE0_MII_CONTROL, + (mii_control | + MDIO_COMBO_IEEO_MII_CONTROL_RESET)); if (set_serdes) bnx2x_set_serdes_access(bp, params->port); @@ -1822,9 +1796,9 @@ static u8 bnx2x_reset_unicore(struct link_params *params, /* the reset erased the previous bank value */ CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_MII_CONTROL, - &mii_control); + MDIO_REG_BANK_COMBO_IEEE0, + MDIO_COMBO_IEEE0_MII_CONTROL, + &mii_control); if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) { udelay(5); @@ -1846,38 +1820,38 @@ static void bnx2x_set_swap_lanes(struct link_params *params, u16 ser_lane, rx_lane_swap, tx_lane_swap; ser_lane = ((params->lane_config & - PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> - PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); + PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> + PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); rx_lane_swap = ((params->lane_config & - PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >> - PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT); + PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >> + PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT); tx_lane_swap = ((params->lane_config & - PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >> - PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT); + PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >> + PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT); if (rx_lane_swap != 0x1b) { CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_XGXS_BLOCK2, - MDIO_XGXS_BLOCK2_RX_LN_SWAP, - (rx_lane_swap | - MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE | - MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE)); + MDIO_REG_BANK_XGXS_BLOCK2, + MDIO_XGXS_BLOCK2_RX_LN_SWAP, + (rx_lane_swap | + MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE | + MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE)); } else { CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_XGXS_BLOCK2, - MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0); + MDIO_REG_BANK_XGXS_BLOCK2, + MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0); } if (tx_lane_swap != 0x1b) { CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_XGXS_BLOCK2, - MDIO_XGXS_BLOCK2_TX_LN_SWAP, - (tx_lane_swap | - MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE)); + MDIO_REG_BANK_XGXS_BLOCK2, + MDIO_XGXS_BLOCK2_TX_LN_SWAP, + (tx_lane_swap | + MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE)); } else { CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_XGXS_BLOCK2, - MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0); + MDIO_REG_BANK_XGXS_BLOCK2, + MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0); } } @@ -1887,9 +1861,9 @@ static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; u16 control2; CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_SERDES_DIGITAL, - MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, - &control2); + MDIO_REG_BANK_SERDES_DIGITAL, + MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, + &control2); if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN; else @@ -1897,9 +1871,9 @@ static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n", phy->speed_cap_mask, control2); CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_SERDES_DIGITAL, - MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, - control2); + MDIO_REG_BANK_SERDES_DIGITAL, + MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, + control2); if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && (phy->speed_cap_mask & @@ -1907,45 +1881,45 @@ static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "XGXS\n"); CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_10G_PARALLEL_DETECT, - MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK, - MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT); + MDIO_REG_BANK_10G_PARALLEL_DETECT, + MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK, + MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT); CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_10G_PARALLEL_DETECT, - MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, - &control2); + MDIO_REG_BANK_10G_PARALLEL_DETECT, + MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, + &control2); control2 |= MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN; CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_10G_PARALLEL_DETECT, - MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, - control2); + MDIO_REG_BANK_10G_PARALLEL_DETECT, + MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, + control2); /* Disable parallel detection of HiG */ CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_XGXS_BLOCK2, - MDIO_XGXS_BLOCK2_UNICORE_MODE_10G, - MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS | - MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS); + MDIO_REG_BANK_XGXS_BLOCK2, + MDIO_XGXS_BLOCK2_UNICORE_MODE_10G, + MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS | + MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS); } } static void bnx2x_set_autoneg(struct bnx2x_phy *phy, struct link_params *params, - struct link_vars *vars, - u8 enable_cl73) + struct link_vars *vars, + u8 enable_cl73) { struct bnx2x *bp = params->bp; u16 reg_val; /* CL37 Autoneg */ CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_MII_CONTROL, ®_val); + MDIO_REG_BANK_COMBO_IEEE0, + MDIO_COMBO_IEEE0_MII_CONTROL, ®_val); /* CL37 Autoneg Enabled */ if (vars->line_speed == SPEED_AUTO_NEG) @@ -1955,14 +1929,14 @@ static void bnx2x_set_autoneg(struct bnx2x_phy *phy, MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN); CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_MII_CONTROL, reg_val); + MDIO_REG_BANK_COMBO_IEEE0, + MDIO_COMBO_IEEE0_MII_CONTROL, reg_val); /* Enable/Disable Autodetection */ CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_SERDES_DIGITAL, - MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val); + MDIO_REG_BANK_SERDES_DIGITAL, + MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val); reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN | MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT); reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE; @@ -1972,13 +1946,13 @@ static void bnx2x_set_autoneg(struct bnx2x_phy *phy, reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET; CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_SERDES_DIGITAL, - MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val); + MDIO_REG_BANK_SERDES_DIGITAL, + MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val); /* Enable TetonII and BAM autoneg */ CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_BAM_NEXT_PAGE, - MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, + MDIO_REG_BANK_BAM_NEXT_PAGE, + MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, ®_val); if (vars->line_speed == SPEED_AUTO_NEG) { /* Enable BAM aneg Mode and TetonII aneg Mode */ @@ -1990,16 +1964,16 @@ static void bnx2x_set_autoneg(struct bnx2x_phy *phy, MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN); } CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_BAM_NEXT_PAGE, - MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, - reg_val); + MDIO_REG_BANK_BAM_NEXT_PAGE, + MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, + reg_val); if (enable_cl73) { /* Enable Cl73 FSM status bits */ CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_CL73_USERB0, - MDIO_CL73_USERB0_CL73_UCTRL, - 0xe); + MDIO_REG_BANK_CL73_USERB0, + MDIO_CL73_USERB0_CL73_UCTRL, + 0xe); /* Enable BAM Station Manager*/ CL45_WR_OVER_CL22(bp, phy, @@ -2011,9 +1985,9 @@ static void bnx2x_set_autoneg(struct bnx2x_phy *phy, /* Advertise CL73 link speeds */ CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_CL73_IEEEB1, - MDIO_CL73_IEEEB1_AN_ADV2, - ®_val); + MDIO_REG_BANK_CL73_IEEEB1, + MDIO_CL73_IEEEB1_AN_ADV2, + ®_val); if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4; @@ -2022,9 +1996,9 @@ static void bnx2x_set_autoneg(struct bnx2x_phy *phy, reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX; CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_CL73_IEEEB1, - MDIO_CL73_IEEEB1_AN_ADV2, - reg_val); + MDIO_REG_BANK_CL73_IEEEB1, + MDIO_CL73_IEEEB1_AN_ADV2, + reg_val); /* CL73 Autoneg Enabled */ reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN; @@ -2033,36 +2007,36 @@ static void bnx2x_set_autoneg(struct bnx2x_phy *phy, reg_val = 0; CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_CL73_IEEEB0, - MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val); + MDIO_REG_BANK_CL73_IEEEB0, + MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val); } /* program SerDes, forced speed */ static void bnx2x_program_serdes(struct bnx2x_phy *phy, struct link_params *params, - struct link_vars *vars) + struct link_vars *vars) { struct bnx2x *bp = params->bp; u16 reg_val; /* program duplex, disable autoneg and sgmii*/ CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_MII_CONTROL, ®_val); + MDIO_REG_BANK_COMBO_IEEE0, + MDIO_COMBO_IEEE0_MII_CONTROL, ®_val); reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX | MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK); if (phy->req_duplex == DUPLEX_FULL) reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX; CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_MII_CONTROL, reg_val); + MDIO_REG_BANK_COMBO_IEEE0, + MDIO_COMBO_IEEE0_MII_CONTROL, reg_val); /* program speed - needed only if the speed is greater than 1G (2.5G or 10G) */ CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_SERDES_DIGITAL, - MDIO_SERDES_DIGITAL_MISC1, ®_val); + MDIO_REG_BANK_SERDES_DIGITAL, + MDIO_SERDES_DIGITAL_MISC1, ®_val); /* clearing the speed value before setting the right speed */ DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val); @@ -2084,8 +2058,8 @@ static void bnx2x_program_serdes(struct bnx2x_phy *phy, } CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_SERDES_DIGITAL, - MDIO_SERDES_DIGITAL_MISC1, reg_val); + MDIO_REG_BANK_SERDES_DIGITAL, + MDIO_SERDES_DIGITAL_MISC1, reg_val); } @@ -2103,12 +2077,12 @@ static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x_phy *phy, if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) val |= MDIO_OVER_1G_UP1_10G; CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_OVER_1G, - MDIO_OVER_1G_UP1, val); + MDIO_REG_BANK_OVER_1G, + MDIO_OVER_1G_UP1, val); CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_OVER_1G, - MDIO_OVER_1G_UP3, 0x400); + MDIO_REG_BANK_OVER_1G, + MDIO_OVER_1G_UP3, 0x400); } static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy, @@ -2121,17 +2095,14 @@ static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy, switch (phy->req_flow_ctrl) { case BNX2X_FLOW_CTRL_AUTO: - if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) { - *ieee_fc |= - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; - } else { + if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) + *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; + else *ieee_fc |= - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; - } + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; break; case BNX2X_FLOW_CTRL_TX: - *ieee_fc |= - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; + *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; break; case BNX2X_FLOW_CTRL_RX: @@ -2149,23 +2120,23 @@ static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy, static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x_phy *phy, struct link_params *params, - u16 ieee_fc) + u16 ieee_fc) { struct bnx2x *bp = params->bp; u16 val; /* for AN, we are always publishing full duplex */ CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc); + MDIO_REG_BANK_COMBO_IEEE0, + MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc); CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_CL73_IEEEB1, - MDIO_CL73_IEEEB1_AN_ADV1, &val); + MDIO_REG_BANK_CL73_IEEEB1, + MDIO_CL73_IEEEB1_AN_ADV1, &val); val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH; val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK); CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_CL73_IEEEB1, - MDIO_CL73_IEEEB1_AN_ADV1, val); + MDIO_REG_BANK_CL73_IEEEB1, + MDIO_CL73_IEEEB1_AN_ADV1, val); } static void bnx2x_restart_autoneg(struct bnx2x_phy *phy, @@ -2180,37 +2151,37 @@ static void bnx2x_restart_autoneg(struct bnx2x_phy *phy, if (enable_cl73) { CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_CL73_IEEEB0, - MDIO_CL73_IEEEB0_CL73_AN_CONTROL, - &mii_control); + MDIO_REG_BANK_CL73_IEEEB0, + MDIO_CL73_IEEEB0_CL73_AN_CONTROL, + &mii_control); CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_CL73_IEEEB0, - MDIO_CL73_IEEEB0_CL73_AN_CONTROL, - (mii_control | - MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN | - MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN)); + MDIO_REG_BANK_CL73_IEEEB0, + MDIO_CL73_IEEEB0_CL73_AN_CONTROL, + (mii_control | + MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN | + MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN)); } else { CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_MII_CONTROL, - &mii_control); + MDIO_REG_BANK_COMBO_IEEE0, + MDIO_COMBO_IEEE0_MII_CONTROL, + &mii_control); DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg mii_control before = 0x%x\n", mii_control); CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_MII_CONTROL, - (mii_control | - MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | - MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN)); + MDIO_REG_BANK_COMBO_IEEE0, + MDIO_COMBO_IEEE0_MII_CONTROL, + (mii_control | + MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | + MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN)); } } static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy, struct link_params *params, - struct link_vars *vars) + struct link_vars *vars) { struct bnx2x *bp = params->bp; u16 control1; @@ -2218,18 +2189,18 @@ static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy, /* in SGMII mode, the unicore is always slave */ CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_SERDES_DIGITAL, - MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, - &control1); + MDIO_REG_BANK_SERDES_DIGITAL, + MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, + &control1); control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT; /* set sgmii mode (and not fiber) */ control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE | MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET | MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE); CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_SERDES_DIGITAL, - MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, - control1); + MDIO_REG_BANK_SERDES_DIGITAL, + MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, + control1); /* if forced speed */ if (!(vars->line_speed == SPEED_AUTO_NEG)) { @@ -2237,9 +2208,9 @@ static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy, u16 mii_control; CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_MII_CONTROL, - &mii_control); + MDIO_REG_BANK_COMBO_IEEE0, + MDIO_COMBO_IEEE0_MII_CONTROL, + &mii_control); mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK| MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX); @@ -2268,9 +2239,9 @@ static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy, mii_control |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX; CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_MII_CONTROL, - mii_control); + MDIO_REG_BANK_COMBO_IEEE0, + MDIO_COMBO_IEEE0_MII_CONTROL, + mii_control); } else { /* AN mode */ /* enable and restart AN */ @@ -2285,19 +2256,19 @@ static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy, static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result) { /* LD LP */ - switch (pause_result) { /* ASYM P ASYM P */ - case 0xb: /* 1 0 1 1 */ + switch (pause_result) { /* ASYM P ASYM P */ + case 0xb: /* 1 0 1 1 */ vars->flow_ctrl = BNX2X_FLOW_CTRL_TX; break; - case 0xe: /* 1 1 1 0 */ + case 0xe: /* 1 1 1 0 */ vars->flow_ctrl = BNX2X_FLOW_CTRL_RX; break; - case 0x5: /* 0 1 0 1 */ - case 0x7: /* 0 1 1 1 */ - case 0xd: /* 1 1 0 1 */ - case 0xf: /* 1 1 1 1 */ + case 0x5: /* 0 1 0 1 */ + case 0x7: /* 0 1 1 1 */ + case 0xd: /* 1 1 0 1 */ + case 0xf: /* 1 1 1 1 */ vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH; break; @@ -2318,13 +2289,13 @@ static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy, if (phy->req_line_speed != SPEED_AUTO_NEG) return 0; CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_SERDES_DIGITAL, - MDIO_SERDES_DIGITAL_A_1000X_STATUS2, - &status2_1000x); + MDIO_REG_BANK_SERDES_DIGITAL, + MDIO_SERDES_DIGITAL_A_1000X_STATUS2, + &status2_1000x); CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_SERDES_DIGITAL, - MDIO_SERDES_DIGITAL_A_1000X_STATUS2, - &status2_1000x); + MDIO_REG_BANK_SERDES_DIGITAL, + MDIO_SERDES_DIGITAL_A_1000X_STATUS2, + &status2_1000x); if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) { DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n", params->port); @@ -2332,9 +2303,9 @@ static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy, } CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_10G_PARALLEL_DETECT, - MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS, - &pd_10g); + MDIO_REG_BANK_10G_PARALLEL_DETECT, + MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS, + &pd_10g); if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) { DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n", @@ -2374,13 +2345,13 @@ static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy, MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) { CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_CL73_IEEEB1, - MDIO_CL73_IEEEB1_AN_ADV1, - &ld_pause); + MDIO_REG_BANK_CL73_IEEEB1, + MDIO_CL73_IEEEB1_AN_ADV1, + &ld_pause); CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_CL73_IEEEB1, - MDIO_CL73_IEEEB1_AN_LP_ADV1, - &lp_pause); + MDIO_REG_BANK_CL73_IEEEB1, + MDIO_CL73_IEEEB1_AN_LP_ADV1, + &lp_pause); pause_result = (ld_pause & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK) >> 8; @@ -2391,17 +2362,17 @@ static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy, pause_result); } else { CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_AUTO_NEG_ADV, - &ld_pause); + MDIO_REG_BANK_COMBO_IEEE0, + MDIO_COMBO_IEEE0_AUTO_NEG_ADV, + &ld_pause); CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1, - &lp_pause); + MDIO_REG_BANK_COMBO_IEEE0, + MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1, + &lp_pause); pause_result = (ld_pause & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5; pause_result |= (lp_pause & - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7; + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7; DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n", pause_result); } @@ -2418,24 +2389,24 @@ static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n"); /* Step 1: Make sure signal is detected */ CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_RX0, - MDIO_RX0_RX_STATUS, - &rx_status); + MDIO_REG_BANK_RX0, + MDIO_RX0_RX_STATUS, + &rx_status); if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) != (MDIO_RX0_RX_STATUS_SIGDET)) { DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73." "rx_status(0x80b0) = 0x%x\n", rx_status); CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_CL73_IEEEB0, - MDIO_CL73_IEEEB0_CL73_AN_CONTROL, - MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN); + MDIO_REG_BANK_CL73_IEEEB0, + MDIO_CL73_IEEEB0_CL73_AN_CONTROL, + MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN); return; } /* Step 2: Check CL73 state machine */ CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_CL73_USERB0, - MDIO_CL73_USERB0_CL73_USTAT1, - &ustat_val); + MDIO_REG_BANK_CL73_USERB0, + MDIO_CL73_USERB0_CL73_USTAT1, + &ustat_val); if ((ustat_val & (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK | MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) != @@ -2448,9 +2419,9 @@ static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy, /* Step 3: Check CL37 Message Pages received to indicate LP supports only CL37 */ CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_REMOTE_PHY, - MDIO_REMOTE_PHY_MISC_RX_STATUS, - &cl37_fsm_recieved); + MDIO_REG_BANK_REMOTE_PHY, + MDIO_REMOTE_PHY_MISC_RX_STATUS, + &cl37_fsm_recieved); if ((cl37_fsm_recieved & (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG | MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) != @@ -2466,9 +2437,9 @@ static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy, cl37 BAM. In this case we disable cl73 and restart cl37 auto-neg */ /* Disable CL73 */ CL45_WR_OVER_CL22(bp, phy, - MDIO_REG_BANK_CL73_IEEEB0, - MDIO_CL73_IEEEB0_CL73_AN_CONTROL, - 0); + MDIO_REG_BANK_CL73_IEEEB0, + MDIO_CL73_IEEEB0_CL73_AN_CONTROL, + 0); /* Restart CL37 autoneg */ bnx2x_restart_autoneg(phy, params, 0); DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n"); @@ -2493,14 +2464,14 @@ static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u16 new_line_speed , gp_status; + u16 new_line_speed, gp_status; u8 rc = 0; /* Read gp_status */ CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_GP_STATUS, - MDIO_GP_STATUS_TOP_AN_STATUS1, - &gp_status); + MDIO_REG_BANK_GP_STATUS, + MDIO_GP_STATUS_TOP_AN_STATUS1, + &gp_status); if (phy->req_line_speed == SPEED_AUTO_NEG) vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED; @@ -2638,8 +2609,8 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params) /* read precomp */ CL45_RD_OVER_CL22(bp, phy, - MDIO_REG_BANK_OVER_1G, - MDIO_OVER_1G_LP_UP2, &lp_up2); + MDIO_REG_BANK_OVER_1G, + MDIO_OVER_1G_LP_UP2, &lp_up2); /* bits [10:7] at lp_up2, positioned at [15:12] */ lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >> @@ -2652,8 +2623,8 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params) for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3; bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) { CL45_RD_OVER_CL22(bp, phy, - bank, - MDIO_TX0_TX_DRIVER, &tx_driver); + bank, + MDIO_TX0_TX_DRIVER, &tx_driver); /* replace tx_driver bits [15:12] */ if (lp_up2 != @@ -2661,8 +2632,8 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params) tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK; tx_driver |= lp_up2; CL45_WR_OVER_CL22(bp, phy, - bank, - MDIO_TX0_TX_DRIVER, tx_driver); + bank, + MDIO_TX0_TX_DRIVER, tx_driver); } } } @@ -2676,10 +2647,10 @@ static u8 bnx2x_emac_program(struct link_params *params, DP(NETIF_MSG_LINK, "setting link speed & duplex\n"); bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 + - EMAC_REG_EMAC_MODE, - (EMAC_MODE_25G_MODE | - EMAC_MODE_PORT_MII_10M | - EMAC_MODE_HALF_DUPLEX)); + EMAC_REG_EMAC_MODE, + (EMAC_MODE_25G_MODE | + EMAC_MODE_PORT_MII_10M | + EMAC_MODE_HALF_DUPLEX)); switch (vars->line_speed) { case SPEED_10: mode |= EMAC_MODE_PORT_MII_10M; @@ -2707,8 +2678,8 @@ static u8 bnx2x_emac_program(struct link_params *params, if (vars->duplex == DUPLEX_HALF) mode |= EMAC_MODE_HALF_DUPLEX; bnx2x_bits_en(bp, - GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE, - mode); + GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE, + mode); bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed); return 0; @@ -2754,7 +2725,7 @@ static void bnx2x_init_internal_phy(struct bnx2x_phy *phy, /* forced speed requested? */ if (vars->line_speed != SPEED_AUTO_NEG || (SINGLE_MEDIA_DIRECT(params) && - params->loopback_mode == LOOPBACK_EXT)) { + params->loopback_mode == LOOPBACK_EXT)) { DP(NETIF_MSG_LINK, "not SGMII, no AN\n"); /* disable autoneg */ @@ -2771,7 +2742,7 @@ static void bnx2x_init_internal_phy(struct bnx2x_phy *phy, /* program duplex & pause advertisement (for aneg) */ bnx2x_set_ieee_aneg_advertisment(phy, params, - vars->ieee_fc); + vars->ieee_fc); /* enable autoneg */ bnx2x_set_autoneg(phy, params, vars, enable_cl73); @@ -2933,13 +2904,13 @@ static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port, /* For all latched-signal=up : Re-Arm Latch signals */ REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8, - (latch_status & 0xfffe) | (latch_status & 1)); + (latch_status & 0xfffe) | (latch_status & 1)); } /* For all latched-signal=up,Write original_signal to status */ } static void bnx2x_link_int_ack(struct link_params *params, - struct link_vars *vars, u8 is_10g) + struct link_vars *vars, u8 is_10g) { struct bnx2x *bp = params->bp; u8 port = params->port; @@ -2947,9 +2918,9 @@ static void bnx2x_link_int_ack(struct link_params *params, /* first reset all status * we assume only one line will be change at a time */ bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - (NIG_STATUS_XGXS0_LINK10G | - NIG_STATUS_XGXS0_LINK_STATUS | - NIG_STATUS_SERDES0_LINK_STATUS)); + (NIG_STATUS_XGXS0_LINK10G | + NIG_STATUS_XGXS0_LINK_STATUS | + NIG_STATUS_SERDES0_LINK_STATUS)); if (vars->phy_link_up) { if (is_10g) { /* Disable the 10G link interrupt @@ -3059,8 +3030,7 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, } if ((params->num_phys == MAX_PHYS) && (params->phy[EXT_PHY2].ver_addr != 0)) { - spirom_ver = REG_RD(bp, - params->phy[EXT_PHY2].ver_addr); + spirom_ver = REG_RD(bp, params->phy[EXT_PHY2].ver_addr); if (params->phy[EXT_PHY2].format_fw_ver) { *ver_p = '/'; ver_p++; @@ -3089,29 +3059,27 @@ static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy, /* change the uni_phy_addr in the nig */ md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD + - port*0x18)); + port*0x18)); REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5); bnx2x_cl45_write(bp, phy, - 5, - (MDIO_REG_BANK_AER_BLOCK + - (MDIO_AER_BLOCK_AER_REG & 0xf)), - 0x2800); + 5, + (MDIO_REG_BANK_AER_BLOCK + + (MDIO_AER_BLOCK_AER_REG & 0xf)), + 0x2800); bnx2x_cl45_write(bp, phy, - 5, - (MDIO_REG_BANK_CL73_IEEEB0 + - (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)), - 0x6041); + 5, + (MDIO_REG_BANK_CL73_IEEEB0 + + (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)), + 0x6041); msleep(200); /* set aer mmd back */ bnx2x_set_aer_mmd_xgxs(params, phy); /* and md_devad */ - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, - md_devad); - + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, md_devad); } else { u16 mii_ctrl; DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n"); @@ -3152,7 +3120,7 @@ u8 bnx2x_set_led(struct link_params *params, case LED_MODE_OFF: REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0); REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, - SHARED_HW_CFG_LED_MAC1); + SHARED_HW_CFG_LED_MAC1); tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE)); @@ -3190,20 +3158,17 @@ u8 bnx2x_set_led(struct link_params *params, REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0); REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1); } else { - REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, - hw_led_mode); + REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode); } - REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + - port*4, 0); + REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0); /* Set blinking rate to ~15.9Hz */ REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4, - LED_BLINK_RATE_VAL); + LED_BLINK_RATE_VAL); REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 + - port*4, 1); + port*4, 1); tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); - EMAC_WR(bp, EMAC_REG_EMAC_LED, - (tmp & (~EMAC_LED_OVERRIDE))); + EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp & (~EMAC_LED_OVERRIDE))); if (CHIP_IS_E1(bp) && ((speed == SPEED_2500) || @@ -3213,11 +3178,11 @@ u8 bnx2x_set_led(struct link_params *params, /* On Everest 1 Ax chip versions for speeds less than 10G LED scheme is different */ REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 - + port*4, 1); + + port*4, 1); REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + - port*4, 0); + port*4, 0); REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 + - port*4, 1); + port*4, 1); } break; @@ -3244,9 +3209,9 @@ u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars, struct link_vars temp_vars; CL45_RD_OVER_CL22(bp, ¶ms->phy[INT_PHY], - MDIO_REG_BANK_GP_STATUS, - MDIO_GP_STATUS_TOP_AN_STATUS1, - &gp_status); + MDIO_REG_BANK_GP_STATUS, + MDIO_GP_STATUS_TOP_AN_STATUS1, + &gp_status); /* link is up only if both local phy and external phy are up */ if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)) return -ESRCH; @@ -3358,9 +3323,8 @@ static void bnx2x_int_link_reset(struct bnx2x_phy *phy, struct link_params *params) { /* reset the SerDes/XGXS */ - REG_WR(params->bp, GRCBASE_MISC + - MISC_REGISTERS_RESET_REG_3_CLEAR, - (0x1ff << (params->port*16))); + REG_WR(params->bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, + (0x1ff << (params->port*16))); } static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy, @@ -3374,11 +3338,11 @@ static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy, else gpio_port = params->port; bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, - gpio_port); + MISC_REGISTERS_GPIO_OUTPUT_LOW, + gpio_port); bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_LOW, - gpio_port); + MISC_REGISTERS_GPIO_OUTPUT_LOW, + gpio_port); DP(NETIF_MSG_LINK, "reset external PHY\n"); } @@ -3409,9 +3373,8 @@ static u8 bnx2x_update_link_down(struct link_params *params, /* reset BigMac */ bnx2x_bmac_rx_disable(bp, params->port); - REG_WR(bp, GRCBASE_MISC + - MISC_REGISTERS_RESET_REG_2_CLEAR, - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); return 0; } @@ -3501,12 +3464,11 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4)); is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + - port*0x18) > 0); + port*0x18) > 0); DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n", REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), is_mi_int, - REG_RD(bp, - NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c)); + REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c)); DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n", REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), @@ -3658,8 +3620,8 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) ext_phy_line_speed); vars->phy_link_up = 0; } else if (prev_line_speed != vars->line_speed) { - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE - + params->port*4, 0); + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, + 0); msleep(1); } } @@ -3724,10 +3686,10 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port) { bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, port); + MISC_REGISTERS_GPIO_OUTPUT_LOW, port); msleep(1); bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); + MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); } static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port, @@ -3747,9 +3709,9 @@ static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u16 fw_ver1, fw_ver2; bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER1, &fw_ver1); + MDIO_PMA_REG_ROM_VER1, &fw_ver1); bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER2, &fw_ver2); + MDIO_PMA_REG_ROM_VER2, &fw_ver2); bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr); } @@ -3770,7 +3732,7 @@ static void bnx2x_ext_phy_set_pause(struct link_params *params, if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) == MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) { - val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC; + val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC; } if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) == @@ -3801,11 +3763,11 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) { ret = 1; bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_ADV_PAUSE, &ld_pause); + MDIO_AN_DEVAD, + MDIO_AN_REG_ADV_PAUSE, &ld_pause); bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_LP_AUTO_NEG, &lp_pause); + MDIO_AN_DEVAD, + MDIO_AN_REG_LP_AUTO_NEG, &lp_pause); pause_result = (ld_pause & MDIO_AN_REG_ADV_PAUSE_MASK) >> 8; pause_result |= (lp_pause & @@ -3881,31 +3843,31 @@ static u8 bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, /* Boot port from external ROM */ /* EDC grst */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - 0x0001); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, + 0x0001); /* ucode reboot and rst */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - 0x008c); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, + 0x008c); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL1, 0x0001); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_MISC_CTRL1, 0x0001); /* Reset internal microprocessor */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, + MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); /* Release srst bit */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, + MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); /* Delay 100ms per the PHY specifications */ msleep(100); @@ -3936,8 +3898,8 @@ static u8 bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, /* Clear ser_boot_ctl bit */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL1, 0x0000); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_MISC_CTRL1, 0x0000); bnx2x_save_bcm_spirom_ver(bp, phy, port); DP(NETIF_MSG_LINK, @@ -3958,8 +3920,8 @@ static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy) /* Read 8073 HW revision*/ bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8073_CHIP_REV, &val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8073_CHIP_REV, &val); if (val != 1) { /* No need to workaround in 8073 A1 */ @@ -3967,8 +3929,8 @@ static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy) } bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER2, &val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_ROM_VER2, &val); /* SNR should be applied only for version 0x102 */ if (val != 0x102) @@ -3982,8 +3944,8 @@ static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy) u16 val, cnt, cnt1 ; bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8073_CHIP_REV, &val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8073_CHIP_REV, &val); if (val > 0) { /* No need to workaround in 8073 A1 */ @@ -3996,9 +3958,9 @@ static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy) for (cnt = 0; cnt < 1000; cnt++) { bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8073_SPEED_LINK_STATUS, - &val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8073_SPEED_LINK_STATUS, + &val); /* If bit [14] = 0 or bit [13] = 0, continue on with system initialization (XAUI work-around not required, as these bits indicate 2.5G or 1G link up). */ @@ -4093,10 +4055,10 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, gpio_port = params->port; /* Restore normal power mode*/ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port); + MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port); bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port); + MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port); /* enable LASI */ bnx2x_cl45_write(bp, phy, @@ -4381,8 +4343,8 @@ static void bnx2x_8073_link_reset(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n", gpio_port); bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_LOW, - gpio_port); + MISC_REGISTERS_GPIO_OUTPUT_LOW, + gpio_port); } /******************************************************************/ @@ -4396,7 +4358,7 @@ static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "init 8705\n"); /* Restore normal power mode*/ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); /* HW reset */ bnx2x_ext_phy_hw_reset(bp, params->port); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); @@ -4479,7 +4441,7 @@ static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, struct link_params *params, - u16 addr, u8 byte_cnt, u8 *o_buf) + u16 addr, u8 byte_cnt, u8 *o_buf) { struct bnx2x *bp = params->bp; u16 val = 0; @@ -4492,23 +4454,23 @@ static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, /* Set the read command byte count */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT, - (byte_cnt | 0xa000)); + (byte_cnt | 0xa000)); /* Set the read command address */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR, - addr); + addr); /* Activate read command */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, - 0x2c0f); + 0x2c0f); /* Wait up to 500us for command complete status */ for (i = 0; i < 100; i++) { bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) break; @@ -4526,15 +4488,15 @@ static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, /* Read the buffer */ for (i = 0; i < byte_cnt; i++) { bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val); o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK); } for (i = 0; i < 100; i++) { bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) return 0; @@ -4545,7 +4507,7 @@ static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, struct link_params *params, - u16 addr, u8 byte_cnt, u8 *o_buf) + u16 addr, u8 byte_cnt, u8 *o_buf) { struct bnx2x *bp = params->bp; u16 val, i; @@ -4558,32 +4520,32 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, /* Need to read from 1.8000 to clear it */ bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, - &val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, + &val); /* Set the read command byte count */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT, - ((byte_cnt < 2) ? 2 : byte_cnt)); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT, + ((byte_cnt < 2) ? 2 : byte_cnt)); /* Set the read command address */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR, - addr); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR, + addr); /* Set the destination address */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - 0x8004, - MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF); + MDIO_PMA_DEVAD, + 0x8004, + MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF); /* Activate read command */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, - 0x8002); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, + 0x8002); /* Wait appropriate time for two-wire command to finish before polling the status register */ msleep(1); @@ -4591,8 +4553,8 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, /* Wait up to 500us for command complete status */ for (i = 0; i < 100; i++) { bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) break; @@ -4610,15 +4572,15 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, /* Read the buffer */ for (i = 0; i < byte_cnt; i++) { bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val); o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK); } for (i = 0; i < 100; i++) { bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) return 0; @@ -4628,22 +4590,22 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, return -EINVAL; } -static u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, - struct link_params *params, u16 addr, - u8 byte_cnt, u8 *o_buf) +u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, + struct link_params *params, u16 addr, + u8 byte_cnt, u8 *o_buf) { if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) return bnx2x_8726_read_sfp_module_eeprom(phy, params, addr, - byte_cnt, o_buf); + byte_cnt, o_buf); else if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) return bnx2x_8727_read_sfp_module_eeprom(phy, params, addr, - byte_cnt, o_buf); + byte_cnt, o_buf); return -EINVAL; } static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy, struct link_params *params, - u16 *edc_mode) + u16 *edc_mode) { struct bnx2x *bp = params->bp; u8 val, check_limiting_mode = 0; @@ -4774,17 +4736,17 @@ static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy, /* format the warning message */ if (bnx2x_read_sfp_module_eeprom(phy, params, - SFP_EEPROM_VENDOR_NAME_ADDR, - SFP_EEPROM_VENDOR_NAME_SIZE, - (u8 *)vendor_name)) + SFP_EEPROM_VENDOR_NAME_ADDR, + SFP_EEPROM_VENDOR_NAME_SIZE, + (u8 *)vendor_name)) vendor_name[0] = '\0'; else vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0'; if (bnx2x_read_sfp_module_eeprom(phy, params, - SFP_EEPROM_PART_NO_ADDR, - SFP_EEPROM_PART_NO_SIZE, - (u8 *)vendor_pn)) + SFP_EEPROM_PART_NO_ADDR, + SFP_EEPROM_PART_NO_SIZE, + (u8 *)vendor_pn)) vendor_pn[0] = '\0'; else vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0'; @@ -4861,15 +4823,14 @@ static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp, u16 cur_limiting_mode; bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER2, - &cur_limiting_mode); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_ROM_VER2, + &cur_limiting_mode); DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n", cur_limiting_mode); if (edc_mode == EDC_MODE_LIMITING) { - DP(NETIF_MSG_LINK, - "Setting LIMITING MODE\n"); + DP(NETIF_MSG_LINK, "Setting LIMITING MODE\n"); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER2, @@ -4885,55 +4846,55 @@ static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp, return 0; bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LRM_MODE, - 0); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_LRM_MODE, + 0); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER2, - 0x128); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_ROM_VER2, + 0x128); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL0, - 0x4008); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_MISC_CTRL0, + 0x4008); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LRM_MODE, - 0xaaaa); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_LRM_MODE, + 0xaaaa); } return 0; } static u8 bnx2x_8727_set_limiting_mode(struct bnx2x *bp, struct bnx2x_phy *phy, - u16 edc_mode) + u16 edc_mode) { u16 phy_identifier; u16 rom_ver2_val; bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - &phy_identifier); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, + &phy_identifier); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - (phy_identifier & ~(1<<9))); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, + (phy_identifier & ~(1<<9))); bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER2, - &rom_ver2_val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_ROM_VER2, + &rom_ver2_val); /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER2, - (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff)); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_ROM_VER2, + (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff)); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - (phy_identifier | (1<<9))); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, + (phy_identifier | (1<<9))); return 0; } @@ -4976,8 +4937,7 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) { DP(NETIF_MSG_LINK, "Failed to get valid module type\n"); return -EINVAL; - } else if (bnx2x_verify_sfp_module(phy, params) != - 0) { + } else if (bnx2x_verify_sfp_module(phy, params) != 0) { /* check SFP+ module compatibility */ DP(NETIF_MSG_LINK, "Module verification failed!!\n"); rc = -EINVAL; @@ -5053,9 +5013,9 @@ void bnx2x_handle_module_detect_int(struct link_params *params) DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n"); } else { u32 val = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, dev_info. - port_feature_config[params->port]. - config)); + offsetof(struct shmem_region, dev_info. + port_feature_config[params->port]. + config)); bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, MISC_REGISTERS_GPIO_INT_OUTPUT_SET, @@ -5126,7 +5086,7 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, u16 cnt, val; struct bnx2x *bp = params->bp; bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); /* HW reset */ bnx2x_ext_phy_hw_reset(bp, params->port); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); @@ -5231,26 +5191,26 @@ static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy, /* Set soft reset */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, + MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL1, 0x0001); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_MISC_CTRL1, 0x0001); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, + MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); /* wait for 150ms for microcode load */ msleep(150); /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL1, 0x0000); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_MISC_CTRL1, 0x0000); msleep(200); bnx2x_save_bcm_spirom_ver(bp, phy, params->port); @@ -5367,7 +5327,7 @@ static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy, /* Set GPIO3 to trigger SFP+ module insertion/removal */ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, - MISC_REGISTERS_GPIO_INPUT_HI_Z, params->port); + MISC_REGISTERS_GPIO_INPUT_HI_Z, params->port); /* The GPIO should be swapped if the swap register is set and active */ swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); @@ -5467,7 +5427,7 @@ static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy, swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); port = (swap_val && swap_override) ^ 1; bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, port); + MISC_REGISTERS_GPIO_OUTPUT_LOW, port); } static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, @@ -5620,8 +5580,8 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, port_feature_config[params->port]. config)); bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs); if (mod_abs & (1<<8)) { /* Module is absent */ @@ -5638,14 +5598,14 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, if (!(phy->flags & FLAGS_NOC)) mod_abs &= ~(1<<9); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); /* Clear RX alarm since it stays up as long as the mod_abs wasn't changed */ bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); } else { /* Module is present */ @@ -6086,7 +6046,7 @@ static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; /* Restore normal power mode*/ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); /* HW reset */ bnx2x_ext_phy_hw_reset(bp, params->port); @@ -6176,8 +6136,8 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, } static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, - struct link_params *params, - struct link_vars *vars) + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; u16 val, val1, val2; @@ -6273,9 +6233,9 @@ static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy, struct link_params *params) { bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, 0); + MISC_REGISTERS_GPIO_OUTPUT_LOW, 0); bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, 1); + MISC_REGISTERS_GPIO_OUTPUT_LOW, 1); } static void bnx2x_8481_link_reset(struct bnx2x_phy *phy, @@ -6297,8 +6257,8 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy, else port = params->port; bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, - MISC_REGISTERS_GPIO_OUTPUT_LOW, - port); + MISC_REGISTERS_GPIO_OUTPUT_LOW, + port); } static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, @@ -6353,24 +6313,24 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, /* Set LED masks */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED1_MASK, - 0x0); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x0); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED2_MASK, - 0x0); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED2_MASK, + 0x0); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED3_MASK, - 0x0); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED3_MASK, + 0x0); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED5_MASK, - 0x20); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED5_MASK, + 0x20); } else { bnx2x_cl45_write(bp, phy, @@ -6394,35 +6354,35 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, val |= 0x2492; bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LINK_SIGNAL, - val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LINK_SIGNAL, + val); /* Set LED masks */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED1_MASK, - 0x0); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x0); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED2_MASK, - 0x20); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED2_MASK, + 0x20); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED3_MASK, - 0x20); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED3_MASK, + 0x20); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED5_MASK, - 0x0); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED5_MASK, + 0x0); } else { bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED1_MASK, - 0x20); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x20); } break; @@ -6440,8 +6400,8 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, &val); if (!((val & - MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK) - >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)){ + MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK) + >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)) { DP(NETIF_MSG_LINK, "Seting LINK_SIGNAL\n"); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, @@ -6451,24 +6411,24 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, /* Set LED masks */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED1_MASK, - 0x10); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x10); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED2_MASK, - 0x80); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED2_MASK, + 0x80); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED3_MASK, - 0x98); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED3_MASK, + 0x98); bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED5_MASK, - 0x40); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED5_MASK, + 0x40); } else { bnx2x_cl45_write(bp, phy, @@ -6513,7 +6473,7 @@ static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy, /* Restore normal power mode*/ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); /* HW reset */ bnx2x_ext_phy_hw_reset(bp, params->port); bnx2x_wait_reset_complete(bp, phy); @@ -6599,20 +6559,20 @@ void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy) u16 val, cnt; bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_7101_RESET, &val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_7101_RESET, &val); for (cnt = 0; cnt < 10; cnt++) { msleep(50); /* Writes a self-clearing reset */ bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_7101_RESET, - (val | (1<<15))); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_7101_RESET, + (val | (1<<15))); /* Wait for clear */ bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_7101_RESET, &val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_7101_RESET, &val); if ((val & (1<<15)) == 0) break; @@ -6623,10 +6583,10 @@ static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy, struct link_params *params) { /* Low power mode is controlled by GPIO 2 */ bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port); + MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port); /* The PHY reset is controlled by GPIO 1 */ bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port); + MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port); } static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy, @@ -6668,9 +6628,9 @@ static struct bnx2x_phy phy_null = { .supported = 0, .media_type = ETH_PHY_NOT_PRESENT, .ver_addr = 0, - .req_flow_ctrl = 0, - .req_line_speed = 0, - .speed_cap_mask = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, .req_duplex = 0, .rsrv = 0, .config_init = (config_init_t)NULL, @@ -6705,8 +6665,8 @@ static struct bnx2x_phy phy_serdes = { .media_type = ETH_PHY_UNSPECIFIED, .ver_addr = 0, .req_flow_ctrl = 0, - .req_line_speed = 0, - .speed_cap_mask = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, .req_duplex = 0, .rsrv = 0, .config_init = (config_init_t)bnx2x_init_serdes, @@ -6742,8 +6702,8 @@ static struct bnx2x_phy phy_xgxs = { .media_type = ETH_PHY_UNSPECIFIED, .ver_addr = 0, .req_flow_ctrl = 0, - .req_line_speed = 0, - .speed_cap_mask = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, .req_duplex = 0, .rsrv = 0, .config_init = (config_init_t)bnx2x_init_xgxs, @@ -6773,8 +6733,8 @@ static struct bnx2x_phy phy_7101 = { .media_type = ETH_PHY_BASE_T, .ver_addr = 0, .req_flow_ctrl = 0, - .req_line_speed = 0, - .speed_cap_mask = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, .req_duplex = 0, .rsrv = 0, .config_init = (config_init_t)bnx2x_7101_config_init, @@ -6804,9 +6764,9 @@ static struct bnx2x_phy phy_8073 = { SUPPORTED_Asym_Pause), .media_type = ETH_PHY_UNSPECIFIED, .ver_addr = 0, - .req_flow_ctrl = 0, - .req_line_speed = 0, - .speed_cap_mask = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, .req_duplex = 0, .rsrv = 0, .config_init = (config_init_t)bnx2x_8073_config_init, @@ -7036,19 +6996,19 @@ static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base, if (phy_index == INT_PHY || phy_index == EXT_PHY1) { rx = REG_RD(bp, shmem_base + offsetof(struct shmem_region, - dev_info.port_hw_config[port].xgxs_config_rx[i<<1])); + dev_info.port_hw_config[port].xgxs_config_rx[i<<1])); tx = REG_RD(bp, shmem_base + offsetof(struct shmem_region, - dev_info.port_hw_config[port].xgxs_config_tx[i<<1])); + dev_info.port_hw_config[port].xgxs_config_tx[i<<1])); } else { rx = REG_RD(bp, shmem_base + offsetof(struct shmem_region, - dev_info.port_hw_config[port].xgxs_config2_rx[i<<1])); + dev_info.port_hw_config[port].xgxs_config2_rx[i<<1])); tx = REG_RD(bp, shmem_base + offsetof(struct shmem_region, - dev_info.port_hw_config[port].xgxs_config2_rx[i<<1])); + dev_info.port_hw_config[port].xgxs_config2_rx[i<<1])); } phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff); @@ -7193,10 +7153,10 @@ static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, phy->ver_addr = shmem_base + offsetof(struct shmem_region, port_mb[port].ext_phy_fw_version); - /* Check specific mdc mdio settings */ - if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK) - mdc_mdio_access = config2 & - SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK; + /* Check specific mdc mdio settings */ + if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK) + mdc_mdio_access = config2 & + SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK; } else { u32 size = REG_RD(bp, shmem2_base); @@ -7250,18 +7210,20 @@ static void bnx2x_phy_def_cfg(struct link_params *params, /* Populate the default phy configuration for MF mode */ if (phy_index == EXT_PHY2) { link_config = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, dev_info. + offsetof(struct shmem_region, dev_info. port_feature_config[params->port].link_config2)); phy->speed_cap_mask = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, dev_info. + offsetof(struct shmem_region, + dev_info. port_hw_config[params->port].speed_capability_mask2)); } else { link_config = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, dev_info. + offsetof(struct shmem_region, dev_info. port_feature_config[params->port].link_config)); phy->speed_cap_mask = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, dev_info. - port_hw_config[params->port].speed_capability_mask)); + offsetof(struct shmem_region, + dev_info. + port_hw_config[params->port].speed_capability_mask)); } DP(NETIF_MSG_LINK, "Default config phy idx %x cfg 0x%x speed_cap_mask" " 0x%x\n", phy_index, link_config, phy->speed_cap_mask); @@ -7408,7 +7370,7 @@ static void set_phy_vars(struct link_params *params) else if (phy_index == EXT_PHY2) actual_phy_idx = EXT_PHY1; } - params->phy[actual_phy_idx].req_flow_ctrl = + params->phy[actual_phy_idx].req_flow_ctrl = params->req_flow_ctrl[link_cfg_idx]; params->phy[actual_phy_idx].req_line_speed = @@ -7527,8 +7489,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) /* set bmac loopback */ bnx2x_bmac_enable(params, vars, 1); - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + - params->port*4, 0); + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); } else if (params->loopback_mode == LOOPBACK_EMAC) { @@ -7544,8 +7505,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) /* set bmac loopback */ bnx2x_emac_enable(params, vars, 1); bnx2x_emac_program(params, vars); - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + - params->port*4, 0); + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); } else if ((params->loopback_mode == LOOPBACK_XGXS) || (params->loopback_mode == LOOPBACK_EXT_PHY)) { @@ -7568,8 +7528,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) bnx2x_emac_program(params, vars); bnx2x_emac_enable(params, vars, 0); } else - bnx2x_bmac_enable(params, vars, 0); - + bnx2x_bmac_enable(params, vars, 0); if (params->loopback_mode == LOOPBACK_XGXS) { /* set 10G XGXS loopback */ params->phy[INT_PHY].config_loopback( @@ -7587,9 +7546,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) params); } } - - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + - params->port*4, 0); + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed); @@ -7608,7 +7565,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) return 0; } u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, - u8 reset_ext_phy) + u8 reset_ext_phy) { struct bnx2x *bp = params->bp; u8 phy_index, port = params->port, clear_latch_ind = 0; @@ -7617,10 +7574,10 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, vars->link_status = 0; bnx2x_update_mng(params, vars->link_status); bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, - (NIG_MASK_XGXS0_LINK_STATUS | - NIG_MASK_XGXS0_LINK10G | - NIG_MASK_SERDES0_LINK_STATUS | - NIG_MASK_MI_INT)); + (NIG_MASK_XGXS0_LINK_STATUS | + NIG_MASK_XGXS0_LINK10G | + NIG_MASK_SERDES0_LINK_STATUS | + NIG_MASK_MI_INT)); /* activate nig drain */ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); @@ -7719,21 +7676,22 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, /* disable attentions */ bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port_of_path*4, - (NIG_MASK_XGXS0_LINK_STATUS | - NIG_MASK_XGXS0_LINK10G | - NIG_MASK_SERDES0_LINK_STATUS | - NIG_MASK_MI_INT)); + (NIG_MASK_XGXS0_LINK_STATUS | + NIG_MASK_XGXS0_LINK10G | + NIG_MASK_SERDES0_LINK_STATUS | + NIG_MASK_MI_INT)); /* Need to take the phy out of low power mode in order to write to access its registers */ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); + MISC_REGISTERS_GPIO_OUTPUT_HIGH, + port); /* Reset the phy */ bnx2x_cl45_write(bp, &phy[port], - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, - 1<<15); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_CTRL, + 1<<15); } /* Add delay of 150ms after reset */ @@ -7762,14 +7720,14 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, /* Only set bit 10 = 1 (Tx power down) */ bnx2x_cl45_read(bp, phy_blk[port], - MDIO_PMA_DEVAD, - MDIO_PMA_REG_TX_POWER_DOWN, &val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_TX_POWER_DOWN, &val); /* Phase1 of TX_POWER_DOWN reset */ bnx2x_cl45_write(bp, phy_blk[port], - MDIO_PMA_DEVAD, - MDIO_PMA_REG_TX_POWER_DOWN, - (val | 1<<10)); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_TX_POWER_DOWN, + (val | 1<<10)); } /* Toggle Transmitter: Power down and then up with 600ms @@ -7781,25 +7739,25 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, /* Phase2 of POWER_DOWN_RESET */ /* Release bit 10 (Release Tx power down) */ bnx2x_cl45_read(bp, phy_blk[port], - MDIO_PMA_DEVAD, - MDIO_PMA_REG_TX_POWER_DOWN, &val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_TX_POWER_DOWN, &val); bnx2x_cl45_write(bp, phy_blk[port], - MDIO_PMA_DEVAD, - MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10)))); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10)))); msleep(15); /* Read modify write the SPI-ROM version select register */ bnx2x_cl45_read(bp, phy_blk[port], - MDIO_PMA_DEVAD, - MDIO_PMA_REG_EDC_FFE_MAIN, &val); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_EDC_FFE_MAIN, &val); bnx2x_cl45_write(bp, phy_blk[port], - MDIO_PMA_DEVAD, - MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12))); + MDIO_PMA_DEVAD, + MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12))); /* set GPIO2 back to LOW */ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_LOW, port); + MISC_REGISTERS_GPIO_OUTPUT_LOW, port); } return 0; } @@ -7846,8 +7804,8 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, /* Set fault module detected LED on */ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, - MISC_REGISTERS_GPIO_HIGH, - port); + MISC_REGISTERS_GPIO_HIGH, + port); } return 0; @@ -7862,8 +7820,8 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, struct bnx2x_phy phy[PORT_MAX]; struct bnx2x_phy *phy_blk[PORT_MAX]; s8 port_of_path; - swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); - swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); + swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); + swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); port = 1; @@ -7907,9 +7865,7 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, /* Reset the phy */ bnx2x_cl45_write(bp, &phy[port], - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, - 1<<15); + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); } /* Add delay of 150ms after reset */ @@ -7923,7 +7879,7 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, } /* PART2 - Download firmware to both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { - if (CHIP_IS_E2(bp)) + if (CHIP_IS_E2(bp)) port_of_path = 0; else port_of_path = port; diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index bedab1a942c4..d9e847bb96f8 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -1,4 +1,4 @@ -/* Copyright 2008-2010 Broadcom Corporation +/* Copyright 2008-2011 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -33,7 +33,7 @@ #define BNX2X_FLOW_CTRL_BOTH PORT_FEATURE_FLOW_CONTROL_BOTH #define BNX2X_FLOW_CTRL_NONE PORT_FEATURE_FLOW_CONTROL_NONE -#define SPEED_AUTO_NEG 0 +#define SPEED_AUTO_NEG 0 #define SPEED_12000 12000 #define SPEED_12500 12500 #define SPEED_13000 13000 @@ -44,8 +44,8 @@ #define SFP_EEPROM_VENDOR_NAME_SIZE 16 #define SFP_EEPROM_VENDOR_OUI_ADDR 0x25 #define SFP_EEPROM_VENDOR_OUI_SIZE 3 -#define SFP_EEPROM_PART_NO_ADDR 0x28 -#define SFP_EEPROM_PART_NO_SIZE 16 +#define SFP_EEPROM_PART_NO_ADDR 0x28 +#define SFP_EEPROM_PART_NO_SIZE 16 #define PWR_FLT_ERR_MSG_LEN 250 #define XGXS_EXT_PHY_TYPE(ext_phy_config) \ @@ -62,7 +62,7 @@ #define SINGLE_MEDIA(params) (params->num_phys == 2) /* Dual Media board contains two external phy with different media */ #define DUAL_MEDIA(params) (params->num_phys == 3) -#define FW_PARAM_MDIO_CTRL_OFFSET 16 +#define FW_PARAM_MDIO_CTRL_OFFSET 16 #define FW_PARAM_SET(phy_addr, phy_type, mdio_access) \ (phy_addr | phy_type | mdio_access << FW_PARAM_MDIO_CTRL_OFFSET) @@ -201,12 +201,14 @@ struct link_params { /* Default / User Configuration */ u8 loopback_mode; -#define LOOPBACK_NONE 0 -#define LOOPBACK_EMAC 1 -#define LOOPBACK_BMAC 2 +#define LOOPBACK_NONE 0 +#define LOOPBACK_EMAC 1 +#define LOOPBACK_BMAC 2 #define LOOPBACK_XGXS 3 #define LOOPBACK_EXT_PHY 4 -#define LOOPBACK_EXT 5 +#define LOOPBACK_EXT 5 +#define LOOPBACK_UMAC 6 +#define LOOPBACK_XMAC 7 /* Device parameters */ u8 mac_addr[6]; @@ -230,10 +232,11 @@ struct link_params { /* Phy register parameter */ u32 chip_id; + /* features */ u32 feature_config_flags; -#define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0) -#define FEATURE_CONFIG_PFC_ENABLED (1<<1) -#define FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY (1<<2) +#define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0) +#define FEATURE_CONFIG_PFC_ENABLED (1<<1) +#define FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY (1<<2) #define FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY (1<<3) /* Will be populated during common init */ struct bnx2x_phy phy[MAX_PHYS]; @@ -379,7 +382,7 @@ void bnx2x_ets_disabled(struct link_params *params); /* Used to configure the ETS to BW limited */ void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw, - const u32 cos1_bw); + const u32 cos1_bw); /* Used to configure the ETS to strict */ u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos); -- cgit v1.2.3 From cd2be89b8ed7a50b781fae43a43f20d6ef1a137b Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Mon, 31 Jan 2011 04:21:45 +0000 Subject: bnx2x: Rename CL45 macro This patch contains cosmetic changes only of renaming CL45_WR_OVER_CL22 macro to CL22_WR_OVER_CL45 as it should be. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 133 ++++++++++++++++++++--------------------- 1 file changed, 66 insertions(+), 67 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index e992d40e2462..3be2ce03804a 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -171,13 +171,13 @@ /* INTERFACE */ /**********************************************************/ -#define CL45_WR_OVER_CL22(_bp, _phy, _bank, _addr, _val) \ +#define CL22_WR_OVER_CL45(_bp, _phy, _bank, _addr, _val) \ bnx2x_cl45_write(_bp, _phy, \ (_phy)->def_md_devad, \ (_bank + (_addr & 0xf)), \ _val) -#define CL45_RD_OVER_CL22(_bp, _phy, _bank, _addr, _val) \ +#define CL22_RD_OVER_CL45(_bp, _phy, _bank, _addr, _val) \ bnx2x_cl45_read(_bp, _phy, \ (_phy)->def_md_devad, \ (_bank + (_addr & 0xf)), \ @@ -1553,13 +1553,13 @@ static void bnx2x_set_aer_mmd_xgxs(struct link_params *params, aer_val = 0x3800 + offset - 1; else aer_val = 0x3800 + offset; - CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_AER_BLOCK, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, MDIO_AER_BLOCK_AER_REG, aer_val); } static void bnx2x_set_aer_mmd_serdes(struct bnx2x *bp, struct bnx2x_phy *phy) { - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, MDIO_AER_BLOCK_AER_REG, 0x3800); } @@ -1758,12 +1758,12 @@ static void bnx2x_set_master_ln(struct link_params *params, PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); /* set the master_ln for AN */ - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2, MDIO_XGXS_BLOCK2_TEST_MODE_LANE, &new_master_ln); - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2 , MDIO_XGXS_BLOCK2_TEST_MODE_LANE, (new_master_ln | ser_lane)); @@ -1776,13 +1776,12 @@ static u8 bnx2x_reset_unicore(struct link_params *params, struct bnx2x *bp = params->bp; u16 mii_control; u16 i; - - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control); /* reset the unicore */ - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, (mii_control | @@ -1795,7 +1794,7 @@ static u8 bnx2x_reset_unicore(struct link_params *params, udelay(5); /* the reset erased the previous bank value */ - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control); @@ -1830,26 +1829,26 @@ static void bnx2x_set_swap_lanes(struct link_params *params, PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT); if (rx_lane_swap != 0x1b) { - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2, MDIO_XGXS_BLOCK2_RX_LN_SWAP, (rx_lane_swap | MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE | MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE)); } else { - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2, MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0); } if (tx_lane_swap != 0x1b) { - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2, MDIO_XGXS_BLOCK2_TX_LN_SWAP, (tx_lane_swap | MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE)); } else { - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2, MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0); } @@ -1860,7 +1859,7 @@ static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; u16 control2; - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, &control2); @@ -1870,7 +1869,7 @@ static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy, control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN; DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n", phy->speed_cap_mask, control2); - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, control2); @@ -1880,12 +1879,12 @@ static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy, PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { DP(NETIF_MSG_LINK, "XGXS\n"); - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_10G_PARALLEL_DETECT, MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK, MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT); - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_10G_PARALLEL_DETECT, MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, &control2); @@ -1894,13 +1893,13 @@ static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy, control2 |= MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN; - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_10G_PARALLEL_DETECT, MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, control2); /* Disable parallel detection of HiG */ - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2, MDIO_XGXS_BLOCK2_UNICORE_MODE_10G, MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS | @@ -1917,7 +1916,7 @@ static void bnx2x_set_autoneg(struct bnx2x_phy *phy, u16 reg_val; /* CL37 Autoneg */ - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, ®_val); @@ -1928,13 +1927,13 @@ static void bnx2x_set_autoneg(struct bnx2x_phy *phy, reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN); - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, reg_val); /* Enable/Disable Autodetection */ - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val); reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN | @@ -1945,12 +1944,12 @@ static void bnx2x_set_autoneg(struct bnx2x_phy *phy, else reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET; - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val); /* Enable TetonII and BAM autoneg */ - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_BAM_NEXT_PAGE, MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, ®_val); @@ -1963,20 +1962,20 @@ static void bnx2x_set_autoneg(struct bnx2x_phy *phy, reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE | MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN); } - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_BAM_NEXT_PAGE, MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, reg_val); if (enable_cl73) { /* Enable Cl73 FSM status bits */ - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_CL73_USERB0, MDIO_CL73_USERB0_CL73_UCTRL, 0xe); /* Enable BAM Station Manager*/ - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_CL73_USERB0, MDIO_CL73_USERB0_CL73_BAM_CTRL1, MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN | @@ -1984,7 +1983,7 @@ static void bnx2x_set_autoneg(struct bnx2x_phy *phy, MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN); /* Advertise CL73 link speeds */ - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_ADV2, ®_val); @@ -1995,7 +1994,7 @@ static void bnx2x_set_autoneg(struct bnx2x_phy *phy, PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX; - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_ADV2, reg_val); @@ -2006,7 +2005,7 @@ static void bnx2x_set_autoneg(struct bnx2x_phy *phy, } else /* CL73 Autoneg Disabled */ reg_val = 0; - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_CL73_IEEEB0, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val); } @@ -2020,7 +2019,7 @@ static void bnx2x_program_serdes(struct bnx2x_phy *phy, u16 reg_val; /* program duplex, disable autoneg and sgmii*/ - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, ®_val); reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX | @@ -2028,13 +2027,13 @@ static void bnx2x_program_serdes(struct bnx2x_phy *phy, MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK); if (phy->req_duplex == DUPLEX_FULL) reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX; - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, reg_val); /* program speed - needed only if the speed is greater than 1G (2.5G or 10G) */ - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_MISC1, ®_val); /* clearing the speed value before setting the right speed */ @@ -2057,7 +2056,7 @@ static void bnx2x_program_serdes(struct bnx2x_phy *phy, MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G; } - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_MISC1, reg_val); @@ -2076,11 +2075,11 @@ static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x_phy *phy, val |= MDIO_OVER_1G_UP1_2_5G; if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) val |= MDIO_OVER_1G_UP1_10G; - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_OVER_1G, MDIO_OVER_1G_UP1, val); - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_OVER_1G, MDIO_OVER_1G_UP3, 0x400); } @@ -2126,15 +2125,15 @@ static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x_phy *phy, u16 val; /* for AN, we are always publishing full duplex */ - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc); - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_ADV1, &val); val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH; val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK); - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_ADV1, val); } @@ -2150,12 +2149,12 @@ static void bnx2x_restart_autoneg(struct bnx2x_phy *phy, /* Enable and restart BAM/CL37 aneg */ if (enable_cl73) { - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_CL73_IEEEB0, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, &mii_control); - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_CL73_IEEEB0, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, (mii_control | @@ -2163,14 +2162,14 @@ static void bnx2x_restart_autoneg(struct bnx2x_phy *phy, MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN)); } else { - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control); DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg mii_control before = 0x%x\n", mii_control); - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, (mii_control | @@ -2188,7 +2187,7 @@ static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy, /* in SGMII mode, the unicore is always slave */ - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &control1); @@ -2197,7 +2196,7 @@ static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy, control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE | MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET | MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE); - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, control1); @@ -2207,7 +2206,7 @@ static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy, /* set speed, disable autoneg */ u16 mii_control; - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control); @@ -2238,7 +2237,7 @@ static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy, if (phy->req_duplex == DUPLEX_FULL) mii_control |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX; - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, mii_control); @@ -2288,11 +2287,11 @@ static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy, u16 pd_10g, status2_1000x; if (phy->req_line_speed != SPEED_AUTO_NEG) return 0; - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_STATUS2, &status2_1000x); - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_STATUS2, &status2_1000x); @@ -2302,7 +2301,7 @@ static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy, return 1; } - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_10G_PARALLEL_DETECT, MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS, &pd_10g); @@ -2344,11 +2343,11 @@ static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy, (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) { - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_ADV1, &ld_pause); - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_LP_ADV1, &lp_pause); @@ -2361,11 +2360,11 @@ static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n", pause_result); } else { - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_AUTO_NEG_ADV, &ld_pause); - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1, &lp_pause); @@ -2388,7 +2387,7 @@ static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy, u16 rx_status, ustat_val, cl37_fsm_recieved; DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n"); /* Step 1: Make sure signal is detected */ - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_RX0, MDIO_RX0_RX_STATUS, &rx_status); @@ -2396,14 +2395,14 @@ static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy, (MDIO_RX0_RX_STATUS_SIGDET)) { DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73." "rx_status(0x80b0) = 0x%x\n", rx_status); - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_CL73_IEEEB0, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN); return; } /* Step 2: Check CL73 state machine */ - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_CL73_USERB0, MDIO_CL73_USERB0_CL73_USTAT1, &ustat_val); @@ -2418,7 +2417,7 @@ static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy, } /* Step 3: Check CL37 Message Pages received to indicate LP supports only CL37 */ - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_REMOTE_PHY, MDIO_REMOTE_PHY_MISC_RX_STATUS, &cl37_fsm_recieved); @@ -2436,7 +2435,7 @@ static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy, connected to a device which does not support cl73, but does support cl37 BAM. In this case we disable cl73 and restart cl37 auto-neg */ /* Disable CL73 */ - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_CL73_IEEEB0, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, 0); @@ -2468,7 +2467,7 @@ static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy, u8 rc = 0; /* Read gp_status */ - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_GP_STATUS, MDIO_GP_STATUS_TOP_AN_STATUS1, &gp_status); @@ -2608,7 +2607,7 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params) u16 bank; /* read precomp */ - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_OVER_1G, MDIO_OVER_1G_LP_UP2, &lp_up2); @@ -2622,7 +2621,7 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params) for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3; bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) { - CL45_RD_OVER_CL22(bp, phy, + CL22_RD_OVER_CL45(bp, phy, bank, MDIO_TX0_TX_DRIVER, &tx_driver); @@ -2631,7 +2630,7 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params) (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) { tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK; tx_driver |= lp_up2; - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, bank, MDIO_TX0_TX_DRIVER, tx_driver); } @@ -2694,7 +2693,7 @@ static void bnx2x_set_preemphasis(struct bnx2x_phy *phy, for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3; bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) { - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, bank, MDIO_RX0_RX_EQ_BOOST, phy->rx_preemphasis[i]); @@ -2702,7 +2701,7 @@ static void bnx2x_set_preemphasis(struct bnx2x_phy *phy, for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3; bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) { - CL45_WR_OVER_CL22(bp, phy, + CL22_WR_OVER_CL45(bp, phy, bank, MDIO_TX0_TX_DRIVER, phy->tx_preemphasis[i]); @@ -3208,7 +3207,7 @@ u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars, u8 ext_phy_link_up = 0, serdes_phy_type; struct link_vars temp_vars; - CL45_RD_OVER_CL22(bp, ¶ms->phy[INT_PHY], + CL22_RD_OVER_CL45(bp, ¶ms->phy[INT_PHY], MDIO_REG_BANK_GP_STATUS, MDIO_GP_STATUS_TOP_AN_STATUS1, &gp_status); -- cgit v1.2.3 From 2cf7acf98ef8327588e49bf74b7653ca4a063f09 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Mon, 31 Jan 2011 04:21:55 +0000 Subject: bnx2x: Set comments according to preferred Linux style This patch contains cosmetic changes only of restyling comments according to Linux coding standard, and add comment for get_emac_base function. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 651 +++++++++++++++++++++++------------------ 1 file changed, 364 insertions(+), 287 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 3be2ce03804a..9fadcdbe4115 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -217,7 +217,7 @@ void bnx2x_ets_disabled(struct link_params *params) DP(NETIF_MSG_LINK, "ETS disabled configuration\n"); - /** + /* * mapping between entry priority to client number (0,1,2 -debug and * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST) * 3bits client num. @@ -226,7 +226,7 @@ void bnx2x_ets_disabled(struct link_params *params) */ REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688); - /** + /* * Bitmap of 5bits length. Each bit specifies whether the entry behaves * as strict. Bits 0,1,2 - debug and management entries, 3 - * COS0 entry, 4 - COS1 entry. @@ -238,12 +238,12 @@ void bnx2x_ets_disabled(struct link_params *params) REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7); /* defines which entries (clients) are subjected to WFQ arbitration */ REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0); - /** - * For strict priority entries defines the number of consecutive - * slots for the highest priority. - */ + /* + * For strict priority entries defines the number of consecutive + * slots for the highest priority. + */ REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100); - /** + /* * mapping between the CREDIT_WEIGHT registers and actual client * numbers */ @@ -256,7 +256,7 @@ void bnx2x_ets_disabled(struct link_params *params) REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0); /* ETS mode disable */ REG_WR(bp, PBF_REG_ETS_ENABLED, 0); - /** + /* * If ETS mode is enabled (there is no strict priority) defines a WFQ * weight for COS0/COS1. */ @@ -274,19 +274,19 @@ void bnx2x_ets_bw_limit_common(const struct link_params *params) /* ETS disabled configuration */ struct bnx2x *bp = params->bp; DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n"); - /** - * defines which entries (clients) are subjected to WFQ arbitration - * COS0 0x8 - * COS1 0x10 - */ + /* + * defines which entries (clients) are subjected to WFQ arbitration + * COS0 0x8 + * COS1 0x10 + */ REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18); - /** - * mapping between the ARB_CREDIT_WEIGHT registers and actual - * client numbers (WEIGHT_0 does not actually have to represent - * client 0) - * PRI4 | PRI3 | PRI2 | PRI1 | PRI0 - * cos1-001 cos0-000 dbg1-100 dbg0-011 MCP-010 - */ + /* + * mapping between the ARB_CREDIT_WEIGHT registers and actual + * client numbers (WEIGHT_0 does not actually have to represent + * client 0) + * PRI4 | PRI3 | PRI2 | PRI1 | PRI0 + * cos1-001 cos0-000 dbg1-100 dbg0-011 MCP-010 + */ REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A); REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, @@ -299,14 +299,14 @@ void bnx2x_ets_bw_limit_common(const struct link_params *params) /* Defines the number of consecutive slots for the strict priority */ REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0); - /** - * Bitmap of 5bits length. Each bit specifies whether the entry behaves - * as strict. Bits 0,1,2 - debug and management entries, 3 - COS0 - * entry, 4 - COS1 entry. - * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT - * bit4 bit3 bit2 bit1 bit0 - * MCP and debug are strict - */ + /* + * Bitmap of 5bits length. Each bit specifies whether the entry behaves + * as strict. Bits 0,1,2 - debug and management entries, 3 - COS0 + * entry, 4 - COS1 entry. + * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT + * bit4 bit3 bit2 bit1 bit0 + * MCP and debug are strict + */ REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7); /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/ @@ -355,7 +355,7 @@ u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos) u32 val = 0; DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n"); - /** + /* * Bitmap of 5bits length. Each bit specifies whether the entry behaves * as strict. Bits 0,1,2 - debug and management entries, * 3 - COS0 entry, 4 - COS1 entry. @@ -364,7 +364,7 @@ u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos) * MCP and debug are strict */ REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F); - /** + /* * For strict priority entries defines the number of consecutive slots * for the highest priority. */ @@ -377,14 +377,14 @@ u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos) /* Defines the number of consecutive slots for the strict priority */ REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos); - /** - * mapping between entry priority to client number (0,1,2 -debug and - * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST) - * 3bits client num. - * PRI4 | PRI3 | PRI2 | PRI1 | PRI0 - * dbg0-010 dbg1-001 cos1-100 cos0-011 MCP-000 - * dbg0-010 dbg1-001 cos0-011 cos1-100 MCP-000 - */ + /* + * mapping between entry priority to client number (0,1,2 -debug and + * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST) + * 3bits client num. + * PRI4 | PRI3 | PRI2 | PRI1 | PRI0 + * dbg0-010 dbg1-001 cos1-100 cos0-011 MCP-000 + * dbg0-010 dbg1-001 cos0-011 cos1-100 MCP-000 + */ val = (0 == strict_cos) ? 0x2318 : 0x22E0; REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val); @@ -599,14 +599,14 @@ static u8 bnx2x_emac_enable(struct link_params *params, val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE); val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS; - /** - * Setting this bit causes MAC control frames (except for pause - * frames) to be passed on for processing. This setting has no - * affect on the operation of the pause frames. This bit effects - * all packets regardless of RX Parser packet sorting logic. - * Turn the PFC off to make sure we are in Xon state before - * enabling it. - */ + /* + * Setting this bit causes MAC control frames (except for pause + * frames) to be passed on for processing. This setting has no + * affect on the operation of the pause frames. This bit effects + * all packets regardless of RX Parser packet sorting logic. + * Turn the PFC off to make sure we are in Xon state before + * enabling it. + */ EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0); if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) { DP(NETIF_MSG_LINK, "PFC is enabled\n"); @@ -760,12 +760,12 @@ static void bnx2x_update_pfc_bmac2(struct link_params *params, REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2); - /** - * Set Time (based unit is 512 bit time) between automatic - * re-sending of PP packets amd enable automatic re-send of - * Per-Priroity Packet as long as pp_gen is asserted and - * pp_disable is low. - */ + /* + * Set Time (based unit is 512 bit time) between automatic + * re-sending of PP packets amd enable automatic re-send of + * Per-Priroity Packet as long as pp_gen is asserted and + * pp_disable is low. + */ val = 0x8000; if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) val |= (1<<16); /* enable automatic re-send */ @@ -816,17 +816,25 @@ static void bnx2x_update_pfc_brb(struct link_params *params, full_xon_th = PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE; } - /* The number of free blocks below which the pause signal to class 0 - of MAC #n is asserted. n=0,1 */ + /* + * The number of free blocks below which the pause signal to class 0 + * of MAC #n is asserted. n=0,1 + */ REG_WR(bp, BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 , pause_xoff_th); - /* The number of free blocks above which the pause signal to class 0 - of MAC #n is de-asserted. n=0,1 */ + /* + * The number of free blocks above which the pause signal to class 0 + * of MAC #n is de-asserted. n=0,1 + */ REG_WR(bp, BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , pause_xon_th); - /* The number of free blocks below which the full signal to class 0 - of MAC #n is asserted. n=0,1 */ + /* + * The number of free blocks below which the full signal to class 0 + * of MAC #n is asserted. n=0,1 + */ REG_WR(bp, BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , full_xoff_th); - /* The number of free blocks above which the full signal to class 0 - of MAC #n is de-asserted. n=0,1 */ + /* + * The number of free blocks above which the full signal to class 0 + * of MAC #n is de-asserted. n=0,1 + */ REG_WR(bp, BRB1_REG_FULL_0_XON_THRESHOLD_0 , full_xon_th); if (set_pfc && pfc_params) { @@ -850,25 +858,25 @@ static void bnx2x_update_pfc_brb(struct link_params *params, full_xon_th = PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE; } - /** + /* * The number of free blocks below which the pause signal to * class 1 of MAC #n is asserted. n=0,1 - **/ + */ REG_WR(bp, BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0, pause_xoff_th); - /** + /* * The number of free blocks above which the pause signal to * class 1 of MAC #n is de-asserted. n=0,1 - **/ + */ REG_WR(bp, BRB1_REG_PAUSE_1_XON_THRESHOLD_0, pause_xon_th); - /** + /* * The number of free blocks below which the full signal to * class 1 of MAC #n is asserted. n=0,1 - **/ + */ REG_WR(bp, BRB1_REG_FULL_1_XOFF_THRESHOLD_0, full_xoff_th); - /** + /* * The number of free blocks above which the full signal to * class 1 of MAC #n is de-asserted. n=0,1 - **/ + */ REG_WR(bp, BRB1_REG_FULL_1_XON_THRESHOLD_0, full_xon_th); } } @@ -887,7 +895,7 @@ static void bnx2x_update_pfc_nig(struct link_params *params, FEATURE_CONFIG_PFC_ENABLED; DP(NETIF_MSG_LINK, "updating pfc nig parameters\n"); - /** + /* * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set * MAC control frames (that are not pause packets) * will be forwarded to the XCM. @@ -895,7 +903,7 @@ static void bnx2x_update_pfc_nig(struct link_params *params, xcm_mask = REG_RD(bp, port ? NIG_REG_LLH1_XCM_MASK : NIG_REG_LLH0_XCM_MASK); - /** + /* * nig params will override non PFC params, since it's possible to * do transition from PFC to SAFC */ @@ -985,7 +993,7 @@ void bnx2x_update_pfc(struct link_params *params, struct link_vars *vars, struct bnx2x_nig_brb_pfc_port_params *pfc_params) { - /** + /* * The PFC and pause are orthogonal to one another, meaning when * PFC is enabled, the pause are disabled, and when PFC is * disabled, pause are set according to the pause result. @@ -1331,6 +1339,23 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl, return 0; } +/* + * get_emac_base + * + * @param cb + * @param mdc_mdio_access + * @param port + * + * @return u32 + * + * This function selects the MDC/MDIO access (through emac0 or + * emac1) depend on the mdc_mdio_access, port, port swapped. Each + * phy has a default access mode, which could also be overridden + * by nvram configuration. This parameter, whether this is the + * default phy configuration, or the nvram overrun + * configuration, is passed here as mdc_mdio_access and selects + * the emac_base for the CL45 read/writes operations + */ static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 mdc_mdio_access, u8 port) { @@ -1363,13 +1388,16 @@ static u32 bnx2x_get_emac_base(struct bnx2x *bp, } +/******************************************************************/ +/* CL45 access functions */ +/******************************************************************/ u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, u8 devad, u16 reg, u16 val) { u32 tmp, saved_mode; u8 i, rc = 0; - - /* set clause 45 mode, slow down the MDIO clock to 2.5MHz + /* + * Set clause 45 mode, slow down the MDIO clock to 2.5MHz * (a value of 49==0x31) and make sure that the AUTO poll is off */ @@ -1436,8 +1464,8 @@ u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, u32 val, saved_mode; u16 i; u8 rc = 0; - - /* set clause 45 mode, slow down the MDIO clock to 2.5MHz + /* + * Set clause 45 mode, slow down the MDIO clock to 2.5MHz * (a value of 49==0x31) and make sure that the AUTO poll is off */ @@ -1506,7 +1534,7 @@ u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr, u8 devad, u16 reg, u16 *ret_val) { u8 phy_index; - /** + /* * Probe for the phy according to the given phy_addr, and execute * the read request on it */ @@ -1524,7 +1552,7 @@ u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr, u8 devad, u16 reg, u16 val) { u8 phy_index; - /** + /* * Probe for the phy according to the given phy_addr, and execute * the write request on it */ @@ -1814,8 +1842,10 @@ static void bnx2x_set_swap_lanes(struct link_params *params, struct bnx2x_phy *phy) { struct bnx2x *bp = params->bp; - /* Each two bits represents a lane number: - No swap is 0123 => 0x1b no need to enable the swap */ + /* + * Each two bits represents a lane number: + * No swap is 0123 => 0x1b no need to enable the swap + */ u16 ser_lane, rx_lane_swap, tx_lane_swap; ser_lane = ((params->lane_config & @@ -2031,8 +2061,10 @@ static void bnx2x_program_serdes(struct bnx2x_phy *phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, reg_val); - /* program speed - - needed only if the speed is greater than 1G (2.5G or 10G) */ + /* + * program speed + * - needed only if the speed is greater than 1G (2.5G or 10G) + */ CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_MISC1, ®_val); @@ -2089,8 +2121,10 @@ static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX; - /* resolve pause mode and advertisement - * Please refer to Table 28B-3 of the 802.3ab-1999 spec */ + /* + * Resolve pause mode and advertisement. + * Please refer to Table 28B-3 of the 802.3ab-1999 spec + */ switch (phy->req_flow_ctrl) { case BNX2X_FLOW_CTRL_AUTO: @@ -2415,8 +2449,10 @@ static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy, "ustat_val(0x8371) = 0x%x\n", ustat_val); return; } - /* Step 3: Check CL37 Message Pages received to indicate LP - supports only CL37 */ + /* + * Step 3: Check CL37 Message Pages received to indicate LP + * supports only CL37 + */ CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_REMOTE_PHY, MDIO_REMOTE_PHY_MISC_RX_STATUS, @@ -2431,9 +2467,13 @@ static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy, cl37_fsm_recieved); return; } - /* The combined cl37/cl73 fsm state information indicating that we are - connected to a device which does not support cl73, but does support - cl37 BAM. In this case we disable cl73 and restart cl37 auto-neg */ + /* + * The combined cl37/cl73 fsm state information indicating that + * we are connected to a device which does not support cl73, but + * does support cl37 BAM. In this case we disable cl73 and + * restart cl37 auto-neg + */ + /* Disable CL73 */ CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_CL73_IEEEB0, @@ -2833,9 +2873,7 @@ static void bnx2x_link_int_enable(struct link_params *params) u32 mask; struct bnx2x *bp = params->bp; - /* setting the status to report on link up - for either XGXS or SerDes */ - + /* Setting the status to report on link up for either XGXS or SerDes */ if (params->switch_cfg == SWITCH_CFG_10G) { mask = (NIG_MASK_XGXS0_LINK10G | NIG_MASK_XGXS0_LINK_STATUS); @@ -2878,7 +2916,7 @@ static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port, { u32 latch_status = 0; - /** + /* * Disable the MI INT ( external phy int ) by writing 1 to the * status register. Link down indication is high-active-signal, * so in this case we need to write the status to clear the XOR @@ -2914,16 +2952,19 @@ static void bnx2x_link_int_ack(struct link_params *params, struct bnx2x *bp = params->bp; u8 port = params->port; - /* first reset all status - * we assume only one line will be change at a time */ + /* + * First reset all status we assume only one line will be + * change at a time + */ bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, (NIG_STATUS_XGXS0_LINK10G | NIG_STATUS_XGXS0_LINK_STATUS | NIG_STATUS_SERDES0_LINK_STATUS)); if (vars->phy_link_up) { if (is_10g) { - /* Disable the 10G link interrupt - * by writing 1 to the status register + /* + * Disable the 10G link interrupt by writing 1 to the + * status register */ DP(NETIF_MSG_LINK, "10G XGXS phy link up\n"); bnx2x_bits_en(bp, @@ -2931,9 +2972,9 @@ static void bnx2x_link_int_ack(struct link_params *params, NIG_STATUS_XGXS0_LINK10G); } else if (params->switch_cfg == SWITCH_CFG_10G) { - /* Disable the link interrupt - * by writing 1 to the relevant lane - * in the status register + /* + * Disable the link interrupt by writing 1 to the + * relevant lane in the status register */ u32 ser_lane = ((params->lane_config & PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> @@ -2948,8 +2989,9 @@ static void bnx2x_link_int_ack(struct link_params *params, } else { /* SerDes */ DP(NETIF_MSG_LINK, "SerDes phy link up\n"); - /* Disable the link interrupt - * by writing 1 to the status register + /* + * Disable the link interrupt by writing 1 to the status + * register */ bnx2x_bits_en(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, @@ -3126,19 +3168,19 @@ u8 bnx2x_set_led(struct link_params *params, break; case LED_MODE_OPER: - /** + /* * For all other phys, OPER mode is same as ON, so in case * link is down, do nothing - **/ + */ if (!vars->link_up) break; case LED_MODE_ON: if (params->phy[EXT_PHY1].type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727 && CHIP_IS_E2(bp) && params->num_phys == 2) { - /** - * This is a work-around for E2+8727 Configurations - */ + /* + * This is a work-around for E2+8727 Configurations + */ if (mode == LED_MODE_ON || speed == SPEED_10000){ REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0); @@ -3150,10 +3192,10 @@ u8 bnx2x_set_led(struct link_params *params, return rc; } } else if (SINGLE_MEDIA_DIRECT(params)) { - /** - * This is a work-around for HW issue found when link - * is up in CL73 - */ + /* + * This is a work-around for HW issue found when link + * is up in CL73 + */ REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0); REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1); } else { @@ -3174,8 +3216,10 @@ u8 bnx2x_set_led(struct link_params *params, (speed == SPEED_1000) || (speed == SPEED_100) || (speed == SPEED_10))) { - /* On Everest 1 Ax chip versions for speeds less than - 10G LED scheme is different */ + /* + * On Everest 1 Ax chip versions for speeds less than + * 10G LED scheme is different + */ REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 1); REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + @@ -3195,7 +3239,7 @@ u8 bnx2x_set_led(struct link_params *params, } -/** +/* * This function comes to reflect the actual link state read DIRECTLY from the * HW */ @@ -3254,15 +3298,15 @@ static u8 bnx2x_link_initialize(struct link_params *params, u8 rc = 0; u8 phy_index, non_ext_phy; struct bnx2x *bp = params->bp; - /** - * In case of external phy existence, the line speed would be the - * line speed linked up by the external phy. In case it is direct - * only, then the line_speed during initialization will be - * equal to the req_line_speed - */ + /* + * In case of external phy existence, the line speed would be the + * line speed linked up by the external phy. In case it is direct + * only, then the line_speed during initialization will be + * equal to the req_line_speed + */ vars->line_speed = params->phy[INT_PHY].req_line_speed; - /** + /* * Initialize the internal phy in case this is a direct board * (no external phys), or this board has external phy which requires * to first. @@ -3290,17 +3334,16 @@ static u8 bnx2x_link_initialize(struct link_params *params, if (!non_ext_phy) for (phy_index = EXT_PHY1; phy_index < params->num_phys; phy_index++) { - /** + /* * No need to initialize second phy in case of first * phy only selection. In case of second phy, we do * need to initialize the first phy, since they are * connected. - **/ + */ if (phy_index == EXT_PHY2 && (bnx2x_phy_selection(params) == PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) { - DP(NETIF_MSG_LINK, "Not initializing" - "second phy\n"); + DP(NETIF_MSG_LINK, "Ignoring second phy\n"); continue; } params->phy[phy_index].config_init( @@ -3424,7 +3467,7 @@ static u8 bnx2x_update_link_up(struct link_params *params, msleep(20); return rc; } -/** +/* * The bnx2x_link_update function should be called upon link * interrupt. * Link is considered up as follows: @@ -3476,14 +3519,14 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) /* disable emac */ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); - /** - * Step 1: - * Check external link change only for external phys, and apply - * priority selection between them in case the link on both phys - * is up. Note that the instead of the common vars, a temporary - * vars argument is used since each phy may have different link/ - * speed/duplex result - */ + /* + * Step 1: + * Check external link change only for external phys, and apply + * priority selection between them in case the link on both phys + * is up. Note that the instead of the common vars, a temporary + * vars argument is used since each phy may have different link/ + * speed/duplex result + */ for (phy_index = EXT_PHY1; phy_index < params->num_phys; phy_index++) { struct bnx2x_phy *phy = ¶ms->phy[phy_index]; @@ -3508,22 +3551,22 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) switch (bnx2x_phy_selection(params)) { case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT: case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY: - /** + /* * In this option, the first PHY makes sure to pass the * traffic through itself only. * Its not clear how to reset the link on the second phy - **/ + */ active_external_phy = EXT_PHY1; break; case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY: - /** + /* * In this option, the first PHY makes sure to pass the * traffic through the second PHY. - **/ + */ active_external_phy = EXT_PHY2; break; default: - /** + /* * Link indication on both PHYs with the following cases * is invalid: * - FIRST_PHY means that second phy wasn't initialized, @@ -3531,7 +3574,7 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) * - SECOND_PHY means that first phy should not be able * to link up by itself (using configuration) * - DEFAULT should be overriden during initialiazation - **/ + */ DP(NETIF_MSG_LINK, "Invalid link indication" "mpc=0x%x. DISABLING LINK !!!\n", params->multi_phy_config); @@ -3541,18 +3584,18 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) } } prev_line_speed = vars->line_speed; - /** - * Step 2: - * Read the status of the internal phy. In case of - * DIRECT_SINGLE_MEDIA board, this link is the external link, - * otherwise this is the link between the 577xx and the first - * external phy - */ + /* + * Step 2: + * Read the status of the internal phy. In case of + * DIRECT_SINGLE_MEDIA board, this link is the external link, + * otherwise this is the link between the 577xx and the first + * external phy + */ if (params->phy[INT_PHY].read_status) params->phy[INT_PHY].read_status( ¶ms->phy[INT_PHY], params, vars); - /** + /* * The INT_PHY flow control reside in the vars. This include the * case where the speed or flow control are not set to AUTO. * Otherwise, the active external phy flow control result is set @@ -3562,13 +3605,13 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) */ if (active_external_phy > INT_PHY) { vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl; - /** + /* * Link speed is taken from the XGXS. AN and FC result from * the external phy. */ vars->link_status |= phy_vars[active_external_phy].link_status; - /** + /* * if active_external_phy is first PHY and link is up - disable * disable TX on second external PHY */ @@ -3604,7 +3647,7 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x," " ext_phy_line_speed = %d\n", vars->flow_ctrl, vars->link_status, ext_phy_line_speed); - /** + /* * Upon link speed change set the NIG into drain mode. Comes to * deals with possible FIFO glitch due to clk change when speed * is decreased without link down indicator @@ -3635,14 +3678,14 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) bnx2x_link_int_ack(params, vars, link_10g); - /** - * In case external phy link is up, and internal link is down - * (not initialized yet probably after link initialization, it - * needs to be initialized. - * Note that after link down-up as result of cable plug, the xgxs - * link would probably become up again without the need - * initialize it - */ + /* + * In case external phy link is up, and internal link is down + * (not initialized yet probably after link initialization, it + * needs to be initialized. + * Note that after link down-up as result of cable plug, the xgxs + * link would probably become up again without the need + * initialize it + */ if (!(SINGLE_MEDIA_DIRECT(params))) { DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d," " init_preceding = %d\n", ext_phy_link_up, @@ -3662,9 +3705,9 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) vars); } } - /** - * Link is up only if both local phy and external phy (in case of - * non-direct board) are up + /* + * Link is up only if both local phy and external phy (in case of + * non-direct board) are up */ vars->link_up = (vars->phy_link_up && (ext_phy_link_up || @@ -3952,26 +3995,32 @@ static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy) } /* XAUI workaround in 8073 A0: */ - /* After loading the boot ROM and restarting Autoneg, - poll Dev1, Reg $C820: */ + /* + * After loading the boot ROM and restarting Autoneg, poll + * Dev1, Reg $C820: + */ for (cnt = 0; cnt < 1000; cnt++) { bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &val); - /* If bit [14] = 0 or bit [13] = 0, continue on with - system initialization (XAUI work-around not required, - as these bits indicate 2.5G or 1G link up). */ + /* + * If bit [14] = 0 or bit [13] = 0, continue on with + * system initialization (XAUI work-around not required, as + * these bits indicate 2.5G or 1G link up). + */ if (!(val & (1<<14)) || !(val & (1<<13))) { DP(NETIF_MSG_LINK, "XAUI work-around not required\n"); return 0; } else if (!(val & (1<<15))) { - DP(NETIF_MSG_LINK, "clc bit 15 went off\n"); - /* If bit 15 is 0, then poll Dev1, Reg $C841 until - it's MSB (bit 15) goes to 1 (indicating that the - XAUI workaround has completed), - then continue on with system initialization.*/ + DP(NETIF_MSG_LINK, "bit 15 went off\n"); + /* + * If bit 15 is 0, then poll Dev1, Reg $C841 until it's + * MSB (bit15) goes to 1 (indicating that the XAUI + * workaround has completed), then continue on with + * system initialization. + */ for (cnt1 = 0; cnt1 < 1000; cnt1++) { bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, @@ -4075,10 +4124,6 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1); - /** - * If this is forced speed, set to KR or KX (all other are not - * supported) - */ /* Swap polarity if required - Must be done only in non-1G mode */ if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) { /* Configure the 8073 to swap _P and _N of the KR lines */ @@ -4121,8 +4166,10 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, val = (1<<7); } else if (phy->req_line_speed == SPEED_2500) { val = (1<<5); - /* Note that 2.5G works only - when used with 1G advertisment */ + /* + * Note that 2.5G works only when used with 1G + * advertisment + */ } else val = (1<<5); } else { @@ -4131,8 +4178,7 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) val |= (1<<7); - /* Note that 2.5G works only when - used with 1G advertisment */ + /* Note that 2.5G works only when used with 1G advertisment */ if (phy->speed_cap_mask & (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G | PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) @@ -4172,9 +4218,11 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, /* Add support for CL37 (passive mode) III */ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); - /* The SNR will improve about 2db by changing - BW and FEE main tap. Rest commands are executed - after link is up*/ + /* + * The SNR will improve about 2db by changing BW and FEE main + * tap. Rest commands are executed after link is up + * Change FFE main cursor to 5 in EDC register + */ if (bnx2x_8073_is_snr_needed(bp, phy)) bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN, @@ -4258,12 +4306,11 @@ static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy, link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1))); if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) { - /* The SNR will improve about 2dbby - changing the BW and FEE main tap.*/ - /* The 1st write to change FFE main - tap is set before restart AN */ - /* Change PLL Bandwidth in EDC - register */ + /* + * The SNR will improve about 2dbby changing the BW and FEE main + * tap. The 1st write to change FFE main tap is set before + * restart AN. Change PLL Bandwidth in EDC register + */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH, 0x26BC); @@ -4307,10 +4354,10 @@ static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy, bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1); - /** - * Set bit 3 to invert Rx in 1G mode and clear this bit - * when it`s in 10G mode. - */ + /* + * Set bit 3 to invert Rx in 1G mode and clear this bit + * when it`s in 10G mode. + */ if (vars->line_speed == SPEED_1000) { DP(NETIF_MSG_LINK, "Swapping 1G polarity for" "the 8073\n"); @@ -4545,8 +4592,10 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, 0x8002); - /* Wait appropriate time for two-wire command to finish before - polling the status register */ + /* + * Wait appropriate time for two-wire command to finish before + * polling the status register + */ msleep(1); /* Wait up to 500us for command complete status */ @@ -4625,8 +4674,10 @@ static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy, { u8 copper_module_type; - /* Check if its active cable( includes SFP+ module) - of passive cable*/ + /* + * Check if its active cable (includes SFP+ module) + * of passive cable + */ if (bnx2x_read_sfp_module_eeprom(phy, params, SFP_EEPROM_FC_TX_TECH_ADDR, @@ -4685,8 +4736,10 @@ static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode); return 0; } -/* This function read the relevant field from the module ( SFP+ ), - and verify it is compliant with this board */ +/* + * This function read the relevant field from the module (SFP+), and verify it + * is compliant with this board + */ static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy, struct link_params *params) { @@ -4764,8 +4817,11 @@ static u8 bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, u8 val; struct bnx2x *bp = params->bp; u16 timeout; - /* Initialization time after hot-plug may take up to 300ms for some - phys type ( e.g. JDSU ) */ + /* + * Initialization time after hot-plug may take up to 300ms for + * some phys type ( e.g. JDSU ) + */ + for (timeout = 0; timeout < 60; timeout++) { if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val) == 0) { @@ -4784,16 +4840,14 @@ static void bnx2x_8727_power_module(struct bnx2x *bp, /* Make sure GPIOs are not using for LED mode */ u16 val; /* - * In the GPIO register, bit 4 is use to detemine if the GPIOs are + * In the GPIO register, bit 4 is use to determine if the GPIOs are * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for * output * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0 * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1 * where the 1st bit is the over-current(only input), and 2nd bit is * for power( only output ) - */ - - /* + * * In case of NOC feature is disabled and power is up, set GPIO control * as input to enable listening of over-current indication */ @@ -4838,9 +4892,10 @@ static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp, DP(NETIF_MSG_LINK, "Setting LRM MODE\n"); - /* Changing to LRM mode takes quite few seconds. - So do it only if current mode is limiting - ( default is LRM )*/ + /* + * Changing to LRM mode takes quite few seconds. So do it only + * if current mode is limiting (default is LRM) + */ if (cur_limiting_mode != EDC_MODE_LIMITING) return 0; @@ -4964,8 +5019,10 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) bnx2x_8727_power_module(bp, phy, 1); - /* Check and set limiting mode / LRM mode on 8726. - On 8727 it is done automatically */ + /* + * Check and set limiting mode / LRM mode on 8726. On 8727 it + * is done automatically + */ if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) bnx2x_8726_set_limiting_mode(bp, phy, edc_mode); else @@ -4996,7 +5053,7 @@ void bnx2x_handle_module_detect_int(struct link_params *params) MISC_REGISTERS_GPIO_HIGH, params->port); - /* Get current gpio val refelecting module plugged in / out*/ + /* Get current gpio val reflecting module plugged in / out*/ gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port); /* Call the handling function in case module is detected */ @@ -5019,8 +5076,10 @@ void bnx2x_handle_module_detect_int(struct link_params *params) bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, MISC_REGISTERS_GPIO_INT_OUTPUT_SET, port); - /* Module was plugged out. */ - /* Disable transmit for this module */ + /* + * Module was plugged out. + * Disable transmit for this module + */ if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); @@ -5059,9 +5118,9 @@ static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps" " link_status 0x%x\n", rx_sd, pcs_status, val2); - /* link is up if both bit 0 of pmd_rx_sd and - * bit 0 of pcs_status are set, or if the autoneg bit - * 1 is set + /* + * link is up if both bit 0 of pmd_rx_sd and bit 0 of pcs_status + * are set, or if the autoneg bit 1 is set */ link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1))); if (link_up) { @@ -5256,11 +5315,12 @@ static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy, bnx2x_8726_external_rom_boot(phy, params); - /* Need to call module detected on initialization since - the module detection triggered by actual module - insertion might occur before driver is loaded, and when - driver is loaded, it reset all registers, including the - transmitter */ + /* + * Need to call module detected on initialization since the module + * detection triggered by actual module insertion might occur before + * driver is loaded, and when driver is loaded, it reset all + * registers, including the transmitter + */ bnx2x_sfp_module_detection(phy, params); if (phy->req_line_speed == SPEED_1000) { @@ -5293,8 +5353,10 @@ static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); - /* Enable RX-ALARM control to receive - interrupt for 1G speed change */ + /* + * Enable RX-ALARM control to receive interrupt for 1G speed + * change + */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x4); bnx2x_cl45_write(bp, phy, @@ -5417,7 +5479,7 @@ static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy, struct link_params *params) { u32 swap_val, swap_override; u8 port; - /** + /* * The PHY reset is controlled by GPIO 1. Fake the port number * to cancel the swap done in set_gpio() */ @@ -5452,14 +5514,17 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val); - /* Initially configure MOD_ABS to interrupt when - module is presence( bit 8) */ + /* + * Initially configure MOD_ABS to interrupt when module is + * presence( bit 8) + */ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs); - /* Set EDC off by setting OPTXLOS signal input to low - (bit 9). - When the EDC is off it locks onto a reference clock and - avoids becoming 'lost'.*/ + /* + * Set EDC off by setting OPTXLOS signal input to low (bit 9). + * When the EDC is off it locks onto a reference clock and avoids + * becoming 'lost' + */ mod_abs &= ~(1<<8); if (!(phy->flags & FLAGS_NOC)) mod_abs &= ~(1<<9); @@ -5474,7 +5539,7 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, if (phy->flags & FLAGS_NOC) val |= (3<<5); - /** + /* * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0 * status which reflect SFP+ module over-current */ @@ -5501,7 +5566,7 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1); DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1); - /** + /* * Power down the XAUI until link is up in case of dual-media * and 1G */ @@ -5527,7 +5592,7 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300); } else { - /** + /* * Since the 8727 has only single reset pin, need to set the 10G * registers although it is default */ @@ -5543,7 +5608,8 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, 0x0008); } - /* Set 2-wire transfer rate of SFP+ module EEPROM + /* + * Set 2-wire transfer rate of SFP+ module EEPROM * to 100Khz since some DACs(direct attached cables) do * not work at 400Khz. */ @@ -5587,12 +5653,14 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "MOD_ABS indication " "show module is absent\n"); - /* 1. Set mod_abs to detect next module - presence event - 2. Set EDC off by setting OPTXLOS signal input to low - (bit 9). - When the EDC is off it locks onto a reference clock and - avoids becoming 'lost'.*/ + /* + * 1. Set mod_abs to detect next module + * presence event + * 2. Set EDC off by setting OPTXLOS signal input to low + * (bit 9). + * When the EDC is off it locks onto a reference clock and + * avoids becoming 'lost'. + */ mod_abs &= ~(1<<8); if (!(phy->flags & FLAGS_NOC)) mod_abs &= ~(1<<9); @@ -5600,8 +5668,10 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); - /* Clear RX alarm since it stays up as long as - the mod_abs wasn't changed */ + /* + * Clear RX alarm since it stays up as long as + * the mod_abs wasn't changed + */ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); @@ -5610,15 +5680,14 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, /* Module is present */ DP(NETIF_MSG_LINK, "MOD_ABS indication " "show module is present\n"); - /* First thing, disable transmitter, - and if the module is ok, the - module_detection will enable it*/ - - /* 1. Set mod_abs to detect next module - absent event ( bit 8) - 2. Restore the default polarity of the OPRXLOS signal and - this signal will then correctly indicate the presence or - absence of the Rx signal. (bit 9) */ + /* + * First disable transmitter, and if the module is ok, the + * module_detection will enable it + * 1. Set mod_abs to detect next module absent event ( bit 8) + * 2. Restore the default polarity of the OPRXLOS signal and + * this signal will then correctly indicate the presence or + * absence of the Rx signal. (bit 9) + */ mod_abs |= (1<<8); if (!(phy->flags & FLAGS_NOC)) mod_abs |= (1<<9); @@ -5626,10 +5695,12 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); - /* Clear RX alarm since it stays up as long as - the mod_abs wasn't changed. This is need to be done - before calling the module detection, otherwise it will clear - the link update alarm */ + /* + * Clear RX alarm since it stays up as long as the mod_abs + * wasn't changed. This is need to be done before calling the + * module detection, otherwise it will clear* the link update + * alarm + */ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); @@ -5646,9 +5717,8 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, } DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", - rx_alarm_status); - /* No need to check link status in case of - module plugged in/out */ + rx_alarm_status); + /* No need to check link status in case of module plugged in/out */ } static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, @@ -5684,7 +5754,7 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1); - /** + /* * If a module is present and there is need to check * for over current */ @@ -5704,12 +5774,8 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, " Please remove the SFP+ module and" " restart the system to clear this" " error.\n", - params->port); - - /* - * Disable all RX_ALARMs except for - * mod_abs - */ + params->port); + /* Disable all RX_ALARMs except for mod_abs */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<5)); @@ -5752,11 +5818,15 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status); - /* Bits 0..2 --> speed detected, - bits 13..15--> link is down */ + /* + * Bits 0..2 --> speed detected, + * Bits 13..15--> link is down + */ if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) { link_up = 1; vars->line_speed = SPEED_10000; + DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n", + params->port); } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) { link_up = 1; vars->line_speed = SPEED_1000; @@ -5778,7 +5848,7 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_GP, &val1); - /** + /* * In case of dual-media board and 1G, power up the XAUI side, * otherwise power it down. For 10G it is done automatically */ @@ -5920,7 +5990,11 @@ static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; u16 autoneg_val, an_1000_val, an_10_100_val; - + /* + * This phy uses the NIG latch mechanism since link indication + * arrives through its LED4 and not via its LASI signal, so we + * get steady signal instead of clear on read + */ bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, 1 << NIG_LATCH_BC_ENABLE_MI_INT); @@ -6079,8 +6153,9 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, bnx2x_wait_reset_complete(bp, phy); /* Wait for GPHY to come out of reset */ msleep(50); - /* BCM84823 requires that XGXS links up first @ 10G for normal - behavior */ + /* + * BCM84823 requires that XGXS links up first @ 10G for normal behavior + */ temp = vars->line_speed; vars->line_speed = SPEED_10000; bnx2x_set_autoneg(¶ms->phy[INT_PHY], params, vars, 0); @@ -6401,7 +6476,7 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, if (!((val & MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK) >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)) { - DP(NETIF_MSG_LINK, "Seting LINK_SIGNAL\n"); + DP(NETIF_MSG_LINK, "Setting LINK_SIGNAL\n"); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LINK_SIGNAL, @@ -6522,9 +6597,7 @@ static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n", val2, val1); link_up = ((val1 & 4) == 4); - /* if link is up - * print the AN outcome of the SFX7101 PHY - */ + /* if link is up print the AN outcome of the SFX7101 PHY */ if (link_up) { bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS, @@ -6987,7 +7060,7 @@ static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base, /* Get the 4 lanes xgxs config rx and tx */ u32 rx = 0, tx = 0, i; for (i = 0; i < 2; i++) { - /** + /* * INT_PHY and EXT_PHY1 share the same value location in the * shmem. When num_phys is greater than 1, than this value * applies only to EXT_PHY1 @@ -7141,11 +7214,11 @@ static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config); bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index); - /** - * The shmem address of the phy version is located on different - * structures. In case this structure is too old, do not set - * the address - */ + /* + * The shmem address of the phy version is located on different + * structures. In case this structure is too old, do not set + * the address + */ config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region, dev_info.shared_hw_config.config2)); if (phy_index == EXT_PHY1) { @@ -7174,7 +7247,7 @@ static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, } phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port); - /** + /* * In case mdc/mdio_access of the external phy is different than the * mdc/mdio access of the XGXS, a HW lock must be taken in each access * to prevent one port interfere with another port's CL45 operations. @@ -7729,8 +7802,10 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, (val | 1<<10)); } - /* Toggle Transmitter: Power down and then up with 600ms - delay between */ + /* + * Toggle Transmitter: Power down and then up with 600ms delay + * between + */ msleep(600); /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */ @@ -7913,8 +7988,10 @@ static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[], break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - /* GPIO1 affects both ports, so there's need to pull - it for single port alone */ + /* + * GPIO1 affects both ports, so there's need to pull + * it for single port alone + */ rc = bnx2x_8726_common_init_phy(bp, shmem_base_path, shmem2_base_path, phy_index, chip_id); @@ -7924,8 +8001,8 @@ static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[], break; default: DP(NETIF_MSG_LINK, - "bnx2x_common_init_phy: ext_phy 0x%x not required\n", - ext_phy_type); + "ext_phy 0x%x common init not required\n", + ext_phy_type); break; } -- cgit v1.2.3 From 65a001bad18eb80f6f953e5e0601132f09bfe197 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Mon, 31 Jan 2011 04:22:03 +0000 Subject: bnx2x: Fix compilation warning messages Fix annoying compilation warning, mainly related to static declarations Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 18 ++++++------------ drivers/net/bnx2x/bnx2x_link.h | 5 +++++ 2 files changed, 11 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 9fadcdbe4115..452e262b0c20 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -183,12 +183,6 @@ (_bank + (_addr & 0xf)), \ _val) -static u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, - u8 devad, u16 reg, u16 *ret_val); - -static u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, - u8 devad, u16 reg, u16 val); - static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits) { u32 val = REG_RD(bp, reg); @@ -269,7 +263,7 @@ void bnx2x_ets_disabled(struct link_params *params) REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0); } -void bnx2x_ets_bw_limit_common(const struct link_params *params) +static void bnx2x_ets_bw_limit_common(const struct link_params *params) { /* ETS disabled configuration */ struct bnx2x *bp = params->bp; @@ -1391,8 +1385,8 @@ static u32 bnx2x_get_emac_base(struct bnx2x *bp, /******************************************************************/ /* CL45 access functions */ /******************************************************************/ -u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, - u8 devad, u16 reg, u16 val) +static u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, + u8 devad, u16 reg, u16 val) { u32 tmp, saved_mode; u8 i, rc = 0; @@ -1458,8 +1452,8 @@ u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, return rc; } -u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, - u8 devad, u16 reg, u16 *ret_val) +static u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, + u8 devad, u16 reg, u16 *ret_val) { u32 val, saved_mode; u16 i; @@ -4614,7 +4608,7 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "Got bad status 0x%x when reading from SFP+ EEPROM\n", (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK)); - return -EINVAL; + return -EFAULT; } /* Read the buffer */ diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index d9e847bb96f8..92f36b6950dc 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -337,6 +337,11 @@ void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port); /* Reset the external of SFX7101 */ void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy); +/* Read "byte_cnt" bytes from address "addr" from the SFP+ EEPROM */ +u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, + struct link_params *params, u16 addr, + u8 byte_cnt, u8 *o_buf); + void bnx2x_hw_reset_phy(struct link_params *params); /* Checks if HW lock is required for this phy/board type */ -- cgit v1.2.3 From 6d870c391ec0e4da4fd75df7e6aca7252162c408 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Mon, 31 Jan 2011 04:22:20 +0000 Subject: bnx2x: Add and change some net_dev messages Add and modify some net dev prints to improve error control Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 452e262b0c20..187387e86d25 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -1422,6 +1422,7 @@ static u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, } if (tmp & EMAC_MDIO_COMM_START_BUSY) { DP(NETIF_MSG_LINK, "write phy register failed\n"); + netdev_err(bp->dev, "MDC/MDIO access timeout\n"); rc = -EFAULT; } else { /* data */ @@ -1442,6 +1443,7 @@ static u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, } if (tmp & EMAC_MDIO_COMM_START_BUSY) { DP(NETIF_MSG_LINK, "write phy register failed\n"); + netdev_err(bp->dev, "MDC/MDIO access timeout\n"); rc = -EFAULT; } } @@ -1489,7 +1491,7 @@ static u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, } if (val & EMAC_MDIO_COMM_START_BUSY) { DP(NETIF_MSG_LINK, "read phy register failed\n"); - + netdev_err(bp->dev, "MDC/MDIO access timeout\n"); *ret_val = 0; rc = -EFAULT; @@ -1512,7 +1514,7 @@ static u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, } if (val & EMAC_MDIO_COMM_START_BUSY) { DP(NETIF_MSG_LINK, "read phy register failed\n"); - + netdev_err(bp->dev, "MDC/MDIO access timeout\n"); *ret_val = 0; rc = -EFAULT; } @@ -1827,6 +1829,9 @@ static u8 bnx2x_reset_unicore(struct link_params *params, } } + netdev_err(bp->dev, "Warning: PHY was not initialized," + " Port %d\n", + params->port); DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n"); return -EINVAL; @@ -2846,7 +2851,8 @@ static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy, } static u16 bnx2x_wait_reset_complete(struct bnx2x *bp, - struct bnx2x_phy *phy) + struct bnx2x_phy *phy, + struct link_params *params) { u16 cnt, ctrl; /* Wait for soft reset to get cleared upto 1 sec */ @@ -2857,6 +2863,11 @@ static u16 bnx2x_wait_reset_complete(struct bnx2x *bp, break; msleep(1); } + + if (cnt == 1000) + netdev_err(bp->dev, "Warning: PHY was not initialized," + " Port %d\n", + params->port); DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt); return cnt; } @@ -4402,7 +4413,7 @@ static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy, /* HW reset */ bnx2x_ext_phy_hw_reset(bp, params->port); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); - bnx2x_wait_reset_complete(bp, phy); + bnx2x_wait_reset_complete(bp, phy, params); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288); @@ -4797,9 +4808,9 @@ static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy, else vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0'; - netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected," - " Port %d from %s part number %s\n", - params->port, vendor_name, vendor_pn); + netdev_err(bp->dev, "Warning: Unqualified SFP+ module detected," + " Port %d from %s part number %s\n", + params->port, vendor_name, vendor_pn); phy->flags |= FLAGS_SFP_NOT_APPROVED; return -EINVAL; } @@ -5142,7 +5153,7 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, /* HW reset */ bnx2x_ext_phy_hw_reset(bp, params->port); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); - bnx2x_wait_reset_complete(bp, phy); + bnx2x_wait_reset_complete(bp, phy, params); /* Wait until fw is loaded */ for (cnt = 0; cnt < 100; cnt++) { @@ -5305,7 +5316,7 @@ static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy, MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); - bnx2x_wait_reset_complete(bp, phy); + bnx2x_wait_reset_complete(bp, phy, params); bnx2x_8726_external_rom_boot(phy, params); @@ -5495,7 +5506,7 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */ - bnx2x_wait_reset_complete(bp, phy); + bnx2x_wait_reset_complete(bp, phy, params); rx_alarm_ctrl_val = (1<<2) | (1<<5) ; lasi_ctrl_val = 0x0004; @@ -6117,7 +6128,7 @@ static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy, /* HW reset */ bnx2x_ext_phy_hw_reset(bp, params->port); - bnx2x_wait_reset_complete(bp, phy); + bnx2x_wait_reset_complete(bp, phy, params); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); return bnx2x_848xx_cmn_config_init(phy, params, vars); @@ -6144,7 +6155,7 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); - bnx2x_wait_reset_complete(bp, phy); + bnx2x_wait_reset_complete(bp, phy, params); /* Wait for GPHY to come out of reset */ msleep(50); /* @@ -6544,7 +6555,7 @@ static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy, MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); /* HW reset */ bnx2x_ext_phy_hw_reset(bp, params->port); - bnx2x_wait_reset_complete(bp, phy); + bnx2x_wait_reset_complete(bp, phy, params); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1); @@ -8000,6 +8011,10 @@ static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[], break; } + if (rc != 0) + netdev_err(bp->dev, "Warning: PHY was not initialized," + " Port %d\n", + 0); return rc; } -- cgit v1.2.3 From a8db5b4cbde619246cd3db9a59dac5d0757aff36 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Mon, 31 Jan 2011 04:22:28 +0000 Subject: bnx2x: Enhance SFP+ module control Add flexible support to control various SFP+ module features either throughout MDIO registers or GPIO pins according to NVRAM configuration Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_hsi.h | 82 +++++++++++++- drivers/net/bnx2x/bnx2x_link.c | 251 ++++++++++++++++++++++++++++++++++------- drivers/net/bnx2x/bnx2x_reg.h | 1 + 3 files changed, 289 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 548f5631c0dc..34e313cf3e25 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -237,8 +237,26 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ #define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT 16 - u32 Reserved0[16]; /* 0x158 */ - + u32 Reserved0[3]; /* 0x158 */ + /* Controls the TX laser of the SFP+ module */ + u32 sfp_ctrl; /* 0x164 */ +#define PORT_HW_CFG_TX_LASER_MASK 0x000000FF +#define PORT_HW_CFG_TX_LASER_SHIFT 0 +#define PORT_HW_CFG_TX_LASER_MDIO 0x00000000 +#define PORT_HW_CFG_TX_LASER_GPIO0 0x00000001 +#define PORT_HW_CFG_TX_LASER_GPIO1 0x00000002 +#define PORT_HW_CFG_TX_LASER_GPIO2 0x00000003 +#define PORT_HW_CFG_TX_LASER_GPIO3 0x00000004 + + /* Controls the fault module LED of the SFP+ */ +#define PORT_HW_CFG_FAULT_MODULE_LED_MASK 0x0000FF00 +#define PORT_HW_CFG_FAULT_MODULE_LED_SHIFT 8 +#define PORT_HW_CFG_FAULT_MODULE_LED_GPIO0 0x00000000 +#define PORT_HW_CFG_FAULT_MODULE_LED_GPIO1 0x00000100 +#define PORT_HW_CFG_FAULT_MODULE_LED_GPIO2 0x00000200 +#define PORT_HW_CFG_FAULT_MODULE_LED_GPIO3 0x00000300 +#define PORT_HW_CFG_FAULT_MODULE_LED_DISABLED 0x00000400 + u32 Reserved01[12]; /* 0x158 */ /* for external PHY, or forced mode or during AN */ u16 xgxs_config_rx[4]; /* 0x198 */ @@ -246,6 +264,66 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ u32 Reserved1[56]; /* 0x1A8 */ u32 default_cfg; /* 0x288 */ +#define PORT_HW_CFG_GPIO0_CONFIG_MASK 0x00000003 +#define PORT_HW_CFG_GPIO0_CONFIG_SHIFT 0 +#define PORT_HW_CFG_GPIO0_CONFIG_NA 0x00000000 +#define PORT_HW_CFG_GPIO0_CONFIG_LOW 0x00000001 +#define PORT_HW_CFG_GPIO0_CONFIG_HIGH 0x00000002 +#define PORT_HW_CFG_GPIO0_CONFIG_INPUT 0x00000003 + +#define PORT_HW_CFG_GPIO1_CONFIG_MASK 0x0000000C +#define PORT_HW_CFG_GPIO1_CONFIG_SHIFT 2 +#define PORT_HW_CFG_GPIO1_CONFIG_NA 0x00000000 +#define PORT_HW_CFG_GPIO1_CONFIG_LOW 0x00000004 +#define PORT_HW_CFG_GPIO1_CONFIG_HIGH 0x00000008 +#define PORT_HW_CFG_GPIO1_CONFIG_INPUT 0x0000000c + +#define PORT_HW_CFG_GPIO2_CONFIG_MASK 0x00000030 +#define PORT_HW_CFG_GPIO2_CONFIG_SHIFT 4 +#define PORT_HW_CFG_GPIO2_CONFIG_NA 0x00000000 +#define PORT_HW_CFG_GPIO2_CONFIG_LOW 0x00000010 +#define PORT_HW_CFG_GPIO2_CONFIG_HIGH 0x00000020 +#define PORT_HW_CFG_GPIO2_CONFIG_INPUT 0x00000030 + +#define PORT_HW_CFG_GPIO3_CONFIG_MASK 0x000000C0 +#define PORT_HW_CFG_GPIO3_CONFIG_SHIFT 6 +#define PORT_HW_CFG_GPIO3_CONFIG_NA 0x00000000 +#define PORT_HW_CFG_GPIO3_CONFIG_LOW 0x00000040 +#define PORT_HW_CFG_GPIO3_CONFIG_HIGH 0x00000080 +#define PORT_HW_CFG_GPIO3_CONFIG_INPUT 0x000000c0 + + /* + * When KR link is required to be set to force which is not + * KR-compliant, this parameter determine what is the trigger for it. + * When GPIO is selected, low input will force the speed. Currently + * default speed is 1G. In the future, it may be widen to select the + * forced speed in with another parameter. Note when force-1G is + * enabled, it override option 56: Link Speed option. + */ +#define PORT_HW_CFG_FORCE_KR_ENABLER_MASK 0x00000F00 +#define PORT_HW_CFG_FORCE_KR_ENABLER_SHIFT 8 +#define PORT_HW_CFG_FORCE_KR_ENABLER_NOT_FORCED 0x00000000 +#define PORT_HW_CFG_FORCE_KR_ENABLER_GPIO0_P0 0x00000100 +#define PORT_HW_CFG_FORCE_KR_ENABLER_GPIO1_P0 0x00000200 +#define PORT_HW_CFG_FORCE_KR_ENABLER_GPIO2_P0 0x00000300 +#define PORT_HW_CFG_FORCE_KR_ENABLER_GPIO3_P0 0x00000400 +#define PORT_HW_CFG_FORCE_KR_ENABLER_GPIO0_P1 0x00000500 +#define PORT_HW_CFG_FORCE_KR_ENABLER_GPIO1_P1 0x00000600 +#define PORT_HW_CFG_FORCE_KR_ENABLER_GPIO2_P1 0x00000700 +#define PORT_HW_CFG_FORCE_KR_ENABLER_GPIO3_P1 0x00000800 +#define PORT_HW_CFG_FORCE_KR_ENABLER_FORCED 0x00000900 + /* Enable to determine with which GPIO to reset the external phy */ +#define PORT_HW_CFG_EXT_PHY_GPIO_RST_MASK 0x000F0000 +#define PORT_HW_CFG_EXT_PHY_GPIO_RST_SHIFT 16 +#define PORT_HW_CFG_EXT_PHY_GPIO_RST_PHY_TYPE 0x00000000 +#define PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0 0x00010000 +#define PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0 0x00020000 +#define PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0 0x00030000 +#define PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0 0x00040000 +#define PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1 0x00050000 +#define PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1 0x00060000 +#define PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1 0x00070000 +#define PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1 0x00080000 /* Enable BAM on KR */ #define PORT_HW_CFG_ENABLE_BAM_ON_KR_MASK 0x00100000 #define PORT_HW_CFG_ENABLE_BAM_ON_KR_SHIFT 20 diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 187387e86d25..a089b62d3df6 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -4464,30 +4464,74 @@ static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy, /******************************************************************/ /* SFP+ module Section */ /******************************************************************/ -static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, +static u8 bnx2x_get_gpio_port(struct link_params *params) +{ + u8 gpio_port; + u32 swap_val, swap_override; + struct bnx2x *bp = params->bp; + if (CHIP_IS_E2(bp)) + gpio_port = BP_PATH(bp); + else + gpio_port = params->port; + swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); + swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); + return gpio_port ^ (swap_val && swap_override); +} +static void bnx2x_sfp_set_transmitter(struct link_params *params, struct bnx2x_phy *phy, - u8 port, u8 tx_en) { u16 val; + u8 port = params->port; + struct bnx2x *bp = params->bp; + u32 tx_en_mode; - DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n", - tx_en, port); /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/ - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - &val); + tx_en_mode = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].sfp_ctrl)) & + PORT_HW_CFG_TX_LASER_MASK; + DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x " + "mode = %x\n", tx_en, port, tx_en_mode); + switch (tx_en_mode) { + case PORT_HW_CFG_TX_LASER_MDIO: - if (tx_en) - val &= ~(1<<15); - else - val |= (1<<15); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, + &val); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - val); + if (tx_en) + val &= ~(1<<15); + else + val |= (1<<15); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, + val); + break; + case PORT_HW_CFG_TX_LASER_GPIO0: + case PORT_HW_CFG_TX_LASER_GPIO1: + case PORT_HW_CFG_TX_LASER_GPIO2: + case PORT_HW_CFG_TX_LASER_GPIO3: + { + u16 gpio_pin; + u8 gpio_port, gpio_mode; + if (tx_en) + gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_HIGH; + else + gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_LOW; + + gpio_pin = tx_en_mode - PORT_HW_CFG_TX_LASER_GPIO0; + gpio_port = bnx2x_get_gpio_port(params); + bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port); + break; + } + default: + DP(NETIF_MSG_LINK, "Invalid TX_LASER_MDIO 0x%x\n", tx_en_mode); + break; + } } static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, @@ -4966,11 +5010,11 @@ static void bnx2x_8727_specific_func(struct bnx2x_phy *phy, switch (action) { case DISABLE_TX: - bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); + bnx2x_sfp_set_transmitter(params, phy, 0); break; case ENABLE_TX: if (!(phy->flags & FLAGS_SFP_NOT_APPROVED)) - bnx2x_sfp_set_transmitter(bp, phy, params->port, 1); + bnx2x_sfp_set_transmitter(params, phy, 1); break; default: DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n", @@ -4979,6 +5023,38 @@ static void bnx2x_8727_specific_func(struct bnx2x_phy *phy, } } +static void bnx2x_set_sfp_module_fault_led(struct link_params *params, + u8 gpio_mode) +{ + struct bnx2x *bp = params->bp; + + u32 fault_led_gpio = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[params->port].sfp_ctrl)) & + PORT_HW_CFG_FAULT_MODULE_LED_MASK; + switch (fault_led_gpio) { + case PORT_HW_CFG_FAULT_MODULE_LED_DISABLED: + return; + case PORT_HW_CFG_FAULT_MODULE_LED_GPIO0: + case PORT_HW_CFG_FAULT_MODULE_LED_GPIO1: + case PORT_HW_CFG_FAULT_MODULE_LED_GPIO2: + case PORT_HW_CFG_FAULT_MODULE_LED_GPIO3: + { + u8 gpio_port = bnx2x_get_gpio_port(params); + u16 gpio_pin = fault_led_gpio - + PORT_HW_CFG_FAULT_MODULE_LED_GPIO0; + DP(NETIF_MSG_LINK, "Set fault module-detected led " + "pin %x port %x mode %x\n", + gpio_pin, gpio_port, gpio_mode); + bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port); + } + break; + default: + DP(NETIF_MSG_LINK, "Error: Invalid fault led mode 0x%x\n", + fault_led_gpio); + } +} + static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, struct link_params *params) { @@ -5001,9 +5077,9 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "Module verification failed!!\n"); rc = -EINVAL; /* Turn on fault module-detected led */ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, - MISC_REGISTERS_GPIO_HIGH, - params->port); + bnx2x_set_sfp_module_fault_led(params, + MISC_REGISTERS_GPIO_HIGH); + if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) && ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) { @@ -5014,10 +5090,7 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, } } else { /* Turn off fault module-detected led */ - DP(NETIF_MSG_LINK, "Turn off fault module-detected led\n"); - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, - MISC_REGISTERS_GPIO_LOW, - params->port); + bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW); } /* power up the SFP module */ @@ -5039,9 +5112,9 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, if (rc == 0 || (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) != PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) - bnx2x_sfp_set_transmitter(bp, phy, params->port, 1); + bnx2x_sfp_set_transmitter(params, phy, 1); else - bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); + bnx2x_sfp_set_transmitter(params, phy, 0); return rc; } @@ -5054,9 +5127,7 @@ void bnx2x_handle_module_detect_int(struct link_params *params) u8 port = params->port; /* Set valid module led off */ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, - MISC_REGISTERS_GPIO_HIGH, - params->port); + bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH); /* Get current gpio val reflecting module plugged in / out*/ gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port); @@ -5087,7 +5158,7 @@ void bnx2x_handle_module_detect_int(struct link_params *params) */ if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) - bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); + bnx2x_sfp_set_transmitter(params, phy, 0); } } @@ -5146,7 +5217,8 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) { - u16 cnt, val; + u32 tx_en_mode; + u16 cnt, val, tmp1; struct bnx2x *bp = params->bp; bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); @@ -5220,6 +5292,26 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, 0x0004); } bnx2x_save_bcm_spirom_ver(bp, phy, params->port); + + /* + * If TX Laser is controlled by GPIO_0, do not let PHY go into low + * power mode, if TX Laser is disabled + */ + + tx_en_mode = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[params->port].sfp_ctrl)) + & PORT_HW_CFG_TX_LASER_MASK; + + if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) { + DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n"); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, &tmp1); + tmp1 |= 0x1; + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, tmp1); + } + return 0; } @@ -5308,12 +5400,6 @@ static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy, u32 val; u32 swap_val, swap_override, aeu_gpio_mask, offset; DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); - /* Restore normal power mode*/ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); - - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); bnx2x_wait_reset_complete(bp, phy, params); @@ -5500,7 +5586,8 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, struct link_params *params, struct link_vars *vars) { - u16 tmp1, val, mod_abs; + u32 tx_en_mode; + u16 tmp1, val, mod_abs, tmp2; u16 rx_alarm_ctrl_val; u16 lasi_ctrl_val; struct bnx2x *bp = params->bp; @@ -5637,6 +5724,26 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, phy->tx_preemphasis[1]); } + /* + * If TX Laser is controlled by GPIO_0, do not let PHY go into low + * power mode, if TX Laser is disabled + */ + tx_en_mode = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[params->port].sfp_ctrl)) + & PORT_HW_CFG_TX_LASER_MASK; + + if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) { + + DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n"); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, &tmp2); + tmp2 |= 0x1000; + tmp2 &= 0xFFEF; + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2); + } + return 0; } @@ -5713,7 +5820,7 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) - bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); + bnx2x_sfp_set_transmitter(params, phy, 0); if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) bnx2x_sfp_module_detection(phy, params); @@ -5873,7 +5980,7 @@ static void bnx2x_8727_link_reset(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; /* Disable Transmitter */ - bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); + bnx2x_sfp_set_transmitter(params, phy, 0); /* Clear LASI */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0); @@ -7889,12 +7996,57 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, return 0; } +static void bnx2x_get_ext_phy_reset_gpio(struct bnx2x *bp, u32 shmem_base, + u8 *io_gpio, u8 *io_port) +{ + + u32 phy_gpio_reset = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[PORT_0].default_cfg)); + switch (phy_gpio_reset) { + case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0: + *io_gpio = 0; + *io_port = 0; + break; + case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0: + *io_gpio = 1; + *io_port = 0; + break; + case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0: + *io_gpio = 2; + *io_port = 0; + break; + case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0: + *io_gpio = 3; + *io_port = 0; + break; + case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1: + *io_gpio = 0; + *io_port = 1; + break; + case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1: + *io_gpio = 1; + *io_port = 1; + break; + case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1: + *io_gpio = 2; + *io_port = 1; + break; + case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1: + *io_gpio = 3; + *io_port = 1; + break; + default: + /* Don't override the io_gpio and io_port */ + break; + } +} static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[], u32 shmem2_base_path[], u8 phy_index, u32 chip_id) { - s8 port; + s8 port, reset_gpio; u32 swap_val, swap_override; struct bnx2x_phy phy[PORT_MAX]; struct bnx2x_phy *phy_blk[PORT_MAX]; @@ -7902,13 +8054,26 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); + reset_gpio = MISC_REGISTERS_GPIO_1; port = 1; - bnx2x_ext_phy_hw_reset(bp, port ^ (swap_val && swap_override)); + /* + * Retrieve the reset gpio/port which control the reset. + * Default is GPIO1, PORT1 + */ + bnx2x_get_ext_phy_reset_gpio(bp, shmem_base_path[0], + (u8 *)&reset_gpio, (u8 *)&port); /* Calculate the port based on port swap */ port ^= (swap_val && swap_override); + /* Initiate PHY reset*/ + bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_LOW, + port); + msleep(1); + bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_HIGH, + port); + msleep(5); /* PART1 - Reset both phys */ diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index e01330bb36c7..1c89f19a4425 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -6083,6 +6083,7 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_PMA_REG_8727_PCS_OPT_CTRL 0xc808 #define MDIO_PMA_REG_8727_GPIO_CTRL 0xc80e #define MDIO_PMA_REG_8727_PCS_GP 0xc842 +#define MDIO_PMA_REG_8727_OPT_CFG_REG 0xc8e4 #define MDIO_AN_REG_8727_MISC_CTRL 0x8309 -- cgit v1.2.3 From c87bca1eaa493779392378b69fe646644580942a Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Mon, 31 Jan 2011 04:22:41 +0000 Subject: bnx2x: Add support for new PHY BCM84833 Add support for new PHY BCM84833. This PHY is very similar to the BCM84823, only it has different register offset compared to the BCM84823, which needs to be handled correctly. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_hsi.h | 1 + drivers/net/bnx2x/bnx2x_link.c | 110 +++++++++++++++++++++++++++++++---------- 2 files changed, 84 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 34e313cf3e25..7c35f4ee3858 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -459,6 +459,7 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727 0x00000900 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC 0x00000a00 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823 0x00000b00 +#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833 0x00000d00 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE 0x0000fd00 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN 0x0000ff00 diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index a089b62d3df6..7d3e7e2c75c6 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -5992,19 +5992,23 @@ static void bnx2x_8727_link_reset(struct bnx2x_phy *phy, static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy, struct link_params *params) { - u16 val, fw_ver1, fw_ver2, cnt; + u16 val, fw_ver1, fw_ver2, cnt, adj; struct bnx2x *bp = params->bp; + adj = 0; + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) + adj = -1; + /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/ /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */ - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819 + adj, 0x0014); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A + adj, 0xc200); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B + adj, 0x0000); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C + adj, 0x0300); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817 + adj, 0x0009); for (cnt = 0; cnt < 100; cnt++) { - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818 + adj, &val); if (val & 1) break; udelay(5); @@ -6018,11 +6022,11 @@ static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy, /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */ - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819 + adj, 0x0000); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A + adj, 0xc200); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817 + adj, 0x000A); for (cnt = 0; cnt < 100; cnt++) { - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818 + adj, &val); if (val & 1) break; udelay(5); @@ -6035,9 +6039,9 @@ static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy, } /* lower 16 bits of the register SPI_FW_STATUS */ - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1); + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B + adj, &fw_ver1); /* upper 16 bits of register SPI_FW_STATUS */ - bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2); + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C + adj, &fw_ver2); bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1, phy->ver_addr); @@ -6046,49 +6050,53 @@ static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy, static void bnx2x_848xx_set_led(struct bnx2x *bp, struct bnx2x_phy *phy) { - u16 val; + u16 val, adj; + + adj = 0; + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) + adj = -1; /* PHYC_CTL_LED_CTL */ bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LINK_SIGNAL, &val); + MDIO_PMA_REG_8481_LINK_SIGNAL + adj, &val); val &= 0xFE00; val |= 0x0092; bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LINK_SIGNAL, val); + MDIO_PMA_REG_8481_LINK_SIGNAL + adj, val); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED1_MASK, + MDIO_PMA_REG_8481_LED1_MASK + adj, 0x80); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED2_MASK, + MDIO_PMA_REG_8481_LED2_MASK + adj, 0x18); /* Select activity source by Tx and Rx, as suggested by PHY AE */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED3_MASK, + MDIO_PMA_REG_8481_LED3_MASK + adj, 0x0006); /* Select the closest activity blink rate to that in 10/100/1000 */ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED3_BLINK, + MDIO_PMA_REG_8481_LED3_BLINK + adj, 0); bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_84823_CTL_LED_CTL_1, &val); + MDIO_PMA_REG_84823_CTL_LED_CTL_1 + adj, &val); val |= MDIO_PMA_REG_84823_LED3_STRETCH_EN; /* stretch_en for LED3*/ bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_PMA_REG_84823_CTL_LED_CTL_1, val); + MDIO_PMA_REG_84823_CTL_LED_CTL_1 + adj, val); /* 'Interrupt Mask' */ bnx2x_cl45_write(bp, phy, @@ -6247,12 +6255,15 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; u8 port, initialize = 1; - u16 val; + u16 val, adj; u16 temp; u32 actual_phy_selection; u8 rc = 0; /* This is just for MDIO_CTL_REG_84823_MEDIA register. */ + adj = 0; + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) + adj = 3; msleep(1); if (CHIP_IS_E2(bp)) @@ -6277,7 +6288,7 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, /* Set dual-media configuration according to configuration */ bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, - MDIO_CTL_REG_84823_MEDIA, &val); + MDIO_CTL_REG_84823_MEDIA + adj, &val); val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK | MDIO_CTL_REG_84823_MEDIA_LINE_MASK | MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN | @@ -6310,7 +6321,7 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G; bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, - MDIO_CTL_REG_84823_MEDIA, val); + MDIO_CTL_REG_84823_MEDIA + adj, val); DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n", params->multi_phy_config, val); @@ -6326,15 +6337,20 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u16 val, val1, val2; + u16 val, val1, val2, adj; u8 link_up = 0; + /* Reg offset adjustment for 84833 */ + adj = 0; + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) + adj = -1; + /* Check 10G-BaseT link status */ /* Check PMD signal ok */ bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, 0xFFFA, &val1); bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL + adj, &val2); DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2); @@ -7159,6 +7175,43 @@ static struct bnx2x_phy phy_84823 = { .phy_specific_func = (phy_specific_func_t)NULL }; +static struct bnx2x_phy phy_84833 = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833, + .addr = 0xff, + .flags = FLAGS_FAN_FAILURE_DET_REQ | + FLAGS_REARM_LATCH_SIGNAL, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_10000baseT_Full | + SUPPORTED_TP | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_BASE_T, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_848x3_config_init, + .read_status = (read_status_t)bnx2x_848xx_read_status, + .link_reset = (link_reset_t)bnx2x_848x3_link_reset, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led, + .phy_specific_func = (phy_specific_func_t)NULL +}; + /*****************************************************************/ /* */ /* Populate the phy according. Main function: bnx2x_populate_phy */ @@ -7312,6 +7365,9 @@ static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: *phy = phy_84823; break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833: + *phy = phy_84833; + break; case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: *phy = phy_7101; break; -- cgit v1.2.3 From 1bef68e3f5d25e17adc5232dc0ad7c0ea0188374 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Mon, 31 Jan 2011 04:22:46 +0000 Subject: bnx2x: Add CMS functionality for 848x3 Add CMS(Common Mode Sense) functionality for 848x3 as this reduces power consumption and allows a better 10G link stability Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_hsi.h | 6 ++++++ drivers/net/bnx2x/bnx2x_link.c | 17 ++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 7c35f4ee3858..51d69db23a71 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -330,6 +330,12 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ #define PORT_HW_CFG_ENABLE_BAM_ON_KR_DISABLED 0x00000000 #define PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED 0x00100000 + /* Enable Common Mode Sense */ +#define PORT_HW_CFG_ENABLE_CMS_MASK 0x00200000 +#define PORT_HW_CFG_ENABLE_CMS_SHIFT 21 +#define PORT_HW_CFG_ENABLE_CMS_DISABLED 0x00000000 +#define PORT_HW_CFG_ENABLE_CMS_ENABLED 0x00200000 + u32 speed_capability_mask2; /* 0x28C */ #define PORT_HW_CFG_SPEED_CAPABILITY2_D3_MASK 0x0000FFFF #define PORT_HW_CFG_SPEED_CAPABILITY2_D3_SHIFT 0 diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 7d3e7e2c75c6..4a1b5ee976b3 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -6257,7 +6257,7 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, u8 port, initialize = 1; u16 val, adj; u16 temp; - u32 actual_phy_selection; + u32 actual_phy_selection, cms_enable; u8 rc = 0; /* This is just for MDIO_CTL_REG_84823_MEDIA register. */ @@ -6329,6 +6329,21 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, rc = bnx2x_848xx_cmn_config_init(phy, params, vars); else bnx2x_save_848xx_spirom_version(phy, params); + cms_enable = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[params->port].default_cfg)) & + PORT_HW_CFG_ENABLE_CMS_MASK; + + bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, + MDIO_CTL_REG_84823_USER_CTRL_REG, &val); + if (cms_enable) + val |= MDIO_CTL_REG_84823_USER_CTRL_CMS; + else + val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS; + bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, + MDIO_CTL_REG_84823_USER_CTRL_REG, val); + + return rc; } -- cgit v1.2.3 From 02a23165f807901818c33acd0facc4ab8f3ebdf7 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Mon, 31 Jan 2011 04:22:53 +0000 Subject: bnx2x: Remove support for emulation/FPGA Remove unneeded support for emulation/FPGA from the code Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_link.c | 88 +----------------------------------------- 1 file changed, 1 insertion(+), 87 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 4a1b5ee976b3..f2f367d4e74d 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -521,22 +521,6 @@ static u8 bnx2x_emac_enable(struct link_params *params, /* enable emac and not bmac */ REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1); - /* for paladium */ - if (CHIP_REV_IS_EMUL(bp)) { - /* Use lane 1 (of lanes 0-3) */ - REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1); - REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1); - } - /* for fpga */ - else - - if (CHIP_REV_IS_FPGA(bp)) { - /* Use lane 1 (of lanes 0-3) */ - DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n"); - - REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1); - REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0); - } else /* ASIC */ if (vars->phy_flags & PHY_XGXS_FLAG) { u32 ser_lane = ((params->lane_config & @@ -654,15 +638,7 @@ static u8 bnx2x_emac_enable(struct link_params *params, REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val); REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1); - if (CHIP_REV_IS_EMUL(bp)) { - /* take the BigMac out of reset */ - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); - - /* enable access for bmac registers */ - REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1); - } else - REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0); + REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0); vars->mac_type = MAC_TYPE_EMAC; return 0; @@ -1086,14 +1062,6 @@ static u8 bnx2x_bmac1_enable(struct link_params *params, wb_data[1] = 0; REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS, wb_data, 2); - /* fix for emulation */ - if (CHIP_REV_IS_EMUL(bp)) { - wb_data[0] = 0xf000; - wb_data[1] = 0; - REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD, - wb_data, 2); - } - return 0; } @@ -7678,57 +7646,6 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) set_phy_vars(params); DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys); - if (CHIP_REV_IS_FPGA(bp)) { - - vars->link_up = 1; - vars->line_speed = SPEED_10000; - vars->duplex = DUPLEX_FULL; - vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD); - /* enable on E1.5 FPGA */ - if (CHIP_IS_E1H(bp)) { - vars->flow_ctrl |= - (BNX2X_FLOW_CTRL_TX | - BNX2X_FLOW_CTRL_RX); - vars->link_status |= - (LINK_STATUS_TX_FLOW_CONTROL_ENABLED | - LINK_STATUS_RX_FLOW_CONTROL_ENABLED); - } - - bnx2x_emac_enable(params, vars, 0); - if (!(CHIP_IS_E2(bp))) - bnx2x_pbf_update(params, vars->flow_ctrl, - vars->line_speed); - /* disable drain */ - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); - - /* update shared memory */ - bnx2x_update_mng(params, vars->link_status); - - return 0; - - } else - if (CHIP_REV_IS_EMUL(bp)) { - - vars->link_up = 1; - vars->line_speed = SPEED_10000; - vars->duplex = DUPLEX_FULL; - vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD); - - bnx2x_bmac_enable(params, vars, 0); - - bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed); - /* Disable drain */ - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE - + params->port*4, 0); - - /* update shared memory */ - bnx2x_update_mng(params, vars->link_status); - - return 0; - - } else if (params->loopback_mode == LOOPBACK_BMAC) { vars->link_up = 1; @@ -8263,9 +8180,6 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[], u32 ext_phy_type, ext_phy_config; DP(NETIF_MSG_LINK, "Begin common phy init\n"); - if (CHIP_REV_IS_EMUL(bp)) - return 0; - /* Check if common init was already done */ phy_ver = REG_RD(bp, shmem_base_path[0] + offsetof(struct shmem_region, -- cgit v1.2.3 From 6b28ff3be829a851378551245fd6b3f9bf93b0ad Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Mon, 31 Jan 2011 04:22:57 +0000 Subject: bnx2x: Update bnx2x version to 1.62.11-0 Update bnx2x version to 1.62.11-0 Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 50a34d9a5b73..04fb72b923b2 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -22,8 +22,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.62.00-5" -#define DRV_MODULE_RELDATE "2011/01/30" +#define DRV_MODULE_VERSION "1.62.11-0" +#define DRV_MODULE_RELDATE "2011/01/31" #define BNX2X_BC_VER 0x040200 #define BNX2X_MULTI_QUEUE -- cgit v1.2.3 From 27a16811ab4dc819eebbd4e7b07d485f6e8f0134 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 31 Jan 2011 13:11:28 -0800 Subject: staging: fix rts_pstor build errors Fix multiple rts_pstor build errors. When CONFIG_PCI is not enabled: drivers/staging/rts_pstor/rtsx.c: In function 'rtsx_acquire_irq': drivers/staging/rts_pstor/rtsx.c:324: error: implicit declaration of function 'pci_intx' drivers/staging/rts_pstor/rtsx.c: In function 'rtsx_read_pci_cfg_byte': drivers/staging/rts_pstor/rtsx.c:336: error: implicit declaration of function 'pci_get_domain_bus_and_slot' drivers/staging/rts_pstor/rtsx.c:336: warning: assignment makes pointer from integer without a cast drivers/staging/rts_pstor/rtsx.c: In function 'rtsx_shutdown': drivers/staging/rts_pstor/rtsx.c:462: error: implicit declaration of function 'pci_disable_msi' drivers/staging/rts_pstor/rtsx.c: In function 'rtsx_probe': drivers/staging/rts_pstor/rtsx.c:981: error: implicit declaration of function 'pci_enable_msi' When CONFIG_SCSI is not enabled: In file included from drivers/staging/rts_pstor/rtsx.h:45, from drivers/staging/rts_pstor/rtsx.c:28: include/scsi/scsi_cmnd.h:27:25: warning: "BLK_MAX_CDB" is not defined include/scsi/scsi_cmnd.h:28:3: error: #error MAX_COMMAND_SIZE can not be bigger than BLK_MAX_CDB In file included from drivers/staging/rts_pstor/rtsx.h:45, from drivers/staging/rts_pstor/rtsx.c:28: include/scsi/scsi_cmnd.h: In function 'scsi_bidi_cmnd': include/scsi/scsi_cmnd.h:184: error: implicit declaration of function 'blk_bidi_rq' include/scsi/scsi_cmnd.h:185: error: dereferencing pointer to incomplete type include/scsi/scsi_cmnd.h: In function 'scsi_in': include/scsi/scsi_cmnd.h:191: error: dereferencing pointer to incomplete type include/scsi/scsi_cmnd.h: In function 'scsi_get_lba': CC drivers/gpu/drm/nouveau/nv04_tv.o include/scsi/scsi_cmnd.h:269: error: implicit declaration of function 'blk_rq_pos' In file included from drivers/staging/rts_pstor/rtsx.h:48, from drivers/staging/rts_pstor/rtsx.c:28: include/scsi/scsi_eh.h: At top level: include/scsi/scsi_eh.h:84: error: 'BLK_MAX_CDB' undeclared here (not in a function) drivers/staging/rts_pstor/rtsx.c: In function 'slave_configure': drivers/staging/rts_pstor/rtsx.c:107: error: implicit declaration of function 'blk_queue_dma_alignment' Signed-off-by: Randy Dunlap Cc: wei_wang@realsil.com.cn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts_pstor/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/rts_pstor/Kconfig b/drivers/staging/rts_pstor/Kconfig index 972becd011f1..4d66a99fba82 100644 --- a/drivers/staging/rts_pstor/Kconfig +++ b/drivers/staging/rts_pstor/Kconfig @@ -1,5 +1,6 @@ config RTS_PSTOR tristate "RealTek PCI-E Card Reader support" + depends on PCI && SCSI help Say Y here to include driver code to support the Realtek PCI-E card readers. -- cgit v1.2.3 From 8aea5882c54feb246ef20399cc55ae4672697ac0 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 25 Jan 2011 23:17:19 +0100 Subject: staging/go7007: remove the BKL There is nothing that the BKL can possibly protect here, so just remove it. Cc: Ross Cohen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/go7007/Kconfig | 1 - drivers/staging/go7007/s2250-loader.c | 3 --- 2 files changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/go7007/Kconfig b/drivers/staging/go7007/Kconfig index 1da57df5cbcb..7dfb2815b9ec 100644 --- a/drivers/staging/go7007/Kconfig +++ b/drivers/staging/go7007/Kconfig @@ -1,7 +1,6 @@ config VIDEO_GO7007 tristate "WIS GO7007 MPEG encoder support" depends on VIDEO_DEV && PCI && I2C - depends on BKL # please fix depends on SND select VIDEOBUF_DMA_SG depends on RC_CORE diff --git a/drivers/staging/go7007/s2250-loader.c b/drivers/staging/go7007/s2250-loader.c index 7547a8f77345..4e132519e253 100644 --- a/drivers/staging/go7007/s2250-loader.c +++ b/drivers/staging/go7007/s2250-loader.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -142,11 +141,9 @@ static void s2250loader_disconnect(struct usb_interface *interface) { pdevice_extension_t s; printk(KERN_INFO "s2250: disconnect\n"); - lock_kernel(); s = usb_get_intfdata(interface); usb_set_intfdata(interface, NULL); kref_put(&(s->kref), s2250loader_delete); - unlock_kernel(); } static const struct usb_device_id s2250loader_ids[] = { -- cgit v1.2.3 From 561c5cf9236a7eb5a52971b6e7e02c5bd094c6d5 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 25 Jan 2011 23:17:20 +0100 Subject: staging: Remove autofs3 autofs3 was moved to staging in 2.6.37, so we can remove it in the 2.6.39 merge window. If we have a reason to bring it back after that, this patch can get reverted. Signed-off-by: Arnd Bergmann About-fscking-timed-by: H. Peter Anvin Cc: Ian Kent Cc: autofs@linux.kernel.org Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 6 - drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/autofs/Kconfig | 22 -- drivers/staging/autofs/Makefile | 7 - drivers/staging/autofs/TODO | 8 - drivers/staging/autofs/autofs_i.h | 165 ---------- drivers/staging/autofs/dirhash.c | 260 --------------- drivers/staging/autofs/init.c | 52 --- drivers/staging/autofs/inode.c | 288 ----------------- drivers/staging/autofs/root.c | 648 -------------------------------------- drivers/staging/autofs/symlink.c | 26 -- drivers/staging/autofs/waitq.c | 205 ------------ 13 files changed, 1690 deletions(-) delete mode 100644 drivers/staging/autofs/Kconfig delete mode 100644 drivers/staging/autofs/Makefile delete mode 100644 drivers/staging/autofs/TODO delete mode 100644 drivers/staging/autofs/autofs_i.h delete mode 100644 drivers/staging/autofs/dirhash.c delete mode 100644 drivers/staging/autofs/init.c delete mode 100644 drivers/staging/autofs/inode.c delete mode 100644 drivers/staging/autofs/root.c delete mode 100644 drivers/staging/autofs/symlink.c delete mode 100644 drivers/staging/autofs/waitq.c (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index 1af022e63668..dd6ca456cde3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3559,12 +3559,6 @@ W: http://lse.sourceforge.net/kdump/ S: Maintained F: Documentation/kdump/ -KERNEL AUTOMOUNTER (AUTOFS) -M: "H. Peter Anvin" -L: autofs@linux.kernel.org -S: Obsolete -F: drivers/staging/autofs/ - KERNEL AUTOMOUNTER v4 (AUTOFS4) M: Ian Kent L: autofs@linux.kernel.org diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 9a5b7a6a97e4..8bcc153310c9 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -93,8 +93,6 @@ source "drivers/staging/frontier/Kconfig" source "drivers/staging/pohmelfs/Kconfig" -source "drivers/staging/autofs/Kconfig" - source "drivers/staging/phison/Kconfig" source "drivers/staging/line6/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 2057b89d4d05..0919a423398c 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -31,7 +31,6 @@ obj-$(CONFIG_RTS_PSTOR) += rts_pstor/ obj-$(CONFIG_SPECTRA) += spectra/ obj-$(CONFIG_TRANZPORT) += frontier/ obj-$(CONFIG_POHMELFS) += pohmelfs/ -obj-$(CONFIG_AUTOFS_FS) += autofs/ obj-$(CONFIG_IDE_PHISON) += phison/ obj-$(CONFIG_LINE6_USB) += line6/ obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/ diff --git a/drivers/staging/autofs/Kconfig b/drivers/staging/autofs/Kconfig deleted file mode 100644 index 480e210c83ab..000000000000 --- a/drivers/staging/autofs/Kconfig +++ /dev/null @@ -1,22 +0,0 @@ -config AUTOFS_FS - tristate "Kernel automounter support" - depends on BKL # unfixable, just use autofs4 - help - The automounter is a tool to automatically mount remote file systems - on demand. This implementation is partially kernel-based to reduce - overhead in the already-mounted case; this is unlike the BSD - automounter (amd), which is a pure user space daemon. - - To use the automounter you need the user-space tools from the autofs - package; you can find the location in . - You also want to answer Y to "NFS file system support", below. - - If you want to use the newer version of the automounter with more - features, say N here and say Y to "Kernel automounter v4 support", - below. - - To compile this support as a module, choose M here: the module will be - called autofs. - - If you are not a part of a fairly large, distributed network, you - probably do not need an automounter, and can say N here. diff --git a/drivers/staging/autofs/Makefile b/drivers/staging/autofs/Makefile deleted file mode 100644 index f48781c34df1..000000000000 --- a/drivers/staging/autofs/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for the linux autofs-filesystem routines. -# - -obj-$(CONFIG_AUTOFS_FS) += autofs.o - -autofs-y := dirhash.o init.o inode.o root.o symlink.o waitq.o diff --git a/drivers/staging/autofs/TODO b/drivers/staging/autofs/TODO deleted file mode 100644 index 543803d03993..000000000000 --- a/drivers/staging/autofs/TODO +++ /dev/null @@ -1,8 +0,0 @@ -autofs version 3 is on its way out of the kernel, -It has been replaced by autofs4 several years ago. - -The autofs3 code uses the big kernel lock which -is getting deprecated. - -Users that find autofs3 to work but not autofs4 -should talk to Ian Kent . diff --git a/drivers/staging/autofs/autofs_i.h b/drivers/staging/autofs/autofs_i.h deleted file mode 100644 index 647a14356e39..000000000000 --- a/drivers/staging/autofs/autofs_i.h +++ /dev/null @@ -1,165 +0,0 @@ -/* -*- linux-c -*- ------------------------------------------------------- * - * - * drivers/staging/autofs/autofs_i.h - * - * Copyright 1997-1998 Transmeta Corporation - All Rights Reserved - * - * This file is part of the Linux kernel and is made available under - * the terms of the GNU General Public License, version 2, or at your - * option, any later version, incorporated herein by reference. - * - * ----------------------------------------------------------------------- */ - -/* Internal header file for autofs */ - -#include - -/* This is the range of ioctl() numbers we claim as ours */ -#define AUTOFS_IOC_FIRST AUTOFS_IOC_READY -#define AUTOFS_IOC_COUNT 32 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifdef DEBUG -#define DPRINTK(D) (printk D) -#else -#define DPRINTK(D) ((void)0) -#endif - -/* - * If the daemon returns a negative response (AUTOFS_IOC_FAIL) then the - * kernel will keep the negative response cached for up to the time given - * here, although the time can be shorter if the kernel throws the dcache - * entry away. This probably should be settable from user space. - */ -#define AUTOFS_NEGATIVE_TIMEOUT (60*HZ) /* 1 minute */ - -/* Structures associated with the root directory hash table */ - -#define AUTOFS_HASH_SIZE 67 - -struct autofs_dir_ent { - int hash; - char *name; - int len; - ino_t ino; - struct dentry *dentry; - /* Linked list of entries */ - struct autofs_dir_ent *next; - struct autofs_dir_ent **back; - /* The following entries are for the expiry system */ - unsigned long last_usage; - struct list_head exp; -}; - -struct autofs_dirhash { - struct autofs_dir_ent *h[AUTOFS_HASH_SIZE]; - struct list_head expiry_head; -}; - -struct autofs_wait_queue { - wait_queue_head_t queue; - struct autofs_wait_queue *next; - autofs_wqt_t wait_queue_token; - /* We use the following to see what we are waiting for */ - int hash; - int len; - char *name; - /* This is for status reporting upon return */ - int status; - int wait_ctr; -}; - -struct autofs_symlink { - char *data; - int len; - time_t mtime; -}; - -#define AUTOFS_MAX_SYMLINKS 256 - -#define AUTOFS_ROOT_INO 1 -#define AUTOFS_FIRST_SYMLINK 2 -#define AUTOFS_FIRST_DIR_INO (AUTOFS_FIRST_SYMLINK+AUTOFS_MAX_SYMLINKS) - -#define AUTOFS_SYMLINK_BITMAP_LEN \ - ((AUTOFS_MAX_SYMLINKS+((sizeof(long)*1)-1))/(sizeof(long)*8)) - -#define AUTOFS_SBI_MAGIC 0x6d4a556d - -struct autofs_sb_info { - u32 magic; - struct file *pipe; - struct pid *oz_pgrp; - int catatonic; - struct super_block *sb; - unsigned long exp_timeout; - ino_t next_dir_ino; - struct autofs_wait_queue *queues; /* Wait queue pointer */ - struct autofs_dirhash dirhash; /* Root directory hash */ - struct autofs_symlink symlink[AUTOFS_MAX_SYMLINKS]; - unsigned long symlink_bitmap[AUTOFS_SYMLINK_BITMAP_LEN]; -}; - -static inline struct autofs_sb_info *autofs_sbi(struct super_block *sb) -{ - return (struct autofs_sb_info *)(sb->s_fs_info); -} - -/* autofs_oz_mode(): do we see the man behind the curtain? (The - processes which do manipulations for us in user space sees the raw - filesystem without "magic".) */ - -static inline int autofs_oz_mode(struct autofs_sb_info *sbi) { - return sbi->catatonic || task_pgrp(current) == sbi->oz_pgrp; -} - -/* Hash operations */ - -void autofs_initialize_hash(struct autofs_dirhash *); -struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *,struct qstr *); -void autofs_hash_insert(struct autofs_dirhash *,struct autofs_dir_ent *); -void autofs_hash_delete(struct autofs_dir_ent *); -struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *,off_t *,struct autofs_dir_ent *); -void autofs_hash_dputall(struct autofs_dirhash *); -void autofs_hash_nuke(struct autofs_sb_info *); - -/* Expiration-handling functions */ - -void autofs_update_usage(struct autofs_dirhash *,struct autofs_dir_ent *); -struct autofs_dir_ent *autofs_expire(struct super_block *,struct autofs_sb_info *, struct vfsmount *mnt); - -/* Operations structures */ - -extern const struct inode_operations autofs_root_inode_operations; -extern const struct inode_operations autofs_symlink_inode_operations; -extern const struct file_operations autofs_root_operations; - -/* Initializing function */ - -int autofs_fill_super(struct super_block *, void *, int); -void autofs_kill_sb(struct super_block *sb); -struct inode *autofs_iget(struct super_block *, unsigned long); - -/* Queue management functions */ - -int autofs_wait(struct autofs_sb_info *,struct qstr *); -int autofs_wait_release(struct autofs_sb_info *,autofs_wqt_t,int); -void autofs_catatonic_mode(struct autofs_sb_info *); - -#ifdef DEBUG -void autofs_say(const char *name, int len); -#else -#define autofs_say(n,l) ((void)0) -#endif diff --git a/drivers/staging/autofs/dirhash.c b/drivers/staging/autofs/dirhash.c deleted file mode 100644 index a08bd7355035..000000000000 --- a/drivers/staging/autofs/dirhash.c +++ /dev/null @@ -1,260 +0,0 @@ -/* -*- linux-c -*- --------------------------------------------------------- * - * - * drivers/staging/autofs/dirhash.c - * - * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved - * - * This file is part of the Linux kernel and is made available under - * the terms of the GNU General Public License, version 2, or at your - * option, any later version, incorporated herein by reference. - * - * ------------------------------------------------------------------------- */ - -#include "autofs_i.h" - -/* Functions for maintenance of expiry queue */ - -static void autofs_init_usage(struct autofs_dirhash *dh, - struct autofs_dir_ent *ent) -{ - list_add_tail(&ent->exp, &dh->expiry_head); - ent->last_usage = jiffies; -} - -static void autofs_delete_usage(struct autofs_dir_ent *ent) -{ - list_del(&ent->exp); -} - -void autofs_update_usage(struct autofs_dirhash *dh, - struct autofs_dir_ent *ent) -{ - autofs_delete_usage(ent); /* Unlink from current position */ - autofs_init_usage(dh, ent); /* Relink at queue tail */ -} - -struct autofs_dir_ent *autofs_expire(struct super_block *sb, - struct autofs_sb_info *sbi, - struct vfsmount *mnt) -{ - struct autofs_dirhash *dh = &sbi->dirhash; - struct autofs_dir_ent *ent; - unsigned long timeout = sbi->exp_timeout; - - while (1) { - struct path path; - int umount_ok; - - if (list_empty(&dh->expiry_head) || sbi->catatonic) - return NULL; /* No entries */ - /* We keep the list sorted by last_usage and want old stuff */ - ent = list_entry(dh->expiry_head.next, - struct autofs_dir_ent, exp); - if (jiffies - ent->last_usage < timeout) - break; - /* Move to end of list in case expiry isn't desirable */ - autofs_update_usage(dh, ent); - - /* Check to see that entry is expirable */ - if (ent->ino < AUTOFS_FIRST_DIR_INO) - return ent; /* Symlinks are always expirable */ - - /* Get the dentry for the autofs subdirectory */ - path.dentry = ent->dentry; - - if (!path.dentry) { - /* Should only happen in catatonic mode */ - printk(KERN_DEBUG "autofs: dentry == NULL but inode \ - range is directory, entry %s\n", ent->name); - autofs_delete_usage(ent); - continue; - } - - if (!path.dentry->d_inode) { - dput(path.dentry); - printk(KERN_DEBUG "autofs: negative dentry on expiry queue: %s\n", - ent->name); - autofs_delete_usage(ent); - continue; - } - - /* Make sure entry is mounted and unused; note that dentry will - point to the mounted-on-top root. */ - if (!S_ISDIR(path.dentry->d_inode->i_mode) || - !d_mountpoint(path.dentry)) { - DPRINTK(("autofs: not expirable \ - (not a mounted directory): %s\n", ent->name)); - continue; - } - path.mnt = mnt; - path_get(&path); - if (!follow_down_one(&path)) { - path_put(&path); - DPRINTK(("autofs: not expirable\ - (not a mounted directory): %s\n", ent->name)); - continue; - } - follow_down(&path, false); // TODO: need to check error - umount_ok = may_umount(path.mnt); - path_put(&path); - - if (umount_ok) { - DPRINTK(("autofs: signaling expire on %s\n", - ent->name)); - return ent; /* Expirable! */ - } - - DPRINTK(("autofs: didn't expire due to may_umount: %s\n", - ent->name)); - } - return NULL; /* No expirable entries */ -} - -void autofs_initialize_hash(struct autofs_dirhash *dh) -{ - memset(&dh->h, 0, AUTOFS_HASH_SIZE*sizeof(struct autofs_dir_ent *)); - INIT_LIST_HEAD(&dh->expiry_head); -} - -struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *dh, - struct qstr *name) -{ - struct autofs_dir_ent *dhn; - - DPRINTK(("autofs_hash_lookup: hash = 0x%08x, name = ", name->hash)); - autofs_say(name->name, name->len); - - for (dhn = dh->h[(unsigned) name->hash % AUTOFS_HASH_SIZE]; - dhn; - dhn = dhn->next) { - if (name->hash == dhn->hash && - name->len == dhn->len && - !memcmp(name->name, dhn->name, name->len)) - break; - } - - return dhn; -} - -void autofs_hash_insert(struct autofs_dirhash *dh, struct autofs_dir_ent *ent) -{ - struct autofs_dir_ent **dhnp; - - DPRINTK(("autofs_hash_insert: hash = 0x%08x, name = ", ent->hash)); - autofs_say(ent->name, ent->len); - - autofs_init_usage(dh, ent); - if (ent->dentry) - dget(ent->dentry); - - dhnp = &dh->h[(unsigned) ent->hash % AUTOFS_HASH_SIZE]; - ent->next = *dhnp; - ent->back = dhnp; - *dhnp = ent; - if (ent->next) - ent->next->back = &(ent->next); -} - -void autofs_hash_delete(struct autofs_dir_ent *ent) -{ - *(ent->back) = ent->next; - if (ent->next) - ent->next->back = ent->back; - - autofs_delete_usage(ent); - - if (ent->dentry) - dput(ent->dentry); - kfree(ent->name); - kfree(ent); -} - -/* - * Used by readdir(). We must validate "ptr", so we can't simply make it - * a pointer. Values below 0xffff are reserved; calling with any value - * <= 0x10000 will return the first entry found. - * - * "last" can be NULL or the value returned by the last search *if* we - * want the next sequential entry. - */ -struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *dh, - off_t *ptr, struct autofs_dir_ent *last) -{ - int bucket, ecount, i; - struct autofs_dir_ent *ent; - - bucket = (*ptr >> 16) - 1; - ecount = *ptr & 0xffff; - - if (bucket < 0) - bucket = ecount = 0; - - DPRINTK(("autofs_hash_enum: bucket %d, entry %d\n", bucket, ecount)); - - ent = last ? last->next : NULL; - - if (ent) { - ecount++; - } else { - while (bucket < AUTOFS_HASH_SIZE) { - ent = dh->h[bucket]; - for (i = ecount ; ent && i ; i--) - ent = ent->next; - - if (ent) { - ecount++; /* Point to *next* entry */ - break; - } - - bucket++; ecount = 0; - } - } - -#ifdef DEBUG - if (!ent) - printk(KERN_DEBUG "autofs_hash_enum: nothing found\n"); - else { - printk(KERN_DEBUG "autofs_hash_enum: found hash %08x, name", - ent->hash); - autofs_say(ent->name, ent->len); - } -#endif - - *ptr = ((bucket+1) << 16) + ecount; - return ent; -} - -/* Iterate over all the ents, and remove all dentry pointers. Used on - entering catatonic mode, in order to make the filesystem unmountable. */ -void autofs_hash_dputall(struct autofs_dirhash *dh) -{ - int i; - struct autofs_dir_ent *ent; - - for (i = 0 ; i < AUTOFS_HASH_SIZE ; i++) { - for (ent = dh->h[i] ; ent ; ent = ent->next) { - if (ent->dentry) { - dput(ent->dentry); - ent->dentry = NULL; - } - } - } -} - -/* Delete everything. This is used on filesystem destruction, so we - make no attempt to keep the pointers valid */ -void autofs_hash_nuke(struct autofs_sb_info *sbi) -{ - int i; - struct autofs_dir_ent *ent, *nent; - - for (i = 0 ; i < AUTOFS_HASH_SIZE ; i++) { - for (ent = sbi->dirhash.h[i] ; ent ; ent = nent) { - nent = ent->next; - if (ent->dentry) - dput(ent->dentry); - kfree(ent->name); - kfree(ent); - } - } -} diff --git a/drivers/staging/autofs/init.c b/drivers/staging/autofs/init.c deleted file mode 100644 index 5e4b372ea663..000000000000 --- a/drivers/staging/autofs/init.c +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- linux-c -*- --------------------------------------------------------- * - * - * drivers/staging/autofs/init.c - * - * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved - * - * This file is part of the Linux kernel and is made available under - * the terms of the GNU General Public License, version 2, or at your - * option, any later version, incorporated herein by reference. - * - * ------------------------------------------------------------------------- */ - -#include -#include -#include "autofs_i.h" - -static struct dentry *autofs_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) -{ - return mount_nodev(fs_type, flags, data, autofs_fill_super); -} - -static struct file_system_type autofs_fs_type = { - .owner = THIS_MODULE, - .name = "autofs", - .mount = autofs_mount, - .kill_sb = autofs_kill_sb, -}; - -static int __init init_autofs_fs(void) -{ - return register_filesystem(&autofs_fs_type); -} - -static void __exit exit_autofs_fs(void) -{ - unregister_filesystem(&autofs_fs_type); -} - -module_init(init_autofs_fs); -module_exit(exit_autofs_fs); - -#ifdef DEBUG -void autofs_say(const char *name, int len) -{ - printk("(%d: ", len); - while ( len-- ) - printk("%c", *name++); - printk(")\n"); -} -#endif -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/autofs/inode.c b/drivers/staging/autofs/inode.c deleted file mode 100644 index 74db190ae845..000000000000 --- a/drivers/staging/autofs/inode.c +++ /dev/null @@ -1,288 +0,0 @@ -/* -*- linux-c -*- --------------------------------------------------------- * - * - * drivers/staging/autofs/inode.c - * - * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved - * - * This file is part of the Linux kernel and is made available under - * the terms of the GNU General Public License, version 2, or at your - * option, any later version, incorporated herein by reference. - * - * ------------------------------------------------------------------------- */ - -#include -#include -#include -#include -#include -#include -#include -#include "autofs_i.h" -#include - -void autofs_kill_sb(struct super_block *sb) -{ - struct autofs_sb_info *sbi = autofs_sbi(sb); - unsigned int n; - - /* - * In the event of a failure in get_sb_nodev the superblock - * info is not present so nothing else has been setup, so - * just call kill_anon_super when we are called from - * deactivate_super. - */ - if (!sbi) - goto out_kill_sb; - - if (!sbi->catatonic) - autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */ - - put_pid(sbi->oz_pgrp); - - autofs_hash_nuke(sbi); - for (n = 0; n < AUTOFS_MAX_SYMLINKS; n++) { - if (test_bit(n, sbi->symlink_bitmap)) - kfree(sbi->symlink[n].data); - } - - kfree(sb->s_fs_info); - -out_kill_sb: - DPRINTK(("autofs: shutting down\n")); - kill_anon_super(sb); -} - -static const struct super_operations autofs_sops = { - .statfs = simple_statfs, - .show_options = generic_show_options, -}; - -enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto}; - -static const match_table_t autofs_tokens = { - {Opt_fd, "fd=%u"}, - {Opt_uid, "uid=%u"}, - {Opt_gid, "gid=%u"}, - {Opt_pgrp, "pgrp=%u"}, - {Opt_minproto, "minproto=%u"}, - {Opt_maxproto, "maxproto=%u"}, - {Opt_err, NULL} -}; - -static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, - pid_t *pgrp, int *minproto, int *maxproto) -{ - char *p; - substring_t args[MAX_OPT_ARGS]; - int option; - - *uid = current_uid(); - *gid = current_gid(); - *pgrp = task_pgrp_nr(current); - - *minproto = *maxproto = AUTOFS_PROTO_VERSION; - - *pipefd = -1; - - if (!options) - return 1; - - while ((p = strsep(&options, ",")) != NULL) { - int token; - if (!*p) - continue; - - token = match_token(p, autofs_tokens, args); - switch (token) { - case Opt_fd: - if (match_int(&args[0], &option)) - return 1; - *pipefd = option; - break; - case Opt_uid: - if (match_int(&args[0], &option)) - return 1; - *uid = option; - break; - case Opt_gid: - if (match_int(&args[0], &option)) - return 1; - *gid = option; - break; - case Opt_pgrp: - if (match_int(&args[0], &option)) - return 1; - *pgrp = option; - break; - case Opt_minproto: - if (match_int(&args[0], &option)) - return 1; - *minproto = option; - break; - case Opt_maxproto: - if (match_int(&args[0], &option)) - return 1; - *maxproto = option; - break; - default: - return 1; - } - } - return (*pipefd < 0); -} - -int autofs_fill_super(struct super_block *s, void *data, int silent) -{ - struct inode * root_inode; - struct dentry * root; - struct file * pipe; - int pipefd; - struct autofs_sb_info *sbi; - int minproto, maxproto; - pid_t pgid; - - save_mount_options(s, data); - - sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); - if (!sbi) - goto fail_unlock; - DPRINTK(("autofs: starting up, sbi = %p\n",sbi)); - - s->s_fs_info = sbi; - sbi->magic = AUTOFS_SBI_MAGIC; - sbi->pipe = NULL; - sbi->catatonic = 1; - sbi->exp_timeout = 0; - autofs_initialize_hash(&sbi->dirhash); - sbi->queues = NULL; - memset(sbi->symlink_bitmap, 0, sizeof(long)*AUTOFS_SYMLINK_BITMAP_LEN); - sbi->next_dir_ino = AUTOFS_FIRST_DIR_INO; - s->s_blocksize = 1024; - s->s_blocksize_bits = 10; - s->s_magic = AUTOFS_SUPER_MAGIC; - s->s_op = &autofs_sops; - s->s_time_gran = 1; - sbi->sb = s; - - root_inode = autofs_iget(s, AUTOFS_ROOT_INO); - if (IS_ERR(root_inode)) - goto fail_free; - root = d_alloc_root(root_inode); - pipe = NULL; - - if (!root) - goto fail_iput; - - /* Can this call block? - WTF cares? s is locked. */ - if (parse_options(data, &pipefd, &root_inode->i_uid, - &root_inode->i_gid, &pgid, &minproto, - &maxproto)) { - printk("autofs: called with bogus options\n"); - goto fail_dput; - } - - /* Couldn't this be tested earlier? */ - if (minproto > AUTOFS_PROTO_VERSION || - maxproto < AUTOFS_PROTO_VERSION) { - printk("autofs: kernel does not match daemon version\n"); - goto fail_dput; - } - - DPRINTK(("autofs: pipe fd = %d, pgrp = %u\n", pipefd, pgid)); - sbi->oz_pgrp = find_get_pid(pgid); - - if (!sbi->oz_pgrp) { - printk("autofs: could not find process group %d\n", pgid); - goto fail_dput; - } - - pipe = fget(pipefd); - - if (!pipe) { - printk("autofs: could not open pipe file descriptor\n"); - goto fail_put_pid; - } - - if (!pipe->f_op || !pipe->f_op->write) - goto fail_fput; - sbi->pipe = pipe; - sbi->catatonic = 0; - - /* - * Success! Install the root dentry now to indicate completion. - */ - s->s_root = root; - return 0; - -fail_fput: - printk("autofs: pipe file descriptor does not contain proper ops\n"); - fput(pipe); -fail_put_pid: - put_pid(sbi->oz_pgrp); -fail_dput: - dput(root); - goto fail_free; -fail_iput: - printk("autofs: get root dentry failed\n"); - iput(root_inode); -fail_free: - kfree(sbi); - s->s_fs_info = NULL; -fail_unlock: - return -EINVAL; -} - -struct inode *autofs_iget(struct super_block *sb, unsigned long ino) -{ - unsigned int n; - struct autofs_sb_info *sbi = autofs_sbi(sb); - struct inode *inode; - - inode = iget_locked(sb, ino); - if (!inode) - return ERR_PTR(-ENOMEM); - if (!(inode->i_state & I_NEW)) - return inode; - - /* Initialize to the default case (stub directory) */ - - inode->i_op = &simple_dir_inode_operations; - inode->i_fop = &simple_dir_operations; - inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; - inode->i_nlink = 2; - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; - - if (ino == AUTOFS_ROOT_INO) { - inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR; - inode->i_op = &autofs_root_inode_operations; - inode->i_fop = &autofs_root_operations; - goto done; - } - - inode->i_uid = inode->i_sb->s_root->d_inode->i_uid; - inode->i_gid = inode->i_sb->s_root->d_inode->i_gid; - - if (ino >= AUTOFS_FIRST_SYMLINK && ino < AUTOFS_FIRST_DIR_INO) { - /* Symlink inode - should be in symlink list */ - struct autofs_symlink *sl; - - n = ino - AUTOFS_FIRST_SYMLINK; - if (n >= AUTOFS_MAX_SYMLINKS || !test_bit(n,sbi->symlink_bitmap)) { - printk("autofs: Looking for bad symlink inode %u\n", (unsigned int) ino); - goto done; - } - - inode->i_op = &autofs_symlink_inode_operations; - sl = &sbi->symlink[n]; - inode->i_private = sl; - inode->i_mode = S_IFLNK | S_IRWXUGO; - inode->i_mtime.tv_sec = inode->i_ctime.tv_sec = sl->mtime; - inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = 0; - inode->i_size = sl->len; - inode->i_nlink = 1; - } - -done: - unlock_new_inode(inode); - return inode; -} diff --git a/drivers/staging/autofs/root.c b/drivers/staging/autofs/root.c deleted file mode 100644 index bf0e9755da67..000000000000 --- a/drivers/staging/autofs/root.c +++ /dev/null @@ -1,648 +0,0 @@ -/* -*- linux-c -*- --------------------------------------------------------- * - * - * drivers/staging/autofs/root.c - * - * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved - * - * This file is part of the Linux kernel and is made available under - * the terms of the GNU General Public License, version 2, or at your - * option, any later version, incorporated herein by reference. - * - * ------------------------------------------------------------------------- */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "autofs_i.h" - -static int autofs_root_readdir(struct file *,void *,filldir_t); -static struct dentry *autofs_root_lookup(struct inode *,struct dentry *, struct nameidata *); -static int autofs_root_symlink(struct inode *,struct dentry *,const char *); -static int autofs_root_unlink(struct inode *,struct dentry *); -static int autofs_root_rmdir(struct inode *,struct dentry *); -static int autofs_root_mkdir(struct inode *,struct dentry *,int); -static long autofs_root_ioctl(struct file *,unsigned int,unsigned long); -#ifdef CONFIG_COMPAT -static long autofs_root_compat_ioctl(struct file *,unsigned int,unsigned long); -#endif - -const struct file_operations autofs_root_operations = { - .llseek = generic_file_llseek, - .read = generic_read_dir, - .readdir = autofs_root_readdir, - .unlocked_ioctl = autofs_root_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = autofs_root_compat_ioctl, -#endif -}; - -const struct inode_operations autofs_root_inode_operations = { - .lookup = autofs_root_lookup, - .unlink = autofs_root_unlink, - .symlink = autofs_root_symlink, - .mkdir = autofs_root_mkdir, - .rmdir = autofs_root_rmdir, -}; - -static int autofs_root_readdir(struct file *filp, void *dirent, filldir_t filldir) -{ - struct autofs_dir_ent *ent = NULL; - struct autofs_dirhash *dirhash; - struct autofs_sb_info *sbi; - struct inode * inode = filp->f_path.dentry->d_inode; - off_t onr, nr; - - lock_kernel(); - - sbi = autofs_sbi(inode->i_sb); - dirhash = &sbi->dirhash; - nr = filp->f_pos; - - switch(nr) - { - case 0: - if (filldir(dirent, ".", 1, nr, inode->i_ino, DT_DIR) < 0) - goto out; - filp->f_pos = ++nr; - /* fall through */ - case 1: - if (filldir(dirent, "..", 2, nr, inode->i_ino, DT_DIR) < 0) - goto out; - filp->f_pos = ++nr; - /* fall through */ - default: - while (onr = nr, ent = autofs_hash_enum(dirhash,&nr,ent)) { - if (!ent->dentry || d_mountpoint(ent->dentry)) { - if (filldir(dirent,ent->name,ent->len,onr,ent->ino,DT_UNKNOWN) < 0) - goto out; - filp->f_pos = nr; - } - } - break; - } - -out: - unlock_kernel(); - return 0; -} - -static int try_to_fill_dentry(struct dentry *dentry, struct super_block *sb, struct autofs_sb_info *sbi) -{ - struct inode * inode; - struct autofs_dir_ent *ent; - int status = 0; - - if (!(ent = autofs_hash_lookup(&sbi->dirhash, &dentry->d_name))) { - do { - if (status && dentry->d_inode) { - if (status != -ENOENT) - printk("autofs warning: lookup failure on positive dentry, status = %d, name = %s\n", status, dentry->d_name.name); - return 0; /* Try to get the kernel to invalidate this dentry */ - } - - /* Turn this into a real negative dentry? */ - if (status == -ENOENT) { - dentry->d_time = jiffies + AUTOFS_NEGATIVE_TIMEOUT; - dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; - return 1; - } else if (status) { - /* Return a negative dentry, but leave it "pending" */ - return 1; - } - status = autofs_wait(sbi, &dentry->d_name); - } while (!(ent = autofs_hash_lookup(&sbi->dirhash, &dentry->d_name))); - } - - /* Abuse this field as a pointer to the directory entry, used to - find the expire list pointers */ - dentry->d_time = (unsigned long) ent; - - if (!dentry->d_inode) { - inode = autofs_iget(sb, ent->ino); - if (IS_ERR(inode)) { - /* Failed, but leave pending for next time */ - return 1; - } - dentry->d_inode = inode; - } - - /* If this is a directory that isn't a mount point, bitch at the - daemon and fix it in user space */ - if (S_ISDIR(dentry->d_inode->i_mode) && !d_mountpoint(dentry)) { - return !autofs_wait(sbi, &dentry->d_name); - } - - /* We don't update the usages for the autofs daemon itself, this - is necessary for recursive autofs mounts */ - if (!autofs_oz_mode(sbi)) { - autofs_update_usage(&sbi->dirhash,ent); - } - - dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; - return 1; -} - - -/* - * Revalidate is called on every cache lookup. Some of those - * cache lookups may actually happen while the dentry is not - * yet completely filled in, and revalidate has to delay such - * lookups.. - */ -static int autofs_revalidate(struct dentry *dentry, struct nameidata *nd) -{ - struct inode * dir; - struct autofs_sb_info *sbi; - struct autofs_dir_ent *ent; - int res; - - if (nd->flags & LOOKUP_RCU) - return -ECHILD; - - lock_kernel(); - dir = dentry->d_parent->d_inode; - sbi = autofs_sbi(dir->i_sb); - - /* Pending dentry */ - if (dentry->d_flags & DCACHE_AUTOFS_PENDING) { - if (autofs_oz_mode(sbi)) - res = 1; - else - res = try_to_fill_dentry(dentry, dir->i_sb, sbi); - unlock_kernel(); - return res; - } - - /* Negative dentry.. invalidate if "old" */ - if (!dentry->d_inode) { - unlock_kernel(); - return (dentry->d_time - jiffies <= AUTOFS_NEGATIVE_TIMEOUT); - } - - /* Check for a non-mountpoint directory */ - if (S_ISDIR(dentry->d_inode->i_mode) && !d_mountpoint(dentry)) { - if (autofs_oz_mode(sbi)) - res = 1; - else - res = try_to_fill_dentry(dentry, dir->i_sb, sbi); - unlock_kernel(); - return res; - } - - /* Update the usage list */ - if (!autofs_oz_mode(sbi)) { - ent = (struct autofs_dir_ent *) dentry->d_time; - if (ent) - autofs_update_usage(&sbi->dirhash,ent); - } - unlock_kernel(); - return 1; -} - -static const struct dentry_operations autofs_dentry_operations = { - .d_revalidate = autofs_revalidate, -}; - -static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -{ - struct autofs_sb_info *sbi; - int oz_mode; - - DPRINTK(("autofs_root_lookup: name = ")); - lock_kernel(); - autofs_say(dentry->d_name.name,dentry->d_name.len); - - if (dentry->d_name.len > NAME_MAX) { - unlock_kernel(); - return ERR_PTR(-ENAMETOOLONG);/* File name too long to exist */ - } - - sbi = autofs_sbi(dir->i_sb); - - oz_mode = autofs_oz_mode(sbi); - DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, " - "oz_mode = %d\n", task_pid_nr(current), - task_pgrp_nr(current), sbi->catatonic, - oz_mode)); - - /* - * Mark the dentry incomplete, but add it. This is needed so - * that the VFS layer knows about the dentry, and we can count - * on catching any lookups through the revalidate. - * - * Let all the hard work be done by the revalidate function that - * needs to be able to do this anyway.. - * - * We need to do this before we release the directory semaphore. - */ - d_set_d_op(dentry, &autofs_dentry_operations); - dentry->d_flags |= DCACHE_AUTOFS_PENDING; - d_add(dentry, NULL); - - mutex_unlock(&dir->i_mutex); - autofs_revalidate(dentry, nd); - mutex_lock(&dir->i_mutex); - - /* - * If we are still pending, check if we had to handle - * a signal. If so we can force a restart.. - */ - if (dentry->d_flags & DCACHE_AUTOFS_PENDING) { - /* See if we were interrupted */ - if (signal_pending(current)) { - sigset_t *sigset = ¤t->pending.signal; - if (sigismember (sigset, SIGKILL) || - sigismember (sigset, SIGQUIT) || - sigismember (sigset, SIGINT)) { - unlock_kernel(); - return ERR_PTR(-ERESTARTNOINTR); - } - } - } - unlock_kernel(); - - /* - * If this dentry is unhashed, then we shouldn't honour this - * lookup even if the dentry is positive. Returning ENOENT here - * doesn't do the right thing for all system calls, but it should - * be OK for the operations we permit from an autofs. - */ - if (dentry->d_inode && d_unhashed(dentry)) - return ERR_PTR(-ENOENT); - - return NULL; -} - -static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const char *symname) -{ - struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb); - struct autofs_dirhash *dh = &sbi->dirhash; - struct autofs_dir_ent *ent; - unsigned int n; - int slsize; - struct autofs_symlink *sl; - struct inode *inode; - - DPRINTK(("autofs_root_symlink: %s <- ", symname)); - autofs_say(dentry->d_name.name,dentry->d_name.len); - - lock_kernel(); - if (!autofs_oz_mode(sbi)) { - unlock_kernel(); - return -EACCES; - } - - if (autofs_hash_lookup(dh, &dentry->d_name)) { - unlock_kernel(); - return -EEXIST; - } - - n = find_first_zero_bit(sbi->symlink_bitmap,AUTOFS_MAX_SYMLINKS); - if (n >= AUTOFS_MAX_SYMLINKS) { - unlock_kernel(); - return -ENOSPC; - } - - set_bit(n,sbi->symlink_bitmap); - sl = &sbi->symlink[n]; - sl->len = strlen(symname); - sl->data = kmalloc(slsize = sl->len+1, GFP_KERNEL); - if (!sl->data) { - clear_bit(n,sbi->symlink_bitmap); - unlock_kernel(); - return -ENOSPC; - } - - ent = kmalloc(sizeof(struct autofs_dir_ent), GFP_KERNEL); - if (!ent) { - kfree(sl->data); - clear_bit(n,sbi->symlink_bitmap); - unlock_kernel(); - return -ENOSPC; - } - - ent->name = kmalloc(dentry->d_name.len+1, GFP_KERNEL); - if (!ent->name) { - kfree(sl->data); - kfree(ent); - clear_bit(n,sbi->symlink_bitmap); - unlock_kernel(); - return -ENOSPC; - } - - memcpy(sl->data,symname,slsize); - sl->mtime = get_seconds(); - - ent->ino = AUTOFS_FIRST_SYMLINK + n; - ent->hash = dentry->d_name.hash; - memcpy(ent->name, dentry->d_name.name, 1+(ent->len = dentry->d_name.len)); - ent->dentry = NULL; /* We don't keep the dentry for symlinks */ - - autofs_hash_insert(dh,ent); - - inode = autofs_iget(dir->i_sb, ent->ino); - if (IS_ERR(inode)) - return PTR_ERR(inode); - - d_instantiate(dentry, inode); - unlock_kernel(); - return 0; -} - -/* - * NOTE! - * - * Normal filesystems would do a "d_delete()" to tell the VFS dcache - * that the file no longer exists. However, doing that means that the - * VFS layer can turn the dentry into a negative dentry, which we - * obviously do not want (we're dropping the entry not because it - * doesn't exist, but because it has timed out). - * - * Also see autofs_root_rmdir().. - */ -static int autofs_root_unlink(struct inode *dir, struct dentry *dentry) -{ - struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb); - struct autofs_dirhash *dh = &sbi->dirhash; - struct autofs_dir_ent *ent; - unsigned int n; - - /* This allows root to remove symlinks */ - lock_kernel(); - if (!autofs_oz_mode(sbi) && !capable(CAP_SYS_ADMIN)) { - unlock_kernel(); - return -EACCES; - } - - ent = autofs_hash_lookup(dh, &dentry->d_name); - if (!ent) { - unlock_kernel(); - return -ENOENT; - } - - n = ent->ino - AUTOFS_FIRST_SYMLINK; - if (n >= AUTOFS_MAX_SYMLINKS) { - unlock_kernel(); - return -EISDIR; /* It's a directory, dummy */ - } - if (!test_bit(n,sbi->symlink_bitmap)) { - unlock_kernel(); - return -EINVAL; /* Nonexistent symlink? Shouldn't happen */ - } - - dentry->d_time = (unsigned long)(struct autofs_dirhash *)NULL; - autofs_hash_delete(ent); - clear_bit(n,sbi->symlink_bitmap); - kfree(sbi->symlink[n].data); - d_drop(dentry); - - unlock_kernel(); - return 0; -} - -static int autofs_root_rmdir(struct inode *dir, struct dentry *dentry) -{ - struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb); - struct autofs_dirhash *dh = &sbi->dirhash; - struct autofs_dir_ent *ent; - - lock_kernel(); - if (!autofs_oz_mode(sbi)) { - unlock_kernel(); - return -EACCES; - } - - ent = autofs_hash_lookup(dh, &dentry->d_name); - if (!ent) { - unlock_kernel(); - return -ENOENT; - } - - if ((unsigned int)ent->ino < AUTOFS_FIRST_DIR_INO) { - unlock_kernel(); - return -ENOTDIR; /* Not a directory */ - } - - if (ent->dentry != dentry) { - printk("autofs_rmdir: odentry != dentry for entry %s\n", dentry->d_name.name); - } - - dentry->d_time = (unsigned long)(struct autofs_dir_ent *)NULL; - autofs_hash_delete(ent); - drop_nlink(dir); - d_drop(dentry); - unlock_kernel(); - - return 0; -} - -static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode) -{ - struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb); - struct autofs_dirhash *dh = &sbi->dirhash; - struct autofs_dir_ent *ent; - struct inode *inode; - ino_t ino; - - lock_kernel(); - if (!autofs_oz_mode(sbi)) { - unlock_kernel(); - return -EACCES; - } - - ent = autofs_hash_lookup(dh, &dentry->d_name); - if (ent) { - unlock_kernel(); - return -EEXIST; - } - - if (sbi->next_dir_ino < AUTOFS_FIRST_DIR_INO) { - printk("autofs: Out of inode numbers -- what the heck did you do??\n"); - unlock_kernel(); - return -ENOSPC; - } - ino = sbi->next_dir_ino++; - - ent = kmalloc(sizeof(struct autofs_dir_ent), GFP_KERNEL); - if (!ent) { - unlock_kernel(); - return -ENOSPC; - } - - ent->name = kmalloc(dentry->d_name.len+1, GFP_KERNEL); - if (!ent->name) { - kfree(ent); - unlock_kernel(); - return -ENOSPC; - } - - ent->hash = dentry->d_name.hash; - memcpy(ent->name, dentry->d_name.name, 1+(ent->len = dentry->d_name.len)); - ent->ino = ino; - ent->dentry = dentry; - autofs_hash_insert(dh,ent); - - inc_nlink(dir); - - inode = autofs_iget(dir->i_sb, ino); - if (IS_ERR(inode)) { - drop_nlink(dir); - return PTR_ERR(inode); - } - - d_instantiate(dentry, inode); - unlock_kernel(); - - return 0; -} - -/* Get/set timeout ioctl() operation */ -#ifdef CONFIG_COMPAT -static inline int autofs_compat_get_set_timeout(struct autofs_sb_info *sbi, - unsigned int __user *p) -{ - unsigned long ntimeout; - - if (get_user(ntimeout, p) || - put_user(sbi->exp_timeout / HZ, p)) - return -EFAULT; - - if (ntimeout > UINT_MAX/HZ) - sbi->exp_timeout = 0; - else - sbi->exp_timeout = ntimeout * HZ; - - return 0; -} -#endif - -static inline int autofs_get_set_timeout(struct autofs_sb_info *sbi, - unsigned long __user *p) -{ - unsigned long ntimeout; - - if (get_user(ntimeout, p) || - put_user(sbi->exp_timeout / HZ, p)) - return -EFAULT; - - if (ntimeout > ULONG_MAX/HZ) - sbi->exp_timeout = 0; - else - sbi->exp_timeout = ntimeout * HZ; - - return 0; -} - -/* Return protocol version */ -static inline int autofs_get_protover(int __user *p) -{ - return put_user(AUTOFS_PROTO_VERSION, p); -} - -/* Perform an expiry operation */ -static inline int autofs_expire_run(struct super_block *sb, - struct autofs_sb_info *sbi, - struct vfsmount *mnt, - struct autofs_packet_expire __user *pkt_p) -{ - struct autofs_dir_ent *ent; - struct autofs_packet_expire pkt; - - memset(&pkt,0,sizeof pkt); - - pkt.hdr.proto_version = AUTOFS_PROTO_VERSION; - pkt.hdr.type = autofs_ptype_expire; - - if (!sbi->exp_timeout || !(ent = autofs_expire(sb,sbi,mnt))) - return -EAGAIN; - - pkt.len = ent->len; - memcpy(pkt.name, ent->name, pkt.len); - pkt.name[pkt.len] = '\0'; - - if (copy_to_user(pkt_p, &pkt, sizeof(struct autofs_packet_expire))) - return -EFAULT; - - return 0; -} - -/* - * ioctl()'s on the root directory is the chief method for the daemon to - * generate kernel reactions - */ -static int autofs_do_root_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb); - void __user *argp = (void __user *)arg; - - DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,task_pgrp_nr(current))); - - if (_IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) || - _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT) - return -ENOTTY; - - if (!autofs_oz_mode(sbi) && !capable(CAP_SYS_ADMIN)) - return -EPERM; - - switch(cmd) { - case AUTOFS_IOC_READY: /* Wait queue: go ahead and retry */ - return autofs_wait_release(sbi,(autofs_wqt_t)arg,0); - case AUTOFS_IOC_FAIL: /* Wait queue: fail with ENOENT */ - return autofs_wait_release(sbi,(autofs_wqt_t)arg,-ENOENT); - case AUTOFS_IOC_CATATONIC: /* Enter catatonic mode (daemon shutdown) */ - autofs_catatonic_mode(sbi); - return 0; - case AUTOFS_IOC_PROTOVER: /* Get protocol version */ - return autofs_get_protover(argp); -#ifdef CONFIG_COMPAT - case AUTOFS_IOC_SETTIMEOUT32: - return autofs_compat_get_set_timeout(sbi, argp); -#endif - case AUTOFS_IOC_SETTIMEOUT: - return autofs_get_set_timeout(sbi, argp); - case AUTOFS_IOC_EXPIRE: - return autofs_expire_run(inode->i_sb, sbi, filp->f_path.mnt, - argp); - default: - return -ENOSYS; - } - -} - -static long autofs_root_ioctl(struct file *filp, - unsigned int cmd, unsigned long arg) -{ - int ret; - - lock_kernel(); - ret = autofs_do_root_ioctl(filp->f_path.dentry->d_inode, - filp, cmd, arg); - unlock_kernel(); - - return ret; -} - -#ifdef CONFIG_COMPAT -static long autofs_root_compat_ioctl(struct file *filp, - unsigned int cmd, unsigned long arg) -{ - struct inode *inode = filp->f_path.dentry->d_inode; - int ret; - - lock_kernel(); - if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL) - ret = autofs_do_root_ioctl(inode, filp, cmd, arg); - else - ret = autofs_do_root_ioctl(inode, filp, cmd, - (unsigned long)compat_ptr(arg)); - unlock_kernel(); - - return ret; -} -#endif diff --git a/drivers/staging/autofs/symlink.c b/drivers/staging/autofs/symlink.c deleted file mode 100644 index ff2c65cde753..000000000000 --- a/drivers/staging/autofs/symlink.c +++ /dev/null @@ -1,26 +0,0 @@ -/* -*- linux-c -*- --------------------------------------------------------- * - * - * drivers/staging/autofs/symlink.c - * - * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved - * - * This file is part of the Linux kernel and is made available under - * the terms of the GNU General Public License, version 2, or at your - * option, any later version, incorporated herein by reference. - * - * ------------------------------------------------------------------------- */ - -#include "autofs_i.h" - -/* Nothing to release.. */ -static void *autofs_follow_link(struct dentry *dentry, struct nameidata *nd) -{ - char *s=((struct autofs_symlink *)dentry->d_inode->i_private)->data; - nd_set_link(nd, s); - return NULL; -} - -const struct inode_operations autofs_symlink_inode_operations = { - .readlink = generic_readlink, - .follow_link = autofs_follow_link -}; diff --git a/drivers/staging/autofs/waitq.c b/drivers/staging/autofs/waitq.c deleted file mode 100644 index d3c8cc9eb4d1..000000000000 --- a/drivers/staging/autofs/waitq.c +++ /dev/null @@ -1,205 +0,0 @@ -/* -*- linux-c -*- --------------------------------------------------------- * - * - * drivers/staging/autofs/waitq.c - * - * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved - * - * This file is part of the Linux kernel and is made available under - * the terms of the GNU General Public License, version 2, or at your - * option, any later version, incorporated herein by reference. - * - * ------------------------------------------------------------------------- */ - -#include -#include -#include -#include -#include "autofs_i.h" - -/* We make this a static variable rather than a part of the superblock; it - is better if we don't reassign numbers easily even across filesystems */ -static autofs_wqt_t autofs_next_wait_queue = 1; - -/* These are the signals we allow interrupting a pending mount */ -#define SHUTDOWN_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) | sigmask(SIGQUIT)) - -void autofs_catatonic_mode(struct autofs_sb_info *sbi) -{ - struct autofs_wait_queue *wq, *nwq; - - DPRINTK(("autofs: entering catatonic mode\n")); - - sbi->catatonic = 1; - wq = sbi->queues; - sbi->queues = NULL; /* Erase all wait queues */ - while ( wq ) { - nwq = wq->next; - wq->status = -ENOENT; /* Magic is gone - report failure */ - kfree(wq->name); - wq->name = NULL; - wake_up(&wq->queue); - wq = nwq; - } - fput(sbi->pipe); /* Close the pipe */ - sbi->pipe = NULL; - autofs_hash_dputall(&sbi->dirhash); /* Remove all dentry pointers */ -} - -static int autofs_write(struct file *file, const void *addr, int bytes) -{ - unsigned long sigpipe, flags; - mm_segment_t fs; - const char *data = (const char *)addr; - ssize_t wr = 0; - - /** WARNING: this is not safe for writing more than PIPE_BUF bytes! **/ - - sigpipe = sigismember(¤t->pending.signal, SIGPIPE); - - /* Save pointer to user space and point back to kernel space */ - fs = get_fs(); - set_fs(KERNEL_DS); - - while (bytes && - (wr = file->f_op->write(file,data,bytes,&file->f_pos)) > 0) { - data += wr; - bytes -= wr; - } - - set_fs(fs); - - /* Keep the currently executing process from receiving a - SIGPIPE unless it was already supposed to get one */ - if (wr == -EPIPE && !sigpipe) { - spin_lock_irqsave(¤t->sighand->siglock, flags); - sigdelset(¤t->pending.signal, SIGPIPE); - recalc_sigpending(); - spin_unlock_irqrestore(¤t->sighand->siglock, flags); - } - - return (bytes > 0); -} - -static void autofs_notify_daemon(struct autofs_sb_info *sbi, struct autofs_wait_queue *wq) -{ - struct autofs_packet_missing pkt; - - DPRINTK(("autofs_wait: wait id = 0x%08lx, name = ", wq->wait_queue_token)); - autofs_say(wq->name,wq->len); - - memset(&pkt,0,sizeof pkt); /* For security reasons */ - - pkt.hdr.proto_version = AUTOFS_PROTO_VERSION; - pkt.hdr.type = autofs_ptype_missing; - pkt.wait_queue_token = wq->wait_queue_token; - pkt.len = wq->len; - memcpy(pkt.name, wq->name, pkt.len); - pkt.name[pkt.len] = '\0'; - - if ( autofs_write(sbi->pipe,&pkt,sizeof(struct autofs_packet_missing)) ) - autofs_catatonic_mode(sbi); -} - -int autofs_wait(struct autofs_sb_info *sbi, struct qstr *name) -{ - struct autofs_wait_queue *wq; - int status; - - /* In catatonic mode, we don't wait for nobody */ - if ( sbi->catatonic ) - return -ENOENT; - - /* We shouldn't be able to get here, but just in case */ - if ( name->len > NAME_MAX ) - return -ENOENT; - - for ( wq = sbi->queues ; wq ; wq = wq->next ) { - if ( wq->hash == name->hash && - wq->len == name->len && - wq->name && !memcmp(wq->name,name->name,name->len) ) - break; - } - - if ( !wq ) { - /* Create a new wait queue */ - wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL); - if ( !wq ) - return -ENOMEM; - - wq->name = kmalloc(name->len,GFP_KERNEL); - if ( !wq->name ) { - kfree(wq); - return -ENOMEM; - } - wq->wait_queue_token = autofs_next_wait_queue++; - init_waitqueue_head(&wq->queue); - wq->hash = name->hash; - wq->len = name->len; - wq->status = -EINTR; /* Status return if interrupted */ - memcpy(wq->name, name->name, name->len); - wq->next = sbi->queues; - sbi->queues = wq; - - /* autofs_notify_daemon() may block */ - wq->wait_ctr = 2; - autofs_notify_daemon(sbi,wq); - } else - wq->wait_ctr++; - - /* wq->name is NULL if and only if the lock is already released */ - - if ( sbi->catatonic ) { - /* We might have slept, so check again for catatonic mode */ - wq->status = -ENOENT; - kfree(wq->name); - wq->name = NULL; - } - - if ( wq->name ) { - /* Block all but "shutdown" signals while waiting */ - sigset_t sigmask; - - siginitsetinv(&sigmask, SHUTDOWN_SIGS); - sigprocmask(SIG_BLOCK, &sigmask, &sigmask); - - interruptible_sleep_on(&wq->queue); - - sigprocmask(SIG_SETMASK, &sigmask, NULL); - } else { - DPRINTK(("autofs_wait: skipped sleeping\n")); - } - - status = wq->status; - - if ( ! --wq->wait_ctr ) /* Are we the last process to need status? */ - kfree(wq); - - return status; -} - - -int autofs_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_token, int status) -{ - struct autofs_wait_queue *wq, **wql; - - for (wql = &sbi->queues; (wq = *wql) != NULL; wql = &wq->next) { - if ( wq->wait_queue_token == wait_queue_token ) - break; - } - if ( !wq ) - return -EINVAL; - - *wql = wq->next; /* Unlink from chain */ - kfree(wq->name); - wq->name = NULL; /* Do not wait on this queue */ - - wq->status = status; - - if ( ! --wq->wait_ctr ) /* Is anyone still waiting for this guy? */ - kfree(wq); - else - wake_up(&wq->queue); - - return 0; -} - -- cgit v1.2.3 From 939cbe5af5fb04de1a53942a8c4a6e0160f4f38b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 25 Jan 2011 23:17:21 +0100 Subject: staging: remove smbfs smbfs got moved to staging in 2.6.37, so we can finally remove it in the 2.6.39 merge window. All users should by now have migrated to cifs. Signed-off-by: Arnd Bergmann Cc: linux-cifs@vger.kernel.org Cc: Jeff Layton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/smbfs/Kconfig | 56 - drivers/staging/smbfs/Makefile | 18 - drivers/staging/smbfs/TODO | 8 - drivers/staging/smbfs/cache.c | 208 --- drivers/staging/smbfs/dir.c | 699 -------- drivers/staging/smbfs/file.c | 456 ----- drivers/staging/smbfs/getopt.c | 64 - drivers/staging/smbfs/getopt.h | 14 - drivers/staging/smbfs/inode.c | 854 --------- drivers/staging/smbfs/ioctl.c | 68 - drivers/staging/smbfs/proc.c | 3502 ------------------------------------- drivers/staging/smbfs/proto.h | 89 - drivers/staging/smbfs/request.c | 817 --------- drivers/staging/smbfs/request.h | 70 - drivers/staging/smbfs/smb.h | 118 -- drivers/staging/smbfs/smb_debug.h | 34 - drivers/staging/smbfs/smb_fs.h | 153 -- drivers/staging/smbfs/smb_fs_i.h | 37 - drivers/staging/smbfs/smb_fs_sb.h | 100 -- drivers/staging/smbfs/smb_mount.h | 65 - drivers/staging/smbfs/smbfs.txt | 8 - drivers/staging/smbfs/smbiod.c | 343 ---- drivers/staging/smbfs/smbno.h | 363 ---- drivers/staging/smbfs/sock.c | 385 ---- drivers/staging/smbfs/symlink.c | 67 - 27 files changed, 8599 deletions(-) delete mode 100644 drivers/staging/smbfs/Kconfig delete mode 100644 drivers/staging/smbfs/Makefile delete mode 100644 drivers/staging/smbfs/TODO delete mode 100644 drivers/staging/smbfs/cache.c delete mode 100644 drivers/staging/smbfs/dir.c delete mode 100644 drivers/staging/smbfs/file.c delete mode 100644 drivers/staging/smbfs/getopt.c delete mode 100644 drivers/staging/smbfs/getopt.h delete mode 100644 drivers/staging/smbfs/inode.c delete mode 100644 drivers/staging/smbfs/ioctl.c delete mode 100644 drivers/staging/smbfs/proc.c delete mode 100644 drivers/staging/smbfs/proto.h delete mode 100644 drivers/staging/smbfs/request.c delete mode 100644 drivers/staging/smbfs/request.h delete mode 100644 drivers/staging/smbfs/smb.h delete mode 100644 drivers/staging/smbfs/smb_debug.h delete mode 100644 drivers/staging/smbfs/smb_fs.h delete mode 100644 drivers/staging/smbfs/smb_fs_i.h delete mode 100644 drivers/staging/smbfs/smb_fs_sb.h delete mode 100644 drivers/staging/smbfs/smb_mount.h delete mode 100644 drivers/staging/smbfs/smbfs.txt delete mode 100644 drivers/staging/smbfs/smbiod.c delete mode 100644 drivers/staging/smbfs/smbno.h delete mode 100644 drivers/staging/smbfs/sock.c delete mode 100644 drivers/staging/smbfs/symlink.c (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 8bcc153310c9..b80755da5394 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -149,8 +149,6 @@ source "drivers/staging/msm/Kconfig" source "drivers/staging/lirc/Kconfig" -source "drivers/staging/smbfs/Kconfig" - source "drivers/staging/easycap/Kconfig" source "drivers/staging/solo6x10/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 0919a423398c..fd26509e5efa 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -34,7 +34,6 @@ obj-$(CONFIG_POHMELFS) += pohmelfs/ obj-$(CONFIG_IDE_PHISON) += phison/ obj-$(CONFIG_LINE6_USB) += line6/ obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/ -obj-$(CONFIG_SMB_FS) += smbfs/ obj-$(CONFIG_USB_SERIAL_QUATECH_USB2) += quatech_usb2/ obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ obj-$(CONFIG_VT6655) += vt6655/ diff --git a/drivers/staging/smbfs/Kconfig b/drivers/staging/smbfs/Kconfig deleted file mode 100644 index 2bc24a8c4039..000000000000 --- a/drivers/staging/smbfs/Kconfig +++ /dev/null @@ -1,56 +0,0 @@ -config SMB_FS - tristate "SMB file system support (OBSOLETE, please use CIFS)" - depends on BKL # probably unfixable - depends on INET - select NLS - help - SMB (Server Message Block) is the protocol Windows for Workgroups - (WfW), Windows 95/98, Windows NT and OS/2 Lan Manager use to share - files and printers over local networks. Saying Y here allows you to - mount their file systems (often called "shares" in this context) and - access them just like any other Unix directory. Currently, this - works only if the Windows machines use TCP/IP as the underlying - transport protocol, and not NetBEUI. For details, read - and the SMB-HOWTO, - available from . - - Note: if you just want your box to act as an SMB *server* and make - files and printing services available to Windows clients (which need - to have a TCP/IP stack), you don't need to say Y here; you can use - the program SAMBA (available from ) - for that. - - General information about how to connect Linux, Windows machines and - Macs is on the WWW at . - - To compile the SMB support as a module, choose M here: - the module will be called smbfs. Most people say N, however. - -config SMB_NLS_DEFAULT - bool "Use a default NLS" - depends on SMB_FS - help - Enabling this will make smbfs use nls translations by default. You - need to specify the local charset (CONFIG_NLS_DEFAULT) in the nls - settings and you need to give the default nls for the SMB server as - CONFIG_SMB_NLS_REMOTE. - - The nls settings can be changed at mount time, if your smbmount - supports that, using the codepage and iocharset parameters. - - smbmount from samba 2.2.0 or later supports this. - -config SMB_NLS_REMOTE - string "Default Remote NLS Option" - depends on SMB_NLS_DEFAULT - default "cp437" - help - This setting allows you to specify a default value for which - codepage the server uses. If this field is left blank no - translations will be done by default. The local codepage/charset - default to CONFIG_NLS_DEFAULT. - - The nls settings can be changed at mount time, if your smbmount - supports that, using the codepage and iocharset parameters. - - smbmount from samba 2.2.0 or later supports this. diff --git a/drivers/staging/smbfs/Makefile b/drivers/staging/smbfs/Makefile deleted file mode 100644 index d2a92c5cb119..000000000000 --- a/drivers/staging/smbfs/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# -# Makefile for the linux smb-filesystem routines. -# - -obj-$(CONFIG_SMB_FS) += smbfs.o - -smbfs-y := proc.o dir.o cache.o sock.o inode.o file.o ioctl.o getopt.o \ - symlink.o smbiod.o request.o - -# If you want debugging output, you may add these flags to the EXTRA_CFLAGS -# SMBFS_PARANOIA should normally be enabled. - -ccflags-y := -DSMBFS_PARANOIA -#ccflags-y += -DSMBFS_DEBUG -#ccflags-y += -DSMBFS_DEBUG_VERBOSE -#ccflags-y += -DDEBUG_SMB_TIMESTAMP -#ccflags-y += -Werror - diff --git a/drivers/staging/smbfs/TODO b/drivers/staging/smbfs/TODO deleted file mode 100644 index 24f4d29d53ac..000000000000 --- a/drivers/staging/smbfs/TODO +++ /dev/null @@ -1,8 +0,0 @@ -smbfs is on its way out of the kernel, it has been replaced -by cifs several years ago. - -The smbfs code uses the big kernel lock which -is getting deprecated. - -Users that find smbfs to work but not cifs should contact -the CIFS developers on linux-cifs@vger.kernel.org. diff --git a/drivers/staging/smbfs/cache.c b/drivers/staging/smbfs/cache.c deleted file mode 100644 index f2a1323ca827..000000000000 --- a/drivers/staging/smbfs/cache.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * cache.c - * - * Copyright (C) 1997 by Bill Hawes - * - * Routines to support directory cacheing using the page cache. - * This cache code is almost directly taken from ncpfs. - * - * Please add a note about your changes to smbfs in the ChangeLog file. - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include "smb_fs.h" -#include "smb_debug.h" -#include "proto.h" - -/* - * Force the next attempt to use the cache to be a timeout. - * If we can't find the page that's fine, it will cause a refresh. - */ -void -smb_invalid_dir_cache(struct inode * dir) -{ - struct smb_sb_info *server = server_from_inode(dir); - union smb_dir_cache *cache = NULL; - struct page *page = NULL; - - page = grab_cache_page(&dir->i_data, 0); - if (!page) - goto out; - - if (!PageUptodate(page)) - goto out_unlock; - - cache = kmap(page); - cache->head.time = jiffies - SMB_MAX_AGE(server); - - kunmap(page); - SetPageUptodate(page); -out_unlock: - unlock_page(page); - page_cache_release(page); -out: - return; -} - -/* - * Mark all dentries for 'parent' as invalid, forcing them to be re-read - */ -void -smb_invalidate_dircache_entries(struct dentry *parent) -{ - struct smb_sb_info *server = server_from_dentry(parent); - struct list_head *next; - struct dentry *dentry; - - spin_lock(&parent->d_lock); - next = parent->d_subdirs.next; - while (next != &parent->d_subdirs) { - dentry = list_entry(next, struct dentry, d_u.d_child); - dentry->d_fsdata = NULL; - smb_age_dentry(server, dentry); - next = next->next; - } - spin_unlock(&parent->d_lock); -} - -/* - * dget, but require that fpos and parent matches what the dentry contains. - * dentry is not known to be a valid pointer at entry. - */ -struct dentry * -smb_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos) -{ - struct dentry *dent = dentry; - struct list_head *next; - - if (d_validate(dent, parent)) { - if (dent->d_name.len <= SMB_MAXNAMELEN && - (unsigned long)dent->d_fsdata == fpos) { - if (!dent->d_inode) { - dput(dent); - dent = NULL; - } - return dent; - } - dput(dent); - } - - /* If a pointer is invalid, we search the dentry. */ - spin_lock(&parent->d_lock); - next = parent->d_subdirs.next; - while (next != &parent->d_subdirs) { - dent = list_entry(next, struct dentry, d_u.d_child); - if ((unsigned long)dent->d_fsdata == fpos) { - if (dent->d_inode) - dget(dent); - else - dent = NULL; - goto out_unlock; - } - next = next->next; - } - dent = NULL; -out_unlock: - spin_unlock(&parent->d_lock); - return dent; -} - - -/* - * Create dentry/inode for this file and add it to the dircache. - */ -int -smb_fill_cache(struct file *filp, void *dirent, filldir_t filldir, - struct smb_cache_control *ctrl, struct qstr *qname, - struct smb_fattr *entry) -{ - struct dentry *newdent, *dentry = filp->f_path.dentry; - struct inode *newino, *inode = dentry->d_inode; - struct smb_cache_control ctl = *ctrl; - int valid = 0; - int hashed = 0; - ino_t ino = 0; - - qname->hash = full_name_hash(qname->name, qname->len); - - if (dentry->d_op && dentry->d_op->d_hash) - if (dentry->d_op->d_hash(dentry, inode, qname) != 0) - goto end_advance; - - newdent = d_lookup(dentry, qname); - - if (!newdent) { - newdent = d_alloc(dentry, qname); - if (!newdent) - goto end_advance; - } else { - hashed = 1; - /* dir i_mutex is locked because we're in readdir */ - dentry_update_name_case(newdent, qname); - } - - if (!newdent->d_inode) { - smb_renew_times(newdent); - entry->f_ino = iunique(inode->i_sb, 2); - newino = smb_iget(inode->i_sb, entry); - if (newino) { - smb_new_dentry(newdent); - d_instantiate(newdent, newino); - if (!hashed) - d_rehash(newdent); - } - } else - smb_set_inode_attr(newdent->d_inode, entry); - - if (newdent->d_inode) { - ino = newdent->d_inode->i_ino; - newdent->d_fsdata = (void *) ctl.fpos; - smb_new_dentry(newdent); - } - - if (ctl.idx >= SMB_DIRCACHE_SIZE) { - if (ctl.page) { - kunmap(ctl.page); - SetPageUptodate(ctl.page); - unlock_page(ctl.page); - page_cache_release(ctl.page); - } - ctl.cache = NULL; - ctl.idx -= SMB_DIRCACHE_SIZE; - ctl.ofs += 1; - ctl.page = grab_cache_page(&inode->i_data, ctl.ofs); - if (ctl.page) - ctl.cache = kmap(ctl.page); - } - if (ctl.cache) { - ctl.cache->dentry[ctl.idx] = newdent; - valid = 1; - } - dput(newdent); - -end_advance: - if (!valid) - ctl.valid = 0; - if (!ctl.filled && (ctl.fpos == filp->f_pos)) { - if (!ino) - ino = find_inode_number(dentry, qname); - if (!ino) - ino = iunique(inode->i_sb, 2); - ctl.filled = filldir(dirent, qname->name, qname->len, - filp->f_pos, ino, DT_UNKNOWN); - if (!ctl.filled) - filp->f_pos += 1; - } - ctl.fpos += 1; - ctl.idx += 1; - *ctrl = ctl; - return (ctl.valid || !ctl.filled); -} diff --git a/drivers/staging/smbfs/dir.c b/drivers/staging/smbfs/dir.c deleted file mode 100644 index f204d33910ec..000000000000 --- a/drivers/staging/smbfs/dir.c +++ /dev/null @@ -1,699 +0,0 @@ -/* - * dir.c - * - * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke - * Copyright (C) 1997 by Volker Lendecke - * - * Please add a note about your changes to smbfs in the ChangeLog file. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "smb_fs.h" -#include "smb_mount.h" -#include "smbno.h" - -#include "smb_debug.h" -#include "proto.h" - -static int smb_readdir(struct file *, void *, filldir_t); -static int smb_dir_open(struct inode *, struct file *); - -static struct dentry *smb_lookup(struct inode *, struct dentry *, struct nameidata *); -static int smb_create(struct inode *, struct dentry *, int, struct nameidata *); -static int smb_mkdir(struct inode *, struct dentry *, int); -static int smb_rmdir(struct inode *, struct dentry *); -static int smb_unlink(struct inode *, struct dentry *); -static int smb_rename(struct inode *, struct dentry *, - struct inode *, struct dentry *); -static int smb_make_node(struct inode *,struct dentry *,int,dev_t); -static int smb_link(struct dentry *, struct inode *, struct dentry *); - -const struct file_operations smb_dir_operations = -{ - .llseek = generic_file_llseek, - .read = generic_read_dir, - .readdir = smb_readdir, - .unlocked_ioctl = smb_ioctl, - .open = smb_dir_open, -}; - -const struct inode_operations smb_dir_inode_operations = -{ - .create = smb_create, - .lookup = smb_lookup, - .unlink = smb_unlink, - .mkdir = smb_mkdir, - .rmdir = smb_rmdir, - .rename = smb_rename, - .getattr = smb_getattr, - .setattr = smb_notify_change, -}; - -const struct inode_operations smb_dir_inode_operations_unix = -{ - .create = smb_create, - .lookup = smb_lookup, - .unlink = smb_unlink, - .mkdir = smb_mkdir, - .rmdir = smb_rmdir, - .rename = smb_rename, - .getattr = smb_getattr, - .setattr = smb_notify_change, - .symlink = smb_symlink, - .mknod = smb_make_node, - .link = smb_link, -}; - -/* - * Read a directory, using filldir to fill the dirent memory. - * smb_proc_readdir does the actual reading from the smb server. - * - * The cache code is almost directly taken from ncpfs - */ -static int -smb_readdir(struct file *filp, void *dirent, filldir_t filldir) -{ - struct dentry *dentry = filp->f_path.dentry; - struct inode *dir = dentry->d_inode; - struct smb_sb_info *server = server_from_dentry(dentry); - union smb_dir_cache *cache = NULL; - struct smb_cache_control ctl; - struct page *page = NULL; - int result; - - ctl.page = NULL; - ctl.cache = NULL; - - VERBOSE("reading %s/%s, f_pos=%d\n", - DENTRY_PATH(dentry), (int) filp->f_pos); - - result = 0; - - lock_kernel(); - - switch ((unsigned int) filp->f_pos) { - case 0: - if (filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR) < 0) - goto out; - filp->f_pos = 1; - /* fallthrough */ - case 1: - if (filldir(dirent, "..", 2, 1, parent_ino(dentry), DT_DIR) < 0) - goto out; - filp->f_pos = 2; - } - - /* - * Make sure our inode is up-to-date. - */ - result = smb_revalidate_inode(dentry); - if (result) - goto out; - - - page = grab_cache_page(&dir->i_data, 0); - if (!page) - goto read_really; - - ctl.cache = cache = kmap(page); - ctl.head = cache->head; - - if (!PageUptodate(page) || !ctl.head.eof) { - VERBOSE("%s/%s, page uptodate=%d, eof=%d\n", - DENTRY_PATH(dentry), PageUptodate(page),ctl.head.eof); - goto init_cache; - } - - if (filp->f_pos == 2) { - if (jiffies - ctl.head.time >= SMB_MAX_AGE(server)) - goto init_cache; - - /* - * N.B. ncpfs checks mtime of dentry too here, we don't. - * 1. common smb servers do not update mtime on dir changes - * 2. it requires an extra smb request - * (revalidate has the same timeout as ctl.head.time) - * - * Instead smbfs invalidates its own cache on local changes - * and remote changes are not seen until timeout. - */ - } - - if (filp->f_pos > ctl.head.end) - goto finished; - - ctl.fpos = filp->f_pos + (SMB_DIRCACHE_START - 2); - ctl.ofs = ctl.fpos / SMB_DIRCACHE_SIZE; - ctl.idx = ctl.fpos % SMB_DIRCACHE_SIZE; - - for (;;) { - if (ctl.ofs != 0) { - ctl.page = find_lock_page(&dir->i_data, ctl.ofs); - if (!ctl.page) - goto invalid_cache; - ctl.cache = kmap(ctl.page); - if (!PageUptodate(ctl.page)) - goto invalid_cache; - } - while (ctl.idx < SMB_DIRCACHE_SIZE) { - struct dentry *dent; - int res; - - dent = smb_dget_fpos(ctl.cache->dentry[ctl.idx], - dentry, filp->f_pos); - if (!dent) - goto invalid_cache; - - res = filldir(dirent, dent->d_name.name, - dent->d_name.len, filp->f_pos, - dent->d_inode->i_ino, DT_UNKNOWN); - dput(dent); - if (res) - goto finished; - filp->f_pos += 1; - ctl.idx += 1; - if (filp->f_pos > ctl.head.end) - goto finished; - } - if (ctl.page) { - kunmap(ctl.page); - SetPageUptodate(ctl.page); - unlock_page(ctl.page); - page_cache_release(ctl.page); - ctl.page = NULL; - } - ctl.idx = 0; - ctl.ofs += 1; - } -invalid_cache: - if (ctl.page) { - kunmap(ctl.page); - unlock_page(ctl.page); - page_cache_release(ctl.page); - ctl.page = NULL; - } - ctl.cache = cache; -init_cache: - smb_invalidate_dircache_entries(dentry); - ctl.head.time = jiffies; - ctl.head.eof = 0; - ctl.fpos = 2; - ctl.ofs = 0; - ctl.idx = SMB_DIRCACHE_START; - ctl.filled = 0; - ctl.valid = 1; -read_really: - result = server->ops->readdir(filp, dirent, filldir, &ctl); - if (result == -ERESTARTSYS && page) - ClearPageUptodate(page); - if (ctl.idx == -1) - goto invalid_cache; /* retry */ - ctl.head.end = ctl.fpos - 1; - ctl.head.eof = ctl.valid; -finished: - if (page) { - cache->head = ctl.head; - kunmap(page); - if (result != -ERESTARTSYS) - SetPageUptodate(page); - unlock_page(page); - page_cache_release(page); - } - if (ctl.page) { - kunmap(ctl.page); - SetPageUptodate(ctl.page); - unlock_page(ctl.page); - page_cache_release(ctl.page); - } -out: - unlock_kernel(); - return result; -} - -static int -smb_dir_open(struct inode *dir, struct file *file) -{ - struct dentry *dentry = file->f_path.dentry; - struct smb_sb_info *server; - int error = 0; - - VERBOSE("(%s/%s)\n", dentry->d_parent->d_name.name, - file->f_path.dentry->d_name.name); - - /* - * Directory timestamps in the core protocol aren't updated - * when a file is added, so we give them a very short TTL. - */ - lock_kernel(); - server = server_from_dentry(dentry); - if (server->opt.protocol < SMB_PROTOCOL_LANMAN2) { - unsigned long age = jiffies - SMB_I(dir)->oldmtime; - if (age > 2*HZ) - smb_invalid_dir_cache(dir); - } - - /* - * Note: in order to allow the smbmount process to open the - * mount point, we only revalidate if the connection is valid or - * if the process is trying to access something other than the root. - */ - if (server->state == CONN_VALID || !IS_ROOT(dentry)) - error = smb_revalidate_inode(dentry); - unlock_kernel(); - return error; -} - -/* - * Dentry operations routines - */ -static int smb_lookup_validate(struct dentry *, struct nameidata *); -static int smb_hash_dentry(const struct dentry *, const struct inode *, - struct qstr *); -static int smb_compare_dentry(const struct dentry *, - const struct inode *, - const struct dentry *, const struct inode *, - unsigned int, const char *, const struct qstr *); -static int smb_delete_dentry(const struct dentry *); - -const struct dentry_operations smbfs_dentry_operations = -{ - .d_revalidate = smb_lookup_validate, - .d_hash = smb_hash_dentry, - .d_compare = smb_compare_dentry, - .d_delete = smb_delete_dentry, -}; - -const struct dentry_operations smbfs_dentry_operations_case = -{ - .d_revalidate = smb_lookup_validate, - .d_delete = smb_delete_dentry, -}; - - -/* - * This is the callback when the dcache has a lookup hit. - */ -static int -smb_lookup_validate(struct dentry *dentry, struct nameidata *nd) -{ - struct smb_sb_info *server; - struct inode *inode; - unsigned long age; - int valid; - - if (nd->flags & LOOKUP_RCU) - return -ECHILD; - - server = server_from_dentry(dentry); - inode = dentry->d_inode; - age = jiffies - dentry->d_time; - - /* - * The default validation is based on dentry age: - * we believe in dentries for a few seconds. (But each - * successful server lookup renews the timestamp.) - */ - valid = (age <= SMB_MAX_AGE(server)); -#ifdef SMBFS_DEBUG_VERBOSE - if (!valid) - VERBOSE("%s/%s not valid, age=%lu\n", - DENTRY_PATH(dentry), age); -#endif - - if (inode) { - lock_kernel(); - if (is_bad_inode(inode)) { - PARANOIA("%s/%s has dud inode\n", DENTRY_PATH(dentry)); - valid = 0; - } else if (!valid) - valid = (smb_revalidate_inode(dentry) == 0); - unlock_kernel(); - } else { - /* - * What should we do for negative dentries? - */ - } - return valid; -} - -static int -smb_hash_dentry(const struct dentry *dir, const struct inode *inode, - struct qstr *this) -{ - unsigned long hash; - int i; - - hash = init_name_hash(); - for (i=0; i < this->len ; i++) - hash = partial_name_hash(tolower(this->name[i]), hash); - this->hash = end_name_hash(hash); - - return 0; -} - -static int -smb_compare_dentry(const struct dentry *parent, - const struct inode *pinode, - const struct dentry *dentry, const struct inode *inode, - unsigned int len, const char *str, const struct qstr *name) -{ - int i, result = 1; - - if (len != name->len) - goto out; - for (i=0; i < len; i++) { - if (tolower(str[i]) != tolower(name->name[i])) - goto out; - } - result = 0; -out: - return result; -} - -/* - * This is the callback from dput() when d_count is going to 0. - * We use this to unhash dentries with bad inodes. - */ -static int -smb_delete_dentry(const struct dentry *dentry) -{ - if (dentry->d_inode) { - if (is_bad_inode(dentry->d_inode)) { - PARANOIA("bad inode, unhashing %s/%s\n", - DENTRY_PATH(dentry)); - return 1; - } - } else { - /* N.B. Unhash negative dentries? */ - } - return 0; -} - -/* - * Initialize a new dentry - */ -void -smb_new_dentry(struct dentry *dentry) -{ - dentry->d_time = jiffies; -} - - -/* - * Whenever a lookup succeeds, we know the parent directories - * are all valid, so we want to update the dentry timestamps. - * N.B. Move this to dcache? - */ -void -smb_renew_times(struct dentry * dentry) -{ - dget(dentry); - dentry->d_time = jiffies; - - while (!IS_ROOT(dentry)) { - struct dentry *parent = dget_parent(dentry); - dput(dentry); - dentry = parent; - - dentry->d_time = jiffies; - } - dput(dentry); -} - -static struct dentry * -smb_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -{ - struct smb_fattr finfo; - struct inode *inode; - int error; - - error = -ENAMETOOLONG; - if (dentry->d_name.len > SMB_MAXNAMELEN) - goto out; - - /* Do not allow lookup of names with backslashes in */ - error = -EINVAL; - if (memchr(dentry->d_name.name, '\\', dentry->d_name.len)) - goto out; - - lock_kernel(); - error = smb_proc_getattr(dentry, &finfo); -#ifdef SMBFS_PARANOIA - if (error && error != -ENOENT) - PARANOIA("find %s/%s failed, error=%d\n", - DENTRY_PATH(dentry), error); -#endif - - inode = NULL; - if (error == -ENOENT) - goto add_entry; - if (!error) { - error = -EACCES; - finfo.f_ino = iunique(dentry->d_sb, 2); - inode = smb_iget(dir->i_sb, &finfo); - if (inode) { - add_entry: - d_add(dentry, inode); - smb_renew_times(dentry); - error = 0; - } - } - unlock_kernel(); -out: - return ERR_PTR(error); -} - -/* - * This code is common to all routines creating a new inode. - */ -static int -smb_instantiate(struct dentry *dentry, __u16 fileid, int have_id) -{ - struct smb_sb_info *server = server_from_dentry(dentry); - struct inode *inode; - int error; - struct smb_fattr fattr; - - VERBOSE("file %s/%s, fileid=%u\n", DENTRY_PATH(dentry), fileid); - - error = smb_proc_getattr(dentry, &fattr); - if (error) - goto out_close; - - smb_renew_times(dentry); - fattr.f_ino = iunique(dentry->d_sb, 2); - inode = smb_iget(dentry->d_sb, &fattr); - if (!inode) - goto out_no_inode; - - if (have_id) { - struct smb_inode_info *ei = SMB_I(inode); - ei->fileid = fileid; - ei->access = SMB_O_RDWR; - ei->open = server->generation; - } - d_instantiate(dentry, inode); -out: - return error; - -out_no_inode: - error = -EACCES; -out_close: - if (have_id) { - PARANOIA("%s/%s failed, error=%d, closing %u\n", - DENTRY_PATH(dentry), error, fileid); - smb_close_fileid(dentry, fileid); - } - goto out; -} - -/* N.B. How should the mode argument be used? */ -static int -smb_create(struct inode *dir, struct dentry *dentry, int mode, - struct nameidata *nd) -{ - struct smb_sb_info *server = server_from_dentry(dentry); - __u16 fileid; - int error; - struct iattr attr; - - VERBOSE("creating %s/%s, mode=%d\n", DENTRY_PATH(dentry), mode); - - lock_kernel(); - smb_invalid_dir_cache(dir); - error = smb_proc_create(dentry, 0, get_seconds(), &fileid); - if (!error) { - if (server->opt.capabilities & SMB_CAP_UNIX) { - /* Set attributes for new file */ - attr.ia_valid = ATTR_MODE; - attr.ia_mode = mode; - error = smb_proc_setattr_unix(dentry, &attr, 0, 0); - } - error = smb_instantiate(dentry, fileid, 1); - } else { - PARANOIA("%s/%s failed, error=%d\n", - DENTRY_PATH(dentry), error); - } - unlock_kernel(); - return error; -} - -/* N.B. How should the mode argument be used? */ -static int -smb_mkdir(struct inode *dir, struct dentry *dentry, int mode) -{ - struct smb_sb_info *server = server_from_dentry(dentry); - int error; - struct iattr attr; - - lock_kernel(); - smb_invalid_dir_cache(dir); - error = smb_proc_mkdir(dentry); - if (!error) { - if (server->opt.capabilities & SMB_CAP_UNIX) { - /* Set attributes for new directory */ - attr.ia_valid = ATTR_MODE; - attr.ia_mode = mode; - error = smb_proc_setattr_unix(dentry, &attr, 0, 0); - } - error = smb_instantiate(dentry, 0, 0); - } - unlock_kernel(); - return error; -} - -static int -smb_rmdir(struct inode *dir, struct dentry *dentry) -{ - struct inode *inode = dentry->d_inode; - int error; - - /* - * Close the directory if it's open. - */ - lock_kernel(); - smb_close(inode); - - /* - * Check that nobody else is using the directory.. - */ - error = -EBUSY; - if (!d_unhashed(dentry)) - goto out; - - smb_invalid_dir_cache(dir); - error = smb_proc_rmdir(dentry); - -out: - unlock_kernel(); - return error; -} - -static int -smb_unlink(struct inode *dir, struct dentry *dentry) -{ - int error; - - /* - * Close the file if it's open. - */ - lock_kernel(); - smb_close(dentry->d_inode); - - smb_invalid_dir_cache(dir); - error = smb_proc_unlink(dentry); - if (!error) - smb_renew_times(dentry); - unlock_kernel(); - return error; -} - -static int -smb_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) -{ - int error; - - /* - * Close any open files, and check whether to delete the - * target before attempting the rename. - */ - lock_kernel(); - if (old_dentry->d_inode) - smb_close(old_dentry->d_inode); - if (new_dentry->d_inode) { - smb_close(new_dentry->d_inode); - error = smb_proc_unlink(new_dentry); - if (error) { - VERBOSE("unlink %s/%s, error=%d\n", - DENTRY_PATH(new_dentry), error); - goto out; - } - /* FIXME */ - d_delete(new_dentry); - } - - smb_invalid_dir_cache(old_dir); - smb_invalid_dir_cache(new_dir); - error = smb_proc_mv(old_dentry, new_dentry); - if (!error) { - smb_renew_times(old_dentry); - smb_renew_times(new_dentry); - } -out: - unlock_kernel(); - return error; -} - -/* - * FIXME: samba servers won't let you create device nodes unless uid/gid - * matches the connection credentials (and we don't know which those are ...) - */ -static int -smb_make_node(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) -{ - int error; - struct iattr attr; - - attr.ia_valid = ATTR_MODE | ATTR_UID | ATTR_GID; - attr.ia_mode = mode; - current_euid_egid(&attr.ia_uid, &attr.ia_gid); - - if (!new_valid_dev(dev)) - return -EINVAL; - - smb_invalid_dir_cache(dir); - error = smb_proc_setattr_unix(dentry, &attr, MAJOR(dev), MINOR(dev)); - if (!error) { - error = smb_instantiate(dentry, 0, 0); - } - return error; -} - -/* - * dentry = existing file - * new_dentry = new file - */ -static int -smb_link(struct dentry *dentry, struct inode *dir, struct dentry *new_dentry) -{ - int error; - - DEBUG1("smb_link old=%s/%s new=%s/%s\n", - DENTRY_PATH(dentry), DENTRY_PATH(new_dentry)); - smb_invalid_dir_cache(dir); - error = smb_proc_link(server_from_dentry(dentry), dentry, new_dentry); - if (!error) { - smb_renew_times(dentry); - error = smb_instantiate(new_dentry, 0, 0); - } - return error; -} diff --git a/drivers/staging/smbfs/file.c b/drivers/staging/smbfs/file.c deleted file mode 100644 index 31372e7b12de..000000000000 --- a/drivers/staging/smbfs/file.c +++ /dev/null @@ -1,456 +0,0 @@ -/* - * file.c - * - * Copyright (C) 1995, 1996, 1997 by Paal-Kr. Engstad and Volker Lendecke - * Copyright (C) 1997 by Volker Lendecke - * - * Please add a note about your changes to smbfs in the ChangeLog file. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "smbno.h" -#include "smb_fs.h" -#include "smb_debug.h" -#include "proto.h" - -static int -smb_fsync(struct file *file, int datasync) -{ - struct dentry *dentry = file->f_path.dentry; - struct smb_sb_info *server = server_from_dentry(dentry); - int result; - - VERBOSE("sync file %s/%s\n", DENTRY_PATH(dentry)); - - /* - * The VFS will writepage() all dirty pages for us, but we - * should send a SMBflush to the server, letting it know that - * we want things synchronized with actual storage. - * - * Note: this function requires all pages to have been written already - * (should be ok with writepage_sync) - */ - result = smb_proc_flush(server, SMB_I(dentry->d_inode)->fileid); - return result; -} - -/* - * Read a page synchronously. - */ -static int -smb_readpage_sync(struct dentry *dentry, struct page *page) -{ - char *buffer = kmap(page); - loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT; - struct smb_sb_info *server = server_from_dentry(dentry); - unsigned int rsize = smb_get_rsize(server); - int count = PAGE_SIZE; - int result; - - VERBOSE("file %s/%s, count=%d@%Ld, rsize=%d\n", - DENTRY_PATH(dentry), count, offset, rsize); - - result = smb_open(dentry, SMB_O_RDONLY); - if (result < 0) - goto io_error; - - do { - if (count < rsize) - rsize = count; - - result = server->ops->read(dentry->d_inode,offset,rsize,buffer); - if (result < 0) - goto io_error; - - count -= result; - offset += result; - buffer += result; - dentry->d_inode->i_atime = - current_fs_time(dentry->d_inode->i_sb); - if (result < rsize) - break; - } while (count); - - memset(buffer, 0, count); - flush_dcache_page(page); - SetPageUptodate(page); - result = 0; - -io_error: - kunmap(page); - unlock_page(page); - return result; -} - -/* - * We are called with the page locked and we unlock it when done. - */ -static int -smb_readpage(struct file *file, struct page *page) -{ - int error; - struct dentry *dentry = file->f_path.dentry; - - page_cache_get(page); - error = smb_readpage_sync(dentry, page); - page_cache_release(page); - return error; -} - -/* - * Write a page synchronously. - * Offset is the data offset within the page. - */ -static int -smb_writepage_sync(struct inode *inode, struct page *page, - unsigned long pageoffset, unsigned int count) -{ - loff_t offset; - char *buffer = kmap(page) + pageoffset; - struct smb_sb_info *server = server_from_inode(inode); - unsigned int wsize = smb_get_wsize(server); - int ret = 0; - - offset = ((loff_t)page->index << PAGE_CACHE_SHIFT) + pageoffset; - VERBOSE("file ino=%ld, fileid=%d, count=%d@%Ld, wsize=%d\n", - inode->i_ino, SMB_I(inode)->fileid, count, offset, wsize); - - do { - int write_ret; - - if (count < wsize) - wsize = count; - - write_ret = server->ops->write(inode, offset, wsize, buffer); - if (write_ret < 0) { - PARANOIA("failed write, wsize=%d, write_ret=%d\n", - wsize, write_ret); - ret = write_ret; - break; - } - /* N.B. what if result < wsize?? */ -#ifdef SMBFS_PARANOIA - if (write_ret < wsize) - PARANOIA("short write, wsize=%d, write_ret=%d\n", - wsize, write_ret); -#endif - buffer += wsize; - offset += wsize; - count -= wsize; - /* - * Update the inode now rather than waiting for a refresh. - */ - inode->i_mtime = inode->i_atime = current_fs_time(inode->i_sb); - SMB_I(inode)->flags |= SMB_F_LOCALWRITE; - if (offset > inode->i_size) - inode->i_size = offset; - } while (count); - - kunmap(page); - return ret; -} - -/* - * Write a page to the server. This will be used for NFS swapping only - * (for now), and we currently do this synchronously only. - * - * We are called with the page locked and we unlock it when done. - */ -static int -smb_writepage(struct page *page, struct writeback_control *wbc) -{ - struct address_space *mapping = page->mapping; - struct inode *inode; - unsigned long end_index; - unsigned offset = PAGE_CACHE_SIZE; - int err; - - BUG_ON(!mapping); - inode = mapping->host; - BUG_ON(!inode); - - end_index = inode->i_size >> PAGE_CACHE_SHIFT; - - /* easy case */ - if (page->index < end_index) - goto do_it; - /* things got complicated... */ - offset = inode->i_size & (PAGE_CACHE_SIZE-1); - /* OK, are we completely out? */ - if (page->index >= end_index+1 || !offset) - return 0; /* truncated - don't care */ -do_it: - page_cache_get(page); - err = smb_writepage_sync(inode, page, 0, offset); - SetPageUptodate(page); - unlock_page(page); - page_cache_release(page); - return err; -} - -static int -smb_updatepage(struct file *file, struct page *page, unsigned long offset, - unsigned int count) -{ - struct dentry *dentry = file->f_path.dentry; - - DEBUG1("(%s/%s %d@%lld)\n", DENTRY_PATH(dentry), count, - ((unsigned long long)page->index << PAGE_CACHE_SHIFT) + offset); - - return smb_writepage_sync(dentry->d_inode, page, offset, count); -} - -static ssize_t -smb_file_aio_read(struct kiocb *iocb, const struct iovec *iov, - unsigned long nr_segs, loff_t pos) -{ - struct file * file = iocb->ki_filp; - struct dentry * dentry = file->f_path.dentry; - ssize_t status; - - VERBOSE("file %s/%s, count=%lu@%lu\n", DENTRY_PATH(dentry), - (unsigned long) iocb->ki_left, (unsigned long) pos); - - status = smb_revalidate_inode(dentry); - if (status) { - PARANOIA("%s/%s validation failed, error=%Zd\n", - DENTRY_PATH(dentry), status); - goto out; - } - - VERBOSE("before read, size=%ld, flags=%x, atime=%ld\n", - (long)dentry->d_inode->i_size, - dentry->d_inode->i_flags, dentry->d_inode->i_atime.tv_sec); - - status = generic_file_aio_read(iocb, iov, nr_segs, pos); -out: - return status; -} - -static int -smb_file_mmap(struct file * file, struct vm_area_struct * vma) -{ - struct dentry * dentry = file->f_path.dentry; - int status; - - VERBOSE("file %s/%s, address %lu - %lu\n", - DENTRY_PATH(dentry), vma->vm_start, vma->vm_end); - - status = smb_revalidate_inode(dentry); - if (status) { - PARANOIA("%s/%s validation failed, error=%d\n", - DENTRY_PATH(dentry), status); - goto out; - } - status = generic_file_mmap(file, vma); -out: - return status; -} - -static ssize_t -smb_file_splice_read(struct file *file, loff_t *ppos, - struct pipe_inode_info *pipe, size_t count, - unsigned int flags) -{ - struct dentry *dentry = file->f_path.dentry; - ssize_t status; - - VERBOSE("file %s/%s, pos=%Ld, count=%lu\n", - DENTRY_PATH(dentry), *ppos, count); - - status = smb_revalidate_inode(dentry); - if (status) { - PARANOIA("%s/%s validation failed, error=%Zd\n", - DENTRY_PATH(dentry), status); - goto out; - } - status = generic_file_splice_read(file, ppos, pipe, count, flags); -out: - return status; -} - -/* - * This does the "real" work of the write. The generic routine has - * allocated the page, locked it, done all the page alignment stuff - * calculations etc. Now we should just copy the data from user - * space and write it back to the real medium.. - * - * If the writer ends up delaying the write, the writer needs to - * increment the page use counts until he is done with the page. - */ -static int smb_write_begin(struct file *file, struct address_space *mapping, - loff_t pos, unsigned len, unsigned flags, - struct page **pagep, void **fsdata) -{ - pgoff_t index = pos >> PAGE_CACHE_SHIFT; - *pagep = grab_cache_page_write_begin(mapping, index, flags); - if (!*pagep) - return -ENOMEM; - return 0; -} - -static int smb_write_end(struct file *file, struct address_space *mapping, - loff_t pos, unsigned len, unsigned copied, - struct page *page, void *fsdata) -{ - int status; - unsigned offset = pos & (PAGE_CACHE_SIZE - 1); - - lock_kernel(); - status = smb_updatepage(file, page, offset, copied); - unlock_kernel(); - - if (!status) { - if (!PageUptodate(page) && copied == PAGE_CACHE_SIZE) - SetPageUptodate(page); - status = copied; - } - - unlock_page(page); - page_cache_release(page); - - return status; -} - -const struct address_space_operations smb_file_aops = { - .readpage = smb_readpage, - .writepage = smb_writepage, - .write_begin = smb_write_begin, - .write_end = smb_write_end, -}; - -/* - * Write to a file (through the page cache). - */ -static ssize_t -smb_file_aio_write(struct kiocb *iocb, const struct iovec *iov, - unsigned long nr_segs, loff_t pos) -{ - struct file * file = iocb->ki_filp; - struct dentry * dentry = file->f_path.dentry; - ssize_t result; - - VERBOSE("file %s/%s, count=%lu@%lu\n", - DENTRY_PATH(dentry), - (unsigned long) iocb->ki_left, (unsigned long) pos); - - result = smb_revalidate_inode(dentry); - if (result) { - PARANOIA("%s/%s validation failed, error=%Zd\n", - DENTRY_PATH(dentry), result); - goto out; - } - - result = smb_open(dentry, SMB_O_WRONLY); - if (result) - goto out; - - if (iocb->ki_left > 0) { - result = generic_file_aio_write(iocb, iov, nr_segs, pos); - VERBOSE("pos=%ld, size=%ld, mtime=%ld, atime=%ld\n", - (long) file->f_pos, (long) dentry->d_inode->i_size, - dentry->d_inode->i_mtime.tv_sec, - dentry->d_inode->i_atime.tv_sec); - } -out: - return result; -} - -static int -smb_file_open(struct inode *inode, struct file * file) -{ - int result; - struct dentry *dentry = file->f_path.dentry; - int smb_mode = (file->f_mode & O_ACCMODE) - 1; - - lock_kernel(); - result = smb_open(dentry, smb_mode); - if (result) - goto out; - SMB_I(inode)->openers++; -out: - unlock_kernel(); - return result; -} - -static int -smb_file_release(struct inode *inode, struct file * file) -{ - lock_kernel(); - if (!--SMB_I(inode)->openers) { - /* We must flush any dirty pages now as we won't be able to - write anything after close. mmap can trigger this. - "openers" should perhaps include mmap'ers ... */ - filemap_write_and_wait(inode->i_mapping); - smb_close(inode); - } - unlock_kernel(); - return 0; -} - -/* - * Check whether the required access is compatible with - * an inode's permission. SMB doesn't recognize superuser - * privileges, so we need our own check for this. - */ -static int -smb_file_permission(struct inode *inode, int mask, unsigned int flags) -{ - int mode = inode->i_mode; - int error = 0; - - if (flags & IPERM_FLAG_RCU) - return -ECHILD; - - VERBOSE("mode=%x, mask=%x\n", mode, mask); - - /* Look at user permissions */ - mode >>= 6; - if (mask & ~mode & (MAY_READ | MAY_WRITE | MAY_EXEC)) - error = -EACCES; - return error; -} - -static loff_t smb_remote_llseek(struct file *file, loff_t offset, int origin) -{ - loff_t ret; - lock_kernel(); - ret = generic_file_llseek_unlocked(file, offset, origin); - unlock_kernel(); - return ret; -} - -const struct file_operations smb_file_operations = -{ - .llseek = smb_remote_llseek, - .read = do_sync_read, - .aio_read = smb_file_aio_read, - .write = do_sync_write, - .aio_write = smb_file_aio_write, - .unlocked_ioctl = smb_ioctl, - .mmap = smb_file_mmap, - .open = smb_file_open, - .release = smb_file_release, - .fsync = smb_fsync, - .splice_read = smb_file_splice_read, -}; - -const struct inode_operations smb_file_inode_operations = -{ - .permission = smb_file_permission, - .getattr = smb_getattr, - .setattr = smb_notify_change, -}; diff --git a/drivers/staging/smbfs/getopt.c b/drivers/staging/smbfs/getopt.c deleted file mode 100644 index 7ae0f5273ab1..000000000000 --- a/drivers/staging/smbfs/getopt.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * getopt.c - */ - -#include -#include -#include - -#include "getopt.h" - -/** - * smb_getopt - option parser - * @caller: name of the caller, for error messages - * @options: the options string - * @opts: an array of &struct option entries controlling parser operations - * @optopt: output; will contain the current option - * @optarg: output; will contain the value (if one exists) - * @flag: output; may be NULL; should point to a long for or'ing flags - * @value: output; may be NULL; will be overwritten with the integer value - * of the current argument. - * - * Helper to parse options on the format used by mount ("a=b,c=d,e,f"). - * Returns opts->val if a matching entry in the 'opts' array is found, - * 0 when no more tokens are found, -1 if an error is encountered. - */ -int smb_getopt(char *caller, char **options, struct option *opts, - char **optopt, char **optarg, unsigned long *flag, - unsigned long *value) -{ - char *token; - char *val; - int i; - - do { - if ((token = strsep(options, ",")) == NULL) - return 0; - } while (*token == '\0'); - *optopt = token; - - *optarg = NULL; - if ((val = strchr (token, '=')) != NULL) { - *val++ = 0; - if (value) - *value = simple_strtoul(val, NULL, 0); - *optarg = val; - } - - for (i = 0; opts[i].name != NULL; i++) { - if (!strcmp(opts[i].name, token)) { - if (!opts[i].flag && (!val || !*val)) { - printk("%s: the %s option requires an argument\n", - caller, token); - return -1; - } - - if (flag && opts[i].flag) - *flag |= opts[i].flag; - - return opts[i].val; - } - } - printk("%s: Unrecognized mount option %s\n", caller, token); - return -1; -} diff --git a/drivers/staging/smbfs/getopt.h b/drivers/staging/smbfs/getopt.h deleted file mode 100644 index 146219ac7c46..000000000000 --- a/drivers/staging/smbfs/getopt.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _LINUX_GETOPT_H -#define _LINUX_GETOPT_H - -struct option { - const char *name; - unsigned long flag; - int val; -}; - -extern int smb_getopt(char *caller, char **options, struct option *opts, - char **optopt, char **optarg, unsigned long *flag, - unsigned long *value); - -#endif /* _LINUX_GETOPT_H */ diff --git a/drivers/staging/smbfs/inode.c b/drivers/staging/smbfs/inode.c deleted file mode 100644 index 0778589d9e9e..000000000000 --- a/drivers/staging/smbfs/inode.c +++ /dev/null @@ -1,854 +0,0 @@ -/* - * inode.c - * - * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke - * Copyright (C) 1997 by Volker Lendecke - * - * Please add a note about your changes to smbfs in the ChangeLog file. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "smb_fs.h" -#include "smbno.h" -#include "smb_mount.h" -#include "smb_debug.h" -#include "getopt.h" -#include "proto.h" - -/* Always pick a default string */ -#ifdef CONFIG_SMB_NLS_REMOTE -#define SMB_NLS_REMOTE CONFIG_SMB_NLS_REMOTE -#else -#define SMB_NLS_REMOTE "" -#endif - -#define SMB_TTL_DEFAULT 1000 - -static void smb_evict_inode(struct inode *); -static void smb_put_super(struct super_block *); -static int smb_statfs(struct dentry *, struct kstatfs *); -static int smb_show_options(struct seq_file *, struct vfsmount *); - -static struct kmem_cache *smb_inode_cachep; - -static struct inode *smb_alloc_inode(struct super_block *sb) -{ - struct smb_inode_info *ei; - ei = (struct smb_inode_info *)kmem_cache_alloc(smb_inode_cachep, GFP_KERNEL); - if (!ei) - return NULL; - return &ei->vfs_inode; -} - -static void smb_i_callback(struct rcu_head *head) -{ - struct inode *inode = container_of(head, struct inode, i_rcu); - INIT_LIST_HEAD(&inode->i_dentry); - kmem_cache_free(smb_inode_cachep, SMB_I(inode)); -} - -static void smb_destroy_inode(struct inode *inode) -{ - call_rcu(&inode->i_rcu, smb_i_callback); -} - -static void init_once(void *foo) -{ - struct smb_inode_info *ei = (struct smb_inode_info *) foo; - - inode_init_once(&ei->vfs_inode); -} - -static int init_inodecache(void) -{ - smb_inode_cachep = kmem_cache_create("smb_inode_cache", - sizeof(struct smb_inode_info), - 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD), - init_once); - if (smb_inode_cachep == NULL) - return -ENOMEM; - return 0; -} - -static void destroy_inodecache(void) -{ - kmem_cache_destroy(smb_inode_cachep); -} - -static int smb_remount(struct super_block *sb, int *flags, char *data) -{ - *flags |= MS_NODIRATIME; - return 0; -} - -static const struct super_operations smb_sops = -{ - .alloc_inode = smb_alloc_inode, - .destroy_inode = smb_destroy_inode, - .drop_inode = generic_delete_inode, - .evict_inode = smb_evict_inode, - .put_super = smb_put_super, - .statfs = smb_statfs, - .show_options = smb_show_options, - .remount_fs = smb_remount, -}; - - -/* We are always generating a new inode here */ -struct inode * -smb_iget(struct super_block *sb, struct smb_fattr *fattr) -{ - struct smb_sb_info *server = SMB_SB(sb); - struct inode *result; - - DEBUG1("smb_iget: %p\n", fattr); - - result = new_inode(sb); - if (!result) - return result; - result->i_ino = fattr->f_ino; - SMB_I(result)->open = 0; - SMB_I(result)->fileid = 0; - SMB_I(result)->access = 0; - SMB_I(result)->flags = 0; - SMB_I(result)->closed = 0; - SMB_I(result)->openers = 0; - smb_set_inode_attr(result, fattr); - if (S_ISREG(result->i_mode)) { - result->i_op = &smb_file_inode_operations; - result->i_fop = &smb_file_operations; - result->i_data.a_ops = &smb_file_aops; - } else if (S_ISDIR(result->i_mode)) { - if (server->opt.capabilities & SMB_CAP_UNIX) - result->i_op = &smb_dir_inode_operations_unix; - else - result->i_op = &smb_dir_inode_operations; - result->i_fop = &smb_dir_operations; - } else if (S_ISLNK(result->i_mode)) { - result->i_op = &smb_link_inode_operations; - } else { - init_special_inode(result, result->i_mode, fattr->f_rdev); - } - insert_inode_hash(result); - return result; -} - -/* - * Copy the inode data to a smb_fattr structure. - */ -void -smb_get_inode_attr(struct inode *inode, struct smb_fattr *fattr) -{ - memset(fattr, 0, sizeof(struct smb_fattr)); - fattr->f_mode = inode->i_mode; - fattr->f_nlink = inode->i_nlink; - fattr->f_ino = inode->i_ino; - fattr->f_uid = inode->i_uid; - fattr->f_gid = inode->i_gid; - fattr->f_size = inode->i_size; - fattr->f_mtime = inode->i_mtime; - fattr->f_ctime = inode->i_ctime; - fattr->f_atime = inode->i_atime; - fattr->f_blocks = inode->i_blocks; - - fattr->attr = SMB_I(inode)->attr; - /* - * Keep the attributes in sync with the inode permissions. - */ - if (fattr->f_mode & S_IWUSR) - fattr->attr &= ~aRONLY; - else - fattr->attr |= aRONLY; -} - -/* - * Update the inode, possibly causing it to invalidate its pages if mtime/size - * is different from last time. - */ -void -smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr) -{ - struct smb_inode_info *ei = SMB_I(inode); - - /* - * A size change should have a different mtime, or same mtime - * but different size. - */ - time_t last_time = inode->i_mtime.tv_sec; - loff_t last_sz = inode->i_size; - - inode->i_mode = fattr->f_mode; - inode->i_nlink = fattr->f_nlink; - inode->i_uid = fattr->f_uid; - inode->i_gid = fattr->f_gid; - inode->i_ctime = fattr->f_ctime; - inode->i_blocks = fattr->f_blocks; - inode->i_size = fattr->f_size; - inode->i_mtime = fattr->f_mtime; - inode->i_atime = fattr->f_atime; - ei->attr = fattr->attr; - - /* - * Update the "last time refreshed" field for revalidation. - */ - ei->oldmtime = jiffies; - - if (inode->i_mtime.tv_sec != last_time || inode->i_size != last_sz) { - VERBOSE("%ld changed, old=%ld, new=%ld, oz=%ld, nz=%ld\n", - inode->i_ino, - (long) last_time, (long) inode->i_mtime.tv_sec, - (long) last_sz, (long) inode->i_size); - - if (!S_ISDIR(inode->i_mode)) - invalidate_remote_inode(inode); - } -} - -/* - * This is called if the connection has gone bad ... - * try to kill off all the current inodes. - */ -void -smb_invalidate_inodes(struct smb_sb_info *server) -{ - VERBOSE("\n"); - shrink_dcache_sb(SB_of(server)); -} - -/* - * This is called to update the inode attributes after - * we've made changes to a file or directory. - */ -static int -smb_refresh_inode(struct dentry *dentry) -{ - struct inode *inode = dentry->d_inode; - int error; - struct smb_fattr fattr; - - error = smb_proc_getattr(dentry, &fattr); - if (!error) { - smb_renew_times(dentry); - /* - * Check whether the type part of the mode changed, - * and don't update the attributes if it did. - * - * And don't dick with the root inode - */ - if (inode->i_ino == 2) - return error; - if (S_ISLNK(inode->i_mode)) - return error; /* VFS will deal with it */ - - if ((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT)) { - smb_set_inode_attr(inode, &fattr); - } else { - /* - * Big trouble! The inode has become a new object, - * so any operations attempted on it are invalid. - * - * To limit damage, mark the inode as bad so that - * subsequent lookup validations will fail. - */ - PARANOIA("%s/%s changed mode, %07o to %07o\n", - DENTRY_PATH(dentry), - inode->i_mode, fattr.f_mode); - - fattr.f_mode = inode->i_mode; /* save mode */ - make_bad_inode(inode); - inode->i_mode = fattr.f_mode; /* restore mode */ - /* - * No need to worry about unhashing the dentry: the - * lookup validation will see that the inode is bad. - * But we do want to invalidate the caches ... - */ - if (!S_ISDIR(inode->i_mode)) - invalidate_remote_inode(inode); - else - smb_invalid_dir_cache(inode); - error = -EIO; - } - } - return error; -} - -/* - * This is called when we want to check whether the inode - * has changed on the server. If it has changed, we must - * invalidate our local caches. - */ -int -smb_revalidate_inode(struct dentry *dentry) -{ - struct smb_sb_info *s = server_from_dentry(dentry); - struct inode *inode = dentry->d_inode; - int error = 0; - - DEBUG1("smb_revalidate_inode\n"); - lock_kernel(); - - /* - * Check whether we've recently refreshed the inode. - */ - if (time_before(jiffies, SMB_I(inode)->oldmtime + SMB_MAX_AGE(s))) { - VERBOSE("up-to-date, ino=%ld, jiffies=%lu, oldtime=%lu\n", - inode->i_ino, jiffies, SMB_I(inode)->oldmtime); - goto out; - } - - error = smb_refresh_inode(dentry); -out: - unlock_kernel(); - return error; -} - -/* - * This routine is called when i_nlink == 0 and i_count goes to 0. - * All blocking cleanup operations need to go here to avoid races. - */ -static void -smb_evict_inode(struct inode *ino) -{ - DEBUG1("ino=%ld\n", ino->i_ino); - truncate_inode_pages(&ino->i_data, 0); - end_writeback(ino); - lock_kernel(); - if (smb_close(ino)) - PARANOIA("could not close inode %ld\n", ino->i_ino); - unlock_kernel(); -} - -static struct option opts[] = { - { "version", 0, 'v' }, - { "win95", SMB_MOUNT_WIN95, 1 }, - { "oldattr", SMB_MOUNT_OLDATTR, 1 }, - { "dirattr", SMB_MOUNT_DIRATTR, 1 }, - { "case", SMB_MOUNT_CASE, 1 }, - { "uid", 0, 'u' }, - { "gid", 0, 'g' }, - { "file_mode", 0, 'f' }, - { "dir_mode", 0, 'd' }, - { "iocharset", 0, 'i' }, - { "codepage", 0, 'c' }, - { "ttl", 0, 't' }, - { NULL, 0, 0} -}; - -static int -parse_options(struct smb_mount_data_kernel *mnt, char *options) -{ - int c; - unsigned long flags; - unsigned long value; - char *optarg; - char *optopt; - - flags = 0; - while ( (c = smb_getopt("smbfs", &options, opts, - &optopt, &optarg, &flags, &value)) > 0) { - - VERBOSE("'%s' -> '%s'\n", optopt, optarg ? optarg : ""); - switch (c) { - case 1: - /* got a "flag" option */ - break; - case 'v': - if (value != SMB_MOUNT_VERSION) { - printk ("smbfs: Bad mount version %ld, expected %d\n", - value, SMB_MOUNT_VERSION); - return 0; - } - mnt->version = value; - break; - case 'u': - mnt->uid = value; - flags |= SMB_MOUNT_UID; - break; - case 'g': - mnt->gid = value; - flags |= SMB_MOUNT_GID; - break; - case 'f': - mnt->file_mode = (value & S_IRWXUGO) | S_IFREG; - flags |= SMB_MOUNT_FMODE; - break; - case 'd': - mnt->dir_mode = (value & S_IRWXUGO) | S_IFDIR; - flags |= SMB_MOUNT_DMODE; - break; - case 'i': - strlcpy(mnt->codepage.local_name, optarg, - SMB_NLS_MAXNAMELEN); - break; - case 'c': - strlcpy(mnt->codepage.remote_name, optarg, - SMB_NLS_MAXNAMELEN); - break; - case 't': - mnt->ttl = value; - break; - default: - printk ("smbfs: Unrecognized mount option %s\n", - optopt); - return -1; - } - } - mnt->flags = flags; - return c; -} - -/* - * smb_show_options() is for displaying mount options in /proc/mounts. - * It tries to avoid showing settings that were not changed from their - * defaults. - */ -static int -smb_show_options(struct seq_file *s, struct vfsmount *m) -{ - struct smb_mount_data_kernel *mnt = SMB_SB(m->mnt_sb)->mnt; - int i; - - for (i = 0; opts[i].name != NULL; i++) - if (mnt->flags & opts[i].flag) - seq_printf(s, ",%s", opts[i].name); - - if (mnt->flags & SMB_MOUNT_UID) - seq_printf(s, ",uid=%d", mnt->uid); - if (mnt->flags & SMB_MOUNT_GID) - seq_printf(s, ",gid=%d", mnt->gid); - if (mnt->mounted_uid != 0) - seq_printf(s, ",mounted_uid=%d", mnt->mounted_uid); - - /* - * Defaults for file_mode and dir_mode are unknown to us; they - * depend on the current umask of the user doing the mount. - */ - if (mnt->flags & SMB_MOUNT_FMODE) - seq_printf(s, ",file_mode=%04o", mnt->file_mode & S_IRWXUGO); - if (mnt->flags & SMB_MOUNT_DMODE) - seq_printf(s, ",dir_mode=%04o", mnt->dir_mode & S_IRWXUGO); - - if (strcmp(mnt->codepage.local_name, CONFIG_NLS_DEFAULT)) - seq_printf(s, ",iocharset=%s", mnt->codepage.local_name); - if (strcmp(mnt->codepage.remote_name, SMB_NLS_REMOTE)) - seq_printf(s, ",codepage=%s", mnt->codepage.remote_name); - - if (mnt->ttl != SMB_TTL_DEFAULT) - seq_printf(s, ",ttl=%d", mnt->ttl); - - return 0; -} - -static void -smb_unload_nls(struct smb_sb_info *server) -{ - unload_nls(server->remote_nls); - unload_nls(server->local_nls); -} - -static void -smb_put_super(struct super_block *sb) -{ - struct smb_sb_info *server = SMB_SB(sb); - - lock_kernel(); - - smb_lock_server(server); - server->state = CONN_INVALID; - smbiod_unregister_server(server); - - smb_close_socket(server); - - if (server->conn_pid) - kill_pid(server->conn_pid, SIGTERM, 1); - - bdi_destroy(&server->bdi); - kfree(server->ops); - smb_unload_nls(server); - sb->s_fs_info = NULL; - smb_unlock_server(server); - put_pid(server->conn_pid); - kfree(server); - - unlock_kernel(); -} - -static int smb_fill_super(struct super_block *sb, void *raw_data, int silent) -{ - struct smb_sb_info *server; - struct smb_mount_data_kernel *mnt; - struct smb_mount_data *oldmnt; - struct inode *root_inode; - struct smb_fattr root; - int ver; - void *mem; - static int warn_count; - - lock_kernel(); - - if (warn_count < 5) { - warn_count++; - printk(KERN_EMERG "smbfs is deprecated and will be removed" - " from the 2.6.37 kernel. Please migrate to cifs\n"); - } - - if (!raw_data) - goto out_no_data; - - oldmnt = (struct smb_mount_data *) raw_data; - ver = oldmnt->version; - if (ver != SMB_MOUNT_OLDVERSION && cpu_to_be32(ver) != SMB_MOUNT_ASCII) - goto out_wrong_data; - - sb->s_flags |= MS_NODIRATIME; - sb->s_blocksize = 1024; /* Eh... Is this correct? */ - sb->s_blocksize_bits = 10; - sb->s_magic = SMB_SUPER_MAGIC; - sb->s_op = &smb_sops; - sb->s_time_gran = 100; - - server = kzalloc(sizeof(struct smb_sb_info), GFP_KERNEL); - if (!server) - goto out_no_server; - sb->s_fs_info = server; - - if (bdi_setup_and_register(&server->bdi, "smbfs", BDI_CAP_MAP_COPY)) - goto out_bdi; - - sb->s_bdi = &server->bdi; - - server->super_block = sb; - server->mnt = NULL; - server->sock_file = NULL; - init_waitqueue_head(&server->conn_wq); - sema_init(&server->sem, 1); - INIT_LIST_HEAD(&server->entry); - INIT_LIST_HEAD(&server->xmitq); - INIT_LIST_HEAD(&server->recvq); - server->conn_error = 0; - server->conn_pid = NULL; - server->state = CONN_INVALID; /* no connection yet */ - server->generation = 0; - - /* Allocate the global temp buffer and some superblock helper structs */ - /* FIXME: move these to the smb_sb_info struct */ - VERBOSE("alloc chunk = %lu\n", sizeof(struct smb_ops) + - sizeof(struct smb_mount_data_kernel)); - mem = kmalloc(sizeof(struct smb_ops) + - sizeof(struct smb_mount_data_kernel), GFP_KERNEL); - if (!mem) - goto out_no_mem; - - server->ops = mem; - smb_install_null_ops(server->ops); - server->mnt = mem + sizeof(struct smb_ops); - - /* Setup NLS stuff */ - server->remote_nls = NULL; - server->local_nls = NULL; - - mnt = server->mnt; - - memset(mnt, 0, sizeof(struct smb_mount_data_kernel)); - strlcpy(mnt->codepage.local_name, CONFIG_NLS_DEFAULT, - SMB_NLS_MAXNAMELEN); - strlcpy(mnt->codepage.remote_name, SMB_NLS_REMOTE, - SMB_NLS_MAXNAMELEN); - - mnt->ttl = SMB_TTL_DEFAULT; - if (ver == SMB_MOUNT_OLDVERSION) { - mnt->version = oldmnt->version; - - SET_UID(mnt->uid, oldmnt->uid); - SET_GID(mnt->gid, oldmnt->gid); - - mnt->file_mode = (oldmnt->file_mode & S_IRWXUGO) | S_IFREG; - mnt->dir_mode = (oldmnt->dir_mode & S_IRWXUGO) | S_IFDIR; - - mnt->flags = (oldmnt->file_mode >> 9) | SMB_MOUNT_UID | - SMB_MOUNT_GID | SMB_MOUNT_FMODE | SMB_MOUNT_DMODE; - } else { - mnt->file_mode = S_IRWXU | S_IRGRP | S_IXGRP | - S_IROTH | S_IXOTH | S_IFREG; - mnt->dir_mode = S_IRWXU | S_IRGRP | S_IXGRP | - S_IROTH | S_IXOTH | S_IFDIR; - if (parse_options(mnt, raw_data)) - goto out_bad_option; - } - mnt->mounted_uid = current_uid(); - smb_setcodepage(server, &mnt->codepage); - - /* - * Display the enabled options - * Note: smb_proc_getattr uses these in 2.4 (but was changed in 2.2) - */ - if (mnt->flags & SMB_MOUNT_OLDATTR) - printk("SMBFS: Using core getattr (Win 95 speedup)\n"); - else if (mnt->flags & SMB_MOUNT_DIRATTR) - printk("SMBFS: Using dir ff getattr\n"); - - if (smbiod_register_server(server) < 0) { - printk(KERN_ERR "smbfs: failed to start smbiod\n"); - goto out_no_smbiod; - } - if (server->mnt->flags & SMB_MOUNT_CASE) - sb->s_d_op = &smbfs_dentry_operations_case; - else - sb->s_d_op = &smbfs_dentry_operations; - - /* - * Keep the super block locked while we get the root inode. - */ - smb_init_root_dirent(server, &root, sb); - root_inode = smb_iget(sb, &root); - if (!root_inode) - goto out_no_root; - - sb->s_root = d_alloc_root(root_inode); - if (!sb->s_root) - goto out_no_root; - - smb_new_dentry(sb->s_root); - - unlock_kernel(); - return 0; - -out_no_root: - iput(root_inode); -out_no_smbiod: - smb_unload_nls(server); -out_bad_option: - kfree(mem); -out_no_mem: - bdi_destroy(&server->bdi); -out_bdi: - if (!server->mnt) - printk(KERN_ERR "smb_fill_super: allocation failure\n"); - sb->s_fs_info = NULL; - kfree(server); - goto out_fail; -out_wrong_data: - printk(KERN_ERR "smbfs: mount_data version %d is not supported\n", ver); - goto out_fail; -out_no_data: - printk(KERN_ERR "smb_fill_super: missing data argument\n"); -out_fail: - unlock_kernel(); - return -EINVAL; -out_no_server: - printk(KERN_ERR "smb_fill_super: cannot allocate struct smb_sb_info\n"); - unlock_kernel(); - return -ENOMEM; -} - -static int -smb_statfs(struct dentry *dentry, struct kstatfs *buf) -{ - int result; - - lock_kernel(); - - result = smb_proc_dskattr(dentry, buf); - - unlock_kernel(); - - buf->f_type = SMB_SUPER_MAGIC; - buf->f_namelen = SMB_MAXPATHLEN; - return result; -} - -int smb_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) -{ - int err = smb_revalidate_inode(dentry); - if (!err) - generic_fillattr(dentry->d_inode, stat); - return err; -} - -int -smb_notify_change(struct dentry *dentry, struct iattr *attr) -{ - struct inode *inode = dentry->d_inode; - struct smb_sb_info *server = server_from_dentry(dentry); - unsigned int mask = (S_IFREG | S_IFDIR | S_IRWXUGO); - int error, changed, refresh = 0; - struct smb_fattr fattr; - - lock_kernel(); - - error = smb_revalidate_inode(dentry); - if (error) - goto out; - - if ((error = inode_change_ok(inode, attr)) < 0) - goto out; - - error = -EPERM; - if ((attr->ia_valid & ATTR_UID) && (attr->ia_uid != server->mnt->uid)) - goto out; - - if ((attr->ia_valid & ATTR_GID) && (attr->ia_uid != server->mnt->gid)) - goto out; - - if ((attr->ia_valid & ATTR_MODE) && (attr->ia_mode & ~mask)) - goto out; - - if ((attr->ia_valid & ATTR_SIZE) != 0) { - VERBOSE("changing %s/%s, old size=%ld, new size=%ld\n", - DENTRY_PATH(dentry), - (long) inode->i_size, (long) attr->ia_size); - - filemap_write_and_wait(inode->i_mapping); - - error = smb_open(dentry, O_WRONLY); - if (error) - goto out; - error = server->ops->truncate(inode, attr->ia_size); - if (error) - goto out; - truncate_setsize(inode, attr->ia_size); - refresh = 1; - } - - if (server->opt.capabilities & SMB_CAP_UNIX) { - /* For now we don't want to set the size with setattr_unix */ - attr->ia_valid &= ~ATTR_SIZE; - /* FIXME: only call if we actually want to set something? */ - error = smb_proc_setattr_unix(dentry, attr, 0, 0); - if (!error) - refresh = 1; - - goto out; - } - - /* - * Initialize the fattr and check for changed fields. - * Note: CTIME under SMB is creation time rather than - * change time, so we don't attempt to change it. - */ - smb_get_inode_attr(inode, &fattr); - - changed = 0; - if ((attr->ia_valid & ATTR_MTIME) != 0) { - fattr.f_mtime = attr->ia_mtime; - changed = 1; - } - if ((attr->ia_valid & ATTR_ATIME) != 0) { - fattr.f_atime = attr->ia_atime; - /* Earlier protocols don't have an access time */ - if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2) - changed = 1; - } - if (changed) { - error = smb_proc_settime(dentry, &fattr); - if (error) - goto out; - refresh = 1; - } - - /* - * Check for mode changes ... we're extremely limited in - * what can be set for SMB servers: just the read-only bit. - */ - if ((attr->ia_valid & ATTR_MODE) != 0) { - VERBOSE("%s/%s mode change, old=%x, new=%x\n", - DENTRY_PATH(dentry), fattr.f_mode, attr->ia_mode); - changed = 0; - if (attr->ia_mode & S_IWUSR) { - if (fattr.attr & aRONLY) { - fattr.attr &= ~aRONLY; - changed = 1; - } - } else { - if (!(fattr.attr & aRONLY)) { - fattr.attr |= aRONLY; - changed = 1; - } - } - if (changed) { - error = smb_proc_setattr(dentry, &fattr); - if (error) - goto out; - refresh = 1; - } - } - error = 0; - -out: - if (refresh) - smb_refresh_inode(dentry); - unlock_kernel(); - return error; -} - -static struct dentry *smb_mount(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) -{ - return mount_nodev(fs_type, flags, data, smb_fill_super); -} - -static struct file_system_type smb_fs_type = { - .owner = THIS_MODULE, - .name = "smbfs", - .mount = smb_mount, - .kill_sb = kill_anon_super, - .fs_flags = FS_BINARY_MOUNTDATA, -}; - -static int __init init_smb_fs(void) -{ - int err; - DEBUG1("registering ...\n"); - - err = init_inodecache(); - if (err) - goto out_inode; - err = smb_init_request_cache(); - if (err) - goto out_request; - err = register_filesystem(&smb_fs_type); - if (err) - goto out; - return 0; -out: - smb_destroy_request_cache(); -out_request: - destroy_inodecache(); -out_inode: - return err; -} - -static void __exit exit_smb_fs(void) -{ - DEBUG1("unregistering ...\n"); - unregister_filesystem(&smb_fs_type); - smb_destroy_request_cache(); - destroy_inodecache(); -} - -module_init(init_smb_fs) -module_exit(exit_smb_fs) -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/smbfs/ioctl.c b/drivers/staging/smbfs/ioctl.c deleted file mode 100644 index 2da169267470..000000000000 --- a/drivers/staging/smbfs/ioctl.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * ioctl.c - * - * Copyright (C) 1995, 1996 by Volker Lendecke - * Copyright (C) 1997 by Volker Lendecke - * - * Please add a note about your changes to smbfs in the ChangeLog file. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "smb_fs.h" -#include "smb_mount.h" -#include "proto.h" - -long -smb_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - struct smb_sb_info *server = server_from_inode(filp->f_path.dentry->d_inode); - struct smb_conn_opt opt; - int result = -EINVAL; - - lock_kernel(); - switch (cmd) { - uid16_t uid16; - uid_t uid32; - case SMB_IOC_GETMOUNTUID: - SET_UID(uid16, server->mnt->mounted_uid); - result = put_user(uid16, (uid16_t __user *) arg); - break; - case SMB_IOC_GETMOUNTUID32: - SET_UID(uid32, server->mnt->mounted_uid); - result = put_user(uid32, (uid_t __user *) arg); - break; - - case SMB_IOC_NEWCONN: - /* arg is smb_conn_opt, or NULL if no connection was made */ - if (!arg) { - result = 0; - smb_lock_server(server); - server->state = CONN_RETRIED; - printk(KERN_ERR "Connection attempt failed! [%d]\n", - server->conn_error); - smbiod_flush(server); - smb_unlock_server(server); - break; - } - - result = -EFAULT; - if (!copy_from_user(&opt, (void __user *)arg, sizeof(opt))) - result = smb_newconn(server, &opt); - break; - default: - break; - } - unlock_kernel(); - - return result; -} diff --git a/drivers/staging/smbfs/proc.c b/drivers/staging/smbfs/proc.c deleted file mode 100644 index ba37b1fae182..000000000000 --- a/drivers/staging/smbfs/proc.c +++ /dev/null @@ -1,3502 +0,0 @@ -/* - * proc.c - * - * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke - * Copyright (C) 1997 by Volker Lendecke - * - * Please add a note about your changes to smbfs in the ChangeLog file. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "smb_fs.h" -#include "smbno.h" -#include "smb_mount.h" -#include "smb_debug.h" -#include "proto.h" -#include "request.h" - - -/* Features. Undefine if they cause problems, this should perhaps be a - config option. */ -#define SMBFS_POSIX_UNLINK 1 - -/* Allow smb_retry to be interrupted. */ -#define SMB_RETRY_INTR - -#define SMB_VWV(packet) ((packet) + SMB_HEADER_LEN) -#define SMB_CMD(packet) (*(packet+8)) -#define SMB_WCT(packet) (*(packet+SMB_HEADER_LEN - 1)) - -#define SMB_DIRINFO_SIZE 43 -#define SMB_STATUS_SIZE 21 - -#define SMB_ST_BLKSIZE (PAGE_SIZE) -#define SMB_ST_BLKSHIFT (PAGE_SHIFT) - -static struct smb_ops smb_ops_core; -static struct smb_ops smb_ops_os2; -static struct smb_ops smb_ops_win95; -static struct smb_ops smb_ops_winNT; -static struct smb_ops smb_ops_unix; -static struct smb_ops smb_ops_null; - -static void -smb_init_dirent(struct smb_sb_info *server, struct smb_fattr *fattr); -static void -smb_finish_dirent(struct smb_sb_info *server, struct smb_fattr *fattr); -static int -smb_proc_getattr_core(struct smb_sb_info *server, struct dentry *dir, - struct smb_fattr *fattr); -static int -smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry, - struct smb_fattr *fattr); -static int -smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry, - u16 attr); -static int -smb_proc_setattr_ext(struct smb_sb_info *server, - struct inode *inode, struct smb_fattr *fattr); -static int -smb_proc_query_cifsunix(struct smb_sb_info *server); -static void -install_ops(struct smb_ops *dst, struct smb_ops *src); - - -static void -str_upper(char *name, int len) -{ - while (len--) - { - if (*name >= 'a' && *name <= 'z') - *name -= ('a' - 'A'); - name++; - } -} - -#if 0 -static void -str_lower(char *name, int len) -{ - while (len--) - { - if (*name >= 'A' && *name <= 'Z') - *name += ('a' - 'A'); - name++; - } -} -#endif - -/* reverse a string inline. This is used by the dircache walking routines */ -static void reverse_string(char *buf, int len) -{ - char c; - char *end = buf+len-1; - - while(buf < end) { - c = *buf; - *(buf++) = *end; - *(end--) = c; - } -} - -/* no conversion, just a wrapper for memcpy. */ -static int convert_memcpy(unsigned char *output, int olen, - const unsigned char *input, int ilen, - struct nls_table *nls_from, - struct nls_table *nls_to) -{ - if (olen < ilen) - return -ENAMETOOLONG; - memcpy(output, input, ilen); - return ilen; -} - -static inline int write_char(unsigned char ch, char *output, int olen) -{ - if (olen < 4) - return -ENAMETOOLONG; - sprintf(output, ":x%02x", ch); - return 4; -} - -static inline int write_unichar(wchar_t ch, char *output, int olen) -{ - if (olen < 5) - return -ENAMETOOLONG; - sprintf(output, ":%04x", ch); - return 5; -} - -/* convert from one "codepage" to another (possibly being utf8). */ -static int convert_cp(unsigned char *output, int olen, - const unsigned char *input, int ilen, - struct nls_table *nls_from, - struct nls_table *nls_to) -{ - int len = 0; - int n; - wchar_t ch; - - while (ilen > 0) { - /* convert by changing to unicode and back to the new cp */ - n = nls_from->char2uni(input, ilen, &ch); - if (n == -EINVAL) { - ilen--; - n = write_char(*input++, output, olen); - if (n < 0) - goto fail; - output += n; - olen -= n; - len += n; - continue; - } else if (n < 0) - goto fail; - input += n; - ilen -= n; - - n = nls_to->uni2char(ch, output, olen); - if (n == -EINVAL) - n = write_unichar(ch, output, olen); - if (n < 0) - goto fail; - output += n; - olen -= n; - - len += n; - } - return len; -fail: - return n; -} - -/* ----------------------------------------------------------- */ - -/* - * nls_unicode - * - * This encodes/decodes little endian unicode format - */ - -static int uni2char(wchar_t uni, unsigned char *out, int boundlen) -{ - if (boundlen < 2) - return -EINVAL; - *out++ = uni & 0xff; - *out++ = uni >> 8; - return 2; -} - -static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni) -{ - if (boundlen < 2) - return -EINVAL; - *uni = (rawstring[1] << 8) | rawstring[0]; - return 2; -} - -static struct nls_table unicode_table = { - .charset = "unicode", - .uni2char = uni2char, - .char2uni = char2uni, -}; - -/* ----------------------------------------------------------- */ - -static int setcodepage(struct nls_table **p, char *name) -{ - struct nls_table *nls; - - if (!name || !*name) { - nls = NULL; - } else if ( (nls = load_nls(name)) == NULL) { - printk (KERN_ERR "smbfs: failed to load nls '%s'\n", name); - return -EINVAL; - } - - /* if already set, unload the previous one. */ - if (*p && *p != &unicode_table) - unload_nls(*p); - *p = nls; - - return 0; -} - -/* Handles all changes to codepage settings. */ -int smb_setcodepage(struct smb_sb_info *server, struct smb_nls_codepage *cp) -{ - int n = 0; - - smb_lock_server(server); - - /* Don't load any nls_* at all, if no remote is requested */ - if (!*cp->remote_name) - goto out; - - /* local */ - n = setcodepage(&server->local_nls, cp->local_name); - if (n != 0) - goto out; - - /* remote */ - if (!strcmp(cp->remote_name, "unicode")) { - server->remote_nls = &unicode_table; - } else { - n = setcodepage(&server->remote_nls, cp->remote_name); - if (n != 0) - setcodepage(&server->local_nls, NULL); - } - -out: - if (server->local_nls != NULL && server->remote_nls != NULL) - server->ops->convert = convert_cp; - else - server->ops->convert = convert_memcpy; - - smb_unlock_server(server); - return n; -} - - -/*****************************************************************************/ -/* */ -/* Encoding/Decoding section */ -/* */ -/*****************************************************************************/ - -static __u8 * -smb_encode_smb_length(__u8 * p, __u32 len) -{ - *p = 0; - *(p+1) = 0; - *(p+2) = (len & 0xFF00) >> 8; - *(p+3) = (len & 0xFF); - if (len > 0xFFFF) - { - *(p+1) = 1; - } - return p + 4; -} - -/* - * smb_build_path: build the path to entry and name storing it in buf. - * The path returned will have the trailing '\0'. - */ -static int smb_build_path(struct smb_sb_info *server, unsigned char *buf, - int maxlen, - struct dentry *entry, struct qstr *name) -{ - unsigned char *path = buf; - int len; - int unicode = (server->mnt->flags & SMB_MOUNT_UNICODE) != 0; - - if (maxlen < (2< SMB_MAXPATHLEN + 1) - maxlen = SMB_MAXPATHLEN + 1; - - if (entry == NULL) - goto test_name_and_out; - - /* - * If IS_ROOT, we have to do no walking at all. - */ - if (IS_ROOT(entry) && !name) { - *path++ = '\\'; - if (unicode) *path++ = '\0'; - *path++ = '\0'; - if (unicode) *path++ = '\0'; - return path-buf; - } - - /* - * Build the path string walking the tree backward from end to ROOT - * and store it in reversed order [see reverse_string()] - */ - dget(entry); - while (!IS_ROOT(entry)) { - struct dentry *parent; - - if (maxlen < (3<d_lock); - len = server->ops->convert(path, maxlen-2, - entry->d_name.name, entry->d_name.len, - server->local_nls, server->remote_nls); - if (len < 0) { - spin_unlock(&entry->d_lock); - dput(entry); - return len; - } - reverse_string(path, len); - path += len; - if (unicode) { - /* Note: reverse order */ - *path++ = '\0'; - maxlen--; - } - *path++ = '\\'; - maxlen -= len+1; - spin_unlock(&entry->d_lock); - - parent = dget_parent(entry); - dput(entry); - entry = parent; - } - dput(entry); - reverse_string(buf, path-buf); - - /* maxlen has space for at least one char */ -test_name_and_out: - if (name) { - if (maxlen < (3<ops->convert(path, maxlen-2, - name->name, name->len, - server->local_nls, server->remote_nls); - if (len < 0) - return len; - path += len; - maxlen -= len+1; - } - /* maxlen has space for at least one char */ - *path++ = '\0'; - if (unicode) *path++ = '\0'; - return path-buf; -} - -static int smb_encode_path(struct smb_sb_info *server, char *buf, int maxlen, - struct dentry *dir, struct qstr *name) -{ - int result; - - result = smb_build_path(server, buf, maxlen, dir, name); - if (result < 0) - goto out; - if (server->opt.protocol <= SMB_PROTOCOL_COREPLUS) - str_upper(buf, result); -out: - return result; -} - -/* encode_path for non-trans2 request SMBs */ -static int smb_simple_encode_path(struct smb_request *req, char **p, - struct dentry * entry, struct qstr * name) -{ - struct smb_sb_info *server = req->rq_server; - char *s = *p; - int res; - int maxlen = ((char *)req->rq_buffer + req->rq_bufsize) - s; - int unicode = (server->mnt->flags & SMB_MOUNT_UNICODE); - - if (!maxlen) - return -ENAMETOOLONG; - *s++ = 4; /* ASCII data format */ - - /* - * SMB Unicode strings must be 16bit aligned relative the start of the - * packet. If they are not they must be padded with 0. - */ - if (unicode) { - int align = s - (char *)req->rq_buffer; - if (!(align & 1)) { - *s++ = '\0'; - maxlen--; - } - } - - res = smb_encode_path(server, s, maxlen-1, entry, name); - if (res < 0) - return res; - *p = s + res; - return 0; -} - -/* The following are taken directly from msdos-fs */ - -/* Linear day numbers of the respective 1sts in non-leap years. */ - -static int day_n[] = -{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0}; - /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */ - - -static time_t -utc2local(struct smb_sb_info *server, time_t time) -{ - return time - server->opt.serverzone*60; -} - -static time_t -local2utc(struct smb_sb_info *server, time_t time) -{ - return time + server->opt.serverzone*60; -} - -/* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */ - -static time_t -date_dos2unix(struct smb_sb_info *server, __u16 date, __u16 time) -{ - int month, year; - time_t secs; - - /* first subtract and mask after that... Otherwise, if - date == 0, bad things happen */ - month = ((date >> 5) - 1) & 15; - year = date >> 9; - secs = (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 + 86400 * - ((date & 31) - 1 + day_n[month] + (year / 4) + year * 365 - ((year & 3) == 0 && - month < 2 ? 1 : 0) + 3653); - /* days since 1.1.70 plus 80's leap day */ - return local2utc(server, secs); -} - - -/* Convert linear UNIX date to a MS-DOS time/date pair. */ - -static void -date_unix2dos(struct smb_sb_info *server, - int unix_date, __u16 *date, __u16 *time) -{ - int day, year, nl_day, month; - - unix_date = utc2local(server, unix_date); - if (unix_date < 315532800) - unix_date = 315532800; - - *time = (unix_date % 60) / 2 + - (((unix_date / 60) % 60) << 5) + - (((unix_date / 3600) % 24) << 11); - - day = unix_date / 86400 - 3652; - year = day / 365; - if ((year + 3) / 4 + 365 * year > day) - year--; - day -= (year + 3) / 4 + 365 * year; - if (day == 59 && !(year & 3)) { - nl_day = day; - month = 2; - } else { - nl_day = (year & 3) || day <= 59 ? day : day - 1; - for (month = 1; month < 12; month++) - if (day_n[month] > nl_day) - break; - } - *date = nl_day - day_n[month - 1] + 1 + (month << 5) + (year << 9); -} - -/* The following are taken from fs/ntfs/util.c */ - -#define NTFS_TIME_OFFSET ((u64)(369*365 + 89) * 24 * 3600 * 10000000) - -/* - * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units) - * into Unix UTC (based 1970-01-01, in seconds). - */ -static struct timespec -smb_ntutc2unixutc(u64 ntutc) -{ - struct timespec ts; - /* FIXME: what about the timezone difference? */ - /* Subtract the NTFS time offset, then convert to 1s intervals. */ - u64 t = ntutc - NTFS_TIME_OFFSET; - ts.tv_nsec = do_div(t, 10000000) * 100; - ts.tv_sec = t; - return ts; -} - -/* Convert the Unix UTC into NT time */ -static u64 -smb_unixutc2ntutc(struct timespec ts) -{ - /* Note: timezone conversion is probably wrong. */ - /* return ((u64)utc2local(server, t)) * 10000000 + NTFS_TIME_OFFSET; */ - return ((u64)ts.tv_sec) * 10000000 + ts.tv_nsec/100 + NTFS_TIME_OFFSET; -} - -#define MAX_FILE_MODE 6 -static mode_t file_mode[] = { - S_IFREG, S_IFDIR, S_IFLNK, S_IFCHR, S_IFBLK, S_IFIFO, S_IFSOCK -}; - -static int smb_filetype_to_mode(u32 filetype) -{ - if (filetype > MAX_FILE_MODE) { - PARANOIA("Filetype out of range: %d\n", filetype); - return S_IFREG; - } - return file_mode[filetype]; -} - -static u32 smb_filetype_from_mode(int mode) -{ - if (S_ISREG(mode)) - return UNIX_TYPE_FILE; - if (S_ISDIR(mode)) - return UNIX_TYPE_DIR; - if (S_ISLNK(mode)) - return UNIX_TYPE_SYMLINK; - if (S_ISCHR(mode)) - return UNIX_TYPE_CHARDEV; - if (S_ISBLK(mode)) - return UNIX_TYPE_BLKDEV; - if (S_ISFIFO(mode)) - return UNIX_TYPE_FIFO; - if (S_ISSOCK(mode)) - return UNIX_TYPE_SOCKET; - return UNIX_TYPE_UNKNOWN; -} - - -/*****************************************************************************/ -/* */ -/* Support section. */ -/* */ -/*****************************************************************************/ - -__u32 -smb_len(__u8 * p) -{ - return ((*(p+1) & 0x1) << 16L) | (*(p+2) << 8L) | *(p+3); -} - -static __u16 -smb_bcc(__u8 * packet) -{ - int pos = SMB_HEADER_LEN + SMB_WCT(packet) * sizeof(__u16); - return WVAL(packet, pos); -} - -/* smb_valid_packet: We check if packet fulfills the basic - requirements of a smb packet */ - -static int -smb_valid_packet(__u8 * packet) -{ - return (packet[4] == 0xff - && packet[5] == 'S' - && packet[6] == 'M' - && packet[7] == 'B' - && (smb_len(packet) + 4 == SMB_HEADER_LEN - + SMB_WCT(packet) * 2 + smb_bcc(packet))); -} - -/* smb_verify: We check if we got the answer we expected, and if we - got enough data. If bcc == -1, we don't care. */ - -static int -smb_verify(__u8 * packet, int command, int wct, int bcc) -{ - if (SMB_CMD(packet) != command) - goto bad_command; - if (SMB_WCT(packet) < wct) - goto bad_wct; - if (bcc != -1 && smb_bcc(packet) < bcc) - goto bad_bcc; - return 0; - -bad_command: - printk(KERN_ERR "smb_verify: command=%x, SMB_CMD=%x??\n", - command, SMB_CMD(packet)); - goto fail; -bad_wct: - printk(KERN_ERR "smb_verify: command=%x, wct=%d, SMB_WCT=%d??\n", - command, wct, SMB_WCT(packet)); - goto fail; -bad_bcc: - printk(KERN_ERR "smb_verify: command=%x, bcc=%d, SMB_BCC=%d??\n", - command, bcc, smb_bcc(packet)); -fail: - return -EIO; -} - -/* - * Returns the maximum read or write size for the "payload". Making all of the - * packet fit within the negotiated max_xmit size. - * - * N.B. Since this value is usually computed before locking the server, - * the server's packet size must never be decreased! - */ -static inline int -smb_get_xmitsize(struct smb_sb_info *server, int overhead) -{ - return server->opt.max_xmit - overhead; -} - -/* - * Calculate the maximum read size - */ -int -smb_get_rsize(struct smb_sb_info *server) -{ - /* readX has 12 parameters, read has 5 */ - int overhead = SMB_HEADER_LEN + 12 * sizeof(__u16) + 2 + 1 + 2; - int size = smb_get_xmitsize(server, overhead); - - VERBOSE("xmit=%d, size=%d\n", server->opt.max_xmit, size); - - return size; -} - -/* - * Calculate the maximum write size - */ -int -smb_get_wsize(struct smb_sb_info *server) -{ - /* writeX has 14 parameters, write has 5 */ - int overhead = SMB_HEADER_LEN + 14 * sizeof(__u16) + 2 + 1 + 2; - int size = smb_get_xmitsize(server, overhead); - - VERBOSE("xmit=%d, size=%d\n", server->opt.max_xmit, size); - - return size; -} - -/* - * Convert SMB error codes to -E... errno values. - */ -int -smb_errno(struct smb_request *req) -{ - int errcls = req->rq_rcls; - int error = req->rq_err; - char *class = "Unknown"; - - VERBOSE("errcls %d code %d from command 0x%x\n", - errcls, error, SMB_CMD(req->rq_header)); - - if (errcls == ERRDOS) { - switch (error) { - case ERRbadfunc: - return -EINVAL; - case ERRbadfile: - case ERRbadpath: - return -ENOENT; - case ERRnofids: - return -EMFILE; - case ERRnoaccess: - return -EACCES; - case ERRbadfid: - return -EBADF; - case ERRbadmcb: - return -EREMOTEIO; - case ERRnomem: - return -ENOMEM; - case ERRbadmem: - return -EFAULT; - case ERRbadenv: - case ERRbadformat: - return -EREMOTEIO; - case ERRbadaccess: - return -EACCES; - case ERRbaddata: - return -E2BIG; - case ERRbaddrive: - return -ENXIO; - case ERRremcd: - return -EREMOTEIO; - case ERRdiffdevice: - return -EXDEV; - case ERRnofiles: - return -ENOENT; - case ERRbadshare: - return -ETXTBSY; - case ERRlock: - return -EDEADLK; - case ERRfilexists: - return -EEXIST; - case ERROR_INVALID_PARAMETER: - return -EINVAL; - case ERROR_DISK_FULL: - return -ENOSPC; - case ERROR_INVALID_NAME: - return -ENOENT; - case ERROR_DIR_NOT_EMPTY: - return -ENOTEMPTY; - case ERROR_NOT_LOCKED: - return -ENOLCK; - case ERROR_ALREADY_EXISTS: - return -EEXIST; - default: - class = "ERRDOS"; - goto err_unknown; - } - } else if (errcls == ERRSRV) { - switch (error) { - /* N.B. This is wrong ... EIO ? */ - case ERRerror: - return -ENFILE; - case ERRbadpw: - return -EINVAL; - case ERRbadtype: - case ERRtimeout: - return -EIO; - case ERRaccess: - return -EACCES; - /* - * This is a fatal error, as it means the "tree ID" - * for this connection is no longer valid. We map - * to a special error code and get a new connection. - */ - case ERRinvnid: - return -EBADSLT; - default: - class = "ERRSRV"; - goto err_unknown; - } - } else if (errcls == ERRHRD) { - switch (error) { - case ERRnowrite: - return -EROFS; - case ERRbadunit: - return -ENODEV; - case ERRnotready: - return -EUCLEAN; - case ERRbadcmd: - case ERRdata: - return -EIO; - case ERRbadreq: - return -ERANGE; - case ERRbadshare: - return -ETXTBSY; - case ERRlock: - return -EDEADLK; - case ERRdiskfull: - return -ENOSPC; - default: - class = "ERRHRD"; - goto err_unknown; - } - } else if (errcls == ERRCMD) { - class = "ERRCMD"; - } else if (errcls == SUCCESS) { - return 0; /* This is the only valid 0 return */ - } - -err_unknown: - printk(KERN_ERR "smb_errno: class %s, code %d from command 0x%x\n", - class, error, SMB_CMD(req->rq_header)); - return -EIO; -} - -/* smb_request_ok: We expect the server to be locked. Then we do the - request and check the answer completely. When smb_request_ok - returns 0, you can be quite sure that everything went well. When - the answer is <=0, the returned number is a valid unix errno. */ - -static int -smb_request_ok(struct smb_request *req, int command, int wct, int bcc) -{ - int result; - - req->rq_resp_wct = wct; - req->rq_resp_bcc = bcc; - - result = smb_add_request(req); - if (result != 0) { - DEBUG1("smb_request failed\n"); - goto out; - } - - if (smb_valid_packet(req->rq_header) != 0) { - PARANOIA("invalid packet!\n"); - goto out; - } - - result = smb_verify(req->rq_header, command, wct, bcc); - -out: - return result; -} - -/* - * This implements the NEWCONN ioctl. It installs the server pid, - * sets server->state to CONN_VALID, and wakes up the waiting process. - */ -int -smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt) -{ - struct file *filp; - struct sock *sk; - int error; - - VERBOSE("fd=%d, pid=%d\n", opt->fd, current->pid); - - smb_lock_server(server); - - /* - * Make sure we don't already have a valid connection ... - */ - error = -EINVAL; - if (server->state == CONN_VALID) - goto out; - - error = -EACCES; - if (current_uid() != server->mnt->mounted_uid && - !capable(CAP_SYS_ADMIN)) - goto out; - - error = -EBADF; - filp = fget(opt->fd); - if (!filp) - goto out; - if (!smb_valid_socket(filp->f_path.dentry->d_inode)) - goto out_putf; - - server->sock_file = filp; - server->conn_pid = get_pid(task_pid(current)); - server->opt = *opt; - server->generation += 1; - server->state = CONN_VALID; - error = 0; - - if (server->conn_error) { - /* - * conn_error is the returncode we originally decided to - * drop the old connection on. This message should be positive - * and not make people ask questions on why smbfs is printing - * error messages ... - */ - printk(KERN_INFO "SMB connection re-established (%d)\n", - server->conn_error); - server->conn_error = 0; - } - - /* - * Store the server in sock user_data (Only used by sunrpc) - */ - sk = SOCKET_I(filp->f_path.dentry->d_inode)->sk; - sk->sk_user_data = server; - - /* chain into the data_ready callback */ - server->data_ready = xchg(&sk->sk_data_ready, smb_data_ready); - - /* check if we have an old smbmount that uses seconds for the - serverzone */ - if (server->opt.serverzone > 12*60 || server->opt.serverzone < -12*60) - server->opt.serverzone /= 60; - - /* now that we have an established connection we can detect the server - type and enable bug workarounds */ - if (server->opt.protocol < SMB_PROTOCOL_LANMAN2) - install_ops(server->ops, &smb_ops_core); - else if (server->opt.protocol == SMB_PROTOCOL_LANMAN2) - install_ops(server->ops, &smb_ops_os2); - else if (server->opt.protocol == SMB_PROTOCOL_NT1 && - (server->opt.max_xmit < 0x1000) && - !(server->opt.capabilities & SMB_CAP_NT_SMBS)) { - /* FIXME: can we kill the WIN95 flag now? */ - server->mnt->flags |= SMB_MOUNT_WIN95; - VERBOSE("detected WIN95 server\n"); - install_ops(server->ops, &smb_ops_win95); - } else { - /* - * Samba has max_xmit 65535 - * NT4spX has max_xmit 4536 (or something like that) - * win2k has ... - */ - VERBOSE("detected NT1 (Samba, NT4/5) server\n"); - install_ops(server->ops, &smb_ops_winNT); - } - - /* FIXME: the win9x code wants to modify these ... (seek/trunc bug) */ - if (server->mnt->flags & SMB_MOUNT_OLDATTR) { - server->ops->getattr = smb_proc_getattr_core; - } else if (server->mnt->flags & SMB_MOUNT_DIRATTR) { - server->ops->getattr = smb_proc_getattr_ff; - } - - /* Decode server capabilities */ - if (server->opt.capabilities & SMB_CAP_LARGE_FILES) { - /* Should be ok to set this now, as no one can access the - mount until the connection has been established. */ - SB_of(server)->s_maxbytes = ~0ULL >> 1; - VERBOSE("LFS enabled\n"); - } - if (server->opt.capabilities & SMB_CAP_UNICODE) { - server->mnt->flags |= SMB_MOUNT_UNICODE; - VERBOSE("Unicode enabled\n"); - } else { - server->mnt->flags &= ~SMB_MOUNT_UNICODE; - } -#if 0 - /* flags we may test for other patches ... */ - if (server->opt.capabilities & SMB_CAP_LARGE_READX) { - VERBOSE("Large reads enabled\n"); - } - if (server->opt.capabilities & SMB_CAP_LARGE_WRITEX) { - VERBOSE("Large writes enabled\n"); - } -#endif - if (server->opt.capabilities & SMB_CAP_UNIX) { - struct inode *inode; - VERBOSE("Using UNIX CIFS extensions\n"); - install_ops(server->ops, &smb_ops_unix); - inode = SB_of(server)->s_root->d_inode; - if (inode) - inode->i_op = &smb_dir_inode_operations_unix; - } - - VERBOSE("protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n", - server->opt.protocol, server->opt.max_xmit, - pid_nr(server->conn_pid), server->opt.capabilities); - - /* FIXME: this really should be done by smbmount. */ - if (server->opt.max_xmit > SMB_MAX_PACKET_SIZE) { - server->opt.max_xmit = SMB_MAX_PACKET_SIZE; - } - - smb_unlock_server(server); - smbiod_wake_up(); - if (server->opt.capabilities & SMB_CAP_UNIX) - smb_proc_query_cifsunix(server); - - server->conn_complete++; - wake_up_interruptible_all(&server->conn_wq); - return error; - -out: - smb_unlock_server(server); - smbiod_wake_up(); - return error; - -out_putf: - fput(filp); - goto out; -} - -/* smb_setup_header: We completely set up the packet. You only have to - insert the command-specific fields */ - -__u8 * -smb_setup_header(struct smb_request *req, __u8 command, __u16 wct, __u16 bcc) -{ - __u32 xmit_len = SMB_HEADER_LEN + wct * sizeof(__u16) + bcc + 2; - __u8 *p = req->rq_header; - struct smb_sb_info *server = req->rq_server; - - p = smb_encode_smb_length(p, xmit_len - 4); - - *p++ = 0xff; - *p++ = 'S'; - *p++ = 'M'; - *p++ = 'B'; - *p++ = command; - - memset(p, '\0', 19); - p += 19; - p += 8; - - if (server->opt.protocol > SMB_PROTOCOL_CORE) { - int flags = SMB_FLAGS_CASELESS_PATHNAMES; - int flags2 = SMB_FLAGS2_LONG_PATH_COMPONENTS | - SMB_FLAGS2_EXTENDED_ATTRIBUTES; /* EA? not really ... */ - - *(req->rq_header + smb_flg) = flags; - if (server->mnt->flags & SMB_MOUNT_UNICODE) - flags2 |= SMB_FLAGS2_UNICODE_STRINGS; - WSET(req->rq_header, smb_flg2, flags2); - } - *p++ = wct; /* wct */ - p += 2 * wct; - WSET(p, 0, bcc); - - /* Include the header in the data to send */ - req->rq_iovlen = 1; - req->rq_iov[0].iov_base = req->rq_header; - req->rq_iov[0].iov_len = xmit_len - bcc; - - return req->rq_buffer; -} - -static void -smb_setup_bcc(struct smb_request *req, __u8 *p) -{ - u16 bcc = p - req->rq_buffer; - u8 *pbcc = req->rq_header + SMB_HEADER_LEN + 2*SMB_WCT(req->rq_header); - - WSET(pbcc, 0, bcc); - - smb_encode_smb_length(req->rq_header, SMB_HEADER_LEN + - 2*SMB_WCT(req->rq_header) - 2 + bcc); - - /* Include the "bytes" in the data to send */ - req->rq_iovlen = 2; - req->rq_iov[1].iov_base = req->rq_buffer; - req->rq_iov[1].iov_len = bcc; -} - -static int -smb_proc_seek(struct smb_sb_info *server, __u16 fileid, - __u16 mode, off_t offset) -{ - int result; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, 0))) - goto out; - - smb_setup_header(req, SMBlseek, 4, 0); - WSET(req->rq_header, smb_vwv0, fileid); - WSET(req->rq_header, smb_vwv1, mode); - DSET(req->rq_header, smb_vwv2, offset); - req->rq_flags |= SMB_REQ_NORETRY; - - result = smb_request_ok(req, SMBlseek, 2, 0); - if (result < 0) { - result = 0; - goto out_free; - } - - result = DVAL(req->rq_header, smb_vwv0); -out_free: - smb_rput(req); -out: - return result; -} - -static int -smb_proc_open(struct smb_sb_info *server, struct dentry *dentry, int wish) -{ - struct inode *ino = dentry->d_inode; - struct smb_inode_info *ei = SMB_I(ino); - int mode, read_write = 0x42, read_only = 0x40; - int res; - char *p; - struct smb_request *req; - - /* - * Attempt to open r/w, unless there are no write privileges. - */ - mode = read_write; - if (!(ino->i_mode & (S_IWUSR | S_IWGRP | S_IWOTH))) - mode = read_only; -#if 0 - /* FIXME: why is this code not in? below we fix it so that a caller - wanting RO doesn't get RW. smb_revalidate_inode does some - optimization based on access mode. tail -f needs it to be correct. - - We must open rw since we don't do the open if called a second time - with different 'wish'. Is that not supported by smb servers? */ - if (!(wish & (O_WRONLY | O_RDWR))) - mode = read_only; -#endif - - res = -ENOMEM; - if (! (req = smb_alloc_request(server, PAGE_SIZE))) - goto out; - - retry: - p = smb_setup_header(req, SMBopen, 2, 0); - WSET(req->rq_header, smb_vwv0, mode); - WSET(req->rq_header, smb_vwv1, aSYSTEM | aHIDDEN | aDIR); - res = smb_simple_encode_path(req, &p, dentry, NULL); - if (res < 0) - goto out_free; - smb_setup_bcc(req, p); - - res = smb_request_ok(req, SMBopen, 7, 0); - if (res != 0) { - if (mode == read_write && - (res == -EACCES || res == -ETXTBSY || res == -EROFS)) - { - VERBOSE("%s/%s R/W failed, error=%d, retrying R/O\n", - DENTRY_PATH(dentry), res); - mode = read_only; - req->rq_flags = 0; - goto retry; - } - goto out_free; - } - /* We should now have data in vwv[0..6]. */ - - ei->fileid = WVAL(req->rq_header, smb_vwv0); - ei->attr = WVAL(req->rq_header, smb_vwv1); - /* smb_vwv2 has mtime */ - /* smb_vwv4 has size */ - ei->access = (WVAL(req->rq_header, smb_vwv6) & SMB_ACCMASK); - ei->open = server->generation; - -out_free: - smb_rput(req); -out: - return res; -} - -/* - * Make sure the file is open, and check that the access - * is compatible with the desired access. - */ -int -smb_open(struct dentry *dentry, int wish) -{ - struct inode *inode = dentry->d_inode; - int result; - __u16 access; - - result = -ENOENT; - if (!inode) { - printk(KERN_ERR "smb_open: no inode for dentry %s/%s\n", - DENTRY_PATH(dentry)); - goto out; - } - - if (!smb_is_open(inode)) { - struct smb_sb_info *server = server_from_inode(inode); - result = 0; - if (!smb_is_open(inode)) - result = smb_proc_open(server, dentry, wish); - if (result) - goto out; - /* - * A successful open means the path is still valid ... - */ - smb_renew_times(dentry); - } - - /* - * Check whether the access is compatible with the desired mode. - */ - result = 0; - access = SMB_I(inode)->access; - if (access != wish && access != SMB_O_RDWR) { - PARANOIA("%s/%s access denied, access=%x, wish=%x\n", - DENTRY_PATH(dentry), access, wish); - result = -EACCES; - } -out: - return result; -} - -static int -smb_proc_close(struct smb_sb_info *server, __u16 fileid, __u32 mtime) -{ - struct smb_request *req; - int result = -ENOMEM; - - if (! (req = smb_alloc_request(server, 0))) - goto out; - - smb_setup_header(req, SMBclose, 3, 0); - WSET(req->rq_header, smb_vwv0, fileid); - DSET(req->rq_header, smb_vwv1, utc2local(server, mtime)); - req->rq_flags |= SMB_REQ_NORETRY; - result = smb_request_ok(req, SMBclose, 0, 0); - - smb_rput(req); -out: - return result; -} - -/* - * Win NT 4.0 has an apparent bug in that it fails to update the - * modify time when writing to a file. As a workaround, we update - * both modify and access time locally, and post the times to the - * server when closing the file. - */ -static int -smb_proc_close_inode(struct smb_sb_info *server, struct inode * ino) -{ - struct smb_inode_info *ei = SMB_I(ino); - int result = 0; - if (smb_is_open(ino)) - { - /* - * We clear the open flag in advance, in case another - * process observes the value while we block below. - */ - ei->open = 0; - - /* - * Kludge alert: SMB timestamps are accurate only to - * two seconds ... round the times to avoid needless - * cache invalidations! - */ - if (ino->i_mtime.tv_sec & 1) { - ino->i_mtime.tv_sec--; - ino->i_mtime.tv_nsec = 0; - } - if (ino->i_atime.tv_sec & 1) { - ino->i_atime.tv_sec--; - ino->i_atime.tv_nsec = 0; - } - /* - * If the file is open with write permissions, - * update the time stamps to sync mtime and atime. - */ - if ((server->opt.capabilities & SMB_CAP_UNIX) == 0 && - (server->opt.protocol >= SMB_PROTOCOL_LANMAN2) && - !(ei->access == SMB_O_RDONLY)) - { - struct smb_fattr fattr; - smb_get_inode_attr(ino, &fattr); - smb_proc_setattr_ext(server, ino, &fattr); - } - - result = smb_proc_close(server, ei->fileid, ino->i_mtime.tv_sec); - /* - * Force a revalidation after closing ... some servers - * don't post the size until the file has been closed. - */ - if (server->opt.protocol < SMB_PROTOCOL_NT1) - ei->oldmtime = 0; - ei->closed = jiffies; - } - return result; -} - -int -smb_close(struct inode *ino) -{ - int result = 0; - - if (smb_is_open(ino)) { - struct smb_sb_info *server = server_from_inode(ino); - result = smb_proc_close_inode(server, ino); - } - return result; -} - -/* - * This is used to close a file following a failed instantiate. - * Since we don't have an inode, we can't use any of the above. - */ -int -smb_close_fileid(struct dentry *dentry, __u16 fileid) -{ - struct smb_sb_info *server = server_from_dentry(dentry); - int result; - - result = smb_proc_close(server, fileid, get_seconds()); - return result; -} - -/* In smb_proc_read and smb_proc_write we do not retry, because the - file-id would not be valid after a reconnection. */ - -static void -smb_proc_read_data(struct smb_request *req) -{ - req->rq_iov[0].iov_base = req->rq_buffer; - req->rq_iov[0].iov_len = 3; - - req->rq_iov[1].iov_base = req->rq_page; - req->rq_iov[1].iov_len = req->rq_rsize; - req->rq_iovlen = 2; - - req->rq_rlen = smb_len(req->rq_header) + 4 - req->rq_bytes_recvd; -} - -static int -smb_proc_read(struct inode *inode, loff_t offset, int count, char *data) -{ - struct smb_sb_info *server = server_from_inode(inode); - __u16 returned_count, data_len; - unsigned char *buf; - int result; - struct smb_request *req; - u8 rbuf[4]; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, 0))) - goto out; - - smb_setup_header(req, SMBread, 5, 0); - buf = req->rq_header; - WSET(buf, smb_vwv0, SMB_I(inode)->fileid); - WSET(buf, smb_vwv1, count); - DSET(buf, smb_vwv2, offset); - WSET(buf, smb_vwv4, 0); - - req->rq_page = data; - req->rq_rsize = count; - req->rq_callback = smb_proc_read_data; - req->rq_buffer = rbuf; - req->rq_flags |= SMB_REQ_NORETRY | SMB_REQ_STATIC; - - result = smb_request_ok(req, SMBread, 5, -1); - if (result < 0) - goto out_free; - returned_count = WVAL(req->rq_header, smb_vwv0); - - data_len = WVAL(rbuf, 1); - - if (returned_count != data_len) { - printk(KERN_NOTICE "smb_proc_read: returned != data_len\n"); - printk(KERN_NOTICE "smb_proc_read: ret_c=%d, data_len=%d\n", - returned_count, data_len); - } - result = data_len; - -out_free: - smb_rput(req); -out: - VERBOSE("ino=%ld, fileid=%d, count=%d, result=%d\n", - inode->i_ino, SMB_I(inode)->fileid, count, result); - return result; -} - -static int -smb_proc_write(struct inode *inode, loff_t offset, int count, const char *data) -{ - struct smb_sb_info *server = server_from_inode(inode); - int result; - u16 fileid = SMB_I(inode)->fileid; - u8 buf[4]; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, 0))) - goto out; - - VERBOSE("ino=%ld, fileid=%d, count=%d@%Ld\n", - inode->i_ino, fileid, count, offset); - - smb_setup_header(req, SMBwrite, 5, count + 3); - WSET(req->rq_header, smb_vwv0, fileid); - WSET(req->rq_header, smb_vwv1, count); - DSET(req->rq_header, smb_vwv2, offset); - WSET(req->rq_header, smb_vwv4, 0); - - buf[0] = 1; - WSET(buf, 1, count); /* yes, again ... */ - req->rq_iov[1].iov_base = buf; - req->rq_iov[1].iov_len = 3; - req->rq_iov[2].iov_base = (char *) data; - req->rq_iov[2].iov_len = count; - req->rq_iovlen = 3; - req->rq_flags |= SMB_REQ_NORETRY; - - result = smb_request_ok(req, SMBwrite, 1, 0); - if (result >= 0) - result = WVAL(req->rq_header, smb_vwv0); - - smb_rput(req); -out: - return result; -} - -/* - * In smb_proc_readX and smb_proc_writeX we do not retry, because the - * file-id would not be valid after a reconnection. - */ - -#define SMB_READX_MAX_PAD 64 -static void -smb_proc_readX_data(struct smb_request *req) -{ - /* header length, excluding the netbios length (-4) */ - int hdrlen = SMB_HEADER_LEN + req->rq_resp_wct*2 - 2; - int data_off = WVAL(req->rq_header, smb_vwv6); - - /* - * Some genius made the padding to the data bytes arbitrary. - * So we must first calculate the amount of padding used by the server. - */ - data_off -= hdrlen; - if (data_off > SMB_READX_MAX_PAD || data_off < 0) { - PARANOIA("offset is larger than SMB_READX_MAX_PAD or negative!\n"); - PARANOIA("%d > %d || %d < 0\n", data_off, SMB_READX_MAX_PAD, data_off); - req->rq_rlen = req->rq_bufsize + 1; - return; - } - req->rq_iov[0].iov_base = req->rq_buffer; - req->rq_iov[0].iov_len = data_off; - - req->rq_iov[1].iov_base = req->rq_page; - req->rq_iov[1].iov_len = req->rq_rsize; - req->rq_iovlen = 2; - - req->rq_rlen = smb_len(req->rq_header) + 4 - req->rq_bytes_recvd; -} - -static int -smb_proc_readX(struct inode *inode, loff_t offset, int count, char *data) -{ - struct smb_sb_info *server = server_from_inode(inode); - unsigned char *buf; - int result; - struct smb_request *req; - static char pad[SMB_READX_MAX_PAD]; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, 0))) - goto out; - - smb_setup_header(req, SMBreadX, 12, 0); - buf = req->rq_header; - WSET(buf, smb_vwv0, 0x00ff); - WSET(buf, smb_vwv1, 0); - WSET(buf, smb_vwv2, SMB_I(inode)->fileid); - DSET(buf, smb_vwv3, (u32)offset); /* low 32 bits */ - WSET(buf, smb_vwv5, count); - WSET(buf, smb_vwv6, 0); - DSET(buf, smb_vwv7, 0); - WSET(buf, smb_vwv9, 0); - DSET(buf, smb_vwv10, (u32)(offset >> 32)); /* high 32 bits */ - WSET(buf, smb_vwv11, 0); - - req->rq_page = data; - req->rq_rsize = count; - req->rq_callback = smb_proc_readX_data; - req->rq_buffer = pad; - req->rq_bufsize = SMB_READX_MAX_PAD; - req->rq_flags |= SMB_REQ_STATIC | SMB_REQ_NORETRY; - - result = smb_request_ok(req, SMBreadX, 12, -1); - if (result < 0) - goto out_free; - result = WVAL(req->rq_header, smb_vwv5); - -out_free: - smb_rput(req); -out: - VERBOSE("ino=%ld, fileid=%d, count=%d, result=%d\n", - inode->i_ino, SMB_I(inode)->fileid, count, result); - return result; -} - -static int -smb_proc_writeX(struct inode *inode, loff_t offset, int count, const char *data) -{ - struct smb_sb_info *server = server_from_inode(inode); - int result; - u8 *p; - static u8 pad[4]; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, 0))) - goto out; - - VERBOSE("ino=%ld, fileid=%d, count=%d@%Ld\n", - inode->i_ino, SMB_I(inode)->fileid, count, offset); - - p = smb_setup_header(req, SMBwriteX, 14, count + 1); - WSET(req->rq_header, smb_vwv0, 0x00ff); - WSET(req->rq_header, smb_vwv1, 0); - WSET(req->rq_header, smb_vwv2, SMB_I(inode)->fileid); - DSET(req->rq_header, smb_vwv3, (u32)offset); /* low 32 bits */ - DSET(req->rq_header, smb_vwv5, 0); - WSET(req->rq_header, smb_vwv7, 0); /* write mode */ - WSET(req->rq_header, smb_vwv8, 0); - WSET(req->rq_header, smb_vwv9, 0); - WSET(req->rq_header, smb_vwv10, count); /* data length */ - WSET(req->rq_header, smb_vwv11, smb_vwv12 + 2 + 1); - DSET(req->rq_header, smb_vwv12, (u32)(offset >> 32)); - - req->rq_iov[1].iov_base = pad; - req->rq_iov[1].iov_len = 1; - req->rq_iov[2].iov_base = (char *) data; - req->rq_iov[2].iov_len = count; - req->rq_iovlen = 3; - req->rq_flags |= SMB_REQ_NORETRY; - - result = smb_request_ok(req, SMBwriteX, 6, 0); - if (result >= 0) - result = WVAL(req->rq_header, smb_vwv2); - - smb_rput(req); -out: - return result; -} - -int -smb_proc_create(struct dentry *dentry, __u16 attr, time_t ctime, __u16 *fileid) -{ - struct smb_sb_info *server = server_from_dentry(dentry); - char *p; - int result; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, PAGE_SIZE))) - goto out; - - p = smb_setup_header(req, SMBcreate, 3, 0); - WSET(req->rq_header, smb_vwv0, attr); - DSET(req->rq_header, smb_vwv1, utc2local(server, ctime)); - result = smb_simple_encode_path(req, &p, dentry, NULL); - if (result < 0) - goto out_free; - smb_setup_bcc(req, p); - - result = smb_request_ok(req, SMBcreate, 1, 0); - if (result < 0) - goto out_free; - - *fileid = WVAL(req->rq_header, smb_vwv0); - result = 0; - -out_free: - smb_rput(req); -out: - return result; -} - -int -smb_proc_mv(struct dentry *old_dentry, struct dentry *new_dentry) -{ - struct smb_sb_info *server = server_from_dentry(old_dentry); - char *p; - int result; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, PAGE_SIZE))) - goto out; - - p = smb_setup_header(req, SMBmv, 1, 0); - WSET(req->rq_header, smb_vwv0, aSYSTEM | aHIDDEN | aDIR); - result = smb_simple_encode_path(req, &p, old_dentry, NULL); - if (result < 0) - goto out_free; - result = smb_simple_encode_path(req, &p, new_dentry, NULL); - if (result < 0) - goto out_free; - smb_setup_bcc(req, p); - - if ((result = smb_request_ok(req, SMBmv, 0, 0)) < 0) - goto out_free; - result = 0; - -out_free: - smb_rput(req); -out: - return result; -} - -/* - * Code common to mkdir and rmdir. - */ -static int -smb_proc_generic_command(struct dentry *dentry, __u8 command) -{ - struct smb_sb_info *server = server_from_dentry(dentry); - char *p; - int result; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, PAGE_SIZE))) - goto out; - - p = smb_setup_header(req, command, 0, 0); - result = smb_simple_encode_path(req, &p, dentry, NULL); - if (result < 0) - goto out_free; - smb_setup_bcc(req, p); - - result = smb_request_ok(req, command, 0, 0); - if (result < 0) - goto out_free; - result = 0; - -out_free: - smb_rput(req); -out: - return result; -} - -int -smb_proc_mkdir(struct dentry *dentry) -{ - return smb_proc_generic_command(dentry, SMBmkdir); -} - -int -smb_proc_rmdir(struct dentry *dentry) -{ - return smb_proc_generic_command(dentry, SMBrmdir); -} - -#if SMBFS_POSIX_UNLINK -/* - * Removes readonly attribute from a file. Used by unlink to give posix - * semantics. - */ -static int -smb_set_rw(struct dentry *dentry,struct smb_sb_info *server) -{ - int result; - struct smb_fattr fattr; - - /* FIXME: cifsUE should allow removing a readonly file. */ - - /* first get current attribute */ - smb_init_dirent(server, &fattr); - result = server->ops->getattr(server, dentry, &fattr); - smb_finish_dirent(server, &fattr); - if (result < 0) - return result; - - /* if RONLY attribute is set, remove it */ - if (fattr.attr & aRONLY) { /* read only attribute is set */ - fattr.attr &= ~aRONLY; - result = smb_proc_setattr_core(server, dentry, fattr.attr); - } - return result; -} -#endif - -int -smb_proc_unlink(struct dentry *dentry) -{ - struct smb_sb_info *server = server_from_dentry(dentry); - int flag = 0; - char *p; - int result; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, PAGE_SIZE))) - goto out; - - retry: - p = smb_setup_header(req, SMBunlink, 1, 0); - WSET(req->rq_header, smb_vwv0, aSYSTEM | aHIDDEN); - result = smb_simple_encode_path(req, &p, dentry, NULL); - if (result < 0) - goto out_free; - smb_setup_bcc(req, p); - - if ((result = smb_request_ok(req, SMBunlink, 0, 0)) < 0) { -#if SMBFS_POSIX_UNLINK - if (result == -EACCES && !flag) { - /* Posix semantics is for the read-only state - of a file to be ignored in unlink(). In the - SMB world a unlink() is refused on a - read-only file. To make things easier for - unix users we try to override the files - permission if the unlink fails with the - right error. - This introduces a race condition that could - lead to a file being written by someone who - shouldn't have access, but as far as I can - tell that is unavoidable */ - - /* remove RONLY attribute and try again */ - result = smb_set_rw(dentry,server); - if (result == 0) { - flag = 1; - req->rq_flags = 0; - goto retry; - } - } -#endif - goto out_free; - } - result = 0; - -out_free: - smb_rput(req); -out: - return result; -} - -int -smb_proc_flush(struct smb_sb_info *server, __u16 fileid) -{ - int result; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, 0))) - goto out; - - smb_setup_header(req, SMBflush, 1, 0); - WSET(req->rq_header, smb_vwv0, fileid); - req->rq_flags |= SMB_REQ_NORETRY; - result = smb_request_ok(req, SMBflush, 0, 0); - - smb_rput(req); -out: - return result; -} - -static int -smb_proc_trunc32(struct inode *inode, loff_t length) -{ - /* - * Writing 0bytes is old-SMB magic for truncating files. - * MAX_NON_LFS should prevent this from being called with a too - * large offset. - */ - return smb_proc_write(inode, length, 0, NULL); -} - -static int -smb_proc_trunc64(struct inode *inode, loff_t length) -{ - struct smb_sb_info *server = server_from_inode(inode); - int result; - char *param; - char *data; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, 14))) - goto out; - - param = req->rq_buffer; - data = req->rq_buffer + 6; - - /* FIXME: must we also set allocation size? winNT seems to do that */ - WSET(param, 0, SMB_I(inode)->fileid); - WSET(param, 2, SMB_SET_FILE_END_OF_FILE_INFO); - WSET(param, 4, 0); - LSET(data, 0, length); - - req->rq_trans2_command = TRANSACT2_SETFILEINFO; - req->rq_ldata = 8; - req->rq_data = data; - req->rq_lparm = 6; - req->rq_parm = param; - req->rq_flags |= SMB_REQ_NORETRY; - result = smb_add_request(req); - if (result < 0) - goto out_free; - - result = 0; - if (req->rq_rcls != 0) - result = smb_errno(req); - -out_free: - smb_rput(req); -out: - return result; -} - -static int -smb_proc_trunc95(struct inode *inode, loff_t length) -{ - struct smb_sb_info *server = server_from_inode(inode); - int result = smb_proc_trunc32(inode, length); - - /* - * win9x doesn't appear to update the size immediately. - * It will return the old file size after the truncate, - * confusing smbfs. So we force an update. - * - * FIXME: is this still necessary? - */ - smb_proc_flush(server, SMB_I(inode)->fileid); - return result; -} - -static void -smb_init_dirent(struct smb_sb_info *server, struct smb_fattr *fattr) -{ - memset(fattr, 0, sizeof(*fattr)); - - fattr->f_nlink = 1; - fattr->f_uid = server->mnt->uid; - fattr->f_gid = server->mnt->gid; - fattr->f_unix = 0; -} - -static void -smb_finish_dirent(struct smb_sb_info *server, struct smb_fattr *fattr) -{ - if (fattr->f_unix) - return; - - fattr->f_mode = server->mnt->file_mode; - if (fattr->attr & aDIR) { - fattr->f_mode = server->mnt->dir_mode; - fattr->f_size = SMB_ST_BLKSIZE; - } - /* Check the read-only flag */ - if (fattr->attr & aRONLY) - fattr->f_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); - - /* How many 512 byte blocks do we need for this file? */ - fattr->f_blocks = 0; - if (fattr->f_size != 0) - fattr->f_blocks = 1 + ((fattr->f_size-1) >> 9); - return; -} - -void -smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr, - struct super_block *sb) -{ - smb_init_dirent(server, fattr); - fattr->attr = aDIR; - fattr->f_ino = 2; /* traditional root inode number */ - fattr->f_mtime = current_fs_time(sb); - smb_finish_dirent(server, fattr); -} - -/* - * Decode a dirent for old protocols - * - * qname is filled with the decoded, and possibly translated, name. - * fattr receives decoded attributes - * - * Bugs Noted: - * (1) Pathworks servers may pad the name with extra spaces. - */ -static char * -smb_decode_short_dirent(struct smb_sb_info *server, char *p, - struct qstr *qname, struct smb_fattr *fattr, - unsigned char *name_buf) -{ - int len; - - /* - * SMB doesn't have a concept of inode numbers ... - */ - smb_init_dirent(server, fattr); - fattr->f_ino = 0; /* FIXME: do we need this? */ - - p += SMB_STATUS_SIZE; /* reserved (search_status) */ - fattr->attr = *p; - fattr->f_mtime.tv_sec = date_dos2unix(server, WVAL(p, 3), WVAL(p, 1)); - fattr->f_mtime.tv_nsec = 0; - fattr->f_size = DVAL(p, 5); - fattr->f_ctime = fattr->f_mtime; - fattr->f_atime = fattr->f_mtime; - qname->name = p + 9; - len = strnlen(qname->name, 12); - - /* - * Trim trailing blanks for Pathworks servers - */ - while (len > 2 && qname->name[len-1] == ' ') - len--; - - smb_finish_dirent(server, fattr); - -#if 0 - /* FIXME: These only work for ascii chars, and recent smbmount doesn't - allow the flag to be set anyway. It kills const. Remove? */ - switch (server->opt.case_handling) { - case SMB_CASE_UPPER: - str_upper(entry->name, len); - break; - case SMB_CASE_LOWER: - str_lower(entry->name, len); - break; - default: - break; - } -#endif - - qname->len = 0; - len = server->ops->convert(name_buf, SMB_MAXNAMELEN, - qname->name, len, - server->remote_nls, server->local_nls); - if (len > 0) { - qname->len = len; - qname->name = name_buf; - DEBUG1("len=%d, name=%.*s\n",qname->len,qname->len,qname->name); - } - - return p + 22; -} - -/* - * This routine is used to read in directory entries from the network. - * Note that it is for short directory name seeks, i.e.: protocol < - * SMB_PROTOCOL_LANMAN2 - */ -static int -smb_proc_readdir_short(struct file *filp, void *dirent, filldir_t filldir, - struct smb_cache_control *ctl) -{ - struct dentry *dir = filp->f_path.dentry; - struct smb_sb_info *server = server_from_dentry(dir); - struct qstr qname; - struct smb_fattr fattr; - char *p; - int result; - int i, first, entries_seen, entries; - int entries_asked = (server->opt.max_xmit - 100) / SMB_DIRINFO_SIZE; - __u16 bcc; - __u16 count; - char status[SMB_STATUS_SIZE]; - static struct qstr mask = { - .name = "*.*", - .len = 3, - }; - unsigned char *last_status; - struct smb_request *req; - unsigned char *name_buf; - - VERBOSE("%s/%s\n", DENTRY_PATH(dir)); - - lock_kernel(); - - result = -ENOMEM; - if (! (name_buf = kmalloc(SMB_MAXNAMELEN, GFP_KERNEL))) - goto out; - - first = 1; - entries = 0; - entries_seen = 2; /* implicit . and .. */ - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, server->opt.max_xmit))) - goto out_name; - - while (1) { - p = smb_setup_header(req, SMBsearch, 2, 0); - WSET(req->rq_header, smb_vwv0, entries_asked); - WSET(req->rq_header, smb_vwv1, aDIR); - if (first == 1) { - result = smb_simple_encode_path(req, &p, dir, &mask); - if (result < 0) - goto out_free; - if (p + 3 > (char *)req->rq_buffer + req->rq_bufsize) { - result = -ENAMETOOLONG; - goto out_free; - } - *p++ = 5; - WSET(p, 0, 0); - p += 2; - first = 0; - } else { - if (p + 5 + SMB_STATUS_SIZE > - (char *)req->rq_buffer + req->rq_bufsize) { - result = -ENAMETOOLONG; - goto out_free; - } - - *p++ = 4; - *p++ = 0; - *p++ = 5; - WSET(p, 0, SMB_STATUS_SIZE); - p += 2; - memcpy(p, status, SMB_STATUS_SIZE); - p += SMB_STATUS_SIZE; - } - - smb_setup_bcc(req, p); - - result = smb_request_ok(req, SMBsearch, 1, -1); - if (result < 0) { - if ((req->rq_rcls == ERRDOS) && - (req->rq_err == ERRnofiles)) - break; - goto out_free; - } - count = WVAL(req->rq_header, smb_vwv0); - if (count <= 0) - break; - - result = -EIO; - bcc = smb_bcc(req->rq_header); - if (bcc != count * SMB_DIRINFO_SIZE + 3) - goto out_free; - p = req->rq_buffer + 3; - - - /* Make sure the response fits in the buffer. Fixed sized - entries means we don't have to check in the decode loop. */ - - last_status = req->rq_buffer + 3 + (count-1) * SMB_DIRINFO_SIZE; - - if (last_status + SMB_DIRINFO_SIZE >= - req->rq_buffer + req->rq_bufsize) { - printk(KERN_ERR "smb_proc_readdir_short: " - "last dir entry outside buffer! " - "%d@%p %d@%p\n", SMB_DIRINFO_SIZE, last_status, - req->rq_bufsize, req->rq_buffer); - goto out_free; - } - - /* Read the last entry into the status field. */ - memcpy(status, last_status, SMB_STATUS_SIZE); - - - /* Now we are ready to parse smb directory entries. */ - - for (i = 0; i < count; i++) { - p = smb_decode_short_dirent(server, p, - &qname, &fattr, name_buf); - if (qname.len == 0) - continue; - - if (entries_seen == 2 && qname.name[0] == '.') { - if (qname.len == 1) - continue; - if (qname.name[1] == '.' && qname.len == 2) - continue; - } - if (!smb_fill_cache(filp, dirent, filldir, ctl, - &qname, &fattr)) - ; /* stop reading? */ - entries_seen++; - } - } - result = entries; - -out_free: - smb_rput(req); -out_name: - kfree(name_buf); -out: - unlock_kernel(); - return result; -} - -static void smb_decode_unix_basic(struct smb_fattr *fattr, struct smb_sb_info *server, char *p) -{ - u64 size, disk_bytes; - - /* FIXME: verify nls support. all is sent as utf8? */ - - fattr->f_unix = 1; - fattr->f_mode = 0; - - /* FIXME: use the uniqueID from the remote instead? */ - /* 0 L file size in bytes */ - /* 8 L file size on disk in bytes (block count) */ - /* 40 L uid */ - /* 48 L gid */ - /* 56 W file type */ - /* 60 L devmajor */ - /* 68 L devminor */ - /* 76 L unique ID (inode) */ - /* 84 L permissions */ - /* 92 L link count */ - - size = LVAL(p, 0); - disk_bytes = LVAL(p, 8); - - /* - * Some samba versions round up on-disk byte usage - * to 1MB boundaries, making it useless. When seeing - * that, use the size instead. - */ - if (!(disk_bytes & 0xfffff)) - disk_bytes = size+511; - - fattr->f_size = size; - fattr->f_blocks = disk_bytes >> 9; - fattr->f_ctime = smb_ntutc2unixutc(LVAL(p, 16)); - fattr->f_atime = smb_ntutc2unixutc(LVAL(p, 24)); - fattr->f_mtime = smb_ntutc2unixutc(LVAL(p, 32)); - - if (server->mnt->flags & SMB_MOUNT_UID) - fattr->f_uid = server->mnt->uid; - else - fattr->f_uid = LVAL(p, 40); - - if (server->mnt->flags & SMB_MOUNT_GID) - fattr->f_gid = server->mnt->gid; - else - fattr->f_gid = LVAL(p, 48); - - fattr->f_mode |= smb_filetype_to_mode(WVAL(p, 56)); - - if (S_ISBLK(fattr->f_mode) || S_ISCHR(fattr->f_mode)) { - __u64 major = LVAL(p, 60); - __u64 minor = LVAL(p, 68); - - fattr->f_rdev = MKDEV(major & 0xffffffff, minor & 0xffffffff); - if (MAJOR(fattr->f_rdev) != (major & 0xffffffff) || - MINOR(fattr->f_rdev) != (minor & 0xffffffff)) - fattr->f_rdev = 0; - } - - fattr->f_mode |= LVAL(p, 84); - - if ( (server->mnt->flags & SMB_MOUNT_DMODE) && - (S_ISDIR(fattr->f_mode)) ) - fattr->f_mode = (server->mnt->dir_mode & S_IRWXUGO) | S_IFDIR; - else if ( (server->mnt->flags & SMB_MOUNT_FMODE) && - !(S_ISDIR(fattr->f_mode)) ) - fattr->f_mode = (server->mnt->file_mode & S_IRWXUGO) | - (fattr->f_mode & S_IFMT); - -} - -/* - * Interpret a long filename structure using the specified info level: - * level 1 for anything below NT1 protocol - * level 260 for NT1 protocol - * - * qname is filled with the decoded, and possibly translated, name - * fattr receives decoded attributes. - * - * Bugs Noted: - * (1) Win NT 4.0 appends a null byte to names and counts it in the length! - */ -static char * -smb_decode_long_dirent(struct smb_sb_info *server, char *p, int level, - struct qstr *qname, struct smb_fattr *fattr, - unsigned char *name_buf) -{ - char *result; - unsigned int len = 0; - int n; - __u16 date, time; - int unicode = (server->mnt->flags & SMB_MOUNT_UNICODE); - - /* - * SMB doesn't have a concept of inode numbers ... - */ - smb_init_dirent(server, fattr); - fattr->f_ino = 0; /* FIXME: do we need this? */ - - switch (level) { - case 1: - len = *((unsigned char *) p + 22); - qname->name = p + 23; - result = p + 24 + len; - - date = WVAL(p, 0); - time = WVAL(p, 2); - fattr->f_ctime.tv_sec = date_dos2unix(server, date, time); - fattr->f_ctime.tv_nsec = 0; - - date = WVAL(p, 4); - time = WVAL(p, 6); - fattr->f_atime.tv_sec = date_dos2unix(server, date, time); - fattr->f_atime.tv_nsec = 0; - - date = WVAL(p, 8); - time = WVAL(p, 10); - fattr->f_mtime.tv_sec = date_dos2unix(server, date, time); - fattr->f_mtime.tv_nsec = 0; - fattr->f_size = DVAL(p, 12); - /* ULONG allocation size */ - fattr->attr = WVAL(p, 20); - - VERBOSE("info 1 at %p, len=%d, name=%.*s\n", - p, len, len, qname->name); - break; - case 260: - result = p + WVAL(p, 0); - len = DVAL(p, 60); - if (len > 255) len = 255; - /* NT4 null terminates, unless we are using unicode ... */ - qname->name = p + 94; - if (!unicode && len && qname->name[len-1] == '\0') - len--; - - fattr->f_ctime = smb_ntutc2unixutc(LVAL(p, 8)); - fattr->f_atime = smb_ntutc2unixutc(LVAL(p, 16)); - fattr->f_mtime = smb_ntutc2unixutc(LVAL(p, 24)); - /* change time (32) */ - fattr->f_size = LVAL(p, 40); - /* alloc size (48) */ - fattr->attr = DVAL(p, 56); - - VERBOSE("info 260 at %p, len=%d, name=%.*s\n", - p, len, len, qname->name); - break; - case SMB_FIND_FILE_UNIX: - result = p + WVAL(p, 0); - qname->name = p + 108; - - len = strlen(qname->name); - /* FIXME: should we check the length?? */ - - p += 8; - smb_decode_unix_basic(fattr, server, p); - VERBOSE("info SMB_FIND_FILE_UNIX at %p, len=%d, name=%.*s\n", - p, len, len, qname->name); - break; - default: - PARANOIA("Unknown info level %d\n", level); - result = p + WVAL(p, 0); - goto out; - } - - smb_finish_dirent(server, fattr); - -#if 0 - /* FIXME: These only work for ascii chars, and recent smbmount doesn't - allow the flag to be set anyway. Remove? */ - switch (server->opt.case_handling) { - case SMB_CASE_UPPER: - str_upper(qname->name, len); - break; - case SMB_CASE_LOWER: - str_lower(qname->name, len); - break; - default: - break; - } -#endif - - qname->len = 0; - n = server->ops->convert(name_buf, SMB_MAXNAMELEN, - qname->name, len, - server->remote_nls, server->local_nls); - if (n > 0) { - qname->len = n; - qname->name = name_buf; - } - -out: - return result; -} - -/* findfirst/findnext flags */ -#define SMB_CLOSE_AFTER_FIRST (1<<0) -#define SMB_CLOSE_IF_END (1<<1) -#define SMB_REQUIRE_RESUME_KEY (1<<2) -#define SMB_CONTINUE_BIT (1<<3) - -/* - * Note: samba-2.0.7 (at least) has a very similar routine, cli_list, in - * source/libsmb/clilist.c. When looking for smb bugs in the readdir code, - * go there for advise. - * - * Bugs Noted: - * (1) When using Info Level 1 Win NT 4.0 truncates directory listings - * for certain patterns of names and/or lengths. The breakage pattern - * is completely reproducible and can be toggled by the creation of a - * single file. (E.g. echo hi >foo breaks, rm -f foo works.) - */ -static int -smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir, - struct smb_cache_control *ctl) -{ - struct dentry *dir = filp->f_path.dentry; - struct smb_sb_info *server = server_from_dentry(dir); - struct qstr qname; - struct smb_fattr fattr; - - unsigned char *p, *lastname; - char *mask, *param; - __u16 command; - int first, entries_seen; - - /* Both NT and OS/2 accept info level 1 (but see note below). */ - int info_level = 260; - const int max_matches = 512; - - unsigned int ff_searchcount = 0; - unsigned int ff_eos = 0; - unsigned int ff_lastname = 0; - unsigned int ff_dir_handle = 0; - unsigned int loop_count = 0; - unsigned int mask_len, i; - int result; - struct smb_request *req; - unsigned char *name_buf; - static struct qstr star = { - .name = "*", - .len = 1, - }; - - lock_kernel(); - - /* - * We always prefer unix style. Use info level 1 for older - * servers that don't do 260. - */ - if (server->opt.capabilities & SMB_CAP_UNIX) - info_level = SMB_FIND_FILE_UNIX; - else if (server->opt.protocol < SMB_PROTOCOL_NT1) - info_level = 1; - - result = -ENOMEM; - if (! (name_buf = kmalloc(SMB_MAXNAMELEN+2, GFP_KERNEL))) - goto out; - if (! (req = smb_alloc_request(server, server->opt.max_xmit))) - goto out_name; - param = req->rq_buffer; - - /* - * Encode the initial path - */ - mask = param + 12; - - result = smb_encode_path(server, mask, SMB_MAXPATHLEN+1, dir, &star); - if (result <= 0) - goto out_free; - mask_len = result - 1; /* mask_len is strlen, not #bytes */ - result = 0; - first = 1; - VERBOSE("starting mask_len=%d, mask=%s\n", mask_len, mask); - - entries_seen = 2; - ff_eos = 0; - - while (ff_eos == 0) { - loop_count += 1; - if (loop_count > 10) { - printk(KERN_WARNING "smb_proc_readdir_long: " - "Looping in FIND_NEXT??\n"); - result = -EIO; - break; - } - - if (first != 0) { - command = TRANSACT2_FINDFIRST; - WSET(param, 0, aSYSTEM | aHIDDEN | aDIR); - WSET(param, 2, max_matches); /* max count */ - WSET(param, 4, SMB_CLOSE_IF_END); - WSET(param, 6, info_level); - DSET(param, 8, 0); - } else { - command = TRANSACT2_FINDNEXT; - - VERBOSE("handle=0x%X, lastname=%d, mask=%.*s\n", - ff_dir_handle, ff_lastname, mask_len, mask); - - WSET(param, 0, ff_dir_handle); /* search handle */ - WSET(param, 2, max_matches); /* max count */ - WSET(param, 4, info_level); - DSET(param, 6, 0); - WSET(param, 10, SMB_CONTINUE_BIT|SMB_CLOSE_IF_END); - } - - req->rq_trans2_command = command; - req->rq_ldata = 0; - req->rq_data = NULL; - req->rq_lparm = 12 + mask_len + 1; - req->rq_parm = param; - req->rq_flags = 0; - result = smb_add_request(req); - if (result < 0) { - PARANOIA("error=%d, breaking\n", result); - break; - } - - if (req->rq_rcls == ERRSRV && req->rq_err == ERRerror) { - /* a damn Win95 bug - sometimes it clags if you - ask it too fast */ - schedule_timeout_interruptible(msecs_to_jiffies(200)); - continue; - } - - if (req->rq_rcls != 0) { - result = smb_errno(req); - PARANOIA("name=%s, result=%d, rcls=%d, err=%d\n", - mask, result, req->rq_rcls, req->rq_err); - break; - } - - /* parse out some important return info */ - if (first != 0) { - ff_dir_handle = WVAL(req->rq_parm, 0); - ff_searchcount = WVAL(req->rq_parm, 2); - ff_eos = WVAL(req->rq_parm, 4); - ff_lastname = WVAL(req->rq_parm, 8); - } else { - ff_searchcount = WVAL(req->rq_parm, 0); - ff_eos = WVAL(req->rq_parm, 2); - ff_lastname = WVAL(req->rq_parm, 6); - } - - if (ff_searchcount == 0) - break; - - /* Now we are ready to parse smb directory entries. */ - - /* point to the data bytes */ - p = req->rq_data; - for (i = 0; i < ff_searchcount; i++) { - /* make sure we stay within the buffer */ - if (p >= req->rq_data + req->rq_ldata) { - printk(KERN_ERR "smb_proc_readdir_long: " - "dirent pointer outside buffer! " - "%p %d@%p\n", - p, req->rq_ldata, req->rq_data); - result = -EIO; /* always a comm. error? */ - goto out_free; - } - - p = smb_decode_long_dirent(server, p, info_level, - &qname, &fattr, name_buf); - - /* ignore . and .. from the server */ - if (entries_seen == 2 && qname.name[0] == '.') { - if (qname.len == 1) - continue; - if (qname.name[1] == '.' && qname.len == 2) - continue; - } - - if (!smb_fill_cache(filp, dirent, filldir, ctl, - &qname, &fattr)) - ; /* stop reading? */ - entries_seen++; - } - - VERBOSE("received %d entries, eos=%d\n", ff_searchcount,ff_eos); - - /* - * We might need the lastname for continuations. - * - * Note that some servers (win95?) point to the filename and - * others (NT4, Samba using NT1) to the dir entry. We assume - * here that those who do not point to a filename do not need - * this info to continue the listing. - * - * OS/2 needs this and talks infolevel 1. - * NetApps want lastname with infolevel 260. - * win2k want lastname with infolevel 260, and points to - * the record not to the name. - * Samba+CifsUnixExt doesn't need lastname. - * - * Both are happy if we return the data they point to. So we do. - * (FIXME: above is not true with win2k) - */ - mask_len = 0; - if (info_level != SMB_FIND_FILE_UNIX && - ff_lastname > 0 && ff_lastname < req->rq_ldata) { - lastname = req->rq_data + ff_lastname; - - switch (info_level) { - case 260: - mask_len = req->rq_ldata - ff_lastname; - break; - case 1: - /* lastname points to a length byte */ - mask_len = *lastname++; - if (ff_lastname + 1 + mask_len > req->rq_ldata) - mask_len = req->rq_ldata - ff_lastname - 1; - break; - } - - /* - * Update the mask string for the next message. - */ - if (mask_len > 255) - mask_len = 255; - if (mask_len) - strncpy(mask, lastname, mask_len); - } - mask_len = strnlen(mask, mask_len); - VERBOSE("new mask, len=%d@%d of %d, mask=%.*s\n", - mask_len, ff_lastname, req->rq_ldata, mask_len, mask); - - first = 0; - loop_count = 0; - } - -out_free: - smb_rput(req); -out_name: - kfree(name_buf); -out: - unlock_kernel(); - return result; -} - -/* - * This version uses the trans2 TRANSACT2_FINDFIRST message - * to get the attribute data. - * - * Bugs Noted: - */ -static int -smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry, - struct smb_fattr *fattr) -{ - char *param, *mask; - __u16 date, time; - int mask_len, result; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, PAGE_SIZE))) - goto out; - param = req->rq_buffer; - mask = param + 12; - - mask_len = smb_encode_path(server, mask, SMB_MAXPATHLEN+1, dentry,NULL); - if (mask_len < 0) { - result = mask_len; - goto out_free; - } - VERBOSE("name=%s, len=%d\n", mask, mask_len); - WSET(param, 0, aSYSTEM | aHIDDEN | aDIR); - WSET(param, 2, 1); /* max count */ - WSET(param, 4, 1); /* close after this call */ - WSET(param, 6, 1); /* info_level */ - DSET(param, 8, 0); - - req->rq_trans2_command = TRANSACT2_FINDFIRST; - req->rq_ldata = 0; - req->rq_data = NULL; - req->rq_lparm = 12 + mask_len; - req->rq_parm = param; - req->rq_flags = 0; - result = smb_add_request(req); - if (result < 0) - goto out_free; - if (req->rq_rcls != 0) { - result = smb_errno(req); -#ifdef SMBFS_PARANOIA - if (result != -ENOENT) - PARANOIA("error for %s, rcls=%d, err=%d\n", - mask, req->rq_rcls, req->rq_err); -#endif - goto out_free; - } - /* Make sure we got enough data ... */ - result = -EINVAL; - if (req->rq_ldata < 22 || WVAL(req->rq_parm, 2) != 1) { - PARANOIA("bad result for %s, len=%d, count=%d\n", - mask, req->rq_ldata, WVAL(req->rq_parm, 2)); - goto out_free; - } - - /* - * Decode the response into the fattr ... - */ - date = WVAL(req->rq_data, 0); - time = WVAL(req->rq_data, 2); - fattr->f_ctime.tv_sec = date_dos2unix(server, date, time); - fattr->f_ctime.tv_nsec = 0; - - date = WVAL(req->rq_data, 4); - time = WVAL(req->rq_data, 6); - fattr->f_atime.tv_sec = date_dos2unix(server, date, time); - fattr->f_atime.tv_nsec = 0; - - date = WVAL(req->rq_data, 8); - time = WVAL(req->rq_data, 10); - fattr->f_mtime.tv_sec = date_dos2unix(server, date, time); - fattr->f_mtime.tv_nsec = 0; - VERBOSE("name=%s, date=%x, time=%x, mtime=%ld\n", - mask, date, time, fattr->f_mtime.tv_sec); - fattr->f_size = DVAL(req->rq_data, 12); - /* ULONG allocation size */ - fattr->attr = WVAL(req->rq_data, 20); - result = 0; - -out_free: - smb_rput(req); -out: - return result; -} - -static int -smb_proc_getattr_core(struct smb_sb_info *server, struct dentry *dir, - struct smb_fattr *fattr) -{ - int result; - char *p; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, PAGE_SIZE))) - goto out; - - p = smb_setup_header(req, SMBgetatr, 0, 0); - result = smb_simple_encode_path(req, &p, dir, NULL); - if (result < 0) - goto out_free; - smb_setup_bcc(req, p); - - if ((result = smb_request_ok(req, SMBgetatr, 10, 0)) < 0) - goto out_free; - fattr->attr = WVAL(req->rq_header, smb_vwv0); - fattr->f_mtime.tv_sec = local2utc(server, DVAL(req->rq_header, smb_vwv1)); - fattr->f_mtime.tv_nsec = 0; - fattr->f_size = DVAL(req->rq_header, smb_vwv3); - fattr->f_ctime = fattr->f_mtime; - fattr->f_atime = fattr->f_mtime; -#ifdef SMBFS_DEBUG_TIMESTAMP - printk("getattr_core: %s/%s, mtime=%ld\n", - DENTRY_PATH(dir), fattr->f_mtime); -#endif - result = 0; - -out_free: - smb_rput(req); -out: - return result; -} - -/* - * Bugs Noted: - * (1) Win 95 swaps the date and time fields in the standard info level. - */ -static int -smb_proc_getattr_trans2(struct smb_sb_info *server, struct dentry *dir, - struct smb_request *req, int infolevel) -{ - char *p, *param; - int result; - - param = req->rq_buffer; - WSET(param, 0, infolevel); - DSET(param, 2, 0); - result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, dir, NULL); - if (result < 0) - goto out; - p = param + 6 + result; - - req->rq_trans2_command = TRANSACT2_QPATHINFO; - req->rq_ldata = 0; - req->rq_data = NULL; - req->rq_lparm = p - param; - req->rq_parm = param; - req->rq_flags = 0; - result = smb_add_request(req); - if (result < 0) - goto out; - if (req->rq_rcls != 0) { - VERBOSE("for %s: result=%d, rcls=%d, err=%d\n", - ¶m[6], result, req->rq_rcls, req->rq_err); - result = smb_errno(req); - goto out; - } - result = -ENOENT; - if (req->rq_ldata < 22) { - PARANOIA("not enough data for %s, len=%d\n", - ¶m[6], req->rq_ldata); - goto out; - } - - result = 0; -out: - return result; -} - -static int -smb_proc_getattr_trans2_std(struct smb_sb_info *server, struct dentry *dir, - struct smb_fattr *attr) -{ - u16 date, time; - int off_date = 0, off_time = 2; - int result; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, PAGE_SIZE))) - goto out; - - result = smb_proc_getattr_trans2(server, dir, req, SMB_INFO_STANDARD); - if (result < 0) - goto out_free; - - /* - * Kludge alert: Win 95 swaps the date and time field, - * contrary to the CIFS docs and Win NT practice. - */ - if (server->mnt->flags & SMB_MOUNT_WIN95) { - off_date = 2; - off_time = 0; - } - date = WVAL(req->rq_data, off_date); - time = WVAL(req->rq_data, off_time); - attr->f_ctime.tv_sec = date_dos2unix(server, date, time); - attr->f_ctime.tv_nsec = 0; - - date = WVAL(req->rq_data, 4 + off_date); - time = WVAL(req->rq_data, 4 + off_time); - attr->f_atime.tv_sec = date_dos2unix(server, date, time); - attr->f_atime.tv_nsec = 0; - - date = WVAL(req->rq_data, 8 + off_date); - time = WVAL(req->rq_data, 8 + off_time); - attr->f_mtime.tv_sec = date_dos2unix(server, date, time); - attr->f_mtime.tv_nsec = 0; -#ifdef SMBFS_DEBUG_TIMESTAMP - printk(KERN_DEBUG "getattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n", - DENTRY_PATH(dir), date, time, attr->f_mtime); -#endif - attr->f_size = DVAL(req->rq_data, 12); - attr->attr = WVAL(req->rq_data, 20); - -out_free: - smb_rput(req); -out: - return result; -} - -static int -smb_proc_getattr_trans2_all(struct smb_sb_info *server, struct dentry *dir, - struct smb_fattr *attr) -{ - struct smb_request *req; - int result; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, PAGE_SIZE))) - goto out; - - result = smb_proc_getattr_trans2(server, dir, req, - SMB_QUERY_FILE_ALL_INFO); - if (result < 0) - goto out_free; - - attr->f_ctime = smb_ntutc2unixutc(LVAL(req->rq_data, 0)); - attr->f_atime = smb_ntutc2unixutc(LVAL(req->rq_data, 8)); - attr->f_mtime = smb_ntutc2unixutc(LVAL(req->rq_data, 16)); - /* change (24) */ - attr->attr = WVAL(req->rq_data, 32); - /* pad? (34) */ - /* allocated size (40) */ - attr->f_size = LVAL(req->rq_data, 48); - -out_free: - smb_rput(req); -out: - return result; -} - -static int -smb_proc_getattr_unix(struct smb_sb_info *server, struct dentry *dir, - struct smb_fattr *attr) -{ - struct smb_request *req; - int result; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, PAGE_SIZE))) - goto out; - - result = smb_proc_getattr_trans2(server, dir, req, - SMB_QUERY_FILE_UNIX_BASIC); - if (result < 0) - goto out_free; - - smb_decode_unix_basic(attr, server, req->rq_data); - -out_free: - smb_rput(req); -out: - return result; -} - -static int -smb_proc_getattr_95(struct smb_sb_info *server, struct dentry *dir, - struct smb_fattr *attr) -{ - struct inode *inode = dir->d_inode; - int result; - - /* FIXME: why not use the "all" version? */ - result = smb_proc_getattr_trans2_std(server, dir, attr); - if (result < 0) - goto out; - - /* - * None of the getattr versions here can make win9x return the right - * filesize if there are changes made to an open file. - * A seek-to-end does return the right size, but we only need to do - * that on files we have written. - */ - if (inode && SMB_I(inode)->flags & SMB_F_LOCALWRITE && - smb_is_open(inode)) - { - __u16 fileid = SMB_I(inode)->fileid; - attr->f_size = smb_proc_seek(server, fileid, 2, 0); - } - -out: - return result; -} - -static int -smb_proc_ops_wait(struct smb_sb_info *server) -{ - int result; - - result = wait_event_interruptible_timeout(server->conn_wq, - server->conn_complete, 30*HZ); - - if (!result || signal_pending(current)) - return -EIO; - - return 0; -} - -static int -smb_proc_getattr_null(struct smb_sb_info *server, struct dentry *dir, - struct smb_fattr *fattr) -{ - int result; - - if (smb_proc_ops_wait(server) < 0) - return -EIO; - - smb_init_dirent(server, fattr); - result = server->ops->getattr(server, dir, fattr); - smb_finish_dirent(server, fattr); - - return result; -} - -static int -smb_proc_readdir_null(struct file *filp, void *dirent, filldir_t filldir, - struct smb_cache_control *ctl) -{ - struct smb_sb_info *server = server_from_dentry(filp->f_path.dentry); - - if (smb_proc_ops_wait(server) < 0) - return -EIO; - - return server->ops->readdir(filp, dirent, filldir, ctl); -} - -int -smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr) -{ - struct smb_sb_info *server = server_from_dentry(dir); - int result; - - smb_init_dirent(server, fattr); - result = server->ops->getattr(server, dir, fattr); - smb_finish_dirent(server, fattr); - - return result; -} - - -/* - * Because of bugs in the core protocol, we use this only to set - * attributes. See smb_proc_settime() below for timestamp handling. - * - * Bugs Noted: - * (1) If mtime is non-zero, both Win 3.1 and Win 95 fail - * with an undocumented error (ERRDOS code 50). Setting - * mtime to 0 allows the attributes to be set. - * (2) The extra parameters following the name string aren't - * in the CIFS docs, but seem to be necessary for operation. - */ -static int -smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry, - __u16 attr) -{ - char *p; - int result; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, PAGE_SIZE))) - goto out; - - p = smb_setup_header(req, SMBsetatr, 8, 0); - WSET(req->rq_header, smb_vwv0, attr); - DSET(req->rq_header, smb_vwv1, 0); /* mtime */ - WSET(req->rq_header, smb_vwv3, 0); /* reserved values */ - WSET(req->rq_header, smb_vwv4, 0); - WSET(req->rq_header, smb_vwv5, 0); - WSET(req->rq_header, smb_vwv6, 0); - WSET(req->rq_header, smb_vwv7, 0); - result = smb_simple_encode_path(req, &p, dentry, NULL); - if (result < 0) - goto out_free; - if (p + 2 > (char *)req->rq_buffer + req->rq_bufsize) { - result = -ENAMETOOLONG; - goto out_free; - } - *p++ = 4; - *p++ = 0; - smb_setup_bcc(req, p); - - result = smb_request_ok(req, SMBsetatr, 0, 0); - if (result < 0) - goto out_free; - result = 0; - -out_free: - smb_rput(req); -out: - return result; -} - -/* - * Because of bugs in the trans2 setattr messages, we must set - * attributes and timestamps separately. The core SMBsetatr - * message seems to be the only reliable way to set attributes. - */ -int -smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr) -{ - struct smb_sb_info *server = server_from_dentry(dir); - int result; - - VERBOSE("setting %s/%s, open=%d\n", - DENTRY_PATH(dir), smb_is_open(dir->d_inode)); - result = smb_proc_setattr_core(server, dir, fattr->attr); - return result; -} - -/* - * Sets the timestamps for an file open with write permissions. - */ -static int -smb_proc_setattr_ext(struct smb_sb_info *server, - struct inode *inode, struct smb_fattr *fattr) -{ - __u16 date, time; - int result; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, 0))) - goto out; - - smb_setup_header(req, SMBsetattrE, 7, 0); - WSET(req->rq_header, smb_vwv0, SMB_I(inode)->fileid); - /* We don't change the creation time */ - WSET(req->rq_header, smb_vwv1, 0); - WSET(req->rq_header, smb_vwv2, 0); - date_unix2dos(server, fattr->f_atime.tv_sec, &date, &time); - WSET(req->rq_header, smb_vwv3, date); - WSET(req->rq_header, smb_vwv4, time); - date_unix2dos(server, fattr->f_mtime.tv_sec, &date, &time); - WSET(req->rq_header, smb_vwv5, date); - WSET(req->rq_header, smb_vwv6, time); -#ifdef SMBFS_DEBUG_TIMESTAMP - printk(KERN_DEBUG "smb_proc_setattr_ext: date=%d, time=%d, mtime=%ld\n", - date, time, fattr->f_mtime); -#endif - - req->rq_flags |= SMB_REQ_NORETRY; - result = smb_request_ok(req, SMBsetattrE, 0, 0); - if (result < 0) - goto out_free; - result = 0; -out_free: - smb_rput(req); -out: - return result; -} - -/* - * Bugs Noted: - * (1) The TRANSACT2_SETPATHINFO message under Win NT 4.0 doesn't - * set the file's attribute flags. - */ -static int -smb_proc_setattr_trans2(struct smb_sb_info *server, - struct dentry *dir, struct smb_fattr *fattr) -{ - __u16 date, time; - char *p, *param; - int result; - char data[26]; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, PAGE_SIZE))) - goto out; - param = req->rq_buffer; - - WSET(param, 0, 1); /* Info level SMB_INFO_STANDARD */ - DSET(param, 2, 0); - result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, dir, NULL); - if (result < 0) - goto out_free; - p = param + 6 + result; - - WSET(data, 0, 0); /* creation time */ - WSET(data, 2, 0); - date_unix2dos(server, fattr->f_atime.tv_sec, &date, &time); - WSET(data, 4, date); - WSET(data, 6, time); - date_unix2dos(server, fattr->f_mtime.tv_sec, &date, &time); - WSET(data, 8, date); - WSET(data, 10, time); -#ifdef SMBFS_DEBUG_TIMESTAMP - printk(KERN_DEBUG "setattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n", - DENTRY_PATH(dir), date, time, fattr->f_mtime); -#endif - DSET(data, 12, 0); /* size */ - DSET(data, 16, 0); /* blksize */ - WSET(data, 20, 0); /* attr */ - DSET(data, 22, 0); /* ULONG EA size */ - - req->rq_trans2_command = TRANSACT2_SETPATHINFO; - req->rq_ldata = 26; - req->rq_data = data; - req->rq_lparm = p - param; - req->rq_parm = param; - req->rq_flags = 0; - result = smb_add_request(req); - if (result < 0) - goto out_free; - result = 0; - if (req->rq_rcls != 0) - result = smb_errno(req); - -out_free: - smb_rput(req); -out: - return result; -} - -/* - * ATTR_MODE 0x001 - * ATTR_UID 0x002 - * ATTR_GID 0x004 - * ATTR_SIZE 0x008 - * ATTR_ATIME 0x010 - * ATTR_MTIME 0x020 - * ATTR_CTIME 0x040 - * ATTR_ATIME_SET 0x080 - * ATTR_MTIME_SET 0x100 - * ATTR_FORCE 0x200 - * ATTR_ATTR_FLAG 0x400 - * - * major/minor should only be set by mknod. - */ -int -smb_proc_setattr_unix(struct dentry *d, struct iattr *attr, - unsigned int major, unsigned int minor) -{ - struct smb_sb_info *server = server_from_dentry(d); - u64 nttime; - char *p, *param; - int result; - char data[100]; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, PAGE_SIZE))) - goto out; - param = req->rq_buffer; - - DEBUG1("valid flags = 0x%04x\n", attr->ia_valid); - - WSET(param, 0, SMB_SET_FILE_UNIX_BASIC); - DSET(param, 2, 0); - result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, d, NULL); - if (result < 0) - goto out_free; - p = param + 6 + result; - - /* 0 L file size in bytes */ - /* 8 L file size on disk in bytes (block count) */ - /* 40 L uid */ - /* 48 L gid */ - /* 56 W file type enum */ - /* 60 L devmajor */ - /* 68 L devminor */ - /* 76 L unique ID (inode) */ - /* 84 L permissions */ - /* 92 L link count */ - LSET(data, 0, SMB_SIZE_NO_CHANGE); - LSET(data, 8, SMB_SIZE_NO_CHANGE); - LSET(data, 16, SMB_TIME_NO_CHANGE); - LSET(data, 24, SMB_TIME_NO_CHANGE); - LSET(data, 32, SMB_TIME_NO_CHANGE); - LSET(data, 40, SMB_UID_NO_CHANGE); - LSET(data, 48, SMB_GID_NO_CHANGE); - DSET(data, 56, smb_filetype_from_mode(attr->ia_mode)); - LSET(data, 60, major); - LSET(data, 68, minor); - LSET(data, 76, 0); - LSET(data, 84, SMB_MODE_NO_CHANGE); - LSET(data, 92, 0); - - if (attr->ia_valid & ATTR_SIZE) { - LSET(data, 0, attr->ia_size); - LSET(data, 8, 0); /* can't set anyway */ - } - - /* - * FIXME: check the conversion function it the correct one - * - * we can't set ctime but we might as well pass this to the server - * and let it ignore it. - */ - if (attr->ia_valid & ATTR_CTIME) { - nttime = smb_unixutc2ntutc(attr->ia_ctime); - LSET(data, 16, nttime); - } - if (attr->ia_valid & ATTR_ATIME) { - nttime = smb_unixutc2ntutc(attr->ia_atime); - LSET(data, 24, nttime); - } - if (attr->ia_valid & ATTR_MTIME) { - nttime = smb_unixutc2ntutc(attr->ia_mtime); - LSET(data, 32, nttime); - } - - if (attr->ia_valid & ATTR_UID) { - LSET(data, 40, attr->ia_uid); - } - if (attr->ia_valid & ATTR_GID) { - LSET(data, 48, attr->ia_gid); - } - - if (attr->ia_valid & ATTR_MODE) { - LSET(data, 84, attr->ia_mode); - } - - req->rq_trans2_command = TRANSACT2_SETPATHINFO; - req->rq_ldata = 100; - req->rq_data = data; - req->rq_lparm = p - param; - req->rq_parm = param; - req->rq_flags = 0; - result = smb_add_request(req); - -out_free: - smb_rput(req); -out: - return result; -} - - -/* - * Set the modify and access timestamps for a file. - * - * Incredibly enough, in all of SMB there is no message to allow - * setting both attributes and timestamps at once. - * - * Bugs Noted: - * (1) Win 95 doesn't support the TRANSACT2_SETFILEINFO message - * with info level 1 (INFO_STANDARD). - * (2) Win 95 seems not to support setting directory timestamps. - * (3) Under the core protocol apparently the only way to set the - * timestamp is to open and close the file. - */ -int -smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr) -{ - struct smb_sb_info *server = server_from_dentry(dentry); - struct inode *inode = dentry->d_inode; - int result; - - VERBOSE("setting %s/%s, open=%d\n", - DENTRY_PATH(dentry), smb_is_open(inode)); - - /* setting the time on a Win95 server fails (tridge) */ - if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2 && - !(server->mnt->flags & SMB_MOUNT_WIN95)) { - if (smb_is_open(inode) && SMB_I(inode)->access != SMB_O_RDONLY) - result = smb_proc_setattr_ext(server, inode, fattr); - else - result = smb_proc_setattr_trans2(server, dentry, fattr); - } else { - /* - * Fail silently on directories ... timestamp can't be set? - */ - result = 0; - if (S_ISREG(inode->i_mode)) { - /* - * Set the mtime by opening and closing the file. - * Note that the file is opened read-only, but this - * still allows us to set the date (tridge) - */ - result = -EACCES; - if (!smb_is_open(inode)) - smb_proc_open(server, dentry, SMB_O_RDONLY); - if (smb_is_open(inode)) { - inode->i_mtime = fattr->f_mtime; - result = smb_proc_close_inode(server, inode); - } - } - } - - return result; -} - -int -smb_proc_dskattr(struct dentry *dentry, struct kstatfs *attr) -{ - struct smb_sb_info *server = SMB_SB(dentry->d_sb); - int result; - char *p; - long unit; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, 0))) - goto out; - - smb_setup_header(req, SMBdskattr, 0, 0); - if ((result = smb_request_ok(req, SMBdskattr, 5, 0)) < 0) - goto out_free; - p = SMB_VWV(req->rq_header); - unit = (WVAL(p, 2) * WVAL(p, 4)) >> SMB_ST_BLKSHIFT; - attr->f_blocks = WVAL(p, 0) * unit; - attr->f_bsize = SMB_ST_BLKSIZE; - attr->f_bavail = attr->f_bfree = WVAL(p, 6) * unit; - result = 0; - -out_free: - smb_rput(req); -out: - return result; -} - -int -smb_proc_read_link(struct smb_sb_info *server, struct dentry *d, - char *buffer, int len) -{ - char *p, *param; - int result; - struct smb_request *req; - - DEBUG1("readlink of %s/%s\n", DENTRY_PATH(d)); - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, PAGE_SIZE))) - goto out; - param = req->rq_buffer; - - WSET(param, 0, SMB_QUERY_FILE_UNIX_LINK); - DSET(param, 2, 0); - result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, d, NULL); - if (result < 0) - goto out_free; - p = param + 6 + result; - - req->rq_trans2_command = TRANSACT2_QPATHINFO; - req->rq_ldata = 0; - req->rq_data = NULL; - req->rq_lparm = p - param; - req->rq_parm = param; - req->rq_flags = 0; - result = smb_add_request(req); - if (result < 0) - goto out_free; - DEBUG1("for %s: result=%d, rcls=%d, err=%d\n", - ¶m[6], result, req->rq_rcls, req->rq_err); - - /* copy data up to the \0 or buffer length */ - result = len; - if (req->rq_ldata < len) - result = req->rq_ldata; - strncpy(buffer, req->rq_data, result); - -out_free: - smb_rput(req); -out: - return result; -} - - -/* - * Create a symlink object called dentry which points to oldpath. - * Samba does not permit dangling links but returns a suitable error message. - */ -int -smb_proc_symlink(struct smb_sb_info *server, struct dentry *d, - const char *oldpath) -{ - char *p, *param; - int result; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, PAGE_SIZE))) - goto out; - param = req->rq_buffer; - - WSET(param, 0, SMB_SET_FILE_UNIX_LINK); - DSET(param, 2, 0); - result = smb_encode_path(server, param + 6, SMB_MAXPATHLEN+1, d, NULL); - if (result < 0) - goto out_free; - p = param + 6 + result; - - req->rq_trans2_command = TRANSACT2_SETPATHINFO; - req->rq_ldata = strlen(oldpath) + 1; - req->rq_data = (char *) oldpath; - req->rq_lparm = p - param; - req->rq_parm = param; - req->rq_flags = 0; - result = smb_add_request(req); - if (result < 0) - goto out_free; - - DEBUG1("for %s: result=%d, rcls=%d, err=%d\n", - ¶m[6], result, req->rq_rcls, req->rq_err); - result = 0; - -out_free: - smb_rput(req); -out: - return result; -} - -/* - * Create a hard link object called new_dentry which points to dentry. - */ -int -smb_proc_link(struct smb_sb_info *server, struct dentry *dentry, - struct dentry *new_dentry) -{ - char *p, *param; - int result; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, PAGE_SIZE))) - goto out; - param = req->rq_buffer; - - WSET(param, 0, SMB_SET_FILE_UNIX_HLINK); - DSET(param, 2, 0); - result = smb_encode_path(server, param + 6, SMB_MAXPATHLEN+1, - new_dentry, NULL); - if (result < 0) - goto out_free; - p = param + 6 + result; - - /* Grr, pointless separation of parameters and data ... */ - req->rq_data = p; - req->rq_ldata = smb_encode_path(server, p, SMB_MAXPATHLEN+1, - dentry, NULL); - - req->rq_trans2_command = TRANSACT2_SETPATHINFO; - req->rq_lparm = p - param; - req->rq_parm = param; - req->rq_flags = 0; - result = smb_add_request(req); - if (result < 0) - goto out_free; - - DEBUG1("for %s: result=%d, rcls=%d, err=%d\n", - ¶m[6], result, req->rq_rcls, req->rq_err); - result = 0; - -out_free: - smb_rput(req); -out: - return result; -} - -static int -smb_proc_query_cifsunix(struct smb_sb_info *server) -{ - int result; - int major, minor; - u64 caps; - char param[2]; - struct smb_request *req; - - result = -ENOMEM; - if (! (req = smb_alloc_request(server, 100))) - goto out; - - WSET(param, 0, SMB_QUERY_CIFS_UNIX_INFO); - - req->rq_trans2_command = TRANSACT2_QFSINFO; - req->rq_ldata = 0; - req->rq_data = NULL; - req->rq_lparm = 2; - req->rq_parm = param; - req->rq_flags = 0; - result = smb_add_request(req); - if (result < 0) - goto out_free; - - if (req->rq_ldata < 12) { - PARANOIA("Not enough data\n"); - goto out_free; - } - major = WVAL(req->rq_data, 0); - minor = WVAL(req->rq_data, 2); - - DEBUG1("Server implements CIFS Extensions for UNIX systems v%d.%d\n", - major, minor); - /* FIXME: verify that we are ok with this major/minor? */ - - caps = LVAL(req->rq_data, 4); - DEBUG1("Server capabilities 0x%016llx\n", caps); - -out_free: - smb_rput(req); -out: - return result; -} - - -static void -install_ops(struct smb_ops *dst, struct smb_ops *src) -{ - memcpy(dst, src, sizeof(void *) * SMB_OPS_NUM_STATIC); -} - -/* < LANMAN2 */ -static struct smb_ops smb_ops_core = -{ - .read = smb_proc_read, - .write = smb_proc_write, - .readdir = smb_proc_readdir_short, - .getattr = smb_proc_getattr_core, - .truncate = smb_proc_trunc32, -}; - -/* LANMAN2, OS/2, others? */ -static struct smb_ops smb_ops_os2 = -{ - .read = smb_proc_read, - .write = smb_proc_write, - .readdir = smb_proc_readdir_long, - .getattr = smb_proc_getattr_trans2_std, - .truncate = smb_proc_trunc32, -}; - -/* Win95, and possibly some NetApp versions too */ -static struct smb_ops smb_ops_win95 = -{ - .read = smb_proc_read, /* does not support 12word readX */ - .write = smb_proc_write, - .readdir = smb_proc_readdir_long, - .getattr = smb_proc_getattr_95, - .truncate = smb_proc_trunc95, -}; - -/* Samba, NT4 and NT5 */ -static struct smb_ops smb_ops_winNT = -{ - .read = smb_proc_readX, - .write = smb_proc_writeX, - .readdir = smb_proc_readdir_long, - .getattr = smb_proc_getattr_trans2_all, - .truncate = smb_proc_trunc64, -}; - -/* Samba w/ unix extensions. Others? */ -static struct smb_ops smb_ops_unix = -{ - .read = smb_proc_readX, - .write = smb_proc_writeX, - .readdir = smb_proc_readdir_long, - .getattr = smb_proc_getattr_unix, - /* FIXME: core/ext/time setattr needs to be cleaned up! */ - /* .setattr = smb_proc_setattr_unix, */ - .truncate = smb_proc_trunc64, -}; - -/* Place holder until real ops are in place */ -static struct smb_ops smb_ops_null = -{ - .readdir = smb_proc_readdir_null, - .getattr = smb_proc_getattr_null, -}; - -void smb_install_null_ops(struct smb_ops *ops) -{ - install_ops(ops, &smb_ops_null); -} diff --git a/drivers/staging/smbfs/proto.h b/drivers/staging/smbfs/proto.h deleted file mode 100644 index 3883cb16a3f6..000000000000 --- a/drivers/staging/smbfs/proto.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Autogenerated with cproto on: Sat Sep 13 17:18:51 CEST 2003 - */ - -struct smb_request; -struct sock; -struct statfs; - -/* proc.c */ -extern int smb_setcodepage(struct smb_sb_info *server, struct smb_nls_codepage *cp); -extern __u32 smb_len(__u8 *p); -extern int smb_get_rsize(struct smb_sb_info *server); -extern int smb_get_wsize(struct smb_sb_info *server); -extern int smb_errno(struct smb_request *req); -extern int smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt); -extern __u8 *smb_setup_header(struct smb_request *req, __u8 command, __u16 wct, __u16 bcc); -extern int smb_open(struct dentry *dentry, int wish); -extern int smb_close(struct inode *ino); -extern int smb_close_fileid(struct dentry *dentry, __u16 fileid); -extern int smb_proc_create(struct dentry *dentry, __u16 attr, time_t ctime, __u16 *fileid); -extern int smb_proc_mv(struct dentry *old_dentry, struct dentry *new_dentry); -extern int smb_proc_mkdir(struct dentry *dentry); -extern int smb_proc_rmdir(struct dentry *dentry); -extern int smb_proc_unlink(struct dentry *dentry); -extern int smb_proc_flush(struct smb_sb_info *server, __u16 fileid); -extern void smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr, - struct super_block *sb); -extern int smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr); -extern int smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr); -extern int smb_proc_setattr_unix(struct dentry *d, struct iattr *attr, unsigned int major, unsigned int minor); -extern int smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr); -extern int smb_proc_dskattr(struct dentry *dentry, struct kstatfs *attr); -extern int smb_proc_read_link(struct smb_sb_info *server, struct dentry *d, char *buffer, int len); -extern int smb_proc_symlink(struct smb_sb_info *server, struct dentry *d, const char *oldpath); -extern int smb_proc_link(struct smb_sb_info *server, struct dentry *dentry, struct dentry *new_dentry); -extern void smb_install_null_ops(struct smb_ops *ops); -/* dir.c */ -extern const struct file_operations smb_dir_operations; -extern const struct inode_operations smb_dir_inode_operations; -extern const struct inode_operations smb_dir_inode_operations_unix; -extern const struct dentry_operations smbfs_dentry_operations_case; -extern const struct dentry_operations smbfs_dentry_operations; -extern void smb_new_dentry(struct dentry *dentry); -extern void smb_renew_times(struct dentry *dentry); -/* cache.c */ -extern void smb_invalid_dir_cache(struct inode *dir); -extern void smb_invalidate_dircache_entries(struct dentry *parent); -extern struct dentry *smb_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos); -extern int smb_fill_cache(struct file *filp, void *dirent, filldir_t filldir, struct smb_cache_control *ctrl, struct qstr *qname, struct smb_fattr *entry); -/* sock.c */ -extern void smb_data_ready(struct sock *sk, int len); -extern int smb_valid_socket(struct inode *inode); -extern void smb_close_socket(struct smb_sb_info *server); -extern int smb_recv_available(struct smb_sb_info *server); -extern int smb_receive_header(struct smb_sb_info *server); -extern int smb_receive_drop(struct smb_sb_info *server); -extern int smb_receive(struct smb_sb_info *server, struct smb_request *req); -extern int smb_send_request(struct smb_request *req); -/* inode.c */ -extern struct inode *smb_iget(struct super_block *sb, struct smb_fattr *fattr); -extern void smb_get_inode_attr(struct inode *inode, struct smb_fattr *fattr); -extern void smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr); -extern void smb_invalidate_inodes(struct smb_sb_info *server); -extern int smb_revalidate_inode(struct dentry *dentry); -extern int smb_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); -extern int smb_notify_change(struct dentry *dentry, struct iattr *attr); -/* file.c */ -extern const struct address_space_operations smb_file_aops; -extern const struct file_operations smb_file_operations; -extern const struct inode_operations smb_file_inode_operations; -/* ioctl.c */ -extern long smb_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -/* smbiod.c */ -extern void smbiod_wake_up(void); -extern int smbiod_register_server(struct smb_sb_info *server); -extern void smbiod_unregister_server(struct smb_sb_info *server); -extern void smbiod_flush(struct smb_sb_info *server); -extern int smbiod_retry(struct smb_sb_info *server); -/* request.c */ -extern int smb_init_request_cache(void); -extern void smb_destroy_request_cache(void); -extern struct smb_request *smb_alloc_request(struct smb_sb_info *server, int bufsize); -extern void smb_rput(struct smb_request *req); -extern int smb_add_request(struct smb_request *req); -extern int smb_request_send_server(struct smb_sb_info *server); -extern int smb_request_recv(struct smb_sb_info *server); -/* symlink.c */ -extern int smb_symlink(struct inode *inode, struct dentry *dentry, const char *oldname); -extern const struct inode_operations smb_link_inode_operations; diff --git a/drivers/staging/smbfs/request.c b/drivers/staging/smbfs/request.c deleted file mode 100644 index 3e7716864306..000000000000 --- a/drivers/staging/smbfs/request.c +++ /dev/null @@ -1,817 +0,0 @@ -/* - * request.c - * - * Copyright (C) 2001 by Urban Widmark - * - * Please add a note about your changes to smbfs in the ChangeLog file. - */ - -#include -#include -#include -#include -#include -#include - -#include "smb_fs.h" -#include "smbno.h" -#include "smb_mount.h" -#include "smb_debug.h" -#include "request.h" -#include "proto.h" - -/* #define SMB_SLAB_DEBUG (SLAB_RED_ZONE | SLAB_POISON) */ -#define SMB_SLAB_DEBUG 0 - -/* cache for request structures */ -static struct kmem_cache *req_cachep; - -static int smb_request_send_req(struct smb_request *req); - -/* - /proc/slabinfo: - name, active, num, objsize, active_slabs, num_slaps, #pages -*/ - - -int smb_init_request_cache(void) -{ - req_cachep = kmem_cache_create("smb_request", - sizeof(struct smb_request), 0, - SMB_SLAB_DEBUG | SLAB_HWCACHE_ALIGN, - NULL); - if (req_cachep == NULL) - return -ENOMEM; - - return 0; -} - -void smb_destroy_request_cache(void) -{ - kmem_cache_destroy(req_cachep); -} - -/* - * Allocate and initialise a request structure - */ -static struct smb_request *smb_do_alloc_request(struct smb_sb_info *server, - int bufsize) -{ - struct smb_request *req; - unsigned char *buf = NULL; - - req = kmem_cache_zalloc(req_cachep, GFP_KERNEL); - VERBOSE("allocating request: %p\n", req); - if (!req) - goto out; - - if (bufsize > 0) { - buf = kmalloc(bufsize, GFP_NOFS); - if (!buf) { - kmem_cache_free(req_cachep, req); - return NULL; - } - } - - req->rq_buffer = buf; - req->rq_bufsize = bufsize; - req->rq_server = server; - init_waitqueue_head(&req->rq_wait); - INIT_LIST_HEAD(&req->rq_queue); - atomic_set(&req->rq_count, 1); - -out: - return req; -} - -struct smb_request *smb_alloc_request(struct smb_sb_info *server, int bufsize) -{ - struct smb_request *req = NULL; - - for (;;) { - atomic_inc(&server->nr_requests); - if (atomic_read(&server->nr_requests) <= MAX_REQUEST_HARD) { - req = smb_do_alloc_request(server, bufsize); - if (req != NULL) - break; - } - -#if 0 - /* - * Try to free up at least one request in order to stay - * below the hard limit - */ - if (nfs_try_to_free_pages(server)) - continue; - - if (fatal_signal_pending(current)) - return ERR_PTR(-ERESTARTSYS); - current->policy = SCHED_YIELD; - schedule(); -#else - /* FIXME: we want something like nfs does above, but that - requires changes to all callers and can wait. */ - break; -#endif - } - return req; -} - -static void smb_free_request(struct smb_request *req) -{ - atomic_dec(&req->rq_server->nr_requests); - if (req->rq_buffer && !(req->rq_flags & SMB_REQ_STATIC)) - kfree(req->rq_buffer); - kfree(req->rq_trans2buffer); - kmem_cache_free(req_cachep, req); -} - -/* - * What prevents a rget to race with a rput? The count must never drop to zero - * while it is in use. Only rput if it is ok that it is free'd. - */ -static void smb_rget(struct smb_request *req) -{ - atomic_inc(&req->rq_count); -} -void smb_rput(struct smb_request *req) -{ - if (atomic_dec_and_test(&req->rq_count)) { - list_del_init(&req->rq_queue); - smb_free_request(req); - } -} - -/* setup to receive the data part of the SMB */ -static int smb_setup_bcc(struct smb_request *req) -{ - int result = 0; - req->rq_rlen = smb_len(req->rq_header) + 4 - req->rq_bytes_recvd; - - if (req->rq_rlen > req->rq_bufsize) { - PARANOIA("Packet too large %d > %d\n", - req->rq_rlen, req->rq_bufsize); - return -ENOBUFS; - } - - req->rq_iov[0].iov_base = req->rq_buffer; - req->rq_iov[0].iov_len = req->rq_rlen; - req->rq_iovlen = 1; - - return result; -} - -/* - * Prepare a "normal" request structure. - */ -static int smb_setup_request(struct smb_request *req) -{ - int len = smb_len(req->rq_header) + 4; - req->rq_slen = len; - - /* if we expect a data part in the reply we set the iov's to read it */ - if (req->rq_resp_bcc) - req->rq_setup_read = smb_setup_bcc; - - /* This tries to support re-using the same request */ - req->rq_bytes_sent = 0; - req->rq_rcls = 0; - req->rq_err = 0; - req->rq_errno = 0; - req->rq_fragment = 0; - kfree(req->rq_trans2buffer); - req->rq_trans2buffer = NULL; - - return 0; -} - -/* - * Prepare a transaction2 request structure - */ -static int smb_setup_trans2request(struct smb_request *req) -{ - struct smb_sb_info *server = req->rq_server; - int mparam, mdata; - static unsigned char padding[4]; - - /* I know the following is very ugly, but I want to build the - smb packet as efficiently as possible. */ - - const int smb_parameters = 15; - const int header = SMB_HEADER_LEN + 2 * smb_parameters + 2; - const int oparam = ALIGN(header + 3, sizeof(u32)); - const int odata = ALIGN(oparam + req->rq_lparm, sizeof(u32)); - const int bcc = (req->rq_data ? odata + req->rq_ldata : - oparam + req->rq_lparm) - header; - - if ((bcc + oparam) > server->opt.max_xmit) - return -ENOMEM; - smb_setup_header(req, SMBtrans2, smb_parameters, bcc); - - /* - * max parameters + max data + max setup == bufsize to make NT4 happy - * and not abort the transfer or split into multiple responses. It also - * makes smbfs happy as handling packets larger than the buffer size - * is extra work. - * - * OS/2 is probably going to hate me for this ... - */ - mparam = SMB_TRANS2_MAX_PARAM; - mdata = req->rq_bufsize - mparam; - - mdata = server->opt.max_xmit - mparam - 100; - if (mdata < 1024) { - mdata = 1024; - mparam = 20; - } - -#if 0 - /* NT/win2k has ~4k max_xmit, so with this we request more than it wants - to return as one SMB. Useful for testing the fragmented trans2 - handling. */ - mdata = 8192; -#endif - - WSET(req->rq_header, smb_tpscnt, req->rq_lparm); - WSET(req->rq_header, smb_tdscnt, req->rq_ldata); - WSET(req->rq_header, smb_mprcnt, mparam); - WSET(req->rq_header, smb_mdrcnt, mdata); - WSET(req->rq_header, smb_msrcnt, 0); /* max setup always 0 ? */ - WSET(req->rq_header, smb_flags, 0); - DSET(req->rq_header, smb_timeout, 0); - WSET(req->rq_header, smb_pscnt, req->rq_lparm); - WSET(req->rq_header, smb_psoff, oparam - 4); - WSET(req->rq_header, smb_dscnt, req->rq_ldata); - WSET(req->rq_header, smb_dsoff, req->rq_data ? odata - 4 : 0); - *(req->rq_header + smb_suwcnt) = 0x01; /* setup count */ - *(req->rq_header + smb_suwcnt + 1) = 0x00; /* reserved */ - WSET(req->rq_header, smb_setup0, req->rq_trans2_command); - - req->rq_iovlen = 2; - req->rq_iov[0].iov_base = (void *) req->rq_header; - req->rq_iov[0].iov_len = oparam; - req->rq_iov[1].iov_base = (req->rq_parm==NULL) ? padding : req->rq_parm; - req->rq_iov[1].iov_len = req->rq_lparm; - req->rq_slen = oparam + req->rq_lparm; - - if (req->rq_data) { - req->rq_iovlen += 2; - req->rq_iov[2].iov_base = padding; - req->rq_iov[2].iov_len = odata - oparam - req->rq_lparm; - req->rq_iov[3].iov_base = req->rq_data; - req->rq_iov[3].iov_len = req->rq_ldata; - req->rq_slen = odata + req->rq_ldata; - } - - /* always a data part for trans2 replies */ - req->rq_setup_read = smb_setup_bcc; - - return 0; -} - -/* - * Add a request and tell smbiod to process it - */ -int smb_add_request(struct smb_request *req) -{ - long timeleft; - struct smb_sb_info *server = req->rq_server; - int result = 0; - - smb_setup_request(req); - if (req->rq_trans2_command) { - if (req->rq_buffer == NULL) { - PARANOIA("trans2 attempted without response buffer!\n"); - return -EIO; - } - result = smb_setup_trans2request(req); - } - if (result < 0) - return result; - -#ifdef SMB_DEBUG_PACKET_SIZE - add_xmit_stats(req); -#endif - - /* add 'req' to the queue of requests */ - if (smb_lock_server_interruptible(server)) - return -EINTR; - - /* - * Try to send the request as the process. If that fails we queue the - * request and let smbiod send it later. - */ - - /* FIXME: each server has a number on the maximum number of parallel - requests. 10, 50 or so. We should not allow more requests to be - active. */ - if (server->mid > 0xf000) - server->mid = 0; - req->rq_mid = server->mid++; - WSET(req->rq_header, smb_mid, req->rq_mid); - - result = 0; - if (server->state == CONN_VALID) { - if (list_empty(&server->xmitq)) - result = smb_request_send_req(req); - if (result < 0) { - /* Connection lost? */ - server->conn_error = result; - server->state = CONN_INVALID; - } - } - if (result != 1) - list_add_tail(&req->rq_queue, &server->xmitq); - smb_rget(req); - - if (server->state != CONN_VALID) - smbiod_retry(server); - - smb_unlock_server(server); - - smbiod_wake_up(); - - timeleft = wait_event_interruptible_timeout(req->rq_wait, - req->rq_flags & SMB_REQ_RECEIVED, 30*HZ); - if (!timeleft || signal_pending(current)) { - /* - * On timeout or on interrupt we want to try and remove the - * request from the recvq/xmitq. - * First check if the request is still part of a queue. (May - * have been removed by some error condition) - */ - smb_lock_server(server); - if (!list_empty(&req->rq_queue)) { - list_del_init(&req->rq_queue); - smb_rput(req); - } - smb_unlock_server(server); - } - - if (!timeleft) { - PARANOIA("request [%p, mid=%d] timed out!\n", - req, req->rq_mid); - VERBOSE("smb_com: %02x\n", *(req->rq_header + smb_com)); - VERBOSE("smb_rcls: %02x\n", *(req->rq_header + smb_rcls)); - VERBOSE("smb_flg: %02x\n", *(req->rq_header + smb_flg)); - VERBOSE("smb_tid: %04x\n", WVAL(req->rq_header, smb_tid)); - VERBOSE("smb_pid: %04x\n", WVAL(req->rq_header, smb_pid)); - VERBOSE("smb_uid: %04x\n", WVAL(req->rq_header, smb_uid)); - VERBOSE("smb_mid: %04x\n", WVAL(req->rq_header, smb_mid)); - VERBOSE("smb_wct: %02x\n", *(req->rq_header + smb_wct)); - - req->rq_rcls = ERRSRV; - req->rq_err = ERRtimeout; - - /* Just in case it was "stuck" */ - smbiod_wake_up(); - } - VERBOSE("woke up, rcls=%d\n", req->rq_rcls); - - if (req->rq_rcls != 0) - req->rq_errno = smb_errno(req); - if (signal_pending(current)) - req->rq_errno = -ERESTARTSYS; - return req->rq_errno; -} - -/* - * Send a request and place it on the recvq if successfully sent. - * Must be called with the server lock held. - */ -static int smb_request_send_req(struct smb_request *req) -{ - struct smb_sb_info *server = req->rq_server; - int result; - - if (req->rq_bytes_sent == 0) { - WSET(req->rq_header, smb_tid, server->opt.tid); - WSET(req->rq_header, smb_pid, 1); - WSET(req->rq_header, smb_uid, server->opt.server_uid); - } - - result = smb_send_request(req); - if (result < 0 && result != -EAGAIN) - goto out; - - result = 0; - if (!(req->rq_flags & SMB_REQ_TRANSMITTED)) - goto out; - - list_move_tail(&req->rq_queue, &server->recvq); - result = 1; -out: - return result; -} - -/* - * Sends one request for this server. (smbiod) - * Must be called with the server lock held. - * Returns: <0 on error - * 0 if no request could be completely sent - * 1 if all data for one request was sent - */ -int smb_request_send_server(struct smb_sb_info *server) -{ - struct list_head *head; - struct smb_request *req; - int result; - - if (server->state != CONN_VALID) - return 0; - - /* dequeue first request, if any */ - req = NULL; - head = server->xmitq.next; - if (head != &server->xmitq) { - req = list_entry(head, struct smb_request, rq_queue); - } - if (!req) - return 0; - - result = smb_request_send_req(req); - if (result < 0) { - server->conn_error = result; - list_move(&req->rq_queue, &server->xmitq); - result = -EIO; - goto out; - } - -out: - return result; -} - -/* - * Try to find a request matching this "mid". Typically the first entry will - * be the matching one. - */ -static struct smb_request *find_request(struct smb_sb_info *server, int mid) -{ - struct list_head *tmp; - struct smb_request *req = NULL; - - list_for_each(tmp, &server->recvq) { - req = list_entry(tmp, struct smb_request, rq_queue); - if (req->rq_mid == mid) { - break; - } - req = NULL; - } - - if (!req) { - VERBOSE("received reply with mid %d but no request!\n", - WVAL(server->header, smb_mid)); - server->rstate = SMB_RECV_DROP; - } - - return req; -} - -/* - * Called when we have read the smb header and believe this is a response. - */ -static int smb_init_request(struct smb_sb_info *server, struct smb_request *req) -{ - int hdrlen, wct; - - memcpy(req->rq_header, server->header, SMB_HEADER_LEN); - - wct = *(req->rq_header + smb_wct); - if (wct > 20) { - PARANOIA("wct too large, %d > 20\n", wct); - server->rstate = SMB_RECV_DROP; - return 0; - } - - req->rq_resp_wct = wct; - hdrlen = SMB_HEADER_LEN + wct*2 + 2; - VERBOSE("header length: %d smb_wct: %2d\n", hdrlen, wct); - - req->rq_bytes_recvd = SMB_HEADER_LEN; - req->rq_rlen = hdrlen; - req->rq_iov[0].iov_base = req->rq_header; - req->rq_iov[0].iov_len = hdrlen; - req->rq_iovlen = 1; - server->rstate = SMB_RECV_PARAM; - -#ifdef SMB_DEBUG_PACKET_SIZE - add_recv_stats(smb_len(server->header)); -#endif - return 0; -} - -/* - * Reads the SMB parameters - */ -static int smb_recv_param(struct smb_sb_info *server, struct smb_request *req) -{ - int result; - - result = smb_receive(server, req); - if (result < 0) - return result; - if (req->rq_bytes_recvd < req->rq_rlen) - return 0; - - VERBOSE("result: %d smb_bcc: %04x\n", result, - WVAL(req->rq_header, SMB_HEADER_LEN + - (*(req->rq_header + smb_wct) * 2))); - - result = 0; - req->rq_iov[0].iov_base = NULL; - req->rq_rlen = 0; - if (req->rq_callback) - req->rq_callback(req); - else if (req->rq_setup_read) - result = req->rq_setup_read(req); - if (result < 0) { - server->rstate = SMB_RECV_DROP; - return result; - } - - server->rstate = req->rq_rlen > 0 ? SMB_RECV_DATA : SMB_RECV_END; - - req->rq_bytes_recvd = 0; // recvd out of the iov - - VERBOSE("rlen: %d\n", req->rq_rlen); - if (req->rq_rlen < 0) { - PARANOIA("Parameters read beyond end of packet!\n"); - server->rstate = SMB_RECV_END; - return -EIO; - } - return 0; -} - -/* - * Reads the SMB data - */ -static int smb_recv_data(struct smb_sb_info *server, struct smb_request *req) -{ - int result; - - result = smb_receive(server, req); - if (result < 0) - goto out; - if (req->rq_bytes_recvd < req->rq_rlen) - goto out; - server->rstate = SMB_RECV_END; -out: - VERBOSE("result: %d\n", result); - return result; -} - -/* - * Receive a transaction2 response - * Return: 0 if the response has been fully read - * 1 if there are further "fragments" to read - * <0 if there is an error - */ -static int smb_recv_trans2(struct smb_sb_info *server, struct smb_request *req) -{ - unsigned char *inbuf; - unsigned int parm_disp, parm_offset, parm_count, parm_tot; - unsigned int data_disp, data_offset, data_count, data_tot; - int hdrlen = SMB_HEADER_LEN + req->rq_resp_wct*2 - 2; - - VERBOSE("handling trans2\n"); - - inbuf = req->rq_header; - data_tot = WVAL(inbuf, smb_tdrcnt); - parm_tot = WVAL(inbuf, smb_tprcnt); - parm_disp = WVAL(inbuf, smb_prdisp); - parm_offset = WVAL(inbuf, smb_proff); - parm_count = WVAL(inbuf, smb_prcnt); - data_disp = WVAL(inbuf, smb_drdisp); - data_offset = WVAL(inbuf, smb_droff); - data_count = WVAL(inbuf, smb_drcnt); - - /* Modify offset for the split header/buffer we use */ - if (data_count || data_offset) { - if (unlikely(data_offset < hdrlen)) - goto out_bad_data; - else - data_offset -= hdrlen; - } - if (parm_count || parm_offset) { - if (unlikely(parm_offset < hdrlen)) - goto out_bad_parm; - else - parm_offset -= hdrlen; - } - - if (parm_count == parm_tot && data_count == data_tot) { - /* - * This packet has all the trans2 data. - * - * We setup the request so that this will be the common - * case. It may be a server error to not return a - * response that fits. - */ - VERBOSE("single trans2 response " - "dcnt=%u, pcnt=%u, doff=%u, poff=%u\n", - data_count, parm_count, - data_offset, parm_offset); - req->rq_ldata = data_count; - req->rq_lparm = parm_count; - req->rq_data = req->rq_buffer + data_offset; - req->rq_parm = req->rq_buffer + parm_offset; - if (unlikely(parm_offset + parm_count > req->rq_rlen)) - goto out_bad_parm; - if (unlikely(data_offset + data_count > req->rq_rlen)) - goto out_bad_data; - return 0; - } - - VERBOSE("multi trans2 response " - "frag=%d, dcnt=%u, pcnt=%u, doff=%u, poff=%u\n", - req->rq_fragment, - data_count, parm_count, - data_offset, parm_offset); - - if (!req->rq_fragment) { - int buf_len; - - /* We got the first trans2 fragment */ - req->rq_fragment = 1; - req->rq_total_data = data_tot; - req->rq_total_parm = parm_tot; - req->rq_ldata = 0; - req->rq_lparm = 0; - - buf_len = data_tot + parm_tot; - if (buf_len > SMB_MAX_PACKET_SIZE) - goto out_too_long; - - req->rq_trans2bufsize = buf_len; - req->rq_trans2buffer = kzalloc(buf_len, GFP_NOFS); - if (!req->rq_trans2buffer) - goto out_no_mem; - - req->rq_parm = req->rq_trans2buffer; - req->rq_data = req->rq_trans2buffer + parm_tot; - } else if (unlikely(req->rq_total_data < data_tot || - req->rq_total_parm < parm_tot)) - goto out_data_grew; - - if (unlikely(parm_disp + parm_count > req->rq_total_parm || - parm_offset + parm_count > req->rq_rlen)) - goto out_bad_parm; - if (unlikely(data_disp + data_count > req->rq_total_data || - data_offset + data_count > req->rq_rlen)) - goto out_bad_data; - - inbuf = req->rq_buffer; - memcpy(req->rq_parm + parm_disp, inbuf + parm_offset, parm_count); - memcpy(req->rq_data + data_disp, inbuf + data_offset, data_count); - - req->rq_ldata += data_count; - req->rq_lparm += parm_count; - - /* - * Check whether we've received all of the data. Note that - * we use the packet totals -- total lengths might shrink! - */ - if (req->rq_ldata >= data_tot && req->rq_lparm >= parm_tot) { - req->rq_ldata = data_tot; - req->rq_lparm = parm_tot; - return 0; - } - return 1; - -out_too_long: - printk(KERN_ERR "smb_trans2: data/param too long, data=%u, parm=%u\n", - data_tot, parm_tot); - goto out_EIO; -out_no_mem: - printk(KERN_ERR "smb_trans2: couldn't allocate data area of %d bytes\n", - req->rq_trans2bufsize); - req->rq_errno = -ENOMEM; - goto out; -out_data_grew: - printk(KERN_ERR "smb_trans2: data/params grew!\n"); - goto out_EIO; -out_bad_parm: - printk(KERN_ERR "smb_trans2: invalid parms, disp=%u, cnt=%u, tot=%u, ofs=%u\n", - parm_disp, parm_count, parm_tot, parm_offset); - goto out_EIO; -out_bad_data: - printk(KERN_ERR "smb_trans2: invalid data, disp=%u, cnt=%u, tot=%u, ofs=%u\n", - data_disp, data_count, data_tot, data_offset); -out_EIO: - req->rq_errno = -EIO; -out: - return req->rq_errno; -} - -/* - * State machine for receiving responses. We handle the fact that we can't - * read the full response in one try by having states telling us how much we - * have read. - * - * Must be called with the server lock held (only called from smbiod). - * - * Return: <0 on error - */ -int smb_request_recv(struct smb_sb_info *server) -{ - struct smb_request *req = NULL; - int result = 0; - - if (smb_recv_available(server) <= 0) - return 0; - - VERBOSE("state: %d\n", server->rstate); - switch (server->rstate) { - case SMB_RECV_DROP: - result = smb_receive_drop(server); - if (result < 0) - break; - if (server->rstate == SMB_RECV_DROP) - break; - server->rstate = SMB_RECV_START; - /* fallthrough */ - case SMB_RECV_START: - server->smb_read = 0; - server->rstate = SMB_RECV_HEADER; - /* fallthrough */ - case SMB_RECV_HEADER: - result = smb_receive_header(server); - if (result < 0) - break; - if (server->rstate == SMB_RECV_HEADER) - break; - if (! (*(server->header + smb_flg) & SMB_FLAGS_REPLY) ) { - server->rstate = SMB_RECV_REQUEST; - break; - } - if (server->rstate != SMB_RECV_HCOMPLETE) - break; - /* fallthrough */ - case SMB_RECV_HCOMPLETE: - req = find_request(server, WVAL(server->header, smb_mid)); - if (!req) - break; - smb_init_request(server, req); - req->rq_rcls = *(req->rq_header + smb_rcls); - req->rq_err = WVAL(req->rq_header, smb_err); - if (server->rstate != SMB_RECV_PARAM) - break; - /* fallthrough */ - case SMB_RECV_PARAM: - if (!req) - req = find_request(server,WVAL(server->header,smb_mid)); - if (!req) - break; - result = smb_recv_param(server, req); - if (result < 0) - break; - if (server->rstate != SMB_RECV_DATA) - break; - /* fallthrough */ - case SMB_RECV_DATA: - if (!req) - req = find_request(server,WVAL(server->header,smb_mid)); - if (!req) - break; - result = smb_recv_data(server, req); - if (result < 0) - break; - break; - - /* We should never be called with any of these states */ - case SMB_RECV_END: - case SMB_RECV_REQUEST: - BUG(); - } - - if (result < 0) { - /* We saw an error */ - return result; - } - - if (server->rstate != SMB_RECV_END) - return 0; - - result = 0; - if (req->rq_trans2_command && req->rq_rcls == SUCCESS) - result = smb_recv_trans2(server, req); - - /* - * Response completely read. Drop any extra bytes sent by the server. - * (Yes, servers sometimes add extra bytes to responses) - */ - VERBOSE("smb_len: %d smb_read: %d\n", - server->smb_len, server->smb_read); - if (server->smb_read < server->smb_len) - smb_receive_drop(server); - - server->rstate = SMB_RECV_START; - - if (!result) { - list_del_init(&req->rq_queue); - req->rq_flags |= SMB_REQ_RECEIVED; - smb_rput(req); - wake_up_interruptible(&req->rq_wait); - } - return 0; -} diff --git a/drivers/staging/smbfs/request.h b/drivers/staging/smbfs/request.h deleted file mode 100644 index efb21451e7c9..000000000000 --- a/drivers/staging/smbfs/request.h +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include -#include - -struct smb_request { - struct list_head rq_queue; /* recvq or xmitq for the server */ - - atomic_t rq_count; - - wait_queue_head_t rq_wait; - int rq_flags; - int rq_mid; /* multiplex ID, set by request.c */ - - struct smb_sb_info *rq_server; - - /* header + word count + parameter words + byte count */ - unsigned char rq_header[SMB_HEADER_LEN + 20*2 + 2]; - - int rq_bufsize; - unsigned char *rq_buffer; - - /* FIXME: this is not good enough for merging IO requests. */ - unsigned char *rq_page; - int rq_rsize; - - int rq_resp_wct; - int rq_resp_bcc; - - int rq_rlen; - int rq_bytes_recvd; - - int rq_slen; - int rq_bytes_sent; - - int rq_iovlen; - struct kvec rq_iov[4]; - - int (*rq_setup_read) (struct smb_request *); - void (*rq_callback) (struct smb_request *); - - /* ------ trans2 stuff ------ */ - - u16 rq_trans2_command; /* 0 if not a trans2 request */ - unsigned int rq_ldata; - unsigned char *rq_data; - unsigned int rq_lparm; - unsigned char *rq_parm; - - int rq_fragment; - u32 rq_total_data; - u32 rq_total_parm; - int rq_trans2bufsize; - unsigned char *rq_trans2buffer; - - /* ------ response ------ */ - - unsigned short rq_rcls; - unsigned short rq_err; - int rq_errno; -}; - -#define SMB_REQ_STATIC 0x0001 /* rq_buffer is static */ -#define SMB_REQ_NORETRY 0x0002 /* request is invalid after retry */ - -#define SMB_REQ_TRANSMITTED 0x4000 /* all data has been sent */ -#define SMB_REQ_RECEIVED 0x8000 /* reply received, smbiod is done */ - -#define xSMB_REQ_NOREPLY 0x0004 /* we don't want the reply (if any) */ -#define xSMB_REQ_NORECEIVER 0x0008 /* caller doesn't wait for response */ diff --git a/drivers/staging/smbfs/smb.h b/drivers/staging/smbfs/smb.h deleted file mode 100644 index 82fefddc5987..000000000000 --- a/drivers/staging/smbfs/smb.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * smb.h - * - * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke - * Copyright (C) 1997 by Volker Lendecke - * - */ - -#ifndef _LINUX_SMB_H -#define _LINUX_SMB_H - -#include -#include -#ifdef __KERNEL__ -#include -#endif - -enum smb_protocol { - SMB_PROTOCOL_NONE, - SMB_PROTOCOL_CORE, - SMB_PROTOCOL_COREPLUS, - SMB_PROTOCOL_LANMAN1, - SMB_PROTOCOL_LANMAN2, - SMB_PROTOCOL_NT1 -}; - -enum smb_case_hndl { - SMB_CASE_DEFAULT, - SMB_CASE_LOWER, - SMB_CASE_UPPER -}; - -struct smb_dskattr { - __u16 total; - __u16 allocblocks; - __u16 blocksize; - __u16 free; -}; - -struct smb_conn_opt { - - /* The socket */ - unsigned int fd; - - enum smb_protocol protocol; - enum smb_case_hndl case_handling; - - /* Connection-Options */ - - __u32 max_xmit; - __u16 server_uid; - __u16 tid; - - /* The following are LANMAN 1.0 options */ - __u16 secmode; - __u16 maxmux; - __u16 maxvcs; - __u16 rawmode; - __u32 sesskey; - - /* The following are NT LM 0.12 options */ - __u32 maxraw; - __u32 capabilities; - __s16 serverzone; -}; - -#ifdef __KERNEL__ - -#define SMB_NLS_MAXNAMELEN 20 -struct smb_nls_codepage { - char local_name[SMB_NLS_MAXNAMELEN]; - char remote_name[SMB_NLS_MAXNAMELEN]; -}; - - -#define SMB_MAXNAMELEN 255 -#define SMB_MAXPATHLEN 1024 - -/* - * Contains all relevant data on a SMB networked file. - */ -struct smb_fattr { - __u16 attr; - - unsigned long f_ino; - umode_t f_mode; - nlink_t f_nlink; - uid_t f_uid; - gid_t f_gid; - dev_t f_rdev; - loff_t f_size; - struct timespec f_atime; - struct timespec f_mtime; - struct timespec f_ctime; - unsigned long f_blocks; - int f_unix; -}; - -enum smb_conn_state { - CONN_VALID, /* everything's fine */ - CONN_INVALID, /* Something went wrong, but did not - try to reconnect yet. */ - CONN_RETRIED, /* Tried a reconnection, but was refused */ - CONN_RETRYING /* Currently trying to reconnect */ -}; - -#define SMB_HEADER_LEN 37 /* includes everything up to, but not - * including smb_bcc */ - -#define SMB_INITIAL_PACKET_SIZE 4000 -#define SMB_MAX_PACKET_SIZE 32768 - -/* reserve this much space for trans2 parameters. Shouldn't have to be more - than 10 or so, but OS/2 seems happier like this. */ -#define SMB_TRANS2_MAX_PARAM 64 - -#endif -#endif diff --git a/drivers/staging/smbfs/smb_debug.h b/drivers/staging/smbfs/smb_debug.h deleted file mode 100644 index fc4b1a5dd755..000000000000 --- a/drivers/staging/smbfs/smb_debug.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Defines some debug macros for smbfs. - */ - -/* This makes a dentry parent/child name pair. Useful for debugging printk's */ -#define DENTRY_PATH(dentry) \ - (dentry)->d_parent->d_name.name,(dentry)->d_name.name - -/* - * safety checks that should never happen ??? - * these are normally enabled. - */ -#ifdef SMBFS_PARANOIA -# define PARANOIA(f, a...) printk(KERN_NOTICE "%s: " f, __func__ , ## a) -#else -# define PARANOIA(f, a...) do { ; } while(0) -#endif - -/* lots of debug messages */ -#ifdef SMBFS_DEBUG_VERBOSE -# define VERBOSE(f, a...) printk(KERN_DEBUG "%s: " f, __func__ , ## a) -#else -# define VERBOSE(f, a...) do { ; } while(0) -#endif - -/* - * "normal" debug messages, but not with a normal DEBUG define ... way - * too common name. - */ -#ifdef SMBFS_DEBUG -#define DEBUG1(f, a...) printk(KERN_DEBUG "%s: " f, __func__ , ## a) -#else -#define DEBUG1(f, a...) do { ; } while(0) -#endif diff --git a/drivers/staging/smbfs/smb_fs.h b/drivers/staging/smbfs/smb_fs.h deleted file mode 100644 index 20a05c188eb9..000000000000 --- a/drivers/staging/smbfs/smb_fs.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * smb_fs.h - * - * Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke - * Copyright (C) 1997 by Volker Lendecke - * - */ - -#ifndef _LINUX_SMB_FS_H -#define _LINUX_SMB_FS_H - -#include "smb.h" - -/* - * ioctl commands - */ -#define SMB_IOC_GETMOUNTUID _IOR('u', 1, __kernel_old_uid_t) -#define SMB_IOC_NEWCONN _IOW('u', 2, struct smb_conn_opt) - -/* __kernel_uid_t can never change, so we have to use __kernel_uid32_t */ -#define SMB_IOC_GETMOUNTUID32 _IOR('u', 3, __kernel_uid32_t) - - -#ifdef __KERNEL__ -#include "smb_fs_i.h" -#include "smb_fs_sb.h" -#include "smb_mount.h" - -#include -#include -#include -#include -#include - -static inline struct smb_sb_info *SMB_SB(struct super_block *sb) -{ - return sb->s_fs_info; -} - -static inline struct smb_inode_info *SMB_I(struct inode *inode) -{ - return container_of(inode, struct smb_inode_info, vfs_inode); -} - -/* macro names are short for word, double-word, long value (?) */ -#define WVAL(buf, pos) (get_unaligned_le16((u8 *)(buf) + (pos))) -#define DVAL(buf, pos) (get_unaligned_le32((u8 *)(buf) + (pos))) -#define LVAL(buf, pos) (get_unaligned_le64((u8 *)(buf) + (pos))) - -#define WSET(buf, pos, val) put_unaligned_le16((val), (u8 *)(buf) + (pos)) -#define DSET(buf, pos, val) put_unaligned_le32((val), (u8 *)(buf) + (pos)) -#define LSET(buf, pos, val) put_unaligned_le64((val), (u8 *)(buf) + (pos)) - -/* where to find the base of the SMB packet proper */ -#define smb_base(buf) ((u8 *)(((u8 *)(buf))+4)) - -/* - * Flags for the in-memory inode - */ -#define SMB_F_LOCALWRITE 0x02 /* file modified locally */ - - -/* NT1 protocol capability bits */ -#define SMB_CAP_RAW_MODE 0x00000001 -#define SMB_CAP_MPX_MODE 0x00000002 -#define SMB_CAP_UNICODE 0x00000004 -#define SMB_CAP_LARGE_FILES 0x00000008 -#define SMB_CAP_NT_SMBS 0x00000010 -#define SMB_CAP_RPC_REMOTE_APIS 0x00000020 -#define SMB_CAP_STATUS32 0x00000040 -#define SMB_CAP_LEVEL_II_OPLOCKS 0x00000080 -#define SMB_CAP_LOCK_AND_READ 0x00000100 -#define SMB_CAP_NT_FIND 0x00000200 -#define SMB_CAP_DFS 0x00001000 -#define SMB_CAP_LARGE_READX 0x00004000 -#define SMB_CAP_LARGE_WRITEX 0x00008000 -#define SMB_CAP_UNIX 0x00800000 /* unofficial ... */ - - -/* - * This is the time we allow an inode, dentry or dir cache to live. It is bad - * for performance to have shorter ttl on an inode than on the cache. It can - * cause refresh on each inode for a dir listing ... one-by-one - */ -#define SMB_MAX_AGE(server) (((server)->mnt->ttl * HZ) / 1000) - -static inline void -smb_age_dentry(struct smb_sb_info *server, struct dentry *dentry) -{ - dentry->d_time = jiffies - SMB_MAX_AGE(server); -} - -struct smb_cache_head { - time_t mtime; /* unused */ - unsigned long time; /* cache age */ - unsigned long end; /* last valid fpos in cache */ - int eof; -}; - -#define SMB_DIRCACHE_SIZE ((int)(PAGE_CACHE_SIZE/sizeof(struct dentry *))) -union smb_dir_cache { - struct smb_cache_head head; - struct dentry *dentry[SMB_DIRCACHE_SIZE]; -}; - -#define SMB_FIRSTCACHE_SIZE ((int)((SMB_DIRCACHE_SIZE * \ - sizeof(struct dentry *) - sizeof(struct smb_cache_head)) / \ - sizeof(struct dentry *))) - -#define SMB_DIRCACHE_START (SMB_DIRCACHE_SIZE - SMB_FIRSTCACHE_SIZE) - -struct smb_cache_control { - struct smb_cache_head head; - struct page *page; - union smb_dir_cache *cache; - unsigned long fpos, ofs; - int filled, valid, idx; -}; - -#define SMB_OPS_NUM_STATIC 5 -struct smb_ops { - int (*read)(struct inode *inode, loff_t offset, int count, - char *data); - int (*write)(struct inode *inode, loff_t offset, int count, const - char *data); - int (*readdir)(struct file *filp, void *dirent, filldir_t filldir, - struct smb_cache_control *ctl); - - int (*getattr)(struct smb_sb_info *server, struct dentry *dir, - struct smb_fattr *fattr); - /* int (*setattr)(...); */ /* setattr is really icky! */ - - int (*truncate)(struct inode *inode, loff_t length); - - - /* --- --- --- end of "static" entries --- --- --- */ - - int (*convert)(unsigned char *output, int olen, - const unsigned char *input, int ilen, - struct nls_table *nls_from, - struct nls_table *nls_to); -}; - -static inline int -smb_is_open(struct inode *i) -{ - return (SMB_I(i)->open == server_from_inode(i)->generation); -} - -extern void smb_install_null_ops(struct smb_ops *); -#endif /* __KERNEL__ */ - -#endif /* _LINUX_SMB_FS_H */ diff --git a/drivers/staging/smbfs/smb_fs_i.h b/drivers/staging/smbfs/smb_fs_i.h deleted file mode 100644 index 8ccf4eca2c3d..000000000000 --- a/drivers/staging/smbfs/smb_fs_i.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * smb_fs_i.h - * - * Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke - * Copyright (C) 1997 by Volker Lendecke - * - */ - -#ifndef _LINUX_SMB_FS_I -#define _LINUX_SMB_FS_I - -#include -#include - -/* - * smb fs inode data (in memory only) - */ -struct smb_inode_info { - - /* - * file handles are local to a connection. A file is open if - * (open == generation). - */ - unsigned int open; /* open generation */ - __u16 fileid; /* What id to handle a file with? */ - __u16 attr; /* Attribute fields, DOS value */ - - __u16 access; /* Access mode */ - __u16 flags; - unsigned long oldmtime; /* last time refreshed */ - unsigned long closed; /* timestamp when closed */ - unsigned openers; /* number of fileid users */ - - struct inode vfs_inode; /* must be at the end */ -}; - -#endif diff --git a/drivers/staging/smbfs/smb_fs_sb.h b/drivers/staging/smbfs/smb_fs_sb.h deleted file mode 100644 index ca058afda900..000000000000 --- a/drivers/staging/smbfs/smb_fs_sb.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * smb_fs_sb.h - * - * Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke - * Copyright (C) 1997 by Volker Lendecke - * - */ - -#ifndef _SMB_FS_SB -#define _SMB_FS_SB - -#include -#include -#include "smb.h" - -/* - * Upper limit on the total number of active smb_request structs. - */ -#define MAX_REQUEST_HARD 256 - -enum smb_receive_state { - SMB_RECV_START, /* No data read, looking for length + sig */ - SMB_RECV_HEADER, /* Reading the header data */ - SMB_RECV_HCOMPLETE, /* Done with the header */ - SMB_RECV_PARAM, /* Reading parameter words */ - SMB_RECV_DATA, /* Reading data bytes */ - SMB_RECV_END, /* End of request */ - SMB_RECV_DROP, /* Dropping this SMB */ - SMB_RECV_REQUEST, /* Received a request and not a reply */ -}; - -/* structure access macros */ -#define server_from_inode(inode) SMB_SB((inode)->i_sb) -#define server_from_dentry(dentry) SMB_SB((dentry)->d_sb) -#define SB_of(server) ((server)->super_block) - -struct smb_sb_info { - /* List of all smbfs superblocks */ - struct list_head entry; - - enum smb_conn_state state; - struct file * sock_file; - int conn_error; - enum smb_receive_state rstate; - - atomic_t nr_requests; - struct list_head xmitq; - struct list_head recvq; - u16 mid; - - struct smb_mount_data_kernel *mnt; - - /* Connections are counted. Each time a new socket arrives, - * generation is incremented. - */ - unsigned int generation; - struct pid *conn_pid; - struct smb_conn_opt opt; - wait_queue_head_t conn_wq; - int conn_complete; - struct semaphore sem; - - unsigned char header[SMB_HEADER_LEN + 20*2 + 2]; - u32 header_len; - u32 smb_len; - u32 smb_read; - - /* We use our own data_ready callback, but need the original one */ - void *data_ready; - - /* nls pointers for codepage conversions */ - struct nls_table *remote_nls; - struct nls_table *local_nls; - - struct smb_ops *ops; - - struct super_block *super_block; - - struct backing_dev_info bdi; -}; - -static inline int -smb_lock_server_interruptible(struct smb_sb_info *server) -{ - return down_interruptible(&(server->sem)); -} - -static inline void -smb_lock_server(struct smb_sb_info *server) -{ - down(&(server->sem)); -} - -static inline void -smb_unlock_server(struct smb_sb_info *server) -{ - up(&(server->sem)); -} - -#endif diff --git a/drivers/staging/smbfs/smb_mount.h b/drivers/staging/smbfs/smb_mount.h deleted file mode 100644 index d10f00cb5703..000000000000 --- a/drivers/staging/smbfs/smb_mount.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * smb_mount.h - * - * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke - * Copyright (C) 1997 by Volker Lendecke - * - */ - -#ifndef _LINUX_SMB_MOUNT_H -#define _LINUX_SMB_MOUNT_H - -#include - -#define SMB_MOUNT_VERSION 6 - -struct smb_mount_data { - int version; - __kernel_uid_t mounted_uid; /* Who may umount() this filesystem? */ - __kernel_uid_t uid; - __kernel_gid_t gid; - __kernel_mode_t file_mode; - __kernel_mode_t dir_mode; -}; - - -#ifdef __KERNEL__ - -/* "vers" in big-endian */ -#define SMB_MOUNT_ASCII 0x76657273 - -#define SMB_MOUNT_OLDVERSION 6 -#undef SMB_MOUNT_VERSION -#define SMB_MOUNT_VERSION 7 - -/* flags */ -#define SMB_MOUNT_WIN95 0x0001 /* Win 95 server */ -#define SMB_MOUNT_OLDATTR 0x0002 /* Use core getattr (Win 95 speedup) */ -#define SMB_MOUNT_DIRATTR 0x0004 /* Use find_first for getattr */ -#define SMB_MOUNT_CASE 0x0008 /* Be case sensitive */ -#define SMB_MOUNT_UNICODE 0x0010 /* Server talks unicode */ -#define SMB_MOUNT_UID 0x0020 /* Use user specified uid */ -#define SMB_MOUNT_GID 0x0040 /* Use user specified gid */ -#define SMB_MOUNT_FMODE 0x0080 /* Use user specified file mode */ -#define SMB_MOUNT_DMODE 0x0100 /* Use user specified dir mode */ - -struct smb_mount_data_kernel { - int version; - - uid_t mounted_uid; /* Who may umount() this filesystem? */ - uid_t uid; - gid_t gid; - mode_t file_mode; - mode_t dir_mode; - - u32 flags; - - /* maximum age in jiffies (inode, dentry and dircache) */ - int ttl; - - struct smb_nls_codepage codepage; -}; - -#endif - -#endif diff --git a/drivers/staging/smbfs/smbfs.txt b/drivers/staging/smbfs/smbfs.txt deleted file mode 100644 index 194fb0decd2c..000000000000 --- a/drivers/staging/smbfs/smbfs.txt +++ /dev/null @@ -1,8 +0,0 @@ -Smbfs is a filesystem that implements the SMB protocol, which is the -protocol used by Windows for Workgroups, Windows 95 and Windows NT. -Smbfs was inspired by Samba, the program written by Andrew Tridgell -that turns any Unix host into a file server for DOS or Windows clients. - -Smbfs is a SMB client, but uses parts of samba for its operation. For -more info on samba, including documentation, please go to -http://www.samba.org/ and then on to your nearest mirror. diff --git a/drivers/staging/smbfs/smbiod.c b/drivers/staging/smbfs/smbiod.c deleted file mode 100644 index ec998920f8d9..000000000000 --- a/drivers/staging/smbfs/smbiod.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * smbiod.c - * - * Copyright (C) 2000, Charles Loep / Corel Corp. - * Copyright (C) 2001, Urban Widmark - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "smb_fs.h" -#include "smbno.h" -#include "smb_mount.h" -#include "smb_debug.h" -#include "request.h" -#include "proto.h" - -enum smbiod_state { - SMBIOD_DEAD, - SMBIOD_STARTING, - SMBIOD_RUNNING, -}; - -static enum smbiod_state smbiod_state = SMBIOD_DEAD; -static struct task_struct *smbiod_thread; -static DECLARE_WAIT_QUEUE_HEAD(smbiod_wait); -static LIST_HEAD(smb_servers); -static DEFINE_SPINLOCK(servers_lock); - -#define SMBIOD_DATA_READY (1<<0) -static unsigned long smbiod_flags; - -static int smbiod(void *); -static int smbiod_start(void); - -/* - * called when there's work for us to do - */ -void smbiod_wake_up(void) -{ - if (smbiod_state == SMBIOD_DEAD) - return; - set_bit(SMBIOD_DATA_READY, &smbiod_flags); - wake_up_interruptible(&smbiod_wait); -} - -/* - * start smbiod if none is running - */ -static int smbiod_start(void) -{ - struct task_struct *tsk; - int err = 0; - - if (smbiod_state != SMBIOD_DEAD) - return 0; - smbiod_state = SMBIOD_STARTING; - __module_get(THIS_MODULE); - spin_unlock(&servers_lock); - tsk = kthread_run(smbiod, NULL, "smbiod"); - if (IS_ERR(tsk)) { - err = PTR_ERR(tsk); - module_put(THIS_MODULE); - } - - spin_lock(&servers_lock); - if (err < 0) { - smbiod_state = SMBIOD_DEAD; - smbiod_thread = NULL; - } else { - smbiod_state = SMBIOD_RUNNING; - smbiod_thread = tsk; - } - return err; -} - -/* - * register a server & start smbiod if necessary - */ -int smbiod_register_server(struct smb_sb_info *server) -{ - int ret; - spin_lock(&servers_lock); - list_add(&server->entry, &smb_servers); - VERBOSE("%p\n", server); - ret = smbiod_start(); - spin_unlock(&servers_lock); - return ret; -} - -/* - * Unregister a server - * Must be called with the server lock held. - */ -void smbiod_unregister_server(struct smb_sb_info *server) -{ - spin_lock(&servers_lock); - list_del_init(&server->entry); - VERBOSE("%p\n", server); - spin_unlock(&servers_lock); - - smbiod_wake_up(); - smbiod_flush(server); -} - -void smbiod_flush(struct smb_sb_info *server) -{ - struct list_head *tmp, *n; - struct smb_request *req; - - list_for_each_safe(tmp, n, &server->xmitq) { - req = list_entry(tmp, struct smb_request, rq_queue); - req->rq_errno = -EIO; - list_del_init(&req->rq_queue); - smb_rput(req); - wake_up_interruptible(&req->rq_wait); - } - list_for_each_safe(tmp, n, &server->recvq) { - req = list_entry(tmp, struct smb_request, rq_queue); - req->rq_errno = -EIO; - list_del_init(&req->rq_queue); - smb_rput(req); - wake_up_interruptible(&req->rq_wait); - } -} - -/* - * Wake up smbmount and make it reconnect to the server. - * This must be called with the server locked. - * - * FIXME: add smbconnect version to this - */ -int smbiod_retry(struct smb_sb_info *server) -{ - struct list_head *head; - struct smb_request *req; - struct pid *pid = get_pid(server->conn_pid); - int result = 0; - - VERBOSE("state: %d\n", server->state); - if (server->state == CONN_VALID || server->state == CONN_RETRYING) - goto out; - - smb_invalidate_inodes(server); - - /* - * Some requests are meaningless after a retry, so we abort them. - * One example are all requests using 'fileid' since the files are - * closed on retry. - */ - head = server->xmitq.next; - while (head != &server->xmitq) { - req = list_entry(head, struct smb_request, rq_queue); - head = head->next; - - req->rq_bytes_sent = 0; - if (req->rq_flags & SMB_REQ_NORETRY) { - VERBOSE("aborting request %p on xmitq\n", req); - req->rq_errno = -EIO; - list_del_init(&req->rq_queue); - smb_rput(req); - wake_up_interruptible(&req->rq_wait); - } - } - - /* - * FIXME: test the code for retrying request we already sent - */ - head = server->recvq.next; - while (head != &server->recvq) { - req = list_entry(head, struct smb_request, rq_queue); - head = head->next; -#if 0 - if (req->rq_flags & SMB_REQ_RETRY) { - /* must move the request to the xmitq */ - VERBOSE("retrying request %p on recvq\n", req); - list_move(&req->rq_queue, &server->xmitq); - continue; - } -#endif - - VERBOSE("aborting request %p on recvq\n", req); - /* req->rq_rcls = ???; */ /* FIXME: set smb error code too? */ - req->rq_errno = -EIO; - list_del_init(&req->rq_queue); - smb_rput(req); - wake_up_interruptible(&req->rq_wait); - } - - smb_close_socket(server); - - if (!pid) { - /* FIXME: this is fatal, umount? */ - printk(KERN_ERR "smb_retry: no connection process\n"); - server->state = CONN_RETRIED; - goto out; - } - - /* - * Change state so that only one retry per server will be started. - */ - server->state = CONN_RETRYING; - - /* - * Note: use the "priv" flag, as a user process may need to reconnect. - */ - result = kill_pid(pid, SIGUSR1, 1); - if (result) { - /* FIXME: this is most likely fatal, umount? */ - printk(KERN_ERR "smb_retry: signal failed [%d]\n", result); - goto out; - } - VERBOSE("signalled pid %d\n", pid_nr(pid)); - - /* FIXME: The retried requests should perhaps get a "time boost". */ - -out: - put_pid(pid); - return result; -} - -/* - * Currently handles lockingX packets. - */ -static void smbiod_handle_request(struct smb_sb_info *server) -{ - PARANOIA("smbiod got a request ... and we don't implement oplocks!\n"); - server->rstate = SMB_RECV_DROP; -} - -/* - * Do some IO for one server. - */ -static void smbiod_doio(struct smb_sb_info *server) -{ - int result; - int maxwork = 7; - - if (server->state != CONN_VALID) - goto out; - - do { - result = smb_request_recv(server); - if (result < 0) { - server->state = CONN_INVALID; - smbiod_retry(server); - goto out; /* reconnecting is slow */ - } else if (server->rstate == SMB_RECV_REQUEST) - smbiod_handle_request(server); - } while (result > 0 && maxwork-- > 0); - - /* - * If there is more to read then we want to be sure to wake up again. - */ - if (server->state != CONN_VALID) - goto out; - if (smb_recv_available(server) > 0) - set_bit(SMBIOD_DATA_READY, &smbiod_flags); - - do { - result = smb_request_send_server(server); - if (result < 0) { - server->state = CONN_INVALID; - smbiod_retry(server); - goto out; /* reconnecting is slow */ - } - } while (result > 0); - - /* - * If the last request was not sent out we want to wake up again. - */ - if (!list_empty(&server->xmitq)) - set_bit(SMBIOD_DATA_READY, &smbiod_flags); - -out: - return; -} - -/* - * smbiod kernel thread - */ -static int smbiod(void *unused) -{ - VERBOSE("SMB Kernel thread starting (%d) ...\n", current->pid); - - for (;;) { - struct smb_sb_info *server; - struct list_head *pos, *n; - - /* FIXME: Use poll? */ - wait_event_interruptible(smbiod_wait, - test_bit(SMBIOD_DATA_READY, &smbiod_flags)); - if (signal_pending(current)) { - spin_lock(&servers_lock); - smbiod_state = SMBIOD_DEAD; - spin_unlock(&servers_lock); - break; - } - - clear_bit(SMBIOD_DATA_READY, &smbiod_flags); - - spin_lock(&servers_lock); - if (list_empty(&smb_servers)) { - smbiod_state = SMBIOD_DEAD; - spin_unlock(&servers_lock); - break; - } - - list_for_each_safe(pos, n, &smb_servers) { - server = list_entry(pos, struct smb_sb_info, entry); - VERBOSE("checking server %p\n", server); - - if (server->state == CONN_VALID) { - spin_unlock(&servers_lock); - - smb_lock_server(server); - smbiod_doio(server); - smb_unlock_server(server); - - spin_lock(&servers_lock); - } - } - spin_unlock(&servers_lock); - } - - VERBOSE("SMB Kernel thread exiting (%d) ...\n", current->pid); - module_put_and_exit(0); -} diff --git a/drivers/staging/smbfs/smbno.h b/drivers/staging/smbfs/smbno.h deleted file mode 100644 index f99e02d9ffe2..000000000000 --- a/drivers/staging/smbfs/smbno.h +++ /dev/null @@ -1,363 +0,0 @@ -#ifndef _SMBNO_H_ -#define _SMBNO_H_ - -/* these define the attribute byte as seen by DOS */ -#define aRONLY (1L<<0) -#define aHIDDEN (1L<<1) -#define aSYSTEM (1L<<2) -#define aVOLID (1L<<3) -#define aDIR (1L<<4) -#define aARCH (1L<<5) - -/* error classes */ -#define SUCCESS 0 /* The request was successful. */ -#define ERRDOS 0x01 /* Error is from the core DOS operating system set. */ -#define ERRSRV 0x02 /* Error is generated by the server network file manager.*/ -#define ERRHRD 0x03 /* Error is an hardware error. */ -#define ERRCMD 0xFF /* Command was not in the "SMB" format. */ - -/* SMB X/Open error codes for the ERRdos error class */ - -#define ERRbadfunc 1 /* Invalid function (or system call) */ -#define ERRbadfile 2 /* File not found (pathname error) */ -#define ERRbadpath 3 /* Directory not found */ -#define ERRnofids 4 /* Too many open files */ -#define ERRnoaccess 5 /* Access denied */ -#define ERRbadfid 6 /* Invalid fid */ -#define ERRbadmcb 7 /* Memory control blocks destroyed */ -#define ERRnomem 8 /* Out of memory */ -#define ERRbadmem 9 /* Invalid memory block address */ -#define ERRbadenv 10 /* Invalid environment */ -#define ERRbadformat 11 /* Invalid format */ -#define ERRbadaccess 12 /* Invalid open mode */ -#define ERRbaddata 13 /* Invalid data (only from ioctl call) */ -#define ERRres 14 /* reserved */ -#define ERRbaddrive 15 /* Invalid drive */ -#define ERRremcd 16 /* Attempt to delete current directory */ -#define ERRdiffdevice 17 /* rename/move across different filesystems */ -#define ERRnofiles 18 /* no more files found in file search */ -#define ERRbadshare 32 /* Share mode on file conflict with open mode */ -#define ERRlock 33 /* Lock request conflicts with existing lock */ -#define ERRfilexists 80 /* File in operation already exists */ -#define ERRbadpipe 230 /* Named pipe invalid */ -#define ERRpipebusy 231 /* All instances of pipe are busy */ -#define ERRpipeclosing 232 /* named pipe close in progress */ -#define ERRnotconnected 233 /* No process on other end of named pipe */ -#define ERRmoredata 234 /* More data to be returned */ - -#define ERROR_INVALID_PARAMETER 87 -#define ERROR_DISK_FULL 112 -#define ERROR_INVALID_NAME 123 -#define ERROR_DIR_NOT_EMPTY 145 -#define ERROR_NOT_LOCKED 158 -#define ERROR_ALREADY_EXISTS 183 /* see also 80 ? */ -#define ERROR_EAS_DIDNT_FIT 275 /* Extended attributes didn't fit */ -#define ERROR_EAS_NOT_SUPPORTED 282 /* Extended attributes not supported */ - -/* Error codes for the ERRSRV class */ - -#define ERRerror 1 /* Non specific error code */ -#define ERRbadpw 2 /* Bad password */ -#define ERRbadtype 3 /* reserved */ -#define ERRaccess 4 /* No permissions to do the requested operation */ -#define ERRinvnid 5 /* tid invalid */ -#define ERRinvnetname 6 /* Invalid servername */ -#define ERRinvdevice 7 /* Invalid device */ -#define ERRqfull 49 /* Print queue full */ -#define ERRqtoobig 50 /* Queued item too big */ -#define ERRinvpfid 52 /* Invalid print file in smb_fid */ -#define ERRsmbcmd 64 /* Unrecognised command */ -#define ERRsrverror 65 /* smb server internal error */ -#define ERRfilespecs 67 /* fid and pathname invalid combination */ -#define ERRbadlink 68 /* reserved */ -#define ERRbadpermits 69 /* Access specified for a file is not valid */ -#define ERRbadpid 70 /* reserved */ -#define ERRsetattrmode 71 /* attribute mode invalid */ -#define ERRpaused 81 /* Message server paused */ -#define ERRmsgoff 82 /* Not receiving messages */ -#define ERRnoroom 83 /* No room for message */ -#define ERRrmuns 87 /* too many remote usernames */ -#define ERRtimeout 88 /* operation timed out */ -#define ERRnoresource 89 /* No resources currently available for request. */ -#define ERRtoomanyuids 90 /* too many userids */ -#define ERRbaduid 91 /* bad userid */ -#define ERRuseMPX 250 /* temporarily unable to use raw mode, use MPX mode */ -#define ERRuseSTD 251 /* temporarily unable to use raw mode, use std.mode */ -#define ERRcontMPX 252 /* resume MPX mode */ -#define ERRbadPW /* reserved */ -#define ERRnosupport 0xFFFF - -/* Error codes for the ERRHRD class */ - -#define ERRnowrite 19 /* read only media */ -#define ERRbadunit 20 /* Unknown device */ -#define ERRnotready 21 /* Drive not ready */ -#define ERRbadcmd 22 /* Unknown command */ -#define ERRdata 23 /* Data (CRC) error */ -#define ERRbadreq 24 /* Bad request structure length */ -#define ERRseek 25 -#define ERRbadmedia 26 -#define ERRbadsector 27 -#define ERRnopaper 28 -#define ERRwrite 29 /* write fault */ -#define ERRread 30 /* read fault */ -#define ERRgeneral 31 /* General hardware failure */ -#define ERRwrongdisk 34 -#define ERRFCBunavail 35 -#define ERRsharebufexc 36 /* share buffer exceeded */ -#define ERRdiskfull 39 - -/* - * Access modes when opening a file - */ -#define SMB_ACCMASK 0x0003 -#define SMB_O_RDONLY 0x0000 -#define SMB_O_WRONLY 0x0001 -#define SMB_O_RDWR 0x0002 - -/* offsets into message for common items */ -#define smb_com 8 -#define smb_rcls 9 -#define smb_reh 10 -#define smb_err 11 -#define smb_flg 13 -#define smb_flg2 14 -#define smb_reb 13 -#define smb_tid 28 -#define smb_pid 30 -#define smb_uid 32 -#define smb_mid 34 -#define smb_wct 36 -#define smb_vwv 37 -#define smb_vwv0 37 -#define smb_vwv1 39 -#define smb_vwv2 41 -#define smb_vwv3 43 -#define smb_vwv4 45 -#define smb_vwv5 47 -#define smb_vwv6 49 -#define smb_vwv7 51 -#define smb_vwv8 53 -#define smb_vwv9 55 -#define smb_vwv10 57 -#define smb_vwv11 59 -#define smb_vwv12 61 -#define smb_vwv13 63 -#define smb_vwv14 65 - -/* these are the trans2 sub fields for primary requests */ -#define smb_tpscnt smb_vwv0 -#define smb_tdscnt smb_vwv1 -#define smb_mprcnt smb_vwv2 -#define smb_mdrcnt smb_vwv3 -#define smb_msrcnt smb_vwv4 -#define smb_flags smb_vwv5 -#define smb_timeout smb_vwv6 -#define smb_pscnt smb_vwv9 -#define smb_psoff smb_vwv10 -#define smb_dscnt smb_vwv11 -#define smb_dsoff smb_vwv12 -#define smb_suwcnt smb_vwv13 -#define smb_setup smb_vwv14 -#define smb_setup0 smb_setup -#define smb_setup1 (smb_setup+2) -#define smb_setup2 (smb_setup+4) - -/* these are for the secondary requests */ -#define smb_spscnt smb_vwv2 -#define smb_spsoff smb_vwv3 -#define smb_spsdisp smb_vwv4 -#define smb_sdscnt smb_vwv5 -#define smb_sdsoff smb_vwv6 -#define smb_sdsdisp smb_vwv7 -#define smb_sfid smb_vwv8 - -/* and these for responses */ -#define smb_tprcnt smb_vwv0 -#define smb_tdrcnt smb_vwv1 -#define smb_prcnt smb_vwv3 -#define smb_proff smb_vwv4 -#define smb_prdisp smb_vwv5 -#define smb_drcnt smb_vwv6 -#define smb_droff smb_vwv7 -#define smb_drdisp smb_vwv8 - -/* the complete */ -#define SMBmkdir 0x00 /* create directory */ -#define SMBrmdir 0x01 /* delete directory */ -#define SMBopen 0x02 /* open file */ -#define SMBcreate 0x03 /* create file */ -#define SMBclose 0x04 /* close file */ -#define SMBflush 0x05 /* flush file */ -#define SMBunlink 0x06 /* delete file */ -#define SMBmv 0x07 /* rename file */ -#define SMBgetatr 0x08 /* get file attributes */ -#define SMBsetatr 0x09 /* set file attributes */ -#define SMBread 0x0A /* read from file */ -#define SMBwrite 0x0B /* write to file */ -#define SMBlock 0x0C /* lock byte range */ -#define SMBunlock 0x0D /* unlock byte range */ -#define SMBctemp 0x0E /* create temporary file */ -#define SMBmknew 0x0F /* make new file */ -#define SMBchkpth 0x10 /* check directory path */ -#define SMBexit 0x11 /* process exit */ -#define SMBlseek 0x12 /* seek */ -#define SMBtcon 0x70 /* tree connect */ -#define SMBtconX 0x75 /* tree connect and X*/ -#define SMBtdis 0x71 /* tree disconnect */ -#define SMBnegprot 0x72 /* negotiate protocol */ -#define SMBdskattr 0x80 /* get disk attributes */ -#define SMBsearch 0x81 /* search directory */ -#define SMBsplopen 0xC0 /* open print spool file */ -#define SMBsplwr 0xC1 /* write to print spool file */ -#define SMBsplclose 0xC2 /* close print spool file */ -#define SMBsplretq 0xC3 /* return print queue */ -#define SMBsends 0xD0 /* send single block message */ -#define SMBsendb 0xD1 /* send broadcast message */ -#define SMBfwdname 0xD2 /* forward user name */ -#define SMBcancelf 0xD3 /* cancel forward */ -#define SMBgetmac 0xD4 /* get machine name */ -#define SMBsendstrt 0xD5 /* send start of multi-block message */ -#define SMBsendend 0xD6 /* send end of multi-block message */ -#define SMBsendtxt 0xD7 /* send text of multi-block message */ - -/* Core+ protocol */ -#define SMBlockread 0x13 /* Lock a range and read */ -#define SMBwriteunlock 0x14 /* Unlock a range then write */ -#define SMBreadbraw 0x1a /* read a block of data with no smb header */ -#define SMBwritebraw 0x1d /* write a block of data with no smb header */ -#define SMBwritec 0x20 /* secondary write request */ -#define SMBwriteclose 0x2c /* write a file then close it */ - -/* dos extended protocol */ -#define SMBreadBraw 0x1A /* read block raw */ -#define SMBreadBmpx 0x1B /* read block multiplexed */ -#define SMBreadBs 0x1C /* read block (secondary response) */ -#define SMBwriteBraw 0x1D /* write block raw */ -#define SMBwriteBmpx 0x1E /* write block multiplexed */ -#define SMBwriteBs 0x1F /* write block (secondary request) */ -#define SMBwriteC 0x20 /* write complete response */ -#define SMBsetattrE 0x22 /* set file attributes expanded */ -#define SMBgetattrE 0x23 /* get file attributes expanded */ -#define SMBlockingX 0x24 /* lock/unlock byte ranges and X */ -#define SMBtrans 0x25 /* transaction - name, bytes in/out */ -#define SMBtranss 0x26 /* transaction (secondary request/response) */ -#define SMBioctl 0x27 /* IOCTL */ -#define SMBioctls 0x28 /* IOCTL (secondary request/response) */ -#define SMBcopy 0x29 /* copy */ -#define SMBmove 0x2A /* move */ -#define SMBecho 0x2B /* echo */ -#define SMBopenX 0x2D /* open and X */ -#define SMBreadX 0x2E /* read and X */ -#define SMBwriteX 0x2F /* write and X */ -#define SMBsesssetupX 0x73 /* Session Set Up & X (including User Logon) */ -#define SMBtconX 0x75 /* tree connect and X */ -#define SMBffirst 0x82 /* find first */ -#define SMBfunique 0x83 /* find unique */ -#define SMBfclose 0x84 /* find close */ -#define SMBinvalid 0xFE /* invalid command */ - - -/* Extended 2.0 protocol */ -#define SMBtrans2 0x32 /* TRANS2 protocol set */ -#define SMBtranss2 0x33 /* TRANS2 protocol set, secondary command */ -#define SMBfindclose 0x34 /* Terminate a TRANSACT2_FINDFIRST */ -#define SMBfindnclose 0x35 /* Terminate a TRANSACT2_FINDNOTIFYFIRST */ -#define SMBulogoffX 0x74 /* user logoff */ - -/* these are the TRANS2 sub commands */ -#define TRANSACT2_OPEN 0 -#define TRANSACT2_FINDFIRST 1 -#define TRANSACT2_FINDNEXT 2 -#define TRANSACT2_QFSINFO 3 -#define TRANSACT2_SETFSINFO 4 -#define TRANSACT2_QPATHINFO 5 -#define TRANSACT2_SETPATHINFO 6 -#define TRANSACT2_QFILEINFO 7 -#define TRANSACT2_SETFILEINFO 8 -#define TRANSACT2_FSCTL 9 -#define TRANSACT2_IOCTL 10 -#define TRANSACT2_FINDNOTIFYFIRST 11 -#define TRANSACT2_FINDNOTIFYNEXT 12 -#define TRANSACT2_MKDIR 13 - -/* Information Levels - Shared? */ -#define SMB_INFO_STANDARD 1 -#define SMB_INFO_QUERY_EA_SIZE 2 -#define SMB_INFO_QUERY_EAS_FROM_LIST 3 -#define SMB_INFO_QUERY_ALL_EAS 4 -#define SMB_INFO_IS_NAME_VALID 6 - -/* Information Levels - TRANSACT2_FINDFIRST */ -#define SMB_FIND_FILE_DIRECTORY_INFO 0x101 -#define SMB_FIND_FILE_FULL_DIRECTORY_INFO 0x102 -#define SMB_FIND_FILE_NAMES_INFO 0x103 -#define SMB_FIND_FILE_BOTH_DIRECTORY_INFO 0x104 - -/* Information Levels - TRANSACT2_QPATHINFO */ -#define SMB_QUERY_FILE_BASIC_INFO 0x101 -#define SMB_QUERY_FILE_STANDARD_INFO 0x102 -#define SMB_QUERY_FILE_EA_INFO 0x103 -#define SMB_QUERY_FILE_NAME_INFO 0x104 -#define SMB_QUERY_FILE_ALL_INFO 0x107 -#define SMB_QUERY_FILE_ALT_NAME_INFO 0x108 -#define SMB_QUERY_FILE_STREAM_INFO 0x109 -#define SMB_QUERY_FILE_COMPRESSION_INFO 0x10b - -/* Information Levels - TRANSACT2_SETFILEINFO */ -#define SMB_SET_FILE_BASIC_INFO 0x101 -#define SMB_SET_FILE_DISPOSITION_INFO 0x102 -#define SMB_SET_FILE_ALLOCATION_INFO 0x103 -#define SMB_SET_FILE_END_OF_FILE_INFO 0x104 - -/* smb_flg field flags */ -#define SMB_FLAGS_SUPPORT_LOCKREAD 0x01 -#define SMB_FLAGS_CLIENT_BUF_AVAIL 0x02 -#define SMB_FLAGS_RESERVED 0x04 -#define SMB_FLAGS_CASELESS_PATHNAMES 0x08 -#define SMB_FLAGS_CANONICAL_PATHNAMES 0x10 -#define SMB_FLAGS_REQUEST_OPLOCK 0x20 -#define SMB_FLAGS_REQUEST_BATCH_OPLOCK 0x40 -#define SMB_FLAGS_REPLY 0x80 - -/* smb_flg2 field flags (samba-2.2.0/source/include/smb.h) */ -#define SMB_FLAGS2_LONG_PATH_COMPONENTS 0x0001 -#define SMB_FLAGS2_EXTENDED_ATTRIBUTES 0x0002 -#define SMB_FLAGS2_DFS_PATHNAMES 0x1000 -#define SMB_FLAGS2_READ_PERMIT_NO_EXECUTE 0x2000 -#define SMB_FLAGS2_32_BIT_ERROR_CODES 0x4000 -#define SMB_FLAGS2_UNICODE_STRINGS 0x8000 - - -/* - * UNIX stuff (from samba trans2.h) - */ -#define MIN_UNIX_INFO_LEVEL 0x200 -#define MAX_UNIX_INFO_LEVEL 0x2FF -#define SMB_FIND_FILE_UNIX 0x202 -#define SMB_QUERY_FILE_UNIX_BASIC 0x200 -#define SMB_QUERY_FILE_UNIX_LINK 0x201 -#define SMB_QUERY_FILE_UNIX_HLINK 0x202 -#define SMB_SET_FILE_UNIX_BASIC 0x200 -#define SMB_SET_FILE_UNIX_LINK 0x201 -#define SMB_SET_FILE_UNIX_HLINK 0x203 -#define SMB_QUERY_CIFS_UNIX_INFO 0x200 - -/* values which means "don't change it" */ -#define SMB_MODE_NO_CHANGE 0xFFFFFFFF -#define SMB_UID_NO_CHANGE 0xFFFFFFFF -#define SMB_GID_NO_CHANGE 0xFFFFFFFF -#define SMB_TIME_NO_CHANGE 0xFFFFFFFFFFFFFFFFULL -#define SMB_SIZE_NO_CHANGE 0xFFFFFFFFFFFFFFFFULL - -/* UNIX filetype mappings. */ -#define UNIX_TYPE_FILE 0 -#define UNIX_TYPE_DIR 1 -#define UNIX_TYPE_SYMLINK 2 -#define UNIX_TYPE_CHARDEV 3 -#define UNIX_TYPE_BLKDEV 4 -#define UNIX_TYPE_FIFO 5 -#define UNIX_TYPE_SOCKET 6 -#define UNIX_TYPE_UNKNOWN 0xFFFFFFFF - -#endif /* _SMBNO_H_ */ diff --git a/drivers/staging/smbfs/sock.c b/drivers/staging/smbfs/sock.c deleted file mode 100644 index 9e264090e611..000000000000 --- a/drivers/staging/smbfs/sock.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - * sock.c - * - * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke - * Copyright (C) 1997 by Volker Lendecke - * - * Please add a note about your changes to smbfs in the ChangeLog file. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "smb_fs.h" -#include "smb.h" -#include "smbno.h" -#include "smb_debug.h" -#include "proto.h" -#include "request.h" - - -static int -_recvfrom(struct socket *socket, unsigned char *ubuf, int size, unsigned flags) -{ - struct kvec iov = {ubuf, size}; - struct msghdr msg = {.msg_flags = flags}; - msg.msg_flags |= MSG_DONTWAIT | MSG_NOSIGNAL; - return kernel_recvmsg(socket, &msg, &iov, 1, size, msg.msg_flags); -} - -/* - * Return the server this socket belongs to - */ -static struct smb_sb_info * -server_from_socket(struct socket *socket) -{ - return socket->sk->sk_user_data; -} - -/* - * Called when there is data on the socket. - */ -void -smb_data_ready(struct sock *sk, int len) -{ - struct smb_sb_info *server = server_from_socket(sk->sk_socket); - void (*data_ready)(struct sock *, int) = server->data_ready; - - data_ready(sk, len); - VERBOSE("(%p, %d)\n", sk, len); - smbiod_wake_up(); -} - -int -smb_valid_socket(struct inode * inode) -{ - return (inode && S_ISSOCK(inode->i_mode) && - SOCKET_I(inode)->type == SOCK_STREAM); -} - -static struct socket * -server_sock(struct smb_sb_info *server) -{ - struct file *file; - - if (server && (file = server->sock_file)) - { -#ifdef SMBFS_PARANOIA - if (!smb_valid_socket(file->f_path.dentry->d_inode)) - PARANOIA("bad socket!\n"); -#endif - return SOCKET_I(file->f_path.dentry->d_inode); - } - return NULL; -} - -void -smb_close_socket(struct smb_sb_info *server) -{ - struct file * file = server->sock_file; - - if (file) { - struct socket *sock = server_sock(server); - - VERBOSE("closing socket %p\n", sock); - sock->sk->sk_data_ready = server->data_ready; - server->sock_file = NULL; - fput(file); - } -} - -static int -smb_get_length(struct socket *socket, unsigned char *header) -{ - int result; - - result = _recvfrom(socket, header, 4, MSG_PEEK); - if (result == -EAGAIN) - return -ENODATA; - if (result < 0) { - PARANOIA("recv error = %d\n", -result); - return result; - } - if (result < 4) - return -ENODATA; - - switch (header[0]) { - case 0x00: - case 0x82: - break; - - case 0x85: - DEBUG1("Got SESSION KEEP ALIVE\n"); - _recvfrom(socket, header, 4, 0); /* read away */ - return -ENODATA; - - default: - PARANOIA("Invalid NBT packet, code=%x\n", header[0]); - return -EIO; - } - - /* The length in the RFC NB header is the raw data length */ - return smb_len(header); -} - -int -smb_recv_available(struct smb_sb_info *server) -{ - mm_segment_t oldfs; - int avail, err; - struct socket *sock = server_sock(server); - - oldfs = get_fs(); - set_fs(get_ds()); - err = sock->ops->ioctl(sock, SIOCINQ, (unsigned long) &avail); - set_fs(oldfs); - return (err >= 0) ? avail : err; -} - -/* - * Adjust the kvec to move on 'n' bytes (from nfs/sunrpc) - */ -static int -smb_move_iov(struct kvec **data, size_t *num, struct kvec *vec, unsigned amount) -{ - struct kvec *iv = *data; - int i; - int len; - - /* - * Eat any sent kvecs - */ - while (iv->iov_len <= amount) { - amount -= iv->iov_len; - iv++; - (*num)--; - } - - /* - * And chew down the partial one - */ - vec[0].iov_len = iv->iov_len-amount; - vec[0].iov_base =((unsigned char *)iv->iov_base)+amount; - iv++; - - len = vec[0].iov_len; - - /* - * And copy any others - */ - for (i = 1; i < *num; i++) { - vec[i] = *iv++; - len += vec[i].iov_len; - } - - *data = vec; - return len; -} - -/* - * smb_receive_header - * Only called by the smbiod thread. - */ -int -smb_receive_header(struct smb_sb_info *server) -{ - struct socket *sock; - int result = 0; - unsigned char peek_buf[4]; - - result = -EIO; - sock = server_sock(server); - if (!sock) - goto out; - if (sock->sk->sk_state != TCP_ESTABLISHED) - goto out; - - if (!server->smb_read) { - result = smb_get_length(sock, peek_buf); - if (result < 0) { - if (result == -ENODATA) - result = 0; - goto out; - } - server->smb_len = result + 4; - - if (server->smb_len < SMB_HEADER_LEN) { - PARANOIA("short packet: %d\n", result); - server->rstate = SMB_RECV_DROP; - result = -EIO; - goto out; - } - if (server->smb_len > SMB_MAX_PACKET_SIZE) { - PARANOIA("long packet: %d\n", result); - server->rstate = SMB_RECV_DROP; - result = -EIO; - goto out; - } - } - - result = _recvfrom(sock, server->header + server->smb_read, - SMB_HEADER_LEN - server->smb_read, 0); - VERBOSE("_recvfrom: %d\n", result); - if (result < 0) { - VERBOSE("receive error: %d\n", result); - goto out; - } - server->smb_read += result; - - if (server->smb_read == SMB_HEADER_LEN) - server->rstate = SMB_RECV_HCOMPLETE; -out: - return result; -} - -static char drop_buffer[PAGE_SIZE]; - -/* - * smb_receive_drop - read and throw away the data - * Only called by the smbiod thread. - * - * FIXME: we are in the kernel, could we just tell the socket that we want - * to drop stuff from the buffer? - */ -int -smb_receive_drop(struct smb_sb_info *server) -{ - struct socket *sock; - unsigned int flags; - struct kvec iov; - struct msghdr msg; - int rlen = smb_len(server->header) - server->smb_read + 4; - int result = -EIO; - - if (rlen > PAGE_SIZE) - rlen = PAGE_SIZE; - - sock = server_sock(server); - if (!sock) - goto out; - if (sock->sk->sk_state != TCP_ESTABLISHED) - goto out; - - flags = MSG_DONTWAIT | MSG_NOSIGNAL; - iov.iov_base = drop_buffer; - iov.iov_len = PAGE_SIZE; - msg.msg_flags = flags; - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_control = NULL; - - result = kernel_recvmsg(sock, &msg, &iov, 1, rlen, flags); - - VERBOSE("read: %d\n", result); - if (result < 0) { - VERBOSE("receive error: %d\n", result); - goto out; - } - server->smb_read += result; - - if (server->smb_read >= server->smb_len) - server->rstate = SMB_RECV_END; - -out: - return result; -} - -/* - * smb_receive - * Only called by the smbiod thread. - */ -int -smb_receive(struct smb_sb_info *server, struct smb_request *req) -{ - struct socket *sock; - unsigned int flags; - struct kvec iov[4]; - struct kvec *p = req->rq_iov; - size_t num = req->rq_iovlen; - struct msghdr msg; - int rlen; - int result = -EIO; - - sock = server_sock(server); - if (!sock) - goto out; - if (sock->sk->sk_state != TCP_ESTABLISHED) - goto out; - - flags = MSG_DONTWAIT | MSG_NOSIGNAL; - msg.msg_flags = flags; - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_control = NULL; - - /* Dont repeat bytes and count available bufferspace */ - rlen = min_t(int, smb_move_iov(&p, &num, iov, req->rq_bytes_recvd), - (req->rq_rlen - req->rq_bytes_recvd)); - - result = kernel_recvmsg(sock, &msg, p, num, rlen, flags); - - VERBOSE("read: %d\n", result); - if (result < 0) { - VERBOSE("receive error: %d\n", result); - goto out; - } - req->rq_bytes_recvd += result; - server->smb_read += result; - -out: - return result; -} - -/* - * Try to send a SMB request. This may return after sending only parts of the - * request. SMB_REQ_TRANSMITTED will be set if a request was fully sent. - * - * Parts of this was taken from xprt_sendmsg from net/sunrpc/xprt.c - */ -int -smb_send_request(struct smb_request *req) -{ - struct smb_sb_info *server = req->rq_server; - struct socket *sock; - struct msghdr msg = {.msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT}; - int slen = req->rq_slen - req->rq_bytes_sent; - int result = -EIO; - struct kvec iov[4]; - struct kvec *p = req->rq_iov; - size_t num = req->rq_iovlen; - - sock = server_sock(server); - if (!sock) - goto out; - if (sock->sk->sk_state != TCP_ESTABLISHED) - goto out; - - /* Dont repeat bytes */ - if (req->rq_bytes_sent) - smb_move_iov(&p, &num, iov, req->rq_bytes_sent); - - result = kernel_sendmsg(sock, &msg, p, num, slen); - - if (result >= 0) { - req->rq_bytes_sent += result; - if (req->rq_bytes_sent >= req->rq_slen) - req->rq_flags |= SMB_REQ_TRANSMITTED; - } -out: - return result; -} diff --git a/drivers/staging/smbfs/symlink.c b/drivers/staging/smbfs/symlink.c deleted file mode 100644 index 632c4acd062d..000000000000 --- a/drivers/staging/smbfs/symlink.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * symlink.c - * - * Copyright (C) 2002 by John Newbigin - * - * Please add a note about your changes to smbfs in the ChangeLog file. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "smbno.h" -#include "smb_fs.h" -#include "smb_debug.h" -#include "proto.h" - -int smb_symlink(struct inode *inode, struct dentry *dentry, const char *oldname) -{ - DEBUG1("create symlink %s -> %s/%s\n", oldname, DENTRY_PATH(dentry)); - - return smb_proc_symlink(server_from_dentry(dentry), dentry, oldname); -} - -static void *smb_follow_link(struct dentry *dentry, struct nameidata *nd) -{ - char *link = __getname(); - DEBUG1("followlink of %s/%s\n", DENTRY_PATH(dentry)); - - if (!link) { - link = ERR_PTR(-ENOMEM); - } else { - int len = smb_proc_read_link(server_from_dentry(dentry), - dentry, link, PATH_MAX - 1); - if (len < 0) { - __putname(link); - link = ERR_PTR(len); - } else { - link[len] = 0; - } - } - nd_set_link(nd, link); - return NULL; -} - -static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p) -{ - char *s = nd_get_link(nd); - if (!IS_ERR(s)) - __putname(s); -} - -const struct inode_operations smb_link_inode_operations = -{ - .readlink = generic_readlink, - .follow_link = smb_follow_link, - .put_link = smb_put_link, -}; -- cgit v1.2.3 From a6238f21736af3f47bdebf3895f477f5f23f1af9 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 25 Jan 2011 23:17:27 +0100 Subject: appletalk: move to staging For all I know, Appletalk is dead, the only reasonable use right now would be nostalgia, and that can be served well enough by old kernels. The code is largely not in a bad shape, but it still uses the big kernel lock, and nobody seems motivated to change that. FWIW, the last release of MacOS that supported Appletalk was MacOS X 10.5, made in 2007, and it has been abandoned by Apple with 10.6. Using TCP/IP instead of Appletalk has been supported since MacOS 7.6, which was released in 1997 and is able to run on most of the legacy hardware. Signed-off-by: Arnd Bergmann Cc: Arnaldo Carvalho de Melo Cc: netdev@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 3 +- drivers/net/Makefile | 1 - drivers/net/appletalk/Kconfig | 126 -- drivers/net/appletalk/Makefile | 7 - drivers/net/appletalk/cops.c | 1013 ------------- drivers/net/appletalk/cops.h | 60 - drivers/net/appletalk/cops_ffdrv.h | 532 ------- drivers/net/appletalk/cops_ltdrv.h | 241 ---- drivers/net/appletalk/ipddp.c | 335 ----- drivers/net/appletalk/ipddp.h | 27 - drivers/net/appletalk/ltpc.c | 1288 ----------------- drivers/net/appletalk/ltpc.h | 73 - drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/appletalk/Kconfig | 126 ++ drivers/staging/appletalk/Makefile | 12 + drivers/staging/appletalk/aarp.c | 1063 ++++++++++++++ drivers/staging/appletalk/atalk.h | 208 +++ drivers/staging/appletalk/atalk_proc.c | 301 ++++ drivers/staging/appletalk/cops.c | 1013 +++++++++++++ drivers/staging/appletalk/cops.h | 60 + drivers/staging/appletalk/cops_ffdrv.h | 532 +++++++ drivers/staging/appletalk/cops_ltdrv.h | 241 ++++ drivers/staging/appletalk/ddp.c | 1981 ++++++++++++++++++++++++++ drivers/staging/appletalk/dev.c | 44 + drivers/staging/appletalk/ipddp.c | 335 +++++ drivers/staging/appletalk/ipddp.h | 27 + drivers/staging/appletalk/ltpc.c | 1288 +++++++++++++++++ drivers/staging/appletalk/ltpc.h | 73 + drivers/staging/appletalk/sysctl_net_atalk.c | 61 + fs/compat_ioctl.c | 1 - include/linux/Kbuild | 1 - include/linux/atalk.h | 208 --- net/Kconfig | 1 - net/Makefile | 1 - net/appletalk/Makefile | 9 - net/appletalk/aarp.c | 1063 -------------- net/appletalk/atalk_proc.c | 301 ---- net/appletalk/ddp.c | 1981 -------------------------- net/appletalk/dev.c | 44 - net/appletalk/sysctl_net_atalk.c | 61 - net/socket.c | 1 - 42 files changed, 7369 insertions(+), 7377 deletions(-) delete mode 100644 drivers/net/appletalk/Kconfig delete mode 100644 drivers/net/appletalk/Makefile delete mode 100644 drivers/net/appletalk/cops.c delete mode 100644 drivers/net/appletalk/cops.h delete mode 100644 drivers/net/appletalk/cops_ffdrv.h delete mode 100644 drivers/net/appletalk/cops_ltdrv.h delete mode 100644 drivers/net/appletalk/ipddp.c delete mode 100644 drivers/net/appletalk/ipddp.h delete mode 100644 drivers/net/appletalk/ltpc.c delete mode 100644 drivers/net/appletalk/ltpc.h create mode 100644 drivers/staging/appletalk/Kconfig create mode 100644 drivers/staging/appletalk/Makefile create mode 100644 drivers/staging/appletalk/aarp.c create mode 100644 drivers/staging/appletalk/atalk.h create mode 100644 drivers/staging/appletalk/atalk_proc.c create mode 100644 drivers/staging/appletalk/cops.c create mode 100644 drivers/staging/appletalk/cops.h create mode 100644 drivers/staging/appletalk/cops_ffdrv.h create mode 100644 drivers/staging/appletalk/cops_ltdrv.h create mode 100644 drivers/staging/appletalk/ddp.c create mode 100644 drivers/staging/appletalk/dev.c create mode 100644 drivers/staging/appletalk/ipddp.c create mode 100644 drivers/staging/appletalk/ipddp.h create mode 100644 drivers/staging/appletalk/ltpc.c create mode 100644 drivers/staging/appletalk/ltpc.h create mode 100644 drivers/staging/appletalk/sysctl_net_atalk.c delete mode 100644 include/linux/atalk.h delete mode 100644 net/appletalk/Makefile delete mode 100644 net/appletalk/aarp.c delete mode 100644 net/appletalk/atalk_proc.c delete mode 100644 net/appletalk/ddp.c delete mode 100644 net/appletalk/dev.c delete mode 100644 net/appletalk/sysctl_net_atalk.c (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index dd6ca456cde3..3118d67d68fb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -554,8 +554,7 @@ F: drivers/hwmon/applesmc.c APPLETALK NETWORK LAYER M: Arnaldo Carvalho de Melo S: Maintained -F: drivers/net/appletalk/ -F: net/appletalk/ +F: drivers/staging/appletalk/ ARC FRAMEBUFFER DRIVER M: Jaya Kumar diff --git a/drivers/net/Makefile b/drivers/net/Makefile index b90738d13994..11a9c053f0c8 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -265,7 +265,6 @@ obj-$(CONFIG_MACB) += macb.o obj-$(CONFIG_S6GMAC) += s6gmac.o obj-$(CONFIG_ARM) += arm/ -obj-$(CONFIG_DEV_APPLETALK) += appletalk/ obj-$(CONFIG_TR) += tokenring/ obj-$(CONFIG_WAN) += wan/ obj-$(CONFIG_ARCNET) += arcnet/ diff --git a/drivers/net/appletalk/Kconfig b/drivers/net/appletalk/Kconfig deleted file mode 100644 index 0b376a990972..000000000000 --- a/drivers/net/appletalk/Kconfig +++ /dev/null @@ -1,126 +0,0 @@ -# -# Appletalk driver configuration -# -config ATALK - tristate "Appletalk protocol support" - depends on BKL # waiting to be removed from net/appletalk/ddp.c - select LLC - ---help--- - AppleTalk is the protocol that Apple computers can use to communicate - on a network. If your Linux box is connected to such a network and you - wish to connect to it, say Y. You will need to use the netatalk package - so that your Linux box can act as a print and file server for Macs as - well as access AppleTalk printers. Check out - on the WWW for details. - EtherTalk is the name used for AppleTalk over Ethernet and the - cheaper and slower LocalTalk is AppleTalk over a proprietary Apple - network using serial links. EtherTalk and LocalTalk are fully - supported by Linux. - - General information about how to connect Linux, Windows machines and - Macs is on the WWW at . The - NET3-4-HOWTO, available from - , contains valuable - information as well. - - To compile this driver as a module, choose M here: the module will be - called appletalk. You almost certainly want to compile it as a - module so you can restart your AppleTalk stack without rebooting - your machine. I hear that the GNU boycott of Apple is over, so - even politically correct people are allowed to say Y here. - -config DEV_APPLETALK - tristate "Appletalk interfaces support" - depends on ATALK - help - AppleTalk is the protocol that Apple computers can use to communicate - on a network. If your Linux box is connected to such a network, and wish - to do IP over it, or you have a LocalTalk card and wish to use it to - connect to the AppleTalk network, say Y. - - -config LTPC - tristate "Apple/Farallon LocalTalk PC support" - depends on DEV_APPLETALK && (ISA || EISA) && ISA_DMA_API - help - This allows you to use the AppleTalk PC card to connect to LocalTalk - networks. The card is also known as the Farallon PhoneNet PC card. - If you are in doubt, this card is the one with the 65C02 chip on it. - You also need version 1.3.3 or later of the netatalk package. - This driver is experimental, which means that it may not work. - See the file . - -config COPS - tristate "COPS LocalTalk PC support" - depends on DEV_APPLETALK && (ISA || EISA) - help - This allows you to use COPS AppleTalk cards to connect to LocalTalk - networks. You also need version 1.3.3 or later of the netatalk - package. This driver is experimental, which means that it may not - work. This driver will only work if you choose "AppleTalk DDP" - networking support, above. - Please read the file . - -config COPS_DAYNA - bool "Dayna firmware support" - depends on COPS - help - Support COPS compatible cards with Dayna style firmware (Dayna - DL2000/ Daynatalk/PC (half length), COPS LT-95, Farallon PhoneNET PC - III, Farallon PhoneNET PC II). - -config COPS_TANGENT - bool "Tangent firmware support" - depends on COPS - help - Support COPS compatible cards with Tangent style firmware (Tangent - ATB_II, Novell NL-1000, Daystar Digital LT-200. - -config IPDDP - tristate "Appletalk-IP driver support" - depends on DEV_APPLETALK && ATALK - ---help--- - This allows IP networking for users who only have AppleTalk - networking available. This feature is experimental. With this - driver, you can encapsulate IP inside AppleTalk (e.g. if your Linux - box is stuck on an AppleTalk only network) or decapsulate (e.g. if - you want your Linux box to act as an Internet gateway for a zoo of - AppleTalk connected Macs). Please see the file - for more information. - - If you say Y here, the AppleTalk-IP support will be compiled into - the kernel. In this case, you can either use encapsulation or - decapsulation, but not both. With the following two questions, you - decide which one you want. - - To compile the AppleTalk-IP support as a module, choose M here: the - module will be called ipddp. - In this case, you will be able to use both encapsulation and - decapsulation simultaneously, by loading two copies of the module - and specifying different values for the module option ipddp_mode. - -config IPDDP_ENCAP - bool "IP to Appletalk-IP Encapsulation support" - depends on IPDDP - help - If you say Y here, the AppleTalk-IP code will be able to encapsulate - IP packets inside AppleTalk frames; this is useful if your Linux box - is stuck on an AppleTalk network (which hopefully contains a - decapsulator somewhere). Please see - for more information. If - you said Y to "AppleTalk-IP driver support" above and you say Y - here, then you cannot say Y to "AppleTalk-IP to IP Decapsulation - support", below. - -config IPDDP_DECAP - bool "Appletalk-IP to IP Decapsulation support" - depends on IPDDP - help - If you say Y here, the AppleTalk-IP code will be able to decapsulate - AppleTalk-IP frames to IP packets; this is useful if you want your - Linux box to act as an Internet gateway for an AppleTalk network. - Please see for more - information. If you said Y to "AppleTalk-IP driver support" above - and you say Y here, then you cannot say Y to "IP to AppleTalk-IP - Encapsulation support", above. - diff --git a/drivers/net/appletalk/Makefile b/drivers/net/appletalk/Makefile deleted file mode 100644 index 6cfc705f7c5c..000000000000 --- a/drivers/net/appletalk/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for drivers/net/appletalk -# - -obj-$(CONFIG_IPDDP) += ipddp.o -obj-$(CONFIG_COPS) += cops.o -obj-$(CONFIG_LTPC) += ltpc.o diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c deleted file mode 100644 index 748c9f526e71..000000000000 --- a/drivers/net/appletalk/cops.c +++ /dev/null @@ -1,1013 +0,0 @@ -/* cops.c: LocalTalk driver for Linux. - * - * Authors: - * - Jay Schulist - * - * With more than a little help from; - * - Alan Cox - * - * Derived from: - * - skeleton.c: A network driver outline for linux. - * Written 1993-94 by Donald Becker. - * - ltpc.c: A driver for the LocalTalk PC card. - * Written by Bradford W. Johnson. - * - * Copyright 1993 United States Government as represented by the - * Director, National Security Agency. - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Changes: - * 19970608 Alan Cox Allowed dual card type support - * Can set board type in insmod - * Hooks for cops_setup routine - * (not yet implemented). - * 19971101 Jay Schulist Fixes for multiple lt* devices. - * 19980607 Steven Hirsch Fixed the badly broken support - * for Tangent type cards. Only - * tested on Daystar LT200. Some - * cleanup of formatting and program - * logic. Added emacs 'local-vars' - * setup for Jay's brace style. - * 20000211 Alan Cox Cleaned up for softnet - */ - -static const char *version = -"cops.c:v0.04 6/7/98 Jay Schulist \n"; -/* - * Sources: - * COPS Localtalk SDK. This provides almost all of the information - * needed. - */ - -/* - * insmod/modprobe configurable stuff. - * - IO Port, choose one your card supports or 0 if you dare. - * - IRQ, also choose one your card supports or nothing and let - * the driver figure it out. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* For udelay() */ -#include -#include -#include -#include - -#include -#include -#include - -#include "cops.h" /* Our Stuff */ -#include "cops_ltdrv.h" /* Firmware code for Tangent type cards. */ -#include "cops_ffdrv.h" /* Firmware code for Dayna type cards. */ - -/* - * The name of the card. Is used for messages and in the requests for - * io regions, irqs and dma channels - */ - -static const char *cardname = "cops"; - -#ifdef CONFIG_COPS_DAYNA -static int board_type = DAYNA; /* Module exported */ -#else -static int board_type = TANGENT; -#endif - -static int io = 0x240; /* Default IO for Dayna */ -static int irq = 5; /* Default IRQ */ - -/* - * COPS Autoprobe information. - * Right now if port address is right but IRQ is not 5 this will - * return a 5 no matter what since we will still get a status response. - * Need one more additional check to narrow down after we have gotten - * the ioaddr. But since only other possible IRQs is 3 and 4 so no real - * hurry on this. I *STRONGLY* recommend using IRQ 5 for your card with - * this driver. - * - * This driver has 2 modes and they are: Dayna mode and Tangent mode. - * Each mode corresponds with the type of card. It has been found - * that there are 2 main types of cards and all other cards are - * the same and just have different names or only have minor differences - * such as more IO ports. As this driver is tested it will - * become more clear on exactly what cards are supported. The driver - * defaults to using Dayna mode. To change the drivers mode, simply - * select Dayna or Tangent mode when configuring the kernel. - * - * This driver should support: - * TANGENT driver mode: - * Tangent ATB-II, Novell NL-1000, Daystar Digital LT-200, - * COPS LT-1 - * DAYNA driver mode: - * Dayna DL2000/DaynaTalk PC (Half Length), COPS LT-95, - * Farallon PhoneNET PC III, Farallon PhoneNET PC II - * Other cards possibly supported mode unknown though: - * Dayna DL2000 (Full length), COPS LT/M (Micro-Channel) - * - * Cards NOT supported by this driver but supported by the ltpc.c - * driver written by Bradford W. Johnson - * Farallon PhoneNET PC - * Original Apple LocalTalk PC card - * - * N.B. - * - * The Daystar Digital LT200 boards do not support interrupt-driven - * IO. You must specify 'irq=0xff' as a module parameter to invoke - * polled mode. I also believe that the port probing logic is quite - * dangerous at best and certainly hopeless for a polled card. Best to - * specify both. - Steve H. - * - */ - -/* - * Zero terminated list of IO ports to probe. - */ - -static unsigned int ports[] = { - 0x240, 0x340, 0x200, 0x210, 0x220, 0x230, 0x260, - 0x2A0, 0x300, 0x310, 0x320, 0x330, 0x350, 0x360, - 0 -}; - -/* - * Zero terminated list of IRQ ports to probe. - */ - -static int cops_irqlist[] = { - 5, 4, 3, 0 -}; - -static struct timer_list cops_timer; - -/* use 0 for production, 1 for verification, 2 for debug, 3 for verbose debug */ -#ifndef COPS_DEBUG -#define COPS_DEBUG 1 -#endif -static unsigned int cops_debug = COPS_DEBUG; - -/* The number of low I/O ports used by the card. */ -#define COPS_IO_EXTENT 8 - -/* Information that needs to be kept for each board. */ - -struct cops_local -{ - int board; /* Holds what board type is. */ - int nodeid; /* Set to 1 once have nodeid. */ - unsigned char node_acquire; /* Node ID when acquired. */ - struct atalk_addr node_addr; /* Full node address */ - spinlock_t lock; /* RX/TX lock */ -}; - -/* Index to functions, as function prototypes. */ -static int cops_probe1 (struct net_device *dev, int ioaddr); -static int cops_irq (int ioaddr, int board); - -static int cops_open (struct net_device *dev); -static int cops_jumpstart (struct net_device *dev); -static void cops_reset (struct net_device *dev, int sleep); -static void cops_load (struct net_device *dev); -static int cops_nodeid (struct net_device *dev, int nodeid); - -static irqreturn_t cops_interrupt (int irq, void *dev_id); -static void cops_poll (unsigned long ltdev); -static void cops_timeout(struct net_device *dev); -static void cops_rx (struct net_device *dev); -static netdev_tx_t cops_send_packet (struct sk_buff *skb, - struct net_device *dev); -static void set_multicast_list (struct net_device *dev); -static int cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); -static int cops_close (struct net_device *dev); - -static void cleanup_card(struct net_device *dev) -{ - if (dev->irq) - free_irq(dev->irq, dev); - release_region(dev->base_addr, COPS_IO_EXTENT); -} - -/* - * Check for a network adaptor of this type, and return '0' iff one exists. - * If dev->base_addr == 0, probe all likely locations. - * If dev->base_addr in [1..0x1ff], always return failure. - * otherwise go with what we pass in. - */ -struct net_device * __init cops_probe(int unit) -{ - struct net_device *dev; - unsigned *port; - int base_addr; - int err = 0; - - dev = alloc_ltalkdev(sizeof(struct cops_local)); - if (!dev) - return ERR_PTR(-ENOMEM); - - if (unit >= 0) { - sprintf(dev->name, "lt%d", unit); - netdev_boot_setup_check(dev); - irq = dev->irq; - base_addr = dev->base_addr; - } else { - base_addr = dev->base_addr = io; - } - - if (base_addr > 0x1ff) { /* Check a single specified location. */ - err = cops_probe1(dev, base_addr); - } else if (base_addr != 0) { /* Don't probe at all. */ - err = -ENXIO; - } else { - /* FIXME Does this really work for cards which generate irq? - * It's definitely N.G. for polled Tangent. sh - * Dayna cards don't autoprobe well at all, but if your card is - * at IRQ 5 & IO 0x240 we find it every time. ;) JS - */ - for (port = ports; *port && cops_probe1(dev, *port) < 0; port++) - ; - if (!*port) - err = -ENODEV; - } - if (err) - goto out; - err = register_netdev(dev); - if (err) - goto out1; - return dev; -out1: - cleanup_card(dev); -out: - free_netdev(dev); - return ERR_PTR(err); -} - -static const struct net_device_ops cops_netdev_ops = { - .ndo_open = cops_open, - .ndo_stop = cops_close, - .ndo_start_xmit = cops_send_packet, - .ndo_tx_timeout = cops_timeout, - .ndo_do_ioctl = cops_ioctl, - .ndo_set_multicast_list = set_multicast_list, -}; - -/* - * This is the real probe routine. Linux has a history of friendly device - * probes on the ISA bus. A good device probes avoids doing writes, and - * verifies that the correct device exists and functions. - */ -static int __init cops_probe1(struct net_device *dev, int ioaddr) -{ - struct cops_local *lp; - static unsigned version_printed; - int board = board_type; - int retval; - - if(cops_debug && version_printed++ == 0) - printk("%s", version); - - /* Grab the region so no one else tries to probe our ioports. */ - if (!request_region(ioaddr, COPS_IO_EXTENT, dev->name)) - return -EBUSY; - - /* - * Since this board has jumpered interrupts, allocate the interrupt - * vector now. There is no point in waiting since no other device - * can use the interrupt, and this marks the irq as busy. Jumpered - * interrupts are typically not reported by the boards, and we must - * used AutoIRQ to find them. - */ - dev->irq = irq; - switch (dev->irq) - { - case 0: - /* COPS AutoIRQ routine */ - dev->irq = cops_irq(ioaddr, board); - if (dev->irq) - break; - /* No IRQ found on this port, fallthrough */ - case 1: - retval = -EINVAL; - goto err_out; - - /* Fixup for users that don't know that IRQ 2 is really - * IRQ 9, or don't know which one to set. - */ - case 2: - dev->irq = 9; - break; - - /* Polled operation requested. Although irq of zero passed as - * a parameter tells the init routines to probe, we'll - * overload it to denote polled operation at runtime. - */ - case 0xff: - dev->irq = 0; - break; - - default: - break; - } - - /* Reserve any actual interrupt. */ - if (dev->irq) { - retval = request_irq(dev->irq, cops_interrupt, 0, dev->name, dev); - if (retval) - goto err_out; - } - - dev->base_addr = ioaddr; - - lp = netdev_priv(dev); - spin_lock_init(&lp->lock); - - /* Copy local board variable to lp struct. */ - lp->board = board; - - dev->netdev_ops = &cops_netdev_ops; - dev->watchdog_timeo = HZ * 2; - - - /* Tell the user where the card is and what mode we're in. */ - if(board==DAYNA) - printk("%s: %s at %#3x, using IRQ %d, in Dayna mode.\n", - dev->name, cardname, ioaddr, dev->irq); - if(board==TANGENT) { - if(dev->irq) - printk("%s: %s at %#3x, IRQ %d, in Tangent mode\n", - dev->name, cardname, ioaddr, dev->irq); - else - printk("%s: %s at %#3x, using polled IO, in Tangent mode.\n", - dev->name, cardname, ioaddr); - - } - return 0; - -err_out: - release_region(ioaddr, COPS_IO_EXTENT); - return retval; -} - -static int __init cops_irq (int ioaddr, int board) -{ /* - * This does not use the IRQ to determine where the IRQ is. We just - * assume that when we get a correct status response that it's the IRQ. - * This really just verifies the IO port but since we only have access - * to such a small number of IRQs (5, 4, 3) this is not bad. - * This will probably not work for more than one card. - */ - int irqaddr=0; - int i, x, status; - - if(board==DAYNA) - { - outb(0, ioaddr+DAYNA_RESET); - inb(ioaddr+DAYNA_RESET); - mdelay(333); - } - if(board==TANGENT) - { - inb(ioaddr); - outb(0, ioaddr); - outb(0, ioaddr+TANG_RESET); - } - - for(i=0; cops_irqlist[i] !=0; i++) - { - irqaddr = cops_irqlist[i]; - for(x = 0xFFFF; x>0; x --) /* wait for response */ - { - if(board==DAYNA) - { - status = (inb(ioaddr+DAYNA_CARD_STATUS)&3); - if(status == 1) - return irqaddr; - } - if(board==TANGENT) - { - if((inb(ioaddr+TANG_CARD_STATUS)& TANG_TX_READY) !=0) - return irqaddr; - } - } - } - return 0; /* no IRQ found */ -} - -/* - * Open/initialize the board. This is called (in the current kernel) - * sometime after booting when the 'ifconfig' program is run. - */ -static int cops_open(struct net_device *dev) -{ - struct cops_local *lp = netdev_priv(dev); - - if(dev->irq==0) - { - /* - * I don't know if the Dayna-style boards support polled - * operation. For now, only allow it for Tangent. - */ - if(lp->board==TANGENT) /* Poll 20 times per second */ - { - init_timer(&cops_timer); - cops_timer.function = cops_poll; - cops_timer.data = (unsigned long)dev; - cops_timer.expires = jiffies + HZ/20; - add_timer(&cops_timer); - } - else - { - printk(KERN_WARNING "%s: No irq line set\n", dev->name); - return -EAGAIN; - } - } - - cops_jumpstart(dev); /* Start the card up. */ - - netif_start_queue(dev); - return 0; -} - -/* - * This allows for a dynamic start/restart of the entire card. - */ -static int cops_jumpstart(struct net_device *dev) -{ - struct cops_local *lp = netdev_priv(dev); - - /* - * Once the card has the firmware loaded and has acquired - * the nodeid, if it is reset it will lose it all. - */ - cops_reset(dev,1); /* Need to reset card before load firmware. */ - cops_load(dev); /* Load the firmware. */ - - /* - * If atalkd already gave us a nodeid we will use that - * one again, else we wait for atalkd to give us a nodeid - * in cops_ioctl. This may cause a problem if someone steals - * our nodeid while we are resetting. - */ - if(lp->nodeid == 1) - cops_nodeid(dev,lp->node_acquire); - - return 0; -} - -static void tangent_wait_reset(int ioaddr) -{ - int timeout=0; - - while(timeout++ < 5 && (inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0) - mdelay(1); /* Wait 1 second */ -} - -/* - * Reset the LocalTalk board. - */ -static void cops_reset(struct net_device *dev, int sleep) -{ - struct cops_local *lp = netdev_priv(dev); - int ioaddr=dev->base_addr; - - if(lp->board==TANGENT) - { - inb(ioaddr); /* Clear request latch. */ - outb(0,ioaddr); /* Clear the TANG_TX_READY flop. */ - outb(0, ioaddr+TANG_RESET); /* Reset the adapter. */ - - tangent_wait_reset(ioaddr); - outb(0, ioaddr+TANG_CLEAR_INT); - } - if(lp->board==DAYNA) - { - outb(0, ioaddr+DAYNA_RESET); /* Assert the reset port */ - inb(ioaddr+DAYNA_RESET); /* Clear the reset */ - if (sleep) - msleep(333); - else - mdelay(333); - } - - netif_wake_queue(dev); -} - -static void cops_load (struct net_device *dev) -{ - struct ifreq ifr; - struct ltfirmware *ltf= (struct ltfirmware *)&ifr.ifr_ifru; - struct cops_local *lp = netdev_priv(dev); - int ioaddr=dev->base_addr; - int length, i = 0; - - strcpy(ifr.ifr_name,"lt0"); - - /* Get card's firmware code and do some checks on it. */ -#ifdef CONFIG_COPS_DAYNA - if(lp->board==DAYNA) - { - ltf->length=sizeof(ffdrv_code); - ltf->data=ffdrv_code; - } - else -#endif -#ifdef CONFIG_COPS_TANGENT - if(lp->board==TANGENT) - { - ltf->length=sizeof(ltdrv_code); - ltf->data=ltdrv_code; - } - else -#endif - { - printk(KERN_INFO "%s; unsupported board type.\n", dev->name); - return; - } - - /* Check to make sure firmware is correct length. */ - if(lp->board==DAYNA && ltf->length!=5983) - { - printk(KERN_WARNING "%s: Firmware is not length of FFDRV.BIN.\n", dev->name); - return; - } - if(lp->board==TANGENT && ltf->length!=2501) - { - printk(KERN_WARNING "%s: Firmware is not length of DRVCODE.BIN.\n", dev->name); - return; - } - - if(lp->board==DAYNA) - { - /* - * We must wait for a status response - * with the DAYNA board. - */ - while(++i<65536) - { - if((inb(ioaddr+DAYNA_CARD_STATUS)&3)==1) - break; - } - - if(i==65536) - return; - } - - /* - * Upload the firmware and kick. Byte-by-byte works nicely here. - */ - i=0; - length = ltf->length; - while(length--) - { - outb(ltf->data[i], ioaddr); - i++; - } - - if(cops_debug > 1) - printk("%s: Uploaded firmware - %d bytes of %d bytes.\n", - dev->name, i, ltf->length); - - if(lp->board==DAYNA) /* Tell Dayna to run the firmware code. */ - outb(1, ioaddr+DAYNA_INT_CARD); - else /* Tell Tang to run the firmware code. */ - inb(ioaddr); - - if(lp->board==TANGENT) - { - tangent_wait_reset(ioaddr); - inb(ioaddr); /* Clear initial ready signal. */ - } -} - -/* - * Get the LocalTalk Nodeid from the card. We can suggest - * any nodeid 1-254. The card will try and get that exact - * address else we can specify 0 as the nodeid and the card - * will autoprobe for a nodeid. - */ -static int cops_nodeid (struct net_device *dev, int nodeid) -{ - struct cops_local *lp = netdev_priv(dev); - int ioaddr = dev->base_addr; - - if(lp->board == DAYNA) - { - /* Empty any pending adapter responses. */ - while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0) - { - outb(0, ioaddr+COPS_CLEAR_INT); /* Clear interrupts. */ - if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST) - cops_rx(dev); /* Kick any packets waiting. */ - schedule(); - } - - outb(2, ioaddr); /* Output command packet length as 2. */ - outb(0, ioaddr); - outb(LAP_INIT, ioaddr); /* Send LAP_INIT command byte. */ - outb(nodeid, ioaddr); /* Suggest node address. */ - } - - if(lp->board == TANGENT) - { - /* Empty any pending adapter responses. */ - while(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY) - { - outb(0, ioaddr+COPS_CLEAR_INT); /* Clear interrupt. */ - cops_rx(dev); /* Kick out packets waiting. */ - schedule(); - } - - /* Not sure what Tangent does if nodeid picked is used. */ - if(nodeid == 0) /* Seed. */ - nodeid = jiffies&0xFF; /* Get a random try */ - outb(2, ioaddr); /* Command length LSB */ - outb(0, ioaddr); /* Command length MSB */ - outb(LAP_INIT, ioaddr); /* Send LAP_INIT byte */ - outb(nodeid, ioaddr); /* LAP address hint. */ - outb(0xFF, ioaddr); /* Int. level to use */ - } - - lp->node_acquire=0; /* Set nodeid holder to 0. */ - while(lp->node_acquire==0) /* Get *True* nodeid finally. */ - { - outb(0, ioaddr+COPS_CLEAR_INT); /* Clear any interrupt. */ - - if(lp->board == DAYNA) - { - if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST) - cops_rx(dev); /* Grab the nodeid put in lp->node_acquire. */ - } - if(lp->board == TANGENT) - { - if(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY) - cops_rx(dev); /* Grab the nodeid put in lp->node_acquire. */ - } - schedule(); - } - - if(cops_debug > 1) - printk(KERN_DEBUG "%s: Node ID %d has been acquired.\n", - dev->name, lp->node_acquire); - - lp->nodeid=1; /* Set got nodeid to 1. */ - - return 0; -} - -/* - * Poll the Tangent type cards to see if we have work. - */ - -static void cops_poll(unsigned long ltdev) -{ - int ioaddr, status; - int boguscount = 0; - - struct net_device *dev = (struct net_device *)ltdev; - - del_timer(&cops_timer); - - if(dev == NULL) - return; /* We've been downed */ - - ioaddr = dev->base_addr; - do { - status=inb(ioaddr+TANG_CARD_STATUS); - if(status & TANG_RX_READY) - cops_rx(dev); - if(status & TANG_TX_READY) - netif_wake_queue(dev); - status = inb(ioaddr+TANG_CARD_STATUS); - } while((++boguscount < 20) && (status&(TANG_RX_READY|TANG_TX_READY))); - - /* poll 20 times per second */ - cops_timer.expires = jiffies + HZ/20; - add_timer(&cops_timer); -} - -/* - * The typical workload of the driver: - * Handle the network interface interrupts. - */ -static irqreturn_t cops_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct cops_local *lp; - int ioaddr, status; - int boguscount = 0; - - ioaddr = dev->base_addr; - lp = netdev_priv(dev); - - if(lp->board==DAYNA) - { - do { - outb(0, ioaddr + COPS_CLEAR_INT); - status=inb(ioaddr+DAYNA_CARD_STATUS); - if((status&0x03)==DAYNA_RX_REQUEST) - cops_rx(dev); - netif_wake_queue(dev); - } while(++boguscount < 20); - } - else - { - do { - status=inb(ioaddr+TANG_CARD_STATUS); - if(status & TANG_RX_READY) - cops_rx(dev); - if(status & TANG_TX_READY) - netif_wake_queue(dev); - status=inb(ioaddr+TANG_CARD_STATUS); - } while((++boguscount < 20) && (status&(TANG_RX_READY|TANG_TX_READY))); - } - - return IRQ_HANDLED; -} - -/* - * We have a good packet(s), get it/them out of the buffers. - */ -static void cops_rx(struct net_device *dev) -{ - int pkt_len = 0; - int rsp_type = 0; - struct sk_buff *skb = NULL; - struct cops_local *lp = netdev_priv(dev); - int ioaddr = dev->base_addr; - int boguscount = 0; - unsigned long flags; - - - spin_lock_irqsave(&lp->lock, flags); - - if(lp->board==DAYNA) - { - outb(0, ioaddr); /* Send out Zero length. */ - outb(0, ioaddr); - outb(DATA_READ, ioaddr); /* Send read command out. */ - - /* Wait for DMA to turn around. */ - while(++boguscount<1000000) - { - barrier(); - if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_READY) - break; - } - - if(boguscount==1000000) - { - printk(KERN_WARNING "%s: DMA timed out.\n",dev->name); - spin_unlock_irqrestore(&lp->lock, flags); - return; - } - } - - /* Get response length. */ - if(lp->board==DAYNA) - pkt_len = inb(ioaddr) & 0xFF; - else - pkt_len = inb(ioaddr) & 0x00FF; - pkt_len |= (inb(ioaddr) << 8); - /* Input IO code. */ - rsp_type=inb(ioaddr); - - /* Malloc up new buffer. */ - skb = dev_alloc_skb(pkt_len); - if(skb == NULL) - { - printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", - dev->name); - dev->stats.rx_dropped++; - while(pkt_len--) /* Discard packet */ - inb(ioaddr); - spin_unlock_irqrestore(&lp->lock, flags); - return; - } - skb->dev = dev; - skb_put(skb, pkt_len); - skb->protocol = htons(ETH_P_LOCALTALK); - - insb(ioaddr, skb->data, pkt_len); /* Eat the Data */ - - if(lp->board==DAYNA) - outb(1, ioaddr+DAYNA_INT_CARD); /* Interrupt the card */ - - spin_unlock_irqrestore(&lp->lock, flags); /* Restore interrupts. */ - - /* Check for bad response length */ - if(pkt_len < 0 || pkt_len > MAX_LLAP_SIZE) - { - printk(KERN_WARNING "%s: Bad packet length of %d bytes.\n", - dev->name, pkt_len); - dev->stats.tx_errors++; - dev_kfree_skb_any(skb); - return; - } - - /* Set nodeid and then get out. */ - if(rsp_type == LAP_INIT_RSP) - { /* Nodeid taken from received packet. */ - lp->node_acquire = skb->data[0]; - dev_kfree_skb_any(skb); - return; - } - - /* One last check to make sure we have a good packet. */ - if(rsp_type != LAP_RESPONSE) - { - printk(KERN_WARNING "%s: Bad packet type %d.\n", dev->name, rsp_type); - dev->stats.tx_errors++; - dev_kfree_skb_any(skb); - return; - } - - skb_reset_mac_header(skb); /* Point to entire packet. */ - skb_pull(skb,3); - skb_reset_transport_header(skb); /* Point to data (Skip header). */ - - /* Update the counters. */ - dev->stats.rx_packets++; - dev->stats.rx_bytes += skb->len; - - /* Send packet to a higher place. */ - netif_rx(skb); -} - -static void cops_timeout(struct net_device *dev) -{ - struct cops_local *lp = netdev_priv(dev); - int ioaddr = dev->base_addr; - - dev->stats.tx_errors++; - if(lp->board==TANGENT) - { - if((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0) - printk(KERN_WARNING "%s: No TX complete interrupt.\n", dev->name); - } - printk(KERN_WARNING "%s: Transmit timed out.\n", dev->name); - cops_jumpstart(dev); /* Restart the card. */ - dev->trans_start = jiffies; /* prevent tx timeout */ - netif_wake_queue(dev); -} - - -/* - * Make the card transmit a LocalTalk packet. - */ - -static netdev_tx_t cops_send_packet(struct sk_buff *skb, - struct net_device *dev) -{ - struct cops_local *lp = netdev_priv(dev); - int ioaddr = dev->base_addr; - unsigned long flags; - - /* - * Block a timer-based transmit from overlapping. - */ - - netif_stop_queue(dev); - - spin_lock_irqsave(&lp->lock, flags); - if(lp->board == DAYNA) /* Wait for adapter transmit buffer. */ - while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0) - cpu_relax(); - if(lp->board == TANGENT) /* Wait for adapter transmit buffer. */ - while((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0) - cpu_relax(); - - /* Output IO length. */ - outb(skb->len, ioaddr); - if(lp->board == DAYNA) - outb(skb->len >> 8, ioaddr); - else - outb((skb->len >> 8)&0x0FF, ioaddr); - - /* Output IO code. */ - outb(LAP_WRITE, ioaddr); - - if(lp->board == DAYNA) /* Check the transmit buffer again. */ - while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0); - - outsb(ioaddr, skb->data, skb->len); /* Send out the data. */ - - if(lp->board==DAYNA) /* Dayna requires you kick the card */ - outb(1, ioaddr+DAYNA_INT_CARD); - - spin_unlock_irqrestore(&lp->lock, flags); /* Restore interrupts. */ - - /* Done sending packet, update counters and cleanup. */ - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - dev_kfree_skb (skb); - return NETDEV_TX_OK; -} - -/* - * Dummy function to keep the Appletalk layer happy. - */ - -static void set_multicast_list(struct net_device *dev) -{ - if(cops_debug >= 3) - printk("%s: set_multicast_list executed\n", dev->name); -} - -/* - * System ioctls for the COPS LocalTalk card. - */ - -static int cops_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - struct cops_local *lp = netdev_priv(dev); - struct sockaddr_at *sa = (struct sockaddr_at *)&ifr->ifr_addr; - struct atalk_addr *aa = (struct atalk_addr *)&lp->node_addr; - - switch(cmd) - { - case SIOCSIFADDR: - /* Get and set the nodeid and network # atalkd wants. */ - cops_nodeid(dev, sa->sat_addr.s_node); - aa->s_net = sa->sat_addr.s_net; - aa->s_node = lp->node_acquire; - - /* Set broardcast address. */ - dev->broadcast[0] = 0xFF; - - /* Set hardware address. */ - dev->dev_addr[0] = aa->s_node; - dev->addr_len = 1; - return 0; - - case SIOCGIFADDR: - sa->sat_addr.s_net = aa->s_net; - sa->sat_addr.s_node = aa->s_node; - return 0; - - default: - return -EOPNOTSUPP; - } -} - -/* - * The inverse routine to cops_open(). - */ - -static int cops_close(struct net_device *dev) -{ - struct cops_local *lp = netdev_priv(dev); - - /* If we were running polled, yank the timer. - */ - if(lp->board==TANGENT && dev->irq==0) - del_timer(&cops_timer); - - netif_stop_queue(dev); - return 0; -} - - -#ifdef MODULE -static struct net_device *cops_dev; - -MODULE_LICENSE("GPL"); -module_param(io, int, 0); -module_param(irq, int, 0); -module_param(board_type, int, 0); - -static int __init cops_module_init(void) -{ - if (io == 0) - printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n", - cardname); - cops_dev = cops_probe(-1); - if (IS_ERR(cops_dev)) - return PTR_ERR(cops_dev); - return 0; -} - -static void __exit cops_module_exit(void) -{ - unregister_netdev(cops_dev); - cleanup_card(cops_dev); - free_netdev(cops_dev); -} -module_init(cops_module_init); -module_exit(cops_module_exit); -#endif /* MODULE */ diff --git a/drivers/net/appletalk/cops.h b/drivers/net/appletalk/cops.h deleted file mode 100644 index fd2750b269c8..000000000000 --- a/drivers/net/appletalk/cops.h +++ /dev/null @@ -1,60 +0,0 @@ -/* cops.h: LocalTalk driver for Linux. - * - * Authors: - * - Jay Schulist - */ - -#ifndef __LINUX_COPSLTALK_H -#define __LINUX_COPSLTALK_H - -#ifdef __KERNEL__ - -/* Max LLAP size we will accept. */ -#define MAX_LLAP_SIZE 603 - -/* Tangent */ -#define TANG_CARD_STATUS 1 -#define TANG_CLEAR_INT 1 -#define TANG_RESET 3 - -#define TANG_TX_READY 1 -#define TANG_RX_READY 2 - -/* Dayna */ -#define DAYNA_CMD_DATA 0 -#define DAYNA_CLEAR_INT 1 -#define DAYNA_CARD_STATUS 2 -#define DAYNA_INT_CARD 3 -#define DAYNA_RESET 4 - -#define DAYNA_RX_READY 0 -#define DAYNA_TX_READY 1 -#define DAYNA_RX_REQUEST 3 - -/* Same on both card types */ -#define COPS_CLEAR_INT 1 - -/* LAP response codes received from the cards. */ -#define LAP_INIT 1 /* Init cmd */ -#define LAP_INIT_RSP 2 /* Init response */ -#define LAP_WRITE 3 /* Write cmd */ -#define DATA_READ 4 /* Data read */ -#define LAP_RESPONSE 4 /* Received ALAP frame response */ -#define LAP_GETSTAT 5 /* Get LAP and HW status */ -#define LAP_RSPSTAT 6 /* Status response */ - -#endif - -/* - * Structure to hold the firmware information. - */ -struct ltfirmware -{ - unsigned int length; - const unsigned char *data; -}; - -#define DAYNA 1 -#define TANGENT 2 - -#endif diff --git a/drivers/net/appletalk/cops_ffdrv.h b/drivers/net/appletalk/cops_ffdrv.h deleted file mode 100644 index b02005087c1b..000000000000 --- a/drivers/net/appletalk/cops_ffdrv.h +++ /dev/null @@ -1,532 +0,0 @@ - -/* - * The firmware this driver downloads into the Localtalk card is a - * separate program and is not GPL'd source code, even though the Linux - * side driver and the routine that loads this data into the card are. - * - * It is taken from the COPS SDK and is under the following license - * - * This material is licensed to you strictly for use in conjunction with - * the use of COPS LocalTalk adapters. - * There is no charge for this SDK. And no waranty express or implied - * about its fitness for any purpose. However, we will cheerefully - * refund every penny you paid for this SDK... - * Regards, - * - * Thomas F. Divine - * Chief Scientist - */ - - -/* cops_ffdrv.h: LocalTalk driver firmware dump for Linux. - * - * Authors: - * - Jay Schulist - */ - - -#ifdef CONFIG_COPS_DAYNA - -static const unsigned char ffdrv_code[] = { - 58,3,0,50,228,149,33,255,255,34,226,149, - 249,17,40,152,33,202,154,183,237,82,77,68, - 11,107,98,19,54,0,237,176,175,50,80,0, - 62,128,237,71,62,32,237,57,51,62,12,237, - 57,50,237,57,54,62,6,237,57,52,62,12, - 237,57,49,33,107,137,34,32,128,33,83,130, - 34,40,128,33,86,130,34,42,128,33,112,130, - 34,36,128,33,211,130,34,38,128,62,0,237, - 57,16,33,63,148,34,34,128,237,94,205,15, - 130,251,205,168,145,24,141,67,111,112,121,114, - 105,103,104,116,32,40,67,41,32,49,57,56, - 56,32,45,32,68,97,121,110,97,32,67,111, - 109,109,117,110,105,99,97,116,105,111,110,115, - 32,32,32,65,108,108,32,114,105,103,104,116, - 115,32,114,101,115,101,114,118,101,100,46,32, - 32,40,68,40,68,7,16,8,34,7,22,6, - 16,5,12,4,8,3,6,140,0,16,39,128, - 0,4,96,10,224,6,0,7,126,2,64,11, - 118,12,6,13,0,14,193,15,0,5,96,3, - 192,1,64,9,8,62,9,211,66,62,192,211, - 66,62,100,61,32,253,6,28,33,205,129,14, - 66,237,163,194,253,129,6,28,33,205,129,14, - 64,237,163,194,9,130,201,62,47,50,71,152, - 62,47,211,68,58,203,129,237,57,20,58,204, - 129,237,57,21,33,77,152,54,132,205,233,129, - 58,228,149,254,209,40,6,56,4,62,0,24, - 2,219,96,33,233,149,119,230,62,33,232,149, - 119,213,33,8,152,17,7,0,25,119,19,25, - 119,209,201,251,237,77,245,197,213,229,221,229, - 205,233,129,62,1,50,106,137,205,158,139,221, - 225,225,209,193,241,251,237,77,245,197,213,219, - 72,237,56,16,230,46,237,57,16,237,56,12, - 58,72,152,183,32,26,6,20,17,128,2,237, - 56,46,187,32,35,237,56,47,186,32,29,219, - 72,230,1,32,3,5,32,232,175,50,72,152, - 229,221,229,62,1,50,106,137,205,158,139,221, - 225,225,24,25,62,1,50,72,152,58,201,129, - 237,57,12,58,202,129,237,57,13,237,56,16, - 246,17,237,57,16,209,193,241,251,237,77,245, - 197,229,213,221,229,237,56,16,230,17,237,57, - 16,237,56,20,58,34,152,246,16,246,8,211, - 68,62,6,61,32,253,58,34,152,246,8,211, - 68,58,203,129,237,57,20,58,204,129,237,57, - 21,237,56,16,246,34,237,57,16,221,225,209, - 225,193,241,251,237,77,33,2,0,57,126,230, - 3,237,100,1,40,2,246,128,230,130,245,62, - 5,211,64,241,211,64,201,229,213,243,237,56, - 16,230,46,237,57,16,237,56,12,251,70,35, - 35,126,254,175,202,77,133,254,129,202,15,133, - 230,128,194,191,132,43,58,44,152,119,33,76, - 152,119,35,62,132,119,120,254,255,40,4,58, - 49,152,119,219,72,43,43,112,17,3,0,237, - 56,52,230,248,237,57,52,219,72,230,1,194, - 141,131,209,225,237,56,52,246,6,237,57,52, - 62,1,55,251,201,62,3,211,66,62,192,211, - 66,62,48,211,66,0,0,219,66,230,1,40, - 4,219,67,24,240,205,203,135,58,75,152,254, - 255,202,128,132,58,49,152,254,161,250,207,131, - 58,34,152,211,68,62,10,211,66,62,128,211, - 66,62,11,211,66,62,6,211,66,24,0,62, - 14,211,66,62,33,211,66,62,1,211,66,62, - 64,211,66,62,3,211,66,62,209,211,66,62, - 100,71,219,66,230,1,32,6,5,32,247,195, - 248,132,219,67,71,58,44,152,184,194,248,132, - 62,100,71,219,66,230,1,32,6,5,32,247, - 195,248,132,219,67,62,100,71,219,66,230,1, - 32,6,5,32,247,195,248,132,219,67,254,133, - 32,7,62,0,50,74,152,24,17,254,173,32, - 7,62,1,50,74,152,24,6,254,141,194,248, - 132,71,209,225,58,49,152,254,132,32,10,62, - 50,205,2,134,205,144,135,24,27,254,140,32, - 15,62,110,205,2,134,62,141,184,32,5,205, - 144,135,24,8,62,10,205,2,134,205,8,134, - 62,1,50,106,137,205,158,139,237,56,52,246, - 6,237,57,52,175,183,251,201,62,20,135,237, - 57,20,175,237,57,21,237,56,16,246,2,237, - 57,16,237,56,20,95,237,56,21,123,254,10, - 48,244,237,56,16,230,17,237,57,16,209,225, - 205,144,135,62,1,50,106,137,205,158,139,237, - 56,52,246,6,237,57,52,175,183,251,201,209, - 225,243,219,72,230,1,40,13,62,10,211,66, - 0,0,219,66,230,192,202,226,132,237,56,52, - 246,6,237,57,52,62,1,55,251,201,205,203, - 135,62,1,50,106,137,205,158,139,237,56,52, - 246,6,237,57,52,183,251,201,209,225,62,1, - 50,106,137,205,158,139,237,56,52,246,6,237, - 57,52,62,2,55,251,201,209,225,243,219,72, - 230,1,202,213,132,62,10,211,66,0,0,219, - 66,230,192,194,213,132,229,62,1,50,106,137, - 42,40,152,205,65,143,225,17,3,0,205,111, - 136,62,6,211,66,58,44,152,211,66,237,56, - 52,246,6,237,57,52,183,251,201,209,197,237, - 56,52,230,248,237,57,52,219,72,230,1,32, - 15,193,225,237,56,52,246,6,237,57,52,62, - 1,55,251,201,14,23,58,37,152,254,0,40, - 14,14,2,254,1,32,5,62,140,119,24,3, - 62,132,119,43,43,197,205,203,135,193,62,1, - 211,66,62,64,211,66,62,3,211,66,62,193, - 211,66,62,100,203,39,71,219,66,230,1,32, - 6,5,32,247,195,229,133,33,238,151,219,67, - 71,58,44,152,184,194,229,133,119,62,100,71, - 219,66,230,1,32,6,5,32,247,195,229,133, - 219,67,35,119,13,32,234,193,225,62,1,50, - 106,137,205,158,139,237,56,52,246,6,237,57, - 52,175,183,251,201,33,234,151,35,35,62,255, - 119,193,225,62,1,50,106,137,205,158,139,237, - 56,52,246,6,237,57,52,175,251,201,243,61, - 32,253,251,201,62,3,211,66,62,192,211,66, - 58,49,152,254,140,32,19,197,229,213,17,181, - 129,33,185,129,1,2,0,237,176,209,225,193, - 24,27,229,213,33,187,129,58,49,152,230,15, - 87,30,2,237,92,25,17,181,129,126,18,19, - 35,126,18,209,225,58,34,152,246,8,211,68, - 58,49,152,254,165,40,14,254,164,40,10,62, - 10,211,66,62,224,211,66,24,25,58,74,152, - 254,0,40,10,62,10,211,66,62,160,211,66, - 24,8,62,10,211,66,62,128,211,66,62,11, - 211,66,62,6,211,66,205,147,143,62,5,211, - 66,62,224,211,66,62,5,211,66,62,96,211, - 66,62,5,61,32,253,62,5,211,66,62,224, - 211,66,62,14,61,32,253,62,5,211,66,62, - 233,211,66,62,128,211,66,58,181,129,61,32, - 253,62,1,211,66,62,192,211,66,1,254,19, - 237,56,46,187,32,6,13,32,247,195,226,134, - 62,192,211,66,0,0,219,66,203,119,40,250, - 219,66,203,87,40,250,243,237,56,16,230,17, - 237,57,16,237,56,20,251,62,5,211,66,62, - 224,211,66,58,182,129,61,32,253,229,33,181, - 129,58,183,129,203,63,119,35,58,184,129,119, - 225,62,10,211,66,62,224,211,66,62,11,211, - 66,62,118,211,66,62,47,211,68,62,5,211, - 66,62,233,211,66,58,181,129,61,32,253,62, - 5,211,66,62,224,211,66,58,182,129,61,32, - 253,62,5,211,66,62,96,211,66,201,229,213, - 58,50,152,230,15,87,30,2,237,92,33,187, - 129,25,17,181,129,126,18,35,19,126,18,209, - 225,58,71,152,246,8,211,68,58,50,152,254, - 165,40,14,254,164,40,10,62,10,211,66,62, - 224,211,66,24,8,62,10,211,66,62,128,211, - 66,62,11,211,66,62,6,211,66,195,248,135, - 62,3,211,66,62,192,211,66,197,229,213,17, - 181,129,33,183,129,1,2,0,237,176,209,225, - 193,62,47,211,68,62,10,211,66,62,224,211, - 66,62,11,211,66,62,118,211,66,62,1,211, - 66,62,0,211,66,205,147,143,195,16,136,62, - 3,211,66,62,192,211,66,197,229,213,17,181, - 129,33,183,129,1,2,0,237,176,209,225,193, - 62,47,211,68,62,10,211,66,62,224,211,66, - 62,11,211,66,62,118,211,66,205,147,143,62, - 5,211,66,62,224,211,66,62,5,211,66,62, - 96,211,66,62,5,61,32,253,62,5,211,66, - 62,224,211,66,62,14,61,32,253,62,5,211, - 66,62,233,211,66,62,128,211,66,58,181,129, - 61,32,253,62,1,211,66,62,192,211,66,1, - 254,19,237,56,46,187,32,6,13,32,247,195, - 88,136,62,192,211,66,0,0,219,66,203,119, - 40,250,219,66,203,87,40,250,62,5,211,66, - 62,224,211,66,58,182,129,61,32,253,62,5, - 211,66,62,96,211,66,201,197,14,67,6,0, - 62,3,211,66,62,192,211,66,62,48,211,66, - 0,0,219,66,230,1,40,4,219,67,24,240, - 62,5,211,66,62,233,211,66,62,128,211,66, - 58,181,129,61,32,253,237,163,29,62,192,211, - 66,219,66,230,4,40,250,237,163,29,32,245, - 219,66,230,4,40,250,62,255,71,219,66,230, - 4,40,3,5,32,247,219,66,230,4,40,250, - 62,5,211,66,62,224,211,66,58,182,129,61, - 32,253,62,5,211,66,62,96,211,66,58,71, - 152,254,1,202,18,137,62,16,211,66,62,56, - 211,66,62,14,211,66,62,33,211,66,62,1, - 211,66,62,248,211,66,237,56,48,246,153,230, - 207,237,57,48,62,3,211,66,62,221,211,66, - 193,201,58,71,152,211,68,62,10,211,66,62, - 128,211,66,62,11,211,66,62,6,211,66,62, - 6,211,66,58,44,152,211,66,62,16,211,66, - 62,56,211,66,62,48,211,66,0,0,62,14, - 211,66,62,33,211,66,62,1,211,66,62,248, - 211,66,237,56,48,246,145,246,8,230,207,237, - 57,48,62,3,211,66,62,221,211,66,193,201, - 44,3,1,0,70,69,1,245,197,213,229,175, - 50,72,152,237,56,16,230,46,237,57,16,237, - 56,12,62,1,211,66,0,0,219,66,95,230, - 160,32,3,195,20,139,123,230,96,194,72,139, - 62,48,211,66,62,1,211,66,62,64,211,66, - 237,91,40,152,205,207,143,25,43,55,237,82, - 218,70,139,34,42,152,98,107,58,44,152,190, - 194,210,138,35,35,62,130,190,194,200,137,62, - 1,50,48,152,62,175,190,202,82,139,62,132, - 190,32,44,50,50,152,62,47,50,71,152,229, - 175,50,106,137,42,40,152,205,65,143,225,54, - 133,43,70,58,44,152,119,43,112,17,3,0, - 62,10,205,2,134,205,111,136,195,158,138,62, - 140,190,32,19,50,50,152,58,233,149,230,4, - 202,222,138,62,1,50,71,152,195,219,137,126, - 254,160,250,185,138,254,166,242,185,138,50,50, - 152,43,126,35,229,213,33,234,149,95,22,0, - 25,126,254,132,40,18,254,140,40,14,58,50, - 152,230,15,87,126,31,21,242,65,138,56,2, - 175,119,58,50,152,230,15,87,58,233,149,230, - 62,31,21,242,85,138,218,98,138,209,225,195, - 20,139,58,50,152,33,100,137,230,15,95,22, - 0,25,126,50,71,152,209,225,58,50,152,254, - 164,250,135,138,58,73,152,254,0,40,4,54, - 173,24,2,54,133,43,70,58,44,152,119,43, - 112,17,3,0,205,70,135,175,50,106,137,205, - 208,139,58,199,129,237,57,12,58,200,129,237, - 57,13,237,56,16,246,17,237,57,16,225,209, - 193,241,251,237,77,62,129,190,194,227,138,54, - 130,43,70,58,44,152,119,43,112,17,3,0, - 205,144,135,195,20,139,35,35,126,254,132,194, - 227,138,175,50,106,137,205,158,139,24,42,58, - 201,154,254,1,40,7,62,1,50,106,137,24, - 237,58,106,137,254,1,202,222,138,62,128,166, - 194,222,138,221,229,221,33,67,152,205,127,142, - 205,109,144,221,225,225,209,193,241,251,237,77, - 58,106,137,254,1,202,44,139,58,50,152,254, - 164,250,44,139,58,73,152,238,1,50,73,152, - 221,229,221,33,51,152,205,127,142,221,225,62, - 1,50,106,137,205,158,139,195,13,139,24,208, - 24,206,24,204,230,64,40,3,195,20,139,195, - 20,139,43,126,33,8,152,119,35,58,44,152, - 119,43,237,91,35,152,205,203,135,205,158,139, - 195,13,139,175,50,78,152,62,3,211,66,62, - 192,211,66,201,197,33,4,0,57,126,35,102, - 111,62,1,50,106,137,219,72,205,141,139,193, - 201,62,1,50,78,152,34,40,152,54,0,35, - 35,54,0,195,163,139,58,78,152,183,200,229, - 33,181,129,58,183,129,119,35,58,184,129,119, - 225,62,47,211,68,62,14,211,66,62,193,211, - 66,62,10,211,66,62,224,211,66,62,11,211, - 66,62,118,211,66,195,3,140,58,78,152,183, - 200,58,71,152,211,68,254,69,40,4,254,70, - 32,17,58,73,152,254,0,40,10,62,10,211, - 66,62,160,211,66,24,8,62,10,211,66,62, - 128,211,66,62,11,211,66,62,6,211,66,62, - 6,211,66,58,44,152,211,66,62,16,211,66, - 62,56,211,66,62,48,211,66,0,0,219,66, - 230,1,40,4,219,67,24,240,62,14,211,66, - 62,33,211,66,42,40,152,205,65,143,62,1, - 211,66,62,248,211,66,237,56,48,246,145,246, - 8,230,207,237,57,48,62,3,211,66,62,221, - 211,66,201,62,16,211,66,62,56,211,66,62, - 48,211,66,0,0,219,66,230,1,40,4,219, - 67,24,240,62,14,211,66,62,33,211,66,62, - 1,211,66,62,248,211,66,237,56,48,246,153, - 230,207,237,57,48,62,3,211,66,62,221,211, - 66,201,229,213,33,234,149,95,22,0,25,126, - 254,132,40,4,254,140,32,2,175,119,123,209, - 225,201,6,8,14,0,31,48,1,12,16,250, - 121,201,33,4,0,57,94,35,86,33,2,0, - 57,126,35,102,111,221,229,34,89,152,237,83, - 91,152,221,33,63,152,205,127,142,58,81,152, - 50,82,152,58,80,152,135,50,80,152,205,162, - 140,254,3,56,16,58,81,152,135,60,230,15, - 50,81,152,175,50,80,152,24,23,58,79,152, - 205,162,140,254,3,48,13,58,81,152,203,63, - 50,81,152,62,255,50,79,152,58,81,152,50, - 82,152,58,79,152,135,50,79,152,62,32,50, - 83,152,50,84,152,237,56,16,230,17,237,57, - 16,219,72,62,192,50,93,152,62,93,50,94, - 152,58,93,152,61,50,93,152,32,9,58,94, - 152,61,50,94,152,40,44,62,170,237,57,20, - 175,237,57,21,237,56,16,246,2,237,57,16, - 219,72,230,1,202,29,141,237,56,20,71,237, - 56,21,120,254,10,48,237,237,56,16,230,17, - 237,57,16,243,62,14,211,66,62,65,211,66, - 251,58,39,152,23,23,60,50,39,152,71,58, - 82,152,160,230,15,40,22,71,14,10,219,66, - 230,16,202,186,141,219,72,230,1,202,186,141, - 13,32,239,16,235,42,89,152,237,91,91,152, - 205,47,131,48,7,61,202,186,141,195,227,141, - 221,225,33,0,0,201,221,33,55,152,205,127, - 142,58,84,152,61,50,84,152,40,19,58,82, - 152,246,1,50,82,152,58,79,152,246,1,50, - 79,152,195,29,141,221,225,33,1,0,201,221, - 33,59,152,205,127,142,58,80,152,246,1,50, - 80,152,58,82,152,135,246,1,50,82,152,58, - 83,152,61,50,83,152,194,29,141,221,225,33, - 2,0,201,221,229,33,0,0,57,17,4,0, - 25,126,50,44,152,230,128,50,85,152,58,85, - 152,183,40,6,221,33,88,2,24,4,221,33, - 150,0,58,44,152,183,40,53,60,40,50,60, - 40,47,61,61,33,86,152,119,35,119,35,54, - 129,175,50,48,152,221,43,221,229,225,124,181, - 40,42,33,86,152,17,3,0,205,189,140,17, - 232,3,27,123,178,32,251,58,48,152,183,40, - 224,58,44,152,71,62,7,128,230,127,71,58, - 85,152,176,50,44,152,24,162,221,225,201,183, - 221,52,0,192,221,52,1,192,221,52,2,192, - 221,52,3,192,55,201,245,62,1,211,100,241, - 201,245,62,1,211,96,241,201,33,2,0,57, - 126,35,102,111,237,56,48,230,175,237,57,48, - 62,48,237,57,49,125,237,57,32,124,237,57, - 33,62,0,237,57,34,62,88,237,57,35,62, - 0,237,57,36,237,57,37,33,128,2,125,237, - 57,38,124,237,57,39,237,56,48,246,97,230, - 207,237,57,48,62,0,237,57,0,62,0,211, - 96,211,100,201,33,2,0,57,126,35,102,111, - 237,56,48,230,175,237,57,48,62,12,237,57, - 49,62,76,237,57,32,62,0,237,57,33,237, - 57,34,125,237,57,35,124,237,57,36,62,0, - 237,57,37,33,128,2,125,237,57,38,124,237, - 57,39,237,56,48,246,97,230,207,237,57,48, - 62,1,211,96,201,33,2,0,57,126,35,102, - 111,229,237,56,48,230,87,237,57,48,125,237, - 57,40,124,237,57,41,62,0,237,57,42,62, - 67,237,57,43,62,0,237,57,44,58,106,137, - 254,1,32,5,33,6,0,24,3,33,128,2, - 125,237,57,46,124,237,57,47,237,56,50,230, - 252,246,2,237,57,50,225,201,33,4,0,57, - 94,35,86,33,2,0,57,126,35,102,111,237, - 56,48,230,87,237,57,48,125,237,57,40,124, - 237,57,41,62,0,237,57,42,62,67,237,57, - 43,62,0,237,57,44,123,237,57,46,122,237, - 57,47,237,56,50,230,244,246,0,237,57,50, - 237,56,48,246,145,230,207,237,57,48,201,213, - 237,56,46,95,237,56,47,87,237,56,46,111, - 237,56,47,103,183,237,82,32,235,33,128,2, - 183,237,82,209,201,213,237,56,38,95,237,56, - 39,87,237,56,38,111,237,56,39,103,183,237, - 82,32,235,33,128,2,183,237,82,209,201,245, - 197,1,52,0,237,120,230,253,237,121,193,241, - 201,245,197,1,52,0,237,120,246,2,237,121, - 193,241,201,33,2,0,57,126,35,102,111,126, - 35,110,103,201,33,0,0,34,102,152,34,96, - 152,34,98,152,33,202,154,34,104,152,237,91, - 104,152,42,226,149,183,237,82,17,0,255,25, - 34,100,152,203,124,40,6,33,0,125,34,100, - 152,42,104,152,35,35,35,229,205,120,139,193, - 201,205,186,149,229,42,40,152,35,35,35,229, - 205,39,144,193,124,230,3,103,221,117,254,221, - 116,255,237,91,42,152,35,35,35,183,237,82, - 32,12,17,5,0,42,42,152,205,171,149,242, - 169,144,42,40,152,229,205,120,139,193,195,198, - 149,237,91,42,152,42,98,152,25,34,98,152, - 19,19,19,42,102,152,25,34,102,152,237,91, - 100,152,33,158,253,25,237,91,102,152,205,171, - 149,242,214,144,33,0,0,34,102,152,62,1, - 50,95,152,205,225,144,195,198,149,58,95,152, - 183,200,237,91,96,152,42,102,152,205,171,149, - 242,5,145,237,91,102,152,33,98,2,25,237, - 91,96,152,205,171,149,250,37,145,237,91,96, - 152,42,102,152,183,237,82,32,7,42,98,152, - 125,180,40,13,237,91,102,152,42,96,152,205, - 171,149,242,58,145,237,91,104,152,42,102,152, - 25,35,35,35,229,205,120,139,193,175,50,95, - 152,201,195,107,139,205,206,149,250,255,243,205, - 225,144,251,58,230,149,183,194,198,149,17,1, - 0,42,98,152,205,171,149,250,198,149,62,1, - 50,230,149,237,91,96,152,42,104,152,25,221, - 117,252,221,116,253,237,91,104,152,42,96,152, - 25,35,35,35,221,117,254,221,116,255,35,35, - 35,229,205,39,144,124,230,3,103,35,35,35, - 221,117,250,221,116,251,235,221,110,252,221,102, - 253,115,35,114,35,54,4,62,1,211,100,211, - 84,195,198,149,33,0,0,34,102,152,34,96, - 152,34,98,152,33,202,154,34,104,152,237,91, - 104,152,42,226,149,183,237,82,17,0,255,25, - 34,100,152,33,109,152,54,0,33,107,152,229, - 205,240,142,193,62,47,50,34,152,62,132,50, - 49,152,205,241,145,205,61,145,58,39,152,60, - 50,39,152,24,241,205,206,149,251,255,33,109, - 152,126,183,202,198,149,110,221,117,251,33,109, - 152,54,0,221,126,251,254,1,40,28,254,3, - 40,101,254,4,202,190,147,254,5,202,147,147, - 254,8,40,87,33,107,152,229,205,240,142,195, - 198,149,58,201,154,183,32,21,33,111,152,126, - 50,229,149,205,52,144,33,110,152,110,38,0, - 229,205,11,142,193,237,91,96,152,42,104,152, - 25,221,117,254,221,116,255,35,35,54,2,17, - 2,0,43,43,115,35,114,58,44,152,35,35, - 119,58,228,149,35,119,62,1,211,100,211,84, - 62,1,50,201,154,24,169,205,153,142,58,231, - 149,183,40,250,175,50,231,149,33,110,152,126, - 254,255,40,91,58,233,149,230,63,183,40,83, - 94,22,0,33,234,149,25,126,183,40,13,33, - 110,152,94,33,234,150,25,126,254,3,32,36, - 205,81,148,125,180,33,110,152,94,22,0,40, - 17,33,234,149,25,54,0,33,107,152,229,205, - 240,142,193,195,198,149,33,234,150,25,54,0, - 33,110,152,94,22,0,33,234,149,25,126,50, - 49,152,254,132,32,37,62,47,50,34,152,42, - 107,152,229,33,110,152,229,205,174,140,193,193, - 125,180,33,110,152,94,22,0,33,234,150,202, - 117,147,25,52,195,120,147,58,49,152,254,140, - 32,7,62,1,50,34,152,24,210,62,32,50, - 106,152,24,19,58,49,152,95,58,106,152,163, - 183,58,106,152,32,11,203,63,50,106,152,58, - 106,152,183,32,231,254,2,40,51,254,4,40, - 38,254,8,40,26,254,16,40,13,254,32,32, - 158,62,165,50,49,152,62,69,24,190,62,164, - 50,49,152,62,70,24,181,62,163,50,49,152, - 175,24,173,62,162,50,49,152,62,1,24,164, - 62,161,50,49,152,62,3,24,155,25,54,0, - 221,126,251,254,8,40,7,58,230,149,183,202, - 32,146,33,107,152,229,205,240,142,193,211,84, - 195,198,149,237,91,96,152,42,104,152,25,221, - 117,254,221,116,255,35,35,54,6,17,2,0, - 43,43,115,35,114,58,228,149,35,35,119,58, - 233,149,35,119,205,146,142,195,32,146,237,91, - 96,152,42,104,152,25,229,205,160,142,193,58, - 231,149,183,40,250,175,50,231,149,243,237,91, - 96,152,42,104,152,25,221,117,254,221,116,255, - 78,35,70,221,113,252,221,112,253,89,80,42, - 98,152,183,237,82,34,98,152,203,124,40,19, - 33,0,0,34,98,152,34,102,152,34,96,152, - 62,1,50,95,152,24,40,221,94,252,221,86, - 253,19,19,19,42,96,152,25,34,96,152,237, - 91,100,152,33,158,253,25,237,91,96,152,205, - 171,149,242,55,148,33,0,0,34,96,152,175, - 50,230,149,251,195,32,146,245,62,1,50,231, - 149,62,16,237,57,0,211,80,241,251,237,77, - 201,205,186,149,229,229,33,0,0,34,37,152, - 33,110,152,126,50,234,151,58,44,152,33,235, - 151,119,221,54,253,0,221,54,254,0,195,230, - 148,33,236,151,54,175,33,3,0,229,33,234, - 151,229,205,174,140,193,193,33,236,151,126,254, - 255,40,74,33,245,151,110,221,117,255,33,249, - 151,126,221,166,255,221,119,255,33,253,151,126, - 221,166,255,221,119,255,58,232,149,95,221,126, - 255,163,221,119,255,183,40,15,230,191,33,110, - 152,94,22,0,33,234,149,25,119,24,12,33, - 110,152,94,22,0,33,234,149,25,54,132,33, - 0,0,195,198,149,221,110,253,221,102,254,35, - 221,117,253,221,116,254,17,32,0,221,110,253, - 221,102,254,205,171,149,250,117,148,58,233,149, - 203,87,40,84,33,1,0,34,37,152,221,54, - 253,0,221,54,254,0,24,53,33,236,151,54, - 175,33,3,0,229,33,234,151,229,205,174,140, - 193,193,33,236,151,126,254,255,40,14,33,110, - 152,94,22,0,33,234,149,25,54,140,24,159, - 221,110,253,221,102,254,35,221,117,253,221,116, - 254,17,32,0,221,110,253,221,102,254,205,171, - 149,250,12,149,33,2,0,34,37,152,221,54, - 253,0,221,54,254,0,24,54,33,236,151,54, - 175,33,3,0,229,33,234,151,229,205,174,140, - 193,193,33,236,151,126,254,255,40,15,33,110, - 152,94,22,0,33,234,149,25,54,132,195,211, - 148,221,110,253,221,102,254,35,221,117,253,221, - 116,254,17,32,0,221,110,253,221,102,254,205, - 171,149,250,96,149,33,1,0,195,198,149,124, - 170,250,179,149,237,82,201,124,230,128,237,82, - 60,201,225,253,229,221,229,221,33,0,0,221, - 57,233,221,249,221,225,253,225,201,233,225,253, - 229,221,229,221,33,0,0,221,57,94,35,86, - 35,235,57,249,235,233,0,0,0,0,0,0, - 62,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 175,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,133,1,0,0,0,63, - 255,255,255,255,0,0,0,63,0,0,0,0, - 0,0,0,0,0,0,0,24,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0 - } ; - -#endif diff --git a/drivers/net/appletalk/cops_ltdrv.h b/drivers/net/appletalk/cops_ltdrv.h deleted file mode 100644 index c699b1ad31da..000000000000 --- a/drivers/net/appletalk/cops_ltdrv.h +++ /dev/null @@ -1,241 +0,0 @@ -/* - * The firmware this driver downloads into the Localtalk card is a - * separate program and is not GPL'd source code, even though the Linux - * side driver and the routine that loads this data into the card are. - * - * It is taken from the COPS SDK and is under the following license - * - * This material is licensed to you strictly for use in conjunction with - * the use of COPS LocalTalk adapters. - * There is no charge for this SDK. And no waranty express or implied - * about its fitness for any purpose. However, we will cheerefully - * refund every penny you paid for this SDK... - * Regards, - * - * Thomas F. Divine - * Chief Scientist - */ - - -/* cops_ltdrv.h: LocalTalk driver firmware dump for Linux. - * - * Authors: - * - Jay Schulist - */ - - -#ifdef CONFIG_COPS_TANGENT - -static const unsigned char ltdrv_code[] = { - 58,3,0,50,148,10,33,143,15,62,85,119, - 190,32,9,62,170,119,190,32,3,35,24,241, - 34,146,10,249,17,150,10,33,143,15,183,237, - 82,77,68,11,107,98,19,54,0,237,176,62, - 16,237,57,51,62,0,237,57,50,237,57,54, - 62,12,237,57,49,62,195,33,39,2,50,56, - 0,34,57,0,237,86,205,30,2,251,205,60, - 10,24,169,67,111,112,121,114,105,103,104,116, - 32,40,99,41,32,49,57,56,56,45,49,57, - 57,50,44,32,80,114,105,110,116,105,110,103, - 32,67,111,109,109,117,110,105,99,97,116,105, - 111,110,115,32,65,115,115,111,99,105,97,116, - 101,115,44,32,73,110,99,46,65,108,108,32, - 114,105,103,104,116,115,32,114,101,115,101,114, - 118,101,100,46,32,32,4,4,22,40,255,60, - 4,96,10,224,6,0,7,126,2,64,11,246, - 12,6,13,0,14,193,15,0,5,96,3,192, - 1,0,9,8,62,3,211,82,62,192,211,82, - 201,62,3,211,82,62,213,211,82,201,62,5, - 211,82,62,224,211,82,201,62,5,211,82,62, - 224,211,82,201,62,5,211,82,62,96,211,82, - 201,6,28,33,180,1,14,82,237,163,194,4, - 2,33,39,2,34,64,0,58,3,0,230,1, - 192,62,11,237,121,62,118,237,121,201,33,182, - 10,54,132,205,253,1,201,245,197,213,229,42, - 150,10,14,83,17,98,2,67,20,237,162,58, - 179,1,95,219,82,230,1,32,6,29,32,247, - 195,17,3,62,1,211,82,219,82,95,230,160, - 32,10,237,162,32,225,21,32,222,195,15,3, - 237,162,123,230,96,194,21,3,62,48,211,82, - 62,1,211,82,175,211,82,237,91,150,10,43, - 55,237,82,218,19,3,34,152,10,98,107,58, - 154,10,190,32,81,62,1,50,158,10,35,35, - 62,132,190,32,44,54,133,43,70,58,154,10, - 119,43,112,17,3,0,205,137,3,62,16,211, - 82,62,56,211,82,205,217,1,42,150,10,14, - 83,17,98,2,67,20,58,178,1,95,195,59, - 2,62,129,190,194,227,2,54,130,43,70,58, - 154,10,119,43,112,17,3,0,205,137,3,195, - 254,2,35,35,126,254,132,194,227,2,205,61, - 3,24,20,62,128,166,194,222,2,221,229,221, - 33,175,10,205,93,6,205,144,7,221,225,225, - 209,193,241,251,237,77,221,229,221,33,159,10, - 205,93,6,221,225,205,61,3,195,247,2,24, - 237,24,235,24,233,230,64,40,2,24,227,24, - 225,175,50,179,10,205,208,1,201,197,33,4, - 0,57,126,35,102,111,205,51,3,193,201,62, - 1,50,179,10,34,150,10,54,0,58,179,10, - 183,200,62,14,211,82,62,193,211,82,62,10, - 211,82,62,224,211,82,62,6,211,82,58,154, - 10,211,82,62,16,211,82,62,56,211,82,62, - 48,211,82,219,82,230,1,40,4,219,83,24, - 242,62,14,211,82,62,33,211,82,62,1,211, - 82,62,9,211,82,62,32,211,82,205,217,1, - 201,14,83,205,208,1,24,23,14,83,205,208, - 1,205,226,1,58,174,1,61,32,253,205,244, - 1,58,174,1,61,32,253,205,226,1,58,175, - 1,61,32,253,62,5,211,82,62,233,211,82, - 62,128,211,82,58,176,1,61,32,253,237,163, - 27,62,192,211,82,219,82,230,4,40,250,237, - 163,27,122,179,32,243,219,82,230,4,40,250, - 58,178,1,71,219,82,230,4,40,3,5,32, - 247,219,82,230,4,40,250,205,235,1,58,177, - 1,61,32,253,205,244,1,201,229,213,35,35, - 126,230,128,194,145,4,43,58,154,10,119,43, - 70,33,181,10,119,43,112,17,3,0,243,62, - 10,211,82,219,82,230,128,202,41,4,209,225, - 62,1,55,251,201,205,144,3,58,180,10,254, - 255,202,127,4,205,217,1,58,178,1,71,219, - 82,230,1,32,6,5,32,247,195,173,4,219, - 83,71,58,154,10,184,194,173,4,58,178,1, - 71,219,82,230,1,32,6,5,32,247,195,173, - 4,219,83,58,178,1,71,219,82,230,1,32, - 6,5,32,247,195,173,4,219,83,254,133,194, - 173,4,58,179,1,24,4,58,179,1,135,61, - 32,253,209,225,205,137,3,205,61,3,183,251, - 201,209,225,243,62,10,211,82,219,82,230,128, - 202,164,4,62,1,55,251,201,205,144,3,205, - 61,3,183,251,201,209,225,62,2,55,251,201, - 243,62,14,211,82,62,33,211,82,251,201,33, - 4,0,57,94,35,86,33,2,0,57,126,35, - 102,111,221,229,34,193,10,237,83,195,10,221, - 33,171,10,205,93,6,58,185,10,50,186,10, - 58,184,10,135,50,184,10,205,112,6,254,3, - 56,16,58,185,10,135,60,230,15,50,185,10, - 175,50,184,10,24,23,58,183,10,205,112,6, - 254,3,48,13,58,185,10,203,63,50,185,10, - 62,255,50,183,10,58,185,10,50,186,10,58, - 183,10,135,50,183,10,62,32,50,187,10,50, - 188,10,6,255,219,82,230,16,32,3,5,32, - 247,205,180,4,6,40,219,82,230,16,40,3, - 5,32,247,62,10,211,82,219,82,230,128,194, - 46,5,219,82,230,16,40,214,237,95,71,58, - 186,10,160,230,15,40,32,71,14,10,62,10, - 211,82,219,82,230,128,202,119,5,205,180,4, - 195,156,5,219,82,230,16,202,156,5,13,32, - 229,16,225,42,193,10,237,91,195,10,205,252, - 3,48,7,61,202,156,5,195,197,5,221,225, - 33,0,0,201,221,33,163,10,205,93,6,58, - 188,10,61,50,188,10,40,19,58,186,10,246, - 1,50,186,10,58,183,10,246,1,50,183,10, - 195,46,5,221,225,33,1,0,201,221,33,167, - 10,205,93,6,58,184,10,246,1,50,184,10, - 58,186,10,135,246,1,50,186,10,58,187,10, - 61,50,187,10,194,46,5,221,225,33,2,0, - 201,221,229,33,0,0,57,17,4,0,25,126, - 50,154,10,230,128,50,189,10,58,189,10,183, - 40,6,221,33,88,2,24,4,221,33,150,0, - 58,154,10,183,40,49,60,40,46,61,33,190, - 10,119,35,119,35,54,129,175,50,158,10,221, - 43,221,229,225,124,181,40,42,33,190,10,17, - 3,0,205,206,4,17,232,3,27,123,178,32, - 251,58,158,10,183,40,224,58,154,10,71,62, - 7,128,230,127,71,58,189,10,176,50,154,10, - 24,166,221,225,201,183,221,52,0,192,221,52, - 1,192,221,52,2,192,221,52,3,192,55,201, - 6,8,14,0,31,48,1,12,16,250,121,201, - 33,2,0,57,94,35,86,35,78,35,70,35, - 126,35,102,105,79,120,68,103,237,176,201,33, - 2,0,57,126,35,102,111,62,17,237,57,48, - 125,237,57,40,124,237,57,41,62,0,237,57, - 42,62,64,237,57,43,62,0,237,57,44,33, - 128,2,125,237,57,46,124,237,57,47,62,145, - 237,57,48,211,68,58,149,10,211,66,201,33, - 2,0,57,126,35,102,111,62,33,237,57,48, - 62,64,237,57,32,62,0,237,57,33,237,57, - 34,125,237,57,35,124,237,57,36,62,0,237, - 57,37,33,128,2,125,237,57,38,124,237,57, - 39,62,97,237,57,48,211,67,58,149,10,211, - 66,201,237,56,46,95,237,56,47,87,237,56, - 46,111,237,56,47,103,183,237,82,32,235,33, - 128,2,183,237,82,201,237,56,38,95,237,56, - 39,87,237,56,38,111,237,56,39,103,183,237, - 82,32,235,33,128,2,183,237,82,201,205,106, - 10,221,110,6,221,102,7,126,35,110,103,195, - 118,10,205,106,10,33,0,0,34,205,10,34, - 198,10,34,200,10,33,143,15,34,207,10,237, - 91,207,10,42,146,10,183,237,82,17,0,255, - 25,34,203,10,203,124,40,6,33,0,125,34, - 203,10,42,207,10,229,205,37,3,195,118,10, - 205,106,10,229,42,150,10,35,35,35,229,205, - 70,7,193,124,230,3,103,221,117,254,221,116, - 255,237,91,152,10,35,35,35,183,237,82,32, - 12,17,5,0,42,152,10,205,91,10,242,203, - 7,42,150,10,229,205,37,3,195,118,10,237, - 91,152,10,42,200,10,25,34,200,10,42,205, - 10,25,34,205,10,237,91,203,10,33,158,253, - 25,237,91,205,10,205,91,10,242,245,7,33, - 0,0,34,205,10,62,1,50,197,10,205,5, - 8,33,0,0,57,249,195,118,10,205,106,10, - 58,197,10,183,202,118,10,237,91,198,10,42, - 205,10,205,91,10,242,46,8,237,91,205,10, - 33,98,2,25,237,91,198,10,205,91,10,250, - 78,8,237,91,198,10,42,205,10,183,237,82, - 32,7,42,200,10,125,180,40,13,237,91,205, - 10,42,198,10,205,91,10,242,97,8,237,91, - 207,10,42,205,10,25,229,205,37,3,175,50, - 197,10,195,118,10,205,29,3,33,0,0,57, - 249,195,118,10,205,106,10,58,202,10,183,40, - 22,205,14,7,237,91,209,10,19,19,19,205, - 91,10,242,139,8,33,1,0,195,118,10,33, - 0,0,195,118,10,205,126,10,252,255,205,108, - 8,125,180,194,118,10,237,91,200,10,33,0, - 0,205,91,10,242,118,10,237,91,207,10,42, - 198,10,25,221,117,254,221,116,255,35,35,35, - 229,205,70,7,193,124,230,3,103,35,35,35, - 221,117,252,221,116,253,229,221,110,254,221,102, - 255,229,33,212,10,229,205,124,6,193,193,221, - 110,252,221,102,253,34,209,10,33,211,10,54, - 4,33,209,10,227,205,147,6,193,62,1,50, - 202,10,243,221,94,252,221,86,253,42,200,10, - 183,237,82,34,200,10,203,124,40,17,33,0, - 0,34,200,10,34,205,10,34,198,10,50,197, - 10,24,37,221,94,252,221,86,253,42,198,10, - 25,34,198,10,237,91,203,10,33,158,253,25, - 237,91,198,10,205,91,10,242,68,9,33,0, - 0,34,198,10,205,5,8,33,0,0,57,249, - 251,195,118,10,205,106,10,33,49,13,126,183, - 40,16,205,42,7,237,91,47,13,19,19,19, - 205,91,10,242,117,9,58,142,15,198,1,50, - 142,15,195,118,10,33,49,13,126,254,1,40, - 25,254,3,202,7,10,254,5,202,21,10,33, - 49,13,54,0,33,47,13,229,205,207,6,195, - 118,10,58,141,15,183,32,72,33,51,13,126, - 50,149,10,205,86,7,33,50,13,126,230,127, - 183,32,40,58,142,15,230,127,50,142,15,183, - 32,5,198,1,50,142,15,33,50,13,126,111, - 23,159,103,203,125,58,142,15,40,5,198,128, - 50,142,15,33,50,13,119,33,50,13,126,111, - 23,159,103,229,205,237,5,193,33,211,10,54, - 2,33,2,0,34,209,10,58,154,10,33,212, - 10,119,58,148,10,33,213,10,119,33,209,10, - 229,205,147,6,193,24,128,42,47,13,229,33, - 50,13,229,205,191,4,193,24,239,33,211,10, - 54,6,33,3,0,34,209,10,58,154,10,33, - 212,10,119,58,148,10,33,213,10,119,33,214, - 10,54,5,33,209,10,229,205,147,6,24,200, - 205,106,10,33,49,13,54,0,33,47,13,229, - 205,207,6,33,209,10,227,205,147,6,193,205, - 80,9,205,145,8,24,248,124,170,250,99,10, - 237,82,201,124,230,128,237,82,60,201,225,253, - 229,221,229,221,33,0,0,221,57,233,221,249, - 221,225,253,225,201,233,225,253,229,221,229,221, - 33,0,0,221,57,94,35,86,35,235,57,249, - 235,233,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0 - } ; - -#endif diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c deleted file mode 100644 index 10d0dba572c2..000000000000 --- a/drivers/net/appletalk/ipddp.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * ipddp.c: IP to Appletalk-IP Encapsulation driver for Linux - * Appletalk-IP to IP Decapsulation driver for Linux - * - * Authors: - * - DDP-IP Encap by: Bradford W. Johnson - * - DDP-IP Decap by: Jay Schulist - * - * Derived from: - * - Almost all code already existed in net/appletalk/ddp.c I just - * moved/reorginized it into a driver file. Original IP-over-DDP code - * was done by Bradford W. Johnson - * - skeleton.c: A network driver outline for linux. - * Written 1993-94 by Donald Becker. - * - dummy.c: A dummy net driver. By Nick Holloway. - * - MacGate: A user space Daemon for Appletalk-IP Decap for - * Linux by Jay Schulist - * - * Copyright 1993 United States Government as represented by the - * Director, National Security Agency. - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ipddp.h" /* Our stuff */ - -static const char version[] = KERN_INFO "ipddp.c:v0.01 8/28/97 Bradford W. Johnson \n"; - -static struct ipddp_route *ipddp_route_list; -static DEFINE_SPINLOCK(ipddp_route_lock); - -#ifdef CONFIG_IPDDP_ENCAP -static int ipddp_mode = IPDDP_ENCAP; -#else -static int ipddp_mode = IPDDP_DECAP; -#endif - -/* Index to functions, as function prototypes. */ -static netdev_tx_t ipddp_xmit(struct sk_buff *skb, - struct net_device *dev); -static int ipddp_create(struct ipddp_route *new_rt); -static int ipddp_delete(struct ipddp_route *rt); -static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt); -static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); - -static const struct net_device_ops ipddp_netdev_ops = { - .ndo_start_xmit = ipddp_xmit, - .ndo_do_ioctl = ipddp_ioctl, - .ndo_change_mtu = eth_change_mtu, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, -}; - -static struct net_device * __init ipddp_init(void) -{ - static unsigned version_printed; - struct net_device *dev; - int err; - - dev = alloc_etherdev(0); - if (!dev) - return ERR_PTR(-ENOMEM); - - dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; - strcpy(dev->name, "ipddp%d"); - - if (version_printed++ == 0) - printk(version); - - /* Initialize the device structure. */ - dev->netdev_ops = &ipddp_netdev_ops; - - dev->type = ARPHRD_IPDDP; /* IP over DDP tunnel */ - dev->mtu = 585; - dev->flags |= IFF_NOARP; - - /* - * The worst case header we will need is currently a - * ethernet header (14 bytes) and a ddp header (sizeof ddpehdr+1) - * We send over SNAP so that takes another 8 bytes. - */ - dev->hard_header_len = 14+8+sizeof(struct ddpehdr)+1; - - err = register_netdev(dev); - if (err) { - free_netdev(dev); - return ERR_PTR(err); - } - - /* Let the user now what mode we are in */ - if(ipddp_mode == IPDDP_ENCAP) - printk("%s: Appletalk-IP Encap. mode by Bradford W. Johnson \n", - dev->name); - if(ipddp_mode == IPDDP_DECAP) - printk("%s: Appletalk-IP Decap. mode by Jay Schulist \n", - dev->name); - - return dev; -} - - -/* - * Transmit LLAP/ELAP frame using aarp_send_ddp. - */ -static netdev_tx_t ipddp_xmit(struct sk_buff *skb, struct net_device *dev) -{ - __be32 paddr = skb_rtable(skb)->rt_gateway; - struct ddpehdr *ddp; - struct ipddp_route *rt; - struct atalk_addr *our_addr; - - spin_lock(&ipddp_route_lock); - - /* - * Find appropriate route to use, based only on IP number. - */ - for(rt = ipddp_route_list; rt != NULL; rt = rt->next) - { - if(rt->ip == paddr) - break; - } - if(rt == NULL) { - spin_unlock(&ipddp_route_lock); - return NETDEV_TX_OK; - } - - our_addr = atalk_find_dev_addr(rt->dev); - - if(ipddp_mode == IPDDP_DECAP) - /* - * Pull off the excess room that should not be there. - * This is due to a hard-header problem. This is the - * quick fix for now though, till it breaks. - */ - skb_pull(skb, 35-(sizeof(struct ddpehdr)+1)); - - /* Create the Extended DDP header */ - ddp = (struct ddpehdr *)skb->data; - ddp->deh_len_hops = htons(skb->len + (1<<10)); - ddp->deh_sum = 0; - - /* - * For Localtalk we need aarp_send_ddp to strip the - * long DDP header and place a shot DDP header on it. - */ - if(rt->dev->type == ARPHRD_LOCALTLK) - { - ddp->deh_dnet = 0; /* FIXME more hops?? */ - ddp->deh_snet = 0; - } - else - { - ddp->deh_dnet = rt->at.s_net; /* FIXME more hops?? */ - ddp->deh_snet = our_addr->s_net; - } - ddp->deh_dnode = rt->at.s_node; - ddp->deh_snode = our_addr->s_node; - ddp->deh_dport = 72; - ddp->deh_sport = 72; - - *((__u8 *)(ddp+1)) = 22; /* ddp type = IP */ - - skb->protocol = htons(ETH_P_ATALK); /* Protocol has changed */ - - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - - aarp_send_ddp(rt->dev, skb, &rt->at, NULL); - - spin_unlock(&ipddp_route_lock); - - return NETDEV_TX_OK; -} - -/* - * Create a routing entry. We first verify that the - * record does not already exist. If it does we return -EEXIST - */ -static int ipddp_create(struct ipddp_route *new_rt) -{ - struct ipddp_route *rt = kmalloc(sizeof(*rt), GFP_KERNEL); - - if (rt == NULL) - return -ENOMEM; - - rt->ip = new_rt->ip; - rt->at = new_rt->at; - rt->next = NULL; - if ((rt->dev = atrtr_get_dev(&rt->at)) == NULL) { - kfree(rt); - return -ENETUNREACH; - } - - spin_lock_bh(&ipddp_route_lock); - if (__ipddp_find_route(rt)) { - spin_unlock_bh(&ipddp_route_lock); - kfree(rt); - return -EEXIST; - } - - rt->next = ipddp_route_list; - ipddp_route_list = rt; - - spin_unlock_bh(&ipddp_route_lock); - - return 0; -} - -/* - * Delete a route, we only delete a FULL match. - * If route does not exist we return -ENOENT. - */ -static int ipddp_delete(struct ipddp_route *rt) -{ - struct ipddp_route **r = &ipddp_route_list; - struct ipddp_route *tmp; - - spin_lock_bh(&ipddp_route_lock); - while((tmp = *r) != NULL) - { - if(tmp->ip == rt->ip && - tmp->at.s_net == rt->at.s_net && - tmp->at.s_node == rt->at.s_node) - { - *r = tmp->next; - spin_unlock_bh(&ipddp_route_lock); - kfree(tmp); - return 0; - } - r = &tmp->next; - } - - spin_unlock_bh(&ipddp_route_lock); - return -ENOENT; -} - -/* - * Find a routing entry, we only return a FULL match - */ -static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt) -{ - struct ipddp_route *f; - - for(f = ipddp_route_list; f != NULL; f = f->next) - { - if(f->ip == rt->ip && - f->at.s_net == rt->at.s_net && - f->at.s_node == rt->at.s_node) - return f; - } - - return NULL; -} - -static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - struct ipddp_route __user *rt = ifr->ifr_data; - struct ipddp_route rcp, rcp2, *rp; - - if(!capable(CAP_NET_ADMIN)) - return -EPERM; - - if(copy_from_user(&rcp, rt, sizeof(rcp))) - return -EFAULT; - - switch(cmd) - { - case SIOCADDIPDDPRT: - return ipddp_create(&rcp); - - case SIOCFINDIPDDPRT: - spin_lock_bh(&ipddp_route_lock); - rp = __ipddp_find_route(&rcp); - if (rp) - memcpy(&rcp2, rp, sizeof(rcp2)); - spin_unlock_bh(&ipddp_route_lock); - - if (rp) { - if (copy_to_user(rt, &rcp2, - sizeof(struct ipddp_route))) - return -EFAULT; - return 0; - } else - return -ENOENT; - - case SIOCDELIPDDPRT: - return ipddp_delete(&rcp); - - default: - return -EINVAL; - } -} - -static struct net_device *dev_ipddp; - -MODULE_LICENSE("GPL"); -module_param(ipddp_mode, int, 0); - -static int __init ipddp_init_module(void) -{ - dev_ipddp = ipddp_init(); - if (IS_ERR(dev_ipddp)) - return PTR_ERR(dev_ipddp); - return 0; -} - -static void __exit ipddp_cleanup_module(void) -{ - struct ipddp_route *p; - - unregister_netdev(dev_ipddp); - free_netdev(dev_ipddp); - - while (ipddp_route_list) { - p = ipddp_route_list->next; - kfree(ipddp_route_list); - ipddp_route_list = p; - } -} - -module_init(ipddp_init_module); -module_exit(ipddp_cleanup_module); diff --git a/drivers/net/appletalk/ipddp.h b/drivers/net/appletalk/ipddp.h deleted file mode 100644 index 531519da99a3..000000000000 --- a/drivers/net/appletalk/ipddp.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * ipddp.h: Header for IP-over-DDP driver for Linux. - */ - -#ifndef __LINUX_IPDDP_H -#define __LINUX_IPDDP_H - -#ifdef __KERNEL__ - -#define SIOCADDIPDDPRT (SIOCDEVPRIVATE) -#define SIOCDELIPDDPRT (SIOCDEVPRIVATE+1) -#define SIOCFINDIPDDPRT (SIOCDEVPRIVATE+2) - -struct ipddp_route -{ - struct net_device *dev; /* Carrier device */ - __be32 ip; /* IP address */ - struct atalk_addr at; /* Gateway appletalk address */ - int flags; - struct ipddp_route *next; -}; - -#define IPDDP_ENCAP 1 -#define IPDDP_DECAP 2 - -#endif /* __KERNEL__ */ -#endif /* __LINUX_IPDDP_H */ diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c deleted file mode 100644 index e69eead12ec7..000000000000 --- a/drivers/net/appletalk/ltpc.c +++ /dev/null @@ -1,1288 +0,0 @@ -/*** ltpc.c -- a driver for the LocalTalk PC card. - * - * Copyright (c) 1995,1996 Bradford W. Johnson - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * This is ALPHA code at best. It may not work for you. It may - * damage your equipment. It may damage your relations with other - * users of your network. Use it at your own risk! - * - * Based in part on: - * skeleton.c by Donald Becker - * dummy.c by Nick Holloway and Alan Cox - * loopback.c by Ross Biro, Fred van Kampen, Donald Becker - * the netatalk source code (UMICH) - * lots of work on the card... - * - * I do not have access to the (proprietary) SDK that goes with the card. - * If you do, I don't want to know about it, and you can probably write - * a better driver yourself anyway. This does mean that the pieces that - * talk to the card are guesswork on my part, so use at your own risk! - * - * This is my first try at writing Linux networking code, and is also - * guesswork. Again, use at your own risk! (Although on this part, I'd - * welcome suggestions) - * - * This is a loadable kernel module which seems to work at my site - * consisting of a 1.2.13 linux box running netatalk 1.3.3, and with - * the kernel support from 1.3.3b2 including patches routing.patch - * and ddp.disappears.from.chooser. In order to run it, you will need - * to patch ddp.c and aarp.c in the kernel, but only a little... - * - * I'm fairly confident that while this is arguably badly written, the - * problems that people experience will be "higher level", that is, with - * complications in the netatalk code. The driver itself doesn't do - * anything terribly complicated -- it pretends to be an ether device - * as far as netatalk is concerned, strips the DDP data out of the ether - * frame and builds a LLAP packet to send out the card. In the other - * direction, it receives LLAP frames from the card and builds a fake - * ether packet that it then tosses up to the networking code. You can - * argue (correctly) that this is an ugly way to do things, but it - * requires a minimal amount of fooling with the code in ddp.c and aarp.c. - * - * The card will do a lot more than is used here -- I *think* it has the - * layers up through ATP. Even if you knew how that part works (which I - * don't) it would be a big job to carve up the kernel ddp code to insert - * things at a higher level, and probably a bad idea... - * - * There are a number of other cards that do LocalTalk on the PC. If - * nobody finds any insurmountable (at the netatalk level) problems - * here, this driver should encourage people to put some work into the - * other cards (some of which I gather are still commercially available) - * and also to put hooks for LocalTalk into the official ddp code. - * - * I welcome comments and suggestions. This is my first try at Linux - * networking stuff, and there are probably lots of things that I did - * suboptimally. - * - ***/ - -/*** - * - * $Log: ltpc.c,v $ - * Revision 1.1.2.1 2000/03/01 05:35:07 jgarzik - * at and tr cleanup - * - * Revision 1.8 1997/01/28 05:44:54 bradford - * Clean up for non-module a little. - * Hacked about a bit to clean things up - Alan Cox - * Probably broken it from the origina 1.8 - * - - * 1998/11/09: David Huggins-Daines - * Cleaned up the initialization code to use the standard autoirq methods, - and to probe for things in the standard order of i/o, irq, dma. This - removes the "reset the reset" hack, because I couldn't figure out an - easy way to get the card to trigger an interrupt after it. - * Added support for passing configuration parameters on the kernel command - line and through insmod - * Changed the device name from "ltalk0" to "lt0", both to conform with the - other localtalk driver, and to clear up the inconsistency between the - module and the non-module versions of the driver :-) - * Added a bunch of comments (I was going to make some enums for the state - codes and the register offsets, but I'm still not sure exactly what their - semantics are) - * Don't poll anymore in interrupt-driven mode - * It seems to work as a module now (as of 2.1.127), but I don't think - I'm responsible for that... - - * - * Revision 1.7 1996/12/12 03:42:33 bradford - * DMA alloc cribbed from 3c505.c. - * - * Revision 1.6 1996/12/12 03:18:58 bradford - * Added virt_to_bus; works in 2.1.13. - * - * Revision 1.5 1996/12/12 03:13:22 root - * xmitQel initialization -- think through better though. - * - * Revision 1.4 1996/06/18 14:55:55 root - * Change names to ltpc. Tabs. Took a shot at dma alloc, - * although more needs to be done eventually. - * - * Revision 1.3 1996/05/22 14:59:39 root - * Change dev->open, dev->close to track dummy.c in 1.99.(around 7) - * - * Revision 1.2 1996/05/22 14:58:24 root - * Change tabs mostly. - * - * Revision 1.1 1996/04/23 04:45:09 root - * Initial revision - * - * Revision 0.16 1996/03/05 15:59:56 root - * Change ARPHRD_LOCALTLK definition to the "real" one. - * - * Revision 0.15 1996/03/05 06:28:30 root - * Changes for kernel 1.3.70. Still need a few patches to kernel, but - * it's getting closer. - * - * Revision 0.14 1996/02/25 17:38:32 root - * More cleanups. Removed query to card on get_stats. - * - * Revision 0.13 1996/02/21 16:27:40 root - * Refix debug_print_skb. Fix mac.raw gotcha that appeared in 1.3.65. - * Clean up receive code a little. - * - * Revision 0.12 1996/02/19 16:34:53 root - * Fix debug_print_skb. Kludge outgoing snet to 0 when using startup - * range. Change debug to mask: 1 for verbose, 2 for higher level stuff - * including packet printing, 4 for lower level (card i/o) stuff. - * - * Revision 0.11 1996/02/12 15:53:38 root - * Added router sends (requires new aarp.c patch) - * - * Revision 0.10 1996/02/11 00:19:35 root - * Change source LTALK_LOGGING debug switch to insmod ... debug=2. - * - * Revision 0.9 1996/02/10 23:59:35 root - * Fixed those fixes for 1.2 -- DANGER! The at.h that comes with netatalk - * has a *different* definition of struct sockaddr_at than the Linux kernel - * does. This is an "insidious and invidious" bug... - * (Actually the preceding comment is false -- it's the atalk.h in the - * ancient atalk-0.06 that's the problem) - * - * Revision 0.8 1996/02/10 19:09:00 root - * Merge 1.3 changes. Tested OK under 1.3.60. - * - * Revision 0.7 1996/02/10 17:56:56 root - * Added debug=1 parameter on insmod for debugging prints. Tried - * to fix timer unload on rmmod, but I don't think that's the problem. - * - * Revision 0.6 1995/12/31 19:01:09 root - * Clean up rmmod, irq comments per feedback from Corin Anderson (Thanks Corey!) - * Clean up initial probing -- sometimes the card wakes up latched in reset. - * - * Revision 0.5 1995/12/22 06:03:44 root - * Added comments in front and cleaned up a bit. - * This version sent out to people. - * - * Revision 0.4 1995/12/18 03:46:44 root - * Return shortDDP to longDDP fake to 0/0. Added command structs. - * - ***/ - -/* ltpc jumpers are: -* -* Interrupts -- set at most one. If none are set, the driver uses -* polled mode. Because the card was developed in the XT era, the -* original documentation refers to IRQ2. Since you'll be running -* this on an AT (or later) class machine, that really means IRQ9. -* -* SW1 IRQ 4 -* SW2 IRQ 3 -* SW3 IRQ 9 (2 in original card documentation only applies to XT) -* -* -* DMA -- choose DMA 1 or 3, and set both corresponding switches. -* -* SW4 DMA 3 -* SW5 DMA 1 -* SW6 DMA 3 -* SW7 DMA 1 -* -* -* I/O address -- choose one. -* -* SW8 220 / 240 -*/ - -/* To have some stuff logged, do -* insmod ltpc.o debug=1 -* -* For a whole bunch of stuff, use higher numbers. -* -* The default is 0, i.e. no messages except for the probe results. -*/ - -/* insmod-tweakable variables */ -static int debug; -#define DEBUG_VERBOSE 1 -#define DEBUG_UPPER 2 -#define DEBUG_LOWER 4 - -static int io; -static int irq; -static int dma; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* our stuff */ -#include "ltpc.h" - -static DEFINE_SPINLOCK(txqueue_lock); -static DEFINE_SPINLOCK(mbox_lock); - -/* function prototypes */ -static int do_read(struct net_device *dev, void *cbuf, int cbuflen, - void *dbuf, int dbuflen); -static int sendup_buffer (struct net_device *dev); - -/* Dma Memory related stuff, cribbed directly from 3c505.c */ - -static unsigned long dma_mem_alloc(int size) -{ - int order = get_order(size); - - return __get_dma_pages(GFP_KERNEL, order); -} - -/* DMA data buffer, DMA command buffer */ -static unsigned char *ltdmabuf; -static unsigned char *ltdmacbuf; - -/* private struct, holds our appletalk address */ - -struct ltpc_private -{ - struct atalk_addr my_addr; -}; - -/* transmit queue element struct */ - -struct xmitQel { - struct xmitQel *next; - /* command buffer */ - unsigned char *cbuf; - short cbuflen; - /* data buffer */ - unsigned char *dbuf; - short dbuflen; - unsigned char QWrite; /* read or write data */ - unsigned char mailbox; -}; - -/* the transmit queue itself */ - -static struct xmitQel *xmQhd, *xmQtl; - -static void enQ(struct xmitQel *qel) -{ - unsigned long flags; - qel->next = NULL; - - spin_lock_irqsave(&txqueue_lock, flags); - if (xmQtl) { - xmQtl->next = qel; - } else { - xmQhd = qel; - } - xmQtl = qel; - spin_unlock_irqrestore(&txqueue_lock, flags); - - if (debug & DEBUG_LOWER) - printk("enqueued a 0x%02x command\n",qel->cbuf[0]); -} - -static struct xmitQel *deQ(void) -{ - unsigned long flags; - int i; - struct xmitQel *qel=NULL; - - spin_lock_irqsave(&txqueue_lock, flags); - if (xmQhd) { - qel = xmQhd; - xmQhd = qel->next; - if(!xmQhd) xmQtl = NULL; - } - spin_unlock_irqrestore(&txqueue_lock, flags); - - if ((debug & DEBUG_LOWER) && qel) { - int n; - printk(KERN_DEBUG "ltpc: dequeued command "); - n = qel->cbuflen; - if (n>100) n=100; - for(i=0;icbuf[i]); - printk("\n"); - } - - return qel; -} - -/* and... the queue elements we'll be using */ -static struct xmitQel qels[16]; - -/* and their corresponding mailboxes */ -static unsigned char mailbox[16]; -static unsigned char mboxinuse[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - -static int wait_timeout(struct net_device *dev, int c) -{ - /* returns true if it stayed c */ - /* this uses base+6, but it's ok */ - int i; - - /* twenty second or so total */ - - for(i=0;i<200000;i++) { - if ( c != inb_p(dev->base_addr+6) ) return 0; - udelay(100); - } - return 1; /* timed out */ -} - -/* get the first free mailbox */ - -static int getmbox(void) -{ - unsigned long flags; - int i; - - spin_lock_irqsave(&mbox_lock, flags); - for(i=1;i<16;i++) if(!mboxinuse[i]) { - mboxinuse[i]=1; - spin_unlock_irqrestore(&mbox_lock, flags); - return i; - } - spin_unlock_irqrestore(&mbox_lock, flags); - return 0; -} - -/* read a command from the card */ -static void handlefc(struct net_device *dev) -{ - /* called *only* from idle, non-reentrant */ - int dma = dev->dma; - int base = dev->base_addr; - unsigned long flags; - - - flags=claim_dma_lock(); - disable_dma(dma); - clear_dma_ff(dma); - set_dma_mode(dma,DMA_MODE_READ); - set_dma_addr(dma,virt_to_bus(ltdmacbuf)); - set_dma_count(dma,50); - enable_dma(dma); - release_dma_lock(flags); - - inb_p(base+3); - inb_p(base+2); - - if ( wait_timeout(dev,0xfc) ) printk("timed out in handlefc\n"); -} - -/* read data from the card */ -static void handlefd(struct net_device *dev) -{ - int dma = dev->dma; - int base = dev->base_addr; - unsigned long flags; - - flags=claim_dma_lock(); - disable_dma(dma); - clear_dma_ff(dma); - set_dma_mode(dma,DMA_MODE_READ); - set_dma_addr(dma,virt_to_bus(ltdmabuf)); - set_dma_count(dma,800); - enable_dma(dma); - release_dma_lock(flags); - - inb_p(base+3); - inb_p(base+2); - - if ( wait_timeout(dev,0xfd) ) printk("timed out in handlefd\n"); - sendup_buffer(dev); -} - -static void handlewrite(struct net_device *dev) -{ - /* called *only* from idle, non-reentrant */ - /* on entry, 0xfb and ltdmabuf holds data */ - int dma = dev->dma; - int base = dev->base_addr; - unsigned long flags; - - flags=claim_dma_lock(); - disable_dma(dma); - clear_dma_ff(dma); - set_dma_mode(dma,DMA_MODE_WRITE); - set_dma_addr(dma,virt_to_bus(ltdmabuf)); - set_dma_count(dma,800); - enable_dma(dma); - release_dma_lock(flags); - - inb_p(base+3); - inb_p(base+2); - - if ( wait_timeout(dev,0xfb) ) { - flags=claim_dma_lock(); - printk("timed out in handlewrite, dma res %d\n", - get_dma_residue(dev->dma) ); - release_dma_lock(flags); - } -} - -static void handleread(struct net_device *dev) -{ - /* on entry, 0xfb */ - /* on exit, ltdmabuf holds data */ - int dma = dev->dma; - int base = dev->base_addr; - unsigned long flags; - - - flags=claim_dma_lock(); - disable_dma(dma); - clear_dma_ff(dma); - set_dma_mode(dma,DMA_MODE_READ); - set_dma_addr(dma,virt_to_bus(ltdmabuf)); - set_dma_count(dma,800); - enable_dma(dma); - release_dma_lock(flags); - - inb_p(base+3); - inb_p(base+2); - if ( wait_timeout(dev,0xfb) ) printk("timed out in handleread\n"); -} - -static void handlecommand(struct net_device *dev) -{ - /* on entry, 0xfa and ltdmacbuf holds command */ - int dma = dev->dma; - int base = dev->base_addr; - unsigned long flags; - - flags=claim_dma_lock(); - disable_dma(dma); - clear_dma_ff(dma); - set_dma_mode(dma,DMA_MODE_WRITE); - set_dma_addr(dma,virt_to_bus(ltdmacbuf)); - set_dma_count(dma,50); - enable_dma(dma); - release_dma_lock(flags); - inb_p(base+3); - inb_p(base+2); - if ( wait_timeout(dev,0xfa) ) printk("timed out in handlecommand\n"); -} - -/* ready made command for getting the result from the card */ -static unsigned char rescbuf[2] = {LT_GETRESULT,0}; -static unsigned char resdbuf[2]; - -static int QInIdle; - -/* idle expects to be called with the IRQ line high -- either because of - * an interrupt, or because the line is tri-stated - */ - -static void idle(struct net_device *dev) -{ - unsigned long flags; - int state; - /* FIXME This is initialized to shut the warning up, but I need to - * think this through again. - */ - struct xmitQel *q = NULL; - int oops; - int i; - int base = dev->base_addr; - - spin_lock_irqsave(&txqueue_lock, flags); - if(QInIdle) { - spin_unlock_irqrestore(&txqueue_lock, flags); - return; - } - QInIdle = 1; - spin_unlock_irqrestore(&txqueue_lock, flags); - - /* this tri-states the IRQ line */ - (void) inb_p(base+6); - - oops = 100; - -loop: - if (0>oops--) { - printk("idle: looped too many times\n"); - goto done; - } - - state = inb_p(base+6); - if (state != inb_p(base+6)) goto loop; - - switch(state) { - case 0xfc: - /* incoming command */ - if (debug & DEBUG_LOWER) printk("idle: fc\n"); - handlefc(dev); - break; - case 0xfd: - /* incoming data */ - if(debug & DEBUG_LOWER) printk("idle: fd\n"); - handlefd(dev); - break; - case 0xf9: - /* result ready */ - if (debug & DEBUG_LOWER) printk("idle: f9\n"); - if(!mboxinuse[0]) { - mboxinuse[0] = 1; - qels[0].cbuf = rescbuf; - qels[0].cbuflen = 2; - qels[0].dbuf = resdbuf; - qels[0].dbuflen = 2; - qels[0].QWrite = 0; - qels[0].mailbox = 0; - enQ(&qels[0]); - } - inb_p(dev->base_addr+1); - inb_p(dev->base_addr+0); - if( wait_timeout(dev,0xf9) ) - printk("timed out idle f9\n"); - break; - case 0xf8: - /* ?? */ - if (xmQhd) { - inb_p(dev->base_addr+1); - inb_p(dev->base_addr+0); - if(wait_timeout(dev,0xf8) ) - printk("timed out idle f8\n"); - } else { - goto done; - } - break; - case 0xfa: - /* waiting for command */ - if(debug & DEBUG_LOWER) printk("idle: fa\n"); - if (xmQhd) { - q=deQ(); - memcpy(ltdmacbuf,q->cbuf,q->cbuflen); - ltdmacbuf[1] = q->mailbox; - if (debug>1) { - int n; - printk("ltpc: sent command "); - n = q->cbuflen; - if (n>100) n=100; - for(i=0;iQWrite) { - memcpy(ltdmabuf,q->dbuf,q->dbuflen); - handlewrite(dev); - } else { - handleread(dev); - /* non-zero mailbox numbers are for - commmands, 0 is for GETRESULT - requests */ - if(q->mailbox) { - memcpy(q->dbuf,ltdmabuf,q->dbuflen); - } else { - /* this was a result */ - mailbox[ 0x0f & ltdmabuf[0] ] = ltdmabuf[1]; - mboxinuse[0]=0; - } - } - break; - } - goto loop; - -done: - QInIdle=0; - - /* now set the interrupts back as appropriate */ - /* the first read takes it out of tri-state (but still high) */ - /* the second resets it */ - /* note that after this point, any read of base+6 will - trigger an interrupt */ - - if (dev->irq) { - inb_p(base+7); - inb_p(base+7); - } -} - - -static int do_write(struct net_device *dev, void *cbuf, int cbuflen, - void *dbuf, int dbuflen) -{ - - int i = getmbox(); - int ret; - - if(i) { - qels[i].cbuf = (unsigned char *) cbuf; - qels[i].cbuflen = cbuflen; - qels[i].dbuf = (unsigned char *) dbuf; - qels[i].dbuflen = dbuflen; - qels[i].QWrite = 1; - qels[i].mailbox = i; /* this should be initted rather */ - enQ(&qels[i]); - idle(dev); - ret = mailbox[i]; - mboxinuse[i]=0; - return ret; - } - printk("ltpc: could not allocate mbox\n"); - return -1; -} - -static int do_read(struct net_device *dev, void *cbuf, int cbuflen, - void *dbuf, int dbuflen) -{ - - int i = getmbox(); - int ret; - - if(i) { - qels[i].cbuf = (unsigned char *) cbuf; - qels[i].cbuflen = cbuflen; - qels[i].dbuf = (unsigned char *) dbuf; - qels[i].dbuflen = dbuflen; - qels[i].QWrite = 0; - qels[i].mailbox = i; /* this should be initted rather */ - enQ(&qels[i]); - idle(dev); - ret = mailbox[i]; - mboxinuse[i]=0; - return ret; - } - printk("ltpc: could not allocate mbox\n"); - return -1; -} - -/* end of idle handlers -- what should be seen is do_read, do_write */ - -static struct timer_list ltpc_timer; - -static netdev_tx_t ltpc_xmit(struct sk_buff *skb, struct net_device *dev); - -static int read_30 ( struct net_device *dev) -{ - lt_command c; - c.getflags.command = LT_GETFLAGS; - return do_read(dev, &c, sizeof(c.getflags),&c,0); -} - -static int set_30 (struct net_device *dev,int x) -{ - lt_command c; - c.setflags.command = LT_SETFLAGS; - c.setflags.flags = x; - return do_write(dev, &c, sizeof(c.setflags),&c,0); -} - -/* LLAP to DDP translation */ - -static int sendup_buffer (struct net_device *dev) -{ - /* on entry, command is in ltdmacbuf, data in ltdmabuf */ - /* called from idle, non-reentrant */ - - int dnode, snode, llaptype, len; - int sklen; - struct sk_buff *skb; - struct lt_rcvlap *ltc = (struct lt_rcvlap *) ltdmacbuf; - - if (ltc->command != LT_RCVLAP) { - printk("unknown command 0x%02x from ltpc card\n",ltc->command); - return -1; - } - dnode = ltc->dnode; - snode = ltc->snode; - llaptype = ltc->laptype; - len = ltc->length; - - sklen = len; - if (llaptype == 1) - sklen += 8; /* correct for short ddp */ - if(sklen > 800) { - printk(KERN_INFO "%s: nonsense length in ltpc command 0x14: 0x%08x\n", - dev->name,sklen); - return -1; - } - - if ( (llaptype==0) || (llaptype>2) ) { - printk(KERN_INFO "%s: unknown LLAP type: %d\n",dev->name,llaptype); - return -1; - } - - - skb = dev_alloc_skb(3+sklen); - if (skb == NULL) - { - printk("%s: dropping packet due to memory squeeze.\n", - dev->name); - return -1; - } - skb->dev = dev; - - if (sklen > len) - skb_reserve(skb,8); - skb_put(skb,len+3); - skb->protocol = htons(ETH_P_LOCALTALK); - /* add LLAP header */ - skb->data[0] = dnode; - skb->data[1] = snode; - skb->data[2] = llaptype; - skb_reset_mac_header(skb); /* save pointer to llap header */ - skb_pull(skb,3); - - /* copy ddp(s,e)hdr + contents */ - skb_copy_to_linear_data(skb, ltdmabuf, len); - - skb_reset_transport_header(skb); - - dev->stats.rx_packets++; - dev->stats.rx_bytes += skb->len; - - /* toss it onwards */ - netif_rx(skb); - return 0; -} - -/* the handler for the board interrupt */ - -static irqreturn_t -ltpc_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - - if (dev==NULL) { - printk("ltpc_interrupt: unknown device.\n"); - return IRQ_NONE; - } - - inb_p(dev->base_addr+6); /* disable further interrupts from board */ - - idle(dev); /* handle whatever is coming in */ - - /* idle re-enables interrupts from board */ - - return IRQ_HANDLED; -} - -/*** - * - * The ioctls that the driver responds to are: - * - * SIOCSIFADDR -- do probe using the passed node hint. - * SIOCGIFADDR -- return net, node. - * - * some of this stuff should be done elsewhere. - * - ***/ - -static int ltpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - struct sockaddr_at *sa = (struct sockaddr_at *) &ifr->ifr_addr; - /* we'll keep the localtalk node address in dev->pa_addr */ - struct ltpc_private *ltpc_priv = netdev_priv(dev); - struct atalk_addr *aa = <pc_priv->my_addr; - struct lt_init c; - int ltflags; - - if(debug & DEBUG_VERBOSE) printk("ltpc_ioctl called\n"); - - switch(cmd) { - case SIOCSIFADDR: - - aa->s_net = sa->sat_addr.s_net; - - /* this does the probe and returns the node addr */ - c.command = LT_INIT; - c.hint = sa->sat_addr.s_node; - - aa->s_node = do_read(dev,&c,sizeof(c),&c,0); - - /* get all llap frames raw */ - ltflags = read_30(dev); - ltflags |= LT_FLAG_ALLLAP; - set_30 (dev,ltflags); - - dev->broadcast[0] = 0xFF; - dev->dev_addr[0] = aa->s_node; - - dev->addr_len=1; - - return 0; - - case SIOCGIFADDR: - - sa->sat_addr.s_net = aa->s_net; - sa->sat_addr.s_node = aa->s_node; - - return 0; - - default: - return -EINVAL; - } -} - -static void set_multicast_list(struct net_device *dev) -{ - /* This needs to be present to keep netatalk happy. */ - /* Actually netatalk needs fixing! */ -} - -static int ltpc_poll_counter; - -static void ltpc_poll(unsigned long l) -{ - struct net_device *dev = (struct net_device *) l; - - del_timer(<pc_timer); - - if(debug & DEBUG_VERBOSE) { - if (!ltpc_poll_counter) { - ltpc_poll_counter = 50; - printk("ltpc poll is alive\n"); - } - ltpc_poll_counter--; - } - - if (!dev) - return; /* we've been downed */ - - /* poll 20 times per second */ - idle(dev); - ltpc_timer.expires = jiffies + HZ/20; - - add_timer(<pc_timer); -} - -/* DDP to LLAP translation */ - -static netdev_tx_t ltpc_xmit(struct sk_buff *skb, struct net_device *dev) -{ - /* in kernel 1.3.xx, on entry skb->data points to ddp header, - * and skb->len is the length of the ddp data + ddp header - */ - int i; - struct lt_sendlap cbuf; - unsigned char *hdr; - - cbuf.command = LT_SENDLAP; - cbuf.dnode = skb->data[0]; - cbuf.laptype = skb->data[2]; - skb_pull(skb,3); /* skip past LLAP header */ - cbuf.length = skb->len; /* this is host order */ - skb_reset_transport_header(skb); - - if(debug & DEBUG_UPPER) { - printk("command "); - for(i=0;i<6;i++) - printk("%02x ",((unsigned char *)&cbuf)[i]); - printk("\n"); - } - - hdr = skb_transport_header(skb); - do_write(dev, &cbuf, sizeof(cbuf), hdr, skb->len); - - if(debug & DEBUG_UPPER) { - printk("sent %d ddp bytes\n",skb->len); - for (i = 0; i < skb->len; i++) - printk("%02x ", hdr[i]); - printk("\n"); - } - - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - - dev_kfree_skb(skb); - return NETDEV_TX_OK; -} - -/* initialization stuff */ - -static int __init ltpc_probe_dma(int base, int dma) -{ - int want = (dma == 3) ? 2 : (dma == 1) ? 1 : 3; - unsigned long timeout; - unsigned long f; - - if (want & 1) { - if (request_dma(1,"ltpc")) { - want &= ~1; - } else { - f=claim_dma_lock(); - disable_dma(1); - clear_dma_ff(1); - set_dma_mode(1,DMA_MODE_WRITE); - set_dma_addr(1,virt_to_bus(ltdmabuf)); - set_dma_count(1,sizeof(struct lt_mem)); - enable_dma(1); - release_dma_lock(f); - } - } - if (want & 2) { - if (request_dma(3,"ltpc")) { - want &= ~2; - } else { - f=claim_dma_lock(); - disable_dma(3); - clear_dma_ff(3); - set_dma_mode(3,DMA_MODE_WRITE); - set_dma_addr(3,virt_to_bus(ltdmabuf)); - set_dma_count(3,sizeof(struct lt_mem)); - enable_dma(3); - release_dma_lock(f); - } - } - /* set up request */ - - /* FIXME -- do timings better! */ - - ltdmabuf[0] = LT_READMEM; - ltdmabuf[1] = 1; /* mailbox */ - ltdmabuf[2] = 0; ltdmabuf[3] = 0; /* address */ - ltdmabuf[4] = 0; ltdmabuf[5] = 1; /* read 0x0100 bytes */ - ltdmabuf[6] = 0; /* dunno if this is necessary */ - - inb_p(io+1); - inb_p(io+0); - timeout = jiffies+100*HZ/100; - while(time_before(jiffies, timeout)) { - if ( 0xfa == inb_p(io+6) ) break; - } - - inb_p(io+3); - inb_p(io+2); - while(time_before(jiffies, timeout)) { - if ( 0xfb == inb_p(io+6) ) break; - } - - /* release the other dma channel (if we opened both of them) */ - - if ((want & 2) && (get_dma_residue(3)==sizeof(struct lt_mem))) { - want &= ~2; - free_dma(3); - } - - if ((want & 1) && (get_dma_residue(1)==sizeof(struct lt_mem))) { - want &= ~1; - free_dma(1); - } - - if (!want) - return 0; - - return (want & 2) ? 3 : 1; -} - -static const struct net_device_ops ltpc_netdev = { - .ndo_start_xmit = ltpc_xmit, - .ndo_do_ioctl = ltpc_ioctl, - .ndo_set_multicast_list = set_multicast_list, -}; - -struct net_device * __init ltpc_probe(void) -{ - struct net_device *dev; - int err = -ENOMEM; - int x=0,y=0; - int autoirq; - unsigned long f; - unsigned long timeout; - - dev = alloc_ltalkdev(sizeof(struct ltpc_private)); - if (!dev) - goto out; - - /* probe for the I/O port address */ - - if (io != 0x240 && request_region(0x220,8,"ltpc")) { - x = inb_p(0x220+6); - if ( (x!=0xff) && (x>=0xf0) ) { - io = 0x220; - goto got_port; - } - release_region(0x220,8); - } - if (io != 0x220 && request_region(0x240,8,"ltpc")) { - y = inb_p(0x240+6); - if ( (y!=0xff) && (y>=0xf0) ){ - io = 0x240; - goto got_port; - } - release_region(0x240,8); - } - - /* give up in despair */ - printk(KERN_ERR "LocalTalk card not found; 220 = %02x, 240 = %02x.\n", x,y); - err = -ENODEV; - goto out1; - - got_port: - /* probe for the IRQ line */ - if (irq < 2) { - unsigned long irq_mask; - - irq_mask = probe_irq_on(); - /* reset the interrupt line */ - inb_p(io+7); - inb_p(io+7); - /* trigger an interrupt (I hope) */ - inb_p(io+6); - mdelay(2); - autoirq = probe_irq_off(irq_mask); - - if (autoirq == 0) { - printk(KERN_ERR "ltpc: probe at %#x failed to detect IRQ line.\n", io); - } else { - irq = autoirq; - } - } - - /* allocate a DMA buffer */ - ltdmabuf = (unsigned char *) dma_mem_alloc(1000); - if (!ltdmabuf) { - printk(KERN_ERR "ltpc: mem alloc failed\n"); - err = -ENOMEM; - goto out2; - } - - ltdmacbuf = <dmabuf[800]; - - if(debug & DEBUG_VERBOSE) { - printk("ltdmabuf pointer %08lx\n",(unsigned long) ltdmabuf); - } - - /* reset the card */ - - inb_p(io+1); - inb_p(io+3); - - msleep(20); - - inb_p(io+0); - inb_p(io+2); - inb_p(io+7); /* clear reset */ - inb_p(io+4); - inb_p(io+5); - inb_p(io+5); /* enable dma */ - inb_p(io+6); /* tri-state interrupt line */ - - ssleep(1); - - /* now, figure out which dma channel we're using, unless it's - already been specified */ - /* well, 0 is a legal DMA channel, but the LTPC card doesn't - use it... */ - dma = ltpc_probe_dma(io, dma); - if (!dma) { /* no dma channel */ - printk(KERN_ERR "No DMA channel found on ltpc card.\n"); - err = -ENODEV; - goto out3; - } - - /* print out friendly message */ - if(irq) - printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, IR%d, DMA%d.\n",io,irq,dma); - else - printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, DMA%d. Using polled mode.\n",io,dma); - - dev->netdev_ops = <pc_netdev; - dev->base_addr = io; - dev->irq = irq; - dev->dma = dma; - - /* the card will want to send a result at this point */ - /* (I think... leaving out this part makes the kernel crash, - so I put it back in...) */ - - f=claim_dma_lock(); - disable_dma(dma); - clear_dma_ff(dma); - set_dma_mode(dma,DMA_MODE_READ); - set_dma_addr(dma,virt_to_bus(ltdmabuf)); - set_dma_count(dma,0x100); - enable_dma(dma); - release_dma_lock(f); - - (void) inb_p(io+3); - (void) inb_p(io+2); - timeout = jiffies+100*HZ/100; - - while(time_before(jiffies, timeout)) { - if( 0xf9 == inb_p(io+6)) - break; - schedule(); - } - - if(debug & DEBUG_VERBOSE) { - printk("setting up timer and irq\n"); - } - - /* grab it and don't let go :-) */ - if (irq && request_irq( irq, ltpc_interrupt, 0, "ltpc", dev) >= 0) - { - (void) inb_p(io+7); /* enable interrupts from board */ - (void) inb_p(io+7); /* and reset irq line */ - } else { - if( irq ) - printk(KERN_ERR "ltpc: IRQ already in use, using polled mode.\n"); - dev->irq = 0; - /* polled mode -- 20 times per second */ - /* this is really, really slow... should it poll more often? */ - init_timer(<pc_timer); - ltpc_timer.function=ltpc_poll; - ltpc_timer.data = (unsigned long) dev; - - ltpc_timer.expires = jiffies + HZ/20; - add_timer(<pc_timer); - } - err = register_netdev(dev); - if (err) - goto out4; - - return NULL; -out4: - del_timer_sync(<pc_timer); - if (dev->irq) - free_irq(dev->irq, dev); -out3: - free_pages((unsigned long)ltdmabuf, get_order(1000)); -out2: - release_region(io, 8); -out1: - free_netdev(dev); -out: - return ERR_PTR(err); -} - -#ifndef MODULE -/* handles "ltpc=io,irq,dma" kernel command lines */ -static int __init ltpc_setup(char *str) -{ - int ints[5]; - - str = get_options(str, ARRAY_SIZE(ints), ints); - - if (ints[0] == 0) { - if (str && !strncmp(str, "auto", 4)) { - /* do nothing :-) */ - } - else { - /* usage message */ - printk (KERN_ERR - "ltpc: usage: ltpc=auto|iobase[,irq[,dma]]\n"); - return 0; - } - } else { - io = ints[1]; - if (ints[0] > 1) { - irq = ints[2]; - } - if (ints[0] > 2) { - dma = ints[3]; - } - /* ignore any other parameters */ - } - return 1; -} - -__setup("ltpc=", ltpc_setup); -#endif /* MODULE */ - -static struct net_device *dev_ltpc; - -#ifdef MODULE - -MODULE_LICENSE("GPL"); -module_param(debug, int, 0); -module_param(io, int, 0); -module_param(irq, int, 0); -module_param(dma, int, 0); - - -static int __init ltpc_module_init(void) -{ - if(io == 0) - printk(KERN_NOTICE - "ltpc: Autoprobing is not recommended for modules\n"); - - dev_ltpc = ltpc_probe(); - if (IS_ERR(dev_ltpc)) - return PTR_ERR(dev_ltpc); - return 0; -} -module_init(ltpc_module_init); -#endif - -static void __exit ltpc_cleanup(void) -{ - - if(debug & DEBUG_VERBOSE) printk("unregister_netdev\n"); - unregister_netdev(dev_ltpc); - - ltpc_timer.data = 0; /* signal the poll routine that we're done */ - - del_timer_sync(<pc_timer); - - if(debug & DEBUG_VERBOSE) printk("freeing irq\n"); - - if (dev_ltpc->irq) - free_irq(dev_ltpc->irq, dev_ltpc); - - if(debug & DEBUG_VERBOSE) printk("freeing dma\n"); - - if (dev_ltpc->dma) - free_dma(dev_ltpc->dma); - - if(debug & DEBUG_VERBOSE) printk("freeing ioaddr\n"); - - if (dev_ltpc->base_addr) - release_region(dev_ltpc->base_addr,8); - - free_netdev(dev_ltpc); - - if(debug & DEBUG_VERBOSE) printk("free_pages\n"); - - free_pages( (unsigned long) ltdmabuf, get_order(1000)); - - if(debug & DEBUG_VERBOSE) printk("returning from cleanup_module\n"); -} - -module_exit(ltpc_cleanup); diff --git a/drivers/net/appletalk/ltpc.h b/drivers/net/appletalk/ltpc.h deleted file mode 100644 index cd30544a3729..000000000000 --- a/drivers/net/appletalk/ltpc.h +++ /dev/null @@ -1,73 +0,0 @@ -/*** ltpc.h - * - * - ***/ - -#define LT_GETRESULT 0x00 -#define LT_WRITEMEM 0x01 -#define LT_READMEM 0x02 -#define LT_GETFLAGS 0x04 -#define LT_SETFLAGS 0x05 -#define LT_INIT 0x10 -#define LT_SENDLAP 0x13 -#define LT_RCVLAP 0x14 - -/* the flag that we care about */ -#define LT_FLAG_ALLLAP 0x04 - -struct lt_getresult { - unsigned char command; - unsigned char mailbox; -}; - -struct lt_mem { - unsigned char command; - unsigned char mailbox; - unsigned short addr; /* host order */ - unsigned short length; /* host order */ -}; - -struct lt_setflags { - unsigned char command; - unsigned char mailbox; - unsigned char flags; -}; - -struct lt_getflags { - unsigned char command; - unsigned char mailbox; -}; - -struct lt_init { - unsigned char command; - unsigned char mailbox; - unsigned char hint; -}; - -struct lt_sendlap { - unsigned char command; - unsigned char mailbox; - unsigned char dnode; - unsigned char laptype; - unsigned short length; /* host order */ -}; - -struct lt_rcvlap { - unsigned char command; - unsigned char dnode; - unsigned char snode; - unsigned char laptype; - unsigned short length; /* host order */ -}; - -union lt_command { - struct lt_getresult getresult; - struct lt_mem mem; - struct lt_setflags setflags; - struct lt_getflags getflags; - struct lt_init init; - struct lt_sendlap sendlap; - struct lt_rcvlap rcvlap; -}; -typedef union lt_command lt_command; - diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index b80755da5394..584d4e264807 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -169,6 +169,8 @@ source "drivers/staging/bcm/Kconfig" source "drivers/staging/ft1000/Kconfig" +source "drivers/staging/appletalk/Kconfig" + source "drivers/staging/intel_sst/Kconfig" source "drivers/staging/speakup/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index fd26509e5efa..88f0c64e7e58 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -65,6 +65,7 @@ obj-$(CONFIG_ATH6K_LEGACY) += ath6kl/ obj-$(CONFIG_USB_ENESTORAGE) += keucr/ obj-$(CONFIG_BCM_WIMAX) += bcm/ obj-$(CONFIG_FT1000) += ft1000/ +obj-$(CONFIG_DEV_APPLETALK) += appletalk/ obj-$(CONFIG_SND_INTEL_SST) += intel_sst/ obj-$(CONFIG_SPEAKUP) += speakup/ obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/ diff --git a/drivers/staging/appletalk/Kconfig b/drivers/staging/appletalk/Kconfig new file mode 100644 index 000000000000..0b376a990972 --- /dev/null +++ b/drivers/staging/appletalk/Kconfig @@ -0,0 +1,126 @@ +# +# Appletalk driver configuration +# +config ATALK + tristate "Appletalk protocol support" + depends on BKL # waiting to be removed from net/appletalk/ddp.c + select LLC + ---help--- + AppleTalk is the protocol that Apple computers can use to communicate + on a network. If your Linux box is connected to such a network and you + wish to connect to it, say Y. You will need to use the netatalk package + so that your Linux box can act as a print and file server for Macs as + well as access AppleTalk printers. Check out + on the WWW for details. + EtherTalk is the name used for AppleTalk over Ethernet and the + cheaper and slower LocalTalk is AppleTalk over a proprietary Apple + network using serial links. EtherTalk and LocalTalk are fully + supported by Linux. + + General information about how to connect Linux, Windows machines and + Macs is on the WWW at . The + NET3-4-HOWTO, available from + , contains valuable + information as well. + + To compile this driver as a module, choose M here: the module will be + called appletalk. You almost certainly want to compile it as a + module so you can restart your AppleTalk stack without rebooting + your machine. I hear that the GNU boycott of Apple is over, so + even politically correct people are allowed to say Y here. + +config DEV_APPLETALK + tristate "Appletalk interfaces support" + depends on ATALK + help + AppleTalk is the protocol that Apple computers can use to communicate + on a network. If your Linux box is connected to such a network, and wish + to do IP over it, or you have a LocalTalk card and wish to use it to + connect to the AppleTalk network, say Y. + + +config LTPC + tristate "Apple/Farallon LocalTalk PC support" + depends on DEV_APPLETALK && (ISA || EISA) && ISA_DMA_API + help + This allows you to use the AppleTalk PC card to connect to LocalTalk + networks. The card is also known as the Farallon PhoneNet PC card. + If you are in doubt, this card is the one with the 65C02 chip on it. + You also need version 1.3.3 or later of the netatalk package. + This driver is experimental, which means that it may not work. + See the file . + +config COPS + tristate "COPS LocalTalk PC support" + depends on DEV_APPLETALK && (ISA || EISA) + help + This allows you to use COPS AppleTalk cards to connect to LocalTalk + networks. You also need version 1.3.3 or later of the netatalk + package. This driver is experimental, which means that it may not + work. This driver will only work if you choose "AppleTalk DDP" + networking support, above. + Please read the file . + +config COPS_DAYNA + bool "Dayna firmware support" + depends on COPS + help + Support COPS compatible cards with Dayna style firmware (Dayna + DL2000/ Daynatalk/PC (half length), COPS LT-95, Farallon PhoneNET PC + III, Farallon PhoneNET PC II). + +config COPS_TANGENT + bool "Tangent firmware support" + depends on COPS + help + Support COPS compatible cards with Tangent style firmware (Tangent + ATB_II, Novell NL-1000, Daystar Digital LT-200. + +config IPDDP + tristate "Appletalk-IP driver support" + depends on DEV_APPLETALK && ATALK + ---help--- + This allows IP networking for users who only have AppleTalk + networking available. This feature is experimental. With this + driver, you can encapsulate IP inside AppleTalk (e.g. if your Linux + box is stuck on an AppleTalk only network) or decapsulate (e.g. if + you want your Linux box to act as an Internet gateway for a zoo of + AppleTalk connected Macs). Please see the file + for more information. + + If you say Y here, the AppleTalk-IP support will be compiled into + the kernel. In this case, you can either use encapsulation or + decapsulation, but not both. With the following two questions, you + decide which one you want. + + To compile the AppleTalk-IP support as a module, choose M here: the + module will be called ipddp. + In this case, you will be able to use both encapsulation and + decapsulation simultaneously, by loading two copies of the module + and specifying different values for the module option ipddp_mode. + +config IPDDP_ENCAP + bool "IP to Appletalk-IP Encapsulation support" + depends on IPDDP + help + If you say Y here, the AppleTalk-IP code will be able to encapsulate + IP packets inside AppleTalk frames; this is useful if your Linux box + is stuck on an AppleTalk network (which hopefully contains a + decapsulator somewhere). Please see + for more information. If + you said Y to "AppleTalk-IP driver support" above and you say Y + here, then you cannot say Y to "AppleTalk-IP to IP Decapsulation + support", below. + +config IPDDP_DECAP + bool "Appletalk-IP to IP Decapsulation support" + depends on IPDDP + help + If you say Y here, the AppleTalk-IP code will be able to decapsulate + AppleTalk-IP frames to IP packets; this is useful if you want your + Linux box to act as an Internet gateway for an AppleTalk network. + Please see for more + information. If you said Y to "AppleTalk-IP driver support" above + and you say Y here, then you cannot say Y to "IP to AppleTalk-IP + Encapsulation support", above. + diff --git a/drivers/staging/appletalk/Makefile b/drivers/staging/appletalk/Makefile new file mode 100644 index 000000000000..2a5129a5c6bc --- /dev/null +++ b/drivers/staging/appletalk/Makefile @@ -0,0 +1,12 @@ +# +# Makefile for drivers/staging/appletalk +# +obj-$(CONFIG_ATALK) += appletalk.o + +appletalk-y := aarp.o ddp.o dev.o +appletalk-$(CONFIG_PROC_FS) += atalk_proc.o +appletalk-$(CONFIG_SYSCTL) += sysctl_net_atalk.o + +obj-$(CONFIG_IPDDP) += ipddp.o +obj-$(CONFIG_COPS) += cops.o +obj-$(CONFIG_LTPC) += ltpc.o diff --git a/drivers/staging/appletalk/aarp.c b/drivers/staging/appletalk/aarp.c new file mode 100644 index 000000000000..7163a1dd501f --- /dev/null +++ b/drivers/staging/appletalk/aarp.c @@ -0,0 +1,1063 @@ +/* + * AARP: An implementation of the AppleTalk AARP protocol for + * Ethernet 'ELAP'. + * + * Alan Cox + * + * This doesn't fit cleanly with the IP arp. Potentially we can use + * the generic neighbour discovery code to clean this up. + * + * FIXME: + * We ought to handle the retransmits with a single list and a + * separate fast timer for when it is needed. + * Use neighbour discovery code. + * Token Ring Support. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * + * References: + * Inside AppleTalk (2nd Ed). + * Fixes: + * Jaume Grau - flush caches on AARP_PROBE + * Rob Newberry - Added proxy AARP and AARP proc fs, + * moved probing from DDP module. + * Arnaldo C. Melo - don't mangle rx packets + * + */ + +#include +#include +#include +#include +#include +#include "atalk.h" +#include +#include +#include +#include + +int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME; +int sysctl_aarp_tick_time = AARP_TICK_TIME; +int sysctl_aarp_retransmit_limit = AARP_RETRANSMIT_LIMIT; +int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME; + +/* Lists of aarp entries */ +/** + * struct aarp_entry - AARP entry + * @last_sent - Last time we xmitted the aarp request + * @packet_queue - Queue of frames wait for resolution + * @status - Used for proxy AARP + * expires_at - Entry expiry time + * target_addr - DDP Address + * dev - Device to use + * hwaddr - Physical i/f address of target/router + * xmit_count - When this hits 10 we give up + * next - Next entry in chain + */ +struct aarp_entry { + /* These first two are only used for unresolved entries */ + unsigned long last_sent; + struct sk_buff_head packet_queue; + int status; + unsigned long expires_at; + struct atalk_addr target_addr; + struct net_device *dev; + char hwaddr[6]; + unsigned short xmit_count; + struct aarp_entry *next; +}; + +/* Hashed list of resolved, unresolved and proxy entries */ +static struct aarp_entry *resolved[AARP_HASH_SIZE]; +static struct aarp_entry *unresolved[AARP_HASH_SIZE]; +static struct aarp_entry *proxies[AARP_HASH_SIZE]; +static int unresolved_count; + +/* One lock protects it all. */ +static DEFINE_RWLOCK(aarp_lock); + +/* Used to walk the list and purge/kick entries. */ +static struct timer_list aarp_timer; + +/* + * Delete an aarp queue + * + * Must run under aarp_lock. + */ +static void __aarp_expire(struct aarp_entry *a) +{ + skb_queue_purge(&a->packet_queue); + kfree(a); +} + +/* + * Send an aarp queue entry request + * + * Must run under aarp_lock. + */ +static void __aarp_send_query(struct aarp_entry *a) +{ + static unsigned char aarp_eth_multicast[ETH_ALEN] = + { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; + struct net_device *dev = a->dev; + struct elapaarp *eah; + int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length; + struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); + struct atalk_addr *sat = atalk_find_dev_addr(dev); + + if (!skb) + return; + + if (!sat) { + kfree_skb(skb); + return; + } + + /* Set up the buffer */ + skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length); + skb_reset_network_header(skb); + skb_reset_transport_header(skb); + skb_put(skb, sizeof(*eah)); + skb->protocol = htons(ETH_P_ATALK); + skb->dev = dev; + eah = aarp_hdr(skb); + + /* Set up the ARP */ + eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); + eah->pa_type = htons(ETH_P_ATALK); + eah->hw_len = ETH_ALEN; + eah->pa_len = AARP_PA_ALEN; + eah->function = htons(AARP_REQUEST); + + memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN); + + eah->pa_src_zero = 0; + eah->pa_src_net = sat->s_net; + eah->pa_src_node = sat->s_node; + + memset(eah->hw_dst, '\0', ETH_ALEN); + + eah->pa_dst_zero = 0; + eah->pa_dst_net = a->target_addr.s_net; + eah->pa_dst_node = a->target_addr.s_node; + + /* Send it */ + aarp_dl->request(aarp_dl, skb, aarp_eth_multicast); + /* Update the sending count */ + a->xmit_count++; + a->last_sent = jiffies; +} + +/* This runs under aarp_lock and in softint context, so only atomic memory + * allocations can be used. */ +static void aarp_send_reply(struct net_device *dev, struct atalk_addr *us, + struct atalk_addr *them, unsigned char *sha) +{ + struct elapaarp *eah; + int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length; + struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); + + if (!skb) + return; + + /* Set up the buffer */ + skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length); + skb_reset_network_header(skb); + skb_reset_transport_header(skb); + skb_put(skb, sizeof(*eah)); + skb->protocol = htons(ETH_P_ATALK); + skb->dev = dev; + eah = aarp_hdr(skb); + + /* Set up the ARP */ + eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); + eah->pa_type = htons(ETH_P_ATALK); + eah->hw_len = ETH_ALEN; + eah->pa_len = AARP_PA_ALEN; + eah->function = htons(AARP_REPLY); + + memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN); + + eah->pa_src_zero = 0; + eah->pa_src_net = us->s_net; + eah->pa_src_node = us->s_node; + + if (!sha) + memset(eah->hw_dst, '\0', ETH_ALEN); + else + memcpy(eah->hw_dst, sha, ETH_ALEN); + + eah->pa_dst_zero = 0; + eah->pa_dst_net = them->s_net; + eah->pa_dst_node = them->s_node; + + /* Send it */ + aarp_dl->request(aarp_dl, skb, sha); +} + +/* + * Send probe frames. Called from aarp_probe_network and + * aarp_proxy_probe_network. + */ + +static void aarp_send_probe(struct net_device *dev, struct atalk_addr *us) +{ + struct elapaarp *eah; + int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length; + struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); + static unsigned char aarp_eth_multicast[ETH_ALEN] = + { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; + + if (!skb) + return; + + /* Set up the buffer */ + skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length); + skb_reset_network_header(skb); + skb_reset_transport_header(skb); + skb_put(skb, sizeof(*eah)); + skb->protocol = htons(ETH_P_ATALK); + skb->dev = dev; + eah = aarp_hdr(skb); + + /* Set up the ARP */ + eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); + eah->pa_type = htons(ETH_P_ATALK); + eah->hw_len = ETH_ALEN; + eah->pa_len = AARP_PA_ALEN; + eah->function = htons(AARP_PROBE); + + memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN); + + eah->pa_src_zero = 0; + eah->pa_src_net = us->s_net; + eah->pa_src_node = us->s_node; + + memset(eah->hw_dst, '\0', ETH_ALEN); + + eah->pa_dst_zero = 0; + eah->pa_dst_net = us->s_net; + eah->pa_dst_node = us->s_node; + + /* Send it */ + aarp_dl->request(aarp_dl, skb, aarp_eth_multicast); +} + +/* + * Handle an aarp timer expire + * + * Must run under the aarp_lock. + */ + +static void __aarp_expire_timer(struct aarp_entry **n) +{ + struct aarp_entry *t; + + while (*n) + /* Expired ? */ + if (time_after(jiffies, (*n)->expires_at)) { + t = *n; + *n = (*n)->next; + __aarp_expire(t); + } else + n = &((*n)->next); +} + +/* + * Kick all pending requests 5 times a second. + * + * Must run under the aarp_lock. + */ +static void __aarp_kick(struct aarp_entry **n) +{ + struct aarp_entry *t; + + while (*n) + /* Expired: if this will be the 11th tx, we delete instead. */ + if ((*n)->xmit_count >= sysctl_aarp_retransmit_limit) { + t = *n; + *n = (*n)->next; + __aarp_expire(t); + } else { + __aarp_send_query(*n); + n = &((*n)->next); + } +} + +/* + * A device has gone down. Take all entries referring to the device + * and remove them. + * + * Must run under the aarp_lock. + */ +static void __aarp_expire_device(struct aarp_entry **n, struct net_device *dev) +{ + struct aarp_entry *t; + + while (*n) + if ((*n)->dev == dev) { + t = *n; + *n = (*n)->next; + __aarp_expire(t); + } else + n = &((*n)->next); +} + +/* Handle the timer event */ +static void aarp_expire_timeout(unsigned long unused) +{ + int ct; + + write_lock_bh(&aarp_lock); + + for (ct = 0; ct < AARP_HASH_SIZE; ct++) { + __aarp_expire_timer(&resolved[ct]); + __aarp_kick(&unresolved[ct]); + __aarp_expire_timer(&unresolved[ct]); + __aarp_expire_timer(&proxies[ct]); + } + + write_unlock_bh(&aarp_lock); + mod_timer(&aarp_timer, jiffies + + (unresolved_count ? sysctl_aarp_tick_time : + sysctl_aarp_expiry_time)); +} + +/* Network device notifier chain handler. */ +static int aarp_device_event(struct notifier_block *this, unsigned long event, + void *ptr) +{ + struct net_device *dev = ptr; + int ct; + + if (!net_eq(dev_net(dev), &init_net)) + return NOTIFY_DONE; + + if (event == NETDEV_DOWN) { + write_lock_bh(&aarp_lock); + + for (ct = 0; ct < AARP_HASH_SIZE; ct++) { + __aarp_expire_device(&resolved[ct], dev); + __aarp_expire_device(&unresolved[ct], dev); + __aarp_expire_device(&proxies[ct], dev); + } + + write_unlock_bh(&aarp_lock); + } + return NOTIFY_DONE; +} + +/* Expire all entries in a hash chain */ +static void __aarp_expire_all(struct aarp_entry **n) +{ + struct aarp_entry *t; + + while (*n) { + t = *n; + *n = (*n)->next; + __aarp_expire(t); + } +} + +/* Cleanup all hash chains -- module unloading */ +static void aarp_purge(void) +{ + int ct; + + write_lock_bh(&aarp_lock); + for (ct = 0; ct < AARP_HASH_SIZE; ct++) { + __aarp_expire_all(&resolved[ct]); + __aarp_expire_all(&unresolved[ct]); + __aarp_expire_all(&proxies[ct]); + } + write_unlock_bh(&aarp_lock); +} + +/* + * Create a new aarp entry. This must use GFP_ATOMIC because it + * runs while holding spinlocks. + */ +static struct aarp_entry *aarp_alloc(void) +{ + struct aarp_entry *a = kmalloc(sizeof(*a), GFP_ATOMIC); + + if (a) + skb_queue_head_init(&a->packet_queue); + return a; +} + +/* + * Find an entry. We might return an expired but not yet purged entry. We + * don't care as it will do no harm. + * + * This must run under the aarp_lock. + */ +static struct aarp_entry *__aarp_find_entry(struct aarp_entry *list, + struct net_device *dev, + struct atalk_addr *sat) +{ + while (list) { + if (list->target_addr.s_net == sat->s_net && + list->target_addr.s_node == sat->s_node && + list->dev == dev) + break; + list = list->next; + } + + return list; +} + +/* Called from the DDP code, and thus must be exported. */ +void aarp_proxy_remove(struct net_device *dev, struct atalk_addr *sa) +{ + int hash = sa->s_node % (AARP_HASH_SIZE - 1); + struct aarp_entry *a; + + write_lock_bh(&aarp_lock); + + a = __aarp_find_entry(proxies[hash], dev, sa); + if (a) + a->expires_at = jiffies - 1; + + write_unlock_bh(&aarp_lock); +} + +/* This must run under aarp_lock. */ +static struct atalk_addr *__aarp_proxy_find(struct net_device *dev, + struct atalk_addr *sa) +{ + int hash = sa->s_node % (AARP_HASH_SIZE - 1); + struct aarp_entry *a = __aarp_find_entry(proxies[hash], dev, sa); + + return a ? sa : NULL; +} + +/* + * Probe a Phase 1 device or a device that requires its Net:Node to + * be set via an ioctl. + */ +static void aarp_send_probe_phase1(struct atalk_iface *iface) +{ + struct ifreq atreq; + struct sockaddr_at *sa = (struct sockaddr_at *)&atreq.ifr_addr; + const struct net_device_ops *ops = iface->dev->netdev_ops; + + sa->sat_addr.s_node = iface->address.s_node; + sa->sat_addr.s_net = ntohs(iface->address.s_net); + + /* We pass the Net:Node to the drivers/cards by a Device ioctl. */ + if (!(ops->ndo_do_ioctl(iface->dev, &atreq, SIOCSIFADDR))) { + ops->ndo_do_ioctl(iface->dev, &atreq, SIOCGIFADDR); + if (iface->address.s_net != htons(sa->sat_addr.s_net) || + iface->address.s_node != sa->sat_addr.s_node) + iface->status |= ATIF_PROBE_FAIL; + + iface->address.s_net = htons(sa->sat_addr.s_net); + iface->address.s_node = sa->sat_addr.s_node; + } +} + + +void aarp_probe_network(struct atalk_iface *atif) +{ + if (atif->dev->type == ARPHRD_LOCALTLK || + atif->dev->type == ARPHRD_PPP) + aarp_send_probe_phase1(atif); + else { + unsigned int count; + + for (count = 0; count < AARP_RETRANSMIT_LIMIT; count++) { + aarp_send_probe(atif->dev, &atif->address); + + /* Defer 1/10th */ + msleep(100); + + if (atif->status & ATIF_PROBE_FAIL) + break; + } + } +} + +int aarp_proxy_probe_network(struct atalk_iface *atif, struct atalk_addr *sa) +{ + int hash, retval = -EPROTONOSUPPORT; + struct aarp_entry *entry; + unsigned int count; + + /* + * we don't currently support LocalTalk or PPP for proxy AARP; + * if someone wants to try and add it, have fun + */ + if (atif->dev->type == ARPHRD_LOCALTLK || + atif->dev->type == ARPHRD_PPP) + goto out; + + /* + * create a new AARP entry with the flags set to be published -- + * we need this one to hang around even if it's in use + */ + entry = aarp_alloc(); + retval = -ENOMEM; + if (!entry) + goto out; + + entry->expires_at = -1; + entry->status = ATIF_PROBE; + entry->target_addr.s_node = sa->s_node; + entry->target_addr.s_net = sa->s_net; + entry->dev = atif->dev; + + write_lock_bh(&aarp_lock); + + hash = sa->s_node % (AARP_HASH_SIZE - 1); + entry->next = proxies[hash]; + proxies[hash] = entry; + + for (count = 0; count < AARP_RETRANSMIT_LIMIT; count++) { + aarp_send_probe(atif->dev, sa); + + /* Defer 1/10th */ + write_unlock_bh(&aarp_lock); + msleep(100); + write_lock_bh(&aarp_lock); + + if (entry->status & ATIF_PROBE_FAIL) + break; + } + + if (entry->status & ATIF_PROBE_FAIL) { + entry->expires_at = jiffies - 1; /* free the entry */ + retval = -EADDRINUSE; /* return network full */ + } else { /* clear the probing flag */ + entry->status &= ~ATIF_PROBE; + retval = 1; + } + + write_unlock_bh(&aarp_lock); +out: + return retval; +} + +/* Send a DDP frame */ +int aarp_send_ddp(struct net_device *dev, struct sk_buff *skb, + struct atalk_addr *sa, void *hwaddr) +{ + static char ddp_eth_multicast[ETH_ALEN] = + { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; + int hash; + struct aarp_entry *a; + + skb_reset_network_header(skb); + + /* Check for LocalTalk first */ + if (dev->type == ARPHRD_LOCALTLK) { + struct atalk_addr *at = atalk_find_dev_addr(dev); + struct ddpehdr *ddp = (struct ddpehdr *)skb->data; + int ft = 2; + + /* + * Compressible ? + * + * IFF: src_net == dest_net == device_net + * (zero matches anything) + */ + + if ((!ddp->deh_snet || at->s_net == ddp->deh_snet) && + (!ddp->deh_dnet || at->s_net == ddp->deh_dnet)) { + skb_pull(skb, sizeof(*ddp) - 4); + + /* + * The upper two remaining bytes are the port + * numbers we just happen to need. Now put the + * length in the lower two. + */ + *((__be16 *)skb->data) = htons(skb->len); + ft = 1; + } + /* + * Nice and easy. No AARP type protocols occur here so we can + * just shovel it out with a 3 byte LLAP header + */ + + skb_push(skb, 3); + skb->data[0] = sa->s_node; + skb->data[1] = at->s_node; + skb->data[2] = ft; + skb->dev = dev; + goto sendit; + } + + /* On a PPP link we neither compress nor aarp. */ + if (dev->type == ARPHRD_PPP) { + skb->protocol = htons(ETH_P_PPPTALK); + skb->dev = dev; + goto sendit; + } + + /* Non ELAP we cannot do. */ + if (dev->type != ARPHRD_ETHER) + goto free_it; + + skb->dev = dev; + skb->protocol = htons(ETH_P_ATALK); + hash = sa->s_node % (AARP_HASH_SIZE - 1); + + /* Do we have a resolved entry? */ + if (sa->s_node == ATADDR_BCAST) { + /* Send it */ + ddp_dl->request(ddp_dl, skb, ddp_eth_multicast); + goto sent; + } + + write_lock_bh(&aarp_lock); + a = __aarp_find_entry(resolved[hash], dev, sa); + + if (a) { /* Return 1 and fill in the address */ + a->expires_at = jiffies + (sysctl_aarp_expiry_time * 10); + ddp_dl->request(ddp_dl, skb, a->hwaddr); + write_unlock_bh(&aarp_lock); + goto sent; + } + + /* Do we have an unresolved entry: This is the less common path */ + a = __aarp_find_entry(unresolved[hash], dev, sa); + if (a) { /* Queue onto the unresolved queue */ + skb_queue_tail(&a->packet_queue, skb); + goto out_unlock; + } + + /* Allocate a new entry */ + a = aarp_alloc(); + if (!a) { + /* Whoops slipped... good job it's an unreliable protocol 8) */ + write_unlock_bh(&aarp_lock); + goto free_it; + } + + /* Set up the queue */ + skb_queue_tail(&a->packet_queue, skb); + a->expires_at = jiffies + sysctl_aarp_resolve_time; + a->dev = dev; + a->next = unresolved[hash]; + a->target_addr = *sa; + a->xmit_count = 0; + unresolved[hash] = a; + unresolved_count++; + + /* Send an initial request for the address */ + __aarp_send_query(a); + + /* + * Switch to fast timer if needed (That is if this is the first + * unresolved entry to get added) + */ + + if (unresolved_count == 1) + mod_timer(&aarp_timer, jiffies + sysctl_aarp_tick_time); + + /* Now finally, it is safe to drop the lock. */ +out_unlock: + write_unlock_bh(&aarp_lock); + + /* Tell the ddp layer we have taken over for this frame. */ + goto sent; + +sendit: + if (skb->sk) + skb->priority = skb->sk->sk_priority; + if (dev_queue_xmit(skb)) + goto drop; +sent: + return NET_XMIT_SUCCESS; +free_it: + kfree_skb(skb); +drop: + return NET_XMIT_DROP; +} +EXPORT_SYMBOL(aarp_send_ddp); + +/* + * An entry in the aarp unresolved queue has become resolved. Send + * all the frames queued under it. + * + * Must run under aarp_lock. + */ +static void __aarp_resolved(struct aarp_entry **list, struct aarp_entry *a, + int hash) +{ + struct sk_buff *skb; + + while (*list) + if (*list == a) { + unresolved_count--; + *list = a->next; + + /* Move into the resolved list */ + a->next = resolved[hash]; + resolved[hash] = a; + + /* Kick frames off */ + while ((skb = skb_dequeue(&a->packet_queue)) != NULL) { + a->expires_at = jiffies + + sysctl_aarp_expiry_time * 10; + ddp_dl->request(ddp_dl, skb, a->hwaddr); + } + } else + list = &((*list)->next); +} + +/* + * This is called by the SNAP driver whenever we see an AARP SNAP + * frame. We currently only support Ethernet. + */ +static int aarp_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt, struct net_device *orig_dev) +{ + struct elapaarp *ea = aarp_hdr(skb); + int hash, ret = 0; + __u16 function; + struct aarp_entry *a; + struct atalk_addr sa, *ma, da; + struct atalk_iface *ifa; + + if (!net_eq(dev_net(dev), &init_net)) + goto out0; + + /* We only do Ethernet SNAP AARP. */ + if (dev->type != ARPHRD_ETHER) + goto out0; + + /* Frame size ok? */ + if (!skb_pull(skb, sizeof(*ea))) + goto out0; + + function = ntohs(ea->function); + + /* Sanity check fields. */ + if (function < AARP_REQUEST || function > AARP_PROBE || + ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN || + ea->pa_src_zero || ea->pa_dst_zero) + goto out0; + + /* Looks good. */ + hash = ea->pa_src_node % (AARP_HASH_SIZE - 1); + + /* Build an address. */ + sa.s_node = ea->pa_src_node; + sa.s_net = ea->pa_src_net; + + /* Process the packet. Check for replies of me. */ + ifa = atalk_find_dev(dev); + if (!ifa) + goto out1; + + if (ifa->status & ATIF_PROBE && + ifa->address.s_node == ea->pa_dst_node && + ifa->address.s_net == ea->pa_dst_net) { + ifa->status |= ATIF_PROBE_FAIL; /* Fail the probe (in use) */ + goto out1; + } + + /* Check for replies of proxy AARP entries */ + da.s_node = ea->pa_dst_node; + da.s_net = ea->pa_dst_net; + + write_lock_bh(&aarp_lock); + a = __aarp_find_entry(proxies[hash], dev, &da); + + if (a && a->status & ATIF_PROBE) { + a->status |= ATIF_PROBE_FAIL; + /* + * we do not respond to probe or request packets for + * this address while we are probing this address + */ + goto unlock; + } + + switch (function) { + case AARP_REPLY: + if (!unresolved_count) /* Speed up */ + break; + + /* Find the entry. */ + a = __aarp_find_entry(unresolved[hash], dev, &sa); + if (!a || dev != a->dev) + break; + + /* We can fill one in - this is good. */ + memcpy(a->hwaddr, ea->hw_src, ETH_ALEN); + __aarp_resolved(&unresolved[hash], a, hash); + if (!unresolved_count) + mod_timer(&aarp_timer, + jiffies + sysctl_aarp_expiry_time); + break; + + case AARP_REQUEST: + case AARP_PROBE: + + /* + * If it is my address set ma to my address and reply. + * We can treat probe and request the same. Probe + * simply means we shouldn't cache the querying host, + * as in a probe they are proposing an address not + * using one. + * + * Support for proxy-AARP added. We check if the + * address is one of our proxies before we toss the + * packet out. + */ + + sa.s_node = ea->pa_dst_node; + sa.s_net = ea->pa_dst_net; + + /* See if we have a matching proxy. */ + ma = __aarp_proxy_find(dev, &sa); + if (!ma) + ma = &ifa->address; + else { /* We need to make a copy of the entry. */ + da.s_node = sa.s_node; + da.s_net = sa.s_net; + ma = &da; + } + + if (function == AARP_PROBE) { + /* + * A probe implies someone trying to get an + * address. So as a precaution flush any + * entries we have for this address. + */ + a = __aarp_find_entry(resolved[sa.s_node % + (AARP_HASH_SIZE - 1)], + skb->dev, &sa); + + /* + * Make it expire next tick - that avoids us + * getting into a probe/flush/learn/probe/ + * flush/learn cycle during probing of a slow + * to respond host addr. + */ + if (a) { + a->expires_at = jiffies - 1; + mod_timer(&aarp_timer, jiffies + + sysctl_aarp_tick_time); + } + } + + if (sa.s_node != ma->s_node) + break; + + if (sa.s_net && ma->s_net && sa.s_net != ma->s_net) + break; + + sa.s_node = ea->pa_src_node; + sa.s_net = ea->pa_src_net; + + /* aarp_my_address has found the address to use for us. + */ + aarp_send_reply(dev, ma, &sa, ea->hw_src); + break; + } + +unlock: + write_unlock_bh(&aarp_lock); +out1: + ret = 1; +out0: + kfree_skb(skb); + return ret; +} + +static struct notifier_block aarp_notifier = { + .notifier_call = aarp_device_event, +}; + +static unsigned char aarp_snap_id[] = { 0x00, 0x00, 0x00, 0x80, 0xF3 }; + +void __init aarp_proto_init(void) +{ + aarp_dl = register_snap_client(aarp_snap_id, aarp_rcv); + if (!aarp_dl) + printk(KERN_CRIT "Unable to register AARP with SNAP.\n"); + setup_timer(&aarp_timer, aarp_expire_timeout, 0); + aarp_timer.expires = jiffies + sysctl_aarp_expiry_time; + add_timer(&aarp_timer); + register_netdevice_notifier(&aarp_notifier); +} + +/* Remove the AARP entries associated with a device. */ +void aarp_device_down(struct net_device *dev) +{ + int ct; + + write_lock_bh(&aarp_lock); + + for (ct = 0; ct < AARP_HASH_SIZE; ct++) { + __aarp_expire_device(&resolved[ct], dev); + __aarp_expire_device(&unresolved[ct], dev); + __aarp_expire_device(&proxies[ct], dev); + } + + write_unlock_bh(&aarp_lock); +} + +#ifdef CONFIG_PROC_FS +struct aarp_iter_state { + int bucket; + struct aarp_entry **table; +}; + +/* + * Get the aarp entry that is in the chain described + * by the iterator. + * If pos is set then skip till that index. + * pos = 1 is the first entry + */ +static struct aarp_entry *iter_next(struct aarp_iter_state *iter, loff_t *pos) +{ + int ct = iter->bucket; + struct aarp_entry **table = iter->table; + loff_t off = 0; + struct aarp_entry *entry; + + rescan: + while(ct < AARP_HASH_SIZE) { + for (entry = table[ct]; entry; entry = entry->next) { + if (!pos || ++off == *pos) { + iter->table = table; + iter->bucket = ct; + return entry; + } + } + ++ct; + } + + if (table == resolved) { + ct = 0; + table = unresolved; + goto rescan; + } + if (table == unresolved) { + ct = 0; + table = proxies; + goto rescan; + } + return NULL; +} + +static void *aarp_seq_start(struct seq_file *seq, loff_t *pos) + __acquires(aarp_lock) +{ + struct aarp_iter_state *iter = seq->private; + + read_lock_bh(&aarp_lock); + iter->table = resolved; + iter->bucket = 0; + + return *pos ? iter_next(iter, pos) : SEQ_START_TOKEN; +} + +static void *aarp_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct aarp_entry *entry = v; + struct aarp_iter_state *iter = seq->private; + + ++*pos; + + /* first line after header */ + if (v == SEQ_START_TOKEN) + entry = iter_next(iter, NULL); + + /* next entry in current bucket */ + else if (entry->next) + entry = entry->next; + + /* next bucket or table */ + else { + ++iter->bucket; + entry = iter_next(iter, NULL); + } + return entry; +} + +static void aarp_seq_stop(struct seq_file *seq, void *v) + __releases(aarp_lock) +{ + read_unlock_bh(&aarp_lock); +} + +static const char *dt2str(unsigned long ticks) +{ + static char buf[32]; + + sprintf(buf, "%ld.%02ld", ticks / HZ, ((ticks % HZ) * 100 ) / HZ); + + return buf; +} + +static int aarp_seq_show(struct seq_file *seq, void *v) +{ + struct aarp_iter_state *iter = seq->private; + struct aarp_entry *entry = v; + unsigned long now = jiffies; + + if (v == SEQ_START_TOKEN) + seq_puts(seq, + "Address Interface Hardware Address" + " Expires LastSend Retry Status\n"); + else { + seq_printf(seq, "%04X:%02X %-12s", + ntohs(entry->target_addr.s_net), + (unsigned int) entry->target_addr.s_node, + entry->dev ? entry->dev->name : "????"); + seq_printf(seq, "%pM", entry->hwaddr); + seq_printf(seq, " %8s", + dt2str((long)entry->expires_at - (long)now)); + if (iter->table == unresolved) + seq_printf(seq, " %8s %6hu", + dt2str(now - entry->last_sent), + entry->xmit_count); + else + seq_puts(seq, " "); + seq_printf(seq, " %s\n", + (iter->table == resolved) ? "resolved" + : (iter->table == unresolved) ? "unresolved" + : (iter->table == proxies) ? "proxies" + : "unknown"); + } + return 0; +} + +static const struct seq_operations aarp_seq_ops = { + .start = aarp_seq_start, + .next = aarp_seq_next, + .stop = aarp_seq_stop, + .show = aarp_seq_show, +}; + +static int aarp_seq_open(struct inode *inode, struct file *file) +{ + return seq_open_private(file, &aarp_seq_ops, + sizeof(struct aarp_iter_state)); +} + +const struct file_operations atalk_seq_arp_fops = { + .owner = THIS_MODULE, + .open = aarp_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_private, +}; +#endif + +/* General module cleanup. Called from cleanup_module() in ddp.c. */ +void aarp_cleanup_module(void) +{ + del_timer_sync(&aarp_timer); + unregister_netdevice_notifier(&aarp_notifier); + unregister_snap_client(aarp_dl); + aarp_purge(); +} diff --git a/drivers/staging/appletalk/atalk.h b/drivers/staging/appletalk/atalk.h new file mode 100644 index 000000000000..d34c187432ed --- /dev/null +++ b/drivers/staging/appletalk/atalk.h @@ -0,0 +1,208 @@ +#ifndef __LINUX_ATALK_H__ +#define __LINUX_ATALK_H__ + +#include +#include + +/* + * AppleTalk networking structures + * + * The following are directly referenced from the University Of Michigan + * netatalk for compatibility reasons. + */ +#define ATPORT_FIRST 1 +#define ATPORT_RESERVED 128 +#define ATPORT_LAST 254 /* 254 is only legal on localtalk */ +#define ATADDR_ANYNET (__u16)0 +#define ATADDR_ANYNODE (__u8)0 +#define ATADDR_ANYPORT (__u8)0 +#define ATADDR_BCAST (__u8)255 +#define DDP_MAXSZ 587 +#define DDP_MAXHOPS 15 /* 4 bits of hop counter */ + +#define SIOCATALKDIFADDR (SIOCPROTOPRIVATE + 0) + +struct atalk_addr { + __be16 s_net; + __u8 s_node; +}; + +struct sockaddr_at { + sa_family_t sat_family; + __u8 sat_port; + struct atalk_addr sat_addr; + char sat_zero[8]; +}; + +struct atalk_netrange { + __u8 nr_phase; + __be16 nr_firstnet; + __be16 nr_lastnet; +}; + +#ifdef __KERNEL__ + +#include + +struct atalk_route { + struct net_device *dev; + struct atalk_addr target; + struct atalk_addr gateway; + int flags; + struct atalk_route *next; +}; + +/** + * struct atalk_iface - AppleTalk Interface + * @dev - Network device associated with this interface + * @address - Our address + * @status - What are we doing? + * @nets - Associated direct netrange + * @next - next element in the list of interfaces + */ +struct atalk_iface { + struct net_device *dev; + struct atalk_addr address; + int status; +#define ATIF_PROBE 1 /* Probing for an address */ +#define ATIF_PROBE_FAIL 2 /* Probe collided */ + struct atalk_netrange nets; + struct atalk_iface *next; +}; + +struct atalk_sock { + /* struct sock has to be the first member of atalk_sock */ + struct sock sk; + __be16 dest_net; + __be16 src_net; + unsigned char dest_node; + unsigned char src_node; + unsigned char dest_port; + unsigned char src_port; +}; + +static inline struct atalk_sock *at_sk(struct sock *sk) +{ + return (struct atalk_sock *)sk; +} + +struct ddpehdr { + __be16 deh_len_hops; /* lower 10 bits are length, next 4 - hops */ + __be16 deh_sum; + __be16 deh_dnet; + __be16 deh_snet; + __u8 deh_dnode; + __u8 deh_snode; + __u8 deh_dport; + __u8 deh_sport; + /* And netatalk apps expect to stick the type in themselves */ +}; + +static __inline__ struct ddpehdr *ddp_hdr(struct sk_buff *skb) +{ + return (struct ddpehdr *)skb_transport_header(skb); +} + +/* AppleTalk AARP headers */ +struct elapaarp { + __be16 hw_type; +#define AARP_HW_TYPE_ETHERNET 1 +#define AARP_HW_TYPE_TOKENRING 2 + __be16 pa_type; + __u8 hw_len; + __u8 pa_len; +#define AARP_PA_ALEN 4 + __be16 function; +#define AARP_REQUEST 1 +#define AARP_REPLY 2 +#define AARP_PROBE 3 + __u8 hw_src[ETH_ALEN]; + __u8 pa_src_zero; + __be16 pa_src_net; + __u8 pa_src_node; + __u8 hw_dst[ETH_ALEN]; + __u8 pa_dst_zero; + __be16 pa_dst_net; + __u8 pa_dst_node; +} __attribute__ ((packed)); + +static __inline__ struct elapaarp *aarp_hdr(struct sk_buff *skb) +{ + return (struct elapaarp *)skb_transport_header(skb); +} + +/* Not specified - how long till we drop a resolved entry */ +#define AARP_EXPIRY_TIME (5 * 60 * HZ) +/* Size of hash table */ +#define AARP_HASH_SIZE 16 +/* Fast retransmission timer when resolving */ +#define AARP_TICK_TIME (HZ / 5) +/* Send 10 requests then give up (2 seconds) */ +#define AARP_RETRANSMIT_LIMIT 10 +/* + * Some value bigger than total retransmit time + a bit for last reply to + * appear and to stop continual requests + */ +#define AARP_RESOLVE_TIME (10 * HZ) + +extern struct datalink_proto *ddp_dl, *aarp_dl; +extern void aarp_proto_init(void); + +/* Inter module exports */ + +/* Give a device find its atif control structure */ +static inline struct atalk_iface *atalk_find_dev(struct net_device *dev) +{ + return dev->atalk_ptr; +} + +extern struct atalk_addr *atalk_find_dev_addr(struct net_device *dev); +extern struct net_device *atrtr_get_dev(struct atalk_addr *sa); +extern int aarp_send_ddp(struct net_device *dev, + struct sk_buff *skb, + struct atalk_addr *sa, void *hwaddr); +extern void aarp_device_down(struct net_device *dev); +extern void aarp_probe_network(struct atalk_iface *atif); +extern int aarp_proxy_probe_network(struct atalk_iface *atif, + struct atalk_addr *sa); +extern void aarp_proxy_remove(struct net_device *dev, + struct atalk_addr *sa); + +extern void aarp_cleanup_module(void); + +extern struct hlist_head atalk_sockets; +extern rwlock_t atalk_sockets_lock; + +extern struct atalk_route *atalk_routes; +extern rwlock_t atalk_routes_lock; + +extern struct atalk_iface *atalk_interfaces; +extern rwlock_t atalk_interfaces_lock; + +extern struct atalk_route atrtr_default; + +extern const struct file_operations atalk_seq_arp_fops; + +extern int sysctl_aarp_expiry_time; +extern int sysctl_aarp_tick_time; +extern int sysctl_aarp_retransmit_limit; +extern int sysctl_aarp_resolve_time; + +#ifdef CONFIG_SYSCTL +extern void atalk_register_sysctl(void); +extern void atalk_unregister_sysctl(void); +#else +#define atalk_register_sysctl() do { } while(0) +#define atalk_unregister_sysctl() do { } while(0) +#endif + +#ifdef CONFIG_PROC_FS +extern int atalk_proc_init(void); +extern void atalk_proc_exit(void); +#else +#define atalk_proc_init() ({ 0; }) +#define atalk_proc_exit() do { } while(0) +#endif /* CONFIG_PROC_FS */ + +#endif /* __KERNEL__ */ +#endif /* __LINUX_ATALK_H__ */ diff --git a/drivers/staging/appletalk/atalk_proc.c b/drivers/staging/appletalk/atalk_proc.c new file mode 100644 index 000000000000..d012ba2e67d1 --- /dev/null +++ b/drivers/staging/appletalk/atalk_proc.c @@ -0,0 +1,301 @@ +/* + * atalk_proc.c - proc support for Appletalk + * + * Copyright(c) Arnaldo Carvalho de Melo + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, version 2. + */ + +#include +#include +#include +#include +#include +#include "atalk.h" + + +static __inline__ struct atalk_iface *atalk_get_interface_idx(loff_t pos) +{ + struct atalk_iface *i; + + for (i = atalk_interfaces; pos && i; i = i->next) + --pos; + + return i; +} + +static void *atalk_seq_interface_start(struct seq_file *seq, loff_t *pos) + __acquires(atalk_interfaces_lock) +{ + loff_t l = *pos; + + read_lock_bh(&atalk_interfaces_lock); + return l ? atalk_get_interface_idx(--l) : SEQ_START_TOKEN; +} + +static void *atalk_seq_interface_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct atalk_iface *i; + + ++*pos; + if (v == SEQ_START_TOKEN) { + i = NULL; + if (atalk_interfaces) + i = atalk_interfaces; + goto out; + } + i = v; + i = i->next; +out: + return i; +} + +static void atalk_seq_interface_stop(struct seq_file *seq, void *v) + __releases(atalk_interfaces_lock) +{ + read_unlock_bh(&atalk_interfaces_lock); +} + +static int atalk_seq_interface_show(struct seq_file *seq, void *v) +{ + struct atalk_iface *iface; + + if (v == SEQ_START_TOKEN) { + seq_puts(seq, "Interface Address Networks " + "Status\n"); + goto out; + } + + iface = v; + seq_printf(seq, "%-16s %04X:%02X %04X-%04X %d\n", + iface->dev->name, ntohs(iface->address.s_net), + iface->address.s_node, ntohs(iface->nets.nr_firstnet), + ntohs(iface->nets.nr_lastnet), iface->status); +out: + return 0; +} + +static __inline__ struct atalk_route *atalk_get_route_idx(loff_t pos) +{ + struct atalk_route *r; + + for (r = atalk_routes; pos && r; r = r->next) + --pos; + + return r; +} + +static void *atalk_seq_route_start(struct seq_file *seq, loff_t *pos) + __acquires(atalk_routes_lock) +{ + loff_t l = *pos; + + read_lock_bh(&atalk_routes_lock); + return l ? atalk_get_route_idx(--l) : SEQ_START_TOKEN; +} + +static void *atalk_seq_route_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct atalk_route *r; + + ++*pos; + if (v == SEQ_START_TOKEN) { + r = NULL; + if (atalk_routes) + r = atalk_routes; + goto out; + } + r = v; + r = r->next; +out: + return r; +} + +static void atalk_seq_route_stop(struct seq_file *seq, void *v) + __releases(atalk_routes_lock) +{ + read_unlock_bh(&atalk_routes_lock); +} + +static int atalk_seq_route_show(struct seq_file *seq, void *v) +{ + struct atalk_route *rt; + + if (v == SEQ_START_TOKEN) { + seq_puts(seq, "Target Router Flags Dev\n"); + goto out; + } + + if (atrtr_default.dev) { + rt = &atrtr_default; + seq_printf(seq, "Default %04X:%02X %-4d %s\n", + ntohs(rt->gateway.s_net), rt->gateway.s_node, + rt->flags, rt->dev->name); + } + + rt = v; + seq_printf(seq, "%04X:%02X %04X:%02X %-4d %s\n", + ntohs(rt->target.s_net), rt->target.s_node, + ntohs(rt->gateway.s_net), rt->gateway.s_node, + rt->flags, rt->dev->name); +out: + return 0; +} + +static void *atalk_seq_socket_start(struct seq_file *seq, loff_t *pos) + __acquires(atalk_sockets_lock) +{ + read_lock_bh(&atalk_sockets_lock); + return seq_hlist_start_head(&atalk_sockets, *pos); +} + +static void *atalk_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos) +{ + return seq_hlist_next(v, &atalk_sockets, pos); +} + +static void atalk_seq_socket_stop(struct seq_file *seq, void *v) + __releases(atalk_sockets_lock) +{ + read_unlock_bh(&atalk_sockets_lock); +} + +static int atalk_seq_socket_show(struct seq_file *seq, void *v) +{ + struct sock *s; + struct atalk_sock *at; + + if (v == SEQ_START_TOKEN) { + seq_printf(seq, "Type Local_addr Remote_addr Tx_queue " + "Rx_queue St UID\n"); + goto out; + } + + s = sk_entry(v); + at = at_sk(s); + + seq_printf(seq, "%02X %04X:%02X:%02X %04X:%02X:%02X %08X:%08X " + "%02X %d\n", + s->sk_type, ntohs(at->src_net), at->src_node, at->src_port, + ntohs(at->dest_net), at->dest_node, at->dest_port, + sk_wmem_alloc_get(s), + sk_rmem_alloc_get(s), + s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); +out: + return 0; +} + +static const struct seq_operations atalk_seq_interface_ops = { + .start = atalk_seq_interface_start, + .next = atalk_seq_interface_next, + .stop = atalk_seq_interface_stop, + .show = atalk_seq_interface_show, +}; + +static const struct seq_operations atalk_seq_route_ops = { + .start = atalk_seq_route_start, + .next = atalk_seq_route_next, + .stop = atalk_seq_route_stop, + .show = atalk_seq_route_show, +}; + +static const struct seq_operations atalk_seq_socket_ops = { + .start = atalk_seq_socket_start, + .next = atalk_seq_socket_next, + .stop = atalk_seq_socket_stop, + .show = atalk_seq_socket_show, +}; + +static int atalk_seq_interface_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &atalk_seq_interface_ops); +} + +static int atalk_seq_route_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &atalk_seq_route_ops); +} + +static int atalk_seq_socket_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &atalk_seq_socket_ops); +} + +static const struct file_operations atalk_seq_interface_fops = { + .owner = THIS_MODULE, + .open = atalk_seq_interface_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static const struct file_operations atalk_seq_route_fops = { + .owner = THIS_MODULE, + .open = atalk_seq_route_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static const struct file_operations atalk_seq_socket_fops = { + .owner = THIS_MODULE, + .open = atalk_seq_socket_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static struct proc_dir_entry *atalk_proc_dir; + +int __init atalk_proc_init(void) +{ + struct proc_dir_entry *p; + int rc = -ENOMEM; + + atalk_proc_dir = proc_mkdir("atalk", init_net.proc_net); + if (!atalk_proc_dir) + goto out; + + p = proc_create("interface", S_IRUGO, atalk_proc_dir, + &atalk_seq_interface_fops); + if (!p) + goto out_interface; + + p = proc_create("route", S_IRUGO, atalk_proc_dir, + &atalk_seq_route_fops); + if (!p) + goto out_route; + + p = proc_create("socket", S_IRUGO, atalk_proc_dir, + &atalk_seq_socket_fops); + if (!p) + goto out_socket; + + p = proc_create("arp", S_IRUGO, atalk_proc_dir, &atalk_seq_arp_fops); + if (!p) + goto out_arp; + + rc = 0; +out: + return rc; +out_arp: + remove_proc_entry("socket", atalk_proc_dir); +out_socket: + remove_proc_entry("route", atalk_proc_dir); +out_route: + remove_proc_entry("interface", atalk_proc_dir); +out_interface: + remove_proc_entry("atalk", init_net.proc_net); + goto out; +} + +void __exit atalk_proc_exit(void) +{ + remove_proc_entry("interface", atalk_proc_dir); + remove_proc_entry("route", atalk_proc_dir); + remove_proc_entry("socket", atalk_proc_dir); + remove_proc_entry("arp", atalk_proc_dir); + remove_proc_entry("atalk", init_net.proc_net); +} diff --git a/drivers/staging/appletalk/cops.c b/drivers/staging/appletalk/cops.c new file mode 100644 index 000000000000..661d42eff7d8 --- /dev/null +++ b/drivers/staging/appletalk/cops.c @@ -0,0 +1,1013 @@ +/* cops.c: LocalTalk driver for Linux. + * + * Authors: + * - Jay Schulist + * + * With more than a little help from; + * - Alan Cox + * + * Derived from: + * - skeleton.c: A network driver outline for linux. + * Written 1993-94 by Donald Becker. + * - ltpc.c: A driver for the LocalTalk PC card. + * Written by Bradford W. Johnson. + * + * Copyright 1993 United States Government as represented by the + * Director, National Security Agency. + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * Changes: + * 19970608 Alan Cox Allowed dual card type support + * Can set board type in insmod + * Hooks for cops_setup routine + * (not yet implemented). + * 19971101 Jay Schulist Fixes for multiple lt* devices. + * 19980607 Steven Hirsch Fixed the badly broken support + * for Tangent type cards. Only + * tested on Daystar LT200. Some + * cleanup of formatting and program + * logic. Added emacs 'local-vars' + * setup for Jay's brace style. + * 20000211 Alan Cox Cleaned up for softnet + */ + +static const char *version = +"cops.c:v0.04 6/7/98 Jay Schulist \n"; +/* + * Sources: + * COPS Localtalk SDK. This provides almost all of the information + * needed. + */ + +/* + * insmod/modprobe configurable stuff. + * - IO Port, choose one your card supports or 0 if you dare. + * - IRQ, also choose one your card supports or nothing and let + * the driver figure it out. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* For udelay() */ +#include +#include +#include + +#include +#include +#include + +#include "atalk.h" +#include "cops.h" /* Our Stuff */ +#include "cops_ltdrv.h" /* Firmware code for Tangent type cards. */ +#include "cops_ffdrv.h" /* Firmware code for Dayna type cards. */ + +/* + * The name of the card. Is used for messages and in the requests for + * io regions, irqs and dma channels + */ + +static const char *cardname = "cops"; + +#ifdef CONFIG_COPS_DAYNA +static int board_type = DAYNA; /* Module exported */ +#else +static int board_type = TANGENT; +#endif + +static int io = 0x240; /* Default IO for Dayna */ +static int irq = 5; /* Default IRQ */ + +/* + * COPS Autoprobe information. + * Right now if port address is right but IRQ is not 5 this will + * return a 5 no matter what since we will still get a status response. + * Need one more additional check to narrow down after we have gotten + * the ioaddr. But since only other possible IRQs is 3 and 4 so no real + * hurry on this. I *STRONGLY* recommend using IRQ 5 for your card with + * this driver. + * + * This driver has 2 modes and they are: Dayna mode and Tangent mode. + * Each mode corresponds with the type of card. It has been found + * that there are 2 main types of cards and all other cards are + * the same and just have different names or only have minor differences + * such as more IO ports. As this driver is tested it will + * become more clear on exactly what cards are supported. The driver + * defaults to using Dayna mode. To change the drivers mode, simply + * select Dayna or Tangent mode when configuring the kernel. + * + * This driver should support: + * TANGENT driver mode: + * Tangent ATB-II, Novell NL-1000, Daystar Digital LT-200, + * COPS LT-1 + * DAYNA driver mode: + * Dayna DL2000/DaynaTalk PC (Half Length), COPS LT-95, + * Farallon PhoneNET PC III, Farallon PhoneNET PC II + * Other cards possibly supported mode unknown though: + * Dayna DL2000 (Full length), COPS LT/M (Micro-Channel) + * + * Cards NOT supported by this driver but supported by the ltpc.c + * driver written by Bradford W. Johnson + * Farallon PhoneNET PC + * Original Apple LocalTalk PC card + * + * N.B. + * + * The Daystar Digital LT200 boards do not support interrupt-driven + * IO. You must specify 'irq=0xff' as a module parameter to invoke + * polled mode. I also believe that the port probing logic is quite + * dangerous at best and certainly hopeless for a polled card. Best to + * specify both. - Steve H. + * + */ + +/* + * Zero terminated list of IO ports to probe. + */ + +static unsigned int ports[] = { + 0x240, 0x340, 0x200, 0x210, 0x220, 0x230, 0x260, + 0x2A0, 0x300, 0x310, 0x320, 0x330, 0x350, 0x360, + 0 +}; + +/* + * Zero terminated list of IRQ ports to probe. + */ + +static int cops_irqlist[] = { + 5, 4, 3, 0 +}; + +static struct timer_list cops_timer; + +/* use 0 for production, 1 for verification, 2 for debug, 3 for verbose debug */ +#ifndef COPS_DEBUG +#define COPS_DEBUG 1 +#endif +static unsigned int cops_debug = COPS_DEBUG; + +/* The number of low I/O ports used by the card. */ +#define COPS_IO_EXTENT 8 + +/* Information that needs to be kept for each board. */ + +struct cops_local +{ + int board; /* Holds what board type is. */ + int nodeid; /* Set to 1 once have nodeid. */ + unsigned char node_acquire; /* Node ID when acquired. */ + struct atalk_addr node_addr; /* Full node address */ + spinlock_t lock; /* RX/TX lock */ +}; + +/* Index to functions, as function prototypes. */ +static int cops_probe1 (struct net_device *dev, int ioaddr); +static int cops_irq (int ioaddr, int board); + +static int cops_open (struct net_device *dev); +static int cops_jumpstart (struct net_device *dev); +static void cops_reset (struct net_device *dev, int sleep); +static void cops_load (struct net_device *dev); +static int cops_nodeid (struct net_device *dev, int nodeid); + +static irqreturn_t cops_interrupt (int irq, void *dev_id); +static void cops_poll (unsigned long ltdev); +static void cops_timeout(struct net_device *dev); +static void cops_rx (struct net_device *dev); +static netdev_tx_t cops_send_packet (struct sk_buff *skb, + struct net_device *dev); +static void set_multicast_list (struct net_device *dev); +static int cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); +static int cops_close (struct net_device *dev); + +static void cleanup_card(struct net_device *dev) +{ + if (dev->irq) + free_irq(dev->irq, dev); + release_region(dev->base_addr, COPS_IO_EXTENT); +} + +/* + * Check for a network adaptor of this type, and return '0' iff one exists. + * If dev->base_addr == 0, probe all likely locations. + * If dev->base_addr in [1..0x1ff], always return failure. + * otherwise go with what we pass in. + */ +struct net_device * __init cops_probe(int unit) +{ + struct net_device *dev; + unsigned *port; + int base_addr; + int err = 0; + + dev = alloc_ltalkdev(sizeof(struct cops_local)); + if (!dev) + return ERR_PTR(-ENOMEM); + + if (unit >= 0) { + sprintf(dev->name, "lt%d", unit); + netdev_boot_setup_check(dev); + irq = dev->irq; + base_addr = dev->base_addr; + } else { + base_addr = dev->base_addr = io; + } + + if (base_addr > 0x1ff) { /* Check a single specified location. */ + err = cops_probe1(dev, base_addr); + } else if (base_addr != 0) { /* Don't probe at all. */ + err = -ENXIO; + } else { + /* FIXME Does this really work for cards which generate irq? + * It's definitely N.G. for polled Tangent. sh + * Dayna cards don't autoprobe well at all, but if your card is + * at IRQ 5 & IO 0x240 we find it every time. ;) JS + */ + for (port = ports; *port && cops_probe1(dev, *port) < 0; port++) + ; + if (!*port) + err = -ENODEV; + } + if (err) + goto out; + err = register_netdev(dev); + if (err) + goto out1; + return dev; +out1: + cleanup_card(dev); +out: + free_netdev(dev); + return ERR_PTR(err); +} + +static const struct net_device_ops cops_netdev_ops = { + .ndo_open = cops_open, + .ndo_stop = cops_close, + .ndo_start_xmit = cops_send_packet, + .ndo_tx_timeout = cops_timeout, + .ndo_do_ioctl = cops_ioctl, + .ndo_set_multicast_list = set_multicast_list, +}; + +/* + * This is the real probe routine. Linux has a history of friendly device + * probes on the ISA bus. A good device probes avoids doing writes, and + * verifies that the correct device exists and functions. + */ +static int __init cops_probe1(struct net_device *dev, int ioaddr) +{ + struct cops_local *lp; + static unsigned version_printed; + int board = board_type; + int retval; + + if(cops_debug && version_printed++ == 0) + printk("%s", version); + + /* Grab the region so no one else tries to probe our ioports. */ + if (!request_region(ioaddr, COPS_IO_EXTENT, dev->name)) + return -EBUSY; + + /* + * Since this board has jumpered interrupts, allocate the interrupt + * vector now. There is no point in waiting since no other device + * can use the interrupt, and this marks the irq as busy. Jumpered + * interrupts are typically not reported by the boards, and we must + * used AutoIRQ to find them. + */ + dev->irq = irq; + switch (dev->irq) + { + case 0: + /* COPS AutoIRQ routine */ + dev->irq = cops_irq(ioaddr, board); + if (dev->irq) + break; + /* No IRQ found on this port, fallthrough */ + case 1: + retval = -EINVAL; + goto err_out; + + /* Fixup for users that don't know that IRQ 2 is really + * IRQ 9, or don't know which one to set. + */ + case 2: + dev->irq = 9; + break; + + /* Polled operation requested. Although irq of zero passed as + * a parameter tells the init routines to probe, we'll + * overload it to denote polled operation at runtime. + */ + case 0xff: + dev->irq = 0; + break; + + default: + break; + } + + /* Reserve any actual interrupt. */ + if (dev->irq) { + retval = request_irq(dev->irq, cops_interrupt, 0, dev->name, dev); + if (retval) + goto err_out; + } + + dev->base_addr = ioaddr; + + lp = netdev_priv(dev); + spin_lock_init(&lp->lock); + + /* Copy local board variable to lp struct. */ + lp->board = board; + + dev->netdev_ops = &cops_netdev_ops; + dev->watchdog_timeo = HZ * 2; + + + /* Tell the user where the card is and what mode we're in. */ + if(board==DAYNA) + printk("%s: %s at %#3x, using IRQ %d, in Dayna mode.\n", + dev->name, cardname, ioaddr, dev->irq); + if(board==TANGENT) { + if(dev->irq) + printk("%s: %s at %#3x, IRQ %d, in Tangent mode\n", + dev->name, cardname, ioaddr, dev->irq); + else + printk("%s: %s at %#3x, using polled IO, in Tangent mode.\n", + dev->name, cardname, ioaddr); + + } + return 0; + +err_out: + release_region(ioaddr, COPS_IO_EXTENT); + return retval; +} + +static int __init cops_irq (int ioaddr, int board) +{ /* + * This does not use the IRQ to determine where the IRQ is. We just + * assume that when we get a correct status response that it's the IRQ. + * This really just verifies the IO port but since we only have access + * to such a small number of IRQs (5, 4, 3) this is not bad. + * This will probably not work for more than one card. + */ + int irqaddr=0; + int i, x, status; + + if(board==DAYNA) + { + outb(0, ioaddr+DAYNA_RESET); + inb(ioaddr+DAYNA_RESET); + mdelay(333); + } + if(board==TANGENT) + { + inb(ioaddr); + outb(0, ioaddr); + outb(0, ioaddr+TANG_RESET); + } + + for(i=0; cops_irqlist[i] !=0; i++) + { + irqaddr = cops_irqlist[i]; + for(x = 0xFFFF; x>0; x --) /* wait for response */ + { + if(board==DAYNA) + { + status = (inb(ioaddr+DAYNA_CARD_STATUS)&3); + if(status == 1) + return irqaddr; + } + if(board==TANGENT) + { + if((inb(ioaddr+TANG_CARD_STATUS)& TANG_TX_READY) !=0) + return irqaddr; + } + } + } + return 0; /* no IRQ found */ +} + +/* + * Open/initialize the board. This is called (in the current kernel) + * sometime after booting when the 'ifconfig' program is run. + */ +static int cops_open(struct net_device *dev) +{ + struct cops_local *lp = netdev_priv(dev); + + if(dev->irq==0) + { + /* + * I don't know if the Dayna-style boards support polled + * operation. For now, only allow it for Tangent. + */ + if(lp->board==TANGENT) /* Poll 20 times per second */ + { + init_timer(&cops_timer); + cops_timer.function = cops_poll; + cops_timer.data = (unsigned long)dev; + cops_timer.expires = jiffies + HZ/20; + add_timer(&cops_timer); + } + else + { + printk(KERN_WARNING "%s: No irq line set\n", dev->name); + return -EAGAIN; + } + } + + cops_jumpstart(dev); /* Start the card up. */ + + netif_start_queue(dev); + return 0; +} + +/* + * This allows for a dynamic start/restart of the entire card. + */ +static int cops_jumpstart(struct net_device *dev) +{ + struct cops_local *lp = netdev_priv(dev); + + /* + * Once the card has the firmware loaded and has acquired + * the nodeid, if it is reset it will lose it all. + */ + cops_reset(dev,1); /* Need to reset card before load firmware. */ + cops_load(dev); /* Load the firmware. */ + + /* + * If atalkd already gave us a nodeid we will use that + * one again, else we wait for atalkd to give us a nodeid + * in cops_ioctl. This may cause a problem if someone steals + * our nodeid while we are resetting. + */ + if(lp->nodeid == 1) + cops_nodeid(dev,lp->node_acquire); + + return 0; +} + +static void tangent_wait_reset(int ioaddr) +{ + int timeout=0; + + while(timeout++ < 5 && (inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0) + mdelay(1); /* Wait 1 second */ +} + +/* + * Reset the LocalTalk board. + */ +static void cops_reset(struct net_device *dev, int sleep) +{ + struct cops_local *lp = netdev_priv(dev); + int ioaddr=dev->base_addr; + + if(lp->board==TANGENT) + { + inb(ioaddr); /* Clear request latch. */ + outb(0,ioaddr); /* Clear the TANG_TX_READY flop. */ + outb(0, ioaddr+TANG_RESET); /* Reset the adapter. */ + + tangent_wait_reset(ioaddr); + outb(0, ioaddr+TANG_CLEAR_INT); + } + if(lp->board==DAYNA) + { + outb(0, ioaddr+DAYNA_RESET); /* Assert the reset port */ + inb(ioaddr+DAYNA_RESET); /* Clear the reset */ + if (sleep) + msleep(333); + else + mdelay(333); + } + + netif_wake_queue(dev); +} + +static void cops_load (struct net_device *dev) +{ + struct ifreq ifr; + struct ltfirmware *ltf= (struct ltfirmware *)&ifr.ifr_ifru; + struct cops_local *lp = netdev_priv(dev); + int ioaddr=dev->base_addr; + int length, i = 0; + + strcpy(ifr.ifr_name,"lt0"); + + /* Get card's firmware code and do some checks on it. */ +#ifdef CONFIG_COPS_DAYNA + if(lp->board==DAYNA) + { + ltf->length=sizeof(ffdrv_code); + ltf->data=ffdrv_code; + } + else +#endif +#ifdef CONFIG_COPS_TANGENT + if(lp->board==TANGENT) + { + ltf->length=sizeof(ltdrv_code); + ltf->data=ltdrv_code; + } + else +#endif + { + printk(KERN_INFO "%s; unsupported board type.\n", dev->name); + return; + } + + /* Check to make sure firmware is correct length. */ + if(lp->board==DAYNA && ltf->length!=5983) + { + printk(KERN_WARNING "%s: Firmware is not length of FFDRV.BIN.\n", dev->name); + return; + } + if(lp->board==TANGENT && ltf->length!=2501) + { + printk(KERN_WARNING "%s: Firmware is not length of DRVCODE.BIN.\n", dev->name); + return; + } + + if(lp->board==DAYNA) + { + /* + * We must wait for a status response + * with the DAYNA board. + */ + while(++i<65536) + { + if((inb(ioaddr+DAYNA_CARD_STATUS)&3)==1) + break; + } + + if(i==65536) + return; + } + + /* + * Upload the firmware and kick. Byte-by-byte works nicely here. + */ + i=0; + length = ltf->length; + while(length--) + { + outb(ltf->data[i], ioaddr); + i++; + } + + if(cops_debug > 1) + printk("%s: Uploaded firmware - %d bytes of %d bytes.\n", + dev->name, i, ltf->length); + + if(lp->board==DAYNA) /* Tell Dayna to run the firmware code. */ + outb(1, ioaddr+DAYNA_INT_CARD); + else /* Tell Tang to run the firmware code. */ + inb(ioaddr); + + if(lp->board==TANGENT) + { + tangent_wait_reset(ioaddr); + inb(ioaddr); /* Clear initial ready signal. */ + } +} + +/* + * Get the LocalTalk Nodeid from the card. We can suggest + * any nodeid 1-254. The card will try and get that exact + * address else we can specify 0 as the nodeid and the card + * will autoprobe for a nodeid. + */ +static int cops_nodeid (struct net_device *dev, int nodeid) +{ + struct cops_local *lp = netdev_priv(dev); + int ioaddr = dev->base_addr; + + if(lp->board == DAYNA) + { + /* Empty any pending adapter responses. */ + while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0) + { + outb(0, ioaddr+COPS_CLEAR_INT); /* Clear interrupts. */ + if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST) + cops_rx(dev); /* Kick any packets waiting. */ + schedule(); + } + + outb(2, ioaddr); /* Output command packet length as 2. */ + outb(0, ioaddr); + outb(LAP_INIT, ioaddr); /* Send LAP_INIT command byte. */ + outb(nodeid, ioaddr); /* Suggest node address. */ + } + + if(lp->board == TANGENT) + { + /* Empty any pending adapter responses. */ + while(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY) + { + outb(0, ioaddr+COPS_CLEAR_INT); /* Clear interrupt. */ + cops_rx(dev); /* Kick out packets waiting. */ + schedule(); + } + + /* Not sure what Tangent does if nodeid picked is used. */ + if(nodeid == 0) /* Seed. */ + nodeid = jiffies&0xFF; /* Get a random try */ + outb(2, ioaddr); /* Command length LSB */ + outb(0, ioaddr); /* Command length MSB */ + outb(LAP_INIT, ioaddr); /* Send LAP_INIT byte */ + outb(nodeid, ioaddr); /* LAP address hint. */ + outb(0xFF, ioaddr); /* Int. level to use */ + } + + lp->node_acquire=0; /* Set nodeid holder to 0. */ + while(lp->node_acquire==0) /* Get *True* nodeid finally. */ + { + outb(0, ioaddr+COPS_CLEAR_INT); /* Clear any interrupt. */ + + if(lp->board == DAYNA) + { + if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST) + cops_rx(dev); /* Grab the nodeid put in lp->node_acquire. */ + } + if(lp->board == TANGENT) + { + if(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY) + cops_rx(dev); /* Grab the nodeid put in lp->node_acquire. */ + } + schedule(); + } + + if(cops_debug > 1) + printk(KERN_DEBUG "%s: Node ID %d has been acquired.\n", + dev->name, lp->node_acquire); + + lp->nodeid=1; /* Set got nodeid to 1. */ + + return 0; +} + +/* + * Poll the Tangent type cards to see if we have work. + */ + +static void cops_poll(unsigned long ltdev) +{ + int ioaddr, status; + int boguscount = 0; + + struct net_device *dev = (struct net_device *)ltdev; + + del_timer(&cops_timer); + + if(dev == NULL) + return; /* We've been downed */ + + ioaddr = dev->base_addr; + do { + status=inb(ioaddr+TANG_CARD_STATUS); + if(status & TANG_RX_READY) + cops_rx(dev); + if(status & TANG_TX_READY) + netif_wake_queue(dev); + status = inb(ioaddr+TANG_CARD_STATUS); + } while((++boguscount < 20) && (status&(TANG_RX_READY|TANG_TX_READY))); + + /* poll 20 times per second */ + cops_timer.expires = jiffies + HZ/20; + add_timer(&cops_timer); +} + +/* + * The typical workload of the driver: + * Handle the network interface interrupts. + */ +static irqreturn_t cops_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct cops_local *lp; + int ioaddr, status; + int boguscount = 0; + + ioaddr = dev->base_addr; + lp = netdev_priv(dev); + + if(lp->board==DAYNA) + { + do { + outb(0, ioaddr + COPS_CLEAR_INT); + status=inb(ioaddr+DAYNA_CARD_STATUS); + if((status&0x03)==DAYNA_RX_REQUEST) + cops_rx(dev); + netif_wake_queue(dev); + } while(++boguscount < 20); + } + else + { + do { + status=inb(ioaddr+TANG_CARD_STATUS); + if(status & TANG_RX_READY) + cops_rx(dev); + if(status & TANG_TX_READY) + netif_wake_queue(dev); + status=inb(ioaddr+TANG_CARD_STATUS); + } while((++boguscount < 20) && (status&(TANG_RX_READY|TANG_TX_READY))); + } + + return IRQ_HANDLED; +} + +/* + * We have a good packet(s), get it/them out of the buffers. + */ +static void cops_rx(struct net_device *dev) +{ + int pkt_len = 0; + int rsp_type = 0; + struct sk_buff *skb = NULL; + struct cops_local *lp = netdev_priv(dev); + int ioaddr = dev->base_addr; + int boguscount = 0; + unsigned long flags; + + + spin_lock_irqsave(&lp->lock, flags); + + if(lp->board==DAYNA) + { + outb(0, ioaddr); /* Send out Zero length. */ + outb(0, ioaddr); + outb(DATA_READ, ioaddr); /* Send read command out. */ + + /* Wait for DMA to turn around. */ + while(++boguscount<1000000) + { + barrier(); + if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_READY) + break; + } + + if(boguscount==1000000) + { + printk(KERN_WARNING "%s: DMA timed out.\n",dev->name); + spin_unlock_irqrestore(&lp->lock, flags); + return; + } + } + + /* Get response length. */ + if(lp->board==DAYNA) + pkt_len = inb(ioaddr) & 0xFF; + else + pkt_len = inb(ioaddr) & 0x00FF; + pkt_len |= (inb(ioaddr) << 8); + /* Input IO code. */ + rsp_type=inb(ioaddr); + + /* Malloc up new buffer. */ + skb = dev_alloc_skb(pkt_len); + if(skb == NULL) + { + printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", + dev->name); + dev->stats.rx_dropped++; + while(pkt_len--) /* Discard packet */ + inb(ioaddr); + spin_unlock_irqrestore(&lp->lock, flags); + return; + } + skb->dev = dev; + skb_put(skb, pkt_len); + skb->protocol = htons(ETH_P_LOCALTALK); + + insb(ioaddr, skb->data, pkt_len); /* Eat the Data */ + + if(lp->board==DAYNA) + outb(1, ioaddr+DAYNA_INT_CARD); /* Interrupt the card */ + + spin_unlock_irqrestore(&lp->lock, flags); /* Restore interrupts. */ + + /* Check for bad response length */ + if(pkt_len < 0 || pkt_len > MAX_LLAP_SIZE) + { + printk(KERN_WARNING "%s: Bad packet length of %d bytes.\n", + dev->name, pkt_len); + dev->stats.tx_errors++; + dev_kfree_skb_any(skb); + return; + } + + /* Set nodeid and then get out. */ + if(rsp_type == LAP_INIT_RSP) + { /* Nodeid taken from received packet. */ + lp->node_acquire = skb->data[0]; + dev_kfree_skb_any(skb); + return; + } + + /* One last check to make sure we have a good packet. */ + if(rsp_type != LAP_RESPONSE) + { + printk(KERN_WARNING "%s: Bad packet type %d.\n", dev->name, rsp_type); + dev->stats.tx_errors++; + dev_kfree_skb_any(skb); + return; + } + + skb_reset_mac_header(skb); /* Point to entire packet. */ + skb_pull(skb,3); + skb_reset_transport_header(skb); /* Point to data (Skip header). */ + + /* Update the counters. */ + dev->stats.rx_packets++; + dev->stats.rx_bytes += skb->len; + + /* Send packet to a higher place. */ + netif_rx(skb); +} + +static void cops_timeout(struct net_device *dev) +{ + struct cops_local *lp = netdev_priv(dev); + int ioaddr = dev->base_addr; + + dev->stats.tx_errors++; + if(lp->board==TANGENT) + { + if((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0) + printk(KERN_WARNING "%s: No TX complete interrupt.\n", dev->name); + } + printk(KERN_WARNING "%s: Transmit timed out.\n", dev->name); + cops_jumpstart(dev); /* Restart the card. */ + dev->trans_start = jiffies; /* prevent tx timeout */ + netif_wake_queue(dev); +} + + +/* + * Make the card transmit a LocalTalk packet. + */ + +static netdev_tx_t cops_send_packet(struct sk_buff *skb, + struct net_device *dev) +{ + struct cops_local *lp = netdev_priv(dev); + int ioaddr = dev->base_addr; + unsigned long flags; + + /* + * Block a timer-based transmit from overlapping. + */ + + netif_stop_queue(dev); + + spin_lock_irqsave(&lp->lock, flags); + if(lp->board == DAYNA) /* Wait for adapter transmit buffer. */ + while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0) + cpu_relax(); + if(lp->board == TANGENT) /* Wait for adapter transmit buffer. */ + while((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0) + cpu_relax(); + + /* Output IO length. */ + outb(skb->len, ioaddr); + if(lp->board == DAYNA) + outb(skb->len >> 8, ioaddr); + else + outb((skb->len >> 8)&0x0FF, ioaddr); + + /* Output IO code. */ + outb(LAP_WRITE, ioaddr); + + if(lp->board == DAYNA) /* Check the transmit buffer again. */ + while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0); + + outsb(ioaddr, skb->data, skb->len); /* Send out the data. */ + + if(lp->board==DAYNA) /* Dayna requires you kick the card */ + outb(1, ioaddr+DAYNA_INT_CARD); + + spin_unlock_irqrestore(&lp->lock, flags); /* Restore interrupts. */ + + /* Done sending packet, update counters and cleanup. */ + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + dev_kfree_skb (skb); + return NETDEV_TX_OK; +} + +/* + * Dummy function to keep the Appletalk layer happy. + */ + +static void set_multicast_list(struct net_device *dev) +{ + if(cops_debug >= 3) + printk("%s: set_multicast_list executed\n", dev->name); +} + +/* + * System ioctls for the COPS LocalTalk card. + */ + +static int cops_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct cops_local *lp = netdev_priv(dev); + struct sockaddr_at *sa = (struct sockaddr_at *)&ifr->ifr_addr; + struct atalk_addr *aa = (struct atalk_addr *)&lp->node_addr; + + switch(cmd) + { + case SIOCSIFADDR: + /* Get and set the nodeid and network # atalkd wants. */ + cops_nodeid(dev, sa->sat_addr.s_node); + aa->s_net = sa->sat_addr.s_net; + aa->s_node = lp->node_acquire; + + /* Set broardcast address. */ + dev->broadcast[0] = 0xFF; + + /* Set hardware address. */ + dev->dev_addr[0] = aa->s_node; + dev->addr_len = 1; + return 0; + + case SIOCGIFADDR: + sa->sat_addr.s_net = aa->s_net; + sa->sat_addr.s_node = aa->s_node; + return 0; + + default: + return -EOPNOTSUPP; + } +} + +/* + * The inverse routine to cops_open(). + */ + +static int cops_close(struct net_device *dev) +{ + struct cops_local *lp = netdev_priv(dev); + + /* If we were running polled, yank the timer. + */ + if(lp->board==TANGENT && dev->irq==0) + del_timer(&cops_timer); + + netif_stop_queue(dev); + return 0; +} + + +#ifdef MODULE +static struct net_device *cops_dev; + +MODULE_LICENSE("GPL"); +module_param(io, int, 0); +module_param(irq, int, 0); +module_param(board_type, int, 0); + +static int __init cops_module_init(void) +{ + if (io == 0) + printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n", + cardname); + cops_dev = cops_probe(-1); + if (IS_ERR(cops_dev)) + return PTR_ERR(cops_dev); + return 0; +} + +static void __exit cops_module_exit(void) +{ + unregister_netdev(cops_dev); + cleanup_card(cops_dev); + free_netdev(cops_dev); +} +module_init(cops_module_init); +module_exit(cops_module_exit); +#endif /* MODULE */ diff --git a/drivers/staging/appletalk/cops.h b/drivers/staging/appletalk/cops.h new file mode 100644 index 000000000000..fd2750b269c8 --- /dev/null +++ b/drivers/staging/appletalk/cops.h @@ -0,0 +1,60 @@ +/* cops.h: LocalTalk driver for Linux. + * + * Authors: + * - Jay Schulist + */ + +#ifndef __LINUX_COPSLTALK_H +#define __LINUX_COPSLTALK_H + +#ifdef __KERNEL__ + +/* Max LLAP size we will accept. */ +#define MAX_LLAP_SIZE 603 + +/* Tangent */ +#define TANG_CARD_STATUS 1 +#define TANG_CLEAR_INT 1 +#define TANG_RESET 3 + +#define TANG_TX_READY 1 +#define TANG_RX_READY 2 + +/* Dayna */ +#define DAYNA_CMD_DATA 0 +#define DAYNA_CLEAR_INT 1 +#define DAYNA_CARD_STATUS 2 +#define DAYNA_INT_CARD 3 +#define DAYNA_RESET 4 + +#define DAYNA_RX_READY 0 +#define DAYNA_TX_READY 1 +#define DAYNA_RX_REQUEST 3 + +/* Same on both card types */ +#define COPS_CLEAR_INT 1 + +/* LAP response codes received from the cards. */ +#define LAP_INIT 1 /* Init cmd */ +#define LAP_INIT_RSP 2 /* Init response */ +#define LAP_WRITE 3 /* Write cmd */ +#define DATA_READ 4 /* Data read */ +#define LAP_RESPONSE 4 /* Received ALAP frame response */ +#define LAP_GETSTAT 5 /* Get LAP and HW status */ +#define LAP_RSPSTAT 6 /* Status response */ + +#endif + +/* + * Structure to hold the firmware information. + */ +struct ltfirmware +{ + unsigned int length; + const unsigned char *data; +}; + +#define DAYNA 1 +#define TANGENT 2 + +#endif diff --git a/drivers/staging/appletalk/cops_ffdrv.h b/drivers/staging/appletalk/cops_ffdrv.h new file mode 100644 index 000000000000..b02005087c1b --- /dev/null +++ b/drivers/staging/appletalk/cops_ffdrv.h @@ -0,0 +1,532 @@ + +/* + * The firmware this driver downloads into the Localtalk card is a + * separate program and is not GPL'd source code, even though the Linux + * side driver and the routine that loads this data into the card are. + * + * It is taken from the COPS SDK and is under the following license + * + * This material is licensed to you strictly for use in conjunction with + * the use of COPS LocalTalk adapters. + * There is no charge for this SDK. And no waranty express or implied + * about its fitness for any purpose. However, we will cheerefully + * refund every penny you paid for this SDK... + * Regards, + * + * Thomas F. Divine + * Chief Scientist + */ + + +/* cops_ffdrv.h: LocalTalk driver firmware dump for Linux. + * + * Authors: + * - Jay Schulist + */ + + +#ifdef CONFIG_COPS_DAYNA + +static const unsigned char ffdrv_code[] = { + 58,3,0,50,228,149,33,255,255,34,226,149, + 249,17,40,152,33,202,154,183,237,82,77,68, + 11,107,98,19,54,0,237,176,175,50,80,0, + 62,128,237,71,62,32,237,57,51,62,12,237, + 57,50,237,57,54,62,6,237,57,52,62,12, + 237,57,49,33,107,137,34,32,128,33,83,130, + 34,40,128,33,86,130,34,42,128,33,112,130, + 34,36,128,33,211,130,34,38,128,62,0,237, + 57,16,33,63,148,34,34,128,237,94,205,15, + 130,251,205,168,145,24,141,67,111,112,121,114, + 105,103,104,116,32,40,67,41,32,49,57,56, + 56,32,45,32,68,97,121,110,97,32,67,111, + 109,109,117,110,105,99,97,116,105,111,110,115, + 32,32,32,65,108,108,32,114,105,103,104,116, + 115,32,114,101,115,101,114,118,101,100,46,32, + 32,40,68,40,68,7,16,8,34,7,22,6, + 16,5,12,4,8,3,6,140,0,16,39,128, + 0,4,96,10,224,6,0,7,126,2,64,11, + 118,12,6,13,0,14,193,15,0,5,96,3, + 192,1,64,9,8,62,9,211,66,62,192,211, + 66,62,100,61,32,253,6,28,33,205,129,14, + 66,237,163,194,253,129,6,28,33,205,129,14, + 64,237,163,194,9,130,201,62,47,50,71,152, + 62,47,211,68,58,203,129,237,57,20,58,204, + 129,237,57,21,33,77,152,54,132,205,233,129, + 58,228,149,254,209,40,6,56,4,62,0,24, + 2,219,96,33,233,149,119,230,62,33,232,149, + 119,213,33,8,152,17,7,0,25,119,19,25, + 119,209,201,251,237,77,245,197,213,229,221,229, + 205,233,129,62,1,50,106,137,205,158,139,221, + 225,225,209,193,241,251,237,77,245,197,213,219, + 72,237,56,16,230,46,237,57,16,237,56,12, + 58,72,152,183,32,26,6,20,17,128,2,237, + 56,46,187,32,35,237,56,47,186,32,29,219, + 72,230,1,32,3,5,32,232,175,50,72,152, + 229,221,229,62,1,50,106,137,205,158,139,221, + 225,225,24,25,62,1,50,72,152,58,201,129, + 237,57,12,58,202,129,237,57,13,237,56,16, + 246,17,237,57,16,209,193,241,251,237,77,245, + 197,229,213,221,229,237,56,16,230,17,237,57, + 16,237,56,20,58,34,152,246,16,246,8,211, + 68,62,6,61,32,253,58,34,152,246,8,211, + 68,58,203,129,237,57,20,58,204,129,237,57, + 21,237,56,16,246,34,237,57,16,221,225,209, + 225,193,241,251,237,77,33,2,0,57,126,230, + 3,237,100,1,40,2,246,128,230,130,245,62, + 5,211,64,241,211,64,201,229,213,243,237,56, + 16,230,46,237,57,16,237,56,12,251,70,35, + 35,126,254,175,202,77,133,254,129,202,15,133, + 230,128,194,191,132,43,58,44,152,119,33,76, + 152,119,35,62,132,119,120,254,255,40,4,58, + 49,152,119,219,72,43,43,112,17,3,0,237, + 56,52,230,248,237,57,52,219,72,230,1,194, + 141,131,209,225,237,56,52,246,6,237,57,52, + 62,1,55,251,201,62,3,211,66,62,192,211, + 66,62,48,211,66,0,0,219,66,230,1,40, + 4,219,67,24,240,205,203,135,58,75,152,254, + 255,202,128,132,58,49,152,254,161,250,207,131, + 58,34,152,211,68,62,10,211,66,62,128,211, + 66,62,11,211,66,62,6,211,66,24,0,62, + 14,211,66,62,33,211,66,62,1,211,66,62, + 64,211,66,62,3,211,66,62,209,211,66,62, + 100,71,219,66,230,1,32,6,5,32,247,195, + 248,132,219,67,71,58,44,152,184,194,248,132, + 62,100,71,219,66,230,1,32,6,5,32,247, + 195,248,132,219,67,62,100,71,219,66,230,1, + 32,6,5,32,247,195,248,132,219,67,254,133, + 32,7,62,0,50,74,152,24,17,254,173,32, + 7,62,1,50,74,152,24,6,254,141,194,248, + 132,71,209,225,58,49,152,254,132,32,10,62, + 50,205,2,134,205,144,135,24,27,254,140,32, + 15,62,110,205,2,134,62,141,184,32,5,205, + 144,135,24,8,62,10,205,2,134,205,8,134, + 62,1,50,106,137,205,158,139,237,56,52,246, + 6,237,57,52,175,183,251,201,62,20,135,237, + 57,20,175,237,57,21,237,56,16,246,2,237, + 57,16,237,56,20,95,237,56,21,123,254,10, + 48,244,237,56,16,230,17,237,57,16,209,225, + 205,144,135,62,1,50,106,137,205,158,139,237, + 56,52,246,6,237,57,52,175,183,251,201,209, + 225,243,219,72,230,1,40,13,62,10,211,66, + 0,0,219,66,230,192,202,226,132,237,56,52, + 246,6,237,57,52,62,1,55,251,201,205,203, + 135,62,1,50,106,137,205,158,139,237,56,52, + 246,6,237,57,52,183,251,201,209,225,62,1, + 50,106,137,205,158,139,237,56,52,246,6,237, + 57,52,62,2,55,251,201,209,225,243,219,72, + 230,1,202,213,132,62,10,211,66,0,0,219, + 66,230,192,194,213,132,229,62,1,50,106,137, + 42,40,152,205,65,143,225,17,3,0,205,111, + 136,62,6,211,66,58,44,152,211,66,237,56, + 52,246,6,237,57,52,183,251,201,209,197,237, + 56,52,230,248,237,57,52,219,72,230,1,32, + 15,193,225,237,56,52,246,6,237,57,52,62, + 1,55,251,201,14,23,58,37,152,254,0,40, + 14,14,2,254,1,32,5,62,140,119,24,3, + 62,132,119,43,43,197,205,203,135,193,62,1, + 211,66,62,64,211,66,62,3,211,66,62,193, + 211,66,62,100,203,39,71,219,66,230,1,32, + 6,5,32,247,195,229,133,33,238,151,219,67, + 71,58,44,152,184,194,229,133,119,62,100,71, + 219,66,230,1,32,6,5,32,247,195,229,133, + 219,67,35,119,13,32,234,193,225,62,1,50, + 106,137,205,158,139,237,56,52,246,6,237,57, + 52,175,183,251,201,33,234,151,35,35,62,255, + 119,193,225,62,1,50,106,137,205,158,139,237, + 56,52,246,6,237,57,52,175,251,201,243,61, + 32,253,251,201,62,3,211,66,62,192,211,66, + 58,49,152,254,140,32,19,197,229,213,17,181, + 129,33,185,129,1,2,0,237,176,209,225,193, + 24,27,229,213,33,187,129,58,49,152,230,15, + 87,30,2,237,92,25,17,181,129,126,18,19, + 35,126,18,209,225,58,34,152,246,8,211,68, + 58,49,152,254,165,40,14,254,164,40,10,62, + 10,211,66,62,224,211,66,24,25,58,74,152, + 254,0,40,10,62,10,211,66,62,160,211,66, + 24,8,62,10,211,66,62,128,211,66,62,11, + 211,66,62,6,211,66,205,147,143,62,5,211, + 66,62,224,211,66,62,5,211,66,62,96,211, + 66,62,5,61,32,253,62,5,211,66,62,224, + 211,66,62,14,61,32,253,62,5,211,66,62, + 233,211,66,62,128,211,66,58,181,129,61,32, + 253,62,1,211,66,62,192,211,66,1,254,19, + 237,56,46,187,32,6,13,32,247,195,226,134, + 62,192,211,66,0,0,219,66,203,119,40,250, + 219,66,203,87,40,250,243,237,56,16,230,17, + 237,57,16,237,56,20,251,62,5,211,66,62, + 224,211,66,58,182,129,61,32,253,229,33,181, + 129,58,183,129,203,63,119,35,58,184,129,119, + 225,62,10,211,66,62,224,211,66,62,11,211, + 66,62,118,211,66,62,47,211,68,62,5,211, + 66,62,233,211,66,58,181,129,61,32,253,62, + 5,211,66,62,224,211,66,58,182,129,61,32, + 253,62,5,211,66,62,96,211,66,201,229,213, + 58,50,152,230,15,87,30,2,237,92,33,187, + 129,25,17,181,129,126,18,35,19,126,18,209, + 225,58,71,152,246,8,211,68,58,50,152,254, + 165,40,14,254,164,40,10,62,10,211,66,62, + 224,211,66,24,8,62,10,211,66,62,128,211, + 66,62,11,211,66,62,6,211,66,195,248,135, + 62,3,211,66,62,192,211,66,197,229,213,17, + 181,129,33,183,129,1,2,0,237,176,209,225, + 193,62,47,211,68,62,10,211,66,62,224,211, + 66,62,11,211,66,62,118,211,66,62,1,211, + 66,62,0,211,66,205,147,143,195,16,136,62, + 3,211,66,62,192,211,66,197,229,213,17,181, + 129,33,183,129,1,2,0,237,176,209,225,193, + 62,47,211,68,62,10,211,66,62,224,211,66, + 62,11,211,66,62,118,211,66,205,147,143,62, + 5,211,66,62,224,211,66,62,5,211,66,62, + 96,211,66,62,5,61,32,253,62,5,211,66, + 62,224,211,66,62,14,61,32,253,62,5,211, + 66,62,233,211,66,62,128,211,66,58,181,129, + 61,32,253,62,1,211,66,62,192,211,66,1, + 254,19,237,56,46,187,32,6,13,32,247,195, + 88,136,62,192,211,66,0,0,219,66,203,119, + 40,250,219,66,203,87,40,250,62,5,211,66, + 62,224,211,66,58,182,129,61,32,253,62,5, + 211,66,62,96,211,66,201,197,14,67,6,0, + 62,3,211,66,62,192,211,66,62,48,211,66, + 0,0,219,66,230,1,40,4,219,67,24,240, + 62,5,211,66,62,233,211,66,62,128,211,66, + 58,181,129,61,32,253,237,163,29,62,192,211, + 66,219,66,230,4,40,250,237,163,29,32,245, + 219,66,230,4,40,250,62,255,71,219,66,230, + 4,40,3,5,32,247,219,66,230,4,40,250, + 62,5,211,66,62,224,211,66,58,182,129,61, + 32,253,62,5,211,66,62,96,211,66,58,71, + 152,254,1,202,18,137,62,16,211,66,62,56, + 211,66,62,14,211,66,62,33,211,66,62,1, + 211,66,62,248,211,66,237,56,48,246,153,230, + 207,237,57,48,62,3,211,66,62,221,211,66, + 193,201,58,71,152,211,68,62,10,211,66,62, + 128,211,66,62,11,211,66,62,6,211,66,62, + 6,211,66,58,44,152,211,66,62,16,211,66, + 62,56,211,66,62,48,211,66,0,0,62,14, + 211,66,62,33,211,66,62,1,211,66,62,248, + 211,66,237,56,48,246,145,246,8,230,207,237, + 57,48,62,3,211,66,62,221,211,66,193,201, + 44,3,1,0,70,69,1,245,197,213,229,175, + 50,72,152,237,56,16,230,46,237,57,16,237, + 56,12,62,1,211,66,0,0,219,66,95,230, + 160,32,3,195,20,139,123,230,96,194,72,139, + 62,48,211,66,62,1,211,66,62,64,211,66, + 237,91,40,152,205,207,143,25,43,55,237,82, + 218,70,139,34,42,152,98,107,58,44,152,190, + 194,210,138,35,35,62,130,190,194,200,137,62, + 1,50,48,152,62,175,190,202,82,139,62,132, + 190,32,44,50,50,152,62,47,50,71,152,229, + 175,50,106,137,42,40,152,205,65,143,225,54, + 133,43,70,58,44,152,119,43,112,17,3,0, + 62,10,205,2,134,205,111,136,195,158,138,62, + 140,190,32,19,50,50,152,58,233,149,230,4, + 202,222,138,62,1,50,71,152,195,219,137,126, + 254,160,250,185,138,254,166,242,185,138,50,50, + 152,43,126,35,229,213,33,234,149,95,22,0, + 25,126,254,132,40,18,254,140,40,14,58,50, + 152,230,15,87,126,31,21,242,65,138,56,2, + 175,119,58,50,152,230,15,87,58,233,149,230, + 62,31,21,242,85,138,218,98,138,209,225,195, + 20,139,58,50,152,33,100,137,230,15,95,22, + 0,25,126,50,71,152,209,225,58,50,152,254, + 164,250,135,138,58,73,152,254,0,40,4,54, + 173,24,2,54,133,43,70,58,44,152,119,43, + 112,17,3,0,205,70,135,175,50,106,137,205, + 208,139,58,199,129,237,57,12,58,200,129,237, + 57,13,237,56,16,246,17,237,57,16,225,209, + 193,241,251,237,77,62,129,190,194,227,138,54, + 130,43,70,58,44,152,119,43,112,17,3,0, + 205,144,135,195,20,139,35,35,126,254,132,194, + 227,138,175,50,106,137,205,158,139,24,42,58, + 201,154,254,1,40,7,62,1,50,106,137,24, + 237,58,106,137,254,1,202,222,138,62,128,166, + 194,222,138,221,229,221,33,67,152,205,127,142, + 205,109,144,221,225,225,209,193,241,251,237,77, + 58,106,137,254,1,202,44,139,58,50,152,254, + 164,250,44,139,58,73,152,238,1,50,73,152, + 221,229,221,33,51,152,205,127,142,221,225,62, + 1,50,106,137,205,158,139,195,13,139,24,208, + 24,206,24,204,230,64,40,3,195,20,139,195, + 20,139,43,126,33,8,152,119,35,58,44,152, + 119,43,237,91,35,152,205,203,135,205,158,139, + 195,13,139,175,50,78,152,62,3,211,66,62, + 192,211,66,201,197,33,4,0,57,126,35,102, + 111,62,1,50,106,137,219,72,205,141,139,193, + 201,62,1,50,78,152,34,40,152,54,0,35, + 35,54,0,195,163,139,58,78,152,183,200,229, + 33,181,129,58,183,129,119,35,58,184,129,119, + 225,62,47,211,68,62,14,211,66,62,193,211, + 66,62,10,211,66,62,224,211,66,62,11,211, + 66,62,118,211,66,195,3,140,58,78,152,183, + 200,58,71,152,211,68,254,69,40,4,254,70, + 32,17,58,73,152,254,0,40,10,62,10,211, + 66,62,160,211,66,24,8,62,10,211,66,62, + 128,211,66,62,11,211,66,62,6,211,66,62, + 6,211,66,58,44,152,211,66,62,16,211,66, + 62,56,211,66,62,48,211,66,0,0,219,66, + 230,1,40,4,219,67,24,240,62,14,211,66, + 62,33,211,66,42,40,152,205,65,143,62,1, + 211,66,62,248,211,66,237,56,48,246,145,246, + 8,230,207,237,57,48,62,3,211,66,62,221, + 211,66,201,62,16,211,66,62,56,211,66,62, + 48,211,66,0,0,219,66,230,1,40,4,219, + 67,24,240,62,14,211,66,62,33,211,66,62, + 1,211,66,62,248,211,66,237,56,48,246,153, + 230,207,237,57,48,62,3,211,66,62,221,211, + 66,201,229,213,33,234,149,95,22,0,25,126, + 254,132,40,4,254,140,32,2,175,119,123,209, + 225,201,6,8,14,0,31,48,1,12,16,250, + 121,201,33,4,0,57,94,35,86,33,2,0, + 57,126,35,102,111,221,229,34,89,152,237,83, + 91,152,221,33,63,152,205,127,142,58,81,152, + 50,82,152,58,80,152,135,50,80,152,205,162, + 140,254,3,56,16,58,81,152,135,60,230,15, + 50,81,152,175,50,80,152,24,23,58,79,152, + 205,162,140,254,3,48,13,58,81,152,203,63, + 50,81,152,62,255,50,79,152,58,81,152,50, + 82,152,58,79,152,135,50,79,152,62,32,50, + 83,152,50,84,152,237,56,16,230,17,237,57, + 16,219,72,62,192,50,93,152,62,93,50,94, + 152,58,93,152,61,50,93,152,32,9,58,94, + 152,61,50,94,152,40,44,62,170,237,57,20, + 175,237,57,21,237,56,16,246,2,237,57,16, + 219,72,230,1,202,29,141,237,56,20,71,237, + 56,21,120,254,10,48,237,237,56,16,230,17, + 237,57,16,243,62,14,211,66,62,65,211,66, + 251,58,39,152,23,23,60,50,39,152,71,58, + 82,152,160,230,15,40,22,71,14,10,219,66, + 230,16,202,186,141,219,72,230,1,202,186,141, + 13,32,239,16,235,42,89,152,237,91,91,152, + 205,47,131,48,7,61,202,186,141,195,227,141, + 221,225,33,0,0,201,221,33,55,152,205,127, + 142,58,84,152,61,50,84,152,40,19,58,82, + 152,246,1,50,82,152,58,79,152,246,1,50, + 79,152,195,29,141,221,225,33,1,0,201,221, + 33,59,152,205,127,142,58,80,152,246,1,50, + 80,152,58,82,152,135,246,1,50,82,152,58, + 83,152,61,50,83,152,194,29,141,221,225,33, + 2,0,201,221,229,33,0,0,57,17,4,0, + 25,126,50,44,152,230,128,50,85,152,58,85, + 152,183,40,6,221,33,88,2,24,4,221,33, + 150,0,58,44,152,183,40,53,60,40,50,60, + 40,47,61,61,33,86,152,119,35,119,35,54, + 129,175,50,48,152,221,43,221,229,225,124,181, + 40,42,33,86,152,17,3,0,205,189,140,17, + 232,3,27,123,178,32,251,58,48,152,183,40, + 224,58,44,152,71,62,7,128,230,127,71,58, + 85,152,176,50,44,152,24,162,221,225,201,183, + 221,52,0,192,221,52,1,192,221,52,2,192, + 221,52,3,192,55,201,245,62,1,211,100,241, + 201,245,62,1,211,96,241,201,33,2,0,57, + 126,35,102,111,237,56,48,230,175,237,57,48, + 62,48,237,57,49,125,237,57,32,124,237,57, + 33,62,0,237,57,34,62,88,237,57,35,62, + 0,237,57,36,237,57,37,33,128,2,125,237, + 57,38,124,237,57,39,237,56,48,246,97,230, + 207,237,57,48,62,0,237,57,0,62,0,211, + 96,211,100,201,33,2,0,57,126,35,102,111, + 237,56,48,230,175,237,57,48,62,12,237,57, + 49,62,76,237,57,32,62,0,237,57,33,237, + 57,34,125,237,57,35,124,237,57,36,62,0, + 237,57,37,33,128,2,125,237,57,38,124,237, + 57,39,237,56,48,246,97,230,207,237,57,48, + 62,1,211,96,201,33,2,0,57,126,35,102, + 111,229,237,56,48,230,87,237,57,48,125,237, + 57,40,124,237,57,41,62,0,237,57,42,62, + 67,237,57,43,62,0,237,57,44,58,106,137, + 254,1,32,5,33,6,0,24,3,33,128,2, + 125,237,57,46,124,237,57,47,237,56,50,230, + 252,246,2,237,57,50,225,201,33,4,0,57, + 94,35,86,33,2,0,57,126,35,102,111,237, + 56,48,230,87,237,57,48,125,237,57,40,124, + 237,57,41,62,0,237,57,42,62,67,237,57, + 43,62,0,237,57,44,123,237,57,46,122,237, + 57,47,237,56,50,230,244,246,0,237,57,50, + 237,56,48,246,145,230,207,237,57,48,201,213, + 237,56,46,95,237,56,47,87,237,56,46,111, + 237,56,47,103,183,237,82,32,235,33,128,2, + 183,237,82,209,201,213,237,56,38,95,237,56, + 39,87,237,56,38,111,237,56,39,103,183,237, + 82,32,235,33,128,2,183,237,82,209,201,245, + 197,1,52,0,237,120,230,253,237,121,193,241, + 201,245,197,1,52,0,237,120,246,2,237,121, + 193,241,201,33,2,0,57,126,35,102,111,126, + 35,110,103,201,33,0,0,34,102,152,34,96, + 152,34,98,152,33,202,154,34,104,152,237,91, + 104,152,42,226,149,183,237,82,17,0,255,25, + 34,100,152,203,124,40,6,33,0,125,34,100, + 152,42,104,152,35,35,35,229,205,120,139,193, + 201,205,186,149,229,42,40,152,35,35,35,229, + 205,39,144,193,124,230,3,103,221,117,254,221, + 116,255,237,91,42,152,35,35,35,183,237,82, + 32,12,17,5,0,42,42,152,205,171,149,242, + 169,144,42,40,152,229,205,120,139,193,195,198, + 149,237,91,42,152,42,98,152,25,34,98,152, + 19,19,19,42,102,152,25,34,102,152,237,91, + 100,152,33,158,253,25,237,91,102,152,205,171, + 149,242,214,144,33,0,0,34,102,152,62,1, + 50,95,152,205,225,144,195,198,149,58,95,152, + 183,200,237,91,96,152,42,102,152,205,171,149, + 242,5,145,237,91,102,152,33,98,2,25,237, + 91,96,152,205,171,149,250,37,145,237,91,96, + 152,42,102,152,183,237,82,32,7,42,98,152, + 125,180,40,13,237,91,102,152,42,96,152,205, + 171,149,242,58,145,237,91,104,152,42,102,152, + 25,35,35,35,229,205,120,139,193,175,50,95, + 152,201,195,107,139,205,206,149,250,255,243,205, + 225,144,251,58,230,149,183,194,198,149,17,1, + 0,42,98,152,205,171,149,250,198,149,62,1, + 50,230,149,237,91,96,152,42,104,152,25,221, + 117,252,221,116,253,237,91,104,152,42,96,152, + 25,35,35,35,221,117,254,221,116,255,35,35, + 35,229,205,39,144,124,230,3,103,35,35,35, + 221,117,250,221,116,251,235,221,110,252,221,102, + 253,115,35,114,35,54,4,62,1,211,100,211, + 84,195,198,149,33,0,0,34,102,152,34,96, + 152,34,98,152,33,202,154,34,104,152,237,91, + 104,152,42,226,149,183,237,82,17,0,255,25, + 34,100,152,33,109,152,54,0,33,107,152,229, + 205,240,142,193,62,47,50,34,152,62,132,50, + 49,152,205,241,145,205,61,145,58,39,152,60, + 50,39,152,24,241,205,206,149,251,255,33,109, + 152,126,183,202,198,149,110,221,117,251,33,109, + 152,54,0,221,126,251,254,1,40,28,254,3, + 40,101,254,4,202,190,147,254,5,202,147,147, + 254,8,40,87,33,107,152,229,205,240,142,195, + 198,149,58,201,154,183,32,21,33,111,152,126, + 50,229,149,205,52,144,33,110,152,110,38,0, + 229,205,11,142,193,237,91,96,152,42,104,152, + 25,221,117,254,221,116,255,35,35,54,2,17, + 2,0,43,43,115,35,114,58,44,152,35,35, + 119,58,228,149,35,119,62,1,211,100,211,84, + 62,1,50,201,154,24,169,205,153,142,58,231, + 149,183,40,250,175,50,231,149,33,110,152,126, + 254,255,40,91,58,233,149,230,63,183,40,83, + 94,22,0,33,234,149,25,126,183,40,13,33, + 110,152,94,33,234,150,25,126,254,3,32,36, + 205,81,148,125,180,33,110,152,94,22,0,40, + 17,33,234,149,25,54,0,33,107,152,229,205, + 240,142,193,195,198,149,33,234,150,25,54,0, + 33,110,152,94,22,0,33,234,149,25,126,50, + 49,152,254,132,32,37,62,47,50,34,152,42, + 107,152,229,33,110,152,229,205,174,140,193,193, + 125,180,33,110,152,94,22,0,33,234,150,202, + 117,147,25,52,195,120,147,58,49,152,254,140, + 32,7,62,1,50,34,152,24,210,62,32,50, + 106,152,24,19,58,49,152,95,58,106,152,163, + 183,58,106,152,32,11,203,63,50,106,152,58, + 106,152,183,32,231,254,2,40,51,254,4,40, + 38,254,8,40,26,254,16,40,13,254,32,32, + 158,62,165,50,49,152,62,69,24,190,62,164, + 50,49,152,62,70,24,181,62,163,50,49,152, + 175,24,173,62,162,50,49,152,62,1,24,164, + 62,161,50,49,152,62,3,24,155,25,54,0, + 221,126,251,254,8,40,7,58,230,149,183,202, + 32,146,33,107,152,229,205,240,142,193,211,84, + 195,198,149,237,91,96,152,42,104,152,25,221, + 117,254,221,116,255,35,35,54,6,17,2,0, + 43,43,115,35,114,58,228,149,35,35,119,58, + 233,149,35,119,205,146,142,195,32,146,237,91, + 96,152,42,104,152,25,229,205,160,142,193,58, + 231,149,183,40,250,175,50,231,149,243,237,91, + 96,152,42,104,152,25,221,117,254,221,116,255, + 78,35,70,221,113,252,221,112,253,89,80,42, + 98,152,183,237,82,34,98,152,203,124,40,19, + 33,0,0,34,98,152,34,102,152,34,96,152, + 62,1,50,95,152,24,40,221,94,252,221,86, + 253,19,19,19,42,96,152,25,34,96,152,237, + 91,100,152,33,158,253,25,237,91,96,152,205, + 171,149,242,55,148,33,0,0,34,96,152,175, + 50,230,149,251,195,32,146,245,62,1,50,231, + 149,62,16,237,57,0,211,80,241,251,237,77, + 201,205,186,149,229,229,33,0,0,34,37,152, + 33,110,152,126,50,234,151,58,44,152,33,235, + 151,119,221,54,253,0,221,54,254,0,195,230, + 148,33,236,151,54,175,33,3,0,229,33,234, + 151,229,205,174,140,193,193,33,236,151,126,254, + 255,40,74,33,245,151,110,221,117,255,33,249, + 151,126,221,166,255,221,119,255,33,253,151,126, + 221,166,255,221,119,255,58,232,149,95,221,126, + 255,163,221,119,255,183,40,15,230,191,33,110, + 152,94,22,0,33,234,149,25,119,24,12,33, + 110,152,94,22,0,33,234,149,25,54,132,33, + 0,0,195,198,149,221,110,253,221,102,254,35, + 221,117,253,221,116,254,17,32,0,221,110,253, + 221,102,254,205,171,149,250,117,148,58,233,149, + 203,87,40,84,33,1,0,34,37,152,221,54, + 253,0,221,54,254,0,24,53,33,236,151,54, + 175,33,3,0,229,33,234,151,229,205,174,140, + 193,193,33,236,151,126,254,255,40,14,33,110, + 152,94,22,0,33,234,149,25,54,140,24,159, + 221,110,253,221,102,254,35,221,117,253,221,116, + 254,17,32,0,221,110,253,221,102,254,205,171, + 149,250,12,149,33,2,0,34,37,152,221,54, + 253,0,221,54,254,0,24,54,33,236,151,54, + 175,33,3,0,229,33,234,151,229,205,174,140, + 193,193,33,236,151,126,254,255,40,15,33,110, + 152,94,22,0,33,234,149,25,54,132,195,211, + 148,221,110,253,221,102,254,35,221,117,253,221, + 116,254,17,32,0,221,110,253,221,102,254,205, + 171,149,250,96,149,33,1,0,195,198,149,124, + 170,250,179,149,237,82,201,124,230,128,237,82, + 60,201,225,253,229,221,229,221,33,0,0,221, + 57,233,221,249,221,225,253,225,201,233,225,253, + 229,221,229,221,33,0,0,221,57,94,35,86, + 35,235,57,249,235,233,0,0,0,0,0,0, + 62,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 175,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,133,1,0,0,0,63, + 255,255,255,255,0,0,0,63,0,0,0,0, + 0,0,0,0,0,0,0,24,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0 + } ; + +#endif diff --git a/drivers/staging/appletalk/cops_ltdrv.h b/drivers/staging/appletalk/cops_ltdrv.h new file mode 100644 index 000000000000..c699b1ad31da --- /dev/null +++ b/drivers/staging/appletalk/cops_ltdrv.h @@ -0,0 +1,241 @@ +/* + * The firmware this driver downloads into the Localtalk card is a + * separate program and is not GPL'd source code, even though the Linux + * side driver and the routine that loads this data into the card are. + * + * It is taken from the COPS SDK and is under the following license + * + * This material is licensed to you strictly for use in conjunction with + * the use of COPS LocalTalk adapters. + * There is no charge for this SDK. And no waranty express or implied + * about its fitness for any purpose. However, we will cheerefully + * refund every penny you paid for this SDK... + * Regards, + * + * Thomas F. Divine + * Chief Scientist + */ + + +/* cops_ltdrv.h: LocalTalk driver firmware dump for Linux. + * + * Authors: + * - Jay Schulist + */ + + +#ifdef CONFIG_COPS_TANGENT + +static const unsigned char ltdrv_code[] = { + 58,3,0,50,148,10,33,143,15,62,85,119, + 190,32,9,62,170,119,190,32,3,35,24,241, + 34,146,10,249,17,150,10,33,143,15,183,237, + 82,77,68,11,107,98,19,54,0,237,176,62, + 16,237,57,51,62,0,237,57,50,237,57,54, + 62,12,237,57,49,62,195,33,39,2,50,56, + 0,34,57,0,237,86,205,30,2,251,205,60, + 10,24,169,67,111,112,121,114,105,103,104,116, + 32,40,99,41,32,49,57,56,56,45,49,57, + 57,50,44,32,80,114,105,110,116,105,110,103, + 32,67,111,109,109,117,110,105,99,97,116,105, + 111,110,115,32,65,115,115,111,99,105,97,116, + 101,115,44,32,73,110,99,46,65,108,108,32, + 114,105,103,104,116,115,32,114,101,115,101,114, + 118,101,100,46,32,32,4,4,22,40,255,60, + 4,96,10,224,6,0,7,126,2,64,11,246, + 12,6,13,0,14,193,15,0,5,96,3,192, + 1,0,9,8,62,3,211,82,62,192,211,82, + 201,62,3,211,82,62,213,211,82,201,62,5, + 211,82,62,224,211,82,201,62,5,211,82,62, + 224,211,82,201,62,5,211,82,62,96,211,82, + 201,6,28,33,180,1,14,82,237,163,194,4, + 2,33,39,2,34,64,0,58,3,0,230,1, + 192,62,11,237,121,62,118,237,121,201,33,182, + 10,54,132,205,253,1,201,245,197,213,229,42, + 150,10,14,83,17,98,2,67,20,237,162,58, + 179,1,95,219,82,230,1,32,6,29,32,247, + 195,17,3,62,1,211,82,219,82,95,230,160, + 32,10,237,162,32,225,21,32,222,195,15,3, + 237,162,123,230,96,194,21,3,62,48,211,82, + 62,1,211,82,175,211,82,237,91,150,10,43, + 55,237,82,218,19,3,34,152,10,98,107,58, + 154,10,190,32,81,62,1,50,158,10,35,35, + 62,132,190,32,44,54,133,43,70,58,154,10, + 119,43,112,17,3,0,205,137,3,62,16,211, + 82,62,56,211,82,205,217,1,42,150,10,14, + 83,17,98,2,67,20,58,178,1,95,195,59, + 2,62,129,190,194,227,2,54,130,43,70,58, + 154,10,119,43,112,17,3,0,205,137,3,195, + 254,2,35,35,126,254,132,194,227,2,205,61, + 3,24,20,62,128,166,194,222,2,221,229,221, + 33,175,10,205,93,6,205,144,7,221,225,225, + 209,193,241,251,237,77,221,229,221,33,159,10, + 205,93,6,221,225,205,61,3,195,247,2,24, + 237,24,235,24,233,230,64,40,2,24,227,24, + 225,175,50,179,10,205,208,1,201,197,33,4, + 0,57,126,35,102,111,205,51,3,193,201,62, + 1,50,179,10,34,150,10,54,0,58,179,10, + 183,200,62,14,211,82,62,193,211,82,62,10, + 211,82,62,224,211,82,62,6,211,82,58,154, + 10,211,82,62,16,211,82,62,56,211,82,62, + 48,211,82,219,82,230,1,40,4,219,83,24, + 242,62,14,211,82,62,33,211,82,62,1,211, + 82,62,9,211,82,62,32,211,82,205,217,1, + 201,14,83,205,208,1,24,23,14,83,205,208, + 1,205,226,1,58,174,1,61,32,253,205,244, + 1,58,174,1,61,32,253,205,226,1,58,175, + 1,61,32,253,62,5,211,82,62,233,211,82, + 62,128,211,82,58,176,1,61,32,253,237,163, + 27,62,192,211,82,219,82,230,4,40,250,237, + 163,27,122,179,32,243,219,82,230,4,40,250, + 58,178,1,71,219,82,230,4,40,3,5,32, + 247,219,82,230,4,40,250,205,235,1,58,177, + 1,61,32,253,205,244,1,201,229,213,35,35, + 126,230,128,194,145,4,43,58,154,10,119,43, + 70,33,181,10,119,43,112,17,3,0,243,62, + 10,211,82,219,82,230,128,202,41,4,209,225, + 62,1,55,251,201,205,144,3,58,180,10,254, + 255,202,127,4,205,217,1,58,178,1,71,219, + 82,230,1,32,6,5,32,247,195,173,4,219, + 83,71,58,154,10,184,194,173,4,58,178,1, + 71,219,82,230,1,32,6,5,32,247,195,173, + 4,219,83,58,178,1,71,219,82,230,1,32, + 6,5,32,247,195,173,4,219,83,254,133,194, + 173,4,58,179,1,24,4,58,179,1,135,61, + 32,253,209,225,205,137,3,205,61,3,183,251, + 201,209,225,243,62,10,211,82,219,82,230,128, + 202,164,4,62,1,55,251,201,205,144,3,205, + 61,3,183,251,201,209,225,62,2,55,251,201, + 243,62,14,211,82,62,33,211,82,251,201,33, + 4,0,57,94,35,86,33,2,0,57,126,35, + 102,111,221,229,34,193,10,237,83,195,10,221, + 33,171,10,205,93,6,58,185,10,50,186,10, + 58,184,10,135,50,184,10,205,112,6,254,3, + 56,16,58,185,10,135,60,230,15,50,185,10, + 175,50,184,10,24,23,58,183,10,205,112,6, + 254,3,48,13,58,185,10,203,63,50,185,10, + 62,255,50,183,10,58,185,10,50,186,10,58, + 183,10,135,50,183,10,62,32,50,187,10,50, + 188,10,6,255,219,82,230,16,32,3,5,32, + 247,205,180,4,6,40,219,82,230,16,40,3, + 5,32,247,62,10,211,82,219,82,230,128,194, + 46,5,219,82,230,16,40,214,237,95,71,58, + 186,10,160,230,15,40,32,71,14,10,62,10, + 211,82,219,82,230,128,202,119,5,205,180,4, + 195,156,5,219,82,230,16,202,156,5,13,32, + 229,16,225,42,193,10,237,91,195,10,205,252, + 3,48,7,61,202,156,5,195,197,5,221,225, + 33,0,0,201,221,33,163,10,205,93,6,58, + 188,10,61,50,188,10,40,19,58,186,10,246, + 1,50,186,10,58,183,10,246,1,50,183,10, + 195,46,5,221,225,33,1,0,201,221,33,167, + 10,205,93,6,58,184,10,246,1,50,184,10, + 58,186,10,135,246,1,50,186,10,58,187,10, + 61,50,187,10,194,46,5,221,225,33,2,0, + 201,221,229,33,0,0,57,17,4,0,25,126, + 50,154,10,230,128,50,189,10,58,189,10,183, + 40,6,221,33,88,2,24,4,221,33,150,0, + 58,154,10,183,40,49,60,40,46,61,33,190, + 10,119,35,119,35,54,129,175,50,158,10,221, + 43,221,229,225,124,181,40,42,33,190,10,17, + 3,0,205,206,4,17,232,3,27,123,178,32, + 251,58,158,10,183,40,224,58,154,10,71,62, + 7,128,230,127,71,58,189,10,176,50,154,10, + 24,166,221,225,201,183,221,52,0,192,221,52, + 1,192,221,52,2,192,221,52,3,192,55,201, + 6,8,14,0,31,48,1,12,16,250,121,201, + 33,2,0,57,94,35,86,35,78,35,70,35, + 126,35,102,105,79,120,68,103,237,176,201,33, + 2,0,57,126,35,102,111,62,17,237,57,48, + 125,237,57,40,124,237,57,41,62,0,237,57, + 42,62,64,237,57,43,62,0,237,57,44,33, + 128,2,125,237,57,46,124,237,57,47,62,145, + 237,57,48,211,68,58,149,10,211,66,201,33, + 2,0,57,126,35,102,111,62,33,237,57,48, + 62,64,237,57,32,62,0,237,57,33,237,57, + 34,125,237,57,35,124,237,57,36,62,0,237, + 57,37,33,128,2,125,237,57,38,124,237,57, + 39,62,97,237,57,48,211,67,58,149,10,211, + 66,201,237,56,46,95,237,56,47,87,237,56, + 46,111,237,56,47,103,183,237,82,32,235,33, + 128,2,183,237,82,201,237,56,38,95,237,56, + 39,87,237,56,38,111,237,56,39,103,183,237, + 82,32,235,33,128,2,183,237,82,201,205,106, + 10,221,110,6,221,102,7,126,35,110,103,195, + 118,10,205,106,10,33,0,0,34,205,10,34, + 198,10,34,200,10,33,143,15,34,207,10,237, + 91,207,10,42,146,10,183,237,82,17,0,255, + 25,34,203,10,203,124,40,6,33,0,125,34, + 203,10,42,207,10,229,205,37,3,195,118,10, + 205,106,10,229,42,150,10,35,35,35,229,205, + 70,7,193,124,230,3,103,221,117,254,221,116, + 255,237,91,152,10,35,35,35,183,237,82,32, + 12,17,5,0,42,152,10,205,91,10,242,203, + 7,42,150,10,229,205,37,3,195,118,10,237, + 91,152,10,42,200,10,25,34,200,10,42,205, + 10,25,34,205,10,237,91,203,10,33,158,253, + 25,237,91,205,10,205,91,10,242,245,7,33, + 0,0,34,205,10,62,1,50,197,10,205,5, + 8,33,0,0,57,249,195,118,10,205,106,10, + 58,197,10,183,202,118,10,237,91,198,10,42, + 205,10,205,91,10,242,46,8,237,91,205,10, + 33,98,2,25,237,91,198,10,205,91,10,250, + 78,8,237,91,198,10,42,205,10,183,237,82, + 32,7,42,200,10,125,180,40,13,237,91,205, + 10,42,198,10,205,91,10,242,97,8,237,91, + 207,10,42,205,10,25,229,205,37,3,175,50, + 197,10,195,118,10,205,29,3,33,0,0,57, + 249,195,118,10,205,106,10,58,202,10,183,40, + 22,205,14,7,237,91,209,10,19,19,19,205, + 91,10,242,139,8,33,1,0,195,118,10,33, + 0,0,195,118,10,205,126,10,252,255,205,108, + 8,125,180,194,118,10,237,91,200,10,33,0, + 0,205,91,10,242,118,10,237,91,207,10,42, + 198,10,25,221,117,254,221,116,255,35,35,35, + 229,205,70,7,193,124,230,3,103,35,35,35, + 221,117,252,221,116,253,229,221,110,254,221,102, + 255,229,33,212,10,229,205,124,6,193,193,221, + 110,252,221,102,253,34,209,10,33,211,10,54, + 4,33,209,10,227,205,147,6,193,62,1,50, + 202,10,243,221,94,252,221,86,253,42,200,10, + 183,237,82,34,200,10,203,124,40,17,33,0, + 0,34,200,10,34,205,10,34,198,10,50,197, + 10,24,37,221,94,252,221,86,253,42,198,10, + 25,34,198,10,237,91,203,10,33,158,253,25, + 237,91,198,10,205,91,10,242,68,9,33,0, + 0,34,198,10,205,5,8,33,0,0,57,249, + 251,195,118,10,205,106,10,33,49,13,126,183, + 40,16,205,42,7,237,91,47,13,19,19,19, + 205,91,10,242,117,9,58,142,15,198,1,50, + 142,15,195,118,10,33,49,13,126,254,1,40, + 25,254,3,202,7,10,254,5,202,21,10,33, + 49,13,54,0,33,47,13,229,205,207,6,195, + 118,10,58,141,15,183,32,72,33,51,13,126, + 50,149,10,205,86,7,33,50,13,126,230,127, + 183,32,40,58,142,15,230,127,50,142,15,183, + 32,5,198,1,50,142,15,33,50,13,126,111, + 23,159,103,203,125,58,142,15,40,5,198,128, + 50,142,15,33,50,13,119,33,50,13,126,111, + 23,159,103,229,205,237,5,193,33,211,10,54, + 2,33,2,0,34,209,10,58,154,10,33,212, + 10,119,58,148,10,33,213,10,119,33,209,10, + 229,205,147,6,193,24,128,42,47,13,229,33, + 50,13,229,205,191,4,193,24,239,33,211,10, + 54,6,33,3,0,34,209,10,58,154,10,33, + 212,10,119,58,148,10,33,213,10,119,33,214, + 10,54,5,33,209,10,229,205,147,6,24,200, + 205,106,10,33,49,13,54,0,33,47,13,229, + 205,207,6,33,209,10,227,205,147,6,193,205, + 80,9,205,145,8,24,248,124,170,250,99,10, + 237,82,201,124,230,128,237,82,60,201,225,253, + 229,221,229,221,33,0,0,221,57,233,221,249, + 221,225,253,225,201,233,225,253,229,221,229,221, + 33,0,0,221,57,94,35,86,35,235,57,249, + 235,233,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0 + } ; + +#endif diff --git a/drivers/staging/appletalk/ddp.c b/drivers/staging/appletalk/ddp.c new file mode 100644 index 000000000000..940dd1908339 --- /dev/null +++ b/drivers/staging/appletalk/ddp.c @@ -0,0 +1,1981 @@ +/* + * DDP: An implementation of the AppleTalk DDP protocol for + * Ethernet 'ELAP'. + * + * Alan Cox + * + * With more than a little assistance from + * + * Wesley Craig + * + * Fixes: + * Neil Horman : Added missing device ioctls + * Michael Callahan : Made routing work + * Wesley Craig : Fix probing to listen to a + * passed node id. + * Alan Cox : Added send/recvmsg support + * Alan Cox : Moved at. to protinfo in + * socket. + * Alan Cox : Added firewall hooks. + * Alan Cox : Supports new ARPHRD_LOOPBACK + * Christer Weinigel : Routing and /proc fixes. + * Bradford Johnson : LocalTalk. + * Tom Dyas : Module support. + * Alan Cox : Hooks for PPP (based on the + * LocalTalk hook). + * Alan Cox : Posix bits + * Alan Cox/Mike Freeman : Possible fix to NBP problems + * Bradford Johnson : IP-over-DDP (experimental) + * Jay Schulist : Moved IP-over-DDP to its own + * driver file. (ipddp.c & ipddp.h) + * Jay Schulist : Made work as module with + * AppleTalk drivers, cleaned it. + * Rob Newberry : Added proxy AARP and AARP + * procfs, moved probing to AARP + * module. + * Adrian Sun/ + * Michael Zuelsdorff : fix for net.0 packets. don't + * allow illegal ether/tokentalk + * port assignment. we lose a + * valid localtalk port as a + * result. + * Arnaldo C. de Melo : Cleanup, in preparation for + * shared skb support 8) + * Arnaldo C. de Melo : Move proc stuff to atalk_proc.c, + * use seq_file + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include /* For TIOCOUTQ/INQ */ +#include +#include +#include +#include +#include +#include +#include +#include "atalk.h" +#include "../../net/core/kmap_skb.h" + +struct datalink_proto *ddp_dl, *aarp_dl; +static const struct proto_ops atalk_dgram_ops; + +/**************************************************************************\ +* * +* Handlers for the socket list. * +* * +\**************************************************************************/ + +HLIST_HEAD(atalk_sockets); +DEFINE_RWLOCK(atalk_sockets_lock); + +static inline void __atalk_insert_socket(struct sock *sk) +{ + sk_add_node(sk, &atalk_sockets); +} + +static inline void atalk_remove_socket(struct sock *sk) +{ + write_lock_bh(&atalk_sockets_lock); + sk_del_node_init(sk); + write_unlock_bh(&atalk_sockets_lock); +} + +static struct sock *atalk_search_socket(struct sockaddr_at *to, + struct atalk_iface *atif) +{ + struct sock *s; + struct hlist_node *node; + + read_lock_bh(&atalk_sockets_lock); + sk_for_each(s, node, &atalk_sockets) { + struct atalk_sock *at = at_sk(s); + + if (to->sat_port != at->src_port) + continue; + + if (to->sat_addr.s_net == ATADDR_ANYNET && + to->sat_addr.s_node == ATADDR_BCAST) + goto found; + + if (to->sat_addr.s_net == at->src_net && + (to->sat_addr.s_node == at->src_node || + to->sat_addr.s_node == ATADDR_BCAST || + to->sat_addr.s_node == ATADDR_ANYNODE)) + goto found; + + /* XXXX.0 -- we got a request for this router. make sure + * that the node is appropriately set. */ + if (to->sat_addr.s_node == ATADDR_ANYNODE && + to->sat_addr.s_net != ATADDR_ANYNET && + atif->address.s_node == at->src_node) { + to->sat_addr.s_node = atif->address.s_node; + goto found; + } + } + s = NULL; +found: + read_unlock_bh(&atalk_sockets_lock); + return s; +} + +/** + * atalk_find_or_insert_socket - Try to find a socket matching ADDR + * @sk - socket to insert in the list if it is not there already + * @sat - address to search for + * + * Try to find a socket matching ADDR in the socket list, if found then return + * it. If not, insert SK into the socket list. + * + * This entire operation must execute atomically. + */ +static struct sock *atalk_find_or_insert_socket(struct sock *sk, + struct sockaddr_at *sat) +{ + struct sock *s; + struct hlist_node *node; + struct atalk_sock *at; + + write_lock_bh(&atalk_sockets_lock); + sk_for_each(s, node, &atalk_sockets) { + at = at_sk(s); + + if (at->src_net == sat->sat_addr.s_net && + at->src_node == sat->sat_addr.s_node && + at->src_port == sat->sat_port) + goto found; + } + s = NULL; + __atalk_insert_socket(sk); /* Wheee, it's free, assign and insert. */ +found: + write_unlock_bh(&atalk_sockets_lock); + return s; +} + +static void atalk_destroy_timer(unsigned long data) +{ + struct sock *sk = (struct sock *)data; + + if (sk_has_allocations(sk)) { + sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; + add_timer(&sk->sk_timer); + } else + sock_put(sk); +} + +static inline void atalk_destroy_socket(struct sock *sk) +{ + atalk_remove_socket(sk); + skb_queue_purge(&sk->sk_receive_queue); + + if (sk_has_allocations(sk)) { + setup_timer(&sk->sk_timer, atalk_destroy_timer, + (unsigned long)sk); + sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; + add_timer(&sk->sk_timer); + } else + sock_put(sk); +} + +/**************************************************************************\ +* * +* Routing tables for the AppleTalk socket layer. * +* * +\**************************************************************************/ + +/* Anti-deadlock ordering is atalk_routes_lock --> iface_lock -DaveM */ +struct atalk_route *atalk_routes; +DEFINE_RWLOCK(atalk_routes_lock); + +struct atalk_iface *atalk_interfaces; +DEFINE_RWLOCK(atalk_interfaces_lock); + +/* For probing devices or in a routerless network */ +struct atalk_route atrtr_default; + +/* AppleTalk interface control */ +/* + * Drop a device. Doesn't drop any of its routes - that is the caller's + * problem. Called when we down the interface or delete the address. + */ +static void atif_drop_device(struct net_device *dev) +{ + struct atalk_iface **iface = &atalk_interfaces; + struct atalk_iface *tmp; + + write_lock_bh(&atalk_interfaces_lock); + while ((tmp = *iface) != NULL) { + if (tmp->dev == dev) { + *iface = tmp->next; + dev_put(dev); + kfree(tmp); + dev->atalk_ptr = NULL; + } else + iface = &tmp->next; + } + write_unlock_bh(&atalk_interfaces_lock); +} + +static struct atalk_iface *atif_add_device(struct net_device *dev, + struct atalk_addr *sa) +{ + struct atalk_iface *iface = kzalloc(sizeof(*iface), GFP_KERNEL); + + if (!iface) + goto out; + + dev_hold(dev); + iface->dev = dev; + dev->atalk_ptr = iface; + iface->address = *sa; + iface->status = 0; + + write_lock_bh(&atalk_interfaces_lock); + iface->next = atalk_interfaces; + atalk_interfaces = iface; + write_unlock_bh(&atalk_interfaces_lock); +out: + return iface; +} + +/* Perform phase 2 AARP probing on our tentative address */ +static int atif_probe_device(struct atalk_iface *atif) +{ + int netrange = ntohs(atif->nets.nr_lastnet) - + ntohs(atif->nets.nr_firstnet) + 1; + int probe_net = ntohs(atif->address.s_net); + int probe_node = atif->address.s_node; + int netct, nodect; + + /* Offset the network we start probing with */ + if (probe_net == ATADDR_ANYNET) { + probe_net = ntohs(atif->nets.nr_firstnet); + if (netrange) + probe_net += jiffies % netrange; + } + if (probe_node == ATADDR_ANYNODE) + probe_node = jiffies & 0xFF; + + /* Scan the networks */ + atif->status |= ATIF_PROBE; + for (netct = 0; netct <= netrange; netct++) { + /* Sweep the available nodes from a given start */ + atif->address.s_net = htons(probe_net); + for (nodect = 0; nodect < 256; nodect++) { + atif->address.s_node = (nodect + probe_node) & 0xFF; + if (atif->address.s_node > 0 && + atif->address.s_node < 254) { + /* Probe a proposed address */ + aarp_probe_network(atif); + + if (!(atif->status & ATIF_PROBE_FAIL)) { + atif->status &= ~ATIF_PROBE; + return 0; + } + } + atif->status &= ~ATIF_PROBE_FAIL; + } + probe_net++; + if (probe_net > ntohs(atif->nets.nr_lastnet)) + probe_net = ntohs(atif->nets.nr_firstnet); + } + atif->status &= ~ATIF_PROBE; + + return -EADDRINUSE; /* Network is full... */ +} + + +/* Perform AARP probing for a proxy address */ +static int atif_proxy_probe_device(struct atalk_iface *atif, + struct atalk_addr* proxy_addr) +{ + int netrange = ntohs(atif->nets.nr_lastnet) - + ntohs(atif->nets.nr_firstnet) + 1; + /* we probe the interface's network */ + int probe_net = ntohs(atif->address.s_net); + int probe_node = ATADDR_ANYNODE; /* we'll take anything */ + int netct, nodect; + + /* Offset the network we start probing with */ + if (probe_net == ATADDR_ANYNET) { + probe_net = ntohs(atif->nets.nr_firstnet); + if (netrange) + probe_net += jiffies % netrange; + } + + if (probe_node == ATADDR_ANYNODE) + probe_node = jiffies & 0xFF; + + /* Scan the networks */ + for (netct = 0; netct <= netrange; netct++) { + /* Sweep the available nodes from a given start */ + proxy_addr->s_net = htons(probe_net); + for (nodect = 0; nodect < 256; nodect++) { + proxy_addr->s_node = (nodect + probe_node) & 0xFF; + if (proxy_addr->s_node > 0 && + proxy_addr->s_node < 254) { + /* Tell AARP to probe a proposed address */ + int ret = aarp_proxy_probe_network(atif, + proxy_addr); + + if (ret != -EADDRINUSE) + return ret; + } + } + probe_net++; + if (probe_net > ntohs(atif->nets.nr_lastnet)) + probe_net = ntohs(atif->nets.nr_firstnet); + } + + return -EADDRINUSE; /* Network is full... */ +} + + +struct atalk_addr *atalk_find_dev_addr(struct net_device *dev) +{ + struct atalk_iface *iface = dev->atalk_ptr; + return iface ? &iface->address : NULL; +} + +static struct atalk_addr *atalk_find_primary(void) +{ + struct atalk_iface *fiface = NULL; + struct atalk_addr *retval; + struct atalk_iface *iface; + + /* + * Return a point-to-point interface only if + * there is no non-ptp interface available. + */ + read_lock_bh(&atalk_interfaces_lock); + for (iface = atalk_interfaces; iface; iface = iface->next) { + if (!fiface && !(iface->dev->flags & IFF_LOOPBACK)) + fiface = iface; + if (!(iface->dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) { + retval = &iface->address; + goto out; + } + } + + if (fiface) + retval = &fiface->address; + else if (atalk_interfaces) + retval = &atalk_interfaces->address; + else + retval = NULL; +out: + read_unlock_bh(&atalk_interfaces_lock); + return retval; +} + +/* + * Find a match for 'any network' - ie any of our interfaces with that + * node number will do just nicely. + */ +static struct atalk_iface *atalk_find_anynet(int node, struct net_device *dev) +{ + struct atalk_iface *iface = dev->atalk_ptr; + + if (!iface || iface->status & ATIF_PROBE) + goto out_err; + + if (node != ATADDR_BCAST && + iface->address.s_node != node && + node != ATADDR_ANYNODE) + goto out_err; +out: + return iface; +out_err: + iface = NULL; + goto out; +} + +/* Find a match for a specific network:node pair */ +static struct atalk_iface *atalk_find_interface(__be16 net, int node) +{ + struct atalk_iface *iface; + + read_lock_bh(&atalk_interfaces_lock); + for (iface = atalk_interfaces; iface; iface = iface->next) { + if ((node == ATADDR_BCAST || + node == ATADDR_ANYNODE || + iface->address.s_node == node) && + iface->address.s_net == net && + !(iface->status & ATIF_PROBE)) + break; + + /* XXXX.0 -- net.0 returns the iface associated with net */ + if (node == ATADDR_ANYNODE && net != ATADDR_ANYNET && + ntohs(iface->nets.nr_firstnet) <= ntohs(net) && + ntohs(net) <= ntohs(iface->nets.nr_lastnet)) + break; + } + read_unlock_bh(&atalk_interfaces_lock); + return iface; +} + + +/* + * Find a route for an AppleTalk packet. This ought to get cached in + * the socket (later on...). We know about host routes and the fact + * that a route must be direct to broadcast. + */ +static struct atalk_route *atrtr_find(struct atalk_addr *target) +{ + /* + * we must search through all routes unless we find a + * host route, because some host routes might overlap + * network routes + */ + struct atalk_route *net_route = NULL; + struct atalk_route *r; + + read_lock_bh(&atalk_routes_lock); + for (r = atalk_routes; r; r = r->next) { + if (!(r->flags & RTF_UP)) + continue; + + if (r->target.s_net == target->s_net) { + if (r->flags & RTF_HOST) { + /* + * if this host route is for the target, + * the we're done + */ + if (r->target.s_node == target->s_node) + goto out; + } else + /* + * this route will work if there isn't a + * direct host route, so cache it + */ + net_route = r; + } + } + + /* + * if we found a network route but not a direct host + * route, then return it + */ + if (net_route) + r = net_route; + else if (atrtr_default.dev) + r = &atrtr_default; + else /* No route can be found */ + r = NULL; +out: + read_unlock_bh(&atalk_routes_lock); + return r; +} + + +/* + * Given an AppleTalk network, find the device to use. This can be + * a simple lookup. + */ +struct net_device *atrtr_get_dev(struct atalk_addr *sa) +{ + struct atalk_route *atr = atrtr_find(sa); + return atr ? atr->dev : NULL; +} + +/* Set up a default router */ +static void atrtr_set_default(struct net_device *dev) +{ + atrtr_default.dev = dev; + atrtr_default.flags = RTF_UP; + atrtr_default.gateway.s_net = htons(0); + atrtr_default.gateway.s_node = 0; +} + +/* + * Add a router. Basically make sure it looks valid and stuff the + * entry in the list. While it uses netranges we always set them to one + * entry to work like netatalk. + */ +static int atrtr_create(struct rtentry *r, struct net_device *devhint) +{ + struct sockaddr_at *ta = (struct sockaddr_at *)&r->rt_dst; + struct sockaddr_at *ga = (struct sockaddr_at *)&r->rt_gateway; + struct atalk_route *rt; + struct atalk_iface *iface, *riface; + int retval = -EINVAL; + + /* + * Fixme: Raise/Lower a routing change semaphore for these + * operations. + */ + + /* Validate the request */ + if (ta->sat_family != AF_APPLETALK || + (!devhint && ga->sat_family != AF_APPLETALK)) + goto out; + + /* Now walk the routing table and make our decisions */ + write_lock_bh(&atalk_routes_lock); + for (rt = atalk_routes; rt; rt = rt->next) { + if (r->rt_flags != rt->flags) + continue; + + if (ta->sat_addr.s_net == rt->target.s_net) { + if (!(rt->flags & RTF_HOST)) + break; + if (ta->sat_addr.s_node == rt->target.s_node) + break; + } + } + + if (!devhint) { + riface = NULL; + + read_lock_bh(&atalk_interfaces_lock); + for (iface = atalk_interfaces; iface; iface = iface->next) { + if (!riface && + ntohs(ga->sat_addr.s_net) >= + ntohs(iface->nets.nr_firstnet) && + ntohs(ga->sat_addr.s_net) <= + ntohs(iface->nets.nr_lastnet)) + riface = iface; + + if (ga->sat_addr.s_net == iface->address.s_net && + ga->sat_addr.s_node == iface->address.s_node) + riface = iface; + } + read_unlock_bh(&atalk_interfaces_lock); + + retval = -ENETUNREACH; + if (!riface) + goto out_unlock; + + devhint = riface->dev; + } + + if (!rt) { + rt = kzalloc(sizeof(*rt), GFP_ATOMIC); + + retval = -ENOBUFS; + if (!rt) + goto out_unlock; + + rt->next = atalk_routes; + atalk_routes = rt; + } + + /* Fill in the routing entry */ + rt->target = ta->sat_addr; + dev_hold(devhint); + rt->dev = devhint; + rt->flags = r->rt_flags; + rt->gateway = ga->sat_addr; + + retval = 0; +out_unlock: + write_unlock_bh(&atalk_routes_lock); +out: + return retval; +} + +/* Delete a route. Find it and discard it */ +static int atrtr_delete(struct atalk_addr * addr) +{ + struct atalk_route **r = &atalk_routes; + int retval = 0; + struct atalk_route *tmp; + + write_lock_bh(&atalk_routes_lock); + while ((tmp = *r) != NULL) { + if (tmp->target.s_net == addr->s_net && + (!(tmp->flags&RTF_GATEWAY) || + tmp->target.s_node == addr->s_node)) { + *r = tmp->next; + dev_put(tmp->dev); + kfree(tmp); + goto out; + } + r = &tmp->next; + } + retval = -ENOENT; +out: + write_unlock_bh(&atalk_routes_lock); + return retval; +} + +/* + * Called when a device is downed. Just throw away any routes + * via it. + */ +static void atrtr_device_down(struct net_device *dev) +{ + struct atalk_route **r = &atalk_routes; + struct atalk_route *tmp; + + write_lock_bh(&atalk_routes_lock); + while ((tmp = *r) != NULL) { + if (tmp->dev == dev) { + *r = tmp->next; + dev_put(dev); + kfree(tmp); + } else + r = &tmp->next; + } + write_unlock_bh(&atalk_routes_lock); + + if (atrtr_default.dev == dev) + atrtr_set_default(NULL); +} + +/* Actually down the interface */ +static inline void atalk_dev_down(struct net_device *dev) +{ + atrtr_device_down(dev); /* Remove all routes for the device */ + aarp_device_down(dev); /* Remove AARP entries for the device */ + atif_drop_device(dev); /* Remove the device */ +} + +/* + * A device event has occurred. Watch for devices going down and + * delete our use of them (iface and route). + */ +static int ddp_device_event(struct notifier_block *this, unsigned long event, + void *ptr) +{ + struct net_device *dev = ptr; + + if (!net_eq(dev_net(dev), &init_net)) + return NOTIFY_DONE; + + if (event == NETDEV_DOWN) + /* Discard any use of this */ + atalk_dev_down(dev); + + return NOTIFY_DONE; +} + +/* ioctl calls. Shouldn't even need touching */ +/* Device configuration ioctl calls */ +static int atif_ioctl(int cmd, void __user *arg) +{ + static char aarp_mcast[6] = { 0x09, 0x00, 0x00, 0xFF, 0xFF, 0xFF }; + struct ifreq atreq; + struct atalk_netrange *nr; + struct sockaddr_at *sa; + struct net_device *dev; + struct atalk_iface *atif; + int ct; + int limit; + struct rtentry rtdef; + int add_route; + + if (copy_from_user(&atreq, arg, sizeof(atreq))) + return -EFAULT; + + dev = __dev_get_by_name(&init_net, atreq.ifr_name); + if (!dev) + return -ENODEV; + + sa = (struct sockaddr_at *)&atreq.ifr_addr; + atif = atalk_find_dev(dev); + + switch (cmd) { + case SIOCSIFADDR: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (sa->sat_family != AF_APPLETALK) + return -EINVAL; + if (dev->type != ARPHRD_ETHER && + dev->type != ARPHRD_LOOPBACK && + dev->type != ARPHRD_LOCALTLK && + dev->type != ARPHRD_PPP) + return -EPROTONOSUPPORT; + + nr = (struct atalk_netrange *)&sa->sat_zero[0]; + add_route = 1; + + /* + * if this is a point-to-point iface, and we already + * have an iface for this AppleTalk address, then we + * should not add a route + */ + if ((dev->flags & IFF_POINTOPOINT) && + atalk_find_interface(sa->sat_addr.s_net, + sa->sat_addr.s_node)) { + printk(KERN_DEBUG "AppleTalk: point-to-point " + "interface added with " + "existing address\n"); + add_route = 0; + } + + /* + * Phase 1 is fine on LocalTalk but we don't do + * EtherTalk phase 1. Anyone wanting to add it go ahead. + */ + if (dev->type == ARPHRD_ETHER && nr->nr_phase != 2) + return -EPROTONOSUPPORT; + if (sa->sat_addr.s_node == ATADDR_BCAST || + sa->sat_addr.s_node == 254) + return -EINVAL; + if (atif) { + /* Already setting address */ + if (atif->status & ATIF_PROBE) + return -EBUSY; + + atif->address.s_net = sa->sat_addr.s_net; + atif->address.s_node = sa->sat_addr.s_node; + atrtr_device_down(dev); /* Flush old routes */ + } else { + atif = atif_add_device(dev, &sa->sat_addr); + if (!atif) + return -ENOMEM; + } + atif->nets = *nr; + + /* + * Check if the chosen address is used. If so we + * error and atalkd will try another. + */ + + if (!(dev->flags & IFF_LOOPBACK) && + !(dev->flags & IFF_POINTOPOINT) && + atif_probe_device(atif) < 0) { + atif_drop_device(dev); + return -EADDRINUSE; + } + + /* Hey it worked - add the direct routes */ + sa = (struct sockaddr_at *)&rtdef.rt_gateway; + sa->sat_family = AF_APPLETALK; + sa->sat_addr.s_net = atif->address.s_net; + sa->sat_addr.s_node = atif->address.s_node; + sa = (struct sockaddr_at *)&rtdef.rt_dst; + rtdef.rt_flags = RTF_UP; + sa->sat_family = AF_APPLETALK; + sa->sat_addr.s_node = ATADDR_ANYNODE; + if (dev->flags & IFF_LOOPBACK || + dev->flags & IFF_POINTOPOINT) + rtdef.rt_flags |= RTF_HOST; + + /* Routerless initial state */ + if (nr->nr_firstnet == htons(0) && + nr->nr_lastnet == htons(0xFFFE)) { + sa->sat_addr.s_net = atif->address.s_net; + atrtr_create(&rtdef, dev); + atrtr_set_default(dev); + } else { + limit = ntohs(nr->nr_lastnet); + if (limit - ntohs(nr->nr_firstnet) > 4096) { + printk(KERN_WARNING "Too many routes/" + "iface.\n"); + return -EINVAL; + } + if (add_route) + for (ct = ntohs(nr->nr_firstnet); + ct <= limit; ct++) { + sa->sat_addr.s_net = htons(ct); + atrtr_create(&rtdef, dev); + } + } + dev_mc_add_global(dev, aarp_mcast); + return 0; + + case SIOCGIFADDR: + if (!atif) + return -EADDRNOTAVAIL; + + sa->sat_family = AF_APPLETALK; + sa->sat_addr = atif->address; + break; + + case SIOCGIFBRDADDR: + if (!atif) + return -EADDRNOTAVAIL; + + sa->sat_family = AF_APPLETALK; + sa->sat_addr.s_net = atif->address.s_net; + sa->sat_addr.s_node = ATADDR_BCAST; + break; + + case SIOCATALKDIFADDR: + case SIOCDIFADDR: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (sa->sat_family != AF_APPLETALK) + return -EINVAL; + atalk_dev_down(dev); + break; + + case SIOCSARP: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (sa->sat_family != AF_APPLETALK) + return -EINVAL; + /* + * for now, we only support proxy AARP on ELAP; + * we should be able to do it for LocalTalk, too. + */ + if (dev->type != ARPHRD_ETHER) + return -EPROTONOSUPPORT; + + /* + * atif points to the current interface on this network; + * we aren't concerned about its current status (at + * least for now), but it has all the settings about + * the network we're going to probe. Consequently, it + * must exist. + */ + if (!atif) + return -EADDRNOTAVAIL; + + nr = (struct atalk_netrange *)&(atif->nets); + /* + * Phase 1 is fine on Localtalk but we don't do + * Ethertalk phase 1. Anyone wanting to add it go ahead. + */ + if (dev->type == ARPHRD_ETHER && nr->nr_phase != 2) + return -EPROTONOSUPPORT; + + if (sa->sat_addr.s_node == ATADDR_BCAST || + sa->sat_addr.s_node == 254) + return -EINVAL; + + /* + * Check if the chosen address is used. If so we + * error and ATCP will try another. + */ + if (atif_proxy_probe_device(atif, &(sa->sat_addr)) < 0) + return -EADDRINUSE; + + /* + * We now have an address on the local network, and + * the AARP code will defend it for us until we take it + * down. We don't set up any routes right now, because + * ATCP will install them manually via SIOCADDRT. + */ + break; + + case SIOCDARP: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (sa->sat_family != AF_APPLETALK) + return -EINVAL; + if (!atif) + return -EADDRNOTAVAIL; + + /* give to aarp module to remove proxy entry */ + aarp_proxy_remove(atif->dev, &(sa->sat_addr)); + return 0; + } + + return copy_to_user(arg, &atreq, sizeof(atreq)) ? -EFAULT : 0; +} + +/* Routing ioctl() calls */ +static int atrtr_ioctl(unsigned int cmd, void __user *arg) +{ + struct rtentry rt; + + if (copy_from_user(&rt, arg, sizeof(rt))) + return -EFAULT; + + switch (cmd) { + case SIOCDELRT: + if (rt.rt_dst.sa_family != AF_APPLETALK) + return -EINVAL; + return atrtr_delete(&((struct sockaddr_at *) + &rt.rt_dst)->sat_addr); + + case SIOCADDRT: { + struct net_device *dev = NULL; + if (rt.rt_dev) { + char name[IFNAMSIZ]; + if (copy_from_user(name, rt.rt_dev, IFNAMSIZ-1)) + return -EFAULT; + name[IFNAMSIZ-1] = '\0'; + dev = __dev_get_by_name(&init_net, name); + if (!dev) + return -ENODEV; + } + return atrtr_create(&rt, dev); + } + } + return -EINVAL; +} + +/**************************************************************************\ +* * +* Handling for system calls applied via the various interfaces to an * +* AppleTalk socket object. * +* * +\**************************************************************************/ + +/* + * Checksum: This is 'optional'. It's quite likely also a good + * candidate for assembler hackery 8) + */ +static unsigned long atalk_sum_partial(const unsigned char *data, + int len, unsigned long sum) +{ + /* This ought to be unwrapped neatly. I'll trust gcc for now */ + while (len--) { + sum += *data++; + sum = rol16(sum, 1); + } + return sum; +} + +/* Checksum skb data -- similar to skb_checksum */ +static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, + int len, unsigned long sum) +{ + int start = skb_headlen(skb); + struct sk_buff *frag_iter; + int i, copy; + + /* checksum stuff in header space */ + if ( (copy = start - offset) > 0) { + if (copy > len) + copy = len; + sum = atalk_sum_partial(skb->data + offset, copy, sum); + if ( (len -= copy) == 0) + return sum; + + offset += copy; + } + + /* checksum stuff in frags */ + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + int end; + + WARN_ON(start > offset + len); + + end = start + skb_shinfo(skb)->frags[i].size; + if ((copy = end - offset) > 0) { + u8 *vaddr; + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + if (copy > len) + copy = len; + vaddr = kmap_skb_frag(frag); + sum = atalk_sum_partial(vaddr + frag->page_offset + + offset - start, copy, sum); + kunmap_skb_frag(vaddr); + + if (!(len -= copy)) + return sum; + offset += copy; + } + start = end; + } + + skb_walk_frags(skb, frag_iter) { + int end; + + WARN_ON(start > offset + len); + + end = start + frag_iter->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + sum = atalk_sum_skb(frag_iter, offset - start, + copy, sum); + if ((len -= copy) == 0) + return sum; + offset += copy; + } + start = end; + } + + BUG_ON(len > 0); + + return sum; +} + +static __be16 atalk_checksum(const struct sk_buff *skb, int len) +{ + unsigned long sum; + + /* skip header 4 bytes */ + sum = atalk_sum_skb(skb, 4, len-4, 0); + + /* Use 0xFFFF for 0. 0 itself means none */ + return sum ? htons((unsigned short)sum) : htons(0xFFFF); +} + +static struct proto ddp_proto = { + .name = "DDP", + .owner = THIS_MODULE, + .obj_size = sizeof(struct atalk_sock), +}; + +/* + * Create a socket. Initialise the socket, blank the addresses + * set the state. + */ +static int atalk_create(struct net *net, struct socket *sock, int protocol, + int kern) +{ + struct sock *sk; + int rc = -ESOCKTNOSUPPORT; + + if (!net_eq(net, &init_net)) + return -EAFNOSUPPORT; + + /* + * We permit SOCK_DGRAM and RAW is an extension. It is trivial to do + * and gives you the full ELAP frame. Should be handy for CAP 8) + */ + if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM) + goto out; + rc = -ENOMEM; + sk = sk_alloc(net, PF_APPLETALK, GFP_KERNEL, &ddp_proto); + if (!sk) + goto out; + rc = 0; + sock->ops = &atalk_dgram_ops; + sock_init_data(sock, sk); + + /* Checksums on by default */ + sock_set_flag(sk, SOCK_ZAPPED); +out: + return rc; +} + +/* Free a socket. No work needed */ +static int atalk_release(struct socket *sock) +{ + struct sock *sk = sock->sk; + + lock_kernel(); + if (sk) { + sock_orphan(sk); + sock->sk = NULL; + atalk_destroy_socket(sk); + } + unlock_kernel(); + return 0; +} + +/** + * atalk_pick_and_bind_port - Pick a source port when one is not given + * @sk - socket to insert into the tables + * @sat - address to search for + * + * Pick a source port when one is not given. If we can find a suitable free + * one, we insert the socket into the tables using it. + * + * This whole operation must be atomic. + */ +static int atalk_pick_and_bind_port(struct sock *sk, struct sockaddr_at *sat) +{ + int retval; + + write_lock_bh(&atalk_sockets_lock); + + for (sat->sat_port = ATPORT_RESERVED; + sat->sat_port < ATPORT_LAST; + sat->sat_port++) { + struct sock *s; + struct hlist_node *node; + + sk_for_each(s, node, &atalk_sockets) { + struct atalk_sock *at = at_sk(s); + + if (at->src_net == sat->sat_addr.s_net && + at->src_node == sat->sat_addr.s_node && + at->src_port == sat->sat_port) + goto try_next_port; + } + + /* Wheee, it's free, assign and insert. */ + __atalk_insert_socket(sk); + at_sk(sk)->src_port = sat->sat_port; + retval = 0; + goto out; + +try_next_port:; + } + + retval = -EBUSY; +out: + write_unlock_bh(&atalk_sockets_lock); + return retval; +} + +static int atalk_autobind(struct sock *sk) +{ + struct atalk_sock *at = at_sk(sk); + struct sockaddr_at sat; + struct atalk_addr *ap = atalk_find_primary(); + int n = -EADDRNOTAVAIL; + + if (!ap || ap->s_net == htons(ATADDR_ANYNET)) + goto out; + + at->src_net = sat.sat_addr.s_net = ap->s_net; + at->src_node = sat.sat_addr.s_node = ap->s_node; + + n = atalk_pick_and_bind_port(sk, &sat); + if (!n) + sock_reset_flag(sk, SOCK_ZAPPED); +out: + return n; +} + +/* Set the address 'our end' of the connection */ +static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) +{ + struct sockaddr_at *addr = (struct sockaddr_at *)uaddr; + struct sock *sk = sock->sk; + struct atalk_sock *at = at_sk(sk); + int err; + + if (!sock_flag(sk, SOCK_ZAPPED) || + addr_len != sizeof(struct sockaddr_at)) + return -EINVAL; + + if (addr->sat_family != AF_APPLETALK) + return -EAFNOSUPPORT; + + lock_kernel(); + if (addr->sat_addr.s_net == htons(ATADDR_ANYNET)) { + struct atalk_addr *ap = atalk_find_primary(); + + err = -EADDRNOTAVAIL; + if (!ap) + goto out; + + at->src_net = addr->sat_addr.s_net = ap->s_net; + at->src_node = addr->sat_addr.s_node= ap->s_node; + } else { + err = -EADDRNOTAVAIL; + if (!atalk_find_interface(addr->sat_addr.s_net, + addr->sat_addr.s_node)) + goto out; + + at->src_net = addr->sat_addr.s_net; + at->src_node = addr->sat_addr.s_node; + } + + if (addr->sat_port == ATADDR_ANYPORT) { + err = atalk_pick_and_bind_port(sk, addr); + + if (err < 0) + goto out; + } else { + at->src_port = addr->sat_port; + + err = -EADDRINUSE; + if (atalk_find_or_insert_socket(sk, addr)) + goto out; + } + + sock_reset_flag(sk, SOCK_ZAPPED); + err = 0; +out: + unlock_kernel(); + return err; +} + +/* Set the address we talk to */ +static int atalk_connect(struct socket *sock, struct sockaddr *uaddr, + int addr_len, int flags) +{ + struct sock *sk = sock->sk; + struct atalk_sock *at = at_sk(sk); + struct sockaddr_at *addr; + int err; + + sk->sk_state = TCP_CLOSE; + sock->state = SS_UNCONNECTED; + + if (addr_len != sizeof(*addr)) + return -EINVAL; + + addr = (struct sockaddr_at *)uaddr; + + if (addr->sat_family != AF_APPLETALK) + return -EAFNOSUPPORT; + + if (addr->sat_addr.s_node == ATADDR_BCAST && + !sock_flag(sk, SOCK_BROADCAST)) { +#if 1 + printk(KERN_WARNING "%s is broken and did not set " + "SO_BROADCAST. It will break when 2.2 is " + "released.\n", + current->comm); +#else + return -EACCES; +#endif + } + + lock_kernel(); + err = -EBUSY; + if (sock_flag(sk, SOCK_ZAPPED)) + if (atalk_autobind(sk) < 0) + goto out; + + err = -ENETUNREACH; + if (!atrtr_get_dev(&addr->sat_addr)) + goto out; + + at->dest_port = addr->sat_port; + at->dest_net = addr->sat_addr.s_net; + at->dest_node = addr->sat_addr.s_node; + + sock->state = SS_CONNECTED; + sk->sk_state = TCP_ESTABLISHED; + err = 0; +out: + unlock_kernel(); + return err; +} + +/* + * Find the name of an AppleTalk socket. Just copy the right + * fields into the sockaddr. + */ +static int atalk_getname(struct socket *sock, struct sockaddr *uaddr, + int *uaddr_len, int peer) +{ + struct sockaddr_at sat; + struct sock *sk = sock->sk; + struct atalk_sock *at = at_sk(sk); + int err; + + lock_kernel(); + err = -ENOBUFS; + if (sock_flag(sk, SOCK_ZAPPED)) + if (atalk_autobind(sk) < 0) + goto out; + + *uaddr_len = sizeof(struct sockaddr_at); + memset(&sat.sat_zero, 0, sizeof(sat.sat_zero)); + + if (peer) { + err = -ENOTCONN; + if (sk->sk_state != TCP_ESTABLISHED) + goto out; + + sat.sat_addr.s_net = at->dest_net; + sat.sat_addr.s_node = at->dest_node; + sat.sat_port = at->dest_port; + } else { + sat.sat_addr.s_net = at->src_net; + sat.sat_addr.s_node = at->src_node; + sat.sat_port = at->src_port; + } + + err = 0; + sat.sat_family = AF_APPLETALK; + memcpy(uaddr, &sat, sizeof(sat)); + +out: + unlock_kernel(); + return err; +} + +static unsigned int atalk_poll(struct file *file, struct socket *sock, + poll_table *wait) +{ + int err; + lock_kernel(); + err = datagram_poll(file, sock, wait); + unlock_kernel(); + return err; +} + +#if defined(CONFIG_IPDDP) || defined(CONFIG_IPDDP_MODULE) +static __inline__ int is_ip_over_ddp(struct sk_buff *skb) +{ + return skb->data[12] == 22; +} + +static int handle_ip_over_ddp(struct sk_buff *skb) +{ + struct net_device *dev = __dev_get_by_name(&init_net, "ipddp0"); + struct net_device_stats *stats; + + /* This needs to be able to handle ipddp"N" devices */ + if (!dev) { + kfree_skb(skb); + return NET_RX_DROP; + } + + skb->protocol = htons(ETH_P_IP); + skb_pull(skb, 13); + skb->dev = dev; + skb_reset_transport_header(skb); + + stats = netdev_priv(dev); + stats->rx_packets++; + stats->rx_bytes += skb->len + 13; + return netif_rx(skb); /* Send the SKB up to a higher place. */ +} +#else +/* make it easy for gcc to optimize this test out, i.e. kill the code */ +#define is_ip_over_ddp(skb) 0 +#define handle_ip_over_ddp(skb) 0 +#endif + +static int atalk_route_packet(struct sk_buff *skb, struct net_device *dev, + struct ddpehdr *ddp, __u16 len_hops, int origlen) +{ + struct atalk_route *rt; + struct atalk_addr ta; + + /* + * Don't route multicast, etc., packets, or packets sent to "this + * network" + */ + if (skb->pkt_type != PACKET_HOST || !ddp->deh_dnet) { + /* + * FIXME: + * + * Can it ever happen that a packet is from a PPP iface and + * needs to be broadcast onto the default network? + */ + if (dev->type == ARPHRD_PPP) + printk(KERN_DEBUG "AppleTalk: didn't forward broadcast " + "packet received from PPP iface\n"); + goto free_it; + } + + ta.s_net = ddp->deh_dnet; + ta.s_node = ddp->deh_dnode; + + /* Route the packet */ + rt = atrtr_find(&ta); + /* increment hops count */ + len_hops += 1 << 10; + if (!rt || !(len_hops & (15 << 10))) + goto free_it; + + /* FIXME: use skb->cb to be able to use shared skbs */ + + /* + * Route goes through another gateway, so set the target to the + * gateway instead. + */ + + if (rt->flags & RTF_GATEWAY) { + ta.s_net = rt->gateway.s_net; + ta.s_node = rt->gateway.s_node; + } + + /* Fix up skb->len field */ + skb_trim(skb, min_t(unsigned int, origlen, + (rt->dev->hard_header_len + + ddp_dl->header_length + (len_hops & 1023)))); + + /* FIXME: use skb->cb to be able to use shared skbs */ + ddp->deh_len_hops = htons(len_hops); + + /* + * Send the buffer onwards + * + * Now we must always be careful. If it's come from LocalTalk to + * EtherTalk it might not fit + * + * Order matters here: If a packet has to be copied to make a new + * headroom (rare hopefully) then it won't need unsharing. + * + * Note. ddp-> becomes invalid at the realloc. + */ + if (skb_headroom(skb) < 22) { + /* 22 bytes - 12 ether, 2 len, 3 802.2 5 snap */ + struct sk_buff *nskb = skb_realloc_headroom(skb, 32); + kfree_skb(skb); + skb = nskb; + } else + skb = skb_unshare(skb, GFP_ATOMIC); + + /* + * If the buffer didn't vanish into the lack of space bitbucket we can + * send it. + */ + if (skb == NULL) + goto drop; + + if (aarp_send_ddp(rt->dev, skb, &ta, NULL) == NET_XMIT_DROP) + return NET_RX_DROP; + return NET_RX_SUCCESS; +free_it: + kfree_skb(skb); +drop: + return NET_RX_DROP; +} + +/** + * atalk_rcv - Receive a packet (in skb) from device dev + * @skb - packet received + * @dev - network device where the packet comes from + * @pt - packet type + * + * Receive a packet (in skb) from device dev. This has come from the SNAP + * decoder, and on entry skb->transport_header is the DDP header, skb->len + * is the DDP header, skb->len is the DDP length. The physical headers + * have been extracted. PPP should probably pass frames marked as for this + * layer. [ie ARPHRD_ETHERTALK] + */ +static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt, struct net_device *orig_dev) +{ + struct ddpehdr *ddp; + struct sock *sock; + struct atalk_iface *atif; + struct sockaddr_at tosat; + int origlen; + __u16 len_hops; + + if (!net_eq(dev_net(dev), &init_net)) + goto drop; + + /* Don't mangle buffer if shared */ + if (!(skb = skb_share_check(skb, GFP_ATOMIC))) + goto out; + + /* Size check and make sure header is contiguous */ + if (!pskb_may_pull(skb, sizeof(*ddp))) + goto drop; + + ddp = ddp_hdr(skb); + + len_hops = ntohs(ddp->deh_len_hops); + + /* Trim buffer in case of stray trailing data */ + origlen = skb->len; + skb_trim(skb, min_t(unsigned int, skb->len, len_hops & 1023)); + + /* + * Size check to see if ddp->deh_len was crap + * (Otherwise we'll detonate most spectacularly + * in the middle of atalk_checksum() or recvmsg()). + */ + if (skb->len < sizeof(*ddp) || skb->len < (len_hops & 1023)) { + pr_debug("AppleTalk: dropping corrupted frame (deh_len=%u, " + "skb->len=%u)\n", len_hops & 1023, skb->len); + goto drop; + } + + /* + * Any checksums. Note we don't do htons() on this == is assumed to be + * valid for net byte orders all over the networking code... + */ + if (ddp->deh_sum && + atalk_checksum(skb, len_hops & 1023) != ddp->deh_sum) + /* Not a valid AppleTalk frame - dustbin time */ + goto drop; + + /* Check the packet is aimed at us */ + if (!ddp->deh_dnet) /* Net 0 is 'this network' */ + atif = atalk_find_anynet(ddp->deh_dnode, dev); + else + atif = atalk_find_interface(ddp->deh_dnet, ddp->deh_dnode); + + if (!atif) { + /* Not ours, so we route the packet via the correct + * AppleTalk iface + */ + return atalk_route_packet(skb, dev, ddp, len_hops, origlen); + } + + /* if IP over DDP is not selected this code will be optimized out */ + if (is_ip_over_ddp(skb)) + return handle_ip_over_ddp(skb); + /* + * Which socket - atalk_search_socket() looks for a *full match* + * of the tuple. + */ + tosat.sat_addr.s_net = ddp->deh_dnet; + tosat.sat_addr.s_node = ddp->deh_dnode; + tosat.sat_port = ddp->deh_dport; + + sock = atalk_search_socket(&tosat, atif); + if (!sock) /* But not one of our sockets */ + goto drop; + + /* Queue packet (standard) */ + skb->sk = sock; + + if (sock_queue_rcv_skb(sock, skb) < 0) + goto drop; + + return NET_RX_SUCCESS; + +drop: + kfree_skb(skb); +out: + return NET_RX_DROP; + +} + +/* + * Receive a LocalTalk frame. We make some demands on the caller here. + * Caller must provide enough headroom on the packet to pull the short + * header and append a long one. + */ +static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt, struct net_device *orig_dev) +{ + if (!net_eq(dev_net(dev), &init_net)) + goto freeit; + + /* Expand any short form frames */ + if (skb_mac_header(skb)[2] == 1) { + struct ddpehdr *ddp; + /* Find our address */ + struct atalk_addr *ap = atalk_find_dev_addr(dev); + + if (!ap || skb->len < sizeof(__be16) || skb->len > 1023) + goto freeit; + + /* Don't mangle buffer if shared */ + if (!(skb = skb_share_check(skb, GFP_ATOMIC))) + return 0; + + /* + * The push leaves us with a ddephdr not an shdr, and + * handily the port bytes in the right place preset. + */ + ddp = (struct ddpehdr *) skb_push(skb, sizeof(*ddp) - 4); + + /* Now fill in the long header */ + + /* + * These two first. The mac overlays the new source/dest + * network information so we MUST copy these before + * we write the network numbers ! + */ + + ddp->deh_dnode = skb_mac_header(skb)[0]; /* From physical header */ + ddp->deh_snode = skb_mac_header(skb)[1]; /* From physical header */ + + ddp->deh_dnet = ap->s_net; /* Network number */ + ddp->deh_snet = ap->s_net; + ddp->deh_sum = 0; /* No checksum */ + /* + * Not sure about this bit... + */ + /* Non routable, so force a drop if we slip up later */ + ddp->deh_len_hops = htons(skb->len + (DDP_MAXHOPS << 10)); + } + skb_reset_transport_header(skb); + + return atalk_rcv(skb, dev, pt, orig_dev); +freeit: + kfree_skb(skb); + return 0; +} + +static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, + size_t len) +{ + struct sock *sk = sock->sk; + struct atalk_sock *at = at_sk(sk); + struct sockaddr_at *usat = (struct sockaddr_at *)msg->msg_name; + int flags = msg->msg_flags; + int loopback = 0; + struct sockaddr_at local_satalk, gsat; + struct sk_buff *skb; + struct net_device *dev; + struct ddpehdr *ddp; + int size; + struct atalk_route *rt; + int err; + + if (flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) + return -EINVAL; + + if (len > DDP_MAXSZ) + return -EMSGSIZE; + + lock_kernel(); + if (usat) { + err = -EBUSY; + if (sock_flag(sk, SOCK_ZAPPED)) + if (atalk_autobind(sk) < 0) + goto out; + + err = -EINVAL; + if (msg->msg_namelen < sizeof(*usat) || + usat->sat_family != AF_APPLETALK) + goto out; + + err = -EPERM; + /* netatalk didn't implement this check */ + if (usat->sat_addr.s_node == ATADDR_BCAST && + !sock_flag(sk, SOCK_BROADCAST)) { + goto out; + } + } else { + err = -ENOTCONN; + if (sk->sk_state != TCP_ESTABLISHED) + goto out; + usat = &local_satalk; + usat->sat_family = AF_APPLETALK; + usat->sat_port = at->dest_port; + usat->sat_addr.s_node = at->dest_node; + usat->sat_addr.s_net = at->dest_net; + } + + /* Build a packet */ + SOCK_DEBUG(sk, "SK %p: Got address.\n", sk); + + /* For headers */ + size = sizeof(struct ddpehdr) + len + ddp_dl->header_length; + + if (usat->sat_addr.s_net || usat->sat_addr.s_node == ATADDR_ANYNODE) { + rt = atrtr_find(&usat->sat_addr); + } else { + struct atalk_addr at_hint; + + at_hint.s_node = 0; + at_hint.s_net = at->src_net; + + rt = atrtr_find(&at_hint); + } + err = ENETUNREACH; + if (!rt) + goto out; + + dev = rt->dev; + + SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n", + sk, size, dev->name); + + size += dev->hard_header_len; + skb = sock_alloc_send_skb(sk, size, (flags & MSG_DONTWAIT), &err); + if (!skb) + goto out; + + skb->sk = sk; + skb_reserve(skb, ddp_dl->header_length); + skb_reserve(skb, dev->hard_header_len); + skb->dev = dev; + + SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk); + + ddp = (struct ddpehdr *)skb_put(skb, sizeof(struct ddpehdr)); + ddp->deh_len_hops = htons(len + sizeof(*ddp)); + ddp->deh_dnet = usat->sat_addr.s_net; + ddp->deh_snet = at->src_net; + ddp->deh_dnode = usat->sat_addr.s_node; + ddp->deh_snode = at->src_node; + ddp->deh_dport = usat->sat_port; + ddp->deh_sport = at->src_port; + + SOCK_DEBUG(sk, "SK %p: Copy user data (%Zd bytes).\n", sk, len); + + err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); + if (err) { + kfree_skb(skb); + err = -EFAULT; + goto out; + } + + if (sk->sk_no_check == 1) + ddp->deh_sum = 0; + else + ddp->deh_sum = atalk_checksum(skb, len + sizeof(*ddp)); + + /* + * Loopback broadcast packets to non gateway targets (ie routes + * to group we are in) + */ + if (ddp->deh_dnode == ATADDR_BCAST && + !(rt->flags & RTF_GATEWAY) && !(dev->flags & IFF_LOOPBACK)) { + struct sk_buff *skb2 = skb_copy(skb, GFP_KERNEL); + + if (skb2) { + loopback = 1; + SOCK_DEBUG(sk, "SK %p: send out(copy).\n", sk); + /* + * If it fails it is queued/sent above in the aarp queue + */ + aarp_send_ddp(dev, skb2, &usat->sat_addr, NULL); + } + } + + if (dev->flags & IFF_LOOPBACK || loopback) { + SOCK_DEBUG(sk, "SK %p: Loop back.\n", sk); + /* loop back */ + skb_orphan(skb); + if (ddp->deh_dnode == ATADDR_BCAST) { + struct atalk_addr at_lo; + + at_lo.s_node = 0; + at_lo.s_net = 0; + + rt = atrtr_find(&at_lo); + if (!rt) { + kfree_skb(skb); + err = -ENETUNREACH; + goto out; + } + dev = rt->dev; + skb->dev = dev; + } + ddp_dl->request(ddp_dl, skb, dev->dev_addr); + } else { + SOCK_DEBUG(sk, "SK %p: send out.\n", sk); + if (rt->flags & RTF_GATEWAY) { + gsat.sat_addr = rt->gateway; + usat = &gsat; + } + + /* + * If it fails it is queued/sent above in the aarp queue + */ + aarp_send_ddp(dev, skb, &usat->sat_addr, NULL); + } + SOCK_DEBUG(sk, "SK %p: Done write (%Zd).\n", sk, len); + +out: + unlock_kernel(); + return err ? : len; +} + +static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, + size_t size, int flags) +{ + struct sock *sk = sock->sk; + struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name; + struct ddpehdr *ddp; + int copied = 0; + int offset = 0; + int err = 0; + struct sk_buff *skb; + + lock_kernel(); + skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, + flags & MSG_DONTWAIT, &err); + if (!skb) + goto out; + + /* FIXME: use skb->cb to be able to use shared skbs */ + ddp = ddp_hdr(skb); + copied = ntohs(ddp->deh_len_hops) & 1023; + + if (sk->sk_type != SOCK_RAW) { + offset = sizeof(*ddp); + copied -= offset; + } + + if (copied > size) { + copied = size; + msg->msg_flags |= MSG_TRUNC; + } + err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied); + + if (!err) { + if (sat) { + sat->sat_family = AF_APPLETALK; + sat->sat_port = ddp->deh_sport; + sat->sat_addr.s_node = ddp->deh_snode; + sat->sat_addr.s_net = ddp->deh_snet; + } + msg->msg_namelen = sizeof(*sat); + } + + skb_free_datagram(sk, skb); /* Free the datagram. */ + +out: + unlock_kernel(); + return err ? : copied; +} + + +/* + * AppleTalk ioctl calls. + */ +static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) +{ + int rc = -ENOIOCTLCMD; + struct sock *sk = sock->sk; + void __user *argp = (void __user *)arg; + + switch (cmd) { + /* Protocol layer */ + case TIOCOUTQ: { + long amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); + + if (amount < 0) + amount = 0; + rc = put_user(amount, (int __user *)argp); + break; + } + case TIOCINQ: { + /* + * These two are safe on a single CPU system as only + * user tasks fiddle here + */ + struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); + long amount = 0; + + if (skb) + amount = skb->len - sizeof(struct ddpehdr); + rc = put_user(amount, (int __user *)argp); + break; + } + case SIOCGSTAMP: + rc = sock_get_timestamp(sk, argp); + break; + case SIOCGSTAMPNS: + rc = sock_get_timestampns(sk, argp); + break; + /* Routing */ + case SIOCADDRT: + case SIOCDELRT: + rc = -EPERM; + if (capable(CAP_NET_ADMIN)) + rc = atrtr_ioctl(cmd, argp); + break; + /* Interface */ + case SIOCGIFADDR: + case SIOCSIFADDR: + case SIOCGIFBRDADDR: + case SIOCATALKDIFADDR: + case SIOCDIFADDR: + case SIOCSARP: /* proxy AARP */ + case SIOCDARP: /* proxy AARP */ + rtnl_lock(); + rc = atif_ioctl(cmd, argp); + rtnl_unlock(); + break; + } + + return rc; +} + + +#ifdef CONFIG_COMPAT +static int atalk_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) +{ + /* + * SIOCATALKDIFADDR is a SIOCPROTOPRIVATE ioctl number, so we + * cannot handle it in common code. The data we access if ifreq + * here is compatible, so we can simply call the native + * handler. + */ + if (cmd == SIOCATALKDIFADDR) + return atalk_ioctl(sock, cmd, (unsigned long)compat_ptr(arg)); + + return -ENOIOCTLCMD; +} +#endif + + +static const struct net_proto_family atalk_family_ops = { + .family = PF_APPLETALK, + .create = atalk_create, + .owner = THIS_MODULE, +}; + +static const struct proto_ops atalk_dgram_ops = { + .family = PF_APPLETALK, + .owner = THIS_MODULE, + .release = atalk_release, + .bind = atalk_bind, + .connect = atalk_connect, + .socketpair = sock_no_socketpair, + .accept = sock_no_accept, + .getname = atalk_getname, + .poll = atalk_poll, + .ioctl = atalk_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = atalk_compat_ioctl, +#endif + .listen = sock_no_listen, + .shutdown = sock_no_shutdown, + .setsockopt = sock_no_setsockopt, + .getsockopt = sock_no_getsockopt, + .sendmsg = atalk_sendmsg, + .recvmsg = atalk_recvmsg, + .mmap = sock_no_mmap, + .sendpage = sock_no_sendpage, +}; + +static struct notifier_block ddp_notifier = { + .notifier_call = ddp_device_event, +}; + +static struct packet_type ltalk_packet_type __read_mostly = { + .type = cpu_to_be16(ETH_P_LOCALTALK), + .func = ltalk_rcv, +}; + +static struct packet_type ppptalk_packet_type __read_mostly = { + .type = cpu_to_be16(ETH_P_PPPTALK), + .func = atalk_rcv, +}; + +static unsigned char ddp_snap_id[] = { 0x08, 0x00, 0x07, 0x80, 0x9B }; + +/* Export symbols for use by drivers when AppleTalk is a module */ +EXPORT_SYMBOL(atrtr_get_dev); +EXPORT_SYMBOL(atalk_find_dev_addr); + +static const char atalk_err_snap[] __initconst = + KERN_CRIT "Unable to register DDP with SNAP.\n"; + +/* Called by proto.c on kernel start up */ +static int __init atalk_init(void) +{ + int rc = proto_register(&ddp_proto, 0); + + if (rc != 0) + goto out; + + (void)sock_register(&atalk_family_ops); + ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv); + if (!ddp_dl) + printk(atalk_err_snap); + + dev_add_pack(<alk_packet_type); + dev_add_pack(&ppptalk_packet_type); + + register_netdevice_notifier(&ddp_notifier); + aarp_proto_init(); + atalk_proc_init(); + atalk_register_sysctl(); +out: + return rc; +} +module_init(atalk_init); + +/* + * No explicit module reference count manipulation is needed in the + * protocol. Socket layer sets module reference count for us + * and interfaces reference counting is done + * by the network device layer. + * + * Ergo, before the AppleTalk module can be removed, all AppleTalk + * sockets be closed from user space. + */ +static void __exit atalk_exit(void) +{ +#ifdef CONFIG_SYSCTL + atalk_unregister_sysctl(); +#endif /* CONFIG_SYSCTL */ + atalk_proc_exit(); + aarp_cleanup_module(); /* General aarp clean-up. */ + unregister_netdevice_notifier(&ddp_notifier); + dev_remove_pack(<alk_packet_type); + dev_remove_pack(&ppptalk_packet_type); + unregister_snap_client(ddp_dl); + sock_unregister(PF_APPLETALK); + proto_unregister(&ddp_proto); +} +module_exit(atalk_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Alan Cox "); +MODULE_DESCRIPTION("AppleTalk 0.20\n"); +MODULE_ALIAS_NETPROTO(PF_APPLETALK); diff --git a/drivers/staging/appletalk/dev.c b/drivers/staging/appletalk/dev.c new file mode 100644 index 000000000000..6c8016f61866 --- /dev/null +++ b/drivers/staging/appletalk/dev.c @@ -0,0 +1,44 @@ +/* + * Moved here from drivers/net/net_init.c, which is: + * Written 1993,1994,1995 by Donald Becker. + */ + +#include +#include +#include +#include +#include + +static void ltalk_setup(struct net_device *dev) +{ + /* Fill in the fields of the device structure with localtalk-generic values. */ + + dev->type = ARPHRD_LOCALTLK; + dev->hard_header_len = LTALK_HLEN; + dev->mtu = LTALK_MTU; + dev->addr_len = LTALK_ALEN; + dev->tx_queue_len = 10; + + dev->broadcast[0] = 0xFF; + + dev->flags = IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP; +} + +/** + * alloc_ltalkdev - Allocates and sets up an localtalk device + * @sizeof_priv: Size of additional driver-private structure to be allocated + * for this localtalk device + * + * Fill in the fields of the device structure with localtalk-generic + * values. Basically does everything except registering the device. + * + * Constructs a new net device, complete with a private data area of + * size @sizeof_priv. A 32-byte (not bit) alignment is enforced for + * this private data area. + */ + +struct net_device *alloc_ltalkdev(int sizeof_priv) +{ + return alloc_netdev(sizeof_priv, "lt%d", ltalk_setup); +} +EXPORT_SYMBOL(alloc_ltalkdev); diff --git a/drivers/staging/appletalk/ipddp.c b/drivers/staging/appletalk/ipddp.c new file mode 100644 index 000000000000..58b4e6098ad4 --- /dev/null +++ b/drivers/staging/appletalk/ipddp.c @@ -0,0 +1,335 @@ +/* + * ipddp.c: IP to Appletalk-IP Encapsulation driver for Linux + * Appletalk-IP to IP Decapsulation driver for Linux + * + * Authors: + * - DDP-IP Encap by: Bradford W. Johnson + * - DDP-IP Decap by: Jay Schulist + * + * Derived from: + * - Almost all code already existed in net/appletalk/ddp.c I just + * moved/reorginized it into a driver file. Original IP-over-DDP code + * was done by Bradford W. Johnson + * - skeleton.c: A network driver outline for linux. + * Written 1993-94 by Donald Becker. + * - dummy.c: A dummy net driver. By Nick Holloway. + * - MacGate: A user space Daemon for Appletalk-IP Decap for + * Linux by Jay Schulist + * + * Copyright 1993 United States Government as represented by the + * Director, National Security Agency. + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "atalk.h" +#include "ipddp.h" /* Our stuff */ + +static const char version[] = KERN_INFO "ipddp.c:v0.01 8/28/97 Bradford W. Johnson \n"; + +static struct ipddp_route *ipddp_route_list; +static DEFINE_SPINLOCK(ipddp_route_lock); + +#ifdef CONFIG_IPDDP_ENCAP +static int ipddp_mode = IPDDP_ENCAP; +#else +static int ipddp_mode = IPDDP_DECAP; +#endif + +/* Index to functions, as function prototypes. */ +static netdev_tx_t ipddp_xmit(struct sk_buff *skb, + struct net_device *dev); +static int ipddp_create(struct ipddp_route *new_rt); +static int ipddp_delete(struct ipddp_route *rt); +static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt); +static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); + +static const struct net_device_ops ipddp_netdev_ops = { + .ndo_start_xmit = ipddp_xmit, + .ndo_do_ioctl = ipddp_ioctl, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + +static struct net_device * __init ipddp_init(void) +{ + static unsigned version_printed; + struct net_device *dev; + int err; + + dev = alloc_etherdev(0); + if (!dev) + return ERR_PTR(-ENOMEM); + + dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; + strcpy(dev->name, "ipddp%d"); + + if (version_printed++ == 0) + printk(version); + + /* Initialize the device structure. */ + dev->netdev_ops = &ipddp_netdev_ops; + + dev->type = ARPHRD_IPDDP; /* IP over DDP tunnel */ + dev->mtu = 585; + dev->flags |= IFF_NOARP; + + /* + * The worst case header we will need is currently a + * ethernet header (14 bytes) and a ddp header (sizeof ddpehdr+1) + * We send over SNAP so that takes another 8 bytes. + */ + dev->hard_header_len = 14+8+sizeof(struct ddpehdr)+1; + + err = register_netdev(dev); + if (err) { + free_netdev(dev); + return ERR_PTR(err); + } + + /* Let the user now what mode we are in */ + if(ipddp_mode == IPDDP_ENCAP) + printk("%s: Appletalk-IP Encap. mode by Bradford W. Johnson \n", + dev->name); + if(ipddp_mode == IPDDP_DECAP) + printk("%s: Appletalk-IP Decap. mode by Jay Schulist \n", + dev->name); + + return dev; +} + + +/* + * Transmit LLAP/ELAP frame using aarp_send_ddp. + */ +static netdev_tx_t ipddp_xmit(struct sk_buff *skb, struct net_device *dev) +{ + __be32 paddr = skb_rtable(skb)->rt_gateway; + struct ddpehdr *ddp; + struct ipddp_route *rt; + struct atalk_addr *our_addr; + + spin_lock(&ipddp_route_lock); + + /* + * Find appropriate route to use, based only on IP number. + */ + for(rt = ipddp_route_list; rt != NULL; rt = rt->next) + { + if(rt->ip == paddr) + break; + } + if(rt == NULL) { + spin_unlock(&ipddp_route_lock); + return NETDEV_TX_OK; + } + + our_addr = atalk_find_dev_addr(rt->dev); + + if(ipddp_mode == IPDDP_DECAP) + /* + * Pull off the excess room that should not be there. + * This is due to a hard-header problem. This is the + * quick fix for now though, till it breaks. + */ + skb_pull(skb, 35-(sizeof(struct ddpehdr)+1)); + + /* Create the Extended DDP header */ + ddp = (struct ddpehdr *)skb->data; + ddp->deh_len_hops = htons(skb->len + (1<<10)); + ddp->deh_sum = 0; + + /* + * For Localtalk we need aarp_send_ddp to strip the + * long DDP header and place a shot DDP header on it. + */ + if(rt->dev->type == ARPHRD_LOCALTLK) + { + ddp->deh_dnet = 0; /* FIXME more hops?? */ + ddp->deh_snet = 0; + } + else + { + ddp->deh_dnet = rt->at.s_net; /* FIXME more hops?? */ + ddp->deh_snet = our_addr->s_net; + } + ddp->deh_dnode = rt->at.s_node; + ddp->deh_snode = our_addr->s_node; + ddp->deh_dport = 72; + ddp->deh_sport = 72; + + *((__u8 *)(ddp+1)) = 22; /* ddp type = IP */ + + skb->protocol = htons(ETH_P_ATALK); /* Protocol has changed */ + + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + + aarp_send_ddp(rt->dev, skb, &rt->at, NULL); + + spin_unlock(&ipddp_route_lock); + + return NETDEV_TX_OK; +} + +/* + * Create a routing entry. We first verify that the + * record does not already exist. If it does we return -EEXIST + */ +static int ipddp_create(struct ipddp_route *new_rt) +{ + struct ipddp_route *rt = kmalloc(sizeof(*rt), GFP_KERNEL); + + if (rt == NULL) + return -ENOMEM; + + rt->ip = new_rt->ip; + rt->at = new_rt->at; + rt->next = NULL; + if ((rt->dev = atrtr_get_dev(&rt->at)) == NULL) { + kfree(rt); + return -ENETUNREACH; + } + + spin_lock_bh(&ipddp_route_lock); + if (__ipddp_find_route(rt)) { + spin_unlock_bh(&ipddp_route_lock); + kfree(rt); + return -EEXIST; + } + + rt->next = ipddp_route_list; + ipddp_route_list = rt; + + spin_unlock_bh(&ipddp_route_lock); + + return 0; +} + +/* + * Delete a route, we only delete a FULL match. + * If route does not exist we return -ENOENT. + */ +static int ipddp_delete(struct ipddp_route *rt) +{ + struct ipddp_route **r = &ipddp_route_list; + struct ipddp_route *tmp; + + spin_lock_bh(&ipddp_route_lock); + while((tmp = *r) != NULL) + { + if(tmp->ip == rt->ip && + tmp->at.s_net == rt->at.s_net && + tmp->at.s_node == rt->at.s_node) + { + *r = tmp->next; + spin_unlock_bh(&ipddp_route_lock); + kfree(tmp); + return 0; + } + r = &tmp->next; + } + + spin_unlock_bh(&ipddp_route_lock); + return -ENOENT; +} + +/* + * Find a routing entry, we only return a FULL match + */ +static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt) +{ + struct ipddp_route *f; + + for(f = ipddp_route_list; f != NULL; f = f->next) + { + if(f->ip == rt->ip && + f->at.s_net == rt->at.s_net && + f->at.s_node == rt->at.s_node) + return f; + } + + return NULL; +} + +static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct ipddp_route __user *rt = ifr->ifr_data; + struct ipddp_route rcp, rcp2, *rp; + + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + + if(copy_from_user(&rcp, rt, sizeof(rcp))) + return -EFAULT; + + switch(cmd) + { + case SIOCADDIPDDPRT: + return ipddp_create(&rcp); + + case SIOCFINDIPDDPRT: + spin_lock_bh(&ipddp_route_lock); + rp = __ipddp_find_route(&rcp); + if (rp) + memcpy(&rcp2, rp, sizeof(rcp2)); + spin_unlock_bh(&ipddp_route_lock); + + if (rp) { + if (copy_to_user(rt, &rcp2, + sizeof(struct ipddp_route))) + return -EFAULT; + return 0; + } else + return -ENOENT; + + case SIOCDELIPDDPRT: + return ipddp_delete(&rcp); + + default: + return -EINVAL; + } +} + +static struct net_device *dev_ipddp; + +MODULE_LICENSE("GPL"); +module_param(ipddp_mode, int, 0); + +static int __init ipddp_init_module(void) +{ + dev_ipddp = ipddp_init(); + if (IS_ERR(dev_ipddp)) + return PTR_ERR(dev_ipddp); + return 0; +} + +static void __exit ipddp_cleanup_module(void) +{ + struct ipddp_route *p; + + unregister_netdev(dev_ipddp); + free_netdev(dev_ipddp); + + while (ipddp_route_list) { + p = ipddp_route_list->next; + kfree(ipddp_route_list); + ipddp_route_list = p; + } +} + +module_init(ipddp_init_module); +module_exit(ipddp_cleanup_module); diff --git a/drivers/staging/appletalk/ipddp.h b/drivers/staging/appletalk/ipddp.h new file mode 100644 index 000000000000..531519da99a3 --- /dev/null +++ b/drivers/staging/appletalk/ipddp.h @@ -0,0 +1,27 @@ +/* + * ipddp.h: Header for IP-over-DDP driver for Linux. + */ + +#ifndef __LINUX_IPDDP_H +#define __LINUX_IPDDP_H + +#ifdef __KERNEL__ + +#define SIOCADDIPDDPRT (SIOCDEVPRIVATE) +#define SIOCDELIPDDPRT (SIOCDEVPRIVATE+1) +#define SIOCFINDIPDDPRT (SIOCDEVPRIVATE+2) + +struct ipddp_route +{ + struct net_device *dev; /* Carrier device */ + __be32 ip; /* IP address */ + struct atalk_addr at; /* Gateway appletalk address */ + int flags; + struct ipddp_route *next; +}; + +#define IPDDP_ENCAP 1 +#define IPDDP_DECAP 2 + +#endif /* __KERNEL__ */ +#endif /* __LINUX_IPDDP_H */ diff --git a/drivers/staging/appletalk/ltpc.c b/drivers/staging/appletalk/ltpc.c new file mode 100644 index 000000000000..60caf892695e --- /dev/null +++ b/drivers/staging/appletalk/ltpc.c @@ -0,0 +1,1288 @@ +/*** ltpc.c -- a driver for the LocalTalk PC card. + * + * Copyright (c) 1995,1996 Bradford W. Johnson + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * This is ALPHA code at best. It may not work for you. It may + * damage your equipment. It may damage your relations with other + * users of your network. Use it at your own risk! + * + * Based in part on: + * skeleton.c by Donald Becker + * dummy.c by Nick Holloway and Alan Cox + * loopback.c by Ross Biro, Fred van Kampen, Donald Becker + * the netatalk source code (UMICH) + * lots of work on the card... + * + * I do not have access to the (proprietary) SDK that goes with the card. + * If you do, I don't want to know about it, and you can probably write + * a better driver yourself anyway. This does mean that the pieces that + * talk to the card are guesswork on my part, so use at your own risk! + * + * This is my first try at writing Linux networking code, and is also + * guesswork. Again, use at your own risk! (Although on this part, I'd + * welcome suggestions) + * + * This is a loadable kernel module which seems to work at my site + * consisting of a 1.2.13 linux box running netatalk 1.3.3, and with + * the kernel support from 1.3.3b2 including patches routing.patch + * and ddp.disappears.from.chooser. In order to run it, you will need + * to patch ddp.c and aarp.c in the kernel, but only a little... + * + * I'm fairly confident that while this is arguably badly written, the + * problems that people experience will be "higher level", that is, with + * complications in the netatalk code. The driver itself doesn't do + * anything terribly complicated -- it pretends to be an ether device + * as far as netatalk is concerned, strips the DDP data out of the ether + * frame and builds a LLAP packet to send out the card. In the other + * direction, it receives LLAP frames from the card and builds a fake + * ether packet that it then tosses up to the networking code. You can + * argue (correctly) that this is an ugly way to do things, but it + * requires a minimal amount of fooling with the code in ddp.c and aarp.c. + * + * The card will do a lot more than is used here -- I *think* it has the + * layers up through ATP. Even if you knew how that part works (which I + * don't) it would be a big job to carve up the kernel ddp code to insert + * things at a higher level, and probably a bad idea... + * + * There are a number of other cards that do LocalTalk on the PC. If + * nobody finds any insurmountable (at the netatalk level) problems + * here, this driver should encourage people to put some work into the + * other cards (some of which I gather are still commercially available) + * and also to put hooks for LocalTalk into the official ddp code. + * + * I welcome comments and suggestions. This is my first try at Linux + * networking stuff, and there are probably lots of things that I did + * suboptimally. + * + ***/ + +/*** + * + * $Log: ltpc.c,v $ + * Revision 1.1.2.1 2000/03/01 05:35:07 jgarzik + * at and tr cleanup + * + * Revision 1.8 1997/01/28 05:44:54 bradford + * Clean up for non-module a little. + * Hacked about a bit to clean things up - Alan Cox + * Probably broken it from the origina 1.8 + * + + * 1998/11/09: David Huggins-Daines + * Cleaned up the initialization code to use the standard autoirq methods, + and to probe for things in the standard order of i/o, irq, dma. This + removes the "reset the reset" hack, because I couldn't figure out an + easy way to get the card to trigger an interrupt after it. + * Added support for passing configuration parameters on the kernel command + line and through insmod + * Changed the device name from "ltalk0" to "lt0", both to conform with the + other localtalk driver, and to clear up the inconsistency between the + module and the non-module versions of the driver :-) + * Added a bunch of comments (I was going to make some enums for the state + codes and the register offsets, but I'm still not sure exactly what their + semantics are) + * Don't poll anymore in interrupt-driven mode + * It seems to work as a module now (as of 2.1.127), but I don't think + I'm responsible for that... + + * + * Revision 1.7 1996/12/12 03:42:33 bradford + * DMA alloc cribbed from 3c505.c. + * + * Revision 1.6 1996/12/12 03:18:58 bradford + * Added virt_to_bus; works in 2.1.13. + * + * Revision 1.5 1996/12/12 03:13:22 root + * xmitQel initialization -- think through better though. + * + * Revision 1.4 1996/06/18 14:55:55 root + * Change names to ltpc. Tabs. Took a shot at dma alloc, + * although more needs to be done eventually. + * + * Revision 1.3 1996/05/22 14:59:39 root + * Change dev->open, dev->close to track dummy.c in 1.99.(around 7) + * + * Revision 1.2 1996/05/22 14:58:24 root + * Change tabs mostly. + * + * Revision 1.1 1996/04/23 04:45:09 root + * Initial revision + * + * Revision 0.16 1996/03/05 15:59:56 root + * Change ARPHRD_LOCALTLK definition to the "real" one. + * + * Revision 0.15 1996/03/05 06:28:30 root + * Changes for kernel 1.3.70. Still need a few patches to kernel, but + * it's getting closer. + * + * Revision 0.14 1996/02/25 17:38:32 root + * More cleanups. Removed query to card on get_stats. + * + * Revision 0.13 1996/02/21 16:27:40 root + * Refix debug_print_skb. Fix mac.raw gotcha that appeared in 1.3.65. + * Clean up receive code a little. + * + * Revision 0.12 1996/02/19 16:34:53 root + * Fix debug_print_skb. Kludge outgoing snet to 0 when using startup + * range. Change debug to mask: 1 for verbose, 2 for higher level stuff + * including packet printing, 4 for lower level (card i/o) stuff. + * + * Revision 0.11 1996/02/12 15:53:38 root + * Added router sends (requires new aarp.c patch) + * + * Revision 0.10 1996/02/11 00:19:35 root + * Change source LTALK_LOGGING debug switch to insmod ... debug=2. + * + * Revision 0.9 1996/02/10 23:59:35 root + * Fixed those fixes for 1.2 -- DANGER! The at.h that comes with netatalk + * has a *different* definition of struct sockaddr_at than the Linux kernel + * does. This is an "insidious and invidious" bug... + * (Actually the preceding comment is false -- it's the atalk.h in the + * ancient atalk-0.06 that's the problem) + * + * Revision 0.8 1996/02/10 19:09:00 root + * Merge 1.3 changes. Tested OK under 1.3.60. + * + * Revision 0.7 1996/02/10 17:56:56 root + * Added debug=1 parameter on insmod for debugging prints. Tried + * to fix timer unload on rmmod, but I don't think that's the problem. + * + * Revision 0.6 1995/12/31 19:01:09 root + * Clean up rmmod, irq comments per feedback from Corin Anderson (Thanks Corey!) + * Clean up initial probing -- sometimes the card wakes up latched in reset. + * + * Revision 0.5 1995/12/22 06:03:44 root + * Added comments in front and cleaned up a bit. + * This version sent out to people. + * + * Revision 0.4 1995/12/18 03:46:44 root + * Return shortDDP to longDDP fake to 0/0. Added command structs. + * + ***/ + +/* ltpc jumpers are: +* +* Interrupts -- set at most one. If none are set, the driver uses +* polled mode. Because the card was developed in the XT era, the +* original documentation refers to IRQ2. Since you'll be running +* this on an AT (or later) class machine, that really means IRQ9. +* +* SW1 IRQ 4 +* SW2 IRQ 3 +* SW3 IRQ 9 (2 in original card documentation only applies to XT) +* +* +* DMA -- choose DMA 1 or 3, and set both corresponding switches. +* +* SW4 DMA 3 +* SW5 DMA 1 +* SW6 DMA 3 +* SW7 DMA 1 +* +* +* I/O address -- choose one. +* +* SW8 220 / 240 +*/ + +/* To have some stuff logged, do +* insmod ltpc.o debug=1 +* +* For a whole bunch of stuff, use higher numbers. +* +* The default is 0, i.e. no messages except for the probe results. +*/ + +/* insmod-tweakable variables */ +static int debug; +#define DEBUG_VERBOSE 1 +#define DEBUG_UPPER 2 +#define DEBUG_LOWER 4 + +static int io; +static int irq; +static int dma; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* our stuff */ +#include "atalk.h" +#include "ltpc.h" + +static DEFINE_SPINLOCK(txqueue_lock); +static DEFINE_SPINLOCK(mbox_lock); + +/* function prototypes */ +static int do_read(struct net_device *dev, void *cbuf, int cbuflen, + void *dbuf, int dbuflen); +static int sendup_buffer (struct net_device *dev); + +/* Dma Memory related stuff, cribbed directly from 3c505.c */ + +static unsigned long dma_mem_alloc(int size) +{ + int order = get_order(size); + + return __get_dma_pages(GFP_KERNEL, order); +} + +/* DMA data buffer, DMA command buffer */ +static unsigned char *ltdmabuf; +static unsigned char *ltdmacbuf; + +/* private struct, holds our appletalk address */ + +struct ltpc_private +{ + struct atalk_addr my_addr; +}; + +/* transmit queue element struct */ + +struct xmitQel { + struct xmitQel *next; + /* command buffer */ + unsigned char *cbuf; + short cbuflen; + /* data buffer */ + unsigned char *dbuf; + short dbuflen; + unsigned char QWrite; /* read or write data */ + unsigned char mailbox; +}; + +/* the transmit queue itself */ + +static struct xmitQel *xmQhd, *xmQtl; + +static void enQ(struct xmitQel *qel) +{ + unsigned long flags; + qel->next = NULL; + + spin_lock_irqsave(&txqueue_lock, flags); + if (xmQtl) { + xmQtl->next = qel; + } else { + xmQhd = qel; + } + xmQtl = qel; + spin_unlock_irqrestore(&txqueue_lock, flags); + + if (debug & DEBUG_LOWER) + printk("enqueued a 0x%02x command\n",qel->cbuf[0]); +} + +static struct xmitQel *deQ(void) +{ + unsigned long flags; + int i; + struct xmitQel *qel=NULL; + + spin_lock_irqsave(&txqueue_lock, flags); + if (xmQhd) { + qel = xmQhd; + xmQhd = qel->next; + if(!xmQhd) xmQtl = NULL; + } + spin_unlock_irqrestore(&txqueue_lock, flags); + + if ((debug & DEBUG_LOWER) && qel) { + int n; + printk(KERN_DEBUG "ltpc: dequeued command "); + n = qel->cbuflen; + if (n>100) n=100; + for(i=0;icbuf[i]); + printk("\n"); + } + + return qel; +} + +/* and... the queue elements we'll be using */ +static struct xmitQel qels[16]; + +/* and their corresponding mailboxes */ +static unsigned char mailbox[16]; +static unsigned char mboxinuse[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +static int wait_timeout(struct net_device *dev, int c) +{ + /* returns true if it stayed c */ + /* this uses base+6, but it's ok */ + int i; + + /* twenty second or so total */ + + for(i=0;i<200000;i++) { + if ( c != inb_p(dev->base_addr+6) ) return 0; + udelay(100); + } + return 1; /* timed out */ +} + +/* get the first free mailbox */ + +static int getmbox(void) +{ + unsigned long flags; + int i; + + spin_lock_irqsave(&mbox_lock, flags); + for(i=1;i<16;i++) if(!mboxinuse[i]) { + mboxinuse[i]=1; + spin_unlock_irqrestore(&mbox_lock, flags); + return i; + } + spin_unlock_irqrestore(&mbox_lock, flags); + return 0; +} + +/* read a command from the card */ +static void handlefc(struct net_device *dev) +{ + /* called *only* from idle, non-reentrant */ + int dma = dev->dma; + int base = dev->base_addr; + unsigned long flags; + + + flags=claim_dma_lock(); + disable_dma(dma); + clear_dma_ff(dma); + set_dma_mode(dma,DMA_MODE_READ); + set_dma_addr(dma,virt_to_bus(ltdmacbuf)); + set_dma_count(dma,50); + enable_dma(dma); + release_dma_lock(flags); + + inb_p(base+3); + inb_p(base+2); + + if ( wait_timeout(dev,0xfc) ) printk("timed out in handlefc\n"); +} + +/* read data from the card */ +static void handlefd(struct net_device *dev) +{ + int dma = dev->dma; + int base = dev->base_addr; + unsigned long flags; + + flags=claim_dma_lock(); + disable_dma(dma); + clear_dma_ff(dma); + set_dma_mode(dma,DMA_MODE_READ); + set_dma_addr(dma,virt_to_bus(ltdmabuf)); + set_dma_count(dma,800); + enable_dma(dma); + release_dma_lock(flags); + + inb_p(base+3); + inb_p(base+2); + + if ( wait_timeout(dev,0xfd) ) printk("timed out in handlefd\n"); + sendup_buffer(dev); +} + +static void handlewrite(struct net_device *dev) +{ + /* called *only* from idle, non-reentrant */ + /* on entry, 0xfb and ltdmabuf holds data */ + int dma = dev->dma; + int base = dev->base_addr; + unsigned long flags; + + flags=claim_dma_lock(); + disable_dma(dma); + clear_dma_ff(dma); + set_dma_mode(dma,DMA_MODE_WRITE); + set_dma_addr(dma,virt_to_bus(ltdmabuf)); + set_dma_count(dma,800); + enable_dma(dma); + release_dma_lock(flags); + + inb_p(base+3); + inb_p(base+2); + + if ( wait_timeout(dev,0xfb) ) { + flags=claim_dma_lock(); + printk("timed out in handlewrite, dma res %d\n", + get_dma_residue(dev->dma) ); + release_dma_lock(flags); + } +} + +static void handleread(struct net_device *dev) +{ + /* on entry, 0xfb */ + /* on exit, ltdmabuf holds data */ + int dma = dev->dma; + int base = dev->base_addr; + unsigned long flags; + + + flags=claim_dma_lock(); + disable_dma(dma); + clear_dma_ff(dma); + set_dma_mode(dma,DMA_MODE_READ); + set_dma_addr(dma,virt_to_bus(ltdmabuf)); + set_dma_count(dma,800); + enable_dma(dma); + release_dma_lock(flags); + + inb_p(base+3); + inb_p(base+2); + if ( wait_timeout(dev,0xfb) ) printk("timed out in handleread\n"); +} + +static void handlecommand(struct net_device *dev) +{ + /* on entry, 0xfa and ltdmacbuf holds command */ + int dma = dev->dma; + int base = dev->base_addr; + unsigned long flags; + + flags=claim_dma_lock(); + disable_dma(dma); + clear_dma_ff(dma); + set_dma_mode(dma,DMA_MODE_WRITE); + set_dma_addr(dma,virt_to_bus(ltdmacbuf)); + set_dma_count(dma,50); + enable_dma(dma); + release_dma_lock(flags); + inb_p(base+3); + inb_p(base+2); + if ( wait_timeout(dev,0xfa) ) printk("timed out in handlecommand\n"); +} + +/* ready made command for getting the result from the card */ +static unsigned char rescbuf[2] = {LT_GETRESULT,0}; +static unsigned char resdbuf[2]; + +static int QInIdle; + +/* idle expects to be called with the IRQ line high -- either because of + * an interrupt, or because the line is tri-stated + */ + +static void idle(struct net_device *dev) +{ + unsigned long flags; + int state; + /* FIXME This is initialized to shut the warning up, but I need to + * think this through again. + */ + struct xmitQel *q = NULL; + int oops; + int i; + int base = dev->base_addr; + + spin_lock_irqsave(&txqueue_lock, flags); + if(QInIdle) { + spin_unlock_irqrestore(&txqueue_lock, flags); + return; + } + QInIdle = 1; + spin_unlock_irqrestore(&txqueue_lock, flags); + + /* this tri-states the IRQ line */ + (void) inb_p(base+6); + + oops = 100; + +loop: + if (0>oops--) { + printk("idle: looped too many times\n"); + goto done; + } + + state = inb_p(base+6); + if (state != inb_p(base+6)) goto loop; + + switch(state) { + case 0xfc: + /* incoming command */ + if (debug & DEBUG_LOWER) printk("idle: fc\n"); + handlefc(dev); + break; + case 0xfd: + /* incoming data */ + if(debug & DEBUG_LOWER) printk("idle: fd\n"); + handlefd(dev); + break; + case 0xf9: + /* result ready */ + if (debug & DEBUG_LOWER) printk("idle: f9\n"); + if(!mboxinuse[0]) { + mboxinuse[0] = 1; + qels[0].cbuf = rescbuf; + qels[0].cbuflen = 2; + qels[0].dbuf = resdbuf; + qels[0].dbuflen = 2; + qels[0].QWrite = 0; + qels[0].mailbox = 0; + enQ(&qels[0]); + } + inb_p(dev->base_addr+1); + inb_p(dev->base_addr+0); + if( wait_timeout(dev,0xf9) ) + printk("timed out idle f9\n"); + break; + case 0xf8: + /* ?? */ + if (xmQhd) { + inb_p(dev->base_addr+1); + inb_p(dev->base_addr+0); + if(wait_timeout(dev,0xf8) ) + printk("timed out idle f8\n"); + } else { + goto done; + } + break; + case 0xfa: + /* waiting for command */ + if(debug & DEBUG_LOWER) printk("idle: fa\n"); + if (xmQhd) { + q=deQ(); + memcpy(ltdmacbuf,q->cbuf,q->cbuflen); + ltdmacbuf[1] = q->mailbox; + if (debug>1) { + int n; + printk("ltpc: sent command "); + n = q->cbuflen; + if (n>100) n=100; + for(i=0;iQWrite) { + memcpy(ltdmabuf,q->dbuf,q->dbuflen); + handlewrite(dev); + } else { + handleread(dev); + /* non-zero mailbox numbers are for + commmands, 0 is for GETRESULT + requests */ + if(q->mailbox) { + memcpy(q->dbuf,ltdmabuf,q->dbuflen); + } else { + /* this was a result */ + mailbox[ 0x0f & ltdmabuf[0] ] = ltdmabuf[1]; + mboxinuse[0]=0; + } + } + break; + } + goto loop; + +done: + QInIdle=0; + + /* now set the interrupts back as appropriate */ + /* the first read takes it out of tri-state (but still high) */ + /* the second resets it */ + /* note that after this point, any read of base+6 will + trigger an interrupt */ + + if (dev->irq) { + inb_p(base+7); + inb_p(base+7); + } +} + + +static int do_write(struct net_device *dev, void *cbuf, int cbuflen, + void *dbuf, int dbuflen) +{ + + int i = getmbox(); + int ret; + + if(i) { + qels[i].cbuf = (unsigned char *) cbuf; + qels[i].cbuflen = cbuflen; + qels[i].dbuf = (unsigned char *) dbuf; + qels[i].dbuflen = dbuflen; + qels[i].QWrite = 1; + qels[i].mailbox = i; /* this should be initted rather */ + enQ(&qels[i]); + idle(dev); + ret = mailbox[i]; + mboxinuse[i]=0; + return ret; + } + printk("ltpc: could not allocate mbox\n"); + return -1; +} + +static int do_read(struct net_device *dev, void *cbuf, int cbuflen, + void *dbuf, int dbuflen) +{ + + int i = getmbox(); + int ret; + + if(i) { + qels[i].cbuf = (unsigned char *) cbuf; + qels[i].cbuflen = cbuflen; + qels[i].dbuf = (unsigned char *) dbuf; + qels[i].dbuflen = dbuflen; + qels[i].QWrite = 0; + qels[i].mailbox = i; /* this should be initted rather */ + enQ(&qels[i]); + idle(dev); + ret = mailbox[i]; + mboxinuse[i]=0; + return ret; + } + printk("ltpc: could not allocate mbox\n"); + return -1; +} + +/* end of idle handlers -- what should be seen is do_read, do_write */ + +static struct timer_list ltpc_timer; + +static netdev_tx_t ltpc_xmit(struct sk_buff *skb, struct net_device *dev); + +static int read_30 ( struct net_device *dev) +{ + lt_command c; + c.getflags.command = LT_GETFLAGS; + return do_read(dev, &c, sizeof(c.getflags),&c,0); +} + +static int set_30 (struct net_device *dev,int x) +{ + lt_command c; + c.setflags.command = LT_SETFLAGS; + c.setflags.flags = x; + return do_write(dev, &c, sizeof(c.setflags),&c,0); +} + +/* LLAP to DDP translation */ + +static int sendup_buffer (struct net_device *dev) +{ + /* on entry, command is in ltdmacbuf, data in ltdmabuf */ + /* called from idle, non-reentrant */ + + int dnode, snode, llaptype, len; + int sklen; + struct sk_buff *skb; + struct lt_rcvlap *ltc = (struct lt_rcvlap *) ltdmacbuf; + + if (ltc->command != LT_RCVLAP) { + printk("unknown command 0x%02x from ltpc card\n",ltc->command); + return -1; + } + dnode = ltc->dnode; + snode = ltc->snode; + llaptype = ltc->laptype; + len = ltc->length; + + sklen = len; + if (llaptype == 1) + sklen += 8; /* correct for short ddp */ + if(sklen > 800) { + printk(KERN_INFO "%s: nonsense length in ltpc command 0x14: 0x%08x\n", + dev->name,sklen); + return -1; + } + + if ( (llaptype==0) || (llaptype>2) ) { + printk(KERN_INFO "%s: unknown LLAP type: %d\n",dev->name,llaptype); + return -1; + } + + + skb = dev_alloc_skb(3+sklen); + if (skb == NULL) + { + printk("%s: dropping packet due to memory squeeze.\n", + dev->name); + return -1; + } + skb->dev = dev; + + if (sklen > len) + skb_reserve(skb,8); + skb_put(skb,len+3); + skb->protocol = htons(ETH_P_LOCALTALK); + /* add LLAP header */ + skb->data[0] = dnode; + skb->data[1] = snode; + skb->data[2] = llaptype; + skb_reset_mac_header(skb); /* save pointer to llap header */ + skb_pull(skb,3); + + /* copy ddp(s,e)hdr + contents */ + skb_copy_to_linear_data(skb, ltdmabuf, len); + + skb_reset_transport_header(skb); + + dev->stats.rx_packets++; + dev->stats.rx_bytes += skb->len; + + /* toss it onwards */ + netif_rx(skb); + return 0; +} + +/* the handler for the board interrupt */ + +static irqreturn_t +ltpc_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + + if (dev==NULL) { + printk("ltpc_interrupt: unknown device.\n"); + return IRQ_NONE; + } + + inb_p(dev->base_addr+6); /* disable further interrupts from board */ + + idle(dev); /* handle whatever is coming in */ + + /* idle re-enables interrupts from board */ + + return IRQ_HANDLED; +} + +/*** + * + * The ioctls that the driver responds to are: + * + * SIOCSIFADDR -- do probe using the passed node hint. + * SIOCGIFADDR -- return net, node. + * + * some of this stuff should be done elsewhere. + * + ***/ + +static int ltpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct sockaddr_at *sa = (struct sockaddr_at *) &ifr->ifr_addr; + /* we'll keep the localtalk node address in dev->pa_addr */ + struct ltpc_private *ltpc_priv = netdev_priv(dev); + struct atalk_addr *aa = <pc_priv->my_addr; + struct lt_init c; + int ltflags; + + if(debug & DEBUG_VERBOSE) printk("ltpc_ioctl called\n"); + + switch(cmd) { + case SIOCSIFADDR: + + aa->s_net = sa->sat_addr.s_net; + + /* this does the probe and returns the node addr */ + c.command = LT_INIT; + c.hint = sa->sat_addr.s_node; + + aa->s_node = do_read(dev,&c,sizeof(c),&c,0); + + /* get all llap frames raw */ + ltflags = read_30(dev); + ltflags |= LT_FLAG_ALLLAP; + set_30 (dev,ltflags); + + dev->broadcast[0] = 0xFF; + dev->dev_addr[0] = aa->s_node; + + dev->addr_len=1; + + return 0; + + case SIOCGIFADDR: + + sa->sat_addr.s_net = aa->s_net; + sa->sat_addr.s_node = aa->s_node; + + return 0; + + default: + return -EINVAL; + } +} + +static void set_multicast_list(struct net_device *dev) +{ + /* This needs to be present to keep netatalk happy. */ + /* Actually netatalk needs fixing! */ +} + +static int ltpc_poll_counter; + +static void ltpc_poll(unsigned long l) +{ + struct net_device *dev = (struct net_device *) l; + + del_timer(<pc_timer); + + if(debug & DEBUG_VERBOSE) { + if (!ltpc_poll_counter) { + ltpc_poll_counter = 50; + printk("ltpc poll is alive\n"); + } + ltpc_poll_counter--; + } + + if (!dev) + return; /* we've been downed */ + + /* poll 20 times per second */ + idle(dev); + ltpc_timer.expires = jiffies + HZ/20; + + add_timer(<pc_timer); +} + +/* DDP to LLAP translation */ + +static netdev_tx_t ltpc_xmit(struct sk_buff *skb, struct net_device *dev) +{ + /* in kernel 1.3.xx, on entry skb->data points to ddp header, + * and skb->len is the length of the ddp data + ddp header + */ + int i; + struct lt_sendlap cbuf; + unsigned char *hdr; + + cbuf.command = LT_SENDLAP; + cbuf.dnode = skb->data[0]; + cbuf.laptype = skb->data[2]; + skb_pull(skb,3); /* skip past LLAP header */ + cbuf.length = skb->len; /* this is host order */ + skb_reset_transport_header(skb); + + if(debug & DEBUG_UPPER) { + printk("command "); + for(i=0;i<6;i++) + printk("%02x ",((unsigned char *)&cbuf)[i]); + printk("\n"); + } + + hdr = skb_transport_header(skb); + do_write(dev, &cbuf, sizeof(cbuf), hdr, skb->len); + + if(debug & DEBUG_UPPER) { + printk("sent %d ddp bytes\n",skb->len); + for (i = 0; i < skb->len; i++) + printk("%02x ", hdr[i]); + printk("\n"); + } + + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + + dev_kfree_skb(skb); + return NETDEV_TX_OK; +} + +/* initialization stuff */ + +static int __init ltpc_probe_dma(int base, int dma) +{ + int want = (dma == 3) ? 2 : (dma == 1) ? 1 : 3; + unsigned long timeout; + unsigned long f; + + if (want & 1) { + if (request_dma(1,"ltpc")) { + want &= ~1; + } else { + f=claim_dma_lock(); + disable_dma(1); + clear_dma_ff(1); + set_dma_mode(1,DMA_MODE_WRITE); + set_dma_addr(1,virt_to_bus(ltdmabuf)); + set_dma_count(1,sizeof(struct lt_mem)); + enable_dma(1); + release_dma_lock(f); + } + } + if (want & 2) { + if (request_dma(3,"ltpc")) { + want &= ~2; + } else { + f=claim_dma_lock(); + disable_dma(3); + clear_dma_ff(3); + set_dma_mode(3,DMA_MODE_WRITE); + set_dma_addr(3,virt_to_bus(ltdmabuf)); + set_dma_count(3,sizeof(struct lt_mem)); + enable_dma(3); + release_dma_lock(f); + } + } + /* set up request */ + + /* FIXME -- do timings better! */ + + ltdmabuf[0] = LT_READMEM; + ltdmabuf[1] = 1; /* mailbox */ + ltdmabuf[2] = 0; ltdmabuf[3] = 0; /* address */ + ltdmabuf[4] = 0; ltdmabuf[5] = 1; /* read 0x0100 bytes */ + ltdmabuf[6] = 0; /* dunno if this is necessary */ + + inb_p(io+1); + inb_p(io+0); + timeout = jiffies+100*HZ/100; + while(time_before(jiffies, timeout)) { + if ( 0xfa == inb_p(io+6) ) break; + } + + inb_p(io+3); + inb_p(io+2); + while(time_before(jiffies, timeout)) { + if ( 0xfb == inb_p(io+6) ) break; + } + + /* release the other dma channel (if we opened both of them) */ + + if ((want & 2) && (get_dma_residue(3)==sizeof(struct lt_mem))) { + want &= ~2; + free_dma(3); + } + + if ((want & 1) && (get_dma_residue(1)==sizeof(struct lt_mem))) { + want &= ~1; + free_dma(1); + } + + if (!want) + return 0; + + return (want & 2) ? 3 : 1; +} + +static const struct net_device_ops ltpc_netdev = { + .ndo_start_xmit = ltpc_xmit, + .ndo_do_ioctl = ltpc_ioctl, + .ndo_set_multicast_list = set_multicast_list, +}; + +struct net_device * __init ltpc_probe(void) +{ + struct net_device *dev; + int err = -ENOMEM; + int x=0,y=0; + int autoirq; + unsigned long f; + unsigned long timeout; + + dev = alloc_ltalkdev(sizeof(struct ltpc_private)); + if (!dev) + goto out; + + /* probe for the I/O port address */ + + if (io != 0x240 && request_region(0x220,8,"ltpc")) { + x = inb_p(0x220+6); + if ( (x!=0xff) && (x>=0xf0) ) { + io = 0x220; + goto got_port; + } + release_region(0x220,8); + } + if (io != 0x220 && request_region(0x240,8,"ltpc")) { + y = inb_p(0x240+6); + if ( (y!=0xff) && (y>=0xf0) ){ + io = 0x240; + goto got_port; + } + release_region(0x240,8); + } + + /* give up in despair */ + printk(KERN_ERR "LocalTalk card not found; 220 = %02x, 240 = %02x.\n", x,y); + err = -ENODEV; + goto out1; + + got_port: + /* probe for the IRQ line */ + if (irq < 2) { + unsigned long irq_mask; + + irq_mask = probe_irq_on(); + /* reset the interrupt line */ + inb_p(io+7); + inb_p(io+7); + /* trigger an interrupt (I hope) */ + inb_p(io+6); + mdelay(2); + autoirq = probe_irq_off(irq_mask); + + if (autoirq == 0) { + printk(KERN_ERR "ltpc: probe at %#x failed to detect IRQ line.\n", io); + } else { + irq = autoirq; + } + } + + /* allocate a DMA buffer */ + ltdmabuf = (unsigned char *) dma_mem_alloc(1000); + if (!ltdmabuf) { + printk(KERN_ERR "ltpc: mem alloc failed\n"); + err = -ENOMEM; + goto out2; + } + + ltdmacbuf = <dmabuf[800]; + + if(debug & DEBUG_VERBOSE) { + printk("ltdmabuf pointer %08lx\n",(unsigned long) ltdmabuf); + } + + /* reset the card */ + + inb_p(io+1); + inb_p(io+3); + + msleep(20); + + inb_p(io+0); + inb_p(io+2); + inb_p(io+7); /* clear reset */ + inb_p(io+4); + inb_p(io+5); + inb_p(io+5); /* enable dma */ + inb_p(io+6); /* tri-state interrupt line */ + + ssleep(1); + + /* now, figure out which dma channel we're using, unless it's + already been specified */ + /* well, 0 is a legal DMA channel, but the LTPC card doesn't + use it... */ + dma = ltpc_probe_dma(io, dma); + if (!dma) { /* no dma channel */ + printk(KERN_ERR "No DMA channel found on ltpc card.\n"); + err = -ENODEV; + goto out3; + } + + /* print out friendly message */ + if(irq) + printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, IR%d, DMA%d.\n",io,irq,dma); + else + printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, DMA%d. Using polled mode.\n",io,dma); + + dev->netdev_ops = <pc_netdev; + dev->base_addr = io; + dev->irq = irq; + dev->dma = dma; + + /* the card will want to send a result at this point */ + /* (I think... leaving out this part makes the kernel crash, + so I put it back in...) */ + + f=claim_dma_lock(); + disable_dma(dma); + clear_dma_ff(dma); + set_dma_mode(dma,DMA_MODE_READ); + set_dma_addr(dma,virt_to_bus(ltdmabuf)); + set_dma_count(dma,0x100); + enable_dma(dma); + release_dma_lock(f); + + (void) inb_p(io+3); + (void) inb_p(io+2); + timeout = jiffies+100*HZ/100; + + while(time_before(jiffies, timeout)) { + if( 0xf9 == inb_p(io+6)) + break; + schedule(); + } + + if(debug & DEBUG_VERBOSE) { + printk("setting up timer and irq\n"); + } + + /* grab it and don't let go :-) */ + if (irq && request_irq( irq, ltpc_interrupt, 0, "ltpc", dev) >= 0) + { + (void) inb_p(io+7); /* enable interrupts from board */ + (void) inb_p(io+7); /* and reset irq line */ + } else { + if( irq ) + printk(KERN_ERR "ltpc: IRQ already in use, using polled mode.\n"); + dev->irq = 0; + /* polled mode -- 20 times per second */ + /* this is really, really slow... should it poll more often? */ + init_timer(<pc_timer); + ltpc_timer.function=ltpc_poll; + ltpc_timer.data = (unsigned long) dev; + + ltpc_timer.expires = jiffies + HZ/20; + add_timer(<pc_timer); + } + err = register_netdev(dev); + if (err) + goto out4; + + return NULL; +out4: + del_timer_sync(<pc_timer); + if (dev->irq) + free_irq(dev->irq, dev); +out3: + free_pages((unsigned long)ltdmabuf, get_order(1000)); +out2: + release_region(io, 8); +out1: + free_netdev(dev); +out: + return ERR_PTR(err); +} + +#ifndef MODULE +/* handles "ltpc=io,irq,dma" kernel command lines */ +static int __init ltpc_setup(char *str) +{ + int ints[5]; + + str = get_options(str, ARRAY_SIZE(ints), ints); + + if (ints[0] == 0) { + if (str && !strncmp(str, "auto", 4)) { + /* do nothing :-) */ + } + else { + /* usage message */ + printk (KERN_ERR + "ltpc: usage: ltpc=auto|iobase[,irq[,dma]]\n"); + return 0; + } + } else { + io = ints[1]; + if (ints[0] > 1) { + irq = ints[2]; + } + if (ints[0] > 2) { + dma = ints[3]; + } + /* ignore any other parameters */ + } + return 1; +} + +__setup("ltpc=", ltpc_setup); +#endif /* MODULE */ + +static struct net_device *dev_ltpc; + +#ifdef MODULE + +MODULE_LICENSE("GPL"); +module_param(debug, int, 0); +module_param(io, int, 0); +module_param(irq, int, 0); +module_param(dma, int, 0); + + +static int __init ltpc_module_init(void) +{ + if(io == 0) + printk(KERN_NOTICE + "ltpc: Autoprobing is not recommended for modules\n"); + + dev_ltpc = ltpc_probe(); + if (IS_ERR(dev_ltpc)) + return PTR_ERR(dev_ltpc); + return 0; +} +module_init(ltpc_module_init); +#endif + +static void __exit ltpc_cleanup(void) +{ + + if(debug & DEBUG_VERBOSE) printk("unregister_netdev\n"); + unregister_netdev(dev_ltpc); + + ltpc_timer.data = 0; /* signal the poll routine that we're done */ + + del_timer_sync(<pc_timer); + + if(debug & DEBUG_VERBOSE) printk("freeing irq\n"); + + if (dev_ltpc->irq) + free_irq(dev_ltpc->irq, dev_ltpc); + + if(debug & DEBUG_VERBOSE) printk("freeing dma\n"); + + if (dev_ltpc->dma) + free_dma(dev_ltpc->dma); + + if(debug & DEBUG_VERBOSE) printk("freeing ioaddr\n"); + + if (dev_ltpc->base_addr) + release_region(dev_ltpc->base_addr,8); + + free_netdev(dev_ltpc); + + if(debug & DEBUG_VERBOSE) printk("free_pages\n"); + + free_pages( (unsigned long) ltdmabuf, get_order(1000)); + + if(debug & DEBUG_VERBOSE) printk("returning from cleanup_module\n"); +} + +module_exit(ltpc_cleanup); diff --git a/drivers/staging/appletalk/ltpc.h b/drivers/staging/appletalk/ltpc.h new file mode 100644 index 000000000000..cd30544a3729 --- /dev/null +++ b/drivers/staging/appletalk/ltpc.h @@ -0,0 +1,73 @@ +/*** ltpc.h + * + * + ***/ + +#define LT_GETRESULT 0x00 +#define LT_WRITEMEM 0x01 +#define LT_READMEM 0x02 +#define LT_GETFLAGS 0x04 +#define LT_SETFLAGS 0x05 +#define LT_INIT 0x10 +#define LT_SENDLAP 0x13 +#define LT_RCVLAP 0x14 + +/* the flag that we care about */ +#define LT_FLAG_ALLLAP 0x04 + +struct lt_getresult { + unsigned char command; + unsigned char mailbox; +}; + +struct lt_mem { + unsigned char command; + unsigned char mailbox; + unsigned short addr; /* host order */ + unsigned short length; /* host order */ +}; + +struct lt_setflags { + unsigned char command; + unsigned char mailbox; + unsigned char flags; +}; + +struct lt_getflags { + unsigned char command; + unsigned char mailbox; +}; + +struct lt_init { + unsigned char command; + unsigned char mailbox; + unsigned char hint; +}; + +struct lt_sendlap { + unsigned char command; + unsigned char mailbox; + unsigned char dnode; + unsigned char laptype; + unsigned short length; /* host order */ +}; + +struct lt_rcvlap { + unsigned char command; + unsigned char dnode; + unsigned char snode; + unsigned char laptype; + unsigned short length; /* host order */ +}; + +union lt_command { + struct lt_getresult getresult; + struct lt_mem mem; + struct lt_setflags setflags; + struct lt_getflags getflags; + struct lt_init init; + struct lt_sendlap sendlap; + struct lt_rcvlap rcvlap; +}; +typedef union lt_command lt_command; + diff --git a/drivers/staging/appletalk/sysctl_net_atalk.c b/drivers/staging/appletalk/sysctl_net_atalk.c new file mode 100644 index 000000000000..4c896b625b2b --- /dev/null +++ b/drivers/staging/appletalk/sysctl_net_atalk.c @@ -0,0 +1,61 @@ +/* + * sysctl_net_atalk.c: sysctl interface to net AppleTalk subsystem. + * + * Begun April 1, 1996, Mike Shaver. + * Added /proc/sys/net/atalk directory entry (empty =) ). [MS] + * Dynamic registration, added aarp entries. (5/30/97 Chris Horn) + */ + +#include +#include +#include "atalk.h" + +static struct ctl_table atalk_table[] = { + { + .procname = "aarp-expiry-time", + .data = &sysctl_aarp_expiry_time, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_jiffies, + }, + { + .procname = "aarp-tick-time", + .data = &sysctl_aarp_tick_time, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_jiffies, + }, + { + .procname = "aarp-retransmit-limit", + .data = &sysctl_aarp_retransmit_limit, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { + .procname = "aarp-resolve-time", + .data = &sysctl_aarp_resolve_time, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_jiffies, + }, + { }, +}; + +static struct ctl_path atalk_path[] = { + { .procname = "net", }, + { .procname = "appletalk", }, + { } +}; + +static struct ctl_table_header *atalk_table_header; + +void atalk_register_sysctl(void) +{ + atalk_table_header = register_sysctl_paths(atalk_path, atalk_table); +} + +void atalk_unregister_sysctl(void) +{ + unregister_sysctl_table(atalk_table_header); +} diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 61abb638b4bf..86a2d7d905c0 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -56,7 +56,6 @@ #include #include #include -#include #include #include diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 2296d8b1931f..362041b73a2f 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -43,7 +43,6 @@ header-y += agpgart.h header-y += aio_abi.h header-y += apm_bios.h header-y += arcfb.h -header-y += atalk.h header-y += atm.h header-y += atm_eni.h header-y += atm_he.h diff --git a/include/linux/atalk.h b/include/linux/atalk.h deleted file mode 100644 index d34c187432ed..000000000000 --- a/include/linux/atalk.h +++ /dev/null @@ -1,208 +0,0 @@ -#ifndef __LINUX_ATALK_H__ -#define __LINUX_ATALK_H__ - -#include -#include - -/* - * AppleTalk networking structures - * - * The following are directly referenced from the University Of Michigan - * netatalk for compatibility reasons. - */ -#define ATPORT_FIRST 1 -#define ATPORT_RESERVED 128 -#define ATPORT_LAST 254 /* 254 is only legal on localtalk */ -#define ATADDR_ANYNET (__u16)0 -#define ATADDR_ANYNODE (__u8)0 -#define ATADDR_ANYPORT (__u8)0 -#define ATADDR_BCAST (__u8)255 -#define DDP_MAXSZ 587 -#define DDP_MAXHOPS 15 /* 4 bits of hop counter */ - -#define SIOCATALKDIFADDR (SIOCPROTOPRIVATE + 0) - -struct atalk_addr { - __be16 s_net; - __u8 s_node; -}; - -struct sockaddr_at { - sa_family_t sat_family; - __u8 sat_port; - struct atalk_addr sat_addr; - char sat_zero[8]; -}; - -struct atalk_netrange { - __u8 nr_phase; - __be16 nr_firstnet; - __be16 nr_lastnet; -}; - -#ifdef __KERNEL__ - -#include - -struct atalk_route { - struct net_device *dev; - struct atalk_addr target; - struct atalk_addr gateway; - int flags; - struct atalk_route *next; -}; - -/** - * struct atalk_iface - AppleTalk Interface - * @dev - Network device associated with this interface - * @address - Our address - * @status - What are we doing? - * @nets - Associated direct netrange - * @next - next element in the list of interfaces - */ -struct atalk_iface { - struct net_device *dev; - struct atalk_addr address; - int status; -#define ATIF_PROBE 1 /* Probing for an address */ -#define ATIF_PROBE_FAIL 2 /* Probe collided */ - struct atalk_netrange nets; - struct atalk_iface *next; -}; - -struct atalk_sock { - /* struct sock has to be the first member of atalk_sock */ - struct sock sk; - __be16 dest_net; - __be16 src_net; - unsigned char dest_node; - unsigned char src_node; - unsigned char dest_port; - unsigned char src_port; -}; - -static inline struct atalk_sock *at_sk(struct sock *sk) -{ - return (struct atalk_sock *)sk; -} - -struct ddpehdr { - __be16 deh_len_hops; /* lower 10 bits are length, next 4 - hops */ - __be16 deh_sum; - __be16 deh_dnet; - __be16 deh_snet; - __u8 deh_dnode; - __u8 deh_snode; - __u8 deh_dport; - __u8 deh_sport; - /* And netatalk apps expect to stick the type in themselves */ -}; - -static __inline__ struct ddpehdr *ddp_hdr(struct sk_buff *skb) -{ - return (struct ddpehdr *)skb_transport_header(skb); -} - -/* AppleTalk AARP headers */ -struct elapaarp { - __be16 hw_type; -#define AARP_HW_TYPE_ETHERNET 1 -#define AARP_HW_TYPE_TOKENRING 2 - __be16 pa_type; - __u8 hw_len; - __u8 pa_len; -#define AARP_PA_ALEN 4 - __be16 function; -#define AARP_REQUEST 1 -#define AARP_REPLY 2 -#define AARP_PROBE 3 - __u8 hw_src[ETH_ALEN]; - __u8 pa_src_zero; - __be16 pa_src_net; - __u8 pa_src_node; - __u8 hw_dst[ETH_ALEN]; - __u8 pa_dst_zero; - __be16 pa_dst_net; - __u8 pa_dst_node; -} __attribute__ ((packed)); - -static __inline__ struct elapaarp *aarp_hdr(struct sk_buff *skb) -{ - return (struct elapaarp *)skb_transport_header(skb); -} - -/* Not specified - how long till we drop a resolved entry */ -#define AARP_EXPIRY_TIME (5 * 60 * HZ) -/* Size of hash table */ -#define AARP_HASH_SIZE 16 -/* Fast retransmission timer when resolving */ -#define AARP_TICK_TIME (HZ / 5) -/* Send 10 requests then give up (2 seconds) */ -#define AARP_RETRANSMIT_LIMIT 10 -/* - * Some value bigger than total retransmit time + a bit for last reply to - * appear and to stop continual requests - */ -#define AARP_RESOLVE_TIME (10 * HZ) - -extern struct datalink_proto *ddp_dl, *aarp_dl; -extern void aarp_proto_init(void); - -/* Inter module exports */ - -/* Give a device find its atif control structure */ -static inline struct atalk_iface *atalk_find_dev(struct net_device *dev) -{ - return dev->atalk_ptr; -} - -extern struct atalk_addr *atalk_find_dev_addr(struct net_device *dev); -extern struct net_device *atrtr_get_dev(struct atalk_addr *sa); -extern int aarp_send_ddp(struct net_device *dev, - struct sk_buff *skb, - struct atalk_addr *sa, void *hwaddr); -extern void aarp_device_down(struct net_device *dev); -extern void aarp_probe_network(struct atalk_iface *atif); -extern int aarp_proxy_probe_network(struct atalk_iface *atif, - struct atalk_addr *sa); -extern void aarp_proxy_remove(struct net_device *dev, - struct atalk_addr *sa); - -extern void aarp_cleanup_module(void); - -extern struct hlist_head atalk_sockets; -extern rwlock_t atalk_sockets_lock; - -extern struct atalk_route *atalk_routes; -extern rwlock_t atalk_routes_lock; - -extern struct atalk_iface *atalk_interfaces; -extern rwlock_t atalk_interfaces_lock; - -extern struct atalk_route atrtr_default; - -extern const struct file_operations atalk_seq_arp_fops; - -extern int sysctl_aarp_expiry_time; -extern int sysctl_aarp_tick_time; -extern int sysctl_aarp_retransmit_limit; -extern int sysctl_aarp_resolve_time; - -#ifdef CONFIG_SYSCTL -extern void atalk_register_sysctl(void); -extern void atalk_unregister_sysctl(void); -#else -#define atalk_register_sysctl() do { } while(0) -#define atalk_unregister_sysctl() do { } while(0) -#endif - -#ifdef CONFIG_PROC_FS -extern int atalk_proc_init(void); -extern void atalk_proc_exit(void); -#else -#define atalk_proc_init() ({ 0; }) -#define atalk_proc_exit() do { } while(0) -#endif /* CONFIG_PROC_FS */ - -#endif /* __KERNEL__ */ -#endif /* __LINUX_ATALK_H__ */ diff --git a/net/Kconfig b/net/Kconfig index 72840626284b..082c8bc977e1 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -204,7 +204,6 @@ source "net/8021q/Kconfig" source "net/decnet/Kconfig" source "net/llc/Kconfig" source "net/ipx/Kconfig" -source "drivers/net/appletalk/Kconfig" source "net/x25/Kconfig" source "net/lapb/Kconfig" source "net/econet/Kconfig" diff --git a/net/Makefile b/net/Makefile index a3330ebe2c53..16d9947b4b95 100644 --- a/net/Makefile +++ b/net/Makefile @@ -27,7 +27,6 @@ obj-$(CONFIG_NET_KEY) += key/ obj-$(CONFIG_BRIDGE) += bridge/ obj-$(CONFIG_NET_DSA) += dsa/ obj-$(CONFIG_IPX) += ipx/ -obj-$(CONFIG_ATALK) += appletalk/ obj-$(CONFIG_WAN_ROUTER) += wanrouter/ obj-$(CONFIG_X25) += x25/ obj-$(CONFIG_LAPB) += lapb/ diff --git a/net/appletalk/Makefile b/net/appletalk/Makefile deleted file mode 100644 index 5cda56edef57..000000000000 --- a/net/appletalk/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# Makefile for the Linux AppleTalk layer. -# - -obj-$(CONFIG_ATALK) += appletalk.o - -appletalk-y := aarp.o ddp.o dev.o -appletalk-$(CONFIG_PROC_FS) += atalk_proc.o -appletalk-$(CONFIG_SYSCTL) += sysctl_net_atalk.o diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c deleted file mode 100644 index 50dce7981321..000000000000 --- a/net/appletalk/aarp.c +++ /dev/null @@ -1,1063 +0,0 @@ -/* - * AARP: An implementation of the AppleTalk AARP protocol for - * Ethernet 'ELAP'. - * - * Alan Cox - * - * This doesn't fit cleanly with the IP arp. Potentially we can use - * the generic neighbour discovery code to clean this up. - * - * FIXME: - * We ought to handle the retransmits with a single list and a - * separate fast timer for when it is needed. - * Use neighbour discovery code. - * Token Ring Support. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * - * References: - * Inside AppleTalk (2nd Ed). - * Fixes: - * Jaume Grau - flush caches on AARP_PROBE - * Rob Newberry - Added proxy AARP and AARP proc fs, - * moved probing from DDP module. - * Arnaldo C. Melo - don't mangle rx packets - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME; -int sysctl_aarp_tick_time = AARP_TICK_TIME; -int sysctl_aarp_retransmit_limit = AARP_RETRANSMIT_LIMIT; -int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME; - -/* Lists of aarp entries */ -/** - * struct aarp_entry - AARP entry - * @last_sent - Last time we xmitted the aarp request - * @packet_queue - Queue of frames wait for resolution - * @status - Used for proxy AARP - * expires_at - Entry expiry time - * target_addr - DDP Address - * dev - Device to use - * hwaddr - Physical i/f address of target/router - * xmit_count - When this hits 10 we give up - * next - Next entry in chain - */ -struct aarp_entry { - /* These first two are only used for unresolved entries */ - unsigned long last_sent; - struct sk_buff_head packet_queue; - int status; - unsigned long expires_at; - struct atalk_addr target_addr; - struct net_device *dev; - char hwaddr[6]; - unsigned short xmit_count; - struct aarp_entry *next; -}; - -/* Hashed list of resolved, unresolved and proxy entries */ -static struct aarp_entry *resolved[AARP_HASH_SIZE]; -static struct aarp_entry *unresolved[AARP_HASH_SIZE]; -static struct aarp_entry *proxies[AARP_HASH_SIZE]; -static int unresolved_count; - -/* One lock protects it all. */ -static DEFINE_RWLOCK(aarp_lock); - -/* Used to walk the list and purge/kick entries. */ -static struct timer_list aarp_timer; - -/* - * Delete an aarp queue - * - * Must run under aarp_lock. - */ -static void __aarp_expire(struct aarp_entry *a) -{ - skb_queue_purge(&a->packet_queue); - kfree(a); -} - -/* - * Send an aarp queue entry request - * - * Must run under aarp_lock. - */ -static void __aarp_send_query(struct aarp_entry *a) -{ - static unsigned char aarp_eth_multicast[ETH_ALEN] = - { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; - struct net_device *dev = a->dev; - struct elapaarp *eah; - int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length; - struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); - struct atalk_addr *sat = atalk_find_dev_addr(dev); - - if (!skb) - return; - - if (!sat) { - kfree_skb(skb); - return; - } - - /* Set up the buffer */ - skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length); - skb_reset_network_header(skb); - skb_reset_transport_header(skb); - skb_put(skb, sizeof(*eah)); - skb->protocol = htons(ETH_P_ATALK); - skb->dev = dev; - eah = aarp_hdr(skb); - - /* Set up the ARP */ - eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); - eah->pa_type = htons(ETH_P_ATALK); - eah->hw_len = ETH_ALEN; - eah->pa_len = AARP_PA_ALEN; - eah->function = htons(AARP_REQUEST); - - memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN); - - eah->pa_src_zero = 0; - eah->pa_src_net = sat->s_net; - eah->pa_src_node = sat->s_node; - - memset(eah->hw_dst, '\0', ETH_ALEN); - - eah->pa_dst_zero = 0; - eah->pa_dst_net = a->target_addr.s_net; - eah->pa_dst_node = a->target_addr.s_node; - - /* Send it */ - aarp_dl->request(aarp_dl, skb, aarp_eth_multicast); - /* Update the sending count */ - a->xmit_count++; - a->last_sent = jiffies; -} - -/* This runs under aarp_lock and in softint context, so only atomic memory - * allocations can be used. */ -static void aarp_send_reply(struct net_device *dev, struct atalk_addr *us, - struct atalk_addr *them, unsigned char *sha) -{ - struct elapaarp *eah; - int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length; - struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); - - if (!skb) - return; - - /* Set up the buffer */ - skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length); - skb_reset_network_header(skb); - skb_reset_transport_header(skb); - skb_put(skb, sizeof(*eah)); - skb->protocol = htons(ETH_P_ATALK); - skb->dev = dev; - eah = aarp_hdr(skb); - - /* Set up the ARP */ - eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); - eah->pa_type = htons(ETH_P_ATALK); - eah->hw_len = ETH_ALEN; - eah->pa_len = AARP_PA_ALEN; - eah->function = htons(AARP_REPLY); - - memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN); - - eah->pa_src_zero = 0; - eah->pa_src_net = us->s_net; - eah->pa_src_node = us->s_node; - - if (!sha) - memset(eah->hw_dst, '\0', ETH_ALEN); - else - memcpy(eah->hw_dst, sha, ETH_ALEN); - - eah->pa_dst_zero = 0; - eah->pa_dst_net = them->s_net; - eah->pa_dst_node = them->s_node; - - /* Send it */ - aarp_dl->request(aarp_dl, skb, sha); -} - -/* - * Send probe frames. Called from aarp_probe_network and - * aarp_proxy_probe_network. - */ - -static void aarp_send_probe(struct net_device *dev, struct atalk_addr *us) -{ - struct elapaarp *eah; - int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length; - struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); - static unsigned char aarp_eth_multicast[ETH_ALEN] = - { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; - - if (!skb) - return; - - /* Set up the buffer */ - skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length); - skb_reset_network_header(skb); - skb_reset_transport_header(skb); - skb_put(skb, sizeof(*eah)); - skb->protocol = htons(ETH_P_ATALK); - skb->dev = dev; - eah = aarp_hdr(skb); - - /* Set up the ARP */ - eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); - eah->pa_type = htons(ETH_P_ATALK); - eah->hw_len = ETH_ALEN; - eah->pa_len = AARP_PA_ALEN; - eah->function = htons(AARP_PROBE); - - memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN); - - eah->pa_src_zero = 0; - eah->pa_src_net = us->s_net; - eah->pa_src_node = us->s_node; - - memset(eah->hw_dst, '\0', ETH_ALEN); - - eah->pa_dst_zero = 0; - eah->pa_dst_net = us->s_net; - eah->pa_dst_node = us->s_node; - - /* Send it */ - aarp_dl->request(aarp_dl, skb, aarp_eth_multicast); -} - -/* - * Handle an aarp timer expire - * - * Must run under the aarp_lock. - */ - -static void __aarp_expire_timer(struct aarp_entry **n) -{ - struct aarp_entry *t; - - while (*n) - /* Expired ? */ - if (time_after(jiffies, (*n)->expires_at)) { - t = *n; - *n = (*n)->next; - __aarp_expire(t); - } else - n = &((*n)->next); -} - -/* - * Kick all pending requests 5 times a second. - * - * Must run under the aarp_lock. - */ -static void __aarp_kick(struct aarp_entry **n) -{ - struct aarp_entry *t; - - while (*n) - /* Expired: if this will be the 11th tx, we delete instead. */ - if ((*n)->xmit_count >= sysctl_aarp_retransmit_limit) { - t = *n; - *n = (*n)->next; - __aarp_expire(t); - } else { - __aarp_send_query(*n); - n = &((*n)->next); - } -} - -/* - * A device has gone down. Take all entries referring to the device - * and remove them. - * - * Must run under the aarp_lock. - */ -static void __aarp_expire_device(struct aarp_entry **n, struct net_device *dev) -{ - struct aarp_entry *t; - - while (*n) - if ((*n)->dev == dev) { - t = *n; - *n = (*n)->next; - __aarp_expire(t); - } else - n = &((*n)->next); -} - -/* Handle the timer event */ -static void aarp_expire_timeout(unsigned long unused) -{ - int ct; - - write_lock_bh(&aarp_lock); - - for (ct = 0; ct < AARP_HASH_SIZE; ct++) { - __aarp_expire_timer(&resolved[ct]); - __aarp_kick(&unresolved[ct]); - __aarp_expire_timer(&unresolved[ct]); - __aarp_expire_timer(&proxies[ct]); - } - - write_unlock_bh(&aarp_lock); - mod_timer(&aarp_timer, jiffies + - (unresolved_count ? sysctl_aarp_tick_time : - sysctl_aarp_expiry_time)); -} - -/* Network device notifier chain handler. */ -static int aarp_device_event(struct notifier_block *this, unsigned long event, - void *ptr) -{ - struct net_device *dev = ptr; - int ct; - - if (!net_eq(dev_net(dev), &init_net)) - return NOTIFY_DONE; - - if (event == NETDEV_DOWN) { - write_lock_bh(&aarp_lock); - - for (ct = 0; ct < AARP_HASH_SIZE; ct++) { - __aarp_expire_device(&resolved[ct], dev); - __aarp_expire_device(&unresolved[ct], dev); - __aarp_expire_device(&proxies[ct], dev); - } - - write_unlock_bh(&aarp_lock); - } - return NOTIFY_DONE; -} - -/* Expire all entries in a hash chain */ -static void __aarp_expire_all(struct aarp_entry **n) -{ - struct aarp_entry *t; - - while (*n) { - t = *n; - *n = (*n)->next; - __aarp_expire(t); - } -} - -/* Cleanup all hash chains -- module unloading */ -static void aarp_purge(void) -{ - int ct; - - write_lock_bh(&aarp_lock); - for (ct = 0; ct < AARP_HASH_SIZE; ct++) { - __aarp_expire_all(&resolved[ct]); - __aarp_expire_all(&unresolved[ct]); - __aarp_expire_all(&proxies[ct]); - } - write_unlock_bh(&aarp_lock); -} - -/* - * Create a new aarp entry. This must use GFP_ATOMIC because it - * runs while holding spinlocks. - */ -static struct aarp_entry *aarp_alloc(void) -{ - struct aarp_entry *a = kmalloc(sizeof(*a), GFP_ATOMIC); - - if (a) - skb_queue_head_init(&a->packet_queue); - return a; -} - -/* - * Find an entry. We might return an expired but not yet purged entry. We - * don't care as it will do no harm. - * - * This must run under the aarp_lock. - */ -static struct aarp_entry *__aarp_find_entry(struct aarp_entry *list, - struct net_device *dev, - struct atalk_addr *sat) -{ - while (list) { - if (list->target_addr.s_net == sat->s_net && - list->target_addr.s_node == sat->s_node && - list->dev == dev) - break; - list = list->next; - } - - return list; -} - -/* Called from the DDP code, and thus must be exported. */ -void aarp_proxy_remove(struct net_device *dev, struct atalk_addr *sa) -{ - int hash = sa->s_node % (AARP_HASH_SIZE - 1); - struct aarp_entry *a; - - write_lock_bh(&aarp_lock); - - a = __aarp_find_entry(proxies[hash], dev, sa); - if (a) - a->expires_at = jiffies - 1; - - write_unlock_bh(&aarp_lock); -} - -/* This must run under aarp_lock. */ -static struct atalk_addr *__aarp_proxy_find(struct net_device *dev, - struct atalk_addr *sa) -{ - int hash = sa->s_node % (AARP_HASH_SIZE - 1); - struct aarp_entry *a = __aarp_find_entry(proxies[hash], dev, sa); - - return a ? sa : NULL; -} - -/* - * Probe a Phase 1 device or a device that requires its Net:Node to - * be set via an ioctl. - */ -static void aarp_send_probe_phase1(struct atalk_iface *iface) -{ - struct ifreq atreq; - struct sockaddr_at *sa = (struct sockaddr_at *)&atreq.ifr_addr; - const struct net_device_ops *ops = iface->dev->netdev_ops; - - sa->sat_addr.s_node = iface->address.s_node; - sa->sat_addr.s_net = ntohs(iface->address.s_net); - - /* We pass the Net:Node to the drivers/cards by a Device ioctl. */ - if (!(ops->ndo_do_ioctl(iface->dev, &atreq, SIOCSIFADDR))) { - ops->ndo_do_ioctl(iface->dev, &atreq, SIOCGIFADDR); - if (iface->address.s_net != htons(sa->sat_addr.s_net) || - iface->address.s_node != sa->sat_addr.s_node) - iface->status |= ATIF_PROBE_FAIL; - - iface->address.s_net = htons(sa->sat_addr.s_net); - iface->address.s_node = sa->sat_addr.s_node; - } -} - - -void aarp_probe_network(struct atalk_iface *atif) -{ - if (atif->dev->type == ARPHRD_LOCALTLK || - atif->dev->type == ARPHRD_PPP) - aarp_send_probe_phase1(atif); - else { - unsigned int count; - - for (count = 0; count < AARP_RETRANSMIT_LIMIT; count++) { - aarp_send_probe(atif->dev, &atif->address); - - /* Defer 1/10th */ - msleep(100); - - if (atif->status & ATIF_PROBE_FAIL) - break; - } - } -} - -int aarp_proxy_probe_network(struct atalk_iface *atif, struct atalk_addr *sa) -{ - int hash, retval = -EPROTONOSUPPORT; - struct aarp_entry *entry; - unsigned int count; - - /* - * we don't currently support LocalTalk or PPP for proxy AARP; - * if someone wants to try and add it, have fun - */ - if (atif->dev->type == ARPHRD_LOCALTLK || - atif->dev->type == ARPHRD_PPP) - goto out; - - /* - * create a new AARP entry with the flags set to be published -- - * we need this one to hang around even if it's in use - */ - entry = aarp_alloc(); - retval = -ENOMEM; - if (!entry) - goto out; - - entry->expires_at = -1; - entry->status = ATIF_PROBE; - entry->target_addr.s_node = sa->s_node; - entry->target_addr.s_net = sa->s_net; - entry->dev = atif->dev; - - write_lock_bh(&aarp_lock); - - hash = sa->s_node % (AARP_HASH_SIZE - 1); - entry->next = proxies[hash]; - proxies[hash] = entry; - - for (count = 0; count < AARP_RETRANSMIT_LIMIT; count++) { - aarp_send_probe(atif->dev, sa); - - /* Defer 1/10th */ - write_unlock_bh(&aarp_lock); - msleep(100); - write_lock_bh(&aarp_lock); - - if (entry->status & ATIF_PROBE_FAIL) - break; - } - - if (entry->status & ATIF_PROBE_FAIL) { - entry->expires_at = jiffies - 1; /* free the entry */ - retval = -EADDRINUSE; /* return network full */ - } else { /* clear the probing flag */ - entry->status &= ~ATIF_PROBE; - retval = 1; - } - - write_unlock_bh(&aarp_lock); -out: - return retval; -} - -/* Send a DDP frame */ -int aarp_send_ddp(struct net_device *dev, struct sk_buff *skb, - struct atalk_addr *sa, void *hwaddr) -{ - static char ddp_eth_multicast[ETH_ALEN] = - { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; - int hash; - struct aarp_entry *a; - - skb_reset_network_header(skb); - - /* Check for LocalTalk first */ - if (dev->type == ARPHRD_LOCALTLK) { - struct atalk_addr *at = atalk_find_dev_addr(dev); - struct ddpehdr *ddp = (struct ddpehdr *)skb->data; - int ft = 2; - - /* - * Compressible ? - * - * IFF: src_net == dest_net == device_net - * (zero matches anything) - */ - - if ((!ddp->deh_snet || at->s_net == ddp->deh_snet) && - (!ddp->deh_dnet || at->s_net == ddp->deh_dnet)) { - skb_pull(skb, sizeof(*ddp) - 4); - - /* - * The upper two remaining bytes are the port - * numbers we just happen to need. Now put the - * length in the lower two. - */ - *((__be16 *)skb->data) = htons(skb->len); - ft = 1; - } - /* - * Nice and easy. No AARP type protocols occur here so we can - * just shovel it out with a 3 byte LLAP header - */ - - skb_push(skb, 3); - skb->data[0] = sa->s_node; - skb->data[1] = at->s_node; - skb->data[2] = ft; - skb->dev = dev; - goto sendit; - } - - /* On a PPP link we neither compress nor aarp. */ - if (dev->type == ARPHRD_PPP) { - skb->protocol = htons(ETH_P_PPPTALK); - skb->dev = dev; - goto sendit; - } - - /* Non ELAP we cannot do. */ - if (dev->type != ARPHRD_ETHER) - goto free_it; - - skb->dev = dev; - skb->protocol = htons(ETH_P_ATALK); - hash = sa->s_node % (AARP_HASH_SIZE - 1); - - /* Do we have a resolved entry? */ - if (sa->s_node == ATADDR_BCAST) { - /* Send it */ - ddp_dl->request(ddp_dl, skb, ddp_eth_multicast); - goto sent; - } - - write_lock_bh(&aarp_lock); - a = __aarp_find_entry(resolved[hash], dev, sa); - - if (a) { /* Return 1 and fill in the address */ - a->expires_at = jiffies + (sysctl_aarp_expiry_time * 10); - ddp_dl->request(ddp_dl, skb, a->hwaddr); - write_unlock_bh(&aarp_lock); - goto sent; - } - - /* Do we have an unresolved entry: This is the less common path */ - a = __aarp_find_entry(unresolved[hash], dev, sa); - if (a) { /* Queue onto the unresolved queue */ - skb_queue_tail(&a->packet_queue, skb); - goto out_unlock; - } - - /* Allocate a new entry */ - a = aarp_alloc(); - if (!a) { - /* Whoops slipped... good job it's an unreliable protocol 8) */ - write_unlock_bh(&aarp_lock); - goto free_it; - } - - /* Set up the queue */ - skb_queue_tail(&a->packet_queue, skb); - a->expires_at = jiffies + sysctl_aarp_resolve_time; - a->dev = dev; - a->next = unresolved[hash]; - a->target_addr = *sa; - a->xmit_count = 0; - unresolved[hash] = a; - unresolved_count++; - - /* Send an initial request for the address */ - __aarp_send_query(a); - - /* - * Switch to fast timer if needed (That is if this is the first - * unresolved entry to get added) - */ - - if (unresolved_count == 1) - mod_timer(&aarp_timer, jiffies + sysctl_aarp_tick_time); - - /* Now finally, it is safe to drop the lock. */ -out_unlock: - write_unlock_bh(&aarp_lock); - - /* Tell the ddp layer we have taken over for this frame. */ - goto sent; - -sendit: - if (skb->sk) - skb->priority = skb->sk->sk_priority; - if (dev_queue_xmit(skb)) - goto drop; -sent: - return NET_XMIT_SUCCESS; -free_it: - kfree_skb(skb); -drop: - return NET_XMIT_DROP; -} -EXPORT_SYMBOL(aarp_send_ddp); - -/* - * An entry in the aarp unresolved queue has become resolved. Send - * all the frames queued under it. - * - * Must run under aarp_lock. - */ -static void __aarp_resolved(struct aarp_entry **list, struct aarp_entry *a, - int hash) -{ - struct sk_buff *skb; - - while (*list) - if (*list == a) { - unresolved_count--; - *list = a->next; - - /* Move into the resolved list */ - a->next = resolved[hash]; - resolved[hash] = a; - - /* Kick frames off */ - while ((skb = skb_dequeue(&a->packet_queue)) != NULL) { - a->expires_at = jiffies + - sysctl_aarp_expiry_time * 10; - ddp_dl->request(ddp_dl, skb, a->hwaddr); - } - } else - list = &((*list)->next); -} - -/* - * This is called by the SNAP driver whenever we see an AARP SNAP - * frame. We currently only support Ethernet. - */ -static int aarp_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, struct net_device *orig_dev) -{ - struct elapaarp *ea = aarp_hdr(skb); - int hash, ret = 0; - __u16 function; - struct aarp_entry *a; - struct atalk_addr sa, *ma, da; - struct atalk_iface *ifa; - - if (!net_eq(dev_net(dev), &init_net)) - goto out0; - - /* We only do Ethernet SNAP AARP. */ - if (dev->type != ARPHRD_ETHER) - goto out0; - - /* Frame size ok? */ - if (!skb_pull(skb, sizeof(*ea))) - goto out0; - - function = ntohs(ea->function); - - /* Sanity check fields. */ - if (function < AARP_REQUEST || function > AARP_PROBE || - ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN || - ea->pa_src_zero || ea->pa_dst_zero) - goto out0; - - /* Looks good. */ - hash = ea->pa_src_node % (AARP_HASH_SIZE - 1); - - /* Build an address. */ - sa.s_node = ea->pa_src_node; - sa.s_net = ea->pa_src_net; - - /* Process the packet. Check for replies of me. */ - ifa = atalk_find_dev(dev); - if (!ifa) - goto out1; - - if (ifa->status & ATIF_PROBE && - ifa->address.s_node == ea->pa_dst_node && - ifa->address.s_net == ea->pa_dst_net) { - ifa->status |= ATIF_PROBE_FAIL; /* Fail the probe (in use) */ - goto out1; - } - - /* Check for replies of proxy AARP entries */ - da.s_node = ea->pa_dst_node; - da.s_net = ea->pa_dst_net; - - write_lock_bh(&aarp_lock); - a = __aarp_find_entry(proxies[hash], dev, &da); - - if (a && a->status & ATIF_PROBE) { - a->status |= ATIF_PROBE_FAIL; - /* - * we do not respond to probe or request packets for - * this address while we are probing this address - */ - goto unlock; - } - - switch (function) { - case AARP_REPLY: - if (!unresolved_count) /* Speed up */ - break; - - /* Find the entry. */ - a = __aarp_find_entry(unresolved[hash], dev, &sa); - if (!a || dev != a->dev) - break; - - /* We can fill one in - this is good. */ - memcpy(a->hwaddr, ea->hw_src, ETH_ALEN); - __aarp_resolved(&unresolved[hash], a, hash); - if (!unresolved_count) - mod_timer(&aarp_timer, - jiffies + sysctl_aarp_expiry_time); - break; - - case AARP_REQUEST: - case AARP_PROBE: - - /* - * If it is my address set ma to my address and reply. - * We can treat probe and request the same. Probe - * simply means we shouldn't cache the querying host, - * as in a probe they are proposing an address not - * using one. - * - * Support for proxy-AARP added. We check if the - * address is one of our proxies before we toss the - * packet out. - */ - - sa.s_node = ea->pa_dst_node; - sa.s_net = ea->pa_dst_net; - - /* See if we have a matching proxy. */ - ma = __aarp_proxy_find(dev, &sa); - if (!ma) - ma = &ifa->address; - else { /* We need to make a copy of the entry. */ - da.s_node = sa.s_node; - da.s_net = sa.s_net; - ma = &da; - } - - if (function == AARP_PROBE) { - /* - * A probe implies someone trying to get an - * address. So as a precaution flush any - * entries we have for this address. - */ - a = __aarp_find_entry(resolved[sa.s_node % - (AARP_HASH_SIZE - 1)], - skb->dev, &sa); - - /* - * Make it expire next tick - that avoids us - * getting into a probe/flush/learn/probe/ - * flush/learn cycle during probing of a slow - * to respond host addr. - */ - if (a) { - a->expires_at = jiffies - 1; - mod_timer(&aarp_timer, jiffies + - sysctl_aarp_tick_time); - } - } - - if (sa.s_node != ma->s_node) - break; - - if (sa.s_net && ma->s_net && sa.s_net != ma->s_net) - break; - - sa.s_node = ea->pa_src_node; - sa.s_net = ea->pa_src_net; - - /* aarp_my_address has found the address to use for us. - */ - aarp_send_reply(dev, ma, &sa, ea->hw_src); - break; - } - -unlock: - write_unlock_bh(&aarp_lock); -out1: - ret = 1; -out0: - kfree_skb(skb); - return ret; -} - -static struct notifier_block aarp_notifier = { - .notifier_call = aarp_device_event, -}; - -static unsigned char aarp_snap_id[] = { 0x00, 0x00, 0x00, 0x80, 0xF3 }; - -void __init aarp_proto_init(void) -{ - aarp_dl = register_snap_client(aarp_snap_id, aarp_rcv); - if (!aarp_dl) - printk(KERN_CRIT "Unable to register AARP with SNAP.\n"); - setup_timer(&aarp_timer, aarp_expire_timeout, 0); - aarp_timer.expires = jiffies + sysctl_aarp_expiry_time; - add_timer(&aarp_timer); - register_netdevice_notifier(&aarp_notifier); -} - -/* Remove the AARP entries associated with a device. */ -void aarp_device_down(struct net_device *dev) -{ - int ct; - - write_lock_bh(&aarp_lock); - - for (ct = 0; ct < AARP_HASH_SIZE; ct++) { - __aarp_expire_device(&resolved[ct], dev); - __aarp_expire_device(&unresolved[ct], dev); - __aarp_expire_device(&proxies[ct], dev); - } - - write_unlock_bh(&aarp_lock); -} - -#ifdef CONFIG_PROC_FS -struct aarp_iter_state { - int bucket; - struct aarp_entry **table; -}; - -/* - * Get the aarp entry that is in the chain described - * by the iterator. - * If pos is set then skip till that index. - * pos = 1 is the first entry - */ -static struct aarp_entry *iter_next(struct aarp_iter_state *iter, loff_t *pos) -{ - int ct = iter->bucket; - struct aarp_entry **table = iter->table; - loff_t off = 0; - struct aarp_entry *entry; - - rescan: - while(ct < AARP_HASH_SIZE) { - for (entry = table[ct]; entry; entry = entry->next) { - if (!pos || ++off == *pos) { - iter->table = table; - iter->bucket = ct; - return entry; - } - } - ++ct; - } - - if (table == resolved) { - ct = 0; - table = unresolved; - goto rescan; - } - if (table == unresolved) { - ct = 0; - table = proxies; - goto rescan; - } - return NULL; -} - -static void *aarp_seq_start(struct seq_file *seq, loff_t *pos) - __acquires(aarp_lock) -{ - struct aarp_iter_state *iter = seq->private; - - read_lock_bh(&aarp_lock); - iter->table = resolved; - iter->bucket = 0; - - return *pos ? iter_next(iter, pos) : SEQ_START_TOKEN; -} - -static void *aarp_seq_next(struct seq_file *seq, void *v, loff_t *pos) -{ - struct aarp_entry *entry = v; - struct aarp_iter_state *iter = seq->private; - - ++*pos; - - /* first line after header */ - if (v == SEQ_START_TOKEN) - entry = iter_next(iter, NULL); - - /* next entry in current bucket */ - else if (entry->next) - entry = entry->next; - - /* next bucket or table */ - else { - ++iter->bucket; - entry = iter_next(iter, NULL); - } - return entry; -} - -static void aarp_seq_stop(struct seq_file *seq, void *v) - __releases(aarp_lock) -{ - read_unlock_bh(&aarp_lock); -} - -static const char *dt2str(unsigned long ticks) -{ - static char buf[32]; - - sprintf(buf, "%ld.%02ld", ticks / HZ, ((ticks % HZ) * 100 ) / HZ); - - return buf; -} - -static int aarp_seq_show(struct seq_file *seq, void *v) -{ - struct aarp_iter_state *iter = seq->private; - struct aarp_entry *entry = v; - unsigned long now = jiffies; - - if (v == SEQ_START_TOKEN) - seq_puts(seq, - "Address Interface Hardware Address" - " Expires LastSend Retry Status\n"); - else { - seq_printf(seq, "%04X:%02X %-12s", - ntohs(entry->target_addr.s_net), - (unsigned int) entry->target_addr.s_node, - entry->dev ? entry->dev->name : "????"); - seq_printf(seq, "%pM", entry->hwaddr); - seq_printf(seq, " %8s", - dt2str((long)entry->expires_at - (long)now)); - if (iter->table == unresolved) - seq_printf(seq, " %8s %6hu", - dt2str(now - entry->last_sent), - entry->xmit_count); - else - seq_puts(seq, " "); - seq_printf(seq, " %s\n", - (iter->table == resolved) ? "resolved" - : (iter->table == unresolved) ? "unresolved" - : (iter->table == proxies) ? "proxies" - : "unknown"); - } - return 0; -} - -static const struct seq_operations aarp_seq_ops = { - .start = aarp_seq_start, - .next = aarp_seq_next, - .stop = aarp_seq_stop, - .show = aarp_seq_show, -}; - -static int aarp_seq_open(struct inode *inode, struct file *file) -{ - return seq_open_private(file, &aarp_seq_ops, - sizeof(struct aarp_iter_state)); -} - -const struct file_operations atalk_seq_arp_fops = { - .owner = THIS_MODULE, - .open = aarp_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release_private, -}; -#endif - -/* General module cleanup. Called from cleanup_module() in ddp.c. */ -void aarp_cleanup_module(void) -{ - del_timer_sync(&aarp_timer); - unregister_netdevice_notifier(&aarp_notifier); - unregister_snap_client(aarp_dl); - aarp_purge(); -} diff --git a/net/appletalk/atalk_proc.c b/net/appletalk/atalk_proc.c deleted file mode 100644 index 6ef0e761e5de..000000000000 --- a/net/appletalk/atalk_proc.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * atalk_proc.c - proc support for Appletalk - * - * Copyright(c) Arnaldo Carvalho de Melo - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, version 2. - */ - -#include -#include -#include -#include -#include -#include - - -static __inline__ struct atalk_iface *atalk_get_interface_idx(loff_t pos) -{ - struct atalk_iface *i; - - for (i = atalk_interfaces; pos && i; i = i->next) - --pos; - - return i; -} - -static void *atalk_seq_interface_start(struct seq_file *seq, loff_t *pos) - __acquires(atalk_interfaces_lock) -{ - loff_t l = *pos; - - read_lock_bh(&atalk_interfaces_lock); - return l ? atalk_get_interface_idx(--l) : SEQ_START_TOKEN; -} - -static void *atalk_seq_interface_next(struct seq_file *seq, void *v, loff_t *pos) -{ - struct atalk_iface *i; - - ++*pos; - if (v == SEQ_START_TOKEN) { - i = NULL; - if (atalk_interfaces) - i = atalk_interfaces; - goto out; - } - i = v; - i = i->next; -out: - return i; -} - -static void atalk_seq_interface_stop(struct seq_file *seq, void *v) - __releases(atalk_interfaces_lock) -{ - read_unlock_bh(&atalk_interfaces_lock); -} - -static int atalk_seq_interface_show(struct seq_file *seq, void *v) -{ - struct atalk_iface *iface; - - if (v == SEQ_START_TOKEN) { - seq_puts(seq, "Interface Address Networks " - "Status\n"); - goto out; - } - - iface = v; - seq_printf(seq, "%-16s %04X:%02X %04X-%04X %d\n", - iface->dev->name, ntohs(iface->address.s_net), - iface->address.s_node, ntohs(iface->nets.nr_firstnet), - ntohs(iface->nets.nr_lastnet), iface->status); -out: - return 0; -} - -static __inline__ struct atalk_route *atalk_get_route_idx(loff_t pos) -{ - struct atalk_route *r; - - for (r = atalk_routes; pos && r; r = r->next) - --pos; - - return r; -} - -static void *atalk_seq_route_start(struct seq_file *seq, loff_t *pos) - __acquires(atalk_routes_lock) -{ - loff_t l = *pos; - - read_lock_bh(&atalk_routes_lock); - return l ? atalk_get_route_idx(--l) : SEQ_START_TOKEN; -} - -static void *atalk_seq_route_next(struct seq_file *seq, void *v, loff_t *pos) -{ - struct atalk_route *r; - - ++*pos; - if (v == SEQ_START_TOKEN) { - r = NULL; - if (atalk_routes) - r = atalk_routes; - goto out; - } - r = v; - r = r->next; -out: - return r; -} - -static void atalk_seq_route_stop(struct seq_file *seq, void *v) - __releases(atalk_routes_lock) -{ - read_unlock_bh(&atalk_routes_lock); -} - -static int atalk_seq_route_show(struct seq_file *seq, void *v) -{ - struct atalk_route *rt; - - if (v == SEQ_START_TOKEN) { - seq_puts(seq, "Target Router Flags Dev\n"); - goto out; - } - - if (atrtr_default.dev) { - rt = &atrtr_default; - seq_printf(seq, "Default %04X:%02X %-4d %s\n", - ntohs(rt->gateway.s_net), rt->gateway.s_node, - rt->flags, rt->dev->name); - } - - rt = v; - seq_printf(seq, "%04X:%02X %04X:%02X %-4d %s\n", - ntohs(rt->target.s_net), rt->target.s_node, - ntohs(rt->gateway.s_net), rt->gateway.s_node, - rt->flags, rt->dev->name); -out: - return 0; -} - -static void *atalk_seq_socket_start(struct seq_file *seq, loff_t *pos) - __acquires(atalk_sockets_lock) -{ - read_lock_bh(&atalk_sockets_lock); - return seq_hlist_start_head(&atalk_sockets, *pos); -} - -static void *atalk_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos) -{ - return seq_hlist_next(v, &atalk_sockets, pos); -} - -static void atalk_seq_socket_stop(struct seq_file *seq, void *v) - __releases(atalk_sockets_lock) -{ - read_unlock_bh(&atalk_sockets_lock); -} - -static int atalk_seq_socket_show(struct seq_file *seq, void *v) -{ - struct sock *s; - struct atalk_sock *at; - - if (v == SEQ_START_TOKEN) { - seq_printf(seq, "Type Local_addr Remote_addr Tx_queue " - "Rx_queue St UID\n"); - goto out; - } - - s = sk_entry(v); - at = at_sk(s); - - seq_printf(seq, "%02X %04X:%02X:%02X %04X:%02X:%02X %08X:%08X " - "%02X %d\n", - s->sk_type, ntohs(at->src_net), at->src_node, at->src_port, - ntohs(at->dest_net), at->dest_node, at->dest_port, - sk_wmem_alloc_get(s), - sk_rmem_alloc_get(s), - s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); -out: - return 0; -} - -static const struct seq_operations atalk_seq_interface_ops = { - .start = atalk_seq_interface_start, - .next = atalk_seq_interface_next, - .stop = atalk_seq_interface_stop, - .show = atalk_seq_interface_show, -}; - -static const struct seq_operations atalk_seq_route_ops = { - .start = atalk_seq_route_start, - .next = atalk_seq_route_next, - .stop = atalk_seq_route_stop, - .show = atalk_seq_route_show, -}; - -static const struct seq_operations atalk_seq_socket_ops = { - .start = atalk_seq_socket_start, - .next = atalk_seq_socket_next, - .stop = atalk_seq_socket_stop, - .show = atalk_seq_socket_show, -}; - -static int atalk_seq_interface_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &atalk_seq_interface_ops); -} - -static int atalk_seq_route_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &atalk_seq_route_ops); -} - -static int atalk_seq_socket_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &atalk_seq_socket_ops); -} - -static const struct file_operations atalk_seq_interface_fops = { - .owner = THIS_MODULE, - .open = atalk_seq_interface_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -static const struct file_operations atalk_seq_route_fops = { - .owner = THIS_MODULE, - .open = atalk_seq_route_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -static const struct file_operations atalk_seq_socket_fops = { - .owner = THIS_MODULE, - .open = atalk_seq_socket_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -static struct proc_dir_entry *atalk_proc_dir; - -int __init atalk_proc_init(void) -{ - struct proc_dir_entry *p; - int rc = -ENOMEM; - - atalk_proc_dir = proc_mkdir("atalk", init_net.proc_net); - if (!atalk_proc_dir) - goto out; - - p = proc_create("interface", S_IRUGO, atalk_proc_dir, - &atalk_seq_interface_fops); - if (!p) - goto out_interface; - - p = proc_create("route", S_IRUGO, atalk_proc_dir, - &atalk_seq_route_fops); - if (!p) - goto out_route; - - p = proc_create("socket", S_IRUGO, atalk_proc_dir, - &atalk_seq_socket_fops); - if (!p) - goto out_socket; - - p = proc_create("arp", S_IRUGO, atalk_proc_dir, &atalk_seq_arp_fops); - if (!p) - goto out_arp; - - rc = 0; -out: - return rc; -out_arp: - remove_proc_entry("socket", atalk_proc_dir); -out_socket: - remove_proc_entry("route", atalk_proc_dir); -out_route: - remove_proc_entry("interface", atalk_proc_dir); -out_interface: - remove_proc_entry("atalk", init_net.proc_net); - goto out; -} - -void __exit atalk_proc_exit(void) -{ - remove_proc_entry("interface", atalk_proc_dir); - remove_proc_entry("route", atalk_proc_dir); - remove_proc_entry("socket", atalk_proc_dir); - remove_proc_entry("arp", atalk_proc_dir); - remove_proc_entry("atalk", init_net.proc_net); -} diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c deleted file mode 100644 index c410b93fda2e..000000000000 --- a/net/appletalk/ddp.c +++ /dev/null @@ -1,1981 +0,0 @@ -/* - * DDP: An implementation of the AppleTalk DDP protocol for - * Ethernet 'ELAP'. - * - * Alan Cox - * - * With more than a little assistance from - * - * Wesley Craig - * - * Fixes: - * Neil Horman : Added missing device ioctls - * Michael Callahan : Made routing work - * Wesley Craig : Fix probing to listen to a - * passed node id. - * Alan Cox : Added send/recvmsg support - * Alan Cox : Moved at. to protinfo in - * socket. - * Alan Cox : Added firewall hooks. - * Alan Cox : Supports new ARPHRD_LOOPBACK - * Christer Weinigel : Routing and /proc fixes. - * Bradford Johnson : LocalTalk. - * Tom Dyas : Module support. - * Alan Cox : Hooks for PPP (based on the - * LocalTalk hook). - * Alan Cox : Posix bits - * Alan Cox/Mike Freeman : Possible fix to NBP problems - * Bradford Johnson : IP-over-DDP (experimental) - * Jay Schulist : Moved IP-over-DDP to its own - * driver file. (ipddp.c & ipddp.h) - * Jay Schulist : Made work as module with - * AppleTalk drivers, cleaned it. - * Rob Newberry : Added proxy AARP and AARP - * procfs, moved probing to AARP - * module. - * Adrian Sun/ - * Michael Zuelsdorff : fix for net.0 packets. don't - * allow illegal ether/tokentalk - * port assignment. we lose a - * valid localtalk port as a - * result. - * Arnaldo C. de Melo : Cleanup, in preparation for - * shared skb support 8) - * Arnaldo C. de Melo : Move proc stuff to atalk_proc.c, - * use seq_file - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#include -#include -#include -#include -#include /* For TIOCOUTQ/INQ */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "../core/kmap_skb.h" - -struct datalink_proto *ddp_dl, *aarp_dl; -static const struct proto_ops atalk_dgram_ops; - -/**************************************************************************\ -* * -* Handlers for the socket list. * -* * -\**************************************************************************/ - -HLIST_HEAD(atalk_sockets); -DEFINE_RWLOCK(atalk_sockets_lock); - -static inline void __atalk_insert_socket(struct sock *sk) -{ - sk_add_node(sk, &atalk_sockets); -} - -static inline void atalk_remove_socket(struct sock *sk) -{ - write_lock_bh(&atalk_sockets_lock); - sk_del_node_init(sk); - write_unlock_bh(&atalk_sockets_lock); -} - -static struct sock *atalk_search_socket(struct sockaddr_at *to, - struct atalk_iface *atif) -{ - struct sock *s; - struct hlist_node *node; - - read_lock_bh(&atalk_sockets_lock); - sk_for_each(s, node, &atalk_sockets) { - struct atalk_sock *at = at_sk(s); - - if (to->sat_port != at->src_port) - continue; - - if (to->sat_addr.s_net == ATADDR_ANYNET && - to->sat_addr.s_node == ATADDR_BCAST) - goto found; - - if (to->sat_addr.s_net == at->src_net && - (to->sat_addr.s_node == at->src_node || - to->sat_addr.s_node == ATADDR_BCAST || - to->sat_addr.s_node == ATADDR_ANYNODE)) - goto found; - - /* XXXX.0 -- we got a request for this router. make sure - * that the node is appropriately set. */ - if (to->sat_addr.s_node == ATADDR_ANYNODE && - to->sat_addr.s_net != ATADDR_ANYNET && - atif->address.s_node == at->src_node) { - to->sat_addr.s_node = atif->address.s_node; - goto found; - } - } - s = NULL; -found: - read_unlock_bh(&atalk_sockets_lock); - return s; -} - -/** - * atalk_find_or_insert_socket - Try to find a socket matching ADDR - * @sk - socket to insert in the list if it is not there already - * @sat - address to search for - * - * Try to find a socket matching ADDR in the socket list, if found then return - * it. If not, insert SK into the socket list. - * - * This entire operation must execute atomically. - */ -static struct sock *atalk_find_or_insert_socket(struct sock *sk, - struct sockaddr_at *sat) -{ - struct sock *s; - struct hlist_node *node; - struct atalk_sock *at; - - write_lock_bh(&atalk_sockets_lock); - sk_for_each(s, node, &atalk_sockets) { - at = at_sk(s); - - if (at->src_net == sat->sat_addr.s_net && - at->src_node == sat->sat_addr.s_node && - at->src_port == sat->sat_port) - goto found; - } - s = NULL; - __atalk_insert_socket(sk); /* Wheee, it's free, assign and insert. */ -found: - write_unlock_bh(&atalk_sockets_lock); - return s; -} - -static void atalk_destroy_timer(unsigned long data) -{ - struct sock *sk = (struct sock *)data; - - if (sk_has_allocations(sk)) { - sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; - add_timer(&sk->sk_timer); - } else - sock_put(sk); -} - -static inline void atalk_destroy_socket(struct sock *sk) -{ - atalk_remove_socket(sk); - skb_queue_purge(&sk->sk_receive_queue); - - if (sk_has_allocations(sk)) { - setup_timer(&sk->sk_timer, atalk_destroy_timer, - (unsigned long)sk); - sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; - add_timer(&sk->sk_timer); - } else - sock_put(sk); -} - -/**************************************************************************\ -* * -* Routing tables for the AppleTalk socket layer. * -* * -\**************************************************************************/ - -/* Anti-deadlock ordering is atalk_routes_lock --> iface_lock -DaveM */ -struct atalk_route *atalk_routes; -DEFINE_RWLOCK(atalk_routes_lock); - -struct atalk_iface *atalk_interfaces; -DEFINE_RWLOCK(atalk_interfaces_lock); - -/* For probing devices or in a routerless network */ -struct atalk_route atrtr_default; - -/* AppleTalk interface control */ -/* - * Drop a device. Doesn't drop any of its routes - that is the caller's - * problem. Called when we down the interface or delete the address. - */ -static void atif_drop_device(struct net_device *dev) -{ - struct atalk_iface **iface = &atalk_interfaces; - struct atalk_iface *tmp; - - write_lock_bh(&atalk_interfaces_lock); - while ((tmp = *iface) != NULL) { - if (tmp->dev == dev) { - *iface = tmp->next; - dev_put(dev); - kfree(tmp); - dev->atalk_ptr = NULL; - } else - iface = &tmp->next; - } - write_unlock_bh(&atalk_interfaces_lock); -} - -static struct atalk_iface *atif_add_device(struct net_device *dev, - struct atalk_addr *sa) -{ - struct atalk_iface *iface = kzalloc(sizeof(*iface), GFP_KERNEL); - - if (!iface) - goto out; - - dev_hold(dev); - iface->dev = dev; - dev->atalk_ptr = iface; - iface->address = *sa; - iface->status = 0; - - write_lock_bh(&atalk_interfaces_lock); - iface->next = atalk_interfaces; - atalk_interfaces = iface; - write_unlock_bh(&atalk_interfaces_lock); -out: - return iface; -} - -/* Perform phase 2 AARP probing on our tentative address */ -static int atif_probe_device(struct atalk_iface *atif) -{ - int netrange = ntohs(atif->nets.nr_lastnet) - - ntohs(atif->nets.nr_firstnet) + 1; - int probe_net = ntohs(atif->address.s_net); - int probe_node = atif->address.s_node; - int netct, nodect; - - /* Offset the network we start probing with */ - if (probe_net == ATADDR_ANYNET) { - probe_net = ntohs(atif->nets.nr_firstnet); - if (netrange) - probe_net += jiffies % netrange; - } - if (probe_node == ATADDR_ANYNODE) - probe_node = jiffies & 0xFF; - - /* Scan the networks */ - atif->status |= ATIF_PROBE; - for (netct = 0; netct <= netrange; netct++) { - /* Sweep the available nodes from a given start */ - atif->address.s_net = htons(probe_net); - for (nodect = 0; nodect < 256; nodect++) { - atif->address.s_node = (nodect + probe_node) & 0xFF; - if (atif->address.s_node > 0 && - atif->address.s_node < 254) { - /* Probe a proposed address */ - aarp_probe_network(atif); - - if (!(atif->status & ATIF_PROBE_FAIL)) { - atif->status &= ~ATIF_PROBE; - return 0; - } - } - atif->status &= ~ATIF_PROBE_FAIL; - } - probe_net++; - if (probe_net > ntohs(atif->nets.nr_lastnet)) - probe_net = ntohs(atif->nets.nr_firstnet); - } - atif->status &= ~ATIF_PROBE; - - return -EADDRINUSE; /* Network is full... */ -} - - -/* Perform AARP probing for a proxy address */ -static int atif_proxy_probe_device(struct atalk_iface *atif, - struct atalk_addr* proxy_addr) -{ - int netrange = ntohs(atif->nets.nr_lastnet) - - ntohs(atif->nets.nr_firstnet) + 1; - /* we probe the interface's network */ - int probe_net = ntohs(atif->address.s_net); - int probe_node = ATADDR_ANYNODE; /* we'll take anything */ - int netct, nodect; - - /* Offset the network we start probing with */ - if (probe_net == ATADDR_ANYNET) { - probe_net = ntohs(atif->nets.nr_firstnet); - if (netrange) - probe_net += jiffies % netrange; - } - - if (probe_node == ATADDR_ANYNODE) - probe_node = jiffies & 0xFF; - - /* Scan the networks */ - for (netct = 0; netct <= netrange; netct++) { - /* Sweep the available nodes from a given start */ - proxy_addr->s_net = htons(probe_net); - for (nodect = 0; nodect < 256; nodect++) { - proxy_addr->s_node = (nodect + probe_node) & 0xFF; - if (proxy_addr->s_node > 0 && - proxy_addr->s_node < 254) { - /* Tell AARP to probe a proposed address */ - int ret = aarp_proxy_probe_network(atif, - proxy_addr); - - if (ret != -EADDRINUSE) - return ret; - } - } - probe_net++; - if (probe_net > ntohs(atif->nets.nr_lastnet)) - probe_net = ntohs(atif->nets.nr_firstnet); - } - - return -EADDRINUSE; /* Network is full... */ -} - - -struct atalk_addr *atalk_find_dev_addr(struct net_device *dev) -{ - struct atalk_iface *iface = dev->atalk_ptr; - return iface ? &iface->address : NULL; -} - -static struct atalk_addr *atalk_find_primary(void) -{ - struct atalk_iface *fiface = NULL; - struct atalk_addr *retval; - struct atalk_iface *iface; - - /* - * Return a point-to-point interface only if - * there is no non-ptp interface available. - */ - read_lock_bh(&atalk_interfaces_lock); - for (iface = atalk_interfaces; iface; iface = iface->next) { - if (!fiface && !(iface->dev->flags & IFF_LOOPBACK)) - fiface = iface; - if (!(iface->dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) { - retval = &iface->address; - goto out; - } - } - - if (fiface) - retval = &fiface->address; - else if (atalk_interfaces) - retval = &atalk_interfaces->address; - else - retval = NULL; -out: - read_unlock_bh(&atalk_interfaces_lock); - return retval; -} - -/* - * Find a match for 'any network' - ie any of our interfaces with that - * node number will do just nicely. - */ -static struct atalk_iface *atalk_find_anynet(int node, struct net_device *dev) -{ - struct atalk_iface *iface = dev->atalk_ptr; - - if (!iface || iface->status & ATIF_PROBE) - goto out_err; - - if (node != ATADDR_BCAST && - iface->address.s_node != node && - node != ATADDR_ANYNODE) - goto out_err; -out: - return iface; -out_err: - iface = NULL; - goto out; -} - -/* Find a match for a specific network:node pair */ -static struct atalk_iface *atalk_find_interface(__be16 net, int node) -{ - struct atalk_iface *iface; - - read_lock_bh(&atalk_interfaces_lock); - for (iface = atalk_interfaces; iface; iface = iface->next) { - if ((node == ATADDR_BCAST || - node == ATADDR_ANYNODE || - iface->address.s_node == node) && - iface->address.s_net == net && - !(iface->status & ATIF_PROBE)) - break; - - /* XXXX.0 -- net.0 returns the iface associated with net */ - if (node == ATADDR_ANYNODE && net != ATADDR_ANYNET && - ntohs(iface->nets.nr_firstnet) <= ntohs(net) && - ntohs(net) <= ntohs(iface->nets.nr_lastnet)) - break; - } - read_unlock_bh(&atalk_interfaces_lock); - return iface; -} - - -/* - * Find a route for an AppleTalk packet. This ought to get cached in - * the socket (later on...). We know about host routes and the fact - * that a route must be direct to broadcast. - */ -static struct atalk_route *atrtr_find(struct atalk_addr *target) -{ - /* - * we must search through all routes unless we find a - * host route, because some host routes might overlap - * network routes - */ - struct atalk_route *net_route = NULL; - struct atalk_route *r; - - read_lock_bh(&atalk_routes_lock); - for (r = atalk_routes; r; r = r->next) { - if (!(r->flags & RTF_UP)) - continue; - - if (r->target.s_net == target->s_net) { - if (r->flags & RTF_HOST) { - /* - * if this host route is for the target, - * the we're done - */ - if (r->target.s_node == target->s_node) - goto out; - } else - /* - * this route will work if there isn't a - * direct host route, so cache it - */ - net_route = r; - } - } - - /* - * if we found a network route but not a direct host - * route, then return it - */ - if (net_route) - r = net_route; - else if (atrtr_default.dev) - r = &atrtr_default; - else /* No route can be found */ - r = NULL; -out: - read_unlock_bh(&atalk_routes_lock); - return r; -} - - -/* - * Given an AppleTalk network, find the device to use. This can be - * a simple lookup. - */ -struct net_device *atrtr_get_dev(struct atalk_addr *sa) -{ - struct atalk_route *atr = atrtr_find(sa); - return atr ? atr->dev : NULL; -} - -/* Set up a default router */ -static void atrtr_set_default(struct net_device *dev) -{ - atrtr_default.dev = dev; - atrtr_default.flags = RTF_UP; - atrtr_default.gateway.s_net = htons(0); - atrtr_default.gateway.s_node = 0; -} - -/* - * Add a router. Basically make sure it looks valid and stuff the - * entry in the list. While it uses netranges we always set them to one - * entry to work like netatalk. - */ -static int atrtr_create(struct rtentry *r, struct net_device *devhint) -{ - struct sockaddr_at *ta = (struct sockaddr_at *)&r->rt_dst; - struct sockaddr_at *ga = (struct sockaddr_at *)&r->rt_gateway; - struct atalk_route *rt; - struct atalk_iface *iface, *riface; - int retval = -EINVAL; - - /* - * Fixme: Raise/Lower a routing change semaphore for these - * operations. - */ - - /* Validate the request */ - if (ta->sat_family != AF_APPLETALK || - (!devhint && ga->sat_family != AF_APPLETALK)) - goto out; - - /* Now walk the routing table and make our decisions */ - write_lock_bh(&atalk_routes_lock); - for (rt = atalk_routes; rt; rt = rt->next) { - if (r->rt_flags != rt->flags) - continue; - - if (ta->sat_addr.s_net == rt->target.s_net) { - if (!(rt->flags & RTF_HOST)) - break; - if (ta->sat_addr.s_node == rt->target.s_node) - break; - } - } - - if (!devhint) { - riface = NULL; - - read_lock_bh(&atalk_interfaces_lock); - for (iface = atalk_interfaces; iface; iface = iface->next) { - if (!riface && - ntohs(ga->sat_addr.s_net) >= - ntohs(iface->nets.nr_firstnet) && - ntohs(ga->sat_addr.s_net) <= - ntohs(iface->nets.nr_lastnet)) - riface = iface; - - if (ga->sat_addr.s_net == iface->address.s_net && - ga->sat_addr.s_node == iface->address.s_node) - riface = iface; - } - read_unlock_bh(&atalk_interfaces_lock); - - retval = -ENETUNREACH; - if (!riface) - goto out_unlock; - - devhint = riface->dev; - } - - if (!rt) { - rt = kzalloc(sizeof(*rt), GFP_ATOMIC); - - retval = -ENOBUFS; - if (!rt) - goto out_unlock; - - rt->next = atalk_routes; - atalk_routes = rt; - } - - /* Fill in the routing entry */ - rt->target = ta->sat_addr; - dev_hold(devhint); - rt->dev = devhint; - rt->flags = r->rt_flags; - rt->gateway = ga->sat_addr; - - retval = 0; -out_unlock: - write_unlock_bh(&atalk_routes_lock); -out: - return retval; -} - -/* Delete a route. Find it and discard it */ -static int atrtr_delete(struct atalk_addr * addr) -{ - struct atalk_route **r = &atalk_routes; - int retval = 0; - struct atalk_route *tmp; - - write_lock_bh(&atalk_routes_lock); - while ((tmp = *r) != NULL) { - if (tmp->target.s_net == addr->s_net && - (!(tmp->flags&RTF_GATEWAY) || - tmp->target.s_node == addr->s_node)) { - *r = tmp->next; - dev_put(tmp->dev); - kfree(tmp); - goto out; - } - r = &tmp->next; - } - retval = -ENOENT; -out: - write_unlock_bh(&atalk_routes_lock); - return retval; -} - -/* - * Called when a device is downed. Just throw away any routes - * via it. - */ -static void atrtr_device_down(struct net_device *dev) -{ - struct atalk_route **r = &atalk_routes; - struct atalk_route *tmp; - - write_lock_bh(&atalk_routes_lock); - while ((tmp = *r) != NULL) { - if (tmp->dev == dev) { - *r = tmp->next; - dev_put(dev); - kfree(tmp); - } else - r = &tmp->next; - } - write_unlock_bh(&atalk_routes_lock); - - if (atrtr_default.dev == dev) - atrtr_set_default(NULL); -} - -/* Actually down the interface */ -static inline void atalk_dev_down(struct net_device *dev) -{ - atrtr_device_down(dev); /* Remove all routes for the device */ - aarp_device_down(dev); /* Remove AARP entries for the device */ - atif_drop_device(dev); /* Remove the device */ -} - -/* - * A device event has occurred. Watch for devices going down and - * delete our use of them (iface and route). - */ -static int ddp_device_event(struct notifier_block *this, unsigned long event, - void *ptr) -{ - struct net_device *dev = ptr; - - if (!net_eq(dev_net(dev), &init_net)) - return NOTIFY_DONE; - - if (event == NETDEV_DOWN) - /* Discard any use of this */ - atalk_dev_down(dev); - - return NOTIFY_DONE; -} - -/* ioctl calls. Shouldn't even need touching */ -/* Device configuration ioctl calls */ -static int atif_ioctl(int cmd, void __user *arg) -{ - static char aarp_mcast[6] = { 0x09, 0x00, 0x00, 0xFF, 0xFF, 0xFF }; - struct ifreq atreq; - struct atalk_netrange *nr; - struct sockaddr_at *sa; - struct net_device *dev; - struct atalk_iface *atif; - int ct; - int limit; - struct rtentry rtdef; - int add_route; - - if (copy_from_user(&atreq, arg, sizeof(atreq))) - return -EFAULT; - - dev = __dev_get_by_name(&init_net, atreq.ifr_name); - if (!dev) - return -ENODEV; - - sa = (struct sockaddr_at *)&atreq.ifr_addr; - atif = atalk_find_dev(dev); - - switch (cmd) { - case SIOCSIFADDR: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (sa->sat_family != AF_APPLETALK) - return -EINVAL; - if (dev->type != ARPHRD_ETHER && - dev->type != ARPHRD_LOOPBACK && - dev->type != ARPHRD_LOCALTLK && - dev->type != ARPHRD_PPP) - return -EPROTONOSUPPORT; - - nr = (struct atalk_netrange *)&sa->sat_zero[0]; - add_route = 1; - - /* - * if this is a point-to-point iface, and we already - * have an iface for this AppleTalk address, then we - * should not add a route - */ - if ((dev->flags & IFF_POINTOPOINT) && - atalk_find_interface(sa->sat_addr.s_net, - sa->sat_addr.s_node)) { - printk(KERN_DEBUG "AppleTalk: point-to-point " - "interface added with " - "existing address\n"); - add_route = 0; - } - - /* - * Phase 1 is fine on LocalTalk but we don't do - * EtherTalk phase 1. Anyone wanting to add it go ahead. - */ - if (dev->type == ARPHRD_ETHER && nr->nr_phase != 2) - return -EPROTONOSUPPORT; - if (sa->sat_addr.s_node == ATADDR_BCAST || - sa->sat_addr.s_node == 254) - return -EINVAL; - if (atif) { - /* Already setting address */ - if (atif->status & ATIF_PROBE) - return -EBUSY; - - atif->address.s_net = sa->sat_addr.s_net; - atif->address.s_node = sa->sat_addr.s_node; - atrtr_device_down(dev); /* Flush old routes */ - } else { - atif = atif_add_device(dev, &sa->sat_addr); - if (!atif) - return -ENOMEM; - } - atif->nets = *nr; - - /* - * Check if the chosen address is used. If so we - * error and atalkd will try another. - */ - - if (!(dev->flags & IFF_LOOPBACK) && - !(dev->flags & IFF_POINTOPOINT) && - atif_probe_device(atif) < 0) { - atif_drop_device(dev); - return -EADDRINUSE; - } - - /* Hey it worked - add the direct routes */ - sa = (struct sockaddr_at *)&rtdef.rt_gateway; - sa->sat_family = AF_APPLETALK; - sa->sat_addr.s_net = atif->address.s_net; - sa->sat_addr.s_node = atif->address.s_node; - sa = (struct sockaddr_at *)&rtdef.rt_dst; - rtdef.rt_flags = RTF_UP; - sa->sat_family = AF_APPLETALK; - sa->sat_addr.s_node = ATADDR_ANYNODE; - if (dev->flags & IFF_LOOPBACK || - dev->flags & IFF_POINTOPOINT) - rtdef.rt_flags |= RTF_HOST; - - /* Routerless initial state */ - if (nr->nr_firstnet == htons(0) && - nr->nr_lastnet == htons(0xFFFE)) { - sa->sat_addr.s_net = atif->address.s_net; - atrtr_create(&rtdef, dev); - atrtr_set_default(dev); - } else { - limit = ntohs(nr->nr_lastnet); - if (limit - ntohs(nr->nr_firstnet) > 4096) { - printk(KERN_WARNING "Too many routes/" - "iface.\n"); - return -EINVAL; - } - if (add_route) - for (ct = ntohs(nr->nr_firstnet); - ct <= limit; ct++) { - sa->sat_addr.s_net = htons(ct); - atrtr_create(&rtdef, dev); - } - } - dev_mc_add_global(dev, aarp_mcast); - return 0; - - case SIOCGIFADDR: - if (!atif) - return -EADDRNOTAVAIL; - - sa->sat_family = AF_APPLETALK; - sa->sat_addr = atif->address; - break; - - case SIOCGIFBRDADDR: - if (!atif) - return -EADDRNOTAVAIL; - - sa->sat_family = AF_APPLETALK; - sa->sat_addr.s_net = atif->address.s_net; - sa->sat_addr.s_node = ATADDR_BCAST; - break; - - case SIOCATALKDIFADDR: - case SIOCDIFADDR: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (sa->sat_family != AF_APPLETALK) - return -EINVAL; - atalk_dev_down(dev); - break; - - case SIOCSARP: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (sa->sat_family != AF_APPLETALK) - return -EINVAL; - /* - * for now, we only support proxy AARP on ELAP; - * we should be able to do it for LocalTalk, too. - */ - if (dev->type != ARPHRD_ETHER) - return -EPROTONOSUPPORT; - - /* - * atif points to the current interface on this network; - * we aren't concerned about its current status (at - * least for now), but it has all the settings about - * the network we're going to probe. Consequently, it - * must exist. - */ - if (!atif) - return -EADDRNOTAVAIL; - - nr = (struct atalk_netrange *)&(atif->nets); - /* - * Phase 1 is fine on Localtalk but we don't do - * Ethertalk phase 1. Anyone wanting to add it go ahead. - */ - if (dev->type == ARPHRD_ETHER && nr->nr_phase != 2) - return -EPROTONOSUPPORT; - - if (sa->sat_addr.s_node == ATADDR_BCAST || - sa->sat_addr.s_node == 254) - return -EINVAL; - - /* - * Check if the chosen address is used. If so we - * error and ATCP will try another. - */ - if (atif_proxy_probe_device(atif, &(sa->sat_addr)) < 0) - return -EADDRINUSE; - - /* - * We now have an address on the local network, and - * the AARP code will defend it for us until we take it - * down. We don't set up any routes right now, because - * ATCP will install them manually via SIOCADDRT. - */ - break; - - case SIOCDARP: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (sa->sat_family != AF_APPLETALK) - return -EINVAL; - if (!atif) - return -EADDRNOTAVAIL; - - /* give to aarp module to remove proxy entry */ - aarp_proxy_remove(atif->dev, &(sa->sat_addr)); - return 0; - } - - return copy_to_user(arg, &atreq, sizeof(atreq)) ? -EFAULT : 0; -} - -/* Routing ioctl() calls */ -static int atrtr_ioctl(unsigned int cmd, void __user *arg) -{ - struct rtentry rt; - - if (copy_from_user(&rt, arg, sizeof(rt))) - return -EFAULT; - - switch (cmd) { - case SIOCDELRT: - if (rt.rt_dst.sa_family != AF_APPLETALK) - return -EINVAL; - return atrtr_delete(&((struct sockaddr_at *) - &rt.rt_dst)->sat_addr); - - case SIOCADDRT: { - struct net_device *dev = NULL; - if (rt.rt_dev) { - char name[IFNAMSIZ]; - if (copy_from_user(name, rt.rt_dev, IFNAMSIZ-1)) - return -EFAULT; - name[IFNAMSIZ-1] = '\0'; - dev = __dev_get_by_name(&init_net, name); - if (!dev) - return -ENODEV; - } - return atrtr_create(&rt, dev); - } - } - return -EINVAL; -} - -/**************************************************************************\ -* * -* Handling for system calls applied via the various interfaces to an * -* AppleTalk socket object. * -* * -\**************************************************************************/ - -/* - * Checksum: This is 'optional'. It's quite likely also a good - * candidate for assembler hackery 8) - */ -static unsigned long atalk_sum_partial(const unsigned char *data, - int len, unsigned long sum) -{ - /* This ought to be unwrapped neatly. I'll trust gcc for now */ - while (len--) { - sum += *data++; - sum = rol16(sum, 1); - } - return sum; -} - -/* Checksum skb data -- similar to skb_checksum */ -static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, - int len, unsigned long sum) -{ - int start = skb_headlen(skb); - struct sk_buff *frag_iter; - int i, copy; - - /* checksum stuff in header space */ - if ( (copy = start - offset) > 0) { - if (copy > len) - copy = len; - sum = atalk_sum_partial(skb->data + offset, copy, sum); - if ( (len -= copy) == 0) - return sum; - - offset += copy; - } - - /* checksum stuff in frags */ - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - int end; - - WARN_ON(start > offset + len); - - end = start + skb_shinfo(skb)->frags[i].size; - if ((copy = end - offset) > 0) { - u8 *vaddr; - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - - if (copy > len) - copy = len; - vaddr = kmap_skb_frag(frag); - sum = atalk_sum_partial(vaddr + frag->page_offset + - offset - start, copy, sum); - kunmap_skb_frag(vaddr); - - if (!(len -= copy)) - return sum; - offset += copy; - } - start = end; - } - - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); - - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - sum = atalk_sum_skb(frag_iter, offset - start, - copy, sum); - if ((len -= copy) == 0) - return sum; - offset += copy; - } - start = end; - } - - BUG_ON(len > 0); - - return sum; -} - -static __be16 atalk_checksum(const struct sk_buff *skb, int len) -{ - unsigned long sum; - - /* skip header 4 bytes */ - sum = atalk_sum_skb(skb, 4, len-4, 0); - - /* Use 0xFFFF for 0. 0 itself means none */ - return sum ? htons((unsigned short)sum) : htons(0xFFFF); -} - -static struct proto ddp_proto = { - .name = "DDP", - .owner = THIS_MODULE, - .obj_size = sizeof(struct atalk_sock), -}; - -/* - * Create a socket. Initialise the socket, blank the addresses - * set the state. - */ -static int atalk_create(struct net *net, struct socket *sock, int protocol, - int kern) -{ - struct sock *sk; - int rc = -ESOCKTNOSUPPORT; - - if (!net_eq(net, &init_net)) - return -EAFNOSUPPORT; - - /* - * We permit SOCK_DGRAM and RAW is an extension. It is trivial to do - * and gives you the full ELAP frame. Should be handy for CAP 8) - */ - if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM) - goto out; - rc = -ENOMEM; - sk = sk_alloc(net, PF_APPLETALK, GFP_KERNEL, &ddp_proto); - if (!sk) - goto out; - rc = 0; - sock->ops = &atalk_dgram_ops; - sock_init_data(sock, sk); - - /* Checksums on by default */ - sock_set_flag(sk, SOCK_ZAPPED); -out: - return rc; -} - -/* Free a socket. No work needed */ -static int atalk_release(struct socket *sock) -{ - struct sock *sk = sock->sk; - - lock_kernel(); - if (sk) { - sock_orphan(sk); - sock->sk = NULL; - atalk_destroy_socket(sk); - } - unlock_kernel(); - return 0; -} - -/** - * atalk_pick_and_bind_port - Pick a source port when one is not given - * @sk - socket to insert into the tables - * @sat - address to search for - * - * Pick a source port when one is not given. If we can find a suitable free - * one, we insert the socket into the tables using it. - * - * This whole operation must be atomic. - */ -static int atalk_pick_and_bind_port(struct sock *sk, struct sockaddr_at *sat) -{ - int retval; - - write_lock_bh(&atalk_sockets_lock); - - for (sat->sat_port = ATPORT_RESERVED; - sat->sat_port < ATPORT_LAST; - sat->sat_port++) { - struct sock *s; - struct hlist_node *node; - - sk_for_each(s, node, &atalk_sockets) { - struct atalk_sock *at = at_sk(s); - - if (at->src_net == sat->sat_addr.s_net && - at->src_node == sat->sat_addr.s_node && - at->src_port == sat->sat_port) - goto try_next_port; - } - - /* Wheee, it's free, assign and insert. */ - __atalk_insert_socket(sk); - at_sk(sk)->src_port = sat->sat_port; - retval = 0; - goto out; - -try_next_port:; - } - - retval = -EBUSY; -out: - write_unlock_bh(&atalk_sockets_lock); - return retval; -} - -static int atalk_autobind(struct sock *sk) -{ - struct atalk_sock *at = at_sk(sk); - struct sockaddr_at sat; - struct atalk_addr *ap = atalk_find_primary(); - int n = -EADDRNOTAVAIL; - - if (!ap || ap->s_net == htons(ATADDR_ANYNET)) - goto out; - - at->src_net = sat.sat_addr.s_net = ap->s_net; - at->src_node = sat.sat_addr.s_node = ap->s_node; - - n = atalk_pick_and_bind_port(sk, &sat); - if (!n) - sock_reset_flag(sk, SOCK_ZAPPED); -out: - return n; -} - -/* Set the address 'our end' of the connection */ -static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) -{ - struct sockaddr_at *addr = (struct sockaddr_at *)uaddr; - struct sock *sk = sock->sk; - struct atalk_sock *at = at_sk(sk); - int err; - - if (!sock_flag(sk, SOCK_ZAPPED) || - addr_len != sizeof(struct sockaddr_at)) - return -EINVAL; - - if (addr->sat_family != AF_APPLETALK) - return -EAFNOSUPPORT; - - lock_kernel(); - if (addr->sat_addr.s_net == htons(ATADDR_ANYNET)) { - struct atalk_addr *ap = atalk_find_primary(); - - err = -EADDRNOTAVAIL; - if (!ap) - goto out; - - at->src_net = addr->sat_addr.s_net = ap->s_net; - at->src_node = addr->sat_addr.s_node= ap->s_node; - } else { - err = -EADDRNOTAVAIL; - if (!atalk_find_interface(addr->sat_addr.s_net, - addr->sat_addr.s_node)) - goto out; - - at->src_net = addr->sat_addr.s_net; - at->src_node = addr->sat_addr.s_node; - } - - if (addr->sat_port == ATADDR_ANYPORT) { - err = atalk_pick_and_bind_port(sk, addr); - - if (err < 0) - goto out; - } else { - at->src_port = addr->sat_port; - - err = -EADDRINUSE; - if (atalk_find_or_insert_socket(sk, addr)) - goto out; - } - - sock_reset_flag(sk, SOCK_ZAPPED); - err = 0; -out: - unlock_kernel(); - return err; -} - -/* Set the address we talk to */ -static int atalk_connect(struct socket *sock, struct sockaddr *uaddr, - int addr_len, int flags) -{ - struct sock *sk = sock->sk; - struct atalk_sock *at = at_sk(sk); - struct sockaddr_at *addr; - int err; - - sk->sk_state = TCP_CLOSE; - sock->state = SS_UNCONNECTED; - - if (addr_len != sizeof(*addr)) - return -EINVAL; - - addr = (struct sockaddr_at *)uaddr; - - if (addr->sat_family != AF_APPLETALK) - return -EAFNOSUPPORT; - - if (addr->sat_addr.s_node == ATADDR_BCAST && - !sock_flag(sk, SOCK_BROADCAST)) { -#if 1 - printk(KERN_WARNING "%s is broken and did not set " - "SO_BROADCAST. It will break when 2.2 is " - "released.\n", - current->comm); -#else - return -EACCES; -#endif - } - - lock_kernel(); - err = -EBUSY; - if (sock_flag(sk, SOCK_ZAPPED)) - if (atalk_autobind(sk) < 0) - goto out; - - err = -ENETUNREACH; - if (!atrtr_get_dev(&addr->sat_addr)) - goto out; - - at->dest_port = addr->sat_port; - at->dest_net = addr->sat_addr.s_net; - at->dest_node = addr->sat_addr.s_node; - - sock->state = SS_CONNECTED; - sk->sk_state = TCP_ESTABLISHED; - err = 0; -out: - unlock_kernel(); - return err; -} - -/* - * Find the name of an AppleTalk socket. Just copy the right - * fields into the sockaddr. - */ -static int atalk_getname(struct socket *sock, struct sockaddr *uaddr, - int *uaddr_len, int peer) -{ - struct sockaddr_at sat; - struct sock *sk = sock->sk; - struct atalk_sock *at = at_sk(sk); - int err; - - lock_kernel(); - err = -ENOBUFS; - if (sock_flag(sk, SOCK_ZAPPED)) - if (atalk_autobind(sk) < 0) - goto out; - - *uaddr_len = sizeof(struct sockaddr_at); - memset(&sat.sat_zero, 0, sizeof(sat.sat_zero)); - - if (peer) { - err = -ENOTCONN; - if (sk->sk_state != TCP_ESTABLISHED) - goto out; - - sat.sat_addr.s_net = at->dest_net; - sat.sat_addr.s_node = at->dest_node; - sat.sat_port = at->dest_port; - } else { - sat.sat_addr.s_net = at->src_net; - sat.sat_addr.s_node = at->src_node; - sat.sat_port = at->src_port; - } - - err = 0; - sat.sat_family = AF_APPLETALK; - memcpy(uaddr, &sat, sizeof(sat)); - -out: - unlock_kernel(); - return err; -} - -static unsigned int atalk_poll(struct file *file, struct socket *sock, - poll_table *wait) -{ - int err; - lock_kernel(); - err = datagram_poll(file, sock, wait); - unlock_kernel(); - return err; -} - -#if defined(CONFIG_IPDDP) || defined(CONFIG_IPDDP_MODULE) -static __inline__ int is_ip_over_ddp(struct sk_buff *skb) -{ - return skb->data[12] == 22; -} - -static int handle_ip_over_ddp(struct sk_buff *skb) -{ - struct net_device *dev = __dev_get_by_name(&init_net, "ipddp0"); - struct net_device_stats *stats; - - /* This needs to be able to handle ipddp"N" devices */ - if (!dev) { - kfree_skb(skb); - return NET_RX_DROP; - } - - skb->protocol = htons(ETH_P_IP); - skb_pull(skb, 13); - skb->dev = dev; - skb_reset_transport_header(skb); - - stats = netdev_priv(dev); - stats->rx_packets++; - stats->rx_bytes += skb->len + 13; - return netif_rx(skb); /* Send the SKB up to a higher place. */ -} -#else -/* make it easy for gcc to optimize this test out, i.e. kill the code */ -#define is_ip_over_ddp(skb) 0 -#define handle_ip_over_ddp(skb) 0 -#endif - -static int atalk_route_packet(struct sk_buff *skb, struct net_device *dev, - struct ddpehdr *ddp, __u16 len_hops, int origlen) -{ - struct atalk_route *rt; - struct atalk_addr ta; - - /* - * Don't route multicast, etc., packets, or packets sent to "this - * network" - */ - if (skb->pkt_type != PACKET_HOST || !ddp->deh_dnet) { - /* - * FIXME: - * - * Can it ever happen that a packet is from a PPP iface and - * needs to be broadcast onto the default network? - */ - if (dev->type == ARPHRD_PPP) - printk(KERN_DEBUG "AppleTalk: didn't forward broadcast " - "packet received from PPP iface\n"); - goto free_it; - } - - ta.s_net = ddp->deh_dnet; - ta.s_node = ddp->deh_dnode; - - /* Route the packet */ - rt = atrtr_find(&ta); - /* increment hops count */ - len_hops += 1 << 10; - if (!rt || !(len_hops & (15 << 10))) - goto free_it; - - /* FIXME: use skb->cb to be able to use shared skbs */ - - /* - * Route goes through another gateway, so set the target to the - * gateway instead. - */ - - if (rt->flags & RTF_GATEWAY) { - ta.s_net = rt->gateway.s_net; - ta.s_node = rt->gateway.s_node; - } - - /* Fix up skb->len field */ - skb_trim(skb, min_t(unsigned int, origlen, - (rt->dev->hard_header_len + - ddp_dl->header_length + (len_hops & 1023)))); - - /* FIXME: use skb->cb to be able to use shared skbs */ - ddp->deh_len_hops = htons(len_hops); - - /* - * Send the buffer onwards - * - * Now we must always be careful. If it's come from LocalTalk to - * EtherTalk it might not fit - * - * Order matters here: If a packet has to be copied to make a new - * headroom (rare hopefully) then it won't need unsharing. - * - * Note. ddp-> becomes invalid at the realloc. - */ - if (skb_headroom(skb) < 22) { - /* 22 bytes - 12 ether, 2 len, 3 802.2 5 snap */ - struct sk_buff *nskb = skb_realloc_headroom(skb, 32); - kfree_skb(skb); - skb = nskb; - } else - skb = skb_unshare(skb, GFP_ATOMIC); - - /* - * If the buffer didn't vanish into the lack of space bitbucket we can - * send it. - */ - if (skb == NULL) - goto drop; - - if (aarp_send_ddp(rt->dev, skb, &ta, NULL) == NET_XMIT_DROP) - return NET_RX_DROP; - return NET_RX_SUCCESS; -free_it: - kfree_skb(skb); -drop: - return NET_RX_DROP; -} - -/** - * atalk_rcv - Receive a packet (in skb) from device dev - * @skb - packet received - * @dev - network device where the packet comes from - * @pt - packet type - * - * Receive a packet (in skb) from device dev. This has come from the SNAP - * decoder, and on entry skb->transport_header is the DDP header, skb->len - * is the DDP header, skb->len is the DDP length. The physical headers - * have been extracted. PPP should probably pass frames marked as for this - * layer. [ie ARPHRD_ETHERTALK] - */ -static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, struct net_device *orig_dev) -{ - struct ddpehdr *ddp; - struct sock *sock; - struct atalk_iface *atif; - struct sockaddr_at tosat; - int origlen; - __u16 len_hops; - - if (!net_eq(dev_net(dev), &init_net)) - goto drop; - - /* Don't mangle buffer if shared */ - if (!(skb = skb_share_check(skb, GFP_ATOMIC))) - goto out; - - /* Size check and make sure header is contiguous */ - if (!pskb_may_pull(skb, sizeof(*ddp))) - goto drop; - - ddp = ddp_hdr(skb); - - len_hops = ntohs(ddp->deh_len_hops); - - /* Trim buffer in case of stray trailing data */ - origlen = skb->len; - skb_trim(skb, min_t(unsigned int, skb->len, len_hops & 1023)); - - /* - * Size check to see if ddp->deh_len was crap - * (Otherwise we'll detonate most spectacularly - * in the middle of atalk_checksum() or recvmsg()). - */ - if (skb->len < sizeof(*ddp) || skb->len < (len_hops & 1023)) { - pr_debug("AppleTalk: dropping corrupted frame (deh_len=%u, " - "skb->len=%u)\n", len_hops & 1023, skb->len); - goto drop; - } - - /* - * Any checksums. Note we don't do htons() on this == is assumed to be - * valid for net byte orders all over the networking code... - */ - if (ddp->deh_sum && - atalk_checksum(skb, len_hops & 1023) != ddp->deh_sum) - /* Not a valid AppleTalk frame - dustbin time */ - goto drop; - - /* Check the packet is aimed at us */ - if (!ddp->deh_dnet) /* Net 0 is 'this network' */ - atif = atalk_find_anynet(ddp->deh_dnode, dev); - else - atif = atalk_find_interface(ddp->deh_dnet, ddp->deh_dnode); - - if (!atif) { - /* Not ours, so we route the packet via the correct - * AppleTalk iface - */ - return atalk_route_packet(skb, dev, ddp, len_hops, origlen); - } - - /* if IP over DDP is not selected this code will be optimized out */ - if (is_ip_over_ddp(skb)) - return handle_ip_over_ddp(skb); - /* - * Which socket - atalk_search_socket() looks for a *full match* - * of the tuple. - */ - tosat.sat_addr.s_net = ddp->deh_dnet; - tosat.sat_addr.s_node = ddp->deh_dnode; - tosat.sat_port = ddp->deh_dport; - - sock = atalk_search_socket(&tosat, atif); - if (!sock) /* But not one of our sockets */ - goto drop; - - /* Queue packet (standard) */ - skb->sk = sock; - - if (sock_queue_rcv_skb(sock, skb) < 0) - goto drop; - - return NET_RX_SUCCESS; - -drop: - kfree_skb(skb); -out: - return NET_RX_DROP; - -} - -/* - * Receive a LocalTalk frame. We make some demands on the caller here. - * Caller must provide enough headroom on the packet to pull the short - * header and append a long one. - */ -static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, struct net_device *orig_dev) -{ - if (!net_eq(dev_net(dev), &init_net)) - goto freeit; - - /* Expand any short form frames */ - if (skb_mac_header(skb)[2] == 1) { - struct ddpehdr *ddp; - /* Find our address */ - struct atalk_addr *ap = atalk_find_dev_addr(dev); - - if (!ap || skb->len < sizeof(__be16) || skb->len > 1023) - goto freeit; - - /* Don't mangle buffer if shared */ - if (!(skb = skb_share_check(skb, GFP_ATOMIC))) - return 0; - - /* - * The push leaves us with a ddephdr not an shdr, and - * handily the port bytes in the right place preset. - */ - ddp = (struct ddpehdr *) skb_push(skb, sizeof(*ddp) - 4); - - /* Now fill in the long header */ - - /* - * These two first. The mac overlays the new source/dest - * network information so we MUST copy these before - * we write the network numbers ! - */ - - ddp->deh_dnode = skb_mac_header(skb)[0]; /* From physical header */ - ddp->deh_snode = skb_mac_header(skb)[1]; /* From physical header */ - - ddp->deh_dnet = ap->s_net; /* Network number */ - ddp->deh_snet = ap->s_net; - ddp->deh_sum = 0; /* No checksum */ - /* - * Not sure about this bit... - */ - /* Non routable, so force a drop if we slip up later */ - ddp->deh_len_hops = htons(skb->len + (DDP_MAXHOPS << 10)); - } - skb_reset_transport_header(skb); - - return atalk_rcv(skb, dev, pt, orig_dev); -freeit: - kfree_skb(skb); - return 0; -} - -static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, - size_t len) -{ - struct sock *sk = sock->sk; - struct atalk_sock *at = at_sk(sk); - struct sockaddr_at *usat = (struct sockaddr_at *)msg->msg_name; - int flags = msg->msg_flags; - int loopback = 0; - struct sockaddr_at local_satalk, gsat; - struct sk_buff *skb; - struct net_device *dev; - struct ddpehdr *ddp; - int size; - struct atalk_route *rt; - int err; - - if (flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) - return -EINVAL; - - if (len > DDP_MAXSZ) - return -EMSGSIZE; - - lock_kernel(); - if (usat) { - err = -EBUSY; - if (sock_flag(sk, SOCK_ZAPPED)) - if (atalk_autobind(sk) < 0) - goto out; - - err = -EINVAL; - if (msg->msg_namelen < sizeof(*usat) || - usat->sat_family != AF_APPLETALK) - goto out; - - err = -EPERM; - /* netatalk didn't implement this check */ - if (usat->sat_addr.s_node == ATADDR_BCAST && - !sock_flag(sk, SOCK_BROADCAST)) { - goto out; - } - } else { - err = -ENOTCONN; - if (sk->sk_state != TCP_ESTABLISHED) - goto out; - usat = &local_satalk; - usat->sat_family = AF_APPLETALK; - usat->sat_port = at->dest_port; - usat->sat_addr.s_node = at->dest_node; - usat->sat_addr.s_net = at->dest_net; - } - - /* Build a packet */ - SOCK_DEBUG(sk, "SK %p: Got address.\n", sk); - - /* For headers */ - size = sizeof(struct ddpehdr) + len + ddp_dl->header_length; - - if (usat->sat_addr.s_net || usat->sat_addr.s_node == ATADDR_ANYNODE) { - rt = atrtr_find(&usat->sat_addr); - } else { - struct atalk_addr at_hint; - - at_hint.s_node = 0; - at_hint.s_net = at->src_net; - - rt = atrtr_find(&at_hint); - } - err = ENETUNREACH; - if (!rt) - goto out; - - dev = rt->dev; - - SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n", - sk, size, dev->name); - - size += dev->hard_header_len; - skb = sock_alloc_send_skb(sk, size, (flags & MSG_DONTWAIT), &err); - if (!skb) - goto out; - - skb->sk = sk; - skb_reserve(skb, ddp_dl->header_length); - skb_reserve(skb, dev->hard_header_len); - skb->dev = dev; - - SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk); - - ddp = (struct ddpehdr *)skb_put(skb, sizeof(struct ddpehdr)); - ddp->deh_len_hops = htons(len + sizeof(*ddp)); - ddp->deh_dnet = usat->sat_addr.s_net; - ddp->deh_snet = at->src_net; - ddp->deh_dnode = usat->sat_addr.s_node; - ddp->deh_snode = at->src_node; - ddp->deh_dport = usat->sat_port; - ddp->deh_sport = at->src_port; - - SOCK_DEBUG(sk, "SK %p: Copy user data (%Zd bytes).\n", sk, len); - - err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); - if (err) { - kfree_skb(skb); - err = -EFAULT; - goto out; - } - - if (sk->sk_no_check == 1) - ddp->deh_sum = 0; - else - ddp->deh_sum = atalk_checksum(skb, len + sizeof(*ddp)); - - /* - * Loopback broadcast packets to non gateway targets (ie routes - * to group we are in) - */ - if (ddp->deh_dnode == ATADDR_BCAST && - !(rt->flags & RTF_GATEWAY) && !(dev->flags & IFF_LOOPBACK)) { - struct sk_buff *skb2 = skb_copy(skb, GFP_KERNEL); - - if (skb2) { - loopback = 1; - SOCK_DEBUG(sk, "SK %p: send out(copy).\n", sk); - /* - * If it fails it is queued/sent above in the aarp queue - */ - aarp_send_ddp(dev, skb2, &usat->sat_addr, NULL); - } - } - - if (dev->flags & IFF_LOOPBACK || loopback) { - SOCK_DEBUG(sk, "SK %p: Loop back.\n", sk); - /* loop back */ - skb_orphan(skb); - if (ddp->deh_dnode == ATADDR_BCAST) { - struct atalk_addr at_lo; - - at_lo.s_node = 0; - at_lo.s_net = 0; - - rt = atrtr_find(&at_lo); - if (!rt) { - kfree_skb(skb); - err = -ENETUNREACH; - goto out; - } - dev = rt->dev; - skb->dev = dev; - } - ddp_dl->request(ddp_dl, skb, dev->dev_addr); - } else { - SOCK_DEBUG(sk, "SK %p: send out.\n", sk); - if (rt->flags & RTF_GATEWAY) { - gsat.sat_addr = rt->gateway; - usat = &gsat; - } - - /* - * If it fails it is queued/sent above in the aarp queue - */ - aarp_send_ddp(dev, skb, &usat->sat_addr, NULL); - } - SOCK_DEBUG(sk, "SK %p: Done write (%Zd).\n", sk, len); - -out: - unlock_kernel(); - return err ? : len; -} - -static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, - size_t size, int flags) -{ - struct sock *sk = sock->sk; - struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name; - struct ddpehdr *ddp; - int copied = 0; - int offset = 0; - int err = 0; - struct sk_buff *skb; - - lock_kernel(); - skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, - flags & MSG_DONTWAIT, &err); - if (!skb) - goto out; - - /* FIXME: use skb->cb to be able to use shared skbs */ - ddp = ddp_hdr(skb); - copied = ntohs(ddp->deh_len_hops) & 1023; - - if (sk->sk_type != SOCK_RAW) { - offset = sizeof(*ddp); - copied -= offset; - } - - if (copied > size) { - copied = size; - msg->msg_flags |= MSG_TRUNC; - } - err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied); - - if (!err) { - if (sat) { - sat->sat_family = AF_APPLETALK; - sat->sat_port = ddp->deh_sport; - sat->sat_addr.s_node = ddp->deh_snode; - sat->sat_addr.s_net = ddp->deh_snet; - } - msg->msg_namelen = sizeof(*sat); - } - - skb_free_datagram(sk, skb); /* Free the datagram. */ - -out: - unlock_kernel(); - return err ? : copied; -} - - -/* - * AppleTalk ioctl calls. - */ -static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) -{ - int rc = -ENOIOCTLCMD; - struct sock *sk = sock->sk; - void __user *argp = (void __user *)arg; - - switch (cmd) { - /* Protocol layer */ - case TIOCOUTQ: { - long amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); - - if (amount < 0) - amount = 0; - rc = put_user(amount, (int __user *)argp); - break; - } - case TIOCINQ: { - /* - * These two are safe on a single CPU system as only - * user tasks fiddle here - */ - struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); - long amount = 0; - - if (skb) - amount = skb->len - sizeof(struct ddpehdr); - rc = put_user(amount, (int __user *)argp); - break; - } - case SIOCGSTAMP: - rc = sock_get_timestamp(sk, argp); - break; - case SIOCGSTAMPNS: - rc = sock_get_timestampns(sk, argp); - break; - /* Routing */ - case SIOCADDRT: - case SIOCDELRT: - rc = -EPERM; - if (capable(CAP_NET_ADMIN)) - rc = atrtr_ioctl(cmd, argp); - break; - /* Interface */ - case SIOCGIFADDR: - case SIOCSIFADDR: - case SIOCGIFBRDADDR: - case SIOCATALKDIFADDR: - case SIOCDIFADDR: - case SIOCSARP: /* proxy AARP */ - case SIOCDARP: /* proxy AARP */ - rtnl_lock(); - rc = atif_ioctl(cmd, argp); - rtnl_unlock(); - break; - } - - return rc; -} - - -#ifdef CONFIG_COMPAT -static int atalk_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) -{ - /* - * SIOCATALKDIFADDR is a SIOCPROTOPRIVATE ioctl number, so we - * cannot handle it in common code. The data we access if ifreq - * here is compatible, so we can simply call the native - * handler. - */ - if (cmd == SIOCATALKDIFADDR) - return atalk_ioctl(sock, cmd, (unsigned long)compat_ptr(arg)); - - return -ENOIOCTLCMD; -} -#endif - - -static const struct net_proto_family atalk_family_ops = { - .family = PF_APPLETALK, - .create = atalk_create, - .owner = THIS_MODULE, -}; - -static const struct proto_ops atalk_dgram_ops = { - .family = PF_APPLETALK, - .owner = THIS_MODULE, - .release = atalk_release, - .bind = atalk_bind, - .connect = atalk_connect, - .socketpair = sock_no_socketpair, - .accept = sock_no_accept, - .getname = atalk_getname, - .poll = atalk_poll, - .ioctl = atalk_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = atalk_compat_ioctl, -#endif - .listen = sock_no_listen, - .shutdown = sock_no_shutdown, - .setsockopt = sock_no_setsockopt, - .getsockopt = sock_no_getsockopt, - .sendmsg = atalk_sendmsg, - .recvmsg = atalk_recvmsg, - .mmap = sock_no_mmap, - .sendpage = sock_no_sendpage, -}; - -static struct notifier_block ddp_notifier = { - .notifier_call = ddp_device_event, -}; - -static struct packet_type ltalk_packet_type __read_mostly = { - .type = cpu_to_be16(ETH_P_LOCALTALK), - .func = ltalk_rcv, -}; - -static struct packet_type ppptalk_packet_type __read_mostly = { - .type = cpu_to_be16(ETH_P_PPPTALK), - .func = atalk_rcv, -}; - -static unsigned char ddp_snap_id[] = { 0x08, 0x00, 0x07, 0x80, 0x9B }; - -/* Export symbols for use by drivers when AppleTalk is a module */ -EXPORT_SYMBOL(atrtr_get_dev); -EXPORT_SYMBOL(atalk_find_dev_addr); - -static const char atalk_err_snap[] __initconst = - KERN_CRIT "Unable to register DDP with SNAP.\n"; - -/* Called by proto.c on kernel start up */ -static int __init atalk_init(void) -{ - int rc = proto_register(&ddp_proto, 0); - - if (rc != 0) - goto out; - - (void)sock_register(&atalk_family_ops); - ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv); - if (!ddp_dl) - printk(atalk_err_snap); - - dev_add_pack(<alk_packet_type); - dev_add_pack(&ppptalk_packet_type); - - register_netdevice_notifier(&ddp_notifier); - aarp_proto_init(); - atalk_proc_init(); - atalk_register_sysctl(); -out: - return rc; -} -module_init(atalk_init); - -/* - * No explicit module reference count manipulation is needed in the - * protocol. Socket layer sets module reference count for us - * and interfaces reference counting is done - * by the network device layer. - * - * Ergo, before the AppleTalk module can be removed, all AppleTalk - * sockets be closed from user space. - */ -static void __exit atalk_exit(void) -{ -#ifdef CONFIG_SYSCTL - atalk_unregister_sysctl(); -#endif /* CONFIG_SYSCTL */ - atalk_proc_exit(); - aarp_cleanup_module(); /* General aarp clean-up. */ - unregister_netdevice_notifier(&ddp_notifier); - dev_remove_pack(<alk_packet_type); - dev_remove_pack(&ppptalk_packet_type); - unregister_snap_client(ddp_dl); - sock_unregister(PF_APPLETALK); - proto_unregister(&ddp_proto); -} -module_exit(atalk_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Alan Cox "); -MODULE_DESCRIPTION("AppleTalk 0.20\n"); -MODULE_ALIAS_NETPROTO(PF_APPLETALK); diff --git a/net/appletalk/dev.c b/net/appletalk/dev.c deleted file mode 100644 index 6c8016f61866..000000000000 --- a/net/appletalk/dev.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Moved here from drivers/net/net_init.c, which is: - * Written 1993,1994,1995 by Donald Becker. - */ - -#include -#include -#include -#include -#include - -static void ltalk_setup(struct net_device *dev) -{ - /* Fill in the fields of the device structure with localtalk-generic values. */ - - dev->type = ARPHRD_LOCALTLK; - dev->hard_header_len = LTALK_HLEN; - dev->mtu = LTALK_MTU; - dev->addr_len = LTALK_ALEN; - dev->tx_queue_len = 10; - - dev->broadcast[0] = 0xFF; - - dev->flags = IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP; -} - -/** - * alloc_ltalkdev - Allocates and sets up an localtalk device - * @sizeof_priv: Size of additional driver-private structure to be allocated - * for this localtalk device - * - * Fill in the fields of the device structure with localtalk-generic - * values. Basically does everything except registering the device. - * - * Constructs a new net device, complete with a private data area of - * size @sizeof_priv. A 32-byte (not bit) alignment is enforced for - * this private data area. - */ - -struct net_device *alloc_ltalkdev(int sizeof_priv) -{ - return alloc_netdev(sizeof_priv, "lt%d", ltalk_setup); -} -EXPORT_SYMBOL(alloc_ltalkdev); diff --git a/net/appletalk/sysctl_net_atalk.c b/net/appletalk/sysctl_net_atalk.c deleted file mode 100644 index 04e9c0da7aa9..000000000000 --- a/net/appletalk/sysctl_net_atalk.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * sysctl_net_atalk.c: sysctl interface to net AppleTalk subsystem. - * - * Begun April 1, 1996, Mike Shaver. - * Added /proc/sys/net/atalk directory entry (empty =) ). [MS] - * Dynamic registration, added aarp entries. (5/30/97 Chris Horn) - */ - -#include -#include -#include - -static struct ctl_table atalk_table[] = { - { - .procname = "aarp-expiry-time", - .data = &sysctl_aarp_expiry_time, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec_jiffies, - }, - { - .procname = "aarp-tick-time", - .data = &sysctl_aarp_tick_time, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec_jiffies, - }, - { - .procname = "aarp-retransmit-limit", - .data = &sysctl_aarp_retransmit_limit, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec, - }, - { - .procname = "aarp-resolve-time", - .data = &sysctl_aarp_resolve_time, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec_jiffies, - }, - { }, -}; - -static struct ctl_path atalk_path[] = { - { .procname = "net", }, - { .procname = "appletalk", }, - { } -}; - -static struct ctl_table_header *atalk_table_header; - -void atalk_register_sysctl(void) -{ - atalk_table_header = register_sysctl_paths(atalk_path, atalk_table); -} - -void atalk_unregister_sysctl(void) -{ - unregister_sysctl_table(atalk_table_header); -} diff --git a/net/socket.c b/net/socket.c index ac2219f90d5d..26f7bcf36810 100644 --- a/net/socket.c +++ b/net/socket.c @@ -103,7 +103,6 @@ #include #include #include -#include static int sock_no_open(struct inode *irrelevant, struct file *dontcare); static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, -- cgit v1.2.3 From 15b2f6479b5c5220848ba159248665d56694d2f9 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Wed, 26 Jan 2011 12:12:07 -0800 Subject: staging: hv: Convert camel cased variables in connection.c to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel.c | 48 ++++++------ drivers/staging/hv/channel_mgmt.c | 48 ++++++------ drivers/staging/hv/connection.c | 154 +++++++++++++++++++------------------ drivers/staging/hv/vmbus_drv.c | 2 +- drivers/staging/hv/vmbus_private.h | 2 +- 5 files changed, 128 insertions(+), 126 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index 69e78568f359..99b2d2ae8dd6 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -77,10 +77,10 @@ static void vmbus_setevent(struct vmbus_channel *channel) if (channel->offermsg.monitor_allocated) { /* Each u32 represents 32 channels */ set_bit(channel->offermsg.child_relid & 31, - (unsigned long *) gVmbusConnection.SendInterruptPage + + (unsigned long *) vmbus_connection.SendInterruptPage + (channel->offermsg.child_relid >> 5)); - monitorpage = gVmbusConnection.MonitorPages; + monitorpage = vmbus_connection.MonitorPages; monitorpage++; /* Get the child to parent monitor page */ set_bit(channel->monitor_bit, @@ -100,11 +100,11 @@ static void VmbusChannelClearEvent(struct vmbus_channel *channel) if (Channel->offermsg.monitor_allocated) { /* Each u32 represents 32 channels */ clear_bit(Channel->offermsg.child_relid & 31, - (unsigned long *)gVmbusConnection.SendInterruptPage + + (unsigned long *)vmbus_connection.SendInterruptPage + (Channel->offermsg.child_relid >> 5)); monitorPage = - (struct hv_monitor_page *)gVmbusConnection.MonitorPages; + (struct hv_monitor_page *)vmbus_connection.MonitorPages; monitorPage++; /* Get the child to parent monitor page */ clear_bit(Channel->monitor_bit, @@ -133,7 +133,7 @@ void vmbus_get_debug_info(struct vmbus_channel *channel, &channel->offermsg.offer.InterfaceInstance, sizeof(struct hv_guid)); - monitorpage = (struct hv_monitor_page *)gVmbusConnection.MonitorPages; + monitorpage = (struct hv_monitor_page *)vmbus_connection.MonitorPages; debuginfo->monitorid = channel->offermsg.monitorid; @@ -265,10 +265,10 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, if (userdatalen) memcpy(openMsg->userdata, userdata, userdatalen); - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); list_add_tail(&openInfo->msglistentry, - &gVmbusConnection.ChannelMsgList); - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + &vmbus_connection.ChannelMsgList); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); DPRINT_DBG(VMBUS, "Sending channel open msg..."); @@ -289,9 +289,9 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, newchannel, openInfo->response.open_result.status); Cleanup: - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); list_del(&openInfo->msglistentry); - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); kfree(openInfo->waitevent); kfree(openInfo); @@ -501,8 +501,8 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, unsigned long flags; int ret = 0; - next_gpadl_handle = atomic_read(&gVmbusConnection.NextGpadlHandle); - atomic_inc(&gVmbusConnection.NextGpadlHandle); + next_gpadl_handle = atomic_read(&vmbus_connection.NextGpadlHandle); + atomic_inc(&vmbus_connection.NextGpadlHandle); ret = create_gpadl_header(kbuffer, size, &msginfo, &msgcount); if (ret) @@ -521,11 +521,11 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, dump_gpadl_header(gpadlmsg); - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); list_add_tail(&msginfo->msglistentry, - &gVmbusConnection.ChannelMsgList); + &vmbus_connection.ChannelMsgList); - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); DPRINT_DBG(VMBUS, "buffer %p, size %d msg cnt %d", kbuffer, size, msgcount); @@ -577,9 +577,9 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, *gpadl_handle = gpadlmsg->gpadl; Cleanup: - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); list_del(&msginfo->msglistentry); - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); kfree(msginfo->waitevent); kfree(msginfo); @@ -616,10 +616,10 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) msg->child_relid = channel->offermsg.child_relid; msg->gpadl = gpadl_handle; - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); list_add_tail(&info->msglistentry, - &gVmbusConnection.ChannelMsgList); - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + &vmbus_connection.ChannelMsgList); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); ret = VmbusPostMessage(msg, sizeof(struct vmbus_channel_gpadl_teardown)); @@ -631,9 +631,9 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) osd_waitevent_wait(info->waitevent); /* Received a torndown response */ - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); list_del(&info->msglistentry); - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); kfree(info->waitevent); kfree(info); @@ -697,9 +697,9 @@ void vmbus_close(struct vmbus_channel *channel) */ if (channel->state == CHANNEL_OPEN_STATE) { - spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); + spin_lock_irqsave(&vmbus_connection.channel_lock, flags); list_del(&channel->listentry); - spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); free_channel(channel); } diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index fb71f88e697d..351ebeb89dd0 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -308,7 +308,7 @@ void free_channel(struct vmbus_channel *channel) * ie we can't destroy ourselves. */ INIT_WORK(&channel->work, release_channel); - queue_work(gVmbusConnection.WorkQueue, &channel->work); + queue_work(vmbus_connection.WorkQueue, &channel->work); } @@ -323,10 +323,10 @@ static void count_hv_channel(void) static int counter; unsigned long flags; - spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); + spin_lock_irqsave(&vmbus_connection.channel_lock, flags); if (++counter == MAX_MSG_TYPES) complete(&hv_channel_ready); - spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); } /* @@ -361,9 +361,9 @@ static void vmbus_process_offer(struct work_struct *work) INIT_WORK(&newchannel->work, vmbus_process_rescind_offer); /* Make sure this is a new offer */ - spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); + spin_lock_irqsave(&vmbus_connection.channel_lock, flags); - list_for_each_entry(channel, &gVmbusConnection.ChannelList, listentry) { + list_for_each_entry(channel, &vmbus_connection.ChannelList, listentry) { if (!memcmp(&channel->offermsg.offer.InterfaceType, &newchannel->offermsg.offer.InterfaceType, sizeof(struct hv_guid)) && @@ -377,9 +377,9 @@ static void vmbus_process_offer(struct work_struct *work) if (fnew) list_add_tail(&newchannel->listentry, - &gVmbusConnection.ChannelList); + &vmbus_connection.ChannelList); - spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); if (!fnew) { DPRINT_DBG(VMBUS, "Ignoring duplicate offer for relid (%d)", @@ -412,9 +412,9 @@ static void vmbus_process_offer(struct work_struct *work) "unable to add child device object (relid %d)", newchannel->offermsg.child_relid); - spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); + spin_lock_irqsave(&vmbus_connection.channel_lock, flags); list_del(&newchannel->listentry); - spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); free_channel(newchannel); } else { @@ -577,9 +577,9 @@ static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr) /* * Find the open msg, copy the result and signal/unblock the wait event */ - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_for_each(curr, &gVmbusConnection.ChannelMsgList) { + list_for_each(curr, &vmbus_connection.ChannelMsgList) { /* FIXME: this should probably use list_entry() instead */ msginfo = (struct vmbus_channel_msginfo *)curr; requestheader = @@ -598,7 +598,7 @@ static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr) } } } - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); } /* @@ -625,9 +625,9 @@ static void vmbus_ongpadl_created(struct vmbus_channel_message_header *hdr) * Find the establish msg, copy the result and signal/unblock the wait * event */ - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_for_each(curr, &gVmbusConnection.ChannelMsgList) { + list_for_each(curr, &vmbus_connection.ChannelMsgList) { /* FIXME: this should probably use list_entry() instead */ msginfo = (struct vmbus_channel_msginfo *)curr; requestheader = @@ -648,7 +648,7 @@ static void vmbus_ongpadl_created(struct vmbus_channel_message_header *hdr) } } } - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); } /* @@ -673,9 +673,9 @@ static void vmbus_ongpadl_torndown( /* * Find the open msg, copy the result and signal/unblock the wait event */ - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_for_each(curr, &gVmbusConnection.ChannelMsgList) { + list_for_each(curr, &vmbus_connection.ChannelMsgList) { /* FIXME: this should probably use list_entry() instead */ msginfo = (struct vmbus_channel_msginfo *)curr; requestheader = @@ -694,7 +694,7 @@ static void vmbus_ongpadl_torndown( } } } - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); } /* @@ -715,9 +715,9 @@ static void vmbus_onversion_response( unsigned long flags; version_response = (struct vmbus_channel_version_response *)hdr; - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_for_each(curr, &gVmbusConnection.ChannelMsgList) { + list_for_each(curr, &vmbus_connection.ChannelMsgList) { /* FIXME: this should probably use list_entry() instead */ msginfo = (struct vmbus_channel_msginfo *)curr; requestheader = @@ -733,7 +733,7 @@ static void vmbus_onversion_response( osd_waitevent_set(msginfo->waitevent); } } - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); } /* Channel message dispatch table */ @@ -857,9 +857,9 @@ void vmbus_release_unattached_channels(void) struct vmbus_channel *start = NULL; unsigned long flags; - spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); + spin_lock_irqsave(&vmbus_connection.channel_lock, flags); - list_for_each_entry_safe(channel, pos, &gVmbusConnection.ChannelList, + list_for_each_entry_safe(channel, pos, &vmbus_connection.ChannelList, listentry) { if (channel == start) break; @@ -878,7 +878,7 @@ void vmbus_release_unattached_channels(void) } } - spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); } /* eof */ diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index c2e298ff4834..a30b98deb6a4 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -29,7 +29,7 @@ #include "vmbus_private.h" -struct VMBUS_CONNECTION gVmbusConnection = { +struct VMBUS_CONNECTION vmbus_connection = { .ConnectState = Disconnected, .NextGpadlHandle = ATOMIC_INIT(0xE1E10), }; @@ -40,86 +40,86 @@ struct VMBUS_CONNECTION gVmbusConnection = { int VmbusConnect(void) { int ret = 0; - struct vmbus_channel_msginfo *msgInfo = NULL; + struct vmbus_channel_msginfo *msginfo = NULL; struct vmbus_channel_initiate_contact *msg; unsigned long flags; /* Make sure we are not connecting or connected */ - if (gVmbusConnection.ConnectState != Disconnected) + if (vmbus_connection.ConnectState != Disconnected) return -1; /* Initialize the vmbus connection */ - gVmbusConnection.ConnectState = Connecting; - gVmbusConnection.WorkQueue = create_workqueue("hv_vmbus_con"); - if (!gVmbusConnection.WorkQueue) { + vmbus_connection.ConnectState = Connecting; + vmbus_connection.WorkQueue = create_workqueue("hv_vmbus_con"); + if (!vmbus_connection.WorkQueue) { ret = -1; goto Cleanup; } - INIT_LIST_HEAD(&gVmbusConnection.ChannelMsgList); - spin_lock_init(&gVmbusConnection.channelmsg_lock); + INIT_LIST_HEAD(&vmbus_connection.ChannelMsgList); + spin_lock_init(&vmbus_connection.channelmsg_lock); - INIT_LIST_HEAD(&gVmbusConnection.ChannelList); - spin_lock_init(&gVmbusConnection.channel_lock); + INIT_LIST_HEAD(&vmbus_connection.ChannelList); + spin_lock_init(&vmbus_connection.channel_lock); /* * Setup the vmbus event connection for channel interrupt * abstraction stuff */ - gVmbusConnection.InterruptPage = osd_page_alloc(1); - if (gVmbusConnection.InterruptPage == NULL) { + vmbus_connection.InterruptPage = osd_page_alloc(1); + if (vmbus_connection.InterruptPage == NULL) { ret = -1; goto Cleanup; } - gVmbusConnection.RecvInterruptPage = gVmbusConnection.InterruptPage; - gVmbusConnection.SendInterruptPage = - (void *)((unsigned long)gVmbusConnection.InterruptPage + + vmbus_connection.RecvInterruptPage = vmbus_connection.InterruptPage; + vmbus_connection.SendInterruptPage = + (void *)((unsigned long)vmbus_connection.InterruptPage + (PAGE_SIZE >> 1)); /* * Setup the monitor notification facility. The 1st page for * parent->child and the 2nd page for child->parent */ - gVmbusConnection.MonitorPages = osd_page_alloc(2); - if (gVmbusConnection.MonitorPages == NULL) { + vmbus_connection.MonitorPages = osd_page_alloc(2); + if (vmbus_connection.MonitorPages == NULL) { ret = -1; goto Cleanup; } - msgInfo = kzalloc(sizeof(*msgInfo) + + msginfo = kzalloc(sizeof(*msginfo) + sizeof(struct vmbus_channel_initiate_contact), GFP_KERNEL); - if (msgInfo == NULL) { + if (msginfo == NULL) { ret = -ENOMEM; goto Cleanup; } - msgInfo->waitevent = osd_waitevent_create(); - if (!msgInfo->waitevent) { + msginfo->waitevent = osd_waitevent_create(); + if (!msginfo->waitevent) { ret = -ENOMEM; goto Cleanup; } - msg = (struct vmbus_channel_initiate_contact *)msgInfo->msg; + msg = (struct vmbus_channel_initiate_contact *)msginfo->msg; msg->header.msgtype = CHANNELMSG_INITIATE_CONTACT; msg->vmbus_version_requested = VMBUS_REVISION_NUMBER; - msg->interrupt_page = virt_to_phys(gVmbusConnection.InterruptPage); - msg->monitor_page1 = virt_to_phys(gVmbusConnection.MonitorPages); + msg->interrupt_page = virt_to_phys(vmbus_connection.InterruptPage); + msg->monitor_page1 = virt_to_phys(vmbus_connection.MonitorPages); msg->monitor_page2 = virt_to_phys( - (void *)((unsigned long)gVmbusConnection.MonitorPages + + (void *)((unsigned long)vmbus_connection.MonitorPages + PAGE_SIZE)); /* * Add to list before we send the request since we may * receive the response before returning from this routine */ - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); - list_add_tail(&msgInfo->msglistentry, - &gVmbusConnection.ChannelMsgList); + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); + list_add_tail(&msginfo->msglistentry, + &vmbus_connection.ChannelMsgList); - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); DPRINT_DBG(VMBUS, "Vmbus connection - interrupt pfn %llx, " "monitor1 pfn %llx,, monitor2 pfn %llx", @@ -129,19 +129,19 @@ int VmbusConnect(void) ret = VmbusPostMessage(msg, sizeof(struct vmbus_channel_initiate_contact)); if (ret != 0) { - list_del(&msgInfo->msglistentry); + list_del(&msginfo->msglistentry); goto Cleanup; } /* Wait for the connection response */ - osd_waitevent_wait(msgInfo->waitevent); + osd_waitevent_wait(msginfo->waitevent); - list_del(&msgInfo->msglistentry); + list_del(&msginfo->msglistentry); /* Check if successful */ - if (msgInfo->response.version_response.version_supported) { + if (msginfo->response.version_response.version_supported) { DPRINT_INFO(VMBUS, "Vmbus connected!!"); - gVmbusConnection.ConnectState = Connected; + vmbus_connection.ConnectState = Connected; } else { DPRINT_ERR(VMBUS, "Vmbus connection failed!!..." @@ -151,29 +151,29 @@ int VmbusConnect(void) goto Cleanup; } - kfree(msgInfo->waitevent); - kfree(msgInfo); + kfree(msginfo->waitevent); + kfree(msginfo); return 0; Cleanup: - gVmbusConnection.ConnectState = Disconnected; + vmbus_connection.ConnectState = Disconnected; - if (gVmbusConnection.WorkQueue) - destroy_workqueue(gVmbusConnection.WorkQueue); + if (vmbus_connection.WorkQueue) + destroy_workqueue(vmbus_connection.WorkQueue); - if (gVmbusConnection.InterruptPage) { - osd_page_free(gVmbusConnection.InterruptPage, 1); - gVmbusConnection.InterruptPage = NULL; + if (vmbus_connection.InterruptPage) { + osd_page_free(vmbus_connection.InterruptPage, 1); + vmbus_connection.InterruptPage = NULL; } - if (gVmbusConnection.MonitorPages) { - osd_page_free(gVmbusConnection.MonitorPages, 2); - gVmbusConnection.MonitorPages = NULL; + if (vmbus_connection.MonitorPages) { + osd_page_free(vmbus_connection.MonitorPages, 2); + vmbus_connection.MonitorPages = NULL; } - if (msgInfo) { - kfree(msgInfo->waitevent); - kfree(msgInfo); + if (msginfo) { + kfree(msginfo->waitevent); + kfree(msginfo); } return ret; @@ -188,7 +188,7 @@ int VmbusDisconnect(void) struct vmbus_channel_message_header *msg; /* Make sure we are connected */ - if (gVmbusConnection.ConnectState != Connected) + if (vmbus_connection.ConnectState != Connected) return -1; msg = kzalloc(sizeof(struct vmbus_channel_message_header), GFP_KERNEL); @@ -202,12 +202,12 @@ int VmbusDisconnect(void) if (ret != 0) goto Cleanup; - osd_page_free(gVmbusConnection.InterruptPage, 1); + osd_page_free(vmbus_connection.InterruptPage, 1); /* TODO: iterate thru the msg list and free up */ - destroy_workqueue(gVmbusConnection.WorkQueue); + destroy_workqueue(vmbus_connection.WorkQueue); - gVmbusConnection.ConnectState = Disconnected; + vmbus_connection.ConnectState = Disconnected; DPRINT_INFO(VMBUS, "Vmbus disconnected!!"); @@ -219,22 +219,22 @@ Cleanup: /* * GetChannelFromRelId - Get the channel object given its child relative id (ie channel id) */ -struct vmbus_channel *GetChannelFromRelId(u32 relId) +struct vmbus_channel *GetChannelFromRelId(u32 relid) { struct vmbus_channel *channel; - struct vmbus_channel *foundChannel = NULL; + struct vmbus_channel *found_channel = NULL; unsigned long flags; - spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); - list_for_each_entry(channel, &gVmbusConnection.ChannelList, listentry) { - if (channel->offermsg.child_relid == relId) { - foundChannel = channel; + spin_lock_irqsave(&vmbus_connection.channel_lock, flags); + list_for_each_entry(channel, &vmbus_connection.ChannelList, listentry) { + if (channel->offermsg.child_relid == relid) { + found_channel = channel; break; } } - spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); - return foundChannel; + return found_channel; } /* @@ -243,7 +243,7 @@ struct vmbus_channel *GetChannelFromRelId(u32 relId) static void VmbusProcessChannelEvent(void *context) { struct vmbus_channel *channel; - u32 relId = (u32)(unsigned long)context; + u32 relid = (u32)(unsigned long)context; /* ASSERT(relId > 0); */ @@ -251,7 +251,7 @@ static void VmbusProcessChannelEvent(void *context) * Find the channel based on this relid and invokes the * channel callback to process the event */ - channel = GetChannelFromRelId(relId); + channel = GetChannelFromRelId(relid); if (channel) { vmbus_onchannel_event(channel); @@ -261,7 +261,7 @@ static void VmbusProcessChannelEvent(void *context) * (void*)channel); */ } else { - DPRINT_ERR(VMBUS, "channel not found for relid - %d.", relId); + DPRINT_ERR(VMBUS, "channel not found for relid - %d.", relid); } } @@ -274,14 +274,16 @@ void VmbusOnEvents(void) int maxdword = MAX_NUM_CHANNELS_SUPPORTED >> 5; int bit; int relid; - u32 *recvInterruptPage = gVmbusConnection.RecvInterruptPage; + u32 *recv_int_page = vmbus_connection.RecvInterruptPage; /* Check events */ - if (recvInterruptPage) { + if (recv_int_page) { for (dword = 0; dword < maxdword; dword++) { - if (recvInterruptPage[dword]) { + if (recv_int_page[dword]) { for (bit = 0; bit < 32; bit++) { - if (test_and_clear_bit(bit, (unsigned long *)&recvInterruptPage[dword])) { + if (test_and_clear_bit(bit, + (unsigned long *) + &recv_int_page[dword])) { relid = (dword << 5) + bit; DPRINT_DBG(VMBUS, "event detected for relid - %d", relid); @@ -305,24 +307,24 @@ void VmbusOnEvents(void) /* * VmbusPostMessage - Send a msg on the vmbus's message connection */ -int VmbusPostMessage(void *buffer, size_t bufferLen) +int VmbusPostMessage(void *buffer, size_t buflen) { - union hv_connection_id connId; + union hv_connection_id conn_id; - connId.asu32 = 0; - connId.u.id = VMBUS_MESSAGE_CONNECTION_ID; - return hv_post_message(connId, 1, buffer, bufferLen); + conn_id.asu32 = 0; + conn_id.u.id = VMBUS_MESSAGE_CONNECTION_ID; + return hv_post_message(conn_id, 1, buffer, buflen); } /* * VmbusSetEvent - Send an event notification to the parent */ -int VmbusSetEvent(u32 childRelId) +int VmbusSetEvent(u32 child_relid) { /* Each u32 represents 32 channels */ - set_bit(childRelId & 31, - (unsigned long *)gVmbusConnection.SendInterruptPage + - (childRelId >> 5)); + set_bit(child_relid & 31, + (unsigned long *)vmbus_connection.SendInterruptPage + + (child_relid >> 5)); return hv_signal_event(); } diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 84fdb64d3ceb..fd0881a4f888 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -239,7 +239,7 @@ static void vmbus_on_msg_dpc(struct hv_driver *drv) continue; INIT_WORK(&ctx->work, vmbus_onmessage_work); memcpy(&ctx->msg, msg, sizeof(*msg)); - queue_work(gVmbusConnection.WorkQueue, &ctx->work); + queue_work(vmbus_connection.WorkQueue, &ctx->work); } msg->header.message_type = HVMSG_NONE; diff --git a/drivers/staging/hv/vmbus_private.h b/drivers/staging/hv/vmbus_private.h index 07f6d22eeabb..9b51ac1ee2f0 100644 --- a/drivers/staging/hv/vmbus_private.h +++ b/drivers/staging/hv/vmbus_private.h @@ -98,7 +98,7 @@ struct VMBUS_MSGINFO { }; -extern struct VMBUS_CONNECTION gVmbusConnection; +extern struct VMBUS_CONNECTION vmbus_connection; /* General vmbus interface */ -- cgit v1.2.3 From c69776771f5fcc49d9a49580234d3a481409c80e Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Wed, 26 Jan 2011 12:12:08 -0800 Subject: staging: hv: Convert camel cased functions in connection.c to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel.c | 12 ++++++------ drivers/staging/hv/channel_mgmt.c | 4 ++-- drivers/staging/hv/connection.c | 39 ++++++++++++++++++++------------------ drivers/staging/hv/vmbus_drv.c | 6 +++--- drivers/staging/hv/vmbus_private.h | 12 ++++++------ 5 files changed, 38 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index 99b2d2ae8dd6..ca7609868650 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -88,7 +88,7 @@ static void vmbus_setevent(struct vmbus_channel *channel) [channel->monitor_grp].pending); } else { - VmbusSetEvent(channel->offermsg.child_relid); + vmbus_set_event(channel->offermsg.child_relid); } } @@ -272,7 +272,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, DPRINT_DBG(VMBUS, "Sending channel open msg..."); - ret = VmbusPostMessage(openMsg, + ret = vmbus_post_msg(openMsg, sizeof(struct vmbus_channel_open_channel)); if (ret != 0) { DPRINT_ERR(VMBUS, "unable to open channel - %d", ret); @@ -532,7 +532,7 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, DPRINT_DBG(VMBUS, "Sending GPADL Header - len %zd", msginfo->msgsize - sizeof(*msginfo)); - ret = VmbusPostMessage(gpadlmsg, msginfo->msgsize - + ret = vmbus_post_msg(gpadlmsg, msginfo->msgsize - sizeof(*msginfo)); if (ret != 0) { DPRINT_ERR(VMBUS, "Unable to open channel - %d", ret); @@ -557,7 +557,7 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, dump_gpadl_body(gpadl_body, submsginfo->msgsize - sizeof(*submsginfo)); - ret = VmbusPostMessage(gpadl_body, + ret = vmbus_post_msg(gpadl_body, submsginfo->msgsize - sizeof(*submsginfo)); if (ret != 0) @@ -621,7 +621,7 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) &vmbus_connection.ChannelMsgList); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); - ret = VmbusPostMessage(msg, + ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_gpadl_teardown)); if (ret != 0) { /* TODO: */ @@ -669,7 +669,7 @@ void vmbus_close(struct vmbus_channel *channel) msg->header.msgtype = CHANNELMSG_CLOSECHANNEL; msg->child_relid = channel->offermsg.child_relid; - ret = VmbusPostMessage(msg, sizeof(struct vmbus_channel_close_channel)); + ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_close_channel)); if (ret != 0) { /* TODO: */ /* something... */ diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 351ebeb89dd0..0ce8f54cfc2e 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -532,7 +532,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) struct vmbus_channel *channel; rescind = (struct vmbus_channel_rescind_offer *)hdr; - channel = GetChannelFromRelId(rescind->child_relid); + channel = relid2channel(rescind->child_relid); if (channel == NULL) { DPRINT_DBG(VMBUS, "channel not found for relId %d", rescind->child_relid); @@ -820,7 +820,7 @@ int vmbus_request_offers(void) &msgInfo->msgListEntry); SpinlockRelease(gVmbusConnection.channelMsgLock);*/ - ret = VmbusPostMessage(msg, + ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_message_header)); if (ret != 0) { DPRINT_ERR(VMBUS, "Unable to request offers - %d", ret); diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index a30b98deb6a4..002e86caf70c 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -35,9 +35,9 @@ struct VMBUS_CONNECTION vmbus_connection = { }; /* - * VmbusConnect - Sends a connect request on the partition service connection + * vmbus_connect - Sends a connect request on the partition service connection */ -int VmbusConnect(void) +int vmbus_connect(void) { int ret = 0; struct vmbus_channel_msginfo *msginfo = NULL; @@ -126,7 +126,7 @@ int VmbusConnect(void) msg->interrupt_page, msg->monitor_page1, msg->monitor_page2); DPRINT_DBG(VMBUS, "Sending channel initiate msg..."); - ret = VmbusPostMessage(msg, + ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_initiate_contact)); if (ret != 0) { list_del(&msginfo->msglistentry); @@ -180,9 +180,10 @@ Cleanup: } /* - * VmbusDisconnect - Sends a disconnect request on the partition service connection + * vmbus_disconnect - + * Sends a disconnect request on the partition service connection */ -int VmbusDisconnect(void) +int vmbus_disconnect(void) { int ret = 0; struct vmbus_channel_message_header *msg; @@ -197,7 +198,7 @@ int VmbusDisconnect(void) msg->msgtype = CHANNELMSG_UNLOAD; - ret = VmbusPostMessage(msg, + ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_message_header)); if (ret != 0) goto Cleanup; @@ -217,9 +218,10 @@ Cleanup: } /* - * GetChannelFromRelId - Get the channel object given its child relative id (ie channel id) + * relid2channel - Get the channel object given its + * child relative id (ie channel id) */ -struct vmbus_channel *GetChannelFromRelId(u32 relid) +struct vmbus_channel *relid2channel(u32 relid) { struct vmbus_channel *channel; struct vmbus_channel *found_channel = NULL; @@ -238,9 +240,9 @@ struct vmbus_channel *GetChannelFromRelId(u32 relid) } /* - * VmbusProcessChannelEvent - Process a channel event notification + * process_chn_event - Process a channel event notification */ -static void VmbusProcessChannelEvent(void *context) +static void process_chn_event(void *context) { struct vmbus_channel *channel; u32 relid = (u32)(unsigned long)context; @@ -251,7 +253,7 @@ static void VmbusProcessChannelEvent(void *context) * Find the channel based on this relid and invokes the * channel callback to process the event */ - channel = GetChannelFromRelId(relid); + channel = relid2channel(relid); if (channel) { vmbus_onchannel_event(channel); @@ -266,9 +268,9 @@ static void VmbusProcessChannelEvent(void *context) } /* - * VmbusOnEvents - Handler for events + * vmbus_on_event - Handler for events */ -void VmbusOnEvents(void) +void vmbus_on_event(void) { int dword; int maxdword = MAX_NUM_CHANNELS_SUPPORTED >> 5; @@ -294,7 +296,8 @@ void VmbusOnEvents(void) } else { /* QueueWorkItem(VmbusProcessEvent, (void*)relid); */ /* ret = WorkQueueQueueWorkItem(gVmbusConnection.workQueue, VmbusProcessChannelEvent, (void*)relid); */ - VmbusProcessChannelEvent((void *)(unsigned long)relid); + process_chn_event((void *) + (unsigned long)relid); } } } @@ -305,9 +308,9 @@ void VmbusOnEvents(void) } /* - * VmbusPostMessage - Send a msg on the vmbus's message connection + * vmbus_post_msg - Send a msg on the vmbus's message connection */ -int VmbusPostMessage(void *buffer, size_t buflen) +int vmbus_post_msg(void *buffer, size_t buflen) { union hv_connection_id conn_id; @@ -317,9 +320,9 @@ int VmbusPostMessage(void *buffer, size_t buflen) } /* - * VmbusSetEvent - Send an event notification to the parent + * vmbus_set_event - Send an event notification to the parent */ -int VmbusSetEvent(u32 child_relid) +int vmbus_set_event(u32 child_relid) { /* Each u32 represents 32 channels */ set_bit(child_relid & 31, diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index fd0881a4f888..b33f4972e75c 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -174,7 +174,7 @@ static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo) on_each_cpu(hv_synic_init, (void *)irqvector, 1); /* Connect to VMBus in the root partition */ - ret = VmbusConnect(); + ret = vmbus_connect(); /* VmbusSendEvent(device->localPortId+1); */ return ret; @@ -188,7 +188,7 @@ static int VmbusOnDeviceRemove(struct hv_device *dev) int ret = 0; vmbus_release_unattached_channels(); - VmbusDisconnect(); + vmbus_disconnect(); on_each_cpu(hv_synic_cleanup, NULL, 1); return ret; } @@ -1045,7 +1045,7 @@ static void vmbus_msg_dpc(unsigned long data) static void vmbus_event_dpc(unsigned long data) { /* Call to bus driver to handle interrupt */ - VmbusOnEvents(); + vmbus_on_event(); } static irqreturn_t vmbus_isr(int irq, void *dev_id) diff --git a/drivers/staging/hv/vmbus_private.h b/drivers/staging/hv/vmbus_private.h index 9b51ac1ee2f0..e3b0663b8db5 100644 --- a/drivers/staging/hv/vmbus_private.h +++ b/drivers/staging/hv/vmbus_private.h @@ -115,20 +115,20 @@ void vmbus_child_device_unregister(struct hv_device *device_obj); /* VmbusChildDeviceDestroy( */ /* struct hv_device *); */ -struct vmbus_channel *GetChannelFromRelId(u32 relId); +struct vmbus_channel *relid2channel(u32 relid); /* Connection interface */ -int VmbusConnect(void); +int vmbus_connect(void); -int VmbusDisconnect(void); +int vmbus_disconnect(void); -int VmbusPostMessage(void *buffer, size_t bufSize); +int vmbus_post_msg(void *buffer, size_t buflen); -int VmbusSetEvent(u32 childRelId); +int vmbus_set_event(u32 child_relid); -void VmbusOnEvents(void); +void vmbus_on_event(void); #endif /* _VMBUS_PRIVATE_H_ */ -- cgit v1.2.3 From adf874cb355fcc3293aa489f427f682e708cf586 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Wed, 26 Jan 2011 12:12:09 -0800 Subject: staging: hv: Convert camel cased variables in vmbus_drv.c to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 50 +++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index b33f4972e75c..99686f06d2f5 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -113,7 +113,7 @@ static struct device_attribute vmbus_device_attrs[] = { }; /* The one and only one */ -static struct vmbus_driver_context g_vmbus_drv = { +static struct vmbus_driver_context vmbus_drv = { .bus.name = "vmbus", .bus.match = vmbus_match, .bus.shutdown = vmbus_shutdown, @@ -123,14 +123,14 @@ static struct vmbus_driver_context g_vmbus_drv = { .bus.dev_attrs = vmbus_device_attrs, }; -static const char *gDriverName = "hyperv"; +static const char *driver_name = "hyperv"; /* * Windows vmbus does not defined this. * We defined this to be consistent with other devices */ /* {c5295816-f63a-4d5f-8d1a-4daf999ca185} */ -static const struct hv_guid gVmbusDeviceType = { +static const struct hv_guid device_type = { .data = { 0x16, 0x58, 0x29, 0xc5, 0x3a, 0xf6, 0x5f, 0x4d, 0x8d, 0x1a, 0x4d, 0xaf, 0x99, 0x9c, 0xa1, 0x85 @@ -138,35 +138,35 @@ static const struct hv_guid gVmbusDeviceType = { }; /* {ac3760fc-9adf-40aa-9427-a70ed6de95c5} */ -static const struct hv_guid gVmbusDeviceId = { +static const struct hv_guid device_id = { .data = { 0xfc, 0x60, 0x37, 0xac, 0xdf, 0x9a, 0xaa, 0x40, 0x94, 0x27, 0xa7, 0x0e, 0xd6, 0xde, 0x95, 0xc5 } }; -static struct hv_device *gDevice; /* vmbus root device */ +static struct hv_device *vmbus_device; /* vmbus root device */ /* * VmbusChildDeviceAdd - Registers the child device with the vmbus */ -int VmbusChildDeviceAdd(struct hv_device *ChildDevice) +int VmbusChildDeviceAdd(struct hv_device *child_dev) { - return vmbus_child_device_register(gDevice, ChildDevice); + return vmbus_child_device_register(vmbus_device, child_dev); } /* * VmbusOnDeviceAdd - Callback when the root bus device is added */ -static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo) +static int VmbusOnDeviceAdd(struct hv_device *dev, void *info) { - u32 *irqvector = AdditionalInfo; + u32 *irqvector = info; int ret; - gDevice = dev; + vmbus_device = dev; - memcpy(&gDevice->deviceType, &gVmbusDeviceType, sizeof(struct hv_guid)); - memcpy(&gDevice->deviceInstance, &gVmbusDeviceId, + memcpy(&vmbus_device->deviceType, &device_type, sizeof(struct hv_guid)); + memcpy(&vmbus_device->deviceInstance, &device_id, sizeof(struct hv_guid)); /* strcpy(dev->name, "vmbus"); */ @@ -461,9 +461,9 @@ static ssize_t vmbus_show_device_attr(struct device *dev, */ static int vmbus_bus_init(void) { - struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv; - struct hv_driver *driver = &g_vmbus_drv.drv_obj; - struct vm_device *dev_ctx = &g_vmbus_drv.device_ctx; + struct vmbus_driver_context *vmbus_drv_ctx = &vmbus_drv; + struct hv_driver *driver = &vmbus_drv.drv_obj; + struct vm_device *dev_ctx = &vmbus_drv.device_ctx; int ret; unsigned int vector; @@ -478,8 +478,8 @@ static int vmbus_bus_init(void) sizeof(struct vmbus_channel_packet_page_buffer), sizeof(struct vmbus_channel_packet_multipage_buffer)); - driver->name = gDriverName; - memcpy(&driver->deviceType, &gVmbusDeviceType, sizeof(struct hv_guid)); + driver->name = driver_name; + memcpy(&driver->deviceType, &device_type, sizeof(struct hv_guid)); /* Setup dispatch table */ driver->OnDeviceAdd = VmbusOnDeviceAdd; @@ -590,10 +590,10 @@ cleanup: */ static void vmbus_bus_exit(void) { - struct hv_driver *driver = &g_vmbus_drv.drv_obj; - struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv; + struct hv_driver *driver = &vmbus_drv.drv_obj; + struct vmbus_driver_context *vmbus_drv_ctx = &vmbus_drv; - struct vm_device *dev_ctx = &g_vmbus_drv.device_ctx; + struct vm_device *dev_ctx = &vmbus_drv.device_ctx; /* Remove the root device */ if (driver->OnDeviceRemove) @@ -634,7 +634,7 @@ int vmbus_child_driver_register(struct driver_context *driver_ctx) driver_ctx, driver_ctx->driver.name); /* The child driver on this vmbus */ - driver_ctx->driver.bus = &g_vmbus_drv.bus; + driver_ctx->driver.bus = &vmbus_drv.bus; ret = driver_register(&driver_ctx->driver); @@ -737,7 +737,7 @@ int vmbus_child_device_register(struct hv_device *root_device_obj, atomic_inc_return(&device_num)); /* The new device belongs to this bus */ - child_device_ctx->device.bus = &g_vmbus_drv.bus; /* device->dev.bus; */ + child_device_ctx->device.bus = &vmbus_drv.bus; /* device->dev.bus; */ child_device_ctx->device.parent = &root_device_ctx->device; child_device_ctx->device.release = vmbus_device_release; @@ -1050,7 +1050,7 @@ static void vmbus_event_dpc(unsigned long data) static irqreturn_t vmbus_isr(int irq, void *dev_id) { - struct hv_driver *driver = &g_vmbus_drv.drv_obj; + struct hv_driver *driver = &vmbus_drv.drv_obj; int ret; /* Call to bus driver to handle interrupt */ @@ -1059,10 +1059,10 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) /* Schedules a dpc if necessary */ if (ret > 0) { if (test_bit(0, (unsigned long *)&ret)) - tasklet_schedule(&g_vmbus_drv.msg_dpc); + tasklet_schedule(&vmbus_drv.msg_dpc); if (test_bit(1, (unsigned long *)&ret)) - tasklet_schedule(&g_vmbus_drv.event_dpc); + tasklet_schedule(&vmbus_drv.event_dpc); return IRQ_HANDLED; } else { -- cgit v1.2.3 From 646f1ea3796c7bd46587e4a9b58f64cf005efdfe Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Wed, 26 Jan 2011 12:12:10 -0800 Subject: staging: hv: Convert camel cased functions in vmbus_drv.c to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel_mgmt.c | 4 ++-- drivers/staging/hv/vmbus_drv.c | 22 +++++++++++----------- drivers/staging/hv/vmbus_private.h | 6 +++--- 3 files changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 0ce8f54cfc2e..732a457c3b49 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -391,7 +391,7 @@ static void vmbus_process_offer(struct work_struct *work) /* * Start the process of binding this offer to the driver * We need to set the DeviceObject field before calling - * VmbusChildDeviceAdd() + * vmbus_child_dev_add() */ newchannel->device_obj = vmbus_child_device_create( &newchannel->offermsg.offer.InterfaceType, @@ -406,7 +406,7 @@ static void vmbus_process_offer(struct work_struct *work) * binding which eventually invokes the device driver's AddDevice() * method. */ - ret = VmbusChildDeviceAdd(newchannel->device_obj); + ret = vmbus_child_dev_add(newchannel->device_obj); if (ret != 0) { DPRINT_ERR(VMBUS, "unable to add child device object (relid %d)", diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 99686f06d2f5..0c0aadbea1f7 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -148,17 +148,17 @@ static const struct hv_guid device_id = { static struct hv_device *vmbus_device; /* vmbus root device */ /* - * VmbusChildDeviceAdd - Registers the child device with the vmbus + * vmbus_child_dev_add - Registers the child device with the vmbus */ -int VmbusChildDeviceAdd(struct hv_device *child_dev) +int vmbus_child_dev_add(struct hv_device *child_dev) { return vmbus_child_device_register(vmbus_device, child_dev); } /* - * VmbusOnDeviceAdd - Callback when the root bus device is added + * vmbus_dev_add - Callback when the root bus device is added */ -static int VmbusOnDeviceAdd(struct hv_device *dev, void *info) +static int vmbus_dev_add(struct hv_device *dev, void *info) { u32 *irqvector = info; int ret; @@ -181,9 +181,9 @@ static int VmbusOnDeviceAdd(struct hv_device *dev, void *info) } /* - * VmbusOnDeviceRemove - Callback when the root bus device is removed + * vmbus_dev_rm - Callback when the root bus device is removed */ -static int VmbusOnDeviceRemove(struct hv_device *dev) +static int vmbus_dev_rm(struct hv_device *dev) { int ret = 0; @@ -194,9 +194,9 @@ static int VmbusOnDeviceRemove(struct hv_device *dev) } /* - * VmbusOnCleanup - Perform any cleanup when the driver is removed + * vmbus_cleanup - Perform any cleanup when the driver is removed */ -static void VmbusOnCleanup(struct hv_driver *drv) +static void vmbus_cleanup(struct hv_driver *drv) { /* struct vmbus_driver *driver = (struct vmbus_driver *)drv; */ @@ -482,9 +482,9 @@ static int vmbus_bus_init(void) memcpy(&driver->deviceType, &device_type, sizeof(struct hv_guid)); /* Setup dispatch table */ - driver->OnDeviceAdd = VmbusOnDeviceAdd; - driver->OnDeviceRemove = VmbusOnDeviceRemove; - driver->OnCleanup = VmbusOnCleanup; + driver->OnDeviceAdd = vmbus_dev_add; + driver->OnDeviceRemove = vmbus_dev_rm; + driver->OnCleanup = vmbus_cleanup; /* Hypervisor initialization...setup hypercall page..etc */ ret = hv_init(); diff --git a/drivers/staging/hv/vmbus_private.h b/drivers/staging/hv/vmbus_private.h index e3b0663b8db5..0ab404ed3609 100644 --- a/drivers/staging/hv/vmbus_private.h +++ b/drivers/staging/hv/vmbus_private.h @@ -102,11 +102,11 @@ extern struct VMBUS_CONNECTION vmbus_connection; /* General vmbus interface */ -struct hv_device *vmbus_child_device_create(struct hv_guid *deviceType, - struct hv_guid *deviceInstance, +struct hv_device *vmbus_child_device_create(struct hv_guid *type, + struct hv_guid *instance, struct vmbus_channel *channel); -int VmbusChildDeviceAdd(struct hv_device *Device); +int vmbus_child_dev_add(struct hv_device *device); int vmbus_child_device_register(struct hv_device *root_device_obj, struct hv_device *child_device_obj); void vmbus_child_device_unregister(struct hv_device *device_obj); -- cgit v1.2.3 From ca623ad3558f71efa08ec0fdefd79989a32a88e2 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Wed, 26 Jan 2011 12:12:11 -0800 Subject: staging: hv: Convert camel cased struct fields in vmbus_api.h to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc.c | 20 ++--- drivers/staging/hv/blkvsc_drv.c | 56 ++++++------ drivers/staging/hv/channel.c | 20 ++--- drivers/staging/hv/channel_mgmt.c | 2 +- drivers/staging/hv/netvsc.c | 58 ++++++------ drivers/staging/hv/netvsc_drv.c | 38 ++++---- drivers/staging/hv/rndis_filter.c | 52 +++++------ drivers/staging/hv/storvsc.c | 34 +++---- drivers/staging/hv/storvsc_drv.c | 28 +++--- drivers/staging/hv/vmbus_api.h | 68 +++++++------- drivers/staging/hv/vmbus_drv.c | 181 +++++++++++++++++++------------------- 11 files changed, 279 insertions(+), 278 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/blkvsc.c b/drivers/staging/hv/blkvsc.c index 11a2523a74e3..b0e07c1fc4c8 100644 --- a/drivers/staging/hv/blkvsc.c +++ b/drivers/staging/hv/blkvsc.c @@ -51,13 +51,13 @@ static int blk_vsc_on_device_add(struct hv_device *device, void *additional_info * id. For IDE devices, the device instance id is formatted as * * - - 8899 - 000000000000. */ - device_info->path_id = device->deviceInstance.data[3] << 24 | - device->deviceInstance.data[2] << 16 | - device->deviceInstance.data[1] << 8 | - device->deviceInstance.data[0]; + device_info->path_id = device->dev_instance.data[3] << 24 | + device->dev_instance.data[2] << 16 | + device->dev_instance.data[1] << 8 | + device->dev_instance.data[0]; - device_info->target_id = device->deviceInstance.data[5] << 8 | - device->deviceInstance.data[4]; + device_info->target_id = device->dev_instance.data[5] << 8 | + device->dev_instance.data[4]; return ret; } @@ -73,7 +73,7 @@ int blk_vsc_initialize(struct hv_driver *driver) /* ASSERT(stor_driver->RingBufferSize >= (PAGE_SIZE << 1)); */ driver->name = g_blk_driver_name; - memcpy(&driver->deviceType, &g_blk_device_type, sizeof(struct hv_guid)); + memcpy(&driver->dev_type, &g_blk_device_type, sizeof(struct hv_guid)); stor_driver->request_ext_size = sizeof(struct storvsc_request_extension); @@ -93,9 +93,9 @@ int blk_vsc_initialize(struct hv_driver *driver) stor_driver->max_outstanding_req_per_channel); /* Setup the dispatch table */ - stor_driver->base.OnDeviceAdd = blk_vsc_on_device_add; - stor_driver->base.OnDeviceRemove = stor_vsc_on_device_remove; - stor_driver->base.OnCleanup = stor_vsc_on_cleanup; + stor_driver->base.dev_add = blk_vsc_on_device_add; + stor_driver->base.dev_rm = stor_vsc_on_device_remove; + stor_driver->base.cleanup = stor_vsc_on_cleanup; stor_driver->on_io_request = stor_vsc_on_io_request; return ret; diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index b3d05fcfe6d2..b0e83162e6bc 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -183,7 +183,7 @@ static int blkvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) drv_init(&storvsc_drv_obj->base); drv_ctx->driver.name = storvsc_drv_obj->base.name; - memcpy(&drv_ctx->class_id, &storvsc_drv_obj->base.deviceType, + memcpy(&drv_ctx->class_id, &storvsc_drv_obj->base.dev_type, sizeof(struct hv_guid)); drv_ctx->probe = blkvsc_probe; @@ -230,8 +230,8 @@ static void blkvsc_drv_exit(void) device_unregister(current_dev); } - if (storvsc_drv_obj->base.OnCleanup) - storvsc_drv_obj->base.OnCleanup(&storvsc_drv_obj->base); + if (storvsc_drv_obj->base.cleanup) + storvsc_drv_obj->base.cleanup(&storvsc_drv_obj->base); vmbus_child_driver_unregister(drv_ctx); @@ -262,7 +262,7 @@ static int blkvsc_probe(struct device *device) DPRINT_DBG(BLKVSC_DRV, "blkvsc_probe - enter"); - if (!storvsc_drv_obj->base.OnDeviceAdd) { + if (!storvsc_drv_obj->base.dev_add) { DPRINT_ERR(BLKVSC_DRV, "OnDeviceAdd() not set"); ret = -1; goto Cleanup; @@ -293,7 +293,7 @@ static int blkvsc_probe(struct device *device) /* Call to the vsc driver to add the device */ - ret = storvsc_drv_obj->base.OnDeviceAdd(device_obj, &device_info); + ret = storvsc_drv_obj->base.dev_add(device_obj, &device_info); if (ret != 0) { DPRINT_ERR(BLKVSC_DRV, "unable to add blkvsc device"); goto Cleanup; @@ -391,7 +391,7 @@ static int blkvsc_probe(struct device *device) return ret; Remove: - storvsc_drv_obj->base.OnDeviceRemove(device_obj); + storvsc_drv_obj->base.dev_rm(device_obj); Cleanup: if (blkdev) { @@ -459,9 +459,9 @@ static int blkvsc_do_flush(struct block_device_context *blkdev) blkvsc_req->req = NULL; blkvsc_req->write = 0; - blkvsc_req->request.data_buffer.PfnArray[0] = 0; - blkvsc_req->request.data_buffer.Offset = 0; - blkvsc_req->request.data_buffer.Length = 0; + blkvsc_req->request.data_buffer.pfn_array[0] = 0; + blkvsc_req->request.data_buffer.offset = 0; + blkvsc_req->request.data_buffer.len = 0; blkvsc_req->cmnd[0] = SYNCHRONIZE_CACHE; blkvsc_req->cmd_len = 10; @@ -506,9 +506,9 @@ static int blkvsc_do_inquiry(struct block_device_context *blkdev) blkvsc_req->req = NULL; blkvsc_req->write = 0; - blkvsc_req->request.data_buffer.PfnArray[0] = page_to_pfn(page_buf); - blkvsc_req->request.data_buffer.Offset = 0; - blkvsc_req->request.data_buffer.Length = 64; + blkvsc_req->request.data_buffer.pfn_array[0] = page_to_pfn(page_buf); + blkvsc_req->request.data_buffer.offset = 0; + blkvsc_req->request.data_buffer.len = 64; blkvsc_req->cmnd[0] = INQUIRY; blkvsc_req->cmnd[1] = 0x1; /* Get product data */ @@ -593,9 +593,9 @@ static int blkvsc_do_read_capacity(struct block_device_context *blkdev) blkvsc_req->req = NULL; blkvsc_req->write = 0; - blkvsc_req->request.data_buffer.PfnArray[0] = page_to_pfn(page_buf); - blkvsc_req->request.data_buffer.Offset = 0; - blkvsc_req->request.data_buffer.Length = 8; + blkvsc_req->request.data_buffer.pfn_array[0] = page_to_pfn(page_buf); + blkvsc_req->request.data_buffer.offset = 0; + blkvsc_req->request.data_buffer.len = 8; blkvsc_req->cmnd[0] = READ_CAPACITY; blkvsc_req->cmd_len = 16; @@ -670,9 +670,9 @@ static int blkvsc_do_read_capacity16(struct block_device_context *blkdev) blkvsc_req->req = NULL; blkvsc_req->write = 0; - blkvsc_req->request.data_buffer.PfnArray[0] = page_to_pfn(page_buf); - blkvsc_req->request.data_buffer.Offset = 0; - blkvsc_req->request.data_buffer.Length = 12; + blkvsc_req->request.data_buffer.pfn_array[0] = page_to_pfn(page_buf); + blkvsc_req->request.data_buffer.offset = 0; + blkvsc_req->request.data_buffer.len = 12; blkvsc_req->cmnd[0] = 0x9E; /* READ_CAPACITY16; */ blkvsc_req->cmd_len = 16; @@ -741,14 +741,14 @@ static int blkvsc_remove(struct device *device) DPRINT_DBG(BLKVSC_DRV, "blkvsc_remove()\n"); - if (!storvsc_drv_obj->base.OnDeviceRemove) + if (!storvsc_drv_obj->base.dev_rm) return -1; /* * Call to the vsc driver to let it know that the device is being * removed */ - ret = storvsc_drv_obj->base.OnDeviceRemove(device_obj); + ret = storvsc_drv_obj->base.dev_rm(device_obj); if (ret != 0) { /* TODO: */ DPRINT_ERR(BLKVSC_DRV, @@ -865,10 +865,10 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, (blkvsc_req->write) ? "WRITE" : "READ", (unsigned long) blkvsc_req->sector_start, blkvsc_req->sector_count, - blkvsc_req->request.data_buffer.Offset, - blkvsc_req->request.data_buffer.Length); + blkvsc_req->request.data_buffer.offset, + blkvsc_req->request.data_buffer.len); #if 0 - for (i = 0; i < (blkvsc_req->request.data_buffer.Length >> 12); i++) { + for (i = 0; i < (blkvsc_req->request.data_buffer.len >> 12); i++) { DPRINT_DBG(BLKVSC_DRV, "blkvsc_submit_request() - " "req %p pfn[%d] %llx\n", blkvsc_req, i, @@ -992,9 +992,9 @@ static int blkvsc_do_request(struct block_device_context *blkdev, blkvsc_req->dev = blkdev; blkvsc_req->req = req; - blkvsc_req->request.data_buffer.Offset + blkvsc_req->request.data_buffer.offset = bvec->bv_offset; - blkvsc_req->request.data_buffer.Length + blkvsc_req->request.data_buffer.len = 0; /* Add to the group */ @@ -1010,9 +1010,9 @@ static int blkvsc_do_request(struct block_device_context *blkdev, /* Add the curr bvec/segment to the curr blkvsc_req */ blkvsc_req->request.data_buffer. - PfnArray[databuf_idx] + pfn_array[databuf_idx] = page_to_pfn(bvec->bv_page); - blkvsc_req->request.data_buffer.Length + blkvsc_req->request.data_buffer.len += bvec->bv_len; prev_bvec = bvec; @@ -1115,7 +1115,7 @@ static void blkvsc_request_completion(struct hv_storvsc_request *request) (blkvsc_req->write) ? "WRITE" : "READ", (unsigned long)blkvsc_req->sector_start, blkvsc_req->sector_count, - blkvsc_req->request.data_buffer.Length, + blkvsc_req->request.data_buffer.len, blkvsc_req->group->outstanding, blkdev->num_outstanding_reqs); diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index ca7609868650..960e155d34ef 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -806,9 +806,9 @@ int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel, desc.rangecount = pagecount; for (i = 0; i < pagecount; i++) { - desc.range[i].Length = pagebuffers[i].Length; - desc.range[i].Offset = pagebuffers[i].Offset; - desc.range[i].Pfn = pagebuffers[i].Pfn; + desc.range[i].len = pagebuffers[i].len; + desc.range[i].offset = pagebuffers[i].offset; + desc.range[i].pfn = pagebuffers[i].pfn; } sg_init_table(bufferlist, 3); @@ -842,14 +842,14 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, u32 packetlen_aligned; struct scatterlist bufferlist[3]; u64 aligned_data = 0; - u32 pfncount = NUM_PAGES_SPANNED(multi_pagebuffer->Offset, - multi_pagebuffer->Length); + u32 pfncount = NUM_PAGES_SPANNED(multi_pagebuffer->offset, + multi_pagebuffer->len); dump_vmbus_channel(channel); DPRINT_DBG(VMBUS, "data buffer - offset %u len %u pfn count %u", - multi_pagebuffer->Offset, - multi_pagebuffer->Length, pfncount); + multi_pagebuffer->offset, + multi_pagebuffer->len, pfncount); if ((pfncount < 0) || (pfncount > MAX_MULTIPAGE_BUFFER_COUNT)) return -EINVAL; @@ -874,10 +874,10 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, desc.transactionid = requestid; desc.rangecount = 1; - desc.range.Length = multi_pagebuffer->Length; - desc.range.Offset = multi_pagebuffer->Offset; + desc.range.len = multi_pagebuffer->len; + desc.range.offset = multi_pagebuffer->offset; - memcpy(desc.range.PfnArray, multi_pagebuffer->PfnArray, + memcpy(desc.range.pfn_array, multi_pagebuffer->pfn_array, pfncount * sizeof(u64)); sg_init_table(bufferlist, 3); diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 732a457c3b49..b4a856155b29 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -864,7 +864,7 @@ void vmbus_release_unattached_channels(void) if (channel == start) break; - if (!channel->device_obj->Driver) { + if (!channel->device_obj->drv) { list_del(&channel->listentry); DPRINT_INFO(VMBUS, "Releasing unattached device object %p", diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index df9cd131e953..b13a070dcfac 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -86,7 +86,7 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device) atomic_cmpxchg(&net_device->refcnt, 0, 2); net_device->dev = device; - device->Extension = net_device; + device->ext = net_device; return net_device; } @@ -94,7 +94,7 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device) static void free_net_device(struct netvsc_device *device) { WARN_ON(atomic_read(&device->refcnt) == 0); - device->dev->Extension = NULL; + device->dev->ext = NULL; kfree(device); } @@ -104,7 +104,7 @@ static struct netvsc_device *get_outbound_net_device(struct hv_device *device) { struct netvsc_device *net_device; - net_device = device->Extension; + net_device = device->ext; if (net_device && atomic_read(&net_device->refcnt) > 1) atomic_inc(&net_device->refcnt); else @@ -118,7 +118,7 @@ static struct netvsc_device *get_inbound_net_device(struct hv_device *device) { struct netvsc_device *net_device; - net_device = device->Extension; + net_device = device->ext; if (net_device && atomic_read(&net_device->refcnt)) atomic_inc(&net_device->refcnt); else @@ -131,7 +131,7 @@ static void put_net_device(struct hv_device *device) { struct netvsc_device *net_device; - net_device = device->Extension; + net_device = device->ext; /* ASSERT(netDevice); */ atomic_dec(&net_device->refcnt); @@ -142,7 +142,7 @@ static struct netvsc_device *release_outbound_net_device( { struct netvsc_device *net_device; - net_device = device->Extension; + net_device = device->ext; if (net_device == NULL) return NULL; @@ -158,7 +158,7 @@ static struct netvsc_device *release_inbound_net_device( { struct netvsc_device *net_device; - net_device = device->Extension; + net_device = device->ext; if (net_device == NULL) return NULL; @@ -166,7 +166,7 @@ static struct netvsc_device *release_inbound_net_device( while (atomic_cmpxchg(&net_device->refcnt, 1, 0) != 1) udelay(100); - device->Extension = NULL; + device->ext = NULL; return net_device; } @@ -188,7 +188,7 @@ int netvsc_initialize(struct hv_driver *drv) /* ASSERT(driver->RingBufferSize >= (PAGE_SIZE << 1)); */ drv->name = driver_name; - memcpy(&drv->deviceType, &netvsc_device_type, sizeof(struct hv_guid)); + memcpy(&drv->dev_type, &netvsc_device_type, sizeof(struct hv_guid)); /* Make sure it is set by the caller */ /* FIXME: These probably should still be tested in some way */ @@ -196,9 +196,9 @@ int netvsc_initialize(struct hv_driver *drv) /* ASSERT(driver->OnLinkStatusChanged); */ /* Setup the dispatch table */ - driver->base.OnDeviceAdd = netvsc_device_add; - driver->base.OnDeviceRemove = netvsc_device_remove; - driver->base.OnCleanup = netvsc_cleanup; + driver->base.dev_add = netvsc_device_add; + driver->base.dev_rm = netvsc_device_remove; + driver->base.cleanup = netvsc_cleanup; driver->send = netvsc_send; @@ -708,7 +708,7 @@ static int netvsc_device_add(struct hv_device *device, void *additional_info) struct netvsc_device *net_device; struct hv_netvsc_packet *packet, *pos; struct netvsc_driver *net_driver = - (struct netvsc_driver *)device->Driver; + (struct netvsc_driver *)device->drv; net_device = alloc_net_device(device); if (!net_device) { @@ -806,7 +806,7 @@ static int netvsc_device_remove(struct hv_device *device) struct hv_netvsc_packet *netvsc_packet, *pos; DPRINT_INFO(NETVSC, "Disabling outbound traffic on net device (%p)...", - device->Extension); + device->ext); /* Stop outbound traffic ie sends and receives completions */ net_device = release_outbound_net_device(device); @@ -827,7 +827,7 @@ static int netvsc_device_remove(struct hv_device *device) NetVscDisconnectFromVsp(net_device); DPRINT_INFO(NETVSC, "Disabling inbound traffic on net device (%p)...", - device->Extension); + device->ext); /* Stop inbound traffic ie receives and sends completions */ net_device = release_inbound_net_device(device); @@ -1101,42 +1101,42 @@ static void netvsc_receive(struct hv_device *device, /* vmxferpagePacket->Ranges[i].ByteCount < */ /* netDevice->ReceiveBufferSize); */ - netvsc_packet->page_buf[0].Length = + netvsc_packet->page_buf[0].len = vmxferpage_packet->Ranges[i].ByteCount; start = virt_to_phys((void *)((unsigned long)net_device-> recv_buf + vmxferpage_packet->Ranges[i].ByteOffset)); - netvsc_packet->page_buf[0].Pfn = start >> PAGE_SHIFT; + netvsc_packet->page_buf[0].pfn = start >> PAGE_SHIFT; end_virtual = (unsigned long)net_device->recv_buf + vmxferpage_packet->Ranges[i].ByteOffset + vmxferpage_packet->Ranges[i].ByteCount - 1; end = virt_to_phys((void *)end_virtual); /* Calculate the page relative offset */ - netvsc_packet->page_buf[0].Offset = + netvsc_packet->page_buf[0].offset = vmxferpage_packet->Ranges[i].ByteOffset & (PAGE_SIZE - 1); if ((end >> PAGE_SHIFT) != (start >> PAGE_SHIFT)) { /* Handle frame across multiple pages: */ - netvsc_packet->page_buf[0].Length = - (netvsc_packet->page_buf[0].Pfn << + netvsc_packet->page_buf[0].len = + (netvsc_packet->page_buf[0].pfn << PAGE_SHIFT) + PAGE_SIZE - start; bytes_remain = netvsc_packet->total_data_buflen - - netvsc_packet->page_buf[0].Length; + netvsc_packet->page_buf[0].len; for (j = 1; j < NETVSC_PACKET_MAXPAGE; j++) { - netvsc_packet->page_buf[j].Offset = 0; + netvsc_packet->page_buf[j].offset = 0; if (bytes_remain <= PAGE_SIZE) { - netvsc_packet->page_buf[j].Length = + netvsc_packet->page_buf[j].len = bytes_remain; bytes_remain = 0; } else { - netvsc_packet->page_buf[j].Length = + netvsc_packet->page_buf[j].len = PAGE_SIZE; bytes_remain -= PAGE_SIZE; } - netvsc_packet->page_buf[j].Pfn = + netvsc_packet->page_buf[j].pfn = virt_to_phys((void *)(end_virtual - bytes_remain)) >> PAGE_SHIFT; netvsc_packet->page_buf_cnt++; @@ -1149,12 +1149,12 @@ static void netvsc_receive(struct hv_device *device, "(pfn %llx, offset %u, len %u)", i, vmxferpage_packet->Ranges[i].ByteOffset, vmxferpage_packet->Ranges[i].ByteCount, - netvsc_packet->page_buf[0].Pfn, - netvsc_packet->page_buf[0].Offset, - netvsc_packet->page_buf[0].Length); + netvsc_packet->page_buf[0].pfn, + netvsc_packet->page_buf[0].offset, + netvsc_packet->page_buf[0].len); /* Pass it to the upper layer */ - ((struct netvsc_driver *)device->Driver)-> + ((struct netvsc_driver *)device->drv)-> recv_cb(device, netvsc_packet); netvsc_receive_completion(netvsc_packet-> diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 0147b407512c..9d9313899fe5 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -178,18 +178,18 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) packet->total_data_buflen = skb->len; /* Start filling in the page buffers starting after RNDIS buffer. */ - packet->page_buf[1].Pfn = virt_to_phys(skb->data) >> PAGE_SHIFT; - packet->page_buf[1].Offset + packet->page_buf[1].pfn = virt_to_phys(skb->data) >> PAGE_SHIFT; + packet->page_buf[1].offset = (unsigned long)skb->data & (PAGE_SIZE - 1); - packet->page_buf[1].Length = skb_headlen(skb); + packet->page_buf[1].len = skb_headlen(skb); /* Additional fragments are after SKB data */ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { skb_frag_t *f = &skb_shinfo(skb)->frags[i]; - packet->page_buf[i+2].Pfn = page_to_pfn(f->page); - packet->page_buf[i+2].Offset = f->page_offset; - packet->page_buf[i+2].Length = f->size; + packet->page_buf[i+2].pfn = page_to_pfn(f->page); + packet->page_buf[i+2].offset = f->page_offset; + packet->page_buf[i+2].len = f->size; } /* Set the completion routine */ @@ -277,16 +277,16 @@ static int netvsc_recv_callback(struct hv_device *device_obj, * hv_netvsc_packet cannot be deallocated */ for (i = 0; i < packet->page_buf_cnt; i++) { - data = kmap_atomic(pfn_to_page(packet->page_buf[i].Pfn), + data = kmap_atomic(pfn_to_page(packet->page_buf[i].pfn), KM_IRQ1); data = (void *)(unsigned long)data + - packet->page_buf[i].Offset; + packet->page_buf[i].offset; - memcpy(skb_put(skb, packet->page_buf[i].Length), data, - packet->page_buf[i].Length); + memcpy(skb_put(skb, packet->page_buf[i].len), data, + packet->page_buf[i].len); kunmap_atomic((void *)((unsigned long)data - - packet->page_buf[i].Offset), KM_IRQ1); + packet->page_buf[i].offset), KM_IRQ1); } local_irq_restore(flags); @@ -349,7 +349,7 @@ static int netvsc_probe(struct device *device) struct netvsc_device_info device_info; int ret; - if (!net_drv_obj->base.OnDeviceAdd) + if (!net_drv_obj->base.dev_add) return -1; net = alloc_etherdev(sizeof(struct net_device_context)); @@ -366,7 +366,7 @@ static int netvsc_probe(struct device *device) dev_set_drvdata(device, net); /* Notify the netvsc driver of the new device */ - ret = net_drv_obj->base.OnDeviceAdd(device_obj, &device_info); + ret = net_drv_obj->base.dev_add(device_obj, &device_info); if (ret != 0) { free_netdev(net); dev_set_drvdata(device, NULL); @@ -401,7 +401,7 @@ static int netvsc_probe(struct device *device) ret = register_netdev(net); if (ret != 0) { /* Remove the device and release the resource */ - net_drv_obj->base.OnDeviceRemove(device_obj); + net_drv_obj->base.dev_rm(device_obj); free_netdev(net); } @@ -425,7 +425,7 @@ static int netvsc_remove(struct device *device) return 0; } - if (!net_drv_obj->base.OnDeviceRemove) + if (!net_drv_obj->base.dev_rm) return -1; /* Stop outbound asap */ @@ -438,7 +438,7 @@ static int netvsc_remove(struct device *device) * Call to the vsc driver to let it know that the device is being * removed */ - ret = net_drv_obj->base.OnDeviceRemove(device_obj); + ret = net_drv_obj->base.dev_rm(device_obj); if (ret != 0) { /* TODO: */ DPRINT_ERR(NETVSC, "unable to remove vsc device (ret %d)", ret); @@ -484,8 +484,8 @@ static void netvsc_drv_exit(void) device_unregister(current_dev); } - if (netvsc_drv_obj->base.OnCleanup) - netvsc_drv_obj->base.OnCleanup(&netvsc_drv_obj->base); + if (netvsc_drv_obj->base.cleanup) + netvsc_drv_obj->base.cleanup(&netvsc_drv_obj->base); vmbus_child_driver_unregister(drv_ctx); @@ -506,7 +506,7 @@ static int netvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) drv_init(&net_drv_obj->base); drv_ctx->driver.name = net_drv_obj->base.name; - memcpy(&drv_ctx->class_id, &net_drv_obj->base.deviceType, + memcpy(&drv_ctx->class_id, &net_drv_obj->base.dev_type, sizeof(struct hv_guid)); drv_ctx->probe = netvsc_probe; diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c index 53676dcbf381..287e12eddd89 100644 --- a/drivers/staging/hv/rndis_filter.c +++ b/drivers/staging/hv/rndis_filter.c @@ -255,10 +255,10 @@ static int rndis_filter_send_request(struct rndis_device *dev, packet->total_data_buflen = req->request_msg.msg_len; packet->page_buf_cnt = 1; - packet->page_buf[0].Pfn = virt_to_phys(&req->request_msg) >> + packet->page_buf[0].pfn = virt_to_phys(&req->request_msg) >> PAGE_SHIFT; - packet->page_buf[0].Length = req->request_msg.msg_len; - packet->page_buf[0].Offset = + packet->page_buf[0].len = req->request_msg.msg_len; + packet->page_buf[0].offset = (unsigned long)&req->request_msg & (PAGE_SIZE - 1); packet->completion.send.send_completion_ctx = req;/* packet; */ @@ -371,8 +371,8 @@ static void rndis_filter_receive_data(struct rndis_device *dev, data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset; pkt->total_data_buflen -= data_offset; - pkt->page_buf[0].Offset += data_offset; - pkt->page_buf[0].Length -= data_offset; + pkt->page_buf[0].offset += data_offset; + pkt->page_buf[0].len -= data_offset; pkt->is_data_pkt = true; @@ -383,7 +383,7 @@ static void rndis_filter_receive_data(struct rndis_device *dev, static int rndis_filter_receive(struct hv_device *dev, struct hv_netvsc_packet *pkt) { - struct netvsc_device *net_dev = dev->Extension; + struct netvsc_device *net_dev = dev->ext; struct rndis_device *rndis_dev; struct rndis_message rndis_msg; struct rndis_message *rndis_hdr; @@ -406,10 +406,10 @@ static int rndis_filter_receive(struct hv_device *dev, } rndis_hdr = (struct rndis_message *)kmap_atomic( - pfn_to_page(pkt->page_buf[0].Pfn), KM_IRQ0); + pfn_to_page(pkt->page_buf[0].pfn), KM_IRQ0); rndis_hdr = (void *)((unsigned long)rndis_hdr + - pkt->page_buf[0].Offset); + pkt->page_buf[0].offset); /* Make sure we got a valid rndis message */ /* @@ -419,7 +419,7 @@ static int rndis_filter_receive(struct hv_device *dev, * */ #if 0 if (pkt->total_data_buflen != rndis_hdr->msg_len) { - kunmap_atomic(rndis_hdr - pkt->page_buf[0].Offset, + kunmap_atomic(rndis_hdr - pkt->page_buf[0].offset, KM_IRQ0); DPRINT_ERR(NETVSC, "invalid rndis message? (expected %u " @@ -443,7 +443,7 @@ static int rndis_filter_receive(struct hv_device *dev, sizeof(struct rndis_message) : rndis_hdr->msg_len); - kunmap_atomic(rndis_hdr - pkt->page_buf[0].Offset, KM_IRQ0); + kunmap_atomic(rndis_hdr - pkt->page_buf[0].offset, KM_IRQ0); dump_rndis_message(&rndis_msg); @@ -622,10 +622,10 @@ int rndis_filter_init(struct netvsc_driver *drv) rndisDriver->OnLinkStatusChanged = Driver->OnLinkStatusChanged;*/ /* Save the original dispatch handlers before we override it */ - rndis_filter.inner_drv.base.OnDeviceAdd = drv->base.OnDeviceAdd; - rndis_filter.inner_drv.base.OnDeviceRemove = - drv->base.OnDeviceRemove; - rndis_filter.inner_drv.base.OnCleanup = drv->base.OnCleanup; + rndis_filter.inner_drv.base.dev_add = drv->base.dev_add; + rndis_filter.inner_drv.base.dev_rm = + drv->base.dev_rm; + rndis_filter.inner_drv.base.cleanup = drv->base.cleanup; /* ASSERT(Driver->OnSend); */ /* ASSERT(Driver->OnReceiveCallback); */ @@ -635,9 +635,9 @@ int rndis_filter_init(struct netvsc_driver *drv) drv->link_status_change; /* Override */ - drv->base.OnDeviceAdd = rndis_filte_device_add; - drv->base.OnDeviceRemove = rndis_filter_device_remove; - drv->base.OnCleanup = rndis_filter_cleanup; + drv->base.dev_add = rndis_filte_device_add; + drv->base.dev_rm = rndis_filter_device_remove; + drv->base.cleanup = rndis_filter_cleanup; drv->send = rndis_filter_send; /* Driver->QueryLinkStatus = RndisFilterQueryDeviceLinkStatus; */ drv->recv_cb = rndis_filter_receive; @@ -770,7 +770,7 @@ static int rndis_filte_device_add(struct hv_device *dev, * NOTE! Once the channel is created, we may get a receive callback * (RndisFilterOnReceive()) before this call is completed */ - ret = rndis_filter.inner_drv.base.OnDeviceAdd(dev, additional_info); + ret = rndis_filter.inner_drv.base.dev_add(dev, additional_info); if (ret != 0) { kfree(rndisDevice); return ret; @@ -778,7 +778,7 @@ static int rndis_filte_device_add(struct hv_device *dev, /* Initialize the rndis device */ - netDevice = dev->Extension; + netDevice = dev->ext; /* ASSERT(netDevice); */ /* ASSERT(netDevice->Device); */ @@ -818,7 +818,7 @@ static int rndis_filte_device_add(struct hv_device *dev, static int rndis_filter_device_remove(struct hv_device *dev) { - struct netvsc_device *net_dev = dev->Extension; + struct netvsc_device *net_dev = dev->ext; struct rndis_device *rndis_dev = net_dev->extension; /* Halt and release the rndis device */ @@ -828,7 +828,7 @@ static int rndis_filter_device_remove(struct hv_device *dev) net_dev->extension = NULL; /* Pass control to inner driver to remove the device */ - rndis_filter.inner_drv.base.OnDeviceRemove(dev); + rndis_filter.inner_drv.base.dev_rm(dev); return 0; } @@ -839,7 +839,7 @@ static void rndis_filter_cleanup(struct hv_driver *drv) int rndis_filter_open(struct hv_device *dev) { - struct netvsc_device *netDevice = dev->Extension; + struct netvsc_device *netDevice = dev->ext; if (!netDevice) return -EINVAL; @@ -849,7 +849,7 @@ int rndis_filter_open(struct hv_device *dev) int rndis_filter_close(struct hv_device *dev) { - struct netvsc_device *netDevice = dev->Extension; + struct netvsc_device *netDevice = dev->ext; if (!netDevice) return -EINVAL; @@ -884,10 +884,10 @@ static int rndis_filter_send(struct hv_device *dev, rndisPacket->data_len = pkt->total_data_buflen; pkt->is_data_pkt = true; - pkt->page_buf[0].Pfn = virt_to_phys(rndisMessage) >> PAGE_SHIFT; - pkt->page_buf[0].Offset = + pkt->page_buf[0].pfn = virt_to_phys(rndisMessage) >> PAGE_SHIFT; + pkt->page_buf[0].offset = (unsigned long)rndisMessage & (PAGE_SIZE-1); - pkt->page_buf[0].Length = rndisMessageSize; + pkt->page_buf[0].len = rndisMessageSize; /* Save the packet send completion and context */ filterPacket->completion = pkt->completion.send.send_completion; diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 5680fb06532d..b80b1e921350 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -94,7 +94,7 @@ static inline struct storvsc_device *alloc_stor_device(struct hv_device *device) atomic_cmpxchg(&stor_device->ref_count, 0, 2); stor_device->device = device; - device->Extension = stor_device; + device->ext = stor_device; return stor_device; } @@ -110,7 +110,7 @@ static inline struct storvsc_device *get_stor_device(struct hv_device *device) { struct storvsc_device *stor_device; - stor_device = (struct storvsc_device *)device->Extension; + stor_device = (struct storvsc_device *)device->ext; if (stor_device && atomic_read(&stor_device->ref_count) > 1) atomic_inc(&stor_device->ref_count); else @@ -125,7 +125,7 @@ static inline struct storvsc_device *must_get_stor_device( { struct storvsc_device *stor_device; - stor_device = (struct storvsc_device *)device->Extension; + stor_device = (struct storvsc_device *)device->ext; if (stor_device && atomic_read(&stor_device->ref_count)) atomic_inc(&stor_device->ref_count); else @@ -138,7 +138,7 @@ static inline void put_stor_device(struct hv_device *device) { struct storvsc_device *stor_device; - stor_device = (struct storvsc_device *)device->Extension; + stor_device = (struct storvsc_device *)device->ext; /* ASSERT(stor_device); */ atomic_dec(&stor_device->ref_count); @@ -151,7 +151,7 @@ static inline struct storvsc_device *release_stor_device( { struct storvsc_device *stor_device; - stor_device = (struct storvsc_device *)device->Extension; + stor_device = (struct storvsc_device *)device->ext; /* ASSERT(stor_device); */ /* Busy wait until the ref drop to 2, then set it to 1 */ @@ -167,14 +167,14 @@ static inline struct storvsc_device *final_release_stor_device( { struct storvsc_device *stor_device; - stor_device = (struct storvsc_device *)device->Extension; + stor_device = (struct storvsc_device *)device->ext; /* ASSERT(stor_device); */ /* Busy wait until the ref drop to 1, then set it to 0 */ while (atomic_cmpxchg(&stor_device->ref_count, 1, 0) != 1) udelay(100); - device->Extension = NULL; + device->ext = NULL; return stor_device; } @@ -499,7 +499,7 @@ static int stor_vsc_connect_to_vsp(struct hv_device *device) struct storvsc_driver_object *stor_driver; int ret; - stor_driver = (struct storvsc_driver_object *)device->Driver; + stor_driver = (struct storvsc_driver_object *)device->drv; memset(&props, 0, sizeof(struct vmstorage_channel_properties)); /* Open the channel */ @@ -581,7 +581,7 @@ static int stor_vsc_on_device_remove(struct hv_device *device) struct storvsc_device *stor_device; DPRINT_INFO(STORVSC, "disabling storage device (%p)...", - device->Extension); + device->ext); stor_device = release_stor_device(device); @@ -597,7 +597,7 @@ static int stor_vsc_on_device_remove(struct hv_device *device) } DPRINT_INFO(STORVSC, "removing storage device (%p)...", - device->Extension); + device->ext); stor_device = final_release_stor_device(device); @@ -687,7 +687,7 @@ static int stor_vsc_on_io_request(struct hv_device *device, request_extension); DPRINT_DBG(STORVSC, "req %p len %d bus %d, target %d, lun %d cdblen %d", - request, request->data_buffer.Length, request->bus, + request, request->data_buffer.len, request->bus, request->target_id, request->lun_id, request->cdb_len); if (!stor_device) { @@ -720,7 +720,7 @@ static int stor_vsc_on_io_request(struct hv_device *device, memcpy(&vstor_packet->vm_srb.cdb, request->cdb, request->cdb_len); vstor_packet->vm_srb.data_in = request->type; - vstor_packet->vm_srb.data_transfer_length = request->data_buffer.Length; + vstor_packet->vm_srb.data_transfer_length = request->data_buffer.len; vstor_packet->operation = VSTOR_OPERATION_EXECUTE_SRB; @@ -734,7 +734,7 @@ static int stor_vsc_on_io_request(struct hv_device *device, vstor_packet->vm_srb.sense_info_length, vstor_packet->vm_srb.cdb_length); - if (request_extension->request->data_buffer.Length) { + if (request_extension->request->data_buffer.len) { ret = vmbus_sendpacket_multipagebuffer(device->channel, &request_extension->request->data_buffer, vstor_packet, @@ -788,7 +788,7 @@ int stor_vsc_initialize(struct hv_driver *driver) /* ASSERT(stor_driver->RingBufferSize >= (PAGE_SIZE << 1)); */ driver->name = g_driver_name; - memcpy(&driver->deviceType, &gStorVscDeviceType, + memcpy(&driver->dev_type, &gStorVscDeviceType, sizeof(struct hv_guid)); stor_driver->request_ext_size = @@ -811,9 +811,9 @@ int stor_vsc_initialize(struct hv_driver *driver) STORVSC_MAX_IO_REQUESTS); /* Setup the dispatch table */ - stor_driver->base.OnDeviceAdd = stor_vsc_on_device_add; - stor_driver->base.OnDeviceRemove = stor_vsc_on_device_remove; - stor_driver->base.OnCleanup = stor_vsc_on_cleanup; + stor_driver->base.dev_add = stor_vsc_on_device_add; + stor_driver->base.dev_rm = stor_vsc_on_device_remove; + stor_driver->base.cleanup = stor_vsc_on_cleanup; stor_driver->on_io_request = stor_vsc_on_io_request; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 7651ca2accc7..956c9ebaa6a5 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -161,7 +161,7 @@ static int storvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) } drv_ctx->driver.name = storvsc_drv_obj->base.name; - memcpy(&drv_ctx->class_id, &storvsc_drv_obj->base.deviceType, + memcpy(&drv_ctx->class_id, &storvsc_drv_obj->base.dev_type, sizeof(struct hv_guid)); drv_ctx->probe = storvsc_probe; @@ -206,8 +206,8 @@ static void storvsc_drv_exit(void) device_unregister(current_dev); } - if (storvsc_drv_obj->base.OnCleanup) - storvsc_drv_obj->base.OnCleanup(&storvsc_drv_obj->base); + if (storvsc_drv_obj->base.cleanup) + storvsc_drv_obj->base.cleanup(&storvsc_drv_obj->base); vmbus_child_driver_unregister(drv_ctx); return; @@ -231,7 +231,7 @@ static int storvsc_probe(struct device *device) struct host_device_context *host_device_ctx; struct storvsc_device_info device_info; - if (!storvsc_drv_obj->base.OnDeviceAdd) + if (!storvsc_drv_obj->base.dev_add) return -1; host = scsi_host_alloc(&scsi_driver, @@ -262,7 +262,7 @@ static int storvsc_probe(struct device *device) device_info.port_number = host->host_no; /* Call to the vsc driver to add the device */ - ret = storvsc_drv_obj->base.OnDeviceAdd(device_obj, + ret = storvsc_drv_obj->base.dev_add(device_obj, (void *)&device_info); if (ret != 0) { DPRINT_ERR(STORVSC_DRV, "unable to add scsi vsc device"); @@ -287,7 +287,7 @@ static int storvsc_probe(struct device *device) if (ret != 0) { DPRINT_ERR(STORVSC_DRV, "unable to add scsi host device"); - storvsc_drv_obj->base.OnDeviceRemove(device_obj); + storvsc_drv_obj->base.dev_rm(device_obj); kmem_cache_destroy(host_device_ctx->request_pool); scsi_host_put(host); @@ -317,14 +317,14 @@ static int storvsc_remove(struct device *device) (struct host_device_context *)host->hostdata; - if (!storvsc_drv_obj->base.OnDeviceRemove) + if (!storvsc_drv_obj->base.dev_rm) return -1; /* * Call to the vsc driver to let it know that the device is being * removed */ - ret = storvsc_drv_obj->base.OnDeviceRemove(device_obj); + ret = storvsc_drv_obj->base.dev_rm(device_obj); if (ret != 0) { /* TODO: */ DPRINT_ERR(STORVSC, "unable to remove vsc device (ret %d)", @@ -385,7 +385,7 @@ static void storvsc_commmand_completion(struct hv_storvsc_request *request) /* ASSERT(request->BytesXfer <= request->data_buffer.Length); */ scsi_set_resid(scmnd, - request->data_buffer.Length - request->bytes_xfer); + request->data_buffer.len - request->bytes_xfer); scsi_done_fn = scmnd->scsi_done; @@ -693,7 +693,7 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, request->sense_buffer_size = SCSI_SENSE_BUFFERSIZE; - request->data_buffer.Length = scsi_bufflen(scmnd); + request->data_buffer.len = scsi_bufflen(scmnd); if (scsi_sg_count(scmnd)) { sgl = (struct scatterlist *)scsi_sglist(scmnd); sg_count = scsi_sg_count(scmnd); @@ -734,19 +734,19 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, sg_count = cmd_request->bounce_sgl_count; } - request->data_buffer.Offset = sgl[0].offset; + request->data_buffer.offset = sgl[0].offset; for (i = 0; i < sg_count; i++) { DPRINT_DBG(STORVSC_DRV, "sgl[%d] len %d offset %d\n", i, sgl[i].length, sgl[i].offset); - request->data_buffer.PfnArray[i] = + request->data_buffer.pfn_array[i] = page_to_pfn(sg_page((&sgl[i]))); } } else if (scsi_sglist(scmnd)) { /* ASSERT(scsi_bufflen(scmnd) <= PAGE_SIZE); */ - request->data_buffer.Offset = + request->data_buffer.offset = virt_to_phys(scsi_sglist(scmnd)) & (PAGE_SIZE-1); - request->data_buffer.PfnArray[0] = + request->data_buffer.pfn_array[0] = virt_to_phys(scsi_sglist(scmnd)) >> PAGE_SHIFT; } diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index 2da3f52610b3..635ce22a0334 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -32,17 +32,17 @@ /* Single-page buffer */ struct hv_page_buffer { - u32 Length; - u32 Offset; - u64 Pfn; + u32 len; + u32 offset; + u64 pfn; }; /* Multiple-page buffer */ struct hv_multipage_buffer { /* Length and Offset determines the # of pfns in the array */ - u32 Length; - u32 Offset; - u64 PfnArray[MAX_MULTIPAGE_BUFFER_COUNT]; + u32 len; + u32 offset; + u64 pfn_array[MAX_MULTIPAGE_BUFFER_COUNT]; }; /* 0x18 includes the proprietary packet header */ @@ -59,29 +59,29 @@ struct hv_driver; struct hv_device; struct hv_dev_port_info { - u32 InterruptMask; - u32 ReadIndex; - u32 WriteIndex; - u32 BytesAvailToRead; - u32 BytesAvailToWrite; + u32 int_mask; + u32 read_idx; + u32 write_idx; + u32 bytes_avail_toread; + u32 bytes_avail_towrite; }; struct hv_device_info { - u32 ChannelId; - u32 ChannelState; - struct hv_guid ChannelType; - struct hv_guid ChannelInstance; - - u32 MonitorId; - u32 ServerMonitorPending; - u32 ServerMonitorLatency; - u32 ServerMonitorConnectionId; - u32 ClientMonitorPending; - u32 ClientMonitorLatency; - u32 ClientMonitorConnectionId; - - struct hv_dev_port_info Inbound; - struct hv_dev_port_info Outbound; + u32 chn_id; + u32 chn_state; + struct hv_guid chn_type; + struct hv_guid chn_instance; + + u32 monitor_id; + u32 server_monitor_pending; + u32 server_monitor_latency; + u32 server_monitor_conn_id; + u32 client_monitor_pending; + u32 client_monitor_latency; + u32 client_monitor_conn_id; + + struct hv_dev_port_info inbound; + struct hv_dev_port_info outbound; }; /* Base driver object */ @@ -89,30 +89,30 @@ struct hv_driver { const char *name; /* the device type supported by this driver */ - struct hv_guid deviceType; + struct hv_guid dev_type; - int (*OnDeviceAdd)(struct hv_device *device, void *data); - int (*OnDeviceRemove)(struct hv_device *device); - void (*OnCleanup)(struct hv_driver *driver); + int (*dev_add)(struct hv_device *device, void *data); + int (*dev_rm)(struct hv_device *device); + void (*cleanup)(struct hv_driver *driver); }; /* Base device object */ struct hv_device { /* the driver for this device */ - struct hv_driver *Driver; + struct hv_driver *drv; char name[64]; /* the device type id of this device */ - struct hv_guid deviceType; + struct hv_guid dev_type; /* the device instance id of this device */ - struct hv_guid deviceInstance; + struct hv_guid dev_instance; struct vmbus_channel *channel; /* Device extension; */ - void *Extension; + void *ext; }; #endif /* _VMBUS_API_H_ */ diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 0c0aadbea1f7..4c56bea47ff2 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -165,8 +165,8 @@ static int vmbus_dev_add(struct hv_device *dev, void *info) vmbus_device = dev; - memcpy(&vmbus_device->deviceType, &device_type, sizeof(struct hv_guid)); - memcpy(&vmbus_device->deviceInstance, &device_id, + memcpy(&vmbus_device->dev_type, &device_type, sizeof(struct hv_guid)); + memcpy(&vmbus_device->dev_instance, &device_id, sizeof(struct hv_guid)); /* strcpy(dev->name, "vmbus"); */ @@ -309,37 +309,38 @@ static void get_channel_info(struct hv_device *device, vmbus_get_debug_info(device->channel, &debug_info); - info->ChannelId = debug_info.relid; - info->ChannelState = debug_info.state; - memcpy(&info->ChannelType, &debug_info.interfacetype, + info->chn_id = debug_info.relid; + info->chn_state = debug_info.state; + memcpy(&info->chn_type, &debug_info.interfacetype, sizeof(struct hv_guid)); - memcpy(&info->ChannelInstance, &debug_info.interface_instance, + memcpy(&info->chn_instance, &debug_info.interface_instance, sizeof(struct hv_guid)); - info->MonitorId = debug_info.monitorid; + info->monitor_id = debug_info.monitorid; - info->ServerMonitorPending = debug_info.servermonitor_pending; - info->ServerMonitorLatency = debug_info.servermonitor_latency; - info->ServerMonitorConnectionId = debug_info.servermonitor_connectionid; + info->server_monitor_pending = debug_info.servermonitor_pending; + info->server_monitor_latency = debug_info.servermonitor_latency; + info->server_monitor_conn_id = debug_info.servermonitor_connectionid; - info->ClientMonitorPending = debug_info.clientmonitor_pending; - info->ClientMonitorLatency = debug_info.clientmonitor_latency; - info->ClientMonitorConnectionId = debug_info.clientmonitor_connectionid; + info->client_monitor_pending = debug_info.clientmonitor_pending; + info->client_monitor_latency = debug_info.clientmonitor_latency; + info->client_monitor_conn_id = debug_info.clientmonitor_connectionid; - info->Inbound.InterruptMask = debug_info.inbound.current_interrupt_mask; - info->Inbound.ReadIndex = debug_info.inbound.current_read_index; - info->Inbound.WriteIndex = debug_info.inbound.current_write_index; - info->Inbound.BytesAvailToRead = debug_info.inbound.bytes_avail_toread; - info->Inbound.BytesAvailToWrite = + info->inbound.int_mask = debug_info.inbound.current_interrupt_mask; + info->inbound.read_idx = debug_info.inbound.current_read_index; + info->inbound.write_idx = debug_info.inbound.current_write_index; + info->inbound.bytes_avail_toread = + debug_info.inbound.bytes_avail_toread; + info->inbound.bytes_avail_towrite = debug_info.inbound.bytes_avail_towrite; - info->Outbound.InterruptMask = + info->outbound.int_mask = debug_info.outbound.current_interrupt_mask; - info->Outbound.ReadIndex = debug_info.outbound.current_read_index; - info->Outbound.WriteIndex = debug_info.outbound.current_write_index; - info->Outbound.BytesAvailToRead = + info->outbound.read_idx = debug_info.outbound.current_read_index; + info->outbound.write_idx = debug_info.outbound.current_write_index; + info->outbound.bytes_avail_toread = debug_info.outbound.bytes_avail_toread; - info->Outbound.BytesAvailToWrite = + info->outbound.bytes_avail_towrite = debug_info.outbound.bytes_avail_towrite; } @@ -363,85 +364,85 @@ static ssize_t vmbus_show_device_attr(struct device *dev, if (!strcmp(dev_attr->attr.name, "class_id")) { return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-" "%02x%02x%02x%02x%02x%02x%02x%02x}\n", - device_info.ChannelType.data[3], - device_info.ChannelType.data[2], - device_info.ChannelType.data[1], - device_info.ChannelType.data[0], - device_info.ChannelType.data[5], - device_info.ChannelType.data[4], - device_info.ChannelType.data[7], - device_info.ChannelType.data[6], - device_info.ChannelType.data[8], - device_info.ChannelType.data[9], - device_info.ChannelType.data[10], - device_info.ChannelType.data[11], - device_info.ChannelType.data[12], - device_info.ChannelType.data[13], - device_info.ChannelType.data[14], - device_info.ChannelType.data[15]); + device_info.chn_type.data[3], + device_info.chn_type.data[2], + device_info.chn_type.data[1], + device_info.chn_type.data[0], + device_info.chn_type.data[5], + device_info.chn_type.data[4], + device_info.chn_type.data[7], + device_info.chn_type.data[6], + device_info.chn_type.data[8], + device_info.chn_type.data[9], + device_info.chn_type.data[10], + device_info.chn_type.data[11], + device_info.chn_type.data[12], + device_info.chn_type.data[13], + device_info.chn_type.data[14], + device_info.chn_type.data[15]); } else if (!strcmp(dev_attr->attr.name, "device_id")) { return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-" "%02x%02x%02x%02x%02x%02x%02x%02x}\n", - device_info.ChannelInstance.data[3], - device_info.ChannelInstance.data[2], - device_info.ChannelInstance.data[1], - device_info.ChannelInstance.data[0], - device_info.ChannelInstance.data[5], - device_info.ChannelInstance.data[4], - device_info.ChannelInstance.data[7], - device_info.ChannelInstance.data[6], - device_info.ChannelInstance.data[8], - device_info.ChannelInstance.data[9], - device_info.ChannelInstance.data[10], - device_info.ChannelInstance.data[11], - device_info.ChannelInstance.data[12], - device_info.ChannelInstance.data[13], - device_info.ChannelInstance.data[14], - device_info.ChannelInstance.data[15]); + device_info.chn_instance.data[3], + device_info.chn_instance.data[2], + device_info.chn_instance.data[1], + device_info.chn_instance.data[0], + device_info.chn_instance.data[5], + device_info.chn_instance.data[4], + device_info.chn_instance.data[7], + device_info.chn_instance.data[6], + device_info.chn_instance.data[8], + device_info.chn_instance.data[9], + device_info.chn_instance.data[10], + device_info.chn_instance.data[11], + device_info.chn_instance.data[12], + device_info.chn_instance.data[13], + device_info.chn_instance.data[14], + device_info.chn_instance.data[15]); } else if (!strcmp(dev_attr->attr.name, "state")) { - return sprintf(buf, "%d\n", device_info.ChannelState); + return sprintf(buf, "%d\n", device_info.chn_state); } else if (!strcmp(dev_attr->attr.name, "id")) { - return sprintf(buf, "%d\n", device_info.ChannelId); + return sprintf(buf, "%d\n", device_info.chn_id); } else if (!strcmp(dev_attr->attr.name, "out_intr_mask")) { - return sprintf(buf, "%d\n", device_info.Outbound.InterruptMask); + return sprintf(buf, "%d\n", device_info.outbound.int_mask); } else if (!strcmp(dev_attr->attr.name, "out_read_index")) { - return sprintf(buf, "%d\n", device_info.Outbound.ReadIndex); + return sprintf(buf, "%d\n", device_info.outbound.read_idx); } else if (!strcmp(dev_attr->attr.name, "out_write_index")) { - return sprintf(buf, "%d\n", device_info.Outbound.WriteIndex); + return sprintf(buf, "%d\n", device_info.outbound.write_idx); } else if (!strcmp(dev_attr->attr.name, "out_read_bytes_avail")) { return sprintf(buf, "%d\n", - device_info.Outbound.BytesAvailToRead); + device_info.outbound.bytes_avail_toread); } else if (!strcmp(dev_attr->attr.name, "out_write_bytes_avail")) { return sprintf(buf, "%d\n", - device_info.Outbound.BytesAvailToWrite); + device_info.outbound.bytes_avail_towrite); } else if (!strcmp(dev_attr->attr.name, "in_intr_mask")) { - return sprintf(buf, "%d\n", device_info.Inbound.InterruptMask); + return sprintf(buf, "%d\n", device_info.inbound.int_mask); } else if (!strcmp(dev_attr->attr.name, "in_read_index")) { - return sprintf(buf, "%d\n", device_info.Inbound.ReadIndex); + return sprintf(buf, "%d\n", device_info.inbound.read_idx); } else if (!strcmp(dev_attr->attr.name, "in_write_index")) { - return sprintf(buf, "%d\n", device_info.Inbound.WriteIndex); + return sprintf(buf, "%d\n", device_info.inbound.write_idx); } else if (!strcmp(dev_attr->attr.name, "in_read_bytes_avail")) { return sprintf(buf, "%d\n", - device_info.Inbound.BytesAvailToRead); + device_info.inbound.bytes_avail_toread); } else if (!strcmp(dev_attr->attr.name, "in_write_bytes_avail")) { return sprintf(buf, "%d\n", - device_info.Inbound.BytesAvailToWrite); + device_info.inbound.bytes_avail_towrite); } else if (!strcmp(dev_attr->attr.name, "monitor_id")) { - return sprintf(buf, "%d\n", device_info.MonitorId); + return sprintf(buf, "%d\n", device_info.monitor_id); } else if (!strcmp(dev_attr->attr.name, "server_monitor_pending")) { - return sprintf(buf, "%d\n", device_info.ServerMonitorPending); + return sprintf(buf, "%d\n", device_info.server_monitor_pending); } else if (!strcmp(dev_attr->attr.name, "server_monitor_latency")) { - return sprintf(buf, "%d\n", device_info.ServerMonitorLatency); + return sprintf(buf, "%d\n", device_info.server_monitor_latency); } else if (!strcmp(dev_attr->attr.name, "server_monitor_conn_id")) { return sprintf(buf, "%d\n", - device_info.ServerMonitorConnectionId); + device_info.server_monitor_conn_id); } else if (!strcmp(dev_attr->attr.name, "client_monitor_pending")) { - return sprintf(buf, "%d\n", device_info.ClientMonitorPending); + return sprintf(buf, "%d\n", device_info.client_monitor_pending); } else if (!strcmp(dev_attr->attr.name, "client_monitor_latency")) { - return sprintf(buf, "%d\n", device_info.ClientMonitorLatency); + return sprintf(buf, "%d\n", device_info.client_monitor_latency); } else if (!strcmp(dev_attr->attr.name, "client_monitor_conn_id")) { return sprintf(buf, "%d\n", - device_info.ClientMonitorConnectionId); + device_info.client_monitor_conn_id); } else { return 0; } @@ -479,12 +480,12 @@ static int vmbus_bus_init(void) sizeof(struct vmbus_channel_packet_multipage_buffer)); driver->name = driver_name; - memcpy(&driver->deviceType, &device_type, sizeof(struct hv_guid)); + memcpy(&driver->dev_type, &device_type, sizeof(struct hv_guid)); /* Setup dispatch table */ - driver->OnDeviceAdd = vmbus_dev_add; - driver->OnDeviceRemove = vmbus_dev_rm; - driver->OnCleanup = vmbus_cleanup; + driver->dev_add = vmbus_dev_add; + driver->dev_rm = vmbus_dev_rm; + driver->cleanup = vmbus_cleanup; /* Hypervisor initialization...setup hypercall page..etc */ ret = hv_init(); @@ -495,7 +496,7 @@ static int vmbus_bus_init(void) } /* Sanity checks */ - if (!driver->OnDeviceAdd) { + if (!driver->dev_add) { DPRINT_ERR(VMBUS_DRV, "OnDeviceAdd() routine not set"); ret = -1; goto cleanup; @@ -536,7 +537,7 @@ static int vmbus_bus_init(void) /* Call to bus driver to add the root device */ memset(dev_ctx, 0, sizeof(struct vm_device)); - ret = driver->OnDeviceAdd(&dev_ctx->device_obj, &vector); + ret = driver->dev_add(&dev_ctx->device_obj, &vector); if (ret != 0) { DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to add vmbus root device"); @@ -550,9 +551,9 @@ static int vmbus_bus_init(void) } /* strcpy(dev_ctx->device.bus_id, dev_ctx->device_obj.name); */ dev_set_name(&dev_ctx->device, "vmbus_0_0"); - memcpy(&dev_ctx->class_id, &dev_ctx->device_obj.deviceType, + memcpy(&dev_ctx->class_id, &dev_ctx->device_obj.dev_type, sizeof(struct hv_guid)); - memcpy(&dev_ctx->device_id, &dev_ctx->device_obj.deviceInstance, + memcpy(&dev_ctx->device_id, &dev_ctx->device_obj.dev_instance, sizeof(struct hv_guid)); /* No need to bind a driver to the root device. */ @@ -596,11 +597,11 @@ static void vmbus_bus_exit(void) struct vm_device *dev_ctx = &vmbus_drv.device_ctx; /* Remove the root device */ - if (driver->OnDeviceRemove) - driver->OnDeviceRemove(&dev_ctx->device_obj); + if (driver->dev_rm) + driver->dev_rm(&dev_ctx->device_obj); - if (driver->OnCleanup) - driver->OnCleanup(driver); + if (driver->cleanup) + driver->cleanup(driver); /* Unregister the root bus device */ device_unregister(&dev_ctx->device); @@ -706,8 +707,8 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *type, child_device_obj = &child_device_ctx->device_obj; child_device_obj->channel = channel; - memcpy(&child_device_obj->deviceType, type, sizeof(struct hv_guid)); - memcpy(&child_device_obj->deviceInstance, instance, + memcpy(&child_device_obj->dev_type, type, sizeof(struct hv_guid)); + memcpy(&child_device_obj->dev_instance, instance, sizeof(struct hv_guid)); memcpy(&child_device_ctx->class_id, type, sizeof(struct hv_guid)); @@ -875,11 +876,11 @@ static int vmbus_match(struct device *device, struct device_driver *driver) struct vmbus_driver_context *vmbus_drv_ctx = (struct vmbus_driver_context *)driver_ctx; - device_ctx->device_obj.Driver = &vmbus_drv_ctx->drv_obj; + device_ctx->device_obj.drv = &vmbus_drv_ctx->drv_obj; DPRINT_INFO(VMBUS_DRV, "device object (%p) set to driver object (%p)", &device_ctx->device_obj, - device_ctx->device_obj.Driver); + device_ctx->device_obj.drv); match = 1; } -- cgit v1.2.3 From 767dff6853ae0f68438e623199cc7137441a286d Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Wed, 26 Jan 2011 12:12:12 -0800 Subject: staging: hv: Convert camel cased struct fields in vmbus_channel_interface.h to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel.c | 4 ++-- drivers/staging/hv/channel_mgmt.c | 20 ++++++++++---------- drivers/staging/hv/vmbus_channel_interface.h | 26 +++++++++++++------------- 3 files changed, 25 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index 960e155d34ef..711548fd9160 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -128,9 +128,9 @@ void vmbus_get_debug_info(struct vmbus_channel *channel, debuginfo->relid = channel->offermsg.child_relid; debuginfo->state = channel->state; memcpy(&debuginfo->interfacetype, - &channel->offermsg.offer.InterfaceType, sizeof(struct hv_guid)); + &channel->offermsg.offer.if_type, sizeof(struct hv_guid)); memcpy(&debuginfo->interface_instance, - &channel->offermsg.offer.InterfaceInstance, + &channel->offermsg.offer.if_instance, sizeof(struct hv_guid)); monitorpage = (struct hv_monitor_page *)vmbus_connection.MonitorPages; diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index b4a856155b29..3e229fa178e8 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -364,11 +364,11 @@ static void vmbus_process_offer(struct work_struct *work) spin_lock_irqsave(&vmbus_connection.channel_lock, flags); list_for_each_entry(channel, &vmbus_connection.ChannelList, listentry) { - if (!memcmp(&channel->offermsg.offer.InterfaceType, - &newchannel->offermsg.offer.InterfaceType, + if (!memcmp(&channel->offermsg.offer.if_type, + &newchannel->offermsg.offer.if_type, sizeof(struct hv_guid)) && - !memcmp(&channel->offermsg.offer.InterfaceInstance, - &newchannel->offermsg.offer.InterfaceInstance, + !memcmp(&channel->offermsg.offer.if_instance, + &newchannel->offermsg.offer.if_instance, sizeof(struct hv_guid))) { fnew = false; break; @@ -394,8 +394,8 @@ static void vmbus_process_offer(struct work_struct *work) * vmbus_child_dev_add() */ newchannel->device_obj = vmbus_child_device_create( - &newchannel->offermsg.offer.InterfaceType, - &newchannel->offermsg.offer.InterfaceInstance, + &newchannel->offermsg.offer.if_type, + &newchannel->offermsg.offer.if_instance, newchannel); DPRINT_DBG(VMBUS, "child device object allocated - %p", @@ -427,7 +427,7 @@ static void vmbus_process_offer(struct work_struct *work) /* Open IC channels */ for (cnt = 0; cnt < MAX_MSG_TYPES; cnt++) { - if (memcmp(&newchannel->offermsg.offer.InterfaceType, + if (memcmp(&newchannel->offermsg.offer.if_type, &hv_cb_utils[cnt].data, sizeof(struct hv_guid)) == 0 && vmbus_open(newchannel, 2 * PAGE_SIZE, @@ -461,7 +461,7 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) offer = (struct vmbus_channel_offer_channel *)hdr; for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) { - if (memcmp(&offer->offer.InterfaceType, + if (memcmp(&offer->offer.if_type, &gSupportedDeviceClasses[i], sizeof(struct hv_guid)) == 0) { fsupported = 1; break; @@ -474,8 +474,8 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) return; } - guidtype = &offer->offer.InterfaceType; - guidinstance = &offer->offer.InterfaceInstance; + guidtype = &offer->offer.if_type; + guidinstance = &offer->offer.if_instance; DPRINT_INFO(VMBUS, "Channel offer notification - " "child relid %d monitor id %d allocated %d, " diff --git a/drivers/staging/hv/vmbus_channel_interface.h b/drivers/staging/hv/vmbus_channel_interface.h index 26742823748d..fbfad5e8b92d 100644 --- a/drivers/staging/hv/vmbus_channel_interface.h +++ b/drivers/staging/hv/vmbus_channel_interface.h @@ -48,19 +48,19 @@ * struct contains the fundamental information about an offer. */ struct vmbus_channel_offer { - struct hv_guid InterfaceType; - struct hv_guid InterfaceInstance; - u64 InterruptLatencyIn100nsUnits; - u32 InterfaceRevision; - u32 ServerContextAreaSize; /* in bytes */ - u16 ChannelFlags; - u16 MmioMegabytes; /* in bytes * 1024 * 1024 */ + struct hv_guid if_type; + struct hv_guid if_instance; + u64 int_latency; /* in 100ns units */ + u32 if_revision; + u32 server_ctx_size; /* in bytes */ + u16 chn_flags; + u16 mmio_megabytes; /* in bytes * 1024 * 1024 */ union { /* Non-pipes: The user has MAX_USER_DEFINED_BYTES bytes. */ struct { - unsigned char UserDefined[MAX_USER_DEFINED_BYTES]; - } Standard; + unsigned char user_def[MAX_USER_DEFINED_BYTES]; + } std; /* * Pipes: @@ -70,11 +70,11 @@ struct vmbus_channel_offer { * use. */ struct { - u32 PipeMode; - unsigned char UserDefined[MAX_PIPE_USER_DEFINED_BYTES]; - } Pipe; + u32 pipe_mode; + unsigned char user_def[MAX_PIPE_USER_DEFINED_BYTES]; + } pipe; } u; - u32 Padding; + u32 padding; } __attribute__((packed)); /* Server Flags */ -- cgit v1.2.3 From 415f228712d86dd5598f809e8e379ff5ad729652 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Wed, 26 Jan 2011 12:12:13 -0800 Subject: staging: hv: Convert camel cased struct fields in vmbus_packet_format.h to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 2 +- drivers/staging/hv/channel.c | 56 +++++++-------- drivers/staging/hv/channel_mgmt.c | 2 +- drivers/staging/hv/hv_kvp.c | 4 +- drivers/staging/hv/hv_util.c | 6 +- drivers/staging/hv/netvsc.c | 68 +++++++++--------- drivers/staging/hv/storvsc.c | 12 ++-- drivers/staging/hv/vmbus_packet_format.h | 118 +++++++++++++++---------------- 8 files changed, 134 insertions(+), 134 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index b0e83162e6bc..26a35cfbf572 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -872,7 +872,7 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, DPRINT_DBG(BLKVSC_DRV, "blkvsc_submit_request() - " "req %p pfn[%d] %llx\n", blkvsc_req, i, - blkvsc_req->request.data_buffer.PfnArray[i]); + blkvsc_req->request.data_buffer.pfn_array[i]); } #endif diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index 711548fd9160..a8f5c3869fbb 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -338,16 +338,16 @@ static void dump_gpadl_header(struct vmbus_channel_gpadl_header *gpadl) "gpadl header - relid %d, range count %d, range buflen %d", gpadl->child_relid, gpadl->rangecount, gpadl->range_buflen); for (i = 0; i < gpadl->rangecount; i++) { - pagecount = gpadl->range[i].ByteCount >> PAGE_SHIFT; + pagecount = gpadl->range[i].byte_count >> PAGE_SHIFT; pagecount = (pagecount > 26) ? 26 : pagecount; DPRINT_DBG(VMBUS, "gpadl range %d - len %d offset %d " - "page count %d", i, gpadl->range[i].ByteCount, - gpadl->range[i].ByteOffset, pagecount); + "page count %d", i, gpadl->range[i].byte_count, + gpadl->range[i].byte_offset, pagecount); for (j = 0; j < pagecount; j++) DPRINT_DBG(VMBUS, "%d) pfn %llu", j, - gpadl->range[i].PfnArray[j]); + gpadl->range[i].pfn_array[j]); } } @@ -399,10 +399,10 @@ static int create_gpadl_header(void *kbuffer, u32 size, gpadl_header->rangecount = 1; gpadl_header->range_buflen = sizeof(struct gpa_range) + pagecount * sizeof(u64); - gpadl_header->range[0].ByteOffset = 0; - gpadl_header->range[0].ByteCount = size; + gpadl_header->range[0].byte_offset = 0; + gpadl_header->range[0].byte_count = size; for (i = 0; i < pfncount; i++) - gpadl_header->range[0].PfnArray[i] = pfn+i; + gpadl_header->range[0].pfn_array[i] = pfn+i; *msginfo = msgheader; *messagecount = 1; @@ -463,10 +463,10 @@ static int create_gpadl_header(void *kbuffer, u32 size, gpadl_header->rangecount = 1; gpadl_header->range_buflen = sizeof(struct gpa_range) + pagecount * sizeof(u64); - gpadl_header->range[0].ByteOffset = 0; - gpadl_header->range[0].ByteCount = size; + gpadl_header->range[0].byte_offset = 0; + gpadl_header->range[0].byte_count = size; for (i = 0; i < pagecount; i++) - gpadl_header->range[0].PfnArray[i] = pfn+i; + gpadl_header->range[0].pfn_array[i] = pfn+i; *msginfo = msgheader; *messagecount = 1; @@ -739,12 +739,12 @@ int vmbus_sendpacket(struct vmbus_channel *channel, const void *buffer, /* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */ /* Setup the descriptor */ - desc.Type = type; /* VmbusPacketTypeDataInBand; */ - desc.Flags = flags; /* VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; */ + desc.type = type; /* VmbusPacketTypeDataInBand; */ + desc.flags = flags; /* VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; */ /* in 8-bytes granularity */ - desc.DataOffset8 = sizeof(struct vmpacket_descriptor) >> 3; - desc.Length8 = (u16)(packetlen_aligned >> 3); - desc.TransactionId = requestid; + desc.offset8 = sizeof(struct vmpacket_descriptor) >> 3; + desc.len8 = (u16)(packetlen_aligned >> 3); + desc.trans_id = requestid; sg_init_table(bufferlist, 3); sg_set_buf(&bufferlist[0], &desc, sizeof(struct vmpacket_descriptor)); @@ -798,7 +798,7 @@ int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel, /* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */ /* Setup the descriptor */ - desc.type = VmbusPacketTypeDataUsingGpaDirect; + desc.type = VM_PKT_DATA_USING_GPA_DIRECT; desc.flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; desc.dataoffset8 = descsize >> 3; /* in 8-bytes grandularity */ desc.length8 = (u16)(packetlen_aligned >> 3); @@ -867,7 +867,7 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, /* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */ /* Setup the descriptor */ - desc.type = VmbusPacketTypeDataUsingGpaDirect; + desc.type = VM_PKT_DATA_USING_GPA_DIRECT; desc.flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; desc.dataoffset8 = descsize >> 3; /* in 8-bytes grandularity */ desc.length8 = (u16)(packetlen_aligned >> 3); @@ -934,14 +934,14 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, /* VmbusChannelClearEvent(Channel); */ - packetlen = desc.Length8 << 3; - userlen = packetlen - (desc.DataOffset8 << 3); + packetlen = desc.len8 << 3; + userlen = packetlen - (desc.offset8 << 3); /* ASSERT(userLen > 0); */ DPRINT_DBG(VMBUS, "packet received on channel %p relid %d ", - channel, channel->offermsg.child_relid, desc.Type, - desc.Flags, desc.TransactionId, packetlen, userlen); + channel, channel->offermsg.child_relid, desc.type, + desc.flags, desc.trans_id, packetlen, userlen); *buffer_actual_len = userlen; @@ -953,11 +953,11 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, return -1; } - *requestid = desc.TransactionId; + *requestid = desc.trans_id; /* Copy over the packet to the user buffer */ ret = ringbuffer_read(&channel->inbound, buffer, userlen, - (desc.DataOffset8 << 3)); + (desc.offset8 << 3)); spin_unlock_irqrestore(&channel->inbound_lock, flags); @@ -994,13 +994,13 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, /* VmbusChannelClearEvent(Channel); */ - packetlen = desc.Length8 << 3; - userlen = packetlen - (desc.DataOffset8 << 3); + packetlen = desc.len8 << 3; + userlen = packetlen - (desc.offset8 << 3); DPRINT_DBG(VMBUS, "packet received on channel %p relid %d ", - channel, channel->offermsg.child_relid, desc.Type, - desc.Flags, desc.TransactionId, packetlen, userlen); + channel, channel->offermsg.child_relid, desc.type, + desc.flags, desc.trans_id, packetlen, userlen); *buffer_actual_len = packetlen; @@ -1012,7 +1012,7 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, return -2; } - *requestid = desc.TransactionId; + *requestid = desc.trans_id; /* Copy over the entire packet to the user buffer */ ret = ringbuffer_read(&channel->inbound, buffer, packetlen, 0); diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 3e229fa178e8..78c4f1096b7b 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -194,7 +194,7 @@ void chn_cb_negotiate(void *context) vmbus_sendpacket(channel, buf, recvlen, requestid, - VmbusPacketTypeDataInBand, 0); + VM_PKT_DATA_INBAND, 0); } kfree(buf); diff --git a/drivers/staging/hv/hv_kvp.c b/drivers/staging/hv/hv_kvp.c index 5458631b09cd..bc1c20e8d611 100644 --- a/drivers/staging/hv/hv_kvp.c +++ b/drivers/staging/hv/hv_kvp.c @@ -224,7 +224,7 @@ response_done: icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; vmbus_sendpacket(channel, recv_buffer, buf_len, req_id, - VmbusPacketTypeDataInBand, 0); + VM_PKT_DATA_INBAND, 0); kvp_transaction.active = false; } @@ -318,7 +318,7 @@ callback_done: vmbus_sendpacket(channel, recv_buffer, recvlen, requestid, - VmbusPacketTypeDataInBand, 0); + VM_PKT_DATA_INBAND, 0); } } diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c index dea0513eef71..43c7ec0e9adb 100644 --- a/drivers/staging/hv/hv_util.c +++ b/drivers/staging/hv/hv_util.c @@ -97,7 +97,7 @@ static void shutdown_onchannelcallback(void *context) vmbus_sendpacket(channel, shut_txf_buf, recvlen, requestid, - VmbusPacketTypeDataInBand, 0); + VM_PKT_DATA_INBAND, 0); } if (execute_shutdown == true) @@ -179,7 +179,7 @@ static void timesync_onchannelcallback(void *context) vmbus_sendpacket(channel, time_txf_buf, recvlen, requestid, - VmbusPacketTypeDataInBand, 0); + VM_PKT_DATA_INBAND, 0); } } @@ -225,7 +225,7 @@ static void heartbeat_onchannelcallback(void *context) vmbus_sendpacket(channel, hbeat_txf_buf, recvlen, requestid, - VmbusPacketTypeDataInBand, 0); + VM_PKT_DATA_INBAND, 0); } } diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index b13a070dcfac..9a159dea89d2 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -270,7 +270,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) ret = vmbus_sendpacket(device->channel, init_packet, sizeof(struct nvsp_message), (unsigned long)init_packet, - VmbusPacketTypeDataInBand, + VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { DPRINT_ERR(NETVSC, @@ -404,7 +404,7 @@ static int netvsc_init_send_buf(struct hv_device *device) ret = vmbus_sendpacket(device->channel, init_packet, sizeof(struct nvsp_message), (unsigned long)init_packet, - VmbusPacketTypeDataInBand, + VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { DPRINT_ERR(NETVSC, @@ -466,7 +466,7 @@ static int netvsc_destroy_recv_buf(struct netvsc_device *net_device) revoke_packet, sizeof(struct nvsp_message), (unsigned long)revoke_packet, - VmbusPacketTypeDataInBand, 0); + VM_PKT_DATA_INBAND, 0); /* * If we failed here, we might as well return and * have a leak rather than continue and a bugchk @@ -540,7 +540,7 @@ static int netvsc_destroy_send_buf(struct netvsc_device *net_device) revoke_packet, sizeof(struct nvsp_message), (unsigned long)revoke_packet, - VmbusPacketTypeDataInBand, 0); + VM_PKT_DATA_INBAND, 0); /* * If we failed here, we might as well return and have a leak * rather than continue and a bugchk @@ -612,7 +612,7 @@ static int netvsc_connect_vsp(struct hv_device *device) ret = vmbus_sendpacket(device->channel, init_packet, sizeof(struct nvsp_message), (unsigned long)init_packet, - VmbusPacketTypeDataInBand, + VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { @@ -666,7 +666,7 @@ static int netvsc_connect_vsp(struct hv_device *device) ret = vmbus_sendpacket(device->channel, init_packet, sizeof(struct nvsp_message), (unsigned long)init_packet, - VmbusPacketTypeDataInBand, 0); + VM_PKT_DATA_INBAND, 0); if (ret != 0) { DPRINT_ERR(NETVSC, "unable to send NvspMessage1TypeSendNdisVersion"); @@ -872,7 +872,7 @@ static void netvsc_send_completion(struct hv_device *device, } nvsp_packet = (struct nvsp_message *)((unsigned long)packet + - (packet->DataOffset8 << 3)); + (packet->offset8 << 3)); DPRINT_DBG(NETVSC, "send completion packet - type %d", nvsp_packet->hdr.msg_type); @@ -890,7 +890,7 @@ static void netvsc_send_completion(struct hv_device *device, NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE) { /* Get the send context */ nvsc_packet = (struct hv_netvsc_packet *)(unsigned long) - packet->TransactionId; + packet->trans_id; /* ASSERT(nvscPacket); */ /* Notify the layer above us */ @@ -946,7 +946,7 @@ static int netvsc_send(struct hv_device *device, ret = vmbus_sendpacket(device->channel, &sendMessage, sizeof(struct nvsp_message), (unsigned long)packet, - VmbusPacketTypeDataInBand, + VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); } @@ -987,15 +987,15 @@ static void netvsc_receive(struct hv_device *device, * All inbound packets other than send completion should be xfer page * packet */ - if (packet->Type != VmbusPacketTypeDataUsingTransferPages) { + if (packet->type != VM_PKT_DATA_USING_XFER_PAGES) { DPRINT_ERR(NETVSC, "Unknown packet type received - %d", - packet->Type); + packet->type); put_net_device(device); return; } nvsp_packet = (struct nvsp_message *)((unsigned long)packet + - (packet->DataOffset8 << 3)); + (packet->offset8 << 3)); /* Make sure this is a valid nvsp packet */ if (nvsp_packet->hdr.msg_type != @@ -1011,16 +1011,16 @@ static void netvsc_receive(struct hv_device *device, vmxferpage_packet = (struct vmtransfer_page_packet_header *)packet; - if (vmxferpage_packet->TransferPageSetId != NETVSC_RECEIVE_BUFFER_ID) { + if (vmxferpage_packet->xfer_pageset_id != NETVSC_RECEIVE_BUFFER_ID) { DPRINT_ERR(NETVSC, "Invalid xfer page set id - " "expecting %x got %x", NETVSC_RECEIVE_BUFFER_ID, - vmxferpage_packet->TransferPageSetId); + vmxferpage_packet->xfer_pageset_id); put_net_device(device); return; } DPRINT_DBG(NETVSC, "xfer page - range count %d", - vmxferpage_packet->RangeCount); + vmxferpage_packet->range_cnt); /* * Grab free packets (range count + 1) to represent this xfer @@ -1031,7 +1031,7 @@ static void netvsc_receive(struct hv_device *device, spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags); while (!list_empty(&net_device->recv_pkt_list)) { list_move_tail(net_device->recv_pkt_list.next, &listHead); - if (++count == vmxferpage_packet->RangeCount + 1) + if (++count == vmxferpage_packet->range_cnt + 1) break; } spin_unlock_irqrestore(&net_device->recv_pkt_list_lock, flags); @@ -1044,7 +1044,7 @@ static void netvsc_receive(struct hv_device *device, if (count < 2) { DPRINT_ERR(NETVSC, "Got only %d netvsc pkt...needed %d pkts. " "Dropping this xfer page packet completely!", - count, vmxferpage_packet->RangeCount + 1); + count, vmxferpage_packet->range_cnt + 1); /* Return it to the freelist */ spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags); @@ -1056,7 +1056,7 @@ static void netvsc_receive(struct hv_device *device, flags); netvsc_send_recv_completion(device, - vmxferpage_packet->d.TransactionId); + vmxferpage_packet->d.trans_id); put_net_device(device); return; @@ -1071,9 +1071,9 @@ static void netvsc_receive(struct hv_device *device, /* ASSERT(xferpagePacket->Count > 0 && xferpagePacket->Count <= */ /* vmxferpagePacket->RangeCount); */ - if (xferpage_packet->count != vmxferpage_packet->RangeCount) { + if (xferpage_packet->count != vmxferpage_packet->range_cnt) { DPRINT_INFO(NETVSC, "Needed %d netvsc pkts to satisy this xfer " - "page...got %d", vmxferpage_packet->RangeCount, + "page...got %d", vmxferpage_packet->range_cnt, xferpage_packet->count); } @@ -1091,10 +1091,10 @@ static void netvsc_receive(struct hv_device *device, netvsc_packet->device = device; /* Save this so that we can send it back */ netvsc_packet->completion.recv.recv_completion_tid = - vmxferpage_packet->d.TransactionId; + vmxferpage_packet->d.trans_id; netvsc_packet->total_data_buflen = - vmxferpage_packet->Ranges[i].ByteCount; + vmxferpage_packet->ranges[i].byte_count; netvsc_packet->page_buf_cnt = 1; /* ASSERT(vmxferpagePacket->Ranges[i].ByteOffset + */ @@ -1102,20 +1102,20 @@ static void netvsc_receive(struct hv_device *device, /* netDevice->ReceiveBufferSize); */ netvsc_packet->page_buf[0].len = - vmxferpage_packet->Ranges[i].ByteCount; + vmxferpage_packet->ranges[i].byte_count; start = virt_to_phys((void *)((unsigned long)net_device-> - recv_buf + vmxferpage_packet->Ranges[i].ByteOffset)); + recv_buf + vmxferpage_packet->ranges[i].byte_offset)); netvsc_packet->page_buf[0].pfn = start >> PAGE_SHIFT; end_virtual = (unsigned long)net_device->recv_buf - + vmxferpage_packet->Ranges[i].ByteOffset - + vmxferpage_packet->Ranges[i].ByteCount - 1; + + vmxferpage_packet->ranges[i].byte_offset + + vmxferpage_packet->ranges[i].byte_count - 1; end = virt_to_phys((void *)end_virtual); /* Calculate the page relative offset */ netvsc_packet->page_buf[0].offset = - vmxferpage_packet->Ranges[i].ByteOffset & + vmxferpage_packet->ranges[i].byte_offset & (PAGE_SIZE - 1); if ((end >> PAGE_SHIFT) != (start >> PAGE_SHIFT)) { /* Handle frame across multiple pages: */ @@ -1147,8 +1147,8 @@ static void netvsc_receive(struct hv_device *device, } DPRINT_DBG(NETVSC, "[%d] - (abs offset %u len %u) => " "(pfn %llx, offset %u, len %u)", i, - vmxferpage_packet->Ranges[i].ByteOffset, - vmxferpage_packet->Ranges[i].ByteCount, + vmxferpage_packet->ranges[i].byte_offset, + vmxferpage_packet->ranges[i].byte_count, netvsc_packet->page_buf[0].pfn, netvsc_packet->page_buf[0].offset, netvsc_packet->page_buf[0].len); @@ -1187,7 +1187,7 @@ retry_send_cmplt: /* Send the completion */ ret = vmbus_sendpacket(device->channel, &recvcompMessage, sizeof(struct nvsp_message), transaction_id, - VmbusPacketTypeCompletion, 0); + VM_PKT_COMP, 0); if (ret == 0) { /* success */ /* no-op */ @@ -1300,12 +1300,12 @@ static void netvsc_channel_cb(void *context) bytes_recvd, request_id); desc = (struct vmpacket_descriptor *)buffer; - switch (desc->Type) { - case VmbusPacketTypeCompletion: + switch (desc->type) { + case VM_PKT_COMP: netvsc_send_completion(device, desc); break; - case VmbusPacketTypeDataUsingTransferPages: + case VM_PKT_DATA_USING_XFER_PAGES: netvsc_receive(device, desc); break; @@ -1313,7 +1313,7 @@ static void netvsc_channel_cb(void *context) DPRINT_ERR(NETVSC, "unhandled packet type %d, " "tid %llx len %d\n", - desc->Type, request_id, + desc->type, request_id, bytes_recvd); break; } diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index b80b1e921350..a6121092d47a 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -218,7 +218,7 @@ static int stor_vsc_channel_init(struct hv_device *device) ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, - VmbusPacketTypeDataInBand, + VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { DPRINT_ERR(STORVSC, @@ -249,7 +249,7 @@ static int stor_vsc_channel_init(struct hv_device *device) ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, - VmbusPacketTypeDataInBand, + VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { DPRINT_ERR(STORVSC, @@ -280,7 +280,7 @@ static int stor_vsc_channel_init(struct hv_device *device) ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, - VmbusPacketTypeDataInBand, + VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { @@ -317,7 +317,7 @@ static int stor_vsc_channel_init(struct hv_device *device) ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, - VmbusPacketTypeDataInBand, + VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { @@ -642,7 +642,7 @@ int stor_vsc_on_host_reset(struct hv_device *device) ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)&stor_device->reset_request, - VmbusPacketTypeDataInBand, + VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { DPRINT_ERR(STORVSC, "Unable to send reset packet %p ret %d", @@ -744,7 +744,7 @@ static int stor_vsc_on_io_request(struct hv_device *device, ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request_extension, - VmbusPacketTypeDataInBand, + VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); } diff --git a/drivers/staging/hv/vmbus_packet_format.h b/drivers/staging/hv/vmbus_packet_format.h index f9f6b4bf6fb1..5cb13e523c48 100644 --- a/drivers/staging/hv/vmbus_packet_format.h +++ b/drivers/staging/hv/vmbus_packet_format.h @@ -25,43 +25,43 @@ #define _VMBUSPACKETFORMAT_H_ struct vmpacket_descriptor { - u16 Type; - u16 DataOffset8; - u16 Length8; - u16 Flags; - u64 TransactionId; + u16 type; + u16 offset8; + u16 len8; + u16 flags; + u64 trans_id; } __attribute__((packed)); struct vmpacket_header { - u32 PreviousPacketStartOffset; - struct vmpacket_descriptor Descriptor; + u32 prev_pkt_start_offset; + struct vmpacket_descriptor descriptor; } __attribute__((packed)); struct vmtransfer_page_range { - u32 ByteCount; - u32 ByteOffset; + u32 byte_count; + u32 byte_offset; } __attribute__((packed)); struct vmtransfer_page_packet_header { struct vmpacket_descriptor d; - u16 TransferPageSetId; - bool SenderOwnsSet; - u8 Reserved; - u32 RangeCount; - struct vmtransfer_page_range Ranges[1]; + u16 xfer_pageset_id; + bool sender_owns_set; + u8 reserved; + u32 range_cnt; + struct vmtransfer_page_range ranges[1]; } __attribute__((packed)); struct vmgpadl_packet_header { struct vmpacket_descriptor d; - u32 Gpadl; - u32 Reserved; + u32 gpadl; + u32 reserved; } __attribute__((packed)); struct vmadd_remove_transfer_page_set { struct vmpacket_descriptor d; - u32 Gpadl; - u16 TransferPageSetId; - u16 Reserved; + u32 gpadl; + u16 xfer_pageset_id; + u16 reserved; } __attribute__((packed)); /* @@ -69,9 +69,9 @@ struct vmadd_remove_transfer_page_set { * look virtually contiguous. */ struct gpa_range { - u32 ByteCount; - u32 ByteOffset; - u64 PfnArray[0]; + u32 byte_count; + u32 byte_offset; + u64 pfn_array[0]; }; /* @@ -83,9 +83,9 @@ struct gpa_range { */ struct vmestablish_gpadl { struct vmpacket_descriptor d; - u32 Gpadl; - u32 RangeCount; - struct gpa_range Range[1]; + u32 gpadl; + u32 range_cnt; + struct gpa_range range[1]; } __attribute__((packed)); /* @@ -94,8 +94,8 @@ struct vmestablish_gpadl { */ struct vmteardown_gpadl { struct vmpacket_descriptor d; - u32 Gpadl; - u32 Reserved; /* for alignment to a 8-byte boundary */ + u32 gpadl; + u32 reserved; /* for alignment to a 8-byte boundary */ } __attribute__((packed)); /* @@ -104,56 +104,56 @@ struct vmteardown_gpadl { */ struct vmdata_gpa_direct { struct vmpacket_descriptor d; - u32 Reserved; - u32 RangeCount; - struct gpa_range Range[1]; + u32 reserved; + u32 range_cnt; + struct gpa_range range[1]; } __attribute__((packed)); /* This is the format for a Additional Data Packet. */ struct vmadditional_data { struct vmpacket_descriptor d; - u64 TotalBytes; - u32 ByteOffset; - u32 ByteCount; - unsigned char Data[1]; + u64 total_bytes; + u32 offset; + u32 byte_cnt; + unsigned char data[1]; } __attribute__((packed)); union vmpacket_largest_possible_header { - struct vmpacket_descriptor SimpleHeader; - struct vmtransfer_page_packet_header TransferPageHeader; - struct vmgpadl_packet_header GpadlHeader; - struct vmadd_remove_transfer_page_set AddRemoveTransferPageHeader; - struct vmestablish_gpadl EstablishGpadlHeader; - struct vmteardown_gpadl TeardownGpadlHeader; - struct vmdata_gpa_direct DataGpaDirectHeader; + struct vmpacket_descriptor simple_hdr; + struct vmtransfer_page_packet_header xfer_page_hdr; + struct vmgpadl_packet_header gpadl_hdr; + struct vmadd_remove_transfer_page_set add_rm_xfer_page_hdr; + struct vmestablish_gpadl establish_gpadl_hdr; + struct vmteardown_gpadl teardown_gpadl_hdr; + struct vmdata_gpa_direct data_gpa_direct_hdr; }; #define VMPACKET_DATA_START_ADDRESS(__packet) \ (void *)(((unsigned char *)__packet) + \ - ((struct vmpacket_descriptor)__packet)->DataOffset8 * 8) + ((struct vmpacket_descriptor)__packet)->offset8 * 8) #define VMPACKET_DATA_LENGTH(__packet) \ - ((((struct vmpacket_descriptor)__packet)->Length8 - \ - ((struct vmpacket_descriptor)__packet)->DataOffset8) * 8) + ((((struct vmpacket_descriptor)__packet)->len8 - \ + ((struct vmpacket_descriptor)__packet)->offset8) * 8) #define VMPACKET_TRANSFER_MODE(__packet) \ - (((struct IMPACT)__packet)->Type) + (((struct IMPACT)__packet)->type) enum vmbus_packet_type { - VmbusPacketTypeInvalid = 0x0, - VmbusPacketTypeSynch = 0x1, - VmbusPacketTypeAddTransferPageSet = 0x2, - VmbusPacketTypeRemoveTransferPageSet = 0x3, - VmbusPacketTypeEstablishGpadl = 0x4, - VmbusPacketTypeTearDownGpadl = 0x5, - VmbusPacketTypeDataInBand = 0x6, - VmbusPacketTypeDataUsingTransferPages = 0x7, - VmbusPacketTypeDataUsingGpadl = 0x8, - VmbusPacketTypeDataUsingGpaDirect = 0x9, - VmbusPacketTypeCancelRequest = 0xa, - VmbusPacketTypeCompletion = 0xb, - VmbusPacketTypeDataUsingAdditionalPackets = 0xc, - VmbusPacketTypeAdditionalData = 0xd + VM_PKT_INVALID = 0x0, + VM_PKT_SYNCH = 0x1, + VM_PKT_ADD_XFER_PAGESET = 0x2, + VM_PKT_RM_XFER_PAGESET = 0x3, + VM_PKT_ESTABLISH_GPADL = 0x4, + VM_PKT_TEARDOWN_GPADL = 0x5, + VM_PKT_DATA_INBAND = 0x6, + VM_PKT_DATA_USING_XFER_PAGES = 0x7, + VM_PKT_DATA_USING_GPADL = 0x8, + VM_PKT_DATA_USING_GPA_DIRECT = 0x9, + VM_PKT_CANCEL_REQUEST = 0xa, + VM_PKT_COMP = 0xb, + VM_PKT_DATA_USING_ADDITIONAL_PKT = 0xc, + VM_PKT_ADDITIONAL_DATA = 0xd }; #define VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED 1 -- cgit v1.2.3 From da9fcb7260af0cd85351740b526afdc88d4f348a Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Wed, 26 Jan 2011 12:12:14 -0800 Subject: staging: hv: Convert camel cased struct fields in vmbus_private.h to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel.c | 22 ++++++------ drivers/staging/hv/channel_mgmt.c | 16 ++++----- drivers/staging/hv/connection.c | 74 +++++++++++++++++++------------------- drivers/staging/hv/vmbus_drv.c | 2 +- drivers/staging/hv/vmbus_private.h | 40 ++++++++++----------- 5 files changed, 77 insertions(+), 77 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index a8f5c3869fbb..ba9afdabedc1 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -77,10 +77,10 @@ static void vmbus_setevent(struct vmbus_channel *channel) if (channel->offermsg.monitor_allocated) { /* Each u32 represents 32 channels */ set_bit(channel->offermsg.child_relid & 31, - (unsigned long *) vmbus_connection.SendInterruptPage + + (unsigned long *) vmbus_connection.send_int_page + (channel->offermsg.child_relid >> 5)); - monitorpage = vmbus_connection.MonitorPages; + monitorpage = vmbus_connection.monitor_pages; monitorpage++; /* Get the child to parent monitor page */ set_bit(channel->monitor_bit, @@ -100,11 +100,11 @@ static void VmbusChannelClearEvent(struct vmbus_channel *channel) if (Channel->offermsg.monitor_allocated) { /* Each u32 represents 32 channels */ clear_bit(Channel->offermsg.child_relid & 31, - (unsigned long *)vmbus_connection.SendInterruptPage + + (unsigned long *)vmbus_connection.send_int_page + (Channel->offermsg.child_relid >> 5)); - monitorPage = - (struct hv_monitor_page *)vmbus_connection.MonitorPages; + monitorPage = (struct hv_monitor_page *) + vmbus_connection.monitor_pages; monitorPage++; /* Get the child to parent monitor page */ clear_bit(Channel->monitor_bit, @@ -133,7 +133,7 @@ void vmbus_get_debug_info(struct vmbus_channel *channel, &channel->offermsg.offer.if_instance, sizeof(struct hv_guid)); - monitorpage = (struct hv_monitor_page *)vmbus_connection.MonitorPages; + monitorpage = (struct hv_monitor_page *)vmbus_connection.monitor_pages; debuginfo->monitorid = channel->offermsg.monitorid; @@ -267,7 +267,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); list_add_tail(&openInfo->msglistentry, - &vmbus_connection.ChannelMsgList); + &vmbus_connection.chn_msg_list); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); DPRINT_DBG(VMBUS, "Sending channel open msg..."); @@ -501,8 +501,8 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, unsigned long flags; int ret = 0; - next_gpadl_handle = atomic_read(&vmbus_connection.NextGpadlHandle); - atomic_inc(&vmbus_connection.NextGpadlHandle); + next_gpadl_handle = atomic_read(&vmbus_connection.next_gpadl_handle); + atomic_inc(&vmbus_connection.next_gpadl_handle); ret = create_gpadl_header(kbuffer, size, &msginfo, &msgcount); if (ret) @@ -523,7 +523,7 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); list_add_tail(&msginfo->msglistentry, - &vmbus_connection.ChannelMsgList); + &vmbus_connection.chn_msg_list); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); DPRINT_DBG(VMBUS, "buffer %p, size %d msg cnt %d", @@ -618,7 +618,7 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); list_add_tail(&info->msglistentry, - &vmbus_connection.ChannelMsgList); + &vmbus_connection.chn_msg_list); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); ret = vmbus_post_msg(msg, diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 78c4f1096b7b..a9c9d49a99bb 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -308,7 +308,7 @@ void free_channel(struct vmbus_channel *channel) * ie we can't destroy ourselves. */ INIT_WORK(&channel->work, release_channel); - queue_work(vmbus_connection.WorkQueue, &channel->work); + queue_work(vmbus_connection.work_queue, &channel->work); } @@ -363,7 +363,7 @@ static void vmbus_process_offer(struct work_struct *work) /* Make sure this is a new offer */ spin_lock_irqsave(&vmbus_connection.channel_lock, flags); - list_for_each_entry(channel, &vmbus_connection.ChannelList, listentry) { + list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) { if (!memcmp(&channel->offermsg.offer.if_type, &newchannel->offermsg.offer.if_type, sizeof(struct hv_guid)) && @@ -377,7 +377,7 @@ static void vmbus_process_offer(struct work_struct *work) if (fnew) list_add_tail(&newchannel->listentry, - &vmbus_connection.ChannelList); + &vmbus_connection.chn_list); spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); @@ -579,7 +579,7 @@ static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr) */ spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_for_each(curr, &vmbus_connection.ChannelMsgList) { + list_for_each(curr, &vmbus_connection.chn_msg_list) { /* FIXME: this should probably use list_entry() instead */ msginfo = (struct vmbus_channel_msginfo *)curr; requestheader = @@ -627,7 +627,7 @@ static void vmbus_ongpadl_created(struct vmbus_channel_message_header *hdr) */ spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_for_each(curr, &vmbus_connection.ChannelMsgList) { + list_for_each(curr, &vmbus_connection.chn_msg_list) { /* FIXME: this should probably use list_entry() instead */ msginfo = (struct vmbus_channel_msginfo *)curr; requestheader = @@ -675,7 +675,7 @@ static void vmbus_ongpadl_torndown( */ spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_for_each(curr, &vmbus_connection.ChannelMsgList) { + list_for_each(curr, &vmbus_connection.chn_msg_list) { /* FIXME: this should probably use list_entry() instead */ msginfo = (struct vmbus_channel_msginfo *)curr; requestheader = @@ -717,7 +717,7 @@ static void vmbus_onversion_response( version_response = (struct vmbus_channel_version_response *)hdr; spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_for_each(curr, &vmbus_connection.ChannelMsgList) { + list_for_each(curr, &vmbus_connection.chn_msg_list) { /* FIXME: this should probably use list_entry() instead */ msginfo = (struct vmbus_channel_msginfo *)curr; requestheader = @@ -859,7 +859,7 @@ void vmbus_release_unattached_channels(void) spin_lock_irqsave(&vmbus_connection.channel_lock, flags); - list_for_each_entry_safe(channel, pos, &vmbus_connection.ChannelList, + list_for_each_entry_safe(channel, pos, &vmbus_connection.chn_list, listentry) { if (channel == start) break; diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index 002e86caf70c..b3ac66e5499f 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -29,9 +29,9 @@ #include "vmbus_private.h" -struct VMBUS_CONNECTION vmbus_connection = { - .ConnectState = Disconnected, - .NextGpadlHandle = ATOMIC_INIT(0xE1E10), +struct vmbus_connection vmbus_connection = { + .conn_state = DISCONNECTED, + .next_gpadl_handle = ATOMIC_INIT(0xE1E10), }; /* @@ -45,44 +45,44 @@ int vmbus_connect(void) unsigned long flags; /* Make sure we are not connecting or connected */ - if (vmbus_connection.ConnectState != Disconnected) + if (vmbus_connection.conn_state != DISCONNECTED) return -1; /* Initialize the vmbus connection */ - vmbus_connection.ConnectState = Connecting; - vmbus_connection.WorkQueue = create_workqueue("hv_vmbus_con"); - if (!vmbus_connection.WorkQueue) { + vmbus_connection.conn_state = CONNECTING; + vmbus_connection.work_queue = create_workqueue("hv_vmbus_con"); + if (!vmbus_connection.work_queue) { ret = -1; goto Cleanup; } - INIT_LIST_HEAD(&vmbus_connection.ChannelMsgList); + INIT_LIST_HEAD(&vmbus_connection.chn_msg_list); spin_lock_init(&vmbus_connection.channelmsg_lock); - INIT_LIST_HEAD(&vmbus_connection.ChannelList); + INIT_LIST_HEAD(&vmbus_connection.chn_list); spin_lock_init(&vmbus_connection.channel_lock); /* * Setup the vmbus event connection for channel interrupt * abstraction stuff */ - vmbus_connection.InterruptPage = osd_page_alloc(1); - if (vmbus_connection.InterruptPage == NULL) { + vmbus_connection.int_page = osd_page_alloc(1); + if (vmbus_connection.int_page == NULL) { ret = -1; goto Cleanup; } - vmbus_connection.RecvInterruptPage = vmbus_connection.InterruptPage; - vmbus_connection.SendInterruptPage = - (void *)((unsigned long)vmbus_connection.InterruptPage + + vmbus_connection.recv_int_page = vmbus_connection.int_page; + vmbus_connection.send_int_page = + (void *)((unsigned long)vmbus_connection.int_page + (PAGE_SIZE >> 1)); /* * Setup the monitor notification facility. The 1st page for * parent->child and the 2nd page for child->parent */ - vmbus_connection.MonitorPages = osd_page_alloc(2); - if (vmbus_connection.MonitorPages == NULL) { + vmbus_connection.monitor_pages = osd_page_alloc(2); + if (vmbus_connection.monitor_pages == NULL) { ret = -1; goto Cleanup; } @@ -105,10 +105,10 @@ int vmbus_connect(void) msg->header.msgtype = CHANNELMSG_INITIATE_CONTACT; msg->vmbus_version_requested = VMBUS_REVISION_NUMBER; - msg->interrupt_page = virt_to_phys(vmbus_connection.InterruptPage); - msg->monitor_page1 = virt_to_phys(vmbus_connection.MonitorPages); + msg->interrupt_page = virt_to_phys(vmbus_connection.int_page); + msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages); msg->monitor_page2 = virt_to_phys( - (void *)((unsigned long)vmbus_connection.MonitorPages + + (void *)((unsigned long)vmbus_connection.monitor_pages + PAGE_SIZE)); /* @@ -117,7 +117,7 @@ int vmbus_connect(void) */ spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); list_add_tail(&msginfo->msglistentry, - &vmbus_connection.ChannelMsgList); + &vmbus_connection.chn_msg_list); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); @@ -141,7 +141,7 @@ int vmbus_connect(void) /* Check if successful */ if (msginfo->response.version_response.version_supported) { DPRINT_INFO(VMBUS, "Vmbus connected!!"); - vmbus_connection.ConnectState = Connected; + vmbus_connection.conn_state = CONNECTED; } else { DPRINT_ERR(VMBUS, "Vmbus connection failed!!..." @@ -156,19 +156,19 @@ int vmbus_connect(void) return 0; Cleanup: - vmbus_connection.ConnectState = Disconnected; + vmbus_connection.conn_state = DISCONNECTED; - if (vmbus_connection.WorkQueue) - destroy_workqueue(vmbus_connection.WorkQueue); + if (vmbus_connection.work_queue) + destroy_workqueue(vmbus_connection.work_queue); - if (vmbus_connection.InterruptPage) { - osd_page_free(vmbus_connection.InterruptPage, 1); - vmbus_connection.InterruptPage = NULL; + if (vmbus_connection.int_page) { + osd_page_free(vmbus_connection.int_page, 1); + vmbus_connection.int_page = NULL; } - if (vmbus_connection.MonitorPages) { - osd_page_free(vmbus_connection.MonitorPages, 2); - vmbus_connection.MonitorPages = NULL; + if (vmbus_connection.monitor_pages) { + osd_page_free(vmbus_connection.monitor_pages, 2); + vmbus_connection.monitor_pages = NULL; } if (msginfo) { @@ -189,7 +189,7 @@ int vmbus_disconnect(void) struct vmbus_channel_message_header *msg; /* Make sure we are connected */ - if (vmbus_connection.ConnectState != Connected) + if (vmbus_connection.conn_state != CONNECTED) return -1; msg = kzalloc(sizeof(struct vmbus_channel_message_header), GFP_KERNEL); @@ -203,12 +203,12 @@ int vmbus_disconnect(void) if (ret != 0) goto Cleanup; - osd_page_free(vmbus_connection.InterruptPage, 1); + osd_page_free(vmbus_connection.int_page, 1); /* TODO: iterate thru the msg list and free up */ - destroy_workqueue(vmbus_connection.WorkQueue); + destroy_workqueue(vmbus_connection.work_queue); - vmbus_connection.ConnectState = Disconnected; + vmbus_connection.conn_state = DISCONNECTED; DPRINT_INFO(VMBUS, "Vmbus disconnected!!"); @@ -228,7 +228,7 @@ struct vmbus_channel *relid2channel(u32 relid) unsigned long flags; spin_lock_irqsave(&vmbus_connection.channel_lock, flags); - list_for_each_entry(channel, &vmbus_connection.ChannelList, listentry) { + list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) { if (channel->offermsg.child_relid == relid) { found_channel = channel; break; @@ -276,7 +276,7 @@ void vmbus_on_event(void) int maxdword = MAX_NUM_CHANNELS_SUPPORTED >> 5; int bit; int relid; - u32 *recv_int_page = vmbus_connection.RecvInterruptPage; + u32 *recv_int_page = vmbus_connection.recv_int_page; /* Check events */ if (recv_int_page) { @@ -326,7 +326,7 @@ int vmbus_set_event(u32 child_relid) { /* Each u32 represents 32 channels */ set_bit(child_relid & 31, - (unsigned long *)vmbus_connection.SendInterruptPage + + (unsigned long *)vmbus_connection.send_int_page + (child_relid >> 5)); return hv_signal_event(); diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 4c56bea47ff2..dacaa54edeac 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -239,7 +239,7 @@ static void vmbus_on_msg_dpc(struct hv_driver *drv) continue; INIT_WORK(&ctx->work, vmbus_onmessage_work); memcpy(&ctx->msg, msg, sizeof(*msg)); - queue_work(vmbus_connection.WorkQueue, &ctx->work); + queue_work(vmbus_connection.work_queue, &ctx->work); } msg->header.message_type = HVMSG_NONE; diff --git a/drivers/staging/hv/vmbus_private.h b/drivers/staging/hv/vmbus_private.h index 0ab404ed3609..004d8de1c7df 100644 --- a/drivers/staging/hv/vmbus_private.h +++ b/drivers/staging/hv/vmbus_private.h @@ -45,19 +45,19 @@ #define MAX_NUM_CHANNELS_SUPPORTED 256 -enum VMBUS_CONNECT_STATE { - Disconnected, - Connecting, - Connected, - Disconnecting +enum vmbus_connect_state { + DISCONNECTED, + CONNECTING, + CONNECTED, + DISCONNECTING }; #define MAX_SIZE_CHANNEL_MESSAGE HV_MESSAGE_PAYLOAD_BYTE_COUNT -struct VMBUS_CONNECTION { - enum VMBUS_CONNECT_STATE ConnectState; +struct vmbus_connection { + enum vmbus_connect_state conn_state; - atomic_t NextGpadlHandle; + atomic_t next_gpadl_handle; /* * Represents channel interrupts. Each bit position represents a @@ -66,39 +66,39 @@ struct VMBUS_CONNECTION { * event. The other end receives the port event and parse the * recvInterruptPage to see which bit is set */ - void *InterruptPage; - void *SendInterruptPage; - void *RecvInterruptPage; + void *int_page; + void *send_int_page; + void *recv_int_page; /* * 2 pages - 1st page for parent->child notification and 2nd * is child->parent notification */ - void *MonitorPages; - struct list_head ChannelMsgList; + void *monitor_pages; + struct list_head chn_msg_list; spinlock_t channelmsg_lock; /* List of channels */ - struct list_head ChannelList; + struct list_head chn_list; spinlock_t channel_lock; - struct workqueue_struct *WorkQueue; + struct workqueue_struct *work_queue; }; -struct VMBUS_MSGINFO { +struct vmbus_msginfo { /* Bookkeeping stuff */ - struct list_head MsgListEntry; + struct list_head msglist_entry; /* Synchronize the request/response if needed */ - struct osd_waitevent *WaitEvent; + struct osd_waitevent *wait_event; /* The message itself */ - unsigned char Msg[0]; + unsigned char msg[0]; }; -extern struct VMBUS_CONNECTION vmbus_connection; +extern struct vmbus_connection vmbus_connection; /* General vmbus interface */ -- cgit v1.2.3 From 3073acd61cf278e4f85521186e937ab6e7fee739 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 27 Jan 2011 16:49:07 +0100 Subject: staging: msm/lcdc.c: Convert IS_ERR result to PTR_ERR This code elsewhere returns a negative constant to an indicate an error, while IS_ERR returns the result of a >= operation. The semantic patch that fixes this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression x; @@ if (...) { ... - return IS_ERR(x); + return PTR_ERR(x); } // Signed-off-by: Julia Lawall Acked-by: David Brown Signed-off-by: Greg Kroah-Hartman --- drivers/staging/msm/lcdc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/msm/lcdc.c b/drivers/staging/msm/lcdc.c index 735280ab72cb..8183394aef76 100644 --- a/drivers/staging/msm/lcdc.c +++ b/drivers/staging/msm/lcdc.c @@ -224,12 +224,12 @@ static int __init lcdc_driver_init(void) mdp_lcdc_pclk_clk = clk_get(NULL, "mdp_lcdc_pclk_clk"); if (IS_ERR(mdp_lcdc_pclk_clk)) { printk(KERN_ERR "error: can't get mdp_lcdc_pclk_clk!\n"); - return IS_ERR(mdp_lcdc_pclk_clk); + return PTR_ERR(mdp_lcdc_pclk_clk); } mdp_lcdc_pad_pclk_clk = clk_get(NULL, "mdp_lcdc_pad_pclk_clk"); if (IS_ERR(mdp_lcdc_pad_pclk_clk)) { printk(KERN_ERR "error: can't get mdp_lcdc_pad_pclk_clk!\n"); - return IS_ERR(mdp_lcdc_pad_pclk_clk); + return PTR_ERR(mdp_lcdc_pad_pclk_clk); } // pm_qos_add_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc", // PM_QOS_DEFAULT_VALUE); -- cgit v1.2.3 From d7ddd16933ca9f7957b6caed5b323f7f167faa60 Mon Sep 17 00:00:00 2001 From: Coly Li Date: Thu, 27 Jan 2011 20:12:35 +0800 Subject: Staging: wl_cfg80211.c: use BUG_ON correctly This patch removes explicit unlikely() when using BUG_ON() in wl_cfg80211.c Signed-off-by: Coly Li Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 6a552bd5c90b..6962f5eea1a8 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -673,7 +673,7 @@ wl_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param, s32 iolen; iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen); - BUG_ON(unlikely(!iolen)); + BUG_ON(!iolen); return wl_dev_ioctl(dev, WLC_SET_VAR, bufptr, iolen); } @@ -685,7 +685,7 @@ wl_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param, s32 iolen; iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen); - BUG_ON(unlikely(!iolen)); + BUG_ON(!iolen); return wl_dev_ioctl(dev, WLC_GET_VAR, bufptr, buflen); } @@ -703,7 +703,7 @@ wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action) params = kzalloc(params_size, GFP_KERNEL); if (unlikely(!params)) return -ENOMEM; - BUG_ON(unlikely(params_size >= WLC_IOCTL_SMLEN)); + BUG_ON(params_size >= WLC_IOCTL_SMLEN); wl_iscan_prep(¶ms->params, ssid); @@ -874,7 +874,7 @@ static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val) val = htod32(val); len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf)); - BUG_ON(unlikely(!len)); + BUG_ON(!len); err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len); if (unlikely(err)) { @@ -898,7 +898,7 @@ wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval) len = bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var), sizeof(var.buf)); - BUG_ON(unlikely(!len)); + BUG_ON(!len); err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len); if (unlikely(err)) { WL_ERR("error (%d)\n", err); @@ -2435,7 +2435,7 @@ wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len) u32 buflen; buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX); - BUG_ON(unlikely(!buflen)); + BUG_ON(!buflen); return wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen); } @@ -2449,7 +2449,7 @@ wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf, s32 err = 0; len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX); - BUG_ON(unlikely(!len)); + BUG_ON(!len); err = wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf, WL_IOCTL_LEN_MAX); if (unlikely(err)) { -- cgit v1.2.3 From a789325dc3aa89bb5001d26b542d7abc775b46f1 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 27 Jan 2011 20:04:18 -0800 Subject: staging: ath6kl: Update cfg80211 to recent calling convention changes Add bool unicast and bool multicast to set_default_key Return struct net_device * to add_virtual_intf Signed-off-by: Joe Perches Acked-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/cfg80211.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index 7269d0a1d618..cbd9d55a2933 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -978,7 +978,7 @@ ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, static int ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, - A_UINT8 key_index) + A_UINT8 key_index, bool unicast, bool multicast) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); struct ar_key *key = NULL; @@ -1201,7 +1201,7 @@ ar6k_cfg80211_set_power_mgmt(struct wiphy *wiphy, return 0; } -static int +static struct net_device * ar6k_cfg80211_add_virtual_intf(struct wiphy *wiphy, char *name, enum nl80211_iftype type, u32 *flags, struct vif_params *params) @@ -1212,7 +1212,7 @@ ar6k_cfg80211_add_virtual_intf(struct wiphy *wiphy, char *name, /* Multiple virtual interface is not supported. * The default interface supports STA and IBSS type */ - return -EOPNOTSUPP; + return ERR_PTR(-EOPNOTSUPP); } static int -- cgit v1.2.3 From 1f4c34bded914e81b4388ccfdfab8a31da5ab0c3 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 27 Jan 2011 20:04:19 -0800 Subject: staging: ath6kl: Convert enum A_STATUS to int Convert enum members to int as well. Signed-off-by: Joe Perches Acked-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/bmi/include/bmi_internal.h | 4 +- drivers/staging/ath6kl/bmi/src/bmi.c | 72 +-- .../hif/sdio/linux_sdio/include/hif_internal.h | 10 +- .../staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 46 +- .../ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c | 12 +- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 74 +-- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 72 +-- drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c | 38 +- drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c | 40 +- .../ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c | 58 +-- drivers/staging/ath6kl/htc2/htc.c | 10 +- drivers/staging/ath6kl/htc2/htc_internal.h | 8 +- drivers/staging/ath6kl/htc2/htc_recv.c | 40 +- drivers/staging/ath6kl/htc2/htc_send.c | 10 +- drivers/staging/ath6kl/htc2/htc_services.c | 8 +- drivers/staging/ath6kl/include/a_debug.h | 4 +- drivers/staging/ath6kl/include/ar3kconfig.h | 4 +- drivers/staging/ath6kl/include/ar6000_diag.h | 10 +- drivers/staging/ath6kl/include/bmi.h | 34 +- drivers/staging/ath6kl/include/common/athdefs.h | 75 +-- drivers/staging/ath6kl/include/common_drv.h | 24 +- drivers/staging/ath6kl/include/dset_api.h | 4 +- drivers/staging/ath6kl/include/gpio_api.h | 10 +- drivers/staging/ath6kl/include/hci_transport_api.h | 18 +- drivers/staging/ath6kl/include/hif.h | 34 +- drivers/staging/ath6kl/include/htc_api.h | 18 +- drivers/staging/ath6kl/include/htc_packet.h | 2 +- drivers/staging/ath6kl/include/wlan_api.h | 2 +- drivers/staging/ath6kl/include/wmi_api.h | 274 +++++------ drivers/staging/ath6kl/miscdrv/ar3kconfig.c | 38 +- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c | 28 +- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h | 4 +- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c | 18 +- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h | 6 +- drivers/staging/ath6kl/miscdrv/common_drv.c | 66 +-- drivers/staging/ath6kl/miscdrv/credit_dist.c | 2 +- drivers/staging/ath6kl/os/linux/ar6000_android.c | 6 +- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 106 ++--- drivers/staging/ath6kl/os/linux/ar6000_pm.c | 34 +- drivers/staging/ath6kl/os/linux/ar6000_raw_if.c | 6 +- drivers/staging/ath6kl/os/linux/ar6k_pal.c | 14 +- drivers/staging/ath6kl/os/linux/cfg80211.c | 10 +- .../staging/ath6kl/os/linux/export_hci_transport.c | 28 +- drivers/staging/ath6kl/os/linux/hci_bridge.c | 48 +- .../staging/ath6kl/os/linux/include/ar6000_drv.h | 8 +- .../ath6kl/os/linux/include/ar6xapi_linux.h | 30 +- drivers/staging/ath6kl/os/linux/include/cfg80211.h | 2 +- .../ath6kl/os/linux/include/export_hci_transport.h | 22 +- .../staging/ath6kl/os/linux/include/osapi_linux.h | 18 +- drivers/staging/ath6kl/os/linux/ioctl.c | 38 +- drivers/staging/ath6kl/os/linux/netbuf.c | 18 +- drivers/staging/ath6kl/os/linux/wireless_ext.c | 8 +- drivers/staging/ath6kl/reorder/rcv_aggr.c | 4 +- drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c | 2 +- drivers/staging/ath6kl/wmi/wmi.c | 528 ++++++++++----------- 55 files changed, 1055 insertions(+), 1052 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/bmi/include/bmi_internal.h b/drivers/staging/ath6kl/bmi/include/bmi_internal.h index a44027cee4ea..34e86f31eb94 100644 --- a/drivers/staging/ath6kl/bmi/include/bmi_internal.h +++ b/drivers/staging/ath6kl/bmi/include/bmi_internal.h @@ -41,12 +41,12 @@ /* ------ Global Variable Declarations ------- */ static A_BOOL bmiDone; -A_STATUS +int bmiBufferSend(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length); -A_STATUS +int bmiBufferReceive(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length, diff --git a/drivers/staging/ath6kl/bmi/src/bmi.c b/drivers/staging/ath6kl/bmi/src/bmi.c index f17f5636f5b2..a782166875ef 100644 --- a/drivers/staging/ath6kl/bmi/src/bmi.c +++ b/drivers/staging/ath6kl/bmi/src/bmi.c @@ -105,10 +105,10 @@ BMICleanup(void) } } -A_STATUS +int BMIDone(HIF_DEVICE *device) { - A_STATUS status; + int status; A_UINT32 cid; if (bmiDone) { @@ -141,10 +141,10 @@ BMIDone(HIF_DEVICE *device) return A_OK; } -A_STATUS +int BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) { - A_STATUS status; + int status; A_UINT32 cid; if (bmiDone) { @@ -200,14 +200,14 @@ BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) return A_OK; } -A_STATUS +int BMIReadMemory(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length) { A_UINT32 cid; - A_STATUS status; + int status; A_UINT32 offset; A_UINT32 remaining, rxlen; @@ -256,14 +256,14 @@ BMIReadMemory(HIF_DEVICE *device, return A_OK; } -A_STATUS +int BMIWriteMemory(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length) { A_UINT32 cid; - A_STATUS status; + int status; A_UINT32 offset; A_UINT32 remaining, txlen; const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(length); @@ -321,13 +321,13 @@ BMIWriteMemory(HIF_DEVICE *device, return A_OK; } -A_STATUS +int BMIExecute(HIF_DEVICE *device, A_UINT32 address, A_UINT32 *param) { A_UINT32 cid; - A_STATUS status; + int status; A_UINT32 offset; A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param))); @@ -369,12 +369,12 @@ BMIExecute(HIF_DEVICE *device, return A_OK; } -A_STATUS +int BMISetAppStart(HIF_DEVICE *device, A_UINT32 address) { A_UINT32 cid; - A_STATUS status; + int status; A_UINT32 offset; A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address))); @@ -406,13 +406,13 @@ BMISetAppStart(HIF_DEVICE *device, return A_OK; } -A_STATUS +int BMIReadSOCRegister(HIF_DEVICE *device, A_UINT32 address, A_UINT32 *param) { A_UINT32 cid; - A_STATUS status; + int status; A_UINT32 offset; A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address))); @@ -452,13 +452,13 @@ BMIReadSOCRegister(HIF_DEVICE *device, return A_OK; } -A_STATUS +int BMIWriteSOCRegister(HIF_DEVICE *device, A_UINT32 address, A_UINT32 param) { A_UINT32 cid; - A_STATUS status; + int status; A_UINT32 offset; A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param))); @@ -492,7 +492,7 @@ BMIWriteSOCRegister(HIF_DEVICE *device, return A_OK; } -A_STATUS +int BMIrompatchInstall(HIF_DEVICE *device, A_UINT32 ROM_addr, A_UINT32 RAM_addr, @@ -501,7 +501,7 @@ BMIrompatchInstall(HIF_DEVICE *device, A_UINT32 *rompatch_id) { A_UINT32 cid; - A_STATUS status; + int status; A_UINT32 offset; A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) + @@ -548,12 +548,12 @@ BMIrompatchInstall(HIF_DEVICE *device, return A_OK; } -A_STATUS +int BMIrompatchUninstall(HIF_DEVICE *device, A_UINT32 rompatch_id) { A_UINT32 cid; - A_STATUS status; + int status; A_UINT32 offset; A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(rompatch_id))); @@ -585,14 +585,14 @@ BMIrompatchUninstall(HIF_DEVICE *device, return A_OK; } -static A_STATUS +static int _BMIrompatchChangeActivation(HIF_DEVICE *device, A_UINT32 rompatch_count, A_UINT32 *rompatch_list, A_UINT32 do_activate) { A_UINT32 cid; - A_STATUS status; + int status; A_UINT32 offset; A_UINT32 length; @@ -629,7 +629,7 @@ _BMIrompatchChangeActivation(HIF_DEVICE *device, return A_OK; } -A_STATUS +int BMIrompatchActivate(HIF_DEVICE *device, A_UINT32 rompatch_count, A_UINT32 *rompatch_list) @@ -637,7 +637,7 @@ BMIrompatchActivate(HIF_DEVICE *device, return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 1); } -A_STATUS +int BMIrompatchDeactivate(HIF_DEVICE *device, A_UINT32 rompatch_count, A_UINT32 *rompatch_list) @@ -645,13 +645,13 @@ BMIrompatchDeactivate(HIF_DEVICE *device, return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 0); } -A_STATUS +int BMILZData(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length) { A_UINT32 cid; - A_STATUS status; + int status; A_UINT32 offset; A_UINT32 remaining, txlen; const A_UINT32 header = sizeof(cid) + sizeof(length); @@ -695,12 +695,12 @@ BMILZData(HIF_DEVICE *device, return A_OK; } -A_STATUS +int BMILZStreamStart(HIF_DEVICE *device, A_UINT32 address) { A_UINT32 cid; - A_STATUS status; + int status; A_UINT32 offset; A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address))); @@ -733,12 +733,12 @@ BMILZStreamStart(HIF_DEVICE *device, } /* BMI Access routines */ -A_STATUS +int bmiBufferSend(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length) { - A_STATUS status; + int status; A_UINT32 timeout; A_UINT32 address; A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX]; @@ -781,13 +781,13 @@ bmiBufferSend(HIF_DEVICE *device, return status; } -A_STATUS +int bmiBufferReceive(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length, A_BOOL want_timeout) { - A_STATUS status; + int status; A_UINT32 address; A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX]; HIF_PENDING_EVENTS_INFO hifPendingEvents; @@ -957,10 +957,10 @@ bmiBufferReceive(HIF_DEVICE *device, return A_OK; } -A_STATUS +int BMIFastDownload(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length) { - A_STATUS status = A_ERROR; + int status = A_ERROR; A_UINT32 lastWord = 0; A_UINT32 lastWordOffset = length & ~0x3; A_UINT32 unalignedBytes = length & 0x3; @@ -997,13 +997,13 @@ BMIFastDownload(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 return status; } -A_STATUS +int BMIRawWrite(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length) { return bmiBufferSend(device, buffer, length); } -A_STATUS +int BMIRawRead(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length, A_BOOL want_timeout) { return bmiBufferReceive(device, buffer, length, want_timeout); diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h index 857f35f36ca2..f72ba6cf50c4 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h @@ -58,7 +58,7 @@ typedef struct bus_request { A_UINT32 length; A_UINT32 request; void *context; - A_STATUS status; + int status; struct _HIF_SCATTER_REQ_PRIV *pScatterReq; /* this request is a scatter request */ } BUS_REQUEST; @@ -110,18 +110,18 @@ typedef struct _HIF_SCATTER_REQ_PRIV { #define ATH_DEBUG_SCATTER ATH_DEBUG_MAKE_MODULE_MASK(0) -A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo); +int SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo); void CleanupHIFScatterResources(HIF_DEVICE *device); -A_STATUS DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest); +int DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest); #else // HIF_LINUX_MMC_SCATTER_SUPPORT -static inline A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo) +static inline int SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo) { return A_ENOTSUP; } -static inline A_STATUS DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest) +static inline int DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest) { return A_ENOTSUP; } diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index e96662b84ed9..61166a5cb02e 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -107,8 +107,8 @@ extern A_UINT32 busspeedlow; extern A_UINT32 debughif; static void ResetAllCards(void); -static A_STATUS hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func); -static A_STATUS hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func); +static int hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func); +static int hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func); #ifdef DEBUG @@ -123,7 +123,7 @@ ATH_DEBUG_INSTANTIATE_MODULE_VAR(hif, /* ------ Functions ------ */ -A_STATUS HIFInit(OSDRV_CALLBACKS *callbacks) +int HIFInit(OSDRV_CALLBACKS *callbacks) { int status; AR_DEBUG_ASSERT(callbacks != NULL); @@ -152,7 +152,7 @@ A_STATUS HIFInit(OSDRV_CALLBACKS *callbacks) } -static A_STATUS +static int __HIFReadWrite(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, @@ -161,7 +161,7 @@ __HIFReadWrite(HIF_DEVICE *device, void *context) { A_UINT8 opcode; - A_STATUS status = A_OK; + int status = A_OK; int ret; A_UINT8 *tbuffer; A_BOOL bounced = FALSE; @@ -329,7 +329,7 @@ void AddToAsyncList(HIF_DEVICE *device, BUS_REQUEST *busrequest) /* queue a read/write request */ -A_STATUS +int HIFReadWrite(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, @@ -337,7 +337,7 @@ HIFReadWrite(HIF_DEVICE *device, A_UINT32 request, void *context) { - A_STATUS status = A_OK; + int status = A_OK; BUS_REQUEST *busrequest; @@ -375,7 +375,7 @@ HIFReadWrite(HIF_DEVICE *device, /* interrupted, exit */ return A_ERROR; } else { - A_STATUS status = busrequest->status; + int status = busrequest->status; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: sync return freeing 0x%lX: 0x%X\n", (unsigned long)busrequest, busrequest->status)); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: freeing req: 0x%X\n", (unsigned int)request)); @@ -402,7 +402,7 @@ static int async_task(void *param) { HIF_DEVICE *device; BUS_REQUEST *request; - A_STATUS status; + int status; unsigned long flags; device = (HIF_DEVICE *)param; @@ -488,7 +488,7 @@ static A_INT32 IssueSDCommand(HIF_DEVICE *device, A_UINT32 opcode, A_UINT32 arg, return err; } -A_STATUS ReinitSDIO(HIF_DEVICE *device) +int ReinitSDIO(HIF_DEVICE *device) { A_INT32 err; struct mmc_host *host; @@ -647,10 +647,10 @@ A_STATUS ReinitSDIO(HIF_DEVICE *device) return (err) ? A_ERROR : A_OK; } -A_STATUS +int PowerStateChangeNotify(HIF_DEVICE *device, HIF_DEVICE_POWER_CHANGE_TYPE config) { - A_STATUS status = A_OK; + int status = A_OK; #if defined(CONFIG_PM) struct sdio_func *func = device->func; int old_reset_val; @@ -690,12 +690,12 @@ PowerStateChangeNotify(HIF_DEVICE *device, HIF_DEVICE_POWER_CHANGE_TYPE config) return status; } -A_STATUS +int HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, void *config, A_UINT32 configLen) { A_UINT32 count; - A_STATUS status = A_OK; + int status = A_OK; switch(opcode) { case HIF_DEVICE_GET_MBOX_BLOCK_SIZE: @@ -774,7 +774,7 @@ HIFShutDownDevice(HIF_DEVICE *device) static void hifIRQHandler(struct sdio_func *func) { - A_STATUS status; + int status; HIF_DEVICE *device; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifIRQHandler\n")); @@ -949,10 +949,10 @@ hifFreeBusRequest(HIF_DEVICE *device, BUS_REQUEST *busrequest) spin_unlock_irqrestore(&device->lock, flag); } -static A_STATUS hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func) +static int hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func) { int ret; - A_STATUS status = A_OK; + int status = A_OK; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDisableFunc\n")); device = getHifDevice(func); @@ -1080,7 +1080,7 @@ static int hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func) static int hifDeviceSuspend(struct device *dev) { struct sdio_func *func=dev_to_sdio_func(dev); - A_STATUS status = A_OK; + int status = A_OK; HIF_DEVICE *device; device = getHifDevice(func); @@ -1107,7 +1107,7 @@ static int hifDeviceSuspend(struct device *dev) static int hifDeviceResume(struct device *dev) { struct sdio_func *func=dev_to_sdio_func(dev); - A_STATUS status = A_OK; + int status = A_OK; HIF_DEVICE *device; device = getHifDevice(func); @@ -1126,7 +1126,7 @@ static int hifDeviceResume(struct device *dev) static void hifDeviceRemoved(struct sdio_func *func) { - A_STATUS status = A_OK; + int status = A_OK; HIF_DEVICE *device; AR_DEBUG_ASSERT(func != NULL); @@ -1151,11 +1151,11 @@ static void hifDeviceRemoved(struct sdio_func *func) /* * This should be moved to AR6K HTC layer. */ -A_STATUS hifWaitForPendingRecv(HIF_DEVICE *device) +int hifWaitForPendingRecv(HIF_DEVICE *device) { A_INT32 cnt = 10; A_UINT8 host_int_status; - A_STATUS status = A_OK; + int status = A_OK; do { while (atomic_read(&device->irqHandling)) { @@ -1233,7 +1233,7 @@ void HIFReleaseDevice(HIF_DEVICE *device) device->claimedContext = NULL; } -A_STATUS HIFAttachHTC(HIF_DEVICE *device, HTC_CALLBACKS *callbacks) +int HIFAttachHTC(HIF_DEVICE *device, HTC_CALLBACKS *callbacks) { if (device->htcCallbacks.context != NULL) { /* already in use! */ diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c index ee8b47746a15..ceeced47cd22 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c @@ -79,7 +79,7 @@ static HIF_SCATTER_REQ *AllocScatterReq(HIF_DEVICE *device) } /* called by async task to perform the operation synchronously using direct MMC APIs */ -A_STATUS DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest) +int DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest) { int i; A_UINT8 rw; @@ -89,7 +89,7 @@ A_STATUS DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest) struct mmc_data data; HIF_SCATTER_REQ_PRIV *pReqPriv; HIF_SCATTER_REQ *pReq; - A_STATUS status = A_OK; + int status = A_OK; struct scatterlist *pSg; pReqPriv = busrequest->pScatterReq; @@ -199,9 +199,9 @@ A_STATUS DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest) } /* callback to issue a read-write scatter request */ -static A_STATUS HifReadWriteScatter(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq) +static int HifReadWriteScatter(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq) { - A_STATUS status = A_EINVAL; + int status = A_EINVAL; A_UINT32 request = pReq->Request; HIF_SCATTER_REQ_PRIV *pReqPriv = (HIF_SCATTER_REQ_PRIV *)pReq->HIFPrivate[0]; @@ -275,9 +275,9 @@ static A_STATUS HifReadWriteScatter(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq) } /* setup of HIF scatter resources */ -A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo) +int SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo) { - A_STATUS status = A_ERROR; + int status = A_ERROR; int i; HIF_SCATTER_REQ_PRIV *pReqPriv; BUS_REQUEST *busrequest; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index 1efc85ce02b2..8c6d6591ecad 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -35,8 +35,8 @@ #define MAILBOX_FOR_BLOCK_SIZE 1 -A_STATUS DevEnableInterrupts(AR6K_DEVICE *pDev); -A_STATUS DevDisableInterrupts(AR6K_DEVICE *pDev); +int DevEnableInterrupts(AR6K_DEVICE *pDev); +int DevDisableInterrupts(AR6K_DEVICE *pDev); static void DevCleanupVirtualScatterSupport(AR6K_DEVICE *pDev); @@ -74,10 +74,10 @@ void DevCleanup(AR6K_DEVICE *pDev) } } -A_STATUS DevSetup(AR6K_DEVICE *pDev) +int DevSetup(AR6K_DEVICE *pDev) { A_UINT32 blocksizes[AR6K_MAILBOXES]; - A_STATUS status = A_OK; + int status = A_OK; int i; HTC_CALLBACKS htcCallbacks; @@ -216,9 +216,9 @@ A_STATUS DevSetup(AR6K_DEVICE *pDev) } -A_STATUS DevEnableInterrupts(AR6K_DEVICE *pDev) +int DevEnableInterrupts(AR6K_DEVICE *pDev) { - A_STATUS status; + int status; AR6K_IRQ_ENABLE_REGISTERS regs; LOCK_AR6K(pDev); @@ -276,7 +276,7 @@ A_STATUS DevEnableInterrupts(AR6K_DEVICE *pDev) return status; } -A_STATUS DevDisableInterrupts(AR6K_DEVICE *pDev) +int DevDisableInterrupts(AR6K_DEVICE *pDev) { AR6K_IRQ_ENABLE_REGISTERS regs; @@ -301,7 +301,7 @@ A_STATUS DevDisableInterrupts(AR6K_DEVICE *pDev) } /* enable device interrupts */ -A_STATUS DevUnmaskInterrupts(AR6K_DEVICE *pDev) +int DevUnmaskInterrupts(AR6K_DEVICE *pDev) { /* for good measure, make sure interrupt are disabled before unmasking at the HIF * layer. @@ -309,7 +309,7 @@ A_STATUS DevUnmaskInterrupts(AR6K_DEVICE *pDev) * and when HTC is finally ready to handle interrupts, other software can perform target "soft" resets. * The AR6K interrupt enables reset back to an "enabled" state when this happens. * */ - A_STATUS IntStatus = A_OK; + int IntStatus = A_OK; DevDisableInterrupts(pDev); #ifdef THREAD_X @@ -327,7 +327,7 @@ A_STATUS DevUnmaskInterrupts(AR6K_DEVICE *pDev) } /* disable all device interrupts */ -A_STATUS DevMaskInterrupts(AR6K_DEVICE *pDev) +int DevMaskInterrupts(AR6K_DEVICE *pDev) { /* mask the interrupt at the HIF layer, we don't want a stray interrupt taken while * we zero out our shadow registers in DevDisableInterrupts()*/ @@ -355,9 +355,9 @@ static void DevDoEnableDisableRecvAsyncHandler(void *Context, HTC_PACKET *pPacke /* disable packet reception (used in case the host runs out of buffers) * this is the "override" method when the HIF reports another methods to * disable recv events */ -static A_STATUS DevDoEnableDisableRecvOverride(AR6K_DEVICE *pDev, A_BOOL EnableRecv, A_BOOL AsyncMode) +static int DevDoEnableDisableRecvOverride(AR6K_DEVICE *pDev, A_BOOL EnableRecv, A_BOOL AsyncMode) { - A_STATUS status = A_OK; + int status = A_OK; HTC_PACKET *pIOPacket = NULL; AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("DevDoEnableDisableRecvOverride: Enable:%d Mode:%d\n", @@ -403,9 +403,9 @@ static A_STATUS DevDoEnableDisableRecvOverride(AR6K_DEVICE *pDev, A_BOOL EnableR /* disable packet reception (used in case the host runs out of buffers) * this is the "normal" method using the interrupt enable registers through * the host I/F */ -static A_STATUS DevDoEnableDisableRecvNormal(AR6K_DEVICE *pDev, A_BOOL EnableRecv, A_BOOL AsyncMode) +static int DevDoEnableDisableRecvNormal(AR6K_DEVICE *pDev, A_BOOL EnableRecv, A_BOOL AsyncMode) { - A_STATUS status = A_OK; + int status = A_OK; HTC_PACKET *pIOPacket = NULL; AR6K_IRQ_ENABLE_REGISTERS regs; @@ -470,7 +470,7 @@ static A_STATUS DevDoEnableDisableRecvNormal(AR6K_DEVICE *pDev, A_BOOL EnableRec } -A_STATUS DevStopRecv(AR6K_DEVICE *pDev, A_BOOL AsyncMode) +int DevStopRecv(AR6K_DEVICE *pDev, A_BOOL AsyncMode) { if (NULL == pDev->HifMaskUmaskRecvEvent) { return DevDoEnableDisableRecvNormal(pDev,FALSE,AsyncMode); @@ -479,7 +479,7 @@ A_STATUS DevStopRecv(AR6K_DEVICE *pDev, A_BOOL AsyncMode) } } -A_STATUS DevEnableRecv(AR6K_DEVICE *pDev, A_BOOL AsyncMode) +int DevEnableRecv(AR6K_DEVICE *pDev, A_BOOL AsyncMode) { if (NULL == pDev->HifMaskUmaskRecvEvent) { return DevDoEnableDisableRecvNormal(pDev,TRUE,AsyncMode); @@ -488,9 +488,9 @@ A_STATUS DevEnableRecv(AR6K_DEVICE *pDev, A_BOOL AsyncMode) } } -A_STATUS DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,A_BOOL *pbIsRecvPending) +int DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,A_BOOL *pbIsRecvPending) { - A_STATUS status = A_OK; + int status = A_OK; A_UCHAR host_int_status = 0x0; A_UINT32 counter = 0x0; @@ -608,7 +608,7 @@ static void DevFreeScatterReq(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) UNLOCK_AR6K(pDev); } -A_STATUS DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, A_BOOL FromDMA) +int DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, A_BOOL FromDMA) { A_UINT8 *pDMABuffer = NULL; int i, remaining; @@ -664,10 +664,10 @@ static void DevReadWriteScatterAsyncHandler(void *Context, HTC_PACKET *pPacket) AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-DevReadWriteScatterAsyncHandler \n")); } -static A_STATUS DevReadWriteScatter(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) +static int DevReadWriteScatter(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) { AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; - A_STATUS status = A_OK; + int status = A_OK; HTC_PACKET *pIOPacket = NULL; A_UINT32 request = pReq->Request; @@ -749,9 +749,9 @@ static void DevCleanupVirtualScatterSupport(AR6K_DEVICE *pDev) } /* function to set up virtual scatter support if HIF layer has not implemented the interface */ -static A_STATUS DevSetupVirtualScatterSupport(AR6K_DEVICE *pDev) +static int DevSetupVirtualScatterSupport(AR6K_DEVICE *pDev) { - A_STATUS status = A_OK; + int status = A_OK; int bufferSize, sgreqSize; int i; DEV_SCATTER_DMA_VIRTUAL_INFO *pVirtualInfo; @@ -811,9 +811,9 @@ static A_STATUS DevSetupVirtualScatterSupport(AR6K_DEVICE *pDev) } -A_STATUS DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer) +int DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer) { - A_STATUS status; + int status; if (pDev->MailBoxInfo.Flags & HIF_MBOX_FLAG_NO_BUNDLING) { AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HIF requires bundling disabled\n")); @@ -876,9 +876,9 @@ A_STATUS DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer) return status; } -A_STATUS DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, A_BOOL Read, A_BOOL Async) +int DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, A_BOOL Read, A_BOOL Async) { - A_STATUS status; + int status; if (Read) { /* read operation */ @@ -1125,9 +1125,9 @@ static A_UINT16 GetEndMarker(void) #define ATH_PRINT_OUT_ZONE ATH_DEBUG_ERR /* send the ordered buffers to the target */ -static A_STATUS SendBuffers(AR6K_DEVICE *pDev, int mbox) +static int SendBuffers(AR6K_DEVICE *pDev, int mbox) { - A_STATUS status = A_OK; + int status = A_OK; A_UINT32 request = HIF_WR_SYNC_BLOCK_INC; BUFFER_PROC_LIST sendList[BUFFER_PROC_LIST_DEPTH]; int i; @@ -1169,9 +1169,9 @@ static A_STATUS SendBuffers(AR6K_DEVICE *pDev, int mbox) } /* poll the mailbox credit counter until we get a credit or timeout */ -static A_STATUS GetCredits(AR6K_DEVICE *pDev, int mbox, int *pCredits) +static int GetCredits(AR6K_DEVICE *pDev, int mbox, int *pCredits) { - A_STATUS status = A_OK; + int status = A_OK; int timeout = TEST_CREDITS_RECV_TIMEOUT; A_UINT8 credits = 0; A_UINT32 address; @@ -1216,9 +1216,9 @@ static A_STATUS GetCredits(AR6K_DEVICE *pDev, int mbox, int *pCredits) /* wait for the buffers to come back */ -static A_STATUS RecvBuffers(AR6K_DEVICE *pDev, int mbox) +static int RecvBuffers(AR6K_DEVICE *pDev, int mbox) { - A_STATUS status = A_OK; + int status = A_OK; A_UINT32 request = HIF_RD_SYNC_BLOCK_INC; BUFFER_PROC_LIST recvList[BUFFER_PROC_LIST_DEPTH]; int curBuffer; @@ -1294,9 +1294,9 @@ static A_STATUS RecvBuffers(AR6K_DEVICE *pDev, int mbox) } -static A_STATUS DoOneMboxHWTest(AR6K_DEVICE *pDev, int mbox) +static int DoOneMboxHWTest(AR6K_DEVICE *pDev, int mbox) { - A_STATUS status; + int status; do { /* send out buffers */ @@ -1330,10 +1330,10 @@ static A_STATUS DoOneMboxHWTest(AR6K_DEVICE *pDev, int mbox) } /* here is where the test starts */ -A_STATUS DoMboxHWTest(AR6K_DEVICE *pDev) +int DoMboxHWTest(AR6K_DEVICE *pDev) { int i; - A_STATUS status; + int status; int credits = 0; A_UINT8 params[4]; int numBufs; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index b30fd877aebf..7578e91562b9 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -98,9 +98,9 @@ typedef struct AR6K_ASYNC_REG_IO_BUFFER { typedef struct _AR6K_GMBOX_INFO { void *pProtocolContext; - A_STATUS (*pMessagePendingCallBack)(void *pContext, A_UINT8 LookAheadBytes[], int ValidBytes); - A_STATUS (*pCreditsPendingCallback)(void *pContext, int NumCredits, A_BOOL CreditIRQEnabled); - void (*pTargetFailureCallback)(void *pContext, A_STATUS Status); + int (*pMessagePendingCallBack)(void *pContext, A_UINT8 LookAheadBytes[], int ValidBytes); + int (*pCreditsPendingCallback)(void *pContext, int NumCredits, A_BOOL CreditIRQEnabled); + void (*pTargetFailureCallback)(void *pContext, int Status); void (*pStateDumpCallback)(void *pContext); A_BOOL CreditCountIRQEnabled; } AR6K_GMBOX_INFO; @@ -121,7 +121,7 @@ typedef struct _AR6K_DEVICE { HTC_PACKET_QUEUE RegisterIOList; AR6K_ASYNC_REG_IO_BUFFER RegIOBuffers[AR6K_MAX_REG_IO_BUFFERS]; void (*TargetFailureCallback)(void *Context); - A_STATUS (*MessagePendingCallback)(void *Context, + int (*MessagePendingCallback)(void *Context, A_UINT32 LookAheads[], int NumLookAheads, A_BOOL *pAsyncProc, @@ -147,16 +147,16 @@ typedef struct _AR6K_DEVICE { #define UNLOCK_AR6K(p) A_MUTEX_UNLOCK(&(p)->Lock); #define REF_IRQ_STATUS_RECHECK(p) (p)->RecheckIRQStatusCnt = 1 /* note: no need to lock this, it only gets set */ -A_STATUS DevSetup(AR6K_DEVICE *pDev); +int DevSetup(AR6K_DEVICE *pDev); void DevCleanup(AR6K_DEVICE *pDev); -A_STATUS DevUnmaskInterrupts(AR6K_DEVICE *pDev); -A_STATUS DevMaskInterrupts(AR6K_DEVICE *pDev); -A_STATUS DevPollMboxMsgRecv(AR6K_DEVICE *pDev, +int DevUnmaskInterrupts(AR6K_DEVICE *pDev); +int DevMaskInterrupts(AR6K_DEVICE *pDev); +int DevPollMboxMsgRecv(AR6K_DEVICE *pDev, A_UINT32 *pLookAhead, int TimeoutMS); -A_STATUS DevRWCompletionHandler(void *context, A_STATUS status); -A_STATUS DevDsrHandler(void *context); -A_STATUS DevCheckPendingRecvMsgsAsync(void *context); +int DevRWCompletionHandler(void *context, int status); +int DevDsrHandler(void *context); +int DevCheckPendingRecvMsgsAsync(void *context); void DevAsyncIrqProcessComplete(AR6K_DEVICE *pDev); void DevDumpRegisters(AR6K_DEVICE *pDev, AR6K_IRQ_PROC_REGISTERS *pIrqProcRegs, @@ -166,20 +166,20 @@ void DevDumpRegisters(AR6K_DEVICE *pDev, #define DEV_STOP_RECV_SYNC FALSE #define DEV_ENABLE_RECV_ASYNC TRUE #define DEV_ENABLE_RECV_SYNC FALSE -A_STATUS DevStopRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode); -A_STATUS DevEnableRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode); -A_STATUS DevEnableInterrupts(AR6K_DEVICE *pDev); -A_STATUS DevDisableInterrupts(AR6K_DEVICE *pDev); -A_STATUS DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,A_BOOL *pbIsRecvPending); +int DevStopRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode); +int DevEnableRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode); +int DevEnableInterrupts(AR6K_DEVICE *pDev); +int DevDisableInterrupts(AR6K_DEVICE *pDev); +int DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,A_BOOL *pbIsRecvPending); #define DEV_CALC_RECV_PADDED_LEN(pDev, length) (((length) + (pDev)->BlockMask) & (~((pDev)->BlockMask))) #define DEV_CALC_SEND_PADDED_LEN(pDev, length) DEV_CALC_RECV_PADDED_LEN(pDev,length) #define DEV_IS_LEN_BLOCK_ALIGNED(pDev, length) (((length) % (pDev)->BlockSize) == 0) -static INLINE A_STATUS DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 SendLength) { +static INLINE int DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 SendLength) { A_UINT32 paddedLength; A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE; - A_STATUS status; + int status; /* adjust the length to be a multiple of block size if appropriate */ paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, SendLength); @@ -219,9 +219,9 @@ static INLINE A_STATUS DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_U return status; } -static INLINE A_STATUS DevRecvPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 RecvLength) { +static INLINE int DevRecvPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 RecvLength) { A_UINT32 paddedLength; - A_STATUS status; + int status; A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE; /* adjust the length to be a multiple of block size if appropriate */ @@ -272,7 +272,7 @@ static INLINE A_STATUS DevRecvPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_U * */ -A_STATUS DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, A_BOOL FromDMA); +int DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, A_BOOL FromDMA); /* copy any READ data back into scatter list */ #define DEV_FINISH_SCATTER_OPERATION(pR) \ @@ -283,7 +283,7 @@ A_STATUS DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, A_BOOL FromDMA } /* copy any WRITE data to bounce buffer */ -static INLINE A_STATUS DEV_PREPARE_SCATTER_OPERATION(HIF_SCATTER_REQ *pReq) { +static INLINE int DEV_PREPARE_SCATTER_OPERATION(HIF_SCATTER_REQ *pReq) { if ((pReq->Request & HIF_WRITE) && (pReq->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) { return DevCopyScatterListToFromDMABuffer(pReq,TO_DMA_BUFFER); } else { @@ -292,7 +292,7 @@ static INLINE A_STATUS DEV_PREPARE_SCATTER_OPERATION(HIF_SCATTER_REQ *pReq) { } -A_STATUS DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer); +int DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer); #define DEV_GET_MAX_MSG_PER_BUNDLE(pDev) (pDev)->HifScatterInfo.MaxScatterEntries #define DEV_GET_MAX_BUNDLE_LENGTH(pDev) (pDev)->HifScatterInfo.MaxTransferSizePerScatterReq @@ -309,10 +309,10 @@ A_STATUS DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer); #define DEV_SCATTER_WRITE FALSE #define DEV_SCATTER_ASYNC TRUE #define DEV_SCATTER_SYNC FALSE -A_STATUS DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, A_BOOL Read, A_BOOL Async); +int DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, A_BOOL Read, A_BOOL Async); #ifdef MBOXHW_UNIT_TEST -A_STATUS DoMboxHWTest(AR6K_DEVICE *pDev); +int DoMboxHWTest(AR6K_DEVICE *pDev); #endif /* completely virtual */ @@ -334,8 +334,8 @@ void DumpAR6KDevState(AR6K_DEVICE *pDev); #ifdef ATH_AR6K_ENABLE_GMBOX void DevCleanupGMbox(AR6K_DEVICE *pDev); -A_STATUS DevSetupGMbox(AR6K_DEVICE *pDev); -A_STATUS DevCheckGMboxInterrupts(AR6K_DEVICE *pDev); +int DevSetupGMbox(AR6K_DEVICE *pDev); +int DevCheckGMboxInterrupts(AR6K_DEVICE *pDev); void DevNotifyGMboxTargetFailure(AR6K_DEVICE *pDev); #else @@ -345,7 +345,7 @@ void DevNotifyGMboxTargetFailure(AR6K_DEVICE *pDev); #define DevCheckGMboxInterrupts(p) A_OK #define DevNotifyGMboxTargetFailure(p) -static INLINE A_STATUS DevSetupGMbox(AR6K_DEVICE *pDev) { +static INLINE int DevSetupGMbox(AR6K_DEVICE *pDev) { pDev->GMboxEnabled = FALSE; return A_OK; } @@ -356,7 +356,7 @@ static INLINE A_STATUS DevSetupGMbox(AR6K_DEVICE *pDev) { /* GMBOX protocol modules must expose each of these internal APIs */ HCI_TRANSPORT_HANDLE GMboxAttachProtocol(AR6K_DEVICE *pDev, HCI_TRANSPORT_CONFIG_INFO *pInfo); -A_STATUS GMboxProtocolInstall(AR6K_DEVICE *pDev); +int GMboxProtocolInstall(AR6K_DEVICE *pDev); void GMboxProtocolUninstall(AR6K_DEVICE *pDev); /* API used by GMBOX protocol modules */ @@ -372,8 +372,8 @@ AR6K_DEVICE *HTCGetAR6KDevice(void *HTCHandle); #define DEV_GMBOX_GET_PROTOCOL(pDev) (pDev)->GMboxInfo.pProtocolContext -A_STATUS DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 WriteLength); -A_STATUS DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 ReadLength); +int DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 WriteLength); +int DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 ReadLength); #define PROC_IO_ASYNC TRUE #define PROC_IO_SYNC FALSE @@ -387,11 +387,11 @@ typedef enum GMBOX_IRQ_ACTION_TYPE { GMBOX_CREDIT_IRQ_DISABLE, } GMBOX_IRQ_ACTION_TYPE; -A_STATUS DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE, A_BOOL AsyncMode); -A_STATUS DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, A_BOOL AsyncMode, int *pCredits); -A_STATUS DevGMboxReadCreditSize(AR6K_DEVICE *pDev, int *pCreditSize); -A_STATUS DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, A_UINT8 *pLookAheadBuffer, int *pLookAheadBytes); -A_STATUS DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int SignalNumber, int AckTimeoutMS); +int DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE, A_BOOL AsyncMode); +int DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, A_BOOL AsyncMode, int *pCredits); +int DevGMboxReadCreditSize(AR6K_DEVICE *pDev, int *pCreditSize); +int DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, A_UINT8 *pLookAheadBuffer, int *pLookAheadBytes); +int DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int SignalNumber, int AckTimeoutMS); #endif diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c index 920123b9ba1a..21d88f19011d 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c @@ -36,12 +36,12 @@ extern void AR6KFreeIOPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket); extern HTC_PACKET *AR6KAllocIOPacket(AR6K_DEVICE *pDev); -static A_STATUS DevServiceDebugInterrupt(AR6K_DEVICE *pDev); +static int DevServiceDebugInterrupt(AR6K_DEVICE *pDev); #define DELAY_PER_INTERVAL_MS 10 /* 10 MS delay per polling interval */ /* completion routine for ALL HIF layer async I/O */ -A_STATUS DevRWCompletionHandler(void *context, A_STATUS status) +int DevRWCompletionHandler(void *context, int status) { HTC_PACKET *pPacket = (HTC_PACKET *)context; @@ -59,11 +59,11 @@ A_STATUS DevRWCompletionHandler(void *context, A_STATUS status) } /* mailbox recv message polling */ -A_STATUS DevPollMboxMsgRecv(AR6K_DEVICE *pDev, +int DevPollMboxMsgRecv(AR6K_DEVICE *pDev, A_UINT32 *pLookAhead, int TimeoutMS) { - A_STATUS status = A_OK; + int status = A_OK; int timeout = TimeoutMS/DELAY_PER_INTERVAL_MS; A_ASSERT(timeout > 0); @@ -152,9 +152,9 @@ A_STATUS DevPollMboxMsgRecv(AR6K_DEVICE *pDev, return status; } -static A_STATUS DevServiceCPUInterrupt(AR6K_DEVICE *pDev) +static int DevServiceCPUInterrupt(AR6K_DEVICE *pDev) { - A_STATUS status; + int status; A_UINT8 cpu_int_status; A_UINT8 regBuffer[4]; @@ -192,9 +192,9 @@ static A_STATUS DevServiceCPUInterrupt(AR6K_DEVICE *pDev) } -static A_STATUS DevServiceErrorInterrupt(AR6K_DEVICE *pDev) +static int DevServiceErrorInterrupt(AR6K_DEVICE *pDev) { - A_STATUS status; + int status; A_UINT8 error_int_status; A_UINT8 regBuffer[4]; @@ -245,10 +245,10 @@ static A_STATUS DevServiceErrorInterrupt(AR6K_DEVICE *pDev) return status; } -static A_STATUS DevServiceDebugInterrupt(AR6K_DEVICE *pDev) +static int DevServiceDebugInterrupt(AR6K_DEVICE *pDev) { A_UINT32 dummy; - A_STATUS status; + int status; /* Send a target failure event to the application */ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Target debug interrupt\n")); @@ -275,7 +275,7 @@ static A_STATUS DevServiceDebugInterrupt(AR6K_DEVICE *pDev) return status; } -static A_STATUS DevServiceCounterInterrupt(AR6K_DEVICE *pDev) +static int DevServiceCounterInterrupt(AR6K_DEVICE *pDev) { A_UINT8 counter_int_status; @@ -363,7 +363,7 @@ static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket) HIFAckInterrupt(pDev->HIFDevice); } else { int fetched = 0; - A_STATUS status; + int status; AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, (" DevGetEventAsyncHandler : detected another message, lookahead :0x%X \n", @@ -388,10 +388,10 @@ static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket) /* called by the HTC layer when it wants us to check if the device has any more pending * recv messages, this starts off a series of async requests to read interrupt registers */ -A_STATUS DevCheckPendingRecvMsgsAsync(void *context) +int DevCheckPendingRecvMsgsAsync(void *context) { AR6K_DEVICE *pDev = (AR6K_DEVICE *)context; - A_STATUS status = A_OK; + int status = A_OK; HTC_PACKET *pIOPacket; /* this is called in an ASYNC only context, we may NOT block, sleep or call any apis that can @@ -467,9 +467,9 @@ void DevAsyncIrqProcessComplete(AR6K_DEVICE *pDev) } /* process pending interrupts synchronously */ -static A_STATUS ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pASyncProcessing) +static int ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pASyncProcessing) { - A_STATUS status = A_OK; + int status = A_OK; A_UINT8 host_int_status = 0; A_UINT32 lookAhead = 0; @@ -681,10 +681,10 @@ static A_STATUS ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pAS /* Synchronousinterrupt handler, this handler kicks off all interrupt processing.*/ -A_STATUS DevDsrHandler(void *context) +int DevDsrHandler(void *context) { AR6K_DEVICE *pDev = (AR6K_DEVICE *)context; - A_STATUS status = A_OK; + int status = A_OK; A_BOOL done = FALSE; A_BOOL asyncProc = FALSE; @@ -746,7 +746,7 @@ A_STATUS DevDsrHandler(void *context) #ifdef ATH_DEBUG_MODULE void DumpAR6KDevState(AR6K_DEVICE *pDev) { - A_STATUS status; + int status; AR6K_IRQ_ENABLE_REGISTERS regs; AR6K_IRQ_PROC_REGISTERS procRegs; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c index e3d270d1d626..d6b18eeaccf2 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c @@ -74,9 +74,9 @@ static void DevGMboxIRQActionAsyncHandler(void *Context, HTC_PACKET *pPacket) AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxIRQActionAsyncHandler \n")); } -static A_STATUS DevGMboxCounterEnableDisable(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, A_BOOL AsyncMode) +static int DevGMboxCounterEnableDisable(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, A_BOOL AsyncMode) { - A_STATUS status = A_OK; + int status = A_OK; AR6K_IRQ_ENABLE_REGISTERS regs; HTC_PACKET *pIOPacket = NULL; @@ -155,9 +155,9 @@ static A_STATUS DevGMboxCounterEnableDisable(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION } -A_STATUS DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, A_BOOL AsyncMode) +int DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, A_BOOL AsyncMode) { - A_STATUS status = A_OK; + int status = A_OK; HTC_PACKET *pIOPacket = NULL; A_UINT8 GMboxIntControl[4]; @@ -269,9 +269,9 @@ void DevCleanupGMbox(AR6K_DEVICE *pDev) } } -A_STATUS DevSetupGMbox(AR6K_DEVICE *pDev) +int DevSetupGMbox(AR6K_DEVICE *pDev) { - A_STATUS status = A_OK; + int status = A_OK; A_UINT8 muxControl[4]; do { @@ -322,9 +322,9 @@ A_STATUS DevSetupGMbox(AR6K_DEVICE *pDev) return status; } -A_STATUS DevCheckGMboxInterrupts(AR6K_DEVICE *pDev) +int DevCheckGMboxInterrupts(AR6K_DEVICE *pDev) { - A_STATUS status = A_OK; + int status = A_OK; A_UINT8 counter_int_status; int credits; A_UINT8 host_int_status2; @@ -396,11 +396,11 @@ A_STATUS DevCheckGMboxInterrupts(AR6K_DEVICE *pDev) } -A_STATUS DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 WriteLength) +int DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 WriteLength) { A_UINT32 paddedLength; A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE; - A_STATUS status; + int status; A_UINT32 address; /* adjust the length to be a multiple of block size if appropriate */ @@ -433,11 +433,11 @@ A_STATUS DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 WriteLen return status; } -A_STATUS DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 ReadLength) +int DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 ReadLength) { A_UINT32 paddedLength; - A_STATUS status; + int status; A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE; /* adjust the length to be a multiple of block size if appropriate */ @@ -539,9 +539,9 @@ static void DevGMboxReadCreditsAsyncHandler(void *Context, HTC_PACKET *pPacket) AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxReadCreditsAsyncHandler \n")); } -A_STATUS DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, A_BOOL AsyncMode, int *pCredits) +int DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, A_BOOL AsyncMode, int *pCredits) { - A_STATUS status = A_OK; + int status = A_OK; HTC_PACKET *pIOPacket = NULL; AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+DevGMboxReadCreditCounter (%s) \n", AsyncMode ? "ASYNC" : "SYNC")); @@ -602,9 +602,9 @@ A_STATUS DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, A_BOOL AsyncMode, int *pCr return status; } -A_STATUS DevGMboxReadCreditSize(AR6K_DEVICE *pDev, int *pCreditSize) +int DevGMboxReadCreditSize(AR6K_DEVICE *pDev, int *pCreditSize) { - A_STATUS status; + int status; A_UINT8 buffer[4]; status = HIFReadWrite(pDev->HIFDevice, @@ -634,10 +634,10 @@ void DevNotifyGMboxTargetFailure(AR6K_DEVICE *pDev) } } -A_STATUS DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, A_UINT8 *pLookAheadBuffer, int *pLookAheadBytes) +int DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, A_UINT8 *pLookAheadBuffer, int *pLookAheadBytes) { - A_STATUS status = A_OK; + int status = A_OK; AR6K_IRQ_PROC_REGISTERS procRegs; int maxCopy; @@ -676,9 +676,9 @@ A_STATUS DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, A_UINT8 *pLookAheadBuffer, return status; } -A_STATUS DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int Signal, int AckTimeoutMS) +int DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int Signal, int AckTimeoutMS) { - A_STATUS status = A_OK; + int status = A_OK; int i; A_UINT8 buffer[4]; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c index db6d30c113b0..6b61dc4c41ce 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c @@ -94,7 +94,7 @@ typedef struct { (p)->HCIConfig.pHCISendComplete((p)->HCIConfig.pContext, (pt)); \ } -static A_STATUS HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, A_BOOL Synchronous); +static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, A_BOOL Synchronous); static void HCIUartCleanup(GMBOX_PROTO_HCI_UART *pProtocol) { @@ -106,9 +106,9 @@ static void HCIUartCleanup(GMBOX_PROTO_HCI_UART *pProtocol) A_FREE(pProtocol); } -static A_STATUS InitTxCreditState(GMBOX_PROTO_HCI_UART *pProt) +static int InitTxCreditState(GMBOX_PROTO_HCI_UART *pProt) { - A_STATUS status; + int status; int credits; int creditPollCount = CREDIT_POLL_COUNT; A_BOOL gotCredits = FALSE; @@ -184,13 +184,13 @@ static A_STATUS InitTxCreditState(GMBOX_PROTO_HCI_UART *pProt) return status; } -static A_STATUS CreditsAvailableCallback(void *pContext, int Credits, A_BOOL CreditIRQEnabled) +static int CreditsAvailableCallback(void *pContext, int Credits, A_BOOL CreditIRQEnabled) { GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)pContext; A_BOOL enableCreditIrq = FALSE; A_BOOL disableCreditIrq = FALSE; A_BOOL doPendingSends = FALSE; - A_STATUS status = A_OK; + int status = A_OK; /** this callback is called under 2 conditions: * 1. The credit IRQ interrupt was enabled and signaled. @@ -269,14 +269,14 @@ static A_STATUS CreditsAvailableCallback(void *pContext, int Credits, A_BOOL Cre return status; } -static INLINE void NotifyTransportFailure(GMBOX_PROTO_HCI_UART *pProt, A_STATUS status) +static INLINE void NotifyTransportFailure(GMBOX_PROTO_HCI_UART *pProt, int status) { if (pProt->HCIConfig.TransportFailure != NULL) { pProt->HCIConfig.TransportFailure(pProt->HCIConfig.pContext, status); } } -static void FailureCallback(void *pContext, A_STATUS Status) +static void FailureCallback(void *pContext, int Status) { GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)pContext; @@ -299,10 +299,10 @@ static void StateDumpCallback(void *pContext) AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("==================================================\n")); } -static A_STATUS HCIUartMessagePending(void *pContext, A_UINT8 LookAheadBytes[], int ValidBytes) +static int HCIUartMessagePending(void *pContext, A_UINT8 LookAheadBytes[], int ValidBytes) { GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)pContext; - A_STATUS status = A_OK; + int status = A_OK; int totalRecvLength = 0; HCI_TRANSPORT_PACKET_TYPE pktType = HCI_PACKET_INVALID; A_BOOL recvRefillCalled = FALSE; @@ -542,9 +542,9 @@ static void HCISendPacketCompletion(void *Context, HTC_PACKET *pPacket) AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCISendPacketCompletion \n")); } -static A_STATUS SeekCreditsSynch(GMBOX_PROTO_HCI_UART *pProt) +static int SeekCreditsSynch(GMBOX_PROTO_HCI_UART *pProt) { - A_STATUS status = A_OK; + int status = A_OK; int credits; int retry = 100; @@ -574,9 +574,9 @@ static A_STATUS SeekCreditsSynch(GMBOX_PROTO_HCI_UART *pProt) return status; } -static A_STATUS HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, A_BOOL Synchronous) +static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, A_BOOL Synchronous) { - A_STATUS status = A_OK; + int status = A_OK; int transferLength; int creditsRequired, remainder; A_UINT8 hciUartType; @@ -841,9 +841,9 @@ static void FlushRecvBuffers(GMBOX_PROTO_HCI_UART *pProt) /*** protocol module install entry point ***/ -A_STATUS GMboxProtocolInstall(AR6K_DEVICE *pDev) +int GMboxProtocolInstall(AR6K_DEVICE *pDev) { - A_STATUS status = A_OK; + int status = A_OK; GMBOX_PROTO_HCI_UART *pProtocol = NULL; do { @@ -903,10 +903,10 @@ void GMboxProtocolUninstall(AR6K_DEVICE *pDev) } -static A_STATUS NotifyTransportReady(GMBOX_PROTO_HCI_UART *pProt) +static int NotifyTransportReady(GMBOX_PROTO_HCI_UART *pProt) { HCI_TRANSPORT_PROPERTIES props; - A_STATUS status = A_OK; + int status = A_OK; do { @@ -996,10 +996,10 @@ void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans) AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportAttach \n")); } -A_STATUS HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue) +int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue) { GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; - A_STATUS status = A_OK; + int status = A_OK; A_BOOL unblockRecv = FALSE; HTC_PACKET *pPacket; @@ -1064,7 +1064,7 @@ A_STATUS HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_Q return A_OK; } -A_STATUS HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, A_BOOL Synchronous) +int HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, A_BOOL Synchronous) { GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; @@ -1097,9 +1097,9 @@ void HCI_TransportStop(HCI_TRANSPORT_HANDLE HciTrans) AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportStop \n")); } -A_STATUS HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans) +int HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans) { - A_STATUS status; + int status; GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportStart \n")); @@ -1144,7 +1144,7 @@ A_STATUS HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans) return status; } -A_STATUS HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable) +int HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable) { GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; return DevGMboxIRQAction(pProt->pDev, @@ -1153,12 +1153,12 @@ A_STATUS HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, A_BO } -A_STATUS HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, +int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, int MaxPollMS) { GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; - A_STATUS status = A_OK; + int status = A_OK; A_UINT8 lookAhead[8]; int bytes; int totalRecvLength; @@ -1225,12 +1225,12 @@ A_STATUS HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, #define LSB_SCRATCH_IDX 4 #define MSB_SCRATCH_IDX 5 -A_STATUS HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud) +int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud) { GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; HIF_DEVICE *pHIFDevice = (HIF_DEVICE *)(pProt->pDev->HIFDevice); A_UINT32 scaledBaud, scratchAddr; - A_STATUS status = A_OK; + int status = A_OK; /* Divide the desired baud rate by 100 * Store the LSB in the local scratch register 4 and the MSB in the local @@ -1256,9 +1256,9 @@ A_STATUS HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud) return status; } -A_STATUS HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable) +int HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable) { - A_STATUS status; + int status; GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; if (Enable) { diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index 7df62a20d482..2ab5975d79ef 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -93,7 +93,7 @@ static void HTCCleanup(HTC_TARGET *target) HTC_HANDLE HTCCreate(void *hif_handle, HTC_INIT_INFO *pInfo) { HTC_TARGET *target = NULL; - A_STATUS status = A_OK; + int status = A_OK; int i; A_UINT32 ctrl_bufsz; A_UINT32 blocksizes[HTC_MAILBOX_NUM_MAX]; @@ -222,10 +222,10 @@ void *HTCGetHifDevice(HTC_HANDLE HTCHandle) /* wait for the target to arrive (sends HTC Ready message) * this operation is fully synchronous and the message is polled for */ -A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle) +int HTCWaitTarget(HTC_HANDLE HTCHandle) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - A_STATUS status; + int status; HTC_PACKET *pPacket = NULL; HTC_READY_EX_MSG *pRdyMsg; @@ -369,11 +369,11 @@ A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle) /* Start HTC, enable interrupts and let the target know host has finished setup */ -A_STATUS HTCStart(HTC_HANDLE HTCHandle) +int HTCStart(HTC_HANDLE HTCHandle) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); HTC_PACKET *pPacket; - A_STATUS status; + int status; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n")); diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h index bd6754beb221..46364cba333a 100644 --- a/drivers/staging/ath6kl/htc2/htc_internal.h +++ b/drivers/staging/ath6kl/htc2/htc_internal.h @@ -164,14 +164,14 @@ typedef struct _HTC_TARGET { /* internal HTC functions */ void HTCControlTxComplete(void *Context, HTC_PACKET *pPacket); void HTCControlRecv(void *Context, HTC_PACKET *pPacket); -A_STATUS HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket); +int HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket); HTC_PACKET *HTCAllocControlBuffer(HTC_TARGET *target, HTC_PACKET_QUEUE *pList); void HTCFreeControlBuffer(HTC_TARGET *target, HTC_PACKET *pPacket, HTC_PACKET_QUEUE *pList); -A_STATUS HTCIssueSend(HTC_TARGET *target, HTC_PACKET *pPacket); +int HTCIssueSend(HTC_TARGET *target, HTC_PACKET *pPacket); void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket); -A_STATUS HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int NumLookAheads, A_BOOL *pAsyncProc, int *pNumPktsFetched); +int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int NumLookAheads, A_BOOL *pAsyncProc, int *pNumPktsFetched); void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint); -A_STATUS HTCSendSetupComplete(HTC_TARGET *target); +int HTCSendSetupComplete(HTC_TARGET *target); void HTCFlushRecvBuffers(HTC_TARGET *target); void HTCFlushSendPkts(HTC_TARGET *target); diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c index 3503657fe7d2..189d5106c9bb 100644 --- a/drivers/staging/ath6kl/htc2/htc_recv.c +++ b/drivers/staging/ath6kl/htc2/htc_recv.c @@ -83,7 +83,7 @@ static void DoRecvCompletion(HTC_ENDPOINT *pEndpoint, } -static INLINE A_STATUS HTCProcessTrailer(HTC_TARGET *target, +static INLINE int HTCProcessTrailer(HTC_TARGET *target, A_UINT8 *pBuffer, int Length, A_UINT32 *pNextLookAheads, @@ -95,7 +95,7 @@ static INLINE A_STATUS HTCProcessTrailer(HTC_TARGET *target, HTC_LOOKAHEAD_REPORT *pLookAhead; A_UINT8 *pOrigBuffer; int origLength; - A_STATUS status; + int status; AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCProcessTrailer (length:%d) \n", Length)); @@ -226,14 +226,14 @@ static INLINE A_STATUS HTCProcessTrailer(HTC_TARGET *target, /* process a received message (i.e. strip off header, process any trailer data) * note : locks must be released when this function is called */ -static A_STATUS HTCProcessRecvHeader(HTC_TARGET *target, +static int HTCProcessRecvHeader(HTC_TARGET *target, HTC_PACKET *pPacket, A_UINT32 *pNextLookAheads, int *pNumLookAheads) { A_UINT8 temp; A_UINT8 *pBuf; - A_STATUS status = A_OK; + int status = A_OK; A_UINT16 payloadLen; A_UINT32 lookAhead; @@ -392,7 +392,7 @@ static INLINE void HTCAsyncRecvCheckMorePackets(HTC_TARGET *target, { /* was there a lookahead for the next packet? */ if (NumLookAheads > 0) { - A_STATUS nextStatus; + int nextStatus; int fetched = 0; AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("HTCAsyncRecvCheckMorePackets - num lookaheads were non-zero : %d \n", @@ -521,7 +521,7 @@ void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket) HTC_ENDPOINT *pEndpoint; A_UINT32 nextLookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; int numLookAheads = 0; - A_STATUS status; + int status; A_BOOL checkMorePkts = TRUE; AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCRecvCompleteHandler (pkt:0x%lX, status:%d, ep:%d) \n", @@ -587,9 +587,9 @@ void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket) /* synchronously wait for a control message from the target, * This function is used at initialization time ONLY. At init messages * on ENDPOINT 0 are expected. */ -A_STATUS HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket) +int HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket) { - A_STATUS status; + int status; A_UINT32 lookAhead; HTC_PACKET *pPacket = NULL; HTC_FRAME_HDR *pHdr; @@ -686,13 +686,13 @@ A_STATUS HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPack return status; } -static A_STATUS AllocAndPrepareRxPackets(HTC_TARGET *target, +static int AllocAndPrepareRxPackets(HTC_TARGET *target, A_UINT32 LookAheads[], int Messages, HTC_ENDPOINT *pEndpoint, HTC_PACKET_QUEUE *pQueue) { - A_STATUS status = A_OK; + int status = A_OK; HTC_PACKET *pPacket; HTC_FRAME_HDR *pHdr; int i,j; @@ -887,7 +887,7 @@ static void HTCAsyncRecvScatterCompletion(HIF_SCATTER_REQ *pScatterReq) A_UINT32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; int numLookAheads = 0; HTC_TARGET *target = (HTC_TARGET *)pScatterReq->Context; - A_STATUS status; + int status; A_BOOL partialBundle = FALSE; HTC_PACKET_QUEUE localRecvQueue; A_BOOL procError = FALSE; @@ -984,13 +984,13 @@ static void HTCAsyncRecvScatterCompletion(HIF_SCATTER_REQ *pScatterReq) AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCAsyncRecvScatterCompletion \n")); } -static A_STATUS HTCIssueRecvPacketBundle(HTC_TARGET *target, +static int HTCIssueRecvPacketBundle(HTC_TARGET *target, HTC_PACKET_QUEUE *pRecvPktQueue, HTC_PACKET_QUEUE *pSyncCompletionQueue, int *pNumPacketsFetched, A_BOOL PartialBundle) { - A_STATUS status = A_OK; + int status = A_OK; HIF_SCATTER_REQ *pScatterReq; int i, totalLength; int pktsToScatter; @@ -1117,10 +1117,10 @@ static INLINE void CheckRecvWaterMark(HTC_ENDPOINT *pEndpoint) } /* callback when device layer or lookahead report parsing detects a pending message */ -A_STATUS HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int NumLookAheads, A_BOOL *pAsyncProc, int *pNumPktsFetched) +int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int NumLookAheads, A_BOOL *pAsyncProc, int *pNumPktsFetched) { HTC_TARGET *target = (HTC_TARGET *)Context; - A_STATUS status = A_OK; + int status = A_OK; HTC_PACKET *pPacket; HTC_ENDPOINT *pEndpoint; A_BOOL asyncProc = FALSE; @@ -1385,12 +1385,12 @@ A_STATUS HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], i return status; } -A_STATUS HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) +int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); HTC_ENDPOINT *pEndpoint; A_BOOL unblockRecv = FALSE; - A_STATUS status = A_OK; + int status = A_OK; HTC_PACKET *pFirstPacket; pFirstPacket = HTC_GET_PKT_AT_HEAD(pPktQueue); @@ -1455,7 +1455,7 @@ A_STATUS HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQu } /* Makes a buffer available to the HTC module */ -A_STATUS HTCAddReceivePkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket) +int HTCAddReceivePkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket) { HTC_PACKET_QUEUE queue; INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket); @@ -1563,11 +1563,11 @@ int HTCGetNumRecvBuffers(HTC_HANDLE HTCHandle, return HTC_PACKET_QUEUE_DEPTH(&(target->EndPoint[Endpoint].RxBuffers)); } -A_STATUS HTCWaitForPendingRecv(HTC_HANDLE HTCHandle, +int HTCWaitForPendingRecv(HTC_HANDLE HTCHandle, A_UINT32 TimeoutInMs, A_BOOL *pbIsRecvPending) { - A_STATUS status = A_OK; + int status = A_OK; HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); status = DevWaitForPendingRecv(&target->Device, diff --git a/drivers/staging/ath6kl/htc2/htc_send.c b/drivers/staging/ath6kl/htc2/htc_send.c index bc7ee7848263..797400802e2a 100644 --- a/drivers/staging/ath6kl/htc2/htc_send.c +++ b/drivers/staging/ath6kl/htc2/htc_send.c @@ -113,9 +113,9 @@ static void HTCSendPktCompletionHandler(void *Context, HTC_PACKET *pPacket) DO_EP_TX_COMPLETION(pEndpoint,&container); } -A_STATUS HTCIssueSend(HTC_TARGET *target, HTC_PACKET *pPacket) +int HTCIssueSend(HTC_TARGET *target, HTC_PACKET *pPacket) { - A_STATUS status; + int status; A_BOOL sync = FALSE; if (pPacket->Completion == NULL) { @@ -270,7 +270,7 @@ static void HTCAsyncSendScatterCompletion(HIF_SCATTER_REQ *pScatterReq) HTC_PACKET *pPacket; HTC_ENDPOINT *pEndpoint = (HTC_ENDPOINT *)pScatterReq->Context; HTC_TARGET *target = (HTC_TARGET *)pEndpoint->target; - A_STATUS status = A_OK; + int status = A_OK; HTC_PACKET_QUEUE sendCompletes; INIT_HTC_PACKET_QUEUE(&sendCompletes); @@ -668,7 +668,7 @@ static HTC_SEND_QUEUE_RESULT HTCTrySend(HTC_TARGET *target, return HTC_SEND_QUEUE_OK; } -A_STATUS HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) +int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); HTC_ENDPOINT *pEndpoint; @@ -709,7 +709,7 @@ A_STATUS HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) } /* HTC API - HTCSendPkt */ -A_STATUS HTCSendPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket) +int HTCSendPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket) { HTC_PACKET_QUEUE queue; diff --git a/drivers/staging/ath6kl/htc2/htc_services.c b/drivers/staging/ath6kl/htc2/htc_services.c index 64fddc0ee376..a78660264977 100644 --- a/drivers/staging/ath6kl/htc2/htc_services.c +++ b/drivers/staging/ath6kl/htc2/htc_services.c @@ -57,10 +57,10 @@ void HTCControlRecv(void *Context, HTC_PACKET *pPacket) HTC_RECYCLE_RX_PKT((HTC_TARGET*)Context,pPacket,&((HTC_TARGET*)Context)->EndPoint[0]); } -A_STATUS HTCSendSetupComplete(HTC_TARGET *target) +int HTCSendSetupComplete(HTC_TARGET *target) { HTC_PACKET *pSendPacket = NULL; - A_STATUS status; + int status; do { /* allocate a packet to send to the target */ @@ -121,12 +121,12 @@ A_STATUS HTCSendSetupComplete(HTC_TARGET *target) } -A_STATUS HTCConnectService(HTC_HANDLE HTCHandle, +int HTCConnectService(HTC_HANDLE HTCHandle, HTC_SERVICE_CONNECT_REQ *pConnectReq, HTC_SERVICE_CONNECT_RESP *pConnectResp) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - A_STATUS status = A_OK; + int status = A_OK; HTC_PACKET *pRecvPacket = NULL; HTC_PACKET *pSendPacket = NULL; HTC_CONNECT_SERVICE_RESPONSE_MSG *pResponseMsg; diff --git a/drivers/staging/ath6kl/include/a_debug.h b/drivers/staging/ath6kl/include/a_debug.h index 5a1b01fbb93c..007010cfad99 100644 --- a/drivers/staging/ath6kl/include/a_debug.h +++ b/drivers/staging/ath6kl/include/a_debug.h @@ -181,8 +181,8 @@ void a_register_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo); #endif -A_STATUS a_get_module_mask(A_CHAR *module_name, A_UINT32 *pMask); -A_STATUS a_set_module_mask(A_CHAR *module_name, A_UINT32 Mask); +int a_get_module_mask(A_CHAR *module_name, A_UINT32 *pMask); +int a_set_module_mask(A_CHAR *module_name, A_UINT32 Mask); void a_dump_module_debug_info_by_name(A_CHAR *module_name); void a_module_debug_support_init(void); void a_module_debug_support_cleanup(void); diff --git a/drivers/staging/ath6kl/include/ar3kconfig.h b/drivers/staging/ath6kl/include/ar3kconfig.h index a10788cee461..24f5b2aa96c8 100644 --- a/drivers/staging/ath6kl/include/ar3kconfig.h +++ b/drivers/staging/ath6kl/include/ar3kconfig.h @@ -54,9 +54,9 @@ typedef struct { A_UINT8 bdaddr[6]; /* Bluetooth device address */ } AR3K_CONFIG_INFO; -A_STATUS AR3KConfigure(AR3K_CONFIG_INFO *pConfigInfo); +int AR3KConfigure(AR3K_CONFIG_INFO *pConfigInfo); -A_STATUS AR3KConfigureExit(void *config); +int AR3KConfigureExit(void *config); #ifdef __cplusplus } diff --git a/drivers/staging/ath6kl/include/ar6000_diag.h b/drivers/staging/ath6kl/include/ar6000_diag.h index b53512e23d32..1470d2070984 100644 --- a/drivers/staging/ath6kl/include/ar6000_diag.h +++ b/drivers/staging/ath6kl/include/ar6000_diag.h @@ -25,21 +25,21 @@ #define AR6000_DIAG_H_ -A_STATUS +int ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); -A_STATUS +int ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); -A_STATUS +int ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, A_UCHAR *data, A_UINT32 length); -A_STATUS +int ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, A_UCHAR *data, A_UINT32 length); -A_STATUS +int ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, A_UINT32 *regval); void diff --git a/drivers/staging/ath6kl/include/bmi.h b/drivers/staging/ath6kl/include/bmi.h index 27aa98df9c0b..9b45dc312319 100644 --- a/drivers/staging/ath6kl/include/bmi.h +++ b/drivers/staging/ath6kl/include/bmi.h @@ -43,44 +43,44 @@ BMIInit(void); void BMICleanup(void); -A_STATUS +int BMIDone(HIF_DEVICE *device); -A_STATUS +int BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info); -A_STATUS +int BMIReadMemory(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length); -A_STATUS +int BMIWriteMemory(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length); -A_STATUS +int BMIExecute(HIF_DEVICE *device, A_UINT32 address, A_UINT32 *param); -A_STATUS +int BMISetAppStart(HIF_DEVICE *device, A_UINT32 address); -A_STATUS +int BMIReadSOCRegister(HIF_DEVICE *device, A_UINT32 address, A_UINT32 *param); -A_STATUS +int BMIWriteSOCRegister(HIF_DEVICE *device, A_UINT32 address, A_UINT32 param); -A_STATUS +int BMIrompatchInstall(HIF_DEVICE *device, A_UINT32 ROM_addr, A_UINT32 RAM_addr, @@ -88,41 +88,41 @@ BMIrompatchInstall(HIF_DEVICE *device, A_UINT32 do_activate, A_UINT32 *patch_id); -A_STATUS +int BMIrompatchUninstall(HIF_DEVICE *device, A_UINT32 rompatch_id); -A_STATUS +int BMIrompatchActivate(HIF_DEVICE *device, A_UINT32 rompatch_count, A_UINT32 *rompatch_list); -A_STATUS +int BMIrompatchDeactivate(HIF_DEVICE *device, A_UINT32 rompatch_count, A_UINT32 *rompatch_list); -A_STATUS +int BMILZStreamStart(HIF_DEVICE *device, A_UINT32 address); -A_STATUS +int BMILZData(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length); -A_STATUS +int BMIFastDownload(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length); -A_STATUS +int BMIRawWrite(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length); -A_STATUS +int BMIRawRead(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length, diff --git a/drivers/staging/ath6kl/include/common/athdefs.h b/drivers/staging/ath6kl/include/common/athdefs.h index b59bfd3af0a5..2cd072012388 100644 --- a/drivers/staging/ath6kl/include/common/athdefs.h +++ b/drivers/staging/ath6kl/include/common/athdefs.h @@ -31,44 +31,47 @@ /* * Generic error codes that can be used by hw, sta, ap, sim, dk - * and any other environments. Since these are enums, feel free to - * add any more codes that you need. + * and any other environments. + * Feel free to add any more codes that you need. */ -typedef enum { - A_ERROR = -1, /* Generic error return */ - A_OK = 0, /* success */ - /* Following values start at 1 */ - A_DEVICE_NOT_FOUND, /* not able to find PCI device */ - A_NO_MEMORY, /* not able to allocate memory, not available */ - A_MEMORY_NOT_AVAIL, /* memory region is not free for mapping */ - A_NO_FREE_DESC, /* no free descriptors available */ - A_BAD_ADDRESS, /* address does not match descriptor */ - A_WIN_DRIVER_ERROR, /* used in NT_HW version, if problem at init */ - A_REGS_NOT_MAPPED, /* registers not correctly mapped */ - A_EPERM, /* Not superuser */ - A_EACCES, /* Access denied */ - A_ENOENT, /* No such entry, search failed, etc. */ - A_EEXIST, /* The object already exists (can't create) */ - A_EFAULT, /* Bad address fault */ - A_EBUSY, /* Object is busy */ - A_EINVAL, /* Invalid parameter */ - A_EMSGSIZE, /* Inappropriate message buffer length */ - A_ECANCELED, /* Operation canceled */ - A_ENOTSUP, /* Operation not supported */ - A_ECOMM, /* Communication error on send */ - A_EPROTO, /* Protocol error */ - A_ENODEV, /* No such device */ - A_EDEVNOTUP, /* device is not UP */ - A_NO_RESOURCE, /* No resources for requested operation */ - A_HARDWARE, /* Hardware failure */ - A_PENDING, /* Asynchronous routine; will send up results la -ter (typically in callback) */ - A_EBADCHANNEL, /* The channel cannot be used */ - A_DECRYPT_ERROR, /* Decryption error */ - A_PHY_ERROR, /* RX PHY error */ - A_CONSUMED /* Object was consumed */ -} A_STATUS; +#define A_ERROR (-1) /* Generic error return */ +#define A_OK 0 /* success */ +#define A_DEVICE_NOT_FOUND 1 /* not able to find PCI device */ +#define A_NO_MEMORY 2 /* not able to allocate memory, + * not avail#defineable */ +#define A_MEMORY_NOT_AVAIL 3 /* memory region is not free for + * mapping */ +#define A_NO_FREE_DESC 4 /* no free descriptors available */ +#define A_BAD_ADDRESS 5 /* address does not match descriptor */ +#define A_WIN_DRIVER_ERROR 6 /* used in NT_HW version, + * if problem at init */ +#define A_REGS_NOT_MAPPED 7 /* registers not correctly mapped */ +#define A_EPERM 8 /* Not superuser */ +#define A_EACCES 0 /* Access denied */ +#define A_ENOENT 10 /* No such entry, search failed, etc. */ +#define A_EEXIST 11 /* The object already exists + * (can't create) */ +#define A_EFAULT 12 /* Bad address fault */ +#define A_EBUSY 13 /* Object is busy */ +#define A_EINVAL 14 /* Invalid parameter */ +#define A_EMSGSIZE 15 /* Bad message buffer length */ +#define A_ECANCELED 16 /* Operation canceled */ +#define A_ENOTSUP 17 /* Operation not supported */ +#define A_ECOMM 18 /* Communication error on send */ +#define A_EPROTO 19 /* Protocol error */ +#define A_ENODEV 20 /* No such device */ +#define A_EDEVNOTUP 21 /* device is not UP */ +#define A_NO_RESOURCE 22 /* No resources for + * requested operation */ +#define A_HARDWARE 23 /* Hardware failure */ +#define A_PENDING 24 /* Asynchronous routine; will send up + * results later + * (typically in callback) */ +#define A_EBADCHANNEL 25 /* The channel cannot be used */ +#define A_DECRYPT_ERROR 26 /* Decryption error */ +#define A_PHY_ERROR 27 /* RX PHY error */ +#define A_CONSUMED 28 /* Object was consumed */ #define A_SUCCESS(x) (x == A_OK) #define A_FAILED(x) (!A_SUCCESS(x)) diff --git a/drivers/staging/ath6kl/include/common_drv.h b/drivers/staging/ath6kl/include/common_drv.h index 8ebb93d5f3c2..c6f0b2dc550a 100644 --- a/drivers/staging/ath6kl/include/common_drv.h +++ b/drivers/staging/ath6kl/include/common_drv.h @@ -64,28 +64,28 @@ extern "C" { #endif /* OS-independent APIs */ -A_STATUS ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, COMMON_CREDIT_STATE_INFO *pCredInfo); +int ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, COMMON_CREDIT_STATE_INFO *pCredInfo); -A_STATUS ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); +int ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); -A_STATUS ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); +int ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); -A_STATUS ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, A_UCHAR *data, A_UINT32 length); +int ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, A_UCHAR *data, A_UINT32 length); -A_STATUS ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_BOOL waitForCompletion, A_BOOL coldReset); +int ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_BOOL waitForCompletion, A_BOOL coldReset); void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType); -A_STATUS ar6000_set_htc_params(HIF_DEVICE *hifDevice, +int ar6000_set_htc_params(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_UINT32 MboxIsrYieldValue, A_UINT8 HtcControlBuffers); -A_STATUS ar6000_prepare_target(HIF_DEVICE *hifDevice, +int ar6000_prepare_target(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_UINT32 TargetVersion); -A_STATUS ar6000_set_hci_bridge_flags(HIF_DEVICE *hifDevice, +int ar6000_set_hci_bridge_flags(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_UINT32 Flags); @@ -93,13 +93,13 @@ void ar6000_copy_cust_data_from_target(HIF_DEVICE *hifDevice, A_UINT32 TargetTyp A_UINT8 *ar6000_get_cust_data_buffer(A_UINT32 TargetType); -A_STATUS ar6000_setBTState(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize); +int ar6000_setBTState(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize); -A_STATUS ar6000_setDevicePowerState(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize); +int ar6000_setDevicePowerState(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize); -A_STATUS ar6000_setWowMode(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize); +int ar6000_setWowMode(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize); -A_STATUS ar6000_setHostMode(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize); +int ar6000_setHostMode(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize); #ifdef __cplusplus } diff --git a/drivers/staging/ath6kl/include/dset_api.h b/drivers/staging/ath6kl/include/dset_api.h index 0cc121fd25a0..c2014f2b8649 100644 --- a/drivers/staging/ath6kl/include/dset_api.h +++ b/drivers/staging/ath6kl/include/dset_api.h @@ -39,7 +39,7 @@ extern "C" { #endif /* Called to send a DataSet Open Reply back to the Target. */ -A_STATUS wmi_dset_open_reply(struct wmi_t *wmip, +int wmi_dset_open_reply(struct wmi_t *wmip, A_UINT32 status, A_UINT32 access_cookie, A_UINT32 size, @@ -49,7 +49,7 @@ A_STATUS wmi_dset_open_reply(struct wmi_t *wmip, A_UINT32 targ_reply_arg); /* Called to send a DataSet Data Reply back to the Target. */ -A_STATUS wmi_dset_data_reply(struct wmi_t *wmip, +int wmi_dset_data_reply(struct wmi_t *wmip, A_UINT32 status, A_UINT8 *host_buf, A_UINT32 length, diff --git a/drivers/staging/ath6kl/include/gpio_api.h b/drivers/staging/ath6kl/include/gpio_api.h index 96a150383358..81c228dd16ab 100644 --- a/drivers/staging/ath6kl/include/gpio_api.h +++ b/drivers/staging/ath6kl/include/gpio_api.h @@ -28,7 +28,7 @@ /* * Send a command to the Target in order to change output on GPIO pins. */ -A_STATUS wmi_gpio_output_set(struct wmi_t *wmip, +int wmi_gpio_output_set(struct wmi_t *wmip, A_UINT32 set_mask, A_UINT32 clear_mask, A_UINT32 enable_mask, @@ -37,23 +37,23 @@ A_STATUS wmi_gpio_output_set(struct wmi_t *wmip, /* * Send a command to the Target requesting input state of GPIO pins. */ -A_STATUS wmi_gpio_input_get(struct wmi_t *wmip); +int wmi_gpio_input_get(struct wmi_t *wmip); /* * Send a command to the Target to change the value of a GPIO register. */ -A_STATUS wmi_gpio_register_set(struct wmi_t *wmip, +int wmi_gpio_register_set(struct wmi_t *wmip, A_UINT32 gpioreg_id, A_UINT32 value); /* * Send a command to the Target to fetch the value of a GPIO register. */ -A_STATUS wmi_gpio_register_get(struct wmi_t *wmip, A_UINT32 gpioreg_id); +int wmi_gpio_register_get(struct wmi_t *wmip, A_UINT32 gpioreg_id); /* * Send a command to the Target, acknowledging some GPIO interrupts. */ -A_STATUS wmi_gpio_intr_ack(struct wmi_t *wmip, A_UINT32 ack_mask); +int wmi_gpio_intr_ack(struct wmi_t *wmip, A_UINT32 ack_mask); #endif /* _GPIO_API_H_ */ diff --git a/drivers/staging/ath6kl/include/hci_transport_api.h b/drivers/staging/ath6kl/include/hci_transport_api.h index b5157ea5d9e9..b611ab1cef4c 100644 --- a/drivers/staging/ath6kl/include/hci_transport_api.h +++ b/drivers/staging/ath6kl/include/hci_transport_api.h @@ -90,8 +90,8 @@ typedef struct _HCI_TRANSPORT_CONFIG_INFO { int EventRecvBufferWaterMark; /* low watermark to trigger recv refill */ int MaxSendQueueDepth; /* max number of packets in the single send queue */ void *pContext; /* context for all callbacks */ - void (*TransportFailure)(void *pContext, A_STATUS Status); /* transport failure callback */ - A_STATUS (*TransportReady)(HCI_TRANSPORT_HANDLE, HCI_TRANSPORT_PROPERTIES *,void *pContext); /* transport is ready */ + void (*TransportFailure)(void *pContext, int Status); /* transport failure callback */ + int (*TransportReady)(HCI_TRANSPORT_HANDLE, HCI_TRANSPORT_PROPERTIES *,void *pContext); /* transport is ready */ void (*TransportRemoved)(void *pContext); /* transport was removed */ /* packet processing callbacks */ HCI_TRANSPORT_SEND_PKT_COMPLETE pHCISendComplete; @@ -141,7 +141,7 @@ void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans); @example: @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -A_STATUS HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue); +int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Send an HCI packet packet @@ -166,7 +166,7 @@ A_STATUS HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKE @example: @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -A_STATUS HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, A_BOOL Synchronous); +int HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, A_BOOL Synchronous); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -193,7 +193,7 @@ void HCI_TransportStop(HCI_TRANSPORT_HANDLE HciTrans); @example: @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -A_STATUS HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans); +int HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Enable or Disable Asynchronous Recv @@ -206,7 +206,7 @@ A_STATUS HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans); @example: @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -A_STATUS HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable); +int HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Receive an event packet from the HCI transport synchronously using polling @@ -222,7 +222,7 @@ A_STATUS HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, A @example: @see also: HCI_TransportEnableDisableAsyncRecv +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -A_STATUS HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, +int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, int MaxPollMS); @@ -237,7 +237,7 @@ A_STATUS HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, @example: @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -A_STATUS HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud); +int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Enable/Disable HCI Transport Power Management @@ -250,7 +250,7 @@ A_STATUS HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Bau @example: @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -A_STATUS HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable); +int HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable); #ifdef __cplusplus } diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h index 2a082678512c..331d98515678 100644 --- a/drivers/staging/ath6kl/include/hif.h +++ b/drivers/staging/ath6kl/include/hif.h @@ -293,7 +293,7 @@ typedef struct _HIF_SCATTER_REQ { A_UINT32 TotalLength; /* total length of entire transfer */ A_UINT32 CallerFlags; /* caller specific flags can be stored here */ HIF_SCATTER_COMP_CB CompletionRoutine; /* completion routine set by caller */ - A_STATUS CompletionStatus; /* status of completion */ + int CompletionStatus; /* status of completion */ void *Context; /* caller context for this request */ int ValidScatterEntries; /* number of valid entries set by caller */ HIF_SCATTER_METHOD ScatterMethod; /* scatter method handled by HIF */ @@ -304,7 +304,7 @@ typedef struct _HIF_SCATTER_REQ { typedef HIF_SCATTER_REQ * ( *HIF_ALLOCATE_SCATTER_REQUEST)(HIF_DEVICE *device); typedef void ( *HIF_FREE_SCATTER_REQUEST)(HIF_DEVICE *device, HIF_SCATTER_REQ *request); -typedef A_STATUS ( *HIF_READWRITE_SCATTER)(HIF_DEVICE *device, HIF_SCATTER_REQ *request); +typedef int ( *HIF_READWRITE_SCATTER)(HIF_DEVICE *device, HIF_SCATTER_REQ *request); typedef struct _HIF_DEVICE_SCATTER_SUPPORT_INFO { /* information returned from HIF layer */ @@ -324,19 +324,19 @@ typedef struct { struct htc_callbacks { void *context; /* context to pass to the dsrhandler note : rwCompletionHandler is provided the context passed to HIFReadWrite */ - A_STATUS (* rwCompletionHandler)(void *rwContext, A_STATUS status); - A_STATUS (* dsrHandler)(void *context); + int (* rwCompletionHandler)(void *rwContext, int status); + int (* dsrHandler)(void *context); }; typedef struct osdrv_callbacks { void *context; /* context to pass for all callbacks except deviceRemovedHandler the deviceRemovedHandler is only called if the device is claimed */ - A_STATUS (* deviceInsertedHandler)(void *context, void *hif_handle); - A_STATUS (* deviceRemovedHandler)(void *claimedContext, void *hif_handle); - A_STATUS (* deviceSuspendHandler)(void *context); - A_STATUS (* deviceResumeHandler)(void *context); - A_STATUS (* deviceWakeupHandler)(void *context); - A_STATUS (* devicePowerChangeHandler)(void *context, HIF_DEVICE_POWER_CHANGE_TYPE config); + int (* deviceInsertedHandler)(void *context, void *hif_handle); + int (* deviceRemovedHandler)(void *claimedContext, void *hif_handle); + int (* deviceSuspendHandler)(void *context); + int (* deviceResumeHandler)(void *context); + int (* deviceWakeupHandler)(void *context); + int (* devicePowerChangeHandler)(void *context, HIF_DEVICE_POWER_CHANGE_TYPE config); } OSDRV_CALLBACKS; #define HIF_OTHER_EVENTS (1 << 0) /* other interrupts (non-Recv) are pending, host @@ -355,14 +355,14 @@ typedef struct _HIF_PENDING_EVENTS_INFO { /* function to get pending events , some HIF modules use special mechanisms * to detect packet available and other interrupts */ -typedef A_STATUS ( *HIF_PENDING_EVENTS_FUNC)(HIF_DEVICE *device, +typedef int ( *HIF_PENDING_EVENTS_FUNC)(HIF_DEVICE *device, HIF_PENDING_EVENTS_INFO *pEvents, void *AsyncContext); #define HIF_MASK_RECV TRUE #define HIF_UNMASK_RECV FALSE /* function to mask recv events */ -typedef A_STATUS ( *HIF_MASK_UNMASK_RECV_EVENT)(HIF_DEVICE *device, +typedef int ( *HIF_MASK_UNMASK_RECV_EVENT)(HIF_DEVICE *device, A_BOOL Mask, void *AsyncContext); @@ -372,7 +372,7 @@ typedef A_STATUS ( *HIF_MASK_UNMASK_RECV_EVENT)(HIF_DEVICE *device, * and to set OS driver callbacks (i.e. insertion/removal) to the HIF layer * */ -A_STATUS HIFInit(OSDRV_CALLBACKS *callbacks); +int HIFInit(OSDRV_CALLBACKS *callbacks); /* This API claims the HIF device and provides a context for handling removal. * The device removal callback is only called when the OSDRV layer claims @@ -382,7 +382,7 @@ void HIFClaimDevice(HIF_DEVICE *device, void *claimedContext); void HIFReleaseDevice(HIF_DEVICE *device); /* This API allows the HTC layer to attach to the HIF device */ -A_STATUS HIFAttachHTC(HIF_DEVICE *device, HTC_CALLBACKS *callbacks); +int HIFAttachHTC(HIF_DEVICE *device, HTC_CALLBACKS *callbacks); /* This API detaches the HTC layer from the HIF device */ void HIFDetachHTC(HIF_DEVICE *device); @@ -398,7 +398,7 @@ void HIFDetachHTC(HIF_DEVICE *device); * length - Amount of data to be transmitted or received. * request - Characterizes the attributes of the command. */ -A_STATUS +int HIFReadWrite(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, @@ -441,7 +441,7 @@ int HIFIRQEventNotify(void); int HIFRWCompleteEventNotify(void); #endif -A_STATUS +int HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, void *config, A_UINT32 configLen); @@ -449,7 +449,7 @@ HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, * This API wait for the remaining MBOX messages to be drained * This should be moved to HTC AR6K layer */ -A_STATUS hifWaitForPendingRecv(HIF_DEVICE *device); +int hifWaitForPendingRecv(HIF_DEVICE *device); #ifdef __cplusplus } diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h index b007051e0551..94040bff7896 100644 --- a/drivers/staging/ath6kl/include/htc_api.h +++ b/drivers/staging/ath6kl/include/htc_api.h @@ -45,7 +45,7 @@ typedef A_UINT16 HTC_SERVICE_ID; typedef struct _HTC_INIT_INFO { void *pContext; /* context for target failure notification */ - void (*TargetFailure)(void *Instance, A_STATUS Status); + void (*TargetFailure)(void *Instance, int Status); } HTC_INIT_INFO; /* per service connection send completion */ @@ -319,7 +319,7 @@ void HTCSetCreditDistribution(HTC_HANDLE HTCHandle, @example: @see also: HTCConnectService +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle); +int HTCWaitTarget(HTC_HANDLE HTCHandle); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Start target service communications @function name: HTCStart @@ -334,7 +334,7 @@ A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle); @example: @see also: HTCConnectService +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -A_STATUS HTCStart(HTC_HANDLE HTCHandle); +int HTCStart(HTC_HANDLE HTCHandle); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Add receive packet to HTC @function name: HTCAddReceivePkt @@ -348,7 +348,7 @@ A_STATUS HTCStart(HTC_HANDLE HTCHandle); @example: @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -A_STATUS HTCAddReceivePkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket); +int HTCAddReceivePkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Connect to an HTC service @function name: HTCConnectService @@ -361,7 +361,7 @@ A_STATUS HTCAddReceivePkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket); @example: @see also: HTCStart +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -A_STATUS HTCConnectService(HTC_HANDLE HTCHandle, +int HTCConnectService(HTC_HANDLE HTCHandle, HTC_SERVICE_CONNECT_REQ *pReq, HTC_SERVICE_CONNECT_RESP *pResp); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -377,7 +377,7 @@ A_STATUS HTCConnectService(HTC_HANDLE HTCHandle, @example: @see also: HTCFlushEndpoint +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -A_STATUS HTCSendPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket); +int HTCSendPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Stop HTC service communications @function name: HTCStop @@ -511,7 +511,7 @@ void HTCUnblockRecv(HTC_HANDLE HTCHandle); @example: @see also: HTCFlushEndpoint +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -A_STATUS HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue); +int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Add multiple receive packets to HTC @@ -530,7 +530,7 @@ A_STATUS HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueu @example: @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -A_STATUS HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue); +int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Check if an endpoint is marked active @@ -564,7 +564,7 @@ int HTCGetNumRecvBuffers(HTC_HANDLE HTCHandle, /* internally used functions for testing... */ void HTCEnableRecv(HTC_HANDLE HTCHandle); void HTCDisableRecv(HTC_HANDLE HTCHandle); -A_STATUS HTCWaitForPendingRecv(HTC_HANDLE HTCHandle, +int HTCWaitForPendingRecv(HTC_HANDLE HTCHandle, A_UINT32 TimeoutInMs, A_BOOL *pbIsRecvPending); diff --git a/drivers/staging/ath6kl/include/htc_packet.h b/drivers/staging/ath6kl/include/htc_packet.h index 15175cff2f28..243268c9d515 100644 --- a/drivers/staging/ath6kl/include/htc_packet.h +++ b/drivers/staging/ath6kl/include/htc_packet.h @@ -89,7 +89,7 @@ typedef struct _HTC_PACKET { A_UINT32 BufferLength; /* length of buffer */ A_UINT32 ActualLength; /* actual length of payload */ HTC_ENDPOINT_ID Endpoint; /* endpoint that this packet was sent/recv'd from */ - A_STATUS Status; /* completion status */ + int Status; /* completion status */ union { HTC_TX_PACKET_INFO AsTx; /* Tx Packet specific info */ HTC_RX_PACKET_INFO AsRx; /* Rx Packet specific info */ diff --git a/drivers/staging/ath6kl/include/wlan_api.h b/drivers/staging/ath6kl/include/wlan_api.h index f55a6454a6b4..041df74e2db7 100644 --- a/drivers/staging/ath6kl/include/wlan_api.h +++ b/drivers/staging/ath6kl/include/wlan_api.h @@ -96,7 +96,7 @@ void wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt); void wlan_node_table_reset(struct ieee80211_node_table *nt); void wlan_node_table_cleanup(struct ieee80211_node_table *nt); -A_STATUS wlan_parse_beacon(A_UINT8 *buf, int framelen, +int wlan_parse_beacon(A_UINT8 *buf, int framelen, struct ieee80211_common_ie *cie); A_UINT16 wlan_ieee2freq(int chan); diff --git a/drivers/staging/ath6kl/include/wmi_api.h b/drivers/staging/ath6kl/include/wmi_api.h index 4a9154316a35..5207a198ed1e 100644 --- a/drivers/staging/ath6kl/include/wmi_api.h +++ b/drivers/staging/ath6kl/include/wmi_api.h @@ -70,21 +70,21 @@ void wmi_shutdown(struct wmi_t *wmip); HTC_ENDPOINT_ID wmi_get_control_ep(struct wmi_t * wmip); void wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid); A_UINT16 wmi_get_mapped_qos_queue(struct wmi_t *, A_UINT8); -A_STATUS wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf); -A_STATUS wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType, A_BOOL bMoreData, WMI_DATA_HDR_DATA_TYPE data_type,A_UINT8 metaVersion, void *pTxMetaS); -A_STATUS wmi_dot3_2_dix(void *osbuf); +int wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf); +int wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType, A_BOOL bMoreData, WMI_DATA_HDR_DATA_TYPE data_type,A_UINT8 metaVersion, void *pTxMetaS); +int wmi_dot3_2_dix(void *osbuf); -A_STATUS wmi_dot11_hdr_remove (struct wmi_t *wmip, void *osbuf); -A_STATUS wmi_dot11_hdr_add(struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode); +int wmi_dot11_hdr_remove (struct wmi_t *wmip, void *osbuf); +int wmi_dot11_hdr_add(struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode); -A_STATUS wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf); -A_STATUS wmi_syncpoint(struct wmi_t *wmip); -A_STATUS wmi_syncpoint_reset(struct wmi_t *wmip); +int wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf); +int wmi_syncpoint(struct wmi_t *wmip); +int wmi_syncpoint_reset(struct wmi_t *wmip); A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 layer2Priority, A_BOOL wmmEnabled); A_UINT8 wmi_determine_userPriority (A_UINT8 *pkt, A_UINT32 layer2Pri); -A_STATUS wmi_control_rx(struct wmi_t *wmip, void *osbuf); +int wmi_control_rx(struct wmi_t *wmip, void *osbuf); void wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg); void wmi_free_allnodes(struct wmi_t *wmip); bss_t *wmi_find_node(struct wmi_t *wmip, const A_UINT8 *macaddr); @@ -99,10 +99,10 @@ typedef enum { END_WMIFLAG /* end marker */ } WMI_SYNC_FLAG; -A_STATUS wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId, +int wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId, WMI_SYNC_FLAG flag); -A_STATUS wmi_connect_cmd(struct wmi_t *wmip, +int wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType, DOT11_AUTH_MODE dot11AuthMode, AUTH_MODE authMode, @@ -116,209 +116,209 @@ A_STATUS wmi_connect_cmd(struct wmi_t *wmip, A_UINT16 channel, A_UINT32 ctrl_flags); -A_STATUS wmi_reconnect_cmd(struct wmi_t *wmip, +int wmi_reconnect_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT16 channel); -A_STATUS wmi_disconnect_cmd(struct wmi_t *wmip); -A_STATUS wmi_getrev_cmd(struct wmi_t *wmip); -A_STATUS wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, +int wmi_disconnect_cmd(struct wmi_t *wmip); +int wmi_getrev_cmd(struct wmi_t *wmip); +int wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, A_BOOL forceFgScan, A_BOOL isLegacy, A_UINT32 homeDwellTime, A_UINT32 forceScanInterval, A_INT8 numChan, A_UINT16 *channelList); -A_STATUS wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec, +int wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec, A_UINT16 fg_end_sec, A_UINT16 bg_sec, A_UINT16 minact_chdw_msec, A_UINT16 maxact_chdw_msec, A_UINT16 pas_chdw_msec, A_UINT8 shScanRatio, A_UINT8 scanCtrlFlags, A_UINT32 max_dfsch_act_time, A_UINT16 maxact_scan_per_ssid); -A_STATUS wmi_bssfilter_cmd(struct wmi_t *wmip, A_UINT8 filter, A_UINT32 ieMask); -A_STATUS wmi_probedSsid_cmd(struct wmi_t *wmip, A_UINT8 index, A_UINT8 flag, +int wmi_bssfilter_cmd(struct wmi_t *wmip, A_UINT8 filter, A_UINT32 ieMask); +int wmi_probedSsid_cmd(struct wmi_t *wmip, A_UINT8 index, A_UINT8 flag, A_UINT8 ssidLength, A_UCHAR *ssid); -A_STATUS wmi_listeninterval_cmd(struct wmi_t *wmip, A_UINT16 listenInterval, A_UINT16 listenBeacons); -A_STATUS wmi_bmisstime_cmd(struct wmi_t *wmip, A_UINT16 bmisstime, A_UINT16 bmissbeacons); -A_STATUS wmi_associnfo_cmd(struct wmi_t *wmip, A_UINT8 ieType, +int wmi_listeninterval_cmd(struct wmi_t *wmip, A_UINT16 listenInterval, A_UINT16 listenBeacons); +int wmi_bmisstime_cmd(struct wmi_t *wmip, A_UINT16 bmisstime, A_UINT16 bmissbeacons); +int wmi_associnfo_cmd(struct wmi_t *wmip, A_UINT8 ieType, A_UINT8 ieLen, A_UINT8 *ieInfo); -A_STATUS wmi_powermode_cmd(struct wmi_t *wmip, A_UINT8 powerMode); -A_STATUS wmi_ibsspmcaps_cmd(struct wmi_t *wmip, A_UINT8 pmEnable, A_UINT8 ttl, +int wmi_powermode_cmd(struct wmi_t *wmip, A_UINT8 powerMode); +int wmi_ibsspmcaps_cmd(struct wmi_t *wmip, A_UINT8 pmEnable, A_UINT8 ttl, A_UINT16 atim_windows, A_UINT16 timeout_value); -A_STATUS wmi_apps_cmd(struct wmi_t *wmip, A_UINT8 psType, A_UINT32 idle_time, +int wmi_apps_cmd(struct wmi_t *wmip, A_UINT8 psType, A_UINT32 idle_time, A_UINT32 ps_period, A_UINT8 sleep_period); -A_STATUS wmi_pmparams_cmd(struct wmi_t *wmip, A_UINT16 idlePeriod, +int wmi_pmparams_cmd(struct wmi_t *wmip, A_UINT16 idlePeriod, A_UINT16 psPollNum, A_UINT16 dtimPolicy, A_UINT16 wakup_tx_policy, A_UINT16 num_tx_to_wakeup, A_UINT16 ps_fail_event_policy); -A_STATUS wmi_disctimeout_cmd(struct wmi_t *wmip, A_UINT8 timeout); -A_STATUS wmi_sync_cmd(struct wmi_t *wmip, A_UINT8 syncNumber); -A_STATUS wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *pstream); -A_STATUS wmi_delete_pstream_cmd(struct wmi_t *wmip, A_UINT8 trafficClass, A_UINT8 streamID); -A_STATUS wmi_set_framerate_cmd(struct wmi_t *wmip, A_UINT8 bEnable, A_UINT8 type, A_UINT8 subType, A_UINT16 rateMask); -A_STATUS wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 dataRate, A_INT32 mgmtRate, A_INT32 ctlRate); -A_STATUS wmi_get_bitrate_cmd(struct wmi_t *wmip); +int wmi_disctimeout_cmd(struct wmi_t *wmip, A_UINT8 timeout); +int wmi_sync_cmd(struct wmi_t *wmip, A_UINT8 syncNumber); +int wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *pstream); +int wmi_delete_pstream_cmd(struct wmi_t *wmip, A_UINT8 trafficClass, A_UINT8 streamID); +int wmi_set_framerate_cmd(struct wmi_t *wmip, A_UINT8 bEnable, A_UINT8 type, A_UINT8 subType, A_UINT16 rateMask); +int wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 dataRate, A_INT32 mgmtRate, A_INT32 ctlRate); +int wmi_get_bitrate_cmd(struct wmi_t *wmip); A_INT8 wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, A_INT8 *rate_idx); -A_STATUS wmi_get_regDomain_cmd(struct wmi_t *wmip); -A_STATUS wmi_get_channelList_cmd(struct wmi_t *wmip); -A_STATUS wmi_set_channelParams_cmd(struct wmi_t *wmip, A_UINT8 scanParam, +int wmi_get_regDomain_cmd(struct wmi_t *wmip); +int wmi_get_channelList_cmd(struct wmi_t *wmip); +int wmi_set_channelParams_cmd(struct wmi_t *wmip, A_UINT8 scanParam, WMI_PHY_MODE mode, A_INT8 numChan, A_UINT16 *channelList); -A_STATUS wmi_set_snr_threshold_params(struct wmi_t *wmip, +int wmi_set_snr_threshold_params(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd); -A_STATUS wmi_set_rssi_threshold_params(struct wmi_t *wmip, +int wmi_set_rssi_threshold_params(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd); -A_STATUS wmi_clr_rssi_snr(struct wmi_t *wmip); -A_STATUS wmi_set_lq_threshold_params(struct wmi_t *wmip, +int wmi_clr_rssi_snr(struct wmi_t *wmip); +int wmi_set_lq_threshold_params(struct wmi_t *wmip, WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd); -A_STATUS wmi_set_rts_cmd(struct wmi_t *wmip, A_UINT16 threshold); -A_STATUS wmi_set_lpreamble_cmd(struct wmi_t *wmip, A_UINT8 status, A_UINT8 preamblePolicy); +int wmi_set_rts_cmd(struct wmi_t *wmip, A_UINT16 threshold); +int wmi_set_lpreamble_cmd(struct wmi_t *wmip, A_UINT8 status, A_UINT8 preamblePolicy); -A_STATUS wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 bitmask); +int wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 bitmask); -A_STATUS wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie, +int wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie, A_UINT32 source); -A_STATUS wmi_config_debug_module_cmd(struct wmi_t *wmip, A_UINT16 mmask, +int wmi_config_debug_module_cmd(struct wmi_t *wmip, A_UINT16 mmask, A_UINT16 tsr, A_BOOL rep, A_UINT16 size, A_UINT32 valid); -A_STATUS wmi_get_stats_cmd(struct wmi_t *wmip); +int wmi_get_stats_cmd(struct wmi_t *wmip); -A_STATUS wmi_addKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex, +int wmi_addKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex, CRYPTO_TYPE keyType, A_UINT8 keyUsage, A_UINT8 keyLength,A_UINT8 *keyRSC, A_UINT8 *keyMaterial, A_UINT8 key_op_ctrl, A_UINT8 *mac, WMI_SYNC_FLAG sync_flag); -A_STATUS wmi_add_krk_cmd(struct wmi_t *wmip, A_UINT8 *krk); -A_STATUS wmi_delete_krk_cmd(struct wmi_t *wmip); -A_STATUS wmi_deleteKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex); -A_STATUS wmi_set_akmp_params_cmd(struct wmi_t *wmip, +int wmi_add_krk_cmd(struct wmi_t *wmip, A_UINT8 *krk); +int wmi_delete_krk_cmd(struct wmi_t *wmip); +int wmi_deleteKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex); +int wmi_set_akmp_params_cmd(struct wmi_t *wmip, WMI_SET_AKMP_PARAMS_CMD *akmpParams); -A_STATUS wmi_get_pmkid_list_cmd(struct wmi_t *wmip); -A_STATUS wmi_set_pmkid_list_cmd(struct wmi_t *wmip, +int wmi_get_pmkid_list_cmd(struct wmi_t *wmip); +int wmi_set_pmkid_list_cmd(struct wmi_t *wmip, WMI_SET_PMKID_LIST_CMD *pmkInfo); -A_STATUS wmi_abort_scan_cmd(struct wmi_t *wmip); -A_STATUS wmi_set_txPwr_cmd(struct wmi_t *wmip, A_UINT8 dbM); -A_STATUS wmi_get_txPwr_cmd(struct wmi_t *wmip); -A_STATUS wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid); -A_STATUS wmi_deleteBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex); -A_STATUS wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, A_BOOL en); -A_STATUS wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId, +int wmi_abort_scan_cmd(struct wmi_t *wmip); +int wmi_set_txPwr_cmd(struct wmi_t *wmip, A_UINT8 dbM); +int wmi_get_txPwr_cmd(struct wmi_t *wmip); +int wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid); +int wmi_deleteBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex); +int wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, A_BOOL en); +int wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId, A_BOOL set); -A_STATUS wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT8 ac, A_UINT16 txop, +int wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT8 ac, A_UINT16 txop, A_UINT8 eCWmin, A_UINT8 eCWmax, A_UINT8 aifsn); -A_STATUS wmi_set_retry_limits_cmd(struct wmi_t *wmip, A_UINT8 frameType, +int wmi_set_retry_limits_cmd(struct wmi_t *wmip, A_UINT8 frameType, A_UINT8 trafficClass, A_UINT8 maxRetries, A_UINT8 enableNotify); void wmi_get_current_bssid(struct wmi_t *wmip, A_UINT8 *bssid); -A_STATUS wmi_get_roam_tbl_cmd(struct wmi_t *wmip); -A_STATUS wmi_get_roam_data_cmd(struct wmi_t *wmip, A_UINT8 roamDataType); -A_STATUS wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p, +int wmi_get_roam_tbl_cmd(struct wmi_t *wmip); +int wmi_get_roam_data_cmd(struct wmi_t *wmip, A_UINT8 roamDataType); +int wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p, A_UINT8 size); -A_STATUS wmi_set_powersave_timers_cmd(struct wmi_t *wmip, +int wmi_set_powersave_timers_cmd(struct wmi_t *wmip, WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd, A_UINT8 size); -A_STATUS wmi_set_opt_mode_cmd(struct wmi_t *wmip, A_UINT8 optMode); -A_STATUS wmi_opt_tx_frame_cmd(struct wmi_t *wmip, +int wmi_set_opt_mode_cmd(struct wmi_t *wmip, A_UINT8 optMode); +int wmi_opt_tx_frame_cmd(struct wmi_t *wmip, A_UINT8 frmType, A_UINT8 *dstMacAddr, A_UINT8 *bssid, A_UINT16 optIEDataLen, A_UINT8 *optIEData); -A_STATUS wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl); -A_STATUS wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize); -A_STATUS wmi_set_max_sp_len_cmd(struct wmi_t *wmip, A_UINT8 maxSpLen); +int wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl); +int wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize); +int wmi_set_max_sp_len_cmd(struct wmi_t *wmip, A_UINT8 maxSpLen); A_UINT8 convert_userPriority_to_trafficClass(A_UINT8 userPriority); A_UINT8 wmi_get_power_mode_cmd(struct wmi_t *wmip); -A_STATUS wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, A_BOOL tspecCompliance); +int wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, A_BOOL tspecCompliance); #ifdef CONFIG_HOST_TCMD_SUPPORT -A_STATUS wmi_test_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT32 len); +int wmi_test_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT32 len); #endif -A_STATUS wmi_set_bt_status_cmd(struct wmi_t *wmip, A_UINT8 streamType, A_UINT8 status); -A_STATUS wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd); +int wmi_set_bt_status_cmd(struct wmi_t *wmip, A_UINT8 streamType, A_UINT8 status); +int wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd); -A_STATUS wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd); +int wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd); -A_STATUS wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip, +int wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd); -A_STATUS wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip, +int wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *cmd); -A_STATUS wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip, +int wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd); -A_STATUS wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip, +int wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_A2DP_CONFIG_CMD* cmd); -A_STATUS wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD* cmd); +int wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD* cmd); -A_STATUS wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd); +int wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd); -A_STATUS wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip, +int wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip, WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd); -A_STATUS wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd); +int wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd); -A_STATUS wmi_get_btcoex_stats_cmd(struct wmi_t * wmip); +int wmi_get_btcoex_stats_cmd(struct wmi_t * wmip); -A_STATUS wmi_SGI_cmd(struct wmi_t *wmip, A_UINT32 sgiMask, A_UINT8 sgiPERThreshold); +int wmi_SGI_cmd(struct wmi_t *wmip, A_UINT32 sgiMask, A_UINT8 sgiPERThreshold); /* * This function is used to configure the fix rates mask to the target. */ -A_STATUS wmi_set_fixrates_cmd(struct wmi_t *wmip, A_UINT32 fixRatesMask); -A_STATUS wmi_get_ratemask_cmd(struct wmi_t *wmip); +int wmi_set_fixrates_cmd(struct wmi_t *wmip, A_UINT32 fixRatesMask); +int wmi_get_ratemask_cmd(struct wmi_t *wmip); -A_STATUS wmi_set_authmode_cmd(struct wmi_t *wmip, A_UINT8 mode); +int wmi_set_authmode_cmd(struct wmi_t *wmip, A_UINT8 mode); -A_STATUS wmi_set_reassocmode_cmd(struct wmi_t *wmip, A_UINT8 mode); +int wmi_set_reassocmode_cmd(struct wmi_t *wmip, A_UINT8 mode); -A_STATUS wmi_set_qos_supp_cmd(struct wmi_t *wmip,A_UINT8 status); -A_STATUS wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status); -A_STATUS wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG txEnable); -A_STATUS wmi_set_country(struct wmi_t *wmip, A_UCHAR *countryCode); +int wmi_set_qos_supp_cmd(struct wmi_t *wmip,A_UINT8 status); +int wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status); +int wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG txEnable); +int wmi_set_country(struct wmi_t *wmip, A_UCHAR *countryCode); -A_STATUS wmi_get_keepalive_configured(struct wmi_t *wmip); +int wmi_get_keepalive_configured(struct wmi_t *wmip); A_UINT8 wmi_get_keepalive_cmd(struct wmi_t *wmip); -A_STATUS wmi_set_keepalive_cmd(struct wmi_t *wmip, A_UINT8 keepaliveInterval); +int wmi_set_keepalive_cmd(struct wmi_t *wmip, A_UINT8 keepaliveInterval); -A_STATUS wmi_set_appie_cmd(struct wmi_t *wmip, A_UINT8 mgmtFrmType, +int wmi_set_appie_cmd(struct wmi_t *wmip, A_UINT8 mgmtFrmType, A_UINT8 ieLen,A_UINT8 *ieInfo); -A_STATUS wmi_set_halparam_cmd(struct wmi_t *wmip, A_UINT8 *cmd, A_UINT16 dataLen); +int wmi_set_halparam_cmd(struct wmi_t *wmip, A_UINT8 *cmd, A_UINT16 dataLen); A_INT32 wmi_get_rate(A_INT8 rateindex); -A_STATUS wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *cmd); +int wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *cmd); /*Wake on Wireless WMI commands*/ -A_STATUS wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, WMI_SET_HOST_SLEEP_MODE_CMD *cmd); -A_STATUS wmi_set_wow_mode_cmd(struct wmi_t *wmip, WMI_SET_WOW_MODE_CMD *cmd); -A_STATUS wmi_get_wow_list_cmd(struct wmi_t *wmip, WMI_GET_WOW_LIST_CMD *cmd); -A_STATUS wmi_add_wow_pattern_cmd(struct wmi_t *wmip, +int wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, WMI_SET_HOST_SLEEP_MODE_CMD *cmd); +int wmi_set_wow_mode_cmd(struct wmi_t *wmip, WMI_SET_WOW_MODE_CMD *cmd); +int wmi_get_wow_list_cmd(struct wmi_t *wmip, WMI_GET_WOW_LIST_CMD *cmd); +int wmi_add_wow_pattern_cmd(struct wmi_t *wmip, WMI_ADD_WOW_PATTERN_CMD *cmd, A_UINT8* pattern, A_UINT8* mask, A_UINT8 pattern_size); -A_STATUS wmi_del_wow_pattern_cmd(struct wmi_t *wmip, +int wmi_del_wow_pattern_cmd(struct wmi_t *wmip, WMI_DEL_WOW_PATTERN_CMD *cmd); -A_STATUS wmi_set_wsc_status_cmd(struct wmi_t *wmip, A_UINT32 status); +int wmi_set_wsc_status_cmd(struct wmi_t *wmip, A_UINT32 status); -A_STATUS +int wmi_set_params_cmd(struct wmi_t *wmip, A_UINT32 opcode, A_UINT32 length, A_CHAR* buffer); -A_STATUS +int wmi_set_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 dot3, A_UINT8 dot4); -A_STATUS +int wmi_del_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 dot3, A_UINT8 dot4); -A_STATUS +int wmi_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 enable); bss_t * @@ -333,93 +333,93 @@ void wmi_set_nodeage(struct wmi_t *wmip, A_UINT32 nodeAge); #if defined(CONFIG_TARGET_PROFILE_SUPPORT) -A_STATUS wmi_prof_cfg_cmd(struct wmi_t *wmip, A_UINT32 period, A_UINT32 nbins); -A_STATUS wmi_prof_addr_set_cmd(struct wmi_t *wmip, A_UINT32 addr); -A_STATUS wmi_prof_start_cmd(struct wmi_t *wmip); -A_STATUS wmi_prof_stop_cmd(struct wmi_t *wmip); -A_STATUS wmi_prof_count_get_cmd(struct wmi_t *wmip); +int wmi_prof_cfg_cmd(struct wmi_t *wmip, A_UINT32 period, A_UINT32 nbins); +int wmi_prof_addr_set_cmd(struct wmi_t *wmip, A_UINT32 addr); +int wmi_prof_start_cmd(struct wmi_t *wmip); +int wmi_prof_stop_cmd(struct wmi_t *wmip); +int wmi_prof_count_get_cmd(struct wmi_t *wmip); #endif /* CONFIG_TARGET_PROFILE_SUPPORT */ #ifdef OS_ROAM_MANAGEMENT void wmi_scan_indication (struct wmi_t *wmip); #endif -A_STATUS +int wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd); bss_t *wmi_rm_current_bss (struct wmi_t *wmip, A_UINT8 *id); -A_STATUS wmi_add_current_bss (struct wmi_t *wmip, A_UINT8 *id, bss_t *bss); +int wmi_add_current_bss (struct wmi_t *wmip, A_UINT8 *id, bss_t *bss); /* * AP mode */ -A_STATUS +int wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p); -A_STATUS +int wmi_ap_set_hidden_ssid(struct wmi_t *wmip, A_UINT8 hidden_ssid); -A_STATUS +int wmi_ap_set_num_sta(struct wmi_t *wmip, A_UINT8 num_sta); -A_STATUS +int wmi_ap_set_acl_policy(struct wmi_t *wmip, A_UINT8 policy); -A_STATUS +int wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *a); A_UINT8 acl_add_del_mac(WMI_AP_ACL *a, WMI_AP_ACL_MAC_CMD *acl); -A_STATUS +int wmi_ap_set_mlme(struct wmi_t *wmip, A_UINT8 cmd, A_UINT8 *mac, A_UINT16 reason); -A_STATUS +int wmi_set_pvb_cmd(struct wmi_t *wmip, A_UINT16 aid, A_BOOL flag); -A_STATUS +int wmi_ap_conn_inact_time(struct wmi_t *wmip, A_UINT32 period); -A_STATUS +int wmi_ap_bgscan_time(struct wmi_t *wmip, A_UINT32 period, A_UINT32 dwell); -A_STATUS +int wmi_ap_set_dtim(struct wmi_t *wmip, A_UINT8 dtim); -A_STATUS +int wmi_ap_set_rateset(struct wmi_t *wmip, A_UINT8 rateset); -A_STATUS +int wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd); -A_STATUS +int wmi_set_ht_op_cmd(struct wmi_t *wmip, A_UINT8 sta_chan_width); -A_STATUS +int wmi_send_hci_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT16 sz); -A_STATUS +int wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, A_UINT32 *pMaskArray); -A_STATUS +int wmi_setup_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid); -A_STATUS +int wmi_delete_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid, A_BOOL uplink); -A_STATUS +int wmi_allow_aggr_cmd(struct wmi_t *wmip, A_UINT16 tx_tidmask, A_UINT16 rx_tidmask); -A_STATUS +int wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, A_UINT8 rxMetaVersion, A_BOOL rxDot11Hdr, A_BOOL defragOnHost); -A_STATUS +int wmi_set_thin_mode_cmd(struct wmi_t *wmip, A_BOOL bThinMode); -A_STATUS +int wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence); -A_STATUS +int wmi_set_pmk_cmd(struct wmi_t *wmip, A_UINT8 *pmk); A_UINT16 diff --git a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c index 83bc5be3ef1b..687f963ec468 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c @@ -47,14 +47,14 @@ #define HCI_MAX_EVT_RECV_LENGTH 257 #define EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET 5 -A_STATUS AthPSInitialize(AR3K_CONFIG_INFO *hdev); +int AthPSInitialize(AR3K_CONFIG_INFO *hdev); -static A_STATUS SendHCICommand(AR3K_CONFIG_INFO *pConfig, +static int SendHCICommand(AR3K_CONFIG_INFO *pConfig, A_UINT8 *pBuffer, int Length) { HTC_PACKET *pPacket = NULL; - A_STATUS status = A_OK; + int status = A_OK; do { @@ -84,11 +84,11 @@ static A_STATUS SendHCICommand(AR3K_CONFIG_INFO *pConfig, return status; } -static A_STATUS RecvHCIEvent(AR3K_CONFIG_INFO *pConfig, +static int RecvHCIEvent(AR3K_CONFIG_INFO *pConfig, A_UINT8 *pBuffer, int *pLength) { - A_STATUS status = A_OK; + int status = A_OK; HTC_PACKET *pRecvPacket = NULL; do { @@ -122,13 +122,13 @@ static A_STATUS RecvHCIEvent(AR3K_CONFIG_INFO *pConfig, return status; } -A_STATUS SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, +int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, A_UINT8 *pHCICommand, int CmdLength, A_UINT8 **ppEventBuffer, A_UINT8 **ppBufferToFree) { - A_STATUS status = A_OK; + int status = A_OK; A_UINT8 *pBuffer = NULL; A_UINT8 *pTemp; int length; @@ -209,9 +209,9 @@ A_STATUS SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, return status; } -static A_STATUS AR3KConfigureHCIBaud(AR3K_CONFIG_INFO *pConfig) +static int AR3KConfigureHCIBaud(AR3K_CONFIG_INFO *pConfig) { - A_STATUS status = A_OK; + int status = A_OK; A_UINT8 hciBaudChangeCommand[] = {0x0c,0xfc,0x2,0,0}; A_UINT16 baudVal; A_UINT8 *pEvent = NULL; @@ -274,9 +274,9 @@ static A_STATUS AR3KConfigureHCIBaud(AR3K_CONFIG_INFO *pConfig) return status; } -static A_STATUS AR3KExitMinBoot(AR3K_CONFIG_INFO *pConfig) +static int AR3KExitMinBoot(AR3K_CONFIG_INFO *pConfig) { - A_STATUS status; + int status; A_CHAR exitMinBootCmd[] = {0x25,0xFC,0x0c,0x03,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00}; A_UINT8 *pEvent = NULL; @@ -310,9 +310,9 @@ static A_STATUS AR3KExitMinBoot(AR3K_CONFIG_INFO *pConfig) return status; } -static A_STATUS AR3KConfigureSendHCIReset(AR3K_CONFIG_INFO *pConfig) +static int AR3KConfigureSendHCIReset(AR3K_CONFIG_INFO *pConfig) { - A_STATUS status = A_OK; + int status = A_OK; A_UINT8 hciResetCommand[] = {0x03,0x0c,0x0}; A_UINT8 *pEvent = NULL; A_UINT8 *pBufferToFree = NULL; @@ -334,9 +334,9 @@ static A_STATUS AR3KConfigureSendHCIReset(AR3K_CONFIG_INFO *pConfig) return status; } -static A_STATUS AR3KEnableTLPM(AR3K_CONFIG_INFO *pConfig) +static int AR3KEnableTLPM(AR3K_CONFIG_INFO *pConfig) { - A_STATUS status; + int status; /* AR3K vendor specific command for Host Wakeup Config */ A_CHAR hostWakeupConfig[] = {0x31,0xFC,0x18, 0x02,0x00,0x00,0x00, @@ -453,9 +453,9 @@ static A_STATUS AR3KEnableTLPM(AR3K_CONFIG_INFO *pConfig) return status; } -A_STATUS AR3KConfigure(AR3K_CONFIG_INFO *pConfig) +int AR3KConfigure(AR3K_CONFIG_INFO *pConfig) { - A_STATUS status = A_OK; + int status = A_OK; AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Configuring AR3K ...\n")); @@ -521,9 +521,9 @@ A_STATUS AR3KConfigure(AR3K_CONFIG_INFO *pConfig) return status; } -A_STATUS AR3KConfigureExit(void *config) +int AR3KConfigureExit(void *config) { - A_STATUS status = A_OK; + int status = A_OK; AR3K_CONFIG_INFO *pConfig = (AR3K_CONFIG_INFO *)config; AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Cleaning up AR3K ...\n")); diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c index 0e298dba9fc8..50f2edd0827a 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c @@ -46,7 +46,7 @@ typedef struct { AR3K_CONFIG_INFO *dev; }HciCommandListParam; -A_STATUS SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, +int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, A_UINT8 *pHCICommand, int CmdLength, A_UINT8 **ppEventBuffer, @@ -56,8 +56,8 @@ A_UINT32 Rom_Version; A_UINT32 Build_Version; extern A_BOOL BDADDR; -A_STATUS getDeviceType(AR3K_CONFIG_INFO *pConfig, A_UINT32 * code); -A_STATUS ReadVersionInfo(AR3K_CONFIG_INFO *pConfig); +int getDeviceType(AR3K_CONFIG_INFO *pConfig, A_UINT32 * code); +int ReadVersionInfo(AR3K_CONFIG_INFO *pConfig); #ifndef HCI_TRANSPORT_SDIO DECLARE_WAIT_QUEUE_HEAD(PsCompleteEvent); @@ -70,7 +70,7 @@ int PSHciWritepacket(struct hci_dev*,A_UCHAR* Data, A_UINT32 len); extern char *bdaddr; #endif /* HCI_TRANSPORT_SDIO */ -A_STATUS write_bdaddr(AR3K_CONFIG_INFO *pConfig,A_UCHAR *bdaddr,int type); +int write_bdaddr(AR3K_CONFIG_INFO *pConfig,A_UCHAR *bdaddr,int type); int PSSendOps(void *arg); @@ -91,9 +91,9 @@ void Hci_log(A_UCHAR * log_string,A_UCHAR *data,A_UINT32 len) -A_STATUS AthPSInitialize(AR3K_CONFIG_INFO *hdev) +int AthPSInitialize(AR3K_CONFIG_INFO *hdev) { - A_STATUS status = A_OK; + int status = A_OK; if(hdev == NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Device handle received\n")); return A_ERROR; @@ -389,7 +389,7 @@ complete: * with a HCI Command Complete event. * For HCI SDIO transport, this will be internally defined. */ -A_STATUS SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, +int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, A_UINT8 *pHCICommand, int CmdLength, A_UINT8 **ppEventBuffer, @@ -419,7 +419,7 @@ A_STATUS SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, } #endif /* HCI_TRANSPORT_SDIO */ -A_STATUS ReadPSEvent(A_UCHAR* Data){ +int ReadPSEvent(A_UCHAR* Data){ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" PS Event %x %x %x\n",Data[4],Data[5],Data[3])); if(Data[4] == 0xFC && Data[5] == 0x00) @@ -481,14 +481,14 @@ int str2ba(unsigned char *str_bdaddr,unsigned char *bdaddr) return 0; } -A_STATUS write_bdaddr(AR3K_CONFIG_INFO *pConfig,A_UCHAR *bdaddr,int type) +int write_bdaddr(AR3K_CONFIG_INFO *pConfig,A_UCHAR *bdaddr,int type) { A_UCHAR bdaddr_cmd[] = { 0x0B, 0xFC, 0x0A, 0x01, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; A_UINT8 *event; A_UINT8 *bufferToFree = NULL; - A_STATUS result = A_ERROR; + int result = A_ERROR; int inc,outc; if (type == BDADDR_TYPE_STRING) @@ -516,12 +516,12 @@ A_STATUS write_bdaddr(AR3K_CONFIG_INFO *pConfig,A_UCHAR *bdaddr,int type) return result; } -A_STATUS ReadVersionInfo(AR3K_CONFIG_INFO *pConfig) +int ReadVersionInfo(AR3K_CONFIG_INFO *pConfig) { A_UINT8 hciCommand[] = {0x1E,0xfc,0x00}; A_UINT8 *event; A_UINT8 *bufferToFree = NULL; - A_STATUS result = A_ERROR; + int result = A_ERROR; if(A_OK == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) { result = ReadPSEvent(event); @@ -531,13 +531,13 @@ A_STATUS ReadVersionInfo(AR3K_CONFIG_INFO *pConfig) } return result; } -A_STATUS getDeviceType(AR3K_CONFIG_INFO *pConfig, A_UINT32 * code) +int getDeviceType(AR3K_CONFIG_INFO *pConfig, A_UINT32 * code) { A_UINT8 hciCommand[] = {0x05,0xfc,0x05,0x00,0x00,0x00,0x00,0x04}; A_UINT8 *event; A_UINT8 *bufferToFree = NULL; A_UINT32 reg; - A_STATUS result = A_ERROR; + int result = A_ERROR; *code = 0; hciCommand[3] = (A_UINT8)(FPGA_REGISTER & 0xFF); hciCommand[4] = (A_UINT8)((FPGA_REGISTER >> 8) & 0xFF); diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h index 4e5b7bfc0ea9..975bf6250249 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h @@ -70,6 +70,6 @@ extern wait_queue_t Eventwait; extern A_UCHAR *HciEventpacket; #endif /* #ifndef HCI_TRANSPORT_SDIO */ -A_STATUS AthPSInitialize(AR3K_CONFIG_INFO *hdev); -A_STATUS ReadPSEvent(A_UCHAR* Data); +int AthPSInitialize(AR3K_CONFIG_INFO *hdev); +int ReadPSEvent(A_UCHAR* Data); #endif /* __AR3KPSCONFIG_H */ diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c index 8dce0542282b..3b2c0ccdf1d5 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c @@ -127,10 +127,10 @@ tPsTagEntry PsTagEntry[RAMPS_MAX_PS_TAGS_PER_FILE]; tRamPatch RamPatch[MAX_NUM_PATCH_ENTRY]; -A_STATUS AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat); +int AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat); char AthReadChar(A_UCHAR *buffer, A_UINT32 len,A_UINT32 *pos); char * AthGetLine(char * buffer, int maxlen, A_UCHAR *srcbuffer,A_UINT32 len,A_UINT32 *pos); -static A_STATUS AthPSCreateHCICommand(A_UCHAR Opcode, A_UINT32 Param1,PSCmdPacket *PSPatchPacket,A_UINT32 *index); +static int AthPSCreateHCICommand(A_UCHAR Opcode, A_UINT32 Param1,PSCmdPacket *PSPatchPacket,A_UINT32 *index); /* Function to reads the next character from the input buffer */ char AthReadChar(A_UCHAR *buffer, A_UINT32 len,A_UINT32 *pos) @@ -315,7 +315,7 @@ unsigned int uReadDataInSection(char *pCharLine, ST_PS_DATA_FORMAT stPS_DataForm return (0x0FFF); } } -A_STATUS AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat) +int AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat) { char *Buffer; char *pCharLine; @@ -558,7 +558,7 @@ A_STATUS AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat /********************/ -A_STATUS GetNextTwoChar(A_UCHAR *srcbuffer,A_UINT32 len, A_UINT32 *pos, char * buffer) +int GetNextTwoChar(A_UCHAR *srcbuffer,A_UINT32 len, A_UINT32 *pos, char * buffer) { unsigned char ch; @@ -579,7 +579,7 @@ A_STATUS GetNextTwoChar(A_UCHAR *srcbuffer,A_UINT32 len, A_UINT32 *pos, char * b return A_OK; } -A_STATUS AthDoParsePatch(A_UCHAR *patchbuffer, A_UINT32 patchlen) +int AthDoParsePatch(A_UCHAR *patchbuffer, A_UINT32 patchlen) { char Byte[3]; @@ -659,9 +659,9 @@ A_STATUS AthDoParsePatch(A_UCHAR *patchbuffer, A_UINT32 patchlen) /********************/ -A_STATUS AthDoParsePS(A_UCHAR *srcbuffer, A_UINT32 srclen) +int AthDoParsePS(A_UCHAR *srcbuffer, A_UINT32 srclen) { - A_STATUS status; + int status; int i; A_BOOL BDADDR_Present = A_ERROR; @@ -833,7 +833,7 @@ int AthCreateCommandList(PSCmdPacket **HciPacketList, A_UINT32 *numPackets) //////////////////////// ///////////// -static A_STATUS AthPSCreateHCICommand(A_UCHAR Opcode, A_UINT32 Param1,PSCmdPacket *PSPatchPacket,A_UINT32 *index) +static int AthPSCreateHCICommand(A_UCHAR Opcode, A_UINT32 Param1,PSCmdPacket *PSPatchPacket,A_UINT32 *index) { A_UCHAR *HCI_PS_Command; A_UINT32 Length; @@ -955,7 +955,7 @@ static A_STATUS AthPSCreateHCICommand(A_UCHAR Opcode, A_UINT32 Param1,PSCmdPacke } return A_OK; } -A_STATUS AthFreeCommandList(PSCmdPacket **HciPacketList, A_UINT32 numPackets) +int AthFreeCommandList(PSCmdPacket **HciPacketList, A_UINT32 numPackets) { int i; if(*HciPacketList == NULL) { diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h index 007b0eb950d2..96c3e3f9030a 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h @@ -104,10 +104,10 @@ typedef struct PSCmdPacket } PSCmdPacket; /* Parses a Patch information buffer and store it in global structure */ -A_STATUS AthDoParsePatch(A_UCHAR *, A_UINT32); +int AthDoParsePatch(A_UCHAR *, A_UINT32); /* parses a PS information buffer and stores it in a global structure */ -A_STATUS AthDoParsePS(A_UCHAR *, A_UINT32); +int AthDoParsePS(A_UCHAR *, A_UINT32); /* * Uses the output of Both AthDoParsePS and AthDoParsePatch APIs to form HCI command array with @@ -123,5 +123,5 @@ A_STATUS AthDoParsePS(A_UCHAR *, A_UINT32); int AthCreateCommandList(PSCmdPacket **, A_UINT32 *); /* Cleanup the dynamically allicated HCI command list */ -A_STATUS AthFreeCommandList(PSCmdPacket **HciPacketList, A_UINT32 numPackets); +int AthFreeCommandList(PSCmdPacket **HciPacketList, A_UINT32 numPackets); #endif /* __AR3KPSPARSER_H */ diff --git a/drivers/staging/ath6kl/miscdrv/common_drv.c b/drivers/staging/ath6kl/miscdrv/common_drv.c index 6754fde467de..2b5fe5bed855 100644 --- a/drivers/staging/ath6kl/miscdrv/common_drv.c +++ b/drivers/staging/ath6kl/miscdrv/common_drv.c @@ -83,9 +83,9 @@ static A_UINT8 custDataAR6003[AR6003_CUST_DATA_SIZE]; #ifdef USE_4BYTE_REGISTER_ACCESS /* set the window address register (using 4-byte register access ). */ -A_STATUS ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr, A_UINT32 Address) +int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr, A_UINT32 Address) { - A_STATUS status; + int status; A_UINT8 addrValue[4]; A_INT32 i; @@ -144,9 +144,9 @@ A_STATUS ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 Registe #else /* set the window address register */ -A_STATUS ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr, A_UINT32 Address) +int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr, A_UINT32 Address) { - A_STATUS status; + int status; /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written * last to initiate the access cycle */ @@ -186,10 +186,10 @@ A_STATUS ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 Registe * Read from the AR6000 through its diagnostic window. * No cooperation from the Target is required for this. */ -A_STATUS +int ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data) { - A_STATUS status; + int status; /* set window register to start read cycle */ status = ar6000_SetAddressWindowRegister(hifDevice, @@ -220,10 +220,10 @@ ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data) * Write to the AR6000 through its diagnostic window. * No cooperation from the Target is required for this. */ -A_STATUS +int ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data) { - A_STATUS status; + int status; /* set write data */ status = HIFReadWrite(hifDevice, @@ -243,12 +243,12 @@ ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data) *address); } -A_STATUS +int ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, A_UCHAR *data, A_UINT32 length) { A_UINT32 count; - A_STATUS status = A_OK; + int status = A_OK; for (count = 0; count < length; count += 4, address += 4) { if ((status = ar6000_ReadRegDiag(hifDevice, &address, @@ -261,12 +261,12 @@ ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, return status; } -A_STATUS +int ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, A_UCHAR *data, A_UINT32 length) { A_UINT32 count; - A_STATUS status = A_OK; + int status = A_OK; for (count = 0; count < length; count += 4, address += 4) { if ((status = ar6000_WriteRegDiag(hifDevice, &address, @@ -279,10 +279,10 @@ ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, return status; } -A_STATUS +int ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, A_UINT32 *regval) { - A_STATUS status; + int status; A_UCHAR vals[4]; A_UCHAR register_selection[4]; @@ -329,10 +329,10 @@ ar6k_FetchTargetRegs(HIF_DEVICE *hifDevice, A_UINT32 *targregs) } #if 0 -static A_STATUS +static int _do_write_diag(HIF_DEVICE *hifDevice, A_UINT32 addr, A_UINT32 value) { - A_STATUS status; + int status; status = ar6000_WriteRegDiag(hifDevice, &addr, &value); if (status != A_OK) @@ -357,7 +357,7 @@ _do_write_diag(HIF_DEVICE *hifDevice, A_UINT32 addr, A_UINT32 value) * TBD: Might want to add special handling for AR6K_OPTION_BMI_DISABLE. */ #if 0 -static A_STATUS +static int _delay_until_target_alive(HIF_DEVICE *hifDevice, A_INT32 wait_msecs, A_UINT32 TargetType) { A_INT32 actual_wait; @@ -399,9 +399,9 @@ _delay_until_target_alive(HIF_DEVICE *hifDevice, A_INT32 wait_msecs, A_UINT32 Ta #define AR6002_RESET_CONTROL_ADDRESS 0x00004000 #define AR6003_RESET_CONTROL_ADDRESS 0x00004000 /* reset device */ -A_STATUS ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_BOOL waitForCompletion, A_BOOL coldReset) +int ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_BOOL waitForCompletion, A_BOOL coldReset) { - A_STATUS status = A_OK; + int status = A_OK; A_UINT32 address; A_UINT32 data; @@ -557,7 +557,7 @@ void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType) { A_UINT32 address; A_UINT32 regDumpArea = 0; - A_STATUS status; + int status; A_UINT32 regDumpValues[REGISTER_DUMP_LEN_MAX]; A_UINT32 regDumpCount = 0; A_UINT32 i; @@ -625,12 +625,12 @@ void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType) /* set HTC/Mbox operational parameters, this can only be called when the target is in the * BMI phase */ -A_STATUS ar6000_set_htc_params(HIF_DEVICE *hifDevice, +int ar6000_set_htc_params(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_UINT32 MboxIsrYieldValue, A_UINT8 HtcControlBuffers) { - A_STATUS status; + int status; A_UINT32 blocksizes[HTC_MAILBOX_NUM_MAX]; do { @@ -685,18 +685,18 @@ A_STATUS ar6000_set_htc_params(HIF_DEVICE *hifDevice, } -static A_STATUS prepare_ar6002(HIF_DEVICE *hifDevice, A_UINT32 TargetVersion) +static int prepare_ar6002(HIF_DEVICE *hifDevice, A_UINT32 TargetVersion) { - A_STATUS status = A_OK; + int status = A_OK; /* placeholder */ return status; } -static A_STATUS prepare_ar6003(HIF_DEVICE *hifDevice, A_UINT32 TargetVersion) +static int prepare_ar6003(HIF_DEVICE *hifDevice, A_UINT32 TargetVersion) { - A_STATUS status = A_OK; + int status = A_OK; /* placeholder */ @@ -704,7 +704,7 @@ static A_STATUS prepare_ar6003(HIF_DEVICE *hifDevice, A_UINT32 TargetVersion) } /* this function assumes the caller has already initialized the BMI APIs */ -A_STATUS ar6000_prepare_target(HIF_DEVICE *hifDevice, +int ar6000_prepare_target(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_UINT32 TargetVersion) { @@ -725,7 +725,7 @@ A_STATUS ar6000_prepare_target(HIF_DEVICE *hifDevice, * THIS IS FOR USE ONLY WITH AR6002 REV 1.x. * TBDXXX: Remove this function when REV 1.x is desupported. */ -A_STATUS +int ar6002_REV1_reset_force_host (HIF_DEVICE *hifDevice) { A_INT32 i; @@ -735,7 +735,7 @@ ar6002_REV1_reset_force_host (HIF_DEVICE *hifDevice) }; struct forceROM_s *ForceROM; A_INT32 szForceROM; - A_STATUS status = A_OK; + int status = A_OK; A_UINT32 address; A_UINT32 data; @@ -934,7 +934,7 @@ void a_dump_module_debug_info_by_name(A_CHAR *module_name) } -A_STATUS a_get_module_mask(A_CHAR *module_name, A_UINT32 *pMask) +int a_get_module_mask(A_CHAR *module_name, A_UINT32 *pMask) { ATH_DEBUG_MODULE_DBG_INFO *pInfo = FindModule(module_name); @@ -946,7 +946,7 @@ A_STATUS a_get_module_mask(A_CHAR *module_name, A_UINT32 *pMask) return A_OK; } -A_STATUS a_set_module_mask(A_CHAR *module_name, A_UINT32 Mask) +int a_set_module_mask(A_CHAR *module_name, A_UINT32 Mask) { ATH_DEBUG_MODULE_DBG_INFO *pInfo = FindModule(module_name); @@ -999,11 +999,11 @@ void a_module_debug_support_cleanup(void) } /* can only be called during bmi init stage */ -A_STATUS ar6000_set_hci_bridge_flags(HIF_DEVICE *hifDevice, +int ar6000_set_hci_bridge_flags(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_UINT32 Flags) { - A_STATUS status = A_OK; + int status = A_OK; do { diff --git a/drivers/staging/ath6kl/miscdrv/credit_dist.c b/drivers/staging/ath6kl/miscdrv/credit_dist.c index 91316e0b109e..3f7543d08ab2 100644 --- a/drivers/staging/ath6kl/miscdrv/credit_dist.c +++ b/drivers/staging/ath6kl/miscdrv/credit_dist.c @@ -393,7 +393,7 @@ static void SeekCredits(COMMON_CREDIT_STATE_INFO *pCredInfo, } /* initialize and setup credit distribution */ -A_STATUS ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, COMMON_CREDIT_STATE_INFO *pCredInfo) +int ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, COMMON_CREDIT_STATE_INFO *pCredInfo) { HTC_SERVICE_ID servicepriority[5]; diff --git a/drivers/staging/ath6kl/os/linux/ar6000_android.c b/drivers/staging/ath6kl/os/linux/ar6000_android.c index dbde05f7ed14..88487ccb08ee 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_android.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_android.c @@ -51,7 +51,7 @@ static int screen_is_off; static struct early_suspend ar6k_early_suspend; #endif -static A_STATUS (*ar6000_avail_ev_p)(void *, void *); +static int (*ar6000_avail_ev_p)(void *, void *); #if defined(CONFIG_ANDROID_LOGGER) && (!defined(CONFIG_MMC_MSM)) int logger_write(const enum logidx index, @@ -269,9 +269,9 @@ void android_release_firmware(const struct firmware *firmware) } } -static A_STATUS ar6000_android_avail_ev(void *context, void *hif_handle) +static int ar6000_android_avail_ev(void *context, void *hif_handle) { - A_STATUS ret; + int ret; ar6000_enable_mmchost_detect_change(0); ret = ar6000_avail_ev_p(context, hif_handle); return ret; diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 126a36a2daa6..c171be5a1099 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -305,13 +305,13 @@ extern void android_module_exit(void); /* * HTC service connection handlers */ -static A_STATUS ar6000_avail_ev(void *context, void *hif_handle); +static int ar6000_avail_ev(void *context, void *hif_handle); -static A_STATUS ar6000_unavail_ev(void *context, void *hif_handle); +static int ar6000_unavail_ev(void *context, void *hif_handle); -A_STATUS ar6000_configure_target(AR_SOFTC_T *ar); +int ar6000_configure_target(AR_SOFTC_T *ar); -static void ar6000_target_failure(void *Instance, A_STATUS Status); +static void ar6000_target_failure(void *Instance, int Status); static void ar6000_rx(void *Context, HTC_PACKET *pPacket); @@ -343,17 +343,17 @@ ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t count); -static A_STATUS +static int ar6000_sysfs_bmi_init(AR_SOFTC_T *ar); /* HCI PAL callback function declarations */ -A_STATUS ar6k_setup_hci_pal(AR_SOFTC_T *ar); +int ar6k_setup_hci_pal(AR_SOFTC_T *ar); void ar6k_cleanup_hci_pal(AR_SOFTC_T *ar); static void ar6000_sysfs_bmi_deinit(AR_SOFTC_T *ar); -A_STATUS +int ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode); /* @@ -370,7 +370,7 @@ static void ar6000_free_cookie(AR_SOFTC_T *ar, struct ar_cookie * cookie); static struct ar_cookie *ar6000_alloc_cookie(AR_SOFTC_T *ar); #ifdef USER_KEYS -static A_STATUS ar6000_reinstall_keys(AR_SOFTC_T *ar,A_UINT8 key_op_ctrl); +static int ar6000_reinstall_keys(AR_SOFTC_T *ar,A_UINT8 key_op_ctrl); #endif #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT @@ -402,7 +402,7 @@ static struct net_device_ops ar6000_netdev_ops = { */ #define REPORT_DEBUG_LOGS_TO_APP -A_STATUS +int ar6000_set_host_app_area(AR_SOFTC_T *ar) { A_UINT32 address, data; @@ -430,7 +430,7 @@ dbglog_get_debug_hdr_ptr(AR_SOFTC_T *ar) { A_UINT32 param; A_UINT32 address; - A_STATUS status; + int status; address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbglog_hdr)); if ((status = ar6000_ReadDataDiag(ar->arHifDevice, address, @@ -633,7 +633,7 @@ static int __init ar6000_init_module(void) { static int probed = 0; - A_STATUS status; + int status; OSDRV_CALLBACKS osdrvCallbacks; a_module_debug_support_init(); @@ -741,7 +741,7 @@ aptcTimerHandler(unsigned long arg) A_UINT32 numbytes; A_UINT32 throughput; AR_SOFTC_T *ar; - A_STATUS status; + int status; ar = (AR_SOFTC_T *)arg; A_ASSERT(ar != NULL); @@ -852,10 +852,10 @@ ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj, return count; } -static A_STATUS +static int ar6000_sysfs_bmi_init(AR_SOFTC_T *ar) { - A_STATUS status; + int status; AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Creating sysfs entry\n")); A_MEMZERO(&ar->osDevInfo, sizeof(HIF_DEVICE_OS_DEVICE_INFO)); @@ -993,10 +993,10 @@ ar6000_softmac_update(AR_SOFTC_T *ar, A_UCHAR *eeprom_data, size_t size) } #endif /* SOFTMAC_FILE_USED */ -static A_STATUS +static int ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, A_BOOL compressed) { - A_STATUS status; + int status; const char *filename; const struct firmware *fw_entry; A_UINT32 fw_entry_size; @@ -1157,7 +1157,7 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, A } #endif /* INIT_MODE_DRV_ENABLED */ -A_STATUS +int ar6000_update_bdaddr(AR_SOFTC_T *ar) { @@ -1184,7 +1184,7 @@ ar6000_update_bdaddr(AR_SOFTC_T *ar) return A_OK; } -A_STATUS +int ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode) { AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Requesting device specific configuration\n")); @@ -1205,7 +1205,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode) #ifdef INIT_MODE_DRV_ENABLED } else { /* The config is contained within the driver itself */ - A_STATUS status; + int status; A_UINT32 param, options, sleep, address; /* Temporarily disable system sleep */ @@ -1399,7 +1399,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode) return A_OK; } -A_STATUS +int ar6000_configure_target(AR_SOFTC_T *ar) { A_UINT32 param; @@ -1595,7 +1595,7 @@ init_netdev(struct net_device *dev, char *name) /* * HTC Event handlers */ -static A_STATUS +static int ar6000_avail_ev(void *context, void *hif_handle) { int i; @@ -1607,7 +1607,7 @@ ar6000_avail_ev(void *context, void *hif_handle) #ifdef ATH6K_CONFIG_CFG80211 struct wireless_dev *wdev; #endif /* ATH6K_CONFIG_CFG80211 */ - A_STATUS init_status = A_OK; + int init_status = A_OK; AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_available\n")); @@ -1799,7 +1799,7 @@ ar6000_avail_ev(void *context, void *hif_handle) if ((wlaninitmode == WLAN_INIT_MODE_UDEV) || (wlaninitmode == WLAN_INIT_MODE_DRV)) { - A_STATUS status = A_OK; + int status = A_OK; do { if ((status = ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != A_OK) { @@ -1850,7 +1850,7 @@ avail_ev_failed : return init_status; } -static void ar6000_target_failure(void *Instance, A_STATUS Status) +static void ar6000_target_failure(void *Instance, int Status) { AR_SOFTC_T *ar = (AR_SOFTC_T *)Instance; WMI_TARGET_ERROR_REPORT_EVENT errEvent; @@ -1885,7 +1885,7 @@ static void ar6000_target_failure(void *Instance, A_STATUS Status) } } -static A_STATUS +static int ar6000_unavail_ev(void *context, void *hif_handle) { AR_SOFTC_T *ar = (AR_SOFTC_T *)context; @@ -1899,7 +1899,7 @@ ar6000_unavail_ev(void *context, void *hif_handle) void ar6000_restart_endpoint(struct net_device *dev) { - A_STATUS status = A_OK; + int status = A_OK; AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); BMIInit(); @@ -2015,7 +2015,7 @@ ar6000_stop_endpoint(struct net_device *dev, A_BOOL keepprofile, A_BOOL getdbglo // FIXME: workaround to reset BT's UART baud rate to default if (NULL != ar->exitCallback) { AR3K_CONFIG_INFO ar3kconfig; - A_STATUS status; + int status; A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig)); ar6000_set_default_ar3kconfig(ar, (void *)&ar3kconfig); @@ -2344,11 +2344,11 @@ ar6000_close(struct net_device *dev) } /* connect to a service */ -static A_STATUS ar6000_connectservice(AR_SOFTC_T *ar, +static int ar6000_connectservice(AR_SOFTC_T *ar, HTC_SERVICE_CONNECT_REQ *pConnect, char *pDesc) { - A_STATUS status; + int status; HTC_SERVICE_CONNECT_RESP response; do { @@ -2433,7 +2433,7 @@ ar6000_endpoint_id2_ac(void * devt, HTC_ENDPOINT_ID ep ) int ar6000_init(struct net_device *dev) { AR_SOFTC_T *ar; - A_STATUS status; + int status; A_INT32 timeleft; A_INT16 i; int ret = 0; @@ -2618,7 +2618,7 @@ int ar6000_init(struct net_device *dev) hciHandles.netDevice = ar->arNetDev; hciHandles.hifDevice = ar->arHifDevice; hciHandles.htcHandle = ar->arHtcTarget; - status = (A_STATUS)(ar6kHciTransCallbacks.setupTransport(&hciHandles)); + status = (int)(ar6kHciTransCallbacks.setupTransport(&hciHandles)); } #else if (setuphci) { @@ -3273,7 +3273,7 @@ applyAPTCHeuristics(AR_SOFTC_T *ar) A_UINT32 numbytes; A_UINT32 throughput; struct timeval ts; - A_STATUS status; + int status; AR6000_SPIN_LOCK(&ar->arLock, 0); @@ -3395,7 +3395,7 @@ ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPacketQueue) { AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; A_UINT32 mapNo = 0; - A_STATUS status; + int status; struct ar_cookie * ar_cookie; HTC_ENDPOINT_ID eid; A_BOOL wakeEvent = FALSE; @@ -3578,7 +3578,7 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) struct sk_buff *skb = (struct sk_buff *)pPacket->pPktContext; int minHdrLen; A_UINT8 containsDot11Hdr = 0; - A_STATUS status = pPacket->Status; + int status = pPacket->Status; HTC_ENDPOINT_ID ept = pPacket->Endpoint; A_ASSERT((status != A_OK) || @@ -4762,7 +4762,7 @@ ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd) void *osbuf = NULL; A_INT8 i; A_UINT8 size, *buf; - A_STATUS ret = A_OK; + int ret = A_OK; size = cmd->evt_buf_sz + 4; osbuf = A_NETBUF_ALLOC(size); @@ -4887,7 +4887,7 @@ ar6000_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, A_BOOL ismcast) } void -ar6000_scanComplete_event(AR_SOFTC_T *ar, A_STATUS status) +ar6000_scanComplete_event(AR_SOFTC_T *ar, int status) { #ifdef ATH6K_CONFIG_CFG80211 @@ -5267,11 +5267,11 @@ ar6000_bssInfo_event_rx(AR_SOFTC_T *ar, A_UINT8 *datap, int len) A_UINT32 wmiSendCmdNum; -A_STATUS +int ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid) { AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; - A_STATUS status = A_OK; + int status = A_OK; struct ar_cookie *cookie = NULL; int i; #ifdef CONFIG_PM @@ -5649,13 +5649,13 @@ a_copy_from_user(void *to, const void *from, A_UINT32 n) } -A_STATUS +int ar6000_get_driver_cfg(struct net_device *dev, A_UINT16 cfgParam, void *result) { - A_STATUS ret = 0; + int ret = 0; switch(cfgParam) { @@ -5958,11 +5958,11 @@ void ap_wapi_rekey_event(AR_SOFTC_T *ar, A_UINT8 type, A_UINT8 *mac) #endif #ifdef USER_KEYS -static A_STATUS +static int ar6000_reinstall_keys(AR_SOFTC_T *ar, A_UINT8 key_op_ctrl) { - A_STATUS status = A_OK; + int status = A_OK; struct ieee80211req_key *uik = &ar->user_saved_keys.ucast_ik; struct ieee80211req_key *bik = &ar->user_saved_keys.bcast_ik; CRYPTO_TYPE keyType = ar->user_saved_keys.keyType; @@ -6102,7 +6102,7 @@ ar6000_ap_mode_profile_commit(struct ar6_softc *ar) return 0; } -A_STATUS +int ar6000_connect_to_ap(struct ar6_softc *ar) { /* The ssid length check prevents second "essid off" from the user, @@ -6110,7 +6110,7 @@ ar6000_connect_to_ap(struct ar6_softc *ar) */ if((ar->arWmiReady == TRUE) && (ar->arSsidLen > 0) && ar->arNetworkType!=AP_NETWORK) { - A_STATUS status; + int status; if((ADHOC_NETWORK != ar->arNetworkType) && (NONE_AUTH==ar->arAuthMode) && (WEP_CRYPT==ar->arPairwiseCrypto)) { @@ -6173,7 +6173,7 @@ ar6000_connect_to_ap(struct ar6_softc *ar) return A_ERROR; } -A_STATUS +int ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie) { sta_t *conn = NULL; @@ -6189,7 +6189,7 @@ ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie return 0; } -A_STATUS +int is_iwioctl_allowed(A_UINT8 mode, A_UINT16 cmd) { if(cmd >= SIOCSIWCOMMIT && cmd <= SIOCGIWPOWER) { @@ -6206,7 +6206,7 @@ is_iwioctl_allowed(A_UINT8 mode, A_UINT16 cmd) return A_ENOTSUP; } -A_STATUS +int is_xioctl_allowed(A_UINT8 mode, int cmd) { if(sizeof(xioctl_filter)-1 < cmd) { @@ -6224,7 +6224,7 @@ ap_set_wapi_key(struct ar6_softc *ar, void *ikey) { struct ieee80211req_key *ik = (struct ieee80211req_key *)ikey; KEY_USAGE keyUsage = 0; - A_STATUS status; + int status; if (A_MEMCMP(ik->ik_macaddr, bcast_mac, IEEE80211_ADDR_LEN) == 0) { keyUsage = GROUP_USAGE; @@ -6345,7 +6345,7 @@ static void DoHTCSendPktsTest(AR_SOFTC_T *ar, int MapNo, HTC_ENDPOINT_ID eid, st * AP mode. */ -A_STATUS ar6000_start_ap_interface(AR_SOFTC_T *ar) +int ar6000_start_ap_interface(AR_SOFTC_T *ar) { AR_VIRTUAL_INTERFACE_T *arApDev; @@ -6356,7 +6356,7 @@ A_STATUS ar6000_start_ap_interface(AR_SOFTC_T *ar) return A_OK; } -A_STATUS ar6000_stop_ap_interface(AR_SOFTC_T *ar) +int ar6000_stop_ap_interface(AR_SOFTC_T *ar) { AR_VIRTUAL_INTERFACE_T *arApDev; @@ -6370,7 +6370,7 @@ A_STATUS ar6000_stop_ap_interface(AR_SOFTC_T *ar) } -A_STATUS ar6000_create_ap_interface(AR_SOFTC_T *ar, char *ap_ifname) +int ar6000_create_ap_interface(AR_SOFTC_T *ar, char *ap_ifname) { struct net_device *dev; AR_VIRTUAL_INTERFACE_T *arApDev; @@ -6403,7 +6403,7 @@ A_STATUS ar6000_create_ap_interface(AR_SOFTC_T *ar, char *ap_ifname) return A_OK; } -A_STATUS ar6000_add_ap_interface(AR_SOFTC_T *ar, char *ap_ifname) +int ar6000_add_ap_interface(AR_SOFTC_T *ar, char *ap_ifname) { /* Interface already added, need not proceed further */ if (ar->arApDev != NULL) { @@ -6420,7 +6420,7 @@ A_STATUS ar6000_add_ap_interface(AR_SOFTC_T *ar, char *ap_ifname) return ar6000_start_ap_interface(ar); } -A_STATUS ar6000_remove_ap_interface(AR_SOFTC_T *ar) +int ar6000_remove_ap_interface(AR_SOFTC_T *ar) { if (arApNetDev) { ar6000_stop_ap_interface(ar); diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c index 13195d4c7427..fbac26429d84 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_pm.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_pm.c @@ -57,7 +57,7 @@ ATH_DEBUG_INSTANTIATE_MODULE_VAR(pm, #endif /* DEBUG */ -A_STATUS ar6000_exit_cut_power_state(AR_SOFTC_T *ar); +int ar6000_exit_cut_power_state(AR_SOFTC_T *ar); #ifdef CONFIG_PM static void ar6k_send_asleep_event_to_app(AR_SOFTC_T *ar, A_BOOL asleep) @@ -122,7 +122,7 @@ static void ar6000_wow_suspend(AR_SOFTC_T *ar) struct in_ifaddr *ifa = NULL; struct in_device *in_dev; A_UINT8 macMask[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - A_STATUS status; + int status; WMI_ADD_WOW_PATTERN_CMD addWowCmd = { .filter = { 0 } }; WMI_DEL_WOW_PATTERN_CMD delWowCmd; WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {FALSE, TRUE}; @@ -211,9 +211,9 @@ static void ar6000_wow_suspend(AR_SOFTC_T *ar) } } -A_STATUS ar6000_suspend_ev(void *context) +int ar6000_suspend_ev(void *context) { - A_STATUS status = A_OK; + int status = A_OK; AR_SOFTC_T *ar = (AR_SOFTC_T *)context; A_INT16 pmmode = ar->arSuspendConfig; wow_not_connected: @@ -248,7 +248,7 @@ wow_not_connected: return status; } -A_STATUS ar6000_resume_ev(void *context) +int ar6000_resume_ev(void *context) { AR_SOFTC_T *ar = (AR_SOFTC_T *)context; A_UINT16 powerState = ar->arWlanPowerState; @@ -290,10 +290,10 @@ void ar6000_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, A_BOOL isEvent } } -A_STATUS ar6000_power_change_ev(void *context, A_UINT32 config) +int ar6000_power_change_ev(void *context, A_UINT32 config) { AR_SOFTC_T *ar = (AR_SOFTC_T *)context; - A_STATUS status = A_OK; + int status = A_OK; AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: power change event callback %d \n", __func__, config)); switch (config) { @@ -342,10 +342,10 @@ static struct platform_driver ar6000_pm_device = { }; #endif /* CONFIG_PM */ -A_STATUS +int ar6000_setup_cut_power_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) { - A_STATUS status = A_OK; + int status = A_OK; HIF_DEVICE_POWER_CHANGE_TYPE config; AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: Cut power %d %d \n", __func__,state, ar->arWlanPowerState)); @@ -412,10 +412,10 @@ ar6000_setup_cut_power_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) return status; } -A_STATUS +int ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) { - A_STATUS status = A_OK; + int status = A_OK; AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: Deep sleep %d %d \n", __func__,state, ar->arWlanPowerState)); #ifdef CONFIG_PM @@ -536,10 +536,10 @@ ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) return status; } -A_STATUS +int ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, A_BOOL pmEvent) { - A_STATUS status = A_OK; + int status = A_OK; A_UINT16 powerState, oldPowerState; AR6000_WLAN_STATE oldstate = ar->arWlanState; A_BOOL wlanOff = ar->arWlanOff; @@ -650,12 +650,12 @@ ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, A_BO return status; } -A_STATUS +int ar6000_set_bt_hw_state(struct ar6_softc *ar, A_UINT32 enable) { #ifdef CONFIG_PM A_BOOL off = (enable == 0); - A_STATUS status; + int status; if (ar->arBTOff == off) { return A_OK; } @@ -667,10 +667,10 @@ ar6000_set_bt_hw_state(struct ar6_softc *ar, A_UINT32 enable) #endif } -A_STATUS +int ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) { - A_STATUS status; + int status; A_BOOL off = (state == WLAN_DISABLED); if (ar->arWlanOff == off) { return A_OK; diff --git a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c index 6b8eeea475cf..10f48851dc58 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c @@ -111,10 +111,10 @@ ar6000_htc_raw_write_cb(void *Context, HTC_PACKET *pPacket) } /* connect to a service */ -static A_STATUS ar6000_connect_raw_service(AR_SOFTC_T *ar, +static int ar6000_connect_raw_service(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID) { - A_STATUS status; + int status; HTC_SERVICE_CONNECT_RESP response; A_UINT8 streamNo; HTC_SERVICE_CONNECT_REQ connect; @@ -168,7 +168,7 @@ static A_STATUS ar6000_connect_raw_service(AR_SOFTC_T *ar, int ar6000_htc_raw_open(AR_SOFTC_T *ar) { - A_STATUS status; + int status; int streamID, endPt, count2; raw_htc_buffer *buffer; HTC_SERVICE_ID servicepriority; diff --git a/drivers/staging/ath6kl/os/linux/ar6k_pal.c b/drivers/staging/ath6kl/os/linux/ar6k_pal.c index 6c98a8817aed..10ee89ef782b 100644 --- a/drivers/staging/ath6kl/os/linux/ar6k_pal.c +++ b/drivers/staging/ath6kl/os/linux/ar6k_pal.c @@ -120,7 +120,7 @@ static int btpal_send_frame(struct sk_buff *skb) struct hci_dev *hdev = (struct hci_dev *)skb->dev; HCI_TRANSPORT_PACKET_TYPE type; ar6k_hci_pal_info_t *pHciPalInfo; - A_STATUS status = A_OK; + int status = A_OK; struct sk_buff *txSkb = NULL; AR_SOFTC_T *ar; @@ -269,9 +269,9 @@ static void bt_cleanup_hci_pal(ar6k_hci_pal_info_t *pHciPalInfo) /********************************************************* * Allocate HCI device and store in PAL private info structure. *********************************************************/ -static A_STATUS bt_setup_hci_pal(ar6k_hci_pal_info_t *pHciPalInfo) +static int bt_setup_hci_pal(ar6k_hci_pal_info_t *pHciPalInfo) { - A_STATUS status = A_OK; + int status = A_OK; struct hci_dev *pHciDev = NULL; if (!setupbtdev) { @@ -402,9 +402,9 @@ A_BOOL ar6k_pal_recv_pkt(void *pHciPal, void *osbuf) * Registers a HCI device. * Registers packet receive callback function with ar6k **********************************************************/ -A_STATUS ar6k_setup_hci_pal(void *ar_p) +int ar6k_setup_hci_pal(void *ar_p) { - A_STATUS status = A_OK; + int status = A_OK; ar6k_hci_pal_info_t *pHciPalInfo; ar6k_pal_config_t ar6k_pal_config; AR_SOFTC_T *ar = (AR_SOFTC_T *)ar_p; @@ -443,7 +443,7 @@ A_STATUS ar6k_setup_hci_pal(void *ar_p) return status; } #else /* AR6K_ENABLE_HCI_PAL */ -A_STATUS ar6k_setup_hci_pal(void *ar_p) +int ar6k_setup_hci_pal(void *ar_p) { return A_OK; } @@ -457,7 +457,7 @@ void ar6k_cleanup_hci_pal(void *ar_p) * Register init and callback function with ar6k * when PAL driver is a separate kernel module. ****************************************************/ -A_STATUS ar6k_register_hci_pal(HCI_TRANSPORT_CALLBACKS *hciTransCallbacks); +int ar6k_register_hci_pal(HCI_TRANSPORT_CALLBACKS *hciTransCallbacks); static int __init pal_init_module(void) { HCI_TRANSPORT_CALLBACKS hciTransCallbacks; diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index cbd9d55a2933..e3dc99ae07f2 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -245,7 +245,7 @@ ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) { AR_SOFTC_T *ar = ar6k_priv(dev); - A_STATUS status; + int status; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); @@ -780,7 +780,7 @@ ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, } void -ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, A_STATUS status) +ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, int status) { AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status)); @@ -815,7 +815,7 @@ ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, struct ar_key *key = NULL; A_UINT8 key_usage; A_UINT8 key_type; - A_STATUS status = 0; + int status = 0; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s:\n", __func__)); @@ -982,7 +982,7 @@ ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); struct ar_key *key = NULL; - A_STATUS status = A_OK; + int status = A_OK; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index)); @@ -1269,7 +1269,7 @@ ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *ibss_param) { AR_SOFTC_T *ar = ar6k_priv(dev); - A_STATUS status; + int status; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); diff --git a/drivers/staging/ath6kl/os/linux/export_hci_transport.c b/drivers/staging/ath6kl/os/linux/export_hci_transport.c index ffbf3d229a5e..03f4567eafcf 100644 --- a/drivers/staging/ath6kl/os/linux/export_hci_transport.c +++ b/drivers/staging/ath6kl/os/linux/export_hci_transport.c @@ -38,20 +38,20 @@ HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, HCI_TRANSPORT_CONFIG_INFO *pInfo); void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans); -A_STATUS (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue); -A_STATUS (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, A_BOOL Synchronous); +int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue); +int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, A_BOOL Synchronous); void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans); -A_STATUS (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans); -A_STATUS (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable); -A_STATUS (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans, +int (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans); +int (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable); +int (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, int MaxPollMS); -A_STATUS (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud); -A_STATUS (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable); +int (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud); +int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable); extern HCI_TRANSPORT_CALLBACKS ar6kHciTransCallbacks; -A_STATUS ar6000_register_hci_transport(HCI_TRANSPORT_CALLBACKS *hciTransCallbacks) +int ar6000_register_hci_transport(HCI_TRANSPORT_CALLBACKS *hciTransCallbacks) { ar6kHciTransCallbacks = *hciTransCallbacks; @@ -69,10 +69,10 @@ A_STATUS ar6000_register_hci_transport(HCI_TRANSPORT_CALLBACKS *hciTransCallback return A_OK; } -A_STATUS +int ar6000_get_hif_dev(HIF_DEVICE *device, void *config) { - A_STATUS status; + int status; status = HIFConfigureDevice(device, HIF_DEVICE_GET_OS_DEVICE, @@ -81,13 +81,13 @@ ar6000_get_hif_dev(HIF_DEVICE *device, void *config) return status; } -A_STATUS ar6000_set_uart_config(HIF_DEVICE *hifDevice, +int ar6000_set_uart_config(HIF_DEVICE *hifDevice, A_UINT32 scale, A_UINT32 step) { A_UINT32 regAddress; A_UINT32 regVal; - A_STATUS status; + int status; regAddress = WLAN_UART_BASE_ADDRESS | UART_CLKDIV_ADDRESS; regVal = ((A_UINT32)scale << 16) | step; @@ -97,10 +97,10 @@ A_STATUS ar6000_set_uart_config(HIF_DEVICE *hifDevice, return status; } -A_STATUS ar6000_get_core_clock_config(HIF_DEVICE *hifDevice, A_UINT32 *data) +int ar6000_get_core_clock_config(HIF_DEVICE *hifDevice, A_UINT32 *data) { A_UINT32 regAddress; - A_STATUS status; + int status; regAddress = WLAN_RTC_BASE_ADDRESS | WLAN_CPU_CLOCK_ADDRESS; /* read CPU clock settings*/ diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index 5cdc3b85a6f6..c7e0b4e87317 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -106,9 +106,9 @@ AR3K_CONFIG_INFO ar3kconfig; AR6K_HCI_BRIDGE_INFO *g_pHcidevInfo; #endif -static A_STATUS bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo); +static int bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo); static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo); -static A_STATUS bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo); +static int bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo); static A_BOOL bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, HCI_TRANSPORT_PACKET_TYPE Type, struct sk_buff *skb); @@ -116,14 +116,14 @@ static struct sk_buff *bt_alloc_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, int Le static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, struct sk_buff *skb); #ifdef EXPORT_HCI_BRIDGE_INTERFACE -A_STATUS ar6000_setup_hci(void *ar); +int ar6000_setup_hci(void *ar); void ar6000_cleanup_hci(void *ar); -A_STATUS hci_test_send(void *ar, struct sk_buff *skb); +int hci_test_send(void *ar, struct sk_buff *skb); #else -A_STATUS ar6000_setup_hci(AR_SOFTC_T *ar); +int ar6000_setup_hci(AR_SOFTC_T *ar); void ar6000_cleanup_hci(AR_SOFTC_T *ar); /* HCI bridge testing */ -A_STATUS hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb); +int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb); #endif /* EXPORT_HCI_BRIDGE_INTERFACE */ #define LOCK_BRIDGE(dev) spin_lock_bh(&(dev)->BridgeLock) @@ -215,12 +215,12 @@ static void RefillRecvBuffers(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, #define HOST_INTEREST_ITEM_ADDRESS(ar, item) \ (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \ (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0)) -static A_STATUS ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle, +static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle, HCI_TRANSPORT_PROPERTIES *pProps, void *pContext) { AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext; - A_STATUS status; + int status; A_UINT32 address, hci_uart_pwr_mgmt_params; // AR3K_CONFIG_INFO ar3kconfig; @@ -323,7 +323,7 @@ static A_STATUS ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle, return status; } -static void ar6000_hci_transport_failure(void *pContext, A_STATUS Status) +static void ar6000_hci_transport_failure(void *pContext, int Status) { AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext; @@ -464,13 +464,13 @@ static HCI_SEND_FULL_ACTION ar6000_hci_pkt_send_full(void *pContext, HTC_PACKET } #ifdef EXPORT_HCI_BRIDGE_INTERFACE -A_STATUS ar6000_setup_hci(void *ar) +int ar6000_setup_hci(void *ar) #else -A_STATUS ar6000_setup_hci(AR_SOFTC_T *ar) +int ar6000_setup_hci(AR_SOFTC_T *ar) #endif { HCI_TRANSPORT_CONFIG_INFO config; - A_STATUS status = A_OK; + int status = A_OK; int i; HTC_PACKET *pPacket; AR6K_HCI_BRIDGE_INFO *pHcidevInfo; @@ -596,9 +596,9 @@ void ar6000_cleanup_hci(AR_SOFTC_T *ar) } #ifdef EXPORT_HCI_BRIDGE_INTERFACE -A_STATUS hci_test_send(void *ar, struct sk_buff *skb) +int hci_test_send(void *ar, struct sk_buff *skb) #else -A_STATUS hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb) +int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb) #endif { int status = A_OK; @@ -712,7 +712,7 @@ static int bt_send_frame(struct sk_buff *skb) HCI_TRANSPORT_PACKET_TYPE type; AR6K_HCI_BRIDGE_INFO *pHcidevInfo; HTC_PACKET *pPacket; - A_STATUS status = A_OK; + int status = A_OK; struct sk_buff *txSkb = NULL; if (!hdev) { @@ -853,9 +853,9 @@ static void bt_destruct(struct hci_dev *hdev) /* nothing to do here */ } -static A_STATUS bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) +static int bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) { - A_STATUS status = A_OK; + int status = A_OK; struct hci_dev *pHciDev = NULL; HIF_DEVICE_OS_DEVICE_INFO osDevInfo; @@ -935,10 +935,10 @@ static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) } } -static A_STATUS bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) +static int bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) { int err; - A_STATUS status = A_OK; + int status = A_OK; do { AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: registering HCI... \n")); @@ -1041,7 +1041,7 @@ static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, struct sk_buff *sk #else // { CONFIG_BLUEZ_HCI_BRIDGE /* stubs when we only want to test the HCI bridging Interface without the HT stack */ -static A_STATUS bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) +static int bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) { return A_OK; } @@ -1049,7 +1049,7 @@ static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) { } -static A_STATUS bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) +static int bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) { A_ASSERT(FALSE); return A_ERROR; @@ -1080,9 +1080,9 @@ static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, struct sk_buff *sk /* stubs when GMBOX support is not needed */ #ifdef EXPORT_HCI_BRIDGE_INTERFACE -A_STATUS ar6000_setup_hci(void *ar) +int ar6000_setup_hci(void *ar) #else -A_STATUS ar6000_setup_hci(AR_SOFTC_T *ar) +int ar6000_setup_hci(AR_SOFTC_T *ar) #endif { return A_OK; @@ -1120,7 +1120,7 @@ int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb) static int __init hcibridge_init_module(void) { - A_STATUS status; + int status; HCI_TRANSPORT_CALLBACKS hciTransCallbacks; hciTransCallbacks.setupTransport = ar6000_setup_hci; diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index e6248830b7ef..0dee74a17978 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -121,8 +121,8 @@ struct USER_SAVEDKEYS { #define DBG_DEFAULTS (DBG_ERROR|DBG_WARNING) -A_STATUS ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); -A_STATUS ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); +int ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); +int ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); #ifdef __cplusplus extern "C" { @@ -737,12 +737,12 @@ remove_sta(AR_SOFTC_T *ar, A_UINT8 *mac, A_UINT16 reason); /* HCI support */ #ifndef EXPORT_HCI_BRIDGE_INTERFACE -A_STATUS ar6000_setup_hci(AR_SOFTC_T *ar); +int ar6000_setup_hci(AR_SOFTC_T *ar); void ar6000_cleanup_hci(AR_SOFTC_T *ar); void ar6000_set_default_ar3kconfig(AR_SOFTC_T *ar, void *ar3kconfig); /* HCI bridge testing */ -A_STATUS hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb); +int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb); #endif ATH_DEBUG_DECLARE_EXTERN(htc); diff --git a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h index ea2d181dcfe2..29fac6bad83a 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h @@ -31,7 +31,7 @@ struct ar6_softc; void ar6000_ready_event(void *devt, A_UINT8 *datap, A_UINT8 phyCap, A_UINT32 sw_ver, A_UINT32 abi_ver); -A_STATUS ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid); +int ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid); void ar6000_connect_event(struct ar6_softc *ar, A_UINT16 channel, A_UINT8 *bssid, A_UINT16 listenInterval, A_UINT16 beaconInterval, NETWORK_TYPE networkType, @@ -50,7 +50,7 @@ void ar6000_keepalive_rx(void *devt, A_UINT8 configured); void ar6000_neighborReport_event(struct ar6_softc *ar, int numAps, WMI_NEIGHBOR_INFO *info); void ar6000_set_numdataendpts(struct ar6_softc *ar, A_UINT32 num); -void ar6000_scanComplete_event(struct ar6_softc *ar, A_STATUS status); +void ar6000_scanComplete_event(struct ar6_softc *ar, int status); void ar6000_targetStats_event(struct ar6_softc *ar, A_UINT8 *ptr, A_UINT32 len); void ar6000_rssiThreshold_event(struct ar6_softc *ar, WMI_RSSI_THRESHOLD_VAL newThreshold, @@ -103,7 +103,7 @@ void ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL range, A_UINT8 void ar6000_ratemask_rx(void *devt, A_UINT32 ratemask); -A_STATUS ar6000_get_driver_cfg(struct net_device *dev, +int ar6000_get_driver_cfg(struct net_device *dev, A_UINT16 cfgParam, void *result); void ar6000_bssInfo_event_rx(struct ar6_softc *ar, A_UINT8 *data, int len); @@ -149,12 +149,12 @@ A_UINT32 ar6000_getclkfreq (void); int ar6000_ap_mode_profile_commit(struct ar6_softc *ar); struct ieee80211req_wpaie; -A_STATUS +int ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie); -A_STATUS is_iwioctl_allowed(A_UINT8 mode, A_UINT16 cmd); +int is_iwioctl_allowed(A_UINT8 mode, A_UINT16 cmd); -A_STATUS is_xioctl_allowed(A_UINT8 mode, int cmd); +int is_xioctl_allowed(A_UINT8 mode, int cmd); void ar6000_pspoll_event(struct ar6_softc *ar,A_UINT8 aid); @@ -170,15 +170,15 @@ int ap_set_wapi_key(struct ar6_softc *ar, void *ik); void ap_wapi_rekey_event(struct ar6_softc *ar, A_UINT8 type, A_UINT8 *mac); #endif -A_STATUS ar6000_connect_to_ap(struct ar6_softc *ar); -A_STATUS ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, A_BOOL suspending); -A_STATUS ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state); -A_STATUS ar6000_set_bt_hw_state(struct ar6_softc *ar, A_UINT32 state); +int ar6000_connect_to_ap(struct ar6_softc *ar); +int ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, A_BOOL suspending); +int ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state); +int ar6000_set_bt_hw_state(struct ar6_softc *ar, A_UINT32 state); #ifdef CONFIG_PM -A_STATUS ar6000_suspend_ev(void *context); -A_STATUS ar6000_resume_ev(void *context); -A_STATUS ar6000_power_change_ev(void *context, A_UINT32 config); +int ar6000_suspend_ev(void *context); +int ar6000_resume_ev(void *context); +int ar6000_power_change_ev(void *context, A_UINT32 config); void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, A_BOOL isEvent); #endif @@ -186,8 +186,8 @@ void ar6000_pm_init(void); void ar6000_pm_exit(void); #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT -A_STATUS ar6000_add_ap_interface(struct ar6_softc *ar, char *ifname); -A_STATUS ar6000_remove_ap_interface(struct ar6_softc *ar); +int ar6000_add_ap_interface(struct ar6_softc *ar, char *ifname); +int ar6000_remove_ap_interface(struct ar6_softc *ar); #endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */ #ifdef __cplusplus diff --git a/drivers/staging/ath6kl/os/linux/include/cfg80211.h b/drivers/staging/ath6kl/os/linux/include/cfg80211.h index b60e8acf4931..4494410972fb 100644 --- a/drivers/staging/ath6kl/os/linux/include/cfg80211.h +++ b/drivers/staging/ath6kl/os/linux/include/cfg80211.h @@ -27,7 +27,7 @@ struct wireless_dev *ar6k_cfg80211_init(struct device *dev); void ar6k_cfg80211_deinit(AR_SOFTC_T *ar); -void ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, A_STATUS status); +void ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, int status); void ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, A_UINT8 *bssid, A_UINT16 listenInterval, diff --git a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h index c1506805a4d5..49a5d3fece48 100644 --- a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h +++ b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h @@ -27,16 +27,16 @@ extern HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, HCI_TRANSPORT_CONFIG_INFO *pInfo); extern void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans); -extern A_STATUS (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue); -extern A_STATUS (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, A_BOOL Synchronous); +extern int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue); +extern int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, A_BOOL Synchronous); extern void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans); -extern A_STATUS (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans); -extern A_STATUS (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable); -extern A_STATUS (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans, +extern int (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans); +extern int (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable); +extern int (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, int MaxPollMS); -extern A_STATUS (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud); -extern A_STATUS (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable); +extern int (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud); +extern int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable); #define HCI_TransportAttach(HTCHandle, pInfo) \ @@ -61,11 +61,11 @@ extern A_STATUS (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTran _HCI_TransportEnablePowerMgmt((HciTrans), (Enable)) -extern A_STATUS ar6000_register_hci_transport(HCI_TRANSPORT_CALLBACKS *hciTransCallbacks); +extern int ar6000_register_hci_transport(HCI_TRANSPORT_CALLBACKS *hciTransCallbacks); -extern A_STATUS ar6000_get_hif_dev(HIF_DEVICE *device, void *config); +extern int ar6000_get_hif_dev(HIF_DEVICE *device, void *config); -extern A_STATUS ar6000_set_uart_config(HIF_DEVICE *hifDevice, A_UINT32 scale, A_UINT32 step); +extern int ar6000_set_uart_config(HIF_DEVICE *hifDevice, A_UINT32 scale, A_UINT32 step); /* get core clock register settings * data: 0 - 40/44MHz @@ -73,4 +73,4 @@ extern A_STATUS ar6000_set_uart_config(HIF_DEVICE *hifDevice, A_UINT32 scale, A_ * where (5G band/2.4G band) * assume 2.4G band for now */ -extern A_STATUS ar6000_get_core_clock_config(HIF_DEVICE *hifDevice, A_UINT32 *data); +extern int ar6000_get_core_clock_config(HIF_DEVICE *hifDevice, A_UINT32 *data); diff --git a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h index fce6ceb73fa4..a1dd02404003 100644 --- a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h @@ -307,15 +307,15 @@ void *a_netbuf_alloc_raw(int size); void a_netbuf_free(void *bufPtr); void *a_netbuf_to_data(void *bufPtr); A_UINT32 a_netbuf_to_len(void *bufPtr); -A_STATUS a_netbuf_push(void *bufPtr, A_INT32 len); -A_STATUS a_netbuf_push_data(void *bufPtr, char *srcPtr, A_INT32 len); -A_STATUS a_netbuf_put(void *bufPtr, A_INT32 len); -A_STATUS a_netbuf_put_data(void *bufPtr, char *srcPtr, A_INT32 len); -A_STATUS a_netbuf_pull(void *bufPtr, A_INT32 len); -A_STATUS a_netbuf_pull_data(void *bufPtr, char *dstPtr, A_INT32 len); -A_STATUS a_netbuf_trim(void *bufPtr, A_INT32 len); -A_STATUS a_netbuf_trim_data(void *bufPtr, char *dstPtr, A_INT32 len); -A_STATUS a_netbuf_setlen(void *bufPtr, A_INT32 len); +int a_netbuf_push(void *bufPtr, A_INT32 len); +int a_netbuf_push_data(void *bufPtr, char *srcPtr, A_INT32 len); +int a_netbuf_put(void *bufPtr, A_INT32 len); +int a_netbuf_put_data(void *bufPtr, char *srcPtr, A_INT32 len); +int a_netbuf_pull(void *bufPtr, A_INT32 len); +int a_netbuf_pull_data(void *bufPtr, char *dstPtr, A_INT32 len); +int a_netbuf_trim(void *bufPtr, A_INT32 len); +int a_netbuf_trim_data(void *bufPtr, char *dstPtr, A_INT32 len); +int a_netbuf_setlen(void *bufPtr, A_INT32 len); A_INT32 a_netbuf_headroom(void *bufPtr); void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt); void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt); diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index 0b10376fad2d..a159ae59add1 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -136,7 +136,7 @@ ar6000_ioctl_set_qos_supp(struct net_device *dev, struct ifreq *rq) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_SET_QOS_SUPP_CMD cmd; - A_STATUS ret; + int ret; if ((dev->flags & IFF_UP) != IFF_UP) { return -EIO; @@ -171,7 +171,7 @@ ar6000_ioctl_set_wmm(struct net_device *dev, struct ifreq *rq) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_SET_WMM_CMD cmd; - A_STATUS ret; + int ret; if ((dev->flags & IFF_UP) != IFF_UP) { return -EIO; @@ -212,7 +212,7 @@ ar6000_ioctl_set_txop(struct net_device *dev, struct ifreq *rq) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_SET_WMM_TXOP_CMD cmd; - A_STATUS ret; + int ret; if ((dev->flags & IFF_UP) != IFF_UP) { return -EIO; @@ -246,7 +246,7 @@ static int ar6000_ioctl_get_rd(struct net_device *dev, struct ifreq *rq) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - A_STATUS ret = 0; + int ret = 0; if ((dev->flags & IFF_UP) != IFF_UP || ar->arWmiReady == FALSE) { return -EIO; @@ -264,7 +264,7 @@ ar6000_ioctl_set_country(struct net_device *dev, struct ifreq *rq) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_AP_SET_COUNTRY_CMD cmd; - A_STATUS ret; + int ret; if ((dev->flags & IFF_UP) != IFF_UP) { return -EIO; @@ -577,7 +577,7 @@ ar6000_ioctl_create_qos(struct net_device *dev, struct ifreq *rq) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_CREATE_PSTREAM_CMD cmd; - A_STATUS ret; + int ret; if (ar->arWmiReady == FALSE) { return -EIO; @@ -662,7 +662,7 @@ ar6000_ioctl_get_qos_queue(struct net_device *dev, struct ifreq *rq) } #ifdef CONFIG_HOST_TCMD_SUPPORT -static A_STATUS +static int ar6000_ioctl_tcmd_get_rx_report(struct net_device *dev, struct ifreq *rq, A_UINT8 *data, A_UINT32 len) { @@ -1386,7 +1386,7 @@ ar6000_gpio_ack_rx(void) wake_up(&arEvent); } -A_STATUS +int ar6000_gpio_output_set(struct net_device *dev, A_UINT32 set_mask, A_UINT32 clear_mask, @@ -1400,7 +1400,7 @@ ar6000_gpio_output_set(struct net_device *dev, set_mask, clear_mask, enable_mask, disable_mask); } -static A_STATUS +static int ar6000_gpio_input_get(struct net_device *dev) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); @@ -1409,7 +1409,7 @@ ar6000_gpio_input_get(struct net_device *dev) return wmi_gpio_input_get(ar->arWmi); } -static A_STATUS +static int ar6000_gpio_register_set(struct net_device *dev, A_UINT32 gpioreg_id, A_UINT32 value) @@ -1420,7 +1420,7 @@ ar6000_gpio_register_set(struct net_device *dev, return wmi_gpio_register_set(ar->arWmi, gpioreg_id, value); } -static A_STATUS +static int ar6000_gpio_register_get(struct net_device *dev, A_UINT32 gpioreg_id) { @@ -1430,7 +1430,7 @@ ar6000_gpio_register_get(struct net_device *dev, return wmi_gpio_register_get(ar->arWmi, gpioreg_id); } -static A_STATUS +static int ar6000_gpio_intr_ack(struct net_device *dev, A_UINT32 ack_mask) { @@ -1445,7 +1445,7 @@ ar6000_gpio_intr_ack(struct net_device *dev, static struct prof_count_s prof_count_results; static A_BOOL prof_count_available; /* Requested GPIO data available */ -static A_STATUS +static int prof_count_get(struct net_device *dev) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); @@ -1469,14 +1469,14 @@ prof_count_rx(A_UINT32 addr, A_UINT32 count) #endif /* CONFIG_TARGET_PROFILE_SUPPORT */ -static A_STATUS +static int ar6000_create_acl_data_osbuf(struct net_device *dev, A_UINT8 *userdata, void **p_osbuf) { void *osbuf = NULL; A_UINT8 tmp_space[8]; HCI_ACL_DATA_PKT *acl; A_UINT8 hdr_size, *datap=NULL; - A_STATUS ret = A_OK; + int ret = A_OK; /* ACL is in data path. There is a need to create pool * mechanism for allocating and freeing NETBUFs - ToDo later. @@ -1739,7 +1739,7 @@ int ar6000_ioctl_setkey(AR_SOFTC_T *ar, struct ieee80211req_key *ik) { KEY_USAGE keyUsage; - A_STATUS status; + int status; CRYPTO_TYPE keyType = NONE_CRYPT; #ifdef USER_KEYS @@ -1885,7 +1885,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) goto ioctl_done; } } else { - A_STATUS ret = is_iwioctl_allowed(ar->arNextMode, cmd); + int ret = is_iwioctl_allowed(ar->arNextMode, cmd); if(ret == A_ENOTSUP) { A_PRINTF("iwioctl: cmd=0x%x not allowed in this mode\n", cmd); ret = -EOPNOTSUPP; @@ -1994,7 +1994,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } else if (copy_from_user(&req, userdata, sizeof(struct ieee80211req_addpmkid))) { ret = -EFAULT; } else { - A_STATUS status; + int status; AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("Add pmkid for %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x en=%d\n", req.pi_bssid[0], req.pi_bssid[1], req.pi_bssid[2], @@ -3365,7 +3365,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_WMI_SETFIXRATES: { WMI_FIX_RATES_CMD setFixRatesCmd; - A_STATUS returnStatus; + int returnStatus; if (ar->arWmiReady == FALSE) { ret = -EIO; diff --git a/drivers/staging/ath6kl/os/linux/netbuf.c b/drivers/staging/ath6kl/os/linux/netbuf.c index 15e5d0475202..31848d74a21e 100644 --- a/drivers/staging/ath6kl/os/linux/netbuf.c +++ b/drivers/staging/ath6kl/os/linux/netbuf.c @@ -105,7 +105,7 @@ a_netbuf_to_data(void *bufPtr) * Add len # of bytes to the beginning of the network buffer * pointed to by bufPtr */ -A_STATUS +int a_netbuf_push(void *bufPtr, A_INT32 len) { skb_push((struct sk_buff *)bufPtr, len); @@ -117,7 +117,7 @@ a_netbuf_push(void *bufPtr, A_INT32 len) * Add len # of bytes to the beginning of the network buffer * pointed to by bufPtr and also fill with data */ -A_STATUS +int a_netbuf_push_data(void *bufPtr, char *srcPtr, A_INT32 len) { skb_push((struct sk_buff *) bufPtr, len); @@ -130,7 +130,7 @@ a_netbuf_push_data(void *bufPtr, char *srcPtr, A_INT32 len) * Add len # of bytes to the end of the network buffer * pointed to by bufPtr */ -A_STATUS +int a_netbuf_put(void *bufPtr, A_INT32 len) { skb_put((struct sk_buff *)bufPtr, len); @@ -142,7 +142,7 @@ a_netbuf_put(void *bufPtr, A_INT32 len) * Add len # of bytes to the end of the network buffer * pointed to by bufPtr and also fill with data */ -A_STATUS +int a_netbuf_put_data(void *bufPtr, char *srcPtr, A_INT32 len) { char *start = (char*)(((struct sk_buff *)bufPtr)->data + @@ -157,7 +157,7 @@ a_netbuf_put_data(void *bufPtr, char *srcPtr, A_INT32 len) /* * Trim the network buffer pointed to by bufPtr to len # of bytes */ -A_STATUS +int a_netbuf_setlen(void *bufPtr, A_INT32 len) { skb_trim((struct sk_buff *)bufPtr, len); @@ -168,7 +168,7 @@ a_netbuf_setlen(void *bufPtr, A_INT32 len) /* * Chop of len # of bytes from the end of the buffer. */ -A_STATUS +int a_netbuf_trim(void *bufPtr, A_INT32 len) { skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len); @@ -179,7 +179,7 @@ a_netbuf_trim(void *bufPtr, A_INT32 len) /* * Chop of len # of bytes from the end of the buffer and return the data. */ -A_STATUS +int a_netbuf_trim_data(void *bufPtr, char *dstPtr, A_INT32 len) { char *start = (char*)(((struct sk_buff *)bufPtr)->data + @@ -204,7 +204,7 @@ a_netbuf_headroom(void *bufPtr) /* * Removes specified number of bytes from the beginning of the buffer */ -A_STATUS +int a_netbuf_pull(void *bufPtr, A_INT32 len) { skb_pull((struct sk_buff *)bufPtr, len); @@ -216,7 +216,7 @@ a_netbuf_pull(void *bufPtr, A_INT32 len) * Removes specified number of bytes from the beginning of the buffer * and return the data */ -A_STATUS +int a_netbuf_pull_data(void *bufPtr, char *dstPtr, A_INT32 len) { A_MEMCPY(dstPtr, ((struct sk_buff *)bufPtr)->data, len); diff --git a/drivers/staging/ath6kl/os/linux/wireless_ext.c b/drivers/staging/ath6kl/os/linux/wireless_ext.c index bb6de0f404fe..dc32e2d4bb02 100644 --- a/drivers/staging/ath6kl/os/linux/wireless_ext.c +++ b/drivers/staging/ath6kl/os/linux/wireless_ext.c @@ -463,7 +463,7 @@ ar6000_ioctl_siwessid(struct net_device *dev, struct iw_point *data, char *ssid) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - A_STATUS status; + int status; A_UINT8 arNetworkType; A_UINT8 prevMode = ar->arNetworkType; @@ -1548,7 +1548,7 @@ ar6000_ioctl_siwpmksa(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); A_INT32 ret; - A_STATUS status; + int status; struct iw_pmksa *pmksa; pmksa = (struct iw_pmksa *)extra; @@ -1599,7 +1599,7 @@ static int ar6000_set_wapi_key(struct net_device *dev, A_INT32 index; A_UINT32 *PN; A_INT32 i; - A_STATUS status; + int status; A_UINT8 wapiKeyRsc[16]; CRYPTO_TYPE keyType = WAPI_CRYPT; const A_UINT8 broadcastMac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; @@ -1660,7 +1660,7 @@ ar6000_ioctl_siwencodeext(struct net_device *dev, A_INT32 keyLen; A_UINT8 *keyData; A_UINT8 keyRsc[8]; - A_STATUS status; + int status; CRYPTO_TYPE keyType; #ifdef USER_KEYS struct ieee80211req_key ik; diff --git a/drivers/staging/ath6kl/reorder/rcv_aggr.c b/drivers/staging/ath6kl/reorder/rcv_aggr.c index 092bb3007c5d..d53ab15624da 100644 --- a/drivers/staging/ath6kl/reorder/rcv_aggr.c +++ b/drivers/staging/ath6kl/reorder/rcv_aggr.c @@ -33,7 +33,7 @@ #include "aggr_rx_internal.h" #include "wmi.h" -extern A_STATUS +extern int wmi_dot3_2_dix(void *osbuf); static void @@ -57,7 +57,7 @@ aggr_init(ALLOC_NETBUFS netbuf_allocator) AGGR_INFO *p_aggr = NULL; RXTID *rxtid; A_UINT8 i; - A_STATUS status = A_OK; + int status = A_OK; A_PRINTF("In aggr_init..\n"); diff --git a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c index f4926f215bbd..2743c4cf604d 100644 --- a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c +++ b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c @@ -97,7 +97,7 @@ iswscoui(const A_UINT8 *frm) return frm[1] > 3 && LE_READ_4(frm+2) == ((0x04<<24)|WPA_OUI); } -A_STATUS +int wlan_parse_beacon(A_UINT8 *buf, int framelen, struct ieee80211_common_ie *cie) { A_UINT8 *frm, *efrm; diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index 7800778099bd..1cf9e961b654 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -70,100 +70,100 @@ ATH_DEBUG_INSTANTIATE_MODULE_VAR(wmi, #define A_DPRINTF AR_DEBUG_PRINTF #endif -static A_STATUS wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_sync_point(struct wmi_t *wmip); +static int wmi_sync_point(struct wmi_t *wmip); -static A_STATUS wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); #ifdef CONFIG_HOST_DSET_SUPPORT -static A_STATUS wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); #endif /* CONFIG_HOST_DSET_SUPPORT */ -static A_STATUS wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_channel_change_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_channel_change_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS +static int wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len); -static A_STATUS +static int wmi_set_params_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len); -static A_STATUS +static int wmi_acm_reject_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len); #ifdef CONFIG_HOST_GPIO_SUPPORT -static A_STATUS wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); #endif /* CONFIG_HOST_GPIO_SUPPORT */ #ifdef CONFIG_HOST_TCMD_SUPPORT -static A_STATUS +static int wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); #endif -static A_STATUS +static int wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS +static int wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS +static int wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); static A_BOOL wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex); -static A_STATUS +static int wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS +static int wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -A_STATUS wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId, +int wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId, WMI_SYNC_FLAG syncflag); A_UINT8 ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, A_UINT32 size); @@ -171,33 +171,33 @@ A_UINT8 ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, void wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd); void wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd); -static A_STATUS wmi_send_rssi_threshold_params(struct wmi_t *wmip, +static int wmi_send_rssi_threshold_params(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd); -static A_STATUS wmi_send_snr_threshold_params(struct wmi_t *wmip, +static int wmi_send_snr_threshold_params(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd); #if defined(CONFIG_TARGET_PROFILE_SUPPORT) -static A_STATUS +static int wmi_prof_count_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); #endif /* CONFIG_TARGET_PROFILE_SUPPORT */ -static A_STATUS wmi_pspoll_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_pspoll_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_dtimexpiry_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_dtimexpiry_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_peer_node_event_rx (struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_peer_node_event_rx (struct wmi_t *wmip, A_UINT8 *datap, int len); #ifdef ATH_AR6K_11N_SUPPORT -static A_STATUS wmi_addba_req_event_rx(struct wmi_t *, A_UINT8 *, int); -static A_STATUS wmi_addba_resp_event_rx(struct wmi_t *, A_UINT8 *, int); -static A_STATUS wmi_delba_req_event_rx(struct wmi_t *, A_UINT8 *, int); -static A_STATUS wmi_btcoex_config_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_STATUS wmi_btcoex_stats_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_addba_req_event_rx(struct wmi_t *, A_UINT8 *, int); +static int wmi_addba_resp_event_rx(struct wmi_t *, A_UINT8 *, int); +static int wmi_delba_req_event_rx(struct wmi_t *, A_UINT8 *, int); +static int wmi_btcoex_config_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_btcoex_stats_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); #endif -static A_STATUS wmi_hci_event_rx(struct wmi_t *, A_UINT8 *, int); +static int wmi_hci_event_rx(struct wmi_t *, A_UINT8 *, int); #ifdef WAPI_ENABLE -static A_STATUS wmi_wapi_rekey_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_wapi_rekey_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); #endif @@ -391,7 +391,7 @@ wmi_shutdown(struct wmi_t *wmip) * Assumes the entire DIX header is contigous and that there is * enough room in the buffer for a 802.3 mac header and LLC+SNAP headers. */ -A_STATUS +int wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf) { A_UINT8 *datap; @@ -449,7 +449,7 @@ wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf) return (A_OK); } -A_STATUS wmi_meta_add(struct wmi_t *wmip, void *osbuf, A_UINT8 *pVersion,void *pTxMetaS) +int wmi_meta_add(struct wmi_t *wmip, void *osbuf, A_UINT8 *pVersion,void *pTxMetaS) { switch(*pVersion){ case 0: @@ -494,13 +494,13 @@ A_STATUS wmi_meta_add(struct wmi_t *wmip, void *osbuf, A_UINT8 *pVersion,void *p } /* Adds a WMI data header */ -A_STATUS +int wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType, A_BOOL bMoreData, WMI_DATA_HDR_DATA_TYPE data_type,A_UINT8 metaVersion, void *pTxMetaS) { WMI_DATA_HDR *dtHdr; // A_UINT8 metaVersion = 0; - A_STATUS status; + int status; A_ASSERT(osbuf != NULL); @@ -621,7 +621,7 @@ A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 la return trafficClass; } -A_STATUS +int wmi_dot11_hdr_add (struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode) { A_UINT8 *datap; @@ -713,7 +713,7 @@ AddDot11Hdr: return (A_OK); } -A_STATUS +int wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf) { A_UINT8 *datap; @@ -781,7 +781,7 @@ wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf) * performs 802.3 to DIX encapsulation for received packets. * Assumes the entire 802.3 header is contigous. */ -A_STATUS +int wmi_dot3_2_dix(void *osbuf) { A_UINT8 *datap; @@ -809,7 +809,7 @@ wmi_dot3_2_dix(void *osbuf) /* * Removes a WMI data header */ -A_STATUS +int wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf) { A_ASSERT(osbuf != NULL); @@ -826,14 +826,14 @@ wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg) /* * WMI Extended Event received from Target. */ -A_STATUS +int wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf) { WMIX_CMD_HDR *cmd; A_UINT16 id; A_UINT8 *datap; A_UINT32 len; - A_STATUS status = A_OK; + int status = A_OK; if (A_NETBUF_LEN(osbuf) < sizeof(WMIX_CMD_HDR)) { A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG)); @@ -903,14 +903,14 @@ wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf) */ A_UINT32 cmdRecvNum; -A_STATUS +int wmi_control_rx(struct wmi_t *wmip, void *osbuf) { WMI_CMD_HDR *cmd; A_UINT16 id; A_UINT8 *datap; A_UINT32 len, i, loggingReq; - A_STATUS status = A_OK; + int status = A_OK; A_ASSERT(osbuf != NULL); if (A_NETBUF_LEN(osbuf) < sizeof(WMI_CMD_HDR)) { @@ -1192,7 +1192,7 @@ wmi_control_rx(struct wmi_t *wmip, void *osbuf) } /* Send a "simple" wmi command -- one with no arguments */ -static A_STATUS +static int wmi_simple_cmd(struct wmi_t *wmip, WMI_COMMAND_ID cmdid) { void *osbuf; @@ -1209,7 +1209,7 @@ wmi_simple_cmd(struct wmi_t *wmip, WMI_COMMAND_ID cmdid) Enabling this command only if GPIO or profiling support is enabled. This is to suppress warnings on some platforms */ #if defined(CONFIG_HOST_GPIO_SUPPORT) || defined(CONFIG_TARGET_PROFILE_SUPPORT) -static A_STATUS +static int wmi_simple_cmd_xtnd(struct wmi_t *wmip, WMIX_COMMAND_ID cmdid) { void *osbuf; @@ -1223,7 +1223,7 @@ wmi_simple_cmd_xtnd(struct wmi_t *wmip, WMIX_COMMAND_ID cmdid) } #endif -static A_STATUS +static int wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_READY_EVENT *ev = (WMI_READY_EVENT *)datap; @@ -1257,7 +1257,7 @@ iswmmparam(const A_UINT8 *frm) } -static A_STATUS +static int wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_CONNECT_EVENT *ev; @@ -1317,7 +1317,7 @@ wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_REG_DOMAIN_EVENT *ev; @@ -1332,7 +1332,7 @@ wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_NEIGHBOR_REPORT_EVENT *ev; @@ -1353,7 +1353,7 @@ wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_DISCONNECT_EVENT *ev; @@ -1378,7 +1378,7 @@ wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_peer_node_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_PEER_NODE_EVENT *ev; @@ -1398,7 +1398,7 @@ wmi_peer_node_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_TKIP_MICERR_EVENT *ev; @@ -1414,7 +1414,7 @@ wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { bss_t *bss = NULL; @@ -1578,7 +1578,7 @@ wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { bss_t *bss; @@ -1623,7 +1623,7 @@ wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) /* This event indicates inactivity timeout of a fatpipe(pstream) * at the target */ -static A_STATUS +static int wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_PSTREAM_TIMEOUT_EVENT *ev; @@ -1653,7 +1653,7 @@ wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_BIT_RATE_REPLY *reply; @@ -1684,7 +1684,7 @@ wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_FIX_RATES_REPLY *reply; @@ -1701,7 +1701,7 @@ wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_CHANNEL_LIST_REPLY *reply; @@ -1718,7 +1718,7 @@ wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_TX_PWR_REPLY *reply; @@ -1733,7 +1733,7 @@ wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_GET_KEEPALIVE_CMD *reply; @@ -1750,7 +1750,7 @@ wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } -static A_STATUS +static int wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMIX_DSETOPENREQ_EVENT *dsetopenreq; @@ -1771,7 +1771,7 @@ wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } #ifdef CONFIG_HOST_DSET_SUPPORT -static A_STATUS +static int wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMIX_DSETCLOSE_EVENT *dsetclose; @@ -1787,7 +1787,7 @@ wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMIX_DSETDATAREQ_EVENT *dsetdatareq; @@ -1810,16 +1810,16 @@ wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } #endif /* CONFIG_HOST_DSET_SUPPORT */ -static A_STATUS +static int wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_SCAN_COMPLETE_EVENT *ev; ev = (WMI_SCAN_COMPLETE_EVENT *)datap; - if ((A_STATUS)ev->status == A_OK) { + if ((int)ev->status == A_OK) { wlan_refresh_inactive_nodes(&wmip->wmi_scan_table); } - A_WMI_SCANCOMPLETE_EVENT(wmip->wmi_devt, (A_STATUS) ev->status); + A_WMI_SCANCOMPLETE_EVENT(wmip->wmi_devt, (int) ev->status); is_probe_ssid = FALSE; return A_OK; @@ -1832,7 +1832,7 @@ wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) * Behavior of target after wmi error event is undefined. * A reset is recommended. */ -static A_STATUS +static int wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_CMD_ERROR_EVENT *ev; @@ -1855,7 +1855,7 @@ wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } -static A_STATUS +static int wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); @@ -1865,7 +1865,7 @@ wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_RSSI_THRESHOLD_EVENT *reply; @@ -1970,7 +1970,7 @@ wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } -static A_STATUS +static int wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_TARGET_ERROR_REPORT_EVENT *reply; @@ -1986,7 +1986,7 @@ wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_CAC_EVENT *reply; @@ -2056,7 +2056,7 @@ wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_channel_change_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_CHANNEL_CHANGE_EVENT *reply; @@ -2073,7 +2073,7 @@ wmi_channel_change_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMIX_HB_CHALLENGE_RESP_EVENT *reply; @@ -2089,7 +2089,7 @@ wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_TARGET_ROAM_TBL *reply; @@ -2105,7 +2105,7 @@ wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_TARGET_ROAM_DATA *reply; @@ -2121,7 +2121,7 @@ wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { if (len < sizeof(WMI_TX_RETRY_ERR_EVENT)) { @@ -2134,7 +2134,7 @@ wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_SNR_THRESHOLD_EVENT *reply; @@ -2227,7 +2227,7 @@ wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_LQ_THRESHOLD_EVENT *reply; @@ -2245,7 +2245,7 @@ wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { A_UINT16 ap_info_entry_size; @@ -2286,7 +2286,7 @@ wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { A_UINT32 dropped; @@ -2299,7 +2299,7 @@ wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } #ifdef CONFIG_HOST_GPIO_SUPPORT -static A_STATUS +static int wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMIX_GPIO_INTR_EVENT *gpio_intr = (WMIX_GPIO_INTR_EVENT *)datap; @@ -2313,7 +2313,7 @@ wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMIX_GPIO_DATA_EVENT *gpio_data = (WMIX_GPIO_DATA_EVENT *)datap; @@ -2327,7 +2327,7 @@ wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); @@ -2342,11 +2342,11 @@ wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) * Called to send a wmi command. Command specific data is already built * on osbuf and current osbuf->data points to it. */ -A_STATUS +int wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId, WMI_SYNC_FLAG syncflag) { - A_STATUS status; + int status; #define IS_OPT_TX_CMD(cmdId) ((cmdId == WMI_OPT_TX_FRAME_CMDID)) WMI_CMD_HDR *cHdr; HTC_ENDPOINT_ID eid = wmip->wmi_endpoint_id; @@ -2398,7 +2398,7 @@ wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId, #undef IS_OPT_TX_CMD } -A_STATUS +int wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId, WMI_SYNC_FLAG syncflag) { @@ -2415,7 +2415,7 @@ wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId, return wmi_cmd_send(wmip, osbuf, WMI_EXTENSION_CMDID, syncflag); } -A_STATUS +int wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType, DOT11_AUTH_MODE dot11AuthMode, AUTH_MODE authMode, CRYPTO_TYPE pairwiseCrypto, A_UINT8 pairwiseCryptoLen, @@ -2470,7 +2470,7 @@ wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType, return (wmi_cmd_send(wmip, osbuf, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_reconnect_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT16 channel) { void *osbuf; @@ -2496,10 +2496,10 @@ wmi_reconnect_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT16 channel) return (wmi_cmd_send(wmip, osbuf, WMI_RECONNECT_CMDID, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_disconnect_cmd(struct wmi_t *wmip) { - A_STATUS status; + int status; wmip->wmi_traffic_class = 100; /* Bug fix for 24817(elevator bug) - the disconnect command does not @@ -2509,7 +2509,7 @@ wmi_disconnect_cmd(struct wmi_t *wmip) return status; } -A_STATUS +int wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, A_BOOL forceFgScan, A_BOOL isLegacy, A_UINT32 homeDwellTime, A_UINT32 forceScanInterval, @@ -2553,7 +2553,7 @@ wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, return (wmi_cmd_send(wmip, osbuf, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec, A_UINT16 fg_end_sec, A_UINT16 bg_sec, A_UINT16 minact_chdw_msec, A_UINT16 maxact_chdw_msec, @@ -2588,7 +2588,7 @@ wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_bssfilter_cmd(struct wmi_t *wmip, A_UINT8 filter, A_UINT32 ieMask) { void *osbuf; @@ -2614,7 +2614,7 @@ wmi_bssfilter_cmd(struct wmi_t *wmip, A_UINT8 filter, A_UINT32 ieMask) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_probedSsid_cmd(struct wmi_t *wmip, A_UINT8 index, A_UINT8 flag, A_UINT8 ssidLength, A_UCHAR *ssid) { @@ -2656,7 +2656,7 @@ wmi_probedSsid_cmd(struct wmi_t *wmip, A_UINT8 index, A_UINT8 flag, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_listeninterval_cmd(struct wmi_t *wmip, A_UINT16 listenInterval, A_UINT16 listenBeacons) { void *osbuf; @@ -2678,7 +2678,7 @@ wmi_listeninterval_cmd(struct wmi_t *wmip, A_UINT16 listenInterval, A_UINT16 lis NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_bmisstime_cmd(struct wmi_t *wmip, A_UINT16 bmissTime, A_UINT16 bmissBeacons) { void *osbuf; @@ -2700,7 +2700,7 @@ wmi_bmisstime_cmd(struct wmi_t *wmip, A_UINT16 bmissTime, A_UINT16 bmissBeacons) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_associnfo_cmd(struct wmi_t *wmip, A_UINT8 ieType, A_UINT8 ieLen, A_UINT8 *ieInfo) { @@ -2726,7 +2726,7 @@ wmi_associnfo_cmd(struct wmi_t *wmip, A_UINT8 ieType, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_powermode_cmd(struct wmi_t *wmip, A_UINT8 powerMode) { void *osbuf; @@ -2748,7 +2748,7 @@ wmi_powermode_cmd(struct wmi_t *wmip, A_UINT8 powerMode) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_ibsspmcaps_cmd(struct wmi_t *wmip, A_UINT8 pmEnable, A_UINT8 ttl, A_UINT16 atim_windows, A_UINT16 timeout_value) { @@ -2773,7 +2773,7 @@ wmi_ibsspmcaps_cmd(struct wmi_t *wmip, A_UINT8 pmEnable, A_UINT8 ttl, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_apps_cmd(struct wmi_t *wmip, A_UINT8 psType, A_UINT32 idle_time, A_UINT32 ps_period, A_UINT8 sleep_period) { @@ -2798,7 +2798,7 @@ wmi_apps_cmd(struct wmi_t *wmip, A_UINT8 psType, A_UINT32 idle_time, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_pmparams_cmd(struct wmi_t *wmip, A_UINT16 idlePeriod, A_UINT16 psPollNum, A_UINT16 dtimPolicy, A_UINT16 tx_wakeup_policy, A_UINT16 num_tx_to_wakeup, @@ -2827,7 +2827,7 @@ wmi_pmparams_cmd(struct wmi_t *wmip, A_UINT16 idlePeriod, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_disctimeout_cmd(struct wmi_t *wmip, A_UINT8 timeout) { void *osbuf; @@ -2848,7 +2848,7 @@ wmi_disctimeout_cmd(struct wmi_t *wmip, A_UINT8 timeout) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_addKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex, CRYPTO_TYPE keyType, A_UINT8 keyUsage, A_UINT8 keyLength, A_UINT8 *keyRSC, A_UINT8 *keyMaterial, A_UINT8 key_op_ctrl, A_UINT8 *macAddr, @@ -2897,7 +2897,7 @@ wmi_addKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex, CRYPTO_TYPE keyType, return (wmi_cmd_send(wmip, osbuf, WMI_ADD_CIPHER_KEY_CMDID, sync_flag)); } -A_STATUS +int wmi_add_krk_cmd(struct wmi_t *wmip, A_UINT8 *krk) { void *osbuf; @@ -2917,13 +2917,13 @@ wmi_add_krk_cmd(struct wmi_t *wmip, A_UINT8 *krk) return (wmi_cmd_send(wmip, osbuf, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_delete_krk_cmd(struct wmi_t *wmip) { return wmi_simple_cmd(wmip, WMI_DELETE_KRK_CMDID); } -A_STATUS +int wmi_deleteKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex) { void *osbuf; @@ -2948,7 +2948,7 @@ wmi_deleteKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId, A_BOOL set) { @@ -2983,7 +2983,7 @@ wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId, return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_CMDID, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, A_BOOL en) { void *osbuf; @@ -3003,7 +3003,7 @@ wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, A_BOOL en) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_akmp_params_cmd(struct wmi_t *wmip, WMI_SET_AKMP_PARAMS_CMD *akmpParams) { @@ -3023,7 +3023,7 @@ wmi_set_akmp_params_cmd(struct wmi_t *wmip, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_pmkid_list_cmd(struct wmi_t *wmip, WMI_SET_PMKID_LIST_CMD *pmkInfo) { @@ -3053,13 +3053,13 @@ wmi_set_pmkid_list_cmd(struct wmi_t *wmip, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_get_pmkid_list_cmd(struct wmi_t *wmip) { return wmi_simple_cmd(wmip, WMI_GET_PMKID_LIST_CMDID); } -A_STATUS +int wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, HTC_ENDPOINT_ID eid) { WMI_DATA_HDR *dtHdr; @@ -3085,14 +3085,14 @@ typedef struct _WMI_DATA_SYNC_BUFS { void *osbuf; }WMI_DATA_SYNC_BUFS; -static A_STATUS +static int wmi_sync_point(struct wmi_t *wmip) { void *cmd_osbuf; WMI_SYNC_CMD *cmd; WMI_DATA_SYNC_BUFS dataSyncBufs[WMM_NUM_AC]; A_UINT8 i,numPriStreams=0; - A_STATUS status = A_OK; + int status = A_OK; A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); @@ -3195,7 +3195,7 @@ wmi_sync_point(struct wmi_t *wmip) return (status); } -A_STATUS +int wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params) { void *osbuf; @@ -3291,12 +3291,12 @@ wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_delete_pstream_cmd(struct wmi_t *wmip, A_UINT8 trafficClass, A_UINT8 tsid) { void *osbuf; WMI_DELETE_PSTREAM_CMD *cmd; - A_STATUS status; + int status; A_UINT16 activeTsids=0; /* validate the parameters */ @@ -3355,7 +3355,7 @@ wmi_delete_pstream_cmd(struct wmi_t *wmip, A_UINT8 trafficClass, A_UINT8 tsid) return status; } -A_STATUS +int wmi_set_framerate_cmd(struct wmi_t *wmip, A_UINT8 bEnable, A_UINT8 type, A_UINT8 subType, A_UINT16 rateMask) { void *osbuf; @@ -3394,7 +3394,7 @@ wmi_set_framerate_cmd(struct wmi_t *wmip, A_UINT8 bEnable, A_UINT8 type, A_UINT8 * used to set the bit rate. rate is in Kbps. If rate == -1 * then auto selection is used. */ -A_STATUS +int wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 dataRate, A_INT32 mgmtRate, A_INT32 ctlRate) { void *osbuf; @@ -3444,7 +3444,7 @@ wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 dataRate, A_INT32 mgmtRate, A_IN return (wmi_cmd_send(wmip, osbuf, WMI_SET_BITRATE_CMDID, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_get_bitrate_cmd(struct wmi_t *wmip) { return wmi_simple_cmd(wmip, WMI_GET_BITRATE_CMDID); @@ -3532,7 +3532,7 @@ wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, A_INT8 *rate_idx) return A_OK; } -A_STATUS +int wmi_set_fixrates_cmd(struct wmi_t *wmip, A_UINT32 fixRatesMask) { void *osbuf; @@ -3572,13 +3572,13 @@ wmi_set_fixrates_cmd(struct wmi_t *wmip, A_UINT32 fixRatesMask) return (wmi_cmd_send(wmip, osbuf, WMI_SET_FIXRATES_CMDID, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_get_ratemask_cmd(struct wmi_t *wmip) { return wmi_simple_cmd(wmip, WMI_GET_FIXRATES_CMDID); } -A_STATUS +int wmi_get_channelList_cmd(struct wmi_t *wmip) { return wmi_simple_cmd(wmip, WMI_GET_CHANNEL_LIST_CMDID); @@ -3594,7 +3594,7 @@ wmi_get_channelList_cmd(struct wmi_t *wmip) * should limit its operation to. It should be NULL if numChan == 0. Size of * array should correspond to numChan entries. */ -A_STATUS +int wmi_set_channelParams_cmd(struct wmi_t *wmip, A_UINT8 scanParam, WMI_PHY_MODE mode, A_INT8 numChan, A_UINT16 *channelList) @@ -3681,7 +3681,7 @@ wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_ } } -A_STATUS +int wmi_set_rssi_threshold_params(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd) { @@ -3706,7 +3706,7 @@ wmi_set_rssi_threshold_params(struct wmi_t *wmip, return (wmi_send_rssi_threshold_params(wmip, rssiCmd)); } -A_STATUS +int wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *ipCmd) { void *osbuf; @@ -3731,7 +3731,7 @@ wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *ipCmd) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, WMI_SET_HOST_SLEEP_MODE_CMD *hostModeCmd) { @@ -3793,7 +3793,7 @@ wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_wow_mode_cmd(struct wmi_t *wmip, WMI_SET_WOW_MODE_CMD *wowModeCmd) { @@ -3819,7 +3819,7 @@ wmi_set_wow_mode_cmd(struct wmi_t *wmip, } -A_STATUS +int wmi_get_wow_list_cmd(struct wmi_t *wmip, WMI_GET_WOW_LIST_CMD *wowListCmd) { @@ -3845,7 +3845,7 @@ wmi_get_wow_list_cmd(struct wmi_t *wmip, } -static A_STATUS +static int wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_GET_WOW_LIST_REPLY *reply; @@ -3861,7 +3861,7 @@ wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -A_STATUS wmi_add_wow_pattern_cmd(struct wmi_t *wmip, +int wmi_add_wow_pattern_cmd(struct wmi_t *wmip, WMI_ADD_WOW_PATTERN_CMD *addWowCmd, A_UINT8* pattern, A_UINT8* mask, A_UINT8 pattern_size) @@ -3896,7 +3896,7 @@ A_STATUS wmi_add_wow_pattern_cmd(struct wmi_t *wmip, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_del_wow_pattern_cmd(struct wmi_t *wmip, WMI_DEL_WOW_PATTERN_CMD *delWowCmd) { @@ -3967,7 +3967,7 @@ wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CM } } -A_STATUS +int wmi_set_snr_threshold_params(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd) { @@ -3984,7 +3984,7 @@ wmi_set_snr_threshold_params(struct wmi_t *wmip, return (wmi_send_snr_threshold_params(wmip, snrCmd)); } -A_STATUS +int wmi_clr_rssi_snr(struct wmi_t *wmip) { void *osbuf; @@ -3998,7 +3998,7 @@ wmi_clr_rssi_snr(struct wmi_t *wmip) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_lq_threshold_params(struct wmi_t *wmip, WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd) { @@ -4033,7 +4033,7 @@ wmi_set_lq_threshold_params(struct wmi_t *wmip, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 mask) { void *osbuf; @@ -4058,7 +4058,7 @@ wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 mask) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie, A_UINT32 source) { void *osbuf; @@ -4079,7 +4079,7 @@ wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie, A_UINT32 source) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_config_debug_module_cmd(struct wmi_t *wmip, A_UINT16 mmask, A_UINT16 tsr, A_BOOL rep, A_UINT16 size, A_UINT32 valid) @@ -4105,13 +4105,13 @@ wmi_config_debug_module_cmd(struct wmi_t *wmip, A_UINT16 mmask, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_get_stats_cmd(struct wmi_t *wmip) { return wmi_simple_cmd(wmip, WMI_GET_STATISTICS_CMDID); } -A_STATUS +int wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid) { void *osbuf; @@ -4135,7 +4135,7 @@ wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid) return (wmi_cmd_send(wmip, osbuf, WMI_ADD_BAD_AP_CMDID, SYNC_BEFORE_WMIFLAG)); } -A_STATUS +int wmi_deleteBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex) { void *osbuf; @@ -4159,13 +4159,13 @@ wmi_deleteBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_abort_scan_cmd(struct wmi_t *wmip) { return wmi_simple_cmd(wmip, WMI_ABORT_SCAN_CMDID); } -A_STATUS +int wmi_set_txPwr_cmd(struct wmi_t *wmip, A_UINT8 dbM) { void *osbuf; @@ -4184,7 +4184,7 @@ wmi_set_txPwr_cmd(struct wmi_t *wmip, A_UINT8 dbM) return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_PWR_CMDID, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_get_txPwr_cmd(struct wmi_t *wmip) { return wmi_simple_cmd(wmip, WMI_GET_TX_PWR_CMDID); @@ -4202,13 +4202,13 @@ wmi_get_mapped_qos_queue(struct wmi_t *wmip, A_UINT8 trafficClass) return activeTsids; } -A_STATUS +int wmi_get_roam_tbl_cmd(struct wmi_t *wmip) { return wmi_simple_cmd(wmip, WMI_GET_ROAM_TBL_CMDID); } -A_STATUS +int wmi_get_roam_data_cmd(struct wmi_t *wmip, A_UINT8 roamDataType) { void *osbuf; @@ -4229,7 +4229,7 @@ wmi_get_roam_data_cmd(struct wmi_t *wmip, A_UINT8 roamDataType) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p, A_UINT8 size) { @@ -4252,7 +4252,7 @@ wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_powersave_timers_cmd(struct wmi_t *wmip, WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd, A_UINT8 size) @@ -4286,7 +4286,7 @@ wmi_set_powersave_timers_cmd(struct wmi_t *wmip, #ifdef CONFIG_HOST_GPIO_SUPPORT /* Send a command to Target to change GPIO output pins. */ -A_STATUS +int wmi_gpio_output_set(struct wmi_t *wmip, A_UINT32 set_mask, A_UINT32 clear_mask, @@ -4320,7 +4320,7 @@ wmi_gpio_output_set(struct wmi_t *wmip, } /* Send a command to the Target requesting state of the GPIO input pins */ -A_STATUS +int wmi_gpio_input_get(struct wmi_t *wmip) { A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); @@ -4329,7 +4329,7 @@ wmi_gpio_input_get(struct wmi_t *wmip) } /* Send a command to the Target that changes the value of a GPIO register. */ -A_STATUS +int wmi_gpio_register_set(struct wmi_t *wmip, A_UINT32 gpioreg_id, A_UINT32 value) @@ -4358,7 +4358,7 @@ wmi_gpio_register_set(struct wmi_t *wmip, } /* Send a command to the Target to fetch the value of a GPIO register. */ -A_STATUS +int wmi_gpio_register_get(struct wmi_t *wmip, A_UINT32 gpioreg_id) { @@ -4384,7 +4384,7 @@ wmi_gpio_register_get(struct wmi_t *wmip, } /* Send a command to the Target acknowledging some GPIO interrupts. */ -A_STATUS +int wmi_gpio_intr_ack(struct wmi_t *wmip, A_UINT32 ack_mask) { @@ -4410,7 +4410,7 @@ wmi_gpio_intr_ack(struct wmi_t *wmip, } #endif /* CONFIG_HOST_GPIO_SUPPORT */ -A_STATUS +int wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT8 ac, A_UINT16 txop, A_UINT8 eCWmin, A_UINT8 eCWmax, A_UINT8 aifsn) { @@ -4441,7 +4441,7 @@ wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT8 ac, A_UINT16 txop, A_UINT NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_retry_limits_cmd(struct wmi_t *wmip, A_UINT8 frameType, A_UINT8 trafficClass, A_UINT8 maxRetries, A_UINT8 enableNotify) @@ -4488,7 +4488,7 @@ wmi_get_current_bssid(struct wmi_t *wmip, A_UINT8 *bssid) } } -A_STATUS +int wmi_set_opt_mode_cmd(struct wmi_t *wmip, A_UINT8 optMode) { void *osbuf; @@ -4509,7 +4509,7 @@ wmi_set_opt_mode_cmd(struct wmi_t *wmip, A_UINT8 optMode) SYNC_BOTH_WMIFLAG)); } -A_STATUS +int wmi_opt_tx_frame_cmd(struct wmi_t *wmip, A_UINT8 frmType, A_UINT8 *dstMacAddr, @@ -4540,7 +4540,7 @@ wmi_opt_tx_frame_cmd(struct wmi_t *wmip, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl) { void *osbuf; @@ -4562,7 +4562,7 @@ wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl) } -A_STATUS +int wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize) { void *osbuf; @@ -4584,7 +4584,7 @@ wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize) } -A_STATUS +int wmi_set_max_sp_len_cmd(struct wmi_t *wmip, A_UINT8 maxSPLen) { void *osbuf; @@ -4649,10 +4649,10 @@ wmi_get_power_mode_cmd(struct wmi_t *wmip) return wmip->wmi_powerMode; } -A_STATUS +int wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, A_BOOL tspecCompliance) { - A_STATUS ret = A_OK; + int ret = A_OK; #define TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF (~0) #define TSPEC_SERVICE_START_TIME_ATHEROS_DEF 0 @@ -4682,7 +4682,7 @@ wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, A_BOOL tspecCompliance) } #ifdef CONFIG_HOST_TCMD_SUPPORT -static A_STATUS +static int wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { @@ -4695,7 +4695,7 @@ wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) #endif /* CONFIG_HOST_TCMD_SUPPORT*/ -A_STATUS +int wmi_set_authmode_cmd(struct wmi_t *wmip, A_UINT8 mode) { void *osbuf; @@ -4716,7 +4716,7 @@ wmi_set_authmode_cmd(struct wmi_t *wmip, A_UINT8 mode) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_reassocmode_cmd(struct wmi_t *wmip, A_UINT8 mode) { void *osbuf; @@ -4737,7 +4737,7 @@ wmi_set_reassocmode_cmd(struct wmi_t *wmip, A_UINT8 mode) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_lpreamble_cmd(struct wmi_t *wmip, A_UINT8 status, A_UINT8 preamblePolicy) { void *osbuf; @@ -4759,7 +4759,7 @@ wmi_set_lpreamble_cmd(struct wmi_t *wmip, A_UINT8 status, A_UINT8 preamblePolicy NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_rts_cmd(struct wmi_t *wmip, A_UINT16 threshold) { void *osbuf; @@ -4780,7 +4780,7 @@ wmi_set_rts_cmd(struct wmi_t *wmip, A_UINT16 threshold) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status) { void *osbuf; @@ -4802,7 +4802,7 @@ wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status) } -A_STATUS +int wmi_set_qos_supp_cmd(struct wmi_t *wmip, A_UINT8 status) { void *osbuf; @@ -4823,7 +4823,7 @@ wmi_set_qos_supp_cmd(struct wmi_t *wmip, A_UINT8 status) } -A_STATUS +int wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG cfg) { void *osbuf; @@ -4848,7 +4848,7 @@ wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG cfg) } -A_STATUS +int wmi_set_country(struct wmi_t *wmip, A_UCHAR *countryCode) { void *osbuf; @@ -4874,7 +4874,7 @@ wmi_set_country(struct wmi_t *wmip, A_UCHAR *countryCode) This would be beneficial for customers like Qualcomm, who might have different test command requirements from differnt manufacturers */ -A_STATUS +int wmi_test_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT32 len) { void *osbuf; @@ -4897,7 +4897,7 @@ wmi_test_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT32 len) #endif -A_STATUS +int wmi_set_bt_status_cmd(struct wmi_t *wmip, A_UINT8 streamType, A_UINT8 status) { void *osbuf; @@ -4921,7 +4921,7 @@ wmi_set_bt_status_cmd(struct wmi_t *wmip, A_UINT8 streamType, A_UINT8 status) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd) { void *osbuf; @@ -4983,7 +4983,7 @@ wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd) { void *osbuf; @@ -5003,7 +5003,7 @@ wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd) } -A_STATUS +int wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd) { @@ -5024,7 +5024,7 @@ wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip, } -A_STATUS +int wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD* cmd) { @@ -5044,7 +5044,7 @@ wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip, } -A_STATUS +int wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd) { @@ -5064,7 +5064,7 @@ wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip, } -A_STATUS +int wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_A2DP_CONFIG_CMD * cmd) { @@ -5084,7 +5084,7 @@ wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip, } -A_STATUS +int wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD * cmd) { @@ -5104,7 +5104,7 @@ wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip, } -A_STATUS +int wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd) { void *osbuf; @@ -5123,7 +5123,7 @@ wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd) } -A_STATUS +int wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip, WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd) { @@ -5143,7 +5143,7 @@ wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip, } -A_STATUS +int wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd) { void *osbuf; @@ -5162,7 +5162,7 @@ wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd) } -A_STATUS +int wmi_get_btcoex_stats_cmd(struct wmi_t *wmip) { @@ -5170,7 +5170,7 @@ wmi_get_btcoex_stats_cmd(struct wmi_t *wmip) } -A_STATUS +int wmi_get_keepalive_configured(struct wmi_t *wmip) { void *osbuf; @@ -5192,7 +5192,7 @@ wmi_get_keepalive_cmd(struct wmi_t *wmip) return wmip->wmi_keepaliveInterval; } -A_STATUS +int wmi_set_keepalive_cmd(struct wmi_t *wmip, A_UINT8 keepaliveInterval) { void *osbuf; @@ -5214,7 +5214,7 @@ wmi_set_keepalive_cmd(struct wmi_t *wmip, A_UINT8 keepaliveInterval) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_params_cmd(struct wmi_t *wmip, A_UINT32 opcode, A_UINT32 length, A_CHAR* buffer) { void *osbuf; @@ -5238,7 +5238,7 @@ wmi_set_params_cmd(struct wmi_t *wmip, A_UINT32 opcode, A_UINT32 length, A_CHAR* } -A_STATUS +int wmi_set_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 dot3, A_UINT8 dot4) { void *osbuf; @@ -5264,7 +5264,7 @@ wmi_set_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 } -A_STATUS +int wmi_del_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 dot3, A_UINT8 dot4) { void *osbuf; @@ -5289,7 +5289,7 @@ wmi_del_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 enable) { void *osbuf; @@ -5309,7 +5309,7 @@ wmi_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 enable) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_appie_cmd(struct wmi_t *wmip, A_UINT8 mgmtFrmType, A_UINT8 ieLen, A_UINT8 *ieInfo) { @@ -5335,7 +5335,7 @@ wmi_set_appie_cmd(struct wmi_t *wmip, A_UINT8 mgmtFrmType, A_UINT8 ieLen, return (wmi_cmd_send(wmip, osbuf, WMI_SET_APPIE_CMDID, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_halparam_cmd(struct wmi_t *wmip, A_UINT8 *cmd, A_UINT16 dataLen) { void *osbuf; @@ -5426,7 +5426,7 @@ wmi_free_node(struct wmi_t *wmip, const A_UINT8 *macaddr) return; } -A_STATUS +int wmi_dset_open_reply(struct wmi_t *wmip, A_UINT32 status, A_UINT32 access_cookie, @@ -5461,7 +5461,7 @@ wmi_dset_open_reply(struct wmi_t *wmip, NO_SYNC_WMIFLAG)); } -static A_STATUS +static int wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len) { WMI_PMKID_LIST_REPLY *reply; @@ -5484,7 +5484,7 @@ wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len) } -static A_STATUS +static int wmi_set_params_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len) { WMI_SET_PARAMS_REPLY *reply; @@ -5508,7 +5508,7 @@ wmi_set_params_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len) -static A_STATUS +static int wmi_acm_reject_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len) { WMI_ACM_REJECT_EVENT *ev; @@ -5521,7 +5521,7 @@ wmi_acm_reject_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len) #ifdef CONFIG_HOST_DSET_SUPPORT -A_STATUS +int wmi_dset_data_reply(struct wmi_t *wmip, A_UINT32 status, A_UINT8 *user_buf, @@ -5568,7 +5568,7 @@ wmi_dset_data_reply(struct wmi_t *wmip, } #endif /* CONFIG_HOST_DSET_SUPPORT */ -A_STATUS +int wmi_set_wsc_status_cmd(struct wmi_t *wmip, A_UINT32 status) { void *osbuf; @@ -5592,7 +5592,7 @@ wmi_set_wsc_status_cmd(struct wmi_t *wmip, A_UINT32 status) } #if defined(CONFIG_TARGET_PROFILE_SUPPORT) -A_STATUS +int wmi_prof_cfg_cmd(struct wmi_t *wmip, A_UINT32 period, A_UINT32 nbins) @@ -5615,7 +5615,7 @@ wmi_prof_cfg_cmd(struct wmi_t *wmip, return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_CFG_CMDID, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_prof_addr_set_cmd(struct wmi_t *wmip, A_UINT32 addr) { void *osbuf; @@ -5635,26 +5635,26 @@ wmi_prof_addr_set_cmd(struct wmi_t *wmip, A_UINT32 addr) return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_ADDR_SET_CMDID, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_prof_start_cmd(struct wmi_t *wmip) { return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_START_CMDID); } -A_STATUS +int wmi_prof_stop_cmd(struct wmi_t *wmip) { return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_STOP_CMDID); } -A_STATUS +int wmi_prof_count_get_cmd(struct wmi_t *wmip) { return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_COUNT_GET_CMDID); } /* Called to handle WMIX_PROF_CONT_EVENTID */ -static A_STATUS +static int wmi_prof_count_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMIX_PROF_COUNT_EVENT *prof_data = (WMIX_PROF_COUNT_EVENT *)datap; @@ -5923,7 +5923,7 @@ ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, return threshold; } -static A_STATUS +static int wmi_send_rssi_threshold_params(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd) { @@ -5947,7 +5947,7 @@ wmi_send_rssi_threshold_params(struct wmi_t *wmip, return (wmi_cmd_send(wmip, osbuf, WMI_RSSI_THRESHOLD_PARAMS_CMDID, NO_SYNC_WMIFLAG)); } -static A_STATUS +static int wmi_send_snr_threshold_params(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd) { @@ -5971,7 +5971,7 @@ wmi_send_snr_threshold_params(struct wmi_t *wmip, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd) { void *osbuf; @@ -5998,14 +5998,14 @@ bss_t *wmi_rm_current_bss (struct wmi_t *wmip, A_UINT8 *id) return wlan_node_remove (&wmip->wmi_scan_table, id); } -A_STATUS wmi_add_current_bss (struct wmi_t *wmip, A_UINT8 *id, bss_t *bss) +int wmi_add_current_bss (struct wmi_t *wmip, A_UINT8 *id, bss_t *bss) { wlan_setup_node (&wmip->wmi_scan_table, bss, id); return A_OK; } #ifdef ATH_AR6K_11N_SUPPORT -static A_STATUS +static int wmi_addba_req_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_ADDBA_REQ_EVENT *cmd = (WMI_ADDBA_REQ_EVENT *)datap; @@ -6016,7 +6016,7 @@ wmi_addba_req_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } -static A_STATUS +static int wmi_addba_resp_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_ADDBA_RESP_EVENT *cmd = (WMI_ADDBA_RESP_EVENT *)datap; @@ -6026,7 +6026,7 @@ wmi_addba_resp_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_delba_req_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_DELBA_EVENT *cmd = (WMI_DELBA_EVENT *)datap; @@ -6036,7 +6036,7 @@ wmi_delba_req_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -A_STATUS +int wmi_btcoex_config_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); @@ -6047,7 +6047,7 @@ wmi_btcoex_config_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } -A_STATUS +int wmi_btcoex_stats_event_rx(struct wmi_t * wmip,A_UINT8 * datap,int len) { A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); @@ -6059,7 +6059,7 @@ wmi_btcoex_stats_event_rx(struct wmi_t * wmip,A_UINT8 * datap,int len) } #endif -static A_STATUS +static int wmi_hci_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_HCI_EVENT *cmd = (WMI_HCI_EVENT *)datap; @@ -6083,7 +6083,7 @@ wmi_hci_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) * commit cmd will not be sent to target. Without calling this IOCTL * the changes will not take effect. */ -A_STATUS +int wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p) { void *osbuf; @@ -6109,7 +6109,7 @@ wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p) * This command will be used to enable/disable hidden ssid functioanlity of * beacon. If it is enabled, ssid will be NULL in beacon. */ -A_STATUS +int wmi_ap_set_hidden_ssid(struct wmi_t *wmip, A_UINT8 hidden_ssid) { void *osbuf; @@ -6138,7 +6138,7 @@ wmi_ap_set_hidden_ssid(struct wmi_t *wmip, A_UINT8 hidden_ssid) * is max num of STA supported by AP). Value was already validated * in ioctl.c */ -A_STATUS +int wmi_ap_set_num_sta(struct wmi_t *wmip, A_UINT8 num_sta) { void *osbuf; @@ -6166,7 +6166,7 @@ wmi_ap_set_num_sta(struct wmi_t *wmip, A_UINT8 num_sta) * be allowed to connect with this AP. When this list is empty * firware will allow all STAs till the count reaches AP_MAX_NUM_STA. */ -A_STATUS +int wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *acl) { void *osbuf; @@ -6192,7 +6192,7 @@ wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *acl) * be allowed to connect with this AP. When this list is empty * firware will allow all STAs till the count reaches AP_MAX_NUM_STA. */ -A_STATUS +int wmi_ap_set_mlme(struct wmi_t *wmip, A_UINT8 cmd, A_UINT8 *mac, A_UINT16 reason) { void *osbuf; @@ -6214,7 +6214,7 @@ wmi_ap_set_mlme(struct wmi_t *wmip, A_UINT8 cmd, A_UINT8 *mac, A_UINT16 reason) return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_MLME_CMDID, NO_SYNC_WMIFLAG)); } -static A_STATUS +static int wmi_pspoll_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { WMI_PSPOLL_EVENT *ev; @@ -6228,7 +6228,7 @@ wmi_pspoll_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } -static A_STATUS +static int wmi_dtimexpiry_event_rx(struct wmi_t *wmip, A_UINT8 *datap,int len) { A_WMI_DTIMEXPIRY_EVENT(wmip->wmi_devt); @@ -6236,7 +6236,7 @@ wmi_dtimexpiry_event_rx(struct wmi_t *wmip, A_UINT8 *datap,int len) } #ifdef WAPI_ENABLE -static A_STATUS +static int wmi_wapi_rekey_event_rx(struct wmi_t *wmip, A_UINT8 *datap,int len) { A_UINT8 *ev; @@ -6251,7 +6251,7 @@ wmi_wapi_rekey_event_rx(struct wmi_t *wmip, A_UINT8 *datap,int len) } #endif -A_STATUS +int wmi_set_pvb_cmd(struct wmi_t *wmip, A_UINT16 aid, A_BOOL flag) { WMI_AP_SET_PVB_CMD *cmd; @@ -6272,7 +6272,7 @@ wmi_set_pvb_cmd(struct wmi_t *wmip, A_UINT16 aid, A_BOOL flag) return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_PVB_CMDID, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_ap_conn_inact_time(struct wmi_t *wmip, A_UINT32 period) { WMI_AP_CONN_INACT_CMD *cmd; @@ -6292,7 +6292,7 @@ wmi_ap_conn_inact_time(struct wmi_t *wmip, A_UINT32 period) return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONN_INACT_CMDID, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_ap_bgscan_time(struct wmi_t *wmip, A_UINT32 period, A_UINT32 dwell) { WMI_AP_PROT_SCAN_TIME_CMD *cmd; @@ -6313,7 +6313,7 @@ wmi_ap_bgscan_time(struct wmi_t *wmip, A_UINT32 period, A_UINT32 dwell) return (wmi_cmd_send(wmip, osbuf, WMI_AP_PROT_SCAN_TIME_CMDID, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_ap_set_dtim(struct wmi_t *wmip, A_UINT8 dtim) { WMI_AP_SET_DTIM_CMD *cmd; @@ -6341,7 +6341,7 @@ wmi_ap_set_dtim(struct wmi_t *wmip, A_UINT8 dtim) * OR with AP_ACL_RETAIN_LIST_MASK, else the existing list will be cleared. * If there is no chage in policy, the list will be intact. */ -A_STATUS +int wmi_ap_set_acl_policy(struct wmi_t *wmip, A_UINT8 policy) { void *osbuf; @@ -6361,7 +6361,7 @@ wmi_ap_set_acl_policy(struct wmi_t *wmip, A_UINT8 policy) return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_POLICY_CMDID, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_ap_set_rateset(struct wmi_t *wmip, A_UINT8 rateset) { void *osbuf; @@ -6382,7 +6382,7 @@ wmi_ap_set_rateset(struct wmi_t *wmip, A_UINT8 rateset) } #ifdef ATH_AR6K_11N_SUPPORT -A_STATUS +int wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd) { void *osbuf; @@ -6407,7 +6407,7 @@ wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd) NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_ht_op_cmd(struct wmi_t *wmip, A_UINT8 sta_chan_width) { void *osbuf; @@ -6429,7 +6429,7 @@ wmi_set_ht_op_cmd(struct wmi_t *wmip, A_UINT8 sta_chan_width) } #endif -A_STATUS +int wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, A_UINT32 *pMaskArray) { void *osbuf; @@ -6450,7 +6450,7 @@ wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, A_UINT32 *pMaskArray) } -A_STATUS +int wmi_send_hci_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT16 sz) { void *osbuf; @@ -6470,7 +6470,7 @@ wmi_send_hci_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT16 sz) } #ifdef ATH_AR6K_11N_SUPPORT -A_STATUS +int wmi_allow_aggr_cmd(struct wmi_t *wmip, A_UINT16 tx_tidmask, A_UINT16 rx_tidmask) { void *osbuf; @@ -6490,7 +6490,7 @@ wmi_allow_aggr_cmd(struct wmi_t *wmip, A_UINT16 tx_tidmask, A_UINT16 rx_tidmask) return (wmi_cmd_send(wmip, osbuf, WMI_ALLOW_AGGR_CMDID, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_setup_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid) { void *osbuf; @@ -6509,7 +6509,7 @@ wmi_setup_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid) return (wmi_cmd_send(wmip, osbuf, WMI_ADDBA_REQ_CMDID, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_delete_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid, A_BOOL uplink) { void *osbuf; @@ -6531,7 +6531,7 @@ wmi_delete_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid, A_BOOL uplink) } #endif -A_STATUS +int wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, A_UINT8 rxMetaVersion, A_BOOL rxDot11Hdr, A_BOOL defragOnHost) { @@ -6555,7 +6555,7 @@ wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, A_UINT8 rxMetaVersion, } -A_STATUS +int wmi_set_thin_mode_cmd(struct wmi_t *wmip, A_BOOL bThinMode) { void *osbuf; @@ -6576,7 +6576,7 @@ wmi_set_thin_mode_cmd(struct wmi_t *wmip, A_BOOL bThinMode) } -A_STATUS +int wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence) { void *osbuf; @@ -6597,7 +6597,7 @@ wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE pre NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_set_pmk_cmd(struct wmi_t *wmip, A_UINT8 *pmk) { void *osbuf; @@ -6618,7 +6618,7 @@ wmi_set_pmk_cmd(struct wmi_t *wmip, A_UINT8 *pmk) return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMK_CMDID, NO_SYNC_WMIFLAG)); } -A_STATUS +int wmi_SGI_cmd(struct wmi_t *wmip, A_UINT32 sgiMask, A_UINT8 sgiPERThreshold) { void *osbuf; -- cgit v1.2.3 From 509c9d973055e3d98c0d2aa2cb40c9139526fd74 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 27 Jan 2011 20:04:20 -0800 Subject: staging: ath6kl: Remove A_SUCCESS macro Remove obfuscating A_SUCCESS(foo) macro. Just test for !foo instead. Reformat a few macros that used A_SUCCESS for better readability. Add do { foo } while (0) surrounds to those macros too. Signed-off-by: Joe Perches Acked-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/bmi/src/bmi.c | 2 +- .../staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 4 ++-- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 6 +++--- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 16 ++++++++++------ drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c | 4 ++-- drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c | 6 +++--- .../staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c | 21 +++++++++++++-------- drivers/staging/ath6kl/htc2/htc_recv.c | 10 +++++----- drivers/staging/ath6kl/include/common/athdefs.h | 3 +-- drivers/staging/ath6kl/miscdrv/ar3kconfig.c | 2 +- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 10 +++++----- 11 files changed, 46 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/bmi/src/bmi.c b/drivers/staging/ath6kl/bmi/src/bmi.c index a782166875ef..ccec7c4ff4ad 100644 --- a/drivers/staging/ath6kl/bmi/src/bmi.c +++ b/drivers/staging/ath6kl/bmi/src/bmi.c @@ -985,7 +985,7 @@ BMIFastDownload(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 status = BMILZData(device, (A_UINT8 *)&lastWord, 4); } - if (A_SUCCESS(status)) { + if (!status) { // // Close compressed stream and open a new (fake) one. This serves mainly to flush Target caches. // diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index 61166a5cb02e..56f6a07117a5 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -1120,7 +1120,7 @@ static int hifDeviceResume(struct device *dev) } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceResume\n")); - return A_SUCCESS(status) ? 0 : status; + return status; } #endif /* CONFIG_PM */ @@ -1167,7 +1167,7 @@ int hifWaitForPendingRecv(HIF_DEVICE *device) status = HIFReadWrite(device, HOST_INT_STATUS_ADDRESS, (A_UINT8 *)&host_int_status, sizeof(host_int_status), HIF_RD_SYNC_BYTE_INC, NULL); - host_int_status = A_SUCCESS(status) ? (host_int_status & (1 << 0)) : 0; + host_int_status = !status ? (host_int_status & (1 << 0)) : 0; if (host_int_status) { schedule(); /* schedule for next dsrHandler */ } diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index 8c6d6591ecad..65c5d9b671a4 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -516,7 +516,7 @@ int DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,A_BOOL *pbIsRec break; } - host_int_status = A_SUCCESS(status) ? (host_int_status & (1 << 0)):0; + host_int_status = !status ? (host_int_status & (1 << 0)):0; if(!host_int_status) { status = A_OK; @@ -832,7 +832,7 @@ int DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer) /* we can try to use a virtual DMA scatter mechanism using legacy HIFReadWrite() */ status = DevSetupVirtualScatterSupport(pDev); - if (A_SUCCESS(status)) { + if (!status) { AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("AR6K: virtual scatter transfers enabled (max scatter items:%d: maxlen:%d) \n", DEV_GET_MAX_MSG_PER_BUNDLE(pDev), DEV_GET_MAX_BUNDLE_LENGTH(pDev))); @@ -844,7 +844,7 @@ int DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer) DEV_GET_MAX_MSG_PER_BUNDLE(pDev), DEV_GET_MAX_BUNDLE_LENGTH(pDev))); } - if (A_SUCCESS(status)) { + if (!status) { /* for the recv path, the maximum number of bytes per recv bundle is just limited * by the maximum transfer size at the HIF layer */ pDev->MaxRecvBundleSize = pDev->HifScatterInfo.MaxTransferSizePerScatterReq; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index 7578e91562b9..2eced101d162 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -275,12 +275,16 @@ static INLINE int DevRecvPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 int DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, A_BOOL FromDMA); /* copy any READ data back into scatter list */ -#define DEV_FINISH_SCATTER_OPERATION(pR) \ - if (A_SUCCESS((pR)->CompletionStatus) && \ - !((pR)->Request & HIF_WRITE) && \ - ((pR)->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) { \ - (pR)->CompletionStatus = DevCopyScatterListToFromDMABuffer((pR),FROM_DMA_BUFFER); \ - } +#define DEV_FINISH_SCATTER_OPERATION(pR) \ +do { \ + if (!((pR)->CompletionStatus) && \ + !((pR)->Request & HIF_WRITE) && \ + ((pR)->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) { \ + (pR)->CompletionStatus = \ + DevCopyScatterListToFromDMABuffer((pR), \ + FROM_DMA_BUFFER); \ + } \ +} while (0) /* copy any WRITE data to bounce buffer */ static INLINE int DEV_PREPARE_SCATTER_OPERATION(HIF_SCATTER_REQ *pReq) { diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c index 21d88f19011d..f12ae42e4152 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c @@ -372,7 +372,7 @@ static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket) * go get the next message */ status = pDev->MessagePendingCallback(pDev->HTCContext, &lookAhead, 1, NULL, &fetched); - if (A_SUCCESS(status) && !fetched) { + if (!status && !fetched) { /* HTC layer could not pull out messages due to lack of resources, stop IRQ processing */ AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("MessagePendingCallback did not pull any messages, force-ack \n")); DevAsyncIrqProcessComplete(pDev); @@ -725,7 +725,7 @@ int DevDsrHandler(void *context) } - if (A_SUCCESS(status) && !asyncProc) { + if (!status && !asyncProc) { /* Ack the interrupt only if : * 1. we did not get any errors in processing interrupts * 2. there are no outstanding async processing requests */ diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c index d6b18eeaccf2..4c4c8fbfe127 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c @@ -589,7 +589,7 @@ int DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, A_BOOL AsyncMode, int *pCredits } if (pIOPacket != NULL) { - if (A_SUCCESS(status)) { + if (!status) { /* sync mode processing */ *pCredits = ProcessCreditCounterReadBuffer(pIOPacket->pBuffer, AR6K_REG_IO_BUFFER_SIZE); } @@ -614,7 +614,7 @@ int DevGMboxReadCreditSize(AR6K_DEVICE *pDev, int *pCreditSize) HIF_RD_SYNC_BYTE_FIX, /* hit the register 4 times to align the I/O */ NULL); - if (A_SUCCESS(status)) { + if (!status) { if (buffer[0] == 0) { *pCreditSize = 256; } else { @@ -708,7 +708,7 @@ int DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int Signal, int AckTimeoutMS) } while (FALSE); - if (A_SUCCESS(status)) { + if (!status) { /* now read back the register to see if the bit cleared */ while (AckTimeoutMS) { status = HIFReadWrite(pDev->HIFDevice, diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c index 6b61dc4c41ce..8c801b09827b 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c @@ -82,11 +82,16 @@ typedef struct { #define LOCK_HCI_TX(t) A_MUTEX_LOCK(&(t)->HCITxLock); #define UNLOCK_HCI_TX(t) A_MUTEX_UNLOCK(&(t)->HCITxLock); -#define DO_HCI_RECV_INDICATION(p,pt) \ -{ AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI: Indicate Recv on packet:0x%lX status:%d len:%d type:%d \n", \ - (unsigned long)(pt),(pt)->Status, A_SUCCESS((pt)->Status) ? (pt)->ActualLength : 0, HCI_GET_PACKET_TYPE(pt))); \ - (p)->HCIConfig.pHCIPktRecv((p)->HCIConfig.pContext, (pt)); \ -} +#define DO_HCI_RECV_INDICATION(p, pt) \ +do { \ + AR_DEBUG_PRINTF(ATH_DEBUG_RECV, \ + ("HCI: Indicate Recv on packet:0x%lX status:%d len:%d type:%d \n", \ + (unsigned long)(pt), \ + (pt)->Status, \ + !(pt)->Status ? (pt)->ActualLength : 0, \ + HCI_GET_PACKET_TYPE(pt))); \ + (p)->HCIConfig.pHCIPktRecv((p)->HCIConfig.pContext, (pt)); \ +} while (0) #define DO_HCI_SEND_INDICATION(p,pt) \ { AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: Indicate Send on packet:0x%lX status:%d type:%d \n", \ @@ -175,7 +180,7 @@ static int InitTxCreditState(GMBOX_PROTO_HCI_UART *pProt) } while (FALSE); - if (A_SUCCESS(status)) { + if (!status) { pProt->CreditsAvailable = pProt->CreditsMax; AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HCI : InitTxCreditState - credits avail: %d, size: %d \n", pProt->CreditsAvailable, pProt->CreditSize)); @@ -768,7 +773,7 @@ static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, A_BOOL S if (Synchronous) { A_ASSERT(pPacket != NULL); - if (A_SUCCESS(status) && (!synchSendComplete)) { + if (!status && (!synchSendComplete)) { status = A_EBUSY; A_ASSERT(FALSE); LOCK_HCI_TX(pProt); @@ -865,7 +870,7 @@ int GMboxProtocolInstall(AR6K_DEVICE *pDev) } while (FALSE); - if (A_SUCCESS(status)) { + if (!status) { LOCK_AR6K(pDev); DEV_GMBOX_SET_PROTOCOL(pDev, HCIUartMessagePending, diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c index 189d5106c9bb..9762109b8bb3 100644 --- a/drivers/staging/ath6kl/htc2/htc_recv.c +++ b/drivers/staging/ath6kl/htc2/htc_recv.c @@ -410,7 +410,7 @@ static INLINE void HTCAsyncRecvCheckMorePackets(HTC_TARGET *target, "BAD lookaheads from lookahead report"); #endif } - if (A_SUCCESS(nextStatus) && !fetched) { + if (!nextStatus && !fetched) { /* we could not fetch any more packets due to resources */ DevAsyncIrqProcessComplete(&target->Device); } @@ -923,14 +923,14 @@ static void HTCAsyncRecvScatterCompletion(HIF_SCATTER_REQ *pScatterReq) * break out of this loop */ numLookAheads = 0; - if (A_SUCCESS(pScatterReq->CompletionStatus)) { + if (!pScatterReq->CompletionStatus) { /* process header for each of the recv packets */ status = HTCProcessRecvHeader(target,pPacket,lookAheads,&numLookAheads); } else { status = A_ERROR; } - if (A_SUCCESS(status)) { + if (!status) { #ifdef HTC_EP_STAT_PROFILING LOCK_HTC_RX(target); HTC_RX_STAT_PROFILE(target,pEndpoint,numLookAheads); @@ -1085,7 +1085,7 @@ static int HTCIssueRecvPacketBundle(HTC_TARGET *target, status = DevSubmitScatterRequest(&target->Device, pScatterReq, DEV_SCATTER_READ, asyncMode); - if (A_SUCCESS(status)) { + if (!status) { *pNumPacketsFetched = i; } @@ -1261,7 +1261,7 @@ int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int Nu } - if (A_SUCCESS(status)) { + if (!status) { CheckRecvWaterMark(pEndpoint); } diff --git a/drivers/staging/ath6kl/include/common/athdefs.h b/drivers/staging/ath6kl/include/common/athdefs.h index 2cd072012388..ef6075487aec 100644 --- a/drivers/staging/ath6kl/include/common/athdefs.h +++ b/drivers/staging/ath6kl/include/common/athdefs.h @@ -73,8 +73,7 @@ #define A_PHY_ERROR 27 /* RX PHY error */ #define A_CONSUMED 28 /* Object was consumed */ -#define A_SUCCESS(x) (x == A_OK) -#define A_FAILED(x) (!A_SUCCESS(x)) +#define A_FAILED(x) (!!x) #ifndef TRUE #define TRUE 1 diff --git a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c index 687f963ec468..fa6b43f59943 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c @@ -288,7 +288,7 @@ static int AR3KExitMinBoot(AR3K_CONFIG_INFO *pConfig) &pEvent, &pBufferToFree); - if (A_SUCCESS(status)) { + if (!status) { if (pEvent[EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET] != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR3K Config: MinBoot exit command event status failed: %d \n", diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index c171be5a1099..4ad78f25f182 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -1674,8 +1674,8 @@ ar6000_avail_ev(void *context, void *hif_handle) if (ar_netif) { HIF_DEVICE_OS_DEVICE_INFO osDevInfo; A_MEMZERO(&osDevInfo, sizeof(osDevInfo)); - if ( A_SUCCESS( HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_OS_DEVICE, - &osDevInfo, sizeof(osDevInfo))) ) { + if (!HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_OS_DEVICE, + &osDevInfo, sizeof(osDevInfo))) { SET_NETDEV_DEV(dev, osDevInfo.pOSDevice); } } @@ -3115,7 +3115,7 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) if (ac == HCI_TRANSPORT_STREAM_NUM) { /* pass this to HCI */ #ifndef EXPORT_HCI_BRIDGE_INTERFACE - if (A_SUCCESS(hci_test_send(ar,skb))) { + if (!hci_test_send(ar,skb)) { return 0; } #endif @@ -3428,7 +3428,7 @@ ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPacketQueue) /* add this to the list, use faster non-lock API */ __skb_queue_tail(&skb_queue,pktSkb); - if (A_SUCCESS(status)) { + if (!status) { A_ASSERT(pPacket->ActualLength == A_NETBUF_LEN(pktSkb)); } @@ -3597,7 +3597,7 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) * and adaptive power throughput state */ AR6000_SPIN_LOCK(&ar->arLock, 0); - if (A_SUCCESS(status)) { + if (!status) { AR6000_STAT_INC(ar, rx_packets); ar->arNetStats.rx_bytes += pPacket->ActualLength; #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL -- cgit v1.2.3 From 391bb2116a4ffeeee75dfbbe2e9de678d2fac88d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 27 Jan 2011 20:04:21 -0800 Subject: staging: ath6kl: Remove A_FAILED macro Remove obfuscating A_FAILED(foo) macro. Just test for foo instead. Signed-off-by: Joe Perches Acked-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/bmi/src/bmi.c | 6 +-- .../staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 2 +- .../ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c | 6 +-- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 22 +++++------ drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c | 24 ++++++------ drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c | 28 +++++++------- .../ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c | 44 +++++++++++----------- drivers/staging/ath6kl/htc2/htc.c | 18 ++++----- drivers/staging/ath6kl/htc2/htc_recv.c | 42 ++++++++++----------- drivers/staging/ath6kl/htc2/htc_send.c | 4 +- drivers/staging/ath6kl/htc2/htc_services.c | 4 +- drivers/staging/ath6kl/include/common/athdefs.h | 2 - drivers/staging/ath6kl/miscdrv/ar3kconfig.c | 36 +++++++++--------- drivers/staging/ath6kl/miscdrv/common_drv.c | 18 ++++----- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 36 +++++++++--------- drivers/staging/ath6kl/os/linux/ar6000_raw_if.c | 8 ++-- drivers/staging/ath6kl/os/linux/ar6k_pal.c | 6 +-- drivers/staging/ath6kl/os/linux/hci_bridge.c | 18 ++++----- drivers/staging/ath6kl/os/linux/ioctl.c | 6 +-- drivers/staging/ath6kl/wmi/wmi.c | 6 +-- 20 files changed, 166 insertions(+), 170 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/bmi/src/bmi.c b/drivers/staging/ath6kl/bmi/src/bmi.c index ccec7c4ff4ad..355e22bd505c 100644 --- a/drivers/staging/ath6kl/bmi/src/bmi.c +++ b/drivers/staging/ath6kl/bmi/src/bmi.c @@ -966,7 +966,7 @@ BMIFastDownload(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 A_UINT32 unalignedBytes = length & 0x3; status = BMILZStreamStart (device, address); - if (A_FAILED(status)) { + if (status) { return A_ERROR; } @@ -977,7 +977,7 @@ BMIFastDownload(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 status = BMILZData(device, buffer, lastWordOffset); - if (A_FAILED(status)) { + if (status) { return A_ERROR; } @@ -990,7 +990,7 @@ BMIFastDownload(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 // Close compressed stream and open a new (fake) one. This serves mainly to flush Target caches. // status = BMILZStreamStart (device, 0x00); - if (A_FAILED(status)) { + if (status) { return A_ERROR; } } diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index 56f6a07117a5..26d8a7f30990 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -724,7 +724,7 @@ HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, return A_ENOTSUP; } status = SetupHIFScatterSupport(device, (HIF_DEVICE_SCATTER_SUPPORT_INFO *)config); - if (A_FAILED(status)) { + if (status) { device->scatter_enabled = FALSE; } break; diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c index ceeced47cd22..7ec1f4a92cdf 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c @@ -176,7 +176,7 @@ int DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest) AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: data error: %d \n",data.error)); } - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: FAILED!!! (%s) Address: 0x%X, Block mode (BlockLen: %d, BlockCount: %d)\n", (pReq->Request & HIF_WRITE) ? "WRITE":"READ",pReq->Address, data.blksz, data.blocks)); } @@ -265,7 +265,7 @@ static int HifReadWriteScatter(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq) } while (FALSE); - if (A_FAILED(status) && (request & HIF_ASYNCHRONOUS)) { + if (status && (request & HIF_ASYNCHRONOUS)) { pReq->CompletionStatus = status; pReq->CompletionRoutine(pReq); status = A_OK; @@ -348,7 +348,7 @@ int SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO * } while (FALSE); - if (A_FAILED(status)) { + if (status) { CleanupHIFScatterResources(device); } diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index 65c5d9b671a4..6a410f1bae21 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -96,7 +96,7 @@ int DevSetup(AR6K_DEVICE *pDev) status = HIFAttachHTC(pDev->HIFDevice, &htcCallbacks); - if (A_FAILED(status)) { + if (status) { break; } @@ -197,7 +197,7 @@ int DevSetup(AR6K_DEVICE *pDev) status = DevDisableInterrupts(pDev); - if (A_FAILED(status)) { + if (status) { break; } @@ -205,7 +205,7 @@ int DevSetup(AR6K_DEVICE *pDev) } while (FALSE); - if (A_FAILED(status)) { + if (status) { if (pDev->HifAttached) { HIFDetachHTC(pDev->HIFDevice); pDev->HifAttached = FALSE; @@ -343,7 +343,7 @@ static void DevDoEnableDisableRecvAsyncHandler(void *Context, HTC_PACKET *pPacke AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDoEnableDisableRecvAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); - if (A_FAILED(pPacket->Status)) { + if (pPacket->Status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Failed to disable receiver, status:%d \n", pPacket->Status)); } @@ -393,7 +393,7 @@ static int DevDoEnableDisableRecvOverride(AR6K_DEVICE *pDev, A_BOOL EnableRecv, } while (FALSE); - if (A_FAILED(status) && (pIOPacket != NULL)) { + if (status && (pIOPacket != NULL)) { AR6KFreeIOPacket(pDev,pIOPacket); } @@ -462,7 +462,7 @@ static int DevDoEnableDisableRecvNormal(AR6K_DEVICE *pDev, A_BOOL EnableRecv, A_ } while (FALSE); - if (A_FAILED(status) && (pIOPacket != NULL)) { + if (status && (pIOPacket != NULL)) { AR6KFreeIOPacket(pDev,pIOPacket); } @@ -510,7 +510,7 @@ int DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,A_BOOL *pbIsRec sizeof(A_UCHAR), HIF_RD_SYNC_BYTE_INC, NULL); - if(A_FAILED(status)) + if(status) { AR_DEBUG_PRINTF(ATH_LOG_ERR,("DevWaitForPendingRecv:Read HOST_INT_STATUS_ADDRESS Failed 0x%X\n",status)); break; @@ -721,7 +721,7 @@ static int DevReadWriteScatter(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) } while (FALSE); - if ((status != A_PENDING) && A_FAILED(status) && (request & HIF_ASYNCHRONOUS)) { + if ((status != A_PENDING) && status && (request & HIF_ASYNCHRONOUS)) { if (pIOPacket != NULL) { AR6KFreeIOPacket(pDev,pIOPacket); } @@ -790,7 +790,7 @@ static int DevSetupVirtualScatterSupport(AR6K_DEVICE *pDev) DevFreeScatterReq((HIF_DEVICE *)pDev,pReq); } - if (A_FAILED(status)) { + if (status) { DevCleanupVirtualScatterSupport(pDev); } else { pDev->HifScatterInfo.pAllocateReqFunc = DevAllocScatterReq; @@ -825,7 +825,7 @@ int DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer) &pDev->HifScatterInfo, sizeof(pDev->HifScatterInfo)); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6K: ** HIF layer does not support scatter requests (%d) \n",status)); @@ -919,7 +919,7 @@ int DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, A_B status = DEV_PREPARE_SCATTER_OPERATION(pScatterReq); - if (A_FAILED(status)) { + if (status) { if (Async) { pScatterReq->CompletionStatus = status; pScatterReq->CompletionRoutine(pScatterReq); diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c index f12ae42e4152..1e3d6cd43554 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c @@ -85,7 +85,7 @@ int DevPollMboxMsgRecv(AR6K_DEVICE *pDev, status = pDev->GetPendingEventsFunc(pDev->HIFDevice, &events, NULL); - if (A_FAILED(status)) + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to get pending events \n")); break; @@ -109,7 +109,7 @@ int DevPollMboxMsgRecv(AR6K_DEVICE *pDev, HIF_RD_SYNC_BYTE_INC, NULL); - if (A_FAILED(status)){ + if (status){ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to read register table \n")); break; } @@ -310,7 +310,7 @@ static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket) do { - if (A_FAILED(pPacket->Status)) { + if (pPacket->Status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" GetEvents I/O request failed, status:%d \n", pPacket->Status)); /* bail out, don't unmask HIF interrupt */ @@ -501,7 +501,7 @@ static int ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pASyncPr &events, NULL); - if (A_FAILED(status)) { + if (status) { break; } @@ -550,7 +550,7 @@ static int ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pASyncPr HIF_RD_SYNC_BYTE_INC, NULL); - if (A_FAILED(status)) { + if (status) { break; } @@ -597,7 +597,7 @@ static int ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pASyncPr do { /* did the interrupt status fetches succeed? */ - if (A_FAILED(status)) { + if (status) { break; } @@ -617,7 +617,7 @@ static int ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pASyncPr * completion routine of the callers read request. This can improve performance * by reducing context switching when we rapidly pull packets */ status = pDev->MessagePendingCallback(pDev->HTCContext, &lookAhead, 1, pASyncProcessing, &fetched); - if (A_FAILED(status)) { + if (status) { break; } @@ -637,7 +637,7 @@ static int ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pASyncPr if (HOST_INT_STATUS_CPU_GET(host_int_status)) { /* CPU Interrupt */ status = DevServiceCPUInterrupt(pDev); - if (A_FAILED(status)){ + if (status){ break; } } @@ -645,7 +645,7 @@ static int ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pASyncPr if (HOST_INT_STATUS_ERROR_GET(host_int_status)) { /* Error Interrupt */ status = DevServiceErrorInterrupt(pDev); - if (A_FAILED(status)){ + if (status){ break; } } @@ -653,7 +653,7 @@ static int ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pASyncPr if (HOST_INT_STATUS_COUNTER_GET(host_int_status)) { /* Counter Interrupt */ status = DevServiceCounterInterrupt(pDev); - if (A_FAILED(status)){ + if (status){ break; } } @@ -697,7 +697,7 @@ int DevDsrHandler(void *context) while (!done) { status = ProcessPendingIRQs(pDev, &done, &asyncProc); - if (A_FAILED(status)) { + if (status) { break; } @@ -763,7 +763,7 @@ void DumpAR6KDevState(AR6K_DEVICE *pDev) HIF_RD_SYNC_BYTE_INC, NULL); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("DumpAR6KDevState : Failed to read register table (%d) \n",status)); return; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c index 4c4c8fbfe127..74165765f5ea 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c @@ -65,7 +65,7 @@ static void DevGMboxIRQActionAsyncHandler(void *Context, HTC_PACKET *pPacket) AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxIRQActionAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); - if (A_FAILED(pPacket->Status)) { + if (pPacket->Status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("IRQAction Operation (%d) failed! status:%d \n", pPacket->PktInfo.AsRx.HTCRxFlags,pPacket->Status)); } @@ -137,7 +137,7 @@ static int DevGMboxCounterEnableDisable(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE NULL); } while (FALSE); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, status)); } else { @@ -244,7 +244,7 @@ int DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, A_BOOL } while (FALSE); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, status)); } else { @@ -285,7 +285,7 @@ int DevSetupGMbox(AR6K_DEVICE *pDev) status = DevGMboxIRQAction(pDev, GMBOX_DISABLE_ALL, PROC_IO_SYNC); - if (A_FAILED(status)) { + if (status) { break; } @@ -305,13 +305,13 @@ int DevSetupGMbox(AR6K_DEVICE *pDev) HIF_WR_SYNC_BYTE_FIX, /* hit this register 4 times */ NULL); - if (A_FAILED(status)) { + if (status) { break; } status = GMboxProtocolInstall(pDev); - if (A_FAILED(status)) { + if (status) { break; } @@ -348,7 +348,7 @@ int DevCheckGMboxInterrupts(AR6K_DEVICE *pDev) status = A_ECOMM; } - if (A_FAILED(status)) { + if (status) { if (pDev->GMboxInfo.pTargetFailureCallback != NULL) { pDev->GMboxInfo.pTargetFailureCallback(pDev->GMboxInfo.pProtocolContext, status); } @@ -365,7 +365,7 @@ int DevCheckGMboxInterrupts(AR6K_DEVICE *pDev) } } - if (A_FAILED(status)) { + if (status) { break; } @@ -378,7 +378,7 @@ int DevCheckGMboxInterrupts(AR6K_DEVICE *pDev) /* do synchronous read */ status = DevGMboxReadCreditCounter(pDev, PROC_IO_SYNC, &credits); - if (A_FAILED(status)) { + if (status) { break; } @@ -522,7 +522,7 @@ static void DevGMboxReadCreditsAsyncHandler(void *Context, HTC_PACKET *pPacket) AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxReadCreditsAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); - if (A_FAILED(pPacket->Status)) { + if (pPacket->Status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Read Credit Operation failed! status:%d \n", pPacket->Status)); } else { @@ -583,7 +583,7 @@ int DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, A_BOOL AsyncMode, int *pCredits NULL); } while (FALSE); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" DevGMboxReadCreditCounter failed! status:%d \n", status)); } @@ -659,7 +659,7 @@ int DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, A_UINT8 *pLookAheadBuffer, int HIF_RD_SYNC_BYTE_INC, NULL); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("DevGMboxRecvLookAheadPeek : Failed to read register table (%d) \n",status)); break; @@ -701,7 +701,7 @@ int DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int Signal, int AckTimeoutMS) HIF_WR_SYNC_BYTE_FIX, /* hit the register 4 times to align the I/O */ NULL); - if (A_FAILED(status)) { + if (status) { break; } @@ -718,7 +718,7 @@ int DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int Signal, int AckTimeoutMS) HIF_RD_SYNC_BYTE_FIX, NULL); - if (A_FAILED(status)) { + if (status) { break; } diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c index 8c801b09827b..bdb8632dbe84 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c @@ -140,7 +140,7 @@ static int InitTxCreditState(GMBOX_PROTO_HCI_UART *pProt) status = DevGMboxReadCreditCounter(pProt->pDev, PROC_IO_SYNC, &credits); - if (A_FAILED(status)) { + if (status) { break; } @@ -160,7 +160,7 @@ static int InitTxCreditState(GMBOX_PROTO_HCI_UART *pProt) pProt->CreditsMax += credits; } - if (A_FAILED(status)) { + if (status) { break; } @@ -174,7 +174,7 @@ static int InitTxCreditState(GMBOX_PROTO_HCI_UART *pProt) /* now get the size */ status = DevGMboxReadCreditSize(pProt->pDev, &pProt->CreditSize); - if (A_FAILED(status)) { + if (status) { break; } @@ -353,7 +353,7 @@ static int HCIUartMessagePending(void *pContext, A_UINT8 LookAheadBytes[], int V break; } - if (A_FAILED(status)) { + if (status) { break; } @@ -426,7 +426,7 @@ static int HCIUartMessagePending(void *pContext, A_UINT8 LookAheadBytes[], int V do { - if (A_FAILED(status) || (NULL == pPacket)) { + if (status || (NULL == pPacket)) { break; } @@ -438,7 +438,7 @@ static int HCIUartMessagePending(void *pContext, A_UINT8 LookAheadBytes[], int V status = DevGMboxRead(pProt->pDev, pPacket, totalRecvLength); - if (A_FAILED(status)) { + if (status) { break; } @@ -508,12 +508,12 @@ static int HCIUartMessagePending(void *pContext, A_UINT8 LookAheadBytes[], int V } while (FALSE); /* check if we need to disable the reciever */ - if (A_FAILED(status) || blockRecv) { + if (status || blockRecv) { DevGMboxIRQAction(pProt->pDev, GMBOX_RECV_IRQ_DISABLE, PROC_IO_SYNC); } /* see if we need to recycle the recv buffer */ - if (A_FAILED(status) && (pPacket != NULL)) { + if (status && (pPacket != NULL)) { HTC_PACKET_QUEUE queue; if (A_EPROTO == status) { @@ -537,7 +537,7 @@ static void HCISendPacketCompletion(void *Context, HTC_PACKET *pPacket) GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)Context; AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCISendPacketCompletion (pPacket:0x%lX) \n",(unsigned long)pPacket)); - if (A_FAILED(pPacket->Status)) { + if (pPacket->Status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Send Packet (0x%lX) failed: %d , len:%d \n", (unsigned long)pPacket, pPacket->Status, pPacket->ActualLength)); } @@ -556,7 +556,7 @@ static int SeekCreditsSynch(GMBOX_PROTO_HCI_UART *pProt) while (TRUE) { credits = 0; status = DevGMboxReadCreditCounter(pProt->pDev, PROC_IO_SYNC, &credits); - if (A_FAILED(status)) { + if (status) { break; } LOCK_HCI_TX(pProt); @@ -676,7 +676,7 @@ static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, A_BOOL S break; } - if (A_FAILED(status)) { + if (status) { break; } @@ -706,7 +706,7 @@ static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, A_BOOL S UNLOCK_HCI_TX(pProt); status = SeekCreditsSynch(pProt); LOCK_HCI_TX(pProt); - if (A_FAILED(status)) { + if (status) { break; } /* fall through and continue processing this send op */ @@ -784,7 +784,7 @@ static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, A_BOOL S UNLOCK_HCI_TX(pProt); } } else { - if (A_FAILED(status) && (pPacket != NULL)) { + if (status && (pPacket != NULL)) { pPacket->Status = status; DO_HCI_SEND_INDICATION(pProt,pPacket); } @@ -1052,7 +1052,7 @@ int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE UNLOCK_HCI_RX(pProt); - if (A_FAILED(status)) { + if (status) { while (!HTC_QUEUE_EMPTY(pQueue)) { pPacket = HTC_PACKET_DEQUEUE(pQueue); pPacket->Status = A_ECANCELED; @@ -1116,25 +1116,25 @@ int HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans) status = InitTxCreditState(pProt); - if (A_FAILED(status)) { + if (status) { break; } status = DevGMboxIRQAction(pProt->pDev, GMBOX_ERRORS_IRQ_ENABLE, PROC_IO_SYNC); - if (A_FAILED(status)) { + if (status) { break; } /* enable recv */ status = DevGMboxIRQAction(pProt->pDev, GMBOX_RECV_IRQ_ENABLE, PROC_IO_SYNC); - if (A_FAILED(status)) { + if (status) { break; } /* signal bridge side to power up BT */ status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_BT_ON, BTON_TIMEOUT_MS); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI_TransportStart : Failed to trigger BT ON \n")); break; } @@ -1178,7 +1178,7 @@ int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, bytes = sizeof(lookAhead); status = DevGMboxRecvLookAheadPeek(pProt->pDev,lookAhead,&bytes); - if (A_FAILED(status)) { + if (status) { break; } @@ -1204,13 +1204,13 @@ int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, break; } - if (A_FAILED(status)) { + if (status) { break; } pPacket->Completion = NULL; status = DevGMboxRead(pProt->pDev,pPacket,totalRecvLength); - if (A_FAILED(status)) { + if (status) { break; } @@ -1272,7 +1272,7 @@ int HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable) status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_PWR_SAV_OFF, BTPWRSAV_TIMEOUT_MS); } - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to enable/disable HCI power management!\n")); } else { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI power management enabled/disabled!\n")); diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index 2ab5975d79ef..b24698ebbecb 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -137,7 +137,7 @@ HTC_HANDLE HTCCreate(void *hif_handle, HTC_INIT_INFO *pInfo) /* setup device layer */ status = DevSetup(&target->Device); - if (A_FAILED(status)) { + if (status) { break; } @@ -145,7 +145,7 @@ HTC_HANDLE HTCCreate(void *hif_handle, HTC_INIT_INFO *pInfo) /* get the block sizes */ status = HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_MBOX_BLOCK_SIZE, blocksizes, sizeof(blocksizes)); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to get block size info from HIF layer...\n")); break; } @@ -165,7 +165,7 @@ HTC_HANDLE HTCCreate(void *hif_handle, HTC_INIT_INFO *pInfo) } } - if (A_FAILED(status)) { + if (status) { break; } @@ -192,7 +192,7 @@ HTC_HANDLE HTCCreate(void *hif_handle, HTC_INIT_INFO *pInfo) } while (FALSE); - if (A_FAILED(status)) { + if (status) { if (target != NULL) { HTCCleanup(target); target = NULL; @@ -249,7 +249,7 @@ int HTCWaitTarget(HTC_HANDLE HTCHandle) /* we should be getting 1 control message that the target is ready */ status = HTCWaitforControlMessage(target, &pPacket); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Target Not Available!!\n")); break; } @@ -305,7 +305,7 @@ int HTCWaitTarget(HTC_HANDLE HTCHandle) /* limit what HTC can handle */ target->MaxMsgPerBundle = min(HTC_HOST_MAX_MSG_PER_BUNDLE, target->MaxMsgPerBundle); /* target supports message bundling, setup device layer */ - if (A_FAILED(DevSetupMsgBundling(&target->Device,target->MaxMsgPerBundle))) { + if (DevSetupMsgBundling(&target->Device,target->MaxMsgPerBundle)) { /* device layer can't handle bundling */ target->MaxMsgPerBundle = 0; } else { @@ -351,7 +351,7 @@ int HTCWaitTarget(HTC_HANDLE HTCHandle) &connect, &resp); - if (!A_FAILED(status)) { + if (!status) { break; } @@ -419,14 +419,14 @@ int HTCStart(HTC_HANDLE HTCHandle) * target that the setup phase is complete */ status = HTCSendSetupComplete(target); - if (A_FAILED(status)) { + if (status) { break; } /* unmask interrupts */ status = DevUnmaskInterrupts(&target->Device); - if (A_FAILED(status)) { + if (status) { HTCStop(target); } diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c index 9762109b8bb3..b38211b8828b 100644 --- a/drivers/staging/ath6kl/htc2/htc_recv.c +++ b/drivers/staging/ath6kl/htc2/htc_recv.c @@ -204,7 +204,7 @@ static INLINE int HTCProcessTrailer(HTC_TARGET *target, break; } - if (A_FAILED(status)) { + if (status) { break; } @@ -214,7 +214,7 @@ static INLINE int HTCProcessTrailer(HTC_TARGET *target, } #ifdef ATH_DEBUG_MODULE - if (A_FAILED(status)) { + if (status) { DebugDumpBytes(pOrigBuffer,origLength,"BAD Recv Trailer"); } #endif @@ -341,7 +341,7 @@ static int HTCProcessRecvHeader(HTC_TARGET *target, pNumLookAheads, pPacket->Endpoint); - if (A_FAILED(status)) { + if (status) { break; } @@ -365,7 +365,7 @@ static int HTCProcessRecvHeader(HTC_TARGET *target, } while (FALSE); - if (A_FAILED(status)) { + if (status) { /* dump the whole packet */ #ifdef ATH_DEBUG_MODULE DebugDumpBytes(pBuf,pPacket->ActualLength < 256 ? pPacket->ActualLength : 256 ,"BAD HTC Recv PKT"); @@ -537,7 +537,7 @@ void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket) do { - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTCRecvCompleteHandler: request failed (status:%d, ep:%d) \n", pPacket->Status, pPacket->Endpoint)); break; @@ -545,7 +545,7 @@ void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket) /* process the header for any trailer data */ status = HTCProcessRecvHeader(target,pPacket,nextLookAheads,&numLookAheads); - if (A_FAILED(status)) { + if (status) { break; } @@ -570,7 +570,7 @@ void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket) } while (FALSE); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTCRecvCompleteHandler , message fetch failed (status = %d) \n", status)); @@ -605,7 +605,7 @@ int HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket) &lookAhead, HTC_TARGET_RESPONSE_TIMEOUT); - if (A_FAILED(status)) { + if (status) { break; } @@ -622,7 +622,7 @@ int HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket) break; } - if (A_FAILED(status)) { + if (status) { /* bad message */ AR_DEBUG_ASSERT(FALSE); status = A_EPROTO; @@ -653,7 +653,7 @@ int HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket) /* get the message from the device, this will block */ status = HTCIssueRecv(target, pPacket); - if (A_FAILED(status)) { + if (status) { break; } @@ -662,7 +662,7 @@ int HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket) pPacket->Status = status; - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTCWaitforControlMessage, HTCProcessRecvHeader failed (status = %d) \n", status)); @@ -674,7 +674,7 @@ int HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket) } while (FALSE); - if (A_FAILED(status)) { + if (status) { if (pPacket != NULL) { /* cleanup buffer on error */ HTC_FREE_CONTROL_RX(target,pPacket); @@ -856,7 +856,7 @@ static int AllocAndPrepareRxPackets(HTC_TARGET *target, pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH; } - if (A_FAILED(status)) { + if (status) { if (A_NO_RESOURCE == status) { /* this is actually okay */ status = A_OK; @@ -868,7 +868,7 @@ static int AllocAndPrepareRxPackets(HTC_TARGET *target, UNLOCK_HTC_RX(target); - if (A_FAILED(status)) { + if (status) { while (!HTC_QUEUE_EMPTY(pQueue)) { pPacket = HTC_PACKET_DEQUEUE(pQueue); /* recycle all allocated packets */ @@ -897,7 +897,7 @@ static void HTCAsyncRecvScatterCompletion(HIF_SCATTER_REQ *pScatterReq) A_ASSERT(!IS_DEV_IRQ_PROC_SYNC_MODE(&target->Device)); - if (A_FAILED(pScatterReq->CompletionStatus)) { + if (pScatterReq->CompletionStatus) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** Recv Scatter Request Failed: %d \n",pScatterReq->CompletionStatus)); } @@ -1186,7 +1186,7 @@ int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int Nu NumLookAheads, pEndpoint, &recvPktQueue); - if (A_FAILED(status)) { + if (status) { break; } @@ -1214,7 +1214,7 @@ int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int Nu asyncProc ? NULL : &syncCompletedPktsQueue, &pktsFetched, partialBundle); - if (A_FAILED(status)) { + if (status) { break; } @@ -1248,7 +1248,7 @@ int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int Nu /* go fetch the packet */ status = HTCIssueRecv(target, pPacket); - if (A_FAILED(status)) { + if (status) { break; } @@ -1295,7 +1295,7 @@ int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int Nu /* process header for each of the recv packets * note: the lookahead of the last packet is useful for us to continue in this loop */ status = HTCProcessRecvHeader(target,pPacket,lookAheads,&NumLookAheads); - if (A_FAILED(status)) { + if (status) { break; } @@ -1317,7 +1317,7 @@ int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int Nu DO_RCV_COMPLETION(pEndpoint,&container); } - if (A_FAILED(status)) { + if (status) { break; } @@ -1346,7 +1346,7 @@ int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int Nu REF_IRQ_STATUS_RECHECK(&target->Device); } - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to get pending recv messages (%d) \n",status)); /* cleanup any packets we allocated but didn't use to actually fetch any packets */ diff --git a/drivers/staging/ath6kl/htc2/htc_send.c b/drivers/staging/ath6kl/htc2/htc_send.c index 797400802e2a..e645e2d3b434 100644 --- a/drivers/staging/ath6kl/htc2/htc_send.c +++ b/drivers/staging/ath6kl/htc2/htc_send.c @@ -81,7 +81,7 @@ static INLINE void CompleteSentPacket(HTC_TARGET *target, HTC_ENDPOINT *pEndpoin { pPacket->Completion = NULL; - if (A_FAILED(pPacket->Status)) { + if (pPacket->Status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("CompleteSentPacket: request failed (status:%d, ep:%d, length:%d creds:%d) \n", pPacket->Status, pPacket->Endpoint, pPacket->ActualLength, pPacket->PktInfo.AsTx.CreditsUsed)); @@ -280,7 +280,7 @@ static void HTCAsyncSendScatterCompletion(HIF_SCATTER_REQ *pScatterReq) DEV_FINISH_SCATTER_OPERATION(pScatterReq); - if (A_FAILED(pScatterReq->CompletionStatus)) { + if (pScatterReq->CompletionStatus) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** Send Scatter Request Failed: %d \n",pScatterReq->CompletionStatus)); status = A_ERROR; } diff --git a/drivers/staging/ath6kl/htc2/htc_services.c b/drivers/staging/ath6kl/htc2/htc_services.c index a78660264977..63189b583618 100644 --- a/drivers/staging/ath6kl/htc2/htc_services.c +++ b/drivers/staging/ath6kl/htc2/htc_services.c @@ -184,14 +184,14 @@ int HTCConnectService(HTC_HANDLE HTCHandle, HTC_PREPARE_SEND_PKT(pSendPacket,0,0,0); status = HTCIssueSend(target,pSendPacket); - if (A_FAILED(status)) { + if (status) { break; } /* wait for response */ status = HTCWaitforControlMessage(target, &pRecvPacket); - if (A_FAILED(status)) { + if (status) { break; } /* we controlled the buffer creation so it has to be properly aligned */ diff --git a/drivers/staging/ath6kl/include/common/athdefs.h b/drivers/staging/ath6kl/include/common/athdefs.h index ef6075487aec..c6ae9ba84b6b 100644 --- a/drivers/staging/ath6kl/include/common/athdefs.h +++ b/drivers/staging/ath6kl/include/common/athdefs.h @@ -73,8 +73,6 @@ #define A_PHY_ERROR 27 /* RX PHY error */ #define A_CONSUMED 28 /* Object was consumed */ -#define A_FAILED(x) (!!x) - #ifndef TRUE #define TRUE 1 #endif diff --git a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c index fa6b43f59943..4bdc48925ebc 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c @@ -107,7 +107,7 @@ static int RecvHCIEvent(AR3K_CONFIG_INFO *pConfig, status = HCI_TransportRecvHCIEventSync(pConfig->pHCIDev, pRecvPacket, HCI_EVENT_RESP_TIMEOUTMS); - if (A_FAILED(status)) { + if (status) { break; } @@ -158,7 +158,7 @@ int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, status = SendHCICommand(pConfig, pBuffer + pConfig->pHCIProps->HeadRoom, CmdLength); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Failed to send HCI Command (%d) \n", status)); AR_DEBUG_PRINTBUF(pHCICommand,CmdLength,"HCI Bridge Failed HCI Command"); break; @@ -167,7 +167,7 @@ int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, /* reuse buffer to capture command complete event */ A_MEMZERO(pBuffer,length); status = RecvHCIEvent(pConfig,pBuffer,&length); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: HCI event recv failed \n")); AR_DEBUG_PRINTBUF(pHCICommand,CmdLength,"HCI Bridge Failed HCI Command"); break; @@ -229,7 +229,7 @@ static int AR3KConfigureHCIBaud(AR3K_CONFIG_INFO *pConfig) sizeof(hciBaudChangeCommand), &pEvent, &pBufferToFree); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Baud rate change failed! \n")); break; } @@ -255,7 +255,7 @@ static int AR3KConfigureHCIBaud(AR3K_CONFIG_INFO *pConfig) /* Tell target to change UART baud rate for AR6K */ status = HCI_TransportSetBaudRate(pConfig->pHCIDev, pConfig->AR3KBaudRate); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR3K Config: failed to set scale and step values: %d \n", status)); break; @@ -323,7 +323,7 @@ static int AR3KConfigureSendHCIReset(AR3K_CONFIG_INFO *pConfig) &pEvent, &pBufferToFree ); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: HCI reset failed! \n")); } @@ -384,7 +384,7 @@ static int AR3KEnableTLPM(AR3K_CONFIG_INFO *pConfig) if (pBufferToFree != NULL) { A_FREE(pBufferToFree); } - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HostWakeup Config Failed! \n")); return status; } @@ -399,7 +399,7 @@ static int AR3KEnableTLPM(AR3K_CONFIG_INFO *pConfig) if (pBufferToFree != NULL) { A_FREE(pBufferToFree); } - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Target Wakeup Config Failed! \n")); return status; } @@ -414,7 +414,7 @@ static int AR3KEnableTLPM(AR3K_CONFIG_INFO *pConfig) if (pBufferToFree != NULL) { A_FREE(pBufferToFree); } - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HostWakeup Enable Failed! \n")); return status; } @@ -429,7 +429,7 @@ static int AR3KEnableTLPM(AR3K_CONFIG_INFO *pConfig) if (pBufferToFree != NULL) { A_FREE(pBufferToFree); } - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Target Wakeup Enable Failed! \n")); return status; } @@ -444,7 +444,7 @@ static int AR3KEnableTLPM(AR3K_CONFIG_INFO *pConfig) if (pBufferToFree != NULL) { A_FREE(pBufferToFree); } - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Sleep Enable Failed! \n")); } @@ -468,13 +468,13 @@ int AR3KConfigure(AR3K_CONFIG_INFO *pConfig) /* disable asynchronous recv while we issue commands and receive events synchronously */ status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,FALSE); - if (A_FAILED(status)) { + if (status) { break; } if (pConfig->Flags & AR3K_CONFIG_FLAG_FORCE_MINBOOT_EXIT) { status = AR3KExitMinBoot(pConfig); - if (A_FAILED(status)) { + if (status) { break; } } @@ -491,7 +491,7 @@ int AR3KConfigure(AR3K_CONFIG_INFO *pConfig) if (pConfig->Flags & (AR3K_CONFIG_FLAG_SET_AR3K_BAUD | AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP)) { status = AR3KConfigureHCIBaud(pConfig); - if (A_FAILED(status)) { + if (status) { break; } } @@ -508,7 +508,7 @@ int AR3KConfigure(AR3K_CONFIG_INFO *pConfig) /* re-enable asynchronous recv */ status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,TRUE); - if (A_FAILED(status)) { + if (status) { break; } @@ -537,21 +537,21 @@ int AR3KConfigureExit(void *config) /* disable asynchronous recv while we issue commands and receive events synchronously */ status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,FALSE); - if (A_FAILED(status)) { + if (status) { break; } if (pConfig->Flags & (AR3K_CONFIG_FLAG_SET_AR3K_BAUD | AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP)) { status = AR3KConfigureHCIBaud(pConfig); - if (A_FAILED(status)) { + if (status) { break; } } /* re-enable asynchronous recv */ status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,TRUE); - if (A_FAILED(status)) { + if (status) { break; } diff --git a/drivers/staging/ath6kl/miscdrv/common_drv.c b/drivers/staging/ath6kl/miscdrv/common_drv.c index 2b5fe5bed855..926f88fba9db 100644 --- a/drivers/staging/ath6kl/miscdrv/common_drv.c +++ b/drivers/staging/ath6kl/miscdrv/common_drv.c @@ -428,7 +428,7 @@ int ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_BOOL waitF status = ar6000_WriteRegDiag(hifDevice, &address, &data); - if (A_FAILED(status)) { + if (status) { break; } @@ -458,7 +458,7 @@ int ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_BOOL waitF data = 0; status = ar6000_ReadRegDiag(hifDevice, &address, &data); - if (A_FAILED(status)) { + if (status) { break; } @@ -472,7 +472,7 @@ int ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_BOOL waitF } while (FALSE); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Failed to reset target \n")); } @@ -579,7 +579,7 @@ void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType) /* read RAM location through diagnostic window */ status = ar6000_ReadRegDiag(hifDevice, &address, ®DumpArea); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get ptr to register dump area \n")); break; } @@ -599,7 +599,7 @@ void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType) (A_UCHAR *)®DumpValues[0], regDumpCount * (sizeof(A_UINT32))); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get register dump \n")); break; } @@ -638,7 +638,7 @@ int ar6000_set_htc_params(HIF_DEVICE *hifDevice, status = HIFConfigureDevice(hifDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE, blocksizes, sizeof(blocksizes)); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_LOG_ERR,("Failed to get block size info from HIF layer...\n")); break; } @@ -658,7 +658,7 @@ int ar6000_set_htc_params(HIF_DEVICE *hifDevice, (A_UCHAR *)&blocksizes[1], 4); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_LOG_ERR,("BMIWriteMemory for IO block size failed \n")); break; } @@ -673,7 +673,7 @@ int ar6000_set_htc_params(HIF_DEVICE *hifDevice, (A_UCHAR *)&MboxIsrYieldValue, 4); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_LOG_ERR,("BMIWriteMemory for yield limit failed \n")); break; } @@ -771,7 +771,7 @@ ar6002_REV1_reset_force_host (HIF_DEVICE *hifDevice) address = 0x004ed4b0; /* REV1 target software ID is stored here */ status = ar6000_ReadRegDiag(hifDevice, &address, &data); - if (A_FAILED(status) || (data != AR6002_VERSION_REV1)) { + if (status || (data != AR6002_VERSION_REV1)) { return A_ERROR; /* Not AR6002 REV1 */ } diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 4ad78f25f182..9ed95e323a12 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -866,7 +866,7 @@ ar6000_sysfs_bmi_init(AR_SOFTC_T *ar) &ar->osDevInfo, sizeof(HIF_DEVICE_OS_DEVICE_INFO)); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failed to get OS device info from HIF\n")); return A_ERROR; } @@ -1536,18 +1536,16 @@ ar6000_configure_target(AR_SOFTC_T *ar) /* since BMIInit is called in the driver layer, we have to set the block * size here for the target */ - if (A_FAILED(ar6000_set_htc_params(ar->arHifDevice, - ar->arTargetType, - mbox_yield_limit, - 0 /* use default number of control buffers */ - ))) { + if (ar6000_set_htc_params(ar->arHifDevice, ar->arTargetType, + mbox_yield_limit, 0)) { + /* use default number of control buffers */ return A_ERROR; } if (setupbtdev != 0) { - if (A_FAILED(ar6000_set_hci_bridge_flags(ar->arHifDevice, - ar->arTargetType, - setupbtdev))) { + if (ar6000_set_hci_bridge_flags(ar->arHifDevice, + ar->arTargetType, + setupbtdev)) { return A_ERROR; } } @@ -1841,7 +1839,7 @@ ar6000_avail_ev(void *context, void *hif_handle) (unsigned long)ar)); avail_ev_failed : - if (A_FAILED(init_status)) { + if (init_status) { if (bmienable) { ar6000_sysfs_bmi_deinit(ar); } @@ -2359,7 +2357,7 @@ static int ar6000_connectservice(AR_SOFTC_T *ar, pConnect, &response); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Failed to connect to %s service status:%d \n", pDesc, status)); break; @@ -2502,7 +2500,7 @@ int ar6000_init(struct net_device *dev) */ status = HTCWaitTarget(ar->arHtcTarget); - if (A_FAILED(status)) { + if (status) { break; } @@ -2533,7 +2531,7 @@ int ar6000_init(struct net_device *dev) status = ar6000_connectservice(ar, &connect, "WMI CONTROL"); - if (A_FAILED(status)) { + if (status) { break; } @@ -2563,7 +2561,7 @@ int ar6000_init(struct net_device *dev) status = ar6000_connectservice(ar, &connect, "WMI DATA BE"); - if (A_FAILED(status)) { + if (status) { break; } @@ -2573,7 +2571,7 @@ int ar6000_init(struct net_device *dev) status = ar6000_connectservice(ar, &connect, "WMI DATA BK"); - if (A_FAILED(status)) { + if (status) { break; } @@ -2583,7 +2581,7 @@ int ar6000_init(struct net_device *dev) status = ar6000_connectservice(ar, &connect, "WMI DATA VI"); - if (A_FAILED(status)) { + if (status) { break; } @@ -2596,7 +2594,7 @@ int ar6000_init(struct net_device *dev) status = ar6000_connectservice(ar, &connect, "WMI DATA VO"); - if (A_FAILED(status)) { + if (status) { break; } @@ -2636,7 +2634,7 @@ int ar6000_init(struct net_device *dev) } while (FALSE); - if (A_FAILED(status)) { + if (status) { ret = -EIO; goto ar6000_init_done; } @@ -3455,7 +3453,7 @@ ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPacketQueue) } } - if (A_FAILED(status)) { + if (status) { if (status == A_ECANCELED) { /* a packet was flushed */ flushing = TRUE; diff --git a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c index 10f48851dc58..59e2af4f641e 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c @@ -147,7 +147,7 @@ static int ar6000_connect_raw_service(AR_SOFTC_T *ar, &connect, &response); - if (A_FAILED(status)) { + if (status) { if (response.ConnectRespCode == HTC_SERVICE_NO_MORE_EP) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC RAW , No more streams allowed \n")); status = A_OK; @@ -187,7 +187,7 @@ int ar6000_htc_raw_open(AR_SOFTC_T *ar) /* wait for target */ status = HTCWaitTarget(ar->arHtcTarget); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTCWaitTarget failed (%d)\n", status)); return -ENODEV; } @@ -206,7 +206,7 @@ int ar6000_htc_raw_open(AR_SOFTC_T *ar) /* try to connect to the raw service */ status = ar6000_connect_raw_service(ar,streamID); - if (A_FAILED(status)) { + if (status) { break; } @@ -245,7 +245,7 @@ int ar6000_htc_raw_open(AR_SOFTC_T *ar) arRaw->write_buffer_available[streamID] = TRUE; } - if (A_FAILED(status)) { + if (status) { return -EIO; } diff --git a/drivers/staging/ath6kl/os/linux/ar6k_pal.c b/drivers/staging/ath6kl/os/linux/ar6k_pal.c index 10ee89ef782b..5a0b373cd3e1 100644 --- a/drivers/staging/ath6kl/os/linux/ar6k_pal.c +++ b/drivers/staging/ath6kl/os/linux/ar6k_pal.c @@ -304,7 +304,7 @@ static int bt_setup_hci_pal(ar6k_hci_pal_info_t *pHciPalInfo) } while (FALSE); - if (A_FAILED(status)) { + if (status) { bt_cleanup_hci_pal(pHciPalInfo); } return status; @@ -423,7 +423,7 @@ int ar6k_setup_hci_pal(void *ar_p) pHciPalInfo->ar = ar; status = bt_setup_hci_pal(pHciPalInfo); - if (A_FAILED(status)) { + if (status) { break; } @@ -437,7 +437,7 @@ int ar6k_setup_hci_pal(void *ar_p) ar6k_pal_transport_ready(ar->hcipal_info); } while (FALSE); - if (A_FAILED(status)) { + if (status) { ar6k_cleanup_hci_pal(ar); } return status; diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index c7e0b4e87317..857ef8bc4fc6 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -248,7 +248,7 @@ static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle, /* start transport */ status = HCI_TransportStart(pHcidevInfo->pHCIDev); - if (A_FAILED(status)) { + if (status) { break; } @@ -304,14 +304,14 @@ static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle, /* configure the AR3K device */ memcpy(ar3kconfig.bdaddr,pHcidevInfo->ar->bdaddr,6); status = AR3KConfigure(&ar3kconfig); - if (A_FAILED(status)) { + if (status) { break; } /* Make sure both AR6K and AR3K have power management enabled */ if (ar3kconfig.PwrMgmtEnabled) { status = HCI_TransportEnablePowerMgmt(pHcidevInfo->pHCIDev, TRUE); - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to enable TLPM for AR6K! \n")); } } @@ -354,7 +354,7 @@ static void ar6000_hci_send_complete(void *pContext, HTC_PACKET *pPacket) A_ASSERT(osbuf != NULL); A_ASSERT(pHcidevInfo != NULL); - if (A_FAILED(pPacket->Status)) { + if (pPacket->Status) { if ((pPacket->Status != A_ECANCELED) && (pPacket->Status != A_NO_RESOURCE)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: Send Packet Failed: %d \n",pPacket->Status)); } @@ -376,7 +376,7 @@ static void ar6000_hci_pkt_recv(void *pContext, HTC_PACKET *pPacket) do { - if (A_FAILED(pPacket->Status)) { + if (pPacket->Status) { break; } @@ -499,7 +499,7 @@ int ar6000_setup_hci(AR_SOFTC_T *ar) ar->exitCallback = AR3KConfigureExit; status = bt_setup_hci(pHcidevInfo); - if (A_FAILED(status)) { + if (status) { break; } @@ -546,7 +546,7 @@ int ar6000_setup_hci(AR_SOFTC_T *ar) } while (FALSE); - if (A_FAILED(status)) { + if (status) { if (pHcidevInfo != NULL) { if (NULL == pHcidevInfo->pHCIDev) { /* GMBOX may not be present in older chips */ @@ -877,7 +877,7 @@ static int bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) sizeof(osDevInfo)); #endif - if (A_FAILED(status)) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to OS device info from HIF\n")); break; } @@ -906,7 +906,7 @@ static int bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) } while (FALSE); - if (A_FAILED(status)) { + if (status) { bt_cleanup_hci(pHcidevInfo); } diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index a159ae59add1..ea1f202445be 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -2203,7 +2203,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 0, /* use default yield */ 0 /* use default number of HTC ctrl buffers */ ); - if (A_FAILED(ret)) { + if (ret) { break; } /* Terminate the BMI phase */ @@ -4276,7 +4276,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) break; } - if (A_FAILED(a_set_module_mask(moduleinfo.modulename, moduleinfo.mask))) { + if (a_set_module_mask(moduleinfo.modulename, moduleinfo.mask)) { ret = -EFAULT; } @@ -4291,7 +4291,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) break; } - if (A_FAILED(a_get_module_mask(moduleinfo.modulename, &moduleinfo.mask))) { + if (a_get_module_mask(moduleinfo.modulename, &moduleinfo.mask)) { ret = -EFAULT; break; } diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index 1cf9e961b654..73cf866d007a 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -3144,7 +3144,7 @@ wmi_sync_point(struct wmi_t *wmip) /* if Buffer allocation for any of the dataSync fails, then do not * send the Synchronize cmd on the control ep */ - if (A_FAILED(status)) { + if (status) { break; } @@ -3155,7 +3155,7 @@ wmi_sync_point(struct wmi_t *wmip) status = wmi_cmd_send(wmip, cmd_osbuf, WMI_SYNCHRONIZE_CMDID, NO_SYNC_WMIFLAG); - if (A_FAILED(status)) { + if (status) { break; } /* cmd buffer sent, we no longer own it */ @@ -3170,7 +3170,7 @@ wmi_sync_point(struct wmi_t *wmip) trafficClass) ); - if (A_FAILED(status)) { + if (status) { break; } /* we don't own this buffer anymore, NULL it out of the array so it -- cgit v1.2.3 From ae8e1e7ad2ecdf4ecd68cf02d54a5ed6054b01c3 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 27 Jan 2011 20:04:22 -0800 Subject: staging: ath6kl: wmi.h: Convert packed structures with A_BOOL to u32 These structures are device native and need to be 4 bytes long. Signed-off-by: Joe Perches Acked-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/include/common/wmi.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/include/common/wmi.h b/drivers/staging/ath6kl/include/common/wmi.h index c75d310c37a7..eb8f7ba0df2b 100644 --- a/drivers/staging/ath6kl/include/common/wmi.h +++ b/drivers/staging/ath6kl/include/common/wmi.h @@ -635,8 +635,8 @@ typedef enum { } WMI_SCAN_TYPE; typedef PREPACK struct { - A_BOOL forceFgScan; - A_BOOL isLegacy; /* For Legacy Cisco AP compatibility */ + u32 forceFgScan; + u32 isLegacy; /* For Legacy Cisco AP compatibility */ A_UINT32 homeDwellTime; /* Maximum duration in the home channel(milliseconds) */ A_UINT32 forceScanInterval; /* Time interval between scans (milliseconds)*/ A_UINT8 scanType; /* WMI_SCAN_TYPE */ @@ -1241,7 +1241,7 @@ typedef PREPACK struct { * WMI_ENABLE_RM_CMDID */ typedef PREPACK struct { - A_BOOL enable_radio_measurements; + u32 enable_radio_measurements; } POSTPACK WMI_ENABLE_RM_CMD; /* @@ -2638,7 +2638,7 @@ typedef PREPACK struct { } POSTPACK WMI_SET_KEEPALIVE_CMD; typedef PREPACK struct { - A_BOOL configured; + u32 configured; A_UINT8 keepaliveInterval; } POSTPACK WMI_GET_KEEPALIVE_CMD; @@ -2717,8 +2717,8 @@ typedef PREPACK struct { } POSTPACK WMI_SET_IP_CMD; typedef PREPACK struct { - A_BOOL awake; - A_BOOL asleep; + u32 awake; + u32 asleep; } POSTPACK WMI_SET_HOST_SLEEP_MODE_CMD; typedef enum { @@ -2726,7 +2726,7 @@ typedef enum { } WMI_WOW_FILTER; typedef PREPACK struct { - A_BOOL enable_wow; + u32 enable_wow; WMI_WOW_FILTER filter; A_UINT16 hostReqDelay; } POSTPACK WMI_SET_WOW_MODE_CMD; @@ -3010,7 +3010,7 @@ typedef PREPACK struct { } POSTPACK WMI_AP_PROT_SCAN_TIME_CMD; typedef PREPACK struct { - A_BOOL flag; + u32 flag; A_UINT16 aid; } POSTPACK WMI_AP_SET_PVB_CMD; -- cgit v1.2.3 From f192c2bdede465481cad49095ec71d4dfad904b1 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 27 Jan 2011 20:04:23 -0800 Subject: staging: ath6kl: Convert bypasswmi to bool Types should match logical uses. Remove unused extern, make static. Signed-off-by: Joe Perches Acked-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 8 ++++---- drivers/staging/ath6kl/os/linux/ioctl.c | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 9ed95e323a12..3ad3d57f9b92 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -123,7 +123,7 @@ int bmienable = BMIENABLE_DEFAULT; char ifname[IFNAMSIZ] = {0,}; int wlaninitmode = WLAN_INIT_MODE_DEFAULT; -unsigned int bypasswmi = 0; +static bool bypasswmi; unsigned int debuglevel = 0; int tspecCompliance = ATHEROS_COMPLIANCE; unsigned int busspeedlow = 0; @@ -165,7 +165,7 @@ unsigned int eppingtest=0; module_param_string(ifname, ifname, sizeof(ifname), 0644); module_param(wlaninitmode, int, 0644); module_param(bmienable, int, 0644); -module_param(bypasswmi, uint, 0644); +module_param(bypasswmi, bool, 0644); module_param(debuglevel, uint, 0644); module_param(tspecCompliance, int, 0644); module_param(onebitmode, uint, 0644); @@ -1024,7 +1024,7 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, A } if (eppingtest) { - bypasswmi = TRUE; + bypasswmi = true; if (ar->arVersion.target_ver == AR6003_REV1_VERSION) { filename = AR6003_REV1_EPPING_FIRMWARE_FILE; } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { @@ -3512,7 +3512,7 @@ ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPacketQueue) A_NETBUF_FREE(pktSkb); } - if ((ar->arConnected == TRUE) || (bypasswmi)) { + if ((ar->arConnected == TRUE) || bypasswmi) { if (!flushing) { /* don't wake the queue if we are flushing, other wise it will just * keep queueing packets, which will keep failing */ diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index ea1f202445be..9a508c48fc53 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -34,7 +34,6 @@ extern unsigned int wmitimeout; extern A_WAITQUEUE_HEAD arEvent; extern int tspecCompliance; extern int bmienable; -extern int bypasswmi; extern int loghci; static int -- cgit v1.2.3 From 879cf160ed0494ea1ffa8959c388d3aa391f3be2 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 27 Jan 2011 20:04:24 -0800 Subject: staging: ath6kl: Convert type of streamExists to A_UINT8 Make the declaration type match the assigned from type. It's not a bool, it's a u8. Signed-off-by: Joe Perches Acked-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/wmi/wmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index 73cf866d007a..b6c9905ed515 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -537,7 +537,7 @@ A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 la A_UINT8 trafficClass = WMM_AC_BE; A_UINT16 ipType = IP_ETHERTYPE; WMI_DATA_HDR *dtHdr; - A_BOOL streamExists = FALSE; + A_UINT8 streamExists = 0; A_UINT8 userPriority; A_UINT32 hdrsize, metasize; ATH_LLC_SNAP_HDR *llcHdr; -- cgit v1.2.3 From 807208fe775e3c41776007544bc7d4f7e5d2ef25 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 27 Jan 2011 20:04:25 -0800 Subject: staging: ath6kl: Convert BDADDR_Present uses to TRUE/FALSE bugfix The previous uses of BDADDR_Present set the initial value to A_ERROR (-1) when not present and A_OK (0) when present. A later test for (!BDADDR_Present) was therefore logically inverted. Convert the values to TRUE/FALSE and the test is now logically correct. Signed-off-by: Joe Perches Acked-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c index 3b2c0ccdf1d5..5df17661c4a1 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c @@ -663,7 +663,7 @@ int AthDoParsePS(A_UCHAR *srcbuffer, A_UINT32 srclen) { int status; int i; - A_BOOL BDADDR_Present = A_ERROR; + A_BOOL BDADDR_Present = FALSE; Tag_Count = 0; @@ -689,7 +689,7 @@ int AthDoParsePS(A_UCHAR *srcbuffer, A_UINT32 srclen) else{ for(i=0; i Date: Thu, 27 Jan 2011 20:04:26 -0800 Subject: staging: ath6kl: Convert A_BOOL compressed sets from 0 to FALSE Use the appropriate define. Signed-off-by: Joe Perches Acked-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 3ad3d57f9b92..01ebdf160220 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -1034,7 +1034,7 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, A ar->arVersion.target_ver)); return A_ERROR; } - compressed = 0; + compressed = FALSE; } #ifdef CONFIG_HOST_TCMD_SUPPORT @@ -1047,7 +1047,7 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, A AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver)); return A_ERROR; } - compressed = 0; + compressed = FALSE; } #endif #ifdef HTC_RAW_INTERFACE @@ -1060,7 +1060,7 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, A AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver)); return A_ERROR; } - compressed = 0; + compressed = FALSE; } #endif break; -- cgit v1.2.3 From 6be02be5f95269978e033345d9938066f157c6bf Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 27 Jan 2011 20:04:27 -0800 Subject: staging: ath6kl: Convert 0 to FALSE Convert a set of an A_BOOL from 0 to FALSE. Signed-off-by: Joe Perches Acked-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_android.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/ar6000_android.c b/drivers/staging/ath6kl/os/linux/ar6000_android.c index 88487ccb08ee..ce1a94c38ff7 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_android.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_android.c @@ -29,7 +29,7 @@ #include #endif -A_BOOL enable_mmc_host_detect_change = 0; +A_BOOL enable_mmc_host_detect_change = FALSE; static void ar6000_enable_mmchost_detect_change(int enable); -- cgit v1.2.3 From e2ad9082eb8c88793a9aa1475b28932d48ce7a7e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 27 Jan 2011 20:04:28 -0800 Subject: staging: ath6kl: cfg80211: Convert forceFgScan to A_UINT32 It's declared that way in the prototype, use it that way too. Signed-off-by: Joe Perches Acked-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/cfg80211.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index e3dc99ae07f2..936879e06c23 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -726,7 +726,7 @@ ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); int ret = 0; - A_BOOL forceFgScan = FALSE; + A_UINT32 forceFgScan = 0; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); @@ -765,7 +765,7 @@ ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, } if(ar->arConnected) { - forceFgScan = TRUE; + forceFgScan = 1; } if(wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, forceFgScan, FALSE, \ -- cgit v1.2.3 From ebb8e4909860474060ff7fcdcfd05f183f0f3568 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 27 Jan 2011 20:04:29 -0800 Subject: staging: ath6kl: Convert A_UINT8 is_amsdu and is_acl_data_frame to A_BOOL Use A_BOOL as appropriate for actual variable uses. Signed-off-by: Joe Perches Acked-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 01ebdf160220..5a5e0852b9e7 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -3630,7 +3630,9 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) wmi_control_rx(ar->arWmi, skb); } else { WMI_DATA_HDR *dhdr = (WMI_DATA_HDR *)A_NETBUF_DATA(skb); - A_UINT8 is_amsdu, tid, is_acl_data_frame; + A_BOOL is_amsdu; + A_UINT8 tid; + A_BOOL is_acl_data_frame; is_acl_data_frame = WMI_DATA_HDR_GET_DATA_TYPE(dhdr) == WMI_DATA_HDR_DATA_TYPE_ACL; #ifdef CONFIG_PM ar6000_check_wow_status(ar, NULL, FALSE); @@ -3751,7 +3753,7 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) } } - is_amsdu = WMI_DATA_HDR_IS_AMSDU(dhdr); + is_amsdu = WMI_DATA_HDR_IS_AMSDU(dhdr) ? TRUE : FALSE; tid = WMI_DATA_HDR_GET_UP(dhdr); seq_no = WMI_DATA_HDR_GET_SEQNO(dhdr); meta_type = WMI_DATA_HDR_GET_META(dhdr); -- cgit v1.2.3 From 5bb5572ab6cee2887d87ce1de433a44bba15a998 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 27 Jan 2011 20:04:30 -0800 Subject: staging: ath6kl: Convert A_NETBUF_QUEUE_EMPTY to return TRUE or FALSE Make the return an A_BOOL not int. Signed-off-by: Joe Perches Acked-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/include/osapi_linux.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h index a1dd02404003..cdbda890939b 100644 --- a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h @@ -247,7 +247,7 @@ typedef struct sk_buff_head A_NETBUF_QUEUE_T; #define A_NETBUF_QUEUE_SIZE(q) \ a_netbuf_queue_size(q) #define A_NETBUF_QUEUE_EMPTY(q) \ - a_netbuf_queue_empty(q) + (a_netbuf_queue_empty(q) ? TRUE : FALSE) /* * Network buffer support -- cgit v1.2.3 From 34603829c46d3c23fac99b0d5528878602a81862 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 27 Jan 2011 20:04:31 -0800 Subject: staging: ath6kl: Convert sets of scanSpecificSsid to TRUE/FALSE. Don't use 0/1 for an A_BOOL. Signed-off-by: Joe Perches Acked-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/wireless_ext.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/wireless_ext.c b/drivers/staging/ath6kl/os/linux/wireless_ext.c index dc32e2d4bb02..ea933d0d9392 100644 --- a/drivers/staging/ath6kl/os/linux/wireless_ext.c +++ b/drivers/staging/ath6kl/os/linux/wireless_ext.c @@ -2510,14 +2510,14 @@ ar6000_ioctl_siwscan(struct net_device *dev, return -EIO; if (wmi_probedSsid_cmd(ar->arWmi, 1, SPECIFIC_SSID_FLAG, req.essid_len, req.essid) != A_OK) return -EIO; - ar->scanSpecificSsid = 1; + ar->scanSpecificSsid = TRUE; } else { if (ar->scanSpecificSsid) { if (wmi_probedSsid_cmd(ar->arWmi, 1, DISABLE_SSID_FLAG, 0, NULL) != A_OK) return -EIO; - ar->scanSpecificSsid = 0; + ar->scanSpecificSsid = FALSE; } } } @@ -2526,7 +2526,7 @@ ar6000_ioctl_siwscan(struct net_device *dev, if (ar->scanSpecificSsid) { if (wmi_probedSsid_cmd(ar->arWmi, 1, DISABLE_SSID_FLAG, 0, NULL) != A_OK) return -EIO; - ar->scanSpecificSsid = 0; + ar->scanSpecificSsid = FALSE; } } #endif -- cgit v1.2.3 From 8205669a4026d593a6b87c8cc983563e51997021 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 27 Jan 2011 20:04:32 -0800 Subject: staging: ath6kl: Convert tspecCompliance from A_BOOL to int Make the use in wmi_verify_tspec_params match the declaration of the variable. Signed-off-by: Joe Perches Acked-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/include/wmi_api.h | 2 +- drivers/staging/ath6kl/wmi/wmi.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/include/wmi_api.h b/drivers/staging/ath6kl/include/wmi_api.h index 5207a198ed1e..0d7d0cca7726 100644 --- a/drivers/staging/ath6kl/include/wmi_api.h +++ b/drivers/staging/ath6kl/include/wmi_api.h @@ -234,7 +234,7 @@ int wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize); int wmi_set_max_sp_len_cmd(struct wmi_t *wmip, A_UINT8 maxSpLen); A_UINT8 convert_userPriority_to_trafficClass(A_UINT8 userPriority); A_UINT8 wmi_get_power_mode_cmd(struct wmi_t *wmip); -int wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, A_BOOL tspecCompliance); +int wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance); #ifdef CONFIG_HOST_TCMD_SUPPORT int wmi_test_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT32 len); diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index b6c9905ed515..c384bb2e956e 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -4650,7 +4650,7 @@ wmi_get_power_mode_cmd(struct wmi_t *wmip) } int -wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, A_BOOL tspecCompliance) +wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance) { int ret = A_OK; -- cgit v1.2.3 From c282f2e3458a4ee51e2d97328633ee4679f5dc55 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 31 Jan 2011 22:07:54 +0900 Subject: Staging: rtl8192e: Remove variable that is never written Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 1 - drivers/staging/rtl8192e/r8192E_core.c | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 5f85872e39a2..19fd188163f0 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -479,7 +479,6 @@ typedef struct Stats unsigned long rxrdu; unsigned long rxok; unsigned long rxcmdpkt[4]; //08/05/08 amy rx cmd element txfeedback/bcn report/cfg set/query - unsigned long rxurberr; /* remove */ unsigned long received_rate_histogram[4][32]; //0: Total, 1:OK, 2:CRC, 3:ICV, 2007 07 03 cosa unsigned long rxoverflow; unsigned long rxint; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index a465f3770baa..2a7f19b880e0 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -589,12 +589,10 @@ static int proc_get_stats_rx(char *page, char **start, len += snprintf(page + len, count - len, "RX packets: %lu\n" "RX desc err: %lu\n" - "RX rx overflow error: %lu\n" - "RX invalid urb error: %lu\n", + "RX rx overflow error: %lu\n", priv->stats.rxint, priv->stats.rxrdu, - priv->stats.rxoverflow, - priv->stats.rxurberr); + priv->stats.rxoverflow); *eof = 1; return len; -- cgit v1.2.3 From 356955aefd93ba5b36960701c21b5f14dca64c99 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 31 Jan 2011 22:08:08 +0900 Subject: Staging: rtl8192e: Remove unused statistics Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 1 - drivers/staging/rtl8192e/r819xE_cmdpkt.c | 9 --------- 2 files changed, 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 19fd188163f0..35842f8df4d6 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -478,7 +478,6 @@ typedef struct Stats { unsigned long rxrdu; unsigned long rxok; - unsigned long rxcmdpkt[4]; //08/05/08 amy rx cmd element txfeedback/bcn report/cfg set/query unsigned long received_rate_histogram[4][32]; //0: Total, 1:OK, 2:CRC, 3:ICV, 2007 07 03 cosa unsigned long rxoverflow; unsigned long rxint; diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.c b/drivers/staging/rtl8192e/r819xE_cmdpkt.c index e841e1665fe8..b69d4dbbd87f 100644 --- a/drivers/staging/rtl8192e/r819xE_cmdpkt.c +++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.c @@ -440,7 +440,6 @@ cmpk_handle_tx_rate_history( u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats *pstats) { // u32 debug_level = DBG_LOUD; - struct r8192_priv *priv = ieee80211_priv(dev); int total_length; u8 cmd_length, exe_cnt = 0; u8 element_id; @@ -529,14 +528,6 @@ u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats *ps RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():unknown CMD Element\n"); return 1; /* This is a command packet. */ } - // 2007/01/22 MH Display received rx command packet info. - //cmpk_Display_Message(cmd_length, pcmd_buff); - - // 2007/01/22 MH Add to display tx statistic. - //cmpk_DisplayTxStatistic(pAdapter); - - /* 2007/03/09 MH Collect sidderent cmd element pkt num. */ - priv->stats.rxcmdpkt[element_id]++; total_length -= cmd_length; pcmd_buff += cmd_length; -- cgit v1.2.3 From 8875899c05ebf596934fcb9dde2f7601930f28f9 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 31 Jan 2011 22:08:18 +0900 Subject: Staging: rtl8192e: Delete dead code Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8190_rtl8256.c | 9 ----- drivers/staging/rtl8192e/r8192E_core.c | 23 ------------ drivers/staging/rtl8192e/r8192E_dm.c | 62 +++----------------------------- 3 files changed, 5 insertions(+), 89 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index 642f3bfe2755..4ad4b062c5c4 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -432,7 +432,6 @@ SetRFPowerState8190( if(priv->SetRFPowerStateInProgress == true) return false; - //RT_TRACE(COMP_PS, "===========> SetRFPowerState8190()!\n"); priv->SetRFPowerStateInProgress = true; switch(priv->rf_chip) @@ -441,7 +440,6 @@ SetRFPowerState8190( switch( eRFPowerState ) { case eRfOn: - //RT_TRACE(COMP_PS, "SetRFPowerState8190() eRfOn !\n"); //RXTX enable control: On //for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) // PHY_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x2); @@ -620,7 +618,6 @@ SetRFPowerState8190( break; case eRfOff: - //RT_TRACE(COMP_PS, "SetRFPowerState8190() eRfOff/Sleep !\n"); // Update current RF state variable. //priv->ieee80211->eRFPowerState = eRFPowerState; @@ -718,9 +715,7 @@ SetRFPowerState8190( priv->ieee80211->eRFPowerState = eRFPowerState; } - //printk("%s()priv->ieee80211->eRFPowerState:%s\n" ,__func__,priv->ieee80211->eRFPowerState == eRfOn ? "On" : "Off"); priv->SetRFPowerStateInProgress = false; - //RT_TRACE(COMP_PS, "<=========== SetRFPowerState8190() bResult = %d!\n", bResult); return bResult; } @@ -774,8 +769,6 @@ MgntDisconnectIBSS( u8 i; bool bFilterOutNonAssociatedBSSID = false; - //IEEE80211_DEBUG(IEEE80211_DL_TRACE, "XXXXXXXXXX MgntDisconnect IBSS\n"); - priv->ieee80211->state = IEEE80211_NOLINK; // PlatformZeroMemory( pMgntInfo->Bssid, 6 ); @@ -1003,7 +996,6 @@ MgntDisconnect( { if( priv->ieee80211->iw_mode == IW_MODE_ADHOC ) { - //RT_TRACE(COMP_MLME, "MgntDisconnect() ===> MgntDisconnectIBSS\n"); MgntDisconnectIBSS(dev); } if( priv->ieee80211->iw_mode == IW_MODE_INFRA ) @@ -1013,7 +1005,6 @@ MgntDisconnect( // e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is // used to handle disassociation related things to AP, e.g. send Disassoc // frame to AP. 2005.01.27, by rcnjko. - //IEEE80211_DEBUG(IEEE80211_DL_TRACE,"MgntDisconnect() ===> MgntDisconnectAP\n"); MgntDisconnectAP(dev, asRsn); } diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 2a7f19b880e0..342ccb65b863 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1685,7 +1685,6 @@ static void rtl8192_qos_activate(struct work_struct * work) (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)| (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)| ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET)); - //printk("===>u4bAcParam:%x, ", u4bAcParam); write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam); //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332); } @@ -3529,26 +3528,22 @@ static bool HalRxCheckStuck8190Pci(struct net_device *dev) { if(rx_chk_cnt < 4) { - //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI); return bStuck; } else { rx_chk_cnt = 0; - //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI); } } else { if(rx_chk_cnt < 8) { - //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI); return bStuck; } else { rx_chk_cnt = 0; - //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI); } } if(priv->RxCounter==RegRxCounter) @@ -4033,7 +4028,6 @@ IPSEnter(struct net_device *dev) && (priv->ieee80211->state != IEEE80211_LINKED) ) { RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n"); - //printk("IPSEnter(): Turn off RF.\n"); pPSC->eInactivePowerState = eRfOff; // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem)); InactivePsWorkItemCallback(dev); @@ -4059,7 +4053,6 @@ IPSLeave(struct net_device *dev) if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS) { RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n"); - //printk("IPSLeave(): Turn on RF.\n"); pPSC->eInactivePowerState = eRfOn; // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem)); InactivePsWorkItemCallback(dev); @@ -4150,14 +4143,11 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) return; hal_dm_watchdog(dev); #ifdef ENABLE_IPS -// printk("watch_dog ENABLE_IPS\n"); if(ieee->actscanning == false){ - //printk("%d,%d,%d,%d\n", ieee->eRFPowerState, ieee->is_set_key, ieee->proto_stoppping, ieee->wx_set_enc); if((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == IEEE80211_NOLINK) && (ieee->eRFPowerState == eRfOn)&&!ieee->is_set_key && (!ieee->proto_stoppping) && !ieee->wx_set_enc){ if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){ - //printk("====================>haha:IPSEnter()\n"); IPSEnter(dev); //ieee80211_stop_scan(priv->ieee80211); } @@ -4177,8 +4167,6 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) if( ((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod + ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) || (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) ) { - //printk("ieee->LinkDetectInfo.NumRxUnicastOkInPeriod is %d,ieee->LinkDetectInfo.NumTxOkInPeriod is %d\n", - // ieee->LinkDetectInfo.NumRxUnicastOkInPeriod,ieee->LinkDetectInfo.NumTxOkInPeriod); bEnterPS= false; } else @@ -4186,7 +4174,6 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) bEnterPS= true; } - //printk("***bEnterPS = %d\n", bEnterPS); // LeisurePS only work in infra mode. if(bEnterPS) { @@ -4248,7 +4235,6 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) { ResetType = rtl819x_ifcheck_resetornot(dev); check_reset_cnt = 3; - //DbgPrint("Start to check silent reset\n"); } spin_unlock_irqrestore(&priv->tx_lock,flags); if(!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL) @@ -4784,7 +4770,6 @@ static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct if(priv->stats.rx_rssi_percentage[rfpath] == 0) { priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath]; - //DbgPrint("MIMO RSSI initialize \n"); } if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath]) { @@ -4816,12 +4801,10 @@ static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX; last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index]; priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb; - //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n", // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total); } priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll; priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll; - //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll); slide_beacon_adc_pwdb_index++; if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX) slide_beacon_adc_pwdb_index = 0; @@ -4839,7 +4822,6 @@ static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct if(priv->undecorated_smoothed_pwdb < 0) // initialize { priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll; - //DbgPrint("First pwdb initialize \n"); } #if 1 if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb) @@ -5094,7 +5076,6 @@ static void rtl8192_query_rxphystatus( cck_adc_pwdb[i] = (char)tmp_pwdb; cck_adc_pwdb[i] /= 2; pstats->cck_adc_pwdb[i] = precord_stats->cck_adc_pwdb[i] = cck_adc_pwdb[i]; - //DbgPrint("RF-%d tmp_pwdb = 0x%x, cck_adc_pwdb = %d", i, tmp_pwdb, cck_adc_pwdb[i]); } } #endif @@ -5323,13 +5304,11 @@ static void TranslateRxSignalStuff819xpci(struct net_device *dev, if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON) { bPacketBeacon = true; - //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf); } if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK) { if((!compare_ether_addr(praddr,dev->dev_addr))) bToSelfBA = true; - //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf); } #endif @@ -6103,7 +6082,6 @@ void setKey( struct net_device *dev, write_nic_dword(dev, WCAMI, TargetContent); write_nic_dword(dev, RWCAM, TargetCommand); - // printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo)); } else if(i==1){//MAC TargetContent = (u32)(*(MacAddr+2)) | @@ -6147,7 +6125,6 @@ bool NicIFEnableNIC(struct net_device* dev) priv->bdisable_nic = false; //YJ,add,091111 return -1; } - //printk("start adapter finished\n"); RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); //priv->bfirst_init = false; diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index 08275b3cde39..55bdaebe8035 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -406,20 +406,16 @@ static void dm_check_rate_adaptive(struct net_device * dev) (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M); } - //DbgPrint("[DM] Thresh H/L=%d/%d\n\r", RATR.HighRSSIThreshForRA, RATR.LowRSSIThreshForRA); if(priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA) { - //DbgPrint("[DM] RSSI=%d STA=HIGH\n\r", pHalData->UndecoratedSmoothedPWDB); pra->ratr_state = DM_RATR_STA_HIGH; targetRATR = pra->upper_rssi_threshold_ratr; }else if(priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA) { - //DbgPrint("[DM] RSSI=%d STA=Middle\n\r", pHalData->UndecoratedSmoothedPWDB); pra->ratr_state = DM_RATR_STA_MIDDLE; targetRATR = pra->middle_rssi_threshold_ratr; }else { - //DbgPrint("[DM] RSSI=%d STA=LOW\n\r", pHalData->UndecoratedSmoothedPWDB); pra->ratr_state = DM_RATR_STA_LOW; targetRATR = pra->low_rssi_threshold_ratr; } @@ -433,17 +429,13 @@ static void dm_check_rate_adaptive(struct net_device * dev) if( (priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) || ping_rssi_state ) { - //DbgPrint("TestRSSI = %d, set RATR to 0x%x \n", pHalData->UndecoratedSmoothedPWDB, pRA->TestRSSIRATR); pra->ratr_state = DM_RATR_STA_LOW; targetRATR = pra->ping_rssi_ratr; ping_rssi_state = 1; } - //else - // DbgPrint("TestRSSI is between the range. \n"); } else { - //DbgPrint("TestRSSI Recover to 0x%x \n", targetRATR); ping_rssi_state = 0; } } @@ -616,7 +608,7 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) cmpk_message_handle_tx(dev, (u8*)&tx_cmd, DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T)); #endif mdelay(1); - //DbgPrint("hi, vivi, strange\n"); + for(i = 0;i <= 30; i++) { Pwr_Flag = read_nic_byte(dev, Pw_Track_Flag); @@ -910,9 +902,7 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev) tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval; tmpCCK40Mindex = 0; } - //DbgPrint("%ddb, tmpOFDMindex = %d, tmpCCK20Mindex = %d, tmpCCK40Mindex = %d", - //((u1Byte)tmpRegA - pHalData->ThermalMeter[0]), - //tmpOFDMindex, tmpCCK20Mindex, tmpCCK40Mindex); + if(priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) //40M tmpCCKindex = tmpCCK40Mindex; else @@ -943,7 +933,6 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev) if(CCKSwingNeedUpdate) { - //DbgPrint("Update CCK Swing, CCK_index = %d\n", pHalData->CCK_index); dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); } if(priv->OFDM_index != tmpOFDMindex) @@ -1143,7 +1132,6 @@ static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev) struct r8192_priv *priv = ieee80211_priv(dev); static u8 TM_Trigger=0; - //DbgPrint("dm_CheckTXPowerTracking() \n"); if(!priv->btxpower_tracking) return; else @@ -1159,7 +1147,6 @@ static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev) { //Attention!! You have to wirte all 12bits data to RF, or it may cause RF to crash //actually write reg0x02 bit1=0, then bit1=1. - //DbgPrint("Trigger ThermalMeter, write RF reg0x2 = 0x4d to 0x4f\n"); rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); @@ -1168,8 +1155,7 @@ static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev) return; } else { - //DbgPrint("Schedule TxPowerTrackingWorkItem\n"); - queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0); + queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0); TM_Trigger = 0; } } @@ -1373,10 +1359,7 @@ void dm_restore_dynamic_mechanism_state(struct net_device *dev) if(priv->rf_type == RF_1T2R) // 1T2R, Spatial Stream 2 should be disabled { ratr_value &=~ (RATE_ALL_OFDM_2SS); - //DbgPrint("HW_VAR_TATR_0 from 0x%x ==> 0x%x\n", ((pu4Byte)(val))[0], ratr_value); } - //DbgPrint("set HW_VAR_TATR_0 = 0x%x\n", ratr_value); - //cosa PlatformEFIOWrite4Byte(Adapter, RATR0, ((pu4Byte)(val))[0]); write_nic_dword(dev, RATR0, ratr_value); write_nic_byte(dev, UFWP, 1); } @@ -1591,7 +1574,6 @@ static void dm_ctrl_initgain_byrssi_by_driverrssi( if (dm_digtable.dig_enable_flag == false) return; - //DbgPrint("Dig by Sw Rssi \n"); if(dm_digtable.dig_algorithm_switch) // if swithed algorithm, we have to disable FW Dig. fw_dig = 0; if(fw_dig <= 3) // execute several times to make sure the FW Dig is disabled @@ -1607,12 +1589,9 @@ static void dm_ctrl_initgain_byrssi_by_driverrssi( else dm_digtable.cur_connect_state = DIG_DISCONNECT; - //DbgPrint("DM_DigTable.PreConnectState = %d, DM_DigTable.CurConnectState = %d \n", - //DM_DigTable.PreConnectState, DM_DigTable.CurConnectState); - if(dm_digtable.dbg_mode == DM_DBG_OFF) dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb; - //DbgPrint("DM_DigTable.Rssi_val = %d \n", DM_DigTable.Rssi_val); + dm_initial_gain(dev); dm_pd_th(dev); dm_cs_ratio(dev); @@ -1650,11 +1629,7 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( { return; } - //DbgPrint("Dig by Fw False Alarm\n"); - //if (DM_DigTable.Dig_State == DM_STA_DIG_OFF) - /*DbgPrint("DIG Check\n\r RSSI=%d LOW=%d HIGH=%d STATE=%d", - pHalData->UndecoratedSmoothedPWDB, DM_DigTable.RssiLowThresh, - DM_DigTable.RssiHighThresh, DM_DigTable.Dig_State);*/ + /* 1. When RSSI decrease, We have to judge if it is smaller than a threshold and then execute below step. */ if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh)) @@ -1736,7 +1711,6 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( } dm_digtable.dig_state = DM_STA_DIG_ON; - //DbgPrint("DIG ON\n\r"); // 2.1 Set initial gain. // 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment. @@ -1906,7 +1880,6 @@ static void dm_initial_gain( dm_digtable.cur_ig_value = priv->DefaultInitialGain[0]; dm_digtable.pre_ig_value = 0; } - //DbgPrint("DM_DigTable.CurIGValue = 0x%x, DM_DigTable.PreIGValue = 0x%x\n", DM_DigTable.CurIGValue, DM_DigTable.PreIGValue); // if silent reset happened, we should rewrite the values back if(priv->reset_count != reset_cnt) @@ -1923,7 +1896,6 @@ static void dm_initial_gain( || !initialized || force_write) { initial_gain = (u8)dm_digtable.cur_ig_value; - //DbgPrint("Write initial gain = 0x%x\n", initial_gain); // Set initial gain. write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain); write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain); @@ -1984,7 +1956,6 @@ static void dm_pd_th( if((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) || (initialized<=3) || force_write) { - //DbgPrint("Write PD_TH state = %d\n", DM_DigTable.CurPD_THState); if(dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) { // Lower PD_TH for OFDM. @@ -2093,7 +2064,6 @@ static void dm_cs_ratio( if((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) || !initialized || force_write) { - //DbgPrint("Write CS_ratio state = %d\n", DM_DigTable.CurCS_ratioState); if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER) { // Lower CS ratio for CCK. @@ -2145,7 +2115,6 @@ static void dm_check_edca_turbo( if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO) goto dm_CheckEdcaTurbo_EXIT; -// printk("========>%s():bis_any_nonbepkts is %d\n",__FUNCTION__,priv->bis_any_nonbepkts); // Check the status for current condition. if(!priv->ieee80211->bis_any_nonbepkts) { @@ -2154,7 +2123,6 @@ static void dm_check_edca_turbo( // For RT-AP, we needs to turn it on when Rx>Tx if(curRxOkCnt > 4*curTxOkCnt) { - //printk("%s():curRxOkCnt > 4*curTxOkCnt\n"); if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) { write_nic_dword(dev, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]); @@ -2163,8 +2131,6 @@ static void dm_check_edca_turbo( } else { - - //printk("%s():curRxOkCnt < 4*curTxOkCnt\n"); if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) { write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]); @@ -2269,7 +2235,6 @@ static void dm_ctstoself(struct net_device *dev) if(curRxOkCnt > 4*curTxOkCnt) //downlink, disable CTS to self { pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF; - //DbgPrint("dm_CTSToSelf() ==> CTS to self disabled -- downlink\n"); } else //uplink { @@ -2279,12 +2244,10 @@ static void dm_ctstoself(struct net_device *dev) if(priv->undecorated_smoothed_pwdb < priv->ieee80211->CTSToSelfTH) // disable CTS to self { pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF; - //DbgPrint("dm_CTSToSelf() ==> CTS to self disabled\n"); } else if(priv->undecorated_smoothed_pwdb >= (priv->ieee80211->CTSToSelfTH+5)) // enable CTS to self { pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF; - //DbgPrint("dm_CTSToSelf() ==> CTS to self enabled\n"); } #endif } @@ -2467,7 +2430,6 @@ static void dm_rxpath_sel_byrssi(struct net_device * dev) if(priv->ieee80211->mode == WIRELESS_MODE_B) { DM_RxPathSelTable.cck_method = CCK_Rx_Version_2; //pure B mode, fixed cck version2 - //DbgPrint("Pure B mode, use cck rx version2 \n"); } //decide max/sec/min rssi index @@ -2689,7 +2651,6 @@ static void dm_rxpath_sel_byrssi(struct net_device * dev) if(tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i]) { //enable the BB Rx path - //DbgPrint("RF-%d is enabled. \n", 0x1<HardwareType == HARDWARE_TYPE_RTL8190P) - DbgPrint("Fsync is idle, rssi<=35, write 0xc38 = 0x%x \n", 0x10); - else - DbgPrint("Fsync is idle, rssi<=35, write 0xc38 = 0x%x \n", 0x90); - #endif } } else if(priv->undecorated_smoothed_pwdb >= (RegC38_TH+5)) @@ -3067,7 +3022,6 @@ void dm_check_fsync(struct net_device *dev) { write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); reg_c38_State = RegC38_Default; - //DbgPrint("Fsync is idle, rssi>=40, write 0xc38 = 0x%x \n", pHalData->framesync); } } } @@ -3077,7 +3031,6 @@ void dm_check_fsync(struct net_device *dev) { write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); reg_c38_State = RegC38_Default; - //DbgPrint("Fsync is idle, not connected, write 0xc38 = 0x%x \n", pHalData->framesync); } } } @@ -3089,7 +3042,6 @@ void dm_check_fsync(struct net_device *dev) write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); reg_c38_State = RegC38_Default; reset_cnt = priv->reset_count; - //DbgPrint("reg_c38_State = 0 for silent reset. \n"); } } else @@ -3098,7 +3050,6 @@ void dm_check_fsync(struct net_device *dev) { write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); reg_c38_State = RegC38_Default; - //DbgPrint("framesync no monitor, write 0xc38 = 0x%x \n", pHalData->framesync); } } } @@ -3130,7 +3081,6 @@ static void dm_dynamic_txpower(struct net_device *dev) priv->bDynamicTxLowPower = false; return; } - //printk("priv->ieee80211->current_network.unknown_cap_exist is %d ,priv->ieee80211->current_network.broadcom_cap_exist is %d\n",priv->ieee80211->current_network.unknown_cap_exist,priv->ieee80211->current_network.broadcom_cap_exist); if((priv->ieee80211->current_network.atheros_cap_exist ) && (priv->ieee80211->mode == IEEE_G)){ txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH; txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW; @@ -3141,8 +3091,6 @@ static void dm_dynamic_txpower(struct net_device *dev) txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW; } -// printk("=======>%s(): txhipower_threshhold is %d,txlowpower_threshold is %d\n",__FUNCTION__,txhipower_threshhold,txlowpower_threshold); - RT_TRACE(COMP_TXAGC,"priv->undecorated_smoothed_pwdb = %ld \n" , priv->undecorated_smoothed_pwdb); if(priv->ieee80211->state == IEEE80211_LINKED) -- cgit v1.2.3 From d128eaccbedc8f3799492b5a590a72674c580308 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 31 Jan 2011 22:08:36 +0900 Subject: Staging: rtl8192e: Remove unused struct members Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 28 +++------------------------- drivers/staging/rtl8192e/r8192E_core.c | 11 ----------- drivers/staging/rtl8192e/r8192E_dm.c | 2 -- drivers/staging/rtl8192e/r819xE_cmdpkt.c | 3 --- 4 files changed, 3 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 35842f8df4d6..0ec2c062db26 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -478,7 +478,7 @@ typedef struct Stats { unsigned long rxrdu; unsigned long rxok; - unsigned long received_rate_histogram[4][32]; //0: Total, 1:OK, 2:CRC, 3:ICV, 2007 07 03 cosa + unsigned long received_rate_histogram[4][32]; //0: Total, 1:OK, 2:CRC, 3:ICV unsigned long rxoverflow; unsigned long rxint; unsigned long txoverflow; @@ -493,10 +493,8 @@ typedef struct Stats unsigned long txfeedback; unsigned long txfeedbackok; unsigned long txoktotal; - unsigned long txunicast; unsigned long txbytesunicast; unsigned long rxbytesunicast; - unsigned long txerrbytestotal; unsigned long slide_signal_strength[100]; unsigned long slide_evm[100]; @@ -505,8 +503,8 @@ typedef struct Stats long signal_strength; // Transformed, in dbm. Beautified signal strength for UI, not correct. u8 rx_rssi_percentage[4]; u8 rx_evm_percentage[2]; - u32 Slide_Beacon_pwdb[100]; //cosa add for beacon rssi - u32 Slide_Beacon_Total; //cosa add for beacon rssi + u32 Slide_Beacon_pwdb[100]; + u32 Slide_Beacon_Total; RT_SMOOTH_DATA_4RF cck_adc_pwdb; } Stats; @@ -974,8 +972,6 @@ typedef struct r8192_priv bool bLastDTPFlag_High; bool bLastDTPFlag_Low; - bool bstore_last_dtpflag; - bool bstart_txctrl_bydtp; //Define to discriminate on High power State or on sitesuvey to change Tx gain index //Add by amy for Rate Adaptive rate_adaptive rate_adaptive; //Add by amy for TX power tracking @@ -1008,7 +1004,6 @@ typedef struct r8192_priv bool bis_cur_rdlstate; struct timer_list fsync_timer; - bool bfsync_processing; // 500ms Fsync timer is active or not u32 rate_record; u32 rateCountDiffRecord; u32 ContiuneDiffCount; @@ -1017,13 +1012,6 @@ typedef struct r8192_priv u8 framesync; u32 framesyncC34; u8 framesyncMonitor; - //Added by amy 080516 for RX related - u16 nrxAMPDU_size; - u8 nrxAMPDU_aggr_num; - - /*Last RxDesc TSF value*/ - u32 last_rxdesc_tsf_high; - u32 last_rxdesc_tsf_low; //by amy for gpio bool bHwRadioOff; @@ -1033,16 +1021,6 @@ typedef struct r8192_priv RT_OP_MODE OpMode; //by amy for reset_count u32 reset_count; - bool bpbc_pressed; - //by amy for debug - u32 txpower_checkcnt; - u32 txpower_tracking_callback_cnt; - u8 thermal_read_val[40]; - u8 thermal_readback_index; - u32 ccktxpower_adjustcnt_not_ch14; - u32 ccktxpower_adjustcnt_ch14; - u8 tx_fwinfo_force_subcarriermode; - u8 tx_fwinfo_force_subcarrierval; //by amy for silent reset RESET_TYPE ResetProgress; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 342ccb65b863..f36dba375e71 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -2092,10 +2092,6 @@ static void rtl8192_init_priv_variable(struct net_device* dev) priv->chan = 1; //set to channel 1 priv->RegWirelessMode = WIRELESS_MODE_AUTO; priv->RegChannelPlan = 0xf; - priv->nrxAMPDU_size = 0; - priv->nrxAMPDU_aggr_num = 0; - priv->last_rxdesc_tsf_high = 0; - priv->last_rxdesc_tsf_low = 0; priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO priv->ieee80211->iw_mode = IW_MODE_INFRA; priv->ieee80211->ieee_up=0; @@ -2106,7 +2102,6 @@ static void rtl8192_init_priv_variable(struct net_device* dev) priv->ieee80211->short_slot = 1; priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0; priv->bcck_in_ch14 = false; - priv->bfsync_processing = false; priv->CCKPresentAttentuation = 0; priv->rfa_txpowertrackingindex = 0; priv->rfc_txpowertrackingindex = 0; @@ -2123,12 +2118,6 @@ static void rtl8192_init_priv_variable(struct net_device* dev) priv->SetRFPowerStateInProgress = false; priv->ieee80211->PowerSaveControl.bInactivePs = true; priv->ieee80211->PowerSaveControl.bIPSModeBackup = false; - //just for debug - priv->txpower_checkcnt = 0; - priv->thermal_readback_index =0; - priv->txpower_tracking_callback_cnt = 0; - priv->ccktxpower_adjustcnt_ch14 = 0; - priv->ccktxpower_adjustcnt_not_ch14 = 0; priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL; priv->ieee80211->iw_mode = IW_MODE_INFRA; diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index 55bdaebe8035..01a7ba613408 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -1411,7 +1411,6 @@ void dm_backup_dynamic_mechanism_state(struct net_device *dev) // Fsync to avoid reset priv->bswitch_fsync = false; - priv->bfsync_processing = false; //Backup BB InitialGain dm_bb_initialgain_backup(dev); @@ -2302,7 +2301,6 @@ static void dm_check_pbc_gpio(struct net_device *dev) // Here we only set bPbcPressed to TRUE // After trigger PBC, the variable will be set to FALSE RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n"); - priv->bpbc_pressed = true; } #endif diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.c b/drivers/staging/rtl8192e/r819xE_cmdpkt.c index b69d4dbbd87f..76beaa3beb7f 100644 --- a/drivers/staging/rtl8192e/r819xE_cmdpkt.c +++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.c @@ -165,7 +165,6 @@ cmpk_count_txstatistic( /* We can not make sure broadcast/multicast or unicast mode. */ if (pstx_fb->pkt_type != PACKET_MULTICAST && pstx_fb->pkt_type != PACKET_BROADCAST) { - priv->stats.txunicast++; priv->stats.txbytesunicast += pstx_fb->pkt_length; } } @@ -366,8 +365,6 @@ static void cmpk_count_tx_status( struct net_device *dev, priv->stats.txfeedbackok += pstx_status->txok; priv->stats.txoktotal += pstx_status->txok; - priv->stats.txunicast += pstx_status->txucok; - priv->stats.txbytesunicast += pstx_status->txuclength; } -- cgit v1.2.3 From 890a6850b34d81e0052d5953a14f97fe6511b83b Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 31 Jan 2011 22:09:02 +0900 Subject: Staging: rtl8192e: Remove support for legacy wireless extentions Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 12 ++---------- drivers/staging/rtl8192e/r8192E_wx.c | 23 ++++------------------- 2 files changed, 6 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index f36dba375e71..92c191082bde 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -5661,17 +5661,10 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, dev->netdev_ops = &rtl8192_netdev_ops; - //DMESG("Oops: i'm coming\n"); -#if WIRELESS_EXT >= 12 -#if WIRELESS_EXT < 17 - dev->get_wireless_stats = r8192_get_wireless_stats; -#endif - dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def; -#endif - //dev->get_wireless_stats = r8192_get_wireless_stats; + dev->wireless_handlers = &r8192_wx_handlers_def; dev->type=ARPHRD_ETHER; - dev->watchdog_timeo = HZ*3; //modified by john, 0805 + dev->watchdog_timeo = HZ*3; if (dev_alloc_name(dev, ifname) < 0){ RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n"); @@ -5835,7 +5828,6 @@ static int __init rtl8192_pci_module_init(void) printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n"); printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n"); RT_TRACE(COMP_INIT, "Initializing module"); - RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT); rtl8192_proc_module_init(); if(0!=pci_register_driver(&rtl8192_pci_driver)) { diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c index 15b08013aae0..7b5ac0d26812 100644 --- a/drivers/staging/rtl8192e/r8192E_wx.c +++ b/drivers/staging/rtl8192e/r8192E_wx.c @@ -364,10 +364,10 @@ static int rtl8180_wx_get_range(struct net_device *dev, } range->num_frequency = val; range->num_channels = val; -#if WIRELESS_EXT > 17 + range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2| IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP; -#endif + tmp->scan_capa = 0x01; return 0; } @@ -900,7 +900,6 @@ exit: return err; } -#if (WIRELESS_EXT >= 18) static int r8192_wx_set_enc_ext(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -1040,7 +1039,7 @@ static int r8192_wx_set_mlme(struct net_device *dev, up(&priv->wx_sem); return ret; } -#endif + static int r8192_wx_set_gen_ie(struct net_device *dev, struct iw_request_info *info, union iwreq_data *data, char *extra) @@ -1126,11 +1125,7 @@ static iw_handler r8192_wx_handlers[] = NULL, /* SIOCWIWTHRSPY */ r8192_wx_set_wap, /* SIOCSIWAP */ r8192_wx_get_wap, /* SIOCGIWAP */ -#if (WIRELESS_EXT >= 18) - r8192_wx_set_mlme, /* MLME-- */ -#else - NULL, -#endif + r8192_wx_set_mlme, /* MLME-- */ dummy, /* SIOCGIWAPLIST -- depricated */ r8192_wx_set_scan, /* SIOCSIWSCAN */ r8192_wx_get_scan, /* SIOCGIWSCAN */ @@ -1158,15 +1153,9 @@ static iw_handler r8192_wx_handlers[] = NULL, /*---hole---*/ r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */ NULL, /* SIOCSIWGENIE */ -#if (WIRELESS_EXT >= 18) r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */ NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */ r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */ -#else - NULL, - NULL, - NULL, -#endif NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */ NULL, /* SIOCSIWPMKSA */ NULL, /*---hole---*/ @@ -1214,7 +1203,6 @@ static iw_handler r8192_private_handler[] = { r8192_wx_adapter_power_status, }; -//#if WIRELESS_EXT >= 17 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); @@ -1243,7 +1231,6 @@ struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev) wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; return wstats; } -//#endif struct iw_handler_def r8192_wx_handlers_def={ @@ -1252,8 +1239,6 @@ struct iw_handler_def r8192_wx_handlers_def={ .private = r8192_private_handler, .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler), .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args), -#if WIRELESS_EXT >= 17 .get_wireless_stats = r8192_get_wireless_stats, -#endif .private_args = (struct iw_priv_args *)r8192_private_args, }; -- cgit v1.2.3 From 6376f210aeca59c89c67efe8ccf28c36bb98b832 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 31 Jan 2011 22:09:15 +0900 Subject: Staging: rtl8192e: Don't mess with carrier before registering device Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 92c191082bde..5685d33d25b9 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -5678,9 +5678,6 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, goto fail; } - netif_carrier_off(dev); - netif_stop_queue(dev); - register_netdev(dev); RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name); rtl8192_proc_init_one(dev); -- cgit v1.2.3 From b3bb17e6dada06a4b68a7b1414dbfc6c46f6d9ff Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 31 Jan 2011 22:09:27 +0900 Subject: Staging: rtl8192e: Remove PF_SYNCTHREADifdefs Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c | 4 ---- drivers/staging/rtl8192e/r8192E_core.c | 4 ---- 2 files changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index c92e8f6c6c3c..a684743da213 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -2803,11 +2803,7 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee) ieee->beacon_timer.data = (unsigned long) ieee; ieee->beacon_timer.function = ieee80211_send_beacon_cb; -#ifdef PF_SYNCTHREAD - ieee->wq = create_workqueue(DRV_NAME,0); -#else ieee->wq = create_workqueue(DRV_NAME); -#endif INIT_DELAYED_WORK(&ieee->start_ibss_wq,ieee80211_start_ibss_wq); INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq); diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 5685d33d25b9..2fdc1cd75ed9 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -2222,11 +2222,7 @@ static void rtl8192_init_priv_task(struct net_device* dev) { struct r8192_priv *priv = ieee80211_priv(dev); -#ifdef PF_SYNCTHREAD - priv->priv_wq = create_workqueue(DRV_NAME,0); -#else priv->priv_wq = create_workqueue(DRV_NAME); -#endif #ifdef ENABLE_IPS INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq); -- cgit v1.2.3 From 935ce8991a9760d101311a34a53503b291faaa11 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 31 Jan 2011 22:09:44 +0900 Subject: Staging: rtl8192e: Move static variable to device struct Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 1 + drivers/staging/rtl8192e/r8192E_core.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 0ec2c062db26..0de74da1a48f 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -884,6 +884,7 @@ typedef struct r8192_priv u8 retry_rts; struct work_struct reset_wq; + u8 rx_chk_cnt; //for rtl819xPci // Data Rate Config. Added by Annie, 2006-04-13. diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 2fdc1cd75ed9..f6313766a91a 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -3484,51 +3484,51 @@ static bool HalRxCheckStuck8190Pci(struct net_device *dev) struct r8192_priv *priv = ieee80211_priv(dev); u16 RegRxCounter = read_nic_word(dev, 0x130); bool bStuck = FALSE; - static u8 rx_chk_cnt = 0; + RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter); // If rssi is small, we should check rx for long time because of bad rx. // or maybe it will continuous silent reset every 2 seconds. - rx_chk_cnt++; + priv->rx_chk_cnt++; if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5)) { - rx_chk_cnt = 0; //high rssi, check rx stuck right now. + priv->rx_chk_cnt = 0; /* high rssi, check rx stuck right now. */ } else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) && ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) || (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) ) { - if(rx_chk_cnt < 2) + if(priv->rx_chk_cnt < 2) { return bStuck; } else { - rx_chk_cnt = 0; + priv->rx_chk_cnt = 0; } } else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdbCurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdbundecorated_smoothed_pwdb >= VeryLowRSSI) { - if(rx_chk_cnt < 4) + if(priv->rx_chk_cnt < 4) { return bStuck; } else { - rx_chk_cnt = 0; + priv->rx_chk_cnt = 0; } } else { - if(rx_chk_cnt < 8) + if(priv->rx_chk_cnt < 8) { return bStuck; } else { - rx_chk_cnt = 0; + priv->rx_chk_cnt = 0; } } if(priv->RxCounter==RegRxCounter) -- cgit v1.2.3 From d5fdaa3ae73ef61de5a82b63a601afa9c4dc1d3b Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 31 Jan 2011 22:09:58 +0900 Subject: Staging: rtl8192e: Move static variable to device struct Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 2 ++ drivers/staging/rtl8192e/r8192E_core.c | 11 +++++------ 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 0de74da1a48f..0189a3d290e8 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -964,6 +964,8 @@ typedef struct r8192_priv bool brfpath_rxenable[4]; //+by amy 080507 struct timer_list watch_dog_timer; + u8 watchdog_last_time; + u8 watchdog_check_reset_cnt; //+by amy 080515 for dynamic mechenism //Add by amy Tx Power Control for Near/Far Range 2008/05/15 diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index f6313766a91a..c5be6bcbd49f 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -4115,10 +4115,8 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) struct net_device *dev = priv->ieee80211->dev; struct ieee80211_device* ieee = priv->ieee80211; RESET_TYPE ResetType = RESET_TYPE_NORESET; - static u8 check_reset_cnt=0; unsigned long flags; bool bBusyTraffic = false; - static u8 last_time = 0; bool bEnterPS = false; if ((!priv->up) || priv->bHwRadioOff) @@ -4216,10 +4214,11 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) } //check if reset the driver spin_lock_irqsave(&priv->tx_lock,flags); - if(check_reset_cnt++ >= 3 && !ieee->is_roaming && (last_time != 1)) + if (priv->watchdog_check_reset_cnt++ >= 3 && !ieee->is_roaming && + priv->watchdog_last_time != 1) { ResetType = rtl819x_ifcheck_resetornot(dev); - check_reset_cnt = 3; + priv->watchdog_check_reset_cnt = 3; } spin_unlock_irqrestore(&priv->tx_lock,flags); if(!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL) @@ -4232,11 +4231,11 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) #if 1 if( ((priv->force_reset) || (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT))) // This is control by OID set in Pomelo { - last_time = 1; + priv->watchdog_last_time = 1; rtl819x_ifsilentreset(dev); } else - last_time = 0; + priv->watchdog_last_time = 0; #endif priv->force_reset = false; priv->bForcedSilentReset = false; -- cgit v1.2.3 From d163f324af5cd2c504796f471f29a8b62d71bf93 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 31 Jan 2011 22:10:12 +0900 Subject: Staging: rtl8192e: Move static variable to device struct Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 4 ++++ drivers/staging/rtl8192e/r8192E_core.c | 12 ++++-------- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 0189a3d290e8..a8b69d3960ae 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -975,6 +975,10 @@ typedef struct r8192_priv bool bLastDTPFlag_High; bool bLastDTPFlag_Low; + /* OFDM RSSI. For high power or not */ + u8 phy_check_reg824; + u32 phy_reg824_bit9; + //Add by amy for Rate Adaptive rate_adaptive rate_adaptive; //Add by amy for TX power tracking diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index c5be6bcbd49f..bb86f93c0086 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -5001,10 +5001,6 @@ static void rtl8192_query_rxphystatus( u8 is_cck_rate=0; u8 rf_rx_num = 0; - /* 2007/07/04 MH For OFDM RSSI. For high power or not. */ - static u8 check_reg824 = 0; - static u32 reg824_bit9 = 0; - is_cck_rate = rx_hal_is_cck_rate(pdrvinfo); // Record it for next packet processing @@ -5015,10 +5011,10 @@ static void rtl8192_query_rxphystatus( pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon; pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA; /*2007.08.30 requested by SD3 Jerry */ - if(check_reg824 == 0) + if (priv->phy_check_reg824 == 0) { - reg824_bit9 = rtl8192_QueryBBReg(priv->ieee80211->dev, rFPGA0_XA_HSSIParameter2, 0x200); - check_reg824 = 1; + priv->phy_reg824_bit9 = rtl8192_QueryBBReg(priv->ieee80211->dev, rFPGA0_XA_HSSIParameter2, 0x200); + priv->phy_check_reg824 = 1; } @@ -5064,7 +5060,7 @@ static void rtl8192_query_rxphystatus( } #endif - if(!reg824_bit9) + if (!priv->phy_reg824_bit9) { report = pcck_buf->cck_agc_rpt & 0xc0; report = report>>6; -- cgit v1.2.3 From 83184e692826975c296aa0f5ed18d3809b2d1630 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 31 Jan 2011 22:10:38 +0900 Subject: Staging: rtl8192e: Move static variable to device struct Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 1 + drivers/staging/rtl8192e/r8192E_core.c | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index a8b69d3960ae..a63a2a5633f9 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -864,6 +864,7 @@ typedef struct r8192_priv struct Stats stats; struct iw_statistics wstats; struct proc_dir_entry *dir_dev; + struct ieee80211_rx_stats previous_stats; /* RX stuff */ struct sk_buff_head skb_queue; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index bb86f93c0086..1958e73bf441 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -5258,7 +5258,6 @@ static void TranslateRxSignalStuff819xpci(struct net_device *dev, struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); bool bpacket_match_bssid, bpacket_toself; bool bPacketBeacon=false, bToSelfBA=false; - static struct ieee80211_rx_stats previous_stats; struct ieee80211_hdr_3addr *hdr; u16 fc,type; @@ -5298,10 +5297,10 @@ static void TranslateRxSignalStuff819xpci(struct net_device *dev, // // Because phy information is contained in the last packet of AMPDU only, so driver // should process phy information of previous packet - rtl8192_process_phyinfo(priv, tmp_buf,&previous_stats, pstats); - rtl8192_query_rxphystatus(priv, pstats, pdesc, pdrvinfo, &previous_stats, bpacket_match_bssid, + rtl8192_process_phyinfo(priv, tmp_buf, &priv->previous_stats, pstats); + rtl8192_query_rxphystatus(priv, pstats, pdesc, pdrvinfo, &priv->previous_stats, bpacket_match_bssid, bpacket_toself ,bPacketBeacon, bToSelfBA); - rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats); + rtl8192_record_rxdesc_forlateruse(pstats, &priv->previous_stats); } -- cgit v1.2.3 From 11aacc282d6755f452fb88f76a883ea77c3b982e Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 31 Jan 2011 22:10:48 +0900 Subject: Staging: rtl8192e: Remove #if 1 blocks Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 49 +++++++--------------------------- 1 file changed, 10 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 1958e73bf441..fb16bef4973f 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1606,11 +1606,10 @@ static void rtl8192_link_change(struct net_device *dev) { rtl8192_net_update(dev); rtl8192_update_ratr_table(dev); -#if 1 + //add this as in pure N mode, wep encryption will use software way, but there is no chance to set this as wep will not set group key in wext. WB.2008.07.08 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) EnableHWSecurityConfig8192(dev); -#endif } else { @@ -3157,7 +3156,6 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) RT_TRACE(COMP_INIT, "Before C-cut\n"); } -#if 1 //Firmware download RT_TRACE(COMP_INIT, "Load Firmware!\n"); bfirmwareok = init_firmware(dev); @@ -3166,7 +3164,7 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) return rtStatus; } RT_TRACE(COMP_INIT, "Load Firmware finished!\n"); -#endif + //RF config if(priv->ResetProgress == RESET_TYPE_NORESET) { @@ -3465,7 +3463,6 @@ TxCheckStuck(struct net_device *dev) break; } -#if 1 if(bCheckFwTxCnt) { if(HalTxCheckStuck8190Pci(dev)) @@ -3474,7 +3471,7 @@ TxCheckStuck(struct net_device *dev) return RESET_TYPE_SILENT; } } -#endif + return RESET_TYPE_NORESET; } @@ -3562,7 +3559,7 @@ rtl819x_ifcheck_resetornot(struct net_device *dev) rfState = priv->ieee80211->eRFPowerState; TxResetType = TxCheckStuck(dev); -#if 1 + if( rfState != eRfOff && /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/ (priv->ieee80211->iw_mode != IW_MODE_ADHOC)) @@ -3577,7 +3574,6 @@ rtl819x_ifcheck_resetornot(struct net_device *dev) // set, STA cannot hear any packet a all. Emily, 2008.04.12 RxResetType = RxCheckStuck(dev); } -#endif RT_TRACE(COMP_RESET,"%s(): TxResetType is %d, RxResetType is %d\n",__FUNCTION__,TxResetType,RxResetType); if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL) @@ -3757,7 +3753,7 @@ RESET_START: // Set the variable for reset. priv->ResetProgress = RESET_TYPE_SILENT; // rtl8192_close(dev); -#if 1 + down(&priv->wx_sem); if(priv->up == 0) { @@ -3810,18 +3806,13 @@ RESET_START: RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n",__FUNCTION__); } } -#endif ieee->is_silent_reset = 1; -#if 1 EnableHWSecurityConfig8192(dev); -#if 1 if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA) { ieee->set_chan(ieee->dev, ieee->current_network.channel); -#if 1 queue_work(ieee->wq, &ieee->associate_complete_wq); -#endif } else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC) @@ -3837,7 +3828,6 @@ RESET_START: ieee->data_hard_resume(ieee->dev); netif_carrier_on(ieee->dev); } -#endif CamRestoreAllEntry(dev); @@ -3853,7 +3843,6 @@ RESET_START: // For test --> force write UFWP. write_nic_byte(dev, UFWP, 1); RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count); -#endif } } @@ -4228,7 +4217,7 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) return; } /* disable silent reset temply 2008.9.11*/ -#if 1 + if( ((priv->force_reset) || (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT))) // This is control by OID set in Pomelo { priv->watchdog_last_time = 1; @@ -4236,7 +4225,7 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) } else priv->watchdog_last_time = 0; -#endif + priv->force_reset = false; priv->bForcedSilentReset = false; priv->bResetInProgress = false; @@ -4807,7 +4796,7 @@ static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct { priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll; } -#if 1 + if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb) { priv->undecorated_smoothed_pwdb = @@ -4821,20 +4810,6 @@ static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) + (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor); } -#else - //Fixed by Jacken 2008-03-20 - if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB) - { - pHalData->UndecoratedSmoothedPWDB = - ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6; - pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1; - } - else - { - pHalData->UndecoratedSmoothedPWDB = - ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6; - } -#endif } // @@ -5279,7 +5254,7 @@ static void TranslateRxSignalStuff819xpci(struct net_device *dev, (!compare_ether_addr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3)) && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV)); bpacket_toself = bpacket_match_bssid & (!compare_ether_addr(praddr, priv->ieee80211->dev->dev_addr)); -#if 1//cosa + if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON) { bPacketBeacon = true; @@ -5290,8 +5265,6 @@ static void TranslateRxSignalStuff819xpci(struct net_device *dev, bToSelfBA = true; } -#endif - // // Process PHY information for previous packet (RSSI/PWDB/EVM) // @@ -5961,7 +5934,7 @@ void EnableHWSecurityConfig8192(struct net_device *dev) struct ieee80211_device* ieee = priv->ieee80211; SECR_value = SCR_TxEncEnable | SCR_RxDecEnable; -#if 1 + if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2)) { SECR_value |= SCR_RxUseDK; @@ -5973,8 +5946,6 @@ void EnableHWSecurityConfig8192(struct net_device *dev) SECR_value |= SCR_TxUseDK; } -#endif - //add HWSec active enable here. //default using hwsec. when peer AP is in N mode only and pairwise_key_type is none_aes(which HT_IOT_ACT_PURE_N_MODE indicates it), use software security. when peer AP is in b,g,n mode mixed and pairwise_key_type is none_aes, use g mode hw security. WB on 2008.7.4 ieee->hwsec_active = 1; -- cgit v1.2.3 From 1694027394a625fc880d8a6d5357d17d48d64978 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 31 Jan 2011 22:11:02 +0900 Subject: Staging: rtl8192e: Remove unused endian_swap function Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index fb16bef4973f..13158fa33769 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -2263,17 +2263,6 @@ static void rtl8192_get_eeprom_size(struct net_device* dev) RT_TRACE(COMP_INIT, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype); } -/* - * used to swap endian. as ntohl & htonl are not - * neccessary to swap endian, so use this instead. - */ -static inline u16 endian_swap(u16* data) -{ - u16 tmp = *data; - *data = (tmp >> 8) | (tmp << 8); - return *data; -} - /* * Adapter->EEPROMAddressSize should be set before this function call. * EEPROM address size can be got through GetEEPROMSize8185() -- cgit v1.2.3 From 51da8e2b4e0e4b14e5ec0fd32473dcfc2562b822 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 31 Jan 2011 22:11:15 +0900 Subject: Staging: rtl8192e: Remove unused card type Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211.h | 1 - drivers/staging/rtl8192e/r8192E.h | 5 ----- drivers/staging/rtl8192e/r8192E_core.c | 3 --- 3 files changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211.h b/drivers/staging/rtl8192e/ieee80211.h index 16298e052667..ffa4d7bd1105 100644 --- a/drivers/staging/rtl8192e/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211.h @@ -868,7 +868,6 @@ struct ieee80211_rx_stats { u16 len; u64 tsf; u32 beacon_time; - u8 nic_type; u16 Length; // u8 DataRate; // In 0.5 Mbps u8 SignalQuality; // in 0-100 index. diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index a63a2a5633f9..515f492b214d 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -814,7 +814,6 @@ typedef struct r8192_priv #endif bool being_init_adapter; u8 Rf_Mode; - short card_8192; /* O: rtl8192, 1:rtl8185 V B/C, 2:rtl8185 V D */ u8 card_8192_version; /* if TCR reports card V B/C this discriminates */ spinlock_t irq_th_lock; spinlock_t tx_lock; @@ -1051,10 +1050,6 @@ typedef struct r8192_priv struct workqueue_struct *priv_wq; }r8192_priv; -typedef enum{ - NIC_8192E = 1, -} nic_t; - bool init_firmware(struct net_device *dev); short rtl8192_tx(struct net_device *dev, struct sk_buff* skb); u32 read_cam(struct net_device *dev, u8 addr); diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 13158fa33769..2c17b57aac8f 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -2086,7 +2086,6 @@ static void rtl8192_init_priv_variable(struct net_device* dev) priv->rxbuffersize = 9100;//2048;//1024; priv->rxringcount = MAX_RX_COUNT;//64; priv->irq_enabled=0; - priv->card_8192 = NIC_8192E; priv->rx_skb_complete = 1; priv->chan = 1; //set to channel 1 priv->RegWirelessMode = WIRELESS_MODE_AUTO; @@ -5369,8 +5368,6 @@ static void rtl8192_rx(struct net_device *dev) }; unsigned int count = priv->rxringcount; - stats.nic_type = NIC_8192E; - while (count--) { rx_desc_819x_pci *pdesc = &priv->rx_ring[priv->rx_idx];//rx descriptor struct sk_buff *skb = priv->rx_buf[priv->rx_idx];//rx pkt -- cgit v1.2.3 From 0ffbf8bf21db0186e9fbb024a1796c3148790578 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 31 Jan 2011 14:03:00 -0800 Subject: Revert "appletalk: move to staging" This reverts commit a6238f21736af3f47bdebf3895f477f5f23f1af9 Appletalk got some patches to fix up the BLK usage in it in the network tree, so this removal isn't needed. Cc: Arnd Bergmann Cc: Cc: netdev@vger.kernel.org, Cc: David Miller Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 3 +- drivers/net/Makefile | 1 + drivers/net/appletalk/Kconfig | 126 ++ drivers/net/appletalk/Makefile | 7 + drivers/net/appletalk/cops.c | 1013 +++++++++++++ drivers/net/appletalk/cops.h | 60 + drivers/net/appletalk/cops_ffdrv.h | 532 +++++++ drivers/net/appletalk/cops_ltdrv.h | 241 ++++ drivers/net/appletalk/ipddp.c | 335 +++++ drivers/net/appletalk/ipddp.h | 27 + drivers/net/appletalk/ltpc.c | 1288 +++++++++++++++++ drivers/net/appletalk/ltpc.h | 73 + drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/appletalk/Kconfig | 126 -- drivers/staging/appletalk/Makefile | 12 - drivers/staging/appletalk/aarp.c | 1063 -------------- drivers/staging/appletalk/atalk.h | 208 --- drivers/staging/appletalk/atalk_proc.c | 301 ---- drivers/staging/appletalk/cops.c | 1013 ------------- drivers/staging/appletalk/cops.h | 60 - drivers/staging/appletalk/cops_ffdrv.h | 532 ------- drivers/staging/appletalk/cops_ltdrv.h | 241 ---- drivers/staging/appletalk/ddp.c | 1981 -------------------------- drivers/staging/appletalk/dev.c | 44 - drivers/staging/appletalk/ipddp.c | 335 ----- drivers/staging/appletalk/ipddp.h | 27 - drivers/staging/appletalk/ltpc.c | 1288 ----------------- drivers/staging/appletalk/ltpc.h | 73 - drivers/staging/appletalk/sysctl_net_atalk.c | 61 - fs/compat_ioctl.c | 1 + include/linux/Kbuild | 1 + include/linux/atalk.h | 208 +++ net/Kconfig | 1 + net/Makefile | 1 + net/appletalk/Makefile | 9 + net/appletalk/aarp.c | 1063 ++++++++++++++ net/appletalk/atalk_proc.c | 301 ++++ net/appletalk/ddp.c | 1981 ++++++++++++++++++++++++++ net/appletalk/dev.c | 44 + net/appletalk/sysctl_net_atalk.c | 61 + net/socket.c | 1 + 42 files changed, 7377 insertions(+), 7369 deletions(-) create mode 100644 drivers/net/appletalk/Kconfig create mode 100644 drivers/net/appletalk/Makefile create mode 100644 drivers/net/appletalk/cops.c create mode 100644 drivers/net/appletalk/cops.h create mode 100644 drivers/net/appletalk/cops_ffdrv.h create mode 100644 drivers/net/appletalk/cops_ltdrv.h create mode 100644 drivers/net/appletalk/ipddp.c create mode 100644 drivers/net/appletalk/ipddp.h create mode 100644 drivers/net/appletalk/ltpc.c create mode 100644 drivers/net/appletalk/ltpc.h delete mode 100644 drivers/staging/appletalk/Kconfig delete mode 100644 drivers/staging/appletalk/Makefile delete mode 100644 drivers/staging/appletalk/aarp.c delete mode 100644 drivers/staging/appletalk/atalk.h delete mode 100644 drivers/staging/appletalk/atalk_proc.c delete mode 100644 drivers/staging/appletalk/cops.c delete mode 100644 drivers/staging/appletalk/cops.h delete mode 100644 drivers/staging/appletalk/cops_ffdrv.h delete mode 100644 drivers/staging/appletalk/cops_ltdrv.h delete mode 100644 drivers/staging/appletalk/ddp.c delete mode 100644 drivers/staging/appletalk/dev.c delete mode 100644 drivers/staging/appletalk/ipddp.c delete mode 100644 drivers/staging/appletalk/ipddp.h delete mode 100644 drivers/staging/appletalk/ltpc.c delete mode 100644 drivers/staging/appletalk/ltpc.h delete mode 100644 drivers/staging/appletalk/sysctl_net_atalk.c create mode 100644 include/linux/atalk.h create mode 100644 net/appletalk/Makefile create mode 100644 net/appletalk/aarp.c create mode 100644 net/appletalk/atalk_proc.c create mode 100644 net/appletalk/ddp.c create mode 100644 net/appletalk/dev.c create mode 100644 net/appletalk/sysctl_net_atalk.c (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index 3118d67d68fb..dd6ca456cde3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -554,7 +554,8 @@ F: drivers/hwmon/applesmc.c APPLETALK NETWORK LAYER M: Arnaldo Carvalho de Melo S: Maintained -F: drivers/staging/appletalk/ +F: drivers/net/appletalk/ +F: net/appletalk/ ARC FRAMEBUFFER DRIVER M: Jaya Kumar diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 11a9c053f0c8..b90738d13994 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -265,6 +265,7 @@ obj-$(CONFIG_MACB) += macb.o obj-$(CONFIG_S6GMAC) += s6gmac.o obj-$(CONFIG_ARM) += arm/ +obj-$(CONFIG_DEV_APPLETALK) += appletalk/ obj-$(CONFIG_TR) += tokenring/ obj-$(CONFIG_WAN) += wan/ obj-$(CONFIG_ARCNET) += arcnet/ diff --git a/drivers/net/appletalk/Kconfig b/drivers/net/appletalk/Kconfig new file mode 100644 index 000000000000..0b376a990972 --- /dev/null +++ b/drivers/net/appletalk/Kconfig @@ -0,0 +1,126 @@ +# +# Appletalk driver configuration +# +config ATALK + tristate "Appletalk protocol support" + depends on BKL # waiting to be removed from net/appletalk/ddp.c + select LLC + ---help--- + AppleTalk is the protocol that Apple computers can use to communicate + on a network. If your Linux box is connected to such a network and you + wish to connect to it, say Y. You will need to use the netatalk package + so that your Linux box can act as a print and file server for Macs as + well as access AppleTalk printers. Check out + on the WWW for details. + EtherTalk is the name used for AppleTalk over Ethernet and the + cheaper and slower LocalTalk is AppleTalk over a proprietary Apple + network using serial links. EtherTalk and LocalTalk are fully + supported by Linux. + + General information about how to connect Linux, Windows machines and + Macs is on the WWW at . The + NET3-4-HOWTO, available from + , contains valuable + information as well. + + To compile this driver as a module, choose M here: the module will be + called appletalk. You almost certainly want to compile it as a + module so you can restart your AppleTalk stack without rebooting + your machine. I hear that the GNU boycott of Apple is over, so + even politically correct people are allowed to say Y here. + +config DEV_APPLETALK + tristate "Appletalk interfaces support" + depends on ATALK + help + AppleTalk is the protocol that Apple computers can use to communicate + on a network. If your Linux box is connected to such a network, and wish + to do IP over it, or you have a LocalTalk card and wish to use it to + connect to the AppleTalk network, say Y. + + +config LTPC + tristate "Apple/Farallon LocalTalk PC support" + depends on DEV_APPLETALK && (ISA || EISA) && ISA_DMA_API + help + This allows you to use the AppleTalk PC card to connect to LocalTalk + networks. The card is also known as the Farallon PhoneNet PC card. + If you are in doubt, this card is the one with the 65C02 chip on it. + You also need version 1.3.3 or later of the netatalk package. + This driver is experimental, which means that it may not work. + See the file . + +config COPS + tristate "COPS LocalTalk PC support" + depends on DEV_APPLETALK && (ISA || EISA) + help + This allows you to use COPS AppleTalk cards to connect to LocalTalk + networks. You also need version 1.3.3 or later of the netatalk + package. This driver is experimental, which means that it may not + work. This driver will only work if you choose "AppleTalk DDP" + networking support, above. + Please read the file . + +config COPS_DAYNA + bool "Dayna firmware support" + depends on COPS + help + Support COPS compatible cards with Dayna style firmware (Dayna + DL2000/ Daynatalk/PC (half length), COPS LT-95, Farallon PhoneNET PC + III, Farallon PhoneNET PC II). + +config COPS_TANGENT + bool "Tangent firmware support" + depends on COPS + help + Support COPS compatible cards with Tangent style firmware (Tangent + ATB_II, Novell NL-1000, Daystar Digital LT-200. + +config IPDDP + tristate "Appletalk-IP driver support" + depends on DEV_APPLETALK && ATALK + ---help--- + This allows IP networking for users who only have AppleTalk + networking available. This feature is experimental. With this + driver, you can encapsulate IP inside AppleTalk (e.g. if your Linux + box is stuck on an AppleTalk only network) or decapsulate (e.g. if + you want your Linux box to act as an Internet gateway for a zoo of + AppleTalk connected Macs). Please see the file + for more information. + + If you say Y here, the AppleTalk-IP support will be compiled into + the kernel. In this case, you can either use encapsulation or + decapsulation, but not both. With the following two questions, you + decide which one you want. + + To compile the AppleTalk-IP support as a module, choose M here: the + module will be called ipddp. + In this case, you will be able to use both encapsulation and + decapsulation simultaneously, by loading two copies of the module + and specifying different values for the module option ipddp_mode. + +config IPDDP_ENCAP + bool "IP to Appletalk-IP Encapsulation support" + depends on IPDDP + help + If you say Y here, the AppleTalk-IP code will be able to encapsulate + IP packets inside AppleTalk frames; this is useful if your Linux box + is stuck on an AppleTalk network (which hopefully contains a + decapsulator somewhere). Please see + for more information. If + you said Y to "AppleTalk-IP driver support" above and you say Y + here, then you cannot say Y to "AppleTalk-IP to IP Decapsulation + support", below. + +config IPDDP_DECAP + bool "Appletalk-IP to IP Decapsulation support" + depends on IPDDP + help + If you say Y here, the AppleTalk-IP code will be able to decapsulate + AppleTalk-IP frames to IP packets; this is useful if you want your + Linux box to act as an Internet gateway for an AppleTalk network. + Please see for more + information. If you said Y to "AppleTalk-IP driver support" above + and you say Y here, then you cannot say Y to "IP to AppleTalk-IP + Encapsulation support", above. + diff --git a/drivers/net/appletalk/Makefile b/drivers/net/appletalk/Makefile new file mode 100644 index 000000000000..6cfc705f7c5c --- /dev/null +++ b/drivers/net/appletalk/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for drivers/net/appletalk +# + +obj-$(CONFIG_IPDDP) += ipddp.o +obj-$(CONFIG_COPS) += cops.o +obj-$(CONFIG_LTPC) += ltpc.o diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c new file mode 100644 index 000000000000..748c9f526e71 --- /dev/null +++ b/drivers/net/appletalk/cops.c @@ -0,0 +1,1013 @@ +/* cops.c: LocalTalk driver for Linux. + * + * Authors: + * - Jay Schulist + * + * With more than a little help from; + * - Alan Cox + * + * Derived from: + * - skeleton.c: A network driver outline for linux. + * Written 1993-94 by Donald Becker. + * - ltpc.c: A driver for the LocalTalk PC card. + * Written by Bradford W. Johnson. + * + * Copyright 1993 United States Government as represented by the + * Director, National Security Agency. + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * Changes: + * 19970608 Alan Cox Allowed dual card type support + * Can set board type in insmod + * Hooks for cops_setup routine + * (not yet implemented). + * 19971101 Jay Schulist Fixes for multiple lt* devices. + * 19980607 Steven Hirsch Fixed the badly broken support + * for Tangent type cards. Only + * tested on Daystar LT200. Some + * cleanup of formatting and program + * logic. Added emacs 'local-vars' + * setup for Jay's brace style. + * 20000211 Alan Cox Cleaned up for softnet + */ + +static const char *version = +"cops.c:v0.04 6/7/98 Jay Schulist \n"; +/* + * Sources: + * COPS Localtalk SDK. This provides almost all of the information + * needed. + */ + +/* + * insmod/modprobe configurable stuff. + * - IO Port, choose one your card supports or 0 if you dare. + * - IRQ, also choose one your card supports or nothing and let + * the driver figure it out. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* For udelay() */ +#include +#include +#include +#include + +#include +#include +#include + +#include "cops.h" /* Our Stuff */ +#include "cops_ltdrv.h" /* Firmware code for Tangent type cards. */ +#include "cops_ffdrv.h" /* Firmware code for Dayna type cards. */ + +/* + * The name of the card. Is used for messages and in the requests for + * io regions, irqs and dma channels + */ + +static const char *cardname = "cops"; + +#ifdef CONFIG_COPS_DAYNA +static int board_type = DAYNA; /* Module exported */ +#else +static int board_type = TANGENT; +#endif + +static int io = 0x240; /* Default IO for Dayna */ +static int irq = 5; /* Default IRQ */ + +/* + * COPS Autoprobe information. + * Right now if port address is right but IRQ is not 5 this will + * return a 5 no matter what since we will still get a status response. + * Need one more additional check to narrow down after we have gotten + * the ioaddr. But since only other possible IRQs is 3 and 4 so no real + * hurry on this. I *STRONGLY* recommend using IRQ 5 for your card with + * this driver. + * + * This driver has 2 modes and they are: Dayna mode and Tangent mode. + * Each mode corresponds with the type of card. It has been found + * that there are 2 main types of cards and all other cards are + * the same and just have different names or only have minor differences + * such as more IO ports. As this driver is tested it will + * become more clear on exactly what cards are supported. The driver + * defaults to using Dayna mode. To change the drivers mode, simply + * select Dayna or Tangent mode when configuring the kernel. + * + * This driver should support: + * TANGENT driver mode: + * Tangent ATB-II, Novell NL-1000, Daystar Digital LT-200, + * COPS LT-1 + * DAYNA driver mode: + * Dayna DL2000/DaynaTalk PC (Half Length), COPS LT-95, + * Farallon PhoneNET PC III, Farallon PhoneNET PC II + * Other cards possibly supported mode unknown though: + * Dayna DL2000 (Full length), COPS LT/M (Micro-Channel) + * + * Cards NOT supported by this driver but supported by the ltpc.c + * driver written by Bradford W. Johnson + * Farallon PhoneNET PC + * Original Apple LocalTalk PC card + * + * N.B. + * + * The Daystar Digital LT200 boards do not support interrupt-driven + * IO. You must specify 'irq=0xff' as a module parameter to invoke + * polled mode. I also believe that the port probing logic is quite + * dangerous at best and certainly hopeless for a polled card. Best to + * specify both. - Steve H. + * + */ + +/* + * Zero terminated list of IO ports to probe. + */ + +static unsigned int ports[] = { + 0x240, 0x340, 0x200, 0x210, 0x220, 0x230, 0x260, + 0x2A0, 0x300, 0x310, 0x320, 0x330, 0x350, 0x360, + 0 +}; + +/* + * Zero terminated list of IRQ ports to probe. + */ + +static int cops_irqlist[] = { + 5, 4, 3, 0 +}; + +static struct timer_list cops_timer; + +/* use 0 for production, 1 for verification, 2 for debug, 3 for verbose debug */ +#ifndef COPS_DEBUG +#define COPS_DEBUG 1 +#endif +static unsigned int cops_debug = COPS_DEBUG; + +/* The number of low I/O ports used by the card. */ +#define COPS_IO_EXTENT 8 + +/* Information that needs to be kept for each board. */ + +struct cops_local +{ + int board; /* Holds what board type is. */ + int nodeid; /* Set to 1 once have nodeid. */ + unsigned char node_acquire; /* Node ID when acquired. */ + struct atalk_addr node_addr; /* Full node address */ + spinlock_t lock; /* RX/TX lock */ +}; + +/* Index to functions, as function prototypes. */ +static int cops_probe1 (struct net_device *dev, int ioaddr); +static int cops_irq (int ioaddr, int board); + +static int cops_open (struct net_device *dev); +static int cops_jumpstart (struct net_device *dev); +static void cops_reset (struct net_device *dev, int sleep); +static void cops_load (struct net_device *dev); +static int cops_nodeid (struct net_device *dev, int nodeid); + +static irqreturn_t cops_interrupt (int irq, void *dev_id); +static void cops_poll (unsigned long ltdev); +static void cops_timeout(struct net_device *dev); +static void cops_rx (struct net_device *dev); +static netdev_tx_t cops_send_packet (struct sk_buff *skb, + struct net_device *dev); +static void set_multicast_list (struct net_device *dev); +static int cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); +static int cops_close (struct net_device *dev); + +static void cleanup_card(struct net_device *dev) +{ + if (dev->irq) + free_irq(dev->irq, dev); + release_region(dev->base_addr, COPS_IO_EXTENT); +} + +/* + * Check for a network adaptor of this type, and return '0' iff one exists. + * If dev->base_addr == 0, probe all likely locations. + * If dev->base_addr in [1..0x1ff], always return failure. + * otherwise go with what we pass in. + */ +struct net_device * __init cops_probe(int unit) +{ + struct net_device *dev; + unsigned *port; + int base_addr; + int err = 0; + + dev = alloc_ltalkdev(sizeof(struct cops_local)); + if (!dev) + return ERR_PTR(-ENOMEM); + + if (unit >= 0) { + sprintf(dev->name, "lt%d", unit); + netdev_boot_setup_check(dev); + irq = dev->irq; + base_addr = dev->base_addr; + } else { + base_addr = dev->base_addr = io; + } + + if (base_addr > 0x1ff) { /* Check a single specified location. */ + err = cops_probe1(dev, base_addr); + } else if (base_addr != 0) { /* Don't probe at all. */ + err = -ENXIO; + } else { + /* FIXME Does this really work for cards which generate irq? + * It's definitely N.G. for polled Tangent. sh + * Dayna cards don't autoprobe well at all, but if your card is + * at IRQ 5 & IO 0x240 we find it every time. ;) JS + */ + for (port = ports; *port && cops_probe1(dev, *port) < 0; port++) + ; + if (!*port) + err = -ENODEV; + } + if (err) + goto out; + err = register_netdev(dev); + if (err) + goto out1; + return dev; +out1: + cleanup_card(dev); +out: + free_netdev(dev); + return ERR_PTR(err); +} + +static const struct net_device_ops cops_netdev_ops = { + .ndo_open = cops_open, + .ndo_stop = cops_close, + .ndo_start_xmit = cops_send_packet, + .ndo_tx_timeout = cops_timeout, + .ndo_do_ioctl = cops_ioctl, + .ndo_set_multicast_list = set_multicast_list, +}; + +/* + * This is the real probe routine. Linux has a history of friendly device + * probes on the ISA bus. A good device probes avoids doing writes, and + * verifies that the correct device exists and functions. + */ +static int __init cops_probe1(struct net_device *dev, int ioaddr) +{ + struct cops_local *lp; + static unsigned version_printed; + int board = board_type; + int retval; + + if(cops_debug && version_printed++ == 0) + printk("%s", version); + + /* Grab the region so no one else tries to probe our ioports. */ + if (!request_region(ioaddr, COPS_IO_EXTENT, dev->name)) + return -EBUSY; + + /* + * Since this board has jumpered interrupts, allocate the interrupt + * vector now. There is no point in waiting since no other device + * can use the interrupt, and this marks the irq as busy. Jumpered + * interrupts are typically not reported by the boards, and we must + * used AutoIRQ to find them. + */ + dev->irq = irq; + switch (dev->irq) + { + case 0: + /* COPS AutoIRQ routine */ + dev->irq = cops_irq(ioaddr, board); + if (dev->irq) + break; + /* No IRQ found on this port, fallthrough */ + case 1: + retval = -EINVAL; + goto err_out; + + /* Fixup for users that don't know that IRQ 2 is really + * IRQ 9, or don't know which one to set. + */ + case 2: + dev->irq = 9; + break; + + /* Polled operation requested. Although irq of zero passed as + * a parameter tells the init routines to probe, we'll + * overload it to denote polled operation at runtime. + */ + case 0xff: + dev->irq = 0; + break; + + default: + break; + } + + /* Reserve any actual interrupt. */ + if (dev->irq) { + retval = request_irq(dev->irq, cops_interrupt, 0, dev->name, dev); + if (retval) + goto err_out; + } + + dev->base_addr = ioaddr; + + lp = netdev_priv(dev); + spin_lock_init(&lp->lock); + + /* Copy local board variable to lp struct. */ + lp->board = board; + + dev->netdev_ops = &cops_netdev_ops; + dev->watchdog_timeo = HZ * 2; + + + /* Tell the user where the card is and what mode we're in. */ + if(board==DAYNA) + printk("%s: %s at %#3x, using IRQ %d, in Dayna mode.\n", + dev->name, cardname, ioaddr, dev->irq); + if(board==TANGENT) { + if(dev->irq) + printk("%s: %s at %#3x, IRQ %d, in Tangent mode\n", + dev->name, cardname, ioaddr, dev->irq); + else + printk("%s: %s at %#3x, using polled IO, in Tangent mode.\n", + dev->name, cardname, ioaddr); + + } + return 0; + +err_out: + release_region(ioaddr, COPS_IO_EXTENT); + return retval; +} + +static int __init cops_irq (int ioaddr, int board) +{ /* + * This does not use the IRQ to determine where the IRQ is. We just + * assume that when we get a correct status response that it's the IRQ. + * This really just verifies the IO port but since we only have access + * to such a small number of IRQs (5, 4, 3) this is not bad. + * This will probably not work for more than one card. + */ + int irqaddr=0; + int i, x, status; + + if(board==DAYNA) + { + outb(0, ioaddr+DAYNA_RESET); + inb(ioaddr+DAYNA_RESET); + mdelay(333); + } + if(board==TANGENT) + { + inb(ioaddr); + outb(0, ioaddr); + outb(0, ioaddr+TANG_RESET); + } + + for(i=0; cops_irqlist[i] !=0; i++) + { + irqaddr = cops_irqlist[i]; + for(x = 0xFFFF; x>0; x --) /* wait for response */ + { + if(board==DAYNA) + { + status = (inb(ioaddr+DAYNA_CARD_STATUS)&3); + if(status == 1) + return irqaddr; + } + if(board==TANGENT) + { + if((inb(ioaddr+TANG_CARD_STATUS)& TANG_TX_READY) !=0) + return irqaddr; + } + } + } + return 0; /* no IRQ found */ +} + +/* + * Open/initialize the board. This is called (in the current kernel) + * sometime after booting when the 'ifconfig' program is run. + */ +static int cops_open(struct net_device *dev) +{ + struct cops_local *lp = netdev_priv(dev); + + if(dev->irq==0) + { + /* + * I don't know if the Dayna-style boards support polled + * operation. For now, only allow it for Tangent. + */ + if(lp->board==TANGENT) /* Poll 20 times per second */ + { + init_timer(&cops_timer); + cops_timer.function = cops_poll; + cops_timer.data = (unsigned long)dev; + cops_timer.expires = jiffies + HZ/20; + add_timer(&cops_timer); + } + else + { + printk(KERN_WARNING "%s: No irq line set\n", dev->name); + return -EAGAIN; + } + } + + cops_jumpstart(dev); /* Start the card up. */ + + netif_start_queue(dev); + return 0; +} + +/* + * This allows for a dynamic start/restart of the entire card. + */ +static int cops_jumpstart(struct net_device *dev) +{ + struct cops_local *lp = netdev_priv(dev); + + /* + * Once the card has the firmware loaded and has acquired + * the nodeid, if it is reset it will lose it all. + */ + cops_reset(dev,1); /* Need to reset card before load firmware. */ + cops_load(dev); /* Load the firmware. */ + + /* + * If atalkd already gave us a nodeid we will use that + * one again, else we wait for atalkd to give us a nodeid + * in cops_ioctl. This may cause a problem if someone steals + * our nodeid while we are resetting. + */ + if(lp->nodeid == 1) + cops_nodeid(dev,lp->node_acquire); + + return 0; +} + +static void tangent_wait_reset(int ioaddr) +{ + int timeout=0; + + while(timeout++ < 5 && (inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0) + mdelay(1); /* Wait 1 second */ +} + +/* + * Reset the LocalTalk board. + */ +static void cops_reset(struct net_device *dev, int sleep) +{ + struct cops_local *lp = netdev_priv(dev); + int ioaddr=dev->base_addr; + + if(lp->board==TANGENT) + { + inb(ioaddr); /* Clear request latch. */ + outb(0,ioaddr); /* Clear the TANG_TX_READY flop. */ + outb(0, ioaddr+TANG_RESET); /* Reset the adapter. */ + + tangent_wait_reset(ioaddr); + outb(0, ioaddr+TANG_CLEAR_INT); + } + if(lp->board==DAYNA) + { + outb(0, ioaddr+DAYNA_RESET); /* Assert the reset port */ + inb(ioaddr+DAYNA_RESET); /* Clear the reset */ + if (sleep) + msleep(333); + else + mdelay(333); + } + + netif_wake_queue(dev); +} + +static void cops_load (struct net_device *dev) +{ + struct ifreq ifr; + struct ltfirmware *ltf= (struct ltfirmware *)&ifr.ifr_ifru; + struct cops_local *lp = netdev_priv(dev); + int ioaddr=dev->base_addr; + int length, i = 0; + + strcpy(ifr.ifr_name,"lt0"); + + /* Get card's firmware code and do some checks on it. */ +#ifdef CONFIG_COPS_DAYNA + if(lp->board==DAYNA) + { + ltf->length=sizeof(ffdrv_code); + ltf->data=ffdrv_code; + } + else +#endif +#ifdef CONFIG_COPS_TANGENT + if(lp->board==TANGENT) + { + ltf->length=sizeof(ltdrv_code); + ltf->data=ltdrv_code; + } + else +#endif + { + printk(KERN_INFO "%s; unsupported board type.\n", dev->name); + return; + } + + /* Check to make sure firmware is correct length. */ + if(lp->board==DAYNA && ltf->length!=5983) + { + printk(KERN_WARNING "%s: Firmware is not length of FFDRV.BIN.\n", dev->name); + return; + } + if(lp->board==TANGENT && ltf->length!=2501) + { + printk(KERN_WARNING "%s: Firmware is not length of DRVCODE.BIN.\n", dev->name); + return; + } + + if(lp->board==DAYNA) + { + /* + * We must wait for a status response + * with the DAYNA board. + */ + while(++i<65536) + { + if((inb(ioaddr+DAYNA_CARD_STATUS)&3)==1) + break; + } + + if(i==65536) + return; + } + + /* + * Upload the firmware and kick. Byte-by-byte works nicely here. + */ + i=0; + length = ltf->length; + while(length--) + { + outb(ltf->data[i], ioaddr); + i++; + } + + if(cops_debug > 1) + printk("%s: Uploaded firmware - %d bytes of %d bytes.\n", + dev->name, i, ltf->length); + + if(lp->board==DAYNA) /* Tell Dayna to run the firmware code. */ + outb(1, ioaddr+DAYNA_INT_CARD); + else /* Tell Tang to run the firmware code. */ + inb(ioaddr); + + if(lp->board==TANGENT) + { + tangent_wait_reset(ioaddr); + inb(ioaddr); /* Clear initial ready signal. */ + } +} + +/* + * Get the LocalTalk Nodeid from the card. We can suggest + * any nodeid 1-254. The card will try and get that exact + * address else we can specify 0 as the nodeid and the card + * will autoprobe for a nodeid. + */ +static int cops_nodeid (struct net_device *dev, int nodeid) +{ + struct cops_local *lp = netdev_priv(dev); + int ioaddr = dev->base_addr; + + if(lp->board == DAYNA) + { + /* Empty any pending adapter responses. */ + while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0) + { + outb(0, ioaddr+COPS_CLEAR_INT); /* Clear interrupts. */ + if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST) + cops_rx(dev); /* Kick any packets waiting. */ + schedule(); + } + + outb(2, ioaddr); /* Output command packet length as 2. */ + outb(0, ioaddr); + outb(LAP_INIT, ioaddr); /* Send LAP_INIT command byte. */ + outb(nodeid, ioaddr); /* Suggest node address. */ + } + + if(lp->board == TANGENT) + { + /* Empty any pending adapter responses. */ + while(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY) + { + outb(0, ioaddr+COPS_CLEAR_INT); /* Clear interrupt. */ + cops_rx(dev); /* Kick out packets waiting. */ + schedule(); + } + + /* Not sure what Tangent does if nodeid picked is used. */ + if(nodeid == 0) /* Seed. */ + nodeid = jiffies&0xFF; /* Get a random try */ + outb(2, ioaddr); /* Command length LSB */ + outb(0, ioaddr); /* Command length MSB */ + outb(LAP_INIT, ioaddr); /* Send LAP_INIT byte */ + outb(nodeid, ioaddr); /* LAP address hint. */ + outb(0xFF, ioaddr); /* Int. level to use */ + } + + lp->node_acquire=0; /* Set nodeid holder to 0. */ + while(lp->node_acquire==0) /* Get *True* nodeid finally. */ + { + outb(0, ioaddr+COPS_CLEAR_INT); /* Clear any interrupt. */ + + if(lp->board == DAYNA) + { + if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST) + cops_rx(dev); /* Grab the nodeid put in lp->node_acquire. */ + } + if(lp->board == TANGENT) + { + if(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY) + cops_rx(dev); /* Grab the nodeid put in lp->node_acquire. */ + } + schedule(); + } + + if(cops_debug > 1) + printk(KERN_DEBUG "%s: Node ID %d has been acquired.\n", + dev->name, lp->node_acquire); + + lp->nodeid=1; /* Set got nodeid to 1. */ + + return 0; +} + +/* + * Poll the Tangent type cards to see if we have work. + */ + +static void cops_poll(unsigned long ltdev) +{ + int ioaddr, status; + int boguscount = 0; + + struct net_device *dev = (struct net_device *)ltdev; + + del_timer(&cops_timer); + + if(dev == NULL) + return; /* We've been downed */ + + ioaddr = dev->base_addr; + do { + status=inb(ioaddr+TANG_CARD_STATUS); + if(status & TANG_RX_READY) + cops_rx(dev); + if(status & TANG_TX_READY) + netif_wake_queue(dev); + status = inb(ioaddr+TANG_CARD_STATUS); + } while((++boguscount < 20) && (status&(TANG_RX_READY|TANG_TX_READY))); + + /* poll 20 times per second */ + cops_timer.expires = jiffies + HZ/20; + add_timer(&cops_timer); +} + +/* + * The typical workload of the driver: + * Handle the network interface interrupts. + */ +static irqreturn_t cops_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct cops_local *lp; + int ioaddr, status; + int boguscount = 0; + + ioaddr = dev->base_addr; + lp = netdev_priv(dev); + + if(lp->board==DAYNA) + { + do { + outb(0, ioaddr + COPS_CLEAR_INT); + status=inb(ioaddr+DAYNA_CARD_STATUS); + if((status&0x03)==DAYNA_RX_REQUEST) + cops_rx(dev); + netif_wake_queue(dev); + } while(++boguscount < 20); + } + else + { + do { + status=inb(ioaddr+TANG_CARD_STATUS); + if(status & TANG_RX_READY) + cops_rx(dev); + if(status & TANG_TX_READY) + netif_wake_queue(dev); + status=inb(ioaddr+TANG_CARD_STATUS); + } while((++boguscount < 20) && (status&(TANG_RX_READY|TANG_TX_READY))); + } + + return IRQ_HANDLED; +} + +/* + * We have a good packet(s), get it/them out of the buffers. + */ +static void cops_rx(struct net_device *dev) +{ + int pkt_len = 0; + int rsp_type = 0; + struct sk_buff *skb = NULL; + struct cops_local *lp = netdev_priv(dev); + int ioaddr = dev->base_addr; + int boguscount = 0; + unsigned long flags; + + + spin_lock_irqsave(&lp->lock, flags); + + if(lp->board==DAYNA) + { + outb(0, ioaddr); /* Send out Zero length. */ + outb(0, ioaddr); + outb(DATA_READ, ioaddr); /* Send read command out. */ + + /* Wait for DMA to turn around. */ + while(++boguscount<1000000) + { + barrier(); + if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_READY) + break; + } + + if(boguscount==1000000) + { + printk(KERN_WARNING "%s: DMA timed out.\n",dev->name); + spin_unlock_irqrestore(&lp->lock, flags); + return; + } + } + + /* Get response length. */ + if(lp->board==DAYNA) + pkt_len = inb(ioaddr) & 0xFF; + else + pkt_len = inb(ioaddr) & 0x00FF; + pkt_len |= (inb(ioaddr) << 8); + /* Input IO code. */ + rsp_type=inb(ioaddr); + + /* Malloc up new buffer. */ + skb = dev_alloc_skb(pkt_len); + if(skb == NULL) + { + printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", + dev->name); + dev->stats.rx_dropped++; + while(pkt_len--) /* Discard packet */ + inb(ioaddr); + spin_unlock_irqrestore(&lp->lock, flags); + return; + } + skb->dev = dev; + skb_put(skb, pkt_len); + skb->protocol = htons(ETH_P_LOCALTALK); + + insb(ioaddr, skb->data, pkt_len); /* Eat the Data */ + + if(lp->board==DAYNA) + outb(1, ioaddr+DAYNA_INT_CARD); /* Interrupt the card */ + + spin_unlock_irqrestore(&lp->lock, flags); /* Restore interrupts. */ + + /* Check for bad response length */ + if(pkt_len < 0 || pkt_len > MAX_LLAP_SIZE) + { + printk(KERN_WARNING "%s: Bad packet length of %d bytes.\n", + dev->name, pkt_len); + dev->stats.tx_errors++; + dev_kfree_skb_any(skb); + return; + } + + /* Set nodeid and then get out. */ + if(rsp_type == LAP_INIT_RSP) + { /* Nodeid taken from received packet. */ + lp->node_acquire = skb->data[0]; + dev_kfree_skb_any(skb); + return; + } + + /* One last check to make sure we have a good packet. */ + if(rsp_type != LAP_RESPONSE) + { + printk(KERN_WARNING "%s: Bad packet type %d.\n", dev->name, rsp_type); + dev->stats.tx_errors++; + dev_kfree_skb_any(skb); + return; + } + + skb_reset_mac_header(skb); /* Point to entire packet. */ + skb_pull(skb,3); + skb_reset_transport_header(skb); /* Point to data (Skip header). */ + + /* Update the counters. */ + dev->stats.rx_packets++; + dev->stats.rx_bytes += skb->len; + + /* Send packet to a higher place. */ + netif_rx(skb); +} + +static void cops_timeout(struct net_device *dev) +{ + struct cops_local *lp = netdev_priv(dev); + int ioaddr = dev->base_addr; + + dev->stats.tx_errors++; + if(lp->board==TANGENT) + { + if((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0) + printk(KERN_WARNING "%s: No TX complete interrupt.\n", dev->name); + } + printk(KERN_WARNING "%s: Transmit timed out.\n", dev->name); + cops_jumpstart(dev); /* Restart the card. */ + dev->trans_start = jiffies; /* prevent tx timeout */ + netif_wake_queue(dev); +} + + +/* + * Make the card transmit a LocalTalk packet. + */ + +static netdev_tx_t cops_send_packet(struct sk_buff *skb, + struct net_device *dev) +{ + struct cops_local *lp = netdev_priv(dev); + int ioaddr = dev->base_addr; + unsigned long flags; + + /* + * Block a timer-based transmit from overlapping. + */ + + netif_stop_queue(dev); + + spin_lock_irqsave(&lp->lock, flags); + if(lp->board == DAYNA) /* Wait for adapter transmit buffer. */ + while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0) + cpu_relax(); + if(lp->board == TANGENT) /* Wait for adapter transmit buffer. */ + while((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0) + cpu_relax(); + + /* Output IO length. */ + outb(skb->len, ioaddr); + if(lp->board == DAYNA) + outb(skb->len >> 8, ioaddr); + else + outb((skb->len >> 8)&0x0FF, ioaddr); + + /* Output IO code. */ + outb(LAP_WRITE, ioaddr); + + if(lp->board == DAYNA) /* Check the transmit buffer again. */ + while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0); + + outsb(ioaddr, skb->data, skb->len); /* Send out the data. */ + + if(lp->board==DAYNA) /* Dayna requires you kick the card */ + outb(1, ioaddr+DAYNA_INT_CARD); + + spin_unlock_irqrestore(&lp->lock, flags); /* Restore interrupts. */ + + /* Done sending packet, update counters and cleanup. */ + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + dev_kfree_skb (skb); + return NETDEV_TX_OK; +} + +/* + * Dummy function to keep the Appletalk layer happy. + */ + +static void set_multicast_list(struct net_device *dev) +{ + if(cops_debug >= 3) + printk("%s: set_multicast_list executed\n", dev->name); +} + +/* + * System ioctls for the COPS LocalTalk card. + */ + +static int cops_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct cops_local *lp = netdev_priv(dev); + struct sockaddr_at *sa = (struct sockaddr_at *)&ifr->ifr_addr; + struct atalk_addr *aa = (struct atalk_addr *)&lp->node_addr; + + switch(cmd) + { + case SIOCSIFADDR: + /* Get and set the nodeid and network # atalkd wants. */ + cops_nodeid(dev, sa->sat_addr.s_node); + aa->s_net = sa->sat_addr.s_net; + aa->s_node = lp->node_acquire; + + /* Set broardcast address. */ + dev->broadcast[0] = 0xFF; + + /* Set hardware address. */ + dev->dev_addr[0] = aa->s_node; + dev->addr_len = 1; + return 0; + + case SIOCGIFADDR: + sa->sat_addr.s_net = aa->s_net; + sa->sat_addr.s_node = aa->s_node; + return 0; + + default: + return -EOPNOTSUPP; + } +} + +/* + * The inverse routine to cops_open(). + */ + +static int cops_close(struct net_device *dev) +{ + struct cops_local *lp = netdev_priv(dev); + + /* If we were running polled, yank the timer. + */ + if(lp->board==TANGENT && dev->irq==0) + del_timer(&cops_timer); + + netif_stop_queue(dev); + return 0; +} + + +#ifdef MODULE +static struct net_device *cops_dev; + +MODULE_LICENSE("GPL"); +module_param(io, int, 0); +module_param(irq, int, 0); +module_param(board_type, int, 0); + +static int __init cops_module_init(void) +{ + if (io == 0) + printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n", + cardname); + cops_dev = cops_probe(-1); + if (IS_ERR(cops_dev)) + return PTR_ERR(cops_dev); + return 0; +} + +static void __exit cops_module_exit(void) +{ + unregister_netdev(cops_dev); + cleanup_card(cops_dev); + free_netdev(cops_dev); +} +module_init(cops_module_init); +module_exit(cops_module_exit); +#endif /* MODULE */ diff --git a/drivers/net/appletalk/cops.h b/drivers/net/appletalk/cops.h new file mode 100644 index 000000000000..fd2750b269c8 --- /dev/null +++ b/drivers/net/appletalk/cops.h @@ -0,0 +1,60 @@ +/* cops.h: LocalTalk driver for Linux. + * + * Authors: + * - Jay Schulist + */ + +#ifndef __LINUX_COPSLTALK_H +#define __LINUX_COPSLTALK_H + +#ifdef __KERNEL__ + +/* Max LLAP size we will accept. */ +#define MAX_LLAP_SIZE 603 + +/* Tangent */ +#define TANG_CARD_STATUS 1 +#define TANG_CLEAR_INT 1 +#define TANG_RESET 3 + +#define TANG_TX_READY 1 +#define TANG_RX_READY 2 + +/* Dayna */ +#define DAYNA_CMD_DATA 0 +#define DAYNA_CLEAR_INT 1 +#define DAYNA_CARD_STATUS 2 +#define DAYNA_INT_CARD 3 +#define DAYNA_RESET 4 + +#define DAYNA_RX_READY 0 +#define DAYNA_TX_READY 1 +#define DAYNA_RX_REQUEST 3 + +/* Same on both card types */ +#define COPS_CLEAR_INT 1 + +/* LAP response codes received from the cards. */ +#define LAP_INIT 1 /* Init cmd */ +#define LAP_INIT_RSP 2 /* Init response */ +#define LAP_WRITE 3 /* Write cmd */ +#define DATA_READ 4 /* Data read */ +#define LAP_RESPONSE 4 /* Received ALAP frame response */ +#define LAP_GETSTAT 5 /* Get LAP and HW status */ +#define LAP_RSPSTAT 6 /* Status response */ + +#endif + +/* + * Structure to hold the firmware information. + */ +struct ltfirmware +{ + unsigned int length; + const unsigned char *data; +}; + +#define DAYNA 1 +#define TANGENT 2 + +#endif diff --git a/drivers/net/appletalk/cops_ffdrv.h b/drivers/net/appletalk/cops_ffdrv.h new file mode 100644 index 000000000000..b02005087c1b --- /dev/null +++ b/drivers/net/appletalk/cops_ffdrv.h @@ -0,0 +1,532 @@ + +/* + * The firmware this driver downloads into the Localtalk card is a + * separate program and is not GPL'd source code, even though the Linux + * side driver and the routine that loads this data into the card are. + * + * It is taken from the COPS SDK and is under the following license + * + * This material is licensed to you strictly for use in conjunction with + * the use of COPS LocalTalk adapters. + * There is no charge for this SDK. And no waranty express or implied + * about its fitness for any purpose. However, we will cheerefully + * refund every penny you paid for this SDK... + * Regards, + * + * Thomas F. Divine + * Chief Scientist + */ + + +/* cops_ffdrv.h: LocalTalk driver firmware dump for Linux. + * + * Authors: + * - Jay Schulist + */ + + +#ifdef CONFIG_COPS_DAYNA + +static const unsigned char ffdrv_code[] = { + 58,3,0,50,228,149,33,255,255,34,226,149, + 249,17,40,152,33,202,154,183,237,82,77,68, + 11,107,98,19,54,0,237,176,175,50,80,0, + 62,128,237,71,62,32,237,57,51,62,12,237, + 57,50,237,57,54,62,6,237,57,52,62,12, + 237,57,49,33,107,137,34,32,128,33,83,130, + 34,40,128,33,86,130,34,42,128,33,112,130, + 34,36,128,33,211,130,34,38,128,62,0,237, + 57,16,33,63,148,34,34,128,237,94,205,15, + 130,251,205,168,145,24,141,67,111,112,121,114, + 105,103,104,116,32,40,67,41,32,49,57,56, + 56,32,45,32,68,97,121,110,97,32,67,111, + 109,109,117,110,105,99,97,116,105,111,110,115, + 32,32,32,65,108,108,32,114,105,103,104,116, + 115,32,114,101,115,101,114,118,101,100,46,32, + 32,40,68,40,68,7,16,8,34,7,22,6, + 16,5,12,4,8,3,6,140,0,16,39,128, + 0,4,96,10,224,6,0,7,126,2,64,11, + 118,12,6,13,0,14,193,15,0,5,96,3, + 192,1,64,9,8,62,9,211,66,62,192,211, + 66,62,100,61,32,253,6,28,33,205,129,14, + 66,237,163,194,253,129,6,28,33,205,129,14, + 64,237,163,194,9,130,201,62,47,50,71,152, + 62,47,211,68,58,203,129,237,57,20,58,204, + 129,237,57,21,33,77,152,54,132,205,233,129, + 58,228,149,254,209,40,6,56,4,62,0,24, + 2,219,96,33,233,149,119,230,62,33,232,149, + 119,213,33,8,152,17,7,0,25,119,19,25, + 119,209,201,251,237,77,245,197,213,229,221,229, + 205,233,129,62,1,50,106,137,205,158,139,221, + 225,225,209,193,241,251,237,77,245,197,213,219, + 72,237,56,16,230,46,237,57,16,237,56,12, + 58,72,152,183,32,26,6,20,17,128,2,237, + 56,46,187,32,35,237,56,47,186,32,29,219, + 72,230,1,32,3,5,32,232,175,50,72,152, + 229,221,229,62,1,50,106,137,205,158,139,221, + 225,225,24,25,62,1,50,72,152,58,201,129, + 237,57,12,58,202,129,237,57,13,237,56,16, + 246,17,237,57,16,209,193,241,251,237,77,245, + 197,229,213,221,229,237,56,16,230,17,237,57, + 16,237,56,20,58,34,152,246,16,246,8,211, + 68,62,6,61,32,253,58,34,152,246,8,211, + 68,58,203,129,237,57,20,58,204,129,237,57, + 21,237,56,16,246,34,237,57,16,221,225,209, + 225,193,241,251,237,77,33,2,0,57,126,230, + 3,237,100,1,40,2,246,128,230,130,245,62, + 5,211,64,241,211,64,201,229,213,243,237,56, + 16,230,46,237,57,16,237,56,12,251,70,35, + 35,126,254,175,202,77,133,254,129,202,15,133, + 230,128,194,191,132,43,58,44,152,119,33,76, + 152,119,35,62,132,119,120,254,255,40,4,58, + 49,152,119,219,72,43,43,112,17,3,0,237, + 56,52,230,248,237,57,52,219,72,230,1,194, + 141,131,209,225,237,56,52,246,6,237,57,52, + 62,1,55,251,201,62,3,211,66,62,192,211, + 66,62,48,211,66,0,0,219,66,230,1,40, + 4,219,67,24,240,205,203,135,58,75,152,254, + 255,202,128,132,58,49,152,254,161,250,207,131, + 58,34,152,211,68,62,10,211,66,62,128,211, + 66,62,11,211,66,62,6,211,66,24,0,62, + 14,211,66,62,33,211,66,62,1,211,66,62, + 64,211,66,62,3,211,66,62,209,211,66,62, + 100,71,219,66,230,1,32,6,5,32,247,195, + 248,132,219,67,71,58,44,152,184,194,248,132, + 62,100,71,219,66,230,1,32,6,5,32,247, + 195,248,132,219,67,62,100,71,219,66,230,1, + 32,6,5,32,247,195,248,132,219,67,254,133, + 32,7,62,0,50,74,152,24,17,254,173,32, + 7,62,1,50,74,152,24,6,254,141,194,248, + 132,71,209,225,58,49,152,254,132,32,10,62, + 50,205,2,134,205,144,135,24,27,254,140,32, + 15,62,110,205,2,134,62,141,184,32,5,205, + 144,135,24,8,62,10,205,2,134,205,8,134, + 62,1,50,106,137,205,158,139,237,56,52,246, + 6,237,57,52,175,183,251,201,62,20,135,237, + 57,20,175,237,57,21,237,56,16,246,2,237, + 57,16,237,56,20,95,237,56,21,123,254,10, + 48,244,237,56,16,230,17,237,57,16,209,225, + 205,144,135,62,1,50,106,137,205,158,139,237, + 56,52,246,6,237,57,52,175,183,251,201,209, + 225,243,219,72,230,1,40,13,62,10,211,66, + 0,0,219,66,230,192,202,226,132,237,56,52, + 246,6,237,57,52,62,1,55,251,201,205,203, + 135,62,1,50,106,137,205,158,139,237,56,52, + 246,6,237,57,52,183,251,201,209,225,62,1, + 50,106,137,205,158,139,237,56,52,246,6,237, + 57,52,62,2,55,251,201,209,225,243,219,72, + 230,1,202,213,132,62,10,211,66,0,0,219, + 66,230,192,194,213,132,229,62,1,50,106,137, + 42,40,152,205,65,143,225,17,3,0,205,111, + 136,62,6,211,66,58,44,152,211,66,237,56, + 52,246,6,237,57,52,183,251,201,209,197,237, + 56,52,230,248,237,57,52,219,72,230,1,32, + 15,193,225,237,56,52,246,6,237,57,52,62, + 1,55,251,201,14,23,58,37,152,254,0,40, + 14,14,2,254,1,32,5,62,140,119,24,3, + 62,132,119,43,43,197,205,203,135,193,62,1, + 211,66,62,64,211,66,62,3,211,66,62,193, + 211,66,62,100,203,39,71,219,66,230,1,32, + 6,5,32,247,195,229,133,33,238,151,219,67, + 71,58,44,152,184,194,229,133,119,62,100,71, + 219,66,230,1,32,6,5,32,247,195,229,133, + 219,67,35,119,13,32,234,193,225,62,1,50, + 106,137,205,158,139,237,56,52,246,6,237,57, + 52,175,183,251,201,33,234,151,35,35,62,255, + 119,193,225,62,1,50,106,137,205,158,139,237, + 56,52,246,6,237,57,52,175,251,201,243,61, + 32,253,251,201,62,3,211,66,62,192,211,66, + 58,49,152,254,140,32,19,197,229,213,17,181, + 129,33,185,129,1,2,0,237,176,209,225,193, + 24,27,229,213,33,187,129,58,49,152,230,15, + 87,30,2,237,92,25,17,181,129,126,18,19, + 35,126,18,209,225,58,34,152,246,8,211,68, + 58,49,152,254,165,40,14,254,164,40,10,62, + 10,211,66,62,224,211,66,24,25,58,74,152, + 254,0,40,10,62,10,211,66,62,160,211,66, + 24,8,62,10,211,66,62,128,211,66,62,11, + 211,66,62,6,211,66,205,147,143,62,5,211, + 66,62,224,211,66,62,5,211,66,62,96,211, + 66,62,5,61,32,253,62,5,211,66,62,224, + 211,66,62,14,61,32,253,62,5,211,66,62, + 233,211,66,62,128,211,66,58,181,129,61,32, + 253,62,1,211,66,62,192,211,66,1,254,19, + 237,56,46,187,32,6,13,32,247,195,226,134, + 62,192,211,66,0,0,219,66,203,119,40,250, + 219,66,203,87,40,250,243,237,56,16,230,17, + 237,57,16,237,56,20,251,62,5,211,66,62, + 224,211,66,58,182,129,61,32,253,229,33,181, + 129,58,183,129,203,63,119,35,58,184,129,119, + 225,62,10,211,66,62,224,211,66,62,11,211, + 66,62,118,211,66,62,47,211,68,62,5,211, + 66,62,233,211,66,58,181,129,61,32,253,62, + 5,211,66,62,224,211,66,58,182,129,61,32, + 253,62,5,211,66,62,96,211,66,201,229,213, + 58,50,152,230,15,87,30,2,237,92,33,187, + 129,25,17,181,129,126,18,35,19,126,18,209, + 225,58,71,152,246,8,211,68,58,50,152,254, + 165,40,14,254,164,40,10,62,10,211,66,62, + 224,211,66,24,8,62,10,211,66,62,128,211, + 66,62,11,211,66,62,6,211,66,195,248,135, + 62,3,211,66,62,192,211,66,197,229,213,17, + 181,129,33,183,129,1,2,0,237,176,209,225, + 193,62,47,211,68,62,10,211,66,62,224,211, + 66,62,11,211,66,62,118,211,66,62,1,211, + 66,62,0,211,66,205,147,143,195,16,136,62, + 3,211,66,62,192,211,66,197,229,213,17,181, + 129,33,183,129,1,2,0,237,176,209,225,193, + 62,47,211,68,62,10,211,66,62,224,211,66, + 62,11,211,66,62,118,211,66,205,147,143,62, + 5,211,66,62,224,211,66,62,5,211,66,62, + 96,211,66,62,5,61,32,253,62,5,211,66, + 62,224,211,66,62,14,61,32,253,62,5,211, + 66,62,233,211,66,62,128,211,66,58,181,129, + 61,32,253,62,1,211,66,62,192,211,66,1, + 254,19,237,56,46,187,32,6,13,32,247,195, + 88,136,62,192,211,66,0,0,219,66,203,119, + 40,250,219,66,203,87,40,250,62,5,211,66, + 62,224,211,66,58,182,129,61,32,253,62,5, + 211,66,62,96,211,66,201,197,14,67,6,0, + 62,3,211,66,62,192,211,66,62,48,211,66, + 0,0,219,66,230,1,40,4,219,67,24,240, + 62,5,211,66,62,233,211,66,62,128,211,66, + 58,181,129,61,32,253,237,163,29,62,192,211, + 66,219,66,230,4,40,250,237,163,29,32,245, + 219,66,230,4,40,250,62,255,71,219,66,230, + 4,40,3,5,32,247,219,66,230,4,40,250, + 62,5,211,66,62,224,211,66,58,182,129,61, + 32,253,62,5,211,66,62,96,211,66,58,71, + 152,254,1,202,18,137,62,16,211,66,62,56, + 211,66,62,14,211,66,62,33,211,66,62,1, + 211,66,62,248,211,66,237,56,48,246,153,230, + 207,237,57,48,62,3,211,66,62,221,211,66, + 193,201,58,71,152,211,68,62,10,211,66,62, + 128,211,66,62,11,211,66,62,6,211,66,62, + 6,211,66,58,44,152,211,66,62,16,211,66, + 62,56,211,66,62,48,211,66,0,0,62,14, + 211,66,62,33,211,66,62,1,211,66,62,248, + 211,66,237,56,48,246,145,246,8,230,207,237, + 57,48,62,3,211,66,62,221,211,66,193,201, + 44,3,1,0,70,69,1,245,197,213,229,175, + 50,72,152,237,56,16,230,46,237,57,16,237, + 56,12,62,1,211,66,0,0,219,66,95,230, + 160,32,3,195,20,139,123,230,96,194,72,139, + 62,48,211,66,62,1,211,66,62,64,211,66, + 237,91,40,152,205,207,143,25,43,55,237,82, + 218,70,139,34,42,152,98,107,58,44,152,190, + 194,210,138,35,35,62,130,190,194,200,137,62, + 1,50,48,152,62,175,190,202,82,139,62,132, + 190,32,44,50,50,152,62,47,50,71,152,229, + 175,50,106,137,42,40,152,205,65,143,225,54, + 133,43,70,58,44,152,119,43,112,17,3,0, + 62,10,205,2,134,205,111,136,195,158,138,62, + 140,190,32,19,50,50,152,58,233,149,230,4, + 202,222,138,62,1,50,71,152,195,219,137,126, + 254,160,250,185,138,254,166,242,185,138,50,50, + 152,43,126,35,229,213,33,234,149,95,22,0, + 25,126,254,132,40,18,254,140,40,14,58,50, + 152,230,15,87,126,31,21,242,65,138,56,2, + 175,119,58,50,152,230,15,87,58,233,149,230, + 62,31,21,242,85,138,218,98,138,209,225,195, + 20,139,58,50,152,33,100,137,230,15,95,22, + 0,25,126,50,71,152,209,225,58,50,152,254, + 164,250,135,138,58,73,152,254,0,40,4,54, + 173,24,2,54,133,43,70,58,44,152,119,43, + 112,17,3,0,205,70,135,175,50,106,137,205, + 208,139,58,199,129,237,57,12,58,200,129,237, + 57,13,237,56,16,246,17,237,57,16,225,209, + 193,241,251,237,77,62,129,190,194,227,138,54, + 130,43,70,58,44,152,119,43,112,17,3,0, + 205,144,135,195,20,139,35,35,126,254,132,194, + 227,138,175,50,106,137,205,158,139,24,42,58, + 201,154,254,1,40,7,62,1,50,106,137,24, + 237,58,106,137,254,1,202,222,138,62,128,166, + 194,222,138,221,229,221,33,67,152,205,127,142, + 205,109,144,221,225,225,209,193,241,251,237,77, + 58,106,137,254,1,202,44,139,58,50,152,254, + 164,250,44,139,58,73,152,238,1,50,73,152, + 221,229,221,33,51,152,205,127,142,221,225,62, + 1,50,106,137,205,158,139,195,13,139,24,208, + 24,206,24,204,230,64,40,3,195,20,139,195, + 20,139,43,126,33,8,152,119,35,58,44,152, + 119,43,237,91,35,152,205,203,135,205,158,139, + 195,13,139,175,50,78,152,62,3,211,66,62, + 192,211,66,201,197,33,4,0,57,126,35,102, + 111,62,1,50,106,137,219,72,205,141,139,193, + 201,62,1,50,78,152,34,40,152,54,0,35, + 35,54,0,195,163,139,58,78,152,183,200,229, + 33,181,129,58,183,129,119,35,58,184,129,119, + 225,62,47,211,68,62,14,211,66,62,193,211, + 66,62,10,211,66,62,224,211,66,62,11,211, + 66,62,118,211,66,195,3,140,58,78,152,183, + 200,58,71,152,211,68,254,69,40,4,254,70, + 32,17,58,73,152,254,0,40,10,62,10,211, + 66,62,160,211,66,24,8,62,10,211,66,62, + 128,211,66,62,11,211,66,62,6,211,66,62, + 6,211,66,58,44,152,211,66,62,16,211,66, + 62,56,211,66,62,48,211,66,0,0,219,66, + 230,1,40,4,219,67,24,240,62,14,211,66, + 62,33,211,66,42,40,152,205,65,143,62,1, + 211,66,62,248,211,66,237,56,48,246,145,246, + 8,230,207,237,57,48,62,3,211,66,62,221, + 211,66,201,62,16,211,66,62,56,211,66,62, + 48,211,66,0,0,219,66,230,1,40,4,219, + 67,24,240,62,14,211,66,62,33,211,66,62, + 1,211,66,62,248,211,66,237,56,48,246,153, + 230,207,237,57,48,62,3,211,66,62,221,211, + 66,201,229,213,33,234,149,95,22,0,25,126, + 254,132,40,4,254,140,32,2,175,119,123,209, + 225,201,6,8,14,0,31,48,1,12,16,250, + 121,201,33,4,0,57,94,35,86,33,2,0, + 57,126,35,102,111,221,229,34,89,152,237,83, + 91,152,221,33,63,152,205,127,142,58,81,152, + 50,82,152,58,80,152,135,50,80,152,205,162, + 140,254,3,56,16,58,81,152,135,60,230,15, + 50,81,152,175,50,80,152,24,23,58,79,152, + 205,162,140,254,3,48,13,58,81,152,203,63, + 50,81,152,62,255,50,79,152,58,81,152,50, + 82,152,58,79,152,135,50,79,152,62,32,50, + 83,152,50,84,152,237,56,16,230,17,237,57, + 16,219,72,62,192,50,93,152,62,93,50,94, + 152,58,93,152,61,50,93,152,32,9,58,94, + 152,61,50,94,152,40,44,62,170,237,57,20, + 175,237,57,21,237,56,16,246,2,237,57,16, + 219,72,230,1,202,29,141,237,56,20,71,237, + 56,21,120,254,10,48,237,237,56,16,230,17, + 237,57,16,243,62,14,211,66,62,65,211,66, + 251,58,39,152,23,23,60,50,39,152,71,58, + 82,152,160,230,15,40,22,71,14,10,219,66, + 230,16,202,186,141,219,72,230,1,202,186,141, + 13,32,239,16,235,42,89,152,237,91,91,152, + 205,47,131,48,7,61,202,186,141,195,227,141, + 221,225,33,0,0,201,221,33,55,152,205,127, + 142,58,84,152,61,50,84,152,40,19,58,82, + 152,246,1,50,82,152,58,79,152,246,1,50, + 79,152,195,29,141,221,225,33,1,0,201,221, + 33,59,152,205,127,142,58,80,152,246,1,50, + 80,152,58,82,152,135,246,1,50,82,152,58, + 83,152,61,50,83,152,194,29,141,221,225,33, + 2,0,201,221,229,33,0,0,57,17,4,0, + 25,126,50,44,152,230,128,50,85,152,58,85, + 152,183,40,6,221,33,88,2,24,4,221,33, + 150,0,58,44,152,183,40,53,60,40,50,60, + 40,47,61,61,33,86,152,119,35,119,35,54, + 129,175,50,48,152,221,43,221,229,225,124,181, + 40,42,33,86,152,17,3,0,205,189,140,17, + 232,3,27,123,178,32,251,58,48,152,183,40, + 224,58,44,152,71,62,7,128,230,127,71,58, + 85,152,176,50,44,152,24,162,221,225,201,183, + 221,52,0,192,221,52,1,192,221,52,2,192, + 221,52,3,192,55,201,245,62,1,211,100,241, + 201,245,62,1,211,96,241,201,33,2,0,57, + 126,35,102,111,237,56,48,230,175,237,57,48, + 62,48,237,57,49,125,237,57,32,124,237,57, + 33,62,0,237,57,34,62,88,237,57,35,62, + 0,237,57,36,237,57,37,33,128,2,125,237, + 57,38,124,237,57,39,237,56,48,246,97,230, + 207,237,57,48,62,0,237,57,0,62,0,211, + 96,211,100,201,33,2,0,57,126,35,102,111, + 237,56,48,230,175,237,57,48,62,12,237,57, + 49,62,76,237,57,32,62,0,237,57,33,237, + 57,34,125,237,57,35,124,237,57,36,62,0, + 237,57,37,33,128,2,125,237,57,38,124,237, + 57,39,237,56,48,246,97,230,207,237,57,48, + 62,1,211,96,201,33,2,0,57,126,35,102, + 111,229,237,56,48,230,87,237,57,48,125,237, + 57,40,124,237,57,41,62,0,237,57,42,62, + 67,237,57,43,62,0,237,57,44,58,106,137, + 254,1,32,5,33,6,0,24,3,33,128,2, + 125,237,57,46,124,237,57,47,237,56,50,230, + 252,246,2,237,57,50,225,201,33,4,0,57, + 94,35,86,33,2,0,57,126,35,102,111,237, + 56,48,230,87,237,57,48,125,237,57,40,124, + 237,57,41,62,0,237,57,42,62,67,237,57, + 43,62,0,237,57,44,123,237,57,46,122,237, + 57,47,237,56,50,230,244,246,0,237,57,50, + 237,56,48,246,145,230,207,237,57,48,201,213, + 237,56,46,95,237,56,47,87,237,56,46,111, + 237,56,47,103,183,237,82,32,235,33,128,2, + 183,237,82,209,201,213,237,56,38,95,237,56, + 39,87,237,56,38,111,237,56,39,103,183,237, + 82,32,235,33,128,2,183,237,82,209,201,245, + 197,1,52,0,237,120,230,253,237,121,193,241, + 201,245,197,1,52,0,237,120,246,2,237,121, + 193,241,201,33,2,0,57,126,35,102,111,126, + 35,110,103,201,33,0,0,34,102,152,34,96, + 152,34,98,152,33,202,154,34,104,152,237,91, + 104,152,42,226,149,183,237,82,17,0,255,25, + 34,100,152,203,124,40,6,33,0,125,34,100, + 152,42,104,152,35,35,35,229,205,120,139,193, + 201,205,186,149,229,42,40,152,35,35,35,229, + 205,39,144,193,124,230,3,103,221,117,254,221, + 116,255,237,91,42,152,35,35,35,183,237,82, + 32,12,17,5,0,42,42,152,205,171,149,242, + 169,144,42,40,152,229,205,120,139,193,195,198, + 149,237,91,42,152,42,98,152,25,34,98,152, + 19,19,19,42,102,152,25,34,102,152,237,91, + 100,152,33,158,253,25,237,91,102,152,205,171, + 149,242,214,144,33,0,0,34,102,152,62,1, + 50,95,152,205,225,144,195,198,149,58,95,152, + 183,200,237,91,96,152,42,102,152,205,171,149, + 242,5,145,237,91,102,152,33,98,2,25,237, + 91,96,152,205,171,149,250,37,145,237,91,96, + 152,42,102,152,183,237,82,32,7,42,98,152, + 125,180,40,13,237,91,102,152,42,96,152,205, + 171,149,242,58,145,237,91,104,152,42,102,152, + 25,35,35,35,229,205,120,139,193,175,50,95, + 152,201,195,107,139,205,206,149,250,255,243,205, + 225,144,251,58,230,149,183,194,198,149,17,1, + 0,42,98,152,205,171,149,250,198,149,62,1, + 50,230,149,237,91,96,152,42,104,152,25,221, + 117,252,221,116,253,237,91,104,152,42,96,152, + 25,35,35,35,221,117,254,221,116,255,35,35, + 35,229,205,39,144,124,230,3,103,35,35,35, + 221,117,250,221,116,251,235,221,110,252,221,102, + 253,115,35,114,35,54,4,62,1,211,100,211, + 84,195,198,149,33,0,0,34,102,152,34,96, + 152,34,98,152,33,202,154,34,104,152,237,91, + 104,152,42,226,149,183,237,82,17,0,255,25, + 34,100,152,33,109,152,54,0,33,107,152,229, + 205,240,142,193,62,47,50,34,152,62,132,50, + 49,152,205,241,145,205,61,145,58,39,152,60, + 50,39,152,24,241,205,206,149,251,255,33,109, + 152,126,183,202,198,149,110,221,117,251,33,109, + 152,54,0,221,126,251,254,1,40,28,254,3, + 40,101,254,4,202,190,147,254,5,202,147,147, + 254,8,40,87,33,107,152,229,205,240,142,195, + 198,149,58,201,154,183,32,21,33,111,152,126, + 50,229,149,205,52,144,33,110,152,110,38,0, + 229,205,11,142,193,237,91,96,152,42,104,152, + 25,221,117,254,221,116,255,35,35,54,2,17, + 2,0,43,43,115,35,114,58,44,152,35,35, + 119,58,228,149,35,119,62,1,211,100,211,84, + 62,1,50,201,154,24,169,205,153,142,58,231, + 149,183,40,250,175,50,231,149,33,110,152,126, + 254,255,40,91,58,233,149,230,63,183,40,83, + 94,22,0,33,234,149,25,126,183,40,13,33, + 110,152,94,33,234,150,25,126,254,3,32,36, + 205,81,148,125,180,33,110,152,94,22,0,40, + 17,33,234,149,25,54,0,33,107,152,229,205, + 240,142,193,195,198,149,33,234,150,25,54,0, + 33,110,152,94,22,0,33,234,149,25,126,50, + 49,152,254,132,32,37,62,47,50,34,152,42, + 107,152,229,33,110,152,229,205,174,140,193,193, + 125,180,33,110,152,94,22,0,33,234,150,202, + 117,147,25,52,195,120,147,58,49,152,254,140, + 32,7,62,1,50,34,152,24,210,62,32,50, + 106,152,24,19,58,49,152,95,58,106,152,163, + 183,58,106,152,32,11,203,63,50,106,152,58, + 106,152,183,32,231,254,2,40,51,254,4,40, + 38,254,8,40,26,254,16,40,13,254,32,32, + 158,62,165,50,49,152,62,69,24,190,62,164, + 50,49,152,62,70,24,181,62,163,50,49,152, + 175,24,173,62,162,50,49,152,62,1,24,164, + 62,161,50,49,152,62,3,24,155,25,54,0, + 221,126,251,254,8,40,7,58,230,149,183,202, + 32,146,33,107,152,229,205,240,142,193,211,84, + 195,198,149,237,91,96,152,42,104,152,25,221, + 117,254,221,116,255,35,35,54,6,17,2,0, + 43,43,115,35,114,58,228,149,35,35,119,58, + 233,149,35,119,205,146,142,195,32,146,237,91, + 96,152,42,104,152,25,229,205,160,142,193,58, + 231,149,183,40,250,175,50,231,149,243,237,91, + 96,152,42,104,152,25,221,117,254,221,116,255, + 78,35,70,221,113,252,221,112,253,89,80,42, + 98,152,183,237,82,34,98,152,203,124,40,19, + 33,0,0,34,98,152,34,102,152,34,96,152, + 62,1,50,95,152,24,40,221,94,252,221,86, + 253,19,19,19,42,96,152,25,34,96,152,237, + 91,100,152,33,158,253,25,237,91,96,152,205, + 171,149,242,55,148,33,0,0,34,96,152,175, + 50,230,149,251,195,32,146,245,62,1,50,231, + 149,62,16,237,57,0,211,80,241,251,237,77, + 201,205,186,149,229,229,33,0,0,34,37,152, + 33,110,152,126,50,234,151,58,44,152,33,235, + 151,119,221,54,253,0,221,54,254,0,195,230, + 148,33,236,151,54,175,33,3,0,229,33,234, + 151,229,205,174,140,193,193,33,236,151,126,254, + 255,40,74,33,245,151,110,221,117,255,33,249, + 151,126,221,166,255,221,119,255,33,253,151,126, + 221,166,255,221,119,255,58,232,149,95,221,126, + 255,163,221,119,255,183,40,15,230,191,33,110, + 152,94,22,0,33,234,149,25,119,24,12,33, + 110,152,94,22,0,33,234,149,25,54,132,33, + 0,0,195,198,149,221,110,253,221,102,254,35, + 221,117,253,221,116,254,17,32,0,221,110,253, + 221,102,254,205,171,149,250,117,148,58,233,149, + 203,87,40,84,33,1,0,34,37,152,221,54, + 253,0,221,54,254,0,24,53,33,236,151,54, + 175,33,3,0,229,33,234,151,229,205,174,140, + 193,193,33,236,151,126,254,255,40,14,33,110, + 152,94,22,0,33,234,149,25,54,140,24,159, + 221,110,253,221,102,254,35,221,117,253,221,116, + 254,17,32,0,221,110,253,221,102,254,205,171, + 149,250,12,149,33,2,0,34,37,152,221,54, + 253,0,221,54,254,0,24,54,33,236,151,54, + 175,33,3,0,229,33,234,151,229,205,174,140, + 193,193,33,236,151,126,254,255,40,15,33,110, + 152,94,22,0,33,234,149,25,54,132,195,211, + 148,221,110,253,221,102,254,35,221,117,253,221, + 116,254,17,32,0,221,110,253,221,102,254,205, + 171,149,250,96,149,33,1,0,195,198,149,124, + 170,250,179,149,237,82,201,124,230,128,237,82, + 60,201,225,253,229,221,229,221,33,0,0,221, + 57,233,221,249,221,225,253,225,201,233,225,253, + 229,221,229,221,33,0,0,221,57,94,35,86, + 35,235,57,249,235,233,0,0,0,0,0,0, + 62,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 175,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,133,1,0,0,0,63, + 255,255,255,255,0,0,0,63,0,0,0,0, + 0,0,0,0,0,0,0,24,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0 + } ; + +#endif diff --git a/drivers/net/appletalk/cops_ltdrv.h b/drivers/net/appletalk/cops_ltdrv.h new file mode 100644 index 000000000000..c699b1ad31da --- /dev/null +++ b/drivers/net/appletalk/cops_ltdrv.h @@ -0,0 +1,241 @@ +/* + * The firmware this driver downloads into the Localtalk card is a + * separate program and is not GPL'd source code, even though the Linux + * side driver and the routine that loads this data into the card are. + * + * It is taken from the COPS SDK and is under the following license + * + * This material is licensed to you strictly for use in conjunction with + * the use of COPS LocalTalk adapters. + * There is no charge for this SDK. And no waranty express or implied + * about its fitness for any purpose. However, we will cheerefully + * refund every penny you paid for this SDK... + * Regards, + * + * Thomas F. Divine + * Chief Scientist + */ + + +/* cops_ltdrv.h: LocalTalk driver firmware dump for Linux. + * + * Authors: + * - Jay Schulist + */ + + +#ifdef CONFIG_COPS_TANGENT + +static const unsigned char ltdrv_code[] = { + 58,3,0,50,148,10,33,143,15,62,85,119, + 190,32,9,62,170,119,190,32,3,35,24,241, + 34,146,10,249,17,150,10,33,143,15,183,237, + 82,77,68,11,107,98,19,54,0,237,176,62, + 16,237,57,51,62,0,237,57,50,237,57,54, + 62,12,237,57,49,62,195,33,39,2,50,56, + 0,34,57,0,237,86,205,30,2,251,205,60, + 10,24,169,67,111,112,121,114,105,103,104,116, + 32,40,99,41,32,49,57,56,56,45,49,57, + 57,50,44,32,80,114,105,110,116,105,110,103, + 32,67,111,109,109,117,110,105,99,97,116,105, + 111,110,115,32,65,115,115,111,99,105,97,116, + 101,115,44,32,73,110,99,46,65,108,108,32, + 114,105,103,104,116,115,32,114,101,115,101,114, + 118,101,100,46,32,32,4,4,22,40,255,60, + 4,96,10,224,6,0,7,126,2,64,11,246, + 12,6,13,0,14,193,15,0,5,96,3,192, + 1,0,9,8,62,3,211,82,62,192,211,82, + 201,62,3,211,82,62,213,211,82,201,62,5, + 211,82,62,224,211,82,201,62,5,211,82,62, + 224,211,82,201,62,5,211,82,62,96,211,82, + 201,6,28,33,180,1,14,82,237,163,194,4, + 2,33,39,2,34,64,0,58,3,0,230,1, + 192,62,11,237,121,62,118,237,121,201,33,182, + 10,54,132,205,253,1,201,245,197,213,229,42, + 150,10,14,83,17,98,2,67,20,237,162,58, + 179,1,95,219,82,230,1,32,6,29,32,247, + 195,17,3,62,1,211,82,219,82,95,230,160, + 32,10,237,162,32,225,21,32,222,195,15,3, + 237,162,123,230,96,194,21,3,62,48,211,82, + 62,1,211,82,175,211,82,237,91,150,10,43, + 55,237,82,218,19,3,34,152,10,98,107,58, + 154,10,190,32,81,62,1,50,158,10,35,35, + 62,132,190,32,44,54,133,43,70,58,154,10, + 119,43,112,17,3,0,205,137,3,62,16,211, + 82,62,56,211,82,205,217,1,42,150,10,14, + 83,17,98,2,67,20,58,178,1,95,195,59, + 2,62,129,190,194,227,2,54,130,43,70,58, + 154,10,119,43,112,17,3,0,205,137,3,195, + 254,2,35,35,126,254,132,194,227,2,205,61, + 3,24,20,62,128,166,194,222,2,221,229,221, + 33,175,10,205,93,6,205,144,7,221,225,225, + 209,193,241,251,237,77,221,229,221,33,159,10, + 205,93,6,221,225,205,61,3,195,247,2,24, + 237,24,235,24,233,230,64,40,2,24,227,24, + 225,175,50,179,10,205,208,1,201,197,33,4, + 0,57,126,35,102,111,205,51,3,193,201,62, + 1,50,179,10,34,150,10,54,0,58,179,10, + 183,200,62,14,211,82,62,193,211,82,62,10, + 211,82,62,224,211,82,62,6,211,82,58,154, + 10,211,82,62,16,211,82,62,56,211,82,62, + 48,211,82,219,82,230,1,40,4,219,83,24, + 242,62,14,211,82,62,33,211,82,62,1,211, + 82,62,9,211,82,62,32,211,82,205,217,1, + 201,14,83,205,208,1,24,23,14,83,205,208, + 1,205,226,1,58,174,1,61,32,253,205,244, + 1,58,174,1,61,32,253,205,226,1,58,175, + 1,61,32,253,62,5,211,82,62,233,211,82, + 62,128,211,82,58,176,1,61,32,253,237,163, + 27,62,192,211,82,219,82,230,4,40,250,237, + 163,27,122,179,32,243,219,82,230,4,40,250, + 58,178,1,71,219,82,230,4,40,3,5,32, + 247,219,82,230,4,40,250,205,235,1,58,177, + 1,61,32,253,205,244,1,201,229,213,35,35, + 126,230,128,194,145,4,43,58,154,10,119,43, + 70,33,181,10,119,43,112,17,3,0,243,62, + 10,211,82,219,82,230,128,202,41,4,209,225, + 62,1,55,251,201,205,144,3,58,180,10,254, + 255,202,127,4,205,217,1,58,178,1,71,219, + 82,230,1,32,6,5,32,247,195,173,4,219, + 83,71,58,154,10,184,194,173,4,58,178,1, + 71,219,82,230,1,32,6,5,32,247,195,173, + 4,219,83,58,178,1,71,219,82,230,1,32, + 6,5,32,247,195,173,4,219,83,254,133,194, + 173,4,58,179,1,24,4,58,179,1,135,61, + 32,253,209,225,205,137,3,205,61,3,183,251, + 201,209,225,243,62,10,211,82,219,82,230,128, + 202,164,4,62,1,55,251,201,205,144,3,205, + 61,3,183,251,201,209,225,62,2,55,251,201, + 243,62,14,211,82,62,33,211,82,251,201,33, + 4,0,57,94,35,86,33,2,0,57,126,35, + 102,111,221,229,34,193,10,237,83,195,10,221, + 33,171,10,205,93,6,58,185,10,50,186,10, + 58,184,10,135,50,184,10,205,112,6,254,3, + 56,16,58,185,10,135,60,230,15,50,185,10, + 175,50,184,10,24,23,58,183,10,205,112,6, + 254,3,48,13,58,185,10,203,63,50,185,10, + 62,255,50,183,10,58,185,10,50,186,10,58, + 183,10,135,50,183,10,62,32,50,187,10,50, + 188,10,6,255,219,82,230,16,32,3,5,32, + 247,205,180,4,6,40,219,82,230,16,40,3, + 5,32,247,62,10,211,82,219,82,230,128,194, + 46,5,219,82,230,16,40,214,237,95,71,58, + 186,10,160,230,15,40,32,71,14,10,62,10, + 211,82,219,82,230,128,202,119,5,205,180,4, + 195,156,5,219,82,230,16,202,156,5,13,32, + 229,16,225,42,193,10,237,91,195,10,205,252, + 3,48,7,61,202,156,5,195,197,5,221,225, + 33,0,0,201,221,33,163,10,205,93,6,58, + 188,10,61,50,188,10,40,19,58,186,10,246, + 1,50,186,10,58,183,10,246,1,50,183,10, + 195,46,5,221,225,33,1,0,201,221,33,167, + 10,205,93,6,58,184,10,246,1,50,184,10, + 58,186,10,135,246,1,50,186,10,58,187,10, + 61,50,187,10,194,46,5,221,225,33,2,0, + 201,221,229,33,0,0,57,17,4,0,25,126, + 50,154,10,230,128,50,189,10,58,189,10,183, + 40,6,221,33,88,2,24,4,221,33,150,0, + 58,154,10,183,40,49,60,40,46,61,33,190, + 10,119,35,119,35,54,129,175,50,158,10,221, + 43,221,229,225,124,181,40,42,33,190,10,17, + 3,0,205,206,4,17,232,3,27,123,178,32, + 251,58,158,10,183,40,224,58,154,10,71,62, + 7,128,230,127,71,58,189,10,176,50,154,10, + 24,166,221,225,201,183,221,52,0,192,221,52, + 1,192,221,52,2,192,221,52,3,192,55,201, + 6,8,14,0,31,48,1,12,16,250,121,201, + 33,2,0,57,94,35,86,35,78,35,70,35, + 126,35,102,105,79,120,68,103,237,176,201,33, + 2,0,57,126,35,102,111,62,17,237,57,48, + 125,237,57,40,124,237,57,41,62,0,237,57, + 42,62,64,237,57,43,62,0,237,57,44,33, + 128,2,125,237,57,46,124,237,57,47,62,145, + 237,57,48,211,68,58,149,10,211,66,201,33, + 2,0,57,126,35,102,111,62,33,237,57,48, + 62,64,237,57,32,62,0,237,57,33,237,57, + 34,125,237,57,35,124,237,57,36,62,0,237, + 57,37,33,128,2,125,237,57,38,124,237,57, + 39,62,97,237,57,48,211,67,58,149,10,211, + 66,201,237,56,46,95,237,56,47,87,237,56, + 46,111,237,56,47,103,183,237,82,32,235,33, + 128,2,183,237,82,201,237,56,38,95,237,56, + 39,87,237,56,38,111,237,56,39,103,183,237, + 82,32,235,33,128,2,183,237,82,201,205,106, + 10,221,110,6,221,102,7,126,35,110,103,195, + 118,10,205,106,10,33,0,0,34,205,10,34, + 198,10,34,200,10,33,143,15,34,207,10,237, + 91,207,10,42,146,10,183,237,82,17,0,255, + 25,34,203,10,203,124,40,6,33,0,125,34, + 203,10,42,207,10,229,205,37,3,195,118,10, + 205,106,10,229,42,150,10,35,35,35,229,205, + 70,7,193,124,230,3,103,221,117,254,221,116, + 255,237,91,152,10,35,35,35,183,237,82,32, + 12,17,5,0,42,152,10,205,91,10,242,203, + 7,42,150,10,229,205,37,3,195,118,10,237, + 91,152,10,42,200,10,25,34,200,10,42,205, + 10,25,34,205,10,237,91,203,10,33,158,253, + 25,237,91,205,10,205,91,10,242,245,7,33, + 0,0,34,205,10,62,1,50,197,10,205,5, + 8,33,0,0,57,249,195,118,10,205,106,10, + 58,197,10,183,202,118,10,237,91,198,10,42, + 205,10,205,91,10,242,46,8,237,91,205,10, + 33,98,2,25,237,91,198,10,205,91,10,250, + 78,8,237,91,198,10,42,205,10,183,237,82, + 32,7,42,200,10,125,180,40,13,237,91,205, + 10,42,198,10,205,91,10,242,97,8,237,91, + 207,10,42,205,10,25,229,205,37,3,175,50, + 197,10,195,118,10,205,29,3,33,0,0,57, + 249,195,118,10,205,106,10,58,202,10,183,40, + 22,205,14,7,237,91,209,10,19,19,19,205, + 91,10,242,139,8,33,1,0,195,118,10,33, + 0,0,195,118,10,205,126,10,252,255,205,108, + 8,125,180,194,118,10,237,91,200,10,33,0, + 0,205,91,10,242,118,10,237,91,207,10,42, + 198,10,25,221,117,254,221,116,255,35,35,35, + 229,205,70,7,193,124,230,3,103,35,35,35, + 221,117,252,221,116,253,229,221,110,254,221,102, + 255,229,33,212,10,229,205,124,6,193,193,221, + 110,252,221,102,253,34,209,10,33,211,10,54, + 4,33,209,10,227,205,147,6,193,62,1,50, + 202,10,243,221,94,252,221,86,253,42,200,10, + 183,237,82,34,200,10,203,124,40,17,33,0, + 0,34,200,10,34,205,10,34,198,10,50,197, + 10,24,37,221,94,252,221,86,253,42,198,10, + 25,34,198,10,237,91,203,10,33,158,253,25, + 237,91,198,10,205,91,10,242,68,9,33,0, + 0,34,198,10,205,5,8,33,0,0,57,249, + 251,195,118,10,205,106,10,33,49,13,126,183, + 40,16,205,42,7,237,91,47,13,19,19,19, + 205,91,10,242,117,9,58,142,15,198,1,50, + 142,15,195,118,10,33,49,13,126,254,1,40, + 25,254,3,202,7,10,254,5,202,21,10,33, + 49,13,54,0,33,47,13,229,205,207,6,195, + 118,10,58,141,15,183,32,72,33,51,13,126, + 50,149,10,205,86,7,33,50,13,126,230,127, + 183,32,40,58,142,15,230,127,50,142,15,183, + 32,5,198,1,50,142,15,33,50,13,126,111, + 23,159,103,203,125,58,142,15,40,5,198,128, + 50,142,15,33,50,13,119,33,50,13,126,111, + 23,159,103,229,205,237,5,193,33,211,10,54, + 2,33,2,0,34,209,10,58,154,10,33,212, + 10,119,58,148,10,33,213,10,119,33,209,10, + 229,205,147,6,193,24,128,42,47,13,229,33, + 50,13,229,205,191,4,193,24,239,33,211,10, + 54,6,33,3,0,34,209,10,58,154,10,33, + 212,10,119,58,148,10,33,213,10,119,33,214, + 10,54,5,33,209,10,229,205,147,6,24,200, + 205,106,10,33,49,13,54,0,33,47,13,229, + 205,207,6,33,209,10,227,205,147,6,193,205, + 80,9,205,145,8,24,248,124,170,250,99,10, + 237,82,201,124,230,128,237,82,60,201,225,253, + 229,221,229,221,33,0,0,221,57,233,221,249, + 221,225,253,225,201,233,225,253,229,221,229,221, + 33,0,0,221,57,94,35,86,35,235,57,249, + 235,233,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0 + } ; + +#endif diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c new file mode 100644 index 000000000000..10d0dba572c2 --- /dev/null +++ b/drivers/net/appletalk/ipddp.c @@ -0,0 +1,335 @@ +/* + * ipddp.c: IP to Appletalk-IP Encapsulation driver for Linux + * Appletalk-IP to IP Decapsulation driver for Linux + * + * Authors: + * - DDP-IP Encap by: Bradford W. Johnson + * - DDP-IP Decap by: Jay Schulist + * + * Derived from: + * - Almost all code already existed in net/appletalk/ddp.c I just + * moved/reorginized it into a driver file. Original IP-over-DDP code + * was done by Bradford W. Johnson + * - skeleton.c: A network driver outline for linux. + * Written 1993-94 by Donald Becker. + * - dummy.c: A dummy net driver. By Nick Holloway. + * - MacGate: A user space Daemon for Appletalk-IP Decap for + * Linux by Jay Schulist + * + * Copyright 1993 United States Government as represented by the + * Director, National Security Agency. + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ipddp.h" /* Our stuff */ + +static const char version[] = KERN_INFO "ipddp.c:v0.01 8/28/97 Bradford W. Johnson \n"; + +static struct ipddp_route *ipddp_route_list; +static DEFINE_SPINLOCK(ipddp_route_lock); + +#ifdef CONFIG_IPDDP_ENCAP +static int ipddp_mode = IPDDP_ENCAP; +#else +static int ipddp_mode = IPDDP_DECAP; +#endif + +/* Index to functions, as function prototypes. */ +static netdev_tx_t ipddp_xmit(struct sk_buff *skb, + struct net_device *dev); +static int ipddp_create(struct ipddp_route *new_rt); +static int ipddp_delete(struct ipddp_route *rt); +static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt); +static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); + +static const struct net_device_ops ipddp_netdev_ops = { + .ndo_start_xmit = ipddp_xmit, + .ndo_do_ioctl = ipddp_ioctl, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + +static struct net_device * __init ipddp_init(void) +{ + static unsigned version_printed; + struct net_device *dev; + int err; + + dev = alloc_etherdev(0); + if (!dev) + return ERR_PTR(-ENOMEM); + + dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; + strcpy(dev->name, "ipddp%d"); + + if (version_printed++ == 0) + printk(version); + + /* Initialize the device structure. */ + dev->netdev_ops = &ipddp_netdev_ops; + + dev->type = ARPHRD_IPDDP; /* IP over DDP tunnel */ + dev->mtu = 585; + dev->flags |= IFF_NOARP; + + /* + * The worst case header we will need is currently a + * ethernet header (14 bytes) and a ddp header (sizeof ddpehdr+1) + * We send over SNAP so that takes another 8 bytes. + */ + dev->hard_header_len = 14+8+sizeof(struct ddpehdr)+1; + + err = register_netdev(dev); + if (err) { + free_netdev(dev); + return ERR_PTR(err); + } + + /* Let the user now what mode we are in */ + if(ipddp_mode == IPDDP_ENCAP) + printk("%s: Appletalk-IP Encap. mode by Bradford W. Johnson \n", + dev->name); + if(ipddp_mode == IPDDP_DECAP) + printk("%s: Appletalk-IP Decap. mode by Jay Schulist \n", + dev->name); + + return dev; +} + + +/* + * Transmit LLAP/ELAP frame using aarp_send_ddp. + */ +static netdev_tx_t ipddp_xmit(struct sk_buff *skb, struct net_device *dev) +{ + __be32 paddr = skb_rtable(skb)->rt_gateway; + struct ddpehdr *ddp; + struct ipddp_route *rt; + struct atalk_addr *our_addr; + + spin_lock(&ipddp_route_lock); + + /* + * Find appropriate route to use, based only on IP number. + */ + for(rt = ipddp_route_list; rt != NULL; rt = rt->next) + { + if(rt->ip == paddr) + break; + } + if(rt == NULL) { + spin_unlock(&ipddp_route_lock); + return NETDEV_TX_OK; + } + + our_addr = atalk_find_dev_addr(rt->dev); + + if(ipddp_mode == IPDDP_DECAP) + /* + * Pull off the excess room that should not be there. + * This is due to a hard-header problem. This is the + * quick fix for now though, till it breaks. + */ + skb_pull(skb, 35-(sizeof(struct ddpehdr)+1)); + + /* Create the Extended DDP header */ + ddp = (struct ddpehdr *)skb->data; + ddp->deh_len_hops = htons(skb->len + (1<<10)); + ddp->deh_sum = 0; + + /* + * For Localtalk we need aarp_send_ddp to strip the + * long DDP header and place a shot DDP header on it. + */ + if(rt->dev->type == ARPHRD_LOCALTLK) + { + ddp->deh_dnet = 0; /* FIXME more hops?? */ + ddp->deh_snet = 0; + } + else + { + ddp->deh_dnet = rt->at.s_net; /* FIXME more hops?? */ + ddp->deh_snet = our_addr->s_net; + } + ddp->deh_dnode = rt->at.s_node; + ddp->deh_snode = our_addr->s_node; + ddp->deh_dport = 72; + ddp->deh_sport = 72; + + *((__u8 *)(ddp+1)) = 22; /* ddp type = IP */ + + skb->protocol = htons(ETH_P_ATALK); /* Protocol has changed */ + + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + + aarp_send_ddp(rt->dev, skb, &rt->at, NULL); + + spin_unlock(&ipddp_route_lock); + + return NETDEV_TX_OK; +} + +/* + * Create a routing entry. We first verify that the + * record does not already exist. If it does we return -EEXIST + */ +static int ipddp_create(struct ipddp_route *new_rt) +{ + struct ipddp_route *rt = kmalloc(sizeof(*rt), GFP_KERNEL); + + if (rt == NULL) + return -ENOMEM; + + rt->ip = new_rt->ip; + rt->at = new_rt->at; + rt->next = NULL; + if ((rt->dev = atrtr_get_dev(&rt->at)) == NULL) { + kfree(rt); + return -ENETUNREACH; + } + + spin_lock_bh(&ipddp_route_lock); + if (__ipddp_find_route(rt)) { + spin_unlock_bh(&ipddp_route_lock); + kfree(rt); + return -EEXIST; + } + + rt->next = ipddp_route_list; + ipddp_route_list = rt; + + spin_unlock_bh(&ipddp_route_lock); + + return 0; +} + +/* + * Delete a route, we only delete a FULL match. + * If route does not exist we return -ENOENT. + */ +static int ipddp_delete(struct ipddp_route *rt) +{ + struct ipddp_route **r = &ipddp_route_list; + struct ipddp_route *tmp; + + spin_lock_bh(&ipddp_route_lock); + while((tmp = *r) != NULL) + { + if(tmp->ip == rt->ip && + tmp->at.s_net == rt->at.s_net && + tmp->at.s_node == rt->at.s_node) + { + *r = tmp->next; + spin_unlock_bh(&ipddp_route_lock); + kfree(tmp); + return 0; + } + r = &tmp->next; + } + + spin_unlock_bh(&ipddp_route_lock); + return -ENOENT; +} + +/* + * Find a routing entry, we only return a FULL match + */ +static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt) +{ + struct ipddp_route *f; + + for(f = ipddp_route_list; f != NULL; f = f->next) + { + if(f->ip == rt->ip && + f->at.s_net == rt->at.s_net && + f->at.s_node == rt->at.s_node) + return f; + } + + return NULL; +} + +static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct ipddp_route __user *rt = ifr->ifr_data; + struct ipddp_route rcp, rcp2, *rp; + + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + + if(copy_from_user(&rcp, rt, sizeof(rcp))) + return -EFAULT; + + switch(cmd) + { + case SIOCADDIPDDPRT: + return ipddp_create(&rcp); + + case SIOCFINDIPDDPRT: + spin_lock_bh(&ipddp_route_lock); + rp = __ipddp_find_route(&rcp); + if (rp) + memcpy(&rcp2, rp, sizeof(rcp2)); + spin_unlock_bh(&ipddp_route_lock); + + if (rp) { + if (copy_to_user(rt, &rcp2, + sizeof(struct ipddp_route))) + return -EFAULT; + return 0; + } else + return -ENOENT; + + case SIOCDELIPDDPRT: + return ipddp_delete(&rcp); + + default: + return -EINVAL; + } +} + +static struct net_device *dev_ipddp; + +MODULE_LICENSE("GPL"); +module_param(ipddp_mode, int, 0); + +static int __init ipddp_init_module(void) +{ + dev_ipddp = ipddp_init(); + if (IS_ERR(dev_ipddp)) + return PTR_ERR(dev_ipddp); + return 0; +} + +static void __exit ipddp_cleanup_module(void) +{ + struct ipddp_route *p; + + unregister_netdev(dev_ipddp); + free_netdev(dev_ipddp); + + while (ipddp_route_list) { + p = ipddp_route_list->next; + kfree(ipddp_route_list); + ipddp_route_list = p; + } +} + +module_init(ipddp_init_module); +module_exit(ipddp_cleanup_module); diff --git a/drivers/net/appletalk/ipddp.h b/drivers/net/appletalk/ipddp.h new file mode 100644 index 000000000000..531519da99a3 --- /dev/null +++ b/drivers/net/appletalk/ipddp.h @@ -0,0 +1,27 @@ +/* + * ipddp.h: Header for IP-over-DDP driver for Linux. + */ + +#ifndef __LINUX_IPDDP_H +#define __LINUX_IPDDP_H + +#ifdef __KERNEL__ + +#define SIOCADDIPDDPRT (SIOCDEVPRIVATE) +#define SIOCDELIPDDPRT (SIOCDEVPRIVATE+1) +#define SIOCFINDIPDDPRT (SIOCDEVPRIVATE+2) + +struct ipddp_route +{ + struct net_device *dev; /* Carrier device */ + __be32 ip; /* IP address */ + struct atalk_addr at; /* Gateway appletalk address */ + int flags; + struct ipddp_route *next; +}; + +#define IPDDP_ENCAP 1 +#define IPDDP_DECAP 2 + +#endif /* __KERNEL__ */ +#endif /* __LINUX_IPDDP_H */ diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c new file mode 100644 index 000000000000..e69eead12ec7 --- /dev/null +++ b/drivers/net/appletalk/ltpc.c @@ -0,0 +1,1288 @@ +/*** ltpc.c -- a driver for the LocalTalk PC card. + * + * Copyright (c) 1995,1996 Bradford W. Johnson + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * This is ALPHA code at best. It may not work for you. It may + * damage your equipment. It may damage your relations with other + * users of your network. Use it at your own risk! + * + * Based in part on: + * skeleton.c by Donald Becker + * dummy.c by Nick Holloway and Alan Cox + * loopback.c by Ross Biro, Fred van Kampen, Donald Becker + * the netatalk source code (UMICH) + * lots of work on the card... + * + * I do not have access to the (proprietary) SDK that goes with the card. + * If you do, I don't want to know about it, and you can probably write + * a better driver yourself anyway. This does mean that the pieces that + * talk to the card are guesswork on my part, so use at your own risk! + * + * This is my first try at writing Linux networking code, and is also + * guesswork. Again, use at your own risk! (Although on this part, I'd + * welcome suggestions) + * + * This is a loadable kernel module which seems to work at my site + * consisting of a 1.2.13 linux box running netatalk 1.3.3, and with + * the kernel support from 1.3.3b2 including patches routing.patch + * and ddp.disappears.from.chooser. In order to run it, you will need + * to patch ddp.c and aarp.c in the kernel, but only a little... + * + * I'm fairly confident that while this is arguably badly written, the + * problems that people experience will be "higher level", that is, with + * complications in the netatalk code. The driver itself doesn't do + * anything terribly complicated -- it pretends to be an ether device + * as far as netatalk is concerned, strips the DDP data out of the ether + * frame and builds a LLAP packet to send out the card. In the other + * direction, it receives LLAP frames from the card and builds a fake + * ether packet that it then tosses up to the networking code. You can + * argue (correctly) that this is an ugly way to do things, but it + * requires a minimal amount of fooling with the code in ddp.c and aarp.c. + * + * The card will do a lot more than is used here -- I *think* it has the + * layers up through ATP. Even if you knew how that part works (which I + * don't) it would be a big job to carve up the kernel ddp code to insert + * things at a higher level, and probably a bad idea... + * + * There are a number of other cards that do LocalTalk on the PC. If + * nobody finds any insurmountable (at the netatalk level) problems + * here, this driver should encourage people to put some work into the + * other cards (some of which I gather are still commercially available) + * and also to put hooks for LocalTalk into the official ddp code. + * + * I welcome comments and suggestions. This is my first try at Linux + * networking stuff, and there are probably lots of things that I did + * suboptimally. + * + ***/ + +/*** + * + * $Log: ltpc.c,v $ + * Revision 1.1.2.1 2000/03/01 05:35:07 jgarzik + * at and tr cleanup + * + * Revision 1.8 1997/01/28 05:44:54 bradford + * Clean up for non-module a little. + * Hacked about a bit to clean things up - Alan Cox + * Probably broken it from the origina 1.8 + * + + * 1998/11/09: David Huggins-Daines + * Cleaned up the initialization code to use the standard autoirq methods, + and to probe for things in the standard order of i/o, irq, dma. This + removes the "reset the reset" hack, because I couldn't figure out an + easy way to get the card to trigger an interrupt after it. + * Added support for passing configuration parameters on the kernel command + line and through insmod + * Changed the device name from "ltalk0" to "lt0", both to conform with the + other localtalk driver, and to clear up the inconsistency between the + module and the non-module versions of the driver :-) + * Added a bunch of comments (I was going to make some enums for the state + codes and the register offsets, but I'm still not sure exactly what their + semantics are) + * Don't poll anymore in interrupt-driven mode + * It seems to work as a module now (as of 2.1.127), but I don't think + I'm responsible for that... + + * + * Revision 1.7 1996/12/12 03:42:33 bradford + * DMA alloc cribbed from 3c505.c. + * + * Revision 1.6 1996/12/12 03:18:58 bradford + * Added virt_to_bus; works in 2.1.13. + * + * Revision 1.5 1996/12/12 03:13:22 root + * xmitQel initialization -- think through better though. + * + * Revision 1.4 1996/06/18 14:55:55 root + * Change names to ltpc. Tabs. Took a shot at dma alloc, + * although more needs to be done eventually. + * + * Revision 1.3 1996/05/22 14:59:39 root + * Change dev->open, dev->close to track dummy.c in 1.99.(around 7) + * + * Revision 1.2 1996/05/22 14:58:24 root + * Change tabs mostly. + * + * Revision 1.1 1996/04/23 04:45:09 root + * Initial revision + * + * Revision 0.16 1996/03/05 15:59:56 root + * Change ARPHRD_LOCALTLK definition to the "real" one. + * + * Revision 0.15 1996/03/05 06:28:30 root + * Changes for kernel 1.3.70. Still need a few patches to kernel, but + * it's getting closer. + * + * Revision 0.14 1996/02/25 17:38:32 root + * More cleanups. Removed query to card on get_stats. + * + * Revision 0.13 1996/02/21 16:27:40 root + * Refix debug_print_skb. Fix mac.raw gotcha that appeared in 1.3.65. + * Clean up receive code a little. + * + * Revision 0.12 1996/02/19 16:34:53 root + * Fix debug_print_skb. Kludge outgoing snet to 0 when using startup + * range. Change debug to mask: 1 for verbose, 2 for higher level stuff + * including packet printing, 4 for lower level (card i/o) stuff. + * + * Revision 0.11 1996/02/12 15:53:38 root + * Added router sends (requires new aarp.c patch) + * + * Revision 0.10 1996/02/11 00:19:35 root + * Change source LTALK_LOGGING debug switch to insmod ... debug=2. + * + * Revision 0.9 1996/02/10 23:59:35 root + * Fixed those fixes for 1.2 -- DANGER! The at.h that comes with netatalk + * has a *different* definition of struct sockaddr_at than the Linux kernel + * does. This is an "insidious and invidious" bug... + * (Actually the preceding comment is false -- it's the atalk.h in the + * ancient atalk-0.06 that's the problem) + * + * Revision 0.8 1996/02/10 19:09:00 root + * Merge 1.3 changes. Tested OK under 1.3.60. + * + * Revision 0.7 1996/02/10 17:56:56 root + * Added debug=1 parameter on insmod for debugging prints. Tried + * to fix timer unload on rmmod, but I don't think that's the problem. + * + * Revision 0.6 1995/12/31 19:01:09 root + * Clean up rmmod, irq comments per feedback from Corin Anderson (Thanks Corey!) + * Clean up initial probing -- sometimes the card wakes up latched in reset. + * + * Revision 0.5 1995/12/22 06:03:44 root + * Added comments in front and cleaned up a bit. + * This version sent out to people. + * + * Revision 0.4 1995/12/18 03:46:44 root + * Return shortDDP to longDDP fake to 0/0. Added command structs. + * + ***/ + +/* ltpc jumpers are: +* +* Interrupts -- set at most one. If none are set, the driver uses +* polled mode. Because the card was developed in the XT era, the +* original documentation refers to IRQ2. Since you'll be running +* this on an AT (or later) class machine, that really means IRQ9. +* +* SW1 IRQ 4 +* SW2 IRQ 3 +* SW3 IRQ 9 (2 in original card documentation only applies to XT) +* +* +* DMA -- choose DMA 1 or 3, and set both corresponding switches. +* +* SW4 DMA 3 +* SW5 DMA 1 +* SW6 DMA 3 +* SW7 DMA 1 +* +* +* I/O address -- choose one. +* +* SW8 220 / 240 +*/ + +/* To have some stuff logged, do +* insmod ltpc.o debug=1 +* +* For a whole bunch of stuff, use higher numbers. +* +* The default is 0, i.e. no messages except for the probe results. +*/ + +/* insmod-tweakable variables */ +static int debug; +#define DEBUG_VERBOSE 1 +#define DEBUG_UPPER 2 +#define DEBUG_LOWER 4 + +static int io; +static int irq; +static int dma; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* our stuff */ +#include "ltpc.h" + +static DEFINE_SPINLOCK(txqueue_lock); +static DEFINE_SPINLOCK(mbox_lock); + +/* function prototypes */ +static int do_read(struct net_device *dev, void *cbuf, int cbuflen, + void *dbuf, int dbuflen); +static int sendup_buffer (struct net_device *dev); + +/* Dma Memory related stuff, cribbed directly from 3c505.c */ + +static unsigned long dma_mem_alloc(int size) +{ + int order = get_order(size); + + return __get_dma_pages(GFP_KERNEL, order); +} + +/* DMA data buffer, DMA command buffer */ +static unsigned char *ltdmabuf; +static unsigned char *ltdmacbuf; + +/* private struct, holds our appletalk address */ + +struct ltpc_private +{ + struct atalk_addr my_addr; +}; + +/* transmit queue element struct */ + +struct xmitQel { + struct xmitQel *next; + /* command buffer */ + unsigned char *cbuf; + short cbuflen; + /* data buffer */ + unsigned char *dbuf; + short dbuflen; + unsigned char QWrite; /* read or write data */ + unsigned char mailbox; +}; + +/* the transmit queue itself */ + +static struct xmitQel *xmQhd, *xmQtl; + +static void enQ(struct xmitQel *qel) +{ + unsigned long flags; + qel->next = NULL; + + spin_lock_irqsave(&txqueue_lock, flags); + if (xmQtl) { + xmQtl->next = qel; + } else { + xmQhd = qel; + } + xmQtl = qel; + spin_unlock_irqrestore(&txqueue_lock, flags); + + if (debug & DEBUG_LOWER) + printk("enqueued a 0x%02x command\n",qel->cbuf[0]); +} + +static struct xmitQel *deQ(void) +{ + unsigned long flags; + int i; + struct xmitQel *qel=NULL; + + spin_lock_irqsave(&txqueue_lock, flags); + if (xmQhd) { + qel = xmQhd; + xmQhd = qel->next; + if(!xmQhd) xmQtl = NULL; + } + spin_unlock_irqrestore(&txqueue_lock, flags); + + if ((debug & DEBUG_LOWER) && qel) { + int n; + printk(KERN_DEBUG "ltpc: dequeued command "); + n = qel->cbuflen; + if (n>100) n=100; + for(i=0;icbuf[i]); + printk("\n"); + } + + return qel; +} + +/* and... the queue elements we'll be using */ +static struct xmitQel qels[16]; + +/* and their corresponding mailboxes */ +static unsigned char mailbox[16]; +static unsigned char mboxinuse[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +static int wait_timeout(struct net_device *dev, int c) +{ + /* returns true if it stayed c */ + /* this uses base+6, but it's ok */ + int i; + + /* twenty second or so total */ + + for(i=0;i<200000;i++) { + if ( c != inb_p(dev->base_addr+6) ) return 0; + udelay(100); + } + return 1; /* timed out */ +} + +/* get the first free mailbox */ + +static int getmbox(void) +{ + unsigned long flags; + int i; + + spin_lock_irqsave(&mbox_lock, flags); + for(i=1;i<16;i++) if(!mboxinuse[i]) { + mboxinuse[i]=1; + spin_unlock_irqrestore(&mbox_lock, flags); + return i; + } + spin_unlock_irqrestore(&mbox_lock, flags); + return 0; +} + +/* read a command from the card */ +static void handlefc(struct net_device *dev) +{ + /* called *only* from idle, non-reentrant */ + int dma = dev->dma; + int base = dev->base_addr; + unsigned long flags; + + + flags=claim_dma_lock(); + disable_dma(dma); + clear_dma_ff(dma); + set_dma_mode(dma,DMA_MODE_READ); + set_dma_addr(dma,virt_to_bus(ltdmacbuf)); + set_dma_count(dma,50); + enable_dma(dma); + release_dma_lock(flags); + + inb_p(base+3); + inb_p(base+2); + + if ( wait_timeout(dev,0xfc) ) printk("timed out in handlefc\n"); +} + +/* read data from the card */ +static void handlefd(struct net_device *dev) +{ + int dma = dev->dma; + int base = dev->base_addr; + unsigned long flags; + + flags=claim_dma_lock(); + disable_dma(dma); + clear_dma_ff(dma); + set_dma_mode(dma,DMA_MODE_READ); + set_dma_addr(dma,virt_to_bus(ltdmabuf)); + set_dma_count(dma,800); + enable_dma(dma); + release_dma_lock(flags); + + inb_p(base+3); + inb_p(base+2); + + if ( wait_timeout(dev,0xfd) ) printk("timed out in handlefd\n"); + sendup_buffer(dev); +} + +static void handlewrite(struct net_device *dev) +{ + /* called *only* from idle, non-reentrant */ + /* on entry, 0xfb and ltdmabuf holds data */ + int dma = dev->dma; + int base = dev->base_addr; + unsigned long flags; + + flags=claim_dma_lock(); + disable_dma(dma); + clear_dma_ff(dma); + set_dma_mode(dma,DMA_MODE_WRITE); + set_dma_addr(dma,virt_to_bus(ltdmabuf)); + set_dma_count(dma,800); + enable_dma(dma); + release_dma_lock(flags); + + inb_p(base+3); + inb_p(base+2); + + if ( wait_timeout(dev,0xfb) ) { + flags=claim_dma_lock(); + printk("timed out in handlewrite, dma res %d\n", + get_dma_residue(dev->dma) ); + release_dma_lock(flags); + } +} + +static void handleread(struct net_device *dev) +{ + /* on entry, 0xfb */ + /* on exit, ltdmabuf holds data */ + int dma = dev->dma; + int base = dev->base_addr; + unsigned long flags; + + + flags=claim_dma_lock(); + disable_dma(dma); + clear_dma_ff(dma); + set_dma_mode(dma,DMA_MODE_READ); + set_dma_addr(dma,virt_to_bus(ltdmabuf)); + set_dma_count(dma,800); + enable_dma(dma); + release_dma_lock(flags); + + inb_p(base+3); + inb_p(base+2); + if ( wait_timeout(dev,0xfb) ) printk("timed out in handleread\n"); +} + +static void handlecommand(struct net_device *dev) +{ + /* on entry, 0xfa and ltdmacbuf holds command */ + int dma = dev->dma; + int base = dev->base_addr; + unsigned long flags; + + flags=claim_dma_lock(); + disable_dma(dma); + clear_dma_ff(dma); + set_dma_mode(dma,DMA_MODE_WRITE); + set_dma_addr(dma,virt_to_bus(ltdmacbuf)); + set_dma_count(dma,50); + enable_dma(dma); + release_dma_lock(flags); + inb_p(base+3); + inb_p(base+2); + if ( wait_timeout(dev,0xfa) ) printk("timed out in handlecommand\n"); +} + +/* ready made command for getting the result from the card */ +static unsigned char rescbuf[2] = {LT_GETRESULT,0}; +static unsigned char resdbuf[2]; + +static int QInIdle; + +/* idle expects to be called with the IRQ line high -- either because of + * an interrupt, or because the line is tri-stated + */ + +static void idle(struct net_device *dev) +{ + unsigned long flags; + int state; + /* FIXME This is initialized to shut the warning up, but I need to + * think this through again. + */ + struct xmitQel *q = NULL; + int oops; + int i; + int base = dev->base_addr; + + spin_lock_irqsave(&txqueue_lock, flags); + if(QInIdle) { + spin_unlock_irqrestore(&txqueue_lock, flags); + return; + } + QInIdle = 1; + spin_unlock_irqrestore(&txqueue_lock, flags); + + /* this tri-states the IRQ line */ + (void) inb_p(base+6); + + oops = 100; + +loop: + if (0>oops--) { + printk("idle: looped too many times\n"); + goto done; + } + + state = inb_p(base+6); + if (state != inb_p(base+6)) goto loop; + + switch(state) { + case 0xfc: + /* incoming command */ + if (debug & DEBUG_LOWER) printk("idle: fc\n"); + handlefc(dev); + break; + case 0xfd: + /* incoming data */ + if(debug & DEBUG_LOWER) printk("idle: fd\n"); + handlefd(dev); + break; + case 0xf9: + /* result ready */ + if (debug & DEBUG_LOWER) printk("idle: f9\n"); + if(!mboxinuse[0]) { + mboxinuse[0] = 1; + qels[0].cbuf = rescbuf; + qels[0].cbuflen = 2; + qels[0].dbuf = resdbuf; + qels[0].dbuflen = 2; + qels[0].QWrite = 0; + qels[0].mailbox = 0; + enQ(&qels[0]); + } + inb_p(dev->base_addr+1); + inb_p(dev->base_addr+0); + if( wait_timeout(dev,0xf9) ) + printk("timed out idle f9\n"); + break; + case 0xf8: + /* ?? */ + if (xmQhd) { + inb_p(dev->base_addr+1); + inb_p(dev->base_addr+0); + if(wait_timeout(dev,0xf8) ) + printk("timed out idle f8\n"); + } else { + goto done; + } + break; + case 0xfa: + /* waiting for command */ + if(debug & DEBUG_LOWER) printk("idle: fa\n"); + if (xmQhd) { + q=deQ(); + memcpy(ltdmacbuf,q->cbuf,q->cbuflen); + ltdmacbuf[1] = q->mailbox; + if (debug>1) { + int n; + printk("ltpc: sent command "); + n = q->cbuflen; + if (n>100) n=100; + for(i=0;iQWrite) { + memcpy(ltdmabuf,q->dbuf,q->dbuflen); + handlewrite(dev); + } else { + handleread(dev); + /* non-zero mailbox numbers are for + commmands, 0 is for GETRESULT + requests */ + if(q->mailbox) { + memcpy(q->dbuf,ltdmabuf,q->dbuflen); + } else { + /* this was a result */ + mailbox[ 0x0f & ltdmabuf[0] ] = ltdmabuf[1]; + mboxinuse[0]=0; + } + } + break; + } + goto loop; + +done: + QInIdle=0; + + /* now set the interrupts back as appropriate */ + /* the first read takes it out of tri-state (but still high) */ + /* the second resets it */ + /* note that after this point, any read of base+6 will + trigger an interrupt */ + + if (dev->irq) { + inb_p(base+7); + inb_p(base+7); + } +} + + +static int do_write(struct net_device *dev, void *cbuf, int cbuflen, + void *dbuf, int dbuflen) +{ + + int i = getmbox(); + int ret; + + if(i) { + qels[i].cbuf = (unsigned char *) cbuf; + qels[i].cbuflen = cbuflen; + qels[i].dbuf = (unsigned char *) dbuf; + qels[i].dbuflen = dbuflen; + qels[i].QWrite = 1; + qels[i].mailbox = i; /* this should be initted rather */ + enQ(&qels[i]); + idle(dev); + ret = mailbox[i]; + mboxinuse[i]=0; + return ret; + } + printk("ltpc: could not allocate mbox\n"); + return -1; +} + +static int do_read(struct net_device *dev, void *cbuf, int cbuflen, + void *dbuf, int dbuflen) +{ + + int i = getmbox(); + int ret; + + if(i) { + qels[i].cbuf = (unsigned char *) cbuf; + qels[i].cbuflen = cbuflen; + qels[i].dbuf = (unsigned char *) dbuf; + qels[i].dbuflen = dbuflen; + qels[i].QWrite = 0; + qels[i].mailbox = i; /* this should be initted rather */ + enQ(&qels[i]); + idle(dev); + ret = mailbox[i]; + mboxinuse[i]=0; + return ret; + } + printk("ltpc: could not allocate mbox\n"); + return -1; +} + +/* end of idle handlers -- what should be seen is do_read, do_write */ + +static struct timer_list ltpc_timer; + +static netdev_tx_t ltpc_xmit(struct sk_buff *skb, struct net_device *dev); + +static int read_30 ( struct net_device *dev) +{ + lt_command c; + c.getflags.command = LT_GETFLAGS; + return do_read(dev, &c, sizeof(c.getflags),&c,0); +} + +static int set_30 (struct net_device *dev,int x) +{ + lt_command c; + c.setflags.command = LT_SETFLAGS; + c.setflags.flags = x; + return do_write(dev, &c, sizeof(c.setflags),&c,0); +} + +/* LLAP to DDP translation */ + +static int sendup_buffer (struct net_device *dev) +{ + /* on entry, command is in ltdmacbuf, data in ltdmabuf */ + /* called from idle, non-reentrant */ + + int dnode, snode, llaptype, len; + int sklen; + struct sk_buff *skb; + struct lt_rcvlap *ltc = (struct lt_rcvlap *) ltdmacbuf; + + if (ltc->command != LT_RCVLAP) { + printk("unknown command 0x%02x from ltpc card\n",ltc->command); + return -1; + } + dnode = ltc->dnode; + snode = ltc->snode; + llaptype = ltc->laptype; + len = ltc->length; + + sklen = len; + if (llaptype == 1) + sklen += 8; /* correct for short ddp */ + if(sklen > 800) { + printk(KERN_INFO "%s: nonsense length in ltpc command 0x14: 0x%08x\n", + dev->name,sklen); + return -1; + } + + if ( (llaptype==0) || (llaptype>2) ) { + printk(KERN_INFO "%s: unknown LLAP type: %d\n",dev->name,llaptype); + return -1; + } + + + skb = dev_alloc_skb(3+sklen); + if (skb == NULL) + { + printk("%s: dropping packet due to memory squeeze.\n", + dev->name); + return -1; + } + skb->dev = dev; + + if (sklen > len) + skb_reserve(skb,8); + skb_put(skb,len+3); + skb->protocol = htons(ETH_P_LOCALTALK); + /* add LLAP header */ + skb->data[0] = dnode; + skb->data[1] = snode; + skb->data[2] = llaptype; + skb_reset_mac_header(skb); /* save pointer to llap header */ + skb_pull(skb,3); + + /* copy ddp(s,e)hdr + contents */ + skb_copy_to_linear_data(skb, ltdmabuf, len); + + skb_reset_transport_header(skb); + + dev->stats.rx_packets++; + dev->stats.rx_bytes += skb->len; + + /* toss it onwards */ + netif_rx(skb); + return 0; +} + +/* the handler for the board interrupt */ + +static irqreturn_t +ltpc_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + + if (dev==NULL) { + printk("ltpc_interrupt: unknown device.\n"); + return IRQ_NONE; + } + + inb_p(dev->base_addr+6); /* disable further interrupts from board */ + + idle(dev); /* handle whatever is coming in */ + + /* idle re-enables interrupts from board */ + + return IRQ_HANDLED; +} + +/*** + * + * The ioctls that the driver responds to are: + * + * SIOCSIFADDR -- do probe using the passed node hint. + * SIOCGIFADDR -- return net, node. + * + * some of this stuff should be done elsewhere. + * + ***/ + +static int ltpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct sockaddr_at *sa = (struct sockaddr_at *) &ifr->ifr_addr; + /* we'll keep the localtalk node address in dev->pa_addr */ + struct ltpc_private *ltpc_priv = netdev_priv(dev); + struct atalk_addr *aa = <pc_priv->my_addr; + struct lt_init c; + int ltflags; + + if(debug & DEBUG_VERBOSE) printk("ltpc_ioctl called\n"); + + switch(cmd) { + case SIOCSIFADDR: + + aa->s_net = sa->sat_addr.s_net; + + /* this does the probe and returns the node addr */ + c.command = LT_INIT; + c.hint = sa->sat_addr.s_node; + + aa->s_node = do_read(dev,&c,sizeof(c),&c,0); + + /* get all llap frames raw */ + ltflags = read_30(dev); + ltflags |= LT_FLAG_ALLLAP; + set_30 (dev,ltflags); + + dev->broadcast[0] = 0xFF; + dev->dev_addr[0] = aa->s_node; + + dev->addr_len=1; + + return 0; + + case SIOCGIFADDR: + + sa->sat_addr.s_net = aa->s_net; + sa->sat_addr.s_node = aa->s_node; + + return 0; + + default: + return -EINVAL; + } +} + +static void set_multicast_list(struct net_device *dev) +{ + /* This needs to be present to keep netatalk happy. */ + /* Actually netatalk needs fixing! */ +} + +static int ltpc_poll_counter; + +static void ltpc_poll(unsigned long l) +{ + struct net_device *dev = (struct net_device *) l; + + del_timer(<pc_timer); + + if(debug & DEBUG_VERBOSE) { + if (!ltpc_poll_counter) { + ltpc_poll_counter = 50; + printk("ltpc poll is alive\n"); + } + ltpc_poll_counter--; + } + + if (!dev) + return; /* we've been downed */ + + /* poll 20 times per second */ + idle(dev); + ltpc_timer.expires = jiffies + HZ/20; + + add_timer(<pc_timer); +} + +/* DDP to LLAP translation */ + +static netdev_tx_t ltpc_xmit(struct sk_buff *skb, struct net_device *dev) +{ + /* in kernel 1.3.xx, on entry skb->data points to ddp header, + * and skb->len is the length of the ddp data + ddp header + */ + int i; + struct lt_sendlap cbuf; + unsigned char *hdr; + + cbuf.command = LT_SENDLAP; + cbuf.dnode = skb->data[0]; + cbuf.laptype = skb->data[2]; + skb_pull(skb,3); /* skip past LLAP header */ + cbuf.length = skb->len; /* this is host order */ + skb_reset_transport_header(skb); + + if(debug & DEBUG_UPPER) { + printk("command "); + for(i=0;i<6;i++) + printk("%02x ",((unsigned char *)&cbuf)[i]); + printk("\n"); + } + + hdr = skb_transport_header(skb); + do_write(dev, &cbuf, sizeof(cbuf), hdr, skb->len); + + if(debug & DEBUG_UPPER) { + printk("sent %d ddp bytes\n",skb->len); + for (i = 0; i < skb->len; i++) + printk("%02x ", hdr[i]); + printk("\n"); + } + + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + + dev_kfree_skb(skb); + return NETDEV_TX_OK; +} + +/* initialization stuff */ + +static int __init ltpc_probe_dma(int base, int dma) +{ + int want = (dma == 3) ? 2 : (dma == 1) ? 1 : 3; + unsigned long timeout; + unsigned long f; + + if (want & 1) { + if (request_dma(1,"ltpc")) { + want &= ~1; + } else { + f=claim_dma_lock(); + disable_dma(1); + clear_dma_ff(1); + set_dma_mode(1,DMA_MODE_WRITE); + set_dma_addr(1,virt_to_bus(ltdmabuf)); + set_dma_count(1,sizeof(struct lt_mem)); + enable_dma(1); + release_dma_lock(f); + } + } + if (want & 2) { + if (request_dma(3,"ltpc")) { + want &= ~2; + } else { + f=claim_dma_lock(); + disable_dma(3); + clear_dma_ff(3); + set_dma_mode(3,DMA_MODE_WRITE); + set_dma_addr(3,virt_to_bus(ltdmabuf)); + set_dma_count(3,sizeof(struct lt_mem)); + enable_dma(3); + release_dma_lock(f); + } + } + /* set up request */ + + /* FIXME -- do timings better! */ + + ltdmabuf[0] = LT_READMEM; + ltdmabuf[1] = 1; /* mailbox */ + ltdmabuf[2] = 0; ltdmabuf[3] = 0; /* address */ + ltdmabuf[4] = 0; ltdmabuf[5] = 1; /* read 0x0100 bytes */ + ltdmabuf[6] = 0; /* dunno if this is necessary */ + + inb_p(io+1); + inb_p(io+0); + timeout = jiffies+100*HZ/100; + while(time_before(jiffies, timeout)) { + if ( 0xfa == inb_p(io+6) ) break; + } + + inb_p(io+3); + inb_p(io+2); + while(time_before(jiffies, timeout)) { + if ( 0xfb == inb_p(io+6) ) break; + } + + /* release the other dma channel (if we opened both of them) */ + + if ((want & 2) && (get_dma_residue(3)==sizeof(struct lt_mem))) { + want &= ~2; + free_dma(3); + } + + if ((want & 1) && (get_dma_residue(1)==sizeof(struct lt_mem))) { + want &= ~1; + free_dma(1); + } + + if (!want) + return 0; + + return (want & 2) ? 3 : 1; +} + +static const struct net_device_ops ltpc_netdev = { + .ndo_start_xmit = ltpc_xmit, + .ndo_do_ioctl = ltpc_ioctl, + .ndo_set_multicast_list = set_multicast_list, +}; + +struct net_device * __init ltpc_probe(void) +{ + struct net_device *dev; + int err = -ENOMEM; + int x=0,y=0; + int autoirq; + unsigned long f; + unsigned long timeout; + + dev = alloc_ltalkdev(sizeof(struct ltpc_private)); + if (!dev) + goto out; + + /* probe for the I/O port address */ + + if (io != 0x240 && request_region(0x220,8,"ltpc")) { + x = inb_p(0x220+6); + if ( (x!=0xff) && (x>=0xf0) ) { + io = 0x220; + goto got_port; + } + release_region(0x220,8); + } + if (io != 0x220 && request_region(0x240,8,"ltpc")) { + y = inb_p(0x240+6); + if ( (y!=0xff) && (y>=0xf0) ){ + io = 0x240; + goto got_port; + } + release_region(0x240,8); + } + + /* give up in despair */ + printk(KERN_ERR "LocalTalk card not found; 220 = %02x, 240 = %02x.\n", x,y); + err = -ENODEV; + goto out1; + + got_port: + /* probe for the IRQ line */ + if (irq < 2) { + unsigned long irq_mask; + + irq_mask = probe_irq_on(); + /* reset the interrupt line */ + inb_p(io+7); + inb_p(io+7); + /* trigger an interrupt (I hope) */ + inb_p(io+6); + mdelay(2); + autoirq = probe_irq_off(irq_mask); + + if (autoirq == 0) { + printk(KERN_ERR "ltpc: probe at %#x failed to detect IRQ line.\n", io); + } else { + irq = autoirq; + } + } + + /* allocate a DMA buffer */ + ltdmabuf = (unsigned char *) dma_mem_alloc(1000); + if (!ltdmabuf) { + printk(KERN_ERR "ltpc: mem alloc failed\n"); + err = -ENOMEM; + goto out2; + } + + ltdmacbuf = <dmabuf[800]; + + if(debug & DEBUG_VERBOSE) { + printk("ltdmabuf pointer %08lx\n",(unsigned long) ltdmabuf); + } + + /* reset the card */ + + inb_p(io+1); + inb_p(io+3); + + msleep(20); + + inb_p(io+0); + inb_p(io+2); + inb_p(io+7); /* clear reset */ + inb_p(io+4); + inb_p(io+5); + inb_p(io+5); /* enable dma */ + inb_p(io+6); /* tri-state interrupt line */ + + ssleep(1); + + /* now, figure out which dma channel we're using, unless it's + already been specified */ + /* well, 0 is a legal DMA channel, but the LTPC card doesn't + use it... */ + dma = ltpc_probe_dma(io, dma); + if (!dma) { /* no dma channel */ + printk(KERN_ERR "No DMA channel found on ltpc card.\n"); + err = -ENODEV; + goto out3; + } + + /* print out friendly message */ + if(irq) + printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, IR%d, DMA%d.\n",io,irq,dma); + else + printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, DMA%d. Using polled mode.\n",io,dma); + + dev->netdev_ops = <pc_netdev; + dev->base_addr = io; + dev->irq = irq; + dev->dma = dma; + + /* the card will want to send a result at this point */ + /* (I think... leaving out this part makes the kernel crash, + so I put it back in...) */ + + f=claim_dma_lock(); + disable_dma(dma); + clear_dma_ff(dma); + set_dma_mode(dma,DMA_MODE_READ); + set_dma_addr(dma,virt_to_bus(ltdmabuf)); + set_dma_count(dma,0x100); + enable_dma(dma); + release_dma_lock(f); + + (void) inb_p(io+3); + (void) inb_p(io+2); + timeout = jiffies+100*HZ/100; + + while(time_before(jiffies, timeout)) { + if( 0xf9 == inb_p(io+6)) + break; + schedule(); + } + + if(debug & DEBUG_VERBOSE) { + printk("setting up timer and irq\n"); + } + + /* grab it and don't let go :-) */ + if (irq && request_irq( irq, ltpc_interrupt, 0, "ltpc", dev) >= 0) + { + (void) inb_p(io+7); /* enable interrupts from board */ + (void) inb_p(io+7); /* and reset irq line */ + } else { + if( irq ) + printk(KERN_ERR "ltpc: IRQ already in use, using polled mode.\n"); + dev->irq = 0; + /* polled mode -- 20 times per second */ + /* this is really, really slow... should it poll more often? */ + init_timer(<pc_timer); + ltpc_timer.function=ltpc_poll; + ltpc_timer.data = (unsigned long) dev; + + ltpc_timer.expires = jiffies + HZ/20; + add_timer(<pc_timer); + } + err = register_netdev(dev); + if (err) + goto out4; + + return NULL; +out4: + del_timer_sync(<pc_timer); + if (dev->irq) + free_irq(dev->irq, dev); +out3: + free_pages((unsigned long)ltdmabuf, get_order(1000)); +out2: + release_region(io, 8); +out1: + free_netdev(dev); +out: + return ERR_PTR(err); +} + +#ifndef MODULE +/* handles "ltpc=io,irq,dma" kernel command lines */ +static int __init ltpc_setup(char *str) +{ + int ints[5]; + + str = get_options(str, ARRAY_SIZE(ints), ints); + + if (ints[0] == 0) { + if (str && !strncmp(str, "auto", 4)) { + /* do nothing :-) */ + } + else { + /* usage message */ + printk (KERN_ERR + "ltpc: usage: ltpc=auto|iobase[,irq[,dma]]\n"); + return 0; + } + } else { + io = ints[1]; + if (ints[0] > 1) { + irq = ints[2]; + } + if (ints[0] > 2) { + dma = ints[3]; + } + /* ignore any other parameters */ + } + return 1; +} + +__setup("ltpc=", ltpc_setup); +#endif /* MODULE */ + +static struct net_device *dev_ltpc; + +#ifdef MODULE + +MODULE_LICENSE("GPL"); +module_param(debug, int, 0); +module_param(io, int, 0); +module_param(irq, int, 0); +module_param(dma, int, 0); + + +static int __init ltpc_module_init(void) +{ + if(io == 0) + printk(KERN_NOTICE + "ltpc: Autoprobing is not recommended for modules\n"); + + dev_ltpc = ltpc_probe(); + if (IS_ERR(dev_ltpc)) + return PTR_ERR(dev_ltpc); + return 0; +} +module_init(ltpc_module_init); +#endif + +static void __exit ltpc_cleanup(void) +{ + + if(debug & DEBUG_VERBOSE) printk("unregister_netdev\n"); + unregister_netdev(dev_ltpc); + + ltpc_timer.data = 0; /* signal the poll routine that we're done */ + + del_timer_sync(<pc_timer); + + if(debug & DEBUG_VERBOSE) printk("freeing irq\n"); + + if (dev_ltpc->irq) + free_irq(dev_ltpc->irq, dev_ltpc); + + if(debug & DEBUG_VERBOSE) printk("freeing dma\n"); + + if (dev_ltpc->dma) + free_dma(dev_ltpc->dma); + + if(debug & DEBUG_VERBOSE) printk("freeing ioaddr\n"); + + if (dev_ltpc->base_addr) + release_region(dev_ltpc->base_addr,8); + + free_netdev(dev_ltpc); + + if(debug & DEBUG_VERBOSE) printk("free_pages\n"); + + free_pages( (unsigned long) ltdmabuf, get_order(1000)); + + if(debug & DEBUG_VERBOSE) printk("returning from cleanup_module\n"); +} + +module_exit(ltpc_cleanup); diff --git a/drivers/net/appletalk/ltpc.h b/drivers/net/appletalk/ltpc.h new file mode 100644 index 000000000000..cd30544a3729 --- /dev/null +++ b/drivers/net/appletalk/ltpc.h @@ -0,0 +1,73 @@ +/*** ltpc.h + * + * + ***/ + +#define LT_GETRESULT 0x00 +#define LT_WRITEMEM 0x01 +#define LT_READMEM 0x02 +#define LT_GETFLAGS 0x04 +#define LT_SETFLAGS 0x05 +#define LT_INIT 0x10 +#define LT_SENDLAP 0x13 +#define LT_RCVLAP 0x14 + +/* the flag that we care about */ +#define LT_FLAG_ALLLAP 0x04 + +struct lt_getresult { + unsigned char command; + unsigned char mailbox; +}; + +struct lt_mem { + unsigned char command; + unsigned char mailbox; + unsigned short addr; /* host order */ + unsigned short length; /* host order */ +}; + +struct lt_setflags { + unsigned char command; + unsigned char mailbox; + unsigned char flags; +}; + +struct lt_getflags { + unsigned char command; + unsigned char mailbox; +}; + +struct lt_init { + unsigned char command; + unsigned char mailbox; + unsigned char hint; +}; + +struct lt_sendlap { + unsigned char command; + unsigned char mailbox; + unsigned char dnode; + unsigned char laptype; + unsigned short length; /* host order */ +}; + +struct lt_rcvlap { + unsigned char command; + unsigned char dnode; + unsigned char snode; + unsigned char laptype; + unsigned short length; /* host order */ +}; + +union lt_command { + struct lt_getresult getresult; + struct lt_mem mem; + struct lt_setflags setflags; + struct lt_getflags getflags; + struct lt_init init; + struct lt_sendlap sendlap; + struct lt_rcvlap rcvlap; +}; +typedef union lt_command lt_command; + diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 584d4e264807..b80755da5394 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -169,8 +169,6 @@ source "drivers/staging/bcm/Kconfig" source "drivers/staging/ft1000/Kconfig" -source "drivers/staging/appletalk/Kconfig" - source "drivers/staging/intel_sst/Kconfig" source "drivers/staging/speakup/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 88f0c64e7e58..fd26509e5efa 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -65,7 +65,6 @@ obj-$(CONFIG_ATH6K_LEGACY) += ath6kl/ obj-$(CONFIG_USB_ENESTORAGE) += keucr/ obj-$(CONFIG_BCM_WIMAX) += bcm/ obj-$(CONFIG_FT1000) += ft1000/ -obj-$(CONFIG_DEV_APPLETALK) += appletalk/ obj-$(CONFIG_SND_INTEL_SST) += intel_sst/ obj-$(CONFIG_SPEAKUP) += speakup/ obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/ diff --git a/drivers/staging/appletalk/Kconfig b/drivers/staging/appletalk/Kconfig deleted file mode 100644 index 0b376a990972..000000000000 --- a/drivers/staging/appletalk/Kconfig +++ /dev/null @@ -1,126 +0,0 @@ -# -# Appletalk driver configuration -# -config ATALK - tristate "Appletalk protocol support" - depends on BKL # waiting to be removed from net/appletalk/ddp.c - select LLC - ---help--- - AppleTalk is the protocol that Apple computers can use to communicate - on a network. If your Linux box is connected to such a network and you - wish to connect to it, say Y. You will need to use the netatalk package - so that your Linux box can act as a print and file server for Macs as - well as access AppleTalk printers. Check out - on the WWW for details. - EtherTalk is the name used for AppleTalk over Ethernet and the - cheaper and slower LocalTalk is AppleTalk over a proprietary Apple - network using serial links. EtherTalk and LocalTalk are fully - supported by Linux. - - General information about how to connect Linux, Windows machines and - Macs is on the WWW at . The - NET3-4-HOWTO, available from - , contains valuable - information as well. - - To compile this driver as a module, choose M here: the module will be - called appletalk. You almost certainly want to compile it as a - module so you can restart your AppleTalk stack without rebooting - your machine. I hear that the GNU boycott of Apple is over, so - even politically correct people are allowed to say Y here. - -config DEV_APPLETALK - tristate "Appletalk interfaces support" - depends on ATALK - help - AppleTalk is the protocol that Apple computers can use to communicate - on a network. If your Linux box is connected to such a network, and wish - to do IP over it, or you have a LocalTalk card and wish to use it to - connect to the AppleTalk network, say Y. - - -config LTPC - tristate "Apple/Farallon LocalTalk PC support" - depends on DEV_APPLETALK && (ISA || EISA) && ISA_DMA_API - help - This allows you to use the AppleTalk PC card to connect to LocalTalk - networks. The card is also known as the Farallon PhoneNet PC card. - If you are in doubt, this card is the one with the 65C02 chip on it. - You also need version 1.3.3 or later of the netatalk package. - This driver is experimental, which means that it may not work. - See the file . - -config COPS - tristate "COPS LocalTalk PC support" - depends on DEV_APPLETALK && (ISA || EISA) - help - This allows you to use COPS AppleTalk cards to connect to LocalTalk - networks. You also need version 1.3.3 or later of the netatalk - package. This driver is experimental, which means that it may not - work. This driver will only work if you choose "AppleTalk DDP" - networking support, above. - Please read the file . - -config COPS_DAYNA - bool "Dayna firmware support" - depends on COPS - help - Support COPS compatible cards with Dayna style firmware (Dayna - DL2000/ Daynatalk/PC (half length), COPS LT-95, Farallon PhoneNET PC - III, Farallon PhoneNET PC II). - -config COPS_TANGENT - bool "Tangent firmware support" - depends on COPS - help - Support COPS compatible cards with Tangent style firmware (Tangent - ATB_II, Novell NL-1000, Daystar Digital LT-200. - -config IPDDP - tristate "Appletalk-IP driver support" - depends on DEV_APPLETALK && ATALK - ---help--- - This allows IP networking for users who only have AppleTalk - networking available. This feature is experimental. With this - driver, you can encapsulate IP inside AppleTalk (e.g. if your Linux - box is stuck on an AppleTalk only network) or decapsulate (e.g. if - you want your Linux box to act as an Internet gateway for a zoo of - AppleTalk connected Macs). Please see the file - for more information. - - If you say Y here, the AppleTalk-IP support will be compiled into - the kernel. In this case, you can either use encapsulation or - decapsulation, but not both. With the following two questions, you - decide which one you want. - - To compile the AppleTalk-IP support as a module, choose M here: the - module will be called ipddp. - In this case, you will be able to use both encapsulation and - decapsulation simultaneously, by loading two copies of the module - and specifying different values for the module option ipddp_mode. - -config IPDDP_ENCAP - bool "IP to Appletalk-IP Encapsulation support" - depends on IPDDP - help - If you say Y here, the AppleTalk-IP code will be able to encapsulate - IP packets inside AppleTalk frames; this is useful if your Linux box - is stuck on an AppleTalk network (which hopefully contains a - decapsulator somewhere). Please see - for more information. If - you said Y to "AppleTalk-IP driver support" above and you say Y - here, then you cannot say Y to "AppleTalk-IP to IP Decapsulation - support", below. - -config IPDDP_DECAP - bool "Appletalk-IP to IP Decapsulation support" - depends on IPDDP - help - If you say Y here, the AppleTalk-IP code will be able to decapsulate - AppleTalk-IP frames to IP packets; this is useful if you want your - Linux box to act as an Internet gateway for an AppleTalk network. - Please see for more - information. If you said Y to "AppleTalk-IP driver support" above - and you say Y here, then you cannot say Y to "IP to AppleTalk-IP - Encapsulation support", above. - diff --git a/drivers/staging/appletalk/Makefile b/drivers/staging/appletalk/Makefile deleted file mode 100644 index 2a5129a5c6bc..000000000000 --- a/drivers/staging/appletalk/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# Makefile for drivers/staging/appletalk -# -obj-$(CONFIG_ATALK) += appletalk.o - -appletalk-y := aarp.o ddp.o dev.o -appletalk-$(CONFIG_PROC_FS) += atalk_proc.o -appletalk-$(CONFIG_SYSCTL) += sysctl_net_atalk.o - -obj-$(CONFIG_IPDDP) += ipddp.o -obj-$(CONFIG_COPS) += cops.o -obj-$(CONFIG_LTPC) += ltpc.o diff --git a/drivers/staging/appletalk/aarp.c b/drivers/staging/appletalk/aarp.c deleted file mode 100644 index 7163a1dd501f..000000000000 --- a/drivers/staging/appletalk/aarp.c +++ /dev/null @@ -1,1063 +0,0 @@ -/* - * AARP: An implementation of the AppleTalk AARP protocol for - * Ethernet 'ELAP'. - * - * Alan Cox - * - * This doesn't fit cleanly with the IP arp. Potentially we can use - * the generic neighbour discovery code to clean this up. - * - * FIXME: - * We ought to handle the retransmits with a single list and a - * separate fast timer for when it is needed. - * Use neighbour discovery code. - * Token Ring Support. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * - * References: - * Inside AppleTalk (2nd Ed). - * Fixes: - * Jaume Grau - flush caches on AARP_PROBE - * Rob Newberry - Added proxy AARP and AARP proc fs, - * moved probing from DDP module. - * Arnaldo C. Melo - don't mangle rx packets - * - */ - -#include -#include -#include -#include -#include -#include "atalk.h" -#include -#include -#include -#include - -int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME; -int sysctl_aarp_tick_time = AARP_TICK_TIME; -int sysctl_aarp_retransmit_limit = AARP_RETRANSMIT_LIMIT; -int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME; - -/* Lists of aarp entries */ -/** - * struct aarp_entry - AARP entry - * @last_sent - Last time we xmitted the aarp request - * @packet_queue - Queue of frames wait for resolution - * @status - Used for proxy AARP - * expires_at - Entry expiry time - * target_addr - DDP Address - * dev - Device to use - * hwaddr - Physical i/f address of target/router - * xmit_count - When this hits 10 we give up - * next - Next entry in chain - */ -struct aarp_entry { - /* These first two are only used for unresolved entries */ - unsigned long last_sent; - struct sk_buff_head packet_queue; - int status; - unsigned long expires_at; - struct atalk_addr target_addr; - struct net_device *dev; - char hwaddr[6]; - unsigned short xmit_count; - struct aarp_entry *next; -}; - -/* Hashed list of resolved, unresolved and proxy entries */ -static struct aarp_entry *resolved[AARP_HASH_SIZE]; -static struct aarp_entry *unresolved[AARP_HASH_SIZE]; -static struct aarp_entry *proxies[AARP_HASH_SIZE]; -static int unresolved_count; - -/* One lock protects it all. */ -static DEFINE_RWLOCK(aarp_lock); - -/* Used to walk the list and purge/kick entries. */ -static struct timer_list aarp_timer; - -/* - * Delete an aarp queue - * - * Must run under aarp_lock. - */ -static void __aarp_expire(struct aarp_entry *a) -{ - skb_queue_purge(&a->packet_queue); - kfree(a); -} - -/* - * Send an aarp queue entry request - * - * Must run under aarp_lock. - */ -static void __aarp_send_query(struct aarp_entry *a) -{ - static unsigned char aarp_eth_multicast[ETH_ALEN] = - { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; - struct net_device *dev = a->dev; - struct elapaarp *eah; - int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length; - struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); - struct atalk_addr *sat = atalk_find_dev_addr(dev); - - if (!skb) - return; - - if (!sat) { - kfree_skb(skb); - return; - } - - /* Set up the buffer */ - skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length); - skb_reset_network_header(skb); - skb_reset_transport_header(skb); - skb_put(skb, sizeof(*eah)); - skb->protocol = htons(ETH_P_ATALK); - skb->dev = dev; - eah = aarp_hdr(skb); - - /* Set up the ARP */ - eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); - eah->pa_type = htons(ETH_P_ATALK); - eah->hw_len = ETH_ALEN; - eah->pa_len = AARP_PA_ALEN; - eah->function = htons(AARP_REQUEST); - - memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN); - - eah->pa_src_zero = 0; - eah->pa_src_net = sat->s_net; - eah->pa_src_node = sat->s_node; - - memset(eah->hw_dst, '\0', ETH_ALEN); - - eah->pa_dst_zero = 0; - eah->pa_dst_net = a->target_addr.s_net; - eah->pa_dst_node = a->target_addr.s_node; - - /* Send it */ - aarp_dl->request(aarp_dl, skb, aarp_eth_multicast); - /* Update the sending count */ - a->xmit_count++; - a->last_sent = jiffies; -} - -/* This runs under aarp_lock and in softint context, so only atomic memory - * allocations can be used. */ -static void aarp_send_reply(struct net_device *dev, struct atalk_addr *us, - struct atalk_addr *them, unsigned char *sha) -{ - struct elapaarp *eah; - int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length; - struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); - - if (!skb) - return; - - /* Set up the buffer */ - skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length); - skb_reset_network_header(skb); - skb_reset_transport_header(skb); - skb_put(skb, sizeof(*eah)); - skb->protocol = htons(ETH_P_ATALK); - skb->dev = dev; - eah = aarp_hdr(skb); - - /* Set up the ARP */ - eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); - eah->pa_type = htons(ETH_P_ATALK); - eah->hw_len = ETH_ALEN; - eah->pa_len = AARP_PA_ALEN; - eah->function = htons(AARP_REPLY); - - memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN); - - eah->pa_src_zero = 0; - eah->pa_src_net = us->s_net; - eah->pa_src_node = us->s_node; - - if (!sha) - memset(eah->hw_dst, '\0', ETH_ALEN); - else - memcpy(eah->hw_dst, sha, ETH_ALEN); - - eah->pa_dst_zero = 0; - eah->pa_dst_net = them->s_net; - eah->pa_dst_node = them->s_node; - - /* Send it */ - aarp_dl->request(aarp_dl, skb, sha); -} - -/* - * Send probe frames. Called from aarp_probe_network and - * aarp_proxy_probe_network. - */ - -static void aarp_send_probe(struct net_device *dev, struct atalk_addr *us) -{ - struct elapaarp *eah; - int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length; - struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); - static unsigned char aarp_eth_multicast[ETH_ALEN] = - { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; - - if (!skb) - return; - - /* Set up the buffer */ - skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length); - skb_reset_network_header(skb); - skb_reset_transport_header(skb); - skb_put(skb, sizeof(*eah)); - skb->protocol = htons(ETH_P_ATALK); - skb->dev = dev; - eah = aarp_hdr(skb); - - /* Set up the ARP */ - eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); - eah->pa_type = htons(ETH_P_ATALK); - eah->hw_len = ETH_ALEN; - eah->pa_len = AARP_PA_ALEN; - eah->function = htons(AARP_PROBE); - - memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN); - - eah->pa_src_zero = 0; - eah->pa_src_net = us->s_net; - eah->pa_src_node = us->s_node; - - memset(eah->hw_dst, '\0', ETH_ALEN); - - eah->pa_dst_zero = 0; - eah->pa_dst_net = us->s_net; - eah->pa_dst_node = us->s_node; - - /* Send it */ - aarp_dl->request(aarp_dl, skb, aarp_eth_multicast); -} - -/* - * Handle an aarp timer expire - * - * Must run under the aarp_lock. - */ - -static void __aarp_expire_timer(struct aarp_entry **n) -{ - struct aarp_entry *t; - - while (*n) - /* Expired ? */ - if (time_after(jiffies, (*n)->expires_at)) { - t = *n; - *n = (*n)->next; - __aarp_expire(t); - } else - n = &((*n)->next); -} - -/* - * Kick all pending requests 5 times a second. - * - * Must run under the aarp_lock. - */ -static void __aarp_kick(struct aarp_entry **n) -{ - struct aarp_entry *t; - - while (*n) - /* Expired: if this will be the 11th tx, we delete instead. */ - if ((*n)->xmit_count >= sysctl_aarp_retransmit_limit) { - t = *n; - *n = (*n)->next; - __aarp_expire(t); - } else { - __aarp_send_query(*n); - n = &((*n)->next); - } -} - -/* - * A device has gone down. Take all entries referring to the device - * and remove them. - * - * Must run under the aarp_lock. - */ -static void __aarp_expire_device(struct aarp_entry **n, struct net_device *dev) -{ - struct aarp_entry *t; - - while (*n) - if ((*n)->dev == dev) { - t = *n; - *n = (*n)->next; - __aarp_expire(t); - } else - n = &((*n)->next); -} - -/* Handle the timer event */ -static void aarp_expire_timeout(unsigned long unused) -{ - int ct; - - write_lock_bh(&aarp_lock); - - for (ct = 0; ct < AARP_HASH_SIZE; ct++) { - __aarp_expire_timer(&resolved[ct]); - __aarp_kick(&unresolved[ct]); - __aarp_expire_timer(&unresolved[ct]); - __aarp_expire_timer(&proxies[ct]); - } - - write_unlock_bh(&aarp_lock); - mod_timer(&aarp_timer, jiffies + - (unresolved_count ? sysctl_aarp_tick_time : - sysctl_aarp_expiry_time)); -} - -/* Network device notifier chain handler. */ -static int aarp_device_event(struct notifier_block *this, unsigned long event, - void *ptr) -{ - struct net_device *dev = ptr; - int ct; - - if (!net_eq(dev_net(dev), &init_net)) - return NOTIFY_DONE; - - if (event == NETDEV_DOWN) { - write_lock_bh(&aarp_lock); - - for (ct = 0; ct < AARP_HASH_SIZE; ct++) { - __aarp_expire_device(&resolved[ct], dev); - __aarp_expire_device(&unresolved[ct], dev); - __aarp_expire_device(&proxies[ct], dev); - } - - write_unlock_bh(&aarp_lock); - } - return NOTIFY_DONE; -} - -/* Expire all entries in a hash chain */ -static void __aarp_expire_all(struct aarp_entry **n) -{ - struct aarp_entry *t; - - while (*n) { - t = *n; - *n = (*n)->next; - __aarp_expire(t); - } -} - -/* Cleanup all hash chains -- module unloading */ -static void aarp_purge(void) -{ - int ct; - - write_lock_bh(&aarp_lock); - for (ct = 0; ct < AARP_HASH_SIZE; ct++) { - __aarp_expire_all(&resolved[ct]); - __aarp_expire_all(&unresolved[ct]); - __aarp_expire_all(&proxies[ct]); - } - write_unlock_bh(&aarp_lock); -} - -/* - * Create a new aarp entry. This must use GFP_ATOMIC because it - * runs while holding spinlocks. - */ -static struct aarp_entry *aarp_alloc(void) -{ - struct aarp_entry *a = kmalloc(sizeof(*a), GFP_ATOMIC); - - if (a) - skb_queue_head_init(&a->packet_queue); - return a; -} - -/* - * Find an entry. We might return an expired but not yet purged entry. We - * don't care as it will do no harm. - * - * This must run under the aarp_lock. - */ -static struct aarp_entry *__aarp_find_entry(struct aarp_entry *list, - struct net_device *dev, - struct atalk_addr *sat) -{ - while (list) { - if (list->target_addr.s_net == sat->s_net && - list->target_addr.s_node == sat->s_node && - list->dev == dev) - break; - list = list->next; - } - - return list; -} - -/* Called from the DDP code, and thus must be exported. */ -void aarp_proxy_remove(struct net_device *dev, struct atalk_addr *sa) -{ - int hash = sa->s_node % (AARP_HASH_SIZE - 1); - struct aarp_entry *a; - - write_lock_bh(&aarp_lock); - - a = __aarp_find_entry(proxies[hash], dev, sa); - if (a) - a->expires_at = jiffies - 1; - - write_unlock_bh(&aarp_lock); -} - -/* This must run under aarp_lock. */ -static struct atalk_addr *__aarp_proxy_find(struct net_device *dev, - struct atalk_addr *sa) -{ - int hash = sa->s_node % (AARP_HASH_SIZE - 1); - struct aarp_entry *a = __aarp_find_entry(proxies[hash], dev, sa); - - return a ? sa : NULL; -} - -/* - * Probe a Phase 1 device or a device that requires its Net:Node to - * be set via an ioctl. - */ -static void aarp_send_probe_phase1(struct atalk_iface *iface) -{ - struct ifreq atreq; - struct sockaddr_at *sa = (struct sockaddr_at *)&atreq.ifr_addr; - const struct net_device_ops *ops = iface->dev->netdev_ops; - - sa->sat_addr.s_node = iface->address.s_node; - sa->sat_addr.s_net = ntohs(iface->address.s_net); - - /* We pass the Net:Node to the drivers/cards by a Device ioctl. */ - if (!(ops->ndo_do_ioctl(iface->dev, &atreq, SIOCSIFADDR))) { - ops->ndo_do_ioctl(iface->dev, &atreq, SIOCGIFADDR); - if (iface->address.s_net != htons(sa->sat_addr.s_net) || - iface->address.s_node != sa->sat_addr.s_node) - iface->status |= ATIF_PROBE_FAIL; - - iface->address.s_net = htons(sa->sat_addr.s_net); - iface->address.s_node = sa->sat_addr.s_node; - } -} - - -void aarp_probe_network(struct atalk_iface *atif) -{ - if (atif->dev->type == ARPHRD_LOCALTLK || - atif->dev->type == ARPHRD_PPP) - aarp_send_probe_phase1(atif); - else { - unsigned int count; - - for (count = 0; count < AARP_RETRANSMIT_LIMIT; count++) { - aarp_send_probe(atif->dev, &atif->address); - - /* Defer 1/10th */ - msleep(100); - - if (atif->status & ATIF_PROBE_FAIL) - break; - } - } -} - -int aarp_proxy_probe_network(struct atalk_iface *atif, struct atalk_addr *sa) -{ - int hash, retval = -EPROTONOSUPPORT; - struct aarp_entry *entry; - unsigned int count; - - /* - * we don't currently support LocalTalk or PPP for proxy AARP; - * if someone wants to try and add it, have fun - */ - if (atif->dev->type == ARPHRD_LOCALTLK || - atif->dev->type == ARPHRD_PPP) - goto out; - - /* - * create a new AARP entry with the flags set to be published -- - * we need this one to hang around even if it's in use - */ - entry = aarp_alloc(); - retval = -ENOMEM; - if (!entry) - goto out; - - entry->expires_at = -1; - entry->status = ATIF_PROBE; - entry->target_addr.s_node = sa->s_node; - entry->target_addr.s_net = sa->s_net; - entry->dev = atif->dev; - - write_lock_bh(&aarp_lock); - - hash = sa->s_node % (AARP_HASH_SIZE - 1); - entry->next = proxies[hash]; - proxies[hash] = entry; - - for (count = 0; count < AARP_RETRANSMIT_LIMIT; count++) { - aarp_send_probe(atif->dev, sa); - - /* Defer 1/10th */ - write_unlock_bh(&aarp_lock); - msleep(100); - write_lock_bh(&aarp_lock); - - if (entry->status & ATIF_PROBE_FAIL) - break; - } - - if (entry->status & ATIF_PROBE_FAIL) { - entry->expires_at = jiffies - 1; /* free the entry */ - retval = -EADDRINUSE; /* return network full */ - } else { /* clear the probing flag */ - entry->status &= ~ATIF_PROBE; - retval = 1; - } - - write_unlock_bh(&aarp_lock); -out: - return retval; -} - -/* Send a DDP frame */ -int aarp_send_ddp(struct net_device *dev, struct sk_buff *skb, - struct atalk_addr *sa, void *hwaddr) -{ - static char ddp_eth_multicast[ETH_ALEN] = - { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; - int hash; - struct aarp_entry *a; - - skb_reset_network_header(skb); - - /* Check for LocalTalk first */ - if (dev->type == ARPHRD_LOCALTLK) { - struct atalk_addr *at = atalk_find_dev_addr(dev); - struct ddpehdr *ddp = (struct ddpehdr *)skb->data; - int ft = 2; - - /* - * Compressible ? - * - * IFF: src_net == dest_net == device_net - * (zero matches anything) - */ - - if ((!ddp->deh_snet || at->s_net == ddp->deh_snet) && - (!ddp->deh_dnet || at->s_net == ddp->deh_dnet)) { - skb_pull(skb, sizeof(*ddp) - 4); - - /* - * The upper two remaining bytes are the port - * numbers we just happen to need. Now put the - * length in the lower two. - */ - *((__be16 *)skb->data) = htons(skb->len); - ft = 1; - } - /* - * Nice and easy. No AARP type protocols occur here so we can - * just shovel it out with a 3 byte LLAP header - */ - - skb_push(skb, 3); - skb->data[0] = sa->s_node; - skb->data[1] = at->s_node; - skb->data[2] = ft; - skb->dev = dev; - goto sendit; - } - - /* On a PPP link we neither compress nor aarp. */ - if (dev->type == ARPHRD_PPP) { - skb->protocol = htons(ETH_P_PPPTALK); - skb->dev = dev; - goto sendit; - } - - /* Non ELAP we cannot do. */ - if (dev->type != ARPHRD_ETHER) - goto free_it; - - skb->dev = dev; - skb->protocol = htons(ETH_P_ATALK); - hash = sa->s_node % (AARP_HASH_SIZE - 1); - - /* Do we have a resolved entry? */ - if (sa->s_node == ATADDR_BCAST) { - /* Send it */ - ddp_dl->request(ddp_dl, skb, ddp_eth_multicast); - goto sent; - } - - write_lock_bh(&aarp_lock); - a = __aarp_find_entry(resolved[hash], dev, sa); - - if (a) { /* Return 1 and fill in the address */ - a->expires_at = jiffies + (sysctl_aarp_expiry_time * 10); - ddp_dl->request(ddp_dl, skb, a->hwaddr); - write_unlock_bh(&aarp_lock); - goto sent; - } - - /* Do we have an unresolved entry: This is the less common path */ - a = __aarp_find_entry(unresolved[hash], dev, sa); - if (a) { /* Queue onto the unresolved queue */ - skb_queue_tail(&a->packet_queue, skb); - goto out_unlock; - } - - /* Allocate a new entry */ - a = aarp_alloc(); - if (!a) { - /* Whoops slipped... good job it's an unreliable protocol 8) */ - write_unlock_bh(&aarp_lock); - goto free_it; - } - - /* Set up the queue */ - skb_queue_tail(&a->packet_queue, skb); - a->expires_at = jiffies + sysctl_aarp_resolve_time; - a->dev = dev; - a->next = unresolved[hash]; - a->target_addr = *sa; - a->xmit_count = 0; - unresolved[hash] = a; - unresolved_count++; - - /* Send an initial request for the address */ - __aarp_send_query(a); - - /* - * Switch to fast timer if needed (That is if this is the first - * unresolved entry to get added) - */ - - if (unresolved_count == 1) - mod_timer(&aarp_timer, jiffies + sysctl_aarp_tick_time); - - /* Now finally, it is safe to drop the lock. */ -out_unlock: - write_unlock_bh(&aarp_lock); - - /* Tell the ddp layer we have taken over for this frame. */ - goto sent; - -sendit: - if (skb->sk) - skb->priority = skb->sk->sk_priority; - if (dev_queue_xmit(skb)) - goto drop; -sent: - return NET_XMIT_SUCCESS; -free_it: - kfree_skb(skb); -drop: - return NET_XMIT_DROP; -} -EXPORT_SYMBOL(aarp_send_ddp); - -/* - * An entry in the aarp unresolved queue has become resolved. Send - * all the frames queued under it. - * - * Must run under aarp_lock. - */ -static void __aarp_resolved(struct aarp_entry **list, struct aarp_entry *a, - int hash) -{ - struct sk_buff *skb; - - while (*list) - if (*list == a) { - unresolved_count--; - *list = a->next; - - /* Move into the resolved list */ - a->next = resolved[hash]; - resolved[hash] = a; - - /* Kick frames off */ - while ((skb = skb_dequeue(&a->packet_queue)) != NULL) { - a->expires_at = jiffies + - sysctl_aarp_expiry_time * 10; - ddp_dl->request(ddp_dl, skb, a->hwaddr); - } - } else - list = &((*list)->next); -} - -/* - * This is called by the SNAP driver whenever we see an AARP SNAP - * frame. We currently only support Ethernet. - */ -static int aarp_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, struct net_device *orig_dev) -{ - struct elapaarp *ea = aarp_hdr(skb); - int hash, ret = 0; - __u16 function; - struct aarp_entry *a; - struct atalk_addr sa, *ma, da; - struct atalk_iface *ifa; - - if (!net_eq(dev_net(dev), &init_net)) - goto out0; - - /* We only do Ethernet SNAP AARP. */ - if (dev->type != ARPHRD_ETHER) - goto out0; - - /* Frame size ok? */ - if (!skb_pull(skb, sizeof(*ea))) - goto out0; - - function = ntohs(ea->function); - - /* Sanity check fields. */ - if (function < AARP_REQUEST || function > AARP_PROBE || - ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN || - ea->pa_src_zero || ea->pa_dst_zero) - goto out0; - - /* Looks good. */ - hash = ea->pa_src_node % (AARP_HASH_SIZE - 1); - - /* Build an address. */ - sa.s_node = ea->pa_src_node; - sa.s_net = ea->pa_src_net; - - /* Process the packet. Check for replies of me. */ - ifa = atalk_find_dev(dev); - if (!ifa) - goto out1; - - if (ifa->status & ATIF_PROBE && - ifa->address.s_node == ea->pa_dst_node && - ifa->address.s_net == ea->pa_dst_net) { - ifa->status |= ATIF_PROBE_FAIL; /* Fail the probe (in use) */ - goto out1; - } - - /* Check for replies of proxy AARP entries */ - da.s_node = ea->pa_dst_node; - da.s_net = ea->pa_dst_net; - - write_lock_bh(&aarp_lock); - a = __aarp_find_entry(proxies[hash], dev, &da); - - if (a && a->status & ATIF_PROBE) { - a->status |= ATIF_PROBE_FAIL; - /* - * we do not respond to probe or request packets for - * this address while we are probing this address - */ - goto unlock; - } - - switch (function) { - case AARP_REPLY: - if (!unresolved_count) /* Speed up */ - break; - - /* Find the entry. */ - a = __aarp_find_entry(unresolved[hash], dev, &sa); - if (!a || dev != a->dev) - break; - - /* We can fill one in - this is good. */ - memcpy(a->hwaddr, ea->hw_src, ETH_ALEN); - __aarp_resolved(&unresolved[hash], a, hash); - if (!unresolved_count) - mod_timer(&aarp_timer, - jiffies + sysctl_aarp_expiry_time); - break; - - case AARP_REQUEST: - case AARP_PROBE: - - /* - * If it is my address set ma to my address and reply. - * We can treat probe and request the same. Probe - * simply means we shouldn't cache the querying host, - * as in a probe they are proposing an address not - * using one. - * - * Support for proxy-AARP added. We check if the - * address is one of our proxies before we toss the - * packet out. - */ - - sa.s_node = ea->pa_dst_node; - sa.s_net = ea->pa_dst_net; - - /* See if we have a matching proxy. */ - ma = __aarp_proxy_find(dev, &sa); - if (!ma) - ma = &ifa->address; - else { /* We need to make a copy of the entry. */ - da.s_node = sa.s_node; - da.s_net = sa.s_net; - ma = &da; - } - - if (function == AARP_PROBE) { - /* - * A probe implies someone trying to get an - * address. So as a precaution flush any - * entries we have for this address. - */ - a = __aarp_find_entry(resolved[sa.s_node % - (AARP_HASH_SIZE - 1)], - skb->dev, &sa); - - /* - * Make it expire next tick - that avoids us - * getting into a probe/flush/learn/probe/ - * flush/learn cycle during probing of a slow - * to respond host addr. - */ - if (a) { - a->expires_at = jiffies - 1; - mod_timer(&aarp_timer, jiffies + - sysctl_aarp_tick_time); - } - } - - if (sa.s_node != ma->s_node) - break; - - if (sa.s_net && ma->s_net && sa.s_net != ma->s_net) - break; - - sa.s_node = ea->pa_src_node; - sa.s_net = ea->pa_src_net; - - /* aarp_my_address has found the address to use for us. - */ - aarp_send_reply(dev, ma, &sa, ea->hw_src); - break; - } - -unlock: - write_unlock_bh(&aarp_lock); -out1: - ret = 1; -out0: - kfree_skb(skb); - return ret; -} - -static struct notifier_block aarp_notifier = { - .notifier_call = aarp_device_event, -}; - -static unsigned char aarp_snap_id[] = { 0x00, 0x00, 0x00, 0x80, 0xF3 }; - -void __init aarp_proto_init(void) -{ - aarp_dl = register_snap_client(aarp_snap_id, aarp_rcv); - if (!aarp_dl) - printk(KERN_CRIT "Unable to register AARP with SNAP.\n"); - setup_timer(&aarp_timer, aarp_expire_timeout, 0); - aarp_timer.expires = jiffies + sysctl_aarp_expiry_time; - add_timer(&aarp_timer); - register_netdevice_notifier(&aarp_notifier); -} - -/* Remove the AARP entries associated with a device. */ -void aarp_device_down(struct net_device *dev) -{ - int ct; - - write_lock_bh(&aarp_lock); - - for (ct = 0; ct < AARP_HASH_SIZE; ct++) { - __aarp_expire_device(&resolved[ct], dev); - __aarp_expire_device(&unresolved[ct], dev); - __aarp_expire_device(&proxies[ct], dev); - } - - write_unlock_bh(&aarp_lock); -} - -#ifdef CONFIG_PROC_FS -struct aarp_iter_state { - int bucket; - struct aarp_entry **table; -}; - -/* - * Get the aarp entry that is in the chain described - * by the iterator. - * If pos is set then skip till that index. - * pos = 1 is the first entry - */ -static struct aarp_entry *iter_next(struct aarp_iter_state *iter, loff_t *pos) -{ - int ct = iter->bucket; - struct aarp_entry **table = iter->table; - loff_t off = 0; - struct aarp_entry *entry; - - rescan: - while(ct < AARP_HASH_SIZE) { - for (entry = table[ct]; entry; entry = entry->next) { - if (!pos || ++off == *pos) { - iter->table = table; - iter->bucket = ct; - return entry; - } - } - ++ct; - } - - if (table == resolved) { - ct = 0; - table = unresolved; - goto rescan; - } - if (table == unresolved) { - ct = 0; - table = proxies; - goto rescan; - } - return NULL; -} - -static void *aarp_seq_start(struct seq_file *seq, loff_t *pos) - __acquires(aarp_lock) -{ - struct aarp_iter_state *iter = seq->private; - - read_lock_bh(&aarp_lock); - iter->table = resolved; - iter->bucket = 0; - - return *pos ? iter_next(iter, pos) : SEQ_START_TOKEN; -} - -static void *aarp_seq_next(struct seq_file *seq, void *v, loff_t *pos) -{ - struct aarp_entry *entry = v; - struct aarp_iter_state *iter = seq->private; - - ++*pos; - - /* first line after header */ - if (v == SEQ_START_TOKEN) - entry = iter_next(iter, NULL); - - /* next entry in current bucket */ - else if (entry->next) - entry = entry->next; - - /* next bucket or table */ - else { - ++iter->bucket; - entry = iter_next(iter, NULL); - } - return entry; -} - -static void aarp_seq_stop(struct seq_file *seq, void *v) - __releases(aarp_lock) -{ - read_unlock_bh(&aarp_lock); -} - -static const char *dt2str(unsigned long ticks) -{ - static char buf[32]; - - sprintf(buf, "%ld.%02ld", ticks / HZ, ((ticks % HZ) * 100 ) / HZ); - - return buf; -} - -static int aarp_seq_show(struct seq_file *seq, void *v) -{ - struct aarp_iter_state *iter = seq->private; - struct aarp_entry *entry = v; - unsigned long now = jiffies; - - if (v == SEQ_START_TOKEN) - seq_puts(seq, - "Address Interface Hardware Address" - " Expires LastSend Retry Status\n"); - else { - seq_printf(seq, "%04X:%02X %-12s", - ntohs(entry->target_addr.s_net), - (unsigned int) entry->target_addr.s_node, - entry->dev ? entry->dev->name : "????"); - seq_printf(seq, "%pM", entry->hwaddr); - seq_printf(seq, " %8s", - dt2str((long)entry->expires_at - (long)now)); - if (iter->table == unresolved) - seq_printf(seq, " %8s %6hu", - dt2str(now - entry->last_sent), - entry->xmit_count); - else - seq_puts(seq, " "); - seq_printf(seq, " %s\n", - (iter->table == resolved) ? "resolved" - : (iter->table == unresolved) ? "unresolved" - : (iter->table == proxies) ? "proxies" - : "unknown"); - } - return 0; -} - -static const struct seq_operations aarp_seq_ops = { - .start = aarp_seq_start, - .next = aarp_seq_next, - .stop = aarp_seq_stop, - .show = aarp_seq_show, -}; - -static int aarp_seq_open(struct inode *inode, struct file *file) -{ - return seq_open_private(file, &aarp_seq_ops, - sizeof(struct aarp_iter_state)); -} - -const struct file_operations atalk_seq_arp_fops = { - .owner = THIS_MODULE, - .open = aarp_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release_private, -}; -#endif - -/* General module cleanup. Called from cleanup_module() in ddp.c. */ -void aarp_cleanup_module(void) -{ - del_timer_sync(&aarp_timer); - unregister_netdevice_notifier(&aarp_notifier); - unregister_snap_client(aarp_dl); - aarp_purge(); -} diff --git a/drivers/staging/appletalk/atalk.h b/drivers/staging/appletalk/atalk.h deleted file mode 100644 index d34c187432ed..000000000000 --- a/drivers/staging/appletalk/atalk.h +++ /dev/null @@ -1,208 +0,0 @@ -#ifndef __LINUX_ATALK_H__ -#define __LINUX_ATALK_H__ - -#include -#include - -/* - * AppleTalk networking structures - * - * The following are directly referenced from the University Of Michigan - * netatalk for compatibility reasons. - */ -#define ATPORT_FIRST 1 -#define ATPORT_RESERVED 128 -#define ATPORT_LAST 254 /* 254 is only legal on localtalk */ -#define ATADDR_ANYNET (__u16)0 -#define ATADDR_ANYNODE (__u8)0 -#define ATADDR_ANYPORT (__u8)0 -#define ATADDR_BCAST (__u8)255 -#define DDP_MAXSZ 587 -#define DDP_MAXHOPS 15 /* 4 bits of hop counter */ - -#define SIOCATALKDIFADDR (SIOCPROTOPRIVATE + 0) - -struct atalk_addr { - __be16 s_net; - __u8 s_node; -}; - -struct sockaddr_at { - sa_family_t sat_family; - __u8 sat_port; - struct atalk_addr sat_addr; - char sat_zero[8]; -}; - -struct atalk_netrange { - __u8 nr_phase; - __be16 nr_firstnet; - __be16 nr_lastnet; -}; - -#ifdef __KERNEL__ - -#include - -struct atalk_route { - struct net_device *dev; - struct atalk_addr target; - struct atalk_addr gateway; - int flags; - struct atalk_route *next; -}; - -/** - * struct atalk_iface - AppleTalk Interface - * @dev - Network device associated with this interface - * @address - Our address - * @status - What are we doing? - * @nets - Associated direct netrange - * @next - next element in the list of interfaces - */ -struct atalk_iface { - struct net_device *dev; - struct atalk_addr address; - int status; -#define ATIF_PROBE 1 /* Probing for an address */ -#define ATIF_PROBE_FAIL 2 /* Probe collided */ - struct atalk_netrange nets; - struct atalk_iface *next; -}; - -struct atalk_sock { - /* struct sock has to be the first member of atalk_sock */ - struct sock sk; - __be16 dest_net; - __be16 src_net; - unsigned char dest_node; - unsigned char src_node; - unsigned char dest_port; - unsigned char src_port; -}; - -static inline struct atalk_sock *at_sk(struct sock *sk) -{ - return (struct atalk_sock *)sk; -} - -struct ddpehdr { - __be16 deh_len_hops; /* lower 10 bits are length, next 4 - hops */ - __be16 deh_sum; - __be16 deh_dnet; - __be16 deh_snet; - __u8 deh_dnode; - __u8 deh_snode; - __u8 deh_dport; - __u8 deh_sport; - /* And netatalk apps expect to stick the type in themselves */ -}; - -static __inline__ struct ddpehdr *ddp_hdr(struct sk_buff *skb) -{ - return (struct ddpehdr *)skb_transport_header(skb); -} - -/* AppleTalk AARP headers */ -struct elapaarp { - __be16 hw_type; -#define AARP_HW_TYPE_ETHERNET 1 -#define AARP_HW_TYPE_TOKENRING 2 - __be16 pa_type; - __u8 hw_len; - __u8 pa_len; -#define AARP_PA_ALEN 4 - __be16 function; -#define AARP_REQUEST 1 -#define AARP_REPLY 2 -#define AARP_PROBE 3 - __u8 hw_src[ETH_ALEN]; - __u8 pa_src_zero; - __be16 pa_src_net; - __u8 pa_src_node; - __u8 hw_dst[ETH_ALEN]; - __u8 pa_dst_zero; - __be16 pa_dst_net; - __u8 pa_dst_node; -} __attribute__ ((packed)); - -static __inline__ struct elapaarp *aarp_hdr(struct sk_buff *skb) -{ - return (struct elapaarp *)skb_transport_header(skb); -} - -/* Not specified - how long till we drop a resolved entry */ -#define AARP_EXPIRY_TIME (5 * 60 * HZ) -/* Size of hash table */ -#define AARP_HASH_SIZE 16 -/* Fast retransmission timer when resolving */ -#define AARP_TICK_TIME (HZ / 5) -/* Send 10 requests then give up (2 seconds) */ -#define AARP_RETRANSMIT_LIMIT 10 -/* - * Some value bigger than total retransmit time + a bit for last reply to - * appear and to stop continual requests - */ -#define AARP_RESOLVE_TIME (10 * HZ) - -extern struct datalink_proto *ddp_dl, *aarp_dl; -extern void aarp_proto_init(void); - -/* Inter module exports */ - -/* Give a device find its atif control structure */ -static inline struct atalk_iface *atalk_find_dev(struct net_device *dev) -{ - return dev->atalk_ptr; -} - -extern struct atalk_addr *atalk_find_dev_addr(struct net_device *dev); -extern struct net_device *atrtr_get_dev(struct atalk_addr *sa); -extern int aarp_send_ddp(struct net_device *dev, - struct sk_buff *skb, - struct atalk_addr *sa, void *hwaddr); -extern void aarp_device_down(struct net_device *dev); -extern void aarp_probe_network(struct atalk_iface *atif); -extern int aarp_proxy_probe_network(struct atalk_iface *atif, - struct atalk_addr *sa); -extern void aarp_proxy_remove(struct net_device *dev, - struct atalk_addr *sa); - -extern void aarp_cleanup_module(void); - -extern struct hlist_head atalk_sockets; -extern rwlock_t atalk_sockets_lock; - -extern struct atalk_route *atalk_routes; -extern rwlock_t atalk_routes_lock; - -extern struct atalk_iface *atalk_interfaces; -extern rwlock_t atalk_interfaces_lock; - -extern struct atalk_route atrtr_default; - -extern const struct file_operations atalk_seq_arp_fops; - -extern int sysctl_aarp_expiry_time; -extern int sysctl_aarp_tick_time; -extern int sysctl_aarp_retransmit_limit; -extern int sysctl_aarp_resolve_time; - -#ifdef CONFIG_SYSCTL -extern void atalk_register_sysctl(void); -extern void atalk_unregister_sysctl(void); -#else -#define atalk_register_sysctl() do { } while(0) -#define atalk_unregister_sysctl() do { } while(0) -#endif - -#ifdef CONFIG_PROC_FS -extern int atalk_proc_init(void); -extern void atalk_proc_exit(void); -#else -#define atalk_proc_init() ({ 0; }) -#define atalk_proc_exit() do { } while(0) -#endif /* CONFIG_PROC_FS */ - -#endif /* __KERNEL__ */ -#endif /* __LINUX_ATALK_H__ */ diff --git a/drivers/staging/appletalk/atalk_proc.c b/drivers/staging/appletalk/atalk_proc.c deleted file mode 100644 index d012ba2e67d1..000000000000 --- a/drivers/staging/appletalk/atalk_proc.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * atalk_proc.c - proc support for Appletalk - * - * Copyright(c) Arnaldo Carvalho de Melo - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, version 2. - */ - -#include -#include -#include -#include -#include -#include "atalk.h" - - -static __inline__ struct atalk_iface *atalk_get_interface_idx(loff_t pos) -{ - struct atalk_iface *i; - - for (i = atalk_interfaces; pos && i; i = i->next) - --pos; - - return i; -} - -static void *atalk_seq_interface_start(struct seq_file *seq, loff_t *pos) - __acquires(atalk_interfaces_lock) -{ - loff_t l = *pos; - - read_lock_bh(&atalk_interfaces_lock); - return l ? atalk_get_interface_idx(--l) : SEQ_START_TOKEN; -} - -static void *atalk_seq_interface_next(struct seq_file *seq, void *v, loff_t *pos) -{ - struct atalk_iface *i; - - ++*pos; - if (v == SEQ_START_TOKEN) { - i = NULL; - if (atalk_interfaces) - i = atalk_interfaces; - goto out; - } - i = v; - i = i->next; -out: - return i; -} - -static void atalk_seq_interface_stop(struct seq_file *seq, void *v) - __releases(atalk_interfaces_lock) -{ - read_unlock_bh(&atalk_interfaces_lock); -} - -static int atalk_seq_interface_show(struct seq_file *seq, void *v) -{ - struct atalk_iface *iface; - - if (v == SEQ_START_TOKEN) { - seq_puts(seq, "Interface Address Networks " - "Status\n"); - goto out; - } - - iface = v; - seq_printf(seq, "%-16s %04X:%02X %04X-%04X %d\n", - iface->dev->name, ntohs(iface->address.s_net), - iface->address.s_node, ntohs(iface->nets.nr_firstnet), - ntohs(iface->nets.nr_lastnet), iface->status); -out: - return 0; -} - -static __inline__ struct atalk_route *atalk_get_route_idx(loff_t pos) -{ - struct atalk_route *r; - - for (r = atalk_routes; pos && r; r = r->next) - --pos; - - return r; -} - -static void *atalk_seq_route_start(struct seq_file *seq, loff_t *pos) - __acquires(atalk_routes_lock) -{ - loff_t l = *pos; - - read_lock_bh(&atalk_routes_lock); - return l ? atalk_get_route_idx(--l) : SEQ_START_TOKEN; -} - -static void *atalk_seq_route_next(struct seq_file *seq, void *v, loff_t *pos) -{ - struct atalk_route *r; - - ++*pos; - if (v == SEQ_START_TOKEN) { - r = NULL; - if (atalk_routes) - r = atalk_routes; - goto out; - } - r = v; - r = r->next; -out: - return r; -} - -static void atalk_seq_route_stop(struct seq_file *seq, void *v) - __releases(atalk_routes_lock) -{ - read_unlock_bh(&atalk_routes_lock); -} - -static int atalk_seq_route_show(struct seq_file *seq, void *v) -{ - struct atalk_route *rt; - - if (v == SEQ_START_TOKEN) { - seq_puts(seq, "Target Router Flags Dev\n"); - goto out; - } - - if (atrtr_default.dev) { - rt = &atrtr_default; - seq_printf(seq, "Default %04X:%02X %-4d %s\n", - ntohs(rt->gateway.s_net), rt->gateway.s_node, - rt->flags, rt->dev->name); - } - - rt = v; - seq_printf(seq, "%04X:%02X %04X:%02X %-4d %s\n", - ntohs(rt->target.s_net), rt->target.s_node, - ntohs(rt->gateway.s_net), rt->gateway.s_node, - rt->flags, rt->dev->name); -out: - return 0; -} - -static void *atalk_seq_socket_start(struct seq_file *seq, loff_t *pos) - __acquires(atalk_sockets_lock) -{ - read_lock_bh(&atalk_sockets_lock); - return seq_hlist_start_head(&atalk_sockets, *pos); -} - -static void *atalk_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos) -{ - return seq_hlist_next(v, &atalk_sockets, pos); -} - -static void atalk_seq_socket_stop(struct seq_file *seq, void *v) - __releases(atalk_sockets_lock) -{ - read_unlock_bh(&atalk_sockets_lock); -} - -static int atalk_seq_socket_show(struct seq_file *seq, void *v) -{ - struct sock *s; - struct atalk_sock *at; - - if (v == SEQ_START_TOKEN) { - seq_printf(seq, "Type Local_addr Remote_addr Tx_queue " - "Rx_queue St UID\n"); - goto out; - } - - s = sk_entry(v); - at = at_sk(s); - - seq_printf(seq, "%02X %04X:%02X:%02X %04X:%02X:%02X %08X:%08X " - "%02X %d\n", - s->sk_type, ntohs(at->src_net), at->src_node, at->src_port, - ntohs(at->dest_net), at->dest_node, at->dest_port, - sk_wmem_alloc_get(s), - sk_rmem_alloc_get(s), - s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); -out: - return 0; -} - -static const struct seq_operations atalk_seq_interface_ops = { - .start = atalk_seq_interface_start, - .next = atalk_seq_interface_next, - .stop = atalk_seq_interface_stop, - .show = atalk_seq_interface_show, -}; - -static const struct seq_operations atalk_seq_route_ops = { - .start = atalk_seq_route_start, - .next = atalk_seq_route_next, - .stop = atalk_seq_route_stop, - .show = atalk_seq_route_show, -}; - -static const struct seq_operations atalk_seq_socket_ops = { - .start = atalk_seq_socket_start, - .next = atalk_seq_socket_next, - .stop = atalk_seq_socket_stop, - .show = atalk_seq_socket_show, -}; - -static int atalk_seq_interface_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &atalk_seq_interface_ops); -} - -static int atalk_seq_route_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &atalk_seq_route_ops); -} - -static int atalk_seq_socket_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &atalk_seq_socket_ops); -} - -static const struct file_operations atalk_seq_interface_fops = { - .owner = THIS_MODULE, - .open = atalk_seq_interface_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -static const struct file_operations atalk_seq_route_fops = { - .owner = THIS_MODULE, - .open = atalk_seq_route_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -static const struct file_operations atalk_seq_socket_fops = { - .owner = THIS_MODULE, - .open = atalk_seq_socket_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -static struct proc_dir_entry *atalk_proc_dir; - -int __init atalk_proc_init(void) -{ - struct proc_dir_entry *p; - int rc = -ENOMEM; - - atalk_proc_dir = proc_mkdir("atalk", init_net.proc_net); - if (!atalk_proc_dir) - goto out; - - p = proc_create("interface", S_IRUGO, atalk_proc_dir, - &atalk_seq_interface_fops); - if (!p) - goto out_interface; - - p = proc_create("route", S_IRUGO, atalk_proc_dir, - &atalk_seq_route_fops); - if (!p) - goto out_route; - - p = proc_create("socket", S_IRUGO, atalk_proc_dir, - &atalk_seq_socket_fops); - if (!p) - goto out_socket; - - p = proc_create("arp", S_IRUGO, atalk_proc_dir, &atalk_seq_arp_fops); - if (!p) - goto out_arp; - - rc = 0; -out: - return rc; -out_arp: - remove_proc_entry("socket", atalk_proc_dir); -out_socket: - remove_proc_entry("route", atalk_proc_dir); -out_route: - remove_proc_entry("interface", atalk_proc_dir); -out_interface: - remove_proc_entry("atalk", init_net.proc_net); - goto out; -} - -void __exit atalk_proc_exit(void) -{ - remove_proc_entry("interface", atalk_proc_dir); - remove_proc_entry("route", atalk_proc_dir); - remove_proc_entry("socket", atalk_proc_dir); - remove_proc_entry("arp", atalk_proc_dir); - remove_proc_entry("atalk", init_net.proc_net); -} diff --git a/drivers/staging/appletalk/cops.c b/drivers/staging/appletalk/cops.c deleted file mode 100644 index 661d42eff7d8..000000000000 --- a/drivers/staging/appletalk/cops.c +++ /dev/null @@ -1,1013 +0,0 @@ -/* cops.c: LocalTalk driver for Linux. - * - * Authors: - * - Jay Schulist - * - * With more than a little help from; - * - Alan Cox - * - * Derived from: - * - skeleton.c: A network driver outline for linux. - * Written 1993-94 by Donald Becker. - * - ltpc.c: A driver for the LocalTalk PC card. - * Written by Bradford W. Johnson. - * - * Copyright 1993 United States Government as represented by the - * Director, National Security Agency. - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Changes: - * 19970608 Alan Cox Allowed dual card type support - * Can set board type in insmod - * Hooks for cops_setup routine - * (not yet implemented). - * 19971101 Jay Schulist Fixes for multiple lt* devices. - * 19980607 Steven Hirsch Fixed the badly broken support - * for Tangent type cards. Only - * tested on Daystar LT200. Some - * cleanup of formatting and program - * logic. Added emacs 'local-vars' - * setup for Jay's brace style. - * 20000211 Alan Cox Cleaned up for softnet - */ - -static const char *version = -"cops.c:v0.04 6/7/98 Jay Schulist \n"; -/* - * Sources: - * COPS Localtalk SDK. This provides almost all of the information - * needed. - */ - -/* - * insmod/modprobe configurable stuff. - * - IO Port, choose one your card supports or 0 if you dare. - * - IRQ, also choose one your card supports or nothing and let - * the driver figure it out. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* For udelay() */ -#include -#include -#include - -#include -#include -#include - -#include "atalk.h" -#include "cops.h" /* Our Stuff */ -#include "cops_ltdrv.h" /* Firmware code for Tangent type cards. */ -#include "cops_ffdrv.h" /* Firmware code for Dayna type cards. */ - -/* - * The name of the card. Is used for messages and in the requests for - * io regions, irqs and dma channels - */ - -static const char *cardname = "cops"; - -#ifdef CONFIG_COPS_DAYNA -static int board_type = DAYNA; /* Module exported */ -#else -static int board_type = TANGENT; -#endif - -static int io = 0x240; /* Default IO for Dayna */ -static int irq = 5; /* Default IRQ */ - -/* - * COPS Autoprobe information. - * Right now if port address is right but IRQ is not 5 this will - * return a 5 no matter what since we will still get a status response. - * Need one more additional check to narrow down after we have gotten - * the ioaddr. But since only other possible IRQs is 3 and 4 so no real - * hurry on this. I *STRONGLY* recommend using IRQ 5 for your card with - * this driver. - * - * This driver has 2 modes and they are: Dayna mode and Tangent mode. - * Each mode corresponds with the type of card. It has been found - * that there are 2 main types of cards and all other cards are - * the same and just have different names or only have minor differences - * such as more IO ports. As this driver is tested it will - * become more clear on exactly what cards are supported. The driver - * defaults to using Dayna mode. To change the drivers mode, simply - * select Dayna or Tangent mode when configuring the kernel. - * - * This driver should support: - * TANGENT driver mode: - * Tangent ATB-II, Novell NL-1000, Daystar Digital LT-200, - * COPS LT-1 - * DAYNA driver mode: - * Dayna DL2000/DaynaTalk PC (Half Length), COPS LT-95, - * Farallon PhoneNET PC III, Farallon PhoneNET PC II - * Other cards possibly supported mode unknown though: - * Dayna DL2000 (Full length), COPS LT/M (Micro-Channel) - * - * Cards NOT supported by this driver but supported by the ltpc.c - * driver written by Bradford W. Johnson - * Farallon PhoneNET PC - * Original Apple LocalTalk PC card - * - * N.B. - * - * The Daystar Digital LT200 boards do not support interrupt-driven - * IO. You must specify 'irq=0xff' as a module parameter to invoke - * polled mode. I also believe that the port probing logic is quite - * dangerous at best and certainly hopeless for a polled card. Best to - * specify both. - Steve H. - * - */ - -/* - * Zero terminated list of IO ports to probe. - */ - -static unsigned int ports[] = { - 0x240, 0x340, 0x200, 0x210, 0x220, 0x230, 0x260, - 0x2A0, 0x300, 0x310, 0x320, 0x330, 0x350, 0x360, - 0 -}; - -/* - * Zero terminated list of IRQ ports to probe. - */ - -static int cops_irqlist[] = { - 5, 4, 3, 0 -}; - -static struct timer_list cops_timer; - -/* use 0 for production, 1 for verification, 2 for debug, 3 for verbose debug */ -#ifndef COPS_DEBUG -#define COPS_DEBUG 1 -#endif -static unsigned int cops_debug = COPS_DEBUG; - -/* The number of low I/O ports used by the card. */ -#define COPS_IO_EXTENT 8 - -/* Information that needs to be kept for each board. */ - -struct cops_local -{ - int board; /* Holds what board type is. */ - int nodeid; /* Set to 1 once have nodeid. */ - unsigned char node_acquire; /* Node ID when acquired. */ - struct atalk_addr node_addr; /* Full node address */ - spinlock_t lock; /* RX/TX lock */ -}; - -/* Index to functions, as function prototypes. */ -static int cops_probe1 (struct net_device *dev, int ioaddr); -static int cops_irq (int ioaddr, int board); - -static int cops_open (struct net_device *dev); -static int cops_jumpstart (struct net_device *dev); -static void cops_reset (struct net_device *dev, int sleep); -static void cops_load (struct net_device *dev); -static int cops_nodeid (struct net_device *dev, int nodeid); - -static irqreturn_t cops_interrupt (int irq, void *dev_id); -static void cops_poll (unsigned long ltdev); -static void cops_timeout(struct net_device *dev); -static void cops_rx (struct net_device *dev); -static netdev_tx_t cops_send_packet (struct sk_buff *skb, - struct net_device *dev); -static void set_multicast_list (struct net_device *dev); -static int cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); -static int cops_close (struct net_device *dev); - -static void cleanup_card(struct net_device *dev) -{ - if (dev->irq) - free_irq(dev->irq, dev); - release_region(dev->base_addr, COPS_IO_EXTENT); -} - -/* - * Check for a network adaptor of this type, and return '0' iff one exists. - * If dev->base_addr == 0, probe all likely locations. - * If dev->base_addr in [1..0x1ff], always return failure. - * otherwise go with what we pass in. - */ -struct net_device * __init cops_probe(int unit) -{ - struct net_device *dev; - unsigned *port; - int base_addr; - int err = 0; - - dev = alloc_ltalkdev(sizeof(struct cops_local)); - if (!dev) - return ERR_PTR(-ENOMEM); - - if (unit >= 0) { - sprintf(dev->name, "lt%d", unit); - netdev_boot_setup_check(dev); - irq = dev->irq; - base_addr = dev->base_addr; - } else { - base_addr = dev->base_addr = io; - } - - if (base_addr > 0x1ff) { /* Check a single specified location. */ - err = cops_probe1(dev, base_addr); - } else if (base_addr != 0) { /* Don't probe at all. */ - err = -ENXIO; - } else { - /* FIXME Does this really work for cards which generate irq? - * It's definitely N.G. for polled Tangent. sh - * Dayna cards don't autoprobe well at all, but if your card is - * at IRQ 5 & IO 0x240 we find it every time. ;) JS - */ - for (port = ports; *port && cops_probe1(dev, *port) < 0; port++) - ; - if (!*port) - err = -ENODEV; - } - if (err) - goto out; - err = register_netdev(dev); - if (err) - goto out1; - return dev; -out1: - cleanup_card(dev); -out: - free_netdev(dev); - return ERR_PTR(err); -} - -static const struct net_device_ops cops_netdev_ops = { - .ndo_open = cops_open, - .ndo_stop = cops_close, - .ndo_start_xmit = cops_send_packet, - .ndo_tx_timeout = cops_timeout, - .ndo_do_ioctl = cops_ioctl, - .ndo_set_multicast_list = set_multicast_list, -}; - -/* - * This is the real probe routine. Linux has a history of friendly device - * probes on the ISA bus. A good device probes avoids doing writes, and - * verifies that the correct device exists and functions. - */ -static int __init cops_probe1(struct net_device *dev, int ioaddr) -{ - struct cops_local *lp; - static unsigned version_printed; - int board = board_type; - int retval; - - if(cops_debug && version_printed++ == 0) - printk("%s", version); - - /* Grab the region so no one else tries to probe our ioports. */ - if (!request_region(ioaddr, COPS_IO_EXTENT, dev->name)) - return -EBUSY; - - /* - * Since this board has jumpered interrupts, allocate the interrupt - * vector now. There is no point in waiting since no other device - * can use the interrupt, and this marks the irq as busy. Jumpered - * interrupts are typically not reported by the boards, and we must - * used AutoIRQ to find them. - */ - dev->irq = irq; - switch (dev->irq) - { - case 0: - /* COPS AutoIRQ routine */ - dev->irq = cops_irq(ioaddr, board); - if (dev->irq) - break; - /* No IRQ found on this port, fallthrough */ - case 1: - retval = -EINVAL; - goto err_out; - - /* Fixup for users that don't know that IRQ 2 is really - * IRQ 9, or don't know which one to set. - */ - case 2: - dev->irq = 9; - break; - - /* Polled operation requested. Although irq of zero passed as - * a parameter tells the init routines to probe, we'll - * overload it to denote polled operation at runtime. - */ - case 0xff: - dev->irq = 0; - break; - - default: - break; - } - - /* Reserve any actual interrupt. */ - if (dev->irq) { - retval = request_irq(dev->irq, cops_interrupt, 0, dev->name, dev); - if (retval) - goto err_out; - } - - dev->base_addr = ioaddr; - - lp = netdev_priv(dev); - spin_lock_init(&lp->lock); - - /* Copy local board variable to lp struct. */ - lp->board = board; - - dev->netdev_ops = &cops_netdev_ops; - dev->watchdog_timeo = HZ * 2; - - - /* Tell the user where the card is and what mode we're in. */ - if(board==DAYNA) - printk("%s: %s at %#3x, using IRQ %d, in Dayna mode.\n", - dev->name, cardname, ioaddr, dev->irq); - if(board==TANGENT) { - if(dev->irq) - printk("%s: %s at %#3x, IRQ %d, in Tangent mode\n", - dev->name, cardname, ioaddr, dev->irq); - else - printk("%s: %s at %#3x, using polled IO, in Tangent mode.\n", - dev->name, cardname, ioaddr); - - } - return 0; - -err_out: - release_region(ioaddr, COPS_IO_EXTENT); - return retval; -} - -static int __init cops_irq (int ioaddr, int board) -{ /* - * This does not use the IRQ to determine where the IRQ is. We just - * assume that when we get a correct status response that it's the IRQ. - * This really just verifies the IO port but since we only have access - * to such a small number of IRQs (5, 4, 3) this is not bad. - * This will probably not work for more than one card. - */ - int irqaddr=0; - int i, x, status; - - if(board==DAYNA) - { - outb(0, ioaddr+DAYNA_RESET); - inb(ioaddr+DAYNA_RESET); - mdelay(333); - } - if(board==TANGENT) - { - inb(ioaddr); - outb(0, ioaddr); - outb(0, ioaddr+TANG_RESET); - } - - for(i=0; cops_irqlist[i] !=0; i++) - { - irqaddr = cops_irqlist[i]; - for(x = 0xFFFF; x>0; x --) /* wait for response */ - { - if(board==DAYNA) - { - status = (inb(ioaddr+DAYNA_CARD_STATUS)&3); - if(status == 1) - return irqaddr; - } - if(board==TANGENT) - { - if((inb(ioaddr+TANG_CARD_STATUS)& TANG_TX_READY) !=0) - return irqaddr; - } - } - } - return 0; /* no IRQ found */ -} - -/* - * Open/initialize the board. This is called (in the current kernel) - * sometime after booting when the 'ifconfig' program is run. - */ -static int cops_open(struct net_device *dev) -{ - struct cops_local *lp = netdev_priv(dev); - - if(dev->irq==0) - { - /* - * I don't know if the Dayna-style boards support polled - * operation. For now, only allow it for Tangent. - */ - if(lp->board==TANGENT) /* Poll 20 times per second */ - { - init_timer(&cops_timer); - cops_timer.function = cops_poll; - cops_timer.data = (unsigned long)dev; - cops_timer.expires = jiffies + HZ/20; - add_timer(&cops_timer); - } - else - { - printk(KERN_WARNING "%s: No irq line set\n", dev->name); - return -EAGAIN; - } - } - - cops_jumpstart(dev); /* Start the card up. */ - - netif_start_queue(dev); - return 0; -} - -/* - * This allows for a dynamic start/restart of the entire card. - */ -static int cops_jumpstart(struct net_device *dev) -{ - struct cops_local *lp = netdev_priv(dev); - - /* - * Once the card has the firmware loaded and has acquired - * the nodeid, if it is reset it will lose it all. - */ - cops_reset(dev,1); /* Need to reset card before load firmware. */ - cops_load(dev); /* Load the firmware. */ - - /* - * If atalkd already gave us a nodeid we will use that - * one again, else we wait for atalkd to give us a nodeid - * in cops_ioctl. This may cause a problem if someone steals - * our nodeid while we are resetting. - */ - if(lp->nodeid == 1) - cops_nodeid(dev,lp->node_acquire); - - return 0; -} - -static void tangent_wait_reset(int ioaddr) -{ - int timeout=0; - - while(timeout++ < 5 && (inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0) - mdelay(1); /* Wait 1 second */ -} - -/* - * Reset the LocalTalk board. - */ -static void cops_reset(struct net_device *dev, int sleep) -{ - struct cops_local *lp = netdev_priv(dev); - int ioaddr=dev->base_addr; - - if(lp->board==TANGENT) - { - inb(ioaddr); /* Clear request latch. */ - outb(0,ioaddr); /* Clear the TANG_TX_READY flop. */ - outb(0, ioaddr+TANG_RESET); /* Reset the adapter. */ - - tangent_wait_reset(ioaddr); - outb(0, ioaddr+TANG_CLEAR_INT); - } - if(lp->board==DAYNA) - { - outb(0, ioaddr+DAYNA_RESET); /* Assert the reset port */ - inb(ioaddr+DAYNA_RESET); /* Clear the reset */ - if (sleep) - msleep(333); - else - mdelay(333); - } - - netif_wake_queue(dev); -} - -static void cops_load (struct net_device *dev) -{ - struct ifreq ifr; - struct ltfirmware *ltf= (struct ltfirmware *)&ifr.ifr_ifru; - struct cops_local *lp = netdev_priv(dev); - int ioaddr=dev->base_addr; - int length, i = 0; - - strcpy(ifr.ifr_name,"lt0"); - - /* Get card's firmware code and do some checks on it. */ -#ifdef CONFIG_COPS_DAYNA - if(lp->board==DAYNA) - { - ltf->length=sizeof(ffdrv_code); - ltf->data=ffdrv_code; - } - else -#endif -#ifdef CONFIG_COPS_TANGENT - if(lp->board==TANGENT) - { - ltf->length=sizeof(ltdrv_code); - ltf->data=ltdrv_code; - } - else -#endif - { - printk(KERN_INFO "%s; unsupported board type.\n", dev->name); - return; - } - - /* Check to make sure firmware is correct length. */ - if(lp->board==DAYNA && ltf->length!=5983) - { - printk(KERN_WARNING "%s: Firmware is not length of FFDRV.BIN.\n", dev->name); - return; - } - if(lp->board==TANGENT && ltf->length!=2501) - { - printk(KERN_WARNING "%s: Firmware is not length of DRVCODE.BIN.\n", dev->name); - return; - } - - if(lp->board==DAYNA) - { - /* - * We must wait for a status response - * with the DAYNA board. - */ - while(++i<65536) - { - if((inb(ioaddr+DAYNA_CARD_STATUS)&3)==1) - break; - } - - if(i==65536) - return; - } - - /* - * Upload the firmware and kick. Byte-by-byte works nicely here. - */ - i=0; - length = ltf->length; - while(length--) - { - outb(ltf->data[i], ioaddr); - i++; - } - - if(cops_debug > 1) - printk("%s: Uploaded firmware - %d bytes of %d bytes.\n", - dev->name, i, ltf->length); - - if(lp->board==DAYNA) /* Tell Dayna to run the firmware code. */ - outb(1, ioaddr+DAYNA_INT_CARD); - else /* Tell Tang to run the firmware code. */ - inb(ioaddr); - - if(lp->board==TANGENT) - { - tangent_wait_reset(ioaddr); - inb(ioaddr); /* Clear initial ready signal. */ - } -} - -/* - * Get the LocalTalk Nodeid from the card. We can suggest - * any nodeid 1-254. The card will try and get that exact - * address else we can specify 0 as the nodeid and the card - * will autoprobe for a nodeid. - */ -static int cops_nodeid (struct net_device *dev, int nodeid) -{ - struct cops_local *lp = netdev_priv(dev); - int ioaddr = dev->base_addr; - - if(lp->board == DAYNA) - { - /* Empty any pending adapter responses. */ - while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0) - { - outb(0, ioaddr+COPS_CLEAR_INT); /* Clear interrupts. */ - if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST) - cops_rx(dev); /* Kick any packets waiting. */ - schedule(); - } - - outb(2, ioaddr); /* Output command packet length as 2. */ - outb(0, ioaddr); - outb(LAP_INIT, ioaddr); /* Send LAP_INIT command byte. */ - outb(nodeid, ioaddr); /* Suggest node address. */ - } - - if(lp->board == TANGENT) - { - /* Empty any pending adapter responses. */ - while(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY) - { - outb(0, ioaddr+COPS_CLEAR_INT); /* Clear interrupt. */ - cops_rx(dev); /* Kick out packets waiting. */ - schedule(); - } - - /* Not sure what Tangent does if nodeid picked is used. */ - if(nodeid == 0) /* Seed. */ - nodeid = jiffies&0xFF; /* Get a random try */ - outb(2, ioaddr); /* Command length LSB */ - outb(0, ioaddr); /* Command length MSB */ - outb(LAP_INIT, ioaddr); /* Send LAP_INIT byte */ - outb(nodeid, ioaddr); /* LAP address hint. */ - outb(0xFF, ioaddr); /* Int. level to use */ - } - - lp->node_acquire=0; /* Set nodeid holder to 0. */ - while(lp->node_acquire==0) /* Get *True* nodeid finally. */ - { - outb(0, ioaddr+COPS_CLEAR_INT); /* Clear any interrupt. */ - - if(lp->board == DAYNA) - { - if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST) - cops_rx(dev); /* Grab the nodeid put in lp->node_acquire. */ - } - if(lp->board == TANGENT) - { - if(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY) - cops_rx(dev); /* Grab the nodeid put in lp->node_acquire. */ - } - schedule(); - } - - if(cops_debug > 1) - printk(KERN_DEBUG "%s: Node ID %d has been acquired.\n", - dev->name, lp->node_acquire); - - lp->nodeid=1; /* Set got nodeid to 1. */ - - return 0; -} - -/* - * Poll the Tangent type cards to see if we have work. - */ - -static void cops_poll(unsigned long ltdev) -{ - int ioaddr, status; - int boguscount = 0; - - struct net_device *dev = (struct net_device *)ltdev; - - del_timer(&cops_timer); - - if(dev == NULL) - return; /* We've been downed */ - - ioaddr = dev->base_addr; - do { - status=inb(ioaddr+TANG_CARD_STATUS); - if(status & TANG_RX_READY) - cops_rx(dev); - if(status & TANG_TX_READY) - netif_wake_queue(dev); - status = inb(ioaddr+TANG_CARD_STATUS); - } while((++boguscount < 20) && (status&(TANG_RX_READY|TANG_TX_READY))); - - /* poll 20 times per second */ - cops_timer.expires = jiffies + HZ/20; - add_timer(&cops_timer); -} - -/* - * The typical workload of the driver: - * Handle the network interface interrupts. - */ -static irqreturn_t cops_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct cops_local *lp; - int ioaddr, status; - int boguscount = 0; - - ioaddr = dev->base_addr; - lp = netdev_priv(dev); - - if(lp->board==DAYNA) - { - do { - outb(0, ioaddr + COPS_CLEAR_INT); - status=inb(ioaddr+DAYNA_CARD_STATUS); - if((status&0x03)==DAYNA_RX_REQUEST) - cops_rx(dev); - netif_wake_queue(dev); - } while(++boguscount < 20); - } - else - { - do { - status=inb(ioaddr+TANG_CARD_STATUS); - if(status & TANG_RX_READY) - cops_rx(dev); - if(status & TANG_TX_READY) - netif_wake_queue(dev); - status=inb(ioaddr+TANG_CARD_STATUS); - } while((++boguscount < 20) && (status&(TANG_RX_READY|TANG_TX_READY))); - } - - return IRQ_HANDLED; -} - -/* - * We have a good packet(s), get it/them out of the buffers. - */ -static void cops_rx(struct net_device *dev) -{ - int pkt_len = 0; - int rsp_type = 0; - struct sk_buff *skb = NULL; - struct cops_local *lp = netdev_priv(dev); - int ioaddr = dev->base_addr; - int boguscount = 0; - unsigned long flags; - - - spin_lock_irqsave(&lp->lock, flags); - - if(lp->board==DAYNA) - { - outb(0, ioaddr); /* Send out Zero length. */ - outb(0, ioaddr); - outb(DATA_READ, ioaddr); /* Send read command out. */ - - /* Wait for DMA to turn around. */ - while(++boguscount<1000000) - { - barrier(); - if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_READY) - break; - } - - if(boguscount==1000000) - { - printk(KERN_WARNING "%s: DMA timed out.\n",dev->name); - spin_unlock_irqrestore(&lp->lock, flags); - return; - } - } - - /* Get response length. */ - if(lp->board==DAYNA) - pkt_len = inb(ioaddr) & 0xFF; - else - pkt_len = inb(ioaddr) & 0x00FF; - pkt_len |= (inb(ioaddr) << 8); - /* Input IO code. */ - rsp_type=inb(ioaddr); - - /* Malloc up new buffer. */ - skb = dev_alloc_skb(pkt_len); - if(skb == NULL) - { - printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", - dev->name); - dev->stats.rx_dropped++; - while(pkt_len--) /* Discard packet */ - inb(ioaddr); - spin_unlock_irqrestore(&lp->lock, flags); - return; - } - skb->dev = dev; - skb_put(skb, pkt_len); - skb->protocol = htons(ETH_P_LOCALTALK); - - insb(ioaddr, skb->data, pkt_len); /* Eat the Data */ - - if(lp->board==DAYNA) - outb(1, ioaddr+DAYNA_INT_CARD); /* Interrupt the card */ - - spin_unlock_irqrestore(&lp->lock, flags); /* Restore interrupts. */ - - /* Check for bad response length */ - if(pkt_len < 0 || pkt_len > MAX_LLAP_SIZE) - { - printk(KERN_WARNING "%s: Bad packet length of %d bytes.\n", - dev->name, pkt_len); - dev->stats.tx_errors++; - dev_kfree_skb_any(skb); - return; - } - - /* Set nodeid and then get out. */ - if(rsp_type == LAP_INIT_RSP) - { /* Nodeid taken from received packet. */ - lp->node_acquire = skb->data[0]; - dev_kfree_skb_any(skb); - return; - } - - /* One last check to make sure we have a good packet. */ - if(rsp_type != LAP_RESPONSE) - { - printk(KERN_WARNING "%s: Bad packet type %d.\n", dev->name, rsp_type); - dev->stats.tx_errors++; - dev_kfree_skb_any(skb); - return; - } - - skb_reset_mac_header(skb); /* Point to entire packet. */ - skb_pull(skb,3); - skb_reset_transport_header(skb); /* Point to data (Skip header). */ - - /* Update the counters. */ - dev->stats.rx_packets++; - dev->stats.rx_bytes += skb->len; - - /* Send packet to a higher place. */ - netif_rx(skb); -} - -static void cops_timeout(struct net_device *dev) -{ - struct cops_local *lp = netdev_priv(dev); - int ioaddr = dev->base_addr; - - dev->stats.tx_errors++; - if(lp->board==TANGENT) - { - if((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0) - printk(KERN_WARNING "%s: No TX complete interrupt.\n", dev->name); - } - printk(KERN_WARNING "%s: Transmit timed out.\n", dev->name); - cops_jumpstart(dev); /* Restart the card. */ - dev->trans_start = jiffies; /* prevent tx timeout */ - netif_wake_queue(dev); -} - - -/* - * Make the card transmit a LocalTalk packet. - */ - -static netdev_tx_t cops_send_packet(struct sk_buff *skb, - struct net_device *dev) -{ - struct cops_local *lp = netdev_priv(dev); - int ioaddr = dev->base_addr; - unsigned long flags; - - /* - * Block a timer-based transmit from overlapping. - */ - - netif_stop_queue(dev); - - spin_lock_irqsave(&lp->lock, flags); - if(lp->board == DAYNA) /* Wait for adapter transmit buffer. */ - while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0) - cpu_relax(); - if(lp->board == TANGENT) /* Wait for adapter transmit buffer. */ - while((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0) - cpu_relax(); - - /* Output IO length. */ - outb(skb->len, ioaddr); - if(lp->board == DAYNA) - outb(skb->len >> 8, ioaddr); - else - outb((skb->len >> 8)&0x0FF, ioaddr); - - /* Output IO code. */ - outb(LAP_WRITE, ioaddr); - - if(lp->board == DAYNA) /* Check the transmit buffer again. */ - while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0); - - outsb(ioaddr, skb->data, skb->len); /* Send out the data. */ - - if(lp->board==DAYNA) /* Dayna requires you kick the card */ - outb(1, ioaddr+DAYNA_INT_CARD); - - spin_unlock_irqrestore(&lp->lock, flags); /* Restore interrupts. */ - - /* Done sending packet, update counters and cleanup. */ - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - dev_kfree_skb (skb); - return NETDEV_TX_OK; -} - -/* - * Dummy function to keep the Appletalk layer happy. - */ - -static void set_multicast_list(struct net_device *dev) -{ - if(cops_debug >= 3) - printk("%s: set_multicast_list executed\n", dev->name); -} - -/* - * System ioctls for the COPS LocalTalk card. - */ - -static int cops_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - struct cops_local *lp = netdev_priv(dev); - struct sockaddr_at *sa = (struct sockaddr_at *)&ifr->ifr_addr; - struct atalk_addr *aa = (struct atalk_addr *)&lp->node_addr; - - switch(cmd) - { - case SIOCSIFADDR: - /* Get and set the nodeid and network # atalkd wants. */ - cops_nodeid(dev, sa->sat_addr.s_node); - aa->s_net = sa->sat_addr.s_net; - aa->s_node = lp->node_acquire; - - /* Set broardcast address. */ - dev->broadcast[0] = 0xFF; - - /* Set hardware address. */ - dev->dev_addr[0] = aa->s_node; - dev->addr_len = 1; - return 0; - - case SIOCGIFADDR: - sa->sat_addr.s_net = aa->s_net; - sa->sat_addr.s_node = aa->s_node; - return 0; - - default: - return -EOPNOTSUPP; - } -} - -/* - * The inverse routine to cops_open(). - */ - -static int cops_close(struct net_device *dev) -{ - struct cops_local *lp = netdev_priv(dev); - - /* If we were running polled, yank the timer. - */ - if(lp->board==TANGENT && dev->irq==0) - del_timer(&cops_timer); - - netif_stop_queue(dev); - return 0; -} - - -#ifdef MODULE -static struct net_device *cops_dev; - -MODULE_LICENSE("GPL"); -module_param(io, int, 0); -module_param(irq, int, 0); -module_param(board_type, int, 0); - -static int __init cops_module_init(void) -{ - if (io == 0) - printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n", - cardname); - cops_dev = cops_probe(-1); - if (IS_ERR(cops_dev)) - return PTR_ERR(cops_dev); - return 0; -} - -static void __exit cops_module_exit(void) -{ - unregister_netdev(cops_dev); - cleanup_card(cops_dev); - free_netdev(cops_dev); -} -module_init(cops_module_init); -module_exit(cops_module_exit); -#endif /* MODULE */ diff --git a/drivers/staging/appletalk/cops.h b/drivers/staging/appletalk/cops.h deleted file mode 100644 index fd2750b269c8..000000000000 --- a/drivers/staging/appletalk/cops.h +++ /dev/null @@ -1,60 +0,0 @@ -/* cops.h: LocalTalk driver for Linux. - * - * Authors: - * - Jay Schulist - */ - -#ifndef __LINUX_COPSLTALK_H -#define __LINUX_COPSLTALK_H - -#ifdef __KERNEL__ - -/* Max LLAP size we will accept. */ -#define MAX_LLAP_SIZE 603 - -/* Tangent */ -#define TANG_CARD_STATUS 1 -#define TANG_CLEAR_INT 1 -#define TANG_RESET 3 - -#define TANG_TX_READY 1 -#define TANG_RX_READY 2 - -/* Dayna */ -#define DAYNA_CMD_DATA 0 -#define DAYNA_CLEAR_INT 1 -#define DAYNA_CARD_STATUS 2 -#define DAYNA_INT_CARD 3 -#define DAYNA_RESET 4 - -#define DAYNA_RX_READY 0 -#define DAYNA_TX_READY 1 -#define DAYNA_RX_REQUEST 3 - -/* Same on both card types */ -#define COPS_CLEAR_INT 1 - -/* LAP response codes received from the cards. */ -#define LAP_INIT 1 /* Init cmd */ -#define LAP_INIT_RSP 2 /* Init response */ -#define LAP_WRITE 3 /* Write cmd */ -#define DATA_READ 4 /* Data read */ -#define LAP_RESPONSE 4 /* Received ALAP frame response */ -#define LAP_GETSTAT 5 /* Get LAP and HW status */ -#define LAP_RSPSTAT 6 /* Status response */ - -#endif - -/* - * Structure to hold the firmware information. - */ -struct ltfirmware -{ - unsigned int length; - const unsigned char *data; -}; - -#define DAYNA 1 -#define TANGENT 2 - -#endif diff --git a/drivers/staging/appletalk/cops_ffdrv.h b/drivers/staging/appletalk/cops_ffdrv.h deleted file mode 100644 index b02005087c1b..000000000000 --- a/drivers/staging/appletalk/cops_ffdrv.h +++ /dev/null @@ -1,532 +0,0 @@ - -/* - * The firmware this driver downloads into the Localtalk card is a - * separate program and is not GPL'd source code, even though the Linux - * side driver and the routine that loads this data into the card are. - * - * It is taken from the COPS SDK and is under the following license - * - * This material is licensed to you strictly for use in conjunction with - * the use of COPS LocalTalk adapters. - * There is no charge for this SDK. And no waranty express or implied - * about its fitness for any purpose. However, we will cheerefully - * refund every penny you paid for this SDK... - * Regards, - * - * Thomas F. Divine - * Chief Scientist - */ - - -/* cops_ffdrv.h: LocalTalk driver firmware dump for Linux. - * - * Authors: - * - Jay Schulist - */ - - -#ifdef CONFIG_COPS_DAYNA - -static const unsigned char ffdrv_code[] = { - 58,3,0,50,228,149,33,255,255,34,226,149, - 249,17,40,152,33,202,154,183,237,82,77,68, - 11,107,98,19,54,0,237,176,175,50,80,0, - 62,128,237,71,62,32,237,57,51,62,12,237, - 57,50,237,57,54,62,6,237,57,52,62,12, - 237,57,49,33,107,137,34,32,128,33,83,130, - 34,40,128,33,86,130,34,42,128,33,112,130, - 34,36,128,33,211,130,34,38,128,62,0,237, - 57,16,33,63,148,34,34,128,237,94,205,15, - 130,251,205,168,145,24,141,67,111,112,121,114, - 105,103,104,116,32,40,67,41,32,49,57,56, - 56,32,45,32,68,97,121,110,97,32,67,111, - 109,109,117,110,105,99,97,116,105,111,110,115, - 32,32,32,65,108,108,32,114,105,103,104,116, - 115,32,114,101,115,101,114,118,101,100,46,32, - 32,40,68,40,68,7,16,8,34,7,22,6, - 16,5,12,4,8,3,6,140,0,16,39,128, - 0,4,96,10,224,6,0,7,126,2,64,11, - 118,12,6,13,0,14,193,15,0,5,96,3, - 192,1,64,9,8,62,9,211,66,62,192,211, - 66,62,100,61,32,253,6,28,33,205,129,14, - 66,237,163,194,253,129,6,28,33,205,129,14, - 64,237,163,194,9,130,201,62,47,50,71,152, - 62,47,211,68,58,203,129,237,57,20,58,204, - 129,237,57,21,33,77,152,54,132,205,233,129, - 58,228,149,254,209,40,6,56,4,62,0,24, - 2,219,96,33,233,149,119,230,62,33,232,149, - 119,213,33,8,152,17,7,0,25,119,19,25, - 119,209,201,251,237,77,245,197,213,229,221,229, - 205,233,129,62,1,50,106,137,205,158,139,221, - 225,225,209,193,241,251,237,77,245,197,213,219, - 72,237,56,16,230,46,237,57,16,237,56,12, - 58,72,152,183,32,26,6,20,17,128,2,237, - 56,46,187,32,35,237,56,47,186,32,29,219, - 72,230,1,32,3,5,32,232,175,50,72,152, - 229,221,229,62,1,50,106,137,205,158,139,221, - 225,225,24,25,62,1,50,72,152,58,201,129, - 237,57,12,58,202,129,237,57,13,237,56,16, - 246,17,237,57,16,209,193,241,251,237,77,245, - 197,229,213,221,229,237,56,16,230,17,237,57, - 16,237,56,20,58,34,152,246,16,246,8,211, - 68,62,6,61,32,253,58,34,152,246,8,211, - 68,58,203,129,237,57,20,58,204,129,237,57, - 21,237,56,16,246,34,237,57,16,221,225,209, - 225,193,241,251,237,77,33,2,0,57,126,230, - 3,237,100,1,40,2,246,128,230,130,245,62, - 5,211,64,241,211,64,201,229,213,243,237,56, - 16,230,46,237,57,16,237,56,12,251,70,35, - 35,126,254,175,202,77,133,254,129,202,15,133, - 230,128,194,191,132,43,58,44,152,119,33,76, - 152,119,35,62,132,119,120,254,255,40,4,58, - 49,152,119,219,72,43,43,112,17,3,0,237, - 56,52,230,248,237,57,52,219,72,230,1,194, - 141,131,209,225,237,56,52,246,6,237,57,52, - 62,1,55,251,201,62,3,211,66,62,192,211, - 66,62,48,211,66,0,0,219,66,230,1,40, - 4,219,67,24,240,205,203,135,58,75,152,254, - 255,202,128,132,58,49,152,254,161,250,207,131, - 58,34,152,211,68,62,10,211,66,62,128,211, - 66,62,11,211,66,62,6,211,66,24,0,62, - 14,211,66,62,33,211,66,62,1,211,66,62, - 64,211,66,62,3,211,66,62,209,211,66,62, - 100,71,219,66,230,1,32,6,5,32,247,195, - 248,132,219,67,71,58,44,152,184,194,248,132, - 62,100,71,219,66,230,1,32,6,5,32,247, - 195,248,132,219,67,62,100,71,219,66,230,1, - 32,6,5,32,247,195,248,132,219,67,254,133, - 32,7,62,0,50,74,152,24,17,254,173,32, - 7,62,1,50,74,152,24,6,254,141,194,248, - 132,71,209,225,58,49,152,254,132,32,10,62, - 50,205,2,134,205,144,135,24,27,254,140,32, - 15,62,110,205,2,134,62,141,184,32,5,205, - 144,135,24,8,62,10,205,2,134,205,8,134, - 62,1,50,106,137,205,158,139,237,56,52,246, - 6,237,57,52,175,183,251,201,62,20,135,237, - 57,20,175,237,57,21,237,56,16,246,2,237, - 57,16,237,56,20,95,237,56,21,123,254,10, - 48,244,237,56,16,230,17,237,57,16,209,225, - 205,144,135,62,1,50,106,137,205,158,139,237, - 56,52,246,6,237,57,52,175,183,251,201,209, - 225,243,219,72,230,1,40,13,62,10,211,66, - 0,0,219,66,230,192,202,226,132,237,56,52, - 246,6,237,57,52,62,1,55,251,201,205,203, - 135,62,1,50,106,137,205,158,139,237,56,52, - 246,6,237,57,52,183,251,201,209,225,62,1, - 50,106,137,205,158,139,237,56,52,246,6,237, - 57,52,62,2,55,251,201,209,225,243,219,72, - 230,1,202,213,132,62,10,211,66,0,0,219, - 66,230,192,194,213,132,229,62,1,50,106,137, - 42,40,152,205,65,143,225,17,3,0,205,111, - 136,62,6,211,66,58,44,152,211,66,237,56, - 52,246,6,237,57,52,183,251,201,209,197,237, - 56,52,230,248,237,57,52,219,72,230,1,32, - 15,193,225,237,56,52,246,6,237,57,52,62, - 1,55,251,201,14,23,58,37,152,254,0,40, - 14,14,2,254,1,32,5,62,140,119,24,3, - 62,132,119,43,43,197,205,203,135,193,62,1, - 211,66,62,64,211,66,62,3,211,66,62,193, - 211,66,62,100,203,39,71,219,66,230,1,32, - 6,5,32,247,195,229,133,33,238,151,219,67, - 71,58,44,152,184,194,229,133,119,62,100,71, - 219,66,230,1,32,6,5,32,247,195,229,133, - 219,67,35,119,13,32,234,193,225,62,1,50, - 106,137,205,158,139,237,56,52,246,6,237,57, - 52,175,183,251,201,33,234,151,35,35,62,255, - 119,193,225,62,1,50,106,137,205,158,139,237, - 56,52,246,6,237,57,52,175,251,201,243,61, - 32,253,251,201,62,3,211,66,62,192,211,66, - 58,49,152,254,140,32,19,197,229,213,17,181, - 129,33,185,129,1,2,0,237,176,209,225,193, - 24,27,229,213,33,187,129,58,49,152,230,15, - 87,30,2,237,92,25,17,181,129,126,18,19, - 35,126,18,209,225,58,34,152,246,8,211,68, - 58,49,152,254,165,40,14,254,164,40,10,62, - 10,211,66,62,224,211,66,24,25,58,74,152, - 254,0,40,10,62,10,211,66,62,160,211,66, - 24,8,62,10,211,66,62,128,211,66,62,11, - 211,66,62,6,211,66,205,147,143,62,5,211, - 66,62,224,211,66,62,5,211,66,62,96,211, - 66,62,5,61,32,253,62,5,211,66,62,224, - 211,66,62,14,61,32,253,62,5,211,66,62, - 233,211,66,62,128,211,66,58,181,129,61,32, - 253,62,1,211,66,62,192,211,66,1,254,19, - 237,56,46,187,32,6,13,32,247,195,226,134, - 62,192,211,66,0,0,219,66,203,119,40,250, - 219,66,203,87,40,250,243,237,56,16,230,17, - 237,57,16,237,56,20,251,62,5,211,66,62, - 224,211,66,58,182,129,61,32,253,229,33,181, - 129,58,183,129,203,63,119,35,58,184,129,119, - 225,62,10,211,66,62,224,211,66,62,11,211, - 66,62,118,211,66,62,47,211,68,62,5,211, - 66,62,233,211,66,58,181,129,61,32,253,62, - 5,211,66,62,224,211,66,58,182,129,61,32, - 253,62,5,211,66,62,96,211,66,201,229,213, - 58,50,152,230,15,87,30,2,237,92,33,187, - 129,25,17,181,129,126,18,35,19,126,18,209, - 225,58,71,152,246,8,211,68,58,50,152,254, - 165,40,14,254,164,40,10,62,10,211,66,62, - 224,211,66,24,8,62,10,211,66,62,128,211, - 66,62,11,211,66,62,6,211,66,195,248,135, - 62,3,211,66,62,192,211,66,197,229,213,17, - 181,129,33,183,129,1,2,0,237,176,209,225, - 193,62,47,211,68,62,10,211,66,62,224,211, - 66,62,11,211,66,62,118,211,66,62,1,211, - 66,62,0,211,66,205,147,143,195,16,136,62, - 3,211,66,62,192,211,66,197,229,213,17,181, - 129,33,183,129,1,2,0,237,176,209,225,193, - 62,47,211,68,62,10,211,66,62,224,211,66, - 62,11,211,66,62,118,211,66,205,147,143,62, - 5,211,66,62,224,211,66,62,5,211,66,62, - 96,211,66,62,5,61,32,253,62,5,211,66, - 62,224,211,66,62,14,61,32,253,62,5,211, - 66,62,233,211,66,62,128,211,66,58,181,129, - 61,32,253,62,1,211,66,62,192,211,66,1, - 254,19,237,56,46,187,32,6,13,32,247,195, - 88,136,62,192,211,66,0,0,219,66,203,119, - 40,250,219,66,203,87,40,250,62,5,211,66, - 62,224,211,66,58,182,129,61,32,253,62,5, - 211,66,62,96,211,66,201,197,14,67,6,0, - 62,3,211,66,62,192,211,66,62,48,211,66, - 0,0,219,66,230,1,40,4,219,67,24,240, - 62,5,211,66,62,233,211,66,62,128,211,66, - 58,181,129,61,32,253,237,163,29,62,192,211, - 66,219,66,230,4,40,250,237,163,29,32,245, - 219,66,230,4,40,250,62,255,71,219,66,230, - 4,40,3,5,32,247,219,66,230,4,40,250, - 62,5,211,66,62,224,211,66,58,182,129,61, - 32,253,62,5,211,66,62,96,211,66,58,71, - 152,254,1,202,18,137,62,16,211,66,62,56, - 211,66,62,14,211,66,62,33,211,66,62,1, - 211,66,62,248,211,66,237,56,48,246,153,230, - 207,237,57,48,62,3,211,66,62,221,211,66, - 193,201,58,71,152,211,68,62,10,211,66,62, - 128,211,66,62,11,211,66,62,6,211,66,62, - 6,211,66,58,44,152,211,66,62,16,211,66, - 62,56,211,66,62,48,211,66,0,0,62,14, - 211,66,62,33,211,66,62,1,211,66,62,248, - 211,66,237,56,48,246,145,246,8,230,207,237, - 57,48,62,3,211,66,62,221,211,66,193,201, - 44,3,1,0,70,69,1,245,197,213,229,175, - 50,72,152,237,56,16,230,46,237,57,16,237, - 56,12,62,1,211,66,0,0,219,66,95,230, - 160,32,3,195,20,139,123,230,96,194,72,139, - 62,48,211,66,62,1,211,66,62,64,211,66, - 237,91,40,152,205,207,143,25,43,55,237,82, - 218,70,139,34,42,152,98,107,58,44,152,190, - 194,210,138,35,35,62,130,190,194,200,137,62, - 1,50,48,152,62,175,190,202,82,139,62,132, - 190,32,44,50,50,152,62,47,50,71,152,229, - 175,50,106,137,42,40,152,205,65,143,225,54, - 133,43,70,58,44,152,119,43,112,17,3,0, - 62,10,205,2,134,205,111,136,195,158,138,62, - 140,190,32,19,50,50,152,58,233,149,230,4, - 202,222,138,62,1,50,71,152,195,219,137,126, - 254,160,250,185,138,254,166,242,185,138,50,50, - 152,43,126,35,229,213,33,234,149,95,22,0, - 25,126,254,132,40,18,254,140,40,14,58,50, - 152,230,15,87,126,31,21,242,65,138,56,2, - 175,119,58,50,152,230,15,87,58,233,149,230, - 62,31,21,242,85,138,218,98,138,209,225,195, - 20,139,58,50,152,33,100,137,230,15,95,22, - 0,25,126,50,71,152,209,225,58,50,152,254, - 164,250,135,138,58,73,152,254,0,40,4,54, - 173,24,2,54,133,43,70,58,44,152,119,43, - 112,17,3,0,205,70,135,175,50,106,137,205, - 208,139,58,199,129,237,57,12,58,200,129,237, - 57,13,237,56,16,246,17,237,57,16,225,209, - 193,241,251,237,77,62,129,190,194,227,138,54, - 130,43,70,58,44,152,119,43,112,17,3,0, - 205,144,135,195,20,139,35,35,126,254,132,194, - 227,138,175,50,106,137,205,158,139,24,42,58, - 201,154,254,1,40,7,62,1,50,106,137,24, - 237,58,106,137,254,1,202,222,138,62,128,166, - 194,222,138,221,229,221,33,67,152,205,127,142, - 205,109,144,221,225,225,209,193,241,251,237,77, - 58,106,137,254,1,202,44,139,58,50,152,254, - 164,250,44,139,58,73,152,238,1,50,73,152, - 221,229,221,33,51,152,205,127,142,221,225,62, - 1,50,106,137,205,158,139,195,13,139,24,208, - 24,206,24,204,230,64,40,3,195,20,139,195, - 20,139,43,126,33,8,152,119,35,58,44,152, - 119,43,237,91,35,152,205,203,135,205,158,139, - 195,13,139,175,50,78,152,62,3,211,66,62, - 192,211,66,201,197,33,4,0,57,126,35,102, - 111,62,1,50,106,137,219,72,205,141,139,193, - 201,62,1,50,78,152,34,40,152,54,0,35, - 35,54,0,195,163,139,58,78,152,183,200,229, - 33,181,129,58,183,129,119,35,58,184,129,119, - 225,62,47,211,68,62,14,211,66,62,193,211, - 66,62,10,211,66,62,224,211,66,62,11,211, - 66,62,118,211,66,195,3,140,58,78,152,183, - 200,58,71,152,211,68,254,69,40,4,254,70, - 32,17,58,73,152,254,0,40,10,62,10,211, - 66,62,160,211,66,24,8,62,10,211,66,62, - 128,211,66,62,11,211,66,62,6,211,66,62, - 6,211,66,58,44,152,211,66,62,16,211,66, - 62,56,211,66,62,48,211,66,0,0,219,66, - 230,1,40,4,219,67,24,240,62,14,211,66, - 62,33,211,66,42,40,152,205,65,143,62,1, - 211,66,62,248,211,66,237,56,48,246,145,246, - 8,230,207,237,57,48,62,3,211,66,62,221, - 211,66,201,62,16,211,66,62,56,211,66,62, - 48,211,66,0,0,219,66,230,1,40,4,219, - 67,24,240,62,14,211,66,62,33,211,66,62, - 1,211,66,62,248,211,66,237,56,48,246,153, - 230,207,237,57,48,62,3,211,66,62,221,211, - 66,201,229,213,33,234,149,95,22,0,25,126, - 254,132,40,4,254,140,32,2,175,119,123,209, - 225,201,6,8,14,0,31,48,1,12,16,250, - 121,201,33,4,0,57,94,35,86,33,2,0, - 57,126,35,102,111,221,229,34,89,152,237,83, - 91,152,221,33,63,152,205,127,142,58,81,152, - 50,82,152,58,80,152,135,50,80,152,205,162, - 140,254,3,56,16,58,81,152,135,60,230,15, - 50,81,152,175,50,80,152,24,23,58,79,152, - 205,162,140,254,3,48,13,58,81,152,203,63, - 50,81,152,62,255,50,79,152,58,81,152,50, - 82,152,58,79,152,135,50,79,152,62,32,50, - 83,152,50,84,152,237,56,16,230,17,237,57, - 16,219,72,62,192,50,93,152,62,93,50,94, - 152,58,93,152,61,50,93,152,32,9,58,94, - 152,61,50,94,152,40,44,62,170,237,57,20, - 175,237,57,21,237,56,16,246,2,237,57,16, - 219,72,230,1,202,29,141,237,56,20,71,237, - 56,21,120,254,10,48,237,237,56,16,230,17, - 237,57,16,243,62,14,211,66,62,65,211,66, - 251,58,39,152,23,23,60,50,39,152,71,58, - 82,152,160,230,15,40,22,71,14,10,219,66, - 230,16,202,186,141,219,72,230,1,202,186,141, - 13,32,239,16,235,42,89,152,237,91,91,152, - 205,47,131,48,7,61,202,186,141,195,227,141, - 221,225,33,0,0,201,221,33,55,152,205,127, - 142,58,84,152,61,50,84,152,40,19,58,82, - 152,246,1,50,82,152,58,79,152,246,1,50, - 79,152,195,29,141,221,225,33,1,0,201,221, - 33,59,152,205,127,142,58,80,152,246,1,50, - 80,152,58,82,152,135,246,1,50,82,152,58, - 83,152,61,50,83,152,194,29,141,221,225,33, - 2,0,201,221,229,33,0,0,57,17,4,0, - 25,126,50,44,152,230,128,50,85,152,58,85, - 152,183,40,6,221,33,88,2,24,4,221,33, - 150,0,58,44,152,183,40,53,60,40,50,60, - 40,47,61,61,33,86,152,119,35,119,35,54, - 129,175,50,48,152,221,43,221,229,225,124,181, - 40,42,33,86,152,17,3,0,205,189,140,17, - 232,3,27,123,178,32,251,58,48,152,183,40, - 224,58,44,152,71,62,7,128,230,127,71,58, - 85,152,176,50,44,152,24,162,221,225,201,183, - 221,52,0,192,221,52,1,192,221,52,2,192, - 221,52,3,192,55,201,245,62,1,211,100,241, - 201,245,62,1,211,96,241,201,33,2,0,57, - 126,35,102,111,237,56,48,230,175,237,57,48, - 62,48,237,57,49,125,237,57,32,124,237,57, - 33,62,0,237,57,34,62,88,237,57,35,62, - 0,237,57,36,237,57,37,33,128,2,125,237, - 57,38,124,237,57,39,237,56,48,246,97,230, - 207,237,57,48,62,0,237,57,0,62,0,211, - 96,211,100,201,33,2,0,57,126,35,102,111, - 237,56,48,230,175,237,57,48,62,12,237,57, - 49,62,76,237,57,32,62,0,237,57,33,237, - 57,34,125,237,57,35,124,237,57,36,62,0, - 237,57,37,33,128,2,125,237,57,38,124,237, - 57,39,237,56,48,246,97,230,207,237,57,48, - 62,1,211,96,201,33,2,0,57,126,35,102, - 111,229,237,56,48,230,87,237,57,48,125,237, - 57,40,124,237,57,41,62,0,237,57,42,62, - 67,237,57,43,62,0,237,57,44,58,106,137, - 254,1,32,5,33,6,0,24,3,33,128,2, - 125,237,57,46,124,237,57,47,237,56,50,230, - 252,246,2,237,57,50,225,201,33,4,0,57, - 94,35,86,33,2,0,57,126,35,102,111,237, - 56,48,230,87,237,57,48,125,237,57,40,124, - 237,57,41,62,0,237,57,42,62,67,237,57, - 43,62,0,237,57,44,123,237,57,46,122,237, - 57,47,237,56,50,230,244,246,0,237,57,50, - 237,56,48,246,145,230,207,237,57,48,201,213, - 237,56,46,95,237,56,47,87,237,56,46,111, - 237,56,47,103,183,237,82,32,235,33,128,2, - 183,237,82,209,201,213,237,56,38,95,237,56, - 39,87,237,56,38,111,237,56,39,103,183,237, - 82,32,235,33,128,2,183,237,82,209,201,245, - 197,1,52,0,237,120,230,253,237,121,193,241, - 201,245,197,1,52,0,237,120,246,2,237,121, - 193,241,201,33,2,0,57,126,35,102,111,126, - 35,110,103,201,33,0,0,34,102,152,34,96, - 152,34,98,152,33,202,154,34,104,152,237,91, - 104,152,42,226,149,183,237,82,17,0,255,25, - 34,100,152,203,124,40,6,33,0,125,34,100, - 152,42,104,152,35,35,35,229,205,120,139,193, - 201,205,186,149,229,42,40,152,35,35,35,229, - 205,39,144,193,124,230,3,103,221,117,254,221, - 116,255,237,91,42,152,35,35,35,183,237,82, - 32,12,17,5,0,42,42,152,205,171,149,242, - 169,144,42,40,152,229,205,120,139,193,195,198, - 149,237,91,42,152,42,98,152,25,34,98,152, - 19,19,19,42,102,152,25,34,102,152,237,91, - 100,152,33,158,253,25,237,91,102,152,205,171, - 149,242,214,144,33,0,0,34,102,152,62,1, - 50,95,152,205,225,144,195,198,149,58,95,152, - 183,200,237,91,96,152,42,102,152,205,171,149, - 242,5,145,237,91,102,152,33,98,2,25,237, - 91,96,152,205,171,149,250,37,145,237,91,96, - 152,42,102,152,183,237,82,32,7,42,98,152, - 125,180,40,13,237,91,102,152,42,96,152,205, - 171,149,242,58,145,237,91,104,152,42,102,152, - 25,35,35,35,229,205,120,139,193,175,50,95, - 152,201,195,107,139,205,206,149,250,255,243,205, - 225,144,251,58,230,149,183,194,198,149,17,1, - 0,42,98,152,205,171,149,250,198,149,62,1, - 50,230,149,237,91,96,152,42,104,152,25,221, - 117,252,221,116,253,237,91,104,152,42,96,152, - 25,35,35,35,221,117,254,221,116,255,35,35, - 35,229,205,39,144,124,230,3,103,35,35,35, - 221,117,250,221,116,251,235,221,110,252,221,102, - 253,115,35,114,35,54,4,62,1,211,100,211, - 84,195,198,149,33,0,0,34,102,152,34,96, - 152,34,98,152,33,202,154,34,104,152,237,91, - 104,152,42,226,149,183,237,82,17,0,255,25, - 34,100,152,33,109,152,54,0,33,107,152,229, - 205,240,142,193,62,47,50,34,152,62,132,50, - 49,152,205,241,145,205,61,145,58,39,152,60, - 50,39,152,24,241,205,206,149,251,255,33,109, - 152,126,183,202,198,149,110,221,117,251,33,109, - 152,54,0,221,126,251,254,1,40,28,254,3, - 40,101,254,4,202,190,147,254,5,202,147,147, - 254,8,40,87,33,107,152,229,205,240,142,195, - 198,149,58,201,154,183,32,21,33,111,152,126, - 50,229,149,205,52,144,33,110,152,110,38,0, - 229,205,11,142,193,237,91,96,152,42,104,152, - 25,221,117,254,221,116,255,35,35,54,2,17, - 2,0,43,43,115,35,114,58,44,152,35,35, - 119,58,228,149,35,119,62,1,211,100,211,84, - 62,1,50,201,154,24,169,205,153,142,58,231, - 149,183,40,250,175,50,231,149,33,110,152,126, - 254,255,40,91,58,233,149,230,63,183,40,83, - 94,22,0,33,234,149,25,126,183,40,13,33, - 110,152,94,33,234,150,25,126,254,3,32,36, - 205,81,148,125,180,33,110,152,94,22,0,40, - 17,33,234,149,25,54,0,33,107,152,229,205, - 240,142,193,195,198,149,33,234,150,25,54,0, - 33,110,152,94,22,0,33,234,149,25,126,50, - 49,152,254,132,32,37,62,47,50,34,152,42, - 107,152,229,33,110,152,229,205,174,140,193,193, - 125,180,33,110,152,94,22,0,33,234,150,202, - 117,147,25,52,195,120,147,58,49,152,254,140, - 32,7,62,1,50,34,152,24,210,62,32,50, - 106,152,24,19,58,49,152,95,58,106,152,163, - 183,58,106,152,32,11,203,63,50,106,152,58, - 106,152,183,32,231,254,2,40,51,254,4,40, - 38,254,8,40,26,254,16,40,13,254,32,32, - 158,62,165,50,49,152,62,69,24,190,62,164, - 50,49,152,62,70,24,181,62,163,50,49,152, - 175,24,173,62,162,50,49,152,62,1,24,164, - 62,161,50,49,152,62,3,24,155,25,54,0, - 221,126,251,254,8,40,7,58,230,149,183,202, - 32,146,33,107,152,229,205,240,142,193,211,84, - 195,198,149,237,91,96,152,42,104,152,25,221, - 117,254,221,116,255,35,35,54,6,17,2,0, - 43,43,115,35,114,58,228,149,35,35,119,58, - 233,149,35,119,205,146,142,195,32,146,237,91, - 96,152,42,104,152,25,229,205,160,142,193,58, - 231,149,183,40,250,175,50,231,149,243,237,91, - 96,152,42,104,152,25,221,117,254,221,116,255, - 78,35,70,221,113,252,221,112,253,89,80,42, - 98,152,183,237,82,34,98,152,203,124,40,19, - 33,0,0,34,98,152,34,102,152,34,96,152, - 62,1,50,95,152,24,40,221,94,252,221,86, - 253,19,19,19,42,96,152,25,34,96,152,237, - 91,100,152,33,158,253,25,237,91,96,152,205, - 171,149,242,55,148,33,0,0,34,96,152,175, - 50,230,149,251,195,32,146,245,62,1,50,231, - 149,62,16,237,57,0,211,80,241,251,237,77, - 201,205,186,149,229,229,33,0,0,34,37,152, - 33,110,152,126,50,234,151,58,44,152,33,235, - 151,119,221,54,253,0,221,54,254,0,195,230, - 148,33,236,151,54,175,33,3,0,229,33,234, - 151,229,205,174,140,193,193,33,236,151,126,254, - 255,40,74,33,245,151,110,221,117,255,33,249, - 151,126,221,166,255,221,119,255,33,253,151,126, - 221,166,255,221,119,255,58,232,149,95,221,126, - 255,163,221,119,255,183,40,15,230,191,33,110, - 152,94,22,0,33,234,149,25,119,24,12,33, - 110,152,94,22,0,33,234,149,25,54,132,33, - 0,0,195,198,149,221,110,253,221,102,254,35, - 221,117,253,221,116,254,17,32,0,221,110,253, - 221,102,254,205,171,149,250,117,148,58,233,149, - 203,87,40,84,33,1,0,34,37,152,221,54, - 253,0,221,54,254,0,24,53,33,236,151,54, - 175,33,3,0,229,33,234,151,229,205,174,140, - 193,193,33,236,151,126,254,255,40,14,33,110, - 152,94,22,0,33,234,149,25,54,140,24,159, - 221,110,253,221,102,254,35,221,117,253,221,116, - 254,17,32,0,221,110,253,221,102,254,205,171, - 149,250,12,149,33,2,0,34,37,152,221,54, - 253,0,221,54,254,0,24,54,33,236,151,54, - 175,33,3,0,229,33,234,151,229,205,174,140, - 193,193,33,236,151,126,254,255,40,15,33,110, - 152,94,22,0,33,234,149,25,54,132,195,211, - 148,221,110,253,221,102,254,35,221,117,253,221, - 116,254,17,32,0,221,110,253,221,102,254,205, - 171,149,250,96,149,33,1,0,195,198,149,124, - 170,250,179,149,237,82,201,124,230,128,237,82, - 60,201,225,253,229,221,229,221,33,0,0,221, - 57,233,221,249,221,225,253,225,201,233,225,253, - 229,221,229,221,33,0,0,221,57,94,35,86, - 35,235,57,249,235,233,0,0,0,0,0,0, - 62,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 175,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,133,1,0,0,0,63, - 255,255,255,255,0,0,0,63,0,0,0,0, - 0,0,0,0,0,0,0,24,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0 - } ; - -#endif diff --git a/drivers/staging/appletalk/cops_ltdrv.h b/drivers/staging/appletalk/cops_ltdrv.h deleted file mode 100644 index c699b1ad31da..000000000000 --- a/drivers/staging/appletalk/cops_ltdrv.h +++ /dev/null @@ -1,241 +0,0 @@ -/* - * The firmware this driver downloads into the Localtalk card is a - * separate program and is not GPL'd source code, even though the Linux - * side driver and the routine that loads this data into the card are. - * - * It is taken from the COPS SDK and is under the following license - * - * This material is licensed to you strictly for use in conjunction with - * the use of COPS LocalTalk adapters. - * There is no charge for this SDK. And no waranty express or implied - * about its fitness for any purpose. However, we will cheerefully - * refund every penny you paid for this SDK... - * Regards, - * - * Thomas F. Divine - * Chief Scientist - */ - - -/* cops_ltdrv.h: LocalTalk driver firmware dump for Linux. - * - * Authors: - * - Jay Schulist - */ - - -#ifdef CONFIG_COPS_TANGENT - -static const unsigned char ltdrv_code[] = { - 58,3,0,50,148,10,33,143,15,62,85,119, - 190,32,9,62,170,119,190,32,3,35,24,241, - 34,146,10,249,17,150,10,33,143,15,183,237, - 82,77,68,11,107,98,19,54,0,237,176,62, - 16,237,57,51,62,0,237,57,50,237,57,54, - 62,12,237,57,49,62,195,33,39,2,50,56, - 0,34,57,0,237,86,205,30,2,251,205,60, - 10,24,169,67,111,112,121,114,105,103,104,116, - 32,40,99,41,32,49,57,56,56,45,49,57, - 57,50,44,32,80,114,105,110,116,105,110,103, - 32,67,111,109,109,117,110,105,99,97,116,105, - 111,110,115,32,65,115,115,111,99,105,97,116, - 101,115,44,32,73,110,99,46,65,108,108,32, - 114,105,103,104,116,115,32,114,101,115,101,114, - 118,101,100,46,32,32,4,4,22,40,255,60, - 4,96,10,224,6,0,7,126,2,64,11,246, - 12,6,13,0,14,193,15,0,5,96,3,192, - 1,0,9,8,62,3,211,82,62,192,211,82, - 201,62,3,211,82,62,213,211,82,201,62,5, - 211,82,62,224,211,82,201,62,5,211,82,62, - 224,211,82,201,62,5,211,82,62,96,211,82, - 201,6,28,33,180,1,14,82,237,163,194,4, - 2,33,39,2,34,64,0,58,3,0,230,1, - 192,62,11,237,121,62,118,237,121,201,33,182, - 10,54,132,205,253,1,201,245,197,213,229,42, - 150,10,14,83,17,98,2,67,20,237,162,58, - 179,1,95,219,82,230,1,32,6,29,32,247, - 195,17,3,62,1,211,82,219,82,95,230,160, - 32,10,237,162,32,225,21,32,222,195,15,3, - 237,162,123,230,96,194,21,3,62,48,211,82, - 62,1,211,82,175,211,82,237,91,150,10,43, - 55,237,82,218,19,3,34,152,10,98,107,58, - 154,10,190,32,81,62,1,50,158,10,35,35, - 62,132,190,32,44,54,133,43,70,58,154,10, - 119,43,112,17,3,0,205,137,3,62,16,211, - 82,62,56,211,82,205,217,1,42,150,10,14, - 83,17,98,2,67,20,58,178,1,95,195,59, - 2,62,129,190,194,227,2,54,130,43,70,58, - 154,10,119,43,112,17,3,0,205,137,3,195, - 254,2,35,35,126,254,132,194,227,2,205,61, - 3,24,20,62,128,166,194,222,2,221,229,221, - 33,175,10,205,93,6,205,144,7,221,225,225, - 209,193,241,251,237,77,221,229,221,33,159,10, - 205,93,6,221,225,205,61,3,195,247,2,24, - 237,24,235,24,233,230,64,40,2,24,227,24, - 225,175,50,179,10,205,208,1,201,197,33,4, - 0,57,126,35,102,111,205,51,3,193,201,62, - 1,50,179,10,34,150,10,54,0,58,179,10, - 183,200,62,14,211,82,62,193,211,82,62,10, - 211,82,62,224,211,82,62,6,211,82,58,154, - 10,211,82,62,16,211,82,62,56,211,82,62, - 48,211,82,219,82,230,1,40,4,219,83,24, - 242,62,14,211,82,62,33,211,82,62,1,211, - 82,62,9,211,82,62,32,211,82,205,217,1, - 201,14,83,205,208,1,24,23,14,83,205,208, - 1,205,226,1,58,174,1,61,32,253,205,244, - 1,58,174,1,61,32,253,205,226,1,58,175, - 1,61,32,253,62,5,211,82,62,233,211,82, - 62,128,211,82,58,176,1,61,32,253,237,163, - 27,62,192,211,82,219,82,230,4,40,250,237, - 163,27,122,179,32,243,219,82,230,4,40,250, - 58,178,1,71,219,82,230,4,40,3,5,32, - 247,219,82,230,4,40,250,205,235,1,58,177, - 1,61,32,253,205,244,1,201,229,213,35,35, - 126,230,128,194,145,4,43,58,154,10,119,43, - 70,33,181,10,119,43,112,17,3,0,243,62, - 10,211,82,219,82,230,128,202,41,4,209,225, - 62,1,55,251,201,205,144,3,58,180,10,254, - 255,202,127,4,205,217,1,58,178,1,71,219, - 82,230,1,32,6,5,32,247,195,173,4,219, - 83,71,58,154,10,184,194,173,4,58,178,1, - 71,219,82,230,1,32,6,5,32,247,195,173, - 4,219,83,58,178,1,71,219,82,230,1,32, - 6,5,32,247,195,173,4,219,83,254,133,194, - 173,4,58,179,1,24,4,58,179,1,135,61, - 32,253,209,225,205,137,3,205,61,3,183,251, - 201,209,225,243,62,10,211,82,219,82,230,128, - 202,164,4,62,1,55,251,201,205,144,3,205, - 61,3,183,251,201,209,225,62,2,55,251,201, - 243,62,14,211,82,62,33,211,82,251,201,33, - 4,0,57,94,35,86,33,2,0,57,126,35, - 102,111,221,229,34,193,10,237,83,195,10,221, - 33,171,10,205,93,6,58,185,10,50,186,10, - 58,184,10,135,50,184,10,205,112,6,254,3, - 56,16,58,185,10,135,60,230,15,50,185,10, - 175,50,184,10,24,23,58,183,10,205,112,6, - 254,3,48,13,58,185,10,203,63,50,185,10, - 62,255,50,183,10,58,185,10,50,186,10,58, - 183,10,135,50,183,10,62,32,50,187,10,50, - 188,10,6,255,219,82,230,16,32,3,5,32, - 247,205,180,4,6,40,219,82,230,16,40,3, - 5,32,247,62,10,211,82,219,82,230,128,194, - 46,5,219,82,230,16,40,214,237,95,71,58, - 186,10,160,230,15,40,32,71,14,10,62,10, - 211,82,219,82,230,128,202,119,5,205,180,4, - 195,156,5,219,82,230,16,202,156,5,13,32, - 229,16,225,42,193,10,237,91,195,10,205,252, - 3,48,7,61,202,156,5,195,197,5,221,225, - 33,0,0,201,221,33,163,10,205,93,6,58, - 188,10,61,50,188,10,40,19,58,186,10,246, - 1,50,186,10,58,183,10,246,1,50,183,10, - 195,46,5,221,225,33,1,0,201,221,33,167, - 10,205,93,6,58,184,10,246,1,50,184,10, - 58,186,10,135,246,1,50,186,10,58,187,10, - 61,50,187,10,194,46,5,221,225,33,2,0, - 201,221,229,33,0,0,57,17,4,0,25,126, - 50,154,10,230,128,50,189,10,58,189,10,183, - 40,6,221,33,88,2,24,4,221,33,150,0, - 58,154,10,183,40,49,60,40,46,61,33,190, - 10,119,35,119,35,54,129,175,50,158,10,221, - 43,221,229,225,124,181,40,42,33,190,10,17, - 3,0,205,206,4,17,232,3,27,123,178,32, - 251,58,158,10,183,40,224,58,154,10,71,62, - 7,128,230,127,71,58,189,10,176,50,154,10, - 24,166,221,225,201,183,221,52,0,192,221,52, - 1,192,221,52,2,192,221,52,3,192,55,201, - 6,8,14,0,31,48,1,12,16,250,121,201, - 33,2,0,57,94,35,86,35,78,35,70,35, - 126,35,102,105,79,120,68,103,237,176,201,33, - 2,0,57,126,35,102,111,62,17,237,57,48, - 125,237,57,40,124,237,57,41,62,0,237,57, - 42,62,64,237,57,43,62,0,237,57,44,33, - 128,2,125,237,57,46,124,237,57,47,62,145, - 237,57,48,211,68,58,149,10,211,66,201,33, - 2,0,57,126,35,102,111,62,33,237,57,48, - 62,64,237,57,32,62,0,237,57,33,237,57, - 34,125,237,57,35,124,237,57,36,62,0,237, - 57,37,33,128,2,125,237,57,38,124,237,57, - 39,62,97,237,57,48,211,67,58,149,10,211, - 66,201,237,56,46,95,237,56,47,87,237,56, - 46,111,237,56,47,103,183,237,82,32,235,33, - 128,2,183,237,82,201,237,56,38,95,237,56, - 39,87,237,56,38,111,237,56,39,103,183,237, - 82,32,235,33,128,2,183,237,82,201,205,106, - 10,221,110,6,221,102,7,126,35,110,103,195, - 118,10,205,106,10,33,0,0,34,205,10,34, - 198,10,34,200,10,33,143,15,34,207,10,237, - 91,207,10,42,146,10,183,237,82,17,0,255, - 25,34,203,10,203,124,40,6,33,0,125,34, - 203,10,42,207,10,229,205,37,3,195,118,10, - 205,106,10,229,42,150,10,35,35,35,229,205, - 70,7,193,124,230,3,103,221,117,254,221,116, - 255,237,91,152,10,35,35,35,183,237,82,32, - 12,17,5,0,42,152,10,205,91,10,242,203, - 7,42,150,10,229,205,37,3,195,118,10,237, - 91,152,10,42,200,10,25,34,200,10,42,205, - 10,25,34,205,10,237,91,203,10,33,158,253, - 25,237,91,205,10,205,91,10,242,245,7,33, - 0,0,34,205,10,62,1,50,197,10,205,5, - 8,33,0,0,57,249,195,118,10,205,106,10, - 58,197,10,183,202,118,10,237,91,198,10,42, - 205,10,205,91,10,242,46,8,237,91,205,10, - 33,98,2,25,237,91,198,10,205,91,10,250, - 78,8,237,91,198,10,42,205,10,183,237,82, - 32,7,42,200,10,125,180,40,13,237,91,205, - 10,42,198,10,205,91,10,242,97,8,237,91, - 207,10,42,205,10,25,229,205,37,3,175,50, - 197,10,195,118,10,205,29,3,33,0,0,57, - 249,195,118,10,205,106,10,58,202,10,183,40, - 22,205,14,7,237,91,209,10,19,19,19,205, - 91,10,242,139,8,33,1,0,195,118,10,33, - 0,0,195,118,10,205,126,10,252,255,205,108, - 8,125,180,194,118,10,237,91,200,10,33,0, - 0,205,91,10,242,118,10,237,91,207,10,42, - 198,10,25,221,117,254,221,116,255,35,35,35, - 229,205,70,7,193,124,230,3,103,35,35,35, - 221,117,252,221,116,253,229,221,110,254,221,102, - 255,229,33,212,10,229,205,124,6,193,193,221, - 110,252,221,102,253,34,209,10,33,211,10,54, - 4,33,209,10,227,205,147,6,193,62,1,50, - 202,10,243,221,94,252,221,86,253,42,200,10, - 183,237,82,34,200,10,203,124,40,17,33,0, - 0,34,200,10,34,205,10,34,198,10,50,197, - 10,24,37,221,94,252,221,86,253,42,198,10, - 25,34,198,10,237,91,203,10,33,158,253,25, - 237,91,198,10,205,91,10,242,68,9,33,0, - 0,34,198,10,205,5,8,33,0,0,57,249, - 251,195,118,10,205,106,10,33,49,13,126,183, - 40,16,205,42,7,237,91,47,13,19,19,19, - 205,91,10,242,117,9,58,142,15,198,1,50, - 142,15,195,118,10,33,49,13,126,254,1,40, - 25,254,3,202,7,10,254,5,202,21,10,33, - 49,13,54,0,33,47,13,229,205,207,6,195, - 118,10,58,141,15,183,32,72,33,51,13,126, - 50,149,10,205,86,7,33,50,13,126,230,127, - 183,32,40,58,142,15,230,127,50,142,15,183, - 32,5,198,1,50,142,15,33,50,13,126,111, - 23,159,103,203,125,58,142,15,40,5,198,128, - 50,142,15,33,50,13,119,33,50,13,126,111, - 23,159,103,229,205,237,5,193,33,211,10,54, - 2,33,2,0,34,209,10,58,154,10,33,212, - 10,119,58,148,10,33,213,10,119,33,209,10, - 229,205,147,6,193,24,128,42,47,13,229,33, - 50,13,229,205,191,4,193,24,239,33,211,10, - 54,6,33,3,0,34,209,10,58,154,10,33, - 212,10,119,58,148,10,33,213,10,119,33,214, - 10,54,5,33,209,10,229,205,147,6,24,200, - 205,106,10,33,49,13,54,0,33,47,13,229, - 205,207,6,33,209,10,227,205,147,6,193,205, - 80,9,205,145,8,24,248,124,170,250,99,10, - 237,82,201,124,230,128,237,82,60,201,225,253, - 229,221,229,221,33,0,0,221,57,233,221,249, - 221,225,253,225,201,233,225,253,229,221,229,221, - 33,0,0,221,57,94,35,86,35,235,57,249, - 235,233,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0 - } ; - -#endif diff --git a/drivers/staging/appletalk/ddp.c b/drivers/staging/appletalk/ddp.c deleted file mode 100644 index 940dd1908339..000000000000 --- a/drivers/staging/appletalk/ddp.c +++ /dev/null @@ -1,1981 +0,0 @@ -/* - * DDP: An implementation of the AppleTalk DDP protocol for - * Ethernet 'ELAP'. - * - * Alan Cox - * - * With more than a little assistance from - * - * Wesley Craig - * - * Fixes: - * Neil Horman : Added missing device ioctls - * Michael Callahan : Made routing work - * Wesley Craig : Fix probing to listen to a - * passed node id. - * Alan Cox : Added send/recvmsg support - * Alan Cox : Moved at. to protinfo in - * socket. - * Alan Cox : Added firewall hooks. - * Alan Cox : Supports new ARPHRD_LOOPBACK - * Christer Weinigel : Routing and /proc fixes. - * Bradford Johnson : LocalTalk. - * Tom Dyas : Module support. - * Alan Cox : Hooks for PPP (based on the - * LocalTalk hook). - * Alan Cox : Posix bits - * Alan Cox/Mike Freeman : Possible fix to NBP problems - * Bradford Johnson : IP-over-DDP (experimental) - * Jay Schulist : Moved IP-over-DDP to its own - * driver file. (ipddp.c & ipddp.h) - * Jay Schulist : Made work as module with - * AppleTalk drivers, cleaned it. - * Rob Newberry : Added proxy AARP and AARP - * procfs, moved probing to AARP - * module. - * Adrian Sun/ - * Michael Zuelsdorff : fix for net.0 packets. don't - * allow illegal ether/tokentalk - * port assignment. we lose a - * valid localtalk port as a - * result. - * Arnaldo C. de Melo : Cleanup, in preparation for - * shared skb support 8) - * Arnaldo C. de Melo : Move proc stuff to atalk_proc.c, - * use seq_file - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#include -#include -#include -#include -#include /* For TIOCOUTQ/INQ */ -#include -#include -#include -#include -#include -#include -#include -#include "atalk.h" -#include "../../net/core/kmap_skb.h" - -struct datalink_proto *ddp_dl, *aarp_dl; -static const struct proto_ops atalk_dgram_ops; - -/**************************************************************************\ -* * -* Handlers for the socket list. * -* * -\**************************************************************************/ - -HLIST_HEAD(atalk_sockets); -DEFINE_RWLOCK(atalk_sockets_lock); - -static inline void __atalk_insert_socket(struct sock *sk) -{ - sk_add_node(sk, &atalk_sockets); -} - -static inline void atalk_remove_socket(struct sock *sk) -{ - write_lock_bh(&atalk_sockets_lock); - sk_del_node_init(sk); - write_unlock_bh(&atalk_sockets_lock); -} - -static struct sock *atalk_search_socket(struct sockaddr_at *to, - struct atalk_iface *atif) -{ - struct sock *s; - struct hlist_node *node; - - read_lock_bh(&atalk_sockets_lock); - sk_for_each(s, node, &atalk_sockets) { - struct atalk_sock *at = at_sk(s); - - if (to->sat_port != at->src_port) - continue; - - if (to->sat_addr.s_net == ATADDR_ANYNET && - to->sat_addr.s_node == ATADDR_BCAST) - goto found; - - if (to->sat_addr.s_net == at->src_net && - (to->sat_addr.s_node == at->src_node || - to->sat_addr.s_node == ATADDR_BCAST || - to->sat_addr.s_node == ATADDR_ANYNODE)) - goto found; - - /* XXXX.0 -- we got a request for this router. make sure - * that the node is appropriately set. */ - if (to->sat_addr.s_node == ATADDR_ANYNODE && - to->sat_addr.s_net != ATADDR_ANYNET && - atif->address.s_node == at->src_node) { - to->sat_addr.s_node = atif->address.s_node; - goto found; - } - } - s = NULL; -found: - read_unlock_bh(&atalk_sockets_lock); - return s; -} - -/** - * atalk_find_or_insert_socket - Try to find a socket matching ADDR - * @sk - socket to insert in the list if it is not there already - * @sat - address to search for - * - * Try to find a socket matching ADDR in the socket list, if found then return - * it. If not, insert SK into the socket list. - * - * This entire operation must execute atomically. - */ -static struct sock *atalk_find_or_insert_socket(struct sock *sk, - struct sockaddr_at *sat) -{ - struct sock *s; - struct hlist_node *node; - struct atalk_sock *at; - - write_lock_bh(&atalk_sockets_lock); - sk_for_each(s, node, &atalk_sockets) { - at = at_sk(s); - - if (at->src_net == sat->sat_addr.s_net && - at->src_node == sat->sat_addr.s_node && - at->src_port == sat->sat_port) - goto found; - } - s = NULL; - __atalk_insert_socket(sk); /* Wheee, it's free, assign and insert. */ -found: - write_unlock_bh(&atalk_sockets_lock); - return s; -} - -static void atalk_destroy_timer(unsigned long data) -{ - struct sock *sk = (struct sock *)data; - - if (sk_has_allocations(sk)) { - sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; - add_timer(&sk->sk_timer); - } else - sock_put(sk); -} - -static inline void atalk_destroy_socket(struct sock *sk) -{ - atalk_remove_socket(sk); - skb_queue_purge(&sk->sk_receive_queue); - - if (sk_has_allocations(sk)) { - setup_timer(&sk->sk_timer, atalk_destroy_timer, - (unsigned long)sk); - sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; - add_timer(&sk->sk_timer); - } else - sock_put(sk); -} - -/**************************************************************************\ -* * -* Routing tables for the AppleTalk socket layer. * -* * -\**************************************************************************/ - -/* Anti-deadlock ordering is atalk_routes_lock --> iface_lock -DaveM */ -struct atalk_route *atalk_routes; -DEFINE_RWLOCK(atalk_routes_lock); - -struct atalk_iface *atalk_interfaces; -DEFINE_RWLOCK(atalk_interfaces_lock); - -/* For probing devices or in a routerless network */ -struct atalk_route atrtr_default; - -/* AppleTalk interface control */ -/* - * Drop a device. Doesn't drop any of its routes - that is the caller's - * problem. Called when we down the interface or delete the address. - */ -static void atif_drop_device(struct net_device *dev) -{ - struct atalk_iface **iface = &atalk_interfaces; - struct atalk_iface *tmp; - - write_lock_bh(&atalk_interfaces_lock); - while ((tmp = *iface) != NULL) { - if (tmp->dev == dev) { - *iface = tmp->next; - dev_put(dev); - kfree(tmp); - dev->atalk_ptr = NULL; - } else - iface = &tmp->next; - } - write_unlock_bh(&atalk_interfaces_lock); -} - -static struct atalk_iface *atif_add_device(struct net_device *dev, - struct atalk_addr *sa) -{ - struct atalk_iface *iface = kzalloc(sizeof(*iface), GFP_KERNEL); - - if (!iface) - goto out; - - dev_hold(dev); - iface->dev = dev; - dev->atalk_ptr = iface; - iface->address = *sa; - iface->status = 0; - - write_lock_bh(&atalk_interfaces_lock); - iface->next = atalk_interfaces; - atalk_interfaces = iface; - write_unlock_bh(&atalk_interfaces_lock); -out: - return iface; -} - -/* Perform phase 2 AARP probing on our tentative address */ -static int atif_probe_device(struct atalk_iface *atif) -{ - int netrange = ntohs(atif->nets.nr_lastnet) - - ntohs(atif->nets.nr_firstnet) + 1; - int probe_net = ntohs(atif->address.s_net); - int probe_node = atif->address.s_node; - int netct, nodect; - - /* Offset the network we start probing with */ - if (probe_net == ATADDR_ANYNET) { - probe_net = ntohs(atif->nets.nr_firstnet); - if (netrange) - probe_net += jiffies % netrange; - } - if (probe_node == ATADDR_ANYNODE) - probe_node = jiffies & 0xFF; - - /* Scan the networks */ - atif->status |= ATIF_PROBE; - for (netct = 0; netct <= netrange; netct++) { - /* Sweep the available nodes from a given start */ - atif->address.s_net = htons(probe_net); - for (nodect = 0; nodect < 256; nodect++) { - atif->address.s_node = (nodect + probe_node) & 0xFF; - if (atif->address.s_node > 0 && - atif->address.s_node < 254) { - /* Probe a proposed address */ - aarp_probe_network(atif); - - if (!(atif->status & ATIF_PROBE_FAIL)) { - atif->status &= ~ATIF_PROBE; - return 0; - } - } - atif->status &= ~ATIF_PROBE_FAIL; - } - probe_net++; - if (probe_net > ntohs(atif->nets.nr_lastnet)) - probe_net = ntohs(atif->nets.nr_firstnet); - } - atif->status &= ~ATIF_PROBE; - - return -EADDRINUSE; /* Network is full... */ -} - - -/* Perform AARP probing for a proxy address */ -static int atif_proxy_probe_device(struct atalk_iface *atif, - struct atalk_addr* proxy_addr) -{ - int netrange = ntohs(atif->nets.nr_lastnet) - - ntohs(atif->nets.nr_firstnet) + 1; - /* we probe the interface's network */ - int probe_net = ntohs(atif->address.s_net); - int probe_node = ATADDR_ANYNODE; /* we'll take anything */ - int netct, nodect; - - /* Offset the network we start probing with */ - if (probe_net == ATADDR_ANYNET) { - probe_net = ntohs(atif->nets.nr_firstnet); - if (netrange) - probe_net += jiffies % netrange; - } - - if (probe_node == ATADDR_ANYNODE) - probe_node = jiffies & 0xFF; - - /* Scan the networks */ - for (netct = 0; netct <= netrange; netct++) { - /* Sweep the available nodes from a given start */ - proxy_addr->s_net = htons(probe_net); - for (nodect = 0; nodect < 256; nodect++) { - proxy_addr->s_node = (nodect + probe_node) & 0xFF; - if (proxy_addr->s_node > 0 && - proxy_addr->s_node < 254) { - /* Tell AARP to probe a proposed address */ - int ret = aarp_proxy_probe_network(atif, - proxy_addr); - - if (ret != -EADDRINUSE) - return ret; - } - } - probe_net++; - if (probe_net > ntohs(atif->nets.nr_lastnet)) - probe_net = ntohs(atif->nets.nr_firstnet); - } - - return -EADDRINUSE; /* Network is full... */ -} - - -struct atalk_addr *atalk_find_dev_addr(struct net_device *dev) -{ - struct atalk_iface *iface = dev->atalk_ptr; - return iface ? &iface->address : NULL; -} - -static struct atalk_addr *atalk_find_primary(void) -{ - struct atalk_iface *fiface = NULL; - struct atalk_addr *retval; - struct atalk_iface *iface; - - /* - * Return a point-to-point interface only if - * there is no non-ptp interface available. - */ - read_lock_bh(&atalk_interfaces_lock); - for (iface = atalk_interfaces; iface; iface = iface->next) { - if (!fiface && !(iface->dev->flags & IFF_LOOPBACK)) - fiface = iface; - if (!(iface->dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) { - retval = &iface->address; - goto out; - } - } - - if (fiface) - retval = &fiface->address; - else if (atalk_interfaces) - retval = &atalk_interfaces->address; - else - retval = NULL; -out: - read_unlock_bh(&atalk_interfaces_lock); - return retval; -} - -/* - * Find a match for 'any network' - ie any of our interfaces with that - * node number will do just nicely. - */ -static struct atalk_iface *atalk_find_anynet(int node, struct net_device *dev) -{ - struct atalk_iface *iface = dev->atalk_ptr; - - if (!iface || iface->status & ATIF_PROBE) - goto out_err; - - if (node != ATADDR_BCAST && - iface->address.s_node != node && - node != ATADDR_ANYNODE) - goto out_err; -out: - return iface; -out_err: - iface = NULL; - goto out; -} - -/* Find a match for a specific network:node pair */ -static struct atalk_iface *atalk_find_interface(__be16 net, int node) -{ - struct atalk_iface *iface; - - read_lock_bh(&atalk_interfaces_lock); - for (iface = atalk_interfaces; iface; iface = iface->next) { - if ((node == ATADDR_BCAST || - node == ATADDR_ANYNODE || - iface->address.s_node == node) && - iface->address.s_net == net && - !(iface->status & ATIF_PROBE)) - break; - - /* XXXX.0 -- net.0 returns the iface associated with net */ - if (node == ATADDR_ANYNODE && net != ATADDR_ANYNET && - ntohs(iface->nets.nr_firstnet) <= ntohs(net) && - ntohs(net) <= ntohs(iface->nets.nr_lastnet)) - break; - } - read_unlock_bh(&atalk_interfaces_lock); - return iface; -} - - -/* - * Find a route for an AppleTalk packet. This ought to get cached in - * the socket (later on...). We know about host routes and the fact - * that a route must be direct to broadcast. - */ -static struct atalk_route *atrtr_find(struct atalk_addr *target) -{ - /* - * we must search through all routes unless we find a - * host route, because some host routes might overlap - * network routes - */ - struct atalk_route *net_route = NULL; - struct atalk_route *r; - - read_lock_bh(&atalk_routes_lock); - for (r = atalk_routes; r; r = r->next) { - if (!(r->flags & RTF_UP)) - continue; - - if (r->target.s_net == target->s_net) { - if (r->flags & RTF_HOST) { - /* - * if this host route is for the target, - * the we're done - */ - if (r->target.s_node == target->s_node) - goto out; - } else - /* - * this route will work if there isn't a - * direct host route, so cache it - */ - net_route = r; - } - } - - /* - * if we found a network route but not a direct host - * route, then return it - */ - if (net_route) - r = net_route; - else if (atrtr_default.dev) - r = &atrtr_default; - else /* No route can be found */ - r = NULL; -out: - read_unlock_bh(&atalk_routes_lock); - return r; -} - - -/* - * Given an AppleTalk network, find the device to use. This can be - * a simple lookup. - */ -struct net_device *atrtr_get_dev(struct atalk_addr *sa) -{ - struct atalk_route *atr = atrtr_find(sa); - return atr ? atr->dev : NULL; -} - -/* Set up a default router */ -static void atrtr_set_default(struct net_device *dev) -{ - atrtr_default.dev = dev; - atrtr_default.flags = RTF_UP; - atrtr_default.gateway.s_net = htons(0); - atrtr_default.gateway.s_node = 0; -} - -/* - * Add a router. Basically make sure it looks valid and stuff the - * entry in the list. While it uses netranges we always set them to one - * entry to work like netatalk. - */ -static int atrtr_create(struct rtentry *r, struct net_device *devhint) -{ - struct sockaddr_at *ta = (struct sockaddr_at *)&r->rt_dst; - struct sockaddr_at *ga = (struct sockaddr_at *)&r->rt_gateway; - struct atalk_route *rt; - struct atalk_iface *iface, *riface; - int retval = -EINVAL; - - /* - * Fixme: Raise/Lower a routing change semaphore for these - * operations. - */ - - /* Validate the request */ - if (ta->sat_family != AF_APPLETALK || - (!devhint && ga->sat_family != AF_APPLETALK)) - goto out; - - /* Now walk the routing table and make our decisions */ - write_lock_bh(&atalk_routes_lock); - for (rt = atalk_routes; rt; rt = rt->next) { - if (r->rt_flags != rt->flags) - continue; - - if (ta->sat_addr.s_net == rt->target.s_net) { - if (!(rt->flags & RTF_HOST)) - break; - if (ta->sat_addr.s_node == rt->target.s_node) - break; - } - } - - if (!devhint) { - riface = NULL; - - read_lock_bh(&atalk_interfaces_lock); - for (iface = atalk_interfaces; iface; iface = iface->next) { - if (!riface && - ntohs(ga->sat_addr.s_net) >= - ntohs(iface->nets.nr_firstnet) && - ntohs(ga->sat_addr.s_net) <= - ntohs(iface->nets.nr_lastnet)) - riface = iface; - - if (ga->sat_addr.s_net == iface->address.s_net && - ga->sat_addr.s_node == iface->address.s_node) - riface = iface; - } - read_unlock_bh(&atalk_interfaces_lock); - - retval = -ENETUNREACH; - if (!riface) - goto out_unlock; - - devhint = riface->dev; - } - - if (!rt) { - rt = kzalloc(sizeof(*rt), GFP_ATOMIC); - - retval = -ENOBUFS; - if (!rt) - goto out_unlock; - - rt->next = atalk_routes; - atalk_routes = rt; - } - - /* Fill in the routing entry */ - rt->target = ta->sat_addr; - dev_hold(devhint); - rt->dev = devhint; - rt->flags = r->rt_flags; - rt->gateway = ga->sat_addr; - - retval = 0; -out_unlock: - write_unlock_bh(&atalk_routes_lock); -out: - return retval; -} - -/* Delete a route. Find it and discard it */ -static int atrtr_delete(struct atalk_addr * addr) -{ - struct atalk_route **r = &atalk_routes; - int retval = 0; - struct atalk_route *tmp; - - write_lock_bh(&atalk_routes_lock); - while ((tmp = *r) != NULL) { - if (tmp->target.s_net == addr->s_net && - (!(tmp->flags&RTF_GATEWAY) || - tmp->target.s_node == addr->s_node)) { - *r = tmp->next; - dev_put(tmp->dev); - kfree(tmp); - goto out; - } - r = &tmp->next; - } - retval = -ENOENT; -out: - write_unlock_bh(&atalk_routes_lock); - return retval; -} - -/* - * Called when a device is downed. Just throw away any routes - * via it. - */ -static void atrtr_device_down(struct net_device *dev) -{ - struct atalk_route **r = &atalk_routes; - struct atalk_route *tmp; - - write_lock_bh(&atalk_routes_lock); - while ((tmp = *r) != NULL) { - if (tmp->dev == dev) { - *r = tmp->next; - dev_put(dev); - kfree(tmp); - } else - r = &tmp->next; - } - write_unlock_bh(&atalk_routes_lock); - - if (atrtr_default.dev == dev) - atrtr_set_default(NULL); -} - -/* Actually down the interface */ -static inline void atalk_dev_down(struct net_device *dev) -{ - atrtr_device_down(dev); /* Remove all routes for the device */ - aarp_device_down(dev); /* Remove AARP entries for the device */ - atif_drop_device(dev); /* Remove the device */ -} - -/* - * A device event has occurred. Watch for devices going down and - * delete our use of them (iface and route). - */ -static int ddp_device_event(struct notifier_block *this, unsigned long event, - void *ptr) -{ - struct net_device *dev = ptr; - - if (!net_eq(dev_net(dev), &init_net)) - return NOTIFY_DONE; - - if (event == NETDEV_DOWN) - /* Discard any use of this */ - atalk_dev_down(dev); - - return NOTIFY_DONE; -} - -/* ioctl calls. Shouldn't even need touching */ -/* Device configuration ioctl calls */ -static int atif_ioctl(int cmd, void __user *arg) -{ - static char aarp_mcast[6] = { 0x09, 0x00, 0x00, 0xFF, 0xFF, 0xFF }; - struct ifreq atreq; - struct atalk_netrange *nr; - struct sockaddr_at *sa; - struct net_device *dev; - struct atalk_iface *atif; - int ct; - int limit; - struct rtentry rtdef; - int add_route; - - if (copy_from_user(&atreq, arg, sizeof(atreq))) - return -EFAULT; - - dev = __dev_get_by_name(&init_net, atreq.ifr_name); - if (!dev) - return -ENODEV; - - sa = (struct sockaddr_at *)&atreq.ifr_addr; - atif = atalk_find_dev(dev); - - switch (cmd) { - case SIOCSIFADDR: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (sa->sat_family != AF_APPLETALK) - return -EINVAL; - if (dev->type != ARPHRD_ETHER && - dev->type != ARPHRD_LOOPBACK && - dev->type != ARPHRD_LOCALTLK && - dev->type != ARPHRD_PPP) - return -EPROTONOSUPPORT; - - nr = (struct atalk_netrange *)&sa->sat_zero[0]; - add_route = 1; - - /* - * if this is a point-to-point iface, and we already - * have an iface for this AppleTalk address, then we - * should not add a route - */ - if ((dev->flags & IFF_POINTOPOINT) && - atalk_find_interface(sa->sat_addr.s_net, - sa->sat_addr.s_node)) { - printk(KERN_DEBUG "AppleTalk: point-to-point " - "interface added with " - "existing address\n"); - add_route = 0; - } - - /* - * Phase 1 is fine on LocalTalk but we don't do - * EtherTalk phase 1. Anyone wanting to add it go ahead. - */ - if (dev->type == ARPHRD_ETHER && nr->nr_phase != 2) - return -EPROTONOSUPPORT; - if (sa->sat_addr.s_node == ATADDR_BCAST || - sa->sat_addr.s_node == 254) - return -EINVAL; - if (atif) { - /* Already setting address */ - if (atif->status & ATIF_PROBE) - return -EBUSY; - - atif->address.s_net = sa->sat_addr.s_net; - atif->address.s_node = sa->sat_addr.s_node; - atrtr_device_down(dev); /* Flush old routes */ - } else { - atif = atif_add_device(dev, &sa->sat_addr); - if (!atif) - return -ENOMEM; - } - atif->nets = *nr; - - /* - * Check if the chosen address is used. If so we - * error and atalkd will try another. - */ - - if (!(dev->flags & IFF_LOOPBACK) && - !(dev->flags & IFF_POINTOPOINT) && - atif_probe_device(atif) < 0) { - atif_drop_device(dev); - return -EADDRINUSE; - } - - /* Hey it worked - add the direct routes */ - sa = (struct sockaddr_at *)&rtdef.rt_gateway; - sa->sat_family = AF_APPLETALK; - sa->sat_addr.s_net = atif->address.s_net; - sa->sat_addr.s_node = atif->address.s_node; - sa = (struct sockaddr_at *)&rtdef.rt_dst; - rtdef.rt_flags = RTF_UP; - sa->sat_family = AF_APPLETALK; - sa->sat_addr.s_node = ATADDR_ANYNODE; - if (dev->flags & IFF_LOOPBACK || - dev->flags & IFF_POINTOPOINT) - rtdef.rt_flags |= RTF_HOST; - - /* Routerless initial state */ - if (nr->nr_firstnet == htons(0) && - nr->nr_lastnet == htons(0xFFFE)) { - sa->sat_addr.s_net = atif->address.s_net; - atrtr_create(&rtdef, dev); - atrtr_set_default(dev); - } else { - limit = ntohs(nr->nr_lastnet); - if (limit - ntohs(nr->nr_firstnet) > 4096) { - printk(KERN_WARNING "Too many routes/" - "iface.\n"); - return -EINVAL; - } - if (add_route) - for (ct = ntohs(nr->nr_firstnet); - ct <= limit; ct++) { - sa->sat_addr.s_net = htons(ct); - atrtr_create(&rtdef, dev); - } - } - dev_mc_add_global(dev, aarp_mcast); - return 0; - - case SIOCGIFADDR: - if (!atif) - return -EADDRNOTAVAIL; - - sa->sat_family = AF_APPLETALK; - sa->sat_addr = atif->address; - break; - - case SIOCGIFBRDADDR: - if (!atif) - return -EADDRNOTAVAIL; - - sa->sat_family = AF_APPLETALK; - sa->sat_addr.s_net = atif->address.s_net; - sa->sat_addr.s_node = ATADDR_BCAST; - break; - - case SIOCATALKDIFADDR: - case SIOCDIFADDR: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (sa->sat_family != AF_APPLETALK) - return -EINVAL; - atalk_dev_down(dev); - break; - - case SIOCSARP: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (sa->sat_family != AF_APPLETALK) - return -EINVAL; - /* - * for now, we only support proxy AARP on ELAP; - * we should be able to do it for LocalTalk, too. - */ - if (dev->type != ARPHRD_ETHER) - return -EPROTONOSUPPORT; - - /* - * atif points to the current interface on this network; - * we aren't concerned about its current status (at - * least for now), but it has all the settings about - * the network we're going to probe. Consequently, it - * must exist. - */ - if (!atif) - return -EADDRNOTAVAIL; - - nr = (struct atalk_netrange *)&(atif->nets); - /* - * Phase 1 is fine on Localtalk but we don't do - * Ethertalk phase 1. Anyone wanting to add it go ahead. - */ - if (dev->type == ARPHRD_ETHER && nr->nr_phase != 2) - return -EPROTONOSUPPORT; - - if (sa->sat_addr.s_node == ATADDR_BCAST || - sa->sat_addr.s_node == 254) - return -EINVAL; - - /* - * Check if the chosen address is used. If so we - * error and ATCP will try another. - */ - if (atif_proxy_probe_device(atif, &(sa->sat_addr)) < 0) - return -EADDRINUSE; - - /* - * We now have an address on the local network, and - * the AARP code will defend it for us until we take it - * down. We don't set up any routes right now, because - * ATCP will install them manually via SIOCADDRT. - */ - break; - - case SIOCDARP: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (sa->sat_family != AF_APPLETALK) - return -EINVAL; - if (!atif) - return -EADDRNOTAVAIL; - - /* give to aarp module to remove proxy entry */ - aarp_proxy_remove(atif->dev, &(sa->sat_addr)); - return 0; - } - - return copy_to_user(arg, &atreq, sizeof(atreq)) ? -EFAULT : 0; -} - -/* Routing ioctl() calls */ -static int atrtr_ioctl(unsigned int cmd, void __user *arg) -{ - struct rtentry rt; - - if (copy_from_user(&rt, arg, sizeof(rt))) - return -EFAULT; - - switch (cmd) { - case SIOCDELRT: - if (rt.rt_dst.sa_family != AF_APPLETALK) - return -EINVAL; - return atrtr_delete(&((struct sockaddr_at *) - &rt.rt_dst)->sat_addr); - - case SIOCADDRT: { - struct net_device *dev = NULL; - if (rt.rt_dev) { - char name[IFNAMSIZ]; - if (copy_from_user(name, rt.rt_dev, IFNAMSIZ-1)) - return -EFAULT; - name[IFNAMSIZ-1] = '\0'; - dev = __dev_get_by_name(&init_net, name); - if (!dev) - return -ENODEV; - } - return atrtr_create(&rt, dev); - } - } - return -EINVAL; -} - -/**************************************************************************\ -* * -* Handling for system calls applied via the various interfaces to an * -* AppleTalk socket object. * -* * -\**************************************************************************/ - -/* - * Checksum: This is 'optional'. It's quite likely also a good - * candidate for assembler hackery 8) - */ -static unsigned long atalk_sum_partial(const unsigned char *data, - int len, unsigned long sum) -{ - /* This ought to be unwrapped neatly. I'll trust gcc for now */ - while (len--) { - sum += *data++; - sum = rol16(sum, 1); - } - return sum; -} - -/* Checksum skb data -- similar to skb_checksum */ -static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, - int len, unsigned long sum) -{ - int start = skb_headlen(skb); - struct sk_buff *frag_iter; - int i, copy; - - /* checksum stuff in header space */ - if ( (copy = start - offset) > 0) { - if (copy > len) - copy = len; - sum = atalk_sum_partial(skb->data + offset, copy, sum); - if ( (len -= copy) == 0) - return sum; - - offset += copy; - } - - /* checksum stuff in frags */ - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - int end; - - WARN_ON(start > offset + len); - - end = start + skb_shinfo(skb)->frags[i].size; - if ((copy = end - offset) > 0) { - u8 *vaddr; - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - - if (copy > len) - copy = len; - vaddr = kmap_skb_frag(frag); - sum = atalk_sum_partial(vaddr + frag->page_offset + - offset - start, copy, sum); - kunmap_skb_frag(vaddr); - - if (!(len -= copy)) - return sum; - offset += copy; - } - start = end; - } - - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); - - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - sum = atalk_sum_skb(frag_iter, offset - start, - copy, sum); - if ((len -= copy) == 0) - return sum; - offset += copy; - } - start = end; - } - - BUG_ON(len > 0); - - return sum; -} - -static __be16 atalk_checksum(const struct sk_buff *skb, int len) -{ - unsigned long sum; - - /* skip header 4 bytes */ - sum = atalk_sum_skb(skb, 4, len-4, 0); - - /* Use 0xFFFF for 0. 0 itself means none */ - return sum ? htons((unsigned short)sum) : htons(0xFFFF); -} - -static struct proto ddp_proto = { - .name = "DDP", - .owner = THIS_MODULE, - .obj_size = sizeof(struct atalk_sock), -}; - -/* - * Create a socket. Initialise the socket, blank the addresses - * set the state. - */ -static int atalk_create(struct net *net, struct socket *sock, int protocol, - int kern) -{ - struct sock *sk; - int rc = -ESOCKTNOSUPPORT; - - if (!net_eq(net, &init_net)) - return -EAFNOSUPPORT; - - /* - * We permit SOCK_DGRAM and RAW is an extension. It is trivial to do - * and gives you the full ELAP frame. Should be handy for CAP 8) - */ - if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM) - goto out; - rc = -ENOMEM; - sk = sk_alloc(net, PF_APPLETALK, GFP_KERNEL, &ddp_proto); - if (!sk) - goto out; - rc = 0; - sock->ops = &atalk_dgram_ops; - sock_init_data(sock, sk); - - /* Checksums on by default */ - sock_set_flag(sk, SOCK_ZAPPED); -out: - return rc; -} - -/* Free a socket. No work needed */ -static int atalk_release(struct socket *sock) -{ - struct sock *sk = sock->sk; - - lock_kernel(); - if (sk) { - sock_orphan(sk); - sock->sk = NULL; - atalk_destroy_socket(sk); - } - unlock_kernel(); - return 0; -} - -/** - * atalk_pick_and_bind_port - Pick a source port when one is not given - * @sk - socket to insert into the tables - * @sat - address to search for - * - * Pick a source port when one is not given. If we can find a suitable free - * one, we insert the socket into the tables using it. - * - * This whole operation must be atomic. - */ -static int atalk_pick_and_bind_port(struct sock *sk, struct sockaddr_at *sat) -{ - int retval; - - write_lock_bh(&atalk_sockets_lock); - - for (sat->sat_port = ATPORT_RESERVED; - sat->sat_port < ATPORT_LAST; - sat->sat_port++) { - struct sock *s; - struct hlist_node *node; - - sk_for_each(s, node, &atalk_sockets) { - struct atalk_sock *at = at_sk(s); - - if (at->src_net == sat->sat_addr.s_net && - at->src_node == sat->sat_addr.s_node && - at->src_port == sat->sat_port) - goto try_next_port; - } - - /* Wheee, it's free, assign and insert. */ - __atalk_insert_socket(sk); - at_sk(sk)->src_port = sat->sat_port; - retval = 0; - goto out; - -try_next_port:; - } - - retval = -EBUSY; -out: - write_unlock_bh(&atalk_sockets_lock); - return retval; -} - -static int atalk_autobind(struct sock *sk) -{ - struct atalk_sock *at = at_sk(sk); - struct sockaddr_at sat; - struct atalk_addr *ap = atalk_find_primary(); - int n = -EADDRNOTAVAIL; - - if (!ap || ap->s_net == htons(ATADDR_ANYNET)) - goto out; - - at->src_net = sat.sat_addr.s_net = ap->s_net; - at->src_node = sat.sat_addr.s_node = ap->s_node; - - n = atalk_pick_and_bind_port(sk, &sat); - if (!n) - sock_reset_flag(sk, SOCK_ZAPPED); -out: - return n; -} - -/* Set the address 'our end' of the connection */ -static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) -{ - struct sockaddr_at *addr = (struct sockaddr_at *)uaddr; - struct sock *sk = sock->sk; - struct atalk_sock *at = at_sk(sk); - int err; - - if (!sock_flag(sk, SOCK_ZAPPED) || - addr_len != sizeof(struct sockaddr_at)) - return -EINVAL; - - if (addr->sat_family != AF_APPLETALK) - return -EAFNOSUPPORT; - - lock_kernel(); - if (addr->sat_addr.s_net == htons(ATADDR_ANYNET)) { - struct atalk_addr *ap = atalk_find_primary(); - - err = -EADDRNOTAVAIL; - if (!ap) - goto out; - - at->src_net = addr->sat_addr.s_net = ap->s_net; - at->src_node = addr->sat_addr.s_node= ap->s_node; - } else { - err = -EADDRNOTAVAIL; - if (!atalk_find_interface(addr->sat_addr.s_net, - addr->sat_addr.s_node)) - goto out; - - at->src_net = addr->sat_addr.s_net; - at->src_node = addr->sat_addr.s_node; - } - - if (addr->sat_port == ATADDR_ANYPORT) { - err = atalk_pick_and_bind_port(sk, addr); - - if (err < 0) - goto out; - } else { - at->src_port = addr->sat_port; - - err = -EADDRINUSE; - if (atalk_find_or_insert_socket(sk, addr)) - goto out; - } - - sock_reset_flag(sk, SOCK_ZAPPED); - err = 0; -out: - unlock_kernel(); - return err; -} - -/* Set the address we talk to */ -static int atalk_connect(struct socket *sock, struct sockaddr *uaddr, - int addr_len, int flags) -{ - struct sock *sk = sock->sk; - struct atalk_sock *at = at_sk(sk); - struct sockaddr_at *addr; - int err; - - sk->sk_state = TCP_CLOSE; - sock->state = SS_UNCONNECTED; - - if (addr_len != sizeof(*addr)) - return -EINVAL; - - addr = (struct sockaddr_at *)uaddr; - - if (addr->sat_family != AF_APPLETALK) - return -EAFNOSUPPORT; - - if (addr->sat_addr.s_node == ATADDR_BCAST && - !sock_flag(sk, SOCK_BROADCAST)) { -#if 1 - printk(KERN_WARNING "%s is broken and did not set " - "SO_BROADCAST. It will break when 2.2 is " - "released.\n", - current->comm); -#else - return -EACCES; -#endif - } - - lock_kernel(); - err = -EBUSY; - if (sock_flag(sk, SOCK_ZAPPED)) - if (atalk_autobind(sk) < 0) - goto out; - - err = -ENETUNREACH; - if (!atrtr_get_dev(&addr->sat_addr)) - goto out; - - at->dest_port = addr->sat_port; - at->dest_net = addr->sat_addr.s_net; - at->dest_node = addr->sat_addr.s_node; - - sock->state = SS_CONNECTED; - sk->sk_state = TCP_ESTABLISHED; - err = 0; -out: - unlock_kernel(); - return err; -} - -/* - * Find the name of an AppleTalk socket. Just copy the right - * fields into the sockaddr. - */ -static int atalk_getname(struct socket *sock, struct sockaddr *uaddr, - int *uaddr_len, int peer) -{ - struct sockaddr_at sat; - struct sock *sk = sock->sk; - struct atalk_sock *at = at_sk(sk); - int err; - - lock_kernel(); - err = -ENOBUFS; - if (sock_flag(sk, SOCK_ZAPPED)) - if (atalk_autobind(sk) < 0) - goto out; - - *uaddr_len = sizeof(struct sockaddr_at); - memset(&sat.sat_zero, 0, sizeof(sat.sat_zero)); - - if (peer) { - err = -ENOTCONN; - if (sk->sk_state != TCP_ESTABLISHED) - goto out; - - sat.sat_addr.s_net = at->dest_net; - sat.sat_addr.s_node = at->dest_node; - sat.sat_port = at->dest_port; - } else { - sat.sat_addr.s_net = at->src_net; - sat.sat_addr.s_node = at->src_node; - sat.sat_port = at->src_port; - } - - err = 0; - sat.sat_family = AF_APPLETALK; - memcpy(uaddr, &sat, sizeof(sat)); - -out: - unlock_kernel(); - return err; -} - -static unsigned int atalk_poll(struct file *file, struct socket *sock, - poll_table *wait) -{ - int err; - lock_kernel(); - err = datagram_poll(file, sock, wait); - unlock_kernel(); - return err; -} - -#if defined(CONFIG_IPDDP) || defined(CONFIG_IPDDP_MODULE) -static __inline__ int is_ip_over_ddp(struct sk_buff *skb) -{ - return skb->data[12] == 22; -} - -static int handle_ip_over_ddp(struct sk_buff *skb) -{ - struct net_device *dev = __dev_get_by_name(&init_net, "ipddp0"); - struct net_device_stats *stats; - - /* This needs to be able to handle ipddp"N" devices */ - if (!dev) { - kfree_skb(skb); - return NET_RX_DROP; - } - - skb->protocol = htons(ETH_P_IP); - skb_pull(skb, 13); - skb->dev = dev; - skb_reset_transport_header(skb); - - stats = netdev_priv(dev); - stats->rx_packets++; - stats->rx_bytes += skb->len + 13; - return netif_rx(skb); /* Send the SKB up to a higher place. */ -} -#else -/* make it easy for gcc to optimize this test out, i.e. kill the code */ -#define is_ip_over_ddp(skb) 0 -#define handle_ip_over_ddp(skb) 0 -#endif - -static int atalk_route_packet(struct sk_buff *skb, struct net_device *dev, - struct ddpehdr *ddp, __u16 len_hops, int origlen) -{ - struct atalk_route *rt; - struct atalk_addr ta; - - /* - * Don't route multicast, etc., packets, or packets sent to "this - * network" - */ - if (skb->pkt_type != PACKET_HOST || !ddp->deh_dnet) { - /* - * FIXME: - * - * Can it ever happen that a packet is from a PPP iface and - * needs to be broadcast onto the default network? - */ - if (dev->type == ARPHRD_PPP) - printk(KERN_DEBUG "AppleTalk: didn't forward broadcast " - "packet received from PPP iface\n"); - goto free_it; - } - - ta.s_net = ddp->deh_dnet; - ta.s_node = ddp->deh_dnode; - - /* Route the packet */ - rt = atrtr_find(&ta); - /* increment hops count */ - len_hops += 1 << 10; - if (!rt || !(len_hops & (15 << 10))) - goto free_it; - - /* FIXME: use skb->cb to be able to use shared skbs */ - - /* - * Route goes through another gateway, so set the target to the - * gateway instead. - */ - - if (rt->flags & RTF_GATEWAY) { - ta.s_net = rt->gateway.s_net; - ta.s_node = rt->gateway.s_node; - } - - /* Fix up skb->len field */ - skb_trim(skb, min_t(unsigned int, origlen, - (rt->dev->hard_header_len + - ddp_dl->header_length + (len_hops & 1023)))); - - /* FIXME: use skb->cb to be able to use shared skbs */ - ddp->deh_len_hops = htons(len_hops); - - /* - * Send the buffer onwards - * - * Now we must always be careful. If it's come from LocalTalk to - * EtherTalk it might not fit - * - * Order matters here: If a packet has to be copied to make a new - * headroom (rare hopefully) then it won't need unsharing. - * - * Note. ddp-> becomes invalid at the realloc. - */ - if (skb_headroom(skb) < 22) { - /* 22 bytes - 12 ether, 2 len, 3 802.2 5 snap */ - struct sk_buff *nskb = skb_realloc_headroom(skb, 32); - kfree_skb(skb); - skb = nskb; - } else - skb = skb_unshare(skb, GFP_ATOMIC); - - /* - * If the buffer didn't vanish into the lack of space bitbucket we can - * send it. - */ - if (skb == NULL) - goto drop; - - if (aarp_send_ddp(rt->dev, skb, &ta, NULL) == NET_XMIT_DROP) - return NET_RX_DROP; - return NET_RX_SUCCESS; -free_it: - kfree_skb(skb); -drop: - return NET_RX_DROP; -} - -/** - * atalk_rcv - Receive a packet (in skb) from device dev - * @skb - packet received - * @dev - network device where the packet comes from - * @pt - packet type - * - * Receive a packet (in skb) from device dev. This has come from the SNAP - * decoder, and on entry skb->transport_header is the DDP header, skb->len - * is the DDP header, skb->len is the DDP length. The physical headers - * have been extracted. PPP should probably pass frames marked as for this - * layer. [ie ARPHRD_ETHERTALK] - */ -static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, struct net_device *orig_dev) -{ - struct ddpehdr *ddp; - struct sock *sock; - struct atalk_iface *atif; - struct sockaddr_at tosat; - int origlen; - __u16 len_hops; - - if (!net_eq(dev_net(dev), &init_net)) - goto drop; - - /* Don't mangle buffer if shared */ - if (!(skb = skb_share_check(skb, GFP_ATOMIC))) - goto out; - - /* Size check and make sure header is contiguous */ - if (!pskb_may_pull(skb, sizeof(*ddp))) - goto drop; - - ddp = ddp_hdr(skb); - - len_hops = ntohs(ddp->deh_len_hops); - - /* Trim buffer in case of stray trailing data */ - origlen = skb->len; - skb_trim(skb, min_t(unsigned int, skb->len, len_hops & 1023)); - - /* - * Size check to see if ddp->deh_len was crap - * (Otherwise we'll detonate most spectacularly - * in the middle of atalk_checksum() or recvmsg()). - */ - if (skb->len < sizeof(*ddp) || skb->len < (len_hops & 1023)) { - pr_debug("AppleTalk: dropping corrupted frame (deh_len=%u, " - "skb->len=%u)\n", len_hops & 1023, skb->len); - goto drop; - } - - /* - * Any checksums. Note we don't do htons() on this == is assumed to be - * valid for net byte orders all over the networking code... - */ - if (ddp->deh_sum && - atalk_checksum(skb, len_hops & 1023) != ddp->deh_sum) - /* Not a valid AppleTalk frame - dustbin time */ - goto drop; - - /* Check the packet is aimed at us */ - if (!ddp->deh_dnet) /* Net 0 is 'this network' */ - atif = atalk_find_anynet(ddp->deh_dnode, dev); - else - atif = atalk_find_interface(ddp->deh_dnet, ddp->deh_dnode); - - if (!atif) { - /* Not ours, so we route the packet via the correct - * AppleTalk iface - */ - return atalk_route_packet(skb, dev, ddp, len_hops, origlen); - } - - /* if IP over DDP is not selected this code will be optimized out */ - if (is_ip_over_ddp(skb)) - return handle_ip_over_ddp(skb); - /* - * Which socket - atalk_search_socket() looks for a *full match* - * of the tuple. - */ - tosat.sat_addr.s_net = ddp->deh_dnet; - tosat.sat_addr.s_node = ddp->deh_dnode; - tosat.sat_port = ddp->deh_dport; - - sock = atalk_search_socket(&tosat, atif); - if (!sock) /* But not one of our sockets */ - goto drop; - - /* Queue packet (standard) */ - skb->sk = sock; - - if (sock_queue_rcv_skb(sock, skb) < 0) - goto drop; - - return NET_RX_SUCCESS; - -drop: - kfree_skb(skb); -out: - return NET_RX_DROP; - -} - -/* - * Receive a LocalTalk frame. We make some demands on the caller here. - * Caller must provide enough headroom on the packet to pull the short - * header and append a long one. - */ -static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, struct net_device *orig_dev) -{ - if (!net_eq(dev_net(dev), &init_net)) - goto freeit; - - /* Expand any short form frames */ - if (skb_mac_header(skb)[2] == 1) { - struct ddpehdr *ddp; - /* Find our address */ - struct atalk_addr *ap = atalk_find_dev_addr(dev); - - if (!ap || skb->len < sizeof(__be16) || skb->len > 1023) - goto freeit; - - /* Don't mangle buffer if shared */ - if (!(skb = skb_share_check(skb, GFP_ATOMIC))) - return 0; - - /* - * The push leaves us with a ddephdr not an shdr, and - * handily the port bytes in the right place preset. - */ - ddp = (struct ddpehdr *) skb_push(skb, sizeof(*ddp) - 4); - - /* Now fill in the long header */ - - /* - * These two first. The mac overlays the new source/dest - * network information so we MUST copy these before - * we write the network numbers ! - */ - - ddp->deh_dnode = skb_mac_header(skb)[0]; /* From physical header */ - ddp->deh_snode = skb_mac_header(skb)[1]; /* From physical header */ - - ddp->deh_dnet = ap->s_net; /* Network number */ - ddp->deh_snet = ap->s_net; - ddp->deh_sum = 0; /* No checksum */ - /* - * Not sure about this bit... - */ - /* Non routable, so force a drop if we slip up later */ - ddp->deh_len_hops = htons(skb->len + (DDP_MAXHOPS << 10)); - } - skb_reset_transport_header(skb); - - return atalk_rcv(skb, dev, pt, orig_dev); -freeit: - kfree_skb(skb); - return 0; -} - -static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, - size_t len) -{ - struct sock *sk = sock->sk; - struct atalk_sock *at = at_sk(sk); - struct sockaddr_at *usat = (struct sockaddr_at *)msg->msg_name; - int flags = msg->msg_flags; - int loopback = 0; - struct sockaddr_at local_satalk, gsat; - struct sk_buff *skb; - struct net_device *dev; - struct ddpehdr *ddp; - int size; - struct atalk_route *rt; - int err; - - if (flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) - return -EINVAL; - - if (len > DDP_MAXSZ) - return -EMSGSIZE; - - lock_kernel(); - if (usat) { - err = -EBUSY; - if (sock_flag(sk, SOCK_ZAPPED)) - if (atalk_autobind(sk) < 0) - goto out; - - err = -EINVAL; - if (msg->msg_namelen < sizeof(*usat) || - usat->sat_family != AF_APPLETALK) - goto out; - - err = -EPERM; - /* netatalk didn't implement this check */ - if (usat->sat_addr.s_node == ATADDR_BCAST && - !sock_flag(sk, SOCK_BROADCAST)) { - goto out; - } - } else { - err = -ENOTCONN; - if (sk->sk_state != TCP_ESTABLISHED) - goto out; - usat = &local_satalk; - usat->sat_family = AF_APPLETALK; - usat->sat_port = at->dest_port; - usat->sat_addr.s_node = at->dest_node; - usat->sat_addr.s_net = at->dest_net; - } - - /* Build a packet */ - SOCK_DEBUG(sk, "SK %p: Got address.\n", sk); - - /* For headers */ - size = sizeof(struct ddpehdr) + len + ddp_dl->header_length; - - if (usat->sat_addr.s_net || usat->sat_addr.s_node == ATADDR_ANYNODE) { - rt = atrtr_find(&usat->sat_addr); - } else { - struct atalk_addr at_hint; - - at_hint.s_node = 0; - at_hint.s_net = at->src_net; - - rt = atrtr_find(&at_hint); - } - err = ENETUNREACH; - if (!rt) - goto out; - - dev = rt->dev; - - SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n", - sk, size, dev->name); - - size += dev->hard_header_len; - skb = sock_alloc_send_skb(sk, size, (flags & MSG_DONTWAIT), &err); - if (!skb) - goto out; - - skb->sk = sk; - skb_reserve(skb, ddp_dl->header_length); - skb_reserve(skb, dev->hard_header_len); - skb->dev = dev; - - SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk); - - ddp = (struct ddpehdr *)skb_put(skb, sizeof(struct ddpehdr)); - ddp->deh_len_hops = htons(len + sizeof(*ddp)); - ddp->deh_dnet = usat->sat_addr.s_net; - ddp->deh_snet = at->src_net; - ddp->deh_dnode = usat->sat_addr.s_node; - ddp->deh_snode = at->src_node; - ddp->deh_dport = usat->sat_port; - ddp->deh_sport = at->src_port; - - SOCK_DEBUG(sk, "SK %p: Copy user data (%Zd bytes).\n", sk, len); - - err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); - if (err) { - kfree_skb(skb); - err = -EFAULT; - goto out; - } - - if (sk->sk_no_check == 1) - ddp->deh_sum = 0; - else - ddp->deh_sum = atalk_checksum(skb, len + sizeof(*ddp)); - - /* - * Loopback broadcast packets to non gateway targets (ie routes - * to group we are in) - */ - if (ddp->deh_dnode == ATADDR_BCAST && - !(rt->flags & RTF_GATEWAY) && !(dev->flags & IFF_LOOPBACK)) { - struct sk_buff *skb2 = skb_copy(skb, GFP_KERNEL); - - if (skb2) { - loopback = 1; - SOCK_DEBUG(sk, "SK %p: send out(copy).\n", sk); - /* - * If it fails it is queued/sent above in the aarp queue - */ - aarp_send_ddp(dev, skb2, &usat->sat_addr, NULL); - } - } - - if (dev->flags & IFF_LOOPBACK || loopback) { - SOCK_DEBUG(sk, "SK %p: Loop back.\n", sk); - /* loop back */ - skb_orphan(skb); - if (ddp->deh_dnode == ATADDR_BCAST) { - struct atalk_addr at_lo; - - at_lo.s_node = 0; - at_lo.s_net = 0; - - rt = atrtr_find(&at_lo); - if (!rt) { - kfree_skb(skb); - err = -ENETUNREACH; - goto out; - } - dev = rt->dev; - skb->dev = dev; - } - ddp_dl->request(ddp_dl, skb, dev->dev_addr); - } else { - SOCK_DEBUG(sk, "SK %p: send out.\n", sk); - if (rt->flags & RTF_GATEWAY) { - gsat.sat_addr = rt->gateway; - usat = &gsat; - } - - /* - * If it fails it is queued/sent above in the aarp queue - */ - aarp_send_ddp(dev, skb, &usat->sat_addr, NULL); - } - SOCK_DEBUG(sk, "SK %p: Done write (%Zd).\n", sk, len); - -out: - unlock_kernel(); - return err ? : len; -} - -static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, - size_t size, int flags) -{ - struct sock *sk = sock->sk; - struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name; - struct ddpehdr *ddp; - int copied = 0; - int offset = 0; - int err = 0; - struct sk_buff *skb; - - lock_kernel(); - skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, - flags & MSG_DONTWAIT, &err); - if (!skb) - goto out; - - /* FIXME: use skb->cb to be able to use shared skbs */ - ddp = ddp_hdr(skb); - copied = ntohs(ddp->deh_len_hops) & 1023; - - if (sk->sk_type != SOCK_RAW) { - offset = sizeof(*ddp); - copied -= offset; - } - - if (copied > size) { - copied = size; - msg->msg_flags |= MSG_TRUNC; - } - err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied); - - if (!err) { - if (sat) { - sat->sat_family = AF_APPLETALK; - sat->sat_port = ddp->deh_sport; - sat->sat_addr.s_node = ddp->deh_snode; - sat->sat_addr.s_net = ddp->deh_snet; - } - msg->msg_namelen = sizeof(*sat); - } - - skb_free_datagram(sk, skb); /* Free the datagram. */ - -out: - unlock_kernel(); - return err ? : copied; -} - - -/* - * AppleTalk ioctl calls. - */ -static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) -{ - int rc = -ENOIOCTLCMD; - struct sock *sk = sock->sk; - void __user *argp = (void __user *)arg; - - switch (cmd) { - /* Protocol layer */ - case TIOCOUTQ: { - long amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); - - if (amount < 0) - amount = 0; - rc = put_user(amount, (int __user *)argp); - break; - } - case TIOCINQ: { - /* - * These two are safe on a single CPU system as only - * user tasks fiddle here - */ - struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); - long amount = 0; - - if (skb) - amount = skb->len - sizeof(struct ddpehdr); - rc = put_user(amount, (int __user *)argp); - break; - } - case SIOCGSTAMP: - rc = sock_get_timestamp(sk, argp); - break; - case SIOCGSTAMPNS: - rc = sock_get_timestampns(sk, argp); - break; - /* Routing */ - case SIOCADDRT: - case SIOCDELRT: - rc = -EPERM; - if (capable(CAP_NET_ADMIN)) - rc = atrtr_ioctl(cmd, argp); - break; - /* Interface */ - case SIOCGIFADDR: - case SIOCSIFADDR: - case SIOCGIFBRDADDR: - case SIOCATALKDIFADDR: - case SIOCDIFADDR: - case SIOCSARP: /* proxy AARP */ - case SIOCDARP: /* proxy AARP */ - rtnl_lock(); - rc = atif_ioctl(cmd, argp); - rtnl_unlock(); - break; - } - - return rc; -} - - -#ifdef CONFIG_COMPAT -static int atalk_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) -{ - /* - * SIOCATALKDIFADDR is a SIOCPROTOPRIVATE ioctl number, so we - * cannot handle it in common code. The data we access if ifreq - * here is compatible, so we can simply call the native - * handler. - */ - if (cmd == SIOCATALKDIFADDR) - return atalk_ioctl(sock, cmd, (unsigned long)compat_ptr(arg)); - - return -ENOIOCTLCMD; -} -#endif - - -static const struct net_proto_family atalk_family_ops = { - .family = PF_APPLETALK, - .create = atalk_create, - .owner = THIS_MODULE, -}; - -static const struct proto_ops atalk_dgram_ops = { - .family = PF_APPLETALK, - .owner = THIS_MODULE, - .release = atalk_release, - .bind = atalk_bind, - .connect = atalk_connect, - .socketpair = sock_no_socketpair, - .accept = sock_no_accept, - .getname = atalk_getname, - .poll = atalk_poll, - .ioctl = atalk_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = atalk_compat_ioctl, -#endif - .listen = sock_no_listen, - .shutdown = sock_no_shutdown, - .setsockopt = sock_no_setsockopt, - .getsockopt = sock_no_getsockopt, - .sendmsg = atalk_sendmsg, - .recvmsg = atalk_recvmsg, - .mmap = sock_no_mmap, - .sendpage = sock_no_sendpage, -}; - -static struct notifier_block ddp_notifier = { - .notifier_call = ddp_device_event, -}; - -static struct packet_type ltalk_packet_type __read_mostly = { - .type = cpu_to_be16(ETH_P_LOCALTALK), - .func = ltalk_rcv, -}; - -static struct packet_type ppptalk_packet_type __read_mostly = { - .type = cpu_to_be16(ETH_P_PPPTALK), - .func = atalk_rcv, -}; - -static unsigned char ddp_snap_id[] = { 0x08, 0x00, 0x07, 0x80, 0x9B }; - -/* Export symbols for use by drivers when AppleTalk is a module */ -EXPORT_SYMBOL(atrtr_get_dev); -EXPORT_SYMBOL(atalk_find_dev_addr); - -static const char atalk_err_snap[] __initconst = - KERN_CRIT "Unable to register DDP with SNAP.\n"; - -/* Called by proto.c on kernel start up */ -static int __init atalk_init(void) -{ - int rc = proto_register(&ddp_proto, 0); - - if (rc != 0) - goto out; - - (void)sock_register(&atalk_family_ops); - ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv); - if (!ddp_dl) - printk(atalk_err_snap); - - dev_add_pack(<alk_packet_type); - dev_add_pack(&ppptalk_packet_type); - - register_netdevice_notifier(&ddp_notifier); - aarp_proto_init(); - atalk_proc_init(); - atalk_register_sysctl(); -out: - return rc; -} -module_init(atalk_init); - -/* - * No explicit module reference count manipulation is needed in the - * protocol. Socket layer sets module reference count for us - * and interfaces reference counting is done - * by the network device layer. - * - * Ergo, before the AppleTalk module can be removed, all AppleTalk - * sockets be closed from user space. - */ -static void __exit atalk_exit(void) -{ -#ifdef CONFIG_SYSCTL - atalk_unregister_sysctl(); -#endif /* CONFIG_SYSCTL */ - atalk_proc_exit(); - aarp_cleanup_module(); /* General aarp clean-up. */ - unregister_netdevice_notifier(&ddp_notifier); - dev_remove_pack(<alk_packet_type); - dev_remove_pack(&ppptalk_packet_type); - unregister_snap_client(ddp_dl); - sock_unregister(PF_APPLETALK); - proto_unregister(&ddp_proto); -} -module_exit(atalk_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Alan Cox "); -MODULE_DESCRIPTION("AppleTalk 0.20\n"); -MODULE_ALIAS_NETPROTO(PF_APPLETALK); diff --git a/drivers/staging/appletalk/dev.c b/drivers/staging/appletalk/dev.c deleted file mode 100644 index 6c8016f61866..000000000000 --- a/drivers/staging/appletalk/dev.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Moved here from drivers/net/net_init.c, which is: - * Written 1993,1994,1995 by Donald Becker. - */ - -#include -#include -#include -#include -#include - -static void ltalk_setup(struct net_device *dev) -{ - /* Fill in the fields of the device structure with localtalk-generic values. */ - - dev->type = ARPHRD_LOCALTLK; - dev->hard_header_len = LTALK_HLEN; - dev->mtu = LTALK_MTU; - dev->addr_len = LTALK_ALEN; - dev->tx_queue_len = 10; - - dev->broadcast[0] = 0xFF; - - dev->flags = IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP; -} - -/** - * alloc_ltalkdev - Allocates and sets up an localtalk device - * @sizeof_priv: Size of additional driver-private structure to be allocated - * for this localtalk device - * - * Fill in the fields of the device structure with localtalk-generic - * values. Basically does everything except registering the device. - * - * Constructs a new net device, complete with a private data area of - * size @sizeof_priv. A 32-byte (not bit) alignment is enforced for - * this private data area. - */ - -struct net_device *alloc_ltalkdev(int sizeof_priv) -{ - return alloc_netdev(sizeof_priv, "lt%d", ltalk_setup); -} -EXPORT_SYMBOL(alloc_ltalkdev); diff --git a/drivers/staging/appletalk/ipddp.c b/drivers/staging/appletalk/ipddp.c deleted file mode 100644 index 58b4e6098ad4..000000000000 --- a/drivers/staging/appletalk/ipddp.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * ipddp.c: IP to Appletalk-IP Encapsulation driver for Linux - * Appletalk-IP to IP Decapsulation driver for Linux - * - * Authors: - * - DDP-IP Encap by: Bradford W. Johnson - * - DDP-IP Decap by: Jay Schulist - * - * Derived from: - * - Almost all code already existed in net/appletalk/ddp.c I just - * moved/reorginized it into a driver file. Original IP-over-DDP code - * was done by Bradford W. Johnson - * - skeleton.c: A network driver outline for linux. - * Written 1993-94 by Donald Becker. - * - dummy.c: A dummy net driver. By Nick Holloway. - * - MacGate: A user space Daemon for Appletalk-IP Decap for - * Linux by Jay Schulist - * - * Copyright 1993 United States Government as represented by the - * Director, National Security Agency. - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "atalk.h" -#include "ipddp.h" /* Our stuff */ - -static const char version[] = KERN_INFO "ipddp.c:v0.01 8/28/97 Bradford W. Johnson \n"; - -static struct ipddp_route *ipddp_route_list; -static DEFINE_SPINLOCK(ipddp_route_lock); - -#ifdef CONFIG_IPDDP_ENCAP -static int ipddp_mode = IPDDP_ENCAP; -#else -static int ipddp_mode = IPDDP_DECAP; -#endif - -/* Index to functions, as function prototypes. */ -static netdev_tx_t ipddp_xmit(struct sk_buff *skb, - struct net_device *dev); -static int ipddp_create(struct ipddp_route *new_rt); -static int ipddp_delete(struct ipddp_route *rt); -static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt); -static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); - -static const struct net_device_ops ipddp_netdev_ops = { - .ndo_start_xmit = ipddp_xmit, - .ndo_do_ioctl = ipddp_ioctl, - .ndo_change_mtu = eth_change_mtu, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, -}; - -static struct net_device * __init ipddp_init(void) -{ - static unsigned version_printed; - struct net_device *dev; - int err; - - dev = alloc_etherdev(0); - if (!dev) - return ERR_PTR(-ENOMEM); - - dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; - strcpy(dev->name, "ipddp%d"); - - if (version_printed++ == 0) - printk(version); - - /* Initialize the device structure. */ - dev->netdev_ops = &ipddp_netdev_ops; - - dev->type = ARPHRD_IPDDP; /* IP over DDP tunnel */ - dev->mtu = 585; - dev->flags |= IFF_NOARP; - - /* - * The worst case header we will need is currently a - * ethernet header (14 bytes) and a ddp header (sizeof ddpehdr+1) - * We send over SNAP so that takes another 8 bytes. - */ - dev->hard_header_len = 14+8+sizeof(struct ddpehdr)+1; - - err = register_netdev(dev); - if (err) { - free_netdev(dev); - return ERR_PTR(err); - } - - /* Let the user now what mode we are in */ - if(ipddp_mode == IPDDP_ENCAP) - printk("%s: Appletalk-IP Encap. mode by Bradford W. Johnson \n", - dev->name); - if(ipddp_mode == IPDDP_DECAP) - printk("%s: Appletalk-IP Decap. mode by Jay Schulist \n", - dev->name); - - return dev; -} - - -/* - * Transmit LLAP/ELAP frame using aarp_send_ddp. - */ -static netdev_tx_t ipddp_xmit(struct sk_buff *skb, struct net_device *dev) -{ - __be32 paddr = skb_rtable(skb)->rt_gateway; - struct ddpehdr *ddp; - struct ipddp_route *rt; - struct atalk_addr *our_addr; - - spin_lock(&ipddp_route_lock); - - /* - * Find appropriate route to use, based only on IP number. - */ - for(rt = ipddp_route_list; rt != NULL; rt = rt->next) - { - if(rt->ip == paddr) - break; - } - if(rt == NULL) { - spin_unlock(&ipddp_route_lock); - return NETDEV_TX_OK; - } - - our_addr = atalk_find_dev_addr(rt->dev); - - if(ipddp_mode == IPDDP_DECAP) - /* - * Pull off the excess room that should not be there. - * This is due to a hard-header problem. This is the - * quick fix for now though, till it breaks. - */ - skb_pull(skb, 35-(sizeof(struct ddpehdr)+1)); - - /* Create the Extended DDP header */ - ddp = (struct ddpehdr *)skb->data; - ddp->deh_len_hops = htons(skb->len + (1<<10)); - ddp->deh_sum = 0; - - /* - * For Localtalk we need aarp_send_ddp to strip the - * long DDP header and place a shot DDP header on it. - */ - if(rt->dev->type == ARPHRD_LOCALTLK) - { - ddp->deh_dnet = 0; /* FIXME more hops?? */ - ddp->deh_snet = 0; - } - else - { - ddp->deh_dnet = rt->at.s_net; /* FIXME more hops?? */ - ddp->deh_snet = our_addr->s_net; - } - ddp->deh_dnode = rt->at.s_node; - ddp->deh_snode = our_addr->s_node; - ddp->deh_dport = 72; - ddp->deh_sport = 72; - - *((__u8 *)(ddp+1)) = 22; /* ddp type = IP */ - - skb->protocol = htons(ETH_P_ATALK); /* Protocol has changed */ - - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - - aarp_send_ddp(rt->dev, skb, &rt->at, NULL); - - spin_unlock(&ipddp_route_lock); - - return NETDEV_TX_OK; -} - -/* - * Create a routing entry. We first verify that the - * record does not already exist. If it does we return -EEXIST - */ -static int ipddp_create(struct ipddp_route *new_rt) -{ - struct ipddp_route *rt = kmalloc(sizeof(*rt), GFP_KERNEL); - - if (rt == NULL) - return -ENOMEM; - - rt->ip = new_rt->ip; - rt->at = new_rt->at; - rt->next = NULL; - if ((rt->dev = atrtr_get_dev(&rt->at)) == NULL) { - kfree(rt); - return -ENETUNREACH; - } - - spin_lock_bh(&ipddp_route_lock); - if (__ipddp_find_route(rt)) { - spin_unlock_bh(&ipddp_route_lock); - kfree(rt); - return -EEXIST; - } - - rt->next = ipddp_route_list; - ipddp_route_list = rt; - - spin_unlock_bh(&ipddp_route_lock); - - return 0; -} - -/* - * Delete a route, we only delete a FULL match. - * If route does not exist we return -ENOENT. - */ -static int ipddp_delete(struct ipddp_route *rt) -{ - struct ipddp_route **r = &ipddp_route_list; - struct ipddp_route *tmp; - - spin_lock_bh(&ipddp_route_lock); - while((tmp = *r) != NULL) - { - if(tmp->ip == rt->ip && - tmp->at.s_net == rt->at.s_net && - tmp->at.s_node == rt->at.s_node) - { - *r = tmp->next; - spin_unlock_bh(&ipddp_route_lock); - kfree(tmp); - return 0; - } - r = &tmp->next; - } - - spin_unlock_bh(&ipddp_route_lock); - return -ENOENT; -} - -/* - * Find a routing entry, we only return a FULL match - */ -static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt) -{ - struct ipddp_route *f; - - for(f = ipddp_route_list; f != NULL; f = f->next) - { - if(f->ip == rt->ip && - f->at.s_net == rt->at.s_net && - f->at.s_node == rt->at.s_node) - return f; - } - - return NULL; -} - -static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - struct ipddp_route __user *rt = ifr->ifr_data; - struct ipddp_route rcp, rcp2, *rp; - - if(!capable(CAP_NET_ADMIN)) - return -EPERM; - - if(copy_from_user(&rcp, rt, sizeof(rcp))) - return -EFAULT; - - switch(cmd) - { - case SIOCADDIPDDPRT: - return ipddp_create(&rcp); - - case SIOCFINDIPDDPRT: - spin_lock_bh(&ipddp_route_lock); - rp = __ipddp_find_route(&rcp); - if (rp) - memcpy(&rcp2, rp, sizeof(rcp2)); - spin_unlock_bh(&ipddp_route_lock); - - if (rp) { - if (copy_to_user(rt, &rcp2, - sizeof(struct ipddp_route))) - return -EFAULT; - return 0; - } else - return -ENOENT; - - case SIOCDELIPDDPRT: - return ipddp_delete(&rcp); - - default: - return -EINVAL; - } -} - -static struct net_device *dev_ipddp; - -MODULE_LICENSE("GPL"); -module_param(ipddp_mode, int, 0); - -static int __init ipddp_init_module(void) -{ - dev_ipddp = ipddp_init(); - if (IS_ERR(dev_ipddp)) - return PTR_ERR(dev_ipddp); - return 0; -} - -static void __exit ipddp_cleanup_module(void) -{ - struct ipddp_route *p; - - unregister_netdev(dev_ipddp); - free_netdev(dev_ipddp); - - while (ipddp_route_list) { - p = ipddp_route_list->next; - kfree(ipddp_route_list); - ipddp_route_list = p; - } -} - -module_init(ipddp_init_module); -module_exit(ipddp_cleanup_module); diff --git a/drivers/staging/appletalk/ipddp.h b/drivers/staging/appletalk/ipddp.h deleted file mode 100644 index 531519da99a3..000000000000 --- a/drivers/staging/appletalk/ipddp.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * ipddp.h: Header for IP-over-DDP driver for Linux. - */ - -#ifndef __LINUX_IPDDP_H -#define __LINUX_IPDDP_H - -#ifdef __KERNEL__ - -#define SIOCADDIPDDPRT (SIOCDEVPRIVATE) -#define SIOCDELIPDDPRT (SIOCDEVPRIVATE+1) -#define SIOCFINDIPDDPRT (SIOCDEVPRIVATE+2) - -struct ipddp_route -{ - struct net_device *dev; /* Carrier device */ - __be32 ip; /* IP address */ - struct atalk_addr at; /* Gateway appletalk address */ - int flags; - struct ipddp_route *next; -}; - -#define IPDDP_ENCAP 1 -#define IPDDP_DECAP 2 - -#endif /* __KERNEL__ */ -#endif /* __LINUX_IPDDP_H */ diff --git a/drivers/staging/appletalk/ltpc.c b/drivers/staging/appletalk/ltpc.c deleted file mode 100644 index 60caf892695e..000000000000 --- a/drivers/staging/appletalk/ltpc.c +++ /dev/null @@ -1,1288 +0,0 @@ -/*** ltpc.c -- a driver for the LocalTalk PC card. - * - * Copyright (c) 1995,1996 Bradford W. Johnson - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * This is ALPHA code at best. It may not work for you. It may - * damage your equipment. It may damage your relations with other - * users of your network. Use it at your own risk! - * - * Based in part on: - * skeleton.c by Donald Becker - * dummy.c by Nick Holloway and Alan Cox - * loopback.c by Ross Biro, Fred van Kampen, Donald Becker - * the netatalk source code (UMICH) - * lots of work on the card... - * - * I do not have access to the (proprietary) SDK that goes with the card. - * If you do, I don't want to know about it, and you can probably write - * a better driver yourself anyway. This does mean that the pieces that - * talk to the card are guesswork on my part, so use at your own risk! - * - * This is my first try at writing Linux networking code, and is also - * guesswork. Again, use at your own risk! (Although on this part, I'd - * welcome suggestions) - * - * This is a loadable kernel module which seems to work at my site - * consisting of a 1.2.13 linux box running netatalk 1.3.3, and with - * the kernel support from 1.3.3b2 including patches routing.patch - * and ddp.disappears.from.chooser. In order to run it, you will need - * to patch ddp.c and aarp.c in the kernel, but only a little... - * - * I'm fairly confident that while this is arguably badly written, the - * problems that people experience will be "higher level", that is, with - * complications in the netatalk code. The driver itself doesn't do - * anything terribly complicated -- it pretends to be an ether device - * as far as netatalk is concerned, strips the DDP data out of the ether - * frame and builds a LLAP packet to send out the card. In the other - * direction, it receives LLAP frames from the card and builds a fake - * ether packet that it then tosses up to the networking code. You can - * argue (correctly) that this is an ugly way to do things, but it - * requires a minimal amount of fooling with the code in ddp.c and aarp.c. - * - * The card will do a lot more than is used here -- I *think* it has the - * layers up through ATP. Even if you knew how that part works (which I - * don't) it would be a big job to carve up the kernel ddp code to insert - * things at a higher level, and probably a bad idea... - * - * There are a number of other cards that do LocalTalk on the PC. If - * nobody finds any insurmountable (at the netatalk level) problems - * here, this driver should encourage people to put some work into the - * other cards (some of which I gather are still commercially available) - * and also to put hooks for LocalTalk into the official ddp code. - * - * I welcome comments and suggestions. This is my first try at Linux - * networking stuff, and there are probably lots of things that I did - * suboptimally. - * - ***/ - -/*** - * - * $Log: ltpc.c,v $ - * Revision 1.1.2.1 2000/03/01 05:35:07 jgarzik - * at and tr cleanup - * - * Revision 1.8 1997/01/28 05:44:54 bradford - * Clean up for non-module a little. - * Hacked about a bit to clean things up - Alan Cox - * Probably broken it from the origina 1.8 - * - - * 1998/11/09: David Huggins-Daines - * Cleaned up the initialization code to use the standard autoirq methods, - and to probe for things in the standard order of i/o, irq, dma. This - removes the "reset the reset" hack, because I couldn't figure out an - easy way to get the card to trigger an interrupt after it. - * Added support for passing configuration parameters on the kernel command - line and through insmod - * Changed the device name from "ltalk0" to "lt0", both to conform with the - other localtalk driver, and to clear up the inconsistency between the - module and the non-module versions of the driver :-) - * Added a bunch of comments (I was going to make some enums for the state - codes and the register offsets, but I'm still not sure exactly what their - semantics are) - * Don't poll anymore in interrupt-driven mode - * It seems to work as a module now (as of 2.1.127), but I don't think - I'm responsible for that... - - * - * Revision 1.7 1996/12/12 03:42:33 bradford - * DMA alloc cribbed from 3c505.c. - * - * Revision 1.6 1996/12/12 03:18:58 bradford - * Added virt_to_bus; works in 2.1.13. - * - * Revision 1.5 1996/12/12 03:13:22 root - * xmitQel initialization -- think through better though. - * - * Revision 1.4 1996/06/18 14:55:55 root - * Change names to ltpc. Tabs. Took a shot at dma alloc, - * although more needs to be done eventually. - * - * Revision 1.3 1996/05/22 14:59:39 root - * Change dev->open, dev->close to track dummy.c in 1.99.(around 7) - * - * Revision 1.2 1996/05/22 14:58:24 root - * Change tabs mostly. - * - * Revision 1.1 1996/04/23 04:45:09 root - * Initial revision - * - * Revision 0.16 1996/03/05 15:59:56 root - * Change ARPHRD_LOCALTLK definition to the "real" one. - * - * Revision 0.15 1996/03/05 06:28:30 root - * Changes for kernel 1.3.70. Still need a few patches to kernel, but - * it's getting closer. - * - * Revision 0.14 1996/02/25 17:38:32 root - * More cleanups. Removed query to card on get_stats. - * - * Revision 0.13 1996/02/21 16:27:40 root - * Refix debug_print_skb. Fix mac.raw gotcha that appeared in 1.3.65. - * Clean up receive code a little. - * - * Revision 0.12 1996/02/19 16:34:53 root - * Fix debug_print_skb. Kludge outgoing snet to 0 when using startup - * range. Change debug to mask: 1 for verbose, 2 for higher level stuff - * including packet printing, 4 for lower level (card i/o) stuff. - * - * Revision 0.11 1996/02/12 15:53:38 root - * Added router sends (requires new aarp.c patch) - * - * Revision 0.10 1996/02/11 00:19:35 root - * Change source LTALK_LOGGING debug switch to insmod ... debug=2. - * - * Revision 0.9 1996/02/10 23:59:35 root - * Fixed those fixes for 1.2 -- DANGER! The at.h that comes with netatalk - * has a *different* definition of struct sockaddr_at than the Linux kernel - * does. This is an "insidious and invidious" bug... - * (Actually the preceding comment is false -- it's the atalk.h in the - * ancient atalk-0.06 that's the problem) - * - * Revision 0.8 1996/02/10 19:09:00 root - * Merge 1.3 changes. Tested OK under 1.3.60. - * - * Revision 0.7 1996/02/10 17:56:56 root - * Added debug=1 parameter on insmod for debugging prints. Tried - * to fix timer unload on rmmod, but I don't think that's the problem. - * - * Revision 0.6 1995/12/31 19:01:09 root - * Clean up rmmod, irq comments per feedback from Corin Anderson (Thanks Corey!) - * Clean up initial probing -- sometimes the card wakes up latched in reset. - * - * Revision 0.5 1995/12/22 06:03:44 root - * Added comments in front and cleaned up a bit. - * This version sent out to people. - * - * Revision 0.4 1995/12/18 03:46:44 root - * Return shortDDP to longDDP fake to 0/0. Added command structs. - * - ***/ - -/* ltpc jumpers are: -* -* Interrupts -- set at most one. If none are set, the driver uses -* polled mode. Because the card was developed in the XT era, the -* original documentation refers to IRQ2. Since you'll be running -* this on an AT (or later) class machine, that really means IRQ9. -* -* SW1 IRQ 4 -* SW2 IRQ 3 -* SW3 IRQ 9 (2 in original card documentation only applies to XT) -* -* -* DMA -- choose DMA 1 or 3, and set both corresponding switches. -* -* SW4 DMA 3 -* SW5 DMA 1 -* SW6 DMA 3 -* SW7 DMA 1 -* -* -* I/O address -- choose one. -* -* SW8 220 / 240 -*/ - -/* To have some stuff logged, do -* insmod ltpc.o debug=1 -* -* For a whole bunch of stuff, use higher numbers. -* -* The default is 0, i.e. no messages except for the probe results. -*/ - -/* insmod-tweakable variables */ -static int debug; -#define DEBUG_VERBOSE 1 -#define DEBUG_UPPER 2 -#define DEBUG_LOWER 4 - -static int io; -static int irq; -static int dma; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* our stuff */ -#include "atalk.h" -#include "ltpc.h" - -static DEFINE_SPINLOCK(txqueue_lock); -static DEFINE_SPINLOCK(mbox_lock); - -/* function prototypes */ -static int do_read(struct net_device *dev, void *cbuf, int cbuflen, - void *dbuf, int dbuflen); -static int sendup_buffer (struct net_device *dev); - -/* Dma Memory related stuff, cribbed directly from 3c505.c */ - -static unsigned long dma_mem_alloc(int size) -{ - int order = get_order(size); - - return __get_dma_pages(GFP_KERNEL, order); -} - -/* DMA data buffer, DMA command buffer */ -static unsigned char *ltdmabuf; -static unsigned char *ltdmacbuf; - -/* private struct, holds our appletalk address */ - -struct ltpc_private -{ - struct atalk_addr my_addr; -}; - -/* transmit queue element struct */ - -struct xmitQel { - struct xmitQel *next; - /* command buffer */ - unsigned char *cbuf; - short cbuflen; - /* data buffer */ - unsigned char *dbuf; - short dbuflen; - unsigned char QWrite; /* read or write data */ - unsigned char mailbox; -}; - -/* the transmit queue itself */ - -static struct xmitQel *xmQhd, *xmQtl; - -static void enQ(struct xmitQel *qel) -{ - unsigned long flags; - qel->next = NULL; - - spin_lock_irqsave(&txqueue_lock, flags); - if (xmQtl) { - xmQtl->next = qel; - } else { - xmQhd = qel; - } - xmQtl = qel; - spin_unlock_irqrestore(&txqueue_lock, flags); - - if (debug & DEBUG_LOWER) - printk("enqueued a 0x%02x command\n",qel->cbuf[0]); -} - -static struct xmitQel *deQ(void) -{ - unsigned long flags; - int i; - struct xmitQel *qel=NULL; - - spin_lock_irqsave(&txqueue_lock, flags); - if (xmQhd) { - qel = xmQhd; - xmQhd = qel->next; - if(!xmQhd) xmQtl = NULL; - } - spin_unlock_irqrestore(&txqueue_lock, flags); - - if ((debug & DEBUG_LOWER) && qel) { - int n; - printk(KERN_DEBUG "ltpc: dequeued command "); - n = qel->cbuflen; - if (n>100) n=100; - for(i=0;icbuf[i]); - printk("\n"); - } - - return qel; -} - -/* and... the queue elements we'll be using */ -static struct xmitQel qels[16]; - -/* and their corresponding mailboxes */ -static unsigned char mailbox[16]; -static unsigned char mboxinuse[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - -static int wait_timeout(struct net_device *dev, int c) -{ - /* returns true if it stayed c */ - /* this uses base+6, but it's ok */ - int i; - - /* twenty second or so total */ - - for(i=0;i<200000;i++) { - if ( c != inb_p(dev->base_addr+6) ) return 0; - udelay(100); - } - return 1; /* timed out */ -} - -/* get the first free mailbox */ - -static int getmbox(void) -{ - unsigned long flags; - int i; - - spin_lock_irqsave(&mbox_lock, flags); - for(i=1;i<16;i++) if(!mboxinuse[i]) { - mboxinuse[i]=1; - spin_unlock_irqrestore(&mbox_lock, flags); - return i; - } - spin_unlock_irqrestore(&mbox_lock, flags); - return 0; -} - -/* read a command from the card */ -static void handlefc(struct net_device *dev) -{ - /* called *only* from idle, non-reentrant */ - int dma = dev->dma; - int base = dev->base_addr; - unsigned long flags; - - - flags=claim_dma_lock(); - disable_dma(dma); - clear_dma_ff(dma); - set_dma_mode(dma,DMA_MODE_READ); - set_dma_addr(dma,virt_to_bus(ltdmacbuf)); - set_dma_count(dma,50); - enable_dma(dma); - release_dma_lock(flags); - - inb_p(base+3); - inb_p(base+2); - - if ( wait_timeout(dev,0xfc) ) printk("timed out in handlefc\n"); -} - -/* read data from the card */ -static void handlefd(struct net_device *dev) -{ - int dma = dev->dma; - int base = dev->base_addr; - unsigned long flags; - - flags=claim_dma_lock(); - disable_dma(dma); - clear_dma_ff(dma); - set_dma_mode(dma,DMA_MODE_READ); - set_dma_addr(dma,virt_to_bus(ltdmabuf)); - set_dma_count(dma,800); - enable_dma(dma); - release_dma_lock(flags); - - inb_p(base+3); - inb_p(base+2); - - if ( wait_timeout(dev,0xfd) ) printk("timed out in handlefd\n"); - sendup_buffer(dev); -} - -static void handlewrite(struct net_device *dev) -{ - /* called *only* from idle, non-reentrant */ - /* on entry, 0xfb and ltdmabuf holds data */ - int dma = dev->dma; - int base = dev->base_addr; - unsigned long flags; - - flags=claim_dma_lock(); - disable_dma(dma); - clear_dma_ff(dma); - set_dma_mode(dma,DMA_MODE_WRITE); - set_dma_addr(dma,virt_to_bus(ltdmabuf)); - set_dma_count(dma,800); - enable_dma(dma); - release_dma_lock(flags); - - inb_p(base+3); - inb_p(base+2); - - if ( wait_timeout(dev,0xfb) ) { - flags=claim_dma_lock(); - printk("timed out in handlewrite, dma res %d\n", - get_dma_residue(dev->dma) ); - release_dma_lock(flags); - } -} - -static void handleread(struct net_device *dev) -{ - /* on entry, 0xfb */ - /* on exit, ltdmabuf holds data */ - int dma = dev->dma; - int base = dev->base_addr; - unsigned long flags; - - - flags=claim_dma_lock(); - disable_dma(dma); - clear_dma_ff(dma); - set_dma_mode(dma,DMA_MODE_READ); - set_dma_addr(dma,virt_to_bus(ltdmabuf)); - set_dma_count(dma,800); - enable_dma(dma); - release_dma_lock(flags); - - inb_p(base+3); - inb_p(base+2); - if ( wait_timeout(dev,0xfb) ) printk("timed out in handleread\n"); -} - -static void handlecommand(struct net_device *dev) -{ - /* on entry, 0xfa and ltdmacbuf holds command */ - int dma = dev->dma; - int base = dev->base_addr; - unsigned long flags; - - flags=claim_dma_lock(); - disable_dma(dma); - clear_dma_ff(dma); - set_dma_mode(dma,DMA_MODE_WRITE); - set_dma_addr(dma,virt_to_bus(ltdmacbuf)); - set_dma_count(dma,50); - enable_dma(dma); - release_dma_lock(flags); - inb_p(base+3); - inb_p(base+2); - if ( wait_timeout(dev,0xfa) ) printk("timed out in handlecommand\n"); -} - -/* ready made command for getting the result from the card */ -static unsigned char rescbuf[2] = {LT_GETRESULT,0}; -static unsigned char resdbuf[2]; - -static int QInIdle; - -/* idle expects to be called with the IRQ line high -- either because of - * an interrupt, or because the line is tri-stated - */ - -static void idle(struct net_device *dev) -{ - unsigned long flags; - int state; - /* FIXME This is initialized to shut the warning up, but I need to - * think this through again. - */ - struct xmitQel *q = NULL; - int oops; - int i; - int base = dev->base_addr; - - spin_lock_irqsave(&txqueue_lock, flags); - if(QInIdle) { - spin_unlock_irqrestore(&txqueue_lock, flags); - return; - } - QInIdle = 1; - spin_unlock_irqrestore(&txqueue_lock, flags); - - /* this tri-states the IRQ line */ - (void) inb_p(base+6); - - oops = 100; - -loop: - if (0>oops--) { - printk("idle: looped too many times\n"); - goto done; - } - - state = inb_p(base+6); - if (state != inb_p(base+6)) goto loop; - - switch(state) { - case 0xfc: - /* incoming command */ - if (debug & DEBUG_LOWER) printk("idle: fc\n"); - handlefc(dev); - break; - case 0xfd: - /* incoming data */ - if(debug & DEBUG_LOWER) printk("idle: fd\n"); - handlefd(dev); - break; - case 0xf9: - /* result ready */ - if (debug & DEBUG_LOWER) printk("idle: f9\n"); - if(!mboxinuse[0]) { - mboxinuse[0] = 1; - qels[0].cbuf = rescbuf; - qels[0].cbuflen = 2; - qels[0].dbuf = resdbuf; - qels[0].dbuflen = 2; - qels[0].QWrite = 0; - qels[0].mailbox = 0; - enQ(&qels[0]); - } - inb_p(dev->base_addr+1); - inb_p(dev->base_addr+0); - if( wait_timeout(dev,0xf9) ) - printk("timed out idle f9\n"); - break; - case 0xf8: - /* ?? */ - if (xmQhd) { - inb_p(dev->base_addr+1); - inb_p(dev->base_addr+0); - if(wait_timeout(dev,0xf8) ) - printk("timed out idle f8\n"); - } else { - goto done; - } - break; - case 0xfa: - /* waiting for command */ - if(debug & DEBUG_LOWER) printk("idle: fa\n"); - if (xmQhd) { - q=deQ(); - memcpy(ltdmacbuf,q->cbuf,q->cbuflen); - ltdmacbuf[1] = q->mailbox; - if (debug>1) { - int n; - printk("ltpc: sent command "); - n = q->cbuflen; - if (n>100) n=100; - for(i=0;iQWrite) { - memcpy(ltdmabuf,q->dbuf,q->dbuflen); - handlewrite(dev); - } else { - handleread(dev); - /* non-zero mailbox numbers are for - commmands, 0 is for GETRESULT - requests */ - if(q->mailbox) { - memcpy(q->dbuf,ltdmabuf,q->dbuflen); - } else { - /* this was a result */ - mailbox[ 0x0f & ltdmabuf[0] ] = ltdmabuf[1]; - mboxinuse[0]=0; - } - } - break; - } - goto loop; - -done: - QInIdle=0; - - /* now set the interrupts back as appropriate */ - /* the first read takes it out of tri-state (but still high) */ - /* the second resets it */ - /* note that after this point, any read of base+6 will - trigger an interrupt */ - - if (dev->irq) { - inb_p(base+7); - inb_p(base+7); - } -} - - -static int do_write(struct net_device *dev, void *cbuf, int cbuflen, - void *dbuf, int dbuflen) -{ - - int i = getmbox(); - int ret; - - if(i) { - qels[i].cbuf = (unsigned char *) cbuf; - qels[i].cbuflen = cbuflen; - qels[i].dbuf = (unsigned char *) dbuf; - qels[i].dbuflen = dbuflen; - qels[i].QWrite = 1; - qels[i].mailbox = i; /* this should be initted rather */ - enQ(&qels[i]); - idle(dev); - ret = mailbox[i]; - mboxinuse[i]=0; - return ret; - } - printk("ltpc: could not allocate mbox\n"); - return -1; -} - -static int do_read(struct net_device *dev, void *cbuf, int cbuflen, - void *dbuf, int dbuflen) -{ - - int i = getmbox(); - int ret; - - if(i) { - qels[i].cbuf = (unsigned char *) cbuf; - qels[i].cbuflen = cbuflen; - qels[i].dbuf = (unsigned char *) dbuf; - qels[i].dbuflen = dbuflen; - qels[i].QWrite = 0; - qels[i].mailbox = i; /* this should be initted rather */ - enQ(&qels[i]); - idle(dev); - ret = mailbox[i]; - mboxinuse[i]=0; - return ret; - } - printk("ltpc: could not allocate mbox\n"); - return -1; -} - -/* end of idle handlers -- what should be seen is do_read, do_write */ - -static struct timer_list ltpc_timer; - -static netdev_tx_t ltpc_xmit(struct sk_buff *skb, struct net_device *dev); - -static int read_30 ( struct net_device *dev) -{ - lt_command c; - c.getflags.command = LT_GETFLAGS; - return do_read(dev, &c, sizeof(c.getflags),&c,0); -} - -static int set_30 (struct net_device *dev,int x) -{ - lt_command c; - c.setflags.command = LT_SETFLAGS; - c.setflags.flags = x; - return do_write(dev, &c, sizeof(c.setflags),&c,0); -} - -/* LLAP to DDP translation */ - -static int sendup_buffer (struct net_device *dev) -{ - /* on entry, command is in ltdmacbuf, data in ltdmabuf */ - /* called from idle, non-reentrant */ - - int dnode, snode, llaptype, len; - int sklen; - struct sk_buff *skb; - struct lt_rcvlap *ltc = (struct lt_rcvlap *) ltdmacbuf; - - if (ltc->command != LT_RCVLAP) { - printk("unknown command 0x%02x from ltpc card\n",ltc->command); - return -1; - } - dnode = ltc->dnode; - snode = ltc->snode; - llaptype = ltc->laptype; - len = ltc->length; - - sklen = len; - if (llaptype == 1) - sklen += 8; /* correct for short ddp */ - if(sklen > 800) { - printk(KERN_INFO "%s: nonsense length in ltpc command 0x14: 0x%08x\n", - dev->name,sklen); - return -1; - } - - if ( (llaptype==0) || (llaptype>2) ) { - printk(KERN_INFO "%s: unknown LLAP type: %d\n",dev->name,llaptype); - return -1; - } - - - skb = dev_alloc_skb(3+sklen); - if (skb == NULL) - { - printk("%s: dropping packet due to memory squeeze.\n", - dev->name); - return -1; - } - skb->dev = dev; - - if (sklen > len) - skb_reserve(skb,8); - skb_put(skb,len+3); - skb->protocol = htons(ETH_P_LOCALTALK); - /* add LLAP header */ - skb->data[0] = dnode; - skb->data[1] = snode; - skb->data[2] = llaptype; - skb_reset_mac_header(skb); /* save pointer to llap header */ - skb_pull(skb,3); - - /* copy ddp(s,e)hdr + contents */ - skb_copy_to_linear_data(skb, ltdmabuf, len); - - skb_reset_transport_header(skb); - - dev->stats.rx_packets++; - dev->stats.rx_bytes += skb->len; - - /* toss it onwards */ - netif_rx(skb); - return 0; -} - -/* the handler for the board interrupt */ - -static irqreturn_t -ltpc_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - - if (dev==NULL) { - printk("ltpc_interrupt: unknown device.\n"); - return IRQ_NONE; - } - - inb_p(dev->base_addr+6); /* disable further interrupts from board */ - - idle(dev); /* handle whatever is coming in */ - - /* idle re-enables interrupts from board */ - - return IRQ_HANDLED; -} - -/*** - * - * The ioctls that the driver responds to are: - * - * SIOCSIFADDR -- do probe using the passed node hint. - * SIOCGIFADDR -- return net, node. - * - * some of this stuff should be done elsewhere. - * - ***/ - -static int ltpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - struct sockaddr_at *sa = (struct sockaddr_at *) &ifr->ifr_addr; - /* we'll keep the localtalk node address in dev->pa_addr */ - struct ltpc_private *ltpc_priv = netdev_priv(dev); - struct atalk_addr *aa = <pc_priv->my_addr; - struct lt_init c; - int ltflags; - - if(debug & DEBUG_VERBOSE) printk("ltpc_ioctl called\n"); - - switch(cmd) { - case SIOCSIFADDR: - - aa->s_net = sa->sat_addr.s_net; - - /* this does the probe and returns the node addr */ - c.command = LT_INIT; - c.hint = sa->sat_addr.s_node; - - aa->s_node = do_read(dev,&c,sizeof(c),&c,0); - - /* get all llap frames raw */ - ltflags = read_30(dev); - ltflags |= LT_FLAG_ALLLAP; - set_30 (dev,ltflags); - - dev->broadcast[0] = 0xFF; - dev->dev_addr[0] = aa->s_node; - - dev->addr_len=1; - - return 0; - - case SIOCGIFADDR: - - sa->sat_addr.s_net = aa->s_net; - sa->sat_addr.s_node = aa->s_node; - - return 0; - - default: - return -EINVAL; - } -} - -static void set_multicast_list(struct net_device *dev) -{ - /* This needs to be present to keep netatalk happy. */ - /* Actually netatalk needs fixing! */ -} - -static int ltpc_poll_counter; - -static void ltpc_poll(unsigned long l) -{ - struct net_device *dev = (struct net_device *) l; - - del_timer(<pc_timer); - - if(debug & DEBUG_VERBOSE) { - if (!ltpc_poll_counter) { - ltpc_poll_counter = 50; - printk("ltpc poll is alive\n"); - } - ltpc_poll_counter--; - } - - if (!dev) - return; /* we've been downed */ - - /* poll 20 times per second */ - idle(dev); - ltpc_timer.expires = jiffies + HZ/20; - - add_timer(<pc_timer); -} - -/* DDP to LLAP translation */ - -static netdev_tx_t ltpc_xmit(struct sk_buff *skb, struct net_device *dev) -{ - /* in kernel 1.3.xx, on entry skb->data points to ddp header, - * and skb->len is the length of the ddp data + ddp header - */ - int i; - struct lt_sendlap cbuf; - unsigned char *hdr; - - cbuf.command = LT_SENDLAP; - cbuf.dnode = skb->data[0]; - cbuf.laptype = skb->data[2]; - skb_pull(skb,3); /* skip past LLAP header */ - cbuf.length = skb->len; /* this is host order */ - skb_reset_transport_header(skb); - - if(debug & DEBUG_UPPER) { - printk("command "); - for(i=0;i<6;i++) - printk("%02x ",((unsigned char *)&cbuf)[i]); - printk("\n"); - } - - hdr = skb_transport_header(skb); - do_write(dev, &cbuf, sizeof(cbuf), hdr, skb->len); - - if(debug & DEBUG_UPPER) { - printk("sent %d ddp bytes\n",skb->len); - for (i = 0; i < skb->len; i++) - printk("%02x ", hdr[i]); - printk("\n"); - } - - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - - dev_kfree_skb(skb); - return NETDEV_TX_OK; -} - -/* initialization stuff */ - -static int __init ltpc_probe_dma(int base, int dma) -{ - int want = (dma == 3) ? 2 : (dma == 1) ? 1 : 3; - unsigned long timeout; - unsigned long f; - - if (want & 1) { - if (request_dma(1,"ltpc")) { - want &= ~1; - } else { - f=claim_dma_lock(); - disable_dma(1); - clear_dma_ff(1); - set_dma_mode(1,DMA_MODE_WRITE); - set_dma_addr(1,virt_to_bus(ltdmabuf)); - set_dma_count(1,sizeof(struct lt_mem)); - enable_dma(1); - release_dma_lock(f); - } - } - if (want & 2) { - if (request_dma(3,"ltpc")) { - want &= ~2; - } else { - f=claim_dma_lock(); - disable_dma(3); - clear_dma_ff(3); - set_dma_mode(3,DMA_MODE_WRITE); - set_dma_addr(3,virt_to_bus(ltdmabuf)); - set_dma_count(3,sizeof(struct lt_mem)); - enable_dma(3); - release_dma_lock(f); - } - } - /* set up request */ - - /* FIXME -- do timings better! */ - - ltdmabuf[0] = LT_READMEM; - ltdmabuf[1] = 1; /* mailbox */ - ltdmabuf[2] = 0; ltdmabuf[3] = 0; /* address */ - ltdmabuf[4] = 0; ltdmabuf[5] = 1; /* read 0x0100 bytes */ - ltdmabuf[6] = 0; /* dunno if this is necessary */ - - inb_p(io+1); - inb_p(io+0); - timeout = jiffies+100*HZ/100; - while(time_before(jiffies, timeout)) { - if ( 0xfa == inb_p(io+6) ) break; - } - - inb_p(io+3); - inb_p(io+2); - while(time_before(jiffies, timeout)) { - if ( 0xfb == inb_p(io+6) ) break; - } - - /* release the other dma channel (if we opened both of them) */ - - if ((want & 2) && (get_dma_residue(3)==sizeof(struct lt_mem))) { - want &= ~2; - free_dma(3); - } - - if ((want & 1) && (get_dma_residue(1)==sizeof(struct lt_mem))) { - want &= ~1; - free_dma(1); - } - - if (!want) - return 0; - - return (want & 2) ? 3 : 1; -} - -static const struct net_device_ops ltpc_netdev = { - .ndo_start_xmit = ltpc_xmit, - .ndo_do_ioctl = ltpc_ioctl, - .ndo_set_multicast_list = set_multicast_list, -}; - -struct net_device * __init ltpc_probe(void) -{ - struct net_device *dev; - int err = -ENOMEM; - int x=0,y=0; - int autoirq; - unsigned long f; - unsigned long timeout; - - dev = alloc_ltalkdev(sizeof(struct ltpc_private)); - if (!dev) - goto out; - - /* probe for the I/O port address */ - - if (io != 0x240 && request_region(0x220,8,"ltpc")) { - x = inb_p(0x220+6); - if ( (x!=0xff) && (x>=0xf0) ) { - io = 0x220; - goto got_port; - } - release_region(0x220,8); - } - if (io != 0x220 && request_region(0x240,8,"ltpc")) { - y = inb_p(0x240+6); - if ( (y!=0xff) && (y>=0xf0) ){ - io = 0x240; - goto got_port; - } - release_region(0x240,8); - } - - /* give up in despair */ - printk(KERN_ERR "LocalTalk card not found; 220 = %02x, 240 = %02x.\n", x,y); - err = -ENODEV; - goto out1; - - got_port: - /* probe for the IRQ line */ - if (irq < 2) { - unsigned long irq_mask; - - irq_mask = probe_irq_on(); - /* reset the interrupt line */ - inb_p(io+7); - inb_p(io+7); - /* trigger an interrupt (I hope) */ - inb_p(io+6); - mdelay(2); - autoirq = probe_irq_off(irq_mask); - - if (autoirq == 0) { - printk(KERN_ERR "ltpc: probe at %#x failed to detect IRQ line.\n", io); - } else { - irq = autoirq; - } - } - - /* allocate a DMA buffer */ - ltdmabuf = (unsigned char *) dma_mem_alloc(1000); - if (!ltdmabuf) { - printk(KERN_ERR "ltpc: mem alloc failed\n"); - err = -ENOMEM; - goto out2; - } - - ltdmacbuf = <dmabuf[800]; - - if(debug & DEBUG_VERBOSE) { - printk("ltdmabuf pointer %08lx\n",(unsigned long) ltdmabuf); - } - - /* reset the card */ - - inb_p(io+1); - inb_p(io+3); - - msleep(20); - - inb_p(io+0); - inb_p(io+2); - inb_p(io+7); /* clear reset */ - inb_p(io+4); - inb_p(io+5); - inb_p(io+5); /* enable dma */ - inb_p(io+6); /* tri-state interrupt line */ - - ssleep(1); - - /* now, figure out which dma channel we're using, unless it's - already been specified */ - /* well, 0 is a legal DMA channel, but the LTPC card doesn't - use it... */ - dma = ltpc_probe_dma(io, dma); - if (!dma) { /* no dma channel */ - printk(KERN_ERR "No DMA channel found on ltpc card.\n"); - err = -ENODEV; - goto out3; - } - - /* print out friendly message */ - if(irq) - printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, IR%d, DMA%d.\n",io,irq,dma); - else - printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, DMA%d. Using polled mode.\n",io,dma); - - dev->netdev_ops = <pc_netdev; - dev->base_addr = io; - dev->irq = irq; - dev->dma = dma; - - /* the card will want to send a result at this point */ - /* (I think... leaving out this part makes the kernel crash, - so I put it back in...) */ - - f=claim_dma_lock(); - disable_dma(dma); - clear_dma_ff(dma); - set_dma_mode(dma,DMA_MODE_READ); - set_dma_addr(dma,virt_to_bus(ltdmabuf)); - set_dma_count(dma,0x100); - enable_dma(dma); - release_dma_lock(f); - - (void) inb_p(io+3); - (void) inb_p(io+2); - timeout = jiffies+100*HZ/100; - - while(time_before(jiffies, timeout)) { - if( 0xf9 == inb_p(io+6)) - break; - schedule(); - } - - if(debug & DEBUG_VERBOSE) { - printk("setting up timer and irq\n"); - } - - /* grab it and don't let go :-) */ - if (irq && request_irq( irq, ltpc_interrupt, 0, "ltpc", dev) >= 0) - { - (void) inb_p(io+7); /* enable interrupts from board */ - (void) inb_p(io+7); /* and reset irq line */ - } else { - if( irq ) - printk(KERN_ERR "ltpc: IRQ already in use, using polled mode.\n"); - dev->irq = 0; - /* polled mode -- 20 times per second */ - /* this is really, really slow... should it poll more often? */ - init_timer(<pc_timer); - ltpc_timer.function=ltpc_poll; - ltpc_timer.data = (unsigned long) dev; - - ltpc_timer.expires = jiffies + HZ/20; - add_timer(<pc_timer); - } - err = register_netdev(dev); - if (err) - goto out4; - - return NULL; -out4: - del_timer_sync(<pc_timer); - if (dev->irq) - free_irq(dev->irq, dev); -out3: - free_pages((unsigned long)ltdmabuf, get_order(1000)); -out2: - release_region(io, 8); -out1: - free_netdev(dev); -out: - return ERR_PTR(err); -} - -#ifndef MODULE -/* handles "ltpc=io,irq,dma" kernel command lines */ -static int __init ltpc_setup(char *str) -{ - int ints[5]; - - str = get_options(str, ARRAY_SIZE(ints), ints); - - if (ints[0] == 0) { - if (str && !strncmp(str, "auto", 4)) { - /* do nothing :-) */ - } - else { - /* usage message */ - printk (KERN_ERR - "ltpc: usage: ltpc=auto|iobase[,irq[,dma]]\n"); - return 0; - } - } else { - io = ints[1]; - if (ints[0] > 1) { - irq = ints[2]; - } - if (ints[0] > 2) { - dma = ints[3]; - } - /* ignore any other parameters */ - } - return 1; -} - -__setup("ltpc=", ltpc_setup); -#endif /* MODULE */ - -static struct net_device *dev_ltpc; - -#ifdef MODULE - -MODULE_LICENSE("GPL"); -module_param(debug, int, 0); -module_param(io, int, 0); -module_param(irq, int, 0); -module_param(dma, int, 0); - - -static int __init ltpc_module_init(void) -{ - if(io == 0) - printk(KERN_NOTICE - "ltpc: Autoprobing is not recommended for modules\n"); - - dev_ltpc = ltpc_probe(); - if (IS_ERR(dev_ltpc)) - return PTR_ERR(dev_ltpc); - return 0; -} -module_init(ltpc_module_init); -#endif - -static void __exit ltpc_cleanup(void) -{ - - if(debug & DEBUG_VERBOSE) printk("unregister_netdev\n"); - unregister_netdev(dev_ltpc); - - ltpc_timer.data = 0; /* signal the poll routine that we're done */ - - del_timer_sync(<pc_timer); - - if(debug & DEBUG_VERBOSE) printk("freeing irq\n"); - - if (dev_ltpc->irq) - free_irq(dev_ltpc->irq, dev_ltpc); - - if(debug & DEBUG_VERBOSE) printk("freeing dma\n"); - - if (dev_ltpc->dma) - free_dma(dev_ltpc->dma); - - if(debug & DEBUG_VERBOSE) printk("freeing ioaddr\n"); - - if (dev_ltpc->base_addr) - release_region(dev_ltpc->base_addr,8); - - free_netdev(dev_ltpc); - - if(debug & DEBUG_VERBOSE) printk("free_pages\n"); - - free_pages( (unsigned long) ltdmabuf, get_order(1000)); - - if(debug & DEBUG_VERBOSE) printk("returning from cleanup_module\n"); -} - -module_exit(ltpc_cleanup); diff --git a/drivers/staging/appletalk/ltpc.h b/drivers/staging/appletalk/ltpc.h deleted file mode 100644 index cd30544a3729..000000000000 --- a/drivers/staging/appletalk/ltpc.h +++ /dev/null @@ -1,73 +0,0 @@ -/*** ltpc.h - * - * - ***/ - -#define LT_GETRESULT 0x00 -#define LT_WRITEMEM 0x01 -#define LT_READMEM 0x02 -#define LT_GETFLAGS 0x04 -#define LT_SETFLAGS 0x05 -#define LT_INIT 0x10 -#define LT_SENDLAP 0x13 -#define LT_RCVLAP 0x14 - -/* the flag that we care about */ -#define LT_FLAG_ALLLAP 0x04 - -struct lt_getresult { - unsigned char command; - unsigned char mailbox; -}; - -struct lt_mem { - unsigned char command; - unsigned char mailbox; - unsigned short addr; /* host order */ - unsigned short length; /* host order */ -}; - -struct lt_setflags { - unsigned char command; - unsigned char mailbox; - unsigned char flags; -}; - -struct lt_getflags { - unsigned char command; - unsigned char mailbox; -}; - -struct lt_init { - unsigned char command; - unsigned char mailbox; - unsigned char hint; -}; - -struct lt_sendlap { - unsigned char command; - unsigned char mailbox; - unsigned char dnode; - unsigned char laptype; - unsigned short length; /* host order */ -}; - -struct lt_rcvlap { - unsigned char command; - unsigned char dnode; - unsigned char snode; - unsigned char laptype; - unsigned short length; /* host order */ -}; - -union lt_command { - struct lt_getresult getresult; - struct lt_mem mem; - struct lt_setflags setflags; - struct lt_getflags getflags; - struct lt_init init; - struct lt_sendlap sendlap; - struct lt_rcvlap rcvlap; -}; -typedef union lt_command lt_command; - diff --git a/drivers/staging/appletalk/sysctl_net_atalk.c b/drivers/staging/appletalk/sysctl_net_atalk.c deleted file mode 100644 index 4c896b625b2b..000000000000 --- a/drivers/staging/appletalk/sysctl_net_atalk.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * sysctl_net_atalk.c: sysctl interface to net AppleTalk subsystem. - * - * Begun April 1, 1996, Mike Shaver. - * Added /proc/sys/net/atalk directory entry (empty =) ). [MS] - * Dynamic registration, added aarp entries. (5/30/97 Chris Horn) - */ - -#include -#include -#include "atalk.h" - -static struct ctl_table atalk_table[] = { - { - .procname = "aarp-expiry-time", - .data = &sysctl_aarp_expiry_time, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec_jiffies, - }, - { - .procname = "aarp-tick-time", - .data = &sysctl_aarp_tick_time, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec_jiffies, - }, - { - .procname = "aarp-retransmit-limit", - .data = &sysctl_aarp_retransmit_limit, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec, - }, - { - .procname = "aarp-resolve-time", - .data = &sysctl_aarp_resolve_time, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec_jiffies, - }, - { }, -}; - -static struct ctl_path atalk_path[] = { - { .procname = "net", }, - { .procname = "appletalk", }, - { } -}; - -static struct ctl_table_header *atalk_table_header; - -void atalk_register_sysctl(void) -{ - atalk_table_header = register_sysctl_paths(atalk_path, atalk_table); -} - -void atalk_unregister_sysctl(void) -{ - unregister_sysctl_table(atalk_table_header); -} diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 86a2d7d905c0..61abb638b4bf 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 362041b73a2f..2296d8b1931f 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -43,6 +43,7 @@ header-y += agpgart.h header-y += aio_abi.h header-y += apm_bios.h header-y += arcfb.h +header-y += atalk.h header-y += atm.h header-y += atm_eni.h header-y += atm_he.h diff --git a/include/linux/atalk.h b/include/linux/atalk.h new file mode 100644 index 000000000000..d34c187432ed --- /dev/null +++ b/include/linux/atalk.h @@ -0,0 +1,208 @@ +#ifndef __LINUX_ATALK_H__ +#define __LINUX_ATALK_H__ + +#include +#include + +/* + * AppleTalk networking structures + * + * The following are directly referenced from the University Of Michigan + * netatalk for compatibility reasons. + */ +#define ATPORT_FIRST 1 +#define ATPORT_RESERVED 128 +#define ATPORT_LAST 254 /* 254 is only legal on localtalk */ +#define ATADDR_ANYNET (__u16)0 +#define ATADDR_ANYNODE (__u8)0 +#define ATADDR_ANYPORT (__u8)0 +#define ATADDR_BCAST (__u8)255 +#define DDP_MAXSZ 587 +#define DDP_MAXHOPS 15 /* 4 bits of hop counter */ + +#define SIOCATALKDIFADDR (SIOCPROTOPRIVATE + 0) + +struct atalk_addr { + __be16 s_net; + __u8 s_node; +}; + +struct sockaddr_at { + sa_family_t sat_family; + __u8 sat_port; + struct atalk_addr sat_addr; + char sat_zero[8]; +}; + +struct atalk_netrange { + __u8 nr_phase; + __be16 nr_firstnet; + __be16 nr_lastnet; +}; + +#ifdef __KERNEL__ + +#include + +struct atalk_route { + struct net_device *dev; + struct atalk_addr target; + struct atalk_addr gateway; + int flags; + struct atalk_route *next; +}; + +/** + * struct atalk_iface - AppleTalk Interface + * @dev - Network device associated with this interface + * @address - Our address + * @status - What are we doing? + * @nets - Associated direct netrange + * @next - next element in the list of interfaces + */ +struct atalk_iface { + struct net_device *dev; + struct atalk_addr address; + int status; +#define ATIF_PROBE 1 /* Probing for an address */ +#define ATIF_PROBE_FAIL 2 /* Probe collided */ + struct atalk_netrange nets; + struct atalk_iface *next; +}; + +struct atalk_sock { + /* struct sock has to be the first member of atalk_sock */ + struct sock sk; + __be16 dest_net; + __be16 src_net; + unsigned char dest_node; + unsigned char src_node; + unsigned char dest_port; + unsigned char src_port; +}; + +static inline struct atalk_sock *at_sk(struct sock *sk) +{ + return (struct atalk_sock *)sk; +} + +struct ddpehdr { + __be16 deh_len_hops; /* lower 10 bits are length, next 4 - hops */ + __be16 deh_sum; + __be16 deh_dnet; + __be16 deh_snet; + __u8 deh_dnode; + __u8 deh_snode; + __u8 deh_dport; + __u8 deh_sport; + /* And netatalk apps expect to stick the type in themselves */ +}; + +static __inline__ struct ddpehdr *ddp_hdr(struct sk_buff *skb) +{ + return (struct ddpehdr *)skb_transport_header(skb); +} + +/* AppleTalk AARP headers */ +struct elapaarp { + __be16 hw_type; +#define AARP_HW_TYPE_ETHERNET 1 +#define AARP_HW_TYPE_TOKENRING 2 + __be16 pa_type; + __u8 hw_len; + __u8 pa_len; +#define AARP_PA_ALEN 4 + __be16 function; +#define AARP_REQUEST 1 +#define AARP_REPLY 2 +#define AARP_PROBE 3 + __u8 hw_src[ETH_ALEN]; + __u8 pa_src_zero; + __be16 pa_src_net; + __u8 pa_src_node; + __u8 hw_dst[ETH_ALEN]; + __u8 pa_dst_zero; + __be16 pa_dst_net; + __u8 pa_dst_node; +} __attribute__ ((packed)); + +static __inline__ struct elapaarp *aarp_hdr(struct sk_buff *skb) +{ + return (struct elapaarp *)skb_transport_header(skb); +} + +/* Not specified - how long till we drop a resolved entry */ +#define AARP_EXPIRY_TIME (5 * 60 * HZ) +/* Size of hash table */ +#define AARP_HASH_SIZE 16 +/* Fast retransmission timer when resolving */ +#define AARP_TICK_TIME (HZ / 5) +/* Send 10 requests then give up (2 seconds) */ +#define AARP_RETRANSMIT_LIMIT 10 +/* + * Some value bigger than total retransmit time + a bit for last reply to + * appear and to stop continual requests + */ +#define AARP_RESOLVE_TIME (10 * HZ) + +extern struct datalink_proto *ddp_dl, *aarp_dl; +extern void aarp_proto_init(void); + +/* Inter module exports */ + +/* Give a device find its atif control structure */ +static inline struct atalk_iface *atalk_find_dev(struct net_device *dev) +{ + return dev->atalk_ptr; +} + +extern struct atalk_addr *atalk_find_dev_addr(struct net_device *dev); +extern struct net_device *atrtr_get_dev(struct atalk_addr *sa); +extern int aarp_send_ddp(struct net_device *dev, + struct sk_buff *skb, + struct atalk_addr *sa, void *hwaddr); +extern void aarp_device_down(struct net_device *dev); +extern void aarp_probe_network(struct atalk_iface *atif); +extern int aarp_proxy_probe_network(struct atalk_iface *atif, + struct atalk_addr *sa); +extern void aarp_proxy_remove(struct net_device *dev, + struct atalk_addr *sa); + +extern void aarp_cleanup_module(void); + +extern struct hlist_head atalk_sockets; +extern rwlock_t atalk_sockets_lock; + +extern struct atalk_route *atalk_routes; +extern rwlock_t atalk_routes_lock; + +extern struct atalk_iface *atalk_interfaces; +extern rwlock_t atalk_interfaces_lock; + +extern struct atalk_route atrtr_default; + +extern const struct file_operations atalk_seq_arp_fops; + +extern int sysctl_aarp_expiry_time; +extern int sysctl_aarp_tick_time; +extern int sysctl_aarp_retransmit_limit; +extern int sysctl_aarp_resolve_time; + +#ifdef CONFIG_SYSCTL +extern void atalk_register_sysctl(void); +extern void atalk_unregister_sysctl(void); +#else +#define atalk_register_sysctl() do { } while(0) +#define atalk_unregister_sysctl() do { } while(0) +#endif + +#ifdef CONFIG_PROC_FS +extern int atalk_proc_init(void); +extern void atalk_proc_exit(void); +#else +#define atalk_proc_init() ({ 0; }) +#define atalk_proc_exit() do { } while(0) +#endif /* CONFIG_PROC_FS */ + +#endif /* __KERNEL__ */ +#endif /* __LINUX_ATALK_H__ */ diff --git a/net/Kconfig b/net/Kconfig index 082c8bc977e1..72840626284b 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -204,6 +204,7 @@ source "net/8021q/Kconfig" source "net/decnet/Kconfig" source "net/llc/Kconfig" source "net/ipx/Kconfig" +source "drivers/net/appletalk/Kconfig" source "net/x25/Kconfig" source "net/lapb/Kconfig" source "net/econet/Kconfig" diff --git a/net/Makefile b/net/Makefile index 16d9947b4b95..a3330ebe2c53 100644 --- a/net/Makefile +++ b/net/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_NET_KEY) += key/ obj-$(CONFIG_BRIDGE) += bridge/ obj-$(CONFIG_NET_DSA) += dsa/ obj-$(CONFIG_IPX) += ipx/ +obj-$(CONFIG_ATALK) += appletalk/ obj-$(CONFIG_WAN_ROUTER) += wanrouter/ obj-$(CONFIG_X25) += x25/ obj-$(CONFIG_LAPB) += lapb/ diff --git a/net/appletalk/Makefile b/net/appletalk/Makefile new file mode 100644 index 000000000000..5cda56edef57 --- /dev/null +++ b/net/appletalk/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for the Linux AppleTalk layer. +# + +obj-$(CONFIG_ATALK) += appletalk.o + +appletalk-y := aarp.o ddp.o dev.o +appletalk-$(CONFIG_PROC_FS) += atalk_proc.o +appletalk-$(CONFIG_SYSCTL) += sysctl_net_atalk.o diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c new file mode 100644 index 000000000000..50dce7981321 --- /dev/null +++ b/net/appletalk/aarp.c @@ -0,0 +1,1063 @@ +/* + * AARP: An implementation of the AppleTalk AARP protocol for + * Ethernet 'ELAP'. + * + * Alan Cox + * + * This doesn't fit cleanly with the IP arp. Potentially we can use + * the generic neighbour discovery code to clean this up. + * + * FIXME: + * We ought to handle the retransmits with a single list and a + * separate fast timer for when it is needed. + * Use neighbour discovery code. + * Token Ring Support. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * + * References: + * Inside AppleTalk (2nd Ed). + * Fixes: + * Jaume Grau - flush caches on AARP_PROBE + * Rob Newberry - Added proxy AARP and AARP proc fs, + * moved probing from DDP module. + * Arnaldo C. Melo - don't mangle rx packets + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME; +int sysctl_aarp_tick_time = AARP_TICK_TIME; +int sysctl_aarp_retransmit_limit = AARP_RETRANSMIT_LIMIT; +int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME; + +/* Lists of aarp entries */ +/** + * struct aarp_entry - AARP entry + * @last_sent - Last time we xmitted the aarp request + * @packet_queue - Queue of frames wait for resolution + * @status - Used for proxy AARP + * expires_at - Entry expiry time + * target_addr - DDP Address + * dev - Device to use + * hwaddr - Physical i/f address of target/router + * xmit_count - When this hits 10 we give up + * next - Next entry in chain + */ +struct aarp_entry { + /* These first two are only used for unresolved entries */ + unsigned long last_sent; + struct sk_buff_head packet_queue; + int status; + unsigned long expires_at; + struct atalk_addr target_addr; + struct net_device *dev; + char hwaddr[6]; + unsigned short xmit_count; + struct aarp_entry *next; +}; + +/* Hashed list of resolved, unresolved and proxy entries */ +static struct aarp_entry *resolved[AARP_HASH_SIZE]; +static struct aarp_entry *unresolved[AARP_HASH_SIZE]; +static struct aarp_entry *proxies[AARP_HASH_SIZE]; +static int unresolved_count; + +/* One lock protects it all. */ +static DEFINE_RWLOCK(aarp_lock); + +/* Used to walk the list and purge/kick entries. */ +static struct timer_list aarp_timer; + +/* + * Delete an aarp queue + * + * Must run under aarp_lock. + */ +static void __aarp_expire(struct aarp_entry *a) +{ + skb_queue_purge(&a->packet_queue); + kfree(a); +} + +/* + * Send an aarp queue entry request + * + * Must run under aarp_lock. + */ +static void __aarp_send_query(struct aarp_entry *a) +{ + static unsigned char aarp_eth_multicast[ETH_ALEN] = + { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; + struct net_device *dev = a->dev; + struct elapaarp *eah; + int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length; + struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); + struct atalk_addr *sat = atalk_find_dev_addr(dev); + + if (!skb) + return; + + if (!sat) { + kfree_skb(skb); + return; + } + + /* Set up the buffer */ + skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length); + skb_reset_network_header(skb); + skb_reset_transport_header(skb); + skb_put(skb, sizeof(*eah)); + skb->protocol = htons(ETH_P_ATALK); + skb->dev = dev; + eah = aarp_hdr(skb); + + /* Set up the ARP */ + eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); + eah->pa_type = htons(ETH_P_ATALK); + eah->hw_len = ETH_ALEN; + eah->pa_len = AARP_PA_ALEN; + eah->function = htons(AARP_REQUEST); + + memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN); + + eah->pa_src_zero = 0; + eah->pa_src_net = sat->s_net; + eah->pa_src_node = sat->s_node; + + memset(eah->hw_dst, '\0', ETH_ALEN); + + eah->pa_dst_zero = 0; + eah->pa_dst_net = a->target_addr.s_net; + eah->pa_dst_node = a->target_addr.s_node; + + /* Send it */ + aarp_dl->request(aarp_dl, skb, aarp_eth_multicast); + /* Update the sending count */ + a->xmit_count++; + a->last_sent = jiffies; +} + +/* This runs under aarp_lock and in softint context, so only atomic memory + * allocations can be used. */ +static void aarp_send_reply(struct net_device *dev, struct atalk_addr *us, + struct atalk_addr *them, unsigned char *sha) +{ + struct elapaarp *eah; + int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length; + struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); + + if (!skb) + return; + + /* Set up the buffer */ + skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length); + skb_reset_network_header(skb); + skb_reset_transport_header(skb); + skb_put(skb, sizeof(*eah)); + skb->protocol = htons(ETH_P_ATALK); + skb->dev = dev; + eah = aarp_hdr(skb); + + /* Set up the ARP */ + eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); + eah->pa_type = htons(ETH_P_ATALK); + eah->hw_len = ETH_ALEN; + eah->pa_len = AARP_PA_ALEN; + eah->function = htons(AARP_REPLY); + + memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN); + + eah->pa_src_zero = 0; + eah->pa_src_net = us->s_net; + eah->pa_src_node = us->s_node; + + if (!sha) + memset(eah->hw_dst, '\0', ETH_ALEN); + else + memcpy(eah->hw_dst, sha, ETH_ALEN); + + eah->pa_dst_zero = 0; + eah->pa_dst_net = them->s_net; + eah->pa_dst_node = them->s_node; + + /* Send it */ + aarp_dl->request(aarp_dl, skb, sha); +} + +/* + * Send probe frames. Called from aarp_probe_network and + * aarp_proxy_probe_network. + */ + +static void aarp_send_probe(struct net_device *dev, struct atalk_addr *us) +{ + struct elapaarp *eah; + int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length; + struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); + static unsigned char aarp_eth_multicast[ETH_ALEN] = + { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; + + if (!skb) + return; + + /* Set up the buffer */ + skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length); + skb_reset_network_header(skb); + skb_reset_transport_header(skb); + skb_put(skb, sizeof(*eah)); + skb->protocol = htons(ETH_P_ATALK); + skb->dev = dev; + eah = aarp_hdr(skb); + + /* Set up the ARP */ + eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); + eah->pa_type = htons(ETH_P_ATALK); + eah->hw_len = ETH_ALEN; + eah->pa_len = AARP_PA_ALEN; + eah->function = htons(AARP_PROBE); + + memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN); + + eah->pa_src_zero = 0; + eah->pa_src_net = us->s_net; + eah->pa_src_node = us->s_node; + + memset(eah->hw_dst, '\0', ETH_ALEN); + + eah->pa_dst_zero = 0; + eah->pa_dst_net = us->s_net; + eah->pa_dst_node = us->s_node; + + /* Send it */ + aarp_dl->request(aarp_dl, skb, aarp_eth_multicast); +} + +/* + * Handle an aarp timer expire + * + * Must run under the aarp_lock. + */ + +static void __aarp_expire_timer(struct aarp_entry **n) +{ + struct aarp_entry *t; + + while (*n) + /* Expired ? */ + if (time_after(jiffies, (*n)->expires_at)) { + t = *n; + *n = (*n)->next; + __aarp_expire(t); + } else + n = &((*n)->next); +} + +/* + * Kick all pending requests 5 times a second. + * + * Must run under the aarp_lock. + */ +static void __aarp_kick(struct aarp_entry **n) +{ + struct aarp_entry *t; + + while (*n) + /* Expired: if this will be the 11th tx, we delete instead. */ + if ((*n)->xmit_count >= sysctl_aarp_retransmit_limit) { + t = *n; + *n = (*n)->next; + __aarp_expire(t); + } else { + __aarp_send_query(*n); + n = &((*n)->next); + } +} + +/* + * A device has gone down. Take all entries referring to the device + * and remove them. + * + * Must run under the aarp_lock. + */ +static void __aarp_expire_device(struct aarp_entry **n, struct net_device *dev) +{ + struct aarp_entry *t; + + while (*n) + if ((*n)->dev == dev) { + t = *n; + *n = (*n)->next; + __aarp_expire(t); + } else + n = &((*n)->next); +} + +/* Handle the timer event */ +static void aarp_expire_timeout(unsigned long unused) +{ + int ct; + + write_lock_bh(&aarp_lock); + + for (ct = 0; ct < AARP_HASH_SIZE; ct++) { + __aarp_expire_timer(&resolved[ct]); + __aarp_kick(&unresolved[ct]); + __aarp_expire_timer(&unresolved[ct]); + __aarp_expire_timer(&proxies[ct]); + } + + write_unlock_bh(&aarp_lock); + mod_timer(&aarp_timer, jiffies + + (unresolved_count ? sysctl_aarp_tick_time : + sysctl_aarp_expiry_time)); +} + +/* Network device notifier chain handler. */ +static int aarp_device_event(struct notifier_block *this, unsigned long event, + void *ptr) +{ + struct net_device *dev = ptr; + int ct; + + if (!net_eq(dev_net(dev), &init_net)) + return NOTIFY_DONE; + + if (event == NETDEV_DOWN) { + write_lock_bh(&aarp_lock); + + for (ct = 0; ct < AARP_HASH_SIZE; ct++) { + __aarp_expire_device(&resolved[ct], dev); + __aarp_expire_device(&unresolved[ct], dev); + __aarp_expire_device(&proxies[ct], dev); + } + + write_unlock_bh(&aarp_lock); + } + return NOTIFY_DONE; +} + +/* Expire all entries in a hash chain */ +static void __aarp_expire_all(struct aarp_entry **n) +{ + struct aarp_entry *t; + + while (*n) { + t = *n; + *n = (*n)->next; + __aarp_expire(t); + } +} + +/* Cleanup all hash chains -- module unloading */ +static void aarp_purge(void) +{ + int ct; + + write_lock_bh(&aarp_lock); + for (ct = 0; ct < AARP_HASH_SIZE; ct++) { + __aarp_expire_all(&resolved[ct]); + __aarp_expire_all(&unresolved[ct]); + __aarp_expire_all(&proxies[ct]); + } + write_unlock_bh(&aarp_lock); +} + +/* + * Create a new aarp entry. This must use GFP_ATOMIC because it + * runs while holding spinlocks. + */ +static struct aarp_entry *aarp_alloc(void) +{ + struct aarp_entry *a = kmalloc(sizeof(*a), GFP_ATOMIC); + + if (a) + skb_queue_head_init(&a->packet_queue); + return a; +} + +/* + * Find an entry. We might return an expired but not yet purged entry. We + * don't care as it will do no harm. + * + * This must run under the aarp_lock. + */ +static struct aarp_entry *__aarp_find_entry(struct aarp_entry *list, + struct net_device *dev, + struct atalk_addr *sat) +{ + while (list) { + if (list->target_addr.s_net == sat->s_net && + list->target_addr.s_node == sat->s_node && + list->dev == dev) + break; + list = list->next; + } + + return list; +} + +/* Called from the DDP code, and thus must be exported. */ +void aarp_proxy_remove(struct net_device *dev, struct atalk_addr *sa) +{ + int hash = sa->s_node % (AARP_HASH_SIZE - 1); + struct aarp_entry *a; + + write_lock_bh(&aarp_lock); + + a = __aarp_find_entry(proxies[hash], dev, sa); + if (a) + a->expires_at = jiffies - 1; + + write_unlock_bh(&aarp_lock); +} + +/* This must run under aarp_lock. */ +static struct atalk_addr *__aarp_proxy_find(struct net_device *dev, + struct atalk_addr *sa) +{ + int hash = sa->s_node % (AARP_HASH_SIZE - 1); + struct aarp_entry *a = __aarp_find_entry(proxies[hash], dev, sa); + + return a ? sa : NULL; +} + +/* + * Probe a Phase 1 device or a device that requires its Net:Node to + * be set via an ioctl. + */ +static void aarp_send_probe_phase1(struct atalk_iface *iface) +{ + struct ifreq atreq; + struct sockaddr_at *sa = (struct sockaddr_at *)&atreq.ifr_addr; + const struct net_device_ops *ops = iface->dev->netdev_ops; + + sa->sat_addr.s_node = iface->address.s_node; + sa->sat_addr.s_net = ntohs(iface->address.s_net); + + /* We pass the Net:Node to the drivers/cards by a Device ioctl. */ + if (!(ops->ndo_do_ioctl(iface->dev, &atreq, SIOCSIFADDR))) { + ops->ndo_do_ioctl(iface->dev, &atreq, SIOCGIFADDR); + if (iface->address.s_net != htons(sa->sat_addr.s_net) || + iface->address.s_node != sa->sat_addr.s_node) + iface->status |= ATIF_PROBE_FAIL; + + iface->address.s_net = htons(sa->sat_addr.s_net); + iface->address.s_node = sa->sat_addr.s_node; + } +} + + +void aarp_probe_network(struct atalk_iface *atif) +{ + if (atif->dev->type == ARPHRD_LOCALTLK || + atif->dev->type == ARPHRD_PPP) + aarp_send_probe_phase1(atif); + else { + unsigned int count; + + for (count = 0; count < AARP_RETRANSMIT_LIMIT; count++) { + aarp_send_probe(atif->dev, &atif->address); + + /* Defer 1/10th */ + msleep(100); + + if (atif->status & ATIF_PROBE_FAIL) + break; + } + } +} + +int aarp_proxy_probe_network(struct atalk_iface *atif, struct atalk_addr *sa) +{ + int hash, retval = -EPROTONOSUPPORT; + struct aarp_entry *entry; + unsigned int count; + + /* + * we don't currently support LocalTalk or PPP for proxy AARP; + * if someone wants to try and add it, have fun + */ + if (atif->dev->type == ARPHRD_LOCALTLK || + atif->dev->type == ARPHRD_PPP) + goto out; + + /* + * create a new AARP entry with the flags set to be published -- + * we need this one to hang around even if it's in use + */ + entry = aarp_alloc(); + retval = -ENOMEM; + if (!entry) + goto out; + + entry->expires_at = -1; + entry->status = ATIF_PROBE; + entry->target_addr.s_node = sa->s_node; + entry->target_addr.s_net = sa->s_net; + entry->dev = atif->dev; + + write_lock_bh(&aarp_lock); + + hash = sa->s_node % (AARP_HASH_SIZE - 1); + entry->next = proxies[hash]; + proxies[hash] = entry; + + for (count = 0; count < AARP_RETRANSMIT_LIMIT; count++) { + aarp_send_probe(atif->dev, sa); + + /* Defer 1/10th */ + write_unlock_bh(&aarp_lock); + msleep(100); + write_lock_bh(&aarp_lock); + + if (entry->status & ATIF_PROBE_FAIL) + break; + } + + if (entry->status & ATIF_PROBE_FAIL) { + entry->expires_at = jiffies - 1; /* free the entry */ + retval = -EADDRINUSE; /* return network full */ + } else { /* clear the probing flag */ + entry->status &= ~ATIF_PROBE; + retval = 1; + } + + write_unlock_bh(&aarp_lock); +out: + return retval; +} + +/* Send a DDP frame */ +int aarp_send_ddp(struct net_device *dev, struct sk_buff *skb, + struct atalk_addr *sa, void *hwaddr) +{ + static char ddp_eth_multicast[ETH_ALEN] = + { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; + int hash; + struct aarp_entry *a; + + skb_reset_network_header(skb); + + /* Check for LocalTalk first */ + if (dev->type == ARPHRD_LOCALTLK) { + struct atalk_addr *at = atalk_find_dev_addr(dev); + struct ddpehdr *ddp = (struct ddpehdr *)skb->data; + int ft = 2; + + /* + * Compressible ? + * + * IFF: src_net == dest_net == device_net + * (zero matches anything) + */ + + if ((!ddp->deh_snet || at->s_net == ddp->deh_snet) && + (!ddp->deh_dnet || at->s_net == ddp->deh_dnet)) { + skb_pull(skb, sizeof(*ddp) - 4); + + /* + * The upper two remaining bytes are the port + * numbers we just happen to need. Now put the + * length in the lower two. + */ + *((__be16 *)skb->data) = htons(skb->len); + ft = 1; + } + /* + * Nice and easy. No AARP type protocols occur here so we can + * just shovel it out with a 3 byte LLAP header + */ + + skb_push(skb, 3); + skb->data[0] = sa->s_node; + skb->data[1] = at->s_node; + skb->data[2] = ft; + skb->dev = dev; + goto sendit; + } + + /* On a PPP link we neither compress nor aarp. */ + if (dev->type == ARPHRD_PPP) { + skb->protocol = htons(ETH_P_PPPTALK); + skb->dev = dev; + goto sendit; + } + + /* Non ELAP we cannot do. */ + if (dev->type != ARPHRD_ETHER) + goto free_it; + + skb->dev = dev; + skb->protocol = htons(ETH_P_ATALK); + hash = sa->s_node % (AARP_HASH_SIZE - 1); + + /* Do we have a resolved entry? */ + if (sa->s_node == ATADDR_BCAST) { + /* Send it */ + ddp_dl->request(ddp_dl, skb, ddp_eth_multicast); + goto sent; + } + + write_lock_bh(&aarp_lock); + a = __aarp_find_entry(resolved[hash], dev, sa); + + if (a) { /* Return 1 and fill in the address */ + a->expires_at = jiffies + (sysctl_aarp_expiry_time * 10); + ddp_dl->request(ddp_dl, skb, a->hwaddr); + write_unlock_bh(&aarp_lock); + goto sent; + } + + /* Do we have an unresolved entry: This is the less common path */ + a = __aarp_find_entry(unresolved[hash], dev, sa); + if (a) { /* Queue onto the unresolved queue */ + skb_queue_tail(&a->packet_queue, skb); + goto out_unlock; + } + + /* Allocate a new entry */ + a = aarp_alloc(); + if (!a) { + /* Whoops slipped... good job it's an unreliable protocol 8) */ + write_unlock_bh(&aarp_lock); + goto free_it; + } + + /* Set up the queue */ + skb_queue_tail(&a->packet_queue, skb); + a->expires_at = jiffies + sysctl_aarp_resolve_time; + a->dev = dev; + a->next = unresolved[hash]; + a->target_addr = *sa; + a->xmit_count = 0; + unresolved[hash] = a; + unresolved_count++; + + /* Send an initial request for the address */ + __aarp_send_query(a); + + /* + * Switch to fast timer if needed (That is if this is the first + * unresolved entry to get added) + */ + + if (unresolved_count == 1) + mod_timer(&aarp_timer, jiffies + sysctl_aarp_tick_time); + + /* Now finally, it is safe to drop the lock. */ +out_unlock: + write_unlock_bh(&aarp_lock); + + /* Tell the ddp layer we have taken over for this frame. */ + goto sent; + +sendit: + if (skb->sk) + skb->priority = skb->sk->sk_priority; + if (dev_queue_xmit(skb)) + goto drop; +sent: + return NET_XMIT_SUCCESS; +free_it: + kfree_skb(skb); +drop: + return NET_XMIT_DROP; +} +EXPORT_SYMBOL(aarp_send_ddp); + +/* + * An entry in the aarp unresolved queue has become resolved. Send + * all the frames queued under it. + * + * Must run under aarp_lock. + */ +static void __aarp_resolved(struct aarp_entry **list, struct aarp_entry *a, + int hash) +{ + struct sk_buff *skb; + + while (*list) + if (*list == a) { + unresolved_count--; + *list = a->next; + + /* Move into the resolved list */ + a->next = resolved[hash]; + resolved[hash] = a; + + /* Kick frames off */ + while ((skb = skb_dequeue(&a->packet_queue)) != NULL) { + a->expires_at = jiffies + + sysctl_aarp_expiry_time * 10; + ddp_dl->request(ddp_dl, skb, a->hwaddr); + } + } else + list = &((*list)->next); +} + +/* + * This is called by the SNAP driver whenever we see an AARP SNAP + * frame. We currently only support Ethernet. + */ +static int aarp_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt, struct net_device *orig_dev) +{ + struct elapaarp *ea = aarp_hdr(skb); + int hash, ret = 0; + __u16 function; + struct aarp_entry *a; + struct atalk_addr sa, *ma, da; + struct atalk_iface *ifa; + + if (!net_eq(dev_net(dev), &init_net)) + goto out0; + + /* We only do Ethernet SNAP AARP. */ + if (dev->type != ARPHRD_ETHER) + goto out0; + + /* Frame size ok? */ + if (!skb_pull(skb, sizeof(*ea))) + goto out0; + + function = ntohs(ea->function); + + /* Sanity check fields. */ + if (function < AARP_REQUEST || function > AARP_PROBE || + ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN || + ea->pa_src_zero || ea->pa_dst_zero) + goto out0; + + /* Looks good. */ + hash = ea->pa_src_node % (AARP_HASH_SIZE - 1); + + /* Build an address. */ + sa.s_node = ea->pa_src_node; + sa.s_net = ea->pa_src_net; + + /* Process the packet. Check for replies of me. */ + ifa = atalk_find_dev(dev); + if (!ifa) + goto out1; + + if (ifa->status & ATIF_PROBE && + ifa->address.s_node == ea->pa_dst_node && + ifa->address.s_net == ea->pa_dst_net) { + ifa->status |= ATIF_PROBE_FAIL; /* Fail the probe (in use) */ + goto out1; + } + + /* Check for replies of proxy AARP entries */ + da.s_node = ea->pa_dst_node; + da.s_net = ea->pa_dst_net; + + write_lock_bh(&aarp_lock); + a = __aarp_find_entry(proxies[hash], dev, &da); + + if (a && a->status & ATIF_PROBE) { + a->status |= ATIF_PROBE_FAIL; + /* + * we do not respond to probe or request packets for + * this address while we are probing this address + */ + goto unlock; + } + + switch (function) { + case AARP_REPLY: + if (!unresolved_count) /* Speed up */ + break; + + /* Find the entry. */ + a = __aarp_find_entry(unresolved[hash], dev, &sa); + if (!a || dev != a->dev) + break; + + /* We can fill one in - this is good. */ + memcpy(a->hwaddr, ea->hw_src, ETH_ALEN); + __aarp_resolved(&unresolved[hash], a, hash); + if (!unresolved_count) + mod_timer(&aarp_timer, + jiffies + sysctl_aarp_expiry_time); + break; + + case AARP_REQUEST: + case AARP_PROBE: + + /* + * If it is my address set ma to my address and reply. + * We can treat probe and request the same. Probe + * simply means we shouldn't cache the querying host, + * as in a probe they are proposing an address not + * using one. + * + * Support for proxy-AARP added. We check if the + * address is one of our proxies before we toss the + * packet out. + */ + + sa.s_node = ea->pa_dst_node; + sa.s_net = ea->pa_dst_net; + + /* See if we have a matching proxy. */ + ma = __aarp_proxy_find(dev, &sa); + if (!ma) + ma = &ifa->address; + else { /* We need to make a copy of the entry. */ + da.s_node = sa.s_node; + da.s_net = sa.s_net; + ma = &da; + } + + if (function == AARP_PROBE) { + /* + * A probe implies someone trying to get an + * address. So as a precaution flush any + * entries we have for this address. + */ + a = __aarp_find_entry(resolved[sa.s_node % + (AARP_HASH_SIZE - 1)], + skb->dev, &sa); + + /* + * Make it expire next tick - that avoids us + * getting into a probe/flush/learn/probe/ + * flush/learn cycle during probing of a slow + * to respond host addr. + */ + if (a) { + a->expires_at = jiffies - 1; + mod_timer(&aarp_timer, jiffies + + sysctl_aarp_tick_time); + } + } + + if (sa.s_node != ma->s_node) + break; + + if (sa.s_net && ma->s_net && sa.s_net != ma->s_net) + break; + + sa.s_node = ea->pa_src_node; + sa.s_net = ea->pa_src_net; + + /* aarp_my_address has found the address to use for us. + */ + aarp_send_reply(dev, ma, &sa, ea->hw_src); + break; + } + +unlock: + write_unlock_bh(&aarp_lock); +out1: + ret = 1; +out0: + kfree_skb(skb); + return ret; +} + +static struct notifier_block aarp_notifier = { + .notifier_call = aarp_device_event, +}; + +static unsigned char aarp_snap_id[] = { 0x00, 0x00, 0x00, 0x80, 0xF3 }; + +void __init aarp_proto_init(void) +{ + aarp_dl = register_snap_client(aarp_snap_id, aarp_rcv); + if (!aarp_dl) + printk(KERN_CRIT "Unable to register AARP with SNAP.\n"); + setup_timer(&aarp_timer, aarp_expire_timeout, 0); + aarp_timer.expires = jiffies + sysctl_aarp_expiry_time; + add_timer(&aarp_timer); + register_netdevice_notifier(&aarp_notifier); +} + +/* Remove the AARP entries associated with a device. */ +void aarp_device_down(struct net_device *dev) +{ + int ct; + + write_lock_bh(&aarp_lock); + + for (ct = 0; ct < AARP_HASH_SIZE; ct++) { + __aarp_expire_device(&resolved[ct], dev); + __aarp_expire_device(&unresolved[ct], dev); + __aarp_expire_device(&proxies[ct], dev); + } + + write_unlock_bh(&aarp_lock); +} + +#ifdef CONFIG_PROC_FS +struct aarp_iter_state { + int bucket; + struct aarp_entry **table; +}; + +/* + * Get the aarp entry that is in the chain described + * by the iterator. + * If pos is set then skip till that index. + * pos = 1 is the first entry + */ +static struct aarp_entry *iter_next(struct aarp_iter_state *iter, loff_t *pos) +{ + int ct = iter->bucket; + struct aarp_entry **table = iter->table; + loff_t off = 0; + struct aarp_entry *entry; + + rescan: + while(ct < AARP_HASH_SIZE) { + for (entry = table[ct]; entry; entry = entry->next) { + if (!pos || ++off == *pos) { + iter->table = table; + iter->bucket = ct; + return entry; + } + } + ++ct; + } + + if (table == resolved) { + ct = 0; + table = unresolved; + goto rescan; + } + if (table == unresolved) { + ct = 0; + table = proxies; + goto rescan; + } + return NULL; +} + +static void *aarp_seq_start(struct seq_file *seq, loff_t *pos) + __acquires(aarp_lock) +{ + struct aarp_iter_state *iter = seq->private; + + read_lock_bh(&aarp_lock); + iter->table = resolved; + iter->bucket = 0; + + return *pos ? iter_next(iter, pos) : SEQ_START_TOKEN; +} + +static void *aarp_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct aarp_entry *entry = v; + struct aarp_iter_state *iter = seq->private; + + ++*pos; + + /* first line after header */ + if (v == SEQ_START_TOKEN) + entry = iter_next(iter, NULL); + + /* next entry in current bucket */ + else if (entry->next) + entry = entry->next; + + /* next bucket or table */ + else { + ++iter->bucket; + entry = iter_next(iter, NULL); + } + return entry; +} + +static void aarp_seq_stop(struct seq_file *seq, void *v) + __releases(aarp_lock) +{ + read_unlock_bh(&aarp_lock); +} + +static const char *dt2str(unsigned long ticks) +{ + static char buf[32]; + + sprintf(buf, "%ld.%02ld", ticks / HZ, ((ticks % HZ) * 100 ) / HZ); + + return buf; +} + +static int aarp_seq_show(struct seq_file *seq, void *v) +{ + struct aarp_iter_state *iter = seq->private; + struct aarp_entry *entry = v; + unsigned long now = jiffies; + + if (v == SEQ_START_TOKEN) + seq_puts(seq, + "Address Interface Hardware Address" + " Expires LastSend Retry Status\n"); + else { + seq_printf(seq, "%04X:%02X %-12s", + ntohs(entry->target_addr.s_net), + (unsigned int) entry->target_addr.s_node, + entry->dev ? entry->dev->name : "????"); + seq_printf(seq, "%pM", entry->hwaddr); + seq_printf(seq, " %8s", + dt2str((long)entry->expires_at - (long)now)); + if (iter->table == unresolved) + seq_printf(seq, " %8s %6hu", + dt2str(now - entry->last_sent), + entry->xmit_count); + else + seq_puts(seq, " "); + seq_printf(seq, " %s\n", + (iter->table == resolved) ? "resolved" + : (iter->table == unresolved) ? "unresolved" + : (iter->table == proxies) ? "proxies" + : "unknown"); + } + return 0; +} + +static const struct seq_operations aarp_seq_ops = { + .start = aarp_seq_start, + .next = aarp_seq_next, + .stop = aarp_seq_stop, + .show = aarp_seq_show, +}; + +static int aarp_seq_open(struct inode *inode, struct file *file) +{ + return seq_open_private(file, &aarp_seq_ops, + sizeof(struct aarp_iter_state)); +} + +const struct file_operations atalk_seq_arp_fops = { + .owner = THIS_MODULE, + .open = aarp_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_private, +}; +#endif + +/* General module cleanup. Called from cleanup_module() in ddp.c. */ +void aarp_cleanup_module(void) +{ + del_timer_sync(&aarp_timer); + unregister_netdevice_notifier(&aarp_notifier); + unregister_snap_client(aarp_dl); + aarp_purge(); +} diff --git a/net/appletalk/atalk_proc.c b/net/appletalk/atalk_proc.c new file mode 100644 index 000000000000..6ef0e761e5de --- /dev/null +++ b/net/appletalk/atalk_proc.c @@ -0,0 +1,301 @@ +/* + * atalk_proc.c - proc support for Appletalk + * + * Copyright(c) Arnaldo Carvalho de Melo + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, version 2. + */ + +#include +#include +#include +#include +#include +#include + + +static __inline__ struct atalk_iface *atalk_get_interface_idx(loff_t pos) +{ + struct atalk_iface *i; + + for (i = atalk_interfaces; pos && i; i = i->next) + --pos; + + return i; +} + +static void *atalk_seq_interface_start(struct seq_file *seq, loff_t *pos) + __acquires(atalk_interfaces_lock) +{ + loff_t l = *pos; + + read_lock_bh(&atalk_interfaces_lock); + return l ? atalk_get_interface_idx(--l) : SEQ_START_TOKEN; +} + +static void *atalk_seq_interface_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct atalk_iface *i; + + ++*pos; + if (v == SEQ_START_TOKEN) { + i = NULL; + if (atalk_interfaces) + i = atalk_interfaces; + goto out; + } + i = v; + i = i->next; +out: + return i; +} + +static void atalk_seq_interface_stop(struct seq_file *seq, void *v) + __releases(atalk_interfaces_lock) +{ + read_unlock_bh(&atalk_interfaces_lock); +} + +static int atalk_seq_interface_show(struct seq_file *seq, void *v) +{ + struct atalk_iface *iface; + + if (v == SEQ_START_TOKEN) { + seq_puts(seq, "Interface Address Networks " + "Status\n"); + goto out; + } + + iface = v; + seq_printf(seq, "%-16s %04X:%02X %04X-%04X %d\n", + iface->dev->name, ntohs(iface->address.s_net), + iface->address.s_node, ntohs(iface->nets.nr_firstnet), + ntohs(iface->nets.nr_lastnet), iface->status); +out: + return 0; +} + +static __inline__ struct atalk_route *atalk_get_route_idx(loff_t pos) +{ + struct atalk_route *r; + + for (r = atalk_routes; pos && r; r = r->next) + --pos; + + return r; +} + +static void *atalk_seq_route_start(struct seq_file *seq, loff_t *pos) + __acquires(atalk_routes_lock) +{ + loff_t l = *pos; + + read_lock_bh(&atalk_routes_lock); + return l ? atalk_get_route_idx(--l) : SEQ_START_TOKEN; +} + +static void *atalk_seq_route_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct atalk_route *r; + + ++*pos; + if (v == SEQ_START_TOKEN) { + r = NULL; + if (atalk_routes) + r = atalk_routes; + goto out; + } + r = v; + r = r->next; +out: + return r; +} + +static void atalk_seq_route_stop(struct seq_file *seq, void *v) + __releases(atalk_routes_lock) +{ + read_unlock_bh(&atalk_routes_lock); +} + +static int atalk_seq_route_show(struct seq_file *seq, void *v) +{ + struct atalk_route *rt; + + if (v == SEQ_START_TOKEN) { + seq_puts(seq, "Target Router Flags Dev\n"); + goto out; + } + + if (atrtr_default.dev) { + rt = &atrtr_default; + seq_printf(seq, "Default %04X:%02X %-4d %s\n", + ntohs(rt->gateway.s_net), rt->gateway.s_node, + rt->flags, rt->dev->name); + } + + rt = v; + seq_printf(seq, "%04X:%02X %04X:%02X %-4d %s\n", + ntohs(rt->target.s_net), rt->target.s_node, + ntohs(rt->gateway.s_net), rt->gateway.s_node, + rt->flags, rt->dev->name); +out: + return 0; +} + +static void *atalk_seq_socket_start(struct seq_file *seq, loff_t *pos) + __acquires(atalk_sockets_lock) +{ + read_lock_bh(&atalk_sockets_lock); + return seq_hlist_start_head(&atalk_sockets, *pos); +} + +static void *atalk_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos) +{ + return seq_hlist_next(v, &atalk_sockets, pos); +} + +static void atalk_seq_socket_stop(struct seq_file *seq, void *v) + __releases(atalk_sockets_lock) +{ + read_unlock_bh(&atalk_sockets_lock); +} + +static int atalk_seq_socket_show(struct seq_file *seq, void *v) +{ + struct sock *s; + struct atalk_sock *at; + + if (v == SEQ_START_TOKEN) { + seq_printf(seq, "Type Local_addr Remote_addr Tx_queue " + "Rx_queue St UID\n"); + goto out; + } + + s = sk_entry(v); + at = at_sk(s); + + seq_printf(seq, "%02X %04X:%02X:%02X %04X:%02X:%02X %08X:%08X " + "%02X %d\n", + s->sk_type, ntohs(at->src_net), at->src_node, at->src_port, + ntohs(at->dest_net), at->dest_node, at->dest_port, + sk_wmem_alloc_get(s), + sk_rmem_alloc_get(s), + s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); +out: + return 0; +} + +static const struct seq_operations atalk_seq_interface_ops = { + .start = atalk_seq_interface_start, + .next = atalk_seq_interface_next, + .stop = atalk_seq_interface_stop, + .show = atalk_seq_interface_show, +}; + +static const struct seq_operations atalk_seq_route_ops = { + .start = atalk_seq_route_start, + .next = atalk_seq_route_next, + .stop = atalk_seq_route_stop, + .show = atalk_seq_route_show, +}; + +static const struct seq_operations atalk_seq_socket_ops = { + .start = atalk_seq_socket_start, + .next = atalk_seq_socket_next, + .stop = atalk_seq_socket_stop, + .show = atalk_seq_socket_show, +}; + +static int atalk_seq_interface_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &atalk_seq_interface_ops); +} + +static int atalk_seq_route_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &atalk_seq_route_ops); +} + +static int atalk_seq_socket_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &atalk_seq_socket_ops); +} + +static const struct file_operations atalk_seq_interface_fops = { + .owner = THIS_MODULE, + .open = atalk_seq_interface_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static const struct file_operations atalk_seq_route_fops = { + .owner = THIS_MODULE, + .open = atalk_seq_route_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static const struct file_operations atalk_seq_socket_fops = { + .owner = THIS_MODULE, + .open = atalk_seq_socket_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static struct proc_dir_entry *atalk_proc_dir; + +int __init atalk_proc_init(void) +{ + struct proc_dir_entry *p; + int rc = -ENOMEM; + + atalk_proc_dir = proc_mkdir("atalk", init_net.proc_net); + if (!atalk_proc_dir) + goto out; + + p = proc_create("interface", S_IRUGO, atalk_proc_dir, + &atalk_seq_interface_fops); + if (!p) + goto out_interface; + + p = proc_create("route", S_IRUGO, atalk_proc_dir, + &atalk_seq_route_fops); + if (!p) + goto out_route; + + p = proc_create("socket", S_IRUGO, atalk_proc_dir, + &atalk_seq_socket_fops); + if (!p) + goto out_socket; + + p = proc_create("arp", S_IRUGO, atalk_proc_dir, &atalk_seq_arp_fops); + if (!p) + goto out_arp; + + rc = 0; +out: + return rc; +out_arp: + remove_proc_entry("socket", atalk_proc_dir); +out_socket: + remove_proc_entry("route", atalk_proc_dir); +out_route: + remove_proc_entry("interface", atalk_proc_dir); +out_interface: + remove_proc_entry("atalk", init_net.proc_net); + goto out; +} + +void __exit atalk_proc_exit(void) +{ + remove_proc_entry("interface", atalk_proc_dir); + remove_proc_entry("route", atalk_proc_dir); + remove_proc_entry("socket", atalk_proc_dir); + remove_proc_entry("arp", atalk_proc_dir); + remove_proc_entry("atalk", init_net.proc_net); +} diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c new file mode 100644 index 000000000000..c410b93fda2e --- /dev/null +++ b/net/appletalk/ddp.c @@ -0,0 +1,1981 @@ +/* + * DDP: An implementation of the AppleTalk DDP protocol for + * Ethernet 'ELAP'. + * + * Alan Cox + * + * With more than a little assistance from + * + * Wesley Craig + * + * Fixes: + * Neil Horman : Added missing device ioctls + * Michael Callahan : Made routing work + * Wesley Craig : Fix probing to listen to a + * passed node id. + * Alan Cox : Added send/recvmsg support + * Alan Cox : Moved at. to protinfo in + * socket. + * Alan Cox : Added firewall hooks. + * Alan Cox : Supports new ARPHRD_LOOPBACK + * Christer Weinigel : Routing and /proc fixes. + * Bradford Johnson : LocalTalk. + * Tom Dyas : Module support. + * Alan Cox : Hooks for PPP (based on the + * LocalTalk hook). + * Alan Cox : Posix bits + * Alan Cox/Mike Freeman : Possible fix to NBP problems + * Bradford Johnson : IP-over-DDP (experimental) + * Jay Schulist : Moved IP-over-DDP to its own + * driver file. (ipddp.c & ipddp.h) + * Jay Schulist : Made work as module with + * AppleTalk drivers, cleaned it. + * Rob Newberry : Added proxy AARP and AARP + * procfs, moved probing to AARP + * module. + * Adrian Sun/ + * Michael Zuelsdorff : fix for net.0 packets. don't + * allow illegal ether/tokentalk + * port assignment. we lose a + * valid localtalk port as a + * result. + * Arnaldo C. de Melo : Cleanup, in preparation for + * shared skb support 8) + * Arnaldo C. de Melo : Move proc stuff to atalk_proc.c, + * use seq_file + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include /* For TIOCOUTQ/INQ */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../core/kmap_skb.h" + +struct datalink_proto *ddp_dl, *aarp_dl; +static const struct proto_ops atalk_dgram_ops; + +/**************************************************************************\ +* * +* Handlers for the socket list. * +* * +\**************************************************************************/ + +HLIST_HEAD(atalk_sockets); +DEFINE_RWLOCK(atalk_sockets_lock); + +static inline void __atalk_insert_socket(struct sock *sk) +{ + sk_add_node(sk, &atalk_sockets); +} + +static inline void atalk_remove_socket(struct sock *sk) +{ + write_lock_bh(&atalk_sockets_lock); + sk_del_node_init(sk); + write_unlock_bh(&atalk_sockets_lock); +} + +static struct sock *atalk_search_socket(struct sockaddr_at *to, + struct atalk_iface *atif) +{ + struct sock *s; + struct hlist_node *node; + + read_lock_bh(&atalk_sockets_lock); + sk_for_each(s, node, &atalk_sockets) { + struct atalk_sock *at = at_sk(s); + + if (to->sat_port != at->src_port) + continue; + + if (to->sat_addr.s_net == ATADDR_ANYNET && + to->sat_addr.s_node == ATADDR_BCAST) + goto found; + + if (to->sat_addr.s_net == at->src_net && + (to->sat_addr.s_node == at->src_node || + to->sat_addr.s_node == ATADDR_BCAST || + to->sat_addr.s_node == ATADDR_ANYNODE)) + goto found; + + /* XXXX.0 -- we got a request for this router. make sure + * that the node is appropriately set. */ + if (to->sat_addr.s_node == ATADDR_ANYNODE && + to->sat_addr.s_net != ATADDR_ANYNET && + atif->address.s_node == at->src_node) { + to->sat_addr.s_node = atif->address.s_node; + goto found; + } + } + s = NULL; +found: + read_unlock_bh(&atalk_sockets_lock); + return s; +} + +/** + * atalk_find_or_insert_socket - Try to find a socket matching ADDR + * @sk - socket to insert in the list if it is not there already + * @sat - address to search for + * + * Try to find a socket matching ADDR in the socket list, if found then return + * it. If not, insert SK into the socket list. + * + * This entire operation must execute atomically. + */ +static struct sock *atalk_find_or_insert_socket(struct sock *sk, + struct sockaddr_at *sat) +{ + struct sock *s; + struct hlist_node *node; + struct atalk_sock *at; + + write_lock_bh(&atalk_sockets_lock); + sk_for_each(s, node, &atalk_sockets) { + at = at_sk(s); + + if (at->src_net == sat->sat_addr.s_net && + at->src_node == sat->sat_addr.s_node && + at->src_port == sat->sat_port) + goto found; + } + s = NULL; + __atalk_insert_socket(sk); /* Wheee, it's free, assign and insert. */ +found: + write_unlock_bh(&atalk_sockets_lock); + return s; +} + +static void atalk_destroy_timer(unsigned long data) +{ + struct sock *sk = (struct sock *)data; + + if (sk_has_allocations(sk)) { + sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; + add_timer(&sk->sk_timer); + } else + sock_put(sk); +} + +static inline void atalk_destroy_socket(struct sock *sk) +{ + atalk_remove_socket(sk); + skb_queue_purge(&sk->sk_receive_queue); + + if (sk_has_allocations(sk)) { + setup_timer(&sk->sk_timer, atalk_destroy_timer, + (unsigned long)sk); + sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; + add_timer(&sk->sk_timer); + } else + sock_put(sk); +} + +/**************************************************************************\ +* * +* Routing tables for the AppleTalk socket layer. * +* * +\**************************************************************************/ + +/* Anti-deadlock ordering is atalk_routes_lock --> iface_lock -DaveM */ +struct atalk_route *atalk_routes; +DEFINE_RWLOCK(atalk_routes_lock); + +struct atalk_iface *atalk_interfaces; +DEFINE_RWLOCK(atalk_interfaces_lock); + +/* For probing devices or in a routerless network */ +struct atalk_route atrtr_default; + +/* AppleTalk interface control */ +/* + * Drop a device. Doesn't drop any of its routes - that is the caller's + * problem. Called when we down the interface or delete the address. + */ +static void atif_drop_device(struct net_device *dev) +{ + struct atalk_iface **iface = &atalk_interfaces; + struct atalk_iface *tmp; + + write_lock_bh(&atalk_interfaces_lock); + while ((tmp = *iface) != NULL) { + if (tmp->dev == dev) { + *iface = tmp->next; + dev_put(dev); + kfree(tmp); + dev->atalk_ptr = NULL; + } else + iface = &tmp->next; + } + write_unlock_bh(&atalk_interfaces_lock); +} + +static struct atalk_iface *atif_add_device(struct net_device *dev, + struct atalk_addr *sa) +{ + struct atalk_iface *iface = kzalloc(sizeof(*iface), GFP_KERNEL); + + if (!iface) + goto out; + + dev_hold(dev); + iface->dev = dev; + dev->atalk_ptr = iface; + iface->address = *sa; + iface->status = 0; + + write_lock_bh(&atalk_interfaces_lock); + iface->next = atalk_interfaces; + atalk_interfaces = iface; + write_unlock_bh(&atalk_interfaces_lock); +out: + return iface; +} + +/* Perform phase 2 AARP probing on our tentative address */ +static int atif_probe_device(struct atalk_iface *atif) +{ + int netrange = ntohs(atif->nets.nr_lastnet) - + ntohs(atif->nets.nr_firstnet) + 1; + int probe_net = ntohs(atif->address.s_net); + int probe_node = atif->address.s_node; + int netct, nodect; + + /* Offset the network we start probing with */ + if (probe_net == ATADDR_ANYNET) { + probe_net = ntohs(atif->nets.nr_firstnet); + if (netrange) + probe_net += jiffies % netrange; + } + if (probe_node == ATADDR_ANYNODE) + probe_node = jiffies & 0xFF; + + /* Scan the networks */ + atif->status |= ATIF_PROBE; + for (netct = 0; netct <= netrange; netct++) { + /* Sweep the available nodes from a given start */ + atif->address.s_net = htons(probe_net); + for (nodect = 0; nodect < 256; nodect++) { + atif->address.s_node = (nodect + probe_node) & 0xFF; + if (atif->address.s_node > 0 && + atif->address.s_node < 254) { + /* Probe a proposed address */ + aarp_probe_network(atif); + + if (!(atif->status & ATIF_PROBE_FAIL)) { + atif->status &= ~ATIF_PROBE; + return 0; + } + } + atif->status &= ~ATIF_PROBE_FAIL; + } + probe_net++; + if (probe_net > ntohs(atif->nets.nr_lastnet)) + probe_net = ntohs(atif->nets.nr_firstnet); + } + atif->status &= ~ATIF_PROBE; + + return -EADDRINUSE; /* Network is full... */ +} + + +/* Perform AARP probing for a proxy address */ +static int atif_proxy_probe_device(struct atalk_iface *atif, + struct atalk_addr* proxy_addr) +{ + int netrange = ntohs(atif->nets.nr_lastnet) - + ntohs(atif->nets.nr_firstnet) + 1; + /* we probe the interface's network */ + int probe_net = ntohs(atif->address.s_net); + int probe_node = ATADDR_ANYNODE; /* we'll take anything */ + int netct, nodect; + + /* Offset the network we start probing with */ + if (probe_net == ATADDR_ANYNET) { + probe_net = ntohs(atif->nets.nr_firstnet); + if (netrange) + probe_net += jiffies % netrange; + } + + if (probe_node == ATADDR_ANYNODE) + probe_node = jiffies & 0xFF; + + /* Scan the networks */ + for (netct = 0; netct <= netrange; netct++) { + /* Sweep the available nodes from a given start */ + proxy_addr->s_net = htons(probe_net); + for (nodect = 0; nodect < 256; nodect++) { + proxy_addr->s_node = (nodect + probe_node) & 0xFF; + if (proxy_addr->s_node > 0 && + proxy_addr->s_node < 254) { + /* Tell AARP to probe a proposed address */ + int ret = aarp_proxy_probe_network(atif, + proxy_addr); + + if (ret != -EADDRINUSE) + return ret; + } + } + probe_net++; + if (probe_net > ntohs(atif->nets.nr_lastnet)) + probe_net = ntohs(atif->nets.nr_firstnet); + } + + return -EADDRINUSE; /* Network is full... */ +} + + +struct atalk_addr *atalk_find_dev_addr(struct net_device *dev) +{ + struct atalk_iface *iface = dev->atalk_ptr; + return iface ? &iface->address : NULL; +} + +static struct atalk_addr *atalk_find_primary(void) +{ + struct atalk_iface *fiface = NULL; + struct atalk_addr *retval; + struct atalk_iface *iface; + + /* + * Return a point-to-point interface only if + * there is no non-ptp interface available. + */ + read_lock_bh(&atalk_interfaces_lock); + for (iface = atalk_interfaces; iface; iface = iface->next) { + if (!fiface && !(iface->dev->flags & IFF_LOOPBACK)) + fiface = iface; + if (!(iface->dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) { + retval = &iface->address; + goto out; + } + } + + if (fiface) + retval = &fiface->address; + else if (atalk_interfaces) + retval = &atalk_interfaces->address; + else + retval = NULL; +out: + read_unlock_bh(&atalk_interfaces_lock); + return retval; +} + +/* + * Find a match for 'any network' - ie any of our interfaces with that + * node number will do just nicely. + */ +static struct atalk_iface *atalk_find_anynet(int node, struct net_device *dev) +{ + struct atalk_iface *iface = dev->atalk_ptr; + + if (!iface || iface->status & ATIF_PROBE) + goto out_err; + + if (node != ATADDR_BCAST && + iface->address.s_node != node && + node != ATADDR_ANYNODE) + goto out_err; +out: + return iface; +out_err: + iface = NULL; + goto out; +} + +/* Find a match for a specific network:node pair */ +static struct atalk_iface *atalk_find_interface(__be16 net, int node) +{ + struct atalk_iface *iface; + + read_lock_bh(&atalk_interfaces_lock); + for (iface = atalk_interfaces; iface; iface = iface->next) { + if ((node == ATADDR_BCAST || + node == ATADDR_ANYNODE || + iface->address.s_node == node) && + iface->address.s_net == net && + !(iface->status & ATIF_PROBE)) + break; + + /* XXXX.0 -- net.0 returns the iface associated with net */ + if (node == ATADDR_ANYNODE && net != ATADDR_ANYNET && + ntohs(iface->nets.nr_firstnet) <= ntohs(net) && + ntohs(net) <= ntohs(iface->nets.nr_lastnet)) + break; + } + read_unlock_bh(&atalk_interfaces_lock); + return iface; +} + + +/* + * Find a route for an AppleTalk packet. This ought to get cached in + * the socket (later on...). We know about host routes and the fact + * that a route must be direct to broadcast. + */ +static struct atalk_route *atrtr_find(struct atalk_addr *target) +{ + /* + * we must search through all routes unless we find a + * host route, because some host routes might overlap + * network routes + */ + struct atalk_route *net_route = NULL; + struct atalk_route *r; + + read_lock_bh(&atalk_routes_lock); + for (r = atalk_routes; r; r = r->next) { + if (!(r->flags & RTF_UP)) + continue; + + if (r->target.s_net == target->s_net) { + if (r->flags & RTF_HOST) { + /* + * if this host route is for the target, + * the we're done + */ + if (r->target.s_node == target->s_node) + goto out; + } else + /* + * this route will work if there isn't a + * direct host route, so cache it + */ + net_route = r; + } + } + + /* + * if we found a network route but not a direct host + * route, then return it + */ + if (net_route) + r = net_route; + else if (atrtr_default.dev) + r = &atrtr_default; + else /* No route can be found */ + r = NULL; +out: + read_unlock_bh(&atalk_routes_lock); + return r; +} + + +/* + * Given an AppleTalk network, find the device to use. This can be + * a simple lookup. + */ +struct net_device *atrtr_get_dev(struct atalk_addr *sa) +{ + struct atalk_route *atr = atrtr_find(sa); + return atr ? atr->dev : NULL; +} + +/* Set up a default router */ +static void atrtr_set_default(struct net_device *dev) +{ + atrtr_default.dev = dev; + atrtr_default.flags = RTF_UP; + atrtr_default.gateway.s_net = htons(0); + atrtr_default.gateway.s_node = 0; +} + +/* + * Add a router. Basically make sure it looks valid and stuff the + * entry in the list. While it uses netranges we always set them to one + * entry to work like netatalk. + */ +static int atrtr_create(struct rtentry *r, struct net_device *devhint) +{ + struct sockaddr_at *ta = (struct sockaddr_at *)&r->rt_dst; + struct sockaddr_at *ga = (struct sockaddr_at *)&r->rt_gateway; + struct atalk_route *rt; + struct atalk_iface *iface, *riface; + int retval = -EINVAL; + + /* + * Fixme: Raise/Lower a routing change semaphore for these + * operations. + */ + + /* Validate the request */ + if (ta->sat_family != AF_APPLETALK || + (!devhint && ga->sat_family != AF_APPLETALK)) + goto out; + + /* Now walk the routing table and make our decisions */ + write_lock_bh(&atalk_routes_lock); + for (rt = atalk_routes; rt; rt = rt->next) { + if (r->rt_flags != rt->flags) + continue; + + if (ta->sat_addr.s_net == rt->target.s_net) { + if (!(rt->flags & RTF_HOST)) + break; + if (ta->sat_addr.s_node == rt->target.s_node) + break; + } + } + + if (!devhint) { + riface = NULL; + + read_lock_bh(&atalk_interfaces_lock); + for (iface = atalk_interfaces; iface; iface = iface->next) { + if (!riface && + ntohs(ga->sat_addr.s_net) >= + ntohs(iface->nets.nr_firstnet) && + ntohs(ga->sat_addr.s_net) <= + ntohs(iface->nets.nr_lastnet)) + riface = iface; + + if (ga->sat_addr.s_net == iface->address.s_net && + ga->sat_addr.s_node == iface->address.s_node) + riface = iface; + } + read_unlock_bh(&atalk_interfaces_lock); + + retval = -ENETUNREACH; + if (!riface) + goto out_unlock; + + devhint = riface->dev; + } + + if (!rt) { + rt = kzalloc(sizeof(*rt), GFP_ATOMIC); + + retval = -ENOBUFS; + if (!rt) + goto out_unlock; + + rt->next = atalk_routes; + atalk_routes = rt; + } + + /* Fill in the routing entry */ + rt->target = ta->sat_addr; + dev_hold(devhint); + rt->dev = devhint; + rt->flags = r->rt_flags; + rt->gateway = ga->sat_addr; + + retval = 0; +out_unlock: + write_unlock_bh(&atalk_routes_lock); +out: + return retval; +} + +/* Delete a route. Find it and discard it */ +static int atrtr_delete(struct atalk_addr * addr) +{ + struct atalk_route **r = &atalk_routes; + int retval = 0; + struct atalk_route *tmp; + + write_lock_bh(&atalk_routes_lock); + while ((tmp = *r) != NULL) { + if (tmp->target.s_net == addr->s_net && + (!(tmp->flags&RTF_GATEWAY) || + tmp->target.s_node == addr->s_node)) { + *r = tmp->next; + dev_put(tmp->dev); + kfree(tmp); + goto out; + } + r = &tmp->next; + } + retval = -ENOENT; +out: + write_unlock_bh(&atalk_routes_lock); + return retval; +} + +/* + * Called when a device is downed. Just throw away any routes + * via it. + */ +static void atrtr_device_down(struct net_device *dev) +{ + struct atalk_route **r = &atalk_routes; + struct atalk_route *tmp; + + write_lock_bh(&atalk_routes_lock); + while ((tmp = *r) != NULL) { + if (tmp->dev == dev) { + *r = tmp->next; + dev_put(dev); + kfree(tmp); + } else + r = &tmp->next; + } + write_unlock_bh(&atalk_routes_lock); + + if (atrtr_default.dev == dev) + atrtr_set_default(NULL); +} + +/* Actually down the interface */ +static inline void atalk_dev_down(struct net_device *dev) +{ + atrtr_device_down(dev); /* Remove all routes for the device */ + aarp_device_down(dev); /* Remove AARP entries for the device */ + atif_drop_device(dev); /* Remove the device */ +} + +/* + * A device event has occurred. Watch for devices going down and + * delete our use of them (iface and route). + */ +static int ddp_device_event(struct notifier_block *this, unsigned long event, + void *ptr) +{ + struct net_device *dev = ptr; + + if (!net_eq(dev_net(dev), &init_net)) + return NOTIFY_DONE; + + if (event == NETDEV_DOWN) + /* Discard any use of this */ + atalk_dev_down(dev); + + return NOTIFY_DONE; +} + +/* ioctl calls. Shouldn't even need touching */ +/* Device configuration ioctl calls */ +static int atif_ioctl(int cmd, void __user *arg) +{ + static char aarp_mcast[6] = { 0x09, 0x00, 0x00, 0xFF, 0xFF, 0xFF }; + struct ifreq atreq; + struct atalk_netrange *nr; + struct sockaddr_at *sa; + struct net_device *dev; + struct atalk_iface *atif; + int ct; + int limit; + struct rtentry rtdef; + int add_route; + + if (copy_from_user(&atreq, arg, sizeof(atreq))) + return -EFAULT; + + dev = __dev_get_by_name(&init_net, atreq.ifr_name); + if (!dev) + return -ENODEV; + + sa = (struct sockaddr_at *)&atreq.ifr_addr; + atif = atalk_find_dev(dev); + + switch (cmd) { + case SIOCSIFADDR: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (sa->sat_family != AF_APPLETALK) + return -EINVAL; + if (dev->type != ARPHRD_ETHER && + dev->type != ARPHRD_LOOPBACK && + dev->type != ARPHRD_LOCALTLK && + dev->type != ARPHRD_PPP) + return -EPROTONOSUPPORT; + + nr = (struct atalk_netrange *)&sa->sat_zero[0]; + add_route = 1; + + /* + * if this is a point-to-point iface, and we already + * have an iface for this AppleTalk address, then we + * should not add a route + */ + if ((dev->flags & IFF_POINTOPOINT) && + atalk_find_interface(sa->sat_addr.s_net, + sa->sat_addr.s_node)) { + printk(KERN_DEBUG "AppleTalk: point-to-point " + "interface added with " + "existing address\n"); + add_route = 0; + } + + /* + * Phase 1 is fine on LocalTalk but we don't do + * EtherTalk phase 1. Anyone wanting to add it go ahead. + */ + if (dev->type == ARPHRD_ETHER && nr->nr_phase != 2) + return -EPROTONOSUPPORT; + if (sa->sat_addr.s_node == ATADDR_BCAST || + sa->sat_addr.s_node == 254) + return -EINVAL; + if (atif) { + /* Already setting address */ + if (atif->status & ATIF_PROBE) + return -EBUSY; + + atif->address.s_net = sa->sat_addr.s_net; + atif->address.s_node = sa->sat_addr.s_node; + atrtr_device_down(dev); /* Flush old routes */ + } else { + atif = atif_add_device(dev, &sa->sat_addr); + if (!atif) + return -ENOMEM; + } + atif->nets = *nr; + + /* + * Check if the chosen address is used. If so we + * error and atalkd will try another. + */ + + if (!(dev->flags & IFF_LOOPBACK) && + !(dev->flags & IFF_POINTOPOINT) && + atif_probe_device(atif) < 0) { + atif_drop_device(dev); + return -EADDRINUSE; + } + + /* Hey it worked - add the direct routes */ + sa = (struct sockaddr_at *)&rtdef.rt_gateway; + sa->sat_family = AF_APPLETALK; + sa->sat_addr.s_net = atif->address.s_net; + sa->sat_addr.s_node = atif->address.s_node; + sa = (struct sockaddr_at *)&rtdef.rt_dst; + rtdef.rt_flags = RTF_UP; + sa->sat_family = AF_APPLETALK; + sa->sat_addr.s_node = ATADDR_ANYNODE; + if (dev->flags & IFF_LOOPBACK || + dev->flags & IFF_POINTOPOINT) + rtdef.rt_flags |= RTF_HOST; + + /* Routerless initial state */ + if (nr->nr_firstnet == htons(0) && + nr->nr_lastnet == htons(0xFFFE)) { + sa->sat_addr.s_net = atif->address.s_net; + atrtr_create(&rtdef, dev); + atrtr_set_default(dev); + } else { + limit = ntohs(nr->nr_lastnet); + if (limit - ntohs(nr->nr_firstnet) > 4096) { + printk(KERN_WARNING "Too many routes/" + "iface.\n"); + return -EINVAL; + } + if (add_route) + for (ct = ntohs(nr->nr_firstnet); + ct <= limit; ct++) { + sa->sat_addr.s_net = htons(ct); + atrtr_create(&rtdef, dev); + } + } + dev_mc_add_global(dev, aarp_mcast); + return 0; + + case SIOCGIFADDR: + if (!atif) + return -EADDRNOTAVAIL; + + sa->sat_family = AF_APPLETALK; + sa->sat_addr = atif->address; + break; + + case SIOCGIFBRDADDR: + if (!atif) + return -EADDRNOTAVAIL; + + sa->sat_family = AF_APPLETALK; + sa->sat_addr.s_net = atif->address.s_net; + sa->sat_addr.s_node = ATADDR_BCAST; + break; + + case SIOCATALKDIFADDR: + case SIOCDIFADDR: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (sa->sat_family != AF_APPLETALK) + return -EINVAL; + atalk_dev_down(dev); + break; + + case SIOCSARP: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (sa->sat_family != AF_APPLETALK) + return -EINVAL; + /* + * for now, we only support proxy AARP on ELAP; + * we should be able to do it for LocalTalk, too. + */ + if (dev->type != ARPHRD_ETHER) + return -EPROTONOSUPPORT; + + /* + * atif points to the current interface on this network; + * we aren't concerned about its current status (at + * least for now), but it has all the settings about + * the network we're going to probe. Consequently, it + * must exist. + */ + if (!atif) + return -EADDRNOTAVAIL; + + nr = (struct atalk_netrange *)&(atif->nets); + /* + * Phase 1 is fine on Localtalk but we don't do + * Ethertalk phase 1. Anyone wanting to add it go ahead. + */ + if (dev->type == ARPHRD_ETHER && nr->nr_phase != 2) + return -EPROTONOSUPPORT; + + if (sa->sat_addr.s_node == ATADDR_BCAST || + sa->sat_addr.s_node == 254) + return -EINVAL; + + /* + * Check if the chosen address is used. If so we + * error and ATCP will try another. + */ + if (atif_proxy_probe_device(atif, &(sa->sat_addr)) < 0) + return -EADDRINUSE; + + /* + * We now have an address on the local network, and + * the AARP code will defend it for us until we take it + * down. We don't set up any routes right now, because + * ATCP will install them manually via SIOCADDRT. + */ + break; + + case SIOCDARP: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (sa->sat_family != AF_APPLETALK) + return -EINVAL; + if (!atif) + return -EADDRNOTAVAIL; + + /* give to aarp module to remove proxy entry */ + aarp_proxy_remove(atif->dev, &(sa->sat_addr)); + return 0; + } + + return copy_to_user(arg, &atreq, sizeof(atreq)) ? -EFAULT : 0; +} + +/* Routing ioctl() calls */ +static int atrtr_ioctl(unsigned int cmd, void __user *arg) +{ + struct rtentry rt; + + if (copy_from_user(&rt, arg, sizeof(rt))) + return -EFAULT; + + switch (cmd) { + case SIOCDELRT: + if (rt.rt_dst.sa_family != AF_APPLETALK) + return -EINVAL; + return atrtr_delete(&((struct sockaddr_at *) + &rt.rt_dst)->sat_addr); + + case SIOCADDRT: { + struct net_device *dev = NULL; + if (rt.rt_dev) { + char name[IFNAMSIZ]; + if (copy_from_user(name, rt.rt_dev, IFNAMSIZ-1)) + return -EFAULT; + name[IFNAMSIZ-1] = '\0'; + dev = __dev_get_by_name(&init_net, name); + if (!dev) + return -ENODEV; + } + return atrtr_create(&rt, dev); + } + } + return -EINVAL; +} + +/**************************************************************************\ +* * +* Handling for system calls applied via the various interfaces to an * +* AppleTalk socket object. * +* * +\**************************************************************************/ + +/* + * Checksum: This is 'optional'. It's quite likely also a good + * candidate for assembler hackery 8) + */ +static unsigned long atalk_sum_partial(const unsigned char *data, + int len, unsigned long sum) +{ + /* This ought to be unwrapped neatly. I'll trust gcc for now */ + while (len--) { + sum += *data++; + sum = rol16(sum, 1); + } + return sum; +} + +/* Checksum skb data -- similar to skb_checksum */ +static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, + int len, unsigned long sum) +{ + int start = skb_headlen(skb); + struct sk_buff *frag_iter; + int i, copy; + + /* checksum stuff in header space */ + if ( (copy = start - offset) > 0) { + if (copy > len) + copy = len; + sum = atalk_sum_partial(skb->data + offset, copy, sum); + if ( (len -= copy) == 0) + return sum; + + offset += copy; + } + + /* checksum stuff in frags */ + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + int end; + + WARN_ON(start > offset + len); + + end = start + skb_shinfo(skb)->frags[i].size; + if ((copy = end - offset) > 0) { + u8 *vaddr; + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + if (copy > len) + copy = len; + vaddr = kmap_skb_frag(frag); + sum = atalk_sum_partial(vaddr + frag->page_offset + + offset - start, copy, sum); + kunmap_skb_frag(vaddr); + + if (!(len -= copy)) + return sum; + offset += copy; + } + start = end; + } + + skb_walk_frags(skb, frag_iter) { + int end; + + WARN_ON(start > offset + len); + + end = start + frag_iter->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + sum = atalk_sum_skb(frag_iter, offset - start, + copy, sum); + if ((len -= copy) == 0) + return sum; + offset += copy; + } + start = end; + } + + BUG_ON(len > 0); + + return sum; +} + +static __be16 atalk_checksum(const struct sk_buff *skb, int len) +{ + unsigned long sum; + + /* skip header 4 bytes */ + sum = atalk_sum_skb(skb, 4, len-4, 0); + + /* Use 0xFFFF for 0. 0 itself means none */ + return sum ? htons((unsigned short)sum) : htons(0xFFFF); +} + +static struct proto ddp_proto = { + .name = "DDP", + .owner = THIS_MODULE, + .obj_size = sizeof(struct atalk_sock), +}; + +/* + * Create a socket. Initialise the socket, blank the addresses + * set the state. + */ +static int atalk_create(struct net *net, struct socket *sock, int protocol, + int kern) +{ + struct sock *sk; + int rc = -ESOCKTNOSUPPORT; + + if (!net_eq(net, &init_net)) + return -EAFNOSUPPORT; + + /* + * We permit SOCK_DGRAM and RAW is an extension. It is trivial to do + * and gives you the full ELAP frame. Should be handy for CAP 8) + */ + if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM) + goto out; + rc = -ENOMEM; + sk = sk_alloc(net, PF_APPLETALK, GFP_KERNEL, &ddp_proto); + if (!sk) + goto out; + rc = 0; + sock->ops = &atalk_dgram_ops; + sock_init_data(sock, sk); + + /* Checksums on by default */ + sock_set_flag(sk, SOCK_ZAPPED); +out: + return rc; +} + +/* Free a socket. No work needed */ +static int atalk_release(struct socket *sock) +{ + struct sock *sk = sock->sk; + + lock_kernel(); + if (sk) { + sock_orphan(sk); + sock->sk = NULL; + atalk_destroy_socket(sk); + } + unlock_kernel(); + return 0; +} + +/** + * atalk_pick_and_bind_port - Pick a source port when one is not given + * @sk - socket to insert into the tables + * @sat - address to search for + * + * Pick a source port when one is not given. If we can find a suitable free + * one, we insert the socket into the tables using it. + * + * This whole operation must be atomic. + */ +static int atalk_pick_and_bind_port(struct sock *sk, struct sockaddr_at *sat) +{ + int retval; + + write_lock_bh(&atalk_sockets_lock); + + for (sat->sat_port = ATPORT_RESERVED; + sat->sat_port < ATPORT_LAST; + sat->sat_port++) { + struct sock *s; + struct hlist_node *node; + + sk_for_each(s, node, &atalk_sockets) { + struct atalk_sock *at = at_sk(s); + + if (at->src_net == sat->sat_addr.s_net && + at->src_node == sat->sat_addr.s_node && + at->src_port == sat->sat_port) + goto try_next_port; + } + + /* Wheee, it's free, assign and insert. */ + __atalk_insert_socket(sk); + at_sk(sk)->src_port = sat->sat_port; + retval = 0; + goto out; + +try_next_port:; + } + + retval = -EBUSY; +out: + write_unlock_bh(&atalk_sockets_lock); + return retval; +} + +static int atalk_autobind(struct sock *sk) +{ + struct atalk_sock *at = at_sk(sk); + struct sockaddr_at sat; + struct atalk_addr *ap = atalk_find_primary(); + int n = -EADDRNOTAVAIL; + + if (!ap || ap->s_net == htons(ATADDR_ANYNET)) + goto out; + + at->src_net = sat.sat_addr.s_net = ap->s_net; + at->src_node = sat.sat_addr.s_node = ap->s_node; + + n = atalk_pick_and_bind_port(sk, &sat); + if (!n) + sock_reset_flag(sk, SOCK_ZAPPED); +out: + return n; +} + +/* Set the address 'our end' of the connection */ +static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) +{ + struct sockaddr_at *addr = (struct sockaddr_at *)uaddr; + struct sock *sk = sock->sk; + struct atalk_sock *at = at_sk(sk); + int err; + + if (!sock_flag(sk, SOCK_ZAPPED) || + addr_len != sizeof(struct sockaddr_at)) + return -EINVAL; + + if (addr->sat_family != AF_APPLETALK) + return -EAFNOSUPPORT; + + lock_kernel(); + if (addr->sat_addr.s_net == htons(ATADDR_ANYNET)) { + struct atalk_addr *ap = atalk_find_primary(); + + err = -EADDRNOTAVAIL; + if (!ap) + goto out; + + at->src_net = addr->sat_addr.s_net = ap->s_net; + at->src_node = addr->sat_addr.s_node= ap->s_node; + } else { + err = -EADDRNOTAVAIL; + if (!atalk_find_interface(addr->sat_addr.s_net, + addr->sat_addr.s_node)) + goto out; + + at->src_net = addr->sat_addr.s_net; + at->src_node = addr->sat_addr.s_node; + } + + if (addr->sat_port == ATADDR_ANYPORT) { + err = atalk_pick_and_bind_port(sk, addr); + + if (err < 0) + goto out; + } else { + at->src_port = addr->sat_port; + + err = -EADDRINUSE; + if (atalk_find_or_insert_socket(sk, addr)) + goto out; + } + + sock_reset_flag(sk, SOCK_ZAPPED); + err = 0; +out: + unlock_kernel(); + return err; +} + +/* Set the address we talk to */ +static int atalk_connect(struct socket *sock, struct sockaddr *uaddr, + int addr_len, int flags) +{ + struct sock *sk = sock->sk; + struct atalk_sock *at = at_sk(sk); + struct sockaddr_at *addr; + int err; + + sk->sk_state = TCP_CLOSE; + sock->state = SS_UNCONNECTED; + + if (addr_len != sizeof(*addr)) + return -EINVAL; + + addr = (struct sockaddr_at *)uaddr; + + if (addr->sat_family != AF_APPLETALK) + return -EAFNOSUPPORT; + + if (addr->sat_addr.s_node == ATADDR_BCAST && + !sock_flag(sk, SOCK_BROADCAST)) { +#if 1 + printk(KERN_WARNING "%s is broken and did not set " + "SO_BROADCAST. It will break when 2.2 is " + "released.\n", + current->comm); +#else + return -EACCES; +#endif + } + + lock_kernel(); + err = -EBUSY; + if (sock_flag(sk, SOCK_ZAPPED)) + if (atalk_autobind(sk) < 0) + goto out; + + err = -ENETUNREACH; + if (!atrtr_get_dev(&addr->sat_addr)) + goto out; + + at->dest_port = addr->sat_port; + at->dest_net = addr->sat_addr.s_net; + at->dest_node = addr->sat_addr.s_node; + + sock->state = SS_CONNECTED; + sk->sk_state = TCP_ESTABLISHED; + err = 0; +out: + unlock_kernel(); + return err; +} + +/* + * Find the name of an AppleTalk socket. Just copy the right + * fields into the sockaddr. + */ +static int atalk_getname(struct socket *sock, struct sockaddr *uaddr, + int *uaddr_len, int peer) +{ + struct sockaddr_at sat; + struct sock *sk = sock->sk; + struct atalk_sock *at = at_sk(sk); + int err; + + lock_kernel(); + err = -ENOBUFS; + if (sock_flag(sk, SOCK_ZAPPED)) + if (atalk_autobind(sk) < 0) + goto out; + + *uaddr_len = sizeof(struct sockaddr_at); + memset(&sat.sat_zero, 0, sizeof(sat.sat_zero)); + + if (peer) { + err = -ENOTCONN; + if (sk->sk_state != TCP_ESTABLISHED) + goto out; + + sat.sat_addr.s_net = at->dest_net; + sat.sat_addr.s_node = at->dest_node; + sat.sat_port = at->dest_port; + } else { + sat.sat_addr.s_net = at->src_net; + sat.sat_addr.s_node = at->src_node; + sat.sat_port = at->src_port; + } + + err = 0; + sat.sat_family = AF_APPLETALK; + memcpy(uaddr, &sat, sizeof(sat)); + +out: + unlock_kernel(); + return err; +} + +static unsigned int atalk_poll(struct file *file, struct socket *sock, + poll_table *wait) +{ + int err; + lock_kernel(); + err = datagram_poll(file, sock, wait); + unlock_kernel(); + return err; +} + +#if defined(CONFIG_IPDDP) || defined(CONFIG_IPDDP_MODULE) +static __inline__ int is_ip_over_ddp(struct sk_buff *skb) +{ + return skb->data[12] == 22; +} + +static int handle_ip_over_ddp(struct sk_buff *skb) +{ + struct net_device *dev = __dev_get_by_name(&init_net, "ipddp0"); + struct net_device_stats *stats; + + /* This needs to be able to handle ipddp"N" devices */ + if (!dev) { + kfree_skb(skb); + return NET_RX_DROP; + } + + skb->protocol = htons(ETH_P_IP); + skb_pull(skb, 13); + skb->dev = dev; + skb_reset_transport_header(skb); + + stats = netdev_priv(dev); + stats->rx_packets++; + stats->rx_bytes += skb->len + 13; + return netif_rx(skb); /* Send the SKB up to a higher place. */ +} +#else +/* make it easy for gcc to optimize this test out, i.e. kill the code */ +#define is_ip_over_ddp(skb) 0 +#define handle_ip_over_ddp(skb) 0 +#endif + +static int atalk_route_packet(struct sk_buff *skb, struct net_device *dev, + struct ddpehdr *ddp, __u16 len_hops, int origlen) +{ + struct atalk_route *rt; + struct atalk_addr ta; + + /* + * Don't route multicast, etc., packets, or packets sent to "this + * network" + */ + if (skb->pkt_type != PACKET_HOST || !ddp->deh_dnet) { + /* + * FIXME: + * + * Can it ever happen that a packet is from a PPP iface and + * needs to be broadcast onto the default network? + */ + if (dev->type == ARPHRD_PPP) + printk(KERN_DEBUG "AppleTalk: didn't forward broadcast " + "packet received from PPP iface\n"); + goto free_it; + } + + ta.s_net = ddp->deh_dnet; + ta.s_node = ddp->deh_dnode; + + /* Route the packet */ + rt = atrtr_find(&ta); + /* increment hops count */ + len_hops += 1 << 10; + if (!rt || !(len_hops & (15 << 10))) + goto free_it; + + /* FIXME: use skb->cb to be able to use shared skbs */ + + /* + * Route goes through another gateway, so set the target to the + * gateway instead. + */ + + if (rt->flags & RTF_GATEWAY) { + ta.s_net = rt->gateway.s_net; + ta.s_node = rt->gateway.s_node; + } + + /* Fix up skb->len field */ + skb_trim(skb, min_t(unsigned int, origlen, + (rt->dev->hard_header_len + + ddp_dl->header_length + (len_hops & 1023)))); + + /* FIXME: use skb->cb to be able to use shared skbs */ + ddp->deh_len_hops = htons(len_hops); + + /* + * Send the buffer onwards + * + * Now we must always be careful. If it's come from LocalTalk to + * EtherTalk it might not fit + * + * Order matters here: If a packet has to be copied to make a new + * headroom (rare hopefully) then it won't need unsharing. + * + * Note. ddp-> becomes invalid at the realloc. + */ + if (skb_headroom(skb) < 22) { + /* 22 bytes - 12 ether, 2 len, 3 802.2 5 snap */ + struct sk_buff *nskb = skb_realloc_headroom(skb, 32); + kfree_skb(skb); + skb = nskb; + } else + skb = skb_unshare(skb, GFP_ATOMIC); + + /* + * If the buffer didn't vanish into the lack of space bitbucket we can + * send it. + */ + if (skb == NULL) + goto drop; + + if (aarp_send_ddp(rt->dev, skb, &ta, NULL) == NET_XMIT_DROP) + return NET_RX_DROP; + return NET_RX_SUCCESS; +free_it: + kfree_skb(skb); +drop: + return NET_RX_DROP; +} + +/** + * atalk_rcv - Receive a packet (in skb) from device dev + * @skb - packet received + * @dev - network device where the packet comes from + * @pt - packet type + * + * Receive a packet (in skb) from device dev. This has come from the SNAP + * decoder, and on entry skb->transport_header is the DDP header, skb->len + * is the DDP header, skb->len is the DDP length. The physical headers + * have been extracted. PPP should probably pass frames marked as for this + * layer. [ie ARPHRD_ETHERTALK] + */ +static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt, struct net_device *orig_dev) +{ + struct ddpehdr *ddp; + struct sock *sock; + struct atalk_iface *atif; + struct sockaddr_at tosat; + int origlen; + __u16 len_hops; + + if (!net_eq(dev_net(dev), &init_net)) + goto drop; + + /* Don't mangle buffer if shared */ + if (!(skb = skb_share_check(skb, GFP_ATOMIC))) + goto out; + + /* Size check and make sure header is contiguous */ + if (!pskb_may_pull(skb, sizeof(*ddp))) + goto drop; + + ddp = ddp_hdr(skb); + + len_hops = ntohs(ddp->deh_len_hops); + + /* Trim buffer in case of stray trailing data */ + origlen = skb->len; + skb_trim(skb, min_t(unsigned int, skb->len, len_hops & 1023)); + + /* + * Size check to see if ddp->deh_len was crap + * (Otherwise we'll detonate most spectacularly + * in the middle of atalk_checksum() or recvmsg()). + */ + if (skb->len < sizeof(*ddp) || skb->len < (len_hops & 1023)) { + pr_debug("AppleTalk: dropping corrupted frame (deh_len=%u, " + "skb->len=%u)\n", len_hops & 1023, skb->len); + goto drop; + } + + /* + * Any checksums. Note we don't do htons() on this == is assumed to be + * valid for net byte orders all over the networking code... + */ + if (ddp->deh_sum && + atalk_checksum(skb, len_hops & 1023) != ddp->deh_sum) + /* Not a valid AppleTalk frame - dustbin time */ + goto drop; + + /* Check the packet is aimed at us */ + if (!ddp->deh_dnet) /* Net 0 is 'this network' */ + atif = atalk_find_anynet(ddp->deh_dnode, dev); + else + atif = atalk_find_interface(ddp->deh_dnet, ddp->deh_dnode); + + if (!atif) { + /* Not ours, so we route the packet via the correct + * AppleTalk iface + */ + return atalk_route_packet(skb, dev, ddp, len_hops, origlen); + } + + /* if IP over DDP is not selected this code will be optimized out */ + if (is_ip_over_ddp(skb)) + return handle_ip_over_ddp(skb); + /* + * Which socket - atalk_search_socket() looks for a *full match* + * of the tuple. + */ + tosat.sat_addr.s_net = ddp->deh_dnet; + tosat.sat_addr.s_node = ddp->deh_dnode; + tosat.sat_port = ddp->deh_dport; + + sock = atalk_search_socket(&tosat, atif); + if (!sock) /* But not one of our sockets */ + goto drop; + + /* Queue packet (standard) */ + skb->sk = sock; + + if (sock_queue_rcv_skb(sock, skb) < 0) + goto drop; + + return NET_RX_SUCCESS; + +drop: + kfree_skb(skb); +out: + return NET_RX_DROP; + +} + +/* + * Receive a LocalTalk frame. We make some demands on the caller here. + * Caller must provide enough headroom on the packet to pull the short + * header and append a long one. + */ +static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt, struct net_device *orig_dev) +{ + if (!net_eq(dev_net(dev), &init_net)) + goto freeit; + + /* Expand any short form frames */ + if (skb_mac_header(skb)[2] == 1) { + struct ddpehdr *ddp; + /* Find our address */ + struct atalk_addr *ap = atalk_find_dev_addr(dev); + + if (!ap || skb->len < sizeof(__be16) || skb->len > 1023) + goto freeit; + + /* Don't mangle buffer if shared */ + if (!(skb = skb_share_check(skb, GFP_ATOMIC))) + return 0; + + /* + * The push leaves us with a ddephdr not an shdr, and + * handily the port bytes in the right place preset. + */ + ddp = (struct ddpehdr *) skb_push(skb, sizeof(*ddp) - 4); + + /* Now fill in the long header */ + + /* + * These two first. The mac overlays the new source/dest + * network information so we MUST copy these before + * we write the network numbers ! + */ + + ddp->deh_dnode = skb_mac_header(skb)[0]; /* From physical header */ + ddp->deh_snode = skb_mac_header(skb)[1]; /* From physical header */ + + ddp->deh_dnet = ap->s_net; /* Network number */ + ddp->deh_snet = ap->s_net; + ddp->deh_sum = 0; /* No checksum */ + /* + * Not sure about this bit... + */ + /* Non routable, so force a drop if we slip up later */ + ddp->deh_len_hops = htons(skb->len + (DDP_MAXHOPS << 10)); + } + skb_reset_transport_header(skb); + + return atalk_rcv(skb, dev, pt, orig_dev); +freeit: + kfree_skb(skb); + return 0; +} + +static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, + size_t len) +{ + struct sock *sk = sock->sk; + struct atalk_sock *at = at_sk(sk); + struct sockaddr_at *usat = (struct sockaddr_at *)msg->msg_name; + int flags = msg->msg_flags; + int loopback = 0; + struct sockaddr_at local_satalk, gsat; + struct sk_buff *skb; + struct net_device *dev; + struct ddpehdr *ddp; + int size; + struct atalk_route *rt; + int err; + + if (flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) + return -EINVAL; + + if (len > DDP_MAXSZ) + return -EMSGSIZE; + + lock_kernel(); + if (usat) { + err = -EBUSY; + if (sock_flag(sk, SOCK_ZAPPED)) + if (atalk_autobind(sk) < 0) + goto out; + + err = -EINVAL; + if (msg->msg_namelen < sizeof(*usat) || + usat->sat_family != AF_APPLETALK) + goto out; + + err = -EPERM; + /* netatalk didn't implement this check */ + if (usat->sat_addr.s_node == ATADDR_BCAST && + !sock_flag(sk, SOCK_BROADCAST)) { + goto out; + } + } else { + err = -ENOTCONN; + if (sk->sk_state != TCP_ESTABLISHED) + goto out; + usat = &local_satalk; + usat->sat_family = AF_APPLETALK; + usat->sat_port = at->dest_port; + usat->sat_addr.s_node = at->dest_node; + usat->sat_addr.s_net = at->dest_net; + } + + /* Build a packet */ + SOCK_DEBUG(sk, "SK %p: Got address.\n", sk); + + /* For headers */ + size = sizeof(struct ddpehdr) + len + ddp_dl->header_length; + + if (usat->sat_addr.s_net || usat->sat_addr.s_node == ATADDR_ANYNODE) { + rt = atrtr_find(&usat->sat_addr); + } else { + struct atalk_addr at_hint; + + at_hint.s_node = 0; + at_hint.s_net = at->src_net; + + rt = atrtr_find(&at_hint); + } + err = ENETUNREACH; + if (!rt) + goto out; + + dev = rt->dev; + + SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n", + sk, size, dev->name); + + size += dev->hard_header_len; + skb = sock_alloc_send_skb(sk, size, (flags & MSG_DONTWAIT), &err); + if (!skb) + goto out; + + skb->sk = sk; + skb_reserve(skb, ddp_dl->header_length); + skb_reserve(skb, dev->hard_header_len); + skb->dev = dev; + + SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk); + + ddp = (struct ddpehdr *)skb_put(skb, sizeof(struct ddpehdr)); + ddp->deh_len_hops = htons(len + sizeof(*ddp)); + ddp->deh_dnet = usat->sat_addr.s_net; + ddp->deh_snet = at->src_net; + ddp->deh_dnode = usat->sat_addr.s_node; + ddp->deh_snode = at->src_node; + ddp->deh_dport = usat->sat_port; + ddp->deh_sport = at->src_port; + + SOCK_DEBUG(sk, "SK %p: Copy user data (%Zd bytes).\n", sk, len); + + err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); + if (err) { + kfree_skb(skb); + err = -EFAULT; + goto out; + } + + if (sk->sk_no_check == 1) + ddp->deh_sum = 0; + else + ddp->deh_sum = atalk_checksum(skb, len + sizeof(*ddp)); + + /* + * Loopback broadcast packets to non gateway targets (ie routes + * to group we are in) + */ + if (ddp->deh_dnode == ATADDR_BCAST && + !(rt->flags & RTF_GATEWAY) && !(dev->flags & IFF_LOOPBACK)) { + struct sk_buff *skb2 = skb_copy(skb, GFP_KERNEL); + + if (skb2) { + loopback = 1; + SOCK_DEBUG(sk, "SK %p: send out(copy).\n", sk); + /* + * If it fails it is queued/sent above in the aarp queue + */ + aarp_send_ddp(dev, skb2, &usat->sat_addr, NULL); + } + } + + if (dev->flags & IFF_LOOPBACK || loopback) { + SOCK_DEBUG(sk, "SK %p: Loop back.\n", sk); + /* loop back */ + skb_orphan(skb); + if (ddp->deh_dnode == ATADDR_BCAST) { + struct atalk_addr at_lo; + + at_lo.s_node = 0; + at_lo.s_net = 0; + + rt = atrtr_find(&at_lo); + if (!rt) { + kfree_skb(skb); + err = -ENETUNREACH; + goto out; + } + dev = rt->dev; + skb->dev = dev; + } + ddp_dl->request(ddp_dl, skb, dev->dev_addr); + } else { + SOCK_DEBUG(sk, "SK %p: send out.\n", sk); + if (rt->flags & RTF_GATEWAY) { + gsat.sat_addr = rt->gateway; + usat = &gsat; + } + + /* + * If it fails it is queued/sent above in the aarp queue + */ + aarp_send_ddp(dev, skb, &usat->sat_addr, NULL); + } + SOCK_DEBUG(sk, "SK %p: Done write (%Zd).\n", sk, len); + +out: + unlock_kernel(); + return err ? : len; +} + +static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, + size_t size, int flags) +{ + struct sock *sk = sock->sk; + struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name; + struct ddpehdr *ddp; + int copied = 0; + int offset = 0; + int err = 0; + struct sk_buff *skb; + + lock_kernel(); + skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, + flags & MSG_DONTWAIT, &err); + if (!skb) + goto out; + + /* FIXME: use skb->cb to be able to use shared skbs */ + ddp = ddp_hdr(skb); + copied = ntohs(ddp->deh_len_hops) & 1023; + + if (sk->sk_type != SOCK_RAW) { + offset = sizeof(*ddp); + copied -= offset; + } + + if (copied > size) { + copied = size; + msg->msg_flags |= MSG_TRUNC; + } + err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied); + + if (!err) { + if (sat) { + sat->sat_family = AF_APPLETALK; + sat->sat_port = ddp->deh_sport; + sat->sat_addr.s_node = ddp->deh_snode; + sat->sat_addr.s_net = ddp->deh_snet; + } + msg->msg_namelen = sizeof(*sat); + } + + skb_free_datagram(sk, skb); /* Free the datagram. */ + +out: + unlock_kernel(); + return err ? : copied; +} + + +/* + * AppleTalk ioctl calls. + */ +static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) +{ + int rc = -ENOIOCTLCMD; + struct sock *sk = sock->sk; + void __user *argp = (void __user *)arg; + + switch (cmd) { + /* Protocol layer */ + case TIOCOUTQ: { + long amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); + + if (amount < 0) + amount = 0; + rc = put_user(amount, (int __user *)argp); + break; + } + case TIOCINQ: { + /* + * These two are safe on a single CPU system as only + * user tasks fiddle here + */ + struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); + long amount = 0; + + if (skb) + amount = skb->len - sizeof(struct ddpehdr); + rc = put_user(amount, (int __user *)argp); + break; + } + case SIOCGSTAMP: + rc = sock_get_timestamp(sk, argp); + break; + case SIOCGSTAMPNS: + rc = sock_get_timestampns(sk, argp); + break; + /* Routing */ + case SIOCADDRT: + case SIOCDELRT: + rc = -EPERM; + if (capable(CAP_NET_ADMIN)) + rc = atrtr_ioctl(cmd, argp); + break; + /* Interface */ + case SIOCGIFADDR: + case SIOCSIFADDR: + case SIOCGIFBRDADDR: + case SIOCATALKDIFADDR: + case SIOCDIFADDR: + case SIOCSARP: /* proxy AARP */ + case SIOCDARP: /* proxy AARP */ + rtnl_lock(); + rc = atif_ioctl(cmd, argp); + rtnl_unlock(); + break; + } + + return rc; +} + + +#ifdef CONFIG_COMPAT +static int atalk_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) +{ + /* + * SIOCATALKDIFADDR is a SIOCPROTOPRIVATE ioctl number, so we + * cannot handle it in common code. The data we access if ifreq + * here is compatible, so we can simply call the native + * handler. + */ + if (cmd == SIOCATALKDIFADDR) + return atalk_ioctl(sock, cmd, (unsigned long)compat_ptr(arg)); + + return -ENOIOCTLCMD; +} +#endif + + +static const struct net_proto_family atalk_family_ops = { + .family = PF_APPLETALK, + .create = atalk_create, + .owner = THIS_MODULE, +}; + +static const struct proto_ops atalk_dgram_ops = { + .family = PF_APPLETALK, + .owner = THIS_MODULE, + .release = atalk_release, + .bind = atalk_bind, + .connect = atalk_connect, + .socketpair = sock_no_socketpair, + .accept = sock_no_accept, + .getname = atalk_getname, + .poll = atalk_poll, + .ioctl = atalk_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = atalk_compat_ioctl, +#endif + .listen = sock_no_listen, + .shutdown = sock_no_shutdown, + .setsockopt = sock_no_setsockopt, + .getsockopt = sock_no_getsockopt, + .sendmsg = atalk_sendmsg, + .recvmsg = atalk_recvmsg, + .mmap = sock_no_mmap, + .sendpage = sock_no_sendpage, +}; + +static struct notifier_block ddp_notifier = { + .notifier_call = ddp_device_event, +}; + +static struct packet_type ltalk_packet_type __read_mostly = { + .type = cpu_to_be16(ETH_P_LOCALTALK), + .func = ltalk_rcv, +}; + +static struct packet_type ppptalk_packet_type __read_mostly = { + .type = cpu_to_be16(ETH_P_PPPTALK), + .func = atalk_rcv, +}; + +static unsigned char ddp_snap_id[] = { 0x08, 0x00, 0x07, 0x80, 0x9B }; + +/* Export symbols for use by drivers when AppleTalk is a module */ +EXPORT_SYMBOL(atrtr_get_dev); +EXPORT_SYMBOL(atalk_find_dev_addr); + +static const char atalk_err_snap[] __initconst = + KERN_CRIT "Unable to register DDP with SNAP.\n"; + +/* Called by proto.c on kernel start up */ +static int __init atalk_init(void) +{ + int rc = proto_register(&ddp_proto, 0); + + if (rc != 0) + goto out; + + (void)sock_register(&atalk_family_ops); + ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv); + if (!ddp_dl) + printk(atalk_err_snap); + + dev_add_pack(<alk_packet_type); + dev_add_pack(&ppptalk_packet_type); + + register_netdevice_notifier(&ddp_notifier); + aarp_proto_init(); + atalk_proc_init(); + atalk_register_sysctl(); +out: + return rc; +} +module_init(atalk_init); + +/* + * No explicit module reference count manipulation is needed in the + * protocol. Socket layer sets module reference count for us + * and interfaces reference counting is done + * by the network device layer. + * + * Ergo, before the AppleTalk module can be removed, all AppleTalk + * sockets be closed from user space. + */ +static void __exit atalk_exit(void) +{ +#ifdef CONFIG_SYSCTL + atalk_unregister_sysctl(); +#endif /* CONFIG_SYSCTL */ + atalk_proc_exit(); + aarp_cleanup_module(); /* General aarp clean-up. */ + unregister_netdevice_notifier(&ddp_notifier); + dev_remove_pack(<alk_packet_type); + dev_remove_pack(&ppptalk_packet_type); + unregister_snap_client(ddp_dl); + sock_unregister(PF_APPLETALK); + proto_unregister(&ddp_proto); +} +module_exit(atalk_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Alan Cox "); +MODULE_DESCRIPTION("AppleTalk 0.20\n"); +MODULE_ALIAS_NETPROTO(PF_APPLETALK); diff --git a/net/appletalk/dev.c b/net/appletalk/dev.c new file mode 100644 index 000000000000..6c8016f61866 --- /dev/null +++ b/net/appletalk/dev.c @@ -0,0 +1,44 @@ +/* + * Moved here from drivers/net/net_init.c, which is: + * Written 1993,1994,1995 by Donald Becker. + */ + +#include +#include +#include +#include +#include + +static void ltalk_setup(struct net_device *dev) +{ + /* Fill in the fields of the device structure with localtalk-generic values. */ + + dev->type = ARPHRD_LOCALTLK; + dev->hard_header_len = LTALK_HLEN; + dev->mtu = LTALK_MTU; + dev->addr_len = LTALK_ALEN; + dev->tx_queue_len = 10; + + dev->broadcast[0] = 0xFF; + + dev->flags = IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP; +} + +/** + * alloc_ltalkdev - Allocates and sets up an localtalk device + * @sizeof_priv: Size of additional driver-private structure to be allocated + * for this localtalk device + * + * Fill in the fields of the device structure with localtalk-generic + * values. Basically does everything except registering the device. + * + * Constructs a new net device, complete with a private data area of + * size @sizeof_priv. A 32-byte (not bit) alignment is enforced for + * this private data area. + */ + +struct net_device *alloc_ltalkdev(int sizeof_priv) +{ + return alloc_netdev(sizeof_priv, "lt%d", ltalk_setup); +} +EXPORT_SYMBOL(alloc_ltalkdev); diff --git a/net/appletalk/sysctl_net_atalk.c b/net/appletalk/sysctl_net_atalk.c new file mode 100644 index 000000000000..04e9c0da7aa9 --- /dev/null +++ b/net/appletalk/sysctl_net_atalk.c @@ -0,0 +1,61 @@ +/* + * sysctl_net_atalk.c: sysctl interface to net AppleTalk subsystem. + * + * Begun April 1, 1996, Mike Shaver. + * Added /proc/sys/net/atalk directory entry (empty =) ). [MS] + * Dynamic registration, added aarp entries. (5/30/97 Chris Horn) + */ + +#include +#include +#include + +static struct ctl_table atalk_table[] = { + { + .procname = "aarp-expiry-time", + .data = &sysctl_aarp_expiry_time, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_jiffies, + }, + { + .procname = "aarp-tick-time", + .data = &sysctl_aarp_tick_time, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_jiffies, + }, + { + .procname = "aarp-retransmit-limit", + .data = &sysctl_aarp_retransmit_limit, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { + .procname = "aarp-resolve-time", + .data = &sysctl_aarp_resolve_time, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_jiffies, + }, + { }, +}; + +static struct ctl_path atalk_path[] = { + { .procname = "net", }, + { .procname = "appletalk", }, + { } +}; + +static struct ctl_table_header *atalk_table_header; + +void atalk_register_sysctl(void) +{ + atalk_table_header = register_sysctl_paths(atalk_path, atalk_table); +} + +void atalk_unregister_sysctl(void) +{ + unregister_sysctl_table(atalk_table_header); +} diff --git a/net/socket.c b/net/socket.c index 26f7bcf36810..ac2219f90d5d 100644 --- a/net/socket.c +++ b/net/socket.c @@ -103,6 +103,7 @@ #include #include #include +#include static int sock_no_open(struct inode *irrelevant, struct file *dontcare); static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, -- cgit v1.2.3 From 61ceb7f91b7a56c129abb8d94a1267786fefcf70 Mon Sep 17 00:00:00 2001 From: Timo von Holtz Date: Sun, 30 Jan 2011 19:24:03 +0100 Subject: Staging: usbvideo: usbvideo: fixed some coding style issues fixed coding style issues. Signed-off-by: Timo von Holtz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbvideo/usbvideo.c | 170 +++++++++++++++++------------------- 1 file changed, 81 insertions(+), 89 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/usbvideo/usbvideo.c b/drivers/staging/usbvideo/usbvideo.c index f1fcf9744961..cd4c73af99ab 100644 --- a/drivers/staging/usbvideo/usbvideo.c +++ b/drivers/staging/usbvideo/usbvideo.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include "usbvideo.h" @@ -112,9 +112,9 @@ static void RingQueue_Allocate(struct RingQueue *rq, int rqLen) assert(rq != NULL); assert(rqLen > 0); - while(rqLen >> i) + while (rqLen >> i) i++; - if(rqLen != 1 << (i-1)) + if (rqLen != 1 << (i-1)) rqLen = 1 << i; rq->length = rqLen; @@ -148,15 +148,15 @@ int RingQueue_Dequeue(struct RingQueue *rq, unsigned char *dst, int len) assert(dst != NULL); rql = RingQueue_GetLength(rq); - if(!rql) + if (!rql) return 0; /* Clip requested length to available data */ - if(len > rql) + if (len > rql) len = rql; toread = len; - if(rq->ri > rq->wi) { + if (rq->ri > rq->wi) { /* Read data from tail */ int read = (toread < (rq->length - rq->ri)) ? toread : rq->length - rq->ri; memcpy(dst, rq->queue + rq->ri, read); @@ -164,7 +164,7 @@ int RingQueue_Dequeue(struct RingQueue *rq, unsigned char *dst, int len) dst += read; rq->ri = (rq->ri + read) & (rq->length-1); } - if(toread) { + if (toread) { /* Read data from head */ memcpy(dst, rq->queue + rq->ri, toread); rq->ri = (rq->ri + toread) & (rq->length-1); @@ -292,12 +292,11 @@ static void usbvideo_OverlayChar(struct uvd *uvd, struct usbvideo_frame *frame, return; digit = digits[value]; - for (iy=0; iy < 5; iy++) { - for (ix=0; ix < 3; ix++) { + for (iy = 0; iy < 5; iy++) { + for (ix = 0; ix < 3; ix++) { if (digit & 0x8000) { - if (uvd->paletteBits & (1L << VIDEO_PALETTE_RGB24)) { + if (uvd->paletteBits & (1L << VIDEO_PALETTE_RGB24)) /* TODO */ RGB24_PUTPIXEL(frame, x+ix, y+iy, 0xFF, 0xFF, 0xFF); - } } digit = digit << 1; } @@ -332,7 +331,7 @@ static void usbvideo_OverlayStats(struct uvd *uvd, struct usbvideo_frame *frame) { const int y_diff = 8; char tmp[16]; - int x = 10, y=10; + int x = 10, y = 10; long i, j, barLength; const int qi_x1 = 60, qi_y1 = 10; const int qi_x2 = VIDEOSIZE_X(frame->request) - 10, qi_h = 10; @@ -375,8 +374,8 @@ static void usbvideo_OverlayStats(struct uvd *uvd, struct usbvideo_frame *frame) m_lo = (u_lo > 0) ? (qi_x1 + ((barLength * u_lo) / uvd->dp.length)) : -1; m_hi = qi_x1 + ((barLength * u_hi) / uvd->dp.length); - for (j=qi_y1; j < (qi_y1 + qi_h); j++) { - for (i=qi_x1; i < qi_x2; i++) { + for (j = qi_y1; j < (qi_y1 + qi_h); j++) { + for (i = qi_x1; i < qi_x2; i++) { /* Draw border lines */ if ((j == qi_y1) || (j == (qi_y1 + qi_h - 1)) || (i == qi_x1) || (i == (qi_x2 - 1))) { @@ -384,11 +383,11 @@ static void usbvideo_OverlayStats(struct uvd *uvd, struct usbvideo_frame *frame) continue; } /* For all other points the Y coordinate does not matter */ - if ((i >= m_ri) && (i <= (m_ri + 3))) { + if ((i >= m_ri) && (i <= (m_ri + 3))) RGB24_PUTPIXEL(frame, i, j, 0x00, 0xFF, 0x00); - } else if ((i >= m_wi) && (i <= (m_wi + 3))) { + else if ((i >= m_wi) && (i <= (m_wi + 3))) RGB24_PUTPIXEL(frame, i, j, 0xFF, 0x00, 0x00); - } else if ((i < m_lo) || ((i > m_ri) && (i < m_hi))) + else if ((i < m_lo) || ((i > m_ri) && (i < m_hi))) RGB24_PUTPIXEL(frame, i, j, 0x00, 0x00, 0xFF); } } @@ -551,8 +550,8 @@ void usbvideo_TestPattern(struct uvd *uvd, int fullframe, int pmode) int i; unsigned char *f = frame->data + (VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL * frame->curline); - for (i=0; i < VIDEOSIZE_X(frame->request); i++) { - unsigned char cb=0x80; + for (i = 0; i < VIDEOSIZE_X(frame->request); i++) { + unsigned char cb = 0x80; unsigned char cg = 0; unsigned char cr = 0; @@ -605,10 +604,10 @@ void usbvideo_HexDump(const unsigned char *data, int len) char tmp[128]; /* 32*3 + 5 */ int i, k; - for (i=k=0; len > 0; i++, len--) { + for (i = k = 0; len > 0; i++, len--) { if (i > 0 && ((i % bytes_per_line) == 0)) { printk("%s\n", tmp); - k=0; + k = 0; } if ((i % bytes_per_line) == 0) k += sprintf(&tmp[k], "%04x: ", i); @@ -787,7 +786,7 @@ void usbvideo_Deregister(struct usbvideo **pCams) usb_deregister(&cams->usbdrv); dbg("%s: Deallocating cams=$%p (%d. cameras)", __func__, cams, cams->num_cameras); - for (i=0; i < cams->num_cameras; i++) { + for (i = 0; i < cams->num_cameras; i++) { struct uvd *up = &cams->cam[i]; int warning = 0; @@ -840,7 +839,7 @@ EXPORT_SYMBOL(usbvideo_Deregister); */ static void usbvideo_Disconnect(struct usb_interface *intf) { - struct uvd *uvd = usb_get_intfdata (intf); + struct uvd *uvd = usb_get_intfdata(intf); int i; if (uvd == NULL) { @@ -848,7 +847,7 @@ static void usbvideo_Disconnect(struct usb_interface *intf) return; } - usb_set_intfdata (intf, NULL); + usb_set_intfdata(intf, NULL); usbvideo_ClientIncModCount(uvd); if (uvd->debug > 0) @@ -860,11 +859,11 @@ static void usbvideo_Disconnect(struct usb_interface *intf) /* At this time we ask to cancel outstanding URBs */ GET_CALLBACK(uvd, stopDataPump)(uvd); - for (i=0; i < USBVIDEO_NUMSBUF; i++) + for (i = 0; i < USBVIDEO_NUMSBUF; i++) usb_free_urb(uvd->sbuf[i].urb); usb_put_dev(uvd->dev); - uvd->dev = NULL; /* USB device is no more */ + uvd->dev = NULL; /* USB device is no more */ video_unregister_device(&uvd->vdev); if (uvd->debug > 0) @@ -925,8 +924,7 @@ static int usbvideo_find_struct(struct usbvideo *cams) mutex_lock(&cams->lock); for (u = 0; u < cams->num_cameras; u++) { struct uvd *uvd = &cams->cam[u]; - if (!uvd->uvd_used) /* This one is free */ - { + if (!uvd->uvd_used) { /* This one is free */ uvd->uvd_used = 1; /* In use now */ mutex_init(&uvd->lock); /* to 1 == available */ uvd->dev = NULL; @@ -941,10 +939,10 @@ static int usbvideo_find_struct(struct usbvideo *cams) static const struct v4l2_file_operations usbvideo_fops = { .owner = THIS_MODULE, .open = usbvideo_v4l_open, - .release =usbvideo_v4l_close, - .read = usbvideo_v4l_read, - .mmap = usbvideo_v4l_mmap, - .ioctl = usbvideo_v4l_ioctl, + .release = usbvideo_v4l_close, + .read = usbvideo_v4l_read, + .mmap = usbvideo_v4l_mmap, + .ioctl = usbvideo_v4l_ioctl, }; static const struct video_device usbvideo_template = { .fops = &usbvideo_fops, @@ -972,7 +970,7 @@ struct uvd *usbvideo_AllocateDevice(struct usbvideo *cams) usbvideo_ClientIncModCount(uvd); mutex_lock(&uvd->lock); - for (i=0; i < USBVIDEO_NUMSBUF; i++) { + for (i = 0; i < USBVIDEO_NUMSBUF; i++) { uvd->sbuf[i].urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL); if (uvd->sbuf[i].urb == NULL) { err("usb_alloc_urb(%d.) failed.", FRAMES_PER_DESC); @@ -981,7 +979,7 @@ struct uvd *usbvideo_AllocateDevice(struct usbvideo *cams) goto allocate_done; } } - uvd->user=0; + uvd->user = 0; uvd->remove_pending = 0; uvd->last_error = 0; RingQueue_Initialize(&uvd->dp); @@ -1127,7 +1125,7 @@ static int usbvideo_v4l_open(struct file *file) memset(&uvd->stats, 0, sizeof(uvd->stats)); /* Clean pointers so we know if we allocated something */ - for (i=0; i < USBVIDEO_NUMSBUF; i++) + for (i = 0; i < USBVIDEO_NUMSBUF; i++) uvd->sbuf[i].data = NULL; /* Allocate memory for the frame buffers */ @@ -1140,7 +1138,7 @@ static int usbvideo_v4l_open(struct file *file) errCode = -ENOMEM; } else { /* Allocate all buffers */ - for (i=0; i < USBVIDEO_NUMFRAMES; i++) { + for (i = 0; i < USBVIDEO_NUMFRAMES; i++) { uvd->frame[i].frameState = FrameState_Unused; uvd->frame[i].data = uvd->fbuf + i*(uvd->max_frame_size); /* @@ -1150,7 +1148,7 @@ static int usbvideo_v4l_open(struct file *file) uvd->frame[i].canvas = uvd->canvas; uvd->frame[i].seqRead_Index = 0; } - for (i=0; i < USBVIDEO_NUMSBUF; i++) { + for (i = 0; i < USBVIDEO_NUMSBUF; i++) { uvd->sbuf[i].data = kmalloc(sb_size, GFP_KERNEL); if (uvd->sbuf[i].data == NULL) { errCode = -ENOMEM; @@ -1165,7 +1163,7 @@ static int usbvideo_v4l_open(struct file *file) uvd->fbuf = NULL; } RingQueue_Free(&uvd->dp); - for (i=0; i < USBVIDEO_NUMSBUF; i++) { + for (i = 0; i < USBVIDEO_NUMSBUF; i++) { kfree(uvd->sbuf[i].data); uvd->sbuf[i].data = NULL; } @@ -1240,7 +1238,7 @@ static int usbvideo_v4l_close(struct file *file) uvd->fbuf = NULL; RingQueue_Free(&uvd->dp); - for (i=0; i < USBVIDEO_NUMSBUF; i++) { + for (i = 0; i < USBVIDEO_NUMSBUF; i++) { kfree(uvd->sbuf[i].data); uvd->sbuf[i].data = NULL; } @@ -1281,32 +1279,32 @@ static long usbvideo_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg return -EIO; switch (cmd) { - case VIDIOCGCAP: + case VIDIOCGCAP: { struct video_capability *b = arg; *b = uvd->vcap; return 0; } - case VIDIOCGCHAN: + case VIDIOCGCHAN: { struct video_channel *v = arg; *v = uvd->vchan; return 0; } - case VIDIOCSCHAN: + case VIDIOCSCHAN: { struct video_channel *v = arg; if (v->channel != 0) return -EINVAL; return 0; } - case VIDIOCGPICT: + case VIDIOCGPICT: { struct video_picture *pic = arg; *pic = uvd->vpic; return 0; } - case VIDIOCSPICT: + case VIDIOCSPICT: { struct video_picture *pic = arg; /* @@ -1321,13 +1319,12 @@ static long usbvideo_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg uvd->settingsAdjusted = 0; /* Will force new settings */ return 0; } - case VIDIOCSWIN: + case VIDIOCSWIN: { struct video_window *vw = arg; - if(VALID_CALLBACK(uvd, setVideoMode)) { + if (VALID_CALLBACK(uvd, setVideoMode)) return GET_CALLBACK(uvd, setVideoMode)(uvd, vw); - } if (vw->flags) return -EINVAL; @@ -1340,7 +1337,7 @@ static long usbvideo_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg return 0; } - case VIDIOCGWIN: + case VIDIOCGWIN: { struct video_window *vw = arg; @@ -1355,7 +1352,7 @@ static long usbvideo_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg vw->flags = 10; /* FIXME: do better! */ return 0; } - case VIDIOCGMBUF: + case VIDIOCGMBUF: { struct video_mbuf *vm = arg; int i; @@ -1363,12 +1360,12 @@ static long usbvideo_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg memset(vm, 0, sizeof(*vm)); vm->size = uvd->max_frame_size * USBVIDEO_NUMFRAMES; vm->frames = USBVIDEO_NUMFRAMES; - for(i = 0; i < USBVIDEO_NUMFRAMES; i++) - vm->offsets[i] = i * uvd->max_frame_size; + for (i = 0; i < USBVIDEO_NUMFRAMES; i++) + vm->offsets[i] = i * uvd->max_frame_size; return 0; } - case VIDIOCMCAPTURE: + case VIDIOCMCAPTURE: { struct video_mmap *vm = arg; @@ -1429,7 +1426,7 @@ static long usbvideo_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg return usbvideo_NewFrame(uvd, vm->frame); } - case VIDIOCSYNC: + case VIDIOCSYNC: { int *frameNum = arg; int ret; @@ -1445,9 +1442,8 @@ static long usbvideo_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg ret = usbvideo_GetFrame(uvd, *frameNum); else if (VALID_CALLBACK(uvd, getFrame)) { ret = GET_CALLBACK(uvd, getFrame)(uvd, *frameNum); - if ((ret < 0) && (uvd->debug >= 1)) { + if ((ret < 0) && (uvd->debug >= 1)) err("VIDIOCSYNC: getFrame() returned %d.", ret); - } } else { err("VIDIOCSYNC: getFrame is not set"); ret = -EFAULT; @@ -1462,33 +1458,33 @@ static long usbvideo_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg uvd->frame[*frameNum].frameState = FrameState_Unused; return ret; } - case VIDIOCGFBUF: + case VIDIOCGFBUF: { struct video_buffer *vb = arg; memset(vb, 0, sizeof(*vb)); return 0; } - case VIDIOCKEY: - return 0; + case VIDIOCKEY: + return 0; - case VIDIOCCAPTURE: - return -EINVAL; + case VIDIOCCAPTURE: + return -EINVAL; - case VIDIOCSFBUF: + case VIDIOCSFBUF: - case VIDIOCGTUNER: - case VIDIOCSTUNER: + case VIDIOCGTUNER: + case VIDIOCSTUNER: - case VIDIOCGFREQ: - case VIDIOCSFREQ: + case VIDIOCGFREQ: + case VIDIOCSFREQ: - case VIDIOCGAUDIO: - case VIDIOCSAUDIO: - return -EINVAL; + case VIDIOCGAUDIO: + case VIDIOCSAUDIO: + return -EINVAL; - default: - return -ENOIOCTLCMD; + default: + return -ENOIOCTLCMD; } return 0; } @@ -1529,7 +1525,7 @@ static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, mutex_lock(&uvd->lock); /* See if a frame is completed, then use it. */ - for(i = 0; i < USBVIDEO_NUMFRAMES; i++) { + for (i = 0; i < USBVIDEO_NUMFRAMES; i++) { if ((uvd->frame[i].frameState == FrameState_Done) || (uvd->frame[i].frameState == FrameState_Done_Hold) || (uvd->frame[i].frameState == FrameState_Error)) { @@ -1550,7 +1546,7 @@ static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, * We will need to wait until it becomes cooked, of course. */ if (frmx == -1) { - for(i = 0; i < USBVIDEO_NUMFRAMES; i++) { + for (i = 0; i < USBVIDEO_NUMFRAMES; i++) { if (uvd->frame[i].frameState == FrameState_Grabbing) { frmx = i; break; @@ -1653,9 +1649,8 @@ static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, /* Mark it as available to be used again. */ uvd->frame[frmx].frameState = FrameState_Unused; - if (usbvideo_NewFrame(uvd, (frmx + 1) % USBVIDEO_NUMFRAMES)) { + if (usbvideo_NewFrame(uvd, (frmx + 1) % USBVIDEO_NUMFRAMES)) err("%s: usbvideo_NewFrame failed.", __func__); - } } read_done: mutex_unlock(&uvd->lock); @@ -1744,8 +1739,8 @@ urb_done_with: } urb->status = 0; urb->dev = uvd->dev; - ret = usb_submit_urb (urb, GFP_KERNEL); - if(ret) + ret = usb_submit_urb(urb, GFP_KERNEL); + if (ret) err("usb_submit_urb error (%d)", ret); return; } @@ -1785,7 +1780,7 @@ static int usbvideo_StartDataPump(struct uvd *uvd) err("%s: videoStart not set", __func__); /* We double buffer the Iso lists */ - for (i=0; i < USBVIDEO_NUMSBUF; i++) { + for (i = 0; i < USBVIDEO_NUMSBUF; i++) { int j, k; struct urb *urb = uvd->sbuf[i].urb; urb->dev = dev; @@ -1797,14 +1792,14 @@ static int usbvideo_StartDataPump(struct uvd *uvd) urb->complete = usbvideo_IsocIrq; urb->number_of_packets = FRAMES_PER_DESC; urb->transfer_buffer_length = uvd->iso_packet_len * FRAMES_PER_DESC; - for (j=k=0; j < FRAMES_PER_DESC; j++, k += uvd->iso_packet_len) { + for (j = k = 0; j < FRAMES_PER_DESC; j++, k += uvd->iso_packet_len) { urb->iso_frame_desc[j].offset = k; urb->iso_frame_desc[j].length = uvd->iso_packet_len; } } /* Submit all URBs */ - for (i=0; i < USBVIDEO_NUMSBUF; i++) { + for (i = 0; i < USBVIDEO_NUMSBUF; i++) { errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL); if (errFlag) err("%s: usb_submit_isoc(%d) ret %d", __func__, i, errFlag); @@ -1839,9 +1834,8 @@ static void usbvideo_StopDataPump(struct uvd *uvd) dev_info(&uvd->dev->dev, "%s($%p)\n", __func__, uvd); /* Unschedule all of the iso td's */ - for (i=0; i < USBVIDEO_NUMSBUF; i++) { + for (i = 0; i < USBVIDEO_NUMSBUF; i++) usb_kill_urb(uvd->sbuf[i].urb); - } if (uvd->debug > 1) dev_info(&uvd->dev->dev, "%s: streaming=0\n", __func__); uvd->streaming = 0; @@ -1995,7 +1989,7 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) case FrameState_Error: { int ntries, signalPending; - redo: +redo: if (!CAMERA_IS_OPERATIONAL(uvd)) { if (uvd->debug >= 2) dev_info(&uvd->dev->dev, @@ -2133,8 +2127,7 @@ void usbvideo_DeinterlaceFrame(struct uvd *uvd, struct usbvideo_frame *frame) return; if ((frame->deinterlace == Deinterlace_FillEvenLines) || - (frame->deinterlace == Deinterlace_FillOddLines)) - { + (frame->deinterlace == Deinterlace_FillOddLines)) { const int v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL; int i = (frame->deinterlace == Deinterlace_FillEvenLines) ? 0 : 1; @@ -2160,8 +2153,7 @@ void usbvideo_DeinterlaceFrame(struct uvd *uvd, struct usbvideo_frame *frame) /* Sanity check */ if ((ip < 0) || (in < 0) || (ip >= VIDEOSIZE_Y(frame->request)) || - (in >= VIDEOSIZE_Y(frame->request))) - { + (in >= VIDEOSIZE_Y(frame->request))) { err("Error: ip=%d. in=%d. req.height=%ld.", ip, in, VIDEOSIZE_Y(frame->request)); break; @@ -2173,7 +2165,7 @@ void usbvideo_DeinterlaceFrame(struct uvd *uvd, struct usbvideo_frame *frame) fd = frame->data + (v4l_linesize * i); /* Average lines around destination */ - for (j=0; j < v4l_linesize; j++) { + for (j = 0; j < v4l_linesize; j++) { fd[j] = (unsigned char)((((unsigned) fs1[j]) + ((unsigned)fs2[j])) >> 1); } @@ -2215,9 +2207,9 @@ static void usbvideo_SoftwareContrastAdjustment(struct uvd *uvd, return; } v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL; - for (i=0; i < VIDEOSIZE_Y(frame->request); i++) { + for (i = 0; i < VIDEOSIZE_Y(frame->request); i++) { unsigned char *fd = frame->data + (v4l_linesize * i); - for (j=0; j < v4l_linesize; j++) { + for (j = 0; j < v4l_linesize; j++) { signed long v = (signed long) fd[j]; /* Magnify up to 2 times, reduce down to zero */ v = 128 + ((ccm + adj) * (v - 128)) / ccm; -- cgit v1.2.3 From 046d747e0d2cb597e0b6fa4a79c32b43e97ed792 Mon Sep 17 00:00:00 2001 From: Timo von Holtz Date: Sun, 30 Jan 2011 20:04:55 +0100 Subject: Staging: usbvideo: vicam: fixed some coding style issues fixed coding style issues. Signed-off-by: Timo von Holtz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbvideo/vicam.c | 164 +++++++++++++++++++-------------------- 1 file changed, 79 insertions(+), 85 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/usbvideo/vicam.c b/drivers/staging/usbvideo/vicam.c index ecdb121297c9..a6816a4395b0 100644 --- a/drivers/staging/usbvideo/vicam.c +++ b/drivers/staging/usbvideo/vicam.c @@ -48,13 +48,13 @@ #include #include "usbvideo.h" -// #define VICAM_DEBUG +/* #define VICAM_DEBUG */ #ifdef VICAM_DEBUG -#define ADBG(lineno,fmt,args...) printk(fmt, jiffies, __func__, lineno, ##args) -#define DBG(fmt,args...) ADBG((__LINE__),KERN_DEBUG __FILE__"(%ld):%s (%d):"fmt,##args) +#define ADBG(lineno, fmt, args...) printk(fmt, jiffies, __func__, lineno, ##args) +#define DBG(fmt, args...) ADBG((__LINE__), KERN_DEBUG __FILE__"(%ld):%s (%d):"fmt, ##args) #else -#define DBG(fmn,args...) do {} while(0) +#define DBG(fmn, args...) do {} while (0) #endif #define DRIVER_AUTHOR "Joe Burks, jburks@wavicle.org" @@ -118,15 +118,15 @@ static void rvfree(void *mem, unsigned long size) } struct vicam_camera { - u16 shutter_speed; // capture shutter speed - u16 gain; // capture gain + u16 shutter_speed; /* capture shutter speed */ + u16 gain; /* capture gain */ - u8 *raw_image; // raw data captured from the camera - u8 *framebuf; // processed data in RGB24 format - u8 *cntrlbuf; // area used to send control msgs + u8 *raw_image; /* raw data captured from the camera */ + u8 *framebuf; /* processed data in RGB24 format */ + u8 *cntrlbuf; /* area used to send control msgs */ - struct video_device vdev; // v4l video device - struct usb_device *udev; // usb device + struct video_device vdev; /* v4l video device */ + struct usb_device *udev; /* usb device */ /* guard against simultaneous accesses to the camera */ struct mutex cam_lock; @@ -137,7 +137,7 @@ struct vicam_camera { int needsDummyRead; }; -static int vicam_probe( struct usb_interface *intf, const struct usb_device_id *id); +static int vicam_probe(struct usb_interface *intf, const struct usb_device_id *id); static void vicam_disconnect(struct usb_interface *intf); static void read_frame(struct vicam_camera *cam, int framenum); static void vicam_decode_color(const u8 *, u8 *); @@ -219,12 +219,12 @@ set_camera_power(struct vicam_camera *cam, int state) { int status; - if ((status = send_control_msg(cam, 0x50, state, 0, NULL, 0)) < 0) + status = send_control_msg(cam, 0x50, state, 0, NULL, 0)); + if (status < 0) return status; - if (state) { + if (state) send_control_msg(cam, 0x55, 1, 0, NULL, 0); - } return 0; } @@ -307,11 +307,11 @@ vicam_ioctl(struct file *file, unsigned int ioctlnr, unsigned long arg) { struct video_picture vp; DBG("VIDIOCGPICT\n"); - memset(&vp, 0, sizeof (struct video_picture)); + memset(&vp, 0, sizeof(struct video_picture)); vp.brightness = cam->gain << 8; vp.depth = 24; vp.palette = VIDEO_PALETTE_RGB24; - if (copy_to_user(user_arg, &vp, sizeof (struct video_picture))) + if (copy_to_user(user_arg, &vp, sizeof(struct video_picture))) retval = -EFAULT; break; } @@ -355,8 +355,8 @@ vicam_ioctl(struct file *file, unsigned int ioctlnr, unsigned long arg) if (copy_to_user(user_arg, (void *)&vw, sizeof(vw))) retval = -EFAULT; - // I'm not sure what the deal with a capture window is, it is very poorly described - // in the doc. So I won't support it now. + /* I'm not sure what the deal with a capture window is, it is very poorly described + * in the doc. So I won't support it now. */ break; } @@ -372,7 +372,7 @@ vicam_ioctl(struct file *file, unsigned int ioctlnr, unsigned long arg) DBG("VIDIOCSWIN %d x %d\n", vw.width, vw.height); - if ( vw.width != 320 || vw.height != 240 ) + if (vw.width != 320 || vw.height != 240) retval = -EFAULT; break; @@ -385,7 +385,7 @@ vicam_ioctl(struct file *file, unsigned int ioctlnr, unsigned long arg) int i; DBG("VIDIOCGMBUF\n"); - memset(&vm, 0, sizeof (vm)); + memset(&vm, 0, sizeof(vm)); vm.size = VICAM_MAX_FRAME_SIZE * VICAM_FRAMES; vm.frames = VICAM_FRAMES; @@ -401,23 +401,24 @@ vicam_ioctl(struct file *file, unsigned int ioctlnr, unsigned long arg) case VIDIOCMCAPTURE: { struct video_mmap vm; - // int video_size; + /* int video_size; */ if (copy_from_user((void *)&vm, user_arg, sizeof(vm))) { retval = -EFAULT; break; } - DBG("VIDIOCMCAPTURE frame=%d, height=%d, width=%d, format=%d.\n",vm.frame,vm.width,vm.height,vm.format); + DBG("VIDIOCMCAPTURE frame=%d, height=%d, width=%d, format=%d.\n", + vm.frame, vm.width, vm.height, vm.format); - if ( vm.frame >= VICAM_FRAMES || vm.format != VIDEO_PALETTE_RGB24 ) + if (vm.frame >= VICAM_FRAMES || vm.format != VIDEO_PALETTE_RGB24) retval = -EINVAL; - // in theory right here we'd start the image capturing - // (fill in a bulk urb and submit it asynchronously) - // - // Instead we're going to do a total hack job for now and - // retrieve the frame in VIDIOCSYNC + /* in theory right here we'd start the image capturing + * (fill in a bulk urb and submit it asynchronously) + * + * Instead we're going to do a total hack job for now and + * retrieve the frame in VIDIOCSYNC */ break; } @@ -435,7 +436,7 @@ vicam_ioctl(struct file *file, unsigned int ioctlnr, unsigned long arg) read_frame(cam, frame); vicam_decode_color(cam->raw_image, cam->framebuf + - frame * VICAM_MAX_FRAME_SIZE ); + frame * VICAM_MAX_FRAME_SIZE); break; } @@ -522,7 +523,7 @@ vicam_open(struct file *file) mutex_unlock(&cam->cam_lock); - // First upload firmware, then turn the camera on + /* First upload firmware, then turn the camera on */ if (!cam->is_initialized) { initialize_camera(cam); @@ -562,9 +563,8 @@ vicam_close(struct file *file) mutex_unlock(&cam->cam_lock); - if (!open_count && !udev) { + if (!open_count && !udev) kfree(cam); - } return 0; } @@ -582,57 +582,55 @@ static void vicam_decode_color(const u8 *data, u8 *rgb) data += VICAM_HEADER_SIZE; - for( i = 0; i < 240; i++, data += 512 ) { - const int y = ( i * 242 ) / 240; + for (i = 0; i < 240; i++, data += 512) { + const int y = (i * 242) / 240; int j, prevX, nextX; int Y, Cr, Cb; - if ( y == 242 - 1 ) { + if (y == 242 - 1) nextY = -512; - } prevX = 1; nextX = 1; - for ( j = 0; j < 320; j++, rgb += 3 ) { - const int x = ( j * 512 ) / 320; + for (j = 0; j < 320; j++, rgb += 3) { + const int x = (j * 512) / 320; const u8 * const src = &data[x]; - if ( x == 512 - 1 ) { + if (x == 512 - 1) nextX = -1; - } - Cr = ( src[prevX] - src[0] ) + - ( src[nextX] - src[0] ); + Cr = (src[prevX] - src[0]) + + (src[nextX] - src[0]); Cr /= 2; - Cb = ( src[prevY] - src[prevX + prevY] ) + - ( src[prevY] - src[nextX + prevY] ) + - ( src[nextY] - src[prevX + nextY] ) + - ( src[nextY] - src[nextX + nextY] ); + Cb = (src[prevY] - src[prevX + prevY]) + + (src[prevY] - src[nextX + prevY]) + + (src[nextY] - src[prevX + nextY]) + + (src[nextY] - src[nextX + nextY]); Cb /= 4; - Y = 1160 * ( src[0] + ( Cr / 2 ) - 16 ); + Y = 1160 * (src[0] + (Cr / 2) - 16); - if ( i & 1 ) { + if (i & 1) { int Ct = Cr; Cr = Cb; Cb = Ct; } - if ( ( x ^ i ) & 1 ) { + if ((x ^ i) & 1) { Cr = -Cr; Cb = -Cb; } - rgb[0] = clamp( ( ( Y + ( 2017 * Cb ) ) + - 500 ) / 900, 0, 255 ); - rgb[1] = clamp( ( ( Y - ( 392 * Cb ) - - ( 813 * Cr ) ) + - 500 ) / 1000, 0, 255 ); - rgb[2] = clamp( ( ( Y + ( 1594 * Cr ) ) + - 500 ) / 1300, 0, 255 ); + rgb[0] = clamp(((Y + (2017 * Cb)) + + 500) / 900, 0, 255); + rgb[1] = clamp(((Y - (392 * Cb) - + (813 * Cr)) + + 500) / 1000, 0, 255); + rgb[2] = clamp(((Y + (1594 * Cr)) + + 500) / 1300, 0, 255); prevX = -1; } @@ -655,15 +653,15 @@ read_frame(struct vicam_camera *cam, int framenum) } memset(request, 0, 16); - request[0] = cam->gain; // 0 = 0% gain, FF = 100% gain + request[0] = cam->gain; /* 0 = 0% gain, FF = 100% gain */ - request[1] = 0; // 512x242 capture + request[1] = 0; /* 512x242 capture */ - request[2] = 0x90; // the function of these two bytes - request[3] = 0x07; // is not yet understood + request[2] = 0x90; /* the function of these two bytes */ + request[3] = 0x07; /* is not yet understood */ if (cam->shutter_speed > 60) { - // Short exposure + /* Short exposure */ realShutter = ((-15631900 / cam->shutter_speed) + 260533) / 1000; request[4] = realShutter & 0xFF; @@ -671,7 +669,7 @@ read_frame(struct vicam_camera *cam, int framenum) request[6] = 0x03; request[7] = 0x01; } else { - // Long exposure + /* Long exposure */ realShutter = 15600 / cam->shutter_speed - 1; request[4] = 0; request[5] = 0; @@ -679,15 +677,14 @@ read_frame(struct vicam_camera *cam, int framenum) request[7] = realShutter >> 8; } - // Per John Markus Bjørndalen, byte at index 8 causes problems if it isn't 0 + /* Per John Markus Bjørndalen, byte at index 8 causes problems if it isn't 0*/ request[8] = 0; - // bytes 9-15 do not seem to affect exposure or image quality + /* bytes 9-15 do not seem to affect exposure or image quality */ mutex_lock(&cam->cam_lock); - if (!cam->udev) { + if (!cam->udev) goto done; - } n = __send_control_msg(cam, 0x51, 0x80, 0, request, 16); @@ -712,7 +709,7 @@ read_frame(struct vicam_camera *cam, int framenum) } static ssize_t -vicam_read( struct file *file, char __user *buf, size_t count, loff_t *ppos ) +vicam_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct vicam_camera *cam = file->private_data; @@ -732,15 +729,13 @@ vicam_read( struct file *file, char __user *buf, size_t count, loff_t *ppos ) count = min_t(size_t, count, VICAM_MAX_FRAME_SIZE - *ppos); - if (copy_to_user(buf, &cam->framebuf[*ppos], count)) { + if (copy_to_user(buf, &cam->framebuf[*ppos], count)) count = -EFAULT; - } else { + else *ppos += count; - } - if (count == VICAM_MAX_FRAME_SIZE) { + if (count == VICAM_MAX_FRAME_SIZE) *ppos = 0; - } return count; } @@ -749,7 +744,7 @@ vicam_read( struct file *file, char __user *buf, size_t count, loff_t *ppos ) static int vicam_mmap(struct file *file, struct vm_area_struct *vma) { - // TODO: allocate the raw frame buffer if necessary + /* TODO: allocate the raw frame buffer if necessary */ unsigned long page, pos; unsigned long start = vma->vm_start; unsigned long size = vma->vm_end-vma->vm_start; @@ -793,9 +788,9 @@ static const struct v4l2_file_operations vicam_fops = { }; static struct video_device vicam_template = { - .name = "ViCam-based USB Camera", - .fops = &vicam_fops, - .release = video_device_release_empty, + .name = "ViCam-based USB Camera", + .fops = &vicam_fops, + .release = video_device_release_empty, }; /* table of devices that work with this driver */ @@ -823,7 +818,7 @@ static struct usb_driver vicam_driver = { * this driver might be interested in. */ static int -vicam_probe( struct usb_interface *intf, const struct usb_device_id *id) +vicam_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); int bulkEndpoint = 0; @@ -847,8 +842,8 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id) "No bulk in endpoint was found ?! (this is bad)\n"); } - if ((cam = - kzalloc(sizeof (struct vicam_camera), GFP_KERNEL)) == NULL) { + cam = kzalloc(sizeof(struct vicam_camera), GFP_KERNEL); + if (cam == NULL) { printk(KERN_WARNING "could not allocate kernel memory for vicam_camera struct\n"); return -ENOMEM; @@ -874,7 +869,7 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id) printk(KERN_INFO "ViCam webcam driver now controlling device %s\n", video_device_node_name(&cam->vdev)); - usb_set_intfdata (intf, cam); + usb_set_intfdata(intf, cam); return 0; } @@ -883,8 +878,8 @@ static void vicam_disconnect(struct usb_interface *intf) { int open_count; - struct vicam_camera *cam = usb_get_intfdata (intf); - usb_set_intfdata (intf, NULL); + struct vicam_camera *cam = usb_get_intfdata(intf); + usb_set_intfdata(intf, NULL); /* we must unregister the device before taking its * cam_lock. This is because the video open call @@ -914,9 +909,8 @@ vicam_disconnect(struct usb_interface *intf) mutex_unlock(&cam->cam_lock); - if (!open_count) { + if (!open_count) kfree(cam); - } printk(KERN_DEBUG "ViCam-based WebCam disconnected\n"); } -- cgit v1.2.3 From 868788278eaa5b841ec1a810b41e156f5fba0ab5 Mon Sep 17 00:00:00 2001 From: Timo von Holtz Date: Sun, 30 Jan 2011 22:19:39 +0100 Subject: Staging: dabusb: fixed coding style issues Fixed coding style issues Signed-off-by: Timo von Holtz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dabusb/dabusb.c | 338 +++++++++++++++++++++------------------- drivers/staging/dabusb/dabusb.h | 41 +++-- 2 files changed, 193 insertions(+), 186 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dabusb/dabusb.c b/drivers/staging/dabusb/dabusb.c index f3e25e91366d..21768a627750 100644 --- a/drivers/staging/dabusb/dabusb.c +++ b/drivers/staging/dabusb/dabusb.c @@ -33,8 +33,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -66,28 +66,29 @@ static struct usb_driver dabusb_driver; /*-------------------------------------------------------------------*/ -static int dabusb_add_buf_tail (pdabusb_t s, struct list_head *dst, struct list_head *src) +static int dabusb_add_buf_tail(pdabusb_t s, struct list_head *dst, + struct list_head *src) { unsigned long flags; struct list_head *tmp; int ret = 0; - spin_lock_irqsave (&s->lock, flags); + spin_lock_irqsave(&s->lock, flags); - if (list_empty (src)) { - // no elements in source buffer + if (list_empty(src)) { + /* no elements in source buffer */ ret = -1; goto err; } tmp = src->next; - list_move_tail (tmp, dst); + list_move_tail(tmp, dst); - err: spin_unlock_irqrestore (&s->lock, flags); +err: spin_unlock_irqrestore(&s->lock, flags); return ret; } /*-------------------------------------------------------------------*/ #ifdef DEBUG -static void dump_urb (struct urb *urb) +static void dump_urb(struct urb *urb) { dbg("urb :%p", urb); dbg("dev :%p", urb->dev); @@ -107,26 +108,26 @@ static void dump_urb (struct urb *urb) } #endif /*-------------------------------------------------------------------*/ -static int dabusb_cancel_queue (pdabusb_t s, struct list_head *q) +static int dabusb_cancel_queue(pdabusb_t s, struct list_head *q) { unsigned long flags; pbuff_t b; dbg("dabusb_cancel_queue"); - spin_lock_irqsave (&s->lock, flags); + spin_lock_irqsave(&s->lock, flags); list_for_each_entry(b, q, buff_list) { #ifdef DEBUG dump_urb(b->purb); #endif - usb_unlink_urb (b->purb); + usb_unlink_urb(b->purb); } - spin_unlock_irqrestore (&s->lock, flags); + spin_unlock_irqrestore(&s->lock, flags); return 0; } /*-------------------------------------------------------------------*/ -static int dabusb_free_queue (struct list_head *q) +static int dabusb_free_queue(struct list_head *q) { struct list_head *tmp; struct list_head *p; @@ -134,7 +135,7 @@ static int dabusb_free_queue (struct list_head *q) dbg("dabusb_free_queue"); for (p = q->next; p != q;) { - b = list_entry (p, buff_t, buff_list); + b = list_entry(p, buff_t, buff_list); #ifdef DEBUG dump_urb(b->purb); @@ -142,23 +143,23 @@ static int dabusb_free_queue (struct list_head *q) kfree(b->purb->transfer_buffer); usb_free_urb(b->purb); tmp = p->next; - list_del (p); - kfree (b); + list_del(p); + kfree(b); p = tmp; } return 0; } /*-------------------------------------------------------------------*/ -static int dabusb_free_buffers (pdabusb_t s) +static int dabusb_free_buffers(pdabusb_t s) { unsigned long flags; dbg("dabusb_free_buffers"); spin_lock_irqsave(&s->lock, flags); - dabusb_free_queue (&s->free_buff_list); - dabusb_free_queue (&s->rec_buff_list); + dabusb_free_queue(&s->free_buff_list); + dabusb_free_queue(&s->rec_buff_list); spin_unlock_irqrestore(&s->lock, flags); @@ -166,7 +167,7 @@ static int dabusb_free_buffers (pdabusb_t s) return 0; } /*-------------------------------------------------------------------*/ -static void dabusb_iso_complete (struct urb *purb) +static void dabusb_iso_complete(struct urb *purb) { pbuff_t b = purb->context; pdabusb_t s = b->s; @@ -177,42 +178,45 @@ static void dabusb_iso_complete (struct urb *purb) dbg("dabusb_iso_complete"); - // process if URB was not killed + /* process if URB was not killed */ if (purb->status != -ENOENT) { - unsigned int pipe = usb_rcvisocpipe (purb->dev, _DABUSB_ISOPIPE); - int pipesize = usb_maxpacket (purb->dev, pipe, usb_pipeout (pipe)); + unsigned int pipe = usb_rcvisocpipe(purb->dev, _DABUSB_ISOPIPE); + int pipesize = usb_maxpacket(purb->dev, pipe, + usb_pipeout(pipe)); for (i = 0; i < purb->number_of_packets; i++) if (!purb->iso_frame_desc[i].status) { len = purb->iso_frame_desc[i].actual_length; if (len <= pipesize) { - memcpy (buf + dst, buf + purb->iso_frame_desc[i].offset, len); + memcpy(buf + dst, buf + purb->iso_frame_desc[i].offset, len); dst += len; - } - else + } else dev_err(&purb->dev->dev, - "dabusb_iso_complete: invalid len %d\n", len); - } - else - dev_warn(&purb->dev->dev, "dabusb_iso_complete: corrupted packet status: %d\n", purb->iso_frame_desc[i].status); + "dabusb_iso_complete: invalid len %d\n", + len); + } else + dev_warn(&purb->dev->dev, + "dabusb_iso_complete: corrupted packet status: %d\n", + purb->iso_frame_desc[i].status); if (dst != purb->actual_length) dev_err(&purb->dev->dev, "dst!=purb->actual_length:%d!=%d\n", dst, purb->actual_length); } - if (atomic_dec_and_test (&s->pending_io) && !s->remove_pending && s->state != _stopped) { + if (atomic_dec_and_test(&s->pending_io) && + !s->remove_pending && s->state != _stopped) { s->overruns++; dev_err(&purb->dev->dev, "overrun (%d)\n", s->overruns); } - wake_up (&s->wait); + wake_up(&s->wait); } /*-------------------------------------------------------------------*/ -static int dabusb_alloc_buffers (pdabusb_t s) +static int dabusb_alloc_buffers(pdabusb_t s) { int transfer_len = 0; pbuff_t b; - unsigned int pipe = usb_rcvisocpipe (s->usbdev, _DABUSB_ISOPIPE); - int pipesize = usb_maxpacket (s->usbdev, pipe, usb_pipeout (pipe)); + unsigned int pipe = usb_rcvisocpipe(s->usbdev, _DABUSB_ISOPIPE); + int pipesize = usb_maxpacket(s->usbdev, pipe, usb_pipeout(pipe)); int packets = _ISOPIPESIZE / pipesize; int transfer_buffer_length = packets * pipesize; int i; @@ -221,7 +225,7 @@ static int dabusb_alloc_buffers (pdabusb_t s) pipesize, packets, transfer_buffer_length); while (transfer_len < (s->total_buffer_size << 10)) { - b = kzalloc(sizeof (buff_t), GFP_KERNEL); + b = kzalloc(sizeof(buff_t), GFP_KERNEL); if (!b) { dev_err(&s->usbdev->dev, "kzalloc(sizeof(buff_t))==NULL\n"); @@ -231,14 +235,15 @@ static int dabusb_alloc_buffers (pdabusb_t s) b->purb = usb_alloc_urb(packets, GFP_KERNEL); if (!b->purb) { dev_err(&s->usbdev->dev, "usb_alloc_urb == NULL\n"); - kfree (b); + kfree(b); goto err; } - b->purb->transfer_buffer = kmalloc (transfer_buffer_length, GFP_KERNEL); + b->purb->transfer_buffer = kmalloc(transfer_buffer_length, + GFP_KERNEL); if (!b->purb->transfer_buffer) { - kfree (b->purb); - kfree (b); + kfree(b->purb); + kfree(b); dev_err(&s->usbdev->dev, "kmalloc(%d)==NULL\n", transfer_buffer_length); goto err; @@ -258,18 +263,18 @@ static int dabusb_alloc_buffers (pdabusb_t s) } transfer_len += transfer_buffer_length; - list_add_tail (&b->buff_list, &s->free_buff_list); + list_add_tail(&b->buff_list, &s->free_buff_list); } s->got_mem = transfer_len; return 0; - err: - dabusb_free_buffers (s); +err: + dabusb_free_buffers(s); return -ENOMEM; } /*-------------------------------------------------------------------*/ -static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb) +static int dabusb_bulk(pdabusb_t s, pbulk_transfer_t pb) { int ret; unsigned int pipe; @@ -278,25 +283,26 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb) dbg("dabusb_bulk"); if (!pb->pipe) - pipe = usb_rcvbulkpipe (s->usbdev, 2); + pipe = usb_rcvbulkpipe(s->usbdev, 2); else - pipe = usb_sndbulkpipe (s->usbdev, 2); + pipe = usb_sndbulkpipe(s->usbdev, 2); - ret=usb_bulk_msg(s->usbdev, pipe, pb->data, pb->size, &actual_length, 100); - if(ret<0) { + ret = usb_bulk_msg(s->usbdev, pipe, pb->data, + pb->size, &actual_length, 100); + if (ret < 0) { dev_err(&s->usbdev->dev, "usb_bulk_msg failed(%d)\n", ret); - if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) { + if (usb_set_interface(s->usbdev, _DABUSB_IF, 1) < 0) { dev_err(&s->usbdev->dev, "set_interface failed\n"); return -EINVAL; } } - if( ret == -EPIPE ) { + if (ret == -EPIPE) { dev_warn(&s->usbdev->dev, "CLEAR_FEATURE request to remove STALL condition.\n"); - if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe))) + if (usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe))) dev_err(&s->usbdev->dev, "request failed\n"); } @@ -304,11 +310,11 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb) return ret; } /* --------------------------------------------------------------------- */ -static int dabusb_writemem (pdabusb_t s, int pos, const unsigned char *data, +static int dabusb_writemem(pdabusb_t s, int pos, const unsigned char *data, int len) { int ret; - unsigned char *transfer_buffer = kmalloc (len, GFP_KERNEL); + unsigned char *transfer_buffer = kmalloc(len, GFP_KERNEL); if (!transfer_buffer) { dev_err(&s->usbdev->dev, @@ -316,21 +322,22 @@ static int dabusb_writemem (pdabusb_t s, int pos, const unsigned char *data, return -ENOMEM; } - memcpy (transfer_buffer, data, len); + memcpy(transfer_buffer, data, len); - ret=usb_control_msg(s->usbdev, usb_sndctrlpipe( s->usbdev, 0 ), 0xa0, 0x40, pos, 0, transfer_buffer, len, 300); + ret = usb_control_msg(s->usbdev, usb_sndctrlpipe(s->usbdev, 0), + 0xa0, 0x40, pos, 0, transfer_buffer, len, 300); - kfree (transfer_buffer); + kfree(transfer_buffer); return ret; } /* --------------------------------------------------------------------- */ -static int dabusb_8051_reset (pdabusb_t s, unsigned char reset_bit) +static int dabusb_8051_reset(pdabusb_t s, unsigned char reset_bit) { - dbg("dabusb_8051_reset: %d",reset_bit); - return dabusb_writemem (s, CPUCS_REG, &reset_bit, 1); + dbg("dabusb_8051_reset: %d", reset_bit); + return dabusb_writemem(s, CPUCS_REG, &reset_bit, 1); } /* --------------------------------------------------------------------- */ -static int dabusb_loadmem (pdabusb_t s, const char *fname) +static int dabusb_loadmem(pdabusb_t s, const char *fname) { int ret; const struct ihex_binrec *rec; @@ -344,7 +351,7 @@ static int dabusb_loadmem (pdabusb_t s, const char *fname) "Failed to load \"dabusb/firmware.fw\": %d\n", ret); goto out; } - ret = dabusb_8051_reset (s, 1); + ret = dabusb_8051_reset(s, 1); for (rec = (const struct ihex_binrec *)fw->data; rec; rec = ihex_next_binrec(rec)) { @@ -361,7 +368,7 @@ static int dabusb_loadmem (pdabusb_t s, const char *fname) break; } } - ret = dabusb_8051_reset (s, 0); + ret = dabusb_8051_reset(s, 0); release_firmware(fw); out: dbg("dabusb_loadmem: exit"); @@ -369,7 +376,7 @@ static int dabusb_loadmem (pdabusb_t s, const char *fname) return ret; } /* --------------------------------------------------------------------- */ -static int dabusb_fpga_clear (pdabusb_t s, pbulk_transfer_t b) +static int dabusb_fpga_clear(pdabusb_t s, pbulk_transfer_t b) { b->size = 4; b->data[0] = 0x2a; @@ -379,10 +386,10 @@ static int dabusb_fpga_clear (pdabusb_t s, pbulk_transfer_t b) dbg("dabusb_fpga_clear"); - return dabusb_bulk (s, b); + return dabusb_bulk(s, b); } /* --------------------------------------------------------------------- */ -static int dabusb_fpga_init (pdabusb_t s, pbulk_transfer_t b) +static int dabusb_fpga_init(pdabusb_t s, pbulk_transfer_t b) { b->size = 4; b->data[0] = 0x2c; @@ -392,12 +399,12 @@ static int dabusb_fpga_init (pdabusb_t s, pbulk_transfer_t b) dbg("dabusb_fpga_init"); - return dabusb_bulk (s, b); + return dabusb_bulk(s, b); } /* --------------------------------------------------------------------- */ -static int dabusb_fpga_download (pdabusb_t s, const char *fname) +static int dabusb_fpga_download(pdabusb_t s, const char *fname) { - pbulk_transfer_t b = kmalloc (sizeof (bulk_transfer_t), GFP_KERNEL); + pbulk_transfer_t b = kmalloc(sizeof(bulk_transfer_t), GFP_KERNEL); const struct firmware *fw; unsigned int blen, n; int ret; @@ -419,8 +426,8 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname) } b->pipe = 1; - ret = dabusb_fpga_clear (s, b); - mdelay (10); + ret = dabusb_fpga_clear(s, b); + mdelay(10); blen = fw->data[73] + (fw->data[72] << 8); dbg("Bitstream len: %i", blen); @@ -431,19 +438,19 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname) b->data[3] = 60; for (n = 0; n <= blen + 60; n += 60) { - // some cclks for startup + /* some cclks for startup */ b->size = 64; - memcpy (b->data + 4, fw->data + 74 + n, 60); - ret = dabusb_bulk (s, b); + memcpy(b->data + 4, fw->data + 74 + n, 60); + ret = dabusb_bulk(s, b); if (ret < 0) { dev_err(&s->usbdev->dev, "dabusb_bulk failed.\n"); break; } - mdelay (1); + mdelay(1); } - ret = dabusb_fpga_init (s, b); - kfree (b); + ret = dabusb_fpga_init(s, b); + kfree(b); release_firmware(fw); dbg("exit dabusb_fpga_download"); @@ -451,12 +458,12 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname) return ret; } -static int dabusb_stop (pdabusb_t s) +static int dabusb_stop(pdabusb_t s) { dbg("dabusb_stop"); s->state = _stopped; - dabusb_cancel_queue (s, &s->rec_buff_list); + dabusb_cancel_queue(s, &s->rec_buff_list); dbg("pending_io: %d", s->pending_io.counter); @@ -464,50 +471,53 @@ static int dabusb_stop (pdabusb_t s) return 0; } -static int dabusb_startrek (pdabusb_t s) +static int dabusb_startrek(pdabusb_t s) { if (!s->got_mem && s->state != _started) { dbg("dabusb_startrek"); - if (dabusb_alloc_buffers (s) < 0) + if (dabusb_alloc_buffers(s) < 0) return -ENOMEM; - dabusb_stop (s); + dabusb_stop(s); s->state = _started; s->readptr = 0; } - if (!list_empty (&s->free_buff_list)) { + if (!list_empty(&s->free_buff_list)) { pbuff_t end; int ret; - while (!dabusb_add_buf_tail (s, &s->rec_buff_list, &s->free_buff_list)) { + while (!dabusb_add_buf_tail(s, &s->rec_buff_list, &s->free_buff_list)) { - dbg("submitting: end:%p s->rec_buff_list:%p", s->rec_buff_list.prev, &s->rec_buff_list); + dbg("submitting: end:%p s->rec_buff_list:%p", + s->rec_buff_list.prev, &s->rec_buff_list); - end = list_entry (s->rec_buff_list.prev, buff_t, buff_list); + end = list_entry(s->rec_buff_list.prev, + buff_t, buff_list); - ret = usb_submit_urb (end->purb, GFP_KERNEL); + ret = usb_submit_urb(end->purb, GFP_KERNEL); if (ret) { dev_err(&s->usbdev->dev, "usb_submit_urb returned:%d\n", ret); - if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list)) + if (dabusb_add_buf_tail(s, &s->free_buff_list, + &s->rec_buff_list)) dev_err(&s->usbdev->dev, "startrek: dabusb_add_buf_tail failed\n"); break; - } - else - atomic_inc (&s->pending_io); + } else + atomic_inc(&s->pending_io); } - dbg("pending_io: %d",s->pending_io.counter); + dbg("pending_io: %d", s->pending_io.counter); } return 0; } -static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, loff_t * ppos) +static ssize_t dabusb_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) { - pdabusb_t s = (pdabusb_t) file->private_data; + pdabusb_t s = (pdabusb_t)file->private_data; unsigned long flags; unsigned ret = 0; int rem; @@ -528,11 +538,11 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l return -EIO; while (count > 0) { - dabusb_startrek (s); + dabusb_startrek(s); - spin_lock_irqsave (&s->lock, flags); + spin_lock_irqsave(&s->lock, flags); - if (list_empty (&s->rec_buff_list)) { + if (list_empty(&s->rec_buff_list)) { spin_unlock_irqrestore(&s->lock, flags); @@ -541,30 +551,30 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l goto err; } - b = list_entry (s->rec_buff_list.next, buff_t, buff_list); + b = list_entry(s->rec_buff_list.next, buff_t, buff_list); purb = b->purb; spin_unlock_irqrestore(&s->lock, flags); if (purb->status == -EINPROGRESS) { - if (file->f_flags & O_NONBLOCK) // return nonblocking - { + /* return nonblocking */ + if (file->f_flags & O_NONBLOCK) { if (!ret) ret = -EAGAIN; goto err; } - interruptible_sleep_on (&s->wait); + interruptible_sleep_on(&s->wait); - if (signal_pending (current)) { + if (signal_pending(current)) { if (!ret) ret = -ERESTARTSYS; goto err; } - spin_lock_irqsave (&s->lock, flags); + spin_lock_irqsave(&s->lock, flags); - if (list_empty (&s->rec_buff_list)) { + if (list_empty(&s->rec_buff_list)) { spin_unlock_irqrestore(&s->lock, flags); dev_err(&s->usbdev->dev, "error: still no buffer available.\n"); @@ -578,16 +588,20 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l goto err; } - rem = purb->actual_length - s->readptr; // set remaining bytes to copy + /* set remaining bytes to copy */ + rem = purb->actual_length - s->readptr; if (count >= rem) cnt = rem; else cnt = count; - dbg("copy_to_user:%p %p %d",buf, purb->transfer_buffer + s->readptr, cnt); + dbg("copy_to_user:%p %p %d", buf, + purb->transfer_buffer + s->readptr, cnt); - if (copy_to_user (buf, purb->transfer_buffer + s->readptr, cnt)) { + if (copy_to_user(buf, + purb->transfer_buffer + s->readptr, + cnt)) { dev_err(&s->usbdev->dev, "read: copy_to_user failed\n"); if (!ret) ret = -EFAULT; @@ -600,18 +614,19 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l ret += cnt; if (s->readptr == purb->actual_length) { - // finished, take next buffer - if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list)) + /* finished, take next buffer */ + if (dabusb_add_buf_tail(s, &s->free_buff_list, + &s->rec_buff_list)) dev_err(&s->usbdev->dev, "read: dabusb_add_buf_tail failed\n"); s->readptr = 0; } } - err: //mutex_unlock(&s->mutex); +err: /*mutex_unlock(&s->mutex);*/ return ret; } -static int dabusb_open (struct inode *inode, struct file *file) +static int dabusb_open(struct inode *inode, struct file *file) { int devnum = iminor(inode); pdabusb_t s; @@ -632,11 +647,11 @@ static int dabusb_open (struct inode *inode, struct file *file) return -EBUSY; msleep_interruptible(500); - if (signal_pending (current)) + if (signal_pending(current)) return -EAGAIN; mutex_lock(&s->mutex); } - if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) { + if (usb_set_interface(s->usbdev, _DABUSB_IF, 1) < 0) { mutex_unlock(&s->mutex); dev_err(&s->usbdev->dev, "set_interface failed\n"); return -EINVAL; @@ -651,31 +666,30 @@ static int dabusb_open (struct inode *inode, struct file *file) return r; } -static int dabusb_release (struct inode *inode, struct file *file) +static int dabusb_release(struct inode *inode, struct file *file) { - pdabusb_t s = (pdabusb_t) file->private_data; + pdabusb_t s = (pdabusb_t)file->private_data; dbg("dabusb_release"); mutex_lock(&s->mutex); - dabusb_stop (s); - dabusb_free_buffers (s); + dabusb_stop(s); + dabusb_free_buffers(s); mutex_unlock(&s->mutex); if (!s->remove_pending) { - if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0) + if (usb_set_interface(s->usbdev, _DABUSB_IF, 0) < 0) dev_err(&s->usbdev->dev, "set_interface failed\n"); - } - else - wake_up (&s->remove_ok); + } else + wake_up(&s->remove_ok); s->opened = 0; return 0; } -static long dabusb_ioctl (struct file *file, unsigned int cmd, unsigned long arg) +static long dabusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - pdabusb_t s = (pdabusb_t) file->private_data; + pdabusb_t s = (pdabusb_t)file->private_data; pbulk_transfer_t pbulk; int ret = 0; int version = DABUSB_VERSION; @@ -703,20 +717,20 @@ static long dabusb_ioctl (struct file *file, unsigned int cmd, unsigned long arg break; } - ret=dabusb_bulk (s, pbulk); - if(ret==0) + ret = dabusb_bulk(s, pbulk); + if (ret == 0) if (copy_to_user((void __user *)arg, pbulk, sizeof(bulk_transfer_t))) ret = -EFAULT; - kfree (pbulk); + kfree(pbulk); break; case IOCTL_DAB_OVERRUNS: - ret = put_user (s->overruns, (unsigned int __user *) arg); + ret = put_user(s->overruns, (unsigned int __user *) arg); break; case IOCTL_DAB_VERSION: - ret = put_user (version, (unsigned int __user *) arg); + ret = put_user(version, (unsigned int __user *) arg); break; default: @@ -727,8 +741,7 @@ static long dabusb_ioctl (struct file *file, unsigned int cmd, unsigned long arg return ret; } -static const struct file_operations dabusb_fops = -{ +static const struct file_operations dabusb_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .read = dabusb_read, @@ -751,7 +764,7 @@ static struct usb_class_driver dabusb_class = { /* --------------------------------------------------------------------- */ -static int dabusb_probe (struct usb_interface *intf, +static int dabusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *usbdev = interface_to_usbdev(intf); @@ -780,54 +793,53 @@ static int dabusb_probe (struct usb_interface *intf, s->usbdev = usbdev; s->devnum = intf->minor; - if (usb_reset_configuration (usbdev) < 0) { + if (usb_reset_configuration(usbdev) < 0) { dev_err(&intf->dev, "reset_configuration failed\n"); goto reject; } if (le16_to_cpu(usbdev->descriptor.idProduct) == 0x2131) { - dabusb_loadmem (s, NULL); + dabusb_loadmem(s, NULL); goto reject; - } - else { - dabusb_fpga_download (s, NULL); + } else { + dabusb_fpga_download(s, NULL); - if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0) { + if (usb_set_interface(s->usbdev, _DABUSB_IF, 0) < 0) { dev_err(&intf->dev, "set_interface failed\n"); goto reject; } } dbg("bound to interface: %d", intf->altsetting->desc.bInterfaceNumber); - usb_set_intfdata (intf, s); + usb_set_intfdata(intf, s); mutex_unlock(&s->mutex); retval = usb_register_dev(intf, &dabusb_class); if (retval) { - usb_set_intfdata (intf, NULL); + usb_set_intfdata(intf, NULL); return -ENOMEM; } return 0; - reject: +reject: mutex_unlock(&s->mutex); s->usbdev = NULL; return -ENODEV; } -static void dabusb_disconnect (struct usb_interface *intf) +static void dabusb_disconnect(struct usb_interface *intf) { wait_queue_t __wait; - pdabusb_t s = usb_get_intfdata (intf); + pdabusb_t s = usb_get_intfdata(intf); dbg("dabusb_disconnect"); init_waitqueue_entry(&__wait, current); - usb_set_intfdata (intf, NULL); + usb_set_intfdata(intf, NULL); if (s) { - usb_deregister_dev (intf, &dabusb_class); + usb_deregister_dev(intf, &dabusb_class); s->remove_pending = 1; - wake_up (&s->wait); + wake_up(&s->wait); add_wait_queue(&s->remove_ok, &__wait); set_current_state(TASK_UNINTERRUPTIBLE); if (s->state == _started) @@ -840,13 +852,13 @@ static void dabusb_disconnect (struct usb_interface *intf) } } -static struct usb_device_id dabusb_ids [] = { - // { USB_DEVICE(0x0547, 0x2131) }, /* An2131 chip, no boot ROM */ +static struct usb_device_id dabusb_ids[] = { + /* { USB_DEVICE(0x0547, 0x2131) },*/ /* An2131 chip, no boot ROM */ { USB_DEVICE(0x0547, 0x9999) }, { } /* Terminating entry */ }; -MODULE_DEVICE_TABLE (usb, dabusb_ids); +MODULE_DEVICE_TABLE(usb, dabusb_ids); static struct usb_driver dabusb_driver = { .name = "dabusb", @@ -857,7 +869,7 @@ static struct usb_driver dabusb_driver = { /* --------------------------------------------------------------------- */ -static int __init dabusb_init (void) +static int __init dabusb_init(void) { int retval; unsigned u; @@ -865,15 +877,15 @@ static int __init dabusb_init (void) /* initialize struct */ for (u = 0; u < NRDABUSB; u++) { pdabusb_t s = &dabusb[u]; - memset (s, 0, sizeof (dabusb_t)); - mutex_init (&s->mutex); + memset(s, 0, sizeof(dabusb_t)); + mutex_init(&s->mutex); s->usbdev = NULL; s->total_buffer_size = buffers; - init_waitqueue_head (&s->wait); - init_waitqueue_head (&s->remove_ok); - spin_lock_init (&s->lock); - INIT_LIST_HEAD (&s->free_buff_list); - INIT_LIST_HEAD (&s->rec_buff_list); + init_waitqueue_head(&s->wait); + init_waitqueue_head(&s->remove_ok); + spin_lock_init(&s->lock); + INIT_LIST_HEAD(&s->free_buff_list); + INIT_LIST_HEAD(&s->rec_buff_list); } /* register misc device */ @@ -890,25 +902,25 @@ out: return retval; } -static void __exit dabusb_cleanup (void) +static void __exit dabusb_cleanup(void) { dbg("dabusb_cleanup"); - usb_deregister (&dabusb_driver); + usb_deregister(&dabusb_driver); } /* --------------------------------------------------------------------- */ -MODULE_AUTHOR( DRIVER_AUTHOR ); -MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); MODULE_FIRMWARE("dabusb/firmware.fw"); MODULE_FIRMWARE("dabusb/bitstream.bin"); module_param(buffers, int, 0); -MODULE_PARM_DESC (buffers, "Number of buffers (default=256)"); +MODULE_PARM_DESC(buffers, "Number of buffers (default=256)"); -module_init (dabusb_init); -module_exit (dabusb_cleanup); +module_init(dabusb_init); +module_exit(dabusb_cleanup); /* --------------------------------------------------------------------- */ diff --git a/drivers/staging/dabusb/dabusb.h b/drivers/staging/dabusb/dabusb.h index 00eb34c863eb..c1772efe7c2c 100644 --- a/drivers/staging/dabusb/dabusb.h +++ b/drivers/staging/dabusb/dabusb.h @@ -1,10 +1,9 @@ #define _BULK_DATA_LEN 64 -typedef struct -{ +typedef struct { unsigned char data[_BULK_DATA_LEN]; unsigned int size; unsigned int pipe; -}bulk_transfer_t,*pbulk_transfer_t; +} bulk_transfer_t, *pbulk_transfer_t; #define DABUSB_MINOR 240 /* some unassigned USB minor */ #define DABUSB_VERSION 0x1000 @@ -14,10 +13,9 @@ typedef struct #ifdef __KERNEL__ -typedef enum { _stopped=0, _started } driver_state_t; +typedef enum { _stopped = 0, _started } driver_state_t; -typedef struct -{ +typedef struct { struct mutex mutex; struct usb_device *usbdev; wait_queue_head_t wait; @@ -34,17 +32,15 @@ typedef struct int devnum; struct list_head free_buff_list; struct list_head rec_buff_list; -} dabusb_t,*pdabusb_t; +} dabusb_t, *pdabusb_t; -typedef struct -{ +typedef struct { pdabusb_t s; struct urb *purb; struct list_head buff_list; -} buff_t,*pbuff_t; +} buff_t, *pbuff_t; -typedef struct -{ +typedef struct { wait_queue_head_t wait; } bulk_completion_context_t, *pbulk_completion_context_t; @@ -54,11 +50,11 @@ typedef struct #define _ISOPIPESIZE 16384 #define _BULK_DATA_LEN 64 -// Vendor specific request code for Anchor Upload/Download -// This one is implemented in the core +/* Vendor specific request code for Anchor Upload/Download + *This one is implemented in the core */ #define ANCHOR_LOAD_INTERNAL 0xA0 -// EZ-USB Control and Status Register. Bit 0 controls 8051 reset +/* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */ #define CPUCS_REG 0x7F92 #define _TOTAL_BUFFERS 384 @@ -67,19 +63,18 @@ typedef struct #ifndef _BYTE_DEFINED #define _BYTE_DEFINED typedef unsigned char BYTE; -#endif // !_BYTE_DEFINED +#endif /* !_BYTE_DEFINED */ #ifndef _WORD_DEFINED #define _WORD_DEFINED typedef unsigned short WORD; -#endif // !_WORD_DEFINED +#endif /* !_WORD_DEFINED */ -typedef struct _INTEL_HEX_RECORD -{ - BYTE Length; - WORD Address; - BYTE Type; - BYTE Data[MAX_INTEL_HEX_RECORD_LENGTH]; +typedef struct _INTEL_HEX_RECORD { + BYTE Length; + WORD Address; + BYTE Type; + BYTE Data[MAX_INTEL_HEX_RECORD_LENGTH]; } INTEL_HEX_RECORD, *PINTEL_HEX_RECORD; #endif -- cgit v1.2.3 From 826514b4ee347bf683f043e0900590cfac4d6da5 Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Sat, 29 Jan 2011 16:36:46 +0100 Subject: Staging: iio: max517.c: Fix client obtainment by using iio_dev_get_devdata() max517.c: Fix client obtainment by using iio_dev_get_devdata() This patch uses dev_get_drvdata() and iio_dev_get_devdata() instead of to_i2c_client() (broken!) to obtain i2c_client data. Further, some minor typo fixes are included. Signed-off-by: Roland Stigge Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/max517.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/dac/max517.c b/drivers/staging/iio/dac/max517.c index 4974e70f66a0..7071f713604a 100644 --- a/drivers/staging/iio/dac/max517.c +++ b/drivers/staging/iio/dac/max517.c @@ -45,6 +45,7 @@ enum max517_device_ids { struct max517_data { struct iio_dev *indio_dev; + struct i2c_client *client; unsigned short vref_mv[2]; }; @@ -57,7 +58,9 @@ static ssize_t max517_set_value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count, int channel) { - struct i2c_client *client = to_i2c_client(dev); + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct max517_data *data = iio_dev_get_devdata(dev_info); + struct i2c_client *client = data->client; u8 outbuf[4]; /* 1x or 2x command + value */ int outbuf_size = 0; int res; @@ -147,7 +150,7 @@ static ssize_t max517_show_scale2(struct device *dev, } static IIO_DEVICE_ATTR(out2_scale, S_IRUGO, max517_show_scale2, NULL, 0); -/* On MAX517 variant, we have two outputs */ +/* On MAX517 variant, we have one output */ static struct attribute *max517_attributes[] = { &iio_dev_attr_out1_raw.dev_attr.attr, &iio_dev_attr_out1_scale.dev_attr.attr, @@ -158,7 +161,7 @@ static struct attribute_group max517_attribute_group = { .attrs = max517_attributes, }; -/* On MAX518 and MAX518 variant, we have two outputs */ +/* On MAX518 and MAX519 variant, we have two outputs */ static struct attribute *max518_attributes[] = { &iio_dev_attr_out1_raw.dev_attr.attr, &iio_dev_attr_out1_scale.dev_attr.attr, @@ -201,6 +204,8 @@ static int max517_probe(struct i2c_client *client, i2c_set_clientdata(client, data); + data->client = client; + data->indio_dev = iio_allocate_device(); if (data->indio_dev == NULL) { err = -ENOMEM; -- cgit v1.2.3 From ae639830fe6299d67407ca63f43bb28ea781684a Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Sat, 29 Jan 2011 16:27:17 +0100 Subject: Staging: iio: ad7476_core.c: Fixed i2c -> spi documentation typo ad7476_core.c: Fixed i2c -> spi documentation typo Minor documentation fix in comment Signed-off-by: Roland Stigge Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/ad7476_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c index deb68c8a6e18..4708b8e954f3 100644 --- a/drivers/staging/iio/adc/ad7476_core.c +++ b/drivers/staging/iio/adc/ad7476_core.c @@ -190,7 +190,7 @@ static int __devinit ad7476_probe(struct spi_device *spi) goto error_disable_reg; } - /* Estabilish that the iio_dev is a child of the i2c device */ + /* Establish that the iio_dev is a child of the spi device */ st->indio_dev->dev.parent = &spi->dev; st->indio_dev->attrs = &ad7476_attribute_group; st->indio_dev->dev_data = (void *)(st); -- cgit v1.2.3 From e80528b78e8d33494a0784dc214e71a728162d92 Mon Sep 17 00:00:00 2001 From: Adam Thompson Date: Sat, 29 Jan 2011 02:08:50 -0500 Subject: Staging: wlan-ng: fix 2 space coding style issues This patch to p80211conv.c fixes to space coding style warnings found with checkpatch.pl Signed-off-by: Adam Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211conv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c index 146f3651b6f2..f53a27a2e3fe 100644 --- a/drivers/staging/wlan-ng/p80211conv.c +++ b/drivers/staging/wlan-ng/p80211conv.c @@ -379,7 +379,7 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv, } else if ((payload_length >= sizeof(struct wlan_llc) + sizeof(struct wlan_snap)) - &&(e_llc->dsap == 0xaa) + && (e_llc->dsap == 0xaa) && (e_llc->ssap == 0xaa) && (e_llc->ctl == 0x03) && @@ -415,7 +415,7 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv, } else if ((payload_length >= sizeof(struct wlan_llc) + sizeof(struct wlan_snap)) - &&(e_llc->dsap == 0xaa) + && (e_llc->dsap == 0xaa) && (e_llc->ssap == 0xaa) && (e_llc->ctl == 0x03)) { pr_debug("802.1h/RFC1042 len: %d\n", payload_length); -- cgit v1.2.3 From bc8bf90a643123f99f98027040f7256ce79b45da Mon Sep 17 00:00:00 2001 From: Nick Robinson Date: Mon, 31 Jan 2011 10:56:50 -0600 Subject: Staging: comedi: Fix checpatch.pl issues in file rtd520.c This patch fixes the checkpatch errors listed below: ERROR: code indent should use tabs where possible WARNING: space prohibited between function name and open parenthesis '(' WARNING: please, no spaces at the start of a line WARNING: braces {} are not necessary for single statement blocks WARNING: printk() should include KERN_ facility level Signed-off-by: Nick Robinson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 321 ++++++++++++++++---------------- 1 file changed, 157 insertions(+), 164 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index aa8aeeee043f..357858d27441 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -59,7 +59,7 @@ Configuration options: Data sheet: http://www.rtdusa.com/pdf/dm7520.pdf Example source: http://www.rtdusa.com/examples/dm/dm7520.zip Call them and ask for the register level manual. - PCI chip: http://www.plxtech.com/products/io/pci9080 + PCI chip: http://www.plxtech.com/products/io/pci9080 Notes: This board is memory mapped. There is some IO stuff, but it isn't needed. @@ -136,7 +136,7 @@ Configuration options: #define RTD_DMA_TIMEOUT 33000 /* 1 msec */ #else /* by delaying, power and electrical noise are reduced somewhat */ -#define WAIT_QUIETLY udelay (1) +#define WAIT_QUIETLY udelay(1) #define RTD_ADC_TIMEOUT 2000 /* in usec */ #define RTD_DAC_TIMEOUT 2000 /* in usec */ #define RTD_DMA_TIMEOUT 1000 /* in usec */ @@ -414,296 +414,296 @@ struct rtdPrivate { /* Reset board */ #define RtdResetBoard(dev) \ - writel (0, devpriv->las0+LAS0_BOARD_RESET) + writel(0, devpriv->las0+LAS0_BOARD_RESET) /* Reset channel gain table read pointer */ #define RtdResetCGT(dev) \ - writel (0, devpriv->las0+LAS0_CGT_RESET) + writel(0, devpriv->las0+LAS0_CGT_RESET) /* Reset channel gain table read and write pointers */ #define RtdClearCGT(dev) \ - writel (0, devpriv->las0+LAS0_CGT_CLEAR) + writel(0, devpriv->las0+LAS0_CGT_CLEAR) /* Reset channel gain table read and write pointers */ #define RtdEnableCGT(dev, v) \ - writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_CGT_ENABLE) + writel((v > 0) ? 1 : 0, devpriv->las0+LAS0_CGT_ENABLE) /* Write channel gain table entry */ #define RtdWriteCGTable(dev, v) \ - writel (v, devpriv->las0+LAS0_CGT_WRITE) + writel(v, devpriv->las0+LAS0_CGT_WRITE) /* Write Channel Gain Latch */ #define RtdWriteCGLatch(dev, v) \ - writel (v, devpriv->las0+LAS0_CGL_WRITE) + writel(v, devpriv->las0+LAS0_CGL_WRITE) /* Reset ADC FIFO */ #define RtdAdcClearFifo(dev) \ - writel (0, devpriv->las0+LAS0_ADC_FIFO_CLEAR) + writel(0, devpriv->las0+LAS0_ADC_FIFO_CLEAR) /* Set ADC start conversion source select (write only) */ #define RtdAdcConversionSource(dev, v) \ - writel (v, devpriv->las0+LAS0_ADC_CONVERSION) + writel(v, devpriv->las0+LAS0_ADC_CONVERSION) /* Set burst start source select (write only) */ #define RtdBurstStartSource(dev, v) \ - writel (v, devpriv->las0+LAS0_BURST_START) + writel(v, devpriv->las0+LAS0_BURST_START) /* Set Pacer start source select (write only) */ #define RtdPacerStartSource(dev, v) \ - writel (v, devpriv->las0+LAS0_PACER_START) + writel(v, devpriv->las0+LAS0_PACER_START) /* Set Pacer stop source select (write only) */ #define RtdPacerStopSource(dev, v) \ - writel (v, devpriv->las0+LAS0_PACER_STOP) + writel(v, devpriv->las0+LAS0_PACER_STOP) /* Set Pacer clock source select (write only) 0=external 1=internal */ #define RtdPacerClockSource(dev, v) \ - writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_PACER_SELECT) + writel((v > 0) ? 1 : 0, devpriv->las0+LAS0_PACER_SELECT) /* Set sample counter source select (write only) */ #define RtdAdcSampleCounterSource(dev, v) \ - writel (v, devpriv->las0+LAS0_ADC_SCNT_SRC) + writel(v, devpriv->las0+LAS0_ADC_SCNT_SRC) /* Set Pacer trigger mode select (write only) 0=single cycle, 1=repeat */ #define RtdPacerTriggerMode(dev, v) \ - writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_PACER_REPEAT) + writel((v > 0) ? 1 : 0, devpriv->las0+LAS0_PACER_REPEAT) /* Set About counter stop enable (write only) */ #define RtdAboutStopEnable(dev, v) \ - writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_ACNT_STOP_ENABLE) + writel((v > 0) ? 1 : 0, devpriv->las0+LAS0_ACNT_STOP_ENABLE) /* Set external trigger polarity (write only) 0=positive edge, 1=negative */ #define RtdTriggerPolarity(dev, v) \ - writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_ETRG_POLARITY) + writel((v > 0) ? 1 : 0, devpriv->las0+LAS0_ETRG_POLARITY) /* Start single ADC conversion */ #define RtdAdcStart(dev) \ - writew (0, devpriv->las0+LAS0_ADC) + writew(0, devpriv->las0+LAS0_ADC) /* Read one ADC data value (12bit (with sign extend) as 16bit) */ /* Note: matches what DMA would get. Actual value >> 3 */ #define RtdAdcFifoGet(dev) \ - readw (devpriv->las1+LAS1_ADC_FIFO) + readw(devpriv->las1+LAS1_ADC_FIFO) /* Read two ADC data values (DOESNT WORK) */ #define RtdAdcFifoGet2(dev) \ - readl (devpriv->las1+LAS1_ADC_FIFO) + readl(devpriv->las1+LAS1_ADC_FIFO) /* FIFO status */ #define RtdFifoStatus(dev) \ - readl (devpriv->las0+LAS0_ADC) + readl(devpriv->las0+LAS0_ADC) /* pacer start/stop read=start, write=stop*/ #define RtdPacerStart(dev) \ - readl (devpriv->las0+LAS0_PACER) + readl(devpriv->las0+LAS0_PACER) #define RtdPacerStop(dev) \ - writel (0, devpriv->las0+LAS0_PACER) + writel(0, devpriv->las0+LAS0_PACER) /* Interrupt status */ #define RtdInterruptStatus(dev) \ - readw (devpriv->las0+LAS0_IT) + readw(devpriv->las0+LAS0_IT) /* Interrupt mask */ #define RtdInterruptMask(dev, v) \ - writew ((devpriv->intMask = (v)), devpriv->las0+LAS0_IT) + writew((devpriv->intMask = (v)), devpriv->las0+LAS0_IT) /* Interrupt status clear (only bits set in mask) */ #define RtdInterruptClear(dev) \ - readw (devpriv->las0+LAS0_CLEAR) + readw(devpriv->las0+LAS0_CLEAR) /* Interrupt clear mask */ #define RtdInterruptClearMask(dev, v) \ - writew ((devpriv->intClearMask = (v)), devpriv->las0+LAS0_CLEAR) + writew((devpriv->intClearMask = (v)), devpriv->las0+LAS0_CLEAR) /* Interrupt overrun status */ #define RtdInterruptOverrunStatus(dev) \ - readl (devpriv->las0+LAS0_OVERRUN) + readl(devpriv->las0+LAS0_OVERRUN) /* Interrupt overrun clear */ #define RtdInterruptOverrunClear(dev) \ - writel (0, devpriv->las0+LAS0_OVERRUN) + writel(0, devpriv->las0+LAS0_OVERRUN) /* Pacer counter, 24bit */ #define RtdPacerCount(dev) \ - readl (devpriv->las0+LAS0_PCLK) + readl(devpriv->las0+LAS0_PCLK) #define RtdPacerCounter(dev, v) \ - writel ((v) & 0xffffff, devpriv->las0+LAS0_PCLK) + writel((v) & 0xffffff, devpriv->las0+LAS0_PCLK) /* Burst counter, 10bit */ #define RtdBurstCount(dev) \ - readl (devpriv->las0+LAS0_BCLK) + readl(devpriv->las0+LAS0_BCLK) #define RtdBurstCounter(dev, v) \ - writel ((v) & 0x3ff, devpriv->las0+LAS0_BCLK) + writel((v) & 0x3ff, devpriv->las0+LAS0_BCLK) /* Delay counter, 16bit */ #define RtdDelayCount(dev) \ - readl (devpriv->las0+LAS0_DCLK) + readl(devpriv->las0+LAS0_DCLK) #define RtdDelayCounter(dev, v) \ - writel ((v) & 0xffff, devpriv->las0+LAS0_DCLK) + writel((v) & 0xffff, devpriv->las0+LAS0_DCLK) /* About counter, 16bit */ #define RtdAboutCount(dev) \ - readl (devpriv->las0+LAS0_ACNT) + readl(devpriv->las0+LAS0_ACNT) #define RtdAboutCounter(dev, v) \ - writel ((v) & 0xffff, devpriv->las0+LAS0_ACNT) + writel((v) & 0xffff, devpriv->las0+LAS0_ACNT) /* ADC sample counter, 10bit */ #define RtdAdcSampleCount(dev) \ - readl (devpriv->las0+LAS0_ADC_SCNT) + readl(devpriv->las0+LAS0_ADC_SCNT) #define RtdAdcSampleCounter(dev, v) \ - writel ((v) & 0x3ff, devpriv->las0+LAS0_ADC_SCNT) + writel((v) & 0x3ff, devpriv->las0+LAS0_ADC_SCNT) /* User Timer/Counter (8254) */ #define RtdUtcCounterGet(dev, n) \ - readb (devpriv->las0 \ - + ((n <= 0) ? LAS0_UTC0 : ((1 == n) ? LAS0_UTC1 : LAS0_UTC2))) + readb(devpriv->las0 \ + + ((n <= 0) ? LAS0_UTC0 : ((1 == n) ? LAS0_UTC1 : LAS0_UTC2))) #define RtdUtcCounterPut(dev, n, v) \ - writeb ((v) & 0xff, devpriv->las0 \ - + ((n <= 0) ? LAS0_UTC0 : ((1 == n) ? LAS0_UTC1 : LAS0_UTC2))) + writeb((v) & 0xff, devpriv->las0 \ + + ((n <= 0) ? LAS0_UTC0 : ((1 == n) ? LAS0_UTC1 : LAS0_UTC2))) /* Set UTC (8254) control byte */ #define RtdUtcCtrlPut(dev, n, v) \ - writeb (devpriv->utcCtrl[(n) & 3] = (((n) & 3) << 6) | ((v) & 0x3f), \ - devpriv->las0 + LAS0_UTC_CTRL) + writeb(devpriv->utcCtrl[(n) & 3] = (((n) & 3) << 6) | ((v) & 0x3f), \ + devpriv->las0 + LAS0_UTC_CTRL) /* Set UTCn clock source (write only) */ #define RtdUtcClockSource(dev, n, v) \ - writew (v, devpriv->las0 \ - + ((n <= 0) ? LAS0_UTC0_CLOCK : \ - ((1 == n) ? LAS0_UTC1_CLOCK : LAS0_UTC2_CLOCK))) + writew(v, devpriv->las0 \ + + ((n <= 0) ? LAS0_UTC0_CLOCK : \ + ((1 == n) ? LAS0_UTC1_CLOCK : LAS0_UTC2_CLOCK))) /* Set UTCn gate source (write only) */ #define RtdUtcGateSource(dev, n, v) \ - writew (v, devpriv->las0 \ - + ((n <= 0) ? LAS0_UTC0_GATE : \ - ((1 == n) ? LAS0_UTC1_GATE : LAS0_UTC2_GATE))) + writew(v, devpriv->las0 \ + + ((n <= 0) ? LAS0_UTC0_GATE : \ + ((1 == n) ? LAS0_UTC1_GATE : LAS0_UTC2_GATE))) /* User output N source select (write only) */ #define RtdUsrOutSource(dev, n, v) \ - writel (v, devpriv->las0+((n <= 0) ? LAS0_UOUT0_SELECT : LAS0_UOUT1_SELECT)) + writel(v, devpriv->las0+((n <= 0) ? LAS0_UOUT0_SELECT : LAS0_UOUT1_SELECT)) /* Digital IO */ #define RtdDio0Read(dev) \ - (readw (devpriv->las0+LAS0_DIO0) & 0xff) + (readw(devpriv->las0+LAS0_DIO0) & 0xff) #define RtdDio0Write(dev, v) \ - writew ((v) & 0xff, devpriv->las0+LAS0_DIO0) + writew((v) & 0xff, devpriv->las0+LAS0_DIO0) #define RtdDio1Read(dev) \ - (readw (devpriv->las0+LAS0_DIO1) & 0xff) + (readw(devpriv->las0+LAS0_DIO1) & 0xff) #define RtdDio1Write(dev, v) \ - writew ((v) & 0xff, devpriv->las0+LAS0_DIO1) + writew((v) & 0xff, devpriv->las0+LAS0_DIO1) #define RtdDioStatusRead(dev) \ - (readw (devpriv->las0+LAS0_DIO_STATUS) & 0xff) + (readw(devpriv->las0+LAS0_DIO_STATUS) & 0xff) #define RtdDioStatusWrite(dev, v) \ - writew ((devpriv->dioStatus = (v)), devpriv->las0+LAS0_DIO_STATUS) + writew((devpriv->dioStatus = (v)), devpriv->las0+LAS0_DIO_STATUS) #define RtdDio0CtrlRead(dev) \ - (readw (devpriv->las0+LAS0_DIO0_CTRL) & 0xff) + (readw(devpriv->las0+LAS0_DIO0_CTRL) & 0xff) #define RtdDio0CtrlWrite(dev, v) \ - writew ((v) & 0xff, devpriv->las0+LAS0_DIO0_CTRL) + writew((v) & 0xff, devpriv->las0+LAS0_DIO0_CTRL) /* Digital to Analog converter */ /* Write one data value (sign + 12bit + marker bits) */ /* Note: matches what DMA would put. Actual value << 3 */ #define RtdDacFifoPut(dev, n, v) \ - writew ((v), devpriv->las1 +(((n) == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO)) + writew((v), devpriv->las1 + (((n) == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO)) /* Start single DAC conversion */ #define RtdDacUpdate(dev, n) \ - writew (0, devpriv->las0 +(((n) == 0) ? LAS0_DAC1 : LAS0_DAC2)) + writew(0, devpriv->las0 + (((n) == 0) ? LAS0_DAC1 : LAS0_DAC2)) /* Start single DAC conversion on both DACs */ #define RtdDacBothUpdate(dev) \ - writew (0, devpriv->las0+LAS0_DAC) + writew(0, devpriv->las0+LAS0_DAC) /* Set DAC output type and range */ #define RtdDacRange(dev, n, v) \ - writew ((v) & 7, devpriv->las0 \ - +(((n) == 0) ? LAS0_DAC1_CTRL : LAS0_DAC2_CTRL)) + writew((v) & 7, devpriv->las0 \ + +(((n) == 0) ? LAS0_DAC1_CTRL : LAS0_DAC2_CTRL)) /* Reset DAC FIFO */ #define RtdDacClearFifo(dev, n) \ - writel (0, devpriv->las0+(((n) == 0) ? LAS0_DAC1_RESET : LAS0_DAC2_RESET)) + writel(0, devpriv->las0+(((n) == 0) ? LAS0_DAC1_RESET : LAS0_DAC2_RESET)) /* Set source for DMA 0 (write only, shadow?) */ #define RtdDma0Source(dev, n) \ - writel ((n) & 0xf, devpriv->las0+LAS0_DMA0_SRC) + writel((n) & 0xf, devpriv->las0+LAS0_DMA0_SRC) /* Set source for DMA 1 (write only, shadow?) */ #define RtdDma1Source(dev, n) \ - writel ((n) & 0xf, devpriv->las0+LAS0_DMA1_SRC) + writel((n) & 0xf, devpriv->las0+LAS0_DMA1_SRC) /* Reset board state for DMA 0 */ #define RtdDma0Reset(dev) \ - writel (0, devpriv->las0+LAS0_DMA0_RESET) + writel(0, devpriv->las0+LAS0_DMA0_RESET) /* Reset board state for DMA 1 */ #define RtdDma1Reset(dev) \ - writel (0, devpriv->las0+LAS0_DMA1_SRC) + writel(0, devpriv->las0+LAS0_DMA1_SRC) /* PLX9080 interrupt mask and status */ #define RtdPlxInterruptRead(dev) \ - readl (devpriv->lcfg+LCFG_ITCSR) + readl(devpriv->lcfg+LCFG_ITCSR) #define RtdPlxInterruptWrite(dev, v) \ - writel (v, devpriv->lcfg+LCFG_ITCSR) + writel(v, devpriv->lcfg+LCFG_ITCSR) /* Set mode for DMA 0 */ #define RtdDma0Mode(dev, m) \ - writel ((m), devpriv->lcfg+LCFG_DMAMODE0) + writel((m), devpriv->lcfg+LCFG_DMAMODE0) /* Set PCI address for DMA 0 */ #define RtdDma0PciAddr(dev, a) \ - writel ((a), devpriv->lcfg+LCFG_DMAPADR0) + writel((a), devpriv->lcfg+LCFG_DMAPADR0) /* Set local address for DMA 0 */ #define RtdDma0LocalAddr(dev, a) \ - writel ((a), devpriv->lcfg+LCFG_DMALADR0) + writel((a), devpriv->lcfg+LCFG_DMALADR0) /* Set byte count for DMA 0 */ #define RtdDma0Count(dev, c) \ - writel ((c), devpriv->lcfg+LCFG_DMASIZ0) + writel((c), devpriv->lcfg+LCFG_DMASIZ0) /* Set next descriptor for DMA 0 */ #define RtdDma0Next(dev, a) \ - writel ((a), devpriv->lcfg+LCFG_DMADPR0) + writel((a), devpriv->lcfg+LCFG_DMADPR0) /* Set mode for DMA 1 */ #define RtdDma1Mode(dev, m) \ - writel ((m), devpriv->lcfg+LCFG_DMAMODE1) + writel((m), devpriv->lcfg+LCFG_DMAMODE1) /* Set PCI address for DMA 1 */ #define RtdDma1PciAddr(dev, a) \ - writel ((a), devpriv->lcfg+LCFG_DMAADR1) + writel((a), devpriv->lcfg+LCFG_DMAADR1) /* Set local address for DMA 1 */ #define RtdDma1LocalAddr(dev, a) \ - writel ((a), devpriv->lcfg+LCFG_DMALADR1) + writel((a), devpriv->lcfg+LCFG_DMALADR1) /* Set byte count for DMA 1 */ #define RtdDma1Count(dev, c) \ - writel ((c), devpriv->lcfg+LCFG_DMASIZ1) + writel((c), devpriv->lcfg+LCFG_DMASIZ1) /* Set next descriptor for DMA 1 */ #define RtdDma1Next(dev, a) \ - writel ((a), devpriv->lcfg+LCFG_DMADPR1) + writel((a), devpriv->lcfg+LCFG_DMADPR1) /* Set control for DMA 0 (write only, shadow?) */ #define RtdDma0Control(dev, n) \ - writeb (devpriv->dma0Control = (n), devpriv->lcfg+LCFG_DMACSR0) + writeb(devpriv->dma0Control = (n), devpriv->lcfg+LCFG_DMACSR0) /* Get status for DMA 0 */ #define RtdDma0Status(dev) \ - readb (devpriv->lcfg+LCFG_DMACSR0) + readb(devpriv->lcfg+LCFG_DMACSR0) /* Set control for DMA 1 (write only, shadow?) */ #define RtdDma1Control(dev, n) \ - writeb (devpriv->dma1Control = (n), devpriv->lcfg+LCFG_DMACSR1) + writeb(devpriv->dma1Control = (n), devpriv->lcfg+LCFG_DMACSR1) /* Get status for DMA 1 */ #define RtdDma1Status(dev) \ - readb (devpriv->lcfg+LCFG_DMACSR1) + readb(devpriv->lcfg+LCFG_DMACSR1) /* * The struct comedi_driver structure tells the Comedi core module @@ -760,9 +760,9 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) int index; #endif - printk("comedi%d: rtd520 attaching.\n", dev->minor); + printk(KERN_INFO "comedi%d: rtd520 attaching.\n", dev->minor); -#if defined (CONFIG_COMEDI_DEBUG) && defined (USE_DMA) +#if defined(CONFIG_COMEDI_DEBUG) && defined(USE_DMA) /* You can set this a load time: modprobe comedi comedi_debug=1 */ if (0 == comedi_debug) /* force DMA debug printks */ comedi_debug = 1; @@ -800,10 +800,10 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) } if (!pcidev) { if (it->options[0] && it->options[1]) { - printk("No RTD card at bus=%d slot=%d.\n", + printk(KERN_INFO "No RTD card at bus=%d slot=%d.\n", it->options[0], it->options[1]); } else { - printk("No RTD card found.\n"); + printk(KERN_INFO "No RTD card found.\n"); } return -EIO; } @@ -812,7 +812,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) ret = comedi_pci_enable(pcidev, DRV_NAME); if (ret < 0) { - printk("Failed to enable PCI device and request regions.\n"); + printk(KERN_INFO "Failed to enable PCI device and request regions.\n"); return ret; } devpriv->got_regions = 1; @@ -830,9 +830,9 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->las1 = ioremap_nocache(physLas1, LAS1_PCISIZE); devpriv->lcfg = ioremap_nocache(physLcfg, LCFG_PCISIZE); - if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg) { + if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg) return -ENOMEM; - } + DPRINTK("%s: LAS0=%llx, LAS1=%llx, CFG=%llx.\n", dev->board_name, (unsigned long long)physLas0, (unsigned long long)physLas1, @@ -849,7 +849,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) pci_read_config_byte(devpriv->pci_dev, PCI_LATENCY_TIMER, &pci_latency); if (pci_latency < 32) { - printk("%s: PCI latency changed from %d to %d\n", + printk(KERN_INFO "%s: PCI latency changed from %d to %d\n", dev->board_name, pci_latency, 32); pci_write_config_byte(devpriv->pci_dev, PCI_LATENCY_TIMER, 32); @@ -875,9 +875,9 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) * Allocate the subdevice structures. alloc_subdevice() is a * convenient macro defined in comedidev.h. */ - if (alloc_subdevices(dev, 4) < 0) { + if (alloc_subdevices(dev, 4) < 0) return -ENOMEM; - } + s = dev->subdevices + 0; dev->read_subdev = s; @@ -887,11 +887,11 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF | SDF_CMD_READ; s->n_chan = thisboard->aiChans; s->maxdata = (1 << thisboard->aiBits) - 1; - if (thisboard->aiMaxGain <= 32) { + if (thisboard->aiMaxGain <= 32) s->range_table = &rtd_ai_7520_range; - } else { + else s->range_table = &rtd_ai_4520_range; - } + s->len_chanlist = RTD_MAX_CHANLIST; /* devpriv->fifoLen */ s->insn_read = rtd_ai_rinsn; s->do_cmd = rtd_ai_cmd; @@ -961,9 +961,9 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk("( irq=%u )", dev->irq); ret = rtd520_probe_fifo_depth(dev); - if (ret < 0) { + if (ret < 0) return ret; - } + devpriv->fifoLen = ret; printk("( fifoLen=%d )", devpriv->fifoLen); @@ -1028,7 +1028,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) RtdDma0Mode(dev, DMA_MODE_BITS); RtdDma0Source(dev, DMAS_ADFIFO_HALF_FULL); /* set DMA trigger source */ } else { - printk("( no IRQ->no DMA )"); + printk(KERN_INFO "( no IRQ->no DMA )"); } #endif /* USE_DMA */ @@ -1071,18 +1071,18 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* release all regions that were allocated */ - if (devpriv->las0) { + if (devpriv->las0) iounmap(devpriv->las0); - } - if (devpriv->las1) { + + if (devpriv->las1) iounmap(devpriv->las1); - } - if (devpriv->lcfg) { + + if (devpriv->lcfg) iounmap(devpriv->lcfg); - } - if (devpriv->pci_dev) { + + if (devpriv->pci_dev) pci_dev_put(devpriv->pci_dev); - } + return ret; #endif } @@ -1158,24 +1158,24 @@ static int rtd_detach(struct comedi_device *dev) } /* release all regions that were allocated */ - if (devpriv->las0) { + if (devpriv->las0) iounmap(devpriv->las0); - } - if (devpriv->las1) { + + if (devpriv->las1) iounmap(devpriv->las1); - } - if (devpriv->lcfg) { + + if (devpriv->lcfg) iounmap(devpriv->lcfg); - } + if (devpriv->pci_dev) { - if (devpriv->got_regions) { + if (devpriv->got_regions) comedi_pci_disable(devpriv->pci_dev); - } + pci_dev_put(devpriv->pci_dev); } } - printk("comedi%d: rtd520: removed.\n", dev->minor); + printk(KERN_INFO "comedi%d: rtd520: removed.\n", dev->minor); return 0; } @@ -1275,13 +1275,13 @@ static int rtd520_probe_fifo_depth(struct comedi_device *dev) } } if (i == limit) { - printk("\ncomedi: %s: failed to probe fifo size.\n", DRV_NAME); + printk(KERN_INFO "\ncomedi: %s: failed to probe fifo size.\n", DRV_NAME); return -EIO; } RtdAdcClearFifo(dev); if (fifo_size != 0x400 && fifo_size != 0x2000) { printk - ("\ncomedi: %s: unexpected fifo size of %i, expected 1024 or 8192.\n", + (KERN_INFO "\ncomedi: %s: unexpected fifo size of %i, expected 1024 or 8192.\n", DRV_NAME, fifo_size); return -EIO; } @@ -1335,11 +1335,10 @@ static int rtd_ai_rinsn(struct comedi_device *dev, d = RtdAdcFifoGet(dev); /* get 2s comp value */ /*printk ("rtd520: Got 0x%x after %d usec\n", d, ii+1); */ d = d >> 3; /* low 3 bits are marker lines */ - if (CHAN_ARRAY_TEST(devpriv->chanBipolar, 0)) { + if (CHAN_ARRAY_TEST(devpriv->chanBipolar, 0)) data[n] = d + 2048; /* convert to comedi unsigned data */ - } else { + else data[n] = d; - } } /* return the number of samples read/written */ @@ -1375,11 +1374,11 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, d = RtdAdcFifoGet(dev); /* get 2s comp value */ d = d >> 3; /* low 3 bits are marker lines */ - if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) { + if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) sample = d + 2048; /* convert to comedi unsigned data */ - } else { + else sample = d; - } + if (!comedi_buf_put(s->async, sample)) return -1; @@ -1403,11 +1402,11 @@ static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s) } d = d >> 3; /* low 3 bits are marker lines */ - if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) { + if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) sample = d + 2048; /* convert to comedi unsigned data */ - } else { + else sample = d; - } + if (!comedi_buf_put(s->async, sample)) return -1; @@ -1493,9 +1492,9 @@ static int ai_process_dma(struct comedi_device *dev, struct comedi_subdevice *s) if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) { sample = (*dp >> 3) + 2048; /* convert to comedi unsigned data */ - } else { + else sample = *dp >> 3; /* low 3 bits are marker lines */ - } + *dp++ = sample; /* put processed value back */ if (++s->async->cur_chan >= s->async->cmd.chanlist_len) @@ -1546,9 +1545,8 @@ static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */ u16 fifoStatus; struct comedi_subdevice *s = dev->subdevices + 0; /* analog in subdevice */ - if (!dev->attached) { + if (!dev->attached) return IRQ_NONE; - } devpriv->intCount++; /* DEBUG statistics */ @@ -1594,9 +1592,8 @@ static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */ status = RtdInterruptStatus(dev); /* if interrupt was not caused by our board, or handled above */ - if (0 == status) { + if (0 == status) return IRQ_HANDLED; - } if (status & IRQM_ADC_ABOUT_CNT) { /* sample count -> read FIFO */ /* since the priority interrupt controller may have queued a sample @@ -1734,33 +1731,32 @@ static int rtd_ai_cmdtest(struct comedi_device *dev, tmp = cmd->start_src; cmd->start_src &= TRIG_NOW; - if (!cmd->start_src || tmp != cmd->start_src) { + if (!cmd->start_src || tmp != cmd->start_src) err++; - } tmp = cmd->scan_begin_src; cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) { + if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) err++; - } + tmp = cmd->convert_src; cmd->convert_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->convert_src || tmp != cmd->convert_src) { + if (!cmd->convert_src || tmp != cmd->convert_src) err++; - } + tmp = cmd->scan_end_src; cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) { + if (!cmd->scan_end_src || tmp != cmd->scan_end_src) err++; - } + tmp = cmd->stop_src; cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) { + if (!cmd->stop_src || tmp != cmd->stop_src) err++; - } + if (err) return 1; @@ -1772,16 +1768,14 @@ static int rtd_ai_cmdtest(struct comedi_device *dev, cmd->scan_begin_src != TRIG_EXT) { err++; } - if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) { + if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) err++; - } - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) { + + if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) err++; - } - if (err) { + if (err) return 2; - } /* step 3: make sure arguments are trivially compatible */ @@ -1882,9 +1876,9 @@ static int rtd_ai_cmdtest(struct comedi_device *dev, } } - if (err) { + if (err) return 3; - } + /* step 4: fix up any arguments */ @@ -1896,17 +1890,17 @@ static int rtd_ai_cmdtest(struct comedi_device *dev, tmp = cmd->scan_begin_arg; rtd_ns_to_timer(&cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK); - if (tmp != cmd->scan_begin_arg) { + if (tmp != cmd->scan_begin_arg) err++; - } + } if (cmd->convert_src == TRIG_TIMER) { tmp = cmd->convert_arg; rtd_ns_to_timer(&cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK); - if (tmp != cmd->convert_arg) { + if (tmp != cmd->convert_arg) err++; - } + if (cmd->scan_begin_src == TRIG_TIMER && (cmd->scan_begin_arg < (cmd->convert_arg * cmd->scan_end_arg))) { @@ -1916,9 +1910,8 @@ static int rtd_ai_cmdtest(struct comedi_device *dev, } } - if (err) { + if (err) return 4; - } return 0; } @@ -2221,7 +2214,7 @@ static int rtd_ao_winsn(struct comedi_device *dev, /* VERIFY: comedi range and offset conversions */ if ((range > 1) /* bipolar */ - &&(data[i] < 2048)) { + && (data[i] < 2048)) { /* offset and sign extend */ val = (((int)data[i]) - 2048) << 3; } else { /* unipolor */ @@ -2267,9 +2260,9 @@ static int rtd_ao_rinsn(struct comedi_device *dev, int i; int chan = CR_CHAN(insn->chanspec); - for (i = 0; i < insn->n; i++) { + for (i = 0; i < insn->n; i++) data[i] = devpriv->aoValue[chan]; - } + return i; } -- cgit v1.2.3 From 2ba451421b23636c45fabfa522858c5c124b3673 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Mon, 31 Jan 2011 14:39:17 +0000 Subject: bnx2x, cnic: Consolidate iSCSI/FCoE shared mem logic in bnx2x Move all shared mem code to bnx2x to avoid code duplication. bnx2x now performs: - Read the FCoE and iSCSI max connection information. - Read the iSCSI and FCoE MACs from NPAR configuration in shmem. - Block the CNIC for the current function if there is neither FCoE nor iSCSI valid configuration by returning NULL from bnx2x_cnic_probe(). Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.h | 2 + drivers/net/bnx2x/bnx2x.h | 5 +- drivers/net/bnx2x/bnx2x_hsi.h | 25 ++++--- drivers/net/bnx2x/bnx2x_main.c | 112 ++++++++++++++++++++++++++++---- drivers/net/cnic.c | 143 ++++++----------------------------------- drivers/net/cnic_if.h | 8 ++- 6 files changed, 146 insertions(+), 149 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 0132ea959995..7a5e88f831f6 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -6207,6 +6207,8 @@ struct l2_fhdr { #define BNX2_CP_SCRATCH 0x001a0000 +#define BNX2_FW_MAX_ISCSI_CONN 0x001a0080 + /* * mcp_reg definition diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 04fb72b923b2..ff87ec33d00e 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -976,8 +976,12 @@ struct bnx2x { #define MF_FUNC_DIS 0x1000 #define FCOE_MACS_SET 0x2000 #define NO_FCOE_FLAG 0x4000 +#define NO_ISCSI_OOO_FLAG 0x8000 +#define NO_ISCSI_FLAG 0x10000 #define NO_FCOE(bp) ((bp)->flags & NO_FCOE_FLAG) +#define NO_ISCSI(bp) ((bp)->flags & NO_ISCSI_FLAG) +#define NO_ISCSI_OOO(bp) ((bp)->flags & NO_ISCSI_OOO_FLAG) int pf_num; /* absolute PF number */ int pfid; /* per-path PF number */ @@ -1125,7 +1129,6 @@ struct bnx2x { u16 cnic_kwq_pending; u16 cnic_spq_pending; struct mutex cnic_mutex; - u8 iscsi_mac[ETH_ALEN]; u8 fip_mac[ETH_ALEN]; #endif diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 51d69db23a71..be503cc0a50b 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -11,20 +11,27 @@ #include "bnx2x_fw_defs.h" +#define FW_ENCODE_32BIT_PATTERN 0x1e1e1e1e + struct license_key { u32 reserved[6]; -#if defined(__BIG_ENDIAN) - u16 max_iscsi_init_conn; - u16 max_iscsi_trgt_conn; -#elif defined(__LITTLE_ENDIAN) - u16 max_iscsi_trgt_conn; - u16 max_iscsi_init_conn; -#endif + u32 max_iscsi_conn; +#define BNX2X_MAX_ISCSI_TRGT_CONN_MASK 0xFFFF +#define BNX2X_MAX_ISCSI_TRGT_CONN_SHIFT 0 +#define BNX2X_MAX_ISCSI_INIT_CONN_MASK 0xFFFF0000 +#define BNX2X_MAX_ISCSI_INIT_CONN_SHIFT 16 - u32 reserved_a[6]; -}; + u32 reserved_a; + + u32 max_fcoe_conn; +#define BNX2X_MAX_FCOE_TRGT_CONN_MASK 0xFFFF +#define BNX2X_MAX_FCOE_TRGT_CONN_SHIFT 0 +#define BNX2X_MAX_FCOE_INIT_CONN_MASK 0xFFFF0000 +#define BNX2X_MAX_FCOE_INIT_CONN_SHIFT 16 + u32 reserved_b[4]; +}; #define PORT_0 0 #define PORT_1 1 diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 2215a39f74fb..ae8d20a2b4fc 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -6456,12 +6456,13 @@ static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set) u32 iscsi_l2_cl_id = BNX2X_ISCSI_ETH_CL_ID + BP_E1HVN(bp) * NONE_ETH_CONTEXT_USE; u32 cl_bit_vec = (1 << iscsi_l2_cl_id); + u8 *iscsi_mac = bp->cnic_eth_dev.iscsi_mac; /* Send a SET_MAC ramrod */ - bnx2x_set_mac_addr_gen(bp, set, bp->iscsi_mac, cl_bit_vec, + bnx2x_set_mac_addr_gen(bp, set, iscsi_mac, cl_bit_vec, cam_offset, 0); - bnx2x_set_mac_in_nig(bp, set, bp->iscsi_mac, LLH_CAM_ISCSI_ETH_LINE); + bnx2x_set_mac_in_nig(bp, set, iscsi_mac, LLH_CAM_ISCSI_ETH_LINE); return 0; } @@ -8385,11 +8386,47 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) bp->common.shmem2_base); } +#ifdef BCM_CNIC +static void __devinit bnx2x_get_cnic_info(struct bnx2x *bp) +{ + u32 max_iscsi_conn = FW_ENCODE_32BIT_PATTERN ^ SHMEM_RD(bp, + drv_lic_key[BP_PORT(bp)].max_iscsi_conn); + u32 max_fcoe_conn = FW_ENCODE_32BIT_PATTERN ^ SHMEM_RD(bp, + drv_lic_key[BP_PORT(bp)].max_fcoe_conn); + + /* Get the number of maximum allowed iSCSI and FCoE connections */ + bp->cnic_eth_dev.max_iscsi_conn = + (max_iscsi_conn & BNX2X_MAX_ISCSI_INIT_CONN_MASK) >> + BNX2X_MAX_ISCSI_INIT_CONN_SHIFT; + + bp->cnic_eth_dev.max_fcoe_conn = + (max_fcoe_conn & BNX2X_MAX_FCOE_INIT_CONN_MASK) >> + BNX2X_MAX_FCOE_INIT_CONN_SHIFT; + + BNX2X_DEV_INFO("max_iscsi_conn 0x%x max_fcoe_conn 0x%x\n", + bp->cnic_eth_dev.max_iscsi_conn, + bp->cnic_eth_dev.max_fcoe_conn); + + /* If mamimum allowed number of connections is zero - + * disable the feature. + */ + if (!bp->cnic_eth_dev.max_iscsi_conn) + bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG; + + if (!bp->cnic_eth_dev.max_fcoe_conn) + bp->flags |= NO_FCOE_FLAG; +} +#endif + static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) { u32 val, val2; int func = BP_ABS_FUNC(bp); int port = BP_PORT(bp); +#ifdef BCM_CNIC + u8 *iscsi_mac = bp->cnic_eth_dev.iscsi_mac; + u8 *fip_mac = bp->fip_mac; +#endif if (BP_NOMCP(bp)) { BNX2X_ERROR("warning: random MAC workaround active\n"); @@ -8402,7 +8439,9 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2); #ifdef BCM_CNIC - /* iSCSI NPAR MAC */ + /* iSCSI and FCoE NPAR MACs: if there is no either iSCSI or + * FCoE MAC then the appropriate feature should be disabled. + */ if (IS_MF_SI(bp)) { u32 cfg = MF_CFG_RD(bp, func_ext_config[func].func_cfg); if (cfg & MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD) { @@ -8410,8 +8449,39 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) iscsi_mac_addr_upper); val = MF_CFG_RD(bp, func_ext_config[func]. iscsi_mac_addr_lower); - bnx2x_set_mac_buf(bp->iscsi_mac, val, val2); - } + BNX2X_DEV_INFO("Read iSCSI MAC: " + "0x%x:0x%04x\n", val2, val); + bnx2x_set_mac_buf(iscsi_mac, val, val2); + + /* Disable iSCSI OOO if MAC configuration is + * invalid. + */ + if (!is_valid_ether_addr(iscsi_mac)) { + bp->flags |= NO_ISCSI_OOO_FLAG | + NO_ISCSI_FLAG; + memset(iscsi_mac, 0, ETH_ALEN); + } + } else + bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG; + + if (cfg & MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD) { + val2 = MF_CFG_RD(bp, func_ext_config[func]. + fcoe_mac_addr_upper); + val = MF_CFG_RD(bp, func_ext_config[func]. + fcoe_mac_addr_lower); + BNX2X_DEV_INFO("Read FCoE MAC to " + "0x%x:0x%04x\n", val2, val); + bnx2x_set_mac_buf(fip_mac, val, val2); + + /* Disable FCoE if MAC configuration is + * invalid. + */ + if (!is_valid_ether_addr(fip_mac)) { + bp->flags |= NO_FCOE_FLAG; + memset(bp->fip_mac, 0, ETH_ALEN); + } + } else + bp->flags |= NO_FCOE_FLAG; } #endif } else { @@ -8425,7 +8495,7 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) iscsi_mac_upper); val = SHMEM_RD(bp, dev_info.port_hw_config[port]. iscsi_mac_lower); - bnx2x_set_mac_buf(bp->iscsi_mac, val, val2); + bnx2x_set_mac_buf(iscsi_mac, val, val2); #endif } @@ -8433,14 +8503,12 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN); #ifdef BCM_CNIC - /* Inform the upper layers about FCoE MAC */ + /* Set the FCoE MAC in modes other then MF_SI */ if (!CHIP_IS_E1x(bp)) { if (IS_MF_SD(bp)) - memcpy(bp->fip_mac, bp->dev->dev_addr, - sizeof(bp->fip_mac)); - else - memcpy(bp->fip_mac, bp->iscsi_mac, - sizeof(bp->fip_mac)); + memcpy(fip_mac, bp->dev->dev_addr, ETH_ALEN); + else if (!IS_MF(bp)) + memcpy(fip_mac, iscsi_mac, ETH_ALEN); } #endif } @@ -8603,6 +8671,10 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) /* Get MAC addresses */ bnx2x_get_mac_hwinfo(bp); +#ifdef BCM_CNIC + bnx2x_get_cnic_info(bp); +#endif + return rc; } @@ -10077,6 +10149,13 @@ struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev) struct bnx2x *bp = netdev_priv(dev); struct cnic_eth_dev *cp = &bp->cnic_eth_dev; + /* If both iSCSI and FCoE are disabled - return NULL in + * order to indicate CNIC that it should not try to work + * with this device. + */ + if (NO_ISCSI(bp) && NO_FCOE(bp)) + return NULL; + cp->drv_owner = THIS_MODULE; cp->chip_id = CHIP_ID(bp); cp->pdev = bp->pdev; @@ -10097,6 +10176,15 @@ struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev) BP_E1HVN(bp) * NONE_ETH_CONTEXT_USE; cp->iscsi_l2_cid = BNX2X_ISCSI_ETH_CID; + if (NO_ISCSI_OOO(bp)) + cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI_OOO; + + if (NO_ISCSI(bp)) + cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI; + + if (NO_FCOE(bp)) + cp->drv_state |= CNIC_DRV_STATE_NO_FCOE; + DP(BNX2X_MSG_SP, "page_size %d, tbl_offset %d, tbl_lines %d, " "starting cid %d\n", cp->ctx_blk_size, diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index c82049635139..2d2d28f58e91 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -4179,6 +4179,14 @@ static void cnic_enable_bnx2_int(struct cnic_dev *dev) BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | cp->last_status_idx); } +static void cnic_get_bnx2_iscsi_info(struct cnic_dev *dev) +{ + u32 max_conn; + + max_conn = cnic_reg_rd_ind(dev, BNX2_FW_MAX_ISCSI_CONN); + dev->max_iscsi_conn = max_conn; +} + static void cnic_disable_bnx2_int_sync(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; @@ -4503,6 +4511,8 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev) return err; } + cnic_get_bnx2_iscsi_info(dev); + return 0; } @@ -4714,129 +4724,6 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev, cp->rx_cons = *cp->rx_cons_ptr; } -static int cnic_read_bnx2x_iscsi_mac(struct cnic_dev *dev, u32 upper_addr, - u32 lower_addr) -{ - u32 val; - u8 mac[6]; - - val = CNIC_RD(dev, upper_addr); - - mac[0] = (u8) (val >> 8); - mac[1] = (u8) val; - - val = CNIC_RD(dev, lower_addr); - - mac[2] = (u8) (val >> 24); - mac[3] = (u8) (val >> 16); - mac[4] = (u8) (val >> 8); - mac[5] = (u8) val; - - if (is_valid_ether_addr(mac)) { - memcpy(dev->mac_addr, mac, 6); - return 0; - } else { - return -EINVAL; - } -} - -static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) -{ - struct cnic_local *cp = dev->cnic_priv; - u32 base, base2, addr, addr1, val; - int port = CNIC_PORT(cp); - - dev->max_iscsi_conn = 0; - base = CNIC_RD(dev, MISC_REG_SHARED_MEM_ADDR); - if (base == 0) - return; - - base2 = CNIC_RD(dev, (CNIC_PATH(cp) ? MISC_REG_GENERIC_CR_1 : - MISC_REG_GENERIC_CR_0)); - addr = BNX2X_SHMEM_ADDR(base, - dev_info.port_hw_config[port].iscsi_mac_upper); - - addr1 = BNX2X_SHMEM_ADDR(base, - dev_info.port_hw_config[port].iscsi_mac_lower); - - cnic_read_bnx2x_iscsi_mac(dev, addr, addr1); - - addr = BNX2X_SHMEM_ADDR(base, validity_map[port]); - val = CNIC_RD(dev, addr); - - if (!(val & SHR_MEM_VALIDITY_LIC_NO_KEY_IN_EFFECT)) { - u16 val16; - - addr = BNX2X_SHMEM_ADDR(base, - drv_lic_key[port].max_iscsi_init_conn); - val16 = CNIC_RD16(dev, addr); - - if (val16) - val16 ^= 0x1e1e; - dev->max_iscsi_conn = val16; - } - - if (BNX2X_CHIP_IS_E2(cp->chip_id)) - dev->max_fcoe_conn = BNX2X_FCOE_NUM_CONNECTIONS; - - if (BNX2X_CHIP_IS_E1H(cp->chip_id) || BNX2X_CHIP_IS_E2(cp->chip_id)) { - int func = CNIC_FUNC(cp); - u32 mf_cfg_addr; - - if (BNX2X_SHMEM2_HAS(base2, mf_cfg_addr)) - mf_cfg_addr = CNIC_RD(dev, BNX2X_SHMEM2_ADDR(base2, - mf_cfg_addr)); - else - mf_cfg_addr = base + BNX2X_SHMEM_MF_BLK_OFFSET; - - if (BNX2X_CHIP_IS_E2(cp->chip_id)) { - /* Must determine if the MF is SD vs SI mode */ - addr = BNX2X_SHMEM_ADDR(base, - dev_info.shared_feature_config.config); - val = CNIC_RD(dev, addr); - if ((val & SHARED_FEAT_CFG_FORCE_SF_MODE_MASK) == - SHARED_FEAT_CFG_FORCE_SF_MODE_SWITCH_INDEPT) { - int rc; - - /* MULTI_FUNCTION_SI mode */ - addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr, - func_ext_config[func].func_cfg); - val = CNIC_RD(dev, addr); - if (!(val & MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD)) - dev->max_iscsi_conn = 0; - - if (!(val & MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD)) - dev->max_fcoe_conn = 0; - - addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr, - func_ext_config[func]. - iscsi_mac_addr_upper); - addr1 = BNX2X_MF_CFG_ADDR(mf_cfg_addr, - func_ext_config[func]. - iscsi_mac_addr_lower); - rc = cnic_read_bnx2x_iscsi_mac(dev, addr, - addr1); - if (rc && func > 1) - dev->max_iscsi_conn = 0; - - return; - } - } - - addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr, - func_mf_config[func].e1hov_tag); - - val = CNIC_RD(dev, addr); - val &= FUNC_MF_CFG_E1HOV_TAG_MASK; - if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { - dev->max_fcoe_conn = 0; - dev->max_iscsi_conn = 0; - } - } - if (!is_valid_ether_addr(dev->mac_addr)) - dev->max_iscsi_conn = 0; -} - static void cnic_init_bnx2x_kcq(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; @@ -4918,8 +4805,6 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) cnic_init_bnx2x_kcq(dev); - cnic_get_bnx2x_iscsi_info(dev); - /* Only 1 EQ */ CNIC_WR16(dev, cp->kcq1.io_addr, MAX_KCQ_IDX); CNIC_WR(dev, BAR_CSTRORM_INTMEM + @@ -5352,6 +5237,14 @@ static struct cnic_dev *init_bnx2x_cnic(struct net_device *dev) cdev->pcidev = pdev; cp->chip_id = ethdev->chip_id; + if (!(ethdev->drv_state & CNIC_DRV_STATE_NO_ISCSI)) + cdev->max_iscsi_conn = ethdev->max_iscsi_conn; + if (BNX2X_CHIP_IS_E2(cp->chip_id) && + !(ethdev->drv_state & CNIC_DRV_STATE_NO_FCOE)) + cdev->max_fcoe_conn = ethdev->max_fcoe_conn; + + memcpy(cdev->mac_addr, ethdev->iscsi_mac, 6); + cp->cnic_ops = &cnic_bnx2x_ops; cp->start_hw = cnic_start_bnx2x_hw; cp->stop_hw = cnic_stop_bnx2x_hw; diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h index 9f44e0ffe003..e01b49ee3591 100644 --- a/drivers/net/cnic_if.h +++ b/drivers/net/cnic_if.h @@ -12,8 +12,8 @@ #ifndef CNIC_IF_H #define CNIC_IF_H -#define CNIC_MODULE_VERSION "2.2.12" -#define CNIC_MODULE_RELDATE "Jan 03, 2011" +#define CNIC_MODULE_VERSION "2.2.13" +#define CNIC_MODULE_RELDATE "Jan 31, 2011" #define CNIC_ULP_RDMA 0 #define CNIC_ULP_ISCSI 1 @@ -159,6 +159,9 @@ struct cnic_eth_dev { u32 drv_state; #define CNIC_DRV_STATE_REGD 0x00000001 #define CNIC_DRV_STATE_USING_MSIX 0x00000002 +#define CNIC_DRV_STATE_NO_ISCSI_OOO 0x00000004 +#define CNIC_DRV_STATE_NO_ISCSI 0x00000008 +#define CNIC_DRV_STATE_NO_FCOE 0x00000010 u32 chip_id; u32 max_kwqe_pending; struct pci_dev *pdev; @@ -176,6 +179,7 @@ struct cnic_eth_dev { u32 fcoe_init_cid; u16 iscsi_l2_client_id; u16 iscsi_l2_cid; + u8 iscsi_mac[ETH_ALEN]; int num_irq; struct cnic_irq irq_arr[MAX_CNIC_VEC]; -- cgit v1.2.3 From 28a1bc1c0a5a15e72afae1050b227761227b6af2 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Mon, 31 Jan 2011 21:06:38 -0800 Subject: Input: wacom_w8001 - report resolution to userland Serial devices send both pen and touch data through the same logical port. Since we scaled touch to pen maximum, we use pen resolution for touch as well here. This is under the assumption that pen and touch share the same physical surface. In the case when a small physical dimensional difference occurs between pen and touch, we assume the tolerance for touch point precision is higher than pen and the difference is within touch point tolerance. A per-MT tool based resolution mechanism should be introduced if the above assumption does not hold true for the pen and touch devices any more. Signed-off-by: Ping Cheng Reviewed-by: Henrik Rydberg Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wacom_w8001.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index 5cb8449c909d..c14412ef4648 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c @@ -51,6 +51,10 @@ MODULE_LICENSE("GPL"); #define W8001_PKTLEN_TPCCTL 11 /* control packet */ #define W8001_PKTLEN_TOUCH2FG 13 +/* resolution in points/mm */ +#define W8001_PEN_RESOLUTION 100 +#define W8001_TOUCH_RESOLUTION 10 + struct w8001_coord { u8 rdy; u8 tsw; @@ -198,7 +202,7 @@ static void parse_touchquery(u8 *data, struct w8001_touch_query *query) query->y = 1024; if (query->panel_res) query->x = query->y = (1 << query->panel_res); - query->panel_res = 10; + query->panel_res = W8001_TOUCH_RESOLUTION; } } @@ -394,6 +398,8 @@ static int w8001_setup(struct w8001 *w8001) input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0); + input_abs_set_res(dev, ABS_X, W8001_PEN_RESOLUTION); + input_abs_set_res(dev, ABS_Y, W8001_PEN_RESOLUTION); input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0); if (coord.tilt_x && coord.tilt_y) { input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); @@ -418,14 +424,17 @@ static int w8001_setup(struct w8001 *w8001) w8001->max_touch_x = touch.x; w8001->max_touch_y = touch.y; - /* scale to pen maximum */ if (w8001->max_pen_x && w8001->max_pen_y) { + /* if pen is supported scale to pen maximum */ touch.x = w8001->max_pen_x; touch.y = w8001->max_pen_y; + touch.panel_res = W8001_PEN_RESOLUTION; } input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0); input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0); + input_abs_set_res(dev, ABS_X, touch.panel_res); + input_abs_set_res(dev, ABS_Y, touch.panel_res); switch (touch.sensor_id) { case 0: -- cgit v1.2.3 From 44d2588e1102b4e35022d03b7f124dd6ea013ce8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 1 Feb 2011 11:42:42 +0100 Subject: acpi: kacpi*_wq don't need WQ_MEM_RECLAIM ACPI workqueues aren't used during memory reclaming. Use alloc_workqueue() to create workqueues w/o rescuers. If the purpose of the separation between kacpid_wq and kacpi_notify_wq was to give notifications better response time, kacpi_notify_wq can be dropped and kacpi_wq can be created with higher @max_active. Signed-off-by: Tejun Heo Cc: Len Brown Cc: linux-acpi@vger.kernel.org --- drivers/acpi/osl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index b0931818cf98..60a80cbfcdc7 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1578,9 +1578,9 @@ acpi_status __init acpi_os_initialize(void) acpi_status __init acpi_os_initialize1(void) { - kacpid_wq = create_workqueue("kacpid"); - kacpi_notify_wq = create_workqueue("kacpi_notify"); - kacpi_hotplug_wq = create_workqueue("kacpi_hotplug"); + kacpid_wq = alloc_workqueue("kacpid", 0, 1); + kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1); + kacpi_hotplug_wq = alloc_workqueue("kacpi_hotplug", 0, 1); BUG_ON(!kacpid_wq); BUG_ON(!kacpi_notify_wq); BUG_ON(!kacpi_hotplug_wq); -- cgit v1.2.3 From 52286713a9ae1c4c80d521a8990e8c3ba14118f3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 1 Feb 2011 11:42:42 +0100 Subject: i2o: use alloc_workqueue() instead of create_workqueue() This is an identity conversion. Signed-off-by: Tejun Heo Cc: Markus Lidel --- drivers/message/i2o/driver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c index a0421efe04ca..8a5b2d8f4daf 100644 --- a/drivers/message/i2o/driver.c +++ b/drivers/message/i2o/driver.c @@ -84,7 +84,8 @@ int i2o_driver_register(struct i2o_driver *drv) osm_debug("Register driver %s\n", drv->name); if (drv->event) { - drv->event_queue = create_workqueue(drv->name); + drv->event_queue = alloc_workqueue(drv->name, + WQ_MEM_RECLAIM, 1); if (!drv->event_queue) { osm_err("Could not initialize event queue for driver " "%s\n", drv->name); -- cgit v1.2.3 From 51f50f815778b91c699fbcc3aac0dda891a7b795 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 1 Feb 2011 11:42:42 +0100 Subject: misc/iwmc3200top: use system_wq instead of dedicated workqueues With cmwq, there's no reason to use separate workqueues in iwmc3200top. Drop them and use system_wq instead. The used work items are sync flushed before driver detach. Signed-off-by: Tejun Heo Cc: Tomas Winkler --- drivers/misc/iwmc3200top/iwmc3200top.h | 4 +--- drivers/misc/iwmc3200top/main.c | 14 +++++--------- 2 files changed, 6 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/iwmc3200top/iwmc3200top.h b/drivers/misc/iwmc3200top/iwmc3200top.h index 740ff0738ea8..620973ed8bf9 100644 --- a/drivers/misc/iwmc3200top/iwmc3200top.h +++ b/drivers/misc/iwmc3200top/iwmc3200top.h @@ -183,9 +183,7 @@ struct iwmct_priv { u32 barker; struct iwmct_dbg dbg; - /* drivers work queue */ - struct workqueue_struct *wq; - struct workqueue_struct *bus_rescan_wq; + /* drivers work items */ struct work_struct bus_rescan_worker; struct work_struct isr_worker; diff --git a/drivers/misc/iwmc3200top/main.c b/drivers/misc/iwmc3200top/main.c index c73cef2c3c5e..727af07f1fbd 100644 --- a/drivers/misc/iwmc3200top/main.c +++ b/drivers/misc/iwmc3200top/main.c @@ -89,7 +89,7 @@ static void op_top_message(struct iwmct_priv *priv, struct top_msg *msg) switch (msg->hdr.opcode) { case OP_OPR_ALIVE: LOG_INFO(priv, FW_MSG, "Got ALIVE from device, wake rescan\n"); - queue_work(priv->bus_rescan_wq, &priv->bus_rescan_worker); + schedule_work(&priv->bus_rescan_worker); break; default: LOG_INFO(priv, FW_MSG, "Received msg opcode 0x%X\n", @@ -360,7 +360,7 @@ static void iwmct_irq(struct sdio_func *func) /* clear the function's interrupt request bit (write 1 to clear) */ sdio_writeb(func, 1, IWMC_SDIO_INTR_CLEAR_ADDR, &ret); - queue_work(priv->wq, &priv->isr_worker); + schedule_work(&priv->isr_worker); LOG_TRACE(priv, IRQ, "exit iwmct_irq\n"); @@ -506,10 +506,6 @@ static int iwmct_probe(struct sdio_func *func, priv->func = func; sdio_set_drvdata(func, priv); - - /* create drivers work queue */ - priv->wq = create_workqueue(DRV_NAME "_wq"); - priv->bus_rescan_wq = create_workqueue(DRV_NAME "_rescan_wq"); INIT_WORK(&priv->bus_rescan_worker, iwmct_rescan_worker); INIT_WORK(&priv->isr_worker, iwmct_irq_read_worker); @@ -604,9 +600,9 @@ static void iwmct_remove(struct sdio_func *func) sdio_release_irq(func); sdio_release_host(func); - /* Safely destroy osc workqueue */ - destroy_workqueue(priv->bus_rescan_wq); - destroy_workqueue(priv->wq); + /* Make sure works are finished */ + flush_work_sync(&priv->bus_rescan_worker); + flush_work_sync(&priv->isr_worker); sdio_claim_host(func); sdio_disable_func(func); -- cgit v1.2.3 From 278274d544e6c6b02312fee59817faa6e810b03a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 1 Feb 2011 11:42:42 +0100 Subject: scsi/be2iscsi,qla2xxx: convert to alloc_workqueue() Switch to new workqueue interface alloc_workqueue(). These are identity conversions. Signed-off-by: Tejun Heo Acked-by: Madhuranath Iyengar Cc: Jayamohan Kallickal Cc: Andrew Vasquez Cc: "James E.J. Bottomley" Cc: linux-scsi@vger.kernel.org --- drivers/scsi/be2iscsi/be_main.c | 2 +- drivers/scsi/qla2xxx/qla_os.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 79cefbe31367..638c72b7f94a 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -4277,7 +4277,7 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u", phba->shost->host_no); - phba->wq = create_workqueue(phba->wq_name); + phba->wq = alloc_workqueue(phba->wq_name, WQ_MEM_RECLAIM, 1); if (!phba->wq) { shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" "Failed to allocate work queue\n"); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index c194c23ca1fb..1d0607677727 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -349,7 +349,7 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha) "Can't create request queue\n"); goto fail; } - ha->wq = create_workqueue("qla2xxx_wq"); + ha->wq = alloc_workqueue("qla2xxx_wq", WQ_MEM_RECLAIM, 1); vha->req = ha->req_q_map[req]; options |= BIT_1; for (ques = 1; ques < ha->max_rsp_queues; ques++) { -- cgit v1.2.3 From 40f38ffb72cd58452dc5afc25ca5215bb90538a4 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 1 Feb 2011 11:42:42 +0100 Subject: scsi/scsi_tgt_lib: scsi_tgtd isn't used in memory reclaim path Workqueue scsi_tgtd isn't used during memory reclaim. Convert to alloc_workqueue() without WQ_MEM_RECLAIM. Signed-off-by: Tejun Heo Cc: FUJITA Tomonori Cc: "James E.J. Bottomley" Cc: linux-scsi@vger.kernel.org --- drivers/scsi/scsi_tgt_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c index c399be979921..f67282058ba1 100644 --- a/drivers/scsi/scsi_tgt_lib.c +++ b/drivers/scsi/scsi_tgt_lib.c @@ -629,7 +629,7 @@ static int __init scsi_tgt_init(void) if (!scsi_tgt_cmd_cache) return -ENOMEM; - scsi_tgtd = create_workqueue("scsi_tgtd"); + scsi_tgtd = alloc_workqueue("scsi_tgtd", 0, 1); if (!scsi_tgtd) { err = -ENOMEM; goto free_kmemcache; -- cgit v1.2.3 From 38a26ef272d8a93c88de54d8d3bd14ac3ce36056 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 1 Feb 2011 11:31:40 +0000 Subject: staging: usbvideo: vicam: Fix build in -next Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbvideo/vicam.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/usbvideo/vicam.c b/drivers/staging/usbvideo/vicam.c index a6816a4395b0..38a373a8d077 100644 --- a/drivers/staging/usbvideo/vicam.c +++ b/drivers/staging/usbvideo/vicam.c @@ -219,7 +219,7 @@ set_camera_power(struct vicam_camera *cam, int state) { int status; - status = send_control_msg(cam, 0x50, state, 0, NULL, 0)); + status = send_control_msg(cam, 0x50, state, 0, NULL, 0); if (status < 0) return status; -- cgit v1.2.3 From 836aded1613dc93bebe7b1d2710f4a416725db50 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 1 Feb 2011 11:34:40 +0000 Subject: staging: sep: Further tidying More debug printk pruning and turn down some that the user can cause intentionally to debug level. Tidy up the ioctl code a bit more Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 78 ++++++++++------------------------------ 1 file changed, 19 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index ee234547c877..d841289c1faf 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -232,7 +232,6 @@ static void *sep_shared_bus_to_virt(struct sep_device *sep, */ static int sep_singleton_open(struct inode *inode_ptr, struct file *file_ptr) { - int error = 0; struct sep_device *sep; /* @@ -243,13 +242,9 @@ static int sep_singleton_open(struct inode *inode_ptr, struct file *file_ptr) file_ptr->private_data = sep; - if (test_and_set_bit(0, &sep->singleton_access_flag)) { - error = -EBUSY; - goto end_function; - } - -end_function: - return error; + if (test_and_set_bit(0, &sep->singleton_access_flag)) + return -EBUSY; + return 0; } /** @@ -273,8 +268,6 @@ static int sep_open(struct inode *inode, struct file *filp) sep = sep_dev; filp->private_data = sep; - dev_dbg(&sep->pdev->dev, "Open for pid %d\n", current->pid); - /* Anyone can open; locking takes place at transaction level */ return 0; } @@ -313,9 +306,6 @@ static int sep_request_daemon_open(struct inode *inode, struct file *filp) filp->private_data = sep; - dev_dbg(&sep->pdev->dev, "Request daemon open for pid %d\n", - current->pid); - /* There is supposed to be only one request daemon */ if (test_and_set_bit(0, &sep->request_daemon_open)) error = -EBUSY; @@ -662,7 +652,7 @@ static unsigned int sep_poll(struct file *filp, poll_table *wait) /* Am I the process that owns the transaction? */ mutex_lock(&sep->sep_mutex); if (current->pid != sep->pid_doing_transaction) { - dev_warn(&sep->pdev->dev, "poll; wrong pid\n"); + dev_dbg(&sep->pdev->dev, "poll; wrong pid\n"); mask = POLLERR; mutex_unlock(&sep->sep_mutex); goto end_function; @@ -791,8 +781,8 @@ static int sep_set_caller_id_handler(struct sep_device *sep, unsigned long arg) } if (i == SEP_CALLER_ID_TABLE_NUM_ENTRIES) { - dev_warn(&sep->pdev->dev, "no more caller id entries left\n"); - dev_warn(&sep->pdev->dev, "maximum number is %d\n", + dev_dbg(&sep->pdev->dev, "no more caller id entries left\n"); + dev_dbg(&sep->pdev->dev, "maximum number is %d\n", SEP_CALLER_ID_TABLE_NUM_ENTRIES); error = -EUSERS; goto end_function; @@ -971,7 +961,6 @@ static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, sep->num_of_data_allocations += 1; end_function: - dev_dbg(&sep->pdev->dev, "sep_allocate_data_pool_memory_handler end\n"); return error; } @@ -2502,7 +2491,7 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) if (reg_val != 0x2) { error = SEP_ALREADY_INITIALIZED_ERR; - dev_warn(&sep->pdev->dev, "init; device already initialized\n"); + dev_dbg(&sep->pdev->dev, "init; device already initialized\n"); goto end_function; } @@ -2703,13 +2692,7 @@ end_function: */ static int sep_free_dcb_handler(struct sep_device *sep) { - int error ; - - dev_dbg(&sep->pdev->dev, "free dcbs num of DCBs %x\n", sep->nr_dcb_creat); - - error = sep_free_dma_tables_and_dcb(sep, false, false); - - return error; + return sep_free_dma_tables_and_dcb(sep, false, false); } /** @@ -2801,25 +2784,19 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) int error = 0; struct sep_device *sep = filp->private_data; - dev_dbg(&sep->pdev->dev, "ioctl cmd is %x\n", cmd); - /* Make sure we own this device */ mutex_lock(&sep->sep_mutex); if ((current->pid != sep->pid_doing_transaction) && (sep->pid_doing_transaction != 0)) { - dev_warn(&sep->pdev->dev, "ioctl pid is not owner\n"); - mutex_unlock(&sep->sep_mutex); + dev_dbg(&sep->pdev->dev, "ioctl pid is not owner\n"); error = -EACCES; goto end_function; } mutex_unlock(&sep->sep_mutex); - /* Check that the command is for SEP device */ - if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) { - error = -ENOTTY; - goto end_function; - } + if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) + return -ENOTTY; /* Lock to prevent the daemon to interfere with operation */ mutex_lock(&sep->ioctl_mutex); @@ -2878,14 +2855,12 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) error = sep_free_dcb_handler(sep); break; default: - dev_dbg(&sep->pdev->dev, "invalid ioctl %x\n", cmd); error = -ENOTTY; break; } - mutex_unlock(&sep->ioctl_mutex); end_function: - dev_dbg(&sep->pdev->dev, "ioctl end\n"); + mutex_unlock(&sep->ioctl_mutex); return error; } @@ -2902,22 +2877,17 @@ static long sep_singleton_ioctl(struct file *filp, u32 cmd, unsigned long arg) long error = 0; struct sep_device *sep = filp->private_data; - dev_dbg(&sep->pdev->dev, "singleton ioctl cmd is %x\n", cmd); - /* Check that the command is for the SEP device */ - if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) { - error = -ENOTTY; - goto end_function; - } + if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) + return -ENOTTY; /* Make sure we own this device */ mutex_lock(&sep->sep_mutex); if ((current->pid != sep->pid_doing_transaction) && (sep->pid_doing_transaction != 0)) { - dev_warn(&sep->pdev->dev, "singleton ioctl pid is not owner\n"); + dev_dbg(&sep->pdev->dev, "singleton ioctl pid is not owner\n"); mutex_unlock(&sep->sep_mutex); - error = -EACCES; - goto end_function; + return -EACCES; } mutex_unlock(&sep->sep_mutex); @@ -2932,8 +2902,6 @@ static long sep_singleton_ioctl(struct file *filp, u32 cmd, unsigned long arg) error = sep_ioctl(filp, cmd, arg); break; } - -end_function: return error; } @@ -2952,13 +2920,9 @@ static long sep_request_daemon_ioctl(struct file *filp, u32 cmd, long error; struct sep_device *sep = filp->private_data; - dev_dbg(&sep->pdev->dev, "daemon ioctl: cmd is %x\n", cmd); - /* Check that the command is for SEP device */ - if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) { - error = -ENOTTY; - goto end_function; - } + if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) + return -ENOTTY; /* Only one process can access ioctl at any given time */ mutex_lock(&sep->ioctl_mutex); @@ -2977,14 +2941,10 @@ static long sep_request_daemon_ioctl(struct file *filp, u32 cmd, error = 0; break; default: - dev_warn(&sep->pdev->dev, "daemon ioctl: no such IOCTL\n"); error = -ENOTTY; } mutex_unlock(&sep->ioctl_mutex); - -end_function: return error; - } /** @@ -3285,7 +3245,7 @@ static int __devinit sep_probe(struct pci_dev *pdev, if (error) goto end_function_dealloc_rar; - /* The new chip requires ashared area reconfigure */ + /* The new chip requires a shared area reconfigure */ if (sep->pdev->revision == 4) { /* Only for new chip */ error = sep_reconfig_shared_area(sep); if (error) -- cgit v1.2.3 From 15c88fad4b7dca6b66cebe53c641593b95432fec Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sat, 15 Jan 2011 21:58:57 -0300 Subject: [media] DM04/QQBOX memcpy to const char fix Driver Version v1.75 Kernel oops appears in 2.6.37-rc8 in lme_firmware_switch because of a memcpy to a const char. Signed-off-by: Malcolm Priestley Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/lmedm04.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c index 9eea4188303b..46ccd01a7696 100644 --- a/drivers/media/dvb/dvb-usb/lmedm04.c +++ b/drivers/media/dvb/dvb-usb/lmedm04.c @@ -659,7 +659,7 @@ static int lme2510_download_firmware(struct usb_device *dev, } /* Default firmware for LME2510C */ -const char lme_firmware[50] = "dvb-usb-lme2510c-s7395.fw"; +char lme_firmware[50] = "dvb-usb-lme2510c-s7395.fw"; static void lme_coldreset(struct usb_device *dev) { @@ -1006,7 +1006,7 @@ static struct dvb_usb_device_properties lme2510c_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, .usb_ctrl = DEVICE_SPECIFIC, .download_firmware = lme2510_download_firmware, - .firmware = lme_firmware, + .firmware = (const char *)&lme_firmware, .size_of_priv = sizeof(struct lme2510_state), .num_adapters = 1, .adapter = { @@ -1109,5 +1109,5 @@ module_exit(lme2510_module_exit); MODULE_AUTHOR("Malcolm Priestley "); MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0"); -MODULE_VERSION("1.74"); +MODULE_VERSION("1.75"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 0552774d0670692f37a8d94374ed16fd9f676dbf Mon Sep 17 00:00:00 2001 From: Pawel Osciak Date: Sun, 16 Jan 2011 16:22:20 -0300 Subject: [media] Fix double free of video_device in mem2mem_testdev video_device is already being freed in video_device.release callback on release. Signed-off-by: Pawel Osciak Reported-by: Roland Kletzing Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/mem2mem_testdev.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c index c179041d91f8..e7e717800ee2 100644 --- a/drivers/media/video/mem2mem_testdev.c +++ b/drivers/media/video/mem2mem_testdev.c @@ -1011,7 +1011,6 @@ static int m2mtest_remove(struct platform_device *pdev) v4l2_m2m_release(dev->m2m_dev); del_timer_sync(&dev->timer); video_unregister_device(dev->vfd); - video_device_release(dev->vfd); v4l2_device_unregister(&dev->v4l2_dev); kfree(dev); -- cgit v1.2.3 From 752eb7ae5075506fb6ac96a901b0e5b3e459f001 Mon Sep 17 00:00:00 2001 From: sensoray-dev Date: Wed, 19 Jan 2011 17:41:45 -0300 Subject: [media] s2255drv: firmware re-loading changes Change for firmware re-loading and updated firmware versions. Signed-off-by: Dean Anderson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s2255drv.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index b63f8cafa671..561909b65ce6 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c @@ -57,7 +57,7 @@ #include #define S2255_MAJOR_VERSION 1 -#define S2255_MINOR_VERSION 20 +#define S2255_MINOR_VERSION 21 #define S2255_RELEASE 0 #define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \ S2255_MINOR_VERSION, \ @@ -312,9 +312,9 @@ struct s2255_fh { }; /* current cypress EEPROM firmware version */ -#define S2255_CUR_USB_FWVER ((3 << 8) | 6) +#define S2255_CUR_USB_FWVER ((3 << 8) | 11) /* current DSP FW version */ -#define S2255_CUR_DSP_FWVER 8 +#define S2255_CUR_DSP_FWVER 10102 /* Need DSP version 5+ for video status feature */ #define S2255_MIN_DSP_STATUS 5 #define S2255_MIN_DSP_COLORFILTER 8 @@ -492,9 +492,11 @@ static void planar422p_to_yuv_packed(const unsigned char *in, static void s2255_reset_dsppower(struct s2255_dev *dev) { - s2255_vendor_req(dev, 0x40, 0x0b0b, 0x0b0b, NULL, 0, 1); + s2255_vendor_req(dev, 0x40, 0x0b0b, 0x0b01, NULL, 0, 1); msleep(10); s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1); + msleep(600); + s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1); return; } -- cgit v1.2.3 From 83587839d648e2a9b5edb5b9d4d9118ead56f22d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Jan 2011 18:16:50 -0300 Subject: [media] ir-raw: Properly initialize the IR event (BZ#27202) Changeset 4651918a4afdd49bdea21d2f919b189ef17a6399 changed the way events are stored. However, it forgot to fix ir_raw_event_store_edge() to work with the new way. Due to that, the decoders will likely do bad things. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ir-raw.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c index 73230ff93b8a..01f258a2a57a 100644 --- a/drivers/media/rc/ir-raw.c +++ b/drivers/media/rc/ir-raw.c @@ -112,7 +112,7 @@ int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type) { ktime_t now; s64 delta; /* ns */ - struct ir_raw_event ev; + DEFINE_IR_RAW_EVENT(ev); int rc = 0; if (!dev->raw) @@ -125,7 +125,6 @@ int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type) * being called for the first time, note that delta can't * possibly be negative. */ - ev.duration = 0; if (delta > IR_MAX_DURATION || !dev->raw->last_type) type |= IR_START_EVENT; else -- cgit v1.2.3 From 54ebb8b83f2be99413261c8ba8238b390159a026 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Sun, 23 Jan 2011 19:12:27 -0300 Subject: [media] au0828: fix VBI handling when in V4L2 streaming mode au0828: fix VBI handling when in V4L2 streaming mode It turns up V4L2 streaming mode (a.k.a mmap) was broken for VBI streaming. This was causing libzvbi to fall back to V4L1 capture mode, and is a blatent violation of the V4L2 specification. Make the implementation work properly in this mode. Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/au0828/au0828-video.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c index e41e4ad5cc40..9c475c600fc9 100644 --- a/drivers/media/video/au0828/au0828-video.c +++ b/drivers/media/video/au0828/au0828-video.c @@ -1758,7 +1758,12 @@ static int vidioc_reqbufs(struct file *file, void *priv, if (rc < 0) return rc; - return videobuf_reqbufs(&fh->vb_vidq, rb); + if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + rc = videobuf_reqbufs(&fh->vb_vidq, rb); + else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) + rc = videobuf_reqbufs(&fh->vb_vbiq, rb); + + return rc; } static int vidioc_querybuf(struct file *file, void *priv, @@ -1772,7 +1777,12 @@ static int vidioc_querybuf(struct file *file, void *priv, if (rc < 0) return rc; - return videobuf_querybuf(&fh->vb_vidq, b); + if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + rc = videobuf_querybuf(&fh->vb_vidq, b); + else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) + rc = videobuf_querybuf(&fh->vb_vbiq, b); + + return rc; } static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) @@ -1785,7 +1795,12 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) if (rc < 0) return rc; - return videobuf_qbuf(&fh->vb_vidq, b); + if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + rc = videobuf_qbuf(&fh->vb_vidq, b); + else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) + rc = videobuf_qbuf(&fh->vb_vbiq, b); + + return rc; } static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) @@ -1806,7 +1821,12 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) dev->greenscreen_detected = 0; } - return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK); + if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + rc = videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK); + else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) + rc = videobuf_dqbuf(&fh->vb_vbiq, b, file->f_flags & O_NONBLOCK); + + return rc; } static struct v4l2_file_operations au0828_v4l_fops = { -- cgit v1.2.3 From 1e6d767924c74929c0cfe839ae8f37bcee9e544e Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Tue, 1 Feb 2011 13:50:58 +0000 Subject: time: Correct the *settime* parameters Both settimeofday() and clock_settime() promise with a 'const' attribute not to alter the arguments passed in. This patch adds the missing 'const' attribute into the various kernel functions implementing these calls. Signed-off-by: Richard Cochran Acked-by: John Stultz LKML-Reference: <20110201134417.545698637@linutronix.de> Signed-off-by: Thomas Gleixner --- drivers/char/mmtimer.c | 2 +- include/linux/posix-timers.h | 5 +++-- include/linux/security.h | 9 +++++---- include/linux/time.h | 5 +++-- kernel/posix-timers.c | 4 ++-- kernel/time.c | 2 +- kernel/time/timekeeping.c | 2 +- security/commoncap.c | 2 +- security/security.c | 2 +- 9 files changed, 18 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index e6d75627c6c8..ecd0082502ef 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c @@ -487,7 +487,7 @@ static int sgi_clock_get(clockid_t clockid, struct timespec *tp) return 0; }; -static int sgi_clock_set(clockid_t clockid, struct timespec *tp) +static int sgi_clock_set(const clockid_t clockid, const struct timespec *tp) { u64 nsec; diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 3e23844a6990..b2c14cbd47a6 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -69,7 +69,8 @@ struct k_itimer { struct k_clock { int res; /* in nanoseconds */ int (*clock_getres) (const clockid_t which_clock, struct timespec *tp); - int (*clock_set) (const clockid_t which_clock, struct timespec * tp); + int (*clock_set) (const clockid_t which_clock, + const struct timespec *tp); int (*clock_get) (const clockid_t which_clock, struct timespec * tp); int (*timer_create) (struct k_itimer *timer); int (*nsleep) (const clockid_t which_clock, int flags, @@ -89,7 +90,7 @@ void register_posix_clock(const clockid_t clock_id, struct k_clock *new_clock); /* error handlers for timer_create, nanosleep and settime */ int do_posix_clock_nonanosleep(const clockid_t, int flags, struct timespec *, struct timespec __user *); -int do_posix_clock_nosettime(const clockid_t, struct timespec *tp); +int do_posix_clock_nosettime(const clockid_t, const struct timespec *tp); /* function to call to trigger timer event */ int posix_timer_event(struct k_itimer *timr, int si_private); diff --git a/include/linux/security.h b/include/linux/security.h index c642bb8b8f5a..c096aa6fca60 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -53,7 +53,7 @@ struct audit_krule; */ extern int cap_capable(struct task_struct *tsk, const struct cred *cred, int cap, int audit); -extern int cap_settime(struct timespec *ts, struct timezone *tz); +extern int cap_settime(const struct timespec *ts, const struct timezone *tz); extern int cap_ptrace_access_check(struct task_struct *child, unsigned int mode); extern int cap_ptrace_traceme(struct task_struct *parent); extern int cap_capget(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); @@ -1387,7 +1387,7 @@ struct security_operations { int (*quotactl) (int cmds, int type, int id, struct super_block *sb); int (*quota_on) (struct dentry *dentry); int (*syslog) (int type); - int (*settime) (struct timespec *ts, struct timezone *tz); + int (*settime) (const struct timespec *ts, const struct timezone *tz); int (*vm_enough_memory) (struct mm_struct *mm, long pages); int (*bprm_set_creds) (struct linux_binprm *bprm); @@ -1669,7 +1669,7 @@ int security_sysctl(struct ctl_table *table, int op); int security_quotactl(int cmds, int type, int id, struct super_block *sb); int security_quota_on(struct dentry *dentry); int security_syslog(int type); -int security_settime(struct timespec *ts, struct timezone *tz); +int security_settime(const struct timespec *ts, const struct timezone *tz); int security_vm_enough_memory(long pages); int security_vm_enough_memory_mm(struct mm_struct *mm, long pages); int security_vm_enough_memory_kern(long pages); @@ -1904,7 +1904,8 @@ static inline int security_syslog(int type) return 0; } -static inline int security_settime(struct timespec *ts, struct timezone *tz) +static inline int security_settime(const struct timespec *ts, + const struct timezone *tz) { return cap_settime(ts, tz); } diff --git a/include/linux/time.h b/include/linux/time.h index 38c5206c2673..7c44e7778033 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -145,8 +145,9 @@ static inline u32 arch_gettimeoffset(void) { return 0; } #endif extern void do_gettimeofday(struct timeval *tv); -extern int do_settimeofday(struct timespec *tv); -extern int do_sys_settimeofday(struct timespec *tv, struct timezone *tz); +extern int do_settimeofday(const struct timespec *tv); +extern int do_sys_settimeofday(const struct timespec *tv, + const struct timezone *tz); #define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts) extern long do_utimes(int dfd, const char __user *filename, struct timespec *times, int flags); struct itimerval; diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 93bd2eb2bc53..21b7ca205f38 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -192,7 +192,7 @@ static int common_clock_get(clockid_t which_clock, struct timespec *tp) } static inline int common_clock_set(const clockid_t which_clock, - struct timespec *tp) + const struct timespec *tp) { return do_sys_settimeofday(tp, NULL); } @@ -928,7 +928,7 @@ void exit_itimers(struct signal_struct *sig) } /* Not available / possible... functions */ -int do_posix_clock_nosettime(const clockid_t clockid, struct timespec *tp) +int do_posix_clock_nosettime(const clockid_t clockid, const struct timespec *tp) { return -EINVAL; } diff --git a/kernel/time.c b/kernel/time.c index a31b51220ac6..5cb80533d8b5 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -150,7 +150,7 @@ static inline void warp_clock(void) * various programs will get confused when the clock gets warped. */ -int do_sys_settimeofday(struct timespec *tv, struct timezone *tz) +int do_sys_settimeofday(const struct timespec *tv, const struct timezone *tz) { static int firsttime = 1; int error = 0; diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 02c13a313d15..4f9f65b91323 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -353,7 +353,7 @@ EXPORT_SYMBOL(do_gettimeofday); * * Sets the time of day to the new time and update NTP and notify hrtimers */ -int do_settimeofday(struct timespec *tv) +int do_settimeofday(const struct timespec *tv) { struct timespec ts_delta; unsigned long flags; diff --git a/security/commoncap.c b/security/commoncap.c index 64c2ed9c9015..dbfdaed4cc66 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -93,7 +93,7 @@ int cap_capable(struct task_struct *tsk, const struct cred *cred, int cap, * Determine whether the current process may set the system clock and timezone * information, returning 0 if permission granted, -ve if denied. */ -int cap_settime(struct timespec *ts, struct timezone *tz) +int cap_settime(const struct timespec *ts, const struct timezone *tz) { if (!capable(CAP_SYS_TIME)) return -EPERM; diff --git a/security/security.c b/security/security.c index 739e40362f44..b995428f1c96 100644 --- a/security/security.c +++ b/security/security.c @@ -202,7 +202,7 @@ int security_syslog(int type) return security_ops->syslog(type); } -int security_settime(struct timespec *ts, struct timezone *tz) +int security_settime(const struct timespec *ts, const struct timezone *tz) { return security_ops->settime(ts, tz); } -- cgit v1.2.3 From 2fd1f04089cb657c5d6c484b280ec4d3398aa157 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 1 Feb 2011 13:51:03 +0000 Subject: posix-timers: Cleanup struct initializers Cosmetic. No functional change Signed-off-by: Thomas Gleixner Acked-by: John Stultz Tested-by: Richard Cochran LKML-Reference: <20110201134417.745627057@linutronix.de> --- drivers/char/mmtimer.c | 14 +++++++------- kernel/posix-cpu-timers.c | 24 ++++++++++++------------ kernel/posix-timers.c | 38 +++++++++++++++++++------------------- 3 files changed, 38 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index ecd0082502ef..fd51cd8ee063 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c @@ -765,13 +765,13 @@ static int sgi_timer_set(struct k_itimer *timr, int flags, static struct k_clock sgi_clock = { .res = 0, - .clock_set = sgi_clock_set, - .clock_get = sgi_clock_get, - .timer_create = sgi_timer_create, - .nsleep = do_posix_clock_nonanosleep, - .timer_set = sgi_timer_set, - .timer_del = sgi_timer_del, - .timer_get = sgi_timer_get + .clock_set = sgi_clock_set, + .clock_get = sgi_clock_get, + .timer_create = sgi_timer_create, + .nsleep = do_posix_clock_nonanosleep, + .timer_set = sgi_timer_set, + .timer_del = sgi_timer_del, + .timer_get = sgi_timer_get }; /** diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 05bb7173850e..11b91dc0992b 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -1607,20 +1607,20 @@ static long thread_cpu_nsleep_restart(struct restart_block *restart_block) static __init int init_posix_cpu_timers(void) { struct k_clock process = { - .clock_getres = process_cpu_clock_getres, - .clock_get = process_cpu_clock_get, - .clock_set = do_posix_clock_nosettime, - .timer_create = process_cpu_timer_create, - .nsleep = process_cpu_nsleep, - .nsleep_restart = process_cpu_nsleep_restart, + .clock_getres = process_cpu_clock_getres, + .clock_get = process_cpu_clock_get, + .clock_set = do_posix_clock_nosettime, + .timer_create = process_cpu_timer_create, + .nsleep = process_cpu_nsleep, + .nsleep_restart = process_cpu_nsleep_restart, }; struct k_clock thread = { - .clock_getres = thread_cpu_clock_getres, - .clock_get = thread_cpu_clock_get, - .clock_set = do_posix_clock_nosettime, - .timer_create = thread_cpu_timer_create, - .nsleep = thread_cpu_nsleep, - .nsleep_restart = thread_cpu_nsleep_restart, + .clock_getres = thread_cpu_clock_getres, + .clock_get = thread_cpu_clock_get, + .clock_set = do_posix_clock_nosettime, + .timer_create = thread_cpu_timer_create, + .nsleep = thread_cpu_nsleep, + .nsleep_restart = thread_cpu_nsleep_restart, }; struct timespec ts; diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 89bff3766d7d..e7d26afd8ee5 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -281,33 +281,33 @@ static int posix_get_coarse_res(const clockid_t which_clock, struct timespec *tp static __init int init_posix_timers(void) { struct k_clock clock_realtime = { - .clock_getres = hrtimer_get_res, + .clock_getres = hrtimer_get_res, }; struct k_clock clock_monotonic = { - .clock_getres = hrtimer_get_res, - .clock_get = posix_ktime_get_ts, - .clock_set = do_posix_clock_nosettime, + .clock_getres = hrtimer_get_res, + .clock_get = posix_ktime_get_ts, + .clock_set = do_posix_clock_nosettime, }; struct k_clock clock_monotonic_raw = { - .clock_getres = hrtimer_get_res, - .clock_get = posix_get_monotonic_raw, - .clock_set = do_posix_clock_nosettime, - .timer_create = no_timer_create, - .nsleep = no_nsleep, + .clock_getres = hrtimer_get_res, + .clock_get = posix_get_monotonic_raw, + .clock_set = do_posix_clock_nosettime, + .timer_create = no_timer_create, + .nsleep = no_nsleep, }; struct k_clock clock_realtime_coarse = { - .clock_getres = posix_get_coarse_res, - .clock_get = posix_get_realtime_coarse, - .clock_set = do_posix_clock_nosettime, - .timer_create = no_timer_create, - .nsleep = no_nsleep, + .clock_getres = posix_get_coarse_res, + .clock_get = posix_get_realtime_coarse, + .clock_set = do_posix_clock_nosettime, + .timer_create = no_timer_create, + .nsleep = no_nsleep, }; struct k_clock clock_monotonic_coarse = { - .clock_getres = posix_get_coarse_res, - .clock_get = posix_get_monotonic_coarse, - .clock_set = do_posix_clock_nosettime, - .timer_create = no_timer_create, - .nsleep = no_nsleep, + .clock_getres = posix_get_coarse_res, + .clock_get = posix_get_monotonic_coarse, + .clock_set = do_posix_clock_nosettime, + .timer_create = no_timer_create, + .nsleep = no_nsleep, }; register_posix_clock(CLOCK_REALTIME, &clock_realtime); -- cgit v1.2.3 From a5cd2880106cb2c79b3fe24f1c53dadba6a542a0 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 1 Feb 2011 13:51:11 +0000 Subject: posix-timers: Convert clock_nanosleep to clockid_to_kclock() Use the new kclock decoding function in clock_nanosleep and cleanup all kclocks which use the default functions. Signed-off-by: Thomas Gleixner Acked-by: John Stultz Tested-by: Richard Cochran LKML-Reference: <20110201134418.034175556@linutronix.de> --- drivers/char/mmtimer.c | 1 - include/linux/posix-timers.h | 2 -- kernel/posix-timers.c | 26 +++++++------------------- 3 files changed, 7 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index fd51cd8ee063..262d10453cb8 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c @@ -768,7 +768,6 @@ static struct k_clock sgi_clock = { .clock_set = sgi_clock_set, .clock_get = sgi_clock_get, .timer_create = sgi_timer_create, - .nsleep = do_posix_clock_nonanosleep, .timer_set = sgi_timer_set, .timer_del = sgi_timer_del, .timer_get = sgi_timer_get diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 1330ff331526..cd6da067bce1 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -90,8 +90,6 @@ extern struct k_clock clock_posix_cpu; void register_posix_clock(const clockid_t clock_id, struct k_clock *new_clock); /* error handlers for timer_create, nanosleep and settime */ -int do_posix_clock_nonanosleep(const clockid_t, int flags, struct timespec *, - struct timespec __user *); int do_posix_clock_nosettime(const clockid_t, const struct timespec *tp); /* function to call to trigger timer event */ diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 14b0a70ffb1e..ee69b216d5c3 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -216,12 +216,6 @@ static int no_timer_create(struct k_itimer *new_timer) return -EOPNOTSUPP; } -static int no_nsleep(const clockid_t which_clock, int flags, - struct timespec *tsave, struct timespec __user *rmtp) -{ - return -EOPNOTSUPP; -} - /* * Return nonzero if we know a priori this clockid_t value is bogus. */ @@ -282,32 +276,31 @@ static __init int init_posix_timers(void) { struct k_clock clock_realtime = { .clock_getres = hrtimer_get_res, + .nsleep = common_nsleep, }; struct k_clock clock_monotonic = { .clock_getres = hrtimer_get_res, .clock_get = posix_ktime_get_ts, .clock_set = do_posix_clock_nosettime, + .nsleep = common_nsleep, }; struct k_clock clock_monotonic_raw = { .clock_getres = hrtimer_get_res, .clock_get = posix_get_monotonic_raw, .clock_set = do_posix_clock_nosettime, .timer_create = no_timer_create, - .nsleep = no_nsleep, }; struct k_clock clock_realtime_coarse = { .clock_getres = posix_get_coarse_res, .clock_get = posix_get_realtime_coarse, .clock_set = do_posix_clock_nosettime, .timer_create = no_timer_create, - .nsleep = no_nsleep, }; struct k_clock clock_monotonic_coarse = { .clock_getres = posix_get_coarse_res, .clock_get = posix_get_monotonic_coarse, .clock_set = do_posix_clock_nosettime, .timer_create = no_timer_create, - .nsleep = no_nsleep, }; register_posix_clock(CLOCK_REALTIME, &clock_realtime); @@ -952,13 +945,6 @@ int do_posix_clock_nosettime(const clockid_t clockid, const struct timespec *tp) } EXPORT_SYMBOL_GPL(do_posix_clock_nosettime); -int do_posix_clock_nonanosleep(const clockid_t clock, int flags, - struct timespec *t, struct timespec __user *r) -{ - return -ENANOSLEEP_NOTSUP; -} -EXPORT_SYMBOL_GPL(do_posix_clock_nonanosleep); - SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, const struct timespec __user *, tp) { @@ -1023,10 +1009,13 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, const struct timespec __user *, rqtp, struct timespec __user *, rmtp) { + struct k_clock *kc = clockid_to_kclock(which_clock); struct timespec t; - if (invalid_clockid(which_clock)) + if (!kc) return -EINVAL; + if (!kc->nsleep) + return -ENANOSLEEP_NOTSUP; if (copy_from_user(&t, rqtp, sizeof (struct timespec))) return -EFAULT; @@ -1034,8 +1023,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, if (!timespec_valid(&t)) return -EINVAL; - return CLOCK_DISPATCH(which_clock, nsleep, - (which_clock, flags, &t, rmtp)); + return kc->nsleep(which_clock, flags, &t, rmtp); } /* -- cgit v1.2.3 From e5e542eea9075dd008993c2ee80b2cc9f31fc494 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 1 Feb 2011 13:51:53 +0000 Subject: posix-timers: Convert clock_getres() to clockid_to_kclock() Use the new kclock decoding. Fixup the fallout in mmtimer.c Signed-off-by: Thomas Gleixner Acked-by: John Stultz Tested-by: Richard Cochran LKML-Reference: <20110201134418.709802797@linutronix.de> --- drivers/char/mmtimer.c | 10 ++++++++++ kernel/posix-timers.c | 17 ++++------------- 2 files changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index 262d10453cb8..141ffaeb976c 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c @@ -53,6 +53,8 @@ MODULE_LICENSE("GPL"); #define RTC_BITS 55 /* 55 bits for this implementation */ +static struct k_clock sgi_clock; + extern unsigned long sn_rtc_cycles_per_second; #define RTC_COUNTER_ADDR ((long *)LOCAL_MMR_ADDR(SH_RTC)) @@ -763,10 +765,18 @@ static int sgi_timer_set(struct k_itimer *timr, int flags, return err; } +static int sgi_clock_getres(const clockid_t which_clock, struct timespec *tp) +{ + tp->tv_sec = 0; + tp->tv_nsec = sgi_clock.res; + return 0; +} + static struct k_clock sgi_clock = { .res = 0, .clock_set = sgi_clock_set, .clock_get = sgi_clock_get, + .clock_getres = sgi_clock_getres, .timer_create = sgi_timer_create, .timer_set = sgi_timer_set, .timer_del = sgi_timer_del, diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 7f66143d1ce5..748497fffd0f 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -182,14 +182,6 @@ static inline void unlock_timer(struct k_itimer *timr, unsigned long flags) * the function pointer CALL in struct k_clock. */ -static inline int common_clock_getres(const clockid_t which_clock, - struct timespec *tp) -{ - tp->tv_sec = 0; - tp->tv_nsec = posix_clocks[which_clock].res; - return 0; -} - static int common_timer_create(struct k_itimer *new_timer) { hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock, 0); @@ -984,18 +976,17 @@ SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp) { + struct k_clock *kc = clockid_to_kclock(which_clock); struct timespec rtn_tp; int error; - if (invalid_clockid(which_clock)) + if (!kc) return -EINVAL; - error = CLOCK_DISPATCH(which_clock, clock_getres, - (which_clock, &rtn_tp)); + error = kc->clock_getres(which_clock, &rtn_tp); - if (!error && tp && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp))) { + if (!error && tp && copy_to_user(tp, &rtn_tp, sizeof (rtn_tp))) error = -EFAULT; - } return error; } -- cgit v1.2.3 From ebaac757acae0431e2c79c00e09f1debdabbddd7 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 1 Feb 2011 13:51:56 +0000 Subject: posix-timers: Remove useless res field from k_clock The res member of kclock is only used by mmtimer.c, but even there it contains redundant information. Remove the field and fixup mmtimer. Signed-off-by: Thomas Gleixner Acked-by: John Stultz Tested-by: Richard Cochran LKML-Reference: <20110201134418.808714587@linutronix.de> --- drivers/char/mmtimer.c | 5 ++--- include/linux/posix-timers.h | 1 - kernel/posix-timers.c | 2 -- 3 files changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index 141ffaeb976c..ff41eb3eec92 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c @@ -768,12 +768,11 @@ static int sgi_timer_set(struct k_itimer *timr, int flags, static int sgi_clock_getres(const clockid_t which_clock, struct timespec *tp) { tp->tv_sec = 0; - tp->tv_nsec = sgi_clock.res; + tp->tv_nsec = sgi_clock_period; return 0; } static struct k_clock sgi_clock = { - .res = 0, .clock_set = sgi_clock_set, .clock_get = sgi_clock_get, .clock_getres = sgi_clock_getres, @@ -840,7 +839,7 @@ static int __init mmtimer_init(void) (unsigned long) node); } - sgi_clock_period = sgi_clock.res = NSEC_PER_SEC / sn_rtc_cycles_per_second; + sgi_clock_period = NSEC_PER_SEC / sn_rtc_cycles_per_second; register_posix_clock(CLOCK_SGI_CYCLE, &sgi_clock); printk(KERN_INFO "%s: v%s, %ld MHz\n", MMTIMER_DESC, MMTIMER_VERSION, diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 4aaf0c5c7cea..ef574d177fb6 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -67,7 +67,6 @@ struct k_itimer { }; struct k_clock { - int res; /* in nanoseconds */ int (*clock_getres) (const clockid_t which_clock, struct timespec *tp); int (*clock_set) (const clockid_t which_clock, const struct timespec *tp); diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 748497fffd0f..f9142a99b5cb 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -204,8 +204,6 @@ static inline int invalid_clockid(const clockid_t which_clock) return 1; if (posix_clocks[which_clock].clock_getres != NULL) return 0; - if (posix_clocks[which_clock].res != 0) - return 0; return 1; } -- cgit v1.2.3 From 527087374faa488776a789375a7d6ea74fda6f71 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 2 Feb 2011 12:10:09 +0100 Subject: posix-timers: Cleanup namespace Rename register_posix_clock() to posix_timers_register_clock(). That's what the function really does. As a side effect this cleans up the posix_clock namespace for the upcoming dynamic posix_clock infrastructure. Signed-off-by: Thomas Gleixner Tested-by: Richard Cochran Cc: John Stultz LKML-Reference: --- drivers/char/mmtimer.c | 2 +- include/linux/posix-timers.h | 2 +- kernel/posix-cpu-timers.c | 4 ++-- kernel/posix-timers.c | 15 ++++++++------- 4 files changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index ff41eb3eec92..33dc2298af73 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c @@ -840,7 +840,7 @@ static int __init mmtimer_init(void) } sgi_clock_period = NSEC_PER_SEC / sn_rtc_cycles_per_second; - register_posix_clock(CLOCK_SGI_CYCLE, &sgi_clock); + posix_timers_register_clock(CLOCK_SGI_CYCLE, &sgi_clock); printk(KERN_INFO "%s: v%s, %ld MHz\n", MMTIMER_DESC, MMTIMER_VERSION, sn_rtc_cycles_per_second/(unsigned long)1E6); diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 88b9256169f8..9d6ffe2c92e5 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -101,7 +101,7 @@ struct k_clock { extern struct k_clock clock_posix_cpu; -void register_posix_clock(const clockid_t clock_id, struct k_clock *new_clock); +void posix_timers_register_clock(const clockid_t clock_id, struct k_clock *new_clock); /* function to call to trigger timer event */ int posix_timer_event(struct k_itimer *timr, int si_private); diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 609e187f43e7..67fea9d25d55 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -1618,8 +1618,8 @@ static __init int init_posix_cpu_timers(void) }; struct timespec ts; - register_posix_clock(CLOCK_PROCESS_CPUTIME_ID, &process); - register_posix_clock(CLOCK_THREAD_CPUTIME_ID, &thread); + posix_timers_register_clock(CLOCK_PROCESS_CPUTIME_ID, &process); + posix_timers_register_clock(CLOCK_THREAD_CPUTIME_ID, &thread); cputime_to_timespec(cputime_one_jiffy, &ts); onecputick = ts.tv_nsec; diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index df629d853a81..af936fd37140 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -253,11 +253,11 @@ static __init int init_posix_timers(void) .clock_get = posix_get_monotonic_coarse, }; - register_posix_clock(CLOCK_REALTIME, &clock_realtime); - register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic); - register_posix_clock(CLOCK_MONOTONIC_RAW, &clock_monotonic_raw); - register_posix_clock(CLOCK_REALTIME_COARSE, &clock_realtime_coarse); - register_posix_clock(CLOCK_MONOTONIC_COARSE, &clock_monotonic_coarse); + posix_timers_register_clock(CLOCK_REALTIME, &clock_realtime); + posix_timers_register_clock(CLOCK_MONOTONIC, &clock_monotonic); + posix_timers_register_clock(CLOCK_MONOTONIC_RAW, &clock_monotonic_raw); + posix_timers_register_clock(CLOCK_REALTIME_COARSE, &clock_realtime_coarse); + posix_timers_register_clock(CLOCK_MONOTONIC_COARSE, &clock_monotonic_coarse); posix_timers_cache = kmem_cache_create("posix_timers_cache", sizeof (struct k_itimer), 0, SLAB_PANIC, @@ -433,7 +433,8 @@ static struct pid *good_sigevent(sigevent_t * event) return task_pid(rtn); } -void register_posix_clock(const clockid_t clock_id, struct k_clock *new_clock) +void posix_timers_register_clock(const clockid_t clock_id, + struct k_clock *new_clock) { if ((unsigned) clock_id >= MAX_CLOCKS) { printk(KERN_WARNING "POSIX clock register failed for clock_id %d\n", @@ -454,7 +455,7 @@ void register_posix_clock(const clockid_t clock_id, struct k_clock *new_clock) posix_clocks[clock_id] = *new_clock; } -EXPORT_SYMBOL_GPL(register_posix_clock); +EXPORT_SYMBOL_GPL(posix_timers_register_clock); static struct k_itimer * alloc_posix_timer(void) { -- cgit v1.2.3 From 71a77e07d0e33b57d4a50c173e5ce4fabceddbec Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 2 Feb 2011 12:13:49 +0000 Subject: drm/i915: Invalidate TLB caches on SNB BLT/BSD rings Signed-off-by: Chris Wilson Cc: stable@kernel.org --- drivers/gpu/drm/i915/i915_reg.h | 4 +++- drivers/gpu/drm/i915/intel_ringbuffer.c | 26 ++++++++++++++++---------- 2 files changed, 19 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5cfc68940f17..15d94c63918c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -174,7 +174,9 @@ * address/value pairs. Don't overdue it, though, x <= 2^4 must hold! */ #define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*x-1) -#define MI_FLUSH_DW MI_INSTR(0x26, 2) /* for GEN6 */ +#define MI_FLUSH_DW MI_INSTR(0x26, 1) /* for GEN6 */ +#define MI_INVALIDATE_TLB (1<<18) +#define MI_INVALIDATE_BSD (1<<7) #define MI_BATCH_BUFFER MI_INSTR(0x30, 1) #define MI_BATCH_NON_SECURE (1) #define MI_BATCH_NON_SECURE_I965 (1<<8) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 6218fa97aa1e..445f27efe677 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1059,22 +1059,25 @@ static void gen6_bsd_ring_write_tail(struct intel_ring_buffer *ring, } static int gen6_ring_flush(struct intel_ring_buffer *ring, - u32 invalidate_domains, - u32 flush_domains) + u32 invalidate, u32 flush) { + uint32_t cmd; int ret; - if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) + if (((invalidate | flush) & I915_GEM_GPU_DOMAINS) == 0) return 0; ret = intel_ring_begin(ring, 4); if (ret) return ret; - intel_ring_emit(ring, MI_FLUSH_DW); - intel_ring_emit(ring, 0); + cmd = MI_FLUSH_DW; + if (invalidate & I915_GEM_GPU_DOMAINS) + cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD; + intel_ring_emit(ring, cmd); intel_ring_emit(ring, 0); intel_ring_emit(ring, 0); + intel_ring_emit(ring, MI_NOOP); intel_ring_advance(ring); return 0; } @@ -1230,22 +1233,25 @@ static int blt_ring_begin(struct intel_ring_buffer *ring, } static int blt_ring_flush(struct intel_ring_buffer *ring, - u32 invalidate_domains, - u32 flush_domains) + u32 invalidate, u32 flush) { + uint32_t cmd; int ret; - if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) + if (((invalidate | flush) & I915_GEM_DOMAIN_RENDER) == 0) return 0; ret = blt_ring_begin(ring, 4); if (ret) return ret; - intel_ring_emit(ring, MI_FLUSH_DW); - intel_ring_emit(ring, 0); + cmd = MI_FLUSH_DW; + if (invalidate & I915_GEM_DOMAIN_RENDER) + cmd |= MI_INVALIDATE_TLB; + intel_ring_emit(ring, cmd); intel_ring_emit(ring, 0); intel_ring_emit(ring, 0); + intel_ring_emit(ring, MI_NOOP); intel_ring_advance(ring); return 0; } -- cgit v1.2.3 From 1071a134d0822663f497a1dda4866cffa7df4e36 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 2 Feb 2011 14:05:47 -0800 Subject: staging: ath6kl: Remove A_BOOL and TRUE/FALSE Use kernel bool and true/false. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/bmi/include/bmi_internal.h | 4 +- drivers/staging/ath6kl/bmi/src/bmi.c | 28 +- .../staging/ath6kl/hif/common/hif_sdio_common.h | 2 +- .../hif/sdio/linux_sdio/include/hif_internal.h | 6 +- .../staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 28 +- .../ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c | 6 +- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 88 +++--- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 62 ++-- drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c | 32 +- drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c | 44 +-- .../ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c | 96 +++--- drivers/staging/ath6kl/htc2/htc.c | 36 +-- drivers/staging/ath6kl/htc2/htc_internal.h | 6 +- drivers/staging/ath6kl/htc2/htc_recv.c | 84 ++--- drivers/staging/ath6kl/htc2/htc_send.c | 46 +-- drivers/staging/ath6kl/htc2/htc_services.c | 20 +- drivers/staging/ath6kl/include/a_drv_api.h | 4 +- drivers/staging/ath6kl/include/aggr_recv_api.h | 2 +- drivers/staging/ath6kl/include/bmi.h | 2 +- drivers/staging/ath6kl/include/common/athdefs.h | 8 - drivers/staging/ath6kl/include/common_drv.h | 2 +- drivers/staging/ath6kl/include/hci_transport_api.h | 12 +- drivers/staging/ath6kl/include/hif.h | 6 +- drivers/staging/ath6kl/include/htc_api.h | 16 +- drivers/staging/ath6kl/include/wlan_api.h | 2 +- drivers/staging/ath6kl/include/wmi_api.h | 22 +- drivers/staging/ath6kl/miscdrv/ar3kconfig.c | 26 +- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c | 16 +- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c | 12 +- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h | 6 +- drivers/staging/ath6kl/miscdrv/common_drv.c | 16 +- drivers/staging/ath6kl/miscdrv/credit_dist.c | 4 +- drivers/staging/ath6kl/os/linux/ar6000_android.c | 10 +- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 252 +++++++-------- drivers/staging/ath6kl/os/linux/ar6000_pm.c | 56 ++-- drivers/staging/ath6kl/os/linux/ar6000_raw_if.c | 26 +- drivers/staging/ath6kl/os/linux/ar6k_pal.c | 28 +- drivers/staging/ath6kl/os/linux/cfg80211.c | 56 ++-- drivers/staging/ath6kl/os/linux/eeprom.c | 2 +- .../staging/ath6kl/os/linux/export_hci_transport.c | 6 +- drivers/staging/ath6kl/os/linux/hci_bridge.c | 58 ++-- .../staging/ath6kl/os/linux/include/ar6000_drv.h | 46 +-- drivers/staging/ath6kl/os/linux/include/ar6k_pal.h | 2 +- .../ath6kl/os/linux/include/ar6xapi_linux.h | 10 +- .../staging/ath6kl/os/linux/include/athdrv_linux.h | 6 +- .../ath6kl/os/linux/include/athtypes_linux.h | 1 - drivers/staging/ath6kl/os/linux/include/cfg80211.h | 2 +- .../ath6kl/os/linux/include/export_hci_transport.h | 6 +- .../staging/ath6kl/os/linux/include/osapi_linux.h | 4 +- drivers/staging/ath6kl/os/linux/ioctl.c | 350 ++++++++++----------- drivers/staging/ath6kl/os/linux/wireless_ext.c | 112 +++---- drivers/staging/ath6kl/reorder/aggr_rx_internal.h | 8 +- drivers/staging/ath6kl/reorder/rcv_aggr.c | 48 +-- drivers/staging/ath6kl/wlan/src/wlan_node.c | 20 +- drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c | 4 +- drivers/staging/ath6kl/wmi/wmi.c | 84 ++--- drivers/staging/ath6kl/wmi/wmi_host.h | 6 +- 57 files changed, 969 insertions(+), 978 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/bmi/include/bmi_internal.h b/drivers/staging/ath6kl/bmi/include/bmi_internal.h index 34e86f31eb94..c9839f437ac1 100644 --- a/drivers/staging/ath6kl/bmi/include/bmi_internal.h +++ b/drivers/staging/ath6kl/bmi/include/bmi_internal.h @@ -39,7 +39,7 @@ #define BMI_COMMUNICATION_TIMEOUT 100000 /* ------ Global Variable Declarations ------- */ -static A_BOOL bmiDone; +static bool bmiDone; int bmiBufferSend(HIF_DEVICE *device, @@ -50,6 +50,6 @@ int bmiBufferReceive(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length, - A_BOOL want_timeout); + bool want_timeout); #endif diff --git a/drivers/staging/ath6kl/bmi/src/bmi.c b/drivers/staging/ath6kl/bmi/src/bmi.c index 355e22bd505c..a29f60e0ce6c 100644 --- a/drivers/staging/ath6kl/bmi/src/bmi.c +++ b/drivers/staging/ath6kl/bmi/src/bmi.c @@ -53,7 +53,7 @@ and does not use the HTC protocol nor even DMA -- it is intentionally kept very simple. */ -static A_BOOL pendingEventsFuncCheck = FALSE; +static bool pendingEventsFuncCheck = false; static A_UINT32 *pBMICmdCredits; static A_UCHAR *pBMICmdBuf; #define MAX_BMI_CMDBUF_SZ (BMI_DATASZ_MAX + \ @@ -66,8 +66,8 @@ static A_UCHAR *pBMICmdBuf; void BMIInit(void) { - bmiDone = FALSE; - pendingEventsFuncCheck = FALSE; + bmiDone = false; + pendingEventsFuncCheck = false; /* * On some platforms, it's not possible to DMA to a static variable @@ -117,7 +117,7 @@ BMIDone(HIF_DEVICE *device) } AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Enter (device: 0x%p)\n", device)); - bmiDone = TRUE; + bmiDone = true; cid = BMI_DONE; status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid)); @@ -162,7 +162,7 @@ BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) } status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_ver, - sizeof(targ_info->target_ver), TRUE); + sizeof(targ_info->target_ver), true); if (status != A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Version from the device\n")); return A_ERROR; @@ -171,7 +171,7 @@ BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) if (targ_info->target_ver == TARGET_VERSION_SENTINAL) { /* Determine how many bytes are in the Target's targ_info */ status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_info_byte_count, - sizeof(targ_info->target_info_byte_count), TRUE); + sizeof(targ_info->target_info_byte_count), true); if (status != A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info Byte Count from the device\n")); return A_ERROR; @@ -186,7 +186,7 @@ BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) /* Read the remainder of the targ_info */ status = bmiBufferReceive(device, ((A_UCHAR *)targ_info)+sizeof(targ_info->target_info_byte_count), - sizeof(*targ_info)-sizeof(targ_info->target_info_byte_count), TRUE); + sizeof(*targ_info)-sizeof(targ_info->target_info_byte_count), true); if (status != A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info (%d bytes) from the device\n", targ_info->target_info_byte_count)); @@ -243,7 +243,7 @@ BMIReadMemory(HIF_DEVICE *device, AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); return A_ERROR; } - status = bmiBufferReceive(device, pBMICmdBuf, rxlen, TRUE); + status = bmiBufferReceive(device, pBMICmdBuf, rxlen, true); if (status != A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); return A_ERROR; @@ -357,7 +357,7 @@ BMIExecute(HIF_DEVICE *device, return A_ERROR; } - status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), FALSE); + status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), false); if (status != A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); return A_ERROR; @@ -441,7 +441,7 @@ BMIReadSOCRegister(HIF_DEVICE *device, return A_ERROR; } - status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), TRUE); + status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), true); if (status != A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); return A_ERROR; @@ -537,7 +537,7 @@ BMIrompatchInstall(HIF_DEVICE *device, return A_ERROR; } - status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*rompatch_id), TRUE); + status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*rompatch_id), true); if (status != A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); return A_ERROR; @@ -785,7 +785,7 @@ int bmiBufferReceive(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length, - A_BOOL want_timeout) + bool want_timeout) { int status; A_UINT32 address; @@ -800,7 +800,7 @@ bmiBufferReceive(HIF_DEVICE *device, HIF_DEVICE_GET_PENDING_EVENTS_FUNC, &getPendingEventsFunc, sizeof(getPendingEventsFunc)); - pendingEventsFuncCheck = TRUE; + pendingEventsFuncCheck = true; } HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR, @@ -1004,7 +1004,7 @@ BMIRawWrite(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length) } int -BMIRawRead(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length, A_BOOL want_timeout) +BMIRawRead(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length, bool want_timeout) { return bmiBufferReceive(device, buffer, length, want_timeout); } diff --git a/drivers/staging/ath6kl/hif/common/hif_sdio_common.h b/drivers/staging/ath6kl/hif/common/hif_sdio_common.h index 0f4e913cb13b..299fd2583c7f 100644 --- a/drivers/staging/ath6kl/hif/common/hif_sdio_common.h +++ b/drivers/staging/ath6kl/hif/common/hif_sdio_common.h @@ -74,7 +74,7 @@ static INLINE void SetExtendedMboxWindowInfo(A_UINT16 Manfid, HIF_DEVICE_MBOX_IN pInfo->GMboxSize = HIF_GMBOX_WIDTH; break; default: - A_ASSERT(FALSE); + A_ASSERT(false); break; } } diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h index f72ba6cf50c4..18713c2b2002 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h @@ -78,9 +78,9 @@ struct hif_device { HTC_CALLBACKS htcCallbacks; A_UINT8 *dma_buffer; DL_LIST ScatterReqHead; /* scatter request list head */ - A_BOOL scatter_enabled; /* scatter enabled flag */ - A_BOOL is_suspend; - A_BOOL is_disabled; + bool scatter_enabled; /* scatter enabled flag */ + bool is_suspend; + bool is_disabled; atomic_t irqHandling; HIF_DEVICE_POWER_CHANGE_TYPE powerConfig; const struct sdio_device_id *id; diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index 26d8a7f30990..273aa6372d2a 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -46,7 +46,7 @@ */ #define BUFFER_NEEDS_BOUNCE(buffer) (((unsigned long)(buffer) & 0x3) || !virt_addr_valid((buffer))) #else -#define BUFFER_NEEDS_BOUNCE(buffer) (FALSE) +#define BUFFER_NEEDS_BOUNCE(buffer) (false) #endif /* ATHENV */ @@ -164,7 +164,7 @@ __HIFReadWrite(HIF_DEVICE *device, int status = A_OK; int ret; A_UINT8 *tbuffer; - A_BOOL bounced = FALSE; + bool bounced = false; AR_DEBUG_ASSERT(device != NULL); AR_DEBUG_ASSERT(device->func != NULL); @@ -243,7 +243,7 @@ __HIFReadWrite(HIF_DEVICE *device, /* copy the write data to the dma buffer */ AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE); memcpy(tbuffer, buffer, length); - bounced = TRUE; + bounced = true; } else { tbuffer = buffer; } @@ -265,7 +265,7 @@ __HIFReadWrite(HIF_DEVICE *device, AR_DEBUG_ASSERT(device->dma_buffer != NULL); AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE); tbuffer = device->dma_buffer; - bounced = TRUE; + bounced = true; } else { tbuffer = buffer; } @@ -299,7 +299,7 @@ __HIFReadWrite(HIF_DEVICE *device, ("AR6000: SDIO bus operation failed! MMC stack returned : %d \n", ret)); status = A_ERROR; } - } while (FALSE); + } while (false); return status; } @@ -725,7 +725,7 @@ HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, } status = SetupHIFScatterSupport(device, (HIF_DEVICE_SCATTER_SUPPORT_INFO *)config); if (status) { - device->scatter_enabled = FALSE; + device->scatter_enabled = false; } break; case HIF_DEVICE_GET_OS_DEVICE: @@ -837,7 +837,7 @@ static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id device = getHifDevice(func); device->id = id; - device->is_disabled = TRUE; + device->is_disabled = true; spin_lock_init(&device->lock); @@ -848,7 +848,7 @@ static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id if (!nohifscattersupport) { /* try to allow scatter operation on all instances, * unless globally overridden */ - device->scatter_enabled = TRUE; + device->scatter_enabled = true; } /* Initialize the bus requests to be used later */ @@ -989,7 +989,7 @@ static int hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func) sdio_release_host(device->func); if (status == A_OK) { - device->is_disabled = TRUE; + device->is_disabled = true; } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDisableFunc\n")); @@ -1036,7 +1036,7 @@ static int hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func) __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret)); return A_ERROR; } - device->is_disabled = FALSE; + device->is_disabled = false; /* create async I/O thread */ if (!device->async_task) { device->async_shutdown = 0; @@ -1086,10 +1086,10 @@ static int hifDeviceSuspend(struct device *dev) device = getHifDevice(func); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceSuspend\n")); if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) { - device->is_suspend = TRUE; /* set true first for PowerStateChangeNotify(..) */ + device->is_suspend = true; /* set true first for PowerStateChangeNotify(..) */ status = osdrvCallbacks.deviceSuspendHandler(device->claimedContext); if (status != A_OK) { - device->is_suspend = FALSE; + device->is_suspend = false; } } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceSuspend\n")); @@ -1115,7 +1115,7 @@ static int hifDeviceResume(struct device *dev) if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) { status = osdrvCallbacks.deviceResumeHandler(device->claimedContext); if (status == A_OK) { - device->is_suspend = FALSE; + device->is_suspend = false; } } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceResume\n")); @@ -1137,7 +1137,7 @@ static void hifDeviceRemoved(struct sdio_func *func) } if (device->is_disabled) { - device->is_disabled = FALSE; + device->is_disabled = false; } else { status = hifDisableFunc(device, func); } diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c index 7ec1f4a92cdf..8d9aed7a8cea 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c @@ -237,7 +237,7 @@ static int HifReadWriteScatter(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq) } if (pReq->TotalLength == 0) { - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -263,7 +263,7 @@ static int HifReadWriteScatter(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq) status = A_OK; } - } while (FALSE); + } while (false); if (status && (request & HIF_ASYNCHRONOUS)) { pReq->CompletionStatus = status; @@ -346,7 +346,7 @@ int SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO * status = A_OK; - } while (FALSE); + } while (false); if (status) { CleanupHIFScatterResources(device); diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index 6a410f1bae21..11311af07641 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -64,7 +64,7 @@ void DevCleanup(AR6K_DEVICE *pDev) if (pDev->HifAttached) { HIFDetachHTC(pDev->HIFDevice); - pDev->HifAttached = FALSE; + pDev->HifAttached = false; } DevCleanupVirtualScatterSupport(pDev); @@ -100,14 +100,14 @@ int DevSetup(AR6K_DEVICE *pDev) break; } - pDev->HifAttached = TRUE; + pDev->HifAttached = true; /* get the addresses for all 4 mailboxes */ status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR, &pDev->MailBoxInfo, sizeof(pDev->MailBoxInfo)); if (status != A_OK) { - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -128,7 +128,7 @@ int DevSetup(AR6K_DEVICE *pDev) blocksizes, sizeof(blocksizes)); if (status != A_OK) { - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -174,14 +174,14 @@ int DevSetup(AR6K_DEVICE *pDev) AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HIF requests that DSR yield per %d RECV packets \n", pDev->HifIRQYieldParams.RecvPacketYieldCount)); - pDev->DSRCanYield = TRUE; + pDev->DSRCanYield = true; } break; case HIF_DEVICE_IRQ_ASYNC_SYNC: AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF Interrupt processing is ASYNC and SYNC\n")); break; default: - A_ASSERT(FALSE); + A_ASSERT(false); } pDev->HifMaskUmaskRecvEvent = NULL; @@ -203,12 +203,12 @@ int DevSetup(AR6K_DEVICE *pDev) status = DevSetupGMbox(pDev); - } while (FALSE); + } while (false); if (status) { if (pDev->HifAttached) { HIFDetachHTC(pDev->HIFDevice); - pDev->HifAttached = FALSE; + pDev->HifAttached = false; } } @@ -355,7 +355,7 @@ static void DevDoEnableDisableRecvAsyncHandler(void *Context, HTC_PACKET *pPacke /* disable packet reception (used in case the host runs out of buffers) * this is the "override" method when the HIF reports another methods to * disable recv events */ -static int DevDoEnableDisableRecvOverride(AR6K_DEVICE *pDev, A_BOOL EnableRecv, A_BOOL AsyncMode) +static int DevDoEnableDisableRecvOverride(AR6K_DEVICE *pDev, bool EnableRecv, bool AsyncMode) { int status = A_OK; HTC_PACKET *pIOPacket = NULL; @@ -371,7 +371,7 @@ static int DevDoEnableDisableRecvOverride(AR6K_DEVICE *pDev, A_BOOL EnableRecv, if (NULL == pIOPacket) { status = A_NO_MEMORY; - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -391,7 +391,7 @@ static int DevDoEnableDisableRecvOverride(AR6K_DEVICE *pDev, A_BOOL EnableRecv, EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV, NULL); - } while (FALSE); + } while (false); if (status && (pIOPacket != NULL)) { AR6KFreeIOPacket(pDev,pIOPacket); @@ -403,7 +403,7 @@ static int DevDoEnableDisableRecvOverride(AR6K_DEVICE *pDev, A_BOOL EnableRecv, /* disable packet reception (used in case the host runs out of buffers) * this is the "normal" method using the interrupt enable registers through * the host I/F */ -static int DevDoEnableDisableRecvNormal(AR6K_DEVICE *pDev, A_BOOL EnableRecv, A_BOOL AsyncMode) +static int DevDoEnableDisableRecvNormal(AR6K_DEVICE *pDev, bool EnableRecv, bool AsyncMode) { int status = A_OK; HTC_PACKET *pIOPacket = NULL; @@ -430,7 +430,7 @@ static int DevDoEnableDisableRecvNormal(AR6K_DEVICE *pDev, A_BOOL EnableRecv, A_ if (NULL == pIOPacket) { status = A_NO_MEMORY; - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -460,7 +460,7 @@ static int DevDoEnableDisableRecvNormal(AR6K_DEVICE *pDev, A_BOOL EnableRecv, A_ HIF_WR_SYNC_BYTE_INC, NULL); - } while (FALSE); + } while (false); if (status && (pIOPacket != NULL)) { AR6KFreeIOPacket(pDev,pIOPacket); @@ -470,25 +470,25 @@ static int DevDoEnableDisableRecvNormal(AR6K_DEVICE *pDev, A_BOOL EnableRecv, A_ } -int DevStopRecv(AR6K_DEVICE *pDev, A_BOOL AsyncMode) +int DevStopRecv(AR6K_DEVICE *pDev, bool AsyncMode) { if (NULL == pDev->HifMaskUmaskRecvEvent) { - return DevDoEnableDisableRecvNormal(pDev,FALSE,AsyncMode); + return DevDoEnableDisableRecvNormal(pDev,false,AsyncMode); } else { - return DevDoEnableDisableRecvOverride(pDev,FALSE,AsyncMode); + return DevDoEnableDisableRecvOverride(pDev,false,AsyncMode); } } -int DevEnableRecv(AR6K_DEVICE *pDev, A_BOOL AsyncMode) +int DevEnableRecv(AR6K_DEVICE *pDev, bool AsyncMode) { if (NULL == pDev->HifMaskUmaskRecvEvent) { - return DevDoEnableDisableRecvNormal(pDev,TRUE,AsyncMode); + return DevDoEnableDisableRecvNormal(pDev,true,AsyncMode); } else { - return DevDoEnableDisableRecvOverride(pDev,TRUE,AsyncMode); + return DevDoEnableDisableRecvOverride(pDev,true,AsyncMode); } } -int DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,A_BOOL *pbIsRecvPending) +int DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,bool *pbIsRecvPending) { int status = A_OK; A_UCHAR host_int_status = 0x0; @@ -520,12 +520,12 @@ int DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,A_BOOL *pbIsRec if(!host_int_status) { status = A_OK; - *pbIsRecvPending = FALSE; + *pbIsRecvPending = false; break; } else { - *pbIsRecvPending = TRUE; + *pbIsRecvPending = true; } A_MDELAY(100); @@ -608,7 +608,7 @@ static void DevFreeScatterReq(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) UNLOCK_AR6K(pDev); } -int DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, A_BOOL FromDMA) +int DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, bool FromDMA) { A_UINT8 *pDMABuffer = NULL; int i, remaining; @@ -617,7 +617,7 @@ int DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, A_BOOL FromDMA) pDMABuffer = pReq->pScatterBounceBuffer; if (pDMABuffer == NULL) { - A_ASSERT(FALSE); + A_ASSERT(false); return A_EINVAL; } @@ -628,7 +628,7 @@ int DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, A_BOOL FromDMA) length = min((int)pReq->ScatterList[i].Length, remaining); if (length != (int)pReq->ScatterList[i].Length) { - A_ASSERT(FALSE); + A_ASSERT(false); /* there is a problem with the scatter list */ return A_EINVAL; } @@ -680,7 +680,7 @@ static int DevReadWriteScatter(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) } if (pReq->TotalLength == 0) { - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -719,7 +719,7 @@ static int DevReadWriteScatter(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) request, (request & HIF_ASYNCHRONOUS) ? pIOPacket : NULL); - } while (FALSE); + } while (false); if ((status != A_PENDING) && status && (request & HIF_ASYNCHRONOUS)) { if (pIOPacket != NULL) { @@ -804,7 +804,7 @@ static int DevSetupVirtualScatterSupport(AR6K_DEVICE *pDev) pDev->HifScatterInfo.MaxScatterEntries = AR6K_SCATTER_ENTRIES_PER_REQ; pDev->HifScatterInfo.MaxTransferSizePerScatterReq = AR6K_MAX_TRANSFER_SIZE_PER_SCATTER; } - pDev->ScatterIsVirtual = TRUE; + pDev->ScatterIsVirtual = true; } return status; @@ -876,7 +876,7 @@ int DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer) return status; } -int DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, A_BOOL Read, A_BOOL Async) +int DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, bool Read, bool Async) { int status; @@ -1038,9 +1038,9 @@ static void AssembleBufferList(BUFFER_PROC_LIST *pList) } -#define FILL_ZERO TRUE -#define FILL_COUNTING FALSE -static void InitBuffers(A_BOOL Zero) +#define FILL_ZERO true +#define FILL_COUNTING false +static void InitBuffers(bool Zero) { A_UINT16 *pBuffer16 = (A_UINT16 *)g_Buffer; int i; @@ -1056,11 +1056,11 @@ static void InitBuffers(A_BOOL Zero) } -static A_BOOL CheckOneBuffer(A_UINT16 *pBuffer16, int Length) +static bool CheckOneBuffer(A_UINT16 *pBuffer16, int Length) { int i; A_UINT16 startCount; - A_BOOL success = TRUE; + bool success = true; /* get the starting count */ startCount = pBuffer16[0]; @@ -1070,7 +1070,7 @@ static A_BOOL CheckOneBuffer(A_UINT16 *pBuffer16, int Length) for (i = 0; i < (Length / 2) ; i++,startCount++) { /* target will invert all the data */ if ((A_UINT16)pBuffer16[i] != (A_UINT16)~startCount) { - success = FALSE; + success = false; AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid Data Got:0x%X, Expecting:0x%X (offset:%d, total:%d) \n", pBuffer16[i], ((A_UINT16)~startCount), i, Length)); AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("0x%X 0x%X 0x%X 0x%X \n", @@ -1082,10 +1082,10 @@ static A_BOOL CheckOneBuffer(A_UINT16 *pBuffer16, int Length) return success; } -static A_BOOL CheckBuffers(void) +static bool CheckBuffers(void) { int i; - A_BOOL success = TRUE; + bool success = true; BUFFER_PROC_LIST checkList[BUFFER_PROC_LIST_DEPTH]; /* assemble the list */ @@ -1176,7 +1176,7 @@ static int GetCredits(AR6K_DEVICE *pDev, int mbox, int *pCredits) A_UINT8 credits = 0; A_UINT32 address; - while (TRUE) { + while (true) { /* Read the counter register to get credits, this auto-decrements */ address = COUNT_DEC_ADDRESS + (AR6K_MAILBOXES + mbox) * 4; @@ -1283,7 +1283,7 @@ static int RecvBuffers(AR6K_DEVICE *pDev, int mbox) } if (totalBytes != TEST_BYTES) { - A_ASSERT(FALSE); + A_ASSERT(false); } else { AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Got all buffers on mbox:%d total recv :%d (w/Padding : %d) \n", mbox, totalBytes, totalwPadding)); @@ -1324,7 +1324,7 @@ static int DoOneMboxHWTest(AR6K_DEVICE *pDev, int mbox) AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" Send/Recv success! mailbox : %d \n",mbox)); - } while (FALSE); + } while (false); return status; } @@ -1349,7 +1349,7 @@ int DoMboxHWTest(AR6K_DEVICE *pDev) g_MailboxAddrs, sizeof(g_MailboxAddrs)); if (status != A_OK) { - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -1358,7 +1358,7 @@ int DoMboxHWTest(AR6K_DEVICE *pDev) g_BlockSizes, sizeof(g_BlockSizes)); if (status != A_OK) { - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -1455,7 +1455,7 @@ int DoMboxHWTest(AR6K_DEVICE *pDev) } } - } while (FALSE); + } while (false); if (status == A_OK) { AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest DONE - SUCCESS! - \n")); diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index 2eced101d162..a015da1322b5 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -75,8 +75,8 @@ typedef PREPACK struct _AR6K_GMBOX_CTRL_REGISTERS { #define AR6K_REG_IO_BUFFER_SIZE 32 #define AR6K_MAX_REG_IO_BUFFERS 8 -#define FROM_DMA_BUFFER TRUE -#define TO_DMA_BUFFER FALSE +#define FROM_DMA_BUFFER true +#define TO_DMA_BUFFER false #define AR6K_SCATTER_ENTRIES_PER_REQ 16 #define AR6K_MAX_TRANSFER_SIZE_PER_SCATTER 16*1024 #define AR6K_SCATTER_REQS 4 @@ -99,10 +99,10 @@ typedef struct AR6K_ASYNC_REG_IO_BUFFER { typedef struct _AR6K_GMBOX_INFO { void *pProtocolContext; int (*pMessagePendingCallBack)(void *pContext, A_UINT8 LookAheadBytes[], int ValidBytes); - int (*pCreditsPendingCallback)(void *pContext, int NumCredits, A_BOOL CreditIRQEnabled); + int (*pCreditsPendingCallback)(void *pContext, int NumCredits, bool CreditIRQEnabled); void (*pTargetFailureCallback)(void *pContext, int Status); void (*pStateDumpCallback)(void *pContext); - A_BOOL CreditCountIRQEnabled; + bool CreditCountIRQEnabled; } AR6K_GMBOX_INFO; typedef struct _AR6K_DEVICE { @@ -124,21 +124,21 @@ typedef struct _AR6K_DEVICE { int (*MessagePendingCallback)(void *Context, A_UINT32 LookAheads[], int NumLookAheads, - A_BOOL *pAsyncProc, + bool *pAsyncProc, int *pNumPktsFetched); HIF_DEVICE_IRQ_PROCESSING_MODE HifIRQProcessingMode; HIF_MASK_UNMASK_RECV_EVENT HifMaskUmaskRecvEvent; - A_BOOL HifAttached; + bool HifAttached; HIF_DEVICE_IRQ_YIELD_PARAMS HifIRQYieldParams; - A_BOOL DSRCanYield; + bool DSRCanYield; int CurrentDSRRecvCount; HIF_DEVICE_SCATTER_SUPPORT_INFO HifScatterInfo; DL_LIST ScatterReqHead; - A_BOOL ScatterIsVirtual; + bool ScatterIsVirtual; int MaxRecvBundleSize; int MaxSendBundleSize; AR6K_GMBOX_INFO GMboxInfo; - A_BOOL GMboxEnabled; + bool GMboxEnabled; AR6K_GMBOX_CTRL_REGISTERS GMboxControlRegisters; int RecheckIRQStatusCnt; } AR6K_DEVICE; @@ -162,15 +162,15 @@ void DevDumpRegisters(AR6K_DEVICE *pDev, AR6K_IRQ_PROC_REGISTERS *pIrqProcRegs, AR6K_IRQ_ENABLE_REGISTERS *pIrqEnableRegs); -#define DEV_STOP_RECV_ASYNC TRUE -#define DEV_STOP_RECV_SYNC FALSE -#define DEV_ENABLE_RECV_ASYNC TRUE -#define DEV_ENABLE_RECV_SYNC FALSE -int DevStopRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode); -int DevEnableRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode); +#define DEV_STOP_RECV_ASYNC true +#define DEV_STOP_RECV_SYNC false +#define DEV_ENABLE_RECV_ASYNC true +#define DEV_ENABLE_RECV_SYNC false +int DevStopRecv(AR6K_DEVICE *pDev, bool ASyncMode); +int DevEnableRecv(AR6K_DEVICE *pDev, bool ASyncMode); int DevEnableInterrupts(AR6K_DEVICE *pDev); int DevDisableInterrupts(AR6K_DEVICE *pDev); -int DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,A_BOOL *pbIsRecvPending); +int DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,bool *pbIsRecvPending); #define DEV_CALC_RECV_PADDED_LEN(pDev, length) (((length) + (pDev)->BlockMask) & (~((pDev)->BlockMask))) #define DEV_CALC_SEND_PADDED_LEN(pDev, length) DEV_CALC_RECV_PADDED_LEN(pDev,length) @@ -178,7 +178,7 @@ int DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,A_BOOL *pbIsRec static INLINE int DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 SendLength) { A_UINT32 paddedLength; - A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE; + bool sync = (pPacket->Completion == NULL) ? true : false; int status; /* adjust the length to be a multiple of block size if appropriate */ @@ -186,7 +186,7 @@ static INLINE int DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 #if 0 if (paddedLength > pPacket->BufferLength) { - A_ASSERT(FALSE); + A_ASSERT(false); if (pPacket->Completion != NULL) { COMPLETE_HTC_PACKET(pPacket,A_EINVAL); return A_OK; @@ -222,13 +222,13 @@ static INLINE int DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 static INLINE int DevRecvPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 RecvLength) { A_UINT32 paddedLength; int status; - A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE; + bool sync = (pPacket->Completion == NULL) ? true : false; /* adjust the length to be a multiple of block size if appropriate */ paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, RecvLength); if (paddedLength > pPacket->BufferLength) { - A_ASSERT(FALSE); + A_ASSERT(false); AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("DevRecvPacket, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n", paddedLength,RecvLength,pPacket->BufferLength)); @@ -272,7 +272,7 @@ static INLINE int DevRecvPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 * */ -int DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, A_BOOL FromDMA); +int DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, bool FromDMA); /* copy any READ data back into scatter list */ #define DEV_FINISH_SCATTER_OPERATION(pR) \ @@ -309,11 +309,11 @@ int DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer); #define DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev) (pDev)->MaxRecvBundleSize #define DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev) (pDev)->MaxSendBundleSize -#define DEV_SCATTER_READ TRUE -#define DEV_SCATTER_WRITE FALSE -#define DEV_SCATTER_ASYNC TRUE -#define DEV_SCATTER_SYNC FALSE -int DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, A_BOOL Read, A_BOOL Async); +#define DEV_SCATTER_READ true +#define DEV_SCATTER_WRITE false +#define DEV_SCATTER_ASYNC true +#define DEV_SCATTER_SYNC false +int DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, bool Read, bool Async); #ifdef MBOXHW_UNIT_TEST int DoMboxHWTest(AR6K_DEVICE *pDev); @@ -350,7 +350,7 @@ void DevNotifyGMboxTargetFailure(AR6K_DEVICE *pDev); #define DevNotifyGMboxTargetFailure(p) static INLINE int DevSetupGMbox(AR6K_DEVICE *pDev) { - pDev->GMboxEnabled = FALSE; + pDev->GMboxEnabled = false; return A_OK; } @@ -379,8 +379,8 @@ AR6K_DEVICE *HTCGetAR6KDevice(void *HTCHandle); int DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 WriteLength); int DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 ReadLength); -#define PROC_IO_ASYNC TRUE -#define PROC_IO_SYNC FALSE +#define PROC_IO_ASYNC true +#define PROC_IO_SYNC false typedef enum GMBOX_IRQ_ACTION_TYPE { GMBOX_ACTION_NONE = 0, GMBOX_DISABLE_ALL, @@ -391,8 +391,8 @@ typedef enum GMBOX_IRQ_ACTION_TYPE { GMBOX_CREDIT_IRQ_DISABLE, } GMBOX_IRQ_ACTION_TYPE; -int DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE, A_BOOL AsyncMode); -int DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, A_BOOL AsyncMode, int *pCredits); +int DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE, bool AsyncMode); +int DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, bool AsyncMode, int *pCredits); int DevGMboxReadCreditSize(AR6K_DEVICE *pDev, int *pCreditSize); int DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, A_UINT8 *pLookAheadBuffer, int *pLookAheadBytes); int DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int SignalNumber, int AckTimeoutMS); diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c index 1e3d6cd43554..92d89c0480c3 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c @@ -70,7 +70,7 @@ int DevPollMboxMsgRecv(AR6K_DEVICE *pDev, AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevPollMboxMsgRecv \n")); - while (TRUE) { + while (true) { if (pDev->GetPendingEventsFunc != NULL) { @@ -304,7 +304,7 @@ static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket) { AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; A_UINT32 lookAhead = 0; - A_BOOL otherInts = FALSE; + bool otherInts = false; AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGetEventAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); @@ -327,7 +327,7 @@ static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket) } } if (pEvents->Events & HIF_OTHER_EVENTS) { - otherInts = TRUE; + otherInts = true; } } else { /* standard interrupt table handling.... */ @@ -349,7 +349,7 @@ static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket) if (host_int_status) { /* there are other interrupts to handle */ - otherInts = TRUE; + otherInts = true; } } @@ -379,7 +379,7 @@ static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket) } } - } while (FALSE); + } while (false); /* free this IO packet */ AR6KFreeIOPacket(pDev,pPacket); @@ -428,7 +428,7 @@ int DevCheckPendingRecvMsgsAsync(void *context) /* there should be only 1 asynchronous request out at a time to read these registers * so this should actually never happen */ status = A_NO_MEMORY; - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -453,7 +453,7 @@ int DevCheckPendingRecvMsgsAsync(void *context) } AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Async IO issued to get interrupt status...\n")); - } while (FALSE); + } while (false); AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevCheckPendingRecvMsgsAsync \n")); @@ -467,7 +467,7 @@ void DevAsyncIrqProcessComplete(AR6K_DEVICE *pDev) } /* process pending interrupts synchronously */ -static int ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pASyncProcessing) +static int ProcessPendingIRQs(AR6K_DEVICE *pDev, bool *pDone, bool *pASyncProcessing) { int status = A_OK; A_UINT8 host_int_status = 0; @@ -591,7 +591,7 @@ static int ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pASyncPr status = DevCheckGMboxInterrupts(pDev); } - } while (FALSE); + } while (false); do { @@ -603,7 +603,7 @@ static int ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pASyncPr if ((0 == host_int_status) && (0 == lookAhead)) { /* nothing to process, the caller can use this to break out of a loop */ - *pDone = TRUE; + *pDone = true; break; } @@ -624,7 +624,7 @@ static int ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pASyncPr if (!fetched) { /* HTC could not pull any messages out due to lack of resources */ /* force DSR handler to ack the interrupt */ - *pASyncProcessing = FALSE; + *pASyncProcessing = false; pDev->RecheckIRQStatusCnt = 0; } } @@ -658,7 +658,7 @@ static int ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pASyncPr } } - } while (FALSE); + } while (false); /* an optimization to bypass reading the IRQ status registers unecessarily which can re-wake * the target, if upper layers determine that we are in a low-throughput mode, we can @@ -670,7 +670,7 @@ static int ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pASyncPr * messages from the mailbox before exiting the ISR routine. */ if (!(*pASyncProcessing) && (pDev->RecheckIRQStatusCnt == 0) && (pDev->GetPendingEventsFunc == NULL)) { AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Bypassing IRQ Status re-check, forcing done \n")); - *pDone = TRUE; + *pDone = true; } AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-ProcessPendingIRQs: (done:%d, async:%d) status=%d \n", @@ -685,8 +685,8 @@ int DevDsrHandler(void *context) { AR6K_DEVICE *pDev = (AR6K_DEVICE *)context; int status = A_OK; - A_BOOL done = FALSE; - A_BOOL asyncProc = FALSE; + bool done = false; + bool asyncProc = false; AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDsrHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); @@ -703,7 +703,7 @@ int DevDsrHandler(void *context) if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) { /* the HIF layer does not allow async IRQ processing, override the asyncProc flag */ - asyncProc = FALSE; + asyncProc = false; /* this will cause us to re-enter ProcessPendingIRQ() and re-read interrupt status registers. * this has a nice side effect of blocking us until all async read requests are completed. * This behavior is required on some HIF implementations that do not allow ASYNC diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c index 74165765f5ea..b21c9fb88f81 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c @@ -74,7 +74,7 @@ static void DevGMboxIRQActionAsyncHandler(void *Context, HTC_PACKET *pPacket) AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxIRQActionAsyncHandler \n")); } -static int DevGMboxCounterEnableDisable(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, A_BOOL AsyncMode) +static int DevGMboxCounterEnableDisable(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode) { int status = A_OK; AR6K_IRQ_ENABLE_REGISTERS regs; @@ -83,12 +83,12 @@ static int DevGMboxCounterEnableDisable(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE LOCK_AR6K(pDev); if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) { - pDev->GMboxInfo.CreditCountIRQEnabled = TRUE; + pDev->GMboxInfo.CreditCountIRQEnabled = true; pDev->IrqEnableRegisters.counter_int_status_enable |= COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER); pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_COUNTER_SET(0x01); } else { - pDev->GMboxInfo.CreditCountIRQEnabled = FALSE; + pDev->GMboxInfo.CreditCountIRQEnabled = false; pDev->IrqEnableRegisters.counter_int_status_enable &= ~(COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER)); } @@ -105,7 +105,7 @@ static int DevGMboxCounterEnableDisable(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE if (NULL == pIOPacket) { status = A_NO_MEMORY; - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -135,7 +135,7 @@ static int DevGMboxCounterEnableDisable(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE AR6K_IRQ_ENABLE_REGS_SIZE, HIF_WR_SYNC_BYTE_INC, NULL); - } while (FALSE); + } while (false); if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, @@ -155,7 +155,7 @@ static int DevGMboxCounterEnableDisable(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE } -int DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, A_BOOL AsyncMode) +int DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode) { int status = A_OK; HTC_PACKET *pIOPacket = NULL; @@ -192,7 +192,7 @@ int DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, A_BOOL break; case GMBOX_ACTION_NONE: default: - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -211,7 +211,7 @@ int DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, A_BOOL if (NULL == pIOPacket) { status = A_NO_MEMORY; - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -242,7 +242,7 @@ int DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, A_BOOL HIF_WR_SYNC_BYTE_FIX, NULL); - } while (FALSE); + } while (false); if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, @@ -264,7 +264,7 @@ int DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, A_BOOL void DevCleanupGMbox(AR6K_DEVICE *pDev) { if (pDev->GMboxEnabled) { - pDev->GMboxEnabled = FALSE; + pDev->GMboxEnabled = false; GMboxProtocolUninstall(pDev); } } @@ -315,9 +315,9 @@ int DevSetupGMbox(AR6K_DEVICE *pDev) break; } - pDev->GMboxEnabled = TRUE; + pDev->GMboxEnabled = true; - } while (FALSE); + } while (false); return status; } @@ -388,7 +388,7 @@ int DevCheckGMboxInterrupts(AR6K_DEVICE *pDev) pDev->GMboxInfo.CreditCountIRQEnabled); } - } while (FALSE); + } while (false); AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("-DevCheckGMboxInterrupts (%d) \n",status)); @@ -399,7 +399,7 @@ int DevCheckGMboxInterrupts(AR6K_DEVICE *pDev) int DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 WriteLength) { A_UINT32 paddedLength; - A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE; + bool sync = (pPacket->Completion == NULL) ? true : false; int status; A_UINT32 address; @@ -438,13 +438,13 @@ int DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 ReadLength) A_UINT32 paddedLength; int status; - A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE; + bool sync = (pPacket->Completion == NULL) ? true : false; /* adjust the length to be a multiple of block size if appropriate */ paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, ReadLength); if (paddedLength > pPacket->BufferLength) { - A_ASSERT(FALSE); + A_ASSERT(false); AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("DevGMboxRead, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n", paddedLength,ReadLength,pPacket->BufferLength)); @@ -539,7 +539,7 @@ static void DevGMboxReadCreditsAsyncHandler(void *Context, HTC_PACKET *pPacket) AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxReadCreditsAsyncHandler \n")); } -int DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, A_BOOL AsyncMode, int *pCredits) +int DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, bool AsyncMode, int *pCredits) { int status = A_OK; HTC_PACKET *pIOPacket = NULL; @@ -552,7 +552,7 @@ int DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, A_BOOL AsyncMode, int *pCredits if (NULL == pIOPacket) { status = A_NO_MEMORY; - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -581,7 +581,7 @@ int DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, A_BOOL AsyncMode, int *pCredits AR6K_REG_IO_BUFFER_SIZE, HIF_RD_SYNC_BYTE_FIX, NULL); - } while (FALSE); + } while (false); if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, @@ -644,7 +644,7 @@ int DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, A_UINT8 *pLookAheadBuffer, int do { /* on entry the caller provides the length of the lookahead buffer */ if (*pLookAheadBytes > sizeof(procRegs.rx_gmbox_lookahead_alias)) { - A_ASSERT(FALSE); + A_ASSERT(false); status = A_EINVAL; break; } @@ -671,7 +671,7 @@ int DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, A_UINT8 *pLookAheadBuffer, int *pLookAheadBytes = bytes; } - } while (FALSE); + } while (false); return status; } @@ -705,7 +705,7 @@ int DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int Signal, int AckTimeoutMS) break; } - } while (FALSE); + } while (false); if (!status) { diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c index bdb8632dbe84..2a87a49a79e5 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c @@ -58,8 +58,8 @@ typedef struct { HCI_TRANSPORT_CONFIG_INFO HCIConfig; - A_BOOL HCIAttached; - A_BOOL HCIStopped; + bool HCIAttached; + bool HCIStopped; A_UINT32 RecvStateFlags; A_UINT32 SendStateFlags; HCI_TRANSPORT_PACKET_TYPE WaitBufferType; @@ -99,7 +99,7 @@ do { \ (p)->HCIConfig.pHCISendComplete((p)->HCIConfig.pContext, (pt)); \ } -static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, A_BOOL Synchronous); +static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, bool Synchronous); static void HCIUartCleanup(GMBOX_PROTO_HCI_UART *pProtocol) { @@ -116,7 +116,7 @@ static int InitTxCreditState(GMBOX_PROTO_HCI_UART *pProt) int status; int credits; int creditPollCount = CREDIT_POLL_COUNT; - A_BOOL gotCredits = FALSE; + bool gotCredits = false; pProt->CreditsConsumed = 0; @@ -125,7 +125,7 @@ static int InitTxCreditState(GMBOX_PROTO_HCI_UART *pProt) if (pProt->CreditsMax != 0) { /* we can only call this only once per target reset */ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI: InitTxCreditState - already called! \n")); - A_ASSERT(FALSE); + A_ASSERT(false); status = A_EINVAL; break; } @@ -150,7 +150,7 @@ static int InitTxCreditState(GMBOX_PROTO_HCI_UART *pProt) A_MDELAY(HCI_DELAY_PER_INTERVAL_MS); continue; } else { - gotCredits = TRUE; + gotCredits = true; } if (0 == credits) { @@ -178,7 +178,7 @@ static int InitTxCreditState(GMBOX_PROTO_HCI_UART *pProt) break; } - } while (FALSE); + } while (false); if (!status) { pProt->CreditsAvailable = pProt->CreditsMax; @@ -189,12 +189,12 @@ static int InitTxCreditState(GMBOX_PROTO_HCI_UART *pProt) return status; } -static int CreditsAvailableCallback(void *pContext, int Credits, A_BOOL CreditIRQEnabled) +static int CreditsAvailableCallback(void *pContext, int Credits, bool CreditIRQEnabled) { GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)pContext; - A_BOOL enableCreditIrq = FALSE; - A_BOOL disableCreditIrq = FALSE; - A_BOOL doPendingSends = FALSE; + bool enableCreditIrq = false; + bool disableCreditIrq = false; + bool doPendingSends = false; int status = A_OK; /** this callback is called under 2 conditions: @@ -214,7 +214,7 @@ static int CreditsAvailableCallback(void *pContext, int Credits, A_BOOL CreditIR if (0 == Credits) { if (!CreditIRQEnabled) { /* enable credit IRQ */ - enableCreditIrq = TRUE; + enableCreditIrq = true; } break; } @@ -240,19 +240,19 @@ static int CreditsAvailableCallback(void *pContext, int Credits, A_BOOL CreditIR /* we have enough credits to fullfill at least 1 packet waiting in the queue */ pProt->CreditsCurrentSeek = 0; pProt->SendStateFlags &= ~HCI_SEND_WAIT_CREDITS; - doPendingSends = TRUE; + doPendingSends = true; if (CreditIRQEnabled) { /* credit IRQ was enabled, we shouldn't need it anymore */ - disableCreditIrq = TRUE; + disableCreditIrq = true; } } else { /* not enough credits yet, enable credit IRQ if we haven't already */ if (!CreditIRQEnabled) { - enableCreditIrq = TRUE; + enableCreditIrq = true; } } - } while (FALSE); + } while (false); UNLOCK_HCI_TX(pProt); @@ -267,7 +267,7 @@ static int CreditsAvailableCallback(void *pContext, int Credits, A_BOOL CreditIR } if (doPendingSends) { - HCITrySend(pProt, NULL, FALSE); + HCITrySend(pProt, NULL, false); } AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+CreditsAvailableCallback \n")); @@ -310,8 +310,8 @@ static int HCIUartMessagePending(void *pContext, A_UINT8 LookAheadBytes[], int V int status = A_OK; int totalRecvLength = 0; HCI_TRANSPORT_PACKET_TYPE pktType = HCI_PACKET_INVALID; - A_BOOL recvRefillCalled = FALSE; - A_BOOL blockRecv = FALSE; + bool recvRefillCalled = false; + bool blockRecv = false; HTC_PACKET *pPacket = NULL; /** caller guarantees that this is a fully block-able context (synch I/O is allowed) */ @@ -382,7 +382,7 @@ static int HCIUartMessagePending(void *pContext, A_UINT8 LookAheadBytes[], int V pktType)); /* check for refill handler */ if (pProt->HCIConfig.pHCIPktRecvRefill != NULL) { - recvRefillCalled = TRUE; + recvRefillCalled = true; UNLOCK_HCI_RX(pProt); /* call the re-fill handler */ pProt->HCIConfig.pHCIPktRecvRefill(pProt->HCIConfig.pContext, @@ -407,7 +407,7 @@ static int HCIUartMessagePending(void *pContext, A_UINT8 LookAheadBytes[], int V /* this is not an error, we simply need to mark that we are waiting for buffers.*/ pProt->RecvStateFlags |= HCI_RECV_WAIT_BUFFERS; pProt->WaitBufferType = pktType; - blockRecv = TRUE; + blockRecv = true; break; } @@ -418,7 +418,7 @@ static int HCIUartMessagePending(void *pContext, A_UINT8 LookAheadBytes[], int V break; } - } while (FALSE); + } while (false); UNLOCK_HCI_RX(pProt); @@ -505,7 +505,7 @@ static int HCIUartMessagePending(void *pContext, A_UINT8 LookAheadBytes[], int V } } - } while (FALSE); + } while (false); /* check if we need to disable the reciever */ if (status || blockRecv) { @@ -553,7 +553,7 @@ static int SeekCreditsSynch(GMBOX_PROTO_HCI_UART *pProt) int credits; int retry = 100; - while (TRUE) { + while (true) { credits = 0; status = DevGMboxReadCreditCounter(pProt->pDev, PROC_IO_SYNC, &credits); if (status) { @@ -579,13 +579,13 @@ static int SeekCreditsSynch(GMBOX_PROTO_HCI_UART *pProt) return status; } -static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, A_BOOL Synchronous) +static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, bool Synchronous) { int status = A_OK; int transferLength; int creditsRequired, remainder; A_UINT8 hciUartType; - A_BOOL synchSendComplete = FALSE; + bool synchSendComplete = false; AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCITrySend (pPacket:0x%lX) %s \n",(unsigned long)pPacket, Synchronous ? "SYNC" :"ASYNC")); @@ -608,14 +608,14 @@ static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, A_BOOL S /* in synchronous mode, the send queue can only hold 1 packet */ if (!HTC_QUEUE_EMPTY(&pProt->SendQueue)) { status = A_EBUSY; - A_ASSERT(FALSE); + A_ASSERT(false); break; } if (pProt->SendProcessCount > 1) { /* another thread or task is draining the TX queues */ status = A_EBUSY; - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -672,7 +672,7 @@ static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, A_BOOL S break; default: status = A_EINVAL; - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -756,7 +756,7 @@ static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, A_BOOL S status = DevGMboxWrite(pProt->pDev,pPacket,transferLength); if (Synchronous) { - synchSendComplete = TRUE; + synchSendComplete = true; } else { pPacket = NULL; } @@ -765,7 +765,7 @@ static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, A_BOOL S } - } while (FALSE); + } while (false); pProt->SendProcessCount--; A_ASSERT(pProt->SendProcessCount >= 0); @@ -775,7 +775,7 @@ static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, A_BOOL S A_ASSERT(pPacket != NULL); if (!status && (!synchSendComplete)) { status = A_EBUSY; - A_ASSERT(FALSE); + A_ASSERT(false); LOCK_HCI_TX(pProt); if (pPacket->ListLink.pNext != NULL) { /* remove from the queue */ @@ -868,7 +868,7 @@ int GMboxProtocolInstall(AR6K_DEVICE *pDev) A_MUTEX_INIT(&pProtocol->HCIRxLock); A_MUTEX_INIT(&pProtocol->HCITxLock); - } while (FALSE); + } while (false); if (!status) { LOCK_AR6K(pDev); @@ -899,7 +899,7 @@ void GMboxProtocolUninstall(AR6K_DEVICE *pDev) if (pProtocol->HCIAttached) { A_ASSERT(pProtocol->HCIConfig.TransportRemoved != NULL); pProtocol->HCIConfig.TransportRemoved(pProtocol->HCIConfig.pContext); - pProtocol->HCIAttached = FALSE; + pProtocol->HCIAttached = false; } HCIUartCleanup(pProtocol); @@ -929,7 +929,7 @@ static int NotifyTransportReady(GMBOX_PROTO_HCI_UART *pProt) pProt->HCIConfig.pContext); } - } while (FALSE); + } while (false); return status; } @@ -966,9 +966,9 @@ HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, HCI_TRANSPORT_CONFIG_I A_ASSERT(pProtocol->HCIConfig.pHCIPktRecv != NULL); A_ASSERT(pProtocol->HCIConfig.pHCISendComplete != NULL); - pProtocol->HCIAttached = TRUE; + pProtocol->HCIAttached = true; - } while (FALSE); + } while (false); UNLOCK_AR6K(pDev); @@ -994,7 +994,7 @@ void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans) UNLOCK_AR6K(pDev); return; } - pProtocol->HCIAttached = FALSE; + pProtocol->HCIAttached = false; UNLOCK_AR6K(pDev); HCI_TransportStop(HciTrans); @@ -1005,7 +1005,7 @@ int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE { GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; int status = A_OK; - A_BOOL unblockRecv = FALSE; + bool unblockRecv = false; HTC_PACKET *pPacket; AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HCI_TransportAddReceivePkt \n")); @@ -1044,11 +1044,11 @@ int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE pProt->WaitBufferType)); pProt->RecvStateFlags &= ~HCI_RECV_WAIT_BUFFERS; pProt->WaitBufferType = HCI_PACKET_INVALID; - unblockRecv = TRUE; + unblockRecv = true; } } - } while (FALSE); + } while (false); UNLOCK_HCI_RX(pProt); @@ -1069,7 +1069,7 @@ int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE return A_OK; } -int HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, A_BOOL Synchronous) +int HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, bool Synchronous) { GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; @@ -1088,7 +1088,7 @@ void HCI_TransportStop(HCI_TRANSPORT_HANDLE HciTrans) AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportStop \n")); return; } - pProt->HCIStopped = TRUE; + pProt->HCIStopped = true; UNLOCK_AR6K(pProt->pDev); /* disable interrupts */ @@ -1110,7 +1110,7 @@ int HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans) AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportStart \n")); /* set stopped in case we have a problem in starting */ - pProt->HCIStopped = TRUE; + pProt->HCIStopped = true; do { @@ -1140,16 +1140,16 @@ int HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans) } /* we made it */ - pProt->HCIStopped = FALSE; + pProt->HCIStopped = false; - } while (FALSE); + } while (false); AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportStart \n")); return status; } -int HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable) +int HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, bool Enable) { GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; return DevGMboxIRQAction(pProt->pDev, @@ -1261,7 +1261,7 @@ int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud) return status; } -int HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable) +int HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, bool Enable) { int status; GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index b24698ebbecb..3c831e0abe36 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -190,7 +190,7 @@ HTC_HANDLE HTCCreate(void *hif_handle, HTC_INIT_INFO *pInfo) HTC_FREE_CONTROL_TX(target,pControlPacket); } - } while (FALSE); + } while (false); if (status) { if (target != NULL) { @@ -260,7 +260,7 @@ int HTCWaitTarget(HTC_HANDLE HTCHandle) if ((pRdyMsg->Version2_0_Info.MessageID != HTC_MSG_READY_ID) || (pPacket->ActualLength < sizeof(HTC_READY_MSG))) { /* this message is not valid */ - AR_DEBUG_ASSERT(FALSE); + AR_DEBUG_ASSERT(false); status = A_EPROTO; break; } @@ -268,7 +268,7 @@ int HTCWaitTarget(HTC_HANDLE HTCHandle) if (pRdyMsg->Version2_0_Info.CreditCount == 0 || pRdyMsg->Version2_0_Info.CreditSize == 0) { /* this message is not valid */ - AR_DEBUG_ASSERT(FALSE); + AR_DEBUG_ASSERT(false); status = A_EPROTO; break; } @@ -320,10 +320,10 @@ int HTCWaitTarget(HTC_HANDLE HTCHandle) (" HTC bundling allowed. Max Msg Per HTC Bundle: %d\n", target->MaxMsgPerBundle)); if (DEV_GET_MAX_BUNDLE_SEND_LENGTH(&target->Device) != 0) { - target->SendBundlingEnabled = TRUE; + target->SendBundlingEnabled = true; } if (DEV_GET_MAX_BUNDLE_RECV_LENGTH(&target->Device) != 0) { - target->RecvBundlingEnabled = TRUE; + target->RecvBundlingEnabled = true; } if (!DEV_IS_LEN_BLOCK_ALIGNED(&target->Device,target->TargetCreditSize)) { @@ -331,7 +331,7 @@ int HTCWaitTarget(HTC_HANDLE HTCHandle) target->TargetCreditSize)); /* disallow send bundling since the credit size is not aligned to a block size * the I/O block padding will spill into the next credit buffer which is fatal */ - target->SendBundlingEnabled = FALSE; + target->SendBundlingEnabled = false; } } @@ -355,7 +355,7 @@ int HTCWaitTarget(HTC_HANDLE HTCHandle) break; } - } while (FALSE); + } while (false); if (pPacket != NULL) { HTC_FREE_CONTROL_RX(target,pPacket); @@ -430,7 +430,7 @@ int HTCStart(HTC_HANDLE HTCHandle) HTCStop(target); } - } while (FALSE); + } while (false); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n")); return status; @@ -511,7 +511,7 @@ static void HTCReportFailure(void *Context) { HTC_TARGET *target = (HTC_TARGET *)Context; - target->TargetFailure = TRUE; + target->TargetFailure = true; if (target->HTCInitInfo.TargetFailure != NULL) { /* let upper layer know, it needs to call HTCStop() */ @@ -519,7 +519,7 @@ static void HTCReportFailure(void *Context) } } -A_BOOL HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, +bool HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_ENDPOINT_STAT_ACTION Action, HTC_ENDPOINT_STATS *pStats) @@ -527,19 +527,19 @@ A_BOOL HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, #ifdef HTC_EP_STAT_PROFILING HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - A_BOOL clearStats = FALSE; - A_BOOL sample = FALSE; + bool clearStats = false; + bool sample = false; switch (Action) { case HTC_EP_STAT_SAMPLE : - sample = TRUE; + sample = true; break; case HTC_EP_STAT_SAMPLE_AND_CLEAR : - sample = TRUE; - clearStats = TRUE; + sample = true; + clearStats = true; break; case HTC_EP_STAT_CLEAR : - clearStats = TRUE; + clearStats = true; break; default: break; @@ -565,9 +565,9 @@ A_BOOL HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, UNLOCK_HTC_RX(target); UNLOCK_HTC_TX(target); - return TRUE; + return true; #else - return FALSE; + return false; #endif } diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h index 46364cba333a..48d2afefee0b 100644 --- a/drivers/staging/ath6kl/htc2/htc_internal.h +++ b/drivers/staging/ath6kl/htc2/htc_internal.h @@ -126,7 +126,7 @@ typedef struct _HTC_TARGET { A_UINT32 OpStateFlags; A_UINT32 RecvStateFlags; HTC_ENDPOINT_ID EpWaitingForBuffers; - A_BOOL TargetFailure; + bool TargetFailure; #ifdef HTC_CAPTURE_LAST_FRAME HTC_FRAME_HDR LastFrameHdr; /* useful for debugging */ A_UINT8 LastTrailer[256]; @@ -135,7 +135,7 @@ typedef struct _HTC_TARGET { HTC_INIT_INFO HTCInitInfo; A_UINT8 HTCTargetVersion; int MaxMsgPerBundle; /* max messages per bundle for HTC */ - A_BOOL SendBundlingEnabled; /* run time enable for send bundling (dynamic) */ + bool SendBundlingEnabled; /* run time enable for send bundling (dynamic) */ int RecvBundlingEnabled; /* run time enable for recv bundling (dynamic) */ } HTC_TARGET; @@ -169,7 +169,7 @@ HTC_PACKET *HTCAllocControlBuffer(HTC_TARGET *target, HTC_PACKET_QUEUE *pList); void HTCFreeControlBuffer(HTC_TARGET *target, HTC_PACKET *pPacket, HTC_PACKET_QUEUE *pList); int HTCIssueSend(HTC_TARGET *target, HTC_PACKET *pPacket); void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket); -int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int NumLookAheads, A_BOOL *pAsyncProc, int *pNumPktsFetched); +int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched); void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint); int HTCSendSetupComplete(HTC_TARGET *target); void HTCFlushRecvBuffers(HTC_TARGET *target); diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c index b38211b8828b..fcbee0d15b5f 100644 --- a/drivers/staging/ath6kl/htc2/htc_recv.c +++ b/drivers/staging/ath6kl/htc2/htc_recv.c @@ -79,7 +79,7 @@ static void DoRecvCompletion(HTC_ENDPOINT *pEndpoint, } while (!HTC_QUEUE_EMPTY(pQueueToIndicate)); } - } while (FALSE); + } while (false); } @@ -182,7 +182,7 @@ static INLINE int HTCProcessTrailer(HTC_TARGET *target, HTC_HOST_MAX_MSG_PER_BUNDLE) { /* this should never happen, the target restricts the number * of messages per bundle configured by the host */ - A_ASSERT(FALSE); + A_ASSERT(false); status = A_EPROTO; break; } @@ -363,7 +363,7 @@ static int HTCProcessRecvHeader(HTC_TARGET *target, pPacket->pBuffer += HTC_HDR_LENGTH; pPacket->ActualLength -= HTC_HDR_LENGTH; - } while (FALSE); + } while (false); if (status) { /* dump the whole packet */ @@ -388,7 +388,7 @@ static int HTCProcessRecvHeader(HTC_TARGET *target, static INLINE void HTCAsyncRecvCheckMorePackets(HTC_TARGET *target, A_UINT32 NextLookAheads[], int NumLookAheads, - A_BOOL CheckMoreMsgs) + bool CheckMoreMsgs) { /* was there a lookahead for the next packet? */ if (NumLookAheads > 0) { @@ -454,7 +454,7 @@ static INLINE void DrainRecvIndicationQueue(HTC_TARGET *target, HTC_ENDPOINT *pE /******* at this point only 1 thread may enter ******/ - while (TRUE) { + while (true) { /* transfer items from main recv queue to the local one so we can release the lock */ HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&recvCompletions, &pEndpoint->RecvIndicationQueue); @@ -522,7 +522,7 @@ void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket) A_UINT32 nextLookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; int numLookAheads = 0; int status; - A_BOOL checkMorePkts = TRUE; + bool checkMorePkts = true; AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCRecvCompleteHandler (pkt:0x%lX, status:%d, ep:%d) \n", (unsigned long)pPacket, pPacket->Status, pPacket->Endpoint)); @@ -554,7 +554,7 @@ void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket) * It was fetched one message at a time. There may be other asynchronous reads queued behind this one. * Do no issue another check for more packets since the last one in the series of requests * will handle it */ - checkMorePkts = FALSE; + checkMorePkts = false; } DUMP_RECV_PKT_INFO(pPacket); @@ -568,7 +568,7 @@ void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket) /* check for more recv packets before indicating */ HTCAsyncRecvCheckMorePackets(target,nextLookAheads,numLookAheads,checkMorePkts); - } while (FALSE); + } while (false); if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, @@ -617,14 +617,14 @@ int HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket) if (pHdr->EndpointID != ENDPOINT_0) { /* unexpected endpoint number, should be zero */ - AR_DEBUG_ASSERT(FALSE); + AR_DEBUG_ASSERT(false); status = A_EPROTO; break; } if (status) { /* bad message */ - AR_DEBUG_ASSERT(FALSE); + AR_DEBUG_ASSERT(false); status = A_EPROTO; break; } @@ -632,7 +632,7 @@ int HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket) pPacket = HTC_ALLOC_CONTROL_RX(target); if (pPacket == NULL) { - AR_DEBUG_ASSERT(FALSE); + AR_DEBUG_ASSERT(false); status = A_NO_MEMORY; break; } @@ -642,7 +642,7 @@ int HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket) pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH; if (pPacket->ActualLength > pPacket->BufferLength) { - AR_DEBUG_ASSERT(FALSE); + AR_DEBUG_ASSERT(false); status = A_EPROTO; break; } @@ -672,7 +672,7 @@ int HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket) /* give the caller this control message packet, they are responsible to free */ *ppControlPacket = pPacket; - } while (FALSE); + } while (false); if (status) { if (pPacket != NULL) { @@ -698,7 +698,7 @@ static int AllocAndPrepareRxPackets(HTC_TARGET *target, int i,j; int numMessages; int fullLength; - A_BOOL noRecycle; + bool noRecycle; /* lock RX while we assemble the packet buffers */ LOCK_HTC_RX(target); @@ -759,11 +759,11 @@ static int AllocAndPrepareRxPackets(HTC_TARGET *target, /* reset flag, any packets allocated using the RecvAlloc() API cannot be recycled on cleanup, * they must be explicitly returned */ - noRecycle = FALSE; + noRecycle = false; if (pEndpoint->EpCallBacks.EpRecvAlloc != NULL) { UNLOCK_HTC_RX(target); - noRecycle = TRUE; + noRecycle = true; /* user is using a per-packet allocation callback */ pPacket = pEndpoint->EpCallBacks.EpRecvAlloc(pEndpoint->EpCallBacks.pContext, pEndpoint->Id, @@ -776,7 +776,7 @@ static int AllocAndPrepareRxPackets(HTC_TARGET *target, INC_HTC_EP_STAT(pEndpoint,RxAllocThreshBytes,pHdr->PayloadLen); /* threshold was hit, call the special recv allocation callback */ UNLOCK_HTC_RX(target); - noRecycle = TRUE; + noRecycle = true; /* user wants to allocate packets above a certain threshold */ pPacket = pEndpoint->EpCallBacks.EpRecvAllocThresh(pEndpoint->EpCallBacks.pContext, pEndpoint->Id, @@ -888,9 +888,9 @@ static void HTCAsyncRecvScatterCompletion(HIF_SCATTER_REQ *pScatterReq) int numLookAheads = 0; HTC_TARGET *target = (HTC_TARGET *)pScatterReq->Context; int status; - A_BOOL partialBundle = FALSE; + bool partialBundle = false; HTC_PACKET_QUEUE localRecvQueue; - A_BOOL procError = FALSE; + bool procError = false; AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCAsyncRecvScatterCompletion TotLen: %d Entries: %d\n", pScatterReq->TotalLength, pScatterReq->ValidScatterEntries)); @@ -902,7 +902,7 @@ static void HTCAsyncRecvScatterCompletion(HIF_SCATTER_REQ *pScatterReq) } if (pScatterReq->CallerFlags & HTC_SCATTER_REQ_FLAGS_PARTIAL_BUNDLE) { - partialBundle = TRUE; + partialBundle = true; } DEV_FINISH_SCATTER_OPERATION(pScatterReq); @@ -956,7 +956,7 @@ static void HTCAsyncRecvScatterCompletion(HIF_SCATTER_REQ *pScatterReq) /* recycle failed recv */ HTC_RECYCLE_RX_PKT(target, pPacket, pEndpoint); /* set flag and continue processing the remaining scatter entries */ - procError = TRUE; + procError = true; } } @@ -975,7 +975,7 @@ static void HTCAsyncRecvScatterCompletion(HIF_SCATTER_REQ *pScatterReq) HTCAsyncRecvCheckMorePackets(target, lookAheads, numLookAheads, - partialBundle ? FALSE : TRUE); + partialBundle ? false : true); } /* now drain the indication queue */ @@ -988,14 +988,14 @@ static int HTCIssueRecvPacketBundle(HTC_TARGET *target, HTC_PACKET_QUEUE *pRecvPktQueue, HTC_PACKET_QUEUE *pSyncCompletionQueue, int *pNumPacketsFetched, - A_BOOL PartialBundle) + bool PartialBundle) { int status = A_OK; HIF_SCATTER_REQ *pScatterReq; int i, totalLength; int pktsToScatter; HTC_PACKET *pPacket; - A_BOOL asyncMode = (pSyncCompletionQueue == NULL) ? TRUE : FALSE; + bool asyncMode = (pSyncCompletionQueue == NULL) ? true : false; int scatterSpaceRemaining = DEV_GET_MAX_BUNDLE_RECV_LENGTH(&target->Device); pktsToScatter = HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue); @@ -1004,7 +1004,7 @@ static int HTCIssueRecvPacketBundle(HTC_TARGET *target, if ((HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue) - pktsToScatter) > 0) { /* we were forced to split this bundle receive operation * all packets in this partial bundle must have their lookaheads ignored */ - PartialBundle = TRUE; + PartialBundle = true; /* this would only happen if the target ignored our max bundle limit */ AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HTCIssueRecvPacketBundle : partial bundle detected num:%d , %d \n", @@ -1094,7 +1094,7 @@ static int HTCIssueRecvPacketBundle(HTC_TARGET *target, DEV_FREE_SCATTER_REQ(&target->Device, pScatterReq); } - } while (FALSE); + } while (false); AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCIssueRecvPacketBundle (status:%d) (fetched:%d) \n", status,*pNumPacketsFetched)); @@ -1117,17 +1117,17 @@ static INLINE void CheckRecvWaterMark(HTC_ENDPOINT *pEndpoint) } /* callback when device layer or lookahead report parsing detects a pending message */ -int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int NumLookAheads, A_BOOL *pAsyncProc, int *pNumPktsFetched) +int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched) { HTC_TARGET *target = (HTC_TARGET *)Context; int status = A_OK; HTC_PACKET *pPacket; HTC_ENDPOINT *pEndpoint; - A_BOOL asyncProc = FALSE; + bool asyncProc = false; A_UINT32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; int pktsFetched; HTC_PACKET_QUEUE recvPktQueue, syncCompletedPktsQueue; - A_BOOL partialBundle; + bool partialBundle; HTC_ENDPOINT_ID id; int totalFetched = 0; @@ -1141,7 +1141,7 @@ int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int Nu /* We use async mode to get the packets if the device layer supports it. * The device layer interfaces with HIF in which HIF may have restrictions on * how interrupts are processed */ - asyncProc = TRUE; + asyncProc = true; } if (pAsyncProc != NULL) { @@ -1150,14 +1150,14 @@ int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int Nu } if (NumLookAheads > HTC_HOST_MAX_MSG_PER_BUNDLE) { - A_ASSERT(FALSE); + A_ASSERT(false); return A_EPROTO; } /* on first entry copy the lookaheads into our temp array for processing */ A_MEMCPY(lookAheads, MsgLookAheads, (sizeof(A_UINT32)) * NumLookAheads); - while (TRUE) { + while (true) { /* reset packets queues */ INIT_HTC_PACKET_QUEUE(&recvPktQueue); @@ -1165,7 +1165,7 @@ int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int Nu if (NumLookAheads > HTC_HOST_MAX_MSG_PER_BUNDLE) { status = A_EPROTO; - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -1200,7 +1200,7 @@ int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int Nu /* we've got packet buffers for all we can currently fetch, * this count is not valid anymore */ NumLookAheads = 0; - partialBundle = FALSE; + partialBundle = false; /* now go fetch the list of HTC packets */ while (!HTC_QUEUE_EMPTY(&recvPktQueue)) { @@ -1221,7 +1221,7 @@ int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int Nu if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) != 0) { /* we couldn't fetch all packets at one time, this creates a broken * bundle */ - partialBundle = TRUE; + partialBundle = true; } } @@ -1389,14 +1389,14 @@ int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); HTC_ENDPOINT *pEndpoint; - A_BOOL unblockRecv = FALSE; + bool unblockRecv = false; int status = A_OK; HTC_PACKET *pFirstPacket; pFirstPacket = HTC_GET_PKT_AT_HEAD(pPktQueue); if (NULL == pFirstPacket) { - A_ASSERT(FALSE); + A_ASSERT(false); return A_EINVAL; } @@ -1438,7 +1438,7 @@ int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) target->EpWaitingForBuffers)); target->RecvStateFlags &= ~HTC_RECV_WAIT_BUFFERS; target->EpWaitingForBuffers = ENDPOINT_MAX; - unblockRecv = TRUE; + unblockRecv = true; } } @@ -1449,7 +1449,7 @@ int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) DevEnableRecv(&target->Device,DEV_ENABLE_RECV_SYNC); } - } while (FALSE); + } while (false); return status; } @@ -1465,7 +1465,7 @@ int HTCAddReceivePkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket) void HTCUnblockRecv(HTC_HANDLE HTCHandle) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - A_BOOL unblockRecv = FALSE; + bool unblockRecv = false; LOCK_HTC_RX(target); @@ -1475,7 +1475,7 @@ void HTCUnblockRecv(HTC_HANDLE HTCHandle) target->EpWaitingForBuffers)); target->RecvStateFlags &= ~HTC_RECV_WAIT_BUFFERS; target->EpWaitingForBuffers = ENDPOINT_MAX; - unblockRecv = TRUE; + unblockRecv = true; } UNLOCK_HTC_RX(target); @@ -1565,7 +1565,7 @@ int HTCGetNumRecvBuffers(HTC_HANDLE HTCHandle, int HTCWaitForPendingRecv(HTC_HANDLE HTCHandle, A_UINT32 TimeoutInMs, - A_BOOL *pbIsRecvPending) + bool *pbIsRecvPending) { int status = A_OK; HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); diff --git a/drivers/staging/ath6kl/htc2/htc_send.c b/drivers/staging/ath6kl/htc2/htc_send.c index e645e2d3b434..a6b860a70532 100644 --- a/drivers/staging/ath6kl/htc2/htc_send.c +++ b/drivers/staging/ath6kl/htc2/htc_send.c @@ -72,7 +72,7 @@ static void DoSendCompletion(HTC_ENDPOINT *pEndpoint, } while (!HTC_QUEUE_EMPTY(pQueueToIndicate)); } - } while (FALSE); + } while (false); } @@ -116,11 +116,11 @@ static void HTCSendPktCompletionHandler(void *Context, HTC_PACKET *pPacket) int HTCIssueSend(HTC_TARGET *target, HTC_PACKET *pPacket) { int status; - A_BOOL sync = FALSE; + bool sync = false; if (pPacket->Completion == NULL) { /* mark that this request was synchronously issued */ - sync = TRUE; + sync = true; } AR_DEBUG_PRINTF(ATH_DEBUG_SEND, @@ -160,7 +160,7 @@ static INLINE void GetHTCSendPackets(HTC_TARGET *target, AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+GetHTCSendPackets \n")); /* loop until we can grab as many packets out of the queue as we can */ - while (TRUE) { + while (true) { sendFlags = 0; /* get packet at head, but don't remove it */ @@ -320,7 +320,7 @@ static void HTCIssueSendBundle(HTC_ENDPOINT *pEndpoint, int i, packetsInScatterReq; unsigned int transferLength; HTC_PACKET *pPacket; - A_BOOL done = FALSE; + bool done = false; int bundlesSent = 0; int totalPktsInBundle = 0; HTC_TARGET *target = pEndpoint->target; @@ -361,7 +361,7 @@ static void HTCIssueSendBundle(HTC_ENDPOINT *pEndpoint, pPacket = HTC_GET_PKT_AT_HEAD(pQueue); if (pPacket == NULL) { - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -400,7 +400,7 @@ static void HTCIssueSendBundle(HTC_ENDPOINT *pEndpoint, if (NULL == pPacket) { /* can't bundle */ - done = TRUE; + done = true; break; } @@ -571,7 +571,7 @@ static HTC_SEND_QUEUE_RESULT HTCTrySend(HTC_TARGET *target, } } - } while (FALSE); + } while (false); if (result != HTC_SEND_QUEUE_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend: \n")); @@ -602,7 +602,7 @@ static HTC_SEND_QUEUE_RESULT HTCTrySend(HTC_TARGET *target, /* now drain the endpoint TX queue for transmission as long as we have enough * credits */ - while (TRUE) { + while (true) { if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) == 0) { break; @@ -623,7 +623,7 @@ static HTC_SEND_QUEUE_RESULT HTCTrySend(HTC_TARGET *target, bundlesSent = 0; pktsInBundles = 0; - while (TRUE) { + while (true) { /* try to send a bundle on each pass */ if ((target->SendBundlingEnabled) && @@ -758,7 +758,7 @@ void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEnt int i; HTC_ENDPOINT *pEndpoint; int totalCredits = 0; - A_BOOL doDist = FALSE; + bool doDist = false; AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCProcessCreditRpt, Credit Report Entries:%d \n", NumEntries)); @@ -767,7 +767,7 @@ void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEnt for (i = 0; i < NumEntries; i++, pRpt++) { if (pRpt->EndpointID >= ENDPOINT_MAX) { - AR_DEBUG_ASSERT(FALSE); + AR_DEBUG_ASSERT(false); break; } @@ -807,7 +807,7 @@ void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEnt * will handle giving out credits back to the endpoints */ pEndpoint->CreditDist.TxCreditsToDist += pRpt->Credits; /* flag that we have to do the distribution */ - doDist = TRUE; + doDist = true; } /* refresh tx depth for distribution function that will recover these credits @@ -945,7 +945,7 @@ void HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG HTC_ENDPOINT *pEndpoint = &target->EndPoint[Endpoint]; if (pEndpoint->ServiceID == 0) { - AR_DEBUG_ASSERT(FALSE); + AR_DEBUG_ASSERT(false); /* not in use.. */ return; } @@ -956,14 +956,14 @@ void HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG /* HTC API to indicate activity to the credit distribution function */ void HTCIndicateActivityChange(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, - A_BOOL Active) + bool Active) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); HTC_ENDPOINT *pEndpoint = &target->EndPoint[Endpoint]; - A_BOOL doDist = FALSE; + bool doDist = false; if (pEndpoint->ServiceID == 0) { - AR_DEBUG_ASSERT(FALSE); + AR_DEBUG_ASSERT(false); /* not in use.. */ return; } @@ -974,13 +974,13 @@ void HTCIndicateActivityChange(HTC_HANDLE HTCHandle, if (!(pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE)) { /* mark active now */ pEndpoint->CreditDist.DistFlags |= HTC_EP_ACTIVE; - doDist = TRUE; + doDist = true; } } else { if (pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE) { /* mark inactive now */ pEndpoint->CreditDist.DistFlags &= ~HTC_EP_ACTIVE; - doDist = TRUE; + doDist = true; } } @@ -1005,19 +1005,19 @@ void HTCIndicateActivityChange(HTC_HANDLE HTCHandle, } } -A_BOOL HTCIsEndpointActive(HTC_HANDLE HTCHandle, +bool HTCIsEndpointActive(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); HTC_ENDPOINT *pEndpoint = &target->EndPoint[Endpoint]; if (pEndpoint->ServiceID == 0) { - return FALSE; + return false; } if (pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE) { - return TRUE; + return true; } - return FALSE; + return false; } diff --git a/drivers/staging/ath6kl/htc2/htc_services.c b/drivers/staging/ath6kl/htc2/htc_services.c index 63189b583618..5f01c2d19e1b 100644 --- a/drivers/staging/ath6kl/htc2/htc_services.c +++ b/drivers/staging/ath6kl/htc2/htc_services.c @@ -26,7 +26,7 @@ void HTCControlTxComplete(void *Context, HTC_PACKET *pPacket) { /* not implemented * we do not send control TX frames during normal runtime, only during setup */ - AR_DEBUG_ASSERT(FALSE); + AR_DEBUG_ASSERT(false); } /* callback when a control message arrives on this endpoint */ @@ -111,7 +111,7 @@ int HTCSendSetupComplete(HTC_TARGET *target) /* send the message */ status = HTCIssueSend(target,pSendPacket); - } while (FALSE); + } while (false); if (pSendPacket != NULL) { HTC_FREE_CONTROL_TX(target,pSendPacket); @@ -151,7 +151,7 @@ int HTCConnectService(HTC_HANDLE HTCHandle, pSendPacket = HTC_ALLOC_CONTROL_TX(target); if (NULL == pSendPacket) { - AR_DEBUG_ASSERT(FALSE); + AR_DEBUG_ASSERT(false); status = A_NO_MEMORY; break; } @@ -200,7 +200,7 @@ int HTCConnectService(HTC_HANDLE HTCHandle, if ((pResponseMsg->MessageID != HTC_MSG_CONNECT_SERVICE_RESPONSE_ID) || (pRecvPacket->ActualLength < sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG))) { /* this message is not valid */ - AR_DEBUG_ASSERT(FALSE); + AR_DEBUG_ASSERT(false); status = A_EPROTO; break; } @@ -236,12 +236,12 @@ int HTCConnectService(HTC_HANDLE HTCHandle, status = A_EPROTO; if (assignedEndpoint >= ENDPOINT_MAX) { - AR_DEBUG_ASSERT(FALSE); + AR_DEBUG_ASSERT(false); break; } if (0 == maxMsgSize) { - AR_DEBUG_ASSERT(FALSE); + AR_DEBUG_ASSERT(false); break; } @@ -249,7 +249,7 @@ int HTCConnectService(HTC_HANDLE HTCHandle, pEndpoint->Id = assignedEndpoint; if (pEndpoint->ServiceID != 0) { /* endpoint already in use! */ - AR_DEBUG_ASSERT(FALSE); + AR_DEBUG_ASSERT(false); break; } @@ -275,7 +275,7 @@ int HTCConnectService(HTC_HANDLE HTCHandle, * since the host will actually issue smaller messages in the Send path */ if (pConnectReq->MaxSendMsgSize > maxMsgSize) { /* can't be larger than the maximum the target can support */ - AR_DEBUG_ASSERT(FALSE); + AR_DEBUG_ASSERT(false); break; } pEndpoint->CreditDist.TxCreditsPerMaxMsg = pConnectReq->MaxSendMsgSize / target->TargetCreditSize; @@ -292,7 +292,7 @@ int HTCConnectService(HTC_HANDLE HTCHandle, status = A_OK; - } while (FALSE); + } while (false); if (pSendPacket != NULL) { HTC_FREE_CONTROL_TX(target,pSendPacket); @@ -360,7 +360,7 @@ static void HTCDefaultCreditInit(void *Context, if (creditsPerEndpoint < pCurEpDist->TxCreditsPerMaxMsg) { /* too many endpoints and not enough credits */ - AR_DEBUG_ASSERT(FALSE); + AR_DEBUG_ASSERT(false); break; } /* our minimum is set for at least 1 max message */ diff --git a/drivers/staging/ath6kl/include/a_drv_api.h b/drivers/staging/ath6kl/include/a_drv_api.h index 7d077c62ad70..5e098cb30f56 100644 --- a/drivers/staging/ath6kl/include/a_drv_api.h +++ b/drivers/staging/ath6kl/include/a_drv_api.h @@ -188,10 +188,10 @@ extern "C" { ar6000_dbglog_event((ar), (dropped), (buffer), (length)); #define A_WMI_STREAM_TX_ACTIVE(devt,trafficClass) \ - ar6000_indicate_tx_activity((devt),(trafficClass), TRUE) + ar6000_indicate_tx_activity((devt),(trafficClass), true) #define A_WMI_STREAM_TX_INACTIVE(devt,trafficClass) \ - ar6000_indicate_tx_activity((devt),(trafficClass), FALSE) + ar6000_indicate_tx_activity((devt),(trafficClass), false) #define A_WMI_Ac2EndpointID(devht, ac)\ ar6000_ac2_endpoint_id((devht), (ac)) diff --git a/drivers/staging/ath6kl/include/aggr_recv_api.h b/drivers/staging/ath6kl/include/aggr_recv_api.h index 0682bb4edcf1..d3140171ddc3 100644 --- a/drivers/staging/ath6kl/include/aggr_recv_api.h +++ b/drivers/staging/ath6kl/include/aggr_recv_api.h @@ -108,7 +108,7 @@ aggr_recv_delba_req_evt(void * cntxt, A_UINT8 tid); * callback may be called to deliver frames in order. */ void -aggr_process_recv_frm(void *cntxt, A_UINT8 tid, A_UINT16 seq_no, A_BOOL is_amsdu, void **osbuf); +aggr_process_recv_frm(void *cntxt, A_UINT8 tid, A_UINT16 seq_no, bool is_amsdu, void **osbuf); /* diff --git a/drivers/staging/ath6kl/include/bmi.h b/drivers/staging/ath6kl/include/bmi.h index 9b45dc312319..931ac408e3a0 100644 --- a/drivers/staging/ath6kl/include/bmi.h +++ b/drivers/staging/ath6kl/include/bmi.h @@ -126,7 +126,7 @@ int BMIRawRead(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length, - A_BOOL want_timeout); + bool want_timeout); #ifdef __cplusplus } diff --git a/drivers/staging/ath6kl/include/common/athdefs.h b/drivers/staging/ath6kl/include/common/athdefs.h index c6ae9ba84b6b..255c7ddf3081 100644 --- a/drivers/staging/ath6kl/include/common/athdefs.h +++ b/drivers/staging/ath6kl/include/common/athdefs.h @@ -73,12 +73,4 @@ #define A_PHY_ERROR 27 /* RX PHY error */ #define A_CONSUMED 28 /* Object was consumed */ -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - #endif /* __ATHDEFS_H__ */ diff --git a/drivers/staging/ath6kl/include/common_drv.h b/drivers/staging/ath6kl/include/common_drv.h index c6f0b2dc550a..8407c9f1627a 100644 --- a/drivers/staging/ath6kl/include/common_drv.h +++ b/drivers/staging/ath6kl/include/common_drv.h @@ -72,7 +72,7 @@ int ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data int ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, A_UCHAR *data, A_UINT32 length); -int ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_BOOL waitForCompletion, A_BOOL coldReset); +int ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType, bool waitForCompletion, bool coldReset); void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType); diff --git a/drivers/staging/ath6kl/include/hci_transport_api.h b/drivers/staging/ath6kl/include/hci_transport_api.h index b611ab1cef4c..9b8b9aa39777 100644 --- a/drivers/staging/ath6kl/include/hci_transport_api.h +++ b/drivers/staging/ath6kl/include/hci_transport_api.h @@ -153,9 +153,9 @@ int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUE @return: A_OK @notes: Caller must initialize packet using SET_HTC_PACKET_INFO_TX() and HCI_SET_PACKET_TYPE() macros to prepare the packet. - If Synchronous is set to FALSE the call is fully asynchronous. On error or completion, + If Synchronous is set to false the call is fully asynchronous. On error or completion, the registered send complete callback will be called. - If Synchronous is set to TRUE, the call will block until the packet is sent, if the + If Synchronous is set to true, the call will block until the packet is sent, if the interface cannot send the packet within a 2 second timeout, the function will return the failure code : A_EBUSY. @@ -166,7 +166,7 @@ int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUE @example: @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, A_BOOL Synchronous); +int HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, bool Synchronous); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -206,7 +206,7 @@ int HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans); @example: @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable); +int HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Receive an event packet from the HCI transport synchronously using polling @@ -217,7 +217,7 @@ int HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL @output: @return: A_OK on success @notes: This API should be used only during HCI device initialization, the caller must call - HCI_TransportEnableDisableAsyncRecv with Enable=FALSE prior to using this API. + HCI_TransportEnableDisableAsyncRecv with Enable=false prior to using this API. This API will only capture HCI Event packets. @example: @see also: HCI_TransportEnableDisableAsyncRecv @@ -250,7 +250,7 @@ int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud); @example: @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable); +int HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); #ifdef __cplusplus } diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h index 331d98515678..6a4d27007051 100644 --- a/drivers/staging/ath6kl/include/hif.h +++ b/drivers/staging/ath6kl/include/hif.h @@ -359,11 +359,11 @@ typedef int ( *HIF_PENDING_EVENTS_FUNC)(HIF_DEVICE *device, HIF_PENDING_EVENTS_INFO *pEvents, void *AsyncContext); -#define HIF_MASK_RECV TRUE -#define HIF_UNMASK_RECV FALSE +#define HIF_MASK_RECV true +#define HIF_UNMASK_RECV false /* function to mask recv events */ typedef int ( *HIF_MASK_UNMASK_RECV_EVENT)(HIF_DEVICE *device, - A_BOOL Mask, + bool Mask, void *AsyncContext); diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h index 94040bff7896..d9d4e2e71963 100644 --- a/drivers/staging/ath6kl/include/htc_api.h +++ b/drivers/staging/ath6kl/include/htc_api.h @@ -431,7 +431,7 @@ void HTCDumpCreditStates(HTC_HANDLE HTCHandle); @function name: HTCIndicateActivityChange @input: HTCHandle - HTC handle Endpoint - endpoint in which activity has changed - Active - TRUE if active, FALSE if it has become inactive + Active - true if active, false if it has become inactive @output: @return: @notes: This triggers the registered credit distribution function to @@ -441,7 +441,7 @@ void HTCDumpCreditStates(HTC_HANDLE HTCHandle); +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ void HTCIndicateActivityChange(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, - A_BOOL Active); + bool Active); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Get endpoint statistics @@ -452,9 +452,9 @@ void HTCIndicateActivityChange(HTC_HANDLE HTCHandle, @output: pStats - statistics that were sampled (can be NULL if Action is HTC_EP_STAT_CLEAR) - @return: TRUE if statistics profiling is enabled, otherwise FALSE. + @return: true if statistics profiling is enabled, otherwise false. - @notes: Statistics is a compile-time option and this function may return FALSE + @notes: Statistics is a compile-time option and this function may return false if HTC is not compiled with profiling. The caller can specify the statistic "action" to take when sampling @@ -469,7 +469,7 @@ void HTCIndicateActivityChange(HTC_HANDLE HTCHandle, @example: @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -A_BOOL HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, +bool HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_ENDPOINT_STAT_ACTION Action, HTC_ENDPOINT_STATS *pStats); @@ -538,12 +538,12 @@ int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueu @input: HTCHandle - HTC handle Endpoint - endpoint to check for active state @output: - @return: returns TRUE if Endpoint is Active + @return: returns true if Endpoint is Active @notes: @example: @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -A_BOOL HTCIsEndpointActive(HTC_HANDLE HTCHandle, +bool HTCIsEndpointActive(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint); @@ -566,7 +566,7 @@ void HTCEnableRecv(HTC_HANDLE HTCHandle); void HTCDisableRecv(HTC_HANDLE HTCHandle); int HTCWaitForPendingRecv(HTC_HANDLE HTCHandle, A_UINT32 TimeoutInMs, - A_BOOL *pbIsRecvPending); + bool *pbIsRecvPending); #ifdef __cplusplus } diff --git a/drivers/staging/ath6kl/include/wlan_api.h b/drivers/staging/ath6kl/include/wlan_api.h index 041df74e2db7..5114ff8bc179 100644 --- a/drivers/staging/ath6kl/include/wlan_api.h +++ b/drivers/staging/ath6kl/include/wlan_api.h @@ -109,7 +109,7 @@ wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt); bss_t * wlan_find_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid, - A_UINT32 ssidLength, A_BOOL bIsWPA2, A_BOOL bMatchSSID); + A_UINT32 ssidLength, bool bIsWPA2, bool bMatchSSID); void wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni); diff --git a/drivers/staging/ath6kl/include/wmi_api.h b/drivers/staging/ath6kl/include/wmi_api.h index 0d7d0cca7726..ee2270663a37 100644 --- a/drivers/staging/ath6kl/include/wmi_api.h +++ b/drivers/staging/ath6kl/include/wmi_api.h @@ -71,7 +71,7 @@ HTC_ENDPOINT_ID wmi_get_control_ep(struct wmi_t * wmip); void wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid); A_UINT16 wmi_get_mapped_qos_queue(struct wmi_t *, A_UINT8); int wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf); -int wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType, A_BOOL bMoreData, WMI_DATA_HDR_DATA_TYPE data_type,A_UINT8 metaVersion, void *pTxMetaS); +int wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType, bool bMoreData, WMI_DATA_HDR_DATA_TYPE data_type,A_UINT8 metaVersion, void *pTxMetaS); int wmi_dot3_2_dix(void *osbuf); int wmi_dot11_hdr_remove (struct wmi_t *wmip, void *osbuf); @@ -80,7 +80,7 @@ int wmi_dot11_hdr_add(struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode); int wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf); int wmi_syncpoint(struct wmi_t *wmip); int wmi_syncpoint_reset(struct wmi_t *wmip); -A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 layer2Priority, A_BOOL wmmEnabled); +A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 layer2Priority, bool wmmEnabled); A_UINT8 wmi_determine_userPriority (A_UINT8 *pkt, A_UINT32 layer2Pri); @@ -122,7 +122,7 @@ int wmi_reconnect_cmd(struct wmi_t *wmip, int wmi_disconnect_cmd(struct wmi_t *wmip); int wmi_getrev_cmd(struct wmi_t *wmip); int wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, - A_BOOL forceFgScan, A_BOOL isLegacy, + u32 forceFgScan, u32 isLegacy, A_UINT32 homeDwellTime, A_UINT32 forceScanInterval, A_INT8 numChan, A_UINT16 *channelList); int wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec, @@ -178,7 +178,7 @@ int wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie, A_UINT32 source); int wmi_config_debug_module_cmd(struct wmi_t *wmip, A_UINT16 mmask, - A_UINT16 tsr, A_BOOL rep, A_UINT16 size, + A_UINT16 tsr, bool rep, A_UINT16 size, A_UINT32 valid); int wmi_get_stats_cmd(struct wmi_t *wmip); @@ -201,9 +201,9 @@ int wmi_set_txPwr_cmd(struct wmi_t *wmip, A_UINT8 dbM); int wmi_get_txPwr_cmd(struct wmi_t *wmip); int wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid); int wmi_deleteBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex); -int wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, A_BOOL en); +int wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, bool en); int wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId, - A_BOOL set); + bool set); int wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT8 ac, A_UINT16 txop, A_UINT8 eCWmin, A_UINT8 eCWmax, A_UINT8 aifsn); @@ -323,7 +323,7 @@ wmi_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 enable); bss_t * wmi_find_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid, - A_UINT32 ssidLength, A_BOOL bIsWPA2, A_BOOL bMatchSSID); + A_UINT32 ssidLength, bool bIsWPA2, bool bMatchSSID); void @@ -375,7 +375,7 @@ int wmi_ap_set_mlme(struct wmi_t *wmip, A_UINT8 cmd, A_UINT8 *mac, A_UINT16 reason); int -wmi_set_pvb_cmd(struct wmi_t *wmip, A_UINT16 aid, A_BOOL flag); +wmi_set_pvb_cmd(struct wmi_t *wmip, A_UINT16 aid, bool flag); int wmi_ap_conn_inact_time(struct wmi_t *wmip, A_UINT32 period); @@ -405,16 +405,16 @@ int wmi_setup_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid); int -wmi_delete_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid, A_BOOL uplink); +wmi_delete_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid, bool uplink); int wmi_allow_aggr_cmd(struct wmi_t *wmip, A_UINT16 tx_tidmask, A_UINT16 rx_tidmask); int -wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, A_UINT8 rxMetaVersion, A_BOOL rxDot11Hdr, A_BOOL defragOnHost); +wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, A_UINT8 rxMetaVersion, bool rxDot11Hdr, bool defragOnHost); int -wmi_set_thin_mode_cmd(struct wmi_t *wmip, A_BOOL bThinMode); +wmi_set_thin_mode_cmd(struct wmi_t *wmip, bool bThinMode); int wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence); diff --git a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c index 4bdc48925ebc..f61dd44a2626 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c @@ -73,9 +73,9 @@ static int SendHCICommand(AR3K_CONFIG_INFO *pConfig, AR6K_CONTROL_PKT_TAG); /* issue synchronously */ - status = HCI_TransportSendPkt(pConfig->pHCIDev,pPacket,TRUE); + status = HCI_TransportSendPkt(pConfig->pHCIDev,pPacket,true); - } while (FALSE); + } while (false); if (pPacket != NULL) { A_FREE(pPacket); @@ -113,7 +113,7 @@ static int RecvHCIEvent(AR3K_CONFIG_INFO *pConfig, *pLength = pRecvPacket->ActualLength; - } while (FALSE); + } while (false); if (pRecvPacket != NULL) { A_FREE(pRecvPacket); @@ -132,7 +132,7 @@ int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, A_UINT8 *pBuffer = NULL; A_UINT8 *pTemp; int length; - A_BOOL commandComplete = FALSE; + bool commandComplete = false; A_UINT8 opCodeBytes[2]; do { @@ -177,7 +177,7 @@ int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, if (pTemp[0] == HCI_CMD_COMPLETE_EVENT_CODE) { if ((pTemp[HCI_EVENT_OPCODE_BYTE_LOW] == opCodeBytes[0]) && (pTemp[HCI_EVENT_OPCODE_BYTE_HI] == opCodeBytes[1])) { - commandComplete = TRUE; + commandComplete = true; } } @@ -200,7 +200,7 @@ int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, pBuffer = NULL; } - } while (FALSE); + } while (false); if (pBuffer != NULL) { A_FREE(pBuffer); @@ -265,7 +265,7 @@ static int AR3KConfigureHCIBaud(AR3K_CONFIG_INFO *pConfig) ("AR3K Config: Baud changed to %d for AR6K\n", pConfig->AR3KBaudRate)); } - } while (FALSE); + } while (false); if (pBufferToFree != NULL) { A_FREE(pBufferToFree); @@ -467,7 +467,7 @@ int AR3KConfigure(AR3K_CONFIG_INFO *pConfig) } /* disable asynchronous recv while we issue commands and receive events synchronously */ - status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,FALSE); + status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,false); if (status) { break; } @@ -507,13 +507,13 @@ int AR3KConfigure(AR3K_CONFIG_INFO *pConfig) } /* re-enable asynchronous recv */ - status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,TRUE); + status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,true); if (status) { break; } - } while (FALSE); + } while (false); AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Configuration Complete (status = %d) \n",status)); @@ -536,7 +536,7 @@ int AR3KConfigureExit(void *config) } /* disable asynchronous recv while we issue commands and receive events synchronously */ - status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,FALSE); + status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,false); if (status) { break; } @@ -550,13 +550,13 @@ int AR3KConfigureExit(void *config) } /* re-enable asynchronous recv */ - status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,TRUE); + status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,true); if (status) { break; } - } while (FALSE); + } while (false); AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Cleanup Complete (status = %d) \n",status)); diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c index e2a67fcfe3c8..e87f598a0ca0 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c @@ -54,7 +54,7 @@ int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, A_UINT32 Rom_Version; A_UINT32 Build_Version; -extern A_BOOL BDADDR; +extern bool BDADDR; int getDeviceType(AR3K_CONFIG_INFO *pConfig, A_UINT32 * code); int ReadVersionInfo(AR3K_CONFIG_INFO *pConfig); @@ -118,7 +118,7 @@ int AthPSInitialize(AR3K_CONFIG_INFO *hdev) remove_wait_queue(&PsCompleteEvent,&wait); return A_ERROR; } - wait_event_interruptible(PsCompleteEvent,(PSTagMode == FALSE)); + wait_event_interruptible(PsCompleteEvent,(PSTagMode == false)); set_current_state(TASK_RUNNING); remove_wait_queue(&PsCompleteEvent,&wait); @@ -157,7 +157,7 @@ int PSSendOps(void *arg) #else device = hdev; firmwareDev = &device->dev; - AthEnableSyncCommandOp(TRUE); + AthEnableSyncCommandOp(true); #endif /* HCI_TRANSPORT_SDIO */ /* First verify if the controller is an FPGA or ASIC, so depending on the device type the PS file to be written will be different. */ @@ -326,7 +326,7 @@ int PSSendOps(void *arg) } } #ifdef HCI_TRANSPORT_SDIO - if(BDADDR == FALSE) + if(BDADDR == false) if(hdev->bdaddr[0] !=0x00 || hdev->bdaddr[1] !=0x00 || hdev->bdaddr[2] !=0x00 || @@ -368,8 +368,8 @@ int PSSendOps(void *arg) } complete: #ifndef HCI_TRANSPORT_SDIO - AthEnableSyncCommandOp(FALSE); - PSTagMode = FALSE; + AthEnableSyncCommandOp(false); + PSTagMode = false; wake_up_interruptible(&PsCompleteEvent); #endif /* HCI_TRANSPORT_SDIO */ if(NULL != HciCmdList) { @@ -399,13 +399,13 @@ int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, return A_ERROR; } Hci_log("COM Write -->",pHCICommand,CmdLength); - PSAcked = FALSE; + PSAcked = false; if(PSHciWritepacket(pConfig,pHCICommand,CmdLength) == 0) { /* If the controller is not available, return Error */ return A_ERROR; } //add_timer(&psCmdTimer); - wait_event_interruptible(HciEvent,(PSAcked == TRUE)); + wait_event_interruptible(HciEvent,(PSAcked == true)); if(NULL != HciEventpacket) { *ppEventBuffer = HciEventpacket; *ppBufferToFree = HciEventpacket; diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c index 5df17661c4a1..b3013c58d83a 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c @@ -102,7 +102,7 @@ typedef struct tRamPatch typedef struct ST_PS_DATA_FORMAT { enum eType eDataType; - A_BOOL bIsArray; + bool bIsArray; }ST_PS_DATA_FORMAT; typedef struct ST_READ_STATUS { @@ -120,7 +120,7 @@ static A_UINT32 Tag_Count = 0; /* Stores the number of patch commands */ static A_UINT32 Patch_Count = 0; static A_UINT32 Total_tag_lenght = 0; -A_BOOL BDADDR = FALSE; +bool BDADDR = false; A_UINT32 StartTagId; tPsTagEntry PsTagEntry[RAMPS_MAX_PS_TAGS_PER_FILE]; @@ -663,12 +663,12 @@ int AthDoParsePS(A_UCHAR *srcbuffer, A_UINT32 srclen) { int status; int i; - A_BOOL BDADDR_Present = FALSE; + bool BDADDR_Present = false; Tag_Count = 0; Total_tag_lenght = 0; - BDADDR = FALSE; + BDADDR = false; status = A_ERROR; @@ -689,7 +689,7 @@ int AthDoParsePS(A_UCHAR *srcbuffer, A_UINT32 srclen) else{ for(i=0; iCurrentFreeCredits <= 0) { AR_DEBUG_PRINTF(ATH_LOG_INF, ("Not enough credits (%d) to do credit distributions \n", TotalCredits)); - A_ASSERT(FALSE); + A_ASSERT(false); return; } @@ -382,7 +382,7 @@ static void SeekCredits(COMMON_CREDIT_STATE_INFO *pCredInfo, /* return what we can get */ credits = min(pCredInfo->CurrentFreeCredits,pEPDist->TxCreditsSeek); - } while (FALSE); + } while (false); /* did we find some credits? */ if (credits) { diff --git a/drivers/staging/ath6kl/os/linux/ar6000_android.c b/drivers/staging/ath6kl/os/linux/ar6000_android.c index ce1a94c38ff7..7759a3d8703f 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_android.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_android.c @@ -29,7 +29,7 @@ #include #endif -A_BOOL enable_mmc_host_detect_change = FALSE; +bool enable_mmc_host_detect_change = false; static void ar6000_enable_mmchost_detect_change(int enable); @@ -336,21 +336,21 @@ void android_module_exit(void) } #ifdef CONFIG_PM -void android_ar6k_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, A_BOOL isEvent) +void android_ar6k_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, bool isEvent) { if ( #ifdef CONFIG_HAS_EARLYSUSPEND screen_is_off && #endif skb && ar->arConnected) { - A_BOOL needWake = FALSE; + bool needWake = false; if (isEvent) { if (A_NETBUF_LEN(skb) >= sizeof(A_UINT16)) { A_UINT16 cmd = *(const A_UINT16 *)A_NETBUF_DATA(skb); switch (cmd) { case WMI_CONNECT_EVENTID: case WMI_DISCONNECT_EVENTID: - needWake = TRUE; + needWake = true; break; default: /* dont wake lock the system for other event */ @@ -365,7 +365,7 @@ void android_ar6k_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, A_BOOL i case 0x888e: /* EAPOL */ case 0x88c7: /* RSN_PREAUTH */ case 0x88b4: /* WAPI */ - needWake = TRUE; + needWake = true; break; case 0x0806: /* ARP is not important to hold wake lock */ default: diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 5a5e0852b9e7..5bf505ca4a2c 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -102,7 +102,7 @@ MODULE_LICENSE("Dual BSD/GPL"); #define APTC_LOWER_THROUGHPUT_THRESHOLD 2000 /* Kbps */ typedef struct aptc_traffic_record { - A_BOOL timerScheduled; + bool timerScheduled; struct timeval samplingTS; unsigned long bytesReceived; unsigned long bytesTransmitted; @@ -449,7 +449,7 @@ dbglog_get_debug_hdr_ptr(AR_SOFTC_T *ar) void ar6000_dbglog_init_done(AR_SOFTC_T *ar) { - ar->dbglog_init_done = TRUE; + ar->dbglog_init_done = true; } A_UINT32 @@ -540,7 +540,7 @@ ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar) } /* block out others */ - ar->dbgLogFetchInProgress = TRUE; + ar->dbgLogFetchInProgress = true; AR6000_SPIN_UNLOCK(&ar->arLock, 0); @@ -592,7 +592,7 @@ ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar) } while (address != firstbuf); } - ar->dbgLogFetchInProgress = FALSE; + ar->dbgLogFetchInProgress = false; return A_OK; } @@ -757,12 +757,12 @@ aptcTimerHandler(unsigned long arg) throughput = ((numbytes * 8)/APTC_TRAFFIC_SAMPLING_INTERVAL); /* Kbps */ if (throughput < APTC_LOWER_THROUGHPUT_THRESHOLD) { /* Enable Sleep and delete the timer */ - A_ASSERT(ar->arWmiReady == TRUE); + A_ASSERT(ar->arWmiReady == true); AR6000_SPIN_UNLOCK(&ar->arLock, 0); status = wmi_powermode_cmd(ar->arWmi, REC_POWER); AR6000_SPIN_LOCK(&ar->arLock, 0); A_ASSERT(status == A_OK); - aptcTR.timerScheduled = FALSE; + aptcTR.timerScheduled = false; } else { A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0); } @@ -818,7 +818,7 @@ ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj, if (index == MAX_AR6000) return 0; - if ((BMIRawRead(ar->arHifDevice, (A_UCHAR*)buf, count, TRUE)) != A_OK) { + if ((BMIRawRead(ar->arHifDevice, (A_UCHAR*)buf, count, true)) != A_OK) { return 0; } @@ -994,7 +994,7 @@ ar6000_softmac_update(AR_SOFTC_T *ar, A_UCHAR *eeprom_data, size_t size) #endif /* SOFTMAC_FILE_USED */ static int -ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, A_BOOL compressed) +ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, bool compressed) { int status; const char *filename; @@ -1034,7 +1034,7 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, A ar->arVersion.target_ver)); return A_ERROR; } - compressed = FALSE; + compressed = false; } #ifdef CONFIG_HOST_TCMD_SUPPORT @@ -1047,7 +1047,7 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, A AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver)); return A_ERROR; } - compressed = FALSE; + compressed = false; } #endif #ifdef HTC_RAW_INTERFACE @@ -1060,7 +1060,7 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, A AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver)); return A_ERROR; } - compressed = FALSE; + compressed = false; } #endif break; @@ -1286,7 +1286,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode) AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board Data download address: 0x%x\n", address)); /* Write EEPROM data to Target RAM */ - if ((ar6000_transfer_bin_file(ar, AR6K_BOARD_DATA_FILE, address, FALSE)) != A_OK) { + if ((ar6000_transfer_bin_file(ar, AR6K_BOARD_DATA_FILE, address, false)) != A_OK) { return A_ERROR; } @@ -1296,7 +1296,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode) /* Transfer One time Programmable data */ AR6K_DATA_DOWNLOAD_ADDRESS(address, ar->arVersion.target_ver); - status = ar6000_transfer_bin_file(ar, AR6K_OTP_FILE, address, TRUE); + status = ar6000_transfer_bin_file(ar, AR6K_OTP_FILE, address, true); if (status == A_OK) { /* Execute the OTP code */ param = 0; @@ -1312,7 +1312,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode) /* Download Target firmware */ AR6K_DATA_DOWNLOAD_ADDRESS(address, ar->arVersion.target_ver); - if ((ar6000_transfer_bin_file(ar, AR6K_FIRMWARE_FILE, address, TRUE)) != A_OK) { + if ((ar6000_transfer_bin_file(ar, AR6K_FIRMWARE_FILE, address, true)) != A_OK) { return A_ERROR; } @@ -1322,7 +1322,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode) /* Apply the patches */ AR6K_PATCH_DOWNLOAD_ADDRESS(address, ar->arVersion.target_ver); - if ((ar6000_transfer_bin_file(ar, AR6K_PATCH_FILE, address, FALSE)) != A_OK) { + if ((ar6000_transfer_bin_file(ar, AR6K_PATCH_FILE, address, false)) != A_OK) { return A_ERROR; } @@ -1685,10 +1685,10 @@ ar6000_avail_ev(void *context, void *hif_handle) ar->arDeviceIndex = device_index; ar->arWlanPowerState = WLAN_POWER_STATE_ON; - ar->arWlanOff = FALSE; /* We are in ON state */ + ar->arWlanOff = false; /* We are in ON state */ #ifdef CONFIG_PM ar->arWowState = WLAN_WOW_STATE_NONE; - ar->arBTOff = TRUE; /* BT chip assumed to be OFF */ + ar->arBTOff = true; /* BT chip assumed to be OFF */ ar->arBTSharing = WLAN_CONFIG_BT_SHARING; ar->arWlanOffConfig = WLAN_CONFIG_WLAN_OFF; ar->arSuspendConfig = WLAN_CONFIG_PM_SUSPEND; @@ -1697,7 +1697,7 @@ ar6000_avail_ev(void *context, void *hif_handle) A_INIT_TIMER(&ar->arHBChallengeResp.timer, ar6000_detect_error, dev); ar->arHBChallengeResp.seqNum = 0; - ar->arHBChallengeResp.outstanding = FALSE; + ar->arHBChallengeResp.outstanding = false; ar->arHBChallengeResp.missCnt = 0; ar->arHBChallengeResp.frequency = AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT; ar->arHBChallengeResp.missThres = AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT; @@ -1705,7 +1705,7 @@ ar6000_avail_ev(void *context, void *hif_handle) ar6000_init_control_info(ar); init_waitqueue_head(&arEvent); sema_init(&ar->arSem, 1); - ar->bIsDestroyProgress = FALSE; + ar->bIsDestroyProgress = false; INIT_HTC_PACKET_QUEUE(&ar->amsdu_rx_buffer_queue); @@ -1813,7 +1813,7 @@ ar6000_avail_ev(void *context, void *hif_handle) if (status != A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_init\n")); } - } while (FALSE); + } while (false); if (status != A_OK) { init_status = status; @@ -1852,7 +1852,7 @@ static void ar6000_target_failure(void *Instance, int Status) { AR_SOFTC_T *ar = (AR_SOFTC_T *)Instance; WMI_TARGET_ERROR_REPORT_EVENT errEvent; - static A_BOOL sip = FALSE; + static bool sip = false; if (Status != A_OK) { @@ -1873,7 +1873,7 @@ static void ar6000_target_failure(void *Instance, int Status) /* Report the error only once */ if (!sip) { - sip = TRUE; + sip = true; errEvent.errorVal = WMI_TARGET_COM_ERR | WMI_TARGET_FATAL_ERR; ar6000_send_event_to_app(ar, WMI_ERROR_REPORT_EVENTID, @@ -1930,7 +1930,7 @@ ar6000_restart_endpoint(struct net_device *dev) } void -ar6000_stop_endpoint(struct net_device *dev, A_BOOL keepprofile, A_BOOL getdbglogs) +ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); @@ -1938,11 +1938,11 @@ ar6000_stop_endpoint(struct net_device *dev, A_BOOL keepprofile, A_BOOL getdbglo netif_stop_queue(dev); /* Disable the target and the interrupts associated with it */ - if (ar->arWmiReady == TRUE) + if (ar->arWmiReady == true) { if (!bypasswmi) { - if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) + if (ar->arConnected == true || ar->arConnectPending == true) { AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): Disconnect\n", __func__)); if (!keepprofile) { @@ -1959,9 +1959,9 @@ ar6000_stop_endpoint(struct net_device *dev, A_BOOL keepprofile, A_BOOL getdbglo ar6000_dbglog_get_debug_logs(ar); } - ar->arWmiReady = FALSE; + ar->arWmiReady = false; wmi_shutdown(ar->arWmi); - ar->arWmiEnabled = FALSE; + ar->arWmiEnabled = false; ar->arWmi = NULL; /* * After wmi_shudown all WMI events will be dropped. @@ -1972,14 +1972,14 @@ ar6000_stop_endpoint(struct net_device *dev, A_BOOL keepprofile, A_BOOL getdbglo * Sometimes disconnect_event will be received when the debug logs * are collected. */ - if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) { + if (ar->arConnected == true || ar->arConnectPending == true) { if(ar->arNetworkType & AP_NETWORK) { ar6000_disconnect_event(ar, DISCONNECT_CMD, bcast_mac, 0, NULL, 0); } else { ar6000_disconnect_event(ar, DISCONNECT_CMD, ar->arBssid, 0, NULL, 0); } - ar->arConnected = FALSE; - ar->arConnectPending = FALSE; + ar->arConnected = false; + ar->arConnectPending = false; } #ifdef USER_KEYS ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT; @@ -1995,11 +1995,11 @@ ar6000_stop_endpoint(struct net_device *dev, A_BOOL keepprofile, A_BOOL getdbglo __func__, (unsigned long) ar, (unsigned long) ar->arWmi)); /* Shut down WMI if we have started it */ - if(ar->arWmiEnabled == TRUE) + if(ar->arWmiEnabled == true) { AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): Shut down WMI\n", __func__)); wmi_shutdown(ar->arWmi); - ar->arWmiEnabled = FALSE; + ar->arWmiEnabled = false; ar->arWmi = NULL; } } @@ -2046,8 +2046,8 @@ ar6000_stop_endpoint(struct net_device *dev, A_BOOL keepprofile, A_BOOL getdbglo * a debug session */ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Attempting to reset target on instance destroy.... \n")); if (ar->arHifDevice != NULL) { - A_BOOL coldReset = (ar->arTargetType == TARGET_TYPE_AR6003) ? TRUE: FALSE; - ar6000_reset_device(ar->arHifDevice, ar->arTargetType, TRUE, coldReset); + bool coldReset = (ar->arTargetType == TARGET_TYPE_AR6003) ? true: false; + ar6000_reset_device(ar->arHifDevice, ar->arTargetType, true, coldReset); } } else { AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Host does not want target reset. \n")); @@ -2082,7 +2082,7 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister) return; } - ar->bIsDestroyProgress = TRUE; + ar->bIsDestroyProgress = true; if (down_interruptible(&ar->arSem)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s(): down_interruptible failed \n", __func__)); @@ -2091,7 +2091,7 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister) if (ar->arWlanPowerState != WLAN_POWER_STATE_CUT_PWR) { /* only stop endpoint if we are not stop it in suspend_ev */ - ar6000_stop_endpoint(dev, FALSE, TRUE); + ar6000_stop_endpoint(dev, false, true); } else { /* clear up the platform power state before rmmod */ plat_setup_power(1,0); @@ -2193,7 +2193,7 @@ static void ar6000_detect_error(unsigned long ptr) /* Generate the sequence number for the next challenge */ ar->arHBChallengeResp.seqNum++; - ar->arHBChallengeResp.outstanding = TRUE; + ar->arHBChallengeResp.outstanding = true; AR6000_SPIN_UNLOCK(&ar->arLock, 0); @@ -2234,13 +2234,13 @@ void ar6000_init_profile_info(AR_SOFTC_T *ar) A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); A_MEMZERO(ar->arBssid, sizeof(ar->arBssid)); ar->arBssChannel = 0; - ar->arConnected = FALSE; + ar->arConnected = false; } static void ar6000_init_control_info(AR_SOFTC_T *ar) { - ar->arWmiEnabled = FALSE; + ar->arWmiEnabled = false; ar6000_init_profile_info(ar); ar->arDefTxKeyIndex = 0; A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList)); @@ -2250,12 +2250,12 @@ ar6000_init_control_info(AR_SOFTC_T *ar) ar->arVersion.host_ver = AR6K_SW_VERSION; ar->arRssi = 0; ar->arTxPwr = 0; - ar->arTxPwrSet = FALSE; + ar->arTxPwrSet = false; ar->arSkipScan = 0; ar->arBeaconInterval = 0; ar->arBitRate = 0; ar->arMaxRetries = 0; - ar->arWmmEnabled = TRUE; + ar->arWmmEnabled = true; ar->intra_bss = 1; ar->scan_triggered = 0; A_MEMZERO(&ar->scParams, sizeof(ar->scParams)); @@ -2322,14 +2322,14 @@ ar6000_close(struct net_device *dev) #ifdef ATH6K_CONFIG_CFG80211 AR6000_SPIN_LOCK(&ar->arLock, 0); - if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) { + if (ar->arConnected == true || ar->arConnectPending == true) { AR6000_SPIN_UNLOCK(&ar->arLock, 0); wmi_disconnect_cmd(ar->arWmi); } else { AR6000_SPIN_UNLOCK(&ar->arLock, 0); } - if(ar->arWmiReady == TRUE) { + if(ar->arWmiReady == true) { if (wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0) != A_OK) { return -EIO; @@ -2389,7 +2389,7 @@ static int ar6000_connectservice(AR_SOFTC_T *ar, break; } - } while (FALSE); + } while (false); return status; } @@ -2480,7 +2480,7 @@ int ar6000_init(struct net_device *dev) #endif /* Indicate that WMI is enabled (although not ready yet) */ - ar->arWmiEnabled = TRUE; + ar->arWmiEnabled = true; if ((ar->arWmi = wmi_init((void *) ar)) == NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize WMI.\n", __func__)); @@ -2632,7 +2632,7 @@ int ar6000_init(struct net_device *dev) status = ar6k_setup_hci_pal(ar); #endif - } while (FALSE); + } while (false); if (status) { ret = -EIO; @@ -2670,9 +2670,9 @@ int ar6000_init(struct net_device *dev) status = HTCStart(ar->arHtcTarget); if (status != A_OK) { - if (ar->arWmiEnabled == TRUE) { + if (ar->arWmiEnabled == true) { wmi_shutdown(ar->arWmi); - ar->arWmiEnabled = FALSE; + ar->arWmiEnabled = false; ar->arWmi = NULL; } ar6000_cookie_cleanup(ar); @@ -2683,7 +2683,7 @@ int ar6000_init(struct net_device *dev) if (!bypasswmi) { /* Wait for Wmi event to be ready */ timeleft = wait_event_interruptible_timeout(arEvent, - (ar->arWmiReady == TRUE), wmitimeout * HZ); + (ar->arWmiReady == true), wmitimeout * HZ); if (ar->arVersion.abi_ver != AR6K_ABI_VERSION) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ABI Version mismatch: Host(0x%x), Target(0x%x)\n", AR6K_ABI_VERSION, ar->arVersion.abi_ver)); @@ -2708,7 +2708,7 @@ int ar6000_init(struct net_device *dev) } /* configure the device for rx dot11 header rules 0,0 are the default values - * therefore this command can be skipped if the inputs are 0,FALSE,FALSE.Required + * therefore this command can be skipped if the inputs are 0,false,false.Required if checksum offload is needed. Set RxMetaVersion to 2*/ if ((wmi_set_rx_frame_format_cmd(ar->arWmi,ar->rxMetaVersion, processDot11Hdr, processDot11Hdr)) != A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the rx frame format.\n")); @@ -2893,7 +2893,7 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) A_UINT32 mapNo = 0; int len; struct ar_cookie *cookie; - A_BOOL checkAdHocPsMapping = FALSE,bMoreData = FALSE; + bool checkAdHocPsMapping = false,bMoreData = false; HTC_TX_TAG htc_tag = AR6K_DATA_PKT_TAG; A_UINT8 dot11Hdr = processDot11Hdr; #ifdef CONFIG_PM @@ -2920,7 +2920,7 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) do { - if (ar->arWmiReady == FALSE && bypasswmi == 0) { + if (ar->arWmiReady == false && bypasswmi == 0) { break; } @@ -2943,19 +2943,19 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) */ if (IEEE80211_IS_MULTICAST(datap->dstMac)) { A_UINT8 ctr=0; - A_BOOL qMcast=FALSE; + bool qMcast=false; for (ctr=0; ctrsta_list[ctr]))) { - qMcast = TRUE; + qMcast = true; } } if(qMcast) { /* If this transmit is not because of a Dtim Expiry q it */ - if (ar->DTIMExpired == FALSE) { - A_BOOL isMcastqEmpty = FALSE; + if (ar->DTIMExpired == false) { + bool isMcastqEmpty = false; A_MUTEX_LOCK(&ar->mcastpsqLock); isMcastqEmpty = A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq); @@ -2976,7 +2976,7 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) */ A_MUTEX_LOCK(&ar->mcastpsqLock); if(!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) { - bMoreData = TRUE; + bMoreData = true; } A_MUTEX_UNLOCK(&ar->mcastpsqLock); } @@ -2987,7 +2987,7 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) if (STA_IS_PWR_SLEEP(conn)) { /* If this transmit is not because of a PsPoll q it*/ if (!STA_IS_PS_POLLED(conn)) { - A_BOOL isPsqEmpty = FALSE; + bool isPsqEmpty = false; /* Queue the frames if the STA is sleeping */ A_MUTEX_LOCK(&conn->psqLock); isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq); @@ -3008,7 +3008,7 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) */ A_MUTEX_LOCK(&conn->psqLock); if (!A_NETBUF_QUEUE_EMPTY(&conn->psq)) { - bMoreData = TRUE; + bMoreData = true; } A_MUTEX_UNLOCK(&conn->psqLock); } @@ -3089,7 +3089,7 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable && ar->arConnected) { /* flag to check adhoc mapping once we take the lock below: */ - checkAdHocPsMapping = TRUE; + checkAdHocPsMapping = true; } else { /* get the stream mapping */ @@ -3134,7 +3134,7 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) } } - } while (FALSE); + } while (false); /* did we succeed ? */ if ((ac == AC_NOT_MAPPED) && !checkAdHocPsMapping) { @@ -3171,7 +3171,7 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) ar->arTotalTxDataPending++; } - } while (FALSE); + } while (false); AR6000_SPIN_UNLOCK(&ar->arLock, 0); @@ -3290,12 +3290,12 @@ applyAPTCHeuristics(AR_SOFTC_T *ar) throughput = ((numbytes * 8) / duration); if (throughput > APTC_UPPER_THROUGHPUT_THRESHOLD) { /* Disable Sleep and schedule a timer */ - A_ASSERT(ar->arWmiReady == TRUE); + A_ASSERT(ar->arWmiReady == true); AR6000_SPIN_UNLOCK(&ar->arLock, 0); status = wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER); AR6000_SPIN_LOCK(&ar->arLock, 0); A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0); - aptcTR.timerScheduled = TRUE; + aptcTR.timerScheduled = true; } } } @@ -3308,7 +3308,7 @@ static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, HTC_PACKET *pPac { AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; HTC_SEND_FULL_ACTION action = HTC_SEND_FULL_KEEP; - A_BOOL stopNet = FALSE; + bool stopNet = false; HTC_ENDPOINT_ID Endpoint = HTC_GET_ENDPOINT_FROM_PKT(pPacket); do { @@ -3325,10 +3325,10 @@ static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, HTC_PACKET *pPac /* for endpoint ping testing drop Best Effort and Background */ if ((accessClass == WMM_AC_BE) || (accessClass == WMM_AC_BK)) { action = HTC_SEND_FULL_DROP; - stopNet = FALSE; + stopNet = false; } else { /* keep but stop the netqueues */ - stopNet = TRUE; + stopNet = true; } break; } @@ -3339,11 +3339,11 @@ static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, HTC_PACKET *pPac * the only exception to this is during testing using endpointping */ AR6000_SPIN_LOCK(&ar->arLock, 0); /* set flag to handle subsequent messages */ - ar->arWMIControlEpFull = TRUE; + ar->arWMIControlEpFull = true; AR6000_SPIN_UNLOCK(&ar->arLock, 0); AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI Control Endpoint is FULL!!! \n")); /* no need to stop the network */ - stopNet = FALSE; + stopNet = false; break; } @@ -3357,7 +3357,7 @@ static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, HTC_PACKET *pPac if (ar->arNetworkType == ADHOC_NETWORK) { /* in adhoc mode, we cannot differentiate traffic priorities so there is no need to * continue, however we should stop the network */ - stopNet = TRUE; + stopNet = true; break; } /* the last MAX_HI_COOKIE_NUM "batch" of cookies are reserved for the highest @@ -3369,15 +3369,15 @@ static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, HTC_PACKET *pPac * HTC to drop the packet that overflowed */ action = HTC_SEND_FULL_DROP; /* since we are dropping packets, no need to stop the network */ - stopNet = FALSE; + stopNet = false; break; } - } while (FALSE); + } while (false); if (stopNet) { AR6000_SPIN_LOCK(&ar->arLock, 0); - ar->arNetQueueStopped = TRUE; + ar->arNetQueueStopped = true; AR6000_SPIN_UNLOCK(&ar->arLock, 0); /* one of the data endpoints queues is getting full..need to stop network stack * the queue will resume in ar6000_tx_complete() */ @@ -3396,11 +3396,11 @@ ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPacketQueue) int status; struct ar_cookie * ar_cookie; HTC_ENDPOINT_ID eid; - A_BOOL wakeEvent = FALSE; + bool wakeEvent = false; struct sk_buff_head skb_queue; HTC_PACKET *pPacket; struct sk_buff *pktSkb; - A_BOOL flushing = FALSE; + bool flushing = false; skb_queue_head_init(&skb_queue); @@ -3445,18 +3445,18 @@ ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPacketQueue) { if (ar->arWMIControlEpFull) { /* since this packet completed, the WMI EP is no longer full */ - ar->arWMIControlEpFull = FALSE; + ar->arWMIControlEpFull = false; } if (ar->arTxPending[eid] == 0) { - wakeEvent = TRUE; + wakeEvent = true; } } if (status) { if (status == A_ECANCELED) { /* a packet was flushed */ - flushing = TRUE; + flushing = true; } AR6000_STAT_INC(ar, tx_errors); if (status != A_NO_RESOURCE) { @@ -3465,7 +3465,7 @@ ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPacketQueue) } } else { AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("OK\n")); - flushing = FALSE; + flushing = false; AR6000_STAT_INC(ar, tx_packets); ar->arNetStats.tx_bytes += A_NETBUF_LEN(pktSkb); #ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL @@ -3497,7 +3497,7 @@ ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPacketQueue) ar6000_free_cookie(ar, ar_cookie); if (ar->arNetQueueStopped) { - ar->arNetQueueStopped = FALSE; + ar->arNetQueueStopped = false; } } @@ -3512,7 +3512,7 @@ ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPacketQueue) A_NETBUF_FREE(pktSkb); } - if ((ar->arConnected == TRUE) || bypasswmi) { + if ((ar->arConnected == true) || bypasswmi) { if (!flushing) { /* don't wake the queue if we are flushing, other wise it will just * keep queueing packets, which will keep failing */ @@ -3619,23 +3619,23 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) if (status != A_OK) { AR6000_STAT_INC(ar, rx_errors); A_NETBUF_FREE(skb); - } else if (ar->arWmiEnabled == TRUE) { + } else if (ar->arWmiEnabled == true) { if (ept == ar->arControlEp) { /* * this is a wmi control msg */ #ifdef CONFIG_PM - ar6000_check_wow_status(ar, skb, TRUE); + ar6000_check_wow_status(ar, skb, true); #endif /* CONFIG_PM */ wmi_control_rx(ar->arWmi, skb); } else { WMI_DATA_HDR *dhdr = (WMI_DATA_HDR *)A_NETBUF_DATA(skb); - A_BOOL is_amsdu; + bool is_amsdu; A_UINT8 tid; - A_BOOL is_acl_data_frame; + bool is_acl_data_frame; is_acl_data_frame = WMI_DATA_HDR_GET_DATA_TYPE(dhdr) == WMI_DATA_HDR_DATA_TYPE_ACL; #ifdef CONFIG_PM - ar6000_check_wow_status(ar, NULL, FALSE); + ar6000_check_wow_status(ar, NULL, false); #endif /* CONFIG_PM */ /* * this is a wmi data packet @@ -3742,7 +3742,7 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) } } else { /* This frame is from a STA that is not associated*/ - A_ASSERT(FALSE); + A_ASSERT(false); } /* Drop NULL data frames here */ @@ -3753,7 +3753,7 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) } } - is_amsdu = WMI_DATA_HDR_IS_AMSDU(dhdr) ? TRUE : FALSE; + is_amsdu = WMI_DATA_HDR_IS_AMSDU(dhdr) ? true : false; tid = WMI_DATA_HDR_GET_UP(dhdr); seq_no = WMI_DATA_HDR_GET_SEQNO(dhdr); meta_type = WMI_DATA_HDR_GET_META(dhdr); @@ -3805,7 +3805,7 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) *((short *)A_NETBUF_DATA(skb)) = WMI_ACL_DATA_EVENTID; /* send the data packet to PAL driver */ if(ar6k_pal_config_g.fpar6k_pal_recv_pkt) { - if((*ar6k_pal_config_g.fpar6k_pal_recv_pkt)(ar->hcipal_info, skb) == TRUE) + if((*ar6k_pal_config_g.fpar6k_pal_recv_pkt)(ar->hcipal_info, skb) == true) goto rx_done; } } @@ -3870,7 +3870,7 @@ ar6000_deliver_frames_to_nw_stack(void *dev, void *osbuf) skb->dev = dev; if ((skb->dev->flags & IFF_UP) == IFF_UP) { #ifdef CONFIG_PM - ar6000_check_wow_status((AR_SOFTC_T *)ar6k_priv(dev), skb, FALSE); + ar6000_check_wow_status((AR_SOFTC_T *)ar6k_priv(dev), skb, false); #endif /* CONFIG_PM */ skb->protocol = eth_type_trans(skb, skb->dev); /* @@ -3963,7 +3963,7 @@ static void ar6000_cleanup_amsdu_rxbufs(AR_SOFTC_T *ar) void *osBuf; /* empty AMSDU buffer queue and free OS bufs */ - while (TRUE) { + while (true) { AR6000_SPIN_LOCK(&ar->arLock, 0); pPacket = HTC_PACKET_DEQUEUE(&ar->amsdu_rx_buffer_queue); @@ -3975,7 +3975,7 @@ static void ar6000_cleanup_amsdu_rxbufs(AR_SOFTC_T *ar) osBuf = pPacket->pPktContext; if (NULL == osBuf) { - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -4030,12 +4030,12 @@ static HTC_PACKET *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpo if (Length <= AR6000_BUFFER_SIZE) { /* shouldn't be getting called on normal sized packets */ - A_ASSERT(FALSE); + A_ASSERT(false); break; } if (Length > AR6000_AMSDU_BUFFER_SIZE) { - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -4052,7 +4052,7 @@ static HTC_PACKET *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpo /* set actual endpoint ID */ pPacket->Endpoint = Endpoint; - } while (FALSE); + } while (false); if (refillCount >= AR6000_AMSDU_REFILL_THRESHOLD) { ar6000_refill_amsdu_rxbufs(ar,refillCount); @@ -4082,7 +4082,7 @@ ar6000_get_iwstats(struct net_device * dev) struct iw_statistics * pIwStats = &ar->arIwStats; int rtnllocked; - if (ar->bIsDestroyProgress || ar->arWmiReady == FALSE || ar->arWlanState == WLAN_DISABLED) + if (ar->bIsDestroyProgress || ar->arWmiReady == false || ar->arWlanState == WLAN_DISABLED) { pIwStats->status = 0; pIwStats->qual.qual = 0; @@ -4132,13 +4132,13 @@ ar6000_get_iwstats(struct net_device * dev) break; } - ar->statsUpdatePending = TRUE; + ar->statsUpdatePending = true; if(wmi_get_stats_cmd(ar->arWmi) != A_OK) { break; } - wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, wmitimeout * HZ); + wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == false, wmitimeout * HZ); if (signal_pending(current)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000 : WMI get stats timeout \n")); break; @@ -4178,7 +4178,7 @@ ar6000_ready_event(void *devt, A_UINT8 *datap, A_UINT8 phyCap, A_UINT32 sw_ver, ar->arVersion.abi_ver = abi_ver; /* Indicate to the waiting thread that the ready event was received */ - ar->arWmiReady = TRUE; + ar->arWmiReady = true; wake_up(&arEvent); #if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN @@ -4280,7 +4280,7 @@ ar6000_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, A_UINT8 *bssid, break; } skip_key: - ar->arConnected = TRUE; + ar->arConnected = true; return; } @@ -4450,7 +4450,7 @@ skip_key: #ifdef USER_KEYS if (ar->user_savedkeys_stat == USER_SAVEDKEYS_STAT_RUN && - ar->user_saved_keys.keyOk == TRUE) + ar->user_saved_keys.keyOk == true) { key_op_ctrl = KEY_OP_VALID_MASK & ~KEY_OP_INIT_TSC; @@ -4487,8 +4487,8 @@ skip_key: /* Update connect & link status atomically */ spin_lock_irqsave(&ar->arLock, flags); - ar->arConnected = TRUE; - ar->arConnectPending = FALSE; + ar->arConnected = true; + ar->arConnectPending = false; netif_carrier_on(ar->arNetDev); spin_unlock_irqrestore(&ar->arLock, flags); /* reset the rx aggr state */ @@ -4654,15 +4654,15 @@ ar6000_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, A_UINT8 *bssid, */ if( reason == DISCONNECT_CMD) { - ar->arConnectPending = FALSE; + ar->arConnectPending = false; if ((!ar->arUserBssFilter) && (ar->arWmiReady)) { wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0); } } else { - ar->arConnectPending = TRUE; + ar->arConnectPending = true; if (((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x11)) || ((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x0) && (reconnect_flag == 1))) { - ar->arConnected = TRUE; + ar->arConnected = true; return; } } @@ -4684,7 +4684,7 @@ ar6000_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, A_UINT8 *bssid, * Find the nodes based on SSID and remove it * NOTE :: This case will not work out for Hidden-SSID */ - pWmiSsidnode = wmi_find_Ssidnode (ar->arWmi, ar->arSsid, ar->arSsidLen, FALSE, TRUE); + pWmiSsidnode = wmi_find_Ssidnode (ar->arWmi, ar->arSsid, ar->arSsidLen, false, true); if (pWmiSsidnode) { @@ -4696,7 +4696,7 @@ ar6000_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, A_UINT8 *bssid, /* Update connect & link status atomically */ spin_lock_irqsave(&ar->arLock, flags); - ar->arConnected = FALSE; + ar->arConnected = false; netif_carrier_off(ar->arNetDev); spin_unlock_irqrestore(&ar->arLock, flags); @@ -4784,7 +4784,7 @@ ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd) if(ar6k_pal_config_g.fpar6k_pal_recv_pkt) { /* pass the cmd packet to PAL driver */ - if((*ar6k_pal_config_g.fpar6k_pal_recv_pkt)(ar->hcipal_info, osbuf) == TRUE) + if((*ar6k_pal_config_g.fpar6k_pal_recv_pkt)(ar->hcipal_info, osbuf) == true) return; } ar6000_deliver_frames_to_nw_stack(ar->arNetDev, osbuf); @@ -4850,7 +4850,7 @@ ar6000_neighborReport_event(AR_SOFTC_T *ar, int numAps, WMI_NEIGHBOR_INFO *info) } void -ar6000_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, A_BOOL ismcast) +ar6000_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, bool ismcast) { static const char *tag = "MLME-MICHAELMICFAILURE.indication"; char buf[128]; @@ -5028,7 +5028,7 @@ ar6000_targetStats_event(AR_SOFTC_T *ar, A_UINT8 *ptr, A_UINT32 len) pStats->arp_replied += pTarget->arpStats.arp_replied; if (ar->statsUpdatePending) { - ar->statsUpdatePending = FALSE; + ar->statsUpdatePending = false; wake_up(&arEvent); } } @@ -5065,7 +5065,7 @@ ar6000_hbChallengeResp_event(AR_SOFTC_T *ar, A_UINT32 cookie, A_UINT32 source) } else { /* This would ignore the replys that come in after their due time */ if (cookie == ar->arHBChallengeResp.seqNum) { - ar->arHBChallengeResp.outstanding = FALSE; + ar->arHBChallengeResp.outstanding = false; } } } @@ -5312,7 +5312,7 @@ ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid) wmiSendCmdNum++; - } while (FALSE); + } while (false); if (cookie != NULL) { /* got a structure to send it out on */ @@ -5347,7 +5347,7 @@ ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid) } /* indicate tx activity or inactivity on a WMI stream */ -void ar6000_indicate_tx_activity(void *devt, A_UINT8 TrafficClass, A_BOOL Active) +void ar6000_indicate_tx_activity(void *devt, A_UINT8 TrafficClass, bool Active) { AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; HTC_ENDPOINT_ID eid ; @@ -5438,7 +5438,7 @@ ar6000_btcoex_config_event(struct ar6_softc *ar, A_UINT8 *ptr, A_UINT32 len) break; } if (ar->statsUpdatePending) { - ar->statsUpdatePending = FALSE; + ar->statsUpdatePending = false; wake_up(&arEvent); } } @@ -5453,7 +5453,7 @@ ar6000_btcoex_stats_event(struct ar6_softc *ar, A_UINT8 *ptr, A_UINT32 len) A_MEMCPY(&ar->arBtcoexStats, pBtcoexStats, sizeof(WMI_BTCOEX_STATS_EVENT)); if (ar->statsUpdatePending) { - ar->statsUpdatePending = FALSE; + ar->statsUpdatePending = false; wake_up(&arEvent); } @@ -5708,7 +5708,7 @@ ar6000_pmkid_list_event(void *devt, A_UINT8 numPMKID, WMI_PMKID *pmkidList, void ar6000_pspoll_event(AR_SOFTC_T *ar,A_UINT8 aid) { sta_t *conn=NULL; - A_BOOL isPsqEmpty = FALSE; + bool isPsqEmpty = false; conn = ieee80211_find_conn_for_aid(ar, aid); @@ -5747,7 +5747,7 @@ void ar6000_pspoll_event(AR_SOFTC_T *ar,A_UINT8 aid) void ar6000_dtimexpiry_event(AR_SOFTC_T *ar) { - A_BOOL isMcastQueued = FALSE; + bool isMcastQueued = false; struct sk_buff *skb = NULL; /* If there are no associated STAs, ignore the DTIM expiry event. @@ -5766,11 +5766,11 @@ void ar6000_dtimexpiry_event(AR_SOFTC_T *ar) isMcastQueued = A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq); A_MUTEX_UNLOCK(&ar->mcastpsqLock); - A_ASSERT(isMcastQueued == FALSE); + A_ASSERT(isMcastQueued == false); /* Flush the mcast psq to the target */ /* Set the STA flag to DTIMExpired, so that the frame will go out */ - ar->DTIMExpired = TRUE; + ar->DTIMExpired = true; A_MUTEX_LOCK(&ar->mcastpsqLock); while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) { @@ -5784,7 +5784,7 @@ void ar6000_dtimexpiry_event(AR_SOFTC_T *ar) A_MUTEX_UNLOCK(&ar->mcastpsqLock); /* Reset the DTIMExpired flag back to 0 */ - ar->DTIMExpired = FALSE; + ar->DTIMExpired = false; /* Clear the LSB of the BitMapCtl field of the TIM IE */ wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0); @@ -5893,7 +5893,7 @@ rssi_compensation_calc(AR_SOFTC_T *ar, A_INT16 rssi) } A_INT16 -rssi_compensation_reverse_calc(AR_SOFTC_T *ar, A_INT16 rssi, A_BOOL Above) +rssi_compensation_reverse_calc(AR_SOFTC_T *ar, A_INT16 rssi, bool Above) { A_INT16 i; @@ -6091,11 +6091,11 @@ ar6000_ap_mode_profile_commit(struct ar6_softc *ar) p.groupCryptoLen = ar->arGroupCryptoLen; p.ctrl_flags = ar->arConnectCtrlFlags; - ar->arConnected = FALSE; + ar->arConnected = false; wmi_ap_profile_commit(ar->arWmi, &p); spin_lock_irqsave(&ar->arLock, flags); - ar->arConnected = TRUE; + ar->arConnected = true; netif_carrier_on(ar->arNetDev); spin_unlock_irqrestore(&ar->arLock, flags); ar->ap_profile_flag = 0; @@ -6108,7 +6108,7 @@ ar6000_connect_to_ap(struct ar6_softc *ar) /* The ssid length check prevents second "essid off" from the user, to be treated as a connect cmd. The second "essid off" is ignored. */ - if((ar->arWmiReady == TRUE) && (ar->arSsidLen > 0) && ar->arNetworkType!=AP_NETWORK) + if((ar->arWmiReady == true) && (ar->arSsidLen > 0) && ar->arNetworkType!=AP_NETWORK) { int status; if((ADHOC_NETWORK != ar->arNetworkType) && @@ -6167,7 +6167,7 @@ ar6000_connect_to_ap(struct ar6_softc *ar) ar->arConnectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD; - ar->arConnectPending = TRUE; + ar->arConnectPending = true; return status; } return A_ERROR; diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c index fbac26429d84..a7a48292291c 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_pm.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_pm.c @@ -37,7 +37,7 @@ extern unsigned int wmitimeout; extern wait_queue_head_t arEvent; #ifdef ANDROID_ENV -extern void android_ar6k_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, A_BOOL isEvent); +extern void android_ar6k_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, bool isEvent); #endif #undef ATH_MODULE_NAME #define ATH_MODULE_NAME pm @@ -60,7 +60,7 @@ ATH_DEBUG_INSTANTIATE_MODULE_VAR(pm, int ar6000_exit_cut_power_state(AR_SOFTC_T *ar); #ifdef CONFIG_PM -static void ar6k_send_asleep_event_to_app(AR_SOFTC_T *ar, A_BOOL asleep) +static void ar6k_send_asleep_event_to_app(AR_SOFTC_T *ar, bool asleep) { char buf[128]; union iwreq_data wrqu; @@ -76,7 +76,7 @@ static void ar6000_wow_resume(AR_SOFTC_T *ar) if (ar->arWowState!= WLAN_WOW_STATE_NONE) { A_UINT16 fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period; A_UINT16 bg_period = (ar->scParams.bg_period==0) ? 60 : ar->scParams.bg_period; - WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {TRUE, FALSE}; + WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {true, false}; ar->arWowState = WLAN_WOW_STATE_NONE; if (wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)!=A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup restore host awake\n")); @@ -102,7 +102,7 @@ static void ar6000_wow_resume(AR_SOFTC_T *ar) if (wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB) == A_OK) { } #endif - ar6k_send_asleep_event_to_app(ar, FALSE); + ar6k_send_asleep_event_to_app(ar, false); AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Resume WoW successfully\n")); } else { AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WoW does not invoked. skip resume")); @@ -125,8 +125,8 @@ static void ar6000_wow_suspend(AR_SOFTC_T *ar) int status; WMI_ADD_WOW_PATTERN_CMD addWowCmd = { .filter = { 0 } }; WMI_DEL_WOW_PATTERN_CMD delWowCmd; - WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {FALSE, TRUE}; - WMI_SET_WOW_MODE_CMD wowMode = { .enable_wow = TRUE, + WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {false, true}; + WMI_SET_WOW_MODE_CMD wowMode = { .enable_wow = true, .hostReqDelay = 500 };/*500 ms delay*/ if (ar->arWowState!= WLAN_WOW_STATE_NONE) { @@ -185,7 +185,7 @@ static void ar6000_wow_suspend(AR_SOFTC_T *ar) if (status != A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to enable wow mode\n")); } - ar6k_send_asleep_event_to_app(ar, TRUE); + ar6k_send_asleep_event_to_app(ar, true); status = wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode); if (status != A_OK) { @@ -234,7 +234,7 @@ wow_not_connected: case WLAN_SUSPEND_DEEP_SLEEP: /* fall through */ default: - status = ar6000_update_wlan_pwr_state(ar, WLAN_DISABLED, TRUE); + status = ar6000_update_wlan_pwr_state(ar, WLAN_DISABLED, true); if (ar->arWlanPowerState==WLAN_POWER_STATE_ON || ar->arWlanPowerState==WLAN_POWER_STATE_WOW) { AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Strange suspend state for not wow mode %d", ar->arWlanPowerState)); @@ -261,7 +261,7 @@ int ar6000_resume_ev(void *context) case WLAN_POWER_STATE_CUT_PWR: /* fall through */ case WLAN_POWER_STATE_DEEP_SLEEP: - ar6000_update_wlan_pwr_state(ar, WLAN_ENABLED, TRUE); + ar6000_update_wlan_pwr_state(ar, WLAN_ENABLED, true); AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Resume for %d mode pwr %d\n", __func__, powerState, ar->arWlanPowerState)); break; case WLAN_POWER_STATE_ON: @@ -273,7 +273,7 @@ int ar6000_resume_ev(void *context) return A_OK; } -void ar6000_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, A_BOOL isEvent) +void ar6000_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, bool isEvent) { if (ar->arWowState!=WLAN_WOW_STATE_NONE) { if (ar->arWowState==WLAN_WOW_STATE_SUSPENDING) { @@ -376,7 +376,7 @@ ar6000_setup_cut_power_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) #ifdef ANDROID_ENV /* Wait for WMI ready event */ A_UINT32 timeleft = wait_event_interruptible_timeout(arEvent, - (ar->arWmiReady == TRUE), wmitimeout * HZ); + (ar->arWmiReady == true), wmitimeout * HZ); if (!timeleft || signal_pending(current)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000 : Failed to get wmi ready \n")); status = A_ERROR; @@ -395,7 +395,7 @@ ar6000_setup_cut_power_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) if (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) { break; } - ar6000_stop_endpoint(ar->arNetDev, TRUE, FALSE); + ar6000_stop_endpoint(ar->arNetDev, true, false); config = HIF_DEVICE_POWER_CUT; status = HIFConfigureDevice(ar->arHifDevice, @@ -436,8 +436,8 @@ ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) } fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period; - hostSleepMode.awake = TRUE; - hostSleepMode.asleep = FALSE; + hostSleepMode.awake = true; + hostSleepMode.asleep = false; if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)) != A_OK) { break; @@ -471,7 +471,7 @@ ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) } } } else if (state == WLAN_DISABLED){ - WMI_SET_WOW_MODE_CMD wowMode = { .enable_wow = FALSE }; + WMI_SET_WOW_MODE_CMD wowMode = { .enable_wow = false }; /* Already in deep sleep state.. exit */ if (ar->arWlanPowerState != WLAN_POWER_STATE_ON) { @@ -485,7 +485,7 @@ ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) { /* Disconnect from the AP and disable foreground scanning */ AR6000_SPIN_LOCK(&ar->arLock, 0); - if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) { + if (ar->arConnected == true || ar->arConnectPending == true) { AR6000_SPIN_UNLOCK(&ar->arLock, 0); wmi_disconnect_cmd(ar->arWmi); } else { @@ -510,8 +510,8 @@ ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) wmi_powermode_cmd(ar->arWmi, REC_POWER); #endif - hostSleepMode.awake = FALSE; - hostSleepMode.asleep = TRUE; + hostSleepMode.awake = false; + hostSleepMode.asleep = true; if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode))!=A_OK) { break; } @@ -537,14 +537,14 @@ ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) } int -ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, A_BOOL pmEvent) +ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool pmEvent) { int status = A_OK; A_UINT16 powerState, oldPowerState; AR6000_WLAN_STATE oldstate = ar->arWlanState; - A_BOOL wlanOff = ar->arWlanOff; + bool wlanOff = ar->arWlanOff; #ifdef CONFIG_PM - A_BOOL btOff = ar->arBTOff; + bool btOff = ar->arBTOff; #endif /* CONFIG_PM */ if ((state!=WLAN_DISABLED && state!=WLAN_ENABLED)) { @@ -578,7 +578,7 @@ ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, A_BO } #ifdef CONFIG_PM else if (pmEvent && wlanOff) { - A_BOOL allowCutPwr = ((!ar->arBTSharing) || btOff); + bool allowCutPwr = ((!ar->arBTSharing) || btOff); if ((powerState==WLAN_POWER_STATE_CUT_PWR) && (!allowCutPwr)) { /* Come out of cut power */ ar6000_setup_cut_power_state(ar, WLAN_ENABLED); @@ -591,10 +591,10 @@ ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, A_BO powerState = WLAN_POWER_STATE_DEEP_SLEEP; #ifdef CONFIG_PM if (pmEvent) { /* disable due to suspend */ - A_BOOL suspendCutPwr = (ar->arSuspendConfig == WLAN_SUSPEND_CUT_PWR || + bool suspendCutPwr = (ar->arSuspendConfig == WLAN_SUSPEND_CUT_PWR || (ar->arSuspendConfig == WLAN_SUSPEND_WOW && ar->arWow2Config==WLAN_SUSPEND_CUT_PWR)); - A_BOOL suspendCutIfBtOff = ((ar->arSuspendConfig == + bool suspendCutIfBtOff = ((ar->arSuspendConfig == WLAN_SUSPEND_CUT_PWR_IF_BT_OFF || (ar->arSuspendConfig == WLAN_SUSPEND_WOW && ar->arWow2Config==WLAN_SUSPEND_CUT_PWR_IF_BT_OFF)) && @@ -654,13 +654,13 @@ int ar6000_set_bt_hw_state(struct ar6_softc *ar, A_UINT32 enable) { #ifdef CONFIG_PM - A_BOOL off = (enable == 0); + bool off = (enable == 0); int status; if (ar->arBTOff == off) { return A_OK; } ar->arBTOff = off; - status = ar6000_update_wlan_pwr_state(ar, ar->arWlanOff ? WLAN_DISABLED : WLAN_ENABLED, FALSE); + status = ar6000_update_wlan_pwr_state(ar, ar->arWlanOff ? WLAN_DISABLED : WLAN_ENABLED, false); return status; #else return A_OK; @@ -671,12 +671,12 @@ int ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) { int status; - A_BOOL off = (state == WLAN_DISABLED); + bool off = (state == WLAN_DISABLED); if (ar->arWlanOff == off) { return A_OK; } ar->arWlanOff = off; - status = ar6000_update_wlan_pwr_state(ar, state, FALSE); + status = ar6000_update_wlan_pwr_state(ar, state, false); return status; } diff --git a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c index 59e2af4f641e..6c03035051b6 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c @@ -60,7 +60,7 @@ ar6000_htc_raw_read_cb(void *Context, HTC_PACKET *pPacket) busy->length = pPacket->ActualLength + HTC_HEADER_LEN; busy->currPtr = HTC_HEADER_LEN; - arRaw->read_buffer_available[streamID] = TRUE; + arRaw->read_buffer_available[streamID] = true; //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("raw read cb: 0x%X 0x%X \n", busy->currPtr,busy->length); up(&arRaw->raw_htc_read_sem[streamID]); @@ -102,7 +102,7 @@ ar6000_htc_raw_write_cb(void *Context, HTC_PACKET *pPacket) A_ASSERT(pPacket->pBuffer == (free->data + HTC_HEADER_LEN)); free->length = 0; - arRaw->write_buffer_available[streamID] = TRUE; + arRaw->write_buffer_available[streamID] = true; up(&arRaw->raw_htc_write_sem[streamID]); /* Signal the waiting process */ @@ -161,7 +161,7 @@ static int ar6000_connect_raw_service(AR_SOFTC_T *ar, AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("HTC RAW : stream ID: %d, endpoint: %d\n", StreamID, arRawStream2EndpointID(ar,StreamID))); - } while (FALSE); + } while (false); return status; } @@ -241,8 +241,8 @@ int ar6000_htc_raw_open(AR_SOFTC_T *ar) memset(buffer, 0, sizeof(raw_htc_buffer)); } - arRaw->read_buffer_available[streamID] = FALSE; - arRaw->write_buffer_available[streamID] = TRUE; + arRaw->read_buffer_available[streamID] = false; + arRaw->write_buffer_available[streamID] = true; } if (status) { @@ -267,7 +267,7 @@ int ar6000_htc_raw_open(AR_SOFTC_T *ar) return -EIO; } - (ar)->arRawIfInit = TRUE; + (ar)->arRawIfInit = true; return 0; } @@ -278,7 +278,7 @@ int ar6000_htc_raw_close(AR_SOFTC_T *ar) HTCStop(ar->arHtcTarget); /* reset the device */ - ar6000_reset_device(ar->arHifDevice, ar->arTargetType, TRUE, FALSE); + ar6000_reset_device(ar->arHifDevice, ar->arTargetType, true, false); /* Initialize the BMI component */ BMIInit(); @@ -300,9 +300,9 @@ get_filled_buffer(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID) } } if (busy->length) { - arRaw->read_buffer_available[StreamID] = TRUE; + arRaw->read_buffer_available[StreamID] = true; } else { - arRaw->read_buffer_available[StreamID] = FALSE; + arRaw->read_buffer_available[StreamID] = false; } return busy; @@ -361,7 +361,7 @@ ssize_t ar6000_htc_raw_read(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID, //AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("raw read ioctl: ep for packet:%d \n", busy->HTCPacket.Endpoint)); HTCAddReceivePkt(ar->arHtcTarget, &busy->HTCPacket); } - arRaw->read_buffer_available[StreamID] = FALSE; + arRaw->read_buffer_available[StreamID] = false; up(&arRaw->raw_htc_read_sem[StreamID]); return length; @@ -382,9 +382,9 @@ get_free_buffer(AR_SOFTC_T *ar, HTC_ENDPOINT_ID StreamID) } } if (!free->length) { - arRaw->write_buffer_available[StreamID] = TRUE; + arRaw->write_buffer_available[StreamID] = true; } else { - arRaw->write_buffer_available[StreamID] = FALSE; + arRaw->write_buffer_available[StreamID] = false; } return free; @@ -447,7 +447,7 @@ ssize_t ar6000_htc_raw_write(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID, HTCSendPkt(ar->arHtcTarget,&free->HTCPacket); - arRaw->write_buffer_available[StreamID] = FALSE; + arRaw->write_buffer_available[StreamID] = false; up(&arRaw->raw_htc_write_sem[StreamID]); return length; diff --git a/drivers/staging/ath6kl/os/linux/ar6k_pal.c b/drivers/staging/ath6kl/os/linux/ar6k_pal.c index 5a0b373cd3e1..bca028afab6a 100644 --- a/drivers/staging/ath6kl/os/linux/ar6k_pal.c +++ b/drivers/staging/ath6kl/os/linux/ar6k_pal.c @@ -157,7 +157,7 @@ static int btpal_send_frame(struct sk_buff *skb) kfree_skb(skb); return 0; default: - A_ASSERT(FALSE); + A_ASSERT(false); kfree_skb(skb); return 0; } @@ -178,7 +178,7 @@ static int btpal_send_frame(struct sk_buff *skb) { PRIN_LOG("HCI command"); - if (ar->arWmiReady == FALSE) + if (ar->arWmiReady == false) { PRIN_LOG("WMI not ready "); break; @@ -195,7 +195,7 @@ static int btpal_send_frame(struct sk_buff *skb) void *osbuf; PRIN_LOG("ACL data"); - if (ar->arWmiReady == FALSE) + if (ar->arWmiReady == false) { PRIN_LOG("WMI not ready"); break; @@ -229,7 +229,7 @@ static int btpal_send_frame(struct sk_buff *skb) } txSkb = NULL; } - } while (FALSE); + } while (false); if (txSkb != NULL) { PRIN_LOG("Free skb"); @@ -302,7 +302,7 @@ static int bt_setup_hci_pal(ar6k_hci_pal_info_t *pHciPalInfo) PRIN_LOG("Normal mode enabled"); bt_set_bit(pHciPalInfo->ulFlags, HCI_NORMAL_MODE); - } while (FALSE); + } while (false); if (status) { bt_cleanup_hci_pal(pHciPalInfo); @@ -328,22 +328,22 @@ void ar6k_cleanup_hci_pal(void *ar_p) /**************************** * Register HCI device ****************************/ -static A_BOOL ar6k_pal_transport_ready(void *pHciPal) +static bool ar6k_pal_transport_ready(void *pHciPal) { ar6k_hci_pal_info_t *pHciPalInfo = (ar6k_hci_pal_info_t *)pHciPal; PRIN_LOG("HCI device transport ready"); if(pHciPalInfo == NULL) - return FALSE; + return false; if (hci_register_dev(pHciPalInfo->hdev) < 0) { PRIN_LOG("Can't register HCI device"); hci_free_dev(pHciPalInfo->hdev); - return FALSE; + return false; } PRIN_LOG("HCI device registered"); pHciPalInfo->ulFlags |= HCI_REGISTERED; - return TRUE; + return true; } /************************************************** @@ -351,11 +351,11 @@ static A_BOOL ar6k_pal_transport_ready(void *pHciPal) * packet is received. Pass the packet to bluetooth * stack via hci_recv_frame. **************************************************/ -A_BOOL ar6k_pal_recv_pkt(void *pHciPal, void *osbuf) +bool ar6k_pal_recv_pkt(void *pHciPal, void *osbuf) { struct sk_buff *skb = (struct sk_buff *)osbuf; ar6k_hci_pal_info_t *pHciPalInfo; - A_BOOL success = FALSE; + bool success = false; A_UINT8 btType = 0; pHciPalInfo = (ar6k_hci_pal_info_t *)pHciPal; @@ -391,8 +391,8 @@ A_BOOL ar6k_pal_recv_pkt(void *pHciPal, void *osbuf) PRIN_LOG("HCI PAL: Indicated RCV of type:%d, Length:%d \n",HCI_EVENT_PKT, skb->len); } PRIN_LOG("hci recv success"); - success = TRUE; - }while(FALSE); + success = true; + }while(false); return success; } @@ -435,7 +435,7 @@ int ar6k_setup_hci_pal(void *ar_p) ar6k_pal_config.fpar6k_pal_recv_pkt = ar6k_pal_recv_pkt; register_pal_cb(&ar6k_pal_config); ar6k_pal_transport_ready(ar->hcipal_info); - } while (FALSE); + } while (false); if (status) { ar6k_cleanup_hci_pal(ar); diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index 936879e06c23..f03e4c108bd6 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -183,7 +183,7 @@ ar6k_set_auth_type(AR_SOFTC_T *ar, enum nl80211_auth_type auth_type) } static int -ar6k_set_cipher(AR_SOFTC_T *ar, A_UINT32 cipher, A_BOOL ucast) +ar6k_set_cipher(AR_SOFTC_T *ar, A_UINT32 cipher, bool ucast) { A_UINT8 *ar_cipher = ucast ? &ar->arPairwiseCrypto : &ar->arGroupCrypto; @@ -249,7 +249,7 @@ ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); - if(ar->arWmiReady == FALSE) { + if(ar->arWmiReady == false) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready yet\n", __func__)); return -EIO; } @@ -269,7 +269,7 @@ ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, return -EINVAL; } - if(ar->arSkipScan == TRUE && + if(ar->arSkipScan == true && ((sme->channel && sme->channel->center_freq == 0) || (sme->bssid && !sme->bssid[0] && !sme->bssid[1] && !sme->bssid[2] && !sme->bssid[3] && !sme->bssid[4] && !sme->bssid[5]))) @@ -302,10 +302,10 @@ ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, } } - if(ar->arConnected == TRUE && + if(ar->arConnected == true && ar->arSsidLen == sme->ssid_len && !A_MEMCMP(ar->arSsid, sme->ssid, ar->arSsidLen)) { - reconnect_flag = TRUE; + reconnect_flag = true; status = wmi_reconnect_cmd(ar->arWmi, ar->arReqBssid, ar->arChannelHint); @@ -422,7 +422,7 @@ ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, } ar->arConnectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD; - ar->arConnectPending = TRUE; + ar->arConnectPending = true; return 0; } @@ -560,7 +560,7 @@ ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, return; } - if (FALSE == ar->arConnected) { + if (false == ar->arConnected) { /* inform connect result to cfg80211 */ cfg80211_connect_result(ar->arNetDev, bssid, assocReqIe, assocReqLen, @@ -583,7 +583,7 @@ ar6k_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason_code)); - if(ar->arWmiReady == FALSE) { + if(ar->arWmiReady == false) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); return -EIO; } @@ -608,7 +608,7 @@ ar6k_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); ar->arSsidLen = 0; - if (ar->arSkipScan == FALSE) { + if (ar->arSkipScan == false) { A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); } @@ -644,7 +644,7 @@ ar6k_cfg80211_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, } } - if(FALSE == ar->arConnected) { + if(false == ar->arConnected) { if(NO_NETWORK_AVAIL == reason) { /* connect cmd failed */ cfg80211_connect_result(ar->arNetDev, bssid, @@ -730,7 +730,7 @@ ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); - if(ar->arWmiReady == FALSE) { + if(ar->arWmiReady == false) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); return -EIO; } @@ -768,7 +768,7 @@ ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, forceFgScan = 1; } - if(wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, forceFgScan, FALSE, \ + if(wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, forceFgScan, false, \ 0, 0, 0, NULL) != A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_startscan_cmd failed\n", __func__)); ret = -EIO; @@ -819,7 +819,7 @@ ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s:\n", __func__)); - if(ar->arWmiReady == FALSE) { + if(ar->arWmiReady == false) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); return -EIO; } @@ -907,7 +907,7 @@ ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index)); - if(ar->arWmiReady == FALSE) { + if(ar->arWmiReady == false) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); return -EIO; } @@ -946,7 +946,7 @@ ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index)); - if(ar->arWmiReady == FALSE) { + if(ar->arWmiReady == false) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); return -EIO; } @@ -986,7 +986,7 @@ ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index)); - if(ar->arWmiReady == FALSE) { + if(ar->arWmiReady == false) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); return -EIO; } @@ -1030,7 +1030,7 @@ ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev, AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index)); - if(ar->arWmiReady == FALSE) { + if(ar->arWmiReady == false) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); return -EIO; } @@ -1045,7 +1045,7 @@ ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev, } void -ar6k_cfg80211_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, A_BOOL ismcast) +ar6k_cfg80211_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, bool ismcast) { AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast)); @@ -1062,7 +1062,7 @@ ar6k_cfg80211_set_wiphy_params(struct wiphy *wiphy, A_UINT32 changed) AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: changed 0x%x\n", __func__, changed)); - if(ar->arWmiReady == FALSE) { + if(ar->arWmiReady == false) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); return -EIO; } @@ -1100,7 +1100,7 @@ ar6k_cfg80211_set_txpower(struct wiphy *wiphy, enum nl80211_tx_power_setting typ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x, dbm %d\n", __func__, type, dbm)); - if(ar->arWmiReady == FALSE) { + if(ar->arWmiReady == false) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); return -EIO; } @@ -1110,13 +1110,13 @@ ar6k_cfg80211_set_txpower(struct wiphy *wiphy, enum nl80211_tx_power_setting typ return -EIO; } - ar->arTxPwrSet = FALSE; + ar->arTxPwrSet = false; switch(type) { case NL80211_TX_POWER_AUTOMATIC: return 0; case NL80211_TX_POWER_LIMITED: ar->arTxPwr = ar_dbm = dbm; - ar->arTxPwrSet = TRUE; + ar->arTxPwrSet = true; break; default: AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x not supported\n", __func__, type)); @@ -1135,7 +1135,7 @@ ar6k_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm) AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); - if(ar->arWmiReady == FALSE) { + if(ar->arWmiReady == false) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); return -EIO; } @@ -1145,7 +1145,7 @@ ar6k_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm) return -EIO; } - if((ar->arConnected == TRUE)) { + if((ar->arConnected == true)) { ar->arTxPwr = 0; if(wmi_get_txPwr_cmd(ar->arWmi) != A_OK) { @@ -1175,7 +1175,7 @@ ar6k_cfg80211_set_power_mgmt(struct wiphy *wiphy, AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: pmgmt %d, timeout %d\n", __func__, pmgmt, timeout)); - if(ar->arWmiReady == FALSE) { + if(ar->arWmiReady == false) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); return -EIO; } @@ -1237,7 +1237,7 @@ ar6k_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type %u\n", __func__, type)); - if(ar->arWmiReady == FALSE) { + if(ar->arWmiReady == false) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); return -EIO; } @@ -1273,7 +1273,7 @@ ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); - if(ar->arWmiReady == FALSE) { + if(ar->arWmiReady == false) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); return -EIO; } @@ -1346,7 +1346,7 @@ ar6k_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); - if(ar->arWmiReady == FALSE) { + if(ar->arWmiReady == false) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); return -EIO; } diff --git a/drivers/staging/ath6kl/os/linux/eeprom.c b/drivers/staging/ath6kl/os/linux/eeprom.c index be77fb87ebf5..fd0e0837ad43 100644 --- a/drivers/staging/ath6kl/os/linux/eeprom.c +++ b/drivers/staging/ath6kl/os/linux/eeprom.c @@ -266,7 +266,7 @@ request_4byte_write(int offset, A_UINT32 data) * Check whether or not an EEPROM request that was started * earlier has completed yet. */ -static A_BOOL +static bool request_in_progress(void) { A_UINT32 regval; diff --git a/drivers/staging/ath6kl/os/linux/export_hci_transport.c b/drivers/staging/ath6kl/os/linux/export_hci_transport.c index 03f4567eafcf..28823df23119 100644 --- a/drivers/staging/ath6kl/os/linux/export_hci_transport.c +++ b/drivers/staging/ath6kl/os/linux/export_hci_transport.c @@ -39,15 +39,15 @@ HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, HCI_TRANSPORT_CONFIG_INFO *pInfo); void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans); int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue); -int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, A_BOOL Synchronous); +int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, bool Synchronous); void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans); int (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans); -int (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable); +int (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); int (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, int MaxPollMS); int (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud); -int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable); +int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); extern HCI_TRANSPORT_CALLBACKS ar6kHciTransCallbacks; diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index 857ef8bc4fc6..6e77bff6ef63 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -77,8 +77,8 @@ typedef struct { void *pHCIDev; /* HCI bridge device */ HCI_TRANSPORT_PROPERTIES HCIProps; /* HCI bridge props */ struct hci_dev *pBtStackHCIDev; /* BT Stack HCI dev */ - A_BOOL HciNormalMode; /* Actual HCI mode enabled (non-TEST)*/ - A_BOOL HciRegistered; /* HCI device registered with stack */ + bool HciNormalMode; /* Actual HCI mode enabled (non-TEST)*/ + bool HciRegistered; /* HCI device registered with stack */ HTC_PACKET_QUEUE HTCPacketStructHead; A_UINT8 *pHTCStructAlloc; spinlock_t BridgeLock; @@ -109,7 +109,7 @@ AR6K_HCI_BRIDGE_INFO *g_pHcidevInfo; static int bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo); static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo); static int bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo); -static A_BOOL bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, +static bool bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, HCI_TRANSPORT_PACKET_TYPE Type, struct sk_buff *skb); static struct sk_buff *bt_alloc_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, int Length); @@ -310,7 +310,7 @@ static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle, /* Make sure both AR6K and AR3K have power management enabled */ if (ar3kconfig.PwrMgmtEnabled) { - status = HCI_TransportEnablePowerMgmt(pHcidevInfo->pHCIDev, TRUE); + status = HCI_TransportEnablePowerMgmt(pHcidevInfo->pHCIDev, true); if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to enable TLPM for AR6K! \n")); } @@ -318,7 +318,7 @@ static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle, status = bt_register_hci(pHcidevInfo); - } while (FALSE); + } while (false); return status; } @@ -419,7 +419,7 @@ static void ar6000_hci_pkt_recv(void *pContext, HTC_PACKET *pPacket) skb = NULL; } - } while (FALSE); + } while (false); FreeHTCStruct(pHcidevInfo,pPacket); @@ -544,7 +544,7 @@ int ar6000_setup_hci(AR_SOFTC_T *ar) status = A_ERROR; } - } while (FALSE); + } while (false); if (status) { if (pHcidevInfo != NULL) { @@ -656,10 +656,10 @@ int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb) HCI_ACL_TYPE, /* send every thing out as ACL */ htc_tag); - HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,FALSE); + HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,false); pPacket = NULL; - } while (FALSE); + } while (false); return status; } @@ -747,7 +747,7 @@ static int bt_send_frame(struct sk_buff *skb) kfree_skb(skb); return 0; default: - A_ASSERT(FALSE); + A_ASSERT(false); kfree_skb(skb); return 0; } @@ -802,11 +802,11 @@ static int bt_send_frame(struct sk_buff *skb) AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("HCI Bridge: type:%d, Total Length:%d Bytes \n", type, txSkb->len)); - status = HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,FALSE); + status = HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,false); pPacket = NULL; txSkb = NULL; - } while (FALSE); + } while (false); if (txSkb != NULL) { kfree_skb(txSkb); @@ -902,9 +902,9 @@ static int bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) pHciDev->destruct = bt_destruct; pHciDev->owner = THIS_MODULE; /* driver is running in normal BT mode */ - pHcidevInfo->HciNormalMode = TRUE; + pHcidevInfo->HciNormalMode = true; - } while (FALSE); + } while (false); if (status) { bt_cleanup_hci(pHcidevInfo); @@ -918,7 +918,7 @@ static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) int err; if (pHcidevInfo->HciRegistered) { - pHcidevInfo->HciRegistered = FALSE; + pHcidevInfo->HciRegistered = false; clear_bit(HCI_RUNNING, &pHcidevInfo->pBtStackHCIDev->flags); clear_bit(HCI_UP, &pHcidevInfo->pBtStackHCIDev->flags); clear_bit(HCI_INIT, &pHcidevInfo->pBtStackHCIDev->flags); @@ -944,28 +944,28 @@ static int bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: registering HCI... \n")); A_ASSERT(pHcidevInfo->pBtStackHCIDev != NULL); /* mark that we are registered */ - pHcidevInfo->HciRegistered = TRUE; + pHcidevInfo->HciRegistered = true; if ((err = hci_register_dev(pHcidevInfo->pBtStackHCIDev)) < 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to register with bluetooth %d\n",err)); - pHcidevInfo->HciRegistered = FALSE; + pHcidevInfo->HciRegistered = false; status = A_ERROR; break; } AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: HCI registered \n")); - } while (FALSE); + } while (false); return status; } -static A_BOOL bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, +static bool bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, HCI_TRANSPORT_PACKET_TYPE Type, struct sk_buff *skb) { A_UINT8 btType; int len; - A_BOOL success = FALSE; + bool success = false; BT_HCI_EVENT_HEADER *pEvent; do { @@ -984,7 +984,7 @@ static A_BOOL bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, break; default: btType = 0; - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -1015,9 +1015,9 @@ static A_BOOL bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, ("HCI Bridge: Indicated RCV of type:%d, Length:%d \n",btType,len)); } - success = TRUE; + success = true; - } while (FALSE); + } while (false); return success; } @@ -1051,26 +1051,26 @@ static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) } static int bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) { - A_ASSERT(FALSE); + A_ASSERT(false); return A_ERROR; } -static A_BOOL bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, +static bool bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, HCI_TRANSPORT_PACKET_TYPE Type, struct sk_buff *skb) { - A_ASSERT(FALSE); - return FALSE; + A_ASSERT(false); + return false; } static struct sk_buff* bt_alloc_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, int Length) { - A_ASSERT(FALSE); + A_ASSERT(false); return NULL; } static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, struct sk_buff *skb) { - A_ASSERT(FALSE); + A_ASSERT(false); } #endif // } CONFIG_BLUEZ_HCI_BRIDGE diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 0dee74a17978..233a1d3cc8e1 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -104,7 +104,7 @@ struct USER_SAVEDKEYS { struct ieee80211req_key ucast_ik; struct ieee80211req_key bcast_ik; CRYPTO_TYPE keyType; - A_BOOL keyOk; + bool keyOk; }; #endif @@ -412,7 +412,7 @@ struct ar_hb_chlng_resp { A_TIMER timer; A_UINT32 frequency; A_UINT32 seqNum; - A_BOOL outstanding; + bool outstanding; A_UINT8 missCnt; A_UINT8 missThres; }; @@ -456,8 +456,8 @@ typedef struct ar6_raw_htc { wait_queue_head_t raw_htc_write_queue[HTC_RAW_STREAM_NUM_MAX]; raw_htc_buffer raw_htc_read_buffer[HTC_RAW_STREAM_NUM_MAX][RAW_HTC_READ_BUFFERS_NUM]; raw_htc_buffer raw_htc_write_buffer[HTC_RAW_STREAM_NUM_MAX][RAW_HTC_WRITE_BUFFERS_NUM]; - A_BOOL write_buffer_available[HTC_RAW_STREAM_NUM_MAX]; - A_BOOL read_buffer_available[HTC_RAW_STREAM_NUM_MAX]; + bool write_buffer_available[HTC_RAW_STREAM_NUM_MAX]; + bool read_buffer_available[HTC_RAW_STREAM_NUM_MAX]; } AR_RAW_HTC_T; typedef struct ar6_softc { @@ -466,9 +466,9 @@ typedef struct ar6_softc { int arTxPending[ENDPOINT_MAX]; int arTotalTxDataPending; A_UINT8 arNumDataEndPts; - A_BOOL arWmiEnabled; - A_BOOL arWmiReady; - A_BOOL arConnected; + bool arWmiEnabled; + bool arWmiReady; + bool arConnected; HTC_HANDLE arHtcTarget; void *arHifDevice; spinlock_t arLock; @@ -495,14 +495,14 @@ typedef struct ar6_softc { A_UINT32 arTargetType; A_INT8 arRssi; A_UINT8 arTxPwr; - A_BOOL arTxPwrSet; + bool arTxPwrSet; A_INT32 arBitRate; struct net_device_stats arNetStats; struct iw_statistics arIwStats; A_INT8 arNumChannels; A_UINT16 arChannelList[32]; A_UINT32 arRegCode; - A_BOOL statsUpdatePending; + bool statsUpdatePending; TARGET_STATS arTargetStats; A_INT8 arMaxRetries; A_UINT8 arPhyCapability; @@ -527,13 +527,13 @@ typedef struct ar6_softc { A_UINT32 arRateMask; A_UINT8 arSkipScan; A_UINT16 arBeaconInterval; - A_BOOL arConnectPending; - A_BOOL arWmmEnabled; + bool arConnectPending; + bool arWmmEnabled; struct ar_hb_chlng_resp arHBChallengeResp; A_UINT8 arKeepaliveConfigured; A_UINT32 arMgmtFilter; HTC_ENDPOINT_ID arAc2EpMapping[WMM_NUM_AC]; - A_BOOL arAcStreamActive[WMM_NUM_AC]; + bool arAcStreamActive[WMM_NUM_AC]; A_UINT8 arAcStreamPriMap[WMM_NUM_AC]; A_UINT8 arHiAcStreamActivePri; A_UINT8 arEp2AcMapping[ENDPOINT_MAX]; @@ -541,12 +541,12 @@ typedef struct ar6_softc { #ifdef HTC_RAW_INTERFACE AR_RAW_HTC_T *arRawHtc; #endif - A_BOOL arNetQueueStopped; - A_BOOL arRawIfInit; + bool arNetQueueStopped; + bool arRawIfInit; int arDeviceIndex; COMMON_CREDIT_STATE_INFO arCreditStateInfo; - A_BOOL arWMIControlEpFull; - A_BOOL dbgLogFetchInProgress; + bool arWMIControlEpFull; + bool dbgLogFetchInProgress; A_UCHAR log_buffer[DBGLOG_HOST_LOG_BUFFER_SIZE]; A_UINT32 log_cnt; A_UINT32 dbglog_init_done; @@ -565,7 +565,7 @@ typedef struct ar6_softc { struct ieee80211req_key ap_mode_bkey; /* AP mode */ A_NETBUF_QUEUE_T mcastpsq; /* power save q for Mcast frames */ A_MUTEX_T mcastpsqLock; - A_BOOL DTIMExpired; /* flag to indicate DTIM expired */ + bool DTIMExpired; /* flag to indicate DTIM expired */ A_UINT8 intra_bss; /* enable/disable intra bss data forward */ void *aggr_cntxt; #ifndef EXPORT_HCI_BRIDGE_INTERFACE @@ -581,7 +581,7 @@ typedef struct ar6_softc { A_UINT16 arRTS; A_UINT16 arACS; /* AP mode - Auto Channel Selection */ HTC_PACKET_QUEUE amsdu_rx_buffer_queue; - A_BOOL bIsDestroyProgress; /* flag to indicate ar6k destroy is in progress */ + bool bIsDestroyProgress; /* flag to indicate ar6k destroy is in progress */ A_TIMER disconnect_timer; A_UINT8 rxMetaVersion; #ifdef WAPI_ENABLE @@ -597,11 +597,11 @@ typedef struct ar6_softc { struct ar_key keys[WMI_MAX_KEY_INDEX + 1]; #endif /* ATH6K_CONFIG_CFG80211 */ A_UINT16 arWlanPowerState; - A_BOOL arWlanOff; + bool arWlanOff; #ifdef CONFIG_PM A_UINT16 arWowState; - A_BOOL arBTOff; - A_BOOL arBTSharing; + bool arBTOff; + bool arBTSharing; A_UINT16 arSuspendConfig; A_UINT16 arWlanOffConfig; A_UINT16 arWow2Config; @@ -611,7 +611,7 @@ typedef struct ar6_softc { #define AR_MCAST_FILTER_MAC_ADDR_SIZE 4 A_UINT8 mcast_filters[MAC_MAX_FILTERS_PER_LIST][AR_MCAST_FILTER_MAC_ADDR_SIZE]; A_UINT8 bdaddr[6]; - A_BOOL scanSpecificSsid; + bool scanSpecificSsid; #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT void *arApDev; #endif @@ -704,7 +704,7 @@ int ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar); void ar6000_TxDataCleanup(AR_SOFTC_T *ar); int ar6000_acl_data_tx(struct sk_buff *skb, struct net_device *dev); void ar6000_restart_endpoint(struct net_device *dev); -void ar6000_stop_endpoint(struct net_device *dev, A_BOOL keepprofile, A_BOOL getdbglogs); +void ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs); #ifdef HTC_RAW_INTERFACE diff --git a/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h b/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h index a9a29a624a10..b2ee6525cba0 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h @@ -26,7 +26,7 @@ /* transmit packet reserve offset */ #define TX_PACKET_RSV_OFFSET 32 /* pal specific config structure */ -typedef A_BOOL (*ar6k_pal_recv_pkt_t)(void *pHciPalInfo, void *skb); +typedef bool (*ar6k_pal_recv_pkt_t)(void *pHciPalInfo, void *skb); typedef struct ar6k_pal_config_s { ar6k_pal_recv_pkt_t fpar6k_pal_recv_pkt; diff --git a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h index 29fac6bad83a..014b7a4b0a1a 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h @@ -41,7 +41,7 @@ void ar6000_disconnect_event(struct ar6_softc *ar, A_UINT8 reason, A_UINT8 *bssid, A_UINT8 assocRespLen, A_UINT8 *assocInfo, A_UINT16 protocolReasonStatus); void ar6000_tkip_micerr_event(struct ar6_softc *ar, A_UINT8 keyid, - A_BOOL ismcast); + bool ismcast); void ar6000_bitrate_rx(void *devt, A_INT32 rateKbps); void ar6000_channelList_rx(void *devt, A_INT8 numChan, A_UINT16 *chanList); void ar6000_regDomain_event(struct ar6_softc *ar, A_UINT32 regCode); @@ -79,7 +79,7 @@ void ar6000_gpio_ack_rx(void); A_INT32 rssi_compensation_calc_tcmd(A_UINT32 freq, A_INT32 rssi, A_UINT32 totalPkt); A_INT16 rssi_compensation_calc(struct ar6_softc *ar, A_INT16 rssi); -A_INT16 rssi_compensation_reverse_calc(struct ar6_softc *ar, A_INT16 rssi, A_BOOL Above); +A_INT16 rssi_compensation_reverse_calc(struct ar6_softc *ar, A_INT16 rssi, bool Above); void ar6000_dbglog_init_done(struct ar6_softc *ar); @@ -115,7 +115,7 @@ int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar); void ar6000_peer_event(void *devt, A_UINT8 eventCode, A_UINT8 *bssid); -void ar6000_indicate_tx_activity(void *devt, A_UINT8 trafficClass, A_BOOL Active); +void ar6000_indicate_tx_activity(void *devt, A_UINT8 trafficClass, bool Active); HTC_ENDPOINT_ID ar6000_ac2_endpoint_id ( void * devt, A_UINT8 ac); A_UINT8 ar6000_endpoint_id2_ac (void * devt, HTC_ENDPOINT_ID ep ); @@ -171,7 +171,7 @@ void ap_wapi_rekey_event(struct ar6_softc *ar, A_UINT8 type, A_UINT8 *mac); #endif int ar6000_connect_to_ap(struct ar6_softc *ar); -int ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, A_BOOL suspending); +int ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool suspending); int ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state); int ar6000_set_bt_hw_state(struct ar6_softc *ar, A_UINT32 state); @@ -179,7 +179,7 @@ int ar6000_set_bt_hw_state(struct ar6_softc *ar, A_UINT32 state); int ar6000_suspend_ev(void *context); int ar6000_resume_ev(void *context); int ar6000_power_change_ev(void *context, A_UINT32 config); -void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, A_BOOL isEvent); +void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent); #endif void ar6000_pm_init(void); diff --git a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h index 53bbb4837d30..15b6b0832af4 100644 --- a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h @@ -531,7 +531,7 @@ typedef enum { * UINT32 cmd (AR6000_XIOCTL_WMI_STARTSCAN) * UINT8 scanType * UINT8 scanConnected - * A_BOOL forceFgScan + * u32 forceFgScan * uses: WMI_START_SCAN_CMDID */ @@ -643,7 +643,7 @@ typedef enum { * arguments: * UINT8 cmd (AR6000_XIOCTL_WMI_GET_KEEPALIVE) * UINT8 keepaliveInterval - * A_BOOL configured + * u32 configured * uses: WMI_GET_KEEPALIVE_CMDID */ @@ -1134,7 +1134,7 @@ typedef struct ar6000_dbglog_module_config_s { A_UINT32 valid; A_UINT16 mmask; A_UINT16 tsr; - A_BOOL rep; + u32 rep; A_UINT16 size; } DBGLOG_MODULE_CONFIG; diff --git a/drivers/staging/ath6kl/os/linux/include/athtypes_linux.h b/drivers/staging/ath6kl/os/linux/include/athtypes_linux.h index 9d9ecbb2a4d7..32bd29ba455d 100644 --- a/drivers/staging/ath6kl/os/linux/include/athtypes_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/athtypes_linux.h @@ -44,7 +44,6 @@ typedef u_int16_t A_UINT16; typedef u_int32_t A_UINT32; typedef u_int64_t A_UINT64; -typedef int A_BOOL; typedef char A_CHAR; typedef unsigned char A_UCHAR; typedef unsigned long A_ATH_TIMER; diff --git a/drivers/staging/ath6kl/os/linux/include/cfg80211.h b/drivers/staging/ath6kl/os/linux/include/cfg80211.h index 4494410972fb..a32cdcdfd955 100644 --- a/drivers/staging/ath6kl/os/linux/include/cfg80211.h +++ b/drivers/staging/ath6kl/os/linux/include/cfg80211.h @@ -39,7 +39,7 @@ void ar6k_cfg80211_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, A_UINT8 *bssid, A_UINT8 assocRespLen, A_UINT8 *assocInfo, A_UINT16 protocolReasonStatus); -void ar6k_cfg80211_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, A_BOOL ismcast); +void ar6k_cfg80211_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, bool ismcast); #endif /* _AR6K_CFG80211_H_ */ diff --git a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h index 49a5d3fece48..08a0700e470b 100644 --- a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h +++ b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h @@ -28,15 +28,15 @@ extern HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, HCI_TRANSPORT_CONFIG_INFO *pInfo); extern void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans); extern int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue); -extern int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, A_BOOL Synchronous); +extern int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, bool Synchronous); extern void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans); extern int (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans); -extern int (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable); +extern int (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); extern int (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, int MaxPollMS); extern int (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud); -extern int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable); +extern int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); #define HCI_TransportAttach(HTCHandle, pInfo) \ diff --git a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h index cdbda890939b..bf034cdfa893 100644 --- a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h @@ -116,7 +116,7 @@ typedef spinlock_t A_MUTEX_T; #define A_MUTEX_INIT(mutex) spin_lock_init(mutex) #define A_MUTEX_LOCK(mutex) spin_lock_bh(mutex) #define A_MUTEX_UNLOCK(mutex) spin_unlock_bh(mutex) -#define A_IS_MUTEX_VALID(mutex) TRUE /* okay to return true, since A_MUTEX_DELETE does nothing */ +#define A_IS_MUTEX_VALID(mutex) true /* okay to return true, since A_MUTEX_DELETE does nothing */ #define A_MUTEX_DELETE(mutex) /* spin locks are not kernel resources so nothing to free.. */ /* Get current time in ms adding a constant offset (in ms) */ @@ -247,7 +247,7 @@ typedef struct sk_buff_head A_NETBUF_QUEUE_T; #define A_NETBUF_QUEUE_SIZE(q) \ a_netbuf_queue_size(q) #define A_NETBUF_QUEUE_EMPTY(q) \ - (a_netbuf_queue_empty(q) ? TRUE : FALSE) + (a_netbuf_queue_empty(q) ? true : false) /* * Network buffer support diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index 9a508c48fc53..a120a5c3fc88 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -41,7 +41,7 @@ ar6000_ioctl_get_roam_tbl(struct net_device *dev, struct ifreq *rq) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -57,7 +57,7 @@ ar6000_ioctl_get_roam_data(struct net_device *dev, struct ifreq *rq) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -78,7 +78,7 @@ ar6000_ioctl_set_roam_ctrl(struct net_device *dev, char *userdata) WMI_SET_ROAM_CTRL_CMD cmd; A_UINT8 size = sizeof(cmd); - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -111,7 +111,7 @@ ar6000_ioctl_set_powersave_timers(struct net_device *dev, char *userdata) WMI_POWERSAVE_TIMERS_POLICY_CMD cmd; A_UINT8 size = sizeof(cmd); - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -140,7 +140,7 @@ ar6000_ioctl_set_qos_supp(struct net_device *dev, struct ifreq *rq) if ((dev->flags & IFF_UP) != IFF_UP) { return -EIO; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -175,7 +175,7 @@ ar6000_ioctl_set_wmm(struct net_device *dev, struct ifreq *rq) if ((dev->flags & IFF_UP) != IFF_UP) { return -EIO; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -186,9 +186,9 @@ ar6000_ioctl_set_wmm(struct net_device *dev, struct ifreq *rq) } if (cmd.status == WMI_WMM_ENABLED) { - ar->arWmmEnabled = TRUE; + ar->arWmmEnabled = true; } else { - ar->arWmmEnabled = FALSE; + ar->arWmmEnabled = false; } ret = wmi_set_wmm_cmd(ar->arWmi, cmd.status); @@ -216,7 +216,7 @@ ar6000_ioctl_set_txop(struct net_device *dev, struct ifreq *rq) if ((dev->flags & IFF_UP) != IFF_UP) { return -EIO; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -247,7 +247,7 @@ ar6000_ioctl_get_rd(struct net_device *dev, struct ifreq *rq) AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); int ret = 0; - if ((dev->flags & IFF_UP) != IFF_UP || ar->arWmiReady == FALSE) { + if ((dev->flags & IFF_UP) != IFF_UP || ar->arWmiReady == false) { return -EIO; } @@ -268,7 +268,7 @@ ar6000_ioctl_set_country(struct net_device *dev, struct ifreq *rq) if ((dev->flags & IFF_UP) != IFF_UP) { return -EIO; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -305,7 +305,7 @@ ar6000_ioctl_get_power_mode(struct net_device *dev, struct ifreq *rq) WMI_POWER_MODE_CMD power_mode; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -325,7 +325,7 @@ ar6000_ioctl_set_channelParams(struct net_device *dev, struct ifreq *rq) WMI_CHANNEL_PARAMS_CMD cmd, *cmdp; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -386,7 +386,7 @@ ar6000_ioctl_set_snr_threshold(struct net_device *dev, struct ifreq *rq) WMI_SNR_THRESHOLD_PARAMS_CMD cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -420,7 +420,7 @@ ar6000_ioctl_set_rssi_threshold(struct net_device *dev, struct ifreq *rq) A_INT32 i, j; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -462,9 +462,9 @@ ar6000_ioctl_set_rssi_threshold(struct net_device *dev, struct ifreq *rq) if (enablerssicompensation) { for (i = 0; i < 6; i++) - ar->rssi_map[i].rssi = rssi_compensation_reverse_calc(ar, ar->rssi_map[i].rssi, TRUE); + ar->rssi_map[i].rssi = rssi_compensation_reverse_calc(ar, ar->rssi_map[i].rssi, true); for (i = 6; i < 12; i++) - ar->rssi_map[i].rssi = rssi_compensation_reverse_calc(ar, ar->rssi_map[i].rssi, FALSE); + ar->rssi_map[i].rssi = rssi_compensation_reverse_calc(ar, ar->rssi_map[i].rssi, false); } cmd.thresholdAbove1_Val = ar->rssi_map[0].rssi; @@ -495,7 +495,7 @@ ar6000_ioctl_set_lq_threshold(struct net_device *dev, struct ifreq *rq) WMI_LQ_THRESHOLD_PARAMS_CMD cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -518,7 +518,7 @@ ar6000_ioctl_set_probedSsid(struct net_device *dev, struct ifreq *rq) WMI_PROBED_SSID_CMD cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -542,7 +542,7 @@ ar6000_ioctl_set_badAp(struct net_device *dev, struct ifreq *rq) WMI_ADD_BAD_AP_CMD cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -578,7 +578,7 @@ ar6000_ioctl_create_qos(struct net_device *dev, struct ifreq *rq) WMI_CREATE_PSTREAM_CMD cmd; int ret; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -611,7 +611,7 @@ ar6000_ioctl_delete_qos(struct net_device *dev, struct ifreq *rq) WMI_DELETE_PSTREAM_CMD cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -641,7 +641,7 @@ ar6000_ioctl_get_qos_queue(struct net_device *dev, struct ifreq *rq) struct ar6000_queuereq qreq; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -673,7 +673,7 @@ ar6000_ioctl_tcmd_get_rx_report(struct net_device *dev, return -EBUSY; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -746,7 +746,7 @@ ar6000_ioctl_set_error_report_bitmask(struct net_device *dev, struct ifreq *rq) WMI_TARGET_ERROR_REPORT_BITMASK cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -766,7 +766,7 @@ ar6000_clear_target_stats(struct net_device *dev) TARGET_STATS *pStats = &ar->arTargetStats; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } AR6000_SPIN_LOCK(&ar->arLock, 0); @@ -786,7 +786,7 @@ ar6000_ioctl_get_target_stats(struct net_device *dev, struct ifreq *rq) if (ar->bIsDestroyProgress) { return -EBUSY; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { @@ -800,14 +800,14 @@ ar6000_ioctl_get_target_stats(struct net_device *dev, struct ifreq *rq) return -EBUSY; } - ar->statsUpdatePending = TRUE; + ar->statsUpdatePending = true; if(wmi_get_stats_cmd(ar->arWmi) != A_OK) { up(&ar->arSem); return -EIO; } - wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, wmitimeout * HZ); + wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == false, wmitimeout * HZ); if (signal_pending(current)) { ret = -EINTR; @@ -834,7 +834,7 @@ ar6000_ioctl_get_ap_stats(struct net_device *dev, struct ifreq *rq) WMI_AP_MODE_STAT *pStats = &ar->arAPStats; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } if (copy_from_user(&action, (char *)((unsigned int*)rq->ifr_data + 1), @@ -863,14 +863,14 @@ ar6000_ioctl_get_ap_stats(struct net_device *dev, struct ifreq *rq) return -ERESTARTSYS; } - ar->statsUpdatePending = TRUE; + ar->statsUpdatePending = true; if(wmi_get_stats_cmd(ar->arWmi) != A_OK) { up(&ar->arSem); return -EIO; } - wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, wmitimeout * HZ); + wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == false, wmitimeout * HZ); if (signal_pending(current)) { ret = -EINTR; @@ -892,7 +892,7 @@ ar6000_ioctl_set_access_params(struct net_device *dev, struct ifreq *rq) WMI_SET_ACCESS_PARAMS_CMD cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -918,7 +918,7 @@ ar6000_ioctl_set_disconnect_timeout(struct net_device *dev, struct ifreq *rq) WMI_DISC_TIMEOUT_CMD cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -943,7 +943,7 @@ ar6000_xioctl_set_voice_pkt_size(struct net_device *dev, char * userdata) WMI_SET_VOICE_PKT_SIZE_CMD cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -969,7 +969,7 @@ ar6000_xioctl_set_max_sp_len(struct net_device *dev, char * userdata) WMI_SET_MAX_SP_LEN_CMD cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -995,7 +995,7 @@ ar6000_xioctl_set_bt_status_cmd(struct net_device *dev, char * userdata) WMI_SET_BT_STATUS_CMD cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -1020,7 +1020,7 @@ ar6000_xioctl_set_bt_params_cmd(struct net_device *dev, char * userdata) WMI_SET_BT_PARAMS_CMD cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -1045,7 +1045,7 @@ ar6000_xioctl_set_btcoex_fe_ant_cmd(struct net_device * dev, char * userdata) WMI_SET_BTCOEX_FE_ANT_CMD cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } if (copy_from_user(&cmd, userdata, sizeof(cmd))) { @@ -1069,7 +1069,7 @@ ar6000_xioctl_set_btcoex_colocated_bt_dev_cmd(struct net_device * dev, char * us WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -1094,7 +1094,7 @@ ar6000_xioctl_set_btcoex_btinquiry_page_config_cmd(struct net_device * dev, cha WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -1119,7 +1119,7 @@ ar6000_xioctl_set_btcoex_sco_config_cmd(struct net_device * dev, char * userdata WMI_SET_BTCOEX_SCO_CONFIG_CMD cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -1145,7 +1145,7 @@ ar6000_xioctl_set_btcoex_a2dp_config_cmd(struct net_device * dev, WMI_SET_BTCOEX_A2DP_CONFIG_CMD cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -1170,7 +1170,7 @@ ar6000_xioctl_set_btcoex_aclcoex_config_cmd(struct net_device * dev, char * user WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -1195,7 +1195,7 @@ ar60000_xioctl_set_btcoex_debug_cmd(struct net_device * dev, char * userdata) WMI_SET_BTCOEX_DEBUG_CMD cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -1220,7 +1220,7 @@ ar6000_xioctl_set_btcoex_bt_operating_status_cmd(struct net_device * dev, char * WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD cmd; int ret = 0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -1251,7 +1251,7 @@ ar6000_xioctl_get_btcoex_config_cmd(struct net_device * dev, char * userdata, if (ar->bIsDestroyProgress) { return -EBUSY; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } if (copy_from_user(&btcoexConfig.configCmd, userdata, sizeof(AR6000_BTCOEX_CONFIG))) { @@ -1267,9 +1267,9 @@ ar6000_xioctl_get_btcoex_config_cmd(struct net_device * dev, char * userdata, return -EIO; } - ar->statsUpdatePending = TRUE; + ar->statsUpdatePending = true; - wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, wmitimeout * HZ); + wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == false, wmitimeout * HZ); if (signal_pending(current)) { ret = -EINTR; @@ -1293,7 +1293,7 @@ ar6000_xioctl_get_btcoex_stats_cmd(struct net_device * dev, char * userdata, str if (ar->bIsDestroyProgress) { return -EBUSY; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -1311,9 +1311,9 @@ ar6000_xioctl_get_btcoex_stats_cmd(struct net_device * dev, char * userdata, str return -EIO; } - ar->statsUpdatePending = TRUE; + ar->statsUpdatePending = true; - wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, wmitimeout * HZ); + wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == false, wmitimeout * HZ); if (signal_pending(current)) { ret = -EINTR; @@ -1333,16 +1333,16 @@ ar6000_xioctl_get_btcoex_stats_cmd(struct net_device * dev, char * userdata, str struct ar6000_gpio_intr_wait_cmd_s gpio_intr_results; /* gpio_reg_results and gpio_data_available are protected by arSem */ static struct ar6000_gpio_register_cmd_s gpio_reg_results; -static A_BOOL gpio_data_available; /* Requested GPIO data available */ -static A_BOOL gpio_intr_available; /* GPIO interrupt info available */ -static A_BOOL gpio_ack_received; /* GPIO ack was received */ +static bool gpio_data_available; /* Requested GPIO data available */ +static bool gpio_intr_available; /* GPIO interrupt info available */ +static bool gpio_ack_received; /* GPIO ack was received */ /* Host-side initialization for General Purpose I/O support */ void ar6000_gpio_init(void) { - gpio_intr_available = FALSE; - gpio_data_available = FALSE; - gpio_ack_received = FALSE; + gpio_intr_available = false; + gpio_data_available = false; + gpio_ack_received = false; } /* @@ -1355,7 +1355,7 @@ ar6000_gpio_intr_rx(A_UINT32 intr_mask, A_UINT32 input_values) { gpio_intr_results.intr_mask = intr_mask; gpio_intr_results.input_values = input_values; - *((volatile A_BOOL *)&gpio_intr_available) = TRUE; + *((volatile bool *)&gpio_intr_available) = true; wake_up(&arEvent); } @@ -1369,7 +1369,7 @@ ar6000_gpio_data_rx(A_UINT32 reg_id, A_UINT32 value) { gpio_reg_results.gpioreg_id = reg_id; gpio_reg_results.value = value; - *((volatile A_BOOL *)&gpio_data_available) = TRUE; + *((volatile bool *)&gpio_data_available) = true; wake_up(&arEvent); } @@ -1381,7 +1381,7 @@ ar6000_gpio_data_rx(A_UINT32 reg_id, A_UINT32 value) void ar6000_gpio_ack_rx(void) { - gpio_ack_received = TRUE; + gpio_ack_received = true; wake_up(&arEvent); } @@ -1394,7 +1394,7 @@ ar6000_gpio_output_set(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - gpio_ack_received = FALSE; + gpio_ack_received = false; return wmi_gpio_output_set(ar->arWmi, set_mask, clear_mask, enable_mask, disable_mask); } @@ -1404,7 +1404,7 @@ ar6000_gpio_input_get(struct net_device *dev) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - *((volatile A_BOOL *)&gpio_data_available) = FALSE; + *((volatile bool *)&gpio_data_available) = false; return wmi_gpio_input_get(ar->arWmi); } @@ -1415,7 +1415,7 @@ ar6000_gpio_register_set(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - gpio_ack_received = FALSE; + gpio_ack_received = false; return wmi_gpio_register_set(ar->arWmi, gpioreg_id, value); } @@ -1425,7 +1425,7 @@ ar6000_gpio_register_get(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - *((volatile A_BOOL *)&gpio_data_available) = FALSE; + *((volatile bool *)&gpio_data_available) = false; return wmi_gpio_register_get(ar->arWmi, gpioreg_id); } @@ -1435,21 +1435,21 @@ ar6000_gpio_intr_ack(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - gpio_intr_available = FALSE; + gpio_intr_available = false; return wmi_gpio_intr_ack(ar->arWmi, ack_mask); } #endif /* CONFIG_HOST_GPIO_SUPPORT */ #if defined(CONFIG_TARGET_PROFILE_SUPPORT) static struct prof_count_s prof_count_results; -static A_BOOL prof_count_available; /* Requested GPIO data available */ +static bool prof_count_available; /* Requested GPIO data available */ static int prof_count_get(struct net_device *dev) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - *((volatile A_BOOL *)&prof_count_available) = FALSE; + *((volatile bool *)&prof_count_available) = false; return wmi_prof_count_get_cmd(ar->arWmi); } @@ -1462,7 +1462,7 @@ prof_count_rx(A_UINT32 addr, A_UINT32 count) { prof_count_results.addr = addr; prof_count_results.count = count; - *((volatile A_BOOL *)&prof_count_available) = TRUE; + *((volatile bool *)&prof_count_available) = true; wake_up(&arEvent); } #endif /* CONFIG_TARGET_PROFILE_SUPPORT */ @@ -1506,7 +1506,7 @@ ar6000_create_acl_data_osbuf(struct net_device *dev, A_UINT8 *userdata, void **p ret = A_EFAULT; break; } - } while(FALSE); + } while(false); if (ret == A_OK) { *p_osbuf = osbuf; @@ -1601,7 +1601,7 @@ ar6000_ioctl_ap_setparam(AR_SOFTC_T *ar, int param, int value) int ar6000_ioctl_setparam(AR_SOFTC_T *ar, int param, int value) { - A_BOOL profChanged = FALSE; + bool profChanged = false; int ret=0; if(ar->arNextMode == AP_NETWORK) { @@ -1622,15 +1622,15 @@ ar6000_ioctl_setparam(AR_SOFTC_T *ar, int param, int value) switch (value) { case WPA_MODE_WPA1: ar->arAuthMode = WPA_AUTH; - profChanged = TRUE; + profChanged = true; break; case WPA_MODE_WPA2: ar->arAuthMode = WPA2_AUTH; - profChanged = TRUE; + profChanged = true; break; case WPA_MODE_NONE: ar->arAuthMode = NONE_AUTH; - profChanged = TRUE; + profChanged = true; break; } break; @@ -1639,10 +1639,10 @@ ar6000_ioctl_setparam(AR_SOFTC_T *ar, int param, int value) case IEEE80211_AUTH_WPA_PSK: if (WPA_AUTH == ar->arAuthMode) { ar->arAuthMode = WPA_PSK_AUTH; - profChanged = TRUE; + profChanged = true; } else if (WPA2_AUTH == ar->arAuthMode) { ar->arAuthMode = WPA2_PSK_AUTH; - profChanged = TRUE; + profChanged = true; } else { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Error - Setting PSK "\ "mode when WPA param was set to %d\n", @@ -1665,19 +1665,19 @@ ar6000_ioctl_setparam(AR_SOFTC_T *ar, int param, int value) switch (value) { case IEEE80211_CIPHER_AES_CCM: ar->arPairwiseCrypto = AES_CRYPT; - profChanged = TRUE; + profChanged = true; break; case IEEE80211_CIPHER_TKIP: ar->arPairwiseCrypto = TKIP_CRYPT; - profChanged = TRUE; + profChanged = true; break; case IEEE80211_CIPHER_WEP: ar->arPairwiseCrypto = WEP_CRYPT; - profChanged = TRUE; + profChanged = true; break; case IEEE80211_CIPHER_NONE: ar->arPairwiseCrypto = NONE_CRYPT; - profChanged = TRUE; + profChanged = true; break; } break; @@ -1692,19 +1692,19 @@ ar6000_ioctl_setparam(AR_SOFTC_T *ar, int param, int value) switch (value) { case IEEE80211_CIPHER_AES_CCM: ar->arGroupCrypto = AES_CRYPT; - profChanged = TRUE; + profChanged = true; break; case IEEE80211_CIPHER_TKIP: ar->arGroupCrypto = TKIP_CRYPT; - profChanged = TRUE; + profChanged = true; break; case IEEE80211_CIPHER_WEP: ar->arGroupCrypto = WEP_CRYPT; - profChanged = TRUE; + profChanged = true; break; case IEEE80211_CIPHER_NONE: ar->arGroupCrypto = NONE_CRYPT; - profChanged = TRUE; + profChanged = true; break; } break; @@ -1716,7 +1716,7 @@ ar6000_ioctl_setparam(AR_SOFTC_T *ar, int param, int value) } break; case IEEE80211_PARAM_COUNTERMEASURES: - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } wmi_set_tkip_countermeasures_cmd(ar->arWmi, value); @@ -1724,7 +1724,7 @@ ar6000_ioctl_setparam(AR_SOFTC_T *ar, int param, int value) default: break; } - if ((ar->arNextMode != AP_NETWORK) && (profChanged == TRUE)) { + if ((ar->arNextMode != AP_NETWORK) && (profChanged == true)) { /* * profile has changed. Erase ssid to signal change */ @@ -1742,7 +1742,7 @@ ar6000_ioctl_setkey(AR_SOFTC_T *ar, struct ieee80211req_key *ik) CRYPTO_TYPE keyType = NONE_CRYPT; #ifdef USER_KEYS - ar->user_saved_keys.keyOk = FALSE; + ar->user_saved_keys.keyOk = false; #endif if ( (0 == memcmp(ik->ik_macaddr, null_mac, IEEE80211_ADDR_LEN)) || (0 == memcmp(ik->ik_macaddr, bcast_mac, IEEE80211_ADDR_LEN)) ) { @@ -1834,7 +1834,7 @@ ar6000_ioctl_setkey(AR_SOFTC_T *ar, struct ieee80211req_key *ik) } #ifdef USER_KEYS - ar->user_saved_keys.keyOk = TRUE; + ar->user_saved_keys.keyOk = true; #endif return 0; @@ -1919,7 +1919,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { int param, value; int *ptr = (int *)rq->ifr_ifru.ifru_newname; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else { param = *ptr++; @@ -1931,7 +1931,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case IEEE80211_IOCTL_SETKEY: { struct ieee80211req_key keydata; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&keydata, userdata, sizeof(struct ieee80211req_key))) { @@ -1950,7 +1950,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case IEEE80211_IOCTL_SETMLME: { struct ieee80211req_mlme mlme; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&mlme, userdata, sizeof(struct ieee80211req_mlme))) { @@ -1988,7 +1988,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case IEEE80211_IOCTL_ADDPMKID: { struct ieee80211req_addpmkid req; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&req, userdata, sizeof(struct ieee80211req_addpmkid))) { ret = -EFAULT; @@ -2216,7 +2216,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_HTC_RAW_CLOSE: if (arRawIfEnabled(ar)) { ret = ar6000_htc_raw_close(ar); - arRawIfEnabled(ar) = FALSE; + arRawIfEnabled(ar) = false; } else { ret = A_ERROR; } @@ -2347,7 +2347,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EBUSY; goto ioctl_done; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; goto ioctl_done; } @@ -2361,7 +2361,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) goto ioctl_done; } - prof_count_available = FALSE; + prof_count_available = false; ret = prof_count_get(dev); if (ret != A_OK) { up(&ar->arSem); @@ -2398,7 +2398,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_POWER_MODE_CMD pwrModeCmd; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&pwrModeCmd, userdata, sizeof(pwrModeCmd))) @@ -2417,7 +2417,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_IBSS_PM_CAPS_CMD ibssPmCaps; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&ibssPmCaps, userdata, sizeof(ibssPmCaps))) @@ -2439,7 +2439,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_AP_PS_CMD apPsCmd; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&apPsCmd, userdata, sizeof(apPsCmd))) @@ -2458,7 +2458,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_POWER_PARAMS_CMD pmParams; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&pmParams, userdata, sizeof(pmParams))) @@ -2484,7 +2484,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } case AR6000_IOCTL_WMI_SETSCAN: { - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&ar->scParams, userdata, sizeof(ar->scParams))) @@ -2492,9 +2492,9 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; } else { if (CAN_SCAN_IN_CONNECT(ar->scParams.scanCtrlFlags)) { - ar->arSkipScan = FALSE; + ar->arSkipScan = false; } else { - ar->arSkipScan = TRUE; + ar->arSkipScan = true; } if (wmi_scanparams_cmd(ar->arWmi, ar->scParams.fg_start_period, @@ -2517,7 +2517,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_LISTEN_INT_CMD listenCmd; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&listenCmd, userdata, sizeof(listenCmd))) @@ -2540,7 +2540,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_BMISS_TIME_CMD bmissCmd; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&bmissCmd, userdata, sizeof(bmissCmd))) @@ -2557,7 +2557,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_BSS_FILTER_CMD filt; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&filt, userdata, sizeof(filt))) @@ -2586,7 +2586,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } case AR6000_XIOCTL_WMI_CLR_RSSISNR: { - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } ret = wmi_clr_rssi_snr(ar->arWmi); @@ -2601,7 +2601,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_SET_LPREAMBLE_CMD setLpreambleCmd; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&setLpreambleCmd, userdata, sizeof(setLpreambleCmd))) @@ -2625,7 +2625,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_WMI_SET_RTS: { WMI_SET_RTS_CMD rtsCmd; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&rtsCmd, userdata, sizeof(rtsCmd))) @@ -2707,7 +2707,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) WMI_SET_ASSOC_INFO_CMD cmd; A_UINT8 assocInfo[WMI_MAX_ASSOC_INFO_LEN]; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; break; } @@ -2844,7 +2844,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EBUSY; goto ioctl_done; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; goto ioctl_done; } @@ -2881,7 +2881,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EBUSY; goto ioctl_done; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; goto ioctl_done; } @@ -2926,7 +2926,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EBUSY; goto ioctl_done; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; goto ioctl_done; } @@ -2969,7 +2969,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EBUSY; goto ioctl_done; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; goto ioctl_done; } @@ -3019,7 +3019,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EBUSY; goto ioctl_done; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; goto ioctl_done; } @@ -3099,7 +3099,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_SET_ADHOC_BSSID_CMD adhocBssid; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&adhocBssid, userdata, sizeof(adhocBssid))) @@ -3121,7 +3121,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) WMI_SET_OPT_MODE_CMD optModeCmd; AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&optModeCmd, userdata, sizeof(optModeCmd))) @@ -3143,7 +3143,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) WMI_OPT_TX_FRAME_CMD optTxFrmCmd; A_UINT8 data[MAX_OPT_DATA_LEN]; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&optTxFrmCmd, userdata, sizeof(optTxFrmCmd))) @@ -3169,7 +3169,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_SET_RETRY_LIMITS_CMD setRetryParams; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&setRetryParams, userdata, sizeof(setRetryParams))) @@ -3194,7 +3194,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_BEACON_INT_CMD bIntvlCmd; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&bIntvlCmd, userdata, sizeof(bIntvlCmd))) @@ -3216,7 +3216,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); struct ieee80211req_authalg req; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&req, userdata, sizeof(struct ieee80211req_authalg))) @@ -3326,7 +3326,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_START_SCAN_CMD setStartScanCmd, *cmdp; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&setStartScanCmd, userdata, sizeof(setStartScanCmd))) @@ -3366,7 +3366,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) WMI_FIX_RATES_CMD setFixRatesCmd; int returnStatus; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&setFixRatesCmd, userdata, sizeof(setFixRatesCmd))) @@ -3395,7 +3395,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EBUSY; goto ioctl_done; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; goto ioctl_done; } @@ -3443,7 +3443,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_SET_AUTH_MODE_CMD setAuthMode; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&setAuthMode, userdata, sizeof(setAuthMode))) @@ -3461,7 +3461,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_SET_REASSOC_MODE_CMD setReassocMode; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&setReassocMode, userdata, sizeof(setReassocMode))) @@ -3509,7 +3509,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_WMI_SET_KEEPALIVE: { WMI_SET_KEEPALIVE_CMD setKeepAlive; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; goto ioctl_done; } else if (copy_from_user(&setKeepAlive, userdata, @@ -3525,7 +3525,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_WMI_SET_PARAMS: { WMI_SET_PARAMS_CMD cmd; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; goto ioctl_done; } else if (copy_from_user(&cmd, userdata, @@ -3545,7 +3545,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_WMI_SET_MCAST_FILTER: { WMI_SET_MCAST_FILTER_CMD cmd; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; goto ioctl_done; } else if (copy_from_user(&cmd, userdata, @@ -3564,7 +3564,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_WMI_DEL_MCAST_FILTER: { WMI_SET_MCAST_FILTER_CMD cmd; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; goto ioctl_done; } else if (copy_from_user(&cmd, userdata, @@ -3583,7 +3583,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_WMI_MCAST_FILTER: { WMI_MCAST_FILTER_CMD cmd; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; goto ioctl_done; } else if (copy_from_user(&cmd, userdata, @@ -3605,7 +3605,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret =-EBUSY; goto ioctl_done; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; goto ioctl_done; } @@ -3649,7 +3649,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) A_UINT8 appIeInfo[IEEE80211_APPIE_FRAME_MAX_LEN]; A_UINT32 fType,ieLen; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; goto ioctl_done; } @@ -3715,7 +3715,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { A_UINT32 wsc_status; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; goto ioctl_done; } else if (copy_from_user(&wsc_status, userdata, sizeof(A_UINT32))) @@ -3804,7 +3804,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_SET_IP_CMD setIP; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&setIP, userdata, sizeof(setIP))) @@ -3824,7 +3824,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_SET_HOST_SLEEP_MODE_CMD setHostSleepMode; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&setHostSleepMode, userdata, sizeof(setHostSleepMode))) @@ -3843,7 +3843,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_SET_WOW_MODE_CMD setWowMode; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&setWowMode, userdata, sizeof(setWowMode))) @@ -3862,7 +3862,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_GET_WOW_LIST_CMD getWowList; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&getWowList, userdata, sizeof(getWowList))) @@ -3887,7 +3887,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) A_UINT8 pattern_data[WOW_PATTERN_SIZE]={0}; do { - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; break; } @@ -3916,7 +3916,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { ret = -EIO; } - } while(FALSE); + } while(false); #undef WOW_PATTERN_SIZE #undef WOW_MASK_SIZE break; @@ -3925,7 +3925,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_DEL_WOW_PATTERN_CMD delWowPattern; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&delWowPattern, userdata, sizeof(delWowPattern))) @@ -3998,11 +3998,11 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) * change using the stream ID as the traffic class */ ar6000_indicate_tx_activity(ar, (A_UINT8)data.StreamID, - data.Active ? TRUE : FALSE); + data.Active ? true : false); } break; case AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS: - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&connectCtrlFlags, userdata, sizeof(connectCtrlFlags))) @@ -4013,7 +4013,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } break; case AR6000_XIOCTL_WMI_SET_AKMP_PARAMS: - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&akmpParams, userdata, sizeof(WMI_SET_AKMP_PARAMS_CMD))) @@ -4026,7 +4026,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } break; case AR6000_XIOCTL_WMI_SET_PMKID_LIST: - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else { if (copy_from_user(&pmkidInfo.numPMKID, userdata, @@ -4048,7 +4048,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } break; case AR6000_XIOCTL_WMI_GET_PMKID_LIST: - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else { if (wmi_get_pmkid_list_cmd(ar->arWmi) != A_OK) { @@ -4057,7 +4057,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } break; case AR6000_XIOCTL_WMI_ABORT_SCAN: - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } ret = wmi_abort_scan_cmd(ar->arWmi); @@ -4065,7 +4065,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_AP_HIDDEN_SSID: { A_UINT8 hidden_ssid; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&hidden_ssid, userdata, sizeof(hidden_ssid))) { ret = -EFAULT; @@ -4078,7 +4078,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } case AR6000_XIOCTL_AP_GET_STA_LIST: { - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else { A_UINT8 i; @@ -4101,7 +4101,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_AP_SET_NUM_STA: { A_UINT8 num_sta; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&num_sta, userdata, sizeof(num_sta))) { ret = -EFAULT; @@ -4116,7 +4116,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_AP_SET_ACL_POLICY: { A_UINT8 policy; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&policy, userdata, sizeof(policy))) { ret = -EFAULT; @@ -4135,7 +4135,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_AP_SET_ACL_MAC: { WMI_AP_ACL_MAC_CMD acl; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&acl, userdata, sizeof(acl))) { ret = -EFAULT; @@ -4151,7 +4151,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } case AR6000_XIOCTL_AP_GET_ACL_LIST: { - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if(copy_to_user((WMI_AP_ACL *)rq->ifr_data, &ar->g_acl, sizeof(WMI_AP_ACL))) { @@ -4167,7 +4167,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case IEEE80211_IOCTL_GETWPAIE: { struct ieee80211req_wpaie wpaie; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&wpaie, userdata, sizeof(wpaie))) { ret = -EFAULT; @@ -4181,7 +4181,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_AP_CONN_INACT_TIME: { A_UINT32 period; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&period, userdata, sizeof(period))) { ret = -EFAULT; @@ -4193,7 +4193,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_AP_PROT_SCAN_TIME: { WMI_AP_PROT_SCAN_TIME_CMD bgscan; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&bgscan, userdata, sizeof(bgscan))) { ret = -EFAULT; @@ -4210,7 +4210,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_AP_SET_DTIM: { WMI_AP_SET_DTIM_CMD d; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&d, userdata, sizeof(d))) { ret = -EFAULT; @@ -4230,7 +4230,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_SET_TARGET_EVENT_REPORT_CMD evtCfgCmd; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } if (copy_from_user(&evtCfgCmd, userdata, @@ -4244,7 +4244,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_AP_INTRA_BSS_COMM: { A_UINT8 intra=0; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&intra, userdata, sizeof(intra))) { ret = -EFAULT; @@ -4317,7 +4317,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_ADDBA_REQ_CMD cmd; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) { ret = -EFAULT; @@ -4331,7 +4331,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_DELBA_REQ_CMD cmd; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) { ret = -EFAULT; @@ -4345,7 +4345,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_ALLOW_AGGR_CMD cmd; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) { ret = -EFAULT; @@ -4357,7 +4357,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_SET_HT_CAP: { - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&htCap, userdata, sizeof(htCap))) @@ -4374,7 +4374,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } case AR6000_XIOCTL_SET_HT_OP: { - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&htOp, userdata, sizeof(htOp))) @@ -4393,7 +4393,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_ACL_DATA: { void *osbuf = NULL; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (ar6000_create_acl_data_osbuf(dev, (A_UINT8*)userdata, &osbuf) != A_OK) { ret = -EIO; @@ -4415,7 +4415,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) A_UINT8 size; size = sizeof(cmd->cmd_buf_sz); - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(cmd, userdata, size)) { ret = -EFAULT; @@ -4441,7 +4441,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_WLAN_CONN_PRECEDENCE: { WMI_SET_BT_WLAN_CONN_PRECEDENCE cmd; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) { ret = -EFAULT; @@ -4466,7 +4466,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_SET_TX_SELECT_RATES_CMD masks; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&masks, userdata, sizeof(masks))) @@ -4486,7 +4486,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) WMI_AP_HIDDEN_SSID_CMD ssid; ssid.hidden_ssid = ar->ap_hidden_ssid; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if(copy_to_user((WMI_AP_HIDDEN_SSID_CMD *)rq->ifr_data, &ssid, sizeof(WMI_AP_HIDDEN_SSID_CMD))) { @@ -4499,7 +4499,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) WMI_AP_SET_COUNTRY_CMD cty; A_MEMCPY(cty.countryCode, ar->ap_country_code, 3); - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if(copy_to_user((WMI_AP_SET_COUNTRY_CMD *)rq->ifr_data, &cty, sizeof(WMI_AP_SET_COUNTRY_CMD))) { @@ -4509,7 +4509,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } case AR6000_XIOCTL_AP_GET_WMODE: { - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if(copy_to_user((A_UINT8 *)rq->ifr_data, &ar->ap_wmode, sizeof(A_UINT8))) { @@ -4522,7 +4522,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) WMI_AP_SET_DTIM_CMD dtim; dtim.dtim = ar->ap_dtim_period; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if(copy_to_user((WMI_AP_SET_DTIM_CMD *)rq->ifr_data, &dtim, sizeof(WMI_AP_SET_DTIM_CMD))) { @@ -4535,7 +4535,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) WMI_BEACON_INT_CMD bi; bi.beaconInterval = ar->ap_beacon_interval; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if(copy_to_user((WMI_BEACON_INT_CMD *)rq->ifr_data, &bi, sizeof(WMI_BEACON_INT_CMD))) { @@ -4548,7 +4548,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) WMI_SET_RTS_CMD rts; rts.threshold = ar->arRTS; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if(copy_to_user((WMI_SET_RTS_CMD *)rq->ifr_data, &rts, sizeof(WMI_SET_RTS_CMD))) { @@ -4574,7 +4574,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_AP_SET_11BG_RATESET: { WMI_AP_SET_11BG_RATESET_CMD rate; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&rate, userdata, sizeof(rate))) { ret = -EFAULT; @@ -4620,7 +4620,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_SET_TX_SGI_PARAM_CMD SGICmd; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&SGICmd, userdata, sizeof(SGICmd))){ diff --git a/drivers/staging/ath6kl/os/linux/wireless_ext.c b/drivers/staging/ath6kl/os/linux/wireless_ext.c index ea933d0d9392..eb964692649b 100644 --- a/drivers/staging/ath6kl/os/linux/wireless_ext.c +++ b/drivers/staging/ath6kl/os/linux/wireless_ext.c @@ -429,7 +429,7 @@ ar6000_ioctl_giwscan(struct net_device *dev, return -EIO; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -480,7 +480,7 @@ ar6000_ioctl_siwessid(struct net_device *dev, return -EIO; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -532,7 +532,7 @@ ar6000_ioctl_siwessid(struct net_device *dev, and we cannot scan during connect. */ if (data->flags) { - if (ar->arSkipScan == TRUE && + if (ar->arSkipScan == true && (ar->arChannelHint == 0 || (!ar->arReqBssid[0] && !ar->arReqBssid[1] && !ar->arReqBssid[2] && !ar->arReqBssid[3] && !ar->arReqBssid[4] && !ar->arReqBssid[5]))) @@ -592,13 +592,13 @@ ar6000_ioctl_siwessid(struct net_device *dev, * (2) essid off has been issued * */ - if (ar->arWmiReady == TRUE) { + if (ar->arWmiReady == true) { reconnect_flag = 0; status = wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, 0); status = wmi_disconnect_cmd(ar->arWmi); A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); ar->arSsidLen = 0; - if (ar->arSkipScan == FALSE) { + if (ar->arSkipScan == false) { A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); } if (!data->flags) { @@ -617,9 +617,9 @@ ar6000_ioctl_siwessid(struct net_device *dev, * a reconnect cmd. Issue a reconnect only we are already * connected. */ - if((ar->arConnected == TRUE) && (ar->arWmiReady == TRUE)) + if((ar->arConnected == true) && (ar->arWmiReady == true)) { - reconnect_flag = TRUE; + reconnect_flag = true; status = wmi_reconnect_cmd(ar->arWmi,ar->arReqBssid, ar->arChannelHint); up(&ar->arSem); @@ -732,7 +732,7 @@ ar6000_ioctl_siwrate(struct net_device *dev, return -EINVAL; } ar->arBitRate = kbps; - if(ar->arWmiReady == TRUE) + if(ar->arWmiReady == true) { if (wmi_set_bitrate_cmd(ar->arWmi, kbps, -1, -1) != A_OK) { return -EINVAL; @@ -765,7 +765,7 @@ ar6000_ioctl_giwrate(struct net_device *dev, return -EIO; } - if ((ar->arNextMode != AP_NETWORK && !ar->arConnected) || ar->arWmiReady == FALSE) { + if ((ar->arNextMode != AP_NETWORK && !ar->arConnected) || ar->arWmiReady == false) { rrq->value = 1000 * 1000; return 0; } @@ -792,7 +792,7 @@ ar6000_ioctl_giwrate(struct net_device *dev, connected - return the value stored in the device structure */ if (!ret) { if (ar->arBitRate == -1) { - rrq->fixed = TRUE; + rrq->fixed = true; rrq->value = 0; } else { rrq->value = ar->arBitRate * 1000; @@ -833,12 +833,12 @@ ar6000_ioctl_siwtxpow(struct net_device *dev, return -EOPNOTSUPP; } ar->arTxPwr= dbM = rrq->value; - ar->arTxPwrSet = TRUE; + ar->arTxPwrSet = true; } else { ar->arTxPwr = dbM = 0; - ar->arTxPwrSet = FALSE; + ar->arTxPwrSet = false; } - if(ar->arWmiReady == TRUE) + if(ar->arWmiReady == true) { AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("Set tx pwr cmd %d dbM\n", dbM)); wmi_set_txPwr_cmd(ar->arWmi, dbM); @@ -879,7 +879,7 @@ ar6000_ioctl_giwtxpow(struct net_device *dev, return -EBUSY; } - if((ar->arWmiReady == TRUE) && (ar->arConnected == TRUE)) + if((ar->arWmiReady == true) && (ar->arConnected == true)) { ar->arTxPwr = 0; @@ -898,8 +898,8 @@ ar6000_ioctl_giwtxpow(struct net_device *dev, then return value stored in the device structure */ if (!ret) { - if (ar->arTxPwrSet == TRUE) { - rrq->fixed = TRUE; + if (ar->arTxPwrSet == true) { + rrq->fixed = true; } rrq->value = ar->arTxPwr; rrq->flags = IW_TXPOW_DBM; @@ -946,7 +946,7 @@ ar6000_ioctl_siwretry(struct net_device *dev, if ( !(rrq->value >= WMI_MIN_RETRIES) || !(rrq->value <= WMI_MAX_RETRIES)) { return - EINVAL; } - if(ar->arWmiReady == TRUE) + if(ar->arWmiReady == true) { if (wmi_set_retry_limits_cmd(ar->arWmi, DATA_FRAMETYPE, WMM_AC_BE, rrq->value, 0) != A_OK){ @@ -1201,7 +1201,7 @@ ar6000_ioctl_siwgenie(struct net_device *dev, A_UINT8 wapi_ie[128]; #endif - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } #ifdef WAPI_ENABLE @@ -1230,7 +1230,7 @@ ar6000_ioctl_giwgenie(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } erq->length = 0; @@ -1249,12 +1249,12 @@ ar6000_ioctl_siwauth(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - A_BOOL profChanged; + bool profChanged; A_UINT16 param; A_INT32 ret; A_INT32 value; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -1264,7 +1264,7 @@ ar6000_ioctl_siwauth(struct net_device *dev, param = data->flags & IW_AUTH_INDEX; value = data->value; - profChanged = TRUE; + profChanged = true; ret = 0; switch (param) { @@ -1277,7 +1277,7 @@ ar6000_ioctl_siwauth(struct net_device *dev, ar->arAuthMode = WPA2_AUTH; } else { ret = -1; - profChanged = FALSE; + profChanged = false; } break; case IW_AUTH_CIPHER_PAIRWISE: @@ -1298,7 +1298,7 @@ ar6000_ioctl_siwauth(struct net_device *dev, ar->arPairwiseCryptoLen = 13; } else { ret = -1; - profChanged = FALSE; + profChanged = false; } break; case IW_AUTH_CIPHER_GROUP: @@ -1319,7 +1319,7 @@ ar6000_ioctl_siwauth(struct net_device *dev, ar->arGroupCryptoLen = 13; } else { ret = -1; - profChanged = FALSE; + profChanged = false; } break; case IW_AUTH_KEY_MGMT: @@ -1337,10 +1337,10 @@ ar6000_ioctl_siwauth(struct net_device *dev, break; case IW_AUTH_TKIP_COUNTERMEASURES: wmi_set_tkip_countermeasures_cmd(ar->arWmi, value); - profChanged = FALSE; + profChanged = false; break; case IW_AUTH_DROP_UNENCRYPTED: - profChanged = FALSE; + profChanged = false; break; case IW_AUTH_80211_AUTH_ALG: ar->arDot11AuthMode = 0; @@ -1355,7 +1355,7 @@ ar6000_ioctl_siwauth(struct net_device *dev, } if(ar->arDot11AuthMode == 0) { ret = -1; - profChanged = FALSE; + profChanged = false; } break; case IW_AUTH_WPA_ENABLED: @@ -1374,10 +1374,10 @@ ar6000_ioctl_siwauth(struct net_device *dev, } break; case IW_AUTH_RX_UNENCRYPTED_EAPOL: - profChanged = FALSE; + profChanged = false; break; case IW_AUTH_ROAMING_CONTROL: - profChanged = FALSE; + profChanged = false; break; case IW_AUTH_PRIVACY_INVOKED: if (!value) { @@ -1394,11 +1394,11 @@ ar6000_ioctl_siwauth(struct net_device *dev, #endif default: ret = -1; - profChanged = FALSE; + profChanged = false; break; } - if (profChanged == TRUE) { + if (profChanged == true) { /* * profile has changed. Erase ssid to signal change */ @@ -1422,7 +1422,7 @@ ar6000_ioctl_giwauth(struct net_device *dev, A_UINT16 param; A_INT32 ret; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -1553,7 +1553,7 @@ ar6000_ioctl_siwpmksa(struct net_device *dev, pmksa = (struct iw_pmksa *)extra; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -1562,13 +1562,13 @@ ar6000_ioctl_siwpmksa(struct net_device *dev, switch (pmksa->cmd) { case IW_PMKSA_ADD: - status = wmi_setPmkid_cmd(ar->arWmi, (A_UINT8*)pmksa->bssid.sa_data, pmksa->pmkid, TRUE); + status = wmi_setPmkid_cmd(ar->arWmi, (A_UINT8*)pmksa->bssid.sa_data, pmksa->pmkid, true); break; case IW_PMKSA_REMOVE: - status = wmi_setPmkid_cmd(ar->arWmi, (A_UINT8*)pmksa->bssid.sa_data, pmksa->pmkid, FALSE); + status = wmi_setPmkid_cmd(ar->arWmi, (A_UINT8*)pmksa->bssid.sa_data, pmksa->pmkid, false); break; case IW_PMKSA_FLUSH: - if (ar->arConnected == TRUE) { + if (ar->arConnected == true) { status = wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, 0); } break; @@ -1671,7 +1671,7 @@ ar6000_ioctl_siwencodeext(struct net_device *dev, } #ifdef USER_KEYS - ar->user_saved_keys.keyOk = FALSE; + ar->user_saved_keys.keyOk = false; #endif /* USER_KEYS */ index = erq->flags & IW_ENCODE_INDEX; @@ -1811,7 +1811,7 @@ ar6000_ioctl_siwencodeext(struct net_device *dev, memcpy(&ar->user_saved_keys.ucast_ik, &ik, sizeof(struct ieee80211req_key)); } - ar->user_saved_keys.keyOk = TRUE; + ar->user_saved_keys.keyOk = true; #endif /* USER_KEYS */ } @@ -1853,7 +1853,7 @@ static int ar6000_ioctl_siwpower(struct net_device *dev, AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_POWER_MODE power_mode; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -1879,7 +1879,7 @@ static int ar6000_ioctl_giwpower(struct net_device *dev, AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_POWER_MODE power_mode; - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -2026,7 +2026,7 @@ ar6000_ioctl_giwfreq(struct net_device *dev, return -EINVAL; } } else { - if (ar->arConnected != TRUE) { + if (ar->arConnected != true) { return -EINVAL; } else { freq->m = ar->arBssChannel * 100000; @@ -2060,7 +2060,7 @@ ar6000_ioctl_siwmode(struct net_device *dev, /* * clear SSID during mode switch in connected state */ - if(!(ar->arNetworkType == (((*mode) == IW_MODE_INFRA) ? INFRA_NETWORK : ADHOC_NETWORK)) && (ar->arConnected == TRUE) ){ + if(!(ar->arNetworkType == (((*mode) == IW_MODE_INFRA) ? INFRA_NETWORK : ADHOC_NETWORK)) && (ar->arConnected == true) ){ A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); ar->arSsidLen = 0; } @@ -2190,7 +2190,7 @@ ar6000_ioctl_giwrange(struct net_device *dev, return -EBUSY; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -2349,7 +2349,7 @@ ar6000_ioctl_giwap(struct net_device *dev, return 0; } - if (ar->arConnected != TRUE) { + if (ar->arConnected != true) { return -EINVAL; } @@ -2383,7 +2383,7 @@ ar6000_ioctl_siwmlme(struct net_device *dev, return -EIO; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -2404,7 +2404,7 @@ ar6000_ioctl_siwmlme(struct net_device *dev, case IW_MLME_DEAUTH: /* fall through */ case IW_MLME_DISASSOC: - if ((ar->arConnected != TRUE) || + if ((ar->arConnected != true) || (memcmp(ar->arBssid, mlme.addr.sa_data, 6) != 0)) { up(&ar->arSem); @@ -2418,7 +2418,7 @@ ar6000_ioctl_siwmlme(struct net_device *dev, wmi_disconnect_cmd(ar->arWmi); A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); ar->arSsidLen = 0; - if (ar->arSkipScan == FALSE) { + if (ar->arSkipScan == false) { A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); } break; @@ -2468,7 +2468,7 @@ ar6000_ioctl_siwscan(struct net_device *dev, return -EOPNOTSUPP; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -2510,14 +2510,14 @@ ar6000_ioctl_siwscan(struct net_device *dev, return -EIO; if (wmi_probedSsid_cmd(ar->arWmi, 1, SPECIFIC_SSID_FLAG, req.essid_len, req.essid) != A_OK) return -EIO; - ar->scanSpecificSsid = TRUE; + ar->scanSpecificSsid = true; } else { if (ar->scanSpecificSsid) { if (wmi_probedSsid_cmd(ar->arWmi, 1, DISABLE_SSID_FLAG, 0, NULL) != A_OK) return -EIO; - ar->scanSpecificSsid = FALSE; + ar->scanSpecificSsid = false; } } } @@ -2526,13 +2526,13 @@ ar6000_ioctl_siwscan(struct net_device *dev, if (ar->scanSpecificSsid) { if (wmi_probedSsid_cmd(ar->arWmi, 1, DISABLE_SSID_FLAG, 0, NULL) != A_OK) return -EIO; - ar->scanSpecificSsid = FALSE; + ar->scanSpecificSsid = false; } } #endif #endif /* ANDROID_ENV */ - if (wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, FALSE, FALSE, \ + if (wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, false, false, \ 0, 0, 0, NULL) != A_OK) { ret = -EIO; } @@ -2595,7 +2595,7 @@ ar6000_ioctl_siwcommit(struct net_device *dev, return -EOPNOTSUPP; } - if (ar->arWmiReady == FALSE) { + if (ar->arWmiReady == false) { return -EIO; } @@ -2615,8 +2615,8 @@ ar6000_ioctl_siwcommit(struct net_device *dev, * update the host driver association state for the STA|IBSS mode. */ if (ar->arNetworkType != AP_NETWORK && ar->arNextMode == AP_NETWORK) { - ar->arConnectPending = FALSE; - ar->arConnected = FALSE; + ar->arConnectPending = false; + ar->arConnected = false; /* Stop getting pkts from upper stack */ netif_stop_queue(ar->arNetDev); A_MEMZERO(ar->arBssid, sizeof(ar->arBssid)); diff --git a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h index 5dbf8f86f713..5f9bf9b4dc98 100644 --- a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h +++ b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h @@ -61,7 +61,7 @@ typedef enum { typedef struct { void *osbuf; - A_BOOL is_amsdu; + bool is_amsdu; A_UINT16 seq_no; }OSBUF_HOLD_Q; @@ -74,9 +74,9 @@ typedef struct { #endif typedef struct { - A_BOOL aggr; /* is it ON or OFF */ - A_BOOL progress; /* TRUE when frames have arrived after a timer start */ - A_BOOL timerMon; /* TRUE if the timer started for the sake of this TID */ + bool aggr; /* is it ON or OFF */ + bool progress; /* true when frames have arrived after a timer start */ + bool timerMon; /* true if the timer started for the sake of this TID */ A_UINT16 win_sz; /* negotiated window size */ A_UINT16 seq_next; /* Next seq no, in current window */ A_UINT32 hold_q_sz; /* Num of frames that can be held in hold q */ diff --git a/drivers/staging/ath6kl/reorder/rcv_aggr.c b/drivers/staging/ath6kl/reorder/rcv_aggr.c index d53ab15624da..48980d2bdf6a 100644 --- a/drivers/staging/ath6kl/reorder/rcv_aggr.c +++ b/drivers/staging/ath6kl/reorder/rcv_aggr.c @@ -73,7 +73,7 @@ aggr_init(ALLOC_NETBUFS netbuf_allocator) A_MEMZERO(p_aggr, sizeof(AGGR_INFO)); p_aggr->aggr_sz = AGGR_SZ_DEFAULT; A_INIT_TIMER(&p_aggr->timer, aggr_timeout, p_aggr); - p_aggr->timerScheduled = FALSE; + p_aggr->timerScheduled = false; A_NETBUF_QUEUE_INIT(&p_aggr->freeQ); p_aggr->netbuf_allocator = netbuf_allocator; @@ -81,13 +81,13 @@ aggr_init(ALLOC_NETBUFS netbuf_allocator) for(i = 0; i < NUM_OF_TIDS; i++) { rxtid = AGGR_GET_RXTID(p_aggr, i); - rxtid->aggr = FALSE; - rxtid->progress = FALSE; - rxtid->timerMon = FALSE; + rxtid->aggr = false; + rxtid->progress = false; + rxtid->timerMon = false; A_NETBUF_QUEUE_INIT(&rxtid->q); A_MUTEX_INIT(&rxtid->lock); } - }while(FALSE); + }while(false); A_PRINTF("going out of aggr_init..status %s\n", (status == A_OK) ? "OK":"Error"); @@ -115,9 +115,9 @@ aggr_delete_tid_state(AGGR_INFO *p_aggr, A_UINT8 tid) aggr_deque_frms(p_aggr, tid, 0, ALL_SEQNO); } - rxtid->aggr = FALSE; - rxtid->progress = FALSE; - rxtid->timerMon = FALSE; + rxtid->aggr = false; + rxtid->progress = false; + rxtid->timerMon = false; rxtid->win_sz = 0; rxtid->seq_next = 0; rxtid->hold_q_sz = 0; @@ -142,7 +142,7 @@ aggr_module_destroy(void *cntxt) if(p_aggr) { if(p_aggr->timerScheduled) { A_UNTIMEOUT(&p_aggr->timer); - p_aggr->timerScheduled = FALSE; + p_aggr->timerScheduled = false; } for(i = 0; i < NUM_OF_TIDS; i++) { @@ -249,7 +249,7 @@ aggr_recv_addba_req_evt(void *cntxt, A_UINT8 tid, A_UINT16 seq_no, A_UINT8 win_s A_ASSERT(0); } - rxtid->aggr = TRUE; + rxtid->aggr = true; } void @@ -426,7 +426,7 @@ aggr_slice_amsdu(AGGR_INFO *p_aggr, RXTID *rxtid, void **osbuf) } void -aggr_process_recv_frm(void *cntxt, A_UINT8 tid, A_UINT16 seq_no, A_BOOL is_amsdu, void **osbuf) +aggr_process_recv_frm(void *cntxt, A_UINT8 tid, A_UINT16 seq_no, bool is_amsdu, void **osbuf) { AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; RXTID *rxtid; @@ -536,17 +536,17 @@ aggr_process_recv_frm(void *cntxt, A_UINT8 tid, A_UINT16 seq_no, A_BOOL is_amsdu aggr_deque_frms(p_aggr, tid, 0, CONTIGUOUS_SEQNO); if(p_aggr->timerScheduled) { - rxtid->progress = TRUE; + rxtid->progress = true; }else{ for(idx=0 ; idxhold_q_sz ; idx++) { if(rxtid->hold_q[idx].osbuf) { /* there is a frame in the queue and no timer so * start a timer to ensure that the frame doesn't remain * stuck forever. */ - p_aggr->timerScheduled = TRUE; + p_aggr->timerScheduled = true; A_TIMEOUT_MS(&p_aggr->timer, AGGR_RX_TIMEOUT, 0); - rxtid->progress = FALSE; - rxtid->timerMon = TRUE; + rxtid->progress = false; + rxtid->timerMon = true; break; } } @@ -588,9 +588,9 @@ aggr_timeout(A_ATH_TIMER arg) rxtid = AGGR_GET_RXTID(p_aggr, i); stats = AGGR_GET_RXTID_STATS(p_aggr, i); - if(rxtid->aggr == FALSE || - rxtid->timerMon == FALSE || - rxtid->progress == TRUE) { + if(rxtid->aggr == false || + rxtid->timerMon == false || + rxtid->progress == true) { continue; } // dequeue all frames in for this tid @@ -599,25 +599,25 @@ aggr_timeout(A_ATH_TIMER arg) aggr_deque_frms(p_aggr, i, 0, ALL_SEQNO); } - p_aggr->timerScheduled = FALSE; + p_aggr->timerScheduled = false; // determine whether a new timer should be started. for(i = 0; i < NUM_OF_TIDS; i++) { rxtid = AGGR_GET_RXTID(p_aggr, i); - if(rxtid->aggr == TRUE && rxtid->hold_q) { + if(rxtid->aggr == true && rxtid->hold_q) { for(j = 0 ; j < rxtid->hold_q_sz ; j++) { if(rxtid->hold_q[j].osbuf) { - p_aggr->timerScheduled = TRUE; - rxtid->timerMon = TRUE; - rxtid->progress = FALSE; + p_aggr->timerScheduled = true; + rxtid->timerMon = true; + rxtid->progress = false; break; } } if(j >= rxtid->hold_q_sz) { - rxtid->timerMon = FALSE; + rxtid->timerMon = false; } } } diff --git a/drivers/staging/ath6kl/wlan/src/wlan_node.c b/drivers/staging/ath6kl/wlan/src/wlan_node.c index 6ec4e48eb2fd..4cc45c08715d 100644 --- a/drivers/staging/ath6kl/wlan/src/wlan_node.c +++ b/drivers/staging/ath6kl/wlan/src/wlan_node.c @@ -151,7 +151,7 @@ wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni, #ifdef THREAD_X if (!nt->isTimerArmed) { A_TIMEOUT_MS(&nt->nt_inact_timer, timeoutValue, 0); - nt->isTimerArmed = TRUE; + nt->isTimerArmed = true; } #endif @@ -299,7 +299,7 @@ wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt) #ifdef THREAD_X A_INIT_TIMER(&nt->nt_inact_timer, wlan_node_timeout, nt); - nt->isTimerArmed = FALSE; + nt->isTimerArmed = false; #endif nt->nt_wmip = wmip; nt->nt_nodeAge = WLAN_NODE_INACT_TIMEOUT_MSEC; @@ -326,7 +326,7 @@ wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt) { #ifdef THREAD_X bss_t *bss, *nextBss; - A_UINT8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = FALSE; + A_UINT8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = false; wmi_get_current_bssid(nt->nt_wmip, myBssid); @@ -379,7 +379,7 @@ wlan_node_timeout (A_ATH_TIMER arg) { struct ieee80211_node_table *nt = (struct ieee80211_node_table *)arg; bss_t *bss, *nextBss; - A_UINT8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = FALSE; + A_UINT8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = false; A_UINT32 timeoutValue = 0; timeoutValue = nt->nt_nodeAge; @@ -406,7 +406,7 @@ wlan_node_timeout (A_ATH_TIMER arg) * Re-arm timer, only when we have a bss other than * current bss AND it is not aged-out. */ - reArmTimer = TRUE; + reArmTimer = true; } } bss = nextBss; @@ -432,7 +432,7 @@ wlan_node_table_cleanup(struct ieee80211_node_table *nt) bss_t * wlan_find_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid, - A_UINT32 ssidLength, A_BOOL bIsWPA2, A_BOOL bMatchSSID) + A_UINT32 ssidLength, bool bIsWPA2, bool bMatchSSID) { bss_t *ni = NULL; A_UCHAR *pIESsid = NULL; @@ -447,22 +447,22 @@ wlan_find_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid, if (0x00 == memcmp (pSsid, &pIESsid[2], ssidLength)) { // - // Step 2.1 : Check MatchSSID is TRUE, if so, return Matched SSID + // Step 2.1 : Check MatchSSID is true, if so, return Matched SSID // Profile, otherwise check whether WPA2 or WPA // - if (TRUE == bMatchSSID) { + if (true == bMatchSSID) { ieee80211_node_incref (ni); /* mark referenced */ IEEE80211_NODE_UNLOCK (nt); return ni; } // Step 2 : if SSID matches, check WPA or WPA2 - if (TRUE == bIsWPA2 && NULL != ni->ni_cie.ie_rsn) { + if (true == bIsWPA2 && NULL != ni->ni_cie.ie_rsn) { ieee80211_node_incref (ni); /* mark referenced */ IEEE80211_NODE_UNLOCK (nt); return ni; } - if (FALSE == bIsWPA2 && NULL != ni->ni_cie.ie_wpa) { + if (false == bIsWPA2 && NULL != ni->ni_cie.ie_wpa) { ieee80211_node_incref(ni); /* mark referenced */ IEEE80211_NODE_UNLOCK (nt); return ni; diff --git a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c index 2743c4cf604d..e9346bfe0dc4 100644 --- a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c +++ b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c @@ -101,7 +101,7 @@ int wlan_parse_beacon(A_UINT8 *buf, int framelen, struct ieee80211_common_ie *cie) { A_UINT8 *frm, *efrm; - A_UINT8 elemid_ssid = FALSE; + A_UINT8 elemid_ssid = false; frm = buf; efrm = (A_UINT8 *) (frm + framelen); @@ -134,7 +134,7 @@ wlan_parse_beacon(A_UINT8 *buf, int framelen, struct ieee80211_common_ie *cie) case IEEE80211_ELEMID_SSID: if (!elemid_ssid) { cie->ie_ssid = frm; - elemid_ssid = TRUE; + elemid_ssid = true; } break; case IEEE80211_ELEMID_RATES: diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index c384bb2e956e..2b65c087542d 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -152,7 +152,7 @@ wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); static int wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static A_BOOL +static bool wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex); static int @@ -297,7 +297,7 @@ typedef PREPACK struct _iphdr { static A_INT16 rssi_event_value = 0; static A_INT16 snr_event_value = 0; -A_BOOL is_probe_ssid = FALSE; +bool is_probe_ssid = false; void * wmi_init(void *devt) @@ -495,7 +495,7 @@ int wmi_meta_add(struct wmi_t *wmip, void *osbuf, A_UINT8 *pVersion,void *pTxMet /* Adds a WMI data header */ int -wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType, A_BOOL bMoreData, +wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType, bool bMoreData, WMI_DATA_HDR_DATA_TYPE data_type,A_UINT8 metaVersion, void *pTxMetaS) { WMI_DATA_HDR *dtHdr; @@ -531,7 +531,7 @@ wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType, A_BOOL bMoreD } -A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 layer2Priority, A_BOOL wmmEnabled) +A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 layer2Priority, bool wmmEnabled) { A_UINT8 *datap; A_UINT8 trafficClass = WMM_AC_BE; @@ -1232,7 +1232,7 @@ wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_EINVAL; } A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - wmip->wmi_ready = TRUE; + wmip->wmi_ready = true; A_WMI_READY_EVENT(wmip->wmi_devt, ev->macaddr, ev->phyCapability, ev->sw_version, ev->abi_version); @@ -1295,7 +1295,7 @@ wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) { if(iswmmparam (pie)) { - wmip->wmi_is_wmm_enabled = TRUE; + wmip->wmi_is_wmm_enabled = true; } } break; @@ -1368,7 +1368,7 @@ wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) A_MEMZERO(wmip->wmi_bssid, sizeof(wmip->wmi_bssid)); - wmip->wmi_is_wmm_enabled = FALSE; + wmip->wmi_is_wmm_enabled = false; wmip->wmi_pair_crypto_type = NONE_CRYPT; wmip->wmi_grp_crypto_type = NONE_CRYPT; @@ -1475,7 +1475,7 @@ wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) /* In case of hidden AP, beacon will not have ssid, * but a directed probe response will have it, * so cache the probe-resp-ssid if already present. */ - if ((TRUE == is_probe_ssid) && (BEACON_FTYPE == bih->frameType)) + if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType)) { A_UCHAR *ie_ssid; @@ -1510,7 +1510,7 @@ wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) beacon_ssid_len = buf[SSID_IE_LEN_INDEX]; /* If ssid is cached for this hidden AP, then change buffer len accordingly. */ - if ((TRUE == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) && + if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) && (0 != cached_ssid_len) && (0 == beacon_ssid_len || (cached_ssid_len > beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1]))) { @@ -1529,7 +1529,7 @@ wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) /* In case of hidden AP, beacon will not have ssid, * but a directed probe response will have it, * so place the cached-ssid(probe-resp) in the bssinfo. */ - if ((TRUE == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) && + if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) && (0 != cached_ssid_len) && (0 == beacon_ssid_len || (beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1]))) { @@ -1820,7 +1820,7 @@ wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) wlan_refresh_inactive_nodes(&wmip->wmi_scan_table); } A_WMI_SCANCOMPLETE_EVENT(wmip->wmi_devt, (int) ev->status); - is_probe_ssid = FALSE; + is_probe_ssid = false; return A_OK; } @@ -2379,7 +2379,7 @@ wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId, * Only for OPT_TX_CMD, use BE endpoint. */ if (IS_OPT_TX_CMD(cmdId)) { - if ((status=wmi_data_hdr_add(wmip, osbuf, OPT_MSGTYPE, FALSE, FALSE,0,NULL)) != A_OK) { + if ((status=wmi_data_hdr_add(wmip, osbuf, OPT_MSGTYPE, false, false,0,NULL)) != A_OK) { A_NETBUF_FREE(osbuf); return status; } @@ -2511,7 +2511,7 @@ wmi_disconnect_cmd(struct wmi_t *wmip) int wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, - A_BOOL forceFgScan, A_BOOL isLegacy, + u32 forceFgScan, u32 isLegacy, A_UINT32 homeDwellTime, A_UINT32 forceScanInterval, A_INT8 numChan, A_UINT16 *channelList) { @@ -2635,7 +2635,7 @@ wmi_probedSsid_cmd(struct wmi_t *wmip, A_UINT8 index, A_UINT8 flag, } if (flag & SPECIFIC_SSID_FLAG) { - is_probe_ssid = TRUE; + is_probe_ssid = true; } osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); @@ -2950,7 +2950,7 @@ wmi_deleteKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex) int wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId, - A_BOOL set) + bool set) { void *osbuf; WMI_SET_PMKID_CMD *cmd; @@ -2959,7 +2959,7 @@ wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId, return A_EINVAL; } - if ((set == TRUE) && (pmkId == NULL)) { + if ((set == true) && (pmkId == NULL)) { return A_EINVAL; } @@ -2972,7 +2972,7 @@ wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId, cmd = (WMI_SET_PMKID_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid)); - if (set == TRUE) { + if (set == true) { A_MEMCPY(cmd->pmkid, pmkId, sizeof(cmd->pmkid)); cmd->enable = PMKID_ENABLE; } else { @@ -2984,7 +2984,7 @@ wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId, } int -wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, A_BOOL en) +wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, bool en) { void *osbuf; WMI_SET_TKIP_COUNTERMEASURES_CMD *cmd; @@ -2997,7 +2997,7 @@ wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, A_BOOL en) A_NETBUF_PUT(osbuf, sizeof(*cmd)); cmd = (WMI_SET_TKIP_COUNTERMEASURES_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->cm_en = (en == TRUE)? WMI_TKIP_CM_ENABLE : WMI_TKIP_CM_DISABLE; + cmd->cm_en = (en == true)? WMI_TKIP_CM_ENABLE : WMI_TKIP_CM_DISABLE; return (wmi_cmd_send(wmip, osbuf, WMI_SET_TKIP_COUNTERMEASURES_CMDID, NO_SYNC_WMIFLAG)); @@ -3178,7 +3178,7 @@ wmi_sync_point(struct wmi_t *wmip) dataSyncBufs[i].osbuf = NULL; } //end for - } while(FALSE); + } while(false); /* free up any resources left over (possibly due to an error) */ @@ -3451,40 +3451,40 @@ wmi_get_bitrate_cmd(struct wmi_t *wmip) } /* - * Returns TRUE iff the given rate index is legal in the current PHY mode. + * Returns true iff the given rate index is legal in the current PHY mode. */ -A_BOOL +bool wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex) { WMI_PHY_MODE phyMode = (WMI_PHY_MODE) wmip->wmi_phyMode; - A_BOOL isValid = TRUE; + bool isValid = true; switch(phyMode) { case WMI_11A_MODE: if (wmip->wmi_ht_allowed[A_BAND_5GHZ]){ if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) { - isValid = FALSE; + isValid = false; } } else { if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_A_SUPPORT_RATE_STOP)) { - isValid = FALSE; + isValid = false; } } break; case WMI_11B_MODE: if ((rateIndex < MODE_B_SUPPORT_RATE_START) || (rateIndex > MODE_B_SUPPORT_RATE_STOP)) { - isValid = FALSE; + isValid = false; } break; case WMI_11GONLY_MODE: if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){ if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) { - isValid = FALSE; + isValid = false; } } else { if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GONLY_SUPPORT_RATE_STOP)) { - isValid = FALSE; + isValid = false; } } break; @@ -3493,16 +3493,16 @@ wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex) case WMI_11AG_MODE: if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){ if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) { - isValid = FALSE; + isValid = false; } } else { if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_G_SUPPORT_RATE_STOP)) { - isValid = FALSE; + isValid = false; } } break; default: - A_ASSERT(FALSE); + A_ASSERT(false); break; } @@ -3524,7 +3524,7 @@ wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, A_INT8 *rate_idx) } } - if(wmi_is_bitrate_index_valid(wmip, (A_INT32) i) != TRUE) { + if(wmi_is_bitrate_index_valid(wmip, (A_INT32) i) != true) { return A_EINVAL; } @@ -3548,7 +3548,7 @@ wmi_set_fixrates_cmd(struct wmi_t *wmip, A_UINT32 fixRatesMask) /* Make sure all rates in the mask are valid in the current PHY mode */ for(rateIndex = 0; rateIndex < MAX_NUMBER_OF_SUPPORT_RATES; rateIndex++) { if((1 << rateIndex) & (A_UINT32)fixRatesMask) { - if(wmi_is_bitrate_index_valid(wmip, rateIndex) != TRUE) { + if(wmi_is_bitrate_index_valid(wmip, rateIndex) != true) { A_DPRINTF(DBG_WMI, (DBGFMT "Set Fix Rates command failed: Given rate is illegal in current PHY mode\n", DBGARG)); return A_EINVAL; } @@ -4081,7 +4081,7 @@ wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie, A_UINT32 source) int wmi_config_debug_module_cmd(struct wmi_t *wmip, A_UINT16 mmask, - A_UINT16 tsr, A_BOOL rep, A_UINT16 size, + A_UINT16 tsr, bool rep, A_UINT16 size, A_UINT32 valid) { void *osbuf; @@ -5382,7 +5382,7 @@ wmi_set_nodeage(struct wmi_t *wmip, A_UINT32 nodeAge) bss_t * wmi_find_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid, - A_UINT32 ssidLength, A_BOOL bIsWPA2, A_BOOL bMatchSSID) + A_UINT32 ssidLength, bool bIsWPA2, bool bMatchSSID) { bss_t *node = NULL; node = wlan_find_Ssidnode (&wmip->wmi_scan_table, pSsid, @@ -6252,7 +6252,7 @@ wmi_wapi_rekey_event_rx(struct wmi_t *wmip, A_UINT8 *datap,int len) #endif int -wmi_set_pvb_cmd(struct wmi_t *wmip, A_UINT16 aid, A_BOOL flag) +wmi_set_pvb_cmd(struct wmi_t *wmip, A_UINT16 aid, bool flag) { WMI_AP_SET_PVB_CMD *cmd; void *osbuf = NULL; @@ -6510,7 +6510,7 @@ wmi_setup_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid) } int -wmi_delete_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid, A_BOOL uplink) +wmi_delete_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid, bool uplink) { void *osbuf; WMI_DELBA_REQ_CMD *cmd; @@ -6533,7 +6533,7 @@ wmi_delete_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid, A_BOOL uplink) int wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, A_UINT8 rxMetaVersion, - A_BOOL rxDot11Hdr, A_BOOL defragOnHost) + bool rxDot11Hdr, bool defragOnHost) { void *osbuf; WMI_RX_FRAME_FORMAT_CMD *cmd; @@ -6546,8 +6546,8 @@ wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, A_UINT8 rxMetaVersion, A_NETBUF_PUT(osbuf, sizeof(*cmd)); cmd = (WMI_RX_FRAME_FORMAT_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->dot11Hdr = (rxDot11Hdr==TRUE)? 1:0; - cmd->defragOnHost = (defragOnHost==TRUE)? 1:0; + cmd->dot11Hdr = (rxDot11Hdr==true)? 1:0; + cmd->defragOnHost = (defragOnHost==true)? 1:0; cmd->metaVersion = rxMetaVersion; /* */ /* Delete the local aggr state, on host */ @@ -6556,7 +6556,7 @@ wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, A_UINT8 rxMetaVersion, int -wmi_set_thin_mode_cmd(struct wmi_t *wmip, A_BOOL bThinMode) +wmi_set_thin_mode_cmd(struct wmi_t *wmip, bool bThinMode) { void *osbuf; WMI_SET_THIN_MODE_CMD *cmd; @@ -6569,7 +6569,7 @@ wmi_set_thin_mode_cmd(struct wmi_t *wmip, A_BOOL bThinMode) A_NETBUF_PUT(osbuf, sizeof(*cmd)); cmd = (WMI_SET_THIN_MODE_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->enable = (bThinMode==TRUE)? 1:0; + cmd->enable = (bThinMode==true)? 1:0; /* Delete the local aggr state, on host */ return (wmi_cmd_send(wmip, osbuf, WMI_SET_THIN_MODE_CMDID, NO_SYNC_WMIFLAG)); diff --git a/drivers/staging/ath6kl/wmi/wmi_host.h b/drivers/staging/ath6kl/wmi/wmi_host.h index 5c7f7d3c3ce1..c2a64019b0ed 100644 --- a/drivers/staging/ath6kl/wmi/wmi_host.h +++ b/drivers/staging/ath6kl/wmi/wmi_host.h @@ -60,8 +60,8 @@ typedef struct sq_threshold_params_s { #define A_NUM_BANDS 2 struct wmi_t { - A_BOOL wmi_ready; - A_BOOL wmi_numQoSStream; + bool wmi_ready; + bool wmi_numQoSStream; A_UINT16 wmi_streamExistsForAC[WMM_NUM_AC]; A_UINT8 wmi_fatPipeExists; void *wmi_devt; @@ -80,7 +80,7 @@ struct wmi_t { SQ_THRESHOLD_PARAMS wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_NUM_MAX]; CRYPTO_TYPE wmi_pair_crypto_type; CRYPTO_TYPE wmi_grp_crypto_type; - A_BOOL wmi_is_wmm_enabled; + bool wmi_is_wmm_enabled; A_UINT8 wmi_ht_allowed[A_NUM_BANDS]; A_UINT8 wmi_traffic_class; }; -- cgit v1.2.3 From 4c42080f3e4efba6f79fe1840eb0b728f286702d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 2 Feb 2011 14:05:48 -0800 Subject: staging: ath6kl: Convert A_CHAR to char Remove obfuscating A_CHAR uses, just use char. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/include/a_debug.h | 12 +++++----- drivers/staging/ath6kl/include/athbtfilter.h | 2 +- .../include/common/regulatory/reg_dbschema.h | 12 +++++----- drivers/staging/ath6kl/include/common/wmi.h | 2 +- drivers/staging/ath6kl/include/wmi_api.h | 2 +- drivers/staging/ath6kl/miscdrv/ar3kconfig.c | 12 +++++----- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c | 16 ++++++------- drivers/staging/ath6kl/miscdrv/common_drv.c | 12 +++++----- drivers/staging/ath6kl/os/linux/ar6000_android.c | 2 +- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 8 +++---- drivers/staging/ath6kl/os/linux/eeprom.c | 2 +- .../staging/ath6kl/os/linux/include/ar6000_drv.h | 4 ++-- .../staging/ath6kl/os/linux/include/athdrv_linux.h | 2 +- drivers/staging/ath6kl/os/linux/ioctl.c | 28 +++++++++++----------- drivers/staging/ath6kl/os/linux/wireless_ext.c | 6 ++--- drivers/staging/ath6kl/wmi/wmi.c | 2 +- 16 files changed, 62 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/include/a_debug.h b/drivers/staging/ath6kl/include/a_debug.h index 007010cfad99..4cc7b6beffde 100644 --- a/drivers/staging/ath6kl/include/a_debug.h +++ b/drivers/staging/ath6kl/include/a_debug.h @@ -120,15 +120,15 @@ void DebugDumpBytes(A_UCHAR *buffer, A_UINT16 length, char *pDescription); typedef struct { A_UINT32 Mask; - A_CHAR Description[ATH_DEBUG_MAX_MASK_DESC_LENGTH]; + char Description[ATH_DEBUG_MAX_MASK_DESC_LENGTH]; } ATH_DEBUG_MASK_DESCRIPTION; #define ATH_DEBUG_INFO_FLAGS_REGISTERED (1 << 0) typedef struct _ATH_DEBUG_MODULE_DBG_INFO{ struct _ATH_DEBUG_MODULE_DBG_INFO *pNext; - A_CHAR ModuleName[16]; - A_CHAR ModuleDescription[ATH_DEBUG_MAX_MOD_DESC_LENGTH]; + char ModuleName[16]; + char ModuleDescription[ATH_DEBUG_MAX_MOD_DESC_LENGTH]; A_UINT32 Flags; A_UINT32 CurrentMask; int MaxDescriptions; @@ -181,9 +181,9 @@ void a_register_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo); #endif -int a_get_module_mask(A_CHAR *module_name, A_UINT32 *pMask); -int a_set_module_mask(A_CHAR *module_name, A_UINT32 Mask); -void a_dump_module_debug_info_by_name(A_CHAR *module_name); +int a_get_module_mask(char *module_name, A_UINT32 *pMask); +int a_set_module_mask(char *module_name, A_UINT32 Mask); +void a_dump_module_debug_info_by_name(char *module_name); void a_module_debug_support_init(void); void a_module_debug_support_cleanup(void); diff --git a/drivers/staging/ath6kl/include/athbtfilter.h b/drivers/staging/ath6kl/include/athbtfilter.h index dbe68bbb727c..378f96719a17 100644 --- a/drivers/staging/ath6kl/include/athbtfilter.h +++ b/drivers/staging/ath6kl/include/athbtfilter.h @@ -65,7 +65,7 @@ typedef struct _ATHBT_FILTER_INSTANCE { #ifdef UNDER_CE WCHAR *pWlanAdapterName; /* filled in by user */ #else - char *pWlanAdapterName; /* filled in by user */ + char *pWlanAdapterName; /* filled in by user */ #endif /* UNDER_CE */ int FilterEnabled; /* filtering is enabled */ int Attached; /* filter library is attached */ diff --git a/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h b/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h index c6844d69fe47..325d2051eec2 100644 --- a/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h +++ b/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h @@ -125,11 +125,11 @@ enum searchType { */ typedef PREPACK struct dbMasterTable_t { /* Hold ptrs to Table data structures */ A_UCHAR numOfEntries; - A_CHAR entrySize; /* Entry size per table row */ - A_CHAR searchType; /* Index based access or key based */ - A_CHAR reserved[3]; /* for alignment */ + char entrySize; /* Entry size per table row */ + char searchType; /* Index based access or key based */ + char reserved[3]; /* for alignment */ A_UINT16 tableSize; /* Size of this table */ - A_CHAR *dataPtr; /* Ptr to the actual Table */ + char *dataPtr; /* Ptr to the actual Table */ } POSTPACK dbMasterTable; /* Master table - table of tables */ @@ -190,8 +190,8 @@ typedef PREPACK struct reg_dmn_pair_mapping { typedef PREPACK struct { A_UINT16 countryCode; A_UINT16 regDmnEnum; - A_CHAR isoName[3]; - A_CHAR allowMode; /* what mode is allowed - bit 0: OFDM; bit 1: MCS_HT20; bit 2: MCS_HT40_A; bit 3: MCS_HT40_G */ + char isoName[3]; + char allowMode; /* what mode is allowed - bit 0: OFDM; bit 1: MCS_HT20; bit 2: MCS_HT40_A; bit 3: MCS_HT40_G */ } POSTPACK COUNTRY_CODE_TO_ENUM_RD; /* lower 16 bits of ht40ChanMask */ diff --git a/drivers/staging/ath6kl/include/common/wmi.h b/drivers/staging/ath6kl/include/common/wmi.h index eb8f7ba0df2b..70758bfaa134 100644 --- a/drivers/staging/ath6kl/include/common/wmi.h +++ b/drivers/staging/ath6kl/include/common/wmi.h @@ -782,7 +782,7 @@ typedef PREPACK struct { typedef PREPACK struct { A_UINT32 opcode; A_UINT32 length; - A_CHAR buffer[1]; /* WMI_SET_PARAMS */ + char buffer[1]; /* WMI_SET_PARAMS */ } POSTPACK WMI_SET_PARAMS_CMD; typedef PREPACK struct { diff --git a/drivers/staging/ath6kl/include/wmi_api.h b/drivers/staging/ath6kl/include/wmi_api.h index ee2270663a37..ae720a07320a 100644 --- a/drivers/staging/ath6kl/include/wmi_api.h +++ b/drivers/staging/ath6kl/include/wmi_api.h @@ -310,7 +310,7 @@ int wmi_del_wow_pattern_cmd(struct wmi_t *wmip, int wmi_set_wsc_status_cmd(struct wmi_t *wmip, A_UINT32 status); int -wmi_set_params_cmd(struct wmi_t *wmip, A_UINT32 opcode, A_UINT32 length, A_CHAR* buffer); +wmi_set_params_cmd(struct wmi_t *wmip, A_UINT32 opcode, A_UINT32 length, char *buffer); int wmi_set_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 dot3, A_UINT8 dot4); diff --git a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c index f61dd44a2626..1761092f0ecc 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c @@ -277,7 +277,7 @@ static int AR3KConfigureHCIBaud(AR3K_CONFIG_INFO *pConfig) static int AR3KExitMinBoot(AR3K_CONFIG_INFO *pConfig) { int status; - A_CHAR exitMinBootCmd[] = {0x25,0xFC,0x0c,0x03,0x00,0x00,0x00,0x00,0x00,0x00, + char exitMinBootCmd[] = {0x25,0xFC,0x0c,0x03,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00}; A_UINT8 *pEvent = NULL; A_UINT8 *pBufferToFree = NULL; @@ -338,7 +338,7 @@ static int AR3KEnableTLPM(AR3K_CONFIG_INFO *pConfig) { int status; /* AR3K vendor specific command for Host Wakeup Config */ - A_CHAR hostWakeupConfig[] = {0x31,0xFC,0x18, + char hostWakeupConfig[] = {0x31,0xFC,0x18, 0x02,0x00,0x00,0x00, 0x01,0x00,0x00,0x00, TLPM_DEFAULT_IDLE_TIMEOUT_LSB,TLPM_DEFAULT_IDLE_TIMEOUT_MSB,0x00,0x00, //idle timeout in ms @@ -346,7 +346,7 @@ static int AR3KEnableTLPM(AR3K_CONFIG_INFO *pConfig) TLPM_DEFAULT_WAKEUP_TIMEOUT_MS,0x00,0x00,0x00, //wakeup timeout in ms 0x00,0x00,0x00,0x00}; /* AR3K vendor specific command for Target Wakeup Config */ - A_CHAR targetWakeupConfig[] = {0x31,0xFC,0x18, + char targetWakeupConfig[] = {0x31,0xFC,0x18, 0x04,0x00,0x00,0x00, 0x01,0x00,0x00,0x00, TLPM_DEFAULT_IDLE_TIMEOUT_LSB,TLPM_DEFAULT_IDLE_TIMEOUT_MSB,0x00,0x00, //idle timeout in ms @@ -354,13 +354,13 @@ static int AR3KEnableTLPM(AR3K_CONFIG_INFO *pConfig) TLPM_DEFAULT_WAKEUP_TIMEOUT_MS,0x00,0x00,0x00, //wakeup timeout in ms 0x00,0x00,0x00,0x00}; /* AR3K vendor specific command for Host Wakeup Enable */ - A_CHAR hostWakeupEnable[] = {0x31,0xFC,0x4, + char hostWakeupEnable[] = {0x31,0xFC,0x4, 0x01,0x00,0x00,0x00}; /* AR3K vendor specific command for Target Wakeup Enable */ - A_CHAR targetWakeupEnable[] = {0x31,0xFC,0x4, + char targetWakeupEnable[] = {0x31,0xFC,0x4, 0x06,0x00,0x00,0x00}; /* AR3K vendor specific command for Sleep Enable */ - A_CHAR sleepEnable[] = {0x4,0xFC,0x1, + char sleepEnable[] = {0x4,0xFC,0x1, 0x1}; A_UINT8 *pEvent = NULL; A_UINT8 *pBufferToFree = NULL; diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c index b3013c58d83a..7ac1c365314e 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c @@ -129,7 +129,7 @@ tRamPatch RamPatch[MAX_NUM_PATCH_ENTRY]; int AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat); char AthReadChar(A_UCHAR *buffer, A_UINT32 len,A_UINT32 *pos); -char * AthGetLine(char * buffer, int maxlen, A_UCHAR *srcbuffer,A_UINT32 len,A_UINT32 *pos); +char *AthGetLine(char *buffer, int maxlen, A_UCHAR *srcbuffer,A_UINT32 len,A_UINT32 *pos); static int AthPSCreateHCICommand(A_UCHAR Opcode, A_UINT32 Param1,PSCmdPacket *PSPatchPacket,A_UINT32 *index); /* Function to reads the next character from the input buffer */ @@ -146,7 +146,7 @@ char AthReadChar(A_UCHAR *buffer, A_UINT32 len,A_UINT32 *pos) } } /* PS parser helper function */ -unsigned int uGetInputDataFormat(char* pCharLine, ST_PS_DATA_FORMAT *pstFormat) +unsigned int uGetInputDataFormat(char *pCharLine, ST_PS_DATA_FORMAT *pstFormat) { if(pCharLine[0] != '[') { pstFormat->eDataType = eHex; @@ -317,8 +317,8 @@ unsigned int uReadDataInSection(char *pCharLine, ST_PS_DATA_FORMAT stPS_DataForm } int AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat) { - char *Buffer; - char *pCharLine; + char *Buffer; + char *pCharLine; A_UINT8 TagCount; A_UINT16 ByteCount; A_UINT8 ParseSection=RAM_PS_SECTION; @@ -558,7 +558,7 @@ int AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat) /********************/ -int GetNextTwoChar(A_UCHAR *srcbuffer,A_UINT32 len, A_UINT32 *pos, char * buffer) +int GetNextTwoChar(A_UCHAR *srcbuffer,A_UINT32 len, A_UINT32 *pos, char *buffer) { unsigned char ch; @@ -582,8 +582,8 @@ int GetNextTwoChar(A_UCHAR *srcbuffer,A_UINT32 len, A_UINT32 *pos, char * buffer int AthDoParsePatch(A_UCHAR *patchbuffer, A_UINT32 patchlen) { - char Byte[3]; - char Line[MAX_BYTE_LENGTH + 1]; + char Byte[3]; + char Line[MAX_BYTE_LENGTH + 1]; int ByteCount,ByteCount_Org; int count; int i,j,k; @@ -713,7 +713,7 @@ int AthDoParsePS(A_UCHAR *srcbuffer, A_UINT32 srclen) return status; } -char * AthGetLine(char * buffer, int maxlen, A_UCHAR *srcbuffer,A_UINT32 len,A_UINT32 *pos) +char *AthGetLine(char *buffer, int maxlen, A_UCHAR *srcbuffer,A_UINT32 len,A_UINT32 *pos) { int count; diff --git a/drivers/staging/ath6kl/miscdrv/common_drv.c b/drivers/staging/ath6kl/miscdrv/common_drv.c index 94b4eb0000b1..171078596f8b 100644 --- a/drivers/staging/ath6kl/miscdrv/common_drv.c +++ b/drivers/staging/ath6kl/miscdrv/common_drv.c @@ -799,8 +799,8 @@ ar6002_REV1_reset_force_host (HIF_DEVICE *hifDevice) void DebugDumpBytes(A_UCHAR *buffer, A_UINT16 length, char *pDescription) { - A_CHAR stream[60]; - A_CHAR byteOffsetStr[10]; + char stream[60]; + char byteOffsetStr[10]; A_UINT32 i; A_UINT16 offset, count, byteOffset; @@ -868,7 +868,7 @@ void a_dump_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo) } -static ATH_DEBUG_MODULE_DBG_INFO *FindModule(A_CHAR *module_name) +static ATH_DEBUG_MODULE_DBG_INFO *FindModule(char *module_name) { ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead; @@ -909,7 +909,7 @@ void a_register_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo) A_MUTEX_UNLOCK(&g_ModuleListLock); } -void a_dump_module_debug_info_by_name(A_CHAR *module_name) +void a_dump_module_debug_info_by_name(char *module_name) { ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead; @@ -934,7 +934,7 @@ void a_dump_module_debug_info_by_name(A_CHAR *module_name) } -int a_get_module_mask(A_CHAR *module_name, A_UINT32 *pMask) +int a_get_module_mask(char *module_name, A_UINT32 *pMask) { ATH_DEBUG_MODULE_DBG_INFO *pInfo = FindModule(module_name); @@ -946,7 +946,7 @@ int a_get_module_mask(A_CHAR *module_name, A_UINT32 *pMask) return A_OK; } -int a_set_module_mask(A_CHAR *module_name, A_UINT32 Mask) +int a_set_module_mask(char *module_name, A_UINT32 Mask) { ATH_DEBUG_MODULE_DBG_INFO *pInfo = FindModule(module_name); diff --git a/drivers/staging/ath6kl/os/linux/ar6000_android.c b/drivers/staging/ath6kl/os/linux/ar6000_android.c index 7759a3d8703f..88591d7d5444 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_android.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_android.c @@ -155,7 +155,7 @@ int android_logger_lv(void *module, int mask) } } -static int android_readwrite_file(const A_CHAR *filename, A_CHAR *rbuf, const A_CHAR *wbuf, size_t length) +static int android_readwrite_file(const char *filename, char *rbuf, const char *wbuf, size_t length) { int ret = 0; struct file *filp = (struct file *)-ENOENT; diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 5bf505ca4a2c..b1909479179b 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -970,7 +970,7 @@ ar6000_softmac_update(AR_SOFTC_T *ar, A_UCHAR *eeprom_data, size_t size) ptr_mac[5] = random32() & 0xff; if ((A_REQUEST_FIRMWARE(&softmac_entry, "softmac", ((struct device *)ar->osDevInfo.pOSDevice))) == 0) { - A_CHAR *macbuf = A_MALLOC_NOWAIT(softmac_entry->size+1); + char *macbuf = A_MALLOC_NOWAIT(softmac_entry->size+1); if (macbuf) { unsigned int softmac[6]; memcpy(macbuf, softmac_entry->data, softmac_entry->size); @@ -1190,7 +1190,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode) AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Requesting device specific configuration\n")); if (mode == WLAN_INIT_MODE_UDEV) { - A_CHAR version[16]; + char version[16]; const struct firmware *fw_entry; /* Get config using udev through a script in user space */ @@ -2344,7 +2344,7 @@ ar6000_close(struct net_device *dev) /* connect to a service */ static int ar6000_connectservice(AR_SOFTC_T *ar, HTC_SERVICE_CONNECT_REQ *pConnect, - char *pDesc) + char *pDesc) { int status; HTC_SERVICE_CONNECT_RESP response; @@ -5941,7 +5941,7 @@ rssi_compensation_reverse_calc(AR_SOFTC_T *ar, A_INT16 rssi, bool Above) void ap_wapi_rekey_event(AR_SOFTC_T *ar, A_UINT8 type, A_UINT8 *mac) { union iwreq_data wrqu; - A_CHAR buf[20]; + char buf[20]; A_MEMZERO(buf, sizeof(buf)); diff --git a/drivers/staging/ath6kl/os/linux/eeprom.c b/drivers/staging/ath6kl/os/linux/eeprom.c index fd0e0837ad43..75eb092ea2a2 100644 --- a/drivers/staging/ath6kl/os/linux/eeprom.c +++ b/drivers/staging/ath6kl/os/linux/eeprom.c @@ -103,7 +103,7 @@ wmic_ether_aton(const char *orig, A_UINT8 *eth) } static void -update_mac(unsigned char* eeprom, int size, unsigned char* macaddr) +update_mac(unsigned char *eeprom, int size, unsigned char *macaddr) { int i; A_UINT16* ptr = (A_UINT16*)(eeprom+4); diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 233a1d3cc8e1..6b34629bd7c4 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -672,8 +672,8 @@ static inline void *ar6k_priv(struct net_device *dev) #define arEndpoint2RawStreamID(ar,ep) (ar)->arRawHtc->arEp2RawMapping[(ep)] struct ar_giwscan_param { - char *current_ev; - char *end_buf; + char *current_ev; + char *end_buf; A_UINT32 bytes_needed; struct iw_request_info *info; }; diff --git a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h index 15b6b0832af4..e9f7135dd02e 100644 --- a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h @@ -1198,7 +1198,7 @@ struct prof_count_s { /* AR6000_XIOCTL_MODULE_DEBUG_GET_MASK */ /* AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO */ struct drv_debug_module_s { - A_CHAR modulename[128]; /* name of module */ + char modulename[128]; /* name of module */ A_UINT32 mask; /* new mask to set .. or .. current mask */ }; diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index a120a5c3fc88..4403d1a61e7c 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -937,7 +937,7 @@ ar6000_ioctl_set_disconnect_timeout(struct net_device *dev, struct ifreq *rq) } static int -ar6000_xioctl_set_voice_pkt_size(struct net_device *dev, char * userdata) +ar6000_xioctl_set_voice_pkt_size(struct net_device *dev, char *userdata) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_SET_VOICE_PKT_SIZE_CMD cmd; @@ -963,7 +963,7 @@ ar6000_xioctl_set_voice_pkt_size(struct net_device *dev, char * userdata) } static int -ar6000_xioctl_set_max_sp_len(struct net_device *dev, char * userdata) +ar6000_xioctl_set_max_sp_len(struct net_device *dev, char *userdata) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_SET_MAX_SP_LEN_CMD cmd; @@ -989,7 +989,7 @@ ar6000_xioctl_set_max_sp_len(struct net_device *dev, char * userdata) static int -ar6000_xioctl_set_bt_status_cmd(struct net_device *dev, char * userdata) +ar6000_xioctl_set_bt_status_cmd(struct net_device *dev, char *userdata) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_SET_BT_STATUS_CMD cmd; @@ -1014,7 +1014,7 @@ ar6000_xioctl_set_bt_status_cmd(struct net_device *dev, char * userdata) } static int -ar6000_xioctl_set_bt_params_cmd(struct net_device *dev, char * userdata) +ar6000_xioctl_set_bt_params_cmd(struct net_device *dev, char *userdata) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_SET_BT_PARAMS_CMD cmd; @@ -1039,7 +1039,7 @@ ar6000_xioctl_set_bt_params_cmd(struct net_device *dev, char * userdata) } static int -ar6000_xioctl_set_btcoex_fe_ant_cmd(struct net_device * dev, char * userdata) +ar6000_xioctl_set_btcoex_fe_ant_cmd(struct net_device * dev, char *userdata) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_SET_BTCOEX_FE_ANT_CMD cmd; @@ -1063,7 +1063,7 @@ ar6000_xioctl_set_btcoex_fe_ant_cmd(struct net_device * dev, char * userdata) } static int -ar6000_xioctl_set_btcoex_colocated_bt_dev_cmd(struct net_device * dev, char * userdata) +ar6000_xioctl_set_btcoex_colocated_bt_dev_cmd(struct net_device * dev, char *userdata) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD cmd; @@ -1088,7 +1088,7 @@ ar6000_xioctl_set_btcoex_colocated_bt_dev_cmd(struct net_device * dev, char * us } static int -ar6000_xioctl_set_btcoex_btinquiry_page_config_cmd(struct net_device * dev, char * userdata) +ar6000_xioctl_set_btcoex_btinquiry_page_config_cmd(struct net_device * dev, char *userdata) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD cmd; @@ -1113,7 +1113,7 @@ ar6000_xioctl_set_btcoex_btinquiry_page_config_cmd(struct net_device * dev, cha } static int -ar6000_xioctl_set_btcoex_sco_config_cmd(struct net_device * dev, char * userdata) +ar6000_xioctl_set_btcoex_sco_config_cmd(struct net_device * dev, char *userdata) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_SET_BTCOEX_SCO_CONFIG_CMD cmd; @@ -1139,7 +1139,7 @@ ar6000_xioctl_set_btcoex_sco_config_cmd(struct net_device * dev, char * userdata static int ar6000_xioctl_set_btcoex_a2dp_config_cmd(struct net_device * dev, - char * userdata) + char *userdata) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_SET_BTCOEX_A2DP_CONFIG_CMD cmd; @@ -1164,7 +1164,7 @@ ar6000_xioctl_set_btcoex_a2dp_config_cmd(struct net_device * dev, } static int -ar6000_xioctl_set_btcoex_aclcoex_config_cmd(struct net_device * dev, char * userdata) +ar6000_xioctl_set_btcoex_aclcoex_config_cmd(struct net_device * dev, char *userdata) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD cmd; @@ -1189,7 +1189,7 @@ ar6000_xioctl_set_btcoex_aclcoex_config_cmd(struct net_device * dev, char * user } static int -ar60000_xioctl_set_btcoex_debug_cmd(struct net_device * dev, char * userdata) +ar60000_xioctl_set_btcoex_debug_cmd(struct net_device * dev, char *userdata) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_SET_BTCOEX_DEBUG_CMD cmd; @@ -1214,7 +1214,7 @@ ar60000_xioctl_set_btcoex_debug_cmd(struct net_device * dev, char * userdata) } static int -ar6000_xioctl_set_btcoex_bt_operating_status_cmd(struct net_device * dev, char * userdata) +ar6000_xioctl_set_btcoex_bt_operating_status_cmd(struct net_device * dev, char *userdata) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD cmd; @@ -1238,7 +1238,7 @@ ar6000_xioctl_set_btcoex_bt_operating_status_cmd(struct net_device * dev, char * } static int -ar6000_xioctl_get_btcoex_config_cmd(struct net_device * dev, char * userdata, +ar6000_xioctl_get_btcoex_config_cmd(struct net_device * dev, char *userdata, struct ifreq *rq) { @@ -1283,7 +1283,7 @@ ar6000_xioctl_get_btcoex_config_cmd(struct net_device * dev, char * userdata, } static int -ar6000_xioctl_get_btcoex_stats_cmd(struct net_device * dev, char * userdata, struct ifreq *rq) +ar6000_xioctl_get_btcoex_stats_cmd(struct net_device * dev, char *userdata, struct ifreq *rq) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); AR6000_BTCOEX_STATS btcoexStats; diff --git a/drivers/staging/ath6kl/os/linux/wireless_ext.c b/drivers/staging/ath6kl/os/linux/wireless_ext.c index eb964692649b..e167c82ca3d6 100644 --- a/drivers/staging/ath6kl/os/linux/wireless_ext.c +++ b/drivers/staging/ath6kl/os/linux/wireless_ext.c @@ -94,10 +94,10 @@ ar6000_scan_node(void *arg, bss_t *ni) char buf[256]; #endif struct ar_giwscan_param *param; - A_CHAR *current_ev; - A_CHAR *end_buf; + char *current_ev; + char *end_buf; struct ieee80211_common_ie *cie; - A_CHAR *current_val; + char *current_val; A_INT32 j; A_UINT32 rate_len, data_len = 0; diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index 2b65c087542d..695b0dcc7349 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -5215,7 +5215,7 @@ wmi_set_keepalive_cmd(struct wmi_t *wmip, A_UINT8 keepaliveInterval) } int -wmi_set_params_cmd(struct wmi_t *wmip, A_UINT32 opcode, A_UINT32 length, A_CHAR* buffer) +wmi_set_params_cmd(struct wmi_t *wmip, A_UINT32 opcode, A_UINT32 length, char *buffer) { void *osbuf; WMI_SET_PARAMS_CMD *cmd; -- cgit v1.2.3 From ab3655dae4948a82a3be52681af0b778ead2c0ff Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 2 Feb 2011 14:05:49 -0800 Subject: staging: ath6kl: Convert A_UINT8 to u8 Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/bmi/src/bmi.c | 8 +- .../hif/sdio/linux_sdio/include/hif_internal.h | 2 +- .../staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 10 +- .../ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c | 4 +- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 20 +- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 46 +- drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c | 22 +- drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c | 20 +- .../ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c | 6 +- drivers/staging/ath6kl/htc2/htc_internal.h | 18 +- drivers/staging/ath6kl/htc2/htc_recv.c | 42 +- drivers/staging/ath6kl/htc2/htc_send.c | 2 +- drivers/staging/ath6kl/htc2/htc_services.c | 10 +- drivers/staging/ath6kl/include/aggr_recv_api.h | 8 +- drivers/staging/ath6kl/include/ar3kconfig.h | 2 +- drivers/staging/ath6kl/include/ar6kap_common.h | 10 +- drivers/staging/ath6kl/include/common/a_hci.h | 260 ++++----- drivers/staging/ath6kl/include/common/bmi_msg.h | 6 +- drivers/staging/ath6kl/include/common/dbglog.h | 2 +- .../staging/ath6kl/include/common/epping_test.h | 22 +- drivers/staging/ath6kl/include/common/gmboxif.h | 8 +- drivers/staging/ath6kl/include/common/htc.h | 56 +- .../include/common/regulatory/reg_dbschema.h | 20 +- drivers/staging/ath6kl/include/common/wlan_dset.h | 4 +- drivers/staging/ath6kl/include/common/wmi.h | 642 ++++++++++----------- drivers/staging/ath6kl/include/common/wmi_thin.h | 104 ++-- drivers/staging/ath6kl/include/common/wmix.h | 2 +- drivers/staging/ath6kl/include/common_drv.h | 12 +- drivers/staging/ath6kl/include/dset_api.h | 2 +- drivers/staging/ath6kl/include/hif.h | 4 +- drivers/staging/ath6kl/include/htc_api.h | 12 +- drivers/staging/ath6kl/include/htc_packet.h | 6 +- drivers/staging/ath6kl/include/wlan_api.h | 46 +- drivers/staging/ath6kl/include/wmi_api.h | 169 +++--- drivers/staging/ath6kl/miscdrv/ar3kconfig.c | 46 +- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c | 40 +- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c | 24 +- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h | 2 +- drivers/staging/ath6kl/miscdrv/common_drv.c | 17 +- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 173 +++--- drivers/staging/ath6kl/os/linux/ar6000_pm.c | 4 +- drivers/staging/ath6kl/os/linux/ar6000_raw_if.c | 6 +- drivers/staging/ath6kl/os/linux/ar6k_pal.c | 2 +- drivers/staging/ath6kl/os/linux/cfg80211.c | 54 +- drivers/staging/ath6kl/os/linux/eeprom.c | 10 +- drivers/staging/ath6kl/os/linux/hci_bridge.c | 6 +- .../staging/ath6kl/os/linux/include/ar6000_drv.h | 117 ++-- .../ath6kl/os/linux/include/ar6xapi_linux.h | 64 +- .../staging/ath6kl/os/linux/include/athdrv_linux.h | 22 +- drivers/staging/ath6kl/os/linux/include/cfg80211.h | 14 +- .../staging/ath6kl/os/linux/include/osapi_linux.h | 2 +- .../ath6kl/os/linux/include/wmi_filter_linux.h | 6 +- drivers/staging/ath6kl/os/linux/ioctl.c | 66 +-- drivers/staging/ath6kl/os/linux/wireless_ext.c | 49 +- drivers/staging/ath6kl/reorder/aggr_rx_internal.h | 4 +- drivers/staging/ath6kl/reorder/rcv_aggr.c | 26 +- drivers/staging/ath6kl/wlan/include/ieee80211.h | 40 +- .../staging/ath6kl/wlan/include/ieee80211_node.h | 4 +- drivers/staging/ath6kl/wlan/src/wlan_node.c | 16 +- drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c | 26 +- drivers/staging/ath6kl/wmi/wmi.c | 514 ++++++++--------- drivers/staging/ath6kl/wmi/wmi_host.h | 20 +- 62 files changed, 1484 insertions(+), 1497 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/bmi/src/bmi.c b/drivers/staging/ath6kl/bmi/src/bmi.c index a29f60e0ce6c..165b6b3d8dd5 100644 --- a/drivers/staging/ath6kl/bmi/src/bmi.c +++ b/drivers/staging/ath6kl/bmi/src/bmi.c @@ -755,7 +755,7 @@ bmiBufferSend(HIF_DEVICE *device, /* hit the credit counter with a 4-byte access, the first byte read will hit the counter and cause * a decrement, while the remaining 3 bytes has no effect. The rationale behind this is to * make all HIF accesses 4-byte aligned */ - status = HIFReadWrite(device, address, (A_UINT8 *)pBMICmdCredits, 4, + status = HIFReadWrite(device, address, (u8 *)pBMICmdCredits, 4, HIF_RD_SYNC_BYTE_INC, NULL); if (status != A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to decrement the command credit count register\n")); @@ -879,7 +879,7 @@ bmiBufferReceive(HIF_DEVICE *device, continue; } - status = HIFReadWrite(device, RX_LOOKAHEAD_VALID_ADDRESS, (A_UINT8 *)&word_available, + status = HIFReadWrite(device, RX_LOOKAHEAD_VALID_ADDRESS, (u8 *)&word_available, sizeof(word_available), HIF_RD_SYNC_BYTE_INC, NULL); if (status != A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read RX_LOOKAHEAD_VALID register\n")); @@ -930,7 +930,7 @@ bmiBufferReceive(HIF_DEVICE *device, /* read the counter using a 4-byte read. Since the counter is NOT auto-decrementing, * we can read this counter multiple times using a non-incrementing address mode. * The rationale here is to make all HIF accesses a multiple of 4 bytes */ - status = HIFReadWrite(device, address, (A_UINT8 *)pBMICmdCredits, sizeof(*pBMICmdCredits), + status = HIFReadWrite(device, address, (u8 *)pBMICmdCredits, sizeof(*pBMICmdCredits), HIF_RD_SYNC_BYTE_FIX, NULL); if (status != A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the command credit count register\n")); @@ -982,7 +982,7 @@ BMIFastDownload(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 } if (unalignedBytes) { - status = BMILZData(device, (A_UINT8 *)&lastWord, 4); + status = BMILZData(device, (u8 *)&lastWord, 4); } if (!status) { diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h index 18713c2b2002..4a8694e89355 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h @@ -76,7 +76,7 @@ struct hif_device { BUS_REQUEST busRequest[BUS_REQUEST_MAX_NUM]; /* available bus requests */ void *claimedContext; HTC_CALLBACKS htcCallbacks; - A_UINT8 *dma_buffer; + u8 *dma_buffer; DL_LIST ScatterReqHead; /* scatter request list head */ bool scatter_enabled; /* scatter enabled flag */ bool is_suspend; diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index 273aa6372d2a..ced9079e6060 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -160,10 +160,10 @@ __HIFReadWrite(HIF_DEVICE *device, A_UINT32 request, void *context) { - A_UINT8 opcode; + u8 opcode; int status = A_OK; int ret; - A_UINT8 *tbuffer; + u8 *tbuffer; bool bounced = false; AR_DEBUG_ASSERT(device != NULL); @@ -494,7 +494,7 @@ int ReinitSDIO(HIF_DEVICE *device) struct mmc_host *host; struct mmc_card *card; struct sdio_func *func; - A_UINT8 cmd52_resp; + u8 cmd52_resp; A_UINT32 clock; func = device->func; @@ -1154,7 +1154,7 @@ static void hifDeviceRemoved(struct sdio_func *func) int hifWaitForPendingRecv(HIF_DEVICE *device) { A_INT32 cnt = 10; - A_UINT8 host_int_status; + u8 host_int_status; int status = A_OK; do { @@ -1165,7 +1165,7 @@ int hifWaitForPendingRecv(HIF_DEVICE *device) /* check if there is any pending irq due to force done */ host_int_status = 0; status = HIFReadWrite(device, HOST_INT_STATUS_ADDRESS, - (A_UINT8 *)&host_int_status, sizeof(host_int_status), + (u8 *)&host_int_status, sizeof(host_int_status), HIF_RD_SYNC_BYTE_INC, NULL); host_int_status = !status ? (host_int_status & (1 << 0)) : 0; if (host_int_status) { diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c index 8d9aed7a8cea..6b8db5b99811 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c @@ -82,8 +82,8 @@ static HIF_SCATTER_REQ *AllocScatterReq(HIF_DEVICE *device) int DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest) { int i; - A_UINT8 rw; - A_UINT8 opcode; + u8 rw; + u8 opcode; struct mmc_request mmcreq; struct mmc_command cmd; struct mmc_data data; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index 11311af07641..ad14a2f7effb 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -610,7 +610,7 @@ static void DevFreeScatterReq(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) int DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, bool FromDMA) { - A_UINT8 *pDMABuffer = NULL; + u8 *pDMABuffer = NULL; int i, remaining; A_UINT32 length; @@ -775,7 +775,7 @@ static int DevSetupVirtualScatterSupport(AR6K_DEVICE *pDev) A_MEMZERO(pReq, sgreqSize); /* the virtual DMA starts after the scatter request struct */ - pVirtualInfo = (DEV_SCATTER_DMA_VIRTUAL_INFO *)((A_UINT8 *)pReq + sgreqSize); + pVirtualInfo = (DEV_SCATTER_DMA_VIRTUAL_INFO *)((u8 *)pReq + sgreqSize); A_MEMZERO(pVirtualInfo, sizeof(DEV_SCATTER_DMA_VIRTUAL_INFO)); pVirtualInfo->pVirtDmaBuffer = &pVirtualInfo->DataArea[0]; @@ -1002,14 +1002,14 @@ int DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, boo #define TEST_CREDITS_RECV_TIMEOUT 100 -static A_UINT8 g_Buffer[TOTAL_BYTES]; +static u8 g_Buffer[TOTAL_BYTES]; static A_UINT32 g_MailboxAddrs[AR6K_MAILBOXES]; static A_UINT32 g_BlockSizes[AR6K_MAILBOXES]; #define BUFFER_PROC_LIST_DEPTH 4 typedef struct _BUFFER_PROC_LIST{ - A_UINT8 *pBuffer; + u8 *pBuffer; A_UINT32 length; }BUFFER_PROC_LIST; @@ -1025,7 +1025,7 @@ typedef struct _BUFFER_PROC_LIST{ /* a simple and crude way to send different "message" sizes */ static void AssembleBufferList(BUFFER_PROC_LIST *pList) { - A_UINT8 *pBuffer = g_Buffer; + u8 *pBuffer = g_Buffer; #if BUFFER_PROC_LIST_DEPTH < 4 #error "Buffer processing list depth is not deep enough!!" @@ -1107,7 +1107,7 @@ static bool CheckBuffers(void) /* find the end marker for the last buffer we will be sending */ static A_UINT16 GetEndMarker(void) { - A_UINT8 *pBuffer; + u8 *pBuffer; BUFFER_PROC_LIST checkList[BUFFER_PROC_LIST_DEPTH]; /* fill up buffers with the normal counting pattern */ @@ -1173,7 +1173,7 @@ static int GetCredits(AR6K_DEVICE *pDev, int mbox, int *pCredits) { int status = A_OK; int timeout = TEST_CREDITS_RECV_TIMEOUT; - A_UINT8 credits = 0; + u8 credits = 0; A_UINT32 address; while (true) { @@ -1335,7 +1335,7 @@ int DoMboxHWTest(AR6K_DEVICE *pDev) int i; int status; int credits = 0; - A_UINT8 params[4]; + u8 params[4]; int numBufs; int bufferSize; A_UINT16 temp; @@ -1418,7 +1418,7 @@ int DoMboxHWTest(AR6K_DEVICE *pDev) status = HIFReadWrite(pDev->HIFDevice, SCRATCH_ADDRESS + 4, - (A_UINT8 *)&temp, + (u8 *)&temp, 2, HIF_WR_SYNC_BYTE_INC, NULL); @@ -1435,7 +1435,7 @@ int DoMboxHWTest(AR6K_DEVICE *pDev) temp = temp - 1; status = HIFReadWrite(pDev->HIFDevice, SCRATCH_ADDRESS + 6, - (A_UINT8 *)&temp, + (u8 *)&temp, 2, HIF_WR_SYNC_BYTE_INC, NULL); diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index a015da1322b5..0785ca2a77f5 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -44,14 +44,14 @@ #include "athstartpack.h" typedef PREPACK struct _AR6K_IRQ_PROC_REGISTERS { - A_UINT8 host_int_status; - A_UINT8 cpu_int_status; - A_UINT8 error_int_status; - A_UINT8 counter_int_status; - A_UINT8 mbox_frame; - A_UINT8 rx_lookahead_valid; - A_UINT8 host_int_status2; - A_UINT8 gmbox_rx_avail; + u8 host_int_status; + u8 cpu_int_status; + u8 error_int_status; + u8 counter_int_status; + u8 mbox_frame; + u8 rx_lookahead_valid; + u8 host_int_status2; + u8 gmbox_rx_avail; A_UINT32 rx_lookahead[2]; A_UINT32 rx_gmbox_lookahead_alias[2]; } POSTPACK AR6K_IRQ_PROC_REGISTERS; @@ -59,14 +59,14 @@ typedef PREPACK struct _AR6K_IRQ_PROC_REGISTERS { #define AR6K_IRQ_PROC_REGS_SIZE sizeof(AR6K_IRQ_PROC_REGISTERS) typedef PREPACK struct _AR6K_IRQ_ENABLE_REGISTERS { - A_UINT8 int_status_enable; - A_UINT8 cpu_int_status_enable; - A_UINT8 error_status_enable; - A_UINT8 counter_int_status_enable; + u8 int_status_enable; + u8 cpu_int_status_enable; + u8 error_status_enable; + u8 counter_int_status_enable; } POSTPACK AR6K_IRQ_ENABLE_REGISTERS; typedef PREPACK struct _AR6K_GMBOX_CTRL_REGISTERS { - A_UINT8 int_status_enable; + u8 int_status_enable; } POSTPACK AR6K_GMBOX_CTRL_REGISTERS; #include "athendpack.h" @@ -91,14 +91,14 @@ typedef PREPACK struct _AR6K_GMBOX_CTRL_REGISTERS { /* buffers for ASYNC I/O */ typedef struct AR6K_ASYNC_REG_IO_BUFFER { HTC_PACKET HtcPacket; /* we use an HTC packet as a wrapper for our async register-based I/O */ - A_UINT8 _Pad1[A_CACHE_LINE_PAD]; - A_UINT8 Buffer[AR6K_REG_IO_BUFFER_SIZE]; /* cache-line safe with pads around */ - A_UINT8 _Pad2[A_CACHE_LINE_PAD]; + u8 _Pad1[A_CACHE_LINE_PAD]; + u8 Buffer[AR6K_REG_IO_BUFFER_SIZE]; /* cache-line safe with pads around */ + u8 _Pad2[A_CACHE_LINE_PAD]; } AR6K_ASYNC_REG_IO_BUFFER; typedef struct _AR6K_GMBOX_INFO { void *pProtocolContext; - int (*pMessagePendingCallBack)(void *pContext, A_UINT8 LookAheadBytes[], int ValidBytes); + int (*pMessagePendingCallBack)(void *pContext, u8 LookAheadBytes[], int ValidBytes); int (*pCreditsPendingCallback)(void *pContext, int NumCredits, bool CreditIRQEnabled); void (*pTargetFailureCallback)(void *pContext, int Status); void (*pStateDumpCallback)(void *pContext); @@ -107,11 +107,11 @@ typedef struct _AR6K_GMBOX_INFO { typedef struct _AR6K_DEVICE { A_MUTEX_T Lock; - A_UINT8 _Pad1[A_CACHE_LINE_PAD]; + u8 _Pad1[A_CACHE_LINE_PAD]; AR6K_IRQ_PROC_REGISTERS IrqProcRegisters; /* cache-line safe with pads around */ - A_UINT8 _Pad2[A_CACHE_LINE_PAD]; + u8 _Pad2[A_CACHE_LINE_PAD]; AR6K_IRQ_ENABLE_REGISTERS IrqEnableRegisters; /* cache-line safe with pads around */ - A_UINT8 _Pad3[A_CACHE_LINE_PAD]; + u8 _Pad3[A_CACHE_LINE_PAD]; void *HIFDevice; A_UINT32 BlockSize; A_UINT32 BlockMask; @@ -321,8 +321,8 @@ int DoMboxHWTest(AR6K_DEVICE *pDev); /* completely virtual */ typedef struct _DEV_SCATTER_DMA_VIRTUAL_INFO { - A_UINT8 *pVirtDmaBuffer; /* dma-able buffer - CPU accessible address */ - A_UINT8 DataArea[1]; /* start of data area */ + u8 *pVirtDmaBuffer; /* dma-able buffer - CPU accessible address */ + u8 DataArea[1]; /* start of data area */ } DEV_SCATTER_DMA_VIRTUAL_INFO; @@ -394,7 +394,7 @@ typedef enum GMBOX_IRQ_ACTION_TYPE { int DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE, bool AsyncMode); int DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, bool AsyncMode, int *pCredits); int DevGMboxReadCreditSize(AR6K_DEVICE *pDev, int *pCreditSize); -int DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, A_UINT8 *pLookAheadBuffer, int *pLookAheadBytes); +int DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes); int DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int SignalNumber, int AckTimeoutMS); #endif diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c index 92d89c0480c3..8ba426199ff9 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c @@ -104,7 +104,7 @@ int DevPollMboxMsgRecv(AR6K_DEVICE *pDev, /* load the register table */ status = HIFReadWrite(pDev->HIFDevice, HOST_INT_STATUS_ADDRESS, - (A_UINT8 *)&pDev->IrqProcRegisters, + (u8 *)&pDev->IrqProcRegisters, AR6K_IRQ_PROC_REGS_SIZE, HIF_RD_SYNC_BYTE_INC, NULL); @@ -155,8 +155,8 @@ int DevPollMboxMsgRecv(AR6K_DEVICE *pDev, static int DevServiceCPUInterrupt(AR6K_DEVICE *pDev) { int status; - A_UINT8 cpu_int_status; - A_UINT8 regBuffer[4]; + u8 cpu_int_status; + u8 regBuffer[4]; AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("CPU Interrupt\n")); cpu_int_status = pDev->IrqProcRegisters.cpu_int_status & @@ -195,8 +195,8 @@ static int DevServiceCPUInterrupt(AR6K_DEVICE *pDev) static int DevServiceErrorInterrupt(AR6K_DEVICE *pDev) { int status; - A_UINT8 error_int_status; - A_UINT8 regBuffer[4]; + u8 error_int_status; + u8 regBuffer[4]; AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Error Interrupt\n")); error_int_status = pDev->IrqProcRegisters.error_int_status & 0x0F; @@ -266,7 +266,7 @@ static int DevServiceDebugInterrupt(AR6K_DEVICE *pDev) /* read counter to clear interrupt */ status = HIFReadWrite(pDev->HIFDevice, COUNT_DEC_ADDRESS, - (A_UINT8 *)&dummy, + (u8 *)&dummy, 4, HIF_RD_SYNC_BYTE_INC, NULL); @@ -277,7 +277,7 @@ static int DevServiceDebugInterrupt(AR6K_DEVICE *pDev) static int DevServiceCounterInterrupt(AR6K_DEVICE *pDev) { - A_UINT8 counter_int_status; + u8 counter_int_status; AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Counter Interrupt\n")); @@ -332,7 +332,7 @@ static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket) } else { /* standard interrupt table handling.... */ AR6K_IRQ_PROC_REGISTERS *pReg = (AR6K_IRQ_PROC_REGISTERS *)pPacket->pBuffer; - A_UINT8 host_int_status; + u8 host_int_status; host_int_status = pReg->host_int_status & pDev->IrqEnableRegisters.int_status_enable; @@ -470,7 +470,7 @@ void DevAsyncIrqProcessComplete(AR6K_DEVICE *pDev) static int ProcessPendingIRQs(AR6K_DEVICE *pDev, bool *pDone, bool *pASyncProcessing) { int status = A_OK; - A_UINT8 host_int_status = 0; + u8 host_int_status = 0; A_UINT32 lookAhead = 0; AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+ProcessPendingIRQs: (dev: 0x%lX)\n", (unsigned long)pDev)); @@ -545,7 +545,7 @@ static int ProcessPendingIRQs(AR6K_DEVICE *pDev, bool *pDone, bool *pASyncProces #endif /* CONFIG_MMC_SDHCI_S3C */ status = HIFReadWrite(pDev->HIFDevice, HOST_INT_STATUS_ADDRESS, - (A_UINT8 *)&pDev->IrqProcRegisters, + (u8 *)&pDev->IrqProcRegisters, AR6K_IRQ_PROC_REGS_SIZE, HIF_RD_SYNC_BYTE_INC, NULL); @@ -758,7 +758,7 @@ void DumpAR6KDevState(AR6K_DEVICE *pDev) /* load the register table from the device */ status = HIFReadWrite(pDev->HIFDevice, HOST_INT_STATUS_ADDRESS, - (A_UINT8 *)&procRegs, + (u8 *)&procRegs, AR6K_IRQ_PROC_REGS_SIZE, HIF_RD_SYNC_BYTE_INC, NULL); diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c index b21c9fb88f81..1f6bc24621cc 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c @@ -159,7 +159,7 @@ int DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool A { int status = A_OK; HTC_PACKET *pIOPacket = NULL; - A_UINT8 GMboxIntControl[4]; + u8 GMboxIntControl[4]; if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) { return DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_ENABLE, AsyncMode); @@ -272,7 +272,7 @@ void DevCleanupGMbox(AR6K_DEVICE *pDev) int DevSetupGMbox(AR6K_DEVICE *pDev) { int status = A_OK; - A_UINT8 muxControl[4]; + u8 muxControl[4]; do { @@ -325,9 +325,9 @@ int DevSetupGMbox(AR6K_DEVICE *pDev) int DevCheckGMboxInterrupts(AR6K_DEVICE *pDev) { int status = A_OK; - A_UINT8 counter_int_status; + u8 counter_int_status; int credits; - A_UINT8 host_int_status2; + u8 host_int_status2; AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("+DevCheckGMboxInterrupts \n")); @@ -360,7 +360,7 @@ int DevCheckGMboxInterrupts(AR6K_DEVICE *pDev) A_ASSERT(pDev->GMboxInfo.pMessagePendingCallBack != NULL); status = pDev->GMboxInfo.pMessagePendingCallBack( pDev->GMboxInfo.pProtocolContext, - (A_UINT8 *)&pDev->IrqProcRegisters.rx_gmbox_lookahead_alias[0], + (u8 *)&pDev->IrqProcRegisters.rx_gmbox_lookahead_alias[0], pDev->IrqProcRegisters.gmbox_rx_avail); } } @@ -477,7 +477,7 @@ int DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 ReadLength) } -static int ProcessCreditCounterReadBuffer(A_UINT8 *pBuffer, int Length) +static int ProcessCreditCounterReadBuffer(u8 *pBuffer, int Length) { int credits = 0; @@ -605,7 +605,7 @@ int DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, bool AsyncMode, int *pCredits) int DevGMboxReadCreditSize(AR6K_DEVICE *pDev, int *pCreditSize) { int status; - A_UINT8 buffer[4]; + u8 buffer[4]; status = HIFReadWrite(pDev->HIFDevice, AR6K_GMBOX_CREDIT_SIZE_ADDRESS, @@ -634,7 +634,7 @@ void DevNotifyGMboxTargetFailure(AR6K_DEVICE *pDev) } } -int DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, A_UINT8 *pLookAheadBuffer, int *pLookAheadBytes) +int DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes) { int status = A_OK; @@ -654,7 +654,7 @@ int DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, A_UINT8 *pLookAheadBuffer, int /* load the register table from the device */ status = HIFReadWrite(pDev->HIFDevice, HOST_INT_STATUS_ADDRESS, - (A_UINT8 *)&procRegs, + (u8 *)&procRegs, AR6K_IRQ_PROC_REGS_SIZE, HIF_RD_SYNC_BYTE_INC, NULL); @@ -680,7 +680,7 @@ int DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int Signal, int AckTimeoutMS) { int status = A_OK; int i; - A_UINT8 buffer[4]; + u8 buffer[4]; A_MEMZERO(buffer, sizeof(buffer)); diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c index 2a87a49a79e5..961f5a1d44dd 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c @@ -304,7 +304,7 @@ static void StateDumpCallback(void *pContext) AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("==================================================\n")); } -static int HCIUartMessagePending(void *pContext, A_UINT8 LookAheadBytes[], int ValidBytes) +static int HCIUartMessagePending(void *pContext, u8 LookAheadBytes[], int ValidBytes) { GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)pContext; int status = A_OK; @@ -584,7 +584,7 @@ static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, bool Syn int status = A_OK; int transferLength; int creditsRequired, remainder; - A_UINT8 hciUartType; + u8 hciUartType; bool synchSendComplete = false; AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCITrySend (pPacket:0x%lX) %s \n",(unsigned long)pPacket, @@ -1164,7 +1164,7 @@ int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, { GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; int status = A_OK; - A_UINT8 lookAhead[8]; + u8 lookAhead[8]; int bytes; int totalRecvLength; diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h index 48d2afefee0b..332ab8529657 100644 --- a/drivers/staging/ath6kl/htc2/htc_internal.h +++ b/drivers/staging/ath6kl/htc2/htc_internal.h @@ -80,7 +80,7 @@ typedef struct _HTC_ENDPOINT { HTC_PACKET_QUEUE RecvIndicationQueue; /* recv packets ready to be indicated */ int RxProcessCount; /* reference count to allow single processing context */ struct _HTC_TARGET *target; /* back pointer to target */ - A_UINT8 SeqNo; /* TX seq no (helpful) for debugging */ + u8 SeqNo; /* TX seq no (helpful) for debugging */ A_UINT32 LocalConnectionFlags; /* local connection flags */ #ifdef HTC_EP_STAT_PROFILING HTC_ENDPOINT_STATS EndPointStats; /* endpoint statistics */ @@ -101,7 +101,7 @@ typedef struct _HTC_ENDPOINT { typedef struct HTC_CONTROL_BUFFER { HTC_PACKET HtcPacket; - A_UINT8 *Buffer; + u8 *Buffer; } HTC_CONTROL_BUFFER; #define HTC_RECV_WAIT_BUFFERS (1 << 0) @@ -129,11 +129,11 @@ typedef struct _HTC_TARGET { bool TargetFailure; #ifdef HTC_CAPTURE_LAST_FRAME HTC_FRAME_HDR LastFrameHdr; /* useful for debugging */ - A_UINT8 LastTrailer[256]; - A_UINT8 LastTrailerLength; + u8 LastTrailer[256]; + u8 LastTrailerLength; #endif HTC_INIT_INFO HTCInitInfo; - A_UINT8 HTCTargetVersion; + u8 HTCTargetVersion; int MaxMsgPerBundle; /* max messages per bundle for HTC */ bool SendBundlingEnabled; /* run time enable for send bundling (dynamic) */ int RecvBundlingEnabled; /* run time enable for recv bundling (dynamic) */ @@ -200,14 +200,14 @@ static INLINE HTC_PACKET *HTC_ALLOC_CONTROL_TX(HTC_TARGET *target) { #define HTC_PREPARE_SEND_PKT(pP,sendflags,ctrl0,ctrl1) \ { \ - A_UINT8 *pHdrBuf; \ + u8 *pHdrBuf; \ (pP)->pBuffer -= HTC_HDR_LENGTH; \ pHdrBuf = (pP)->pBuffer; \ A_SET_UINT16_FIELD(pHdrBuf,HTC_FRAME_HDR,PayloadLen,(A_UINT16)(pP)->ActualLength); \ A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,Flags,(sendflags)); \ - A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,EndpointID, (A_UINT8)(pP)->Endpoint); \ - A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,ControlBytes[0], (A_UINT8)(ctrl0)); \ - A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,ControlBytes[1], (A_UINT8)(ctrl1)); \ + A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,EndpointID, (u8)(pP)->Endpoint); \ + A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,ControlBytes[0], (u8)(ctrl0)); \ + A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,ControlBytes[1], (u8)(ctrl1)); \ } #define HTC_UNPREPARE_SEND_PKT(pP) \ diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c index fcbee0d15b5f..0b09b22ca8e0 100644 --- a/drivers/staging/ath6kl/htc2/htc_recv.c +++ b/drivers/staging/ath6kl/htc2/htc_recv.c @@ -84,16 +84,16 @@ static void DoRecvCompletion(HTC_ENDPOINT *pEndpoint, } static INLINE int HTCProcessTrailer(HTC_TARGET *target, - A_UINT8 *pBuffer, + u8 *pBuffer, int Length, A_UINT32 *pNextLookAheads, int *pNumLookAheads, HTC_ENDPOINT_ID FromEndpoint) { HTC_RECORD_HDR *pRecord; - A_UINT8 *pRecordBuf; + u8 *pRecordBuf; HTC_LOOKAHEAD_REPORT *pLookAhead; - A_UINT8 *pOrigBuffer; + u8 *pOrigBuffer; int origLength; int status; @@ -149,14 +149,14 @@ static INLINE int HTCProcessTrailer(HTC_TARGET *target, pLookAhead->PostValid)); /* look ahead bytes are valid, copy them over */ - ((A_UINT8 *)(&pNextLookAheads[0]))[0] = pLookAhead->LookAhead[0]; - ((A_UINT8 *)(&pNextLookAheads[0]))[1] = pLookAhead->LookAhead[1]; - ((A_UINT8 *)(&pNextLookAheads[0]))[2] = pLookAhead->LookAhead[2]; - ((A_UINT8 *)(&pNextLookAheads[0]))[3] = pLookAhead->LookAhead[3]; + ((u8 *)(&pNextLookAheads[0]))[0] = pLookAhead->LookAhead[0]; + ((u8 *)(&pNextLookAheads[0]))[1] = pLookAhead->LookAhead[1]; + ((u8 *)(&pNextLookAheads[0]))[2] = pLookAhead->LookAhead[2]; + ((u8 *)(&pNextLookAheads[0]))[3] = pLookAhead->LookAhead[3]; #ifdef ATH_DEBUG_MODULE if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { - DebugDumpBytes((A_UINT8 *)pNextLookAheads,4,"Next Look Ahead"); + DebugDumpBytes((u8 *)pNextLookAheads,4,"Next Look Ahead"); } #endif /* just one normal lookahead */ @@ -188,10 +188,10 @@ static INLINE int HTCProcessTrailer(HTC_TARGET *target, } for (i = 0; i < (int)(pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT))); i++) { - ((A_UINT8 *)(&pNextLookAheads[i]))[0] = pBundledLookAheadRpt->LookAhead[0]; - ((A_UINT8 *)(&pNextLookAheads[i]))[1] = pBundledLookAheadRpt->LookAhead[1]; - ((A_UINT8 *)(&pNextLookAheads[i]))[2] = pBundledLookAheadRpt->LookAhead[2]; - ((A_UINT8 *)(&pNextLookAheads[i]))[3] = pBundledLookAheadRpt->LookAhead[3]; + ((u8 *)(&pNextLookAheads[i]))[0] = pBundledLookAheadRpt->LookAhead[0]; + ((u8 *)(&pNextLookAheads[i]))[1] = pBundledLookAheadRpt->LookAhead[1]; + ((u8 *)(&pNextLookAheads[i]))[2] = pBundledLookAheadRpt->LookAhead[2]; + ((u8 *)(&pNextLookAheads[i]))[3] = pBundledLookAheadRpt->LookAhead[3]; pBundledLookAheadRpt++; } @@ -231,8 +231,8 @@ static int HTCProcessRecvHeader(HTC_TARGET *target, A_UINT32 *pNextLookAheads, int *pNumLookAheads) { - A_UINT8 temp; - A_UINT8 *pBuf; + u8 temp; + u8 *pBuf; int status = A_OK; A_UINT16 payloadLen; A_UINT32 lookAhead; @@ -254,10 +254,10 @@ static int HTCProcessRecvHeader(HTC_TARGET *target, * retrieve 16 bit fields */ payloadLen = A_GET_UINT16_FIELD(pBuf, HTC_FRAME_HDR, PayloadLen); - ((A_UINT8 *)&lookAhead)[0] = pBuf[0]; - ((A_UINT8 *)&lookAhead)[1] = pBuf[1]; - ((A_UINT8 *)&lookAhead)[2] = pBuf[2]; - ((A_UINT8 *)&lookAhead)[3] = pBuf[3]; + ((u8 *)&lookAhead)[0] = pBuf[0]; + ((u8 *)&lookAhead)[1] = pBuf[1]; + ((u8 *)&lookAhead)[2] = pBuf[2]; + ((u8 *)&lookAhead)[3] = pBuf[3]; if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_REFRESH_HDR) { /* refresh expected hdr, since this was unknown at the time we grabbed the packets @@ -293,10 +293,10 @@ static int HTCProcessRecvHeader(HTC_TARGET *target, ("HTCProcessRecvHeader, lookahead mismatch! (pPkt:0x%lX flags:0x%X) \n", (unsigned long)pPacket, pPacket->PktInfo.AsRx.HTCRxFlags)); #ifdef ATH_DEBUG_MODULE - DebugDumpBytes((A_UINT8 *)&pPacket->PktInfo.AsRx.ExpectedHdr,4,"Expected Message LookAhead"); + DebugDumpBytes((u8 *)&pPacket->PktInfo.AsRx.ExpectedHdr,4,"Expected Message LookAhead"); DebugDumpBytes(pBuf,sizeof(HTC_FRAME_HDR),"Current Frame Header"); #ifdef HTC_CAPTURE_LAST_FRAME - DebugDumpBytes((A_UINT8 *)&target->LastFrameHdr,sizeof(HTC_FRAME_HDR),"Last Frame Header"); + DebugDumpBytes((u8 *)&target->LastFrameHdr,sizeof(HTC_FRAME_HDR),"Last Frame Header"); if (target->LastTrailerLength != 0) { DebugDumpBytes(target->LastTrailer, target->LastTrailerLength, @@ -405,7 +405,7 @@ static INLINE void HTCAsyncRecvCheckMorePackets(HTC_TARGET *target, AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Next look ahead from recv header was INVALID\n")); #ifdef ATH_DEBUG_MODULE - DebugDumpBytes((A_UINT8 *)NextLookAheads, + DebugDumpBytes((u8 *)NextLookAheads, NumLookAheads * (sizeof(A_UINT32)), "BAD lookaheads from lookahead report"); #endif diff --git a/drivers/staging/ath6kl/htc2/htc_send.c b/drivers/staging/ath6kl/htc2/htc_send.c index a6b860a70532..26434d328b18 100644 --- a/drivers/staging/ath6kl/htc2/htc_send.c +++ b/drivers/staging/ath6kl/htc2/htc_send.c @@ -152,7 +152,7 @@ static INLINE void GetHTCSendPackets(HTC_TARGET *target, { int creditsRequired; int remainder; - A_UINT8 sendFlags; + u8 sendFlags; HTC_PACKET *pPacket; unsigned int transferLength; diff --git a/drivers/staging/ath6kl/htc2/htc_services.c b/drivers/staging/ath6kl/htc2/htc_services.c index 5f01c2d19e1b..ea0f6e0ebfc8 100644 --- a/drivers/staging/ath6kl/htc2/htc_services.c +++ b/drivers/staging/ath6kl/htc2/htc_services.c @@ -86,7 +86,7 @@ int HTCSendSetupComplete(HTC_TARGET *target) A_MEMCPY(&pSetupCompleteEx->SetupFlags, &setupFlags, sizeof(pSetupCompleteEx->SetupFlags)); SET_HTC_PACKET_INFO_TX(pSendPacket, NULL, - (A_UINT8 *)pSetupCompleteEx, + (u8 *)pSetupCompleteEx, sizeof(HTC_SETUP_COMPLETE_EX_MSG), ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); @@ -99,7 +99,7 @@ int HTCSendSetupComplete(HTC_TARGET *target) pSetupComplete->MessageID = HTC_MSG_SETUP_COMPLETE_ID; SET_HTC_PACKET_INFO_TX(pSendPacket, NULL, - (A_UINT8 *)pSetupComplete, + (u8 *)pSetupComplete, sizeof(HTC_SETUP_COMPLETE_MSG), ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); @@ -166,7 +166,7 @@ int HTCConnectService(HTC_HANDLE HTCHandle, if ((pConnectReq->pMetaData != NULL) && (pConnectReq->MetaDataLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) { /* copy meta data into message buffer (after header ) */ - A_MEMCPY((A_UINT8 *)pConnectMsg + sizeof(HTC_CONNECT_SERVICE_MSG), + A_MEMCPY((u8 *)pConnectMsg + sizeof(HTC_CONNECT_SERVICE_MSG), pConnectReq->pMetaData, pConnectReq->MetaDataLength); pConnectMsg->ServiceMetaLength = pConnectReq->MetaDataLength; @@ -174,7 +174,7 @@ int HTCConnectService(HTC_HANDLE HTCHandle, SET_HTC_PACKET_INFO_TX(pSendPacket, NULL, - (A_UINT8 *)pConnectMsg, + (u8 *)pConnectMsg, sizeof(HTC_CONNECT_SERVICE_MSG) + pConnectMsg->ServiceMetaLength, ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); @@ -225,7 +225,7 @@ int HTCConnectService(HTC_HANDLE HTCHandle, int copyLength = min((int)pConnectResp->BufferLength, (int)pResponseMsg->ServiceMetaLength); /* copy the meta data */ A_MEMCPY(pConnectResp->pMetaData, - ((A_UINT8 *)pResponseMsg) + sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG), + ((u8 *)pResponseMsg) + sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG), copyLength); pConnectResp->ActualLength = copyLength; } diff --git a/drivers/staging/ath6kl/include/aggr_recv_api.h b/drivers/staging/ath6kl/include/aggr_recv_api.h index d3140171ddc3..8f76f3744b5e 100644 --- a/drivers/staging/ath6kl/include/aggr_recv_api.h +++ b/drivers/staging/ath6kl/include/aggr_recv_api.h @@ -64,7 +64,7 @@ aggr_register_rx_dispatcher(void *cntxt, void * dev, RX_CALLBACK fn); * up to the indicated sequence number. */ void -aggr_process_bar(void *cntxt, A_UINT8 tid, A_UINT16 seq_no); +aggr_process_bar(void *cntxt, u8 tid, A_UINT16 seq_no); /* @@ -82,7 +82,7 @@ aggr_process_bar(void *cntxt, A_UINT8 tid, A_UINT16 seq_no); * in hold_q to OS. */ void -aggr_recv_addba_req_evt(void * cntxt, A_UINT8 tid, A_UINT16 seq_no, A_UINT8 win_sz); +aggr_recv_addba_req_evt(void * cntxt, u8 tid, A_UINT16 seq_no, u8 win_sz); /* @@ -93,7 +93,7 @@ aggr_recv_addba_req_evt(void * cntxt, A_UINT8 tid, A_UINT16 seq_no, A_UINT8 win_ * aggr is not enabled on any tid. */ void -aggr_recv_delba_req_evt(void * cntxt, A_UINT8 tid); +aggr_recv_delba_req_evt(void * cntxt, u8 tid); @@ -108,7 +108,7 @@ aggr_recv_delba_req_evt(void * cntxt, A_UINT8 tid); * callback may be called to deliver frames in order. */ void -aggr_process_recv_frm(void *cntxt, A_UINT8 tid, A_UINT16 seq_no, bool is_amsdu, void **osbuf); +aggr_process_recv_frm(void *cntxt, u8 tid, A_UINT16 seq_no, bool is_amsdu, void **osbuf); /* diff --git a/drivers/staging/ath6kl/include/ar3kconfig.h b/drivers/staging/ath6kl/include/ar3kconfig.h index 24f5b2aa96c8..5556660b270f 100644 --- a/drivers/staging/ath6kl/include/ar3kconfig.h +++ b/drivers/staging/ath6kl/include/ar3kconfig.h @@ -51,7 +51,7 @@ typedef struct { A_UINT32 PwrMgmtEnabled; /* TLPM enabled? */ A_UINT16 IdleTimeout; /* TLPM idle timeout */ A_UINT16 WakeupTimeout; /* TLPM wakeup timeout */ - A_UINT8 bdaddr[6]; /* Bluetooth device address */ + u8 bdaddr[6]; /* Bluetooth device address */ } AR3K_CONFIG_INFO; int AR3KConfigure(AR3K_CONFIG_INFO *pConfigInfo); diff --git a/drivers/staging/ath6kl/include/ar6kap_common.h b/drivers/staging/ath6kl/include/ar6kap_common.h index 9b1b8bfae675..532d8eba9326 100644 --- a/drivers/staging/ath6kl/include/ar6kap_common.h +++ b/drivers/staging/ath6kl/include/ar6kap_common.h @@ -32,11 +32,11 @@ * Used with AR6000_XIOCTL_AP_GET_STA_LIST */ typedef struct { - A_UINT8 mac[ATH_MAC_LEN]; - A_UINT8 aid; - A_UINT8 keymgmt; - A_UINT8 ucipher; - A_UINT8 auth; + u8 mac[ATH_MAC_LEN]; + u8 aid; + u8 keymgmt; + u8 ucipher; + u8 auth; } station_t; typedef struct { station_t sta[AP_MAX_NUM_STA]; diff --git a/drivers/staging/ath6kl/include/common/a_hci.h b/drivers/staging/ath6kl/include/common/a_hci.h index f2943466339f..1d7d5fa35421 100644 --- a/drivers/staging/ath6kl/include/common/a_hci.h +++ b/drivers/staging/ath6kl/include/common/a_hci.h @@ -243,8 +243,8 @@ typedef enum { /* Command pkt */ typedef struct hci_cmd_pkt_t { A_UINT16 opcode; - A_UINT8 param_length; - A_UINT8 params[255]; + u8 param_length; + u8 params[255]; } POSTPACK HCI_CMD_PKT; #define ACL_DATA_HDR_SIZE 4 /* hdl_and flags + data_len */ @@ -252,40 +252,40 @@ typedef struct hci_cmd_pkt_t { typedef struct hci_acl_data_pkt_t { A_UINT16 hdl_and_flags; A_UINT16 data_len; - A_UINT8 data[Max80211_PAL_PDU_Size]; + u8 data[Max80211_PAL_PDU_Size]; } POSTPACK HCI_ACL_DATA_PKT; /* Event pkt */ typedef struct hci_event_pkt_t { - A_UINT8 event_code; - A_UINT8 param_len; - A_UINT8 params[256]; + u8 event_code; + u8 param_len; + u8 params[256]; } POSTPACK HCI_EVENT_PKT; /*============== HCI Command definitions ======================= */ typedef struct hci_cmd_phy_link_t { A_UINT16 opcode; - A_UINT8 param_length; - A_UINT8 phy_link_hdl; - A_UINT8 link_key_len; - A_UINT8 link_key_type; - A_UINT8 link_key[LINK_KEY_LEN]; + u8 param_length; + u8 phy_link_hdl; + u8 link_key_len; + u8 link_key_type; + u8 link_key[LINK_KEY_LEN]; } POSTPACK HCI_CMD_PHY_LINK; typedef struct hci_cmd_write_rem_amp_assoc_t { A_UINT16 opcode; - A_UINT8 param_length; - A_UINT8 phy_link_hdl; + u8 param_length; + u8 phy_link_hdl; A_UINT16 len_so_far; A_UINT16 amp_assoc_remaining_len; - A_UINT8 amp_assoc_frag[AMP_ASSOC_MAX_FRAG_SZ]; + u8 amp_assoc_frag[AMP_ASSOC_MAX_FRAG_SZ]; } POSTPACK HCI_CMD_WRITE_REM_AMP_ASSOC; typedef struct hci_cmd_opcode_hdl_t { A_UINT16 opcode; - A_UINT8 param_length; + u8 param_length; A_UINT16 hdl; } POSTPACK HCI_CMD_READ_LINK_QUAL, HCI_CMD_FLUSH, @@ -293,8 +293,8 @@ typedef struct hci_cmd_opcode_hdl_t { typedef struct hci_cmd_read_local_amp_assoc_t { A_UINT16 opcode; - A_UINT8 param_length; - A_UINT8 phy_link_hdl; + u8 param_length; + u8 phy_link_hdl; A_UINT16 len_so_far; A_UINT16 max_rem_amp_assoc_len; } POSTPACK HCI_CMD_READ_LOCAL_AMP_ASSOC; @@ -302,54 +302,54 @@ typedef struct hci_cmd_read_local_amp_assoc_t { typedef struct hci_cmd_set_event_mask_t { A_UINT16 opcode; - A_UINT8 param_length; + u8 param_length; A_UINT64 mask; }POSTPACK HCI_CMD_SET_EVT_MASK, HCI_CMD_SET_EVT_MASK_PG_2; typedef struct hci_cmd_enhanced_flush_t{ A_UINT16 opcode; - A_UINT8 param_length; + u8 param_length; A_UINT16 hdl; - A_UINT8 type; + u8 type; } POSTPACK HCI_CMD_ENHANCED_FLUSH; typedef struct hci_cmd_write_timeout_t { A_UINT16 opcode; - A_UINT8 param_length; + u8 param_length; A_UINT16 timeout; } POSTPACK HCI_CMD_WRITE_TIMEOUT; typedef struct hci_cmd_write_link_supervision_timeout_t { A_UINT16 opcode; - A_UINT8 param_length; + u8 param_length; A_UINT16 hdl; A_UINT16 timeout; } POSTPACK HCI_CMD_WRITE_LINK_SUPERVISION_TIMEOUT; typedef struct hci_cmd_write_flow_control_t { A_UINT16 opcode; - A_UINT8 param_length; - A_UINT8 mode; + u8 param_length; + u8 mode; } POSTPACK HCI_CMD_WRITE_FLOW_CONTROL; typedef struct location_data_cfg_t { - A_UINT8 reg_domain_aware; - A_UINT8 reg_domain[3]; - A_UINT8 reg_options; + u8 reg_domain_aware; + u8 reg_domain[3]; + u8 reg_options; } POSTPACK LOCATION_DATA_CFG; typedef struct hci_cmd_write_location_data_t { A_UINT16 opcode; - A_UINT8 param_length; + u8 param_length; LOCATION_DATA_CFG cfg; } POSTPACK HCI_CMD_WRITE_LOCATION_DATA; typedef struct flow_spec_t { - A_UINT8 id; - A_UINT8 service_type; + u8 id; + u8 service_type; A_UINT16 max_sdu; A_UINT32 sdu_inter_arrival_time; A_UINT32 access_latency; @@ -359,15 +359,15 @@ typedef struct flow_spec_t { typedef struct hci_cmd_create_logical_link_t { A_UINT16 opcode; - A_UINT8 param_length; - A_UINT8 phy_link_hdl; + u8 param_length; + u8 phy_link_hdl; FLOW_SPEC tx_flow_spec; FLOW_SPEC rx_flow_spec; } POSTPACK HCI_CMD_CREATE_LOGICAL_LINK; typedef struct hci_cmd_flow_spec_modify_t { A_UINT16 opcode; - A_UINT8 param_length; + u8 param_length; A_UINT16 hdl; FLOW_SPEC tx_flow_spec; FLOW_SPEC rx_flow_spec; @@ -375,28 +375,28 @@ typedef struct hci_cmd_flow_spec_modify_t { typedef struct hci_cmd_logical_link_cancel_t { A_UINT16 opcode; - A_UINT8 param_length; - A_UINT8 phy_link_hdl; - A_UINT8 tx_flow_spec_id; + u8 param_length; + u8 phy_link_hdl; + u8 tx_flow_spec_id; } POSTPACK HCI_CMD_LOGICAL_LINK_CANCEL; typedef struct hci_cmd_disconnect_logical_link_t { A_UINT16 opcode; - A_UINT8 param_length; + u8 param_length; A_UINT16 logical_link_hdl; } POSTPACK HCI_CMD_DISCONNECT_LOGICAL_LINK; typedef struct hci_cmd_disconnect_phy_link_t { A_UINT16 opcode; - A_UINT8 param_length; - A_UINT8 phy_link_hdl; + u8 param_length; + u8 phy_link_hdl; } POSTPACK HCI_CMD_DISCONNECT_PHY_LINK; typedef struct hci_cmd_srm_t { A_UINT16 opcode; - A_UINT8 param_length; - A_UINT8 phy_link_hdl; - A_UINT8 mode; + u8 param_length; + u8 phy_link_hdl; + u8 mode; } POSTPACK HCI_CMD_SHORT_RANGE_MODE; /*============== HCI Command definitions end ======================= */ @@ -406,123 +406,123 @@ typedef struct hci_cmd_srm_t { /* Command complete event */ typedef struct hci_event_cmd_complete_t { - A_UINT8 event_code; - A_UINT8 param_len; - A_UINT8 num_hci_cmd_pkts; + u8 event_code; + u8 param_len; + u8 num_hci_cmd_pkts; A_UINT16 opcode; - A_UINT8 params[255]; + u8 params[255]; } POSTPACK HCI_EVENT_CMD_COMPLETE; /* Command status event */ typedef struct hci_event_cmd_status_t { - A_UINT8 event_code; - A_UINT8 param_len; - A_UINT8 status; - A_UINT8 num_hci_cmd_pkts; + u8 event_code; + u8 param_len; + u8 status; + u8 num_hci_cmd_pkts; A_UINT16 opcode; } POSTPACK HCI_EVENT_CMD_STATUS; /* Hardware Error event */ typedef struct hci_event_hw_err_t { - A_UINT8 event_code; - A_UINT8 param_len; - A_UINT8 hw_err_code; + u8 event_code; + u8 param_len; + u8 hw_err_code; } POSTPACK HCI_EVENT_HW_ERR; /* Flush occured event */ /* Qos Violation event */ typedef struct hci_event_handle_t { - A_UINT8 event_code; - A_UINT8 param_len; + u8 event_code; + u8 param_len; A_UINT16 handle; } POSTPACK HCI_EVENT_FLUSH_OCCRD, HCI_EVENT_QOS_VIOLATION; /* Loopback command event */ typedef struct hci_loopback_cmd_t { - A_UINT8 event_code; - A_UINT8 param_len; - A_UINT8 params[252]; + u8 event_code; + u8 param_len; + u8 params[252]; } POSTPACK HCI_EVENT_LOOPBACK_CMD; /* Data buffer overflow event */ typedef struct hci_data_buf_overflow_t { - A_UINT8 event_code; - A_UINT8 param_len; - A_UINT8 link_type; + u8 event_code; + u8 param_len; + u8 link_type; } POSTPACK HCI_EVENT_DATA_BUF_OVERFLOW; /* Enhanced Flush complete event */ typedef struct hci_enhanced_flush_complt_t{ - A_UINT8 event_code; - A_UINT8 param_len; + u8 event_code; + u8 param_len; A_UINT16 hdl; } POSTPACK HCI_EVENT_ENHANCED_FLUSH_COMPLT; /* Channel select event */ typedef struct hci_event_chan_select_t { - A_UINT8 event_code; - A_UINT8 param_len; - A_UINT8 phy_link_hdl; + u8 event_code; + u8 param_len; + u8 phy_link_hdl; } POSTPACK HCI_EVENT_CHAN_SELECT; /* Physical Link Complete event */ typedef struct hci_event_phy_link_complete_event_t { - A_UINT8 event_code; - A_UINT8 param_len; - A_UINT8 status; - A_UINT8 phy_link_hdl; + u8 event_code; + u8 param_len; + u8 status; + u8 phy_link_hdl; } POSTPACK HCI_EVENT_PHY_LINK_COMPLETE; /* Logical Link complete event */ typedef struct hci_event_logical_link_complete_event_t { - A_UINT8 event_code; - A_UINT8 param_len; - A_UINT8 status; + u8 event_code; + u8 param_len; + u8 status; A_UINT16 logical_link_hdl; - A_UINT8 phy_hdl; - A_UINT8 tx_flow_id; + u8 phy_hdl; + u8 tx_flow_id; } POSTPACK HCI_EVENT_LOGICAL_LINK_COMPLETE_EVENT; /* Disconnect Logical Link complete event */ typedef struct hci_event_disconnect_logical_link_event_t { - A_UINT8 event_code; - A_UINT8 param_len; - A_UINT8 status; + u8 event_code; + u8 param_len; + u8 status; A_UINT16 logical_link_hdl; - A_UINT8 reason; + u8 reason; } POSTPACK HCI_EVENT_DISCONNECT_LOGICAL_LINK_EVENT; /* Disconnect Physical Link complete event */ typedef struct hci_event_disconnect_phy_link_complete_t { - A_UINT8 event_code; - A_UINT8 param_len; - A_UINT8 status; - A_UINT8 phy_link_hdl; - A_UINT8 reason; + u8 event_code; + u8 param_len; + u8 status; + u8 phy_link_hdl; + u8 reason; } POSTPACK HCI_EVENT_DISCONNECT_PHY_LINK_COMPLETE; typedef struct hci_event_physical_link_loss_early_warning_t{ - A_UINT8 event_code; - A_UINT8 param_len; - A_UINT8 phy_hdl; - A_UINT8 reason; + u8 event_code; + u8 param_len; + u8 phy_hdl; + u8 reason; } POSTPACK HCI_EVENT_PHY_LINK_LOSS_EARLY_WARNING; typedef struct hci_event_physical_link_recovery_t{ - A_UINT8 event_code; - A_UINT8 param_len; - A_UINT8 phy_hdl; + u8 event_code; + u8 param_len; + u8 phy_hdl; } POSTPACK HCI_EVENT_PHY_LINK_RECOVERY; /* Flow spec modify complete event */ /* Flush event */ typedef struct hci_event_status_handle_t { - A_UINT8 event_code; - A_UINT8 param_len; - A_UINT8 status; + u8 event_code; + u8 param_len; + u8 status; A_UINT16 handle; } POSTPACK HCI_EVENT_FLOW_SPEC_MODIFY, HCI_EVENT_FLUSH; @@ -530,40 +530,40 @@ typedef struct hci_event_status_handle_t { /* Num of completed data blocks event */ typedef struct hci_event_num_of_compl_data_blks_t { - A_UINT8 event_code; - A_UINT8 param_len; + u8 event_code; + u8 param_len; A_UINT16 num_data_blks; - A_UINT8 num_handles; - A_UINT8 params[255]; + u8 num_handles; + u8 params[255]; } POSTPACK HCI_EVENT_NUM_COMPL_DATA_BLKS; /* Short range mode change complete event */ typedef struct hci_srm_cmpl_t { - A_UINT8 event_code; - A_UINT8 param_len; - A_UINT8 status; - A_UINT8 phy_link; - A_UINT8 state; + u8 event_code; + u8 param_len; + u8 status; + u8 phy_link; + u8 state; } POSTPACK HCI_EVENT_SRM_COMPL; typedef struct hci_event_amp_status_change_t{ - A_UINT8 event_code; - A_UINT8 param_len; - A_UINT8 status; - A_UINT8 amp_status; + u8 event_code; + u8 param_len; + u8 status; + u8 amp_status; } POSTPACK HCI_EVENT_AMP_STATUS_CHANGE; /*============== Event definitions end =========================== */ typedef struct local_amp_info_resp_t { - A_UINT8 status; - A_UINT8 amp_status; + u8 status; + u8 amp_status; A_UINT32 total_bw; /* kbps */ A_UINT32 max_guranteed_bw; /* kbps */ A_UINT32 min_latency; A_UINT32 max_pdu_size; - A_UINT8 amp_type; + u8 amp_type; A_UINT16 pal_capabilities; A_UINT16 amp_assoc_len; A_UINT32 max_flush_timeout; /* in ms */ @@ -571,10 +571,10 @@ typedef struct local_amp_info_resp_t { } POSTPACK LOCAL_AMP_INFO; typedef struct amp_assoc_cmd_resp_t{ - A_UINT8 status; - A_UINT8 phy_hdl; + u8 status; + u8 phy_hdl; A_UINT16 amp_assoc_len; - A_UINT8 amp_assoc_frag[AMP_ASSOC_MAX_FRAG_SZ]; + u8 amp_assoc_frag[AMP_ASSOC_MAX_FRAG_SZ]; }POSTPACK AMP_ASSOC_CMD_RESP; @@ -618,38 +618,38 @@ enum PAL_HCI_CMD_STATUS { /* Following are event return parameters.. part of HCI events */ typedef struct timeout_read_t { - A_UINT8 status; + u8 status; A_UINT16 timeout; }POSTPACK TIMEOUT_INFO; typedef struct link_supervision_timeout_read_t { - A_UINT8 status; + u8 status; A_UINT16 hdl; A_UINT16 timeout; }POSTPACK LINK_SUPERVISION_TIMEOUT_INFO; typedef struct status_hdl_t { - A_UINT8 status; + u8 status; A_UINT16 hdl; }POSTPACK INFO_STATUS_HDL; typedef struct write_remote_amp_assoc_t{ - A_UINT8 status; - A_UINT8 hdl; + u8 status; + u8 hdl; }POSTPACK WRITE_REMOTE_AMP_ASSOC_INFO; typedef struct read_loc_info_t { - A_UINT8 status; + u8 status; LOCATION_DATA_CFG loc; }POSTPACK READ_LOC_INFO; typedef struct read_flow_ctrl_mode_t { - A_UINT8 status; - A_UINT8 mode; + u8 status; + u8 mode; }POSTPACK READ_FLWCTRL_INFO; typedef struct read_data_blk_size_t { - A_UINT8 status; + u8 status; A_UINT16 max_acl_data_pkt_len; A_UINT16 data_block_len; A_UINT16 total_num_data_blks; @@ -657,23 +657,23 @@ typedef struct read_data_blk_size_t { /* Read Link quality info */ typedef struct link_qual_t { - A_UINT8 status; + u8 status; A_UINT16 hdl; - A_UINT8 link_qual; + u8 link_qual; } POSTPACK READ_LINK_QUAL_INFO, READ_RSSI_INFO; typedef struct ll_cancel_resp_t { - A_UINT8 status; - A_UINT8 phy_link_hdl; - A_UINT8 tx_flow_spec_id; + u8 status; + u8 phy_link_hdl; + u8 tx_flow_spec_id; } POSTPACK LL_CANCEL_RESP; typedef struct read_local_ver_info_t { - A_UINT8 status; - A_UINT8 hci_version; + u8 status; + u8 hci_version; A_UINT16 hci_revision; - A_UINT8 pal_version; + u8 pal_version; A_UINT16 manf_name; A_UINT16 pal_sub_ver; } POSTPACK READ_LOCAL_VER_INFO; diff --git a/drivers/staging/ath6kl/include/common/bmi_msg.h b/drivers/staging/ath6kl/include/common/bmi_msg.h index f9687d325b2f..171bf378baa0 100644 --- a/drivers/staging/ath6kl/include/common/bmi_msg.h +++ b/drivers/staging/ath6kl/include/common/bmi_msg.h @@ -77,7 +77,7 @@ * A_UINT32 address * A_UINT32 length, at most BMI_DATASZ_MAX * Response format: - * A_UINT8 data[length] + * u8 data[length] */ #define BMI_WRITE_MEMORY 3 @@ -87,7 +87,7 @@ * A_UINT32 command (BMI_WRITE_MEMORY) * A_UINT32 address * A_UINT32 length, at most BMI_DATASZ_MAX - * A_UINT8 data[length] + * u8 data[length] * Response format: none */ @@ -229,7 +229,7 @@ PREPACK struct bmi_target_info { * A_UINT32 command (BMI_LZ_DATA) * A_UINT32 length (of compressed data), * at most BMI_DATASZ_MAX - * A_UINT8 CompressedData[length] + * u8 CompressedData[length] * Response format: none * Note: Not supported on all versions of ROM firmware. */ diff --git a/drivers/staging/ath6kl/include/common/dbglog.h b/drivers/staging/ath6kl/include/common/dbglog.h index 382d9a2dd4eb..060a6b16c193 100644 --- a/drivers/staging/ath6kl/include/common/dbglog.h +++ b/drivers/staging/ath6kl/include/common/dbglog.h @@ -89,7 +89,7 @@ extern "C" { PREPACK struct dbglog_buf_s { struct dbglog_buf_s *next; - A_UINT8 *buffer; + u8 *buffer; A_UINT32 bufsize; A_UINT32 length; A_UINT32 count; diff --git a/drivers/staging/ath6kl/include/common/epping_test.h b/drivers/staging/ath6kl/include/common/epping_test.h index f8aeb3f657ea..061884dfb337 100644 --- a/drivers/staging/ath6kl/include/common/epping_test.h +++ b/drivers/staging/ath6kl/include/common/epping_test.h @@ -41,25 +41,25 @@ #define HCI_RSVD_EXPECTED_PKT_TYPE_RECV_OFFSET 7 typedef PREPACK struct { - A_UINT8 _HCIRsvd[8]; /* reserved for HCI packet header (GMBOX) testing */ - A_UINT8 StreamEcho_h; /* stream no. to echo this packet on (filled by host) */ - A_UINT8 StreamEchoSent_t; /* stream no. packet was echoed to (filled by target) + u8 _HCIRsvd[8]; /* reserved for HCI packet header (GMBOX) testing */ + u8 StreamEcho_h; /* stream no. to echo this packet on (filled by host) */ + u8 StreamEchoSent_t; /* stream no. packet was echoed to (filled by target) When echoed: StreamEchoSent_t == StreamEcho_h */ - A_UINT8 StreamRecv_t; /* stream no. that target received this packet on (filled by target) */ - A_UINT8 StreamNo_h; /* stream number to send on (filled by host) */ - A_UINT8 Magic_h[4]; /* magic number to filter for this packet on the host*/ - A_UINT8 _rsvd[6]; /* reserved fields that must be set to a "reserved" value + u8 StreamRecv_t; /* stream no. that target received this packet on (filled by target) */ + u8 StreamNo_h; /* stream number to send on (filled by host) */ + u8 Magic_h[4]; /* magic number to filter for this packet on the host*/ + u8 _rsvd[6]; /* reserved fields that must be set to a "reserved" value since this packet maps to a 14-byte ethernet frame we want to make sure ethertype field is set to something unknown */ - A_UINT8 _pad[2]; /* padding for alignment */ - A_UINT8 TimeStamp[8]; /* timestamp of packet (host or target) */ + u8 _pad[2]; /* padding for alignment */ + u8 TimeStamp[8]; /* timestamp of packet (host or target) */ A_UINT32 HostContext_h; /* 4 byte host context, target echos this back */ A_UINT32 SeqNo; /* sequence number (set by host or target) */ A_UINT16 Cmd_h; /* ping command (filled by host) */ A_UINT16 CmdFlags_h; /* optional flags */ - A_UINT8 CmdBuffer_h[8]; /* buffer for command (host -> target) */ - A_UINT8 CmdBuffer_t[8]; /* buffer for command (target -> host) */ + u8 CmdBuffer_h[8]; /* buffer for command (host -> target) */ + u8 CmdBuffer_t[8]; /* buffer for command (target -> host) */ A_UINT16 DataLength; /* length of data */ A_UINT16 DataCRC; /* 16 bit CRC of data */ A_UINT16 HeaderCRC; /* header CRC (fields : StreamNo_h to end, minus HeaderCRC) */ diff --git a/drivers/staging/ath6kl/include/common/gmboxif.h b/drivers/staging/ath6kl/include/common/gmboxif.h index 4d8d85fd2e7c..374007569d6d 100644 --- a/drivers/staging/ath6kl/include/common/gmboxif.h +++ b/drivers/staging/ath6kl/include/common/gmboxif.h @@ -47,17 +47,17 @@ typedef PREPACK struct { typedef PREPACK struct { A_UINT16 Flags_ConnHandle; - A_UINT8 Length; + u8 Length; } POSTPACK BT_HCI_SCO_HEADER; typedef PREPACK struct { A_UINT16 OpCode; - A_UINT8 ParamLength; + u8 ParamLength; } POSTPACK BT_HCI_COMMAND_HEADER; typedef PREPACK struct { - A_UINT8 EventCode; - A_UINT8 ParamLength; + u8 EventCode; + u8 ParamLength; } POSTPACK BT_HCI_EVENT_HEADER; /* MBOX host interrupt signal assignments */ diff --git a/drivers/staging/ath6kl/include/common/htc.h b/drivers/staging/ath6kl/include/common/htc.h index f96cf7db7e06..13a24da3af8e 100644 --- a/drivers/staging/ath6kl/include/common/htc.h +++ b/drivers/staging/ath6kl/include/common/htc.h @@ -31,7 +31,7 @@ #define A_OFFSETOF(type,field) (unsigned long)(&(((type *)NULL)->field)) #define ASSEMBLE_UNALIGNED_UINT16(p,highbyte,lowbyte) \ - (((A_UINT16)(((A_UINT8 *)(p))[(highbyte)])) << 8 | (A_UINT16)(((A_UINT8 *)(p))[(lowbyte)])) + (((A_UINT16)(((u8 *)(p))[(highbyte)])) << 8 | (A_UINT16)(((u8 *)(p))[(lowbyte)])) /* alignment independent macros (little-endian) to fetch UINT16s or UINT8s from a * structure using only the type and field name. @@ -43,15 +43,15 @@ #define A_SET_UINT16_FIELD(p,type,field,value) \ { \ - ((A_UINT8 *)(p))[A_OFFSETOF(type,field)] = (A_UINT8)(value); \ - ((A_UINT8 *)(p))[A_OFFSETOF(type,field) + 1] = (A_UINT8)((value) >> 8); \ + ((u8 *)(p))[A_OFFSETOF(type,field)] = (u8)(value); \ + ((u8 *)(p))[A_OFFSETOF(type,field) + 1] = (u8)((value) >> 8); \ } #define A_GET_UINT8_FIELD(p,type,field) \ - ((A_UINT8 *)(p))[A_OFFSETOF(type,field)] + ((u8 *)(p))[A_OFFSETOF(type,field)] #define A_SET_UINT8_FIELD(p,type,field,value) \ - ((A_UINT8 *)(p))[A_OFFSETOF(type,field)] = (value) + ((u8 *)(p))[A_OFFSETOF(type,field)] = (value) /****** DANGER DANGER *************** * @@ -69,13 +69,13 @@ typedef PREPACK struct _HTC_FRAME_HDR{ /* do not remove or re-arrange these fields, these are minimally required * to take advantage of 4-byte lookaheads in some hardware implementations */ - A_UINT8 EndpointID; - A_UINT8 Flags; + u8 EndpointID; + u8 Flags; A_UINT16 PayloadLen; /* length of data (including trailer) that follows the header */ /***** end of 4-byte lookahead ****/ - A_UINT8 ControlBytes[2]; + u8 ControlBytes[2]; /* message payload starts after the header */ @@ -119,16 +119,16 @@ typedef PREPACK struct { A_UINT16 MessageID; /* ID */ A_UINT16 CreditCount; /* number of credits the target can offer */ A_UINT16 CreditSize; /* size of each credit */ - A_UINT8 MaxEndpoints; /* maximum number of endpoints the target has resources for */ - A_UINT8 _Pad1; + u8 MaxEndpoints; /* maximum number of endpoints the target has resources for */ + u8 _Pad1; } POSTPACK HTC_READY_MSG; /* extended HTC ready message */ typedef PREPACK struct { HTC_READY_MSG Version2_0_Info; /* legacy version 2.0 information at the front... */ /* extended information */ - A_UINT8 HTCVersion; - A_UINT8 MaxMsgsPerHTCBundle; + u8 HTCVersion; + u8 MaxMsgsPerHTCBundle; } POSTPACK HTC_READY_EX_MSG; #define HTC_VERSION_2P0 0x00 @@ -151,8 +151,8 @@ typedef PREPACK struct { #define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_THREE_FOURTHS 0x2 #define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_UNITY 0x3 - A_UINT8 ServiceMetaLength; /* length of meta data that follows */ - A_UINT8 _Pad1; + u8 ServiceMetaLength; /* length of meta data that follows */ + u8 _Pad1; /* service-specific meta data starts after the header */ @@ -163,11 +163,11 @@ typedef PREPACK struct { typedef PREPACK struct { A_UINT16 MessageID; A_UINT16 ServiceID; /* service ID that the connection request was made */ - A_UINT8 Status; /* service connection status */ - A_UINT8 EndpointID; /* assigned endpoint ID */ + u8 Status; /* service connection status */ + u8 EndpointID; /* assigned endpoint ID */ A_UINT16 MaxMsgSize; /* maximum expected message size on this endpoint */ - A_UINT8 ServiceMetaLength; /* length of meta data that follows */ - A_UINT8 _Pad1; + u8 ServiceMetaLength; /* length of meta data that follows */ + u8 _Pad1; /* service-specific meta data starts after the header */ @@ -182,8 +182,8 @@ typedef PREPACK struct { typedef PREPACK struct { A_UINT16 MessageID; A_UINT32 SetupFlags; - A_UINT8 MaxMsgsPerBundledRecv; - A_UINT8 Rsvd[3]; + u8 MaxMsgsPerBundledRecv; + u8 Rsvd[3]; } POSTPACK HTC_SETUP_COMPLETE_EX_MSG; #define HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV (1 << 0) @@ -204,19 +204,19 @@ typedef PREPACK struct { #define HTC_RECORD_LOOKAHEAD_BUNDLE 3 typedef PREPACK struct { - A_UINT8 RecordID; /* Record ID */ - A_UINT8 Length; /* Length of record */ + u8 RecordID; /* Record ID */ + u8 Length; /* Length of record */ } POSTPACK HTC_RECORD_HDR; typedef PREPACK struct { - A_UINT8 EndpointID; /* Endpoint that owns these credits */ - A_UINT8 Credits; /* credits to report since last report */ + u8 EndpointID; /* Endpoint that owns these credits */ + u8 Credits; /* credits to report since last report */ } POSTPACK HTC_CREDIT_REPORT; typedef PREPACK struct { - A_UINT8 PreValid; /* pre valid guard */ - A_UINT8 LookAhead[4]; /* 4 byte lookahead */ - A_UINT8 PostValid; /* post valid guard */ + u8 PreValid; /* pre valid guard */ + u8 LookAhead[4]; /* 4 byte lookahead */ + u8 PostValid; /* post valid guard */ /* NOTE: the LookAhead array is guarded by a PreValid and Post Valid guard bytes. * The PreValid bytes must equal the inverse of the PostValid byte */ @@ -224,7 +224,7 @@ typedef PREPACK struct { } POSTPACK HTC_LOOKAHEAD_REPORT; typedef PREPACK struct { - A_UINT8 LookAhead[4]; /* 4 byte lookahead */ + u8 LookAhead[4]; /* 4 byte lookahead */ } POSTPACK HTC_BUNDLED_LOOKAHEAD_REPORT; #ifndef ATH_TARGET diff --git a/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h b/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h index 325d2051eec2..a50e9eb24581 100644 --- a/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h +++ b/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h @@ -172,8 +172,8 @@ typedef PREPACK struct reg_dmn_pair_mapping { A_UINT16 regDmnEnum; /* 16 bit reg domain pair */ A_UINT16 regDmn5GHz; /* 5GHz reg domain */ A_UINT16 regDmn2GHz; /* 2GHz reg domain */ - A_UINT8 flags5GHz; /* Requirements flags (AdHoc disallow etc) */ - A_UINT8 flags2GHz; /* Requirements flags (AdHoc disallow etc) */ + u8 flags5GHz; /* Requirements flags (AdHoc disallow etc) */ + u8 flags2GHz; /* Requirements flags (AdHoc disallow etc) */ A_UINT32 pscanMask; /* Passive Scan flags which can override unitary domain passive scan flags. This value is used as a mask on the unitary flags*/ } POSTPACK REG_DMN_PAIR_MAPPING; @@ -211,10 +211,10 @@ typedef PREPACK struct { typedef PREPACK struct RegDmnFreqBand { A_UINT16 lowChannel; /* Low channel center in MHz */ A_UINT16 highChannel; /* High Channel center in MHz */ - A_UINT8 power; /* Max power (dBm) for channel range */ - A_UINT8 channelSep; /* Channel separation within the band */ - A_UINT8 useDfs; /* Use DFS in the RegDomain if corresponding bit is set */ - A_UINT8 mode; /* Mode of operation */ + u8 power; /* Max power (dBm) for channel range */ + u8 channelSep; /* Channel separation within the band */ + u8 useDfs; /* Use DFS in the RegDomain if corresponding bit is set */ + u8 mode; /* Mode of operation */ A_UINT32 usePassScan; /* Use Passive Scan in the RegDomain if corresponding bit is set */ A_UINT32 ht40ChanMask; /* lower 16 bits: indicate which frequencies in the block is HT40 capable upper 16 bits: what rate (half/quarter) the channel is */ @@ -224,10 +224,10 @@ typedef PREPACK struct RegDmnFreqBand { typedef PREPACK struct regDomain { A_UINT16 regDmnEnum; /* value from EnumRd table */ - A_UINT8 rdCTL; - A_UINT8 maxAntGain; - A_UINT8 dfsMask; /* DFS bitmask for 5Ghz tables */ - A_UINT8 flags; /* Requirement flags (AdHoc disallow etc) */ + u8 rdCTL; + u8 maxAntGain; + u8 dfsMask; /* DFS bitmask for 5Ghz tables */ + u8 flags; /* Requirement flags (AdHoc disallow etc) */ A_UINT16 reserved; /* for alignment */ A_UINT32 pscan; /* Bitmask for passive scan */ A_UINT32 chan11a[BMLEN]; /* 64 bit bitmask for channel/band selection */ diff --git a/drivers/staging/ath6kl/include/common/wlan_dset.h b/drivers/staging/ath6kl/include/common/wlan_dset.h index 864a60cedf10..e092020a2632 100644 --- a/drivers/staging/ath6kl/include/common/wlan_dset.h +++ b/drivers/staging/ath6kl/include/common/wlan_dset.h @@ -25,8 +25,8 @@ typedef PREPACK struct wow_config_dset { - A_UINT8 valid_dset; - A_UINT8 gpio_enable; + u8 valid_dset; + u8 gpio_enable; A_UINT16 gpio_pin; } POSTPACK WOW_CONFIG_DSET; diff --git a/drivers/staging/ath6kl/include/common/wmi.h b/drivers/staging/ath6kl/include/common/wmi.h index 70758bfaa134..d39e7282ec23 100644 --- a/drivers/staging/ath6kl/include/common/wmi.h +++ b/drivers/staging/ath6kl/include/common/wmi.h @@ -77,16 +77,16 @@ PREPACK struct host_app_area_s { * Data Path */ typedef PREPACK struct { - A_UINT8 dstMac[ATH_MAC_LEN]; - A_UINT8 srcMac[ATH_MAC_LEN]; + u8 dstMac[ATH_MAC_LEN]; + u8 srcMac[ATH_MAC_LEN]; A_UINT16 typeOrLen; } POSTPACK ATH_MAC_HDR; typedef PREPACK struct { - A_UINT8 dsap; - A_UINT8 ssap; - A_UINT8 cntl; - A_UINT8 orgCode[3]; + u8 dsap; + u8 ssap; + u8 cntl; + u8 orgCode[3]; A_UINT16 etherType; } POSTPACK ATH_LLC_SNAP_HDR; @@ -161,7 +161,7 @@ typedef enum { typedef PREPACK struct { A_INT8 rssi; - A_UINT8 info; /* usage of 'info' field(8-bit): + u8 info; /* usage of 'info' field(8-bit): * b1:b0 - WMI_MSG_TYPE * b4:b3:b2 - UP(tid) * b5 - Used in AP mode. More-data in tx dir, PS in rx. @@ -195,17 +195,17 @@ typedef PREPACK struct { #endif typedef PREPACK struct { - A_UINT8 pktID; /* The packet ID to identify the tx request */ - A_UINT8 ratePolicyID; /* The rate policy to be used for the tx of this frame */ + u8 pktID; /* The packet ID to identify the tx request */ + u8 ratePolicyID; /* The rate policy to be used for the tx of this frame */ } POSTPACK WMI_TX_META_V1; #define WMI_CSUM_DIR_TX (0x1) #define TX_CSUM_CALC_FILL (0x1) typedef PREPACK struct { - A_UINT8 csumStart; /*Offset from start of the WMI header for csum calculation to begin */ - A_UINT8 csumDest; /*Offset from start of WMI header where final csum goes*/ - A_UINT8 csumFlags; /*number of bytes over which csum is calculated*/ + u8 csumStart; /*Offset from start of the WMI header for csum calculation to begin */ + u8 csumDest; /*Offset from start of WMI header where final csum goes*/ + u8 csumFlags; /*number of bytes over which csum is calculated*/ } POSTPACK WMI_TX_META_V2; @@ -242,17 +242,17 @@ typedef PREPACK struct { #endif typedef PREPACK struct { - A_UINT8 status; /* one of WMI_RX_STATUS_... */ - A_UINT8 rix; /* rate index mapped to rate at which this packet was received. */ - A_UINT8 rssi; /* rssi of packet */ - A_UINT8 channel;/* rf channel during packet reception */ + u8 status; /* one of WMI_RX_STATUS_... */ + u8 rix; /* rate index mapped to rate at which this packet was received. */ + u8 rssi; /* rssi of packet */ + u8 channel;/* rf channel during packet reception */ A_UINT16 flags; /* a combination of WMI_RX_FLAGS_... */ } POSTPACK WMI_RX_META_V1; #define RX_CSUM_VALID_FLAG (0x1) typedef PREPACK struct { A_UINT16 csum; - A_UINT8 csumFlags;/* bit 0 set -partial csum valid + u8 csumFlags;/* bit 0 set -partial csum valid bit 1 set -test mode */ } POSTPACK WMI_RX_META_V2; @@ -522,17 +522,17 @@ typedef enum { #define DEFAULT_CONNECT_CTRL_FLAGS (CONNECT_CSA_FOLLOW_BSS) typedef PREPACK struct { - A_UINT8 networkType; - A_UINT8 dot11AuthMode; - A_UINT8 authMode; - A_UINT8 pairwiseCryptoType; - A_UINT8 pairwiseCryptoLen; - A_UINT8 groupCryptoType; - A_UINT8 groupCryptoLen; - A_UINT8 ssidLength; + u8 networkType; + u8 dot11AuthMode; + u8 authMode; + u8 pairwiseCryptoType; + u8 pairwiseCryptoLen; + u8 groupCryptoType; + u8 groupCryptoLen; + u8 ssidLength; A_UCHAR ssid[WMI_MAX_SSID_LEN]; A_UINT16 channel; - A_UINT8 bssid[ATH_MAC_LEN]; + u8 bssid[ATH_MAC_LEN]; A_UINT32 ctrl_flags; } POSTPACK WMI_CONNECT_CMD; @@ -541,12 +541,12 @@ typedef PREPACK struct { */ typedef PREPACK struct { A_UINT16 channel; /* hint */ - A_UINT8 bssid[ATH_MAC_LEN]; /* mandatory if set */ + u8 bssid[ATH_MAC_LEN]; /* mandatory if set */ } POSTPACK WMI_RECONNECT_CMD; #define WMI_PMK_LEN 32 typedef PREPACK struct { - A_UINT8 pmk[WMI_PMK_LEN]; + u8 pmk[WMI_PMK_LEN]; } POSTPACK WMI_SET_PMK_CMD; /* @@ -572,21 +572,21 @@ typedef enum { #define KEY_OP_VALID_MASK 0x03 typedef PREPACK struct { - A_UINT8 keyIndex; - A_UINT8 keyType; - A_UINT8 keyUsage; /* KEY_USAGE */ - A_UINT8 keyLength; - A_UINT8 keyRSC[8]; /* key replay sequence counter */ - A_UINT8 key[WMI_MAX_KEY_LEN]; - A_UINT8 key_op_ctrl; /* Additional Key Control information */ - A_UINT8 key_macaddr[ATH_MAC_LEN]; + u8 keyIndex; + u8 keyType; + u8 keyUsage; /* KEY_USAGE */ + u8 keyLength; + u8 keyRSC[8]; /* key replay sequence counter */ + u8 key[WMI_MAX_KEY_LEN]; + u8 key_op_ctrl; /* Additional Key Control information */ + u8 key_macaddr[ATH_MAC_LEN]; } POSTPACK WMI_ADD_CIPHER_KEY_CMD; /* * WMI_DELETE_CIPHER_KEY_CMDID */ typedef PREPACK struct { - A_UINT8 keyIndex; + u8 keyIndex; } POSTPACK WMI_DELETE_CIPHER_KEY_CMD; #define WMI_KRK_LEN 16 @@ -594,7 +594,7 @@ typedef PREPACK struct { * WMI_ADD_KRK_CMDID */ typedef PREPACK struct { - A_UINT8 krk[WMI_KRK_LEN]; + u8 krk[WMI_KRK_LEN]; } POSTPACK WMI_ADD_KRK_CMD; /* @@ -606,7 +606,7 @@ typedef enum { } WMI_TKIP_CM_CONTROL; typedef PREPACK struct { - A_UINT8 cm_en; /* WMI_TKIP_CM_CONTROL */ + u8 cm_en; /* WMI_TKIP_CM_CONTROL */ } POSTPACK WMI_SET_TKIP_COUNTERMEASURES_CMD; /* @@ -621,9 +621,9 @@ typedef enum { } PMKID_ENABLE_FLG; typedef PREPACK struct { - A_UINT8 bssid[ATH_MAC_LEN]; - A_UINT8 enable; /* PMKID_ENABLE_FLG */ - A_UINT8 pmkid[WMI_PMKID_LEN]; + u8 bssid[ATH_MAC_LEN]; + u8 enable; /* PMKID_ENABLE_FLG */ + u8 pmkid[WMI_PMKID_LEN]; } POSTPACK WMI_SET_PMKID_CMD; /* @@ -639,8 +639,8 @@ typedef PREPACK struct { u32 isLegacy; /* For Legacy Cisco AP compatibility */ A_UINT32 homeDwellTime; /* Maximum duration in the home channel(milliseconds) */ A_UINT32 forceScanInterval; /* Time interval between scans (milliseconds)*/ - A_UINT8 scanType; /* WMI_SCAN_TYPE */ - A_UINT8 numChannels; /* how many channels follow */ + u8 scanType; /* WMI_SCAN_TYPE */ + u8 numChannels; /* how many channels follow */ A_UINT16 channelList[1]; /* channels in Mhz */ } POSTPACK WMI_START_SCAN_CMD; @@ -681,8 +681,8 @@ typedef PREPACK struct { A_UINT16 bg_period; /* seconds */ A_UINT16 maxact_chdwell_time; /* msec */ A_UINT16 pas_chdwell_time; /* msec */ - A_UINT8 shortScanRatio; /* how many shorts scan for one long */ - A_UINT8 scanCtrlFlags; + u8 shortScanRatio; /* how many shorts scan for one long */ + u8 scanCtrlFlags; A_UINT16 minact_chdwell_time; /* msec */ A_UINT16 maxact_scan_per_ssid; /* max active scans per ssid */ A_UINT32 max_dfsch_act_time; /* msecs */ @@ -703,8 +703,8 @@ typedef enum { } WMI_BSS_FILTER; typedef PREPACK struct { - A_UINT8 bssFilter; /* see WMI_BSS_FILTER */ - A_UINT8 reserved1; /* For alignment */ + u8 bssFilter; /* see WMI_BSS_FILTER */ + u8 reserved1; /* For alignment */ A_UINT16 reserved2; /* For alignment */ A_UINT32 ieMask; } POSTPACK WMI_BSS_FILTER_CMD; @@ -721,10 +721,10 @@ typedef enum { } WMI_SSID_FLAG; typedef PREPACK struct { - A_UINT8 entryIndex; /* 0 to MAX_PROBED_SSID_INDEX */ - A_UINT8 flag; /* WMI_SSID_FLG */ - A_UINT8 ssidLength; - A_UINT8 ssid[32]; + u8 entryIndex; /* 0 to MAX_PROBED_SSID_INDEX */ + u8 flag; /* WMI_SSID_FLG */ + u8 ssidLength; + u8 ssid[32]; } POSTPACK WMI_PROBED_SSID_CMD; /* @@ -772,7 +772,7 @@ typedef enum { } WMI_POWER_MODE; typedef PREPACK struct { - A_UINT8 powerMode; /* WMI_POWER_MODE */ + u8 powerMode; /* WMI_POWER_MODE */ } POSTPACK WMI_POWER_MODE_CMD; typedef PREPACK struct { @@ -786,11 +786,11 @@ typedef PREPACK struct { } POSTPACK WMI_SET_PARAMS_CMD; typedef PREPACK struct { - A_UINT8 multicast_mac[ATH_MAC_LEN]; /* WMI_SET_MCAST_FILTER */ + u8 multicast_mac[ATH_MAC_LEN]; /* WMI_SET_MCAST_FILTER */ } POSTPACK WMI_SET_MCAST_FILTER_CMD; typedef PREPACK struct { - A_UINT8 enable; /* WMI_MCAST_FILTER */ + u8 enable; /* WMI_MCAST_FILTER */ } POSTPACK WMI_MCAST_FILTER_CMD; /* @@ -836,8 +836,8 @@ typedef enum { } WMI_ADHOC_PS_TYPE; typedef PREPACK struct { - A_UINT8 power_saving; - A_UINT8 ttl; /* number of beacon periods */ + u8 power_saving; + u8 ttl; /* number of beacon periods */ A_UINT16 atim_windows; /* msec */ A_UINT16 timeout_value; /* msec */ } POSTPACK WMI_IBSS_PM_CAPS_CMD; @@ -851,8 +851,8 @@ typedef enum { typedef PREPACK struct { A_UINT32 idle_time; /* in msec */ A_UINT32 ps_period; /* in usec */ - A_UINT8 sleep_period; /* in ps periods */ - A_UINT8 psType; + u8 sleep_period; /* in ps periods */ + u8 psType; } POSTPACK WMI_AP_PS_CMD; /* @@ -890,14 +890,14 @@ typedef enum { } APSD_SP_LEN_TYPE; typedef PREPACK struct { - A_UINT8 maxSPLen; + u8 maxSPLen; } POSTPACK WMI_SET_MAX_SP_LEN_CMD; /* * WMI_SET_DISC_TIMEOUT_CMDID */ typedef PREPACK struct { - A_UINT8 disconnectTimeout; /* seconds */ + u8 disconnectTimeout; /* seconds */ } POSTPACK WMI_DISC_TIMEOUT_CMD; typedef enum { @@ -921,7 +921,7 @@ typedef enum { * WMI_SYNCHRONIZE_CMDID */ typedef PREPACK struct { - A_UINT8 dataSyncMap; + u8 dataSyncMap; } POSTPACK WMI_SYNC_CMD; /* @@ -943,25 +943,25 @@ typedef PREPACK struct { A_UINT32 mediumTime; A_UINT16 nominalMSDU; /* in octects */ A_UINT16 maxMSDU; /* in octects */ - A_UINT8 trafficClass; - A_UINT8 trafficDirection; /* DIR_TYPE */ - A_UINT8 rxQueueNum; - A_UINT8 trafficType; /* TRAFFIC_TYPE */ - A_UINT8 voicePSCapability; /* VOICEPS_CAP_TYPE */ - A_UINT8 tsid; - A_UINT8 userPriority; /* 802.1D user priority */ - A_UINT8 nominalPHY; /* nominal phy rate */ + u8 trafficClass; + u8 trafficDirection; /* DIR_TYPE */ + u8 rxQueueNum; + u8 trafficType; /* TRAFFIC_TYPE */ + u8 voicePSCapability; /* VOICEPS_CAP_TYPE */ + u8 tsid; + u8 userPriority; /* 802.1D user priority */ + u8 nominalPHY; /* nominal phy rate */ } POSTPACK WMI_CREATE_PSTREAM_CMD; /* * WMI_DELETE_PSTREAM_CMDID */ typedef PREPACK struct { - A_UINT8 txQueueNumber; - A_UINT8 rxQueueNumber; - A_UINT8 trafficDirection; - A_UINT8 trafficClass; - A_UINT8 tsid; + u8 txQueueNumber; + u8 rxQueueNumber; + u8 trafficDirection; + u8 trafficClass; + u8 tsid; } POSTPACK WMI_DELETE_PSTREAM_CMD; /* @@ -978,10 +978,10 @@ typedef enum { #define WMI_MAX_CHANNELS 32 typedef PREPACK struct { - A_UINT8 reserved1; - A_UINT8 scanParam; /* set if enable scan */ - A_UINT8 phyMode; /* see WMI_PHY_MODE */ - A_UINT8 numChannels; /* how many channels follow */ + u8 reserved1; + u8 scanParam; /* set if enable scan */ + u8 phyMode; /* see WMI_PHY_MODE */ + u8 numChannels; /* how many channels follow */ A_UINT16 channelList[1]; /* channels in Mhz */ } POSTPACK WMI_CHANNEL_PARAMS_CMD; @@ -1008,8 +1008,8 @@ typedef PREPACK struct WMI_RSSI_THRESHOLD_PARAMS{ A_INT16 thresholdBelow4_Val; A_INT16 thresholdBelow5_Val; A_INT16 thresholdBelow6_Val; /* highest of bellow */ - A_UINT8 weight; /* "alpha" */ - A_UINT8 reserved[3]; + u8 weight; /* "alpha" */ + u8 reserved[3]; } POSTPACK WMI_RSSI_THRESHOLD_PARAMS_CMD; /* @@ -1019,32 +1019,32 @@ typedef PREPACK struct WMI_RSSI_THRESHOLD_PARAMS{ typedef PREPACK struct WMI_SNR_THRESHOLD_PARAMS{ A_UINT32 pollTime; /* Polling time as a factor of LI */ - A_UINT8 weight; /* "alpha" */ - A_UINT8 thresholdAbove1_Val; /* lowest of uppper*/ - A_UINT8 thresholdAbove2_Val; - A_UINT8 thresholdAbove3_Val; - A_UINT8 thresholdAbove4_Val; /* highest of upper */ - A_UINT8 thresholdBelow1_Val; /* lowest of bellow */ - A_UINT8 thresholdBelow2_Val; - A_UINT8 thresholdBelow3_Val; - A_UINT8 thresholdBelow4_Val; /* highest of bellow */ - A_UINT8 reserved[3]; + u8 weight; /* "alpha" */ + u8 thresholdAbove1_Val; /* lowest of uppper*/ + u8 thresholdAbove2_Val; + u8 thresholdAbove3_Val; + u8 thresholdAbove4_Val; /* highest of upper */ + u8 thresholdBelow1_Val; /* lowest of bellow */ + u8 thresholdBelow2_Val; + u8 thresholdBelow3_Val; + u8 thresholdBelow4_Val; /* highest of bellow */ + u8 reserved[3]; } POSTPACK WMI_SNR_THRESHOLD_PARAMS_CMD; /* * WMI_LQ_THRESHOLD_PARAMS_CMDID */ typedef PREPACK struct WMI_LQ_THRESHOLD_PARAMS { - A_UINT8 enable; - A_UINT8 thresholdAbove1_Val; - A_UINT8 thresholdAbove2_Val; - A_UINT8 thresholdAbove3_Val; - A_UINT8 thresholdAbove4_Val; - A_UINT8 thresholdBelow1_Val; - A_UINT8 thresholdBelow2_Val; - A_UINT8 thresholdBelow3_Val; - A_UINT8 thresholdBelow4_Val; - A_UINT8 reserved[3]; + u8 enable; + u8 thresholdAbove1_Val; + u8 thresholdAbove2_Val; + u8 thresholdAbove3_Val; + u8 thresholdAbove4_Val; + u8 thresholdBelow1_Val; + u8 thresholdBelow2_Val; + u8 thresholdBelow3_Val; + u8 thresholdBelow4_Val; + u8 reserved[3]; } POSTPACK WMI_LQ_THRESHOLD_PARAMS_CMD; typedef enum { @@ -1058,8 +1058,8 @@ typedef enum { } WMI_PREAMBLE_POLICY; typedef PREPACK struct { - A_UINT8 status; - A_UINT8 preamblePolicy; + u8 status; + u8 preamblePolicy; }POSTPACK WMI_SET_LPREAMBLE_CMD; typedef PREPACK struct { @@ -1080,7 +1080,7 @@ typedef PREPACK struct { * WMI_SET_TX_PWR_CMDID */ typedef PREPACK struct { - A_UINT8 dbM; /* in dbM units */ + u8 dbM; /* in dbM units */ } POSTPACK WMI_SET_TX_PWR_CMD, WMI_TX_PWR_REPLY; /* @@ -1095,9 +1095,9 @@ typedef PREPACK struct { #define WMI_MAX_ASSOC_INFO_LEN 240 typedef PREPACK struct { - A_UINT8 ieType; - A_UINT8 bufferSize; - A_UINT8 assocInfo[1]; /* up to WMI_MAX_ASSOC_INFO_LEN */ + u8 ieType; + u8 bufferSize; + u8 assocInfo[1]; /* up to WMI_MAX_ASSOC_INFO_LEN */ } POSTPACK WMI_SET_ASSOC_INFO_CMD; @@ -1111,15 +1111,15 @@ typedef PREPACK struct { #define WMI_MAX_BAD_AP_INDEX 1 typedef PREPACK struct { - A_UINT8 badApIndex; /* 0 to WMI_MAX_BAD_AP_INDEX */ - A_UINT8 bssid[ATH_MAC_LEN]; + u8 badApIndex; /* 0 to WMI_MAX_BAD_AP_INDEX */ + u8 bssid[ATH_MAC_LEN]; } POSTPACK WMI_ADD_BAD_AP_CMD; /* * WMI_DELETE_BAD_AP_CMDID */ typedef PREPACK struct { - A_UINT8 badApIndex; /* 0 to WMI_MAX_BAD_AP_INDEX */ + u8 badApIndex; /* 0 to WMI_MAX_BAD_AP_INDEX */ } POSTPACK WMI_DELETE_BAD_AP_CMD; /* @@ -1133,10 +1133,10 @@ typedef PREPACK struct { #define WMI_MAX_AIFSN_ACPARAM 15 typedef PREPACK struct { A_UINT16 txop; /* in units of 32 usec */ - A_UINT8 eCWmin; - A_UINT8 eCWmax; - A_UINT8 aifsn; - A_UINT8 ac; + u8 eCWmin; + u8 eCWmax; + u8 aifsn; + u8 ac; } POSTPACK WMI_SET_ACCESS_PARAMS_CMD; @@ -1155,10 +1155,10 @@ typedef enum { } WMI_FRAMETYPE; typedef PREPACK struct { - A_UINT8 frameType; /* WMI_FRAMETYPE */ - A_UINT8 trafficClass; /* applies only to DATA_FRAMETYPE */ - A_UINT8 maxRetries; - A_UINT8 enableNotify; + u8 frameType; /* WMI_FRAMETYPE */ + u8 trafficClass; /* applies only to DATA_FRAMETYPE */ + u8 maxRetries; + u8 enableNotify; } POSTPACK WMI_SET_RETRY_LIMITS_CMD; /* @@ -1198,12 +1198,12 @@ typedef enum { */ typedef PREPACK struct { - A_UINT8 bssid[ATH_MAC_LEN]; + u8 bssid[ATH_MAC_LEN]; A_INT8 bias; } POSTPACK WMI_BSS_BIAS; typedef PREPACK struct { - A_UINT8 numBss; + u8 numBss; WMI_BSS_BIAS bssBias[1]; } POSTPACK WMI_BSS_BIAS_INFO; @@ -1211,18 +1211,18 @@ typedef PREPACK struct WMI_LOWRSSI_SCAN_PARAMS { A_UINT16 lowrssi_scan_period; A_INT16 lowrssi_scan_threshold; A_INT16 lowrssi_roam_threshold; - A_UINT8 roam_rssi_floor; - A_UINT8 reserved[1]; /* For alignment */ + u8 roam_rssi_floor; + u8 reserved[1]; /* For alignment */ } POSTPACK WMI_LOWRSSI_SCAN_PARAMS; typedef PREPACK struct { PREPACK union { - A_UINT8 bssid[ATH_MAC_LEN]; /* WMI_FORCE_ROAM */ - A_UINT8 roamMode; /* WMI_SET_ROAM_MODE */ + u8 bssid[ATH_MAC_LEN]; /* WMI_FORCE_ROAM */ + u8 roamMode; /* WMI_SET_ROAM_MODE */ WMI_BSS_BIAS_INFO bssBiasInfo; /* WMI_SET_HOST_BIAS */ WMI_LOWRSSI_SCAN_PARAMS lrScanParams; } POSTPACK info; - A_UINT8 roamCtrlType ; + u8 roamCtrlType ; } POSTPACK WMI_SET_ROAM_CTRL_CMD; /* @@ -1234,7 +1234,7 @@ typedef enum { } BT_WLAN_CONN_PRECEDENCE; typedef PREPACK struct { - A_UINT8 precedence; + u8 precedence; } POSTPACK WMI_SET_BT_WLAN_CONN_PRECEDENCE; /* @@ -1248,12 +1248,12 @@ typedef PREPACK struct { * WMI_SET_MAX_OFFHOME_DURATION_CMDID */ typedef PREPACK struct { - A_UINT8 max_offhome_duration; + u8 max_offhome_duration; } POSTPACK WMI_SET_MAX_OFFHOME_DURATION_CMD; typedef PREPACK struct { A_UINT32 frequency; - A_UINT8 threshold; + u8 threshold; } POSTPACK WMI_SET_HB_CHALLENGE_RESP_PARAMS_CMD; /*---------------------- BTCOEX RELATED -------------------------------------*/ /*----------------------COMMON to AR6002 and AR6003 -------------------------*/ @@ -1286,8 +1286,8 @@ typedef enum { } BT_STREAM_STATUS; typedef PREPACK struct { - A_UINT8 streamType; - A_UINT8 status; + u8 streamType; + u8 status; } POSTPACK WMI_SET_BT_STATUS_CMD; typedef enum { @@ -1346,23 +1346,23 @@ typedef PREPACK struct { 16..23 Low Data Rate Max Cnt */ - A_UINT8 stompDutyCyleVal; /* Sco cycles to limit ps-poll queuing + u8 stompDutyCyleVal; /* Sco cycles to limit ps-poll queuing if stomped */ - A_UINT8 stompDutyCyleMaxVal; /*firm ware increases stomp duty cycle + u8 stompDutyCyleMaxVal; /*firm ware increases stomp duty cycle gradually uptill this value on need basis*/ - A_UINT8 psPollLatencyFraction; /* Fraction of idle + u8 psPollLatencyFraction; /* Fraction of idle period, within which additional ps-polls can be queued */ - A_UINT8 noSCOSlots; /* Number of SCO Tx/Rx slots. + u8 noSCOSlots; /* Number of SCO Tx/Rx slots. HVx, EV3, 2EV3 = 2 */ - A_UINT8 noIdleSlots; /* Number of Bluetooth idle slots between + u8 noIdleSlots; /* Number of Bluetooth idle slots between consecutive SCO Tx/Rx slots HVx, EV3 = 4 2EV3 = 10 */ - A_UINT8 scoOptOffRssi;/*RSSI value below which we go to ps poll*/ - A_UINT8 scoOptOnRssi; /*RSSI value above which we reenter opt mode*/ - A_UINT8 scoOptRtsCount; + u8 scoOptOffRssi;/*RSSI value below which we go to ps poll*/ + u8 scoOptOnRssi; /*RSSI value above which we reenter opt mode*/ + u8 scoOptRtsCount; } POSTPACK BT_PARAMS_SCO; #define BT_A2DP_ALLOW_CLOSE_RANGE_OPT (1 << 0) @@ -1393,10 +1393,10 @@ typedef PREPACK struct { 8..15 Low Data Rate Min Cnt 16..23 Low Data Rate Max Cnt */ - A_UINT8 isCoLocatedBtRoleMaster; - A_UINT8 a2dpOptOffRssi;/*RSSI value below which we go to ps poll*/ - A_UINT8 a2dpOptOnRssi; /*RSSI value above which we reenter opt mode*/ - A_UINT8 a2dpOptRtsCount; + u8 isCoLocatedBtRoleMaster; + u8 a2dpOptOffRssi;/*RSSI value below which we go to ps poll*/ + u8 a2dpOptOnRssi; /*RSSI value above which we reenter opt mode*/ + u8 a2dpOptRtsCount; }POSTPACK BT_PARAMS_A2DP; /* During BT ftp/ BT OPP or any another data based acl profile on bluetooth @@ -1419,16 +1419,16 @@ typedef PREPACK struct { BT_PARAMS_SCO scoParams; BT_PARAMS_A2DP a2dpParams; BT_PARAMS_ACLCOEX aclCoexParams; - A_UINT8 antType; /* 0 -Disabled (default) + u8 antType; /* 0 -Disabled (default) 1 - BT_ANT_TYPE_DUAL 2 - BT_ANT_TYPE_SPLITTER 3 - BT_ANT_TYPE_SWITCH */ - A_UINT8 coLocatedBtDev; /* 0 - BT_COLOCATED_DEV_BTS4020 (default) + u8 coLocatedBtDev; /* 0 - BT_COLOCATED_DEV_BTS4020 (default) 1 - BT_COLCATED_DEV_CSR 2 - BT_COLOCATED_DEV_VALKYRIe */ } POSTPACK info; - A_UINT8 paramType ; + u8 paramType ; } POSTPACK WMI_SET_BT_PARAMS_CMD; /************************ END AR6002 BTCOEX *******************************/ @@ -1448,7 +1448,7 @@ typedef enum { }WMI_BTCOEX_FE_ANT_TYPE; typedef PREPACK struct { - A_UINT8 btcoexFeAntType; /* 1 - WMI_BTCOEX_FE_ANT_SINGLE for single antenna front end + u8 btcoexFeAntType; /* 1 - WMI_BTCOEX_FE_ANT_SINGLE for single antenna front end 2 - WMI_BTCOEX_FE_ANT_DUAL for dual antenna front end (for isolations less 35dB, for higher isolation there is not need to pass this command). @@ -1461,7 +1461,7 @@ typedef PREPACK struct { * bluetooth chip type.Based on bluetooth device, different coexistence protocol would be used. */ typedef PREPACK struct { - A_UINT8 btcoexCoLocatedBTdev; /*1 - Qcom BT (3 -wire PTA) + u8 btcoexCoLocatedBTdev; /*1 - Qcom BT (3 -wire PTA) 2 - CSR BT (3 wire PTA) 3 - Atheros 3001 BT (3 wire PTA) 4 - STE bluetooth (4-wire ePTA) @@ -1867,7 +1867,7 @@ typedef PREPACK struct { typedef PREPACK struct { A_UINT16 cmd_buf_sz; /* HCI cmd buffer size */ - A_UINT8 buf[1]; /* Absolute HCI cmd */ + u8 buf[1]; /* Absolute HCI cmd */ } POSTPACK WMI_HCI_CMD; /* @@ -1878,8 +1878,8 @@ typedef PREPACK struct { * WMI_GET_CHANNEL_LIST_CMDID reply */ typedef PREPACK struct { - A_UINT8 reserved1; - A_UINT8 numChannels; /* number of channels in reply */ + u8 reserved1; + u8 numChannels; /* number of channels in reply */ A_UINT16 channelList[1]; /* channel in Mhz */ } POSTPACK WMI_CHANNEL_LIST_REPLY; @@ -1893,19 +1893,19 @@ typedef enum { } PSTREAM_REPLY_STATUS; typedef PREPACK struct { - A_UINT8 status; /* PSTREAM_REPLY_STATUS */ - A_UINT8 txQueueNumber; - A_UINT8 rxQueueNumber; - A_UINT8 trafficClass; - A_UINT8 trafficDirection; /* DIR_TYPE */ + u8 status; /* PSTREAM_REPLY_STATUS */ + u8 txQueueNumber; + u8 rxQueueNumber; + u8 trafficClass; + u8 trafficDirection; /* DIR_TYPE */ } POSTPACK WMI_CRE_PRIORITY_STREAM_REPLY; typedef PREPACK struct { - A_UINT8 status; /* PSTREAM_REPLY_STATUS */ - A_UINT8 txQueueNumber; - A_UINT8 rxQueueNumber; - A_UINT8 trafficDirection; /* DIR_TYPE */ - A_UINT8 trafficClass; + u8 status; /* PSTREAM_REPLY_STATUS */ + u8 txQueueNumber; + u8 rxQueueNumber; + u8 trafficDirection; /* DIR_TYPE */ + u8 trafficClass; } POSTPACK WMI_DEL_PRIORITY_STREAM_REPLY; /* @@ -1976,15 +1976,15 @@ typedef enum { } WMI_PHY_CAPABILITY; typedef PREPACK struct { - A_UINT8 macaddr[ATH_MAC_LEN]; - A_UINT8 phyCapability; /* WMI_PHY_CAPABILITY */ + u8 macaddr[ATH_MAC_LEN]; + u8 phyCapability; /* WMI_PHY_CAPABILITY */ } POSTPACK WMI_READY_EVENT_1; typedef PREPACK struct { A_UINT32 sw_version; A_UINT32 abi_version; - A_UINT8 macaddr[ATH_MAC_LEN]; - A_UINT8 phyCapability; /* WMI_PHY_CAPABILITY */ + u8 macaddr[ATH_MAC_LEN]; + u8 phyCapability; /* WMI_PHY_CAPABILITY */ } POSTPACK WMI_READY_EVENT_2; #if defined(ATH_TARGET) @@ -2003,14 +2003,14 @@ typedef PREPACK struct { */ typedef PREPACK struct { A_UINT16 channel; - A_UINT8 bssid[ATH_MAC_LEN]; + u8 bssid[ATH_MAC_LEN]; A_UINT16 listenInterval; A_UINT16 beaconInterval; A_UINT32 networkType; - A_UINT8 beaconIeLen; - A_UINT8 assocReqLen; - A_UINT8 assocRespLen; - A_UINT8 assocInfo[1]; + u8 beaconIeLen; + u8 assocReqLen; + u8 assocRespLen; + u8 assocInfo[1]; } POSTPACK WMI_CONNECT_EVENT; /* @@ -2034,10 +2034,10 @@ typedef enum { typedef PREPACK struct { A_UINT16 protocolReasonStatus; /* reason code, see 802.11 spec. */ - A_UINT8 bssid[ATH_MAC_LEN]; /* set if known */ - A_UINT8 disconnectReason ; /* see WMI_DISCONNECT_REASON */ - A_UINT8 assocRespLen; - A_UINT8 assocInfo[1]; + u8 bssid[ATH_MAC_LEN]; /* set if known */ + u8 disconnectReason ; /* see WMI_DISCONNECT_REASON */ + u8 assocRespLen; + u8 assocInfo[1]; } POSTPACK WMI_DISCONNECT_EVENT; /* @@ -2060,10 +2060,10 @@ enum { typedef PREPACK struct { A_UINT16 channel; - A_UINT8 frameType; /* see WMI_BI_FTYPE */ - A_UINT8 snr; + u8 frameType; /* see WMI_BI_FTYPE */ + u8 snr; A_INT16 rssi; - A_UINT8 bssid[ATH_MAC_LEN]; + u8 bssid[ATH_MAC_LEN]; A_UINT32 ieMask; } POSTPACK WMI_BSS_INFO_HDR; @@ -2077,9 +2077,9 @@ typedef PREPACK struct { */ typedef PREPACK struct { A_UINT16 channel; - A_UINT8 frameType; /* see WMI_BI_FTYPE */ - A_UINT8 snr; - A_UINT8 bssid[ATH_MAC_LEN]; + u8 frameType; /* see WMI_BI_FTYPE */ + u8 snr; + u8 bssid[ATH_MAC_LEN]; A_UINT16 ieMask; } POSTPACK WMI_BSS_INFO_HDR2; @@ -2094,7 +2094,7 @@ typedef enum { typedef PREPACK struct { A_UINT16 commandId; - A_UINT8 errorCode; + u8 errorCode; } POSTPACK WMI_CMD_ERROR_EVENT; /* @@ -2105,17 +2105,17 @@ typedef PREPACK struct { } POSTPACK WMI_REG_DOMAIN_EVENT; typedef PREPACK struct { - A_UINT8 txQueueNumber; - A_UINT8 rxQueueNumber; - A_UINT8 trafficDirection; - A_UINT8 trafficClass; + u8 txQueueNumber; + u8 rxQueueNumber; + u8 trafficDirection; + u8 trafficClass; } POSTPACK WMI_PSTREAM_TIMEOUT_EVENT; typedef PREPACK struct { - A_UINT8 reserve1; - A_UINT8 reserve2; - A_UINT8 reserve3; - A_UINT8 trafficClass; + u8 reserve1; + u8 reserve2; + u8 reserve3; + u8 trafficClass; } POSTPACK WMI_ACM_REJECT_EVENT; /* @@ -2134,8 +2134,8 @@ typedef enum { } WMI_BSS_FLAGS; typedef PREPACK struct { - A_UINT8 bssid[ATH_MAC_LEN]; - A_UINT8 bssFlags; /* see WMI_BSS_FLAGS */ + u8 bssid[ATH_MAC_LEN]; + u8 bssFlags; /* see WMI_BSS_FLAGS */ } POSTPACK WMI_NEIGHBOR_INFO; typedef PREPACK struct { @@ -2147,8 +2147,8 @@ typedef PREPACK struct { * TKIP MIC Error Event */ typedef PREPACK struct { - A_UINT8 keyid; - A_UINT8 ismcast; + u8 keyid; + u8 ismcast; } POSTPACK WMI_TKIP_MICERR_EVENT; /* @@ -2164,7 +2164,7 @@ typedef PREPACK struct { * WMI_SET_ADHOC_BSSID_CMDID */ typedef PREPACK struct { - A_UINT8 bssid[ATH_MAC_LEN]; + u8 bssid[ATH_MAC_LEN]; } POSTPACK WMI_SET_ADHOC_BSSID_CMD; /* @@ -2176,7 +2176,7 @@ typedef enum { } OPT_MODE_TYPE; typedef PREPACK struct { - A_UINT8 optMode; + u8 optMode; } POSTPACK WMI_SET_OPT_MODE_CMD; /* @@ -2191,11 +2191,11 @@ typedef enum { typedef PREPACK struct { A_UINT16 optIEDataLen; - A_UINT8 frmType; - A_UINT8 dstAddr[ATH_MAC_LEN]; - A_UINT8 bssid[ATH_MAC_LEN]; - A_UINT8 reserved; /* For alignment */ - A_UINT8 optIEData[1]; + u8 frmType; + u8 dstAddr[ATH_MAC_LEN]; + u8 bssid[ATH_MAC_LEN]; + u8 reserved; /* For alignment */ + u8 optIEData[1]; } POSTPACK WMI_OPT_TX_FRAME_CMD; /* @@ -2206,10 +2206,10 @@ typedef PREPACK struct { */ typedef PREPACK struct { A_UINT16 channel; - A_UINT8 frameType; /* see WMI_OPT_FTYPE */ + u8 frameType; /* see WMI_OPT_FTYPE */ A_INT8 snr; - A_UINT8 srcAddr[ATH_MAC_LEN]; - A_UINT8 bssid[ATH_MAC_LEN]; + u8 srcAddr[ATH_MAC_LEN]; + u8 bssid[ATH_MAC_LEN]; } POSTPACK WMI_OPT_RX_INFO_HDR; /* @@ -2280,9 +2280,9 @@ typedef PREPACK struct { A_INT16 cs_aveBeacon_rssi; A_UINT16 cs_roam_count; A_INT16 cs_rssi; - A_UINT8 cs_snr; - A_UINT8 cs_aveBeacon_snr; - A_UINT8 cs_lastRoam_msec; + u8 cs_snr; + u8 cs_aveBeacon_snr; + u8 cs_lastRoam_msec; } POSTPACK cserv_stats_t; typedef PREPACK struct { @@ -2300,8 +2300,8 @@ typedef PREPACK struct { typedef PREPACK struct { A_UINT32 wow_num_pkts_dropped; A_UINT16 wow_num_events_discarded; - A_UINT8 wow_num_host_pkt_wakeups; - A_UINT8 wow_num_host_event_wakeups; + u8 wow_num_host_pkt_wakeups; + u8 wow_num_host_event_wakeups; } POSTPACK wlan_wow_stats_t; typedef PREPACK struct { @@ -2336,7 +2336,7 @@ typedef enum{ typedef PREPACK struct { A_INT16 rssi; - A_UINT8 range; + u8 range; }POSTPACK WMI_RSSI_THRESHOLD_EVENT; /* @@ -2357,7 +2357,7 @@ typedef PREPACK struct { }POSTPACK WMI_TARGET_ERROR_REPORT_EVENT; typedef PREPACK struct { - A_UINT8 retrys; + u8 retrys; }POSTPACK WMI_TX_RETRY_ERR_EVENT; typedef enum{ @@ -2372,8 +2372,8 @@ typedef enum{ } WMI_SNR_THRESHOLD_VAL; typedef PREPACK struct { - A_UINT8 range; /* WMI_SNR_THRESHOLD_VAL */ - A_UINT8 snr; + u8 range; /* WMI_SNR_THRESHOLD_VAL */ + u8 snr; }POSTPACK WMI_SNR_THRESHOLD_EVENT; typedef enum{ @@ -2389,7 +2389,7 @@ typedef enum{ typedef PREPACK struct { A_INT32 lq; - A_UINT8 range; /* WMI_LQ_THRESHOLD_VAL */ + u8 range; /* WMI_LQ_THRESHOLD_VAL */ }POSTPACK WMI_LQ_THRESHOLD_EVENT; /* * WMI_REPORT_ROAM_TBL_EVENTID @@ -2398,13 +2398,13 @@ typedef PREPACK struct { typedef PREPACK struct { A_INT32 roam_util; - A_UINT8 bssid[ATH_MAC_LEN]; + u8 bssid[ATH_MAC_LEN]; A_INT8 rssi; A_INT8 rssidt; A_INT8 last_rssi; A_INT8 util; A_INT8 bias; - A_UINT8 reserved; /* For alignment */ + u8 reserved; /* For alignment */ } POSTPACK WMI_BSS_ROAM_INFO; @@ -2419,7 +2419,7 @@ typedef PREPACK struct { */ typedef PREPACK struct { A_UINT16 evt_buf_sz; /* HCI event buffer size */ - A_UINT8 buf[1]; /* HCI event */ + u8 buf[1]; /* HCI event */ } POSTPACK WMI_HCI_EVENT; /* @@ -2435,10 +2435,10 @@ typedef enum { #define WMM_TSPEC_IE_LEN 63 typedef PREPACK struct { - A_UINT8 ac; - A_UINT8 cac_indication; - A_UINT8 statusCode; - A_UINT8 tspecSuggestion[WMM_TSPEC_IE_LEN]; + u8 ac; + u8 cac_indication; + u8 statusCode; + u8 tspecSuggestion[WMM_TSPEC_IE_LEN]; }POSTPACK WMI_CAC_EVENT; /* @@ -2450,7 +2450,7 @@ typedef enum { } APLIST_VER; typedef PREPACK struct { - A_UINT8 bssid[ATH_MAC_LEN]; + u8 bssid[ATH_MAC_LEN]; A_UINT16 channel; } POSTPACK WMI_AP_INFO_V1; @@ -2459,8 +2459,8 @@ typedef PREPACK union { } POSTPACK WMI_AP_INFO; typedef PREPACK struct { - A_UINT8 apListVer; - A_UINT8 numAP; + u8 apListVer; + u8 numAP; WMI_AP_INFO apList[1]; } POSTPACK WMI_APLIST_EVENT; @@ -2556,8 +2556,8 @@ typedef PREPACK struct { } POSTPACK WMI_FIX_RATES_CMD, WMI_FIX_RATES_REPLY; typedef PREPACK struct { - A_UINT8 bEnableMask; - A_UINT8 frameType; /*type and subtype*/ + u8 bEnableMask; + u8 frameType; /*type and subtype*/ A_UINT32 frameRateMask; /* see WMI_BIT_RATE */ } POSTPACK WMI_FRAME_RATES_CMD, WMI_FRAME_RATES_REPLY; @@ -2572,7 +2572,7 @@ typedef enum { } WMI_AUTH_MODE; typedef PREPACK struct { - A_UINT8 mode; + u8 mode; } POSTPACK WMI_SET_AUTH_MODE_CMD; /* @@ -2586,7 +2586,7 @@ typedef enum { } WMI_REASSOC_MODE; typedef PREPACK struct { - A_UINT8 mode; + u8 mode; }POSTPACK WMI_SET_REASSOC_MODE_CMD; typedef enum { @@ -2598,9 +2598,9 @@ typedef PREPACK struct { A_UINT32 no_txrx_time; A_UINT32 assoc_time; A_UINT32 allow_txrx_time; - A_UINT8 disassoc_bssid[ATH_MAC_LEN]; + u8 disassoc_bssid[ATH_MAC_LEN]; A_INT8 disassoc_bss_rssi; - A_UINT8 assoc_bssid[ATH_MAC_LEN]; + u8 assoc_bssid[ATH_MAC_LEN]; A_INT8 assoc_bss_rssi; } POSTPACK WMI_TARGET_ROAM_TIME; @@ -2608,7 +2608,7 @@ typedef PREPACK struct { PREPACK union { WMI_TARGET_ROAM_TIME roamTime; } POSTPACK u; - A_UINT8 roamDataType ; + u8 roamDataType ; } POSTPACK WMI_TARGET_ROAM_DATA; typedef enum { @@ -2617,11 +2617,11 @@ typedef enum { } WMI_WMM_STATUS; typedef PREPACK struct { - A_UINT8 status; + u8 status; }POSTPACK WMI_SET_WMM_CMD; typedef PREPACK struct { - A_UINT8 status; + u8 status; }POSTPACK WMI_SET_QOS_SUPP_CMD; typedef enum { @@ -2630,16 +2630,16 @@ typedef enum { } WMI_TXOP_CFG; typedef PREPACK struct { - A_UINT8 txopEnable; + u8 txopEnable; }POSTPACK WMI_SET_WMM_TXOP_CMD; typedef PREPACK struct { - A_UINT8 keepaliveInterval; + u8 keepaliveInterval; } POSTPACK WMI_SET_KEEPALIVE_CMD; typedef PREPACK struct { u32 configured; - A_UINT8 keepaliveInterval; + u8 keepaliveInterval; } POSTPACK WMI_GET_KEEPALIVE_CMD; /* @@ -2648,9 +2648,9 @@ typedef PREPACK struct { #define WMI_MAX_IE_LEN 255 typedef PREPACK struct { - A_UINT8 mgmtFrmType; /* one of WMI_MGMT_FRAME_TYPE */ - A_UINT8 ieLen; /* Length of the IE that should be added to the MGMT frame */ - A_UINT8 ieInfo[1]; + u8 mgmtFrmType; /* one of WMI_MGMT_FRAME_TYPE */ + u8 ieLen; /* Length of the IE that should be added to the MGMT frame */ + u8 ieInfo[1]; } POSTPACK WMI_SET_APPIE_CMD; /* @@ -2665,12 +2665,12 @@ typedef enum { }WHAL_CMDID; typedef PREPACK struct { - A_UINT8 cabTimeOut; + u8 cabTimeOut; } POSTPACK WHAL_SETCABTO_PARAM; typedef PREPACK struct { - A_UINT8 whalCmdId; - A_UINT8 data[1]; + u8 whalCmdId; + u8 data[1]; } POSTPACK WHAL_PARAMCMD; @@ -2682,32 +2682,32 @@ typedef PREPACK struct { #define MAC_MAX_FILTERS_PER_LIST 4 typedef PREPACK struct { - A_UINT8 wow_valid_filter; - A_UINT8 wow_filter_id; - A_UINT8 wow_filter_size; - A_UINT8 wow_filter_offset; - A_UINT8 wow_filter_mask[WOW_MASK_SIZE]; - A_UINT8 wow_filter_pattern[WOW_PATTERN_SIZE]; + u8 wow_valid_filter; + u8 wow_filter_id; + u8 wow_filter_size; + u8 wow_filter_offset; + u8 wow_filter_mask[WOW_MASK_SIZE]; + u8 wow_filter_pattern[WOW_PATTERN_SIZE]; } POSTPACK WOW_FILTER; typedef PREPACK struct { - A_UINT8 wow_valid_list; - A_UINT8 wow_list_id; - A_UINT8 wow_num_filters; - A_UINT8 wow_total_list_size; + u8 wow_valid_list; + u8 wow_list_id; + u8 wow_num_filters; + u8 wow_total_list_size; WOW_FILTER list[WOW_MAX_FILTERS_PER_LIST]; } POSTPACK WOW_FILTER_LIST; typedef PREPACK struct { - A_UINT8 valid_filter; - A_UINT8 mac_addr[ATH_MAC_LEN]; + u8 valid_filter; + u8 mac_addr[ATH_MAC_LEN]; } POSTPACK MAC_FILTER; typedef PREPACK struct { - A_UINT8 total_list_size; - A_UINT8 enable; + u8 total_list_size; + u8 enable; MAC_FILTER list[MAC_MAX_FILTERS_PER_LIST]; } POSTPACK MAC_FILTER_LIST; @@ -2732,25 +2732,25 @@ typedef PREPACK struct { } POSTPACK WMI_SET_WOW_MODE_CMD; typedef PREPACK struct { - A_UINT8 filter_list_id; + u8 filter_list_id; } POSTPACK WMI_GET_WOW_LIST_CMD; /* * WMI_GET_WOW_LIST_CMD reply */ typedef PREPACK struct { - A_UINT8 num_filters; /* number of patterns in reply */ - A_UINT8 this_filter_num; /* this is filter # x of total num_filters */ - A_UINT8 wow_mode; - A_UINT8 host_mode; + u8 num_filters; /* number of patterns in reply */ + u8 this_filter_num; /* this is filter # x of total num_filters */ + u8 wow_mode; + u8 host_mode; WOW_FILTER wow_filters[1]; } POSTPACK WMI_GET_WOW_LIST_REPLY; typedef PREPACK struct { - A_UINT8 filter_list_id; - A_UINT8 filter_size; - A_UINT8 filter_offset; - A_UINT8 filter[1]; + u8 filter_list_id; + u8 filter_size; + u8 filter_offset; + u8 filter[1]; } POSTPACK WMI_ADD_WOW_PATTERN_CMD; typedef PREPACK struct { @@ -2759,7 +2759,7 @@ typedef PREPACK struct { } POSTPACK WMI_DEL_WOW_PATTERN_CMD; typedef PREPACK struct { - A_UINT8 macaddr[ATH_MAC_LEN]; + u8 macaddr[ATH_MAC_LEN]; } POSTPACK WMI_SET_MAC_ADDRESS_CMD; /* @@ -2773,7 +2773,7 @@ typedef PREPACK struct { } POSTPACK WMI_SET_AKMP_PARAMS_CMD; typedef PREPACK struct { - A_UINT8 pmkid[WMI_PMKID_LEN]; + u8 pmkid[WMI_PMKID_LEN]; } POSTPACK WMI_PMKID; /* @@ -2792,7 +2792,7 @@ typedef PREPACK struct { */ typedef PREPACK struct { A_UINT32 numPMKID; - A_UINT8 bssidList[ATH_MAC_LEN][1]; + u8 bssidList[ATH_MAC_LEN][1]; WMI_PMKID pmkidList[1]; } POSTPACK WMI_PMKID_LIST_REPLY; @@ -2808,16 +2808,16 @@ typedef PREPACK struct { /* WMI_ADDBA_REQ_EVENTID */ typedef PREPACK struct { - A_UINT8 tid; - A_UINT8 win_sz; + u8 tid; + u8 win_sz; A_UINT16 st_seq_no; - A_UINT8 status; /* f/w response for ADDBA Req; OK(0) or failure(!=0) */ + u8 status; /* f/w response for ADDBA Req; OK(0) or failure(!=0) */ } POSTPACK WMI_ADDBA_REQ_EVENT; /* WMI_ADDBA_RESP_EVENTID */ typedef PREPACK struct { - A_UINT8 tid; - A_UINT8 status; /* OK(0), failure (!=0) */ + u8 tid; + u8 status; /* OK(0), failure (!=0) */ A_UINT16 amsdu_sz; /* Three values: Not supported(0), 3839, 8k */ } POSTPACK WMI_ADDBA_RESP_EVENT; @@ -2826,8 +2826,8 @@ typedef PREPACK struct { * Host is notified of this */ typedef PREPACK struct { - A_UINT8 tid; - A_UINT8 is_peer_initiator; + u8 tid; + u8 is_peer_initiator; A_UINT16 reason_code; } POSTPACK WMI_DELBA_EVENT; @@ -2836,8 +2836,8 @@ typedef PREPACK struct { #define WAPI_REKEY_UCAST 1 #define WAPI_REKEY_MCAST 2 typedef PREPACK struct { - A_UINT8 type; - A_UINT8 macAddr[ATH_MAC_LEN]; + u8 type; + u8 macAddr[ATH_MAC_LEN]; } POSTPACK WMI_WAPIREKEY_EVENT; #endif @@ -2856,7 +2856,7 @@ typedef PREPACK struct { * on the given tid */ typedef PREPACK struct { - A_UINT8 tid; + u8 tid; } POSTPACK WMI_ADDBA_REQ_CMD; /* WMI_DELBA_REQ_CMDID @@ -2864,8 +2864,8 @@ typedef PREPACK struct { * is_send_initiator indicates if it's or tx or rx side */ typedef PREPACK struct { - A_UINT8 tid; - A_UINT8 is_sender_initiator; + u8 tid; + u8 is_sender_initiator; } POSTPACK WMI_DELBA_REQ_CMD; @@ -2874,8 +2874,8 @@ typedef PREPACK struct { #define PEER_FIRST_NODE_JOIN_EVENT 0x10 #define PEER_LAST_NODE_LEAVE_EVENT 0x11 typedef PREPACK struct { - A_UINT8 eventCode; - A_UINT8 peerMacAddr[ATH_MAC_LEN]; + u8 eventCode; + u8 peerMacAddr[ATH_MAC_LEN]; } POSTPACK WMI_PEER_NODE_EVENT; #define IEEE80211_FRAME_TYPE_MGT 0x00 @@ -2893,10 +2893,10 @@ typedef PREPACK struct { #define TX_COMPLETE_STATUS_TIMEOUT 3 #define TX_COMPLETE_STATUS_OTHER 4 - A_UINT8 status; /* one of TX_COMPLETE_STATUS_... */ - A_UINT8 pktID; /* packet ID to identify parent packet */ - A_UINT8 rateIdx; /* rate index on successful transmission */ - A_UINT8 ackFailures; /* number of ACK failures in tx attempt */ + u8 status; /* one of TX_COMPLETE_STATUS_... */ + u8 pktID; /* packet ID to identify parent packet */ + u8 rateIdx; /* rate index on successful transmission */ + u8 ackFailures; /* number of ACK failures in tx attempt */ #if 0 /* optional params currently ommitted. */ A_UINT32 queueDelay; // usec delay measured Tx Start time - host delivery time A_UINT32 mediaDelay; // usec delay measured ACK rx time - host delivery time @@ -2904,10 +2904,10 @@ typedef PREPACK struct { } POSTPACK TX_COMPLETE_MSG_V1; /* version 1 of tx complete msg */ typedef PREPACK struct { - A_UINT8 numMessages; /* number of tx comp msgs following this struct */ - A_UINT8 msgLen; /* length in bytes for each individual msg following this struct */ - A_UINT8 msgType; /* version of tx complete msg data following this struct */ - A_UINT8 reserved; /* individual messages follow this header */ + u8 numMessages; /* number of tx comp msgs following this struct */ + u8 msgLen; /* length in bytes for each individual msg following this struct */ + u8 msgType; /* version of tx complete msg data following this struct */ + u8 reserved; /* individual messages follow this header */ } POSTPACK WMI_TX_COMPLETE_EVENT; #define WMI_TXCOMPLETE_VERSION_1 (0x01) @@ -2946,7 +2946,7 @@ typedef PREPACK struct { #define HIDDEN_SSID_FALSE 0 #define HIDDEN_SSID_TRUE 1 typedef PREPACK struct { - A_UINT8 hidden_ssid; + u8 hidden_ssid; } POSTPACK WMI_AP_HIDDEN_SSID_CMD; /* @@ -2957,7 +2957,7 @@ typedef PREPACK struct { #define AP_ACL_DENY_MAC 0x02 #define AP_ACL_RETAIN_LIST_MASK 0x80 typedef PREPACK struct { - A_UINT8 policy; + u8 policy; } POSTPACK WMI_AP_ACL_POLICY_CMD; /* @@ -2966,33 +2966,33 @@ typedef PREPACK struct { #define ADD_MAC_ADDR 1 #define DEL_MAC_ADDR 2 typedef PREPACK struct { - A_UINT8 action; - A_UINT8 index; - A_UINT8 mac[ATH_MAC_LEN]; - A_UINT8 wildcard; + u8 action; + u8 index; + u8 mac[ATH_MAC_LEN]; + u8 wildcard; } POSTPACK WMI_AP_ACL_MAC_CMD; typedef PREPACK struct { A_UINT16 index; - A_UINT8 acl_mac[AP_ACL_SIZE][ATH_MAC_LEN]; - A_UINT8 wildcard[AP_ACL_SIZE]; - A_UINT8 policy; + u8 acl_mac[AP_ACL_SIZE][ATH_MAC_LEN]; + u8 wildcard[AP_ACL_SIZE]; + u8 policy; } POSTPACK WMI_AP_ACL; /* * Used with WMI_AP_SET_NUM_STA_CMDID */ typedef PREPACK struct { - A_UINT8 num_sta; + u8 num_sta; } POSTPACK WMI_AP_SET_NUM_STA_CMD; /* * Used with WMI_AP_SET_MLME_CMDID */ typedef PREPACK struct { - A_UINT8 mac[ATH_MAC_LEN]; + u8 mac[ATH_MAC_LEN]; A_UINT16 reason; /* 802.11 reason code */ - A_UINT8 cmd; /* operation to perform */ + u8 cmd; /* operation to perform */ #define WMI_AP_MLME_ASSOC 1 /* associate station */ #define WMI_AP_DISASSOC 2 /* disassociate station */ #define WMI_AP_DEAUTH 3 /* deauthenticate station */ @@ -3021,21 +3021,21 @@ typedef PREPACK struct { } POSTPACK WMI_AP_SET_COUNTRY_CMD; typedef PREPACK struct { - A_UINT8 dtim; + u8 dtim; } POSTPACK WMI_AP_SET_DTIM_CMD; typedef PREPACK struct { - A_UINT8 band; /* specifies which band to apply these values */ - A_UINT8 enable; /* allows 11n to be disabled on a per band basis */ - A_UINT8 chan_width_40M_supported; - A_UINT8 short_GI_20MHz; - A_UINT8 short_GI_40MHz; - A_UINT8 intolerance_40MHz; - A_UINT8 max_ampdu_len_exp; + u8 band; /* specifies which band to apply these values */ + u8 enable; /* allows 11n to be disabled on a per band basis */ + u8 chan_width_40M_supported; + u8 short_GI_20MHz; + u8 short_GI_40MHz; + u8 intolerance_40MHz; + u8 max_ampdu_len_exp; } POSTPACK WMI_SET_HT_CAP_CMD; typedef PREPACK struct { - A_UINT8 sta_chan_width; + u8 sta_chan_width; } POSTPACK WMI_SET_HT_OP_CMD; typedef PREPACK struct { @@ -3044,7 +3044,7 @@ typedef PREPACK struct { typedef PREPACK struct { A_UINT32 sgiMask; - A_UINT8 sgiPERThreshold; + u8 sgiPERThreshold; } POSTPACK WMI_SET_TX_SGI_PARAM_CMD; #define DEFAULT_SGI_MASK 0x08080000 @@ -3052,23 +3052,23 @@ typedef PREPACK struct { typedef PREPACK struct { A_UINT32 rateField; /* 1 bit per rate corresponding to index */ - A_UINT8 id; - A_UINT8 shortTrys; - A_UINT8 longTrys; - A_UINT8 reserved; /* padding */ + u8 id; + u8 shortTrys; + u8 longTrys; + u8 reserved; /* padding */ } POSTPACK WMI_SET_RATE_POLICY_CMD; typedef PREPACK struct { - A_UINT8 metaVersion; /* version of meta data for rx packets <0 = default> (0-7 = valid) */ - A_UINT8 dot11Hdr; /* 1 == leave .11 header intact , 0 == replace .11 header with .3 */ - A_UINT8 defragOnHost; /* 1 == defragmentation is performed by host, 0 == performed by target */ - A_UINT8 reserved[1]; /* alignment */ + u8 metaVersion; /* version of meta data for rx packets <0 = default> (0-7 = valid) */ + u8 dot11Hdr; /* 1 == leave .11 header intact , 0 == replace .11 header with .3 */ + u8 defragOnHost; /* 1 == defragmentation is performed by host, 0 == performed by target */ + u8 reserved[1]; /* alignment */ } POSTPACK WMI_RX_FRAME_FORMAT_CMD; typedef PREPACK struct { - A_UINT8 enable; /* 1 == device operates in thin mode , 0 == normal mode */ - A_UINT8 reserved[3]; + u8 enable; /* 1 == device operates in thin mode , 0 == normal mode */ + u8 reserved[3]; } POSTPACK WMI_SET_THIN_MODE_CMD; /* AP mode events */ @@ -3102,7 +3102,7 @@ typedef PREPACK struct { #define AP_11BG_RATESET2 2 #define DEF_AP_11BG_RATESET AP_11BG_RATESET1 typedef PREPACK struct { - A_UINT8 rateset; + u8 rateset; } POSTPACK WMI_AP_SET_11BG_RATESET_CMD; /* * End of AP mode definitions diff --git a/drivers/staging/ath6kl/include/common/wmi_thin.h b/drivers/staging/ath6kl/include/common/wmi_thin.h index 35391edd20ac..5444a0b9197b 100644 --- a/drivers/staging/ath6kl/include/common/wmi_thin.h +++ b/drivers/staging/ath6kl/include/common/wmi_thin.h @@ -101,8 +101,8 @@ typedef enum{ * disabled by default but can be enabled using this structure and the * WMI_THIN_CONFIG_CMDID. */ typedef PREPACK struct { - A_UINT8 version; /* the versioned type of messages to use or 0 to disable */ - A_UINT8 countThreshold; /* msg count threshold triggering a tx complete message */ + u8 version; /* the versioned type of messages to use or 0 to disable */ + u8 countThreshold; /* msg count threshold triggering a tx complete message */ A_UINT16 timeThreshold; /* timeout interval in MSEC triggering a tx complete message */ } POSTPACK WMI_THIN_CONFIG_TXCOMPLETE; @@ -111,8 +111,8 @@ typedef PREPACK struct { * without notification. Alternately, the MAC Header is forwarded to the host * with the failed status. */ typedef PREPACK struct { - A_UINT8 enable; /* 1 == send decrypt errors to the host, 0 == don't */ - A_UINT8 reserved[3]; /* align padding */ + u8 enable; /* 1 == send decrypt errors to the host, 0 == don't */ + u8 reserved[3]; /* align padding */ } POSTPACK WMI_THIN_CONFIG_DECRYPT_ERR; /* WMI_THIN_CONFIG_TX_MAC_RULES -- Used to configure behavior for transmitted @@ -140,7 +140,7 @@ typedef PREPACK struct { #define WMI_THIN_CFG_FILTER_RULES 0x00000008 A_UINT32 cfgField; /* combination of WMI_THIN_CFG_... describes contents of config command */ A_UINT16 length; /* length in bytes of appended sub-commands */ - A_UINT8 reserved[2]; /* align padding */ + u8 reserved[2]; /* align padding */ } POSTPACK WMI_THIN_CONFIG_CMD; /* MIB Access Identifiers tailored for Symbian. */ @@ -176,7 +176,7 @@ enum { }; typedef PREPACK struct { - A_UINT8 addr[ATH_MAC_LEN]; + u8 addr[ATH_MAC_LEN]; } POSTPACK WMI_THIN_MIB_STA_MAC; typedef PREPACK struct { @@ -184,7 +184,7 @@ typedef PREPACK struct { } POSTPACK WMI_THIN_MIB_RX_LIFE_TIME; typedef PREPACK struct { - A_UINT8 enable; //1 = on, 0 = off + u8 enable; //1 = on, 0 = off } POSTPACK WMI_THIN_MIB_CTS_TO_SELF; typedef PREPACK struct { @@ -196,8 +196,8 @@ typedef PREPACK struct { } POSTPACK WMI_THIN_MIB_RTS_THRESHOLD; typedef PREPACK struct { - A_UINT8 type; // type of frame - A_UINT8 rate; // tx rate to be used (one of WMI_BIT_RATE) + u8 type; // type of frame + u8 rate; // tx rate to be used (one of WMI_BIT_RATE) A_UINT16 length; // num bytes following this structure as the template data } POSTPACK WMI_THIN_MIB_TEMPLATE_FRAME; @@ -212,28 +212,28 @@ typedef PREPACK struct { #define IE_FILTER_TREATMENT_APPEAR 2 typedef PREPACK struct { - A_UINT8 ie; - A_UINT8 treatment; + u8 ie; + u8 treatment; } POSTPACK WMI_THIN_MIB_BEACON_FILTER_TABLE; typedef PREPACK struct { - A_UINT8 ie; - A_UINT8 treatment; - A_UINT8 oui[3]; - A_UINT8 type; + u8 ie; + u8 treatment; + u8 oui[3]; + u8 type; A_UINT16 version; } POSTPACK WMI_THIN_MIB_BEACON_FILTER_TABLE_OUI; typedef PREPACK struct { A_UINT16 numElements; - A_UINT8 entrySize; // sizeof(WMI_THIN_MIB_BEACON_FILTER_TABLE) on host cpu may be 2 may be 4 - A_UINT8 reserved; + u8 entrySize; // sizeof(WMI_THIN_MIB_BEACON_FILTER_TABLE) on host cpu may be 2 may be 4 + u8 reserved; } POSTPACK WMI_THIN_MIB_BEACON_FILTER_TABLE_HEADER; typedef PREPACK struct { A_UINT32 count; /* num beacons between deliveries */ - A_UINT8 enable; - A_UINT8 reserved[3]; + u8 enable; + u8 reserved[3]; } POSTPACK WMI_THIN_MIB_BEACON_FILTER; typedef PREPACK struct { @@ -241,10 +241,10 @@ typedef PREPACK struct { } POSTPACK WMI_THIN_MIB_BEACON_LOST_COUNT; typedef PREPACK struct { - A_UINT8 rssi; /* the low threshold which can trigger an event warning */ - A_UINT8 tolerance; /* the range above and below the threshold to prevent event flooding to the host. */ - A_UINT8 count; /* the sample count of consecutive frames necessary to trigger an event. */ - A_UINT8 reserved[1]; /* padding */ + u8 rssi; /* the low threshold which can trigger an event warning */ + u8 tolerance; /* the range above and below the threshold to prevent event flooding to the host. */ + u8 count; /* the sample count of consecutive frames necessary to trigger an event. */ + u8 reserved[1]; /* padding */ } POSTPACK WMI_THIN_MIB_RSSI_THRESHOLD; @@ -252,52 +252,52 @@ typedef PREPACK struct { A_UINT32 cap; A_UINT32 rxRateField; A_UINT32 beamForming; - A_UINT8 addr[ATH_MAC_LEN]; - A_UINT8 enable; - A_UINT8 stbc; - A_UINT8 maxAMPDU; - A_UINT8 msduSpacing; - A_UINT8 mcsFeedback; - A_UINT8 antennaSelCap; + u8 addr[ATH_MAC_LEN]; + u8 enable; + u8 stbc; + u8 maxAMPDU; + u8 msduSpacing; + u8 mcsFeedback; + u8 antennaSelCap; } POSTPACK WMI_THIN_MIB_HT_CAP; typedef PREPACK struct { A_UINT32 infoField; A_UINT32 basicRateField; - A_UINT8 protection; - A_UINT8 secondChanneloffset; - A_UINT8 channelWidth; - A_UINT8 reserved; + u8 protection; + u8 secondChanneloffset; + u8 channelWidth; + u8 reserved; } POSTPACK WMI_THIN_MIB_HT_OP; typedef PREPACK struct { #define SECOND_BEACON_PRIMARY 1 #define SECOND_BEACON_EITHER 2 #define SECOND_BEACON_SECONDARY 3 - A_UINT8 cfg; - A_UINT8 reserved[3]; /* padding */ + u8 cfg; + u8 reserved[3]; /* padding */ } POSTPACK WMI_THIN_MIB_HT_2ND_BEACON; typedef PREPACK struct { - A_UINT8 txTIDField; - A_UINT8 rxTIDField; - A_UINT8 reserved[2]; /* padding */ + u8 txTIDField; + u8 rxTIDField; + u8 reserved[2]; /* padding */ } POSTPACK WMI_THIN_MIB_HT_BLOCK_ACK; typedef PREPACK struct { - A_UINT8 enableLong; // 1 == long preamble, 0 == short preamble - A_UINT8 reserved[3]; + u8 enableLong; // 1 == long preamble, 0 == short preamble + u8 reserved[3]; } POSTPACK WMI_THIN_MIB_PREAMBLE; typedef PREPACK struct { A_UINT16 length; /* the length in bytes of the appended MIB data */ - A_UINT8 mibID; /* the ID of the MIB element being set */ - A_UINT8 reserved; /* align padding */ + u8 mibID; /* the ID of the MIB element being set */ + u8 reserved; /* align padding */ } POSTPACK WMI_THIN_SET_MIB_CMD; typedef PREPACK struct { - A_UINT8 mibID; /* the ID of the MIB element being set */ - A_UINT8 reserved[3]; /* align padding */ + u8 mibID; /* the ID of the MIB element being set */ + u8 reserved[3]; /* align padding */ } POSTPACK WMI_THIN_GET_MIB_CMD; typedef PREPACK struct { @@ -305,12 +305,12 @@ typedef PREPACK struct { A_UINT32 beaconIntval; /* TUs */ A_UINT16 atimWindow; /* TUs */ A_UINT16 channel; /* frequency in Mhz */ - A_UINT8 networkType; /* INFRA_NETWORK | ADHOC_NETWORK */ - A_UINT8 ssidLength; /* 0 - 32 */ - A_UINT8 probe; /* != 0 : issue probe req at start */ - A_UINT8 reserved; /* alignment */ + u8 networkType; /* INFRA_NETWORK | ADHOC_NETWORK */ + u8 ssidLength; /* 0 - 32 */ + u8 probe; /* != 0 : issue probe req at start */ + u8 reserved; /* alignment */ A_UCHAR ssid[WMI_MAX_SSID_LEN]; - A_UINT8 bssid[ATH_MAC_LEN]; + u8 bssid[ATH_MAC_LEN]; } POSTPACK WMI_THIN_JOIN_CMD; typedef PREPACK struct { @@ -336,8 +336,8 @@ typedef enum { }WMI_THIN_JOIN_RESULT; typedef PREPACK struct { - A_UINT8 result; /* the result of the join cmd. one of WMI_THIN_JOIN_RESULT */ - A_UINT8 reserved[3]; /* alignment */ + u8 result; /* the result of the join cmd. one of WMI_THIN_JOIN_RESULT */ + u8 reserved[3]; /* alignment */ } POSTPACK WMI_THIN_JOIN_EVENT; #ifdef __cplusplus diff --git a/drivers/staging/ath6kl/include/common/wmix.h b/drivers/staging/ath6kl/include/common/wmix.h index 87046e364bae..7dd5434136a2 100644 --- a/drivers/staging/ath6kl/include/common/wmix.h +++ b/drivers/staging/ath6kl/include/common/wmix.h @@ -139,7 +139,7 @@ typedef PREPACK struct { A_UINT32 targ_reply_fn; A_UINT32 targ_reply_arg; A_UINT32 length; - A_UINT8 buf[1]; + u8 buf[1]; } POSTPACK WMIX_DSETDATA_REPLY_CMD; diff --git a/drivers/staging/ath6kl/include/common_drv.h b/drivers/staging/ath6kl/include/common_drv.h index 8407c9f1627a..0d2902db817a 100644 --- a/drivers/staging/ath6kl/include/common_drv.h +++ b/drivers/staging/ath6kl/include/common_drv.h @@ -79,7 +79,7 @@ void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType); int ar6000_set_htc_params(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_UINT32 MboxIsrYieldValue, - A_UINT8 HtcControlBuffers); + u8 HtcControlBuffers); int ar6000_prepare_target(HIF_DEVICE *hifDevice, A_UINT32 TargetType, @@ -91,15 +91,15 @@ int ar6000_set_hci_bridge_flags(HIF_DEVICE *hifDevice, void ar6000_copy_cust_data_from_target(HIF_DEVICE *hifDevice, A_UINT32 TargetType); -A_UINT8 *ar6000_get_cust_data_buffer(A_UINT32 TargetType); +u8 *ar6000_get_cust_data_buffer(A_UINT32 TargetType); -int ar6000_setBTState(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize); +int ar6000_setBTState(void *context, u8 *pInBuf, A_UINT32 InBufSize); -int ar6000_setDevicePowerState(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize); +int ar6000_setDevicePowerState(void *context, u8 *pInBuf, A_UINT32 InBufSize); -int ar6000_setWowMode(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize); +int ar6000_setWowMode(void *context, u8 *pInBuf, A_UINT32 InBufSize); -int ar6000_setHostMode(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize); +int ar6000_setHostMode(void *context, u8 *pInBuf, A_UINT32 InBufSize); #ifdef __cplusplus } diff --git a/drivers/staging/ath6kl/include/dset_api.h b/drivers/staging/ath6kl/include/dset_api.h index c2014f2b8649..7ebc588f51c7 100644 --- a/drivers/staging/ath6kl/include/dset_api.h +++ b/drivers/staging/ath6kl/include/dset_api.h @@ -51,7 +51,7 @@ int wmi_dset_open_reply(struct wmi_t *wmip, /* Called to send a DataSet Data Reply back to the Target. */ int wmi_dset_data_reply(struct wmi_t *wmip, A_UINT32 status, - A_UINT8 *host_buf, + u8 *host_buf, A_UINT32 length, A_UINT32 targ_buf, A_UINT32 targ_reply_fn, diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h index 6a4d27007051..06ddb6883920 100644 --- a/drivers/staging/ath6kl/include/hif.h +++ b/drivers/staging/ath6kl/include/hif.h @@ -271,7 +271,7 @@ typedef struct { typedef struct _HIF_SCATTER_ITEM { - A_UINT8 *pBuffer; /* CPU accessible address of buffer */ + u8 *pBuffer; /* CPU accessible address of buffer */ int Length; /* length of transfer to/from this buffer */ void *pCallerContexts[2]; /* space for caller to insert a context associated with this item */ } HIF_SCATTER_ITEM; @@ -298,7 +298,7 @@ typedef struct _HIF_SCATTER_REQ { int ValidScatterEntries; /* number of valid entries set by caller */ HIF_SCATTER_METHOD ScatterMethod; /* scatter method handled by HIF */ void *HIFPrivate[4]; /* HIF private area */ - A_UINT8 *pScatterBounceBuffer; /* bounce buffer for upper layers to copy to/from */ + u8 *pScatterBounceBuffer; /* bounce buffer for upper layers to copy to/from */ HIF_SCATTER_ITEM ScatterList[1]; /* start of scatter list */ } HIF_SCATTER_REQ; diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h index d9d4e2e71963..9059f249856f 100644 --- a/drivers/staging/ath6kl/include/htc_api.h +++ b/drivers/staging/ath6kl/include/htc_api.h @@ -142,8 +142,8 @@ typedef struct _HTC_EP_CALLBACKS { typedef struct _HTC_SERVICE_CONNECT_REQ { HTC_SERVICE_ID ServiceID; /* service ID to connect to */ A_UINT16 ConnectionFlags; /* connection flags, see htc protocol definition */ - A_UINT8 *pMetaData; /* ptr to optional service-specific meta-data */ - A_UINT8 MetaDataLength; /* optional meta data length */ + u8 *pMetaData; /* ptr to optional service-specific meta-data */ + u8 MetaDataLength; /* optional meta data length */ HTC_EP_CALLBACKS EpCallbacks; /* endpoint callbacks */ int MaxSendQueueDepth; /* maximum depth of any send queue */ A_UINT32 LocalConnectionFlags; /* HTC flags for the host-side (local) connection */ @@ -154,12 +154,12 @@ typedef struct _HTC_SERVICE_CONNECT_REQ { /* service connection response information */ typedef struct _HTC_SERVICE_CONNECT_RESP { - A_UINT8 *pMetaData; /* caller supplied buffer to optional meta-data */ - A_UINT8 BufferLength; /* length of caller supplied buffer */ - A_UINT8 ActualLength; /* actual length of meta data */ + u8 *pMetaData; /* caller supplied buffer to optional meta-data */ + u8 BufferLength; /* length of caller supplied buffer */ + u8 ActualLength; /* actual length of meta data */ HTC_ENDPOINT_ID Endpoint; /* endpoint to communicate over */ unsigned int MaxMsgLength; /* max length of all messages over this endpoint */ - A_UINT8 ConnectRespCode; /* connect response code from target */ + u8 ConnectRespCode; /* connect response code from target */ } HTC_SERVICE_CONNECT_RESP; /* endpoint distribution structure */ diff --git a/drivers/staging/ath6kl/include/htc_packet.h b/drivers/staging/ath6kl/include/htc_packet.h index 243268c9d515..55914efd4be8 100644 --- a/drivers/staging/ath6kl/include/htc_packet.h +++ b/drivers/staging/ath6kl/include/htc_packet.h @@ -51,7 +51,7 @@ typedef A_UINT16 HTC_TX_TAG; typedef struct _HTC_TX_PACKET_INFO { HTC_TX_TAG Tag; /* tag used to selective flush packets */ int CreditsUsed; /* number of credits used for this TX packet (HTC internal) */ - A_UINT8 SendFlags; /* send flags (HTC internal) */ + u8 SendFlags; /* send flags (HTC internal) */ int SeqNo; /* internal seq no for debugging (HTC internal) */ } HTC_TX_PACKET_INFO; @@ -72,7 +72,7 @@ typedef struct _HTC_PACKET { DL_LIST ListLink; /* double link */ void *pPktContext; /* caller's per packet specific context */ - A_UINT8 *pBufferStart; /* the true buffer start , the caller can + u8 *pBufferStart; /* the true buffer start , the caller can store the real buffer start here. In receive callbacks, the HTC layer sets pBuffer to the start of the payload past the header. This @@ -85,7 +85,7 @@ typedef struct _HTC_PACKET { * points to the start of the HTC header but when returned * to the caller points to the start of the payload */ - A_UINT8 *pBuffer; /* payload start (RX/TX) */ + u8 *pBuffer; /* payload start (RX/TX) */ A_UINT32 BufferLength; /* length of buffer */ A_UINT32 ActualLength; /* actual length of payload */ HTC_ENDPOINT_ID Endpoint; /* endpoint that this packet was sent/recv'd from */ diff --git a/drivers/staging/ath6kl/include/wlan_api.h b/drivers/staging/ath6kl/include/wlan_api.h index 5114ff8bc179..bbc9b1f1982f 100644 --- a/drivers/staging/ath6kl/include/wlan_api.h +++ b/drivers/staging/ath6kl/include/wlan_api.h @@ -36,38 +36,38 @@ struct ieee80211_frame; struct ieee80211_common_ie { A_UINT16 ie_chan; - A_UINT8 *ie_tstamp; - A_UINT8 *ie_ssid; - A_UINT8 *ie_rates; - A_UINT8 *ie_xrates; - A_UINT8 *ie_country; - A_UINT8 *ie_wpa; - A_UINT8 *ie_rsn; - A_UINT8 *ie_wmm; - A_UINT8 *ie_ath; + u8 *ie_tstamp; + u8 *ie_ssid; + u8 *ie_rates; + u8 *ie_xrates; + u8 *ie_country; + u8 *ie_wpa; + u8 *ie_rsn; + u8 *ie_wmm; + u8 *ie_ath; A_UINT16 ie_capInfo; A_UINT16 ie_beaconInt; - A_UINT8 *ie_tim; - A_UINT8 *ie_chswitch; - A_UINT8 ie_erp; - A_UINT8 *ie_wsc; - A_UINT8 *ie_htcap; - A_UINT8 *ie_htop; + u8 *ie_tim; + u8 *ie_chswitch; + u8 ie_erp; + u8 *ie_wsc; + u8 *ie_htcap; + u8 *ie_htop; #ifdef WAPI_ENABLE - A_UINT8 *ie_wapi; + u8 *ie_wapi; #endif }; typedef struct bss { - A_UINT8 ni_macaddr[6]; - A_UINT8 ni_snr; + u8 ni_macaddr[6]; + u8 ni_snr; A_INT16 ni_rssi; struct bss *ni_list_next; struct bss *ni_list_prev; struct bss *ni_hash_next; struct bss *ni_hash_prev; struct ieee80211_common_ie ni_cie; - A_UINT8 *ni_buf; + u8 *ni_buf; A_UINT16 ni_framelen; struct ieee80211_node_table *ni_table; A_UINT32 ni_refcnt; @@ -85,8 +85,8 @@ typedef void wlan_node_iter_func(void *arg, bss_t *); bss_t *wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size); void wlan_node_free(bss_t *ni); void wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni, - const A_UINT8 *macaddr); -bss_t *wlan_find_node(struct ieee80211_node_table *nt, const A_UINT8 *macaddr); + const u8 *macaddr); +bss_t *wlan_find_node(struct ieee80211_node_table *nt, const u8 *macaddr); void wlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni); void wlan_free_allnodes(struct ieee80211_node_table *nt); void wlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f, @@ -96,7 +96,7 @@ void wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt); void wlan_node_table_reset(struct ieee80211_node_table *nt); void wlan_node_table_cleanup(struct ieee80211_node_table *nt); -int wlan_parse_beacon(A_UINT8 *buf, int framelen, +int wlan_parse_beacon(u8 *buf, int framelen, struct ieee80211_common_ie *cie); A_UINT16 wlan_ieee2freq(int chan); @@ -114,7 +114,7 @@ wlan_find_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid, void wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni); -bss_t *wlan_node_remove(struct ieee80211_node_table *nt, A_UINT8 *bssid); +bss_t *wlan_node_remove(struct ieee80211_node_table *nt, u8 *bssid); bss_t * wlan_find_matching_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid, diff --git a/drivers/staging/ath6kl/include/wmi_api.h b/drivers/staging/ath6kl/include/wmi_api.h index ae720a07320a..3f622100e9b0 100644 --- a/drivers/staging/ath6kl/include/wmi_api.h +++ b/drivers/staging/ath6kl/include/wmi_api.h @@ -69,9 +69,9 @@ void wmi_qos_state_init(struct wmi_t *wmip); void wmi_shutdown(struct wmi_t *wmip); HTC_ENDPOINT_ID wmi_get_control_ep(struct wmi_t * wmip); void wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid); -A_UINT16 wmi_get_mapped_qos_queue(struct wmi_t *, A_UINT8); +A_UINT16 wmi_get_mapped_qos_queue(struct wmi_t *, u8 ); int wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf); -int wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType, bool bMoreData, WMI_DATA_HDR_DATA_TYPE data_type,A_UINT8 metaVersion, void *pTxMetaS); +int wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, u8 msgType, bool bMoreData, WMI_DATA_HDR_DATA_TYPE data_type,u8 metaVersion, void *pTxMetaS); int wmi_dot3_2_dix(void *osbuf); int wmi_dot11_hdr_remove (struct wmi_t *wmip, void *osbuf); @@ -80,15 +80,15 @@ int wmi_dot11_hdr_add(struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode); int wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf); int wmi_syncpoint(struct wmi_t *wmip); int wmi_syncpoint_reset(struct wmi_t *wmip); -A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 layer2Priority, bool wmmEnabled); +u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 layer2Priority, bool wmmEnabled); -A_UINT8 wmi_determine_userPriority (A_UINT8 *pkt, A_UINT32 layer2Pri); +u8 wmi_determine_userPriority (u8 *pkt, A_UINT32 layer2Pri); int wmi_control_rx(struct wmi_t *wmip, void *osbuf); void wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg); void wmi_free_allnodes(struct wmi_t *wmip); -bss_t *wmi_find_node(struct wmi_t *wmip, const A_UINT8 *macaddr); -void wmi_free_node(struct wmi_t *wmip, const A_UINT8 *macaddr); +bss_t *wmi_find_node(struct wmi_t *wmip, const u8 *macaddr); +void wmi_free_node(struct wmi_t *wmip, const u8 *macaddr); typedef enum { @@ -107,17 +107,17 @@ int wmi_connect_cmd(struct wmi_t *wmip, DOT11_AUTH_MODE dot11AuthMode, AUTH_MODE authMode, CRYPTO_TYPE pairwiseCrypto, - A_UINT8 pairwiseCryptoLen, + u8 pairwiseCryptoLen, CRYPTO_TYPE groupCrypto, - A_UINT8 groupCryptoLen, + u8 groupCryptoLen, int ssidLength, A_UCHAR *ssid, - A_UINT8 *bssid, + u8 *bssid, A_UINT16 channel, A_UINT32 ctrl_flags); int wmi_reconnect_cmd(struct wmi_t *wmip, - A_UINT8 *bssid, + u8 *bssid, A_UINT16 channel); int wmi_disconnect_cmd(struct wmi_t *wmip); int wmi_getrev_cmd(struct wmi_t *wmip); @@ -129,36 +129,36 @@ int wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec, A_UINT16 fg_end_sec, A_UINT16 bg_sec, A_UINT16 minact_chdw_msec, A_UINT16 maxact_chdw_msec, A_UINT16 pas_chdw_msec, - A_UINT8 shScanRatio, A_UINT8 scanCtrlFlags, + u8 shScanRatio, u8 scanCtrlFlags, A_UINT32 max_dfsch_act_time, A_UINT16 maxact_scan_per_ssid); -int wmi_bssfilter_cmd(struct wmi_t *wmip, A_UINT8 filter, A_UINT32 ieMask); -int wmi_probedSsid_cmd(struct wmi_t *wmip, A_UINT8 index, A_UINT8 flag, - A_UINT8 ssidLength, A_UCHAR *ssid); +int wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, A_UINT32 ieMask); +int wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag, + u8 ssidLength, A_UCHAR *ssid); int wmi_listeninterval_cmd(struct wmi_t *wmip, A_UINT16 listenInterval, A_UINT16 listenBeacons); int wmi_bmisstime_cmd(struct wmi_t *wmip, A_UINT16 bmisstime, A_UINT16 bmissbeacons); -int wmi_associnfo_cmd(struct wmi_t *wmip, A_UINT8 ieType, - A_UINT8 ieLen, A_UINT8 *ieInfo); -int wmi_powermode_cmd(struct wmi_t *wmip, A_UINT8 powerMode); -int wmi_ibsspmcaps_cmd(struct wmi_t *wmip, A_UINT8 pmEnable, A_UINT8 ttl, +int wmi_associnfo_cmd(struct wmi_t *wmip, u8 ieType, + u8 ieLen, u8 *ieInfo); +int wmi_powermode_cmd(struct wmi_t *wmip, u8 powerMode); +int wmi_ibsspmcaps_cmd(struct wmi_t *wmip, u8 pmEnable, u8 ttl, A_UINT16 atim_windows, A_UINT16 timeout_value); -int wmi_apps_cmd(struct wmi_t *wmip, A_UINT8 psType, A_UINT32 idle_time, - A_UINT32 ps_period, A_UINT8 sleep_period); +int wmi_apps_cmd(struct wmi_t *wmip, u8 psType, A_UINT32 idle_time, + A_UINT32 ps_period, u8 sleep_period); int wmi_pmparams_cmd(struct wmi_t *wmip, A_UINT16 idlePeriod, A_UINT16 psPollNum, A_UINT16 dtimPolicy, A_UINT16 wakup_tx_policy, A_UINT16 num_tx_to_wakeup, A_UINT16 ps_fail_event_policy); -int wmi_disctimeout_cmd(struct wmi_t *wmip, A_UINT8 timeout); -int wmi_sync_cmd(struct wmi_t *wmip, A_UINT8 syncNumber); +int wmi_disctimeout_cmd(struct wmi_t *wmip, u8 timeout); +int wmi_sync_cmd(struct wmi_t *wmip, u8 syncNumber); int wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *pstream); -int wmi_delete_pstream_cmd(struct wmi_t *wmip, A_UINT8 trafficClass, A_UINT8 streamID); -int wmi_set_framerate_cmd(struct wmi_t *wmip, A_UINT8 bEnable, A_UINT8 type, A_UINT8 subType, A_UINT16 rateMask); +int wmi_delete_pstream_cmd(struct wmi_t *wmip, u8 trafficClass, u8 streamID); +int wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, A_UINT16 rateMask); int wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 dataRate, A_INT32 mgmtRate, A_INT32 ctlRate); int wmi_get_bitrate_cmd(struct wmi_t *wmip); A_INT8 wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, A_INT8 *rate_idx); int wmi_get_regDomain_cmd(struct wmi_t *wmip); int wmi_get_channelList_cmd(struct wmi_t *wmip); -int wmi_set_channelParams_cmd(struct wmi_t *wmip, A_UINT8 scanParam, +int wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam, WMI_PHY_MODE mode, A_INT8 numChan, A_UINT16 *channelList); @@ -170,7 +170,7 @@ int wmi_clr_rssi_snr(struct wmi_t *wmip); int wmi_set_lq_threshold_params(struct wmi_t *wmip, WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd); int wmi_set_rts_cmd(struct wmi_t *wmip, A_UINT16 threshold); -int wmi_set_lpreamble_cmd(struct wmi_t *wmip, A_UINT8 status, A_UINT8 preamblePolicy); +int wmi_set_lpreamble_cmd(struct wmi_t *wmip, u8 status, u8 preamblePolicy); int wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 bitmask); @@ -183,64 +183,64 @@ int wmi_config_debug_module_cmd(struct wmi_t *wmip, A_UINT16 mmask, int wmi_get_stats_cmd(struct wmi_t *wmip); -int wmi_addKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex, - CRYPTO_TYPE keyType, A_UINT8 keyUsage, - A_UINT8 keyLength,A_UINT8 *keyRSC, - A_UINT8 *keyMaterial, A_UINT8 key_op_ctrl, A_UINT8 *mac, +int wmi_addKey_cmd(struct wmi_t *wmip, u8 keyIndex, + CRYPTO_TYPE keyType, u8 keyUsage, + u8 keyLength,u8 *keyRSC, + u8 *keyMaterial, u8 key_op_ctrl, u8 *mac, WMI_SYNC_FLAG sync_flag); -int wmi_add_krk_cmd(struct wmi_t *wmip, A_UINT8 *krk); +int wmi_add_krk_cmd(struct wmi_t *wmip, u8 *krk); int wmi_delete_krk_cmd(struct wmi_t *wmip); -int wmi_deleteKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex); +int wmi_deleteKey_cmd(struct wmi_t *wmip, u8 keyIndex); int wmi_set_akmp_params_cmd(struct wmi_t *wmip, WMI_SET_AKMP_PARAMS_CMD *akmpParams); int wmi_get_pmkid_list_cmd(struct wmi_t *wmip); int wmi_set_pmkid_list_cmd(struct wmi_t *wmip, WMI_SET_PMKID_LIST_CMD *pmkInfo); int wmi_abort_scan_cmd(struct wmi_t *wmip); -int wmi_set_txPwr_cmd(struct wmi_t *wmip, A_UINT8 dbM); +int wmi_set_txPwr_cmd(struct wmi_t *wmip, u8 dbM); int wmi_get_txPwr_cmd(struct wmi_t *wmip); -int wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid); -int wmi_deleteBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex); +int wmi_addBadAp_cmd(struct wmi_t *wmip, u8 apIndex, u8 *bssid); +int wmi_deleteBadAp_cmd(struct wmi_t *wmip, u8 apIndex); int wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, bool en); -int wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId, +int wmi_setPmkid_cmd(struct wmi_t *wmip, u8 *bssid, u8 *pmkId, bool set); -int wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT8 ac, A_UINT16 txop, - A_UINT8 eCWmin, A_UINT8 eCWmax, - A_UINT8 aifsn); -int wmi_set_retry_limits_cmd(struct wmi_t *wmip, A_UINT8 frameType, - A_UINT8 trafficClass, A_UINT8 maxRetries, - A_UINT8 enableNotify); +int wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac, A_UINT16 txop, + u8 eCWmin, u8 eCWmax, + u8 aifsn); +int wmi_set_retry_limits_cmd(struct wmi_t *wmip, u8 frameType, + u8 trafficClass, u8 maxRetries, + u8 enableNotify); -void wmi_get_current_bssid(struct wmi_t *wmip, A_UINT8 *bssid); +void wmi_get_current_bssid(struct wmi_t *wmip, u8 *bssid); int wmi_get_roam_tbl_cmd(struct wmi_t *wmip); -int wmi_get_roam_data_cmd(struct wmi_t *wmip, A_UINT8 roamDataType); +int wmi_get_roam_data_cmd(struct wmi_t *wmip, u8 roamDataType); int wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p, - A_UINT8 size); + u8 size); int wmi_set_powersave_timers_cmd(struct wmi_t *wmip, WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd, - A_UINT8 size); + u8 size); -int wmi_set_opt_mode_cmd(struct wmi_t *wmip, A_UINT8 optMode); +int wmi_set_opt_mode_cmd(struct wmi_t *wmip, u8 optMode); int wmi_opt_tx_frame_cmd(struct wmi_t *wmip, - A_UINT8 frmType, - A_UINT8 *dstMacAddr, - A_UINT8 *bssid, + u8 frmType, + u8 *dstMacAddr, + u8 *bssid, A_UINT16 optIEDataLen, - A_UINT8 *optIEData); + u8 *optIEData); int wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl); int wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize); -int wmi_set_max_sp_len_cmd(struct wmi_t *wmip, A_UINT8 maxSpLen); -A_UINT8 convert_userPriority_to_trafficClass(A_UINT8 userPriority); -A_UINT8 wmi_get_power_mode_cmd(struct wmi_t *wmip); +int wmi_set_max_sp_len_cmd(struct wmi_t *wmip, u8 maxSpLen); +u8 convert_userPriority_to_trafficClass(u8 userPriority); +u8 wmi_get_power_mode_cmd(struct wmi_t *wmip); int wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance); #ifdef CONFIG_HOST_TCMD_SUPPORT -int wmi_test_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT32 len); +int wmi_test_cmd(struct wmi_t *wmip, u8 *buf, A_UINT32 len); #endif -int wmi_set_bt_status_cmd(struct wmi_t *wmip, A_UINT8 streamType, A_UINT8 status); +int wmi_set_bt_status_cmd(struct wmi_t *wmip, u8 streamType, u8 status); int wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd); int wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd); @@ -269,7 +269,7 @@ int wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * c int wmi_get_btcoex_stats_cmd(struct wmi_t * wmip); -int wmi_SGI_cmd(struct wmi_t *wmip, A_UINT32 sgiMask, A_UINT8 sgiPERThreshold); +int wmi_SGI_cmd(struct wmi_t *wmip, A_UINT32 sgiMask, u8 sgiPERThreshold); /* * This function is used to configure the fix rates mask to the target. @@ -277,23 +277,23 @@ int wmi_SGI_cmd(struct wmi_t *wmip, A_UINT32 sgiMask, A_UINT8 sgiPERThreshold); int wmi_set_fixrates_cmd(struct wmi_t *wmip, A_UINT32 fixRatesMask); int wmi_get_ratemask_cmd(struct wmi_t *wmip); -int wmi_set_authmode_cmd(struct wmi_t *wmip, A_UINT8 mode); +int wmi_set_authmode_cmd(struct wmi_t *wmip, u8 mode); -int wmi_set_reassocmode_cmd(struct wmi_t *wmip, A_UINT8 mode); +int wmi_set_reassocmode_cmd(struct wmi_t *wmip, u8 mode); -int wmi_set_qos_supp_cmd(struct wmi_t *wmip,A_UINT8 status); +int wmi_set_qos_supp_cmd(struct wmi_t *wmip,u8 status); int wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status); int wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG txEnable); int wmi_set_country(struct wmi_t *wmip, A_UCHAR *countryCode); int wmi_get_keepalive_configured(struct wmi_t *wmip); -A_UINT8 wmi_get_keepalive_cmd(struct wmi_t *wmip); -int wmi_set_keepalive_cmd(struct wmi_t *wmip, A_UINT8 keepaliveInterval); +u8 wmi_get_keepalive_cmd(struct wmi_t *wmip); +int wmi_set_keepalive_cmd(struct wmi_t *wmip, u8 keepaliveInterval); -int wmi_set_appie_cmd(struct wmi_t *wmip, A_UINT8 mgmtFrmType, - A_UINT8 ieLen,A_UINT8 *ieInfo); +int wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType, + u8 ieLen,u8 *ieInfo); -int wmi_set_halparam_cmd(struct wmi_t *wmip, A_UINT8 *cmd, A_UINT16 dataLen); +int wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, A_UINT16 dataLen); A_INT32 wmi_get_rate(A_INT8 rateindex); @@ -304,7 +304,7 @@ int wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, WMI_SET_HOST_SLEEP_MODE_CMD int wmi_set_wow_mode_cmd(struct wmi_t *wmip, WMI_SET_WOW_MODE_CMD *cmd); int wmi_get_wow_list_cmd(struct wmi_t *wmip, WMI_GET_WOW_LIST_CMD *cmd); int wmi_add_wow_pattern_cmd(struct wmi_t *wmip, - WMI_ADD_WOW_PATTERN_CMD *cmd, A_UINT8* pattern, A_UINT8* mask, A_UINT8 pattern_size); + WMI_ADD_WOW_PATTERN_CMD *cmd, u8 *pattern, u8 *mask, u8 pattern_size); int wmi_del_wow_pattern_cmd(struct wmi_t *wmip, WMI_DEL_WOW_PATTERN_CMD *cmd); int wmi_set_wsc_status_cmd(struct wmi_t *wmip, A_UINT32 status); @@ -313,13 +313,13 @@ int wmi_set_params_cmd(struct wmi_t *wmip, A_UINT32 opcode, A_UINT32 length, char *buffer); int -wmi_set_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 dot3, A_UINT8 dot4); +wmi_set_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4); int -wmi_del_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 dot3, A_UINT8 dot4); +wmi_del_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4); int -wmi_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 enable); +wmi_mcast_filter_cmd(struct wmi_t *wmip, u8 enable); bss_t * wmi_find_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid, @@ -346,8 +346,8 @@ void wmi_scan_indication (struct wmi_t *wmip); int wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd); -bss_t *wmi_rm_current_bss (struct wmi_t *wmip, A_UINT8 *id); -int wmi_add_current_bss (struct wmi_t *wmip, A_UINT8 *id, bss_t *bss); +bss_t *wmi_rm_current_bss (struct wmi_t *wmip, u8 *id); +int wmi_add_current_bss (struct wmi_t *wmip, u8 *id, bss_t *bss); /* @@ -357,22 +357,21 @@ int wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p); int -wmi_ap_set_hidden_ssid(struct wmi_t *wmip, A_UINT8 hidden_ssid); +wmi_ap_set_hidden_ssid(struct wmi_t *wmip, u8 hidden_ssid); int -wmi_ap_set_num_sta(struct wmi_t *wmip, A_UINT8 num_sta); +wmi_ap_set_num_sta(struct wmi_t *wmip, u8 num_sta); int -wmi_ap_set_acl_policy(struct wmi_t *wmip, A_UINT8 policy); +wmi_ap_set_acl_policy(struct wmi_t *wmip, u8 policy); int wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *a); -A_UINT8 -acl_add_del_mac(WMI_AP_ACL *a, WMI_AP_ACL_MAC_CMD *acl); +u8 acl_add_del_mac(WMI_AP_ACL *a, WMI_AP_ACL_MAC_CMD *acl); int -wmi_ap_set_mlme(struct wmi_t *wmip, A_UINT8 cmd, A_UINT8 *mac, A_UINT16 reason); +wmi_ap_set_mlme(struct wmi_t *wmip, u8 cmd, u8 *mac, A_UINT16 reason); int wmi_set_pvb_cmd(struct wmi_t *wmip, A_UINT16 aid, bool flag); @@ -384,34 +383,34 @@ int wmi_ap_bgscan_time(struct wmi_t *wmip, A_UINT32 period, A_UINT32 dwell); int -wmi_ap_set_dtim(struct wmi_t *wmip, A_UINT8 dtim); +wmi_ap_set_dtim(struct wmi_t *wmip, u8 dtim); int -wmi_ap_set_rateset(struct wmi_t *wmip, A_UINT8 rateset); +wmi_ap_set_rateset(struct wmi_t *wmip, u8 rateset); int wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd); int -wmi_set_ht_op_cmd(struct wmi_t *wmip, A_UINT8 sta_chan_width); +wmi_set_ht_op_cmd(struct wmi_t *wmip, u8 sta_chan_width); int -wmi_send_hci_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT16 sz); +wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, A_UINT16 sz); int wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, A_UINT32 *pMaskArray); int -wmi_setup_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid); +wmi_setup_aggr_cmd(struct wmi_t *wmip, u8 tid); int -wmi_delete_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid, bool uplink); +wmi_delete_aggr_cmd(struct wmi_t *wmip, u8 tid, bool uplink); int wmi_allow_aggr_cmd(struct wmi_t *wmip, A_UINT16 tx_tidmask, A_UINT16 rx_tidmask); int -wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, A_UINT8 rxMetaVersion, bool rxDot11Hdr, bool defragOnHost); +wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, u8 rxMetaVersion, bool rxDot11Hdr, bool defragOnHost); int wmi_set_thin_mode_cmd(struct wmi_t *wmip, bool bThinMode); @@ -420,7 +419,7 @@ int wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence); int -wmi_set_pmk_cmd(struct wmi_t *wmip, A_UINT8 *pmk); +wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk); A_UINT16 wmi_ieee2freq (int chan); diff --git a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c index 1761092f0ecc..10c53f57ed83 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c @@ -50,7 +50,7 @@ int AthPSInitialize(AR3K_CONFIG_INFO *hdev); static int SendHCICommand(AR3K_CONFIG_INFO *pConfig, - A_UINT8 *pBuffer, + u8 *pBuffer, int Length) { HTC_PACKET *pPacket = NULL; @@ -85,7 +85,7 @@ static int SendHCICommand(AR3K_CONFIG_INFO *pConfig, } static int RecvHCIEvent(AR3K_CONFIG_INFO *pConfig, - A_UINT8 *pBuffer, + u8 *pBuffer, int *pLength) { int status = A_OK; @@ -123,17 +123,17 @@ static int RecvHCIEvent(AR3K_CONFIG_INFO *pConfig, } int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, - A_UINT8 *pHCICommand, + u8 *pHCICommand, int CmdLength, - A_UINT8 **ppEventBuffer, - A_UINT8 **ppBufferToFree) + u8 **ppEventBuffer, + u8 **ppBufferToFree) { int status = A_OK; - A_UINT8 *pBuffer = NULL; - A_UINT8 *pTemp; + u8 *pBuffer = NULL; + u8 *pTemp; int length; bool commandComplete = false; - A_UINT8 opCodeBytes[2]; + u8 opCodeBytes[2]; do { @@ -141,7 +141,7 @@ int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, length += pConfig->pHCIProps->HeadRoom + pConfig->pHCIProps->TailRoom; length += pConfig->pHCIProps->IOBlockPad; - pBuffer = (A_UINT8 *)A_MALLOC(length); + pBuffer = (u8 *)A_MALLOC(length); if (NULL == pBuffer) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Failed to allocate bt buffer \n")); status = A_NO_MEMORY; @@ -212,17 +212,17 @@ int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, static int AR3KConfigureHCIBaud(AR3K_CONFIG_INFO *pConfig) { int status = A_OK; - A_UINT8 hciBaudChangeCommand[] = {0x0c,0xfc,0x2,0,0}; + u8 hciBaudChangeCommand[] = {0x0c,0xfc,0x2,0,0}; A_UINT16 baudVal; - A_UINT8 *pEvent = NULL; - A_UINT8 *pBufferToFree = NULL; + u8 *pEvent = NULL; + u8 *pBufferToFree = NULL; do { if (pConfig->Flags & AR3K_CONFIG_FLAG_SET_AR3K_BAUD) { baudVal = (A_UINT16)(pConfig->AR3KBaudRate / 100); - hciBaudChangeCommand[3] = (A_UINT8)baudVal; - hciBaudChangeCommand[4] = (A_UINT8)(baudVal >> 8); + hciBaudChangeCommand[3] = (u8)baudVal; + hciBaudChangeCommand[4] = (u8)(baudVal >> 8); status = SendHCICommandWaitCommandComplete(pConfig, hciBaudChangeCommand, @@ -279,8 +279,8 @@ static int AR3KExitMinBoot(AR3K_CONFIG_INFO *pConfig) int status; char exitMinBootCmd[] = {0x25,0xFC,0x0c,0x03,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00}; - A_UINT8 *pEvent = NULL; - A_UINT8 *pBufferToFree = NULL; + u8 *pEvent = NULL; + u8 *pBufferToFree = NULL; status = SendHCICommandWaitCommandComplete(pConfig, exitMinBootCmd, @@ -313,9 +313,9 @@ static int AR3KExitMinBoot(AR3K_CONFIG_INFO *pConfig) static int AR3KConfigureSendHCIReset(AR3K_CONFIG_INFO *pConfig) { int status = A_OK; - A_UINT8 hciResetCommand[] = {0x03,0x0c,0x0}; - A_UINT8 *pEvent = NULL; - A_UINT8 *pBufferToFree = NULL; + u8 hciResetCommand[] = {0x03,0x0c,0x0}; + u8 *pEvent = NULL; + u8 *pBufferToFree = NULL; status = SendHCICommandWaitCommandComplete( pConfig, hciResetCommand, @@ -362,12 +362,12 @@ static int AR3KEnableTLPM(AR3K_CONFIG_INFO *pConfig) /* AR3K vendor specific command for Sleep Enable */ char sleepEnable[] = {0x4,0xFC,0x1, 0x1}; - A_UINT8 *pEvent = NULL; - A_UINT8 *pBufferToFree = NULL; + u8 *pEvent = NULL; + u8 *pBufferToFree = NULL; if (0 != pConfig->IdleTimeout) { - A_UINT8 idle_lsb = pConfig->IdleTimeout & 0xFF; - A_UINT8 idle_msb = (pConfig->IdleTimeout & 0xFF00) >> 8; + u8 idle_lsb = pConfig->IdleTimeout & 0xFF; + u8 idle_msb = (pConfig->IdleTimeout & 0xFF00) >> 8; hostWakeupConfig[11] = targetWakeupConfig[11] = idle_lsb; hostWakeupConfig[12] = targetWakeupConfig[12] = idle_msb; } diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c index e87f598a0ca0..df23158b1097 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c @@ -47,10 +47,10 @@ typedef struct { }HciCommandListParam; int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, - A_UINT8 *pHCICommand, + u8 *pHCICommand, int CmdLength, - A_UINT8 **ppEventBuffer, - A_UINT8 **ppBufferToFree); + u8 **ppEventBuffer, + u8 **ppBufferToFree); A_UINT32 Rom_Version; A_UINT32 Build_Version; @@ -136,8 +136,8 @@ int PSSendOps(void *arg) PSCmdPacket *HciCmdList; /* List storing the commands */ const struct firmware* firmware; A_UINT32 numCmds; - A_UINT8 *event; - A_UINT8 *bufferToFree; + u8 *event; + u8 *bufferToFree; struct hci_dev *device; A_UCHAR *buffer; A_UINT32 len; @@ -390,10 +390,10 @@ complete: * For HCI SDIO transport, this will be internally defined. */ int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, - A_UINT8 *pHCICommand, + u8 *pHCICommand, int CmdLength, - A_UINT8 **ppEventBuffer, - A_UINT8 **ppBufferToFree) + u8 **ppEventBuffer, + u8 **ppBufferToFree) { if(CmdLength == 0) { return A_ERROR; @@ -486,8 +486,8 @@ int write_bdaddr(AR3K_CONFIG_INFO *pConfig,A_UCHAR *bdaddr,int type) A_UCHAR bdaddr_cmd[] = { 0x0B, 0xFC, 0x0A, 0x01, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - A_UINT8 *event; - A_UINT8 *bufferToFree = NULL; + u8 *event; + u8 *bufferToFree = NULL; int result = A_ERROR; int inc,outc; @@ -518,9 +518,9 @@ int write_bdaddr(AR3K_CONFIG_INFO *pConfig,A_UCHAR *bdaddr,int type) } int ReadVersionInfo(AR3K_CONFIG_INFO *pConfig) { - A_UINT8 hciCommand[] = {0x1E,0xfc,0x00}; - A_UINT8 *event; - A_UINT8 *bufferToFree = NULL; + u8 hciCommand[] = {0x1E,0xfc,0x00}; + u8 *event; + u8 *bufferToFree = NULL; int result = A_ERROR; if(A_OK == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) { result = ReadPSEvent(event); @@ -533,16 +533,16 @@ int ReadVersionInfo(AR3K_CONFIG_INFO *pConfig) } int getDeviceType(AR3K_CONFIG_INFO *pConfig, A_UINT32 * code) { - A_UINT8 hciCommand[] = {0x05,0xfc,0x05,0x00,0x00,0x00,0x00,0x04}; - A_UINT8 *event; - A_UINT8 *bufferToFree = NULL; + u8 hciCommand[] = {0x05,0xfc,0x05,0x00,0x00,0x00,0x00,0x04}; + u8 *event; + u8 *bufferToFree = NULL; A_UINT32 reg; int result = A_ERROR; *code = 0; - hciCommand[3] = (A_UINT8)(FPGA_REGISTER & 0xFF); - hciCommand[4] = (A_UINT8)((FPGA_REGISTER >> 8) & 0xFF); - hciCommand[5] = (A_UINT8)((FPGA_REGISTER >> 16) & 0xFF); - hciCommand[6] = (A_UINT8)((FPGA_REGISTER >> 24) & 0xFF); + hciCommand[3] = (u8)(FPGA_REGISTER & 0xFF); + hciCommand[4] = (u8)((FPGA_REGISTER >> 8) & 0xFF); + hciCommand[5] = (u8)((FPGA_REGISTER >> 16) & 0xFF); + hciCommand[6] = (u8)((FPGA_REGISTER >> 24) & 0xFF); if(A_OK == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) { if(event[4] == 0xFC && event[5] == 0x00){ diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c index 7ac1c365314e..62d11dee34df 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c @@ -89,13 +89,13 @@ typedef struct tPsTagEntry { A_UINT32 TagId; A_UINT32 TagLen; - A_UINT8 *TagData; + u8 *TagData; } tPsTagEntry, *tpPsTagEntry; typedef struct tRamPatch { A_UINT16 Len; - A_UINT8 * Data; + u8 *Data; } tRamPatch, *ptRamPatch; @@ -319,9 +319,9 @@ int AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat) { char *Buffer; char *pCharLine; - A_UINT8 TagCount; + u8 TagCount; A_UINT16 ByteCount; - A_UINT8 ParseSection=RAM_PS_SECTION; + u8 ParseSection=RAM_PS_SECTION; A_UINT32 pos; @@ -438,7 +438,7 @@ int AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat) return A_ERROR; } PsTagEntry[TagCount].TagLen = ByteCount; - PsTagEntry[TagCount].TagData = (A_UINT8*)A_MALLOC(ByteCount); + PsTagEntry[TagCount].TagData = (u8 *)A_MALLOC(ByteCount); AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" TAG Length %d Tag Index %d \n",PsTagEntry[TagCount].TagLen,TagCount)); stReadStatus.uSection = 3; stReadStatus.uLineCount = 0; @@ -472,12 +472,12 @@ int AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat) if((stPS_DataFormat.eDataType == eHex) && stPS_DataFormat.bIsArray == true) { while(uReadCount > 0) { PsTagEntry[TagCount].TagData[stReadStatus.uByteCount] = - (A_UINT8)(hex_to_bin(pCharLine[stReadStatus.uCharCount]) << 4) - | (A_UINT8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 1])); + (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount]) << 4) + | (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 1])); PsTagEntry[TagCount].TagData[stReadStatus.uByteCount+1] = - (A_UINT8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 3]) << 4) - | (A_UINT8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 4])); + (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 3]) << 4) + | (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 4])); stReadStatus.uCharCount += 6; // read two bytes, plus a space; stReadStatus.uByteCount += 2; @@ -614,7 +614,7 @@ int AthDoParsePatch(A_UCHAR *patchbuffer, A_UINT32 patchlen) return A_ERROR; } RamPatch[Patch_Count].Len= MAX_BYTE_LENGTH; - RamPatch[Patch_Count].Data = (A_UINT8*)A_MALLOC(MAX_BYTE_LENGTH); + RamPatch[Patch_Count].Data = (u8 *)A_MALLOC(MAX_BYTE_LENGTH); Patch_Count ++; @@ -623,7 +623,7 @@ int AthDoParsePatch(A_UCHAR *patchbuffer, A_UINT32 patchlen) RamPatch[Patch_Count].Len= (ByteCount & 0xFF); if(ByteCount != 0) { - RamPatch[Patch_Count].Data = (A_UINT8*)A_MALLOC(ByteCount); + RamPatch[Patch_Count].Data = (u8 *)A_MALLOC(ByteCount); Patch_Count ++; } count = 0; @@ -767,7 +767,7 @@ static void LoadHeader(A_UCHAR *HCI_PS_Command,A_UCHAR opcode,int length,int ind int AthCreateCommandList(PSCmdPacket **HciPacketList, A_UINT32 *numPackets) { - A_UINT8 count; + u8 count; A_UINT32 NumcmdEntry = 0; A_UINT32 Crc = 0; diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h index b7305abc3feb..58bd4a90024d 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h @@ -52,7 +52,7 @@ #define A_UCHAR unsigned char #define A_UINT32 unsigned long #define A_UINT16 unsigned short -#define A_UINT8 unsigned char +#define u8 unsigned char #define bool unsigned char #endif /* A_UINT32 */ diff --git a/drivers/staging/ath6kl/miscdrv/common_drv.c b/drivers/staging/ath6kl/miscdrv/common_drv.c index 171078596f8b..82bec20e0ff7 100644 --- a/drivers/staging/ath6kl/miscdrv/common_drv.c +++ b/drivers/staging/ath6kl/miscdrv/common_drv.c @@ -71,8 +71,8 @@ ATH_DEBUG_INSTANTIATE_MODULE_VAR(misc, #define CPU_DBG_SEL_ADDRESS 0x00000483 #define CPU_DBG_ADDRESS 0x00000484 -static A_UINT8 custDataAR6002[AR6002_CUST_DATA_SIZE]; -static A_UINT8 custDataAR6003[AR6003_CUST_DATA_SIZE]; +static u8 custDataAR6002[AR6002_CUST_DATA_SIZE]; +static u8 custDataAR6003[AR6003_CUST_DATA_SIZE]; /* Compile the 4BYTE version of the window register setup routine, * This mitigates host interconnect issues with non-4byte aligned bus requests, some @@ -86,7 +86,7 @@ static A_UINT8 custDataAR6003[AR6003_CUST_DATA_SIZE]; int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr, A_UINT32 Address) { int status; - A_UINT8 addrValue[4]; + u8 addrValue[4]; A_INT32 i; /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written @@ -94,7 +94,7 @@ int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr for (i = 1; i <= 3; i++) { /* fill the buffer with the address byte value we want to hit 4 times*/ - addrValue[0] = ((A_UINT8 *)&Address)[i]; + addrValue[0] = ((u8 *)&Address)[i]; addrValue[1] = addrValue[0]; addrValue[2] = addrValue[0]; addrValue[3] = addrValue[0]; @@ -167,7 +167,7 @@ int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr status = HIFReadWrite(hifDevice, RegisterAddr, (A_UCHAR *)(&Address), - sizeof(A_UINT8), + sizeof(u8), HIF_WR_SYNC_BYTE_INC, NULL); @@ -484,7 +484,7 @@ void ar6000_copy_cust_data_from_target(HIF_DEVICE *hifDevice, A_UINT32 TargetType) { A_UINT32 eepHeaderAddr; - A_UINT8 AR6003CustDataShadow[AR6003_CUST_DATA_SIZE+4]; + u8 AR6003CustDataShadow[AR6003_CUST_DATA_SIZE+4]; A_INT32 i; if (BMIReadMemory(hifDevice, @@ -526,8 +526,7 @@ ar6000_copy_cust_data_from_target(HIF_DEVICE *hifDevice, A_UINT32 TargetType) } /* This is the function to call when need to use the cust data */ -A_UINT8 * -ar6000_get_cust_data_buffer(A_UINT32 TargetType) +u8 *ar6000_get_cust_data_buffer(A_UINT32 TargetType) { if (TargetType == TARGET_TYPE_AR6003) return custDataAR6003; @@ -628,7 +627,7 @@ void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType) int ar6000_set_htc_params(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_UINT32 MboxIsrYieldValue, - A_UINT8 HtcControlBuffers) + u8 HtcControlBuffers) { int status; A_UINT32 blocksizes[HTC_MAILBOX_NUM_MAX]; diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index b1909479179b..647c6c983a29 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -47,8 +47,8 @@ #define LINUX_HACK_FUDGE_FACTOR 16 #define BDATA_BDADDR_OFFSET 28 -A_UINT8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; -A_UINT8 null_mac[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; +u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +u8 null_mac[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; #ifdef DEBUG @@ -370,7 +370,7 @@ static void ar6000_free_cookie(AR_SOFTC_T *ar, struct ar_cookie * cookie); static struct ar_cookie *ar6000_alloc_cookie(AR_SOFTC_T *ar); #ifdef USER_KEYS -static int ar6000_reinstall_keys(AR_SOFTC_T *ar,A_UINT8 key_op_ctrl); +static int ar6000_reinstall_keys(AR_SOFTC_T *ar,u8 key_op_ctrl); #endif #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT @@ -614,7 +614,7 @@ ar6000_dbglog_event(AR_SOFTC_T *ar, A_UINT32 dropped, send = dbglog_get_debug_fragment(&buffer[sent], length - sent, MAX_WIRELESS_EVENT_SIZE); while (send) { - ar6000_send_event_to_app(ar, WMIX_DBGLOG_EVENTID, (A_UINT8*)&buffer[sent], send); + ar6000_send_event_to_app(ar, WMIX_DBGLOG_EVENTID, (u8 *)&buffer[sent], send); sent += send; send = dbglog_get_debug_fragment(&buffer[sent], length - sent, MAX_WIRELESS_EVENT_SIZE); @@ -950,10 +950,10 @@ ar6000_softmac_update(AR_SOFTC_T *ar, A_UCHAR *eeprom_data, size_t size) A_UCHAR *ptr_mac; switch (ar->arTargetType) { case TARGET_TYPE_AR6002: - ptr_mac = (A_UINT8 *)((A_UCHAR *)eeprom_data + AR6002_MAC_ADDRESS_OFFSET); + ptr_mac = (u8 *)((A_UCHAR *)eeprom_data + AR6002_MAC_ADDRESS_OFFSET); break; case TARGET_TYPE_AR6003: - ptr_mac = (A_UINT8 *)((A_UCHAR *)eeprom_data + AR6003_MAC_ADDRESS_OFFSET); + ptr_mac = (u8 *)((A_UCHAR *)eeprom_data + AR6003_MAC_ADDRESS_OFFSET); break; default: AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid Target Type\n")); @@ -1877,7 +1877,7 @@ static void ar6000_target_failure(void *Instance, int Status) errEvent.errorVal = WMI_TARGET_COM_ERR | WMI_TARGET_FATAL_ERR; ar6000_send_event_to_app(ar, WMI_ERROR_REPORT_EVENTID, - (A_UINT8 *)&errEvent, + (u8 *)&errEvent, sizeof(WMI_TARGET_ERROR_REPORT_EVENT)); } } @@ -2186,7 +2186,7 @@ static void ar6000_detect_error(unsigned long ptr) errEvent.errorVal = WMI_TARGET_COM_ERR | WMI_TARGET_FATAL_ERR; AR6000_SPIN_UNLOCK(&ar->arLock, 0); ar6000_send_event_to_app(ar, WMI_ERROR_REPORT_EVENTID, - (A_UINT8 *)&errEvent, + (u8 *)&errEvent, sizeof(WMI_TARGET_ERROR_REPORT_EVENT)); return; } @@ -2264,8 +2264,8 @@ ar6000_init_control_info(AR_SOFTC_T *ar) /* Initialize the AP mode state info */ { - A_UINT8 ctr; - A_MEMZERO((A_UINT8 *)ar->sta_list, AP_MAX_NUM_STA * sizeof(sta_t)); + u8 ctr; + A_MEMZERO((u8 *)ar->sta_list, AP_MAX_NUM_STA * sizeof(sta_t)); /* init the Mutexes */ A_MUTEX_INIT(&ar->mcastpsqLock); @@ -2414,14 +2414,13 @@ void ar6000_TxDataCleanup(AR_SOFTC_T *ar) } HTC_ENDPOINT_ID -ar6000_ac2_endpoint_id ( void * devt, A_UINT8 ac) +ar6000_ac2_endpoint_id ( void * devt, u8 ac) { AR_SOFTC_T *ar = (AR_SOFTC_T *) devt; return(arAc2EndpointID(ar, ac)); } -A_UINT8 -ar6000_endpoint_id2_ac(void * devt, HTC_ENDPOINT_ID ep ) +u8 ar6000_endpoint_id2_ac(void * devt, HTC_ENDPOINT_ID ep ) { AR_SOFTC_T *ar = (AR_SOFTC_T *) devt; return(arEndpoint2Ac(ar, ep )); @@ -2788,7 +2787,7 @@ ar6000_ratemask_rx(void *devt, A_UINT32 ratemask) } void -ar6000_txPwr_rx(void *devt, A_UINT8 txPwr) +ar6000_txPwr_rx(void *devt, u8 txPwr) { AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; @@ -2808,11 +2807,10 @@ ar6000_channelList_rx(void *devt, A_INT8 numChan, A_UINT16 *chanList) wake_up(&arEvent); } -A_UINT8 -ar6000_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, A_UINT32 * mapNo) +u8 ar6000_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, A_UINT32 * mapNo) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - A_UINT8 *datap; + u8 *datap; ATH_MAC_HDR *macHdr; A_UINT32 i, eptMap; @@ -2888,14 +2886,14 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) { #define AC_NOT_MAPPED 99 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - A_UINT8 ac = AC_NOT_MAPPED; + u8 ac = AC_NOT_MAPPED; HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED; A_UINT32 mapNo = 0; int len; struct ar_cookie *cookie; bool checkAdHocPsMapping = false,bMoreData = false; HTC_TX_TAG htc_tag = AR6K_DATA_PKT_TAG; - A_UINT8 dot11Hdr = processDot11Hdr; + u8 dot11Hdr = processDot11Hdr; #ifdef CONFIG_PM if (ar->arWowState != WLAN_WOW_STATE_NONE) { A_NETBUF_FREE(skb); @@ -2942,7 +2940,7 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) * mcastq */ if (IEEE80211_IS_MULTICAST(datap->dstMac)) { - A_UINT8 ctr=0; + u8 ctr=0; bool qMcast=false; @@ -3024,9 +3022,9 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) if (ar->arWmiEnabled) { #ifdef CONFIG_CHECKSUM_OFFLOAD - A_UINT8 csumStart=0; - A_UINT8 csumDest=0; - A_UINT8 csum=skb->ip_summed; + u8 csumStart=0; + u8 csumDest=0; + u8 csum=skb->ip_summed; if(csumOffload && (csum==CHECKSUM_PARTIAL)){ csumStart = (skb->head + skb->csum_start - skb_network_header(skb) + sizeof(ATH_LLC_SNAP_HDR)); @@ -3527,10 +3525,10 @@ ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPacketQueue) } sta_t * -ieee80211_find_conn(AR_SOFTC_T *ar, A_UINT8 *node_addr) +ieee80211_find_conn(AR_SOFTC_T *ar, u8 *node_addr) { sta_t *conn = NULL; - A_UINT8 i, max_conn; + u8 i, max_conn; switch(ar->arNetworkType) { case AP_NETWORK: @@ -3551,10 +3549,10 @@ ieee80211_find_conn(AR_SOFTC_T *ar, A_UINT8 *node_addr) return conn; } -sta_t *ieee80211_find_conn_for_aid(AR_SOFTC_T *ar, A_UINT8 aid) +sta_t *ieee80211_find_conn_for_aid(AR_SOFTC_T *ar, u8 aid) { sta_t *conn = NULL; - A_UINT8 ctr; + u8 ctr; for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) { if (ar->sta_list[ctr].aid == aid) { @@ -3575,7 +3573,7 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; struct sk_buff *skb = (struct sk_buff *)pPacket->pPktContext; int minHdrLen; - A_UINT8 containsDot11Hdr = 0; + u8 containsDot11Hdr = 0; int status = pPacket->Status; HTC_ENDPOINT_ID ept = pPacket->Endpoint; @@ -3631,7 +3629,7 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) } else { WMI_DATA_HDR *dhdr = (WMI_DATA_HDR *)A_NETBUF_DATA(skb); bool is_amsdu; - A_UINT8 tid; + u8 tid; bool is_acl_data_frame; is_acl_data_frame = WMI_DATA_HDR_GET_DATA_TYPE(dhdr) == WMI_DATA_HDR_DATA_TYPE_ACL; #ifdef CONFIG_PM @@ -3668,7 +3666,7 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) A_NETBUF_FREE(skb); } else { A_UINT16 seq_no; - A_UINT8 meta_type; + u8 meta_type; #if 0 /* Access RSSI values here */ @@ -3678,7 +3676,7 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) /* Get the Power save state of the STA */ if (ar->arNetworkType == AP_NETWORK) { sta_t *conn = NULL; - A_UINT8 psState=0,prevPsState; + u8 psState=0,prevPsState; ATH_MAC_HDR *datap=NULL; A_UINT16 offset; @@ -4162,7 +4160,7 @@ err_exit: } void -ar6000_ready_event(void *devt, A_UINT8 *datap, A_UINT8 phyCap, A_UINT32 sw_ver, A_UINT32 abi_ver) +ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, A_UINT32 sw_ver, A_UINT32 abi_ver) { AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; struct net_device *dev = ar->arNetDev; @@ -4208,10 +4206,10 @@ ar6000_ready_event(void *devt, A_UINT8 *datap, A_UINT8 phyCap, A_UINT32 sw_ver, } void -add_new_sta(AR_SOFTC_T *ar, A_UINT8 *mac, A_UINT16 aid, A_UINT8 *wpaie, - A_UINT8 ielen, A_UINT8 keymgmt, A_UINT8 ucipher, A_UINT8 auth) +add_new_sta(AR_SOFTC_T *ar, u8 *mac, A_UINT16 aid, u8 *wpaie, + u8 ielen, u8 keymgmt, u8 ucipher, u8 auth) { - A_UINT8 free_slot=aid-1; + u8 free_slot=aid-1; A_MEMCPY(ar->sta_list[free_slot].mac, mac, ATH_MAC_LEN); A_MEMCPY(ar->sta_list[free_slot].wpa_ie, wpaie, ielen); @@ -4224,11 +4222,11 @@ add_new_sta(AR_SOFTC_T *ar, A_UINT8 *mac, A_UINT16 aid, A_UINT8 *wpaie, } void -ar6000_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, A_UINT8 *bssid, +ar6000_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, u8 *bssid, A_UINT16 listenInterval, A_UINT16 beaconInterval, - NETWORK_TYPE networkType, A_UINT8 beaconIeLen, - A_UINT8 assocReqLen, A_UINT8 assocRespLen, - A_UINT8 *assocInfo) + NETWORK_TYPE networkType, u8 beaconIeLen, + u8 assocReqLen, u8 assocRespLen, + u8 *assocInfo) { union iwreq_data wrqu; int i, beacon_ie_pos, assoc_resp_ie_pos, assoc_req_ie_pos; @@ -4237,7 +4235,7 @@ ar6000_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, A_UINT8 *bssid, static const char *beaconIetag = "BEACONIE="; char buf[WMI_CONTROL_MSG_MAX_LEN * 2 + strlen(tag1) + 1]; char *pos; - A_UINT8 key_op_ctrl; + u8 key_op_ctrl; unsigned long flags; struct ieee80211req_key *ik; CRYPTO_TYPE keyType = NONE_CRYPT; @@ -4273,7 +4271,7 @@ ar6000_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, A_UINT8 *bssid, goto skip_key; } wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, keyType, GROUP_USAGE, - ik->ik_keylen, (A_UINT8 *)&ik->ik_keyrsc, + ik->ik_keylen, (u8 *)&ik->ik_keyrsc, ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr, SYNC_BOTH_WMIFLAG); @@ -4517,7 +4515,7 @@ void ar6000_set_numdataendpts(AR_SOFTC_T *ar, A_UINT32 num) } void -sta_cleanup(AR_SOFTC_T *ar, A_UINT8 i) +sta_cleanup(AR_SOFTC_T *ar, u8 i) { struct sk_buff *skb; @@ -4540,10 +4538,9 @@ sta_cleanup(AR_SOFTC_T *ar, A_UINT8 i) } -A_UINT8 -remove_sta(AR_SOFTC_T *ar, A_UINT8 *mac, A_UINT16 reason) +u8 remove_sta(AR_SOFTC_T *ar, u8 *mac, A_UINT16 reason) { - A_UINT8 i, removed=0; + u8 i, removed=0; if(IS_MAC_NULL(mac)) { return removed; @@ -4574,10 +4571,10 @@ remove_sta(AR_SOFTC_T *ar, A_UINT8 *mac, A_UINT16 reason) } void -ar6000_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, A_UINT8 *bssid, - A_UINT8 assocRespLen, A_UINT8 *assocInfo, A_UINT16 protocolReasonStatus) +ar6000_disconnect_event(AR_SOFTC_T *ar, u8 reason, u8 *bssid, + u8 assocRespLen, u8 *assocInfo, A_UINT16 protocolReasonStatus) { - A_UINT8 i; + u8 i; unsigned long flags; union iwreq_data wrqu; @@ -4761,7 +4758,7 @@ ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd) { void *osbuf = NULL; A_INT8 i; - A_UINT8 size, *buf; + u8 size, *buf; int ret = A_OK; size = cmd->evt_buf_sz + 4; @@ -4773,7 +4770,7 @@ ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd) } A_NETBUF_PUT(osbuf, size); - buf = (A_UINT8 *)A_NETBUF_DATA(osbuf); + buf = (u8 *)A_NETBUF_DATA(osbuf); /* First 2-bytes carry HCI event/ACL data type * the next 2 are free */ @@ -4850,7 +4847,7 @@ ar6000_neighborReport_event(AR_SOFTC_T *ar, int numAps, WMI_NEIGHBOR_INFO *info) } void -ar6000_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, bool ismcast) +ar6000_tkip_micerr_event(AR_SOFTC_T *ar, u8 keyid, bool ismcast) { static const char *tag = "MLME-MICHAELMICFAILURE.indication"; char buf[128]; @@ -4910,9 +4907,9 @@ ar6000_scanComplete_event(AR_SOFTC_T *ar, int status) } void -ar6000_targetStats_event(AR_SOFTC_T *ar, A_UINT8 *ptr, A_UINT32 len) +ar6000_targetStats_event(AR_SOFTC_T *ar, u8 *ptr, A_UINT32 len) { - A_UINT8 ac; + u8 ac; if(ar->arNetworkType == AP_NETWORK) { WMI_AP_MODE_STAT *p = (WMI_AP_MODE_STAT *)ptr; @@ -5051,7 +5048,7 @@ ar6000_rssiThreshold_event(AR_SOFTC_T *ar, WMI_RSSI_THRESHOLD_VAL newThreshold, A_PRINTF("rssi Threshold range = %d tag = %d rssi = %d\n", newThreshold, userRssiThold.tag, userRssiThold.rssi); - ar6000_send_event_to_app(ar, WMI_RSSI_THRESHOLD_EVENTID,(A_UINT8 *)&userRssiThold, sizeof(USER_RSSI_THOLD)); + ar6000_send_event_to_app(ar, WMI_RSSI_THRESHOLD_EVENTID,(u8 *)&userRssiThold, sizeof(USER_RSSI_THOLD)); } @@ -5061,7 +5058,7 @@ ar6000_hbChallengeResp_event(AR_SOFTC_T *ar, A_UINT32 cookie, A_UINT32 source) if (source == APP_HB_CHALLENGE) { /* Report it to the app in case it wants a positive acknowledgement */ ar6000_send_event_to_app(ar, WMIX_HB_CHALLENGE_RESP_EVENTID, - (A_UINT8 *)&cookie, sizeof(cookie)); + (u8 *)&cookie, sizeof(cookie)); } else { /* This would ignore the replys that come in after their due time */ if (cookie == ar->arHBChallengeResp.seqNum) { @@ -5107,8 +5104,8 @@ ar6000_reportError_event(AR_SOFTC_T *ar, WMI_TARGET_ERROR_VAL errorVal) void -ar6000_cac_event(AR_SOFTC_T *ar, A_UINT8 ac, A_UINT8 cacIndication, - A_UINT8 statusCode, A_UINT8 *tspecSuggestion) +ar6000_cac_event(AR_SOFTC_T *ar, u8 ac, u8 cacIndication, + u8 statusCode, u8 *tspecSuggestion) { WMM_TSPEC_IE *tspecIe; @@ -5146,7 +5143,7 @@ ar6000_channel_change_event(AR_SOFTC_T *ar, A_UINT16 oldChannel, void ar6000_roam_tbl_event(AR_SOFTC_T *ar, WMI_TARGET_ROAM_TBL *pTbl) { - A_UINT8 i; + u8 i; A_PRINTF("ROAM TABLE NO OF ENTRIES is %d ROAM MODE is %d\n", pTbl->numEntries, pTbl->roamMode); @@ -5169,9 +5166,9 @@ ar6000_roam_tbl_event(AR_SOFTC_T *ar, WMI_TARGET_ROAM_TBL *pTbl) } void -ar6000_wow_list_event(struct ar6_softc *ar, A_UINT8 num_filters, WMI_GET_WOW_LIST_REPLY *wow_reply) +ar6000_wow_list_event(struct ar6_softc *ar, u8 num_filters, WMI_GET_WOW_LIST_REPLY *wow_reply) { - A_UINT8 i,j; + u8 i,j; /*Each event now contains exactly one filter, see bug 26613*/ A_PRINTF("WOW pattern %d of %d patterns\n", wow_reply->this_filter_num, wow_reply->num_filters); @@ -5235,7 +5232,7 @@ ar6000_roam_data_event(AR_SOFTC_T *ar, WMI_TARGET_ROAM_DATA *p) } void -ar6000_bssInfo_event_rx(AR_SOFTC_T *ar, A_UINT8 *datap, int len) +ar6000_bssInfo_event_rx(AR_SOFTC_T *ar, u8 *datap, int len) { struct sk_buff *skb; WMI_BSS_INFO_HDR *bih = (WMI_BSS_INFO_HDR *)datap; @@ -5306,7 +5303,7 @@ ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid) if(logWmiRawMsgs) { A_PRINTF("WMI cmd send, msgNo %d :", wmiSendCmdNum); for(i = 0; i < a_netbuf_to_len(osbuf); i++) - A_PRINTF("%x ", ((A_UINT8 *)a_netbuf_to_data(osbuf))[i]); + A_PRINTF("%x ", ((u8 *)a_netbuf_to_data(osbuf))[i]); A_PRINTF("\n"); } @@ -5347,7 +5344,7 @@ ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid) } /* indicate tx activity or inactivity on a WMI stream */ -void ar6000_indicate_tx_activity(void *devt, A_UINT8 TrafficClass, bool Active) +void ar6000_indicate_tx_activity(void *devt, u8 TrafficClass, bool Active) { AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; HTC_ENDPOINT_ID eid ; @@ -5407,7 +5404,7 @@ void ar6000_indicate_tx_activity(void *devt, A_UINT8 TrafficClass, bool Active) } void -ar6000_btcoex_config_event(struct ar6_softc *ar, A_UINT8 *ptr, A_UINT32 len) +ar6000_btcoex_config_event(struct ar6_softc *ar, u8 *ptr, A_UINT32 len) { WMI_BTCOEX_CONFIG_EVENT *pBtcoexConfig = (WMI_BTCOEX_CONFIG_EVENT *)ptr; @@ -5444,7 +5441,7 @@ ar6000_btcoex_config_event(struct ar6_softc *ar, A_UINT8 *ptr, A_UINT32 len) } void -ar6000_btcoex_stats_event(struct ar6_softc *ar, A_UINT8 *ptr, A_UINT32 len) +ar6000_btcoex_stats_event(struct ar6_softc *ar, u8 *ptr, A_UINT32 len) { WMI_BTCOEX_STATS_EVENT *pBtcoexStats = (WMI_BTCOEX_STATS_EVENT *)ptr; @@ -5523,7 +5520,7 @@ ar6000_alloc_cookie(AR_SOFTC_T *ar) */ #define EVENT_ID_LEN 2 void ar6000_send_event_to_app(AR_SOFTC_T *ar, A_UINT16 eventId, - A_UINT8 *datap, int len) + u8 *datap, int len) { #if (WIRELESS_EXT >= 15) @@ -5568,7 +5565,7 @@ void ar6000_send_event_to_app(AR_SOFTC_T *ar, A_UINT16 eventId, * includes the event ID and event content. */ void ar6000_send_generic_event_to_app(AR_SOFTC_T *ar, A_UINT16 eventId, - A_UINT8 *datap, int len) + u8 *datap, int len) { #if (WIRELESS_EXT >= 18) @@ -5616,7 +5613,7 @@ ar6000_tx_retry_err_event(void *devt) } void -ar6000_snrThresholdEvent_rx(void *devt, WMI_SNR_THRESHOLD_VAL newThreshold, A_UINT8 snr) +ar6000_snrThresholdEvent_rx(void *devt, WMI_SNR_THRESHOLD_VAL newThreshold, u8 snr) { WMI_SNR_THRESHOLD_EVENT event; AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; @@ -5624,12 +5621,12 @@ ar6000_snrThresholdEvent_rx(void *devt, WMI_SNR_THRESHOLD_VAL newThreshold, A_UI event.range = newThreshold; event.snr = snr; - ar6000_send_event_to_app(ar, WMI_SNR_THRESHOLD_EVENTID, (A_UINT8 *)&event, + ar6000_send_event_to_app(ar, WMI_SNR_THRESHOLD_EVENTID, (u8 *)&event, sizeof(WMI_SNR_THRESHOLD_EVENT)); } void -ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL newThreshold, A_UINT8 lq) +ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL newThreshold, u8 lq) { AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("lq threshold range %d, lq %d\n", newThreshold, lq)); } @@ -5674,7 +5671,7 @@ ar6000_get_driver_cfg(struct net_device *dev, } void -ar6000_keepalive_rx(void *devt, A_UINT8 configured) +ar6000_keepalive_rx(void *devt, u8 configured) { AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; @@ -5683,10 +5680,10 @@ ar6000_keepalive_rx(void *devt, A_UINT8 configured) } void -ar6000_pmkid_list_event(void *devt, A_UINT8 numPMKID, WMI_PMKID *pmkidList, - A_UINT8 *bssidList) +ar6000_pmkid_list_event(void *devt, u8 numPMKID, WMI_PMKID *pmkidList, + u8 *bssidList) { - A_UINT8 i, j; + u8 i, j; A_PRINTF("Number of Cached PMKIDs is %d\n", numPMKID); @@ -5700,12 +5697,12 @@ ar6000_pmkid_list_event(void *devt, A_UINT8 numPMKID, WMI_PMKID *pmkidList, for (j = 0; j < WMI_PMKID_LEN; j++) { A_PRINTF("%2.2x", pmkidList->pmkid[j]); } - pmkidList = (WMI_PMKID *)((A_UINT8 *)pmkidList + ATH_MAC_LEN + + pmkidList = (WMI_PMKID *)((u8 *)pmkidList + ATH_MAC_LEN + WMI_PMKID_LEN); } } -void ar6000_pspoll_event(AR_SOFTC_T *ar,A_UINT8 aid) +void ar6000_pspoll_event(AR_SOFTC_T *ar,u8 aid) { sta_t *conn=NULL; bool isPsqEmpty = false; @@ -5793,7 +5790,7 @@ void ar6000_dtimexpiry_event(AR_SOFTC_T *ar) void read_rssi_compensation_param(AR_SOFTC_T *ar) { - A_UINT8 *cust_data_ptr; + u8 *cust_data_ptr; //#define RSSICOMPENSATION_PRINT @@ -5801,7 +5798,7 @@ read_rssi_compensation_param(AR_SOFTC_T *ar) A_INT16 i; cust_data_ptr = ar6000_get_cust_data_buffer(ar->arTargetType); for (i=0; i<16; i++) { - A_PRINTF("cust_data_%d = %x \n", i, *(A_UINT8 *)cust_data_ptr); + A_PRINTF("cust_data_%d = %x \n", i, *(u8 *)cust_data_ptr); cust_data_ptr += 1; } #endif @@ -5938,7 +5935,7 @@ rssi_compensation_reverse_calc(AR_SOFTC_T *ar, A_INT16 rssi, bool Above) } #ifdef WAPI_ENABLE -void ap_wapi_rekey_event(AR_SOFTC_T *ar, A_UINT8 type, A_UINT8 *mac) +void ap_wapi_rekey_event(AR_SOFTC_T *ar, u8 type, u8 *mac) { union iwreq_data wrqu; char buf[20]; @@ -5960,7 +5957,7 @@ void ap_wapi_rekey_event(AR_SOFTC_T *ar, A_UINT8 type, A_UINT8 *mac) #ifdef USER_KEYS static int -ar6000_reinstall_keys(AR_SOFTC_T *ar, A_UINT8 key_op_ctrl) +ar6000_reinstall_keys(AR_SOFTC_T *ar, u8 key_op_ctrl) { int status = A_OK; struct ieee80211req_key *uik = &ar->user_saved_keys.ucast_ik; @@ -5975,7 +5972,7 @@ ar6000_reinstall_keys(AR_SOFTC_T *ar, A_UINT8 key_op_ctrl) if (uik->ik_keylen) { status = wmi_addKey_cmd(ar->arWmi, uik->ik_keyix, ar->user_saved_keys.keyType, PAIRWISE_USAGE, - uik->ik_keylen, (A_UINT8 *)&uik->ik_keyrsc, + uik->ik_keylen, (u8 *)&uik->ik_keyrsc, uik->ik_keydata, key_op_ctrl, uik->ik_macaddr, SYNC_BEFORE_WMIFLAG); } @@ -5991,7 +5988,7 @@ ar6000_reinstall_keys(AR_SOFTC_T *ar, A_UINT8 key_op_ctrl) if (bik->ik_keylen) { status = wmi_addKey_cmd(ar->arWmi, bik->ik_keyix, ar->user_saved_keys.keyType, GROUP_USAGE, - bik->ik_keylen, (A_UINT8 *)&bik->ik_keyrsc, + bik->ik_keylen, (u8 *)&bik->ik_keyrsc, bik->ik_keydata, key_op_ctrl, bik->ik_macaddr, NO_SYNC_WMIFLAG); } } else { @@ -6190,7 +6187,7 @@ ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie } int -is_iwioctl_allowed(A_UINT8 mode, A_UINT16 cmd) +is_iwioctl_allowed(u8 mode, A_UINT16 cmd) { if(cmd >= SIOCSIWCOMMIT && cmd <= SIOCGIWPOWER) { cmd -= SIOCSIWCOMMIT; @@ -6207,7 +6204,7 @@ is_iwioctl_allowed(A_UINT8 mode, A_UINT16 cmd) } int -is_xioctl_allowed(A_UINT8 mode, int cmd) +is_xioctl_allowed(u8 mode, int cmd) { if(sizeof(xioctl_filter)-1 < cmd) { A_PRINTF("Filter for this cmd=%d not defined\n",cmd); @@ -6236,7 +6233,7 @@ ap_set_wapi_key(struct ar6_softc *ar, void *ikey) ik->ik_keylen); status = wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, WAPI_CRYPT, keyUsage, - ik->ik_keylen, (A_UINT8 *)&ik->ik_keyrsc, + ik->ik_keylen, (u8 *)&ik->ik_keyrsc, ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr, SYNC_BOTH_WMIFLAG); @@ -6249,10 +6246,10 @@ ap_set_wapi_key(struct ar6_softc *ar, void *ikey) void ar6000_peer_event( void *context, - A_UINT8 eventCode, - A_UINT8 *macAddr) + u8 eventCode, + u8 *macAddr) { - A_UINT8 pos; + u8 pos; for (pos=0;pos<6;pos++) printk("%02x: ",*(macAddr+pos)); diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c index a7a48292291c..b2a1351cdff8 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_pm.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_pm.c @@ -121,7 +121,7 @@ static void ar6000_wow_suspend(AR_SOFTC_T *ar) struct in_ifaddr **ifap = NULL; struct in_ifaddr *ifa = NULL; struct in_device *in_dev; - A_UINT8 macMask[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + u8 macMask[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; int status; WMI_ADD_WOW_PATTERN_CMD addWowCmd = { .filter = { 0 } }; WMI_DEL_WOW_PATTERN_CMD delWowCmd; @@ -642,7 +642,7 @@ ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool } if (pSleepEvent) { AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("SENT WLAN Sleep Event %d\n", wmiSleepEvent.sleepState)); - ar6000_send_event_to_app(ar, WMI_REPORT_SLEEP_STATE_EVENTID, (A_UINT8*)pSleepEvent, + ar6000_send_event_to_app(ar, WMI_REPORT_SLEEP_STATE_EVENTID, (u8 *)pSleepEvent, sizeof(WMI_REPORT_SLEEP_STATE_EVENTID)); } } diff --git a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c index 6c03035051b6..22d88d70c762 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c @@ -116,16 +116,16 @@ static int ar6000_connect_raw_service(AR_SOFTC_T *ar, { int status; HTC_SERVICE_CONNECT_RESP response; - A_UINT8 streamNo; + u8 streamNo; HTC_SERVICE_CONNECT_REQ connect; do { A_MEMZERO(&connect,sizeof(connect)); /* pass the stream ID as meta data to the RAW streams service */ - streamNo = (A_UINT8)StreamID; + streamNo = (u8)StreamID; connect.pMetaData = &streamNo; - connect.MetaDataLength = sizeof(A_UINT8); + connect.MetaDataLength = sizeof(u8); /* these fields are the same for all endpoints */ connect.EpCallbacks.pContext = ar; connect.EpCallbacks.EpTxComplete = ar6000_htc_raw_write_cb; diff --git a/drivers/staging/ath6kl/os/linux/ar6k_pal.c b/drivers/staging/ath6kl/os/linux/ar6k_pal.c index bca028afab6a..c43ec827a2e7 100644 --- a/drivers/staging/ath6kl/os/linux/ar6k_pal.c +++ b/drivers/staging/ath6kl/os/linux/ar6k_pal.c @@ -356,7 +356,7 @@ bool ar6k_pal_recv_pkt(void *pHciPal, void *osbuf) struct sk_buff *skb = (struct sk_buff *)osbuf; ar6k_hci_pal_info_t *pHciPalInfo; bool success = false; - A_UINT8 btType = 0; + u8 btType = 0; pHciPalInfo = (ar6k_hci_pal_info_t *)pHciPal; do { diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index f03e4c108bd6..f526160b8a73 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -185,9 +185,9 @@ ar6k_set_auth_type(AR_SOFTC_T *ar, enum nl80211_auth_type auth_type) static int ar6k_set_cipher(AR_SOFTC_T *ar, A_UINT32 cipher, bool ucast) { - A_UINT8 *ar_cipher = ucast ? &ar->arPairwiseCrypto : + u8 *ar_cipher = ucast ? &ar->arPairwiseCrypto : &ar->arGroupCrypto; - A_UINT8 *ar_cipher_len = ucast ? &ar->arPairwiseCryptoLen : + u8 *ar_cipher_len = ucast ? &ar->arPairwiseCryptoLen : &ar->arGroupCryptoLen; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, @@ -429,10 +429,10 @@ ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, void ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, - A_UINT8 *bssid, A_UINT16 listenInterval, + u8 *bssid, A_UINT16 listenInterval, A_UINT16 beaconInterval,NETWORK_TYPE networkType, - A_UINT8 beaconIeLen, A_UINT8 assocReqLen, - A_UINT8 assocRespLen, A_UINT8 *assocInfo) + u8 beaconIeLen, u8 assocReqLen, + u8 assocRespLen, u8 *assocInfo) { A_UINT16 size = 0; A_UINT16 capability = 0; @@ -440,19 +440,19 @@ ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, struct ieee80211_mgmt *mgmt = NULL; struct ieee80211_channel *ibss_channel = NULL; s32 signal = 50 * 100; - A_UINT8 ie_buf_len = 0; + u8 ie_buf_len = 0; unsigned char ie_buf[256]; unsigned char *ptr_ie_buf = ie_buf; unsigned char *ieeemgmtbuf = NULL; - A_UINT8 source_mac[ATH_MAC_LEN]; + u8 source_mac[ATH_MAC_LEN]; - A_UINT8 assocReqIeOffset = sizeof(A_UINT16) + /* capinfo*/ + u8 assocReqIeOffset = sizeof(A_UINT16) + /* capinfo*/ sizeof(A_UINT16); /* listen interval */ - A_UINT8 assocRespIeOffset = sizeof(A_UINT16) + /* capinfo*/ + u8 assocRespIeOffset = sizeof(A_UINT16) + /* capinfo*/ sizeof(A_UINT16) + /* status Code */ sizeof(A_UINT16); /* associd */ - A_UINT8 *assocReqIe = assocInfo + beaconIeLen + assocReqIeOffset; - A_UINT8 *assocRespIe = assocInfo + beaconIeLen + assocReqLen + assocRespIeOffset; + u8 *assocReqIe = assocInfo + beaconIeLen + assocReqIeOffset; + u8 *assocRespIe = assocInfo + beaconIeLen + assocReqLen + assocRespIeOffset; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); @@ -618,9 +618,9 @@ ar6k_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, } void -ar6k_cfg80211_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, - A_UINT8 *bssid, A_UINT8 assocRespLen, - A_UINT8 *assocInfo, A_UINT16 protocolReasonStatus) +ar6k_cfg80211_disconnect_event(AR_SOFTC_T *ar, u8 reason, + u8 *bssid, u8 assocRespLen, + u8 *assocInfo, A_UINT16 protocolReasonStatus) { AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason)); @@ -751,7 +751,7 @@ ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, if(request->n_ssids && request->ssids[0].ssid_len) { - A_UINT8 i; + u8 i; if(request->n_ssids > MAX_PROBED_SSID_INDEX) { request->n_ssids = MAX_PROBED_SSID_INDEX; @@ -795,7 +795,7 @@ ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, int status) if(ar->scan_request->n_ssids && ar->scan_request->ssids[0].ssid_len) { - A_UINT8 i; + u8 i; for (i = 0; i < ar->scan_request->n_ssids; i++) { wmi_probedSsid_cmd(ar->arWmi, i, DISABLE_SSID_FLAG, @@ -808,13 +808,13 @@ ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, int status) static int ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, - A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr, + u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); struct ar_key *key = NULL; - A_UINT8 key_usage; - A_UINT8 key_type; + u8 key_usage; + u8 key_type; int status = 0; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s:\n", __func__)); @@ -889,7 +889,7 @@ ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, ar->arDefTxKeyIndex = key_index; status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex, key_type, key_usage, key->key_len, key->seq, key->key, KEY_OP_INIT_VAL, - (A_UINT8*)mac_addr, SYNC_BOTH_WMIFLAG); + (u8 *)mac_addr, SYNC_BOTH_WMIFLAG); if(status != A_OK) { @@ -901,7 +901,7 @@ ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, static int ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, - A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr) + u8 key_index, bool pairwise, const u8 *mac_addr) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); @@ -936,7 +936,7 @@ ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, static int ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, - A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr, + u8 key_index, bool pairwise, const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params*)) { @@ -978,7 +978,7 @@ ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, static int ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, - A_UINT8 key_index, bool unicast, bool multicast) + u8 key_index, bool unicast, bool multicast) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); struct ar_key *key = NULL; @@ -1024,7 +1024,7 @@ ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, static int ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev, - A_UINT8 key_index) + u8 key_index) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); @@ -1045,7 +1045,7 @@ ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev, } void -ar6k_cfg80211_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, bool ismcast) +ar6k_cfg80211_tkip_micerr_event(AR_SOFTC_T *ar, u8 keyid, bool ismcast) { AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast)); @@ -1084,7 +1084,7 @@ ar6k_cfg80211_set_wiphy_params(struct wiphy *wiphy, A_UINT32 changed) static int ar6k_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, - const A_UINT8 *peer, + const u8 *peer, const struct cfg80211_bitrate_mask *mask) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Setting rates: Not supported\n")); @@ -1096,7 +1096,7 @@ static int ar6k_cfg80211_set_txpower(struct wiphy *wiphy, enum nl80211_tx_power_setting type, int dbm) { AR_SOFTC_T *ar = (AR_SOFTC_T *)wiphy_priv(wiphy); - A_UINT8 ar_dbm; + u8 ar_dbm; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x, dbm %d\n", __func__, type, dbm)); diff --git a/drivers/staging/ath6kl/os/linux/eeprom.c b/drivers/staging/ath6kl/os/linux/eeprom.c index 75eb092ea2a2..5a9ba162b793 100644 --- a/drivers/staging/ath6kl/os/linux/eeprom.c +++ b/drivers/staging/ath6kl/os/linux/eeprom.c @@ -63,7 +63,7 @@ static HIF_DEVICE *p_bmi_device; /* soft mac */ static int -wmic_ether_aton(const char *orig, A_UINT8 *eth) +wmic_ether_aton(const char *orig, u8 *eth) { const char *bufp; int i; @@ -148,7 +148,7 @@ BMI_read_mem(A_UINT32 address, A_UINT32 *pvalue) /* Write a word to a Target memory. */ inline void -BMI_write_mem(A_UINT32 address, A_UINT8 *p_data, A_UINT32 sz) +BMI_write_mem(A_UINT32 address, u8 *p_data, A_UINT32 sz) { BMIWriteMemory(p_bmi_device, address, (A_UCHAR*)(p_data), sz); } @@ -289,7 +289,7 @@ request_in_progress(void) static void eeprom_type_detect(void) { A_UINT32 regval; - A_UINT8 i = 0; + u8 i = 0; request_8byte_read(0x100); /* Wait for DONE_INT in SI_CS */ @@ -558,13 +558,13 @@ void eeprom_ar6000_transfer(HIF_DEVICE *device, char *fake_file, char *p_mac) /* soft mac */ /* Write EEPROM data to Target RAM */ - BMI_write_mem(board_data_addr, ((A_UINT8 *)eeprom_data), EEPROM_SZ); + BMI_write_mem(board_data_addr, ((u8 *)eeprom_data), EEPROM_SZ); /* Record the fact that Board Data IS initialized */ { A_UINT32 one = 1; BMI_write_mem(HOST_INTEREST_ITEM_ADDRESS(hi_board_data_initialized), - (A_UINT8 *)&one, sizeof(A_UINT32)); + (u8 *)&one, sizeof(A_UINT32)); } disable_SI(); diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index 6e77bff6ef63..ffccfbd8d4d9 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -80,7 +80,7 @@ typedef struct { bool HciNormalMode; /* Actual HCI mode enabled (non-TEST)*/ bool HciRegistered; /* HCI device registered with stack */ HTC_PACKET_QUEUE HTCPacketStructHead; - A_UINT8 *pHTCStructAlloc; + u8 *pHTCStructAlloc; spinlock_t BridgeLock; #ifdef EXPORT_HCI_BRIDGE_INTERFACE HCI_TRANSPORT_MISC_HANDLES HCITransHdl; @@ -509,7 +509,7 @@ int ar6000_setup_hci(AR_SOFTC_T *ar) AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in test mode... \n")); } - pHcidevInfo->pHTCStructAlloc = (A_UINT8 *)A_MALLOC((sizeof(HTC_PACKET)) * NUM_HTC_PACKET_STRUCTS); + pHcidevInfo->pHTCStructAlloc = (u8 *)A_MALLOC((sizeof(HTC_PACKET)) * NUM_HTC_PACKET_STRUCTS); if (NULL == pHcidevInfo->pHTCStructAlloc) { status = A_NO_MEMORY; @@ -963,7 +963,7 @@ static bool bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, HCI_TRANSPORT_PACKET_TYPE Type, struct sk_buff *skb) { - A_UINT8 btType; + u8 btType; int len; bool success = false; BT_HCI_EVENT_HEADER *pEvent; diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 6b34629bd7c4..2240bcfb9d00 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -380,26 +380,26 @@ enum { #endif /* CONFIG_HOST_TCMD_SUPPORT */ struct ar_wep_key { - A_UINT8 arKeyIndex; - A_UINT8 arKeyLen; - A_UINT8 arKey[64]; + u8 arKeyIndex; + u8 arKeyLen; + u8 arKey[64]; } ; #ifdef ATH6K_CONFIG_CFG80211 struct ar_key { - A_UINT8 key[WLAN_MAX_KEY_LEN]; - A_UINT8 key_len; - A_UINT8 seq[IW_ENCODE_SEQ_MAX_SIZE]; - A_UINT8 seq_len; + u8 key[WLAN_MAX_KEY_LEN]; + u8 key_len; + u8 seq[IW_ENCODE_SEQ_MAX_SIZE]; + u8 seq_len; A_UINT32 cipher; }; #endif /* ATH6K_CONFIG_CFG80211 */ struct ar_node_mapping { - A_UINT8 macAddress[6]; - A_UINT8 epId; - A_UINT8 txPending; + u8 macAddress[6]; + u8 epId; + u8 txPending; }; struct ar_cookie { @@ -413,8 +413,8 @@ struct ar_hb_chlng_resp { A_UINT32 frequency; A_UINT32 seqNum; bool outstanding; - A_UINT8 missCnt; - A_UINT8 missThres; + u8 missCnt; + u8 missThres; }; /* Per STA data, used in AP mode */ @@ -437,12 +437,12 @@ struct ar_hb_chlng_resp { typedef struct { A_UINT16 flags; - A_UINT8 mac[ATH_MAC_LEN]; - A_UINT8 aid; - A_UINT8 keymgmt; - A_UINT8 ucipher; - A_UINT8 auth; - A_UINT8 wpa_ie[IEEE80211_MAX_IE]; + u8 mac[ATH_MAC_LEN]; + u8 aid; + u8 keymgmt; + u8 ucipher; + u8 auth; + u8 wpa_ie[IEEE80211_MAX_IE]; A_NETBUF_QUEUE_T psq; /* power save q */ A_MUTEX_T psqLock; } sta_t; @@ -465,7 +465,7 @@ typedef struct ar6_softc { void *arWmi; int arTxPending[ENDPOINT_MAX]; int arTotalTxDataPending; - A_UINT8 arNumDataEndPts; + u8 arNumDataEndPts; bool arWmiEnabled; bool arWmiReady; bool arConnected; @@ -475,18 +475,18 @@ typedef struct ar6_softc { struct semaphore arSem; int arSsidLen; u_char arSsid[32]; - A_UINT8 arNextMode; - A_UINT8 arNetworkType; - A_UINT8 arDot11AuthMode; - A_UINT8 arAuthMode; - A_UINT8 arPairwiseCrypto; - A_UINT8 arPairwiseCryptoLen; - A_UINT8 arGroupCrypto; - A_UINT8 arGroupCryptoLen; - A_UINT8 arDefTxKeyIndex; + u8 arNextMode; + u8 arNetworkType; + u8 arDot11AuthMode; + u8 arAuthMode; + u8 arPairwiseCrypto; + u8 arPairwiseCryptoLen; + u8 arGroupCrypto; + u8 arGroupCryptoLen; + u8 arDefTxKeyIndex; struct ar_wep_key arWepKeyList[WMI_MAX_KEY_INDEX + 1]; - A_UINT8 arBssid[6]; - A_UINT8 arReqBssid[6]; + u8 arBssid[6]; + u8 arReqBssid[6]; A_UINT16 arChannelHint; A_UINT16 arBssChannel; A_UINT16 arListenIntervalB; @@ -494,7 +494,7 @@ typedef struct ar6_softc { struct ar6000_version arVersion; A_UINT32 arTargetType; A_INT8 arRssi; - A_UINT8 arTxPwr; + u8 arTxPwr; bool arTxPwrSet; A_INT32 arBitRate; struct net_device_stats arNetStats; @@ -505,9 +505,9 @@ typedef struct ar6_softc { bool statsUpdatePending; TARGET_STATS arTargetStats; A_INT8 arMaxRetries; - A_UINT8 arPhyCapability; + u8 arPhyCapability; #ifdef CONFIG_HOST_TCMD_SUPPORT - A_UINT8 tcmdRxReport; + u8 tcmdRxReport; A_UINT32 tcmdRxTotalPkt; A_INT32 tcmdRxRssi; A_UINT32 tcmdPm; @@ -519,24 +519,24 @@ typedef struct ar6_softc { #endif AR6000_WLAN_STATE arWlanState; struct ar_node_mapping arNodeMap[MAX_NODE_NUM]; - A_UINT8 arIbssPsEnable; - A_UINT8 arNodeNum; - A_UINT8 arNexEpId; + u8 arIbssPsEnable; + u8 arNodeNum; + u8 arNexEpId; struct ar_cookie *arCookieList; A_UINT32 arCookieCount; A_UINT32 arRateMask; - A_UINT8 arSkipScan; + u8 arSkipScan; A_UINT16 arBeaconInterval; bool arConnectPending; bool arWmmEnabled; struct ar_hb_chlng_resp arHBChallengeResp; - A_UINT8 arKeepaliveConfigured; + u8 arKeepaliveConfigured; A_UINT32 arMgmtFilter; HTC_ENDPOINT_ID arAc2EpMapping[WMM_NUM_AC]; bool arAcStreamActive[WMM_NUM_AC]; - A_UINT8 arAcStreamPriMap[WMM_NUM_AC]; - A_UINT8 arHiAcStreamActivePri; - A_UINT8 arEp2AcMapping[ENDPOINT_MAX]; + u8 arAcStreamPriMap[WMM_NUM_AC]; + u8 arHiAcStreamActivePri; + u8 arEp2AcMapping[ENDPOINT_MAX]; HTC_ENDPOINT_ID arControlEp; #ifdef HTC_RAW_INTERFACE AR_RAW_HTC_T *arRawHtc; @@ -557,35 +557,35 @@ typedef struct ar6_softc { struct USER_SAVEDKEYS user_saved_keys; #endif USER_RSSI_THOLD rssi_map[12]; - A_UINT8 arUserBssFilter; + u8 arUserBssFilter; A_UINT16 ap_profile_flag; /* AP mode */ WMI_AP_ACL g_acl; /* AP mode */ sta_t sta_list[AP_MAX_NUM_STA]; /* AP mode */ - A_UINT8 sta_list_index; /* AP mode */ + u8 sta_list_index; /* AP mode */ struct ieee80211req_key ap_mode_bkey; /* AP mode */ A_NETBUF_QUEUE_T mcastpsq; /* power save q for Mcast frames */ A_MUTEX_T mcastpsqLock; bool DTIMExpired; /* flag to indicate DTIM expired */ - A_UINT8 intra_bss; /* enable/disable intra bss data forward */ + u8 intra_bss; /* enable/disable intra bss data forward */ void *aggr_cntxt; #ifndef EXPORT_HCI_BRIDGE_INTERFACE void *hcidev_info; #endif void *hcipal_info; WMI_AP_MODE_STAT arAPStats; - A_UINT8 ap_hidden_ssid; - A_UINT8 ap_country_code[3]; - A_UINT8 ap_wmode; - A_UINT8 ap_dtim_period; + u8 ap_hidden_ssid; + u8 ap_country_code[3]; + u8 ap_wmode; + u8 ap_dtim_period; A_UINT16 ap_beacon_interval; A_UINT16 arRTS; A_UINT16 arACS; /* AP mode - Auto Channel Selection */ HTC_PACKET_QUEUE amsdu_rx_buffer_queue; bool bIsDestroyProgress; /* flag to indicate ar6k destroy is in progress */ A_TIMER disconnect_timer; - A_UINT8 rxMetaVersion; + u8 rxMetaVersion; #ifdef WAPI_ENABLE - A_UINT8 arWapiEnable; + u8 arWapiEnable; #endif WMI_BTCOEX_CONFIG_EVENT arBtcoexConfig; WMI_BTCOEX_STATS_EVENT arBtcoexStats; @@ -606,11 +606,11 @@ typedef struct ar6_softc { A_UINT16 arWlanOffConfig; A_UINT16 arWow2Config; #endif - A_UINT8 scan_triggered; + u8 scan_triggered; WMI_SCAN_PARAMS_CMD scParams; #define AR_MCAST_FILTER_MAC_ADDR_SIZE 4 - A_UINT8 mcast_filters[MAC_MAX_FILTERS_PER_LIST][AR_MCAST_FILTER_MAC_ADDR_SIZE]; - A_UINT8 bdaddr[6]; + u8 mcast_filters[MAC_MAX_FILTERS_PER_LIST][AR_MCAST_FILTER_MAC_ADDR_SIZE]; + u8 bdaddr[6]; bool scanSpecificSsid; #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT void *arApDev; @@ -726,13 +726,12 @@ ssize_t ar6000_htc_raw_write(AR_SOFTC_T *ar, /* AP mode */ /*TODO: These routines should be moved to a file that is common across OS */ sta_t * -ieee80211_find_conn(AR_SOFTC_T *ar, A_UINT8 *node_addr); +ieee80211_find_conn(AR_SOFTC_T *ar, u8 *node_addr); sta_t * -ieee80211_find_conn_for_aid(AR_SOFTC_T *ar, A_UINT8 aid); +ieee80211_find_conn_for_aid(AR_SOFTC_T *ar, u8 aid); -A_UINT8 -remove_sta(AR_SOFTC_T *ar, A_UINT8 *mac, A_UINT16 reason); +u8 remove_sta(AR_SOFTC_T *ar, u8 *mac, A_UINT16 reason); /* HCI support */ @@ -752,8 +751,8 @@ ATH_DEBUG_DECLARE_EXTERN(hif); ATH_DEBUG_DECLARE_EXTERN(wlan); ATH_DEBUG_DECLARE_EXTERN(misc); -extern A_UINT8 bcast_mac[]; -extern A_UINT8 null_mac[]; +extern u8 bcast_mac[]; +extern u8 null_mac[]; #ifdef __cplusplus } diff --git a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h index 014b7a4b0a1a..26f5372049e9 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h @@ -29,35 +29,35 @@ extern "C" { struct ar6_softc; -void ar6000_ready_event(void *devt, A_UINT8 *datap, A_UINT8 phyCap, +void ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, A_UINT32 sw_ver, A_UINT32 abi_ver); int ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid); void ar6000_connect_event(struct ar6_softc *ar, A_UINT16 channel, - A_UINT8 *bssid, A_UINT16 listenInterval, + u8 *bssid, A_UINT16 listenInterval, A_UINT16 beaconInterval, NETWORK_TYPE networkType, - A_UINT8 beaconIeLen, A_UINT8 assocReqLen, - A_UINT8 assocRespLen,A_UINT8 *assocInfo); -void ar6000_disconnect_event(struct ar6_softc *ar, A_UINT8 reason, - A_UINT8 *bssid, A_UINT8 assocRespLen, - A_UINT8 *assocInfo, A_UINT16 protocolReasonStatus); -void ar6000_tkip_micerr_event(struct ar6_softc *ar, A_UINT8 keyid, + u8 beaconIeLen, u8 assocReqLen, + u8 assocRespLen,u8 *assocInfo); +void ar6000_disconnect_event(struct ar6_softc *ar, u8 reason, + u8 *bssid, u8 assocRespLen, + u8 *assocInfo, A_UINT16 protocolReasonStatus); +void ar6000_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast); void ar6000_bitrate_rx(void *devt, A_INT32 rateKbps); void ar6000_channelList_rx(void *devt, A_INT8 numChan, A_UINT16 *chanList); void ar6000_regDomain_event(struct ar6_softc *ar, A_UINT32 regCode); -void ar6000_txPwr_rx(void *devt, A_UINT8 txPwr); -void ar6000_keepalive_rx(void *devt, A_UINT8 configured); +void ar6000_txPwr_rx(void *devt, u8 txPwr); +void ar6000_keepalive_rx(void *devt, u8 configured); void ar6000_neighborReport_event(struct ar6_softc *ar, int numAps, WMI_NEIGHBOR_INFO *info); void ar6000_set_numdataendpts(struct ar6_softc *ar, A_UINT32 num); void ar6000_scanComplete_event(struct ar6_softc *ar, int status); -void ar6000_targetStats_event(struct ar6_softc *ar, A_UINT8 *ptr, A_UINT32 len); +void ar6000_targetStats_event(struct ar6_softc *ar, u8 *ptr, A_UINT32 len); void ar6000_rssiThreshold_event(struct ar6_softc *ar, WMI_RSSI_THRESHOLD_VAL newThreshold, A_INT16 rssi); void ar6000_reportError_event(struct ar6_softc *, WMI_TARGET_ERROR_VAL errorVal); -void ar6000_cac_event(struct ar6_softc *ar, A_UINT8 ac, A_UINT8 cac_indication, - A_UINT8 statusCode, A_UINT8 *tspecSuggestion); +void ar6000_cac_event(struct ar6_softc *ar, u8 ac, u8 cac_indication, + u8 statusCode, u8 *tspecSuggestion); void ar6000_channel_change_event(struct ar6_softc *ar, A_UINT16 oldChannel, A_UINT16 newChannel); void ar6000_hbChallengeResp_event(struct ar6_softc *, A_UINT32 cookie, A_UINT32 source); void @@ -67,11 +67,11 @@ void ar6000_roam_data_event(struct ar6_softc *ar, WMI_TARGET_ROAM_DATA *p); void -ar6000_wow_list_event(struct ar6_softc *ar, A_UINT8 num_filters, +ar6000_wow_list_event(struct ar6_softc *ar, u8 num_filters, WMI_GET_WOW_LIST_REPLY *wow_reply); -void ar6000_pmkid_list_event(void *devt, A_UINT8 numPMKID, - WMI_PMKID *pmkidList, A_UINT8 *bssidList); +void ar6000_pmkid_list_event(void *devt, u8 numPMKID, + WMI_PMKID *pmkidList, u8 *bssidList); void ar6000_gpio_intr_rx(A_UINT32 intr_mask, A_UINT32 input_values); void ar6000_gpio_data_rx(A_UINT32 reg_id, A_UINT32 value); @@ -84,21 +84,21 @@ A_INT16 rssi_compensation_reverse_calc(struct ar6_softc *ar, A_INT16 rssi, bool void ar6000_dbglog_init_done(struct ar6_softc *ar); #ifdef SEND_EVENT_TO_APP -void ar6000_send_event_to_app(struct ar6_softc *ar, A_UINT16 eventId, A_UINT8 *datap, int len); -void ar6000_send_generic_event_to_app(struct ar6_softc *ar, A_UINT16 eventId, A_UINT8 *datap, int len); +void ar6000_send_event_to_app(struct ar6_softc *ar, A_UINT16 eventId, u8 *datap, int len); +void ar6000_send_generic_event_to_app(struct ar6_softc *ar, A_UINT16 eventId, u8 *datap, int len); #endif #ifdef CONFIG_HOST_TCMD_SUPPORT -void ar6000_tcmd_rx_report_event(void *devt, A_UINT8 * results, int len); +void ar6000_tcmd_rx_report_event(void *devt, u8 *results, int len); #endif void ar6000_tx_retry_err_event(void *devt); void ar6000_snrThresholdEvent_rx(void *devt, WMI_SNR_THRESHOLD_VAL newThreshold, - A_UINT8 snr); + u8 snr); -void ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL range, A_UINT8 lqVal); +void ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL range, u8 lqVal); void ar6000_ratemask_rx(void *devt, A_UINT32 ratemask); @@ -106,22 +106,22 @@ void ar6000_ratemask_rx(void *devt, A_UINT32 ratemask); int ar6000_get_driver_cfg(struct net_device *dev, A_UINT16 cfgParam, void *result); -void ar6000_bssInfo_event_rx(struct ar6_softc *ar, A_UINT8 *data, int len); +void ar6000_bssInfo_event_rx(struct ar6_softc *ar, u8 *data, int len); void ar6000_dbglog_event(struct ar6_softc *ar, A_UINT32 dropped, A_INT8 *buffer, A_UINT32 length); int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar); -void ar6000_peer_event(void *devt, A_UINT8 eventCode, A_UINT8 *bssid); +void ar6000_peer_event(void *devt, u8 eventCode, u8 *bssid); -void ar6000_indicate_tx_activity(void *devt, A_UINT8 trafficClass, bool Active); -HTC_ENDPOINT_ID ar6000_ac2_endpoint_id ( void * devt, A_UINT8 ac); -A_UINT8 ar6000_endpoint_id2_ac (void * devt, HTC_ENDPOINT_ID ep ); +void ar6000_indicate_tx_activity(void *devt, u8 trafficClass, bool Active); +HTC_ENDPOINT_ID ar6000_ac2_endpoint_id ( void * devt, u8 ac); +u8 ar6000_endpoint_id2_ac (void * devt, HTC_ENDPOINT_ID ep ); -void ar6000_btcoex_config_event(struct ar6_softc *ar, A_UINT8 *ptr, A_UINT32 len); +void ar6000_btcoex_config_event(struct ar6_softc *ar, u8 *ptr, A_UINT32 len); -void ar6000_btcoex_stats_event(struct ar6_softc *ar, A_UINT8 *ptr, A_UINT32 len) ; +void ar6000_btcoex_stats_event(struct ar6_softc *ar, u8 *ptr, A_UINT32 len) ; void ar6000_dset_open_req(void *devt, A_UINT32 id, @@ -152,11 +152,11 @@ struct ieee80211req_wpaie; int ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie); -int is_iwioctl_allowed(A_UINT8 mode, A_UINT16 cmd); +int is_iwioctl_allowed(u8 mode, A_UINT16 cmd); -int is_xioctl_allowed(A_UINT8 mode, int cmd); +int is_xioctl_allowed(u8 mode, int cmd); -void ar6000_pspoll_event(struct ar6_softc *ar,A_UINT8 aid); +void ar6000_pspoll_event(struct ar6_softc *ar,u8 aid); void ar6000_dtimexpiry_event(struct ar6_softc *ar); @@ -167,7 +167,7 @@ void ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd); #ifdef WAPI_ENABLE int ap_set_wapi_key(struct ar6_softc *ar, void *ik); -void ap_wapi_rekey_event(struct ar6_softc *ar, A_UINT8 type, A_UINT8 *mac); +void ap_wapi_rekey_event(struct ar6_softc *ar, u8 type, u8 *mac); #endif int ar6000_connect_to_ap(struct ar6_softc *ar); diff --git a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h index e9f7135dd02e..c8aec1ae04f3 100644 --- a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h @@ -727,8 +727,8 @@ typedef enum { /* * arguments: * struct { - * A_UINT8 streamType; - * A_UINT8 status; + * u8 streamType; + * u8 status; * } * uses: WMI_SET_BT_STATUS_CMDID */ @@ -737,9 +737,9 @@ typedef enum { /* * arguments: * struct { - * A_UINT8 paramType; + * u8 paramType; * union { - * A_UINT8 noSCOPkts; + * u8 noSCOPkts; * BT_PARAMS_A2DP a2dpParams; * BT_COEX_REGS regs; * }; @@ -1008,7 +1008,7 @@ struct ar6000_version { /* used by AR6000_IOCTL_WMI_GET_QOS_QUEUE */ struct ar6000_queuereq { - A_UINT8 trafficClass; + u8 trafficClass; A_UINT16 activeTsids; }; @@ -1072,12 +1072,12 @@ typedef struct targetStats_t { A_INT16 noise_floor_calibation; A_INT16 cs_rssi; A_INT16 cs_aveBeacon_rssi; - A_UINT8 cs_aveBeacon_snr; - A_UINT8 cs_lastRoam_msec; - A_UINT8 cs_snr; + u8 cs_aveBeacon_snr; + u8 cs_lastRoam_msec; + u8 cs_snr; - A_UINT8 wow_num_host_pkt_wakeups; - A_UINT8 wow_num_host_event_wakeups; + u8 wow_num_host_pkt_wakeups; + u8 wow_num_host_event_wakeups; A_UINT32 arp_received; A_UINT32 arp_matched; @@ -1144,7 +1144,7 @@ typedef struct user_rssi_thold_t { } USER_RSSI_THOLD; typedef struct user_rssi_params_t { - A_UINT8 weight; + u8 weight; A_UINT32 pollTime; USER_RSSI_THOLD tholds[12]; } USER_RSSI_PARAMS; diff --git a/drivers/staging/ath6kl/os/linux/include/cfg80211.h b/drivers/staging/ath6kl/os/linux/include/cfg80211.h index a32cdcdfd955..1a304436505c 100644 --- a/drivers/staging/ath6kl/os/linux/include/cfg80211.h +++ b/drivers/staging/ath6kl/os/linux/include/cfg80211.h @@ -30,16 +30,16 @@ void ar6k_cfg80211_deinit(AR_SOFTC_T *ar); void ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, int status); void ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, - A_UINT8 *bssid, A_UINT16 listenInterval, + u8 *bssid, A_UINT16 listenInterval, A_UINT16 beaconInterval,NETWORK_TYPE networkType, - A_UINT8 beaconIeLen, A_UINT8 assocReqLen, - A_UINT8 assocRespLen, A_UINT8 *assocInfo); + u8 beaconIeLen, u8 assocReqLen, + u8 assocRespLen, u8 *assocInfo); -void ar6k_cfg80211_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, - A_UINT8 *bssid, A_UINT8 assocRespLen, - A_UINT8 *assocInfo, A_UINT16 protocolReasonStatus); +void ar6k_cfg80211_disconnect_event(AR_SOFTC_T *ar, u8 reason, + u8 *bssid, u8 assocRespLen, + u8 *assocInfo, A_UINT16 protocolReasonStatus); -void ar6k_cfg80211_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, bool ismcast); +void ar6k_cfg80211_tkip_micerr_event(AR_SOFTC_T *ar, u8 keyid, bool ismcast); #endif /* _AR6K_CFG80211_H_ */ diff --git a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h index bf034cdfa893..5945a484c62e 100644 --- a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h @@ -76,7 +76,7 @@ #define A_CPU2BE16(x) htons(x) #define A_CPU2BE32(x) htonl(x) -#define A_MEMCPY(dst, src, len) memcpy((A_UINT8 *)(dst), (src), (len)) +#define A_MEMCPY(dst, src, len) memcpy((u8 *)(dst), (src), (len)) #define A_MEMZERO(addr, len) memset(addr, 0, len) #define A_MEMCMP(addr1, addr2, len) memcmp((addr1), (addr2), (len)) #define A_MALLOC(size) kmalloc((size), GFP_KERNEL) diff --git a/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h b/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h index 77e4ec6fea3a..0652c69f591d 100644 --- a/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h @@ -41,7 +41,7 @@ * (0xFF) - Allow this cmd always irrespective of mode */ -A_UINT8 sioctl_filter[] = { +u8 sioctl_filter[] = { (AP_NETWORK), /* SIOCSIWCOMMIT 0x8B00 */ (0xFF), /* SIOCGIWNAME 0x8B01 */ (0), /* SIOCSIWNWID 0x8B02 */ @@ -96,7 +96,7 @@ A_UINT8 sioctl_filter[] = { -A_UINT8 pioctl_filter[] = { +u8 pioctl_filter[] = { (INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0) */ (INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_SETKEY (SIOCIWFIRSTPRIV+1) */ (INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_DELKEY (SIOCIWFIRSTPRIV+2) */ @@ -132,7 +132,7 @@ A_UINT8 pioctl_filter[] = { -A_UINT8 xioctl_filter[] = { +u8 xioctl_filter[] = { (0xFF), /* Dummy 0 */ (0xFF), /* AR6000_XIOCTL_BMI_DONE 1 */ (0xFF), /* AR6000_XIOCTL_BMI_READ_MEMORY 2 */ diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index 4403d1a61e7c..c6e44ba2bd51 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -76,7 +76,7 @@ ar6000_ioctl_set_roam_ctrl(struct net_device *dev, char *userdata) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_SET_ROAM_CTRL_CMD cmd; - A_UINT8 size = sizeof(cmd); + u8 size = sizeof(cmd); if (ar->arWmiReady == false) { return -EIO; @@ -109,7 +109,7 @@ ar6000_ioctl_set_powersave_timers(struct net_device *dev, char *userdata) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_POWERSAVE_TIMERS_POLICY_CMD cmd; - A_UINT8 size = sizeof(cmd); + u8 size = sizeof(cmd); if (ar->arWmiReady == false) { return -EIO; @@ -663,7 +663,7 @@ ar6000_ioctl_get_qos_queue(struct net_device *dev, struct ifreq *rq) #ifdef CONFIG_HOST_TCMD_SUPPORT static int ar6000_ioctl_tcmd_get_rx_report(struct net_device *dev, - struct ifreq *rq, A_UINT8 *data, A_UINT32 len) + struct ifreq *rq, u8 *data, A_UINT32 len) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); A_UINT32 buf[4+TCMD_MAX_RATES]; @@ -715,7 +715,7 @@ ar6000_ioctl_tcmd_get_rx_report(struct net_device *dev, } void -ar6000_tcmd_rx_report_event(void *devt, A_UINT8 * results, int len) +ar6000_tcmd_rx_report_event(void *devt, u8 *results, int len) { AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; TCMD_CONT_RX * rx_rep = (TCMD_CONT_RX *)results; @@ -843,7 +843,7 @@ ar6000_ioctl_get_ap_stats(struct net_device *dev, struct ifreq *rq) return -EFAULT; } if (action == AP_CLEAR_STATS) { - A_UINT8 i; + u8 i; AR6000_SPIN_LOCK(&ar->arLock, 0); for(i = 0; i < AP_MAX_NUM_STA; i++) { pStats->sta[i].tx_bytes = 0; @@ -1469,12 +1469,12 @@ prof_count_rx(A_UINT32 addr, A_UINT32 count) static int -ar6000_create_acl_data_osbuf(struct net_device *dev, A_UINT8 *userdata, void **p_osbuf) +ar6000_create_acl_data_osbuf(struct net_device *dev, u8 *userdata, void **p_osbuf) { void *osbuf = NULL; - A_UINT8 tmp_space[8]; + u8 tmp_space[8]; HCI_ACL_DATA_PKT *acl; - A_UINT8 hdr_size, *datap=NULL; + u8 hdr_size, *datap=NULL; int ret = A_OK; /* ACL is in data path. There is a need to create pool @@ -1497,7 +1497,7 @@ ar6000_create_acl_data_osbuf(struct net_device *dev, A_UINT8 *userdata, void **p break; } A_NETBUF_PUT(osbuf, hdr_size + acl->data_len); - datap = (A_UINT8 *)A_NETBUF_DATA(osbuf); + datap = (u8 *)A_NETBUF_DATA(osbuf); /* Real copy to osbuf */ acl = (HCI_ACL_DATA_PKT *)(datap); @@ -1822,7 +1822,7 @@ ar6000_ioctl_setkey(AR_SOFTC_T *ar, struct ieee80211req_key *ik) } status = wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, keyType, keyUsage, - ik->ik_keylen, (A_UINT8 *)&ik->ik_keyrsc, + ik->ik_keylen, (u8 *)&ik->ik_keyrsc, ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr, SYNC_BOTH_WMIFLAG); @@ -2027,7 +2027,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; goto ioctl_done; } else { - wmi_test_cmd(ar->arWmi,(A_UINT8 *)&txCmd, sizeof(TCMD_CONT_TX)); + wmi_test_cmd(ar->arWmi,(u8 *)&txCmd, sizeof(TCMD_CONT_TX)); } } break; @@ -2053,13 +2053,13 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case TCMD_CONT_RX_FILTER: case TCMD_CONT_RX_SETMAC: case TCMD_CONT_RX_SET_ANT_SWITCH_TABLE: - wmi_test_cmd(ar->arWmi,(A_UINT8 *)&rxCmd, + wmi_test_cmd(ar->arWmi,(u8 *)&rxCmd, sizeof(TCMD_CONT_RX)); tcmdRxFreq = rxCmd.u.para.freq; break; case TCMD_CONT_RX_REPORT: ar6000_ioctl_tcmd_get_rx_report(dev, rq, - (A_UINT8 *)&rxCmd, sizeof(TCMD_CONT_RX)); + (u8 *)&rxCmd, sizeof(TCMD_CONT_RX)); break; default: A_PRINTF("Unknown Cont Rx mode: %d\n",rxCmd.act); @@ -2077,7 +2077,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) goto ioctl_done; } ar->tcmdPm = pmCmd.mode; - wmi_test_cmd(ar->arWmi, (A_UINT8*)&pmCmd, sizeof(TCMD_PM)); + wmi_test_cmd(ar->arWmi, (u8 *)&pmCmd, sizeof(TCMD_PM)); } break; #endif /* CONFIG_HOST_TCMD_SUPPORT */ @@ -2705,7 +2705,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_IOCTL_WMI_SET_ASSOC_INFO: { WMI_SET_ASSOC_INFO_CMD cmd; - A_UINT8 assocInfo[WMI_MAX_ASSOC_INFO_LEN]; + u8 assocInfo[WMI_MAX_ASSOC_INFO_LEN]; if (ar->arWmiReady == false) { ret = -EIO; @@ -3141,7 +3141,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_OPT_SEND_FRAME: { WMI_OPT_TX_FRAME_CMD optTxFrmCmd; - A_UINT8 data[MAX_OPT_DATA_LEN]; + u8 data[MAX_OPT_DATA_LEN]; if (ar->arWmiReady == false) { ret = -EIO; @@ -3646,7 +3646,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_WMI_SET_APPIE: { WMI_SET_APPIE_CMD appIEcmd; - A_UINT8 appIeInfo[IEEE80211_APPIE_FRAME_MAX_LEN]; + u8 appIeInfo[IEEE80211_APPIE_FRAME_MAX_LEN]; A_UINT32 fType,ieLen; if (ar->arWmiReady == false) { @@ -3883,8 +3883,8 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) #define WOW_MASK_SIZE 64 WMI_ADD_WOW_PATTERN_CMD cmd; - A_UINT8 mask_data[WOW_PATTERN_SIZE]={0}; - A_UINT8 pattern_data[WOW_PATTERN_SIZE]={0}; + u8 mask_data[WOW_PATTERN_SIZE]={0}; + u8 pattern_data[WOW_PATTERN_SIZE]={0}; do { if (ar->arWmiReady == false) { @@ -3997,7 +3997,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) /* note, this is used for testing (mbox ping testing), indicate activity * change using the stream ID as the traffic class */ ar6000_indicate_tx_activity(ar, - (A_UINT8)data.StreamID, + (u8)data.StreamID, data.Active ? true : false); } break; @@ -4064,7 +4064,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) break; case AR6000_XIOCTL_AP_HIDDEN_SSID: { - A_UINT8 hidden_ssid; + u8 hidden_ssid; if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&hidden_ssid, userdata, sizeof(hidden_ssid))) { @@ -4081,7 +4081,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (ar->arWmiReady == false) { ret = -EIO; } else { - A_UINT8 i; + u8 i; ap_get_sta_t temp; A_MEMZERO(&temp, sizeof(temp)); for(i=0;iarWmiReady == false) { ret = -EIO; } else if (copy_from_user(&num_sta, userdata, sizeof(num_sta))) { @@ -4115,7 +4115,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } case AR6000_XIOCTL_AP_SET_ACL_POLICY: { - A_UINT8 policy; + u8 policy; if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&policy, userdata, sizeof(policy))) { @@ -4243,7 +4243,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } case AR6000_XIOCTL_AP_INTRA_BSS_COMM: { - A_UINT8 intra=0; + u8 intra=0; if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&intra, userdata, sizeof(intra))) { @@ -4395,7 +4395,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) void *osbuf = NULL; if (ar->arWmiReady == false) { ret = -EIO; - } else if (ar6000_create_acl_data_osbuf(dev, (A_UINT8*)userdata, &osbuf) != A_OK) { + } else if (ar6000_create_acl_data_osbuf(dev, (u8 *)userdata, &osbuf) != A_OK) { ret = -EIO; } else { if (wmi_data_hdr_add(ar->arWmi, osbuf, DATA_MSGTYPE, 0, WMI_DATA_HDR_DATA_TYPE_ACL,0,NULL) != A_OK) { @@ -4412,7 +4412,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) char tmp_buf[512]; A_INT8 i; WMI_HCI_CMD *cmd = (WMI_HCI_CMD *)tmp_buf; - A_UINT8 size; + u8 size; size = sizeof(cmd->cmd_buf_sz); if (ar->arWmiReady == false) { @@ -4511,8 +4511,8 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { if (ar->arWmiReady == false) { ret = -EIO; - } else if(copy_to_user((A_UINT8 *)rq->ifr_data, - &ar->ap_wmode, sizeof(A_UINT8))) { + } else if(copy_to_user((u8 *)rq->ifr_data, + &ar->ap_wmode, sizeof(u8))) { ret = -EFAULT; } break; @@ -4594,7 +4594,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } rq->ifr_ifru.ifru_ivalue = ar->arWlanState; /* return value */ - ar6000_send_event_to_app(ar, WMI_REPORT_SLEEP_STATE_EVENTID, (A_UINT8*)&wmiSleepEvent, + ar6000_send_event_to_app(ar, WMI_REPORT_SLEEP_STATE_EVENTID, (u8 *)&wmiSleepEvent, sizeof(WMI_REPORT_SLEEP_STATE_EVENTID)); break; } @@ -4671,9 +4671,9 @@ ioctl_done: return ret; } -A_UINT8 mac_cmp_wild(A_UINT8 *mac, A_UINT8 *new_mac, A_UINT8 wild, A_UINT8 new_wild) +u8 mac_cmp_wild(u8 *mac, u8 *new_mac, u8 wild, u8 new_wild) { - A_UINT8 i; + u8 i; for(i=0;i 14 */ -static A_UINT8 -get_bss_phy_capability(bss_t *bss) +static u8 get_bss_phy_capability(bss_t *bss) { - A_UINT8 capability = 0; + u8 capability = 0; struct ieee80211_common_ie *cie = &bss->ni_cie; #define CHAN_IS_11A(x) (!((x >= 2412) && (x <= 2484))) if (CHAN_IS_11A(cie->ie_chan)) { @@ -464,8 +463,8 @@ ar6000_ioctl_siwessid(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); int status; - A_UINT8 arNetworkType; - A_UINT8 prevMode = ar->arNetworkType; + u8 arNetworkType; + u8 prevMode = ar->arNetworkType; if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); @@ -512,7 +511,7 @@ ar6000_ioctl_siwessid(struct net_device *dev, } return 0; } else if(ar->arNetworkType == AP_NETWORK) { - A_UINT8 ctr; + u8 ctr; struct sk_buff *skb; /* We are switching from AP to STA | IBSS mode, cleanup the AP state */ @@ -683,8 +682,8 @@ ar6000_ioctl_giwessid(struct net_device *dev, void ar6000_install_static_wep_keys(AR_SOFTC_T *ar) { - A_UINT8 index; - A_UINT8 keyUsage; + u8 index; + u8 keyUsage; for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) { if (ar->arWepKeyList[index].arKeyLen) { @@ -813,7 +812,7 @@ ar6000_ioctl_siwtxpow(struct net_device *dev, struct iw_param *rrq, char *extra) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - A_UINT8 dbM; + u8 dbM; if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); @@ -1123,7 +1122,7 @@ ar6000_ioctl_giwencode(struct net_device *dev, struct iw_point *erq, char *key) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - A_UINT8 keyIndex; + u8 keyIndex; struct ar_wep_key *wk; if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { @@ -1195,10 +1194,10 @@ ar6000_ioctl_siwgenie(struct net_device *dev, AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); #ifdef WAPI_ENABLE - A_UINT8 *ie = erq->pointer; - A_UINT8 ie_type = ie[0]; + u8 *ie = erq->pointer; + u8 ie_type = ie[0]; A_UINT16 ie_length = erq->length; - A_UINT8 wapi_ie[128]; + u8 wapi_ie[128]; #endif if (ar->arWmiReady == false) { @@ -1562,10 +1561,10 @@ ar6000_ioctl_siwpmksa(struct net_device *dev, switch (pmksa->cmd) { case IW_PMKSA_ADD: - status = wmi_setPmkid_cmd(ar->arWmi, (A_UINT8*)pmksa->bssid.sa_data, pmksa->pmkid, true); + status = wmi_setPmkid_cmd(ar->arWmi, (u8 *)pmksa->bssid.sa_data, pmksa->pmkid, true); break; case IW_PMKSA_REMOVE: - status = wmi_setPmkid_cmd(ar->arWmi, (A_UINT8*)pmksa->bssid.sa_data, pmksa->pmkid, false); + status = wmi_setPmkid_cmd(ar->arWmi, (u8 *)pmksa->bssid.sa_data, pmksa->pmkid, false); break; case IW_PMKSA_FLUSH: if (ar->arConnected == true) { @@ -1595,14 +1594,14 @@ static int ar6000_set_wapi_key(struct net_device *dev, struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; KEY_USAGE keyUsage = 0; A_INT32 keyLen; - A_UINT8 *keyData; + u8 *keyData; A_INT32 index; A_UINT32 *PN; A_INT32 i; int status; - A_UINT8 wapiKeyRsc[16]; + u8 wapiKeyRsc[16]; CRYPTO_TYPE keyType = WAPI_CRYPT; - const A_UINT8 broadcastMac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + const u8 broadcastMac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; index = erq->flags & IW_ENCODE_INDEX; if (index && (((index - 1) < WMI_MIN_KEY_INDEX) || @@ -1614,7 +1613,7 @@ static int ar6000_set_wapi_key(struct net_device *dev, if (index < 0 || index > 4) { return -EIO; } - keyData = (A_UINT8 *)(ext + 1); + keyData = (u8 *)(ext + 1); keyLen = erq->length - sizeof(struct iw_encode_ext); A_MEMCPY(wapiKeyRsc, ext->tx_seq, sizeof(wapiKeyRsc)); @@ -1658,8 +1657,8 @@ ar6000_ioctl_siwencodeext(struct net_device *dev, struct iw_encode_ext *ext; KEY_USAGE keyUsage; A_INT32 keyLen; - A_UINT8 *keyData; - A_UINT8 keyRsc[8]; + u8 *keyData; + u8 keyRsc[8]; int status; CRYPTO_TYPE keyType; #ifdef USER_KEYS @@ -1721,7 +1720,7 @@ ar6000_ioctl_siwencodeext(struct net_device *dev, } /* key follows iw_encode_ext */ - keyData = (A_UINT8 *)(ext + 1); + keyData = (u8 *)(ext + 1); switch (ext->alg) { case IW_ENCODE_ALG_WEP: @@ -1792,7 +1791,7 @@ ar6000_ioctl_siwencodeext(struct net_device *dev, status = wmi_addKey_cmd(ar->arWmi, index, keyType, keyUsage, keyLen, keyRsc, keyData, KEY_OP_INIT_VAL, - (A_UINT8*)ext->addr.sa_data, + (u8 *)ext->addr.sa_data, SYNC_BOTH_WMIFLAG); if (status != A_OK) { return -EIO; @@ -1906,7 +1905,7 @@ ar6000_ioctl_giwname(struct net_device *dev, struct iw_request_info *info, char *name, char *extra) { - A_UINT8 capability; + u8 capability; AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { @@ -2393,7 +2392,7 @@ ar6000_ioctl_siwmlme(struct net_device *dev, if (data->pointer && data->length == sizeof(struct iw_mlme)) { - A_UINT8 arNetworkType; + u8 arNetworkType; struct iw_mlme mlme; if (copy_from_user(&mlme, data->pointer, sizeof(struct iw_mlme))) diff --git a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h index 5f9bf9b4dc98..f65e290ebdeb 100644 --- a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h +++ b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h @@ -101,8 +101,8 @@ typedef struct { }RXTID_STATS; typedef struct { - A_UINT8 aggr_sz; /* config value of aggregation size */ - A_UINT8 timerScheduled; + u8 aggr_sz; /* config value of aggregation size */ + u8 timerScheduled; A_TIMER timer; /* timer for returning held up pkts in re-order que */ void *dev; /* dev handle */ RX_CALLBACK rx_fn; /* callback function to return frames; to upper layer */ diff --git a/drivers/staging/ath6kl/reorder/rcv_aggr.c b/drivers/staging/ath6kl/reorder/rcv_aggr.c index 48980d2bdf6a..0ae9fdf14114 100644 --- a/drivers/staging/ath6kl/reorder/rcv_aggr.c +++ b/drivers/staging/ath6kl/reorder/rcv_aggr.c @@ -43,7 +43,7 @@ static void aggr_timeout(A_ATH_TIMER arg); static void -aggr_deque_frms(AGGR_INFO *p_aggr, A_UINT8 tid, A_UINT16 seq_no, A_UINT8 order); +aggr_deque_frms(AGGR_INFO *p_aggr, u8 tid, A_UINT16 seq_no, u8 order); static void aggr_dispatch_frames(AGGR_INFO *p_aggr, A_NETBUF_QUEUE_T *q); @@ -56,7 +56,7 @@ aggr_init(ALLOC_NETBUFS netbuf_allocator) { AGGR_INFO *p_aggr = NULL; RXTID *rxtid; - A_UINT8 i; + u8 i; int status = A_OK; A_PRINTF("In aggr_init..\n"); @@ -101,7 +101,7 @@ aggr_init(ALLOC_NETBUFS netbuf_allocator) /* utility function to clear rx hold_q for a tid */ static void -aggr_delete_tid_state(AGGR_INFO *p_aggr, A_UINT8 tid) +aggr_delete_tid_state(AGGR_INFO *p_aggr, u8 tid) { RXTID *rxtid; RXTID_STATS *stats; @@ -135,7 +135,7 @@ aggr_module_destroy(void *cntxt) { AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; RXTID *rxtid; - A_UINT8 i, k; + u8 i, k; A_PRINTF("%s(): aggr = %p\n",_A_FUNCNAME_, p_aggr); A_ASSERT(p_aggr); @@ -187,7 +187,7 @@ aggr_register_rx_dispatcher(void *cntxt, void * dev, RX_CALLBACK fn) void -aggr_process_bar(void *cntxt, A_UINT8 tid, A_UINT16 seq_no) +aggr_process_bar(void *cntxt, u8 tid, A_UINT16 seq_no) { AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; RXTID_STATS *stats; @@ -201,7 +201,7 @@ aggr_process_bar(void *cntxt, A_UINT8 tid, A_UINT16 seq_no) void -aggr_recv_addba_req_evt(void *cntxt, A_UINT8 tid, A_UINT16 seq_no, A_UINT8 win_sz) +aggr_recv_addba_req_evt(void *cntxt, u8 tid, A_UINT16 seq_no, u8 win_sz) { AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; RXTID *rxtid; @@ -253,7 +253,7 @@ aggr_recv_addba_req_evt(void *cntxt, A_UINT8 tid, A_UINT16 seq_no, A_UINT8 win_s } void -aggr_recv_delba_req_evt(void *cntxt, A_UINT8 tid) +aggr_recv_delba_req_evt(void *cntxt, u8 tid) { AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; RXTID *rxtid; @@ -269,7 +269,7 @@ aggr_recv_delba_req_evt(void *cntxt, A_UINT8 tid) } static void -aggr_deque_frms(AGGR_INFO *p_aggr, A_UINT8 tid, A_UINT16 seq_no, A_UINT8 order) +aggr_deque_frms(AGGR_INFO *p_aggr, u8 tid, A_UINT16 seq_no, u8 order) { RXTID *rxtid; OSBUF_HOLD_Q *node; @@ -360,7 +360,7 @@ aggr_slice_amsdu(AGGR_INFO *p_aggr, RXTID *rxtid, void **osbuf) { void *new_buf; A_UINT16 frame_8023_len, payload_8023_len, mac_hdr_len, amsdu_len; - A_UINT8 *framep; + u8 *framep; /* Frame format at this point: * [DIX hdr | 802.3 | 802.3 | ... | 802.3] @@ -426,7 +426,7 @@ aggr_slice_amsdu(AGGR_INFO *p_aggr, RXTID *rxtid, void **osbuf) } void -aggr_process_recv_frm(void *cntxt, A_UINT8 tid, A_UINT16 seq_no, bool is_amsdu, void **osbuf) +aggr_process_recv_frm(void *cntxt, u8 tid, A_UINT16 seq_no, bool is_amsdu, void **osbuf) { AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; RXTID *rxtid; @@ -561,7 +561,7 @@ aggr_process_recv_frm(void *cntxt, A_UINT8 tid, A_UINT16 seq_no, bool is_amsdu, void aggr_reset_state(void *cntxt) { - A_UINT8 tid; + u8 tid; AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; A_ASSERT(p_aggr); @@ -575,7 +575,7 @@ aggr_reset_state(void *cntxt) static void aggr_timeout(A_ATH_TIMER arg) { - A_UINT8 i,j; + u8 i,j; AGGR_INFO *p_aggr = (AGGR_INFO *)arg; RXTID *rxtid; RXTID_STATS *stats; @@ -645,7 +645,7 @@ aggr_dump_stats(void *cntxt, PACKET_LOG **log_buf) AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; RXTID *rxtid; RXTID_STATS *stats; - A_UINT8 i; + u8 i; *log_buf = &p_aggr->pkt_log; A_PRINTF("\n\n================================================\n"); diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211.h b/drivers/staging/ath6kl/wlan/include/ieee80211.h index c4fd13fe0a91..75cece166c59 100644 --- a/drivers/staging/ath6kl/wlan/include/ieee80211.h +++ b/drivers/staging/ath6kl/wlan/include/ieee80211.h @@ -99,24 +99,24 @@ * generic definitions for IEEE 802.11 frames */ PREPACK struct ieee80211_frame { - A_UINT8 i_fc[2]; - A_UINT8 i_dur[2]; - A_UINT8 i_addr1[IEEE80211_ADDR_LEN]; - A_UINT8 i_addr2[IEEE80211_ADDR_LEN]; - A_UINT8 i_addr3[IEEE80211_ADDR_LEN]; - A_UINT8 i_seq[2]; + u8 i_fc[2]; + u8 i_dur[2]; + u8 i_addr1[IEEE80211_ADDR_LEN]; + u8 i_addr2[IEEE80211_ADDR_LEN]; + u8 i_addr3[IEEE80211_ADDR_LEN]; + u8 i_seq[2]; /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */ /* see below */ } POSTPACK; PREPACK struct ieee80211_qosframe { - A_UINT8 i_fc[2]; - A_UINT8 i_dur[2]; - A_UINT8 i_addr1[IEEE80211_ADDR_LEN]; - A_UINT8 i_addr2[IEEE80211_ADDR_LEN]; - A_UINT8 i_addr3[IEEE80211_ADDR_LEN]; - A_UINT8 i_seq[2]; - A_UINT8 i_qos[2]; + u8 i_fc[2]; + u8 i_dur[2]; + u8 i_addr1[IEEE80211_ADDR_LEN]; + u8 i_addr2[IEEE80211_ADDR_LEN]; + u8 i_addr3[IEEE80211_ADDR_LEN]; + u8 i_seq[2]; + u8 i_qos[2]; } POSTPACK; #define IEEE80211_FC0_VERSION_MASK 0x03 @@ -320,14 +320,14 @@ typedef enum { * WMM/802.11e Tspec Element */ typedef PREPACK struct wmm_tspec_ie_t { - A_UINT8 elementId; - A_UINT8 len; - A_UINT8 oui[3]; - A_UINT8 ouiType; - A_UINT8 ouiSubType; - A_UINT8 version; + u8 elementId; + u8 len; + u8 oui[3]; + u8 ouiType; + u8 ouiSubType; + u8 version; A_UINT16 tsInfo_info; - A_UINT8 tsInfo_reserved; + u8 tsInfo_reserved; A_UINT16 nominalMSDU; A_UINT16 maxMSDU; A_UINT32 minServiceInt; diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211_node.h b/drivers/staging/ath6kl/wlan/include/ieee80211_node.h index 683deec87b2d..e2d9617a8518 100644 --- a/drivers/staging/ath6kl/wlan/include/ieee80211_node.h +++ b/drivers/staging/ath6kl/wlan/include/ieee80211_node.h @@ -55,7 +55,7 @@ #define IEEE80211_NODE_HASHSIZE 32 /* simple hash is enough for variation of macaddr */ #define IEEE80211_NODE_HASH(addr) \ - (((const A_UINT8 *)(addr))[IEEE80211_ADDR_LEN - 1] % \ + (((const u8 *)(addr))[IEEE80211_ADDR_LEN - 1] % \ IEEE80211_NODE_HASHSIZE) /* @@ -74,7 +74,7 @@ struct ieee80211_node_table { A_UINT32 nt_scangen; /* gen# for timeout scan */ #ifdef THREAD_X A_TIMER nt_inact_timer; - A_UINT8 isTimerArmed; /* is the node timer armed */ + u8 isTimerArmed; /* is the node timer armed */ #endif A_UINT32 nt_nodeAge; /* node aging time */ #ifdef OS_ROAM_MANAGEMENT diff --git a/drivers/staging/ath6kl/wlan/src/wlan_node.c b/drivers/staging/ath6kl/wlan/src/wlan_node.c index 4cc45c08715d..a29f71245d8b 100644 --- a/drivers/staging/ath6kl/wlan/src/wlan_node.c +++ b/drivers/staging/ath6kl/wlan/src/wlan_node.c @@ -58,7 +58,7 @@ static void wlan_node_timeout(A_ATH_TIMER arg); #endif static bss_t * _ieee80211_find_node (struct ieee80211_node_table *nt, - const A_UINT8 *macaddr); + const u8 *macaddr); bss_t * wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size) @@ -111,7 +111,7 @@ wlan_node_free(bss_t *ni) void wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni, - const A_UINT8 *macaddr) + const u8 *macaddr) { int hash; A_UINT32 timeoutValue = 0; @@ -160,7 +160,7 @@ wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni, static bss_t * _ieee80211_find_node(struct ieee80211_node_table *nt, - const A_UINT8 *macaddr) + const u8 *macaddr) { bss_t *ni; int hash; @@ -178,7 +178,7 @@ _ieee80211_find_node(struct ieee80211_node_table *nt, } bss_t * -wlan_find_node(struct ieee80211_node_table *nt, const A_UINT8 *macaddr) +wlan_find_node(struct ieee80211_node_table *nt, const u8 *macaddr) { bss_t *ni; @@ -326,7 +326,7 @@ wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt) { #ifdef THREAD_X bss_t *bss, *nextBss; - A_UINT8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = false; + u8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = false; wmi_get_current_bssid(nt->nt_wmip, myBssid); @@ -346,7 +346,7 @@ wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt) } #else bss_t *bss, *nextBss; - A_UINT8 myBssid[IEEE80211_ADDR_LEN]; + u8 myBssid[IEEE80211_ADDR_LEN]; A_UINT32 timeoutValue = 0; A_UINT32 now = A_GET_MS(0); timeoutValue = nt->nt_nodeAge; @@ -379,7 +379,7 @@ wlan_node_timeout (A_ATH_TIMER arg) { struct ieee80211_node_table *nt = (struct ieee80211_node_table *)arg; bss_t *bss, *nextBss; - A_UINT8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = false; + u8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = false; A_UINT32 timeoutValue = 0; timeoutValue = nt->nt_nodeAge; @@ -526,7 +526,7 @@ wlan_node_remove_core (struct ieee80211_node_table *nt, bss_t *ni) } bss_t * -wlan_node_remove(struct ieee80211_node_table *nt, A_UINT8 *bssid) +wlan_node_remove(struct ieee80211_node_table *nt, u8 *bssid) { bss_t *bss, *nextBss; diff --git a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c index e9346bfe0dc4..55b2a9623ec3 100644 --- a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c +++ b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c @@ -50,22 +50,22 @@ /* unaligned little endian access */ #define LE_READ_2(p) \ ((A_UINT16) \ - ((((A_UINT8 *)(p))[0] ) | (((A_UINT8 *)(p))[1] << 8))) + ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8))) #define LE_READ_4(p) \ ((A_UINT32) \ - ((((A_UINT8 *)(p))[0] ) | (((A_UINT8 *)(p))[1] << 8) | \ - (((A_UINT8 *)(p))[2] << 16) | (((A_UINT8 *)(p))[3] << 24))) + ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8) | \ + (((u8 *)(p))[2] << 16) | (((u8 *)(p))[3] << 24))) static int __inline -iswpaoui(const A_UINT8 *frm) +iswpaoui(const u8 *frm) { return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI); } static int __inline -iswmmoui(const A_UINT8 *frm) +iswmmoui(const u8 *frm) { return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI); } @@ -73,38 +73,38 @@ iswmmoui(const A_UINT8 *frm) /* unused functions for now */ #if 0 static int __inline -iswmmparam(const A_UINT8 *frm) +iswmmparam(const u8 *frm) { return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE; } static int __inline -iswmminfo(const A_UINT8 *frm) +iswmminfo(const u8 *frm) { return frm[1] > 5 && frm[6] == WMM_INFO_OUI_SUBTYPE; } #endif static int __inline -isatherosoui(const A_UINT8 *frm) +isatherosoui(const u8 *frm) { return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI); } static int __inline -iswscoui(const A_UINT8 *frm) +iswscoui(const u8 *frm) { return frm[1] > 3 && LE_READ_4(frm+2) == ((0x04<<24)|WPA_OUI); } int -wlan_parse_beacon(A_UINT8 *buf, int framelen, struct ieee80211_common_ie *cie) +wlan_parse_beacon(u8 *buf, int framelen, struct ieee80211_common_ie *cie) { - A_UINT8 *frm, *efrm; - A_UINT8 elemid_ssid = false; + u8 *frm, *efrm; + u8 elemid_ssid = false; frm = buf; - efrm = (A_UINT8 *) (frm + framelen); + efrm = (u8 *) (frm + framelen); /* * beacon/probe response frame format diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index 695b0dcc7349..896f4a4c0989 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -70,104 +70,104 @@ ATH_DEBUG_INSTANTIATE_MODULE_VAR(wmi, #define A_DPRINTF AR_DEBUG_PRINTF #endif -static int wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_ready_event_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_disconnect_event_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_tkip_micerr_event_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_opt_frame_event_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_pstream_timeout_event_rx(struct wmi_t *wmip, u8 *datap, int len); static int wmi_sync_point(struct wmi_t *wmip); -static int wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_ratemask_reply_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_channelList_reply_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_regDomain_event_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static int wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_txPwr_reply_rx(struct wmi_t *wmip, u8 *datap, int len); +static int wmi_neighborReport_event_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_dset_open_req_rx(struct wmi_t *wmip, u8 *datap, int len); #ifdef CONFIG_HOST_DSET_SUPPORT -static int wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static int wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_dset_close_rx(struct wmi_t *wmip, u8 *datap, int len); +static int wmi_dset_data_req_rx(struct wmi_t *wmip, u8 *datap, int len); #endif /* CONFIG_HOST_DSET_SUPPORT */ -static int wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_scanComplete_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static int wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static int wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static int wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static int wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static int wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static int wmi_channel_change_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static int wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_errorEvent_rx(struct wmi_t *wmip, u8 *datap, int len); +static int wmi_statsEvent_rx(struct wmi_t *wmip, u8 *datap, int len); +static int wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len); +static int wmi_hbChallengeResp_rx(struct wmi_t *wmip, u8 *datap, int len); +static int wmi_reportErrorEvent_rx(struct wmi_t *wmip, u8 *datap, int len); +static int wmi_cac_event_rx(struct wmi_t *wmip, u8 *datap, int len); +static int wmi_channel_change_event_rx(struct wmi_t *wmip, u8 *datap, int len); +static int wmi_roam_tbl_event_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_roam_data_event_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_get_wow_list_event_rx(struct wmi_t *wmip, u8 *datap, int len); static int -wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len); +wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, A_UINT32 len); static int -wmi_set_params_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len); +wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, A_UINT32 len); static int -wmi_acm_reject_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len); +wmi_acm_reject_event_rx(struct wmi_t *wmip, u8 *datap, A_UINT32 len); #ifdef CONFIG_HOST_GPIO_SUPPORT -static int wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static int wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static int wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_gpio_intr_rx(struct wmi_t *wmip, u8 *datap, int len); +static int wmi_gpio_data_rx(struct wmi_t *wmip, u8 *datap, int len); +static int wmi_gpio_ack_rx(struct wmi_t *wmip, u8 *datap, int len); #endif /* CONFIG_HOST_GPIO_SUPPORT */ #ifdef CONFIG_HOST_TCMD_SUPPORT static int -wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len); #endif static int -wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +wmi_txRetryErrEvent_rx(struct wmi_t *wmip, u8 *datap, int len); static int -wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +wmi_snrThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len); static int -wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len); static bool wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex); static int -wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len); static int -wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len); int wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId, WMI_SYNC_FLAG syncflag); -A_UINT8 ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, A_UINT32 size); -A_UINT8 ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, A_UINT32 size); +u8 ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, A_UINT32 size); +u8 ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, A_UINT32 size); void wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd); void wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd); @@ -177,27 +177,27 @@ static int wmi_send_snr_threshold_params(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd); #if defined(CONFIG_TARGET_PROFILE_SUPPORT) static int -wmi_prof_count_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +wmi_prof_count_rx(struct wmi_t *wmip, u8 *datap, int len); #endif /* CONFIG_TARGET_PROFILE_SUPPORT */ -static int wmi_pspoll_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_pspoll_event_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_dtimexpiry_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_dtimexpiry_event_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_peer_node_event_rx (struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_peer_node_event_rx (struct wmi_t *wmip, u8 *datap, int len); #ifdef ATH_AR6K_11N_SUPPORT -static int wmi_addba_req_event_rx(struct wmi_t *, A_UINT8 *, int); -static int wmi_addba_resp_event_rx(struct wmi_t *, A_UINT8 *, int); -static int wmi_delba_req_event_rx(struct wmi_t *, A_UINT8 *, int); -static int wmi_btcoex_config_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); -static int wmi_btcoex_stats_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); +static int wmi_addba_req_event_rx(struct wmi_t *, u8 *, int); +static int wmi_addba_resp_event_rx(struct wmi_t *, u8 *, int); +static int wmi_delba_req_event_rx(struct wmi_t *, u8 *, int); +static int wmi_btcoex_config_event_rx(struct wmi_t *wmip, u8 *datap, int len); +static int wmi_btcoex_stats_event_rx(struct wmi_t *wmip, u8 *datap, int len); #endif -static int wmi_hci_event_rx(struct wmi_t *, A_UINT8 *, int); +static int wmi_hci_event_rx(struct wmi_t *, u8 *, int); #ifdef WAPI_ENABLE -static int wmi_wapi_rekey_event_rx(struct wmi_t *wmip, A_UINT8 *datap, +static int wmi_wapi_rekey_event_rx(struct wmi_t *wmip, u8 *datap, int len); #endif @@ -262,7 +262,7 @@ static const A_INT32 wmi_rateTable[][2] = { #define MAX_NUMBER_OF_SUPPORT_RATES (MODE_GHT20_SUPPORT_RATE_STOP + 1) /* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */ -const A_UINT8 up_to_ac[]= { +const u8 up_to_ac[]= { WMM_AC_BE, WMM_AC_BK, WMM_AC_BK, @@ -277,19 +277,19 @@ const A_UINT8 up_to_ac[]= { /* This stuff is used when we want a simple layer-3 visibility */ typedef PREPACK struct _iphdr { - A_UINT8 ip_ver_hdrlen; /* version and hdr length */ - A_UINT8 ip_tos; /* type of service */ + u8 ip_ver_hdrlen; /* version and hdr length */ + u8 ip_tos; /* type of service */ A_UINT16 ip_len; /* total length */ A_UINT16 ip_id; /* identification */ A_INT16 ip_off; /* fragment offset field */ #define IP_DF 0x4000 /* dont fragment flag */ #define IP_MF 0x2000 /* more fragments flag */ #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ - A_UINT8 ip_ttl; /* time to live */ - A_UINT8 ip_p; /* protocol */ + u8 ip_ttl; /* time to live */ + u8 ip_p; /* protocol */ A_UINT16 ip_sum; /* checksum */ - A_UINT8 ip_src[4]; /* source and dest address */ - A_UINT8 ip_dst[4]; + u8 ip_src[4]; /* source and dest address */ + u8 ip_dst[4]; } POSTPACK iphdr; #include "athendpack.h" @@ -335,7 +335,7 @@ wmi_init(void *devt) void wmi_qos_state_init(struct wmi_t *wmip) { - A_UINT8 i; + u8 i; if (wmip == NULL) { return; @@ -394,7 +394,7 @@ wmi_shutdown(struct wmi_t *wmip) int wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf) { - A_UINT8 *datap; + u8 *datap; A_UINT16 typeorlen; ATH_MAC_HDR macHdr; ATH_LLC_SNAP_HDR *llcHdr; @@ -449,7 +449,7 @@ wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf) return (A_OK); } -int wmi_meta_add(struct wmi_t *wmip, void *osbuf, A_UINT8 *pVersion,void *pTxMetaS) +int wmi_meta_add(struct wmi_t *wmip, void *osbuf, u8 *pVersion,void *pTxMetaS) { switch(*pVersion){ case 0: @@ -495,11 +495,11 @@ int wmi_meta_add(struct wmi_t *wmip, void *osbuf, A_UINT8 *pVersion,void *pTxMet /* Adds a WMI data header */ int -wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType, bool bMoreData, - WMI_DATA_HDR_DATA_TYPE data_type,A_UINT8 metaVersion, void *pTxMetaS) +wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, u8 msgType, bool bMoreData, + WMI_DATA_HDR_DATA_TYPE data_type,u8 metaVersion, void *pTxMetaS) { WMI_DATA_HDR *dtHdr; -// A_UINT8 metaVersion = 0; +// u8 metaVersion = 0; int status; A_ASSERT(osbuf != NULL); @@ -531,14 +531,14 @@ wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType, bool bMoreDat } -A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 layer2Priority, bool wmmEnabled) +u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 layer2Priority, bool wmmEnabled) { - A_UINT8 *datap; - A_UINT8 trafficClass = WMM_AC_BE; + u8 *datap; + u8 trafficClass = WMM_AC_BE; A_UINT16 ipType = IP_ETHERTYPE; WMI_DATA_HDR *dtHdr; - A_UINT8 streamExists = 0; - A_UINT8 userPriority; + u8 streamExists = 0; + u8 userPriority; A_UINT32 hdrsize, metasize; ATH_LLC_SNAP_HDR *llcHdr; @@ -580,7 +580,7 @@ A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 la { /* Extract the endpoint info from the TOS field in the IP header */ - userPriority = wmi_determine_userPriority (((A_UINT8 *)llcHdr) + sizeof(ATH_LLC_SNAP_HDR),layer2Priority); + userPriority = wmi_determine_userPriority (((u8 *)llcHdr) + sizeof(ATH_LLC_SNAP_HDR),layer2Priority); } else { @@ -624,7 +624,7 @@ A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 la int wmi_dot11_hdr_add (struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode) { - A_UINT8 *datap; + u8 *datap; A_UINT16 typeorlen; ATH_MAC_HDR macHdr; ATH_LLC_SNAP_HDR *llcHdr; @@ -716,9 +716,9 @@ AddDot11Hdr: int wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf) { - A_UINT8 *datap; + u8 *datap; struct ieee80211_frame *pwh,wh; - A_UINT8 type,subtype; + u8 type,subtype; ATH_LLC_SNAP_HDR *llcHdr; ATH_MAC_HDR macHdr; A_UINT32 hdrsize; @@ -730,7 +730,7 @@ wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf) type = pwh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; subtype = pwh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; - A_MEMCPY((A_UINT8 *)&wh, datap, sizeof(struct ieee80211_frame)); + A_MEMCPY((u8 *)&wh, datap, sizeof(struct ieee80211_frame)); /* strip off the 802.11 hdr*/ if (subtype == IEEE80211_FC0_SUBTYPE_QOS) { @@ -784,7 +784,7 @@ wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf) int wmi_dot3_2_dix(void *osbuf) { - A_UINT8 *datap; + u8 *datap; ATH_MAC_HDR macHdr; ATH_LLC_SNAP_HDR *llcHdr; @@ -831,7 +831,7 @@ wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf) { WMIX_CMD_HDR *cmd; A_UINT16 id; - A_UINT8 *datap; + u8 *datap; A_UINT32 len; int status = A_OK; @@ -908,7 +908,7 @@ wmi_control_rx(struct wmi_t *wmip, void *osbuf) { WMI_CMD_HDR *cmd; A_UINT16 id; - A_UINT8 *datap; + u8 *datap; A_UINT32 len, i, loggingReq; int status = A_OK; @@ -1224,7 +1224,7 @@ wmi_simple_cmd_xtnd(struct wmi_t *wmip, WMIX_COMMAND_ID cmdid) #endif static int -wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_ready_event_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_READY_EVENT *ev = (WMI_READY_EVENT *)datap; @@ -1241,27 +1241,27 @@ wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) #define LE_READ_4(p) \ ((A_UINT32) \ - ((((A_UINT8 *)(p))[0] ) | (((A_UINT8 *)(p))[1] << 8) | \ - (((A_UINT8 *)(p))[2] << 16) | (((A_UINT8 *)(p))[3] << 24))) + ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8) | \ + (((u8 *)(p))[2] << 16) | (((u8 *)(p))[3] << 24))) static int __inline -iswmmoui(const A_UINT8 *frm) +iswmmoui(const u8 *frm) { return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI); } static int __inline -iswmmparam(const A_UINT8 *frm) +iswmmparam(const u8 *frm) { return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE; } static int -wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_CONNECT_EVENT *ev; - A_UINT8 *pie,*peie; + u8 *pie,*peie; if (len < sizeof(WMI_CONNECT_EVENT)) { @@ -1318,7 +1318,7 @@ wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_regDomain_event_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_REG_DOMAIN_EVENT *ev; @@ -1333,7 +1333,7 @@ wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_neighborReport_event_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_NEIGHBOR_REPORT_EVENT *ev; int numAps; @@ -1354,7 +1354,7 @@ wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_disconnect_event_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_DISCONNECT_EVENT *ev; wmip->wmi_traffic_class = 100; @@ -1379,7 +1379,7 @@ wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_peer_node_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_peer_node_event_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_PEER_NODE_EVENT *ev; @@ -1399,7 +1399,7 @@ wmi_peer_node_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_tkip_micerr_event_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_TKIP_MICERR_EVENT *ev; @@ -1415,15 +1415,15 @@ wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len) { bss_t *bss = NULL; WMI_BSS_INFO_HDR *bih; - A_UINT8 *buf; + u8 *buf; A_UINT32 nodeCachingAllowed = 1; A_UCHAR cached_ssid_len = 0; A_UCHAR cached_ssid_buf[IEEE80211_NWID_LEN] = {0}; - A_UINT8 beacon_ssid_len = 0; + u8 beacon_ssid_len = 0; if (len <= sizeof(WMI_BSS_INFO_HDR)) { return A_EINVAL; @@ -1533,7 +1533,7 @@ wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) (0 != cached_ssid_len) && (0 == beacon_ssid_len || (beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1]))) { - A_UINT8 *ni_buf = bss->ni_buf; + u8 *ni_buf = bss->ni_buf; int buf_len = len; /* copy the first 14 bytes such as @@ -1579,11 +1579,11 @@ wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_opt_frame_event_rx(struct wmi_t *wmip, u8 *datap, int len) { bss_t *bss; WMI_OPT_RX_INFO_HDR *bih; - A_UINT8 *buf; + u8 *buf; if (len <= sizeof(WMI_OPT_RX_INFO_HDR)) { return A_EINVAL; @@ -1624,7 +1624,7 @@ wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) * at the target */ static int -wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_pstream_timeout_event_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_PSTREAM_TIMEOUT_EVENT *ev; @@ -1654,7 +1654,7 @@ wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_BIT_RATE_REPLY *reply; A_INT32 rate; @@ -1685,7 +1685,7 @@ wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_ratemask_reply_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_FIX_RATES_REPLY *reply; @@ -1702,7 +1702,7 @@ wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_channelList_reply_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_CHANNEL_LIST_REPLY *reply; @@ -1719,7 +1719,7 @@ wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_txPwr_reply_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_TX_PWR_REPLY *reply; @@ -1734,7 +1734,7 @@ wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) return A_OK; } static int -wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_GET_KEEPALIVE_CMD *reply; @@ -1751,7 +1751,7 @@ wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) static int -wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_dset_open_req_rx(struct wmi_t *wmip, u8 *datap, int len) { WMIX_DSETOPENREQ_EVENT *dsetopenreq; @@ -1772,7 +1772,7 @@ wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) #ifdef CONFIG_HOST_DSET_SUPPORT static int -wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_dset_close_rx(struct wmi_t *wmip, u8 *datap, int len) { WMIX_DSETCLOSE_EVENT *dsetclose; @@ -1788,7 +1788,7 @@ wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_dset_data_req_rx(struct wmi_t *wmip, u8 *datap, int len) { WMIX_DSETDATAREQ_EVENT *dsetdatareq; @@ -1811,7 +1811,7 @@ wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) #endif /* CONFIG_HOST_DSET_SUPPORT */ static int -wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_scanComplete_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_SCAN_COMPLETE_EVENT *ev; @@ -1833,7 +1833,7 @@ wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) * A reset is recommended. */ static int -wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_errorEvent_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_CMD_ERROR_EVENT *ev; @@ -1856,7 +1856,7 @@ wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) static int -wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_statsEvent_rx(struct wmi_t *wmip, u8 *datap, int len) { A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); @@ -1866,14 +1866,14 @@ wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_RSSI_THRESHOLD_EVENT *reply; WMI_RSSI_THRESHOLD_VAL newThreshold; WMI_RSSI_THRESHOLD_PARAMS_CMD cmd; SQ_THRESHOLD_PARAMS *sq_thresh = &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI]; - A_UINT8 upper_rssi_threshold, lower_rssi_threshold; + u8 upper_rssi_threshold, lower_rssi_threshold; A_INT16 rssi; if (len < sizeof(*reply)) { @@ -1971,7 +1971,7 @@ wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) static int -wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_reportErrorEvent_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_TARGET_ERROR_REPORT_EVENT *reply; @@ -1987,7 +1987,7 @@ wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_cac_event_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_CAC_EVENT *reply; WMM_TSPEC_IE *tspec_ie; @@ -2008,7 +2008,7 @@ wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) (tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK); } else if (reply->cac_indication == CAC_INDICATION_NO_RESP) { - A_UINT8 i; + u8 i; /* following assumes that there is only one outstanding ADDTS request when this event is received */ @@ -2030,7 +2030,7 @@ wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) * for delete qos stream from AP */ else if (reply->cac_indication == CAC_INDICATION_DELETE) { - A_UINT8 tsid = 0; + u8 tsid = 0; tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion); tsid= ((tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK); @@ -2057,7 +2057,7 @@ wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_channel_change_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_channel_change_event_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_CHANNEL_CHANGE_EVENT *reply; @@ -2074,7 +2074,7 @@ wmi_channel_change_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_hbChallengeResp_rx(struct wmi_t *wmip, u8 *datap, int len) { WMIX_HB_CHALLENGE_RESP_EVENT *reply; @@ -2090,7 +2090,7 @@ wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_roam_tbl_event_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_TARGET_ROAM_TBL *reply; @@ -2106,7 +2106,7 @@ wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_roam_data_event_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_TARGET_ROAM_DATA *reply; @@ -2122,7 +2122,7 @@ wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_txRetryErrEvent_rx(struct wmi_t *wmip, u8 *datap, int len) { if (len < sizeof(WMI_TX_RETRY_ERR_EVENT)) { return A_EINVAL; @@ -2135,14 +2135,14 @@ wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_snrThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_SNR_THRESHOLD_EVENT *reply; SQ_THRESHOLD_PARAMS *sq_thresh = &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR]; WMI_SNR_THRESHOLD_VAL newThreshold; WMI_SNR_THRESHOLD_PARAMS_CMD cmd; - A_UINT8 upper_snr_threshold, lower_snr_threshold; + u8 upper_snr_threshold, lower_snr_threshold; A_INT16 snr; if (len < sizeof(*reply)) { @@ -2228,7 +2228,7 @@ wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_LQ_THRESHOLD_EVENT *reply; @@ -2246,12 +2246,12 @@ wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len) { A_UINT16 ap_info_entry_size; WMI_APLIST_EVENT *ev = (WMI_APLIST_EVENT *)datap; WMI_AP_INFO_V1 *ap_info_v1; - A_UINT8 i; + u8 i; if (len < sizeof(WMI_APLIST_EVENT)) { return A_EINVAL; @@ -2287,7 +2287,7 @@ wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len) { A_UINT32 dropped; @@ -2300,7 +2300,7 @@ wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) #ifdef CONFIG_HOST_GPIO_SUPPORT static int -wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_gpio_intr_rx(struct wmi_t *wmip, u8 *datap, int len) { WMIX_GPIO_INTR_EVENT *gpio_intr = (WMIX_GPIO_INTR_EVENT *)datap; @@ -2314,7 +2314,7 @@ wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_gpio_data_rx(struct wmi_t *wmip, u8 *datap, int len) { WMIX_GPIO_DATA_EVENT *gpio_data = (WMIX_GPIO_DATA_EVENT *)datap; @@ -2328,7 +2328,7 @@ wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_gpio_ack_rx(struct wmi_t *wmip, u8 *datap, int len) { A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); @@ -2418,10 +2418,10 @@ wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId, int wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType, DOT11_AUTH_MODE dot11AuthMode, AUTH_MODE authMode, - CRYPTO_TYPE pairwiseCrypto, A_UINT8 pairwiseCryptoLen, - CRYPTO_TYPE groupCrypto, A_UINT8 groupCryptoLen, + CRYPTO_TYPE pairwiseCrypto, u8 pairwiseCryptoLen, + CRYPTO_TYPE groupCrypto, u8 groupCryptoLen, int ssidLength, A_UCHAR *ssid, - A_UINT8 *bssid, A_UINT16 channel, A_UINT32 ctrl_flags) + u8 *bssid, A_UINT16 channel, A_UINT32 ctrl_flags) { void *osbuf; WMI_CONNECT_CMD *cc; @@ -2471,7 +2471,7 @@ wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType, } int -wmi_reconnect_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT16 channel) +wmi_reconnect_cmd(struct wmi_t *wmip, u8 *bssid, A_UINT16 channel) { void *osbuf; WMI_RECONNECT_CMD *cc; @@ -2558,7 +2558,7 @@ wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec, A_UINT16 fg_end_sec, A_UINT16 bg_sec, A_UINT16 minact_chdw_msec, A_UINT16 maxact_chdw_msec, A_UINT16 pas_chdw_msec, - A_UINT8 shScanRatio, A_UINT8 scanCtrlFlags, + u8 shScanRatio, u8 scanCtrlFlags, A_UINT32 max_dfsch_act_time, A_UINT16 maxact_scan_per_ssid) { void *osbuf; @@ -2589,7 +2589,7 @@ wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec, } int -wmi_bssfilter_cmd(struct wmi_t *wmip, A_UINT8 filter, A_UINT32 ieMask) +wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, A_UINT32 ieMask) { void *osbuf; WMI_BSS_FILTER_CMD *cmd; @@ -2615,8 +2615,8 @@ wmi_bssfilter_cmd(struct wmi_t *wmip, A_UINT8 filter, A_UINT32 ieMask) } int -wmi_probedSsid_cmd(struct wmi_t *wmip, A_UINT8 index, A_UINT8 flag, - A_UINT8 ssidLength, A_UCHAR *ssid) +wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag, + u8 ssidLength, A_UCHAR *ssid) { void *osbuf; WMI_PROBED_SSID_CMD *cmd; @@ -2701,8 +2701,8 @@ wmi_bmisstime_cmd(struct wmi_t *wmip, A_UINT16 bmissTime, A_UINT16 bmissBeacons) } int -wmi_associnfo_cmd(struct wmi_t *wmip, A_UINT8 ieType, - A_UINT8 ieLen, A_UINT8 *ieInfo) +wmi_associnfo_cmd(struct wmi_t *wmip, u8 ieType, + u8 ieLen, u8 *ieInfo) { void *osbuf; WMI_SET_ASSOC_INFO_CMD *cmd; @@ -2727,7 +2727,7 @@ wmi_associnfo_cmd(struct wmi_t *wmip, A_UINT8 ieType, } int -wmi_powermode_cmd(struct wmi_t *wmip, A_UINT8 powerMode) +wmi_powermode_cmd(struct wmi_t *wmip, u8 powerMode) { void *osbuf; WMI_POWER_MODE_CMD *cmd; @@ -2749,7 +2749,7 @@ wmi_powermode_cmd(struct wmi_t *wmip, A_UINT8 powerMode) } int -wmi_ibsspmcaps_cmd(struct wmi_t *wmip, A_UINT8 pmEnable, A_UINT8 ttl, +wmi_ibsspmcaps_cmd(struct wmi_t *wmip, u8 pmEnable, u8 ttl, A_UINT16 atim_windows, A_UINT16 timeout_value) { void *osbuf; @@ -2774,8 +2774,8 @@ wmi_ibsspmcaps_cmd(struct wmi_t *wmip, A_UINT8 pmEnable, A_UINT8 ttl, } int -wmi_apps_cmd(struct wmi_t *wmip, A_UINT8 psType, A_UINT32 idle_time, - A_UINT32 ps_period, A_UINT8 sleep_period) +wmi_apps_cmd(struct wmi_t *wmip, u8 psType, A_UINT32 idle_time, + A_UINT32 ps_period, u8 sleep_period) { void *osbuf; WMI_AP_PS_CMD *cmd; @@ -2828,7 +2828,7 @@ wmi_pmparams_cmd(struct wmi_t *wmip, A_UINT16 idlePeriod, } int -wmi_disctimeout_cmd(struct wmi_t *wmip, A_UINT8 timeout) +wmi_disctimeout_cmd(struct wmi_t *wmip, u8 timeout) { void *osbuf; WMI_DISC_TIMEOUT_CMD *cmd; @@ -2849,9 +2849,9 @@ wmi_disctimeout_cmd(struct wmi_t *wmip, A_UINT8 timeout) } int -wmi_addKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex, CRYPTO_TYPE keyType, - A_UINT8 keyUsage, A_UINT8 keyLength, A_UINT8 *keyRSC, - A_UINT8 *keyMaterial, A_UINT8 key_op_ctrl, A_UINT8 *macAddr, +wmi_addKey_cmd(struct wmi_t *wmip, u8 keyIndex, CRYPTO_TYPE keyType, + u8 keyUsage, u8 keyLength, u8 *keyRSC, + u8 *keyMaterial, u8 key_op_ctrl, u8 *macAddr, WMI_SYNC_FLAG sync_flag) { void *osbuf; @@ -2898,7 +2898,7 @@ wmi_addKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex, CRYPTO_TYPE keyType, } int -wmi_add_krk_cmd(struct wmi_t *wmip, A_UINT8 *krk) +wmi_add_krk_cmd(struct wmi_t *wmip, u8 *krk) { void *osbuf; WMI_ADD_KRK_CMD *cmd; @@ -2924,7 +2924,7 @@ wmi_delete_krk_cmd(struct wmi_t *wmip) } int -wmi_deleteKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex) +wmi_deleteKey_cmd(struct wmi_t *wmip, u8 keyIndex) { void *osbuf; WMI_DELETE_CIPHER_KEY_CMD *cmd; @@ -2949,7 +2949,7 @@ wmi_deleteKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex) } int -wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId, +wmi_setPmkid_cmd(struct wmi_t *wmip, u8 *bssid, u8 *pmkId, bool set) { void *osbuf; @@ -3030,7 +3030,7 @@ wmi_set_pmkid_list_cmd(struct wmi_t *wmip, void *osbuf; WMI_SET_PMKID_LIST_CMD *cmd; A_UINT16 cmdLen; - A_UINT8 i; + u8 i; cmdLen = sizeof(pmkInfo->numPMKID) + pmkInfo->numPMKID * sizeof(WMI_PMKID); @@ -3081,7 +3081,7 @@ wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, HTC_ENDPOINT_ID eid) } typedef struct _WMI_DATA_SYNC_BUFS { - A_UINT8 trafficClass; + u8 trafficClass; void *osbuf; }WMI_DATA_SYNC_BUFS; @@ -3091,7 +3091,7 @@ wmi_sync_point(struct wmi_t *wmip) void *cmd_osbuf; WMI_SYNC_CMD *cmd; WMI_DATA_SYNC_BUFS dataSyncBufs[WMM_NUM_AC]; - A_UINT8 i,numPriStreams=0; + u8 i,numPriStreams=0; int status = A_OK; A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); @@ -3200,7 +3200,7 @@ wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params) { void *osbuf; WMI_CREATE_PSTREAM_CMD *cmd; - A_UINT8 fatPipeExistsForAC=0; + u8 fatPipeExistsForAC=0; A_INT32 minimalPHY = 0; A_INT32 nominalPHY = 0; @@ -3292,7 +3292,7 @@ wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params) } int -wmi_delete_pstream_cmd(struct wmi_t *wmip, A_UINT8 trafficClass, A_UINT8 tsid) +wmi_delete_pstream_cmd(struct wmi_t *wmip, u8 trafficClass, u8 tsid) { void *osbuf; WMI_DELETE_PSTREAM_CMD *cmd; @@ -3356,11 +3356,11 @@ wmi_delete_pstream_cmd(struct wmi_t *wmip, A_UINT8 trafficClass, A_UINT8 tsid) } int -wmi_set_framerate_cmd(struct wmi_t *wmip, A_UINT8 bEnable, A_UINT8 type, A_UINT8 subType, A_UINT16 rateMask) +wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, A_UINT16 rateMask) { void *osbuf; WMI_FRAME_RATES_CMD *cmd; - A_UINT8 frameType; + u8 frameType; A_DPRINTF(DBG_WMI, (DBGFMT " type %02X, subType %02X, rateMask %04x\n", DBGARG, type, subType, rateMask)); @@ -3381,7 +3381,7 @@ wmi_set_framerate_cmd(struct wmi_t *wmip, A_UINT8 bEnable, A_UINT8 type, A_UINT8 cmd = (WMI_FRAME_RATES_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(cmd, sizeof(*cmd)); - frameType = (A_UINT8)((subType << 4) | type); + frameType = (u8)((subType << 4) | type); cmd->bEnableMask = bEnable; cmd->frameType = frameType; @@ -3595,7 +3595,7 @@ wmi_get_channelList_cmd(struct wmi_t *wmip) * array should correspond to numChan entries. */ int -wmi_set_channelParams_cmd(struct wmi_t *wmip, A_UINT8 scanParam, +wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam, WMI_PHY_MODE mode, A_INT8 numChan, A_UINT16 *channelList) { @@ -3713,8 +3713,8 @@ wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *ipCmd) WMI_SET_IP_CMD *cmd; /* Multicast address are not valid */ - if((*((A_UINT8*)&ipCmd->ips[0]) >= 0xE0) || - (*((A_UINT8*)&ipCmd->ips[1]) >= 0xE0)) { + if((*((u8 *)&ipCmd->ips[0]) >= 0xE0) || + (*((u8 *)&ipCmd->ips[1]) >= 0xE0)) { return A_EINVAL; } @@ -3739,8 +3739,8 @@ wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, A_INT8 size; WMI_SET_HOST_SLEEP_MODE_CMD *cmd; A_UINT16 activeTsids=0; - A_UINT8 streamExists=0; - A_UINT8 i; + u8 streamExists=0; + u8 i; if( hostModeCmd->awake == hostModeCmd->asleep) { return A_EINVAL; @@ -3846,7 +3846,7 @@ wmi_get_wow_list_cmd(struct wmi_t *wmip, } static int -wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_get_wow_list_event_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_GET_WOW_LIST_REPLY *reply; @@ -3863,17 +3863,17 @@ wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) int wmi_add_wow_pattern_cmd(struct wmi_t *wmip, WMI_ADD_WOW_PATTERN_CMD *addWowCmd, - A_UINT8* pattern, A_UINT8* mask, - A_UINT8 pattern_size) + u8 *pattern, u8 *mask, + u8 pattern_size) { void *osbuf; A_INT8 size; WMI_ADD_WOW_PATTERN_CMD *cmd; - A_UINT8 *filter_mask = NULL; + u8 *filter_mask = NULL; size = sizeof (*cmd); - size += ((2 * addWowCmd->filter_size)* sizeof(A_UINT8)); + size += ((2 * addWowCmd->filter_size)* sizeof(u8)); osbuf = A_NETBUF_ALLOC(size); if (osbuf == NULL) { return A_NO_MEMORY; @@ -3888,7 +3888,7 @@ int wmi_add_wow_pattern_cmd(struct wmi_t *wmip, A_MEMCPY(cmd->filter, pattern, addWowCmd->filter_size); - filter_mask = (A_UINT8*)(cmd->filter + cmd->filter_size); + filter_mask = (u8 *)(cmd->filter + cmd->filter_size); A_MEMCPY(filter_mask, mask, addWowCmd->filter_size); @@ -3953,8 +3953,8 @@ wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CM * event from the target which is used for the configuring the correct * thresholds */ - snrCmd->thresholdAbove1_Val = (A_UINT8)sq_thresh->upper_threshold[0]; - snrCmd->thresholdBelow1_Val = (A_UINT8)sq_thresh->lower_threshold[0]; + snrCmd->thresholdAbove1_Val = (u8)sq_thresh->upper_threshold[0]; + snrCmd->thresholdBelow1_Val = (u8)sq_thresh->lower_threshold[0]; } else { /* * In case the user issues multiple times of snr_threshold_setting, @@ -4112,7 +4112,7 @@ wmi_get_stats_cmd(struct wmi_t *wmip) } int -wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid) +wmi_addBadAp_cmd(struct wmi_t *wmip, u8 apIndex, u8 *bssid) { void *osbuf; WMI_ADD_BAD_AP_CMD *cmd; @@ -4136,7 +4136,7 @@ wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid) } int -wmi_deleteBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex) +wmi_deleteBadAp_cmd(struct wmi_t *wmip, u8 apIndex) { void *osbuf; WMI_DELETE_BAD_AP_CMD *cmd; @@ -4166,7 +4166,7 @@ wmi_abort_scan_cmd(struct wmi_t *wmip) } int -wmi_set_txPwr_cmd(struct wmi_t *wmip, A_UINT8 dbM) +wmi_set_txPwr_cmd(struct wmi_t *wmip, u8 dbM) { void *osbuf; WMI_SET_TX_PWR_CMD *cmd; @@ -4191,7 +4191,7 @@ wmi_get_txPwr_cmd(struct wmi_t *wmip) } A_UINT16 -wmi_get_mapped_qos_queue(struct wmi_t *wmip, A_UINT8 trafficClass) +wmi_get_mapped_qos_queue(struct wmi_t *wmip, u8 trafficClass) { A_UINT16 activeTsids=0; @@ -4209,10 +4209,10 @@ wmi_get_roam_tbl_cmd(struct wmi_t *wmip) } int -wmi_get_roam_data_cmd(struct wmi_t *wmip, A_UINT8 roamDataType) +wmi_get_roam_data_cmd(struct wmi_t *wmip, u8 roamDataType) { void *osbuf; - A_UINT32 size = sizeof(A_UINT8); + A_UINT32 size = sizeof(u8); WMI_TARGET_ROAM_DATA *cmd; osbuf = A_NETBUF_ALLOC(size); /* no payload */ @@ -4231,7 +4231,7 @@ wmi_get_roam_data_cmd(struct wmi_t *wmip, A_UINT8 roamDataType) int wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p, - A_UINT8 size) + u8 size) { void *osbuf; WMI_SET_ROAM_CTRL_CMD *cmd; @@ -4255,7 +4255,7 @@ wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p, int wmi_set_powersave_timers_cmd(struct wmi_t *wmip, WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd, - A_UINT8 size) + u8 size) { void *osbuf; WMI_POWERSAVE_TIMERS_POLICY_CMD *cmd; @@ -4411,8 +4411,8 @@ wmi_gpio_intr_ack(struct wmi_t *wmip, #endif /* CONFIG_HOST_GPIO_SUPPORT */ int -wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT8 ac, A_UINT16 txop, A_UINT8 eCWmin, - A_UINT8 eCWmax, A_UINT8 aifsn) +wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac, A_UINT16 txop, u8 eCWmin, + u8 eCWmax, u8 aifsn) { void *osbuf; WMI_SET_ACCESS_PARAMS_CMD *cmd; @@ -4442,9 +4442,9 @@ wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT8 ac, A_UINT16 txop, A_UINT } int -wmi_set_retry_limits_cmd(struct wmi_t *wmip, A_UINT8 frameType, - A_UINT8 trafficClass, A_UINT8 maxRetries, - A_UINT8 enableNotify) +wmi_set_retry_limits_cmd(struct wmi_t *wmip, u8 frameType, + u8 trafficClass, u8 maxRetries, + u8 enableNotify) { void *osbuf; WMI_SET_RETRY_LIMITS_CMD *cmd; @@ -4481,7 +4481,7 @@ wmi_set_retry_limits_cmd(struct wmi_t *wmip, A_UINT8 frameType, } void -wmi_get_current_bssid(struct wmi_t *wmip, A_UINT8 *bssid) +wmi_get_current_bssid(struct wmi_t *wmip, u8 *bssid) { if (bssid != NULL) { A_MEMCPY(bssid, wmip->wmi_bssid, ATH_MAC_LEN); @@ -4489,7 +4489,7 @@ wmi_get_current_bssid(struct wmi_t *wmip, A_UINT8 *bssid) } int -wmi_set_opt_mode_cmd(struct wmi_t *wmip, A_UINT8 optMode) +wmi_set_opt_mode_cmd(struct wmi_t *wmip, u8 optMode) { void *osbuf; WMI_SET_OPT_MODE_CMD *cmd; @@ -4511,11 +4511,11 @@ wmi_set_opt_mode_cmd(struct wmi_t *wmip, A_UINT8 optMode) int wmi_opt_tx_frame_cmd(struct wmi_t *wmip, - A_UINT8 frmType, - A_UINT8 *dstMacAddr, - A_UINT8 *bssid, + u8 frmType, + u8 *dstMacAddr, + u8 *bssid, A_UINT16 optIEDataLen, - A_UINT8 *optIEData) + u8 *optIEData) { void *osbuf; WMI_OPT_TX_FRAME_CMD *cmd; @@ -4531,7 +4531,7 @@ wmi_opt_tx_frame_cmd(struct wmi_t *wmip, cmd->frmType = frmType; cmd->optIEDataLen = optIEDataLen; - //cmd->optIEData = (A_UINT8 *)((int)cmd + sizeof(*cmd)); + //cmd->optIEData = (u8 *)((int)cmd + sizeof(*cmd)); A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid)); A_MEMCPY(cmd->dstAddr, dstMacAddr, sizeof(cmd->dstAddr)); A_MEMCPY(&cmd->optIEData[0], optIEData, optIEDataLen); @@ -4585,7 +4585,7 @@ wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize) int -wmi_set_max_sp_len_cmd(struct wmi_t *wmip, A_UINT8 maxSPLen) +wmi_set_max_sp_len_cmd(struct wmi_t *wmip, u8 maxSPLen) { void *osbuf; WMI_SET_MAX_SP_LEN_CMD *cmd; @@ -4611,12 +4611,11 @@ wmi_set_max_sp_len_cmd(struct wmi_t *wmip, A_UINT8 maxSPLen) NO_SYNC_WMIFLAG)); } -A_UINT8 -wmi_determine_userPriority( - A_UINT8 *pkt, +u8 wmi_determine_userPriority( + u8 *pkt, A_UINT32 layer2Pri) { - A_UINT8 ipPri; + u8 ipPri; iphdr *ipHdr = (iphdr *)pkt; /* Determine IPTOS priority */ @@ -4632,19 +4631,17 @@ wmi_determine_userPriority( ipPri &= 0x7; if ((layer2Pri & 0x7) > ipPri) - return ((A_UINT8)layer2Pri & 0x7); + return ((u8)layer2Pri & 0x7); else return ipPri; } -A_UINT8 -convert_userPriority_to_trafficClass(A_UINT8 userPriority) +u8 convert_userPriority_to_trafficClass(u8 userPriority) { return (up_to_ac[userPriority & 0x7]); } -A_UINT8 -wmi_get_power_mode_cmd(struct wmi_t *wmip) +u8 wmi_get_power_mode_cmd(struct wmi_t *wmip) { return wmip->wmi_powerMode; } @@ -4683,7 +4680,7 @@ wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance) #ifdef CONFIG_HOST_TCMD_SUPPORT static int -wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len) { A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); @@ -4696,7 +4693,7 @@ wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) #endif /* CONFIG_HOST_TCMD_SUPPORT*/ int -wmi_set_authmode_cmd(struct wmi_t *wmip, A_UINT8 mode) +wmi_set_authmode_cmd(struct wmi_t *wmip, u8 mode) { void *osbuf; WMI_SET_AUTH_MODE_CMD *cmd; @@ -4717,7 +4714,7 @@ wmi_set_authmode_cmd(struct wmi_t *wmip, A_UINT8 mode) } int -wmi_set_reassocmode_cmd(struct wmi_t *wmip, A_UINT8 mode) +wmi_set_reassocmode_cmd(struct wmi_t *wmip, u8 mode) { void *osbuf; WMI_SET_REASSOC_MODE_CMD *cmd; @@ -4738,7 +4735,7 @@ wmi_set_reassocmode_cmd(struct wmi_t *wmip, A_UINT8 mode) } int -wmi_set_lpreamble_cmd(struct wmi_t *wmip, A_UINT8 status, A_UINT8 preamblePolicy) +wmi_set_lpreamble_cmd(struct wmi_t *wmip, u8 status, u8 preamblePolicy) { void *osbuf; WMI_SET_LPREAMBLE_CMD *cmd; @@ -4803,7 +4800,7 @@ wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status) } int -wmi_set_qos_supp_cmd(struct wmi_t *wmip, A_UINT8 status) +wmi_set_qos_supp_cmd(struct wmi_t *wmip, u8 status) { void *osbuf; WMI_SET_QOS_SUPP_CMD *cmd; @@ -4875,7 +4872,7 @@ wmi_set_country(struct wmi_t *wmip, A_UCHAR *countryCode) have different test command requirements from differnt manufacturers */ int -wmi_test_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT32 len) +wmi_test_cmd(struct wmi_t *wmip, u8 *buf, A_UINT32 len) { void *osbuf; char *data; @@ -4898,7 +4895,7 @@ wmi_test_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT32 len) #endif int -wmi_set_bt_status_cmd(struct wmi_t *wmip, A_UINT8 streamType, A_UINT8 status) +wmi_set_bt_status_cmd(struct wmi_t *wmip, u8 streamType, u8 status) { void *osbuf; WMI_SET_BT_STATUS_CMD *cmd; @@ -5186,14 +5183,13 @@ wmi_get_keepalive_configured(struct wmi_t *wmip) NO_SYNC_WMIFLAG)); } -A_UINT8 -wmi_get_keepalive_cmd(struct wmi_t *wmip) +u8 wmi_get_keepalive_cmd(struct wmi_t *wmip) { return wmip->wmi_keepaliveInterval; } int -wmi_set_keepalive_cmd(struct wmi_t *wmip, A_UINT8 keepaliveInterval) +wmi_set_keepalive_cmd(struct wmi_t *wmip, u8 keepaliveInterval) { void *osbuf; WMI_SET_KEEPALIVE_CMD *cmd; @@ -5239,7 +5235,7 @@ wmi_set_params_cmd(struct wmi_t *wmip, A_UINT32 opcode, A_UINT32 length, char *b int -wmi_set_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 dot3, A_UINT8 dot4) +wmi_set_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4) { void *osbuf; WMI_SET_MCAST_FILTER_CMD *cmd; @@ -5265,7 +5261,7 @@ wmi_set_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 int -wmi_del_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 dot3, A_UINT8 dot4) +wmi_del_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4) { void *osbuf; WMI_SET_MCAST_FILTER_CMD *cmd; @@ -5290,7 +5286,7 @@ wmi_del_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 } int -wmi_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 enable) +wmi_mcast_filter_cmd(struct wmi_t *wmip, u8 enable) { void *osbuf; WMI_MCAST_FILTER_CMD *cmd; @@ -5310,8 +5306,8 @@ wmi_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 enable) } int -wmi_set_appie_cmd(struct wmi_t *wmip, A_UINT8 mgmtFrmType, A_UINT8 ieLen, - A_UINT8 *ieInfo) +wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType, u8 ieLen, + u8 *ieInfo) { void *osbuf; WMI_SET_APPIE_CMD *cmd; @@ -5336,10 +5332,10 @@ wmi_set_appie_cmd(struct wmi_t *wmip, A_UINT8 mgmtFrmType, A_UINT8 ieLen, } int -wmi_set_halparam_cmd(struct wmi_t *wmip, A_UINT8 *cmd, A_UINT16 dataLen) +wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, A_UINT16 dataLen) { void *osbuf; - A_UINT8 *data; + u8 *data; osbuf = A_NETBUF_ALLOC(dataLen); if (osbuf == NULL) { @@ -5406,7 +5402,7 @@ wmi_free_allnodes(struct wmi_t *wmip) } bss_t * -wmi_find_node(struct wmi_t *wmip, const A_UINT8 *macaddr) +wmi_find_node(struct wmi_t *wmip, const u8 *macaddr) { bss_t *ni=NULL; ni=wlan_find_node(&wmip->wmi_scan_table,macaddr); @@ -5414,7 +5410,7 @@ wmi_find_node(struct wmi_t *wmip, const A_UINT8 *macaddr) } void -wmi_free_node(struct wmi_t *wmip, const A_UINT8 *macaddr) +wmi_free_node(struct wmi_t *wmip, const u8 *macaddr) { bss_t *ni=NULL; @@ -5462,7 +5458,7 @@ wmi_dset_open_reply(struct wmi_t *wmip, } static int -wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len) +wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, A_UINT32 len) { WMI_PMKID_LIST_REPLY *reply; A_UINT32 expected_len; @@ -5485,7 +5481,7 @@ wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len) static int -wmi_set_params_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len) +wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, A_UINT32 len) { WMI_SET_PARAMS_REPLY *reply; @@ -5509,7 +5505,7 @@ wmi_set_params_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len) static int -wmi_acm_reject_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len) +wmi_acm_reject_event_rx(struct wmi_t *wmip, u8 *datap, A_UINT32 len) { WMI_ACM_REJECT_EVENT *ev; @@ -5524,7 +5520,7 @@ wmi_acm_reject_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len) int wmi_dset_data_reply(struct wmi_t *wmip, A_UINT32 status, - A_UINT8 *user_buf, + u8 *user_buf, A_UINT32 length, A_UINT32 targ_buf, A_UINT32 targ_reply_fn, @@ -5655,7 +5651,7 @@ wmi_prof_count_get_cmd(struct wmi_t *wmip) /* Called to handle WMIX_PROF_CONT_EVENTID */ static int -wmi_prof_count_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_prof_count_rx(struct wmi_t *wmip, u8 *datap, int len) { WMIX_PROF_COUNT_EVENT *prof_data = (WMIX_PROF_COUNT_EVENT *)datap; @@ -5888,17 +5884,16 @@ wmi_scan_indication (struct wmi_t *wmip) } #endif -A_UINT8 -ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, +u8 ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, A_UINT32 size) { A_UINT32 index; - A_UINT8 threshold = (A_UINT8)sq_thresh->upper_threshold[size - 1]; + u8 threshold = (u8)sq_thresh->upper_threshold[size - 1]; /* The list is already in sorted order. Get the next lower value */ for (index = 0; index < size; index ++) { if (rssi < sq_thresh->upper_threshold[index]) { - threshold = (A_UINT8)sq_thresh->upper_threshold[index]; + threshold = (u8)sq_thresh->upper_threshold[index]; break; } } @@ -5906,17 +5901,16 @@ ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, return threshold; } -A_UINT8 -ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, +u8 ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, A_UINT32 size) { A_UINT32 index; - A_UINT8 threshold = (A_UINT8)sq_thresh->lower_threshold[size - 1]; + u8 threshold = (u8)sq_thresh->lower_threshold[size - 1]; /* The list is already in sorted order. Get the next lower value */ for (index = 0; index < size; index ++) { if (rssi > sq_thresh->lower_threshold[index]) { - threshold = (A_UINT8)sq_thresh->lower_threshold[index]; + threshold = (u8)sq_thresh->lower_threshold[index]; break; } } @@ -5992,13 +5986,13 @@ wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_ NO_SYNC_WMIFLAG)); } -bss_t *wmi_rm_current_bss (struct wmi_t *wmip, A_UINT8 *id) +bss_t *wmi_rm_current_bss (struct wmi_t *wmip, u8 *id) { wmi_get_current_bssid (wmip, id); return wlan_node_remove (&wmip->wmi_scan_table, id); } -int wmi_add_current_bss (struct wmi_t *wmip, A_UINT8 *id, bss_t *bss) +int wmi_add_current_bss (struct wmi_t *wmip, u8 *id, bss_t *bss) { wlan_setup_node (&wmip->wmi_scan_table, bss, id); return A_OK; @@ -6006,7 +6000,7 @@ int wmi_add_current_bss (struct wmi_t *wmip, A_UINT8 *id, bss_t *bss) #ifdef ATH_AR6K_11N_SUPPORT static int -wmi_addba_req_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_addba_req_event_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_ADDBA_REQ_EVENT *cmd = (WMI_ADDBA_REQ_EVENT *)datap; @@ -6017,7 +6011,7 @@ wmi_addba_req_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) static int -wmi_addba_resp_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_addba_resp_event_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_ADDBA_RESP_EVENT *cmd = (WMI_ADDBA_RESP_EVENT *)datap; @@ -6027,7 +6021,7 @@ wmi_addba_resp_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_delba_req_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_delba_req_event_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_DELBA_EVENT *cmd = (WMI_DELBA_EVENT *)datap; @@ -6037,7 +6031,7 @@ wmi_delba_req_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } int -wmi_btcoex_config_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_btcoex_config_event_rx(struct wmi_t *wmip, u8 *datap, int len) { A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); @@ -6048,7 +6042,7 @@ wmi_btcoex_config_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) int -wmi_btcoex_stats_event_rx(struct wmi_t * wmip,A_UINT8 * datap,int len) +wmi_btcoex_stats_event_rx(struct wmi_t * wmip,u8 *datap,int len) { A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); @@ -6060,7 +6054,7 @@ wmi_btcoex_stats_event_rx(struct wmi_t * wmip,A_UINT8 * datap,int len) #endif static int -wmi_hci_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_hci_event_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_HCI_EVENT *cmd = (WMI_HCI_EVENT *)datap; A_WMI_HCI_EVENT_EVT(wmip->wmi_devt, cmd); @@ -6110,7 +6104,7 @@ wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p) * beacon. If it is enabled, ssid will be NULL in beacon. */ int -wmi_ap_set_hidden_ssid(struct wmi_t *wmip, A_UINT8 hidden_ssid) +wmi_ap_set_hidden_ssid(struct wmi_t *wmip, u8 hidden_ssid) { void *osbuf; WMI_AP_HIDDEN_SSID_CMD *hs; @@ -6139,7 +6133,7 @@ wmi_ap_set_hidden_ssid(struct wmi_t *wmip, A_UINT8 hidden_ssid) * in ioctl.c */ int -wmi_ap_set_num_sta(struct wmi_t *wmip, A_UINT8 num_sta) +wmi_ap_set_num_sta(struct wmi_t *wmip, u8 num_sta) { void *osbuf; WMI_AP_SET_NUM_STA_CMD *ns; @@ -6193,7 +6187,7 @@ wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *acl) * firware will allow all STAs till the count reaches AP_MAX_NUM_STA. */ int -wmi_ap_set_mlme(struct wmi_t *wmip, A_UINT8 cmd, A_UINT8 *mac, A_UINT16 reason) +wmi_ap_set_mlme(struct wmi_t *wmip, u8 cmd, u8 *mac, A_UINT16 reason) { void *osbuf; WMI_AP_SET_MLME_CMD *mlme; @@ -6215,7 +6209,7 @@ wmi_ap_set_mlme(struct wmi_t *wmip, A_UINT8 cmd, A_UINT8 *mac, A_UINT16 reason) } static int -wmi_pspoll_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) +wmi_pspoll_event_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_PSPOLL_EVENT *ev; @@ -6229,7 +6223,7 @@ wmi_pspoll_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) } static int -wmi_dtimexpiry_event_rx(struct wmi_t *wmip, A_UINT8 *datap,int len) +wmi_dtimexpiry_event_rx(struct wmi_t *wmip, u8 *datap,int len) { A_WMI_DTIMEXPIRY_EVENT(wmip->wmi_devt); return A_OK; @@ -6237,14 +6231,14 @@ wmi_dtimexpiry_event_rx(struct wmi_t *wmip, A_UINT8 *datap,int len) #ifdef WAPI_ENABLE static int -wmi_wapi_rekey_event_rx(struct wmi_t *wmip, A_UINT8 *datap,int len) +wmi_wapi_rekey_event_rx(struct wmi_t *wmip, u8 *datap,int len) { - A_UINT8 *ev; + u8 *ev; if (len < 7) { return A_EINVAL; } - ev = (A_UINT8 *)datap; + ev = (u8 *)datap; A_WMI_WAPI_REKEY_EVENT(wmip->wmi_devt, *ev, &ev[1]); return A_OK; @@ -6314,7 +6308,7 @@ wmi_ap_bgscan_time(struct wmi_t *wmip, A_UINT32 period, A_UINT32 dwell) } int -wmi_ap_set_dtim(struct wmi_t *wmip, A_UINT8 dtim) +wmi_ap_set_dtim(struct wmi_t *wmip, u8 dtim) { WMI_AP_SET_DTIM_CMD *cmd; void *osbuf = NULL; @@ -6342,7 +6336,7 @@ wmi_ap_set_dtim(struct wmi_t *wmip, A_UINT8 dtim) * If there is no chage in policy, the list will be intact. */ int -wmi_ap_set_acl_policy(struct wmi_t *wmip, A_UINT8 policy) +wmi_ap_set_acl_policy(struct wmi_t *wmip, u8 policy) { void *osbuf; WMI_AP_ACL_POLICY_CMD *po; @@ -6362,7 +6356,7 @@ wmi_ap_set_acl_policy(struct wmi_t *wmip, A_UINT8 policy) } int -wmi_ap_set_rateset(struct wmi_t *wmip, A_UINT8 rateset) +wmi_ap_set_rateset(struct wmi_t *wmip, u8 rateset) { void *osbuf; WMI_AP_SET_11BG_RATESET_CMD *rs; @@ -6387,7 +6381,7 @@ wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd) { void *osbuf; WMI_SET_HT_CAP_CMD *htCap; - A_UINT8 band; + u8 band; osbuf = A_NETBUF_ALLOC(sizeof(*htCap)); if (osbuf == NULL) { @@ -6408,7 +6402,7 @@ wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd) } int -wmi_set_ht_op_cmd(struct wmi_t *wmip, A_UINT8 sta_chan_width) +wmi_set_ht_op_cmd(struct wmi_t *wmip, u8 sta_chan_width) { void *osbuf; WMI_SET_HT_OP_CMD *htInfo; @@ -6451,7 +6445,7 @@ wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, A_UINT32 *pMaskArray) int -wmi_send_hci_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT16 sz) +wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, A_UINT16 sz) { void *osbuf; WMI_HCI_CMD *cmd; @@ -6491,7 +6485,7 @@ wmi_allow_aggr_cmd(struct wmi_t *wmip, A_UINT16 tx_tidmask, A_UINT16 rx_tidmask) } int -wmi_setup_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid) +wmi_setup_aggr_cmd(struct wmi_t *wmip, u8 tid) { void *osbuf; WMI_ADDBA_REQ_CMD *cmd; @@ -6510,7 +6504,7 @@ wmi_setup_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid) } int -wmi_delete_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid, bool uplink) +wmi_delete_aggr_cmd(struct wmi_t *wmip, u8 tid, bool uplink) { void *osbuf; WMI_DELBA_REQ_CMD *cmd; @@ -6532,7 +6526,7 @@ wmi_delete_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid, bool uplink) #endif int -wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, A_UINT8 rxMetaVersion, +wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, u8 rxMetaVersion, bool rxDot11Hdr, bool defragOnHost) { void *osbuf; @@ -6598,7 +6592,7 @@ wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE pre } int -wmi_set_pmk_cmd(struct wmi_t *wmip, A_UINT8 *pmk) +wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk) { void *osbuf; WMI_SET_PMK_CMD *p; @@ -6619,7 +6613,7 @@ wmi_set_pmk_cmd(struct wmi_t *wmip, A_UINT8 *pmk) } int -wmi_SGI_cmd(struct wmi_t *wmip, A_UINT32 sgiMask, A_UINT8 sgiPERThreshold) +wmi_SGI_cmd(struct wmi_t *wmip, A_UINT32 sgiMask, u8 sgiPERThreshold) { void *osbuf; WMI_SET_TX_SGI_PARAM_CMD *cmd; diff --git a/drivers/staging/ath6kl/wmi/wmi_host.h b/drivers/staging/ath6kl/wmi/wmi_host.h index c2a64019b0ed..f69b14031e2e 100644 --- a/drivers/staging/ath6kl/wmi/wmi_host.h +++ b/drivers/staging/ath6kl/wmi/wmi_host.h @@ -47,9 +47,9 @@ typedef struct sq_threshold_params_s { A_UINT32 upper_threshold_valid_count; A_UINT32 lower_threshold_valid_count; A_UINT32 polling_interval; - A_UINT8 weight; - A_UINT8 last_rssi; //normally you would expect this to be bss specific but we keep only one instance because its only valid when the device is in a connected state. Not sure if it belongs to host or target. - A_UINT8 last_rssi_poll_event; //Not sure if it belongs to host or target + u8 weight; + u8 last_rssi; //normally you would expect this to be bss specific but we keep only one instance because its only valid when the device is in a connected state. Not sure if it belongs to host or target. + u8 last_rssi_poll_event; //Not sure if it belongs to host or target } SQ_THRESHOLD_PARAMS; /* @@ -63,14 +63,14 @@ struct wmi_t { bool wmi_ready; bool wmi_numQoSStream; A_UINT16 wmi_streamExistsForAC[WMM_NUM_AC]; - A_UINT8 wmi_fatPipeExists; + u8 wmi_fatPipeExists; void *wmi_devt; struct wmi_stats wmi_stats; struct ieee80211_node_table wmi_scan_table; - A_UINT8 wmi_bssid[ATH_MAC_LEN]; - A_UINT8 wmi_powerMode; - A_UINT8 wmi_phyMode; - A_UINT8 wmi_keepaliveInterval; + u8 wmi_bssid[ATH_MAC_LEN]; + u8 wmi_powerMode; + u8 wmi_phyMode; + u8 wmi_keepaliveInterval; #ifdef THREAD_X A_CSECT_T wmi_lock; #else @@ -81,8 +81,8 @@ struct wmi_t { CRYPTO_TYPE wmi_pair_crypto_type; CRYPTO_TYPE wmi_grp_crypto_type; bool wmi_is_wmm_enabled; - A_UINT8 wmi_ht_allowed[A_NUM_BANDS]; - A_UINT8 wmi_traffic_class; + u8 wmi_ht_allowed[A_NUM_BANDS]; + u8 wmi_traffic_class; }; #ifdef THREAD_X -- cgit v1.2.3 From 4853ac05cff7745979830c52fe6fb46a7be6fa94 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 2 Feb 2011 14:05:50 -0800 Subject: staging: ath6kl: Convert A_UINT16 to u16 Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- .../staging/ath6kl/hif/common/hif_sdio_common.h | 2 +- .../staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 4 +- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 24 ++-- drivers/staging/ath6kl/htc2/htc_internal.h | 4 +- drivers/staging/ath6kl/htc2/htc_recv.c | 2 +- drivers/staging/ath6kl/include/a_debug.h | 2 +- drivers/staging/ath6kl/include/aggr_recv_api.h | 8 +- drivers/staging/ath6kl/include/ar3kconfig.h | 8 +- drivers/staging/ath6kl/include/common/a_hci.h | 106 +++++++------- .../staging/ath6kl/include/common/dset_internal.h | 4 +- .../staging/ath6kl/include/common/epping_test.h | 18 +-- drivers/staging/ath6kl/include/common/gmboxif.h | 8 +- drivers/staging/ath6kl/include/common/htc.h | 28 ++-- drivers/staging/ath6kl/include/common/ini_dset.h | 4 +- drivers/staging/ath6kl/include/common/pkt_log.h | 8 +- .../include/common/regulatory/reg_dbschema.h | 20 +-- drivers/staging/ath6kl/include/common/testcmd.h | 8 +- drivers/staging/ath6kl/include/common/wlan_dset.h | 2 +- drivers/staging/ath6kl/include/common/wmi.h | 158 ++++++++++----------- drivers/staging/ath6kl/include/common/wmi_thin.h | 22 +-- drivers/staging/ath6kl/include/htc_api.h | 4 +- drivers/staging/ath6kl/include/htc_packet.h | 2 +- drivers/staging/ath6kl/include/wlan_api.h | 12 +- drivers/staging/ath6kl/include/wmi_api.h | 65 +++++---- drivers/staging/ath6kl/miscdrv/ar3kconfig.c | 4 +- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c | 4 +- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h | 2 +- drivers/staging/ath6kl/miscdrv/common_drv.c | 4 +- drivers/staging/ath6kl/os/linux/ar6000_android.c | 4 +- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 88 ++++++------ drivers/staging/ath6kl/os/linux/ar6000_pm.c | 10 +- drivers/staging/ath6kl/os/linux/cfg80211.c | 28 ++-- drivers/staging/ath6kl/os/linux/eeprom.c | 8 +- drivers/staging/ath6kl/os/linux/hci_bridge.c | 8 +- .../staging/ath6kl/os/linux/include/ar6000_drv.h | 38 ++--- drivers/staging/ath6kl/os/linux/include/ar6k_pal.h | 2 +- .../ath6kl/os/linux/include/ar6xapi_linux.h | 20 +-- .../staging/ath6kl/os/linux/include/athdrv_linux.h | 10 +- drivers/staging/ath6kl/os/linux/include/cfg80211.h | 8 +- drivers/staging/ath6kl/os/linux/ioctl.c | 6 +- drivers/staging/ath6kl/os/linux/wireless_ext.c | 6 +- drivers/staging/ath6kl/reorder/aggr_rx_internal.h | 10 +- drivers/staging/ath6kl/reorder/rcv_aggr.c | 20 +-- drivers/staging/ath6kl/wlan/include/ieee80211.h | 10 +- drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c | 6 +- drivers/staging/ath6kl/wlan/src/wlan_utils.c | 5 +- drivers/staging/ath6kl/wmi/wmi.c | 122 ++++++++-------- drivers/staging/ath6kl/wmi/wmi_host.h | 2 +- 48 files changed, 472 insertions(+), 476 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/hif/common/hif_sdio_common.h b/drivers/staging/ath6kl/hif/common/hif_sdio_common.h index 299fd2583c7f..9939a4a30d25 100644 --- a/drivers/staging/ath6kl/hif/common/hif_sdio_common.h +++ b/drivers/staging/ath6kl/hif/common/hif_sdio_common.h @@ -58,7 +58,7 @@ #define HIF_DEFAULT_IO_BLOCK_SIZE 128 /* set extended MBOX window information for SDIO interconnects */ -static INLINE void SetExtendedMboxWindowInfo(A_UINT16 Manfid, HIF_DEVICE_MBOX_INFO *pInfo) +static INLINE void SetExtendedMboxWindowInfo(u16 Manfid, HIF_DEVICE_MBOX_INFO *pInfo) { switch (Manfid & MANUFACTURER_ID_AR6K_BASE_MASK) { case MANUFACTURER_ID_AR6002_BASE : diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index ced9079e6060..539b6d226ba7 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -507,7 +507,7 @@ int ReinitSDIO(HIF_DEVICE *device) do { if (!device->is_suspend) { A_UINT32 resp; - A_UINT16 rca; + u16 rca; A_UINT32 i; int bit = fls(host->ocr_avail) - 1; /* emulate the mmc_power_up(...) */ @@ -711,7 +711,7 @@ HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, } if (configLen >= sizeof(HIF_DEVICE_MBOX_INFO)) { - SetExtendedMboxWindowInfo((A_UINT16)device->func->device, + SetExtendedMboxWindowInfo((u16)device->func->device, (HIF_DEVICE_MBOX_INFO *)config); } diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index ad14a2f7effb..6a05f4bccbde 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -1042,13 +1042,13 @@ static void AssembleBufferList(BUFFER_PROC_LIST *pList) #define FILL_COUNTING false static void InitBuffers(bool Zero) { - A_UINT16 *pBuffer16 = (A_UINT16 *)g_Buffer; + u16 *pBuffer16 = (u16 *)g_Buffer; int i; /* fill buffer with 16 bit counting pattern or zeros */ for (i = 0; i < (TOTAL_BYTES / 2) ; i++) { if (!Zero) { - pBuffer16[i] = (A_UINT16)i; + pBuffer16[i] = (u16)i; } else { pBuffer16[i] = 0; } @@ -1056,10 +1056,10 @@ static void InitBuffers(bool Zero) } -static bool CheckOneBuffer(A_UINT16 *pBuffer16, int Length) +static bool CheckOneBuffer(u16 *pBuffer16, int Length) { int i; - A_UINT16 startCount; + u16 startCount; bool success = true; /* get the starting count */ @@ -1069,10 +1069,10 @@ static bool CheckOneBuffer(A_UINT16 *pBuffer16, int Length) /* scan the buffer and verify */ for (i = 0; i < (Length / 2) ; i++,startCount++) { /* target will invert all the data */ - if ((A_UINT16)pBuffer16[i] != (A_UINT16)~startCount) { + if ((u16)pBuffer16[i] != (u16)~startCount) { success = false; AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid Data Got:0x%X, Expecting:0x%X (offset:%d, total:%d) \n", - pBuffer16[i], ((A_UINT16)~startCount), i, Length)); + pBuffer16[i], ((u16)~startCount), i, Length)); AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("0x%X 0x%X 0x%X 0x%X \n", pBuffer16[i], pBuffer16[i + 1], pBuffer16[i + 2],pBuffer16[i+3])); break; @@ -1093,7 +1093,7 @@ static bool CheckBuffers(void) /* scan the buffers and verify */ for (i = 0; i < BUFFER_PROC_LIST_DEPTH ; i++) { - success = CheckOneBuffer((A_UINT16 *)checkList[i].pBuffer, checkList[i].length); + success = CheckOneBuffer((u16 *)checkList[i].pBuffer, checkList[i].length); if (!success) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Buffer : 0x%X, Length:%d failed verify \n", (A_UINT32)checkList[i].pBuffer, checkList[i].length)); @@ -1105,7 +1105,7 @@ static bool CheckBuffers(void) } /* find the end marker for the last buffer we will be sending */ -static A_UINT16 GetEndMarker(void) +static u16 GetEndMarker(void) { u8 *pBuffer; BUFFER_PROC_LIST checkList[BUFFER_PROC_LIST_DEPTH]; @@ -1119,7 +1119,7 @@ static A_UINT16 GetEndMarker(void) pBuffer = &(checkList[BUFFER_PROC_LIST_DEPTH - 1].pBuffer[(checkList[BUFFER_PROC_LIST_DEPTH - 1].length) - 2]); /* the last count in the last buffer is the marker */ - return (A_UINT16)pBuffer[0] | ((A_UINT16)pBuffer[1] << 8); + return (u16)pBuffer[0] | ((u16)pBuffer[1] << 8); } #define ATH_PRINT_OUT_ZONE ATH_DEBUG_ERR @@ -1338,7 +1338,7 @@ int DoMboxHWTest(AR6K_DEVICE *pDev) u8 params[4]; int numBufs; int bufferSize; - A_UINT16 temp; + u16 temp; AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest START - \n")); @@ -1401,7 +1401,7 @@ int DoMboxHWTest(AR6K_DEVICE *pDev) } numBufs = params[0]; - bufferSize = (int)(((A_UINT16)params[2] << 8) | (A_UINT16)params[1]); + bufferSize = (int)(((u16)params[2] << 8) | (u16)params[1]); AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Target parameters: bufs per mailbox:%d, buffer size:%d bytes (total space: %d, minimum required space (w/padding): %d) \n", @@ -1430,7 +1430,7 @@ int DoMboxHWTest(AR6K_DEVICE *pDev) AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("End Marker: 0x%X \n",temp)); - temp = (A_UINT16)g_BlockSizes[1]; + temp = (u16)g_BlockSizes[1]; /* convert to a mask */ temp = temp - 1; status = HIFReadWrite(pDev->HIFDevice, diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h index 332ab8529657..180ad9d9650e 100644 --- a/drivers/staging/ath6kl/htc2/htc_internal.h +++ b/drivers/staging/ath6kl/htc2/htc_internal.h @@ -178,7 +178,7 @@ void HTCFlushSendPkts(HTC_TARGET *target); #ifdef ATH_DEBUG_MODULE void DumpCreditDist(HTC_ENDPOINT_CREDIT_DIST *pEPDist); void DumpCreditDistStates(HTC_TARGET *target); -void DebugDumpBytes(A_UCHAR *buffer, A_UINT16 length, char *pDescription); +void DebugDumpBytes(A_UCHAR *buffer, u16 length, char *pDescription); #endif static INLINE HTC_PACKET *HTC_ALLOC_CONTROL_TX(HTC_TARGET *target) { @@ -203,7 +203,7 @@ static INLINE HTC_PACKET *HTC_ALLOC_CONTROL_TX(HTC_TARGET *target) { u8 *pHdrBuf; \ (pP)->pBuffer -= HTC_HDR_LENGTH; \ pHdrBuf = (pP)->pBuffer; \ - A_SET_UINT16_FIELD(pHdrBuf,HTC_FRAME_HDR,PayloadLen,(A_UINT16)(pP)->ActualLength); \ + A_SET_UINT16_FIELD(pHdrBuf,HTC_FRAME_HDR,PayloadLen,(u16)(pP)->ActualLength); \ A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,Flags,(sendflags)); \ A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,EndpointID, (u8)(pP)->Endpoint); \ A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,ControlBytes[0], (u8)(ctrl0)); \ diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c index 0b09b22ca8e0..66e5ced10e89 100644 --- a/drivers/staging/ath6kl/htc2/htc_recv.c +++ b/drivers/staging/ath6kl/htc2/htc_recv.c @@ -234,7 +234,7 @@ static int HTCProcessRecvHeader(HTC_TARGET *target, u8 temp; u8 *pBuf; int status = A_OK; - A_UINT16 payloadLen; + u16 payloadLen; A_UINT32 lookAhead; pBuf = pPacket->pBuffer; diff --git a/drivers/staging/ath6kl/include/a_debug.h b/drivers/staging/ath6kl/include/a_debug.h index 4cc7b6beffde..dbba3f85616f 100644 --- a/drivers/staging/ath6kl/include/a_debug.h +++ b/drivers/staging/ath6kl/include/a_debug.h @@ -57,7 +57,7 @@ extern "C" { /* macro to make a module-specific masks */ #define ATH_DEBUG_MAKE_MODULE_MASK(index) (1 << (ATH_DEBUG_MODULE_MASK_SHIFT + (index))) -void DebugDumpBytes(A_UCHAR *buffer, A_UINT16 length, char *pDescription); +void DebugDumpBytes(A_UCHAR *buffer, u16 length, char *pDescription); /* Debug support on a per-module basis * diff --git a/drivers/staging/ath6kl/include/aggr_recv_api.h b/drivers/staging/ath6kl/include/aggr_recv_api.h index 8f76f3744b5e..67a058492c4d 100644 --- a/drivers/staging/ath6kl/include/aggr_recv_api.h +++ b/drivers/staging/ath6kl/include/aggr_recv_api.h @@ -30,7 +30,7 @@ extern "C" { typedef void (* RX_CALLBACK)(void * dev, void *osbuf); -typedef void (* ALLOC_NETBUFS)(A_NETBUF_QUEUE_T *q, A_UINT16 num); +typedef void (* ALLOC_NETBUFS)(A_NETBUF_QUEUE_T *q, u16 num); /* * aggr_init: @@ -64,7 +64,7 @@ aggr_register_rx_dispatcher(void *cntxt, void * dev, RX_CALLBACK fn); * up to the indicated sequence number. */ void -aggr_process_bar(void *cntxt, u8 tid, A_UINT16 seq_no); +aggr_process_bar(void *cntxt, u8 tid, u16 seq_no); /* @@ -82,7 +82,7 @@ aggr_process_bar(void *cntxt, u8 tid, A_UINT16 seq_no); * in hold_q to OS. */ void -aggr_recv_addba_req_evt(void * cntxt, u8 tid, A_UINT16 seq_no, u8 win_sz); +aggr_recv_addba_req_evt(void * cntxt, u8 tid, u16 seq_no, u8 win_sz); /* @@ -108,7 +108,7 @@ aggr_recv_delba_req_evt(void * cntxt, u8 tid); * callback may be called to deliver frames in order. */ void -aggr_process_recv_frm(void *cntxt, u8 tid, A_UINT16 seq_no, bool is_amsdu, void **osbuf); +aggr_process_recv_frm(void *cntxt, u8 tid, u16 seq_no, bool is_amsdu, void **osbuf); /* diff --git a/drivers/staging/ath6kl/include/ar3kconfig.h b/drivers/staging/ath6kl/include/ar3kconfig.h index 5556660b270f..b7c503975c11 100644 --- a/drivers/staging/ath6kl/include/ar3kconfig.h +++ b/drivers/staging/ath6kl/include/ar3kconfig.h @@ -45,12 +45,12 @@ typedef struct { HIF_DEVICE *pHIFDevice; /* HIF layer device */ A_UINT32 AR3KBaudRate; /* AR3K operational baud rate */ - A_UINT16 AR6KScale; /* AR6K UART scale value */ - A_UINT16 AR6KStep; /* AR6K UART step value */ + u16 AR6KScale; /* AR6K UART scale value */ + u16 AR6KStep; /* AR6K UART step value */ struct hci_dev *pBtStackHCIDev; /* BT Stack HCI dev */ A_UINT32 PwrMgmtEnabled; /* TLPM enabled? */ - A_UINT16 IdleTimeout; /* TLPM idle timeout */ - A_UINT16 WakeupTimeout; /* TLPM wakeup timeout */ + u16 IdleTimeout; /* TLPM idle timeout */ + u16 WakeupTimeout; /* TLPM wakeup timeout */ u8 bdaddr[6]; /* Bluetooth device address */ } AR3K_CONFIG_INFO; diff --git a/drivers/staging/ath6kl/include/common/a_hci.h b/drivers/staging/ath6kl/include/common/a_hci.h index 1d7d5fa35421..317ea57ba87f 100644 --- a/drivers/staging/ath6kl/include/common/a_hci.h +++ b/drivers/staging/ath6kl/include/common/a_hci.h @@ -242,7 +242,7 @@ typedef enum { /* Command pkt */ typedef struct hci_cmd_pkt_t { - A_UINT16 opcode; + u16 opcode; u8 param_length; u8 params[255]; } POSTPACK HCI_CMD_PKT; @@ -250,8 +250,8 @@ typedef struct hci_cmd_pkt_t { #define ACL_DATA_HDR_SIZE 4 /* hdl_and flags + data_len */ /* Data pkt */ typedef struct hci_acl_data_pkt_t { - A_UINT16 hdl_and_flags; - A_UINT16 data_len; + u16 hdl_and_flags; + u16 data_len; u8 data[Max80211_PAL_PDU_Size]; } POSTPACK HCI_ACL_DATA_PKT; @@ -265,7 +265,7 @@ typedef struct hci_event_pkt_t { /*============== HCI Command definitions ======================= */ typedef struct hci_cmd_phy_link_t { - A_UINT16 opcode; + u16 opcode; u8 param_length; u8 phy_link_hdl; u8 link_key_len; @@ -274,62 +274,62 @@ typedef struct hci_cmd_phy_link_t { } POSTPACK HCI_CMD_PHY_LINK; typedef struct hci_cmd_write_rem_amp_assoc_t { - A_UINT16 opcode; + u16 opcode; u8 param_length; u8 phy_link_hdl; - A_UINT16 len_so_far; - A_UINT16 amp_assoc_remaining_len; + u16 len_so_far; + u16 amp_assoc_remaining_len; u8 amp_assoc_frag[AMP_ASSOC_MAX_FRAG_SZ]; } POSTPACK HCI_CMD_WRITE_REM_AMP_ASSOC; typedef struct hci_cmd_opcode_hdl_t { - A_UINT16 opcode; + u16 opcode; u8 param_length; - A_UINT16 hdl; + u16 hdl; } POSTPACK HCI_CMD_READ_LINK_QUAL, HCI_CMD_FLUSH, HCI_CMD_READ_LINK_SUPERVISION_TIMEOUT; typedef struct hci_cmd_read_local_amp_assoc_t { - A_UINT16 opcode; + u16 opcode; u8 param_length; u8 phy_link_hdl; - A_UINT16 len_so_far; - A_UINT16 max_rem_amp_assoc_len; + u16 len_so_far; + u16 max_rem_amp_assoc_len; } POSTPACK HCI_CMD_READ_LOCAL_AMP_ASSOC; typedef struct hci_cmd_set_event_mask_t { - A_UINT16 opcode; + u16 opcode; u8 param_length; A_UINT64 mask; }POSTPACK HCI_CMD_SET_EVT_MASK, HCI_CMD_SET_EVT_MASK_PG_2; typedef struct hci_cmd_enhanced_flush_t{ - A_UINT16 opcode; + u16 opcode; u8 param_length; - A_UINT16 hdl; + u16 hdl; u8 type; } POSTPACK HCI_CMD_ENHANCED_FLUSH; typedef struct hci_cmd_write_timeout_t { - A_UINT16 opcode; + u16 opcode; u8 param_length; - A_UINT16 timeout; + u16 timeout; } POSTPACK HCI_CMD_WRITE_TIMEOUT; typedef struct hci_cmd_write_link_supervision_timeout_t { - A_UINT16 opcode; + u16 opcode; u8 param_length; - A_UINT16 hdl; - A_UINT16 timeout; + u16 hdl; + u16 timeout; } POSTPACK HCI_CMD_WRITE_LINK_SUPERVISION_TIMEOUT; typedef struct hci_cmd_write_flow_control_t { - A_UINT16 opcode; + u16 opcode; u8 param_length; u8 mode; } POSTPACK HCI_CMD_WRITE_FLOW_CONTROL; @@ -341,7 +341,7 @@ typedef struct location_data_cfg_t { } POSTPACK LOCATION_DATA_CFG; typedef struct hci_cmd_write_location_data_t { - A_UINT16 opcode; + u16 opcode; u8 param_length; LOCATION_DATA_CFG cfg; } POSTPACK HCI_CMD_WRITE_LOCATION_DATA; @@ -350,7 +350,7 @@ typedef struct hci_cmd_write_location_data_t { typedef struct flow_spec_t { u8 id; u8 service_type; - A_UINT16 max_sdu; + u16 max_sdu; A_UINT32 sdu_inter_arrival_time; A_UINT32 access_latency; A_UINT32 flush_timeout; @@ -358,7 +358,7 @@ typedef struct flow_spec_t { typedef struct hci_cmd_create_logical_link_t { - A_UINT16 opcode; + u16 opcode; u8 param_length; u8 phy_link_hdl; FLOW_SPEC tx_flow_spec; @@ -366,34 +366,34 @@ typedef struct hci_cmd_create_logical_link_t { } POSTPACK HCI_CMD_CREATE_LOGICAL_LINK; typedef struct hci_cmd_flow_spec_modify_t { - A_UINT16 opcode; + u16 opcode; u8 param_length; - A_UINT16 hdl; + u16 hdl; FLOW_SPEC tx_flow_spec; FLOW_SPEC rx_flow_spec; } POSTPACK HCI_CMD_FLOW_SPEC_MODIFY; typedef struct hci_cmd_logical_link_cancel_t { - A_UINT16 opcode; + u16 opcode; u8 param_length; u8 phy_link_hdl; u8 tx_flow_spec_id; } POSTPACK HCI_CMD_LOGICAL_LINK_CANCEL; typedef struct hci_cmd_disconnect_logical_link_t { - A_UINT16 opcode; + u16 opcode; u8 param_length; - A_UINT16 logical_link_hdl; + u16 logical_link_hdl; } POSTPACK HCI_CMD_DISCONNECT_LOGICAL_LINK; typedef struct hci_cmd_disconnect_phy_link_t { - A_UINT16 opcode; + u16 opcode; u8 param_length; u8 phy_link_hdl; } POSTPACK HCI_CMD_DISCONNECT_PHY_LINK; typedef struct hci_cmd_srm_t { - A_UINT16 opcode; + u16 opcode; u8 param_length; u8 phy_link_hdl; u8 mode; @@ -409,7 +409,7 @@ typedef struct hci_event_cmd_complete_t { u8 event_code; u8 param_len; u8 num_hci_cmd_pkts; - A_UINT16 opcode; + u16 opcode; u8 params[255]; } POSTPACK HCI_EVENT_CMD_COMPLETE; @@ -420,7 +420,7 @@ typedef struct hci_event_cmd_status_t { u8 param_len; u8 status; u8 num_hci_cmd_pkts; - A_UINT16 opcode; + u16 opcode; } POSTPACK HCI_EVENT_CMD_STATUS; /* Hardware Error event */ @@ -435,7 +435,7 @@ typedef struct hci_event_hw_err_t { typedef struct hci_event_handle_t { u8 event_code; u8 param_len; - A_UINT16 handle; + u16 handle; } POSTPACK HCI_EVENT_FLUSH_OCCRD, HCI_EVENT_QOS_VIOLATION; @@ -457,7 +457,7 @@ typedef struct hci_data_buf_overflow_t { typedef struct hci_enhanced_flush_complt_t{ u8 event_code; u8 param_len; - A_UINT16 hdl; + u16 hdl; } POSTPACK HCI_EVENT_ENHANCED_FLUSH_COMPLT; /* Channel select event */ @@ -480,7 +480,7 @@ typedef struct hci_event_logical_link_complete_event_t { u8 event_code; u8 param_len; u8 status; - A_UINT16 logical_link_hdl; + u16 logical_link_hdl; u8 phy_hdl; u8 tx_flow_id; } POSTPACK HCI_EVENT_LOGICAL_LINK_COMPLETE_EVENT; @@ -490,7 +490,7 @@ typedef struct hci_event_disconnect_logical_link_event_t { u8 event_code; u8 param_len; u8 status; - A_UINT16 logical_link_hdl; + u16 logical_link_hdl; u8 reason; } POSTPACK HCI_EVENT_DISCONNECT_LOGICAL_LINK_EVENT; @@ -523,7 +523,7 @@ typedef struct hci_event_status_handle_t { u8 event_code; u8 param_len; u8 status; - A_UINT16 handle; + u16 handle; } POSTPACK HCI_EVENT_FLOW_SPEC_MODIFY, HCI_EVENT_FLUSH; @@ -532,7 +532,7 @@ typedef struct hci_event_status_handle_t { typedef struct hci_event_num_of_compl_data_blks_t { u8 event_code; u8 param_len; - A_UINT16 num_data_blks; + u16 num_data_blks; u8 num_handles; u8 params[255]; } POSTPACK HCI_EVENT_NUM_COMPL_DATA_BLKS; @@ -564,8 +564,8 @@ typedef struct local_amp_info_resp_t { A_UINT32 min_latency; A_UINT32 max_pdu_size; u8 amp_type; - A_UINT16 pal_capabilities; - A_UINT16 amp_assoc_len; + u16 pal_capabilities; + u16 amp_assoc_len; A_UINT32 max_flush_timeout; /* in ms */ A_UINT32 be_flush_timeout; /* in ms */ } POSTPACK LOCAL_AMP_INFO; @@ -573,7 +573,7 @@ typedef struct local_amp_info_resp_t { typedef struct amp_assoc_cmd_resp_t{ u8 status; u8 phy_hdl; - A_UINT16 amp_assoc_len; + u16 amp_assoc_len; u8 amp_assoc_frag[AMP_ASSOC_MAX_FRAG_SZ]; }POSTPACK AMP_ASSOC_CMD_RESP; @@ -619,18 +619,18 @@ enum PAL_HCI_CMD_STATUS { */ typedef struct timeout_read_t { u8 status; - A_UINT16 timeout; + u16 timeout; }POSTPACK TIMEOUT_INFO; typedef struct link_supervision_timeout_read_t { u8 status; - A_UINT16 hdl; - A_UINT16 timeout; + u16 hdl; + u16 timeout; }POSTPACK LINK_SUPERVISION_TIMEOUT_INFO; typedef struct status_hdl_t { u8 status; - A_UINT16 hdl; + u16 hdl; }POSTPACK INFO_STATUS_HDL; typedef struct write_remote_amp_assoc_t{ @@ -650,15 +650,15 @@ typedef struct read_flow_ctrl_mode_t { typedef struct read_data_blk_size_t { u8 status; - A_UINT16 max_acl_data_pkt_len; - A_UINT16 data_block_len; - A_UINT16 total_num_data_blks; + u16 max_acl_data_pkt_len; + u16 data_block_len; + u16 total_num_data_blks; }POSTPACK READ_DATA_BLK_SIZE_INFO; /* Read Link quality info */ typedef struct link_qual_t { u8 status; - A_UINT16 hdl; + u16 hdl; u8 link_qual; } POSTPACK READ_LINK_QUAL_INFO, READ_RSSI_INFO; @@ -672,10 +672,10 @@ typedef struct ll_cancel_resp_t { typedef struct read_local_ver_info_t { u8 status; u8 hci_version; - A_UINT16 hci_revision; + u16 hci_revision; u8 pal_version; - A_UINT16 manf_name; - A_UINT16 pal_sub_ver; + u16 manf_name; + u16 pal_sub_ver; } POSTPACK READ_LOCAL_VER_INFO; diff --git a/drivers/staging/ath6kl/include/common/dset_internal.h b/drivers/staging/ath6kl/include/common/dset_internal.h index 2460f0ecf12b..74914f9cb3c4 100644 --- a/drivers/staging/ath6kl/include/common/dset_internal.h +++ b/drivers/staging/ath6kl/include/common/dset_internal.h @@ -42,8 +42,8 @@ typedef PREPACK struct dset_descriptor_s { struct dset_descriptor_s *next; /* List link. NULL only at the last descriptor */ - A_UINT16 id; /* Dset ID */ - A_UINT16 size; /* Dset size. */ + u16 id; /* Dset ID */ + u16 size; /* Dset size. */ void *DataPtr; /* Pointer to raw data for standard DataSet or pointer to original dset_descriptor for patched diff --git a/drivers/staging/ath6kl/include/common/epping_test.h b/drivers/staging/ath6kl/include/common/epping_test.h index 061884dfb337..45f82dd79236 100644 --- a/drivers/staging/ath6kl/include/common/epping_test.h +++ b/drivers/staging/ath6kl/include/common/epping_test.h @@ -56,13 +56,13 @@ typedef PREPACK struct { u8 TimeStamp[8]; /* timestamp of packet (host or target) */ A_UINT32 HostContext_h; /* 4 byte host context, target echos this back */ A_UINT32 SeqNo; /* sequence number (set by host or target) */ - A_UINT16 Cmd_h; /* ping command (filled by host) */ - A_UINT16 CmdFlags_h; /* optional flags */ + u16 Cmd_h; /* ping command (filled by host) */ + u16 CmdFlags_h; /* optional flags */ u8 CmdBuffer_h[8]; /* buffer for command (host -> target) */ u8 CmdBuffer_t[8]; /* buffer for command (target -> host) */ - A_UINT16 DataLength; /* length of data */ - A_UINT16 DataCRC; /* 16 bit CRC of data */ - A_UINT16 HeaderCRC; /* header CRC (fields : StreamNo_h to end, minus HeaderCRC) */ + u16 DataLength; /* length of data */ + u16 DataCRC; /* 16 bit CRC of data */ + u16 HeaderCRC; /* header CRC (fields : StreamNo_h to end, minus HeaderCRC) */ } POSTPACK EPPING_HEADER; #define EPPING_PING_MAGIC_0 0xAA @@ -97,9 +97,9 @@ typedef PREPACK struct { /* test command parameters may be no more than 8 bytes */ typedef PREPACK struct { - A_UINT16 BurstCnt; /* number of packets to burst together (for HTC 2.1 testing) */ - A_UINT16 PacketLength; /* length of packet to generate including header */ - A_UINT16 Flags; /* flags */ + u16 BurstCnt; /* number of packets to burst together (for HTC 2.1 testing) */ + u16 PacketLength; /* length of packet to generate including header */ + u16 Flags; /* flags */ #define EPPING_CONT_RX_DATA_CRC (1 << 0) /* Add CRC to all data */ #define EPPING_CONT_RX_RANDOM_DATA (1 << 1) /* randomize the data pattern */ @@ -107,7 +107,7 @@ typedef PREPACK struct { } POSTPACK EPPING_CONT_RX_PARAMS; #define EPPING_HDR_CRC_OFFSET A_OFFSETOF(EPPING_HEADER,StreamNo_h) -#define EPPING_HDR_BYTES_CRC (sizeof(EPPING_HEADER) - EPPING_HDR_CRC_OFFSET - (sizeof(A_UINT16))) +#define EPPING_HDR_BYTES_CRC (sizeof(EPPING_HEADER) - EPPING_HDR_CRC_OFFSET - (sizeof(u16))) #define HCI_TRANSPORT_STREAM_NUM 16 /* this number is higher than the define WMM AC classes so we can use this to distinguish packets */ diff --git a/drivers/staging/ath6kl/include/common/gmboxif.h b/drivers/staging/ath6kl/include/common/gmboxif.h index 374007569d6d..dd9afbd78ff9 100644 --- a/drivers/staging/ath6kl/include/common/gmboxif.h +++ b/drivers/staging/ath6kl/include/common/gmboxif.h @@ -41,17 +41,17 @@ /* definitions for BT HCI packets */ typedef PREPACK struct { - A_UINT16 Flags_ConnHandle; - A_UINT16 Length; + u16 Flags_ConnHandle; + u16 Length; } POSTPACK BT_HCI_ACL_HEADER; typedef PREPACK struct { - A_UINT16 Flags_ConnHandle; + u16 Flags_ConnHandle; u8 Length; } POSTPACK BT_HCI_SCO_HEADER; typedef PREPACK struct { - A_UINT16 OpCode; + u16 OpCode; u8 ParamLength; } POSTPACK BT_HCI_COMMAND_HEADER; diff --git a/drivers/staging/ath6kl/include/common/htc.h b/drivers/staging/ath6kl/include/common/htc.h index 13a24da3af8e..6c85bebd994d 100644 --- a/drivers/staging/ath6kl/include/common/htc.h +++ b/drivers/staging/ath6kl/include/common/htc.h @@ -31,7 +31,7 @@ #define A_OFFSETOF(type,field) (unsigned long)(&(((type *)NULL)->field)) #define ASSEMBLE_UNALIGNED_UINT16(p,highbyte,lowbyte) \ - (((A_UINT16)(((u8 *)(p))[(highbyte)])) << 8 | (A_UINT16)(((u8 *)(p))[(lowbyte)])) + (((u16)(((u8 *)(p))[(highbyte)])) << 8 | (u16)(((u8 *)(p))[(lowbyte)])) /* alignment independent macros (little-endian) to fetch UINT16s or UINT8s from a * structure using only the type and field name. @@ -71,7 +71,7 @@ typedef PREPACK struct _HTC_FRAME_HDR{ * to take advantage of 4-byte lookaheads in some hardware implementations */ u8 EndpointID; u8 Flags; - A_UINT16 PayloadLen; /* length of data (including trailer) that follows the header */ + u16 PayloadLen; /* length of data (including trailer) that follows the header */ /***** end of 4-byte lookahead ****/ @@ -110,15 +110,15 @@ typedef PREPACK struct _HTC_FRAME_HDR{ /* base message ID header */ typedef PREPACK struct { - A_UINT16 MessageID; + u16 MessageID; } POSTPACK HTC_UNKNOWN_MSG; /* HTC ready message * direction : target-to-host */ typedef PREPACK struct { - A_UINT16 MessageID; /* ID */ - A_UINT16 CreditCount; /* number of credits the target can offer */ - A_UINT16 CreditSize; /* size of each credit */ + u16 MessageID; /* ID */ + u16 CreditCount; /* number of credits the target can offer */ + u16 CreditSize; /* size of each credit */ u8 MaxEndpoints; /* maximum number of endpoints the target has resources for */ u8 _Pad1; } POSTPACK HTC_READY_MSG; @@ -139,9 +139,9 @@ typedef PREPACK struct { /* connect service * direction : host-to-target */ typedef PREPACK struct { - A_UINT16 MessageID; - A_UINT16 ServiceID; /* service ID of the service to connect to */ - A_UINT16 ConnectionFlags; /* connection flags */ + u16 MessageID; + u16 ServiceID; /* service ID of the service to connect to */ + u16 ConnectionFlags; /* connection flags */ #define HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE (1 << 2) /* reduce credit dribbling when the host needs credits */ @@ -161,11 +161,11 @@ typedef PREPACK struct { /* connect response * direction : target-to-host */ typedef PREPACK struct { - A_UINT16 MessageID; - A_UINT16 ServiceID; /* service ID that the connection request was made */ + u16 MessageID; + u16 ServiceID; /* service ID that the connection request was made */ u8 Status; /* service connection status */ u8 EndpointID; /* assigned endpoint ID */ - A_UINT16 MaxMsgSize; /* maximum expected message size on this endpoint */ + u16 MaxMsgSize; /* maximum expected message size on this endpoint */ u8 ServiceMetaLength; /* length of meta data that follows */ u8 _Pad1; @@ -174,13 +174,13 @@ typedef PREPACK struct { } POSTPACK HTC_CONNECT_SERVICE_RESPONSE_MSG; typedef PREPACK struct { - A_UINT16 MessageID; + u16 MessageID; /* currently, no other fields */ } POSTPACK HTC_SETUP_COMPLETE_MSG; /* extended setup completion message */ typedef PREPACK struct { - A_UINT16 MessageID; + u16 MessageID; A_UINT32 SetupFlags; u8 MaxMsgsPerBundledRecv; u8 Rsvd[3]; diff --git a/drivers/staging/ath6kl/include/common/ini_dset.h b/drivers/staging/ath6kl/include/common/ini_dset.h index 8cf1af834bd0..d6f2301f5713 100644 --- a/drivers/staging/ath6kl/include/common/ini_dset.h +++ b/drivers/staging/ath6kl/include/common/ini_dset.h @@ -74,8 +74,8 @@ typedef enum { } WHAL_INI_DATA_ID; typedef PREPACK struct { - A_UINT16 freqIndex; // 1 - A mode 2 - B or G mode 0 - common - A_UINT16 offset; + u16 freqIndex; // 1 - A mode 2 - B or G mode 0 - common + u16 offset; A_UINT32 newValue; } POSTPACK INI_DSET_REG_OVERRIDE; diff --git a/drivers/staging/ath6kl/include/common/pkt_log.h b/drivers/staging/ath6kl/include/common/pkt_log.h index 331cc04edada..a3719adf54ca 100644 --- a/drivers/staging/ath6kl/include/common/pkt_log.h +++ b/drivers/staging/ath6kl/include/common/pkt_log.h @@ -31,11 +31,11 @@ extern "C" { /* Pkt log info */ typedef PREPACK struct pkt_log_t { struct info_t { - A_UINT16 st; - A_UINT16 end; - A_UINT16 cur; + u16 st; + u16 end; + u16 cur; }info[4096]; - A_UINT16 last_idx; + u16 last_idx; }POSTPACK PACKET_LOG; diff --git a/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h b/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h index a50e9eb24581..36e266fe02dd 100644 --- a/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h +++ b/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h @@ -128,7 +128,7 @@ typedef PREPACK struct dbMasterTable_t { /* Hold ptrs to Table data structure char entrySize; /* Entry size per table row */ char searchType; /* Index based access or key based */ char reserved[3]; /* for alignment */ - A_UINT16 tableSize; /* Size of this table */ + u16 tableSize; /* Size of this table */ char *dataPtr; /* Ptr to the actual Table */ } POSTPACK dbMasterTable; /* Master table - table of tables */ @@ -169,9 +169,9 @@ typedef PREPACK struct dbMasterTable_t { /* Hold ptrs to Table data structure */ typedef PREPACK struct reg_dmn_pair_mapping { - A_UINT16 regDmnEnum; /* 16 bit reg domain pair */ - A_UINT16 regDmn5GHz; /* 5GHz reg domain */ - A_UINT16 regDmn2GHz; /* 2GHz reg domain */ + u16 regDmnEnum; /* 16 bit reg domain pair */ + u16 regDmn5GHz; /* 5GHz reg domain */ + u16 regDmn2GHz; /* 2GHz reg domain */ u8 flags5GHz; /* Requirements flags (AdHoc disallow etc) */ u8 flags2GHz; /* Requirements flags (AdHoc disallow etc) */ A_UINT32 pscanMask; /* Passive Scan flags which can override unitary domain passive scan @@ -188,8 +188,8 @@ typedef PREPACK struct reg_dmn_pair_mapping { #define MCS_HT40_G_NO (0 << 3) typedef PREPACK struct { - A_UINT16 countryCode; - A_UINT16 regDmnEnum; + u16 countryCode; + u16 regDmnEnum; char isoName[3]; char allowMode; /* what mode is allowed - bit 0: OFDM; bit 1: MCS_HT20; bit 2: MCS_HT40_A; bit 3: MCS_HT40_G */ } POSTPACK COUNTRY_CODE_TO_ENUM_RD; @@ -209,8 +209,8 @@ typedef PREPACK struct { #define FREQ_QUARTER_RATE 0x20000 typedef PREPACK struct RegDmnFreqBand { - A_UINT16 lowChannel; /* Low channel center in MHz */ - A_UINT16 highChannel; /* High Channel center in MHz */ + u16 lowChannel; /* Low channel center in MHz */ + u16 highChannel; /* High Channel center in MHz */ u8 power; /* Max power (dBm) for channel range */ u8 channelSep; /* Channel separation within the band */ u8 useDfs; /* Use DFS in the RegDomain if corresponding bit is set */ @@ -223,12 +223,12 @@ typedef PREPACK struct RegDmnFreqBand { typedef PREPACK struct regDomain { - A_UINT16 regDmnEnum; /* value from EnumRd table */ + u16 regDmnEnum; /* value from EnumRd table */ u8 rdCTL; u8 maxAntGain; u8 dfsMask; /* DFS bitmask for 5Ghz tables */ u8 flags; /* Requirement flags (AdHoc disallow etc) */ - A_UINT16 reserved; /* for alignment */ + u16 reserved; /* for alignment */ A_UINT32 pscan; /* Bitmask for passive scan */ A_UINT32 chan11a[BMLEN]; /* 64 bit bitmask for channel/band selection */ A_UINT32 chan11bg[BMLEN];/* 64 bit bitmask for channel/band selection */ diff --git a/drivers/staging/ath6kl/include/common/testcmd.h b/drivers/staging/ath6kl/include/common/testcmd.h index d6616f0fab7d..4138c1d13d15 100644 --- a/drivers/staging/ath6kl/include/common/testcmd.h +++ b/drivers/staging/ath6kl/include/common/testcmd.h @@ -91,8 +91,8 @@ typedef PREPACK struct { A_UINT32 enANI; A_UINT32 scramblerOff; A_UINT32 aifsn; - A_UINT16 pktSz; - A_UINT16 txPattern; + u16 pktSz; + u16 txPattern; A_UINT32 shortGuard; A_UINT32 numPackets; A_UINT32 wlanMode; @@ -138,8 +138,8 @@ typedef PREPACK struct { A_INT32 rssiInDBm; A_UINT32 crcErrPkt; A_UINT32 secErrPkt; - A_UINT16 rateCnt[TCMD_MAX_RATES]; - A_UINT16 rateCntShortGuard[TCMD_MAX_RATES]; + u16 rateCnt[TCMD_MAX_RATES]; + u16 rateCntShortGuard[TCMD_MAX_RATES]; } POSTPACK report; struct PREPACK TCMD_CONT_RX_MAC { A_UCHAR addr[ATH_MAC_LEN]; diff --git a/drivers/staging/ath6kl/include/common/wlan_dset.h b/drivers/staging/ath6kl/include/common/wlan_dset.h index e092020a2632..e775b25de3a8 100644 --- a/drivers/staging/ath6kl/include/common/wlan_dset.h +++ b/drivers/staging/ath6kl/include/common/wlan_dset.h @@ -27,7 +27,7 @@ typedef PREPACK struct wow_config_dset { u8 valid_dset; u8 gpio_enable; - A_UINT16 gpio_pin; + u16 gpio_pin; } POSTPACK WOW_CONFIG_DSET; #endif diff --git a/drivers/staging/ath6kl/include/common/wmi.h b/drivers/staging/ath6kl/include/common/wmi.h index d39e7282ec23..d4f8d404b6ee 100644 --- a/drivers/staging/ath6kl/include/common/wmi.h +++ b/drivers/staging/ath6kl/include/common/wmi.h @@ -79,7 +79,7 @@ PREPACK struct host_app_area_s { typedef PREPACK struct { u8 dstMac[ATH_MAC_LEN]; u8 srcMac[ATH_MAC_LEN]; - A_UINT16 typeOrLen; + u16 typeOrLen; } POSTPACK ATH_MAC_HDR; typedef PREPACK struct { @@ -87,7 +87,7 @@ typedef PREPACK struct { u8 ssap; u8 cntl; u8 orgCode[3]; - A_UINT16 etherType; + u16 etherType; } POSTPACK ATH_LLC_SNAP_HDR; typedef enum { @@ -170,12 +170,12 @@ typedef PREPACK struct { * ACL data(2) */ - A_UINT16 info2; /* usage of 'info2' field(16-bit): + u16 info2; /* usage of 'info2' field(16-bit): * b11:b0 - seq_no * b12 - A-MSDU? * b15:b13 - META_DATA_VERSION 0 - 7 */ - A_UINT16 reserved; + u16 reserved; } POSTPACK WMI_DATA_HDR; /* @@ -246,12 +246,12 @@ typedef PREPACK struct { u8 rix; /* rate index mapped to rate at which this packet was received. */ u8 rssi; /* rssi of packet */ u8 channel;/* rf channel during packet reception */ - A_UINT16 flags; /* a combination of WMI_RX_FLAGS_... */ + u16 flags; /* a combination of WMI_RX_FLAGS_... */ } POSTPACK WMI_RX_META_V1; #define RX_CSUM_VALID_FLAG (0x1) typedef PREPACK struct { - A_UINT16 csum; + u16 csum; u8 csumFlags;/* bit 0 set -partial csum valid bit 1 set -test mode */ } POSTPACK WMI_RX_META_V2; @@ -264,15 +264,15 @@ typedef PREPACK struct { * Control Path */ typedef PREPACK struct { - A_UINT16 commandId; + u16 commandId; /* * info1 - 16 bits * b03:b00 - id * b15:b04 - unused */ - A_UINT16 info1; + u16 info1; - A_UINT16 reserved; /* For alignment */ + u16 reserved; /* For alignment */ } POSTPACK WMI_CMD_HDR; /* used for commands and events */ /* @@ -531,7 +531,7 @@ typedef PREPACK struct { u8 groupCryptoLen; u8 ssidLength; A_UCHAR ssid[WMI_MAX_SSID_LEN]; - A_UINT16 channel; + u16 channel; u8 bssid[ATH_MAC_LEN]; A_UINT32 ctrl_flags; } POSTPACK WMI_CONNECT_CMD; @@ -540,7 +540,7 @@ typedef PREPACK struct { * WMI_RECONNECT_CMDID */ typedef PREPACK struct { - A_UINT16 channel; /* hint */ + u16 channel; /* hint */ u8 bssid[ATH_MAC_LEN]; /* mandatory if set */ } POSTPACK WMI_RECONNECT_CMD; @@ -641,7 +641,7 @@ typedef PREPACK struct { A_UINT32 forceScanInterval; /* Time interval between scans (milliseconds)*/ u8 scanType; /* WMI_SCAN_TYPE */ u8 numChannels; /* how many channels follow */ - A_UINT16 channelList[1]; /* channels in Mhz */ + u16 channelList[1]; /* channels in Mhz */ } POSTPACK WMI_START_SCAN_CMD; /* @@ -676,15 +676,15 @@ typedef enum { typedef PREPACK struct { - A_UINT16 fg_start_period; /* seconds */ - A_UINT16 fg_end_period; /* seconds */ - A_UINT16 bg_period; /* seconds */ - A_UINT16 maxact_chdwell_time; /* msec */ - A_UINT16 pas_chdwell_time; /* msec */ + u16 fg_start_period; /* seconds */ + u16 fg_end_period; /* seconds */ + u16 bg_period; /* seconds */ + u16 maxact_chdwell_time; /* msec */ + u16 pas_chdwell_time; /* msec */ u8 shortScanRatio; /* how many shorts scan for one long */ u8 scanCtrlFlags; - A_UINT16 minact_chdwell_time; /* msec */ - A_UINT16 maxact_scan_per_ssid; /* max active scans per ssid */ + u16 minact_chdwell_time; /* msec */ + u16 maxact_scan_per_ssid; /* max active scans per ssid */ A_UINT32 max_dfsch_act_time; /* msecs */ } POSTPACK WMI_SCAN_PARAMS_CMD; @@ -705,7 +705,7 @@ typedef enum { typedef PREPACK struct { u8 bssFilter; /* see WMI_BSS_FILTER */ u8 reserved1; /* For alignment */ - A_UINT16 reserved2; /* For alignment */ + u16 reserved2; /* For alignment */ A_UINT32 ieMask; } POSTPACK WMI_BSS_FILTER_CMD; @@ -737,15 +737,15 @@ typedef PREPACK struct { #define MAX_LISTEN_BEACONS 50 typedef PREPACK struct { - A_UINT16 listenInterval; - A_UINT16 numBeacons; + u16 listenInterval; + u16 numBeacons; } POSTPACK WMI_LISTEN_INT_CMD; /* * WMI_SET_BEACON_INT_CMDID */ typedef PREPACK struct { - A_UINT16 beaconInterval; + u16 beaconInterval; } POSTPACK WMI_BEACON_INT_CMD; /* @@ -759,8 +759,8 @@ typedef PREPACK struct { #define MAX_BMISS_BEACONS 50 typedef PREPACK struct { - A_UINT16 bmissTime; - A_UINT16 numBeacons; + u16 bmissTime; + u16 numBeacons; } POSTPACK WMI_BMISS_TIME_CMD; /* @@ -819,12 +819,12 @@ typedef enum { } POWER_SAVE_FAIL_EVENT_POLICY; typedef PREPACK struct { - A_UINT16 idle_period; /* msec */ - A_UINT16 pspoll_number; - A_UINT16 dtim_policy; - A_UINT16 tx_wakeup_policy; - A_UINT16 num_tx_to_wakeup; - A_UINT16 ps_fail_event_policy; + u16 idle_period; /* msec */ + u16 pspoll_number; + u16 dtim_policy; + u16 tx_wakeup_policy; + u16 num_tx_to_wakeup; + u16 ps_fail_event_policy; } POSTPACK WMI_POWER_PARAMS_CMD; /* Adhoc power save types */ @@ -838,8 +838,8 @@ typedef enum { typedef PREPACK struct { u8 power_saving; u8 ttl; /* number of beacon periods */ - A_UINT16 atim_windows; /* msec */ - A_UINT16 timeout_value; /* msec */ + u16 atim_windows; /* msec */ + u16 timeout_value; /* msec */ } POSTPACK WMI_IBSS_PM_CAPS_CMD; /* AP power save types */ @@ -866,8 +866,8 @@ typedef enum { } APSD_TIM_POLICY; typedef PREPACK struct { - A_UINT16 psPollTimeout; /* msec */ - A_UINT16 triggerTimeout; /* msec */ + u16 psPollTimeout; /* msec */ + u16 triggerTimeout; /* msec */ A_UINT32 apsdTimPolicy; /* TIM behavior with ques APSD enabled. Default is IGNORE_TIM_ALL_QUEUES_APSD */ A_UINT32 simulatedAPSDTimPolicy; /* TIM behavior with simulated APSD enabled. Default is PROCESS_TIM_SIMULATED_APSD */ } POSTPACK WMI_POWERSAVE_TIMERS_POLICY_CMD; @@ -876,7 +876,7 @@ typedef PREPACK struct { * WMI_SET_VOICE_PKT_SIZE_CMDID */ typedef PREPACK struct { - A_UINT16 voicePktSize; + u16 voicePktSize; } POSTPACK WMI_SET_VOICE_PKT_SIZE_CMD; /* @@ -941,8 +941,8 @@ typedef PREPACK struct { A_UINT32 minPhyRate; /* in bps */ A_UINT32 sba; A_UINT32 mediumTime; - A_UINT16 nominalMSDU; /* in octects */ - A_UINT16 maxMSDU; /* in octects */ + u16 nominalMSDU; /* in octects */ + u16 maxMSDU; /* in octects */ u8 trafficClass; u8 trafficDirection; /* DIR_TYPE */ u8 rxQueueNum; @@ -982,7 +982,7 @@ typedef PREPACK struct { u8 scanParam; /* set if enable scan */ u8 phyMode; /* see WMI_PHY_MODE */ u8 numChannels; /* how many channels follow */ - A_UINT16 channelList[1]; /* channels in Mhz */ + u16 channelList[1]; /* channels in Mhz */ } POSTPACK WMI_CHANNEL_PARAMS_CMD; @@ -1063,7 +1063,7 @@ typedef PREPACK struct { }POSTPACK WMI_SET_LPREAMBLE_CMD; typedef PREPACK struct { - A_UINT16 threshold; + u16 threshold; }POSTPACK WMI_SET_RTS_CMD; /* @@ -1132,7 +1132,7 @@ typedef PREPACK struct { #define WMI_DEFAULT_AIFSN_ACPARAM 2 #define WMI_MAX_AIFSN_ACPARAM 15 typedef PREPACK struct { - A_UINT16 txop; /* in units of 32 usec */ + u16 txop; /* in units of 32 usec */ u8 eCWmin; u8 eCWmax; u8 aifsn; @@ -1208,7 +1208,7 @@ typedef PREPACK struct { } POSTPACK WMI_BSS_BIAS_INFO; typedef PREPACK struct WMI_LOWRSSI_SCAN_PARAMS { - A_UINT16 lowrssi_scan_period; + u16 lowrssi_scan_period; A_INT16 lowrssi_scan_threshold; A_INT16 lowrssi_roam_threshold; u8 roam_rssi_floor; @@ -1866,7 +1866,7 @@ typedef PREPACK struct { typedef PREPACK struct { - A_UINT16 cmd_buf_sz; /* HCI cmd buffer size */ + u16 cmd_buf_sz; /* HCI cmd buffer size */ u8 buf[1]; /* Absolute HCI cmd */ } POSTPACK WMI_HCI_CMD; @@ -1880,7 +1880,7 @@ typedef PREPACK struct { typedef PREPACK struct { u8 reserved1; u8 numChannels; /* number of channels in reply */ - A_UINT16 channelList[1]; /* channel in Mhz */ + u16 channelList[1]; /* channel in Mhz */ } POSTPACK WMI_CHANNEL_LIST_REPLY; typedef enum { @@ -2002,10 +2002,10 @@ typedef PREPACK struct { * Connect Event */ typedef PREPACK struct { - A_UINT16 channel; + u16 channel; u8 bssid[ATH_MAC_LEN]; - A_UINT16 listenInterval; - A_UINT16 beaconInterval; + u16 listenInterval; + u16 beaconInterval; A_UINT32 networkType; u8 beaconIeLen; u8 assocReqLen; @@ -2033,7 +2033,7 @@ typedef enum { } WMI_DISCONNECT_REASON; typedef PREPACK struct { - A_UINT16 protocolReasonStatus; /* reason code, see 802.11 spec. */ + u16 protocolReasonStatus; /* reason code, see 802.11 spec. */ u8 bssid[ATH_MAC_LEN]; /* set if known */ u8 disconnectReason ; /* see WMI_DISCONNECT_REASON */ u8 assocRespLen; @@ -2059,7 +2059,7 @@ enum { }; typedef PREPACK struct { - A_UINT16 channel; + u16 channel; u8 frameType; /* see WMI_BI_FTYPE */ u8 snr; A_INT16 rssi; @@ -2076,11 +2076,11 @@ typedef PREPACK struct { * - Remove rssi and compute it on the host. rssi = snr - 95 */ typedef PREPACK struct { - A_UINT16 channel; + u16 channel; u8 frameType; /* see WMI_BI_FTYPE */ u8 snr; u8 bssid[ATH_MAC_LEN]; - A_UINT16 ieMask; + u16 ieMask; } POSTPACK WMI_BSS_INFO_HDR2; /* @@ -2093,7 +2093,7 @@ typedef enum { } WMI_ERROR_CODE; typedef PREPACK struct { - A_UINT16 commandId; + u16 commandId; u8 errorCode; } POSTPACK WMI_CMD_ERROR_EVENT; @@ -2190,7 +2190,7 @@ typedef enum { } WMI_OPT_FTYPE; typedef PREPACK struct { - A_UINT16 optIEDataLen; + u16 optIEDataLen; u8 frmType; u8 dstAddr[ATH_MAC_LEN]; u8 bssid[ATH_MAC_LEN]; @@ -2205,7 +2205,7 @@ typedef PREPACK struct { * The 802.11 header is not included. */ typedef PREPACK struct { - A_UINT16 channel; + u16 channel; u8 frameType; /* see WMI_OPT_FTYPE */ A_INT8 snr; u8 srcAddr[ATH_MAC_LEN]; @@ -2266,19 +2266,19 @@ typedef PREPACK struct { typedef PREPACK struct { A_UINT32 power_save_failure_cnt; - A_UINT16 stop_tx_failure_cnt; - A_UINT16 atim_tx_failure_cnt; - A_UINT16 atim_rx_failure_cnt; - A_UINT16 bcn_rx_failure_cnt; + u16 stop_tx_failure_cnt; + u16 atim_tx_failure_cnt; + u16 atim_rx_failure_cnt; + u16 bcn_rx_failure_cnt; }POSTPACK pm_stats_t; typedef PREPACK struct { A_UINT32 cs_bmiss_cnt; A_UINT32 cs_lowRssi_cnt; - A_UINT16 cs_connect_cnt; - A_UINT16 cs_disconnect_cnt; + u16 cs_connect_cnt; + u16 cs_disconnect_cnt; A_INT16 cs_aveBeacon_rssi; - A_UINT16 cs_roam_count; + u16 cs_roam_count; A_INT16 cs_rssi; u8 cs_snr; u8 cs_aveBeacon_snr; @@ -2299,7 +2299,7 @@ typedef PREPACK struct { typedef PREPACK struct { A_UINT32 wow_num_pkts_dropped; - A_UINT16 wow_num_events_discarded; + u16 wow_num_events_discarded; u8 wow_num_host_pkt_wakeups; u8 wow_num_host_event_wakeups; } POSTPACK wlan_wow_stats_t; @@ -2409,8 +2409,8 @@ typedef PREPACK struct { typedef PREPACK struct { - A_UINT16 roamMode; - A_UINT16 numEntries; + u16 roamMode; + u16 numEntries; WMI_BSS_ROAM_INFO bssRoamInfo[1]; } POSTPACK WMI_TARGET_ROAM_TBL; @@ -2418,7 +2418,7 @@ typedef PREPACK struct { * WMI_HCI_EVENT_EVENTID */ typedef PREPACK struct { - A_UINT16 evt_buf_sz; /* HCI event buffer size */ + u16 evt_buf_sz; /* HCI event buffer size */ u8 buf[1]; /* HCI event */ } POSTPACK WMI_HCI_EVENT; @@ -2451,7 +2451,7 @@ typedef enum { typedef PREPACK struct { u8 bssid[ATH_MAC_LEN]; - A_UINT16 channel; + u16 channel; } POSTPACK WMI_AP_INFO_V1; typedef PREPACK union { @@ -2728,7 +2728,7 @@ typedef enum { typedef PREPACK struct { u32 enable_wow; WMI_WOW_FILTER filter; - A_UINT16 hostReqDelay; + u16 hostReqDelay; } POSTPACK WMI_SET_WOW_MODE_CMD; typedef PREPACK struct { @@ -2754,8 +2754,8 @@ typedef PREPACK struct { } POSTPACK WMI_ADD_WOW_PATTERN_CMD; typedef PREPACK struct { - A_UINT16 filter_list_id; - A_UINT16 filter_id; + u16 filter_list_id; + u16 filter_id; } POSTPACK WMI_DEL_WOW_PATTERN_CMD; typedef PREPACK struct { @@ -2797,7 +2797,7 @@ typedef PREPACK struct { } POSTPACK WMI_PMKID_LIST_REPLY; typedef PREPACK struct { - A_UINT16 oldChannel; + u16 oldChannel; A_UINT32 newChannel; } POSTPACK WMI_CHANNEL_CHANGE_EVENT; @@ -2810,7 +2810,7 @@ typedef PREPACK struct { typedef PREPACK struct { u8 tid; u8 win_sz; - A_UINT16 st_seq_no; + u16 st_seq_no; u8 status; /* f/w response for ADDBA Req; OK(0) or failure(!=0) */ } POSTPACK WMI_ADDBA_REQ_EVENT; @@ -2818,7 +2818,7 @@ typedef PREPACK struct { typedef PREPACK struct { u8 tid; u8 status; /* OK(0), failure (!=0) */ - A_UINT16 amsdu_sz; /* Three values: Not supported(0), 3839, 8k */ + u16 amsdu_sz; /* Three values: Not supported(0), 3839, 8k */ } POSTPACK WMI_ADDBA_RESP_EVENT; /* WMI_DELBA_EVENTID @@ -2828,7 +2828,7 @@ typedef PREPACK struct { typedef PREPACK struct { u8 tid; u8 is_peer_initiator; - A_UINT16 reason_code; + u16 reason_code; } POSTPACK WMI_DELBA_EVENT; @@ -2847,8 +2847,8 @@ typedef PREPACK struct { * on each tid, in each direction */ typedef PREPACK struct { - A_UINT16 tx_allow_aggr; /* 16-bit mask to allow uplink ADDBA negotiation - bit position indicates tid*/ - A_UINT16 rx_allow_aggr; /* 16-bit mask to allow donwlink ADDBA negotiation - bit position indicates tid*/ + u16 tx_allow_aggr; /* 16-bit mask to allow uplink ADDBA negotiation - bit position indicates tid*/ + u16 rx_allow_aggr; /* 16-bit mask to allow donwlink ADDBA negotiation - bit position indicates tid*/ } POSTPACK WMI_ALLOW_AGGR_CMD; /* WMI_ADDBA_REQ_CMDID @@ -2973,7 +2973,7 @@ typedef PREPACK struct { } POSTPACK WMI_AP_ACL_MAC_CMD; typedef PREPACK struct { - A_UINT16 index; + u16 index; u8 acl_mac[AP_ACL_SIZE][ATH_MAC_LEN]; u8 wildcard[AP_ACL_SIZE]; u8 policy; @@ -2991,7 +2991,7 @@ typedef PREPACK struct { */ typedef PREPACK struct { u8 mac[ATH_MAC_LEN]; - A_UINT16 reason; /* 802.11 reason code */ + u16 reason; /* 802.11 reason code */ u8 cmd; /* operation to perform */ #define WMI_AP_MLME_ASSOC 1 /* associate station */ #define WMI_AP_DISASSOC 2 /* disassociate station */ @@ -3011,7 +3011,7 @@ typedef PREPACK struct { typedef PREPACK struct { u32 flag; - A_UINT16 aid; + u16 aid; } POSTPACK WMI_AP_SET_PVB_CMD; #define WMI_DISABLE_REGULATORY_CODE "FF" @@ -3074,7 +3074,7 @@ typedef PREPACK struct { /* AP mode events */ /* WMI_PS_POLL_EVENT */ typedef PREPACK struct { - A_UINT16 aid; + u16 aid; } POSTPACK WMI_PSPOLL_EVENT; typedef PREPACK struct { diff --git a/drivers/staging/ath6kl/include/common/wmi_thin.h b/drivers/staging/ath6kl/include/common/wmi_thin.h index 5444a0b9197b..dee5e8aae425 100644 --- a/drivers/staging/ath6kl/include/common/wmi_thin.h +++ b/drivers/staging/ath6kl/include/common/wmi_thin.h @@ -103,7 +103,7 @@ typedef enum{ typedef PREPACK struct { u8 version; /* the versioned type of messages to use or 0 to disable */ u8 countThreshold; /* msg count threshold triggering a tx complete message */ - A_UINT16 timeThreshold; /* timeout interval in MSEC triggering a tx complete message */ + u16 timeThreshold; /* timeout interval in MSEC triggering a tx complete message */ } POSTPACK WMI_THIN_CONFIG_TXCOMPLETE; /* WMI_THIN_CONFIG_DECRYPT_ERR -- Used to configure behavior for received frames @@ -139,7 +139,7 @@ typedef PREPACK struct { #define WMI_THIN_CFG_MAC_RULES 0x00000004 #define WMI_THIN_CFG_FILTER_RULES 0x00000008 A_UINT32 cfgField; /* combination of WMI_THIN_CFG_... describes contents of config command */ - A_UINT16 length; /* length in bytes of appended sub-commands */ + u16 length; /* length in bytes of appended sub-commands */ u8 reserved[2]; /* align padding */ } POSTPACK WMI_THIN_CONFIG_CMD; @@ -192,13 +192,13 @@ typedef PREPACK struct { } POSTPACK WMI_THIN_MIB_SLOT_TIME; typedef PREPACK struct { - A_UINT16 length; //units == bytes + u16 length; //units == bytes } POSTPACK WMI_THIN_MIB_RTS_THRESHOLD; typedef PREPACK struct { u8 type; // type of frame u8 rate; // tx rate to be used (one of WMI_BIT_RATE) - A_UINT16 length; // num bytes following this structure as the template data + u16 length; // num bytes following this structure as the template data } POSTPACK WMI_THIN_MIB_TEMPLATE_FRAME; typedef PREPACK struct { @@ -221,11 +221,11 @@ typedef PREPACK struct { u8 treatment; u8 oui[3]; u8 type; - A_UINT16 version; + u16 version; } POSTPACK WMI_THIN_MIB_BEACON_FILTER_TABLE_OUI; typedef PREPACK struct { - A_UINT16 numElements; + u16 numElements; u8 entrySize; // sizeof(WMI_THIN_MIB_BEACON_FILTER_TABLE) on host cpu may be 2 may be 4 u8 reserved; } POSTPACK WMI_THIN_MIB_BEACON_FILTER_TABLE_HEADER; @@ -290,7 +290,7 @@ typedef PREPACK struct { } POSTPACK WMI_THIN_MIB_PREAMBLE; typedef PREPACK struct { - A_UINT16 length; /* the length in bytes of the appended MIB data */ + u16 length; /* the length in bytes of the appended MIB data */ u8 mibID; /* the ID of the MIB element being set */ u8 reserved; /* align padding */ } POSTPACK WMI_THIN_SET_MIB_CMD; @@ -303,8 +303,8 @@ typedef PREPACK struct { typedef PREPACK struct { A_UINT32 basicRateMask; /* bit mask of basic rates */ A_UINT32 beaconIntval; /* TUs */ - A_UINT16 atimWindow; /* TUs */ - A_UINT16 channel; /* frequency in Mhz */ + u16 atimWindow; /* TUs */ + u16 channel; /* frequency in Mhz */ u8 networkType; /* INFRA_NETWORK | ADHOC_NETWORK */ u8 ssidLength; /* 0 - 32 */ u8 probe; /* != 0 : issue probe req at start */ @@ -314,8 +314,8 @@ typedef PREPACK struct { } POSTPACK WMI_THIN_JOIN_CMD; typedef PREPACK struct { - A_UINT16 dtim; /* dtim interval in num beacons */ - A_UINT16 aid; /* 80211 AID from Assoc resp */ + u16 dtim; /* dtim interval in num beacons */ + u16 aid; /* 80211 AID from Assoc resp */ } POSTPACK WMI_THIN_POST_ASSOC_CMD; typedef enum { diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h index 9059f249856f..27d8fa281c9c 100644 --- a/drivers/staging/ath6kl/include/htc_api.h +++ b/drivers/staging/ath6kl/include/htc_api.h @@ -41,7 +41,7 @@ extern "C" { typedef void *HTC_HANDLE; -typedef A_UINT16 HTC_SERVICE_ID; +typedef u16 HTC_SERVICE_ID; typedef struct _HTC_INIT_INFO { void *pContext; /* context for target failure notification */ @@ -141,7 +141,7 @@ typedef struct _HTC_EP_CALLBACKS { /* service connection information */ typedef struct _HTC_SERVICE_CONNECT_REQ { HTC_SERVICE_ID ServiceID; /* service ID to connect to */ - A_UINT16 ConnectionFlags; /* connection flags, see htc protocol definition */ + u16 ConnectionFlags; /* connection flags, see htc protocol definition */ u8 *pMetaData; /* ptr to optional service-specific meta-data */ u8 MetaDataLength; /* optional meta data length */ HTC_EP_CALLBACKS EpCallbacks; /* endpoint callbacks */ diff --git a/drivers/staging/ath6kl/include/htc_packet.h b/drivers/staging/ath6kl/include/htc_packet.h index 55914efd4be8..bbf33d1564de 100644 --- a/drivers/staging/ath6kl/include/htc_packet.h +++ b/drivers/staging/ath6kl/include/htc_packet.h @@ -46,7 +46,7 @@ struct _HTC_PACKET; typedef void (* HTC_PACKET_COMPLETION)(void *,struct _HTC_PACKET *); -typedef A_UINT16 HTC_TX_TAG; +typedef u16 HTC_TX_TAG; typedef struct _HTC_TX_PACKET_INFO { HTC_TX_TAG Tag; /* tag used to selective flush packets */ diff --git a/drivers/staging/ath6kl/include/wlan_api.h b/drivers/staging/ath6kl/include/wlan_api.h index bbc9b1f1982f..8fe804d6a215 100644 --- a/drivers/staging/ath6kl/include/wlan_api.h +++ b/drivers/staging/ath6kl/include/wlan_api.h @@ -35,7 +35,7 @@ struct ieee80211_node_table; struct ieee80211_frame; struct ieee80211_common_ie { - A_UINT16 ie_chan; + u16 ie_chan; u8 *ie_tstamp; u8 *ie_ssid; u8 *ie_rates; @@ -45,8 +45,8 @@ struct ieee80211_common_ie { u8 *ie_rsn; u8 *ie_wmm; u8 *ie_ath; - A_UINT16 ie_capInfo; - A_UINT16 ie_beaconInt; + u16 ie_capInfo; + u16 ie_beaconInt; u8 *ie_tim; u8 *ie_chswitch; u8 ie_erp; @@ -68,7 +68,7 @@ typedef struct bss { struct bss *ni_hash_prev; struct ieee80211_common_ie ni_cie; u8 *ni_buf; - A_UINT16 ni_framelen; + u16 ni_framelen; struct ieee80211_node_table *ni_table; A_UINT32 ni_refcnt; int ni_scangen; @@ -99,8 +99,8 @@ void wlan_node_table_cleanup(struct ieee80211_node_table *nt); int wlan_parse_beacon(u8 *buf, int framelen, struct ieee80211_common_ie *cie); -A_UINT16 wlan_ieee2freq(int chan); -A_UINT32 wlan_freq2ieee(A_UINT16 freq); +u16 wlan_ieee2freq(int chan); +A_UINT32 wlan_freq2ieee(u16 freq); void wlan_set_nodeage(struct ieee80211_node_table *nt, A_UINT32 nodeAge); diff --git a/drivers/staging/ath6kl/include/wmi_api.h b/drivers/staging/ath6kl/include/wmi_api.h index 3f622100e9b0..a0310b66106c 100644 --- a/drivers/staging/ath6kl/include/wmi_api.h +++ b/drivers/staging/ath6kl/include/wmi_api.h @@ -69,7 +69,7 @@ void wmi_qos_state_init(struct wmi_t *wmip); void wmi_shutdown(struct wmi_t *wmip); HTC_ENDPOINT_ID wmi_get_control_ep(struct wmi_t * wmip); void wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid); -A_UINT16 wmi_get_mapped_qos_queue(struct wmi_t *, u8 ); +u16 wmi_get_mapped_qos_queue(struct wmi_t *, u8 ); int wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf); int wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, u8 msgType, bool bMoreData, WMI_DATA_HDR_DATA_TYPE data_type,u8 metaVersion, void *pTxMetaS); int wmi_dot3_2_dix(void *osbuf); @@ -113,46 +113,46 @@ int wmi_connect_cmd(struct wmi_t *wmip, int ssidLength, A_UCHAR *ssid, u8 *bssid, - A_UINT16 channel, + u16 channel, A_UINT32 ctrl_flags); int wmi_reconnect_cmd(struct wmi_t *wmip, u8 *bssid, - A_UINT16 channel); + u16 channel); int wmi_disconnect_cmd(struct wmi_t *wmip); int wmi_getrev_cmd(struct wmi_t *wmip); int wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, u32 forceFgScan, u32 isLegacy, A_UINT32 homeDwellTime, A_UINT32 forceScanInterval, - A_INT8 numChan, A_UINT16 *channelList); -int wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec, - A_UINT16 fg_end_sec, A_UINT16 bg_sec, - A_UINT16 minact_chdw_msec, - A_UINT16 maxact_chdw_msec, A_UINT16 pas_chdw_msec, + A_INT8 numChan, u16 *channelList); +int wmi_scanparams_cmd(struct wmi_t *wmip, u16 fg_start_sec, + u16 fg_end_sec, u16 bg_sec, + u16 minact_chdw_msec, + u16 maxact_chdw_msec, u16 pas_chdw_msec, u8 shScanRatio, u8 scanCtrlFlags, A_UINT32 max_dfsch_act_time, - A_UINT16 maxact_scan_per_ssid); + u16 maxact_scan_per_ssid); int wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, A_UINT32 ieMask); int wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag, u8 ssidLength, A_UCHAR *ssid); -int wmi_listeninterval_cmd(struct wmi_t *wmip, A_UINT16 listenInterval, A_UINT16 listenBeacons); -int wmi_bmisstime_cmd(struct wmi_t *wmip, A_UINT16 bmisstime, A_UINT16 bmissbeacons); +int wmi_listeninterval_cmd(struct wmi_t *wmip, u16 listenInterval, u16 listenBeacons); +int wmi_bmisstime_cmd(struct wmi_t *wmip, u16 bmisstime, u16 bmissbeacons); int wmi_associnfo_cmd(struct wmi_t *wmip, u8 ieType, u8 ieLen, u8 *ieInfo); int wmi_powermode_cmd(struct wmi_t *wmip, u8 powerMode); int wmi_ibsspmcaps_cmd(struct wmi_t *wmip, u8 pmEnable, u8 ttl, - A_UINT16 atim_windows, A_UINT16 timeout_value); + u16 atim_windows, u16 timeout_value); int wmi_apps_cmd(struct wmi_t *wmip, u8 psType, A_UINT32 idle_time, A_UINT32 ps_period, u8 sleep_period); -int wmi_pmparams_cmd(struct wmi_t *wmip, A_UINT16 idlePeriod, - A_UINT16 psPollNum, A_UINT16 dtimPolicy, - A_UINT16 wakup_tx_policy, A_UINT16 num_tx_to_wakeup, - A_UINT16 ps_fail_event_policy); +int wmi_pmparams_cmd(struct wmi_t *wmip, u16 idlePeriod, + u16 psPollNum, u16 dtimPolicy, + u16 wakup_tx_policy, u16 num_tx_to_wakeup, + u16 ps_fail_event_policy); int wmi_disctimeout_cmd(struct wmi_t *wmip, u8 timeout); int wmi_sync_cmd(struct wmi_t *wmip, u8 syncNumber); int wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *pstream); int wmi_delete_pstream_cmd(struct wmi_t *wmip, u8 trafficClass, u8 streamID); -int wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, A_UINT16 rateMask); +int wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, u16 rateMask); int wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 dataRate, A_INT32 mgmtRate, A_INT32 ctlRate); int wmi_get_bitrate_cmd(struct wmi_t *wmip); A_INT8 wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, A_INT8 *rate_idx); @@ -160,7 +160,7 @@ int wmi_get_regDomain_cmd(struct wmi_t *wmip); int wmi_get_channelList_cmd(struct wmi_t *wmip); int wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam, WMI_PHY_MODE mode, A_INT8 numChan, - A_UINT16 *channelList); + u16 *channelList); int wmi_set_snr_threshold_params(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd); @@ -169,7 +169,7 @@ int wmi_set_rssi_threshold_params(struct wmi_t *wmip, int wmi_clr_rssi_snr(struct wmi_t *wmip); int wmi_set_lq_threshold_params(struct wmi_t *wmip, WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd); -int wmi_set_rts_cmd(struct wmi_t *wmip, A_UINT16 threshold); +int wmi_set_rts_cmd(struct wmi_t *wmip, u16 threshold); int wmi_set_lpreamble_cmd(struct wmi_t *wmip, u8 status, u8 preamblePolicy); int wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 bitmask); @@ -177,8 +177,8 @@ int wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 bitmask); int wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie, A_UINT32 source); -int wmi_config_debug_module_cmd(struct wmi_t *wmip, A_UINT16 mmask, - A_UINT16 tsr, bool rep, A_UINT16 size, +int wmi_config_debug_module_cmd(struct wmi_t *wmip, u16 mmask, + u16 tsr, bool rep, u16 size, A_UINT32 valid); int wmi_get_stats_cmd(struct wmi_t *wmip); @@ -204,7 +204,7 @@ int wmi_deleteBadAp_cmd(struct wmi_t *wmip, u8 apIndex); int wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, bool en); int wmi_setPmkid_cmd(struct wmi_t *wmip, u8 *bssid, u8 *pmkId, bool set); -int wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac, A_UINT16 txop, +int wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac, u16 txop, u8 eCWmin, u8 eCWmax, u8 aifsn); int wmi_set_retry_limits_cmd(struct wmi_t *wmip, u8 frameType, @@ -226,11 +226,11 @@ int wmi_opt_tx_frame_cmd(struct wmi_t *wmip, u8 frmType, u8 *dstMacAddr, u8 *bssid, - A_UINT16 optIEDataLen, + u16 optIEDataLen, u8 *optIEData); -int wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl); -int wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize); +int wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, u16 intvl); +int wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, u16 voicePktSize); int wmi_set_max_sp_len_cmd(struct wmi_t *wmip, u8 maxSpLen); u8 convert_userPriority_to_trafficClass(u8 userPriority); u8 wmi_get_power_mode_cmd(struct wmi_t *wmip); @@ -293,7 +293,7 @@ int wmi_set_keepalive_cmd(struct wmi_t *wmip, u8 keepaliveInterval); int wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType, u8 ieLen,u8 *ieInfo); -int wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, A_UINT16 dataLen); +int wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, u16 dataLen); A_INT32 wmi_get_rate(A_INT8 rateindex); @@ -371,10 +371,10 @@ wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *a); u8 acl_add_del_mac(WMI_AP_ACL *a, WMI_AP_ACL_MAC_CMD *acl); int -wmi_ap_set_mlme(struct wmi_t *wmip, u8 cmd, u8 *mac, A_UINT16 reason); +wmi_ap_set_mlme(struct wmi_t *wmip, u8 cmd, u8 *mac, u16 reason); int -wmi_set_pvb_cmd(struct wmi_t *wmip, A_UINT16 aid, bool flag); +wmi_set_pvb_cmd(struct wmi_t *wmip, u16 aid, bool flag); int wmi_ap_conn_inact_time(struct wmi_t *wmip, A_UINT32 period); @@ -395,7 +395,7 @@ int wmi_set_ht_op_cmd(struct wmi_t *wmip, u8 sta_chan_width); int -wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, A_UINT16 sz); +wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, u16 sz); int wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, A_UINT32 *pMaskArray); @@ -407,7 +407,7 @@ int wmi_delete_aggr_cmd(struct wmi_t *wmip, u8 tid, bool uplink); int -wmi_allow_aggr_cmd(struct wmi_t *wmip, A_UINT16 tx_tidmask, A_UINT16 rx_tidmask); +wmi_allow_aggr_cmd(struct wmi_t *wmip, u16 tx_tidmask, u16 rx_tidmask); int wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, u8 rxMetaVersion, bool rxDot11Hdr, bool defragOnHost); @@ -421,11 +421,10 @@ wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE pre int wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk); -A_UINT16 -wmi_ieee2freq (int chan); +u16 wmi_ieee2freq (int chan); A_UINT32 -wmi_freq2ieee (A_UINT16 freq); +wmi_freq2ieee (u16 freq); bss_t * wmi_find_matching_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid, diff --git a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c index 10c53f57ed83..354008904a66 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c @@ -213,14 +213,14 @@ static int AR3KConfigureHCIBaud(AR3K_CONFIG_INFO *pConfig) { int status = A_OK; u8 hciBaudChangeCommand[] = {0x0c,0xfc,0x2,0,0}; - A_UINT16 baudVal; + u16 baudVal; u8 *pEvent = NULL; u8 *pBufferToFree = NULL; do { if (pConfig->Flags & AR3K_CONFIG_FLAG_SET_AR3K_BAUD) { - baudVal = (A_UINT16)(pConfig->AR3KBaudRate / 100); + baudVal = (u16)(pConfig->AR3KBaudRate / 100); hciBaudChangeCommand[3] = (u8)baudVal; hciBaudChangeCommand[4] = (u8)(baudVal >> 8); diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c index 62d11dee34df..0cbc73ce26fb 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c @@ -94,7 +94,7 @@ typedef struct tPsTagEntry typedef struct tRamPatch { - A_UINT16 Len; + u16 Len; u8 *Data; } tRamPatch, *ptRamPatch; @@ -320,7 +320,7 @@ int AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat) char *Buffer; char *pCharLine; u8 TagCount; - A_UINT16 ByteCount; + u16 ByteCount; u8 ParseSection=RAM_PS_SECTION; A_UINT32 pos; diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h index 58bd4a90024d..13d1d095a456 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h @@ -51,7 +51,7 @@ #ifndef A_UINT32 #define A_UCHAR unsigned char #define A_UINT32 unsigned long -#define A_UINT16 unsigned short +#define u16 unsigned short #define u8 unsigned char #define bool unsigned char #endif /* A_UINT32 */ diff --git a/drivers/staging/ath6kl/miscdrv/common_drv.c b/drivers/staging/ath6kl/miscdrv/common_drv.c index 82bec20e0ff7..1d51d2a34e1d 100644 --- a/drivers/staging/ath6kl/miscdrv/common_drv.c +++ b/drivers/staging/ath6kl/miscdrv/common_drv.c @@ -796,12 +796,12 @@ ar6002_REV1_reset_force_host (HIF_DEVICE *hifDevice) #endif /* CONFIG_AR6002_REV1_FORCE_HOST */ -void DebugDumpBytes(A_UCHAR *buffer, A_UINT16 length, char *pDescription) +void DebugDumpBytes(A_UCHAR *buffer, u16 length, char *pDescription) { char stream[60]; char byteOffsetStr[10]; A_UINT32 i; - A_UINT16 offset, count, byteOffset; + u16 offset, count, byteOffset; A_PRINTF("<---------Dumping %d Bytes : %s ------>\n", length, pDescription); diff --git a/drivers/staging/ath6kl/os/linux/ar6000_android.c b/drivers/staging/ath6kl/os/linux/ar6000_android.c index 88591d7d5444..f7d1069072b9 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_android.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_android.c @@ -345,8 +345,8 @@ void android_ar6k_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, bool isE skb && ar->arConnected) { bool needWake = false; if (isEvent) { - if (A_NETBUF_LEN(skb) >= sizeof(A_UINT16)) { - A_UINT16 cmd = *(const A_UINT16 *)A_NETBUF_DATA(skb); + if (A_NETBUF_LEN(skb) >= sizeof(u16)) { + u16 cmd = *(const u16 *)A_NETBUF_DATA(skb); switch (cmd) { case WMI_CONNECT_EVENTID: case WMI_DISCONNECT_EVENTID: diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 647c6c983a29..9f7a02f50855 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -254,11 +254,11 @@ module_param(blocktx, int, 0644); #endif /* BLOCK_TX_PATH_FLAG */ typedef struct user_rssi_compensation_t { - A_UINT16 customerID; + u16 customerID; union { - A_UINT16 a_enable; - A_UINT16 bg_enable; - A_UINT16 enable; + u16 a_enable; + u16 bg_enable; + u16 enable; }; A_INT16 bg_param_a; A_INT16 bg_param_b; @@ -322,7 +322,7 @@ static void ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPackets); static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, HTC_PACKET *pPacket); #ifdef ATH_AR6K_11N_SUPPORT -static void ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, A_UINT16 num); +static void ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num); #endif static void ar6000_deliver_frames_to_nw_stack(void * dev, void *osbuf); //static void ar6000_deliver_frames_to_bt_stack(void * dev, void *osbuf); @@ -773,7 +773,7 @@ aptcTimerHandler(unsigned long arg) #ifdef ATH_AR6K_11N_SUPPORT static void -ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, A_UINT16 num) +ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num) { void * osbuf; @@ -904,26 +904,26 @@ ar6000_sysfs_bmi_deinit(AR_SOFTC_T *ar) static void calculate_crc(A_UINT32 TargetType, A_UCHAR *eeprom_data) { - A_UINT16 *ptr_crc; - A_UINT16 *ptr16_eeprom; - A_UINT16 checksum; + u16 *ptr_crc; + u16 *ptr16_eeprom; + u16 checksum; A_UINT32 i; A_UINT32 eeprom_size; if (TargetType == TARGET_TYPE_AR6001) { eeprom_size = 512; - ptr_crc = (A_UINT16 *)eeprom_data; + ptr_crc = (u16 *)eeprom_data; } else if (TargetType == TARGET_TYPE_AR6003) { eeprom_size = 1024; - ptr_crc = (A_UINT16 *)((A_UCHAR *)eeprom_data + 0x04); + ptr_crc = (u16 *)((A_UCHAR *)eeprom_data + 0x04); } else { eeprom_size = 768; - ptr_crc = (A_UINT16 *)((A_UCHAR *)eeprom_data + 0x04); + ptr_crc = (u16 *)((A_UCHAR *)eeprom_data + 0x04); } @@ -932,7 +932,7 @@ void calculate_crc(A_UINT32 TargetType, A_UCHAR *eeprom_data) // Recalculate new CRC checksum = 0; - ptr16_eeprom = (A_UINT16 *)eeprom_data; + ptr16_eeprom = (u16 *)eeprom_data; for (i = 0;i < eeprom_size; i += 2) { checksum = checksum ^ (*ptr16_eeprom); @@ -2552,7 +2552,7 @@ int ar6000_init(struct net_device *dev) * of 0-3 */ connect.ConnectionFlags &= ~HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK; connect.ConnectionFlags |= - ((A_UINT16)reduce_credit_dribble - 1) & HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK; + ((u16)reduce_credit_dribble - 1) & HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK; } /* connect to best-effort service */ connect.ServiceID = WMI_DATA_BE_SVC; @@ -2797,11 +2797,11 @@ ar6000_txPwr_rx(void *devt, u8 txPwr) void -ar6000_channelList_rx(void *devt, A_INT8 numChan, A_UINT16 *chanList) +ar6000_channelList_rx(void *devt, A_INT8 numChan, u16 *chanList) { AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; - A_MEMCPY(ar->arChannelList, chanList, numChan * sizeof (A_UINT16)); + A_MEMCPY(ar->arChannelList, chanList, numChan * sizeof (u16)); ar->arNumChannels = numChan; wake_up(&arEvent); @@ -3665,7 +3665,7 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) AR6000_STAT_INC(ar, rx_length_errors); A_NETBUF_FREE(skb); } else { - A_UINT16 seq_no; + u16 seq_no; u8 meta_type; #if 0 @@ -3678,7 +3678,7 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) sta_t *conn = NULL; u8 psState=0,prevPsState; ATH_MAC_HDR *datap=NULL; - A_UINT16 offset; + u16 offset; meta_type = WMI_DATA_HDR_GET_META(dhdr); @@ -4206,7 +4206,7 @@ ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, A_UINT32 sw_ver, A_UINT32 a } void -add_new_sta(AR_SOFTC_T *ar, u8 *mac, A_UINT16 aid, u8 *wpaie, +add_new_sta(AR_SOFTC_T *ar, u8 *mac, u16 aid, u8 *wpaie, u8 ielen, u8 keymgmt, u8 ucipher, u8 auth) { u8 free_slot=aid-1; @@ -4222,8 +4222,8 @@ add_new_sta(AR_SOFTC_T *ar, u8 *mac, A_UINT16 aid, u8 *wpaie, } void -ar6000_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, u8 *bssid, - A_UINT16 listenInterval, A_UINT16 beaconInterval, +ar6000_connect_event(AR_SOFTC_T *ar, u16 channel, u8 *bssid, + u16 listenInterval, u16 beaconInterval, NETWORK_TYPE networkType, u8 beaconIeLen, u8 assocReqLen, u8 assocRespLen, u8 *assocInfo) @@ -4398,9 +4398,9 @@ skip_key: if (assocRespLen && (sizeof(buf) > (12 + (assocRespLen * 2)))) { assoc_resp_ie_pos = beaconIeLen + assocReqLen + - sizeof(A_UINT16) + /* capinfo*/ - sizeof(A_UINT16) + /* status Code */ - sizeof(A_UINT16) ; /* associd */ + sizeof(u16) + /* capinfo*/ + sizeof(u16) + /* status Code */ + sizeof(u16) ; /* associd */ A_MEMZERO(buf, sizeof(buf)); sprintf(buf, "%s", tag2); pos = buf + 12; @@ -4427,8 +4427,8 @@ skip_key: * assoc Request includes capability and listen interval. Skip these. */ assoc_req_ie_pos = beaconIeLen + - sizeof(A_UINT16) + /* capinfo*/ - sizeof(A_UINT16); /* listen interval */ + sizeof(u16) + /* capinfo*/ + sizeof(u16); /* listen interval */ A_MEMZERO(buf, sizeof(buf)); sprintf(buf, "%s", tag1); @@ -4538,7 +4538,7 @@ sta_cleanup(AR_SOFTC_T *ar, u8 i) } -u8 remove_sta(AR_SOFTC_T *ar, u8 *mac, A_UINT16 reason) +u8 remove_sta(AR_SOFTC_T *ar, u8 *mac, u16 reason) { u8 i, removed=0; @@ -4572,7 +4572,7 @@ u8 remove_sta(AR_SOFTC_T *ar, u8 *mac, A_UINT16 reason) void ar6000_disconnect_event(AR_SOFTC_T *ar, u8 reason, u8 *bssid, - u8 assocRespLen, u8 *assocInfo, A_UINT16 protocolReasonStatus) + u8 assocRespLen, u8 *assocInfo, u16 protocolReasonStatus) { u8 i; unsigned long flags; @@ -5127,8 +5127,8 @@ ar6000_cac_event(AR_SOFTC_T *ar, u8 ac, u8 cacIndication, } void -ar6000_channel_change_event(AR_SOFTC_T *ar, A_UINT16 oldChannel, - A_UINT16 newChannel) +ar6000_channel_change_event(AR_SOFTC_T *ar, u16 oldChannel, + u16 newChannel) { A_PRINTF("Channel Change notification\nOld Channel: %d, New Channel: %d\n", oldChannel, newChannel); @@ -5519,7 +5519,7 @@ ar6000_alloc_cookie(AR_SOFTC_T *ar) * the event ID and event content. */ #define EVENT_ID_LEN 2 -void ar6000_send_event_to_app(AR_SOFTC_T *ar, A_UINT16 eventId, +void ar6000_send_event_to_app(AR_SOFTC_T *ar, u16 eventId, u8 *datap, int len) { @@ -5528,7 +5528,7 @@ void ar6000_send_event_to_app(AR_SOFTC_T *ar, A_UINT16 eventId, /* note: IWEVCUSTOM only exists in wireless extensions after version 15 */ char *buf; - A_UINT16 size; + u16 size; union iwreq_data wrqu; size = len + EVENT_ID_LEN; @@ -5549,7 +5549,7 @@ void ar6000_send_event_to_app(AR_SOFTC_T *ar, A_UINT16 eventId, A_MEMCPY(buf, &eventId, EVENT_ID_LEN); A_MEMCPY(buf+EVENT_ID_LEN, datap, len); - //AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("event ID = %d,len = %d\n",*(A_UINT16*)buf, size)); + //AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("event ID = %d,len = %d\n",*(u16 *)buf, size)); A_MEMZERO(&wrqu, sizeof(wrqu)); wrqu.data.length = size; wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf); @@ -5564,7 +5564,7 @@ void ar6000_send_event_to_app(AR_SOFTC_T *ar, A_UINT16 eventId, * to the application. The buf which is sent to application * includes the event ID and event content. */ -void ar6000_send_generic_event_to_app(AR_SOFTC_T *ar, A_UINT16 eventId, +void ar6000_send_generic_event_to_app(AR_SOFTC_T *ar, u16 eventId, u8 *datap, int len) { @@ -5573,7 +5573,7 @@ void ar6000_send_generic_event_to_app(AR_SOFTC_T *ar, A_UINT16 eventId, /* IWEVGENIE exists in wireless extensions version 18 onwards */ char *buf; - A_UINT16 size; + u16 size; union iwreq_data wrqu; size = len + EVENT_ID_LEN; @@ -5648,7 +5648,7 @@ a_copy_from_user(void *to, const void *from, A_UINT32 n) int ar6000_get_driver_cfg(struct net_device *dev, - A_UINT16 cfgParam, + u16 cfgParam, void *result) { @@ -5805,12 +5805,12 @@ read_rssi_compensation_param(AR_SOFTC_T *ar) cust_data_ptr = ar6000_get_cust_data_buffer(ar->arTargetType); - rssi_compensation_param.customerID = *(A_UINT16 *)cust_data_ptr & 0xffff; - rssi_compensation_param.enable = *(A_UINT16 *)(cust_data_ptr+2) & 0xffff; - rssi_compensation_param.bg_param_a = *(A_UINT16 *)(cust_data_ptr+4) & 0xffff; - rssi_compensation_param.bg_param_b = *(A_UINT16 *)(cust_data_ptr+6) & 0xffff; - rssi_compensation_param.a_param_a = *(A_UINT16 *)(cust_data_ptr+8) & 0xffff; - rssi_compensation_param.a_param_b = *(A_UINT16 *)(cust_data_ptr+10) &0xffff; + rssi_compensation_param.customerID = *(u16 *)cust_data_ptr & 0xffff; + rssi_compensation_param.enable = *(u16 *)(cust_data_ptr+2) & 0xffff; + rssi_compensation_param.bg_param_a = *(u16 *)(cust_data_ptr+4) & 0xffff; + rssi_compensation_param.bg_param_b = *(u16 *)(cust_data_ptr+6) & 0xffff; + rssi_compensation_param.a_param_a = *(u16 *)(cust_data_ptr+8) & 0xffff; + rssi_compensation_param.a_param_b = *(u16 *)(cust_data_ptr+10) &0xffff; rssi_compensation_param.reserved = *(A_UINT32 *)(cust_data_ptr+12); #ifdef RSSICOMPENSATION_PRINT @@ -6139,7 +6139,7 @@ ar6000_connect_to_ap(struct ar6_softc *ar) /* Set the listen interval into 1000TUs or more. This value will be indicated to Ap in the conn. later set it back locally at the STA to 100/1000 TUs depending on the power mode */ if ((ar->arNetworkType == INFRA_NETWORK)) { - wmi_listeninterval_cmd(ar->arWmi, max(ar->arListenIntervalT, (A_UINT16)A_MAX_WOW_LISTEN_INTERVAL), 0); + wmi_listeninterval_cmd(ar->arWmi, max(ar->arListenIntervalT, (u16)A_MAX_WOW_LISTEN_INTERVAL), 0); } status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType, ar->arDot11AuthMode, ar->arAuthMode, @@ -6187,7 +6187,7 @@ ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie } int -is_iwioctl_allowed(u8 mode, A_UINT16 cmd) +is_iwioctl_allowed(u8 mode, u16 cmd) { if(cmd >= SIOCSIWCOMMIT && cmd <= SIOCGIWPOWER) { cmd -= SIOCSIWCOMMIT; diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c index b2a1351cdff8..7e680a540713 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_pm.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_pm.c @@ -74,8 +74,8 @@ static void ar6k_send_asleep_event_to_app(AR_SOFTC_T *ar, bool asleep) static void ar6000_wow_resume(AR_SOFTC_T *ar) { if (ar->arWowState!= WLAN_WOW_STATE_NONE) { - A_UINT16 fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period; - A_UINT16 bg_period = (ar->scParams.bg_period==0) ? 60 : ar->scParams.bg_period; + u16 fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period; + u16 bg_period = (ar->scParams.bg_period==0) ? 60 : ar->scParams.bg_period; WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {true, false}; ar->arWowState = WLAN_WOW_STATE_NONE; if (wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)!=A_OK) { @@ -251,7 +251,7 @@ wow_not_connected: int ar6000_resume_ev(void *context) { AR_SOFTC_T *ar = (AR_SOFTC_T *)context; - A_UINT16 powerState = ar->arWlanPowerState; + u16 powerState = ar->arWlanPowerState; AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: enter previous state %d wowState %d\n", __func__, powerState, ar->arWowState)); switch (powerState) { @@ -425,7 +425,7 @@ ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode; if (state == WLAN_ENABLED) { - A_UINT16 fg_start_period; + u16 fg_start_period; /* Not in deep sleep state.. exit */ if (ar->arWlanPowerState != WLAN_POWER_STATE_DEEP_SLEEP) { @@ -540,7 +540,7 @@ int ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool pmEvent) { int status = A_OK; - A_UINT16 powerState, oldPowerState; + u16 powerState, oldPowerState; AR6000_WLAN_STATE oldstate = ar->arWlanState; bool wlanOff = ar->arWlanOff; #ifdef CONFIG_PM diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index f526160b8a73..332b336c3391 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -428,14 +428,14 @@ ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, } void -ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, - u8 *bssid, A_UINT16 listenInterval, - A_UINT16 beaconInterval,NETWORK_TYPE networkType, +ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, u16 channel, + u8 *bssid, u16 listenInterval, + u16 beaconInterval,NETWORK_TYPE networkType, u8 beaconIeLen, u8 assocReqLen, u8 assocRespLen, u8 *assocInfo) { - A_UINT16 size = 0; - A_UINT16 capability = 0; + u16 size = 0; + u16 capability = 0; struct cfg80211_bss *bss = NULL; struct ieee80211_mgmt *mgmt = NULL; struct ieee80211_channel *ibss_channel = NULL; @@ -446,11 +446,11 @@ ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, unsigned char *ieeemgmtbuf = NULL; u8 source_mac[ATH_MAC_LEN]; - u8 assocReqIeOffset = sizeof(A_UINT16) + /* capinfo*/ - sizeof(A_UINT16); /* listen interval */ - u8 assocRespIeOffset = sizeof(A_UINT16) + /* capinfo*/ - sizeof(A_UINT16) + /* status Code */ - sizeof(A_UINT16); /* associd */ + u8 assocReqIeOffset = sizeof(u16) + /* capinfo*/ + sizeof(u16); /* listen interval */ + u8 assocRespIeOffset = sizeof(u16) + /* capinfo*/ + sizeof(u16) + /* status Code */ + sizeof(u16); /* associd */ u8 *assocReqIe = assocInfo + beaconIeLen + assocReqIeOffset; u8 *assocRespIe = assocInfo + beaconIeLen + assocReqLen + assocRespIeOffset; @@ -513,7 +513,7 @@ ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, A_MEMCPY(source_mac, ar->arNetDev->dev_addr, ATH_MAC_LEN); ptr_ie_buf = ie_buf; } else { - capability = *(A_UINT16 *)(&assocInfo[beaconIeLen]); + capability = *(u16 *)(&assocInfo[beaconIeLen]); A_MEMCPY(source_mac, bssid, ATH_MAC_LEN); ptr_ie_buf = assocReqIe; ie_buf_len = assocReqLen; @@ -577,7 +577,7 @@ ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, static int ar6k_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, - A_UINT16 reason_code) + u16 reason_code) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); @@ -620,7 +620,7 @@ ar6k_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, void ar6k_cfg80211_disconnect_event(AR_SOFTC_T *ar, u8 reason, u8 *bssid, u8 assocRespLen, - u8 *assocInfo, A_UINT16 protocolReasonStatus) + u8 *assocInfo, u16 protocolReasonStatus) { AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason)); @@ -663,7 +663,7 @@ void ar6k_cfg80211_scan_node(void *arg, bss_t *ni) { struct wiphy *wiphy = (struct wiphy *)arg; - A_UINT16 size; + u16 size; unsigned char *ieeemgmtbuf = NULL; struct ieee80211_mgmt *mgmt; struct ieee80211_channel *channel; diff --git a/drivers/staging/ath6kl/os/linux/eeprom.c b/drivers/staging/ath6kl/os/linux/eeprom.c index 5a9ba162b793..13cd014b4b6b 100644 --- a/drivers/staging/ath6kl/os/linux/eeprom.c +++ b/drivers/staging/ath6kl/os/linux/eeprom.c @@ -106,20 +106,20 @@ static void update_mac(unsigned char *eeprom, int size, unsigned char *macaddr) { int i; - A_UINT16* ptr = (A_UINT16*)(eeprom+4); - A_UINT16 checksum = 0; + u16 *ptr = (u16 *)(eeprom+4); + u16 checksum = 0; memcpy(eeprom+10,macaddr,6); *ptr = 0; - ptr = (A_UINT16*)eeprom; + ptr = (u16 *)eeprom; for (i=0; ilen)); if (type == HCI_COMMAND_TYPE) { - A_UINT16 opcode = HCI_GET_OP_CODE(skb->data); + u16 opcode = HCI_GET_OP_CODE(skb->data); AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(" HCI Command: OGF:0x%X OCF:0x%X \r\n", opcode >> 10, opcode & 0x3FF)); } diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 2240bcfb9d00..a439370caa01 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -436,7 +436,7 @@ struct ar_hb_chlng_resp { #define STA_IS_PS_POLLED(sta) (sta->flags & (STA_PS_POLLED_MASK << STA_PS_POLLED_SHIFT)) typedef struct { - A_UINT16 flags; + u16 flags; u8 mac[ATH_MAC_LEN]; u8 aid; u8 keymgmt; @@ -487,10 +487,10 @@ typedef struct ar6_softc { struct ar_wep_key arWepKeyList[WMI_MAX_KEY_INDEX + 1]; u8 arBssid[6]; u8 arReqBssid[6]; - A_UINT16 arChannelHint; - A_UINT16 arBssChannel; - A_UINT16 arListenIntervalB; - A_UINT16 arListenIntervalT; + u16 arChannelHint; + u16 arBssChannel; + u16 arListenIntervalB; + u16 arListenIntervalT; struct ar6000_version arVersion; A_UINT32 arTargetType; A_INT8 arRssi; @@ -500,7 +500,7 @@ typedef struct ar6_softc { struct net_device_stats arNetStats; struct iw_statistics arIwStats; A_INT8 arNumChannels; - A_UINT16 arChannelList[32]; + u16 arChannelList[32]; A_UINT32 arRegCode; bool statsUpdatePending; TARGET_STATS arTargetStats; @@ -514,8 +514,8 @@ typedef struct ar6_softc { A_UINT32 arTargetMode; A_UINT32 tcmdRxcrcErrPkt; A_UINT32 tcmdRxsecErrPkt; - A_UINT16 tcmdRateCnt[TCMD_MAX_RATES]; - A_UINT16 tcmdRateCntShortGuard[TCMD_MAX_RATES]; + u16 tcmdRateCnt[TCMD_MAX_RATES]; + u16 tcmdRateCntShortGuard[TCMD_MAX_RATES]; #endif AR6000_WLAN_STATE arWlanState; struct ar_node_mapping arNodeMap[MAX_NODE_NUM]; @@ -526,7 +526,7 @@ typedef struct ar6_softc { A_UINT32 arCookieCount; A_UINT32 arRateMask; u8 arSkipScan; - A_UINT16 arBeaconInterval; + u16 arBeaconInterval; bool arConnectPending; bool arWmmEnabled; struct ar_hb_chlng_resp arHBChallengeResp; @@ -558,7 +558,7 @@ typedef struct ar6_softc { #endif USER_RSSI_THOLD rssi_map[12]; u8 arUserBssFilter; - A_UINT16 ap_profile_flag; /* AP mode */ + u16 ap_profile_flag; /* AP mode */ WMI_AP_ACL g_acl; /* AP mode */ sta_t sta_list[AP_MAX_NUM_STA]; /* AP mode */ u8 sta_list_index; /* AP mode */ @@ -577,9 +577,9 @@ typedef struct ar6_softc { u8 ap_country_code[3]; u8 ap_wmode; u8 ap_dtim_period; - A_UINT16 ap_beacon_interval; - A_UINT16 arRTS; - A_UINT16 arACS; /* AP mode - Auto Channel Selection */ + u16 ap_beacon_interval; + u16 arRTS; + u16 arACS; /* AP mode - Auto Channel Selection */ HTC_PACKET_QUEUE amsdu_rx_buffer_queue; bool bIsDestroyProgress; /* flag to indicate ar6k destroy is in progress */ A_TIMER disconnect_timer; @@ -596,15 +596,15 @@ typedef struct ar6_softc { struct cfg80211_scan_request *scan_request; struct ar_key keys[WMI_MAX_KEY_INDEX + 1]; #endif /* ATH6K_CONFIG_CFG80211 */ - A_UINT16 arWlanPowerState; + u16 arWlanPowerState; bool arWlanOff; #ifdef CONFIG_PM - A_UINT16 arWowState; + u16 arWowState; bool arBTOff; bool arBTSharing; - A_UINT16 arSuspendConfig; - A_UINT16 arWlanOffConfig; - A_UINT16 arWow2Config; + u16 arSuspendConfig; + u16 arWlanOffConfig; + u16 arWow2Config; #endif u8 scan_triggered; WMI_SCAN_PARAMS_CMD scParams; @@ -731,7 +731,7 @@ ieee80211_find_conn(AR_SOFTC_T *ar, u8 *node_addr); sta_t * ieee80211_find_conn_for_aid(AR_SOFTC_T *ar, u8 aid); -u8 remove_sta(AR_SOFTC_T *ar, u8 *mac, A_UINT16 reason); +u8 remove_sta(AR_SOFTC_T *ar, u8 *mac, u16 reason); /* HCI support */ diff --git a/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h b/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h index b2ee6525cba0..39e0873aff24 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h @@ -21,7 +21,7 @@ //============================================================================== #ifndef _AR6K_PAL_H_ #define _AR6K_PAL_H_ -#define HCI_GET_OP_CODE(p) (((A_UINT16)((p)[1])) << 8) | ((A_UINT16)((p)[0])) +#define HCI_GET_OP_CODE(p) (((u16)((p)[1])) << 8) | ((u16)((p)[0])) /* transmit packet reserve offset */ #define TX_PACKET_RSV_OFFSET 32 diff --git a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h index 26f5372049e9..04094f91063b 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h @@ -32,18 +32,18 @@ struct ar6_softc; void ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, A_UINT32 sw_ver, A_UINT32 abi_ver); int ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid); -void ar6000_connect_event(struct ar6_softc *ar, A_UINT16 channel, - u8 *bssid, A_UINT16 listenInterval, - A_UINT16 beaconInterval, NETWORK_TYPE networkType, +void ar6000_connect_event(struct ar6_softc *ar, u16 channel, + u8 *bssid, u16 listenInterval, + u16 beaconInterval, NETWORK_TYPE networkType, u8 beaconIeLen, u8 assocReqLen, u8 assocRespLen,u8 *assocInfo); void ar6000_disconnect_event(struct ar6_softc *ar, u8 reason, u8 *bssid, u8 assocRespLen, - u8 *assocInfo, A_UINT16 protocolReasonStatus); + u8 *assocInfo, u16 protocolReasonStatus); void ar6000_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast); void ar6000_bitrate_rx(void *devt, A_INT32 rateKbps); -void ar6000_channelList_rx(void *devt, A_INT8 numChan, A_UINT16 *chanList); +void ar6000_channelList_rx(void *devt, A_INT8 numChan, u16 *chanList); void ar6000_regDomain_event(struct ar6_softc *ar, A_UINT32 regCode); void ar6000_txPwr_rx(void *devt, u8 txPwr); void ar6000_keepalive_rx(void *devt, u8 configured); @@ -58,7 +58,7 @@ void ar6000_rssiThreshold_event(struct ar6_softc *ar, void ar6000_reportError_event(struct ar6_softc *, WMI_TARGET_ERROR_VAL errorVal); void ar6000_cac_event(struct ar6_softc *ar, u8 ac, u8 cac_indication, u8 statusCode, u8 *tspecSuggestion); -void ar6000_channel_change_event(struct ar6_softc *ar, A_UINT16 oldChannel, A_UINT16 newChannel); +void ar6000_channel_change_event(struct ar6_softc *ar, u16 oldChannel, u16 newChannel); void ar6000_hbChallengeResp_event(struct ar6_softc *, A_UINT32 cookie, A_UINT32 source); void ar6000_roam_tbl_event(struct ar6_softc *ar, WMI_TARGET_ROAM_TBL *pTbl); @@ -84,8 +84,8 @@ A_INT16 rssi_compensation_reverse_calc(struct ar6_softc *ar, A_INT16 rssi, bool void ar6000_dbglog_init_done(struct ar6_softc *ar); #ifdef SEND_EVENT_TO_APP -void ar6000_send_event_to_app(struct ar6_softc *ar, A_UINT16 eventId, u8 *datap, int len); -void ar6000_send_generic_event_to_app(struct ar6_softc *ar, A_UINT16 eventId, u8 *datap, int len); +void ar6000_send_event_to_app(struct ar6_softc *ar, u16 eventId, u8 *datap, int len); +void ar6000_send_generic_event_to_app(struct ar6_softc *ar, u16 eventId, u8 *datap, int len); #endif #ifdef CONFIG_HOST_TCMD_SUPPORT @@ -104,7 +104,7 @@ void ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL range, u8 lqVal void ar6000_ratemask_rx(void *devt, A_UINT32 ratemask); int ar6000_get_driver_cfg(struct net_device *dev, - A_UINT16 cfgParam, + u16 cfgParam, void *result); void ar6000_bssInfo_event_rx(struct ar6_softc *ar, u8 *data, int len); @@ -152,7 +152,7 @@ struct ieee80211req_wpaie; int ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie); -int is_iwioctl_allowed(u8 mode, A_UINT16 cmd); +int is_iwioctl_allowed(u8 mode, u16 cmd); int is_xioctl_allowed(u8 mode, int cmd); diff --git a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h index c8aec1ae04f3..ffde2c5284f7 100644 --- a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h @@ -1009,7 +1009,7 @@ struct ar6000_version { /* used by AR6000_IOCTL_WMI_GET_QOS_QUEUE */ struct ar6000_queuereq { u8 trafficClass; - A_UINT16 activeTsids; + u16 activeTsids; }; /* used by AR6000_IOCTL_WMI_GET_TARGET_STATS */ @@ -1067,7 +1067,7 @@ typedef struct targetStats_t { A_UINT32 lq_val; A_UINT32 wow_num_pkts_dropped; - A_UINT16 wow_num_events_discarded; + u16 wow_num_events_discarded; A_INT16 noise_floor_calibation; A_INT16 cs_rssi; @@ -1132,10 +1132,10 @@ struct ar6000_gpio_intr_wait_cmd_s { /* used by the AR6000_XIOCTL_DBGLOG_CFG_MODULE */ typedef struct ar6000_dbglog_module_config_s { A_UINT32 valid; - A_UINT16 mmask; - A_UINT16 tsr; + u16 mmask; + u16 tsr; u32 rep; - A_UINT16 size; + u16 size; } DBGLOG_MODULE_CONFIG; typedef struct user_rssi_thold_t { diff --git a/drivers/staging/ath6kl/os/linux/include/cfg80211.h b/drivers/staging/ath6kl/os/linux/include/cfg80211.h index 1a304436505c..c2e4fa2ef23b 100644 --- a/drivers/staging/ath6kl/os/linux/include/cfg80211.h +++ b/drivers/staging/ath6kl/os/linux/include/cfg80211.h @@ -29,15 +29,15 @@ void ar6k_cfg80211_deinit(AR_SOFTC_T *ar); void ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, int status); -void ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, - u8 *bssid, A_UINT16 listenInterval, - A_UINT16 beaconInterval,NETWORK_TYPE networkType, +void ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, u16 channel, + u8 *bssid, u16 listenInterval, + u16 beaconInterval,NETWORK_TYPE networkType, u8 beaconIeLen, u8 assocReqLen, u8 assocRespLen, u8 *assocInfo); void ar6k_cfg80211_disconnect_event(AR_SOFTC_T *ar, u8 reason, u8 *bssid, u8 assocRespLen, - u8 *assocInfo, A_UINT16 protocolReasonStatus); + u8 *assocInfo, u16 protocolReasonStatus); void ar6k_cfg80211_tkip_micerr_event(AR_SOFTC_T *ar, u8 keyid, bool ismcast); diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index c6e44ba2bd51..9b5f387940e0 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -343,7 +343,7 @@ ar6000_ioctl_set_channelParams(struct net_device *dev, struct ifreq *rq) cmdp = A_MALLOC(130); if (copy_from_user(cmdp, rq->ifr_data, sizeof (*cmdp) + - ((cmd.numChannels - 1) * sizeof(A_UINT16)))) + ((cmd.numChannels - 1) * sizeof(u16)))) { kfree(cmdp); return -EFAULT; @@ -703,7 +703,7 @@ ar6000_ioctl_tcmd_get_rx_report(struct net_device *dev, buf[2] = ar->tcmdRxcrcErrPkt; buf[3] = ar->tcmdRxsecErrPkt; A_MEMCPY(((A_UCHAR *)buf)+(4*sizeof(A_UINT32)), ar->tcmdRateCnt, sizeof(ar->tcmdRateCnt)); - A_MEMCPY(((A_UCHAR *)buf)+(4*sizeof(A_UINT32))+(TCMD_MAX_RATES *sizeof(A_UINT16)), ar->tcmdRateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard)); + A_MEMCPY(((A_UCHAR *)buf)+(4*sizeof(A_UINT32))+(TCMD_MAX_RATES *sizeof(u16)), ar->tcmdRateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard)); if (!ret && copy_to_user(rq->ifr_data, buf, sizeof(buf))) { ret = -EFAULT; @@ -3338,7 +3338,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (copy_from_user(cmdp, userdata, sizeof (*cmdp) + ((setStartScanCmd.numChannels - 1) * - sizeof(A_UINT16)))) + sizeof(u16)))) { kfree(cmdp); ret = -EFAULT; diff --git a/drivers/staging/ath6kl/os/linux/wireless_ext.c b/drivers/staging/ath6kl/os/linux/wireless_ext.c index e09daec2c743..ae2dfb432ec4 100644 --- a/drivers/staging/ath6kl/os/linux/wireless_ext.c +++ b/drivers/staging/ath6kl/os/linux/wireless_ext.c @@ -1196,7 +1196,7 @@ ar6000_ioctl_siwgenie(struct net_device *dev, #ifdef WAPI_ENABLE u8 *ie = erq->pointer; u8 ie_type = ie[0]; - A_UINT16 ie_length = erq->length; + u16 ie_length = erq->length; u8 wapi_ie[128]; #endif @@ -1249,7 +1249,7 @@ ar6000_ioctl_siwauth(struct net_device *dev, AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); bool profChanged; - A_UINT16 param; + u16 param; A_INT32 ret; A_INT32 value; @@ -1418,7 +1418,7 @@ ar6000_ioctl_giwauth(struct net_device *dev, struct iw_param *data, char *extra) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - A_UINT16 param; + u16 param; A_INT32 ret; if (ar->arWmiReady == false) { diff --git a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h index f65e290ebdeb..42e3de0453b1 100644 --- a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h +++ b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h @@ -62,14 +62,14 @@ typedef enum { typedef struct { void *osbuf; bool is_amsdu; - A_UINT16 seq_no; + u16 seq_no; }OSBUF_HOLD_Q; #if 0 typedef struct { - A_UINT16 seqno_st; - A_UINT16 seqno_end; + u16 seqno_st; + u16 seqno_end; }WINDOW_SNAPSHOT; #endif @@ -77,8 +77,8 @@ typedef struct { bool aggr; /* is it ON or OFF */ bool progress; /* true when frames have arrived after a timer start */ bool timerMon; /* true if the timer started for the sake of this TID */ - A_UINT16 win_sz; /* negotiated window size */ - A_UINT16 seq_next; /* Next seq no, in current window */ + u16 win_sz; /* negotiated window size */ + u16 seq_next; /* Next seq no, in current window */ A_UINT32 hold_q_sz; /* Num of frames that can be held in hold q */ OSBUF_HOLD_Q *hold_q; /* Hold q for re-order */ #if 0 diff --git a/drivers/staging/ath6kl/reorder/rcv_aggr.c b/drivers/staging/ath6kl/reorder/rcv_aggr.c index 0ae9fdf14114..5eeb6e3b54e5 100644 --- a/drivers/staging/ath6kl/reorder/rcv_aggr.c +++ b/drivers/staging/ath6kl/reorder/rcv_aggr.c @@ -43,7 +43,7 @@ static void aggr_timeout(A_ATH_TIMER arg); static void -aggr_deque_frms(AGGR_INFO *p_aggr, u8 tid, A_UINT16 seq_no, u8 order); +aggr_deque_frms(AGGR_INFO *p_aggr, u8 tid, u16 seq_no, u8 order); static void aggr_dispatch_frames(AGGR_INFO *p_aggr, A_NETBUF_QUEUE_T *q); @@ -187,7 +187,7 @@ aggr_register_rx_dispatcher(void *cntxt, void * dev, RX_CALLBACK fn) void -aggr_process_bar(void *cntxt, u8 tid, A_UINT16 seq_no) +aggr_process_bar(void *cntxt, u8 tid, u16 seq_no) { AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; RXTID_STATS *stats; @@ -201,7 +201,7 @@ aggr_process_bar(void *cntxt, u8 tid, A_UINT16 seq_no) void -aggr_recv_addba_req_evt(void *cntxt, u8 tid, A_UINT16 seq_no, u8 win_sz) +aggr_recv_addba_req_evt(void *cntxt, u8 tid, u16 seq_no, u8 win_sz) { AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; RXTID *rxtid; @@ -269,11 +269,11 @@ aggr_recv_delba_req_evt(void *cntxt, u8 tid) } static void -aggr_deque_frms(AGGR_INFO *p_aggr, u8 tid, A_UINT16 seq_no, u8 order) +aggr_deque_frms(AGGR_INFO *p_aggr, u8 tid, u16 seq_no, u8 order) { RXTID *rxtid; OSBUF_HOLD_Q *node; - A_UINT16 idx, idx_end, seq_end; + u16 idx, idx_end, seq_end; RXTID_STATS *stats; A_ASSERT(p_aggr); @@ -359,7 +359,7 @@ static void aggr_slice_amsdu(AGGR_INFO *p_aggr, RXTID *rxtid, void **osbuf) { void *new_buf; - A_UINT16 frame_8023_len, payload_8023_len, mac_hdr_len, amsdu_len; + u16 frame_8023_len, payload_8023_len, mac_hdr_len, amsdu_len; u8 *framep; /* Frame format at this point: @@ -426,13 +426,13 @@ aggr_slice_amsdu(AGGR_INFO *p_aggr, RXTID *rxtid, void **osbuf) } void -aggr_process_recv_frm(void *cntxt, u8 tid, A_UINT16 seq_no, bool is_amsdu, void **osbuf) +aggr_process_recv_frm(void *cntxt, u8 tid, u16 seq_no, bool is_amsdu, void **osbuf) { AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; RXTID *rxtid; RXTID_STATS *stats; - A_UINT16 idx, st, cur, end; - A_UINT16 *log_idx; + u16 idx, st, cur, end; + u16 *log_idx; OSBUF_HOLD_Q *node; PACKET_LOG *log; @@ -472,7 +472,7 @@ aggr_process_recv_frm(void *cntxt, u8 tid, A_UINT16 seq_no, bool is_amsdu, void * be assumed that the window has moved for some valid reason. * Therefore, we dequeue all frames and start fresh. */ - A_UINT16 extended_end; + u16 extended_end; extended_end = (end + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO; diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211.h b/drivers/staging/ath6kl/wlan/include/ieee80211.h index 75cece166c59..1bcef9ce86b1 100644 --- a/drivers/staging/ath6kl/wlan/include/ieee80211.h +++ b/drivers/staging/ath6kl/wlan/include/ieee80211.h @@ -326,10 +326,10 @@ typedef PREPACK struct wmm_tspec_ie_t { u8 ouiType; u8 ouiSubType; u8 version; - A_UINT16 tsInfo_info; + u16 tsInfo_info; u8 tsInfo_reserved; - A_UINT16 nominalMSDU; - A_UINT16 maxMSDU; + u16 nominalMSDU; + u16 maxMSDU; A_UINT32 minServiceInt; A_UINT32 maxServiceInt; A_UINT32 inactivityInt; @@ -341,8 +341,8 @@ typedef PREPACK struct wmm_tspec_ie_t { A_UINT32 maxBurstSize; A_UINT32 delayBound; A_UINT32 minPhyRate; - A_UINT16 sba; - A_UINT16 mediumTime; + u16 sba; + u16 mediumTime; } POSTPACK WMM_TSPEC_IE; diff --git a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c index 55b2a9623ec3..5ed5b9ee154a 100644 --- a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c +++ b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c @@ -49,7 +49,7 @@ /* unaligned little endian access */ #define LE_READ_2(p) \ - ((A_UINT16) \ + ((u16) \ ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8))) #define LE_READ_4(p) \ @@ -125,8 +125,8 @@ wlan_parse_beacon(u8 *buf, int framelen, struct ieee80211_common_ie *cie) A_MEMZERO(cie, sizeof(*cie)); cie->ie_tstamp = frm; frm += 8; - cie->ie_beaconInt = A_LE2CPU16(*(A_UINT16 *)frm); frm += 2; - cie->ie_capInfo = A_LE2CPU16(*(A_UINT16 *)frm); frm += 2; + cie->ie_beaconInt = A_LE2CPU16(*(u16 *)frm); frm += 2; + cie->ie_capInfo = A_LE2CPU16(*(u16 *)frm); frm += 2; cie->ie_chan = 0; while (frm < efrm) { diff --git a/drivers/staging/ath6kl/wlan/src/wlan_utils.c b/drivers/staging/ath6kl/wlan/src/wlan_utils.c index 1eee7bab3e50..3a57d50e4e20 100644 --- a/drivers/staging/ath6kl/wlan/src/wlan_utils.c +++ b/drivers/staging/ath6kl/wlan/src/wlan_utils.c @@ -30,8 +30,7 @@ /* * converts ieee channel number to frequency */ -A_UINT16 -wlan_ieee2freq(int chan) +u16 wlan_ieee2freq(int chan) { if (chan == 14) { return 2484; @@ -49,7 +48,7 @@ wlan_ieee2freq(int chan) * Converts MHz frequency to IEEE channel number. */ A_UINT32 -wlan_freq2ieee(A_UINT16 freq) +wlan_freq2ieee(u16 freq) { if (freq == 2484) return 14; diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index 896f4a4c0989..a575ad809ff3 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -279,15 +279,15 @@ const u8 up_to_ac[]= { typedef PREPACK struct _iphdr { u8 ip_ver_hdrlen; /* version and hdr length */ u8 ip_tos; /* type of service */ - A_UINT16 ip_len; /* total length */ - A_UINT16 ip_id; /* identification */ + u16 ip_len; /* total length */ + u16 ip_id; /* identification */ A_INT16 ip_off; /* fragment offset field */ #define IP_DF 0x4000 /* dont fragment flag */ #define IP_MF 0x2000 /* more fragments flag */ #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ u8 ip_ttl; /* time to live */ u8 ip_p; /* protocol */ - A_UINT16 ip_sum; /* checksum */ + u16 ip_sum; /* checksum */ u8 ip_src[4]; /* source and dest address */ u8 ip_dst[4]; } POSTPACK iphdr; @@ -395,7 +395,7 @@ int wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf) { u8 *datap; - A_UINT16 typeorlen; + u16 typeorlen; ATH_MAC_HDR macHdr; ATH_LLC_SNAP_HDR *llcHdr; @@ -409,7 +409,7 @@ wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf) datap = A_NETBUF_DATA(osbuf); - typeorlen = *(A_UINT16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN); + typeorlen = *(u16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN); if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) { /* @@ -535,7 +535,7 @@ u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 layer2P { u8 *datap; u8 trafficClass = WMM_AC_BE; - A_UINT16 ipType = IP_ETHERTYPE; + u16 ipType = IP_ETHERTYPE; WMI_DATA_HDR *dtHdr; u8 streamExists = 0; u8 userPriority; @@ -625,7 +625,7 @@ int wmi_dot11_hdr_add (struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode) { u8 *datap; - A_UINT16 typeorlen; + u16 typeorlen; ATH_MAC_HDR macHdr; ATH_LLC_SNAP_HDR *llcHdr; struct ieee80211_frame *wh; @@ -641,7 +641,7 @@ wmi_dot11_hdr_add (struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode) datap = A_NETBUF_DATA(osbuf); - typeorlen = *(A_UINT16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN); + typeorlen = *(u16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN); if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) { /* @@ -830,7 +830,7 @@ int wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf) { WMIX_CMD_HDR *cmd; - A_UINT16 id; + u16 id; u8 *datap; A_UINT32 len; int status = A_OK; @@ -907,7 +907,7 @@ int wmi_control_rx(struct wmi_t *wmip, void *osbuf) { WMI_CMD_HDR *cmd; - A_UINT16 id; + u16 id; u8 *datap; A_UINT32 len, i, loggingReq; int status = A_OK; @@ -1279,9 +1279,9 @@ wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap, int len) /* initialize pointer to start of assoc rsp IEs */ pie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen + - sizeof(A_UINT16) + /* capinfo*/ - sizeof(A_UINT16) + /* status Code */ - sizeof(A_UINT16) ; /* associd */ + sizeof(u16) + /* capinfo*/ + sizeof(u16) + /* status Code */ + sizeof(u16) ; /* associd */ /* initialize pointer to end of assoc rsp IEs */ peie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen + ev->assocRespLen; @@ -1991,7 +1991,7 @@ wmi_cac_event_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_CAC_EVENT *reply; WMM_TSPEC_IE *tspec_ie; - A_UINT16 activeTsids; + u16 activeTsids; if (len < sizeof(*reply)) { return A_EINVAL; @@ -2248,7 +2248,7 @@ wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len) static int wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len) { - A_UINT16 ap_info_entry_size; + u16 ap_info_entry_size; WMI_APLIST_EVENT *ev = (WMI_APLIST_EVENT *)datap; WMI_AP_INFO_V1 *ap_info_v1; u8 i; @@ -2372,7 +2372,7 @@ wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId, } cHdr = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf); - cHdr->commandId = (A_UINT16) cmdId; + cHdr->commandId = (u16) cmdId; cHdr->info1 = 0; // added for virtual interface /* @@ -2421,7 +2421,7 @@ wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType, CRYPTO_TYPE pairwiseCrypto, u8 pairwiseCryptoLen, CRYPTO_TYPE groupCrypto, u8 groupCryptoLen, int ssidLength, A_UCHAR *ssid, - u8 *bssid, A_UINT16 channel, A_UINT32 ctrl_flags) + u8 *bssid, u16 channel, A_UINT32 ctrl_flags) { void *osbuf; WMI_CONNECT_CMD *cc; @@ -2471,7 +2471,7 @@ wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType, } int -wmi_reconnect_cmd(struct wmi_t *wmip, u8 *bssid, A_UINT16 channel) +wmi_reconnect_cmd(struct wmi_t *wmip, u8 *bssid, u16 channel) { void *osbuf; WMI_RECONNECT_CMD *cc; @@ -2513,7 +2513,7 @@ int wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, u32 forceFgScan, u32 isLegacy, A_UINT32 homeDwellTime, A_UINT32 forceScanInterval, - A_INT8 numChan, A_UINT16 *channelList) + A_INT8 numChan, u16 *channelList) { void *osbuf; WMI_START_SCAN_CMD *sc; @@ -2529,7 +2529,7 @@ wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, if (numChan > WMI_MAX_CHANNELS) { return A_EINVAL; } - size += sizeof(A_UINT16) * (numChan - 1); + size += sizeof(u16) * (numChan - 1); } osbuf = A_NETBUF_ALLOC(size); @@ -2547,19 +2547,19 @@ wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, sc->forceScanInterval = forceScanInterval; sc->numChannels = numChan; if (numChan) { - A_MEMCPY(sc->channelList, channelList, numChan * sizeof(A_UINT16)); + A_MEMCPY(sc->channelList, channelList, numChan * sizeof(u16)); } return (wmi_cmd_send(wmip, osbuf, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG)); } int -wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec, - A_UINT16 fg_end_sec, A_UINT16 bg_sec, - A_UINT16 minact_chdw_msec, A_UINT16 maxact_chdw_msec, - A_UINT16 pas_chdw_msec, +wmi_scanparams_cmd(struct wmi_t *wmip, u16 fg_start_sec, + u16 fg_end_sec, u16 bg_sec, + u16 minact_chdw_msec, u16 maxact_chdw_msec, + u16 pas_chdw_msec, u8 shScanRatio, u8 scanCtrlFlags, - A_UINT32 max_dfsch_act_time, A_UINT16 maxact_scan_per_ssid) + A_UINT32 max_dfsch_act_time, u16 maxact_scan_per_ssid) { void *osbuf; WMI_SCAN_PARAMS_CMD *sc; @@ -2657,7 +2657,7 @@ wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag, } int -wmi_listeninterval_cmd(struct wmi_t *wmip, A_UINT16 listenInterval, A_UINT16 listenBeacons) +wmi_listeninterval_cmd(struct wmi_t *wmip, u16 listenInterval, u16 listenBeacons) { void *osbuf; WMI_LISTEN_INT_CMD *cmd; @@ -2679,7 +2679,7 @@ wmi_listeninterval_cmd(struct wmi_t *wmip, A_UINT16 listenInterval, A_UINT16 lis } int -wmi_bmisstime_cmd(struct wmi_t *wmip, A_UINT16 bmissTime, A_UINT16 bmissBeacons) +wmi_bmisstime_cmd(struct wmi_t *wmip, u16 bmissTime, u16 bmissBeacons) { void *osbuf; WMI_BMISS_TIME_CMD *cmd; @@ -2706,7 +2706,7 @@ wmi_associnfo_cmd(struct wmi_t *wmip, u8 ieType, { void *osbuf; WMI_SET_ASSOC_INFO_CMD *cmd; - A_UINT16 cmdLen; + u16 cmdLen; cmdLen = sizeof(*cmd) + ieLen - 1; osbuf = A_NETBUF_ALLOC(cmdLen); @@ -2750,7 +2750,7 @@ wmi_powermode_cmd(struct wmi_t *wmip, u8 powerMode) int wmi_ibsspmcaps_cmd(struct wmi_t *wmip, u8 pmEnable, u8 ttl, - A_UINT16 atim_windows, A_UINT16 timeout_value) + u16 atim_windows, u16 timeout_value) { void *osbuf; WMI_IBSS_PM_CAPS_CMD *cmd; @@ -2799,10 +2799,10 @@ wmi_apps_cmd(struct wmi_t *wmip, u8 psType, A_UINT32 idle_time, } int -wmi_pmparams_cmd(struct wmi_t *wmip, A_UINT16 idlePeriod, - A_UINT16 psPollNum, A_UINT16 dtimPolicy, - A_UINT16 tx_wakeup_policy, A_UINT16 num_tx_to_wakeup, - A_UINT16 ps_fail_event_policy) +wmi_pmparams_cmd(struct wmi_t *wmip, u16 idlePeriod, + u16 psPollNum, u16 dtimPolicy, + u16 tx_wakeup_policy, u16 num_tx_to_wakeup, + u16 ps_fail_event_policy) { void *osbuf; WMI_POWER_PARAMS_CMD *pm; @@ -3029,7 +3029,7 @@ wmi_set_pmkid_list_cmd(struct wmi_t *wmip, { void *osbuf; WMI_SET_PMKID_LIST_CMD *cmd; - A_UINT16 cmdLen; + u16 cmdLen; u8 i; cmdLen = sizeof(pmkInfo->numPMKID) + @@ -3297,7 +3297,7 @@ wmi_delete_pstream_cmd(struct wmi_t *wmip, u8 trafficClass, u8 tsid) void *osbuf; WMI_DELETE_PSTREAM_CMD *cmd; int status; - A_UINT16 activeTsids=0; + u16 activeTsids=0; /* validate the parameters */ if (trafficClass > 3) { @@ -3356,7 +3356,7 @@ wmi_delete_pstream_cmd(struct wmi_t *wmip, u8 trafficClass, u8 tsid) } int -wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, A_UINT16 rateMask) +wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, u16 rateMask) { void *osbuf; WMI_FRAME_RATES_CMD *cmd; @@ -3597,7 +3597,7 @@ wmi_get_channelList_cmd(struct wmi_t *wmip) int wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam, WMI_PHY_MODE mode, A_INT8 numChan, - A_UINT16 *channelList) + u16 *channelList) { void *osbuf; WMI_CHANNEL_PARAMS_CMD *cmd; @@ -3609,7 +3609,7 @@ wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam, if (numChan > WMI_MAX_CHANNELS) { return A_EINVAL; } - size += sizeof(A_UINT16) * (numChan - 1); + size += sizeof(u16) * (numChan - 1); } osbuf = A_NETBUF_ALLOC(size); @@ -3626,7 +3626,7 @@ wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam, cmd->scanParam = scanParam; cmd->phyMode = mode; cmd->numChannels = numChan; - A_MEMCPY(cmd->channelList, channelList, numChan * sizeof(A_UINT16)); + A_MEMCPY(cmd->channelList, channelList, numChan * sizeof(u16)); return (wmi_cmd_send(wmip, osbuf, WMI_SET_CHANNEL_PARAMS_CMDID, NO_SYNC_WMIFLAG)); @@ -3738,7 +3738,7 @@ wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, void *osbuf; A_INT8 size; WMI_SET_HOST_SLEEP_MODE_CMD *cmd; - A_UINT16 activeTsids=0; + u16 activeTsids=0; u8 streamExists=0; u8 i; @@ -4080,8 +4080,8 @@ wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie, A_UINT32 source) } int -wmi_config_debug_module_cmd(struct wmi_t *wmip, A_UINT16 mmask, - A_UINT16 tsr, bool rep, A_UINT16 size, +wmi_config_debug_module_cmd(struct wmi_t *wmip, u16 mmask, + u16 tsr, bool rep, u16 size, A_UINT32 valid) { void *osbuf; @@ -4190,10 +4190,9 @@ wmi_get_txPwr_cmd(struct wmi_t *wmip) return wmi_simple_cmd(wmip, WMI_GET_TX_PWR_CMDID); } -A_UINT16 -wmi_get_mapped_qos_queue(struct wmi_t *wmip, u8 trafficClass) +u16 wmi_get_mapped_qos_queue(struct wmi_t *wmip, u8 trafficClass) { - A_UINT16 activeTsids=0; + u16 activeTsids=0; LOCK_WMI(wmip); activeTsids = wmip->wmi_streamExistsForAC[trafficClass]; @@ -4411,7 +4410,7 @@ wmi_gpio_intr_ack(struct wmi_t *wmip, #endif /* CONFIG_HOST_GPIO_SUPPORT */ int -wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac, A_UINT16 txop, u8 eCWmin, +wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac, u16 txop, u8 eCWmin, u8 eCWmax, u8 aifsn) { void *osbuf; @@ -4514,7 +4513,7 @@ wmi_opt_tx_frame_cmd(struct wmi_t *wmip, u8 frmType, u8 *dstMacAddr, u8 *bssid, - A_UINT16 optIEDataLen, + u16 optIEDataLen, u8 *optIEData) { void *osbuf; @@ -4541,7 +4540,7 @@ wmi_opt_tx_frame_cmd(struct wmi_t *wmip, } int -wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl) +wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, u16 intvl) { void *osbuf; WMI_BEACON_INT_CMD *cmd; @@ -4563,7 +4562,7 @@ wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl) int -wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize) +wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, u16 voicePktSize) { void *osbuf; WMI_SET_VOICE_PKT_SIZE_CMD *cmd; @@ -4757,7 +4756,7 @@ wmi_set_lpreamble_cmd(struct wmi_t *wmip, u8 status, u8 preamblePolicy) } int -wmi_set_rts_cmd(struct wmi_t *wmip, A_UINT16 threshold) +wmi_set_rts_cmd(struct wmi_t *wmip, u16 threshold) { void *osbuf; WMI_SET_RTS_CMD *cmd; @@ -5311,7 +5310,7 @@ wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType, u8 ieLen, { void *osbuf; WMI_SET_APPIE_CMD *cmd; - A_UINT16 cmdLen; + u16 cmdLen; cmdLen = sizeof(*cmd) + ieLen - 1; osbuf = A_NETBUF_ALLOC(cmdLen); @@ -5332,7 +5331,7 @@ wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType, u8 ieLen, } int -wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, A_UINT16 dataLen) +wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, u16 dataLen) { void *osbuf; u8 *data; @@ -6187,7 +6186,7 @@ wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *acl) * firware will allow all STAs till the count reaches AP_MAX_NUM_STA. */ int -wmi_ap_set_mlme(struct wmi_t *wmip, u8 cmd, u8 *mac, A_UINT16 reason) +wmi_ap_set_mlme(struct wmi_t *wmip, u8 cmd, u8 *mac, u16 reason) { void *osbuf; WMI_AP_SET_MLME_CMD *mlme; @@ -6246,7 +6245,7 @@ wmi_wapi_rekey_event_rx(struct wmi_t *wmip, u8 *datap,int len) #endif int -wmi_set_pvb_cmd(struct wmi_t *wmip, A_UINT16 aid, bool flag) +wmi_set_pvb_cmd(struct wmi_t *wmip, u16 aid, bool flag) { WMI_AP_SET_PVB_CMD *cmd; void *osbuf = NULL; @@ -6445,7 +6444,7 @@ wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, A_UINT32 *pMaskArray) int -wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, A_UINT16 sz) +wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, u16 sz) { void *osbuf; WMI_HCI_CMD *cmd; @@ -6465,7 +6464,7 @@ wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, A_UINT16 sz) #ifdef ATH_AR6K_11N_SUPPORT int -wmi_allow_aggr_cmd(struct wmi_t *wmip, A_UINT16 tx_tidmask, A_UINT16 rx_tidmask) +wmi_allow_aggr_cmd(struct wmi_t *wmip, u16 tx_tidmask, u16 rx_tidmask) { void *osbuf; WMI_ALLOW_AGGR_CMD *cmd; @@ -6646,19 +6645,18 @@ wmi_find_matching_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid, return node; } -A_UINT16 -wmi_ieee2freq (int chan) +u16 wmi_ieee2freq (int chan) { - A_UINT16 freq = 0; + u16 freq = 0; freq = wlan_ieee2freq (chan); return freq; } A_UINT32 -wmi_freq2ieee (A_UINT16 freq) +wmi_freq2ieee (u16 freq) { - A_UINT16 chan = 0; + u16 chan = 0; chan = wlan_freq2ieee (freq); return chan; } diff --git a/drivers/staging/ath6kl/wmi/wmi_host.h b/drivers/staging/ath6kl/wmi/wmi_host.h index f69b14031e2e..a63f6e925a08 100644 --- a/drivers/staging/ath6kl/wmi/wmi_host.h +++ b/drivers/staging/ath6kl/wmi/wmi_host.h @@ -62,7 +62,7 @@ typedef struct sq_threshold_params_s { struct wmi_t { bool wmi_ready; bool wmi_numQoSStream; - A_UINT16 wmi_streamExistsForAC[WMM_NUM_AC]; + u16 wmi_streamExistsForAC[WMM_NUM_AC]; u8 wmi_fatPipeExists; void *wmi_devt; struct wmi_stats wmi_stats; -- cgit v1.2.3 From e1ce2a3afe041c36ae397abf73f8059eb599e36e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 2 Feb 2011 14:05:51 -0800 Subject: staging: ath6kl: Convert A_UINT32 to u32 Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/bmi/include/bmi_internal.h | 4 +- drivers/staging/ath6kl/bmi/src/bmi.c | 156 +++---- .../hif/sdio/linux_sdio/include/hif_internal.h | 6 +- .../staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 42 +- .../ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c | 2 +- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 30 +- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 26 +- drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c | 8 +- drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c | 10 +- .../ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c | 8 +- drivers/staging/ath6kl/htc2/htc.c | 4 +- drivers/staging/ath6kl/htc2/htc_internal.h | 8 +- drivers/staging/ath6kl/htc2/htc_recv.c | 32 +- drivers/staging/ath6kl/htc2/htc_send.c | 2 +- drivers/staging/ath6kl/htc2/htc_services.c | 4 +- drivers/staging/ath6kl/include/a_debug.h | 10 +- drivers/staging/ath6kl/include/ar3kconfig.h | 6 +- drivers/staging/ath6kl/include/ar6000_diag.h | 16 +- drivers/staging/ath6kl/include/bmi.h | 54 +-- .../ath6kl/include/common/AR6002/AR6002_regdump.h | 34 +- .../staging/ath6kl/include/common/AR6002/addrs.h | 6 +- drivers/staging/ath6kl/include/common/a_hci.h | 18 +- drivers/staging/ath6kl/include/common/bmi_msg.h | 86 ++-- drivers/staging/ath6kl/include/common/btcoexGpio.h | 4 +- drivers/staging/ath6kl/include/common/dbglog.h | 24 +- .../staging/ath6kl/include/common/dset_internal.h | 2 +- drivers/staging/ath6kl/include/common/dsetid.h | 12 +- .../staging/ath6kl/include/common/epping_test.h | 4 +- drivers/staging/ath6kl/include/common/htc.h | 2 +- drivers/staging/ath6kl/include/common/ini_dset.h | 2 +- drivers/staging/ath6kl/include/common/regdump.h | 8 +- .../include/common/regulatory/reg_dbschema.h | 44 +- drivers/staging/ath6kl/include/common/targaddrs.h | 96 ++--- drivers/staging/ath6kl/include/common/testcmd.h | 48 +-- drivers/staging/ath6kl/include/common/wmi.h | 462 ++++++++++----------- drivers/staging/ath6kl/include/common/wmi_thin.h | 30 +- drivers/staging/ath6kl/include/common/wmix.h | 86 ++-- drivers/staging/ath6kl/include/common_drv.h | 34 +- drivers/staging/ath6kl/include/dset_api.h | 24 +- drivers/staging/ath6kl/include/gpio_api.h | 16 +- drivers/staging/ath6kl/include/hci_transport_api.h | 2 +- drivers/staging/ath6kl/include/hif.h | 38 +- drivers/staging/ath6kl/include/htc_api.h | 50 +-- drivers/staging/ath6kl/include/htc_packet.h | 10 +- drivers/staging/ath6kl/include/target_reg_table.h | 84 ++-- drivers/staging/ath6kl/include/wlan_api.h | 18 +- drivers/staging/ath6kl/include/wmi_api.h | 57 ++- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c | 22 +- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c | 50 +-- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h | 15 +- drivers/staging/ath6kl/miscdrv/common_drv.c | 108 ++--- drivers/staging/ath6kl/miscdrv/miscdrv.h | 2 +- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 170 ++++---- drivers/staging/ath6kl/os/linux/ar6000_pm.c | 10 +- drivers/staging/ath6kl/os/linux/cfg80211.c | 10 +- drivers/staging/ath6kl/os/linux/eeprom.c | 44 +- .../staging/ath6kl/os/linux/export_hci_transport.c | 16 +- drivers/staging/ath6kl/os/linux/hci_bridge.c | 2 +- .../staging/ath6kl/os/linux/include/ar6000_drv.h | 40 +- .../ath6kl/os/linux/include/ar6xapi_linux.h | 56 +-- .../staging/ath6kl/os/linux/include/athdrv_linux.h | 82 ++-- .../ath6kl/os/linux/include/export_hci_transport.h | 6 +- .../staging/ath6kl/os/linux/include/osapi_linux.h | 6 +- drivers/staging/ath6kl/os/linux/ioctl.c | 112 ++--- drivers/staging/ath6kl/os/linux/netbuf.c | 3 +- drivers/staging/ath6kl/os/linux/wireless_ext.c | 8 +- drivers/staging/ath6kl/reorder/aggr_rx_internal.h | 20 +- drivers/staging/ath6kl/wlan/include/ieee80211.h | 22 +- .../staging/ath6kl/wlan/include/ieee80211_node.h | 6 +- drivers/staging/ath6kl/wlan/src/wlan_node.c | 18 +- drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c | 2 +- drivers/staging/ath6kl/wlan/src/wlan_utils.c | 3 +- drivers/staging/ath6kl/wmi/wmi.c | 179 ++++---- drivers/staging/ath6kl/wmi/wmi_host.h | 10 +- 74 files changed, 1371 insertions(+), 1380 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/bmi/include/bmi_internal.h b/drivers/staging/ath6kl/bmi/include/bmi_internal.h index c9839f437ac1..ebc037d7922b 100644 --- a/drivers/staging/ath6kl/bmi/include/bmi_internal.h +++ b/drivers/staging/ath6kl/bmi/include/bmi_internal.h @@ -44,12 +44,12 @@ static bool bmiDone; int bmiBufferSend(HIF_DEVICE *device, A_UCHAR *buffer, - A_UINT32 length); + u32 length); int bmiBufferReceive(HIF_DEVICE *device, A_UCHAR *buffer, - A_UINT32 length, + u32 length, bool want_timeout); #endif diff --git a/drivers/staging/ath6kl/bmi/src/bmi.c b/drivers/staging/ath6kl/bmi/src/bmi.c index 165b6b3d8dd5..44add2d99f55 100644 --- a/drivers/staging/ath6kl/bmi/src/bmi.c +++ b/drivers/staging/ath6kl/bmi/src/bmi.c @@ -54,12 +54,12 @@ very simple. */ static bool pendingEventsFuncCheck = false; -static A_UINT32 *pBMICmdCredits; +static u32 *pBMICmdCredits; static A_UCHAR *pBMICmdBuf; #define MAX_BMI_CMDBUF_SZ (BMI_DATASZ_MAX + \ - sizeof(A_UINT32) /* cmd */ + \ - sizeof(A_UINT32) /* addr */ + \ - sizeof(A_UINT32))/* length */ + sizeof(u32) /* cmd */ + \ + sizeof(u32) /* addr */ + \ + sizeof(u32))/* length */ #define BMI_COMMAND_FITS(sz) ((sz) <= MAX_BMI_CMDBUF_SZ) /* APIs visible to the driver */ @@ -79,7 +79,7 @@ BMIInit(void) * bus stack. */ if (!pBMICmdCredits) { - pBMICmdCredits = (A_UINT32 *)A_MALLOC_NOWAIT(4); + pBMICmdCredits = (u32 *)A_MALLOC_NOWAIT(4); A_ASSERT(pBMICmdCredits); } @@ -109,7 +109,7 @@ int BMIDone(HIF_DEVICE *device) { int status; - A_UINT32 cid; + u32 cid; if (bmiDone) { AR_DEBUG_PRINTF (ATH_DEBUG_BMI, ("BMIDone skipped\n")); @@ -145,7 +145,7 @@ int BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) { int status; - A_UINT32 cid; + u32 cid; if (bmiDone) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); @@ -202,14 +202,14 @@ BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) int BMIReadMemory(HIF_DEVICE *device, - A_UINT32 address, + u32 address, A_UCHAR *buffer, - A_UINT32 length) + u32 length) { - A_UINT32 cid; + u32 cid; int status; - A_UINT32 offset; - A_UINT32 remaining, rxlen; + u32 offset; + u32 remaining, rxlen; A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length))); memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length)); @@ -258,15 +258,15 @@ BMIReadMemory(HIF_DEVICE *device, int BMIWriteMemory(HIF_DEVICE *device, - A_UINT32 address, + u32 address, A_UCHAR *buffer, - A_UINT32 length) + u32 length) { - A_UINT32 cid; + u32 cid; int status; - A_UINT32 offset; - A_UINT32 remaining, txlen; - const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(length); + u32 offset; + u32 remaining, txlen; + const u32 header = sizeof(cid) + sizeof(address) + sizeof(length); A_UCHAR alignedBuffer[BMI_DATASZ_MAX]; A_UCHAR *src; @@ -323,12 +323,12 @@ BMIWriteMemory(HIF_DEVICE *device, int BMIExecute(HIF_DEVICE *device, - A_UINT32 address, - A_UINT32 *param) + u32 address, + u32 *param) { - A_UINT32 cid; + u32 cid; int status; - A_UINT32 offset; + u32 offset; A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param))); memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param)); @@ -371,11 +371,11 @@ BMIExecute(HIF_DEVICE *device, int BMISetAppStart(HIF_DEVICE *device, - A_UINT32 address) + u32 address) { - A_UINT32 cid; + u32 cid; int status; - A_UINT32 offset; + u32 offset; A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address))); memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address)); @@ -408,12 +408,12 @@ BMISetAppStart(HIF_DEVICE *device, int BMIReadSOCRegister(HIF_DEVICE *device, - A_UINT32 address, - A_UINT32 *param) + u32 address, + u32 *param) { - A_UINT32 cid; + u32 cid; int status; - A_UINT32 offset; + u32 offset; A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address))); memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address)); @@ -454,12 +454,12 @@ BMIReadSOCRegister(HIF_DEVICE *device, int BMIWriteSOCRegister(HIF_DEVICE *device, - A_UINT32 address, - A_UINT32 param) + u32 address, + u32 param) { - A_UINT32 cid; + u32 cid; int status; - A_UINT32 offset; + u32 offset; A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param))); memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param)); @@ -494,15 +494,15 @@ BMIWriteSOCRegister(HIF_DEVICE *device, int BMIrompatchInstall(HIF_DEVICE *device, - A_UINT32 ROM_addr, - A_UINT32 RAM_addr, - A_UINT32 nbytes, - A_UINT32 do_activate, - A_UINT32 *rompatch_id) + u32 ROM_addr, + u32 RAM_addr, + u32 nbytes, + u32 do_activate, + u32 *rompatch_id) { - A_UINT32 cid; + u32 cid; int status; - A_UINT32 offset; + u32 offset; A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) + sizeof(nbytes) + sizeof(do_activate))); @@ -550,11 +550,11 @@ BMIrompatchInstall(HIF_DEVICE *device, int BMIrompatchUninstall(HIF_DEVICE *device, - A_UINT32 rompatch_id) + u32 rompatch_id) { - A_UINT32 cid; + u32 cid; int status; - A_UINT32 offset; + u32 offset; A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(rompatch_id))); memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(rompatch_id)); @@ -587,14 +587,14 @@ BMIrompatchUninstall(HIF_DEVICE *device, static int _BMIrompatchChangeActivation(HIF_DEVICE *device, - A_UINT32 rompatch_count, - A_UINT32 *rompatch_list, - A_UINT32 do_activate) + u32 rompatch_count, + u32 *rompatch_list, + u32 do_activate) { - A_UINT32 cid; + u32 cid; int status; - A_UINT32 offset; - A_UINT32 length; + u32 offset; + u32 length; A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count))); memset(pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count)); @@ -631,16 +631,16 @@ _BMIrompatchChangeActivation(HIF_DEVICE *device, int BMIrompatchActivate(HIF_DEVICE *device, - A_UINT32 rompatch_count, - A_UINT32 *rompatch_list) + u32 rompatch_count, + u32 *rompatch_list) { return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 1); } int BMIrompatchDeactivate(HIF_DEVICE *device, - A_UINT32 rompatch_count, - A_UINT32 *rompatch_list) + u32 rompatch_count, + u32 *rompatch_list) { return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 0); } @@ -648,13 +648,13 @@ BMIrompatchDeactivate(HIF_DEVICE *device, int BMILZData(HIF_DEVICE *device, A_UCHAR *buffer, - A_UINT32 length) + u32 length) { - A_UINT32 cid; + u32 cid; int status; - A_UINT32 offset; - A_UINT32 remaining, txlen; - const A_UINT32 header = sizeof(cid) + sizeof(length); + u32 offset; + u32 remaining, txlen; + const u32 header = sizeof(cid) + sizeof(length); A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX+header)); memset (pBMICmdBuf, 0, BMI_DATASZ_MAX+header); @@ -697,11 +697,11 @@ BMILZData(HIF_DEVICE *device, int BMILZStreamStart(HIF_DEVICE *device, - A_UINT32 address) + u32 address) { - A_UINT32 cid; + u32 cid; int status; - A_UINT32 offset; + u32 offset; A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address))); memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address)); @@ -736,12 +736,12 @@ BMILZStreamStart(HIF_DEVICE *device, int bmiBufferSend(HIF_DEVICE *device, A_UCHAR *buffer, - A_UINT32 length) + u32 length) { int status; - A_UINT32 timeout; - A_UINT32 address; - A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX]; + u32 timeout; + u32 address; + u32 mboxAddress[HTC_MAILBOX_NUM_MAX]; HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR, &mboxAddress[0], sizeof(mboxAddress)); @@ -784,12 +784,12 @@ bmiBufferSend(HIF_DEVICE *device, int bmiBufferReceive(HIF_DEVICE *device, A_UCHAR *buffer, - A_UINT32 length, + u32 length, bool want_timeout) { int status; - A_UINT32 address; - A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX]; + u32 address; + u32 mboxAddress[HTC_MAILBOX_NUM_MAX]; HIF_PENDING_EVENTS_INFO hifPendingEvents; static HIF_PENDING_EVENTS_FUNC getPendingEventsFunc = NULL; @@ -857,8 +857,8 @@ bmiBufferReceive(HIF_DEVICE *device, * NB: word_available is declared static for esoteric reasons * having to do with protection on some OSes. */ - static A_UINT32 word_available; - A_UINT32 timeout; + static u32 word_available; + u32 timeout; word_available = 0; timeout = BMI_COMMUNICATION_TIMEOUT; @@ -873,7 +873,7 @@ bmiBufferReceive(HIF_DEVICE *device, break; } - if (hifPendingEvents.AvailableRecvBytes >= sizeof(A_UINT32)) { + if (hifPendingEvents.AvailableRecvBytes >= sizeof(u32)) { word_available = 1; } continue; @@ -920,7 +920,7 @@ bmiBufferReceive(HIF_DEVICE *device, * reduce BMI_DATASZ_MAX to 32 or 64 */ if ((length > 4) && (length < 128)) { /* check against MBOX FIFO size */ - A_UINT32 timeout; + u32 timeout; *pBMICmdCredits = 0; timeout = BMI_COMMUNICATION_TIMEOUT; @@ -958,12 +958,12 @@ bmiBufferReceive(HIF_DEVICE *device, } int -BMIFastDownload(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length) +BMIFastDownload(HIF_DEVICE *device, u32 address, A_UCHAR *buffer, u32 length) { int status = A_ERROR; - A_UINT32 lastWord = 0; - A_UINT32 lastWordOffset = length & ~0x3; - A_UINT32 unalignedBytes = length & 0x3; + u32 lastWord = 0; + u32 lastWordOffset = length & ~0x3; + u32 unalignedBytes = length & 0x3; status = BMILZStreamStart (device, address); if (status) { @@ -998,13 +998,13 @@ BMIFastDownload(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 } int -BMIRawWrite(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length) +BMIRawWrite(HIF_DEVICE *device, A_UCHAR *buffer, u32 length) { return bmiBufferSend(device, buffer, length); } int -BMIRawRead(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length, bool want_timeout) +BMIRawRead(HIF_DEVICE *device, A_UCHAR *buffer, u32 length, bool want_timeout) { return bmiBufferReceive(device, buffer, length, want_timeout); } diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h index 4a8694e89355..8ea3d02f602e 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h @@ -53,10 +53,10 @@ typedef struct bus_request { struct bus_request *next; /* link list of available requests */ struct bus_request *inusenext; /* link list of in use requests */ struct semaphore sem_req; - A_UINT32 address; /* request data */ + u32 address; /* request data */ A_UCHAR *buffer; - A_UINT32 length; - A_UINT32 request; + u32 length; + u32 request; void *context; int status; struct _HIF_SCATTER_REQ_PRIV *pScatterReq; /* this request is a scatter request */ diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index 539b6d226ba7..ba4399fb1dd3 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -67,7 +67,7 @@ static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsi int reset_sdio_on_unload = 0; module_param(reset_sdio_on_unload, int, 0644); -extern A_UINT32 nohifscattersupport; +extern u32 nohifscattersupport; /* ------ Static Variables ------ */ @@ -102,9 +102,9 @@ static struct dev_pm_ops ar6k_device_pm_ops = { static int registered = 0; OSDRV_CALLBACKS osdrvCallbacks; -extern A_UINT32 onebitmode; -extern A_UINT32 busspeedlow; -extern A_UINT32 debughif; +extern u32 onebitmode; +extern u32 busspeedlow; +extern u32 debughif; static void ResetAllCards(void); static int hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func); @@ -154,10 +154,10 @@ int HIFInit(OSDRV_CALLBACKS *callbacks) static int __HIFReadWrite(HIF_DEVICE *device, - A_UINT32 address, + u32 address, A_UCHAR *buffer, - A_UINT32 length, - A_UINT32 request, + u32 length, + u32 request, void *context) { u8 opcode; @@ -331,10 +331,10 @@ void AddToAsyncList(HIF_DEVICE *device, BUS_REQUEST *busrequest) /* queue a read/write request */ int HIFReadWrite(HIF_DEVICE *device, - A_UINT32 address, + u32 address, A_UCHAR *buffer, - A_UINT32 length, - A_UINT32 request, + u32 length, + u32 request, void *context) { int status = A_OK; @@ -465,7 +465,7 @@ static int async_task(void *param) return 0; } -static A_INT32 IssueSDCommand(HIF_DEVICE *device, A_UINT32 opcode, A_UINT32 arg, A_UINT32 flags, A_UINT32 *resp) +static A_INT32 IssueSDCommand(HIF_DEVICE *device, u32 opcode, u32 arg, u32 flags, u32 *resp) { struct mmc_command cmd; A_INT32 err; @@ -495,7 +495,7 @@ int ReinitSDIO(HIF_DEVICE *device) struct mmc_card *card; struct sdio_func *func; u8 cmd52_resp; - A_UINT32 clock; + u32 clock; func = device->func; card = func->card; @@ -506,9 +506,9 @@ int ReinitSDIO(HIF_DEVICE *device) do { if (!device->is_suspend) { - A_UINT32 resp; + u32 resp; u16 rca; - A_UINT32 i; + u32 i; int bit = fls(host->ocr_avail) - 1; /* emulate the mmc_power_up(...) */ host->ios.vdd = bit; @@ -692,22 +692,22 @@ PowerStateChangeNotify(HIF_DEVICE *device, HIF_DEVICE_POWER_CHANGE_TYPE config) int HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, - void *config, A_UINT32 configLen) + void *config, u32 configLen) { - A_UINT32 count; + u32 count; int status = A_OK; switch(opcode) { case HIF_DEVICE_GET_MBOX_BLOCK_SIZE: - ((A_UINT32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE; - ((A_UINT32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE; - ((A_UINT32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE; - ((A_UINT32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE; + ((u32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE; + ((u32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE; + ((u32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE; + ((u32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE; break; case HIF_DEVICE_GET_MBOX_ADDR: for (count = 0; count < 4; count ++) { - ((A_UINT32 *)config)[count] = HIF_MBOX_START_ADDR(count); + ((u32 *)config)[count] = HIF_MBOX_START_ADDR(count); } if (configLen >= sizeof(HIF_DEVICE_MBOX_INFO)) { diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c index 6b8db5b99811..4319e3d9ad11 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c @@ -202,7 +202,7 @@ int DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest) static int HifReadWriteScatter(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq) { int status = A_EINVAL; - A_UINT32 request = pReq->Request; + u32 request = pReq->Request; HIF_SCATTER_REQ_PRIV *pReqPriv = (HIF_SCATTER_REQ_PRIV *)pReq->HIFPrivate[0]; do { diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index 6a05f4bccbde..0f57cfc29549 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -76,7 +76,7 @@ void DevCleanup(AR6K_DEVICE *pDev) int DevSetup(AR6K_DEVICE *pDev) { - A_UINT32 blocksizes[AR6K_MAILBOXES]; + u32 blocksizes[AR6K_MAILBOXES]; int status = A_OK; int i; HTC_CALLBACKS htcCallbacks; @@ -488,11 +488,11 @@ int DevEnableRecv(AR6K_DEVICE *pDev, bool AsyncMode) } } -int DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,bool *pbIsRecvPending) +int DevWaitForPendingRecv(AR6K_DEVICE *pDev,u32 TimeoutInMs,bool *pbIsRecvPending) { int status = A_OK; A_UCHAR host_int_status = 0x0; - A_UINT32 counter = 0x0; + u32 counter = 0x0; if(TimeoutInMs < 100) { @@ -612,7 +612,7 @@ int DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, bool FromDMA) { u8 *pDMABuffer = NULL; int i, remaining; - A_UINT32 length; + u32 length; pDMABuffer = pReq->pScatterBounceBuffer; @@ -669,7 +669,7 @@ static int DevReadWriteScatter(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; int status = A_OK; HTC_PACKET *pIOPacket = NULL; - A_UINT32 request = pReq->Request; + u32 request = pReq->Request; do { @@ -884,13 +884,13 @@ int DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, boo /* read operation */ pScatterReq->Request = (Async) ? HIF_RD_ASYNC_BLOCK_FIX : HIF_RD_SYNC_BLOCK_FIX; pScatterReq->Address = pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX]; - A_ASSERT(pScatterReq->TotalLength <= (A_UINT32)DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev)); + A_ASSERT(pScatterReq->TotalLength <= (u32)DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev)); } else { - A_UINT32 mailboxWidth; + u32 mailboxWidth; /* write operation */ pScatterReq->Request = (Async) ? HIF_WR_ASYNC_BLOCK_INC : HIF_WR_SYNC_BLOCK_INC; - A_ASSERT(pScatterReq->TotalLength <= (A_UINT32)DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev)); + A_ASSERT(pScatterReq->TotalLength <= (u32)DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev)); if (pScatterReq->TotalLength > AR6K_LEGACY_MAX_WRITE_LENGTH) { /* for large writes use the extended address */ pScatterReq->Address = pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedAddress; @@ -1003,14 +1003,14 @@ int DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, boo #define TEST_CREDITS_RECV_TIMEOUT 100 static u8 g_Buffer[TOTAL_BYTES]; -static A_UINT32 g_MailboxAddrs[AR6K_MAILBOXES]; -static A_UINT32 g_BlockSizes[AR6K_MAILBOXES]; +static u32 g_MailboxAddrs[AR6K_MAILBOXES]; +static u32 g_BlockSizes[AR6K_MAILBOXES]; #define BUFFER_PROC_LIST_DEPTH 4 typedef struct _BUFFER_PROC_LIST{ u8 *pBuffer; - A_UINT32 length; + u32 length; }BUFFER_PROC_LIST; @@ -1096,7 +1096,7 @@ static bool CheckBuffers(void) success = CheckOneBuffer((u16 *)checkList[i].pBuffer, checkList[i].length); if (!success) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Buffer : 0x%X, Length:%d failed verify \n", - (A_UINT32)checkList[i].pBuffer, checkList[i].length)); + (u32)checkList[i].pBuffer, checkList[i].length)); break; } } @@ -1128,7 +1128,7 @@ static u16 GetEndMarker(void) static int SendBuffers(AR6K_DEVICE *pDev, int mbox) { int status = A_OK; - A_UINT32 request = HIF_WR_SYNC_BLOCK_INC; + u32 request = HIF_WR_SYNC_BLOCK_INC; BUFFER_PROC_LIST sendList[BUFFER_PROC_LIST_DEPTH]; int i; int totalBytes = 0; @@ -1174,7 +1174,7 @@ static int GetCredits(AR6K_DEVICE *pDev, int mbox, int *pCredits) int status = A_OK; int timeout = TEST_CREDITS_RECV_TIMEOUT; u8 credits = 0; - A_UINT32 address; + u32 address; while (true) { @@ -1219,7 +1219,7 @@ static int GetCredits(AR6K_DEVICE *pDev, int mbox, int *pCredits) static int RecvBuffers(AR6K_DEVICE *pDev, int mbox) { int status = A_OK; - A_UINT32 request = HIF_RD_SYNC_BLOCK_INC; + u32 request = HIF_RD_SYNC_BLOCK_INC; BUFFER_PROC_LIST recvList[BUFFER_PROC_LIST_DEPTH]; int curBuffer; int credits; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index 0785ca2a77f5..5e147c0ec240 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -52,8 +52,8 @@ typedef PREPACK struct _AR6K_IRQ_PROC_REGISTERS { u8 rx_lookahead_valid; u8 host_int_status2; u8 gmbox_rx_avail; - A_UINT32 rx_lookahead[2]; - A_UINT32 rx_gmbox_lookahead_alias[2]; + u32 rx_lookahead[2]; + u32 rx_gmbox_lookahead_alias[2]; } POSTPACK AR6K_IRQ_PROC_REGISTERS; #define AR6K_IRQ_PROC_REGS_SIZE sizeof(AR6K_IRQ_PROC_REGISTERS) @@ -113,8 +113,8 @@ typedef struct _AR6K_DEVICE { AR6K_IRQ_ENABLE_REGISTERS IrqEnableRegisters; /* cache-line safe with pads around */ u8 _Pad3[A_CACHE_LINE_PAD]; void *HIFDevice; - A_UINT32 BlockSize; - A_UINT32 BlockMask; + u32 BlockSize; + u32 BlockMask; HIF_DEVICE_MBOX_INFO MailBoxInfo; HIF_PENDING_EVENTS_FUNC GetPendingEventsFunc; void *HTCContext; @@ -122,7 +122,7 @@ typedef struct _AR6K_DEVICE { AR6K_ASYNC_REG_IO_BUFFER RegIOBuffers[AR6K_MAX_REG_IO_BUFFERS]; void (*TargetFailureCallback)(void *Context); int (*MessagePendingCallback)(void *Context, - A_UINT32 LookAheads[], + u32 LookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched); @@ -152,7 +152,7 @@ void DevCleanup(AR6K_DEVICE *pDev); int DevUnmaskInterrupts(AR6K_DEVICE *pDev); int DevMaskInterrupts(AR6K_DEVICE *pDev); int DevPollMboxMsgRecv(AR6K_DEVICE *pDev, - A_UINT32 *pLookAhead, + u32 *pLookAhead, int TimeoutMS); int DevRWCompletionHandler(void *context, int status); int DevDsrHandler(void *context); @@ -170,14 +170,14 @@ int DevStopRecv(AR6K_DEVICE *pDev, bool ASyncMode); int DevEnableRecv(AR6K_DEVICE *pDev, bool ASyncMode); int DevEnableInterrupts(AR6K_DEVICE *pDev); int DevDisableInterrupts(AR6K_DEVICE *pDev); -int DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,bool *pbIsRecvPending); +int DevWaitForPendingRecv(AR6K_DEVICE *pDev,u32 TimeoutInMs,bool *pbIsRecvPending); #define DEV_CALC_RECV_PADDED_LEN(pDev, length) (((length) + (pDev)->BlockMask) & (~((pDev)->BlockMask))) #define DEV_CALC_SEND_PADDED_LEN(pDev, length) DEV_CALC_RECV_PADDED_LEN(pDev,length) #define DEV_IS_LEN_BLOCK_ALIGNED(pDev, length) (((length) % (pDev)->BlockSize) == 0) -static INLINE int DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 SendLength) { - A_UINT32 paddedLength; +static INLINE int DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 SendLength) { + u32 paddedLength; bool sync = (pPacket->Completion == NULL) ? true : false; int status; @@ -219,8 +219,8 @@ static INLINE int DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 return status; } -static INLINE int DevRecvPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 RecvLength) { - A_UINT32 paddedLength; +static INLINE int DevRecvPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 RecvLength) { + u32 paddedLength; int status; bool sync = (pPacket->Completion == NULL) ? true : false; @@ -376,8 +376,8 @@ AR6K_DEVICE *HTCGetAR6KDevice(void *HTCHandle); #define DEV_GMBOX_GET_PROTOCOL(pDev) (pDev)->GMboxInfo.pProtocolContext -int DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 WriteLength); -int DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 ReadLength); +int DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 WriteLength); +int DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 ReadLength); #define PROC_IO_ASYNC true #define PROC_IO_SYNC false diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c index 8ba426199ff9..f9b153315d46 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c @@ -60,7 +60,7 @@ int DevRWCompletionHandler(void *context, int status) /* mailbox recv message polling */ int DevPollMboxMsgRecv(AR6K_DEVICE *pDev, - A_UINT32 *pLookAhead, + u32 *pLookAhead, int TimeoutMS) { int status = A_OK; @@ -247,7 +247,7 @@ static int DevServiceErrorInterrupt(AR6K_DEVICE *pDev) static int DevServiceDebugInterrupt(AR6K_DEVICE *pDev) { - A_UINT32 dummy; + u32 dummy; int status; /* Send a target failure event to the application */ @@ -303,7 +303,7 @@ static int DevServiceCounterInterrupt(AR6K_DEVICE *pDev) static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket) { AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; - A_UINT32 lookAhead = 0; + u32 lookAhead = 0; bool otherInts = false; AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGetEventAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); @@ -471,7 +471,7 @@ static int ProcessPendingIRQs(AR6K_DEVICE *pDev, bool *pDone, bool *pASyncProces { int status = A_OK; u8 host_int_status = 0; - A_UINT32 lookAhead = 0; + u32 lookAhead = 0; AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+ProcessPendingIRQs: (dev: 0x%lX)\n", (unsigned long)pDev)); diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c index 1f6bc24621cc..d27bab4f6c50 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c @@ -396,12 +396,12 @@ int DevCheckGMboxInterrupts(AR6K_DEVICE *pDev) } -int DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 WriteLength) +int DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 WriteLength) { - A_UINT32 paddedLength; + u32 paddedLength; bool sync = (pPacket->Completion == NULL) ? true : false; int status; - A_UINT32 address; + u32 address; /* adjust the length to be a multiple of block size if appropriate */ paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, WriteLength); @@ -433,10 +433,10 @@ int DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 WriteLength) return status; } -int DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 ReadLength) +int DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 ReadLength) { - A_UINT32 paddedLength; + u32 paddedLength; int status; bool sync = (pPacket->Completion == NULL) ? true : false; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c index 961f5a1d44dd..cf45f9912685 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c @@ -60,8 +60,8 @@ typedef struct { HCI_TRANSPORT_CONFIG_INFO HCIConfig; bool HCIAttached; bool HCIStopped; - A_UINT32 RecvStateFlags; - A_UINT32 SendStateFlags; + u32 RecvStateFlags; + u32 SendStateFlags; HCI_TRANSPORT_PACKET_TYPE WaitBufferType; HTC_PACKET_QUEUE SendQueue; /* write queue holding HCI Command and ACL packets */ HTC_PACKET_QUEUE HCIACLRecvBuffers; /* recv queue holding buffers for incomming ACL packets */ @@ -1230,11 +1230,11 @@ int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, #define LSB_SCRATCH_IDX 4 #define MSB_SCRATCH_IDX 5 -int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud) +int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud) { GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; HIF_DEVICE *pHIFDevice = (HIF_DEVICE *)(pProt->pDev->HIFDevice); - A_UINT32 scaledBaud, scratchAddr; + u32 scaledBaud, scratchAddr; int status = A_OK; /* Divide the desired baud rate by 100 diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index 3c831e0abe36..48ae318ff9d2 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -95,8 +95,8 @@ HTC_HANDLE HTCCreate(void *hif_handle, HTC_INIT_INFO *pInfo) HTC_TARGET *target = NULL; int status = A_OK; int i; - A_UINT32 ctrl_bufsz; - A_UINT32 blocksizes[HTC_MAILBOX_NUM_MAX]; + u32 ctrl_bufsz; + u32 blocksizes[HTC_MAILBOX_NUM_MAX]; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCCreate - Enter\n")); diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h index 180ad9d9650e..743469db60eb 100644 --- a/drivers/staging/ath6kl/htc2/htc_internal.h +++ b/drivers/staging/ath6kl/htc2/htc_internal.h @@ -81,7 +81,7 @@ typedef struct _HTC_ENDPOINT { int RxProcessCount; /* reference count to allow single processing context */ struct _HTC_TARGET *target; /* back pointer to target */ u8 SeqNo; /* TX seq no (helpful) for debugging */ - A_UINT32 LocalConnectionFlags; /* local connection flags */ + u32 LocalConnectionFlags; /* local connection flags */ #ifdef HTC_EP_STAT_PROFILING HTC_ENDPOINT_STATS EndPointStats; /* endpoint statistics */ #endif @@ -123,8 +123,8 @@ typedef struct _HTC_TARGET { A_MUTEX_T HTCRxLock; A_MUTEX_T HTCTxLock; AR6K_DEVICE Device; /* AR6K - specific state */ - A_UINT32 OpStateFlags; - A_UINT32 RecvStateFlags; + u32 OpStateFlags; + u32 RecvStateFlags; HTC_ENDPOINT_ID EpWaitingForBuffers; bool TargetFailure; #ifdef HTC_CAPTURE_LAST_FRAME @@ -169,7 +169,7 @@ HTC_PACKET *HTCAllocControlBuffer(HTC_TARGET *target, HTC_PACKET_QUEUE *pList); void HTCFreeControlBuffer(HTC_TARGET *target, HTC_PACKET *pPacket, HTC_PACKET_QUEUE *pList); int HTCIssueSend(HTC_TARGET *target, HTC_PACKET *pPacket); void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket); -int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched); +int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched); void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint); int HTCSendSetupComplete(HTC_TARGET *target); void HTCFlushRecvBuffers(HTC_TARGET *target); diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c index 66e5ced10e89..8a794696d655 100644 --- a/drivers/staging/ath6kl/htc2/htc_recv.c +++ b/drivers/staging/ath6kl/htc2/htc_recv.c @@ -86,7 +86,7 @@ static void DoRecvCompletion(HTC_ENDPOINT *pEndpoint, static INLINE int HTCProcessTrailer(HTC_TARGET *target, u8 *pBuffer, int Length, - A_UINT32 *pNextLookAheads, + u32 *pNextLookAheads, int *pNumLookAheads, HTC_ENDPOINT_ID FromEndpoint) { @@ -228,14 +228,14 @@ static INLINE int HTCProcessTrailer(HTC_TARGET *target, * note : locks must be released when this function is called */ static int HTCProcessRecvHeader(HTC_TARGET *target, HTC_PACKET *pPacket, - A_UINT32 *pNextLookAheads, + u32 *pNextLookAheads, int *pNumLookAheads) { u8 temp; u8 *pBuf; int status = A_OK; u16 payloadLen; - A_UINT32 lookAhead; + u32 lookAhead; pBuf = pPacket->pBuffer; @@ -386,7 +386,7 @@ static int HTCProcessRecvHeader(HTC_TARGET *target, } static INLINE void HTCAsyncRecvCheckMorePackets(HTC_TARGET *target, - A_UINT32 NextLookAheads[], + u32 NextLookAheads[], int NumLookAheads, bool CheckMoreMsgs) { @@ -406,7 +406,7 @@ static INLINE void HTCAsyncRecvCheckMorePackets(HTC_TARGET *target, ("Next look ahead from recv header was INVALID\n")); #ifdef ATH_DEBUG_MODULE DebugDumpBytes((u8 *)NextLookAheads, - NumLookAheads * (sizeof(A_UINT32)), + NumLookAheads * (sizeof(u32)), "BAD lookaheads from lookahead report"); #endif } @@ -496,7 +496,7 @@ static INLINE void DrainRecvIndicationQueue(HTC_TARGET *target, HTC_ENDPOINT *pE (P)->PktInfo.AsRx.IndicationFlags |= HTC_RX_FLAGS_INDICATE_MORE_PKTS; /* note: this function can be called with the RX lock held */ -static INLINE void SetRxPacketIndicationFlags(A_UINT32 LookAhead, +static INLINE void SetRxPacketIndicationFlags(u32 LookAhead, HTC_ENDPOINT *pEndpoint, HTC_PACKET *pPacket) { @@ -519,7 +519,7 @@ void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket) { HTC_TARGET *target = (HTC_TARGET *)Context; HTC_ENDPOINT *pEndpoint; - A_UINT32 nextLookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; + u32 nextLookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; int numLookAheads = 0; int status; bool checkMorePkts = true; @@ -590,7 +590,7 @@ void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket) int HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket) { int status; - A_UINT32 lookAhead; + u32 lookAhead; HTC_PACKET *pPacket = NULL; HTC_FRAME_HDR *pHdr; @@ -687,7 +687,7 @@ int HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket) } static int AllocAndPrepareRxPackets(HTC_TARGET *target, - A_UINT32 LookAheads[], + u32 LookAheads[], int Messages, HTC_ENDPOINT *pEndpoint, HTC_PACKET_QUEUE *pQueue) @@ -724,7 +724,7 @@ static int AllocAndPrepareRxPackets(HTC_TARGET *target, if (pHdr->PayloadLen > HTC_MAX_PAYLOAD_LENGTH) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Payload length %d exceeds max HTC : %d !\n", - pHdr->PayloadLen, (A_UINT32)HTC_MAX_PAYLOAD_LENGTH)); + pHdr->PayloadLen, (u32)HTC_MAX_PAYLOAD_LENGTH)); status = A_EPROTO; break; } @@ -832,7 +832,7 @@ static int AllocAndPrepareRxPackets(HTC_TARGET *target, } /* make sure this message can fit in the endpoint buffer */ - if ((A_UINT32)fullLength > pPacket->BufferLength) { + if ((u32)fullLength > pPacket->BufferLength) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Payload Length Error : header reports payload of: %d (%d) endpoint buffer size: %d \n", pHdr->PayloadLen, fullLength, pPacket->BufferLength)); @@ -884,7 +884,7 @@ static void HTCAsyncRecvScatterCompletion(HIF_SCATTER_REQ *pScatterReq) int i; HTC_PACKET *pPacket; HTC_ENDPOINT *pEndpoint; - A_UINT32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; + u32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; int numLookAheads = 0; HTC_TARGET *target = (HTC_TARGET *)pScatterReq->Context; int status; @@ -1117,14 +1117,14 @@ static INLINE void CheckRecvWaterMark(HTC_ENDPOINT *pEndpoint) } /* callback when device layer or lookahead report parsing detects a pending message */ -int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched) +int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched) { HTC_TARGET *target = (HTC_TARGET *)Context; int status = A_OK; HTC_PACKET *pPacket; HTC_ENDPOINT *pEndpoint; bool asyncProc = false; - A_UINT32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; + u32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; int pktsFetched; HTC_PACKET_QUEUE recvPktQueue, syncCompletedPktsQueue; bool partialBundle; @@ -1155,7 +1155,7 @@ int HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int Nu } /* on first entry copy the lookaheads into our temp array for processing */ - A_MEMCPY(lookAheads, MsgLookAheads, (sizeof(A_UINT32)) * NumLookAheads); + A_MEMCPY(lookAheads, MsgLookAheads, (sizeof(u32)) * NumLookAheads); while (true) { @@ -1564,7 +1564,7 @@ int HTCGetNumRecvBuffers(HTC_HANDLE HTCHandle, } int HTCWaitForPendingRecv(HTC_HANDLE HTCHandle, - A_UINT32 TimeoutInMs, + u32 TimeoutInMs, bool *pbIsRecvPending) { int status = A_OK; diff --git a/drivers/staging/ath6kl/htc2/htc_send.c b/drivers/staging/ath6kl/htc2/htc_send.c index 26434d328b18..8b7c7f01ef57 100644 --- a/drivers/staging/ath6kl/htc2/htc_send.c +++ b/drivers/staging/ath6kl/htc2/htc_send.c @@ -125,7 +125,7 @@ int HTCIssueSend(HTC_TARGET *target, HTC_PACKET *pPacket) AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+-HTCIssueSend: transmit length : %d (%s) \n", - pPacket->ActualLength + (A_UINT32)HTC_HDR_LENGTH, + pPacket->ActualLength + (u32)HTC_HDR_LENGTH, sync ? "SYNC" : "ASYNC" )); /* send message to device */ diff --git a/drivers/staging/ath6kl/htc2/htc_services.c b/drivers/staging/ath6kl/htc2/htc_services.c index ea0f6e0ebfc8..08209a370341 100644 --- a/drivers/staging/ath6kl/htc2/htc_services.c +++ b/drivers/staging/ath6kl/htc2/htc_services.c @@ -44,7 +44,7 @@ void HTCControlRecv(void *Context, HTC_PACKET *pPacket) if (pPacket->ActualLength > 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTCControlRecv, got message with length:%d \n", - pPacket->ActualLength + (A_UINT32)HTC_HDR_LENGTH)); + pPacket->ActualLength + (u32)HTC_HDR_LENGTH)); #ifdef ATH_DEBUG_MODULE /* dump header and message */ @@ -73,7 +73,7 @@ int HTCSendSetupComplete(HTC_TARGET *target) if (target->HTCTargetVersion >= HTC_VERSION_2P1) { HTC_SETUP_COMPLETE_EX_MSG *pSetupCompleteEx; - A_UINT32 setupFlags = 0; + u32 setupFlags = 0; pSetupCompleteEx = (HTC_SETUP_COMPLETE_EX_MSG *)pSendPacket->pBuffer; A_MEMZERO(pSetupCompleteEx, sizeof(HTC_SETUP_COMPLETE_EX_MSG)); diff --git a/drivers/staging/ath6kl/include/a_debug.h b/drivers/staging/ath6kl/include/a_debug.h index dbba3f85616f..57472cfb7e96 100644 --- a/drivers/staging/ath6kl/include/a_debug.h +++ b/drivers/staging/ath6kl/include/a_debug.h @@ -119,7 +119,7 @@ void DebugDumpBytes(A_UCHAR *buffer, u16 length, char *pDescription); #define ATH_DEBUG_MAX_MOD_DESC_LENGTH 64 typedef struct { - A_UINT32 Mask; + u32 Mask; char Description[ATH_DEBUG_MAX_MASK_DESC_LENGTH]; } ATH_DEBUG_MASK_DESCRIPTION; @@ -129,8 +129,8 @@ typedef struct _ATH_DEBUG_MODULE_DBG_INFO{ struct _ATH_DEBUG_MODULE_DBG_INFO *pNext; char ModuleName[16]; char ModuleDescription[ATH_DEBUG_MAX_MOD_DESC_LENGTH]; - A_UINT32 Flags; - A_UINT32 CurrentMask; + u32 Flags; + u32 CurrentMask; int MaxDescriptions; ATH_DEBUG_MASK_DESCRIPTION *pMaskDescriptions; /* pointer to array of descriptions */ } ATH_DEBUG_MODULE_DBG_INFO; @@ -181,8 +181,8 @@ void a_register_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo); #endif -int a_get_module_mask(char *module_name, A_UINT32 *pMask); -int a_set_module_mask(char *module_name, A_UINT32 Mask); +int a_get_module_mask(char *module_name, u32 *pMask); +int a_set_module_mask(char *module_name, u32 Mask); void a_dump_module_debug_info_by_name(char *module_name); void a_module_debug_support_init(void); void a_module_debug_support_cleanup(void); diff --git a/drivers/staging/ath6kl/include/ar3kconfig.h b/drivers/staging/ath6kl/include/ar3kconfig.h index b7c503975c11..4d732019cf2c 100644 --- a/drivers/staging/ath6kl/include/ar3kconfig.h +++ b/drivers/staging/ath6kl/include/ar3kconfig.h @@ -39,16 +39,16 @@ extern "C" { typedef struct { - A_UINT32 Flags; /* config flags */ + u32 Flags; /* config flags */ void *pHCIDev; /* HCI bridge device */ HCI_TRANSPORT_PROPERTIES *pHCIProps; /* HCI bridge props */ HIF_DEVICE *pHIFDevice; /* HIF layer device */ - A_UINT32 AR3KBaudRate; /* AR3K operational baud rate */ + u32 AR3KBaudRate; /* AR3K operational baud rate */ u16 AR6KScale; /* AR6K UART scale value */ u16 AR6KStep; /* AR6K UART step value */ struct hci_dev *pBtStackHCIDev; /* BT Stack HCI dev */ - A_UINT32 PwrMgmtEnabled; /* TLPM enabled? */ + u32 PwrMgmtEnabled; /* TLPM enabled? */ u16 IdleTimeout; /* TLPM idle timeout */ u16 WakeupTimeout; /* TLPM wakeup timeout */ u8 bdaddr[6]; /* Bluetooth device address */ diff --git a/drivers/staging/ath6kl/include/ar6000_diag.h b/drivers/staging/ath6kl/include/ar6000_diag.h index 1470d2070984..78ac59721dc7 100644 --- a/drivers/staging/ath6kl/include/ar6000_diag.h +++ b/drivers/staging/ath6kl/include/ar6000_diag.h @@ -26,23 +26,23 @@ int -ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); +ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data); int -ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); +ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data); int -ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, - A_UCHAR *data, A_UINT32 length); +ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, u32 address, + A_UCHAR *data, u32 length); int -ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, - A_UCHAR *data, A_UINT32 length); +ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, u32 address, + A_UCHAR *data, u32 length); int -ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, A_UINT32 *regval); +ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, u32 *regval); void -ar6k_FetchTargetRegs(HIF_DEVICE *hifDevice, A_UINT32 *targregs); +ar6k_FetchTargetRegs(HIF_DEVICE *hifDevice, u32 *targregs); #endif /*AR6000_DIAG_H_*/ diff --git a/drivers/staging/ath6kl/include/bmi.h b/drivers/staging/ath6kl/include/bmi.h index 931ac408e3a0..788f9af29fc0 100644 --- a/drivers/staging/ath6kl/include/bmi.h +++ b/drivers/staging/ath6kl/include/bmi.h @@ -51,81 +51,81 @@ BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info); int BMIReadMemory(HIF_DEVICE *device, - A_UINT32 address, + u32 address, A_UCHAR *buffer, - A_UINT32 length); + u32 length); int BMIWriteMemory(HIF_DEVICE *device, - A_UINT32 address, + u32 address, A_UCHAR *buffer, - A_UINT32 length); + u32 length); int BMIExecute(HIF_DEVICE *device, - A_UINT32 address, - A_UINT32 *param); + u32 address, + u32 *param); int BMISetAppStart(HIF_DEVICE *device, - A_UINT32 address); + u32 address); int BMIReadSOCRegister(HIF_DEVICE *device, - A_UINT32 address, - A_UINT32 *param); + u32 address, + u32 *param); int BMIWriteSOCRegister(HIF_DEVICE *device, - A_UINT32 address, - A_UINT32 param); + u32 address, + u32 param); int BMIrompatchInstall(HIF_DEVICE *device, - A_UINT32 ROM_addr, - A_UINT32 RAM_addr, - A_UINT32 nbytes, - A_UINT32 do_activate, - A_UINT32 *patch_id); + u32 ROM_addr, + u32 RAM_addr, + u32 nbytes, + u32 do_activate, + u32 *patch_id); int BMIrompatchUninstall(HIF_DEVICE *device, - A_UINT32 rompatch_id); + u32 rompatch_id); int BMIrompatchActivate(HIF_DEVICE *device, - A_UINT32 rompatch_count, - A_UINT32 *rompatch_list); + u32 rompatch_count, + u32 *rompatch_list); int BMIrompatchDeactivate(HIF_DEVICE *device, - A_UINT32 rompatch_count, - A_UINT32 *rompatch_list); + u32 rompatch_count, + u32 *rompatch_list); int BMILZStreamStart(HIF_DEVICE *device, - A_UINT32 address); + u32 address); int BMILZData(HIF_DEVICE *device, A_UCHAR *buffer, - A_UINT32 length); + u32 length); int BMIFastDownload(HIF_DEVICE *device, - A_UINT32 address, + u32 address, A_UCHAR *buffer, - A_UINT32 length); + u32 length); int BMIRawWrite(HIF_DEVICE *device, A_UCHAR *buffer, - A_UINT32 length); + u32 length); int BMIRawRead(HIF_DEVICE *device, A_UCHAR *buffer, - A_UINT32 length, + u32 length, bool want_timeout); #ifdef __cplusplus diff --git a/drivers/staging/ath6kl/include/common/AR6002/AR6002_regdump.h b/drivers/staging/ath6kl/include/common/AR6002/AR6002_regdump.h index e3291cf4dbd4..4a9b275d68b8 100644 --- a/drivers/staging/ath6kl/include/common/AR6002/AR6002_regdump.h +++ b/drivers/staging/ath6kl/include/common/AR6002/AR6002_regdump.h @@ -29,28 +29,28 @@ * This must match the state saved by the target exception handler. */ struct XTensa_exception_frame_s { - A_UINT32 xt_pc; - A_UINT32 xt_ps; - A_UINT32 xt_sar; - A_UINT32 xt_vpri; - A_UINT32 xt_a2; - A_UINT32 xt_a3; - A_UINT32 xt_a4; - A_UINT32 xt_a5; - A_UINT32 xt_exccause; - A_UINT32 xt_lcount; - A_UINT32 xt_lbeg; - A_UINT32 xt_lend; + u32 xt_pc; + u32 xt_ps; + u32 xt_sar; + u32 xt_vpri; + u32 xt_a2; + u32 xt_a3; + u32 xt_a4; + u32 xt_a5; + u32 xt_exccause; + u32 xt_lcount; + u32 xt_lbeg; + u32 xt_lend; - A_UINT32 epc1, epc2, epc3, epc4; + u32 epc1, epc2, epc3, epc4; /* Extra info to simplify post-mortem stack walkback */ #define AR6002_REGDUMP_FRAMES 10 struct { - A_UINT32 a0; /* pc */ - A_UINT32 a1; /* sp */ - A_UINT32 a2; - A_UINT32 a3; + u32 a0; /* pc */ + u32 a1; /* sp */ + u32 a2; + u32 a3; } wb[AR6002_REGDUMP_FRAMES]; }; typedef struct XTensa_exception_frame_s CPU_exception_frame_t; diff --git a/drivers/staging/ath6kl/include/common/AR6002/addrs.h b/drivers/staging/ath6kl/include/common/AR6002/addrs.h index eaaccf4cad7b..bbf8d42828c1 100644 --- a/drivers/staging/ath6kl/include/common/AR6002/addrs.h +++ b/drivers/staging/ath6kl/include/common/AR6002/addrs.h @@ -29,13 +29,13 @@ #if defined(AR6002_REV2) #define AR6K_RAM_START 0x00500000 -#define TARG_RAM_OFFSET(vaddr) ((A_UINT32)(vaddr) & 0xfffff) +#define TARG_RAM_OFFSET(vaddr) ((u32)(vaddr) & 0xfffff) #define TARG_RAM_SZ (184*1024) #define TARG_ROM_SZ (80*1024) #endif #if defined(AR6002_REV4) || defined(AR6003) #define AR6K_RAM_START 0x00540000 -#define TARG_RAM_OFFSET(vaddr) (((A_UINT32)(vaddr) & 0xfffff) - 0x40000) +#define TARG_RAM_OFFSET(vaddr) (((u32)(vaddr) & 0xfffff) - 0x40000) #define TARG_RAM_SZ (256*1024) #define TARG_ROM_SZ (256*1024) #endif @@ -49,7 +49,7 @@ #define TARG_RAM_ADDRS(byte_offset) AR6K_RAM_ADDR(byte_offset) #define AR6K_ROM_START 0x004e0000 -#define TARG_ROM_OFFSET(vaddr) (((A_UINT32)(vaddr) & 0x1fffff) - 0xe0000) +#define TARG_ROM_OFFSET(vaddr) (((u32)(vaddr) & 0x1fffff) - 0xe0000) #define AR6K_ROM_ADDR(byte_offset) (AR6K_ROM_START+(byte_offset)) #define TARG_ROM_ADDRS(byte_offset) AR6K_ROM_ADDR(byte_offset) diff --git a/drivers/staging/ath6kl/include/common/a_hci.h b/drivers/staging/ath6kl/include/common/a_hci.h index 317ea57ba87f..3734662d614f 100644 --- a/drivers/staging/ath6kl/include/common/a_hci.h +++ b/drivers/staging/ath6kl/include/common/a_hci.h @@ -351,9 +351,9 @@ typedef struct flow_spec_t { u8 id; u8 service_type; u16 max_sdu; - A_UINT32 sdu_inter_arrival_time; - A_UINT32 access_latency; - A_UINT32 flush_timeout; + u32 sdu_inter_arrival_time; + u32 access_latency; + u32 flush_timeout; } POSTPACK FLOW_SPEC; @@ -559,15 +559,15 @@ typedef struct hci_event_amp_status_change_t{ typedef struct local_amp_info_resp_t { u8 status; u8 amp_status; - A_UINT32 total_bw; /* kbps */ - A_UINT32 max_guranteed_bw; /* kbps */ - A_UINT32 min_latency; - A_UINT32 max_pdu_size; + u32 total_bw; /* kbps */ + u32 max_guranteed_bw; /* kbps */ + u32 min_latency; + u32 max_pdu_size; u8 amp_type; u16 pal_capabilities; u16 amp_assoc_len; - A_UINT32 max_flush_timeout; /* in ms */ - A_UINT32 be_flush_timeout; /* in ms */ + u32 max_flush_timeout; /* in ms */ + u32 be_flush_timeout; /* in ms */ } POSTPACK LOCAL_AMP_INFO; typedef struct amp_assoc_cmd_resp_t{ diff --git a/drivers/staging/ath6kl/include/common/bmi_msg.h b/drivers/staging/ath6kl/include/common/bmi_msg.h index 171bf378baa0..e76624c5915c 100644 --- a/drivers/staging/ath6kl/include/common/bmi_msg.h +++ b/drivers/staging/ath6kl/include/common/bmi_msg.h @@ -65,7 +65,7 @@ /* * Semantics: Host is done using BMI * Request format: - * A_UINT32 command (BMI_DONE) + * u32 command (BMI_DONE) * Response format: none */ @@ -73,9 +73,9 @@ /* * Semantics: Host reads AR6K memory * Request format: - * A_UINT32 command (BMI_READ_MEMORY) - * A_UINT32 address - * A_UINT32 length, at most BMI_DATASZ_MAX + * u32 command (BMI_READ_MEMORY) + * u32 address + * u32 length, at most BMI_DATASZ_MAX * Response format: * u8 data[length] */ @@ -84,9 +84,9 @@ /* * Semantics: Host writes AR6K memory * Request format: - * A_UINT32 command (BMI_WRITE_MEMORY) - * A_UINT32 address - * A_UINT32 length, at most BMI_DATASZ_MAX + * u32 command (BMI_WRITE_MEMORY) + * u32 address + * u32 length, at most BMI_DATASZ_MAX * u8 data[length] * Response format: none */ @@ -95,19 +95,19 @@ /* * Semantics: Causes AR6K to execute code * Request format: - * A_UINT32 command (BMI_EXECUTE) - * A_UINT32 address - * A_UINT32 parameter + * u32 command (BMI_EXECUTE) + * u32 address + * u32 parameter * Response format: - * A_UINT32 return value + * u32 return value */ #define BMI_SET_APP_START 5 /* * Semantics: Set Target application starting address * Request format: - * A_UINT32 command (BMI_SET_APP_START) - * A_UINT32 address + * u32 command (BMI_SET_APP_START) + * u32 address * Response format: none */ @@ -115,19 +115,19 @@ /* * Semantics: Read a 32-bit Target SOC register. * Request format: - * A_UINT32 command (BMI_READ_REGISTER) - * A_UINT32 address + * u32 command (BMI_READ_REGISTER) + * u32 address * Response format: - * A_UINT32 value + * u32 value */ #define BMI_WRITE_SOC_REGISTER 7 /* * Semantics: Write a 32-bit Target SOC register. * Request format: - * A_UINT32 command (BMI_WRITE_REGISTER) - * A_UINT32 address - * A_UINT32 value + * u32 command (BMI_WRITE_REGISTER) + * u32 address + * u32 value * * Response format: none */ @@ -137,18 +137,18 @@ /* * Semantics: Fetch the 4-byte Target information * Request format: - * A_UINT32 command (BMI_GET_TARGET_ID/INFO) + * u32 command (BMI_GET_TARGET_ID/INFO) * Response format1 (old firmware): - * A_UINT32 TargetVersionID + * u32 TargetVersionID * Response format2 (newer firmware): - * A_UINT32 TARGET_VERSION_SENTINAL + * u32 TARGET_VERSION_SENTINAL * struct bmi_target_info; */ PREPACK struct bmi_target_info { - A_UINT32 target_info_byte_count; /* size of this structure */ - A_UINT32 target_ver; /* Target Version ID */ - A_UINT32 target_type; /* Target type */ + u32 target_info_byte_count; /* size of this structure */ + u32 target_ver; /* Target Version ID */ + u32 target_type; /* Target type */ } POSTPACK; #define TARGET_VERSION_SENTINAL 0xffffffff #define TARGET_TYPE_AR6001 1 @@ -160,14 +160,14 @@ PREPACK struct bmi_target_info { /* * Semantics: Install a ROM Patch. * Request format: - * A_UINT32 command (BMI_ROMPATCH_INSTALL) - * A_UINT32 Target ROM Address - * A_UINT32 Target RAM Address or Value (depending on Target Type) - * A_UINT32 Size, in bytes - * A_UINT32 Activate? 1-->activate; + * u32 command (BMI_ROMPATCH_INSTALL) + * u32 Target ROM Address + * u32 Target RAM Address or Value (depending on Target Type) + * u32 Size, in bytes + * u32 Activate? 1-->activate; * 0-->install but do not activate * Response format: - * A_UINT32 PatchID + * u32 PatchID */ #define BMI_ROMPATCH_UNINSTALL 10 @@ -175,8 +175,8 @@ PREPACK struct bmi_target_info { * Semantics: Uninstall a previously-installed ROM Patch, * automatically deactivating, if necessary. * Request format: - * A_UINT32 command (BMI_ROMPATCH_UNINSTALL) - * A_UINT32 PatchID + * u32 command (BMI_ROMPATCH_UNINSTALL) + * u32 PatchID * * Response format: none */ @@ -185,9 +185,9 @@ PREPACK struct bmi_target_info { /* * Semantics: Activate a list of previously-installed ROM Patches. * Request format: - * A_UINT32 command (BMI_ROMPATCH_ACTIVATE) - * A_UINT32 rompatch_count - * A_UINT32 PatchID[rompatch_count] + * u32 command (BMI_ROMPATCH_ACTIVATE) + * u32 rompatch_count + * u32 PatchID[rompatch_count] * * Response format: none */ @@ -196,9 +196,9 @@ PREPACK struct bmi_target_info { /* * Semantics: Deactivate a list of active ROM Patches. * Request format: - * A_UINT32 command (BMI_ROMPATCH_DEACTIVATE) - * A_UINT32 rompatch_count - * A_UINT32 PatchID[rompatch_count] + * u32 command (BMI_ROMPATCH_DEACTIVATE) + * u32 rompatch_count + * u32 PatchID[rompatch_count] * * Response format: none */ @@ -213,8 +213,8 @@ PREPACK struct bmi_target_info { * output from the compressed input stream. This BMI * command should be followed by a series of 1 or more * BMI_LZ_DATA commands. - * A_UINT32 command (BMI_LZ_STREAM_START) - * A_UINT32 address + * u32 command (BMI_LZ_STREAM_START) + * u32 address * Note: Not supported on all versions of ROM firmware. */ @@ -226,8 +226,8 @@ PREPACK struct bmi_target_info { * of BMI_LZ_DATA commands are considered part of a single * input stream until another BMI_LZ_STREAM_START is issued. * Request format: - * A_UINT32 command (BMI_LZ_DATA) - * A_UINT32 length (of compressed data), + * u32 command (BMI_LZ_DATA) + * u32 length (of compressed data), * at most BMI_DATASZ_MAX * u8 CompressedData[length] * Response format: none diff --git a/drivers/staging/ath6kl/include/common/btcoexGpio.h b/drivers/staging/ath6kl/include/common/btcoexGpio.h index bc067f557eaa..9d5a239f1fba 100644 --- a/drivers/staging/ath6kl/include/common/btcoexGpio.h +++ b/drivers/staging/ath6kl/include/common/btcoexGpio.h @@ -71,8 +71,8 @@ -extern void btcoexDbgPulseWord(A_UINT32 gpioPinMask); -extern void btcoexDbgPulse(A_UINT32 pin); +extern void btcoexDbgPulseWord(u32 gpioPinMask); +extern void btcoexDbgPulse(u32 pin); #ifdef CONFIG_BTCOEX_ENABLE_GPIO_DEBUG #define BTCOEX_DBG_PULSE_WORD(gpioPinMask) (btcoexDbgPulseWord(gpioPinMask)) diff --git a/drivers/staging/ath6kl/include/common/dbglog.h b/drivers/staging/ath6kl/include/common/dbglog.h index 060a6b16c193..3a3d00da0b81 100644 --- a/drivers/staging/ath6kl/include/common/dbglog.h +++ b/drivers/staging/ath6kl/include/common/dbglog.h @@ -90,30 +90,30 @@ extern "C" { PREPACK struct dbglog_buf_s { struct dbglog_buf_s *next; u8 *buffer; - A_UINT32 bufsize; - A_UINT32 length; - A_UINT32 count; - A_UINT32 free; + u32 bufsize; + u32 length; + u32 count; + u32 free; } POSTPACK; PREPACK struct dbglog_hdr_s { struct dbglog_buf_s *dbuf; - A_UINT32 dropped; + u32 dropped; } POSTPACK; PREPACK struct dbglog_config_s { - A_UINT32 cfgvalid; /* Mask with valid config bits */ + u32 cfgvalid; /* Mask with valid config bits */ union { /* TODO: Take care of endianness */ struct { - A_UINT32 mmask:16; /* Mask of modules with logging on */ - A_UINT32 rep:1; /* Reporting enabled or not */ - A_UINT32 tsr:3; /* Time stamp resolution. Def: 1 ms */ - A_UINT32 size:10; /* Report size in number of messages */ - A_UINT32 reserved:2; + u32 mmask:16; /* Mask of modules with logging on */ + u32 rep:1; /* Reporting enabled or not */ + u32 tsr:3; /* Time stamp resolution. Def: 1 ms */ + u32 size:10; /* Report size in number of messages */ + u32 reserved:2; } dbglog_config; - A_UINT32 value; + u32 value; } u; } POSTPACK; diff --git a/drivers/staging/ath6kl/include/common/dset_internal.h b/drivers/staging/ath6kl/include/common/dset_internal.h index 74914f9cb3c4..69475331eab7 100644 --- a/drivers/staging/ath6kl/include/common/dset_internal.h +++ b/drivers/staging/ath6kl/include/common/dset_internal.h @@ -48,7 +48,7 @@ typedef PREPACK struct dset_descriptor_s { DataSet or pointer to original dset_descriptor for patched DataSet */ - A_UINT32 data_type; /* DSET_TYPE_*, above */ + u32 data_type; /* DSET_TYPE_*, above */ void *AuxPtr; /* Additional data that might needed for data_type. For diff --git a/drivers/staging/ath6kl/include/common/dsetid.h b/drivers/staging/ath6kl/include/common/dsetid.h index d08fdeb39ec3..090e30967925 100644 --- a/drivers/staging/ath6kl/include/common/dsetid.h +++ b/drivers/staging/ath6kl/include/common/dsetid.h @@ -81,8 +81,8 @@ * This allows for patches to be stored in flash. */ PREPACK struct patch_s { - A_UINT32 *address; - A_UINT32 data; + u32 *address; + u32 data; } POSTPACK ; /* @@ -92,23 +92,23 @@ PREPACK struct patch_s { * patch code. The "data" in a PATCH_SKIP tells how many * bytes of length "patch_s" to skip. */ -#define PATCH_SKIP ((A_UINT32 *)0x00000000) +#define PATCH_SKIP ((u32 *)0x00000000) /* * Execute code at the address specified by "data". * The address of the patch structure is passed as * the one parameter. */ -#define PATCH_CODE_ABS ((A_UINT32 *)0x00000001) +#define PATCH_CODE_ABS ((u32 *)0x00000001) /* * Same as PATCH_CODE_ABS, but treat "data" as an * offset from the start of the patch word. */ -#define PATCH_CODE_REL ((A_UINT32 *)0x00000002) +#define PATCH_CODE_REL ((u32 *)0x00000002) /* Mark the end of this patch DataSet. */ -#define PATCH_END ((A_UINT32 *)0xffffffff) +#define PATCH_END ((u32 *)0xffffffff) /* * A DataSet which contains a Binary Patch to some other DataSet diff --git a/drivers/staging/ath6kl/include/common/epping_test.h b/drivers/staging/ath6kl/include/common/epping_test.h index 45f82dd79236..2cd43c46c144 100644 --- a/drivers/staging/ath6kl/include/common/epping_test.h +++ b/drivers/staging/ath6kl/include/common/epping_test.h @@ -54,8 +54,8 @@ typedef PREPACK struct { u8 _pad[2]; /* padding for alignment */ u8 TimeStamp[8]; /* timestamp of packet (host or target) */ - A_UINT32 HostContext_h; /* 4 byte host context, target echos this back */ - A_UINT32 SeqNo; /* sequence number (set by host or target) */ + u32 HostContext_h; /* 4 byte host context, target echos this back */ + u32 SeqNo; /* sequence number (set by host or target) */ u16 Cmd_h; /* ping command (filled by host) */ u16 CmdFlags_h; /* optional flags */ u8 CmdBuffer_h[8]; /* buffer for command (host -> target) */ diff --git a/drivers/staging/ath6kl/include/common/htc.h b/drivers/staging/ath6kl/include/common/htc.h index 6c85bebd994d..bed8e26abc3d 100644 --- a/drivers/staging/ath6kl/include/common/htc.h +++ b/drivers/staging/ath6kl/include/common/htc.h @@ -181,7 +181,7 @@ typedef PREPACK struct { /* extended setup completion message */ typedef PREPACK struct { u16 MessageID; - A_UINT32 SetupFlags; + u32 SetupFlags; u8 MaxMsgsPerBundledRecv; u8 Rsvd[3]; } POSTPACK HTC_SETUP_COMPLETE_EX_MSG; diff --git a/drivers/staging/ath6kl/include/common/ini_dset.h b/drivers/staging/ath6kl/include/common/ini_dset.h index d6f2301f5713..8bfc75940c8f 100644 --- a/drivers/staging/ath6kl/include/common/ini_dset.h +++ b/drivers/staging/ath6kl/include/common/ini_dset.h @@ -76,7 +76,7 @@ typedef enum { typedef PREPACK struct { u16 freqIndex; // 1 - A mode 2 - B or G mode 0 - common u16 offset; - A_UINT32 newValue; + u32 newValue; } POSTPACK INI_DSET_REG_OVERRIDE; #endif diff --git a/drivers/staging/ath6kl/include/common/regdump.h b/drivers/staging/ath6kl/include/common/regdump.h index ff79b4846e69..aa64821617e8 100644 --- a/drivers/staging/ath6kl/include/common/regdump.h +++ b/drivers/staging/ath6kl/include/common/regdump.h @@ -42,10 +42,10 @@ * the diagnostic window. */ PREPACK struct register_dump_s { - A_UINT32 target_id; /* Target ID */ - A_UINT32 assline; /* Line number (if assertion failure) */ - A_UINT32 pc; /* Program Counter at time of exception */ - A_UINT32 badvaddr; /* Virtual address causing exception */ + u32 target_id; /* Target ID */ + u32 assline; /* Line number (if assertion failure) */ + u32 pc; /* Program Counter at time of exception */ + u32 badvaddr; /* Virtual address causing exception */ CPU_exception_frame_t exc_frame; /* CPU-specific exception info */ /* Could copy top of stack here, too.... */ diff --git a/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h b/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h index 36e266fe02dd..93d7c0b64fd6 100644 --- a/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h +++ b/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h @@ -145,22 +145,22 @@ typedef PREPACK struct dbMasterTable_t { /* Hold ptrs to Table data structure #define BMZERO {0,0} /* BMLEN zeros */ #define BM(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh) \ - {((((_fa >= 0) && (_fa < 32)) ? (((A_UINT32) 1) << _fa) : 0) | \ - (((_fb >= 0) && (_fb < 32)) ? (((A_UINT32) 1) << _fb) : 0) | \ - (((_fc >= 0) && (_fc < 32)) ? (((A_UINT32) 1) << _fc) : 0) | \ - (((_fd >= 0) && (_fd < 32)) ? (((A_UINT32) 1) << _fd) : 0) | \ - (((_fe >= 0) && (_fe < 32)) ? (((A_UINT32) 1) << _fe) : 0) | \ - (((_ff >= 0) && (_ff < 32)) ? (((A_UINT32) 1) << _ff) : 0) | \ - (((_fg >= 0) && (_fg < 32)) ? (((A_UINT32) 1) << _fg) : 0) | \ - (((_fh >= 0) && (_fh < 32)) ? (((A_UINT32) 1) << _fh) : 0)), \ - ((((_fa > 31) && (_fa < 64)) ? (((A_UINT32) 1) << (_fa - 32)) : 0) | \ - (((_fb > 31) && (_fb < 64)) ? (((A_UINT32) 1) << (_fb - 32)) : 0) | \ - (((_fc > 31) && (_fc < 64)) ? (((A_UINT32) 1) << (_fc - 32)) : 0) | \ - (((_fd > 31) && (_fd < 64)) ? (((A_UINT32) 1) << (_fd - 32)) : 0) | \ - (((_fe > 31) && (_fe < 64)) ? (((A_UINT32) 1) << (_fe - 32)) : 0) | \ - (((_ff > 31) && (_ff < 64)) ? (((A_UINT32) 1) << (_ff - 32)) : 0) | \ - (((_fg > 31) && (_fg < 64)) ? (((A_UINT32) 1) << (_fg - 32)) : 0) | \ - (((_fh > 31) && (_fh < 64)) ? (((A_UINT32) 1) << (_fh - 32)) : 0))} + {((((_fa >= 0) && (_fa < 32)) ? (((u32) 1) << _fa) : 0) | \ + (((_fb >= 0) && (_fb < 32)) ? (((u32) 1) << _fb) : 0) | \ + (((_fc >= 0) && (_fc < 32)) ? (((u32) 1) << _fc) : 0) | \ + (((_fd >= 0) && (_fd < 32)) ? (((u32) 1) << _fd) : 0) | \ + (((_fe >= 0) && (_fe < 32)) ? (((u32) 1) << _fe) : 0) | \ + (((_ff >= 0) && (_ff < 32)) ? (((u32) 1) << _ff) : 0) | \ + (((_fg >= 0) && (_fg < 32)) ? (((u32) 1) << _fg) : 0) | \ + (((_fh >= 0) && (_fh < 32)) ? (((u32) 1) << _fh) : 0)), \ + ((((_fa > 31) && (_fa < 64)) ? (((u32) 1) << (_fa - 32)) : 0) | \ + (((_fb > 31) && (_fb < 64)) ? (((u32) 1) << (_fb - 32)) : 0) | \ + (((_fc > 31) && (_fc < 64)) ? (((u32) 1) << (_fc - 32)) : 0) | \ + (((_fd > 31) && (_fd < 64)) ? (((u32) 1) << (_fd - 32)) : 0) | \ + (((_fe > 31) && (_fe < 64)) ? (((u32) 1) << (_fe - 32)) : 0) | \ + (((_ff > 31) && (_ff < 64)) ? (((u32) 1) << (_ff - 32)) : 0) | \ + (((_fg > 31) && (_fg < 64)) ? (((u32) 1) << (_fg - 32)) : 0) | \ + (((_fh > 31) && (_fh < 64)) ? (((u32) 1) << (_fh - 32)) : 0))} /* @@ -174,7 +174,7 @@ typedef PREPACK struct reg_dmn_pair_mapping { u16 regDmn2GHz; /* 2GHz reg domain */ u8 flags5GHz; /* Requirements flags (AdHoc disallow etc) */ u8 flags2GHz; /* Requirements flags (AdHoc disallow etc) */ - A_UINT32 pscanMask; /* Passive Scan flags which can override unitary domain passive scan + u32 pscanMask; /* Passive Scan flags which can override unitary domain passive scan flags. This value is used as a mask on the unitary flags*/ } POSTPACK REG_DMN_PAIR_MAPPING; @@ -215,8 +215,8 @@ typedef PREPACK struct RegDmnFreqBand { u8 channelSep; /* Channel separation within the band */ u8 useDfs; /* Use DFS in the RegDomain if corresponding bit is set */ u8 mode; /* Mode of operation */ - A_UINT32 usePassScan; /* Use Passive Scan in the RegDomain if corresponding bit is set */ - A_UINT32 ht40ChanMask; /* lower 16 bits: indicate which frequencies in the block is HT40 capable + u32 usePassScan; /* Use Passive Scan in the RegDomain if corresponding bit is set */ + u32 ht40ChanMask; /* lower 16 bits: indicate which frequencies in the block is HT40 capable upper 16 bits: what rate (half/quarter) the channel is */ } POSTPACK REG_DMN_FREQ_BAND; @@ -229,9 +229,9 @@ typedef PREPACK struct regDomain { u8 dfsMask; /* DFS bitmask for 5Ghz tables */ u8 flags; /* Requirement flags (AdHoc disallow etc) */ u16 reserved; /* for alignment */ - A_UINT32 pscan; /* Bitmask for passive scan */ - A_UINT32 chan11a[BMLEN]; /* 64 bit bitmask for channel/band selection */ - A_UINT32 chan11bg[BMLEN];/* 64 bit bitmask for channel/band selection */ + u32 pscan; /* Bitmask for passive scan */ + u32 chan11a[BMLEN]; /* 64 bit bitmask for channel/band selection */ + u32 chan11bg[BMLEN];/* 64 bit bitmask for channel/band selection */ } POSTPACK REG_DOMAIN; #endif /* __REG_DBSCHEMA_H__ */ diff --git a/drivers/staging/ath6kl/include/common/targaddrs.h b/drivers/staging/ath6kl/include/common/targaddrs.h index e8cf70354d21..794ae2182a77 100644 --- a/drivers/staging/ath6kl/include/common/targaddrs.h +++ b/drivers/staging/ath6kl/include/common/targaddrs.h @@ -83,13 +83,13 @@ PREPACK struct host_interest_s { * Pointer to application-defined area, if any. * Set by Target application during startup. */ - A_UINT32 hi_app_host_interest; /* 0x00 */ + u32 hi_app_host_interest; /* 0x00 */ /* Pointer to register dump area, valid after Target crash. */ - A_UINT32 hi_failure_state; /* 0x04 */ + u32 hi_failure_state; /* 0x04 */ /* Pointer to debug logging header */ - A_UINT32 hi_dbglog_hdr; /* 0x08 */ + u32 hi_dbglog_hdr; /* 0x08 */ /* Indicates whether or not flash is present on Target. * NB: flash_is_present indicator is here not just @@ -99,36 +99,36 @@ PREPACK struct host_interest_s { * so that it doesn't get reinitialized with the rest * of data. */ - A_UINT32 hi_flash_is_present; /* 0x0c */ + u32 hi_flash_is_present; /* 0x0c */ /* * General-purpose flag bits, similar to AR6000_OPTION_* flags. * Can be used by application rather than by OS. */ - A_UINT32 hi_option_flag; /* 0x10 */ + u32 hi_option_flag; /* 0x10 */ /* * Boolean that determines whether or not to * display messages on the serial port. */ - A_UINT32 hi_serial_enable; /* 0x14 */ + u32 hi_serial_enable; /* 0x14 */ /* Start address of Flash DataSet index, if any */ - A_UINT32 hi_dset_list_head; /* 0x18 */ + u32 hi_dset_list_head; /* 0x18 */ /* Override Target application start address */ - A_UINT32 hi_app_start; /* 0x1c */ + u32 hi_app_start; /* 0x1c */ /* Clock and voltage tuning */ - A_UINT32 hi_skip_clock_init; /* 0x20 */ - A_UINT32 hi_core_clock_setting; /* 0x24 */ - A_UINT32 hi_cpu_clock_setting; /* 0x28 */ - A_UINT32 hi_system_sleep_setting; /* 0x2c */ - A_UINT32 hi_xtal_control_setting; /* 0x30 */ - A_UINT32 hi_pll_ctrl_setting_24ghz; /* 0x34 */ - A_UINT32 hi_pll_ctrl_setting_5ghz; /* 0x38 */ - A_UINT32 hi_ref_voltage_trim_setting; /* 0x3c */ - A_UINT32 hi_clock_info; /* 0x40 */ + u32 hi_skip_clock_init; /* 0x20 */ + u32 hi_core_clock_setting; /* 0x24 */ + u32 hi_cpu_clock_setting; /* 0x28 */ + u32 hi_system_sleep_setting; /* 0x2c */ + u32 hi_xtal_control_setting; /* 0x30 */ + u32 hi_pll_ctrl_setting_24ghz; /* 0x34 */ + u32 hi_pll_ctrl_setting_5ghz; /* 0x38 */ + u32 hi_ref_voltage_trim_setting; /* 0x3c */ + u32 hi_clock_info; /* 0x40 */ /* * Flash configuration overrides, used only @@ -136,49 +136,49 @@ PREPACK struct host_interest_s { * (When using flash, modify the global variables * with equivalent names.) */ - A_UINT32 hi_bank0_addr_value; /* 0x44 */ - A_UINT32 hi_bank0_read_value; /* 0x48 */ - A_UINT32 hi_bank0_write_value; /* 0x4c */ - A_UINT32 hi_bank0_config_value; /* 0x50 */ + u32 hi_bank0_addr_value; /* 0x44 */ + u32 hi_bank0_read_value; /* 0x48 */ + u32 hi_bank0_write_value; /* 0x4c */ + u32 hi_bank0_config_value; /* 0x50 */ /* Pointer to Board Data */ - A_UINT32 hi_board_data; /* 0x54 */ - A_UINT32 hi_board_data_initialized; /* 0x58 */ + u32 hi_board_data; /* 0x54 */ + u32 hi_board_data_initialized; /* 0x58 */ - A_UINT32 hi_dset_RAM_index_table; /* 0x5c */ + u32 hi_dset_RAM_index_table; /* 0x5c */ - A_UINT32 hi_desired_baud_rate; /* 0x60 */ - A_UINT32 hi_dbglog_config; /* 0x64 */ - A_UINT32 hi_end_RAM_reserve_sz; /* 0x68 */ - A_UINT32 hi_mbox_io_block_sz; /* 0x6c */ + u32 hi_desired_baud_rate; /* 0x60 */ + u32 hi_dbglog_config; /* 0x64 */ + u32 hi_end_RAM_reserve_sz; /* 0x68 */ + u32 hi_mbox_io_block_sz; /* 0x6c */ - A_UINT32 hi_num_bpatch_streams; /* 0x70 -- unused */ - A_UINT32 hi_mbox_isr_yield_limit; /* 0x74 */ + u32 hi_num_bpatch_streams; /* 0x70 -- unused */ + u32 hi_mbox_isr_yield_limit; /* 0x74 */ - A_UINT32 hi_refclk_hz; /* 0x78 */ - A_UINT32 hi_ext_clk_detected; /* 0x7c */ - A_UINT32 hi_dbg_uart_txpin; /* 0x80 */ - A_UINT32 hi_dbg_uart_rxpin; /* 0x84 */ - A_UINT32 hi_hci_uart_baud; /* 0x88 */ - A_UINT32 hi_hci_uart_pin_assignments; /* 0x8C */ + u32 hi_refclk_hz; /* 0x78 */ + u32 hi_ext_clk_detected; /* 0x7c */ + u32 hi_dbg_uart_txpin; /* 0x80 */ + u32 hi_dbg_uart_rxpin; /* 0x84 */ + u32 hi_hci_uart_baud; /* 0x88 */ + u32 hi_hci_uart_pin_assignments; /* 0x8C */ /* NOTE: byte [0] = tx pin, [1] = rx pin, [2] = rts pin, [3] = cts pin */ - A_UINT32 hi_hci_uart_baud_scale_val; /* 0x90 */ - A_UINT32 hi_hci_uart_baud_step_val; /* 0x94 */ + u32 hi_hci_uart_baud_scale_val; /* 0x90 */ + u32 hi_hci_uart_baud_step_val; /* 0x94 */ - A_UINT32 hi_allocram_start; /* 0x98 */ - A_UINT32 hi_allocram_sz; /* 0x9c */ - A_UINT32 hi_hci_bridge_flags; /* 0xa0 */ - A_UINT32 hi_hci_uart_support_pins; /* 0xa4 */ + u32 hi_allocram_start; /* 0x98 */ + u32 hi_allocram_sz; /* 0x9c */ + u32 hi_hci_bridge_flags; /* 0xa0 */ + u32 hi_hci_uart_support_pins; /* 0xa4 */ /* NOTE: byte [0] = RESET pin (bit 7 is polarity), bytes[1]..bytes[3] are for future use */ - A_UINT32 hi_hci_uart_pwr_mgmt_params; /* 0xa8 */ + u32 hi_hci_uart_pwr_mgmt_params; /* 0xa8 */ /* 0xa8 - [0]: 1 = enable, 0 = disable * [1]: 0 = UART FC active low, 1 = UART FC active high * 0xa9 - [7:0]: wakeup timeout in ms * 0xaa, 0xab - [15:0]: idle timeout in ms */ /* Pointer to extended board Data */ - A_UINT32 hi_board_ext_data; /* 0xac */ - A_UINT32 hi_board_ext_data_initialized; /* 0xb0 */ + u32 hi_board_ext_data; /* 0xac */ + u32 hi_board_ext_data_initialized; /* 0xb0 */ } POSTPACK; /* Bits defined in hi_option_flag */ @@ -207,10 +207,10 @@ PREPACK struct host_interest_s { * Example: target_addr = AR6002_HOST_INTEREST_ITEM_ADDRESS(hi_board_data); */ #define AR6002_HOST_INTEREST_ITEM_ADDRESS(item) \ - (A_UINT32)((unsigned long)&((((struct host_interest_s *)(AR6002_HOST_INTEREST_ADDRESS))->item))) + (u32)((unsigned long)&((((struct host_interest_s *)(AR6002_HOST_INTEREST_ADDRESS))->item))) #define AR6003_HOST_INTEREST_ITEM_ADDRESS(item) \ - (A_UINT32)((unsigned long)&((((struct host_interest_s *)(AR6003_HOST_INTEREST_ADDRESS))->item))) + (u32)((unsigned long)&((((struct host_interest_s *)(AR6003_HOST_INTEREST_ADDRESS))->item))) #define HOST_INTEREST_DBGLOG_IS_ENABLED() \ (!(HOST_INTEREST->hi_option_flag & HI_OPTION_DISABLE_DBGLOG)) @@ -233,7 +233,7 @@ PREPACK struct host_interest_s { #define AR6003_BOARD_EXT_DATA_ADDRESS 0x57E600 -/* # of A_UINT32 entries in targregs, used by DIAG_FETCH_TARG_REGS */ +/* # of u32 entries in targregs, used by DIAG_FETCH_TARG_REGS */ #define AR6003_FETCH_TARG_REGS_COUNT 64 #endif /* !__ASSEMBLER__ */ diff --git a/drivers/staging/ath6kl/include/common/testcmd.h b/drivers/staging/ath6kl/include/common/testcmd.h index 4138c1d13d15..49861e2058f0 100644 --- a/drivers/staging/ath6kl/include/common/testcmd.h +++ b/drivers/staging/ath6kl/include/common/testcmd.h @@ -82,20 +82,20 @@ typedef enum { } TCMD_WLAN_MODE; typedef PREPACK struct { - A_UINT32 testCmdId; - A_UINT32 mode; - A_UINT32 freq; - A_UINT32 dataRate; + u32 testCmdId; + u32 mode; + u32 freq; + u32 dataRate; A_INT32 txPwr; - A_UINT32 antenna; - A_UINT32 enANI; - A_UINT32 scramblerOff; - A_UINT32 aifsn; + u32 antenna; + u32 enANI; + u32 scramblerOff; + u32 aifsn; u16 pktSz; u16 txPattern; - A_UINT32 shortGuard; - A_UINT32 numPackets; - A_UINT32 wlanMode; + u32 shortGuard; + u32 numPackets; + u32 wlanMode; } POSTPACK TCMD_CONT_TX; #define TCMD_TXPATTERN_ZERONE 0x1 @@ -124,20 +124,20 @@ typedef enum { } TCMD_CONT_RX_ACT; typedef PREPACK struct { - A_UINT32 testCmdId; - A_UINT32 act; - A_UINT32 enANI; + u32 testCmdId; + u32 act; + u32 enANI; PREPACK union { struct PREPACK TCMD_CONT_RX_PARA { - A_UINT32 freq; - A_UINT32 antenna; - A_UINT32 wlanMode; + u32 freq; + u32 antenna; + u32 wlanMode; } POSTPACK para; struct PREPACK TCMD_CONT_RX_REPORT { - A_UINT32 totalPkt; + u32 totalPkt; A_INT32 rssiInDBm; - A_UINT32 crcErrPkt; - A_UINT32 secErrPkt; + u32 crcErrPkt; + u32 secErrPkt; u16 rateCnt[TCMD_MAX_RATES]; u16 rateCntShortGuard[TCMD_MAX_RATES]; } POSTPACK report; @@ -145,8 +145,8 @@ typedef PREPACK struct { A_UCHAR addr[ATH_MAC_LEN]; } POSTPACK mac; struct PREPACK TCMD_CONT_RX_ANT_SWITCH_TABLE { - A_UINT32 antswitch1; - A_UINT32 antswitch2; + u32 antswitch1; + u32 antswitch2; }POSTPACK antswitchtable; } POSTPACK u; } POSTPACK TCMD_CONT_RX; @@ -162,8 +162,8 @@ typedef enum { } TCMD_PM_MODE; typedef PREPACK struct { - A_UINT32 testCmdId; - A_UINT32 mode; + u32 testCmdId; + u32 mode; } POSTPACK TCMD_PM; typedef enum { diff --git a/drivers/staging/ath6kl/include/common/wmi.h b/drivers/staging/ath6kl/include/common/wmi.h index d4f8d404b6ee..1f90975aac66 100644 --- a/drivers/staging/ath6kl/include/common/wmi.h +++ b/drivers/staging/ath6kl/include/common/wmi.h @@ -70,7 +70,7 @@ extern "C" { #endif PREPACK struct host_app_area_s { - A_UINT32 wmi_protocol_ver; + u32 wmi_protocol_ver; } POSTPACK; /* @@ -533,7 +533,7 @@ typedef PREPACK struct { A_UCHAR ssid[WMI_MAX_SSID_LEN]; u16 channel; u8 bssid[ATH_MAC_LEN]; - A_UINT32 ctrl_flags; + u32 ctrl_flags; } POSTPACK WMI_CONNECT_CMD; /* @@ -637,8 +637,8 @@ typedef enum { typedef PREPACK struct { u32 forceFgScan; u32 isLegacy; /* For Legacy Cisco AP compatibility */ - A_UINT32 homeDwellTime; /* Maximum duration in the home channel(milliseconds) */ - A_UINT32 forceScanInterval; /* Time interval between scans (milliseconds)*/ + u32 homeDwellTime; /* Maximum duration in the home channel(milliseconds) */ + u32 forceScanInterval; /* Time interval between scans (milliseconds)*/ u8 scanType; /* WMI_SCAN_TYPE */ u8 numChannels; /* how many channels follow */ u16 channelList[1]; /* channels in Mhz */ @@ -685,7 +685,7 @@ typedef PREPACK struct { u8 scanCtrlFlags; u16 minact_chdwell_time; /* msec */ u16 maxact_scan_per_ssid; /* max active scans per ssid */ - A_UINT32 max_dfsch_act_time; /* msecs */ + u32 max_dfsch_act_time; /* msecs */ } POSTPACK WMI_SCAN_PARAMS_CMD; /* @@ -706,7 +706,7 @@ typedef PREPACK struct { u8 bssFilter; /* see WMI_BSS_FILTER */ u8 reserved1; /* For alignment */ u16 reserved2; /* For alignment */ - A_UINT32 ieMask; + u32 ieMask; } POSTPACK WMI_BSS_FILTER_CMD; /* @@ -780,8 +780,8 @@ typedef PREPACK struct { } POSTPACK WMI_SET_PARAMS_REPLY; typedef PREPACK struct { - A_UINT32 opcode; - A_UINT32 length; + u32 opcode; + u32 length; char buffer[1]; /* WMI_SET_PARAMS */ } POSTPACK WMI_SET_PARAMS_CMD; @@ -849,8 +849,8 @@ typedef enum { } WMI_AP_PS_TYPE; typedef PREPACK struct { - A_UINT32 idle_time; /* in msec */ - A_UINT32 ps_period; /* in usec */ + u32 idle_time; /* in msec */ + u32 ps_period; /* in usec */ u8 sleep_period; /* in ps periods */ u8 psType; } POSTPACK WMI_AP_PS_CMD; @@ -868,8 +868,8 @@ typedef enum { typedef PREPACK struct { u16 psPollTimeout; /* msec */ u16 triggerTimeout; /* msec */ - A_UINT32 apsdTimPolicy; /* TIM behavior with ques APSD enabled. Default is IGNORE_TIM_ALL_QUEUES_APSD */ - A_UINT32 simulatedAPSDTimPolicy; /* TIM behavior with simulated APSD enabled. Default is PROCESS_TIM_SIMULATED_APSD */ + u32 apsdTimPolicy; /* TIM behavior with ques APSD enabled. Default is IGNORE_TIM_ALL_QUEUES_APSD */ + u32 simulatedAPSDTimPolicy; /* TIM behavior with simulated APSD enabled. Default is PROCESS_TIM_SIMULATED_APSD */ } POSTPACK WMI_POWERSAVE_TIMERS_POLICY_CMD; /* @@ -928,19 +928,19 @@ typedef PREPACK struct { * WMI_CREATE_PSTREAM_CMDID */ typedef PREPACK struct { - A_UINT32 minServiceInt; /* in milli-sec */ - A_UINT32 maxServiceInt; /* in milli-sec */ - A_UINT32 inactivityInt; /* in milli-sec */ - A_UINT32 suspensionInt; /* in milli-sec */ - A_UINT32 serviceStartTime; - A_UINT32 minDataRate; /* in bps */ - A_UINT32 meanDataRate; /* in bps */ - A_UINT32 peakDataRate; /* in bps */ - A_UINT32 maxBurstSize; - A_UINT32 delayBound; - A_UINT32 minPhyRate; /* in bps */ - A_UINT32 sba; - A_UINT32 mediumTime; + u32 minServiceInt; /* in milli-sec */ + u32 maxServiceInt; /* in milli-sec */ + u32 inactivityInt; /* in milli-sec */ + u32 suspensionInt; /* in milli-sec */ + u32 serviceStartTime; + u32 minDataRate; /* in bps */ + u32 meanDataRate; /* in bps */ + u32 peakDataRate; /* in bps */ + u32 maxBurstSize; + u32 delayBound; + u32 minPhyRate; /* in bps */ + u32 sba; + u32 mediumTime; u16 nominalMSDU; /* in octects */ u16 maxMSDU; /* in octects */ u8 trafficClass; @@ -995,7 +995,7 @@ typedef PREPACK struct { */ typedef PREPACK struct WMI_RSSI_THRESHOLD_PARAMS{ - A_UINT32 pollTime; /* Polling time as a factor of LI */ + u32 pollTime; /* Polling time as a factor of LI */ A_INT16 thresholdAbove1_Val; /* lowest of upper */ A_INT16 thresholdAbove2_Val; A_INT16 thresholdAbove3_Val; @@ -1018,7 +1018,7 @@ typedef PREPACK struct WMI_RSSI_THRESHOLD_PARAMS{ */ typedef PREPACK struct WMI_SNR_THRESHOLD_PARAMS{ - A_UINT32 pollTime; /* Polling time as a factor of LI */ + u32 pollTime; /* Polling time as a factor of LI */ u8 weight; /* "alpha" */ u8 thresholdAbove1_Val; /* lowest of uppper*/ u8 thresholdAbove2_Val; @@ -1073,7 +1073,7 @@ typedef PREPACK struct { * via event, unless the bitmask is set again. */ typedef PREPACK struct { - A_UINT32 bitmask; + u32 bitmask; } POSTPACK WMI_TARGET_ERROR_REPORT_BITMASK; /* @@ -1252,7 +1252,7 @@ typedef PREPACK struct { } POSTPACK WMI_SET_MAX_OFFHOME_DURATION_CMD; typedef PREPACK struct { - A_UINT32 frequency; + u32 frequency; u8 threshold; } POSTPACK WMI_SET_HB_CHALLENGE_RESP_PARAMS_CMD; /*---------------------- BTCOEX RELATED -------------------------------------*/ @@ -1329,13 +1329,13 @@ typedef enum { #define BT_SCO_SET_MAX_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 16) typedef PREPACK struct { - A_UINT32 numScoCyclesForceTrigger; /* Number SCO cycles after which + u32 numScoCyclesForceTrigger; /* Number SCO cycles after which force a pspoll. default = 10 */ - A_UINT32 dataResponseTimeout; /* Timeout Waiting for Downlink pkt + u32 dataResponseTimeout; /* Timeout Waiting for Downlink pkt in response for ps-poll, default = 10 msecs */ - A_UINT32 stompScoRules; - A_UINT32 scoOptFlags; /* SCO Options Flags : + u32 stompScoRules; + u32 scoOptFlags; /* SCO Options Flags : bits: meaning: 0 Allow Close Range Optimization 1 Force awake during close range @@ -1377,13 +1377,13 @@ typedef PREPACK struct { #define BT_A2DP_SET_MAX_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 16) typedef PREPACK struct { - A_UINT32 a2dpWlanUsageLimit; /* MAX time firmware uses the medium for + u32 a2dpWlanUsageLimit; /* MAX time firmware uses the medium for wlan, after it identifies the idle time default (30 msecs) */ - A_UINT32 a2dpBurstCntMin; /* Minimum number of bluetooth data frames + u32 a2dpBurstCntMin; /* Minimum number of bluetooth data frames to replenish Wlan Usage limit (default 3) */ - A_UINT32 a2dpDataRespTimeout; - A_UINT32 a2dpOptFlags; /* A2DP Option flags: + u32 a2dpDataRespTimeout; + u32 a2dpOptFlags; /* A2DP Option flags: bits: meaning: 0 Allow Close Range Optimization 1 Force awake during close range @@ -1402,14 +1402,14 @@ typedef PREPACK struct { /* During BT ftp/ BT OPP or any another data based acl profile on bluetooth (non a2dp).*/ typedef PREPACK struct { - A_UINT32 aclWlanMediumUsageTime; /* Wlan usage time during Acl (non-a2dp) + u32 aclWlanMediumUsageTime; /* Wlan usage time during Acl (non-a2dp) coexistence (default 30 msecs) */ - A_UINT32 aclBtMediumUsageTime; /* Bt usage time during acl coexistence + u32 aclBtMediumUsageTime; /* Bt usage time during acl coexistence (default 30 msecs)*/ - A_UINT32 aclDataRespTimeout; - A_UINT32 aclDetectTimeout; /* ACL coexistence enabled if we get + u32 aclDataRespTimeout; + u32 aclDetectTimeout; /* ACL coexistence enabled if we get 10 Pkts in X msec(default 100 msecs) */ - A_UINT32 aclmaxPktCnt; /* No of ACL pkts to receive before + u32 aclmaxPktCnt; /* No of ACL pkts to receive before enabling ACL coex */ }POSTPACK BT_PARAMS_ACLCOEX; @@ -1478,20 +1478,20 @@ typedef PREPACK struct { * During this the station will be power-save mode. */ typedef PREPACK struct { - A_UINT32 btInquiryDataFetchFrequency;/* The frequency of querying the AP for data + u32 btInquiryDataFetchFrequency;/* The frequency of querying the AP for data (via pspoll) is configured by this parameter. "default = 10 ms" */ - A_UINT32 protectBmissDurPostBtInquiry;/* The firmware will continue to be in inquiry state + u32 protectBmissDurPostBtInquiry;/* The firmware will continue to be in inquiry state for configured duration, after inquiry completion . This is to ensure other bluetooth transactions (RDP, SDP profiles, link key exchange ...etc) goes through smoothly without wifi stomping. default = 10 secs*/ - A_UINT32 maxpageStomp; /*Applicable only for STE-BT interface. Currently not + u32 maxpageStomp; /*Applicable only for STE-BT interface. Currently not used */ - A_UINT32 btInquiryPageFlag; /* Not used */ + u32 btInquiryPageFlag; /* Not used */ }POSTPACK WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD; /*---------------------WMI_SET_BTCOEX_SCO_CONFIG_CMDID ---------------*/ @@ -1509,14 +1509,14 @@ typedef PREPACK struct { #define WMI_SCO_CONFIG_FLAG_IS_BT_MASTER (1 << 2) #define WMI_SCO_CONFIG_FLAG_FW_DETECT_OF_PER (1 << 3) typedef PREPACK struct { - A_UINT32 scoSlots; /* Number of SCO Tx/Rx slots. + u32 scoSlots; /* Number of SCO Tx/Rx slots. HVx, EV3, 2EV3 = 2 */ - A_UINT32 scoIdleSlots; /* Number of Bluetooth idle slots between + u32 scoIdleSlots; /* Number of Bluetooth idle slots between consecutive SCO Tx/Rx slots HVx, EV3 = 4 2EV3 = 10 */ - A_UINT32 scoFlags; /* SCO Options Flags : + u32 scoFlags; /* SCO Options Flags : bits: meaning: 0 Allow Close Range Optimization 1 Is EDR capable or Not @@ -1524,21 +1524,21 @@ typedef PREPACK struct { 3 Firmware determines the periodicity of SCO. */ - A_UINT32 linkId; /* applicable to STE-BT - not used */ + u32 linkId; /* applicable to STE-BT - not used */ }POSTPACK BTCOEX_SCO_CONFIG; typedef PREPACK struct { - A_UINT32 scoCyclesForceTrigger; /* Number SCO cycles after which + u32 scoCyclesForceTrigger; /* Number SCO cycles after which force a pspoll. default = 10 */ - A_UINT32 scoDataResponseTimeout; /* Timeout Waiting for Downlink pkt + u32 scoDataResponseTimeout; /* Timeout Waiting for Downlink pkt in response for ps-poll, default = 20 msecs */ - A_UINT32 scoStompDutyCyleVal; /* not implemented */ + u32 scoStompDutyCyleVal; /* not implemented */ - A_UINT32 scoStompDutyCyleMaxVal; /*Not implemented */ + u32 scoStompDutyCyleMaxVal; /*Not implemented */ - A_UINT32 scoPsPollLatencyFraction; /* Fraction of idle + u32 scoPsPollLatencyFraction; /* Fraction of idle period, within which additional ps-polls can be queued 1 - 1/4 of idle duration @@ -1549,29 +1549,29 @@ typedef PREPACK struct { }POSTPACK BTCOEX_PSPOLLMODE_SCO_CONFIG; typedef PREPACK struct { - A_UINT32 scoStompCntIn100ms;/*max number of SCO stomp in 100ms allowed in + u32 scoStompCntIn100ms;/*max number of SCO stomp in 100ms allowed in opt mode. If exceeds the configured value, switch to ps-poll mode default = 3 */ - A_UINT32 scoContStompMax; /* max number of continous stomp allowed in opt mode. + u32 scoContStompMax; /* max number of continous stomp allowed in opt mode. if excedded switch to pspoll mode default = 3 */ - A_UINT32 scoMinlowRateMbps; /* Low rate threshold */ + u32 scoMinlowRateMbps; /* Low rate threshold */ - A_UINT32 scoLowRateCnt; /* number of low rate pkts (< scoMinlowRateMbps) allowed in 100 ms. + u32 scoLowRateCnt; /* number of low rate pkts (< scoMinlowRateMbps) allowed in 100 ms. If exceeded switch/stay to ps-poll mode, lower stay in opt mode. default = 36 */ - A_UINT32 scoHighPktRatio; /*(Total Rx pkts in 100 ms + 1)/ + u32 scoHighPktRatio; /*(Total Rx pkts in 100 ms + 1)/ ((Total tx pkts in 100 ms - No of high rate pkts in 100 ms) + 1) in 100 ms, if exceeded switch/stay in opt mode and if lower switch/stay in pspoll mode. default = 5 (80% of high rates) */ - A_UINT32 scoMaxAggrSize; /* Max number of Rx subframes allowed in this mode. (Firmware re-negogiates + u32 scoMaxAggrSize; /* Max number of Rx subframes allowed in this mode. (Firmware re-negogiates max number of aggregates if it was negogiated to higher value default = 1 Recommended value Basic rate headsets = 1, EDR (2-EV3) =4. @@ -1579,8 +1579,8 @@ typedef PREPACK struct { }POSTPACK BTCOEX_OPTMODE_SCO_CONFIG; typedef PREPACK struct { - A_UINT32 scanInterval; - A_UINT32 maxScanStompCnt; + u32 scanInterval; + u32 maxScanStompCnt; }POSTPACK BTCOEX_WLANSCAN_SCO_CONFIG; typedef PREPACK struct { @@ -1608,7 +1608,7 @@ typedef PREPACK struct { #define WMI_A2DP_CONFIG_FLAG_FIND_BT_ROLE (1 << 4) typedef PREPACK struct { - A_UINT32 a2dpFlags; /* A2DP Option flags: + u32 a2dpFlags; /* A2DP Option flags: bits: meaning: 0 Allow Close Range Optimization 1 IS EDR capable @@ -1616,19 +1616,19 @@ typedef PREPACK struct { 3 a2dp traffic is high priority 4 Fw detect the role of bluetooth. */ - A_UINT32 linkId; /* Applicable only to STE-BT - not used */ + u32 linkId; /* Applicable only to STE-BT - not used */ }POSTPACK BTCOEX_A2DP_CONFIG; typedef PREPACK struct { - A_UINT32 a2dpWlanMaxDur; /* MAX time firmware uses the medium for + u32 a2dpWlanMaxDur; /* MAX time firmware uses the medium for wlan, after it identifies the idle time default (30 msecs) */ - A_UINT32 a2dpMinBurstCnt; /* Minimum number of bluetooth data frames + u32 a2dpMinBurstCnt; /* Minimum number of bluetooth data frames to replenish Wlan Usage limit (default 3) */ - A_UINT32 a2dpDataRespTimeout; /* Max duration firmware waits for downlink + u32 a2dpDataRespTimeout; /* Max duration firmware waits for downlink by stomping on bluetooth after ps-poll is acknowledged. default = 20 ms @@ -1636,25 +1636,25 @@ typedef PREPACK struct { }POSTPACK BTCOEX_PSPOLLMODE_A2DP_CONFIG; typedef PREPACK struct { - A_UINT32 a2dpMinlowRateMbps; /* Low rate threshold */ + u32 a2dpMinlowRateMbps; /* Low rate threshold */ - A_UINT32 a2dpLowRateCnt; /* number of low rate pkts (< a2dpMinlowRateMbps) allowed in 100 ms. + u32 a2dpLowRateCnt; /* number of low rate pkts (< a2dpMinlowRateMbps) allowed in 100 ms. If exceeded switch/stay to ps-poll mode, lower stay in opt mode. default = 36 */ - A_UINT32 a2dpHighPktRatio; /*(Total Rx pkts in 100 ms + 1)/ + u32 a2dpHighPktRatio; /*(Total Rx pkts in 100 ms + 1)/ ((Total tx pkts in 100 ms - No of high rate pkts in 100 ms) + 1) in 100 ms, if exceeded switch/stay in opt mode and if lower switch/stay in pspoll mode. default = 5 (80% of high rates) */ - A_UINT32 a2dpMaxAggrSize; /* Max number of Rx subframes allowed in this mode. (Firmware re-negogiates + u32 a2dpMaxAggrSize; /* Max number of Rx subframes allowed in this mode. (Firmware re-negogiates max number of aggregates if it was negogiated to higher value default = 1 Recommended value Basic rate headsets = 1, EDR (2-EV3) =8. */ - A_UINT32 a2dpPktStompCnt; /*number of a2dp pkts that can be stomped per burst. + u32 a2dpPktStompCnt; /*number of a2dp pkts that can be stomped per burst. default = 6*/ }POSTPACK BTCOEX_OPTMODE_A2DP_CONFIG; @@ -1683,15 +1683,15 @@ typedef PREPACK struct { #define WMI_ACLCOEX_FLAGS_DISABLE_FW_DETECTION (1 << 1) typedef PREPACK struct { - A_UINT32 aclWlanMediumDur; /* Wlan usage time during Acl (non-a2dp) + u32 aclWlanMediumDur; /* Wlan usage time during Acl (non-a2dp) coexistence (default 30 msecs) */ - A_UINT32 aclBtMediumDur; /* Bt usage time during acl coexistence + u32 aclBtMediumDur; /* Bt usage time during acl coexistence (default 30 msecs) */ - A_UINT32 aclDetectTimeout; /* BT activity observation time limit. + u32 aclDetectTimeout; /* BT activity observation time limit. In this time duration, number of bt pkts are counted. If the Cnt reaches "aclPktCntLowerLimit" value for "aclIterToEnableCoex" iteration continuously, @@ -1703,7 +1703,7 @@ typedef PREPACK struct { -default 100 msecs */ - A_UINT32 aclPktCntLowerLimit; /* Acl Pkt Cnt to be received in duration of + u32 aclPktCntLowerLimit; /* Acl Pkt Cnt to be received in duration of "aclDetectTimeout" for "aclIterForEnDis" times to enabling ACL coex. Similar logic is used to disable acl coexistence. @@ -1713,28 +1713,28 @@ typedef PREPACK struct { default = 10 */ - A_UINT32 aclIterForEnDis; /* number of Iteration of "aclPktCntLowerLimit" for Enabling and + u32 aclIterForEnDis; /* number of Iteration of "aclPktCntLowerLimit" for Enabling and Disabling Acl Coexistence. default = 3 */ - A_UINT32 aclPktCntUpperLimit; /* This is upperBound limit, if there is more than + u32 aclPktCntUpperLimit; /* This is upperBound limit, if there is more than "aclPktCntUpperLimit" seen in "aclDetectTimeout", ACL coexistence is enabled right away. - default 15*/ - A_UINT32 aclCoexFlags; /* A2DP Option flags: + u32 aclCoexFlags; /* A2DP Option flags: bits: meaning: 0 Allow Close Range Optimization 1 disable Firmware detection (Currently supported configuration is aclCoexFlags =0) */ - A_UINT32 linkId; /* Applicable only for STE-BT - not used */ + u32 linkId; /* Applicable only for STE-BT - not used */ }POSTPACK BTCOEX_ACLCOEX_CONFIG; typedef PREPACK struct { - A_UINT32 aclDataRespTimeout; /* Max duration firmware waits for downlink + u32 aclDataRespTimeout; /* Max duration firmware waits for downlink by stomping on bluetooth after ps-poll is acknowledged. default = 20 ms */ @@ -1744,11 +1744,11 @@ typedef PREPACK struct { /* Not implemented yet*/ typedef PREPACK struct { - A_UINT32 aclCoexMinlowRateMbps; - A_UINT32 aclCoexLowRateCnt; - A_UINT32 aclCoexHighPktRatio; - A_UINT32 aclCoexMaxAggrSize; - A_UINT32 aclPktStompCnt; + u32 aclCoexMinlowRateMbps; + u32 aclCoexLowRateCnt; + u32 aclCoexHighPktRatio; + u32 aclCoexMaxAggrSize; + u32 aclPktStompCnt; }POSTPACK BTCOEX_OPTMODE_ACLCOEX_CONFIG; typedef PREPACK struct { @@ -1766,39 +1766,39 @@ typedef enum { }WMI_BTCOEX_BT_PROFILE; typedef PREPACK struct { - A_UINT32 btProfileType; - A_UINT32 btOperatingStatus; - A_UINT32 btLinkId; + u32 btProfileType; + u32 btOperatingStatus; + u32 btLinkId; }WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD; /*--------------------- WMI_SET_BTCOEX_DEBUG_CMDID ---------------------*/ /* Used for firmware development and debugging */ typedef PREPACK struct { - A_UINT32 btcoexDbgParam1; - A_UINT32 btcoexDbgParam2; - A_UINT32 btcoexDbgParam3; - A_UINT32 btcoexDbgParam4; - A_UINT32 btcoexDbgParam5; + u32 btcoexDbgParam1; + u32 btcoexDbgParam2; + u32 btcoexDbgParam3; + u32 btcoexDbgParam4; + u32 btcoexDbgParam5; }WMI_SET_BTCOEX_DEBUG_CMD; /*---------------------WMI_GET_BTCOEX_CONFIG_CMDID --------------------- */ /* Command to firmware to get configuration parameters of the bt profile * reported via WMI_BTCOEX_CONFIG_EVENTID */ typedef PREPACK struct { - A_UINT32 btProfileType; /* 1 - SCO + u32 btProfileType; /* 1 - SCO 2 - A2DP 3 - INQUIRY_PAGE 4 - ACLCOEX */ - A_UINT32 linkId; /* not used */ + u32 linkId; /* not used */ }WMI_GET_BTCOEX_CONFIG_CMD; /*------------------WMI_REPORT_BTCOEX_CONFIG_EVENTID------------------- */ /* Event from firmware to host, sent in response to WMI_GET_BTCOEX_CONFIG_CMDID * */ typedef PREPACK struct { - A_UINT32 btProfileType; - A_UINT32 linkId; /* not used */ + u32 btProfileType; + u32 linkId; /* not used */ PREPACK union { WMI_SET_BTCOEX_SCO_CONFIG_CMD scoConfigCmd; WMI_SET_BTCOEX_A2DP_CONFIG_CMD a2dpConfigCmd; @@ -1810,32 +1810,32 @@ typedef PREPACK struct { /*------------- WMI_REPORT_BTCOEX_BTCOEX_STATS_EVENTID--------------------*/ /* Used for firmware development and debugging*/ typedef PREPACK struct { - A_UINT32 highRatePktCnt; - A_UINT32 firstBmissCnt; - A_UINT32 psPollFailureCnt; - A_UINT32 nullFrameFailureCnt; - A_UINT32 optModeTransitionCnt; + u32 highRatePktCnt; + u32 firstBmissCnt; + u32 psPollFailureCnt; + u32 nullFrameFailureCnt; + u32 optModeTransitionCnt; }BTCOEX_GENERAL_STATS; typedef PREPACK struct { - A_UINT32 scoStompCntAvg; - A_UINT32 scoStompIn100ms; - A_UINT32 scoMaxContStomp; - A_UINT32 scoAvgNoRetries; - A_UINT32 scoMaxNoRetriesIn100ms; + u32 scoStompCntAvg; + u32 scoStompIn100ms; + u32 scoMaxContStomp; + u32 scoAvgNoRetries; + u32 scoMaxNoRetriesIn100ms; }BTCOEX_SCO_STATS; typedef PREPACK struct { - A_UINT32 a2dpBurstCnt; - A_UINT32 a2dpMaxBurstCnt; - A_UINT32 a2dpAvgIdletimeIn100ms; - A_UINT32 a2dpAvgStompCnt; + u32 a2dpBurstCnt; + u32 a2dpMaxBurstCnt; + u32 a2dpAvgIdletimeIn100ms; + u32 a2dpAvgStompCnt; }BTCOEX_A2DP_STATS; typedef PREPACK struct { - A_UINT32 aclPktCntInBtTime; - A_UINT32 aclStompCntInWlanTime; - A_UINT32 aclPktCntIn100ms; + u32 aclPktCntInBtTime; + u32 aclStompCntInWlanTime; + u32 aclPktCntIn100ms; }BTCOEX_ACLCOEX_STATS; typedef PREPACK struct { @@ -1848,7 +1848,7 @@ typedef PREPACK struct { /*--------------------------END OF BTCOEX -------------------------------------*/ typedef PREPACK struct { - A_UINT32 sleepState; + u32 sleepState; }WMI_REPORT_SLEEP_STATE_EVENT; typedef enum { @@ -1861,7 +1861,7 @@ typedef enum { } TARGET_EVENT_REPORT_CONFIG; typedef PREPACK struct { - A_UINT32 evtConfig; + u32 evtConfig; } POSTPACK WMI_SET_TARGET_EVENT_REPORT_CMD; @@ -1981,8 +1981,8 @@ typedef PREPACK struct { } POSTPACK WMI_READY_EVENT_1; typedef PREPACK struct { - A_UINT32 sw_version; - A_UINT32 abi_version; + u32 sw_version; + u32 abi_version; u8 macaddr[ATH_MAC_LEN]; u8 phyCapability; /* WMI_PHY_CAPABILITY */ } POSTPACK WMI_READY_EVENT_2; @@ -2006,7 +2006,7 @@ typedef PREPACK struct { u8 bssid[ATH_MAC_LEN]; u16 listenInterval; u16 beaconInterval; - A_UINT32 networkType; + u32 networkType; u8 beaconIeLen; u8 assocReqLen; u8 assocRespLen; @@ -2064,7 +2064,7 @@ typedef PREPACK struct { u8 snr; A_INT16 rssi; u8 bssid[ATH_MAC_LEN]; - A_UINT32 ieMask; + u32 ieMask; } POSTPACK WMI_BSS_INFO_HDR; /* @@ -2101,7 +2101,7 @@ typedef PREPACK struct { * New Regulatory Domain Event */ typedef PREPACK struct { - A_UINT32 regDomain; + u32 regDomain; } POSTPACK WMI_REG_DOMAIN_EVENT; typedef PREPACK struct { @@ -2216,56 +2216,56 @@ typedef PREPACK struct { * Reporting statistics. */ typedef PREPACK struct { - A_UINT32 tx_packets; - A_UINT32 tx_bytes; - A_UINT32 tx_unicast_pkts; - A_UINT32 tx_unicast_bytes; - A_UINT32 tx_multicast_pkts; - A_UINT32 tx_multicast_bytes; - A_UINT32 tx_broadcast_pkts; - A_UINT32 tx_broadcast_bytes; - A_UINT32 tx_rts_success_cnt; - A_UINT32 tx_packet_per_ac[4]; - A_UINT32 tx_errors_per_ac[4]; - - A_UINT32 tx_errors; - A_UINT32 tx_failed_cnt; - A_UINT32 tx_retry_cnt; - A_UINT32 tx_mult_retry_cnt; - A_UINT32 tx_rts_fail_cnt; + u32 tx_packets; + u32 tx_bytes; + u32 tx_unicast_pkts; + u32 tx_unicast_bytes; + u32 tx_multicast_pkts; + u32 tx_multicast_bytes; + u32 tx_broadcast_pkts; + u32 tx_broadcast_bytes; + u32 tx_rts_success_cnt; + u32 tx_packet_per_ac[4]; + u32 tx_errors_per_ac[4]; + + u32 tx_errors; + u32 tx_failed_cnt; + u32 tx_retry_cnt; + u32 tx_mult_retry_cnt; + u32 tx_rts_fail_cnt; A_INT32 tx_unicast_rate; }POSTPACK tx_stats_t; typedef PREPACK struct { - A_UINT32 rx_packets; - A_UINT32 rx_bytes; - A_UINT32 rx_unicast_pkts; - A_UINT32 rx_unicast_bytes; - A_UINT32 rx_multicast_pkts; - A_UINT32 rx_multicast_bytes; - A_UINT32 rx_broadcast_pkts; - A_UINT32 rx_broadcast_bytes; - A_UINT32 rx_fragment_pkt; - - A_UINT32 rx_errors; - A_UINT32 rx_crcerr; - A_UINT32 rx_key_cache_miss; - A_UINT32 rx_decrypt_err; - A_UINT32 rx_duplicate_frames; + u32 rx_packets; + u32 rx_bytes; + u32 rx_unicast_pkts; + u32 rx_unicast_bytes; + u32 rx_multicast_pkts; + u32 rx_multicast_bytes; + u32 rx_broadcast_pkts; + u32 rx_broadcast_bytes; + u32 rx_fragment_pkt; + + u32 rx_errors; + u32 rx_crcerr; + u32 rx_key_cache_miss; + u32 rx_decrypt_err; + u32 rx_duplicate_frames; A_INT32 rx_unicast_rate; }POSTPACK rx_stats_t; typedef PREPACK struct { - A_UINT32 tkip_local_mic_failure; - A_UINT32 tkip_counter_measures_invoked; - A_UINT32 tkip_replays; - A_UINT32 tkip_format_errors; - A_UINT32 ccmp_format_errors; - A_UINT32 ccmp_replays; + u32 tkip_local_mic_failure; + u32 tkip_counter_measures_invoked; + u32 tkip_replays; + u32 tkip_format_errors; + u32 ccmp_format_errors; + u32 ccmp_replays; }POSTPACK tkip_ccmp_stats_t; typedef PREPACK struct { - A_UINT32 power_save_failure_cnt; + u32 power_save_failure_cnt; u16 stop_tx_failure_cnt; u16 atim_tx_failure_cnt; u16 atim_rx_failure_cnt; @@ -2273,8 +2273,8 @@ typedef PREPACK struct { }POSTPACK pm_stats_t; typedef PREPACK struct { - A_UINT32 cs_bmiss_cnt; - A_UINT32 cs_lowRssi_cnt; + u32 cs_bmiss_cnt; + u32 cs_lowRssi_cnt; u16 cs_connect_cnt; u16 cs_disconnect_cnt; A_INT16 cs_aveBeacon_rssi; @@ -2292,20 +2292,20 @@ typedef PREPACK struct { }POSTPACK wlan_net_stats_t; typedef PREPACK struct { - A_UINT32 arp_received; - A_UINT32 arp_matched; - A_UINT32 arp_replied; + u32 arp_received; + u32 arp_matched; + u32 arp_replied; } POSTPACK arp_stats_t; typedef PREPACK struct { - A_UINT32 wow_num_pkts_dropped; + u32 wow_num_pkts_dropped; u16 wow_num_events_discarded; u8 wow_num_host_pkt_wakeups; u8 wow_num_host_event_wakeups; } POSTPACK wlan_wow_stats_t; typedef PREPACK struct { - A_UINT32 lqVal; + u32 lqVal; A_INT32 noise_floor_calibation; pm_stats_t pmStats; wlan_net_stats_t txrxStats; @@ -2353,7 +2353,7 @@ typedef enum{ } WMI_TARGET_ERROR_VAL; typedef PREPACK struct { - A_UINT32 errorVal; + u32 errorVal; }POSTPACK WMI_TARGET_ERROR_REPORT_EVENT; typedef PREPACK struct { @@ -2522,43 +2522,43 @@ typedef PREPACK struct { * * Get fix rates cmd uses same definition as set fix rates cmd */ -#define FIX_RATE_1Mb ((A_UINT32)0x1) -#define FIX_RATE_2Mb ((A_UINT32)0x2) -#define FIX_RATE_5_5Mb ((A_UINT32)0x4) -#define FIX_RATE_11Mb ((A_UINT32)0x8) -#define FIX_RATE_6Mb ((A_UINT32)0x10) -#define FIX_RATE_9Mb ((A_UINT32)0x20) -#define FIX_RATE_12Mb ((A_UINT32)0x40) -#define FIX_RATE_18Mb ((A_UINT32)0x80) -#define FIX_RATE_24Mb ((A_UINT32)0x100) -#define FIX_RATE_36Mb ((A_UINT32)0x200) -#define FIX_RATE_48Mb ((A_UINT32)0x400) -#define FIX_RATE_54Mb ((A_UINT32)0x800) -#define FIX_RATE_MCS_0_20 ((A_UINT32)0x1000) -#define FIX_RATE_MCS_1_20 ((A_UINT32)0x2000) -#define FIX_RATE_MCS_2_20 ((A_UINT32)0x4000) -#define FIX_RATE_MCS_3_20 ((A_UINT32)0x8000) -#define FIX_RATE_MCS_4_20 ((A_UINT32)0x10000) -#define FIX_RATE_MCS_5_20 ((A_UINT32)0x20000) -#define FIX_RATE_MCS_6_20 ((A_UINT32)0x40000) -#define FIX_RATE_MCS_7_20 ((A_UINT32)0x80000) -#define FIX_RATE_MCS_0_40 ((A_UINT32)0x100000) -#define FIX_RATE_MCS_1_40 ((A_UINT32)0x200000) -#define FIX_RATE_MCS_2_40 ((A_UINT32)0x400000) -#define FIX_RATE_MCS_3_40 ((A_UINT32)0x800000) -#define FIX_RATE_MCS_4_40 ((A_UINT32)0x1000000) -#define FIX_RATE_MCS_5_40 ((A_UINT32)0x2000000) -#define FIX_RATE_MCS_6_40 ((A_UINT32)0x4000000) -#define FIX_RATE_MCS_7_40 ((A_UINT32)0x8000000) - -typedef PREPACK struct { - A_UINT32 fixRateMask; /* see WMI_BIT_RATE */ +#define FIX_RATE_1Mb ((u32)0x1) +#define FIX_RATE_2Mb ((u32)0x2) +#define FIX_RATE_5_5Mb ((u32)0x4) +#define FIX_RATE_11Mb ((u32)0x8) +#define FIX_RATE_6Mb ((u32)0x10) +#define FIX_RATE_9Mb ((u32)0x20) +#define FIX_RATE_12Mb ((u32)0x40) +#define FIX_RATE_18Mb ((u32)0x80) +#define FIX_RATE_24Mb ((u32)0x100) +#define FIX_RATE_36Mb ((u32)0x200) +#define FIX_RATE_48Mb ((u32)0x400) +#define FIX_RATE_54Mb ((u32)0x800) +#define FIX_RATE_MCS_0_20 ((u32)0x1000) +#define FIX_RATE_MCS_1_20 ((u32)0x2000) +#define FIX_RATE_MCS_2_20 ((u32)0x4000) +#define FIX_RATE_MCS_3_20 ((u32)0x8000) +#define FIX_RATE_MCS_4_20 ((u32)0x10000) +#define FIX_RATE_MCS_5_20 ((u32)0x20000) +#define FIX_RATE_MCS_6_20 ((u32)0x40000) +#define FIX_RATE_MCS_7_20 ((u32)0x80000) +#define FIX_RATE_MCS_0_40 ((u32)0x100000) +#define FIX_RATE_MCS_1_40 ((u32)0x200000) +#define FIX_RATE_MCS_2_40 ((u32)0x400000) +#define FIX_RATE_MCS_3_40 ((u32)0x800000) +#define FIX_RATE_MCS_4_40 ((u32)0x1000000) +#define FIX_RATE_MCS_5_40 ((u32)0x2000000) +#define FIX_RATE_MCS_6_40 ((u32)0x4000000) +#define FIX_RATE_MCS_7_40 ((u32)0x8000000) + +typedef PREPACK struct { + u32 fixRateMask; /* see WMI_BIT_RATE */ } POSTPACK WMI_FIX_RATES_CMD, WMI_FIX_RATES_REPLY; typedef PREPACK struct { u8 bEnableMask; u8 frameType; /*type and subtype*/ - A_UINT32 frameRateMask; /* see WMI_BIT_RATE */ + u32 frameRateMask; /* see WMI_BIT_RATE */ } POSTPACK WMI_FRAME_RATES_CMD, WMI_FRAME_RATES_REPLY; /* @@ -2594,10 +2594,10 @@ typedef enum { } ROAM_DATA_TYPE; typedef PREPACK struct { - A_UINT32 disassoc_time; - A_UINT32 no_txrx_time; - A_UINT32 assoc_time; - A_UINT32 allow_txrx_time; + u32 disassoc_time; + u32 no_txrx_time; + u32 assoc_time; + u32 allow_txrx_time; u8 disassoc_bssid[ATH_MAC_LEN]; A_INT8 disassoc_bss_rssi; u8 assoc_bssid[ATH_MAC_LEN]; @@ -2713,7 +2713,7 @@ typedef PREPACK struct { #define MAX_IP_ADDRS 2 typedef PREPACK struct { - A_UINT32 ips[MAX_IP_ADDRS]; /* IP in Network Byte Order */ + u32 ips[MAX_IP_ADDRS]; /* IP in Network Byte Order */ } POSTPACK WMI_SET_IP_CMD; typedef PREPACK struct { @@ -2769,7 +2769,7 @@ typedef PREPACK struct { #define WMI_AKMP_MULTI_PMKID_EN 0x000001 typedef PREPACK struct { - A_UINT32 akmpInfo; + u32 akmpInfo; } POSTPACK WMI_SET_AKMP_PARAMS_CMD; typedef PREPACK struct { @@ -2782,7 +2782,7 @@ typedef PREPACK struct { #define WMI_MAX_PMKID_CACHE 8 typedef PREPACK struct { - A_UINT32 numPMKID; + u32 numPMKID; WMI_PMKID pmkidList[WMI_MAX_PMKID_CACHE]; } POSTPACK WMI_SET_PMKID_LIST_CMD; @@ -2791,18 +2791,18 @@ typedef PREPACK struct { * Following the Number of PMKIDs is the list of PMKIDs */ typedef PREPACK struct { - A_UINT32 numPMKID; + u32 numPMKID; u8 bssidList[ATH_MAC_LEN][1]; WMI_PMKID pmkidList[1]; } POSTPACK WMI_PMKID_LIST_REPLY; typedef PREPACK struct { u16 oldChannel; - A_UINT32 newChannel; + u32 newChannel; } POSTPACK WMI_CHANNEL_CHANGE_EVENT; typedef PREPACK struct { - A_UINT32 version; + u32 version; } POSTPACK WMI_WLAN_VERSION_EVENT; @@ -2898,8 +2898,8 @@ typedef PREPACK struct { u8 rateIdx; /* rate index on successful transmission */ u8 ackFailures; /* number of ACK failures in tx attempt */ #if 0 /* optional params currently ommitted. */ - A_UINT32 queueDelay; // usec delay measured Tx Start time - host delivery time - A_UINT32 mediaDelay; // usec delay measured ACK rx time - host delivery time + u32 queueDelay; // usec delay measured Tx Start time - host delivery time + u32 mediaDelay; // usec delay measured ACK rx time - host delivery time #endif } POSTPACK TX_COMPLETE_MSG_V1; /* version 1 of tx complete msg */ @@ -3001,12 +3001,12 @@ typedef PREPACK struct { } POSTPACK WMI_AP_SET_MLME_CMD; typedef PREPACK struct { - A_UINT32 period; + u32 period; } POSTPACK WMI_AP_CONN_INACT_CMD; typedef PREPACK struct { - A_UINT32 period_min; - A_UINT32 dwell_ms; + u32 period_min; + u32 dwell_ms; } POSTPACK WMI_AP_PROT_SCAN_TIME_CMD; typedef PREPACK struct { @@ -3039,11 +3039,11 @@ typedef PREPACK struct { } POSTPACK WMI_SET_HT_OP_CMD; typedef PREPACK struct { - A_UINT32 rateMasks[8]; + u32 rateMasks[8]; } POSTPACK WMI_SET_TX_SELECT_RATES_CMD; typedef PREPACK struct { - A_UINT32 sgiMask; + u32 sgiMask; u8 sgiPERThreshold; } POSTPACK WMI_SET_TX_SGI_PARAM_CMD; @@ -3051,7 +3051,7 @@ typedef PREPACK struct { #define DEFAULT_SGI_PER 10 typedef PREPACK struct { - A_UINT32 rateField; /* 1 bit per rate corresponding to index */ + u32 rateField; /* 1 bit per rate corresponding to index */ u8 id; u8 shortTrys; u8 longTrys; @@ -3078,25 +3078,25 @@ typedef PREPACK struct { } POSTPACK WMI_PSPOLL_EVENT; typedef PREPACK struct { - A_UINT32 tx_bytes; - A_UINT32 tx_pkts; - A_UINT32 tx_error; - A_UINT32 tx_discard; - A_UINT32 rx_bytes; - A_UINT32 rx_pkts; - A_UINT32 rx_error; - A_UINT32 rx_discard; - A_UINT32 aid; + u32 tx_bytes; + u32 tx_pkts; + u32 tx_error; + u32 tx_discard; + u32 rx_bytes; + u32 rx_pkts; + u32 rx_error; + u32 rx_discard; + u32 aid; } POSTPACK WMI_PER_STA_STAT; #define AP_GET_STATS 0 #define AP_CLEAR_STATS 1 typedef PREPACK struct { - A_UINT32 action; + u32 action; WMI_PER_STA_STAT sta[AP_MAX_NUM_STA+1]; } POSTPACK WMI_AP_MODE_STAT; -#define WMI_AP_MODE_STAT_SIZE(numSta) (sizeof(A_UINT32) + ((numSta + 1) * sizeof(WMI_PER_STA_STAT))) +#define WMI_AP_MODE_STAT_SIZE(numSta) (sizeof(u32) + ((numSta + 1) * sizeof(WMI_PER_STA_STAT))) #define AP_11BG_RATESET1 1 #define AP_11BG_RATESET2 2 diff --git a/drivers/staging/ath6kl/include/common/wmi_thin.h b/drivers/staging/ath6kl/include/common/wmi_thin.h index dee5e8aae425..41f2b9ba1021 100644 --- a/drivers/staging/ath6kl/include/common/wmi_thin.h +++ b/drivers/staging/ath6kl/include/common/wmi_thin.h @@ -119,14 +119,14 @@ typedef PREPACK struct { * frames that require partial MAC header construction. These rules * are used by the target to indicate which fields need to be written. */ typedef PREPACK struct { - A_UINT32 rules; /* combination of WMI_WRT_... values */ + u32 rules; /* combination of WMI_WRT_... values */ } POSTPACK WMI_THIN_CONFIG_TX_MAC_RULES; /* WMI_THIN_CONFIG_RX_FILTER_RULES -- Used to configure behavior for received * frames as to which frames should get forwarded to the host and which * should get processed internally. */ typedef PREPACK struct { - A_UINT32 rules; /* combination of WMI_FILT_... values */ + u32 rules; /* combination of WMI_FILT_... values */ } POSTPACK WMI_THIN_CONFIG_RX_FILTER_RULES; /* WMI_THIN_CONFIG_CMD -- Used to contain some combination of the above @@ -138,7 +138,7 @@ typedef PREPACK struct { #define WMI_THIN_CFG_DECRYPT 0x00000002 #define WMI_THIN_CFG_MAC_RULES 0x00000004 #define WMI_THIN_CFG_FILTER_RULES 0x00000008 - A_UINT32 cfgField; /* combination of WMI_THIN_CFG_... describes contents of config command */ + u32 cfgField; /* combination of WMI_THIN_CFG_... describes contents of config command */ u16 length; /* length in bytes of appended sub-commands */ u8 reserved[2]; /* align padding */ } POSTPACK WMI_THIN_CONFIG_CMD; @@ -180,7 +180,7 @@ typedef PREPACK struct { } POSTPACK WMI_THIN_MIB_STA_MAC; typedef PREPACK struct { - A_UINT32 time; // units == msec + u32 time; // units == msec } POSTPACK WMI_THIN_MIB_RX_LIFE_TIME; typedef PREPACK struct { @@ -188,7 +188,7 @@ typedef PREPACK struct { } POSTPACK WMI_THIN_MIB_CTS_TO_SELF; typedef PREPACK struct { - A_UINT32 time; // units == usec + u32 time; // units == usec } POSTPACK WMI_THIN_MIB_SLOT_TIME; typedef PREPACK struct { @@ -204,7 +204,7 @@ typedef PREPACK struct { typedef PREPACK struct { #define FRAME_FILTER_PROMISCUOUS 0x00000001 #define FRAME_FILTER_BSSID 0x00000002 - A_UINT32 filterMask; + u32 filterMask; } POSTPACK WMI_THIN_MIB_RXFRAME_FILTER; @@ -231,13 +231,13 @@ typedef PREPACK struct { } POSTPACK WMI_THIN_MIB_BEACON_FILTER_TABLE_HEADER; typedef PREPACK struct { - A_UINT32 count; /* num beacons between deliveries */ + u32 count; /* num beacons between deliveries */ u8 enable; u8 reserved[3]; } POSTPACK WMI_THIN_MIB_BEACON_FILTER; typedef PREPACK struct { - A_UINT32 count; /* num consec lost beacons after which send event */ + u32 count; /* num consec lost beacons after which send event */ } POSTPACK WMI_THIN_MIB_BEACON_LOST_COUNT; typedef PREPACK struct { @@ -249,9 +249,9 @@ typedef PREPACK struct { typedef PREPACK struct { - A_UINT32 cap; - A_UINT32 rxRateField; - A_UINT32 beamForming; + u32 cap; + u32 rxRateField; + u32 beamForming; u8 addr[ATH_MAC_LEN]; u8 enable; u8 stbc; @@ -262,8 +262,8 @@ typedef PREPACK struct { } POSTPACK WMI_THIN_MIB_HT_CAP; typedef PREPACK struct { - A_UINT32 infoField; - A_UINT32 basicRateField; + u32 infoField; + u32 basicRateField; u8 protection; u8 secondChanneloffset; u8 channelWidth; @@ -301,8 +301,8 @@ typedef PREPACK struct { } POSTPACK WMI_THIN_GET_MIB_CMD; typedef PREPACK struct { - A_UINT32 basicRateMask; /* bit mask of basic rates */ - A_UINT32 beaconIntval; /* TUs */ + u32 basicRateMask; /* bit mask of basic rates */ + u32 beaconIntval; /* TUs */ u16 atimWindow; /* TUs */ u16 channel; /* frequency in Mhz */ u8 networkType; /* INFRA_NETWORK | ADHOC_NETWORK */ diff --git a/drivers/staging/ath6kl/include/common/wmix.h b/drivers/staging/ath6kl/include/common/wmix.h index 7dd5434136a2..5ebb8285d135 100644 --- a/drivers/staging/ath6kl/include/common/wmix.h +++ b/drivers/staging/ath6kl/include/common/wmix.h @@ -55,7 +55,7 @@ extern "C" { * WMI_EVENT_ID=WMI_EXTENSION_EVENTID. */ typedef PREPACK struct { - A_UINT32 commandId; + u32 commandId; } POSTPACK WMIX_CMD_HDR; typedef enum { @@ -96,10 +96,10 @@ typedef enum { * DataSet Open Request Event */ typedef PREPACK struct { - A_UINT32 dset_id; - A_UINT32 targ_dset_handle; /* echo'ed, not used by Host, */ - A_UINT32 targ_reply_fn; /* echo'ed, not used by Host, */ - A_UINT32 targ_reply_arg; /* echo'ed, not used by Host, */ + u32 dset_id; + u32 targ_dset_handle; /* echo'ed, not used by Host, */ + u32 targ_reply_fn; /* echo'ed, not used by Host, */ + u32 targ_reply_arg; /* echo'ed, not used by Host, */ } POSTPACK WMIX_DSETOPENREQ_EVENT; /* @@ -107,7 +107,7 @@ typedef PREPACK struct { * DataSet Close Event */ typedef PREPACK struct { - A_UINT32 access_cookie; + u32 access_cookie; } POSTPACK WMIX_DSETCLOSE_EVENT; /* @@ -115,30 +115,30 @@ typedef PREPACK struct { * DataSet Data Request Event */ typedef PREPACK struct { - A_UINT32 access_cookie; - A_UINT32 offset; - A_UINT32 length; - A_UINT32 targ_buf; /* echo'ed, not used by Host, */ - A_UINT32 targ_reply_fn; /* echo'ed, not used by Host, */ - A_UINT32 targ_reply_arg; /* echo'ed, not used by Host, */ + u32 access_cookie; + u32 offset; + u32 length; + u32 targ_buf; /* echo'ed, not used by Host, */ + u32 targ_reply_fn; /* echo'ed, not used by Host, */ + u32 targ_reply_arg; /* echo'ed, not used by Host, */ } POSTPACK WMIX_DSETDATAREQ_EVENT; typedef PREPACK struct { - A_UINT32 status; - A_UINT32 targ_dset_handle; - A_UINT32 targ_reply_fn; - A_UINT32 targ_reply_arg; - A_UINT32 access_cookie; - A_UINT32 size; - A_UINT32 version; + u32 status; + u32 targ_dset_handle; + u32 targ_reply_fn; + u32 targ_reply_arg; + u32 access_cookie; + u32 size; + u32 version; } POSTPACK WMIX_DSETOPEN_REPLY_CMD; typedef PREPACK struct { - A_UINT32 status; - A_UINT32 targ_buf; - A_UINT32 targ_reply_fn; - A_UINT32 targ_reply_arg; - A_UINT32 length; + u32 status; + u32 targ_buf; + u32 targ_reply_fn; + u32 targ_reply_arg; + u32 length; u8 buf[1]; } POSTPACK WMIX_DSETDATA_REPLY_CMD; @@ -160,10 +160,10 @@ typedef PREPACK struct { * clear/disable or disable/enable, results are undefined. */ typedef PREPACK struct { - A_UINT32 set_mask; /* pins to set */ - A_UINT32 clear_mask; /* pins to clear */ - A_UINT32 enable_mask; /* pins to enable for output */ - A_UINT32 disable_mask; /* pins to disable/tristate */ + u32 set_mask; /* pins to set */ + u32 clear_mask; /* pins to clear */ + u32 enable_mask; /* pins to enable for output */ + u32 disable_mask; /* pins to disable/tristate */ } POSTPACK WMIX_GPIO_OUTPUT_SET_CMD; /* @@ -172,13 +172,13 @@ typedef PREPACK struct { * platform-dependent header. */ typedef PREPACK struct { - A_UINT32 gpioreg_id; /* GPIO register ID */ - A_UINT32 value; /* value to write */ + u32 gpioreg_id; /* GPIO register ID */ + u32 value; /* value to write */ } POSTPACK WMIX_GPIO_REGISTER_SET_CMD; /* Get a GPIO register. For debug/exceptional cases. */ typedef PREPACK struct { - A_UINT32 gpioreg_id; /* GPIO register to read */ + u32 gpioreg_id; /* GPIO register to read */ } POSTPACK WMIX_GPIO_REGISTER_GET_CMD; /* @@ -187,7 +187,7 @@ typedef PREPACK struct { * were delivered in an earlier WMIX_GPIO_INTR_EVENT message. */ typedef PREPACK struct { - A_UINT32 ack_mask; /* interrupts to acknowledge */ + u32 ack_mask; /* interrupts to acknowledge */ } POSTPACK WMIX_GPIO_INTR_ACK_CMD; /* @@ -197,8 +197,8 @@ typedef PREPACK struct { * use of a GPIO interrupt as a Data Valid signal for other GPIO pins. */ typedef PREPACK struct { - A_UINT32 intr_mask; /* pending GPIO interrupts */ - A_UINT32 input_values; /* recent GPIO input values */ + u32 intr_mask; /* pending GPIO interrupts */ + u32 input_values; /* recent GPIO input values */ } POSTPACK WMIX_GPIO_INTR_EVENT; /* @@ -217,8 +217,8 @@ typedef PREPACK struct { * simplify Host GPIO support. */ typedef PREPACK struct { - A_UINT32 value; - A_UINT32 reg_id; + u32 value; + u32 reg_id; } POSTPACK WMIX_GPIO_DATA_EVENT; /* @@ -230,8 +230,8 @@ typedef PREPACK struct { * Heartbeat Challenge Response command */ typedef PREPACK struct { - A_UINT32 cookie; - A_UINT32 source; + u32 cookie; + u32 source; } POSTPACK WMIX_HB_CHALLENGE_RESP_CMD; /* @@ -249,12 +249,12 @@ typedef PREPACK struct { */ typedef PREPACK struct { - A_UINT32 period; /* Time (in 30.5us ticks) between samples */ - A_UINT32 nbins; + u32 period; /* Time (in 30.5us ticks) between samples */ + u32 nbins; } POSTPACK WMIX_PROF_CFG_CMD; typedef PREPACK struct { - A_UINT32 addr; + u32 addr; } POSTPACK WMIX_PROF_ADDR_SET_CMD; /* @@ -264,8 +264,8 @@ typedef PREPACK struct { * count set to the corresponding count */ typedef PREPACK struct { - A_UINT32 addr; - A_UINT32 count; + u32 addr; + u32 count; } POSTPACK WMIX_PROF_COUNT_EVENT; #ifndef ATH_TARGET diff --git a/drivers/staging/ath6kl/include/common_drv.h b/drivers/staging/ath6kl/include/common_drv.h index 0d2902db817a..f5152eb86c5a 100644 --- a/drivers/staging/ath6kl/include/common_drv.h +++ b/drivers/staging/ath6kl/include/common_drv.h @@ -66,40 +66,40 @@ extern "C" { /* OS-independent APIs */ int ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, COMMON_CREDIT_STATE_INFO *pCredInfo); -int ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); +int ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data); -int ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); +int ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data); -int ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, A_UCHAR *data, A_UINT32 length); +int ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, u32 address, A_UCHAR *data, u32 length); -int ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType, bool waitForCompletion, bool coldReset); +int ar6000_reset_device(HIF_DEVICE *hifDevice, u32 TargetType, bool waitForCompletion, bool coldReset); -void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType); +void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, u32 TargetType); int ar6000_set_htc_params(HIF_DEVICE *hifDevice, - A_UINT32 TargetType, - A_UINT32 MboxIsrYieldValue, + u32 TargetType, + u32 MboxIsrYieldValue, u8 HtcControlBuffers); int ar6000_prepare_target(HIF_DEVICE *hifDevice, - A_UINT32 TargetType, - A_UINT32 TargetVersion); + u32 TargetType, + u32 TargetVersion); int ar6000_set_hci_bridge_flags(HIF_DEVICE *hifDevice, - A_UINT32 TargetType, - A_UINT32 Flags); + u32 TargetType, + u32 Flags); -void ar6000_copy_cust_data_from_target(HIF_DEVICE *hifDevice, A_UINT32 TargetType); +void ar6000_copy_cust_data_from_target(HIF_DEVICE *hifDevice, u32 TargetType); -u8 *ar6000_get_cust_data_buffer(A_UINT32 TargetType); +u8 *ar6000_get_cust_data_buffer(u32 TargetType); -int ar6000_setBTState(void *context, u8 *pInBuf, A_UINT32 InBufSize); +int ar6000_setBTState(void *context, u8 *pInBuf, u32 InBufSize); -int ar6000_setDevicePowerState(void *context, u8 *pInBuf, A_UINT32 InBufSize); +int ar6000_setDevicePowerState(void *context, u8 *pInBuf, u32 InBufSize); -int ar6000_setWowMode(void *context, u8 *pInBuf, A_UINT32 InBufSize); +int ar6000_setWowMode(void *context, u8 *pInBuf, u32 InBufSize); -int ar6000_setHostMode(void *context, u8 *pInBuf, A_UINT32 InBufSize); +int ar6000_setHostMode(void *context, u8 *pInBuf, u32 InBufSize); #ifdef __cplusplus } diff --git a/drivers/staging/ath6kl/include/dset_api.h b/drivers/staging/ath6kl/include/dset_api.h index 7ebc588f51c7..fe901ba40ec6 100644 --- a/drivers/staging/ath6kl/include/dset_api.h +++ b/drivers/staging/ath6kl/include/dset_api.h @@ -40,22 +40,22 @@ extern "C" { /* Called to send a DataSet Open Reply back to the Target. */ int wmi_dset_open_reply(struct wmi_t *wmip, - A_UINT32 status, - A_UINT32 access_cookie, - A_UINT32 size, - A_UINT32 version, - A_UINT32 targ_handle, - A_UINT32 targ_reply_fn, - A_UINT32 targ_reply_arg); + u32 status, + u32 access_cookie, + u32 size, + u32 version, + u32 targ_handle, + u32 targ_reply_fn, + u32 targ_reply_arg); /* Called to send a DataSet Data Reply back to the Target. */ int wmi_dset_data_reply(struct wmi_t *wmip, - A_UINT32 status, + u32 status, u8 *host_buf, - A_UINT32 length, - A_UINT32 targ_buf, - A_UINT32 targ_reply_fn, - A_UINT32 targ_reply_arg); + u32 length, + u32 targ_buf, + u32 targ_reply_fn, + u32 targ_reply_arg); #ifdef __cplusplus } diff --git a/drivers/staging/ath6kl/include/gpio_api.h b/drivers/staging/ath6kl/include/gpio_api.h index 81c228dd16ab..6b4c547432e9 100644 --- a/drivers/staging/ath6kl/include/gpio_api.h +++ b/drivers/staging/ath6kl/include/gpio_api.h @@ -29,10 +29,10 @@ * Send a command to the Target in order to change output on GPIO pins. */ int wmi_gpio_output_set(struct wmi_t *wmip, - A_UINT32 set_mask, - A_UINT32 clear_mask, - A_UINT32 enable_mask, - A_UINT32 disable_mask); + u32 set_mask, + u32 clear_mask, + u32 enable_mask, + u32 disable_mask); /* * Send a command to the Target requesting input state of GPIO pins. @@ -43,17 +43,17 @@ int wmi_gpio_input_get(struct wmi_t *wmip); * Send a command to the Target to change the value of a GPIO register. */ int wmi_gpio_register_set(struct wmi_t *wmip, - A_UINT32 gpioreg_id, - A_UINT32 value); + u32 gpioreg_id, + u32 value); /* * Send a command to the Target to fetch the value of a GPIO register. */ -int wmi_gpio_register_get(struct wmi_t *wmip, A_UINT32 gpioreg_id); +int wmi_gpio_register_get(struct wmi_t *wmip, u32 gpioreg_id); /* * Send a command to the Target, acknowledging some GPIO interrupts. */ -int wmi_gpio_intr_ack(struct wmi_t *wmip, A_UINT32 ack_mask); +int wmi_gpio_intr_ack(struct wmi_t *wmip, u32 ack_mask); #endif /* _GPIO_API_H_ */ diff --git a/drivers/staging/ath6kl/include/hci_transport_api.h b/drivers/staging/ath6kl/include/hci_transport_api.h index 9b8b9aa39777..47d0db97ab51 100644 --- a/drivers/staging/ath6kl/include/hci_transport_api.h +++ b/drivers/staging/ath6kl/include/hci_transport_api.h @@ -237,7 +237,7 @@ int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, @example: @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud); +int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Enable/Disable HCI Transport Power Management diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h index 06ddb6883920..3906780d0200 100644 --- a/drivers/staging/ath6kl/include/hif.h +++ b/drivers/staging/ath6kl/include/hif.h @@ -224,8 +224,8 @@ typedef enum { */ typedef struct { - A_UINT32 ExtendedAddress; /* extended address for larger writes */ - A_UINT32 ExtendedSize; + u32 ExtendedAddress; /* extended address for larger writes */ + u32 ExtendedSize; } HIF_MBOX_PROPERTIES; #define HIF_MBOX_FLAG_NO_BUNDLING (1 << 0) /* do not allow bundling over the mailbox */ @@ -236,16 +236,16 @@ typedef enum _MBOX_BUF_IF_TYPE { } MBOX_BUF_IF_TYPE; typedef struct { - A_UINT32 MboxAddresses[4]; /* must be first element for legacy HIFs that return the address in + u32 MboxAddresses[4]; /* must be first element for legacy HIFs that return the address in and ARRAY of 32-bit words */ /* the following describe extended mailbox properties */ HIF_MBOX_PROPERTIES MboxProp[4]; /* if the HIF supports the GMbox extended address region it can report it * here, some interfaces cannot support the GMBOX address range and not set this */ - A_UINT32 GMboxAddress; - A_UINT32 GMboxSize; - A_UINT32 Flags; /* flags to describe mbox behavior or usage */ + u32 GMboxAddress; + u32 GMboxSize; + u32 Flags; /* flags to describe mbox behavior or usage */ MBOX_BUF_IF_TYPE MboxBusIFType; /* mailbox bus interface type */ } HIF_DEVICE_MBOX_INFO; @@ -288,10 +288,10 @@ typedef enum _HIF_SCATTER_METHOD { typedef struct _HIF_SCATTER_REQ { DL_LIST ListLink; /* link management */ - A_UINT32 Address; /* address for the read/write operation */ - A_UINT32 Request; /* request flags */ - A_UINT32 TotalLength; /* total length of entire transfer */ - A_UINT32 CallerFlags; /* caller specific flags can be stored here */ + u32 Address; /* address for the read/write operation */ + u32 Request; /* request flags */ + u32 TotalLength; /* total length of entire transfer */ + u32 CallerFlags; /* caller specific flags can be stored here */ HIF_SCATTER_COMP_CB CompletionRoutine; /* completion routine set by caller */ int CompletionStatus; /* status of completion */ void *Context; /* caller context for this request */ @@ -344,12 +344,12 @@ typedef struct osdrv_callbacks { #define HIF_RECV_MSG_AVAIL (1 << 1) /* pending recv packet */ typedef struct _HIF_PENDING_EVENTS_INFO { - A_UINT32 Events; - A_UINT32 LookAhead; - A_UINT32 AvailableRecvBytes; + u32 Events; + u32 LookAhead; + u32 AvailableRecvBytes; #ifdef THREAD_X - A_UINT32 Polling; - A_UINT32 INT_CAUSE_REG; + u32 Polling; + u32 INT_CAUSE_REG; #endif } HIF_PENDING_EVENTS_INFO; @@ -400,10 +400,10 @@ void HIFDetachHTC(HIF_DEVICE *device); */ int HIFReadWrite(HIF_DEVICE *device, - A_UINT32 address, + u32 address, A_UCHAR *buffer, - A_UINT32 length, - A_UINT32 request, + u32 length, + u32 request, void *context); /* @@ -443,7 +443,7 @@ int HIFRWCompleteEventNotify(void); int HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, - void *config, A_UINT32 configLen); + void *config, u32 configLen); /* * This API wait for the remaining MBOX messages to be drained diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h index 27d8fa281c9c..3cfa9f2c8e05 100644 --- a/drivers/staging/ath6kl/include/htc_api.h +++ b/drivers/staging/ath6kl/include/htc_api.h @@ -146,7 +146,7 @@ typedef struct _HTC_SERVICE_CONNECT_REQ { u8 MetaDataLength; /* optional meta data length */ HTC_EP_CALLBACKS EpCallbacks; /* endpoint callbacks */ int MaxSendQueueDepth; /* maximum depth of any send queue */ - A_UINT32 LocalConnectionFlags; /* HTC flags for the host-side (local) connection */ + u32 LocalConnectionFlags; /* HTC flags for the host-side (local) connection */ unsigned int MaxSendMsgSize; /* override max message size in send direction */ } HTC_SERVICE_CONNECT_REQ; @@ -168,7 +168,7 @@ typedef struct _HTC_ENDPOINT_CREDIT_DIST { struct _HTC_ENDPOINT_CREDIT_DIST *pPrev; HTC_SERVICE_ID ServiceID; /* Service ID (set by HTC) */ HTC_ENDPOINT_ID Endpoint; /* endpoint for this distribution struct (set by HTC) */ - A_UINT32 DistFlags; /* distribution flags, distribution function can + u32 DistFlags; /* distribution flags, distribution function can set default activity using SET_EP_ACTIVE() macro */ int TxCreditsNorm; /* credits for normal operation, anything above this indicates the endpoint is over-subscribed, this field @@ -197,7 +197,7 @@ typedef struct _HTC_ENDPOINT_CREDIT_DIST { */ } HTC_ENDPOINT_CREDIT_DIST; -#define HTC_EP_ACTIVE ((A_UINT32) (1u << 31)) +#define HTC_EP_ACTIVE ((u32) (1u << 31)) /* macro to check if an endpoint has gone active, useful for credit * distributions */ @@ -232,29 +232,29 @@ typedef enum _HTC_ENDPOINT_STAT_ACTION { /* endpoint statistics */ typedef struct _HTC_ENDPOINT_STATS { - A_UINT32 TxCreditLowIndications; /* number of times the host set the credit-low flag in a send message on + u32 TxCreditLowIndications; /* number of times the host set the credit-low flag in a send message on this endpoint */ - A_UINT32 TxIssued; /* running count of total TX packets issued */ - A_UINT32 TxPacketsBundled; /* running count of TX packets that were issued in bundles */ - A_UINT32 TxBundles; /* running count of TX bundles that were issued */ - A_UINT32 TxDropped; /* tx packets that were dropped */ - A_UINT32 TxCreditRpts; /* running count of total credit reports received for this endpoint */ - A_UINT32 TxCreditRptsFromRx; /* credit reports received from this endpoint's RX packets */ - A_UINT32 TxCreditRptsFromOther; /* credit reports received from RX packets of other endpoints */ - A_UINT32 TxCreditRptsFromEp0; /* credit reports received from endpoint 0 RX packets */ - A_UINT32 TxCreditsFromRx; /* count of credits received via Rx packets on this endpoint */ - A_UINT32 TxCreditsFromOther; /* count of credits received via another endpoint */ - A_UINT32 TxCreditsFromEp0; /* count of credits received via another endpoint */ - A_UINT32 TxCreditsConsummed; /* count of consummed credits */ - A_UINT32 TxCreditsReturned; /* count of credits returned */ - A_UINT32 RxReceived; /* count of RX packets received */ - A_UINT32 RxLookAheads; /* count of lookahead records + u32 TxIssued; /* running count of total TX packets issued */ + u32 TxPacketsBundled; /* running count of TX packets that were issued in bundles */ + u32 TxBundles; /* running count of TX bundles that were issued */ + u32 TxDropped; /* tx packets that were dropped */ + u32 TxCreditRpts; /* running count of total credit reports received for this endpoint */ + u32 TxCreditRptsFromRx; /* credit reports received from this endpoint's RX packets */ + u32 TxCreditRptsFromOther; /* credit reports received from RX packets of other endpoints */ + u32 TxCreditRptsFromEp0; /* credit reports received from endpoint 0 RX packets */ + u32 TxCreditsFromRx; /* count of credits received via Rx packets on this endpoint */ + u32 TxCreditsFromOther; /* count of credits received via another endpoint */ + u32 TxCreditsFromEp0; /* count of credits received via another endpoint */ + u32 TxCreditsConsummed; /* count of consummed credits */ + u32 TxCreditsReturned; /* count of credits returned */ + u32 RxReceived; /* count of RX packets received */ + u32 RxLookAheads; /* count of lookahead records found in messages received on this endpoint */ - A_UINT32 RxPacketsBundled; /* count of recv packets received in a bundle */ - A_UINT32 RxBundleLookAheads; /* count of number of bundled lookaheads */ - A_UINT32 RxBundleIndFromHdr; /* count of the number of bundle indications from the HTC header */ - A_UINT32 RxAllocThreshHit; /* count of the number of times the recv allocation threshhold was hit */ - A_UINT32 RxAllocThreshBytes; /* total number of bytes */ + u32 RxPacketsBundled; /* count of recv packets received in a bundle */ + u32 RxBundleLookAheads; /* count of number of bundled lookaheads */ + u32 RxBundleIndFromHdr; /* count of the number of bundle indications from the HTC header */ + u32 RxAllocThreshHit; /* count of the number of times the recv allocation threshhold was hit */ + u32 RxAllocThreshBytes; /* total number of bytes */ } HTC_ENDPOINT_STATS; /* ------ Function Prototypes ------ */ @@ -565,7 +565,7 @@ int HTCGetNumRecvBuffers(HTC_HANDLE HTCHandle, void HTCEnableRecv(HTC_HANDLE HTCHandle); void HTCDisableRecv(HTC_HANDLE HTCHandle); int HTCWaitForPendingRecv(HTC_HANDLE HTCHandle, - A_UINT32 TimeoutInMs, + u32 TimeoutInMs, bool *pbIsRecvPending); #ifdef __cplusplus diff --git a/drivers/staging/ath6kl/include/htc_packet.h b/drivers/staging/ath6kl/include/htc_packet.h index bbf33d1564de..fcf0a0c3bedb 100644 --- a/drivers/staging/ath6kl/include/htc_packet.h +++ b/drivers/staging/ath6kl/include/htc_packet.h @@ -60,9 +60,9 @@ typedef struct _HTC_TX_PACKET_INFO { #define HTC_TX_PACKET_TAG_USER_DEFINED (HTC_TX_PACKET_TAG_INTERNAL + 9) /* user-defined tags start here */ typedef struct _HTC_RX_PACKET_INFO { - A_UINT32 ExpectedHdr; /* HTC internal use */ - A_UINT32 HTCRxFlags; /* HTC internal use */ - A_UINT32 IndicationFlags; /* indication flags set on each RX packet indication */ + u32 ExpectedHdr; /* HTC internal use */ + u32 HTCRxFlags; /* HTC internal use */ + u32 IndicationFlags; /* indication flags set on each RX packet indication */ } HTC_RX_PACKET_INFO; #define HTC_RX_FLAGS_INDICATE_MORE_PKTS (1 << 0) /* more packets on this endpoint are being fetched */ @@ -86,8 +86,8 @@ typedef struct _HTC_PACKET { * to the caller points to the start of the payload */ u8 *pBuffer; /* payload start (RX/TX) */ - A_UINT32 BufferLength; /* length of buffer */ - A_UINT32 ActualLength; /* actual length of payload */ + u32 BufferLength; /* length of buffer */ + u32 ActualLength; /* actual length of payload */ HTC_ENDPOINT_ID Endpoint; /* endpoint that this packet was sent/recv'd from */ int Status; /* completion status */ union { diff --git a/drivers/staging/ath6kl/include/target_reg_table.h b/drivers/staging/ath6kl/include/target_reg_table.h index 901f923bee34..e2225d59dd81 100644 --- a/drivers/staging/ath6kl/include/target_reg_table.h +++ b/drivers/staging/ath6kl/include/target_reg_table.h @@ -30,48 +30,48 @@ /*** WARNING : Add to the end of the TABLE! do not change the order ****/ typedef struct targetdef_s { - A_UINT32 d_RTC_BASE_ADDRESS; - A_UINT32 d_SYSTEM_SLEEP_OFFSET; - A_UINT32 d_SYSTEM_SLEEP_DISABLE_LSB; - A_UINT32 d_SYSTEM_SLEEP_DISABLE_MASK; - A_UINT32 d_CLOCK_CONTROL_OFFSET; - A_UINT32 d_CLOCK_CONTROL_SI0_CLK_MASK; - A_UINT32 d_RESET_CONTROL_OFFSET; - A_UINT32 d_RESET_CONTROL_SI0_RST_MASK; - A_UINT32 d_GPIO_BASE_ADDRESS; - A_UINT32 d_GPIO_PIN0_OFFSET; - A_UINT32 d_GPIO_PIN1_OFFSET; - A_UINT32 d_GPIO_PIN0_CONFIG_MASK; - A_UINT32 d_GPIO_PIN1_CONFIG_MASK; - A_UINT32 d_SI_CONFIG_BIDIR_OD_DATA_LSB; - A_UINT32 d_SI_CONFIG_BIDIR_OD_DATA_MASK; - A_UINT32 d_SI_CONFIG_I2C_LSB; - A_UINT32 d_SI_CONFIG_I2C_MASK; - A_UINT32 d_SI_CONFIG_POS_SAMPLE_LSB; - A_UINT32 d_SI_CONFIG_POS_SAMPLE_MASK; - A_UINT32 d_SI_CONFIG_INACTIVE_CLK_LSB; - A_UINT32 d_SI_CONFIG_INACTIVE_CLK_MASK; - A_UINT32 d_SI_CONFIG_INACTIVE_DATA_LSB; - A_UINT32 d_SI_CONFIG_INACTIVE_DATA_MASK; - A_UINT32 d_SI_CONFIG_DIVIDER_LSB; - A_UINT32 d_SI_CONFIG_DIVIDER_MASK; - A_UINT32 d_SI_BASE_ADDRESS; - A_UINT32 d_SI_CONFIG_OFFSET; - A_UINT32 d_SI_TX_DATA0_OFFSET; - A_UINT32 d_SI_TX_DATA1_OFFSET; - A_UINT32 d_SI_RX_DATA0_OFFSET; - A_UINT32 d_SI_RX_DATA1_OFFSET; - A_UINT32 d_SI_CS_OFFSET; - A_UINT32 d_SI_CS_DONE_ERR_MASK; - A_UINT32 d_SI_CS_DONE_INT_MASK; - A_UINT32 d_SI_CS_START_LSB; - A_UINT32 d_SI_CS_START_MASK; - A_UINT32 d_SI_CS_RX_CNT_LSB; - A_UINT32 d_SI_CS_RX_CNT_MASK; - A_UINT32 d_SI_CS_TX_CNT_LSB; - A_UINT32 d_SI_CS_TX_CNT_MASK; - A_UINT32 d_BOARD_DATA_SZ; - A_UINT32 d_BOARD_EXT_DATA_SZ; + u32 d_RTC_BASE_ADDRESS; + u32 d_SYSTEM_SLEEP_OFFSET; + u32 d_SYSTEM_SLEEP_DISABLE_LSB; + u32 d_SYSTEM_SLEEP_DISABLE_MASK; + u32 d_CLOCK_CONTROL_OFFSET; + u32 d_CLOCK_CONTROL_SI0_CLK_MASK; + u32 d_RESET_CONTROL_OFFSET; + u32 d_RESET_CONTROL_SI0_RST_MASK; + u32 d_GPIO_BASE_ADDRESS; + u32 d_GPIO_PIN0_OFFSET; + u32 d_GPIO_PIN1_OFFSET; + u32 d_GPIO_PIN0_CONFIG_MASK; + u32 d_GPIO_PIN1_CONFIG_MASK; + u32 d_SI_CONFIG_BIDIR_OD_DATA_LSB; + u32 d_SI_CONFIG_BIDIR_OD_DATA_MASK; + u32 d_SI_CONFIG_I2C_LSB; + u32 d_SI_CONFIG_I2C_MASK; + u32 d_SI_CONFIG_POS_SAMPLE_LSB; + u32 d_SI_CONFIG_POS_SAMPLE_MASK; + u32 d_SI_CONFIG_INACTIVE_CLK_LSB; + u32 d_SI_CONFIG_INACTIVE_CLK_MASK; + u32 d_SI_CONFIG_INACTIVE_DATA_LSB; + u32 d_SI_CONFIG_INACTIVE_DATA_MASK; + u32 d_SI_CONFIG_DIVIDER_LSB; + u32 d_SI_CONFIG_DIVIDER_MASK; + u32 d_SI_BASE_ADDRESS; + u32 d_SI_CONFIG_OFFSET; + u32 d_SI_TX_DATA0_OFFSET; + u32 d_SI_TX_DATA1_OFFSET; + u32 d_SI_RX_DATA0_OFFSET; + u32 d_SI_RX_DATA1_OFFSET; + u32 d_SI_CS_OFFSET; + u32 d_SI_CS_DONE_ERR_MASK; + u32 d_SI_CS_DONE_INT_MASK; + u32 d_SI_CS_START_LSB; + u32 d_SI_CS_START_MASK; + u32 d_SI_CS_RX_CNT_LSB; + u32 d_SI_CS_RX_CNT_MASK; + u32 d_SI_CS_TX_CNT_LSB; + u32 d_SI_CS_TX_CNT_MASK; + u32 d_BOARD_DATA_SZ; + u32 d_BOARD_EXT_DATA_SZ; } TARGET_REGISTER_TABLE; #define BOARD_DATA_SZ_MAX 2048 diff --git a/drivers/staging/ath6kl/include/wlan_api.h b/drivers/staging/ath6kl/include/wlan_api.h index 8fe804d6a215..ce799683725d 100644 --- a/drivers/staging/ath6kl/include/wlan_api.h +++ b/drivers/staging/ath6kl/include/wlan_api.h @@ -70,13 +70,13 @@ typedef struct bss { u8 *ni_buf; u16 ni_framelen; struct ieee80211_node_table *ni_table; - A_UINT32 ni_refcnt; + u32 ni_refcnt; int ni_scangen; - A_UINT32 ni_tstamp; - A_UINT32 ni_actcnt; + u32 ni_tstamp; + u32 ni_actcnt; #ifdef OS_ROAM_MANAGEMENT - A_UINT32 ni_si_gen; + u32 ni_si_gen; #endif } bss_t; @@ -100,16 +100,16 @@ int wlan_parse_beacon(u8 *buf, int framelen, struct ieee80211_common_ie *cie); u16 wlan_ieee2freq(int chan); -A_UINT32 wlan_freq2ieee(u16 freq); +u32 wlan_freq2ieee(u16 freq); -void wlan_set_nodeage(struct ieee80211_node_table *nt, A_UINT32 nodeAge); +void wlan_set_nodeage(struct ieee80211_node_table *nt, u32 nodeAge); void wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt); bss_t * wlan_find_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid, - A_UINT32 ssidLength, bool bIsWPA2, bool bMatchSSID); + u32 ssidLength, bool bIsWPA2, bool bMatchSSID); void wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni); @@ -118,8 +118,8 @@ bss_t *wlan_node_remove(struct ieee80211_node_table *nt, u8 *bssid); bss_t * wlan_find_matching_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid, - A_UINT32 ssidLength, A_UINT32 dot11AuthMode, A_UINT32 authMode, - A_UINT32 pairwiseCryptoType, A_UINT32 grpwiseCryptoTyp); + u32 ssidLength, u32 dot11AuthMode, u32 authMode, + u32 pairwiseCryptoType, u32 grpwiseCryptoTyp); #ifdef __cplusplus } diff --git a/drivers/staging/ath6kl/include/wmi_api.h b/drivers/staging/ath6kl/include/wmi_api.h index a0310b66106c..04f809c30519 100644 --- a/drivers/staging/ath6kl/include/wmi_api.h +++ b/drivers/staging/ath6kl/include/wmi_api.h @@ -80,9 +80,9 @@ int wmi_dot11_hdr_add(struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode); int wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf); int wmi_syncpoint(struct wmi_t *wmip); int wmi_syncpoint_reset(struct wmi_t *wmip); -u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 layer2Priority, bool wmmEnabled); +u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, u32 layer2Priority, bool wmmEnabled); -u8 wmi_determine_userPriority (u8 *pkt, A_UINT32 layer2Pri); +u8 wmi_determine_userPriority (u8 *pkt, u32 layer2Pri); int wmi_control_rx(struct wmi_t *wmip, void *osbuf); void wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg); @@ -114,7 +114,7 @@ int wmi_connect_cmd(struct wmi_t *wmip, A_UCHAR *ssid, u8 *bssid, u16 channel, - A_UINT32 ctrl_flags); + u32 ctrl_flags); int wmi_reconnect_cmd(struct wmi_t *wmip, u8 *bssid, @@ -123,16 +123,16 @@ int wmi_disconnect_cmd(struct wmi_t *wmip); int wmi_getrev_cmd(struct wmi_t *wmip); int wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, u32 forceFgScan, u32 isLegacy, - A_UINT32 homeDwellTime, A_UINT32 forceScanInterval, + u32 homeDwellTime, u32 forceScanInterval, A_INT8 numChan, u16 *channelList); int wmi_scanparams_cmd(struct wmi_t *wmip, u16 fg_start_sec, u16 fg_end_sec, u16 bg_sec, u16 minact_chdw_msec, u16 maxact_chdw_msec, u16 pas_chdw_msec, u8 shScanRatio, u8 scanCtrlFlags, - A_UINT32 max_dfsch_act_time, + u32 max_dfsch_act_time, u16 maxact_scan_per_ssid); -int wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, A_UINT32 ieMask); +int wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, u32 ieMask); int wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag, u8 ssidLength, A_UCHAR *ssid); int wmi_listeninterval_cmd(struct wmi_t *wmip, u16 listenInterval, u16 listenBeacons); @@ -142,8 +142,8 @@ int wmi_associnfo_cmd(struct wmi_t *wmip, u8 ieType, int wmi_powermode_cmd(struct wmi_t *wmip, u8 powerMode); int wmi_ibsspmcaps_cmd(struct wmi_t *wmip, u8 pmEnable, u8 ttl, u16 atim_windows, u16 timeout_value); -int wmi_apps_cmd(struct wmi_t *wmip, u8 psType, A_UINT32 idle_time, - A_UINT32 ps_period, u8 sleep_period); +int wmi_apps_cmd(struct wmi_t *wmip, u8 psType, u32 idle_time, + u32 ps_period, u8 sleep_period); int wmi_pmparams_cmd(struct wmi_t *wmip, u16 idlePeriod, u16 psPollNum, u16 dtimPolicy, u16 wakup_tx_policy, u16 num_tx_to_wakeup, @@ -172,14 +172,14 @@ int wmi_set_lq_threshold_params(struct wmi_t *wmip, int wmi_set_rts_cmd(struct wmi_t *wmip, u16 threshold); int wmi_set_lpreamble_cmd(struct wmi_t *wmip, u8 status, u8 preamblePolicy); -int wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 bitmask); +int wmi_set_error_report_bitmask(struct wmi_t *wmip, u32 bitmask); -int wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie, - A_UINT32 source); +int wmi_get_challenge_resp_cmd(struct wmi_t *wmip, u32 cookie, + u32 source); int wmi_config_debug_module_cmd(struct wmi_t *wmip, u16 mmask, u16 tsr, bool rep, u16 size, - A_UINT32 valid); + u32 valid); int wmi_get_stats_cmd(struct wmi_t *wmip); @@ -237,7 +237,7 @@ u8 wmi_get_power_mode_cmd(struct wmi_t *wmip); int wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance); #ifdef CONFIG_HOST_TCMD_SUPPORT -int wmi_test_cmd(struct wmi_t *wmip, u8 *buf, A_UINT32 len); +int wmi_test_cmd(struct wmi_t *wmip, u8 *buf, u32 len); #endif int wmi_set_bt_status_cmd(struct wmi_t *wmip, u8 streamType, u8 status); @@ -269,12 +269,12 @@ int wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * c int wmi_get_btcoex_stats_cmd(struct wmi_t * wmip); -int wmi_SGI_cmd(struct wmi_t *wmip, A_UINT32 sgiMask, u8 sgiPERThreshold); +int wmi_SGI_cmd(struct wmi_t *wmip, u32 sgiMask, u8 sgiPERThreshold); /* * This function is used to configure the fix rates mask to the target. */ -int wmi_set_fixrates_cmd(struct wmi_t *wmip, A_UINT32 fixRatesMask); +int wmi_set_fixrates_cmd(struct wmi_t *wmip, u32 fixRatesMask); int wmi_get_ratemask_cmd(struct wmi_t *wmip); int wmi_set_authmode_cmd(struct wmi_t *wmip, u8 mode); @@ -307,10 +307,10 @@ int wmi_add_wow_pattern_cmd(struct wmi_t *wmip, WMI_ADD_WOW_PATTERN_CMD *cmd, u8 *pattern, u8 *mask, u8 pattern_size); int wmi_del_wow_pattern_cmd(struct wmi_t *wmip, WMI_DEL_WOW_PATTERN_CMD *cmd); -int wmi_set_wsc_status_cmd(struct wmi_t *wmip, A_UINT32 status); +int wmi_set_wsc_status_cmd(struct wmi_t *wmip, u32 status); int -wmi_set_params_cmd(struct wmi_t *wmip, A_UINT32 opcode, A_UINT32 length, char *buffer); +wmi_set_params_cmd(struct wmi_t *wmip, u32 opcode, u32 length, char *buffer); int wmi_set_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4); @@ -323,18 +323,18 @@ wmi_mcast_filter_cmd(struct wmi_t *wmip, u8 enable); bss_t * wmi_find_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid, - A_UINT32 ssidLength, bool bIsWPA2, bool bMatchSSID); + u32 ssidLength, bool bIsWPA2, bool bMatchSSID); void wmi_node_return (struct wmi_t *wmip, bss_t *bss); void -wmi_set_nodeage(struct wmi_t *wmip, A_UINT32 nodeAge); +wmi_set_nodeage(struct wmi_t *wmip, u32 nodeAge); #if defined(CONFIG_TARGET_PROFILE_SUPPORT) -int wmi_prof_cfg_cmd(struct wmi_t *wmip, A_UINT32 period, A_UINT32 nbins); -int wmi_prof_addr_set_cmd(struct wmi_t *wmip, A_UINT32 addr); +int wmi_prof_cfg_cmd(struct wmi_t *wmip, u32 period, u32 nbins); +int wmi_prof_addr_set_cmd(struct wmi_t *wmip, u32 addr); int wmi_prof_start_cmd(struct wmi_t *wmip); int wmi_prof_stop_cmd(struct wmi_t *wmip); int wmi_prof_count_get_cmd(struct wmi_t *wmip); @@ -377,10 +377,10 @@ int wmi_set_pvb_cmd(struct wmi_t *wmip, u16 aid, bool flag); int -wmi_ap_conn_inact_time(struct wmi_t *wmip, A_UINT32 period); +wmi_ap_conn_inact_time(struct wmi_t *wmip, u32 period); int -wmi_ap_bgscan_time(struct wmi_t *wmip, A_UINT32 period, A_UINT32 dwell); +wmi_ap_bgscan_time(struct wmi_t *wmip, u32 period, u32 dwell); int wmi_ap_set_dtim(struct wmi_t *wmip, u8 dtim); @@ -398,7 +398,7 @@ int wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, u16 sz); int -wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, A_UINT32 *pMaskArray); +wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, u32 *pMaskArray); int wmi_setup_aggr_cmd(struct wmi_t *wmip, u8 tid); @@ -423,14 +423,13 @@ wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk); u16 wmi_ieee2freq (int chan); -A_UINT32 -wmi_freq2ieee (u16 freq); +u32 wmi_freq2ieee (u16 freq); bss_t * wmi_find_matching_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid, - A_UINT32 ssidLength, - A_UINT32 dot11AuthMode, A_UINT32 authMode, - A_UINT32 pairwiseCryptoType, A_UINT32 grpwiseCryptoTyp); + u32 ssidLength, + u32 dot11AuthMode, u32 authMode, + u32 pairwiseCryptoType, u32 grpwiseCryptoTyp); #ifdef __cplusplus } diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c index df23158b1097..7106a6a080f0 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c @@ -42,7 +42,7 @@ typedef struct { PSCmdPacket *HciCmdList; - A_UINT32 num_packets; + u32 num_packets; AR3K_CONFIG_INFO *dev; }HciCommandListParam; @@ -52,11 +52,11 @@ int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, u8 **ppEventBuffer, u8 **ppBufferToFree); -A_UINT32 Rom_Version; -A_UINT32 Build_Version; +u32 Rom_Version; +u32 Build_Version; extern bool BDADDR; -int getDeviceType(AR3K_CONFIG_INFO *pConfig, A_UINT32 * code); +int getDeviceType(AR3K_CONFIG_INFO *pConfig, u32 *code); int ReadVersionInfo(AR3K_CONFIG_INFO *pConfig); #ifndef HCI_TRANSPORT_SDIO @@ -66,7 +66,7 @@ A_UCHAR *HciEventpacket; rwlock_t syncLock; wait_queue_t Eventwait; -int PSHciWritepacket(struct hci_dev*,A_UCHAR* Data, A_UINT32 len); +int PSHciWritepacket(struct hci_dev*,A_UCHAR* Data, u32 len); extern char *bdaddr; #endif /* HCI_TRANSPORT_SDIO */ @@ -75,7 +75,7 @@ int write_bdaddr(AR3K_CONFIG_INFO *pConfig,A_UCHAR *bdaddr,int type); int PSSendOps(void *arg); #ifdef BT_PS_DEBUG -void Hci_log(A_UCHAR * log_string,A_UCHAR *data,A_UINT32 len) +void Hci_log(A_UCHAR * log_string,A_UCHAR *data,u32 len) { int i; AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s : ",log_string)); @@ -135,13 +135,13 @@ int PSSendOps(void *arg) int status = 0; PSCmdPacket *HciCmdList; /* List storing the commands */ const struct firmware* firmware; - A_UINT32 numCmds; + u32 numCmds; u8 *event; u8 *bufferToFree; struct hci_dev *device; A_UCHAR *buffer; - A_UINT32 len; - A_UINT32 DevType; + u32 len; + u32 DevType; A_UCHAR *PsFileName; A_UCHAR *patchFileName; A_UCHAR *path = NULL; @@ -531,12 +531,12 @@ int ReadVersionInfo(AR3K_CONFIG_INFO *pConfig) } return result; } -int getDeviceType(AR3K_CONFIG_INFO *pConfig, A_UINT32 * code) +int getDeviceType(AR3K_CONFIG_INFO *pConfig, u32 *code) { u8 hciCommand[] = {0x05,0xfc,0x05,0x00,0x00,0x00,0x00,0x04}; u8 *event; u8 *bufferToFree = NULL; - A_UINT32 reg; + u32 reg; int result = A_ERROR; *code = 0; hciCommand[3] = (u8)(FPGA_REGISTER & 0xFF); diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c index 0cbc73ce26fb..10f2900d596b 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c @@ -87,8 +87,8 @@ enum eType { typedef struct tPsTagEntry { - A_UINT32 TagId; - A_UINT32 TagLen; + u32 TagId; + u32 TagLen; u8 *TagData; } tPsTagEntry, *tpPsTagEntry; @@ -115,25 +115,25 @@ typedef struct ST_READ_STATUS { /* Stores the number of PS Tags */ -static A_UINT32 Tag_Count = 0; +static u32 Tag_Count = 0; /* Stores the number of patch commands */ -static A_UINT32 Patch_Count = 0; -static A_UINT32 Total_tag_lenght = 0; +static u32 Patch_Count = 0; +static u32 Total_tag_lenght = 0; bool BDADDR = false; -A_UINT32 StartTagId; +u32 StartTagId; tPsTagEntry PsTagEntry[RAMPS_MAX_PS_TAGS_PER_FILE]; tRamPatch RamPatch[MAX_NUM_PATCH_ENTRY]; -int AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat); -char AthReadChar(A_UCHAR *buffer, A_UINT32 len,A_UINT32 *pos); -char *AthGetLine(char *buffer, int maxlen, A_UCHAR *srcbuffer,A_UINT32 len,A_UINT32 *pos); -static int AthPSCreateHCICommand(A_UCHAR Opcode, A_UINT32 Param1,PSCmdPacket *PSPatchPacket,A_UINT32 *index); +int AthParseFilesUnified(A_UCHAR *srcbuffer,u32 srclen, int FileFormat); +char AthReadChar(A_UCHAR *buffer, u32 len,u32 *pos); +char *AthGetLine(char *buffer, int maxlen, A_UCHAR *srcbuffer,u32 len,u32 *pos); +static int AthPSCreateHCICommand(A_UCHAR Opcode, u32 Param1,PSCmdPacket *PSPatchPacket,u32 *index); /* Function to reads the next character from the input buffer */ -char AthReadChar(A_UCHAR *buffer, A_UINT32 len,A_UINT32 *pos) +char AthReadChar(A_UCHAR *buffer, u32 len,u32 *pos) { char Ch; if(buffer == NULL || *pos >=len ) @@ -315,14 +315,14 @@ unsigned int uReadDataInSection(char *pCharLine, ST_PS_DATA_FORMAT stPS_DataForm return (0x0FFF); } } -int AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat) +int AthParseFilesUnified(A_UCHAR *srcbuffer,u32 srclen, int FileFormat) { char *Buffer; char *pCharLine; u8 TagCount; u16 ByteCount; u8 ParseSection=RAM_PS_SECTION; - A_UINT32 pos; + u32 pos; @@ -558,7 +558,7 @@ int AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat) /********************/ -int GetNextTwoChar(A_UCHAR *srcbuffer,A_UINT32 len, A_UINT32 *pos, char *buffer) +int GetNextTwoChar(A_UCHAR *srcbuffer,u32 len, u32 *pos, char *buffer) { unsigned char ch; @@ -579,7 +579,7 @@ int GetNextTwoChar(A_UCHAR *srcbuffer,A_UINT32 len, A_UINT32 *pos, char *buffer) return A_OK; } -int AthDoParsePatch(A_UCHAR *patchbuffer, A_UINT32 patchlen) +int AthDoParsePatch(A_UCHAR *patchbuffer, u32 patchlen) { char Byte[3]; @@ -588,7 +588,7 @@ int AthDoParsePatch(A_UCHAR *patchbuffer, A_UINT32 patchlen) int count; int i,j,k; int data; - A_UINT32 filepos; + u32 filepos; Byte[2] = '\0'; j = 0; filepos = 0; @@ -659,7 +659,7 @@ int AthDoParsePatch(A_UCHAR *patchbuffer, A_UINT32 patchlen) /********************/ -int AthDoParsePS(A_UCHAR *srcbuffer, A_UINT32 srclen) +int AthDoParsePS(A_UCHAR *srcbuffer, u32 srclen) { int status; int i; @@ -713,7 +713,7 @@ int AthDoParsePS(A_UCHAR *srcbuffer, A_UINT32 srclen) return status; } -char *AthGetLine(char *buffer, int maxlen, A_UCHAR *srcbuffer,A_UINT32 len,A_UINT32 *pos) +char *AthGetLine(char *buffer, int maxlen, A_UCHAR *srcbuffer,u32 len,u32 *pos) { int count; @@ -764,13 +764,13 @@ static void LoadHeader(A_UCHAR *HCI_PS_Command,A_UCHAR opcode,int length,int ind ///////////////////////// // -int AthCreateCommandList(PSCmdPacket **HciPacketList, A_UINT32 *numPackets) +int AthCreateCommandList(PSCmdPacket **HciPacketList, u32 *numPackets) { u8 count; - A_UINT32 NumcmdEntry = 0; + u32 NumcmdEntry = 0; - A_UINT32 Crc = 0; + u32 Crc = 0; *numPackets = 0; @@ -785,7 +785,7 @@ int AthCreateCommandList(PSCmdPacket **HciPacketList, A_UINT32 *numPackets) if(Patch_Count > 0) { NumcmdEntry++; /* Patch Enable Command */ } - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Num Cmd Entries %d Size %d \r\n",NumcmdEntry,(A_UINT32)sizeof(PSCmdPacket) * NumcmdEntry)); + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Num Cmd Entries %d Size %d \r\n",NumcmdEntry,(u32)sizeof(PSCmdPacket) * NumcmdEntry)); (*HciPacketList) = A_MALLOC(sizeof(PSCmdPacket) * NumcmdEntry); if(NULL == *HciPacketList) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("memory allocation failed \r\n")); @@ -833,10 +833,10 @@ int AthCreateCommandList(PSCmdPacket **HciPacketList, A_UINT32 *numPackets) //////////////////////// ///////////// -static int AthPSCreateHCICommand(A_UCHAR Opcode, A_UINT32 Param1,PSCmdPacket *PSPatchPacket,A_UINT32 *index) +static int AthPSCreateHCICommand(A_UCHAR Opcode, u32 Param1,PSCmdPacket *PSPatchPacket,u32 *index) { A_UCHAR *HCI_PS_Command; - A_UINT32 Length; + u32 Length; int i,j; switch(Opcode) @@ -955,7 +955,7 @@ static int AthPSCreateHCICommand(A_UCHAR Opcode, A_UINT32 Param1,PSCmdPacket *PS } return A_OK; } -int AthFreeCommandList(PSCmdPacket **HciPacketList, A_UINT32 numPackets) +int AthFreeCommandList(PSCmdPacket **HciPacketList, u32 numPackets) { int i; if(*HciPacketList == NULL) { diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h index 13d1d095a456..fdc1c949ab80 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h @@ -48,13 +48,12 @@ /* Helper data type declaration */ -#ifndef A_UINT32 -#define A_UCHAR unsigned char -#define A_UINT32 unsigned long +#ifndef u32 #define A_UCHAR unsigned char +#define u32 unsigned long #define u16 unsigned short #define u8 unsigned char #define bool unsigned char -#endif /* A_UINT32 */ +#endif /* u32 */ #define ATH_DEBUG_ERR (1 << 0) #define ATH_DEBUG_WARN (1 << 1) @@ -104,10 +103,10 @@ typedef struct PSCmdPacket } PSCmdPacket; /* Parses a Patch information buffer and store it in global structure */ -int AthDoParsePatch(A_UCHAR *, A_UINT32); +int AthDoParsePatch(A_UCHAR *, u32 ); /* parses a PS information buffer and stores it in a global structure */ -int AthDoParsePS(A_UCHAR *, A_UINT32); +int AthDoParsePS(A_UCHAR *, u32 ); /* * Uses the output of Both AthDoParsePS and AthDoParsePatch APIs to form HCI command array with @@ -120,8 +119,8 @@ int AthDoParsePS(A_UCHAR *, A_UINT32); * PS Tag Command(s) * */ -int AthCreateCommandList(PSCmdPacket **, A_UINT32 *); +int AthCreateCommandList(PSCmdPacket **, u32 *); /* Cleanup the dynamically allicated HCI command list */ -int AthFreeCommandList(PSCmdPacket **HciPacketList, A_UINT32 numPackets); +int AthFreeCommandList(PSCmdPacket **HciPacketList, u32 numPackets); #endif /* __AR3KPSPARSER_H */ diff --git a/drivers/staging/ath6kl/miscdrv/common_drv.c b/drivers/staging/ath6kl/miscdrv/common_drv.c index 1d51d2a34e1d..d0485bf4229d 100644 --- a/drivers/staging/ath6kl/miscdrv/common_drv.c +++ b/drivers/staging/ath6kl/miscdrv/common_drv.c @@ -83,7 +83,7 @@ static u8 custDataAR6003[AR6003_CUST_DATA_SIZE]; #ifdef USE_4BYTE_REGISTER_ACCESS /* set the window address register (using 4-byte register access ). */ -int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr, A_UINT32 Address) +int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, u32 RegisterAddr, u32 Address) { int status; u8 addrValue[4]; @@ -144,7 +144,7 @@ int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr #else /* set the window address register */ -int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr, A_UINT32 Address) +int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, u32 RegisterAddr, u32 Address) { int status; @@ -153,7 +153,7 @@ int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr status = HIFReadWrite(hifDevice, RegisterAddr+1, /* write upper 3 bytes */ ((A_UCHAR *)(&Address))+1, - sizeof(A_UINT32)-1, + sizeof(u32)-1, HIF_WR_SYNC_BYTE_INC, NULL); @@ -187,7 +187,7 @@ int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr * No cooperation from the Target is required for this. */ int -ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data) +ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data) { int status; @@ -204,7 +204,7 @@ ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data) status = HIFReadWrite(hifDevice, WINDOW_DATA_ADDRESS, (A_UCHAR *)data, - sizeof(A_UINT32), + sizeof(u32), HIF_RD_SYNC_BYTE_INC, NULL); if (status != A_OK) { @@ -221,7 +221,7 @@ ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data) * No cooperation from the Target is required for this. */ int -ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data) +ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data) { int status; @@ -229,7 +229,7 @@ ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data) status = HIFReadWrite(hifDevice, WINDOW_DATA_ADDRESS, (A_UCHAR *)data, - sizeof(A_UINT32), + sizeof(u32), HIF_WR_SYNC_BYTE_INC, NULL); if (status != A_OK) { @@ -244,15 +244,15 @@ ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data) } int -ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, - A_UCHAR *data, A_UINT32 length) +ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, u32 address, + A_UCHAR *data, u32 length) { - A_UINT32 count; + u32 count; int status = A_OK; for (count = 0; count < length; count += 4, address += 4) { if ((status = ar6000_ReadRegDiag(hifDevice, &address, - (A_UINT32 *)&data[count])) != A_OK) + (u32 *)&data[count])) != A_OK) { break; } @@ -262,15 +262,15 @@ ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, } int -ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, - A_UCHAR *data, A_UINT32 length) +ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, u32 address, + A_UCHAR *data, u32 length) { - A_UINT32 count; + u32 count; int status = A_OK; for (count = 0; count < length; count += 4, address += 4) { if ((status = ar6000_WriteRegDiag(hifDevice, &address, - (A_UINT32 *)&data[count])) != A_OK) + (u32 *)&data[count])) != A_OK) { break; } @@ -280,7 +280,7 @@ ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, } int -ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, A_UINT32 *regval) +ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, u32 *regval) { int status; A_UCHAR vals[4]; @@ -316,10 +316,10 @@ ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, A_UINT32 *regval) } void -ar6k_FetchTargetRegs(HIF_DEVICE *hifDevice, A_UINT32 *targregs) +ar6k_FetchTargetRegs(HIF_DEVICE *hifDevice, u32 *targregs) { int i; - A_UINT32 val; + u32 val; for (i=0; i\n", length, pDescription); @@ -933,7 +933,7 @@ void a_dump_module_debug_info_by_name(char *module_name) } -int a_get_module_mask(char *module_name, A_UINT32 *pMask) +int a_get_module_mask(char *module_name, u32 *pMask) { ATH_DEBUG_MODULE_DBG_INFO *pInfo = FindModule(module_name); @@ -945,7 +945,7 @@ int a_get_module_mask(char *module_name, A_UINT32 *pMask) return A_OK; } -int a_set_module_mask(char *module_name, A_UINT32 Mask) +int a_set_module_mask(char *module_name, u32 Mask) { ATH_DEBUG_MODULE_DBG_INFO *pInfo = FindModule(module_name); @@ -999,8 +999,8 @@ void a_module_debug_support_cleanup(void) /* can only be called during bmi init stage */ int ar6000_set_hci_bridge_flags(HIF_DEVICE *hifDevice, - A_UINT32 TargetType, - A_UINT32 Flags) + u32 TargetType, + u32 Flags) { int status = A_OK; diff --git a/drivers/staging/ath6kl/miscdrv/miscdrv.h b/drivers/staging/ath6kl/miscdrv/miscdrv.h index ae24b728c4ad..41be5670db42 100644 --- a/drivers/staging/ath6kl/miscdrv/miscdrv.h +++ b/drivers/staging/ath6kl/miscdrv/miscdrv.h @@ -27,7 +27,7 @@ #define HOST_INTEREST_ITEM_ADDRESS(target, item) \ AR6002_HOST_INTEREST_ITEM_ADDRESS(item) -A_UINT32 ar6kRev2Array[][128] = { +u32 ar6kRev2Array[][128] = { {0xFFFF, 0xFFFF}, // No Patches }; diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 9f7a02f50855..89ff8f483e13 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -207,7 +207,7 @@ unsigned int _mboxnum = HTC_MAILBOX_NUM_MAX; #define mboxnum &_mboxnum #ifdef DEBUG -A_UINT32 g_dbg_flags = DBG_DEFAULTS; +u32 g_dbg_flags = DBG_DEFAULTS; unsigned int debugflags = 0; int debugdriver = 0; unsigned int debughtc = 0; @@ -264,7 +264,7 @@ typedef struct user_rssi_compensation_t { A_INT16 bg_param_b; A_INT16 a_param_a; A_INT16 a_param_b; - A_UINT32 reserved; + u32 reserved; } USER_RSSI_CPENSATION; static USER_RSSI_CPENSATION rssi_compensation_param; @@ -354,7 +354,7 @@ static void ar6000_sysfs_bmi_deinit(AR_SOFTC_T *ar); int -ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode); +ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, u32 mode); /* * Static variables @@ -405,7 +405,7 @@ static struct net_device_ops ar6000_netdev_ops = { int ar6000_set_host_app_area(AR_SOFTC_T *ar) { - A_UINT32 address, data; + u32 address, data; struct host_app_area_s host_app_area; /* Fetch the address of the host_app_area_s instance in the host interest area */ @@ -425,11 +425,10 @@ ar6000_set_host_app_area(AR_SOFTC_T *ar) return A_OK; } -A_UINT32 -dbglog_get_debug_hdr_ptr(AR_SOFTC_T *ar) +u32 dbglog_get_debug_hdr_ptr(AR_SOFTC_T *ar) { - A_UINT32 param; - A_UINT32 address; + u32 param; + u32 address; int status; address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbglog_hdr)); @@ -452,14 +451,13 @@ ar6000_dbglog_init_done(AR_SOFTC_T *ar) ar->dbglog_init_done = true; } -A_UINT32 -dbglog_get_debug_fragment(A_INT8 *datap, A_UINT32 len, A_UINT32 limit) +u32 dbglog_get_debug_fragment(A_INT8 *datap, u32 len, u32 limit) { A_INT32 *buffer; - A_UINT32 count; - A_UINT32 numargs; - A_UINT32 length; - A_UINT32 fraglen; + u32 count; + u32 numargs; + u32 length; + u32 fraglen; count = fraglen = 0; buffer = (A_INT32 *)datap; @@ -479,15 +477,15 @@ dbglog_get_debug_fragment(A_INT8 *datap, A_UINT32 len, A_UINT32 limit) } void -dbglog_parse_debug_logs(A_INT8 *datap, A_UINT32 len) +dbglog_parse_debug_logs(A_INT8 *datap, u32 len) { A_INT32 *buffer; - A_UINT32 count; - A_UINT32 timestamp; - A_UINT32 debugid; - A_UINT32 moduleid; - A_UINT32 numargs; - A_UINT32 length; + u32 count; + u32 timestamp; + u32 debugid; + u32 moduleid; + u32 numargs; + u32 length; count = 0; buffer = (A_INT32 *)datap; @@ -522,12 +520,12 @@ dbglog_parse_debug_logs(A_INT8 *datap, A_UINT32 len) int ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar) { - A_UINT32 data[8]; /* Should be able to accomodate struct dbglog_buf_s */ - A_UINT32 address; - A_UINT32 length; - A_UINT32 dropped; - A_UINT32 firstbuf; - A_UINT32 debug_hdr_ptr; + u32 data[8]; /* Should be able to accomodate struct dbglog_buf_s */ + u32 address; + u32 length; + u32 dropped; + u32 firstbuf; + u32 debug_hdr_ptr; if (!ar->dbglog_init_done) return A_ERROR; @@ -598,8 +596,8 @@ ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar) } void -ar6000_dbglog_event(AR_SOFTC_T *ar, A_UINT32 dropped, - A_INT8 *buffer, A_UINT32 length) +ar6000_dbglog_event(AR_SOFTC_T *ar, u32 dropped, + A_INT8 *buffer, u32 length) { #ifdef REPORT_DEBUG_LOGS_TO_APP #define MAX_WIRELESS_EVENT_SIZE 252 @@ -608,7 +606,7 @@ ar6000_dbglog_event(AR_SOFTC_T *ar, A_UINT32 dropped, * There seems to be a limitation on the length of message that could be * transmitted to the user app via this mechanism. */ - A_UINT32 send, sent; + u32 send, sent; sent = 0; send = dbglog_get_debug_fragment(&buffer[sent], length - sent, @@ -738,8 +736,8 @@ ar6000_cleanup_module(void) void aptcTimerHandler(unsigned long arg) { - A_UINT32 numbytes; - A_UINT32 throughput; + u32 numbytes; + u32 throughput; AR_SOFTC_T *ar; int status; @@ -807,7 +805,7 @@ ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj, AR_SOFTC_T *ar; HIF_DEVICE_OS_DEVICE_INFO *osDevInfo; - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Read %d bytes\n", (A_UINT32)count)); + AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Read %d bytes\n", (u32)count)); for (index=0; index < MAX_AR6000; index++) { ar = (AR_SOFTC_T *)ar6k_priv(ar6000_devices[index]); osDevInfo = &ar->osDevInfo; @@ -834,7 +832,7 @@ ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj, AR_SOFTC_T *ar; HIF_DEVICE_OS_DEVICE_INFO *osDevInfo; - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Write %d bytes\n", (A_UINT32)count)); + AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Write %d bytes\n", (u32)count)); for (index=0; index < MAX_AR6000; index++) { ar = (AR_SOFTC_T *)ar6k_priv(ar6000_devices[index]); osDevInfo = &ar->osDevInfo; @@ -902,13 +900,13 @@ ar6000_sysfs_bmi_deinit(AR_SOFTC_T *ar) #define AR6002_MAC_ADDRESS_OFFSET 0x0A #define AR6003_MAC_ADDRESS_OFFSET 0x16 static -void calculate_crc(A_UINT32 TargetType, A_UCHAR *eeprom_data) +void calculate_crc(u32 TargetType, A_UCHAR *eeprom_data) { u16 *ptr_crc; u16 *ptr16_eeprom; u16 checksum; - A_UINT32 i; - A_UINT32 eeprom_size; + u32 i; + u32 eeprom_size; if (TargetType == TARGET_TYPE_AR6001) { @@ -994,12 +992,12 @@ ar6000_softmac_update(AR_SOFTC_T *ar, A_UCHAR *eeprom_data, size_t size) #endif /* SOFTMAC_FILE_USED */ static int -ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, bool compressed) +ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, u32 address, bool compressed) { int status; const char *filename; const struct firmware *fw_entry; - A_UINT32 fw_entry_size; + u32 fw_entry_size; switch (file) { case AR6K_OTP_FILE: @@ -1108,9 +1106,9 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, b /* Load extended board data for AR6003 */ if ((file==AR6K_BOARD_DATA_FILE) && (fw_entry->data)) { - A_UINT32 board_ext_address; - A_UINT32 board_ext_data_size; - A_UINT32 board_data_size; + u32 board_ext_address; + u32 board_ext_data_size; + u32 board_data_size; board_ext_data_size = (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_BOARD_EXT_DATA_SZ : \ (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_BOARD_EXT_DATA_SZ : 0)); @@ -1124,7 +1122,7 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, b /* check whether the target has allocated memory for extended board data and file contains extended board data */ if ((board_ext_address) && (fw_entry->size == (board_data_size + board_ext_data_size))) { - A_UINT32 param; + u32 param; status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (A_UCHAR *)(fw_entry->data + board_data_size), board_ext_data_size); @@ -1162,7 +1160,7 @@ ar6000_update_bdaddr(AR_SOFTC_T *ar) { if (setupbtdev != 0) { - A_UINT32 address; + u32 address; if (BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (A_UCHAR *)&address, 4) != A_OK) @@ -1185,7 +1183,7 @@ return A_OK; } int -ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode) +ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, u32 mode) { AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Requesting device specific configuration\n")); @@ -1206,7 +1204,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode) } else { /* The config is contained within the driver itself */ int status; - A_UINT32 param, options, sleep, address; + u32 param, options, sleep, address; /* Temporarily disable system sleep */ address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS; @@ -1402,7 +1400,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode) int ar6000_configure_target(AR_SOFTC_T *ar) { - A_UINT32 param; + u32 param; if (enableuartprint) { param = 1; if (BMIWriteMemory(ar->arHifDevice, @@ -1435,7 +1433,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) } #endif if (enabletimerwar) { - A_UINT32 param; + u32 param; if (BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), @@ -1461,7 +1459,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) /* set the firmware mode to STA/IBSS/AP */ { - A_UINT32 param; + u32 param; if (BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), @@ -1487,7 +1485,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) #ifdef ATH6KL_DISABLE_TARGET_DBGLOGS { - A_UINT32 param; + u32 param; if (BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), @@ -2778,7 +2776,7 @@ ar6000_bitrate_rx(void *devt, A_INT32 rateKbps) } void -ar6000_ratemask_rx(void *devt, A_UINT32 ratemask) +ar6000_ratemask_rx(void *devt, u32 ratemask) { AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; @@ -2807,12 +2805,12 @@ ar6000_channelList_rx(void *devt, A_INT8 numChan, u16 *chanList) wake_up(&arEvent); } -u8 ar6000_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, A_UINT32 * mapNo) +u8 ar6000_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, u32 *mapNo) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); u8 *datap; ATH_MAC_HDR *macHdr; - A_UINT32 i, eptMap; + u32 i, eptMap; (*mapNo) = 0; datap = A_NETBUF_DATA(skb); @@ -2888,7 +2886,7 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); u8 ac = AC_NOT_MAPPED; HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED; - A_UINT32 mapNo = 0; + u32 mapNo = 0; int len; struct ar_cookie *cookie; bool checkAdHocPsMapping = false,bMoreData = false; @@ -3265,9 +3263,9 @@ tvsub(register struct timeval *out, register struct timeval *in) void applyAPTCHeuristics(AR_SOFTC_T *ar) { - A_UINT32 duration; - A_UINT32 numbytes; - A_UINT32 throughput; + u32 duration; + u32 numbytes; + u32 throughput; struct timeval ts; int status; @@ -3390,7 +3388,7 @@ static void ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPacketQueue) { AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; - A_UINT32 mapNo = 0; + u32 mapNo = 0; int status; struct ar_cookie * ar_cookie; HTC_ENDPOINT_ID eid; @@ -3480,7 +3478,7 @@ ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPacketQueue) ar->arNodeMap[mapNo].txPending --; if (!ar->arNodeMap[mapNo].txPending && (mapNo == (ar->arNodeNum - 1))) { - A_UINT32 i; + u32 i; for (i = ar->arNodeNum; i > 0; i --) { if (!ar->arNodeMap[i - 1].txPending) { A_MEMZERO(&ar->arNodeMap[i - 1], sizeof(struct ar_node_mapping)); @@ -4160,7 +4158,7 @@ err_exit: } void -ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, A_UINT32 sw_ver, A_UINT32 abi_ver) +ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, u32 sw_ver, u32 abi_ver) { AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; struct net_device *dev = ar->arNetDev; @@ -4508,7 +4506,7 @@ skip_key: } -void ar6000_set_numdataendpts(AR_SOFTC_T *ar, A_UINT32 num) +void ar6000_set_numdataendpts(AR_SOFTC_T *ar, u32 num) { A_ASSERT(num <= (HTC_MAILBOX_NUM_MAX - 1)); ar->arNumDataEndPts = num; @@ -4718,7 +4716,7 @@ ar6000_disconnect_event(AR_SOFTC_T *ar, u8 reason, u8 *bssid, } void -ar6000_regDomain_event(AR_SOFTC_T *ar, A_UINT32 regCode) +ar6000_regDomain_event(AR_SOFTC_T *ar, u32 regCode) { A_PRINTF("AR6000 Reg Code = 0x%x\n", regCode); ar->arRegCode = regCode; @@ -4907,7 +4905,7 @@ ar6000_scanComplete_event(AR_SOFTC_T *ar, int status) } void -ar6000_targetStats_event(AR_SOFTC_T *ar, u8 *ptr, A_UINT32 len) +ar6000_targetStats_event(AR_SOFTC_T *ar, u8 *ptr, u32 len) { u8 ac; @@ -5053,7 +5051,7 @@ ar6000_rssiThreshold_event(AR_SOFTC_T *ar, WMI_RSSI_THRESHOLD_VAL newThreshold, void -ar6000_hbChallengeResp_event(AR_SOFTC_T *ar, A_UINT32 cookie, A_UINT32 source) +ar6000_hbChallengeResp_event(AR_SOFTC_T *ar, u32 cookie, u32 source) { if (source == APP_HB_CHALLENGE) { /* Report it to the app in case it wants a positive acknowledgement */ @@ -5262,7 +5260,7 @@ ar6000_bssInfo_event_rx(AR_SOFTC_T *ar, u8 *datap, int len) } } -A_UINT32 wmiSendCmdNum; +u32 wmiSendCmdNum; int ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid) @@ -5404,7 +5402,7 @@ void ar6000_indicate_tx_activity(void *devt, u8 TrafficClass, bool Active) } void -ar6000_btcoex_config_event(struct ar6_softc *ar, u8 *ptr, A_UINT32 len) +ar6000_btcoex_config_event(struct ar6_softc *ar, u8 *ptr, u32 len) { WMI_BTCOEX_CONFIG_EVENT *pBtcoexConfig = (WMI_BTCOEX_CONFIG_EVENT *)ptr; @@ -5441,7 +5439,7 @@ ar6000_btcoex_config_event(struct ar6_softc *ar, u8 *ptr, A_UINT32 len) } void -ar6000_btcoex_stats_event(struct ar6_softc *ar, u8 *ptr, A_UINT32 len) +ar6000_btcoex_stats_event(struct ar6_softc *ar, u8 *ptr, u32 len) { WMI_BTCOEX_STATS_EVENT *pBtcoexStats = (WMI_BTCOEX_STATS_EVENT *)ptr; @@ -5462,7 +5460,7 @@ module_exit(ar6000_cleanup_module); static void ar6000_cookie_init(AR_SOFTC_T *ar) { - A_UINT32 i; + u32 i; ar->arCookieList = NULL; ar->arCookieCount = 0; @@ -5633,14 +5631,12 @@ ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL newThreshold, u8 lq) -A_UINT32 -a_copy_to_user(void *to, const void *from, A_UINT32 n) +u32 a_copy_to_user(void *to, const void *from, u32 n) { return(copy_to_user(to, from, n)); } -A_UINT32 -a_copy_from_user(void *to, const void *from, A_UINT32 n) +u32 a_copy_from_user(void *to, const void *from, u32 n) { return(copy_from_user(to, from, n)); } @@ -5657,10 +5653,10 @@ ar6000_get_driver_cfg(struct net_device *dev, switch(cfgParam) { case AR6000_DRIVER_CFG_GET_WLANNODECACHING: - *((A_UINT32 *)result) = wlanNodeCaching; + *((u32 *)result) = wlanNodeCaching; break; case AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS: - *((A_UINT32 *)result) = logWmiRawMsgs; + *((u32 *)result) = logWmiRawMsgs; break; default: ret = EINVAL; @@ -5811,7 +5807,7 @@ read_rssi_compensation_param(AR_SOFTC_T *ar) rssi_compensation_param.bg_param_b = *(u16 *)(cust_data_ptr+6) & 0xffff; rssi_compensation_param.a_param_a = *(u16 *)(cust_data_ptr+8) & 0xffff; rssi_compensation_param.a_param_b = *(u16 *)(cust_data_ptr+10) &0xffff; - rssi_compensation_param.reserved = *(A_UINT32 *)(cust_data_ptr+12); + rssi_compensation_param.reserved = *(u32 *)(cust_data_ptr+12); #ifdef RSSICOMPENSATION_PRINT A_PRINTF("customerID = 0x%x \n", rssi_compensation_param.customerID); @@ -5831,7 +5827,7 @@ read_rssi_compensation_param(AR_SOFTC_T *ar) } A_INT32 -rssi_compensation_calc_tcmd(A_UINT32 freq, A_INT32 rssi, A_UINT32 totalPkt) +rssi_compensation_calc_tcmd(u32 freq, A_INT32 rssi, u32 totalPkt) { if (freq > 5000) @@ -6007,17 +6003,17 @@ _reinstall_keys_out: void ar6000_dset_open_req( void *context, - A_UINT32 id, - A_UINT32 targHandle, - A_UINT32 targReplyFn, - A_UINT32 targReplyArg) + u32 id, + u32 targHandle, + u32 targReplyFn, + u32 targReplyArg) { } void ar6000_dset_close( void *context, - A_UINT32 access_cookie) + u32 access_cookie) { return; } @@ -6025,12 +6021,12 @@ ar6000_dset_close( void ar6000_dset_data_req( void *context, - A_UINT32 accessCookie, - A_UINT32 offset, - A_UINT32 length, - A_UINT32 targBuf, - A_UINT32 targReplyFn, - A_UINT32 targReplyArg) + u32 accessCookie, + u32 offset, + u32 length, + u32 targBuf, + u32 targReplyFn, + u32 targReplyArg) { } diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c index 7e680a540713..691e535403a1 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_pm.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_pm.c @@ -194,7 +194,7 @@ static void ar6000_wow_suspend(AR_SOFTC_T *ar) ar->arWowState = WLAN_WOW_STATE_SUSPENDING; if (ar->arTxPending[ar->arControlEp]) { - A_UINT32 timeleft = wait_event_interruptible_timeout(arEvent, + u32 timeleft = wait_event_interruptible_timeout(arEvent, ar->arTxPending[ar->arControlEp] == 0, wmitimeout * HZ); if (!timeleft || signal_pending(current)) { /* what can I do? wow resume at once */ @@ -290,7 +290,7 @@ void ar6000_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, bool isEvent) } } -int ar6000_power_change_ev(void *context, A_UINT32 config) +int ar6000_power_change_ev(void *context, u32 config) { AR_SOFTC_T *ar = (AR_SOFTC_T *)context; int status = A_OK; @@ -375,7 +375,7 @@ ar6000_setup_cut_power_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) if (status == A_PENDING) { #ifdef ANDROID_ENV /* Wait for WMI ready event */ - A_UINT32 timeleft = wait_event_interruptible_timeout(arEvent, + u32 timeleft = wait_event_interruptible_timeout(arEvent, (ar->arWmiReady == true), wmitimeout * HZ); if (!timeleft || signal_pending(current)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000 : Failed to get wmi ready \n")); @@ -516,7 +516,7 @@ ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) break; } if (ar->arTxPending[ar->arControlEp]) { - A_UINT32 timeleft = wait_event_interruptible_timeout(arEvent, + u32 timeleft = wait_event_interruptible_timeout(arEvent, ar->arTxPending[ar->arControlEp] == 0, wmitimeout * HZ); if (!timeleft || signal_pending(current)) { status = A_ERROR; @@ -651,7 +651,7 @@ ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool } int -ar6000_set_bt_hw_state(struct ar6_softc *ar, A_UINT32 enable) +ar6000_set_bt_hw_state(struct ar6_softc *ar, u32 enable) { #ifdef CONFIG_PM bool off = (enable == 0); diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index 332b336c3391..dcbb062818c7 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -183,7 +183,7 @@ ar6k_set_auth_type(AR_SOFTC_T *ar, enum nl80211_auth_type auth_type) } static int -ar6k_set_cipher(AR_SOFTC_T *ar, A_UINT32 cipher, bool ucast) +ar6k_set_cipher(AR_SOFTC_T *ar, u32 cipher, bool ucast) { u8 *ar_cipher = ucast ? &ar->arPairwiseCrypto : &ar->arGroupCrypto; @@ -225,7 +225,7 @@ ar6k_set_cipher(AR_SOFTC_T *ar, A_UINT32 cipher, bool ucast) } static void -ar6k_set_key_mgmt(AR_SOFTC_T *ar, A_UINT32 key_mgmt) +ar6k_set_key_mgmt(AR_SOFTC_T *ar, u32 key_mgmt) { AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, key_mgmt)); @@ -726,7 +726,7 @@ ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); int ret = 0; - A_UINT32 forceFgScan = 0; + u32 forceFgScan = 0; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); @@ -1056,7 +1056,7 @@ ar6k_cfg80211_tkip_micerr_event(AR_SOFTC_T *ar, u8 keyid, bool ismcast) } static int -ar6k_cfg80211_set_wiphy_params(struct wiphy *wiphy, A_UINT32 changed) +ar6k_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) { AR_SOFTC_T *ar = (AR_SOFTC_T *)wiphy_priv(wiphy); @@ -1365,7 +1365,7 @@ ar6k_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) static const -A_UINT32 cipher_suites[] = { +u32 cipher_suites[] = { WLAN_CIPHER_SUITE_WEP40, WLAN_CIPHER_SUITE_WEP104, WLAN_CIPHER_SUITE_TKIP, diff --git a/drivers/staging/ath6kl/os/linux/eeprom.c b/drivers/staging/ath6kl/os/linux/eeprom.c index 13cd014b4b6b..7d7a63dd6f0e 100644 --- a/drivers/staging/ath6kl/os/linux/eeprom.c +++ b/drivers/staging/ath6kl/os/linux/eeprom.c @@ -54,7 +54,7 @@ char *p_mac = NULL; // static A_UCHAR eeprom_data[EEPROM_SZ]; -static A_UINT32 sys_sleep_reg; +static u32 sys_sleep_reg; static HIF_DEVICE *p_bmi_device; // @@ -127,28 +127,28 @@ update_mac(unsigned char *eeprom, int size, unsigned char *macaddr) /* Read a Target register and return its value. */ inline void -BMI_read_reg(A_UINT32 address, A_UINT32 *pvalue) +BMI_read_reg(u32 address, u32 *pvalue) { BMIReadSOCRegister(p_bmi_device, address, pvalue); } /* Write a value to a Target register. */ inline void -BMI_write_reg(A_UINT32 address, A_UINT32 value) +BMI_write_reg(u32 address, u32 value) { BMIWriteSOCRegister(p_bmi_device, address, value); } /* Read Target memory word and return its value. */ inline void -BMI_read_mem(A_UINT32 address, A_UINT32 *pvalue) +BMI_read_mem(u32 address, u32 *pvalue) { BMIReadMemory(p_bmi_device, address, (A_UCHAR*)(pvalue), 4); } /* Write a word to a Target memory. */ inline void -BMI_write_mem(A_UINT32 address, u8 *p_data, A_UINT32 sz) +BMI_write_mem(u32 address, u8 *p_data, u32 sz) { BMIWriteMemory(p_bmi_device, address, (A_UCHAR*)(p_data), sz); } @@ -160,7 +160,7 @@ BMI_write_mem(A_UINT32 address, u8 *p_data, A_UINT32 sz) static void enable_SI(HIF_DEVICE *p_device) { - A_UINT32 regval; + u32 regval; printk("%s\n", __FUNCTION__); @@ -200,7 +200,7 @@ enable_SI(HIF_DEVICE *p_device) static void disable_SI(void) { - A_UINT32 regval; + u32 regval; printk("%s\n", __FUNCTION__); @@ -218,7 +218,7 @@ disable_SI(void) static void request_8byte_read(int offset) { - A_UINT32 regval; + u32 regval; // printk("%s: request_8byte_read from offset 0x%x\n", __FUNCTION__, offset); @@ -241,9 +241,9 @@ request_8byte_read(int offset) * writing values from Target TX_DATA registers. */ static void -request_4byte_write(int offset, A_UINT32 data) +request_4byte_write(int offset, u32 data) { - A_UINT32 regval; + u32 regval; printk("%s: request_4byte_write (0x%x) to offset 0x%x\n", __FUNCTION__, data, offset); @@ -269,7 +269,7 @@ request_4byte_write(int offset, A_UINT32 data) static bool request_in_progress(void) { - A_UINT32 regval; + u32 regval; /* Wait for DONE_INT in SI_CS */ BMI_read_reg(SI_BASE_ADDRESS+SI_CS_OFFSET, ®val); @@ -288,7 +288,7 @@ request_in_progress(void) static void eeprom_type_detect(void) { - A_UINT32 regval; + u32 regval; u8 i = 0; request_8byte_read(0x100); @@ -310,7 +310,7 @@ static void eeprom_type_detect(void) * and return them to the caller. */ inline void -read_8byte_results(A_UINT32 *data) +read_8byte_results(u32 *data) { /* Read SI_RX_DATA0 and SI_RX_DATA1 */ BMI_read_reg(SI_BASE_ADDRESS+SI_RX_DATA0_OFFSET, &data[0]); @@ -339,7 +339,7 @@ wait_for_eeprom_completion(void) * waits for it to complete, and returns the result. */ static void -fetch_8bytes(int offset, A_UINT32 *data) +fetch_8bytes(int offset, u32 *data) { request_8byte_read(offset); wait_for_eeprom_completion(); @@ -354,7 +354,7 @@ fetch_8bytes(int offset, A_UINT32 *data) * and waits for it to complete. */ inline void -commit_4bytes(int offset, A_UINT32 data) +commit_4bytes(int offset, u32 data) { request_4byte_write(offset, data); wait_for_eeprom_completion(); @@ -363,8 +363,8 @@ commit_4bytes(int offset, A_UINT32 data) #ifdef ANDROID_ENV void eeprom_ar6000_transfer(HIF_DEVICE *device, char *fake_file, char *p_mac) { - A_UINT32 first_word; - A_UINT32 board_data_addr; + u32 first_word; + u32 board_data_addr; int i; printk("%s: Enter\n", __FUNCTION__); @@ -437,17 +437,17 @@ void eeprom_ar6000_transfer(HIF_DEVICE *device, char *fake_file, char *p_mac) * Fetch EEPROM_SZ Bytes of Board Data, 8 bytes at a time. */ - fetch_8bytes(0, (A_UINT32 *)(&eeprom_data[0])); + fetch_8bytes(0, (u32 *)(&eeprom_data[0])); /* Check the first word of EEPROM for validity */ - first_word = *((A_UINT32 *)eeprom_data); + first_word = *((u32 *)eeprom_data); if ((first_word == 0) || (first_word == 0xffffffff)) { printk("Did not find EEPROM with valid Board Data.\n"); } for (i=8; ipHCIDev = HCIHandle; diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index a439370caa01..c966f495ba5c 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -121,8 +121,8 @@ struct USER_SAVEDKEYS { #define DBG_DEFAULTS (DBG_ERROR|DBG_WARNING) -int ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); -int ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data); +int ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data); +int ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data); #ifdef __cplusplus extern "C" { @@ -391,7 +391,7 @@ struct ar_key { u8 key_len; u8 seq[IW_ENCODE_SEQ_MAX_SIZE]; u8 seq_len; - A_UINT32 cipher; + u32 cipher; }; #endif /* ATH6K_CONFIG_CFG80211 */ @@ -410,8 +410,8 @@ struct ar_cookie { struct ar_hb_chlng_resp { A_TIMER timer; - A_UINT32 frequency; - A_UINT32 seqNum; + u32 frequency; + u32 seqNum; bool outstanding; u8 missCnt; u8 missThres; @@ -492,7 +492,7 @@ typedef struct ar6_softc { u16 arListenIntervalB; u16 arListenIntervalT; struct ar6000_version arVersion; - A_UINT32 arTargetType; + u32 arTargetType; A_INT8 arRssi; u8 arTxPwr; bool arTxPwrSet; @@ -501,19 +501,19 @@ typedef struct ar6_softc { struct iw_statistics arIwStats; A_INT8 arNumChannels; u16 arChannelList[32]; - A_UINT32 arRegCode; + u32 arRegCode; bool statsUpdatePending; TARGET_STATS arTargetStats; A_INT8 arMaxRetries; u8 arPhyCapability; #ifdef CONFIG_HOST_TCMD_SUPPORT u8 tcmdRxReport; - A_UINT32 tcmdRxTotalPkt; + u32 tcmdRxTotalPkt; A_INT32 tcmdRxRssi; - A_UINT32 tcmdPm; - A_UINT32 arTargetMode; - A_UINT32 tcmdRxcrcErrPkt; - A_UINT32 tcmdRxsecErrPkt; + u32 tcmdPm; + u32 arTargetMode; + u32 tcmdRxcrcErrPkt; + u32 tcmdRxsecErrPkt; u16 tcmdRateCnt[TCMD_MAX_RATES]; u16 tcmdRateCntShortGuard[TCMD_MAX_RATES]; #endif @@ -523,15 +523,15 @@ typedef struct ar6_softc { u8 arNodeNum; u8 arNexEpId; struct ar_cookie *arCookieList; - A_UINT32 arCookieCount; - A_UINT32 arRateMask; + u32 arCookieCount; + u32 arRateMask; u8 arSkipScan; u16 arBeaconInterval; bool arConnectPending; bool arWmmEnabled; struct ar_hb_chlng_resp arHBChallengeResp; u8 arKeepaliveConfigured; - A_UINT32 arMgmtFilter; + u32 arMgmtFilter; HTC_ENDPOINT_ID arAc2EpMapping[WMM_NUM_AC]; bool arAcStreamActive[WMM_NUM_AC]; u8 arAcStreamPriMap[WMM_NUM_AC]; @@ -548,12 +548,12 @@ typedef struct ar6_softc { bool arWMIControlEpFull; bool dbgLogFetchInProgress; A_UCHAR log_buffer[DBGLOG_HOST_LOG_BUFFER_SIZE]; - A_UINT32 log_cnt; - A_UINT32 dbglog_init_done; - A_UINT32 arConnectCtrlFlags; + u32 log_cnt; + u32 dbglog_init_done; + u32 arConnectCtrlFlags; #ifdef USER_KEYS A_INT32 user_savedkeys_stat; - A_UINT32 user_key_ctrl; + u32 user_key_ctrl; struct USER_SAVEDKEYS user_saved_keys; #endif USER_RSSI_THOLD rssi_map[12]; @@ -674,7 +674,7 @@ static inline void *ar6k_priv(struct net_device *dev) struct ar_giwscan_param { char *current_ev; char *end_buf; - A_UINT32 bytes_needed; + u32 bytes_needed; struct iw_request_info *info; }; diff --git a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h index 04094f91063b..d21ca879bfff 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h @@ -30,7 +30,7 @@ extern "C" { struct ar6_softc; void ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, - A_UINT32 sw_ver, A_UINT32 abi_ver); + u32 sw_ver, u32 abi_ver); int ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid); void ar6000_connect_event(struct ar6_softc *ar, u16 channel, u8 *bssid, u16 listenInterval, @@ -44,14 +44,14 @@ void ar6000_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast); void ar6000_bitrate_rx(void *devt, A_INT32 rateKbps); void ar6000_channelList_rx(void *devt, A_INT8 numChan, u16 *chanList); -void ar6000_regDomain_event(struct ar6_softc *ar, A_UINT32 regCode); +void ar6000_regDomain_event(struct ar6_softc *ar, u32 regCode); void ar6000_txPwr_rx(void *devt, u8 txPwr); void ar6000_keepalive_rx(void *devt, u8 configured); void ar6000_neighborReport_event(struct ar6_softc *ar, int numAps, WMI_NEIGHBOR_INFO *info); -void ar6000_set_numdataendpts(struct ar6_softc *ar, A_UINT32 num); +void ar6000_set_numdataendpts(struct ar6_softc *ar, u32 num); void ar6000_scanComplete_event(struct ar6_softc *ar, int status); -void ar6000_targetStats_event(struct ar6_softc *ar, u8 *ptr, A_UINT32 len); +void ar6000_targetStats_event(struct ar6_softc *ar, u8 *ptr, u32 len); void ar6000_rssiThreshold_event(struct ar6_softc *ar, WMI_RSSI_THRESHOLD_VAL newThreshold, A_INT16 rssi); @@ -59,7 +59,7 @@ void ar6000_reportError_event(struct ar6_softc *, WMI_TARGET_ERROR_VAL errorVal) void ar6000_cac_event(struct ar6_softc *ar, u8 ac, u8 cac_indication, u8 statusCode, u8 *tspecSuggestion); void ar6000_channel_change_event(struct ar6_softc *ar, u16 oldChannel, u16 newChannel); -void ar6000_hbChallengeResp_event(struct ar6_softc *, A_UINT32 cookie, A_UINT32 source); +void ar6000_hbChallengeResp_event(struct ar6_softc *, u32 cookie, u32 source); void ar6000_roam_tbl_event(struct ar6_softc *ar, WMI_TARGET_ROAM_TBL *pTbl); @@ -73,11 +73,11 @@ ar6000_wow_list_event(struct ar6_softc *ar, u8 num_filters, void ar6000_pmkid_list_event(void *devt, u8 numPMKID, WMI_PMKID *pmkidList, u8 *bssidList); -void ar6000_gpio_intr_rx(A_UINT32 intr_mask, A_UINT32 input_values); -void ar6000_gpio_data_rx(A_UINT32 reg_id, A_UINT32 value); +void ar6000_gpio_intr_rx(u32 intr_mask, u32 input_values); +void ar6000_gpio_data_rx(u32 reg_id, u32 value); void ar6000_gpio_ack_rx(void); -A_INT32 rssi_compensation_calc_tcmd(A_UINT32 freq, A_INT32 rssi, A_UINT32 totalPkt); +A_INT32 rssi_compensation_calc_tcmd(u32 freq, A_INT32 rssi, u32 totalPkt); A_INT16 rssi_compensation_calc(struct ar6_softc *ar, A_INT16 rssi); A_INT16 rssi_compensation_reverse_calc(struct ar6_softc *ar, A_INT16 rssi, bool Above); @@ -101,15 +101,15 @@ void ar6000_snrThresholdEvent_rx(void *devt, void ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL range, u8 lqVal); -void ar6000_ratemask_rx(void *devt, A_UINT32 ratemask); +void ar6000_ratemask_rx(void *devt, u32 ratemask); int ar6000_get_driver_cfg(struct net_device *dev, u16 cfgParam, void *result); void ar6000_bssInfo_event_rx(struct ar6_softc *ar, u8 *data, int len); -void ar6000_dbglog_event(struct ar6_softc *ar, A_UINT32 dropped, - A_INT8 *buffer, A_UINT32 length); +void ar6000_dbglog_event(struct ar6_softc *ar, u32 dropped, + A_INT8 *buffer, u32 length); int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar); @@ -119,32 +119,32 @@ void ar6000_indicate_tx_activity(void *devt, u8 trafficClass, bool Active); HTC_ENDPOINT_ID ar6000_ac2_endpoint_id ( void * devt, u8 ac); u8 ar6000_endpoint_id2_ac (void * devt, HTC_ENDPOINT_ID ep ); -void ar6000_btcoex_config_event(struct ar6_softc *ar, u8 *ptr, A_UINT32 len); +void ar6000_btcoex_config_event(struct ar6_softc *ar, u8 *ptr, u32 len); -void ar6000_btcoex_stats_event(struct ar6_softc *ar, u8 *ptr, A_UINT32 len) ; +void ar6000_btcoex_stats_event(struct ar6_softc *ar, u8 *ptr, u32 len) ; void ar6000_dset_open_req(void *devt, - A_UINT32 id, - A_UINT32 targ_handle, - A_UINT32 targ_reply_fn, - A_UINT32 targ_reply_arg); -void ar6000_dset_close(void *devt, A_UINT32 access_cookie); + u32 id, + u32 targ_handle, + u32 targ_reply_fn, + u32 targ_reply_arg); +void ar6000_dset_close(void *devt, u32 access_cookie); void ar6000_dset_data_req(void *devt, - A_UINT32 access_cookie, - A_UINT32 offset, - A_UINT32 length, - A_UINT32 targ_buf, - A_UINT32 targ_reply_fn, - A_UINT32 targ_reply_arg); + u32 access_cookie, + u32 offset, + u32 length, + u32 targ_buf, + u32 targ_reply_fn, + u32 targ_reply_arg); #if defined(CONFIG_TARGET_PROFILE_SUPPORT) void prof_count_rx(unsigned int addr, unsigned int count); #endif -A_UINT32 ar6000_getnodeAge (void); +u32 ar6000_getnodeAge (void); -A_UINT32 ar6000_getclkfreq (void); +u32 ar6000_getclkfreq (void); int ar6000_ap_mode_profile_commit(struct ar6_softc *ar); @@ -173,12 +173,12 @@ void ap_wapi_rekey_event(struct ar6_softc *ar, u8 type, u8 *mac); int ar6000_connect_to_ap(struct ar6_softc *ar); int ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool suspending); int ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state); -int ar6000_set_bt_hw_state(struct ar6_softc *ar, A_UINT32 state); +int ar6000_set_bt_hw_state(struct ar6_softc *ar, u32 state); #ifdef CONFIG_PM int ar6000_suspend_ev(void *context); int ar6000_resume_ev(void *context); -int ar6000_power_change_ev(void *context, A_UINT32 config); +int ar6000_power_change_ev(void *context, u32 config); void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent); #endif diff --git a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h index ffde2c5284f7..0d7e81d7e573 100644 --- a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h @@ -660,7 +660,7 @@ typedef enum { * UINT32 number of bytes * UINT32 activate? (0 or 1) * } - * A_UINT32 resulting rompatch ID + * u32 resulting rompatch ID * } * uses: BMI_ROMPATCH_INSTALL */ @@ -710,7 +710,7 @@ typedef enum { #define AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER 66 /* * arguments: - * A_UINT32 filter_type; + * u32 filter_type; */ #define AR6000_XIOCTL_DBGLOG_CFG_MODULE 67 @@ -720,7 +720,7 @@ typedef enum { #define AR6000_XIOCTL_WMI_SET_WSC_STATUS 70 /* * arguments: - * A_UINT32 wsc_status; + * u32 wsc_status; * (WSC_REG_INACTIVE or WSC_REG_ACTIVE) */ @@ -760,8 +760,8 @@ typedef enum { /* * arguments: * UINT32 cmd (AR6000_XIOCTL_TARGET_INFO) - * A_UINT32 TargetVersion (returned) - * A_UINT32 TargetType (returned) + * u32 TargetVersion (returned) + * u32 TargetType (returned) * (See also bmi_msg.h target_ver and target_type) */ @@ -786,7 +786,7 @@ typedef enum { * This ioctl is used to set the connect control flags * * arguments: - * A_UINT32 connectCtrlFlags + * u32 connectCtrlFlags */ #define AR6000_XIOCTL_WMI_SET_AKMP_PARAMS 82 @@ -798,7 +798,7 @@ typedef enum { * * arguments: * struct { - * A_UINT32 akmpInfo; + * u32 akmpInfo; * } * uses: WMI_SET_AKMP_PARAMS_CMD */ @@ -814,7 +814,7 @@ typedef enum { * * arguments: * struct { - * A_UINT32 numPMKID; + * u32 numPMKID; * WMI_PMKID pmkidList[WMI_MAX_PMKID_CACHE]; * } * uses: WMI_SET_PMKIDLIST_CMD @@ -850,14 +850,14 @@ typedef enum { #define AR6000_XIOCTL_PROF_CFG 93 /* * arguments: - * A_UINT32 period - * A_UINT32 nbins + * u32 period + * u32 nbins */ #define AR6000_XIOCTL_PROF_ADDR_SET 94 /* * arguments: - * A_UINT32 Target address + * u32 Target address */ #define AR6000_XIOCTL_PROF_START 95 @@ -1000,10 +1000,10 @@ typedef enum { /* used by AR6000_IOCTL_WMI_GETREV */ struct ar6000_version { - A_UINT32 host_ver; - A_UINT32 target_ver; - A_UINT32 wlan_ver; - A_UINT32 abi_ver; + u32 host_ver; + u32 target_ver; + u32 wlan_ver; + u32 abi_ver; }; /* used by AR6000_IOCTL_WMI_GET_QOS_QUEUE */ @@ -1064,9 +1064,9 @@ typedef struct targetStats_t { A_INT32 tx_unicast_rate; A_INT32 rx_unicast_rate; - A_UINT32 lq_val; + u32 lq_val; - A_UINT32 wow_num_pkts_dropped; + u32 wow_num_pkts_dropped; u16 wow_num_events_discarded; A_INT16 noise_floor_calibation; @@ -1079,9 +1079,9 @@ typedef struct targetStats_t { u8 wow_num_host_pkt_wakeups; u8 wow_num_host_event_wakeups; - A_UINT32 arp_received; - A_UINT32 arp_matched; - A_UINT32 arp_replied; + u32 arp_received; + u32 arp_matched; + u32 arp_replied; }TARGET_STATS; typedef struct targetStats_cmd_t { @@ -1098,40 +1098,40 @@ typedef struct targetStats_cmd_t { #define AR6000_USER_SETKEYS_RSC_UNCHANGED 0x00000002 typedef struct { - A_UINT32 keyOpCtrl; /* Bit Map of Key Mgmt Ctrl Flags */ + u32 keyOpCtrl; /* Bit Map of Key Mgmt Ctrl Flags */ } AR6000_USER_SETKEYS_INFO; /* used by AR6000_XIOCTL_GPIO_OUTPUT_SET */ struct ar6000_gpio_output_set_cmd_s { - A_UINT32 set_mask; - A_UINT32 clear_mask; - A_UINT32 enable_mask; - A_UINT32 disable_mask; + u32 set_mask; + u32 clear_mask; + u32 enable_mask; + u32 disable_mask; }; /* * used by AR6000_XIOCTL_GPIO_REGISTER_GET and AR6000_XIOCTL_GPIO_REGISTER_SET */ struct ar6000_gpio_register_cmd_s { - A_UINT32 gpioreg_id; - A_UINT32 value; + u32 gpioreg_id; + u32 value; }; /* used by AR6000_XIOCTL_GPIO_INTR_ACK */ struct ar6000_gpio_intr_ack_cmd_s { - A_UINT32 ack_mask; + u32 ack_mask; }; /* used by AR6000_XIOCTL_GPIO_INTR_WAIT */ struct ar6000_gpio_intr_wait_cmd_s { - A_UINT32 intr_mask; - A_UINT32 input_values; + u32 intr_mask; + u32 input_values; }; /* used by the AR6000_XIOCTL_DBGLOG_CFG_MODULE */ typedef struct ar6000_dbglog_module_config_s { - A_UINT32 valid; + u32 valid; u16 mmask; u16 tsr; u32 rep; @@ -1145,22 +1145,22 @@ typedef struct user_rssi_thold_t { typedef struct user_rssi_params_t { u8 weight; - A_UINT32 pollTime; + u32 pollTime; USER_RSSI_THOLD tholds[12]; } USER_RSSI_PARAMS; typedef struct ar6000_get_btcoex_config_cmd_t{ - A_UINT32 btProfileType; - A_UINT32 linkId; + u32 btProfileType; + u32 linkId; }AR6000_GET_BTCOEX_CONFIG_CMD; typedef struct ar6000_btcoex_config_t { AR6000_GET_BTCOEX_CONFIG_CMD configCmd; - A_UINT32 * configEvent; + u32 *configEvent; } AR6000_BTCOEX_CONFIG; typedef struct ar6000_btcoex_stats_t { - A_UINT32 * statsEvent; + u32 *statsEvent; }AR6000_BTCOEX_STATS; /* * Host driver may have some config parameters. Typically, these @@ -1183,14 +1183,14 @@ struct ar6000_diag_window_cmd_s { struct ar6000_traffic_activity_change { - A_UINT32 StreamID; /* stream ID to indicate activity change */ - A_UINT32 Active; /* active (1) or inactive (0) */ + u32 StreamID; /* stream ID to indicate activity change */ + u32 Active; /* active (1) or inactive (0) */ }; /* Used with AR6000_XIOCTL_PROF_COUNT_GET */ struct prof_count_s { - A_UINT32 addr; /* bin start address */ - A_UINT32 count; /* hit count */ + u32 addr; /* bin start address */ + u32 count; /* hit count */ }; @@ -1199,7 +1199,7 @@ struct prof_count_s { /* AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO */ struct drv_debug_module_s { char modulename[128]; /* name of module */ - A_UINT32 mask; /* new mask to set .. or .. current mask */ + u32 mask; /* new mask to set .. or .. current mask */ }; diff --git a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h index 08a0700e470b..63d887c14328 100644 --- a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h +++ b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h @@ -35,7 +35,7 @@ extern int (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTr extern int (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, int MaxPollMS); -extern int (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud); +extern int (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud); extern int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); @@ -65,7 +65,7 @@ extern int ar6000_register_hci_transport(HCI_TRANSPORT_CALLBACKS *hciTransCallba extern int ar6000_get_hif_dev(HIF_DEVICE *device, void *config); -extern int ar6000_set_uart_config(HIF_DEVICE *hifDevice, A_UINT32 scale, A_UINT32 step); +extern int ar6000_set_uart_config(HIF_DEVICE *hifDevice, u32 scale, u32 step); /* get core clock register settings * data: 0 - 40/44MHz @@ -73,4 +73,4 @@ extern int ar6000_set_uart_config(HIF_DEVICE *hifDevice, A_UINT32 scale, A_UINT3 * where (5G band/2.4G band) * assume 2.4G band for now */ -extern int ar6000_get_core_clock_config(HIF_DEVICE *hifDevice, A_UINT32 *data); +extern int ar6000_get_core_clock_config(HIF_DEVICE *hifDevice, u32 *data); diff --git a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h index 5945a484c62e..209046f7b93c 100644 --- a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h @@ -306,7 +306,7 @@ void *a_netbuf_alloc(int size); void *a_netbuf_alloc_raw(int size); void a_netbuf_free(void *bufPtr); void *a_netbuf_to_data(void *bufPtr); -A_UINT32 a_netbuf_to_len(void *bufPtr); +u32 a_netbuf_to_len(void *bufPtr); int a_netbuf_push(void *bufPtr, A_INT32 len); int a_netbuf_push_data(void *bufPtr, char *srcPtr, A_INT32 len); int a_netbuf_put(void *bufPtr, A_INT32 len); @@ -328,8 +328,8 @@ void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q); /* * Kernel v.s User space functions */ -A_UINT32 a_copy_to_user(void *to, const void *from, A_UINT32 n); -A_UINT32 a_copy_from_user(void *to, const void *from, A_UINT32 n); +u32 a_copy_to_user(void *to, const void *from, u32 n); +u32 a_copy_from_user(void *to, const void *from, u32 n); /* In linux, WLAN Rx and Tx run in different contexts, so no need to check * for any commands/data queued for WLAN */ diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index 9b5f387940e0..dc958fa2972a 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -29,7 +29,7 @@ #include "wlan_config.h" extern int enablerssicompensation; -A_UINT32 tcmdRxFreq; +u32 tcmdRxFreq; extern unsigned int wmitimeout; extern A_WAITQUEUE_HEAD arEvent; extern int tspecCompliance; @@ -663,10 +663,10 @@ ar6000_ioctl_get_qos_queue(struct net_device *dev, struct ifreq *rq) #ifdef CONFIG_HOST_TCMD_SUPPORT static int ar6000_ioctl_tcmd_get_rx_report(struct net_device *dev, - struct ifreq *rq, u8 *data, A_UINT32 len) + struct ifreq *rq, u8 *data, u32 len) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - A_UINT32 buf[4+TCMD_MAX_RATES]; + u32 buf[4+TCMD_MAX_RATES]; int ret = 0; if (ar->bIsDestroyProgress) { @@ -702,8 +702,8 @@ ar6000_ioctl_tcmd_get_rx_report(struct net_device *dev, buf[1] = ar->tcmdRxRssi; buf[2] = ar->tcmdRxcrcErrPkt; buf[3] = ar->tcmdRxsecErrPkt; - A_MEMCPY(((A_UCHAR *)buf)+(4*sizeof(A_UINT32)), ar->tcmdRateCnt, sizeof(ar->tcmdRateCnt)); - A_MEMCPY(((A_UCHAR *)buf)+(4*sizeof(A_UINT32))+(TCMD_MAX_RATES *sizeof(u16)), ar->tcmdRateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard)); + A_MEMCPY(((A_UCHAR *)buf)+(4*sizeof(u32)), ar->tcmdRateCnt, sizeof(ar->tcmdRateCnt)); + A_MEMCPY(((A_UCHAR *)buf)+(4*sizeof(u32))+(TCMD_MAX_RATES *sizeof(u16)), ar->tcmdRateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard)); if (!ret && copy_to_user(rq->ifr_data, buf, sizeof(buf))) { ret = -EFAULT; @@ -830,7 +830,7 @@ static int ar6000_ioctl_get_ap_stats(struct net_device *dev, struct ifreq *rq) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - A_UINT32 action; /* Allocating only the desired space on the frame. Declaring is as a WMI_AP_MODE_STAT variable results in exceeding the compiler imposed limit on the maximum frame size */ + u32 action; /* Allocating only the desired space on the frame. Declaring is as a WMI_AP_MODE_STAT variable results in exceeding the compiler imposed limit on the maximum frame size */ WMI_AP_MODE_STAT *pStats = &ar->arAPStats; int ret = 0; @@ -838,7 +838,7 @@ ar6000_ioctl_get_ap_stats(struct net_device *dev, struct ifreq *rq) return -EIO; } if (copy_from_user(&action, (char *)((unsigned int*)rq->ifr_data + 1), - sizeof(A_UINT32))) + sizeof(u32))) { return -EFAULT; } @@ -1351,7 +1351,7 @@ void ar6000_gpio_init(void) * input_values shows a recent value of GPIO pins. */ void -ar6000_gpio_intr_rx(A_UINT32 intr_mask, A_UINT32 input_values) +ar6000_gpio_intr_rx(u32 intr_mask, u32 input_values) { gpio_intr_results.intr_mask = intr_mask; gpio_intr_results.input_values = input_values; @@ -1365,7 +1365,7 @@ ar6000_gpio_intr_rx(A_UINT32 intr_mask, A_UINT32 input_values) * call. */ void -ar6000_gpio_data_rx(A_UINT32 reg_id, A_UINT32 value) +ar6000_gpio_data_rx(u32 reg_id, u32 value) { gpio_reg_results.gpioreg_id = reg_id; gpio_reg_results.value = value; @@ -1387,10 +1387,10 @@ ar6000_gpio_ack_rx(void) int ar6000_gpio_output_set(struct net_device *dev, - A_UINT32 set_mask, - A_UINT32 clear_mask, - A_UINT32 enable_mask, - A_UINT32 disable_mask) + u32 set_mask, + u32 clear_mask, + u32 enable_mask, + u32 disable_mask) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); @@ -1410,8 +1410,8 @@ ar6000_gpio_input_get(struct net_device *dev) static int ar6000_gpio_register_set(struct net_device *dev, - A_UINT32 gpioreg_id, - A_UINT32 value) + u32 gpioreg_id, + u32 value) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); @@ -1421,7 +1421,7 @@ ar6000_gpio_register_set(struct net_device *dev, static int ar6000_gpio_register_get(struct net_device *dev, - A_UINT32 gpioreg_id) + u32 gpioreg_id) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); @@ -1431,7 +1431,7 @@ ar6000_gpio_register_get(struct net_device *dev, static int ar6000_gpio_intr_ack(struct net_device *dev, - A_UINT32 ack_mask) + u32 ack_mask) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); @@ -1458,7 +1458,7 @@ prof_count_get(struct net_device *dev) * for a previous prof_count_get call. */ void -prof_count_rx(A_UINT32 addr, A_UINT32 count) +prof_count_rx(u32 addr, u32 count) { prof_count_results.addr = addr; prof_count_results.count = count; @@ -1849,7 +1849,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) unsigned int length = 0; unsigned char *buffer; char *userdata; - A_UINT32 connectCtrlFlags; + u32 connectCtrlFlags; WMI_SET_AKMP_PARAMS_CMD akmpParams; @@ -2152,7 +2152,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Execute (address: 0x%x, param: %d)\n", address, param)); - ret = BMIExecute(hifDevice, address, (A_UINT32*)¶m); + ret = BMIExecute(hifDevice, address, (u32 *)¶m); /* return value */ if (put_user(param, (unsigned int *)rq->ifr_data)) { ret = -EFAULT; @@ -2174,7 +2174,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; break; } - ret = BMIReadSOCRegister(hifDevice, address, (A_UINT32*)¶m); + ret = BMIReadSOCRegister(hifDevice, address, (u32 *)¶m); /* return value */ if (put_user(param, (unsigned int *)rq->ifr_data)) { ret = -EFAULT; @@ -2301,8 +2301,8 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) /* Configure Target-side profiling */ case AR6000_XIOCTL_PROF_CFG: { - A_UINT32 period; - A_UINT32 nbins; + u32 period; + u32 nbins; if (get_user(period, (unsigned int *)userdata) || get_user(nbins, (unsigned int *)userdata + 1)) { ret = -EFAULT; @@ -2319,7 +2319,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) /* Start a profiling bucket/bin at the specified address */ case AR6000_XIOCTL_PROF_ADDR_SET: { - A_UINT32 addr; + u32 addr; if (get_user(addr, (unsigned int *)userdata)) { ret = -EFAULT; break; @@ -2762,12 +2762,12 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) /* If we made it to here, then the Target exists and is ready. */ if (cmd == AR6000_XIOCTL_TARGET_INFO) { - if (copy_to_user((A_UINT32 *)rq->ifr_data, &ar->arVersion.target_ver, + if (copy_to_user((u32 *)rq->ifr_data, &ar->arVersion.target_ver, sizeof(ar->arVersion.target_ver))) { ret = -EFAULT; } - if (copy_to_user(((A_UINT32 *)rq->ifr_data)+1, &ar->arTargetType, + if (copy_to_user(((u32 *)rq->ifr_data)+1, &ar->arTargetType, sizeof(ar->arTargetType))) { ret = -EFAULT; @@ -2803,7 +2803,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } case AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP: { - A_UINT32 cookie; + u32 cookie; if (copy_from_user(&cookie, userdata, sizeof(cookie))) { ret = -EFAULT; @@ -3477,7 +3477,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } case AR6000_XIOCTL_DIAG_READ: { - A_UINT32 addr, data; + u32 addr, data; if (get_user(addr, (unsigned int *)userdata)) { ret = -EFAULT; break; @@ -3494,7 +3494,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } case AR6000_XIOCTL_DIAG_WRITE: { - A_UINT32 addr, data; + u32 addr, data; if (get_user(addr, (unsigned int *)userdata) || get_user(data, (unsigned int *)userdata + 1)) { ret = -EFAULT; @@ -3647,13 +3647,13 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { WMI_SET_APPIE_CMD appIEcmd; u8 appIeInfo[IEEE80211_APPIE_FRAME_MAX_LEN]; - A_UINT32 fType,ieLen; + u32 fType,ieLen; if (ar->arWmiReady == false) { ret = -EIO; goto ioctl_done; } - if (get_user(fType, (A_UINT32 *)userdata)) { + if (get_user(fType, (u32 *)userdata)) { ret = -EFAULT; break; } @@ -3661,7 +3661,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (appIEcmd.mgmtFrmType >= IEEE80211_APPIE_NUM_OF_FRAME) { ret = -EIO; } else { - if (get_user(ieLen, (A_UINT32 *)(userdata + 4))) { + if (get_user(ieLen, (u32 *)(userdata + 4))) { ret = -EFAULT; break; } @@ -3686,9 +3686,9 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER: { WMI_BSS_FILTER_CMD cmd; - A_UINT32 filterType; + u32 filterType; - if (copy_from_user(&filterType, userdata, sizeof(A_UINT32))) + if (copy_from_user(&filterType, userdata, sizeof(u32))) { ret = -EFAULT; goto ioctl_done; @@ -3713,12 +3713,12 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } case AR6000_XIOCTL_WMI_SET_WSC_STATUS: { - A_UINT32 wsc_status; + u32 wsc_status; if (ar->arWmiReady == false) { ret = -EIO; goto ioctl_done; - } else if (copy_from_user(&wsc_status, userdata, sizeof(A_UINT32))) + } else if (copy_from_user(&wsc_status, userdata, sizeof(u32))) { ret = -EFAULT; goto ioctl_done; @@ -3730,16 +3730,16 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } case AR6000_XIOCTL_BMI_ROMPATCH_INSTALL: { - A_UINT32 ROM_addr; - A_UINT32 RAM_addr; - A_UINT32 nbytes; - A_UINT32 do_activate; - A_UINT32 rompatch_id; - - if (get_user(ROM_addr, (A_UINT32 *)userdata) || - get_user(RAM_addr, (A_UINT32 *)userdata + 1) || - get_user(nbytes, (A_UINT32 *)userdata + 2) || - get_user(do_activate, (A_UINT32 *)userdata + 3)) { + u32 ROM_addr; + u32 RAM_addr; + u32 nbytes; + u32 do_activate; + u32 rompatch_id; + + if (get_user(ROM_addr, (u32 *)userdata) || + get_user(RAM_addr, (u32 *)userdata + 1) || + get_user(nbytes, (u32 *)userdata + 2) || + get_user(do_activate, (u32 *)userdata + 3)) { ret = -EFAULT; break; } @@ -3759,9 +3759,9 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL: { - A_UINT32 rompatch_id; + u32 rompatch_id; - if (get_user(rompatch_id, (A_UINT32 *)userdata)) { + if (get_user(rompatch_id, (u32 *)userdata)) { ret = -EFAULT; break; } @@ -3773,14 +3773,14 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE: case AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE: { - A_UINT32 rompatch_count; + u32 rompatch_count; - if (get_user(rompatch_count, (A_UINT32 *)userdata)) { + if (get_user(rompatch_count, (u32 *)userdata)) { ret = -EFAULT; break; } AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Change rompatch activation count=%d\n", rompatch_count)); - length = sizeof(A_UINT32) * rompatch_count; + length = sizeof(u32) * rompatch_count; if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) { A_MEMZERO(buffer, length); if (copy_from_user(buffer, &userdata[sizeof(rompatch_count)], length)) @@ -3788,9 +3788,9 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; } else { if (cmd == AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE) { - ret = BMIrompatchActivate(hifDevice, rompatch_count, (A_UINT32 *)buffer); + ret = BMIrompatchActivate(hifDevice, rompatch_count, (u32 *)buffer); } else { - ret = BMIrompatchDeactivate(hifDevice, rompatch_count, (A_UINT32 *)buffer); + ret = BMIrompatchDeactivate(hifDevice, rompatch_count, (u32 *)buffer); } } A_FREE(buffer); @@ -4180,7 +4180,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } case AR6000_XIOCTL_AP_CONN_INACT_TIME: { - A_UINT32 period; + u32 period; if (ar->arWmiReady == false) { ret = -EIO; } else if (copy_from_user(&period, userdata, sizeof(period))) { @@ -4558,11 +4558,11 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } case AR6000_XIOCTL_FETCH_TARGET_REGS: { - A_UINT32 targregs[AR6003_FETCH_TARG_REGS_COUNT]; + u32 targregs[AR6003_FETCH_TARG_REGS_COUNT]; if (ar->arTargetType == TARGET_TYPE_AR6003) { ar6k_FetchTargetRegs(hifDevice, targregs); - if (copy_to_user((A_UINT32 *)rq->ifr_data, &targregs, sizeof(targregs))) + if (copy_to_user((u32 *)rq->ifr_data, &targregs, sizeof(targregs))) { ret = -EFAULT; } diff --git a/drivers/staging/ath6kl/os/linux/netbuf.c b/drivers/staging/ath6kl/os/linux/netbuf.c index 31848d74a21e..580d82985ec8 100644 --- a/drivers/staging/ath6kl/os/linux/netbuf.c +++ b/drivers/staging/ath6kl/os/linux/netbuf.c @@ -89,8 +89,7 @@ a_netbuf_free(void *bufPtr) dev_kfree_skb(skb); } -A_UINT32 -a_netbuf_to_len(void *bufPtr) +u32 a_netbuf_to_len(void *bufPtr) { return (((struct sk_buff *)bufPtr)->len); } diff --git a/drivers/staging/ath6kl/os/linux/wireless_ext.c b/drivers/staging/ath6kl/os/linux/wireless_ext.c index ae2dfb432ec4..aca58dd28e23 100644 --- a/drivers/staging/ath6kl/os/linux/wireless_ext.c +++ b/drivers/staging/ath6kl/os/linux/wireless_ext.c @@ -98,7 +98,7 @@ ar6000_scan_node(void *arg, bss_t *ni) struct ieee80211_common_ie *cie; char *current_val; A_INT32 j; - A_UINT32 rate_len, data_len = 0; + u32 rate_len, data_len = 0; param = (struct ar_giwscan_param *)arg; @@ -712,7 +712,7 @@ ar6000_ioctl_siwrate(struct net_device *dev, struct iw_param *rrq, char *extra) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - A_UINT32 kbps; + u32 kbps; A_INT8 rate_idx; if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { @@ -1596,7 +1596,7 @@ static int ar6000_set_wapi_key(struct net_device *dev, A_INT32 keyLen; u8 *keyData; A_INT32 index; - A_UINT32 *PN; + u32 *PN; A_INT32 i; int status; u8 wapiKeyRsc[16]; @@ -1619,7 +1619,7 @@ static int ar6000_set_wapi_key(struct net_device *dev, if (A_MEMCMP(ext->addr.sa_data, broadcastMac, sizeof(broadcastMac)) == 0) { keyUsage |= GROUP_USAGE; - PN = (A_UINT32 *)wapiKeyRsc; + PN = (u32 *)wapiKeyRsc; for (i = 0; i < 4; i++) { PN[i] = PN_INIT; } diff --git a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h index 42e3de0453b1..523a23904499 100644 --- a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h +++ b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h @@ -79,7 +79,7 @@ typedef struct { bool timerMon; /* true if the timer started for the sake of this TID */ u16 win_sz; /* negotiated window size */ u16 seq_next; /* Next seq no, in current window */ - A_UINT32 hold_q_sz; /* Num of frames that can be held in hold q */ + u32 hold_q_sz; /* Num of frames that can be held in hold q */ OSBUF_HOLD_Q *hold_q; /* Hold q for re-order */ #if 0 WINDOW_SNAPSHOT old_win; /* Sliding window snapshot - for timeout */ @@ -89,15 +89,15 @@ typedef struct { }RXTID; typedef struct { - A_UINT32 num_into_aggr; /* hitting at the input of this module */ - A_UINT32 num_dups; /* duplicate */ - A_UINT32 num_oow; /* out of window */ - A_UINT32 num_mpdu; /* single payload 802.3/802.11 frame */ - A_UINT32 num_amsdu; /* AMSDU */ - A_UINT32 num_delivered; /* frames delivered to IP stack */ - A_UINT32 num_timeouts; /* num of timeouts, during which frames delivered */ - A_UINT32 num_hole; /* frame not present, when window moved over */ - A_UINT32 num_bar; /* num of resets of seq_num, via BAR */ + u32 num_into_aggr; /* hitting at the input of this module */ + u32 num_dups; /* duplicate */ + u32 num_oow; /* out of window */ + u32 num_mpdu; /* single payload 802.3/802.11 frame */ + u32 num_amsdu; /* AMSDU */ + u32 num_delivered; /* frames delivered to IP stack */ + u32 num_timeouts; /* num of timeouts, during which frames delivered */ + u32 num_hole; /* frame not present, when window moved over */ + u32 num_bar; /* num of resets of seq_num, via BAR */ }RXTID_STATS; typedef struct { diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211.h b/drivers/staging/ath6kl/wlan/include/ieee80211.h index 1bcef9ce86b1..0b5441f6159b 100644 --- a/drivers/staging/ath6kl/wlan/include/ieee80211.h +++ b/drivers/staging/ath6kl/wlan/include/ieee80211.h @@ -330,17 +330,17 @@ typedef PREPACK struct wmm_tspec_ie_t { u8 tsInfo_reserved; u16 nominalMSDU; u16 maxMSDU; - A_UINT32 minServiceInt; - A_UINT32 maxServiceInt; - A_UINT32 inactivityInt; - A_UINT32 suspensionInt; - A_UINT32 serviceStartTime; - A_UINT32 minDataRate; - A_UINT32 meanDataRate; - A_UINT32 peakDataRate; - A_UINT32 maxBurstSize; - A_UINT32 delayBound; - A_UINT32 minPhyRate; + u32 minServiceInt; + u32 maxServiceInt; + u32 inactivityInt; + u32 suspensionInt; + u32 serviceStartTime; + u32 minDataRate; + u32 meanDataRate; + u32 peakDataRate; + u32 maxBurstSize; + u32 delayBound; + u32 minPhyRate; u16 sba; u16 mediumTime; } POSTPACK WMM_TSPEC_IE; diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211_node.h b/drivers/staging/ath6kl/wlan/include/ieee80211_node.h index e2d9617a8518..1cb01671c0d3 100644 --- a/drivers/staging/ath6kl/wlan/include/ieee80211_node.h +++ b/drivers/staging/ath6kl/wlan/include/ieee80211_node.h @@ -71,14 +71,14 @@ struct ieee80211_node_table { struct bss *nt_node_last; /* information of all nodes */ struct bss *nt_hash[IEEE80211_NODE_HASHSIZE]; const char *nt_name; /* for debugging */ - A_UINT32 nt_scangen; /* gen# for timeout scan */ + u32 nt_scangen; /* gen# for timeout scan */ #ifdef THREAD_X A_TIMER nt_inact_timer; u8 isTimerArmed; /* is the node timer armed */ #endif - A_UINT32 nt_nodeAge; /* node aging time */ + u32 nt_nodeAge; /* node aging time */ #ifdef OS_ROAM_MANAGEMENT - A_UINT32 nt_si_gen; /* gen# for scan indication*/ + u32 nt_si_gen; /* gen# for scan indication*/ #endif }; diff --git a/drivers/staging/ath6kl/wlan/src/wlan_node.c b/drivers/staging/ath6kl/wlan/src/wlan_node.c index a29f71245d8b..996b36d01ccb 100644 --- a/drivers/staging/ath6kl/wlan/src/wlan_node.c +++ b/drivers/staging/ath6kl/wlan/src/wlan_node.c @@ -114,7 +114,7 @@ wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni, const u8 *macaddr) { int hash; - A_UINT32 timeoutValue = 0; + u32 timeoutValue = 0; A_MEMCPY(ni->ni_macaddr, macaddr, IEEE80211_ADDR_LEN); hash = IEEE80211_NODE_HASH (macaddr); @@ -262,7 +262,7 @@ wlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f, void *arg) { bss_t *ni; - A_UINT32 gen; + u32 gen; gen = ++nt->nt_scangen; @@ -316,7 +316,7 @@ wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt) } void -wlan_set_nodeage(struct ieee80211_node_table *nt, A_UINT32 nodeAge) +wlan_set_nodeage(struct ieee80211_node_table *nt, u32 nodeAge) { nt->nt_nodeAge = nodeAge; return; @@ -347,8 +347,8 @@ wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt) #else bss_t *bss, *nextBss; u8 myBssid[IEEE80211_ADDR_LEN]; - A_UINT32 timeoutValue = 0; - A_UINT32 now = A_GET_MS(0); + u32 timeoutValue = 0; + u32 now = A_GET_MS(0); timeoutValue = nt->nt_nodeAge; wmi_get_current_bssid(nt->nt_wmip, myBssid); @@ -380,7 +380,7 @@ wlan_node_timeout (A_ATH_TIMER arg) struct ieee80211_node_table *nt = (struct ieee80211_node_table *)arg; bss_t *bss, *nextBss; u8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = false; - A_UINT32 timeoutValue = 0; + u32 timeoutValue = 0; timeoutValue = nt->nt_nodeAge; @@ -432,7 +432,7 @@ wlan_node_table_cleanup(struct ieee80211_node_table *nt) bss_t * wlan_find_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid, - A_UINT32 ssidLength, bool bIsWPA2, bool bMatchSSID) + u32 ssidLength, bool bIsWPA2, bool bMatchSSID) { bss_t *ni = NULL; A_UCHAR *pIESsid = NULL; @@ -554,8 +554,8 @@ wlan_node_remove(struct ieee80211_node_table *nt, u8 *bssid) bss_t * wlan_find_matching_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid, - A_UINT32 ssidLength, A_UINT32 dot11AuthMode, A_UINT32 authMode, - A_UINT32 pairwiseCryptoType, A_UINT32 grpwiseCryptoTyp) + u32 ssidLength, u32 dot11AuthMode, u32 authMode, + u32 pairwiseCryptoType, u32 grpwiseCryptoTyp) { bss_t *ni = NULL; bss_t *best_ni = NULL; diff --git a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c index 5ed5b9ee154a..fedacd2b2aa5 100644 --- a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c +++ b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c @@ -53,7 +53,7 @@ ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8))) #define LE_READ_4(p) \ - ((A_UINT32) \ + ((u32) \ ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8) | \ (((u8 *)(p))[2] << 16) | (((u8 *)(p))[3] << 24))) diff --git a/drivers/staging/ath6kl/wlan/src/wlan_utils.c b/drivers/staging/ath6kl/wlan/src/wlan_utils.c index 3a57d50e4e20..fd05e39f4118 100644 --- a/drivers/staging/ath6kl/wlan/src/wlan_utils.c +++ b/drivers/staging/ath6kl/wlan/src/wlan_utils.c @@ -47,8 +47,7 @@ u16 wlan_ieee2freq(int chan) /* * Converts MHz frequency to IEEE channel number. */ -A_UINT32 -wlan_freq2ieee(u16 freq) +u32 wlan_freq2ieee(u16 freq) { if (freq == 2484) return 14; diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index a575ad809ff3..055f2ef0d0e6 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -124,13 +124,13 @@ static int wmi_roam_data_event_rx(struct wmi_t *wmip, u8 *datap, static int wmi_get_wow_list_event_rx(struct wmi_t *wmip, u8 *datap, int len); static int -wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, A_UINT32 len); +wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, u32 len); static int -wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, A_UINT32 len); +wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len); static int -wmi_acm_reject_event_rx(struct wmi_t *wmip, u8 *datap, A_UINT32 len); +wmi_acm_reject_event_rx(struct wmi_t *wmip, u8 *datap, u32 len); #ifdef CONFIG_HOST_GPIO_SUPPORT static int wmi_gpio_intr_rx(struct wmi_t *wmip, u8 *datap, int len); @@ -166,8 +166,8 @@ static int wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len); int wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId, WMI_SYNC_FLAG syncflag); -u8 ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, A_UINT32 size); -u8 ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, A_UINT32 size); +u8 ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size); +u8 ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size); void wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd); void wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd); @@ -531,7 +531,7 @@ wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, u8 msgType, bool bMoreData, } -u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 layer2Priority, bool wmmEnabled) +u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, u32 layer2Priority, bool wmmEnabled) { u8 *datap; u8 trafficClass = WMM_AC_BE; @@ -539,7 +539,7 @@ u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 layer2P WMI_DATA_HDR *dtHdr; u8 streamExists = 0; u8 userPriority; - A_UINT32 hdrsize, metasize; + u32 hdrsize, metasize; ATH_LLC_SNAP_HDR *llcHdr; WMI_CREATE_PSTREAM_CMD cmd; @@ -564,7 +564,7 @@ u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 layer2P { if (processDot11Hdr) { - hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(A_UINT32)); + hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32)); llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize + hdrsize); @@ -629,7 +629,7 @@ wmi_dot11_hdr_add (struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode) ATH_MAC_HDR macHdr; ATH_LLC_SNAP_HDR *llcHdr; struct ieee80211_frame *wh; - A_UINT32 hdrsize; + u32 hdrsize; A_ASSERT(osbuf != NULL); @@ -682,7 +682,7 @@ AddDot11Hdr: /* Make room for 802.11 hdr */ if (wmip->wmi_is_wmm_enabled) { - hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(A_UINT32)); + hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32)); if (A_NETBUF_PUSH(osbuf, hdrsize) != A_OK) { return A_NO_MEMORY; @@ -692,7 +692,7 @@ AddDot11Hdr: } else { - hdrsize = A_ROUND_UP(sizeof(struct ieee80211_frame),sizeof(A_UINT32)); + hdrsize = A_ROUND_UP(sizeof(struct ieee80211_frame),sizeof(u32)); if (A_NETBUF_PUSH(osbuf, hdrsize) != A_OK) { return A_NO_MEMORY; @@ -721,7 +721,7 @@ wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf) u8 type,subtype; ATH_LLC_SNAP_HDR *llcHdr; ATH_MAC_HDR macHdr; - A_UINT32 hdrsize; + u32 hdrsize; A_ASSERT(osbuf != NULL); datap = A_NETBUF_DATA(osbuf); @@ -734,7 +734,7 @@ wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf) /* strip off the 802.11 hdr*/ if (subtype == IEEE80211_FC0_SUBTYPE_QOS) { - hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(A_UINT32)); + hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32)); A_NETBUF_PULL(osbuf, hdrsize); } else if (subtype == IEEE80211_FC0_SUBTYPE_DATA) { A_NETBUF_PULL(osbuf, sizeof(struct ieee80211_frame)); @@ -832,7 +832,7 @@ wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf) WMIX_CMD_HDR *cmd; u16 id; u8 *datap; - A_UINT32 len; + u32 len; int status = A_OK; if (A_NETBUF_LEN(osbuf) < sizeof(WMIX_CMD_HDR)) { @@ -901,7 +901,7 @@ wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf) /* * Control Path */ -A_UINT32 cmdRecvNum; +u32 cmdRecvNum; int wmi_control_rx(struct wmi_t *wmip, void *osbuf) @@ -909,7 +909,7 @@ wmi_control_rx(struct wmi_t *wmip, void *osbuf) WMI_CMD_HDR *cmd; u16 id; u8 *datap; - A_UINT32 len, i, loggingReq; + u32 len, i, loggingReq; int status = A_OK; A_ASSERT(osbuf != NULL); @@ -1240,7 +1240,7 @@ wmi_ready_event_rx(struct wmi_t *wmip, u8 *datap, int len) } #define LE_READ_4(p) \ - ((A_UINT32) \ + ((u32) \ ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8) | \ (((u8 *)(p))[2] << 16) | (((u8 *)(p))[3] << 24))) @@ -1420,7 +1420,7 @@ wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len) bss_t *bss = NULL; WMI_BSS_INFO_HDR *bih; u8 *buf; - A_UINT32 nodeCachingAllowed = 1; + u32 nodeCachingAllowed = 1; A_UCHAR cached_ssid_len = 0; A_UCHAR cached_ssid_buf[IEEE80211_NWID_LEN] = {0}; u8 beacon_ssid_len = 0; @@ -1658,7 +1658,7 @@ wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_BIT_RATE_REPLY *reply; A_INT32 rate; - A_UINT32 sgi,index; + u32 sgi,index; /* 54149: * WMI_BIT_RATE_CMD structure is changed to WMI_BIT_RATE_REPLY. * since there is difference in the length and to avoid returning @@ -2289,9 +2289,9 @@ wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len) static int wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len) { - A_UINT32 dropped; + u32 dropped; - dropped = *((A_UINT32 *)datap); + dropped = *((u32 *)datap); datap += sizeof(dropped); len -= sizeof(dropped); A_WMI_DBGLOG_EVENT(wmip->wmi_devt, dropped, (A_INT8*)datap, len); @@ -2410,7 +2410,7 @@ wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId, } cHdr = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf); - cHdr->commandId = (A_UINT32) cmdId; + cHdr->commandId = (u32) cmdId; return wmi_cmd_send(wmip, osbuf, WMI_EXTENSION_CMDID, syncflag); } @@ -2421,7 +2421,7 @@ wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType, CRYPTO_TYPE pairwiseCrypto, u8 pairwiseCryptoLen, CRYPTO_TYPE groupCrypto, u8 groupCryptoLen, int ssidLength, A_UCHAR *ssid, - u8 *bssid, u16 channel, A_UINT32 ctrl_flags) + u8 *bssid, u16 channel, u32 ctrl_flags) { void *osbuf; WMI_CONNECT_CMD *cc; @@ -2512,7 +2512,7 @@ wmi_disconnect_cmd(struct wmi_t *wmip) int wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, u32 forceFgScan, u32 isLegacy, - A_UINT32 homeDwellTime, A_UINT32 forceScanInterval, + u32 homeDwellTime, u32 forceScanInterval, A_INT8 numChan, u16 *channelList) { void *osbuf; @@ -2559,7 +2559,7 @@ wmi_scanparams_cmd(struct wmi_t *wmip, u16 fg_start_sec, u16 minact_chdw_msec, u16 maxact_chdw_msec, u16 pas_chdw_msec, u8 shScanRatio, u8 scanCtrlFlags, - A_UINT32 max_dfsch_act_time, u16 maxact_scan_per_ssid) + u32 max_dfsch_act_time, u16 maxact_scan_per_ssid) { void *osbuf; WMI_SCAN_PARAMS_CMD *sc; @@ -2589,7 +2589,7 @@ wmi_scanparams_cmd(struct wmi_t *wmip, u16 fg_start_sec, } int -wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, A_UINT32 ieMask) +wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, u32 ieMask) { void *osbuf; WMI_BSS_FILTER_CMD *cmd; @@ -2774,8 +2774,8 @@ wmi_ibsspmcaps_cmd(struct wmi_t *wmip, u8 pmEnable, u8 ttl, } int -wmi_apps_cmd(struct wmi_t *wmip, u8 psType, A_UINT32 idle_time, - A_UINT32 ps_period, u8 sleep_period) +wmi_apps_cmd(struct wmi_t *wmip, u8 psType, u32 idle_time, + u32 ps_period, u8 sleep_period) { void *osbuf; WMI_AP_PS_CMD *cmd; @@ -3261,7 +3261,7 @@ wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params) A_MEMCPY(cmd, params, sizeof(*cmd)); /* this is an implicitly created Fat pipe */ - if ((A_UINT32)params->tsid == (A_UINT32)WMI_IMPLICIT_PSTREAM) { + if ((u32)params->tsid == (u32)WMI_IMPLICIT_PSTREAM) { LOCK_WMI(wmip); fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass)); wmip->wmi_fatPipeExists |= (1<trafficClass); @@ -3516,10 +3516,10 @@ wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, A_INT8 *rate_idx) for (i=0;;i++) { - if (wmi_rateTable[(A_UINT32) i][0] == 0) { + if (wmi_rateTable[(u32) i][0] == 0) { return A_EINVAL; } - if (wmi_rateTable[(A_UINT32) i][0] == rate) { + if (wmi_rateTable[(u32) i][0] == rate) { break; } } @@ -3533,7 +3533,7 @@ wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, A_INT8 *rate_idx) } int -wmi_set_fixrates_cmd(struct wmi_t *wmip, A_UINT32 fixRatesMask) +wmi_set_fixrates_cmd(struct wmi_t *wmip, u32 fixRatesMask) { void *osbuf; WMI_FIX_RATES_CMD *cmd; @@ -3547,7 +3547,7 @@ wmi_set_fixrates_cmd(struct wmi_t *wmip, A_UINT32 fixRatesMask) * to be used. */ /* Make sure all rates in the mask are valid in the current PHY mode */ for(rateIndex = 0; rateIndex < MAX_NUMBER_OF_SUPPORT_RATES; rateIndex++) { - if((1 << rateIndex) & (A_UINT32)fixRatesMask) { + if((1 << rateIndex) & (u32)fixRatesMask) { if(wmi_is_bitrate_index_valid(wmip, rateIndex) != true) { A_DPRINTF(DBG_WMI, (DBGFMT "Set Fix Rates command failed: Given rate is illegal in current PHY mode\n", DBGARG)); return A_EINVAL; @@ -4034,7 +4034,7 @@ wmi_set_lq_threshold_params(struct wmi_t *wmip, } int -wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 mask) +wmi_set_error_report_bitmask(struct wmi_t *wmip, u32 mask) { void *osbuf; A_INT8 size; @@ -4059,7 +4059,7 @@ wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 mask) } int -wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie, A_UINT32 source) +wmi_get_challenge_resp_cmd(struct wmi_t *wmip, u32 cookie, u32 source) { void *osbuf; WMIX_HB_CHALLENGE_RESP_CMD *cmd; @@ -4082,7 +4082,7 @@ wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie, A_UINT32 source) int wmi_config_debug_module_cmd(struct wmi_t *wmip, u16 mmask, u16 tsr, bool rep, u16 size, - A_UINT32 valid) + u32 valid) { void *osbuf; WMIX_DBGLOG_CFG_MODULE_CMD *cmd; @@ -4211,7 +4211,7 @@ int wmi_get_roam_data_cmd(struct wmi_t *wmip, u8 roamDataType) { void *osbuf; - A_UINT32 size = sizeof(u8); + u32 size = sizeof(u8); WMI_TARGET_ROAM_DATA *cmd; osbuf = A_NETBUF_ALLOC(size); /* no payload */ @@ -4287,10 +4287,10 @@ wmi_set_powersave_timers_cmd(struct wmi_t *wmip, /* Send a command to Target to change GPIO output pins. */ int wmi_gpio_output_set(struct wmi_t *wmip, - A_UINT32 set_mask, - A_UINT32 clear_mask, - A_UINT32 enable_mask, - A_UINT32 disable_mask) + u32 set_mask, + u32 clear_mask, + u32 enable_mask, + u32 disable_mask) { void *osbuf; WMIX_GPIO_OUTPUT_SET_CMD *output_set; @@ -4330,8 +4330,8 @@ wmi_gpio_input_get(struct wmi_t *wmip) /* Send a command to the Target that changes the value of a GPIO register. */ int wmi_gpio_register_set(struct wmi_t *wmip, - A_UINT32 gpioreg_id, - A_UINT32 value) + u32 gpioreg_id, + u32 value) { void *osbuf; WMIX_GPIO_REGISTER_SET_CMD *register_set; @@ -4359,7 +4359,7 @@ wmi_gpio_register_set(struct wmi_t *wmip, /* Send a command to the Target to fetch the value of a GPIO register. */ int wmi_gpio_register_get(struct wmi_t *wmip, - A_UINT32 gpioreg_id) + u32 gpioreg_id) { void *osbuf; WMIX_GPIO_REGISTER_GET_CMD *register_get; @@ -4385,7 +4385,7 @@ wmi_gpio_register_get(struct wmi_t *wmip, /* Send a command to the Target acknowledging some GPIO interrupts. */ int wmi_gpio_intr_ack(struct wmi_t *wmip, - A_UINT32 ack_mask) + u32 ack_mask) { void *osbuf; WMIX_GPIO_INTR_ACK_CMD *intr_ack; @@ -4612,7 +4612,7 @@ wmi_set_max_sp_len_cmd(struct wmi_t *wmip, u8 maxSPLen) u8 wmi_determine_userPriority( u8 *pkt, - A_UINT32 layer2Pri) + u32 layer2Pri) { u8 ipPri; iphdr *ipHdr = (iphdr *)pkt; @@ -4871,7 +4871,7 @@ wmi_set_country(struct wmi_t *wmip, A_UCHAR *countryCode) have different test command requirements from differnt manufacturers */ int -wmi_test_cmd(struct wmi_t *wmip, u8 *buf, A_UINT32 len) +wmi_test_cmd(struct wmi_t *wmip, u8 *buf, u32 len) { void *osbuf; char *data; @@ -5210,7 +5210,7 @@ wmi_set_keepalive_cmd(struct wmi_t *wmip, u8 keepaliveInterval) } int -wmi_set_params_cmd(struct wmi_t *wmip, A_UINT32 opcode, A_UINT32 length, char *buffer) +wmi_set_params_cmd(struct wmi_t *wmip, u32 opcode, u32 length, char *buffer) { void *osbuf; WMI_SET_PARAMS_CMD *cmd; @@ -5356,7 +5356,7 @@ wmi_get_rate(A_INT8 rateindex) if (rateindex == RATE_AUTO) { return 0; } else { - return(wmi_rateTable[(A_UINT32) rateindex][0]); + return(wmi_rateTable[(u32) rateindex][0]); } } @@ -5370,14 +5370,14 @@ wmi_node_return (struct wmi_t *wmip, bss_t *bss) } void -wmi_set_nodeage(struct wmi_t *wmip, A_UINT32 nodeAge) +wmi_set_nodeage(struct wmi_t *wmip, u32 nodeAge) { wlan_set_nodeage(&wmip->wmi_scan_table,nodeAge); } bss_t * wmi_find_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid, - A_UINT32 ssidLength, bool bIsWPA2, bool bMatchSSID) + u32 ssidLength, bool bIsWPA2, bool bMatchSSID) { bss_t *node = NULL; node = wlan_find_Ssidnode (&wmip->wmi_scan_table, pSsid, @@ -5423,13 +5423,13 @@ wmi_free_node(struct wmi_t *wmip, const u8 *macaddr) int wmi_dset_open_reply(struct wmi_t *wmip, - A_UINT32 status, - A_UINT32 access_cookie, - A_UINT32 dset_size, - A_UINT32 dset_version, - A_UINT32 targ_handle, - A_UINT32 targ_reply_fn, - A_UINT32 targ_reply_arg) + u32 status, + u32 access_cookie, + u32 dset_size, + u32 dset_version, + u32 targ_handle, + u32 targ_reply_fn, + u32 targ_reply_arg) { void *osbuf; WMIX_DSETOPEN_REPLY_CMD *open_reply; @@ -5457,10 +5457,10 @@ wmi_dset_open_reply(struct wmi_t *wmip, } static int -wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, A_UINT32 len) +wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, u32 len) { WMI_PMKID_LIST_REPLY *reply; - A_UINT32 expected_len; + u32 expected_len; if (len < sizeof(WMI_PMKID_LIST_REPLY)) { return A_EINVAL; @@ -5480,7 +5480,7 @@ wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, A_UINT32 len) static int -wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, A_UINT32 len) +wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len) { WMI_SET_PARAMS_REPLY *reply; @@ -5504,7 +5504,7 @@ wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, A_UINT32 len) static int -wmi_acm_reject_event_rx(struct wmi_t *wmip, u8 *datap, A_UINT32 len) +wmi_acm_reject_event_rx(struct wmi_t *wmip, u8 *datap, u32 len) { WMI_ACM_REJECT_EVENT *ev; @@ -5518,16 +5518,16 @@ wmi_acm_reject_event_rx(struct wmi_t *wmip, u8 *datap, A_UINT32 len) #ifdef CONFIG_HOST_DSET_SUPPORT int wmi_dset_data_reply(struct wmi_t *wmip, - A_UINT32 status, + u32 status, u8 *user_buf, - A_UINT32 length, - A_UINT32 targ_buf, - A_UINT32 targ_reply_fn, - A_UINT32 targ_reply_arg) + u32 length, + u32 targ_buf, + u32 targ_reply_fn, + u32 targ_reply_arg) { void *osbuf; WMIX_DSETDATA_REPLY_CMD *data_reply; - A_UINT32 size; + u32 size; size = sizeof(*data_reply) + length; @@ -5564,7 +5564,7 @@ wmi_dset_data_reply(struct wmi_t *wmip, #endif /* CONFIG_HOST_DSET_SUPPORT */ int -wmi_set_wsc_status_cmd(struct wmi_t *wmip, A_UINT32 status) +wmi_set_wsc_status_cmd(struct wmi_t *wmip, u32 status) { void *osbuf; char *cmd; @@ -5589,8 +5589,8 @@ wmi_set_wsc_status_cmd(struct wmi_t *wmip, A_UINT32 status) #if defined(CONFIG_TARGET_PROFILE_SUPPORT) int wmi_prof_cfg_cmd(struct wmi_t *wmip, - A_UINT32 period, - A_UINT32 nbins) + u32 period, + u32 nbins) { void *osbuf; WMIX_PROF_CFG_CMD *cmd; @@ -5611,7 +5611,7 @@ wmi_prof_cfg_cmd(struct wmi_t *wmip, } int -wmi_prof_addr_set_cmd(struct wmi_t *wmip, A_UINT32 addr) +wmi_prof_addr_set_cmd(struct wmi_t *wmip, u32 addr) { void *osbuf; WMIX_PROF_ADDR_SET_CMD *cmd; @@ -5672,16 +5672,16 @@ void wmi_scan_indication (struct wmi_t *wmip) { struct ieee80211_node_table *nt; - A_UINT32 gen; - A_UINT32 size; - A_UINT32 bsssize; + u32 gen; + u32 size; + u32 bsssize; bss_t *bss; - A_UINT32 numbss; + u32 numbss; PNDIS_802_11_BSSID_SCAN_INFO psi; PBYTE pie; NDIS_802_11_FIXED_IEs *pFixed; NDIS_802_11_VARIABLE_IEs *pVar; - A_UINT32 RateSize; + u32 RateSize; struct ar6kScanIndication { @@ -5884,9 +5884,9 @@ wmi_scan_indication (struct wmi_t *wmip) #endif u8 ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, - A_UINT32 size) + u32 size) { - A_UINT32 index; + u32 index; u8 threshold = (u8)sq_thresh->upper_threshold[size - 1]; /* The list is already in sorted order. Get the next lower value */ @@ -5901,9 +5901,9 @@ u8 ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, } u8 ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, - A_UINT32 size) + u32 size) { - A_UINT32 index; + u32 index; u8 threshold = (u8)sq_thresh->lower_threshold[size - 1]; /* The list is already in sorted order. Get the next lower value */ @@ -6266,7 +6266,7 @@ wmi_set_pvb_cmd(struct wmi_t *wmip, u16 aid, bool flag) } int -wmi_ap_conn_inact_time(struct wmi_t *wmip, A_UINT32 period) +wmi_ap_conn_inact_time(struct wmi_t *wmip, u32 period) { WMI_AP_CONN_INACT_CMD *cmd; void *osbuf = NULL; @@ -6286,7 +6286,7 @@ wmi_ap_conn_inact_time(struct wmi_t *wmip, A_UINT32 period) } int -wmi_ap_bgscan_time(struct wmi_t *wmip, A_UINT32 period, A_UINT32 dwell) +wmi_ap_bgscan_time(struct wmi_t *wmip, u32 period, u32 dwell) { WMI_AP_PROT_SCAN_TIME_CMD *cmd; void *osbuf = NULL; @@ -6423,7 +6423,7 @@ wmi_set_ht_op_cmd(struct wmi_t *wmip, u8 sta_chan_width) #endif int -wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, A_UINT32 *pMaskArray) +wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, u32 *pMaskArray) { void *osbuf; WMI_SET_TX_SELECT_RATES_CMD *pData; @@ -6612,7 +6612,7 @@ wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk) } int -wmi_SGI_cmd(struct wmi_t *wmip, A_UINT32 sgiMask, u8 sgiPERThreshold) +wmi_SGI_cmd(struct wmi_t *wmip, u32 sgiMask, u8 sgiPERThreshold) { void *osbuf; WMI_SET_TX_SGI_PARAM_CMD *cmd; @@ -6634,9 +6634,9 @@ wmi_SGI_cmd(struct wmi_t *wmip, A_UINT32 sgiMask, u8 sgiPERThreshold) bss_t * wmi_find_matching_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid, - A_UINT32 ssidLength, - A_UINT32 dot11AuthMode, A_UINT32 authMode, - A_UINT32 pairwiseCryptoType, A_UINT32 grpwiseCryptoTyp) + u32 ssidLength, + u32 dot11AuthMode, u32 authMode, + u32 pairwiseCryptoType, u32 grpwiseCryptoTyp) { bss_t *node = NULL; node = wlan_find_matching_Ssidnode (&wmip->wmi_scan_table, pSsid, @@ -6653,8 +6653,7 @@ u16 wmi_ieee2freq (int chan) } -A_UINT32 -wmi_freq2ieee (u16 freq) +u32 wmi_freq2ieee (u16 freq) { u16 chan = 0; chan = wlan_freq2ieee (freq); diff --git a/drivers/staging/ath6kl/wmi/wmi_host.h b/drivers/staging/ath6kl/wmi/wmi_host.h index a63f6e925a08..ed8335fa7c52 100644 --- a/drivers/staging/ath6kl/wmi/wmi_host.h +++ b/drivers/staging/ath6kl/wmi/wmi_host.h @@ -31,8 +31,8 @@ extern "C" { #endif struct wmi_stats { - A_UINT32 cmd_len_err; - A_UINT32 cmd_id_err; + u32 cmd_len_err; + u32 cmd_id_err; }; #define SSID_IE_LEN_INDEX 13 @@ -44,9 +44,9 @@ struct wmi_stats { typedef struct sq_threshold_params_s { A_INT16 upper_threshold[SIGNAL_QUALITY_UPPER_THRESHOLD_LEVELS]; A_INT16 lower_threshold[SIGNAL_QUALITY_LOWER_THRESHOLD_LEVELS]; - A_UINT32 upper_threshold_valid_count; - A_UINT32 lower_threshold_valid_count; - A_UINT32 polling_interval; + u32 upper_threshold_valid_count; + u32 lower_threshold_valid_count; + u32 polling_interval; u8 weight; u8 last_rssi; //normally you would expect this to be bss specific but we keep only one instance because its only valid when the device is in a connected state. Not sure if it belongs to host or target. u8 last_rssi_poll_event; //Not sure if it belongs to host or target -- cgit v1.2.3 From c353f4b397982e210b890c1f1a246611ba222b92 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 2 Feb 2011 14:05:52 -0800 Subject: staging: ath6kl: Convert A_UINT64 to u64 Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/include/common/a_hci.h | 2 +- .../staging/ath6kl/os/linux/include/athdrv_linux.h | 92 +++++++++++----------- 2 files changed, 47 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/include/common/a_hci.h b/drivers/staging/ath6kl/include/common/a_hci.h index 3734662d614f..08cb013090be 100644 --- a/drivers/staging/ath6kl/include/common/a_hci.h +++ b/drivers/staging/ath6kl/include/common/a_hci.h @@ -303,7 +303,7 @@ typedef struct hci_cmd_read_local_amp_assoc_t { typedef struct hci_cmd_set_event_mask_t { u16 opcode; u8 param_length; - A_UINT64 mask; + u64 mask; }POSTPACK HCI_CMD_SET_EVT_MASK, HCI_CMD_SET_EVT_MASK_PG_2; diff --git a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h index 0d7e81d7e573..a345ecd319ba 100644 --- a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h @@ -1014,52 +1014,52 @@ struct ar6000_queuereq { /* used by AR6000_IOCTL_WMI_GET_TARGET_STATS */ typedef struct targetStats_t { - A_UINT64 tx_packets; - A_UINT64 tx_bytes; - A_UINT64 tx_unicast_pkts; - A_UINT64 tx_unicast_bytes; - A_UINT64 tx_multicast_pkts; - A_UINT64 tx_multicast_bytes; - A_UINT64 tx_broadcast_pkts; - A_UINT64 tx_broadcast_bytes; - A_UINT64 tx_rts_success_cnt; - A_UINT64 tx_packet_per_ac[4]; - - A_UINT64 tx_errors; - A_UINT64 tx_failed_cnt; - A_UINT64 tx_retry_cnt; - A_UINT64 tx_mult_retry_cnt; - A_UINT64 tx_rts_fail_cnt; - - A_UINT64 rx_packets; - A_UINT64 rx_bytes; - A_UINT64 rx_unicast_pkts; - A_UINT64 rx_unicast_bytes; - A_UINT64 rx_multicast_pkts; - A_UINT64 rx_multicast_bytes; - A_UINT64 rx_broadcast_pkts; - A_UINT64 rx_broadcast_bytes; - A_UINT64 rx_fragment_pkt; - - A_UINT64 rx_errors; - A_UINT64 rx_crcerr; - A_UINT64 rx_key_cache_miss; - A_UINT64 rx_decrypt_err; - A_UINT64 rx_duplicate_frames; - - A_UINT64 tkip_local_mic_failure; - A_UINT64 tkip_counter_measures_invoked; - A_UINT64 tkip_replays; - A_UINT64 tkip_format_errors; - A_UINT64 ccmp_format_errors; - A_UINT64 ccmp_replays; - - A_UINT64 power_save_failure_cnt; - - A_UINT64 cs_bmiss_cnt; - A_UINT64 cs_lowRssi_cnt; - A_UINT64 cs_connect_cnt; - A_UINT64 cs_disconnect_cnt; + u64 tx_packets; + u64 tx_bytes; + u64 tx_unicast_pkts; + u64 tx_unicast_bytes; + u64 tx_multicast_pkts; + u64 tx_multicast_bytes; + u64 tx_broadcast_pkts; + u64 tx_broadcast_bytes; + u64 tx_rts_success_cnt; + u64 tx_packet_per_ac[4]; + + u64 tx_errors; + u64 tx_failed_cnt; + u64 tx_retry_cnt; + u64 tx_mult_retry_cnt; + u64 tx_rts_fail_cnt; + + u64 rx_packets; + u64 rx_bytes; + u64 rx_unicast_pkts; + u64 rx_unicast_bytes; + u64 rx_multicast_pkts; + u64 rx_multicast_bytes; + u64 rx_broadcast_pkts; + u64 rx_broadcast_bytes; + u64 rx_fragment_pkt; + + u64 rx_errors; + u64 rx_crcerr; + u64 rx_key_cache_miss; + u64 rx_decrypt_err; + u64 rx_duplicate_frames; + + u64 tkip_local_mic_failure; + u64 tkip_counter_measures_invoked; + u64 tkip_replays; + u64 tkip_format_errors; + u64 ccmp_format_errors; + u64 ccmp_replays; + + u64 power_save_failure_cnt; + + u64 cs_bmiss_cnt; + u64 cs_lowRssi_cnt; + u64 cs_connect_cnt; + u64 cs_disconnect_cnt; A_INT32 tx_unicast_rate; A_INT32 rx_unicast_rate; -- cgit v1.2.3 From f2ab1275cb1cfd033868cf0b7c67d1143199630e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 2 Feb 2011 14:05:53 -0800 Subject: staging: ath6kl: Convert A_INT8 to s8 Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/include/common/wmi.h | 32 +++++++++--------- drivers/staging/ath6kl/include/wmi_api.h | 8 ++--- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 14 ++++---- .../staging/ath6kl/os/linux/include/ar6000_drv.h | 6 ++-- .../ath6kl/os/linux/include/ar6xapi_linux.h | 4 +-- drivers/staging/ath6kl/os/linux/ioctl.c | 4 +-- drivers/staging/ath6kl/os/linux/wireless_ext.c | 6 ++-- drivers/staging/ath6kl/wmi/wmi.c | 39 +++++++++++----------- 8 files changed, 56 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/include/common/wmi.h b/drivers/staging/ath6kl/include/common/wmi.h index 1f90975aac66..2fb03bea403e 100644 --- a/drivers/staging/ath6kl/include/common/wmi.h +++ b/drivers/staging/ath6kl/include/common/wmi.h @@ -160,7 +160,7 @@ typedef enum { #define WMI_DATA_HDR_SET_META(h, _v) ((h)->info2 = ((h)->info2 & ~(WMI_DATA_HDR_META_MASK << WMI_DATA_HDR_META_SHIFT)) | ((_v) << WMI_DATA_HDR_META_SHIFT)) typedef PREPACK struct { - A_INT8 rssi; + s8 rssi; u8 info; /* usage of 'info' field(8-bit): * b1:b0 - WMI_MSG_TYPE * b4:b3:b2 - UP(tid) @@ -776,7 +776,7 @@ typedef PREPACK struct { } POSTPACK WMI_POWER_MODE_CMD; typedef PREPACK struct { - A_INT8 status; /* WMI_SET_PARAMS_REPLY */ + s8 status; /* WMI_SET_PARAMS_REPLY */ } POSTPACK WMI_SET_PARAMS_REPLY; typedef PREPACK struct { @@ -1199,7 +1199,7 @@ typedef enum { typedef PREPACK struct { u8 bssid[ATH_MAC_LEN]; - A_INT8 bias; + s8 bias; } POSTPACK WMI_BSS_BIAS; typedef PREPACK struct { @@ -2139,7 +2139,7 @@ typedef PREPACK struct { } POSTPACK WMI_NEIGHBOR_INFO; typedef PREPACK struct { - A_INT8 numberOfAps; + s8 numberOfAps; WMI_NEIGHBOR_INFO neighbor[1]; } POSTPACK WMI_NEIGHBOR_REPORT_EVENT; @@ -2207,7 +2207,7 @@ typedef PREPACK struct { typedef PREPACK struct { u16 channel; u8 frameType; /* see WMI_OPT_FTYPE */ - A_INT8 snr; + s8 snr; u8 srcAddr[ATH_MAC_LEN]; u8 bssid[ATH_MAC_LEN]; } POSTPACK WMI_OPT_RX_INFO_HDR; @@ -2399,11 +2399,11 @@ typedef PREPACK struct { typedef PREPACK struct { A_INT32 roam_util; u8 bssid[ATH_MAC_LEN]; - A_INT8 rssi; - A_INT8 rssidt; - A_INT8 last_rssi; - A_INT8 util; - A_INT8 bias; + s8 rssi; + s8 rssidt; + s8 last_rssi; + s8 util; + s8 bias; u8 reserved; /* For alignment */ } POSTPACK WMI_BSS_ROAM_INFO; @@ -2506,14 +2506,14 @@ typedef enum { } WMI_BIT_RATE; typedef PREPACK struct { - A_INT8 rateIndex; /* see WMI_BIT_RATE */ - A_INT8 mgmtRateIndex; - A_INT8 ctlRateIndex; + s8 rateIndex; /* see WMI_BIT_RATE */ + s8 mgmtRateIndex; + s8 ctlRateIndex; } POSTPACK WMI_BIT_RATE_CMD; typedef PREPACK struct { - A_INT8 rateIndex; /* see WMI_BIT_RATE */ + s8 rateIndex; /* see WMI_BIT_RATE */ } POSTPACK WMI_BIT_RATE_REPLY; @@ -2599,9 +2599,9 @@ typedef PREPACK struct { u32 assoc_time; u32 allow_txrx_time; u8 disassoc_bssid[ATH_MAC_LEN]; - A_INT8 disassoc_bss_rssi; + s8 disassoc_bss_rssi; u8 assoc_bssid[ATH_MAC_LEN]; - A_INT8 assoc_bss_rssi; + s8 assoc_bss_rssi; } POSTPACK WMI_TARGET_ROAM_TIME; typedef PREPACK struct { diff --git a/drivers/staging/ath6kl/include/wmi_api.h b/drivers/staging/ath6kl/include/wmi_api.h index 04f809c30519..b34c1f9c6677 100644 --- a/drivers/staging/ath6kl/include/wmi_api.h +++ b/drivers/staging/ath6kl/include/wmi_api.h @@ -124,7 +124,7 @@ int wmi_getrev_cmd(struct wmi_t *wmip); int wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, u32 forceFgScan, u32 isLegacy, u32 homeDwellTime, u32 forceScanInterval, - A_INT8 numChan, u16 *channelList); + s8 numChan, u16 *channelList); int wmi_scanparams_cmd(struct wmi_t *wmip, u16 fg_start_sec, u16 fg_end_sec, u16 bg_sec, u16 minact_chdw_msec, @@ -155,11 +155,11 @@ int wmi_delete_pstream_cmd(struct wmi_t *wmip, u8 trafficClass, u8 streamID); int wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, u16 rateMask); int wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 dataRate, A_INT32 mgmtRate, A_INT32 ctlRate); int wmi_get_bitrate_cmd(struct wmi_t *wmip); -A_INT8 wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, A_INT8 *rate_idx); +s8 wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, s8 *rate_idx); int wmi_get_regDomain_cmd(struct wmi_t *wmip); int wmi_get_channelList_cmd(struct wmi_t *wmip); int wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam, - WMI_PHY_MODE mode, A_INT8 numChan, + WMI_PHY_MODE mode, s8 numChan, u16 *channelList); int wmi_set_snr_threshold_params(struct wmi_t *wmip, @@ -295,7 +295,7 @@ int wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType, int wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, u16 dataLen); -A_INT32 wmi_get_rate(A_INT8 rateindex); +A_INT32 wmi_get_rate(s8 rateindex); int wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *cmd); diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 89ff8f483e13..d527cee25d1c 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -451,7 +451,7 @@ ar6000_dbglog_init_done(AR_SOFTC_T *ar) ar->dbglog_init_done = true; } -u32 dbglog_get_debug_fragment(A_INT8 *datap, u32 len, u32 limit) +u32 dbglog_get_debug_fragment(s8 *datap, u32 len, u32 limit) { A_INT32 *buffer; u32 count; @@ -477,7 +477,7 @@ u32 dbglog_get_debug_fragment(A_INT8 *datap, u32 len, u32 limit) } void -dbglog_parse_debug_logs(A_INT8 *datap, u32 len) +dbglog_parse_debug_logs(s8 *datap, u32 len) { A_INT32 *buffer; u32 count; @@ -571,7 +571,7 @@ ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar) { break; } - ar6000_dbglog_event(ar, dropped, (A_INT8*)&ar->log_buffer[ar->log_cnt], length); + ar6000_dbglog_event(ar, dropped, (s8 *)&ar->log_buffer[ar->log_cnt], length); ar->log_cnt += length; } else { AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("Length: %d (Total size: %d)\n", @@ -597,7 +597,7 @@ ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar) void ar6000_dbglog_event(AR_SOFTC_T *ar, u32 dropped, - A_INT8 *buffer, u32 length) + s8 *buffer, u32 length) { #ifdef REPORT_DEBUG_LOGS_TO_APP #define MAX_WIRELESS_EVENT_SIZE 252 @@ -622,7 +622,7 @@ ar6000_dbglog_event(AR_SOFTC_T *ar, u32 dropped, dropped, length)); /* Interpret the debug logs */ - dbglog_parse_debug_logs((A_INT8*)buffer, length); + dbglog_parse_debug_logs((s8 *)buffer, length); #endif /* REPORT_DEBUG_LOGS_TO_APP */ } @@ -2795,7 +2795,7 @@ ar6000_txPwr_rx(void *devt, u8 txPwr) void -ar6000_channelList_rx(void *devt, A_INT8 numChan, u16 *chanList) +ar6000_channelList_rx(void *devt, s8 numChan, u16 *chanList) { AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; @@ -4755,7 +4755,7 @@ void ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd) { void *osbuf = NULL; - A_INT8 i; + s8 i; u8 size, *buf; int ret = A_OK; diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index c966f495ba5c..bef88eb75e03 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -493,18 +493,18 @@ typedef struct ar6_softc { u16 arListenIntervalT; struct ar6000_version arVersion; u32 arTargetType; - A_INT8 arRssi; + s8 arRssi; u8 arTxPwr; bool arTxPwrSet; A_INT32 arBitRate; struct net_device_stats arNetStats; struct iw_statistics arIwStats; - A_INT8 arNumChannels; + s8 arNumChannels; u16 arChannelList[32]; u32 arRegCode; bool statsUpdatePending; TARGET_STATS arTargetStats; - A_INT8 arMaxRetries; + s8 arMaxRetries; u8 arPhyCapability; #ifdef CONFIG_HOST_TCMD_SUPPORT u8 tcmdRxReport; diff --git a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h index d21ca879bfff..bd62141b89eb 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h @@ -43,7 +43,7 @@ void ar6000_disconnect_event(struct ar6_softc *ar, u8 reason, void ar6000_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast); void ar6000_bitrate_rx(void *devt, A_INT32 rateKbps); -void ar6000_channelList_rx(void *devt, A_INT8 numChan, u16 *chanList); +void ar6000_channelList_rx(void *devt, s8 numChan, u16 *chanList); void ar6000_regDomain_event(struct ar6_softc *ar, u32 regCode); void ar6000_txPwr_rx(void *devt, u8 txPwr); void ar6000_keepalive_rx(void *devt, u8 configured); @@ -109,7 +109,7 @@ int ar6000_get_driver_cfg(struct net_device *dev, void ar6000_bssInfo_event_rx(struct ar6_softc *ar, u8 *data, int len); void ar6000_dbglog_event(struct ar6_softc *ar, u32 dropped, - A_INT8 *buffer, u32 length); + s8 *buffer, u32 length); int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar); diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index dc958fa2972a..a055528588ad 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -4410,7 +4410,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_HCI_CMD: { char tmp_buf[512]; - A_INT8 i; + s8 i; WMI_HCI_CMD *cmd = (WMI_HCI_CMD *)tmp_buf; u8 size; @@ -4689,7 +4689,7 @@ u8 mac_cmp_wild(u8 *mac, u8 *new_mac, u8 wild, u8 new_wild) u8 acl_add_del_mac(WMI_AP_ACL *a, WMI_AP_ACL_MAC_CMD *acl) { - A_INT8 already_avail=-1, free_slot=-1, i; + s8 already_avail=-1, free_slot=-1, i; /* To check whether this mac is already there in our list */ for(i=AP_ACL_SIZE-1;i>=0;i--) diff --git a/drivers/staging/ath6kl/os/linux/wireless_ext.c b/drivers/staging/ath6kl/os/linux/wireless_ext.c index aca58dd28e23..df02625fabc2 100644 --- a/drivers/staging/ath6kl/os/linux/wireless_ext.c +++ b/drivers/staging/ath6kl/os/linux/wireless_ext.c @@ -32,7 +32,7 @@ #define IWE_STREAM_ADD_VALUE(p1, p2, p3, p4, p5, p6) \ iwe_stream_add_value((p1), (p2), (p3), (p4), (p5), (p6)) -static void ar6000_set_quality(struct iw_quality *iq, A_INT8 rssi); +static void ar6000_set_quality(struct iw_quality *iq, s8 rssi); extern unsigned int wmitimeout; extern A_WAITQUEUE_HEAD arEvent; @@ -713,7 +713,7 @@ ar6000_ioctl_siwrate(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); u32 kbps; - A_INT8 rate_idx; + s8 rate_idx; if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); @@ -2564,7 +2564,7 @@ ar6000_ioctl_siwscan(struct net_device *dev, * drivers for compatibility */ static void -ar6000_set_quality(struct iw_quality *iq, A_INT8 rssi) +ar6000_set_quality(struct iw_quality *iq, s8 rssi) { if (rssi < 0) { iq->qual = 0; diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index 055f2ef0d0e6..f5f9aa1a5353 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -1671,7 +1671,7 @@ wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap, int len) A_DPRINTF(DBG_WMI, (DBGFMT "Enter - rateindex %d\n", DBGARG, reply->rateIndex)); - if (reply->rateIndex == (A_INT8) RATE_AUTO) { + if (reply->rateIndex == (s8) RATE_AUTO) { rate = RATE_AUTO; } else { // the SGI state is stored as the MSb of the rateIndex @@ -2294,7 +2294,7 @@ wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len) dropped = *((u32 *)datap); datap += sizeof(dropped); len -= sizeof(dropped); - A_WMI_DBGLOG_EVENT(wmip->wmi_devt, dropped, (A_INT8*)datap, len); + A_WMI_DBGLOG_EVENT(wmip->wmi_devt, dropped, (s8 *)datap, len); return A_OK; } @@ -2513,11 +2513,11 @@ int wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, u32 forceFgScan, u32 isLegacy, u32 homeDwellTime, u32 forceScanInterval, - A_INT8 numChan, u16 *channelList) + s8 numChan, u16 *channelList) { void *osbuf; WMI_START_SCAN_CMD *sc; - A_INT8 size; + s8 size; size = sizeof (*sc); @@ -3399,7 +3399,7 @@ wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 dataRate, A_INT32 mgmtRate, A_IN { void *osbuf; WMI_BIT_RATE_CMD *cmd; - A_INT8 drix, mrix, crix, ret_val; + s8 drix, mrix, crix, ret_val; if (dataRate != -1) { ret_val = wmi_validate_bitrate(wmip, dataRate, &drix); @@ -3509,10 +3509,9 @@ wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex) return isValid; } -A_INT8 -wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, A_INT8 *rate_idx) +s8 wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, s8 *rate_idx) { - A_INT8 i; + s8 i; for (i=0;;i++) { @@ -3596,12 +3595,12 @@ wmi_get_channelList_cmd(struct wmi_t *wmip) */ int wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam, - WMI_PHY_MODE mode, A_INT8 numChan, + WMI_PHY_MODE mode, s8 numChan, u16 *channelList) { void *osbuf; WMI_CHANNEL_PARAMS_CMD *cmd; - A_INT8 size; + s8 size; size = sizeof (*cmd); @@ -3736,7 +3735,7 @@ wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, WMI_SET_HOST_SLEEP_MODE_CMD *hostModeCmd) { void *osbuf; - A_INT8 size; + s8 size; WMI_SET_HOST_SLEEP_MODE_CMD *cmd; u16 activeTsids=0; u8 streamExists=0; @@ -3798,7 +3797,7 @@ wmi_set_wow_mode_cmd(struct wmi_t *wmip, WMI_SET_WOW_MODE_CMD *wowModeCmd) { void *osbuf; - A_INT8 size; + s8 size; WMI_SET_WOW_MODE_CMD *cmd; size = sizeof (*cmd); @@ -3824,7 +3823,7 @@ wmi_get_wow_list_cmd(struct wmi_t *wmip, WMI_GET_WOW_LIST_CMD *wowListCmd) { void *osbuf; - A_INT8 size; + s8 size; WMI_GET_WOW_LIST_CMD *cmd; size = sizeof (*cmd); @@ -3867,7 +3866,7 @@ int wmi_add_wow_pattern_cmd(struct wmi_t *wmip, u8 pattern_size) { void *osbuf; - A_INT8 size; + s8 size; WMI_ADD_WOW_PATTERN_CMD *cmd; u8 *filter_mask = NULL; @@ -3901,7 +3900,7 @@ wmi_del_wow_pattern_cmd(struct wmi_t *wmip, WMI_DEL_WOW_PATTERN_CMD *delWowCmd) { void *osbuf; - A_INT8 size; + s8 size; WMI_DEL_WOW_PATTERN_CMD *cmd; size = sizeof (*cmd); @@ -4003,7 +4002,7 @@ wmi_set_lq_threshold_params(struct wmi_t *wmip, WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd) { void *osbuf; - A_INT8 size; + s8 size; WMI_LQ_THRESHOLD_PARAMS_CMD *cmd; /* These values are in ascending order */ if( lqCmd->thresholdAbove4_Val <= lqCmd->thresholdAbove3_Val || @@ -4037,7 +4036,7 @@ int wmi_set_error_report_bitmask(struct wmi_t *wmip, u32 mask) { void *osbuf; - A_INT8 size; + s8 size; WMI_TARGET_ERROR_REPORT_BITMASK *cmd; size = sizeof (*cmd); @@ -5351,7 +5350,7 @@ wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, u16 dataLen) } A_INT32 -wmi_get_rate(A_INT8 rateindex) +wmi_get_rate(s8 rateindex) { if (rateindex == RATE_AUTO) { return 0; @@ -5921,7 +5920,7 @@ wmi_send_rssi_threshold_params(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd) { void *osbuf; - A_INT8 size; + s8 size; WMI_RSSI_THRESHOLD_PARAMS_CMD *cmd; size = sizeof (*cmd); @@ -5945,7 +5944,7 @@ wmi_send_snr_threshold_params(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd) { void *osbuf; - A_INT8 size; + s8 size; WMI_SNR_THRESHOLD_PARAMS_CMD *cmd; size = sizeof (*cmd); -- cgit v1.2.3 From cb1e370987c3651707e30e404e41ebdc83571fba Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 2 Feb 2011 14:05:54 -0800 Subject: staging: ath6kl: Convert A_INT16 to s16 Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/include/common/wmi.h | 36 +++++++++++----------- drivers/staging/ath6kl/include/wlan_api.h | 2 +- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 24 +++++++-------- drivers/staging/ath6kl/os/linux/ar6000_pm.c | 2 +- .../ath6kl/os/linux/include/ar6xapi_linux.h | 6 ++-- .../staging/ath6kl/os/linux/include/athdrv_linux.h | 10 +++--- drivers/staging/ath6kl/wmi/wmi.c | 18 +++++------ drivers/staging/ath6kl/wmi/wmi_host.h | 4 +-- 8 files changed, 50 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/include/common/wmi.h b/drivers/staging/ath6kl/include/common/wmi.h index 2fb03bea403e..12ca0254e8ef 100644 --- a/drivers/staging/ath6kl/include/common/wmi.h +++ b/drivers/staging/ath6kl/include/common/wmi.h @@ -996,18 +996,18 @@ typedef PREPACK struct { typedef PREPACK struct WMI_RSSI_THRESHOLD_PARAMS{ u32 pollTime; /* Polling time as a factor of LI */ - A_INT16 thresholdAbove1_Val; /* lowest of upper */ - A_INT16 thresholdAbove2_Val; - A_INT16 thresholdAbove3_Val; - A_INT16 thresholdAbove4_Val; - A_INT16 thresholdAbove5_Val; - A_INT16 thresholdAbove6_Val; /* highest of upper */ - A_INT16 thresholdBelow1_Val; /* lowest of bellow */ - A_INT16 thresholdBelow2_Val; - A_INT16 thresholdBelow3_Val; - A_INT16 thresholdBelow4_Val; - A_INT16 thresholdBelow5_Val; - A_INT16 thresholdBelow6_Val; /* highest of bellow */ + s16 thresholdAbove1_Val; /* lowest of upper */ + s16 thresholdAbove2_Val; + s16 thresholdAbove3_Val; + s16 thresholdAbove4_Val; + s16 thresholdAbove5_Val; + s16 thresholdAbove6_Val; /* highest of upper */ + s16 thresholdBelow1_Val; /* lowest of bellow */ + s16 thresholdBelow2_Val; + s16 thresholdBelow3_Val; + s16 thresholdBelow4_Val; + s16 thresholdBelow5_Val; + s16 thresholdBelow6_Val; /* highest of bellow */ u8 weight; /* "alpha" */ u8 reserved[3]; } POSTPACK WMI_RSSI_THRESHOLD_PARAMS_CMD; @@ -1209,8 +1209,8 @@ typedef PREPACK struct { typedef PREPACK struct WMI_LOWRSSI_SCAN_PARAMS { u16 lowrssi_scan_period; - A_INT16 lowrssi_scan_threshold; - A_INT16 lowrssi_roam_threshold; + s16 lowrssi_scan_threshold; + s16 lowrssi_roam_threshold; u8 roam_rssi_floor; u8 reserved[1]; /* For alignment */ } POSTPACK WMI_LOWRSSI_SCAN_PARAMS; @@ -2062,7 +2062,7 @@ typedef PREPACK struct { u16 channel; u8 frameType; /* see WMI_BI_FTYPE */ u8 snr; - A_INT16 rssi; + s16 rssi; u8 bssid[ATH_MAC_LEN]; u32 ieMask; } POSTPACK WMI_BSS_INFO_HDR; @@ -2277,9 +2277,9 @@ typedef PREPACK struct { u32 cs_lowRssi_cnt; u16 cs_connect_cnt; u16 cs_disconnect_cnt; - A_INT16 cs_aveBeacon_rssi; + s16 cs_aveBeacon_rssi; u16 cs_roam_count; - A_INT16 cs_rssi; + s16 cs_rssi; u8 cs_snr; u8 cs_aveBeacon_snr; u8 cs_lastRoam_msec; @@ -2335,7 +2335,7 @@ typedef enum{ }WMI_RSSI_THRESHOLD_VAL; typedef PREPACK struct { - A_INT16 rssi; + s16 rssi; u8 range; }POSTPACK WMI_RSSI_THRESHOLD_EVENT; diff --git a/drivers/staging/ath6kl/include/wlan_api.h b/drivers/staging/ath6kl/include/wlan_api.h index ce799683725d..ba5493c98a76 100644 --- a/drivers/staging/ath6kl/include/wlan_api.h +++ b/drivers/staging/ath6kl/include/wlan_api.h @@ -61,7 +61,7 @@ struct ieee80211_common_ie { typedef struct bss { u8 ni_macaddr[6]; u8 ni_snr; - A_INT16 ni_rssi; + s16 ni_rssi; struct bss *ni_list_next; struct bss *ni_list_prev; struct bss *ni_hash_next; diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index d527cee25d1c..651f9f4b665a 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -260,16 +260,16 @@ typedef struct user_rssi_compensation_t { u16 bg_enable; u16 enable; }; - A_INT16 bg_param_a; - A_INT16 bg_param_b; - A_INT16 a_param_a; - A_INT16 a_param_b; + s16 bg_param_a; + s16 bg_param_b; + s16 a_param_a; + s16 a_param_b; u32 reserved; } USER_RSSI_CPENSATION; static USER_RSSI_CPENSATION rssi_compensation_param; -static A_INT16 rssi_compensation_table[96]; +static s16 rssi_compensation_table[96]; int reconnect_flag = 0; static ar6k_pal_config_t ar6k_pal_config_g; @@ -2430,7 +2430,7 @@ int ar6000_init(struct net_device *dev) AR_SOFTC_T *ar; int status; A_INT32 timeleft; - A_INT16 i; + s16 i; int ret = 0; #if defined(INIT_MODE_DRV_ENABLED) && defined(ENABLE_COEXISTENCE) WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD sbcb_cmd; @@ -5030,7 +5030,7 @@ ar6000_targetStats_event(AR_SOFTC_T *ar, u8 *ptr, u32 len) } void -ar6000_rssiThreshold_event(AR_SOFTC_T *ar, WMI_RSSI_THRESHOLD_VAL newThreshold, A_INT16 rssi) +ar6000_rssiThreshold_event(AR_SOFTC_T *ar, WMI_RSSI_THRESHOLD_VAL newThreshold, s16 rssi) { USER_RSSI_THOLD userRssiThold; @@ -5791,7 +5791,7 @@ read_rssi_compensation_param(AR_SOFTC_T *ar) //#define RSSICOMPENSATION_PRINT #ifdef RSSICOMPENSATION_PRINT - A_INT16 i; + s16 i; cust_data_ptr = ar6000_get_cust_data_buffer(ar->arTargetType); for (i=0; i<16; i++) { A_PRINTF("cust_data_%d = %x \n", i, *(u8 *)cust_data_ptr); @@ -5856,8 +5856,7 @@ rssi_compensation_calc_tcmd(u32 freq, A_INT32 rssi, u32 totalPkt) return rssi; } -A_INT16 -rssi_compensation_calc(AR_SOFTC_T *ar, A_INT16 rssi) +s16 rssi_compensation_calc(AR_SOFTC_T *ar, s16 rssi) { if (ar->arBssChannel > 5000) { @@ -5885,10 +5884,9 @@ rssi_compensation_calc(AR_SOFTC_T *ar, A_INT16 rssi) return rssi; } -A_INT16 -rssi_compensation_reverse_calc(AR_SOFTC_T *ar, A_INT16 rssi, bool Above) +s16 rssi_compensation_reverse_calc(AR_SOFTC_T *ar, s16 rssi, bool Above) { - A_INT16 i; + s16 i; if (ar->arBssChannel > 5000) { diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c index 691e535403a1..0995bbbb4e38 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_pm.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_pm.c @@ -215,7 +215,7 @@ int ar6000_suspend_ev(void *context) { int status = A_OK; AR_SOFTC_T *ar = (AR_SOFTC_T *)context; - A_INT16 pmmode = ar->arSuspendConfig; + s16 pmmode = ar->arSuspendConfig; wow_not_connected: switch (pmmode) { case WLAN_SUSPEND_WOW: diff --git a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h index bd62141b89eb..328982fb3a94 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h @@ -54,7 +54,7 @@ void ar6000_scanComplete_event(struct ar6_softc *ar, int status); void ar6000_targetStats_event(struct ar6_softc *ar, u8 *ptr, u32 len); void ar6000_rssiThreshold_event(struct ar6_softc *ar, WMI_RSSI_THRESHOLD_VAL newThreshold, - A_INT16 rssi); + s16 rssi); void ar6000_reportError_event(struct ar6_softc *, WMI_TARGET_ERROR_VAL errorVal); void ar6000_cac_event(struct ar6_softc *ar, u8 ac, u8 cac_indication, u8 statusCode, u8 *tspecSuggestion); @@ -78,8 +78,8 @@ void ar6000_gpio_data_rx(u32 reg_id, u32 value); void ar6000_gpio_ack_rx(void); A_INT32 rssi_compensation_calc_tcmd(u32 freq, A_INT32 rssi, u32 totalPkt); -A_INT16 rssi_compensation_calc(struct ar6_softc *ar, A_INT16 rssi); -A_INT16 rssi_compensation_reverse_calc(struct ar6_softc *ar, A_INT16 rssi, bool Above); +s16 rssi_compensation_calc(struct ar6_softc *ar, s16 rssi); +s16 rssi_compensation_reverse_calc(struct ar6_softc *ar, s16 rssi, bool Above); void ar6000_dbglog_init_done(struct ar6_softc *ar); diff --git a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h index a345ecd319ba..a3e65081f98d 100644 --- a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h @@ -1069,9 +1069,9 @@ typedef struct targetStats_t { u32 wow_num_pkts_dropped; u16 wow_num_events_discarded; - A_INT16 noise_floor_calibation; - A_INT16 cs_rssi; - A_INT16 cs_aveBeacon_rssi; + s16 noise_floor_calibation; + s16 cs_rssi; + s16 cs_aveBeacon_rssi; u8 cs_aveBeacon_snr; u8 cs_lastRoam_msec; u8 cs_snr; @@ -1139,8 +1139,8 @@ typedef struct ar6000_dbglog_module_config_s { } DBGLOG_MODULE_CONFIG; typedef struct user_rssi_thold_t { - A_INT16 tag; - A_INT16 rssi; + s16 tag; + s16 rssi; } USER_RSSI_THOLD; typedef struct user_rssi_params_t { diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index f5f9aa1a5353..b80bdb7e7643 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -166,8 +166,8 @@ static int wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len); int wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId, WMI_SYNC_FLAG syncflag); -u8 ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size); -u8 ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size); +u8 ar6000_get_upper_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size); +u8 ar6000_get_lower_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size); void wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd); void wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd); @@ -281,7 +281,7 @@ typedef PREPACK struct _iphdr { u8 ip_tos; /* type of service */ u16 ip_len; /* total length */ u16 ip_id; /* identification */ - A_INT16 ip_off; /* fragment offset field */ + s16 ip_off; /* fragment offset field */ #define IP_DF 0x4000 /* dont fragment flag */ #define IP_MF 0x2000 /* more fragments flag */ #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ @@ -294,8 +294,8 @@ typedef PREPACK struct _iphdr { #include "athendpack.h" -static A_INT16 rssi_event_value = 0; -static A_INT16 snr_event_value = 0; +static s16 rssi_event_value = 0; +static s16 snr_event_value = 0; bool is_probe_ssid = false; @@ -1874,7 +1874,7 @@ wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len) SQ_THRESHOLD_PARAMS *sq_thresh = &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI]; u8 upper_rssi_threshold, lower_rssi_threshold; - A_INT16 rssi; + s16 rssi; if (len < sizeof(*reply)) { return A_EINVAL; @@ -2143,7 +2143,7 @@ wmi_snrThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len) WMI_SNR_THRESHOLD_VAL newThreshold; WMI_SNR_THRESHOLD_PARAMS_CMD cmd; u8 upper_snr_threshold, lower_snr_threshold; - A_INT16 snr; + s16 snr; if (len < sizeof(*reply)) { return A_EINVAL; @@ -5882,7 +5882,7 @@ wmi_scan_indication (struct wmi_t *wmip) } #endif -u8 ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, +u8 ar6000_get_upper_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size) { u32 index; @@ -5899,7 +5899,7 @@ u8 ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, return threshold; } -u8 ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, +u8 ar6000_get_lower_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size) { u32 index; diff --git a/drivers/staging/ath6kl/wmi/wmi_host.h b/drivers/staging/ath6kl/wmi/wmi_host.h index ed8335fa7c52..53e4f085dfe6 100644 --- a/drivers/staging/ath6kl/wmi/wmi_host.h +++ b/drivers/staging/ath6kl/wmi/wmi_host.h @@ -42,8 +42,8 @@ struct wmi_stats { #define SIGNAL_QUALITY_UPPER_THRESHOLD_LEVELS SIGNAL_QUALITY_THRESHOLD_LEVELS #define SIGNAL_QUALITY_LOWER_THRESHOLD_LEVELS SIGNAL_QUALITY_THRESHOLD_LEVELS typedef struct sq_threshold_params_s { - A_INT16 upper_threshold[SIGNAL_QUALITY_UPPER_THRESHOLD_LEVELS]; - A_INT16 lower_threshold[SIGNAL_QUALITY_LOWER_THRESHOLD_LEVELS]; + s16 upper_threshold[SIGNAL_QUALITY_UPPER_THRESHOLD_LEVELS]; + s16 lower_threshold[SIGNAL_QUALITY_LOWER_THRESHOLD_LEVELS]; u32 upper_threshold_valid_count; u32 lower_threshold_valid_count; u32 polling_interval; -- cgit v1.2.3 From f68057e6fab6943ea2c5867d8b72e4b08bef5f6e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 2 Feb 2011 14:05:55 -0800 Subject: staging: ath6kl: Convert A_INT32 to s32 Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- .../staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 10 +++--- drivers/staging/ath6kl/htc2/htc.c | 2 +- drivers/staging/ath6kl/include/common/testcmd.h | 4 +-- drivers/staging/ath6kl/include/common/wmi.h | 12 +++---- drivers/staging/ath6kl/include/common_drv.h | 2 +- drivers/staging/ath6kl/include/wmi_api.h | 6 ++-- drivers/staging/ath6kl/miscdrv/common_drv.c | 14 ++++---- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 15 ++++----- .../staging/ath6kl/os/linux/include/ar6000_drv.h | 8 ++--- .../ath6kl/os/linux/include/ar6xapi_linux.h | 4 +-- .../staging/ath6kl/os/linux/include/athdrv_linux.h | 4 +-- .../staging/ath6kl/os/linux/include/osapi_linux.h | 20 +++++------ drivers/staging/ath6kl/os/linux/ioctl.c | 2 +- drivers/staging/ath6kl/os/linux/netbuf.c | 21 ++++++------ drivers/staging/ath6kl/os/linux/wireless_ext.c | 22 ++++++------ drivers/staging/ath6kl/wmi/wmi.c | 39 +++++++++++----------- 16 files changed, 91 insertions(+), 94 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index ba4399fb1dd3..57cb1f70dcf1 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -465,10 +465,10 @@ static int async_task(void *param) return 0; } -static A_INT32 IssueSDCommand(HIF_DEVICE *device, u32 opcode, u32 arg, u32 flags, u32 *resp) +static s32 IssueSDCommand(HIF_DEVICE *device, u32 opcode, u32 arg, u32 flags, u32 *resp) { struct mmc_command cmd; - A_INT32 err; + s32 err; struct mmc_host *host; struct sdio_func *func; @@ -490,7 +490,7 @@ static A_INT32 IssueSDCommand(HIF_DEVICE *device, u32 opcode, u32 arg, u32 flags int ReinitSDIO(HIF_DEVICE *device) { - A_INT32 err; + s32 err; struct mmc_host *host; struct mmc_card *card; struct sdio_func *func; @@ -1153,7 +1153,7 @@ static void hifDeviceRemoved(struct sdio_func *func) */ int hifWaitForPendingRecv(HIF_DEVICE *device) { - A_INT32 cnt = 10; + s32 cnt = 10; u8 host_int_status; int status = A_OK; @@ -1280,7 +1280,7 @@ static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsi { struct mmc_command ioCmd; unsigned long arg; - A_INT32 err; + s32 err; memset(&ioCmd,0,sizeof(ioCmd)); SDIO_SET_CMD52_READ_ARG(arg,0,address); diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index 48ae318ff9d2..afc523f81bcb 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -64,7 +64,7 @@ HTC_PACKET *HTCAllocControlBuffer(HTC_TARGET *target, HTC_PACKET_QUEUE *pList) /* cleanup the HTC instance */ static void HTCCleanup(HTC_TARGET *target) { - A_INT32 i; + s32 i; DevCleanup(&target->Device); diff --git a/drivers/staging/ath6kl/include/common/testcmd.h b/drivers/staging/ath6kl/include/common/testcmd.h index 49861e2058f0..3799b687498c 100644 --- a/drivers/staging/ath6kl/include/common/testcmd.h +++ b/drivers/staging/ath6kl/include/common/testcmd.h @@ -86,7 +86,7 @@ typedef PREPACK struct { u32 mode; u32 freq; u32 dataRate; - A_INT32 txPwr; + s32 txPwr; u32 antenna; u32 enANI; u32 scramblerOff; @@ -135,7 +135,7 @@ typedef PREPACK struct { } POSTPACK para; struct PREPACK TCMD_CONT_RX_REPORT { u32 totalPkt; - A_INT32 rssiInDBm; + s32 rssiInDBm; u32 crcErrPkt; u32 secErrPkt; u16 rateCnt[TCMD_MAX_RATES]; diff --git a/drivers/staging/ath6kl/include/common/wmi.h b/drivers/staging/ath6kl/include/common/wmi.h index 12ca0254e8ef..a03b4371519f 100644 --- a/drivers/staging/ath6kl/include/common/wmi.h +++ b/drivers/staging/ath6kl/include/common/wmi.h @@ -2155,7 +2155,7 @@ typedef PREPACK struct { * WMI_SCAN_COMPLETE_EVENTID - no parameters (old), staus parameter (new) */ typedef PREPACK struct { - A_INT32 status; + s32 status; } POSTPACK WMI_SCAN_COMPLETE_EVENT; #define MAX_OPT_DATA_LEN 1400 @@ -2233,7 +2233,7 @@ typedef PREPACK struct { u32 tx_retry_cnt; u32 tx_mult_retry_cnt; u32 tx_rts_fail_cnt; - A_INT32 tx_unicast_rate; + s32 tx_unicast_rate; }POSTPACK tx_stats_t; typedef PREPACK struct { @@ -2252,7 +2252,7 @@ typedef PREPACK struct { u32 rx_key_cache_miss; u32 rx_decrypt_err; u32 rx_duplicate_frames; - A_INT32 rx_unicast_rate; + s32 rx_unicast_rate; }POSTPACK rx_stats_t; typedef PREPACK struct { @@ -2306,7 +2306,7 @@ typedef PREPACK struct { typedef PREPACK struct { u32 lqVal; - A_INT32 noise_floor_calibation; + s32 noise_floor_calibation; pm_stats_t pmStats; wlan_net_stats_t txrxStats; wlan_wow_stats_t wowStats; @@ -2388,7 +2388,7 @@ typedef enum{ } WMI_LQ_THRESHOLD_VAL; typedef PREPACK struct { - A_INT32 lq; + s32 lq; u8 range; /* WMI_LQ_THRESHOLD_VAL */ }POSTPACK WMI_LQ_THRESHOLD_EVENT; /* @@ -2397,7 +2397,7 @@ typedef PREPACK struct { #define MAX_ROAM_TBL_CAND 5 typedef PREPACK struct { - A_INT32 roam_util; + s32 roam_util; u8 bssid[ATH_MAC_LEN]; s8 rssi; s8 rssidt; diff --git a/drivers/staging/ath6kl/include/common_drv.h b/drivers/staging/ath6kl/include/common_drv.h index f5152eb86c5a..141b7efc5718 100644 --- a/drivers/staging/ath6kl/include/common_drv.h +++ b/drivers/staging/ath6kl/include/common_drv.h @@ -37,7 +37,7 @@ typedef struct _COMMON_CREDIT_STATE_INFO { } COMMON_CREDIT_STATE_INFO; typedef struct { - A_INT32 (*setupTransport)(void *ar); + s32 (*setupTransport)(void *ar); void (*cleanupTransport)(void *ar); } HCI_TRANSPORT_CALLBACKS; diff --git a/drivers/staging/ath6kl/include/wmi_api.h b/drivers/staging/ath6kl/include/wmi_api.h index b34c1f9c6677..e51440ad7b7d 100644 --- a/drivers/staging/ath6kl/include/wmi_api.h +++ b/drivers/staging/ath6kl/include/wmi_api.h @@ -153,9 +153,9 @@ int wmi_sync_cmd(struct wmi_t *wmip, u8 syncNumber); int wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *pstream); int wmi_delete_pstream_cmd(struct wmi_t *wmip, u8 trafficClass, u8 streamID); int wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, u16 rateMask); -int wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 dataRate, A_INT32 mgmtRate, A_INT32 ctlRate); +int wmi_set_bitrate_cmd(struct wmi_t *wmip, s32 dataRate, s32 mgmtRate, s32 ctlRate); int wmi_get_bitrate_cmd(struct wmi_t *wmip); -s8 wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, s8 *rate_idx); +s8 wmi_validate_bitrate(struct wmi_t *wmip, s32 rate, s8 *rate_idx); int wmi_get_regDomain_cmd(struct wmi_t *wmip); int wmi_get_channelList_cmd(struct wmi_t *wmip); int wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam, @@ -295,7 +295,7 @@ int wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType, int wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, u16 dataLen); -A_INT32 wmi_get_rate(s8 rateindex); +s32 wmi_get_rate(s8 rateindex); int wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *cmd); diff --git a/drivers/staging/ath6kl/miscdrv/common_drv.c b/drivers/staging/ath6kl/miscdrv/common_drv.c index d0485bf4229d..0c9c8a34264b 100644 --- a/drivers/staging/ath6kl/miscdrv/common_drv.c +++ b/drivers/staging/ath6kl/miscdrv/common_drv.c @@ -87,7 +87,7 @@ int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, u32 RegisterAddr, u32 { int status; u8 addrValue[4]; - A_INT32 i; + s32 i; /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written * last to initiate the access cycle */ @@ -358,10 +358,10 @@ _do_write_diag(HIF_DEVICE *hifDevice, u32 addr, u32 value) */ #if 0 static int -_delay_until_target_alive(HIF_DEVICE *hifDevice, A_INT32 wait_msecs, u32 TargetType) +_delay_until_target_alive(HIF_DEVICE *hifDevice, s32 wait_msecs, u32 TargetType) { - A_INT32 actual_wait; - A_INT32 i; + s32 actual_wait; + s32 i; u32 address; actual_wait = 0; @@ -485,7 +485,7 @@ ar6000_copy_cust_data_from_target(HIF_DEVICE *hifDevice, u32 TargetType) { u32 eepHeaderAddr; u8 AR6003CustDataShadow[AR6003_CUST_DATA_SIZE+4]; - A_INT32 i; + s32 i; if (BMIReadMemory(hifDevice, HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_board_data), @@ -727,13 +727,13 @@ int ar6000_prepare_target(HIF_DEVICE *hifDevice, int ar6002_REV1_reset_force_host (HIF_DEVICE *hifDevice) { - A_INT32 i; + s32 i; struct forceROM_s { u32 addr; u32 data; }; struct forceROM_s *ForceROM; - A_INT32 szForceROM; + s32 szForceROM; int status = A_OK; u32 address; u32 data; diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 651f9f4b665a..ed82a3ba568a 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -453,14 +453,14 @@ ar6000_dbglog_init_done(AR_SOFTC_T *ar) u32 dbglog_get_debug_fragment(s8 *datap, u32 len, u32 limit) { - A_INT32 *buffer; + s32 *buffer; u32 count; u32 numargs; u32 length; u32 fraglen; count = fraglen = 0; - buffer = (A_INT32 *)datap; + buffer = (s32 *)datap; length = (limit >> 2); if (len <= limit) { @@ -479,7 +479,7 @@ u32 dbglog_get_debug_fragment(s8 *datap, u32 len, u32 limit) void dbglog_parse_debug_logs(s8 *datap, u32 len) { - A_INT32 *buffer; + s32 *buffer; u32 count; u32 timestamp; u32 debugid; @@ -488,7 +488,7 @@ dbglog_parse_debug_logs(s8 *datap, u32 len) u32 length; count = 0; - buffer = (A_INT32 *)datap; + buffer = (s32 *)datap; length = (len >> 2); while (count < length) { debugid = DBGLOG_GET_DBGID(buffer[count]); @@ -2429,7 +2429,7 @@ int ar6000_init(struct net_device *dev) { AR_SOFTC_T *ar; int status; - A_INT32 timeleft; + s32 timeleft; s16 i; int ret = 0; #if defined(INIT_MODE_DRV_ENABLED) && defined(ENABLE_COEXISTENCE) @@ -2767,7 +2767,7 @@ ar6000_init_done: void -ar6000_bitrate_rx(void *devt, A_INT32 rateKbps) +ar6000_bitrate_rx(void *devt, s32 rateKbps) { AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; @@ -5826,8 +5826,7 @@ read_rssi_compensation_param(AR_SOFTC_T *ar) return; } -A_INT32 -rssi_compensation_calc_tcmd(u32 freq, A_INT32 rssi, u32 totalPkt) +s32 rssi_compensation_calc_tcmd(u32 freq, s32 rssi, u32 totalPkt) { if (freq > 5000) diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index bef88eb75e03..339925a84d6e 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -496,7 +496,7 @@ typedef struct ar6_softc { s8 arRssi; u8 arTxPwr; bool arTxPwrSet; - A_INT32 arBitRate; + s32 arBitRate; struct net_device_stats arNetStats; struct iw_statistics arIwStats; s8 arNumChannels; @@ -509,7 +509,7 @@ typedef struct ar6_softc { #ifdef CONFIG_HOST_TCMD_SUPPORT u8 tcmdRxReport; u32 tcmdRxTotalPkt; - A_INT32 tcmdRxRssi; + s32 tcmdRxRssi; u32 tcmdPm; u32 arTargetMode; u32 tcmdRxcrcErrPkt; @@ -552,7 +552,7 @@ typedef struct ar6_softc { u32 dbglog_init_done; u32 arConnectCtrlFlags; #ifdef USER_KEYS - A_INT32 user_savedkeys_stat; + s32 user_savedkeys_stat; u32 user_key_ctrl; struct USER_SAVEDKEYS user_saved_keys; #endif @@ -589,7 +589,7 @@ typedef struct ar6_softc { #endif WMI_BTCOEX_CONFIG_EVENT arBtcoexConfig; WMI_BTCOEX_STATS_EVENT arBtcoexStats; - A_INT32 (*exitCallback)(void *config); /* generic callback at AR6K exit */ + s32 (*exitCallback)(void *config); /* generic callback at AR6K exit */ HIF_DEVICE_OS_DEVICE_INFO osDevInfo; #ifdef ATH6K_CONFIG_CFG80211 struct wireless_dev *wdev; diff --git a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h index 328982fb3a94..a8d3f5498227 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h @@ -42,7 +42,7 @@ void ar6000_disconnect_event(struct ar6_softc *ar, u8 reason, u8 *assocInfo, u16 protocolReasonStatus); void ar6000_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast); -void ar6000_bitrate_rx(void *devt, A_INT32 rateKbps); +void ar6000_bitrate_rx(void *devt, s32 rateKbps); void ar6000_channelList_rx(void *devt, s8 numChan, u16 *chanList); void ar6000_regDomain_event(struct ar6_softc *ar, u32 regCode); void ar6000_txPwr_rx(void *devt, u8 txPwr); @@ -77,7 +77,7 @@ void ar6000_gpio_intr_rx(u32 intr_mask, u32 input_values); void ar6000_gpio_data_rx(u32 reg_id, u32 value); void ar6000_gpio_ack_rx(void); -A_INT32 rssi_compensation_calc_tcmd(u32 freq, A_INT32 rssi, u32 totalPkt); +s32 rssi_compensation_calc_tcmd(u32 freq, s32 rssi, u32 totalPkt); s16 rssi_compensation_calc(struct ar6_softc *ar, s16 rssi); s16 rssi_compensation_reverse_calc(struct ar6_softc *ar, s16 rssi, bool Above); diff --git a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h index a3e65081f98d..383571a1ab3f 100644 --- a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h @@ -1061,8 +1061,8 @@ typedef struct targetStats_t { u64 cs_connect_cnt; u64 cs_disconnect_cnt; - A_INT32 tx_unicast_rate; - A_INT32 rx_unicast_rate; + s32 tx_unicast_rate; + s32 rx_unicast_rate; u32 lq_val; diff --git a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h index 209046f7b93c..eb09d43f44e9 100644 --- a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h @@ -307,16 +307,16 @@ void *a_netbuf_alloc_raw(int size); void a_netbuf_free(void *bufPtr); void *a_netbuf_to_data(void *bufPtr); u32 a_netbuf_to_len(void *bufPtr); -int a_netbuf_push(void *bufPtr, A_INT32 len); -int a_netbuf_push_data(void *bufPtr, char *srcPtr, A_INT32 len); -int a_netbuf_put(void *bufPtr, A_INT32 len); -int a_netbuf_put_data(void *bufPtr, char *srcPtr, A_INT32 len); -int a_netbuf_pull(void *bufPtr, A_INT32 len); -int a_netbuf_pull_data(void *bufPtr, char *dstPtr, A_INT32 len); -int a_netbuf_trim(void *bufPtr, A_INT32 len); -int a_netbuf_trim_data(void *bufPtr, char *dstPtr, A_INT32 len); -int a_netbuf_setlen(void *bufPtr, A_INT32 len); -A_INT32 a_netbuf_headroom(void *bufPtr); +int a_netbuf_push(void *bufPtr, s32 len); +int a_netbuf_push_data(void *bufPtr, char *srcPtr, s32 len); +int a_netbuf_put(void *bufPtr, s32 len); +int a_netbuf_put_data(void *bufPtr, char *srcPtr, s32 len); +int a_netbuf_pull(void *bufPtr, s32 len); +int a_netbuf_pull_data(void *bufPtr, char *dstPtr, s32 len); +int a_netbuf_trim(void *bufPtr, s32 len); +int a_netbuf_trim_data(void *bufPtr, char *dstPtr, s32 len); +int a_netbuf_setlen(void *bufPtr, s32 len); +s32 a_netbuf_headroom(void *bufPtr); void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt); void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt); void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q); diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index a055528588ad..8f7d20ad4f77 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -417,7 +417,7 @@ ar6000_ioctl_set_rssi_threshold(struct net_device *dev, struct ifreq *rq) AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); WMI_RSSI_THRESHOLD_PARAMS_CMD cmd; USER_RSSI_PARAMS rssiParams; - A_INT32 i, j; + s32 i, j; int ret = 0; if (ar->arWmiReady == false) { diff --git a/drivers/staging/ath6kl/os/linux/netbuf.c b/drivers/staging/ath6kl/os/linux/netbuf.c index 580d82985ec8..703a2cdf84c9 100644 --- a/drivers/staging/ath6kl/os/linux/netbuf.c +++ b/drivers/staging/ath6kl/os/linux/netbuf.c @@ -105,7 +105,7 @@ a_netbuf_to_data(void *bufPtr) * pointed to by bufPtr */ int -a_netbuf_push(void *bufPtr, A_INT32 len) +a_netbuf_push(void *bufPtr, s32 len) { skb_push((struct sk_buff *)bufPtr, len); @@ -117,7 +117,7 @@ a_netbuf_push(void *bufPtr, A_INT32 len) * pointed to by bufPtr and also fill with data */ int -a_netbuf_push_data(void *bufPtr, char *srcPtr, A_INT32 len) +a_netbuf_push_data(void *bufPtr, char *srcPtr, s32 len) { skb_push((struct sk_buff *) bufPtr, len); A_MEMCPY(((struct sk_buff *)bufPtr)->data, srcPtr, len); @@ -130,7 +130,7 @@ a_netbuf_push_data(void *bufPtr, char *srcPtr, A_INT32 len) * pointed to by bufPtr */ int -a_netbuf_put(void *bufPtr, A_INT32 len) +a_netbuf_put(void *bufPtr, s32 len) { skb_put((struct sk_buff *)bufPtr, len); @@ -142,7 +142,7 @@ a_netbuf_put(void *bufPtr, A_INT32 len) * pointed to by bufPtr and also fill with data */ int -a_netbuf_put_data(void *bufPtr, char *srcPtr, A_INT32 len) +a_netbuf_put_data(void *bufPtr, char *srcPtr, s32 len) { char *start = (char*)(((struct sk_buff *)bufPtr)->data + ((struct sk_buff *)bufPtr)->len); @@ -157,7 +157,7 @@ a_netbuf_put_data(void *bufPtr, char *srcPtr, A_INT32 len) * Trim the network buffer pointed to by bufPtr to len # of bytes */ int -a_netbuf_setlen(void *bufPtr, A_INT32 len) +a_netbuf_setlen(void *bufPtr, s32 len) { skb_trim((struct sk_buff *)bufPtr, len); @@ -168,7 +168,7 @@ a_netbuf_setlen(void *bufPtr, A_INT32 len) * Chop of len # of bytes from the end of the buffer. */ int -a_netbuf_trim(void *bufPtr, A_INT32 len) +a_netbuf_trim(void *bufPtr, s32 len) { skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len); @@ -179,7 +179,7 @@ a_netbuf_trim(void *bufPtr, A_INT32 len) * Chop of len # of bytes from the end of the buffer and return the data. */ int -a_netbuf_trim_data(void *bufPtr, char *dstPtr, A_INT32 len) +a_netbuf_trim_data(void *bufPtr, char *dstPtr, s32 len) { char *start = (char*)(((struct sk_buff *)bufPtr)->data + (((struct sk_buff *)bufPtr)->len - len)); @@ -194,8 +194,7 @@ a_netbuf_trim_data(void *bufPtr, char *dstPtr, A_INT32 len) /* * Returns the number of bytes available to a a_netbuf_push() */ -A_INT32 -a_netbuf_headroom(void *bufPtr) +s32 a_netbuf_headroom(void *bufPtr) { return (skb_headroom((struct sk_buff *)bufPtr)); } @@ -204,7 +203,7 @@ a_netbuf_headroom(void *bufPtr) * Removes specified number of bytes from the beginning of the buffer */ int -a_netbuf_pull(void *bufPtr, A_INT32 len) +a_netbuf_pull(void *bufPtr, s32 len) { skb_pull((struct sk_buff *)bufPtr, len); @@ -216,7 +215,7 @@ a_netbuf_pull(void *bufPtr, A_INT32 len) * and return the data */ int -a_netbuf_pull_data(void *bufPtr, char *dstPtr, A_INT32 len) +a_netbuf_pull_data(void *bufPtr, char *dstPtr, s32 len) { A_MEMCPY(dstPtr, ((struct sk_buff *)bufPtr)->data, len); skb_pull((struct sk_buff *)bufPtr, len); diff --git a/drivers/staging/ath6kl/os/linux/wireless_ext.c b/drivers/staging/ath6kl/os/linux/wireless_ext.c index df02625fabc2..7cf4f62a3372 100644 --- a/drivers/staging/ath6kl/os/linux/wireless_ext.c +++ b/drivers/staging/ath6kl/os/linux/wireless_ext.c @@ -97,7 +97,7 @@ ar6000_scan_node(void *arg, bss_t *ni) char *end_buf; struct ieee80211_common_ie *cie; char *current_val; - A_INT32 j; + s32 j; u32 rate_len, data_len = 0; param = (struct ar_giwscan_param *)arg; @@ -1007,7 +1007,7 @@ ar6000_ioctl_siwencode(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); int index; - A_INT32 auth = 0; + s32 auth = 0; if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); @@ -1250,8 +1250,8 @@ ar6000_ioctl_siwauth(struct net_device *dev, bool profChanged; u16 param; - A_INT32 ret; - A_INT32 value; + s32 ret; + s32 value; if (ar->arWmiReady == false) { return -EIO; @@ -1419,7 +1419,7 @@ ar6000_ioctl_giwauth(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); u16 param; - A_INT32 ret; + s32 ret; if (ar->arWmiReady == false) { return -EIO; @@ -1546,7 +1546,7 @@ ar6000_ioctl_siwpmksa(struct net_device *dev, struct iw_point *data, char *extra) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - A_INT32 ret; + s32 ret; int status; struct iw_pmksa *pmksa; @@ -1593,11 +1593,11 @@ static int ar6000_set_wapi_key(struct net_device *dev, AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; KEY_USAGE keyUsage = 0; - A_INT32 keyLen; + s32 keyLen; u8 *keyData; - A_INT32 index; + s32 index; u32 *PN; - A_INT32 i; + s32 i; int status; u8 wapiKeyRsc[16]; CRYPTO_TYPE keyType = WAPI_CRYPT; @@ -1653,10 +1653,10 @@ ar6000_ioctl_siwencodeext(struct net_device *dev, struct iw_point *erq, char *extra) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - A_INT32 index; + s32 index; struct iw_encode_ext *ext; KEY_USAGE keyUsage; - A_INT32 keyLen; + s32 keyLen; u8 *keyData; u8 keyRsc[8]; int status; diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index b80bdb7e7643..cae1c2face02 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -153,7 +153,7 @@ static int wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len); static bool -wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex); +wmi_is_bitrate_index_valid(struct wmi_t *wmip, s32 rateIndex); static int wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len); @@ -212,7 +212,7 @@ extern unsigned int processDot11Hdr; #endif int wps_enable; -static const A_INT32 wmi_rateTable[][2] = { +static const s32 wmi_rateTable[][2] = { //{W/O SGI, with SGI} {1000, 1000}, {2000, 2000}, @@ -244,20 +244,20 @@ static const A_INT32 wmi_rateTable[][2] = { {135000, 150000}, {0, 0}}; -#define MODE_A_SUPPORT_RATE_START ((A_INT32) 4) -#define MODE_A_SUPPORT_RATE_STOP ((A_INT32) 11) +#define MODE_A_SUPPORT_RATE_START ((s32) 4) +#define MODE_A_SUPPORT_RATE_STOP ((s32) 11) #define MODE_GONLY_SUPPORT_RATE_START MODE_A_SUPPORT_RATE_START #define MODE_GONLY_SUPPORT_RATE_STOP MODE_A_SUPPORT_RATE_STOP -#define MODE_B_SUPPORT_RATE_START ((A_INT32) 0) -#define MODE_B_SUPPORT_RATE_STOP ((A_INT32) 3) +#define MODE_B_SUPPORT_RATE_START ((s32) 0) +#define MODE_B_SUPPORT_RATE_STOP ((s32) 3) -#define MODE_G_SUPPORT_RATE_START ((A_INT32) 0) -#define MODE_G_SUPPORT_RATE_STOP ((A_INT32) 11) +#define MODE_G_SUPPORT_RATE_START ((s32) 0) +#define MODE_G_SUPPORT_RATE_STOP ((s32) 11) -#define MODE_GHT20_SUPPORT_RATE_START ((A_INT32) 0) -#define MODE_GHT20_SUPPORT_RATE_STOP ((A_INT32) 19) +#define MODE_GHT20_SUPPORT_RATE_START ((s32) 0) +#define MODE_GHT20_SUPPORT_RATE_STOP ((s32) 19) #define MAX_NUMBER_OF_SUPPORT_RATES (MODE_GHT20_SUPPORT_RATE_STOP + 1) @@ -1657,7 +1657,7 @@ static int wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap, int len) { WMI_BIT_RATE_REPLY *reply; - A_INT32 rate; + s32 rate; u32 sgi,index; /* 54149: * WMI_BIT_RATE_CMD structure is changed to WMI_BIT_RATE_REPLY. @@ -3201,8 +3201,8 @@ wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params) void *osbuf; WMI_CREATE_PSTREAM_CMD *cmd; u8 fatPipeExistsForAC=0; - A_INT32 minimalPHY = 0; - A_INT32 nominalPHY = 0; + s32 minimalPHY = 0; + s32 nominalPHY = 0; /* Validate all the parameters. */ if( !((params->userPriority < 8) && @@ -3395,7 +3395,7 @@ wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, u16 r * then auto selection is used. */ int -wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 dataRate, A_INT32 mgmtRate, A_INT32 ctlRate) +wmi_set_bitrate_cmd(struct wmi_t *wmip, s32 dataRate, s32 mgmtRate, s32 ctlRate) { void *osbuf; WMI_BIT_RATE_CMD *cmd; @@ -3454,7 +3454,7 @@ wmi_get_bitrate_cmd(struct wmi_t *wmip) * Returns true iff the given rate index is legal in the current PHY mode. */ bool -wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex) +wmi_is_bitrate_index_valid(struct wmi_t *wmip, s32 rateIndex) { WMI_PHY_MODE phyMode = (WMI_PHY_MODE) wmip->wmi_phyMode; bool isValid = true; @@ -3509,7 +3509,7 @@ wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex) return isValid; } -s8 wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, s8 *rate_idx) +s8 wmi_validate_bitrate(struct wmi_t *wmip, s32 rate, s8 *rate_idx) { s8 i; @@ -3523,7 +3523,7 @@ s8 wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, s8 *rate_idx) } } - if(wmi_is_bitrate_index_valid(wmip, (A_INT32) i) != true) { + if(wmi_is_bitrate_index_valid(wmip, (s32) i) != true) { return A_EINVAL; } @@ -3537,7 +3537,7 @@ wmi_set_fixrates_cmd(struct wmi_t *wmip, u32 fixRatesMask) void *osbuf; WMI_FIX_RATES_CMD *cmd; #if 0 - A_INT32 rateIndex; + s32 rateIndex; /* This check does not work for AR6003 as the HT modes are enabled only when * the STA is connected to a HT_BSS and is not based only on channel. It is * safe to skip this check however because rate control will only use rates @@ -5349,8 +5349,7 @@ wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, u16 dataLen) return (wmi_cmd_send(wmip, osbuf, WMI_SET_WHALPARAM_CMDID, NO_SYNC_WMIFLAG)); } -A_INT32 -wmi_get_rate(s8 rateindex) +s32 wmi_get_rate(s8 rateindex) { if (rateindex == RATE_AUTO) { return 0; -- cgit v1.2.3 From a1d46529630cbe1072b7b7b1a0104655b47cd7de Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 2 Feb 2011 14:05:56 -0800 Subject: staging: ath6kl: Convert (status != A_OK) to (status) Just use the status variable as a test not a comparison. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/bmi/src/bmi.c | 52 +++++++++++----------- .../staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 2 +- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 36 +++++++-------- drivers/staging/ath6kl/htc2/htc.c | 2 +- drivers/staging/ath6kl/miscdrv/common_drv.c | 22 ++++----- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 26 +++++------ drivers/staging/ath6kl/os/linux/ar6000_pm.c | 12 ++--- drivers/staging/ath6kl/os/linux/cfg80211.c | 8 ++-- drivers/staging/ath6kl/os/linux/hci_bridge.c | 2 +- drivers/staging/ath6kl/os/linux/ioctl.c | 4 +- drivers/staging/ath6kl/os/linux/wireless_ext.c | 6 +-- drivers/staging/ath6kl/reorder/rcv_aggr.c | 2 +- 12 files changed, 87 insertions(+), 87 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/bmi/src/bmi.c b/drivers/staging/ath6kl/bmi/src/bmi.c index 44add2d99f55..104c53e430bb 100644 --- a/drivers/staging/ath6kl/bmi/src/bmi.c +++ b/drivers/staging/ath6kl/bmi/src/bmi.c @@ -121,7 +121,7 @@ BMIDone(HIF_DEVICE *device) cid = BMI_DONE; status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid)); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); return A_ERROR; } @@ -156,14 +156,14 @@ BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) cid = BMI_GET_TARGET_INFO; status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid)); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); return A_ERROR; } status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_ver, sizeof(targ_info->target_ver), true); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Version from the device\n")); return A_ERROR; } @@ -172,7 +172,7 @@ BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) /* Determine how many bytes are in the Target's targ_info */ status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_info_byte_count, sizeof(targ_info->target_info_byte_count), true); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info Byte Count from the device\n")); return A_ERROR; } @@ -187,7 +187,7 @@ BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) status = bmiBufferReceive(device, ((A_UCHAR *)targ_info)+sizeof(targ_info->target_info_byte_count), sizeof(*targ_info)-sizeof(targ_info->target_info_byte_count), true); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info (%d bytes) from the device\n", targ_info->target_info_byte_count)); return A_ERROR; @@ -239,12 +239,12 @@ BMIReadMemory(HIF_DEVICE *device, offset += sizeof(length); status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); return A_ERROR; } status = bmiBufferReceive(device, pBMICmdBuf, rxlen, true); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); return A_ERROR; } @@ -309,7 +309,7 @@ BMIWriteMemory(HIF_DEVICE *device, A_MEMCPY(&(pBMICmdBuf[offset]), src, txlen); offset += txlen; status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); return A_ERROR; } @@ -352,13 +352,13 @@ BMIExecute(HIF_DEVICE *device, A_MEMCPY(&(pBMICmdBuf[offset]), param, sizeof(*param)); offset += sizeof(*param); status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); return A_ERROR; } status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), false); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); return A_ERROR; } @@ -397,7 +397,7 @@ BMISetAppStart(HIF_DEVICE *device, A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); offset += sizeof(address); status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); return A_ERROR; } @@ -436,13 +436,13 @@ BMIReadSOCRegister(HIF_DEVICE *device, offset += sizeof(address); status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); return A_ERROR; } status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), true); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); return A_ERROR; } @@ -483,7 +483,7 @@ BMIWriteSOCRegister(HIF_DEVICE *device, A_MEMCPY(&(pBMICmdBuf[offset]), ¶m, sizeof(param)); offset += sizeof(param); status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); return A_ERROR; } @@ -532,13 +532,13 @@ BMIrompatchInstall(HIF_DEVICE *device, A_MEMCPY(&(pBMICmdBuf[offset]), &do_activate, sizeof(do_activate)); offset += sizeof(do_activate); status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); return A_ERROR; } status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*rompatch_id), true); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); return A_ERROR; } @@ -576,7 +576,7 @@ BMIrompatchUninstall(HIF_DEVICE *device, A_MEMCPY(&(pBMICmdBuf[offset]), &rompatch_id, sizeof(rompatch_id)); offset += sizeof(rompatch_id); status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); return A_ERROR; } @@ -619,7 +619,7 @@ _BMIrompatchChangeActivation(HIF_DEVICE *device, A_MEMCPY(&(pBMICmdBuf[offset]), rompatch_list, length); offset += length; status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); return A_ERROR; } @@ -683,7 +683,7 @@ BMILZData(HIF_DEVICE *device, A_MEMCPY(&(pBMICmdBuf[offset]), &buffer[length - remaining], txlen); offset += txlen; status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); return A_ERROR; } @@ -722,7 +722,7 @@ BMILZStreamStart(HIF_DEVICE *device, A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); offset += sizeof(address); status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to Start LZ Stream to the device\n")); return A_ERROR; } @@ -757,7 +757,7 @@ bmiBufferSend(HIF_DEVICE *device, * make all HIF accesses 4-byte aligned */ status = HIFReadWrite(device, address, (u8 *)pBMICmdCredits, 4, HIF_RD_SYNC_BYTE_INC, NULL); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to decrement the command credit count register\n")); return A_ERROR; } @@ -769,7 +769,7 @@ bmiBufferSend(HIF_DEVICE *device, address = mboxAddress[ENDPOINT1]; status = HIFReadWrite(device, address, buffer, length, HIF_WR_SYNC_BYTE_INC, NULL); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to send the BMI data to the device\n")); return A_ERROR; } @@ -868,7 +868,7 @@ bmiBufferReceive(HIF_DEVICE *device, status = getPendingEventsFunc(device, &hifPendingEvents, NULL); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMI: Failed to get pending events \n")); break; } @@ -881,7 +881,7 @@ bmiBufferReceive(HIF_DEVICE *device, status = HIFReadWrite(device, RX_LOOKAHEAD_VALID_ADDRESS, (u8 *)&word_available, sizeof(word_available), HIF_RD_SYNC_BYTE_INC, NULL); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read RX_LOOKAHEAD_VALID register\n")); return A_ERROR; } @@ -932,7 +932,7 @@ bmiBufferReceive(HIF_DEVICE *device, * The rationale here is to make all HIF accesses a multiple of 4 bytes */ status = HIFReadWrite(device, address, (u8 *)pBMICmdCredits, sizeof(*pBMICmdCredits), HIF_RD_SYNC_BYTE_FIX, NULL); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the command credit count register\n")); return A_ERROR; } @@ -949,7 +949,7 @@ bmiBufferReceive(HIF_DEVICE *device, address = mboxAddress[ENDPOINT1]; status = HIFReadWrite(device, address, buffer, length, HIF_RD_SYNC_BYTE_INC, NULL); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the BMI data from the device\n")); return A_ERROR; } diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index 57cb1f70dcf1..773d134192d6 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -1088,7 +1088,7 @@ static int hifDeviceSuspend(struct device *dev) if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) { device->is_suspend = true; /* set true first for PowerStateChangeNotify(..) */ status = osdrvCallbacks.deviceSuspendHandler(device->claimedContext); - if (status != A_OK) { + if (status) { device->is_suspend = false; } } diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index 0f57cfc29549..ed51a8da965b 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -106,7 +106,7 @@ int DevSetup(AR6K_DEVICE *pDev) status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR, &pDev->MailBoxInfo, sizeof(pDev->MailBoxInfo)); - if (status != A_OK) { + if (status) { A_ASSERT(false); break; } @@ -127,7 +127,7 @@ int DevSetup(AR6K_DEVICE *pDev) status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE, blocksizes, sizeof(blocksizes)); - if (status != A_OK) { + if (status) { A_ASSERT(false); break; } @@ -266,7 +266,7 @@ int DevEnableInterrupts(AR6K_DEVICE *pDev) HIF_WR_SYNC_BYTE_INC, NULL); - if (status != A_OK) { + if (status) { /* Can't write it for some reason */ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to update interrupt control registers err: %d\n", status)); @@ -510,7 +510,7 @@ int DevWaitForPendingRecv(AR6K_DEVICE *pDev,u32 TimeoutInMs,bool *pbIsRecvPendin sizeof(A_UCHAR), HIF_RD_SYNC_BYTE_INC, NULL); - if(status) + if (status) { AR_DEBUG_PRINTF(ATH_LOG_ERR,("DevWaitForPendingRecv:Read HOST_INT_STATUS_ADDRESS Failed 0x%X\n",status)); break; @@ -1156,7 +1156,7 @@ static int SendBuffers(AR6K_DEVICE *pDev, int mbox) paddedLength, request, NULL); - if (status != A_OK) { + if (status) { break; } totalBytes += sendList[i].length; @@ -1182,7 +1182,7 @@ static int GetCredits(AR6K_DEVICE *pDev, int mbox, int *pCredits) address = COUNT_DEC_ADDRESS + (AR6K_MAILBOXES + mbox) * 4; status = HIFReadWrite(pDev->HIFDevice, address, &credits, sizeof(credits), HIF_RD_SYNC_BYTE_FIX, NULL); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to decrement the command credit count register (mbox=%d)\n",mbox)); status = A_ERROR; @@ -1244,7 +1244,7 @@ static int RecvBuffers(AR6K_DEVICE *pDev, int mbox) * until we get at least 1 credit or it times out */ status = GetCredits(pDev, mbox, &credits); - if (status != A_OK) { + if (status) { break; } @@ -1264,7 +1264,7 @@ static int RecvBuffers(AR6K_DEVICE *pDev, int mbox) paddedLength, request, NULL); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to read %d bytes on mailbox:%d : address:0x%X \n", recvList[curBuffer].length, mbox, g_MailboxAddrs[mbox])); break; @@ -1275,7 +1275,7 @@ static int RecvBuffers(AR6K_DEVICE *pDev, int mbox) curBuffer++; } - if (status != A_OK) { + if (status) { break; } /* go back and get some more */ @@ -1302,7 +1302,7 @@ static int DoOneMboxHWTest(AR6K_DEVICE *pDev, int mbox) /* send out buffers */ status = SendBuffers(pDev,mbox); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Sending buffers Failed : %d mbox:%d\n",status,mbox)); break; } @@ -1310,7 +1310,7 @@ static int DoOneMboxHWTest(AR6K_DEVICE *pDev, int mbox) /* go get them, this will block */ status = RecvBuffers(pDev, mbox); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Recv buffers Failed : %d mbox:%d\n",status,mbox)); break; } @@ -1348,7 +1348,7 @@ int DoMboxHWTest(AR6K_DEVICE *pDev) status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR, g_MailboxAddrs, sizeof(g_MailboxAddrs)); - if (status != A_OK) { + if (status) { A_ASSERT(false); break; } @@ -1357,7 +1357,7 @@ int DoMboxHWTest(AR6K_DEVICE *pDev) status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE, g_BlockSizes, sizeof(g_BlockSizes)); - if (status != A_OK) { + if (status) { A_ASSERT(false); break; } @@ -1380,7 +1380,7 @@ int DoMboxHWTest(AR6K_DEVICE *pDev) * mailbox 0 */ status = GetCredits(pDev, 0, &credits); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to wait for target ready \n")); break; } @@ -1395,7 +1395,7 @@ int DoMboxHWTest(AR6K_DEVICE *pDev) HIF_RD_SYNC_BYTE_INC, NULL); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to wait get parameters \n")); break; } @@ -1423,7 +1423,7 @@ int DoMboxHWTest(AR6K_DEVICE *pDev) HIF_WR_SYNC_BYTE_INC, NULL); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to write end marker \n")); break; } @@ -1440,7 +1440,7 @@ int DoMboxHWTest(AR6K_DEVICE *pDev) HIF_WR_SYNC_BYTE_INC, NULL); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to write block mask \n")); break; } @@ -1450,7 +1450,7 @@ int DoMboxHWTest(AR6K_DEVICE *pDev) /* execute the test on each mailbox */ for (i = 0; i < AR6K_MAILBOXES; i++) { status = DoOneMboxHWTest(pDev, i); - if (status != A_OK) { + if (status) { break; } } diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index afc523f81bcb..cf88a9af8053 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -240,7 +240,7 @@ int HTCWaitTarget(HTC_HANDLE HTCHandle) status = DoMboxHWTest(&target->Device); - if (status != A_OK) { + if (status) { break; } diff --git a/drivers/staging/ath6kl/miscdrv/common_drv.c b/drivers/staging/ath6kl/miscdrv/common_drv.c index 0c9c8a34264b..bf71f96847e1 100644 --- a/drivers/staging/ath6kl/miscdrv/common_drv.c +++ b/drivers/staging/ath6kl/miscdrv/common_drv.c @@ -107,12 +107,12 @@ int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, u32 RegisterAddr, u32 4, HIF_WR_SYNC_BYTE_FIX, NULL); - if (status != A_OK) { + if (status) { break; } } - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n", Address, RegisterAddr)); return status; @@ -128,7 +128,7 @@ int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, u32 RegisterAddr, u32 HIF_WR_SYNC_BYTE_INC, NULL); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n", Address, RegisterAddr)); return status; @@ -157,7 +157,7 @@ int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, u32 RegisterAddr, u32 HIF_WR_SYNC_BYTE_INC, NULL); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n", RegisterAddr, Address)); return status; @@ -171,7 +171,7 @@ int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, u32 RegisterAddr, u32 HIF_WR_SYNC_BYTE_INC, NULL); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n", RegisterAddr, Address)); return status; @@ -196,7 +196,7 @@ ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data) WINDOW_READ_ADDR_ADDRESS, *address); - if (status != A_OK) { + if (status) { return status; } @@ -207,7 +207,7 @@ ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data) sizeof(u32), HIF_RD_SYNC_BYTE_INC, NULL); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from WINDOW_DATA_ADDRESS\n")); return status; } @@ -232,7 +232,7 @@ ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data) sizeof(u32), HIF_WR_SYNC_BYTE_INC, NULL); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to WINDOW_DATA_ADDRESS\n", *data)); return status; } @@ -294,7 +294,7 @@ ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, u32 *regval) HIF_WR_SYNC_BYTE_FIX, NULL); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write CPU_DBG_SEL (%d)\n", regsel)); return status; } @@ -305,7 +305,7 @@ ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, u32 *regval) sizeof(vals), HIF_RD_SYNC_BYTE_INC, NULL); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from CPU_DBG_ADDRESS\n")); return status; } @@ -335,7 +335,7 @@ _do_write_diag(HIF_DEVICE *hifDevice, u32 addr, u32 value) int status; status = ar6000_WriteRegDiag(hifDevice, &addr, &value); - if (status != A_OK) + if (status) { AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot force Target to execute ROM!\n")); } diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index ed82a3ba568a..f08c08b16684 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -692,7 +692,7 @@ ar6000_init_module(void) #endif /* CONFIG_HOST_GPIO_SUPPORT */ status = HIFInit(&osdrvCallbacks); - if(status != A_OK) + if (status) return -ENODEV; return 0; @@ -1126,7 +1126,7 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, u32 address, bool c status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (A_UCHAR *)(fw_entry->data + board_data_size), board_ext_data_size); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); A_RELEASE_FIRMWARE(fw_entry); return A_ERROR; @@ -1145,7 +1145,7 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, u32 address, bool c status = BMIWriteMemory(ar->arHifDevice, address, (A_UCHAR *)fw_entry->data, fw_entry_size); } - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); A_RELEASE_FIRMWARE(fw_entry); return A_ERROR; @@ -1808,12 +1808,12 @@ ar6000_avail_ev(void *context, void *hif_handle) rtnl_lock(); status = (ar6000_init(dev)==0) ? A_OK : A_ERROR; rtnl_unlock(); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_init\n")); } } while (false); - if (status != A_OK) { + if (status) { init_status = status; goto avail_ev_failed; } @@ -1911,7 +1911,7 @@ ar6000_restart_endpoint(struct net_device *dev) status = (ar6000_init(dev)==0) ? A_OK : A_ERROR; rtnl_unlock(); - if (status!=A_OK) { + if (status) { break; } if (ar->arSsidLen && ar->arWlanState == WLAN_ENABLED) { @@ -2666,7 +2666,7 @@ int ar6000_init(struct net_device *dev) /* start HTC */ status = HTCStart(ar->arHtcTarget); - if (status != A_OK) { + if (status) { if (ar->arWmiEnabled == true) { wmi_shutdown(ar->arWmi); ar->arWmiEnabled = false; @@ -3575,13 +3575,13 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) int status = pPacket->Status; HTC_ENDPOINT_ID ept = pPacket->Endpoint; - A_ASSERT((status != A_OK) || + A_ASSERT((status) || (pPacket->pBuffer == (A_NETBUF_DATA(skb) + HTC_HEADER_LEN))); AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_rx ar=0x%lx eid=%d, skb=0x%lx, data=0x%lx, len=0x%x status:%d", (unsigned long)ar, ept, (unsigned long)skb, (unsigned long)pPacket->pBuffer, pPacket->ActualLength, status)); - if (status != A_OK) { + if (status) { if (status != A_ECANCELED) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("RX ERR (%d) \n",status)); } @@ -3612,7 +3612,7 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) AR6000_SPIN_UNLOCK(&ar->arLock, 0); skb->dev = ar->arNetDev; - if (status != A_OK) { + if (status) { AR6000_STAT_INC(ar, rx_errors); A_NETBUF_FREE(skb); } else if (ar->arWmiEnabled == true) { @@ -3790,7 +3790,7 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) status = wmi_dot3_2_dix(skb); } - if (status != A_OK) { + if (status) { /* Drop frames that could not be processed (lack of memory, etc.) */ A_NETBUF_FREE(skb); goto rx_done; @@ -5335,7 +5335,7 @@ ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid) status = A_OK; } - if (status != A_OK) { + if (status) { A_NETBUF_FREE(osbuf); } return status; @@ -6141,7 +6141,7 @@ ar6000_connect_to_ap(struct ar6_softc *ar) ar->arSsidLen, ar->arSsid, ar->arReqBssid, ar->arChannelHint, ar->arConnectCtrlFlags); - if (status != A_OK) { + if (status) { wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB); if (!ar->arUserBssFilter) { wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0); diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c index 0995bbbb4e38..d2d18dad5ff1 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_pm.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_pm.c @@ -155,7 +155,7 @@ static void ar6000_wow_suspend(AR_SOFTC_T *ar) addWowCmd.filter_size = 6; /* MAC address */ addWowCmd.filter_offset = 0; status = wmi_add_wow_pattern_cmd(ar->arWmi, &addWowCmd, ar->arNetDev->dev_addr, macMask, addWowCmd.filter_size); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to add WoW pattern\n")); } } @@ -172,7 +172,7 @@ static void ar6000_wow_suspend(AR_SOFTC_T *ar) memset(&ipCmd, 0, sizeof(ipCmd)); ipCmd.ips[0] = ifa->ifa_local; status = wmi_set_ip_cmd(ar->arWmi, &ipCmd); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup IP for ARP agent\n")); } } @@ -182,13 +182,13 @@ static void ar6000_wow_suspend(AR_SOFTC_T *ar) #endif status = wmi_set_wow_mode_cmd(ar->arWmi, &wowMode); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to enable wow mode\n")); } ar6k_send_asleep_event_to_app(ar, true); status = wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to set host asleep\n")); } @@ -529,7 +529,7 @@ ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) } } while (0); - if (status!=A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to enter/exit deep sleep %d\n", state)); } @@ -628,7 +628,7 @@ ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool } - if (status!=A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup WLAN state %d\n", ar->arWlanState)); ar->arWlanState = oldstate; } else if (status == A_OK) { diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index dcbb062818c7..92aeda6b41bd 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -311,7 +311,7 @@ ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, ar->arChannelHint); up(&ar->arSem); - if (status != A_OK) { + if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_reconnect_cmd failed\n", __func__)); return -EIO; } @@ -410,7 +410,7 @@ ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, ar->arSsidLen = 0; AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Invalid request\n", __func__)); return -ENOENT; - } else if (status != A_OK) { + } else if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_connect_cmd failed\n", __func__)); return -EIO; } @@ -892,7 +892,7 @@ ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, (u8 *)mac_addr, SYNC_BOTH_WMIFLAG); - if(status != A_OK) { + if (status) { return -EIO; } @@ -1015,7 +1015,7 @@ ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, ar->arPairwiseCrypto, GROUP_USAGE | TX_USAGE, key->key_len, key->seq, key->key, KEY_OP_INIT_VAL, NULL, SYNC_BOTH_WMIFLAG); - if (status != A_OK) { + if (status) { return -EIO; } diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index f8ac5fc161d1..82cf52fee4f5 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -1127,7 +1127,7 @@ hcibridge_init_module(void) hciTransCallbacks.cleanupTransport = ar6000_cleanup_hci; status = ar6000_register_hci_transport(&hciTransCallbacks); - if(status != A_OK) + if (status) return -ENODEV; return 0; diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index 8f7d20ad4f77..3463a5008767 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -1826,7 +1826,7 @@ ar6000_ioctl_setkey(AR_SOFTC_T *ar, struct ieee80211req_key *ik) ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr, SYNC_BOTH_WMIFLAG); - if (status != A_OK) { + if (status) { return -EIO; } } else { @@ -2003,7 +2003,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) status = wmi_setPmkid_cmd(ar->arWmi, req.pi_bssid, req.pi_pmkid, req.pi_enable); - if (status != A_OK) { + if (status) { ret = -EIO; goto ioctl_done; } diff --git a/drivers/staging/ath6kl/os/linux/wireless_ext.c b/drivers/staging/ath6kl/os/linux/wireless_ext.c index 7cf4f62a3372..6d3ae2ce296d 100644 --- a/drivers/staging/ath6kl/os/linux/wireless_ext.c +++ b/drivers/staging/ath6kl/os/linux/wireless_ext.c @@ -622,7 +622,7 @@ ar6000_ioctl_siwessid(struct net_device *dev, status = wmi_reconnect_cmd(ar->arWmi,ar->arReqBssid, ar->arChannelHint); up(&ar->arSem); - if (status != A_OK) { + if (status) { return -EIO; } return 0; @@ -1575,7 +1575,7 @@ ar6000_ioctl_siwpmksa(struct net_device *dev, ret=-1; break; } - if (status != A_OK) { + if (status) { ret = -1; } @@ -1793,7 +1793,7 @@ ar6000_ioctl_siwencodeext(struct net_device *dev, keyData, KEY_OP_INIT_VAL, (u8 *)ext->addr.sa_data, SYNC_BOTH_WMIFLAG); - if (status != A_OK) { + if (status) { return -EIO; } diff --git a/drivers/staging/ath6kl/reorder/rcv_aggr.c b/drivers/staging/ath6kl/reorder/rcv_aggr.c index 5eeb6e3b54e5..dc1ea558bf32 100644 --- a/drivers/staging/ath6kl/reorder/rcv_aggr.c +++ b/drivers/staging/ath6kl/reorder/rcv_aggr.c @@ -92,7 +92,7 @@ aggr_init(ALLOC_NETBUFS netbuf_allocator) A_PRINTF("going out of aggr_init..status %s\n", (status == A_OK) ? "OK":"Error"); - if(status != A_OK) { + if (status) { /* Cleanup */ aggr_module_destroy(p_aggr); } -- cgit v1.2.3 From 4f69cef0a978e8efc2b2a5c0666bb59f39426685 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 2 Feb 2011 14:05:57 -0800 Subject: staging: ath6kl: Remove #define A_OK Just use 0. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/bmi/src/bmi.c | 30 +-- .../staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 46 ++--- .../ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c | 8 +- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 34 ++-- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 12 +- drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c | 18 +- drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c | 18 +- .../ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c | 28 +-- drivers/staging/ath6kl/htc2/htc.c | 2 +- drivers/staging/ath6kl/htc2/htc_recv.c | 18 +- drivers/staging/ath6kl/htc2/htc_send.c | 4 +- drivers/staging/ath6kl/htc2/htc_services.c | 4 +- drivers/staging/ath6kl/include/common/athdefs.h | 3 +- drivers/staging/ath6kl/include/common/wmi.h | 2 +- drivers/staging/ath6kl/include/hci_transport_api.h | 14 +- drivers/staging/ath6kl/include/htc_api.h | 8 +- drivers/staging/ath6kl/miscdrv/ar3kconfig.c | 16 +- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c | 30 +-- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c | 10 +- drivers/staging/ath6kl/miscdrv/common_drv.c | 44 ++--- drivers/staging/ath6kl/miscdrv/credit_dist.c | 2 +- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 156 +++++++-------- drivers/staging/ath6kl/os/linux/ar6000_pm.c | 50 ++--- drivers/staging/ath6kl/os/linux/ar6000_raw_if.c | 8 +- drivers/staging/ath6kl/os/linux/ar6k_pal.c | 16 +- drivers/staging/ath6kl/os/linux/cfg80211.c | 20 +- .../staging/ath6kl/os/linux/export_hci_transport.c | 2 +- drivers/staging/ath6kl/os/linux/hci_bridge.c | 20 +- drivers/staging/ath6kl/os/linux/ioctl.c | 210 ++++++++++----------- drivers/staging/ath6kl/os/linux/netbuf.c | 18 +- drivers/staging/ath6kl/os/linux/wireless_ext.c | 74 ++++---- drivers/staging/ath6kl/reorder/rcv_aggr.c | 8 +- drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c | 2 +- drivers/staging/ath6kl/wmi/wmi.c | 186 +++++++++--------- 34 files changed, 560 insertions(+), 561 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/bmi/src/bmi.c b/drivers/staging/ath6kl/bmi/src/bmi.c index 104c53e430bb..49aed8ac2dc2 100644 --- a/drivers/staging/ath6kl/bmi/src/bmi.c +++ b/drivers/staging/ath6kl/bmi/src/bmi.c @@ -113,7 +113,7 @@ BMIDone(HIF_DEVICE *device) if (bmiDone) { AR_DEBUG_PRINTF (ATH_DEBUG_BMI, ("BMIDone skipped\n")); - return A_OK; + return 0; } AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Enter (device: 0x%p)\n", device)); @@ -138,7 +138,7 @@ BMIDone(HIF_DEVICE *device) AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Exit\n")); - return A_OK; + return 0; } int @@ -197,7 +197,7 @@ BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Exit (ver: 0x%x type: 0x%x)\n", targ_info->target_ver, targ_info->target_type)); - return A_OK; + return 0; } int @@ -253,7 +253,7 @@ BMIReadMemory(HIF_DEVICE *device, } AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read Memory: Exit\n")); - return A_OK; + return 0; } int @@ -318,7 +318,7 @@ BMIWriteMemory(HIF_DEVICE *device, AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Write Memory: Exit\n")); - return A_OK; + return 0; } int @@ -366,7 +366,7 @@ BMIExecute(HIF_DEVICE *device, A_MEMCPY(param, pBMICmdBuf, sizeof(*param)); AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Execute: Exit (param: %d)\n", *param)); - return A_OK; + return 0; } int @@ -403,7 +403,7 @@ BMISetAppStart(HIF_DEVICE *device, } AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Set App Start: Exit\n")); - return A_OK; + return 0; } int @@ -449,7 +449,7 @@ BMIReadSOCRegister(HIF_DEVICE *device, A_MEMCPY(param, pBMICmdBuf, sizeof(*param)); AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit (value: %d)\n", *param)); - return A_OK; + return 0; } int @@ -489,7 +489,7 @@ BMIWriteSOCRegister(HIF_DEVICE *device, } AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit\n")); - return A_OK; + return 0; } int @@ -545,7 +545,7 @@ BMIrompatchInstall(HIF_DEVICE *device, A_MEMCPY(rompatch_id, pBMICmdBuf, sizeof(*rompatch_id)); AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch Install: (rompatch_id=%d)\n", *rompatch_id)); - return A_OK; + return 0; } int @@ -582,7 +582,7 @@ BMIrompatchUninstall(HIF_DEVICE *device, } AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch UNinstall: (rompatch_id=0x%x)\n", rompatch_id)); - return A_OK; + return 0; } static int @@ -626,7 +626,7 @@ _BMIrompatchChangeActivation(HIF_DEVICE *device, AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Change rompatch Activation: Exit\n")); - return A_OK; + return 0; } int @@ -692,7 +692,7 @@ BMILZData(HIF_DEVICE *device, AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Data: Exit\n")); - return A_OK; + return 0; } int @@ -729,7 +729,7 @@ BMILZStreamStart(HIF_DEVICE *device, AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Stream Start: Exit\n")); - return A_OK; + return 0; } /* BMI Access routines */ @@ -954,7 +954,7 @@ bmiBufferReceive(HIF_DEVICE *device, return A_ERROR; } - return A_OK; + return 0; } int diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index 773d134192d6..4d6feeae2882 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -148,7 +148,7 @@ int HIFInit(OSDRV_CALLBACKS *callbacks) return A_ERROR; } - return A_OK; + return 0; } @@ -161,7 +161,7 @@ __HIFReadWrite(HIF_DEVICE *device, void *context) { u8 opcode; - int status = A_OK; + int status = 0; int ret; u8 *tbuffer; bool bounced = false; @@ -337,7 +337,7 @@ HIFReadWrite(HIF_DEVICE *device, u32 request, void *context) { - int status = A_OK; + int status = 0; BUS_REQUEST *busrequest; @@ -644,13 +644,13 @@ int ReinitSDIO(HIF_DEVICE *device) sdio_release_host(func); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -ReinitSDIO \n")); - return (err) ? A_ERROR : A_OK; + return (err) ? A_ERROR : 0; } int PowerStateChangeNotify(HIF_DEVICE *device, HIF_DEVICE_POWER_CHANGE_TYPE config) { - int status = A_OK; + int status = 0; #if defined(CONFIG_PM) struct sdio_func *func = device->func; int old_reset_val; @@ -678,7 +678,7 @@ PowerStateChangeNotify(HIF_DEVICE *device, HIF_DEVICE_POWER_CHANGE_TYPE config) if (device->powerConfig == HIF_DEVICE_POWER_CUT) { status = ReinitSDIO(device); } - if (status == A_OK) { + if (status == 0) { status = hifEnableFunc(device, func); } break; @@ -695,7 +695,7 @@ HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, void *config, u32 configLen) { u32 count; - int status = A_OK; + int status = 0; switch(opcode) { case HIF_DEVICE_GET_MBOX_BLOCK_SIZE: @@ -785,7 +785,7 @@ hifIRQHandler(struct sdio_func *func) status = device->htcCallbacks.dsrHandler(device->htcCallbacks.context); sdio_claim_host(device->func); atomic_set(&device->irqHandling, 0); - AR_DEBUG_ASSERT(status == A_OK || status == A_ECANCELED); + AR_DEBUG_ASSERT(status == 0 || status == A_ECANCELED); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifIRQHandler\n")); } @@ -797,7 +797,7 @@ static int startup_task(void *param) device = (HIF_DEVICE *)param; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call HTC from startup_task\n")); /* start up inform DRV layer */ - if ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context,device)) != A_OK) { + if ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context,device)) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n")); } return 0; @@ -814,7 +814,7 @@ static int enable_task(void *param) if (device && device->claimedContext && osdrvCallbacks.devicePowerChangeHandler && - osdrvCallbacks.devicePowerChangeHandler(device->claimedContext, HIF_DEVICE_POWER_UP) != A_OK) + osdrvCallbacks.devicePowerChangeHandler(device->claimedContext, HIF_DEVICE_POWER_UP) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n")); } @@ -952,7 +952,7 @@ hifFreeBusRequest(HIF_DEVICE *device, BUS_REQUEST *busrequest) static int hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func) { int ret; - int status = A_OK; + int status = 0; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDisableFunc\n")); device = getHifDevice(func); @@ -988,7 +988,7 @@ static int hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func) sdio_release_host(device->func); - if (status == A_OK) { + if (status == 0) { device->is_disabled = true; } AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDisableFunc\n")); @@ -1001,7 +1001,7 @@ static int hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func) struct task_struct* pTask; const char *taskName = NULL; int (*taskFunc)(void *) = NULL; - int ret = A_OK; + int ret = 0; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifEnableFunc\n")); device = getHifDevice(func); @@ -1055,7 +1055,7 @@ static int hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func) if (!device->claimedContext) { taskFunc = startup_task; taskName = "AR6K startup"; - ret = A_OK; + ret = 0; #if defined(CONFIG_PM) } else { taskFunc = enable_task; @@ -1080,7 +1080,7 @@ static int hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func) static int hifDeviceSuspend(struct device *dev) { struct sdio_func *func=dev_to_sdio_func(dev); - int status = A_OK; + int status = 0; HIF_DEVICE *device; device = getHifDevice(func); @@ -1095,7 +1095,7 @@ static int hifDeviceSuspend(struct device *dev) AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceSuspend\n")); switch (status) { - case A_OK: + case 0: return 0; case A_EBUSY: return -EBUSY; /* Hack for kernel in order to support deep sleep and wow */ @@ -1107,14 +1107,14 @@ static int hifDeviceSuspend(struct device *dev) static int hifDeviceResume(struct device *dev) { struct sdio_func *func=dev_to_sdio_func(dev); - int status = A_OK; + int status = 0; HIF_DEVICE *device; device = getHifDevice(func); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceResume\n")); if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) { status = osdrvCallbacks.deviceResumeHandler(device->claimedContext); - if (status == A_OK) { + if (status == 0) { device->is_suspend = false; } } @@ -1126,7 +1126,7 @@ static int hifDeviceResume(struct device *dev) static void hifDeviceRemoved(struct sdio_func *func) { - int status = A_OK; + int status = 0; HIF_DEVICE *device; AR_DEBUG_ASSERT(func != NULL); @@ -1144,7 +1144,7 @@ static void hifDeviceRemoved(struct sdio_func *func) CleanupHIFScatterResources(device); delHifDevice(device); - AR_DEBUG_ASSERT(status == A_OK); + AR_DEBUG_ASSERT(status == 0); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceRemoved\n")); } @@ -1155,7 +1155,7 @@ int hifWaitForPendingRecv(HIF_DEVICE *device) { s32 cnt = 10; u8 host_int_status; - int status = A_OK; + int status = 0; do { while (atomic_read(&device->irqHandling)) { @@ -1178,7 +1178,7 @@ int hifWaitForPendingRecv(HIF_DEVICE *device) ("AR6000: %s(), Unable clear up pending IRQ before the system suspended\n", __FUNCTION__)); } - return A_OK; + return 0; } @@ -1240,7 +1240,7 @@ int HIFAttachHTC(HIF_DEVICE *device, HTC_CALLBACKS *callbacks) return A_ERROR; } device->htcCallbacks = *callbacks; - return A_OK; + return 0; } void HIFDetachHTC(HIF_DEVICE *device) diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c index 4319e3d9ad11..78cbbb11ed61 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c @@ -89,7 +89,7 @@ int DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest) struct mmc_data data; HIF_SCATTER_REQ_PRIV *pReqPriv; HIF_SCATTER_REQ *pReq; - int status = A_OK; + int status = 0; struct scatterlist *pSg; pReqPriv = busrequest->pScatterReq; @@ -260,7 +260,7 @@ static int HifReadWriteScatter(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq) AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: queued async req: 0x%lX\n", (unsigned long)pReqPriv->busrequest)); /* wake thread, it will process and then take care of the async callback */ up(&device->sem_async); - status = A_OK; + status = 0; } } while (false); @@ -268,7 +268,7 @@ static int HifReadWriteScatter(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq) if (status && (request & HIF_ASYNCHRONOUS)) { pReq->CompletionStatus = status; pReq->CompletionRoutine(pReq); - status = A_OK; + status = 0; } return status; @@ -344,7 +344,7 @@ int SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO * pInfo->MaxScatterEntries = MAX_SCATTER_ENTRIES_PER_REQ; pInfo->MaxTransferSizePerScatterReq = MAX_SCATTER_REQ_TRANSFER_SIZE; - status = A_OK; + status = 0; } while (false); diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index ed51a8da965b..6083231cdbb0 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -77,7 +77,7 @@ void DevCleanup(AR6K_DEVICE *pDev) int DevSetup(AR6K_DEVICE *pDev) { u32 blocksizes[AR6K_MAILBOXES]; - int status = A_OK; + int status = 0; int i; HTC_CALLBACKS htcCallbacks; @@ -309,7 +309,7 @@ int DevUnmaskInterrupts(AR6K_DEVICE *pDev) * and when HTC is finally ready to handle interrupts, other software can perform target "soft" resets. * The AR6K interrupt enables reset back to an "enabled" state when this happens. * */ - int IntStatus = A_OK; + int IntStatus = 0; DevDisableInterrupts(pDev); #ifdef THREAD_X @@ -357,7 +357,7 @@ static void DevDoEnableDisableRecvAsyncHandler(void *Context, HTC_PACKET *pPacke * disable recv events */ static int DevDoEnableDisableRecvOverride(AR6K_DEVICE *pDev, bool EnableRecv, bool AsyncMode) { - int status = A_OK; + int status = 0; HTC_PACKET *pIOPacket = NULL; AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("DevDoEnableDisableRecvOverride: Enable:%d Mode:%d\n", @@ -405,7 +405,7 @@ static int DevDoEnableDisableRecvOverride(AR6K_DEVICE *pDev, bool EnableRecv, bo * the host I/F */ static int DevDoEnableDisableRecvNormal(AR6K_DEVICE *pDev, bool EnableRecv, bool AsyncMode) { - int status = A_OK; + int status = 0; HTC_PACKET *pIOPacket = NULL; AR6K_IRQ_ENABLE_REGISTERS regs; @@ -490,7 +490,7 @@ int DevEnableRecv(AR6K_DEVICE *pDev, bool AsyncMode) int DevWaitForPendingRecv(AR6K_DEVICE *pDev,u32 TimeoutInMs,bool *pbIsRecvPending) { - int status = A_OK; + int status = 0; A_UCHAR host_int_status = 0x0; u32 counter = 0x0; @@ -519,7 +519,7 @@ int DevWaitForPendingRecv(AR6K_DEVICE *pDev,u32 TimeoutInMs,bool *pbIsRecvPendin host_int_status = !status ? (host_int_status & (1 << 0)):0; if(!host_int_status) { - status = A_OK; + status = 0; *pbIsRecvPending = false; break; } @@ -645,7 +645,7 @@ int DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, bool FromDMA) remaining -= length; } - return A_OK; + return 0; } static void DevReadWriteScatterAsyncHandler(void *Context, HTC_PACKET *pPacket) @@ -667,7 +667,7 @@ static void DevReadWriteScatterAsyncHandler(void *Context, HTC_PACKET *pPacket) static int DevReadWriteScatter(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) { AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; - int status = A_OK; + int status = 0; HTC_PACKET *pIOPacket = NULL; u32 request = pReq->Request; @@ -727,7 +727,7 @@ static int DevReadWriteScatter(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) } pReq->CompletionStatus = status; pReq->CompletionRoutine(pReq); - status = A_OK; + status = 0; } return status; @@ -751,7 +751,7 @@ static void DevCleanupVirtualScatterSupport(AR6K_DEVICE *pDev) /* function to set up virtual scatter support if HIF layer has not implemented the interface */ static int DevSetupVirtualScatterSupport(AR6K_DEVICE *pDev) { - int status = A_OK; + int status = 0; int bufferSize, sgreqSize; int i; DEV_SCATTER_DMA_VIRTUAL_INFO *pVirtualInfo; @@ -923,7 +923,7 @@ int DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, boo if (Async) { pScatterReq->CompletionStatus = status; pScatterReq->CompletionRoutine(pScatterReq); - return A_OK; + return 0; } return status; } @@ -936,7 +936,7 @@ int DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, boo DEV_FINISH_SCATTER_OPERATION(pScatterReq); } else { if (status == A_PENDING) { - status = A_OK; + status = 0; } } @@ -1127,7 +1127,7 @@ static u16 GetEndMarker(void) /* send the ordered buffers to the target */ static int SendBuffers(AR6K_DEVICE *pDev, int mbox) { - int status = A_OK; + int status = 0; u32 request = HIF_WR_SYNC_BLOCK_INC; BUFFER_PROC_LIST sendList[BUFFER_PROC_LIST_DEPTH]; int i; @@ -1171,7 +1171,7 @@ static int SendBuffers(AR6K_DEVICE *pDev, int mbox) /* poll the mailbox credit counter until we get a credit or timeout */ static int GetCredits(AR6K_DEVICE *pDev, int mbox, int *pCredits) { - int status = A_OK; + int status = 0; int timeout = TEST_CREDITS_RECV_TIMEOUT; u8 credits = 0; u32 address; @@ -1207,7 +1207,7 @@ static int GetCredits(AR6K_DEVICE *pDev, int mbox, int *pCredits) } - if (status == A_OK) { + if (status == 0) { *pCredits = credits; } @@ -1218,7 +1218,7 @@ static int GetCredits(AR6K_DEVICE *pDev, int mbox, int *pCredits) /* wait for the buffers to come back */ static int RecvBuffers(AR6K_DEVICE *pDev, int mbox) { - int status = A_OK; + int status = 0; u32 request = HIF_RD_SYNC_BLOCK_INC; BUFFER_PROC_LIST recvList[BUFFER_PROC_LIST_DEPTH]; int curBuffer; @@ -1457,7 +1457,7 @@ int DoMboxHWTest(AR6K_DEVICE *pDev) } while (false); - if (status == A_OK) { + if (status == 0) { AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest DONE - SUCCESS! - \n")); } else { AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest DONE - FAILED! - \n")); diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index 5e147c0ec240..d3b6b309dc2a 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -189,7 +189,7 @@ static INLINE int DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 Send A_ASSERT(false); if (pPacket->Completion != NULL) { COMPLETE_HTC_PACKET(pPacket,A_EINVAL); - return A_OK; + return 0; } return A_EINVAL; } @@ -212,7 +212,7 @@ static INLINE int DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 Send pPacket->Status = status; } else { if (status == A_PENDING) { - status = A_OK; + status = 0; } } @@ -234,7 +234,7 @@ static INLINE int DevRecvPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 Recv paddedLength,RecvLength,pPacket->BufferLength)); if (pPacket->Completion != NULL) { COMPLETE_HTC_PACKET(pPacket,A_EINVAL); - return A_OK; + return 0; } return A_EINVAL; } @@ -291,7 +291,7 @@ static INLINE int DEV_PREPARE_SCATTER_OPERATION(HIF_SCATTER_REQ *pReq) { if ((pReq->Request & HIF_WRITE) && (pReq->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) { return DevCopyScatterListToFromDMABuffer(pReq,TO_DMA_BUFFER); } else { - return A_OK; + return 0; } } @@ -346,12 +346,12 @@ void DevNotifyGMboxTargetFailure(AR6K_DEVICE *pDev); /* compiled out */ #define DevCleanupGMbox(p) -#define DevCheckGMboxInterrupts(p) A_OK +#define DevCheckGMboxInterrupts(p) 0 #define DevNotifyGMboxTargetFailure(p) static INLINE int DevSetupGMbox(AR6K_DEVICE *pDev) { pDev->GMboxEnabled = false; - return A_OK; + return 0; } #endif diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c index f9b153315d46..4517bef4ba8f 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c @@ -55,7 +55,7 @@ int DevRWCompletionHandler(void *context, int status) AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-DevRWCompletionHandler\n")); - return A_OK; + return 0; } /* mailbox recv message polling */ @@ -63,7 +63,7 @@ int DevPollMboxMsgRecv(AR6K_DEVICE *pDev, u32 *pLookAhead, int TimeoutMS) { - int status = A_OK; + int status = 0; int timeout = TimeoutMS/DELAY_PER_INTERVAL_MS; A_ASSERT(timeout > 0); @@ -187,7 +187,7 @@ static int DevServiceCPUInterrupt(AR6K_DEVICE *pDev) HIF_WR_SYNC_BYTE_FIX, NULL); - A_ASSERT(status == A_OK); + A_ASSERT(status == 0); return status; } @@ -241,7 +241,7 @@ static int DevServiceErrorInterrupt(AR6K_DEVICE *pDev) HIF_WR_SYNC_BYTE_FIX, NULL); - A_ASSERT(status == A_OK); + A_ASSERT(status == 0); return status; } @@ -271,7 +271,7 @@ static int DevServiceDebugInterrupt(AR6K_DEVICE *pDev) HIF_RD_SYNC_BYTE_INC, NULL); - A_ASSERT(status == A_OK); + A_ASSERT(status == 0); return status; } @@ -296,7 +296,7 @@ static int DevServiceCounterInterrupt(AR6K_DEVICE *pDev) return DevServiceDebugInterrupt(pDev); } - return A_OK; + return 0; } /* callback when our fetch to get interrupt status registers completes */ @@ -391,7 +391,7 @@ static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket) int DevCheckPendingRecvMsgsAsync(void *context) { AR6K_DEVICE *pDev = (AR6K_DEVICE *)context; - int status = A_OK; + int status = 0; HTC_PACKET *pIOPacket; /* this is called in an ASYNC only context, we may NOT block, sleep or call any apis that can @@ -469,7 +469,7 @@ void DevAsyncIrqProcessComplete(AR6K_DEVICE *pDev) /* process pending interrupts synchronously */ static int ProcessPendingIRQs(AR6K_DEVICE *pDev, bool *pDone, bool *pASyncProcessing) { - int status = A_OK; + int status = 0; u8 host_int_status = 0; u32 lookAhead = 0; @@ -684,7 +684,7 @@ static int ProcessPendingIRQs(AR6K_DEVICE *pDev, bool *pDone, bool *pASyncProces int DevDsrHandler(void *context) { AR6K_DEVICE *pDev = (AR6K_DEVICE *)context; - int status = A_OK; + int status = 0; bool done = false; bool asyncProc = false; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c index d27bab4f6c50..d58e41884720 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c @@ -76,7 +76,7 @@ static void DevGMboxIRQActionAsyncHandler(void *Context, HTC_PACKET *pPacket) static int DevGMboxCounterEnableDisable(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode) { - int status = A_OK; + int status = 0; AR6K_IRQ_ENABLE_REGISTERS regs; HTC_PACKET *pIOPacket = NULL; @@ -157,7 +157,7 @@ static int DevGMboxCounterEnableDisable(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE int DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode) { - int status = A_OK; + int status = 0; HTC_PACKET *pIOPacket = NULL; u8 GMboxIntControl[4]; @@ -271,7 +271,7 @@ void DevCleanupGMbox(AR6K_DEVICE *pDev) int DevSetupGMbox(AR6K_DEVICE *pDev) { - int status = A_OK; + int status = 0; u8 muxControl[4]; do { @@ -324,7 +324,7 @@ int DevSetupGMbox(AR6K_DEVICE *pDev) int DevCheckGMboxInterrupts(AR6K_DEVICE *pDev) { - int status = A_OK; + int status = 0; u8 counter_int_status; int credits; u8 host_int_status2; @@ -426,7 +426,7 @@ int DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 WriteLength) pPacket->Status = status; } else { if (status == A_PENDING) { - status = A_OK; + status = 0; } } @@ -450,7 +450,7 @@ int DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 ReadLength) paddedLength,ReadLength,pPacket->BufferLength)); if (pPacket->Completion != NULL) { COMPLETE_HTC_PACKET(pPacket,A_EINVAL); - return A_OK; + return 0; } return A_EINVAL; } @@ -541,7 +541,7 @@ static void DevGMboxReadCreditsAsyncHandler(void *Context, HTC_PACKET *pPacket) int DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, bool AsyncMode, int *pCredits) { - int status = A_OK; + int status = 0; HTC_PACKET *pIOPacket = NULL; AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+DevGMboxReadCreditCounter (%s) \n", AsyncMode ? "ASYNC" : "SYNC")); @@ -637,7 +637,7 @@ void DevNotifyGMboxTargetFailure(AR6K_DEVICE *pDev) int DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes) { - int status = A_OK; + int status = 0; AR6K_IRQ_PROC_REGISTERS procRegs; int maxCopy; @@ -678,7 +678,7 @@ int DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, u8 *pLookAheadBuffer, int *pLoo int DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int Signal, int AckTimeoutMS) { - int status = A_OK; + int status = 0; int i; u8 buffer[4]; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c index cf45f9912685..cddb93993194 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c @@ -195,7 +195,7 @@ static int CreditsAvailableCallback(void *pContext, int Credits, bool CreditIRQE bool enableCreditIrq = false; bool disableCreditIrq = false; bool doPendingSends = false; - int status = A_OK; + int status = 0; /** this callback is called under 2 conditions: * 1. The credit IRQ interrupt was enabled and signaled. @@ -307,7 +307,7 @@ static void StateDumpCallback(void *pContext) static int HCIUartMessagePending(void *pContext, u8 LookAheadBytes[], int ValidBytes) { GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)pContext; - int status = A_OK; + int status = 0; int totalRecvLength = 0; HCI_TRANSPORT_PACKET_TYPE pktType = HCI_PACKET_INVALID; bool recvRefillCalled = false; @@ -476,7 +476,7 @@ static int HCIUartMessagePending(void *pContext, u8 LookAheadBytes[], int ValidB /* adjust buffer to move past packet ID */ pPacket->pBuffer++; pPacket->ActualLength = totalRecvLength - 1; - pPacket->Status = A_OK; + pPacket->Status = 0; /* indicate packet */ DO_HCI_RECV_INDICATION(pProt,pPacket); pPacket = NULL; @@ -549,7 +549,7 @@ static void HCISendPacketCompletion(void *Context, HTC_PACKET *pPacket) static int SeekCreditsSynch(GMBOX_PROTO_HCI_UART *pProt) { - int status = A_OK; + int status = 0; int credits; int retry = 100; @@ -581,7 +581,7 @@ static int SeekCreditsSynch(GMBOX_PROTO_HCI_UART *pProt) static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, bool Synchronous) { - int status = A_OK; + int status = 0; int transferLength; int creditsRequired, remainder; u8 hciUartType; @@ -848,7 +848,7 @@ static void FlushRecvBuffers(GMBOX_PROTO_HCI_UART *pProt) int GMboxProtocolInstall(AR6K_DEVICE *pDev) { - int status = A_OK; + int status = 0; GMBOX_PROTO_HCI_UART *pProtocol = NULL; do { @@ -911,7 +911,7 @@ void GMboxProtocolUninstall(AR6K_DEVICE *pDev) static int NotifyTransportReady(GMBOX_PROTO_HCI_UART *pProt) { HCI_TRANSPORT_PROPERTIES props; - int status = A_OK; + int status = 0; do { @@ -1004,7 +1004,7 @@ void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans) int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue) { GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; - int status = A_OK; + int status = 0; bool unblockRecv = false; HTC_PACKET *pPacket; @@ -1066,7 +1066,7 @@ int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HCI_TransportAddReceivePkt \n")); - return A_OK; + return 0; } int HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, bool Synchronous) @@ -1163,7 +1163,7 @@ int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, int MaxPollMS) { GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; - int status = A_OK; + int status = 0; u8 lookAhead[8]; int bytes; int totalRecvLength; @@ -1216,7 +1216,7 @@ int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, pPacket->pBuffer++; pPacket->ActualLength = totalRecvLength - 1; - pPacket->Status = A_OK; + pPacket->Status = 0; break; } @@ -1235,7 +1235,7 @@ int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud) GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; HIF_DEVICE *pHIFDevice = (HIF_DEVICE *)(pProt->pDev->HIFDevice); u32 scaledBaud, scratchAddr; - int status = A_OK; + int status = 0; /* Divide the desired baud rate by 100 * Store the LSB in the local scratch register 4 and the MSB in the local @@ -1247,14 +1247,14 @@ int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud) scratchAddr = MBOX_BASE_ADDRESS | (LOCAL_SCRATCH_ADDRESS + 4 * MSB_SCRATCH_IDX); scaledBaud = ((Baud / 100) >> (LOCAL_SCRATCH_VALUE_MSB+1)) & LOCAL_SCRATCH_VALUE_MASK; status |= ar6000_WriteRegDiag(pHIFDevice, &scratchAddr, &scaledBaud); - if (A_OK != status) { + if (0 != status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to set up baud rate in scratch register!")); return status; } /* Now interrupt the target to tell it about the baud rate */ status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_BAUD_SET, BAUD_TIMEOUT_MS); - if (A_OK != status) { + if (0 != status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to tell target to change baud rate!")); } diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index cf88a9af8053..684eca9bd022 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -93,7 +93,7 @@ static void HTCCleanup(HTC_TARGET *target) HTC_HANDLE HTCCreate(void *hif_handle, HTC_INIT_INFO *pInfo) { HTC_TARGET *target = NULL; - int status = A_OK; + int status = 0; int i; u32 ctrl_bufsz; u32 blocksizes[HTC_MAILBOX_NUM_MAX]; diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c index 8a794696d655..34454754b8cd 100644 --- a/drivers/staging/ath6kl/htc2/htc_recv.c +++ b/drivers/staging/ath6kl/htc2/htc_recv.c @@ -105,7 +105,7 @@ static INLINE int HTCProcessTrailer(HTC_TARGET *target, pOrigBuffer = pBuffer; origLength = Length; - status = A_OK; + status = 0; while (Length > 0) { @@ -233,7 +233,7 @@ static int HTCProcessRecvHeader(HTC_TARGET *target, { u8 temp; u8 *pBuf; - int status = A_OK; + int status = 0; u16 payloadLen; u32 lookAhead; @@ -692,7 +692,7 @@ static int AllocAndPrepareRxPackets(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint, HTC_PACKET_QUEUE *pQueue) { - int status = A_OK; + int status = 0; HTC_PACKET *pPacket; HTC_FRAME_HDR *pHdr; int i,j; @@ -816,7 +816,7 @@ static int AllocAndPrepareRxPackets(HTC_TARGET *target, /* clear flags */ pPacket->PktInfo.AsRx.HTCRxFlags = 0; pPacket->PktInfo.AsRx.IndicationFlags = 0; - pPacket->Status = A_OK; + pPacket->Status = 0; if (noRecycle) { /* flag that these packets cannot be recycled, they have to be returned to the @@ -859,7 +859,7 @@ static int AllocAndPrepareRxPackets(HTC_TARGET *target, if (status) { if (A_NO_RESOURCE == status) { /* this is actually okay */ - status = A_OK; + status = 0; } break; } @@ -990,7 +990,7 @@ static int HTCIssueRecvPacketBundle(HTC_TARGET *target, int *pNumPacketsFetched, bool PartialBundle) { - int status = A_OK; + int status = 0; HIF_SCATTER_REQ *pScatterReq; int i, totalLength; int pktsToScatter; @@ -1120,7 +1120,7 @@ static INLINE void CheckRecvWaterMark(HTC_ENDPOINT *pEndpoint) int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched) { HTC_TARGET *target = (HTC_TARGET *)Context; - int status = A_OK; + int status = 0; HTC_PACKET *pPacket; HTC_ENDPOINT *pEndpoint; bool asyncProc = false; @@ -1390,7 +1390,7 @@ int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); HTC_ENDPOINT *pEndpoint; bool unblockRecv = false; - int status = A_OK; + int status = 0; HTC_PACKET *pFirstPacket; pFirstPacket = HTC_GET_PKT_AT_HEAD(pPktQueue); @@ -1567,7 +1567,7 @@ int HTCWaitForPendingRecv(HTC_HANDLE HTCHandle, u32 TimeoutInMs, bool *pbIsRecvPending) { - int status = A_OK; + int status = 0; HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); status = DevWaitForPendingRecv(&target->Device, diff --git a/drivers/staging/ath6kl/htc2/htc_send.c b/drivers/staging/ath6kl/htc2/htc_send.c index 8b7c7f01ef57..a31acae9620e 100644 --- a/drivers/staging/ath6kl/htc2/htc_send.c +++ b/drivers/staging/ath6kl/htc2/htc_send.c @@ -270,7 +270,7 @@ static void HTCAsyncSendScatterCompletion(HIF_SCATTER_REQ *pScatterReq) HTC_PACKET *pPacket; HTC_ENDPOINT *pEndpoint = (HTC_ENDPOINT *)pScatterReq->Context; HTC_TARGET *target = (HTC_TARGET *)pEndpoint->target; - int status = A_OK; + int status = 0; HTC_PACKET_QUEUE sendCompletes; INIT_HTC_PACKET_QUEUE(&sendCompletes); @@ -705,7 +705,7 @@ int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPktsMultiple \n")); - return A_OK; + return 0; } /* HTC API - HTCSendPkt */ diff --git a/drivers/staging/ath6kl/htc2/htc_services.c b/drivers/staging/ath6kl/htc2/htc_services.c index 08209a370341..9ddf32cd2dfe 100644 --- a/drivers/staging/ath6kl/htc2/htc_services.c +++ b/drivers/staging/ath6kl/htc2/htc_services.c @@ -126,7 +126,7 @@ int HTCConnectService(HTC_HANDLE HTCHandle, HTC_SERVICE_CONNECT_RESP *pConnectResp) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - int status = A_OK; + int status = 0; HTC_PACKET *pRecvPacket = NULL; HTC_PACKET *pSendPacket = NULL; HTC_CONNECT_SERVICE_RESPONSE_MSG *pResponseMsg; @@ -290,7 +290,7 @@ int HTCConnectService(HTC_HANDLE HTCHandle, /* save local connection flags */ pEndpoint->LocalConnectionFlags = pConnectReq->LocalConnectionFlags; - status = A_OK; + status = 0; } while (false); diff --git a/drivers/staging/ath6kl/include/common/athdefs.h b/drivers/staging/ath6kl/include/common/athdefs.h index 255c7ddf3081..74922481e065 100644 --- a/drivers/staging/ath6kl/include/common/athdefs.h +++ b/drivers/staging/ath6kl/include/common/athdefs.h @@ -32,11 +32,10 @@ /* * Generic error codes that can be used by hw, sta, ap, sim, dk * and any other environments. - * Feel free to add any more codes that you need. + * Feel free to add any more non-zero codes that you need. */ #define A_ERROR (-1) /* Generic error return */ -#define A_OK 0 /* success */ #define A_DEVICE_NOT_FOUND 1 /* not able to find PCI device */ #define A_NO_MEMORY 2 /* not able to allocate memory, * not avail#defineable */ diff --git a/drivers/staging/ath6kl/include/common/wmi.h b/drivers/staging/ath6kl/include/common/wmi.h index a03b4371519f..f16ef28537b9 100644 --- a/drivers/staging/ath6kl/include/common/wmi.h +++ b/drivers/staging/ath6kl/include/common/wmi.h @@ -1884,7 +1884,7 @@ typedef PREPACK struct { } POSTPACK WMI_CHANNEL_LIST_REPLY; typedef enum { - A_SUCCEEDED = A_OK, + A_SUCCEEDED = 0, A_FAILED_DELETE_STREAM_DOESNOT_EXIST=250, A_SUCCEEDED_MODIFY_STREAM=251, A_FAILED_INVALID_STREAM = 252, diff --git a/drivers/staging/ath6kl/include/hci_transport_api.h b/drivers/staging/ath6kl/include/hci_transport_api.h index 47d0db97ab51..8ab692db6cfe 100644 --- a/drivers/staging/ath6kl/include/hci_transport_api.h +++ b/drivers/staging/ath6kl/include/hci_transport_api.h @@ -134,7 +134,7 @@ void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans); @input: HciTrans - HCI transport handle pQueue - a queue holding one or more packets @output: - @return: A_OK on success + @return: 0 on success @notes: user must supply HTC packets for capturing incomming HCI packets. The caller must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL() macro. Each packet in the queue must be of the same type and length @@ -150,7 +150,7 @@ int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUE pPacket - packet to send Synchronous - send the packet synchronously (blocking) @output: - @return: A_OK + @return: 0 @notes: Caller must initialize packet using SET_HTC_PACKET_INFO_TX() and HCI_SET_PACKET_TYPE() macros to prepare the packet. If Synchronous is set to false the call is fully asynchronous. On error or completion, @@ -187,7 +187,7 @@ void HCI_TransportStop(HCI_TRANSPORT_HANDLE HciTrans); @function name: HCI_TransportStart @input: HciTrans - hci transport handle @output: - @return: A_OK on success + @return: 0 on success @notes: HCI transport communication will begin, the caller can expect the arrival of HCI recv packets as soon as this call returns. @example: @@ -201,7 +201,7 @@ int HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans); @input: HciTrans - hci transport handle Enable - enable or disable asynchronous recv @output: - @return: A_OK on success + @return: 0 on success @notes: This API must be called when HCI recv is handled synchronously @example: @see also: @@ -215,7 +215,7 @@ int HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, bool E pPacket - HTC packet to hold the recv data MaxPollMS - maximum polling duration in Milliseconds; @output: - @return: A_OK on success + @return: 0 on success @notes: This API should be used only during HCI device initialization, the caller must call HCI_TransportEnableDisableAsyncRecv with Enable=false prior to using this API. This API will only capture HCI Event packets. @@ -232,7 +232,7 @@ int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, @input: HciTrans - hci transport handle Baud - baud rate in bps @output: - @return: A_OK on success + @return: 0 on success @notes: This API should be used only after HCI device initialization @example: @see also: @@ -245,7 +245,7 @@ int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud); @input: HciTrans - hci transport handle Enable - 1 = Enable, 0 = Disable @output: - @return: A_OK on success + @return: 0 on success @notes: @example: @see also: diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h index 3cfa9f2c8e05..c5c9fed3fe4d 100644 --- a/drivers/staging/ath6kl/include/htc_api.h +++ b/drivers/staging/ath6kl/include/htc_api.h @@ -341,7 +341,7 @@ int HTCStart(HTC_HANDLE HTCHandle); @input: HTCHandle - HTC handle pPacket - HTC receive packet to add @output: - @return: A_OK on success + @return: 0 on success @notes: user must supply HTC packets for capturing incomming HTC frames. The caller must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL() macro. @@ -370,7 +370,7 @@ int HTCConnectService(HTC_HANDLE HTCHandle, @input: HTCHandle - HTC handle pPacket - packet to send @output: - @return: A_OK + @return: 0 @notes: Caller must initialize packet using SET_HTC_PACKET_INFO_TX() macro. This interface is fully asynchronous. On error, HTC SendPkt will call the registered Endpoint callback to cleanup the packet. @@ -499,7 +499,7 @@ void HTCUnblockRecv(HTC_HANDLE HTCHandle); @input: HTCHandle - HTC handle pPktQueue - local queue holding packets to send @output: - @return: A_OK + @return: 0 @notes: Caller must initialize each packet using SET_HTC_PACKET_INFO_TX() macro. The queue must only contain packets directed at the same endpoint. Caller supplies a pointer to an HTC_PACKET_QUEUE structure holding the TX packets in FIFO order. @@ -519,7 +519,7 @@ int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue); @input: HTCHandle - HTC handle pPktQueue - HTC receive packet queue holding packets to add @output: - @return: A_OK on success + @return: 0 on success @notes: user must supply HTC packets for capturing incomming HTC frames. The caller must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL() macro. The queue must only contain recv packets for the same endpoint. diff --git a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c index 354008904a66..29873ac15892 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c @@ -54,7 +54,7 @@ static int SendHCICommand(AR3K_CONFIG_INFO *pConfig, int Length) { HTC_PACKET *pPacket = NULL; - int status = A_OK; + int status = 0; do { @@ -88,7 +88,7 @@ static int RecvHCIEvent(AR3K_CONFIG_INFO *pConfig, u8 *pBuffer, int *pLength) { - int status = A_OK; + int status = 0; HTC_PACKET *pRecvPacket = NULL; do { @@ -128,7 +128,7 @@ int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, u8 **ppEventBuffer, u8 **ppBufferToFree) { - int status = A_OK; + int status = 0; u8 *pBuffer = NULL; u8 *pTemp; int length; @@ -211,7 +211,7 @@ int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, static int AR3KConfigureHCIBaud(AR3K_CONFIG_INFO *pConfig) { - int status = A_OK; + int status = 0; u8 hciBaudChangeCommand[] = {0x0c,0xfc,0x2,0,0}; u16 baudVal; u8 *pEvent = NULL; @@ -312,7 +312,7 @@ static int AR3KExitMinBoot(AR3K_CONFIG_INFO *pConfig) static int AR3KConfigureSendHCIReset(AR3K_CONFIG_INFO *pConfig) { - int status = A_OK; + int status = 0; u8 hciResetCommand[] = {0x03,0x0c,0x0}; u8 *pEvent = NULL; u8 *pBufferToFree = NULL; @@ -455,7 +455,7 @@ static int AR3KEnableTLPM(AR3K_CONFIG_INFO *pConfig) int AR3KConfigure(AR3K_CONFIG_INFO *pConfig) { - int status = A_OK; + int status = 0; AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Configuring AR3K ...\n")); @@ -481,7 +481,7 @@ int AR3KConfigure(AR3K_CONFIG_INFO *pConfig) /* Load patching and PST file if available*/ - if (A_OK != AthPSInitialize(pConfig)) { + if (0 != AthPSInitialize(pConfig)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch Download Failed!\n")); } @@ -523,7 +523,7 @@ int AR3KConfigure(AR3K_CONFIG_INFO *pConfig) int AR3KConfigureExit(void *config) { - int status = A_OK; + int status = 0; AR3K_CONFIG_INFO *pConfig = (AR3K_CONFIG_INFO *)config; AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Cleaning up AR3K ...\n")); diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c index 7106a6a080f0..67e6d5edfa51 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c @@ -93,7 +93,7 @@ void Hci_log(A_UCHAR * log_string,A_UCHAR *data,u32 len) int AthPSInitialize(AR3K_CONFIG_INFO *hdev) { - int status = A_OK; + int status = 0; if(hdev == NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Device handle received\n")); return A_ERROR; @@ -280,8 +280,8 @@ int PSSendOps(void *arg) HciCmdList[0].Hcipacket, HciCmdList[0].packetLen, &event, - &bufferToFree) == A_OK) { - if(ReadPSEvent(event) == A_OK) { /* Exit if the status is success */ + &bufferToFree) == 0) { + if(ReadPSEvent(event) == 0) { /* Exit if the status is success */ if(bufferToFree != NULL) { A_FREE(bufferToFree); } @@ -309,8 +309,8 @@ int PSSendOps(void *arg) HciCmdList[i].Hcipacket, HciCmdList[i].packetLen, &event, - &bufferToFree) == A_OK) { - if(ReadPSEvent(event) != A_OK) { /* Exit if the status is success */ + &bufferToFree) == 0) { + if(ReadPSEvent(event) != 0) { /* Exit if the status is success */ if(bufferToFree != NULL) { A_FREE(bufferToFree); } @@ -415,7 +415,7 @@ int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, return A_ERROR; } - return A_OK; + return 0; } #endif /* HCI_TRANSPORT_SDIO */ @@ -426,14 +426,14 @@ int ReadPSEvent(A_UCHAR* Data){ { switch(Data[3]){ case 0x0B: - return A_OK; + return 0; break; case 0x0C: /* Change Baudrate */ - return A_OK; + return 0; break; case 0x04: - return A_OK; + return 0; break; case 0x1E: Rom_Version = Data[9]; @@ -445,7 +445,7 @@ int ReadPSEvent(A_UCHAR* Data){ Build_Version = ((Build_Version << 8) |Data[12]); Build_Version = ((Build_Version << 8) |Data[11]); Build_Version = ((Build_Version << 8) |Data[10]); - return A_OK; + return 0; break; @@ -499,13 +499,13 @@ int write_bdaddr(AR3K_CONFIG_INFO *pConfig,A_UCHAR *bdaddr,int type) bdaddr_cmd[outc] = bdaddr[inc]; } - if(A_OK == SendHCICommandWaitCommandComplete(pConfig,bdaddr_cmd, + if(0 == SendHCICommandWaitCommandComplete(pConfig,bdaddr_cmd, sizeof(bdaddr_cmd), &event,&bufferToFree)) { if(event[4] == 0xFC && event[5] == 0x00){ if(event[3] == 0x0B){ - result = A_OK; + result = 0; } } @@ -522,7 +522,7 @@ int ReadVersionInfo(AR3K_CONFIG_INFO *pConfig) u8 *event; u8 *bufferToFree = NULL; int result = A_ERROR; - if(A_OK == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) { + if(0 == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) { result = ReadPSEvent(event); } @@ -543,7 +543,7 @@ int getDeviceType(AR3K_CONFIG_INFO *pConfig, u32 *code) hciCommand[4] = (u8)((FPGA_REGISTER >> 8) & 0xFF); hciCommand[5] = (u8)((FPGA_REGISTER >> 16) & 0xFF); hciCommand[6] = (u8)((FPGA_REGISTER >> 24) & 0xFF); - if(A_OK == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) { + if(0 == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) { if(event[4] == 0xFC && event[5] == 0x00){ switch(event[3]){ @@ -553,7 +553,7 @@ int getDeviceType(AR3K_CONFIG_INFO *pConfig, u32 *code) reg = ((reg << 8) |event[7]); reg = ((reg << 8) |event[6]); *code = reg; - result = A_OK; + result = 0; break; case 0x06: diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c index 10f2900d596b..90ced223d1f1 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c @@ -549,7 +549,7 @@ int AthParseFilesUnified(A_UCHAR *srcbuffer,u32 srclen, int FileFormat) if(Buffer != NULL) { A_FREE(Buffer); } - return A_OK; + return 0; } @@ -576,7 +576,7 @@ int GetNextTwoChar(A_UCHAR *srcbuffer,u32 len, u32 *pos, char *buffer) { return A_ERROR; } - return A_OK; + return 0; } int AthDoParsePatch(A_UCHAR *patchbuffer, u32 patchlen) @@ -654,7 +654,7 @@ int AthDoParsePatch(A_UCHAR *patchbuffer, u32 patchlen) } - return A_OK; + return 0; } @@ -953,7 +953,7 @@ static int AthPSCreateHCICommand(A_UCHAR Opcode, u32 Param1,PSCmdPacket *PSPatch case CHANGE_BDADDR: break; } - return A_OK; + return 0; } int AthFreeCommandList(PSCmdPacket **HciPacketList, u32 numPackets) { @@ -965,5 +965,5 @@ int AthFreeCommandList(PSCmdPacket **HciPacketList, u32 numPackets) A_FREE((*HciPacketList)[i].Hcipacket); } A_FREE(*HciPacketList); - return A_OK; + return 0; } diff --git a/drivers/staging/ath6kl/miscdrv/common_drv.c b/drivers/staging/ath6kl/miscdrv/common_drv.c index bf71f96847e1..7a77290da140 100644 --- a/drivers/staging/ath6kl/miscdrv/common_drv.c +++ b/drivers/staging/ath6kl/miscdrv/common_drv.c @@ -134,7 +134,7 @@ int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, u32 RegisterAddr, u32 return status; } - return A_OK; + return 0; @@ -177,7 +177,7 @@ int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, u32 RegisterAddr, u32 return status; } - return A_OK; + return 0; } #endif @@ -248,11 +248,11 @@ ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, u32 address, A_UCHAR *data, u32 length) { u32 count; - int status = A_OK; + int status = 0; for (count = 0; count < length; count += 4, address += 4) { if ((status = ar6000_ReadRegDiag(hifDevice, &address, - (u32 *)&data[count])) != A_OK) + (u32 *)&data[count])) != 0) { break; } @@ -266,11 +266,11 @@ ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, u32 address, A_UCHAR *data, u32 length) { u32 count; - int status = A_OK; + int status = 0; for (count = 0; count < length; count += 4, address += 4) { if ((status = ar6000_WriteRegDiag(hifDevice, &address, - (u32 *)&data[count])) != A_OK) + (u32 *)&data[count])) != 0) { break; } @@ -382,13 +382,13 @@ _delay_until_target_alive(HIF_DEVICE *hifDevice, s32 wait_msecs, u32 TargetType) actual_wait += 100; data = 0; - if (ar6000_ReadRegDiag(hifDevice, &address, &data) != A_OK) { + if (ar6000_ReadRegDiag(hifDevice, &address, &data) != 0) { return A_ERROR; } if (data != 0) { /* No need to wait longer -- we have a BMI credit */ - return A_OK; + return 0; } } return A_ERROR; /* timed out */ @@ -401,7 +401,7 @@ _delay_until_target_alive(HIF_DEVICE *hifDevice, s32 wait_msecs, u32 TargetType) /* reset device */ int ar6000_reset_device(HIF_DEVICE *hifDevice, u32 TargetType, bool waitForCompletion, bool coldReset) { - int status = A_OK; + int status = 0; u32 address; u32 data; @@ -476,7 +476,7 @@ int ar6000_reset_device(HIF_DEVICE *hifDevice, u32 TargetType, bool waitForCompl AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Failed to reset target \n")); } - return A_OK; + return 0; } /* This should be called in BMI phase after firmware is downloaded */ @@ -490,7 +490,7 @@ ar6000_copy_cust_data_from_target(HIF_DEVICE *hifDevice, u32 TargetType) if (BMIReadMemory(hifDevice, HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_board_data), (A_UCHAR *)&eepHeaderAddr, - 4)!= A_OK) + 4)!= 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadMemory for reading board data address failed \n")); return; @@ -500,7 +500,7 @@ ar6000_copy_cust_data_from_target(HIF_DEVICE *hifDevice, u32 TargetType) eepHeaderAddr += 36; /* AR6003 customer data section offset is 37 */ for (i=0; iCurrentMask; - return A_OK; + return 0; } int a_set_module_mask(char *module_name, u32 Mask) @@ -955,7 +955,7 @@ int a_set_module_mask(char *module_name, u32 Mask) pInfo->CurrentMask = Mask; A_PRINTF("Module %s, new mask: 0x%8.8X \n",module_name,pInfo->CurrentMask); - return A_OK; + return 0; } @@ -1002,7 +1002,7 @@ int ar6000_set_hci_bridge_flags(HIF_DEVICE *hifDevice, u32 TargetType, u32 Flags) { - int status = A_OK; + int status = 0; do { diff --git a/drivers/staging/ath6kl/miscdrv/credit_dist.c b/drivers/staging/ath6kl/miscdrv/credit_dist.c index b813f8e8c4df..68b1ed67b307 100644 --- a/drivers/staging/ath6kl/miscdrv/credit_dist.c +++ b/drivers/staging/ath6kl/miscdrv/credit_dist.c @@ -413,6 +413,6 @@ int ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, COMMON_CREDIT_STATE_INFO *pCr servicepriority, 5); - return A_OK; + return 0; } diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index f08c08b16684..26dafc90451e 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -410,19 +410,19 @@ ar6000_set_host_app_area(AR_SOFTC_T *ar) /* Fetch the address of the host_app_area_s instance in the host interest area */ address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest)); - if (ar6000_ReadRegDiag(ar->arHifDevice, &address, &data) != A_OK) { + if (ar6000_ReadRegDiag(ar->arHifDevice, &address, &data) != 0) { return A_ERROR; } address = TARG_VTOP(ar->arTargetType, data); host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION; if (ar6000_WriteDataDiag(ar->arHifDevice, address, (A_UCHAR *)&host_app_area, - sizeof(struct host_app_area_s)) != A_OK) + sizeof(struct host_app_area_s)) != 0) { return A_ERROR; } - return A_OK; + return 0; } u32 dbglog_get_debug_hdr_ptr(AR_SOFTC_T *ar) @@ -433,7 +433,7 @@ u32 dbglog_get_debug_hdr_ptr(AR_SOFTC_T *ar) address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbglog_hdr)); if ((status = ar6000_ReadDataDiag(ar->arHifDevice, address, - (A_UCHAR *)¶m, 4)) != A_OK) + (A_UCHAR *)¶m, 4)) != 0) { param = 0; } @@ -566,7 +566,7 @@ ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar) if (ar->log_cnt > (DBGLOG_HOST_LOG_BUFFER_SIZE - length)) { ar->log_cnt = 0; } - if(A_OK != ar6000_ReadDataDiag(ar->arHifDevice, address, + if(0 != ar6000_ReadDataDiag(ar->arHifDevice, address, (A_UCHAR *)&ar->log_buffer[ar->log_cnt], length)) { break; @@ -581,7 +581,7 @@ ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar) address = TARG_VTOP(ar->arTargetType, data[0] /* next */); length = 4 /* sizeof(next) */ + 4 /* sizeof(buffer) */ + 4 /* sizeof(bufsize) */ + 4 /* sizeof(length) */ + 4 /* sizeof(count) */ + 4 /* sizeof(free) */; A_MEMZERO(data, sizeof(data)); - if(A_OK != ar6000_ReadDataDiag(ar->arHifDevice, address, + if(0 != ar6000_ReadDataDiag(ar->arHifDevice, address, (A_UCHAR *)&data, length)) { break; @@ -592,7 +592,7 @@ ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar) ar->dbgLogFetchInProgress = false; - return A_OK; + return 0; } void @@ -759,7 +759,7 @@ aptcTimerHandler(unsigned long arg) AR6000_SPIN_UNLOCK(&ar->arLock, 0); status = wmi_powermode_cmd(ar->arWmi, REC_POWER); AR6000_SPIN_LOCK(&ar->arLock, 0); - A_ASSERT(status == A_OK); + A_ASSERT(status == 0); aptcTR.timerScheduled = false; } else { A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0); @@ -816,7 +816,7 @@ ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj, if (index == MAX_AR6000) return 0; - if ((BMIRawRead(ar->arHifDevice, (A_UCHAR*)buf, count, true)) != A_OK) { + if ((BMIRawRead(ar->arHifDevice, (A_UCHAR*)buf, count, true)) != 0) { return 0; } @@ -843,7 +843,7 @@ ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj, if (index == MAX_AR6000) return 0; - if ((BMIRawWrite(ar->arHifDevice, (A_UCHAR*)buf, count)) != A_OK) { + if ((BMIRawWrite(ar->arHifDevice, (A_UCHAR*)buf, count)) != 0) { return 0; } @@ -876,7 +876,7 @@ ar6000_sysfs_bmi_init(AR_SOFTC_T *ar) return A_ERROR; } - return A_OK; + return 0; } static void @@ -888,7 +888,7 @@ ar6000_sysfs_bmi_deinit(AR_SOFTC_T *ar) } #define bmifn(fn) do { \ - if ((fn) < A_OK) { \ + if ((fn) < 0) { \ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); \ return A_ERROR; \ } \ @@ -1151,7 +1151,7 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, u32 address, bool c return A_ERROR; } A_RELEASE_FIRMWARE(fw_entry); - return A_OK; + return 0; } #endif /* INIT_MODE_DRV_ENABLED */ @@ -1163,13 +1163,13 @@ ar6000_update_bdaddr(AR_SOFTC_T *ar) u32 address; if (BMIReadMemory(ar->arHifDevice, - HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (A_UCHAR *)&address, 4) != A_OK) + HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (A_UCHAR *)&address, 4) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for hi_board_data failed\n")); return A_ERROR; } - if (BMIReadMemory(ar->arHifDevice, address + BDATA_BDADDR_OFFSET, (A_UCHAR *)ar->bdaddr, 6) != A_OK) + if (BMIReadMemory(ar->arHifDevice, address + BDATA_BDADDR_OFFSET, (A_UCHAR *)ar->bdaddr, 6) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for BD address failed\n")); return A_ERROR; @@ -1179,7 +1179,7 @@ ar6000_update_bdaddr(AR_SOFTC_T *ar) ar->bdaddr[4], ar->bdaddr[5])); } -return A_OK; +return 0; } int @@ -1284,7 +1284,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, u32 mode) AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board Data download address: 0x%x\n", address)); /* Write EEPROM data to Target RAM */ - if ((ar6000_transfer_bin_file(ar, AR6K_BOARD_DATA_FILE, address, false)) != A_OK) { + if ((ar6000_transfer_bin_file(ar, AR6K_BOARD_DATA_FILE, address, false)) != 0) { return A_ERROR; } @@ -1295,7 +1295,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, u32 mode) /* Transfer One time Programmable data */ AR6K_DATA_DOWNLOAD_ADDRESS(address, ar->arVersion.target_ver); status = ar6000_transfer_bin_file(ar, AR6K_OTP_FILE, address, true); - if (status == A_OK) { + if (status == 0) { /* Execute the OTP code */ param = 0; AR6K_APP_START_OVERRIDE_ADDRESS(address, ar->arVersion.target_ver); @@ -1310,7 +1310,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, u32 mode) /* Download Target firmware */ AR6K_DATA_DOWNLOAD_ADDRESS(address, ar->arVersion.target_ver); - if ((ar6000_transfer_bin_file(ar, AR6K_FIRMWARE_FILE, address, true)) != A_OK) { + if ((ar6000_transfer_bin_file(ar, AR6K_FIRMWARE_FILE, address, true)) != 0) { return A_ERROR; } @@ -1320,7 +1320,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, u32 mode) /* Apply the patches */ AR6K_PATCH_DOWNLOAD_ADDRESS(address, ar->arVersion.target_ver); - if ((ar6000_transfer_bin_file(ar, AR6K_PATCH_FILE, address, false)) != A_OK) { + if ((ar6000_transfer_bin_file(ar, AR6K_PATCH_FILE, address, false)) != 0) { return A_ERROR; } @@ -1394,7 +1394,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, u32 mode) #endif /* INIT_MODE_DRV_ENABLED */ } - return A_OK; + return 0; } int @@ -1406,7 +1406,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) if (BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_serial_enable), (A_UCHAR *)¶m, - 4)!= A_OK) + 4)!= 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enableuartprint failed \n")); return A_ERROR; @@ -1419,7 +1419,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) if (BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest), (A_UCHAR *)¶m, - 4)!= A_OK) + 4)!= 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for htc version failed \n")); return A_ERROR; @@ -1438,7 +1438,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) if (BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), (A_UCHAR *)¶m, - 4)!= A_OK) + 4)!= 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for enabletimerwar failed \n")); return A_ERROR; @@ -1449,7 +1449,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) if (BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), (A_UCHAR *)¶m, - 4) != A_OK) + 4) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enabletimerwar failed \n")); return A_ERROR; @@ -1464,7 +1464,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) if (BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), (A_UCHAR *)¶m, - 4)!= A_OK) + 4)!= 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for setting fwmode failed \n")); return A_ERROR; @@ -1475,7 +1475,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) if (BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), (A_UCHAR *)¶m, - 4) != A_OK) + 4) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for setting fwmode failed \n")); return A_ERROR; @@ -1490,7 +1490,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) if (BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), (A_UCHAR *)¶m, - 4)!= A_OK) + 4)!= 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for disabling debug logs failed\n")); return A_ERROR; @@ -1501,7 +1501,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) if (BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), (A_UCHAR *)¶m, - 4) != A_OK) + 4) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for HI_OPTION_DISABLE_DBGLOG\n")); return A_ERROR; @@ -1523,7 +1523,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) if (BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data), (A_UCHAR *)¶m, - 4) != A_OK) + 4) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for hi_board_ext_data failed \n")); return A_ERROR; @@ -1547,7 +1547,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) return A_ERROR; } } - return A_OK; + return 0; } static void @@ -1603,7 +1603,7 @@ ar6000_avail_ev(void *context, void *hif_handle) #ifdef ATH6K_CONFIG_CFG80211 struct wireless_dev *wdev; #endif /* ATH6K_CONFIG_CFG80211 */ - int init_status = A_OK; + int init_status = 0; AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_available\n")); @@ -1722,7 +1722,7 @@ ar6000_avail_ev(void *context, void *hif_handle) { struct bmi_target_info targ_info; - if (BMIGetTargetInfo(ar->arHifDevice, &targ_info) != A_OK) { + if (BMIGetTargetInfo(ar->arHifDevice, &targ_info) != 0) { init_status = A_ERROR; goto avail_ev_failed; } @@ -1733,14 +1733,14 @@ ar6000_avail_ev(void *context, void *hif_handle) /* do any target-specific preparation that can be done through BMI */ if (ar6000_prepare_target(ar->arHifDevice, targ_info.target_type, - targ_info.target_ver) != A_OK) { + targ_info.target_ver) != 0) { init_status = A_ERROR; goto avail_ev_failed; } } - if (ar6000_configure_target(ar) != A_OK) { + if (ar6000_configure_target(ar) != 0) { init_status = A_ERROR; goto avail_ev_failed; } @@ -1795,9 +1795,9 @@ ar6000_avail_ev(void *context, void *hif_handle) if ((wlaninitmode == WLAN_INIT_MODE_UDEV) || (wlaninitmode == WLAN_INIT_MODE_DRV)) { - int status = A_OK; + int status = 0; do { - if ((status = ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != A_OK) + if ((status = ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_sysfs_bmi_get_config failed\n")); break; @@ -1806,7 +1806,7 @@ ar6000_avail_ev(void *context, void *hif_handle) break; /* Don't call ar6000_init for ART */ #endif rtnl_lock(); - status = (ar6000_init(dev)==0) ? A_OK : A_ERROR; + status = (ar6000_init(dev)==0) ? 0 : A_ERROR; rtnl_unlock(); if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_init\n")); @@ -1852,7 +1852,7 @@ static void ar6000_target_failure(void *Instance, int Status) WMI_TARGET_ERROR_REPORT_EVENT errEvent; static bool sip = false; - if (Status != A_OK) { + if (Status != 0) { printk(KERN_ERR "ar6000_target_failure: target asserted \n"); @@ -1889,26 +1889,26 @@ ar6000_unavail_ev(void *context, void *hif_handle) ar6000_devices[ar->arDeviceIndex] = NULL; ar6000_destroy(ar->arNetDev, 1); - return A_OK; + return 0; } void ar6000_restart_endpoint(struct net_device *dev) { - int status = A_OK; + int status = 0; AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); BMIInit(); do { - if ( (status=ar6000_configure_target(ar))!=A_OK) + if ( (status=ar6000_configure_target(ar))!= 0) break; - if ( (status=ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != A_OK) + if ( (status=ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_sysfs_bmi_get_config failed\n")); break; } rtnl_lock(); - status = (ar6000_init(dev)==0) ? A_OK : A_ERROR; + status = (ar6000_init(dev)==0) ? 0 : A_ERROR; rtnl_unlock(); if (status) { @@ -1919,7 +1919,7 @@ ar6000_restart_endpoint(struct net_device *dev) } } while (0); - if (status==A_OK) { + if (status== 0) { return; } @@ -2016,7 +2016,7 @@ ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs) A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig)); ar6000_set_default_ar3kconfig(ar, (void *)&ar3kconfig); status = ar->exitCallback(&ar3kconfig); - if (A_OK != status) { + if (0 != status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to reset AR3K baud rate! \n")); } } @@ -2196,7 +2196,7 @@ static void ar6000_detect_error(unsigned long ptr) AR6000_SPIN_UNLOCK(&ar->arLock, 0); /* Send the challenge on the control channel */ - if (wmi_get_challenge_resp_cmd(ar->arWmi, ar->arHBChallengeResp.seqNum, DRV_HB_CHALLENGE) != A_OK) { + if (wmi_get_challenge_resp_cmd(ar->arWmi, ar->arHBChallengeResp.seqNum, DRV_HB_CHALLENGE) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to send heart beat challenge\n")); } @@ -2329,7 +2329,7 @@ ar6000_close(struct net_device *dev) if(ar->arWmiReady == true) { if (wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, - 0, 0, 0, 0, 0, 0, 0, 0) != A_OK) { + 0, 0, 0, 0, 0, 0, 0, 0) != 0) { return -EIO; } ar->arWlanState = WLAN_DISABLED; @@ -2460,7 +2460,7 @@ int ar6000_init(struct net_device *dev) /* Do we need to finish the BMI phase */ if ((wlaninitmode == WLAN_INIT_MODE_USR || wlaninitmode == WLAN_INIT_MODE_DRV) && - (BMIDone(ar->arHifDevice) != A_OK)) + (BMIDone(ar->arHifDevice) != 0)) { ret = -EIO; goto ar6000_init_done; @@ -2700,14 +2700,14 @@ int ar6000_init(struct net_device *dev) AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() WMI is ready\n", __func__)); /* Communicate the wmi protocol verision to the target */ - if ((ar6000_set_host_app_area(ar)) != A_OK) { + if ((ar6000_set_host_app_area(ar)) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the host app area\n")); } /* configure the device for rx dot11 header rules 0,0 are the default values * therefore this command can be skipped if the inputs are 0,false,false.Required if checksum offload is needed. Set RxMetaVersion to 2*/ - if ((wmi_set_rx_frame_format_cmd(ar->arWmi,ar->rxMetaVersion, processDot11Hdr, processDot11Hdr)) != A_OK) { + if ((wmi_set_rx_frame_format_cmd(ar->arWmi,ar->rxMetaVersion, processDot11Hdr, processDot11Hdr)) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the rx frame format.\n")); } @@ -2724,7 +2724,7 @@ int ar6000_init(struct net_device *dev) #error Unsupported Bluetooth Type #endif /* Collocated Bluetooth Type */ - if ((wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &sbcb_cmd)) != A_OK) + if ((wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &sbcb_cmd)) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set collocated BT type\n")); } @@ -2739,7 +2739,7 @@ int ar6000_init(struct net_device *dev) #error Unsupported Front-End Antenna Configuration #endif /* AR600x Front-End Antenna Configuration */ - if ((wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &sbfa_cmd)) != A_OK) { + if ((wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &sbfa_cmd)) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set fornt end antenna configuration\n")); } #endif /* INIT_MODE_DRV_ENABLED && ENABLE_COEXISTENCE */ @@ -3049,12 +3049,12 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) } if (dot11Hdr) { - if (wmi_dot11_hdr_add(ar->arWmi,skb,ar->arNetworkType) != A_OK) { + if (wmi_dot11_hdr_add(ar->arWmi,skb,ar->arNetworkType) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx-wmi_dot11_hdr_add failed\n")); break; } } else { - if (wmi_dix_2_dot3(ar->arWmi, skb) != A_OK) { + if (wmi_dix_2_dot3(ar->arWmi, skb) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_dix_2_dot3 failed\n")); break; } @@ -3066,7 +3066,7 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) metaV2.csumDest = csumDest; metaV2.csumFlags = 0x1;/*instruct target to calculate checksum*/ if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, dot11Hdr, - WMI_META_VERSION_2,&metaV2) != A_OK) { + WMI_META_VERSION_2,&metaV2) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hdr_add failed\n")); break; } @@ -3075,7 +3075,7 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) else #endif { - if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, dot11Hdr,0,NULL) != A_OK) { + if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, dot11Hdr,0,NULL) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hdr_add failed\n")); break; } @@ -3781,7 +3781,7 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) break; } - A_ASSERT(status == A_OK); + A_ASSERT(status == 0); /* NWF: print the 802.11 hdr bytes */ if(containsDot11Hdr) { @@ -4130,7 +4130,7 @@ ar6000_get_iwstats(struct net_device * dev) ar->statsUpdatePending = true; - if(wmi_get_stats_cmd(ar->arWmi) != A_OK) { + if(wmi_get_stats_cmd(ar->arWmi) != 0) { break; } @@ -4757,7 +4757,7 @@ ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd) void *osbuf = NULL; s8 i; u8 size, *buf; - int ret = A_OK; + int ret = 0; size = cmd->evt_buf_sz + 4; osbuf = A_NETBUF_ALLOC(size); @@ -4893,7 +4893,7 @@ ar6000_scanComplete_event(AR_SOFTC_T *ar, int status) wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0); } if (ar->scan_triggered) { - if (status==A_OK) { + if (status== 0) { union iwreq_data wrqu; A_MEMZERO(&wrqu, sizeof(wrqu)); wireless_send_event(ar->arNetDev, SIOCGIWSCAN, &wrqu, NULL); @@ -5266,7 +5266,7 @@ int ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid) { AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; - int status = A_OK; + int status = 0; struct ar_cookie *cookie = NULL; int i; #ifdef CONFIG_PM @@ -5332,7 +5332,7 @@ ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid) /* this interface is asynchronous, if there is an error, cleanup will happen in the * TX completion callback */ HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt); - status = A_OK; + status = 0; } if (status) { @@ -5952,7 +5952,7 @@ static int ar6000_reinstall_keys(AR_SOFTC_T *ar, u8 key_op_ctrl) { - int status = A_OK; + int status = 0; struct ieee80211req_key *uik = &ar->user_saved_keys.ucast_ik; struct ieee80211req_key *bik = &ar->user_saved_keys.bcast_ik; CRYPTO_TYPE keyType = ar->user_saved_keys.keyType; @@ -6108,7 +6108,7 @@ ar6000_connect_to_ap(struct ar6_softc *ar) } if (!ar->arUserBssFilter) { - if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != A_OK) { + if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != 0) { return -EIO; } } @@ -6184,12 +6184,12 @@ is_iwioctl_allowed(u8 mode, u16 cmd) { if(cmd >= SIOCSIWCOMMIT && cmd <= SIOCGIWPOWER) { cmd -= SIOCSIWCOMMIT; - if(sioctl_filter[cmd] == 0xFF) return A_OK; - if(sioctl_filter[cmd] & mode) return A_OK; + if(sioctl_filter[cmd] == 0xFF) return 0; + if(sioctl_filter[cmd] & mode) return 0; } else if(cmd >= SIOCIWFIRSTPRIV && cmd <= (SIOCIWFIRSTPRIV+30)) { cmd -= SIOCIWFIRSTPRIV; - if(pioctl_filter[cmd] == 0xFF) return A_OK; - if(pioctl_filter[cmd] & mode) return A_OK; + if(pioctl_filter[cmd] == 0xFF) return 0; + if(pioctl_filter[cmd] & mode) return 0; } else { return A_ERROR; } @@ -6203,8 +6203,8 @@ is_xioctl_allowed(u8 mode, int cmd) A_PRINTF("Filter for this cmd=%d not defined\n",cmd); return 0; } - if(xioctl_filter[cmd] == 0xFF) return A_OK; - if(xioctl_filter[cmd] & mode) return A_OK; + if(xioctl_filter[cmd] == 0xFF) return 0; + if(xioctl_filter[cmd] & mode) return 0; return A_ERROR; } @@ -6230,7 +6230,7 @@ ap_set_wapi_key(struct ar6_softc *ar, void *ikey) ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr, SYNC_BOTH_WMIFLAG); - if (A_OK != status) { + if (0 != status) { return -EIO; } return 0; @@ -6343,7 +6343,7 @@ int ar6000_start_ap_interface(AR_SOFTC_T *ar) arApDev = (AR_VIRTUAL_INTERFACE_T *)ar->arApDev; ar->arNetDev = arApDev->arNetDev; - return A_OK; + return 0; } int ar6000_stop_ap_interface(AR_SOFTC_T *ar) @@ -6356,7 +6356,7 @@ int ar6000_stop_ap_interface(AR_SOFTC_T *ar) ar->arNetDev = arApDev->arStaNetDev; } - return A_OK; + return 0; } @@ -6390,7 +6390,7 @@ int ar6000_create_ap_interface(AR_SOFTC_T *ar, char *ap_ifname) /* Copy the MAC address */ A_MEMCPY(dev->dev_addr, ar->arNetDev->dev_addr, AR6000_ETH_ADDR_LEN); - return A_OK; + return 0; } int ar6000_add_ap_interface(AR_SOFTC_T *ar, char *ap_ifname) @@ -6398,10 +6398,10 @@ int ar6000_add_ap_interface(AR_SOFTC_T *ar, char *ap_ifname) /* Interface already added, need not proceed further */ if (ar->arApDev != NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_add_ap_interface: interface already present \n")); - return A_OK; + return 0; } - if (ar6000_create_ap_interface(ar, ap_ifname) != A_OK) { + if (ar6000_create_ap_interface(ar, ap_ifname) != 0) { return A_ERROR; } @@ -6424,7 +6424,7 @@ int ar6000_remove_ap_interface(AR_SOFTC_T *ar) arApNetDev = NULL; - return A_OK; + return 0; } #endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */ diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c index d2d18dad5ff1..46342d87cc00 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_pm.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_pm.c @@ -78,7 +78,7 @@ static void ar6000_wow_resume(AR_SOFTC_T *ar) u16 bg_period = (ar->scParams.bg_period==0) ? 60 : ar->scParams.bg_period; WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {true, false}; ar->arWowState = WLAN_WOW_STATE_NONE; - if (wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)!=A_OK) { + if (wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)!= 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup restore host awake\n")); } #if WOW_SET_SCAN_PARAMS @@ -99,7 +99,7 @@ static void ar6000_wow_resume(AR_SOFTC_T *ar) #if WOW_ENABLE_MAX_INTERVAL /* we don't do it if the power consumption is already good enough. */ - if (wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB) == A_OK) { + if (wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB) == 0) { } #endif ar6k_send_asleep_event_to_app(ar, false); @@ -137,7 +137,7 @@ static void ar6000_wow_suspend(AR_SOFTC_T *ar) ar6000_TxDataCleanup(ar); /* IMPORTANT, otherwise there will be 11mA after listen interval as 1000*/ #if WOW_ENABLE_MAX_INTERVAL /* we don't do it if the power consumption is already good enough. */ - if (wmi_listeninterval_cmd(ar->arWmi, A_MAX_WOW_LISTEN_INTERVAL, 0) == A_OK) { + if (wmi_listeninterval_cmd(ar->arWmi, A_MAX_WOW_LISTEN_INTERVAL, 0) == 0) { } #endif @@ -213,7 +213,7 @@ static void ar6000_wow_suspend(AR_SOFTC_T *ar) int ar6000_suspend_ev(void *context) { - int status = A_OK; + int status = 0; AR_SOFTC_T *ar = (AR_SOFTC_T *)context; s16 pmmode = ar->arSuspendConfig; wow_not_connected: @@ -240,7 +240,7 @@ wow_not_connected: AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Strange suspend state for not wow mode %d", ar->arWlanPowerState)); } AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Suspend for %d mode pwr %d status %d\n", __func__, pmmode, ar->arWlanPowerState, status)); - status = (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) ? A_OK : A_EBUSY; + status = (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) ? 0 : A_EBUSY; break; } @@ -270,7 +270,7 @@ int ar6000_resume_ev(void *context) AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange SDIO bus power mode!!\n")); break; } - return A_OK; + return 0; } void ar6000_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, bool isEvent) @@ -293,17 +293,17 @@ void ar6000_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, bool isEvent) int ar6000_power_change_ev(void *context, u32 config) { AR_SOFTC_T *ar = (AR_SOFTC_T *)context; - int status = A_OK; + int status = 0; AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: power change event callback %d \n", __func__, config)); switch (config) { case HIF_DEVICE_POWER_UP: ar6000_restart_endpoint(ar->arNetDev); - status = A_OK; + status = 0; break; case HIF_DEVICE_POWER_DOWN: case HIF_DEVICE_POWER_CUT: - status = A_OK; + status = 0; break; } return status; @@ -345,7 +345,7 @@ static struct platform_driver ar6000_pm_device = { int ar6000_setup_cut_power_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) { - int status = A_OK; + int status = 0; HIF_DEVICE_POWER_CHANGE_TYPE config; AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: Cut power %d %d \n", __func__,state, ar->arWlanPowerState)); @@ -383,10 +383,10 @@ ar6000_setup_cut_power_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) break; } #endif - status = A_OK; - } else if (status == A_OK) { + status = 0; + } else if (status == 0) { ar6000_restart_endpoint(ar->arNetDev); - status = A_OK; + status = 0; } } else if (state == WLAN_DISABLED) { @@ -415,7 +415,7 @@ ar6000_setup_cut_power_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) int ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) { - int status = A_OK; + int status = 0; AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: Deep sleep %d %d \n", __func__,state, ar->arWlanPowerState)); #ifdef CONFIG_PM @@ -439,7 +439,7 @@ ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) hostSleepMode.awake = true; hostSleepMode.asleep = false; - if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)) != A_OK) { + if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)) != 0) { break; } @@ -456,7 +456,7 @@ ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) ar->scParams.shortScanRatio, ar->scParams.scanCtrlFlags, ar->scParams.max_dfsch_act_time, - ar->scParams.maxact_scan_per_ssid)) != A_OK) + ar->scParams.maxact_scan_per_ssid)) != 0) { break; } @@ -464,7 +464,7 @@ ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) if (ar->arNetworkType != AP_NETWORK) { if (ar->arSsidLen) { - if (ar6000_connect_to_ap(ar) != A_OK) { + if (ar6000_connect_to_ap(ar) != 0) { /* no need to report error if connection failed */ break; } @@ -495,12 +495,12 @@ ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) ar->scan_triggered = 0; - if ((status=wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0)) != A_OK) { + if ((status=wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0)) != 0) { break; } /* make sure we disable wow for deep sleep */ - if ((status=wmi_set_wow_mode_cmd(ar->arWmi, &wowMode))!=A_OK) + if ((status=wmi_set_wow_mode_cmd(ar->arWmi, &wowMode))!= 0) { break; } @@ -512,7 +512,7 @@ ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) hostSleepMode.awake = false; hostSleepMode.asleep = true; - if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode))!=A_OK) { + if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode))!= 0) { break; } if (ar->arTxPending[ar->arControlEp]) { @@ -539,7 +539,7 @@ ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) int ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool pmEvent) { - int status = A_OK; + int status = 0; u16 powerState, oldPowerState; AR6000_WLAN_STATE oldstate = ar->arWlanState; bool wlanOff = ar->arWlanOff; @@ -631,7 +631,7 @@ ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup WLAN state %d\n", ar->arWlanState)); ar->arWlanState = oldstate; - } else if (status == A_OK) { + } else if (status == 0) { WMI_REPORT_SLEEP_STATE_EVENT wmiSleepEvent, *pSleepEvent = NULL; if ((ar->arWlanPowerState == WLAN_POWER_STATE_ON) && (oldPowerState != WLAN_POWER_STATE_ON)) { wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_AWAKE; @@ -657,13 +657,13 @@ ar6000_set_bt_hw_state(struct ar6_softc *ar, u32 enable) bool off = (enable == 0); int status; if (ar->arBTOff == off) { - return A_OK; + return 0; } ar->arBTOff = off; status = ar6000_update_wlan_pwr_state(ar, ar->arWlanOff ? WLAN_DISABLED : WLAN_ENABLED, false); return status; #else - return A_OK; + return 0; #endif } @@ -673,7 +673,7 @@ ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) int status; bool off = (state == WLAN_DISABLED); if (ar->arWlanOff == off) { - return A_OK; + return 0; } ar->arWlanOff = off; status = ar6000_update_wlan_pwr_state(ar, state, false); diff --git a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c index 22d88d70c762..8a197ff9a36c 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c @@ -55,7 +55,7 @@ ar6000_htc_raw_read_cb(void *Context, HTC_PACKET *pPacket) AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n")); } - A_ASSERT((pPacket->Status != A_OK) || + A_ASSERT((pPacket->Status != 0) || (pPacket->pBuffer == (busy->data + HTC_HEADER_LEN))); busy->length = pPacket->ActualLength + HTC_HEADER_LEN; @@ -150,7 +150,7 @@ static int ar6000_connect_raw_service(AR_SOFTC_T *ar, if (status) { if (response.ConnectRespCode == HTC_SERVICE_NO_MORE_EP) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC RAW , No more streams allowed \n")); - status = A_OK; + status = 0; } break; } @@ -228,7 +228,7 @@ int ar6000_htc_raw_open(AR_SOFTC_T *ar) arRawStream2EndpointID(ar,streamID)); /* Queue buffers to HTC for receive */ - if ((status = HTCAddReceivePkt(ar->arHtcTarget, &buffer->HTCPacket)) != A_OK) + if ((status = HTCAddReceivePkt(ar->arHtcTarget, &buffer->HTCPacket)) != 0) { BMIInit(); return -EIO; @@ -262,7 +262,7 @@ int ar6000_htc_raw_open(AR_SOFTC_T *ar) 1); /* Start the HTC component */ - if ((status = HTCStart(ar->arHtcTarget)) != A_OK) { + if ((status = HTCStart(ar->arHtcTarget)) != 0) { BMIInit(); return -EIO; } diff --git a/drivers/staging/ath6kl/os/linux/ar6k_pal.c b/drivers/staging/ath6kl/os/linux/ar6k_pal.c index c43ec827a2e7..831b2e3cf9c8 100644 --- a/drivers/staging/ath6kl/os/linux/ar6k_pal.c +++ b/drivers/staging/ath6kl/os/linux/ar6k_pal.c @@ -120,7 +120,7 @@ static int btpal_send_frame(struct sk_buff *skb) struct hci_dev *hdev = (struct hci_dev *)skb->dev; HCI_TRANSPORT_PACKET_TYPE type; ar6k_hci_pal_info_t *pHciPalInfo; - int status = A_OK; + int status = 0; struct sk_buff *txSkb = NULL; AR_SOFTC_T *ar; @@ -184,7 +184,7 @@ static int btpal_send_frame(struct sk_buff *skb) break; } - if (wmi_send_hci_cmd(ar->arWmi, skb->data, skb->len) != A_OK) + if (wmi_send_hci_cmd(ar->arWmi, skb->data, skb->len) != 0) { PRIN_LOG("send hci cmd error"); break; @@ -220,7 +220,7 @@ static int btpal_send_frame(struct sk_buff *skb) /* Add WMI packet type */ osbuf = (void *)txSkb; - if (wmi_data_hdr_add(ar->arWmi, osbuf, DATA_MSGTYPE, 0, WMI_DATA_HDR_DATA_TYPE_ACL,0,NULL) != A_OK) { + if (wmi_data_hdr_add(ar->arWmi, osbuf, DATA_MSGTYPE, 0, WMI_DATA_HDR_DATA_TYPE_ACL,0,NULL) != 0) { PRIN_LOG("XIOCTL_ACL_DATA - wmi_data_hdr_add failed\n"); } else { /* Send data buffer over HTC */ @@ -271,11 +271,11 @@ static void bt_cleanup_hci_pal(ar6k_hci_pal_info_t *pHciPalInfo) *********************************************************/ static int bt_setup_hci_pal(ar6k_hci_pal_info_t *pHciPalInfo) { - int status = A_OK; + int status = 0; struct hci_dev *pHciDev = NULL; if (!setupbtdev) { - return A_OK; + return 0; } do { @@ -404,7 +404,7 @@ bool ar6k_pal_recv_pkt(void *pHciPal, void *osbuf) **********************************************************/ int ar6k_setup_hci_pal(void *ar_p) { - int status = A_OK; + int status = 0; ar6k_hci_pal_info_t *pHciPalInfo; ar6k_pal_config_t ar6k_pal_config; AR_SOFTC_T *ar = (AR_SOFTC_T *)ar_p; @@ -445,7 +445,7 @@ int ar6k_setup_hci_pal(void *ar_p) #else /* AR6K_ENABLE_HCI_PAL */ int ar6k_setup_hci_pal(void *ar_p) { - return A_OK; + return 0; } void ar6k_cleanup_hci_pal(void *ar_p) { @@ -465,7 +465,7 @@ static int __init pal_init_module(void) hciTransCallbacks.setupTransport = ar6k_setup_hci_pal; hciTransCallbacks.cleanupTransport = ar6k_cleanup_hci_pal; - if(ar6k_register_hci_pal(&hciTransCallbacks) != A_OK) + if(ar6k_register_hci_pal(&hciTransCallbacks) != 0) return -ENODEV; return 0; diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index 92aeda6b41bd..1a4e315bab69 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -153,7 +153,7 @@ ar6k_set_wpa_version(AR_SOFTC_T *ar, enum nl80211_wpa_versions wpa_version) return -ENOTSUPP; } - return A_OK; + return 0; } static int @@ -179,7 +179,7 @@ ar6k_set_auth_type(AR_SOFTC_T *ar, enum nl80211_auth_type auth_type) return -ENOTSUPP; } - return A_OK; + return 0; } static int @@ -221,7 +221,7 @@ ar6k_set_cipher(AR_SOFTC_T *ar, u32 cipher, bool ucast) return -ENOTSUPP; } - return A_OK; + return 0; } static void @@ -378,7 +378,7 @@ ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, } if (!ar->arUserBssFilter) { - if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != A_OK) { + if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__)); up(&ar->arSem); return -EIO; @@ -743,7 +743,7 @@ ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, if (!ar->arUserBssFilter) { if (wmi_bssfilter_cmd(ar->arWmi, (ar->arConnected ? ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), - 0) != A_OK) { + 0) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__)); return -EIO; } @@ -769,7 +769,7 @@ ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, } if(wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, forceFgScan, false, \ - 0, 0, 0, NULL) != A_OK) { + 0, 0, 0, NULL) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_startscan_cmd failed\n", __func__)); ret = -EIO; } @@ -982,7 +982,7 @@ ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); struct ar_key *key = NULL; - int status = A_OK; + int status = 0; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index)); @@ -1073,7 +1073,7 @@ ar6k_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) } if (changed & WIPHY_PARAM_RTS_THRESHOLD) { - if (wmi_set_rts_cmd(ar->arWmi,wiphy->rts_threshold) != A_OK){ + if (wmi_set_rts_cmd(ar->arWmi,wiphy->rts_threshold) != 0){ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_set_rts_cmd failed\n", __func__)); return -EIO; } @@ -1148,7 +1148,7 @@ ar6k_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm) if((ar->arConnected == true)) { ar->arTxPwr = 0; - if(wmi_get_txPwr_cmd(ar->arWmi) != A_OK) { + if(wmi_get_txPwr_cmd(ar->arWmi) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_get_txPwr_cmd failed\n", __func__)); return -EIO; } @@ -1193,7 +1193,7 @@ ar6k_cfg80211_set_power_mgmt(struct wiphy *wiphy, pwrMode.powerMode = REC_POWER; } - if(wmi_powermode_cmd(ar->arWmi, pwrMode.powerMode) != A_OK) { + if(wmi_powermode_cmd(ar->arWmi, pwrMode.powerMode) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_powermode_cmd failed\n", __func__)); return -EIO; } diff --git a/drivers/staging/ath6kl/os/linux/export_hci_transport.c b/drivers/staging/ath6kl/os/linux/export_hci_transport.c index 59b5b08aaa8f..9e8ca5cafdd0 100644 --- a/drivers/staging/ath6kl/os/linux/export_hci_transport.c +++ b/drivers/staging/ath6kl/os/linux/export_hci_transport.c @@ -66,7 +66,7 @@ int ar6000_register_hci_transport(HCI_TRANSPORT_CALLBACKS *hciTransCallbacks) _HCI_TransportSetBaudRate = HCI_TransportSetBaudRate; _HCI_TransportEnablePowerMgmt = HCI_TransportEnablePowerMgmt; - return A_OK; + return 0; } int diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index 82cf52fee4f5..f170382c13a0 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -294,7 +294,7 @@ static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle, address = TARG_VTOP(pHcidevInfo->ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(pHcidevInfo->ar, hi_hci_uart_pwr_mgmt_params)); status = ar6000_ReadRegDiag(pHcidevInfo->ar->arHifDevice, &address, &hci_uart_pwr_mgmt_params); - if (A_OK == status) { + if (0 == status) { ar3kconfig.PwrMgmtEnabled = (hci_uart_pwr_mgmt_params & 0x1); ar3kconfig.IdleTimeout = (hci_uart_pwr_mgmt_params & 0xFFFF0000) >> 16; ar3kconfig.WakeupTimeout = (hci_uart_pwr_mgmt_params & 0xFF00) >> 8; @@ -470,7 +470,7 @@ int ar6000_setup_hci(AR_SOFTC_T *ar) #endif { HCI_TRANSPORT_CONFIG_INFO config; - int status = A_OK; + int status = 0; int i; HTC_PACKET *pPacket; AR6K_HCI_BRIDGE_INFO *pHcidevInfo; @@ -551,7 +551,7 @@ int ar6000_setup_hci(AR_SOFTC_T *ar) if (NULL == pHcidevInfo->pHCIDev) { /* GMBOX may not be present in older chips */ /* just return success */ - status = A_OK; + status = 0; } } ar6000_cleanup_hci(ar); @@ -601,7 +601,7 @@ int hci_test_send(void *ar, struct sk_buff *skb) int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb) #endif { - int status = A_OK; + int status = 0; int length; EPPING_HEADER *pHeader; HTC_PACKET *pPacket; @@ -712,7 +712,7 @@ static int bt_send_frame(struct sk_buff *skb) HCI_TRANSPORT_PACKET_TYPE type; AR6K_HCI_BRIDGE_INFO *pHcidevInfo; HTC_PACKET *pPacket; - int status = A_OK; + int status = 0; struct sk_buff *txSkb = NULL; if (!hdev) { @@ -855,12 +855,12 @@ static void bt_destruct(struct hci_dev *hdev) static int bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) { - int status = A_OK; + int status = 0; struct hci_dev *pHciDev = NULL; HIF_DEVICE_OS_DEVICE_INFO osDevInfo; if (!setupbtdev) { - return A_OK; + return 0; } do { @@ -938,7 +938,7 @@ static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) static int bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) { int err; - int status = A_OK; + int status = 0; do { AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: registering HCI... \n")); @@ -1043,7 +1043,7 @@ static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, struct sk_buff *sk /* stubs when we only want to test the HCI bridging Interface without the HT stack */ static int bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) { - return A_OK; + return 0; } static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) { @@ -1085,7 +1085,7 @@ int ar6000_setup_hci(void *ar) int ar6000_setup_hci(AR_SOFTC_T *ar) #endif { - return A_OK; + return 0; } #ifdef EXPORT_HCI_BRIDGE_INTERFACE diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index 3463a5008767..5be8ea335ee7 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -45,7 +45,7 @@ ar6000_ioctl_get_roam_tbl(struct net_device *dev, struct ifreq *rq) return -EIO; } - if(wmi_get_roam_tbl_cmd(ar->arWmi) != A_OK) { + if(wmi_get_roam_tbl_cmd(ar->arWmi) != 0) { return -EIO; } @@ -63,7 +63,7 @@ ar6000_ioctl_get_roam_data(struct net_device *dev, struct ifreq *rq) /* currently assume only roam times are required */ - if(wmi_get_roam_data_cmd(ar->arWmi, ROAM_DATA_TIME) != A_OK) { + if(wmi_get_roam_data_cmd(ar->arWmi, ROAM_DATA_TIME) != 0) { return -EIO; } @@ -97,7 +97,7 @@ ar6000_ioctl_set_roam_ctrl(struct net_device *dev, char *userdata) return -EFAULT; } - if(wmi_set_roam_ctrl_cmd(ar->arWmi, &cmd, size) != A_OK) { + if(wmi_set_roam_ctrl_cmd(ar->arWmi, &cmd, size) != 0) { return -EIO; } @@ -123,7 +123,7 @@ ar6000_ioctl_set_powersave_timers(struct net_device *dev, char *userdata) return -EFAULT; } - if(wmi_set_powersave_timers_cmd(ar->arWmi, &cmd, size) != A_OK) { + if(wmi_set_powersave_timers_cmd(ar->arWmi, &cmd, size) != 0) { return -EIO; } @@ -153,7 +153,7 @@ ar6000_ioctl_set_qos_supp(struct net_device *dev, struct ifreq *rq) ret = wmi_set_qos_supp_cmd(ar->arWmi, cmd.status); switch (ret) { - case A_OK: + case 0: return 0; case A_EBUSY : return -EBUSY; @@ -194,7 +194,7 @@ ar6000_ioctl_set_wmm(struct net_device *dev, struct ifreq *rq) ret = wmi_set_wmm_cmd(ar->arWmi, cmd.status); switch (ret) { - case A_OK: + case 0: return 0; case A_EBUSY : return -EBUSY; @@ -229,7 +229,7 @@ ar6000_ioctl_set_txop(struct net_device *dev, struct ifreq *rq) ret = wmi_set_wmm_txop(ar->arWmi, cmd.txopEnable); switch (ret) { - case A_OK: + case 0: return 0; case A_EBUSY : return -EBUSY; @@ -284,7 +284,7 @@ ar6000_ioctl_set_country(struct net_device *dev, struct ifreq *rq) A_MEMCPY(ar->ap_country_code, cmd.countryCode, 3); switch (ret) { - case A_OK: + case 0: return 0; case A_EBUSY : return -EBUSY; @@ -361,7 +361,7 @@ ar6000_ioctl_set_channelParams(struct net_device *dev, struct ifreq *rq) if (!ret && (wmi_set_channelParams_cmd(ar->arWmi, cmdp->scanParam, cmdp->phyMode, cmdp->numChannels, cmdp->channelList) - != A_OK)) + != 0)) { ret = -EIO; } @@ -394,7 +394,7 @@ ar6000_ioctl_set_snr_threshold(struct net_device *dev, struct ifreq *rq) return -EFAULT; } - if( wmi_set_snr_threshold_params(ar->arWmi, &cmd) != A_OK ) { + if( wmi_set_snr_threshold_params(ar->arWmi, &cmd) != 0 ) { ret = -EIO; } @@ -480,7 +480,7 @@ ar6000_ioctl_set_rssi_threshold(struct net_device *dev, struct ifreq *rq) cmd.thresholdBelow5_Val = ar->rssi_map[10].rssi; cmd.thresholdBelow6_Val = ar->rssi_map[11].rssi; - if( wmi_set_rssi_threshold_params(ar->arWmi, &cmd) != A_OK ) { + if( wmi_set_rssi_threshold_params(ar->arWmi, &cmd) != 0 ) { ret = -EIO; } @@ -503,7 +503,7 @@ ar6000_ioctl_set_lq_threshold(struct net_device *dev, struct ifreq *rq) return -EFAULT; } - if( wmi_set_lq_threshold_params(ar->arWmi, &cmd) != A_OK ) { + if( wmi_set_lq_threshold_params(ar->arWmi, &cmd) != 0 ) { ret = -EIO; } @@ -527,7 +527,7 @@ ar6000_ioctl_set_probedSsid(struct net_device *dev, struct ifreq *rq) } if (wmi_probedSsid_cmd(ar->arWmi, cmd.entryIndex, cmd.flag, cmd.ssidLength, - cmd.ssid) != A_OK) + cmd.ssid) != 0) { ret = -EIO; } @@ -559,11 +559,11 @@ ar6000_ioctl_set_badAp(struct net_device *dev, struct ifreq *rq) /* * This is a delete badAP. */ - if (wmi_deleteBadAp_cmd(ar->arWmi, cmd.badApIndex) != A_OK) { + if (wmi_deleteBadAp_cmd(ar->arWmi, cmd.badApIndex) != 0) { ret = -EIO; } } else { - if (wmi_addBadAp_cmd(ar->arWmi, cmd.badApIndex, cmd.bssid) != A_OK) { + if (wmi_addBadAp_cmd(ar->arWmi, cmd.badApIndex, cmd.bssid) != 0) { ret = -EIO; } } @@ -588,11 +588,11 @@ ar6000_ioctl_create_qos(struct net_device *dev, struct ifreq *rq) } ret = wmi_verify_tspec_params(&cmd, tspecCompliance); - if (ret == A_OK) + if (ret == 0) ret = wmi_create_pstream_cmd(ar->arWmi, &cmd); switch (ret) { - case A_OK: + case 0: return 0; case A_EBUSY : return -EBUSY; @@ -622,7 +622,7 @@ ar6000_ioctl_delete_qos(struct net_device *dev, struct ifreq *rq) ret = wmi_delete_pstream_cmd(ar->arWmi, cmd.trafficClass, cmd.tsid); switch (ret) { - case A_OK: + case 0: return 0; case A_EBUSY : return -EBUSY; @@ -687,7 +687,7 @@ ar6000_ioctl_tcmd_get_rx_report(struct net_device *dev, } ar->tcmdRxReport = 0; - if (wmi_test_cmd(ar->arWmi, data, len) != A_OK) { + if (wmi_test_cmd(ar->arWmi, data, len) != 0) { up(&ar->arSem); return -EIO; } @@ -802,7 +802,7 @@ ar6000_ioctl_get_target_stats(struct net_device *dev, struct ifreq *rq) ar->statsUpdatePending = true; - if(wmi_get_stats_cmd(ar->arWmi) != A_OK) { + if(wmi_get_stats_cmd(ar->arWmi) != 0) { up(&ar->arSem); return -EIO; } @@ -865,7 +865,7 @@ ar6000_ioctl_get_ap_stats(struct net_device *dev, struct ifreq *rq) ar->statsUpdatePending = true; - if(wmi_get_stats_cmd(ar->arWmi) != A_OK) { + if(wmi_get_stats_cmd(ar->arWmi) != 0) { up(&ar->arSem); return -EIO; } @@ -901,7 +901,7 @@ ar6000_ioctl_set_access_params(struct net_device *dev, struct ifreq *rq) } if (wmi_set_access_params_cmd(ar->arWmi, cmd.ac, cmd.txop, cmd.eCWmin, cmd.eCWmax, - cmd.aifsn) == A_OK) + cmd.aifsn) == 0) { ret = 0; } else { @@ -926,7 +926,7 @@ ar6000_ioctl_set_disconnect_timeout(struct net_device *dev, struct ifreq *rq) return -EFAULT; } - if (wmi_disctimeout_cmd(ar->arWmi, cmd.disconnectTimeout) == A_OK) + if (wmi_disctimeout_cmd(ar->arWmi, cmd.disconnectTimeout) == 0) { ret = 0; } else { @@ -951,7 +951,7 @@ ar6000_xioctl_set_voice_pkt_size(struct net_device *dev, char *userdata) return -EFAULT; } - if (wmi_set_voice_pkt_size_cmd(ar->arWmi, cmd.voicePktSize) == A_OK) + if (wmi_set_voice_pkt_size_cmd(ar->arWmi, cmd.voicePktSize) == 0) { ret = 0; } else { @@ -977,7 +977,7 @@ ar6000_xioctl_set_max_sp_len(struct net_device *dev, char *userdata) return -EFAULT; } - if (wmi_set_max_sp_len_cmd(ar->arWmi, cmd.maxSPLen) == A_OK) + if (wmi_set_max_sp_len_cmd(ar->arWmi, cmd.maxSPLen) == 0) { ret = 0; } else { @@ -1003,7 +1003,7 @@ ar6000_xioctl_set_bt_status_cmd(struct net_device *dev, char *userdata) return -EFAULT; } - if (wmi_set_bt_status_cmd(ar->arWmi, cmd.streamType, cmd.status) == A_OK) + if (wmi_set_bt_status_cmd(ar->arWmi, cmd.streamType, cmd.status) == 0) { ret = 0; } else { @@ -1028,7 +1028,7 @@ ar6000_xioctl_set_bt_params_cmd(struct net_device *dev, char *userdata) return -EFAULT; } - if (wmi_set_bt_params_cmd(ar->arWmi, &cmd) == A_OK) + if (wmi_set_bt_params_cmd(ar->arWmi, &cmd) == 0) { ret = 0; } else { @@ -1052,7 +1052,7 @@ ar6000_xioctl_set_btcoex_fe_ant_cmd(struct net_device * dev, char *userdata) return -EFAULT; } - if (wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &cmd) == A_OK) + if (wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &cmd) == 0) { ret = 0; } else { @@ -1077,7 +1077,7 @@ ar6000_xioctl_set_btcoex_colocated_bt_dev_cmd(struct net_device * dev, char *use return -EFAULT; } - if (wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &cmd) == A_OK) + if (wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &cmd) == 0) { ret = 0; } else { @@ -1102,7 +1102,7 @@ ar6000_xioctl_set_btcoex_btinquiry_page_config_cmd(struct net_device * dev, cha return -EFAULT; } - if (wmi_set_btcoex_btinquiry_page_config_cmd(ar->arWmi, &cmd) == A_OK) + if (wmi_set_btcoex_btinquiry_page_config_cmd(ar->arWmi, &cmd) == 0) { ret = 0; } else { @@ -1127,7 +1127,7 @@ ar6000_xioctl_set_btcoex_sco_config_cmd(struct net_device * dev, char *userdata) return -EFAULT; } - if (wmi_set_btcoex_sco_config_cmd(ar->arWmi, &cmd) == A_OK) + if (wmi_set_btcoex_sco_config_cmd(ar->arWmi, &cmd) == 0) { ret = 0; } else { @@ -1153,7 +1153,7 @@ ar6000_xioctl_set_btcoex_a2dp_config_cmd(struct net_device * dev, return -EFAULT; } - if (wmi_set_btcoex_a2dp_config_cmd(ar->arWmi, &cmd) == A_OK) + if (wmi_set_btcoex_a2dp_config_cmd(ar->arWmi, &cmd) == 0) { ret = 0; } else { @@ -1178,7 +1178,7 @@ ar6000_xioctl_set_btcoex_aclcoex_config_cmd(struct net_device * dev, char *userd return -EFAULT; } - if (wmi_set_btcoex_aclcoex_config_cmd(ar->arWmi, &cmd) == A_OK) + if (wmi_set_btcoex_aclcoex_config_cmd(ar->arWmi, &cmd) == 0) { ret = 0; } else { @@ -1203,7 +1203,7 @@ ar60000_xioctl_set_btcoex_debug_cmd(struct net_device * dev, char *userdata) return -EFAULT; } - if (wmi_set_btcoex_debug_cmd(ar->arWmi, &cmd) == A_OK) + if (wmi_set_btcoex_debug_cmd(ar->arWmi, &cmd) == 0) { ret = 0; } else { @@ -1228,7 +1228,7 @@ ar6000_xioctl_set_btcoex_bt_operating_status_cmd(struct net_device * dev, char * return -EFAULT; } - if (wmi_set_btcoex_bt_operating_status_cmd(ar->arWmi, &cmd) == A_OK) + if (wmi_set_btcoex_bt_operating_status_cmd(ar->arWmi, &cmd) == 0) { ret = 0; } else { @@ -1261,7 +1261,7 @@ ar6000_xioctl_get_btcoex_config_cmd(struct net_device * dev, char *userdata, return -ERESTARTSYS; } - if (wmi_get_btcoex_config_cmd(ar->arWmi, (WMI_GET_BTCOEX_CONFIG_CMD *)&btcoexConfig.configCmd) != A_OK) + if (wmi_get_btcoex_config_cmd(ar->arWmi, (WMI_GET_BTCOEX_CONFIG_CMD *)&btcoexConfig.configCmd) != 0) { up(&ar->arSem); return -EIO; @@ -1305,7 +1305,7 @@ ar6000_xioctl_get_btcoex_stats_cmd(struct net_device * dev, char *userdata, stru return -EFAULT; } - if (wmi_get_btcoex_stats_cmd(ar->arWmi) != A_OK) + if (wmi_get_btcoex_stats_cmd(ar->arWmi) != 0) { up(&ar->arSem); return -EIO; @@ -1475,7 +1475,7 @@ ar6000_create_acl_data_osbuf(struct net_device *dev, u8 *userdata, void **p_osbu u8 tmp_space[8]; HCI_ACL_DATA_PKT *acl; u8 hdr_size, *datap=NULL; - int ret = A_OK; + int ret = 0; /* ACL is in data path. There is a need to create pool * mechanism for allocating and freeing NETBUFs - ToDo later. @@ -1508,7 +1508,7 @@ ar6000_create_acl_data_osbuf(struct net_device *dev, u8 *userdata, void **p_osbu } } while(false); - if (ret == A_OK) { + if (ret == 0) { *p_osbuf = osbuf; } else { A_NETBUF_FREE(osbuf); @@ -1878,7 +1878,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) goto ioctl_done; } userdata = (char *)(((unsigned int *)rq->ifr_data)+1); - if(is_xioctl_allowed(ar->arNextMode, cmd) != A_OK) { + if(is_xioctl_allowed(ar->arNextMode, cmd) != 0) { A_PRINTF("xioctl: cmd=%d not allowed in this mode\n",cmd); ret = -EOPNOTSUPP; goto ioctl_done; @@ -2193,7 +2193,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) #ifdef HTC_RAW_INTERFACE case AR6000_XIOCTL_HTC_RAW_OPEN: - ret = A_OK; + ret = 0; if (!arRawIfEnabled(ar)) { /* make sure block size is set in case the target was reset since last * BMI phase (i.e. flashup downloads) */ @@ -2207,7 +2207,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } /* Terminate the BMI phase */ ret = BMIDone(hifDevice); - if (ret == A_OK) { + if (ret == 0) { ret = ar6000_htc_raw_open(ar); } } @@ -2309,7 +2309,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) break; } - if (wmi_prof_cfg_cmd(ar->arWmi, period, nbins) != A_OK) { + if (wmi_prof_cfg_cmd(ar->arWmi, period, nbins) != 0) { ret = -EIO; } @@ -2325,7 +2325,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) break; } - if (wmi_prof_addr_set_cmd(ar->arWmi, addr) != A_OK) { + if (wmi_prof_addr_set_cmd(ar->arWmi, addr) != 0) { ret = -EIO; } @@ -2363,7 +2363,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) prof_count_available = false; ret = prof_count_get(dev); - if (ret != A_OK) { + if (ret != 0) { up(&ar->arSem); ret = -EIO; goto ioctl_done; @@ -2406,7 +2406,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; } else { if (wmi_powermode_cmd(ar->arWmi, pwrModeCmd.powerMode) - != A_OK) + != 0) { ret = -EIO; } @@ -2425,7 +2425,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; } else { if (wmi_ibsspmcaps_cmd(ar->arWmi, ibssPmCaps.power_saving, ibssPmCaps.ttl, - ibssPmCaps.atim_windows, ibssPmCaps.timeout_value) != A_OK) + ibssPmCaps.atim_windows, ibssPmCaps.timeout_value) != 0) { ret = -EIO; } @@ -2447,7 +2447,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; } else { if (wmi_apps_cmd(ar->arWmi, apPsCmd.psType, apPsCmd.idle_time, - apPsCmd.ps_period, apPsCmd.sleep_period) != A_OK) + apPsCmd.ps_period, apPsCmd.sleep_period) != 0) { ret = -EIO; } @@ -2475,7 +2475,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) #else SEND_POWER_SAVE_FAIL_EVENT_ALWAYS #endif - ) != A_OK) + ) != 0) { ret = -EIO; } @@ -2506,7 +2506,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ar->scParams.shortScanRatio, ar->scParams.scanCtrlFlags, ar->scParams.max_dfsch_act_time, - ar->scParams.maxact_scan_per_ssid) != A_OK) + ar->scParams.maxact_scan_per_ssid) != 0) { ret = -EIO; } @@ -2524,7 +2524,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { ret = -EFAULT; } else { - if (wmi_listeninterval_cmd(ar->arWmi, listenCmd.listenInterval, listenCmd.numBeacons) != A_OK) { + if (wmi_listeninterval_cmd(ar->arWmi, listenCmd.listenInterval, listenCmd.numBeacons) != 0) { ret = -EIO; } else { AR6000_SPIN_LOCK(&ar->arLock, 0); @@ -2547,7 +2547,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { ret = -EFAULT; } else { - if (wmi_bmisstime_cmd(ar->arWmi, bmissCmd.bmissTime, bmissCmd.numBeacons) != A_OK) { + if (wmi_bmisstime_cmd(ar->arWmi, bmissCmd.bmissTime, bmissCmd.numBeacons) != 0) { ret = -EIO; } } @@ -2565,7 +2565,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; } else { if (wmi_bssfilter_cmd(ar->arWmi, filt.bssFilter, filt.ieMask) - != A_OK) { + != 0) { ret = -EIO; } else { ar->arUserBssFilter = param; @@ -2614,7 +2614,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) #else WMI_IGNORE_BARKER_IN_ERP #endif - ) != A_OK) + ) != 0) { ret = -EIO; } @@ -2634,7 +2634,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } else { ar->arRTS = rtsCmd.threshold; if (wmi_set_rts_cmd(ar->arWmi, rtsCmd.threshold) - != A_OK) + != 0) { ret = -EIO; } @@ -2728,7 +2728,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) break; } if (wmi_associnfo_cmd(ar->arWmi, cmd.ieType, - cmd.bufferSize, assocInfo) != A_OK) { + cmd.bufferSize, assocInfo) != 0) { ret = -EIO; break; } @@ -2811,7 +2811,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } /* Send the challenge on the control channel */ - if (wmi_get_challenge_resp_cmd(ar->arWmi, cookie, APP_HB_CHALLENGE) != A_OK) { + if (wmi_get_challenge_resp_cmd(ar->arWmi, cookie, APP_HB_CHALLENGE) != 0) { ret = -EIO; goto ioctl_done; } @@ -2868,7 +2868,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) gpio_output_set_cmd.clear_mask, gpio_output_set_cmd.enable_mask, gpio_output_set_cmd.disable_mask); - if (ret != A_OK) { + if (ret != 0) { ret = -EIO; } } @@ -2896,7 +2896,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } ret = ar6000_gpio_input_get(dev); - if (ret != A_OK) { + if (ret != 0) { up(&ar->arSem); ret = -EIO; goto ioctl_done; @@ -2948,7 +2948,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = ar6000_gpio_register_set(dev, gpio_register_cmd.gpioreg_id, gpio_register_cmd.value); - if (ret != A_OK) { + if (ret != 0) { ret = -EIO; } @@ -2989,7 +2989,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; } else { ret = ar6000_gpio_register_get(dev, gpio_register_cmd.gpioreg_id); - if (ret != A_OK) { + if (ret != 0) { up(&ar->arSem); ret = -EIO; goto ioctl_done; @@ -3039,7 +3039,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; } else { ret = ar6000_gpio_intr_ack(dev, gpio_intr_ack_cmd.ack_mask); - if (ret != A_OK) { + if (ret != 0) { ret = -EIO; } } @@ -3076,7 +3076,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) /* Send the challenge on the control channel */ if (wmi_config_debug_module_cmd(ar->arWmi, config.mmask, config.tsr, config.rep, - config.size, config.valid) != A_OK) + config.size, config.valid) != 0) { ret = -EIO; goto ioctl_done; @@ -3087,7 +3087,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS: { /* Send the challenge on the control channel */ - if (ar6000_dbglog_get_debug_logs(ar) != A_OK) + if (ar6000_dbglog_get_debug_logs(ar) != 0) { ret = -EIO; goto ioctl_done; @@ -3131,7 +3131,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; } else if (wmi_set_opt_mode_cmd(ar->arWmi, optModeCmd.optMode) - != A_OK) + != 0) { ret = -EIO; } @@ -3179,7 +3179,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (wmi_set_retry_limits_cmd(ar->arWmi, setRetryParams.frameType, setRetryParams.trafficClass, setRetryParams.maxRetries, - setRetryParams.enableNotify) != A_OK) + setRetryParams.enableNotify) != 0) { ret = -EIO; } @@ -3201,7 +3201,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { ret = -EFAULT; } else if (wmi_set_adhoc_bconIntvl_cmd(ar->arWmi, bIntvlCmd.beaconInterval) - != A_OK) + != 0) { ret = -EIO; } @@ -3266,7 +3266,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) AR6000_WLAN_STATE state; if (get_user(state, (unsigned int *)userdata)) ret = -EFAULT; - else if (ar6000_set_wlan_state(ar, state) != A_OK) + else if (ar6000_set_wlan_state(ar, state) != 0) ret = -EIO; break; } @@ -3354,7 +3354,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) cmdp->homeDwellTime, cmdp->forceScanInterval, cmdp->numChannels, - cmdp->channelList) != A_OK) + cmdp->channelList) != 0) { ret = -EIO; } @@ -3376,7 +3376,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) returnStatus = wmi_set_fixrates_cmd(ar->arWmi, setFixRatesCmd.fixRateMask); if (returnStatus == A_EINVAL) { ret = -EINVAL; - } else if(returnStatus != A_OK) { + } else if(returnStatus != 0) { ret = -EIO; } else { ar->ap_profile_flag = 1; /* There is a change in profile */ @@ -3415,7 +3415,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } else { ar->arRateMask = 0xFFFFFFFF; - if (wmi_get_ratemask_cmd(ar->arWmi) != A_OK) { + if (wmi_get_ratemask_cmd(ar->arWmi) != 0) { up(&ar->arSem); ret = -EIO; goto ioctl_done; @@ -3450,7 +3450,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { ret = -EFAULT; } else { - if (wmi_set_authmode_cmd(ar->arWmi, setAuthMode.mode) != A_OK) + if (wmi_set_authmode_cmd(ar->arWmi, setAuthMode.mode) != 0) { ret = -EIO; } @@ -3468,7 +3468,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { ret = -EFAULT; } else { - if (wmi_set_reassocmode_cmd(ar->arWmi, setReassocMode.mode) != A_OK) + if (wmi_set_reassocmode_cmd(ar->arWmi, setReassocMode.mode) != 0) { ret = -EIO; } @@ -3483,7 +3483,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) break; } addr = TARG_VTOP(ar->arTargetType, addr); - if (ar6000_ReadRegDiag(ar->arHifDevice, &addr, &data) != A_OK) { + if (ar6000_ReadRegDiag(ar->arHifDevice, &addr, &data) != 0) { ret = -EIO; } if (put_user(data, (unsigned int *)userdata + 1)) { @@ -3501,7 +3501,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) break; } addr = TARG_VTOP(ar->arTargetType, addr); - if (ar6000_WriteRegDiag(ar->arHifDevice, &addr, &data) != A_OK) { + if (ar6000_WriteRegDiag(ar->arHifDevice, &addr, &data) != 0) { ret = -EIO; } break; @@ -3516,7 +3516,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) sizeof(setKeepAlive))){ ret = -EFAULT; } else { - if (wmi_set_keepalive_cmd(ar->arWmi, setKeepAlive.keepaliveInterval) != A_OK) { + if (wmi_set_keepalive_cmd(ar->arWmi, setKeepAlive.keepaliveInterval) != 0) { ret = -EIO; } } @@ -3536,7 +3536,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { ret = -EFAULT; } else { - if (wmi_set_params_cmd(ar->arWmi, cmd.opcode, cmd.length, cmd.buffer) != A_OK) { + if (wmi_set_params_cmd(ar->arWmi, cmd.opcode, cmd.length, cmd.buffer) != 0) { ret = -EIO; } } @@ -3555,7 +3555,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (wmi_set_mcast_filter_cmd(ar->arWmi, cmd.multicast_mac[0], cmd.multicast_mac[1], cmd.multicast_mac[2], - cmd.multicast_mac[3]) != A_OK) { + cmd.multicast_mac[3]) != 0) { ret = -EIO; } } @@ -3574,7 +3574,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (wmi_del_mcast_filter_cmd(ar->arWmi, cmd.multicast_mac[0], cmd.multicast_mac[1], cmd.multicast_mac[2], - cmd.multicast_mac[3]) != A_OK) { + cmd.multicast_mac[3]) != 0) { ret = -EIO; } } @@ -3590,7 +3590,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) sizeof(cmd))){ ret = -EFAULT; } else { - if (wmi_mcast_filter_cmd(ar->arWmi, cmd.enable) != A_OK) { + if (wmi_mcast_filter_cmd(ar->arWmi, cmd.enable) != 0) { ret = -EIO; } } @@ -3623,7 +3623,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } else { getKeepAlive.keepaliveInterval = wmi_get_keepalive_cmd(ar->arWmi); ar->arKeepaliveConfigured = 0xFF; - if (wmi_get_keepalive_configured(ar->arWmi) != A_OK){ + if (wmi_get_keepalive_configured(ar->arWmi) != 0){ up(&ar->arSem); ret = -EIO; goto ioctl_done; @@ -3675,7 +3675,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; } else { if (wmi_set_appie_cmd(ar->arWmi, appIEcmd.mgmtFrmType, - appIEcmd.ieLen, appIeInfo) != A_OK) + appIEcmd.ieLen, appIeInfo) != 0) { ret = -EIO; } @@ -3700,7 +3700,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } else { cmd.bssFilter = NONE_BSS_FILTER; } - if (wmi_bssfilter_cmd(ar->arWmi, cmd.bssFilter, 0) != A_OK) { + if (wmi_bssfilter_cmd(ar->arWmi, cmd.bssFilter, 0) != 0) { ret = -EIO; } else { ar->arUserBssFilter = cmd.bssFilter; @@ -3723,7 +3723,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; goto ioctl_done; } - if (wmi_set_wsc_status_cmd(ar->arWmi, wsc_status) != A_OK) { + if (wmi_set_wsc_status_cmd(ar->arWmi, wsc_status) != 0) { ret = -EIO; } break; @@ -3747,7 +3747,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ROM_addr, RAM_addr, nbytes)); ret = BMIrompatchInstall(hifDevice, ROM_addr, RAM_addr, nbytes, do_activate, &rompatch_id); - if (ret == A_OK) { + if (ret == 0) { /* return value */ if (put_user(rompatch_id, (unsigned int *)rq->ifr_data)) { ret = -EFAULT; @@ -3812,7 +3812,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; } else { if (wmi_set_ip_cmd(ar->arWmi, - &setIP) != A_OK) + &setIP) != 0) { ret = -EIO; } @@ -3832,7 +3832,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; } else { if (wmi_set_host_sleep_mode_cmd(ar->arWmi, - &setHostSleepMode) != A_OK) + &setHostSleepMode) != 0) { ret = -EIO; } @@ -3851,7 +3851,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; } else { if (wmi_set_wow_mode_cmd(ar->arWmi, - &setWowMode) != A_OK) + &setWowMode) != 0) { ret = -EIO; } @@ -3870,7 +3870,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; } else { if (wmi_get_wow_list_cmd(ar->arWmi, - &getWowList) != A_OK) + &getWowList) != 0) { ret = -EIO; } @@ -3912,7 +3912,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) break; } if (wmi_add_wow_pattern_cmd(ar->arWmi, - &cmd, pattern_data, mask_data, cmd.filter_size) != A_OK) + &cmd, pattern_data, mask_data, cmd.filter_size) != 0) { ret = -EIO; } @@ -3933,7 +3933,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; } else { if (wmi_del_wow_pattern_cmd(ar->arWmi, - &delWowPattern) != A_OK) + &delWowPattern) != 0) { ret = -EIO; } @@ -4020,7 +4020,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { ret = -EFAULT; } else { - if (wmi_set_akmp_params_cmd(ar->arWmi, &akmpParams) != A_OK) { + if (wmi_set_akmp_params_cmd(ar->arWmi, &akmpParams) != 0) { ret = -EIO; } } @@ -4042,7 +4042,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; break; } - if (wmi_set_pmkid_list_cmd(ar->arWmi, &pmkidInfo) != A_OK) { + if (wmi_set_pmkid_list_cmd(ar->arWmi, &pmkidInfo) != 0) { ret = -EIO; } } @@ -4051,7 +4051,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (ar->arWmiReady == false) { ret = -EIO; } else { - if (wmi_get_pmkid_list_cmd(ar->arWmi) != A_OK) { + if (wmi_get_pmkid_list_cmd(ar->arWmi) != 0) { ret = -EIO; } } @@ -4365,7 +4365,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; } else { - if (wmi_set_ht_cap_cmd(ar->arWmi, &htCap) != A_OK) + if (wmi_set_ht_cap_cmd(ar->arWmi, &htCap) != 0) { ret = -EIO; } @@ -4382,7 +4382,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; } else { - if (wmi_set_ht_op_cmd(ar->arWmi, htOp.sta_chan_width) != A_OK) + if (wmi_set_ht_op_cmd(ar->arWmi, htOp.sta_chan_width) != 0) { ret = -EIO; } @@ -4395,10 +4395,10 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) void *osbuf = NULL; if (ar->arWmiReady == false) { ret = -EIO; - } else if (ar6000_create_acl_data_osbuf(dev, (u8 *)userdata, &osbuf) != A_OK) { + } else if (ar6000_create_acl_data_osbuf(dev, (u8 *)userdata, &osbuf) != 0) { ret = -EIO; } else { - if (wmi_data_hdr_add(ar->arWmi, osbuf, DATA_MSGTYPE, 0, WMI_DATA_HDR_DATA_TYPE_ACL,0,NULL) != A_OK) { + if (wmi_data_hdr_add(ar->arWmi, osbuf, DATA_MSGTYPE, 0, WMI_DATA_HDR_DATA_TYPE_ACL,0,NULL) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("XIOCTL_ACL_DATA - wmi_data_hdr_add failed\n")); } else { /* Send data buffer over HTC */ @@ -4422,7 +4422,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } else if(copy_from_user(cmd->buf, userdata + size, cmd->cmd_buf_sz)) { ret = -EFAULT; } else { - if (wmi_send_hci_cmd(ar->arWmi, cmd->buf, cmd->cmd_buf_sz) != A_OK) { + if (wmi_send_hci_cmd(ar->arWmi, cmd->buf, cmd->cmd_buf_sz) != 0) { ret = -EIO; }else if(loghci) { A_PRINTF_LOG("HCI Command To PAL --> \n"); @@ -4448,7 +4448,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } else { if (cmd.precedence == BT_WLAN_CONN_PRECDENCE_WLAN || cmd.precedence == BT_WLAN_CONN_PRECDENCE_PAL) { - if ( wmi_set_wlan_conn_precedence_cmd(ar->arWmi, cmd.precedence) != A_OK) { + if ( wmi_set_wlan_conn_precedence_cmd(ar->arWmi, cmd.precedence) != 0) { ret = -EIO; } } else { @@ -4474,7 +4474,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; } else { - if (wmi_set_tx_select_rates_cmd(ar->arWmi, masks.rateMasks) != A_OK) + if (wmi_set_tx_select_rates_cmd(ar->arWmi, masks.rateMasks) != 0) { ret = -EIO; } @@ -4606,7 +4606,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; break; } - if (ar6000_set_bt_hw_state(ar, state)!=A_OK) { + if (ar6000_set_bt_hw_state(ar, state)!= 0) { ret = -EIO; } } @@ -4626,7 +4626,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) sizeof(SGICmd))){ ret = -EFAULT; } else{ - if (wmi_SGI_cmd(ar->arWmi, SGICmd.sgiMask, SGICmd.sgiPERThreshold) != A_OK) { + if (wmi_SGI_cmd(ar->arWmi, SGICmd.sgiMask, SGICmd.sgiPERThreshold) != 0) { ret = -EIO; } @@ -4641,7 +4641,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (copy_from_user(ap_ifname, userdata, IFNAMSIZ)) { ret = -EFAULT; } else { - if (ar6000_add_ap_interface(ar, ap_ifname) != A_OK) { + if (ar6000_add_ap_interface(ar, ap_ifname) != 0) { ret = -EIO; } } @@ -4652,7 +4652,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) break; case AR6000_XIOCTL_REMOVE_AP_INTERFACE: #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT - if (ar6000_remove_ap_interface(ar) != A_OK) { + if (ar6000_remove_ap_interface(ar) != 0) { ret = -EIO; } #else diff --git a/drivers/staging/ath6kl/os/linux/netbuf.c b/drivers/staging/ath6kl/os/linux/netbuf.c index 703a2cdf84c9..0a41df03a8b4 100644 --- a/drivers/staging/ath6kl/os/linux/netbuf.c +++ b/drivers/staging/ath6kl/os/linux/netbuf.c @@ -109,7 +109,7 @@ a_netbuf_push(void *bufPtr, s32 len) { skb_push((struct sk_buff *)bufPtr, len); - return A_OK; + return 0; } /* @@ -122,7 +122,7 @@ a_netbuf_push_data(void *bufPtr, char *srcPtr, s32 len) skb_push((struct sk_buff *) bufPtr, len); A_MEMCPY(((struct sk_buff *)bufPtr)->data, srcPtr, len); - return A_OK; + return 0; } /* @@ -134,7 +134,7 @@ a_netbuf_put(void *bufPtr, s32 len) { skb_put((struct sk_buff *)bufPtr, len); - return A_OK; + return 0; } /* @@ -149,7 +149,7 @@ a_netbuf_put_data(void *bufPtr, char *srcPtr, s32 len) skb_put((struct sk_buff *)bufPtr, len); A_MEMCPY(start, srcPtr, len); - return A_OK; + return 0; } @@ -161,7 +161,7 @@ a_netbuf_setlen(void *bufPtr, s32 len) { skb_trim((struct sk_buff *)bufPtr, len); - return A_OK; + return 0; } /* @@ -172,7 +172,7 @@ a_netbuf_trim(void *bufPtr, s32 len) { skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len); - return A_OK; + return 0; } /* @@ -187,7 +187,7 @@ a_netbuf_trim_data(void *bufPtr, char *dstPtr, s32 len) A_MEMCPY(dstPtr, start, len); skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len); - return A_OK; + return 0; } @@ -207,7 +207,7 @@ a_netbuf_pull(void *bufPtr, s32 len) { skb_pull((struct sk_buff *)bufPtr, len); - return A_OK; + return 0; } /* @@ -220,7 +220,7 @@ a_netbuf_pull_data(void *bufPtr, char *dstPtr, s32 len) A_MEMCPY(dstPtr, ((struct sk_buff *)bufPtr)->data, len); skb_pull((struct sk_buff *)bufPtr, len); - return A_OK; + return 0; } #ifdef EXPORT_HCI_BRIDGE_INTERFACE diff --git a/drivers/staging/ath6kl/os/linux/wireless_ext.c b/drivers/staging/ath6kl/os/linux/wireless_ext.c index 6d3ae2ce296d..1f858ca87a01 100644 --- a/drivers/staging/ath6kl/os/linux/wireless_ext.c +++ b/drivers/staging/ath6kl/os/linux/wireless_ext.c @@ -419,7 +419,7 @@ ar6000_ioctl_giwscan(struct net_device *dev, AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); struct ar_giwscan_param param; - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -466,7 +466,7 @@ ar6000_ioctl_siwessid(struct net_device *dev, u8 arNetworkType; u8 prevMode = ar->arNetworkType; - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -642,7 +642,7 @@ ar6000_ioctl_siwessid(struct net_device *dev, ar->arSsidLen = data->length - 1; A_MEMCPY(ar->arSsid, ssid, ar->arSsidLen); - if (ar6000_connect_to_ap(ar)!= A_OK) { + if (ar6000_connect_to_ap(ar)!= 0) { up(&ar->arSem); return -EIO; }else{ @@ -659,7 +659,7 @@ ar6000_ioctl_giwessid(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -715,7 +715,7 @@ ar6000_ioctl_siwrate(struct net_device *dev, u32 kbps; s8 rate_idx; - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -725,7 +725,7 @@ ar6000_ioctl_siwrate(struct net_device *dev, } else { kbps = -1; /* -1 indicates auto rate */ } - if(kbps != -1 && wmi_validate_bitrate(ar->arWmi, kbps, &rate_idx) != A_OK) + if(kbps != -1 && wmi_validate_bitrate(ar->arWmi, kbps, &rate_idx) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BitRate is not Valid %d\n", kbps)); return -EINVAL; @@ -733,7 +733,7 @@ ar6000_ioctl_siwrate(struct net_device *dev, ar->arBitRate = kbps; if(ar->arWmiReady == true) { - if (wmi_set_bitrate_cmd(ar->arWmi, kbps, -1, -1) != A_OK) { + if (wmi_set_bitrate_cmd(ar->arWmi, kbps, -1, -1) != 0) { return -EINVAL; } } @@ -751,7 +751,7 @@ ar6000_ioctl_giwrate(struct net_device *dev, AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); int ret = 0; - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -779,7 +779,7 @@ ar6000_ioctl_giwrate(struct net_device *dev, } ar->arBitRate = 0xFFFF; - if (wmi_get_bitrate_cmd(ar->arWmi) != A_OK) { + if (wmi_get_bitrate_cmd(ar->arWmi) != 0) { up(&ar->arSem); return -EIO; } @@ -814,7 +814,7 @@ ar6000_ioctl_siwtxpow(struct net_device *dev, AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); u8 dbM; - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -856,7 +856,7 @@ ar6000_ioctl_giwtxpow(struct net_device *dev, AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); int ret = 0; - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -882,7 +882,7 @@ ar6000_ioctl_giwtxpow(struct net_device *dev, { ar->arTxPwr = 0; - if (wmi_get_txPwr_cmd(ar->arWmi) != A_OK) { + if (wmi_get_txPwr_cmd(ar->arWmi) != 0) { up(&ar->arSem); return -EIO; } @@ -925,7 +925,7 @@ ar6000_ioctl_siwretry(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -948,7 +948,7 @@ ar6000_ioctl_siwretry(struct net_device *dev, if(ar->arWmiReady == true) { if (wmi_set_retry_limits_cmd(ar->arWmi, DATA_FRAMETYPE, WMM_AC_BE, - rrq->value, 0) != A_OK){ + rrq->value, 0) != 0){ return -EINVAL; } } @@ -966,7 +966,7 @@ ar6000_ioctl_giwretry(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -1009,7 +1009,7 @@ ar6000_ioctl_siwencode(struct net_device *dev, int index; s32 auth = 0; - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -1125,7 +1125,7 @@ ar6000_ioctl_giwencode(struct net_device *dev, u8 keyIndex; struct ar_wep_key *wk; - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -1557,7 +1557,7 @@ ar6000_ioctl_siwpmksa(struct net_device *dev, } ret = 0; - status = A_OK; + status = 0; switch (pmksa->cmd) { case IW_PMKSA_ADD: @@ -1636,7 +1636,7 @@ static int ar6000_set_wapi_key(struct net_device *dev, KEY_OP_INIT_WAPIPN, NULL, SYNC_BEFORE_WMIFLAG); - if (A_OK != status) { + if (0 != status) { return -EIO; } return 0; @@ -1908,7 +1908,7 @@ ar6000_ioctl_giwname(struct net_device *dev, u8 capability; AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -1962,7 +1962,7 @@ ar6000_ioctl_siwfreq(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -2007,7 +2007,7 @@ ar6000_ioctl_giwfreq(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -2047,7 +2047,7 @@ ar6000_ioctl_siwmode(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -2118,7 +2118,7 @@ ar6000_ioctl_giwmode(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -2180,7 +2180,7 @@ ar6000_ioctl_giwrange(struct net_device *dev, struct iw_range *range = (struct iw_range *) extra; int i, ret = 0; - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -2205,7 +2205,7 @@ ar6000_ioctl_giwrange(struct net_device *dev, ar->arNumChannels = -1; A_MEMZERO(ar->arChannelList, sizeof (ar->arChannelList)); - if (wmi_get_channelList_cmd(ar->arWmi) != A_OK) { + if (wmi_get_channelList_cmd(ar->arWmi) != 0) { up(&ar->arSem); return -EIO; } @@ -2301,7 +2301,7 @@ ar6000_ioctl_siwap(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -2333,7 +2333,7 @@ ar6000_ioctl_giwap(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -2369,7 +2369,7 @@ ar6000_ioctl_siwmlme(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -2462,7 +2462,7 @@ ar6000_ioctl_siwscan(struct net_device *dev, AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); int ret = 0; - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } @@ -2487,13 +2487,13 @@ ar6000_ioctl_siwscan(struct net_device *dev, } if (!ar->arUserBssFilter) { - if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != A_OK) { + if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != 0) { return -EIO; } } if (ar->arConnected) { - if (wmi_get_stats_cmd(ar->arWmi) != A_OK) { + if (wmi_get_stats_cmd(ar->arWmi) != 0) { return -EIO; } } @@ -2507,14 +2507,14 @@ ar6000_ioctl_siwscan(struct net_device *dev, struct iw_scan_req req; if (copy_from_user(&req, data->pointer, sizeof(struct iw_scan_req))) return -EIO; - if (wmi_probedSsid_cmd(ar->arWmi, 1, SPECIFIC_SSID_FLAG, req.essid_len, req.essid) != A_OK) + if (wmi_probedSsid_cmd(ar->arWmi, 1, SPECIFIC_SSID_FLAG, req.essid_len, req.essid) != 0) return -EIO; ar->scanSpecificSsid = true; } else { if (ar->scanSpecificSsid) { - if (wmi_probedSsid_cmd(ar->arWmi, 1, DISABLE_SSID_FLAG, 0, NULL) != A_OK) + if (wmi_probedSsid_cmd(ar->arWmi, 1, DISABLE_SSID_FLAG, 0, NULL) != 0) return -EIO; ar->scanSpecificSsid = false; } @@ -2523,7 +2523,7 @@ ar6000_ioctl_siwscan(struct net_device *dev, else { if (ar->scanSpecificSsid) { - if (wmi_probedSsid_cmd(ar->arWmi, 1, DISABLE_SSID_FLAG, 0, NULL) != A_OK) + if (wmi_probedSsid_cmd(ar->arWmi, 1, DISABLE_SSID_FLAG, 0, NULL) != 0) return -EIO; ar->scanSpecificSsid = false; } @@ -2532,7 +2532,7 @@ ar6000_ioctl_siwscan(struct net_device *dev, #endif /* ANDROID_ENV */ if (wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, false, false, \ - 0, 0, 0, NULL) != A_OK) { + 0, 0, 0, NULL) != 0) { ret = -EIO; } @@ -2589,7 +2589,7 @@ ar6000_ioctl_siwcommit(struct net_device *dev, { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); - if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) { + if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); return -EOPNOTSUPP; } diff --git a/drivers/staging/ath6kl/reorder/rcv_aggr.c b/drivers/staging/ath6kl/reorder/rcv_aggr.c index dc1ea558bf32..5cb4413fbd67 100644 --- a/drivers/staging/ath6kl/reorder/rcv_aggr.c +++ b/drivers/staging/ath6kl/reorder/rcv_aggr.c @@ -57,7 +57,7 @@ aggr_init(ALLOC_NETBUFS netbuf_allocator) AGGR_INFO *p_aggr = NULL; RXTID *rxtid; u8 i; - int status = A_OK; + int status = 0; A_PRINTF("In aggr_init..\n"); @@ -90,13 +90,13 @@ aggr_init(ALLOC_NETBUFS netbuf_allocator) }while(false); A_PRINTF("going out of aggr_init..status %s\n", - (status == A_OK) ? "OK":"Error"); + (status == 0) ? "OK":"Error"); if (status) { /* Cleanup */ aggr_module_destroy(p_aggr); } - return ((status == A_OK) ? p_aggr : NULL); + return ((status == 0) ? p_aggr : NULL); } /* utility function to clear rx hold_q for a tid */ @@ -399,7 +399,7 @@ aggr_slice_amsdu(AGGR_INFO *p_aggr, RXTID *rxtid, void **osbuf) A_MEMCPY(A_NETBUF_DATA(new_buf), framep, frame_8023_len); A_NETBUF_PUT(new_buf, frame_8023_len); - if (wmi_dot3_2_dix(new_buf) != A_OK) { + if (wmi_dot3_2_dix(new_buf) != 0) { A_PRINTF("dot3_2_dix err..\n"); A_NETBUF_FREE(new_buf); break; diff --git a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c index fedacd2b2aa5..9ebfecff54f9 100644 --- a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c +++ b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c @@ -196,5 +196,5 @@ wlan_parse_beacon(u8 *buf, int framelen, struct ieee80211_common_ie *cie) IEEE80211_VERIFY_ELEMENT(cie->ie_rates, IEEE80211_RATE_MAXSIZE); IEEE80211_VERIFY_ELEMENT(cie->ie_ssid, IEEE80211_NWID_LEN); - return A_OK; + return 0; } diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index cae1c2face02..242e855f3085 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -416,7 +416,7 @@ wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf) * packet is already in 802.3 format - return success */ A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG)); - return (A_OK); + return (0); } /* @@ -430,7 +430,7 @@ wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf) /* * Make room for LLC+SNAP headers */ - if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) { + if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) { return A_NO_MEMORY; } datap = A_NETBUF_DATA(osbuf); @@ -446,19 +446,19 @@ wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf) llcHdr->orgCode[2] = 0x0; llcHdr->etherType = typeorlen; - return (A_OK); + return (0); } int wmi_meta_add(struct wmi_t *wmip, void *osbuf, u8 *pVersion,void *pTxMetaS) { switch(*pVersion){ case 0: - return (A_OK); + return (0); case WMI_META_VERSION_1: { WMI_TX_META_V1 *pV1= NULL; A_ASSERT(osbuf != NULL); - if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != A_OK) { + if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != 0) { return A_NO_MEMORY; } @@ -473,23 +473,23 @@ int wmi_meta_add(struct wmi_t *wmip, void *osbuf, u8 *pVersion,void *pTxMetaS) A_ASSERT(pVersion != NULL); /* the version must be used to populate the meta field of the WMI_DATA_HDR */ *pVersion = WMI_META_VERSION_1; - return (A_OK); + return (0); } #ifdef CONFIG_CHECKSUM_OFFLOAD case WMI_META_VERSION_2: { WMI_TX_META_V2 *pV2 ; A_ASSERT(osbuf != NULL); - if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != A_OK) { + if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != 0) { return A_NO_MEMORY; } pV2 = (WMI_TX_META_V2 *)A_NETBUF_DATA(osbuf); A_MEMCPY(pV2,(WMI_TX_META_V2 *)pTxMetaS,sizeof(WMI_TX_META_V2)); - return (A_OK); + return (0); } #endif default: - return (A_OK); + return (0); } } @@ -506,11 +506,11 @@ wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, u8 msgType, bool bMoreData, /* adds the meta data field after the wmi data hdr. If metaVersion * is returns 0 then no meta field was added. */ - if ((status = wmi_meta_add(wmip, osbuf, &metaVersion,pTxMetaS)) != A_OK) { + if ((status = wmi_meta_add(wmip, osbuf, &metaVersion,pTxMetaS)) != 0) { return status; } - if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != A_OK) { + if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != 0) { return A_NO_MEMORY; } @@ -527,7 +527,7 @@ wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, u8 msgType, bool bMoreData, WMI_DATA_HDR_SET_META(dtHdr, metaVersion); //dtHdr->rssi = 0; - return (A_OK); + return (0); } @@ -664,7 +664,7 @@ wmi_dot11_hdr_add (struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode) /* * Make room for LLC+SNAP headers */ - if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) { + if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) { return A_NO_MEMORY; } datap = A_NETBUF_DATA(osbuf); @@ -683,7 +683,7 @@ AddDot11Hdr: if (wmip->wmi_is_wmm_enabled) { hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32)); - if (A_NETBUF_PUSH(osbuf, hdrsize) != A_OK) + if (A_NETBUF_PUSH(osbuf, hdrsize) != 0) { return A_NO_MEMORY; } @@ -693,7 +693,7 @@ AddDot11Hdr: else { hdrsize = A_ROUND_UP(sizeof(struct ieee80211_frame),sizeof(u32)); - if (A_NETBUF_PUSH(osbuf, hdrsize) != A_OK) + if (A_NETBUF_PUSH(osbuf, hdrsize) != 0) { return A_NO_MEMORY; } @@ -710,7 +710,7 @@ AddDot11Hdr: IEEE80211_ADDR_COPY(wh->i_addr1, macHdr.dstMac); } - return (A_OK); + return (0); } int @@ -774,7 +774,7 @@ wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf) A_MEMCPY (datap, &macHdr, sizeof(ATH_MAC_HDR)); - return A_OK; + return 0; } /* @@ -795,7 +795,7 @@ wmi_dot3_2_dix(void *osbuf) llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR)); macHdr.typeOrLen = llcHdr->etherType; - if (A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) { + if (A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) { return A_NO_MEMORY; } @@ -803,7 +803,7 @@ wmi_dot3_2_dix(void *osbuf) A_MEMCPY(datap, &macHdr, sizeof (ATH_MAC_HDR)); - return (A_OK); + return (0); } /* @@ -833,7 +833,7 @@ wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf) u16 id; u8 *datap; u32 len; - int status = A_OK; + int status = 0; if (A_NETBUF_LEN(osbuf) < sizeof(WMIX_CMD_HDR)) { A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG)); @@ -844,7 +844,7 @@ wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf) cmd = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf); id = cmd->commandId; - if (A_NETBUF_PULL(osbuf, sizeof(WMIX_CMD_HDR)) != A_OK) { + if (A_NETBUF_PULL(osbuf, sizeof(WMIX_CMD_HDR)) != 0) { A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG)); wmip->wmi_stats.cmd_len_err++; return A_ERROR; @@ -910,7 +910,7 @@ wmi_control_rx(struct wmi_t *wmip, void *osbuf) u16 id; u8 *datap; u32 len, i, loggingReq; - int status = A_OK; + int status = 0; A_ASSERT(osbuf != NULL); if (A_NETBUF_LEN(osbuf) < sizeof(WMI_CMD_HDR)) { @@ -923,7 +923,7 @@ wmi_control_rx(struct wmi_t *wmip, void *osbuf) cmd = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf); id = cmd->commandId; - if (A_NETBUF_PULL(osbuf, sizeof(WMI_CMD_HDR)) != A_OK) { + if (A_NETBUF_PULL(osbuf, sizeof(WMI_CMD_HDR)) != 0) { A_NETBUF_FREE(osbuf); A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG)); wmip->wmi_stats.cmd_len_err++; @@ -1236,7 +1236,7 @@ wmi_ready_event_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_READY_EVENT(wmip->wmi_devt, ev->macaddr, ev->phyCapability, ev->sw_version, ev->abi_version); - return A_OK; + return 0; } #define LE_READ_4(p) \ @@ -1314,7 +1314,7 @@ wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap, int len) ev->assocReqLen, ev->assocRespLen, ev->assocInfo); - return A_OK; + return 0; } static int @@ -1329,7 +1329,7 @@ wmi_regDomain_event_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_REGDOMAIN_EVENT(wmip->wmi_devt, ev->regDomain); - return A_OK; + return 0; } static int @@ -1350,7 +1350,7 @@ wmi_neighborReport_event_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_NEIGHBORREPORT_EVENT(wmip->wmi_devt, numAps, ev->neighbor); - return A_OK; + return 0; } static int @@ -1375,7 +1375,7 @@ wmi_disconnect_event_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_DISCONNECT_EVENT(wmip->wmi_devt, ev->disconnectReason, ev->bssid, ev->assocRespLen, ev->assocInfo, ev->protocolReasonStatus); - return A_OK; + return 0; } static int @@ -1395,7 +1395,7 @@ wmi_peer_node_event_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_PEER_EVENT (wmip->wmi_devt, ev->eventCode, ev->peerMacAddr); - return A_OK; + return 0; } static int @@ -1411,7 +1411,7 @@ wmi_tkip_micerr_event_rx(struct wmi_t *wmip, u8 *datap, int len) ev = (WMI_TKIP_MICERR_EVENT *)datap; A_WMI_TKIP_MICERR_EVENT(wmip->wmi_devt, ev->keyid, ev->ismcast); - return A_OK; + return 0; } static int @@ -1434,7 +1434,7 @@ wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len) if (bih->rssi > 0) { if (NULL == bss) - return A_OK; //no node found in the table, just drop the node with incorrect RSSI + return 0; //no node found in the table, just drop the node with incorrect RSSI else bih->rssi = bss->ni_rssi; //Adjust RSSI in datap in case it is used in A_WMI_BSSINFO_EVENT_RX } @@ -1443,14 +1443,14 @@ wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len) /* What is driver config for wlan node caching? */ if(ar6000_get_driver_cfg(wmip->wmi_devt, AR6000_DRIVER_CFG_GET_WLANNODECACHING, - &nodeCachingAllowed) != A_OK) { + &nodeCachingAllowed) != 0) { wmi_node_return(wmip, bss); return A_EINVAL; } if(!nodeCachingAllowed) { wmi_node_return(wmip, bss); - return A_OK; + return 0; } buf = datap + sizeof(WMI_BSS_INFO_HDR); @@ -1462,7 +1462,7 @@ wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len) if(wps_enable && (bih->frameType == PROBERESP_FTYPE) ) { wmi_node_return(wmip, bss); - return A_OK; + return 0; } if (bss != NULL) { @@ -1563,7 +1563,7 @@ wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len) A_MEMCPY(bss->ni_buf, buf, len); bss->ni_framelen = len; - if (wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie) != A_OK) { + if (wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie) != 0) { wlan_node_free(bss); return A_EINVAL; } @@ -1575,7 +1575,7 @@ wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len) bss->ni_cie.ie_chan = bih->channel; wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid); - return A_OK; + return 0; } static int @@ -1617,7 +1617,7 @@ wmi_opt_frame_event_rx(struct wmi_t *wmip, u8 *datap, int len) A_MEMCPY(bss->ni_buf, buf, len); wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid); - return A_OK; + return 0; } /* This event indicates inactivity timeout of a fatpipe(pstream) @@ -1650,7 +1650,7 @@ wmi_pstream_timeout_event_rx(struct wmi_t *wmip, u8 *datap, int len) /*Indicate inactivity to driver layer for this fatpipe (pstream)*/ A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, ev->trafficClass); - return A_OK; + return 0; } static int @@ -1681,7 +1681,7 @@ wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap, int len) } A_WMI_BITRATE_RX(wmip->wmi_devt, rate); - return A_OK; + return 0; } static int @@ -1698,7 +1698,7 @@ wmi_ratemask_reply_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_RATEMASK_RX(wmip->wmi_devt, reply->fixRateMask); - return A_OK; + return 0; } static int @@ -1715,7 +1715,7 @@ wmi_channelList_reply_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_CHANNELLIST_RX(wmip->wmi_devt, reply->numChannels, reply->channelList); - return A_OK; + return 0; } static int @@ -1731,7 +1731,7 @@ wmi_txPwr_reply_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_TXPWR_RX(wmip->wmi_devt, reply->dbM); - return A_OK; + return 0; } static int wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len) @@ -1746,7 +1746,7 @@ wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_KEEPALIVE_RX(wmip->wmi_devt, reply->configured); - return A_OK; + return 0; } @@ -1767,7 +1767,7 @@ wmi_dset_open_req_rx(struct wmi_t *wmip, u8 *datap, int len) dsetopenreq->targ_reply_fn, dsetopenreq->targ_reply_arg); - return A_OK; + return 0; } #ifdef CONFIG_HOST_DSET_SUPPORT @@ -1784,7 +1784,7 @@ wmi_dset_close_rx(struct wmi_t *wmip, u8 *datap, int len) dsetclose = (WMIX_DSETCLOSE_EVENT *)datap; A_WMI_DSET_CLOSE(wmip->wmi_devt, dsetclose->access_cookie); - return A_OK; + return 0; } static int @@ -1806,7 +1806,7 @@ wmi_dset_data_req_rx(struct wmi_t *wmip, u8 *datap, int len) dsetdatareq->targ_reply_fn, dsetdatareq->targ_reply_arg); - return A_OK; + return 0; } #endif /* CONFIG_HOST_DSET_SUPPORT */ @@ -1816,13 +1816,13 @@ wmi_scanComplete_rx(struct wmi_t *wmip, u8 *datap, int len) WMI_SCAN_COMPLETE_EVENT *ev; ev = (WMI_SCAN_COMPLETE_EVENT *)datap; - if ((int)ev->status == A_OK) { + if ((int)ev->status == 0) { wlan_refresh_inactive_nodes(&wmip->wmi_scan_table); } A_WMI_SCANCOMPLETE_EVENT(wmip->wmi_devt, (int) ev->status); is_probe_ssid = false; - return A_OK; + return 0; } /* @@ -1851,7 +1851,7 @@ wmi_errorEvent_rx(struct wmi_t *wmip, u8 *datap, int len) break; } - return A_OK; + return 0; } @@ -1862,7 +1862,7 @@ wmi_statsEvent_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_TARGETSTATS_EVENT(wmip->wmi_devt, datap, len); - return A_OK; + return 0; } static int @@ -1959,14 +1959,14 @@ wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len) rssi_event_value = rssi; - if (wmi_send_rssi_threshold_params(wmip, &cmd) != A_OK) { + if (wmi_send_rssi_threshold_params(wmip, &cmd) != 0) { A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the RSSI thresholds\n", DBGARG)); } A_WMI_RSSI_THRESHOLD_EVENT(wmip->wmi_devt, newThreshold, reply->rssi); - return A_OK; + return 0; } @@ -1983,7 +1983,7 @@ wmi_reportErrorEvent_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_REPORT_ERROR_EVENT(wmip->wmi_devt, (WMI_TARGET_ERROR_VAL) reply->errorVal); - return A_OK; + return 0; } static int @@ -2053,7 +2053,7 @@ wmi_cac_event_rx(struct wmi_t *wmip, u8 *datap, int len) reply->cac_indication, reply->statusCode, reply->tspecSuggestion); - return A_OK; + return 0; } static int @@ -2070,7 +2070,7 @@ wmi_channel_change_event_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_CHANNEL_CHANGE_EVENT(wmip->wmi_devt, reply->oldChannel, reply->newChannel); - return A_OK; + return 0; } static int @@ -2086,7 +2086,7 @@ wmi_hbChallengeResp_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_HBCHALLENGERESP_EVENT(wmip->wmi_devt, reply->cookie, reply->source); - return A_OK; + return 0; } static int @@ -2102,7 +2102,7 @@ wmi_roam_tbl_event_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_ROAM_TABLE_EVENT(wmip->wmi_devt, reply); - return A_OK; + return 0; } static int @@ -2118,7 +2118,7 @@ wmi_roam_data_event_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_ROAM_DATA_EVENT(wmip->wmi_devt, reply); - return A_OK; + return 0; } static int @@ -2131,7 +2131,7 @@ wmi_txRetryErrEvent_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_TX_RETRY_ERR_EVENT(wmip->wmi_devt); - return A_OK; + return 0; } static int @@ -2218,13 +2218,13 @@ wmi_snrThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len) snr_event_value = snr; - if (wmi_send_snr_threshold_params(wmip, &cmd) != A_OK) { + if (wmi_send_snr_threshold_params(wmip, &cmd) != 0) { A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the SNR thresholds\n", DBGARG)); } A_WMI_SNR_THRESHOLD_EVENT_RX(wmip->wmi_devt, newThreshold, reply->snr); - return A_OK; + return 0; } static int @@ -2242,7 +2242,7 @@ wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len) (WMI_LQ_THRESHOLD_VAL) reply->range, reply->lq); - return A_OK; + return 0; } static int @@ -2283,7 +2283,7 @@ wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len) ap_info_v1->channel)); ap_info_v1++; } - return A_OK; + return 0; } static int @@ -2295,7 +2295,7 @@ wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len) datap += sizeof(dropped); len -= sizeof(dropped); A_WMI_DBGLOG_EVENT(wmip->wmi_devt, dropped, (s8 *)datap, len); - return A_OK; + return 0; } #ifdef CONFIG_HOST_GPIO_SUPPORT @@ -2310,7 +2310,7 @@ wmi_gpio_intr_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_GPIO_INTR_RX(gpio_intr->intr_mask, gpio_intr->input_values); - return A_OK; + return 0; } static int @@ -2324,7 +2324,7 @@ wmi_gpio_data_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_GPIO_DATA_RX(gpio_data->reg_id, gpio_data->value); - return A_OK; + return 0; } static int @@ -2334,7 +2334,7 @@ wmi_gpio_ack_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_GPIO_ACK_RX(); - return A_OK; + return 0; } #endif /* CONFIG_HOST_GPIO_SUPPORT */ @@ -2366,7 +2366,7 @@ wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId, wmi_sync_point(wmip); } - if (A_NETBUF_PUSH(osbuf, sizeof(WMI_CMD_HDR)) != A_OK) { + if (A_NETBUF_PUSH(osbuf, sizeof(WMI_CMD_HDR)) != 0) { A_NETBUF_FREE(osbuf); return A_NO_MEMORY; } @@ -2379,7 +2379,7 @@ wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId, * Only for OPT_TX_CMD, use BE endpoint. */ if (IS_OPT_TX_CMD(cmdId)) { - if ((status=wmi_data_hdr_add(wmip, osbuf, OPT_MSGTYPE, false, false,0,NULL)) != A_OK) { + if ((status=wmi_data_hdr_add(wmip, osbuf, OPT_MSGTYPE, false, false,0,NULL)) != 0) { A_NETBUF_FREE(osbuf); return status; } @@ -2394,7 +2394,7 @@ wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId, */ wmi_sync_point(wmip); } - return (A_OK); + return (0); #undef IS_OPT_TX_CMD } @@ -2404,7 +2404,7 @@ wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId, { WMIX_CMD_HDR *cHdr; - if (A_NETBUF_PUSH(osbuf, sizeof(WMIX_CMD_HDR)) != A_OK) { + if (A_NETBUF_PUSH(osbuf, sizeof(WMIX_CMD_HDR)) != 0) { A_NETBUF_FREE(osbuf); return A_NO_MEMORY; } @@ -3067,7 +3067,7 @@ wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, HTC_ENDPOINT_ID eid) A_ASSERT( eid != wmip->wmi_endpoint_id); A_ASSERT(osbuf != NULL); - if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != A_OK) { + if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != 0) { return A_NO_MEMORY; } @@ -3092,7 +3092,7 @@ wmi_sync_point(struct wmi_t *wmip) WMI_SYNC_CMD *cmd; WMI_DATA_SYNC_BUFS dataSyncBufs[WMM_NUM_AC]; u8 i,numPriStreams=0; - int status = A_OK; + int status = 0; A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); @@ -3528,7 +3528,7 @@ s8 wmi_validate_bitrate(struct wmi_t *wmip, s32 rate, s8 *rate_idx) } *rate_idx = i; - return A_OK; + return 0; } int @@ -3857,7 +3857,7 @@ wmi_get_wow_list_event_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_WOW_LIST_EVENT(wmip->wmi_devt, reply->num_filters, reply); - return A_OK; + return 0; } int wmi_add_wow_pattern_cmd(struct wmi_t *wmip, @@ -4647,7 +4647,7 @@ u8 wmi_get_power_mode_cmd(struct wmi_t *wmip) int wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance) { - int ret = A_OK; + int ret = 0; #define TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF (~0) #define TSPEC_SERVICE_START_TIME_ATHEROS_DEF 0 @@ -4685,7 +4685,7 @@ wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_TCMD_RX_REPORT_EVENT(wmip->wmi_devt, datap, len); - return A_OK; + return 0; } #endif /* CONFIG_HOST_TCMD_SUPPORT*/ @@ -5473,7 +5473,7 @@ wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, u32 len) A_WMI_PMKID_LIST_EVENT(wmip->wmi_devt, reply->numPMKID, reply->pmkidList, reply->bssidList[0]); - return A_OK; + return 0; } @@ -5487,7 +5487,7 @@ wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len) } reply = (WMI_SET_PARAMS_REPLY *)datap; - if (A_OK == reply->status) + if (0 == reply->status) { } @@ -5496,7 +5496,7 @@ wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len) } - return A_OK; + return 0; } @@ -5509,7 +5509,7 @@ wmi_acm_reject_event_rx(struct wmi_t *wmip, u8 *datap, u32 len) ev = (WMI_ACM_REJECT_EVENT *)datap; wmip->wmi_traffic_class = ev->trafficClass; printk("ACM REJECT %d\n",wmip->wmi_traffic_class); - return A_OK; + return 0; } @@ -5549,7 +5549,7 @@ wmi_dset_data_reply(struct wmi_t *wmip, data_reply->targ_reply_arg = targ_reply_arg; data_reply->length = length; - if (status == A_OK) { + if (status == 0) { if (a_copy_from_user(data_reply->buf, user_buf, length)) { A_NETBUF_FREE(osbuf); return A_ERROR; @@ -5658,7 +5658,7 @@ wmi_prof_count_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_PROF_COUNT_RX(prof_data->addr, prof_data->count); - return A_OK; + return 0; } #endif /* CONFIG_TARGET_PROFILE_SUPPORT */ @@ -5992,7 +5992,7 @@ bss_t *wmi_rm_current_bss (struct wmi_t *wmip, u8 *id) int wmi_add_current_bss (struct wmi_t *wmip, u8 *id, bss_t *bss) { wlan_setup_node (&wmip->wmi_scan_table, bss, id); - return A_OK; + return 0; } #ifdef ATH_AR6K_11N_SUPPORT @@ -6003,7 +6003,7 @@ wmi_addba_req_event_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_AGGR_RECV_ADDBA_REQ_EVT(wmip->wmi_devt, cmd); - return A_OK; + return 0; } @@ -6014,7 +6014,7 @@ wmi_addba_resp_event_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_AGGR_RECV_ADDBA_RESP_EVT(wmip->wmi_devt, cmd); - return A_OK; + return 0; } static int @@ -6024,7 +6024,7 @@ wmi_delba_req_event_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_AGGR_RECV_DELBA_REQ_EVT(wmip->wmi_devt, cmd); - return A_OK; + return 0; } int @@ -6034,7 +6034,7 @@ wmi_btcoex_config_event_rx(struct wmi_t *wmip, u8 *datap, int len) A_WMI_BTCOEX_CONFIG_EVENT(wmip->wmi_devt, datap, len); - return A_OK; + return 0; } @@ -6045,7 +6045,7 @@ wmi_btcoex_stats_event_rx(struct wmi_t * wmip,u8 *datap,int len) A_WMI_BTCOEX_STATS_EVENT(wmip->wmi_devt, datap, len); - return A_OK; + return 0; } #endif @@ -6056,7 +6056,7 @@ wmi_hci_event_rx(struct wmi_t *wmip, u8 *datap, int len) WMI_HCI_EVENT *cmd = (WMI_HCI_EVENT *)datap; A_WMI_HCI_EVENT_EVT(wmip->wmi_devt, cmd); - return A_OK; + return 0; } //////////////////////////////////////////////////////////////////////////////// @@ -6216,14 +6216,14 @@ wmi_pspoll_event_rx(struct wmi_t *wmip, u8 *datap, int len) ev = (WMI_PSPOLL_EVENT *)datap; A_WMI_PSPOLL_EVENT(wmip->wmi_devt, ev->aid); - return A_OK; + return 0; } static int wmi_dtimexpiry_event_rx(struct wmi_t *wmip, u8 *datap,int len) { A_WMI_DTIMEXPIRY_EVENT(wmip->wmi_devt); - return A_OK; + return 0; } #ifdef WAPI_ENABLE @@ -6238,7 +6238,7 @@ wmi_wapi_rekey_event_rx(struct wmi_t *wmip, u8 *datap,int len) ev = (u8 *)datap; A_WMI_WAPI_REKEY_EVENT(wmip->wmi_devt, *ev, &ev[1]); - return A_OK; + return 0; } #endif -- cgit v1.2.3 From 5ea74318c68fcb38f02fc2fc920abd37d9a9bc33 Mon Sep 17 00:00:00 2001 From: Ivan Vecera Date: Wed, 2 Feb 2011 04:37:02 +0000 Subject: bna: use device model DMA API Use DMA API as PCI equivalents will be deprecated. Signed-off-by: Ivan Vecera Signed-off-by: David S. Miller --- drivers/net/bna/bnad.c | 108 +++++++++++++++++++++++++------------------------ drivers/net/bna/bnad.h | 2 +- 2 files changed, 57 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index fad912656fe4..9f356d5d0f33 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -126,22 +126,22 @@ bnad_free_all_txbufs(struct bnad *bnad, } unmap_array[unmap_cons].skb = NULL; - pci_unmap_single(bnad->pcidev, - pci_unmap_addr(&unmap_array[unmap_cons], + dma_unmap_single(&bnad->pcidev->dev, + dma_unmap_addr(&unmap_array[unmap_cons], dma_addr), skb_headlen(skb), - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); - pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, 0); + dma_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, 0); if (++unmap_cons >= unmap_q->q_depth) break; for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - pci_unmap_page(bnad->pcidev, - pci_unmap_addr(&unmap_array[unmap_cons], + dma_unmap_page(&bnad->pcidev->dev, + dma_unmap_addr(&unmap_array[unmap_cons], dma_addr), skb_shinfo(skb)->frags[i].size, - PCI_DMA_TODEVICE); - pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, + DMA_TO_DEVICE); + dma_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, 0); if (++unmap_cons >= unmap_q->q_depth) break; @@ -199,23 +199,23 @@ bnad_free_txbufs(struct bnad *bnad, sent_bytes += skb->len; wis -= BNA_TXQ_WI_NEEDED(1 + skb_shinfo(skb)->nr_frags); - pci_unmap_single(bnad->pcidev, - pci_unmap_addr(&unmap_array[unmap_cons], + dma_unmap_single(&bnad->pcidev->dev, + dma_unmap_addr(&unmap_array[unmap_cons], dma_addr), skb_headlen(skb), - PCI_DMA_TODEVICE); - pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, 0); + DMA_TO_DEVICE); + dma_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, 0); BNA_QE_INDX_ADD(unmap_cons, 1, unmap_q->q_depth); prefetch(&unmap_array[unmap_cons + 1]); for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { prefetch(&unmap_array[unmap_cons + 1]); - pci_unmap_page(bnad->pcidev, - pci_unmap_addr(&unmap_array[unmap_cons], + dma_unmap_page(&bnad->pcidev->dev, + dma_unmap_addr(&unmap_array[unmap_cons], dma_addr), skb_shinfo(skb)->frags[i].size, - PCI_DMA_TODEVICE); - pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, + DMA_TO_DEVICE); + dma_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, 0); BNA_QE_INDX_ADD(unmap_cons, 1, unmap_q->q_depth); } @@ -340,19 +340,22 @@ static void bnad_free_all_rxbufs(struct bnad *bnad, struct bna_rcb *rcb) { struct bnad_unmap_q *unmap_q; + struct bnad_skb_unmap *unmap_array; struct sk_buff *skb; int unmap_cons; unmap_q = rcb->unmap_q; + unmap_array = unmap_q->unmap_array; for (unmap_cons = 0; unmap_cons < unmap_q->q_depth; unmap_cons++) { - skb = unmap_q->unmap_array[unmap_cons].skb; + skb = unmap_array[unmap_cons].skb; if (!skb) continue; - unmap_q->unmap_array[unmap_cons].skb = NULL; - pci_unmap_single(bnad->pcidev, pci_unmap_addr(&unmap_q-> - unmap_array[unmap_cons], - dma_addr), rcb->rxq->buffer_size, - PCI_DMA_FROMDEVICE); + unmap_array[unmap_cons].skb = NULL; + dma_unmap_single(&bnad->pcidev->dev, + dma_unmap_addr(&unmap_array[unmap_cons], + dma_addr), + rcb->rxq->buffer_size, + DMA_FROM_DEVICE); dev_kfree_skb(skb); } bnad_reset_rcb(bnad, rcb); @@ -391,9 +394,10 @@ bnad_alloc_n_post_rxbufs(struct bnad *bnad, struct bna_rcb *rcb) skb->dev = bnad->netdev; skb_reserve(skb, NET_IP_ALIGN); unmap_array[unmap_prod].skb = skb; - dma_addr = pci_map_single(bnad->pcidev, skb->data, - rcb->rxq->buffer_size, PCI_DMA_FROMDEVICE); - pci_unmap_addr_set(&unmap_array[unmap_prod], dma_addr, + dma_addr = dma_map_single(&bnad->pcidev->dev, skb->data, + rcb->rxq->buffer_size, + DMA_FROM_DEVICE); + dma_unmap_addr_set(&unmap_array[unmap_prod], dma_addr, dma_addr); BNA_SET_DMA_ADDR(dma_addr, &rxent->host_addr); BNA_QE_INDX_ADD(unmap_prod, 1, unmap_q->q_depth); @@ -434,8 +438,9 @@ bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget) struct bna_rcb *rcb = NULL; unsigned int wi_range, packets = 0, wis = 0; struct bnad_unmap_q *unmap_q; + struct bnad_skb_unmap *unmap_array; struct sk_buff *skb; - u32 flags; + u32 flags, unmap_cons; u32 qid0 = ccb->rcb[0]->rxq->rxq_id; struct bna_pkt_rate *pkt_rt = &ccb->pkt_rate; @@ -456,17 +461,17 @@ bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget) rcb = ccb->rcb[1]; unmap_q = rcb->unmap_q; + unmap_array = unmap_q->unmap_array; + unmap_cons = unmap_q->consumer_index; - skb = unmap_q->unmap_array[unmap_q->consumer_index].skb; + skb = unmap_array[unmap_cons].skb; BUG_ON(!(skb)); - unmap_q->unmap_array[unmap_q->consumer_index].skb = NULL; - pci_unmap_single(bnad->pcidev, - pci_unmap_addr(&unmap_q-> - unmap_array[unmap_q-> - consumer_index], + unmap_array[unmap_cons].skb = NULL; + dma_unmap_single(&bnad->pcidev->dev, + dma_unmap_addr(&unmap_array[unmap_cons], dma_addr), - rcb->rxq->buffer_size, - PCI_DMA_FROMDEVICE); + rcb->rxq->buffer_size, + DMA_FROM_DEVICE); BNA_QE_INDX_ADD(unmap_q->consumer_index, 1, unmap_q->q_depth); /* Should be more efficient ? Performance ? */ @@ -1015,9 +1020,9 @@ bnad_mem_free(struct bnad *bnad, if (mem_info->mem_type == BNA_MEM_T_DMA) { BNA_GET_DMA_ADDR(&(mem_info->mdl[i].dma), dma_pa); - pci_free_consistent(bnad->pcidev, - mem_info->mdl[i].len, - mem_info->mdl[i].kva, dma_pa); + dma_free_coherent(&bnad->pcidev->dev, + mem_info->mdl[i].len, + mem_info->mdl[i].kva, dma_pa); } else kfree(mem_info->mdl[i].kva); } @@ -1047,8 +1052,9 @@ bnad_mem_alloc(struct bnad *bnad, for (i = 0; i < mem_info->num; i++) { mem_info->mdl[i].len = mem_info->len; mem_info->mdl[i].kva = - pci_alloc_consistent(bnad->pcidev, - mem_info->len, &dma_pa); + dma_alloc_coherent(&bnad->pcidev->dev, + mem_info->len, &dma_pa, + GFP_KERNEL); if (mem_info->mdl[i].kva == NULL) goto err_return; @@ -2600,9 +2606,9 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev) unmap_q->unmap_array[unmap_prod].skb = skb; BUG_ON(!(skb_headlen(skb) <= BFI_TX_MAX_DATA_PER_VECTOR)); txqent->vector[vect_id].length = htons(skb_headlen(skb)); - dma_addr = pci_map_single(bnad->pcidev, skb->data, skb_headlen(skb), - PCI_DMA_TODEVICE); - pci_unmap_addr_set(&unmap_q->unmap_array[unmap_prod], dma_addr, + dma_addr = dma_map_single(&bnad->pcidev->dev, skb->data, + skb_headlen(skb), DMA_TO_DEVICE); + dma_unmap_addr_set(&unmap_q->unmap_array[unmap_prod], dma_addr, dma_addr); BNA_SET_DMA_ADDR(dma_addr, &txqent->vector[vect_id].host_addr); @@ -2630,11 +2636,9 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev) BUG_ON(!(size <= BFI_TX_MAX_DATA_PER_VECTOR)); txqent->vector[vect_id].length = htons(size); - dma_addr = - pci_map_page(bnad->pcidev, frag->page, - frag->page_offset, size, - PCI_DMA_TODEVICE); - pci_unmap_addr_set(&unmap_q->unmap_array[unmap_prod], dma_addr, + dma_addr = dma_map_page(&bnad->pcidev->dev, frag->page, + frag->page_offset, size, DMA_TO_DEVICE); + dma_unmap_addr_set(&unmap_q->unmap_array[unmap_prod], dma_addr, dma_addr); BNA_SET_DMA_ADDR(dma_addr, &txqent->vector[vect_id].host_addr); BNA_QE_INDX_ADD(unmap_prod, 1, unmap_q->q_depth); @@ -3022,14 +3026,14 @@ bnad_pci_init(struct bnad *bnad, err = pci_request_regions(pdev, BNAD_NAME); if (err) goto disable_device; - if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && - !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) { + if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) && + !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) { *using_dac = 1; } else { - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); if (err) { - err = pci_set_consistent_dma_mask(pdev, - DMA_BIT_MASK(32)); + err = dma_set_coherent_mask(&pdev->dev, + DMA_BIT_MASK(32)); if (err) goto release_regions; } diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h index 8b1d51557def..a89117fa4970 100644 --- a/drivers/net/bna/bnad.h +++ b/drivers/net/bna/bnad.h @@ -181,7 +181,7 @@ struct bnad_rx_info { /* Unmap queues for Tx / Rx cleanup */ struct bnad_skb_unmap { struct sk_buff *skb; - DECLARE_PCI_UNMAP_ADDR(dma_addr) + DEFINE_DMA_UNMAP_ADDR(dma_addr); }; struct bnad_unmap_q { -- cgit v1.2.3 From e0d5f4c31d4769b8574dfd8c61a1f753f7cfbc2f Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Wed, 2 Feb 2011 22:59:54 -0800 Subject: Input: rotary_encoder - use proper irqflags IORESOURCE_IRQ_* is wrong for irq_request, use the correct IRQF_* instead. Signed-off-by: Alexander Stein Signed-off-by: Dmitry Torokhov --- drivers/input/misc/rotary_encoder.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 1f8e0108962e..7e64d01da2be 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c @@ -176,7 +176,7 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) /* request the IRQs */ err = request_irq(encoder->irq_a, &rotary_encoder_irq, - IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, DRV_NAME, encoder); if (err) { dev_err(&pdev->dev, "unable to request IRQ %d\n", @@ -185,7 +185,7 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) } err = request_irq(encoder->irq_b, &rotary_encoder_irq, - IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, DRV_NAME, encoder); if (err) { dev_err(&pdev->dev, "unable to request IRQ %d\n", -- cgit v1.2.3 From 19e955415398687b79fbf1c072a84c9874b8d576 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Wed, 2 Feb 2011 22:59:54 -0800 Subject: Input: serio - clear pending rescans after sysfs driver rebind When rebinding a serio driver via sysfs drvctl interface it is possible for an interrupt to trigger after the disconnect of the existing driver and before the binding of the new driver. This will cause the serio interrupt handler to queue a rescan event which will disconnect the new driver immediately after it is attached. This change removes pending rescans from the serio event queue after processing the drvctl request but before releasing the serio mutex. Reproduction involves issuing a rebind of device port from psmouse driver to serio_raw driver while generating input to trigger interrupts. Then checking to see if the corresponding i8042/serio4/driver is correctly attached to the serio_raw driver instead of psmouse. Signed-off-by: Duncan Laurie Signed-off-by: Dmitry Torokhov --- drivers/input/serio/serio.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index db5b0bca1a1a..7c38d1fbabf2 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -188,7 +188,8 @@ static void serio_free_event(struct serio_event *event) kfree(event); } -static void serio_remove_duplicate_events(struct serio_event *event) +static void serio_remove_duplicate_events(void *object, + enum serio_event_type type) { struct serio_event *e, *next; unsigned long flags; @@ -196,13 +197,13 @@ static void serio_remove_duplicate_events(struct serio_event *event) spin_lock_irqsave(&serio_event_lock, flags); list_for_each_entry_safe(e, next, &serio_event_list, node) { - if (event->object == e->object) { + if (object == e->object) { /* * If this event is of different type we should not * look further - we only suppress duplicate events * that were sent back-to-back. */ - if (event->type != e->type) + if (type != e->type) break; list_del_init(&e->node); @@ -245,7 +246,7 @@ static void serio_handle_event(struct work_struct *work) break; } - serio_remove_duplicate_events(event); + serio_remove_duplicate_events(event->object, event->type); serio_free_event(event); } @@ -436,10 +437,12 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute * } else if (!strncmp(buf, "rescan", count)) { serio_disconnect_port(serio); serio_find_driver(serio); + serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); } else if ((drv = driver_find(buf, &serio_bus)) != NULL) { serio_disconnect_port(serio); error = serio_bind_driver(serio, to_serio_driver(drv)); put_driver(drv); + serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); } else { error = -EINVAL; } -- cgit v1.2.3 From 7ab7b5adfb923978a2cab7bd3fac9ccf7d21cc3f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 2 Feb 2011 22:59:54 -0800 Subject: Input: sysrq - rework re-inject logic Internally 'disable' the filter when re-injecting Alt-SysRq instead of relying on input core to suppress delivery of injected events to the originating handler. This allows to revert commit 5fdbe44d033d059cc56c2803e6b4dbd8cb4e5e39 which causes problems with existing userspace programs trying to loopback the events via evdev. Reported-by: Kristen Carlson Accardi Cc: stable@kernel.org Signed-off-by: Dmitry Torokhov --- drivers/char/sysrq.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 8e0dd254eb11..81f13958e751 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c @@ -571,6 +571,7 @@ struct sysrq_state { unsigned int alt_use; bool active; bool need_reinject; + bool reinjecting; }; static void sysrq_reinject_alt_sysrq(struct work_struct *work) @@ -581,6 +582,10 @@ static void sysrq_reinject_alt_sysrq(struct work_struct *work) unsigned int alt_code = sysrq->alt_use; if (sysrq->need_reinject) { + /* we do not want the assignment to be reordered */ + sysrq->reinjecting = true; + mb(); + /* Simulate press and release of Alt + SysRq */ input_inject_event(handle, EV_KEY, alt_code, 1); input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1); @@ -589,6 +594,9 @@ static void sysrq_reinject_alt_sysrq(struct work_struct *work) input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0); input_inject_event(handle, EV_KEY, alt_code, 0); input_inject_event(handle, EV_SYN, SYN_REPORT, 1); + + mb(); + sysrq->reinjecting = false; } } @@ -599,6 +607,13 @@ static bool sysrq_filter(struct input_handle *handle, bool was_active = sysrq->active; bool suppress; + /* + * Do not filter anything if we are in the process of re-injecting + * Alt+SysRq combination. + */ + if (sysrq->reinjecting) + return false; + switch (type) { case EV_SYN: @@ -629,7 +644,7 @@ static bool sysrq_filter(struct input_handle *handle, sysrq->alt_use = sysrq->alt; /* * If nothing else will be pressed we'll need - * to * re-inject Alt-SysRq keysroke. + * to re-inject Alt-SysRq keysroke. */ sysrq->need_reinject = true; } -- cgit v1.2.3 From 9ae4345a46bdb148e32a547e89ff29563a11e127 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 2 Feb 2011 23:04:27 -0800 Subject: Revert "Input: do not pass injected events back to the originating handler" This reverts commit 5fdbe44d033d059cc56c2803e6b4dbd8cb4e5e39. Apparently there exist userspace programs that expect to be able to "loop back" and distribute to readers events written into /dev/input/eventX and this change made for the benefit of SysRq handler broke them. Now that SysRq uses alternative method to suppress filtering of the events it re-injects we can safely revert this change. Reported-by: Kristen Carlson Accardi Cc: stable@kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/input/input.c b/drivers/input/input.c index f37da09a5e4c..b8894a059f87 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -76,7 +76,6 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz) * dev->event_lock held and interrupts disabled. */ static void input_pass_event(struct input_dev *dev, - struct input_handler *src_handler, unsigned int type, unsigned int code, int value) { struct input_handler *handler; @@ -95,15 +94,6 @@ static void input_pass_event(struct input_dev *dev, continue; handler = handle->handler; - - /* - * If this is the handler that injected this - * particular event we want to skip it to avoid - * filters firing again and again. - */ - if (handler == src_handler) - continue; - if (!handler->filter) { if (filtered) break; @@ -133,7 +123,7 @@ static void input_repeat_key(unsigned long data) if (test_bit(dev->repeat_key, dev->key) && is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) { - input_pass_event(dev, NULL, EV_KEY, dev->repeat_key, 2); + input_pass_event(dev, EV_KEY, dev->repeat_key, 2); if (dev->sync) { /* @@ -142,7 +132,7 @@ static void input_repeat_key(unsigned long data) * Otherwise assume that the driver will send * SYN_REPORT once it's done. */ - input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); + input_pass_event(dev, EV_SYN, SYN_REPORT, 1); } if (dev->rep[REP_PERIOD]) @@ -175,7 +165,6 @@ static void input_stop_autorepeat(struct input_dev *dev) #define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) static int input_handle_abs_event(struct input_dev *dev, - struct input_handler *src_handler, unsigned int code, int *pval) { bool is_mt_event; @@ -219,15 +208,13 @@ static int input_handle_abs_event(struct input_dev *dev, /* Flush pending "slot" event */ if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { input_abs_set_val(dev, ABS_MT_SLOT, dev->slot); - input_pass_event(dev, src_handler, - EV_ABS, ABS_MT_SLOT, dev->slot); + input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot); } return INPUT_PASS_TO_HANDLERS; } static void input_handle_event(struct input_dev *dev, - struct input_handler *src_handler, unsigned int type, unsigned int code, int value) { int disposition = INPUT_IGNORE_EVENT; @@ -280,8 +267,7 @@ static void input_handle_event(struct input_dev *dev, case EV_ABS: if (is_event_supported(code, dev->absbit, ABS_MAX)) - disposition = input_handle_abs_event(dev, src_handler, - code, &value); + disposition = input_handle_abs_event(dev, code, &value); break; @@ -339,7 +325,7 @@ static void input_handle_event(struct input_dev *dev, dev->event(dev, type, code, value); if (disposition & INPUT_PASS_TO_HANDLERS) - input_pass_event(dev, src_handler, type, code, value); + input_pass_event(dev, type, code, value); } /** @@ -368,7 +354,7 @@ void input_event(struct input_dev *dev, spin_lock_irqsave(&dev->event_lock, flags); add_input_randomness(type, code, value); - input_handle_event(dev, NULL, type, code, value); + input_handle_event(dev, type, code, value); spin_unlock_irqrestore(&dev->event_lock, flags); } } @@ -398,8 +384,7 @@ void input_inject_event(struct input_handle *handle, rcu_read_lock(); grab = rcu_dereference(dev->grab); if (!grab || grab == handle) - input_handle_event(dev, handle->handler, - type, code, value); + input_handle_event(dev, type, code, value); rcu_read_unlock(); spin_unlock_irqrestore(&dev->event_lock, flags); @@ -612,10 +597,10 @@ static void input_dev_release_keys(struct input_dev *dev) for (code = 0; code <= KEY_MAX; code++) { if (is_event_supported(code, dev->keybit, KEY_MAX) && __test_and_clear_bit(code, dev->key)) { - input_pass_event(dev, NULL, EV_KEY, code, 0); + input_pass_event(dev, EV_KEY, code, 0); } } - input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); + input_pass_event(dev, EV_SYN, SYN_REPORT, 1); } } @@ -890,9 +875,9 @@ int input_set_keycode(struct input_dev *dev, !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && __test_and_clear_bit(old_keycode, dev->key)) { - input_pass_event(dev, NULL, EV_KEY, old_keycode, 0); + input_pass_event(dev, EV_KEY, old_keycode, 0); if (dev->sync) - input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); + input_pass_event(dev, EV_SYN, SYN_REPORT, 1); } out: -- cgit v1.2.3 From 940f3be4058e0aff0505fd6f68e29e547e10e552 Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Mon, 17 Jan 2011 13:08:52 +0300 Subject: tty: serial: bfin_sport_uart: fix signedness error sport->port.irq is unsigned, check for <0 doesn't make sense. Explicitly cast it to int to check for error. Signed-off-by: Vasiliy Kulikov Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/bfin_sport_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/bfin_sport_uart.c b/drivers/tty/serial/bfin_sport_uart.c index e95c524d9d18..c3ec0a61d859 100644 --- a/drivers/tty/serial/bfin_sport_uart.c +++ b/drivers/tty/serial/bfin_sport_uart.c @@ -788,7 +788,7 @@ static int __devinit sport_uart_probe(struct platform_device *pdev) sport->port.mapbase = res->start; sport->port.irq = platform_get_irq(pdev, 0); - if (sport->port.irq < 0) { + if ((int)sport->port.irq < 0) { dev_err(&pdev->dev, "No sport RX/TX IRQ specified\n"); ret = -ENOENT; goto out_error_unmap; -- cgit v1.2.3 From a5f4dbf0ae972510faca799a809d3771fab323b7 Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Wed, 12 Jan 2011 15:03:42 +0800 Subject: serial: mfd: remove the timeout workaround for A0 This is kind of a revert for commit 669b7a0938e "hsu: add a periodic timer to check dma rx channel", which is a workaround for a bug in A0 stepping silicon, where a dma rx data timeout is missing for some case. Since new silicon has fixed it and the old version is phasing out, no need to carry on it any more. Signed-off-by: Feng Tang Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mfd.c | 38 -------------------------------------- 1 file changed, 38 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c index d40010a22ecd..776777462937 100644 --- a/drivers/tty/serial/mfd.c +++ b/drivers/tty/serial/mfd.c @@ -51,8 +51,6 @@ #define mfd_readl(obj, offset) readl(obj->reg + offset) #define mfd_writel(obj, offset, val) writel(val, obj->reg + offset) -#define HSU_DMA_TIMEOUT_CHECK_FREQ (HZ/10) - struct hsu_dma_buffer { u8 *buf; dma_addr_t dma_addr; @@ -65,7 +63,6 @@ struct hsu_dma_chan { enum dma_data_direction dirt; struct uart_hsu_port *uport; void __iomem *reg; - struct timer_list rx_timer; /* only needed by RX channel */ }; struct uart_hsu_port { @@ -355,8 +352,6 @@ void hsu_dma_start_rx_chan(struct hsu_dma_chan *rxc, struct hsu_dma_buffer *dbuf | (0x1 << 24) /* timeout bit, see HSU Errata 1 */ ); chan_writel(rxc, HSU_CH_CR, 0x3); - - mod_timer(&rxc->rx_timer, jiffies + HSU_DMA_TIMEOUT_CHECK_FREQ); } /* Protected by spin_lock_irqsave(port->lock) */ @@ -420,7 +415,6 @@ void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts) chan_writel(chan, HSU_CH_CR, 0x3); return; } - del_timer(&chan->rx_timer); dma_sync_single_for_cpu(port->dev, dbuf->dma_addr, dbuf->dma_size, DMA_FROM_DEVICE); @@ -448,8 +442,6 @@ void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts) tty_flip_buffer_push(tty); chan_writel(chan, HSU_CH_CR, 0x3); - chan->rx_timer.expires = jiffies + HSU_DMA_TIMEOUT_CHECK_FREQ; - add_timer(&chan->rx_timer); } @@ -870,8 +862,6 @@ static void serial_hsu_shutdown(struct uart_port *port) container_of(port, struct uart_hsu_port, port); unsigned long flags; - del_timer_sync(&up->rxc->rx_timer); - /* Disable interrupts from this port */ up->ier = 0; serial_out(up, UART_IER, 0); @@ -1343,28 +1333,6 @@ err_disable: return ret; } -static void hsu_dma_rx_timeout(unsigned long data) -{ - struct hsu_dma_chan *chan = (void *)data; - struct uart_hsu_port *up = chan->uport; - struct hsu_dma_buffer *dbuf = &up->rxbuf; - int count = 0; - unsigned long flags; - - spin_lock_irqsave(&up->port.lock, flags); - - count = chan_readl(chan, HSU_CH_D0SAR) - dbuf->dma_addr; - - if (!count) { - mod_timer(&chan->rx_timer, jiffies + HSU_DMA_TIMEOUT_CHECK_FREQ); - goto exit; - } - - hsu_dma_rx(up, 0); -exit: - spin_unlock_irqrestore(&up->port.lock, flags); -} - static void hsu_global_init(void) { struct hsu_port *hsu; @@ -1427,12 +1395,6 @@ static void hsu_global_init(void) dchan->reg = hsu->reg + HSU_DMA_CHANS_REG_OFFSET + i * HSU_DMA_CHANS_REG_LENGTH; - /* Work around for RX */ - if (dchan->dirt == DMA_FROM_DEVICE) { - init_timer(&dchan->rx_timer); - dchan->rx_timer.function = hsu_dma_rx_timeout; - dchan->rx_timer.data = (unsigned long)dchan; - } dchan++; } -- cgit v1.2.3 From 2f1522eccb09188f0008168f75420bc2fedc9cae Mon Sep 17 00:00:00 2001 From: Russ Gorby Date: Wed, 2 Feb 2011 12:56:58 -0800 Subject: serial: ifx6x60: expanded info available from platform data Some platform attributes (e.g. max_hz, use_dma) were being intuited from the modem type. These things should be specified by the platform data. Added max_hz, use_dma to ifx_modem_platform_data definition, replaced is_6160 w/ modem_type, and changed clients accordingly Signed-off-by: Russ Gorby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ifx6x60.c | 33 +++++++++++++++++---------------- drivers/tty/serial/ifx6x60.h | 4 +++- include/linux/spi/ifx_modem.h | 19 ++++++++++++------- 3 files changed, 32 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index ab93763862d5..c42de7152eea 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -8,7 +8,7 @@ * Jan Dumon * * Copyright (C) 2009, 2010 Intel Corp - * Russ Gorby + * Russ Gorby * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -732,7 +732,7 @@ static void ifx_spi_io(unsigned long data) /* * setup dma pointers */ - if (ifx_dev->is_6160) { + if (ifx_dev->use_dma) { ifx_dev->spi_msg.is_dma_mapped = 1; ifx_dev->tx_dma = ifx_dev->tx_bus; ifx_dev->rx_dma = ifx_dev->rx_bus; @@ -960,7 +960,7 @@ static int ifx_spi_spi_probe(struct spi_device *spi) { int ret; int srdy; - struct ifx_modem_platform_data *pl_data = NULL; + struct ifx_modem_platform_data *pl_data; struct ifx_spi_device *ifx_dev; if (saved_ifx_dev) { @@ -968,6 +968,12 @@ static int ifx_spi_spi_probe(struct spi_device *spi) return -ENODEV; } + pl_data = (struct ifx_modem_platform_data *)spi->dev.platform_data; + if (!pl_data) { + dev_err(&spi->dev, "missing platform data!"); + return -ENODEV; + } + /* initialize structure to hold our device variables */ ifx_dev = kzalloc(sizeof(struct ifx_spi_device), GFP_KERNEL); if (!ifx_dev) { @@ -983,7 +989,9 @@ static int ifx_spi_spi_probe(struct spi_device *spi) init_timer(&ifx_dev->spi_timer); ifx_dev->spi_timer.function = ifx_spi_timeout; ifx_dev->spi_timer.data = (unsigned long)ifx_dev; - ifx_dev->is_6160 = pl_data->is_6160; + ifx_dev->modem = pl_data->modem_type; + ifx_dev->use_dma = pl_data->use_dma; + ifx_dev->max_hz = pl_data->max_hz; /* ensure SPI protocol flags are initialized to enable transfer */ ifx_dev->spi_more = 0; @@ -1025,18 +1033,11 @@ static int ifx_spi_spi_probe(struct spi_device *spi) goto error_ret; } - pl_data = (struct ifx_modem_platform_data *)spi->dev.platform_data; - if (pl_data) { - ifx_dev->gpio.reset = pl_data->rst_pmu; - ifx_dev->gpio.po = pl_data->pwr_on; - ifx_dev->gpio.mrdy = pl_data->mrdy; - ifx_dev->gpio.srdy = pl_data->srdy; - ifx_dev->gpio.reset_out = pl_data->rst_out; - } else { - dev_err(&spi->dev, "missing platform data!"); - ret = -ENODEV; - goto error_ret; - } + ifx_dev->gpio.reset = pl_data->rst_pmu; + ifx_dev->gpio.po = pl_data->pwr_on; + ifx_dev->gpio.mrdy = pl_data->mrdy; + ifx_dev->gpio.srdy = pl_data->srdy; + ifx_dev->gpio.reset_out = pl_data->rst_out; dev_info(&spi->dev, "gpios %d, %d, %d, %d, %d", ifx_dev->gpio.reset, ifx_dev->gpio.po, ifx_dev->gpio.mrdy, diff --git a/drivers/tty/serial/ifx6x60.h b/drivers/tty/serial/ifx6x60.h index deb7b8d977dc..0ec39b58ccc4 100644 --- a/drivers/tty/serial/ifx6x60.h +++ b/drivers/tty/serial/ifx6x60.h @@ -88,7 +88,9 @@ struct ifx_spi_device { dma_addr_t rx_dma; dma_addr_t tx_dma; - int is_6160; /* Modem type */ + int modem; /* Modem type */ + int use_dma; /* provide dma-able addrs in SPI msg */ + long max_hz; /* max SPI frequency */ spinlock_t write_lock; int write_pending; diff --git a/include/linux/spi/ifx_modem.h b/include/linux/spi/ifx_modem.h index a68f3b19d112..394fec9e7722 100644 --- a/include/linux/spi/ifx_modem.h +++ b/include/linux/spi/ifx_modem.h @@ -2,13 +2,18 @@ #define LINUX_IFX_MODEM_H struct ifx_modem_platform_data { - unsigned short rst_out; /* modem reset out */ - unsigned short pwr_on; /* power on */ - unsigned short rst_pmu; /* reset modem */ - unsigned short tx_pwr; /* modem power threshold */ - unsigned short srdy; /* SRDY */ - unsigned short mrdy; /* MRDY */ - unsigned short is_6160; /* Modem type */ + unsigned short rst_out; /* modem reset out */ + unsigned short pwr_on; /* power on */ + unsigned short rst_pmu; /* reset modem */ + unsigned short tx_pwr; /* modem power threshold */ + unsigned short srdy; /* SRDY */ + unsigned short mrdy; /* MRDY */ + unsigned char modem_type; /* Modem type */ + unsigned long max_hz; /* max SPI frequency */ + unsigned short use_dma:1; /* spi protocol driver supplies + dma-able addrs */ }; +#define IFX_MODEM_6160 1 +#define IFX_MODEM_6260 2 #endif -- cgit v1.2.3 From 364a6ece62455f669336e50d5b00f14ba650da93 Mon Sep 17 00:00:00 2001 From: Thomas Weber Date: Tue, 1 Feb 2011 08:30:41 +0100 Subject: OMAP: Enable Magic SysRq on serial console ttyOx Magic SysRq key is not working for OMAP on new serial console ttyOx because SUPPORT_SYSRQ is not defined for omap-serial. This patch defines SUPPORT_SYSRQ in omap-serial and enables handling of Magic SysRq character. Further there is an issue of losing first break character. Removing the reset of the lsr_break_flag fixes this issue. Signed-off-by: Thomas Weber Acked-by: Govindraj.R Tested-by: Manjunath G Kondaiah Acked-by: Kevin Hilman Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 7f2f01058789..699b34446a55 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -20,6 +20,10 @@ * this driver as required for the omap-platform. */ +#if defined(CONFIG_SERIAL_OMAP_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + #include #include #include @@ -190,7 +194,6 @@ static inline void receive_chars(struct uart_omap_port *up, int *status) if (up->port.line == up->port.cons->index) { /* Recover the break flag from console xmit */ lsr |= up->lsr_break_flag; - up->lsr_break_flag = 0; } #endif if (lsr & UART_LSR_BI) -- cgit v1.2.3 From ac54cd2bd5b4db4f1c03392d63daf355627ea180 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 2 Feb 2011 16:55:19 -0800 Subject: RTC: Fix rtc driver ioctl specific shortcutting Some RTC drivers enable functionality directly via their ioctl method instead of using the generic ioctl handling code. With the recent virtualization of the RTC layer, its now important that the generic layer always be used. This patch moved the rtc driver ioctl method call to after the generic ioctl processing is done. This allows hardware specific features or ioctls to still function, while relying on the generic code for handling everything else. This patch on its own may more obviously break rtc drivers that implement the alarm irq enablement via their ioctl method instead of implementing the alarm_irq_eanble method. Those drivers will be fixed in a following patch. Additionaly, those drivers are already likely to not be functioning reliably without this patch. CC: Alessandro Zummo CC: Marcelo Roberto Jimenez CC: Thomas Gleixner Reported-by: Marcelo Roberto Jimenez Tested-by: Marcelo Roberto Jimenez Signed-off-by: John Stultz --- drivers/rtc/rtc-dev.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 212b16edafc0..37c3cc1b3dd5 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c @@ -154,19 +154,7 @@ static long rtc_dev_ioctl(struct file *file, if (err) goto done; - /* try the driver's ioctl interface */ - if (ops->ioctl) { - err = ops->ioctl(rtc->dev.parent, cmd, arg); - if (err != -ENOIOCTLCMD) { - mutex_unlock(&rtc->ops_lock); - return err; - } - } - - /* if the driver does not provide the ioctl interface - * or if that particular ioctl was not implemented - * (-ENOIOCTLCMD), we will try to emulate here. - * + /* * Drivers *SHOULD NOT* provide ioctl implementations * for these requests. Instead, provide methods to * support the following code, so that the RTC's main @@ -329,7 +317,12 @@ static long rtc_dev_ioctl(struct file *file, return err; default: - err = -ENOTTY; + /* Finally try the driver's ioctl interface */ + if (ops->ioctl) { + err = ops->ioctl(rtc->dev.parent, cmd, arg); + if (err == -ENOIOCTLCMD) + err = -ENOTTY; + } break; } -- cgit v1.2.3 From 16380c153a69c3784d2afaddfe0a22f353046cf6 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 2 Feb 2011 17:02:41 -0800 Subject: RTC: Convert rtc drivers to use the alarm_irq_enable method Some rtc drivers use the ioctl method instead of the alarm_irq_enable method for enabling alarm interupts. With the new virtualized RTC rework, its important for drivers to use the alarm_irq_enable instead. This patch converts the drivers that use the AIE ioctl method to use the alarm_irq_enable method. Other ioctl cmds are left untouched. I have not been able to test or even compile most of these drivers. Any help to make sure this change is correct would be appreciated! CC: Alessandro Zummo CC: Thomas Gleixner CC: Marcelo Roberto Jimenez Reported-by: Marcelo Roberto Jimenez Tested-by: Marcelo Roberto Jimenez Signed-off-by: John Stultz --- drivers/rtc/rtc-at32ap700x.c | 19 ++++++----------- drivers/rtc/rtc-at91rm9200.c | 20 +++++++++++------- drivers/rtc/rtc-at91sam9.c | 20 ++++++++++++------ drivers/rtc/rtc-bfin.c | 21 +++++++++++-------- drivers/rtc/rtc-ds1286.c | 41 ++++++++++++++++++++---------------- drivers/rtc/rtc-ds1305.c | 43 ++++++++++++-------------------------- drivers/rtc/rtc-ds1307.c | 49 ++++++++++++-------------------------------- drivers/rtc/rtc-ds1374.c | 37 +++++++++------------------------ drivers/rtc/rtc-m41t80.c | 30 ++++++++------------------- drivers/rtc/rtc-m48t59.c | 21 ++++++------------- drivers/rtc/rtc-mrst.c | 31 +++++----------------------- drivers/rtc/rtc-mv.c | 20 +++++++----------- drivers/rtc/rtc-omap.c | 28 +++++++++++++++++-------- drivers/rtc/rtc-rs5c372.c | 48 ++++++++++++++++++++++++++++++------------- drivers/rtc/rtc-sa1100.c | 22 +++++++++++--------- drivers/rtc/rtc-sh.c | 11 ++++++---- drivers/rtc/rtc-test.c | 21 +++---------------- drivers/rtc/rtc-vr41xx.c | 38 ++++++++++++++++------------------ 18 files changed, 223 insertions(+), 297 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-at32ap700x.c b/drivers/rtc/rtc-at32ap700x.c index b2752b6e7a2f..e725d51e773d 100644 --- a/drivers/rtc/rtc-at32ap700x.c +++ b/drivers/rtc/rtc-at32ap700x.c @@ -134,36 +134,29 @@ static int at32_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) return ret; } -static int at32_rtc_ioctl(struct device *dev, unsigned int cmd, - unsigned long arg) +static int at32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct rtc_at32ap700x *rtc = dev_get_drvdata(dev); int ret = 0; spin_lock_irq(&rtc->lock); - switch (cmd) { - case RTC_AIE_ON: + if(enabled) { if (rtc_readl(rtc, VAL) > rtc->alarm_time) { ret = -EINVAL; - break; + goto out; } rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) | RTC_BIT(CTRL_TOPEN)); rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI)); rtc_writel(rtc, IER, RTC_BIT(IER_TOPI)); - break; - case RTC_AIE_OFF: + } else { rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) & ~RTC_BIT(CTRL_TOPEN)); rtc_writel(rtc, IDR, RTC_BIT(IDR_TOPI)); rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI)); - break; - default: - ret = -ENOIOCTLCMD; - break; } - +out: spin_unlock_irq(&rtc->lock); return ret; @@ -195,11 +188,11 @@ static irqreturn_t at32_rtc_interrupt(int irq, void *dev_id) } static struct rtc_class_ops at32_rtc_ops = { - .ioctl = at32_rtc_ioctl, .read_time = at32_rtc_readtime, .set_time = at32_rtc_settime, .read_alarm = at32_rtc_readalarm, .set_alarm = at32_rtc_setalarm, + .alarm_irq_enable = at32_rtc_alarm_irq_enable, }; static int __init at32_rtc_probe(struct platform_device *pdev) diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index bc8bbca9a2e2..26d1cf5d19ae 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c @@ -195,13 +195,6 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd, /* important: scrub old status before enabling IRQs */ switch (cmd) { - case RTC_AIE_OFF: /* alarm off */ - at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); - break; - case RTC_AIE_ON: /* alarm on */ - at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM); - at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); - break; case RTC_UIE_OFF: /* update off */ at91_sys_write(AT91_RTC_IDR, AT91_RTC_SECEV); break; @@ -217,6 +210,18 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd, return ret; } +static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + pr_debug("%s(): cmd=%08x\n", __func__, enabled); + + if (enabled) { + at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM); + at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); + } else + at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); + + return 0; +} /* * Provide additional RTC information in /proc/driver/rtc */ @@ -270,6 +275,7 @@ static const struct rtc_class_ops at91_rtc_ops = { .read_alarm = at91_rtc_readalarm, .set_alarm = at91_rtc_setalarm, .proc = at91_rtc_proc, + .alarm_irq_enable = at91_rtc_alarm_irq_enable, }; /* diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index f677e0710ca1..c36749e4c926 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -229,12 +229,6 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd, dev_dbg(dev, "ioctl: cmd=%08x, arg=%08lx, mr %08x\n", cmd, arg, mr); switch (cmd) { - case RTC_AIE_OFF: /* alarm off */ - rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN); - break; - case RTC_AIE_ON: /* alarm on */ - rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN); - break; case RTC_UIE_OFF: /* update off */ rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); break; @@ -249,6 +243,19 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd, return ret; } +static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + struct sam9_rtc *rtc = dev_get_drvdata(dev); + u32 mr = rtt_readl(rtc, MR); + + dev_dbg(dev, "alarm_irq_enable: enabled=%08x, mr %08x\n", enabled, mr); + if (enabled) + rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN); + else + rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN); + return 0; +} + /* * Provide additional RTC information in /proc/driver/rtc */ @@ -302,6 +309,7 @@ static const struct rtc_class_ops at91_rtc_ops = { .read_alarm = at91_rtc_readalarm, .set_alarm = at91_rtc_setalarm, .proc = at91_rtc_proc, + .alarm_irq_enabled = at91_rtc_alarm_irq_enable, }; /* diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index b4b6087f2234..17971d93354d 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c @@ -259,15 +259,6 @@ static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long ar bfin_rtc_int_clear(~RTC_ISTAT_SEC); break; - case RTC_AIE_ON: - dev_dbg_stamp(dev); - bfin_rtc_int_set_alarm(rtc); - break; - case RTC_AIE_OFF: - dev_dbg_stamp(dev); - bfin_rtc_int_clear(~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); - break; - default: dev_dbg_stamp(dev); ret = -ENOIOCTLCMD; @@ -276,6 +267,17 @@ static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long ar return ret; } +static int bfin_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + struct bfin_rtc *rtc = dev_get_drvdata(dev); + + dev_dbg_stamp(dev); + if (enabled) + bfin_rtc_int_set_alarm(rtc); + else + bfin_rtc_int_clear(~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); +} + static int bfin_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct bfin_rtc *rtc = dev_get_drvdata(dev); @@ -362,6 +364,7 @@ static struct rtc_class_ops bfin_rtc_ops = { .read_alarm = bfin_rtc_read_alarm, .set_alarm = bfin_rtc_set_alarm, .proc = bfin_rtc_proc, + .alarm_irq_enable = bfin_rtc_alarm_irq_enable, }; static int __devinit bfin_rtc_probe(struct platform_device *pdev) diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c index bf430f9091ed..60ce69600828 100644 --- a/drivers/rtc/rtc-ds1286.c +++ b/drivers/rtc/rtc-ds1286.c @@ -40,6 +40,26 @@ static inline void ds1286_rtc_write(struct ds1286_priv *priv, u8 data, int reg) __raw_writel(data, &priv->rtcregs[reg]); } + +static int ds1286_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + struct ds1286_priv *priv = dev_get_drvdata(dev); + unsigned long flags; + unsigned char val; + + /* Allow or mask alarm interrupts */ + spin_lock_irqsave(&priv->lock, flags); + val = ds1286_rtc_read(priv, RTC_CMD); + if (enabled) + val &= ~RTC_TDM; + else + val |= RTC_TDM; + ds1286_rtc_write(priv, val, RTC_CMD); + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + #ifdef CONFIG_RTC_INTF_DEV static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) @@ -49,22 +69,6 @@ static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) unsigned char val; switch (cmd) { - case RTC_AIE_OFF: - /* Mask alarm int. enab. bit */ - spin_lock_irqsave(&priv->lock, flags); - val = ds1286_rtc_read(priv, RTC_CMD); - val |= RTC_TDM; - ds1286_rtc_write(priv, val, RTC_CMD); - spin_unlock_irqrestore(&priv->lock, flags); - break; - case RTC_AIE_ON: - /* Allow alarm interrupts. */ - spin_lock_irqsave(&priv->lock, flags); - val = ds1286_rtc_read(priv, RTC_CMD); - val &= ~RTC_TDM; - ds1286_rtc_write(priv, val, RTC_CMD); - spin_unlock_irqrestore(&priv->lock, flags); - break; case RTC_WIE_OFF: /* Mask watchdog int. enab. bit */ spin_lock_irqsave(&priv->lock, flags); @@ -316,12 +320,13 @@ static int ds1286_set_alarm(struct device *dev, struct rtc_wkalrm *alm) } static const struct rtc_class_ops ds1286_ops = { - .ioctl = ds1286_ioctl, - .proc = ds1286_proc, + .ioctl = ds1286_ioctl, + .proc = ds1286_proc, .read_time = ds1286_read_time, .set_time = ds1286_set_time, .read_alarm = ds1286_read_alarm, .set_alarm = ds1286_set_alarm, + .alarm_irq_enable = ds1286_alarm_irq_enable, }; static int __devinit ds1286_probe(struct platform_device *pdev) diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 077af1d7b9e4..57fbcc149ba7 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -139,49 +139,32 @@ static u8 hour2bcd(bool hr12, int hour) * Interface to RTC framework */ -#ifdef CONFIG_RTC_INTF_DEV - -/* - * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl) - */ -static int ds1305_ioctl(struct device *dev, unsigned cmd, unsigned long arg) +static int ds1305_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct ds1305 *ds1305 = dev_get_drvdata(dev); u8 buf[2]; - int status = -ENOIOCTLCMD; + long err = -EINVAL; buf[0] = DS1305_WRITE | DS1305_CONTROL; buf[1] = ds1305->ctrl[0]; - switch (cmd) { - case RTC_AIE_OFF: - status = 0; - if (!(buf[1] & DS1305_AEI0)) - goto done; - buf[1] &= ~DS1305_AEI0; - break; - - case RTC_AIE_ON: - status = 0; + if (enabled) { if (ds1305->ctrl[0] & DS1305_AEI0) goto done; buf[1] |= DS1305_AEI0; - break; - } - if (status == 0) { - status = spi_write_then_read(ds1305->spi, buf, sizeof buf, - NULL, 0); - if (status >= 0) - ds1305->ctrl[0] = buf[1]; + } else { + if (!(buf[1] & DS1305_AEI0)) + goto done; + buf[1] &= ~DS1305_AEI0; } - + err = spi_write_then_read(ds1305->spi, buf, sizeof buf, NULL, 0); + if (err >= 0) + ds1305->ctrl[0] = buf[1]; done: - return status; + return err; + } -#else -#define ds1305_ioctl NULL -#endif /* * Get/set of date and time is pretty normal. @@ -460,12 +443,12 @@ done: #endif static const struct rtc_class_ops ds1305_ops = { - .ioctl = ds1305_ioctl, .read_time = ds1305_get_time, .set_time = ds1305_set_time, .read_alarm = ds1305_get_alarm, .set_alarm = ds1305_set_alarm, .proc = ds1305_proc, + .alarm_irq_enable = ds1305_alarm_irq_enable, }; static void ds1305_work(struct work_struct *work) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 0d559b6416dd..4724ba3acf1a 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -495,50 +495,27 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t) return 0; } -static int ds1307_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) +static int ds1307_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct i2c_client *client = to_i2c_client(dev); struct ds1307 *ds1307 = i2c_get_clientdata(client); int ret; - switch (cmd) { - case RTC_AIE_OFF: - if (!test_bit(HAS_ALARM, &ds1307->flags)) - return -ENOTTY; - - ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); - if (ret < 0) - return ret; - - ret &= ~DS1337_BIT_A1IE; - - ret = i2c_smbus_write_byte_data(client, - DS1337_REG_CONTROL, ret); - if (ret < 0) - return ret; - - break; - - case RTC_AIE_ON: - if (!test_bit(HAS_ALARM, &ds1307->flags)) - return -ENOTTY; + if (!test_bit(HAS_ALARM, &ds1307->flags)) + return -ENOTTY; - ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); - if (ret < 0) - return ret; + ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); + if (ret < 0) + return ret; + if (enabled) ret |= DS1337_BIT_A1IE; + else + ret &= ~DS1337_BIT_A1IE; - ret = i2c_smbus_write_byte_data(client, - DS1337_REG_CONTROL, ret); - if (ret < 0) - return ret; - - break; - - default: - return -ENOIOCTLCMD; - } + ret = i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, ret); + if (ret < 0) + return ret; return 0; } @@ -548,7 +525,7 @@ static const struct rtc_class_ops ds13xx_rtc_ops = { .set_time = ds1307_set_time, .read_alarm = ds1337_read_alarm, .set_alarm = ds1337_set_alarm, - .ioctl = ds1307_ioctl, + .alarm_irq_enable = ds1307_alarm_irq_enable, }; /*----------------------------------------------------------------------*/ diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 47fb6357c346..d834a63ec4b0 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -307,42 +307,25 @@ unlock: mutex_unlock(&ds1374->mutex); } -static int ds1374_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) +static int ds1374_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct i2c_client *client = to_i2c_client(dev); struct ds1374 *ds1374 = i2c_get_clientdata(client); - int ret = -ENOIOCTLCMD; + int ret; mutex_lock(&ds1374->mutex); - switch (cmd) { - case RTC_AIE_OFF: - ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR); - if (ret < 0) - goto out; - - ret &= ~DS1374_REG_CR_WACE; - - ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret); - if (ret < 0) - goto out; - - break; - - case RTC_AIE_ON: - ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR); - if (ret < 0) - goto out; + ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR); + if (ret < 0) + goto out; + if (enabled) { ret |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE; ret &= ~DS1374_REG_CR_WDALM; - - ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret); - if (ret < 0) - goto out; - - break; + } else { + ret &= ~DS1374_REG_CR_WACE; } + ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret); out: mutex_unlock(&ds1374->mutex); @@ -354,7 +337,7 @@ static const struct rtc_class_ops ds1374_rtc_ops = { .set_time = ds1374_set_time, .read_alarm = ds1374_read_alarm, .set_alarm = ds1374_set_alarm, - .ioctl = ds1374_ioctl, + .alarm_irq_enable = ds1374_alarm_irq_enable, }; static int ds1374_probe(struct i2c_client *client, diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 5a8daa358066..69fe664a2228 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -213,41 +213,27 @@ static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm) return m41t80_set_datetime(to_i2c_client(dev), tm); } -#if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE) -static int -m41t80_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) +static int m41t80_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct i2c_client *client = to_i2c_client(dev); int rc; - switch (cmd) { - case RTC_AIE_OFF: - case RTC_AIE_ON: - break; - default: - return -ENOIOCTLCMD; - } - rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON); if (rc < 0) goto err; - switch (cmd) { - case RTC_AIE_OFF: - rc &= ~M41T80_ALMON_AFE; - break; - case RTC_AIE_ON: + + if (enabled) rc |= M41T80_ALMON_AFE; - break; - } + else + rc &= ~M41T80_ALMON_AFE; + if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, rc) < 0) goto err; + return 0; err: return -EIO; } -#else -#define m41t80_rtc_ioctl NULL -#endif static int m41t80_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t) { @@ -374,7 +360,7 @@ static struct rtc_class_ops m41t80_rtc_ops = { .read_alarm = m41t80_rtc_read_alarm, .set_alarm = m41t80_rtc_set_alarm, .proc = m41t80_rtc_proc, - .ioctl = m41t80_rtc_ioctl, + .alarm_irq_enable = m41t80_rtc_alarm_irq_enable, }; #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index a99a0b554eb8..3978f4caf724 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c @@ -263,30 +263,21 @@ static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) /* * Handle commands from user-space */ -static int m48t59_rtc_ioctl(struct device *dev, unsigned int cmd, - unsigned long arg) +static int m48t59_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct platform_device *pdev = to_platform_device(dev); struct m48t59_plat_data *pdata = pdev->dev.platform_data; struct m48t59_private *m48t59 = platform_get_drvdata(pdev); unsigned long flags; - int ret = 0; spin_lock_irqsave(&m48t59->lock, flags); - switch (cmd) { - case RTC_AIE_OFF: /* alarm interrupt off */ - M48T59_WRITE(0x00, M48T59_INTR); - break; - case RTC_AIE_ON: /* alarm interrupt on */ + if (enabled) M48T59_WRITE(M48T59_INTR_AFE, M48T59_INTR); - break; - default: - ret = -ENOIOCTLCMD; - break; - } + else + M48T59_WRITE(0x00, M48T59_INTR); spin_unlock_irqrestore(&m48t59->lock, flags); - return ret; + return 0; } static int m48t59_rtc_proc(struct device *dev, struct seq_file *seq) @@ -330,12 +321,12 @@ static irqreturn_t m48t59_rtc_interrupt(int irq, void *dev_id) } static const struct rtc_class_ops m48t59_rtc_ops = { - .ioctl = m48t59_rtc_ioctl, .read_time = m48t59_rtc_read_time, .set_time = m48t59_rtc_set_time, .read_alarm = m48t59_rtc_readalarm, .set_alarm = m48t59_rtc_setalarm, .proc = m48t59_rtc_proc, + .alarm_irq_enable = m48t59_rtc_alarm_irq_enable, }; static const struct rtc_class_ops m48t02_rtc_ops = { diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c index bcd0cf63eb16..1db62db8469d 100644 --- a/drivers/rtc/rtc-mrst.c +++ b/drivers/rtc/rtc-mrst.c @@ -255,42 +255,21 @@ static int mrst_irq_set_state(struct device *dev, int enabled) return 0; } -#if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE) - /* Currently, the vRTC doesn't support UIE ON/OFF */ -static int -mrst_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) +static int mrst_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct mrst_rtc *mrst = dev_get_drvdata(dev); unsigned long flags; - switch (cmd) { - case RTC_AIE_OFF: - case RTC_AIE_ON: - if (!mrst->irq) - return -EINVAL; - break; - default: - /* PIE ON/OFF is handled by mrst_irq_set_state() */ - return -ENOIOCTLCMD; - } - spin_lock_irqsave(&rtc_lock, flags); - switch (cmd) { - case RTC_AIE_OFF: /* alarm off */ - mrst_irq_disable(mrst, RTC_AIE); - break; - case RTC_AIE_ON: /* alarm on */ + if (enabled) mrst_irq_enable(mrst, RTC_AIE); - break; - } + else + mrst_irq_disable(mrst, RTC_AIE); spin_unlock_irqrestore(&rtc_lock, flags); return 0; } -#else -#define mrst_rtc_ioctl NULL -#endif #if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE) @@ -317,13 +296,13 @@ static int mrst_procfs(struct device *dev, struct seq_file *seq) #endif static const struct rtc_class_ops mrst_rtc_ops = { - .ioctl = mrst_rtc_ioctl, .read_time = mrst_read_time, .set_time = mrst_set_time, .read_alarm = mrst_read_alarm, .set_alarm = mrst_set_alarm, .proc = mrst_procfs, .irq_set_state = mrst_irq_set_state, + .alarm_irq_enable = mrst_rtc_alarm_irq_enable, }; static struct mrst_rtc mrst_rtc; diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c index bcca47298554..60627a764514 100644 --- a/drivers/rtc/rtc-mv.c +++ b/drivers/rtc/rtc-mv.c @@ -169,25 +169,19 @@ static int mv_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) return 0; } -static int mv_rtc_ioctl(struct device *dev, unsigned int cmd, - unsigned long arg) +static int mv_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = platform_get_drvdata(pdev); void __iomem *ioaddr = pdata->ioaddr; if (pdata->irq < 0) - return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ - switch (cmd) { - case RTC_AIE_OFF: - writel(0, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS); - break; - case RTC_AIE_ON: + return -EINVAL; /* fall back into rtc-dev's emulation */ + + if (enabled) writel(1, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS); - break; - default: - return -ENOIOCTLCMD; - } + else + writel(0, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS); return 0; } @@ -216,7 +210,7 @@ static const struct rtc_class_ops mv_rtc_alarm_ops = { .set_time = mv_rtc_set_time, .read_alarm = mv_rtc_read_alarm, .set_alarm = mv_rtc_set_alarm, - .ioctl = mv_rtc_ioctl, + .alarm_irq_enable = mv_rtc_alarm_irq_enable, }; static int __devinit mv_rtc_probe(struct platform_device *pdev) diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index e72b523c79a5..b4dbf3a319b3 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -143,8 +143,6 @@ omap_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) u8 reg; switch (cmd) { - case RTC_AIE_OFF: - case RTC_AIE_ON: case RTC_UIE_OFF: case RTC_UIE_ON: break; @@ -156,13 +154,6 @@ omap_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) rtc_wait_not_busy(); reg = rtc_read(OMAP_RTC_INTERRUPTS_REG); switch (cmd) { - /* AIE = Alarm Interrupt Enable */ - case RTC_AIE_OFF: - reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM; - break; - case RTC_AIE_ON: - reg |= OMAP_RTC_INTERRUPTS_IT_ALARM; - break; /* UIE = Update Interrupt Enable (1/second) */ case RTC_UIE_OFF: reg &= ~OMAP_RTC_INTERRUPTS_IT_TIMER; @@ -182,6 +173,24 @@ omap_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) #define omap_rtc_ioctl NULL #endif +static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + u8 reg; + + local_irq_disable(); + rtc_wait_not_busy(); + reg = rtc_read(OMAP_RTC_INTERRUPTS_REG); + if (enabled) + reg |= OMAP_RTC_INTERRUPTS_IT_ALARM; + else + reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM; + rtc_wait_not_busy(); + rtc_write(reg, OMAP_RTC_INTERRUPTS_REG); + local_irq_enable(); + + return 0; +} + /* this hardware doesn't support "don't care" alarm fields */ static int tm2bcd(struct rtc_time *tm) { @@ -309,6 +318,7 @@ static struct rtc_class_ops omap_rtc_ops = { .set_time = omap_rtc_set_time, .read_alarm = omap_rtc_read_alarm, .set_alarm = omap_rtc_set_alarm, + .alarm_irq_enable = omap_rtc_alarm_irq_enable, }; static int omap_rtc_alarm; diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index dd14e202c2c8..6aaa1550e3b1 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -299,14 +299,6 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) if (rs5c->type == rtc_rs5c372a && (buf & RS5C372A_CTRL1_SL1)) return -ENOIOCTLCMD; - case RTC_AIE_OFF: - case RTC_AIE_ON: - /* these irq management calls only make sense for chips - * which are wired up to an IRQ. - */ - if (!rs5c->has_irq) - return -ENOIOCTLCMD; - break; default: return -ENOIOCTLCMD; } @@ -317,12 +309,6 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) addr = RS5C_ADDR(RS5C_REG_CTRL1); switch (cmd) { - case RTC_AIE_OFF: /* alarm off */ - buf &= ~RS5C_CTRL1_AALE; - break; - case RTC_AIE_ON: /* alarm on */ - buf |= RS5C_CTRL1_AALE; - break; case RTC_UIE_OFF: /* update off */ buf &= ~RS5C_CTRL1_CT_MASK; break; @@ -347,6 +333,39 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) #endif +static int rs5c_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + struct i2c_client *client = to_i2c_client(dev); + struct rs5c372 *rs5c = i2c_get_clientdata(client); + unsigned char buf; + int status, addr; + + buf = rs5c->regs[RS5C_REG_CTRL1]; + + if (!rs5c->has_irq) + return -EINVAL; + + status = rs5c_get_regs(rs5c); + if (status < 0) + return status; + + addr = RS5C_ADDR(RS5C_REG_CTRL1); + if (enabled) + buf |= RS5C_CTRL1_AALE; + else + buf &= ~RS5C_CTRL1_AALE; + + if (i2c_smbus_write_byte_data(client, addr, buf) < 0) { + printk(KERN_WARNING "%s: can't update alarm\n", + rs5c->rtc->name); + status = -EIO; + } else + rs5c->regs[RS5C_REG_CTRL1] = buf; + + return status; +} + + /* NOTE: Since RTC_WKALM_{RD,SET} were originally defined for EFI, * which only exposes a polled programming interface; and since * these calls map directly to those EFI requests; we don't demand @@ -466,6 +485,7 @@ static const struct rtc_class_ops rs5c372_rtc_ops = { .set_time = rs5c372_rtc_set_time, .read_alarm = rs5c_read_alarm, .set_alarm = rs5c_set_alarm, + .alarm_irq_enable = rs5c_rtc_alarm_irq_enable, }; #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 88ea52b8647a..5dfe5ffcb0d3 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c @@ -314,16 +314,6 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { switch (cmd) { - case RTC_AIE_OFF: - spin_lock_irq(&sa1100_rtc_lock); - RTSR &= ~RTSR_ALE; - spin_unlock_irq(&sa1100_rtc_lock); - return 0; - case RTC_AIE_ON: - spin_lock_irq(&sa1100_rtc_lock); - RTSR |= RTSR_ALE; - spin_unlock_irq(&sa1100_rtc_lock); - return 0; case RTC_UIE_OFF: spin_lock_irq(&sa1100_rtc_lock); RTSR &= ~RTSR_HZE; @@ -338,6 +328,17 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, return -ENOIOCTLCMD; } +static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + spin_lock_irq(&sa1100_rtc_lock); + if (enabled) + RTSR |= RTSR_ALE; + else + RTSR &= ~RTSR_ALE; + spin_unlock_irq(&sa1100_rtc_lock); + return 0; +} + static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) { rtc_time_to_tm(RCNR, tm); @@ -410,6 +411,7 @@ static const struct rtc_class_ops sa1100_rtc_ops = { .proc = sa1100_rtc_proc, .irq_set_freq = sa1100_irq_set_freq, .irq_set_state = sa1100_irq_set_state, + .alarm_irq_enable = sa1100_rtc_alarm_irq_enable, }; static int sa1100_rtc_probe(struct platform_device *pdev) diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 06e41ed93230..93314a9e7fa9 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -350,10 +350,6 @@ static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) unsigned int ret = 0; switch (cmd) { - case RTC_AIE_OFF: - case RTC_AIE_ON: - sh_rtc_setaie(dev, cmd == RTC_AIE_ON); - break; case RTC_UIE_OFF: rtc->periodic_freq &= ~PF_OXS; sh_rtc_setcie(dev, 0); @@ -369,6 +365,12 @@ static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) return ret; } +static int sh_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + sh_rtc_setaie(dev, enabled); + return 0; +} + static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct platform_device *pdev = to_platform_device(dev); @@ -604,6 +606,7 @@ static struct rtc_class_ops sh_rtc_ops = { .irq_set_state = sh_rtc_irq_set_state, .irq_set_freq = sh_rtc_irq_set_freq, .proc = sh_rtc_proc, + .alarm_irq_enable = sh_rtc_alarm_irq_enable, }; static int __init sh_rtc_probe(struct platform_device *pdev) diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index 51725f7755b0..a82d6fe97076 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c @@ -50,24 +50,9 @@ static int test_rtc_proc(struct device *dev, struct seq_file *seq) return 0; } -static int test_rtc_ioctl(struct device *dev, unsigned int cmd, - unsigned long arg) +static int test_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) { - /* We do support interrupts, they're generated - * using the sysfs interface. - */ - switch (cmd) { - case RTC_PIE_ON: - case RTC_PIE_OFF: - case RTC_UIE_ON: - case RTC_UIE_OFF: - case RTC_AIE_ON: - case RTC_AIE_OFF: - return 0; - - default: - return -ENOIOCTLCMD; - } + return 0; } static const struct rtc_class_ops test_rtc_ops = { @@ -76,7 +61,7 @@ static const struct rtc_class_ops test_rtc_ops = { .read_alarm = test_rtc_read_alarm, .set_alarm = test_rtc_set_alarm, .set_mmss = test_rtc_set_mmss, - .ioctl = test_rtc_ioctl, + .alarm_irq_enable = test_rtc_alarm_irq_enable, }; static ssize_t test_irq_show(struct device *dev, diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index c3244244e8cf..769190ac6d11 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c @@ -240,26 +240,6 @@ static int vr41xx_rtc_irq_set_state(struct device *dev, int enabled) static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { switch (cmd) { - case RTC_AIE_ON: - spin_lock_irq(&rtc_lock); - - if (!alarm_enabled) { - enable_irq(aie_irq); - alarm_enabled = 1; - } - - spin_unlock_irq(&rtc_lock); - break; - case RTC_AIE_OFF: - spin_lock_irq(&rtc_lock); - - if (alarm_enabled) { - disable_irq(aie_irq); - alarm_enabled = 0; - } - - spin_unlock_irq(&rtc_lock); - break; case RTC_EPOCH_READ: return put_user(epoch, (unsigned long __user *)arg); case RTC_EPOCH_SET: @@ -275,6 +255,24 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long return 0; } +static int vr41xx_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + spin_lock_irq(&rtc_lock); + if (enabled) { + if (!alarm_enabled) { + enable_irq(aie_irq); + alarm_enabled = 1; + } + } else { + if (alarm_enabled) { + disable_irq(aie_irq); + alarm_enabled = 0; + } + } + spin_unlock_irq(&rtc_lock); + return 0; +} + static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id) { struct platform_device *pdev = (struct platform_device *)dev_id; -- cgit v1.2.3 From d8ce1481ee8770ef2314eb7984a2228dbf64ad06 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 2 Feb 2011 17:53:42 -0800 Subject: RTC: Fix minor compile warning Two rtc drivers return values from void functions. This patch fixes that. CC: Thomas Gleixner CC: Alessandro Zummo CC: Marcelo Roberto Jimenez Signed-off-by: John Stultz --- drivers/rtc/rtc-msm6242.c | 2 +- drivers/rtc/rtc-rp5c01.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-msm6242.c b/drivers/rtc/rtc-msm6242.c index b2fff0ca49f8..67820626e18f 100644 --- a/drivers/rtc/rtc-msm6242.c +++ b/drivers/rtc/rtc-msm6242.c @@ -82,7 +82,7 @@ static inline unsigned int msm6242_read(struct msm6242_priv *priv, static inline void msm6242_write(struct msm6242_priv *priv, unsigned int val, unsigned int reg) { - return __raw_writel(val, &priv->regs[reg]); + __raw_writel(val, &priv->regs[reg]); } static inline void msm6242_set(struct msm6242_priv *priv, unsigned int val, diff --git a/drivers/rtc/rtc-rp5c01.c b/drivers/rtc/rtc-rp5c01.c index 36eb66184461..694da39b6dd2 100644 --- a/drivers/rtc/rtc-rp5c01.c +++ b/drivers/rtc/rtc-rp5c01.c @@ -76,7 +76,7 @@ static inline unsigned int rp5c01_read(struct rp5c01_priv *priv, static inline void rp5c01_write(struct rp5c01_priv *priv, unsigned int val, unsigned int reg) { - return __raw_writel(val, &priv->regs[reg]); + __raw_writel(val, &priv->regs[reg]); } static void rp5c01_lock(struct rp5c01_priv *priv) -- cgit v1.2.3 From 16f775befc1ccf67e6b223c4d9bb17ac3502ab2c Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Fri, 21 Jan 2011 22:44:48 +0200 Subject: libertas_spi: Use workqueue in hw_host_to_card Use workqueue to perform SPI xfers, it's necessary to fix nasty "BUG: scheduling while atomic", because spu_write() calls spi_sync() and spi_sync() may sleep, but hw_host_to_card() callback can be called from atomic context. Remove kthread completely, workqueue now does its job. Restore intermediate buffers which were removed in commit 86c34fe89e9cad9e1ba4d1a8bbf98259035f4caf that introduced mentioned bug. Signed-off-by: Vasily Khoruzhick Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/if_spi.c | 368 +++++++++++++++++++++------------ 1 file changed, 239 insertions(+), 129 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 00600239a053..f6c2cd665f49 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c @@ -20,10 +20,8 @@ #include #include #include -#include #include #include -#include #include #include #include @@ -34,6 +32,12 @@ #include "dev.h" #include "if_spi.h" +struct if_spi_packet { + struct list_head list; + u16 blen; + u8 buffer[0] __attribute__((aligned(4))); +}; + struct if_spi_card { struct spi_device *spi; struct lbs_private *priv; @@ -51,18 +55,36 @@ struct if_spi_card { unsigned long spu_reg_delay; /* Handles all SPI communication (except for FW load) */ - struct task_struct *spi_thread; - int run_thread; - - /* Used to wake up the spi_thread */ - struct semaphore spi_ready; - struct semaphore spi_thread_terminated; + struct workqueue_struct *workqueue; + struct work_struct packet_work; u8 cmd_buffer[IF_SPI_CMD_BUF_SIZE]; + + /* A buffer of incoming packets from libertas core. + * Since we can't sleep in hw_host_to_card, we have to buffer + * them. */ + struct list_head cmd_packet_list; + struct list_head data_packet_list; + + /* Protects cmd_packet_list and data_packet_list */ + spinlock_t buffer_lock; }; static void free_if_spi_card(struct if_spi_card *card) { + struct list_head *cursor, *next; + struct if_spi_packet *packet; + + list_for_each_safe(cursor, next, &card->cmd_packet_list) { + packet = container_of(cursor, struct if_spi_packet, list); + list_del(&packet->list); + kfree(packet); + } + list_for_each_safe(cursor, next, &card->data_packet_list) { + packet = container_of(cursor, struct if_spi_packet, list); + list_del(&packet->list); + kfree(packet); + } spi_set_drvdata(card->spi, NULL); kfree(card); } @@ -622,7 +644,7 @@ out: /* * SPI Transfer Thread * - * The SPI thread handles all SPI transfers, so there is no need for a lock. + * The SPI worker handles all SPI transfers, so there is no need for a lock. */ /* Move a command from the card to the host */ @@ -742,6 +764,40 @@ out: return err; } +/* Move data or a command from the host to the card. */ +static void if_spi_h2c(struct if_spi_card *card, + struct if_spi_packet *packet, int type) +{ + int err = 0; + u16 int_type, port_reg; + + switch (type) { + case MVMS_DAT: + int_type = IF_SPI_CIC_TX_DOWNLOAD_OVER; + port_reg = IF_SPI_DATA_RDWRPORT_REG; + break; + case MVMS_CMD: + int_type = IF_SPI_CIC_CMD_DOWNLOAD_OVER; + port_reg = IF_SPI_CMD_RDWRPORT_REG; + break; + default: + lbs_pr_err("can't transfer buffer of type %d\n", type); + err = -EINVAL; + goto out; + } + + /* Write the data to the card */ + err = spu_write(card, port_reg, packet->buffer, packet->blen); + if (err) + goto out; + +out: + kfree(packet); + + if (err) + lbs_pr_err("%s: error %d\n", __func__, err); +} + /* Inform the host about a card event */ static void if_spi_e2h(struct if_spi_card *card) { @@ -766,71 +822,88 @@ out: lbs_pr_err("%s: error %d\n", __func__, err); } -static int lbs_spi_thread(void *data) +static void if_spi_host_to_card_worker(struct work_struct *work) { int err; - struct if_spi_card *card = data; + struct if_spi_card *card; u16 hiStatus; + unsigned long flags; + struct if_spi_packet *packet; - while (1) { - /* Wait to be woken up by one of two things. First, our ISR - * could tell us that something happened on the WLAN. - * Secondly, libertas could call hw_host_to_card with more - * data, which we might be able to send. - */ - do { - err = down_interruptible(&card->spi_ready); - if (!card->run_thread) { - up(&card->spi_thread_terminated); - do_exit(0); - } - } while (err == -EINTR); + card = container_of(work, struct if_spi_card, packet_work); - /* Read the host interrupt status register to see what we - * can do. */ - err = spu_read_u16(card, IF_SPI_HOST_INT_STATUS_REG, - &hiStatus); - if (err) { - lbs_pr_err("I/O error\n"); + lbs_deb_enter(LBS_DEB_SPI); + + /* Read the host interrupt status register to see what we + * can do. */ + err = spu_read_u16(card, IF_SPI_HOST_INT_STATUS_REG, + &hiStatus); + if (err) { + lbs_pr_err("I/O error\n"); + goto err; + } + + if (hiStatus & IF_SPI_HIST_CMD_UPLOAD_RDY) { + err = if_spi_c2h_cmd(card); + if (err) goto err; - } + } + if (hiStatus & IF_SPI_HIST_RX_UPLOAD_RDY) { + err = if_spi_c2h_data(card); + if (err) + goto err; + } - if (hiStatus & IF_SPI_HIST_CMD_UPLOAD_RDY) { - err = if_spi_c2h_cmd(card); - if (err) - goto err; - } - if (hiStatus & IF_SPI_HIST_RX_UPLOAD_RDY) { - err = if_spi_c2h_data(card); - if (err) - goto err; + /* workaround: in PS mode, the card does not set the Command + * Download Ready bit, but it sets TX Download Ready. */ + if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY || + (card->priv->psstate != PS_STATE_FULL_POWER && + (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY))) { + /* This means two things. First of all, + * if there was a previous command sent, the card has + * successfully received it. + * Secondly, it is now ready to download another + * command. + */ + lbs_host_to_card_done(card->priv); + + /* Do we have any command packets from the host to + * send? */ + packet = NULL; + spin_lock_irqsave(&card->buffer_lock, flags); + if (!list_empty(&card->cmd_packet_list)) { + packet = (struct if_spi_packet *)(card-> + cmd_packet_list.next); + list_del(&packet->list); } + spin_unlock_irqrestore(&card->buffer_lock, flags); - /* workaround: in PS mode, the card does not set the Command - * Download Ready bit, but it sets TX Download Ready. */ - if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY || - (card->priv->psstate != PS_STATE_FULL_POWER && - (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY))) { - lbs_host_to_card_done(card->priv); + if (packet) + if_spi_h2c(card, packet, MVMS_CMD); + } + if (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY) { + /* Do we have any data packets from the host to + * send? */ + packet = NULL; + spin_lock_irqsave(&card->buffer_lock, flags); + if (!list_empty(&card->data_packet_list)) { + packet = (struct if_spi_packet *)(card-> + data_packet_list.next); + list_del(&packet->list); } + spin_unlock_irqrestore(&card->buffer_lock, flags); - if (hiStatus & IF_SPI_HIST_CARD_EVENT) - if_spi_e2h(card); + if (packet) + if_spi_h2c(card, packet, MVMS_DAT); + } + if (hiStatus & IF_SPI_HIST_CARD_EVENT) + if_spi_e2h(card); err: - if (err) - lbs_pr_err("%s: got error %d\n", __func__, err); - } -} + if (err) + lbs_pr_err("%s: got error %d\n", __func__, err); -/* Block until lbs_spi_thread thread has terminated */ -static void if_spi_terminate_spi_thread(struct if_spi_card *card) -{ - /* It would be nice to use kthread_stop here, but that function - * can't wake threads waiting for a semaphore. */ - card->run_thread = 0; - up(&card->spi_ready); - down(&card->spi_thread_terminated); + lbs_deb_leave(LBS_DEB_SPI); } /* @@ -842,18 +915,40 @@ static int if_spi_host_to_card(struct lbs_private *priv, u8 type, u8 *buf, u16 nb) { int err = 0; + unsigned long flags; struct if_spi_card *card = priv->card; + struct if_spi_packet *packet; + u16 blen; lbs_deb_enter_args(LBS_DEB_SPI, "type %d, bytes %d", type, nb); - nb = ALIGN(nb, 4); + if (nb == 0) { + lbs_pr_err("%s: invalid size requested: %d\n", __func__, nb); + err = -EINVAL; + goto out; + } + blen = ALIGN(nb, 4); + packet = kzalloc(sizeof(struct if_spi_packet) + blen, GFP_ATOMIC); + if (!packet) { + err = -ENOMEM; + goto out; + } + packet->blen = blen; + memcpy(packet->buffer, buf, nb); + memset(packet->buffer + nb, 0, blen - nb); switch (type) { case MVMS_CMD: - err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG, buf, nb); + priv->dnld_sent = DNLD_CMD_SENT; + spin_lock_irqsave(&card->buffer_lock, flags); + list_add_tail(&packet->list, &card->cmd_packet_list); + spin_unlock_irqrestore(&card->buffer_lock, flags); break; case MVMS_DAT: - err = spu_write(card, IF_SPI_DATA_RDWRPORT_REG, buf, nb); + priv->dnld_sent = DNLD_DATA_SENT; + spin_lock_irqsave(&card->buffer_lock, flags); + list_add_tail(&packet->list, &card->data_packet_list); + spin_unlock_irqrestore(&card->buffer_lock, flags); break; default: lbs_pr_err("can't transfer buffer of type %d", type); @@ -861,6 +956,9 @@ static int if_spi_host_to_card(struct lbs_private *priv, break; } + /* Queue spi xfer work */ + queue_work(card->workqueue, &card->packet_work); +out: lbs_deb_leave_args(LBS_DEB_SPI, "err=%d", err); return err; } @@ -869,13 +967,14 @@ static int if_spi_host_to_card(struct lbs_private *priv, * Host Interrupts * * Service incoming interrupts from the WLAN device. We can't sleep here, so - * don't try to talk on the SPI bus, just wake up the SPI thread. + * don't try to talk on the SPI bus, just queue the SPI xfer work. */ static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id) { struct if_spi_card *card = dev_id; - up(&card->spi_ready); + queue_work(card->workqueue, &card->packet_work); + return IRQ_HANDLED; } @@ -883,56 +982,26 @@ static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id) * SPI callbacks */ -static int __devinit if_spi_probe(struct spi_device *spi) +static int if_spi_init_card(struct if_spi_card *card) { - struct if_spi_card *card; - struct lbs_private *priv = NULL; - struct libertas_spi_platform_data *pdata = spi->dev.platform_data; - int err = 0, i; + struct spi_device *spi = card->spi; + int err, i; u32 scratch; - struct sched_param param = { .sched_priority = 1 }; const struct firmware *helper = NULL; const struct firmware *mainfw = NULL; lbs_deb_enter(LBS_DEB_SPI); - if (!pdata) { - err = -EINVAL; - goto out; - } - - if (pdata->setup) { - err = pdata->setup(spi); - if (err) - goto out; - } - - /* Allocate card structure to represent this specific device */ - card = kzalloc(sizeof(struct if_spi_card), GFP_KERNEL); - if (!card) { - err = -ENOMEM; - goto out; - } - spi_set_drvdata(spi, card); - card->pdata = pdata; - card->spi = spi; - card->prev_xfer_time = jiffies; - - sema_init(&card->spi_ready, 0); - sema_init(&card->spi_thread_terminated, 0); - - /* Initialize the SPI Interface Unit */ - err = spu_init(card, pdata->use_dummy_writes); + err = spu_init(card, card->pdata->use_dummy_writes); if (err) - goto free_card; + goto out; err = spu_get_chip_revision(card, &card->card_id, &card->card_rev); if (err) - goto free_card; + goto out; - /* Firmware load */ err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch); if (err) - goto free_card; + goto out; if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC) lbs_deb_spi("Firmware is already loaded for " "Marvell WLAN 802.11 adapter\n"); @@ -946,7 +1015,7 @@ static int __devinit if_spi_probe(struct spi_device *spi) lbs_pr_err("Unsupported chip_id: 0x%02x\n", card->card_id); err = -ENODEV; - goto free_card; + goto out; } err = lbs_get_firmware(&card->spi->dev, NULL, NULL, @@ -954,7 +1023,7 @@ static int __devinit if_spi_probe(struct spi_device *spi) &mainfw); if (err) { lbs_pr_err("failed to find firmware (%d)\n", err); - goto free_card; + goto out; } lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter " @@ -966,14 +1035,67 @@ static int __devinit if_spi_probe(struct spi_device *spi) spi->max_speed_hz); err = if_spi_prog_helper_firmware(card, helper); if (err) - goto free_card; + goto out; err = if_spi_prog_main_firmware(card, mainfw); if (err) - goto free_card; + goto out; lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n"); } err = spu_set_interrupt_mode(card, 0, 1); + if (err) + goto out; + +out: + if (helper) + release_firmware(helper); + if (mainfw) + release_firmware(mainfw); + + lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err); + + return err; +} + +static int __devinit if_spi_probe(struct spi_device *spi) +{ + struct if_spi_card *card; + struct lbs_private *priv = NULL; + struct libertas_spi_platform_data *pdata = spi->dev.platform_data; + int err = 0; + + lbs_deb_enter(LBS_DEB_SPI); + + if (!pdata) { + err = -EINVAL; + goto out; + } + + if (pdata->setup) { + err = pdata->setup(spi); + if (err) + goto out; + } + + /* Allocate card structure to represent this specific device */ + card = kzalloc(sizeof(struct if_spi_card), GFP_KERNEL); + if (!card) { + err = -ENOMEM; + goto teardown; + } + spi_set_drvdata(spi, card); + card->pdata = pdata; + card->spi = spi; + card->prev_xfer_time = jiffies; + + INIT_LIST_HEAD(&card->cmd_packet_list); + INIT_LIST_HEAD(&card->data_packet_list); + spin_lock_init(&card->buffer_lock); + + /* Initialize the SPI Interface Unit */ + + /* Firmware load */ + err = if_spi_init_card(card); if (err) goto free_card; @@ -993,27 +1115,16 @@ static int __devinit if_spi_probe(struct spi_device *spi) priv->fw_ready = 1; /* Initialize interrupt handling stuff. */ - card->run_thread = 1; - card->spi_thread = kthread_run(lbs_spi_thread, card, "lbs_spi_thread"); - if (IS_ERR(card->spi_thread)) { - card->run_thread = 0; - err = PTR_ERR(card->spi_thread); - lbs_pr_err("error creating SPI thread: err=%d\n", err); - goto remove_card; - } - if (sched_setscheduler(card->spi_thread, SCHED_FIFO, ¶m)) - lbs_pr_err("Error setting scheduler, using default.\n"); + card->workqueue = create_workqueue("libertas_spi"); + INIT_WORK(&card->packet_work, if_spi_host_to_card_worker); err = request_irq(spi->irq, if_spi_host_interrupt, IRQF_TRIGGER_FALLING, "libertas_spi", card); if (err) { lbs_pr_err("can't get host irq line-- request_irq failed\n"); - goto terminate_thread; + goto terminate_workqueue; } - /* poke the IRQ handler so that we don't miss the first interrupt */ - up(&card->spi_ready); - /* Start the card. * This will call register_netdev, and we'll start * getting interrupts... */ @@ -1028,18 +1139,16 @@ static int __devinit if_spi_probe(struct spi_device *spi) release_irq: free_irq(spi->irq, card); -terminate_thread: - if_spi_terminate_spi_thread(card); -remove_card: +terminate_workqueue: + flush_workqueue(card->workqueue); + destroy_workqueue(card->workqueue); lbs_remove_card(priv); /* will call free_netdev */ free_card: free_if_spi_card(card); +teardown: + if (pdata->teardown) + pdata->teardown(spi); out: - if (helper) - release_firmware(helper); - if (mainfw) - release_firmware(mainfw); - lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err); return err; } @@ -1056,7 +1165,8 @@ static int __devexit libertas_spi_remove(struct spi_device *spi) lbs_remove_card(priv); /* will call free_netdev */ free_irq(spi->irq, card); - if_spi_terminate_spi_thread(card); + flush_workqueue(card->workqueue); + destroy_workqueue(card->workqueue); if (card->pdata->teardown) card->pdata->teardown(spi); free_if_spi_card(card); -- cgit v1.2.3 From 75abde4d193fe300a2c1d3ee7f632eb777aa48b2 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Fri, 21 Jan 2011 22:44:49 +0200 Subject: libertas: Prepare stuff for if_spi.c pm support To support suspend/resume in if_spi we need two things: - re-setup fw in lbs_resume(), because if_spi powercycles card; - don't touch hwaddr on second lbs_update_hw_spec() call for same reason; Signed-off-by: Vasily Khoruzhick Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cmd.c | 10 +++-- drivers/net/wireless/libertas/dev.h | 2 + drivers/net/wireless/libertas/main.c | 77 +++++++++++++++++++----------------- 3 files changed, 49 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 78c4da150a74..7e8a658b7670 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -145,9 +145,13 @@ int lbs_update_hw_spec(struct lbs_private *priv) if (priv->current_addr[0] == 0xff) memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN); - memcpy(priv->dev->dev_addr, priv->current_addr, ETH_ALEN); - if (priv->mesh_dev) - memcpy(priv->mesh_dev->dev_addr, priv->current_addr, ETH_ALEN); + if (!priv->copied_hwaddr) { + memcpy(priv->dev->dev_addr, priv->current_addr, ETH_ALEN); + if (priv->mesh_dev) + memcpy(priv->mesh_dev->dev_addr, + priv->current_addr, ETH_ALEN); + priv->copied_hwaddr = 1; + } out: lbs_deb_leave(LBS_DEB_CMD); diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 18dd9a02c459..bc461eb39660 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h @@ -90,6 +90,7 @@ struct lbs_private { void *card; u8 fw_ready; u8 surpriseremoved; + u8 setup_fw_on_resume; int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb); void (*reset_card) (struct lbs_private *priv); int (*enter_deep_sleep) (struct lbs_private *priv); @@ -101,6 +102,7 @@ struct lbs_private { u32 fwcapinfo; u16 regioncode; u8 current_addr[ETH_ALEN]; + u8 copied_hwaddr; /* Command download */ u8 dnld_sent; diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 6836a6dd9853..ca8149cd5bd9 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -539,6 +539,43 @@ static int lbs_thread(void *data) return 0; } +/** + * @brief This function gets the HW spec from the firmware and sets + * some basic parameters. + * + * @param priv A pointer to struct lbs_private structure + * @return 0 or -1 + */ +static int lbs_setup_firmware(struct lbs_private *priv) +{ + int ret = -1; + s16 curlevel = 0, minlevel = 0, maxlevel = 0; + + lbs_deb_enter(LBS_DEB_FW); + + /* Read MAC address from firmware */ + memset(priv->current_addr, 0xff, ETH_ALEN); + ret = lbs_update_hw_spec(priv); + if (ret) + goto done; + + /* Read power levels if available */ + ret = lbs_get_tx_power(priv, &curlevel, &minlevel, &maxlevel); + if (ret == 0) { + priv->txpower_cur = curlevel; + priv->txpower_min = minlevel; + priv->txpower_max = maxlevel; + } + + /* Send cmd to FW to enable 11D function */ + ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_11D_ENABLE, 1); + + lbs_set_mac_control(priv); +done: + lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); + return ret; +} + int lbs_suspend(struct lbs_private *priv) { int ret; @@ -584,47 +621,13 @@ int lbs_resume(struct lbs_private *priv) lbs_pr_err("deep sleep activation failed: %d\n", ret); } - lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); - return ret; -} -EXPORT_SYMBOL_GPL(lbs_resume); - -/** - * @brief This function gets the HW spec from the firmware and sets - * some basic parameters. - * - * @param priv A pointer to struct lbs_private structure - * @return 0 or -1 - */ -static int lbs_setup_firmware(struct lbs_private *priv) -{ - int ret = -1; - s16 curlevel = 0, minlevel = 0, maxlevel = 0; - - lbs_deb_enter(LBS_DEB_FW); - - /* Read MAC address from firmware */ - memset(priv->current_addr, 0xff, ETH_ALEN); - ret = lbs_update_hw_spec(priv); - if (ret) - goto done; - - /* Read power levels if available */ - ret = lbs_get_tx_power(priv, &curlevel, &minlevel, &maxlevel); - if (ret == 0) { - priv->txpower_cur = curlevel; - priv->txpower_min = minlevel; - priv->txpower_max = maxlevel; - } + if (priv->setup_fw_on_resume) + ret = lbs_setup_firmware(priv); - /* Send cmd to FW to enable 11D function */ - ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_11D_ENABLE, 1); - - lbs_set_mac_control(priv); -done: lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); return ret; } +EXPORT_SYMBOL_GPL(lbs_resume); /** * This function handles the timeout of command sending. -- cgit v1.2.3 From e7332a41442bde1c14550998cadceca34c967dfc Mon Sep 17 00:00:00 2001 From: David Gnedt Date: Sun, 30 Jan 2011 20:10:46 +0100 Subject: wl1251: fix queue stopping/waking for TX path The queue stopping/waking functionality was broken in a way that could cause the TX to stall if the right circumstances are met. The problem was caused by tx_work, which is scheduled on each TX operation. If the firmware buffer is full, tx_work does nothing. In combinition with stopped queues or non-continues transfers, tx_work is never scheduled again. Moreover the low watermark introduced by 9df86e2e702c6d5547aced7f241addd2d698bb11 never takes effect because of some old code. Solve this by scheduling tx_work every time tx_queue is non-empty and firmware buffer is freed on tx_complete. This also solves a possible but unlikely case: If less frames than the high watermark are queued, but more than firmware buffer can hold. This results in queues staying awake but the only scheduled tx_work doesn't transfer all frames, so the remaining frames are stuck in the queue until more frames get queued and tx_work is scheduled again. Signed-off-by: David Gnedt Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl1251/tx.c | 48 ++++++++++------------------------------ 1 file changed, 12 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl1251/tx.c b/drivers/net/wireless/wl1251/tx.c index 554b4f9a3d3e..10112de55493 100644 --- a/drivers/net/wireless/wl1251/tx.c +++ b/drivers/net/wireless/wl1251/tx.c @@ -368,7 +368,7 @@ static void wl1251_tx_packet_cb(struct wl1251 *wl, { struct ieee80211_tx_info *info; struct sk_buff *skb; - int hdrlen, ret; + int hdrlen; u8 *frame; skb = wl->tx_frames[result->id]; @@ -407,40 +407,12 @@ static void wl1251_tx_packet_cb(struct wl1251 *wl, ieee80211_tx_status(wl->hw, skb); wl->tx_frames[result->id] = NULL; - - if (wl->tx_queue_stopped) { - wl1251_debug(DEBUG_TX, "cb: queue was stopped"); - - skb = skb_dequeue(&wl->tx_queue); - - /* The skb can be NULL because tx_work might have been - scheduled before the queue was stopped making the - queue empty */ - - if (skb) { - ret = wl1251_tx_frame(wl, skb); - if (ret == -EBUSY) { - /* firmware buffer is still full */ - wl1251_debug(DEBUG_TX, "cb: fw buffer " - "still full"); - skb_queue_head(&wl->tx_queue, skb); - return; - } else if (ret < 0) { - dev_kfree_skb(skb); - return; - } - } - - wl1251_debug(DEBUG_TX, "cb: waking queues"); - ieee80211_wake_queues(wl->hw); - wl->tx_queue_stopped = false; - } } /* Called upon reception of a TX complete interrupt */ void wl1251_tx_complete(struct wl1251 *wl) { - int i, result_index, num_complete = 0; + int i, result_index, num_complete = 0, queue_len; struct tx_result result[FW_TX_CMPLT_BLOCK_SIZE], *result_ptr; unsigned long flags; @@ -471,18 +443,22 @@ void wl1251_tx_complete(struct wl1251 *wl) } } - if (wl->tx_queue_stopped - && - skb_queue_len(&wl->tx_queue) <= WL1251_TX_QUEUE_LOW_WATERMARK){ + queue_len = skb_queue_len(&wl->tx_queue); - /* firmware buffer has space, restart queues */ + if ((num_complete > 0) && (queue_len > 0)) { + /* firmware buffer has space, reschedule tx_work */ + wl1251_debug(DEBUG_TX, "tx_complete: reschedule tx_work"); + ieee80211_queue_work(wl->hw, &wl->tx_work); + } + + if (wl->tx_queue_stopped && + queue_len <= WL1251_TX_QUEUE_LOW_WATERMARK) { + /* tx_queue has space, restart queues */ wl1251_debug(DEBUG_TX, "tx_complete: waking queues"); spin_lock_irqsave(&wl->wl_lock, flags); ieee80211_wake_queues(wl->hw); wl->tx_queue_stopped = false; spin_unlock_irqrestore(&wl->wl_lock, flags); - ieee80211_queue_work(wl->hw, &wl->tx_work); - } /* Every completed frame needs to be acknowledged */ -- cgit v1.2.3 From bb4793b3c6370a1fed86978c6590241d770cb43e Mon Sep 17 00:00:00 2001 From: David Gnedt Date: Sun, 30 Jan 2011 20:10:48 +0100 Subject: wl1251: fix 4-byte TX buffer alignment This implements TX buffer alignment for cloned or too small skb by copying and replacing the original skb. Recent changes in wireless-testing seems to make this really necessary. Signed-off-by: David Gnedt Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl1251/tx.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl1251/tx.c b/drivers/net/wireless/wl1251/tx.c index 10112de55493..28121c590a2b 100644 --- a/drivers/net/wireless/wl1251/tx.c +++ b/drivers/net/wireless/wl1251/tx.c @@ -213,16 +213,30 @@ static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb, wl1251_debug(DEBUG_TX, "skb offset %d", offset); /* check whether the current skb can be used */ - if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) { - unsigned char *src = skb->data; + if (skb_cloned(skb) || (skb_tailroom(skb) < offset)) { + struct sk_buff *newskb = skb_copy_expand(skb, 0, 3, + GFP_KERNEL); + + if (unlikely(newskb == NULL)) { + wl1251_error("Can't allocate skb!"); + return -EINVAL; + } + + tx_hdr = (struct tx_double_buffer_desc *) newskb->data; + + dev_kfree_skb_any(skb); + wl->tx_frames[tx_hdr->id] = skb = newskb; - /* align the buffer on a 4-byte boundary */ + offset = (4 - (long)skb->data) & 0x03; + wl1251_debug(DEBUG_TX, "new skb offset %d", offset); + } + + /* align the buffer on a 4-byte boundary */ + if (offset) { + unsigned char *src = skb->data; skb_reserve(skb, offset); memmove(skb->data, src, skb->len); tx_hdr = (struct tx_double_buffer_desc *) skb->data; - } else { - wl1251_info("No handler, fixme!"); - return -EINVAL; } } -- cgit v1.2.3 From c3e334d29484423e78009790a3d3fa78da8b43a1 Mon Sep 17 00:00:00 2001 From: David Gnedt Date: Sun, 30 Jan 2011 20:10:57 +0100 Subject: wl1251: enable beacon early termination while in power-saving mode Port the beacon early termination feature from wl1251 driver version included in the Maemo Fremantle kernel. It is enabled when going to power-saving mode and disabled when leaving power-saving mode. Signed-off-by: David Gnedt Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl1251/acx.c | 28 ++++++++++++++++++++++++++++ drivers/net/wireless/wl1251/acx.h | 27 +++++++++++++++++++++++++++ drivers/net/wireless/wl1251/ps.c | 11 +++++++++++ drivers/net/wireless/wl1251/wl1251.h | 2 ++ 4 files changed, 68 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/wl1251/acx.c b/drivers/net/wireless/wl1251/acx.c index 64a0214cfb29..8c943661f2df 100644 --- a/drivers/net/wireless/wl1251/acx.c +++ b/drivers/net/wireless/wl1251/acx.c @@ -978,6 +978,34 @@ out: return ret; } +int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode, + u8 max_consecutive) +{ + struct wl1251_acx_bet_enable *acx; + int ret; + + wl1251_debug(DEBUG_ACX, "acx bet enable"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->enable = mode; + acx->max_consecutive = max_consecutive; + + ret = wl1251_cmd_configure(wl, ACX_BET_ENABLE, acx, sizeof(*acx)); + if (ret < 0) { + wl1251_warning("wl1251 acx bet enable failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} + int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max, u8 aifs, u16 txop) { diff --git a/drivers/net/wireless/wl1251/acx.h b/drivers/net/wireless/wl1251/acx.h index efcc3aaca14f..6a19f38958f7 100644 --- a/drivers/net/wireless/wl1251/acx.h +++ b/drivers/net/wireless/wl1251/acx.h @@ -1164,6 +1164,31 @@ struct wl1251_acx_wr_tbtt_and_dtim { u8 padding; } __packed; +enum wl1251_acx_bet_mode { + WL1251_ACX_BET_DISABLE = 0, + WL1251_ACX_BET_ENABLE = 1, +}; + +struct wl1251_acx_bet_enable { + struct acx_header header; + + /* + * Specifies if beacon early termination procedure is enabled or + * disabled, see enum wl1251_acx_bet_mode. + */ + u8 enable; + + /* + * Specifies the maximum number of consecutive beacons that may be + * early terminated. After this number is reached at least one full + * beacon must be correctly received in FW before beacon ET + * resumes. Range 0 - 255. + */ + u8 max_consecutive; + + u8 padding[2]; +} __packed; + struct wl1251_acx_ac_cfg { struct acx_header header; @@ -1401,6 +1426,8 @@ int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime); int wl1251_acx_rate_policies(struct wl1251 *wl); int wl1251_acx_mem_cfg(struct wl1251 *wl); int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim); +int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode, + u8 max_consecutive); int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max, u8 aifs, u16 txop); int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue, diff --git a/drivers/net/wireless/wl1251/ps.c b/drivers/net/wireless/wl1251/ps.c index 5ed47c8373d2..9ba23ede51bd 100644 --- a/drivers/net/wireless/wl1251/ps.c +++ b/drivers/net/wireless/wl1251/ps.c @@ -153,6 +153,11 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode) if (ret < 0) return ret; + ret = wl1251_acx_bet_enable(wl, WL1251_ACX_BET_ENABLE, + WL1251_DEFAULT_BET_CONSECUTIVE); + if (ret < 0) + return ret; + ret = wl1251_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE); if (ret < 0) return ret; @@ -170,6 +175,12 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode) if (ret < 0) return ret; + /* disable BET */ + ret = wl1251_acx_bet_enable(wl, WL1251_ACX_BET_DISABLE, + WL1251_DEFAULT_BET_CONSECUTIVE); + if (ret < 0) + return ret; + /* disable beacon filtering */ ret = wl1251_acx_beacon_filter_opt(wl, false); if (ret < 0) diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h index c0ce2c8b43b8..462ac5b20585 100644 --- a/drivers/net/wireless/wl1251/wl1251.h +++ b/drivers/net/wireless/wl1251/wl1251.h @@ -410,6 +410,8 @@ void wl1251_disable_interrupts(struct wl1251 *wl); #define WL1251_DEFAULT_CHANNEL 0 +#define WL1251_DEFAULT_BET_CONSECUTIVE 10 + #define CHIP_ID_1251_PG10 (0x7010101) #define CHIP_ID_1251_PG11 (0x7020101) #define CHIP_ID_1251_PG12 (0x7030101) -- cgit v1.2.3 From 8964e492b5740dae0f4f68e08f4a9a45d4b57620 Mon Sep 17 00:00:00 2001 From: David Gnedt Date: Sun, 30 Jan 2011 20:11:00 +0100 Subject: wl1251: implement connection quality monitoring Implement connection quality monitoring similar to the wl1271 driver. It triggers ieee80211_cqm_rssi_notify with the corresponding event when RSSI drops blow RSSI threshold or rises again above the RSSI threshold. It should be noted that wl1251 doesn't support RSSI hysteresis, instead it uses RSSI averageing and delays events until a certain count of frames proved RSSI change. Signed-off-by: David Gnedt Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl1251/acx.c | 25 ++++++++++++++++++++ drivers/net/wireless/wl1251/acx.h | 45 ++++++++++++++++++++++++++++++++++++ drivers/net/wireless/wl1251/event.c | 18 +++++++++++++++ drivers/net/wireless/wl1251/main.c | 15 +++++++++++- drivers/net/wireless/wl1251/wl1251.h | 5 ++++ 5 files changed, 107 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl1251/acx.c b/drivers/net/wireless/wl1251/acx.c index 8c943661f2df..ef8370edace7 100644 --- a/drivers/net/wireless/wl1251/acx.c +++ b/drivers/net/wireless/wl1251/acx.c @@ -776,6 +776,31 @@ out: return ret; } +int wl1251_acx_low_rssi(struct wl1251 *wl, s8 threshold, u8 weight, + u8 depth, enum wl1251_acx_low_rssi_type type) +{ + struct acx_low_rssi *rssi; + int ret; + + wl1251_debug(DEBUG_ACX, "acx low rssi"); + + rssi = kzalloc(sizeof(*rssi), GFP_KERNEL); + if (!rssi) + return -ENOMEM; + + rssi->threshold = threshold; + rssi->weight = weight; + rssi->depth = depth; + rssi->type = type; + + ret = wl1251_cmd_configure(wl, ACX_LOW_RSSI, rssi, sizeof(*rssi)); + if (ret < 0) + wl1251_warning("failed to set low rssi threshold: %d", ret); + + kfree(rssi); + return ret; +} + int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble) { struct acx_preamble *acx; diff --git a/drivers/net/wireless/wl1251/acx.h b/drivers/net/wireless/wl1251/acx.h index 6a19f38958f7..c2ba100f9b1a 100644 --- a/drivers/net/wireless/wl1251/acx.h +++ b/drivers/net/wireless/wl1251/acx.h @@ -399,6 +399,49 @@ struct acx_rts_threshold { u8 pad[2]; } __packed; +enum wl1251_acx_low_rssi_type { + /* + * The event is a "Level" indication which keeps triggering + * as long as the average RSSI is below the threshold. + */ + WL1251_ACX_LOW_RSSI_TYPE_LEVEL = 0, + + /* + * The event is an "Edge" indication which triggers + * only when the RSSI threshold is crossed from above. + */ + WL1251_ACX_LOW_RSSI_TYPE_EDGE = 1, +}; + +struct acx_low_rssi { + struct acx_header header; + + /* + * The threshold (in dBm) below (or above after low rssi + * indication) which the firmware generates an interrupt to the + * host. This parameter is signed. + */ + s8 threshold; + + /* + * The weight of the current RSSI sample, before adding the new + * sample, that is used to calculate the average RSSI. + */ + u8 weight; + + /* + * The number of Beacons/Probe response frames that will be + * received before issuing the Low or Regained RSSI event. + */ + u8 depth; + + /* + * Configures how the Low RSSI Event is triggered. Refer to + * enum wl1251_acx_low_rssi_type for more. + */ + u8 type; +} __packed; + struct acx_beacon_filter_option { struct acx_header header; @@ -1418,6 +1461,8 @@ int wl1251_acx_cca_threshold(struct wl1251 *wl); int wl1251_acx_bcn_dtim_options(struct wl1251 *wl); int wl1251_acx_aid(struct wl1251 *wl, u16 aid); int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask); +int wl1251_acx_low_rssi(struct wl1251 *wl, s8 threshold, u8 weight, + u8 depth, enum wl1251_acx_low_rssi_type type); int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble); int wl1251_acx_cts_protect(struct wl1251 *wl, enum acx_ctsprotect_type ctsprotect); diff --git a/drivers/net/wireless/wl1251/event.c b/drivers/net/wireless/wl1251/event.c index 712372e50a87..dfc4579acb06 100644 --- a/drivers/net/wireless/wl1251/event.c +++ b/drivers/net/wireless/wl1251/event.c @@ -90,6 +90,24 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox) } } + if (wl->vif && wl->rssi_thold) { + if (vector & ROAMING_TRIGGER_LOW_RSSI_EVENT_ID) { + wl1251_debug(DEBUG_EVENT, + "ROAMING_TRIGGER_LOW_RSSI_EVENT"); + ieee80211_cqm_rssi_notify(wl->vif, + NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, + GFP_KERNEL); + } + + if (vector & ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID) { + wl1251_debug(DEBUG_EVENT, + "ROAMING_TRIGGER_REGAINED_RSSI_EVENT"); + ieee80211_cqm_rssi_notify(wl->vif, + NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, + GFP_KERNEL); + } + } + return 0; } diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index 012e1a4016fe..0325643b7073 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c @@ -502,6 +502,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw) wl->psm = 0; wl->tx_queue_stopped = false; wl->power_level = WL1251_DEFAULT_POWER_LEVEL; + wl->rssi_thold = 0; wl->channel = WL1251_DEFAULT_CHANNEL; wl1251_debugfs_reset(wl); @@ -959,6 +960,16 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw, if (ret < 0) goto out; + if (changed & BSS_CHANGED_CQM) { + ret = wl1251_acx_low_rssi(wl, bss_conf->cqm_rssi_thold, + WL1251_DEFAULT_LOW_RSSI_WEIGHT, + WL1251_DEFAULT_LOW_RSSI_DEPTH, + WL1251_ACX_LOW_RSSI_TYPE_EDGE); + if (ret < 0) + goto out; + wl->rssi_thold = bss_conf->cqm_rssi_thold; + } + if (changed & BSS_CHANGED_BSSID) { memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); @@ -1310,7 +1321,8 @@ int wl1251_init_ieee80211(struct wl1251 *wl) wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_BEACON_FILTER | - IEEE80211_HW_SUPPORTS_UAPSD; + IEEE80211_HW_SUPPORTS_UAPSD | + IEEE80211_HW_SUPPORTS_CQM_RSSI; wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); wl->hw->wiphy->max_scan_ssids = 1; @@ -1374,6 +1386,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void) wl->psm_requested = false; wl->tx_queue_stopped = false; wl->power_level = WL1251_DEFAULT_POWER_LEVEL; + wl->rssi_thold = 0; wl->beacon_int = WL1251_DEFAULT_BEACON_INT; wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD; wl->vif = NULL; diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h index 462ac5b20585..bb23cd522b22 100644 --- a/drivers/net/wireless/wl1251/wl1251.h +++ b/drivers/net/wireless/wl1251/wl1251.h @@ -370,6 +370,8 @@ struct wl1251 { /* in dBm */ int power_level; + int rssi_thold; + struct wl1251_stats stats; struct wl1251_debugfs debugfs; @@ -433,4 +435,7 @@ void wl1251_disable_interrupts(struct wl1251 *wl); #define WL1251_PART_WORK_REG_START REGISTERS_BASE #define WL1251_PART_WORK_REG_SIZE REGISTERS_WORK_SIZE +#define WL1251_DEFAULT_LOW_RSSI_WEIGHT 10 +#define WL1251_DEFAULT_LOW_RSSI_DEPTH 10 + #endif -- cgit v1.2.3 From 43d136442a0af3b26df3f16c7b935b5ea12e493f Mon Sep 17 00:00:00 2001 From: David Gnedt Date: Sun, 30 Jan 2011 20:11:04 +0100 Subject: wl1251: enable adhoc mode Enable adhoc support in wl1251 driver. Signed-off-by: David Gnedt Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl1251/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index 0325643b7073..1c8b0775d849 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c @@ -1324,7 +1324,8 @@ int wl1251_init_ieee80211(struct wl1251 *wl) IEEE80211_HW_SUPPORTS_UAPSD | IEEE80211_HW_SUPPORTS_CQM_RSSI; - wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC); wl->hw->wiphy->max_scan_ssids = 1; wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz; -- cgit v1.2.3 From 73b30dfe4f756315b8cc431fca3ff340090c0ae4 Mon Sep 17 00:00:00 2001 From: David Gnedt Date: Sun, 30 Jan 2011 20:11:10 +0100 Subject: wl1251: set rate index and preamble flag on received packets Set the rate index rate_idx and preamble flag RX_FLAG_SHORTPRE on received packets. Signed-off-by: David Gnedt Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl1251/rx.c | 46 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl1251/rx.c b/drivers/net/wireless/wl1251/rx.c index 86eef456d7b2..b659e15c78df 100644 --- a/drivers/net/wireless/wl1251/rx.c +++ b/drivers/net/wireless/wl1251/rx.c @@ -96,8 +96,52 @@ static void wl1251_rx_status(struct wl1251 *wl, if (unlikely(!(desc->flags & RX_DESC_VALID_FCS))) status->flag |= RX_FLAG_FAILED_FCS_CRC; + switch (desc->rate) { + /* skip 1 and 12 Mbps because they have same value 0x0a */ + case RATE_2MBPS: + status->rate_idx = 1; + break; + case RATE_5_5MBPS: + status->rate_idx = 2; + break; + case RATE_11MBPS: + status->rate_idx = 3; + break; + case RATE_6MBPS: + status->rate_idx = 4; + break; + case RATE_9MBPS: + status->rate_idx = 5; + break; + case RATE_18MBPS: + status->rate_idx = 7; + break; + case RATE_24MBPS: + status->rate_idx = 8; + break; + case RATE_36MBPS: + status->rate_idx = 9; + break; + case RATE_48MBPS: + status->rate_idx = 10; + break; + case RATE_54MBPS: + status->rate_idx = 11; + break; + } + + /* for 1 and 12 Mbps we have to check the modulation */ + if (desc->rate == RATE_1MBPS) { + if (!(desc->mod_pre & OFDM_RATE_BIT)) + /* CCK -> RATE_1MBPS */ + status->rate_idx = 0; + else + /* OFDM -> RATE_12MBPS */ + status->rate_idx = 6; + } - /* FIXME: set status->rate_idx */ + if (desc->mod_pre & SHORT_PREAMBLE_BIT) + status->flag |= RX_FLAG_SHORTPRE; } static void wl1251_rx_body(struct wl1251 *wl, -- cgit v1.2.3 From 45655baa42ce4116dd8a8d93832d75b4b264137a Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 31 Jan 2011 23:47:42 +0530 Subject: ath9k_htc: cancel ani work in ath9k_htc_stop ani work is cancelled in dissaoctiation. But in some cases during suspend, deauthention never be called. So we failed to stop ani work which was identified by the following warning. Call Trace: [] ieee80211_can_queue_work.clone.17+0x2d/0x40 [mac80211] [] ieee80211_queue_delayed_work+0x30/0x60 [mac80211] [] ath9k_ani_work+0x142/0x250 [ath9k_htc] [] async_run_entry_fn+0x0/0x180 [] ath9k_ani_work+0x0/0x250 [ath9k_htc] Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index a702089f18d0..0526c259a634 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1052,6 +1052,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) cancel_work_sync(&priv->fatal_work); cancel_work_sync(&priv->ps_work); cancel_delayed_work_sync(&priv->ath9k_led_blink_work); + cancel_delayed_work_sync(&priv->ath9k_ani_work); ath9k_led_stop_brightness(priv); mutex_lock(&priv->mutex); -- cgit v1.2.3 From c344c9cb01d1dc65f2d5c85f22790e7f01d7dcd8 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 31 Jan 2011 23:47:43 +0530 Subject: ath9k: use common get current channel function Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 1447b55a8d0a..048eaef11f4a 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -64,19 +64,6 @@ static u8 parse_mpdudensity(u8 mpdudensity) } } -static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc, - struct ieee80211_hw *hw) -{ - struct ieee80211_channel *curchan = hw->conf.channel; - struct ath9k_channel *channel; - u8 chan_idx; - - chan_idx = curchan->hw_value; - channel = &sc->sc_ah->channels[chan_idx]; - ath9k_cmn_update_ichannel(channel, curchan, hw->conf.channel_type); - return channel; -} - bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode) { unsigned long flags; @@ -867,7 +854,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) ath9k_hw_configpcipowersave(ah, 0, 0); if (!ah->curchan) - ah->curchan = ath_get_curchannel(sc, sc->hw); + ah->curchan = ath9k_cmn_get_curchannel(sc->hw, ah); r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); if (r) { @@ -928,7 +915,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) ath_flushrecv(sc); /* flush recv queue */ if (!ah->curchan) - ah->curchan = ath_get_curchannel(sc, hw); + ah->curchan = ath9k_cmn_get_curchannel(hw, ah); r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); if (r) { @@ -1029,7 +1016,7 @@ static int ath9k_start(struct ieee80211_hw *hw) /* setup initial channel */ sc->chan_idx = curchan->hw_value; - init_channel = ath_get_curchannel(sc, hw); + init_channel = ath9k_cmn_get_curchannel(hw, ah); /* Reset SERDES registers */ ath9k_hw_configpcipowersave(ah, 0, 0); -- cgit v1.2.3 From 5048e8c378d095a548fe8a6ecd2f07d277ac5be2 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 31 Jan 2011 23:47:44 +0530 Subject: ath9k: move update tx power to common move ath_update_txpow to common to remove code duplication in both ath9k & ath9k_htc. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/common.c | 11 +++++++++++ drivers/net/wireless/ath/ath9k/common.h | 2 ++ drivers/net/wireless/ath/ath9k/main.c | 26 ++++++++++---------------- 3 files changed, 23 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index df1998d48253..615e68276e72 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c @@ -189,6 +189,17 @@ void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common, } EXPORT_SYMBOL(ath9k_cmn_btcoex_bt_stomp); +void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow, + u16 new_txpow, u16 *txpower) +{ + if (cur_txpow != new_txpow) { + ath9k_hw_set_txpowerlimit(ah, new_txpow, false); + /* read back in case value is clamped */ + *txpower = ath9k_hw_regulatory(ah)->power_limit; + } +} +EXPORT_SYMBOL(ath9k_cmn_update_txpow); + static int __init ath9k_cmn_init(void) { return 0; diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index 4c7020b3a5a0..b2f7b5f89097 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h @@ -68,3 +68,5 @@ struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw, int ath9k_cmn_count_streams(unsigned int chainmask, int max); void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common, enum ath_stomp_type stomp_type); +void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow, + u16 new_txpow, u16 *txpower); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 048eaef11f4a..09eb0265b312 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -18,17 +18,6 @@ #include "ath9k.h" #include "btcoex.h" -static void ath_update_txpow(struct ath_softc *sc) -{ - struct ath_hw *ah = sc->sc_ah; - - if (sc->curtxpow != sc->config.txpowlimit) { - ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false); - /* read back in case value is clamped */ - sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit; - } -} - static u8 parse_mpdudensity(u8 mpdudensity) { /* @@ -271,7 +260,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, goto ps_restore; } - ath_update_txpow(sc); + ath9k_cmn_update_txpow(ah, sc->curtxpow, + sc->config.txpowlimit, &sc->curtxpow); ath9k_hw_set_interrupts(ah, ah->imask); if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) { @@ -863,7 +853,8 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) channel->center_freq, r); } - ath_update_txpow(sc); + ath9k_cmn_update_txpow(ah, sc->curtxpow, + sc->config.txpowlimit, &sc->curtxpow); if (ath_startrecv(sc) != 0) { ath_err(common, "Unable to restart recv logic\n"); goto out; @@ -966,7 +957,8 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) * that changes the channel so update any state that * might change as a result. */ - ath_update_txpow(sc); + ath9k_cmn_update_txpow(ah, sc->curtxpow, + sc->config.txpowlimit, &sc->curtxpow); if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL))) ath_beacon_config(sc, NULL); /* restart beacons */ @@ -1042,7 +1034,8 @@ static int ath9k_start(struct ieee80211_hw *hw) * This is needed only to setup initial state * but it's best done after a reset. */ - ath_update_txpow(sc); + ath9k_cmn_update_txpow(ah, sc->curtxpow, + sc->config.txpowlimit, &sc->curtxpow); /* * Setup the hardware after reset: @@ -1707,7 +1700,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_POWER) { sc->config.txpowlimit = 2 * conf->power_level; ath9k_ps_wakeup(sc); - ath_update_txpow(sc); + ath9k_cmn_update_txpow(ah, sc->curtxpow, + sc->config.txpowlimit, &sc->curtxpow); ath9k_ps_restore(sc); } -- cgit v1.2.3 From b2a5c3dfecf3d0e1db08ac7cd94ee4c1cf9bc998 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 31 Jan 2011 23:47:45 +0530 Subject: ath9k_htc: make use common of function to update txpower Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 1 - drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | 3 ++- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 23 ++++++++--------------- 3 files changed, 10 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 63549868e686..0cb504d7b8c4 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -460,7 +460,6 @@ void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv); void ath9k_ps_work(struct work_struct *work); bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, enum ath9k_power_mode mode); -void ath_update_txpow(struct ath9k_htc_priv *priv); void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index fe70f67aa088..7e630a81b453 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -389,7 +389,8 @@ void ath9k_htc_radio_enable(struct ieee80211_hw *hw) ret, ah->curchan->channel); } - ath_update_txpow(priv); + ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit, + &priv->curtxpow); /* Start RX */ WMI_CMD(WMI_START_RECV_CMDID); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 0526c259a634..953036a4ed53 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -24,17 +24,6 @@ static struct dentry *ath9k_debugfs_root; /* Utilities */ /*************/ -void ath_update_txpow(struct ath9k_htc_priv *priv) -{ - struct ath_hw *ah = priv->ah; - - if (priv->curtxpow != priv->txpowlimit) { - ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit, false); - /* read back in case value is clamped */ - priv->curtxpow = ath9k_hw_regulatory(ah)->power_limit; - } -} - /* HACK Alert: Use 11NG for 2.4, use 11NA for 5 */ static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv, struct ath9k_channel *ichan) @@ -147,7 +136,8 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) channel->center_freq, ret); } - ath_update_txpow(priv); + ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit, + &priv->curtxpow); WMI_CMD(WMI_START_RECV_CMDID); ath9k_host_rx_init(priv); @@ -212,7 +202,8 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, goto err; } - ath_update_txpow(priv); + ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit, + &priv->curtxpow); WMI_CMD(WMI_START_RECV_CMDID); if (ret) @@ -988,7 +979,8 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) return ret; } - ath_update_txpow(priv); + ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit, + &priv->curtxpow); mode = ath9k_htc_get_curmode(priv, init_channel); htc_mode = cpu_to_be16(mode); @@ -1254,7 +1246,8 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_POWER) { priv->txpowlimit = 2 * conf->power_level; - ath_update_txpow(priv); + ath9k_cmn_update_txpow(priv->ah, priv->curtxpow, + priv->txpowlimit, &priv->curtxpow); } if (changed & IEEE80211_CONF_CHANGE_IDLE) { -- cgit v1.2.3 From 4c89fe954d929781126af41691fba1bc670293a5 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 31 Jan 2011 23:47:46 +0530 Subject: ath9k: do not access hw registers in FULL SLEEP The opmode recalculation is accessing hw registers. When it is called from remove interface callback and if there are no vifs present then hw is moved to FULL SLEEP by radio disable. So use power save wrappers before accessing hw registers in calculating opmode state. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 09eb0265b312..c9925e943bc0 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1354,6 +1354,7 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, ath9k_calculate_iter_data(hw, vif, &iter_data); + ath9k_ps_wakeup(sc); /* Set BSSID mask. */ memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); ath_hw_setbssidmask(common); @@ -1388,6 +1389,7 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, } ath9k_hw_set_interrupts(ah, ah->imask); + ath9k_ps_restore(sc); /* Set up ANI */ if ((iter_data.naps + iter_data.nadhocs) > 0) { -- cgit v1.2.3 From 4e6975f7b8ca31febaa94a1ee1acfb5322f8a82b Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Mon, 31 Jan 2011 10:37:36 -0800 Subject: ath9k: Show channel type and frequency in debugfs. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 9cdc41b0ec44..5cfcf8c235a4 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -381,21 +381,40 @@ static const struct file_operations fops_interrupt = { .llseek = default_llseek, }; +static const char *channel_type_str(enum nl80211_channel_type t) +{ + switch (t) { + case NL80211_CHAN_NO_HT: + return "no ht"; + case NL80211_CHAN_HT20: + return "ht20"; + case NL80211_CHAN_HT40MINUS: + return "ht40-"; + case NL80211_CHAN_HT40PLUS: + return "ht40+"; + default: + return "???"; + } +} + static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath_softc *sc = file->private_data; struct ieee80211_channel *chan = sc->hw->conf.channel; + struct ieee80211_conf *conf = &(sc->hw->conf); char buf[512]; unsigned int len = 0; u8 addr[ETH_ALEN]; u32 tmp; len += snprintf(buf + len, sizeof(buf) - len, - "%s (chan=%d ht=%d)\n", + "%s (chan=%d center-freq: %d MHz channel-type: %d (%s))\n", wiphy_name(sc->hw->wiphy), ieee80211_frequency_to_channel(chan->center_freq), - conf_is_ht(&sc->hw->conf)); + chan->center_freq, + conf->channel_type, + channel_type_str(conf->channel_type)); put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr); put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4); -- cgit v1.2.3 From 391bd1c443f70447616ce0e152f13daee5ca448f Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 1 Feb 2011 23:05:36 +0530 Subject: ath9k: reserve a beacon slot on beaconing vif addition The beaconing vif addition is based on max beacon slot available. So it is better to reserve a beacon slot on interface addition and let it be configured properly on bss_info change. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c9925e943bc0..e5c695d73025 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1419,9 +1419,7 @@ static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw, * there. */ error = ath_beacon_alloc(sc, vif); - if (error) - ath9k_reclaim_beacon(sc, vif); - else + if (!error) ath_beacon_config(sc, vif); } } -- cgit v1.2.3 From 942a84901b71f8ac1edb80c4b9db08441536a440 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Tue, 1 Feb 2011 21:06:21 -0800 Subject: drivers:net:ipw2100.c change a typo comamnd to command The below patch fixes a typo comamnd to command. Signed-off-by: Justin P. Mattock Signed-off-by: John W. Linville --- drivers/net/wireless/ipw2x00/ipw2100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 61915f371416..da60faee74fc 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -1397,7 +1397,7 @@ static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv) } /* - * Send the CARD_DISABLE_PHY_OFF comamnd to the card to disable it + * Send the CARD_DISABLE_PHY_OFF command to the card to disable it * * After disabling, if the card was associated, a STATUS_ASSN_LOST will be sent. * -- cgit v1.2.3 From 78841462d72fe7038cb7ea48adecc6fc395f2dc5 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 24 Jan 2011 17:51:22 +0200 Subject: serial: omap-serial: Enable the UART wake-up bits always OMAP can do also dynamic idling so wake-up enable register should be set also while system is running. If UART_OMAP_WER is not set, then for instance the RX activity cannot wake up the UART port that is sleeping. This RX wake-up feature was working when the 8250 driver was used instead of omap-serial. Reason for this is that the 8250 doesn't set the UART_OMAP_WER and then arch/arm/mach-omap2/pm34xx.c ends up saving and restoring the reset default which is the same than value OMAP_UART_WER_MOD_WKUP here. Fix this by moving the conditional UART_OMAP_WER write from serial_omap_pm into serial_omap_startup where wake-up bits are set unconditionally. Signed-off-by: Jarkko Nikula Cc: Govindraj.R Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 699b34446a55..763537943a53 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -520,6 +520,9 @@ static int serial_omap_startup(struct uart_port *port) up->ier = UART_IER_RLSI | UART_IER_RDI; serial_out(up, UART_IER, up->ier); + /* Enable module level wake up */ + serial_out(up, UART_OMAP_WER, OMAP_UART_WER_MOD_WKUP); + up->port_activity = jiffies; return 0; } @@ -827,9 +830,6 @@ serial_omap_pm(struct uart_port *port, unsigned int state, serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, UART_EFR, efr); serial_out(up, UART_LCR, 0); - /* Enable module level wake up */ - serial_out(up, UART_OMAP_WER, - (state != 0) ? OMAP_UART_WER_MOD_WKUP : 0); } static void serial_omap_release_port(struct uart_port *port) -- cgit v1.2.3 From 0a1f1a0b626d79071ee9fe91b7fcd28be6332677 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 24 Jan 2011 17:54:12 +0100 Subject: tty_ldisc: don't use flush_scheduled_work() flush_scheduled_work() is scheduled to be deprecated. Explicitly sync flush the used work items instead. Note that before this change, flush_scheduled_work() wouldn't have properly flushed tty->buf.work if it were on timer. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 4214d58276f7..c42f402db9ba 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -534,6 +534,19 @@ static int tty_ldisc_halt(struct tty_struct *tty) return cancel_delayed_work_sync(&tty->buf.work); } +/** + * tty_ldisc_flush_works - flush all works of a tty + * @tty: tty device to flush works for + * + * Sync flush all works belonging to @tty. + */ +static void tty_ldisc_flush_works(struct tty_struct *tty) +{ + flush_work_sync(&tty->hangup_work); + flush_work_sync(&tty->SAK_work); + flush_delayed_work_sync(&tty->buf.work); +} + /** * tty_ldisc_wait_idle - wait for the ldisc to become idle * @tty: tty to wait for @@ -653,7 +666,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) mutex_unlock(&tty->ldisc_mutex); - flush_scheduled_work(); + tty_ldisc_flush_works(tty); retval = tty_ldisc_wait_idle(tty); @@ -905,7 +918,7 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) tty_unlock(); tty_ldisc_halt(tty); - flush_scheduled_work(); + tty_ldisc_flush_works(tty); tty_lock(); mutex_lock(&tty->ldisc_mutex); -- cgit v1.2.3 From d8653d305ef66861c91fa7455fb8038460a7274c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 25 Jan 2011 14:15:11 +0000 Subject: serial: mrst_max3110: make buffer larger This is used to store the spi_device ->modalias so they have to be the same size. SPI_NAME_SIZE is 32. Signed-off-by: Dan Carpenter Signed-off-by: Alan Cox Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mrst_max3110.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index b62857bf2fdb..37e13c3d91d9 100644 --- a/drivers/tty/serial/mrst_max3110.c +++ b/drivers/tty/serial/mrst_max3110.c @@ -51,7 +51,7 @@ struct uart_max3110 { struct uart_port port; struct spi_device *spi; - char name[24]; + char name[SPI_NAME_SIZE]; wait_queue_head_t wq; struct task_struct *main_thread; -- cgit v1.2.3 From 5933a161abcb8d83a2c145177f48027c3c0a8995 Mon Sep 17 00:00:00 2001 From: Yin Kangkai Date: Sun, 30 Jan 2011 11:15:30 +0800 Subject: serial-core: reset the console speed on resume On some platforms, we need to restore the console speed on resume even it was not suspended (no_console_suspend), and on others we don't have to do that. So don't care about the "console_suspend_enabled" and unconditionally reset the console speed if it is a console. This is actually a redo of ba15ab0 (Set proper console speed on resume if console suspend is disabled) from Deepak Saxena. I also tried to investigate more to find out if this change will break others, here is what I've found out: commit 891b9dd10764352926e1e107756aa229dfa2c210 Author: Jason Wang serial-core: restore termios settings when resume console ports commit ca2e71aa8cfb0056ce720f3fd53f59f5fac4a3e1 Author: Jason Wang serial-core: skip call set_termios/console_start when no_console_suspend commit 4547be7809a3b775ce750ec7f8b5748954741523 Author: Stanislav Brabec serial-core: resume serial hardware with no_console_suspend commit ba15ab0e8de0d4439a91342ad52d55ca9e313f3d Author: Deepak Saxena Set proper console speed on resume if console suspend is disabled from ba15ab0, we learned that, even if the console suspend is disabled (when no_console_suspend is set), we may still need to "reset the port to the state it was in before we suspended." Then with 4547be7, this piece of code is removed. And then Jason Wang added that back in ca2e71a and 891b9dd, to fix some breakage on OMAP3EVM platform. From ca2e71a we learned that the "set_termios" things is actually needed by both console is suspended and not suspended. That's why I removed the console_suspended_enabled condition, and only call console_start() when we actually suspeneded it. I also noticed in this thread: http://marc.info/?t=129079257100004&r=1&w=2, which talked about on some platforms, UART HW will be cut power whether or not we set no_console_suspend, and then on resume it does not work quite well. I have a similar HW, and this patch fixed this issue, don't know if this patch also works on their platforms. [Update: Stanislav tested this patch on Zaurus and reported it improves the situation. Thanks.] CC: Greg KH CC: Deepak Saxena CC: Jason Wang CC: Stanislav Brabec CC: Daniel Drake Signed-off-by: Yin Kangkai Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 460a72d91bb7..20563c509b21 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2064,7 +2064,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) /* * Re-enable the console device after suspending. */ - if (console_suspend_enabled && uart_console(uport)) { + if (uart_console(uport)) { /* * First try to use the console cflag setting. */ @@ -2077,9 +2077,9 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) if (port->tty && port->tty->termios && termios.c_cflag == 0) termios = *(port->tty->termios); - uart_change_pm(state, 0); uport->ops->set_termios(uport, &termios, NULL); - console_start(uport->cons); + if (console_suspend_enabled) + console_start(uport->cons); } if (port->flags & ASYNC_SUSPENDED) { -- cgit v1.2.3 From f094298bae5f5d0e1cb3bff4621aae7ef486812a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 24 Jan 2011 17:53:41 +0100 Subject: 68328serial: remove unsed m68k_serial->tqueue_hangup m68k_serial->tqueue_hangup is unused. Remove it. Signed-off-by: Tejun Heo Cc: Greg Ungerer Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/68328serial.c | 23 ----------------------- drivers/tty/serial/68328serial.h | 1 - 2 files changed, 24 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index be0ebce36e54..a9d99856c892 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c @@ -393,28 +393,6 @@ static void do_softint(struct work_struct *work) #endif } -/* - * This routine is called from the scheduler tqueue when the interrupt - * routine has signalled that a hangup has occurred. The path of - * hangup processing is: - * - * serial interrupt routine -> (scheduler tqueue) -> - * do_serial_hangup() -> tty->hangup() -> rs_hangup() - * - */ -static void do_serial_hangup(struct work_struct *work) -{ - struct m68k_serial *info = container_of(work, struct m68k_serial, tqueue_hangup); - struct tty_struct *tty; - - tty = info->port.tty; - if (!tty) - return; - - tty_hangup(tty); -} - - static int startup(struct m68k_serial * info) { m68328_uart *uart = &uart_addr[info->line]; @@ -1348,7 +1326,6 @@ rs68328_init(void) info->count = 0; info->blocked_open = 0; INIT_WORK(&info->tqueue, do_softint); - INIT_WORK(&info->tqueue_hangup, do_serial_hangup); init_waitqueue_head(&info->open_wait); init_waitqueue_head(&info->close_wait); info->line = i; diff --git a/drivers/tty/serial/68328serial.h b/drivers/tty/serial/68328serial.h index 664ceb0a158c..8c9c3c0745db 100644 --- a/drivers/tty/serial/68328serial.h +++ b/drivers/tty/serial/68328serial.h @@ -159,7 +159,6 @@ struct m68k_serial { int xmit_tail; int xmit_cnt; struct work_struct tqueue; - struct work_struct tqueue_hangup; wait_queue_head_t open_wait; wait_queue_head_t close_wait; }; -- cgit v1.2.3 From 4564e1ef219fa69ed827fe2613569543a6b26fbc Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Fri, 28 Jan 2011 18:00:01 +0900 Subject: serial: pch_uart: support new device ML7213 Support ML7213 device of OKI SEMICONDUCTOR. ML7213 is companion chip of Intel Atom E6xx series for IVI(In-Vehicle Infotainment). ML7213 is completely compatible for Intel EG20T PCH. Signed-off-by: Tomoya MORINAGA Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 5 +++++ drivers/tty/serial/pch_uart.c | 27 +++++++++++++++++++-------- 2 files changed, 24 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 2b8334601c8b..86e2c994d440 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1596,4 +1596,9 @@ config SERIAL_PCH_UART This driver is for PCH(Platform controller Hub) UART of Intel EG20T which is an IOH(Input/Output Hub) for x86 embedded processor. Enabling PCH_DMA, this PCH UART works as DMA mode. + + This driver also can be used for OKI SEMICONDUCTOR ML7213 IOH(Input/ + Output Hub) which is for IVI(In-Vehicle Infotainment) use. + ML7213 is companion chip for Intel Atom E6xx series. + ML7213 is completely compatible for Intel EG20T PCH. endmenu diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 70a61458ec42..3b2fb93e1fa1 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -40,10 +40,11 @@ enum { #define PCH_UART_DRIVER_DEVICE "ttyPCH" -#define PCH_UART_NR_GE_256FIFO 1 -#define PCH_UART_NR_GE_64FIFO 3 -#define PCH_UART_NR_GE (PCH_UART_NR_GE_256FIFO+PCH_UART_NR_GE_64FIFO) -#define PCH_UART_NR PCH_UART_NR_GE +/* Set the max number of UART port + * Intel EG20T PCH: 4 port + * OKI SEMICONDUCTOR ML7213 IOH: 3 port +*/ +#define PCH_UART_NR 4 #define PCH_UART_HANDLED_RX_INT (1<<((PCH_UART_HANDLED_RX_INT_SHIFT)<<1)) #define PCH_UART_HANDLED_TX_INT (1<<((PCH_UART_HANDLED_TX_INT_SHIFT)<<1)) @@ -192,6 +193,8 @@ enum { #define PCH_UART_HAL_LOOP (PCH_UART_MCR_LOOP) #define PCH_UART_HAL_AFE (PCH_UART_MCR_AFE) +#define PCI_VENDOR_ID_ROHM 0x10DB + struct pch_uart_buffer { unsigned char *buf; int size; @@ -1249,7 +1252,7 @@ static struct uart_driver pch_uart_driver = { }; static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, - int port_type) + const struct pci_device_id *id) { struct eg20t_port *priv; int ret; @@ -1258,6 +1261,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, unsigned char *rxbuf; int fifosize, base_baud; static int num; + int port_type = id->driver_data; priv = kzalloc(sizeof(struct eg20t_port), GFP_KERNEL); if (priv == NULL) @@ -1269,11 +1273,11 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, switch (port_type) { case PORT_UNKNOWN: - fifosize = 256; /* UART0 */ + fifosize = 256; /* EG20T/ML7213: UART0 */ base_baud = 1843200; /* 1.8432MHz */ break; case PORT_8250: - fifosize = 64; /* UART1~3 */ + fifosize = 64; /* EG20T:UART1~3 ML7213: UART1~2*/ base_baud = 1843200; /* 1.8432MHz */ break; default: @@ -1307,6 +1311,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, pci_set_drvdata(pdev, priv); pch_uart_hal_request(pdev, fifosize, base_baud); + ret = uart_add_one_port(&pch_uart_driver, &priv->port); if (ret < 0) goto init_port_hal_free; @@ -1384,6 +1389,12 @@ static DEFINE_PCI_DEVICE_TABLE(pch_uart_pci_id) = { .driver_data = PCH_UART_2LINE}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8814), .driver_data = PCH_UART_2LINE}, + {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8027), + .driver_data = PCH_UART_8LINE}, + {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8028), + .driver_data = PCH_UART_2LINE}, + {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8029), + .driver_data = PCH_UART_2LINE}, {0,}, }; @@ -1397,7 +1408,7 @@ static int __devinit pch_uart_pci_probe(struct pci_dev *pdev, if (ret < 0) goto probe_error; - priv = pch_uart_init_port(pdev, id->driver_data); + priv = pch_uart_init_port(pdev, id); if (!priv) { ret = -EBUSY; goto probe_disable_device; -- cgit v1.2.3 From 380042f2db653b324ae756d102d872c1ecd412c5 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Fri, 28 Jan 2011 18:00:02 +0900 Subject: serial: pch_uart: revert Kconfig for non-DMA mode PCH_DMA is not always enabled when a user uses PCH_UART. Since overhead of DMA is not small, in case of low frequent communication, without DMA is better. Thus, "select PCH_DMA" and DMADEVICES are unnecessary Signed-off-by: Tomoya MORINAGA Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 86e2c994d440..aaedbad93a75 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1588,10 +1588,9 @@ config SERIAL_IFX6X60 Support for the IFX6x60 modem devices on Intel MID platforms. config SERIAL_PCH_UART - tristate "Intel EG20T PCH UART" - depends on PCI && DMADEVICES + tristate "Intel EG20T PCH UART/OKI SEMICONDUCTOR ML7213 IOH" + depends on PCI select SERIAL_CORE - select PCH_DMA help This driver is for PCH(Platform controller Hub) UART of Intel EG20T which is an IOH(Input/Output Hub) for x86 embedded processor. -- cgit v1.2.3 From a5462516aa9942bd68c8769d4bcefa8a7c718300 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Mon, 13 Dec 2010 14:08:52 -0600 Subject: driver-core: document restrictions on device_rename() Add text, courtesy of Kay Sievers, that provides some background on device_rename() and why it shouldn't be used. Signed-off-by: Timur Tabi Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/core.c b/drivers/base/core.c index 080e9ca11017..9cd3b5cfcc42 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1551,7 +1551,34 @@ EXPORT_SYMBOL_GPL(device_destroy); * on the same device to ensure that new_name is valid and * won't conflict with other devices. * - * "Never use this function, bad things will happen" - gregkh + * Note: Don't call this function. Currently, the networking layer calls this + * function, but that will change. The following text from Kay Sievers offers + * some insight: + * + * Renaming devices is racy at many levels, symlinks and other stuff are not + * replaced atomically, and you get a "move" uevent, but it's not easy to + * connect the event to the old and new device. Device nodes are not renamed at + * all, there isn't even support for that in the kernel now. + * + * In the meantime, during renaming, your target name might be taken by another + * driver, creating conflicts. Or the old name is taken directly after you + * renamed it -- then you get events for the same DEVPATH, before you even see + * the "move" event. It's just a mess, and nothing new should ever rely on + * kernel device renaming. Besides that, it's not even implemented now for + * other things than (driver-core wise very simple) network devices. + * + * We are currently about to change network renaming in udev to completely + * disallow renaming of devices in the same namespace as the kernel uses, + * because we can't solve the problems properly, that arise with swapping names + * of multiple interfaces without races. Means, renaming of eth[0-9]* will only + * be allowed to some other name than eth[0-9]*, for the aforementioned + * reasons. + * + * Make up a "real" name in the driver before you register anything, or add + * some other attributes for userspace to find the device, or use udev to add + * symlinks -- but never rename kernel devices later, it's a complete mess. We + * don't even want to get into that and try to implement the missing pieces in + * the core. We really have other pieces to fix in the driver core mess. :) */ int device_rename(struct device *dev, const char *new_name) { -- cgit v1.2.3 From 072fc8f0a8df9bf36392f15b729044cb2ad27332 Mon Sep 17 00:00:00 2001 From: Bob Liu Date: Wed, 26 Jan 2011 18:33:32 +0800 Subject: firmware_classs: change val uevent's type to bool Some place in firmware_class.c using "int uevent" define, but others use "bool uevent". This patch replace all int uevent define to bool. Signed-off-by: Bob Liu Acked-by: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 7 +++---- include/linux/firmware.h | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 40af43ebd92d..8c798ef7f13f 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -593,8 +593,7 @@ int request_firmware(const struct firmware **firmware_p, const char *name, struct device *device) { - int uevent = 1; - return _request_firmware(firmware_p, name, device, uevent, false); + return _request_firmware(firmware_p, name, device, true, false); } /** @@ -618,7 +617,7 @@ struct firmware_work { struct device *device; void *context; void (*cont)(const struct firmware *fw, void *context); - int uevent; + bool uevent; }; static int request_firmware_work_func(void *arg) @@ -661,7 +660,7 @@ static int request_firmware_work_func(void *arg) **/ int request_firmware_nowait( - struct module *module, int uevent, + struct module *module, bool uevent, const char *name, struct device *device, gfp_t gfp, void *context, void (*cont)(const struct firmware *fw, void *context)) { diff --git a/include/linux/firmware.h b/include/linux/firmware.h index 53d1e6c4f848..21b3e7588abd 100644 --- a/include/linux/firmware.h +++ b/include/linux/firmware.h @@ -39,7 +39,7 @@ struct builtin_fw { int request_firmware(const struct firmware **fw, const char *name, struct device *device); int request_firmware_nowait( - struct module *module, int uevent, + struct module *module, bool uevent, const char *name, struct device *device, gfp_t gfp, void *context, void (*cont)(const struct firmware *fw, void *context)); @@ -52,7 +52,7 @@ static inline int request_firmware(const struct firmware **fw, return -EINVAL; } static inline int request_firmware_nowait( - struct module *module, int uevent, + struct module *module, bool uevent, const char *name, struct device *device, gfp_t gfp, void *context, void (*cont)(const struct firmware *fw, void *context)) { -- cgit v1.2.3 From 345279bc105e5a331ee81b0e8446b61f2c155784 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 1 Feb 2011 17:19:57 +0100 Subject: sysdev: Fixup warning message Use gcc's __func__ instead of the function name. Signed-off-by: Borislav Petkov Signed-off-by: Greg Kroah-Hartman --- drivers/base/sys.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 1667aaf4fde6..b094e0d6139f 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -181,8 +181,8 @@ int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv) int err = 0; if (!cls) { - WARN(1, KERN_WARNING "sysdev: invalid class passed to " - "sysdev_driver_register!\n"); + WARN(1, KERN_WARNING "sysdev: invalid class passed to %s!\n", + __func__); return -EINVAL; } -- cgit v1.2.3 From f4203e3032e5ae74c3e89df85a5a6d96022d0c49 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 1 Feb 2011 17:19:56 +0100 Subject: sysdev: Do not register with sysdev when erroring on add When encountering an error while executing the driver's ->add method, we should cancel registration and unwind what we've regged so far. The low level ->add methods do return proper error codes but those aren't looked at in sysdev_driver_register(). Fix that by sharing the unregistering code. Signed-off-by: Borislav Petkov Signed-off-by: Greg Kroah-Hartman --- drivers/base/sys.c | 61 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/base/sys.c b/drivers/base/sys.c index b094e0d6139f..f6fb54741602 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -166,6 +166,36 @@ EXPORT_SYMBOL_GPL(sysdev_class_unregister); static DEFINE_MUTEX(sysdev_drivers_lock); +/* + * @dev != NULL means that we're unwinding because some drv->add() + * failed for some reason. You need to grab sysdev_drivers_lock before + * calling this. + */ +static void __sysdev_driver_remove(struct sysdev_class *cls, + struct sysdev_driver *drv, + struct sys_device *from_dev) +{ + struct sys_device *dev = from_dev; + + list_del_init(&drv->entry); + if (!cls) + return; + + if (!drv->remove) + goto kset_put; + + if (dev) + list_for_each_entry_continue_reverse(dev, &cls->kset.list, + kobj.entry) + drv->remove(dev); + else + list_for_each_entry(dev, &cls->kset.list, kobj.entry) + drv->remove(dev); + +kset_put: + kset_put(&cls->kset); +} + /** * sysdev_driver_register - Register auxillary driver * @cls: Device class driver belongs to. @@ -175,9 +205,9 @@ static DEFINE_MUTEX(sysdev_drivers_lock); * called on each operation on devices of that class. The refcount * of @cls is incremented. */ - int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv) { + struct sys_device *dev = NULL; int err = 0; if (!cls) { @@ -198,19 +228,27 @@ int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv) /* If devices of this class already exist, tell the driver */ if (drv->add) { - struct sys_device *dev; - list_for_each_entry(dev, &cls->kset.list, kobj.entry) - drv->add(dev); + list_for_each_entry(dev, &cls->kset.list, kobj.entry) { + err = drv->add(dev); + if (err) + goto unwind; + } } } else { err = -EINVAL; WARN(1, KERN_ERR "%s: invalid device class\n", __func__); } + + goto unlock; + +unwind: + __sysdev_driver_remove(cls, drv, dev); + +unlock: mutex_unlock(&sysdev_drivers_lock); return err; } - /** * sysdev_driver_unregister - Remove an auxillary driver. * @cls: Class driver belongs to. @@ -220,23 +258,12 @@ void sysdev_driver_unregister(struct sysdev_class *cls, struct sysdev_driver *drv) { mutex_lock(&sysdev_drivers_lock); - list_del_init(&drv->entry); - if (cls) { - if (drv->remove) { - struct sys_device *dev; - list_for_each_entry(dev, &cls->kset.list, kobj.entry) - drv->remove(dev); - } - kset_put(&cls->kset); - } + __sysdev_driver_remove(cls, drv, NULL); mutex_unlock(&sysdev_drivers_lock); } - EXPORT_SYMBOL_GPL(sysdev_driver_register); EXPORT_SYMBOL_GPL(sysdev_driver_unregister); - - /** * sysdev_register - add a system device to the tree * @sysdev: device in question -- cgit v1.2.3 From c47dda7d179dde17697c3f839f150fecaf6770cb Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Wed, 22 Dec 2010 21:04:11 +0900 Subject: pch_phub: add new device ML7213 Add ML7213 device information. ML7213 is companion chip of Intel Atom E6xx series for IVI(In-Vehicle Infotainment). ML7213 is completely compatible for Intel EG20T PCH. Signed-off-by: Tomoya MORINAGA Signed-off-by: Greg Kroah-Hartman --- drivers/misc/Kconfig | 7 ++++- drivers/misc/pch_phub.c | 69 +++++++++++++++++++++++++++++++++---------------- 2 files changed, 53 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index cc8e49db45fe..b7d5ef234ac9 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -441,7 +441,7 @@ config BMP085 module will be called bmp085. config PCH_PHUB - tristate "PCH Packet Hub of Intel Topcliff" + tristate "PCH Packet Hub of Intel Topcliff / OKI SEMICONDUCTOR ML7213" depends on PCI help This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of @@ -449,6 +449,11 @@ config PCH_PHUB processor. The Topcliff has MAC address and Option ROM data in SROM. This driver can access MAC address and Option ROM data in SROM. + This driver also can be used for OKI SEMICONDUCTOR's ML7213 which is + for IVI(In-Vehicle Infotainment) use. + ML7213 is companion chip for Intel Atom E6xx series. + ML7213 is completely compatible for Intel EG20T PCH. + To compile this driver as a module, choose M here: the module will be called pch_phub. diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c index 744b804aca15..98bffc471b17 100644 --- a/drivers/misc/pch_phub.c +++ b/drivers/misc/pch_phub.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,7 +33,12 @@ #define PHUB_TIMEOUT 0x05 /* Time out value for Status Register */ #define PCH_PHUB_ROM_WRITE_ENABLE 0x01 /* Enabling for writing ROM */ #define PCH_PHUB_ROM_WRITE_DISABLE 0x00 /* Disabling for writing ROM */ -#define PCH_PHUB_ROM_START_ADDR 0x14 /* ROM data area start address offset */ +#define PCH_PHUB_MAC_START_ADDR 0x20C /* MAC data area start address offset */ +#define PCH_PHUB_ROM_START_ADDR_EG20T 0x14 /* ROM data area start address offset + (Intel EG20T PCH)*/ +#define PCH_PHUB_ROM_START_ADDR_ML7213 0x400 /* ROM data area start address + offset(OKI SEMICONDUCTOR ML7213) + */ /* MAX number of INT_REDUCE_CONTROL registers */ #define MAX_NUM_INT_REDUCE_CONTROL_REG 128 @@ -42,6 +47,10 @@ #define CLKCFG_CAN_50MHZ 0x12000000 #define CLKCFG_CANCLK_MASK 0xFF000000 +/* Macros for ML7213 */ +#define PCI_VENDOR_ID_ROHM 0x10db +#define PCI_DEVICE_ID_ROHM_ML7213_PHUB 0x801A + /* SROM ACCESS Macro */ #define PCH_WORD_ADDR_MASK (~((1 << 2) - 1)) @@ -298,7 +307,7 @@ static void pch_phub_read_serial_rom_val(struct pch_phub_reg *chip, { unsigned int mem_addr; - mem_addr = PCH_PHUB_ROM_START_ADDR + + mem_addr = PCH_PHUB_ROM_START_ADDR_EG20T + pch_phub_mac_offset[offset_address]; pch_phub_read_serial_rom(chip, mem_addr, data); @@ -315,7 +324,7 @@ static int pch_phub_write_serial_rom_val(struct pch_phub_reg *chip, int retval; unsigned int mem_addr; - mem_addr = PCH_PHUB_ROM_START_ADDR + + mem_addr = PCH_PHUB_ROM_START_ADDR_EG20T + pch_phub_mac_offset[offset_address]; retval = pch_phub_write_serial_rom(chip, mem_addr, data); @@ -594,23 +603,38 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev, "pch_phub_extrom_base_address variable is %p\n", __func__, chip->pch_phub_extrom_base_address); - pci_set_drvdata(pdev, chip); - - retval = sysfs_create_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); - if (retval) - goto err_sysfs_create; - - retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); - if (retval) - goto exit_bin_attr; - - pch_phub_read_modify_write_reg(chip, (unsigned int)CLKCFG_REG_OFFSET, - CLKCFG_CAN_50MHZ, CLKCFG_CANCLK_MASK); + if (id->driver_data == 1) { + retval = sysfs_create_file(&pdev->dev.kobj, + &dev_attr_pch_mac.attr); + if (retval) + goto err_sysfs_create; - /* set the prefech value */ - iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14); - /* set the interrupt delay value */ - iowrite32(0x25, chip->pch_phub_base_address + 0x44); + retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); + if (retval) + goto exit_bin_attr; + + pch_phub_read_modify_write_reg(chip, + (unsigned int)CLKCFG_REG_OFFSET, + CLKCFG_CAN_50MHZ, + CLKCFG_CANCLK_MASK); + + /* set the prefech value */ + iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14); + /* set the interrupt delay value */ + iowrite32(0x25, chip->pch_phub_base_address + 0x44); + } else if (id->driver_data == 2) { + retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); + if (retval) + goto err_sysfs_create; + /* set the prefech value + * Device2(USB OHCI #1/ USB EHCI #1/ USB Device):a + * Device4(SDIO #0,1,2):f + * Device6(SATA 2):f + * Device8(USB OHCI #0/ USB EHCI #0):a + */ + iowrite32(0x000affa0, chip->pch_phub_base_address + 0x14); + } + pci_set_drvdata(pdev, chip); return 0; exit_bin_attr: @@ -687,8 +711,9 @@ static int pch_phub_resume(struct pci_dev *pdev) #endif /* CONFIG_PM */ static struct pci_device_id pch_phub_pcidev_id[] = { - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH1_PHUB)}, - {0,} + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH1_PHUB), 1, }, + { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2, }, + { } }; static struct pci_driver pch_phub_driver = { -- cgit v1.2.3 From 25a54a6bb87dc966f6a3fc1f2ac6e88db1f5614c Mon Sep 17 00:00:00 2001 From: Maciej Sosnowski Date: Thu, 3 Feb 2011 15:55:26 -0800 Subject: RDMA/nes: Don't generate async events for unregistered devices nes_port_ibevent() should not be called when the nes RDMA device is not registered with the RDMA core. Add missing checks of of_device_registered flag. Signed-off-by: Maciej Sosnowski Signed-off-by: Roland Dreier --- drivers/infiniband/hw/nes/nes_hw.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 8b606fd64022..08c194861af5 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -2610,9 +2610,11 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) netif_carrier_on(nesvnic->netdev); spin_lock(&nesvnic->port_ibevent_lock); - if (nesdev->iw_status == 0) { - nesdev->iw_status = 1; - nes_port_ibevent(nesvnic); + if (nesvnic->of_device_registered) { + if (nesdev->iw_status == 0) { + nesdev->iw_status = 1; + nes_port_ibevent(nesvnic); + } } spin_unlock(&nesvnic->port_ibevent_lock); } @@ -2642,9 +2644,11 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) netif_carrier_off(nesvnic->netdev); spin_lock(&nesvnic->port_ibevent_lock); - if (nesdev->iw_status == 1) { - nesdev->iw_status = 0; - nes_port_ibevent(nesvnic); + if (nesvnic->of_device_registered) { + if (nesdev->iw_status == 1) { + nesdev->iw_status = 0; + nes_port_ibevent(nesvnic); + } } spin_unlock(&nesvnic->port_ibevent_lock); } @@ -2703,9 +2707,11 @@ void nes_recheck_link_status(struct work_struct *work) netif_carrier_on(nesvnic->netdev); spin_lock(&nesvnic->port_ibevent_lock); - if (nesdev->iw_status == 0) { - nesdev->iw_status = 1; - nes_port_ibevent(nesvnic); + if (nesvnic->of_device_registered) { + if (nesdev->iw_status == 0) { + nesdev->iw_status = 1; + nes_port_ibevent(nesvnic); + } } spin_unlock(&nesvnic->port_ibevent_lock); } @@ -2723,9 +2729,11 @@ void nes_recheck_link_status(struct work_struct *work) netif_carrier_off(nesvnic->netdev); spin_lock(&nesvnic->port_ibevent_lock); - if (nesdev->iw_status == 1) { - nesdev->iw_status = 0; - nes_port_ibevent(nesvnic); + if (nesvnic->of_device_registered) { + if (nesdev->iw_status == 1) { + nesdev->iw_status = 0; + nes_port_ibevent(nesvnic); + } } spin_unlock(&nesvnic->port_ibevent_lock); } -- cgit v1.2.3 From a99632014631409483a481a6a0d77d09ded47239 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 3 Feb 2011 15:48:34 -0800 Subject: hvc_dcc: Fix bad code generation by marking assembly volatile Without marking the asm __dcc_getstatus() volatile my compiler decides it can cache the value of __ret in a register and then check the value of it continually in hvc_dcc_put_chars() (I had to replace get_wait/put_wait with 1 and fixup the branch otherwise my disassembler barfed on __dcc_(get|put)char). 00000000 : 0: ee103e11 mrc 14, 0, r3, cr0, cr1, {0} 4: e3a0c000 mov ip, #0 ; 0x0 8: e2033202 and r3, r3, #536870912 ; 0x20000000 c: ea000006 b 2c 10: e3530000 cmp r3, #0 ; 0x0 14: 1afffffd bne 10 18: e7d1000c ldrb r0, [r1, ip] 1c: ee10fe11 mrc 14, 0, pc, cr0, cr1, {0} 20: 2afffffd bcs 1c 24: ee000e15 mcr 14, 0, r0, cr0, cr5, {0} 28: e28cc001 add ip, ip, #1 ; 0x1 2c: e15c0002 cmp ip, r2 30: bafffff6 blt 10 34: e1a00002 mov r0, r2 38: e12fff1e bx lr As you can see, the value of the mrc is checked against DCC_STATUS_TX (bit 29) and then stored in r3 for later use. Marking the asm volatile produces the following: 00000000 : 0: e3a03000 mov r3, #0 ; 0x0 4: ea000007 b 28 8: ee100e11 mrc 14, 0, r0, cr0, cr1, {0} c: e3100202 tst r0, #536870912 ; 0x20000000 10: 1afffffc bne 8 14: e7d10003 ldrb r0, [r1, r3] 18: ee10fe11 mrc 14, 0, pc, cr0, cr1, {0} 1c: 2afffffd bcs 18 20: ee000e15 mcr 14, 0, r0, cr0, cr5, {0} 24: e2833001 add r3, r3, #1 ; 0x1 28: e1530002 cmp r3, r2 2c: bafffff5 blt 8 30: e1a00002 mov r0, r2 34: e12fff1e bx lr which looks better and actually works. Mark all the inline assembly in this file as volatile since we don't want the compiler to optimize away these statements or move them around in any way. Acked-by: Tony Lindgren Cc: Arnd Bergmann Acked-by: Nicolas Pitre Cc: Daniel Walker Signed-off-by: Stephen Boyd Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvc_dcc.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/hvc/hvc_dcc.c b/drivers/tty/hvc/hvc_dcc.c index 6470f63deb4b..155ec105e1c8 100644 --- a/drivers/tty/hvc/hvc_dcc.c +++ b/drivers/tty/hvc/hvc_dcc.c @@ -33,8 +33,7 @@ static inline u32 __dcc_getstatus(void) { u32 __ret; - - asm("mrc p14, 0, %0, c0, c1, 0 @ read comms ctrl reg" + asm volatile("mrc p14, 0, %0, c0, c1, 0 @ read comms ctrl reg" : "=r" (__ret) : : "cc"); return __ret; @@ -46,7 +45,7 @@ static inline char __dcc_getchar(void) { char __c; - asm("get_wait: mrc p14, 0, pc, c0, c1, 0 \n\ + asm volatile("get_wait: mrc p14, 0, pc, c0, c1, 0 \n\ bne get_wait \n\ mrc p14, 0, %0, c0, c5, 0 @ read comms data reg" : "=r" (__c) : : "cc"); @@ -58,7 +57,7 @@ static inline char __dcc_getchar(void) { char __c; - asm("mrc p14, 0, %0, c0, c5, 0 @ read comms data reg" + asm volatile("mrc p14, 0, %0, c0, c5, 0 @ read comms data reg" : "=r" (__c)); return __c; @@ -68,7 +67,7 @@ static inline char __dcc_getchar(void) #if defined(CONFIG_CPU_V7) static inline void __dcc_putchar(char c) { - asm("put_wait: mrc p14, 0, pc, c0, c1, 0 \n\ + asm volatile("put_wait: mrc p14, 0, pc, c0, c1, 0 \n\ bcs put_wait \n\ mcr p14, 0, %0, c0, c5, 0 " : : "r" (c) : "cc"); @@ -76,7 +75,7 @@ static inline void __dcc_putchar(char c) #else static inline void __dcc_putchar(char c) { - asm("mcr p14, 0, %0, c0, c5, 0 @ write a char" + asm volatile("mcr p14, 0, %0, c0, c5, 0 @ write a char" : /* no output register */ : "r" (c)); } -- cgit v1.2.3 From bf73bd35a296b31dace098b9104b6b593ee0070f Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 3 Feb 2011 15:48:35 -0800 Subject: hvc_dcc: Simplify put_chars()/get_chars() loops Casting and anding with 0xff is unnecessary in hvc_dcc_put_chars() since buf is already a char[]. __dcc_get_char() can't return an int less than 0 since it only returns a char. Simplify the if statement in hvc_dcc_get_chars() to take this into account. Cc: Daniel Walker Signed-off-by: Stephen Boyd Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvc_dcc.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/hvc/hvc_dcc.c b/drivers/tty/hvc/hvc_dcc.c index 155ec105e1c8..ad23cc8082a0 100644 --- a/drivers/tty/hvc/hvc_dcc.c +++ b/drivers/tty/hvc/hvc_dcc.c @@ -89,7 +89,7 @@ static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count) while (__dcc_getstatus() & DCC_STATUS_TX) cpu_relax(); - __dcc_putchar((char)(buf[i] & 0xFF)); + __dcc_putchar(buf[i]); } return count; @@ -99,15 +99,11 @@ static int hvc_dcc_get_chars(uint32_t vt, char *buf, int count) { int i; - for (i = 0; i < count; ++i) { - int c = -1; - + for (i = 0; i < count; ++i) if (__dcc_getstatus() & DCC_STATUS_RX) - c = __dcc_getchar(); - if (c < 0) + buf[i] = __dcc_getchar(); + else break; - buf[i] = c; - } return i; } -- cgit v1.2.3 From 8e6d3fe1af38bea3f6c003f8737d2e3a02d00fa0 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 3 Feb 2011 15:48:36 -0800 Subject: hvc_dcc: Simplify assembly for v6 and v7 ARM The inline assembly differences for v6 vs. v7 in the hvc_dcc driver are purely optimizations. On a v7 processor, an mrc with the pc sets the condition codes to the 28-31 bits of the register being read. It just so happens that the TX/RX full bits the DCC driver is testing for are high enough in the register to be put into the condition codes. On a v6 processor, this "feature" isn't implemented and thus we have to do the usual read, mask, test operations to check for TX/RX full. Since we already test the RX/TX full bits before calling __dcc_getchar() and __dcc_putchar() we don't actually need to do anything special for v7 over v6. The only difference is in hvc_dcc_get_chars(). We would test RX full, poll RX full, and then read a character from the buffer, whereas now we will test RX full, read a character from the buffer, and then test RX full again for the second iteration of the loop. It doesn't seem possible for the buffer to go from full to empty between testing the RX full and reading a character. Therefore, replace the v7 versions with the v6 versions and everything works the same. Acked-by: Tony Lindgren Cc: Arnd Bergmann Acked-by: Nicolas Pitre Cc: Daniel Walker Signed-off-by: Stephen Boyd Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvc_dcc.c | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/hvc/hvc_dcc.c b/drivers/tty/hvc/hvc_dcc.c index ad23cc8082a0..435f6facbc23 100644 --- a/drivers/tty/hvc/hvc_dcc.c +++ b/drivers/tty/hvc/hvc_dcc.c @@ -40,19 +40,6 @@ static inline u32 __dcc_getstatus(void) } -#if defined(CONFIG_CPU_V7) -static inline char __dcc_getchar(void) -{ - char __c; - - asm volatile("get_wait: mrc p14, 0, pc, c0, c1, 0 \n\ - bne get_wait \n\ - mrc p14, 0, %0, c0, c5, 0 @ read comms data reg" - : "=r" (__c) : : "cc"); - - return __c; -} -#else static inline char __dcc_getchar(void) { char __c; @@ -62,24 +49,13 @@ static inline char __dcc_getchar(void) return __c; } -#endif -#if defined(CONFIG_CPU_V7) -static inline void __dcc_putchar(char c) -{ - asm volatile("put_wait: mrc p14, 0, pc, c0, c1, 0 \n\ - bcs put_wait \n\ - mcr p14, 0, %0, c0, c5, 0 " - : : "r" (c) : "cc"); -} -#else static inline void __dcc_putchar(char c) { asm volatile("mcr p14, 0, %0, c0, c5, 0 @ write a char" : /* no output register */ : "r" (c)); } -#endif static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count) { -- cgit v1.2.3 From 0c2c99b1b8ab5d294f176d631e945ebdefcce4cd Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Thu, 20 Jan 2011 10:43:34 -0600 Subject: memory hotplug: Allow memory blocks to span multiple memory sections Update the memory sysfs code such that each sysfs memory directory is now considered a memory block that can span multiple memory sections per memory block. The default size of each memory block is SECTION_SIZE_BITS to maintain the current behavior of having a single memory section per memory block (i.e. one sysfs directory per memory section). For architectures that want to have memory blocks span multiple memory sections they need only define their own memory_block_size_bytes() routine. Update the memory hotplug documentation to reflect the new behaviors of memory blocks reflected in sysfs. Signed-off-by: Nathan Fontenot Reviewed-by: Robin Holt Reviewed-by: KAMEZAWA Hiroyuki Signed-off-by: Greg Kroah-Hartman --- Documentation/memory-hotplug.txt | 47 ++++++++---- drivers/base/memory.c | 155 +++++++++++++++++++++++++++------------ 2 files changed, 139 insertions(+), 63 deletions(-) (limited to 'drivers') diff --git a/Documentation/memory-hotplug.txt b/Documentation/memory-hotplug.txt index 57e7e9cc1870..8f485d72cf25 100644 --- a/Documentation/memory-hotplug.txt +++ b/Documentation/memory-hotplug.txt @@ -126,36 +126,51 @@ config options. -------------------------------- 4 sysfs files for memory hotplug -------------------------------- -All sections have their device information under /sys/devices/system/memory as +All sections have their device information in sysfs. Each section is part of +a memory block under /sys/devices/system/memory as /sys/devices/system/memory/memoryXXX -(XXX is section id.) +(XXX is the section id.) -Now, XXX is defined as start_address_of_section / section_size. +Now, XXX is defined as (start_address_of_section / section_size) of the first +section contained in the memory block. The files 'phys_index' and +'end_phys_index' under each directory report the beginning and end section id's +for the memory block covered by the sysfs directory. It is expected that all +memory sections in this range are present and no memory holes exist in the +range. Currently there is no way to determine if there is a memory hole, but +the existence of one should not affect the hotplug capabilities of the memory +block. For example, assume 1GiB section size. A device for a memory starting at 0x100000000 is /sys/device/system/memory/memory4 (0x100000000 / 1Gib = 4) This device covers address range [0x100000000 ... 0x140000000) -Under each section, you can see 4 files. +Under each section, you can see 4 or 5 files, the end_phys_index file being +a recent addition and not present on older kernels. -/sys/devices/system/memory/memoryXXX/phys_index +/sys/devices/system/memory/memoryXXX/start_phys_index +/sys/devices/system/memory/memoryXXX/end_phys_index /sys/devices/system/memory/memoryXXX/phys_device /sys/devices/system/memory/memoryXXX/state /sys/devices/system/memory/memoryXXX/removable -'phys_index' : read-only and contains section id, same as XXX. -'state' : read-write - at read: contains online/offline state of memory. - at write: user can specify "online", "offline" command -'phys_device': read-only: designed to show the name of physical memory device. - This is not well implemented now. -'removable' : read-only: contains an integer value indicating - whether the memory section is removable or not - removable. A value of 1 indicates that the memory - section is removable and a value of 0 indicates that - it is not removable. +'phys_index' : read-only and contains section id of the first section + in the memory block, same as XXX. +'end_phys_index' : read-only and contains section id of the last section + in the memory block. +'state' : read-write + at read: contains online/offline state of memory. + at write: user can specify "online", "offline" command + which will be performed on al sections in the block. +'phys_device' : read-only: designed to show the name of physical memory + device. This is not well implemented now. +'removable' : read-only: contains an integer value indicating + whether the memory block is removable or not + removable. A value of 1 indicates that the memory + block is removable and a value of 0 indicates that + it is not removable. A memory block is removable only if + every section in the block is removable. NOTE: These directories/files appear after physical memory hotplug phase. diff --git a/drivers/base/memory.c b/drivers/base/memory.c index cafeaaf0428f..0b7040042587 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -30,6 +30,14 @@ static DEFINE_MUTEX(mem_sysfs_mutex); #define MEMORY_CLASS_NAME "memory" +#define MIN_MEMORY_BLOCK_SIZE (1 << SECTION_SIZE_BITS) + +static int sections_per_block; + +static inline int base_memory_block_id(int section_nr) +{ + return section_nr / sections_per_block; +} static struct sysdev_class memory_sysdev_class = { .name = MEMORY_CLASS_NAME, @@ -84,28 +92,47 @@ EXPORT_SYMBOL(unregister_memory_isolate_notifier); * register_memory - Setup a sysfs device for a memory block */ static -int register_memory(struct memory_block *memory, struct mem_section *section) +int register_memory(struct memory_block *memory) { int error; memory->sysdev.cls = &memory_sysdev_class; - memory->sysdev.id = __section_nr(section); + memory->sysdev.id = memory->phys_index / sections_per_block; error = sysdev_register(&memory->sysdev); return error; } static void -unregister_memory(struct memory_block *memory, struct mem_section *section) +unregister_memory(struct memory_block *memory) { BUG_ON(memory->sysdev.cls != &memory_sysdev_class); - BUG_ON(memory->sysdev.id != __section_nr(section)); /* drop the ref. we got in remove_memory_block() */ kobject_put(&memory->sysdev.kobj); sysdev_unregister(&memory->sysdev); } +unsigned long __weak memory_block_size_bytes(void) +{ + return MIN_MEMORY_BLOCK_SIZE; +} + +static unsigned long get_memory_block_size(void) +{ + unsigned long block_sz; + + block_sz = memory_block_size_bytes(); + + /* Validate blk_sz is a power of 2 and not less than section size */ + if ((block_sz & (block_sz - 1)) || (block_sz < MIN_MEMORY_BLOCK_SIZE)) { + WARN_ON(1); + block_sz = MIN_MEMORY_BLOCK_SIZE; + } + + return block_sz; +} + /* * use this as the physical section index that this memsection * uses. @@ -116,7 +143,7 @@ static ssize_t show_mem_phys_index(struct sys_device *dev, { struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - return sprintf(buf, "%08lx\n", mem->phys_index); + return sprintf(buf, "%08lx\n", mem->phys_index / sections_per_block); } /* @@ -125,13 +152,16 @@ static ssize_t show_mem_phys_index(struct sys_device *dev, static ssize_t show_mem_removable(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) { - unsigned long start_pfn; - int ret; + unsigned long i, pfn; + int ret = 1; struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - start_pfn = section_nr_to_pfn(mem->phys_index); - ret = is_mem_section_removable(start_pfn, PAGES_PER_SECTION); + for (i = 0; i < sections_per_block; i++) { + pfn = section_nr_to_pfn(mem->phys_index + i); + ret &= is_mem_section_removable(pfn, PAGES_PER_SECTION); + } + return sprintf(buf, "%d\n", ret); } @@ -184,17 +214,14 @@ int memory_isolate_notify(unsigned long val, void *v) * OK to have direct references to sparsemem variables in here. */ static int -memory_block_action(struct memory_block *mem, unsigned long action) +memory_section_action(unsigned long phys_index, unsigned long action) { int i; - unsigned long psection; unsigned long start_pfn, start_paddr; struct page *first_page; int ret; - int old_state = mem->state; - psection = mem->phys_index; - first_page = pfn_to_page(psection << PFN_SECTION_SHIFT); + first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT); /* * The probe routines leave the pages reserved, just @@ -207,8 +234,8 @@ memory_block_action(struct memory_block *mem, unsigned long action) continue; printk(KERN_WARNING "section number %ld page number %d " - "not reserved, was it already online? \n", - psection, i); + "not reserved, was it already online?\n", + phys_index, i); return -EBUSY; } } @@ -219,18 +246,13 @@ memory_block_action(struct memory_block *mem, unsigned long action) ret = online_pages(start_pfn, PAGES_PER_SECTION); break; case MEM_OFFLINE: - mem->state = MEM_GOING_OFFLINE; start_paddr = page_to_pfn(first_page) << PAGE_SHIFT; ret = remove_memory(start_paddr, PAGES_PER_SECTION << PAGE_SHIFT); - if (ret) { - mem->state = old_state; - break; - } break; default: - WARN(1, KERN_WARNING "%s(%p, %ld) unknown action: %ld\n", - __func__, mem, action, action); + WARN(1, KERN_WARNING "%s(%ld, %ld) unknown action: " + "%ld\n", __func__, phys_index, action, action); ret = -EINVAL; } @@ -240,7 +262,8 @@ memory_block_action(struct memory_block *mem, unsigned long action) static int memory_block_change_state(struct memory_block *mem, unsigned long to_state, unsigned long from_state_req) { - int ret = 0; + int i, ret = 0; + mutex_lock(&mem->state_mutex); if (mem->state != from_state_req) { @@ -248,8 +271,22 @@ static int memory_block_change_state(struct memory_block *mem, goto out; } - ret = memory_block_action(mem, to_state); - if (!ret) + if (to_state == MEM_OFFLINE) + mem->state = MEM_GOING_OFFLINE; + + for (i = 0; i < sections_per_block; i++) { + ret = memory_section_action(mem->phys_index + i, to_state); + if (ret) + break; + } + + if (ret) { + for (i = 0; i < sections_per_block; i++) + memory_section_action(mem->phys_index + i, + from_state_req); + + mem->state = from_state_req; + } else mem->state = to_state; out: @@ -262,20 +299,15 @@ store_mem_state(struct sys_device *dev, struct sysdev_attribute *attr, const char *buf, size_t count) { struct memory_block *mem; - unsigned int phys_section_nr; int ret = -EINVAL; mem = container_of(dev, struct memory_block, sysdev); - phys_section_nr = mem->phys_index; - - if (!present_section_nr(phys_section_nr)) - goto out; if (!strncmp(buf, "online", min((int)count, 6))) ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE); else if(!strncmp(buf, "offline", min((int)count, 7))) ret = memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE); -out: + if (ret) return ret; return count; @@ -315,7 +347,7 @@ static ssize_t print_block_size(struct sysdev_class *class, struct sysdev_class_attribute *attr, char *buf) { - return sprintf(buf, "%lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE); + return sprintf(buf, "%lx\n", get_memory_block_size()); } static SYSDEV_CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL); @@ -444,6 +476,7 @@ struct memory_block *find_memory_block_hinted(struct mem_section *section, struct sys_device *sysdev; struct memory_block *mem; char name[sizeof(MEMORY_CLASS_NAME) + 9 + 1]; + int block_id = base_memory_block_id(__section_nr(section)); kobj = hint ? &hint->sysdev.kobj : NULL; @@ -451,7 +484,7 @@ struct memory_block *find_memory_block_hinted(struct mem_section *section, * This only works because we know that section == sysdev->id * slightly redundant with sysdev_register() */ - sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, __section_nr(section)); + sprintf(&name[0], "%s%d", MEMORY_CLASS_NAME, block_id); kobj = kset_find_obj_hinted(&memory_sysdev_class.kset, name, kobj); if (!kobj) @@ -476,26 +509,27 @@ struct memory_block *find_memory_block(struct mem_section *section) return find_memory_block_hinted(section, NULL); } -static int add_memory_block(int nid, struct mem_section *section, - unsigned long state, enum mem_add_context context) +static int init_memory_block(struct memory_block **memory, + struct mem_section *section, unsigned long state) { - struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL); + struct memory_block *mem; unsigned long start_pfn; + int scn_nr; int ret = 0; + mem = kzalloc(sizeof(*mem), GFP_KERNEL); if (!mem) return -ENOMEM; - mutex_lock(&mem_sysfs_mutex); - - mem->phys_index = __section_nr(section); + scn_nr = __section_nr(section); + mem->phys_index = base_memory_block_id(scn_nr) * sections_per_block; mem->state = state; mem->section_count++; mutex_init(&mem->state_mutex); start_pfn = section_nr_to_pfn(mem->phys_index); mem->phys_device = arch_get_memory_phys_device(start_pfn); - ret = register_memory(mem, section); + ret = register_memory(mem); if (!ret) ret = mem_create_simple_file(mem, phys_index); if (!ret) @@ -504,8 +538,29 @@ static int add_memory_block(int nid, struct mem_section *section, ret = mem_create_simple_file(mem, phys_device); if (!ret) ret = mem_create_simple_file(mem, removable); + + *memory = mem; + return ret; +} + +static int add_memory_section(int nid, struct mem_section *section, + unsigned long state, enum mem_add_context context) +{ + struct memory_block *mem; + int ret = 0; + + mutex_lock(&mem_sysfs_mutex); + + mem = find_memory_block(section); + if (mem) { + mem->section_count++; + kobject_put(&mem->sysdev.kobj); + } else + ret = init_memory_block(&mem, section, state); + if (!ret) { - if (context == HOTPLUG) + if (context == HOTPLUG && + mem->section_count == sections_per_block) ret = register_mem_sect_under_node(mem, nid); } @@ -528,8 +583,10 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section, mem_remove_simple_file(mem, state); mem_remove_simple_file(mem, phys_device); mem_remove_simple_file(mem, removable); - unregister_memory(mem, section); - } + unregister_memory(mem); + kfree(mem); + } else + kobject_put(&mem->sysdev.kobj); mutex_unlock(&mem_sysfs_mutex); return 0; @@ -541,7 +598,7 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section, */ int register_new_memory(int nid, struct mem_section *section) { - return add_memory_block(nid, section, MEM_OFFLINE, HOTPLUG); + return add_memory_section(nid, section, MEM_OFFLINE, HOTPLUG); } int unregister_memory_section(struct mem_section *section) @@ -560,12 +617,16 @@ int __init memory_dev_init(void) unsigned int i; int ret; int err; + unsigned long block_sz; memory_sysdev_class.kset.uevent_ops = &memory_uevent_ops; ret = sysdev_class_register(&memory_sysdev_class); if (ret) goto out; + block_sz = get_memory_block_size(); + sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE; + /* * Create entries for memory sections that were found * during boot and have been initialized @@ -573,8 +634,8 @@ int __init memory_dev_init(void) for (i = 0; i < NR_MEM_SECTIONS; i++) { if (!present_section_nr(i)) continue; - err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, - BOOT); + err = add_memory_section(0, __nr_to_section(i), MEM_ONLINE, + BOOT); if (!ret) ret = err; } -- cgit v1.2.3 From d33601644cd3b09afb2edd9474517edc441c8fad Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Thu, 20 Jan 2011 10:44:29 -0600 Subject: memory hotplug: Update phys_index to [start|end]_section_nr Update the 'phys_index' property of a the memory_block struct to be called start_section_nr, and add a end_section_nr property. The data tracked here is the same but the updated naming is more in line with what is stored here, namely the first and last section number that the memory block spans. The names presented to userspace remain the same, phys_index for start_section_nr and end_phys_index for end_section_nr, to avoid breaking anything in userspace. This also updates the node sysfs code to be aware of the new capability for a memory block to contain multiple memory sections and be aware of the memory block structure name changes (start_section_nr). This requires an additional parameter to unregister_mem_sect_under_nodes so that we know which memory section of the memory block to unregister. Signed-off-by: Nathan Fontenot Reviewed-by: Robin Holt Reviewed-by: KAMEZAWA Hiroyuki Signed-off-by: Greg Kroah-Hartman --- drivers/base/memory.c | 41 +++++++++++++++++++++++++++++++---------- drivers/base/node.c | 12 ++++++++---- include/linux/memory.h | 3 ++- include/linux/node.h | 6 ++++-- 4 files changed, 45 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 0b7040042587..71b4a32b1710 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -97,7 +97,7 @@ int register_memory(struct memory_block *memory) int error; memory->sysdev.cls = &memory_sysdev_class; - memory->sysdev.id = memory->phys_index / sections_per_block; + memory->sysdev.id = memory->start_section_nr / sections_per_block; error = sysdev_register(&memory->sysdev); return error; @@ -138,12 +138,26 @@ static unsigned long get_memory_block_size(void) * uses. */ -static ssize_t show_mem_phys_index(struct sys_device *dev, +static ssize_t show_mem_start_phys_index(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) { struct memory_block *mem = container_of(dev, struct memory_block, sysdev); - return sprintf(buf, "%08lx\n", mem->phys_index / sections_per_block); + unsigned long phys_index; + + phys_index = mem->start_section_nr / sections_per_block; + return sprintf(buf, "%08lx\n", phys_index); +} + +static ssize_t show_mem_end_phys_index(struct sys_device *dev, + struct sysdev_attribute *attr, char *buf) +{ + struct memory_block *mem = + container_of(dev, struct memory_block, sysdev); + unsigned long phys_index; + + phys_index = mem->end_section_nr / sections_per_block; + return sprintf(buf, "%08lx\n", phys_index); } /* @@ -158,7 +172,7 @@ static ssize_t show_mem_removable(struct sys_device *dev, container_of(dev, struct memory_block, sysdev); for (i = 0; i < sections_per_block; i++) { - pfn = section_nr_to_pfn(mem->phys_index + i); + pfn = section_nr_to_pfn(mem->start_section_nr + i); ret &= is_mem_section_removable(pfn, PAGES_PER_SECTION); } @@ -275,14 +289,15 @@ static int memory_block_change_state(struct memory_block *mem, mem->state = MEM_GOING_OFFLINE; for (i = 0; i < sections_per_block; i++) { - ret = memory_section_action(mem->phys_index + i, to_state); + ret = memory_section_action(mem->start_section_nr + i, + to_state); if (ret) break; } if (ret) { for (i = 0; i < sections_per_block; i++) - memory_section_action(mem->phys_index + i, + memory_section_action(mem->start_section_nr + i, from_state_req); mem->state = from_state_req; @@ -330,7 +345,8 @@ static ssize_t show_phys_device(struct sys_device *dev, return sprintf(buf, "%d\n", mem->phys_device); } -static SYSDEV_ATTR(phys_index, 0444, show_mem_phys_index, NULL); +static SYSDEV_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL); +static SYSDEV_ATTR(end_phys_index, 0444, show_mem_end_phys_index, NULL); static SYSDEV_ATTR(state, 0644, show_mem_state, store_mem_state); static SYSDEV_ATTR(phys_device, 0444, show_phys_device, NULL); static SYSDEV_ATTR(removable, 0444, show_mem_removable, NULL); @@ -522,16 +538,20 @@ static int init_memory_block(struct memory_block **memory, return -ENOMEM; scn_nr = __section_nr(section); - mem->phys_index = base_memory_block_id(scn_nr) * sections_per_block; + mem->start_section_nr = + base_memory_block_id(scn_nr) * sections_per_block; + mem->end_section_nr = mem->start_section_nr + sections_per_block - 1; mem->state = state; mem->section_count++; mutex_init(&mem->state_mutex); - start_pfn = section_nr_to_pfn(mem->phys_index); + start_pfn = section_nr_to_pfn(mem->start_section_nr); mem->phys_device = arch_get_memory_phys_device(start_pfn); ret = register_memory(mem); if (!ret) ret = mem_create_simple_file(mem, phys_index); + if (!ret) + ret = mem_create_simple_file(mem, end_phys_index); if (!ret) ret = mem_create_simple_file(mem, state); if (!ret) @@ -575,11 +595,12 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section, mutex_lock(&mem_sysfs_mutex); mem = find_memory_block(section); + unregister_mem_sect_under_nodes(mem, __section_nr(section)); mem->section_count--; if (mem->section_count == 0) { - unregister_mem_sect_under_nodes(mem); mem_remove_simple_file(mem, phys_index); + mem_remove_simple_file(mem, end_phys_index); mem_remove_simple_file(mem, state); mem_remove_simple_file(mem, phys_device); mem_remove_simple_file(mem, removable); diff --git a/drivers/base/node.c b/drivers/base/node.c index 36b43052001d..b3b72d64e805 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -375,8 +375,10 @@ int register_mem_sect_under_node(struct memory_block *mem_blk, int nid) return -EFAULT; if (!node_online(nid)) return 0; - sect_start_pfn = section_nr_to_pfn(mem_blk->phys_index); - sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1; + + sect_start_pfn = section_nr_to_pfn(mem_blk->start_section_nr); + sect_end_pfn = section_nr_to_pfn(mem_blk->end_section_nr); + sect_end_pfn += PAGES_PER_SECTION - 1; for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { int page_nid; @@ -400,7 +402,8 @@ int register_mem_sect_under_node(struct memory_block *mem_blk, int nid) } /* unregister memory section under all nodes that it spans */ -int unregister_mem_sect_under_nodes(struct memory_block *mem_blk) +int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, + unsigned long phys_index) { NODEMASK_ALLOC(nodemask_t, unlinked_nodes, GFP_KERNEL); unsigned long pfn, sect_start_pfn, sect_end_pfn; @@ -412,7 +415,8 @@ int unregister_mem_sect_under_nodes(struct memory_block *mem_blk) if (!unlinked_nodes) return -ENOMEM; nodes_clear(*unlinked_nodes); - sect_start_pfn = section_nr_to_pfn(mem_blk->phys_index); + + sect_start_pfn = section_nr_to_pfn(phys_index); sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1; for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { int nid; diff --git a/include/linux/memory.h b/include/linux/memory.h index 06c1fa0a5c7b..e1e3b2b84f85 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h @@ -21,7 +21,8 @@ #include struct memory_block { - unsigned long phys_index; + unsigned long start_section_nr; + unsigned long end_section_nr; unsigned long state; int section_count; diff --git a/include/linux/node.h b/include/linux/node.h index 1466945cc9ef..92370e22343c 100644 --- a/include/linux/node.h +++ b/include/linux/node.h @@ -39,7 +39,8 @@ extern int register_cpu_under_node(unsigned int cpu, unsigned int nid); extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid); extern int register_mem_sect_under_node(struct memory_block *mem_blk, int nid); -extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk); +extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, + unsigned long phys_index); #ifdef CONFIG_HUGETLBFS extern void register_hugetlbfs_with_node(node_registration_func_t doregister, @@ -67,7 +68,8 @@ static inline int register_mem_sect_under_node(struct memory_block *mem_blk, { return 0; } -static inline int unregister_mem_sect_under_nodes(struct memory_block *mem_blk) +static inline int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, + unsigned long phys_index) { return 0; } -- cgit v1.2.3 From 6add7cd618b4d4dc525731beb539c5e06e891855 Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Mon, 31 Jan 2011 10:55:23 -0600 Subject: memory hotplug: sysfs probe routine should add all memory sections As a follow-on to the recent patches I submitted that allowed for a sysfs memory block to span multiple memory sections, we should also update the probe routine to online all of the memory sections in a memory block. Without this patch the current code will only add a single memory section. I think the probe routine should add all of the memory sections in the specified memory block so that its behavior is in line with memory hotplug actions through the sysfs interfaces. This patch applies on top of the previous sysfs memory updates to allow a sysfs directory o span multiple memory sections. https://lkml.org/lkml/2011/1/20/245 Signed-off-by: Nathan Fontenot Signed-off-by: Greg Kroah-Hartman --- drivers/base/memory.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 71b4a32b1710..3da6a43b7756 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -387,12 +387,19 @@ memory_probe_store(struct class *class, struct class_attribute *attr, { u64 phys_addr; int nid; - int ret; + int i, ret; phys_addr = simple_strtoull(buf, NULL, 0); - nid = memory_add_physaddr_to_nid(phys_addr); - ret = add_memory(nid, phys_addr, PAGES_PER_SECTION << PAGE_SHIFT); + for (i = 0; i < sections_per_block; i++) { + nid = memory_add_physaddr_to_nid(phys_addr); + ret = add_memory(nid, phys_addr, + PAGES_PER_SECTION << PAGE_SHIFT); + if (ret) + break; + + phys_addr += MIN_MEMORY_BLOCK_SIZE; + } if (ret) count = ret; -- cgit v1.2.3 From 481e20799bdcf98fd5a1d829d187239a90b15395 Mon Sep 17 00:00:00 2001 From: Ferenc Wagner Date: Fri, 7 Jan 2011 15:17:47 +0100 Subject: driver core: Replace the dangerous to_root_device macro with an inline function The original macro worked only when applied to variables named 'dev'. While this could have been fixed by simply renaming the macro argument, a more type-safe replacement by an inline function is preferred. Signed-off-by: Ferenc Wagner Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/core.c b/drivers/base/core.c index 9cd3b5cfcc42..81b78ede37c4 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1320,7 +1320,10 @@ struct root_device struct module *owner; }; -#define to_root_device(dev) container_of(dev, struct root_device, dev) +inline struct root_device *to_root_device(struct device *d) +{ + return container_of(d, struct root_device, dev); +} static void root_device_release(struct device *dev) { -- cgit v1.2.3 From 2b7bcebf958c74124220ee8103024def8597b36c Mon Sep 17 00:00:00 2001 From: Ivan Vecera Date: Wed, 2 Feb 2011 08:05:12 +0000 Subject: be2net: use device model DMA API Use DMA API as PCI equivalents will be deprecated. Signed-off-by: Ivan Vecera Acked-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_ethtool.c | 25 +++++------ drivers/net/benet/be_main.c | 98 ++++++++++++++++++++++-------------------- 2 files changed, 64 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index b4be0271efe0..0c9931473346 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -376,8 +376,9 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) } phy_cmd.size = sizeof(struct be_cmd_req_get_phy_info); - phy_cmd.va = pci_alloc_consistent(adapter->pdev, phy_cmd.size, - &phy_cmd.dma); + phy_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, + phy_cmd.size, &phy_cmd.dma, + GFP_KERNEL); if (!phy_cmd.va) { dev_err(&adapter->pdev->dev, "Memory alloc failure\n"); return -ENOMEM; @@ -416,8 +417,8 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) adapter->port_type = ecmd->port; adapter->transceiver = ecmd->transceiver; adapter->autoneg = ecmd->autoneg; - pci_free_consistent(adapter->pdev, phy_cmd.size, - phy_cmd.va, phy_cmd.dma); + dma_free_coherent(&adapter->pdev->dev, phy_cmd.size, phy_cmd.va, + phy_cmd.dma); } else { ecmd->speed = adapter->link_speed; ecmd->port = adapter->port_type; @@ -554,8 +555,8 @@ be_test_ddr_dma(struct be_adapter *adapter) }; ddrdma_cmd.size = sizeof(struct be_cmd_req_ddrdma_test); - ddrdma_cmd.va = pci_alloc_consistent(adapter->pdev, ddrdma_cmd.size, - &ddrdma_cmd.dma); + ddrdma_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, ddrdma_cmd.size, + &ddrdma_cmd.dma, GFP_KERNEL); if (!ddrdma_cmd.va) { dev_err(&adapter->pdev->dev, "Memory allocation failure\n"); return -ENOMEM; @@ -569,8 +570,8 @@ be_test_ddr_dma(struct be_adapter *adapter) } err: - pci_free_consistent(adapter->pdev, ddrdma_cmd.size, - ddrdma_cmd.va, ddrdma_cmd.dma); + dma_free_coherent(&adapter->pdev->dev, ddrdma_cmd.size, ddrdma_cmd.va, + ddrdma_cmd.dma); return ret; } @@ -662,8 +663,8 @@ be_read_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, memset(&eeprom_cmd, 0, sizeof(struct be_dma_mem)); eeprom_cmd.size = sizeof(struct be_cmd_req_seeprom_read); - eeprom_cmd.va = pci_alloc_consistent(adapter->pdev, eeprom_cmd.size, - &eeprom_cmd.dma); + eeprom_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, eeprom_cmd.size, + &eeprom_cmd.dma, GFP_KERNEL); if (!eeprom_cmd.va) { dev_err(&adapter->pdev->dev, @@ -677,8 +678,8 @@ be_read_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, resp = (struct be_cmd_resp_seeprom_read *) eeprom_cmd.va; memcpy(data, resp->seeprom_data + eeprom->offset, eeprom->len); } - pci_free_consistent(adapter->pdev, eeprom_cmd.size, eeprom_cmd.va, - eeprom_cmd.dma); + dma_free_coherent(&adapter->pdev->dev, eeprom_cmd.size, eeprom_cmd.va, + eeprom_cmd.dma); return status; } diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index de40d3b7152f..c4966d46f692 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -125,8 +125,8 @@ static void be_queue_free(struct be_adapter *adapter, struct be_queue_info *q) { struct be_dma_mem *mem = &q->dma_mem; if (mem->va) - pci_free_consistent(adapter->pdev, mem->size, - mem->va, mem->dma); + dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va, + mem->dma); } static int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q, @@ -138,7 +138,8 @@ static int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q, q->len = len; q->entry_size = entry_size; mem->size = len * entry_size; - mem->va = pci_alloc_consistent(adapter->pdev, mem->size, &mem->dma); + mem->va = dma_alloc_coherent(&adapter->pdev->dev, mem->size, &mem->dma, + GFP_KERNEL); if (!mem->va) return -1; memset(mem->va, 0, mem->size); @@ -486,7 +487,7 @@ static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr, AMAP_SET_BITS(struct amap_eth_hdr_wrb, len, hdr, len); } -static void unmap_tx_frag(struct pci_dev *pdev, struct be_eth_wrb *wrb, +static void unmap_tx_frag(struct device *dev, struct be_eth_wrb *wrb, bool unmap_single) { dma_addr_t dma; @@ -496,11 +497,10 @@ static void unmap_tx_frag(struct pci_dev *pdev, struct be_eth_wrb *wrb, dma = (u64)wrb->frag_pa_hi << 32 | (u64)wrb->frag_pa_lo; if (wrb->frag_len) { if (unmap_single) - pci_unmap_single(pdev, dma, wrb->frag_len, - PCI_DMA_TODEVICE); + dma_unmap_single(dev, dma, wrb->frag_len, + DMA_TO_DEVICE); else - pci_unmap_page(pdev, dma, wrb->frag_len, - PCI_DMA_TODEVICE); + dma_unmap_page(dev, dma, wrb->frag_len, DMA_TO_DEVICE); } } @@ -509,7 +509,7 @@ static int make_tx_wrbs(struct be_adapter *adapter, { dma_addr_t busaddr; int i, copied = 0; - struct pci_dev *pdev = adapter->pdev; + struct device *dev = &adapter->pdev->dev; struct sk_buff *first_skb = skb; struct be_queue_info *txq = &adapter->tx_obj.q; struct be_eth_wrb *wrb; @@ -523,9 +523,8 @@ static int make_tx_wrbs(struct be_adapter *adapter, if (skb->len > skb->data_len) { int len = skb_headlen(skb); - busaddr = pci_map_single(pdev, skb->data, len, - PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(pdev, busaddr)) + busaddr = dma_map_single(dev, skb->data, len, DMA_TO_DEVICE); + if (dma_mapping_error(dev, busaddr)) goto dma_err; map_single = true; wrb = queue_head_node(txq); @@ -538,10 +537,9 @@ static int make_tx_wrbs(struct be_adapter *adapter, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; - busaddr = pci_map_page(pdev, frag->page, - frag->page_offset, - frag->size, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(pdev, busaddr)) + busaddr = dma_map_page(dev, frag->page, frag->page_offset, + frag->size, DMA_TO_DEVICE); + if (dma_mapping_error(dev, busaddr)) goto dma_err; wrb = queue_head_node(txq); wrb_fill(wrb, busaddr, frag->size); @@ -565,7 +563,7 @@ dma_err: txq->head = map_head; while (copied) { wrb = queue_head_node(txq); - unmap_tx_frag(pdev, wrb, map_single); + unmap_tx_frag(dev, wrb, map_single); map_single = false; copied -= wrb->frag_len; queue_head_inc(txq); @@ -890,8 +888,9 @@ get_rx_page_info(struct be_adapter *adapter, BUG_ON(!rx_page_info->page); if (rx_page_info->last_page_user) { - pci_unmap_page(adapter->pdev, dma_unmap_addr(rx_page_info, bus), - adapter->big_page_size, PCI_DMA_FROMDEVICE); + dma_unmap_page(&adapter->pdev->dev, + dma_unmap_addr(rx_page_info, bus), + adapter->big_page_size, DMA_FROM_DEVICE); rx_page_info->last_page_user = false; } @@ -1197,9 +1196,9 @@ static void be_post_rx_frags(struct be_rx_obj *rxo) rxo->stats.rx_post_fail++; break; } - page_dmaaddr = pci_map_page(adapter->pdev, pagep, 0, - adapter->big_page_size, - PCI_DMA_FROMDEVICE); + page_dmaaddr = dma_map_page(&adapter->pdev->dev, pagep, + 0, adapter->big_page_size, + DMA_FROM_DEVICE); page_info->page_offset = 0; } else { get_page(pagep); @@ -1272,8 +1271,8 @@ static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index) do { cur_index = txq->tail; wrb = queue_tail_node(txq); - unmap_tx_frag(adapter->pdev, wrb, (unmap_skb_hdr && - skb_headlen(sent_skb))); + unmap_tx_frag(&adapter->pdev->dev, wrb, + (unmap_skb_hdr && skb_headlen(sent_skb))); unmap_skb_hdr = false; num_wrbs++; @@ -2181,7 +2180,8 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable) memset(mac, 0, ETH_ALEN); cmd.size = sizeof(struct be_cmd_req_acpi_wol_magic_config); - cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma); + cmd.va = dma_alloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma, + GFP_KERNEL); if (cmd.va == NULL) return -1; memset(cmd.va, 0, cmd.size); @@ -2192,8 +2192,8 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable) if (status) { dev_err(&adapter->pdev->dev, "Could not enable Wake-on-lan\n"); - pci_free_consistent(adapter->pdev, cmd.size, cmd.va, - cmd.dma); + dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, + cmd.dma); return status; } status = be_cmd_enable_magic_wol(adapter, @@ -2206,7 +2206,7 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable) pci_enable_wake(adapter->pdev, PCI_D3cold, 0); } - pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma); + dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma); return status; } @@ -2530,8 +2530,8 @@ int be_load_fw(struct be_adapter *adapter, u8 *func) dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file); flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024; - flash_cmd.va = pci_alloc_consistent(adapter->pdev, flash_cmd.size, - &flash_cmd.dma); + flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size, + &flash_cmd.dma, GFP_KERNEL); if (!flash_cmd.va) { status = -ENOMEM; dev_err(&adapter->pdev->dev, @@ -2560,8 +2560,8 @@ int be_load_fw(struct be_adapter *adapter, u8 *func) status = -1; } - pci_free_consistent(adapter->pdev, flash_cmd.size, flash_cmd.va, - flash_cmd.dma); + dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va, + flash_cmd.dma); if (status) { dev_err(&adapter->pdev->dev, "Firmware load error\n"); goto fw_exit; @@ -2704,13 +2704,13 @@ static void be_ctrl_cleanup(struct be_adapter *adapter) be_unmap_pci_bars(adapter); if (mem->va) - pci_free_consistent(adapter->pdev, mem->size, - mem->va, mem->dma); + dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va, + mem->dma); mem = &adapter->mc_cmd_mem; if (mem->va) - pci_free_consistent(adapter->pdev, mem->size, - mem->va, mem->dma); + dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va, + mem->dma); } static int be_ctrl_init(struct be_adapter *adapter) @@ -2725,8 +2725,10 @@ static int be_ctrl_init(struct be_adapter *adapter) goto done; mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16; - mbox_mem_alloc->va = pci_alloc_consistent(adapter->pdev, - mbox_mem_alloc->size, &mbox_mem_alloc->dma); + mbox_mem_alloc->va = dma_alloc_coherent(&adapter->pdev->dev, + mbox_mem_alloc->size, + &mbox_mem_alloc->dma, + GFP_KERNEL); if (!mbox_mem_alloc->va) { status = -ENOMEM; goto unmap_pci_bars; @@ -2738,8 +2740,9 @@ static int be_ctrl_init(struct be_adapter *adapter) memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox)); mc_cmd_mem->size = sizeof(struct be_cmd_req_mcast_mac_config); - mc_cmd_mem->va = pci_alloc_consistent(adapter->pdev, mc_cmd_mem->size, - &mc_cmd_mem->dma); + mc_cmd_mem->va = dma_alloc_coherent(&adapter->pdev->dev, + mc_cmd_mem->size, &mc_cmd_mem->dma, + GFP_KERNEL); if (mc_cmd_mem->va == NULL) { status = -ENOMEM; goto free_mbox; @@ -2755,8 +2758,8 @@ static int be_ctrl_init(struct be_adapter *adapter) return 0; free_mbox: - pci_free_consistent(adapter->pdev, mbox_mem_alloc->size, - mbox_mem_alloc->va, mbox_mem_alloc->dma); + dma_free_coherent(&adapter->pdev->dev, mbox_mem_alloc->size, + mbox_mem_alloc->va, mbox_mem_alloc->dma); unmap_pci_bars: be_unmap_pci_bars(adapter); @@ -2770,8 +2773,8 @@ static void be_stats_cleanup(struct be_adapter *adapter) struct be_dma_mem *cmd = &adapter->stats_cmd; if (cmd->va) - pci_free_consistent(adapter->pdev, cmd->size, - cmd->va, cmd->dma); + dma_free_coherent(&adapter->pdev->dev, cmd->size, + cmd->va, cmd->dma); } static int be_stats_init(struct be_adapter *adapter) @@ -2779,7 +2782,8 @@ static int be_stats_init(struct be_adapter *adapter) struct be_dma_mem *cmd = &adapter->stats_cmd; cmd->size = sizeof(struct be_cmd_req_get_stats); - cmd->va = pci_alloc_consistent(adapter->pdev, cmd->size, &cmd->dma); + cmd->va = dma_alloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma, + GFP_KERNEL); if (cmd->va == NULL) return -1; memset(cmd->va, 0, cmd->size); @@ -2922,11 +2926,11 @@ static int __devinit be_probe(struct pci_dev *pdev, adapter->netdev = netdev; SET_NETDEV_DEV(netdev, &pdev->dev); - status = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); + status = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)); if (!status) { netdev->features |= NETIF_F_HIGHDMA; } else { - status = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + status = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); if (status) { dev_err(&pdev->dev, "Could not set PCI DMA Mask\n"); goto free_netdev; -- cgit v1.2.3 From 04bea68b2f0eeebb089ecc67b618795925268b4a Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 24 Jan 2011 09:58:55 +0530 Subject: of/pci: move of_irq_map_pci() into generic code There is a tiny difference between PPC32 and PPC64. Microblaze uses the PPC32 variant. Signed-off-by: Sebastian Andrzej Siewior [grant.likely@secretlab.ca: Added comment to #endif, moved documentation block to function implementation, fixed for non ppc and microblaze compiles] Signed-off-by: Grant Likely --- arch/microblaze/include/asm/pci-bridge.h | 12 +++++ arch/microblaze/include/asm/prom.h | 15 ------ arch/microblaze/kernel/prom_parse.c | 77 --------------------------- arch/microblaze/pci/pci-common.c | 1 + arch/powerpc/include/asm/pci-bridge.h | 10 ++++ arch/powerpc/include/asm/prom.h | 15 ------ arch/powerpc/kernel/pci-common.c | 1 + arch/powerpc/kernel/prom_parse.c | 84 ----------------------------- drivers/of/Kconfig | 6 +++ drivers/of/Makefile | 1 + drivers/of/of_pci.c | 91 ++++++++++++++++++++++++++++++++ include/linux/of_pci.h | 9 ++++ 12 files changed, 131 insertions(+), 191 deletions(-) create mode 100644 drivers/of/of_pci.c create mode 100644 include/linux/of_pci.h (limited to 'drivers') diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h index 0c68764ab547..10717669e0c2 100644 --- a/arch/microblaze/include/asm/pci-bridge.h +++ b/arch/microblaze/include/asm/pci-bridge.h @@ -104,11 +104,22 @@ struct pci_controller { int global_number; /* PCI domain number */ }; +#ifdef CONFIG_PCI static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus) { return bus->sysdata; } +static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus) +{ + struct pci_controller *host; + + if (bus->self) + return pci_device_to_OF_node(bus->self); + host = pci_bus_to_host(bus); + return host ? host->dn : NULL; +} + static inline int isa_vaddr_is_ioport(void __iomem *address) { /* No specific ISA handling on ppc32 at this stage, it @@ -116,6 +127,7 @@ static inline int isa_vaddr_is_ioport(void __iomem *address) */ return 0; } +#endif /* CONFIG_PCI */ /* These are used for config access before all the PCI probing has been done. */ diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index 2e72af078b05..d0890d36ef61 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h @@ -64,21 +64,6 @@ extern void kdump_move_device_tree(void); /* CPU OF node matching */ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); -/** - * of_irq_map_pci - Resolve the interrupt for a PCI device - * @pdev: the device whose interrupt is to be resolved - * @out_irq: structure of_irq filled by this function - * - * This function resolves the PCI interrupt for a given PCI device. If a - * device-node exists for a given pci_dev, it will use normal OF tree - * walking. If not, it will implement standard swizzling and walk up the - * PCI tree until an device-node is found, at which point it will finish - * resolving using the OF tree walking. - */ -struct pci_dev; -struct of_irq; -extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); - #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c index 9ae24f4b882b..47187cc2cf00 100644 --- a/arch/microblaze/kernel/prom_parse.c +++ b/arch/microblaze/kernel/prom_parse.c @@ -2,88 +2,11 @@ #include #include -#include #include #include #include #include #include -#include - -#ifdef CONFIG_PCI -int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) -{ - struct device_node *dn, *ppnode; - struct pci_dev *ppdev; - u32 lspec; - u32 laddr[3]; - u8 pin; - int rc; - - /* Check if we have a device node, if yes, fallback to standard OF - * parsing - */ - dn = pci_device_to_OF_node(pdev); - if (dn) - return of_irq_map_one(dn, 0, out_irq); - - /* Ok, we don't, time to have fun. Let's start by building up an - * interrupt spec. we assume #interrupt-cells is 1, which is standard - * for PCI. If you do different, then don't use that routine. - */ - rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin); - if (rc != 0) - return rc; - /* No pin, exit */ - if (pin == 0) - return -ENODEV; - - /* Now we walk up the PCI tree */ - lspec = pin; - for (;;) { - /* Get the pci_dev of our parent */ - ppdev = pdev->bus->self; - - /* Ouch, it's a host bridge... */ - if (ppdev == NULL) { - struct pci_controller *host; - host = pci_bus_to_host(pdev->bus); - ppnode = host ? host->dn : NULL; - /* No node for host bridge ? give up */ - if (ppnode == NULL) - return -EINVAL; - } else - /* We found a P2P bridge, check if it has a node */ - ppnode = pci_device_to_OF_node(ppdev); - - /* Ok, we have found a parent with a device-node, hand over to - * the OF parsing code. - * We build a unit address from the linux device to be used for - * resolution. Note that we use the linux bus number which may - * not match your firmware bus numbering. - * Fortunately, in most cases, interrupt-map-mask doesn't - * include the bus number as part of the matching. - * You should still be careful about that though if you intend - * to rely on this function (you ship a firmware that doesn't - * create device nodes for all PCI devices). - */ - if (ppnode) - break; - - /* We can only get here if we hit a P2P bridge with no node, - * let's do standard swizzling and try again - */ - lspec = pci_swizzle_interrupt_pin(pdev, lspec); - pdev = ppdev; - } - - laddr[0] = (pdev->bus->number << 16) - | (pdev->devfn << 8); - laddr[1] = laddr[2] = 0; - return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq); -} -EXPORT_SYMBOL_GPL(of_irq_map_pci); -#endif /* CONFIG_PCI */ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, unsigned long *busno, unsigned long *phys, unsigned long *size) diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index e363615d6798..1e01a1253631 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 51e9e6f90d12..edeb80fdd2c3 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -171,6 +171,16 @@ static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus) return bus->sysdata; } +static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus) +{ + struct pci_controller *host; + + if (bus->self) + return pci_device_to_OF_node(bus->self); + host = pci_bus_to_host(bus); + return host ? host->dn : NULL; +} + static inline int isa_vaddr_is_ioport(void __iomem *address) { /* No specific ISA handling on ppc32 at this stage, it diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index d72757585595..c189aa5fe1f4 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -70,21 +70,6 @@ static inline int of_node_to_nid(struct device_node *device) { return 0; } #endif #define of_node_to_nid of_node_to_nid -/** - * of_irq_map_pci - Resolve the interrupt for a PCI device - * @pdev: the device whose interrupt is to be resolved - * @out_irq: structure of_irq filled by this function - * - * This function resolves the PCI interrupt for a given PCI device. If a - * device-node exists for a given pci_dev, it will use normal OF tree - * walking. If not, it will implement standard swizzling and walk up the - * PCI tree until an device-node is found, at which point it will finish - * resolving using the OF tree walking. - */ -struct pci_dev; -struct of_irq; -extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); - extern void of_instantiate_rtc(void); /* These includes are put at the bottom because they may contain things diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 10a44e68ef11..eb341be9a4d9 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index c2b7a07cc3d3..47187cc2cf00 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c @@ -2,95 +2,11 @@ #include #include -#include #include #include #include #include #include -#include - -#ifdef CONFIG_PCI -int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) -{ - struct device_node *dn, *ppnode; - struct pci_dev *ppdev; - u32 lspec; - u32 laddr[3]; - u8 pin; - int rc; - - /* Check if we have a device node, if yes, fallback to standard OF - * parsing - */ - dn = pci_device_to_OF_node(pdev); - if (dn) { - rc = of_irq_map_one(dn, 0, out_irq); - if (!rc) - return rc; - } - - /* Ok, we don't, time to have fun. Let's start by building up an - * interrupt spec. we assume #interrupt-cells is 1, which is standard - * for PCI. If you do different, then don't use that routine. - */ - rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin); - if (rc != 0) - return rc; - /* No pin, exit */ - if (pin == 0) - return -ENODEV; - - /* Now we walk up the PCI tree */ - lspec = pin; - for (;;) { - /* Get the pci_dev of our parent */ - ppdev = pdev->bus->self; - - /* Ouch, it's a host bridge... */ - if (ppdev == NULL) { -#ifdef CONFIG_PPC64 - ppnode = pci_bus_to_OF_node(pdev->bus); -#else - struct pci_controller *host; - host = pci_bus_to_host(pdev->bus); - ppnode = host ? host->dn : NULL; -#endif - /* No node for host bridge ? give up */ - if (ppnode == NULL) - return -EINVAL; - } else - /* We found a P2P bridge, check if it has a node */ - ppnode = pci_device_to_OF_node(ppdev); - - /* Ok, we have found a parent with a device-node, hand over to - * the OF parsing code. - * We build a unit address from the linux device to be used for - * resolution. Note that we use the linux bus number which may - * not match your firmware bus numbering. - * Fortunately, in most cases, interrupt-map-mask doesn't include - * the bus number as part of the matching. - * You should still be careful about that though if you intend - * to rely on this function (you ship a firmware that doesn't - * create device nodes for all PCI devices). - */ - if (ppnode) - break; - - /* We can only get here if we hit a P2P bridge with no node, - * let's do standard swizzling and try again - */ - lspec = pci_swizzle_interrupt_pin(pdev, lspec); - pdev = ppdev; - } - - laddr[0] = (pdev->bus->number << 16) - | (pdev->devfn << 8); - laddr[1] = laddr[2] = 0; - return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq); -} -EXPORT_SYMBOL_GPL(of_irq_map_pci); -#endif /* CONFIG_PCI */ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, unsigned long *busno, unsigned long *phys, unsigned long *size) diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index 3c6e100a3ad0..efabbf9dd607 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -69,4 +69,10 @@ config OF_MDIO help OpenFirmware MDIO bus (Ethernet PHY) accessors +config OF_PCI + def_tristate PCI + depends on PCI && (PPC || MICROBLAZE) + help + OpenFirmware PCI bus accessors + endmenu # OF diff --git a/drivers/of/Makefile b/drivers/of/Makefile index 3ab21a0a4907..f7861ed2f287 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_OF_I2C) += of_i2c.o obj-$(CONFIG_OF_NET) += of_net.o obj-$(CONFIG_OF_SPI) += of_spi.o obj-$(CONFIG_OF_MDIO) += of_mdio.o +obj-$(CONFIG_OF_PCI) += of_pci.o diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c new file mode 100644 index 000000000000..314535fa32c1 --- /dev/null +++ b/drivers/of/of_pci.c @@ -0,0 +1,91 @@ +#include +#include +#include + +/** + * of_irq_map_pci - Resolve the interrupt for a PCI device + * @pdev: the device whose interrupt is to be resolved + * @out_irq: structure of_irq filled by this function + * + * This function resolves the PCI interrupt for a given PCI device. If a + * device-node exists for a given pci_dev, it will use normal OF tree + * walking. If not, it will implement standard swizzling and walk up the + * PCI tree until an device-node is found, at which point it will finish + * resolving using the OF tree walking. + */ +int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) +{ + struct device_node *dn, *ppnode; + struct pci_dev *ppdev; + u32 lspec; + __be32 lspec_be; + __be32 laddr[3]; + u8 pin; + int rc; + + /* Check if we have a device node, if yes, fallback to standard + * device tree parsing + */ + dn = pci_device_to_OF_node(pdev); + if (dn) { + rc = of_irq_map_one(dn, 0, out_irq); + if (!rc) + return rc; + } + + /* Ok, we don't, time to have fun. Let's start by building up an + * interrupt spec. we assume #interrupt-cells is 1, which is standard + * for PCI. If you do different, then don't use that routine. + */ + rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin); + if (rc != 0) + return rc; + /* No pin, exit */ + if (pin == 0) + return -ENODEV; + + /* Now we walk up the PCI tree */ + lspec = pin; + for (;;) { + /* Get the pci_dev of our parent */ + ppdev = pdev->bus->self; + + /* Ouch, it's a host bridge... */ + if (ppdev == NULL) { + ppnode = pci_bus_to_OF_node(pdev->bus); + + /* No node for host bridge ? give up */ + if (ppnode == NULL) + return -EINVAL; + } else { + /* We found a P2P bridge, check if it has a node */ + ppnode = pci_device_to_OF_node(ppdev); + } + + /* Ok, we have found a parent with a device-node, hand over to + * the OF parsing code. + * We build a unit address from the linux device to be used for + * resolution. Note that we use the linux bus number which may + * not match your firmware bus numbering. + * Fortunately, in most cases, interrupt-map-mask doesn't + * include the bus number as part of the matching. + * You should still be careful about that though if you intend + * to rely on this function (you ship a firmware that doesn't + * create device nodes for all PCI devices). + */ + if (ppnode) + break; + + /* We can only get here if we hit a P2P bridge with no node, + * let's do standard swizzling and try again + */ + lspec = pci_swizzle_interrupt_pin(pdev, lspec); + pdev = ppdev; + } + + lspec_be = cpu_to_be32(lspec); + laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8)); + laddr[1] = laddr[2] = cpu_to_be32(0); + return of_irq_map_raw(ppnode, &lspec_be, 1, laddr, out_irq); +} +EXPORT_SYMBOL_GPL(of_irq_map_pci); diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h new file mode 100644 index 000000000000..85a27b650d76 --- /dev/null +++ b/include/linux/of_pci.h @@ -0,0 +1,9 @@ +#ifndef __OF_PCI_H +#define __OF_PCI_H + +#include + +struct pci_dev; +struct of_irq; +int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); +#endif -- cgit v1.2.3 From 7af75af2424c3a866041e7981d91f01f93235533 Mon Sep 17 00:00:00 2001 From: Vadim Tsozik Date: Sun, 9 Jan 2011 01:00:11 -0500 Subject: USB: serial: mct_u232: added _ioctl, _msr_to_icount and _get_icount functions Added mct_u232_ioctl (implements TIOCMIWAIT command), mct_u232_get_icount (implements TIOCGICOUNT command) and mct_u232_msr_to_icount functions. MCT U232 P9 is one of a few usb to serail adapters which converts USB +/-5v voltage levels to COM +/-15 voltages. So it can also power COM interfaced devices. This makes it very usable for legacy COM interfaced data-acquisition hardware. I tested new implementation with AWARE Electronics RM-60 radiation meter, which sends pulse via RNG COM line whenever new particle is registered. Signed-off-by: Vadim Tsozik Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mct_u232.c | 107 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 2849f8c32015..1e225aacf46e 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -78,6 +78,8 @@ #include #include #include +#include +#include #include "mct_u232.h" /* @@ -104,6 +106,10 @@ static void mct_u232_break_ctl(struct tty_struct *tty, int break_state); static int mct_u232_tiocmget(struct tty_struct *tty, struct file *file); static int mct_u232_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); +static int mct_u232_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg); +static int mct_u232_get_icount(struct tty_struct *tty, + struct serial_icounter_struct *icount); static void mct_u232_throttle(struct tty_struct *tty); static void mct_u232_unthrottle(struct tty_struct *tty); @@ -150,9 +156,10 @@ static struct usb_serial_driver mct_u232_device = { .tiocmset = mct_u232_tiocmset, .attach = mct_u232_startup, .release = mct_u232_release, + .ioctl = mct_u232_ioctl, + .get_icount = mct_u232_get_icount, }; - struct mct_u232_private { spinlock_t lock; unsigned int control_state; /* Modem Line Setting (TIOCM) */ @@ -160,6 +167,9 @@ struct mct_u232_private { unsigned char last_lsr; /* Line Status Register */ unsigned char last_msr; /* Modem Status Register */ unsigned int rx_flags; /* Throttling flags */ + struct async_icount icount; + wait_queue_head_t msr_wait; /* for handling sleeping while waiting + for msr change to happen */ }; #define THROTTLED 0x01 @@ -386,6 +396,20 @@ static int mct_u232_get_modem_stat(struct usb_serial *serial, return rc; } /* mct_u232_get_modem_stat */ +static void mct_u232_msr_to_icount(struct async_icount *icount, + unsigned char msr) +{ + /* Translate Control Line states */ + if (msr & MCT_U232_MSR_DDSR) + icount->dsr++; + if (msr & MCT_U232_MSR_DCTS) + icount->cts++; + if (msr & MCT_U232_MSR_DRI) + icount->rng++; + if (msr & MCT_U232_MSR_DCD) + icount->dcd++; +} /* mct_u232_msr_to_icount */ + static void mct_u232_msr_to_state(unsigned int *control_state, unsigned char msr) { @@ -422,6 +446,7 @@ static int mct_u232_startup(struct usb_serial *serial) if (!priv) return -ENOMEM; spin_lock_init(&priv->lock); + init_waitqueue_head(&priv->msr_wait); usb_set_serial_port_data(serial->port[0], priv); init_waitqueue_head(&serial->port[0]->write_wait); @@ -621,6 +646,8 @@ static void mct_u232_read_int_callback(struct urb *urb) /* Record Control Line states */ mct_u232_msr_to_state(&priv->control_state, priv->last_msr); + mct_u232_msr_to_icount(&priv->icount, priv->last_msr); + #if 0 /* Not yet handled. See belkin_sa.c for further information */ /* Now to report any errors */ @@ -647,6 +674,7 @@ static void mct_u232_read_int_callback(struct urb *urb) tty_kref_put(tty); } #endif + wake_up_interruptible(&priv->msr_wait); spin_unlock_irqrestore(&priv->lock, flags); exit: retval = usb_submit_urb(urb, GFP_ATOMIC); @@ -826,7 +854,6 @@ static void mct_u232_throttle(struct tty_struct *tty) } } - static void mct_u232_unthrottle(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; @@ -847,6 +874,82 @@ static void mct_u232_unthrottle(struct tty_struct *tty) } } +static int mct_u232_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) +{ + DEFINE_WAIT(wait); + struct usb_serial_port *port = tty->driver_data; + struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port); + struct async_icount cnow, cprev; + unsigned long flags; + + dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd); + + switch (cmd) { + + case TIOCMIWAIT: + + dbg("%s (%d) TIOCMIWAIT", __func__, port->number); + + spin_lock_irqsave(&mct_u232_port->lock, flags); + cprev = mct_u232_port->icount; + spin_unlock_irqrestore(&mct_u232_port->lock, flags); + for ( ; ; ) { + prepare_to_wait(&mct_u232_port->msr_wait, + &wait, TASK_INTERRUPTIBLE); + schedule(); + finish_wait(&mct_u232_port->msr_wait, &wait); + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; + spin_lock_irqsave(&mct_u232_port->lock, flags); + cnow = mct_u232_port->icount; + spin_unlock_irqrestore(&mct_u232_port->lock, flags); + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && + cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) + return -EIO; /* no change => error */ + if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || + ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || + ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || + ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { + return 0; + } + cprev = cnow; + } + + } + return -ENOIOCTLCMD; +} + +static int mct_u232_get_icount(struct tty_struct *tty, + struct serial_icounter_struct *icount) +{ + struct usb_serial_port *port = tty->driver_data; + struct mct_u232_private *mct_u232_port = usb_get_serial_port_data(port); + struct async_icount *ic = &mct_u232_port->icount; + unsigned long flags; + + spin_lock_irqsave(&mct_u232_port->lock, flags); + + icount->cts = ic->cts; + icount->dsr = ic->dsr; + icount->rng = ic->rng; + icount->dcd = ic->dcd; + icount->rx = ic->rx; + icount->tx = ic->tx; + icount->frame = ic->frame; + icount->overrun = ic->overrun; + icount->parity = ic->parity; + icount->brk = ic->brk; + icount->buf_overrun = ic->buf_overrun; + + spin_unlock_irqrestore(&mct_u232_port->lock, flags); + + dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", + __func__, port->number, icount->rx, icount->tx); + return 0; +} + static int __init mct_u232_init(void) { int retval; -- cgit v1.2.3 From 553fbcde3481c98a076c9744a59ad08dbc61c099 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Fri, 14 Jan 2011 11:55:53 +0900 Subject: USB: Gadget: Initialize wMaxPacketSize if not already set Currently, for ISO and INT, a protocol driver must chose the value for wMaxPacketSize arbitrarily. The value may be too low, resulting in lesser than efficient operation or high enough to not work with all UDC drivers. Take un-initialized wMaxPacketSize as a hint to provide maximum possible packetsize for the selected endpoint. The protocol may then choose a value not bigger than that. Signed-off-by: Jassi Brar Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/epautoconf.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 8a832488ccdd..9b7360ff5aa7 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -128,6 +128,13 @@ ep_matches ( } } + /* + * If the protocol driver hasn't yet decided on wMaxPacketSize + * and wants to know the maximum possible, provide the info. + */ + if (desc->wMaxPacketSize == 0) + desc->wMaxPacketSize = cpu_to_le16(ep->maxpacket); + /* endpoint maxpacket size is an input parameter, except for bulk * where it's an output parameter representing the full speed limit. * the usb spec fixes high speed bulk maxpacket at 512 bytes. -- cgit v1.2.3 From a51ea8cc9cfcfd719240455ff8f217b4f165d1d0 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 20 Jan 2011 13:51:52 -0200 Subject: usb: gadget/fsl_mxc_udc: Detect the CPU type in run-time Make sure we are running on a MX35 processor. Signed-off-by: Fabio Estevam Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_mxc_udc.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_mxc_udc.c b/drivers/usb/gadget/fsl_mxc_udc.c index 77b1eb577029..43a49ecc1f36 100644 --- a/drivers/usb/gadget/fsl_mxc_udc.c +++ b/drivers/usb/gadget/fsl_mxc_udc.c @@ -88,15 +88,18 @@ eenahb: void fsl_udc_clk_finalize(struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; -#if defined(CONFIG_ARCH_MX35) - unsigned int v; - - /* workaround ENGcm09152 for i.MX35 */ - if (pdata->workaround & FLS_USB2_WORKAROUND_ENGCM09152) { - v = readl(MX35_IO_ADDRESS(MX35_USB_BASE_ADDR + - USBPHYCTRL_OTGBASE_OFFSET)); - writel(v | USBPHYCTRL_EVDO, MX35_IO_ADDRESS(MX35_USB_BASE_ADDR + - USBPHYCTRL_OTGBASE_OFFSET)); +#if defined(CONFIG_SOC_IMX35) + if (cpu_is_mx35()) { + unsigned int v; + + /* workaround ENGcm09152 for i.MX35 */ + if (pdata->workaround & FLS_USB2_WORKAROUND_ENGCM09152) { + v = readl(MX35_IO_ADDRESS(MX35_USB_BASE_ADDR + + USBPHYCTRL_OTGBASE_OFFSET)); + writel(v | USBPHYCTRL_EVDO, + MX35_IO_ADDRESS(MX35_USB_BASE_ADDR + + USBPHYCTRL_OTGBASE_OFFSET)); + } } #endif -- cgit v1.2.3 From b7d5b439b7a40dd0a0202fe1c118615a3fcc3b25 Mon Sep 17 00:00:00 2001 From: Andiry Xu Date: Tue, 25 Jan 2011 18:41:21 +0800 Subject: USB host: Move AMD PLL quirk to pci-quirks.c This patch moves the AMD PLL quirk code in OHCI/EHCI driver to pci-quirks.c, and exports the functions to be used by xHCI driver later. AMD PLL quirk disable the optional PM feature inside specific SB700/SB800/Hudson-2/3 platforms under the following conditions: 1. If an isochronous device is connected to OHCI/EHCI/xHCI port and is active; 2. Optional PM feature that powers down the internal Bus PLL when the link is in low power state is enabled. Without AMD PLL quirk, USB isochronous stream may stutter or have breaks occasionally, which greatly impair the performance of audio/video streams. Currently AMD PLL quirk is implemented in OHCI and EHCI driver, and will be added to xHCI driver too. They are doing similar things actually, so move the quirk code to pci-quirks.c, which has several advantages: 1. Remove duplicate defines and functions in OHCI/EHCI (and xHCI) driver and make them cleaner; 2. AMD chipset information will be probed only once and then stored. Currently they're probed during every OHCI/EHCI initialization, move the detect code to pci-quirks.c saves the repeat detect cost; 3. Build up synchronization among OHCI/EHCI/xHCI driver. In current code, every host controller enable/disable PLL only according to its own status, and may enable PLL while there is still isoc transfer on other HCs. Move the quirk to pci-quirks.c prevents this issue. Signed-off-by: Andiry Xu Cc: David Brownell Cc: Alex He Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 10 +- drivers/usb/host/ehci-pci.c | 38 +----- drivers/usb/host/ehci-sched.c | 73 ++---------- drivers/usb/host/ehci.h | 2 +- drivers/usb/host/ohci-hcd.c | 13 +-- drivers/usb/host/ohci-pci.c | 110 ++---------------- drivers/usb/host/ohci-q.c | 4 +- drivers/usb/host/ohci.h | 4 +- drivers/usb/host/pci-quirks.c | 260 ++++++++++++++++++++++++++++++++++++++++++ drivers/usb/host/pci-quirks.h | 19 +++ 10 files changed, 311 insertions(+), 222 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 6fee3cd58efe..30515d362c4b 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -114,13 +114,11 @@ MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us\n"); #define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT) -/* for ASPM quirk of ISOC on AMD SB800 */ -static struct pci_dev *amd_nb_dev; - /*-------------------------------------------------------------------------*/ #include "ehci.h" #include "ehci-dbg.c" +#include "pci-quirks.h" /*-------------------------------------------------------------------------*/ @@ -532,10 +530,8 @@ static void ehci_stop (struct usb_hcd *hcd) spin_unlock_irq (&ehci->lock); ehci_mem_cleanup (ehci); - if (amd_nb_dev) { - pci_dev_put(amd_nb_dev); - amd_nb_dev = NULL; - } + if (ehci->amd_pll_fix == 1) + usb_amd_dev_put(); #ifdef EHCI_STATS ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n", diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 76179c39c0e3..1ec8060e8cc4 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -44,35 +44,6 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) return 0; } -static int ehci_quirk_amd_SB800(struct ehci_hcd *ehci) -{ - struct pci_dev *amd_smbus_dev; - u8 rev = 0; - - amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, 0x4385, NULL); - if (!amd_smbus_dev) - return 0; - - pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev); - if (rev < 0x40) { - pci_dev_put(amd_smbus_dev); - amd_smbus_dev = NULL; - return 0; - } - - if (!amd_nb_dev) - amd_nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1510, NULL); - if (!amd_nb_dev) - ehci_err(ehci, "QUIRK: unable to get AMD NB device\n"); - - ehci_info(ehci, "QUIRK: Enable AMD SB800 L1 fix\n"); - - pci_dev_put(amd_smbus_dev); - amd_smbus_dev = NULL; - - return 1; -} - /* called during probe() after chip reset completes */ static int ehci_pci_setup(struct usb_hcd *hcd) { @@ -131,9 +102,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) /* cache this readonly data; minimize chip reads */ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); - if (ehci_quirk_amd_SB800(ehci)) - ehci->amd_l1_fix = 1; - retval = ehci_halt(ehci); if (retval) return retval; @@ -184,6 +152,9 @@ static int ehci_pci_setup(struct usb_hcd *hcd) } break; case PCI_VENDOR_ID_AMD: + /* AMD PLL quirk */ + if (usb_amd_find_chipset_info()) + ehci->amd_pll_fix = 1; /* AMD8111 EHCI doesn't work, according to AMD errata */ if (pdev->device == 0x7463) { ehci_info(ehci, "ignoring AMD8111 (errata)\n"); @@ -229,6 +200,9 @@ static int ehci_pci_setup(struct usb_hcd *hcd) } break; case PCI_VENDOR_ID_ATI: + /* AMD PLL quirk */ + if (usb_amd_find_chipset_info()) + ehci->amd_pll_fix = 1; /* SB600 and old version of SB700 have a bug in EHCI controller, * which causes usb devices lose response in some cases. */ diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index aa46f57f9ec8..b3bd1c6dc61f 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1590,63 +1590,6 @@ itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); } -#define AB_REG_BAR_LOW 0xe0 -#define AB_REG_BAR_HIGH 0xe1 -#define AB_INDX(addr) ((addr) + 0x00) -#define AB_DATA(addr) ((addr) + 0x04) -#define NB_PCIE_INDX_ADDR 0xe0 -#define NB_PCIE_INDX_DATA 0xe4 -#define NB_PIF0_PWRDOWN_0 0x01100012 -#define NB_PIF0_PWRDOWN_1 0x01100013 - -static void ehci_quirk_amd_L1(struct ehci_hcd *ehci, int disable) -{ - u32 addr, addr_low, addr_high, val; - - outb_p(AB_REG_BAR_LOW, 0xcd6); - addr_low = inb_p(0xcd7); - outb_p(AB_REG_BAR_HIGH, 0xcd6); - addr_high = inb_p(0xcd7); - addr = addr_high << 8 | addr_low; - outl_p(0x30, AB_INDX(addr)); - outl_p(0x40, AB_DATA(addr)); - outl_p(0x34, AB_INDX(addr)); - val = inl_p(AB_DATA(addr)); - - if (disable) { - val &= ~0x8; - val |= (1 << 4) | (1 << 9); - } else { - val |= 0x8; - val &= ~((1 << 4) | (1 << 9)); - } - outl_p(val, AB_DATA(addr)); - - if (amd_nb_dev) { - addr = NB_PIF0_PWRDOWN_0; - pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_ADDR, addr); - pci_read_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, &val); - if (disable) - val &= ~(0x3f << 7); - else - val |= 0x3f << 7; - - pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, val); - - addr = NB_PIF0_PWRDOWN_1; - pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_ADDR, addr); - pci_read_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, &val); - if (disable) - val &= ~(0x3f << 7); - else - val |= 0x3f << 7; - - pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, val); - } - - return; -} - /* fit urb's itds into the selected schedule slot; activate as needed */ static int itd_link_urb ( @@ -1675,8 +1618,8 @@ itd_link_urb ( } if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { - if (ehci->amd_l1_fix == 1) - ehci_quirk_amd_L1(ehci, 1); + if (ehci->amd_pll_fix == 1) + usb_amd_quirk_pll_disable(); } ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; @@ -1804,8 +1747,8 @@ itd_complete ( ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { - if (ehci->amd_l1_fix == 1) - ehci_quirk_amd_L1(ehci, 0); + if (ehci->amd_pll_fix == 1) + usb_amd_quirk_pll_enable(); } if (unlikely(list_is_singular(&stream->td_list))) { @@ -2095,8 +2038,8 @@ sitd_link_urb ( } if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { - if (ehci->amd_l1_fix == 1) - ehci_quirk_amd_L1(ehci, 1); + if (ehci->amd_pll_fix == 1) + usb_amd_quirk_pll_disable(); } ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; @@ -2200,8 +2143,8 @@ sitd_complete ( ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { - if (ehci->amd_l1_fix == 1) - ehci_quirk_amd_L1(ehci, 0); + if (ehci->amd_pll_fix == 1) + usb_amd_quirk_pll_enable(); } if (list_is_singular(&stream->td_list)) { diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 799ac16a54b4..f86d3fa20214 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -131,7 +131,7 @@ struct ehci_hcd { /* one per controller */ unsigned has_amcc_usb23:1; unsigned need_io_watchdog:1; unsigned broken_periodic:1; - unsigned amd_l1_fix:1; + unsigned amd_pll_fix:1; unsigned fs_i_thresh:1; /* Intel iso scheduling */ unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/ diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 759a12ff8048..7b791bf1e7b4 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -75,6 +75,7 @@ static const char hcd_name [] = "ohci_hcd"; #define STATECHANGE_DELAY msecs_to_jiffies(300) #include "ohci.h" +#include "pci-quirks.h" static void ohci_dump (struct ohci_hcd *ohci, int verbose); static int ohci_init (struct ohci_hcd *ohci); @@ -85,18 +86,8 @@ static int ohci_restart (struct ohci_hcd *ohci); #endif #ifdef CONFIG_PCI -static void quirk_amd_pll(int state); -static void amd_iso_dev_put(void); static void sb800_prefetch(struct ohci_hcd *ohci, int on); #else -static inline void quirk_amd_pll(int state) -{ - return; -} -static inline void amd_iso_dev_put(void) -{ - return; -} static inline void sb800_prefetch(struct ohci_hcd *ohci, int on) { return; @@ -912,7 +903,7 @@ static void ohci_stop (struct usb_hcd *hcd) if (quirk_zfmicro(ohci)) del_timer(&ohci->unlink_watchdog); if (quirk_amdiso(ohci)) - amd_iso_dev_put(); + usb_amd_dev_put(); remove_debug_files (ohci); ohci_mem_cleanup (ohci); diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 36ee9a666e93..9816a2870d00 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -22,24 +22,6 @@ #include -/* constants used to work around PM-related transfer - * glitches in some AMD 700 series southbridges - */ -#define AB_REG_BAR 0xf0 -#define AB_INDX(addr) ((addr) + 0x00) -#define AB_DATA(addr) ((addr) + 0x04) -#define AX_INDXC 0X30 -#define AX_DATAC 0x34 - -#define NB_PCIE_INDX_ADDR 0xe0 -#define NB_PCIE_INDX_DATA 0xe4 -#define PCIE_P_CNTL 0x10040 -#define BIF_NB 0x10002 - -static struct pci_dev *amd_smbus_dev; -static struct pci_dev *amd_hb_dev; -static int amd_ohci_iso_count; - /*-------------------------------------------------------------------------*/ static int broken_suspend(struct usb_hcd *hcd) @@ -168,11 +150,14 @@ static int ohci_quirk_nec(struct usb_hcd *hcd) static int ohci_quirk_amd700(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); + struct pci_dev *amd_smbus_dev; u8 rev = 0; - if (!amd_smbus_dev) - amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, - PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); + if (usb_amd_find_chipset_info()) + ohci->flags |= OHCI_QUIRK_AMD_PLL; + + amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, + PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); if (!amd_smbus_dev) return 0; @@ -184,19 +169,8 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd) ohci_dbg(ohci, "enabled AMD prefetch quirk\n"); } - if ((rev > 0x3b) || (rev < 0x30)) { - pci_dev_put(amd_smbus_dev); - amd_smbus_dev = NULL; - return 0; - } - - amd_ohci_iso_count++; - - if (!amd_hb_dev) - amd_hb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x9600, NULL); - - ohci->flags |= OHCI_QUIRK_AMD_ISO; - ohci_dbg(ohci, "enabled AMD ISO transfers quirk\n"); + pci_dev_put(amd_smbus_dev); + amd_smbus_dev = NULL; return 0; } @@ -215,74 +189,6 @@ static int ohci_quirk_nvidia_shutdown(struct usb_hcd *hcd) return 0; } -/* - * The hardware normally enables the A-link power management feature, which - * lets the system lower the power consumption in idle states. - * - * Assume the system is configured to have USB 1.1 ISO transfers going - * to or from a USB device. Without this quirk, that stream may stutter - * or have breaks occasionally. For transfers going to speakers, this - * makes a very audible mess... - * - * That audio playback corruption is due to the audio stream getting - * interrupted occasionally when the link goes in lower power state - * This USB quirk prevents the link going into that lower power state - * during audio playback or other ISO operations. - */ -static void quirk_amd_pll(int on) -{ - u32 addr; - u32 val; - u32 bit = (on > 0) ? 1 : 0; - - pci_read_config_dword(amd_smbus_dev, AB_REG_BAR, &addr); - - /* BIT names/meanings are NDA-protected, sorry ... */ - - outl(AX_INDXC, AB_INDX(addr)); - outl(0x40, AB_DATA(addr)); - outl(AX_DATAC, AB_INDX(addr)); - val = inl(AB_DATA(addr)); - val &= ~((1 << 3) | (1 << 4) | (1 << 9)); - val |= (bit << 3) | ((!bit) << 4) | ((!bit) << 9); - outl(val, AB_DATA(addr)); - - if (amd_hb_dev) { - addr = PCIE_P_CNTL; - pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_ADDR, addr); - - pci_read_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, &val); - val &= ~(1 | (1 << 3) | (1 << 4) | (1 << 9) | (1 << 12)); - val |= bit | (bit << 3) | (bit << 12); - val |= ((!bit) << 4) | ((!bit) << 9); - pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, val); - - addr = BIF_NB; - pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_ADDR, addr); - - pci_read_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, &val); - val &= ~(1 << 8); - val |= bit << 8; - pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, val); - } -} - -static void amd_iso_dev_put(void) -{ - amd_ohci_iso_count--; - if (amd_ohci_iso_count == 0) { - if (amd_smbus_dev) { - pci_dev_put(amd_smbus_dev); - amd_smbus_dev = NULL; - } - if (amd_hb_dev) { - pci_dev_put(amd_hb_dev); - amd_hb_dev = NULL; - } - } - -} - static void sb800_prefetch(struct ohci_hcd *ohci, int on) { struct pci_dev *pdev; diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 83094d067e0f..dd24fc115e48 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -52,7 +52,7 @@ __acquires(ohci->lock) ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--; if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) { if (quirk_amdiso(ohci)) - quirk_amd_pll(1); + usb_amd_quirk_pll_enable(); if (quirk_amdprefetch(ohci)) sb800_prefetch(ohci, 0); } @@ -686,7 +686,7 @@ static void td_submit_urb ( } if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) { if (quirk_amdiso(ohci)) - quirk_amd_pll(0); + usb_amd_quirk_pll_disable(); if (quirk_amdprefetch(ohci)) sb800_prefetch(ohci, 1); } diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 51facb985c84..bad11a72c202 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -401,7 +401,7 @@ struct ohci_hcd { #define OHCI_QUIRK_NEC 0x40 /* lost interrupts */ #define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */ #define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */ -#define OHCI_QUIRK_AMD_ISO 0x200 /* ISO transfers*/ +#define OHCI_QUIRK_AMD_PLL 0x200 /* AMD PLL quirk*/ #define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */ #define OHCI_QUIRK_SHUTDOWN 0x800 /* nVidia power bug */ // there are also chip quirks/bugs in init logic @@ -433,7 +433,7 @@ static inline int quirk_zfmicro(struct ohci_hcd *ohci) } static inline int quirk_amdiso(struct ohci_hcd *ohci) { - return ohci->flags & OHCI_QUIRK_AMD_ISO; + return ohci->flags & OHCI_QUIRK_AMD_PLL; } static inline int quirk_amdprefetch(struct ohci_hcd *ohci) { diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 4c502c890ebd..344b25a790e1 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -52,6 +52,266 @@ #define EHCI_USBLEGCTLSTS 4 /* legacy control/status */ #define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */ +/* AMD quirk use */ +#define AB_REG_BAR_LOW 0xe0 +#define AB_REG_BAR_HIGH 0xe1 +#define AB_REG_BAR_SB700 0xf0 +#define AB_INDX(addr) ((addr) + 0x00) +#define AB_DATA(addr) ((addr) + 0x04) +#define AX_INDXC 0x30 +#define AX_DATAC 0x34 + +#define NB_PCIE_INDX_ADDR 0xe0 +#define NB_PCIE_INDX_DATA 0xe4 +#define PCIE_P_CNTL 0x10040 +#define BIF_NB 0x10002 +#define NB_PIF0_PWRDOWN_0 0x01100012 +#define NB_PIF0_PWRDOWN_1 0x01100013 + +static struct amd_chipset_info { + struct pci_dev *nb_dev; + struct pci_dev *smbus_dev; + int nb_type; + int sb_type; + int isoc_reqs; + int probe_count; + int probe_result; +} amd_chipset; + +static DEFINE_SPINLOCK(amd_lock); + +int usb_amd_find_chipset_info(void) +{ + u8 rev = 0; + unsigned long flags; + + spin_lock_irqsave(&amd_lock, flags); + + amd_chipset.probe_count++; + /* probe only once */ + if (amd_chipset.probe_count > 1) { + spin_unlock_irqrestore(&amd_lock, flags); + return amd_chipset.probe_result; + } + + amd_chipset.smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, 0x4385, NULL); + if (amd_chipset.smbus_dev) { + pci_read_config_byte(amd_chipset.smbus_dev, + PCI_REVISION_ID, &rev); + if (rev >= 0x40) + amd_chipset.sb_type = 1; + else if (rev >= 0x30 && rev <= 0x3b) + amd_chipset.sb_type = 3; + } else { + amd_chipset.smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, + 0x780b, NULL); + if (!amd_chipset.smbus_dev) { + spin_unlock_irqrestore(&amd_lock, flags); + return 0; + } + pci_read_config_byte(amd_chipset.smbus_dev, + PCI_REVISION_ID, &rev); + if (rev >= 0x11 && rev <= 0x18) + amd_chipset.sb_type = 2; + } + + if (amd_chipset.sb_type == 0) { + if (amd_chipset.smbus_dev) { + pci_dev_put(amd_chipset.smbus_dev); + amd_chipset.smbus_dev = NULL; + } + spin_unlock_irqrestore(&amd_lock, flags); + return 0; + } + + amd_chipset.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x9601, NULL); + if (amd_chipset.nb_dev) { + amd_chipset.nb_type = 1; + } else { + amd_chipset.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, + 0x1510, NULL); + if (amd_chipset.nb_dev) { + amd_chipset.nb_type = 2; + } else { + amd_chipset.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, + 0x9600, NULL); + if (amd_chipset.nb_dev) + amd_chipset.nb_type = 3; + } + } + + amd_chipset.probe_result = 1; + printk(KERN_DEBUG "QUIRK: Enable AMD PLL fix\n"); + + spin_unlock_irqrestore(&amd_lock, flags); + return amd_chipset.probe_result; +} +EXPORT_SYMBOL_GPL(usb_amd_find_chipset_info); + +/* + * The hardware normally enables the A-link power management feature, which + * lets the system lower the power consumption in idle states. + * + * This USB quirk prevents the link going into that lower power state + * during isochronous transfers. + * + * Without this quirk, isochronous stream on OHCI/EHCI/xHCI controllers of + * some AMD platforms may stutter or have breaks occasionally. + */ +static void usb_amd_quirk_pll(int disable) +{ + u32 addr, addr_low, addr_high, val; + u32 bit = disable ? 0 : 1; + unsigned long flags; + + spin_lock_irqsave(&amd_lock, flags); + + if (disable) { + amd_chipset.isoc_reqs++; + if (amd_chipset.isoc_reqs > 1) { + spin_unlock_irqrestore(&amd_lock, flags); + return; + } + } else { + amd_chipset.isoc_reqs--; + if (amd_chipset.isoc_reqs > 0) { + spin_unlock_irqrestore(&amd_lock, flags); + return; + } + } + + if (amd_chipset.sb_type == 1 || amd_chipset.sb_type == 2) { + outb_p(AB_REG_BAR_LOW, 0xcd6); + addr_low = inb_p(0xcd7); + outb_p(AB_REG_BAR_HIGH, 0xcd6); + addr_high = inb_p(0xcd7); + addr = addr_high << 8 | addr_low; + + outl_p(0x30, AB_INDX(addr)); + outl_p(0x40, AB_DATA(addr)); + outl_p(0x34, AB_INDX(addr)); + val = inl_p(AB_DATA(addr)); + } else if (amd_chipset.sb_type == 3) { + pci_read_config_dword(amd_chipset.smbus_dev, + AB_REG_BAR_SB700, &addr); + outl(AX_INDXC, AB_INDX(addr)); + outl(0x40, AB_DATA(addr)); + outl(AX_DATAC, AB_INDX(addr)); + val = inl(AB_DATA(addr)); + } else { + spin_unlock_irqrestore(&amd_lock, flags); + return; + } + + if (disable) { + val &= ~0x08; + val |= (1 << 4) | (1 << 9); + } else { + val |= 0x08; + val &= ~((1 << 4) | (1 << 9)); + } + outl_p(val, AB_DATA(addr)); + + if (!amd_chipset.nb_dev) { + spin_unlock_irqrestore(&amd_lock, flags); + return; + } + + if (amd_chipset.nb_type == 1 || amd_chipset.nb_type == 3) { + addr = PCIE_P_CNTL; + pci_write_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_ADDR, addr); + pci_read_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_DATA, &val); + + val &= ~(1 | (1 << 3) | (1 << 4) | (1 << 9) | (1 << 12)); + val |= bit | (bit << 3) | (bit << 12); + val |= ((!bit) << 4) | ((!bit) << 9); + pci_write_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_DATA, val); + + addr = BIF_NB; + pci_write_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_ADDR, addr); + pci_read_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_DATA, &val); + val &= ~(1 << 8); + val |= bit << 8; + + pci_write_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_DATA, val); + } else if (amd_chipset.nb_type == 2) { + addr = NB_PIF0_PWRDOWN_0; + pci_write_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_ADDR, addr); + pci_read_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_DATA, &val); + if (disable) + val &= ~(0x3f << 7); + else + val |= 0x3f << 7; + + pci_write_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_DATA, val); + + addr = NB_PIF0_PWRDOWN_1; + pci_write_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_ADDR, addr); + pci_read_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_DATA, &val); + if (disable) + val &= ~(0x3f << 7); + else + val |= 0x3f << 7; + + pci_write_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_DATA, val); + } + + spin_unlock_irqrestore(&amd_lock, flags); + return; +} + +void usb_amd_quirk_pll_disable(void) +{ + usb_amd_quirk_pll(1); +} +EXPORT_SYMBOL_GPL(usb_amd_quirk_pll_disable); + +void usb_amd_quirk_pll_enable(void) +{ + usb_amd_quirk_pll(0); +} +EXPORT_SYMBOL_GPL(usb_amd_quirk_pll_enable); + +void usb_amd_dev_put(void) +{ + unsigned long flags; + + spin_lock_irqsave(&amd_lock, flags); + + amd_chipset.probe_count--; + if (amd_chipset.probe_count > 0) { + spin_unlock_irqrestore(&amd_lock, flags); + return; + } + + if (amd_chipset.nb_dev) { + pci_dev_put(amd_chipset.nb_dev); + amd_chipset.nb_dev = NULL; + } + if (amd_chipset.smbus_dev) { + pci_dev_put(amd_chipset.smbus_dev); + amd_chipset.smbus_dev = NULL; + } + amd_chipset.nb_type = 0; + amd_chipset.sb_type = 0; + amd_chipset.isoc_reqs = 0; + amd_chipset.probe_result = 0; + + spin_unlock_irqrestore(&amd_lock, flags); +} +EXPORT_SYMBOL_GPL(usb_amd_dev_put); /* * Make sure the controller is completely inactive, unable to diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index 1564edfff6fe..4d2118cf1ff8 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h @@ -1,7 +1,26 @@ #ifndef __LINUX_USB_PCI_QUIRKS_H #define __LINUX_USB_PCI_QUIRKS_H +#ifdef CONFIG_PCI void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); +int usb_amd_find_chipset_info(void); +void usb_amd_dev_put(void); +void usb_amd_quirk_pll_disable(void); +void usb_amd_quirk_pll_enable(void); +#else +static inline void usb_amd_quirk_pll_disable(void) +{ + return; +} +static inline void usb_amd_quirk_pll_enable(void) +{ + return; +} +static inline void usb_amd_dev_put(void) +{ + return; +} +#endif /* CONFIG_PCI */ #endif /* __LINUX_USB_PCI_QUIRKS_H */ -- cgit v1.2.3 From fc427a5a4bf3be770d7fbd933474957062049f1f Mon Sep 17 00:00:00 2001 From: David Daney Date: Tue, 25 Jan 2011 09:59:34 -0800 Subject: USB: EHCI: Remove dead code from ehci-sched.c The pre-release GCC-4.6 now correctly flags this code as dead. Signed-off-by: David Daney Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-sched.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index b3bd1c6dc61f..1543c838b3d1 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1048,8 +1048,6 @@ iso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream) * not like a QH -- no persistent state (toggle, halt) */ if (stream->refcount == 1) { - int is_in; - // BUG_ON (!list_empty(&stream->td_list)); while (!list_empty (&stream->free_list)) { @@ -1076,7 +1074,6 @@ iso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream) } } - is_in = (stream->bEndpointAddress & USB_DIR_IN) ? 0x10 : 0; stream->bEndpointAddress &= 0x0f; if (stream->ep) stream->ep->hcpriv = NULL; -- cgit v1.2.3 From 9a1cadb9dd9130345d59638f5b6a8a4982c2b34a Mon Sep 17 00:00:00 2001 From: David Daney Date: Tue, 25 Jan 2011 09:59:35 -0800 Subject: USB: EHCI: Cleanup and rewrite ehci_vdgb(). The vdbg macro is not used anywhere so it can be removed. With pre-release GCC-4.6, there are several complaints of variables that are 'set but not used' caused by the ehci_vdbg() macro expanding to something that does not contain any of its arguments. We can quiet this warning by rewriting ehci_vdbg() as a variadic static inline that does nothing. Signed-off-by: David Daney Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-dbg.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 3be238a24cc5..693c29b30521 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -28,11 +28,9 @@ dev_warn (ehci_to_hcd(ehci)->self.controller , fmt , ## args ) #ifdef VERBOSE_DEBUG -# define vdbg dbg # define ehci_vdbg ehci_dbg #else -# define vdbg(fmt,args...) do { } while (0) -# define ehci_vdbg(ehci, fmt, args...) do { } while (0) + static inline void ehci_vdbg(struct ehci_hcd *ehci, ...) {} #endif #ifdef DEBUG -- cgit v1.2.3 From eb34a90861a290cd271f4b887c0d59070e1b69b0 Mon Sep 17 00:00:00 2001 From: David Daney Date: Tue, 25 Jan 2011 09:59:36 -0800 Subject: USB: EHCI: Rearrange EHCI_URB_TRACE code to avoid GCC-4.6 warnings. With pre-release GCC-4.6, we get a 'set but not used' warning when EHCI_URB_TRACE is not set because we set the qtd variable without using it. Rearrange the statements so that we only set qtd if it will be used. Signed-off-by: David Daney Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-q.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 233c288e3f93..fe99895fb098 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -1107,22 +1107,24 @@ submit_async ( struct list_head *qtd_list, gfp_t mem_flags ) { - struct ehci_qtd *qtd; int epnum; unsigned long flags; struct ehci_qh *qh = NULL; int rc; - qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list); epnum = urb->ep->desc.bEndpointAddress; #ifdef EHCI_URB_TRACE - ehci_dbg (ehci, - "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n", - __func__, urb->dev->devpath, urb, - epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out", - urb->transfer_buffer_length, - qtd, urb->ep->hcpriv); + { + struct ehci_qtd *qtd; + qtd = list_entry(qtd_list->next, struct ehci_qtd, qtd_list); + ehci_dbg(ehci, + "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n", + __func__, urb->dev->devpath, urb, + epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out", + urb->transfer_buffer_length, + qtd, urb->ep->hcpriv); + } #endif spin_lock_irqsave (&ehci->lock, flags); -- cgit v1.2.3 From ac8d67417816fa7c568b24a8f2891eb02e6d0462 Mon Sep 17 00:00:00 2001 From: David Daney Date: Tue, 25 Jan 2011 09:59:37 -0800 Subject: USB: EHCI: Rearrange create_companion_file() to avoid GCC-4.6 warnings. In create_companion_file() there is a bogus assignemt to i created for the express purpose of avoiding an ignored return value warning. With pre-release GCC-4.6, this causes a 'set but not used' warning. Kick the problem further down the road by just returning i. All the callers of create_companion_file() ignore its return value, so all is good: o No warnings are issued. o We still subvert the desires of the authors of device_create_file() by ignorning error conditions. Signed-off-by: David Daney Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hub.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 796ea0c8900f..5aa6c4947325 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -531,14 +531,15 @@ static ssize_t store_companion(struct device *dev, } static DEVICE_ATTR(companion, 0644, show_companion, store_companion); -static inline void create_companion_file(struct ehci_hcd *ehci) +static inline int create_companion_file(struct ehci_hcd *ehci) { - int i; + int i = 0; /* with integrated TT there is no companion! */ if (!ehci_is_TDI(ehci)) i = device_create_file(ehci_to_hcd(ehci)->self.controller, &dev_attr_companion); + return i; } static inline void remove_companion_file(struct ehci_hcd *ehci) -- cgit v1.2.3 From d25bc4db723a44c097268b466ff74bfba4bcc4f3 Mon Sep 17 00:00:00 2001 From: Pete Zaitcev Date: Thu, 3 Feb 2011 22:01:36 -0700 Subject: USB: usbmon: fix-up docs and text API for sparse ISO This is based on a patch that Alan Stern wrote. It did the same simple thing in both text and binary cases. In the same time, Marton and I fixed the binary side properly, but this leaves the text to be fixed. It is not very important due to low maxium data size of text, but let's add it just for extra correctness. The pseudocode is too much to keep fixed up, and we have real code to be used as examples now, so let's drop it too. Signed-off-by: Pete Zaitcev Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/usbmon.txt | 42 +++++++++--------------------------------- drivers/usb/mon/mon_text.c | 3 +++ 2 files changed, 12 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/Documentation/usb/usbmon.txt b/Documentation/usb/usbmon.txt index 66f92d1194c1..a4efa0462f05 100644 --- a/Documentation/usb/usbmon.txt +++ b/Documentation/usb/usbmon.txt @@ -12,6 +12,10 @@ Controller Drivers (HCD). So, if HCD is buggy, the traces reported by usbmon may not correspond to bus transactions precisely. This is the same situation as with tcpdump. +Two APIs are currently implemented: "text" and "binary". The binary API +is available through a character device in /dev namespace and is an ABI. +The text API is deprecated since 2.6.35, but available for convenience. + * How to use usbmon to collect raw text traces Unlike the packet socket, usbmon has an interface which provides traces @@ -162,39 +166,11 @@ Here is the list of words, from left to right: not machine words, but really just a byte stream split into words to make it easier to read. Thus, the last word may contain from one to four bytes. The length of collected data is limited and can be less than the data length - report in Data Length word. - -Here is an example of code to read the data stream in a well known programming -language: - -class ParsedLine { - int data_len; /* Available length of data */ - byte data[]; - - void parseData(StringTokenizer st) { - int availwords = st.countTokens(); - data = new byte[availwords * 4]; - data_len = 0; - while (st.hasMoreTokens()) { - String data_str = st.nextToken(); - int len = data_str.length() / 2; - int i; - int b; // byte is signed, apparently?! XXX - for (i = 0; i < len; i++) { - // data[data_len] = Byte.parseByte( - // data_str.substring(i*2, i*2 + 2), - // 16); - b = Integer.parseInt( - data_str.substring(i*2, i*2 + 2), - 16); - if (b >= 128) - b *= -1; - data[data_len] = (byte) b; - data_len++; - } - } - } -} + reported in the Data Length word. In the case of an Isochronous input (Zi) + completion where the received data is sparse in the buffer, the length of + the collected data can be greater than the Data Length value (because Data + Length counts only the bytes that were received whereas the Data words + contain the entire transfer buffer). Examples: diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index a545d65f6e57..c302e1983c70 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c @@ -236,6 +236,9 @@ static void mon_text_event(struct mon_reader_text *rp, struct urb *urb, fp++; dp++; } + /* Wasteful, but simple to understand: ISO 'C' is sparse. */ + if (ev_type == 'C') + ep->length = urb->transfer_buffer_length; } ep->setup_flag = mon_text_get_setup(ep, urb, ev_type, rp->r.m_bus); -- cgit v1.2.3 From c8cf203a1d228fa001b95534f639ffb7a23d5386 Mon Sep 17 00:00:00 2001 From: Robert Morell Date: Wed, 26 Jan 2011 19:06:47 -0800 Subject: USB: HCD: Add usb_hcd prefix to exported functions The convention is to prefix symbols exported from the USB HCD core with "usb_hcd". This change makes unmap_urb_setup_for_dma() and unmap_urb_for_dma() consistent with that. Signed-off-by: Robert Morell Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 16 ++++++++-------- drivers/usb/host/imx21-hcd.c | 5 +++-- drivers/usb/musb/musb_host.c | 4 ++-- include/linux/usb/hcd.h | 4 ++-- 4 files changed, 15 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 6a95017fa62b..335c1ddb260d 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1262,7 +1262,7 @@ static void hcd_free_coherent(struct usb_bus *bus, dma_addr_t *dma_handle, *dma_handle = 0; } -void unmap_urb_setup_for_dma(struct usb_hcd *hcd, struct urb *urb) +void usb_hcd_unmap_urb_setup_for_dma(struct usb_hcd *hcd, struct urb *urb) { if (urb->transfer_flags & URB_SETUP_MAP_SINGLE) dma_unmap_single(hcd->self.controller, @@ -1279,13 +1279,13 @@ void unmap_urb_setup_for_dma(struct usb_hcd *hcd, struct urb *urb) /* Make it safe to call this routine more than once */ urb->transfer_flags &= ~(URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL); } -EXPORT_SYMBOL_GPL(unmap_urb_setup_for_dma); +EXPORT_SYMBOL_GPL(usb_hcd_unmap_urb_setup_for_dma); -void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) +void usb_hcd_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) { enum dma_data_direction dir; - unmap_urb_setup_for_dma(hcd, urb); + usb_hcd_unmap_urb_setup_for_dma(hcd, urb); dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; if (urb->transfer_flags & URB_DMA_MAP_SG) @@ -1314,7 +1314,7 @@ void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) urb->transfer_flags &= ~(URB_DMA_MAP_SG | URB_DMA_MAP_PAGE | URB_DMA_MAP_SINGLE | URB_MAP_LOCAL); } -EXPORT_SYMBOL_GPL(unmap_urb_for_dma); +EXPORT_SYMBOL_GPL(usb_hcd_unmap_urb_for_dma); static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) @@ -1410,7 +1410,7 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, } if (ret && (urb->transfer_flags & (URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL))) - unmap_urb_for_dma(hcd, urb); + usb_hcd_unmap_urb_for_dma(hcd, urb); } return ret; } @@ -1451,7 +1451,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) if (likely(status == 0)) { status = hcd->driver->urb_enqueue(hcd, urb, mem_flags); if (unlikely(status)) - unmap_urb_for_dma(hcd, urb); + usb_hcd_unmap_urb_for_dma(hcd, urb); } } @@ -1557,7 +1557,7 @@ void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status) !status)) status = -EREMOTEIO; - unmap_urb_for_dma(hcd, urb); + usb_hcd_unmap_urb_for_dma(hcd, urb); usbmon_urb_complete(&hcd->self, urb, status); usb_unanchor_urb(urb); diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index f90d003f2302..b7dfda8a1d51 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -927,7 +927,8 @@ static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb) if (state == US_CTRL_SETUP) { dir = TD_DIR_SETUP; if (unsuitable_for_dma(urb->setup_dma)) - unmap_urb_setup_for_dma(imx21->hcd, urb); + usb_hcd_unmap_urb_setup_for_dma(imx21->hcd, + urb); etd->dma_handle = urb->setup_dma; etd->cpu_buffer = urb->setup_packet; bufround = 0; @@ -943,7 +944,7 @@ static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb) dir = usb_pipeout(pipe) ? TD_DIR_OUT : TD_DIR_IN; bufround = (dir == TD_DIR_IN) ? 1 : 0; if (unsuitable_for_dma(urb->transfer_dma)) - unmap_urb_for_dma(imx21->hcd, urb); + usb_hcd_unmap_urb_for_dma(imx21->hcd, urb); etd->dma_handle = urb->transfer_dma; etd->cpu_buffer = urb->transfer_buffer; diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 4d5bcb4e14d2..4d2f3f79c425 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -1336,7 +1336,7 @@ void musb_host_tx(struct musb *musb, u8 epnum) if (length > qh->maxpacket) length = qh->maxpacket; /* Unmap the buffer so that CPU can use it */ - unmap_urb_for_dma(musb_to_hcd(musb), urb); + usb_hcd_unmap_urb_for_dma(musb_to_hcd(musb), urb); musb_write_fifo(hw_ep, length, urb->transfer_buffer + offset); qh->segsize = length; @@ -1758,7 +1758,7 @@ void musb_host_rx(struct musb *musb, u8 epnum) if (!dma) { /* Unmap the buffer so that CPU can use it */ - unmap_urb_for_dma(musb_to_hcd(musb), urb); + usb_hcd_unmap_urb_for_dma(musb_to_hcd(musb), urb); done = musb_host_packet_rx(musb, urb, epnum, iso_err); DBG(6, "read %spacket\n", done ? "last " : ""); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index dd6ee49a0844..395704bdf5cc 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -329,8 +329,8 @@ extern int usb_hcd_submit_urb(struct urb *urb, gfp_t mem_flags); extern int usb_hcd_unlink_urb(struct urb *urb, int status); extern void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status); -extern void unmap_urb_setup_for_dma(struct usb_hcd *, struct urb *); -extern void unmap_urb_for_dma(struct usb_hcd *, struct urb *); +extern void usb_hcd_unmap_urb_setup_for_dma(struct usb_hcd *, struct urb *); +extern void usb_hcd_unmap_urb_for_dma(struct usb_hcd *, struct urb *); extern void usb_hcd_flush_endpoint(struct usb_device *udev, struct usb_host_endpoint *ep); extern void usb_hcd_disable_endpoint(struct usb_device *udev, -- cgit v1.2.3 From 2694a48d9007a8bdf1731c1b97d4942c9cc49296 Mon Sep 17 00:00:00 2001 From: Robert Morell Date: Wed, 26 Jan 2011 19:06:48 -0800 Subject: USB: HCD: Add driver hooks for (un)?map_urb_for_dma Provide optional hooks for the host controller driver to override the default DMA mapping and unmapping routines. In general, these shouldn't be necessary unless the host controller has special DMA requirements, such as alignment contraints. If these are not specified, the general usb_hcd_(un)?map_urb_for_dma functions will be used instead. Also, pass the status to unmap_urb_for_dma so it can know whether the DMA buffer has been overwritten. Finally, add a flag to be used by these implementations if they allocated a temporary buffer so it can be freed properly when unmapping. Signed-off-by: Robert Morell Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 22 ++++++++++++++++++++-- include/linux/usb.h | 1 + include/linux/usb/hcd.h | 15 +++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 335c1ddb260d..d0b782c4523a 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1281,6 +1281,14 @@ void usb_hcd_unmap_urb_setup_for_dma(struct usb_hcd *hcd, struct urb *urb) } EXPORT_SYMBOL_GPL(usb_hcd_unmap_urb_setup_for_dma); +static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) +{ + if (hcd->driver->unmap_urb_for_dma) + hcd->driver->unmap_urb_for_dma(hcd, urb); + else + usb_hcd_unmap_urb_for_dma(hcd, urb); +} + void usb_hcd_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) { enum dma_data_direction dir; @@ -1318,6 +1326,15 @@ EXPORT_SYMBOL_GPL(usb_hcd_unmap_urb_for_dma); static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) +{ + if (hcd->driver->map_urb_for_dma) + return hcd->driver->map_urb_for_dma(hcd, urb, mem_flags); + else + return usb_hcd_map_urb_for_dma(hcd, urb, mem_flags); +} + +int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, + gfp_t mem_flags) { enum dma_data_direction dir; int ret = 0; @@ -1414,6 +1431,7 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, } return ret; } +EXPORT_SYMBOL_GPL(usb_hcd_map_urb_for_dma); /*-------------------------------------------------------------------------*/ @@ -1451,7 +1469,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) if (likely(status == 0)) { status = hcd->driver->urb_enqueue(hcd, urb, mem_flags); if (unlikely(status)) - usb_hcd_unmap_urb_for_dma(hcd, urb); + unmap_urb_for_dma(hcd, urb); } } @@ -1557,7 +1575,7 @@ void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status) !status)) status = -EREMOTEIO; - usb_hcd_unmap_urb_for_dma(hcd, urb); + unmap_urb_for_dma(hcd, urb); usbmon_urb_complete(&hcd->self, urb, status); usb_unanchor_urb(urb); diff --git a/include/linux/usb.h b/include/linux/usb.h index bd69b65f3356..e63efeb378e3 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -976,6 +976,7 @@ extern int usb_disabled(void); #define URB_SETUP_MAP_SINGLE 0x00100000 /* Setup packet DMA mapped */ #define URB_SETUP_MAP_LOCAL 0x00200000 /* HCD-local setup packet */ #define URB_DMA_SG_COMBINED 0x00400000 /* S-G entries were combined */ +#define URB_ALIGNED_TEMP_BUFFER 0x00800000 /* Temp buffer was alloc'd */ struct usb_iso_packet_descriptor { unsigned int offset; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 395704bdf5cc..92b96fe39307 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -233,6 +233,19 @@ struct hc_driver { int (*urb_dequeue)(struct usb_hcd *hcd, struct urb *urb, int status); + /* + * (optional) these hooks allow an HCD to override the default DMA + * mapping and unmapping routines. In general, they shouldn't be + * necessary unless the host controller has special DMA requirements, + * such as alignment contraints. If these are not specified, the + * general usb_hcd_(un)?map_urb_for_dma functions will be used instead + * (and it may be a good idea to call these functions in your HCD + * implementation) + */ + int (*map_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb, + gfp_t mem_flags); + void (*unmap_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb); + /* hw synch, freeing endpoint resources that urb_dequeue can't */ void (*endpoint_disable)(struct usb_hcd *hcd, struct usb_host_endpoint *ep); @@ -329,6 +342,8 @@ extern int usb_hcd_submit_urb(struct urb *urb, gfp_t mem_flags); extern int usb_hcd_unlink_urb(struct urb *urb, int status); extern void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status); +extern int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, + gfp_t mem_flags); extern void usb_hcd_unmap_urb_setup_for_dma(struct usb_hcd *, struct urb *); extern void usb_hcd_unmap_urb_for_dma(struct usb_hcd *, struct urb *); extern void usb_hcd_flush_endpoint(struct usb_device *udev, -- cgit v1.2.3 From ce1fd3585709e833ad102167024e97217734dbfd Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Fri, 28 Jan 2011 13:55:36 +0100 Subject: USB: gadget: f_fs: even zero-length packets require a buffer Some UDC drivers fails to queue a request if req->buf == NULL even for ZLP requests. This patch adds a poisoned pointer instead of NULL to make the code compliant with the gadget specification and catches possible bug in the UDC driver if it tries to dereference buffer pointer on ZLP request. Signed-off-by: Marek Szyprowski Signed-off-by: Kyungmin Park Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/f_fs.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 1499f9e4afa8..19fffccc370d 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -368,6 +368,14 @@ static int __ffs_ep0_queue_wait(struct ffs_data *ffs, char *data, size_t len) req->buf = data; req->length = len; + /* + * UDC layer requires to provide a buffer even for ZLP, but should + * not use it at all. Let's provide some poisoned pointer to catch + * possible bug in the driver. + */ + if (req->buf == NULL) + req->buf = (void *)0xDEADBABE; + INIT_COMPLETION(ffs->ep0req_completion); ret = usb_ep_queue(ffs->gadget->ep0, req, GFP_ATOMIC); -- cgit v1.2.3 From 5c88b02196a99332dacf305c8757674dd7a303ff Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Fri, 4 Feb 2011 02:23:09 -0600 Subject: drivers:misc: ti-st: register with channel IDs The architecture of shared transport had begun with individual protocols like bluetooth, fm and gps telling the shared transport what sort of protocol they are and then expecting the ST driver to parse the incoming data from chip and forward data only relevant to the protocol drivers. This change would mean each protocol drivers would also send information to ST driver as to how to intrepret their protocol data coming out of the chip. Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_core.c | 355 ++++++++++++++----------------------------- drivers/misc/ti-st/st_kim.c | 56 ++++--- include/linux/ti_wilink_st.h | 40 +++-- 3 files changed, 167 insertions(+), 284 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index f9aad06d1ae5..84d73c5cb74d 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -25,10 +25,9 @@ #include #include -/* understand BT, FM and GPS for now */ -#include -#include -#include +#include +#include + #include /* function pointer pointing to either, @@ -38,21 +37,20 @@ void (*st_recv) (void*, const unsigned char*, long); /********************************************************************/ -#if 0 -/* internal misc functions */ -bool is_protocol_list_empty(void) +static void add_channel_to_table(struct st_data_s *st_gdata, + struct st_proto_s *new_proto) { - unsigned char i = 0; - pr_debug(" %s ", __func__); - for (i = 0; i < ST_MAX; i++) { - if (st_gdata->list[i] != NULL) - return ST_NOTEMPTY; - /* not empty */ - } - /* list empty */ - return ST_EMPTY; + pr_info("%s: id %d\n", __func__, new_proto->chnl_id); + /* list now has the channel id as index itself */ + st_gdata->list[new_proto->chnl_id] = new_proto; +} + +static void remove_channel_from_table(struct st_data_s *st_gdata, + struct st_proto_s *proto) +{ + pr_info("%s: id %d\n", __func__, proto->chnl_id); + st_gdata->list[proto->chnl_id] = NULL; } -#endif /* can be called in from * -- KIM (during fw download) @@ -82,15 +80,15 @@ int st_int_write(struct st_data_s *st_gdata, * push the skb received to relevant * protocol stacks */ -void st_send_frame(enum proto_type protoid, struct st_data_s *st_gdata) +void st_send_frame(unsigned char chnl_id, struct st_data_s *st_gdata) { - pr_info(" %s(prot:%d) ", __func__, protoid); + pr_info(" %s(prot:%d) ", __func__, chnl_id); if (unlikely (st_gdata == NULL || st_gdata->rx_skb == NULL - || st_gdata->list[protoid] == NULL)) { - pr_err("protocol %d not registered, no data to send?", - protoid); + || st_gdata->list[chnl_id] == NULL)) { + pr_err("chnl_id %d not registered, no data to send?", + chnl_id); kfree_skb(st_gdata->rx_skb); return; } @@ -99,17 +97,17 @@ void st_send_frame(enum proto_type protoid, struct st_data_s *st_gdata) * - should be just skb_queue_tail for the * protocol stack driver */ - if (likely(st_gdata->list[protoid]->recv != NULL)) { + if (likely(st_gdata->list[chnl_id]->recv != NULL)) { if (unlikely - (st_gdata->list[protoid]->recv - (st_gdata->list[protoid]->priv_data, st_gdata->rx_skb) + (st_gdata->list[chnl_id]->recv + (st_gdata->list[chnl_id]->priv_data, st_gdata->rx_skb) != 0)) { - pr_err(" proto stack %d's ->recv failed", protoid); + pr_err(" proto stack %d's ->recv failed", chnl_id); kfree_skb(st_gdata->rx_skb); return; } } else { - pr_err(" proto stack %d's ->recv null", protoid); + pr_err(" proto stack %d's ->recv null", chnl_id); kfree_skb(st_gdata->rx_skb); } return; @@ -124,7 +122,7 @@ void st_reg_complete(struct st_data_s *st_gdata, char err) { unsigned char i = 0; pr_info(" %s ", __func__); - for (i = 0; i < ST_MAX; i++) { + for (i = 0; i < ST_MAX_CHANNELS; i++) { if (likely(st_gdata != NULL && st_gdata->list[i] != NULL && st_gdata->list[i]->reg_complete_cb != NULL)) st_gdata->list[i]->reg_complete_cb @@ -133,7 +131,7 @@ void st_reg_complete(struct st_data_s *st_gdata, char err) } static inline int st_check_data_len(struct st_data_s *st_gdata, - int protoid, int len) + unsigned char chnl_id, int len) { int room = skb_tailroom(st_gdata->rx_skb); @@ -144,7 +142,7 @@ static inline int st_check_data_len(struct st_data_s *st_gdata, * has zero length payload. So, ask ST CORE to * forward the packet to protocol driver (BT/FM/GPS) */ - st_send_frame(protoid, st_gdata); + st_send_frame(chnl_id, st_gdata); } else if (len > room) { /* Received packet's payload length is larger. @@ -157,7 +155,7 @@ static inline int st_check_data_len(struct st_data_s *st_gdata, /* Packet header has non-zero payload length and * we have enough space in created skb. Lets read * payload data */ - st_gdata->rx_state = ST_BT_W4_DATA; + st_gdata->rx_state = ST_W4_DATA; st_gdata->rx_count = len; return len; } @@ -167,6 +165,7 @@ static inline int st_check_data_len(struct st_data_s *st_gdata, st_gdata->rx_state = ST_W4_PACKET_TYPE; st_gdata->rx_skb = NULL; st_gdata->rx_count = 0; + st_gdata->rx_chnl = 0; return 0; } @@ -208,13 +207,10 @@ void st_int_recv(void *disc_data, const unsigned char *data, long count) { char *ptr; - struct hci_event_hdr *eh; - struct hci_acl_hdr *ah; - struct hci_sco_hdr *sh; - struct fm_event_hdr *fm; - struct gps_event_hdr *gps; - int len = 0, type = 0, dlen = 0; - static enum proto_type protoid = ST_MAX; + struct st_proto_s *proto; + unsigned short payload_len = 0; + int len = 0, type = 0; + unsigned char *plen; struct st_data_s *st_gdata = (struct st_data_s *)disc_data; ptr = (char *)data; @@ -242,64 +238,36 @@ void st_int_recv(void *disc_data, /* Check ST RX state machine , where are we? */ switch (st_gdata->rx_state) { - - /* Waiting for complete packet ? */ - case ST_BT_W4_DATA: + /* Waiting for complete packet ? */ + case ST_W4_DATA: pr_debug("Complete pkt received"); - /* Ask ST CORE to forward * the packet to protocol driver */ - st_send_frame(protoid, st_gdata); + st_send_frame(st_gdata->rx_chnl, st_gdata); st_gdata->rx_state = ST_W4_PACKET_TYPE; st_gdata->rx_skb = NULL; - protoid = ST_MAX; /* is this required ? */ - continue; - - /* Waiting for Bluetooth event header ? */ - case ST_BT_W4_EVENT_HDR: - eh = (struct hci_event_hdr *)st_gdata->rx_skb-> - data; - - pr_debug("Event header: evt 0x%2.2x" - "plen %d", eh->evt, eh->plen); - - st_check_data_len(st_gdata, protoid, eh->plen); - continue; - - /* Waiting for Bluetooth acl header ? */ - case ST_BT_W4_ACL_HDR: - ah = (struct hci_acl_hdr *)st_gdata->rx_skb-> - data; - dlen = __le16_to_cpu(ah->dlen); - - pr_info("ACL header: dlen %d", dlen); - - st_check_data_len(st_gdata, protoid, dlen); - continue; - - /* Waiting for Bluetooth sco header ? */ - case ST_BT_W4_SCO_HDR: - sh = (struct hci_sco_hdr *)st_gdata->rx_skb-> - data; - - pr_info("SCO header: dlen %d", sh->dlen); - - st_check_data_len(st_gdata, protoid, sh->dlen); - continue; - case ST_FM_W4_EVENT_HDR: - fm = (struct fm_event_hdr *)st_gdata->rx_skb-> - data; - pr_info("FM Header: "); - st_check_data_len(st_gdata, ST_FM, fm->plen); continue; - /* TODO : Add GPS packet machine logic here */ - case ST_GPS_W4_EVENT_HDR: - /* [0x09 pkt hdr][R/W byte][2 byte len] */ - gps = (struct gps_event_hdr *)st_gdata->rx_skb-> - data; - pr_info("GPS Header: "); - st_check_data_len(st_gdata, ST_GPS, gps->plen); + /* parse the header to know details */ + case ST_W4_HEADER: + proto = st_gdata->list[st_gdata->rx_chnl]; + plen = + &st_gdata->rx_skb->data + [proto->offset_len_in_hdr]; + pr_info("plen pointing to %x\n", *plen); + if (proto->len_size == 1)/* 1 byte len field */ + payload_len = *(unsigned char *)plen; + else if (proto->len_size == 2) + payload_len = + __le16_to_cpu(*(unsigned short *)plen); + else + pr_info("%s: invalid length " + "for id %d\n", + __func__, proto->chnl_id); + st_check_data_len(st_gdata, proto->chnl_id, + payload_len); + pr_info("off %d, pay len %d\n", + proto->offset_len_in_hdr, payload_len); continue; } /* end of switch rx_state */ } @@ -308,51 +276,6 @@ void st_int_recv(void *disc_data, /* Check first byte of packet and identify module * owner (BT/FM/GPS) */ switch (*ptr) { - - /* Bluetooth event packet? */ - case HCI_EVENT_PKT: - pr_info("Event packet"); - st_gdata->rx_state = ST_BT_W4_EVENT_HDR; - st_gdata->rx_count = HCI_EVENT_HDR_SIZE; - type = HCI_EVENT_PKT; - protoid = ST_BT; - break; - - /* Bluetooth acl packet? */ - case HCI_ACLDATA_PKT: - pr_info("ACL packet"); - st_gdata->rx_state = ST_BT_W4_ACL_HDR; - st_gdata->rx_count = HCI_ACL_HDR_SIZE; - type = HCI_ACLDATA_PKT; - protoid = ST_BT; - break; - - /* Bluetooth sco packet? */ - case HCI_SCODATA_PKT: - pr_info("SCO packet"); - st_gdata->rx_state = ST_BT_W4_SCO_HDR; - st_gdata->rx_count = HCI_SCO_HDR_SIZE; - type = HCI_SCODATA_PKT; - protoid = ST_BT; - break; - - /* Channel 8(FM) packet? */ - case ST_FM_CH8_PKT: - pr_info("FM CH8 packet"); - type = ST_FM_CH8_PKT; - st_gdata->rx_state = ST_FM_W4_EVENT_HDR; - st_gdata->rx_count = FM_EVENT_HDR_SIZE; - protoid = ST_FM; - break; - - /* Channel 9(GPS) packet? */ - case 0x9: /*ST_LL_GPS_CH9_PKT */ - pr_info("GPS CH9 packet"); - type = 0x9; /* ST_LL_GPS_CH9_PKT; */ - protoid = ST_GPS; - st_gdata->rx_state = ST_GPS_W4_EVENT_HDR; - st_gdata->rx_count = 3; /* GPS_EVENT_HDR_SIZE -1*/ - break; case LL_SLEEP_IND: case LL_SLEEP_ACK: case LL_WAKE_UP_IND: @@ -373,57 +296,22 @@ void st_int_recv(void *disc_data, continue; /* Unknow packet? */ default: - pr_err("Unknown packet type %2.2x", (__u8) *ptr); - ptr++; - count--; - continue; + type = *ptr; + st_gdata->rx_skb = alloc_skb( + st_gdata->list[type]->max_frame_size, + GFP_ATOMIC); + skb_reserve(st_gdata->rx_skb, + st_gdata->list[type]->reserve); + /* next 2 required for BT only */ + st_gdata->rx_skb->cb[0] = type; /*pkt_type*/ + st_gdata->rx_skb->cb[1] = 0; /*incoming*/ + st_gdata->rx_chnl = *ptr; + st_gdata->rx_state = ST_W4_HEADER; + st_gdata->rx_count = st_gdata->list[type]->hdr_len; + pr_info("rx_count %ld\n", st_gdata->rx_count); }; ptr++; count--; - - switch (protoid) { - case ST_BT: - /* Allocate new packet to hold received data */ - st_gdata->rx_skb = - bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); - if (!st_gdata->rx_skb) { - pr_err("Can't allocate mem for new packet"); - st_gdata->rx_state = ST_W4_PACKET_TYPE; - st_gdata->rx_count = 0; - return; - } - bt_cb(st_gdata->rx_skb)->pkt_type = type; - break; - case ST_FM: /* for FM */ - st_gdata->rx_skb = - alloc_skb(FM_MAX_FRAME_SIZE, GFP_ATOMIC); - if (!st_gdata->rx_skb) { - pr_err("Can't allocate mem for new packet"); - st_gdata->rx_state = ST_W4_PACKET_TYPE; - st_gdata->rx_count = 0; - return; - } - /* place holder 0x08 */ - skb_reserve(st_gdata->rx_skb, 1); - st_gdata->rx_skb->cb[0] = ST_FM_CH8_PKT; - break; - case ST_GPS: - /* for GPS */ - st_gdata->rx_skb = - alloc_skb(100 /*GPS_MAX_FRAME_SIZE */ , GFP_ATOMIC); - if (!st_gdata->rx_skb) { - pr_err("Can't allocate mem for new packet"); - st_gdata->rx_state = ST_W4_PACKET_TYPE; - st_gdata->rx_count = 0; - return; - } - /* place holder 0x09 */ - skb_reserve(st_gdata->rx_skb, 1); - st_gdata->rx_skb->cb[0] = 0x09; /*ST_GPS_CH9_PKT; */ - break; - case ST_MAX: - break; - } } pr_debug("done %s", __func__); return; @@ -565,20 +453,28 @@ long st_register(struct st_proto_s *new_proto) unsigned long flags = 0; st_kim_ref(&st_gdata, 0); - pr_info("%s(%d) ", __func__, new_proto->type); + pr_info("%s(%d) ", __func__, new_proto->chnl_id); if (st_gdata == NULL || new_proto == NULL || new_proto->recv == NULL || new_proto->reg_complete_cb == NULL) { pr_err("gdata/new_proto/recv or reg_complete_cb not ready"); + if (st_gdata == NULL) + pr_err("error 1\n"); + if (new_proto == NULL) + pr_err("error 2\n"); + if (new_proto->recv == NULL) + pr_err("error 3\n"); + if (new_proto->reg_complete_cb == NULL) + pr_err("erro 4\n"); return -1; } - if (new_proto->type < ST_BT || new_proto->type >= ST_MAX) { - pr_err("protocol %d not supported", new_proto->type); + if (new_proto->chnl_id >= ST_MAX_CHANNELS) { + pr_err("chnl_id %d not supported", new_proto->chnl_id); return -EPROTONOSUPPORT; } - if (st_gdata->list[new_proto->type] != NULL) { - pr_err("protocol %d already registered", new_proto->type); + if (st_gdata->list[new_proto->chnl_id] != NULL) { + pr_err("chnl_id %d already registered", new_proto->chnl_id); return -EALREADY; } @@ -586,11 +482,11 @@ long st_register(struct st_proto_s *new_proto) spin_lock_irqsave(&st_gdata->lock, flags); if (test_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state)) { - pr_info(" ST_REG_IN_PROGRESS:%d ", new_proto->type); + pr_info(" ST_REG_IN_PROGRESS:%d ", new_proto->chnl_id); /* fw download in progress */ - st_kim_chip_toggle(new_proto->type, KIM_GPIO_ACTIVE); + st_kim_chip_toggle(new_proto->chnl_id, KIM_GPIO_ACTIVE); - st_gdata->list[new_proto->type] = new_proto; + add_channel_to_table(st_gdata, new_proto); st_gdata->protos_registered++; new_proto->write = st_write; @@ -598,7 +494,7 @@ long st_register(struct st_proto_s *new_proto) spin_unlock_irqrestore(&st_gdata->lock, flags); return -EINPROGRESS; } else if (st_gdata->protos_registered == ST_EMPTY) { - pr_info(" protocol list empty :%d ", new_proto->type); + pr_info(" chnl_id list empty :%d ", new_proto->chnl_id); set_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); st_recv = st_kim_recv; @@ -622,9 +518,9 @@ long st_register(struct st_proto_s *new_proto) return -1; } - /* the protocol might require other gpios to be toggled + /* the chnl_id might require other gpios to be toggled */ - st_kim_chip_toggle(new_proto->type, KIM_GPIO_ACTIVE); + st_kim_chip_toggle(new_proto->chnl_id, KIM_GPIO_ACTIVE); clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); st_recv = st_int_recv; @@ -642,14 +538,14 @@ long st_register(struct st_proto_s *new_proto) /* check for already registered once more, * since the above check is old */ - if (st_gdata->list[new_proto->type] != NULL) { + if (st_gdata->list[new_proto->chnl_id] != NULL) { pr_err(" proto %d already registered ", - new_proto->type); + new_proto->chnl_id); return -EALREADY; } spin_lock_irqsave(&st_gdata->lock, flags); - st_gdata->list[new_proto->type] = new_proto; + add_channel_to_table(st_gdata, new_proto); st_gdata->protos_registered++; new_proto->write = st_write; spin_unlock_irqrestore(&st_gdata->lock, flags); @@ -657,22 +553,7 @@ long st_register(struct st_proto_s *new_proto) } /* if fw is already downloaded & new stack registers protocol */ else { - switch (new_proto->type) { - case ST_BT: - /* do nothing */ - break; - case ST_FM: - case ST_GPS: - st_kim_chip_toggle(new_proto->type, KIM_GPIO_ACTIVE); - break; - case ST_MAX: - default: - pr_err("%d protocol not supported", - new_proto->type); - spin_unlock_irqrestore(&st_gdata->lock, flags); - return -EPROTONOSUPPORT; - } - st_gdata->list[new_proto->type] = new_proto; + add_channel_to_table(st_gdata, new_proto); st_gdata->protos_registered++; new_proto->write = st_write; @@ -680,48 +561,48 @@ long st_register(struct st_proto_s *new_proto) spin_unlock_irqrestore(&st_gdata->lock, flags); return err; } - pr_debug("done %s(%d) ", __func__, new_proto->type); + pr_debug("done %s(%d) ", __func__, new_proto->chnl_id); } EXPORT_SYMBOL_GPL(st_register); /* to unregister a protocol - * to be called from protocol stack driver */ -long st_unregister(enum proto_type type) +long st_unregister(struct st_proto_s *proto) { long err = 0; unsigned long flags = 0; struct st_data_s *st_gdata; - pr_debug("%s: %d ", __func__, type); + pr_debug("%s: %d ", __func__, proto->chnl_id); st_kim_ref(&st_gdata, 0); - if (type < ST_BT || type >= ST_MAX) { - pr_err(" protocol %d not supported", type); + if (proto->chnl_id >= ST_MAX_CHANNELS) { + pr_err(" chnl_id %d not supported", proto->chnl_id); return -EPROTONOSUPPORT; } spin_lock_irqsave(&st_gdata->lock, flags); - if (st_gdata->list[type] == NULL) { - pr_err(" protocol %d not registered", type); + if (st_gdata->list[proto->chnl_id] == NULL) { + pr_err(" chnl_id %d not registered", proto->chnl_id); spin_unlock_irqrestore(&st_gdata->lock, flags); return -EPROTONOSUPPORT; } st_gdata->protos_registered--; - st_gdata->list[type] = NULL; + remove_channel_from_table(st_gdata, proto); /* kim ignores BT in the below function * and handles the rest, BT is toggled * only in kim_start and kim_stop */ - st_kim_chip_toggle(type, KIM_GPIO_INACTIVE); + st_kim_chip_toggle(proto->chnl_id, KIM_GPIO_INACTIVE); spin_unlock_irqrestore(&st_gdata->lock, flags); if ((st_gdata->protos_registered == ST_EMPTY) && (!test_bit(ST_REG_PENDING, &st_gdata->st_state))) { - pr_info(" all protocols unregistered "); + pr_info(" all chnl_ids unregistered "); /* stop traffic on tty */ if (st_gdata->tty) { @@ -729,7 +610,7 @@ long st_unregister(enum proto_type type) stop_tty(st_gdata->tty); } - /* all protocols now unregistered */ + /* all chnl_ids now unregistered */ st_kim_stop(st_gdata->kim_data); /* disable ST LL */ st_ll_disable(st_gdata); @@ -745,7 +626,7 @@ long st_write(struct sk_buff *skb) { struct st_data_s *st_gdata; #ifdef DEBUG - enum proto_type protoid = ST_MAX; + unsigned char chnl_id = ST_MAX_CHANNELS; #endif long len; @@ -756,22 +637,10 @@ long st_write(struct sk_buff *skb) return -1; } #ifdef DEBUG /* open-up skb to read the 1st byte */ - switch (skb->data[0]) { - case HCI_COMMAND_PKT: - case HCI_ACLDATA_PKT: - case HCI_SCODATA_PKT: - protoid = ST_BT; - break; - case ST_FM_CH8_PKT: - protoid = ST_FM; - break; - case 0x09: - protoid = ST_GPS; - break; - } - if (unlikely(st_gdata->list[protoid] == NULL)) { - pr_err(" protocol %d not registered, and writing? ", - protoid); + chnl_id = skb->data[0]; + if (unlikely(st_gdata->list[chnl_id] == NULL)) { + pr_err(" chnl_id %d not registered, and writing? ", + chnl_id); return -1; } #endif @@ -824,7 +693,7 @@ static int st_tty_open(struct tty_struct *tty) static void st_tty_close(struct tty_struct *tty) { - unsigned char i = ST_MAX; + unsigned char i = ST_MAX_CHANNELS; unsigned long flags = 0; struct st_data_s *st_gdata = tty->disc_data; @@ -835,7 +704,7 @@ static void st_tty_close(struct tty_struct *tty) * un-installed for some reason - what should be done ? */ spin_lock_irqsave(&st_gdata->lock, flags); - for (i = ST_BT; i < ST_MAX; i++) { + for (i = ST_BT; i < ST_MAX_CHANNELS; i++) { if (st_gdata->list[i] != NULL) pr_err("%d not un-registered", i); st_gdata->list[i] = NULL; @@ -869,7 +738,7 @@ static void st_tty_close(struct tty_struct *tty) static void st_tty_receive(struct tty_struct *tty, const unsigned char *data, char *tty_flags, int count) { - +#define VERBOSE #ifdef VERBOSE print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE, 16, 1, data, count, 0); diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index 73b6c8b0e869..707c85826417 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -32,11 +32,7 @@ #include #include -/* understand BT events for fw response */ -#include -#include -#include - +#include #include @@ -134,7 +130,7 @@ static inline int kim_check_data_len(struct kim_data_s *kim_gdata, int len) /* Packet header has non-zero payload length and * we have enough space in created skb. Lets read * payload data */ - kim_gdata->rx_state = ST_BT_W4_DATA; + kim_gdata->rx_state = ST_W4_DATA; kim_gdata->rx_count = len; return len; } @@ -158,8 +154,8 @@ void kim_int_recv(struct kim_data_s *kim_gdata, const unsigned char *data, long count) { const unsigned char *ptr; - struct hci_event_hdr *eh; int len = 0, type = 0; + unsigned char *plen; pr_debug("%s", __func__); /* Decode received bytes here */ @@ -183,29 +179,27 @@ void kim_int_recv(struct kim_data_s *kim_gdata, /* Check ST RX state machine , where are we? */ switch (kim_gdata->rx_state) { /* Waiting for complete packet ? */ - case ST_BT_W4_DATA: + case ST_W4_DATA: pr_debug("Complete pkt received"); validate_firmware_response(kim_gdata); kim_gdata->rx_state = ST_W4_PACKET_TYPE; kim_gdata->rx_skb = NULL; continue; /* Waiting for Bluetooth event header ? */ - case ST_BT_W4_EVENT_HDR: - eh = (struct hci_event_hdr *)kim_gdata-> - rx_skb->data; - pr_debug("Event header: evt 0x%2.2x" - "plen %d", eh->evt, eh->plen); - kim_check_data_len(kim_gdata, eh->plen); + case ST_W4_HEADER: + plen = + (unsigned char *)&kim_gdata->rx_skb->data[1]; + pr_debug("event hdr: plen 0x%02x\n", *plen); + kim_check_data_len(kim_gdata, *plen); continue; } /* end of switch */ } /* end of if rx_state */ switch (*ptr) { /* Bluetooth event packet? */ - case HCI_EVENT_PKT: - pr_info("Event packet"); - kim_gdata->rx_state = ST_BT_W4_EVENT_HDR; - kim_gdata->rx_count = HCI_EVENT_HDR_SIZE; - type = HCI_EVENT_PKT; + case 0x04: + kim_gdata->rx_state = ST_W4_HEADER; + kim_gdata->rx_count = 2; + type = *ptr; break; default: pr_info("unknown packet"); @@ -216,16 +210,18 @@ void kim_int_recv(struct kim_data_s *kim_gdata, ptr++; count--; kim_gdata->rx_skb = - bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); + alloc_skb(1024+8, GFP_ATOMIC); if (!kim_gdata->rx_skb) { pr_err("can't allocate mem for new packet"); kim_gdata->rx_state = ST_W4_PACKET_TYPE; kim_gdata->rx_count = 0; return; } - bt_cb(kim_gdata->rx_skb)->pkt_type = type; + skb_reserve(kim_gdata->rx_skb, 8); + kim_gdata->rx_skb->cb[0] = 4; + kim_gdata->rx_skb->cb[1] = 0; + } - pr_info("done %s", __func__); return; } @@ -398,7 +394,7 @@ void st_kim_chip_toggle(enum proto_type type, enum kim_gpio_state state) gpio_set_value(kim_gdata->gpios[ST_GPS], GPIO_LOW); break; - case ST_MAX: + case ST_MAX_CHANNELS: default: break; } @@ -416,7 +412,6 @@ void st_kim_recv(void *disc_data, const unsigned char *data, long count) struct st_data_s *st_gdata = (struct st_data_s *)disc_data; struct kim_data_s *kim_gdata = st_gdata->kim_data; - pr_info(" %s ", __func__); /* copy to local buffer */ if (unlikely(data[4] == 0x01 && data[5] == 0x10 && data[0] == 0x04)) { /* must be the read_ver_cmd */ @@ -578,7 +573,7 @@ static int kim_toggle_radio(void *data, bool blocked) else st_kim_chip_toggle(type, KIM_GPIO_ACTIVE); break; - case ST_MAX: + case ST_MAX_CHANNELS: pr_err(" wrong proto type "); break; } @@ -664,12 +659,13 @@ static int kim_probe(struct platform_device *pdev) /* refer to itself */ kim_gdata->core_data->kim_data = kim_gdata; - for (proto = 0; proto < ST_MAX; proto++) { + for (proto = 0; proto < ST_MAX_CHANNELS; proto++) { kim_gdata->gpios[proto] = gpios[proto]; pr_info(" %ld gpio to be requested", gpios[proto]); } - for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) { + for (proto = 0; (proto < ST_MAX_CHANNELS) + && (gpios[proto] != -1); proto++) { /* Claim the Bluetooth/FM/GPIO * nShutdown gpio from the system */ @@ -704,7 +700,8 @@ static int kim_probe(struct platform_device *pdev) init_completion(&kim_gdata->kim_rcvd); init_completion(&kim_gdata->ldisc_installed); - for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) { + for (proto = 0; (proto < ST_MAX_CHANNELS) + && (gpios[proto] != -1); proto++) { /* TODO: should all types be rfkill_type_bt ? */ kim_gdata->rf_protos[proto] = proto; kim_gdata->rfkill[proto] = rfkill_alloc(protocol_names[proto], @@ -752,7 +749,8 @@ static int kim_remove(struct platform_device *pdev) kim_gdata = dev_get_drvdata(&pdev->dev); - for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) { + for (proto = 0; (proto < ST_MAX_CHANNELS) + && (gpios[proto] != -1); proto++) { /* Claim the Bluetooth/FM/GPIO * nShutdown gpio from the system */ diff --git a/include/linux/ti_wilink_st.h b/include/linux/ti_wilink_st.h index 4c7be2263011..1674ca7ab86d 100644 --- a/include/linux/ti_wilink_st.h +++ b/include/linux/ti_wilink_st.h @@ -42,7 +42,7 @@ enum proto_type { ST_BT, ST_FM, ST_GPS, - ST_MAX, + ST_MAX_CHANNELS = 16, }; /** @@ -62,6 +62,17 @@ enum proto_type { * @priv_data: privdate data holder for the protocol drivers, sent * from the protocol drivers during registration, and sent back on * reg_complete_cb and recv. + * @chnl_id: channel id the protocol driver is interested in, the channel + * id is nothing but the 1st byte of the packet in UART frame. + * @max_frame_size: size of the largest frame the protocol can receive. + * @hdr_len: length of the header structure of the protocol. + * @offset_len_in_hdr: this provides the offset of the length field in the + * header structure of the protocol header, to assist ST to know + * how much to receive, if the data is split across UART frames. + * @len_size: whether the length field inside the header is 2 bytes + * or 1 byte. + * @reserve: the number of bytes ST needs to reserve in the skb being + * prepared for the protocol driver. */ struct st_proto_s { enum proto_type type; @@ -70,10 +81,17 @@ struct st_proto_s { void (*reg_complete_cb) (void *, char data); long (*write) (struct sk_buff *skb); void *priv_data; + + unsigned char chnl_id; + unsigned short max_frame_size; + unsigned char hdr_len; + unsigned char offset_len_in_hdr; + unsigned char len_size; + unsigned char reserve; }; extern long st_register(struct st_proto_s *); -extern long st_unregister(enum proto_type); +extern long st_unregister(struct st_proto_s *); /* @@ -114,6 +132,7 @@ extern long st_unregister(enum proto_type); * @rx_skb: the skb where all data for a protocol gets accumulated, * since tty might not call receive when a complete event packet * is received, the states, count and the skb needs to be maintained. + * @rx_chnl: the channel ID for which the data is getting accumalated for. * @txq: the list of skbs which needs to be sent onto the TTY. * @tx_waitq: if the chip is not in AWAKE state, the skbs needs to be queued * up in here, PM(WAKEUP_IND) data needs to be sent and then the skbs @@ -135,10 +154,11 @@ struct st_data_s { #define ST_TX_SENDING 1 #define ST_TX_WAKEUP 2 unsigned long tx_state; - struct st_proto_s *list[ST_MAX]; + struct st_proto_s *list[ST_MAX_CHANNELS]; unsigned long rx_state; unsigned long rx_count; struct sk_buff *rx_skb; + unsigned char rx_chnl; struct sk_buff_head txq, tx_waitq; spinlock_t lock; unsigned char protos_registered; @@ -243,12 +263,12 @@ struct kim_data_s { struct completion kim_rcvd, ldisc_installed; char resp_buffer[30]; const struct firmware *fw_entry; - long gpios[ST_MAX]; + long gpios[ST_MAX_CHANNELS]; unsigned long rx_state; unsigned long rx_count; struct sk_buff *rx_skb; - struct rfkill *rfkill[ST_MAX]; - enum proto_type rf_protos[ST_MAX]; + struct rfkill *rfkill[ST_MAX_CHANNELS]; + enum proto_type rf_protos[ST_MAX_CHANNELS]; struct st_data_s *core_data; struct chip_version version; }; @@ -338,12 +358,8 @@ struct hci_command { /* ST LL receiver states */ #define ST_W4_PACKET_TYPE 0 -#define ST_BT_W4_EVENT_HDR 1 -#define ST_BT_W4_ACL_HDR 2 -#define ST_BT_W4_SCO_HDR 3 -#define ST_BT_W4_DATA 4 -#define ST_FM_W4_EVENT_HDR 5 -#define ST_GPS_W4_EVENT_HDR 6 +#define ST_W4_HEADER 1 +#define ST_W4_DATA 2 /* ST LL state machines */ #define ST_LL_ASLEEP 0 -- cgit v1.2.3 From ec60d0ad20ff8796dc41b30a9dce485478ccd263 Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Fri, 4 Feb 2011 02:23:10 -0600 Subject: drivers:misc: ti-st: move from rfkill to sysfs The communication between ST KIM and UIM was interfaced over the /dev/rfkill device node. Move the interface to a simpler less abusive sysfs entry mechanism and document it in Documentation/ABI/testing/ under sysfs-platform-kim. Shared transport driver would now read the UART details originally received by bootloader or firmware as platform data. The data read will be shared over sysfs entries for the user-space UIM or other n/w manager/plugins to be read, and assist the driver by opening up the UART, setting the baud-rate and installing the line discipline. Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-platform-kim | 48 ++++++ drivers/misc/ti-st/st_kim.c | 244 +++++++++++++-------------- include/linux/ti_wilink_st.h | 19 ++- 3 files changed, 186 insertions(+), 125 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-platform-kim (limited to 'drivers') diff --git a/Documentation/ABI/testing/sysfs-platform-kim b/Documentation/ABI/testing/sysfs-platform-kim new file mode 100644 index 000000000000..c1653271872a --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-kim @@ -0,0 +1,48 @@ +What: /sys/devices/platform/kim/dev_name +Date: January 2010 +KernelVersion: 2.6.38 +Contact: "Pavan Savoy" +Description: + Name of the UART device at which the WL128x chip + is connected. example: "/dev/ttyS0". + The device name flows down to architecture specific board + initialization file from the SFI/ATAGS bootloader + firmware. The name exposed is read from the user-space + dameon and opens the device when install is requested. + +What: /sys/devices/platform/kim/baud_rate +Date: January 2010 +KernelVersion: 2.6.38 +Contact: "Pavan Savoy" +Description: + The maximum reliable baud-rate the host can support. + Different platforms tend to have different high-speed + UART configurations, so the baud-rate needs to be set + locally and also sent across to the WL128x via a HCI-VS + command. The entry is read and made use by the user-space + daemon when the ldisc install is requested. + +What: /sys/devices/platform/kim/flow_cntrl +Date: January 2010 +KernelVersion: 2.6.38 +Contact: "Pavan Savoy" +Description: + The WL128x makes use of flow control mechanism, and this + entry most often should be 1, the host's UART is required + to have the capability of flow-control, or else this + entry can be made use of for exceptions. + +What: /sys/devices/platform/kim/install +Date: January 2010 +KernelVersion: 2.6.38 +Contact: "Pavan Savoy" +Description: + When one of the protocols Bluetooth, FM or GPS wants to make + use of the shared UART transport, it registers to the shared + transport driver, which will signal the user-space for opening, + configuring baud and install line discipline via this sysfs + entry. This entry would be polled upon by the user-space + daemon managing the UART, and is notified about the change + by the sysfs_notify. The value would be '1' when UART needs + to be opened/ldisc installed, and would be '0' when UART + is no more required and needs to be closed. diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index 707c85826417..a7fda8141758 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -30,46 +30,12 @@ #include #include #include -#include +#include #include #include -static int kim_probe(struct platform_device *pdev); -static int kim_remove(struct platform_device *pdev); - -/* KIM platform device driver structure */ -static struct platform_driver kim_platform_driver = { - .probe = kim_probe, - .remove = kim_remove, - /* TODO: ST driver power management during suspend/resume ? - */ -#if 0 - .suspend = kim_suspend, - .resume = kim_resume, -#endif - .driver = { - .name = "kim", - .owner = THIS_MODULE, - }, -}; - -static int kim_toggle_radio(void*, bool); -static const struct rfkill_ops kim_rfkill_ops = { - .set_block = kim_toggle_radio, -}; - -/* strings to be used for rfkill entries and by - * ST Core to be used for sysfs debug entry - */ -#define PROTO_ENTRY(type, name) name -const unsigned char *protocol_names[] = { - PROTO_ENTRY(ST_BT, "Bluetooth"), - PROTO_ENTRY(ST_FM, "FM"), - PROTO_ENTRY(ST_GPS, "GPS"), -}; - #define MAX_ST_DEVICES 3 /* Imagine 1 on each UART for now */ static struct platform_device *st_kim_devices[MAX_ST_DEVICES]; @@ -371,8 +337,7 @@ void st_kim_chip_toggle(enum proto_type type, enum kim_gpio_state state) kim_gdata = dev_get_drvdata(&kim_pdev->dev); if (kim_gdata->gpios[type] == -1) { - pr_info(" gpio not requested for protocol %s", - protocol_names[type]); + pr_info("gpio not requested for protocol %d", type); return; } switch (type) { @@ -450,11 +415,6 @@ long st_kim_start(void *kim_data) pr_info(" %s", __func__); do { - /* TODO: this is only because rfkill sub-system - * doesn't send events to user-space if the state - * isn't changed - */ - rfkill_set_hw_state(kim_gdata->rfkill[ST_BT], 1); /* Configure BT nShutdown to HIGH state */ gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_LOW); mdelay(5); /* FIXME: a proper toggle */ @@ -462,22 +422,20 @@ long st_kim_start(void *kim_data) mdelay(100); /* re-initialize the completion */ INIT_COMPLETION(kim_gdata->ldisc_installed); -#if 0 /* older way of signalling user-space UIM */ - /* send signal to UIM */ - err = kill_pid(find_get_pid(kim_gdata->uim_pid), SIGUSR2, 0); - if (err != 0) { - pr_info(" sending SIGUSR2 to uim failed %ld", err); - err = -1; - continue; - } -#endif - /* unblock and send event to UIM via /dev/rfkill */ - rfkill_set_hw_state(kim_gdata->rfkill[ST_BT], 0); + /* send notification to UIM */ + kim_gdata->ldisc_install = 1; + pr_info("ldisc_install = 1"); + sysfs_notify(&kim_gdata->kim_pdev->dev.kobj, + NULL, "install"); /* wait for ldisc to be installed */ err = wait_for_completion_timeout(&kim_gdata->ldisc_installed, msecs_to_jiffies(LDISC_TIME)); if (!err) { /* timeout */ pr_err("line disc installation timed out "); + kim_gdata->ldisc_install = 0; + pr_info("ldisc_install = 0"); + sysfs_notify(&kim_gdata->kim_pdev->dev.kobj, + NULL, "install"); err = -1; continue; } else { @@ -486,6 +444,10 @@ long st_kim_start(void *kim_data) err = download_firmware(kim_gdata); if (err != 0) { pr_err("download firmware failed"); + kim_gdata->ldisc_install = 0; + pr_info("ldisc_install = 0"); + sysfs_notify(&kim_gdata->kim_pdev->dev.kobj, + NULL, "install"); continue; } else { /* on success don't retry */ break; @@ -505,16 +467,15 @@ long st_kim_stop(void *kim_data) struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data; INIT_COMPLETION(kim_gdata->ldisc_installed); -#if 0 /* older way of signalling user-space UIM */ - /* send signal to UIM */ - err = kill_pid(find_get_pid(kim_gdata->uim_pid), SIGUSR2, 1); - if (err != 0) { - pr_err("sending SIGUSR2 to uim failed %ld", err); - return -1; - } -#endif - /* set BT rfkill to be blocked */ - err = rfkill_set_hw_state(kim_gdata->rfkill[ST_BT], 1); + + /* Flush any pending characters in the driver and discipline. */ + tty_ldisc_flush(kim_gdata->core_data->tty); + tty_driver_flush_buffer(kim_gdata->core_data->tty); + + /* send uninstall notification to UIM */ + pr_info("ldisc_install = 0"); + kim_gdata->ldisc_install = 0; + sysfs_notify(&kim_gdata->kim_pdev->dev.kobj, NULL, "install"); /* wait for ldisc to be un-installed */ err = wait_for_completion_timeout(&kim_gdata->ldisc_installed, @@ -553,33 +514,59 @@ static int show_list(struct seq_file *s, void *unused) return 0; } -/* function called from rfkill subsystem, when someone from - * user space would write 0/1 on the sysfs entry - * /sys/class/rfkill/rfkill0,1,3/state - */ -static int kim_toggle_radio(void *data, bool blocked) +static ssize_t show_install(struct device *dev, + struct device_attribute *attr, char *buf) { - enum proto_type type = *((enum proto_type *)data); - pr_debug(" %s: %d ", __func__, type); + struct kim_data_s *kim_data = dev_get_drvdata(dev); + return sprintf(buf, "%d\n", kim_data->ldisc_install); +} - switch (type) { - case ST_BT: - /* do nothing */ - break; - case ST_FM: - case ST_GPS: - if (blocked) - st_kim_chip_toggle(type, KIM_GPIO_INACTIVE); - else - st_kim_chip_toggle(type, KIM_GPIO_ACTIVE); - break; - case ST_MAX_CHANNELS: - pr_err(" wrong proto type "); - break; - } - return 0; +static ssize_t show_dev_name(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct kim_data_s *kim_data = dev_get_drvdata(dev); + return sprintf(buf, "%s\n", kim_data->dev_name); +} + +static ssize_t show_baud_rate(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct kim_data_s *kim_data = dev_get_drvdata(dev); + return sprintf(buf, "%ld\n", kim_data->baud_rate); +} + +static ssize_t show_flow_cntrl(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct kim_data_s *kim_data = dev_get_drvdata(dev); + return sprintf(buf, "%d\n", kim_data->flow_cntrl); } +/* structures specific for sysfs entries */ +static struct kobj_attribute ldisc_install = +__ATTR(install, 0444, (void *)show_install, NULL); + +static struct kobj_attribute uart_dev_name = +__ATTR(dev_name, 0444, (void *)show_dev_name, NULL); + +static struct kobj_attribute uart_baud_rate = +__ATTR(baud_rate, 0444, (void *)show_baud_rate, NULL); + +static struct kobj_attribute uart_flow_cntrl = +__ATTR(flow_cntrl, 0444, (void *)show_flow_cntrl, NULL); + +static struct attribute *uim_attrs[] = { + &ldisc_install.attr, + &uart_dev_name.attr, + &uart_baud_rate.attr, + &uart_flow_cntrl.attr, + NULL, +}; + +static struct attribute_group uim_attr_grp = { + .attrs = uim_attrs, +}; + /** * st_kim_ref - reference the core's data * This references the per-ST platform device in the arch/xx/ @@ -633,8 +620,9 @@ static int kim_probe(struct platform_device *pdev) { long status; long proto; - long *gpios = pdev->dev.platform_data; struct kim_data_s *kim_gdata; + struct ti_st_plat_data *pdata = pdev->dev.platform_data; + long *gpios = pdata->gpios; if ((pdev->id != -1) && (pdev->id < MAX_ST_DEVICES)) { /* multiple devices could exist */ @@ -700,30 +688,18 @@ static int kim_probe(struct platform_device *pdev) init_completion(&kim_gdata->kim_rcvd); init_completion(&kim_gdata->ldisc_installed); - for (proto = 0; (proto < ST_MAX_CHANNELS) - && (gpios[proto] != -1); proto++) { - /* TODO: should all types be rfkill_type_bt ? */ - kim_gdata->rf_protos[proto] = proto; - kim_gdata->rfkill[proto] = rfkill_alloc(protocol_names[proto], - &pdev->dev, RFKILL_TYPE_BLUETOOTH, - &kim_rfkill_ops, &kim_gdata->rf_protos[proto]); - if (kim_gdata->rfkill[proto] == NULL) { - pr_err("cannot create rfkill entry for gpio %ld", - gpios[proto]); - continue; - } - /* block upon creation */ - rfkill_init_sw_state(kim_gdata->rfkill[proto], 1); - status = rfkill_register(kim_gdata->rfkill[proto]); - if (unlikely(status)) { - pr_err("rfkill registration failed for gpio %ld", - gpios[proto]); - rfkill_unregister(kim_gdata->rfkill[proto]); - continue; - } - pr_info("rfkill entry created for %ld", gpios[proto]); + status = sysfs_create_group(&pdev->dev.kobj, &uim_attr_grp); + if (status) { + pr_err("failed to create sysfs entries"); + return status; } + /* copying platform data */ + strncpy(kim_gdata->dev_name, pdata->dev_name, UART_DEV_NAME_LEN); + kim_gdata->flow_cntrl = pdata->flow_cntrl; + kim_gdata->baud_rate = pdata->baud_rate; + pr_info("sysfs entries created\n"); + kim_debugfs_dir = debugfs_create_dir("ti-st", NULL); if (IS_ERR(kim_debugfs_dir)) { pr_err(" debugfs entries creation failed "); @@ -741,9 +717,9 @@ static int kim_probe(struct platform_device *pdev) static int kim_remove(struct platform_device *pdev) { - /* free the GPIOs requested - */ - long *gpios = pdev->dev.platform_data; + /* free the GPIOs requested */ + struct ti_st_plat_data *pdata = pdev->dev.platform_data; + long *gpios = pdata->gpios; long proto; struct kim_data_s *kim_gdata; @@ -755,12 +731,11 @@ static int kim_remove(struct platform_device *pdev) * nShutdown gpio from the system */ gpio_free(gpios[proto]); - rfkill_unregister(kim_gdata->rfkill[proto]); - rfkill_destroy(kim_gdata->rfkill[proto]); - kim_gdata->rfkill[proto] = NULL; } pr_info("kim: GPIO Freed"); debugfs_remove_recursive(kim_debugfs_dir); + + sysfs_remove_group(&pdev->dev.kobj, &uim_attr_grp); kim_gdata->kim_pdev = NULL; st_core_exit(kim_gdata->core_data); @@ -769,23 +744,46 @@ static int kim_remove(struct platform_device *pdev) return 0; } +int kim_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct ti_st_plat_data *pdata = pdev->dev.platform_data; + + if (pdata->suspend) + return pdata->suspend(pdev, state); + + return -EOPNOTSUPP; +} + +int kim_resume(struct platform_device *pdev) +{ + struct ti_st_plat_data *pdata = pdev->dev.platform_data; + + if (pdata->resume) + return pdata->resume(pdev); + + return -EOPNOTSUPP; +} + /**********************************************************************/ /* entry point for ST KIM module, called in from ST Core */ +static struct platform_driver kim_platform_driver = { + .probe = kim_probe, + .remove = kim_remove, + .suspend = kim_suspend, + .resume = kim_resume, + .driver = { + .name = "kim", + .owner = THIS_MODULE, + }, +}; static int __init st_kim_init(void) { - long ret = 0; - ret = platform_driver_register(&kim_platform_driver); - if (ret != 0) { - pr_err("platform drv registration failed"); - return -1; - } - return 0; + return platform_driver_register(&kim_platform_driver); } static void __exit st_kim_deinit(void) { - /* the following returns void */ platform_driver_unregister(&kim_platform_driver); } diff --git a/include/linux/ti_wilink_st.h b/include/linux/ti_wilink_st.h index 1674ca7ab86d..010cda7287a0 100644 --- a/include/linux/ti_wilink_st.h +++ b/include/linux/ti_wilink_st.h @@ -206,8 +206,8 @@ void gps_chrdrv_stub_init(void); /* time in msec to wait for * line discipline to be installed */ -#define LDISC_TIME 500 -#define CMD_RESP_TIME 500 +#define LDISC_TIME 1000 +#define CMD_RESP_TIME 800 #define MAKEWORD(a, b) ((unsigned short)(((unsigned char)(a)) \ | ((unsigned short)((unsigned char)(b))) << 8)) @@ -230,6 +230,7 @@ struct chip_version { unsigned short maj_ver; }; +#define UART_DEV_NAME_LEN 32 /** * struct kim_data_s - the KIM internal data, embedded as the * platform's drv data. One for each ST device in the system. @@ -271,6 +272,10 @@ struct kim_data_s { enum proto_type rf_protos[ST_MAX_CHANNELS]; struct st_data_s *core_data; struct chip_version version; + unsigned char ldisc_install; + unsigned char dev_name[UART_DEV_NAME_LEN]; + unsigned char flow_cntrl; + unsigned long baud_rate; }; /** @@ -413,4 +418,14 @@ struct gps_event_hdr { u16 plen; } __attribute__ ((packed)); +/* platform data */ +struct ti_st_plat_data { + long gpios[ST_MAX_CHANNELS]; /* BT, FM and GPS */ + unsigned char dev_name[UART_DEV_NAME_LEN]; /* uart name */ + unsigned char flow_cntrl; /* flow control flag */ + unsigned long baud_rate; + int (*suspend)(struct platform_device *, pm_message_t); + int (*resume)(struct platform_device *); +}; + #endif /* TI_WILINK_ST_H */ -- cgit v1.2.3 From 704426649dd4324b34cefea322f4333e5280f852 Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Fri, 4 Feb 2011 02:23:11 -0600 Subject: drivers:misc: ti-st: fix error codes set-right the error codes that the shared transport driver returns. Instead of magic numbers like -1, return relevant codes such as ETIMEDOUT or EIO, EAGAIN when wait times out or uart write bytes don't match expected value or when registration fails and needs to be attempted again. Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_core.c | 31 ++++++++++++++----------------- drivers/misc/ti-st/st_kim.c | 18 +++++++++--------- drivers/misc/ti-st/st_ll.c | 2 +- 3 files changed, 24 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 84d73c5cb74d..79d2dc3fca1f 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -65,7 +65,7 @@ int st_int_write(struct st_data_s *st_gdata, struct tty_struct *tty; if (unlikely(st_gdata == NULL || st_gdata->tty == NULL)) { pr_err("tty unavailable to perform write"); - return -1; + return -EINVAL; } tty = st_gdata->tty; #ifdef VERBOSE @@ -124,9 +124,15 @@ void st_reg_complete(struct st_data_s *st_gdata, char err) pr_info(" %s ", __func__); for (i = 0; i < ST_MAX_CHANNELS; i++) { if (likely(st_gdata != NULL && st_gdata->list[i] != NULL && - st_gdata->list[i]->reg_complete_cb != NULL)) + st_gdata->list[i]->reg_complete_cb != NULL)) { st_gdata->list[i]->reg_complete_cb (st_gdata->list[i]->priv_data, err); + pr_info("protocol %d's cb sent %d\n", i, err); + if (err) { /* cleanup registered protocol */ + st_gdata->protos_registered--; + st_gdata->list[i] = NULL; + } + } } } @@ -457,15 +463,7 @@ long st_register(struct st_proto_s *new_proto) if (st_gdata == NULL || new_proto == NULL || new_proto->recv == NULL || new_proto->reg_complete_cb == NULL) { pr_err("gdata/new_proto/recv or reg_complete_cb not ready"); - if (st_gdata == NULL) - pr_err("error 1\n"); - if (new_proto == NULL) - pr_err("error 2\n"); - if (new_proto->recv == NULL) - pr_err("error 3\n"); - if (new_proto->reg_complete_cb == NULL) - pr_err("erro 4\n"); - return -1; + return -EINVAL; } if (new_proto->chnl_id >= ST_MAX_CHANNELS) { @@ -512,10 +510,9 @@ long st_register(struct st_proto_s *new_proto) if ((st_gdata->protos_registered != ST_EMPTY) && (test_bit(ST_REG_PENDING, &st_gdata->st_state))) { pr_err(" KIM failure complete callback "); - st_reg_complete(st_gdata, -1); + st_reg_complete(st_gdata, err); } - - return -1; + return -EINVAL; } /* the chnl_id might require other gpios to be toggled @@ -634,14 +631,14 @@ long st_write(struct sk_buff *skb) if (unlikely(skb == NULL || st_gdata == NULL || st_gdata->tty == NULL)) { pr_err("data/tty unavailable to perform write"); - return -1; + return -EINVAL; } #ifdef DEBUG /* open-up skb to read the 1st byte */ chnl_id = skb->data[0]; if (unlikely(st_gdata->list[chnl_id] == NULL)) { pr_err(" chnl_id %d not registered, and writing? ", chnl_id); - return -1; + return -EINVAL; } #endif pr_debug("%d to be written", skb->len); @@ -829,7 +826,7 @@ int st_core_init(struct st_data_s **core_data) err = tty_unregister_ldisc(N_TI_WL); if (err) pr_err("unable to un-register ldisc"); - return -1; + return err; } *core_data = st_gdata; return 0; diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index a7fda8141758..ccc46a7b0abb 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -201,13 +201,13 @@ static long read_local_version(struct kim_data_s *kim_gdata, char *bts_scr_name) INIT_COMPLETION(kim_gdata->kim_rcvd); if (4 != st_int_write(kim_gdata->core_data, read_ver_cmd, 4)) { pr_err("kim: couldn't write 4 bytes"); - return -1; + return -EIO; } if (!wait_for_completion_timeout (&kim_gdata->kim_rcvd, msecs_to_jiffies(CMD_RESP_TIME))) { pr_err(" waiting for ver info- timed out "); - return -1; + return -ETIMEDOUT; } version = @@ -257,7 +257,7 @@ static long download_firmware(struct kim_data_s *kim_gdata) (kim_gdata->fw_entry->size == 0))) { pr_err(" request_firmware failed(errno %ld) for %s", err, bts_scr_name); - return -1; + return -EINVAL; } ptr = (void *)kim_gdata->fw_entry->data; len = kim_gdata->fw_entry->size; @@ -292,7 +292,7 @@ static long download_firmware(struct kim_data_s *kim_gdata) ((struct bts_action *)ptr)->size); if (unlikely(err < 0)) { release_firmware(kim_gdata->fw_entry); - return -1; + return err; } if (!wait_for_completion_timeout (&kim_gdata->kim_rcvd, @@ -301,7 +301,7 @@ static long download_firmware(struct kim_data_s *kim_gdata) (" response timeout during fw download "); /* timed out */ release_firmware(kim_gdata->fw_entry); - return -1; + return -ETIMEDOUT; } break; case ACTION_DELAY: /* sleep */ @@ -436,7 +436,7 @@ long st_kim_start(void *kim_data) pr_info("ldisc_install = 0"); sysfs_notify(&kim_gdata->kim_pdev->dev.kobj, NULL, "install"); - err = -1; + err = -ETIMEDOUT; continue; } else { /* ldisc installed now */ @@ -482,7 +482,7 @@ long st_kim_stop(void *kim_data) msecs_to_jiffies(LDISC_TIME)); if (!err) { /* timeout */ pr_err(" timed out waiting for ldisc to be un-installed"); - return -1; + return -ETIMEDOUT; } /* By default configure BT nShutdown to LOW state */ @@ -642,7 +642,7 @@ static int kim_probe(struct platform_device *pdev) status = st_core_init(&kim_gdata->core_data); if (status != 0) { pr_err(" ST core init failed"); - return -1; + return -EIO; } /* refer to itself */ kim_gdata->core_data->kim_data = kim_gdata; @@ -704,7 +704,7 @@ static int kim_probe(struct platform_device *pdev) if (IS_ERR(kim_debugfs_dir)) { pr_err(" debugfs entries creation failed "); kim_debugfs_dir = NULL; - return -1; + return -EIO; } debugfs_create_file("version", S_IRUGO, kim_debugfs_dir, diff --git a/drivers/misc/ti-st/st_ll.c b/drivers/misc/ti-st/st_ll.c index 2bda8dea15b0..f72de6b8c343 100644 --- a/drivers/misc/ti-st/st_ll.c +++ b/drivers/misc/ti-st/st_ll.c @@ -130,7 +130,7 @@ unsigned long st_ll_sleep_state(struct st_data_s *st_data, break; default: pr_err(" unknown input/state "); - return -1; + return -EINVAL; } return 0; } -- cgit v1.2.3 From 6710fcff66ef0330cdc458557271ee86026745d0 Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Fri, 4 Feb 2011 02:23:12 -0600 Subject: drivers:misc: ti-st: set right debug levels for logs pr_debug-ing few pr_infos from the data paths such as tty receive and write so as to reduce debugs when we have higher logging levels enabled undef VERBOSE in receive to avoid huge logs when log level 8 is set. Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_core.c | 19 +++++++++---------- drivers/misc/ti-st/st_ll.c | 8 ++++---- 2 files changed, 13 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 79d2dc3fca1f..f7bb96f3a424 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -82,7 +82,7 @@ int st_int_write(struct st_data_s *st_gdata, */ void st_send_frame(unsigned char chnl_id, struct st_data_s *st_gdata) { - pr_info(" %s(prot:%d) ", __func__, chnl_id); + pr_debug(" %s(prot:%d) ", __func__, chnl_id); if (unlikely (st_gdata == NULL || st_gdata->rx_skb == NULL @@ -226,7 +226,7 @@ void st_int_recv(void *disc_data, return; } - pr_info("count %ld rx_state %ld" + pr_debug("count %ld rx_state %ld" "rx_count %ld", count, st_gdata->rx_state, st_gdata->rx_count); @@ -260,7 +260,7 @@ void st_int_recv(void *disc_data, plen = &st_gdata->rx_skb->data [proto->offset_len_in_hdr]; - pr_info("plen pointing to %x\n", *plen); + pr_debug("plen pointing to %x\n", *plen); if (proto->len_size == 1)/* 1 byte len field */ payload_len = *(unsigned char *)plen; else if (proto->len_size == 2) @@ -272,7 +272,7 @@ void st_int_recv(void *disc_data, __func__, proto->chnl_id); st_check_data_len(st_gdata, proto->chnl_id, payload_len); - pr_info("off %d, pay len %d\n", + pr_debug("off %d, pay len %d\n", proto->offset_len_in_hdr, payload_len); continue; } /* end of switch rx_state */ @@ -285,7 +285,7 @@ void st_int_recv(void *disc_data, case LL_SLEEP_IND: case LL_SLEEP_ACK: case LL_WAKE_UP_IND: - pr_info("PM packet"); + pr_debug("PM packet"); /* this takes appropriate action based on * sleep state received -- */ @@ -294,7 +294,7 @@ void st_int_recv(void *disc_data, count--; continue; case LL_WAKE_UP_ACK: - pr_info("PM packet"); + pr_debug("PM packet"); /* wake up ack received */ st_wakeup_ack(st_gdata, *ptr); ptr++; @@ -314,7 +314,7 @@ void st_int_recv(void *disc_data, st_gdata->rx_chnl = *ptr; st_gdata->rx_state = ST_W4_HEADER; st_gdata->rx_count = st_gdata->list[type]->hdr_len; - pr_info("rx_count %ld\n", st_gdata->rx_count); + pr_debug("rx_count %ld\n", st_gdata->rx_count); }; ptr++; count--; @@ -360,7 +360,7 @@ void st_int_enqueue(struct st_data_s *st_gdata, struct sk_buff *skb) switch (st_ll_getstate(st_gdata)) { case ST_LL_AWAKE: - pr_info("ST LL is AWAKE, sending normally"); + pr_debug("ST LL is AWAKE, sending normally"); skb_queue_tail(&st_gdata->txq, skb); break; case ST_LL_ASLEEP_TO_AWAKE: @@ -400,7 +400,7 @@ void st_tx_wakeup(struct st_data_s *st_data) pr_debug("%s", __func__); /* check for sending & set flag sending here */ if (test_and_set_bit(ST_TX_SENDING, &st_data->tx_state)) { - pr_info("ST already sending"); + pr_debug("ST already sending"); /* keep sending */ set_bit(ST_TX_WAKEUP, &st_data->tx_state); return; @@ -735,7 +735,6 @@ static void st_tty_close(struct tty_struct *tty) static void st_tty_receive(struct tty_struct *tty, const unsigned char *data, char *tty_flags, int count) { -#define VERBOSE #ifdef VERBOSE print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE, 16, 1, data, count, 0); diff --git a/drivers/misc/ti-st/st_ll.c b/drivers/misc/ti-st/st_ll.c index f72de6b8c343..3f2495138855 100644 --- a/drivers/misc/ti-st/st_ll.c +++ b/drivers/misc/ti-st/st_ll.c @@ -30,7 +30,7 @@ static void send_ll_cmd(struct st_data_s *st_data, unsigned char cmd) { - pr_info("%s: writing %x", __func__, cmd); + pr_debug("%s: writing %x", __func__, cmd); st_int_write(st_data, &cmd, 1); return; } @@ -114,18 +114,18 @@ unsigned long st_ll_sleep_state(struct st_data_s *st_data, { switch (cmd) { case LL_SLEEP_IND: /* sleep ind */ - pr_info("sleep indication recvd"); + pr_debug("sleep indication recvd"); ll_device_want_to_sleep(st_data); break; case LL_SLEEP_ACK: /* sleep ack */ pr_err("sleep ack rcvd: host shouldn't"); break; case LL_WAKE_UP_IND: /* wake ind */ - pr_info("wake indication recvd"); + pr_debug("wake indication recvd"); ll_device_want_to_wakeup(st_data); break; case LL_WAKE_UP_ACK: /* wake ack */ - pr_info("wake ack rcvd"); + pr_debug("wake ack rcvd"); st_data->ll_state = ST_LL_AWAKE; break; default: -- cgit v1.2.3 From ef04d121f030329aae0c2d3ec22beea0c5cbcfd3 Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Fri, 4 Feb 2011 02:23:13 -0600 Subject: drivers:misc: ti-st: firmware download optimization To fasten the process of firmware download, the chip allows disabling of the command complete event generation from host. In these cases, only few very essential commands would have the command complete events and hence the wait associated with them. So now the driver would wait for a command complete event, only when it comes across a wait event during firmware parsing. This would also mean we need to skip not just the change baud rate command but also the wait for it. Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_core.c | 18 ++++++++++ drivers/misc/ti-st/st_kim.c | 80 ++++++++++++++++++++++++++++++++++++++++---- include/linux/ti_wilink_st.h | 6 ++++ 3 files changed, 97 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index f7bb96f3a424..dd2c879faff6 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -52,6 +52,24 @@ static void remove_channel_from_table(struct st_data_s *st_gdata, st_gdata->list[proto->chnl_id] = NULL; } +/* + * called from KIM during firmware download. + * + * This is a wrapper function to tty->ops->write_room. + * It returns number of free space available in + * uart tx buffer. + */ +int st_get_uart_wr_room(struct st_data_s *st_gdata) +{ + struct tty_struct *tty; + if (unlikely(st_gdata == NULL || st_gdata->tty == NULL)) { + pr_err("tty unavailable to perform write"); + return -1; + } + tty = st_gdata->tty; + return tty->ops->write_room(tty); +} + /* can be called in from * -- KIM (during fw download) * -- ST Core (during st_write) diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index ccc46a7b0abb..2c096ccd53b0 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -232,6 +232,26 @@ static long read_local_version(struct kim_data_s *kim_gdata, char *bts_scr_name) return 0; } +void skip_change_remote_baud(unsigned char **ptr, long *len) +{ + unsigned char *nxt_action, *cur_action; + cur_action = *ptr; + + nxt_action = cur_action + sizeof(struct bts_action) + + ((struct bts_action *) cur_action)->size; + + if (((struct bts_action *) nxt_action)->type != ACTION_WAIT_EVENT) { + pr_err("invalid action after change remote baud command"); + } else { + *ptr = *ptr + sizeof(struct bts_action) + + ((struct bts_action *)nxt_action)->size; + *len = *len - (sizeof(struct bts_action) + + ((struct bts_action *)nxt_action)->size); + /* warn user on not commenting these in firmware */ + pr_warn("skipping the wait event of change remote baud"); + } +} + /** * download_firmware - * internal function which parses through the .bts firmware @@ -244,6 +264,9 @@ static long download_firmware(struct kim_data_s *kim_gdata) unsigned char *ptr = NULL; unsigned char *action_ptr = NULL; unsigned char bts_scr_name[30] = { 0 }; /* 30 char long bts scr name? */ + int wr_room_space; + int cmd_size; + unsigned long timeout; err = read_local_version(kim_gdata, bts_scr_name); if (err != 0) { @@ -280,13 +303,43 @@ static long download_firmware(struct kim_data_s *kim_gdata) 0xFF36)) { /* ignore remote change * baud rate HCI VS command */ - pr_err - (" change remote baud" + pr_warn("change remote baud" " rate command in firmware"); + skip_change_remote_baud(&ptr, &len); break; } + /* + * Make sure we have enough free space in uart + * tx buffer to write current firmware command + */ + cmd_size = ((struct bts_action *)ptr)->size; + timeout = jiffies + msecs_to_jiffies(CMD_WR_TIME); + do { + wr_room_space = + st_get_uart_wr_room(kim_gdata->core_data); + if (wr_room_space < 0) { + pr_err("Unable to get free " + "space info from uart tx buffer"); + release_firmware(kim_gdata->fw_entry); + return wr_room_space; + } + mdelay(1); /* wait 1ms before checking room */ + } while ((wr_room_space < cmd_size) && + time_before(jiffies, timeout)); + + /* Timeout happened ? */ + if (time_after_eq(jiffies, timeout)) { + pr_err("Timeout while waiting for free " + "free space in uart tx buffer"); + release_firmware(kim_gdata->fw_entry); + return -ETIMEDOUT; + } - INIT_COMPLETION(kim_gdata->kim_rcvd); + /* + * Free space found in uart buffer, call st_int_write + * to send current firmware command to the uart tx + * buffer. + */ err = st_int_write(kim_gdata->core_data, ((struct bts_action_send *)action_ptr)->data, ((struct bts_action *)ptr)->size); @@ -294,15 +347,28 @@ static long download_firmware(struct kim_data_s *kim_gdata) release_firmware(kim_gdata->fw_entry); return err; } + /* + * Check number of bytes written to the uart tx buffer + * and requested command write size + */ + if (err != cmd_size) { + pr_err("Number of bytes written to uart " + "tx buffer are not matching with " + "requested cmd write size"); + release_firmware(kim_gdata->fw_entry); + return -EIO; + } + break; + case ACTION_WAIT_EVENT: /* wait */ if (!wait_for_completion_timeout - (&kim_gdata->kim_rcvd, - msecs_to_jiffies(CMD_RESP_TIME))) { - pr_err - (" response timeout during fw download "); + (&kim_gdata->kim_rcvd, + msecs_to_jiffies(CMD_RESP_TIME))) { + pr_err("response timeout during fw download "); /* timed out */ release_firmware(kim_gdata->fw_entry); return -ETIMEDOUT; } + INIT_COMPLETION(kim_gdata->kim_rcvd); break; case ACTION_DELAY: /* sleep */ pr_info("sleep command in scr"); diff --git a/include/linux/ti_wilink_st.h b/include/linux/ti_wilink_st.h index 010cda7287a0..7885a779c588 100644 --- a/include/linux/ti_wilink_st.h +++ b/include/linux/ti_wilink_st.h @@ -166,6 +166,11 @@ struct st_data_s { void *kim_data; }; +/* + * wrapper around tty->ops->write_room to check + * availability during firmware download + */ +int st_get_uart_wr_room(struct st_data_s *st_gdata); /** * st_int_write - * point this to tty->driver->write or tty->ops->write @@ -208,6 +213,7 @@ void gps_chrdrv_stub_init(void); */ #define LDISC_TIME 1000 #define CMD_RESP_TIME 800 +#define CMD_WR_TIME 5000 #define MAKEWORD(a, b) ((unsigned short)(((unsigned char)(a)) \ | ((unsigned short)((unsigned char)(b))) << 8)) -- cgit v1.2.3 From 6d71ba2105a1d8c1712cdfcf46fc6040e4707cb9 Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Fri, 4 Feb 2011 02:23:14 -0600 Subject: drivers:misc: ti-st: fix hci-ll on wake_ind collision Where file-transfer stops/pauses in between, is result of a HCI-LL anamoly in ST LL driver. ST LL did not copy the contents of WaitQ into the TxQ, when a WAKEUP_IND collision happened. Make also sure, that the copying mechanism is safe, by wrapping it around spin locks inside st_int_recv(). This was easily reproduced when the sleep timeout was reduced to 100ms for HCI-LL. Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_core.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index dd2c879faff6..f0d24d852078 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -236,6 +236,7 @@ void st_int_recv(void *disc_data, int len = 0, type = 0; unsigned char *plen; struct st_data_s *st_gdata = (struct st_data_s *)disc_data; + unsigned long flags; ptr = (char *)data; /* tty_receive sent null ? */ @@ -248,6 +249,7 @@ void st_int_recv(void *disc_data, "rx_count %ld", count, st_gdata->rx_state, st_gdata->rx_count); + spin_lock_irqsave(&st_gdata->lock, flags); /* Decode received bytes here */ while (count) { if (st_gdata->rx_count) { @@ -308,13 +310,25 @@ void st_int_recv(void *disc_data, * sleep state received -- */ st_ll_sleep_state(st_gdata, *ptr); + /* if WAKEUP_IND collides copy from waitq to txq + * and assume chip awake + */ + spin_unlock_irqrestore(&st_gdata->lock, flags); + if (st_ll_getstate(st_gdata) == ST_LL_AWAKE) + st_wakeup_ack(st_gdata, LL_WAKE_UP_ACK); + spin_lock_irqsave(&st_gdata->lock, flags); + ptr++; count--; continue; case LL_WAKE_UP_ACK: pr_debug("PM packet"); + + spin_unlock_irqrestore(&st_gdata->lock, flags); /* wake up ack received */ st_wakeup_ack(st_gdata, *ptr); + spin_lock_irqsave(&st_gdata->lock, flags); + ptr++; count--; continue; @@ -337,6 +351,7 @@ void st_int_recv(void *disc_data, ptr++; count--; } + spin_unlock_irqrestore(&st_gdata->lock, flags); pr_debug("done %s", __func__); return; } -- cgit v1.2.3 From 781a7395d239dbdb59738ca7fe08e71641bf583c Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Fri, 4 Feb 2011 02:23:15 -0600 Subject: drivers:misc: ti-st: remove multiple gpio handling TI shared transport driver previously intended to expose rfkill entries for each of the protocol gpio that the chip would have. However now in case such gpios exist, which requires to be enabled for a specific protocol, the responsibility lay on protocol driver. This patch removes the request/free of multiple gpios, rfkill struct references and also removes the chip_toggle function. Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_core.c | 11 ---- drivers/misc/ti-st/st_kim.c | 117 +++++++++---------------------------------- include/linux/ti_wilink_st.h | 19 +------ 3 files changed, 26 insertions(+), 121 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index f0d24d852078..1847c477c0c0 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -515,7 +515,6 @@ long st_register(struct st_proto_s *new_proto) if (test_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state)) { pr_info(" ST_REG_IN_PROGRESS:%d ", new_proto->chnl_id); /* fw download in progress */ - st_kim_chip_toggle(new_proto->chnl_id, KIM_GPIO_ACTIVE); add_channel_to_table(st_gdata, new_proto); st_gdata->protos_registered++; @@ -548,10 +547,6 @@ long st_register(struct st_proto_s *new_proto) return -EINVAL; } - /* the chnl_id might require other gpios to be toggled - */ - st_kim_chip_toggle(new_proto->chnl_id, KIM_GPIO_ACTIVE); - clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); st_recv = st_int_recv; @@ -622,12 +617,6 @@ long st_unregister(struct st_proto_s *proto) st_gdata->protos_registered--; remove_channel_from_table(st_gdata, proto); - - /* kim ignores BT in the below function - * and handles the rest, BT is toggled - * only in kim_start and kim_stop - */ - st_kim_chip_toggle(proto->chnl_id, KIM_GPIO_INACTIVE); spin_unlock_irqrestore(&st_gdata->lock, flags); if ((st_gdata->protos_registered == ST_EMPTY) && diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index 2c096ccd53b0..9ee4c788aa69 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -390,49 +390,6 @@ static long download_firmware(struct kim_data_s *kim_gdata) /**********************************************************************/ /* functions called from ST core */ -/* function to toggle the GPIO - * needs to know whether the GPIO is active high or active low - */ -void st_kim_chip_toggle(enum proto_type type, enum kim_gpio_state state) -{ - struct platform_device *kim_pdev; - struct kim_data_s *kim_gdata; - pr_info(" %s ", __func__); - - kim_pdev = st_get_plat_device(0); - kim_gdata = dev_get_drvdata(&kim_pdev->dev); - - if (kim_gdata->gpios[type] == -1) { - pr_info("gpio not requested for protocol %d", type); - return; - } - switch (type) { - case ST_BT: - /*Do Nothing */ - break; - - case ST_FM: - if (state == KIM_GPIO_ACTIVE) - gpio_set_value(kim_gdata->gpios[ST_FM], GPIO_LOW); - else - gpio_set_value(kim_gdata->gpios[ST_FM], GPIO_HIGH); - break; - - case ST_GPS: - if (state == KIM_GPIO_ACTIVE) - gpio_set_value(kim_gdata->gpios[ST_GPS], GPIO_HIGH); - else - gpio_set_value(kim_gdata->gpios[ST_GPS], GPIO_LOW); - break; - - case ST_MAX_CHANNELS: - default: - break; - } - - return; -} - /* called from ST Core, when REG_IN_PROGRESS (registration in progress) * can be because of * 1. response to read local version @@ -482,9 +439,9 @@ long st_kim_start(void *kim_data) do { /* Configure BT nShutdown to HIGH state */ - gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_LOW); + gpio_set_value(kim_gdata->nshutdown, GPIO_LOW); mdelay(5); /* FIXME: a proper toggle */ - gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_HIGH); + gpio_set_value(kim_gdata->nshutdown, GPIO_HIGH); mdelay(100); /* re-initialize the completion */ INIT_COMPLETION(kim_gdata->ldisc_installed); @@ -552,11 +509,11 @@ long st_kim_stop(void *kim_data) } /* By default configure BT nShutdown to LOW state */ - gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_LOW); + gpio_set_value(kim_gdata->nshutdown, GPIO_LOW); mdelay(1); - gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_HIGH); + gpio_set_value(kim_gdata->nshutdown, GPIO_HIGH); mdelay(1); - gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_LOW); + gpio_set_value(kim_gdata->nshutdown, GPIO_LOW); return err; } @@ -685,10 +642,8 @@ struct dentry *kim_debugfs_dir; static int kim_probe(struct platform_device *pdev) { long status; - long proto; struct kim_data_s *kim_gdata; struct ti_st_plat_data *pdata = pdev->dev.platform_data; - long *gpios = pdata->gpios; if ((pdev->id != -1) && (pdev->id < MAX_ST_DEVICES)) { /* multiple devices could exist */ @@ -713,40 +668,19 @@ static int kim_probe(struct platform_device *pdev) /* refer to itself */ kim_gdata->core_data->kim_data = kim_gdata; - for (proto = 0; proto < ST_MAX_CHANNELS; proto++) { - kim_gdata->gpios[proto] = gpios[proto]; - pr_info(" %ld gpio to be requested", gpios[proto]); + /* Claim the chip enable nShutdown gpio from the system */ + kim_gdata->nshutdown = pdata->nshutdown_gpio; + status = gpio_request(kim_gdata->nshutdown, "kim"); + if (unlikely(status)) { + pr_err(" gpio %ld request failed ", kim_gdata->nshutdown); + return status; } - for (proto = 0; (proto < ST_MAX_CHANNELS) - && (gpios[proto] != -1); proto++) { - /* Claim the Bluetooth/FM/GPIO - * nShutdown gpio from the system - */ - status = gpio_request(gpios[proto], "kim"); - if (unlikely(status)) { - pr_err(" gpio %ld request failed ", gpios[proto]); - proto -= 1; - while (proto >= 0) { - if (gpios[proto] != -1) - gpio_free(gpios[proto]); - } - return status; - } - - /* Configure nShutdown GPIO as output=0 */ - status = - gpio_direction_output(gpios[proto], 0); - if (unlikely(status)) { - pr_err(" unable to configure gpio %ld", - gpios[proto]); - proto -= 1; - while (proto >= 0) { - if (gpios[proto] != -1) - gpio_free(gpios[proto]); - } - return status; - } + /* Configure nShutdown GPIO as output=0 */ + status = gpio_direction_output(kim_gdata->nshutdown, 0); + if (unlikely(status)) { + pr_err(" unable to configure gpio %ld", kim_gdata->nshutdown); + return status; } /* get reference of pdev for request_firmware */ @@ -785,23 +719,20 @@ static int kim_remove(struct platform_device *pdev) { /* free the GPIOs requested */ struct ti_st_plat_data *pdata = pdev->dev.platform_data; - long *gpios = pdata->gpios; - long proto; struct kim_data_s *kim_gdata; kim_gdata = dev_get_drvdata(&pdev->dev); - for (proto = 0; (proto < ST_MAX_CHANNELS) - && (gpios[proto] != -1); proto++) { - /* Claim the Bluetooth/FM/GPIO - * nShutdown gpio from the system - */ - gpio_free(gpios[proto]); - } - pr_info("kim: GPIO Freed"); - debugfs_remove_recursive(kim_debugfs_dir); + /* Free the Bluetooth/FM/GPIO + * nShutdown gpio from the system + */ + gpio_free(pdata->nshutdown_gpio); + pr_info("nshutdown GPIO Freed"); + debugfs_remove_recursive(kim_debugfs_dir); sysfs_remove_group(&pdev->dev.kobj, &uim_attr_grp); + pr_info("sysfs entries removed"); + kim_gdata->kim_pdev = NULL; st_core_exit(kim_gdata->core_data); diff --git a/include/linux/ti_wilink_st.h b/include/linux/ti_wilink_st.h index 7885a779c588..7071ec5d0118 100644 --- a/include/linux/ti_wilink_st.h +++ b/include/linux/ti_wilink_st.h @@ -25,15 +25,6 @@ #ifndef TI_WILINK_ST_H #define TI_WILINK_ST_H -/** - * enum kim_gpio_state - Few protocols such as FM have ACTIVE LOW - * gpio states for their chip/core enable gpios - */ -enum kim_gpio_state { - KIM_GPIO_INACTIVE, - KIM_GPIO_ACTIVE, -}; - /** * enum proto-type - The protocol on WiLink chips which share a * common physical interface like UART. @@ -252,14 +243,11 @@ struct chip_version { * the ldisc was properly installed. * @resp_buffer: data buffer for the .bts fw file name. * @fw_entry: firmware class struct to request/release the fw. - * @gpios: the list of core/chip enable gpios for BT, FM and GPS cores. * @rx_state: the rx state for kim's receive func during fw download. * @rx_count: the rx count for the kim's receive func during fw download. * @rx_skb: all of fw data might not come at once, and hence data storage for * whole of the fw response, only HCI_EVENTs and hence diff from ST's * response. - * @rfkill: rfkill data for each of the cores to be registered with rfkill. - * @rf_protos: proto types of the data registered with rfkill sub-system. * @core_data: ST core's data, which mainly is the tty's disc_data * @version: chip version available via a sysfs entry. * @@ -270,12 +258,10 @@ struct kim_data_s { struct completion kim_rcvd, ldisc_installed; char resp_buffer[30]; const struct firmware *fw_entry; - long gpios[ST_MAX_CHANNELS]; + long nshutdown; unsigned long rx_state; unsigned long rx_count; struct sk_buff *rx_skb; - struct rfkill *rfkill[ST_MAX_CHANNELS]; - enum proto_type rf_protos[ST_MAX_CHANNELS]; struct st_data_s *core_data; struct chip_version version; unsigned char ldisc_install; @@ -293,7 +279,6 @@ long st_kim_start(void *); long st_kim_stop(void *); void st_kim_recv(void *, const unsigned char *, long count); -void st_kim_chip_toggle(enum proto_type, enum kim_gpio_state); void st_kim_complete(void *); void kim_st_list_protocols(struct st_data_s *, void *); @@ -426,7 +411,7 @@ struct gps_event_hdr { /* platform data */ struct ti_st_plat_data { - long gpios[ST_MAX_CHANNELS]; /* BT, FM and GPS */ + long nshutdown_gpio; unsigned char dev_name[UART_DEV_NAME_LEN]; /* uart name */ unsigned char flow_cntrl; /* flow control flag */ unsigned long baud_rate; -- cgit v1.2.3 From 165d290f8a315b8af950aa15b23665c7950f8843 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 3 Feb 2011 11:07:39 +0100 Subject: staging: ft1000: Remove dead code. Remove code which was under #if 0. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- .../staging/ft1000/ft1000-usb/ft1000_download.c | 63 +--------------------- 1 file changed, 1 insertion(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 17546d8ec08d..0ee80b58a97b 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -168,18 +168,6 @@ static u32 check_usb_db (struct ft1000_device *ft1000dev) DEBUG("check_usb_db: door bell is cleared, return 0\n"); return 0; } -#if 0 - // Check if Card is present - status = ft1000_read_register (ft1000dev, &temp, FT1000_REG_SUP_IMASK); - if (temp == 0x0000) { - break; - } - - status = ft1000_read_register (ft1000dev, &temp, FT1000_REG_ASIC_ID); - if (temp == 0xffff) { - break; - } -#endif } return HANDSHAKE_MAG_TIMEOUT_VALUE; @@ -446,34 +434,6 @@ static long get_request_value(struct ft1000_device *ft1000dev) } -#if 0 -static long get_request_value_usb(struct ft1000_device *ft1000dev) -{ - u32 value; - u16 tempword; - u32 status; - struct ft1000_info * pft1000info = netdev_priv(ft1000dev->net); - - if (pft1000info->usbboot == 2) { - value = pft1000info->tempbuf[4]; - tempword = pft1000info->tempbuf[5]; - } - else { - value = 0; - status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 1); - } - - value |= (tempword << 16); - value = ntohl(value); - - if (pft1000info->usbboot == 1) - pft1000info->usbboot = 2; - - //DEBUG("get_request_value_usb: value is %x\n", value); - return value; - -} -#endif //--------------------------------------------------------------------------- // Function: put_request_value @@ -723,22 +683,7 @@ static u32 write_blk_fifo (struct ft1000_device *ft1000dev, u16 **pUsFile, u8 ** if (byte_length < 64) byte_length = 68; -#if 0 - pblk = kzalloc(byte_length, GFP_KERNEL); - memcpy (pblk, *pUcFile, byte_length); - - pipe = usb_sndbulkpipe (ft1000dev->dev, ft1000dev->bulk_out_endpointAddr); - Status = usb_bulk_msg (ft1000dev->dev, - pipe, - pblk, - byte_length, - &cnt, - 10); - DEBUG("write_blk_fifo Status = 0x%8x Bytes Transfer = %d Data = 0x%x\n", Status, cnt, *pblk); - - kfree(pblk); -#else usb_init_urb(ft1000dev->tx_urb); memcpy (ft1000dev->tx_buf, *pUcFile, byte_length); usb_fill_bulk_urb(ft1000dev->tx_urb, @@ -750,7 +695,6 @@ static u32 write_blk_fifo (struct ft1000_device *ft1000dev, u16 **pUsFile, u8 ** (void*)ft1000dev); usb_submit_urb(ft1000dev->tx_urb, GFP_ATOMIC); -#endif *pUsFile = *pUsFile + (word_length << 1); *pUcFile = *pUcFile + (word_length << 2); @@ -1000,15 +944,10 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng status = STATUS_FAILURE; break; } -#if 0 - word_length = get_request_value_usb(ft1000dev); - //DEBUG("FT1000:download:word_length = %d\n", (int)word_length); - if (word_length > MAX_LENGTH/2) -#else + word_length = get_request_value(ft1000dev); //DEBUG("FT1000:download:word_length = %d\n", (int)word_length); if (word_length > MAX_LENGTH) -#endif { DEBUG("FT1000:download:Download error: Max length exceeded\n"); status = STATUS_FAILURE; -- cgit v1.2.3 From c5d680c0585271593b66b2274658d4b81ff1eb4b Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 3 Feb 2011 11:07:40 +0100 Subject: staging: ft1000: Fix coding style in check_usb_db() function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- .../staging/ft1000/ft1000-usb/ft1000_download.c | 85 ++++++++++------------ 1 file changed, 40 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 0ee80b58a97b..03694db72096 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -125,53 +125,48 @@ struct dsp_image_info { //--------------------------------------------------------------------------- static u32 check_usb_db (struct ft1000_device *ft1000dev) { - int loopcnt; - u16 temp; - u32 status; - - loopcnt = 0; - while (loopcnt < 10) - { - - status = ft1000_read_register (ft1000dev, &temp, FT1000_REG_DOORBELL); - DEBUG("check_usb_db: read FT1000_REG_DOORBELL value is %x\n", temp); - if (temp & 0x0080) - { - DEBUG("FT1000:Got checkusb doorbell\n"); - status = ft1000_write_register (ft1000dev, 0x0080, FT1000_REG_DOORBELL); - status = ft1000_write_register (ft1000dev, 0x0100, FT1000_REG_DOORBELL); - status = ft1000_write_register (ft1000dev, 0x8000, FT1000_REG_DOORBELL); - break; - } - else - { - loopcnt++; - msleep (10); - } - - } //end of while - - - loopcnt = 0; - while (loopcnt < 20) - { - - status = ft1000_read_register (ft1000dev, &temp, FT1000_REG_DOORBELL); - DEBUG("FT1000:check_usb_db:Doorbell = 0x%x\n", temp); - if (temp & 0x8000) - { - loopcnt++; - msleep (10); - } - else - { - DEBUG("check_usb_db: door bell is cleared, return 0\n"); - return 0; - } - } + int loopcnt; + u16 temp; + u32 status; + + loopcnt = 0; + + while (loopcnt < 10) { + status = ft1000_read_register(ft1000dev, &temp, + FT1000_REG_DOORBELL); + DEBUG("check_usb_db: read FT1000_REG_DOORBELL value is %x\n", + temp); + if (temp & 0x0080) { + DEBUG("FT1000:Got checkusb doorbell\n"); + status = ft1000_write_register(ft1000dev, 0x0080, + FT1000_REG_DOORBELL); + status = ft1000_write_register(ft1000dev, 0x0100, + FT1000_REG_DOORBELL); + status = ft1000_write_register(ft1000dev, 0x8000, + FT1000_REG_DOORBELL); + break; + } else { + loopcnt++; + msleep(10); + } - return HANDSHAKE_MAG_TIMEOUT_VALUE; + } + + loopcnt = 0; + while (loopcnt < 20) { + status = ft1000_read_register(ft1000dev, &temp, + FT1000_REG_DOORBELL); + DEBUG("FT1000:check_usb_db:Doorbell = 0x%x\n", temp); + if (temp & 0x8000) { + loopcnt++; + msleep(10); + } else { + DEBUG("check_usb_db: door bell is cleared, return 0\n"); + return 0; + } + } + return HANDSHAKE_MAG_TIMEOUT_VALUE; } //--------------------------------------------------------------------------- -- cgit v1.2.3 From a8d4d198a72692852ab44d9026285feb656549b3 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 3 Feb 2011 11:07:41 +0100 Subject: staging: ft1000: Fix coding style in put_handshake() function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- .../staging/ft1000/ft1000-usb/ft1000_download.c | 27 +++++++++++----------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 03694db72096..14729432d1df 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -254,20 +254,21 @@ static u16 get_handshake(struct ft1000_device *ft1000dev, u16 expected_value) //--------------------------------------------------------------------------- static void put_handshake(struct ft1000_device *ft1000dev,u16 handshake_value) { - u32 tempx; - u16 tempword; - u32 status; - - - - tempx = (u32)handshake_value; - tempx = ntohl(tempx); + u32 tempx; + u16 tempword; + u32 status; - tempword = (u16)(tempx & 0xffff); - status = ft1000_write_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, tempword, 0); - tempword = (u16)(tempx >> 16); - status = ft1000_write_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, tempword, 1); - status = ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX, FT1000_REG_DOORBELL); + tempx = (u32)handshake_value; + tempx = ntohl(tempx); + + tempword = (u16)(tempx & 0xffff); + status = ft1000_write_dpram16(ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, + tempword, 0); + tempword = (u16)(tempx >> 16); + status = ft1000_write_dpram16(ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, + tempword, 1); + status = ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX, + FT1000_REG_DOORBELL); } static u16 get_handshake_usb(struct ft1000_device *ft1000dev, u16 expected_value) -- cgit v1.2.3 From 5865a18eaa170189240f34d4072dd0e0604209ab Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 3 Feb 2011 11:07:42 +0100 Subject: staging: ft1000: Fix coding style in get_handshake_usb() function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- .../staging/ft1000/ft1000-usb/ft1000_download.c | 74 ++++++++++++---------- 1 file changed, 41 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 14729432d1df..c22ce5401671 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -273,42 +273,50 @@ static void put_handshake(struct ft1000_device *ft1000dev,u16 handshake_value) static u16 get_handshake_usb(struct ft1000_device *ft1000dev, u16 expected_value) { - u16 handshake; - int loopcnt; - u16 temp; - u32 status=0; + u16 handshake; + int loopcnt; + u16 temp; + u32 status = 0; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); - loopcnt = 0; - handshake = 0; - while (loopcnt < 100) - { - if (pft1000info->usbboot == 2) { - status = ft1000_read_dpram32 (ft1000dev, 0, (u8 *)&(pft1000info->tempbuf[0]), 64); - for (temp=0; temp<16; temp++) - DEBUG("tempbuf %d = 0x%x\n", temp, pft1000info->tempbuf[temp]); - status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (u8 *)&handshake, 1); - DEBUG("handshake from read_dpram16 = 0x%x\n", handshake); - if (pft1000info->dspalive == pft1000info->tempbuf[6]) - handshake = 0; - else { - handshake = pft1000info->tempbuf[1]; - pft1000info->dspalive = pft1000info->tempbuf[6]; - } - } - else { - status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (u8 *)&handshake, 1); - } - loopcnt++; - msleep(10); - handshake = ntohs(handshake); - if ((handshake == expected_value) || (handshake == HANDSHAKE_RESET_VALUE_USB)) - { - return handshake; - } - } + loopcnt = 0; + handshake = 0; + + while (loopcnt < 100) { + if (pft1000info->usbboot == 2) { + status = ft1000_read_dpram32(ft1000dev, 0, + (u8 *)&(pft1000info->tempbuf[0]), 64); + for (temp = 0; temp < 16; temp++) { + DEBUG("tempbuf %d = 0x%x\n", temp, + pft1000info->tempbuf[temp]); + } + status = ft1000_read_dpram16(ft1000dev, + DWNLD_MAG1_HANDSHAKE_LOC, + (u8 *)&handshake, 1); + DEBUG("handshake from read_dpram16 = 0x%x\n", + handshake); + if (pft1000info->dspalive == pft1000info->tempbuf[6]) { + handshake = 0; + } else { + handshake = pft1000info->tempbuf[1]; + pft1000info->dspalive = + pft1000info->tempbuf[6]; + } + } else { + status = ft1000_read_dpram16(ft1000dev, + DWNLD_MAG1_HANDSHAKE_LOC, + (u8 *)&handshake, 1); + } - return HANDSHAKE_TIMEOUT_VALUE; + loopcnt++; + msleep(10); + handshake = ntohs(handshake); + if ((handshake == expected_value) || + (handshake == HANDSHAKE_RESET_VALUE_USB)) + return handshake; + } + + return HANDSHAKE_TIMEOUT_VALUE; } static void put_handshake_usb(struct ft1000_device *ft1000dev,u16 handshake_value) -- cgit v1.2.3 From 5acc5396af600d0830b4a162b65f8540e5ed17f4 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 3 Feb 2011 11:07:43 +0100 Subject: staging: ft1000: Fix coding style in put_handshake_usb() function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_download.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index c22ce5401671..18364c2c87ca 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -321,7 +321,7 @@ static u16 get_handshake_usb(struct ft1000_device *ft1000dev, u16 expected_value static void put_handshake_usb(struct ft1000_device *ft1000dev,u16 handshake_value) { - int i; + int i; for (i=0; i<1000; i++); } -- cgit v1.2.3 From 9b43f374686a285f023bc3dbc574c09e6e506f64 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 3 Feb 2011 11:07:44 +0100 Subject: staging: ft1000: Fix coding style in get_request_type() function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- .../staging/ft1000/ft1000-usb/ft1000_download.c | 38 ++++++++++------------ 1 file changed, 17 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 18364c2c87ca..ddd4e12279d3 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -340,30 +340,26 @@ static void put_handshake_usb(struct ft1000_device *ft1000dev,u16 handshake_valu //--------------------------------------------------------------------------- static u16 get_request_type(struct ft1000_device *ft1000dev) { - u16 request_type; - u32 status; - u16 tempword; - u32 tempx; + u16 request_type; + u32 status; + u16 tempword; + u32 tempx; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); - if ( pft1000info->bootmode == 1) - { - status = fix_ft1000_read_dpram32 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx); - tempx = ntohl(tempx); - } - else - { - tempx = 0; - - status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (u8 *)&tempword, 1); - tempx |= (tempword << 16); - tempx = ntohl(tempx); - } - request_type = (u16)tempx; - - //DEBUG("get_request_type: request_type is %x\n", request_type); - return request_type; + if (pft1000info->bootmode == 1) { + status = fix_ft1000_read_dpram32(ft1000dev, + DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx); + tempx = ntohl(tempx); + } else { + tempx = 0; + status = ft1000_read_dpram16(ft1000dev, + DWNLD_MAG1_TYPE_LOC, (u8 *)&tempword, 1); + tempx |= (tempword << 16); + tempx = ntohl(tempx); + } + request_type = (u16)tempx; + return request_type; } static u16 get_request_type_usb(struct ft1000_device *ft1000dev) -- cgit v1.2.3 From c3ed5d2f25b89b67011f2883a141c5115eef415b Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 3 Feb 2011 11:07:45 +0100 Subject: staging: ft1000: Fix coding style in get_request_type_usb() function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- .../staging/ft1000/ft1000-usb/ft1000_download.c | 48 +++++++++++----------- 1 file changed, 23 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index ddd4e12279d3..7496ad8732a6 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -364,34 +364,32 @@ static u16 get_request_type(struct ft1000_device *ft1000dev) static u16 get_request_type_usb(struct ft1000_device *ft1000dev) { - u16 request_type; - u32 status; - u16 tempword; - u32 tempx; + u16 request_type; + u32 status; + u16 tempword; + u32 tempx; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); - if ( pft1000info->bootmode == 1) - { - status = fix_ft1000_read_dpram32 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx); - tempx = ntohl(tempx); - } - else - { - if (pft1000info->usbboot == 2) { - tempx = pft1000info->tempbuf[2]; - tempword = pft1000info->tempbuf[3]; - } - else { - tempx = 0; - status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (u8 *)&tempword, 1); - } - tempx |= (tempword << 16); - tempx = ntohl(tempx); - } - request_type = (u16)tempx; - //DEBUG("get_request_type: request_type is %x\n", request_type); - return request_type; + if (pft1000info->bootmode == 1) { + status = fix_ft1000_read_dpram32(ft1000dev, + DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx); + tempx = ntohl(tempx); + } else { + if (pft1000info->usbboot == 2) { + tempx = pft1000info->tempbuf[2]; + tempword = pft1000info->tempbuf[3]; + } else { + tempx = 0; + status = ft1000_read_dpram16(ft1000dev, + DWNLD_MAG1_TYPE_LOC, + (u8 *)&tempword, 1); + } + tempx |= (tempword << 16); + tempx = ntohl(tempx); + } + request_type = (u16)tempx; + return request_type; } //--------------------------------------------------------------------------- -- cgit v1.2.3 From 114a06ae848a1ca718f3e2ab077bddb15e576991 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 3 Feb 2011 11:07:46 +0100 Subject: staging: ft1000: Fix coding style in get_request_value() function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- .../staging/ft1000/ft1000-usb/ft1000_download.c | 38 ++++++++++------------ 1 file changed, 17 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 7496ad8732a6..223c0471ccc2 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -406,30 +406,26 @@ static u16 get_request_type_usb(struct ft1000_device *ft1000dev) //--------------------------------------------------------------------------- static long get_request_value(struct ft1000_device *ft1000dev) { - u32 value; - u16 tempword; - u32 status; + u32 value; + u16 tempword; + u32 status; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); + if (pft1000info->bootmode == 1) { + status = fix_ft1000_read_dpram32(ft1000dev, + DWNLD_MAG1_SIZE_LOC, (u8 *)&value); + value = ntohl(value); + } else { + status = ft1000_read_dpram16(ft1000dev, + DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 0); + value = tempword; + status = ft1000_read_dpram16(ft1000dev, + DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 1); + value |= (tempword << 16); + value = ntohl(value); + } - if ( pft1000info->bootmode == 1) - { - status = fix_ft1000_read_dpram32(ft1000dev, DWNLD_MAG1_SIZE_LOC, (u8 *)&value); - value = ntohl(value); - } - else - { - status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 0); - value = tempword; - status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 1); - value |= (tempword << 16); - value = ntohl(value); - } - - - //DEBUG("get_request_value: value is %x\n", value); - return value; - + return value; } -- cgit v1.2.3 From cc4f65bfbf65e94d5be7573951f87998849b38ff Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 3 Feb 2011 11:07:47 +0100 Subject: staging: ft1000: Fix coding style in put_request_value() function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_download.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 223c0471ccc2..564e5788ba8f 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -444,16 +444,12 @@ static long get_request_value(struct ft1000_device *ft1000dev) //--------------------------------------------------------------------------- static void put_request_value(struct ft1000_device *ft1000dev, long lvalue) { - u32 tempx; - u32 status; - - tempx = ntohl(lvalue); - status = fix_ft1000_write_dpram32(ft1000dev, DWNLD_MAG1_SIZE_LOC, (u8 *)&tempx); - - - - //DEBUG("put_request_value: value is %x\n", lvalue); + u32 tempx; + u32 status; + tempx = ntohl(lvalue); + status = fix_ft1000_write_dpram32(ft1000dev, DWNLD_MAG1_SIZE_LOC, + (u8 *)&tempx); } -- cgit v1.2.3 From 78395f672a3befb69e0c0e2d9672ddddce465095 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 3 Feb 2011 11:07:48 +0100 Subject: staging: ft1000: Fix coding style in hdr_checksum() function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_download.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 564e5788ba8f..b80f11bbd67d 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -468,14 +468,14 @@ static void put_request_value(struct ft1000_device *ft1000dev, long lvalue) //--------------------------------------------------------------------------- static u16 hdr_checksum(struct pseudo_hdr *pHdr) { - u16 *usPtr = (u16 *)pHdr; - u16 chksum; + u16 *usPtr = (u16 *)pHdr; + u16 chksum; - chksum = ((((((usPtr[0] ^ usPtr[1]) ^ usPtr[2]) ^ usPtr[3]) ^ - usPtr[4]) ^ usPtr[5]) ^ usPtr[6]); + chksum = ((((((usPtr[0] ^ usPtr[1]) ^ usPtr[2]) ^ usPtr[3]) ^ + usPtr[4]) ^ usPtr[5]) ^ usPtr[6]); - return chksum; + return chksum; } -- cgit v1.2.3 From d7a7318b387ae4be24619fbac68ce5b5f5a7b7da Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 3 Feb 2011 11:07:49 +0100 Subject: staging: ft1000: Fix coding style in get_handshake() function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- .../staging/ft1000/ft1000-usb/ft1000_download.c | 82 ++++++++++------------ 1 file changed, 37 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index b80f11bbd67d..7a930f56ff46 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -185,57 +185,49 @@ static u32 check_usb_db (struct ft1000_device *ft1000dev) //--------------------------------------------------------------------------- static u16 get_handshake(struct ft1000_device *ft1000dev, u16 expected_value) { - u16 handshake; - int loopcnt; - u32 status=0; + u16 handshake; + int loopcnt; + u32 status = 0; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); - loopcnt = 0; - while (loopcnt < 100) - { + loopcnt = 0; - // Need to clear downloader doorbell if Hartley ASIC - status = ft1000_write_register (ft1000dev, FT1000_DB_DNLD_RX, FT1000_REG_DOORBELL); - //DEBUG("FT1000:get_handshake:doorbell = 0x%x\n", temp); - if (pft1000info->fcodeldr) - { - DEBUG(" get_handshake: fcodeldr is %d\n", pft1000info->fcodeldr); - pft1000info->fcodeldr = 0; - status = check_usb_db(ft1000dev); - if (status != STATUS_SUCCESS) - { - DEBUG("get_handshake: check_usb_db failed\n"); - status = STATUS_FAILURE; - break; - } - status = ft1000_write_register (ft1000dev, FT1000_DB_DNLD_RX, FT1000_REG_DOORBELL); - } + while (loopcnt < 100) { + /* Need to clear downloader doorbell if Hartley ASIC */ + status = ft1000_write_register(ft1000dev, FT1000_DB_DNLD_RX, + FT1000_REG_DOORBELL); + if (pft1000info->fcodeldr) { + DEBUG(" get_handshake: fcodeldr is %d\n", + pft1000info->fcodeldr); + pft1000info->fcodeldr = 0; + status = check_usb_db(ft1000dev); + if (status != STATUS_SUCCESS) { + DEBUG("get_handshake: check_usb_db failed\n"); + status = STATUS_FAILURE; + break; + } + status = ft1000_write_register(ft1000dev, + FT1000_DB_DNLD_RX, + FT1000_REG_DOORBELL); + } - status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (u8 *)&handshake, 1); - //DEBUG("get_handshake: handshake is %x\n", tempx); - handshake = ntohs(handshake); - //DEBUG("get_handshake: after swap, handshake is %x\n", handshake); - - if (status) - return HANDSHAKE_TIMEOUT_VALUE; - - //DEBUG("get_handshake: handshake= %x\n", handshake); - if ((handshake == expected_value) || (handshake == HANDSHAKE_RESET_VALUE_USB)) - { - //DEBUG("get_handshake: return handshake %x\n", handshake); - return handshake; - } - else - { - loopcnt++; - msleep (10); - } - //DEBUG("HANDSHKE LOOP: %d\n", loopcnt); + status = ft1000_read_dpram16(ft1000dev, + DWNLD_MAG1_HANDSHAKE_LOC, (u8 *)&handshake, 1); + handshake = ntohs(handshake); - } + if (status) + return HANDSHAKE_TIMEOUT_VALUE; + + if ((handshake == expected_value) || + (handshake == HANDSHAKE_RESET_VALUE_USB)) { + return handshake; + } else { + loopcnt++; + msleep(10); + } + } - //DEBUG("get_handshake: return handshake time out\n"); - return HANDSHAKE_TIMEOUT_VALUE; + return HANDSHAKE_TIMEOUT_VALUE; } //--------------------------------------------------------------------------- -- cgit v1.2.3 From 857af455c8e7865a8a24047534a92e3d016da4ab Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 3 Feb 2011 11:07:50 +0100 Subject: staging: ft1000: Fix coding style in write_blk_fifo() function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- .../staging/ft1000/ft1000-usb/ft1000_download.c | 56 +++++++++++----------- 1 file changed, 27 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 7a930f56ff46..0c69a68c5c4b 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -644,44 +644,42 @@ static void usb_dnld_complete (struct urb *urb) // Notes: // //--------------------------------------------------------------------------- -static u32 write_blk_fifo (struct ft1000_device *ft1000dev, u16 **pUsFile, u8 **pUcFile, long word_length) +static u32 write_blk_fifo(struct ft1000_device *ft1000dev, u16 **pUsFile, + u8 **pUcFile, long word_length) { - u32 Status = STATUS_SUCCESS; - int byte_length; - long aligncnt; - - byte_length = word_length * 4; + u32 Status = STATUS_SUCCESS; + int byte_length; + long aligncnt; - if (byte_length % 4) - aligncnt = 4 - (byte_length % 4); - else - aligncnt = 0; - byte_length += aligncnt; + byte_length = word_length * 4; - if (byte_length && ((byte_length % 64) == 0)) { - byte_length += 4; - } + if (byte_length % 4) + aligncnt = 4 - (byte_length % 4); + else + aligncnt = 0; + byte_length += aligncnt; - if (byte_length < 64) - byte_length = 68; + if (byte_length && ((byte_length % 64) == 0)) + byte_length += 4; + if (byte_length < 64) + byte_length = 68; - usb_init_urb(ft1000dev->tx_urb); - memcpy (ft1000dev->tx_buf, *pUcFile, byte_length); - usb_fill_bulk_urb(ft1000dev->tx_urb, - ft1000dev->dev, - usb_sndbulkpipe(ft1000dev->dev, ft1000dev->bulk_out_endpointAddr), - ft1000dev->tx_buf, - byte_length, - usb_dnld_complete, - (void*)ft1000dev); + usb_init_urb(ft1000dev->tx_urb); + memcpy(ft1000dev->tx_buf, *pUcFile, byte_length); + usb_fill_bulk_urb(ft1000dev->tx_urb, + ft1000dev->dev, + usb_sndbulkpipe(ft1000dev->dev, + ft1000dev->bulk_out_endpointAddr), + ft1000dev->tx_buf, byte_length, usb_dnld_complete, + (void *)ft1000dev); - usb_submit_urb(ft1000dev->tx_urb, GFP_ATOMIC); + usb_submit_urb(ft1000dev->tx_urb, GFP_ATOMIC); - *pUsFile = *pUsFile + (word_length << 1); - *pUcFile = *pUcFile + (word_length << 2); + *pUsFile = *pUsFile + (word_length << 1); + *pUcFile = *pUcFile + (word_length << 2); - return Status; + return Status; } //--------------------------------------------------------------------------- -- cgit v1.2.3 From 6f953fbbf6a8fdcc54b182a3a528bbd6404d1c55 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 3 Feb 2011 11:07:51 +0100 Subject: staging: ft1000: Fix indentation in scram_dnldr() function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- .../staging/ft1000/ft1000-usb/ft1000_download.c | 948 +++++++++++---------- 1 file changed, 518 insertions(+), 430 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 0c69a68c5c4b..88edc41c1015 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -694,455 +694,542 @@ static u32 write_blk_fifo(struct ft1000_device *ft1000dev, u16 **pUsFile, // Returns: status - return code //--------------------------------------------------------------------------- -u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLength) +u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, + u32 FileLength) { - u16 status = STATUS_SUCCESS; - u32 state; - u16 handshake; + u16 status = STATUS_SUCCESS; + u32 state; + u16 handshake; struct pseudo_hdr *pseudo_header; - u16 pseudo_header_len; - long word_length; - u16 request; - u16 temp; - u16 tempword; + u16 pseudo_header_len; + long word_length; + u16 request; + u16 temp; + u16 tempword; struct dsp_file_hdr *file_hdr; struct dsp_image_info *dsp_img_info = NULL; - long requested_version; - bool correct_version; + long requested_version; + bool correct_version; struct drv_msg *mailbox_data; - u16 *data = NULL; - u16 *s_file = NULL; - u8 *c_file = NULL; - u8 *boot_end = NULL, *code_end= NULL; - int image; - long loader_code_address, loader_code_size = 0; - long run_address = 0, run_size = 0; - - u32 templong; - u32 image_chksum = 0; - - u16 dpram = 0; - u8 *pbuffer; + u16 *data = NULL; + u16 *s_file = NULL; + u8 *c_file = NULL; + u8 *boot_end = NULL, *code_end = NULL; + int image; + long loader_code_address, loader_code_size = 0; + long run_address = 0, run_size = 0; + + u32 templong; + u32 image_chksum = 0; + + u16 dpram = 0; + u8 *pbuffer; struct prov_record *pprov_record; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); - DEBUG("Entered scram_dnldr...\n"); + DEBUG("Entered scram_dnldr...\n"); + + pft1000info->fcodeldr = 0; + pft1000info->usbboot = 0; + pft1000info->dspalive = 0xffff; - pft1000info->fcodeldr = 0; - pft1000info->usbboot = 0; - pft1000info->dspalive = 0xffff; + // + // Get version id of file, at first 4 bytes of file, for newer files. + // + state = STATE_START_DWNLD; - // - // Get version id of file, at first 4 bytes of file, for newer files. - // + file_hdr = (struct dsp_file_hdr *)pFileStart; - state = STATE_START_DWNLD; + ft1000_write_register(ft1000dev, 0x800, FT1000_REG_MAG_WATERMARK); - file_hdr = (struct dsp_file_hdr *)pFileStart; + s_file = (u16 *) (pFileStart + file_hdr->loader_offset); + c_file = (u8 *) (pFileStart + file_hdr->loader_offset); - ft1000_write_register (ft1000dev, 0x800, FT1000_REG_MAG_WATERMARK); + boot_end = (u8 *) (pFileStart + file_hdr->loader_code_end); - s_file = (u16 *)(pFileStart + file_hdr->loader_offset); - c_file = (u8 *)(pFileStart + file_hdr->loader_offset); + loader_code_address = file_hdr->loader_code_address; + loader_code_size = file_hdr->loader_code_size; + correct_version = FALSE; + + while ((status == STATUS_SUCCESS) && (state != STATE_DONE_FILE)) { + switch (state) { + case STATE_START_DWNLD: + DEBUG("FT1000:STATE_START_DWNLD\n"); + if (pft1000info->usbboot) + handshake = + get_handshake_usb(ft1000dev, + HANDSHAKE_DSP_BL_READY); + else + handshake = + get_handshake(ft1000dev, + HANDSHAKE_DSP_BL_READY); + + if (handshake == HANDSHAKE_DSP_BL_READY) { + DEBUG + ("scram_dnldr: handshake is HANDSHAKE_DSP_BL_READY, call put_handshake(HANDSHAKE_DRIVER_READY)\n"); + put_handshake(ft1000dev, + HANDSHAKE_DRIVER_READY); + } else { + DEBUG + ("FT1000:download:Download error: Handshake failed\n"); + status = STATUS_FAILURE; + } - boot_end = (u8 *)(pFileStart + file_hdr->loader_code_end); + state = STATE_BOOT_DWNLD; - loader_code_address = file_hdr->loader_code_address; - loader_code_size = file_hdr->loader_code_size; - correct_version = FALSE; + break; - while ((status == STATUS_SUCCESS) && (state != STATE_DONE_FILE)) - { - switch (state) - { - case STATE_START_DWNLD: - DEBUG("FT1000:STATE_START_DWNLD\n"); - if (pft1000info->usbboot) - handshake = get_handshake_usb(ft1000dev, HANDSHAKE_DSP_BL_READY); - else - handshake = get_handshake(ft1000dev, HANDSHAKE_DSP_BL_READY); - - if (handshake == HANDSHAKE_DSP_BL_READY) - { - DEBUG("scram_dnldr: handshake is HANDSHAKE_DSP_BL_READY, call put_handshake(HANDSHAKE_DRIVER_READY)\n"); - put_handshake(ft1000dev, HANDSHAKE_DRIVER_READY); - } - else - { - DEBUG("FT1000:download:Download error: Handshake failed\n"); - status = STATUS_FAILURE; - } - - state = STATE_BOOT_DWNLD; - - break; - - case STATE_BOOT_DWNLD: - DEBUG("FT1000:STATE_BOOT_DWNLD\n"); - pft1000info->bootmode = 1; - handshake = get_handshake(ft1000dev, HANDSHAKE_REQUEST); - if (handshake == HANDSHAKE_REQUEST) - { - /* - * Get type associated with the request. - */ - request = get_request_type(ft1000dev); - switch (request) - { - case REQUEST_RUN_ADDRESS: - DEBUG("FT1000:REQUEST_RUN_ADDRESS\n"); - put_request_value(ft1000dev, loader_code_address); - break; - case REQUEST_CODE_LENGTH: - DEBUG("FT1000:REQUEST_CODE_LENGTH\n"); - put_request_value(ft1000dev, loader_code_size); - break; - case REQUEST_DONE_BL: - DEBUG("FT1000:REQUEST_DONE_BL\n"); - /* Reposition ptrs to beginning of code section */ - s_file = (u16 *)(boot_end); - c_file = (u8 *)(boot_end); - //DEBUG("FT1000:download:s_file = 0x%8x\n", (int)s_file); - //DEBUG("FT1000:download:c_file = 0x%8x\n", (int)c_file); - state = STATE_CODE_DWNLD; - pft1000info->fcodeldr = 1; - break; - case REQUEST_CODE_SEGMENT: - //DEBUG("FT1000:REQUEST_CODE_SEGMENT\n"); - word_length = get_request_value(ft1000dev); - //DEBUG("FT1000:word_length = 0x%x\n", (int)word_length); - //NdisMSleep (100); - if (word_length > MAX_LENGTH) - { - DEBUG("FT1000:download:Download error: Max length exceeded\n"); - status = STATUS_FAILURE; - break; - } - if ( (word_length*2 + c_file) > boot_end) - { - /* - * Error, beyond boot code range. - */ - DEBUG("FT1000:download:Download error: Requested len=%d exceeds BOOT code boundry.\n", - (int)word_length); - status = STATUS_FAILURE; - break; - } - /* - * Position ASIC DPRAM auto-increment pointer. - */ - dpram = (u16)DWNLD_MAG1_PS_HDR_LOC; + case STATE_BOOT_DWNLD: + DEBUG("FT1000:STATE_BOOT_DWNLD\n"); + pft1000info->bootmode = 1; + handshake = get_handshake(ft1000dev, HANDSHAKE_REQUEST); + if (handshake == HANDSHAKE_REQUEST) { + /* + * Get type associated with the request. + */ + request = get_request_type(ft1000dev); + switch (request) { + case REQUEST_RUN_ADDRESS: + DEBUG("FT1000:REQUEST_RUN_ADDRESS\n"); + put_request_value(ft1000dev, + loader_code_address); + break; + case REQUEST_CODE_LENGTH: + DEBUG("FT1000:REQUEST_CODE_LENGTH\n"); + put_request_value(ft1000dev, + loader_code_size); + break; + case REQUEST_DONE_BL: + DEBUG("FT1000:REQUEST_DONE_BL\n"); + /* Reposition ptrs to beginning of code section */ + s_file = (u16 *) (boot_end); + c_file = (u8 *) (boot_end); + //DEBUG("FT1000:download:s_file = 0x%8x\n", (int)s_file); + //DEBUG("FT1000:download:c_file = 0x%8x\n", (int)c_file); + state = STATE_CODE_DWNLD; + pft1000info->fcodeldr = 1; + break; + case REQUEST_CODE_SEGMENT: + //DEBUG("FT1000:REQUEST_CODE_SEGMENT\n"); + word_length = + get_request_value(ft1000dev); + //DEBUG("FT1000:word_length = 0x%x\n", (int)word_length); + //NdisMSleep (100); + if (word_length > MAX_LENGTH) { + DEBUG + ("FT1000:download:Download error: Max length exceeded\n"); + status = STATUS_FAILURE; + break; + } + if ((word_length * 2 + c_file) > + boot_end) { + /* + * Error, beyond boot code range. + */ + DEBUG + ("FT1000:download:Download error: Requested len=%d exceeds BOOT code boundry.\n", + (int)word_length); + status = STATUS_FAILURE; + break; + } + /* + * Position ASIC DPRAM auto-increment pointer. + */ + dpram = (u16) DWNLD_MAG1_PS_HDR_LOC; if (word_length & 0x1) word_length++; word_length = word_length / 2; - status = write_blk(ft1000dev, &s_file, &c_file, word_length); - //DEBUG("write_blk returned %d\n", status); - break; - default: - DEBUG("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n",request); - status = STATUS_FAILURE; - break; - } - if (pft1000info->usbboot) - put_handshake_usb(ft1000dev, HANDSHAKE_RESPONSE); - else - put_handshake(ft1000dev, HANDSHAKE_RESPONSE); - } - else - { - DEBUG("FT1000:download:Download error: Handshake failed\n"); - status = STATUS_FAILURE; - } - - break; - - case STATE_CODE_DWNLD: - //DEBUG("FT1000:STATE_CODE_DWNLD\n"); - pft1000info->bootmode = 0; - if (pft1000info->usbboot) - handshake = get_handshake_usb(ft1000dev, HANDSHAKE_REQUEST); - else - handshake = get_handshake(ft1000dev, HANDSHAKE_REQUEST); - if (handshake == HANDSHAKE_REQUEST) - { - /* - * Get type associated with the request. - */ - if (pft1000info->usbboot) - request = get_request_type_usb(ft1000dev); - else - request = get_request_type(ft1000dev); - switch (request) - { - case REQUEST_FILE_CHECKSUM: - DEBUG("FT1000:download:image_chksum = 0x%8x\n", image_chksum); - put_request_value(ft1000dev, image_chksum); - break; - case REQUEST_RUN_ADDRESS: - DEBUG("FT1000:download: REQUEST_RUN_ADDRESS\n"); - if (correct_version) - { - DEBUG("FT1000:download:run_address = 0x%8x\n", (int)run_address); - put_request_value(ft1000dev, run_address); - } - else - { - DEBUG("FT1000:download:Download error: Got Run address request before image offset request.\n"); - status = STATUS_FAILURE; - break; - } - break; - case REQUEST_CODE_LENGTH: - DEBUG("FT1000:download:REQUEST_CODE_LENGTH\n"); - if (correct_version) - { - DEBUG("FT1000:download:run_size = 0x%8x\n", (int)run_size); - put_request_value(ft1000dev, run_size); - } - else - { - DEBUG("FT1000:download:Download error: Got Size request before image offset request.\n"); - status = STATUS_FAILURE; - break; - } - break; - case REQUEST_DONE_CL: - pft1000info->usbboot = 3; - /* Reposition ptrs to beginning of provisioning section */ - s_file = (u16 *)(pFileStart + file_hdr->commands_offset); - c_file = (u8 *)(pFileStart + file_hdr->commands_offset); - state = STATE_DONE_DWNLD; - break; - case REQUEST_CODE_SEGMENT: - //DEBUG("FT1000:download: REQUEST_CODE_SEGMENT - CODELOADER\n"); - if (!correct_version) - { - DEBUG("FT1000:download:Download error: Got Code Segment request before image offset request.\n"); - status = STATUS_FAILURE; - break; - } - - word_length = get_request_value(ft1000dev); - //DEBUG("FT1000:download:word_length = %d\n", (int)word_length); - if (word_length > MAX_LENGTH) - { - DEBUG("FT1000:download:Download error: Max length exceeded\n"); - status = STATUS_FAILURE; - break; - } - if ( (word_length*2 + c_file) > code_end) - { - /* - * Error, beyond boot code range. - */ - DEBUG("FT1000:download:Download error: Requested len=%d exceeds DSP code boundry.\n", - (int)word_length); - status = STATUS_FAILURE; - break; - } - /* - * Position ASIC DPRAM auto-increment pointer. - */ - dpram = (u16)DWNLD_MAG1_PS_HDR_LOC; - if (word_length & 0x1) - word_length++; - word_length = word_length / 2; - - write_blk_fifo (ft1000dev, &s_file, &c_file, word_length); - if (pft1000info->usbboot == 0) - pft1000info->usbboot++; - if (pft1000info->usbboot == 1) { - tempword = 0; - ft1000_write_dpram16 (ft1000dev, DWNLD_MAG1_PS_HDR_LOC, tempword, 0); - } - - break; - - case REQUEST_MAILBOX_DATA: - DEBUG("FT1000:download: REQUEST_MAILBOX_DATA\n"); - // Convert length from byte count to word count. Make sure we round up. - word_length = (long)(pft1000info->DSPInfoBlklen + 1)/2; - put_request_value(ft1000dev, word_length); - mailbox_data = (struct drv_msg *)&(pft1000info->DSPInfoBlk[0]); - /* - * Position ASIC DPRAM auto-increment pointer. - */ - - - data = (u16 *)&mailbox_data->data[0]; - dpram = (u16)DWNLD_MAG1_PS_HDR_LOC; - if (word_length & 0x1) - word_length++; - - word_length = (word_length / 2); - - - for (; word_length > 0; word_length--) /* In words */ - { - - templong = *data++; - templong |= (*data++ << 16); - status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, (u8 *)&templong); - - } - break; - - case REQUEST_VERSION_INFO: - DEBUG("FT1000:download:REQUEST_VERSION_INFO\n"); - word_length = file_hdr->version_data_size; - put_request_value(ft1000dev, word_length); - /* - * Position ASIC DPRAM auto-increment pointer. - */ - - s_file = (u16 *)(pFileStart + file_hdr->version_data_offset); - - - dpram = (u16)DWNLD_MAG1_PS_HDR_LOC; - if (word_length & 0x1) - word_length++; - - word_length = (word_length / 2); - - - for (; word_length > 0; word_length--) /* In words */ - { - - templong = ntohs(*s_file++); - temp = ntohs(*s_file++); - templong |= (temp << 16); - status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, (u8 *)&templong); - - } - break; - - case REQUEST_CODE_BY_VERSION: - DEBUG("FT1000:download:REQUEST_CODE_BY_VERSION\n"); - correct_version = FALSE; - requested_version = get_request_value(ft1000dev); - - dsp_img_info = (struct dsp_image_info *)(pFileStart + sizeof(struct dsp_file_hdr )); - - for (image = 0; image < file_hdr->nDspImages; image++) - { - - temp = (u16)(dsp_img_info->version); - templong = temp; - temp = (u16)(dsp_img_info->version >> 16); - templong |= (temp << 16); - if (templong == (u32)requested_version) - { - correct_version = TRUE; - DEBUG("FT1000:download: correct_version is TRUE\n"); - s_file = (u16 *)(pFileStart + dsp_img_info->begin_offset); - c_file = (u8 *)(pFileStart + dsp_img_info->begin_offset); - code_end = (u8 *)(pFileStart + dsp_img_info->end_offset); - run_address = dsp_img_info->run_address; - run_size = dsp_img_info->image_size; - image_chksum = (u32)dsp_img_info->checksum; - break; - } - dsp_img_info++; - - - } //end of for - - if (!correct_version) - { - /* - * Error, beyond boot code range. - */ - DEBUG("FT1000:download:Download error: Bad Version Request = 0x%x.\n",(int)requested_version); - status = STATUS_FAILURE; - break; - } - break; - - default: - DEBUG("FT1000:download:Download error: Bad request type=%d in CODE download state.\n",request); - status = STATUS_FAILURE; - break; - } - if (pft1000info->usbboot) - put_handshake_usb(ft1000dev, HANDSHAKE_RESPONSE); - else - put_handshake(ft1000dev, HANDSHAKE_RESPONSE); - } - else - { - DEBUG("FT1000:download:Download error: Handshake failed\n"); - status = STATUS_FAILURE; - } - - break; - - case STATE_DONE_DWNLD: - DEBUG("FT1000:download:Code loader is done...\n"); - state = STATE_SECTION_PROV; - break; - - case STATE_SECTION_PROV: - DEBUG("FT1000:download:STATE_SECTION_PROV\n"); - pseudo_header = (struct pseudo_hdr *)c_file; - - if (pseudo_header->checksum == hdr_checksum(pseudo_header)) - { - if (pseudo_header->portdest != 0x80 /* Dsp OAM */) - { - state = STATE_DONE_PROV; - break; - } - pseudo_header_len = ntohs(pseudo_header->length); /* Byte length for PROV records */ - - // Get buffer for provisioning data - pbuffer = kmalloc((pseudo_header_len + sizeof(struct pseudo_hdr)), GFP_ATOMIC); - if (pbuffer) { - memcpy(pbuffer, (void *)c_file, (u32)(pseudo_header_len + sizeof(struct pseudo_hdr))); - // link provisioning data - pprov_record = kmalloc(sizeof(struct prov_record), GFP_ATOMIC); - if (pprov_record) { - pprov_record->pprov_data = pbuffer; - list_add_tail (&pprov_record->list, &pft1000info->prov_list); - // Move to next entry if available - c_file = (u8 *)((unsigned long)c_file + (u32)((pseudo_header_len + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr)); - if ( (unsigned long)(c_file) - (unsigned long)(pFileStart) >= (unsigned long)FileLength) { - state = STATE_DONE_FILE; - } - } - else { - kfree(pbuffer); - status = STATUS_FAILURE; - } - } - else { - status = STATUS_FAILURE; - } - } - else - { - /* Checksum did not compute */ - status = STATUS_FAILURE; - } - DEBUG("ft1000:download: after STATE_SECTION_PROV, state = %d, status= %d\n", state, status); - break; - - case STATE_DONE_PROV: - DEBUG("FT1000:download:STATE_DONE_PROV\n"); - state = STATE_DONE_FILE; - break; - - - default: - status = STATUS_FAILURE; - break; - } /* End Switch */ - - if (status != STATUS_SUCCESS) { - break; - } + status = + write_blk(ft1000dev, &s_file, + &c_file, word_length); + //DEBUG("write_blk returned %d\n", status); + break; + default: + DEBUG + ("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n", + request); + status = STATUS_FAILURE; + break; + } + if (pft1000info->usbboot) + put_handshake_usb(ft1000dev, + HANDSHAKE_RESPONSE); + else + put_handshake(ft1000dev, + HANDSHAKE_RESPONSE); + } else { + DEBUG + ("FT1000:download:Download error: Handshake failed\n"); + status = STATUS_FAILURE; + } + + break; + + case STATE_CODE_DWNLD: + //DEBUG("FT1000:STATE_CODE_DWNLD\n"); + pft1000info->bootmode = 0; + if (pft1000info->usbboot) + handshake = + get_handshake_usb(ft1000dev, + HANDSHAKE_REQUEST); + else + handshake = + get_handshake(ft1000dev, HANDSHAKE_REQUEST); + if (handshake == HANDSHAKE_REQUEST) { + /* + * Get type associated with the request. + */ + if (pft1000info->usbboot) + request = + get_request_type_usb(ft1000dev); + else + request = get_request_type(ft1000dev); + switch (request) { + case REQUEST_FILE_CHECKSUM: + DEBUG + ("FT1000:download:image_chksum = 0x%8x\n", + image_chksum); + put_request_value(ft1000dev, + image_chksum); + break; + case REQUEST_RUN_ADDRESS: + DEBUG + ("FT1000:download: REQUEST_RUN_ADDRESS\n"); + if (correct_version) { + DEBUG + ("FT1000:download:run_address = 0x%8x\n", + (int)run_address); + put_request_value(ft1000dev, + run_address); + } else { + DEBUG + ("FT1000:download:Download error: Got Run address request before image offset request.\n"); + status = STATUS_FAILURE; + break; + } + break; + case REQUEST_CODE_LENGTH: + DEBUG + ("FT1000:download:REQUEST_CODE_LENGTH\n"); + if (correct_version) { + DEBUG + ("FT1000:download:run_size = 0x%8x\n", + (int)run_size); + put_request_value(ft1000dev, + run_size); + } else { + DEBUG + ("FT1000:download:Download error: Got Size request before image offset request.\n"); + status = STATUS_FAILURE; + break; + } + break; + case REQUEST_DONE_CL: + pft1000info->usbboot = 3; + /* Reposition ptrs to beginning of provisioning section */ + s_file = + (u16 *) (pFileStart + + file_hdr->commands_offset); + c_file = + (u8 *) (pFileStart + + file_hdr->commands_offset); + state = STATE_DONE_DWNLD; + break; + case REQUEST_CODE_SEGMENT: + //DEBUG("FT1000:download: REQUEST_CODE_SEGMENT - CODELOADER\n"); + if (!correct_version) { + DEBUG + ("FT1000:download:Download error: Got Code Segment request before image offset request.\n"); + status = STATUS_FAILURE; + break; + } + + word_length = + get_request_value(ft1000dev); + //DEBUG("FT1000:download:word_length = %d\n", (int)word_length); + if (word_length > MAX_LENGTH) { + DEBUG + ("FT1000:download:Download error: Max length exceeded\n"); + status = STATUS_FAILURE; + break; + } + if ((word_length * 2 + c_file) > + code_end) { + /* + * Error, beyond boot code range. + */ + DEBUG + ("FT1000:download:Download error: Requested len=%d exceeds DSP code boundry.\n", + (int)word_length); + status = STATUS_FAILURE; + break; + } + /* + * Position ASIC DPRAM auto-increment pointer. + */ + dpram = (u16) DWNLD_MAG1_PS_HDR_LOC; + if (word_length & 0x1) + word_length++; + word_length = word_length / 2; + + write_blk_fifo(ft1000dev, &s_file, + &c_file, word_length); + if (pft1000info->usbboot == 0) + pft1000info->usbboot++; + if (pft1000info->usbboot == 1) { + tempword = 0; + ft1000_write_dpram16(ft1000dev, + DWNLD_MAG1_PS_HDR_LOC, + tempword, + 0); + } + + break; + + case REQUEST_MAILBOX_DATA: + DEBUG + ("FT1000:download: REQUEST_MAILBOX_DATA\n"); + // Convert length from byte count to word count. Make sure we round up. + word_length = + (long)(pft1000info->DSPInfoBlklen + + 1) / 2; + put_request_value(ft1000dev, + word_length); + mailbox_data = + (struct drv_msg *)&(pft1000info-> + DSPInfoBlk[0]); + /* + * Position ASIC DPRAM auto-increment pointer. + */ + + data = (u16 *) & mailbox_data->data[0]; + dpram = (u16) DWNLD_MAG1_PS_HDR_LOC; + if (word_length & 0x1) + word_length++; + + word_length = (word_length / 2); + + for (; word_length > 0; word_length--) { /* In words */ + + templong = *data++; + templong |= (*data++ << 16); + status = + fix_ft1000_write_dpram32 + (ft1000dev, dpram++, + (u8 *) & templong); + + } + break; + + case REQUEST_VERSION_INFO: + DEBUG + ("FT1000:download:REQUEST_VERSION_INFO\n"); + word_length = + file_hdr->version_data_size; + put_request_value(ft1000dev, + word_length); + /* + * Position ASIC DPRAM auto-increment pointer. + */ + + s_file = + (u16 *) (pFileStart + + file_hdr-> + version_data_offset); + + dpram = (u16) DWNLD_MAG1_PS_HDR_LOC; + if (word_length & 0x1) + word_length++; + + word_length = (word_length / 2); + + for (; word_length > 0; word_length--) { /* In words */ + + templong = ntohs(*s_file++); + temp = ntohs(*s_file++); + templong |= (temp << 16); + status = + fix_ft1000_write_dpram32 + (ft1000dev, dpram++, + (u8 *) & templong); + + } + break; + + case REQUEST_CODE_BY_VERSION: + DEBUG + ("FT1000:download:REQUEST_CODE_BY_VERSION\n"); + correct_version = FALSE; + requested_version = + get_request_value(ft1000dev); + + dsp_img_info = + (struct dsp_image_info *)(pFileStart + + + sizeof + (struct + dsp_file_hdr)); + + for (image = 0; + image < file_hdr->nDspImages; + image++) { + + temp = + (u16) (dsp_img_info-> + version); + templong = temp; + temp = + (u16) (dsp_img_info-> + version >> 16); + templong |= (temp << 16); + if (templong == + (u32) requested_version) { + correct_version = TRUE; + DEBUG + ("FT1000:download: correct_version is TRUE\n"); + s_file = + (u16 *) (pFileStart + + + dsp_img_info-> + begin_offset); + c_file = + (u8 *) (pFileStart + + dsp_img_info-> + begin_offset); + code_end = + (u8 *) (pFileStart + + dsp_img_info-> + end_offset); + run_address = + dsp_img_info-> + run_address; + run_size = + dsp_img_info-> + image_size; + image_chksum = + (u32) dsp_img_info-> + checksum; + break; + } + dsp_img_info++; + + } //end of for + + if (!correct_version) { + /* + * Error, beyond boot code range. + */ + DEBUG + ("FT1000:download:Download error: Bad Version Request = 0x%x.\n", + (int)requested_version); + status = STATUS_FAILURE; + break; + } + break; + + default: + DEBUG + ("FT1000:download:Download error: Bad request type=%d in CODE download state.\n", + request); + status = STATUS_FAILURE; + break; + } + if (pft1000info->usbboot) + put_handshake_usb(ft1000dev, + HANDSHAKE_RESPONSE); + else + put_handshake(ft1000dev, + HANDSHAKE_RESPONSE); + } else { + DEBUG + ("FT1000:download:Download error: Handshake failed\n"); + status = STATUS_FAILURE; + } + + break; + + case STATE_DONE_DWNLD: + DEBUG("FT1000:download:Code loader is done...\n"); + state = STATE_SECTION_PROV; + break; + + case STATE_SECTION_PROV: + DEBUG("FT1000:download:STATE_SECTION_PROV\n"); + pseudo_header = (struct pseudo_hdr *)c_file; + + if (pseudo_header->checksum == + hdr_checksum(pseudo_header)) { + if (pseudo_header->portdest != + 0x80 /* Dsp OAM */ ) { + state = STATE_DONE_PROV; + break; + } + pseudo_header_len = ntohs(pseudo_header->length); /* Byte length for PROV records */ + + // Get buffer for provisioning data + pbuffer = + kmalloc((pseudo_header_len + + sizeof(struct pseudo_hdr)), + GFP_ATOMIC); + if (pbuffer) { + memcpy(pbuffer, (void *)c_file, + (u32) (pseudo_header_len + + sizeof(struct + pseudo_hdr))); + // link provisioning data + pprov_record = + kmalloc(sizeof(struct prov_record), + GFP_ATOMIC); + if (pprov_record) { + pprov_record->pprov_data = + pbuffer; + list_add_tail(&pprov_record-> + list, + &pft1000info-> + prov_list); + // Move to next entry if available + c_file = + (u8 *) ((unsigned long) + c_file + + (u32) ((pseudo_header_len + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr)); + if ((unsigned long)(c_file) - + (unsigned long)(pFileStart) + >= + (unsigned long)FileLength) { + state = STATE_DONE_FILE; + } + } else { + kfree(pbuffer); + status = STATUS_FAILURE; + } + } else { + status = STATUS_FAILURE; + } + } else { + /* Checksum did not compute */ + status = STATUS_FAILURE; + } + DEBUG + ("ft1000:download: after STATE_SECTION_PROV, state = %d, status= %d\n", + state, status); + break; + + case STATE_DONE_PROV: + DEBUG("FT1000:download:STATE_DONE_PROV\n"); + state = STATE_DONE_FILE; + break; + + default: + status = STATUS_FAILURE; + break; + } /* End Switch */ + + if (status != STATUS_SUCCESS) { + break; + } /**** // Check if Card is present @@ -1157,11 +1244,12 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng } ****/ - } /* End while */ + } /* End while */ - DEBUG("Download exiting with status = 0x%8x\n", status); - ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX, FT1000_REG_DOORBELL); + DEBUG("Download exiting with status = 0x%8x\n", status); + ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX, + FT1000_REG_DOORBELL); - return status; + return status; } -- cgit v1.2.3 From 672dfeba92bbb1218b5e39f5aff2d1fd2e2268b8 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 3 Feb 2011 11:07:52 +0100 Subject: staging: ft1000: Remove unused variables. Remove variables which was defined and assigned but never used in function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_download.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 88edc41c1015..b789e7805c42 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -492,9 +492,7 @@ static u32 write_blk (struct ft1000_device *ft1000dev, u16 **pUsFile, u8 **pUcFi { u32 Status = STATUS_SUCCESS; u16 dpram; - long temp_word_length; int loopcnt, i, j; - u16 *pTempFile; u16 tempword; u16 tempbuffer[64]; u16 resultbuffer[64]; @@ -513,8 +511,6 @@ static u32 write_blk (struct ft1000_device *ft1000dev, u16 **pUsFile, u8 **pUcFi word_length--; tempword = (u16)word_length; word_length = (word_length / 16) + 1; - pTempFile = *pUsFile; - temp_word_length = word_length; for (; word_length > 0; word_length--) /* In words */ { loopcnt = 0; -- cgit v1.2.3 From e7af0786303cfb6c541582839275f1d0addbeb2b Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 3 Feb 2011 11:07:53 +0100 Subject: staging: ft1000: Create common function for buffers check. Same check was done on three places which make code unreadable. Put repeat routine to separate function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- .../staging/ft1000/ft1000-usb/ft1000_download.c | 59 +++++++++++----------- 1 file changed, 29 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index b789e7805c42..7c4749ae1ea3 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -470,6 +470,17 @@ static u16 hdr_checksum(struct pseudo_hdr *pHdr) return chksum; } +static int check_buffers(u16 *buff_w, u16 *buff_r, int len, int offset) +{ + int i; + + for (i = 0; i < len; i++) { + if (buff_w[i] != buff_r[i + offset]) + return -1; + } + + return 0; +} //--------------------------------------------------------------------------- // Function: write_blk @@ -560,43 +571,31 @@ static u32 write_blk (struct ft1000_device *ft1000dev, u16 **pUsFile, u8 **pUcFi Status = ft1000_read_dpram32 (ft1000dev, dpram, (u8 *)&resultbuffer[0], 64); if ( (tempbuffer[31] & 0xfe00) == 0xfe00) { - for (i=0; i<28; i++) - { - if (resultbuffer[i] != tempbuffer[i]) - { - //NdisMSleep (100); - DEBUG("FT1000:download:DPRAM write failed 1 during bootloading\n"); - msleep(10); - Status = STATUS_FAILURE; - break; + if (check_buffers(tempbuffer, resultbuffer, 28, 0)) { + DEBUG("FT1000:download:DPRAM write failed 1 during bootloading\n"); + msleep(10); + Status = STATUS_FAILURE; + break; } - } Status = ft1000_read_dpram32 (ft1000dev, dpram+12, (u8 *)&resultbuffer[0], 64); - for (i=0; i<16; i++) - { - if (resultbuffer[i] != tempbuffer[i+24]) - { - //NdisMSleep (100); - DEBUG("FT1000:download:DPRAM write failed 2 during bootloading\n"); - msleep(10); - Status = STATUS_FAILURE; - break; + + if (check_buffers(tempbuffer, resultbuffer, 16, 24)) { + DEBUG("FT1000:download:DPRAM write failed 2 during bootloading\n"); + msleep(10); + Status = STATUS_FAILURE; + break; } - } + } else { - for (i=0; i<32; i++) - { - if (resultbuffer[i] != tempbuffer[i]) - { - //NdisMSleep (100); - DEBUG("FT1000:download:DPRAM write failed 3 during bootloading\n"); - msleep(10); - Status = STATUS_FAILURE; - break; + if (check_buffers(tempbuffer, resultbuffer, 32, 0)) { + DEBUG("FT1000:download:DPRAM write failed 3 during bootloading\n"); + msleep(10); + Status = STATUS_FAILURE; + break; } - } + } if (Status == STATUS_SUCCESS) -- cgit v1.2.3 From dfc9539fe88fe548184563d77f1816782289ac1e Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 3 Feb 2011 11:07:54 +0100 Subject: staging: ft1000: Remove unnecessary assignment. dsp_img_info->version and requested_version have same type so additional temporary variable creation could be omitted because variables could be compares directly. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_download.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 7c4749ae1ea3..1797c4da91df 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -1072,16 +1072,8 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, image < file_hdr->nDspImages; image++) { - temp = - (u16) (dsp_img_info-> - version); - templong = temp; - temp = - (u16) (dsp_img_info-> - version >> 16); - templong |= (temp << 16); - if (templong == - (u32) requested_version) { + if (dsp_img_info->version == + requested_version) { correct_version = TRUE; DEBUG ("FT1000:download: correct_version is TRUE\n"); -- cgit v1.2.3 From 3c1fb66ede917d54079a959a95f79777e95920bd Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 3 Feb 2011 13:42:37 +0200 Subject: staging/easycap: don't cast NULL pointer Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_ioctl.c | 26 +++---- drivers/staging/easycap/easycap_low.c | 2 +- drivers/staging/easycap/easycap_main.c | 116 ++++++++++++++-------------- drivers/staging/easycap/easycap_sound.c | 20 ++--- drivers/staging/easycap/easycap_sound_oss.c | 8 +- 5 files changed, 86 insertions(+), 86 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 222192457364..9671ff193acd 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -52,7 +52,7 @@ if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } -if ((struct usb_device *)NULL == peasycap->pusb_device) { +if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -359,7 +359,7 @@ if (0 > peasycap->standard_offset) { return -EBUSY; } p = peasycap->pusb_device; -if ((struct usb_device *)NULL == p) { +if (NULL == p) { SAM("ERROR: peaycap->pusb_device is NULL\n"); return -EFAULT; } @@ -421,7 +421,7 @@ if (V4L2_FIELD_ANY == field) { field = V4L2_FIELD_NONE; SAM("prefer: V4L2_FIELD_NONE=field, was V4L2_FIELD_ANY\n"); } -peasycap_best_format = (struct easycap_format *)NULL; +peasycap_best_format = NULL; peasycap_format = &easycap_format[0]; while (0 != peasycap_format->v4l2_format.fmt.pix.width) { JOM(16, ".> %i %i 0x%08X %ix%i\n", @@ -472,7 +472,7 @@ if (0 == peasycap_format->v4l2_format.fmt.pix.width) { return peasycap->format_offset; } } -if ((struct easycap_format *)NULL == peasycap_best_format) { +if (NULL == peasycap_best_format) { SAM("MISTAKE: peasycap_best_format is NULL"); return -EINVAL; } @@ -628,7 +628,7 @@ if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } -if ((struct usb_device *)NULL == peasycap->pusb_device) { +if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -686,7 +686,7 @@ if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } -if ((struct usb_device *)NULL == peasycap->pusb_device) { +if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -746,7 +746,7 @@ if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } -if ((struct usb_device *)NULL == peasycap->pusb_device) { +if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -806,7 +806,7 @@ if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } -if ((struct usb_device *)NULL == peasycap->pusb_device) { +if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -862,7 +862,7 @@ if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } -if ((struct usb_device *)NULL == peasycap->pusb_device) { +if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -919,7 +919,7 @@ if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } -if ((struct usb_device *)NULL == peasycap->pusb_device) { +if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -955,7 +955,7 @@ return -ENOENT; (defined(EASYCAP_NEEDS_UNLOCKED_IOCTL))) long easycap_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) { - return (long)easycap_ioctl((struct inode *)NULL, file, cmd, arg); + return (long)easycap_ioctl(NULL, file, cmd, arg); } #endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ @@ -2368,7 +2368,7 @@ case VIDIOC_STREAMON: { peasycap->isequence = 0; for (i = 0; i < 180; i++) peasycap->merit[i] = 0; - if ((struct usb_device *)NULL == peasycap->pusb_device) { + if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -2384,7 +2384,7 @@ case VIDIOC_STREAMON: { case VIDIOC_STREAMOFF: { JOM(8, "VIDIOC_STREAMOFF\n"); - if ((struct usb_device *)NULL == peasycap->pusb_device) { + if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index 6ab335a1e6d6..48e3cb4a7197 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -925,7 +925,7 @@ rc0 = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), (__u8)(USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE), (__u16)value, (__u16)index, - (void *)NULL, + NULL, (__u16)0, (int)500); diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index d1d7a4831571..4944fcb6d1d6 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -144,10 +144,10 @@ int rc; JOT(4, "\n"); SAY("==========OPEN=========\n"); -peasycap = (struct easycap *)NULL; +peasycap = NULL; /*---------------------------------------------------------------------------*/ #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) -if ((struct inode *)NULL == inode) { +if (NULL == inode) { SAY("ERROR: inode is NULL.\n"); return -EFAULT; } @@ -160,7 +160,7 @@ peasycap = usb_get_intfdata(pusb_interface); /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #else pvideo_device = video_devdata(file); -if ((struct video_device *)NULL == pvideo_device) { +if (NULL == pvideo_device) { SAY("ERROR: pvideo_device is NULL.\n"); return -EFAULT; } @@ -698,7 +698,7 @@ if (NULL == peasycap) { return -EFAULT; } if (peasycap->video_isoc_streaming) { - if ((struct list_head *)NULL != peasycap->purb_video_head) { + if (NULL != peasycap->purb_video_head) { peasycap->video_isoc_streaming = 0; JOM(4, "killing video urbs\n"); m = 0; @@ -828,7 +828,7 @@ kd = isdongle(peasycap); * FREE VIDEO. */ /*---------------------------------------------------------------------------*/ -if ((struct list_head *)NULL != peasycap->purb_video_head) { +if (NULL != peasycap->purb_video_head) { JOM(4, "freeing video urbs\n"); m = 0; list_for_each(plist_head, (peasycap->purb_video_head)) { @@ -836,9 +836,9 @@ if ((struct list_head *)NULL != peasycap->purb_video_head) { if (NULL == pdata_urb) JOM(4, "ERROR: pdata_urb is NULL\n"); else { - if ((struct urb *)NULL != pdata_urb->purb) { + if (NULL != pdata_urb->purb) { usb_free_urb(pdata_urb->purb); - pdata_urb->purb = (struct urb *)NULL; + pdata_urb->purb = NULL; peasycap->allocation_video_urb -= 1; m++; } @@ -851,8 +851,8 @@ if ((struct list_head *)NULL != peasycap->purb_video_head) { m = 0; list_for_each_safe(plist_head, plist_next, peasycap->purb_video_head) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if ((struct data_urb *)NULL != pdata_urb) { - kfree(pdata_urb); pdata_urb = (struct data_urb *)NULL; + if (NULL != pdata_urb) { + kfree(pdata_urb); pdata_urb = NULL; peasycap->allocation_video_struct -= sizeof(struct data_urb); m++; @@ -860,17 +860,17 @@ if ((struct list_head *)NULL != peasycap->purb_video_head) { } JOM(4, "%i video data_urb structures freed\n", m); JOM(4, "setting peasycap->purb_video_head=NULL\n"); - peasycap->purb_video_head = (struct list_head *)NULL; + peasycap->purb_video_head = NULL; } /*---------------------------------------------------------------------------*/ JOM(4, "freeing video isoc buffers.\n"); m = 0; for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { - if ((void *)NULL != peasycap->video_isoc_buffer[k].pgo) { + if (NULL != peasycap->video_isoc_buffer[k].pgo) { free_pages((unsigned long) (peasycap->video_isoc_buffer[k].pgo), VIDEO_ISOC_ORDER); - peasycap->video_isoc_buffer[k].pgo = (void *)NULL; + peasycap->video_isoc_buffer[k].pgo = NULL; peasycap->allocation_video_page -= ((unsigned int)(0x01 << VIDEO_ISOC_ORDER)); m++; @@ -882,10 +882,10 @@ JOM(4, "freeing video field buffers.\n"); gone = 0; for (k = 0; k < FIELD_BUFFER_MANY; k++) { for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { - if ((void *)NULL != peasycap->field_buffer[k][m].pgo) { + if (NULL != peasycap->field_buffer[k][m].pgo) { free_page((unsigned long) (peasycap->field_buffer[k][m].pgo)); - peasycap->field_buffer[k][m].pgo = (void *)NULL; + peasycap->field_buffer[k][m].pgo = NULL; peasycap->allocation_video_page -= 1; gone++; } @@ -897,10 +897,10 @@ JOM(4, "freeing video frame buffers.\n"); gone = 0; for (k = 0; k < FRAME_BUFFER_MANY; k++) { for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { - if ((void *)NULL != peasycap->frame_buffer[k][m].pgo) { + if (NULL != peasycap->frame_buffer[k][m].pgo) { free_page((unsigned long) (peasycap->frame_buffer[k][m].pgo)); - peasycap->frame_buffer[k][m].pgo = (void *)NULL; + peasycap->frame_buffer[k][m].pgo = NULL; peasycap->allocation_video_page -= 1; gone++; } @@ -912,7 +912,7 @@ JOM(4, "video frame buffers freed: %i pages\n", gone); * FREE AUDIO. */ /*---------------------------------------------------------------------------*/ -if ((struct list_head *)NULL != peasycap->purb_audio_head) { +if (NULL != peasycap->purb_audio_head) { JOM(4, "freeing audio urbs\n"); m = 0; list_for_each(plist_head, (peasycap->purb_audio_head)) { @@ -920,9 +920,9 @@ if ((struct list_head *)NULL != peasycap->purb_audio_head) { if (NULL == pdata_urb) JOM(4, "ERROR: pdata_urb is NULL\n"); else { - if ((struct urb *)NULL != pdata_urb->purb) { + if (NULL != pdata_urb->purb) { usb_free_urb(pdata_urb->purb); - pdata_urb->purb = (struct urb *)NULL; + pdata_urb->purb = NULL; peasycap->allocation_audio_urb -= 1; m++; } @@ -934,8 +934,8 @@ if ((struct list_head *)NULL != peasycap->purb_audio_head) { m = 0; list_for_each_safe(plist_head, plist_next, peasycap->purb_audio_head) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if ((struct data_urb *)NULL != pdata_urb) { - kfree(pdata_urb); pdata_urb = (struct data_urb *)NULL; + if (NULL != pdata_urb) { + kfree(pdata_urb); pdata_urb = NULL; peasycap->allocation_audio_struct -= sizeof(struct data_urb); m++; @@ -943,17 +943,17 @@ if ((struct list_head *)NULL != peasycap->purb_audio_head) { } JOM(4, "%i audio data_urb structures freed\n", m); JOM(4, "setting peasycap->purb_audio_head=NULL\n"); -peasycap->purb_audio_head = (struct list_head *)NULL; +peasycap->purb_audio_head = NULL; } /*---------------------------------------------------------------------------*/ JOM(4, "freeing audio isoc buffers.\n"); m = 0; for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { - if ((void *)NULL != peasycap->audio_isoc_buffer[k].pgo) { + if (NULL != peasycap->audio_isoc_buffer[k].pgo) { free_pages((unsigned long) (peasycap->audio_isoc_buffer[k].pgo), AUDIO_ISOC_ORDER); - peasycap->audio_isoc_buffer[k].pgo = (void *)NULL; + peasycap->audio_isoc_buffer[k].pgo = NULL; peasycap->allocation_audio_page -= ((unsigned int)(0x01 << AUDIO_ISOC_ORDER)); m++; @@ -966,9 +966,9 @@ JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n", JOM(4, "freeing audio buffers.\n"); gone = 0; for (k = 0; k < peasycap->audio_buffer_page_many; k++) { - if ((void *)NULL != peasycap->audio_buffer[k].pgo) { + if (NULL != peasycap->audio_buffer[k].pgo) { free_page((unsigned long)(peasycap->audio_buffer[k].pgo)); - peasycap->audio_buffer[k].pgo = (void *)NULL; + peasycap->audio_buffer[k].pgo = NULL; peasycap->allocation_audio_page -= 1; gone++; } @@ -993,7 +993,7 @@ if (0 <= kd && DONGLE_MANY > kd) { SAY("ERROR: cannot down mutex_dongle\n"); } else { JOM(4, "locked mutex_dongle\n"); - easycapdc60_dongle[kd].peasycap = (struct easycap *)NULL; + easycapdc60_dongle[kd].peasycap = NULL; mutex_unlock(&mutex_dongle); JOM(4, "unlocked mutex_dongle\n"); JOT(4, " null-->easycapdc60_dongle[%i].peasycap\n", kd); @@ -1025,7 +1025,7 @@ JOT(8, "\n"); if (NULL == ((poll_table *)wait)) JOT(8, "WARNING: poll table pointer is NULL ... continuing\n"); -if ((struct file *)NULL == file) { +if (NULL == file) { SAY("ERROR: file pointer is NULL\n"); return -ERESTARTSYS; } @@ -2650,8 +2650,8 @@ struct page *page; struct easycap *peasycap; retcode = VM_FAULT_NOPAGE; -pbuf = (void *)NULL; -page = (struct page *)NULL; +pbuf = NULL; +page = NULL; if (NULL == pvma) { SAY("pvma is NULL\n"); @@ -3197,11 +3197,11 @@ struct v4l2_device *pv4l2_device; /* setup modules params */ -if ((struct usb_interface *)NULL == pusb_interface) { +if (NULL == pusb_interface) { SAY("ERROR: pusb_interface is NULL\n"); return -EFAULT; } -peasycap = (struct easycap *)NULL; +peasycap = NULL; /*---------------------------------------------------------------------------*/ /* * GET POINTER TO STRUCTURE usb_device @@ -3209,12 +3209,12 @@ peasycap = (struct easycap *)NULL; /*---------------------------------------------------------------------------*/ pusb_device1 = container_of(pusb_interface->dev.parent, struct usb_device, dev); -if ((struct usb_device *)NULL == pusb_device1) { +if (NULL == pusb_device1) { SAY("ERROR: pusb_device1 is NULL\n"); return -EFAULT; } pusb_device = usb_get_dev(pusb_device1); -if ((struct usb_device *)NULL == pusb_device) { +if (NULL == pusb_device) { SAY("ERROR: pusb_device is NULL\n"); return -EFAULT; } @@ -3582,7 +3582,7 @@ if (0 == bInterfaceNumber) { /*---------------------------------------------------------------------------*/ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { pv4l2_device = usb_get_intfdata(pusb_interface); - if ((struct v4l2_device *)NULL == pv4l2_device) { + if (NULL == pv4l2_device) { SAY("ERROR: pv4l2_device is NULL\n"); return -ENODEV; } @@ -3634,12 +3634,12 @@ isokalt = 0; for (i = 0; i < pusb_interface->num_altsetting; i++) { pusb_host_interface = &(pusb_interface->altsetting[i]); - if ((struct usb_host_interface *)NULL == pusb_host_interface) { + if (NULL == pusb_host_interface) { SAM("ERROR: pusb_host_interface is NULL\n"); return -EFAULT; } pusb_interface_descriptor = &(pusb_host_interface->desc); - if ((struct usb_interface_descriptor *)NULL == + if (NULL == pusb_interface_descriptor) { SAM("ERROR: pusb_interface_descriptor is NULL\n"); return -EFAULT; @@ -3675,7 +3675,7 @@ for (i = 0; i < pusb_interface->num_altsetting; i++) { /*---------------------------------------------------------------------------*/ for (j = 0; j < pusb_interface_descriptor->bNumEndpoints; j++) { pepd = &(pusb_host_interface->endpoint[j].desc); - if ((struct usb_endpoint_descriptor *)NULL == pepd) { + if (NULL == pepd) { SAM("ERROR: pepd is NULL.\n"); SAM("...... skipping\n"); continue; @@ -3957,12 +3957,12 @@ case 0: { for (k = 0; k < FRAME_BUFFER_MANY; k++) { for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { - if ((void *)NULL != peasycap->frame_buffer[k][m].pgo) + if (NULL != peasycap->frame_buffer[k][m].pgo) SAM("attempting to reallocate frame " " buffers\n"); else { pbuf = (void *)__get_free_page(GFP_KERNEL); - if ((void *)NULL == pbuf) { + if (NULL == pbuf) { SAM("ERROR: Could not allocate frame " "buffer %i page %i\n", k, m); return -ENOMEM; @@ -3987,12 +3987,12 @@ case 0: { for (k = 0; k < FIELD_BUFFER_MANY; k++) { for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { - if ((void *)NULL != peasycap->field_buffer[k][m].pgo) { + if (NULL != peasycap->field_buffer[k][m].pgo) { SAM("ERROR: attempting to reallocate " "field buffers\n"); } else { pbuf = (void *) __get_free_page(GFP_KERNEL); - if ((void *)NULL == pbuf) { + if (NULL == pbuf) { SAM("ERROR: Could not allocate field" " buffer %i page %i\n", k, m); return -ENOMEM; @@ -4183,7 +4183,7 @@ case 0: { * THIS IS BELIEVED TO BE HARMLESS, BUT MAY WELL BE UNNECESSARY OR WRONG: */ /*---------------------------------------------------------------------------*/ - peasycap->video_device.v4l2_dev = (struct v4l2_device *)NULL; + peasycap->video_device.v4l2_dev = NULL; /*---------------------------------------------------------------------------*/ #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ @@ -4356,11 +4356,11 @@ case 2: { peasycap->audio_buffer_page_many); for (k = 0; k < peasycap->audio_buffer_page_many; k++) { - if ((void *)NULL != peasycap->audio_buffer[k].pgo) { + if (NULL != peasycap->audio_buffer[k].pgo) { SAM("ERROR: attempting to reallocate audio buffers\n"); } else { pbuf = (void *) __get_free_page(GFP_KERNEL); - if ((void *)NULL == pbuf) { + if (NULL == pbuf) { SAM("ERROR: Could not allocate audio " "buffer page %i\n", k); return -ENOMEM; @@ -4583,17 +4583,17 @@ struct v4l2_device *pv4l2_device; JOT(4, "\n"); -if ((struct usb_interface *)NULL == pusb_interface) { +if (NULL == pusb_interface) { JOT(4, "ERROR: pusb_interface is NULL\n"); return; } pusb_host_interface = pusb_interface->cur_altsetting; -if ((struct usb_host_interface *)NULL == pusb_host_interface) { +if (NULL == pusb_host_interface) { JOT(4, "ERROR: pusb_host_interface is NULL\n"); return; } pusb_interface_descriptor = &(pusb_host_interface->desc); -if ((struct usb_interface_descriptor *)NULL == pusb_interface_descriptor) { +if (NULL == pusb_interface_descriptor) { JOT(4, "ERROR: pusb_interface_descriptor is NULL\n"); return; } @@ -4625,7 +4625,7 @@ if (NULL == peasycap) { /*---------------------------------------------------------------------------*/ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { pv4l2_device = usb_get_intfdata(pusb_interface); - if ((struct v4l2_device *)NULL == pv4l2_device) { + if (NULL == pv4l2_device) { SAY("ERROR: pv4l2_device is NULL\n"); return; } @@ -4653,15 +4653,15 @@ wake_up_interruptible(&(peasycap->wq_audio)); /*---------------------------------------------------------------------------*/ switch (bInterfaceNumber) { case 0: { - if ((struct list_head *)NULL != peasycap->purb_video_head) { + if (NULL != peasycap->purb_video_head) { JOM(4, "killing video urbs\n"); m = 0; list_for_each(plist_head, (peasycap->purb_video_head)) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if ((struct data_urb *)NULL != pdata_urb) { - if ((struct urb *)NULL != + if (NULL != pdata_urb) { + if (NULL != pdata_urb->purb) { usb_kill_urb(pdata_urb->purb); m++; @@ -4674,15 +4674,15 @@ case 0: { } /*---------------------------------------------------------------------------*/ case 2: { - if ((struct list_head *)NULL != peasycap->purb_audio_head) { + if (NULL != peasycap->purb_audio_head) { JOM(4, "killing audio urbs\n"); m = 0; list_for_each(plist_head, (peasycap->purb_audio_head)) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if ((struct data_urb *)NULL != pdata_urb) { - if ((struct urb *)NULL != + if (NULL != pdata_urb) { + if (NULL != pdata_urb->purb) { usb_kill_urb(pdata_urb->purb); m++; @@ -4724,7 +4724,7 @@ case 0: { SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); /*---------------------------------------------------------------------------*/ #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) - if ((struct easycap *)NULL == peasycap) { + if (NULL == peasycap) { SAM("ERROR: peasycap has become NULL\n"); } else { usb_deregister_dev(pusb_interface, &easycap_class); @@ -4781,7 +4781,7 @@ case 2: { if (0 != snd_card_free(peasycap->psnd_card)) { SAY("ERROR: snd_card_free() failed\n"); } else { - peasycap->psnd_card = (struct snd_card *)NULL; + peasycap->psnd_card = NULL; (peasycap->registered_audio)--; } @@ -4879,7 +4879,7 @@ static int __init easycap_module_init(void) mutex_init(&mutex_dongle); for (k = 0; k < DONGLE_MANY; k++) { - easycapdc60_dongle[k].peasycap = (struct easycap *)NULL; + easycapdc60_dongle[k].peasycap = NULL; mutex_init(&easycapdc60_dongle[k].mutex_video); mutex_init(&easycapdc60_dongle[k].mutex_audio); } diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index 4d25c97a3b2d..2b4ef4eba0c5 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -370,7 +370,7 @@ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { return -EFAULT; } pss->private_data = NULL; -peasycap->psubstream = (struct snd_pcm_substream *)NULL; +peasycap->psubstream = NULL; JOT(4, "ending successfully\n"); return 0; } @@ -647,7 +647,7 @@ if (true == peasycap->microphone) { strcpy(&psnd_pcm->name[0], &psnd_card->id[0]); psnd_pcm->private_data = peasycap; peasycap->psnd_pcm = psnd_pcm; - peasycap->psubstream = (struct snd_pcm_substream *)NULL; + peasycap->psubstream = NULL; rc = snd_card_register(psnd_card); if (0 != rc) { @@ -684,7 +684,7 @@ if (NULL == peasycap) { SAY("ERROR: peasycap is NULL.\n"); return -EFAULT; } -if ((struct usb_device *)NULL == peasycap->pusb_device) { +if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -ENODEV; } @@ -693,12 +693,12 @@ JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device); rc = audio_setup(peasycap); JOM(8, "audio_setup() returned %i\n", rc); -if ((struct usb_device *)NULL == peasycap->pusb_device) { +if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device has become NULL\n"); return -ENODEV; } /*---------------------------------------------------------------------------*/ -if ((struct usb_device *)NULL == peasycap->pusb_device) { +if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device has become NULL\n"); return -ENODEV; } @@ -740,11 +740,11 @@ if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } -if ((struct list_head *)NULL == peasycap->purb_audio_head) { +if (NULL == peasycap->purb_audio_head) { SAM("ERROR: peasycap->urb_audio_head uninitialized\n"); return -EFAULT; } -if ((struct usb_device *)NULL == peasycap->pusb_device) { +if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -855,15 +855,15 @@ if (NULL == peasycap) { return -EFAULT; } if (peasycap->audio_isoc_streaming) { - if ((struct list_head *)NULL != peasycap->purb_audio_head) { + if (NULL != peasycap->purb_audio_head) { peasycap->audio_isoc_streaming = 0; JOM(4, "killing audio urbs\n"); m = 0; list_for_each(plist_head, (peasycap->purb_audio_head)) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if ((struct data_urb *)NULL != pdata_urb) { - if ((struct urb *)NULL != pdata_urb->purb) { + if (NULL != pdata_urb) { + if (NULL != pdata_urb->purb) { usb_kill_urb(pdata_urb->purb); m++; } diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c index 028981421710..d40d1a02a2b9 100644 --- a/drivers/staging/easycap/easycap_sound_oss.c +++ b/drivers/staging/easycap/easycap_sound_oss.c @@ -356,7 +356,7 @@ if (NULL == peasycap) { /*---------------------------------------------------------------------------*/ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { pv4l2_device = usb_get_intfdata(pusb_interface); - if ((struct v4l2_device *)NULL == pv4l2_device) { + if (NULL == pv4l2_device) { SAY("ERROR: pv4l2_device is NULL\n"); return -EFAULT; } @@ -510,7 +510,7 @@ if ((0 > peasycap->audio_read) || return -EFAULT; } pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; -if ((struct data_buffer *)NULL == pdata_buffer) { +if (NULL == pdata_buffer) { SAM("ERROR: pdata_buffer is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; @@ -598,7 +598,7 @@ while (fragment == (peasycap->audio_read / return -EFAULT; } pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; - if ((struct data_buffer *)NULL == pdata_buffer) { + if (NULL == pdata_buffer) { SAM("ERROR: pdata_buffer is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; @@ -1006,7 +1006,7 @@ return 0; static long easyoss_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) { - return (long)easyoss_ioctl((struct inode *)NULL, file, cmd, arg); + return (long)easyoss_ioctl(NULL, file, cmd, arg); } #endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/ /*****************************************************************************/ -- cgit v1.2.3 From 9306b1bb8b6de05786c8aa79a19988aa15453968 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 3 Feb 2011 13:42:38 +0200 Subject: staging/easycap: remove comment: EASYCAP_NEEDS_ALSA Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 2479fc21e838..589f0387e75f 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -34,7 +34,6 @@ * EASYCAP_NEEDS_V4L2_DEVICE_H * EASYCAP_NEEDS_V4L2_FOPS * EASYCAP_NEEDS_UNLOCKED_IOCTL - * EASYCAP_NEEDS_ALSA * EASYCAP_SILENT * * IF REQUIRED THEY MUST BE EXTERNALLY DEFINED, FOR EXAMPLE AS COMPILER -- cgit v1.2.3 From f2b3c685b9b1c048cfa8bef98dac037275b9d20d Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 3 Feb 2011 13:42:39 +0200 Subject: staging/easycap: kill EASYCAP_NEEDS_UNLOCKED_IOCTL we can kill this option for in-kernel driver Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/Makefile | 1 - drivers/staging/easycap/easycap.h | 5 +---- drivers/staging/easycap/easycap_ioctl.c | 15 ++------------- drivers/staging/easycap/easycap_main.c | 12 ++---------- drivers/staging/easycap/easycap_sound_oss.c | 17 ++--------------- 5 files changed, 7 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/Makefile b/drivers/staging/easycap/Makefile index a01ca11ec1e4..987ccb184f57 100644 --- a/drivers/staging/easycap/Makefile +++ b/drivers/staging/easycap/Makefile @@ -12,5 +12,4 @@ ccflags-y := -Wall ccflags-y += -DEASYCAP_IS_VIDEODEV_CLIENT ccflags-y += -DEASYCAP_NEEDS_V4L2_DEVICE_H ccflags-y += -DEASYCAP_NEEDS_V4L2_FOPS -ccflags-y += -DEASYCAP_NEEDS_UNLOCKED_IOCTL diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 589f0387e75f..47467d5fdd2c 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -33,7 +33,6 @@ * EASYCAP_NEEDS_USBVIDEO_H * EASYCAP_NEEDS_V4L2_DEVICE_H * EASYCAP_NEEDS_V4L2_FOPS - * EASYCAP_NEEDS_UNLOCKED_IOCTL * EASYCAP_SILENT * * IF REQUIRED THEY MUST BE EXTERNALLY DEFINED, FOR EXAMPLE AS COMPILER @@ -511,9 +510,7 @@ __s16 oldaudio; * VIDEO FUNCTION PROTOTYPES */ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -long easycap_ioctl_noinode(struct file *, unsigned int, unsigned long); -int easycap_ioctl(struct inode *, struct file *, unsigned int, unsigned long); - +long easycap_unlocked_ioctl(struct file *, unsigned int, unsigned long); int easycap_dqbuf(struct easycap *, int); int submit_video_urbs(struct easycap *); int kill_video_urbs(struct easycap *); diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 9671ff193acd..ee581c4f8037 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -949,20 +949,9 @@ while (0xFFFFFFFF != easycap_control[i1].id) { SAM("WARNING: failed to adjust mute: control not found\n"); return -ENOENT; } -/*****************************************************************************/ -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \ - (defined(EASYCAP_NEEDS_UNLOCKED_IOCTL))) -long -easycap_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) { - return (long)easycap_ioctl(NULL, file, cmd, arg); -} -#endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*---------------------------------------------------------------------------*/ -int -easycap_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +long easycap_unlocked_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) { struct easycap *peasycap; struct usb_device *p; diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 4944fcb6d1d6..dce9bd6e47ef 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -3117,11 +3117,7 @@ static const struct file_operations easycap_fops = { .owner = THIS_MODULE, .open = easycap_open, .release = easycap_release, -#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL) - .unlocked_ioctl = easycap_ioctl_noinode, -#else - .ioctl = easycap_ioctl, -#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/ + .unlocked_ioctl = easycap_unlocked_ioctl, .poll = easycap_poll, .mmap = easycap_mmap, .llseek = no_llseek, @@ -3138,11 +3134,7 @@ static const struct v4l2_file_operations v4l2_fops = { .owner = THIS_MODULE, .open = easycap_open_noinode, .release = easycap_release_noinode, -#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL) - .unlocked_ioctl = easycap_ioctl_noinode, -#else - .ioctl = easycap_ioctl, -#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/ + .unlocked_ioctl = easycap_unlocked_ioctl, .poll = easycap_poll, .mmap = easycap_mmap, }; diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c index d40d1a02a2b9..7c98261bbf22 100644 --- a/drivers/staging/easycap/easycap_sound_oss.c +++ b/drivers/staging/easycap/easycap_sound_oss.c @@ -708,7 +708,7 @@ return szret; } /*---------------------------------------------------------------------------*/ -static int easyoss_ioctl(struct inode *inode, struct file *file, +static long easyoss_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct easycap *peasycap; @@ -1000,26 +1000,13 @@ default: { mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return 0; } -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \ - (defined(EASYCAP_NEEDS_UNLOCKED_IOCTL))) -static long easyoss_ioctl_noinode(struct file *file, - unsigned int cmd, unsigned long arg) -{ - return (long)easyoss_ioctl(NULL, file, cmd, arg); -} -#endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/ /*****************************************************************************/ const struct file_operations easyoss_fops = { .owner = THIS_MODULE, .open = easyoss_open, .release = easyoss_release, -#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL) - .unlocked_ioctl = easyoss_ioctl_noinode, -#else - .ioctl = easyoss_ioctl, -#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/ + .unlocked_ioctl = easyoss_unlocked_ioctl, .read = easyoss_read, .llseek = no_llseek, }; -- cgit v1.2.3 From 3fc0dae888ee216036ae1898fc9186f1dd04f185 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 3 Feb 2011 13:42:40 +0200 Subject: staging/easycap: repace #if defined with simpler #ifdef for sake of readability replace #if defined with #ifdef and #if (!defined with #ifndef Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 18 +++++----- drivers/staging/easycap/easycap_ioctl.c | 8 ++--- drivers/staging/easycap/easycap_low.c | 6 ++-- drivers/staging/easycap/easycap_main.c | 53 ++++++++++++++--------------- drivers/staging/easycap/easycap_sound.c | 8 ++--- drivers/staging/easycap/easycap_sound_oss.c | 30 ++++++++-------- drivers/staging/easycap/easycap_testcard.c | 2 +- 7 files changed, 61 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 47467d5fdd2c..1276cbf52fe3 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -90,22 +90,22 @@ #include #endif /* !CONFIG_EASYCAP_OSS */ /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) +#ifdef EASYCAP_IS_VIDEODEV_CLIENT #include -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H #include #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ #include #include -#if defined(EASYCAP_NEEDS_USBVIDEO_H) +#ifdef EASYCAP_NEEDS_USBVIDEO_H #include #endif /*EASYCAP_NEEDS_USBVIDEO_H*/ -#if (!defined(PAGE_SIZE)) +#ifndef PAGE_SIZE #error "PAGE_SIZE not defined" -#endif +#endif /* PAGE_SIZE */ /*---------------------------------------------------------------------------*/ /* VENDOR, PRODUCT: Syntek Semiconductor Co., Ltd @@ -309,9 +309,9 @@ struct easycap { int minor; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) +#ifdef EASYCAP_IS_VIDEODEV_CLIENT struct video_device video_device; -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H struct v4l2_device v4l2_device; #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ @@ -322,8 +322,8 @@ struct easycap { unsigned int audio_buffer_page_many; #define UPSAMPLE -#if defined(UPSAMPLE) -__s16 oldaudio; +#ifdef UPSAMPLE + __s16 oldaudio; #endif /*UPSAMPLE*/ int ilk; diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index ee581c4f8037..4754f2ffc8ef 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -1387,7 +1387,7 @@ case VIDIOC_G_CTRL: { break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -#if defined(VIDIOC_S_CTRL_OLD) +#ifdef VIDIOC_S_CTRL_OLD case VIDIOC_S_CTRL_OLD: { JOM(8, "VIDIOC_S_CTRL_OLD required at least for xawtv\n"); } @@ -2156,7 +2156,7 @@ case VIDIOC_QBUF: { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_DQBUF: { -#if defined(AUDIOTIME) +#ifdef AUDIOTIME struct signed_div_result sdr; long long int above, below, dnbydt, fudge, sll; unsigned long long int ull; @@ -2269,7 +2269,7 @@ case VIDIOC_DQBUF: do_gettimeofday(&timeval); timeval2 = timeval; -#if defined(AUDIOTIME) +#ifdef AUDIOTIME if (!peasycap->timeval0.tv_sec) { timeval8 = timeval; timeval1 = timeval; @@ -2389,7 +2389,7 @@ case VIDIOC_STREAMOFF: { /*---------------------------------------------------------------------------*/ JOM(8, "calling wake_up on wq_video and wq_audio\n"); wake_up_interruptible(&(peasycap->wq_video)); -#if defined(EASYCAP_NEEDS_ALSA) +#ifdef EASYCAP_NEEDS_ALSA if (NULL != peasycap->psubstream) snd_pcm_period_elapsed(peasycap->psubstream); #else diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index 48e3cb4a7197..15eef6a5200d 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -133,7 +133,7 @@ static const struct saa7113config{ int set; } saa7113configPAL[256] = { {0x01, 0x08}, -#if defined(ANTIALIAS) +#ifdef ANTIALIAS {0x02, 0xC0}, #else {0x02, 0x80}, @@ -191,7 +191,7 @@ static const struct saa7113config{ /*--------------------------------------------------------------------------*/ static const struct saa7113config saa7113configNTSC[256] = { {0x01, 0x08}, -#if defined(ANTIALIAS) +#ifdef ANTIALIAS {0x02, 0xC0}, #else {0x02, 0x80}, @@ -929,7 +929,7 @@ rc0 = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), (__u16)0, (int)500); -#if defined(NOREADBACK) +#ifdef NOREADBACK # #else rc1 = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index dce9bd6e47ef..fcfa11d8dd5c 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -133,7 +133,7 @@ return -1; /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ static int easycap_open(struct inode *inode, struct file *file) { -#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) +#ifndef EASYCAP_IS_VIDEODEV_CLIENT struct usb_interface *pusb_interface; #else struct video_device *pvideo_device; @@ -146,7 +146,7 @@ SAY("==========OPEN=========\n"); peasycap = NULL; /*---------------------------------------------------------------------------*/ -#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) +#ifndef EASYCAP_IS_VIDEODEV_CLIENT if (NULL == inode) { SAY("ERROR: inode is NULL.\n"); return -EFAULT; @@ -728,7 +728,7 @@ return 0; /*--------------------------------------------------------------------------*/ static int easycap_release(struct inode *inode, struct file *file) { -#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) +#ifndef EASYCAP_IS_VIDEODEV_CLIENT struct easycap *peasycap; JOT(4, "\n"); @@ -756,7 +756,7 @@ JOM(4, "ending successfully\n"); return 0; } -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) +#ifdef EASYCAP_IS_VIDEODEV_CLIENT static int easycap_open_noinode(struct file *file) { return easycap_open(NULL, file); @@ -1375,7 +1375,7 @@ if (peasycap->field_read == peasycap->field_fill) { peasycap->field_read); return 0; } -#if defined(EASYCAP_TESTCARD) +#ifdef EASYCAP_TESTCARD easycap_testcard(peasycap, peasycap->field_read); #else if (0 <= input && INPUT_MANY > input) { @@ -3128,8 +3128,8 @@ static const struct usb_class_driver easycap_class = { .minor_base = USB_SKEL_MINOR_BASE, }; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) -#if defined(EASYCAP_NEEDS_V4L2_FOPS) +#ifdef EASYCAP_IS_VIDEODEV_CLIENT +#ifdef EASYCAP_NEEDS_V4L2_FOPS static const struct v4l2_file_operations v4l2_fops = { .owner = THIS_MODULE, .open = easycap_open_noinode, @@ -3180,8 +3180,8 @@ __u16 mask; __s32 value; struct easycap_format *peasycap_format; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +#ifdef EASYCAP_IS_VIDEODEV_CLIENT +#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H struct v4l2_device *pv4l2_device; #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ @@ -3303,10 +3303,10 @@ if (0 == bInterfaceNumber) { } SAM("allocated 0x%08lX=peasycap\n", (unsigned long int) peasycap); /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) +#ifdef EASYCAP_IS_VIDEODEV_CLIENT SAM("where 0x%08lX=&peasycap->video_device\n", (unsigned long int) &peasycap->video_device); -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H SAM("and 0x%08lX=&peasycap->v4l2_device\n", (unsigned long int) &peasycap->v4l2_device); #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ @@ -3559,11 +3559,11 @@ if (0 == bInterfaceNumber) { bInterfaceNumber); return -ENODEV; } -#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) +#ifndef EASYCAP_IS_VIDEODEV_CLIENT # /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #else -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H /*---------------------------------------------------------------------------*/ /* * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS @@ -4128,7 +4128,7 @@ case 0: { * BEWARE. */ /*---------------------------------------------------------------------------*/ -#if defined(PREFER_NTSC) +#ifdef PREFER_NTSC peasycap->ntsc = true; JOM(8, "defaulting initially to NTSC\n"); #else @@ -4145,7 +4145,7 @@ case 0: { * THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY. */ /*--------------------------------------------------------------------------*/ -#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) +#ifndef EASYCAP_IS_VIDEODEV_CLIENT if (0 != (usb_register_dev(pusb_interface, &easycap_class))) { err("Not able to get a minor for this device"); usb_set_intfdata(pusb_interface, NULL); @@ -4158,7 +4158,7 @@ case 0: { } /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #else -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H if (0 != (v4l2_device_register(&(pusb_interface->dev), &(peasycap->v4l2_device)))) { SAM("v4l2_device_register() failed\n"); @@ -4181,7 +4181,7 @@ case 0: { #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ strcpy(&peasycap->video_device.name[0], "easycapdc60"); -#if defined(EASYCAP_NEEDS_V4L2_FOPS) +#ifdef EASYCAP_NEEDS_V4L2_FOPS peasycap->video_device.fops = &v4l2_fops; #else peasycap->video_device.fops = &easycap_fops; @@ -4214,7 +4214,7 @@ case 0: { */ /*--------------------------------------------------------------------------*/ case 1: { -#if defined(EASYCAP_SILENT) +#ifdef EASYCAP_SILENT return -ENOENT; #endif /*EASYCAP_SILENT*/ if (!peasycap) { @@ -4233,7 +4233,7 @@ case 1: { } /*--------------------------------------------------------------------------*/ case 2: { -#if defined(EASYCAP_SILENT) +#ifdef EASYCAP_SILENT return -ENOENT; #endif /*EASYCAP_SILENT*/ if (!peasycap) { @@ -4566,8 +4566,8 @@ struct list_head *plist_head; struct data_urb *pdata_urb; int minor, m, kd; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +#ifdef EASYCAP_IS_VIDEODEV_CLIENT +#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H struct v4l2_device *pv4l2_device; #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ @@ -4602,11 +4602,8 @@ if (NULL == peasycap) { return; } /*---------------------------------------------------------------------------*/ -#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) -# -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#else -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +#ifdef EASYCAP_IS_VIDEODEV_CLIENT +#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H /*---------------------------------------------------------------------------*/ /* * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS @@ -4715,7 +4712,7 @@ case 0: { } else SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); /*---------------------------------------------------------------------------*/ -#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) +#ifndef EASYCAP_IS_VIDEODEV_CLIENT if (NULL == peasycap) { SAM("ERROR: peasycap has become NULL\n"); } else { @@ -4726,7 +4723,7 @@ case 0: { } /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #else -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H if (!peasycap->v4l2_device.name[0]) { SAM("ERROR: peasycap->v4l2_device.name is empty\n"); if (0 <= kd && DONGLE_MANY > kd) diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index 2b4ef4eba0c5..7c07dbc1edc3 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -75,7 +75,7 @@ int isfragment; __u8 *p1, *p2; __s16 s16; int i, j, more, much, rc; -#if defined(UPSAMPLE) +#ifdef UPSAMPLE int k; __s16 oldaudio, newaudio, delta; #endif /*UPSAMPLE*/ @@ -131,7 +131,7 @@ if (purb->status) { */ /*---------------------------------------------------------------------------*/ -#if defined(UPSAMPLE) +#ifdef UPSAMPLE oldaudio = peasycap->oldaudio; #endif /*UPSAMPLE*/ @@ -185,7 +185,7 @@ for (i = 0; i < purb->number_of_packets; i++) { p1 += much; more -= much; } else { -#if defined(UPSAMPLE) +#ifdef UPSAMPLE if (much % 16) JOM(8, "MISTAKE? much" " is not divisible by 16\n"); @@ -271,7 +271,7 @@ for (i = 0; i < purb->number_of_packets; i++) { purb->iso_frame_desc[i].status); } -#if defined(UPSAMPLE) +#ifdef UPSAMPLE peasycap->oldaudio = oldaudio; #endif /*UPSAMPLE*/ diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c index 7c98261bbf22..adf803199cc6 100644 --- a/drivers/staging/easycap/easycap_sound_oss.c +++ b/drivers/staging/easycap/easycap_sound_oss.c @@ -56,7 +56,7 @@ struct data_buffer *paudio_buffer; __u8 *p1, *p2; __s16 s16; int i, j, more, much, leap, rc; -#if defined(UPSAMPLE) +#ifdef UPSAMPLE int k; __s16 oldaudio, newaudio, delta; #endif /*UPSAMPLE*/ @@ -108,7 +108,7 @@ if (purb->status) { * PROCEED HERE WHEN NO ERROR */ /*---------------------------------------------------------------------------*/ -#if defined(UPSAMPLE) +#ifdef UPSAMPLE oldaudio = peasycap->oldaudio; #endif /*UPSAMPLE*/ @@ -119,7 +119,7 @@ for (i = 0; i < purb->number_of_packets; i++) { more = purb->iso_frame_desc[i].actual_length; -#if defined(TESTTONE) +#ifdef TESTTONE if (!more) more = purb->iso_frame_desc[i].length; #endif @@ -167,7 +167,7 @@ for (i = 0; i < purb->number_of_packets; i++) { if (PAGE_SIZE == (paudio_buffer->pto - paudio_buffer->pgo)) { -#if defined(TESTTONE) +#ifdef TESTTONE easyoss_testtone(peasycap, peasycap->audio_fill); #endif /*TESTTONE*/ @@ -218,7 +218,7 @@ for (i = 0; i < purb->number_of_packets; i++) { p1 += much; more -= much; } else { -#if defined(UPSAMPLE) +#ifdef UPSAMPLE if (much % 16) JOM(8, "MISTAKE? much" " is not divisible by 16\n"); @@ -279,7 +279,7 @@ for (i = 0; i < purb->number_of_packets; i++) { purb->iso_frame_desc[i].status); } -#if defined(UPSAMPLE) +#ifdef UPSAMPLE peasycap->oldaudio = oldaudio; #endif /*UPSAMPLE*/ @@ -317,8 +317,8 @@ struct usb_interface *pusb_interface; struct easycap *peasycap; int subminor; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +#ifdef EASYCAP_IS_VIDEODEV_CLIENT +#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H struct v4l2_device *pv4l2_device; #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ @@ -341,11 +341,11 @@ if (NULL == peasycap) { return -1; } /*---------------------------------------------------------------------------*/ -#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) +#ifndef EASYCAP_IS_VIDEODEV_CLIENT # /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #else -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H /*---------------------------------------------------------------------------*/ /* * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS @@ -787,7 +787,7 @@ case SNDCTL_DSP_GETCAPS: { int caps; JOM(8, "SNDCTL_DSP_GETCAPS\n"); -#if defined(UPSAMPLE) +#ifdef UPSAMPLE if (true == peasycap->microphone) caps = 0x04400000; else @@ -809,7 +809,7 @@ case SNDCTL_DSP_GETFMTS: { int incoming; JOM(8, "SNDCTL_DSP_GETFMTS\n"); -#if defined(UPSAMPLE) +#ifdef UPSAMPLE if (true == peasycap->microphone) incoming = AFMT_S16_LE; else @@ -836,7 +836,7 @@ case SNDCTL_DSP_SETFMT: { } JOM(8, "........... %i=incoming\n", incoming); -#if defined(UPSAMPLE) +#ifdef UPSAMPLE if (true == peasycap->microphone) outgoing = AFMT_S16_LE; else @@ -871,7 +871,7 @@ case SNDCTL_DSP_STEREO: { } JOM(8, "........... %i=incoming\n", incoming); -#if defined(UPSAMPLE) +#ifdef UPSAMPLE if (true == peasycap->microphone) incoming = 1; else @@ -898,7 +898,7 @@ case SNDCTL_DSP_SPEED: { } JOM(8, "........... %i=incoming\n", incoming); -#if defined(UPSAMPLE) +#ifdef UPSAMPLE if (true == peasycap->microphone) incoming = 32000; else diff --git a/drivers/staging/easycap/easycap_testcard.c b/drivers/staging/easycap/easycap_testcard.c index 0f8336b6510f..9f21fc8c1390 100644 --- a/drivers/staging/easycap/easycap_testcard.c +++ b/drivers/staging/easycap/easycap_testcard.c @@ -151,7 +151,7 @@ for (line = 0; line < (barheight / 2); line++) { return; } /*****************************************************************************/ -#if defined(EASYCAP_TESTTONE) +#ifdef EASYCAP_TESTTONE /*----------------------------------------------------------------------------- THE tones[] ARRAY BELOW IS THE OUTPUT OF THIS PROGRAM, COMPILED gcc -o prog -lm prog.c -- cgit v1.2.3 From e0a691e35236d3600c47839c85f82188260e4169 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 3 Feb 2011 13:42:41 +0200 Subject: staging/easycap: fix artificial line breaks fix style issue: if (NULL != pdata_urb->purb) { created by the patch: 'staging/easycap: don't cast NULL pointer' After dropping the casting there is no longer 80 columns limitation Reported-by: Dan Carpenter Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_main.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index fcfa11d8dd5c..c453633ae9c0 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -316,8 +316,7 @@ if (true == other) { peasycap_standard = &easycap_standard[0]; while (0xFFFF != peasycap_standard->mask) { if (true == ntsc) { - if (NTSC_M == - peasycap_standard->v4l2_standard.index) { + if (NTSC_M == peasycap_standard->v4l2_standard.index) { peasycap->inputset[input].standard_offset = peasycap_standard - &easycap_standard[0]; @@ -3631,8 +3630,7 @@ for (i = 0; i < pusb_interface->num_altsetting; i++) { return -EFAULT; } pusb_interface_descriptor = &(pusb_host_interface->desc); - if (NULL == - pusb_interface_descriptor) { + if (NULL == pusb_interface_descriptor) { SAM("ERROR: pusb_interface_descriptor is NULL\n"); return -EFAULT; } @@ -4650,8 +4648,7 @@ case 0: { pdata_urb = list_entry(plist_head, struct data_urb, list_head); if (NULL != pdata_urb) { - if (NULL != - pdata_urb->purb) { + if (NULL != pdata_urb->purb) { usb_kill_urb(pdata_urb->purb); m++; } @@ -4671,8 +4668,7 @@ case 2: { pdata_urb = list_entry(plist_head, struct data_urb, list_head); if (NULL != pdata_urb) { - if (NULL != - pdata_urb->purb) { + if (NULL != pdata_urb->purb) { usb_kill_urb(pdata_urb->purb); m++; } -- cgit v1.2.3 From 6911e7e4a6bed8ac7989137387f6a33ef65c2b56 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 3 Feb 2011 13:42:42 +0200 Subject: staging/easycap: improve coding style when checking return value use idiom 'if (rc)' for checking return value instead of if (0 != rc) Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_ioctl.c | 10 ++++----- drivers/staging/easycap/easycap_main.c | 32 ++++++++++++++--------------- drivers/staging/easycap/easycap_sound.c | 6 +++--- drivers/staging/easycap/easycap_sound_oss.c | 6 +++--- 4 files changed, 27 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 4754f2ffc8ef..73cb0d4cd068 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -143,7 +143,7 @@ case NTSC_M_JP: { else itwas = (unsigned int)ir; rc = write_saa(peasycap->pusb_device, reg, set); - if (0 != rc) + if (rc) SAM("ERROR: failed to set SAA register " "0x%02X to 0x%02X for JP standard\n", reg, set); else { @@ -163,7 +163,7 @@ case NTSC_M_JP: { else itwas = (unsigned int)ir; rc = write_saa(peasycap->pusb_device, reg, set); - if (0 != rc) + if (rc) SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X " "for JP standard\n", reg, set); else { @@ -241,7 +241,7 @@ else { else set = itwas & ~0x40 ; rc = write_saa(peasycap->pusb_device, reg, set); - if (0 != rc) + if (rc) SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", reg, set); else { @@ -271,7 +271,7 @@ else { else set = itwas & ~0x80 ; rc = write_saa(peasycap->pusb_device, reg, set); - if (0 != rc) + if (rc) SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", reg, set); else { @@ -1050,7 +1050,7 @@ case VIDIOC_QUERYCAP: { *p2++ = 0; if (3 > i) { rc = (int) strict_strtol(p1, 10, &lng); - if (0 != rc) { + if (rc) { SAM("ERROR: %i=strict_strtol(%s,.,,)\n", rc, p1); mutex_unlock(&easycapdc60_dongle[kd]. diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index c453633ae9c0..21d155a9e28e 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -196,7 +196,7 @@ else { } peasycap->input = 0; rc = reset(peasycap); -if (0 != rc) { +if (rc) { SAM("ERROR: reset() returned %i\n", rc); return -EFAULT; } @@ -452,12 +452,12 @@ if (NULL == peasycap->pusb_device) { rc = usb_set_interface(peasycap->pusb_device, peasycap->video_interface, peasycap->video_altsetting_off); -if (0 != rc) { +if (rc) { SAM("ERROR: usb_set_interface() returned %i\n", rc); return -EFAULT; } rc = stop_100(peasycap->pusb_device); -if (0 != rc) { +if (rc) { SAM("ERROR: stop_100() returned %i\n", rc); return -EFAULT; } @@ -488,7 +488,7 @@ if (input == peasycap->inputset[input].input) { if (off != peasycap->standard_offset) { rc = adjust_standard(peasycap, easycap_standard[off].v4l2_standard.id); - if (0 != rc) { + if (rc) { SAM("ERROR: adjust_standard() returned %i\n", rc); return -EFAULT; } @@ -517,7 +517,7 @@ if (input == peasycap->inputset[input].input) { mood = peasycap->inputset[input].brightness; if (mood != peasycap->brightness) { rc = adjust_brightness(peasycap, mood); - if (0 != rc) { + if (rc) { SAM("ERROR: adjust_brightness returned %i\n", rc); return -EFAULT; } @@ -526,7 +526,7 @@ if (input == peasycap->inputset[input].input) { mood = peasycap->inputset[input].contrast; if (mood != peasycap->contrast) { rc = adjust_contrast(peasycap, mood); - if (0 != rc) { + if (rc) { SAM("ERROR: adjust_contrast returned %i\n", rc); return -EFAULT; } @@ -535,7 +535,7 @@ if (input == peasycap->inputset[input].input) { mood = peasycap->inputset[input].saturation; if (mood != peasycap->saturation) { rc = adjust_saturation(peasycap, mood); - if (0 != rc) { + if (rc) { SAM("ERROR: adjust_saturation returned %i\n", rc); return -EFAULT; } @@ -544,7 +544,7 @@ if (input == peasycap->inputset[input].input) { mood = peasycap->inputset[input].hue; if (mood != peasycap->hue) { rc = adjust_hue(peasycap, mood); - if (0 != rc) { + if (rc) { SAM("ERROR: adjust_hue returned %i\n", rc); return -EFAULT; } @@ -562,12 +562,12 @@ if (NULL == peasycap->pusb_device) { rc = usb_set_interface(peasycap->pusb_device, peasycap->video_interface, peasycap->video_altsetting_on); -if (0 != rc) { +if (rc) { SAM("ERROR: usb_set_interface() returned %i\n", rc); return -EFAULT; } rc = start_100(peasycap->pusb_device); -if (0 != rc) { +if (rc) { SAM("ERROR: start_100() returned %i\n", rc); return -EFAULT; } @@ -1215,7 +1215,7 @@ miss++; JOM(8, "first awakening on wq_video after %i waits\n", miss); rc = field2frame(peasycap); -if (0 != rc) +if (rc) SAM("ERROR: field2frame() returned %i\n", rc); /*---------------------------------------------------------------------------*/ /* @@ -1284,7 +1284,7 @@ miss++; JOM(8, "second awakening on wq_video after %i waits\n", miss); rc = field2frame(peasycap); -if (0 != rc) +if (rc) SAM("ERROR: field2frame() returned %i\n", rc); /*---------------------------------------------------------------------------*/ /* @@ -4134,7 +4134,7 @@ case 0: { JOM(8, "defaulting initially to PAL\n"); #endif /*PREFER_NTSC*/ rc = reset(peasycap); - if (0 != rc) { + if (rc) { SAM("ERROR: reset() returned %i\n", rc); return -EFAULT; } @@ -4498,7 +4498,7 @@ case 2: { JOM(4, "initializing ALSA card\n"); rc = easycap_alsa_probe(peasycap); - if (0 != rc) { + if (rc) { err("easycap_alsa_probe() returned %i\n", rc); return -ENODEV; } else { @@ -4510,7 +4510,7 @@ case 2: { #else /* CONFIG_EASYCAP_OSS */ rc = usb_register_dev(pusb_interface, &easyoss_class); - if (0 != rc) { + if (rc) { SAY("ERROR: usb_register_dev() failed\n"); usb_set_intfdata(pusb_interface, NULL); return -ENODEV; @@ -4870,7 +4870,7 @@ static int __init easycap_module_init(void) } JOT(4, "registering driver easycap\n"); rc = usb_register(&easycap_usb_driver); - if (0 != rc) + if (rc) SAY("ERROR: usb_register returned %i\n", rc); JOT(4, "ends\n"); diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index 7c07dbc1edc3..f5c4645117a4 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -412,7 +412,7 @@ if (NULL == pss) { return -EFAULT; } rc = easycap_alsa_vmalloc(pss, params_buffer_bytes(phw)); -if (0 != rc) +if (rc) return rc; return 0; } @@ -635,7 +635,7 @@ if (true == peasycap->microphone) { peasycap->psnd_card = psnd_card; rc = snd_pcm_new(psnd_card, "easycap_pcm", 0, 0, 1, &psnd_pcm); - if (0 != rc) { + if (rc) { SAM("ERROR: Cannot do ALSA snd_pcm_new()\n"); snd_card_free(psnd_card); return -EFAULT; @@ -650,7 +650,7 @@ if (true == peasycap->microphone) { peasycap->psubstream = NULL; rc = snd_card_register(psnd_card); - if (0 != rc) { + if (rc) { SAM("ERROR: Cannot do ALSA snd_card_register()\n"); snd_card_free(psnd_card); return -EFAULT; diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c index adf803199cc6..2fccb4c62eac 100644 --- a/drivers/staging/easycap/easycap_sound_oss.c +++ b/drivers/staging/easycap/easycap_sound_oss.c @@ -292,7 +292,7 @@ peasycap->oldaudio = oldaudio; resubmit: if (peasycap->audio_isoc_streaming) { rc = usb_submit_urb(purb, GFP_ATOMIC); - if (0 != rc) { + if (rc) { if (-ENODEV != rc && -ENOENT != rc) { SAM("ERROR: while %i=audio_idle, " "usb_submit_urb() failed " @@ -532,7 +532,7 @@ while ((fragment == (peasycap->audio_fill / ((fragment != (peasycap->audio_fill / peasycap->audio_pages_per_fragment)) && (0 < (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))))); - if (0 != rc) { + if (rc) { SAM("aborted by signal\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; @@ -637,7 +637,7 @@ while (fragment == (peasycap->audio_read / } /*---------------------------------------------------------------------------*/ rc = copy_to_user(puserspacebuffer, pdata_buffer->pto, more); - if (0 != rc) { + if (rc) { SAM("ERROR: copy_to_user() returned %li\n", rc); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; -- cgit v1.2.3 From b737f3b8cf2425f8e5f23ea31bbb4d377c41be7f Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 3 Feb 2011 13:42:43 +0200 Subject: staging/easycap: remove explicit NULL initialization remove intializations to NULL where not needed and let the compiler find flows with unitilized variables. Fix one such flow in easycap_vma_fault function Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_main.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 21d155a9e28e..8430e0045494 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -144,7 +144,6 @@ int rc; JOT(4, "\n"); SAY("==========OPEN=========\n"); -peasycap = NULL; /*---------------------------------------------------------------------------*/ #ifndef EASYCAP_IS_VIDEODEV_CLIENT if (NULL == inode) { @@ -851,7 +850,7 @@ if (NULL != peasycap->purb_video_head) { list_for_each_safe(plist_head, plist_next, peasycap->purb_video_head) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); if (NULL != pdata_urb) { - kfree(pdata_urb); pdata_urb = NULL; + kfree(pdata_urb); pdata_urb = NULL; peasycap->allocation_video_struct -= sizeof(struct data_urb); m++; @@ -2649,8 +2648,6 @@ struct page *page; struct easycap *peasycap; retcode = VM_FAULT_NOPAGE; -pbuf = NULL; -page = NULL; if (NULL == pvma) { SAY("pvma is NULL\n"); @@ -2686,16 +2683,15 @@ if (NULL == peasycap) { pbuf = peasycap->frame_buffer[k][m].pgo; if (NULL == pbuf) { SAM("ERROR: pbuf is NULL\n"); - goto finish; + return retcode; } page = virt_to_page(pbuf); if (NULL == page) { SAM("ERROR: page is NULL\n"); - goto finish; + return retcode; } get_page(page); /*---------------------------------------------------------------------------*/ -finish: if (NULL == page) { SAM("ERROR: page is NULL after get_page(page)\n"); } else { @@ -3192,7 +3188,6 @@ if (NULL == pusb_interface) { SAY("ERROR: pusb_interface is NULL\n"); return -EFAULT; } -peasycap = NULL; /*---------------------------------------------------------------------------*/ /* * GET POINTER TO STRUCTURE usb_device -- cgit v1.2.3 From 27d1766927372bf1410a44e8a22132757b0948b0 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 3 Feb 2011 13:42:44 +0200 Subject: staging/easycap: rename variable s32 to tmp 1. naming variable s32 is confusing since it is also a type name. 2. use s32 instead of __s32, the later is for user space Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_main.c | 166 ++++++++++++++++----------------- 1 file changed, 83 insertions(+), 83 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 8430e0045494..28277de50a78 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -1797,13 +1797,13 @@ int redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, __u8 mask, __u8 margin, bool isuy) { -static __s32 ay[256], bu[256], rv[256], gu[256], gv[256]; +static s32 ay[256], bu[256], rv[256], gu[256], gv[256]; __u8 *pcache; __u8 r, g, b, y, u, v, c, *p2, *p3, *pz, *pr; int bytesperpixel; bool byteswaporder, decimatepixel, last; int j, rump; -__s32 s32; +s32 tmp; if (much % 2) { SAM("MISTAKE: much is odd\n"); @@ -1816,14 +1816,14 @@ decimatepixel = peasycap->decimatepixel; /*---------------------------------------------------------------------------*/ if (!bu[255]) { for (j = 0; j < 112; j++) { - s32 = (0xFF00 & (453 * j)) >> 8; - bu[j + 128] = s32; bu[127 - j] = -s32; - s32 = (0xFF00 & (359 * j)) >> 8; - rv[j + 128] = s32; rv[127 - j] = -s32; - s32 = (0xFF00 & (88 * j)) >> 8; - gu[j + 128] = s32; gu[127 - j] = -s32; - s32 = (0xFF00 & (183 * j)) >> 8; - gv[j + 128] = s32; gv[127 - j] = -s32; + tmp = (0xFF00 & (453 * j)) >> 8; + bu[j + 128] = tmp; bu[127 - j] = -tmp; + tmp = (0xFF00 & (359 * j)) >> 8; + rv[j + 128] = tmp; rv[127 - j] = -tmp; + tmp = (0xFF00 & (88 * j)) >> 8; + gu[j + 128] = tmp; gu[127 - j] = -tmp; + tmp = (0xFF00 & (183 * j)) >> 8; + gv[j + 128] = tmp; gv[127 - j] = -tmp; } for (j = 0; j < 16; j++) { bu[j] = bu[16]; rv[j] = rv[16]; @@ -1973,15 +1973,15 @@ case 3: u = *(p2 + 1); } - s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); - s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); if ((true == last) && rump) { pcache = &peasycap->cache[0]; @@ -2046,15 +2046,15 @@ case 3: u = *(p2 + 1); } - s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); - s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); if ((true == last) && rump) { pcache = &peasycap->cache[0]; @@ -2121,16 +2121,16 @@ case 3: } if (true == isuy) { - s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); - s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); if ((true == last) && rump) { pcache = &peasycap->cache[0]; @@ -2197,16 +2197,16 @@ case 3: if (true == isuy) { - s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); - s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); if ((true == last) && rump) { pcache = &peasycap->cache[0]; @@ -2278,15 +2278,15 @@ case 4: u = *(p2 + 1); } - s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); - s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); if ((true == last) && rump) { pcache = &peasycap->cache[0]; @@ -2360,15 +2360,15 @@ case 4: u = *(p2 + 1); } - s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); - s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); if ((true == last) && rump) { pcache = &peasycap->cache[0]; @@ -2446,16 +2446,16 @@ case 4: if (true == isuy) { - s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); - s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); if ((true == last) && rump) { pcache = &peasycap->cache[0]; @@ -2531,16 +2531,16 @@ case 4: } if (true == isuy) { - s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); - s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? - 0 : (__u8)s32); + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (__u8)tmp); if ((true == last) && rump) { pcache = &peasycap->cache[0]; @@ -3172,7 +3172,7 @@ int okepn[8]; int okmps[8]; int maxpacketsize; __u16 mask; -__s32 value; +s32 value; struct easycap_format *peasycap_format; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #ifdef EASYCAP_IS_VIDEODEV_CLIENT -- cgit v1.2.3 From 0117f77904a1cbd62cc6e7c25e3ebfc872707712 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 3 Feb 2011 13:42:45 +0200 Subject: staging/easycap: rename variable u8 to tmp naming variable u8 is confusing since it is also a type name. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_low.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index 15eef6a5200d..a00f4125efad 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -1178,7 +1178,7 @@ int audio_gainset(struct usb_device *pusb_device, __s8 loud) { int igot; -__u8 u8; +__u8 tmp; __u16 mute; if (NULL == pusb_device) @@ -1199,12 +1199,12 @@ if (0 > igot) { mute = 0; if (16 > loud) - u8 = 0x01 | (0x001F & (((__u8)(15 - loud)) << 1)); + tmp = 0x01 | (0x001F & (((__u8)(15 - loud)) << 1)); else - u8 = 0; + tmp = 0; -JOT(8, "0x%04X=(mute|u8) for VT1612A register 0x0E\n", mute | u8); -write_vt(pusb_device, 0x000E, (mute | u8)); +JOT(8, "0x%04X=(mute|tmp) for VT1612A register 0x0E\n", mute | tmp); +write_vt(pusb_device, 0x000E, (mute | tmp)); /*---------------------------------------------------------------------------*/ igot = read_vt(pusb_device, 0x0010); if (0 > igot) { @@ -1214,13 +1214,13 @@ if (0 > igot) { mute = 0x8000 & ((unsigned int)igot); mute = 0; -JOT(8, "0x%04X=(mute|u8|(u8<<8)) for VT1612A register 0x10,...0x18\n", - mute | u8 | (u8 << 8)); -write_vt(pusb_device, 0x0010, (mute | u8 | (u8 << 8))); -write_vt(pusb_device, 0x0012, (mute | u8 | (u8 << 8))); -write_vt(pusb_device, 0x0014, (mute | u8 | (u8 << 8))); -write_vt(pusb_device, 0x0016, (mute | u8 | (u8 << 8))); -write_vt(pusb_device, 0x0018, (mute | u8 | (u8 << 8))); +JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x10,...0x18\n", + mute | tmp | (tmp << 8)); +write_vt(pusb_device, 0x0010, (mute | tmp | (tmp << 8))); +write_vt(pusb_device, 0x0012, (mute | tmp | (tmp << 8))); +write_vt(pusb_device, 0x0014, (mute | tmp | (tmp << 8))); +write_vt(pusb_device, 0x0016, (mute | tmp | (tmp << 8))); +write_vt(pusb_device, 0x0018, (mute | tmp | (tmp << 8))); /*---------------------------------------------------------------------------*/ igot = read_vt(pusb_device, 0x001C); if (0 > igot) { @@ -1231,13 +1231,13 @@ if (0 > igot) { mute = 0; if (16 <= loud) - u8 = 0x000F & (__u8)(loud - 16); + tmp = 0x000F & (__u8)(loud - 16); else - u8 = 0; + tmp = 0; -JOT(8, "0x%04X=(mute|u8|(u8<<8)) for VT1612A register 0x1C\n", - mute | u8 | (u8 << 8)); -write_vt(pusb_device, 0x001C, (mute | u8 | (u8 << 8))); +JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x1C\n", + mute | tmp | (tmp << 8)); +write_vt(pusb_device, 0x001C, (mute | tmp | (tmp << 8))); write_vt(pusb_device, 0x001A, 0x0404); write_vt(pusb_device, 0x0002, 0x0000); return 0; -- cgit v1.2.3 From 1a4cb0fb7da009643368b3577b65a2d1da5485dd Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 3 Feb 2011 13:42:46 +0200 Subject: staging/easycap: rename variable s16 to tmp naming variable s16 is confusing since it is also a type name. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_sound.c | 25 ++++++++++++------------- drivers/staging/easycap/easycap_sound_oss.c | 26 +++++++++++++------------- 2 files changed, 25 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index f5c4645117a4..e0fc188ae38a 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -73,7 +73,7 @@ struct snd_pcm_runtime *prt; int dma_bytes, fragment_bytes; int isfragment; __u8 *p1, *p2; -__s16 s16; +__s16 tmp; int i, j, more, much, rc; #ifdef UPSAMPLE int k; @@ -203,22 +203,22 @@ for (i = 0; i < purb->number_of_packets; i++) { delta = (newaudio - oldaudio) / 4; - s16 = oldaudio + delta; + tmp = oldaudio + delta; for (k = 0; k < 4; k++) { - *p2 = (0x00FF & s16); + *p2 = (0x00FF & tmp); *(p2 + 1) = (0xFF00 & - s16) >> 8; + tmp) >> 8; p2 += 2; - *p2 = (0x00FF & s16); + *p2 = (0x00FF & tmp); *(p2 + 1) = (0xFF00 & - s16) >> 8; + tmp) >> 8; p2 += 2; - s16 += delta; + tmp += delta; } p1++; more--; - oldaudio = s16; + oldaudio = tmp; } #else /*!UPSAMPLE*/ if (much > (2 * more)) @@ -227,11 +227,10 @@ for (i = 0; i < purb->number_of_packets; i++) { peasycap->dma_fill); for (j = 0; j < (much / 2); j++) { - s16 = ((int) *p1) - 128; - s16 = 128 * - s16; - *p2 = (0x00FF & s16); - *(p2 + 1) = (0xFF00 & s16) >> + tmp = ((int) *p1) - 128; + tmp = 128 * tmp; + *p2 = (0x00FF & tmp); + *(p2 + 1) = (0xFF00 & tmp) >> 8; p1++; p2 += 2; more--; diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c index 2fccb4c62eac..639257c0e669 100644 --- a/drivers/staging/easycap/easycap_sound_oss.c +++ b/drivers/staging/easycap/easycap_sound_oss.c @@ -54,7 +54,7 @@ easyoss_complete(struct urb *purb) struct easycap *peasycap; struct data_buffer *paudio_buffer; __u8 *p1, *p2; -__s16 s16; +__s16 tmp; int i, j, more, much, leap, rc; #ifdef UPSAMPLE int k; @@ -235,23 +235,23 @@ for (i = 0; i < purb->number_of_packets; i++) { delta = (newaudio - oldaudio) / 4; - s16 = oldaudio + delta; + tmp = oldaudio + delta; for (k = 0; k < 4; k++) { - *p2 = (0x00FF & s16); + *p2 = (0x00FF & tmp); *(p2 + 1) = (0xFF00 & - s16) >> 8; + tmp) >> 8; p2 += 2; - *p2 = (0x00FF & s16); + *p2 = (0x00FF & tmp); *(p2 + 1) = (0xFF00 & - s16) >> 8; + tmp) >> 8; p2 += 2; - s16 += delta; + tmp += delta; } p1++; more--; - oldaudio = s16; + oldaudio = tmp; } #else /*!UPSAMPLE*/ if (much > (2 * more)) @@ -259,11 +259,11 @@ for (i = 0; i < purb->number_of_packets; i++) { p2 = (__u8 *)paudio_buffer->pto; for (j = 0; j < (much / 2); j++) { - s16 = ((int) *p1) - 128; - s16 = 128 * - s16; - *p2 = (0x00FF & s16); - *(p2 + 1) = (0xFF00 & s16) >> + tmp = ((int) *p1) - 128; + tmp = 128 * + tmp; + *p2 = (0x00FF & tmp); + *(p2 + 1) = (0xFF00 & tmp) >> 8; p1++; p2 += 2; more--; -- cgit v1.2.3 From 055e3a3a2cdcb7d39d14857e2fb2175c11168ee7 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 3 Feb 2011 13:42:47 +0200 Subject: staging/easycap: replace underscored types with regular once the underscored types should be used in user space headers only Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 46 +++++----- drivers/staging/easycap/easycap_ioctl.c | 40 ++++----- drivers/staging/easycap/easycap_low.c | 128 ++++++++++++++-------------- drivers/staging/easycap/easycap_main.c | 98 ++++++++++----------- drivers/staging/easycap/easycap_settings.c | 4 +- drivers/staging/easycap/easycap_sound.c | 12 +-- drivers/staging/easycap/easycap_sound_oss.c | 12 +-- 7 files changed, 170 insertions(+), 170 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 1276cbf52fe3..b282b0b06986 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -259,8 +259,8 @@ struct data_buffer { struct list_head list_head; void *pgo; void *pto; - __u16 kount; - __u16 input; + u16 kount; + u16 input; }; /*---------------------------------------------------------------------------*/ struct data_urb { @@ -271,11 +271,11 @@ struct data_urb { }; /*---------------------------------------------------------------------------*/ struct easycap_standard { - __u16 mask; + u16 mask; struct v4l2_standard v4l2_standard; }; struct easycap_format { - __u16 mask; + u16 mask; char name[128]; struct v4l2_format v4l2_format; }; @@ -323,7 +323,7 @@ struct easycap { #define UPSAMPLE #ifdef UPSAMPLE - __s16 oldaudio; + s16 oldaudio; #endif /*UPSAMPLE*/ int ilk; @@ -388,12 +388,12 @@ struct easycap { struct list_head urb_video_head; struct list_head *purb_video_head; - __u8 cache[8]; - __u8 *pcache; + u8 cache[8]; + u8 *pcache; int video_mt; int audio_mt; long long audio_bytes; - __u32 isequence; + u32 isequence; int vma_many; /*---------------------------------------------------------------------------*/ @@ -418,7 +418,7 @@ struct easycap { * IMAGE PROPERTIES */ /*---------------------------------------------------------------------------*/ - __u32 pixelformat; + u32 pixelformat; int width; int height; int bytesperpixel; @@ -516,12 +516,12 @@ int submit_video_urbs(struct easycap *); int kill_video_urbs(struct easycap *); int field2frame(struct easycap *); int redaub(struct easycap *, void *, void *, - int, int, __u8, __u8, bool); + int, int, u8, u8, bool); void easycap_testcard(struct easycap *, int); int fillin_formats(void); int newinput(struct easycap *, int); int adjust_standard(struct easycap *, v4l2_std_id); -int adjust_format(struct easycap *, __u32, __u32, __u32, +int adjust_format(struct easycap *, u32, u32, u32, int, bool); int adjust_brightness(struct easycap *, int); int adjust_contrast(struct easycap *, int); @@ -551,9 +551,9 @@ int audio_setup(struct easycap *); */ /*---------------------------------------------------------------------------*/ int audio_gainget(struct usb_device *); -int audio_gainset(struct usb_device *, __s8); +int audio_gainset(struct usb_device *, s8); -int set_interface(struct usb_device *, __u16); +int set_interface(struct usb_device *, u16); int wakeup_device(struct usb_device *); int confirm_resolution(struct usb_device *); int confirm_stream(struct usb_device *); @@ -568,20 +568,20 @@ int merit_saa(struct usb_device *); int check_vt(struct usb_device *); int select_input(struct usb_device *, int, int); int set_resolution(struct usb_device *, - __u16, __u16, __u16, __u16); + u16, u16, u16, u16); -int read_saa(struct usb_device *, __u16); -int read_stk(struct usb_device *, __u32); -int write_saa(struct usb_device *, __u16, __u16); +int read_saa(struct usb_device *, u16); +int read_stk(struct usb_device *, u32); +int write_saa(struct usb_device *, u16, u16); int wait_i2c(struct usb_device *); -int write_000(struct usb_device *, __u16, __u16); +int write_000(struct usb_device *, u16, u16); int start_100(struct usb_device *); int stop_100(struct usb_device *); int write_300(struct usb_device *); -int read_vt(struct usb_device *, __u16); -int write_vt(struct usb_device *, __u16, __u16); -int regset(struct usb_device *, __u16, __u16); -int regget(struct usb_device *, __u16, void *); +int read_vt(struct usb_device *, u16); +int write_vt(struct usb_device *, u16, u16); +int regset(struct usb_device *, u16, u16); +int regget(struct usb_device *, u16, void *); int isdongle(struct easycap *); /*---------------------------------------------------------------------------*/ struct signed_div_result { @@ -597,7 +597,7 @@ struct signed_div_result { /*---------------------------------------------------------------------------*/ #define GET(X, Y, Z) do { \ int rc; \ - *(Z) = (__u16)0; \ + *(Z) = (u16)0; \ rc = regget(X, Y, Z); \ if (0 > rc) { \ JOT(8, ":-(%i\n", __LINE__); return(rc); \ diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 73cb0d4cd068..304376f08f5c 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -43,7 +43,7 @@ int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id) { struct easycap_standard const *peasycap_standard; -__u16 reg, set; +u16 reg, set; int ir, rc, need, k; unsigned int itwas, isnow; bool resubmit; @@ -340,14 +340,14 @@ return 0; */ /*--------------------------------------------------------------------------*/ int adjust_format(struct easycap *peasycap, - __u32 width, __u32 height, __u32 pixelformat, int field, bool try) + u32 width, u32 height, u32 pixelformat, int field, bool try) { struct easycap_format *peasycap_format, *peasycap_best_format; -__u16 mask; +u16 mask; struct usb_device *p; int miss, multiplier, best, k; char bf[5], fo[32], *pc; -__u32 uc; +u32 uc; bool resubmit; if (NULL == peasycap) { @@ -855,7 +855,7 @@ return -ENOENT; /*****************************************************************************/ int adjust_volume(struct easycap *peasycap, int value) { -__s8 mood; +s8 mood; int i1; if (NULL == peasycap) { @@ -883,7 +883,7 @@ while (0xFFFFFFFF != easycap_control[i1].id) { peasycap->volume = value; mood = (16 > peasycap->volume) ? 16 : ((31 < peasycap->volume) ? 31 : - (__s8) peasycap->volume); + (s8) peasycap->volume); if (!audio_gainset(peasycap->pusb_device, mood)) { SAM("adjusting volume to 0x%02X\n", mood); return 0; @@ -1093,7 +1093,7 @@ case VIDIOC_QUERYCAP: { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_ENUMINPUT: { struct v4l2_input v4l2_input; - __u32 index; + u32 index; JOM(8, "VIDIOC_ENUMINPUT\n"); @@ -1195,12 +1195,12 @@ case VIDIOC_ENUMINPUT: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_INPUT: { - __u32 index; + u32 index; JOM(8, "VIDIOC_G_INPUT\n"); - index = (__u32)peasycap->input; + index = (u32)peasycap->input; JOM(8, "user is told: %i\n", index); - if (0 != copy_to_user((void __user *)arg, &index, sizeof(__u32))) { + if (0 != copy_to_user((void __user *)arg, &index, sizeof(u32))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } @@ -1209,12 +1209,12 @@ case VIDIOC_G_INPUT: { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_S_INPUT: { - __u32 index; + u32 index; int rc; JOM(8, "VIDIOC_S_INPUT\n"); - if (0 != copy_from_user(&index, (void __user *)arg, sizeof(__u32))) { + if (0 != copy_from_user(&index, (void __user *)arg, sizeof(u32))) { mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } @@ -1465,7 +1465,7 @@ case VIDIOC_S_EXT_CTRLS: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_ENUM_FMT: { - __u32 index; + u32 index; struct v4l2_fmtdesc v4l2_fmtdesc; JOM(8, "VIDIOC_ENUM_FMT\n"); @@ -1545,7 +1545,7 @@ case VIDIOC_ENUM_FMT: { */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_ENUM_FRAMESIZES: { - __u32 index; + u32 index; struct v4l2_frmsizeenum v4l2_frmsizeenum; JOM(8, "VIDIOC_ENUM_FRAMESIZES\n"); @@ -1558,7 +1558,7 @@ case VIDIOC_ENUM_FRAMESIZES: { index = v4l2_frmsizeenum.index; - v4l2_frmsizeenum.type = (__u32) V4L2_FRMSIZE_TYPE_DISCRETE; + v4l2_frmsizeenum.type = (u32) V4L2_FRMSIZE_TYPE_DISCRETE; if (true == peasycap->ntsc) { switch (index) { @@ -1681,7 +1681,7 @@ case VIDIOC_ENUM_FRAMESIZES: { */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_ENUM_FRAMEINTERVALS: { - __u32 index; + u32 index; int denominator; struct v4l2_frmivalenum v4l2_frmivalenum; @@ -1704,7 +1704,7 @@ case VIDIOC_ENUM_FRAMEINTERVALS: { index = v4l2_frmivalenum.index; - v4l2_frmivalenum.type = (__u32) V4L2_FRMIVAL_TYPE_DISCRETE; + v4l2_frmivalenum.type = (u32) V4L2_FRMIVAL_TYPE_DISCRETE; switch (index) { case 0: { @@ -1904,7 +1904,7 @@ case VIDIOC_QUERYSTD: { case VIDIOC_ENUMSTD: { int last0 = -1, last1 = -1, last2 = -1, last3 = -1; struct v4l2_standard v4l2_standard; - __u32 index; + u32 index; struct easycap_standard const *peasycap_standard; JOM(8, "VIDIOC_ENUMSTD\n"); @@ -2054,7 +2054,7 @@ case VIDIOC_REQBUFS: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_QUERYBUF: { - __u32 index; + u32 index; struct v4l2_buffer v4l2_buffer; JOM(8, "VIDIOC_QUERYBUF\n"); @@ -2167,7 +2167,7 @@ case VIDIOC_DQBUF: int i, j; struct v4l2_buffer v4l2_buffer; int rcdq; - __u16 input; + u16 input; JOM(8, "VIDIOC_DQBUF\n"); diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index a00f4125efad..f3dc1fc7e255 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -252,7 +252,7 @@ static const struct saa7113config saa7113configNTSC[256] = { int confirm_resolution(struct usb_device *p) { -__u8 get0, get1, get2, get3, get4, get5, get6, get7; +u8 get0, get1, get2, get3, get4, get5, get6, get7; if (NULL == p) return -ENODEV; @@ -293,8 +293,8 @@ return 0; int confirm_stream(struct usb_device *p) { -__u16 get2; -__u8 igot; +u16 get2; +u8 igot; if (NULL == p) return -ENODEV; @@ -356,9 +356,9 @@ return 0; } /****************************************************************************/ int -write_000(struct usb_device *p, __u16 set2, __u16 set0) +write_000(struct usb_device *p, u16 set2, u16 set0) { -__u8 igot0, igot2; +u8 igot0, igot2; if (NULL == p) return -ENODEV; @@ -370,7 +370,7 @@ return 0; } /****************************************************************************/ int -write_saa(struct usb_device *p, __u16 reg0, __u16 set0) +write_saa(struct usb_device *p, u16 reg0, u16 set0) { if (NULL == p) return -ENODEV; @@ -391,11 +391,11 @@ return wait_i2c(p); */ /*--------------------------------------------------------------------------*/ int -write_vt(struct usb_device *p, __u16 reg0, __u16 set0) +write_vt(struct usb_device *p, u16 reg0, u16 set0) { -__u8 igot; -__u16 got502, got503; -__u16 set502, set503; +u8 igot; +u16 got502, got503; +u16 set502, set503; if (NULL == p) return -ENODEV; @@ -429,10 +429,10 @@ return 0; */ /*--------------------------------------------------------------------------*/ int -read_vt(struct usb_device *p, __u16 reg0) +read_vt(struct usb_device *p, u16 reg0) { -__u8 igot; -__u16 got502, got503; +u8 igot; +u16 got502, got503; if (NULL == p) return -ENODEV; @@ -665,9 +665,9 @@ return 0; } /****************************************************************************/ int -read_saa(struct usb_device *p, __u16 reg0) +read_saa(struct usb_device *p, u16 reg0) { -__u8 igot; +u8 igot; if (NULL == p) return -ENODEV; @@ -681,9 +681,9 @@ return igot; } /****************************************************************************/ int -read_stk(struct usb_device *p, __u32 reg0) +read_stk(struct usb_device *p, u32 reg0) { -__u8 igot; +u8 igot; if (NULL == p) return -ENODEV; @@ -815,9 +815,9 @@ return 0; /****************************************************************************/ int set_resolution(struct usb_device *p, - __u16 set0, __u16 set1, __u16 set2, __u16 set3) + u16 set0, u16 set1, u16 set2, u16 set3) { -__u16 u0x0111, u0x0113, u0x0115, u0x0117; +u16 u0x0111, u0x0113, u0x0115, u0x0117; if (NULL == p) return -ENODEV; @@ -841,8 +841,8 @@ return 0; int start_100(struct usb_device *p) { -__u16 get116, get117, get0; -__u8 igot116, igot117, igot; +u16 get116, get117, get0; +u8 igot116, igot117, igot; if (NULL == p) return -ENODEV; @@ -866,8 +866,8 @@ return 0; int stop_100(struct usb_device *p) { -__u16 get0; -__u8 igot; +u16 get0; +u8 igot; if (NULL == p) return -ENODEV; @@ -885,8 +885,8 @@ return 0; int wait_i2c(struct usb_device *p) { -__u16 get0; -__u8 igot; +u16 get0; +u8 igot; const int max = 2; int k; @@ -912,33 +912,33 @@ return -1; } /****************************************************************************/ int -regset(struct usb_device *pusb_device, __u16 index, __u16 value) +regset(struct usb_device *pusb_device, u16 index, u16 value) { -__u16 igot; +u16 igot; int rc0, rc1; if (!pusb_device) return -ENODEV; rc1 = 0; igot = 0; rc0 = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), - (__u8)0x01, - (__u8)(USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE), - (__u16)value, - (__u16)index, + (u8)0x01, + (u8)(USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE), + (u16)value, + (u16)index, NULL, - (__u16)0, + (u16)0, (int)500); #ifdef NOREADBACK # #else rc1 = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), - (__u8)0x00, - (__u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), - (__u16)0x00, - (__u16)index, + (u8)0x00, + (u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), + (u16)0x00, + (u16)index, (void *)&igot, - (__u16)sizeof(__u16), + (u16)sizeof(u16), (int)50000); igot = 0xFF & igot; switch (index) { @@ -976,19 +976,19 @@ return (0 > rc0) ? rc0 : rc1; } /*****************************************************************************/ int -regget(struct usb_device *pusb_device, __u16 index, void *pvoid) +regget(struct usb_device *pusb_device, u16 index, void *pvoid) { int ir; if (!pusb_device) return -ENODEV; ir = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), - (__u8)0x00, - (__u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), - (__u16)0x00, - (__u16)index, + (u8)0x00, + (u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), + (u16)0x00, + (u16)index, (void *)pvoid, - sizeof(__u8), + sizeof(u8), (int)50000); return 0xFF & ir; } @@ -999,12 +999,12 @@ wakeup_device(struct usb_device *pusb_device) if (!pusb_device) return -ENODEV; return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), - (__u8)USB_REQ_SET_FEATURE, - (__u8)(USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE), + (u8)USB_REQ_SET_FEATURE, + (u8)(USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE), USB_DEVICE_REMOTE_WAKEUP, - (__u16)0, + (u16)0, (void *) NULL, - (__u16)0, + (u16)0, (int)50000); } /*****************************************************************************/ @@ -1022,12 +1022,12 @@ int rc, id1, id2; * TO ENABLE AUDIO THE VALUE 0x0200 MUST BE SENT. */ /*---------------------------------------------------------------------------*/ -const __u8 request = 0x01; -const __u8 requesttype = - (__u8)(USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE); -const __u16 value_unmute = 0x0200; -const __u16 index = 0x0301; -const __u16 length = 1; +const u8 request = 0x01; +const u8 requesttype = + (u8)(USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE); +const u16 value_unmute = 0x0200; +const u16 index = 0x0301; +const u16 length = 1; if (NULL == peasycap) return -EFAULT; @@ -1048,15 +1048,15 @@ JOM(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n", buffer[0] = 0x01; rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), - (__u8)request, - (__u8)requesttype, - (__u16)value_unmute, - (__u16)index, + (u8)request, + (u8)requesttype, + (u16)value_unmute, + (u16)index, (void *)&buffer[0], - (__u16)length, + (u16)length, (int)50000); -JOT(8, "0x%02X=buffer\n", *((__u8 *) &buffer[0])); +JOT(8, "0x%02X=buffer\n", *((u8 *) &buffer[0])); if (rc != (int)length) { switch (rc) { case -EPIPE: { @@ -1175,11 +1175,11 @@ return 0; */ /*---------------------------------------------------------------------------*/ int -audio_gainset(struct usb_device *pusb_device, __s8 loud) +audio_gainset(struct usb_device *pusb_device, s8 loud) { int igot; -__u8 tmp; -__u16 mute; +u8 tmp; +u16 mute; if (NULL == pusb_device) return -ENODEV; @@ -1199,7 +1199,7 @@ if (0 > igot) { mute = 0; if (16 > loud) - tmp = 0x01 | (0x001F & (((__u8)(15 - loud)) << 1)); + tmp = 0x01 | (0x001F & (((u8)(15 - loud)) << 1)); else tmp = 0; @@ -1231,7 +1231,7 @@ if (0 > igot) { mute = 0; if (16 <= loud) - tmp = 0x000F & (__u8)(loud - 16); + tmp = 0x000F & (u8)(loud - 16); else tmp = 0; diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 28277de50a78..58cfa409e914 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -1336,14 +1336,14 @@ field2frame(struct easycap *peasycap) { struct timeval timeval; long long int above, below; -__u32 remainder; +u32 remainder; struct signed_div_result sdr; void *pex, *pad; int kex, kad, mex, mad, rex, rad, rad2; int c2, c3, w2, w3, cz, wz; int rc, bytesperpixel, multiplier, much, more, over, rump, caches, input; -__u8 mask, margin; +u8 mask, margin; bool odd, isuy, decimatepixel, offerfields, badinput; if (NULL == peasycap) { @@ -1464,13 +1464,13 @@ while (cz < wz) { much) / 2) - rad; more = rad; } - mask = (__u8)rump; + mask = (u8)rump; margin = 0; if (much == rex) { mask |= 0x04; if ((mex + 1) < FIELD_BUFFER_SIZE/ PAGE_SIZE) { - margin = *((__u8 *)(peasycap-> + margin = *((u8 *)(peasycap-> field_buffer [kex][mex + 1].pgo)); } else @@ -1588,13 +1588,13 @@ while (cz < wz) { much) / 4) - rad; more = rad; } - mask = (__u8)rump; + mask = (u8)rump; margin = 0; if (much == rex) { mask |= 0x04; if ((mex + 1) < FIELD_BUFFER_SIZE/ PAGE_SIZE) { - margin = *((__u8 *)(peasycap-> + margin = *((u8 *)(peasycap-> field_buffer [kex][mex + 1].pgo)); } @@ -1737,7 +1737,7 @@ if (peasycap->timeval6.tv_sec) { sdr = signed_div(above, below); above = sdr.quotient; - remainder = (__u32)sdr.remainder; + remainder = (u32)sdr.remainder; JOM(8, "video streaming at %3lli.%03i fields per second\n", above, (remainder/1000)); @@ -1795,11 +1795,11 @@ return sdr; /*---------------------------------------------------------------------------*/ int redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, - __u8 mask, __u8 margin, bool isuy) + u8 mask, u8 margin, bool isuy) { static s32 ay[256], bu[256], rv[256], gu[256], gv[256]; -__u8 *pcache; -__u8 r, g, b, y, u, v, c, *p2, *p3, *pz, *pr; +u8 *pcache; +u8 r, g, b, y, u, v, c, *p2, *p3, *pz, *pr; int bytesperpixel; bool byteswaporder, decimatepixel, last; int j, rump; @@ -1857,7 +1857,7 @@ if (!pcache) { if (pcache != &peasycap->cache[0]) JOM(16, "cache has %i bytes\n", (int)(pcache - &peasycap->cache[0])); p2 = &peasycap->cache[0]; -p3 = (__u8 *)pad - (int)(pcache - &peasycap->cache[0]); +p3 = (u8 *)pad - (int)(pcache - &peasycap->cache[0]); while (p2 < pcache) { *p3++ = *p2; p2++; } @@ -1869,7 +1869,7 @@ if (p3 != pad) { /*---------------------------------------------------------------------------*/ rump = (int)(0x03 & mask); u = 0; v = 0; -p2 = (__u8 *)pex; pz = p2 + much; pr = p3 + more; last = false; +p2 = (u8 *)pex; pz = p2 + much; pr = p3 + more; last = false; p2++; if (true == isuy) @@ -1898,7 +1898,7 @@ case 2: { ** YUYV */ /*---------------------------------------------------*/ - p3 = (__u8 *)pad; pz = p3 + much; + p3 = (u8 *)pad; pz = p3 + much; while (pz > p3) { c = *p3; *p3 = *(p3 + 1); @@ -1914,7 +1914,7 @@ case 2: { ** UYVY DECIMATED */ /*---------------------------------------------------*/ - p2 = (__u8 *)pex; p3 = (__u8 *)pad; pz = p2 + much; + p2 = (u8 *)pex; p3 = (u8 *)pad; pz = p2 + much; while (pz > p2) { *p3 = *p2; *(p3 + 1) = *(p2 + 1); @@ -1929,7 +1929,7 @@ case 2: { ** YUYV DECIMATED **/ /*---------------------------------------------------*/ - p2 = (__u8 *)pex; p3 = (__u8 *)pad; pz = p2 + much; + p2 = (u8 *)pex; p3 = (u8 *)pad; pz = p2 + much; while (pz > p2) { *p3 = *(p2 + 1); *(p3 + 1) = *p2; @@ -1975,13 +1975,13 @@ case 3: tmp = ay[(int)y] + rv[(int)v]; r = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; g = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); tmp = ay[(int)y] + bu[(int)u]; b = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); if ((true == last) && rump) { pcache = &peasycap->cache[0]; @@ -2048,13 +2048,13 @@ case 3: tmp = ay[(int)y] + rv[(int)v]; r = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; g = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); tmp = ay[(int)y] + bu[(int)u]; b = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); if ((true == last) && rump) { pcache = &peasycap->cache[0]; @@ -2123,14 +2123,14 @@ case 3: if (true == isuy) { tmp = ay[(int)y] + rv[(int)v]; r = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; g = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); tmp = ay[(int)y] + bu[(int)u]; b = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); if ((true == last) && rump) { pcache = &peasycap->cache[0]; @@ -2199,14 +2199,14 @@ case 3: tmp = ay[(int)y] + rv[(int)v]; r = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; g = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); tmp = ay[(int)y] + bu[(int)u]; b = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); if ((true == last) && rump) { pcache = &peasycap->cache[0]; @@ -2280,13 +2280,13 @@ case 4: tmp = ay[(int)y] + rv[(int)v]; r = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; g = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); tmp = ay[(int)y] + bu[(int)u]; b = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); if ((true == last) && rump) { pcache = &peasycap->cache[0]; @@ -2362,13 +2362,13 @@ case 4: tmp = ay[(int)y] + rv[(int)v]; r = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; g = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); tmp = ay[(int)y] + bu[(int)u]; b = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); if ((true == last) && rump) { pcache = &peasycap->cache[0]; @@ -2448,14 +2448,14 @@ case 4: tmp = ay[(int)y] + rv[(int)v]; r = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; g = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); tmp = ay[(int)y] + bu[(int)u]; b = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); if ((true == last) && rump) { pcache = &peasycap->cache[0]; @@ -2533,14 +2533,14 @@ case 4: if (true == isuy) { tmp = ay[(int)y] + rv[(int)v]; r = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; g = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); tmp = ay[(int)y] + bu[(int)u]; b = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (__u8)tmp); + 0 : (u8)tmp); if ((true == last) && rump) { pcache = &peasycap->cache[0]; @@ -2754,7 +2754,7 @@ int i, more, much, leap, rc, last; int videofieldamount; unsigned int override, bad; int framestatus, framelength, frameactual, frameoffset; -__u8 *pu; +u8 *pu; if (NULL == purb) { SAY("ERROR: easycap_complete(): purb is NULL\n"); @@ -2862,7 +2862,7 @@ if (purb->status) { } pfield_buffer = &peasycap->field_buffer [peasycap->field_fill][peasycap->field_page]; - pu = (__u8 *)(purb->transfer_buffer + + pu = (u8 *)(purb->transfer_buffer + purb->iso_frame_desc[i].offset); if (0x80 & *pu) leap = 8; @@ -3159,19 +3159,19 @@ int ISOCwMaxPacketSize; int BULKwMaxPacketSize; int INTwMaxPacketSize; int CTRLwMaxPacketSize; -__u8 bEndpointAddress; -__u8 ISOCbEndpointAddress; -__u8 INTbEndpointAddress; +u8 bEndpointAddress; +u8 ISOCbEndpointAddress; +u8 INTbEndpointAddress; int isin, i, j, k, m, rc; -__u8 bInterfaceNumber; -__u8 bInterfaceClass; -__u8 bInterfaceSubClass; +u8 bInterfaceNumber; +u8 bInterfaceClass; +u8 bInterfaceSubClass; void *pbuf; int okalt[8], isokalt; int okepn[8]; int okmps[8]; int maxpacketsize; -__u16 mask; +u16 mask; s32 value; struct easycap_format *peasycap_format; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ @@ -4552,7 +4552,7 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) { struct usb_host_interface *pusb_host_interface; struct usb_interface_descriptor *pusb_interface_descriptor; -__u8 bInterfaceNumber; +u8 bInterfaceNumber; struct easycap *peasycap; struct list_head *plist_head; diff --git a/drivers/staging/easycap/easycap_settings.c b/drivers/staging/easycap/easycap_settings.c index 6ae1a73099fd..22d69cca549a 100644 --- a/drivers/staging/easycap/easycap_settings.c +++ b/drivers/staging/easycap/easycap_settings.c @@ -314,10 +314,10 @@ int fillin_formats(void) { int i, j, k, m, n; -__u32 width, height, pixelformat, bytesperline, sizeimage; +u32 width, height, pixelformat, bytesperline, sizeimage; enum v4l2_field field; enum v4l2_colorspace colorspace; -__u16 mask1, mask2, mask3, mask4; +u16 mask1, mask2, mask3, mask4; char name1[32], name2[32], name3[32], name4[32]; for (i = 0, n = 0; i < STANDARD_MANY; i++) { mask1 = 0x0000; diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index e0fc188ae38a..626450a57140 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -72,12 +72,12 @@ struct snd_pcm_substream *pss; struct snd_pcm_runtime *prt; int dma_bytes, fragment_bytes; int isfragment; -__u8 *p1, *p2; -__s16 tmp; +u8 *p1, *p2; +s16 tmp; int i, j, more, much, rc; #ifdef UPSAMPLE int k; -__s16 oldaudio, newaudio, delta; +s16 oldaudio, newaudio, delta; #endif /*UPSAMPLE*/ JOT(16, "\n"); @@ -152,7 +152,7 @@ for (i = 0; i < purb->number_of_packets; i++) { peasycap->audio_mt = 0; } - p1 = (__u8 *)(purb->transfer_buffer + + p1 = (u8 *)(purb->transfer_buffer + purb->iso_frame_desc[i].offset); /*---------------------------------------------------------------------------*/ @@ -193,7 +193,7 @@ for (i = 0; i < purb->number_of_packets; i++) { more)) much = 16 * more; - p2 = (__u8 *)(prt->dma_area + + p2 = (u8 *)(prt->dma_area + peasycap->dma_fill); for (j = 0; j < (much/16); j++) { @@ -223,7 +223,7 @@ for (i = 0; i < purb->number_of_packets; i++) { #else /*!UPSAMPLE*/ if (much > (2 * more)) much = 2 * more; - p2 = (__u8 *)(prt->dma_area + + p2 = (u8 *)(prt->dma_area + peasycap->dma_fill); for (j = 0; j < (much / 2); j++) { diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c index 639257c0e669..7acdd8ff72e4 100644 --- a/drivers/staging/easycap/easycap_sound_oss.c +++ b/drivers/staging/easycap/easycap_sound_oss.c @@ -53,12 +53,12 @@ easyoss_complete(struct urb *purb) { struct easycap *peasycap; struct data_buffer *paudio_buffer; -__u8 *p1, *p2; -__s16 tmp; +u8 *p1, *p2; +s16 tmp; int i, j, more, much, leap, rc; #ifdef UPSAMPLE int k; -__s16 oldaudio, newaudio, delta; +s16 oldaudio, newaudio, delta; #endif /*UPSAMPLE*/ JOT(16, "\n"); @@ -133,7 +133,7 @@ for (i = 0; i < purb->number_of_packets; i++) { peasycap->audio_mt = 0; } - p1 = (__u8 *)(purb->transfer_buffer + + p1 = (u8 *)(purb->transfer_buffer + purb->iso_frame_desc[i].offset); leap = 0; @@ -226,7 +226,7 @@ for (i = 0; i < purb->number_of_packets; i++) { more)) much = 16 * more; - p2 = (__u8 *)paudio_buffer->pto; + p2 = (u8 *)paudio_buffer->pto; for (j = 0; j < (much/16); j++) { newaudio = ((int) *p1) - 128; @@ -256,7 +256,7 @@ for (i = 0; i < purb->number_of_packets; i++) { #else /*!UPSAMPLE*/ if (much > (2 * more)) much = 2 * more; - p2 = (__u8 *)paudio_buffer->pto; + p2 = (u8 *)paudio_buffer->pto; for (j = 0; j < (much / 2); j++) { tmp = ((int) *p1) - 128; -- cgit v1.2.3 From f8cc1e9373c253902a219ec805977d3b4f16a86c Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 3 Feb 2011 13:42:48 +0200 Subject: staging/easycap: don't shadow rc variable from macros rc is used extensively in code as return code variable so it is better not shadowing it in macros Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index b282b0b06986..df0440d5d48f 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -596,19 +596,19 @@ struct signed_div_result { */ /*---------------------------------------------------------------------------*/ #define GET(X, Y, Z) do { \ - int rc; \ + int __rc; \ *(Z) = (u16)0; \ - rc = regget(X, Y, Z); \ - if (0 > rc) { \ - JOT(8, ":-(%i\n", __LINE__); return(rc); \ + __rc = regget(X, Y, Z); \ + if (0 > __rc) { \ + JOT(8, ":-(%i\n", __LINE__); return __rc; \ } \ } while (0) #define SET(X, Y, Z) do { \ - int rc; \ - rc = regset(X, Y, Z); \ - if (0 > rc) { \ - JOT(8, ":-(%i\n", __LINE__); return(rc); \ + int __rc; \ + __rc = regset(X, Y, Z); \ + if (0 > __rc) { \ + JOT(8, ":-(%i\n", __LINE__); return __rc; \ } \ } while (0) /*---------------------------------------------------------------------------*/ -- cgit v1.2.3 From 7863ff276d2a151aaf1b4ad7798ff2610e7b2996 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 3 Feb 2011 13:42:49 +0200 Subject: staging/easycap: kill declaration of not existing variables Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index df0440d5d48f..dfda1008532f 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -690,11 +690,7 @@ extern struct easycap_format easycap_format[]; extern struct v4l2_queryctrl easycap_control[]; extern struct usb_driver easycap_usb_driver; extern struct easycap_dongle easycapdc60_dongle[]; -#ifndef CONFIG_EASYCAP_OSS -extern struct snd_pcm_ops easycap_alsa_ops; -extern struct snd_pcm_hardware easycap_pcm_hardware; -extern struct snd_card *psnd_card; -#else /* CONFIG_EASYCAP_OSS */ +#ifdef CONFIG_EASYCAP_OSS extern struct usb_class_driver easyoss_class; extern const struct file_operations easyoss_fops; #endif /* !CONFIG_EASYCAP_OSS */ -- cgit v1.2.3 From 30a2cb350fcc34f36f86ecf4a5505f02e6810727 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 3 Feb 2011 13:42:50 +0200 Subject: stagine/easycap: make easyoss_fops static easyoss_fops are only accessed from within easycap_sound_oss file Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 1 - drivers/staging/easycap/easycap_sound_oss.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index dfda1008532f..da77e3ee6230 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -692,7 +692,6 @@ extern struct usb_driver easycap_usb_driver; extern struct easycap_dongle easycapdc60_dongle[]; #ifdef CONFIG_EASYCAP_OSS extern struct usb_class_driver easyoss_class; -extern const struct file_operations easyoss_fops; #endif /* !CONFIG_EASYCAP_OSS */ #endif /* !__EASYCAP_H__ */ diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c index 7acdd8ff72e4..ab1b3ccf4147 100644 --- a/drivers/staging/easycap/easycap_sound_oss.c +++ b/drivers/staging/easycap/easycap_sound_oss.c @@ -1002,7 +1002,7 @@ return 0; } /*****************************************************************************/ -const struct file_operations easyoss_fops = { +static const struct file_operations easyoss_fops = { .owner = THIS_MODULE, .open = easyoss_open, .release = easyoss_release, -- cgit v1.2.3 From 7dcef374d17fd20ecd96b1aeccafe8a4a8c15740 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 3 Feb 2011 13:42:51 +0200 Subject: staging/easycap: add level 1 tabs in usb_probe/disconnect function Add first level indentation before revamping the functions This of course breaks 80 characters limit but it will be fixed through the revamp Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_main.c | 2318 ++++++++++++++++---------------- 1 file changed, 1159 insertions(+), 1159 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 58cfa409e914..396f56b1e419 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -3145,139 +3145,139 @@ static const struct v4l2_file_operations v4l2_fops = { static int easycap_usb_probe(struct usb_interface *pusb_interface, const struct usb_device_id *pusb_device_id) { -struct usb_device *pusb_device, *pusb_device1; -struct usb_host_interface *pusb_host_interface; -struct usb_endpoint_descriptor *pepd; -struct usb_interface_descriptor *pusb_interface_descriptor; -struct usb_interface_assoc_descriptor *pusb_interface_assoc_descriptor; -struct urb *purb; -struct easycap *peasycap; -int ndong; -struct data_urb *pdata_urb; -size_t wMaxPacketSize; -int ISOCwMaxPacketSize; -int BULKwMaxPacketSize; -int INTwMaxPacketSize; -int CTRLwMaxPacketSize; -u8 bEndpointAddress; -u8 ISOCbEndpointAddress; -u8 INTbEndpointAddress; -int isin, i, j, k, m, rc; -u8 bInterfaceNumber; -u8 bInterfaceClass; -u8 bInterfaceSubClass; -void *pbuf; -int okalt[8], isokalt; -int okepn[8]; -int okmps[8]; -int maxpacketsize; -u16 mask; -s32 value; -struct easycap_format *peasycap_format; + struct usb_device *pusb_device, *pusb_device1; + struct usb_host_interface *pusb_host_interface; + struct usb_endpoint_descriptor *pepd; + struct usb_interface_descriptor *pusb_interface_descriptor; + struct usb_interface_assoc_descriptor *pusb_interface_assoc_descriptor; + struct urb *purb; + struct easycap *peasycap; + int ndong; + struct data_urb *pdata_urb; + size_t wMaxPacketSize; + int ISOCwMaxPacketSize; + int BULKwMaxPacketSize; + int INTwMaxPacketSize; + int CTRLwMaxPacketSize; + u8 bEndpointAddress; + u8 ISOCbEndpointAddress; + u8 INTbEndpointAddress; + int isin, i, j, k, m, rc; + u8 bInterfaceNumber; + u8 bInterfaceClass; + u8 bInterfaceSubClass; + void *pbuf; + int okalt[8], isokalt; + int okepn[8]; + int okmps[8]; + int maxpacketsize; + u16 mask; + s32 value; + struct easycap_format *peasycap_format; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #ifdef EASYCAP_IS_VIDEODEV_CLIENT #ifdef EASYCAP_NEEDS_V4L2_DEVICE_H -struct v4l2_device *pv4l2_device; + struct v4l2_device *pv4l2_device; #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /* setup modules params */ -if (NULL == pusb_interface) { - SAY("ERROR: pusb_interface is NULL\n"); - return -EFAULT; -} + if (NULL == pusb_interface) { + SAY("ERROR: pusb_interface is NULL\n"); + return -EFAULT; + } /*---------------------------------------------------------------------------*/ /* * GET POINTER TO STRUCTURE usb_device */ /*---------------------------------------------------------------------------*/ -pusb_device1 = container_of(pusb_interface->dev.parent, - struct usb_device, dev); -if (NULL == pusb_device1) { - SAY("ERROR: pusb_device1 is NULL\n"); - return -EFAULT; -} -pusb_device = usb_get_dev(pusb_device1); -if (NULL == pusb_device) { - SAY("ERROR: pusb_device is NULL\n"); - return -EFAULT; -} -if ((unsigned long int)pusb_device1 != (unsigned long int)pusb_device) { - JOT(4, "ERROR: pusb_device1 != pusb_device\n"); - return -EFAULT; -} -JOT(4, "bNumConfigurations=%i\n", pusb_device->descriptor.bNumConfigurations); + pusb_device1 = container_of(pusb_interface->dev.parent, + struct usb_device, dev); + if (NULL == pusb_device1) { + SAY("ERROR: pusb_device1 is NULL\n"); + return -EFAULT; + } + pusb_device = usb_get_dev(pusb_device1); + if (NULL == pusb_device) { + SAY("ERROR: pusb_device is NULL\n"); + return -EFAULT; + } + if ((unsigned long int)pusb_device1 != (unsigned long int)pusb_device) { + JOT(4, "ERROR: pusb_device1 != pusb_device\n"); + return -EFAULT; + } + JOT(4, "bNumConfigurations=%i\n", pusb_device->descriptor.bNumConfigurations); /*---------------------------------------------------------------------------*/ -pusb_host_interface = pusb_interface->cur_altsetting; -if (NULL == pusb_host_interface) { - SAY("ERROR: pusb_host_interface is NULL\n"); - return -EFAULT; -} -pusb_interface_descriptor = &(pusb_host_interface->desc); -if (NULL == pusb_interface_descriptor) { - SAY("ERROR: pusb_interface_descriptor is NULL\n"); - return -EFAULT; -} + pusb_host_interface = pusb_interface->cur_altsetting; + if (NULL == pusb_host_interface) { + SAY("ERROR: pusb_host_interface is NULL\n"); + return -EFAULT; + } + pusb_interface_descriptor = &(pusb_host_interface->desc); + if (NULL == pusb_interface_descriptor) { + SAY("ERROR: pusb_interface_descriptor is NULL\n"); + return -EFAULT; + } /*---------------------------------------------------------------------------*/ /* * GET PROPERTIES OF PROBED INTERFACE */ /*---------------------------------------------------------------------------*/ -bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber; -bInterfaceClass = pusb_interface_descriptor->bInterfaceClass; -bInterfaceSubClass = pusb_interface_descriptor->bInterfaceSubClass; - -JOT(4, "intf[%i]: pusb_interface->num_altsetting=%i\n", - bInterfaceNumber, pusb_interface->num_altsetting); -JOT(4, "intf[%i]: pusb_interface->cur_altsetting - " - "pusb_interface->altsetting=%li\n", bInterfaceNumber, - (long int)(pusb_interface->cur_altsetting - - pusb_interface->altsetting)); -switch (bInterfaceClass) { -case USB_CLASS_AUDIO: { - JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_AUDIO\n", - bInterfaceNumber, bInterfaceClass); break; + bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber; + bInterfaceClass = pusb_interface_descriptor->bInterfaceClass; + bInterfaceSubClass = pusb_interface_descriptor->bInterfaceSubClass; + + JOT(4, "intf[%i]: pusb_interface->num_altsetting=%i\n", + bInterfaceNumber, pusb_interface->num_altsetting); + JOT(4, "intf[%i]: pusb_interface->cur_altsetting - " + "pusb_interface->altsetting=%li\n", bInterfaceNumber, + (long int)(pusb_interface->cur_altsetting - + pusb_interface->altsetting)); + switch (bInterfaceClass) { + case USB_CLASS_AUDIO: { + JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_AUDIO\n", + bInterfaceNumber, bInterfaceClass); break; + } + case USB_CLASS_VIDEO: { + JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VIDEO\n", + bInterfaceNumber, bInterfaceClass); break; + } + case USB_CLASS_VENDOR_SPEC: { + JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VENDOR_SPEC\n", + bInterfaceNumber, bInterfaceClass); break; + } + default: + break; } -case USB_CLASS_VIDEO: { - JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VIDEO\n", - bInterfaceNumber, bInterfaceClass); break; + switch (bInterfaceSubClass) { + case 0x01: { + JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOCONTROL\n", + bInterfaceNumber, bInterfaceSubClass); break; } -case USB_CLASS_VENDOR_SPEC: { - JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VENDOR_SPEC\n", - bInterfaceNumber, bInterfaceClass); break; + case 0x02: { + JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOSTREAMING\n", + bInterfaceNumber, bInterfaceSubClass); break; + } + case 0x03: { + JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=MIDISTREAMING\n", + bInterfaceNumber, bInterfaceSubClass); break; + } + default: + break; } -default: - break; -} -switch (bInterfaceSubClass) { -case 0x01: { - JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOCONTROL\n", - bInterfaceNumber, bInterfaceSubClass); break; -} -case 0x02: { - JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOSTREAMING\n", - bInterfaceNumber, bInterfaceSubClass); break; -} -case 0x03: { - JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=MIDISTREAMING\n", - bInterfaceNumber, bInterfaceSubClass); break; -} -default: - break; -} /*---------------------------------------------------------------------------*/ -pusb_interface_assoc_descriptor = pusb_interface->intf_assoc; -if (NULL != pusb_interface_assoc_descriptor) { - JOT(4, "intf[%i]: bFirstInterface=0x%02X bInterfaceCount=0x%02X\n", - bInterfaceNumber, - pusb_interface_assoc_descriptor->bFirstInterface, - pusb_interface_assoc_descriptor->bInterfaceCount); -} else { -JOT(4, "intf[%i]: pusb_interface_assoc_descriptor is NULL\n", - bInterfaceNumber); -} + pusb_interface_assoc_descriptor = pusb_interface->intf_assoc; + if (NULL != pusb_interface_assoc_descriptor) { + JOT(4, "intf[%i]: bFirstInterface=0x%02X bInterfaceCount=0x%02X\n", + bInterfaceNumber, + pusb_interface_assoc_descriptor->bFirstInterface, + pusb_interface_assoc_descriptor->bInterfaceCount); + } else { + JOT(4, "intf[%i]: pusb_interface_assoc_descriptor is NULL\n", + bInterfaceNumber); + } /*---------------------------------------------------------------------------*/ /* * A NEW struct easycap IS ALWAYS ALLOCATED WHEN INTERFACE 0 IS PROBED. @@ -3289,19 +3289,19 @@ JOT(4, "intf[%i]: pusb_interface_assoc_descriptor is NULL\n", * INTERFACES 1 AND 2 ARE PROBED. */ /*---------------------------------------------------------------------------*/ -if (0 == bInterfaceNumber) { - peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL); - if (NULL == peasycap) { - SAY("ERROR: Could not allocate peasycap\n"); - return -ENOMEM; - } - SAM("allocated 0x%08lX=peasycap\n", (unsigned long int) peasycap); + if (0 == bInterfaceNumber) { + peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL); + if (NULL == peasycap) { + SAY("ERROR: Could not allocate peasycap\n"); + return -ENOMEM; + } + SAM("allocated 0x%08lX=peasycap\n", (unsigned long int) peasycap); /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #ifdef EASYCAP_IS_VIDEODEV_CLIENT - SAM("where 0x%08lX=&peasycap->video_device\n", + SAM("where 0x%08lX=&peasycap->video_device\n", (unsigned long int) &peasycap->video_device); #ifdef EASYCAP_NEEDS_V4L2_DEVICE_H - SAM("and 0x%08lX=&peasycap->v4l2_device\n", + SAM("and 0x%08lX=&peasycap->v4l2_device\n", (unsigned long int) &peasycap->v4l2_device); #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ @@ -3311,24 +3311,24 @@ if (0 == bInterfaceNumber) { * PERFORM URGENT INTIALIZATIONS ... */ /*---------------------------------------------------------------------------*/ - peasycap->minor = -1; - strcpy(&peasycap->telltale[0], TELLTALE); - kref_init(&peasycap->kref); - JOM(8, "intf[%i]: after kref_init(..._video) " - "%i=peasycap->kref.refcount.counter\n", - bInterfaceNumber, peasycap->kref.refcount.counter); + peasycap->minor = -1; + strcpy(&peasycap->telltale[0], TELLTALE); + kref_init(&peasycap->kref); + JOM(8, "intf[%i]: after kref_init(..._video) " + "%i=peasycap->kref.refcount.counter\n", + bInterfaceNumber, peasycap->kref.refcount.counter); - /* module params */ - peasycap->gain = (s8)clamp(easycap_gain, 0, 31); + /* module params */ + peasycap->gain = (s8)clamp(easycap_gain, 0, 31); - init_waitqueue_head(&peasycap->wq_video); - init_waitqueue_head(&peasycap->wq_audio); - init_waitqueue_head(&peasycap->wq_trigger); + init_waitqueue_head(&peasycap->wq_video); + init_waitqueue_head(&peasycap->wq_audio); + init_waitqueue_head(&peasycap->wq_trigger); - if (mutex_lock_interruptible(&mutex_dongle)) { - SAY("ERROR: cannot down mutex_dongle\n"); - return -ERESTARTSYS; - } else { + if (mutex_lock_interruptible(&mutex_dongle)) { + SAY("ERROR: cannot down mutex_dongle\n"); + return -ERESTARTSYS; + } else { /*---------------------------------------------------------------------------*/ /* * FOR INTERFACES 1 AND 2 THE POINTER peasycap WILL NEED TO @@ -3339,193 +3339,193 @@ if (0 == bInterfaceNumber) { * EASYCAPs ARE PLUGGED IN SIMULTANEOUSLY. */ /*---------------------------------------------------------------------------*/ - for (ndong = 0; ndong < DONGLE_MANY; ndong++) { - if ((NULL == easycapdc60_dongle[ndong].peasycap) && - (!mutex_is_locked(&easycapdc60_dongle - [ndong].mutex_video)) && - (!mutex_is_locked(&easycapdc60_dongle - [ndong].mutex_audio))) { - easycapdc60_dongle[ndong].peasycap = peasycap; - peasycap->isdongle = ndong; - JOM(8, "intf[%i]: peasycap-->easycap" - "_dongle[%i].peasycap\n", - bInterfaceNumber, ndong); - break; + for (ndong = 0; ndong < DONGLE_MANY; ndong++) { + if ((NULL == easycapdc60_dongle[ndong].peasycap) && + (!mutex_is_locked(&easycapdc60_dongle + [ndong].mutex_video)) && + (!mutex_is_locked(&easycapdc60_dongle + [ndong].mutex_audio))) { + easycapdc60_dongle[ndong].peasycap = peasycap; + peasycap->isdongle = ndong; + JOM(8, "intf[%i]: peasycap-->easycap" + "_dongle[%i].peasycap\n", + bInterfaceNumber, ndong); + break; + } + } + if (DONGLE_MANY <= ndong) { + SAM("ERROR: too many dongles\n"); + mutex_unlock(&mutex_dongle); + return -ENOMEM; } - } - if (DONGLE_MANY <= ndong) { - SAM("ERROR: too many dongles\n"); mutex_unlock(&mutex_dongle); - return -ENOMEM; } - mutex_unlock(&mutex_dongle); - } - peasycap->allocation_video_struct = sizeof(struct easycap); - peasycap->allocation_video_page = 0; - peasycap->allocation_video_urb = 0; - peasycap->allocation_audio_struct = 0; - peasycap->allocation_audio_page = 0; - peasycap->allocation_audio_urb = 0; + peasycap->allocation_video_struct = sizeof(struct easycap); + peasycap->allocation_video_page = 0; + peasycap->allocation_video_urb = 0; + peasycap->allocation_audio_struct = 0; + peasycap->allocation_audio_page = 0; + peasycap->allocation_audio_urb = 0; /*---------------------------------------------------------------------------*/ /* * ... AND FURTHER INITIALIZE THE STRUCTURE */ /*---------------------------------------------------------------------------*/ - peasycap->pusb_device = pusb_device; - peasycap->pusb_interface = pusb_interface; + peasycap->pusb_device = pusb_device; + peasycap->pusb_interface = pusb_interface; - peasycap->ilk = 0; - peasycap->microphone = false; + peasycap->ilk = 0; + peasycap->microphone = false; - peasycap->video_interface = -1; - peasycap->video_altsetting_on = -1; - peasycap->video_altsetting_off = -1; - peasycap->video_endpointnumber = -1; - peasycap->video_isoc_maxframesize = -1; - peasycap->video_isoc_buffer_size = -1; + peasycap->video_interface = -1; + peasycap->video_altsetting_on = -1; + peasycap->video_altsetting_off = -1; + peasycap->video_endpointnumber = -1; + peasycap->video_isoc_maxframesize = -1; + peasycap->video_isoc_buffer_size = -1; - peasycap->audio_interface = -1; - peasycap->audio_altsetting_on = -1; - peasycap->audio_altsetting_off = -1; - peasycap->audio_endpointnumber = -1; - peasycap->audio_isoc_maxframesize = -1; - peasycap->audio_isoc_buffer_size = -1; + peasycap->audio_interface = -1; + peasycap->audio_altsetting_on = -1; + peasycap->audio_altsetting_off = -1; + peasycap->audio_endpointnumber = -1; + peasycap->audio_isoc_maxframesize = -1; + peasycap->audio_isoc_buffer_size = -1; - peasycap->frame_buffer_many = FRAME_BUFFER_MANY; + peasycap->frame_buffer_many = FRAME_BUFFER_MANY; - for (k = 0; k < INPUT_MANY; k++) - peasycap->lost[k] = 0; - peasycap->skip = 0; - peasycap->skipped = 0; - peasycap->offerfields = 0; + for (k = 0; k < INPUT_MANY; k++) + peasycap->lost[k] = 0; + peasycap->skip = 0; + peasycap->skipped = 0; + peasycap->offerfields = 0; /*---------------------------------------------------------------------------*/ /* * DYNAMICALLY FILL IN THE AVAILABLE FORMATS ... */ /*---------------------------------------------------------------------------*/ - rc = fillin_formats(); - if (0 > rc) { - SAM("ERROR: fillin_formats() returned %i\n", rc); - return -EFAULT; - } - JOM(4, "%i formats available\n", rc); + rc = fillin_formats(); + if (0 > rc) { + SAM("ERROR: fillin_formats() returned %i\n", rc); + return -EFAULT; + } + JOM(4, "%i formats available\n", rc); /*---------------------------------------------------------------------------*/ /* * ... AND POPULATE easycap.inputset[] */ /*---------------------------------------------------------------------------*/ - for (k = 0; k < INPUT_MANY; k++) { - peasycap->inputset[k].input_ok = 0; - peasycap->inputset[k].standard_offset_ok = 0; - peasycap->inputset[k].format_offset_ok = 0; - peasycap->inputset[k].brightness_ok = 0; - peasycap->inputset[k].contrast_ok = 0; - peasycap->inputset[k].saturation_ok = 0; - peasycap->inputset[k].hue_ok = 0; - } - if (true == peasycap->ntsc) { - i = 0; - m = 0; - mask = 0; - while (0xFFFF != easycap_standard[i].mask) { - if (NTSC_M == easycap_standard[i]. - v4l2_standard.index) { - m++; - for (k = 0; k < INPUT_MANY; k++) { - peasycap->inputset[k]. - standard_offset = i; + for (k = 0; k < INPUT_MANY; k++) { + peasycap->inputset[k].input_ok = 0; + peasycap->inputset[k].standard_offset_ok = 0; + peasycap->inputset[k].format_offset_ok = 0; + peasycap->inputset[k].brightness_ok = 0; + peasycap->inputset[k].contrast_ok = 0; + peasycap->inputset[k].saturation_ok = 0; + peasycap->inputset[k].hue_ok = 0; + } + if (true == peasycap->ntsc) { + i = 0; + m = 0; + mask = 0; + while (0xFFFF != easycap_standard[i].mask) { + if (NTSC_M == easycap_standard[i]. + v4l2_standard.index) { + m++; + for (k = 0; k < INPUT_MANY; k++) { + peasycap->inputset[k]. + standard_offset = i; + } + mask = easycap_standard[i].mask; } - mask = easycap_standard[i].mask; + i++; + } + } else { + i = 0; + m = 0; + mask = 0; + while (0xFFFF != easycap_standard[i].mask) { + if (PAL_BGHIN == easycap_standard[i]. + v4l2_standard.index) { + m++; + for (k = 0; k < INPUT_MANY; k++) { + peasycap->inputset[k]. + standard_offset = i; + } + mask = easycap_standard[i].mask; + } + i++; } - i++; } - } else { + + if (1 != m) { + SAM("MISTAKE: easycap.inputset[].standard_offset " + "unpopulated, %i=m\n", m); + return -ENOENT; + } + + peasycap_format = &easycap_format[0]; i = 0; m = 0; - mask = 0; - while (0xFFFF != easycap_standard[i].mask) { - if (PAL_BGHIN == easycap_standard[i]. - v4l2_standard.index) { + while (0 != peasycap_format->v4l2_format.fmt.pix.width) { + if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && + (peasycap_format-> + v4l2_format.fmt.pix.field == + V4L2_FIELD_NONE) && + (peasycap_format-> + v4l2_format.fmt.pix.pixelformat == + V4L2_PIX_FMT_UYVY) && + (peasycap_format-> + v4l2_format.fmt.pix.width == + 640) && + (peasycap_format-> + v4l2_format.fmt.pix.height == 480)) { m++; - for (k = 0; k < INPUT_MANY; k++) { - peasycap->inputset[k]. - standard_offset = i; - } - mask = easycap_standard[i].mask; + for (k = 0; k < INPUT_MANY; k++) + peasycap->inputset[k].format_offset = i; + break; } - i++; + peasycap_format++; + i++; } - } - - if (1 != m) { - SAM("MISTAKE: easycap.inputset[].standard_offset " - "unpopulated, %i=m\n", m); + if (1 != m) { + SAM("MISTAKE: easycap.inputset[].format_offset unpopulated\n"); return -ENOENT; - } - - peasycap_format = &easycap_format[0]; - i = 0; - m = 0; - while (0 != peasycap_format->v4l2_format.fmt.pix.width) { - if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && - (peasycap_format-> - v4l2_format.fmt.pix.field == - V4L2_FIELD_NONE) && - (peasycap_format-> - v4l2_format.fmt.pix.pixelformat == - V4L2_PIX_FMT_UYVY) && - (peasycap_format-> - v4l2_format.fmt.pix.width == - 640) && - (peasycap_format-> - v4l2_format.fmt.pix.height == 480)) { - m++; - for (k = 0; k < INPUT_MANY; k++) - peasycap->inputset[k].format_offset = i; - break; } - peasycap_format++; - i++; - } - if (1 != m) { - SAM("MISTAKE: easycap.inputset[].format_offset unpopulated\n"); - return -ENOENT; - } - i = 0; - m = 0; - while (0xFFFFFFFF != easycap_control[i].id) { - value = easycap_control[i].default_value; - if (V4L2_CID_BRIGHTNESS == easycap_control[i].id) { - m++; - for (k = 0; k < INPUT_MANY; k++) - peasycap->inputset[k].brightness = value; - } else if (V4L2_CID_CONTRAST == easycap_control[i].id) { - m++; - for (k = 0; k < INPUT_MANY; k++) - peasycap->inputset[k].contrast = value; - } else if (V4L2_CID_SATURATION == easycap_control[i].id) { - m++; - for (k = 0; k < INPUT_MANY; k++) - peasycap->inputset[k].saturation = value; - } else if (V4L2_CID_HUE == easycap_control[i].id) { - m++; - for (k = 0; k < INPUT_MANY; k++) - peasycap->inputset[k].hue = value; + i = 0; + m = 0; + while (0xFFFFFFFF != easycap_control[i].id) { + value = easycap_control[i].default_value; + if (V4L2_CID_BRIGHTNESS == easycap_control[i].id) { + m++; + for (k = 0; k < INPUT_MANY; k++) + peasycap->inputset[k].brightness = value; + } else if (V4L2_CID_CONTRAST == easycap_control[i].id) { + m++; + for (k = 0; k < INPUT_MANY; k++) + peasycap->inputset[k].contrast = value; + } else if (V4L2_CID_SATURATION == easycap_control[i].id) { + m++; + for (k = 0; k < INPUT_MANY; k++) + peasycap->inputset[k].saturation = value; + } else if (V4L2_CID_HUE == easycap_control[i].id) { + m++; + for (k = 0; k < INPUT_MANY; k++) + peasycap->inputset[k].hue = value; + } + i++; } - i++; - } - if (4 != m) { - SAM("MISTAKE: easycap.inputset[].brightness,... " - "underpopulated\n"); - return -ENOENT; - } - for (k = 0; k < INPUT_MANY; k++) - peasycap->inputset[k].input = k; - JOM(4, "populated easycap.inputset[]\n"); - JOM(4, "finished initialization\n"); -} else { + if (4 != m) { + SAM("MISTAKE: easycap.inputset[].brightness,... " + "underpopulated\n"); + return -ENOENT; + } + for (k = 0; k < INPUT_MANY; k++) + peasycap->inputset[k].input = k; + JOM(4, "populated easycap.inputset[]\n"); + JOM(4, "finished initialization\n"); + } else { /*---------------------------------------------------------------------------*/ /* * FIXME @@ -3534,25 +3534,25 @@ if (0 == bInterfaceNumber) { * THE ADDRESS OF peasycap->pusb_device IS RELUCTANTLY USED FOR THIS PURPOSE. */ /*---------------------------------------------------------------------------*/ - for (ndong = 0; ndong < DONGLE_MANY; ndong++) { - if (pusb_device == easycapdc60_dongle[ndong].peasycap-> - pusb_device) { - peasycap = easycapdc60_dongle[ndong].peasycap; - JOT(8, "intf[%i]: easycapdc60_dongle[%i].peasycap-->" - "peasycap\n", bInterfaceNumber, ndong); - break; + for (ndong = 0; ndong < DONGLE_MANY; ndong++) { + if (pusb_device == easycapdc60_dongle[ndong].peasycap-> + pusb_device) { + peasycap = easycapdc60_dongle[ndong].peasycap; + JOT(8, "intf[%i]: easycapdc60_dongle[%i].peasycap-->" + "peasycap\n", bInterfaceNumber, ndong); + break; + } + } + if (DONGLE_MANY <= ndong) { + SAY("ERROR: peasycap is unknown when probing interface %i\n", + bInterfaceNumber); + return -ENODEV; + } + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL when probing interface %i\n", + bInterfaceNumber); + return -ENODEV; } - } - if (DONGLE_MANY <= ndong) { - SAY("ERROR: peasycap is unknown when probing interface %i\n", - bInterfaceNumber); - return -ENODEV; - } - if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL when probing interface %i\n", - bInterfaceNumber); - return -ENODEV; - } #ifndef EASYCAP_IS_VIDEODEV_CLIENT # /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ @@ -3566,553 +3566,553 @@ if (0 == bInterfaceNumber) { * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED. */ /*---------------------------------------------------------------------------*/ - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - pv4l2_device = usb_get_intfdata(pusb_interface); - if (NULL == pv4l2_device) { - SAY("ERROR: pv4l2_device is NULL\n"); - return -ENODEV; + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + pv4l2_device = usb_get_intfdata(pusb_interface); + if (NULL == pv4l2_device) { + SAY("ERROR: pv4l2_device is NULL\n"); + return -ENODEV; + } + peasycap = (struct easycap *) + container_of(pv4l2_device, struct easycap, v4l2_device); } - peasycap = (struct easycap *) - container_of(pv4l2_device, struct easycap, v4l2_device); - } #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ } /*---------------------------------------------------------------------------*/ -if ((USB_CLASS_VIDEO == bInterfaceClass) || - (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) { - if (-1 == peasycap->video_interface) { - peasycap->video_interface = bInterfaceNumber; - JOM(4, "setting peasycap->video_interface=%i\n", + if ((USB_CLASS_VIDEO == bInterfaceClass) || + (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) { + if (-1 == peasycap->video_interface) { + peasycap->video_interface = bInterfaceNumber; + JOM(4, "setting peasycap->video_interface=%i\n", + peasycap->video_interface); + } else { + if (peasycap->video_interface != bInterfaceNumber) { + SAM("ERROR: attempting to reset " + "peasycap->video_interface\n"); + SAM("...... continuing with " + "%i=peasycap->video_interface\n", peasycap->video_interface); - } else { - if (peasycap->video_interface != bInterfaceNumber) { - SAM("ERROR: attempting to reset " - "peasycap->video_interface\n"); - SAM("...... continuing with " - "%i=peasycap->video_interface\n", - peasycap->video_interface); + } } - } -} else if ((USB_CLASS_AUDIO == bInterfaceClass) && - (0x02 == bInterfaceSubClass)) { - if (-1 == peasycap->audio_interface) { - peasycap->audio_interface = bInterfaceNumber; - JOM(4, "setting peasycap->audio_interface=%i\n", - peasycap->audio_interface); - } else { - if (peasycap->audio_interface != bInterfaceNumber) { - SAM("ERROR: attempting to reset " - "peasycap->audio_interface\n"); - SAM("...... continuing with " - "%i=peasycap->audio_interface\n", - peasycap->audio_interface); + } else if ((USB_CLASS_AUDIO == bInterfaceClass) && + (0x02 == bInterfaceSubClass)) { + if (-1 == peasycap->audio_interface) { + peasycap->audio_interface = bInterfaceNumber; + JOM(4, "setting peasycap->audio_interface=%i\n", + peasycap->audio_interface); + } else { + if (peasycap->audio_interface != bInterfaceNumber) { + SAM("ERROR: attempting to reset " + "peasycap->audio_interface\n"); + SAM("...... continuing with " + "%i=peasycap->audio_interface\n", + peasycap->audio_interface); + } } } -} /*---------------------------------------------------------------------------*/ /* * INVESTIGATE ALL ALTSETTINGS. * DONE IN DETAIL BECAUSE USB DEVICE 05e1:0408 HAS DISPARATE INCARNATIONS. */ /*---------------------------------------------------------------------------*/ -isokalt = 0; - -for (i = 0; i < pusb_interface->num_altsetting; i++) { - pusb_host_interface = &(pusb_interface->altsetting[i]); - if (NULL == pusb_host_interface) { - SAM("ERROR: pusb_host_interface is NULL\n"); - return -EFAULT; - } - pusb_interface_descriptor = &(pusb_host_interface->desc); - if (NULL == pusb_interface_descriptor) { - SAM("ERROR: pusb_interface_descriptor is NULL\n"); - return -EFAULT; - } + isokalt = 0; - JOM(4, "intf[%i]alt[%i]: desc.bDescriptorType=0x%02X\n", - bInterfaceNumber, i, pusb_interface_descriptor->bDescriptorType); - JOM(4, "intf[%i]alt[%i]: desc.bInterfaceNumber=0x%02X\n", - bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceNumber); - JOM(4, "intf[%i]alt[%i]: desc.bAlternateSetting=0x%02X\n", - bInterfaceNumber, i, pusb_interface_descriptor->bAlternateSetting); - JOM(4, "intf[%i]alt[%i]: desc.bNumEndpoints=0x%02X\n", - bInterfaceNumber, i, pusb_interface_descriptor->bNumEndpoints); - JOM(4, "intf[%i]alt[%i]: desc.bInterfaceClass=0x%02X\n", - bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceClass); - JOM(4, "intf[%i]alt[%i]: desc.bInterfaceSubClass=0x%02X\n", - bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceSubClass); - JOM(4, "intf[%i]alt[%i]: desc.bInterfaceProtocol=0x%02X\n", - bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceProtocol); - JOM(4, "intf[%i]alt[%i]: desc.iInterface=0x%02X\n", - bInterfaceNumber, i, pusb_interface_descriptor->iInterface); - - ISOCwMaxPacketSize = -1; - BULKwMaxPacketSize = -1; - INTwMaxPacketSize = -1; - CTRLwMaxPacketSize = -1; - ISOCbEndpointAddress = 0; - INTbEndpointAddress = 0; - - if (0 == pusb_interface_descriptor->bNumEndpoints) - JOM(4, "intf[%i]alt[%i] has no endpoints\n", - bInterfaceNumber, i); -/*---------------------------------------------------------------------------*/ - for (j = 0; j < pusb_interface_descriptor->bNumEndpoints; j++) { - pepd = &(pusb_host_interface->endpoint[j].desc); - if (NULL == pepd) { - SAM("ERROR: pepd is NULL.\n"); - SAM("...... skipping\n"); - continue; + for (i = 0; i < pusb_interface->num_altsetting; i++) { + pusb_host_interface = &(pusb_interface->altsetting[i]); + if (NULL == pusb_host_interface) { + SAM("ERROR: pusb_host_interface is NULL\n"); + return -EFAULT; } - wMaxPacketSize = le16_to_cpu(pepd->wMaxPacketSize); - bEndpointAddress = pepd->bEndpointAddress; - - JOM(4, "intf[%i]alt[%i]end[%i]: bEndpointAddress=0x%X\n", - bInterfaceNumber, i, j, - pepd->bEndpointAddress); - JOM(4, "intf[%i]alt[%i]end[%i]: bmAttributes=0x%X\n", - bInterfaceNumber, i, j, - pepd->bmAttributes); - JOM(4, "intf[%i]alt[%i]end[%i]: wMaxPacketSize=%i\n", - bInterfaceNumber, i, j, - pepd->wMaxPacketSize); - JOM(4, "intf[%i]alt[%i]end[%i]: bInterval=%i\n", - bInterfaceNumber, i, j, - pepd->bInterval); - - if (pepd->bEndpointAddress & USB_DIR_IN) { - JOM(4, "intf[%i]alt[%i]end[%i] is an IN endpoint\n", - bInterfaceNumber, i, j); - isin = 1; - } else { - JOM(4, "intf[%i]alt[%i]end[%i] is an OUT endpoint\n", - bInterfaceNumber, i, j); - SAM("ERROR: OUT endpoint unexpected\n"); - SAM("...... continuing\n"); - isin = 0; + pusb_interface_descriptor = &(pusb_host_interface->desc); + if (NULL == pusb_interface_descriptor) { + SAM("ERROR: pusb_interface_descriptor is NULL\n"); + return -EFAULT; } - if ((pepd->bmAttributes & - USB_ENDPOINT_XFERTYPE_MASK) == - USB_ENDPOINT_XFER_ISOC) { - JOM(4, "intf[%i]alt[%i]end[%i] is an ISOC endpoint\n", - bInterfaceNumber, i, j); - if (isin) { - switch (bInterfaceClass) { - case USB_CLASS_VIDEO: - case USB_CLASS_VENDOR_SPEC: { - if (!peasycap) { - SAM("MISTAKE: " - "peasycap is NULL\n"); - return -EFAULT; - } - if (pepd->wMaxPacketSize) { - if (8 > isokalt) { - okalt[isokalt] = i; - JOM(4, - "%i=okalt[%i]\n", - okalt[isokalt], - isokalt); - okepn[isokalt] = - pepd-> - bEndpointAddress & - 0x0F; - JOM(4, - "%i=okepn[%i]\n", - okepn[isokalt], - isokalt); - okmps[isokalt] = - le16_to_cpu(pepd-> - wMaxPacketSize); - JOM(4, - "%i=okmps[%i]\n", - okmps[isokalt], - isokalt); - isokalt++; + + JOM(4, "intf[%i]alt[%i]: desc.bDescriptorType=0x%02X\n", + bInterfaceNumber, i, pusb_interface_descriptor->bDescriptorType); + JOM(4, "intf[%i]alt[%i]: desc.bInterfaceNumber=0x%02X\n", + bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceNumber); + JOM(4, "intf[%i]alt[%i]: desc.bAlternateSetting=0x%02X\n", + bInterfaceNumber, i, pusb_interface_descriptor->bAlternateSetting); + JOM(4, "intf[%i]alt[%i]: desc.bNumEndpoints=0x%02X\n", + bInterfaceNumber, i, pusb_interface_descriptor->bNumEndpoints); + JOM(4, "intf[%i]alt[%i]: desc.bInterfaceClass=0x%02X\n", + bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceClass); + JOM(4, "intf[%i]alt[%i]: desc.bInterfaceSubClass=0x%02X\n", + bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceSubClass); + JOM(4, "intf[%i]alt[%i]: desc.bInterfaceProtocol=0x%02X\n", + bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceProtocol); + JOM(4, "intf[%i]alt[%i]: desc.iInterface=0x%02X\n", + bInterfaceNumber, i, pusb_interface_descriptor->iInterface); + + ISOCwMaxPacketSize = -1; + BULKwMaxPacketSize = -1; + INTwMaxPacketSize = -1; + CTRLwMaxPacketSize = -1; + ISOCbEndpointAddress = 0; + INTbEndpointAddress = 0; + + if (0 == pusb_interface_descriptor->bNumEndpoints) + JOM(4, "intf[%i]alt[%i] has no endpoints\n", + bInterfaceNumber, i); +/*---------------------------------------------------------------------------*/ + for (j = 0; j < pusb_interface_descriptor->bNumEndpoints; j++) { + pepd = &(pusb_host_interface->endpoint[j].desc); + if (NULL == pepd) { + SAM("ERROR: pepd is NULL.\n"); + SAM("...... skipping\n"); + continue; + } + wMaxPacketSize = le16_to_cpu(pepd->wMaxPacketSize); + bEndpointAddress = pepd->bEndpointAddress; + + JOM(4, "intf[%i]alt[%i]end[%i]: bEndpointAddress=0x%X\n", + bInterfaceNumber, i, j, + pepd->bEndpointAddress); + JOM(4, "intf[%i]alt[%i]end[%i]: bmAttributes=0x%X\n", + bInterfaceNumber, i, j, + pepd->bmAttributes); + JOM(4, "intf[%i]alt[%i]end[%i]: wMaxPacketSize=%i\n", + bInterfaceNumber, i, j, + pepd->wMaxPacketSize); + JOM(4, "intf[%i]alt[%i]end[%i]: bInterval=%i\n", + bInterfaceNumber, i, j, + pepd->bInterval); + + if (pepd->bEndpointAddress & USB_DIR_IN) { + JOM(4, "intf[%i]alt[%i]end[%i] is an IN endpoint\n", + bInterfaceNumber, i, j); + isin = 1; + } else { + JOM(4, "intf[%i]alt[%i]end[%i] is an OUT endpoint\n", + bInterfaceNumber, i, j); + SAM("ERROR: OUT endpoint unexpected\n"); + SAM("...... continuing\n"); + isin = 0; + } + if ((pepd->bmAttributes & + USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_ISOC) { + JOM(4, "intf[%i]alt[%i]end[%i] is an ISOC endpoint\n", + bInterfaceNumber, i, j); + if (isin) { + switch (bInterfaceClass) { + case USB_CLASS_VIDEO: + case USB_CLASS_VENDOR_SPEC: { + if (!peasycap) { + SAM("MISTAKE: " + "peasycap is NULL\n"); + return -EFAULT; } - } else { - if (-1 == peasycap-> - video_altsetting_off) { - peasycap-> - video_altsetting_off = - i; - JOM(4, "%i=video_" - "altsetting_off " - "<====\n", - peasycap-> - video_altsetting_off); + if (pepd->wMaxPacketSize) { + if (8 > isokalt) { + okalt[isokalt] = i; + JOM(4, + "%i=okalt[%i]\n", + okalt[isokalt], + isokalt); + okepn[isokalt] = + pepd-> + bEndpointAddress & + 0x0F; + JOM(4, + "%i=okepn[%i]\n", + okepn[isokalt], + isokalt); + okmps[isokalt] = + le16_to_cpu(pepd-> + wMaxPacketSize); + JOM(4, + "%i=okmps[%i]\n", + okmps[isokalt], + isokalt); + isokalt++; + } } else { - SAM("ERROR: peasycap" - "->video_altsetting_" - "off already set\n"); - SAM("...... " - "continuing with " - "%i=peasycap->video_" - "altsetting_off\n", - peasycap-> - video_altsetting_off); + if (-1 == peasycap-> + video_altsetting_off) { + peasycap-> + video_altsetting_off = + i; + JOM(4, "%i=video_" + "altsetting_off " + "<====\n", + peasycap-> + video_altsetting_off); + } else { + SAM("ERROR: peasycap" + "->video_altsetting_" + "off already set\n"); + SAM("...... " + "continuing with " + "%i=peasycap->video_" + "altsetting_off\n", + peasycap-> + video_altsetting_off); + } } - } - break; - } - case USB_CLASS_AUDIO: { - if (0x02 != bInterfaceSubClass) break; - if (!peasycap) { - SAM("MISTAKE: " - "peasycap is NULL\n"); - return -EFAULT; } - if (pepd->wMaxPacketSize) { - if (8 > isokalt) { - okalt[isokalt] = i ; - JOM(4, - "%i=okalt[%i]\n", - okalt[isokalt], - isokalt); - okepn[isokalt] = - pepd-> - bEndpointAddress & - 0x0F; - JOM(4, - "%i=okepn[%i]\n", - okepn[isokalt], - isokalt); - okmps[isokalt] = - le16_to_cpu(pepd-> - wMaxPacketSize); - JOM(4, - "%i=okmps[%i]\n", - okmps[isokalt], - isokalt); - isokalt++; + case USB_CLASS_AUDIO: { + if (0x02 != bInterfaceSubClass) + break; + if (!peasycap) { + SAM("MISTAKE: " + "peasycap is NULL\n"); + return -EFAULT; } - } else { - if (-1 == peasycap-> - audio_altsetting_off) { - peasycap-> - audio_altsetting_off = - i; - JOM(4, "%i=audio_" - "altsetting_off " - "<====\n", - peasycap-> - audio_altsetting_off); + if (pepd->wMaxPacketSize) { + if (8 > isokalt) { + okalt[isokalt] = i ; + JOM(4, + "%i=okalt[%i]\n", + okalt[isokalt], + isokalt); + okepn[isokalt] = + pepd-> + bEndpointAddress & + 0x0F; + JOM(4, + "%i=okepn[%i]\n", + okepn[isokalt], + isokalt); + okmps[isokalt] = + le16_to_cpu(pepd-> + wMaxPacketSize); + JOM(4, + "%i=okmps[%i]\n", + okmps[isokalt], + isokalt); + isokalt++; + } } else { - SAM("ERROR: peasycap" - "->audio_altsetting_" - "off already set\n"); - SAM("...... " - "continuing with " - "%i=peasycap->" - "audio_altsetting_" - "off\n", - peasycap-> - audio_altsetting_off); + if (-1 == peasycap-> + audio_altsetting_off) { + peasycap-> + audio_altsetting_off = + i; + JOM(4, "%i=audio_" + "altsetting_off " + "<====\n", + peasycap-> + audio_altsetting_off); + } else { + SAM("ERROR: peasycap" + "->audio_altsetting_" + "off already set\n"); + SAM("...... " + "continuing with " + "%i=peasycap->" + "audio_altsetting_" + "off\n", + peasycap-> + audio_altsetting_off); + } } - } - break; - } - default: break; + } + default: + break; + } } + } else if ((pepd->bmAttributes & + USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_BULK) { + JOM(4, "intf[%i]alt[%i]end[%i] is a BULK endpoint\n", + bInterfaceNumber, i, j); + } else if ((pepd->bmAttributes & + USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_INT) { + JOM(4, "intf[%i]alt[%i]end[%i] is an INT endpoint\n", + bInterfaceNumber, i, j); + } else { + JOM(4, "intf[%i]alt[%i]end[%i] is a CTRL endpoint\n", + bInterfaceNumber, i, j); + } + if (0 == pepd->wMaxPacketSize) { + JOM(4, "intf[%i]alt[%i]end[%i] " + "has zero packet size\n", + bInterfaceNumber, i, j); } - } else if ((pepd->bmAttributes & - USB_ENDPOINT_XFERTYPE_MASK) == - USB_ENDPOINT_XFER_BULK) { - JOM(4, "intf[%i]alt[%i]end[%i] is a BULK endpoint\n", - bInterfaceNumber, i, j); - } else if ((pepd->bmAttributes & - USB_ENDPOINT_XFERTYPE_MASK) == - USB_ENDPOINT_XFER_INT) { - JOM(4, "intf[%i]alt[%i]end[%i] is an INT endpoint\n", - bInterfaceNumber, i, j); - } else { - JOM(4, "intf[%i]alt[%i]end[%i] is a CTRL endpoint\n", - bInterfaceNumber, i, j); - } - if (0 == pepd->wMaxPacketSize) { - JOM(4, "intf[%i]alt[%i]end[%i] " - "has zero packet size\n", - bInterfaceNumber, i, j); } } -} /*---------------------------------------------------------------------------*/ /* * PERFORM INITIALIZATION OF THE PROBED INTERFACE */ /*---------------------------------------------------------------------------*/ -JOM(4, "initialization begins for interface %i\n", - pusb_interface_descriptor->bInterfaceNumber); -switch (bInterfaceNumber) { + JOM(4, "initialization begins for interface %i\n", + pusb_interface_descriptor->bInterfaceNumber); + switch (bInterfaceNumber) { /*---------------------------------------------------------------------------*/ /* * INTERFACE 0 IS THE VIDEO INTERFACE */ /*---------------------------------------------------------------------------*/ -case 0: { - if (!peasycap) { - SAM("MISTAKE: peasycap is NULL\n"); - return -EFAULT; - } - if (!isokalt) { - SAM("ERROR: no viable video_altsetting_on\n"); - return -ENOENT; - } else { - peasycap->video_altsetting_on = okalt[isokalt - 1]; - JOM(4, "%i=video_altsetting_on <====\n", - peasycap->video_altsetting_on); - } + case 0: { + if (!peasycap) { + SAM("MISTAKE: peasycap is NULL\n"); + return -EFAULT; + } + if (!isokalt) { + SAM("ERROR: no viable video_altsetting_on\n"); + return -ENOENT; + } else { + peasycap->video_altsetting_on = okalt[isokalt - 1]; + JOM(4, "%i=video_altsetting_on <====\n", + peasycap->video_altsetting_on); + } /*---------------------------------------------------------------------------*/ /* * DECIDE THE VIDEO STREAMING PARAMETERS */ /*---------------------------------------------------------------------------*/ - peasycap->video_endpointnumber = okepn[isokalt - 1]; - JOM(4, "%i=video_endpointnumber\n", peasycap->video_endpointnumber); - maxpacketsize = okmps[isokalt - 1]; - if (USB_2_0_MAXPACKETSIZE > maxpacketsize) { - peasycap->video_isoc_maxframesize = maxpacketsize; - } else { - peasycap->video_isoc_maxframesize = - USB_2_0_MAXPACKETSIZE; - } - JOM(4, "%i=video_isoc_maxframesize\n", - peasycap->video_isoc_maxframesize); - if (0 >= peasycap->video_isoc_maxframesize) { - SAM("ERROR: bad video_isoc_maxframesize\n"); - SAM(" possibly because port is USB 1.1\n"); - return -ENOENT; - } - peasycap->video_isoc_framesperdesc = VIDEO_ISOC_FRAMESPERDESC; - JOM(4, "%i=video_isoc_framesperdesc\n", - peasycap->video_isoc_framesperdesc); - if (0 >= peasycap->video_isoc_framesperdesc) { - SAM("ERROR: bad video_isoc_framesperdesc\n"); - return -ENOENT; - } - peasycap->video_isoc_buffer_size = - peasycap->video_isoc_maxframesize * - peasycap->video_isoc_framesperdesc; - JOM(4, "%i=video_isoc_buffer_size\n", - peasycap->video_isoc_buffer_size); - if ((PAGE_SIZE << VIDEO_ISOC_ORDER) < - peasycap->video_isoc_buffer_size) { - SAM("MISTAKE: peasycap->video_isoc_buffer_size too big\n"); - return -EFAULT; - } + peasycap->video_endpointnumber = okepn[isokalt - 1]; + JOM(4, "%i=video_endpointnumber\n", peasycap->video_endpointnumber); + maxpacketsize = okmps[isokalt - 1]; + if (USB_2_0_MAXPACKETSIZE > maxpacketsize) { + peasycap->video_isoc_maxframesize = maxpacketsize; + } else { + peasycap->video_isoc_maxframesize = + USB_2_0_MAXPACKETSIZE; + } + JOM(4, "%i=video_isoc_maxframesize\n", + peasycap->video_isoc_maxframesize); + if (0 >= peasycap->video_isoc_maxframesize) { + SAM("ERROR: bad video_isoc_maxframesize\n"); + SAM(" possibly because port is USB 1.1\n"); + return -ENOENT; + } + peasycap->video_isoc_framesperdesc = VIDEO_ISOC_FRAMESPERDESC; + JOM(4, "%i=video_isoc_framesperdesc\n", + peasycap->video_isoc_framesperdesc); + if (0 >= peasycap->video_isoc_framesperdesc) { + SAM("ERROR: bad video_isoc_framesperdesc\n"); + return -ENOENT; + } + peasycap->video_isoc_buffer_size = + peasycap->video_isoc_maxframesize * + peasycap->video_isoc_framesperdesc; + JOM(4, "%i=video_isoc_buffer_size\n", + peasycap->video_isoc_buffer_size); + if ((PAGE_SIZE << VIDEO_ISOC_ORDER) < + peasycap->video_isoc_buffer_size) { + SAM("MISTAKE: peasycap->video_isoc_buffer_size too big\n"); + return -EFAULT; + } /*---------------------------------------------------------------------------*/ - if (-1 == peasycap->video_interface) { - SAM("MISTAKE: video_interface is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->video_altsetting_on) { - SAM("MISTAKE: video_altsetting_on is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->video_altsetting_off) { - SAM("MISTAKE: video_interface_off is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->video_endpointnumber) { - SAM("MISTAKE: video_endpointnumber is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->video_isoc_maxframesize) { - SAM("MISTAKE: video_isoc_maxframesize is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->video_isoc_buffer_size) { - SAM("MISTAKE: video_isoc_buffer_size is unset\n"); - return -EFAULT; - } + if (-1 == peasycap->video_interface) { + SAM("MISTAKE: video_interface is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->video_altsetting_on) { + SAM("MISTAKE: video_altsetting_on is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->video_altsetting_off) { + SAM("MISTAKE: video_interface_off is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->video_endpointnumber) { + SAM("MISTAKE: video_endpointnumber is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->video_isoc_maxframesize) { + SAM("MISTAKE: video_isoc_maxframesize is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->video_isoc_buffer_size) { + SAM("MISTAKE: video_isoc_buffer_size is unset\n"); + return -EFAULT; + } /*---------------------------------------------------------------------------*/ /* * ALLOCATE MEMORY FOR VIDEO BUFFERS. LISTS MUST BE INITIALIZED FIRST. */ /*---------------------------------------------------------------------------*/ - INIT_LIST_HEAD(&(peasycap->urb_video_head)); - peasycap->purb_video_head = &(peasycap->urb_video_head); -/*---------------------------------------------------------------------------*/ - JOM(4, "allocating %i frame buffers of size %li\n", - FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE); - JOM(4, ".... each scattered over %li pages\n", - FRAME_BUFFER_SIZE/PAGE_SIZE); - - for (k = 0; k < FRAME_BUFFER_MANY; k++) { - for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { - if (NULL != peasycap->frame_buffer[k][m].pgo) - SAM("attempting to reallocate frame " - " buffers\n"); - else { - pbuf = (void *)__get_free_page(GFP_KERNEL); - if (NULL == pbuf) { - SAM("ERROR: Could not allocate frame " - "buffer %i page %i\n", k, m); - return -ENOMEM; - } else - peasycap->allocation_video_page += 1; - peasycap->frame_buffer[k][m].pgo = pbuf; + INIT_LIST_HEAD(&(peasycap->urb_video_head)); + peasycap->purb_video_head = &(peasycap->urb_video_head); +/*---------------------------------------------------------------------------*/ + JOM(4, "allocating %i frame buffers of size %li\n", + FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE); + JOM(4, ".... each scattered over %li pages\n", + FRAME_BUFFER_SIZE/PAGE_SIZE); + + for (k = 0; k < FRAME_BUFFER_MANY; k++) { + for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { + if (NULL != peasycap->frame_buffer[k][m].pgo) + SAM("attempting to reallocate frame " + " buffers\n"); + else { + pbuf = (void *)__get_free_page(GFP_KERNEL); + if (NULL == pbuf) { + SAM("ERROR: Could not allocate frame " + "buffer %i page %i\n", k, m); + return -ENOMEM; + } else + peasycap->allocation_video_page += 1; + peasycap->frame_buffer[k][m].pgo = pbuf; + } + peasycap->frame_buffer[k][m].pto = + peasycap->frame_buffer[k][m].pgo; } - peasycap->frame_buffer[k][m].pto = - peasycap->frame_buffer[k][m].pgo; } - } - peasycap->frame_fill = 0; - peasycap->frame_read = 0; - JOM(4, "allocation of frame buffers done: %i pages\n", k * - m); -/*---------------------------------------------------------------------------*/ - JOM(4, "allocating %i field buffers of size %li\n", - FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE); - JOM(4, ".... each scattered over %li pages\n", - FIELD_BUFFER_SIZE/PAGE_SIZE); - - for (k = 0; k < FIELD_BUFFER_MANY; k++) { - for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { - if (NULL != peasycap->field_buffer[k][m].pgo) { - SAM("ERROR: attempting to reallocate " - "field buffers\n"); - } else { - pbuf = (void *) __get_free_page(GFP_KERNEL); - if (NULL == pbuf) { - SAM("ERROR: Could not allocate field" - " buffer %i page %i\n", k, m); - return -ENOMEM; + peasycap->frame_fill = 0; + peasycap->frame_read = 0; + JOM(4, "allocation of frame buffers done: %i pages\n", k * + m); +/*---------------------------------------------------------------------------*/ + JOM(4, "allocating %i field buffers of size %li\n", + FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE); + JOM(4, ".... each scattered over %li pages\n", + FIELD_BUFFER_SIZE/PAGE_SIZE); + + for (k = 0; k < FIELD_BUFFER_MANY; k++) { + for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { + if (NULL != peasycap->field_buffer[k][m].pgo) { + SAM("ERROR: attempting to reallocate " + "field buffers\n"); + } else { + pbuf = (void *) __get_free_page(GFP_KERNEL); + if (NULL == pbuf) { + SAM("ERROR: Could not allocate field" + " buffer %i page %i\n", k, m); + return -ENOMEM; + } + else + peasycap->allocation_video_page += 1; + peasycap->field_buffer[k][m].pgo = pbuf; } - else - peasycap->allocation_video_page += 1; - peasycap->field_buffer[k][m].pgo = pbuf; - } - peasycap->field_buffer[k][m].pto = - peasycap->field_buffer[k][m].pgo; + peasycap->field_buffer[k][m].pto = + peasycap->field_buffer[k][m].pgo; + } + peasycap->field_buffer[k][0].kount = 0x0200; } - peasycap->field_buffer[k][0].kount = 0x0200; - } - peasycap->field_fill = 0; - peasycap->field_page = 0; - peasycap->field_read = 0; - JOM(4, "allocation of field buffers done: %i pages\n", k * - m); -/*---------------------------------------------------------------------------*/ - JOM(4, "allocating %i isoc video buffers of size %i\n", - VIDEO_ISOC_BUFFER_MANY, - peasycap->video_isoc_buffer_size); - JOM(4, ".... each occupying contiguous memory pages\n"); - - for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { - pbuf = (void *)__get_free_pages(GFP_KERNEL, VIDEO_ISOC_ORDER); - if (NULL == pbuf) { - SAM("ERROR: Could not allocate isoc video buffer " - "%i\n", k); - return -ENOMEM; - } else - peasycap->allocation_video_page += - ((unsigned int)(0x01 << VIDEO_ISOC_ORDER)); + peasycap->field_fill = 0; + peasycap->field_page = 0; + peasycap->field_read = 0; + JOM(4, "allocation of field buffers done: %i pages\n", k * + m); +/*---------------------------------------------------------------------------*/ + JOM(4, "allocating %i isoc video buffers of size %i\n", + VIDEO_ISOC_BUFFER_MANY, + peasycap->video_isoc_buffer_size); + JOM(4, ".... each occupying contiguous memory pages\n"); + + for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { + pbuf = (void *)__get_free_pages(GFP_KERNEL, VIDEO_ISOC_ORDER); + if (NULL == pbuf) { + SAM("ERROR: Could not allocate isoc video buffer " + "%i\n", k); + return -ENOMEM; + } else + peasycap->allocation_video_page += + ((unsigned int)(0x01 << VIDEO_ISOC_ORDER)); - peasycap->video_isoc_buffer[k].pgo = pbuf; - peasycap->video_isoc_buffer[k].pto = pbuf + - peasycap->video_isoc_buffer_size; - peasycap->video_isoc_buffer[k].kount = k; - } - JOM(4, "allocation of isoc video buffers done: %i pages\n", - k * (0x01 << VIDEO_ISOC_ORDER)); + peasycap->video_isoc_buffer[k].pgo = pbuf; + peasycap->video_isoc_buffer[k].pto = pbuf + + peasycap->video_isoc_buffer_size; + peasycap->video_isoc_buffer[k].kount = k; + } + JOM(4, "allocation of isoc video buffers done: %i pages\n", + k * (0x01 << VIDEO_ISOC_ORDER)); /*---------------------------------------------------------------------------*/ /* * ALLOCATE AND INITIALIZE MULTIPLE struct urb ... */ /*---------------------------------------------------------------------------*/ - JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY); - JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n", - peasycap->video_isoc_framesperdesc); - JOM(4, "using %i=peasycap->video_isoc_maxframesize\n", - peasycap->video_isoc_maxframesize); - JOM(4, "using %i=peasycap->video_isoc_buffer_sizen", - peasycap->video_isoc_buffer_size); - - for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { - purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc, - GFP_KERNEL); - if (NULL == purb) { - SAM("ERROR: usb_alloc_urb returned NULL for buffer " - "%i\n", k); - return -ENOMEM; - } else - peasycap->allocation_video_urb += 1; + JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY); + JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n", + peasycap->video_isoc_framesperdesc); + JOM(4, "using %i=peasycap->video_isoc_maxframesize\n", + peasycap->video_isoc_maxframesize); + JOM(4, "using %i=peasycap->video_isoc_buffer_sizen", + peasycap->video_isoc_buffer_size); + + for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { + purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc, + GFP_KERNEL); + if (NULL == purb) { + SAM("ERROR: usb_alloc_urb returned NULL for buffer " + "%i\n", k); + return -ENOMEM; + } else + peasycap->allocation_video_urb += 1; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); - if (NULL == pdata_urb) { - SAM("ERROR: Could not allocate struct data_urb.\n"); - return -ENOMEM; - } else - peasycap->allocation_video_struct += - sizeof(struct data_urb); + pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); + if (NULL == pdata_urb) { + SAM("ERROR: Could not allocate struct data_urb.\n"); + return -ENOMEM; + } else + peasycap->allocation_video_struct += + sizeof(struct data_urb); - pdata_urb->purb = purb; - pdata_urb->isbuf = k; - pdata_urb->length = 0; - list_add_tail(&(pdata_urb->list_head), - peasycap->purb_video_head); + pdata_urb->purb = purb; + pdata_urb->isbuf = k; + pdata_urb->length = 0; + list_add_tail(&(pdata_urb->list_head), + peasycap->purb_video_head); /*---------------------------------------------------------------------------*/ /* * ... AND INITIALIZE THEM */ /*---------------------------------------------------------------------------*/ - if (!k) { - JOM(4, "initializing video urbs thus:\n"); - JOM(4, " purb->interval = 1;\n"); - JOM(4, " purb->dev = peasycap->pusb_device;\n"); - JOM(4, " purb->pipe = usb_rcvisocpipe" - "(peasycap->pusb_device,%i);\n", - peasycap->video_endpointnumber); - JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n"); - JOM(4, " purb->transfer_buffer = peasycap->" - "video_isoc_buffer[.].pgo;\n"); - JOM(4, " purb->transfer_buffer_length = %i;\n", - peasycap->video_isoc_buffer_size); - JOM(4, " purb->complete = easycap_complete;\n"); - JOM(4, " purb->context = peasycap;\n"); - JOM(4, " purb->start_frame = 0;\n"); - JOM(4, " purb->number_of_packets = %i;\n", - peasycap->video_isoc_framesperdesc); - JOM(4, " for (j = 0; j < %i; j++)\n", - peasycap->video_isoc_framesperdesc); - JOM(4, " {\n"); - JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n", - peasycap->video_isoc_maxframesize); - JOM(4, " purb->iso_frame_desc[j].length = %i;\n", - peasycap->video_isoc_maxframesize); - JOM(4, " }\n"); - } + if (!k) { + JOM(4, "initializing video urbs thus:\n"); + JOM(4, " purb->interval = 1;\n"); + JOM(4, " purb->dev = peasycap->pusb_device;\n"); + JOM(4, " purb->pipe = usb_rcvisocpipe" + "(peasycap->pusb_device,%i);\n", + peasycap->video_endpointnumber); + JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n"); + JOM(4, " purb->transfer_buffer = peasycap->" + "video_isoc_buffer[.].pgo;\n"); + JOM(4, " purb->transfer_buffer_length = %i;\n", + peasycap->video_isoc_buffer_size); + JOM(4, " purb->complete = easycap_complete;\n"); + JOM(4, " purb->context = peasycap;\n"); + JOM(4, " purb->start_frame = 0;\n"); + JOM(4, " purb->number_of_packets = %i;\n", + peasycap->video_isoc_framesperdesc); + JOM(4, " for (j = 0; j < %i; j++)\n", + peasycap->video_isoc_framesperdesc); + JOM(4, " {\n"); + JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n", + peasycap->video_isoc_maxframesize); + JOM(4, " purb->iso_frame_desc[j].length = %i;\n", + peasycap->video_isoc_maxframesize); + JOM(4, " }\n"); + } - purb->interval = 1; - purb->dev = peasycap->pusb_device; - purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, - peasycap->video_endpointnumber); - purb->transfer_flags = URB_ISO_ASAP; - purb->transfer_buffer = peasycap->video_isoc_buffer[k].pgo; - purb->transfer_buffer_length = - peasycap->video_isoc_buffer_size; - purb->complete = easycap_complete; - purb->context = peasycap; - purb->start_frame = 0; - purb->number_of_packets = peasycap->video_isoc_framesperdesc; - for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) { - purb->iso_frame_desc[j].offset = j * - peasycap->video_isoc_maxframesize; - purb->iso_frame_desc[j].length = - peasycap->video_isoc_maxframesize; + purb->interval = 1; + purb->dev = peasycap->pusb_device; + purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, + peasycap->video_endpointnumber); + purb->transfer_flags = URB_ISO_ASAP; + purb->transfer_buffer = peasycap->video_isoc_buffer[k].pgo; + purb->transfer_buffer_length = + peasycap->video_isoc_buffer_size; + purb->complete = easycap_complete; + purb->context = peasycap; + purb->start_frame = 0; + purb->number_of_packets = peasycap->video_isoc_framesperdesc; + for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) { + purb->iso_frame_desc[j].offset = j * + peasycap->video_isoc_maxframesize; + purb->iso_frame_desc[j].length = + peasycap->video_isoc_maxframesize; + } } - } - JOM(4, "allocation of %i struct urb done.\n", k); + JOM(4, "allocation of %i struct urb done.\n", k); /*--------------------------------------------------------------------------*/ /* * SAVE POINTER peasycap IN THIS INTERFACE. */ /*--------------------------------------------------------------------------*/ - usb_set_intfdata(pusb_interface, peasycap); + usb_set_intfdata(pusb_interface, peasycap); /*---------------------------------------------------------------------------*/ /* * IT IS ESSENTIAL TO INITIALIZE THE HARDWARE BEFORE, RATHER THAN AFTER, @@ -4122,44 +4122,44 @@ case 0: { */ /*---------------------------------------------------------------------------*/ #ifdef PREFER_NTSC - peasycap->ntsc = true; - JOM(8, "defaulting initially to NTSC\n"); + peasycap->ntsc = true; + JOM(8, "defaulting initially to NTSC\n"); #else - peasycap->ntsc = false; - JOM(8, "defaulting initially to PAL\n"); + peasycap->ntsc = false; + JOM(8, "defaulting initially to PAL\n"); #endif /*PREFER_NTSC*/ - rc = reset(peasycap); - if (rc) { - SAM("ERROR: reset() returned %i\n", rc); - return -EFAULT; - } + rc = reset(peasycap); + if (rc) { + SAM("ERROR: reset() returned %i\n", rc); + return -EFAULT; + } /*--------------------------------------------------------------------------*/ /* * THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY. */ /*--------------------------------------------------------------------------*/ #ifndef EASYCAP_IS_VIDEODEV_CLIENT - if (0 != (usb_register_dev(pusb_interface, &easycap_class))) { - err("Not able to get a minor for this device"); - usb_set_intfdata(pusb_interface, NULL); - return -ENODEV; - } else { - (peasycap->registered_video)++; - SAM("easycap attached to minor #%d\n", pusb_interface->minor); - peasycap->minor = pusb_interface->minor; - break; - } + if (0 != (usb_register_dev(pusb_interface, &easycap_class))) { + err("Not able to get a minor for this device"); + usb_set_intfdata(pusb_interface, NULL); + return -ENODEV; + } else { + (peasycap->registered_video)++; + SAM("easycap attached to minor #%d\n", pusb_interface->minor); + peasycap->minor = pusb_interface->minor; + break; + } /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #else #ifdef EASYCAP_NEEDS_V4L2_DEVICE_H - if (0 != (v4l2_device_register(&(pusb_interface->dev), - &(peasycap->v4l2_device)))) { - SAM("v4l2_device_register() failed\n"); - return -ENODEV; - } else { - JOM(4, "registered device instance: %s\n", - &(peasycap->v4l2_device.name[0])); - } + if (0 != (v4l2_device_register(&(pusb_interface->dev), + &(peasycap->v4l2_device)))) { + SAM("v4l2_device_register() failed\n"); + return -ENODEV; + } else { + JOM(4, "registered device instance: %s\n", + &(peasycap->v4l2_device.name[0])); + } /*---------------------------------------------------------------------------*/ /* * FIXME @@ -4168,37 +4168,37 @@ case 0: { * THIS IS BELIEVED TO BE HARMLESS, BUT MAY WELL BE UNNECESSARY OR WRONG: */ /*---------------------------------------------------------------------------*/ - peasycap->video_device.v4l2_dev = NULL; + peasycap->video_device.v4l2_dev = NULL; /*---------------------------------------------------------------------------*/ #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ - strcpy(&peasycap->video_device.name[0], "easycapdc60"); + strcpy(&peasycap->video_device.name[0], "easycapdc60"); #ifdef EASYCAP_NEEDS_V4L2_FOPS - peasycap->video_device.fops = &v4l2_fops; + peasycap->video_device.fops = &v4l2_fops; #else - peasycap->video_device.fops = &easycap_fops; + peasycap->video_device.fops = &easycap_fops; #endif /*EASYCAP_NEEDS_V4L2_FOPS*/ - peasycap->video_device.minor = -1; - peasycap->video_device.release = (void *)(&videodev_release); + peasycap->video_device.minor = -1; + peasycap->video_device.release = (void *)(&videodev_release); - video_set_drvdata(&(peasycap->video_device), (void *)peasycap); + video_set_drvdata(&(peasycap->video_device), (void *)peasycap); - if (0 != (video_register_device(&(peasycap->video_device), - VFL_TYPE_GRABBER, -1))) { - err("Not able to register with videodev"); - videodev_release(&(peasycap->video_device)); - return -ENODEV; - } else { - (peasycap->registered_video)++; - SAM("registered with videodev: %i=minor\n", - peasycap->video_device.minor); - peasycap->minor = peasycap->video_device.minor; - } + if (0 != (video_register_device(&(peasycap->video_device), + VFL_TYPE_GRABBER, -1))) { + err("Not able to register with videodev"); + videodev_release(&(peasycap->video_device)); + return -ENODEV; + } else { + (peasycap->registered_video)++; + SAM("registered with videodev: %i=minor\n", + peasycap->video_device.minor); + peasycap->minor = peasycap->video_device.minor; + } #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - break; + break; } /*--------------------------------------------------------------------------*/ /* @@ -4206,338 +4206,338 @@ case 0: { * INTERFACE 2 IS THE AUDIO STREAMING INTERFACE */ /*--------------------------------------------------------------------------*/ -case 1: { + case 1: { #ifdef EASYCAP_SILENT - return -ENOENT; + return -ENOENT; #endif /*EASYCAP_SILENT*/ - if (!peasycap) { - SAM("MISTAKE: peasycap is NULL\n"); - return -EFAULT; - } + if (!peasycap) { + SAM("MISTAKE: peasycap is NULL\n"); + return -EFAULT; + } /*--------------------------------------------------------------------------*/ /* * SAVE POINTER peasycap IN INTERFACE 1 */ /*--------------------------------------------------------------------------*/ - usb_set_intfdata(pusb_interface, peasycap); - JOM(4, "no initialization required for interface %i\n", - pusb_interface_descriptor->bInterfaceNumber); - break; -} -/*--------------------------------------------------------------------------*/ -case 2: { -#ifdef EASYCAP_SILENT - return -ENOENT; -#endif /*EASYCAP_SILENT*/ - if (!peasycap) { - SAM("MISTAKE: peasycap is NULL\n"); - return -EFAULT; + usb_set_intfdata(pusb_interface, peasycap); + JOM(4, "no initialization required for interface %i\n", + pusb_interface_descriptor->bInterfaceNumber); + break; } - if (!isokalt) { - SAM("ERROR: no viable audio_altsetting_on\n"); + /*--------------------------------------------------------------------------*/ + case 2: { +#ifdef EASYCAP_SILENT return -ENOENT; - } else { - peasycap->audio_altsetting_on = okalt[isokalt - 1]; - JOM(4, "%i=audio_altsetting_on <====\n", - peasycap->audio_altsetting_on); - } +#endif /*EASYCAP_SILENT*/ + if (!peasycap) { + SAM("MISTAKE: peasycap is NULL\n"); + return -EFAULT; + } + if (!isokalt) { + SAM("ERROR: no viable audio_altsetting_on\n"); + return -ENOENT; + } else { + peasycap->audio_altsetting_on = okalt[isokalt - 1]; + JOM(4, "%i=audio_altsetting_on <====\n", + peasycap->audio_altsetting_on); + } - peasycap->audio_endpointnumber = okepn[isokalt - 1]; - JOM(4, "%i=audio_endpointnumber\n", peasycap->audio_endpointnumber); + peasycap->audio_endpointnumber = okepn[isokalt - 1]; + JOM(4, "%i=audio_endpointnumber\n", peasycap->audio_endpointnumber); - peasycap->audio_isoc_maxframesize = okmps[isokalt - 1]; - JOM(4, "%i=audio_isoc_maxframesize\n", - peasycap->audio_isoc_maxframesize); - if (0 >= peasycap->audio_isoc_maxframesize) { - SAM("ERROR: bad audio_isoc_maxframesize\n"); - return -ENOENT; - } - if (9 == peasycap->audio_isoc_maxframesize) { - peasycap->ilk |= 0x02; - SAM("audio hardware is microphone\n"); - peasycap->microphone = true; - peasycap->audio_pages_per_fragment = PAGES_PER_AUDIO_FRAGMENT; - } else if (256 == peasycap->audio_isoc_maxframesize) { - peasycap->ilk &= ~0x02; - SAM("audio hardware is AC'97\n"); - peasycap->microphone = false; - peasycap->audio_pages_per_fragment = PAGES_PER_AUDIO_FRAGMENT; - } else { - SAM("hardware is unidentified:\n"); - SAM("%i=audio_isoc_maxframesize\n", - peasycap->audio_isoc_maxframesize); - return -ENOENT; - } + peasycap->audio_isoc_maxframesize = okmps[isokalt - 1]; + JOM(4, "%i=audio_isoc_maxframesize\n", + peasycap->audio_isoc_maxframesize); + if (0 >= peasycap->audio_isoc_maxframesize) { + SAM("ERROR: bad audio_isoc_maxframesize\n"); + return -ENOENT; + } + if (9 == peasycap->audio_isoc_maxframesize) { + peasycap->ilk |= 0x02; + SAM("audio hardware is microphone\n"); + peasycap->microphone = true; + peasycap->audio_pages_per_fragment = PAGES_PER_AUDIO_FRAGMENT; + } else if (256 == peasycap->audio_isoc_maxframesize) { + peasycap->ilk &= ~0x02; + SAM("audio hardware is AC'97\n"); + peasycap->microphone = false; + peasycap->audio_pages_per_fragment = PAGES_PER_AUDIO_FRAGMENT; + } else { + SAM("hardware is unidentified:\n"); + SAM("%i=audio_isoc_maxframesize\n", + peasycap->audio_isoc_maxframesize); + return -ENOENT; + } - peasycap->audio_bytes_per_fragment = - peasycap->audio_pages_per_fragment * - PAGE_SIZE ; - peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY * - peasycap->audio_pages_per_fragment); - - JOM(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY); - JOM(4, "%6i=audio_pages_per_fragment\n", - peasycap->audio_pages_per_fragment); - JOM(4, "%6i=audio_bytes_per_fragment\n", - peasycap->audio_bytes_per_fragment); - JOM(4, "%6i=audio_buffer_page_many\n", - peasycap->audio_buffer_page_many); - - peasycap->audio_isoc_framesperdesc = AUDIO_ISOC_FRAMESPERDESC; - - JOM(4, "%i=audio_isoc_framesperdesc\n", - peasycap->audio_isoc_framesperdesc); - if (0 >= peasycap->audio_isoc_framesperdesc) { - SAM("ERROR: bad audio_isoc_framesperdesc\n"); - return -ENOENT; - } + peasycap->audio_bytes_per_fragment = + peasycap->audio_pages_per_fragment * + PAGE_SIZE ; + peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY * + peasycap->audio_pages_per_fragment); + + JOM(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY); + JOM(4, "%6i=audio_pages_per_fragment\n", + peasycap->audio_pages_per_fragment); + JOM(4, "%6i=audio_bytes_per_fragment\n", + peasycap->audio_bytes_per_fragment); + JOM(4, "%6i=audio_buffer_page_many\n", + peasycap->audio_buffer_page_many); + + peasycap->audio_isoc_framesperdesc = AUDIO_ISOC_FRAMESPERDESC; + + JOM(4, "%i=audio_isoc_framesperdesc\n", + peasycap->audio_isoc_framesperdesc); + if (0 >= peasycap->audio_isoc_framesperdesc) { + SAM("ERROR: bad audio_isoc_framesperdesc\n"); + return -ENOENT; + } - peasycap->audio_isoc_buffer_size = - peasycap->audio_isoc_maxframesize * - peasycap->audio_isoc_framesperdesc; - JOM(4, "%i=audio_isoc_buffer_size\n", - peasycap->audio_isoc_buffer_size); - if (AUDIO_ISOC_BUFFER_SIZE < peasycap->audio_isoc_buffer_size) { - SAM("MISTAKE: audio_isoc_buffer_size bigger " - "than %li=AUDIO_ISOC_BUFFER_SIZE\n", - AUDIO_ISOC_BUFFER_SIZE); - return -EFAULT; - } - if (-1 == peasycap->audio_interface) { - SAM("MISTAKE: audio_interface is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->audio_altsetting_on) { - SAM("MISTAKE: audio_altsetting_on is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->audio_altsetting_off) { - SAM("MISTAKE: audio_interface_off is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->audio_endpointnumber) { - SAM("MISTAKE: audio_endpointnumber is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->audio_isoc_maxframesize) { - SAM("MISTAKE: audio_isoc_maxframesize is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->audio_isoc_buffer_size) { - SAM("MISTAKE: audio_isoc_buffer_size is unset\n"); - return -EFAULT; - } + peasycap->audio_isoc_buffer_size = + peasycap->audio_isoc_maxframesize * + peasycap->audio_isoc_framesperdesc; + JOM(4, "%i=audio_isoc_buffer_size\n", + peasycap->audio_isoc_buffer_size); + if (AUDIO_ISOC_BUFFER_SIZE < peasycap->audio_isoc_buffer_size) { + SAM("MISTAKE: audio_isoc_buffer_size bigger " + "than %li=AUDIO_ISOC_BUFFER_SIZE\n", + AUDIO_ISOC_BUFFER_SIZE); + return -EFAULT; + } + if (-1 == peasycap->audio_interface) { + SAM("MISTAKE: audio_interface is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->audio_altsetting_on) { + SAM("MISTAKE: audio_altsetting_on is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->audio_altsetting_off) { + SAM("MISTAKE: audio_interface_off is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->audio_endpointnumber) { + SAM("MISTAKE: audio_endpointnumber is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->audio_isoc_maxframesize) { + SAM("MISTAKE: audio_isoc_maxframesize is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->audio_isoc_buffer_size) { + SAM("MISTAKE: audio_isoc_buffer_size is unset\n"); + return -EFAULT; + } /*---------------------------------------------------------------------------*/ /* * ALLOCATE MEMORY FOR AUDIO BUFFERS. LISTS MUST BE INITIALIZED FIRST. */ /*---------------------------------------------------------------------------*/ - INIT_LIST_HEAD(&(peasycap->urb_audio_head)); - peasycap->purb_audio_head = &(peasycap->urb_audio_head); + INIT_LIST_HEAD(&(peasycap->urb_audio_head)); + peasycap->purb_audio_head = &(peasycap->urb_audio_head); #ifdef CONFIG_EASYCAP_OSS - JOM(4, "allocating an audio buffer\n"); - JOM(4, ".... scattered over %i pages\n", - peasycap->audio_buffer_page_many); + JOM(4, "allocating an audio buffer\n"); + JOM(4, ".... scattered over %i pages\n", + peasycap->audio_buffer_page_many); - for (k = 0; k < peasycap->audio_buffer_page_many; k++) { - if (NULL != peasycap->audio_buffer[k].pgo) { - SAM("ERROR: attempting to reallocate audio buffers\n"); - } else { - pbuf = (void *) __get_free_page(GFP_KERNEL); - if (NULL == pbuf) { - SAM("ERROR: Could not allocate audio " - "buffer page %i\n", k); - return -ENOMEM; - } else - peasycap->allocation_audio_page += 1; + for (k = 0; k < peasycap->audio_buffer_page_many; k++) { + if (NULL != peasycap->audio_buffer[k].pgo) { + SAM("ERROR: attempting to reallocate audio buffers\n"); + } else { + pbuf = (void *) __get_free_page(GFP_KERNEL); + if (NULL == pbuf) { + SAM("ERROR: Could not allocate audio " + "buffer page %i\n", k); + return -ENOMEM; + } else + peasycap->allocation_audio_page += 1; - peasycap->audio_buffer[k].pgo = pbuf; + peasycap->audio_buffer[k].pgo = pbuf; + } + peasycap->audio_buffer[k].pto = peasycap->audio_buffer[k].pgo; } - peasycap->audio_buffer[k].pto = peasycap->audio_buffer[k].pgo; - } - peasycap->audio_fill = 0; - peasycap->audio_read = 0; - JOM(4, "allocation of audio buffer done: %i pages\n", k); + peasycap->audio_fill = 0; + peasycap->audio_read = 0; + JOM(4, "allocation of audio buffer done: %i pages\n", k); #endif /* CONFIG_EASYCAP_OSS */ /*---------------------------------------------------------------------------*/ - JOM(4, "allocating %i isoc audio buffers of size %i\n", - AUDIO_ISOC_BUFFER_MANY, peasycap->audio_isoc_buffer_size); - JOM(4, ".... each occupying contiguous memory pages\n"); + JOM(4, "allocating %i isoc audio buffers of size %i\n", + AUDIO_ISOC_BUFFER_MANY, peasycap->audio_isoc_buffer_size); + JOM(4, ".... each occupying contiguous memory pages\n"); - for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { - pbuf = (void *)__get_free_pages(GFP_KERNEL, AUDIO_ISOC_ORDER); - if (NULL == pbuf) { - SAM("ERROR: Could not allocate isoc audio buffer " - "%i\n", k); - return -ENOMEM; - } else - peasycap->allocation_audio_page += - ((unsigned int)(0x01 << AUDIO_ISOC_ORDER)); + for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { + pbuf = (void *)__get_free_pages(GFP_KERNEL, AUDIO_ISOC_ORDER); + if (NULL == pbuf) { + SAM("ERROR: Could not allocate isoc audio buffer " + "%i\n", k); + return -ENOMEM; + } else + peasycap->allocation_audio_page += + ((unsigned int)(0x01 << AUDIO_ISOC_ORDER)); - peasycap->audio_isoc_buffer[k].pgo = pbuf; - peasycap->audio_isoc_buffer[k].pto = pbuf + - peasycap->audio_isoc_buffer_size; - peasycap->audio_isoc_buffer[k].kount = k; - } - JOM(4, "allocation of isoc audio buffers done.\n"); + peasycap->audio_isoc_buffer[k].pgo = pbuf; + peasycap->audio_isoc_buffer[k].pto = pbuf + + peasycap->audio_isoc_buffer_size; + peasycap->audio_isoc_buffer[k].kount = k; + } + JOM(4, "allocation of isoc audio buffers done.\n"); /*---------------------------------------------------------------------------*/ /* * ALLOCATE AND INITIALIZE MULTIPLE struct urb ... */ /*---------------------------------------------------------------------------*/ - JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY); - JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n", - peasycap->audio_isoc_framesperdesc); - JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n", - peasycap->audio_isoc_maxframesize); - JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n", - peasycap->audio_isoc_buffer_size); - - for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { - purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc, - GFP_KERNEL); - if (NULL == purb) { - SAM("ERROR: usb_alloc_urb returned NULL for buffer " - "%i\n", k); - return -ENOMEM; - } else - peasycap->allocation_audio_urb += 1 ; + JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY); + JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n", + peasycap->audio_isoc_framesperdesc); + JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n", + peasycap->audio_isoc_maxframesize); + JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n", + peasycap->audio_isoc_buffer_size); + + for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { + purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc, + GFP_KERNEL); + if (NULL == purb) { + SAM("ERROR: usb_alloc_urb returned NULL for buffer " + "%i\n", k); + return -ENOMEM; + } else + peasycap->allocation_audio_urb += 1 ; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); - if (NULL == pdata_urb) { - SAM("ERROR: Could not allocate struct data_urb.\n"); - return -ENOMEM; - } else - peasycap->allocation_audio_struct += - sizeof(struct data_urb); + pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); + if (NULL == pdata_urb) { + SAM("ERROR: Could not allocate struct data_urb.\n"); + return -ENOMEM; + } else + peasycap->allocation_audio_struct += + sizeof(struct data_urb); - pdata_urb->purb = purb; - pdata_urb->isbuf = k; - pdata_urb->length = 0; - list_add_tail(&(pdata_urb->list_head), - peasycap->purb_audio_head); + pdata_urb->purb = purb; + pdata_urb->isbuf = k; + pdata_urb->length = 0; + list_add_tail(&(pdata_urb->list_head), + peasycap->purb_audio_head); /*---------------------------------------------------------------------------*/ /* * ... AND INITIALIZE THEM */ /*---------------------------------------------------------------------------*/ - if (!k) { - JOM(4, "initializing audio urbs thus:\n"); - JOM(4, " purb->interval = 1;\n"); - JOM(4, " purb->dev = peasycap->pusb_device;\n"); - JOM(4, " purb->pipe = usb_rcvisocpipe(peasycap->" - "pusb_device,%i);\n", - peasycap->audio_endpointnumber); - JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n"); - JOM(4, " purb->transfer_buffer = " - "peasycap->audio_isoc_buffer[.].pgo;\n"); - JOM(4, " purb->transfer_buffer_length = %i;\n", - peasycap->audio_isoc_buffer_size); + if (!k) { + JOM(4, "initializing audio urbs thus:\n"); + JOM(4, " purb->interval = 1;\n"); + JOM(4, " purb->dev = peasycap->pusb_device;\n"); + JOM(4, " purb->pipe = usb_rcvisocpipe(peasycap->" + "pusb_device,%i);\n", + peasycap->audio_endpointnumber); + JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n"); + JOM(4, " purb->transfer_buffer = " + "peasycap->audio_isoc_buffer[.].pgo;\n"); + JOM(4, " purb->transfer_buffer_length = %i;\n", + peasycap->audio_isoc_buffer_size); #ifdef CONFIG_EASYCAP_OSS - JOM(4, " purb->complete = easyoss_complete;\n"); + JOM(4, " purb->complete = easyoss_complete;\n"); #else /* CONFIG_EASYCAP_OSS */ - JOM(4, " purb->complete = easycap_alsa_complete;\n"); + JOM(4, " purb->complete = easycap_alsa_complete;\n"); #endif /* CONFIG_EASYCAP_OSS */ - JOM(4, " purb->context = peasycap;\n"); - JOM(4, " purb->start_frame = 0;\n"); - JOM(4, " purb->number_of_packets = %i;\n", - peasycap->audio_isoc_framesperdesc); - JOM(4, " for (j = 0; j < %i; j++)\n", - peasycap->audio_isoc_framesperdesc); - JOM(4, " {\n"); - JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n", - peasycap->audio_isoc_maxframesize); - JOM(4, " purb->iso_frame_desc[j].length = %i;\n", - peasycap->audio_isoc_maxframesize); - JOM(4, " }\n"); - } + JOM(4, " purb->context = peasycap;\n"); + JOM(4, " purb->start_frame = 0;\n"); + JOM(4, " purb->number_of_packets = %i;\n", + peasycap->audio_isoc_framesperdesc); + JOM(4, " for (j = 0; j < %i; j++)\n", + peasycap->audio_isoc_framesperdesc); + JOM(4, " {\n"); + JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n", + peasycap->audio_isoc_maxframesize); + JOM(4, " purb->iso_frame_desc[j].length = %i;\n", + peasycap->audio_isoc_maxframesize); + JOM(4, " }\n"); + } - purb->interval = 1; - purb->dev = peasycap->pusb_device; - purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, - peasycap->audio_endpointnumber); - purb->transfer_flags = URB_ISO_ASAP; - purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo; - purb->transfer_buffer_length = - peasycap->audio_isoc_buffer_size; + purb->interval = 1; + purb->dev = peasycap->pusb_device; + purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, + peasycap->audio_endpointnumber); + purb->transfer_flags = URB_ISO_ASAP; + purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo; + purb->transfer_buffer_length = + peasycap->audio_isoc_buffer_size; #ifdef CONFIG_EASYCAP_OSS - purb->complete = easyoss_complete; + purb->complete = easyoss_complete; #else /* CONFIG_EASYCAP_OSS */ - purb->complete = easycap_alsa_complete; + purb->complete = easycap_alsa_complete; #endif /* CONFIG_EASYCAP_OSS */ - purb->context = peasycap; - purb->start_frame = 0; - purb->number_of_packets = peasycap->audio_isoc_framesperdesc; - for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) { - purb->iso_frame_desc[j].offset = j * - peasycap->audio_isoc_maxframesize; - purb->iso_frame_desc[j].length = - peasycap->audio_isoc_maxframesize; + purb->context = peasycap; + purb->start_frame = 0; + purb->number_of_packets = peasycap->audio_isoc_framesperdesc; + for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) { + purb->iso_frame_desc[j].offset = j * + peasycap->audio_isoc_maxframesize; + purb->iso_frame_desc[j].length = + peasycap->audio_isoc_maxframesize; + } } - } - JOM(4, "allocation of %i struct urb done.\n", k); + JOM(4, "allocation of %i struct urb done.\n", k); /*---------------------------------------------------------------------------*/ /* * SAVE POINTER peasycap IN THIS INTERFACE. */ /*---------------------------------------------------------------------------*/ - usb_set_intfdata(pusb_interface, peasycap); + usb_set_intfdata(pusb_interface, peasycap); /*---------------------------------------------------------------------------*/ /* * THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY. */ /*---------------------------------------------------------------------------*/ #ifndef CONFIG_EASYCAP_OSS - JOM(4, "initializing ALSA card\n"); + JOM(4, "initializing ALSA card\n"); - rc = easycap_alsa_probe(peasycap); - if (rc) { - err("easycap_alsa_probe() returned %i\n", rc); - return -ENODEV; - } else { - JOM(8, "kref_get() with %i=peasycap->kref.refcount.counter\n", - (int)peasycap->kref.refcount.counter); - kref_get(&peasycap->kref); - (peasycap->registered_audio)++; - } + rc = easycap_alsa_probe(peasycap); + if (rc) { + err("easycap_alsa_probe() returned %i\n", rc); + return -ENODEV; + } else { + JOM(8, "kref_get() with %i=peasycap->kref.refcount.counter\n", + (int)peasycap->kref.refcount.counter); + kref_get(&peasycap->kref); + (peasycap->registered_audio)++; + } #else /* CONFIG_EASYCAP_OSS */ - rc = usb_register_dev(pusb_interface, &easyoss_class); - if (rc) { - SAY("ERROR: usb_register_dev() failed\n"); - usb_set_intfdata(pusb_interface, NULL); - return -ENODEV; - } else { - JOM(8, "kref_get() with %i=peasycap->kref.refcount.counter\n", - (int)peasycap->kref.refcount.counter); - kref_get(&peasycap->kref); - (peasycap->registered_audio)++; - } + rc = usb_register_dev(pusb_interface, &easyoss_class); + if (rc) { + SAY("ERROR: usb_register_dev() failed\n"); + usb_set_intfdata(pusb_interface, NULL); + return -ENODEV; + } else { + JOM(8, "kref_get() with %i=peasycap->kref.refcount.counter\n", + (int)peasycap->kref.refcount.counter); + kref_get(&peasycap->kref); + (peasycap->registered_audio)++; + } /*---------------------------------------------------------------------------*/ /* * LET THE USER KNOW WHAT NODE THE AUDIO DEVICE IS ATTACHED TO. */ /*---------------------------------------------------------------------------*/ - SAM("easyoss attached to minor #%d\n", pusb_interface->minor); + SAM("easyoss attached to minor #%d\n", pusb_interface->minor); #endif /* CONFIG_EASYCAP_OSS */ - break; + break; } /*---------------------------------------------------------------------------*/ /* * INTERFACES OTHER THAN 0, 1 AND 2 ARE UNEXPECTED */ /*---------------------------------------------------------------------------*/ -default: { - JOM(4, "ERROR: unexpected interface %i\n", bInterfaceNumber); - return -EINVAL; -} -} -SAM("ends successfully for interface %i\n", - pusb_interface_descriptor->bInterfaceNumber); -return 0; + default: { + JOM(4, "ERROR: unexpected interface %i\n", bInterfaceNumber); + return -EINVAL; + } + } + SAM("ends successfully for interface %i\n", + pusb_interface_descriptor->bInterfaceNumber); + return 0; } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ @@ -4550,50 +4550,50 @@ return 0; /*---------------------------------------------------------------------------*/ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) { -struct usb_host_interface *pusb_host_interface; -struct usb_interface_descriptor *pusb_interface_descriptor; -u8 bInterfaceNumber; -struct easycap *peasycap; - -struct list_head *plist_head; -struct data_urb *pdata_urb; -int minor, m, kd; + struct usb_host_interface *pusb_host_interface; + struct usb_interface_descriptor *pusb_interface_descriptor; + u8 bInterfaceNumber; + struct easycap *peasycap; + + struct list_head *plist_head; + struct data_urb *pdata_urb; + int minor, m, kd; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #ifdef EASYCAP_IS_VIDEODEV_CLIENT #ifdef EASYCAP_NEEDS_V4L2_DEVICE_H -struct v4l2_device *pv4l2_device; + struct v4l2_device *pv4l2_device; #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -JOT(4, "\n"); + JOT(4, "\n"); -if (NULL == pusb_interface) { - JOT(4, "ERROR: pusb_interface is NULL\n"); - return; -} -pusb_host_interface = pusb_interface->cur_altsetting; -if (NULL == pusb_host_interface) { - JOT(4, "ERROR: pusb_host_interface is NULL\n"); - return; -} -pusb_interface_descriptor = &(pusb_host_interface->desc); -if (NULL == pusb_interface_descriptor) { - JOT(4, "ERROR: pusb_interface_descriptor is NULL\n"); - return; -} -bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber; -minor = pusb_interface->minor; -JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber, minor); + if (NULL == pusb_interface) { + JOT(4, "ERROR: pusb_interface is NULL\n"); + return; + } + pusb_host_interface = pusb_interface->cur_altsetting; + if (NULL == pusb_host_interface) { + JOT(4, "ERROR: pusb_host_interface is NULL\n"); + return; + } + pusb_interface_descriptor = &(pusb_host_interface->desc); + if (NULL == pusb_interface_descriptor) { + JOT(4, "ERROR: pusb_interface_descriptor is NULL\n"); + return; + } + bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber; + minor = pusb_interface->minor; + JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber, minor); -if (1 == bInterfaceNumber) - return; + if (1 == bInterfaceNumber) + return; -peasycap = usb_get_intfdata(pusb_interface); -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return; -} + peasycap = usb_get_intfdata(pusb_interface); + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return; + } /*---------------------------------------------------------------------------*/ #ifdef EASYCAP_IS_VIDEODEV_CLIENT #ifdef EASYCAP_NEEDS_V4L2_DEVICE_H @@ -4605,77 +4605,77 @@ if (NULL == peasycap) { * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED. */ /*---------------------------------------------------------------------------*/ -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - pv4l2_device = usb_get_intfdata(pusb_interface); - if (NULL == pv4l2_device) { - SAY("ERROR: pv4l2_device is NULL\n"); - return; + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + pv4l2_device = usb_get_intfdata(pusb_interface); + if (NULL == pv4l2_device) { + SAY("ERROR: pv4l2_device is NULL\n"); + return; + } + peasycap = (struct easycap *) + container_of(pv4l2_device, struct easycap, v4l2_device); } - peasycap = (struct easycap *) - container_of(pv4l2_device, struct easycap, v4l2_device); -} #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ # #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*---------------------------------------------------------------------------*/ -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); - return; -} + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + return; + } /*---------------------------------------------------------------------------*/ /* * IF THE WAIT QUEUES ARE NOT CLEARED A DEADLOCK IS POSSIBLE. BEWARE. */ /*---------------------------------------------------------------------------*/ -peasycap->video_eof = 1; -peasycap->audio_eof = 1; -wake_up_interruptible(&(peasycap->wq_video)); -wake_up_interruptible(&(peasycap->wq_audio)); -/*---------------------------------------------------------------------------*/ -switch (bInterfaceNumber) { -case 0: { - if (NULL != peasycap->purb_video_head) { - JOM(4, "killing video urbs\n"); - m = 0; - list_for_each(plist_head, (peasycap->purb_video_head)) - { - pdata_urb = list_entry(plist_head, - struct data_urb, list_head); - if (NULL != pdata_urb) { - if (NULL != pdata_urb->purb) { - usb_kill_urb(pdata_urb->purb); - m++; + peasycap->video_eof = 1; + peasycap->audio_eof = 1; + wake_up_interruptible(&(peasycap->wq_video)); + wake_up_interruptible(&(peasycap->wq_audio)); +/*---------------------------------------------------------------------------*/ + switch (bInterfaceNumber) { + case 0: { + if (NULL != peasycap->purb_video_head) { + JOM(4, "killing video urbs\n"); + m = 0; + list_for_each(plist_head, (peasycap->purb_video_head)) + { + pdata_urb = list_entry(plist_head, + struct data_urb, list_head); + if (NULL != pdata_urb) { + if (NULL != pdata_urb->purb) { + usb_kill_urb(pdata_urb->purb); + m++; + } } } + JOM(4, "%i video urbs killed\n", m); } - JOM(4, "%i video urbs killed\n", m); + break; } - break; -} /*---------------------------------------------------------------------------*/ -case 2: { - if (NULL != peasycap->purb_audio_head) { - JOM(4, "killing audio urbs\n"); - m = 0; - list_for_each(plist_head, - (peasycap->purb_audio_head)) { - pdata_urb = list_entry(plist_head, - struct data_urb, list_head); - if (NULL != pdata_urb) { - if (NULL != pdata_urb->purb) { - usb_kill_urb(pdata_urb->purb); - m++; + case 2: { + if (NULL != peasycap->purb_audio_head) { + JOM(4, "killing audio urbs\n"); + m = 0; + list_for_each(plist_head, + (peasycap->purb_audio_head)) { + pdata_urb = list_entry(plist_head, + struct data_urb, list_head); + if (NULL != pdata_urb) { + if (NULL != pdata_urb->purb) { + usb_kill_urb(pdata_urb->purb); + m++; + } } } + JOM(4, "%i audio urbs killed\n", m); } - JOM(4, "%i audio urbs killed\n", m); + break; } - break; -} /*---------------------------------------------------------------------------*/ -default: - break; + default: + break; } /*--------------------------------------------------------------------------*/ /* -- cgit v1.2.3 From 072e9f609cd6d144b64da50b03b712d87b302e12 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 1 Feb 2011 15:41:32 +0000 Subject: staging: et131x: Turn a few more LongCapitalisedThings into Linuxish names Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et1310_eeprom.c | 8 ++--- drivers/staging/et131x/et1310_mac.c | 52 ++++++++++++++++----------------- drivers/staging/et131x/et1310_phy.c | 4 +-- drivers/staging/et131x/et1310_pm.c | 26 ++++++++--------- drivers/staging/et131x/et1310_rx.c | 17 +++++------ drivers/staging/et131x/et131x_adapter.h | 8 ++--- drivers/staging/et131x/et131x_initpci.c | 42 +++++++++++++------------- drivers/staging/et131x/et131x_netdev.c | 2 +- 8 files changed, 79 insertions(+), 80 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/et131x/et1310_eeprom.c b/drivers/staging/et131x/et1310_eeprom.c index 5a8e6b913dab..237584001a8f 100644 --- a/drivers/staging/et131x/et1310_eeprom.c +++ b/drivers/staging/et131x/et1310_eeprom.c @@ -396,12 +396,12 @@ int et131x_init_eeprom(struct et131x_adapter *etdev) /* Read the EEPROM for information regarding LED behavior. Refer to * ET1310_phy.c, et131x_xcvr_init(), for its use. */ - eeprom_read(etdev, 0x70, &etdev->eepromData[0]); - eeprom_read(etdev, 0x71, &etdev->eepromData[1]); + eeprom_read(etdev, 0x70, &etdev->eeprom_data[0]); + eeprom_read(etdev, 0x71, &etdev->eeprom_data[1]); - if (etdev->eepromData[0] != 0xcd) + if (etdev->eeprom_data[0] != 0xcd) /* Disable all optional features */ - etdev->eepromData[1] = 0x00; + etdev->eeprom_data[1] = 0x00; return 0; } diff --git a/drivers/staging/et131x/et1310_mac.c b/drivers/staging/et131x/et1310_mac.c index 16fa13d4821f..43da53964548 100644 --- a/drivers/staging/et131x/et1310_mac.c +++ b/drivers/staging/et131x/et1310_mac.c @@ -136,12 +136,12 @@ void ConfigMACRegs1(struct et131x_adapter *etdev) * station address is used for generating and checking pause control * packets. */ - station2.bits.Octet1 = etdev->CurrentAddress[0]; - station2.bits.Octet2 = etdev->CurrentAddress[1]; - station1.bits.Octet3 = etdev->CurrentAddress[2]; - station1.bits.Octet4 = etdev->CurrentAddress[3]; - station1.bits.Octet5 = etdev->CurrentAddress[4]; - station1.bits.Octet6 = etdev->CurrentAddress[5]; + station2.bits.Octet1 = etdev->addr[0]; + station2.bits.Octet2 = etdev->addr[1]; + station1.bits.Octet3 = etdev->addr[2]; + station1.bits.Octet4 = etdev->addr[3]; + station1.bits.Octet5 = etdev->addr[4]; + station1.bits.Octet6 = etdev->addr[5]; writel(station1.value, &pMac->station_addr_1.value); writel(station2.value, &pMac->station_addr_2.value); @@ -280,14 +280,14 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev) writel(0, &pRxMac->mask4_word3); /* Lets setup the WOL Source Address */ - sa_lo.bits.sa3 = etdev->CurrentAddress[2]; - sa_lo.bits.sa4 = etdev->CurrentAddress[3]; - sa_lo.bits.sa5 = etdev->CurrentAddress[4]; - sa_lo.bits.sa6 = etdev->CurrentAddress[5]; + sa_lo.bits.sa3 = etdev->addr[2]; + sa_lo.bits.sa4 = etdev->addr[3]; + sa_lo.bits.sa5 = etdev->addr[4]; + sa_lo.bits.sa6 = etdev->addr[5]; writel(sa_lo.value, &pRxMac->sa_lo.value); - sa_hi.bits.sa1 = etdev->CurrentAddress[0]; - sa_hi.bits.sa2 = etdev->CurrentAddress[1]; + sa_hi.bits.sa1 = etdev->addr[0]; + sa_hi.bits.sa2 = etdev->addr[1]; writel(sa_hi.value, &pRxMac->sa_hi.value); /* Disable all Packet Filtering */ @@ -597,20 +597,20 @@ void SetupDeviceForUnicast(struct et131x_adapter *etdev) * Set up unicast packet filter reg 3 to be the octets 2 - 5 of the * MAC address for first address */ - uni_pf3.bits.addr1_1 = etdev->CurrentAddress[0]; - uni_pf3.bits.addr1_2 = etdev->CurrentAddress[1]; - uni_pf3.bits.addr2_1 = etdev->CurrentAddress[0]; - uni_pf3.bits.addr2_2 = etdev->CurrentAddress[1]; - - uni_pf2.bits.addr2_3 = etdev->CurrentAddress[2]; - uni_pf2.bits.addr2_4 = etdev->CurrentAddress[3]; - uni_pf2.bits.addr2_5 = etdev->CurrentAddress[4]; - uni_pf2.bits.addr2_6 = etdev->CurrentAddress[5]; - - uni_pf1.bits.addr1_3 = etdev->CurrentAddress[2]; - uni_pf1.bits.addr1_4 = etdev->CurrentAddress[3]; - uni_pf1.bits.addr1_5 = etdev->CurrentAddress[4]; - uni_pf1.bits.addr1_6 = etdev->CurrentAddress[5]; + uni_pf3.bits.addr1_1 = etdev->addr[0]; + uni_pf3.bits.addr1_2 = etdev->addr[1]; + uni_pf3.bits.addr2_1 = etdev->addr[0]; + uni_pf3.bits.addr2_2 = etdev->addr[1]; + + uni_pf2.bits.addr2_3 = etdev->addr[2]; + uni_pf2.bits.addr2_4 = etdev->addr[3]; + uni_pf2.bits.addr2_5 = etdev->addr[4]; + uni_pf2.bits.addr2_6 = etdev->addr[5]; + + uni_pf1.bits.addr1_3 = etdev->addr[2]; + uni_pf1.bits.addr1_4 = etdev->addr[3]; + uni_pf1.bits.addr1_5 = etdev->addr[4]; + uni_pf1.bits.addr1_6 = etdev->addr[5]; pm_csr = readl(&etdev->regs->global.pm_csr); if ((pm_csr & ET_PM_PHY_SW_COMA) == 0) { diff --git a/drivers/staging/et131x/et1310_phy.c b/drivers/staging/et131x/et1310_phy.c index 21c5eeec62dd..f07e03399535 100644 --- a/drivers/staging/et131x/et1310_phy.c +++ b/drivers/staging/et131x/et1310_phy.c @@ -604,10 +604,10 @@ static void et131x_xcvr_init(struct et131x_adapter *etdev) * vendors; The LED behavior is now determined by vendor data in the * EEPROM. However, the above description is the default. */ - if ((etdev->eepromData[1] & 0x4) == 0) { + if ((etdev->eeprom_data[1] & 0x4) == 0) { MiRead(etdev, (u8) offsetof(MI_REGS_t, lcr2), &lcr2.value); - if ((etdev->eepromData[1] & 0x8) == 0) + if ((etdev->eeprom_data[1] & 0x8) == 0) lcr2.bits.led_tx_rx = 0x3; else lcr2.bits.led_tx_rx = 0x4; diff --git a/drivers/staging/et131x/et1310_pm.c b/drivers/staging/et131x/et1310_pm.c index c64bb2c6d0d6..2b6b29548656 100644 --- a/drivers/staging/et131x/et1310_pm.c +++ b/drivers/staging/et131x/et1310_pm.c @@ -109,9 +109,9 @@ void EnablePhyComa(struct et131x_adapter *etdev) { unsigned long flags; - u32 GlobalPmCSR; + u32 pmcsr; - GlobalPmCSR = readl(&etdev->regs->global.pm_csr); + pmcsr = readl(&etdev->regs->global.pm_csr); /* Save the GbE PHY speed and duplex modes. Need to restore this * when cable is plugged back in @@ -120,19 +120,19 @@ void EnablePhyComa(struct et131x_adapter *etdev) etdev->PoMgmt.PowerDownDuplex = etdev->AiForceDpx; /* Stop sending packets. */ - spin_lock_irqsave(&etdev->SendHWLock, flags); + spin_lock_irqsave(&etdev->send_hw_lock, flags); etdev->Flags |= fMP_ADAPTER_LOWER_POWER; - spin_unlock_irqrestore(&etdev->SendHWLock, flags); + spin_unlock_irqrestore(&etdev->send_hw_lock, flags); /* Wait for outstanding Receive packets */ /* Gate off JAGCore 3 clock domains */ - GlobalPmCSR &= ~ET_PMCSR_INIT; - writel(GlobalPmCSR, &etdev->regs->global.pm_csr); + pmcsr &= ~ET_PMCSR_INIT; + writel(pmcsr, &etdev->regs->global.pm_csr); /* Program gigE PHY in to Coma mode */ - GlobalPmCSR |= ET_PM_PHY_SW_COMA; - writel(GlobalPmCSR, &etdev->regs->global.pm_csr); + pmcsr |= ET_PM_PHY_SW_COMA; + writel(pmcsr, &etdev->regs->global.pm_csr); } /** @@ -141,14 +141,14 @@ void EnablePhyComa(struct et131x_adapter *etdev) */ void DisablePhyComa(struct et131x_adapter *etdev) { - u32 GlobalPmCSR; + u32 pmcsr; - GlobalPmCSR = readl(&etdev->regs->global.pm_csr); + pmcsr = readl(&etdev->regs->global.pm_csr); /* Disable phy_sw_coma register and re-enable JAGCore clocks */ - GlobalPmCSR |= ET_PMCSR_INIT; - GlobalPmCSR &= ~ET_PM_PHY_SW_COMA; - writel(GlobalPmCSR, &etdev->regs->global.pm_csr); + pmcsr |= ET_PMCSR_INIT; + pmcsr &= ~ET_PM_PHY_SW_COMA; + writel(pmcsr, &etdev->regs->global.pm_csr); /* Restore the GbE PHY speed and duplex modes; * Reset JAGCore; re-configure and initialize JAGCore and gigE PHY diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c index 8e04bdd8f6b6..8220f1bf64d9 100644 --- a/drivers/staging/et131x/et1310_rx.c +++ b/drivers/staging/et131x/et1310_rx.c @@ -622,7 +622,7 @@ void ConfigRxDmaRegs(struct et131x_adapter *etdev) writel((psr_num_des * LO_MARK_PERCENT_FOR_PSR) / 100, &rx_dma->psr_min_des); - spin_lock_irqsave(&etdev->RcvLock, flags); + spin_lock_irqsave(&etdev->rcv_lock, flags); /* These local variables track the PSR in the adapter structure */ rx_local->local_psr_full = 0; @@ -688,7 +688,7 @@ void ConfigRxDmaRegs(struct et131x_adapter *etdev) */ writel(PARM_RX_TIME_INT_DEF, &rx_dma->max_pkt_time); - spin_unlock_irqrestore(&etdev->RcvLock, flags); + spin_unlock_irqrestore(&etdev->rcv_lock, flags); } /** @@ -854,21 +854,21 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) } /* Get and fill the RFD. */ - spin_lock_irqsave(&etdev->RcvLock, flags); + spin_lock_irqsave(&etdev->rcv_lock, flags); rfd = NULL; element = rx_local->RecvList.next; rfd = (PMP_RFD) list_entry(element, MP_RFD, list_node); if (rfd == NULL) { - spin_unlock_irqrestore(&etdev->RcvLock, flags); + spin_unlock_irqrestore(&etdev->rcv_lock, flags); return NULL; } list_del(&rfd->list_node); rx_local->nReadyRecv--; - spin_unlock_irqrestore(&etdev->RcvLock, flags); + spin_unlock_irqrestore(&etdev->rcv_lock, flags); rfd->bufferindex = bindex; rfd->ringindex = rindex; @@ -887,8 +887,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) if (etdev->ReplicaPhyLoopbk == 1) { buf = rx_local->fbr[rindex]->virt[bindex]; - if (memcmp(&buf[6], &etdev->CurrentAddress[0], - ETH_ALEN) == 0) { + if (memcmp(&buf[6], etdev->addr, ETH_ALEN) == 0) { if (memcmp(&buf[42], "Replica packet", ETH_HLEN)) { etdev->ReplicaPhyLoopbkPF = 1; @@ -1146,10 +1145,10 @@ void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD rfd) /* The processing on this RFD is done, so put it back on the tail of * our list */ - spin_lock_irqsave(&etdev->RcvLock, flags); + spin_lock_irqsave(&etdev->rcv_lock, flags); list_add_tail(&rfd->list_node, &rx_local->RecvList); rx_local->nReadyRecv++; - spin_unlock_irqrestore(&etdev->RcvLock, flags); + spin_unlock_irqrestore(&etdev->rcv_lock, flags); WARN_ON(rx_local->nReadyRecv > rx_local->NumRfd); } diff --git a/drivers/staging/et131x/et131x_adapter.h b/drivers/staging/et131x/et131x_adapter.h index 64a678fcb60a..2398a6ec8aca 100644 --- a/drivers/staging/et131x/et131x_adapter.h +++ b/drivers/staging/et131x/et131x_adapter.h @@ -173,17 +173,17 @@ struct et131x_adapter { u32 HwErrCount; /* Configuration */ - u8 PermanentAddress[ETH_ALEN]; - u8 CurrentAddress[ETH_ALEN]; + u8 rom_addr[ETH_ALEN]; + u8 addr[ETH_ALEN]; bool has_eeprom; - u8 eepromData[2]; + u8 eeprom_data[2]; /* Spinlocks */ spinlock_t Lock; spinlock_t TCBSendQLock; spinlock_t TCBReadyQLock; - spinlock_t SendHWLock; + spinlock_t send_hw_lock; spinlock_t RcvLock; spinlock_t RcvPendLock; diff --git a/drivers/staging/et131x/et131x_initpci.c b/drivers/staging/et131x/et131x_initpci.c index f62ba7a68f34..4d13e7fdfa61 100644 --- a/drivers/staging/et131x/et131x_initpci.c +++ b/drivers/staging/et131x/et131x_initpci.c @@ -131,32 +131,32 @@ void et131x_hwaddr_init(struct et131x_adapter *adapter) * EEPROM then we need to generate the last octet and set it on the * device */ - if (adapter->PermanentAddress[0] == 0x00 && - adapter->PermanentAddress[1] == 0x00 && - adapter->PermanentAddress[2] == 0x00 && - adapter->PermanentAddress[3] == 0x00 && - adapter->PermanentAddress[4] == 0x00 && - adapter->PermanentAddress[5] == 0x00) { + if (adapter->rom_addr[0] == 0x00 && + adapter->rom_addr[1] == 0x00 && + adapter->rom_addr[2] == 0x00 && + adapter->rom_addr[3] == 0x00 && + adapter->rom_addr[4] == 0x00 && + adapter->rom_addr[5] == 0x00) { /* * We need to randomly generate the last octet so we * decrease our chances of setting the mac address to * same as another one of our cards in the system */ - get_random_bytes(&adapter->CurrentAddress[5], 1); + get_random_bytes(&adapter->addr[5], 1); /* * We have the default value in the register we are * working with so we need to copy the current * address into the permanent address */ - memcpy(adapter->PermanentAddress, - adapter->CurrentAddress, ETH_ALEN); + memcpy(adapter->rom_addr, + adapter->addr, ETH_ALEN); } else { /* We do not have an override address, so set the * current address to the permanent address and add * it to the device */ - memcpy(adapter->CurrentAddress, - adapter->PermanentAddress, ETH_ALEN); + memcpy(adapter->addr, + adapter->rom_addr, ETH_ALEN); } } @@ -193,17 +193,17 @@ static int et131x_pci_init(struct et131x_adapter *adapter, max_payload &= 0x07; /* Only the lower 3 bits are valid */ if (max_payload < 2) { - static const u16 AckNak[2] = { 0x76, 0xD0 }; - static const u16 Replay[2] = { 0x1E0, 0x2ED }; + static const u16 acknak[2] = { 0x76, 0xD0 }; + static const u16 replay[2] = { 0x1E0, 0x2ED }; if (pci_write_config_word(pdev, ET1310_PCI_ACK_NACK, - AckNak[max_payload])) { + acknak[max_payload])) { dev_err(&pdev->dev, "Could not write PCI config space for ACK/NAK\n"); return -EIO; } if (pci_write_config_word(pdev, ET1310_PCI_REPLAY, - Replay[max_payload])) { + replay[max_payload])) { dev_err(&pdev->dev, "Could not write PCI config space for Replay Timer\n"); return -EIO; @@ -245,12 +245,12 @@ static int et131x_pci_init(struct et131x_adapter *adapter, for (i = 0; i < ETH_ALEN; i++) { if (pci_read_config_byte(pdev, ET1310_PCI_MAC_ADDRESS + i, - adapter->PermanentAddress + i)) { + adapter->rom_addr + i)) { dev_err(&pdev->dev, "Could not read PCI config space for MAC address\n"); return -EIO; } } - memcpy(adapter->CurrentAddress, adapter->PermanentAddress, ETH_ALEN); + memcpy(adapter->addr, adapter->rom_addr, ETH_ALEN); return 0; } @@ -555,8 +555,8 @@ static struct et131x_adapter *et131x_adapter_init(struct net_device *netdev, spin_lock_init(&etdev->Lock); spin_lock_init(&etdev->TCBSendQLock); spin_lock_init(&etdev->TCBReadyQLock); - spin_lock_init(&etdev->SendHWLock); - spin_lock_init(&etdev->RcvLock); + spin_lock_init(&etdev->send_hw_lock); + spin_lock_init(&etdev->rcv_lock); spin_lock_init(&etdev->RcvPendLock); spin_lock_init(&etdev->FbrLock); spin_lock_init(&etdev->PHYLock); @@ -570,7 +570,7 @@ static struct et131x_adapter *et131x_adapter_init(struct net_device *netdev, etdev->RegistryJumboPacket = 1514; /* 1514-9216 */ /* Set the MAC address to a default */ - memcpy(etdev->CurrentAddress, default_mac, ETH_ALEN); + memcpy(etdev->addr, default_mac, ETH_ALEN); /* Decode SpeedDuplex * @@ -711,7 +711,7 @@ static int __devinit et131x_pci_setup(struct pci_dev *pdev, INIT_WORK(&adapter->task, et131x_isr_handler); /* Copy address into the net_device struct */ - memcpy(netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN); + memcpy(netdev->dev_addr, adapter->addr, ETH_ALEN); /* Setup et1310 as per the documentation */ et131x_adapter_setup(adapter); diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c index 106d548982c4..0c298cae90d9 100644 --- a/drivers/staging/et131x/et131x_netdev.c +++ b/drivers/staging/et131x/et131x_netdev.c @@ -603,7 +603,7 @@ int et131x_change_mtu(struct net_device *netdev, int new_mtu) et131x_init_send(adapter); et131x_hwaddr_init(adapter); - memcpy(netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN); + memcpy(netdev->dev_addr, adapter->addr, ETH_ALEN); /* Init the device with the new settings */ et131x_adapter_setup(adapter); -- cgit v1.2.3 From ae3a08aab5e0700d3f80162bed07a2157bd304f4 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 1 Feb 2011 15:41:45 +0000 Subject: staging: et131x: Kill of the eFLOW_CONTROL enum Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et1310_mac.c | 22 +++++++++++----------- drivers/staging/et131x/et1310_phy.c | 12 ++++++------ drivers/staging/et131x/et1310_tx.c | 4 ++-- drivers/staging/et131x/et131x_adapter.h | 20 +++++++++----------- drivers/staging/et131x/et131x_isr.c | 10 +++++----- 5 files changed, 33 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/et131x/et1310_mac.c b/drivers/staging/et131x/et1310_mac.c index 43da53964548..78f72fa5d5e9 100644 --- a/drivers/staging/et131x/et1310_mac.c +++ b/drivers/staging/et131x/et1310_mac.c @@ -191,7 +191,7 @@ void ConfigMACRegs2(struct et131x_adapter *etdev) cfg1 |= CFG1_RX_ENABLE|CFG1_TX_ENABLE|CFG1_TX_FLOW; /* Initialize loop back to off */ cfg1 &= ~(CFG1_LOOPBACK|CFG1_RX_FLOW); - if (etdev->FlowControl == RxOnly || etdev->FlowControl == Both) + if (etdev->flowcontrol == FLOW_RXONLY || etdev->flowcontrol == FLOW_BOTH) cfg1 |= CFG1_RX_FLOW; writel(cfg1, &pMac->cfg1); @@ -373,7 +373,7 @@ void ConfigTxMacRegs(struct et131x_adapter *etdev) * cfpt - control frame pause timer set to 64 (0x40) * cfep - control frame extended pause timer set to 0x0 */ - if (etdev->FlowControl == None) + if (etdev->flowcontrol == FLOW_NONE) writel(0, &txmac->cf_param); else writel(0x40, &txmac->cf_param); @@ -414,7 +414,7 @@ void ConfigMacStatRegs(struct et131x_adapter *etdev) void ConfigFlowControl(struct et131x_adapter *etdev) { if (etdev->duplex_mode == 0) { - etdev->FlowControl = None; + etdev->flowcontrol = FLOW_NONE; } else { char remote_pause, remote_async_pause; @@ -426,22 +426,22 @@ void ConfigFlowControl(struct et131x_adapter *etdev) if ((remote_pause == TRUEPHY_BIT_SET) && (remote_async_pause == TRUEPHY_BIT_SET)) { - etdev->FlowControl = etdev->RegistryFlowControl; + etdev->flowcontrol = etdev->wanted_flow; } else if ((remote_pause == TRUEPHY_BIT_SET) && (remote_async_pause == TRUEPHY_BIT_CLEAR)) { - if (etdev->RegistryFlowControl == Both) - etdev->FlowControl = Both; + if (etdev->wanted_flow == FLOW_BOTH) + etdev->flowcontrol = FLOW_BOTH; else - etdev->FlowControl = None; + etdev->flowcontrol = FLOW_NONE; } else if ((remote_pause == TRUEPHY_BIT_CLEAR) && (remote_async_pause == TRUEPHY_BIT_CLEAR)) { - etdev->FlowControl = None; + etdev->flowcontrol = FLOW_NONE; } else {/* if (remote_pause == TRUEPHY_CLEAR_BIT && remote_async_pause == TRUEPHY_SET_BIT) */ - if (etdev->RegistryFlowControl == Both) - etdev->FlowControl = RxOnly; + if (etdev->wanted_flow == FLOW_BOTH) + etdev->flowcontrol = FLOW_RXONLY; else - etdev->FlowControl = None; + etdev->flowcontrol = FLOW_NONE; } } } diff --git a/drivers/staging/et131x/et1310_phy.c b/drivers/staging/et131x/et1310_phy.c index f07e03399535..5eab21ac00f4 100644 --- a/drivers/staging/et131x/et1310_phy.c +++ b/drivers/staging/et131x/et1310_phy.c @@ -618,15 +618,15 @@ static void et131x_xcvr_init(struct et131x_adapter *etdev) /* Determine if we need to go into a force mode and set it */ if (etdev->AiForceSpeed == 0 && etdev->AiForceDpx == 0) { - if (etdev->RegistryFlowControl == TxOnly || - etdev->RegistryFlowControl == Both) + if (etdev->wanted_flow == FLOW_TXONLY || + etdev->wanted_flow == FLOW_BOTH) ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_SET, 4, 11, NULL); else ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_CLEAR, 4, 11, NULL); - if (etdev->RegistryFlowControl == Both) + if (etdev->wanted_flow == FLOW_BOTH) ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_SET, 4, 10, NULL); else @@ -645,15 +645,15 @@ static void et131x_xcvr_init(struct et131x_adapter *etdev) /* Set to the correct force mode. */ if (etdev->AiForceDpx != 1) { - if (etdev->RegistryFlowControl == TxOnly || - etdev->RegistryFlowControl == Both) + if (etdev->wanted_flow == FLOW_TXONLY || + etdev->wanted_flow == FLOW_BOTH) ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_SET, 4, 11, NULL); else ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_CLEAR, 4, 11, NULL); - if (etdev->RegistryFlowControl == Both) + if (etdev->wanted_flow == FLOW_BOTH) ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_SET, 4, 10, NULL); else diff --git a/drivers/staging/et131x/et1310_tx.c b/drivers/staging/et131x/et1310_tx.c index 0f3473d758e4..4241d2afecc0 100644 --- a/drivers/staging/et131x/et1310_tx.c +++ b/drivers/staging/et131x/et1310_tx.c @@ -547,7 +547,7 @@ static int nic_send_packet(struct et131x_adapter *etdev, struct tcb *tcb) tcb->index_start = etdev->tx_ring.send_idx; tcb->stale = 0; - spin_lock_irqsave(&etdev->SendHWLock, flags); + spin_lock_irqsave(&etdev->send_hw_lock, flags); thiscopy = NUM_DESC_PER_RING_TX - INDEX10(etdev->tx_ring.send_idx); @@ -613,7 +613,7 @@ static int nic_send_packet(struct et131x_adapter *etdev, struct tcb *tcb) writel(PARM_TX_TIME_INT_DEF * NANO_IN_A_MICRO, &etdev->regs->global.watchdog_timer); } - spin_unlock_irqrestore(&etdev->SendHWLock, flags); + spin_unlock_irqrestore(&etdev->send_hw_lock, flags); return 0; } diff --git a/drivers/staging/et131x/et131x_adapter.h b/drivers/staging/et131x/et131x_adapter.h index 2398a6ec8aca..430947b39673 100644 --- a/drivers/staging/et131x/et131x_adapter.h +++ b/drivers/staging/et131x/et131x_adapter.h @@ -91,13 +91,11 @@ typedef struct _MP_RFD { u8 ringindex; } MP_RFD, *PMP_RFD; -/* Enum for Flow Control */ -typedef enum _eflow_control_t { - Both = 0, - TxOnly = 1, - RxOnly = 2, - None = 3 -} eFLOW_CONTROL_t, *PeFLOW_CONTROL_t; +/* Flow Control */ +#define FLOW_BOTH 0 +#define FLOW_TXONLY 1 +#define FLOW_RXONLY 2 +#define FLOW_NONE 3 /* Struct to define some device statistics */ typedef struct _ce_stats_t { @@ -185,7 +183,7 @@ struct et131x_adapter { spinlock_t TCBReadyQLock; spinlock_t send_hw_lock; - spinlock_t RcvLock; + spinlock_t rcv_lock; spinlock_t RcvPendLock; spinlock_t FbrLock; @@ -205,7 +203,7 @@ struct et131x_adapter { /* Registry parameters */ u8 SpeedDuplex; /* speed/duplex */ - eFLOW_CONTROL_t RegistryFlowControl; /* for 802.3x flow control */ + u8 wanted_flow; /* Flow we want for 802.3x flow control */ u8 RegistryPhyComa; /* Phy Coma mode enable/disable */ u32 RegistryRxMemEnd; /* Size of internal rx memory */ @@ -214,8 +212,8 @@ struct et131x_adapter { /* Derived from the registry: */ u8 AiForceDpx; /* duplex setting */ - u16 AiForceSpeed; /* 'Speed', user over-ride of line speed */ - eFLOW_CONTROL_t FlowControl; /* flow control validated by the far-end */ + u16 AiForceSpeed; /* 'Speed', user over-ride of line speed */ + u8 flowcontrol; /* flow control validated by the far-end */ enum { NETIF_STATUS_INVALID = 0, NETIF_STATUS_MEDIA_CONNECT, diff --git a/drivers/staging/et131x/et131x_isr.c b/drivers/staging/et131x/et131x_isr.c index 36f68fe3e8c9..0cc6c68fdfda 100644 --- a/drivers/staging/et131x/et131x_isr.c +++ b/drivers/staging/et131x/et131x_isr.c @@ -119,7 +119,7 @@ void et131x_enable_interrupts(struct et131x_adapter *adapter) u32 mask; /* Enable all global interrupts */ - if (adapter->FlowControl == TxOnly || adapter->FlowControl == Both) + if (adapter->flowcontrol == FLOW_TXONLY || adapter->flowcontrol == FLOW_BOTH) mask = INT_MASK_ENABLE; else mask = INT_MASK_ENABLE_NO_FLOW; @@ -177,8 +177,8 @@ irqreturn_t et131x_isr(int irq, void *dev_id) */ status = readl(&adapter->regs->global.int_status); - if (adapter->FlowControl == TxOnly || - adapter->FlowControl == Both) { + if (adapter->flowcontrol == FLOW_TXONLY || + adapter->flowcontrol == FLOW_BOTH) { status &= ~INT_MASK_ENABLE; } else { status &= ~INT_MASK_ENABLE_NO_FLOW; @@ -295,8 +295,8 @@ void et131x_isr_handler(struct work_struct *work) /* If the user has flow control on, then we will * send a pause packet, otherwise just exit */ - if (etdev->FlowControl == TxOnly || - etdev->FlowControl == Both) { + if (etdev->flowcontrol == FLOW_TXONLY || + etdev->flowcontrol == FLOW_BOTH) { u32 pm_csr; /* Tell the device to send a pause packet via -- cgit v1.2.3 From 64b728319bed41ef14462a1a504c65656e5a50a4 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 1 Feb 2011 15:41:58 +0000 Subject: staging: et131x: Clean up the phy coma stuff Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et1310_phy.c | 4 ++-- drivers/staging/et131x/et1310_pm.c | 8 ++++---- drivers/staging/et131x/et131x_adapter.h | 27 +++++++++++++-------------- drivers/staging/et131x/et131x_initpci.c | 8 ++++---- 4 files changed, 23 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/et131x/et1310_phy.c b/drivers/staging/et131x/et1310_phy.c index 5eab21ac00f4..a0ec75ed90e1 100644 --- a/drivers/staging/et131x/et1310_phy.c +++ b/drivers/staging/et131x/et1310_phy.c @@ -740,7 +740,7 @@ void et131x_Mii_check(struct et131x_adapter *etdev, if (bmsr_ints.bits.link_status) { if (bmsr.bits.link_status) { - etdev->PoMgmt.TransPhyComaModeOnBoot = 20; + etdev->boot_coma = 20; /* Update our state variables and indicate the * connected state @@ -831,7 +831,7 @@ void et131x_Mii_check(struct et131x_adapter *etdev, etdev->linkspeed = speed; etdev->duplex_mode = duplex; - etdev->PoMgmt.TransPhyComaModeOnBoot = 20; + etdev->boot_coma = 20; if (etdev->linkspeed == TRUEPHY_SPEED_10MBPS) { /* diff --git a/drivers/staging/et131x/et1310_pm.c b/drivers/staging/et131x/et1310_pm.c index 2b6b29548656..2bc19448d2e2 100644 --- a/drivers/staging/et131x/et1310_pm.c +++ b/drivers/staging/et131x/et1310_pm.c @@ -116,8 +116,8 @@ void EnablePhyComa(struct et131x_adapter *etdev) /* Save the GbE PHY speed and duplex modes. Need to restore this * when cable is plugged back in */ - etdev->PoMgmt.PowerDownSpeed = etdev->AiForceSpeed; - etdev->PoMgmt.PowerDownDuplex = etdev->AiForceDpx; + etdev->pdown_speed = etdev->AiForceSpeed; + etdev->pdown_duplex = etdev->AiForceDpx; /* Stop sending packets. */ spin_lock_irqsave(&etdev->send_hw_lock, flags); @@ -153,8 +153,8 @@ void DisablePhyComa(struct et131x_adapter *etdev) /* Restore the GbE PHY speed and duplex modes; * Reset JAGCore; re-configure and initialize JAGCore and gigE PHY */ - etdev->AiForceSpeed = etdev->PoMgmt.PowerDownSpeed; - etdev->AiForceDpx = etdev->PoMgmt.PowerDownDuplex; + etdev->AiForceSpeed = etdev->pdown_speed; + etdev->AiForceDpx = etdev->pdown_duplex; /* Re-initialize the send structures */ et131x_init_send(etdev); diff --git a/drivers/staging/et131x/et131x_adapter.h b/drivers/staging/et131x/et131x_adapter.h index 430947b39673..025d4c40a18e 100644 --- a/drivers/staging/et131x/et131x_adapter.h +++ b/drivers/staging/et131x/et131x_adapter.h @@ -145,19 +145,6 @@ typedef struct _ce_stats_t { u32 InterruptStatus; } CE_STATS_t, *PCE_STATS_t; -typedef struct _MP_POWER_MGMT { - /* variable putting the phy into coma mode when boot up with no cable - * plugged in after 5 seconds - */ - u8 TransPhyComaModeOnBoot; - - /* Next two used to save power information at power down. This - * information will be used during power up to set up parts of Power - * Management in JAGCore - */ - u16 PowerDownSpeed; - u8 PowerDownDuplex; -} MP_POWER_MGMT, *PMP_POWER_MGMT; /* The private adapter structure */ struct et131x_adapter { @@ -223,7 +210,19 @@ struct et131x_adapter { /* Minimize init-time */ struct timer_list ErrorTimer; - MP_POWER_MGMT PoMgmt; + + /* variable putting the phy into coma mode when boot up with no cable + * plugged in after 5 seconds + */ + u8 boot_coma; + + /* Next two used to save power information at power down. This + * information will be used during power up to set up parts of Power + * Management in JAGCore + */ + u16 pdown_speed; + u8 pdown_duplex; + u32 CachedMaskValue; /* Xcvr status at last poll */ diff --git a/drivers/staging/et131x/et131x_initpci.c b/drivers/staging/et131x/et131x_initpci.c index 4d13e7fdfa61..50237acd6985 100644 --- a/drivers/staging/et131x/et131x_initpci.c +++ b/drivers/staging/et131x/et131x_initpci.c @@ -276,11 +276,11 @@ void et131x_error_timer_handler(unsigned long data) if (!etdev->Bmsr.bits.link_status && etdev->RegistryPhyComa && - etdev->PoMgmt.TransPhyComaModeOnBoot < 11) { - etdev->PoMgmt.TransPhyComaModeOnBoot++; + etdev->boot_coma < 11) { + etdev->boot_coma++; } - if (etdev->PoMgmt.TransPhyComaModeOnBoot == 10) { + if (etdev->boot_coma == 10) { if (!etdev->Bmsr.bits.link_status && etdev->RegistryPhyComa) { if ((pm_csr & ET_PM_PHY_SW_COMA) == 0) { @@ -728,7 +728,7 @@ static int __devinit et131x_pci_setup(struct pci_dev *pdev, /* Initialize variable for counting how long we do not have link status */ - adapter->PoMgmt.TransPhyComaModeOnBoot = 0; + adapter->boot_coma = 0; /* We can enable interrupts now * -- cgit v1.2.3 From ae3e5f0e9a27b0c015570cb2899484c1456846a7 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 1 Feb 2011 15:42:10 +0000 Subject: staging: et131x: Clean up the RFD struct/types Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et1310_rx.c | 44 ++++++++++++++++----------------- drivers/staging/et131x/et131x.h | 4 +-- drivers/staging/et131x/et131x_adapter.h | 8 +++--- 3 files changed, 28 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c index 8220f1bf64d9..a87da6848f9c 100644 --- a/drivers/staging/et131x/et1310_rx.c +++ b/drivers/staging/et131x/et1310_rx.c @@ -88,7 +88,7 @@ #include "et1310_rx.h" #include "et131x.h" -void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD pMpRfd); +void nic_return_rfd(struct et131x_adapter *etdev, struct rfd *rfd); /** * et131x_rx_dma_memory_alloc @@ -372,7 +372,7 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) * RFDs will be allocated from this pool. */ rx_ring->RecvLookaside = kmem_cache_create(adapter->netdev->name, - sizeof(MP_RFD), + sizeof(struct rfd), 0, SLAB_CACHE_DMA | SLAB_HWCACHE_ALIGN, @@ -396,7 +396,7 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) u32 index; u32 bufsize; u32 pktStatRingSize; - PMP_RFD rfd; + struct rfd *rfd; struct rx_ring *rx_ring; /* Setup some convenience pointers */ @@ -406,11 +406,11 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) WARN_ON(rx_ring->nReadyRecv != rx_ring->NumRfd); while (!list_empty(&rx_ring->RecvList)) { - rfd = (MP_RFD *) list_entry(rx_ring->RecvList.next, - MP_RFD, list_node); + rfd = (struct rfd *) list_entry(rx_ring->RecvList.next, + struct rfd, list_node); list_del(&rfd->list_node); - rfd->Packet = NULL; + rfd->skb = NULL; kmem_cache_free(adapter->rx_ring.RecvLookaside, rfd); } @@ -537,7 +537,7 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) int et131x_init_recv(struct et131x_adapter *adapter) { int status = -ENOMEM; - PMP_RFD rfd = NULL; + struct rfd *rfd = NULL; u32 rfdct; u32 numrfd = 0; struct rx_ring *rx_ring; @@ -557,7 +557,7 @@ int et131x_init_recv(struct et131x_adapter *adapter) continue; } - rfd->Packet = NULL; + rfd->skb = NULL; /* Add this RFD to the RecvList */ list_add_tail(&rfd->list_node, &rx_ring->RecvList); @@ -776,12 +776,12 @@ void et131x_rx_dma_enable(struct et131x_adapter *etdev) * the packet to it, puts the RFD in the RecvPendList, and also returns * the pointer to the RFD. */ -PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) +struct rfd * nic_rx_pkts(struct et131x_adapter *etdev) { struct rx_ring *rx_local = &etdev->rx_ring; struct rx_status_block *status; struct pkt_stat_desc *psr; - PMP_RFD rfd; + struct rfd *rfd; u32 i; u8 *buf; unsigned long flags; @@ -858,7 +858,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) rfd = NULL; element = rx_local->RecvList.next; - rfd = (PMP_RFD) list_entry(element, MP_RFD, list_node); + rfd = (struct rfd *) list_entry(element, struct rfd, list_node); if (rfd == NULL) { spin_unlock_irqrestore(&etdev->rcv_lock, flags); @@ -938,7 +938,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) * of Multicast address we have, then * this means we did not find this * packet's matching address in our - * list. Set the PacketSize to zero, + * list. Set the len to zero, * so we free our RFD when we return * from this function. */ @@ -962,21 +962,21 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) if (len > 0) { struct sk_buff *skb = NULL; - /* rfd->PacketSize = len - 4; */ - rfd->PacketSize = len; + /*rfd->len = len - 4; */ + rfd->len = len; - skb = dev_alloc_skb(rfd->PacketSize + 2); + skb = dev_alloc_skb(rfd->len + 2); if (!skb) { dev_err(&etdev->pdev->dev, "Couldn't alloc an SKB for Rx\n"); return NULL; } - etdev->net_stats.rx_bytes += rfd->PacketSize; + etdev->net_stats.rx_bytes += rfd->len; - memcpy(skb_put(skb, rfd->PacketSize), + memcpy(skb_put(skb, rfd->len), rx_local->fbr[rindex]->virt[bindex], - rfd->PacketSize); + rfd->len); skb->dev = etdev->netdev; skb->protocol = eth_type_trans(skb, etdev->netdev); @@ -984,7 +984,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) netif_rx(skb); } else { - rfd->PacketSize = 0; + rfd->len = 0; } nic_return_rfd(etdev, rfd); @@ -1011,7 +1011,7 @@ void et131x_reset_recv(struct et131x_adapter *etdev) */ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev) { - PMP_RFD rfd = NULL; + struct rfd *rfd = NULL; u32 count = 0; bool done = true; @@ -1035,7 +1035,7 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev) */ if (!etdev->PacketFilter || !(etdev->Flags & fMP_ADAPTER_LINK_DETECTION) || - rfd->PacketSize == 0) { + rfd->len == 0) { continue; } @@ -1082,7 +1082,7 @@ static inline u32 bump_fbr(u32 *fbr, u32 limit) * @etdev: pointer to our adapter * @rfd: pointer to the RFD */ -void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD rfd) +void nic_return_rfd(struct et131x_adapter *etdev, struct rfd *rfd) { struct rx_ring *rx_local = &etdev->rx_ring; struct rxdma_regs __iomem *rx_dma = &etdev->regs->rxdma; diff --git a/drivers/staging/et131x/et131x.h b/drivers/staging/et131x/et131x.h index a8abfe6ca81f..8aa3365b83cf 100644 --- a/drivers/staging/et131x/et131x.h +++ b/drivers/staging/et131x/et131x.h @@ -126,9 +126,9 @@ void SetPhy_10BaseTHalfDuplex(struct et131x_adapter *adapter); int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter); void et131x_rx_dma_memory_free(struct et131x_adapter *adapter); int et131x_rfd_resources_alloc(struct et131x_adapter *adapter, - struct _MP_RFD *pMpRfd); + struct rfd *rfd); void et131x_rfd_resources_free(struct et131x_adapter *adapter, - struct _MP_RFD *pMpRfd); + struct rfd *rfd); int et131x_init_recv(struct et131x_adapter *adapter); void ConfigRxDmaRegs(struct et131x_adapter *adapter); diff --git a/drivers/staging/et131x/et131x_adapter.h b/drivers/staging/et131x/et131x_adapter.h index 025d4c40a18e..c852f867645f 100644 --- a/drivers/staging/et131x/et131x_adapter.h +++ b/drivers/staging/et131x/et131x_adapter.h @@ -83,13 +83,13 @@ #define LO_MARK_PERCENT_FOR_RX 15 /* RFD (Receive Frame Descriptor) */ -typedef struct _MP_RFD { +struct rfd { struct list_head list_node; - struct sk_buff *Packet; - u32 PacketSize; /* total size of receive frame */ + struct sk_buff *skb; + u32 len; /* total size of receive frame */ u16 bufferindex; u8 ringindex; -} MP_RFD, *PMP_RFD; +}; /* Flow Control */ #define FLOW_BOTH 0 -- cgit v1.2.3 From 404dc5f3f475ce3598d0e295883a28efafb90ac5 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 1 Feb 2011 15:42:22 +0000 Subject: staging: et131x: Begin cleaning up the MI registers Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et1310_phy.c | 50 +-- drivers/staging/et131x/et1310_phy.h | 649 ++++++++++-------------------------- drivers/staging/et131x/et131x_isr.c | 8 +- 3 files changed, 199 insertions(+), 508 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/et131x/et1310_phy.c b/drivers/staging/et131x/et1310_phy.c index a0ec75ed90e1..2798a2ff6123 100644 --- a/drivers/staging/et131x/et1310_phy.c +++ b/drivers/staging/et131x/et1310_phy.c @@ -242,23 +242,23 @@ int MiWrite(struct et131x_adapter *etdev, u8 xcvrReg, u16 value) int et131x_xcvr_find(struct et131x_adapter *etdev) { u8 xcvr_addr; - MI_IDR1_t idr1; - MI_IDR2_t idr2; + u16 idr1; + u16 idr2; u32 xcvr_id; /* We need to get xcvr id and address we just get the first one */ for (xcvr_addr = 0; xcvr_addr < 32; xcvr_addr++) { /* Read the ID from the PHY */ PhyMiRead(etdev, xcvr_addr, - (u8) offsetof(MI_REGS_t, idr1), - &idr1.value); + (u8) offsetof(struct mi_regs, idr1), + &idr1); PhyMiRead(etdev, xcvr_addr, - (u8) offsetof(MI_REGS_t, idr2), - &idr2.value); + (u8) offsetof(struct mi_regs, idr2), + &idr2); - xcvr_id = (u32) ((idr1.value << 16) | idr2.value); + xcvr_id = (u32) ((idr1 << 16) | idr2); - if (idr1.value != 0 && idr1.value != 0xffff) { + if (idr1 != 0 && idr1 != 0xffff) { etdev->Stats.xcvr_id = xcvr_id; etdev->Stats.xcvr_addr = xcvr_addr; return 0; @@ -577,24 +577,22 @@ void et131x_setphy_normal(struct et131x_adapter *etdev) */ static void et131x_xcvr_init(struct et131x_adapter *etdev) { - MI_IMR_t imr; - MI_ISR_t isr; - MI_LCR2_t lcr2; + u16 imr; + u16 isr; + u16 lcr2; /* Zero out the adapter structure variable representing BMSR */ etdev->Bmsr.value = 0; - MiRead(etdev, (u8) offsetof(MI_REGS_t, isr), &isr.value); - MiRead(etdev, (u8) offsetof(MI_REGS_t, imr), &imr.value); + MiRead(etdev, (u8) offsetof(struct mi_regs, isr), &isr); + MiRead(etdev, (u8) offsetof(struct mi_regs, imr), &imr); /* Set the link status interrupt only. Bad behavior when link status * and auto neg are set, we run into a nested interrupt problem */ - imr.bits.int_en = 0x1; - imr.bits.link_status = 0x1; - imr.bits.autoneg_status = 0x1; + imr |= 0x0105; - MiWrite(etdev, (u8) offsetof(MI_REGS_t, imr), imr.value); + MiWrite(etdev, (u8) offsetof(struct mi_regs, imr), imr); /* Set the LED behavior such that LED 1 indicates speed (off = * 10Mbits, blink = 100Mbits, on = 1000Mbits) and LED 2 indicates @@ -605,15 +603,19 @@ static void et131x_xcvr_init(struct et131x_adapter *etdev) * EEPROM. However, the above description is the default. */ if ((etdev->eeprom_data[1] & 0x4) == 0) { - MiRead(etdev, (u8) offsetof(MI_REGS_t, lcr2), - &lcr2.value); + MiRead(etdev, (u8) offsetof(struct mi_regs, lcr2), + &lcr2); + + lcr2 &= 0x00FF; + lcr2 |= 0xA000; /* led link */ + if ((etdev->eeprom_data[1] & 0x8) == 0) - lcr2.bits.led_tx_rx = 0x3; + lcr2 |= 0x0300; else - lcr2.bits.led_tx_rx = 0x4; - lcr2.bits.led_link = 0xa; - MiWrite(etdev, (u8) offsetof(MI_REGS_t, lcr2), - lcr2.value); + lcr2 |= 0x0400; + + MiWrite(etdev, (u8) offsetof(struct mi_regs, lcr2), + lcr2); } /* Determine if we need to go into a force mode and set it */ diff --git a/drivers/staging/et131x/et1310_phy.h b/drivers/staging/et131x/et1310_phy.h index 47907ba76012..78349adc7d8e 100644 --- a/drivers/staging/et131x/et1310_phy.h +++ b/drivers/staging/et131x/et1310_phy.h @@ -98,7 +98,7 @@ #define VMI_RESERVED31_REG 31 /* PHY Register Mapping(MI) Management Interface Regs */ -typedef struct _MI_REGS_t { +struct mi_regs { u8 bmcr; /* Basic mode control reg(Reg 0x00) */ u8 bmsr; /* Basic mode status reg(Reg 0x01) */ u8 idr1; /* Phy identifier reg 1(Reg 0x02) */ @@ -124,7 +124,7 @@ typedef struct _MI_REGS_t { u8 lcr1; /* LED Control 1 Reg(Reg 0x1B) */ u8 lcr2; /* LED Control 2 Reg(Reg 0x1C) */ u8 mi_res4[3]; /* Future use by MI working group(Reg 0x1D - 0x1F) */ -} MI_REGS_t, *PMI_REGS_t; +}; /* MI Register 0: Basic mode control register */ typedef union _MI_BMCR_t { @@ -200,30 +200,6 @@ typedef union _MI_BMSR_t { } bits; } MI_BMSR_t, *PMI_BMSR_t; -/* MI Register 2: Physical Identifier 1 */ -typedef union _MI_IDR1_t { - u16 value; - struct { - u16 ieee_address:16; /* 0x0282 default(bits 0-15) */ - } bits; -} MI_IDR1_t, *PMI_IDR1_t; - -/* MI Register 3: Physical Identifier 2 */ -typedef union _MI_IDR2_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 ieee_address:6; /* 111100 default(bits 10-15) */ - u16 model_no:6; /* 000001 default(bits 4-9) */ - u16 rev_no:4; /* 0010 default(bits 0-3) */ -#else - u16 rev_no:4; /* 0010 default(bits 0-3) */ - u16 model_no:6; /* 000001 default(bits 4-9) */ - u16 ieee_address:6; /* 111100 default(bits 10-15) */ -#endif - } bits; -} MI_IDR2_t, *PMI_IDR2_t; - /* MI Register 4: Auto-negotiation advertisement register */ typedef union _MI_ANAR_t { u16 value; @@ -258,481 +234,194 @@ typedef union _MI_ANAR_t { } bits; } MI_ANAR_t, *PMI_ANAR_t; -/* MI Register 5: Auto-negotiation link partner advertisement register */ -typedef struct _MI_ANLPAR_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 np_indication:1; /* bit 15 */ - u16 acknowledge:1; /* bit 14 */ - u16 remote_fault:1; /* bit 13 */ - u16 res1:1; /* bit 12 */ - u16 cap_asmpause:1; /* bit 11 */ - u16 cap_pause:1; /* bit 10 */ - u16 cap_100T4:1; /* bit 9 */ - u16 cap_100fdx:1; /* bit 8 */ - u16 cap_100hdx:1; /* bit 7 */ - u16 cap_10fdx:1; /* bit 6 */ - u16 cap_10hdx:1; /* bit 5 */ - u16 selector:5; /* bits 0-4 */ -#else - u16 selector:5; /* bits 0-4 */ - u16 cap_10hdx:1; /* bit 5 */ - u16 cap_10fdx:1; /* bit 6 */ - u16 cap_100hdx:1; /* bit 7 */ - u16 cap_100fdx:1; /* bit 8 */ - u16 cap_100T4:1; /* bit 9 */ - u16 cap_pause:1; /* bit 10 */ - u16 cap_asmpause:1; /* bit 11 */ - u16 res1:1; /* bit 12 */ - u16 remote_fault:1; /* bit 13 */ - u16 acknowledge:1; /* bit 14 */ - u16 np_indication:1; /* bit 15 */ -#endif - } bits; -} MI_ANLPAR_t, *PMI_ANLPAR_t; +/* MI Register 5: Auto-negotiation link partner advertisement register + * 15: np_indication + * 14: acknowledge + * 13: remote_fault + * 12: res1:1; + * 11: cap_asmpause + * 10: cap_pause + * 9: cap_100T4 + * 8: cap_100fdx + * 7: cap_100hdx + * 6: cap_10fdx + * 5: cap_10hdx + * 4-0: selector + */ -/* MI Register 6: Auto-negotiation expansion register */ -typedef union _MI_ANER_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 res:11; /* bits 5-15 */ - u16 pdf:1; /* bit 4 */ - u16 lp_np_able:1; /* bit 3 */ - u16 np_able:1; /* bit 2 */ - u16 page_rx:1; /* bit 1 */ - u16 lp_an_able:1; /* bit 0 */ -#else - u16 lp_an_able:1; /* bit 0 */ - u16 page_rx:1; /* bit 1 */ - u16 np_able:1; /* bit 2 */ - u16 lp_np_able:1; /* bit 3 */ - u16 pdf:1; /* bit 4 */ - u16 res:11; /* bits 5-15 */ -#endif - } bits; -} MI_ANER_t, *PMI_ANER_t; +/* MI Register 6: Auto-negotiation expansion register + * 15-5: reserved + * 4: pdf + * 3: lp_np_able + * 2: np_able + * 1: page_rx + * 0: lp_an_able + */ -/* MI Register 7: Auto-negotiation next page transmit reg(0x07) */ -typedef union _MI_ANNPTR_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 np:1; /* bit 15 */ - u16 res1:1; /* bit 14 */ - u16 msg_page:1; /* bit 13 */ - u16 ack2:1; /* bit 12 */ - u16 toggle:1; /* bit 11 */ - u16 msg:11; /* bits 0-10 */ -#else - u16 msg:11; /* bits 0-10 */ - u16 toggle:1; /* bit 11 */ - u16 ack2:1; /* bit 12 */ - u16 msg_page:1; /* bit 13 */ - u16 res1:1; /* bit 14 */ - u16 np:1; /* bit 15 */ -#endif - } bits; -} MI_ANNPTR_t, *PMI_ANNPTR_t; +/* MI Register 7: Auto-negotiation next page transmit reg(0x07) + * 15: np + * 14: reserved + * 13: msg_page + * 12: ack2 + * 11: toggle + * 10-0 msg + */ -/* MI Register 8: Link Partner Next Page Reg(0x08) */ -typedef union _MI_LPNPR_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 np:1; /* bit 15 */ - u16 ack:1; /* bit 14 */ - u16 msg_page:1; /* bit 13 */ - u16 ack2:1; /* bit 12 */ - u16 toggle:1; /* bit 11 */ - u16 msg:11; /* bits 0-10 */ -#else - u16 msg:11; /* bits 0-10 */ - u16 toggle:1; /* bit 11 */ - u16 ack2:1; /* bit 12 */ - u16 msg_page:1; /* bit 13 */ - u16 ack:1; /* bit 14 */ - u16 np:1; /* bit 15 */ -#endif - } bits; -} MI_LPNPR_t, *PMI_LPNPR_t; +/* MI Register 8: Link Partner Next Page Reg(0x08) + * 15: np + * 14: ack + * 13: msg_page + * 12: ack2 + * 11: toggle + * 10-0: msg + */ -/* MI Register 9: 1000BaseT Control Reg(0x09) */ -typedef union _MI_GCR_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 test_mode:3; /* bits 13-15 */ - u16 ms_config_en:1; /* bit 12 */ - u16 ms_value:1; /* bit 11 */ - u16 port_type:1; /* bit 10 */ - u16 link_1000fdx:1; /* bit 9 */ - u16 link_1000hdx:1; /* bit 8 */ - u16 res:8; /* bit 0-7 */ -#else - u16 res:8; /* bit 0-7 */ - u16 link_1000hdx:1; /* bit 8 */ - u16 link_1000fdx:1; /* bit 9 */ - u16 port_type:1; /* bit 10 */ - u16 ms_value:1; /* bit 11 */ - u16 ms_config_en:1; /* bit 12 */ - u16 test_mode:3; /* bits 13-15 */ -#endif - } bits; -} MI_GCR_t, *PMI_GCR_t; +/* MI Register 9: 1000BaseT Control Reg(0x09) + * 15-13: test_mode + * 12: ms_config_en + * 11: ms_value + * 10: port_type + * 9: link_1000fdx + * 8: link_1000hdx + * 7-0: reserved + */ -/* MI Register 10: 1000BaseT Status Reg(0x0A) */ -typedef union _MI_GSR_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 ms_config_fault:1; /* bit 15 */ - u16 ms_resolve:1; /* bit 14 */ - u16 local_rx_status:1; /* bit 13 */ - u16 remote_rx_status:1; /* bit 12 */ - u16 link_1000fdx:1; /* bit 11 */ - u16 link_1000hdx:1; /* bit 10 */ - u16 res:2; /* bits 8-9 */ - u16 idle_err_cnt:8; /* bits 0-7 */ -#else - u16 idle_err_cnt:8; /* bits 0-7 */ - u16 res:2; /* bits 8-9 */ - u16 link_1000hdx:1; /* bit 10 */ - u16 link_1000fdx:1; /* bit 11 */ - u16 remote_rx_status:1; /* bit 12 */ - u16 local_rx_status:1; /* bit 13 */ - u16 ms_resolve:1; /* bit 14 */ - u16 ms_config_fault:1; /* bit 15 */ -#endif - } bits; -} MI_GSR_t, *PMI_GSR_t; +/* MI Register 10: 1000BaseT Status Reg(0x0A) + * 15: ms_config_fault + * 14: ms_resolve + * 13: local_rx_status + * 12: remote_rx_status + * 11: link_1000fdx + * 10: link_1000hdx + * 9-8: reserved + * 7-0: idle_err_cnt + */ /* MI Register 11 - 14: Reserved Regs(0x0B - 0x0E) */ -typedef union _MI_RES_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 res15:1; /* bit 15 */ - u16 res14:1; /* bit 14 */ - u16 res13:1; /* bit 13 */ - u16 res12:1; /* bit 12 */ - u16 res11:1; /* bit 11 */ - u16 res10:1; /* bit 10 */ - u16 res9:1; /* bit 9 */ - u16 res8:1; /* bit 8 */ - u16 res7:1; /* bit 7 */ - u16 res6:1; /* bit 6 */ - u16 res5:1; /* bit 5 */ - u16 res4:1; /* bit 4 */ - u16 res3:1; /* bit 3 */ - u16 res2:1; /* bit 2 */ - u16 res1:1; /* bit 1 */ - u16 res0:1; /* bit 0 */ -#else - u16 res0:1; /* bit 0 */ - u16 res1:1; /* bit 1 */ - u16 res2:1; /* bit 2 */ - u16 res3:1; /* bit 3 */ - u16 res4:1; /* bit 4 */ - u16 res5:1; /* bit 5 */ - u16 res6:1; /* bit 6 */ - u16 res7:1; /* bit 7 */ - u16 res8:1; /* bit 8 */ - u16 res9:1; /* bit 9 */ - u16 res10:1; /* bit 10 */ - u16 res11:1; /* bit 11 */ - u16 res12:1; /* bit 12 */ - u16 res13:1; /* bit 13 */ - u16 res14:1; /* bit 14 */ - u16 res15:1; /* bit 15 */ -#endif - } bits; -} MI_RES_t, *PMI_RES_t; -/* MI Register 15: Extended status Reg(0x0F) */ -typedef union _MI_ESR_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 link_1000Xfdx:1; /* bit 15 */ - u16 link_1000Xhdx:1; /* bit 14 */ - u16 link_1000fdx:1; /* bit 13 */ - u16 link_1000hdx:1; /* bit 12 */ - u16 res:12; /* bit 0-11 */ -#else - u16 res:12; /* bit 0-11 */ - u16 link_1000hdx:1; /* bit 12 */ - u16 link_1000fdx:1; /* bit 13 */ - u16 link_1000Xhdx:1; /* bit 14 */ - u16 link_1000Xfdx:1; /* bit 15 */ -#endif - } bits; -} MI_ESR_t, *PMI_ESR_t; +/* MI Register 15: Extended status Reg(0x0F) + * 15: link_1000Xfdx + * 14: link_1000Xhdx + * 13: link_1000fdx + * 12: link_1000hdx + * 11-0: reserved + */ /* MI Register 16 - 18: Reserved Reg(0x10-0x12) */ -/* MI Register 19: Loopback Control Reg(0x13) */ -typedef union _MI_LCR_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 mii_en:1; /* bit 15 */ - u16 pcs_en:1; /* bit 14 */ - u16 pmd_en:1; /* bit 13 */ - u16 all_digital_en:1; /* bit 12 */ - u16 replica_en:1; /* bit 11 */ - u16 line_driver_en:1; /* bit 10 */ - u16 res:10; /* bit 0-9 */ -#else - u16 res:10; /* bit 0-9 */ - u16 line_driver_en:1; /* bit 10 */ - u16 replica_en:1; /* bit 11 */ - u16 all_digital_en:1; /* bit 12 */ - u16 pmd_en:1; /* bit 13 */ - u16 pcs_en:1; /* bit 14 */ - u16 mii_en:1; /* bit 15 */ -#endif - } bits; -} MI_LCR_t, *PMI_LCR_t; +/* MI Register 19: Loopback Control Reg(0x13) + * 15: mii_en + * 14: pcs_en + * 13: pmd_en + * 12: all_digital_en + * 11: replica_en + * 10: line_driver_en + * 9-0: reserved + */ /* MI Register 20: Reserved Reg(0x14) */ -/* MI Register 21: Management Interface Control Reg(0x15) */ -typedef union _MI_MICR_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 res1:5; /* bits 11-15 */ - u16 mi_error_count:7; /* bits 4-10 */ - u16 res2:1; /* bit 3 */ - u16 ignore_10g_fr:1; /* bit 2 */ - u16 res3:1; /* bit 1 */ - u16 preamble_supress_en:1; /* bit 0 */ -#else - u16 preamble_supress_en:1; /* bit 0 */ - u16 res3:1; /* bit 1 */ - u16 ignore_10g_fr:1; /* bit 2 */ - u16 res2:1; /* bit 3 */ - u16 mi_error_count:7; /* bits 4-10 */ - u16 res1:5; /* bits 11-15 */ -#endif - } bits; -} MI_MICR_t, *PMI_MICR_t; +/* MI Register 21: Management Interface Control Reg(0x15) + * 15-11: reserved + * 10-4: mi_error_count + * 3: reserved + * 2: ignore_10g_fr + * 1: reserved + * 0: preamble_supress_en + */ -/* MI Register 22: PHY Configuration Reg(0x16) */ -typedef union _MI_PHY_CONFIG_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 crs_tx_en:1; /* bit 15 */ - u16 res1:1; /* bit 14 */ - u16 tx_fifo_depth:2; /* bits 12-13 */ - u16 speed_downshift:2; /* bits 10-11 */ - u16 pbi_detect:1; /* bit 9 */ - u16 tbi_rate:1; /* bit 8 */ - u16 alternate_np:1; /* bit 7 */ - u16 group_mdio_en:1; /* bit 6 */ - u16 tx_clock_en:1; /* bit 5 */ - u16 sys_clock_en:1; /* bit 4 */ - u16 res2:1; /* bit 3 */ - u16 mac_if_mode:3; /* bits 0-2 */ -#else - u16 mac_if_mode:3; /* bits 0-2 */ - u16 res2:1; /* bit 3 */ - u16 sys_clock_en:1; /* bit 4 */ - u16 tx_clock_en:1; /* bit 5 */ - u16 group_mdio_en:1; /* bit 6 */ - u16 alternate_np:1; /* bit 7 */ - u16 tbi_rate:1; /* bit 8 */ - u16 pbi_detect:1; /* bit 9 */ - u16 speed_downshift:2; /* bits 10-11 */ - u16 tx_fifo_depth:2; /* bits 12-13 */ - u16 res1:1; /* bit 14 */ - u16 crs_tx_en:1; /* bit 15 */ -#endif - } bits; -} MI_PHY_CONFIG_t, *PMI_PHY_CONFIG_t; +/* MI Register 22: PHY Configuration Reg(0x16) + * 15: crs_tx_en + * 14: reserved + * 13-12: tx_fifo_depth + * 11-10: speed_downshift + * 9: pbi_detect + * 8: tbi_rate + * 7: alternate_np + * 6: group_mdio_en + * 5: tx_clock_en + * 4: sys_clock_en + * 3: reserved + * 2-0: mac_if_mode + */ -/* MI Register 23: PHY CONTROL Reg(0x17) */ -typedef union _MI_PHY_CONTROL_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 res1:1; /* bit 15 */ - u16 tdr_en:1; /* bit 14 */ - u16 res2:1; /* bit 13 */ - u16 downshift_attempts:2; /* bits 11-12 */ - u16 res3:5; /* bit 6-10 */ - u16 jabber_10baseT:1; /* bit 5 */ - u16 sqe_10baseT:1; /* bit 4 */ - u16 tp_loopback_10baseT:1; /* bit 3 */ - u16 preamble_gen_en:1; /* bit 2 */ - u16 res4:1; /* bit 1 */ - u16 force_int:1; /* bit 0 */ -#else - u16 force_int:1; /* bit 0 */ - u16 res4:1; /* bit 1 */ - u16 preamble_gen_en:1; /* bit 2 */ - u16 tp_loopback_10baseT:1; /* bit 3 */ - u16 sqe_10baseT:1; /* bit 4 */ - u16 jabber_10baseT:1; /* bit 5 */ - u16 res3:5; /* bit 6-10 */ - u16 downshift_attempts:2; /* bits 11-12 */ - u16 res2:1; /* bit 13 */ - u16 tdr_en:1; /* bit 14 */ - u16 res1:1; /* bit 15 */ -#endif - } bits; -} MI_PHY_CONTROL_t, *PMI_PHY_CONTROL_t; +/* MI Register 23: PHY CONTROL Reg(0x17) + * 15: reserved + * 14: tdr_en + * 13: reserved + * 12-11: downshift_attempts + * 10-6: reserved + * 5: jabber_10baseT + * 4: sqe_10baseT + * 3: tp_loopback_10baseT + * 2: preamble_gen_en + * 1: reserved + * 0: force_int + */ -/* MI Register 24: Interrupt Mask Reg(0x18) */ -typedef union _MI_IMR_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 res1:6; /* bits 10-15 */ - u16 mdio_sync_lost:1; /* bit 9 */ - u16 autoneg_status:1; /* bit 8 */ - u16 hi_bit_err:1; /* bit 7 */ - u16 np_rx:1; /* bit 6 */ - u16 err_counter_full:1; /* bit 5 */ - u16 fifo_over_underflow:1; /* bit 4 */ - u16 rx_status:1; /* bit 3 */ - u16 link_status:1; /* bit 2 */ - u16 automatic_speed:1; /* bit 1 */ - u16 int_en:1; /* bit 0 */ -#else - u16 int_en:1; /* bit 0 */ - u16 automatic_speed:1; /* bit 1 */ - u16 link_status:1; /* bit 2 */ - u16 rx_status:1; /* bit 3 */ - u16 fifo_over_underflow:1; /* bit 4 */ - u16 err_counter_full:1; /* bit 5 */ - u16 np_rx:1; /* bit 6 */ - u16 hi_bit_err:1; /* bit 7 */ - u16 autoneg_status:1; /* bit 8 */ - u16 mdio_sync_lost:1; /* bit 9 */ - u16 res1:6; /* bits 10-15 */ -#endif - } bits; -} MI_IMR_t, *PMI_IMR_t; +/* MI Register 24: Interrupt Mask Reg(0x18) + * 15-10: reserved + * 9: mdio_sync_lost + * 8: autoneg_status + * 7: hi_bit_err + * 6: np_rx + * 5: err_counter_full + * 4: fifo_over_underflow + * 3: rx_status + * 2: link_status + * 1: automatic_speed + * 0: int_en + */ -/* MI Register 25: Interrupt Status Reg(0x19) */ -typedef union _MI_ISR_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 res1:6; /* bits 10-15 */ - u16 mdio_sync_lost:1; /* bit 9 */ - u16 autoneg_status:1; /* bit 8 */ - u16 hi_bit_err:1; /* bit 7 */ - u16 np_rx:1; /* bit 6 */ - u16 err_counter_full:1; /* bit 5 */ - u16 fifo_over_underflow:1; /* bit 4 */ - u16 rx_status:1; /* bit 3 */ - u16 link_status:1; /* bit 2 */ - u16 automatic_speed:1; /* bit 1 */ - u16 int_en:1; /* bit 0 */ -#else - u16 int_en:1; /* bit 0 */ - u16 automatic_speed:1; /* bit 1 */ - u16 link_status:1; /* bit 2 */ - u16 rx_status:1; /* bit 3 */ - u16 fifo_over_underflow:1; /* bit 4 */ - u16 err_counter_full:1; /* bit 5 */ - u16 np_rx:1; /* bit 6 */ - u16 hi_bit_err:1; /* bit 7 */ - u16 autoneg_status:1; /* bit 8 */ - u16 mdio_sync_lost:1; /* bit 9 */ - u16 res1:6; /* bits 10-15 */ -#endif - } bits; -} MI_ISR_t, *PMI_ISR_t; -/* MI Register 26: PHY Status Reg(0x1A) */ -typedef union _MI_PSR_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 res1:1; /* bit 15 */ - u16 autoneg_fault:2; /* bit 13-14 */ - u16 autoneg_status:1; /* bit 12 */ - u16 mdi_x_status:1; /* bit 11 */ - u16 polarity_status:1; /* bit 10 */ - u16 speed_status:2; /* bits 8-9 */ - u16 duplex_status:1; /* bit 7 */ - u16 link_status:1; /* bit 6 */ - u16 tx_status:1; /* bit 5 */ - u16 rx_status:1; /* bit 4 */ - u16 collision_status:1; /* bit 3 */ - u16 autoneg_en:1; /* bit 2 */ - u16 pause_en:1; /* bit 1 */ - u16 asymmetric_dir:1; /* bit 0 */ -#else - u16 asymmetric_dir:1; /* bit 0 */ - u16 pause_en:1; /* bit 1 */ - u16 autoneg_en:1; /* bit 2 */ - u16 collision_status:1; /* bit 3 */ - u16 rx_status:1; /* bit 4 */ - u16 tx_status:1; /* bit 5 */ - u16 link_status:1; /* bit 6 */ - u16 duplex_status:1; /* bit 7 */ - u16 speed_status:2; /* bits 8-9 */ - u16 polarity_status:1; /* bit 10 */ - u16 mdi_x_status:1; /* bit 11 */ - u16 autoneg_status:1; /* bit 12 */ - u16 autoneg_fault:2; /* bit 13-14 */ - u16 res1:1; /* bit 15 */ -#endif - } bits; -} MI_PSR_t, *PMI_PSR_t; +/* MI Register 25: Interrupt Status Reg(0x19) + * 15-10: reserved + * 9: mdio_sync_lost + * 8: autoneg_status + * 7: hi_bit_err + * 6: np_rx + * 5: err_counter_full + * 4: fifo_over_underflow + * 3: rx_status + * 2: link_status + * 1: automatic_speed + * 0: int_en + */ -/* MI Register 27: LED Control Reg 1(0x1B) */ -typedef union _MI_LCR1_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 res1:2; /* bits 14-15 */ - u16 led_dup_indicate:2; /* bits 12-13 */ - u16 led_10baseT:2; /* bits 10-11 */ - u16 led_collision:2; /* bits 8-9 */ - u16 res2:2; /* bits 6-7 */ - u16 res3:2; /* bits 4-5 */ - u16 pulse_dur:2; /* bits 2-3 */ - u16 pulse_stretch1:1; /* bit 1 */ - u16 pulse_stretch0:1; /* bit 0 */ -#else - u16 pulse_stretch0:1; /* bit 0 */ - u16 pulse_stretch1:1; /* bit 1 */ - u16 pulse_dur:2; /* bits 2-3 */ - u16 res3:2; /* bits 4-5 */ - u16 res2:2; /* bits 6-7 */ - u16 led_collision:2; /* bits 8-9 */ - u16 led_10baseT:2; /* bits 10-11 */ - u16 led_dup_indicate:2; /* bits 12-13 */ - u16 res1:2; /* bits 14-15 */ -#endif - } bits; -} MI_LCR1_t, *PMI_LCR1_t; +/* MI Register 26: PHY Status Reg(0x1A) + * 15: reserved + * 14-13: autoneg_fault + * 12: autoneg_status + * 11: mdi_x_status + * 10: polarity_status + * 9-8: speed_status + * 7: duplex_status + * 6: link_status + * 5: tx_status + * 4: rx_status + * 3: collision_status + * 2: autoneg_en + * 1: pause_en + * 0: asymmetric_dir + */ -/* MI Register 28: LED Control Reg 2(0x1C) */ -typedef union _MI_LCR2_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 led_link:4; /* bits 12-15 */ - u16 led_tx_rx:4; /* bits 8-11 */ - u16 led_100BaseTX:4; /* bits 4-7 */ - u16 led_1000BaseT:4; /* bits 0-3 */ -#else - u16 led_1000BaseT:4; /* bits 0-3 */ - u16 led_100BaseTX:4; /* bits 4-7 */ - u16 led_tx_rx:4; /* bits 8-11 */ - u16 led_link:4; /* bits 12-15 */ -#endif - } bits; -} MI_LCR2_t, *PMI_LCR2_t; +/* MI Register 27: LED Control Reg 1(0x1B) + * 15-14: reserved + * 13-12: led_dup_indicate + * 11-10: led_10baseT + * 9-8: led_collision + * 7-4: reserved + * 3-2: pulse_dur + * 1: pulse_stretch1 + * 0: pulse_stretch0 + */ + +/* MI Register 28: LED Control Reg 2(0x1C) + * 15-12: led_link + * 11-8: led_tx_rx + * 7-4: led_100BaseTX + * 3-0: led_1000BaseT + */ /* MI Register 29 - 31: Reserved Reg(0x1D - 0x1E) */ diff --git a/drivers/staging/et131x/et131x_isr.c b/drivers/staging/et131x/et131x_isr.c index 0cc6c68fdfda..ce4d93042679 100644 --- a/drivers/staging/et131x/et131x_isr.c +++ b/drivers/staging/et131x/et131x_isr.c @@ -366,7 +366,7 @@ void et131x_isr_handler(struct work_struct *work) if (status & ET_INTR_PHY) { u32 pm_csr; MI_BMSR_t BmsrInts, BmsrData; - MI_ISR_t myIsr; + u16 myisr; /* If we are in coma mode when we get this interrupt, * we need to disable it. @@ -384,12 +384,12 @@ void et131x_isr_handler(struct work_struct *work) /* Read the PHY ISR to clear the reason for the * interrupt. */ - MiRead(etdev, (uint8_t) offsetof(MI_REGS_t, isr), - &myIsr.value); + MiRead(etdev, (uint8_t) offsetof(struct mi_regs, isr), + &myisr); if (!etdev->ReplicaPhyLoopbk) { MiRead(etdev, - (uint8_t) offsetof(MI_REGS_t, bmsr), + (uint8_t) offsetof(struct mi_regs, bmsr), &BmsrData.value); BmsrInts.value = -- cgit v1.2.3 From 0838b87cae7e81e497218b5eba3c8e9ca6f3ddbe Mon Sep 17 00:00:00 2001 From: Timo von Holtz Date: Tue, 1 Feb 2011 19:28:46 +0100 Subject: Staging: rts_pstor: fixed some brace code styling issues Fixed all brace coding style issues in the following files: drivers/staging/rts_pstor/rtsx_card.h drivers/staging/rts_pstor/spi.c drivers/staging/rts_pstor/trace.h drivers/staging/rts_pstor/xd.c Signed-off-by: Timo von Holtz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts_pstor/rtsx_card.h | 10 +- drivers/staging/rts_pstor/spi.c | 109 +++++------- drivers/staging/rts_pstor/trace.h | 7 +- drivers/staging/rts_pstor/xd.c | 301 ++++++++++++---------------------- 4 files changed, 150 insertions(+), 277 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rts_pstor/rtsx_card.h b/drivers/staging/rts_pstor/rtsx_card.h index 5a0e167a15d9..3f7277676208 100644 --- a/drivers/staging/rts_pstor/rtsx_card.h +++ b/drivers/staging/rts_pstor/rtsx_card.h @@ -1035,11 +1035,10 @@ static inline u32 get_card_size(struct rtsx_chip *chip, unsigned int lun) #ifdef SUPPORT_SD_LOCK struct sd_info *sd_card = &(chip->sd_card); - if ((get_lun_card(chip, lun) == SD_CARD) && (sd_card->sd_lock_status & SD_LOCKED)) { + if ((get_lun_card(chip, lun) == SD_CARD) && (sd_card->sd_lock_status & SD_LOCKED)) return 0; - } else { + else return chip->capacity[lun]; - } #else return chip->capacity[lun]; #endif @@ -1049,11 +1048,10 @@ static inline int switch_clock(struct rtsx_chip *chip, int clk) { int retval = 0; - if (chip->asic_code) { + if (chip->asic_code) retval = switch_ssc_clock(chip, clk); - } else { + else retval = switch_normal_clock(chip, clk); - } return retval; } diff --git a/drivers/staging/rts_pstor/spi.c b/drivers/staging/rts_pstor/spi.c index 84e0af42ca18..e0682004756d 100644 --- a/drivers/staging/rts_pstor/spi.c +++ b/drivers/staging/rts_pstor/spi.c @@ -55,14 +55,12 @@ static int spi_set_init_para(struct rtsx_chip *chip) RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER0, 0xFF, (u8)(spi->clk_div)); retval = switch_clock(chip, spi->spi_clock); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = select_card(chip, SPI_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_WRITE_REG(chip, CARD_CLK_EN, SPI_CLK_EN, SPI_CLK_EN); RTSX_WRITE_REG(chip, CARD_OE, SPI_OUTPUT_EN, SPI_OUTPUT_EN); @@ -70,9 +68,8 @@ static int spi_set_init_para(struct rtsx_chip *chip) wait_timeout(10); retval = spi_init(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -197,24 +194,21 @@ static int spi_init_eeprom(struct rtsx_chip *chip) int retval; int clk; - if (chip->asic_code) { + if (chip->asic_code) clk = 30; - } else { + else clk = CLK_30; - } RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER1, 0xFF, 0x00); RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER0, 0xFF, 0x27); retval = switch_clock(chip, clk); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = select_card(chip, SPI_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_WRITE_REG(chip, CARD_CLK_EN, SPI_CLK_EN, SPI_CLK_EN); RTSX_WRITE_REG(chip, CARD_OE, SPI_OUTPUT_EN, SPI_OUTPUT_EN); @@ -239,9 +233,8 @@ int spi_eeprom_program_enable(struct rtsx_chip *chip) rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -251,14 +244,12 @@ int spi_erase_eeprom_chip(struct rtsx_chip *chip) int retval; retval = spi_init_eeprom(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = spi_eeprom_program_enable(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } rtsx_init_cmd(chip); @@ -270,9 +261,8 @@ int spi_erase_eeprom_chip(struct rtsx_chip *chip) rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01); @@ -284,14 +274,12 @@ int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr) int retval; retval = spi_init_eeprom(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = spi_eeprom_program_enable(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } rtsx_init_cmd(chip); @@ -305,9 +293,8 @@ int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr) rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01); @@ -321,9 +308,8 @@ int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val) u8 data; retval = spi_init_eeprom(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } rtsx_init_cmd(chip); @@ -338,16 +324,14 @@ int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val) rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } wait_timeout(5); RTSX_READ_REG(chip, SPI_DATA, &data); - if (val) { + if (val) *val = data; - } RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01); @@ -359,14 +343,12 @@ int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val) int retval; retval = spi_init_eeprom(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = spi_eeprom_program_enable(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } rtsx_init_cmd(chip); @@ -381,9 +363,8 @@ int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val) rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01); @@ -408,11 +389,10 @@ int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip) spi_set_err_code(chip, SPI_NO_ERR); - if (chip->asic_code) { + if (chip->asic_code) spi->spi_clock = ((u16)(srb->cmnd[8]) << 8) | srb->cmnd[9]; - } else { + else spi->spi_clock = srb->cmnd[3]; - } spi->clk_div = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; spi->write_en = srb->cmnd[6]; @@ -484,9 +464,8 @@ int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (len) { buf = (u8 *)kmalloc(len, GFP_KERNEL); - if (!buf) { + if (!buf) TRACE_RET(chip, STATUS_ERROR); - } retval = rtsx_read_ppbuf(chip, buf, len); if (retval != STATUS_SUCCESS) { @@ -527,16 +506,14 @@ int spi_read_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) } buf = (u8 *)rtsx_alloc_dma_buf(chip, SF_PAGE_LEN, GFP_KERNEL); - if (buf == NULL) { + if (buf == NULL) TRACE_RET(chip, STATUS_ERROR); - } while (len) { u16 pagelen = SF_PAGE_LEN - (u8)addr; - if (pagelen > len) { + if (pagelen > len) pagelen = len; - } rtsx_init_cmd(chip); @@ -608,9 +585,8 @@ int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (program_mode == BYTE_PROGRAM) { buf = rtsx_alloc_dma_buf(chip, 4, GFP_KERNEL); - if (!buf) { + if (!buf) TRACE_RET(chip, STATUS_ERROR); - } while (len) { retval = sf_enable_write(chip, SPI_WREN); @@ -651,14 +627,12 @@ int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) int first_byte = 1; retval = sf_enable_write(chip, SPI_WREN); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } buf = rtsx_alloc_dma_buf(chip, 4, GFP_KERNEL); - if (!buf) { + if (!buf) TRACE_RET(chip, STATUS_ERROR); - } while (len) { rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset, FROM_XFER_BUF); @@ -694,26 +668,22 @@ int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) rtsx_free_dma_buf(chip, buf); retval = sf_disable_write(chip, SPI_WRDI); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = sf_polling_status(chip, 100); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } else if (program_mode == PAGE_PROGRAM) { buf = rtsx_alloc_dma_buf(chip, SF_PAGE_LEN, GFP_KERNEL); - if (!buf) { + if (!buf) TRACE_RET(chip, STATUS_NOMEM); - } while (len) { u16 pagelen = SF_PAGE_LEN - (u8)addr; - if (pagelen > len) { + if (pagelen > len) pagelen = len; - } retval = sf_enable_write(chip, SPI_WREN); if (retval != STATUS_SUCCESS) { @@ -777,24 +747,20 @@ int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (erase_mode == PAGE_ERASE) { retval = sf_enable_write(chip, SPI_WREN); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = sf_erase(chip, ins, 1, addr); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } else if (erase_mode == CHIP_ERASE) { retval = sf_enable_write(chip, SPI_WREN); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = sf_erase(chip, ins, 0, 0); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } else { spi_set_err_code(chip, SPI_INVALID_COMMAND); TRACE_RET(chip, STATUS_FAIL); @@ -819,9 +785,8 @@ int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) } retval = sf_enable_write(chip, ewsr); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } rtsx_init_cmd(chip); diff --git a/drivers/staging/rts_pstor/trace.h b/drivers/staging/rts_pstor/trace.h index 1b8958948f9e..2c668bae6ff4 100644 --- a/drivers/staging/rts_pstor/trace.h +++ b/drivers/staging/rts_pstor/trace.h @@ -31,16 +31,15 @@ static inline char *filename(char *path) { char *ptr; - if (path == NULL) { + if (path == NULL) return NULL; - } ptr = path; while (*ptr != '\0') { - if ((*ptr == '\\') || (*ptr == '/')) { + if ((*ptr == '\\') || (*ptr == '/')) path = ptr + 1; - } + ptr++; } diff --git a/drivers/staging/rts_pstor/xd.c b/drivers/staging/rts_pstor/xd.c index f654c8b031c5..7bcd468b8f2c 100644 --- a/drivers/staging/rts_pstor/xd.c +++ b/drivers/staging/rts_pstor/xd.c @@ -52,16 +52,14 @@ static int xd_set_init_para(struct rtsx_chip *chip) struct xd_info *xd_card = &(chip->xd_card); int retval; - if (chip->asic_code) { + if (chip->asic_code) xd_card->xd_clock = 47; - } else { + else xd_card->xd_clock = CLK_50; - } retval = switch_clock(chip, xd_card->xd_clock); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -72,14 +70,12 @@ static int xd_switch_clock(struct rtsx_chip *chip) int retval; retval = select_card(chip, XD_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = switch_clock(chip, xd_card->xd_clock); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -95,14 +91,12 @@ static int xd_read_id(struct rtsx_chip *chip, u8 id_cmd, u8 *id_buf, u8 buf_len) rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_READ_ID); rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); - for (i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_ADDRESS1 + i), 0, 0); - } retval = rtsx_send_cmd(chip, XD_CARD, 20); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } ptr = rtsx_get_cmd_data(chip) + 1; if (id_buf && buf_len) { @@ -152,18 +146,15 @@ static int xd_read_redundant(struct rtsx_chip *chip, u32 page_addr, u8 *buf, int rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_READ_REDUNDANT); rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); - for (i = 0; i < 6; i++) { + for (i = 0; i < 6; i++) rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_PAGE_STATUS + i), 0, 0); - } - for (i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_RESERVED0 + i), 0, 0); - } rtsx_add_cmd(chip, READ_REG_CMD, XD_PARITY, 0, 0); retval = rtsx_send_cmd(chip, XD_CARD, 500); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } if (buf && buf_len) { u8 *ptr = rtsx_get_cmd_data(chip) + 1; @@ -180,15 +171,13 @@ static int xd_read_data_from_ppb(struct rtsx_chip *chip, int offset, u8 *buf, in { int retval, i; - if (!buf || (buf_len < 0)) { + if (!buf || (buf_len < 0)) TRACE_RET(chip, STATUS_FAIL); - } rtsx_init_cmd(chip); - for (i = 0; i < buf_len; i++) { + for (i = 0; i < buf_len; i++) rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + offset + i, 0, 0); - } retval = rtsx_send_cmd(chip, 0, 250); if (retval < 0) { @@ -206,9 +195,8 @@ static int xd_read_cis(struct rtsx_chip *chip, u32 page_addr, u8 *buf, int buf_l int retval; u8 reg; - if (!buf || (buf_len < 10)) { + if (!buf || (buf_len < 10)) TRACE_RET(chip, STATUS_FAIL); - } rtsx_init_cmd(chip); @@ -236,9 +224,8 @@ static int xd_read_cis(struct rtsx_chip *chip, u32 page_addr, u8 *buf, int buf_l RTSX_READ_REG(chip, XD_CTL, ®); if (!(reg & XD_ECC1_ERROR) || !(reg & XD_ECC1_UNCORRECTABLE)) { retval = xd_read_data_from_ppb(chip, 0, buf, buf_len); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (reg & XD_ECC1_ERROR) { u8 ecc_bit, ecc_byte; @@ -256,9 +243,8 @@ static int xd_read_cis(struct rtsx_chip *chip, u32 page_addr, u8 *buf, int buf_l rtsx_clear_xd_error(chip); retval = xd_read_data_from_ppb(chip, 256, buf, buf_len); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (reg & XD_ECC2_ERROR) { u8 ecc_bit, ecc_byte; @@ -394,9 +380,8 @@ static void xd_clear_dma_buffer(struct rtsx_chip *chip) RTSX_DEBUGP("xD ECC error, dummy write!\n"); buf = (u8 *)rtsx_alloc_dma_buf(chip, 512, GFP_KERNEL); - if (!buf) { + if (!buf) return; - } rtsx_init_cmd(chip); @@ -461,46 +446,40 @@ static int reset_xd(struct rtsx_chip *chip) u8 *ptr, id_buf[4], redunt[11]; retval = select_card(chip, XD_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } rtsx_init_cmd(chip); rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, 0xFF, XD_PGSTS_NOT_FF); if (chip->asic_code) { - if (!CHECK_PID(chip, 0x5288)) { + if (!CHECK_PID(chip, 0x5288)) xd_fill_pull_ctl_disable(chip); - } else { + else xd_fill_pull_ctl_stage1_barossa(chip); - } } else { rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN3) | 0x20); } - if (!chip->ft2_fast_mode) { + if (!chip->ft2_fast_mode) rtsx_add_cmd(chip, WRITE_REG_CMD, XD_INIT, XD_NO_AUTO_PWR_OFF, 0); - } rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, 0); retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } if (!chip->ft2_fast_mode) { retval = card_power_off(chip, XD_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } wait_timeout(250); - if (CHECK_PID(chip, 0x5209)) { + if (CHECK_PID(chip, 0x5209)) RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0xAA); - } rtsx_init_cmd(chip); @@ -512,14 +491,12 @@ static int reset_xd(struct rtsx_chip *chip) } retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } retval = card_power_on(chip, XD_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } #ifdef SUPPORT_OCP wait_timeout(50); @@ -545,18 +522,15 @@ static int reset_xd(struct rtsx_chip *chip) rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CTL, XD_CE_DISEN, XD_CE_DISEN); retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } - if (!chip->ft2_fast_mode) { + if (!chip->ft2_fast_mode) wait_timeout(200); - } retval = xd_set_init_para(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } /* Read ID to check if the timing setting is right */ for (i = 0; i < 4; i++) { @@ -574,22 +548,19 @@ static int reset_xd(struct rtsx_chip *chip) rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0); retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } ptr = rtsx_get_cmd_data(chip) + 1; RTSX_DEBUGP("XD_DAT: 0x%x, XD_CTL: 0x%x\n", ptr[0], ptr[1]); - if (((ptr[0] & READY_FLAG) != READY_STATE) || !(ptr[1] & XD_RDY)) { + if (((ptr[0] & READY_FLAG) != READY_STATE) || !(ptr[1] & XD_RDY)) continue; - } retval = xd_read_id(chip, READ_ID, id_buf, 4); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_DEBUGP("READ_ID: 0x%x 0x%x 0x%x 0x%x\n", id_buf[0], id_buf[1], id_buf[2], id_buf[3]); @@ -669,9 +640,8 @@ static int reset_xd(struct rtsx_chip *chip) /* Confirm timing setting */ for (j = 0; j < 10; j++) { retval = xd_read_id(chip, READ_ID, id_buf, 4); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if (id_buf[1] != xd_card->device_code) break; @@ -691,34 +661,29 @@ static int reset_xd(struct rtsx_chip *chip) } retval = xd_read_id(chip, READ_xD_ID, id_buf, 4); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_DEBUGP("READ_xD_ID: 0x%x 0x%x 0x%x 0x%x\n", id_buf[0], id_buf[1], id_buf[2], id_buf[3]); - if (id_buf[2] != XD_ID_CODE) { + if (id_buf[2] != XD_ID_CODE) TRACE_RET(chip, STATUS_FAIL); - } /* Search CIS block */ for (i = 0; i < 24; i++) { u32 page_addr; - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } page_addr = (u32)i << xd_card->block_shift; for (j = 0; j < 3; j++) { retval = xd_read_redundant(chip, page_addr, redunt, 11); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) break; - } } - if (j == 3) { + if (j == 3) continue; - } if (redunt[BLOCK_STATUS] != XD_GBLK) continue; @@ -728,9 +693,8 @@ static int reset_xd(struct rtsx_chip *chip) for (j = 1; j <= 8; j++) { retval = xd_read_redundant(chip, page_addr + j, redunt, 11); if (retval == STATUS_SUCCESS) { - if (redunt[PAGE_STATUS] == XD_GPG) { + if (redunt[PAGE_STATUS] == XD_GPG) break; - } } } @@ -745,9 +709,8 @@ static int reset_xd(struct rtsx_chip *chip) page_addr += j; retval = xd_read_cis(chip, page_addr, buf, 10); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } if ((buf[0] == 0x01) && (buf[1] == 0x03) && (buf[2] == 0xD9) && (buf[3] == 0x01) && (buf[4] == 0xFF) @@ -762,9 +725,8 @@ static int reset_xd(struct rtsx_chip *chip) } RTSX_DEBUGP("CIS block: 0x%x\n", xd_card->cis_block); - if (xd_card->cis_block == 0xFFFF) { + if (xd_card->cis_block == 0xFFFF) TRACE_RET(chip, STATUS_FAIL); - } chip->capacity[chip->card2lun[XD_CARD]] = xd_card->capacity; @@ -780,9 +742,9 @@ static int xd_check_data_blank(u8 *redunt) return 0; } - if ((redunt[PARITY] & (XD_ECC1_ALL1 | XD_ECC2_ALL1)) != (XD_ECC1_ALL1 | XD_ECC2_ALL1)) { + if ((redunt[PARITY] & (XD_ECC1_ALL1 | XD_ECC2_ALL1)) != (XD_ECC1_ALL1 | XD_ECC2_ALL1)) return 0; - } + for (i = 0; i < 4; i++) { if (redunt[RESERVED0 + i] != 0xFF) @@ -796,13 +758,12 @@ static u16 xd_load_log_block_addr(u8 *redunt) { u16 addr = 0xFFFF; - if (redunt[PARITY] & XD_BA1_BA2_EQL) { + if (redunt[PARITY] & XD_BA1_BA2_EQL) addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) | redunt[BLOCK_ADDR1_L]; - } else if (redunt[PARITY] & XD_BA1_VALID) { + else if (redunt[PARITY] & XD_BA1_VALID) addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) | redunt[BLOCK_ADDR1_L]; - } else if (redunt[PARITY] & XD_BA2_VALID) { + else if (redunt[PARITY] & XD_BA2_VALID) addr = ((u16)redunt[BLOCK_ADDR2_H] << 8) | redunt[BLOCK_ADDR2_L]; - } return addr; } @@ -814,17 +775,15 @@ static int xd_init_l2p_tbl(struct rtsx_chip *chip) RTSX_DEBUGP("xd_init_l2p_tbl: zone_cnt = %d\n", xd_card->zone_cnt); - if (xd_card->zone_cnt < 1) { + if (xd_card->zone_cnt < 1) TRACE_RET(chip, STATUS_FAIL); - } size = xd_card->zone_cnt * sizeof(struct zone_entry); RTSX_DEBUGP("Buffer size for l2p table is %d\n", size); xd_card->zone = (struct zone_entry *)vmalloc(size); - if (!xd_card->zone) { + if (!xd_card->zone) TRACE_RET(chip, STATUS_ERROR); - } for (i = 0; i < xd_card->zone_cnt; i++) { xd_card->zone[i].build_flag = 0; @@ -874,9 +833,8 @@ static void xd_set_unused_block(struct rtsx_chip *chip, u32 phy_blk) zone = &(xd_card->zone[zone_no]); if (zone->free_table == NULL) { - if (xd_build_l2p_tbl(chip, zone_no) != STATUS_SUCCESS) { + if (xd_build_l2p_tbl(chip, zone_no) != STATUS_SUCCESS) return; - } } if ((zone->set_index >= XD_FREE_TABLE_CNT) @@ -889,9 +847,8 @@ static void xd_set_unused_block(struct rtsx_chip *chip, u32 phy_blk) RTSX_DEBUGP("Set unused block to index %d\n", zone->set_index); zone->free_table[zone->set_index++] = (u16) (phy_blk & 0x3ff); - if (zone->set_index >= XD_FREE_TABLE_CNT) { + if (zone->set_index >= XD_FREE_TABLE_CNT) zone->set_index = 0; - } zone->unused_blk_cnt++; } @@ -923,9 +880,8 @@ static u32 xd_get_unused_block(struct rtsx_chip *chip, int zone_no) phy_blk = zone->free_table[zone->get_index]; zone->free_table[zone->get_index++] = 0xFFFF; - if (zone->get_index >= XD_FREE_TABLE_CNT) { + if (zone->get_index >= XD_FREE_TABLE_CNT) zone->get_index = 0; - } zone->unused_blk_cnt--; phy_blk += ((u32)(zone_no) << 10); @@ -1004,19 +960,16 @@ int reset_xd_card(struct rtsx_chip *chip) xd_card->delay_write.delay_write_flag = 0; retval = enable_card_clock(chip, XD_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = reset_xd(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } retval = xd_init_l2p_tbl(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -1030,9 +983,8 @@ static int xd_mark_bad_block(struct rtsx_chip *chip, u32 phy_blk) RTSX_DEBUGP("mark block 0x%x as bad block\n", phy_blk); - if (phy_blk == BLK_NOT_FOUND) { + if (phy_blk == BLK_NOT_FOUND) TRACE_RET(chip, STATUS_FAIL); - } rtsx_init_cmd(chip); @@ -1060,11 +1012,10 @@ static int xd_mark_bad_block(struct rtsx_chip *chip, u32 phy_blk) if (retval < 0) { rtsx_clear_xd_error(chip); rtsx_read_register(chip, XD_DAT, ®); - if (reg & PROGRAM_ERROR) { + if (reg & PROGRAM_ERROR) xd_set_err_code(chip, XD_PRG_ERROR); - } else { + else xd_set_err_code(chip, XD_TO_ERROR); - } TRACE_RET(chip, STATUS_FAIL); } @@ -1080,12 +1031,10 @@ static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk, u16 logoff, u8 star RTSX_DEBUGP("Init block 0x%x\n", phy_blk); - if (start_page > end_page) { + if (start_page > end_page) TRACE_RET(chip, STATUS_FAIL); - } - if (phy_blk == BLK_NOT_FOUND) { + if (phy_blk == BLK_NOT_FOUND) TRACE_RET(chip, STATUS_FAIL); - } rtsx_init_cmd(chip); @@ -1130,13 +1079,11 @@ static int xd_copy_page(struct rtsx_chip *chip, u32 old_blk, u32 new_blk, u8 sta RTSX_DEBUGP("Copy page from block 0x%x to block 0x%x\n", old_blk, new_blk); - if (start_page > end_page) { + if (start_page > end_page) TRACE_RET(chip, STATUS_FAIL); - } - if ((old_blk == BLK_NOT_FOUND) || (new_blk == BLK_NOT_FOUND)) { + if ((old_blk == BLK_NOT_FOUND) || (new_blk == BLK_NOT_FOUND)) TRACE_RET(chip, STATUS_FAIL); - } old_page = (old_blk << xd_card->block_shift) + start_page; new_page = (new_blk << xd_card->block_shift) + start_page; @@ -1189,9 +1136,8 @@ static int xd_copy_page(struct rtsx_chip *chip, u32 old_blk, u32 new_blk, u8 sta } } - if (XD_CHK_BAD_OLDBLK(xd_card)) { + if (XD_CHK_BAD_OLDBLK(xd_card)) rtsx_clear_xd_error(chip); - } rtsx_init_cmd(chip); @@ -1236,14 +1182,12 @@ static int xd_reset_cmd(struct rtsx_chip *chip) rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0); retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } ptr = rtsx_get_cmd_data(chip) + 1; - if (((ptr[0] & READY_FLAG) == READY_STATE) && (ptr[1] & XD_RDY)) { + if (((ptr[0] & READY_FLAG) == READY_STATE) && (ptr[1] & XD_RDY)) return STATUS_SUCCESS; - } TRACE_RET(chip, STATUS_FAIL); } @@ -1255,9 +1199,8 @@ static int xd_erase_block(struct rtsx_chip *chip, u32 phy_blk) u8 reg = 0, *ptr; int i, retval; - if (phy_blk == BLK_NOT_FOUND) { + if (phy_blk == BLK_NOT_FOUND) TRACE_RET(chip, STATUS_FAIL); - } page_addr = phy_blk << xd_card->block_shift; @@ -1282,9 +1225,8 @@ static int xd_erase_block(struct rtsx_chip *chip, u32 phy_blk) xd_set_err_code(chip, XD_ERASE_FAIL); } retval = xd_reset_cmd(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } continue; } @@ -1317,9 +1259,8 @@ static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no) if (xd_card->zone == NULL) { retval = xd_init_l2p_tbl(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) return retval; - } } if (xd_card->zone[zone_no].build_flag) { @@ -1331,26 +1272,23 @@ static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no) if (zone->l2p_table == NULL) { zone->l2p_table = (u16 *)vmalloc(2000); - if (zone->l2p_table == NULL) { + if (zone->l2p_table == NULL) TRACE_GOTO(chip, Build_Fail); - } } memset((u8 *)(zone->l2p_table), 0xff, 2000); if (zone->free_table == NULL) { zone->free_table = (u16 *)vmalloc(XD_FREE_TABLE_CNT * 2); - if (zone->free_table == NULL) { + if (zone->free_table == NULL) TRACE_GOTO(chip, Build_Fail); - } } memset((u8 *)(zone->free_table), 0xff, XD_FREE_TABLE_CNT * 2); if (zone_no == 0) { - if (xd_card->cis_block == 0xFFFF) { + if (xd_card->cis_block == 0xFFFF) start = 0; - } else { + else start = xd_card->cis_block + 1; - } if (XD_CHK_4MB(xd_card)) { end = 0x200; max_logoff = 499; @@ -1374,9 +1312,8 @@ static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no) u32 phy_block; retval = xd_read_redundant(chip, page_addr, redunt, 11); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) continue; - } if (redunt[BLOCK_STATUS] != 0xFF) { RTSX_DEBUGP("bad block\n"); @@ -1392,15 +1329,13 @@ static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no) cur_fst_page_logoff = xd_load_log_block_addr(redunt); if ((cur_fst_page_logoff == 0xFFFF) || (cur_fst_page_logoff > max_logoff)) { retval = xd_erase_block(chip, i); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) xd_set_unused_block(chip, i); - } continue; } - if ((zone_no == 0) && (cur_fst_page_logoff == 0) && (redunt[PAGE_STATUS] != XD_GPG)) { + if ((zone_no == 0) && (cur_fst_page_logoff == 0) && (redunt[PAGE_STATUS] != XD_GPG)) XD_SET_MBR_FAIL(xd_card); - } if (zone->l2p_table[cur_fst_page_logoff] == 0xFFFF) { zone->l2p_table[cur_fst_page_logoff] = (u16)(i & 0x3FF); @@ -1412,9 +1347,8 @@ static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no) page_addr = ((i + 1) << xd_card->block_shift) - 1; retval = xd_read_redundant(chip, page_addr, redunt, 11); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) continue; - } cur_lst_page_logoff = xd_load_log_block_addr(redunt); if (cur_lst_page_logoff == cur_fst_page_logoff) { @@ -1431,9 +1365,8 @@ static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no) if (m == 3) { zone->l2p_table[cur_fst_page_logoff] = (u16)(i & 0x3FF); retval = xd_erase_block(chip, phy_block); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) xd_set_unused_block(chip, phy_block); - } continue; } @@ -1441,43 +1374,37 @@ static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no) if (ent_lst_page_logoff != cur_fst_page_logoff) { zone->l2p_table[cur_fst_page_logoff] = (u16)(i & 0x3FF); retval = xd_erase_block(chip, phy_block); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) xd_set_unused_block(chip, phy_block); - } continue; } else { retval = xd_erase_block(chip, i); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) xd_set_unused_block(chip, i); - } } } else { retval = xd_erase_block(chip, i); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) xd_set_unused_block(chip, i); - } } } - if (XD_CHK_4MB(xd_card)) { + if (XD_CHK_4MB(xd_card)) end = 500; - } else { + else end = 1000; - } i = 0; for (start = 0; start < end; start++) { - if (zone->l2p_table[start] == 0xFFFF) { + if (zone->l2p_table[start] == 0xFFFF) i++; - } } RTSX_DEBUGP("Block count %d, invalid L2P entry %d\n", end, i); RTSX_DEBUGP("Total unused block: %d\n", zone->unused_blk_cnt); - if ((zone->unused_blk_cnt - i) < 1) { + if ((zone->unused_blk_cnt - i) < 1) chip->card_wp |= XD_CARD; - } zone->build_flag = 1; @@ -1507,9 +1434,8 @@ static int xd_send_cmd(struct rtsx_chip *chip, u8 cmd) rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); retval = rtsx_send_cmd(chip, XD_CARD, 200); - if (retval < 0) { + if (retval < 0) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } @@ -1523,9 +1449,8 @@ static int xd_read_multiple_pages(struct rtsx_chip *chip, u32 phy_blk, u32 log_b u8 reg_val, page_cnt; int zone_no, retval, i; - if (start_page > end_page) { + if (start_page > end_page) TRACE_RET(chip, STATUS_FAIL); - } page_cnt = end_page - start_page; zone_no = (int)(log_blk / 1000); @@ -1584,9 +1509,8 @@ static int xd_read_multiple_pages(struct rtsx_chip *chip, u32 phy_blk, u32 log_b Fail: RTSX_READ_REG(chip, XD_PAGE_STATUS, ®_val); - if (reg_val != XD_GPG) { + if (reg_val != XD_GPG) xd_set_err_code(chip, XD_PRG_ERROR); - } RTSX_READ_REG(chip, XD_CTL, ®_val); @@ -1613,9 +1537,8 @@ Fail: if (retval != STATUS_SUCCESS) { if (!XD_CHK_BAD_NEWBLK(xd_card)) { retval = xd_erase_block(chip, new_blk); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) xd_set_unused_block(chip, new_blk); - } } else { XD_CLR_BAD_NEWBLK(xd_card); } @@ -1641,9 +1564,8 @@ static int xd_finish_write(struct rtsx_chip *chip, RTSX_DEBUGP("xd_finish_write, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n", old_blk, new_blk, log_blk); - if (page_off > xd_card->page_off) { + if (page_off > xd_card->page_off) TRACE_RET(chip, STATUS_FAIL); - } zone_no = (int)(log_blk / 1000); log_off = (u16)(log_blk % 1000); @@ -1653,9 +1575,8 @@ static int xd_finish_write(struct rtsx_chip *chip, page_off, xd_card->page_off + 1); if (retval != STATUS_SUCCESS) { retval = xd_erase_block(chip, new_blk); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) xd_set_unused_block(chip, new_blk); - } TRACE_RET(chip, STATUS_FAIL); } } else { @@ -1664,9 +1585,8 @@ static int xd_finish_write(struct rtsx_chip *chip, if (retval != STATUS_SUCCESS) { if (!XD_CHK_BAD_NEWBLK(xd_card)) { retval = xd_erase_block(chip, new_blk); - if (retval == STATUS_SUCCESS) { + if (retval == STATUS_SUCCESS) xd_set_unused_block(chip, new_blk); - } } XD_CLR_BAD_NEWBLK(xd_card); TRACE_RET(chip, STATUS_FAIL); @@ -1701,9 +1621,8 @@ static int xd_prepare_write(struct rtsx_chip *chip, if (page_off) { retval = xd_copy_page(chip, old_blk, new_blk, 0, page_off); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } return STATUS_SUCCESS; @@ -1722,9 +1641,8 @@ static int xd_write_multiple_pages(struct rtsx_chip *chip, u32 old_blk, u32 new_ RTSX_DEBUGP("%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n", __func__, old_blk, new_blk, log_blk); - if (start_page > end_page) { + if (start_page > end_page) TRACE_RET(chip, STATUS_FAIL); - } page_cnt = end_page - start_page; zone_no = (int)(log_blk / 1000); @@ -1733,9 +1651,8 @@ static int xd_write_multiple_pages(struct rtsx_chip *chip, u32 old_blk, u32 new_ page_addr = (new_blk << xd_card->block_shift) + start_page; retval = xd_send_cmd(chip, READ1_1); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } rtsx_init_cmd(chip); @@ -1812,17 +1729,15 @@ int xd_delay_write(struct rtsx_chip *chip) if (delay_write->delay_write_flag) { RTSX_DEBUGP("xd_delay_write\n"); retval = xd_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } delay_write->delay_write_flag = 0; retval = xd_finish_write(chip, delay_write->old_phyblock, delay_write->new_phyblock, delay_write->logblock, delay_write->pageoff); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } return STATUS_SUCCESS; @@ -1852,9 +1767,9 @@ int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 s ptr = (u8 *)scsi_sglist(srb); retval = xd_switch_clock(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } + if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { chip->card_fail |= XD_CARD; @@ -1955,11 +1870,11 @@ int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 s TRACE_RET(chip, STATUS_FAIL); } - if ((start_page + total_sec_cnt) > (xd_card->page_off + 1)) { + if ((start_page + total_sec_cnt) > (xd_card->page_off + 1)) end_page = xd_card->page_off + 1; - } else { + else end_page = start_page + (u8)total_sec_cnt; - } + page_cnt = end_page - start_page; if (srb->sc_data_direction == DMA_FROM_DEVICE) { retval = xd_read_multiple_pages(chip, old_blk, log_blk, @@ -1999,11 +1914,11 @@ int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 s old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); if (old_blk == BLK_NOT_FOUND) { - if (srb->sc_data_direction == DMA_FROM_DEVICE) { + if (srb->sc_data_direction == DMA_FROM_DEVICE) set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - } else { + else set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - } + TRACE_RET(chip, STATUS_FAIL); } @@ -2089,26 +2004,23 @@ int xd_power_off_card3v3(struct rtsx_chip *chip) int retval; retval = disable_card_clock(chip, XD_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } RTSX_WRITE_REG(chip, CARD_OE, XD_OUTPUT_EN, 0); if (!chip->ft2_fast_mode) { retval = card_power_off(chip, XD_CARD); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } wait_timeout(50); } if (chip->asic_code) { retval = xd_pull_ctl_disable(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } } else { RTSX_WRITE_REG(chip, FPGA_PULL_CTL, 0xFF, 0xDF); } @@ -2132,9 +2044,8 @@ int release_xd_card(struct rtsx_chip *chip) xd_free_l2p_tbl(chip); retval = xd_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) { + if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); - } return STATUS_SUCCESS; } -- cgit v1.2.3 From 2c62c674e0e9994cd54502f8311892e50c8ca347 Mon Sep 17 00:00:00 2001 From: Timo von Holtz Date: Fri, 4 Feb 2011 21:29:46 +0100 Subject: staging: speakup: enlosed macros with complex values in parenthesis Enclosed all macros with complex values in parenthesis Signed-off-by: Timo von Holtz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/spk_priv_keyinfo.h | 44 +++++++++++++++--------------- drivers/staging/speakup/spk_types.h | 18 ++++++------ 2 files changed, 31 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/speakup/spk_priv_keyinfo.h b/drivers/staging/speakup/spk_priv_keyinfo.h index 3fd4b82f84a5..95c473a7e65f 100644 --- a/drivers/staging/speakup/spk_priv_keyinfo.h +++ b/drivers/staging/speakup/spk_priv_keyinfo.h @@ -84,27 +84,27 @@ /* keys for setting variables, must be ordered same as the enum for var_ids */ /* with dec being even and inc being 1 greater */ -#define SPELL_DELAY_DEC VAR_START+0 -#define SPELL_DELAY_INC SPELL_DELAY_DEC+1 -#define PUNC_LEVEL_DEC SPELL_DELAY_DEC+2 -#define PUNC_LEVEL_INC PUNC_LEVEL_DEC+1 -#define READING_PUNC_DEC PUNC_LEVEL_DEC+2 -#define READING_PUNC_INC READING_PUNC_DEC+1 -#define ATTRIB_BLEEP_DEC READING_PUNC_DEC+2 -#define ATTRIB_BLEEP_INC ATTRIB_BLEEP_DEC+1 -#define BLEEPS_DEC ATTRIB_BLEEP_DEC+2 -#define BLEEPS_INC BLEEPS_DEC+1 -#define RATE_DEC BLEEPS_DEC+2 -#define RATE_INC RATE_DEC+1 -#define PITCH_DEC RATE_DEC+2 -#define PITCH_INC PITCH_DEC+1 -#define VOL_DEC PITCH_DEC+2 -#define VOL_INC VOL_DEC+1 -#define TONE_DEC VOL_DEC+2 -#define TONE_INC TONE_DEC+1 -#define PUNCT_DEC TONE_DEC+2 -#define PUNCT_INC PUNCT_DEC+1 -#define VOICE_DEC PUNCT_DEC+2 -#define VOICE_INC VOICE_DEC+1 +#define SPELL_DELAY_DEC (VAR_START+0) +#define SPELL_DELAY_INC (SPELL_DELAY_DEC+1) +#define PUNC_LEVEL_DEC (SPELL_DELAY_DEC+2) +#define PUNC_LEVEL_INC (PUNC_LEVEL_DEC+1) +#define READING_PUNC_DEC (PUNC_LEVEL_DEC+2) +#define READING_PUNC_INC (READING_PUNC_DEC+1) +#define ATTRIB_BLEEP_DEC (READING_PUNC_DEC+2) +#define ATTRIB_BLEEP_INC (ATTRIB_BLEEP_DEC+1) +#define BLEEPS_DEC (ATTRIB_BLEEP_DEC+2) +#define BLEEPS_INC (BLEEPS_DEC+1) +#define RATE_DEC (BLEEPS_DEC+2) +#define RATE_INC (RATE_DEC+1) +#define PITCH_DEC (RATE_DEC+2) +#define PITCH_INC (PITCH_DEC+1) +#define VOL_DEC (PITCH_DEC+2) +#define VOL_INC (VOL_DEC+1) +#define TONE_DEC (VOL_DEC+2) +#define TONE_INC (TONE_DEC+1) +#define PUNCT_DEC (TONE_DEC+2) +#define PUNCT_INC (PUNCT_DEC+1) +#define VOICE_DEC (PUNCT_DEC+2) +#define VOICE_INC (VOICE_DEC+1) #endif diff --git a/drivers/staging/speakup/spk_types.h b/drivers/staging/speakup/spk_types.h index d36c90e30d54..3ac552c1236e 100644 --- a/drivers/staging/speakup/spk_types.h +++ b/drivers/staging/speakup/spk_types.h @@ -79,14 +79,14 @@ struct st_spk_t { }; /* now some defines to make these easier to use. */ -#define spk_shut_up speakup_console[vc->vc_num]->shut_up +#define spk_shut_up (speakup_console[vc->vc_num]->shut_up) #define spk_killed (speakup_console[vc->vc_num]->shut_up & 0x40) -#define spk_x speakup_console[vc->vc_num]->reading_x -#define spk_cx speakup_console[vc->vc_num]->cursor_x -#define spk_y speakup_console[vc->vc_num]->reading_y -#define spk_cy speakup_console[vc->vc_num]->cursor_y +#define spk_x (speakup_console[vc->vc_num]->reading_x) +#define spk_cx (speakup_console[vc->vc_num]->cursor_x) +#define spk_y (speakup_console[vc->vc_num]->reading_y) +#define spk_cy (speakup_console[vc->vc_num]->cursor_y) #define spk_pos (speakup_console[vc->vc_num]->reading_pos) -#define spk_cp speakup_console[vc->vc_num]->cursor_pos +#define spk_cp (speakup_console[vc->vc_num]->cursor_pos) #define goto_pos (speakup_console[vc->vc_num]->go_pos) #define goto_x (speakup_console[vc->vc_num]->go_x) #define win_top (speakup_console[vc->vc_num]->w_top) @@ -95,9 +95,9 @@ struct st_spk_t { #define win_right (speakup_console[vc->vc_num]->w_right) #define win_start (speakup_console[vc->vc_num]->w_start) #define win_enabled (speakup_console[vc->vc_num]->w_enabled) -#define spk_attr speakup_console[vc->vc_num]->reading_attr -#define spk_old_attr speakup_console[vc->vc_num]->old_attr -#define spk_parked speakup_console[vc->vc_num]->parked +#define spk_attr (speakup_console[vc->vc_num]->reading_attr) +#define spk_old_attr (speakup_console[vc->vc_num]->old_attr) +#define spk_parked (speakup_console[vc->vc_num]->parked) struct st_var_header { char *name; -- cgit v1.2.3 From c69ab1a2cfe5018cf7add67b278db9c744661f0f Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 31 Jan 2011 22:48:25 -0800 Subject: staging: pohmelfs: Fix some typos, and comments. The patch below fixes some typos, and makes some comments sound more proper. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/pohmelfs/config.c | 2 +- drivers/staging/pohmelfs/inode.c | 10 +++++----- drivers/staging/pohmelfs/netfs.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c index 89279ba1b737..ed913306e5d6 100644 --- a/drivers/staging/pohmelfs/config.c +++ b/drivers/staging/pohmelfs/config.c @@ -134,7 +134,7 @@ int pohmelfs_copy_config(struct pohmelfs_sb *psb) goto out_unlock; /* - * Run over all entries in given config group and try to crate and + * Run over all entries in given config group and try to create and * initialize those, which do not exist in superblock list. * Skip all existing entries. */ diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c index 56d3a4e5622f..c93ef207b0b4 100644 --- a/drivers/staging/pohmelfs/inode.c +++ b/drivers/staging/pohmelfs/inode.c @@ -834,7 +834,7 @@ static void pohmelfs_i_callback(struct rcu_head *head) } /* - * ->detroy_inode() callback. Deletes inode from the caches + * ->destroy_inode() callback. Deletes inode from the caches * and frees private data. */ static void pohmelfs_destroy_inode(struct inode *inode) @@ -1127,18 +1127,18 @@ static ssize_t pohmelfs_getxattr(struct dentry *dentry, const char *name, /* * This loop is a bit ugly, since it waits until reference counter - * hits 1 and then put object here. Main goal is to prevent race with - * network thread, when it can start processing given request, i.e. + * hits 1 and then puts the object here. Main goal is to prevent race with + * the network thread, when it can start processing the given request, i.e. * increase its reference counter but yet not complete it, while * we will exit from ->getxattr() with timeout, and although request * will not be freed (its reference counter was increased by network * thread), data pointer provided by user may be released, so we will - * overwrite already freed area in network thread. + * overwrite an already freed area in the network thread. * * Now after timeout we remove request from the cache, so it can not be * found by network thread, and wait for its reference counter to hit 1, * i.e. if network thread already started to process this request, we wait - * it to finish, and then free object locally. If reference counter is + * for it to finish, and then free object locally. If reference counter is * already 1, i.e. request is not used by anyone else, we can free it without * problem. */ diff --git a/drivers/staging/pohmelfs/netfs.h b/drivers/staging/pohmelfs/netfs.h index 63391d2c25a4..985b6b755d5d 100644 --- a/drivers/staging/pohmelfs/netfs.h +++ b/drivers/staging/pohmelfs/netfs.h @@ -191,7 +191,7 @@ enum { /* * POHMELFS capabilities: information about supported * crypto operations (hash/cipher, modes, key sizes and so on), - * root informaion (used/available size, number of objects, permissions) + * root information (used/available size, number of objects, permissions) */ enum pohmelfs_capabilities { POHMELFS_CRYPTO_CAPABILITIES = 0, -- cgit v1.2.3 From 00719fab9f6eb90b9e427d1096ad540d51878661 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 25 Jan 2011 01:46:18 +0100 Subject: Staging: bcm: Check correct user provided length and fix error code returned bcm driver copies a buffer length provided by userpace without checking it. RxCntrlMsgBitMask is of type unsigned long so only makes sense to copy sizeof(unsigned long) bytes. Also, copy_from_user() returns the number of bytes that could not be copied. The driver is returning that value as error code instead of -EFAULT. This patch solves both issues. Signed-off-by: Javier Martinez Canillas Cc: Stephen Hemminger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 31674ea1cd48..7dff283edb65 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -2024,6 +2024,12 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if(Status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of Ioctl buffer is failed from user space"); + Status = -EFAULT; + break; + } + + if (IoBuffer.InputLength != sizeof(unsigned long)) { + Status = -EINVAL; break; } @@ -2031,6 +2037,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if(Status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of control bit mask failed from user space"); + Status = -EFAULT; break; } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\n Got user defined cntrl msg bit mask :%lx", RxCntrlMsgBitMask); -- cgit v1.2.3 From b977e29f825a4472520e78b61d92cc1f53d7ba80 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Tue, 1 Feb 2011 21:07:49 -0800 Subject: staging: rt2860: cmm_mac_pci.c change a typo comamnd to command The below patch fixes a typo comamnd to command. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/common/cmm_mac_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/common/cmm_mac_pci.c b/drivers/staging/rt2860/common/cmm_mac_pci.c index 850f0fbc6d90..21eed2507e1c 100644 --- a/drivers/staging/rt2860/common/cmm_mac_pci.c +++ b/drivers/staging/rt2860/common/cmm_mac_pci.c @@ -753,7 +753,7 @@ BOOLEAN AsicCheckCommanOk(struct rt_rtmp_adapter *pAd, u8 Command) /* This command's status is at the same position as command. So AND command position's bitmask to read status. */ if (i < 200) { - /* If Status is 1, the comamnd is success. */ + /* If Status is 1, the command is success. */ if (((CmdStatus & ThisCIDMask) == 0x1) || ((CmdStatus & ThisCIDMask) == 0x100) || ((CmdStatus & ThisCIDMask) == 0x10000) -- cgit v1.2.3 From 698a9dce7757502da5c92e0a166aaff9e7c27345 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Tue, 1 Feb 2011 21:08:09 -0800 Subject: staging: octeon: change a typo comamnd to command The below patch fixes a typo comamnd to command. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/octeon/cvmx-cmd-queue.h | 16 ++++++++-------- drivers/staging/octeon/cvmx-pko.c | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/octeon/cvmx-cmd-queue.h b/drivers/staging/octeon/cvmx-cmd-queue.h index f0cb20ffa39a..59d221422293 100644 --- a/drivers/staging/octeon/cvmx-cmd-queue.h +++ b/drivers/staging/octeon/cvmx-cmd-queue.h @@ -110,7 +110,7 @@ typedef enum { } cvmx_cmd_queue_id_t; /** - * Command write operations can fail if the comamnd queue needs + * Command write operations can fail if the command queue needs * a new buffer and the associated FPA pool is empty. It can also * fail if the number of queued command words reaches the maximum * set at initialization. @@ -136,12 +136,12 @@ typedef struct { uint64_t unused2:6; /* FPA buffer size in 64bit words minus 1 */ uint64_t pool_size_m1:13; - /* Number of comamnds already used in buffer */ + /* Number of commands already used in buffer */ uint64_t index:13; } __cvmx_cmd_queue_state_t; /** - * This structure contains the global state of all comamnd queues. + * This structure contains the global state of all command queues. * It is stored in a bootmem named block and shared by all * applications running on Octeon. Tickets are stored in a differnet * cahce line that queue information to reduce the contention on the @@ -308,7 +308,7 @@ static inline __cvmx_cmd_queue_state_t /** * Write an arbitrary number of command words to a command queue. - * This is a generic function; the fixed number of comamnd word + * This is a generic function; the fixed number of command word * functions yield higher performance. * * @queue_id: Hardware command queue to write to @@ -317,7 +317,7 @@ static inline __cvmx_cmd_queue_state_t * updates. If you don't use this locking you must ensure * exclusivity some other way. Locking is strongly recommended. * @cmd_count: Number of command words to write - * @cmds: Array of comamnds to write + * @cmds: Array of commands to write * * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code */ @@ -363,7 +363,7 @@ static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write(cvmx_cmd_queue_id_t uint64_t *ptr; int count; /* - * We need a new comamnd buffer. Fail if there isn't + * We need a new command buffer. Fail if there isn't * one available. */ uint64_t *new_buffer = @@ -466,7 +466,7 @@ static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write2(cvmx_cmd_queue_id_t */ int count = qptr->pool_size_m1 - qptr->index; /* - * We need a new comamnd buffer. Fail if there isn't + * We need a new command buffer. Fail if there isn't * one available. */ uint64_t *new_buffer = @@ -568,7 +568,7 @@ static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write3(cvmx_cmd_queue_id_t */ int count = qptr->pool_size_m1 - qptr->index; /* - * We need a new comamnd buffer. Fail if there isn't + * We need a new command buffer. Fail if there isn't * one available */ uint64_t *new_buffer = diff --git a/drivers/staging/octeon/cvmx-pko.c b/drivers/staging/octeon/cvmx-pko.c index 00db91529b19..50a2c9bd5a55 100644 --- a/drivers/staging/octeon/cvmx-pko.c +++ b/drivers/staging/octeon/cvmx-pko.c @@ -54,7 +54,7 @@ void cvmx_pko_initialize_global(void) /* * Set the size of the PKO command buffers to an odd number of * 64bit words. This allows the normal two word send to stay - * aligned and never span a comamnd word buffer. + * aligned and never span a command word buffer. */ config.u64 = 0; config.s.pool = CVMX_FPA_OUTPUT_BUFFER_POOL; -- cgit v1.2.3 From 5abb04a63b890dc3f4abdf7d34e8ee1943546bd7 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 21 Jan 2011 15:44:12 +0100 Subject: staging: brcm80211: implementation of RFKILL functionality Resubmitted the patch to align with staging-next tree. This change depends on suspend/resume patch as sent on Wed, Jan 12, 2011. Only hardware switch state needs to be handled by driver. RFKILL is informed when hardware switch is activated. MAC80211 rfkill_poll callback is used to check hardware switch deactivation. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_export.h | 1 + drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 37 ++++++++++++++++++++++- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 8 ++--- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 12 +++++--- drivers/staging/brcm80211/brcmsmac/wlc_pub.h | 1 + 5 files changed, 48 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_export.h b/drivers/staging/brcm80211/brcmsmac/wl_export.h index aa8b5a3ed633..16c626a8458c 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_export.h +++ b/drivers/staging/brcm80211/brcmsmac/wl_export.h @@ -34,6 +34,7 @@ extern void wl_down(struct wl_info *wl); extern void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, int prio); extern bool wl_alloc_dma_resources(struct wl_info *wl, uint dmaddrwidth); +extern bool wl_rfkill_set_hw_state(struct wl_info *wl); /* timer functions */ struct wl_timer; diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index add00462bc52..5ce0f0701d0e 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -142,6 +142,7 @@ static int wl_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, static int wl_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, struct ieee80211_sta *sta, u16 tid, u16 *ssn); +static void wl_ops_rfkill_poll(struct ieee80211_hw *hw); static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { @@ -162,6 +163,7 @@ static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) static int wl_ops_start(struct ieee80211_hw *hw) { struct wl_info *wl = hw->priv; + bool blocked; /* struct ieee80211_channel *curchan = hw->conf.channel; WL_NONE("%s : Initial channel: %d\n", __func__, curchan->hw_value); @@ -170,6 +172,9 @@ static int wl_ops_start(struct ieee80211_hw *hw) WL_LOCK(wl); ieee80211_wake_queues(hw); WL_UNLOCK(wl); + blocked = wl_rfkill_set_hw_state(wl); + if (!blocked) + wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); return 0; } @@ -205,8 +210,9 @@ wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) err = wl_up(wl); WL_UNLOCK(wl); - if (err != 0) + if (err != 0) { WL_ERROR("%s: wl_up() returned %d\n", __func__, err); + } return err; } @@ -583,6 +589,19 @@ wl_ampdu_action(struct ieee80211_hw *hw, return 0; } +static void wl_ops_rfkill_poll(struct ieee80211_hw *hw) +{ + struct wl_info *wl = HW_TO_WL(hw); + bool blocked; + + WL_LOCK(wl); + blocked = wlc_check_radio_disabled(wl->wlc); + WL_UNLOCK(wl); + + WL_ERROR("wl: rfkill_poll: %d\n", blocked); + wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked); +} + static const struct ieee80211_ops wl_ops = { .tx = wl_ops_tx, .start = wl_ops_start, @@ -604,6 +623,7 @@ static const struct ieee80211_ops wl_ops = { .sta_add = wl_sta_add, .sta_remove = wl_sta_remove, .ampdu_action = wl_ampdu_action, + .rfkill_poll = wl_ops_rfkill_poll, }; static int wl_set_hint(struct wl_info *wl, char *abbrev) @@ -1137,6 +1157,11 @@ static void wl_remove(struct pci_dev *pdev) WL_ERROR("wl: wl_remove: pci_get_drvdata failed\n"); return; } + + /* make sure rfkill is not using driver */ + wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); + wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); + if (!wlc_chipmatch(pdev->vendor, pdev->device)) { WL_ERROR("wl: wl_remove: wlc_chipmatch failed\n"); return; @@ -1815,3 +1840,13 @@ int wl_check_firmwares(struct wl_info *wl) return rc; } +bool wl_rfkill_set_hw_state(struct wl_info *wl) +{ + bool blocked = wlc_check_radio_disabled(wl->wlc); + + WL_ERROR("%s: update hw state: blocked=%s\n", __func__, blocked ? "true" : "false"); + wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked); + if (blocked) + wiphy_rfkill_start_polling(wl->pub->ieee_hw->wiphy); + return blocked; +} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 80716c544781..631ee733b9f5 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -428,14 +428,10 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) } if (macintstatus & MI_RFDISABLE) { -#if defined(BCMDBG) - u32 rfd = R_REG(wlc_hw->osh, ®s->phydebug) & PDBG_RFD; -#endif - - WL_ERROR("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n", - wlc_hw->unit, rfd); + WL_TRACE("wl%d: BMAC Detected a change on the RF Disable Input\n", wlc_hw->unit); WLCNTINCR(wlc->pub->_cnt->rfdisable); + wl_rfkill_set_hw_state(wlc->wl); } /* send any enq'd tx packets. Just makes sure to jump start tx */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index 683bc5fd55ea..bba84ebe4d5b 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -2304,10 +2304,6 @@ void wlc_radio_mpc_upd(struct wlc_info *wlc) */ static void wlc_radio_upd(struct wlc_info *wlc) { - if (wlc->pub->radio_disabled) - wlc_radio_disable(wlc); - else - wlc_radio_enable(wlc); } /* maintain LED behavior in down state */ @@ -2324,6 +2320,14 @@ static void wlc_down_led_upd(struct wlc_info *wlc) } } +/* update hwradio status and return it */ +bool wlc_check_radio_disabled(struct wlc_info *wlc) +{ + wlc_radio_hwdisable_upd(wlc); + + return mboolisset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE) ? true : false; +} + void wlc_radio_disable(struct wlc_info *wlc) { if (!wlc->pub->up) { diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h index e8b252a699f8..0e39414d5e54 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h @@ -598,6 +598,7 @@ extern void wlc_getrand(struct wlc_info *wlc, u8 *buf, int len); struct scb; extern void wlc_ps_on(struct wlc_info *wlc, struct scb *scb); extern void wlc_ps_off(struct wlc_info *wlc, struct scb *scb, bool discard); +extern bool wlc_check_radio_disabled(struct wlc_info *wlc); extern bool wlc_radio_monitor_stop(struct wlc_info *wlc); #if defined(BCMDBG) -- cgit v1.2.3 From 2fd31011ac786e2bb9c0a76ddb23468e0e65abdc Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 1 Feb 2011 10:32:28 +0100 Subject: staging: brcm80211: removed unused DMA32 related code removed C code and that was never invoked, and declarations that are not used anymore. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/hnddma.h | 43 +--------- drivers/staging/brcm80211/util/hnddma.c | 133 ----------------------------- 2 files changed, 1 insertion(+), 175 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/hnddma.h b/drivers/staging/brcm80211/include/hnddma.h index 4c5462baf11e..002c118fdc9e 100644 --- a/drivers/staging/brcm80211/include/hnddma.h +++ b/drivers/staging/brcm80211/include/hnddma.h @@ -148,47 +148,7 @@ extern struct hnddma_pub *dma_attach(struct osl_info *osh, char *name, void *dmaregstx, void *dmaregsrx, uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, uint nrxpost, uint rxoffset, uint *msg_level); -#ifdef BCMDMA32 - -#define dma_detach(di) ((di)->di_fn->detach(di)) -#define dma_txreset(di) ((di)->di_fn->txreset(di)) -#define dma_rxreset(di) ((di)->di_fn->rxreset(di)) -#define dma_rxidle(di) ((di)->di_fn->rxidle(di)) -#define dma_txinit(di) ((di)->di_fn->txinit(di)) -#define dma_txenabled(di) ((di)->di_fn->txenabled(di)) -#define dma_rxinit(di) ((di)->di_fn->rxinit(di)) -#define dma_txsuspend(di) ((di)->di_fn->txsuspend(di)) -#define dma_txresume(di) ((di)->di_fn->txresume(di)) -#define dma_txsuspended(di) ((di)->di_fn->txsuspended(di)) -#define dma_txsuspendedidle(di) ((di)->di_fn->txsuspendedidle(di)) -#define dma_txfast(di, p, commit) ((di)->di_fn->txfast(di, p, commit)) -#define dma_fifoloopbackenable(di) ((di)->di_fn->fifoloopbackenable(di)) -#define dma_txstopped(di) ((di)->di_fn->txstopped(di)) -#define dma_rxstopped(di) ((di)->di_fn->rxstopped(di)) -#define dma_rxenable(di) ((di)->di_fn->rxenable(di)) -#define dma_rxenabled(di) ((di)->di_fn->rxenabled(di)) -#define dma_rx(di) ((di)->di_fn->rx(di)) -#define dma_rxfill(di) ((di)->di_fn->rxfill(di)) -#define dma_txreclaim(di, range) ((di)->di_fn->txreclaim(di, range)) -#define dma_rxreclaim(di) ((di)->di_fn->rxreclaim(di)) -#define dma_getvar(di, name) ((di)->di_fn->d_getvar(di, name)) -#define dma_getnexttxp(di, range) ((di)->di_fn->getnexttxp(di, range)) -#define dma_getnextrxp(di, forceall) ((di)->di_fn->getnextrxp(di, forceall)) -#define dma_peeknexttxp(di) ((di)->di_fn->peeknexttxp(di)) -#define dma_peeknextrxp(di) ((di)->di_fn->peeknextrxp(di)) -#define dma_rxparam_get(di, off, bufs) ((di)->di_fn->rxparam_get(di, off, bufs)) - -#define dma_txblock(di) ((di)->di_fn->txblock(di)) -#define dma_txunblock(di) ((di)->di_fn->txunblock(di)) -#define dma_txactive(di) ((di)->di_fn->txactive(di)) -#define dma_rxactive(di) ((di)->di_fn->rxactive(di)) -#define dma_txrotate(di) ((di)->di_fn->txrotate(di)) -#define dma_counterreset(di) ((di)->di_fn->counterreset(di)) -#define dma_ctrlflags(di, mask, flags) ((di)->di_fn->ctrlflags((di), (mask), (flags))) -#define dma_txpending(di) ((di)->di_fn->txpending(di)) -#define dma_txcommitted(di) ((di)->di_fn->txcommitted(di)) - -#else /* BCMDMA32 */ + extern const di_fcn_t dma64proc; #define dma_detach(di) (dma64proc.detach(di)) @@ -231,7 +191,6 @@ extern const di_fcn_t dma64proc; #define dma_txpending(di) (dma64proc.txpending(di)) #define dma_txcommitted(di) (dma64proc.txcommitted(di)) -#endif /* BCMDMA32 */ /* return addresswidth allowed * This needs to be done after SB attach but before dma attach. diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index d08869239d5b..95e572ff2f7f 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -151,24 +151,8 @@ typedef struct dma_info { bool aligndesc_4k; /* descriptor base need to be aligned or not */ } dma_info_t; -/* - * If BCMDMA32 is defined, hnddma will support both 32-bit and 64-bit DMA engines. - * Otherwise it will support only 64-bit. - * - * DMA32_ENAB indicates whether hnddma is compiled with support for 32-bit DMA engines. - * DMA64_ENAB indicates whether hnddma is compiled with support for 64-bit DMA engines. - * - * DMA64_MODE indicates whether the current DMA engine is running as 64-bit. - */ -#ifdef BCMDMA32 -#define DMA32_ENAB(di) 1 -#define DMA64_ENAB(di) 1 -#define DMA64_MODE(di) ((di)->dma64) -#else /* !BCMDMA32 */ -#define DMA32_ENAB(di) 0 #define DMA64_ENAB(di) 1 #define DMA64_MODE(di) 1 -#endif /* !BCMDMA32 */ /* DMA Scatter-gather list is supported. Note this is limited to TX direction only */ #ifdef BCMDMASGLISTOSL @@ -418,12 +402,6 @@ struct hnddma_pub *dma_attach(struct osl_info *osh, char *name, si_t *sih, di->d64txregs = (dma64regs_t *) dmaregstx; di->d64rxregs = (dma64regs_t *) dmaregsrx; di->hnddma.di_fn = (const di_fcn_t *)&dma64proc; - } else if (DMA32_ENAB(di)) { - ASSERT(ntxd <= D32MAXDD); - ASSERT(nrxd <= D32MAXDD); - di->d32txregs = (dma32regs_t *) dmaregstx; - di->d32rxregs = (dma32regs_t *) dmaregsrx; - di->hnddma.di_fn = (const di_fcn_t *)&dma32proc; } else { DMA_ERROR(("dma_attach: driver doesn't support 32-bit DMA\n")); ASSERT(0); @@ -683,8 +661,6 @@ static bool _dma_alloc(dma_info_t *di, uint direction) { if (DMA64_ENAB(di) && DMA64_MODE(di)) { return dma64_alloc(di, direction); - } else if (DMA32_ENAB(di)) { - return dma32_alloc(di, direction); } else ASSERT(0); } @@ -711,17 +687,6 @@ static void _dma_detach(dma_info_t *di) ((s8 *)di->rxd64 - di->rxdalign), di->rxdalloc, (di->rxdpaorig), &di->rx_dmah); - } else if (DMA32_ENAB(di)) { - if (di->txd32) - DMA_FREE_CONSISTENT(di->osh, - ((s8 *)di->txd32 - - di->txdalign), di->txdalloc, - (di->txdpaorig), &di->tx_dmah); - if (di->rxd32) - DMA_FREE_CONSISTENT(di->osh, - ((s8 *)di->rxd32 - - di->rxdalign), di->rxdalloc, - (di->rxdpaorig), &di->rx_dmah); } else ASSERT(0); @@ -786,11 +751,6 @@ static bool _dma_isaddrext(dma_info_t *di) return true; } return false; - } else if (DMA32_ENAB(di)) { - if (di->d32txregs) - return _dma32_addrext(di->osh, di->d32txregs); - else if (di->d32rxregs) - return _dma32_addrext(di->osh, di->d32rxregs); } else ASSERT(0); @@ -848,39 +808,6 @@ static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa) D64_RC_AE, (ae << D64_RC_AE_SHIFT)); } } - - } else if (DMA32_ENAB(di)) { - ASSERT(PHYSADDRHI(pa) == 0); - if ((di->ddoffsetlow == 0) - || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) { - if (direction == DMA_TX) - W_REG(di->osh, &di->d32txregs->addr, - (PHYSADDRLO(pa) + di->ddoffsetlow)); - else - W_REG(di->osh, &di->d32rxregs->addr, - (PHYSADDRLO(pa) + di->ddoffsetlow)); - } else { - /* dma32 address extension */ - u32 ae; - ASSERT(di->addrext); - - /* shift the high bit(s) from pa to ae */ - ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> - PCI32ADDR_HIGH_SHIFT; - PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH; - - if (direction == DMA_TX) { - W_REG(di->osh, &di->d32txregs->addr, - (PHYSADDRLO(pa) + di->ddoffsetlow)); - SET_REG(di->osh, &di->d32txregs->control, XC_AE, - ae << XC_AE_SHIFT); - } else { - W_REG(di->osh, &di->d32rxregs->addr, - (PHYSADDRLO(pa) + di->ddoffsetlow)); - SET_REG(di->osh, &di->d32rxregs->control, RC_AE, - ae << RC_AE_SHIFT); - } - } } else ASSERT(0); } @@ -891,8 +818,6 @@ static void _dma_fifoloopbackenable(dma_info_t *di) if (DMA64_ENAB(di) && DMA64_MODE(di)) OR_REG(di->osh, &di->d64txregs->control, D64_XC_LE); - else if (DMA32_ENAB(di)) - OR_REG(di->osh, &di->d32txregs->control, XC_LE); else ASSERT(0); } @@ -921,11 +846,6 @@ static void _dma_rxinit(dma_info_t *di) if (di->aligndesc_4k) _dma_ddtable_init(di, DMA_RX, di->rxdpa); - } else if (DMA32_ENAB(di)) { - memset((void *)di->rxd32, '\0', - (di->nrxd * sizeof(dma32dd_t))); - _dma_rxenable(di); - _dma_ddtable_init(di, DMA_RX, di->rxdpa); } else ASSERT(0); } @@ -949,18 +869,6 @@ static void _dma_rxenable(dma_info_t *di) W_REG(di->osh, &di->d64rxregs->control, ((di->rxoffset << D64_RC_RO_SHIFT) | control)); - } else if (DMA32_ENAB(di)) { - u32 control = - (R_REG(di->osh, &di->d32rxregs->control) & RC_AE) | RC_RE; - - if ((dmactrlflags & DMA_CTRL_PEN) == 0) - control |= RC_PD; - - if (dmactrlflags & DMA_CTRL_ROC) - control |= RC_OC; - - W_REG(di->osh, &di->d32rxregs->control, - ((di->rxoffset << RC_RO_SHIFT) | control)); } else ASSERT(0); } @@ -1103,11 +1011,6 @@ static bool BCMFASTPATH _dma_rxfill(dma_info_t *di) DMA_ERROR(("%s: rxfill64: ring is empty !\n", di->name)); ring_empty = true; } - } else if (DMA32_ENAB(di)) { - if (dma32_rxidle(di)) { - DMA_ERROR(("%s: rxfill32: ring is empty !\n", di->name)); - ring_empty = true; - } } else ASSERT(0); } @@ -1144,13 +1047,6 @@ static bool BCMFASTPATH _dma_rxfill(dma_info_t *di) dma64_dd_upd(di, di->rxd64, pa, rxout, &flags, di->rxbufsize); - } else if (DMA32_ENAB(di)) { - if (rxout == (di->nrxd - 1)) - flags = CTRL_EOT; - - ASSERT(PHYSADDRHI(pa) == 0); - dma32_dd_upd(di, di->rxd32, pa, rxout, &flags, - di->rxbufsize); } else ASSERT(0); rxout = NEXTRXD(rxout); @@ -1162,8 +1058,6 @@ static bool BCMFASTPATH _dma_rxfill(dma_info_t *di) if (DMA64_ENAB(di) && DMA64_MODE(di)) { W_REG(di->osh, &di->d64rxregs->ptr, di->rcvptrbase + I2B(rxout, dma64dd_t)); - } else if (DMA32_ENAB(di)) { - W_REG(di->osh, &di->d32rxregs->ptr, I2B(rxout, dma32dd_t)); } else ASSERT(0); @@ -1183,10 +1077,6 @@ static void *_dma_peeknexttxp(dma_info_t *di) B2I(((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t); - } else if (DMA32_ENAB(di)) { - end = - B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, - dma32dd_t); } else ASSERT(0); @@ -1210,10 +1100,6 @@ static void *_dma_peeknextrxp(dma_info_t *di) B2I(((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t); - } else if (DMA32_ENAB(di)) { - end = - B2I(R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK, - dma32dd_t); } else ASSERT(0); @@ -1241,8 +1127,6 @@ static void *BCMFASTPATH _dma_getnextrxp(dma_info_t *di, bool forceall) if (DMA64_ENAB(di) && DMA64_MODE(di)) { return dma64_getnextrxp(di, forceall); - } else if (DMA32_ENAB(di)) { - return dma32_getnextrxp(di, forceall); } else ASSERT(0); } @@ -1271,10 +1155,6 @@ static uint _dma_txpending(dma_info_t *di) B2I(((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t); - } else if (DMA32_ENAB(di)) { - curr = - B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, - dma32dd_t); } else ASSERT(0); @@ -1291,8 +1171,6 @@ static uint _dma_txcommitted(dma_info_t *di) if (DMA64_ENAB(di) && DMA64_MODE(di)) { ptr = B2I(R_REG(di->osh, &di->d64txregs->ptr), dma64dd_t); - } else if (DMA32_ENAB(di)) { - ptr = B2I(R_REG(di->osh, &di->d32txregs->ptr), dma32dd_t); } else ASSERT(0); @@ -1344,17 +1222,6 @@ static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags) /* Not supported, don't allow it to be enabled */ dmactrlflags &= ~DMA_CTRL_PEN; } - } else if (DMA32_ENAB(di)) { - control = R_REG(di->osh, &di->d32txregs->control); - W_REG(di->osh, &di->d32txregs->control, - control | XC_PD); - if (R_REG(di->osh, &di->d32txregs->control) & XC_PD) { - W_REG(di->osh, &di->d32txregs->control, - control); - } else { - /* Not supported, don't allow it to be enabled */ - dmactrlflags &= ~DMA_CTRL_PEN; - } } else ASSERT(0); } -- cgit v1.2.3 From 36e319bd39fec1e9350d97cb6f4b589b3968500d Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 1 Feb 2011 10:32:29 +0100 Subject: staging: brcm80211: removed more unused dma32 code Since two preprocessor defines are always '1', could remove code that was never compiled in and removed references to these preprocessor defines (DMA64_ENAB and DMA64_MODE). Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/util/hnddma.c | 394 +++++++++++++------------------- 1 file changed, 162 insertions(+), 232 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 95e572ff2f7f..ae82e6bd0122 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -151,9 +151,6 @@ typedef struct dma_info { bool aligndesc_4k; /* descriptor base need to be aligned or not */ } dma_info_t; -#define DMA64_ENAB(di) 1 -#define DMA64_MODE(di) 1 - /* DMA Scatter-gather list is supported. Note this is limited to TX direction only */ #ifdef BCMDMASGLISTOSL #define DMASGLIST_ENAB true @@ -380,11 +377,7 @@ struct hnddma_pub *dma_attach(struct osl_info *osh, char *name, si_t *sih, /* old chips w/o sb is no longer supported */ ASSERT(sih != NULL); - if (DMA64_ENAB(di)) - di->dma64 = - ((si_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64); - else - di->dma64 = 0; + di->dma64 = ((si_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64); /* check arguments */ ASSERT(ISPOWEROF2(ntxd)); @@ -396,17 +389,11 @@ struct hnddma_pub *dma_attach(struct osl_info *osh, char *name, si_t *sih, ASSERT(dmaregstx == NULL); /* init dma reg pointer */ - if (DMA64_ENAB(di) && DMA64_MODE(di)) { - ASSERT(ntxd <= D64MAXDD); - ASSERT(nrxd <= D64MAXDD); - di->d64txregs = (dma64regs_t *) dmaregstx; - di->d64rxregs = (dma64regs_t *) dmaregsrx; - di->hnddma.di_fn = (const di_fcn_t *)&dma64proc; - } else { - DMA_ERROR(("dma_attach: driver doesn't support 32-bit DMA\n")); - ASSERT(0); - goto fail; - } + ASSERT(ntxd <= D64MAXDD); + ASSERT(nrxd <= D64MAXDD); + di->d64txregs = (dma64regs_t *) dmaregstx; + di->d64rxregs = (dma64regs_t *) dmaregsrx; + di->hnddma.di_fn = (const di_fcn_t *)&dma64proc; /* Default flags (which can be changed by the driver calling dma_ctrlflags * before enable): For backwards compatibility both Rx Overflow Continue @@ -416,7 +403,11 @@ struct hnddma_pub *dma_attach(struct osl_info *osh, char *name, si_t *sih, di->hnddma.di_fn->ctrlflags(&di->hnddma, DMA_CTRL_ROC | DMA_CTRL_PEN, 0); - DMA_TRACE(("%s: dma_attach: %s osh %p flags 0x%x ntxd %d nrxd %d rxbufsize %d " "rxextheadroom %d nrxpost %d rxoffset %d dmaregstx %p dmaregsrx %p\n", name, (DMA64_MODE(di) ? "DMA64" : "DMA32"), osh, di->hnddma.dmactrlflags, ntxd, nrxd, rxbufsize, rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx)); + DMA_TRACE(("%s: dma_attach: %s osh %p flags 0x%x ntxd %d nrxd %d " + "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d " + "dmaregstx %p dmaregsrx %p\n", name, "DMA64", osh, + di->hnddma.dmactrlflags, ntxd, nrxd, rxbufsize, + rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx)); /* make a private copy of our callers name */ strncpy(di->name, name, MAXNAMEL); @@ -450,15 +441,9 @@ struct hnddma_pub *dma_attach(struct osl_info *osh, char *name, si_t *sih, di->dataoffsetlow = 0; /* for pci bus, add offset */ if (sih->bustype == PCI_BUS) { - if ((sih->buscoretype == PCIE_CORE_ID) && DMA64_MODE(di)) { - /* pcie with DMA64 */ - di->ddoffsetlow = 0; - di->ddoffsethigh = SI_PCIE_DMA_H32; - } else { - /* pci(DMA32/DMA64) or pcie with DMA32 */ - di->ddoffsetlow = SI_PCI_DMA; - di->ddoffsethigh = 0; - } + /* pcie with DMA64 */ + di->ddoffsetlow = 0; + di->ddoffsethigh = SI_PCIE_DMA_H32; di->dataoffsetlow = di->ddoffsetlow; di->dataoffsethigh = di->ddoffsethigh; } @@ -478,14 +463,11 @@ struct hnddma_pub *dma_attach(struct osl_info *osh, char *name, si_t *sih, /* does the descriptors need to be aligned and if yes, on 4K/8K or not */ di->aligndesc_4k = _dma_descriptor_align(di); if (di->aligndesc_4k) { - if (DMA64_MODE(di)) { - di->dmadesc_align = D64RINGALIGN_BITS; - if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) { - /* for smaller dd table, HW relax the alignment requirement */ - di->dmadesc_align = D64RINGALIGN_BITS - 1; - } - } else - di->dmadesc_align = D32RINGALIGN_BITS; + di->dmadesc_align = D64RINGALIGN_BITS; + if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) { + /* for smaller dd table, HW relax alignment reqmnt */ + di->dmadesc_align = D64RINGALIGN_BITS - 1; + } } else di->dmadesc_align = 4; /* 16 byte alignment */ @@ -659,10 +641,7 @@ static bool _dma32_addrext(struct osl_info *osh, dma32regs_t *dma32regs) static bool _dma_alloc(dma_info_t *di, uint direction) { - if (DMA64_ENAB(di) && DMA64_MODE(di)) { - return dma64_alloc(di, direction); - } else - ASSERT(0); + return dma64_alloc(di, direction); } /* !! may be called with core in reset */ @@ -676,19 +655,16 @@ static void _dma_detach(dma_info_t *di) ASSERT(di->rxin == di->rxout); /* free dma descriptor rings */ - if (DMA64_ENAB(di) && DMA64_MODE(di)) { - if (di->txd64) - DMA_FREE_CONSISTENT(di->osh, - ((s8 *)di->txd64 - - di->txdalign), di->txdalloc, - (di->txdpaorig), &di->tx_dmah); - if (di->rxd64) - DMA_FREE_CONSISTENT(di->osh, - ((s8 *)di->rxd64 - - di->rxdalign), di->rxdalloc, - (di->rxdpaorig), &di->rx_dmah); - } else - ASSERT(0); + if (di->txd64) + DMA_FREE_CONSISTENT(di->osh, + ((s8 *)di->txd64 - + di->txdalign), di->txdalloc, + (di->txdpaorig), &di->tx_dmah); + if (di->rxd64) + DMA_FREE_CONSISTENT(di->osh, + ((s8 *)di->rxd64 - + di->rxdalign), di->rxdalloc, + (di->rxdpaorig), &di->rx_dmah); /* free packet pointer vectors */ if (di->txp) @@ -711,21 +687,19 @@ static void _dma_detach(dma_info_t *di) static bool _dma_descriptor_align(dma_info_t *di) { - if (DMA64_ENAB(di) && DMA64_MODE(di)) { - u32 addrl; - - /* Check to see if the descriptors need to be aligned on 4K/8K or not */ - if (di->d64txregs != NULL) { - W_REG(di->osh, &di->d64txregs->addrlow, 0xff0); - addrl = R_REG(di->osh, &di->d64txregs->addrlow); - if (addrl != 0) - return false; - } else if (di->d64rxregs != NULL) { - W_REG(di->osh, &di->d64rxregs->addrlow, 0xff0); - addrl = R_REG(di->osh, &di->d64rxregs->addrlow); - if (addrl != 0) - return false; - } + u32 addrl; + + /* Check to see if the descriptors need to be aligned on 4K/8K or not */ + if (di->d64txregs != NULL) { + W_REG(di->osh, &di->d64txregs->addrlow, 0xff0); + addrl = R_REG(di->osh, &di->d64txregs->addrlow); + if (addrl != 0) + return false; + } else if (di->d64rxregs != NULL) { + W_REG(di->osh, &di->d64rxregs->addrlow, 0xff0); + addrl = R_REG(di->osh, &di->d64rxregs->addrlow); + if (addrl != 0) + return false; } return true; } @@ -733,93 +707,84 @@ static bool _dma_descriptor_align(dma_info_t *di) /* return true if this dma engine supports DmaExtendedAddrChanges, otherwise false */ static bool _dma_isaddrext(dma_info_t *di) { - if (DMA64_ENAB(di) && DMA64_MODE(di)) { - /* DMA64 supports full 32- or 64-bit operation. AE is always valid */ + /* DMA64 supports full 32- or 64-bit operation. AE is always valid */ - /* not all tx or rx channel are available */ - if (di->d64txregs != NULL) { - if (!_dma64_addrext(di->osh, di->d64txregs)) { - DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have AE set\n", di->name)); - ASSERT(0); - } - return true; - } else if (di->d64rxregs != NULL) { - if (!_dma64_addrext(di->osh, di->d64rxregs)) { - DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have AE set\n", di->name)); - ASSERT(0); - } - return true; + /* not all tx or rx channel are available */ + if (di->d64txregs != NULL) { + if (!_dma64_addrext(di->osh, di->d64txregs)) { + DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have " + "AE set\n", di->name)); + ASSERT(0); } - return false; - } else - ASSERT(0); - + return true; + } else if (di->d64rxregs != NULL) { + if (!_dma64_addrext(di->osh, di->d64rxregs)) { + DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have " + "AE set\n", di->name)); + ASSERT(0); + } + return true; + } return false; } /* initialize descriptor table base address */ static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa) { - if (DMA64_ENAB(di) && DMA64_MODE(di)) { - if (!di->aligndesc_4k) { - if (direction == DMA_TX) - di->xmtptrbase = PHYSADDRLO(pa); - else - di->rcvptrbase = PHYSADDRLO(pa); - } + if (!di->aligndesc_4k) { + if (direction == DMA_TX) + di->xmtptrbase = PHYSADDRLO(pa); + else + di->rcvptrbase = PHYSADDRLO(pa); + } - if ((di->ddoffsetlow == 0) - || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) { - if (direction == DMA_TX) { - W_REG(di->osh, &di->d64txregs->addrlow, - (PHYSADDRLO(pa) + di->ddoffsetlow)); - W_REG(di->osh, &di->d64txregs->addrhigh, - (PHYSADDRHI(pa) + di->ddoffsethigh)); - } else { - W_REG(di->osh, &di->d64rxregs->addrlow, - (PHYSADDRLO(pa) + di->ddoffsetlow)); - W_REG(di->osh, &di->d64rxregs->addrhigh, - (PHYSADDRHI(pa) + di->ddoffsethigh)); - } + if ((di->ddoffsetlow == 0) + || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) { + if (direction == DMA_TX) { + W_REG(di->osh, &di->d64txregs->addrlow, + (PHYSADDRLO(pa) + di->ddoffsetlow)); + W_REG(di->osh, &di->d64txregs->addrhigh, + (PHYSADDRHI(pa) + di->ddoffsethigh)); } else { - /* DMA64 32bits address extension */ - u32 ae; - ASSERT(di->addrext); - ASSERT(PHYSADDRHI(pa) == 0); + W_REG(di->osh, &di->d64rxregs->addrlow, + (PHYSADDRLO(pa) + di->ddoffsetlow)); + W_REG(di->osh, &di->d64rxregs->addrhigh, + (PHYSADDRHI(pa) + di->ddoffsethigh)); + } + } else { + /* DMA64 32bits address extension */ + u32 ae; + ASSERT(di->addrext); + ASSERT(PHYSADDRHI(pa) == 0); - /* shift the high bit(s) from pa to ae */ - ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> - PCI32ADDR_HIGH_SHIFT; - PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH; - - if (direction == DMA_TX) { - W_REG(di->osh, &di->d64txregs->addrlow, - (PHYSADDRLO(pa) + di->ddoffsetlow)); - W_REG(di->osh, &di->d64txregs->addrhigh, - di->ddoffsethigh); - SET_REG(di->osh, &di->d64txregs->control, - D64_XC_AE, (ae << D64_XC_AE_SHIFT)); - } else { - W_REG(di->osh, &di->d64rxregs->addrlow, - (PHYSADDRLO(pa) + di->ddoffsetlow)); - W_REG(di->osh, &di->d64rxregs->addrhigh, - di->ddoffsethigh); - SET_REG(di->osh, &di->d64rxregs->control, - D64_RC_AE, (ae << D64_RC_AE_SHIFT)); - } + /* shift the high bit(s) from pa to ae */ + ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> + PCI32ADDR_HIGH_SHIFT; + PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH; + + if (direction == DMA_TX) { + W_REG(di->osh, &di->d64txregs->addrlow, + (PHYSADDRLO(pa) + di->ddoffsetlow)); + W_REG(di->osh, &di->d64txregs->addrhigh, + di->ddoffsethigh); + SET_REG(di->osh, &di->d64txregs->control, + D64_XC_AE, (ae << D64_XC_AE_SHIFT)); + } else { + W_REG(di->osh, &di->d64rxregs->addrlow, + (PHYSADDRLO(pa) + di->ddoffsetlow)); + W_REG(di->osh, &di->d64rxregs->addrhigh, + di->ddoffsethigh); + SET_REG(di->osh, &di->d64rxregs->control, + D64_RC_AE, (ae << D64_RC_AE_SHIFT)); } - } else - ASSERT(0); + } } static void _dma_fifoloopbackenable(dma_info_t *di) { DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name)); - if (DMA64_ENAB(di) && DMA64_MODE(di)) - OR_REG(di->osh, &di->d64txregs->control, D64_XC_LE); - else - ASSERT(0); + OR_REG(di->osh, &di->d64txregs->control, D64_XC_LE); } static void _dma_rxinit(dma_info_t *di) @@ -832,45 +797,40 @@ static void _dma_rxinit(dma_info_t *di) di->rxin = di->rxout = 0; /* clear rx descriptor ring */ - if (DMA64_ENAB(di) && DMA64_MODE(di)) { - memset((void *)di->rxd64, '\0', - (di->nrxd * sizeof(dma64dd_t))); + memset((void *)di->rxd64, '\0', + (di->nrxd * sizeof(dma64dd_t))); - /* DMA engine with out alignment requirement requires table to be inited - * before enabling the engine - */ - if (!di->aligndesc_4k) - _dma_ddtable_init(di, DMA_RX, di->rxdpa); + /* DMA engine with out alignment requirement requires table to be inited + * before enabling the engine + */ + if (!di->aligndesc_4k) + _dma_ddtable_init(di, DMA_RX, di->rxdpa); - _dma_rxenable(di); + _dma_rxenable(di); - if (di->aligndesc_4k) - _dma_ddtable_init(di, DMA_RX, di->rxdpa); - } else - ASSERT(0); + if (di->aligndesc_4k) + _dma_ddtable_init(di, DMA_RX, di->rxdpa); } static void _dma_rxenable(dma_info_t *di) { uint dmactrlflags = di->hnddma.dmactrlflags; + u32 control; DMA_TRACE(("%s: dma_rxenable\n", di->name)); - if (DMA64_ENAB(di) && DMA64_MODE(di)) { - u32 control = - (R_REG(di->osh, &di->d64rxregs->control) & D64_RC_AE) | - D64_RC_RE; + control = + (R_REG(di->osh, &di->d64rxregs->control) & D64_RC_AE) | + D64_RC_RE; - if ((dmactrlflags & DMA_CTRL_PEN) == 0) - control |= D64_RC_PD; + if ((dmactrlflags & DMA_CTRL_PEN) == 0) + control |= D64_RC_PD; - if (dmactrlflags & DMA_CTRL_ROC) - control |= D64_RC_OC; + if (dmactrlflags & DMA_CTRL_ROC) + control |= D64_RC_OC; - W_REG(di->osh, &di->d64rxregs->control, - ((di->rxoffset << D64_RC_RO_SHIFT) | control)); - } else - ASSERT(0); + W_REG(di->osh, &di->d64rxregs->control, + ((di->rxoffset << D64_RC_RO_SHIFT) | control)); } static void @@ -936,14 +896,11 @@ static void *BCMFASTPATH _dma_rx(dma_info_t *di) if (resid > 0) { uint cur; ASSERT(p == NULL); - cur = (DMA64_ENAB(di) && DMA64_MODE(di)) ? + cur = B2I(((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK, - dma64dd_t) : B2I(R_REG(di->osh, - &di->d32rxregs-> - status) & RS_CD_MASK, - dma32dd_t); + dma64dd_t); DMA_ERROR(("_dma_rx, rxin %d rxout %d, hw_curr %d\n", di->rxin, di->rxout, cur)); } @@ -1005,14 +962,10 @@ static bool BCMFASTPATH _dma_rxfill(dma_info_t *di) if (p == NULL) { DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name)); - if (i == 0) { - if (DMA64_ENAB(di) && DMA64_MODE(di)) { - if (dma64_rxidle(di)) { - DMA_ERROR(("%s: rxfill64: ring is empty !\n", di->name)); - ring_empty = true; - } - } else - ASSERT(0); + if (i == 0 && dma64_rxidle(di)) { + DMA_ERROR(("%s: rxfill64: ring is empty !\n", + di->name)); + ring_empty = true; } di->hnddma.rxnobuf++; break; @@ -1041,25 +994,19 @@ static bool BCMFASTPATH _dma_rxfill(dma_info_t *di) /* reset flags for each descriptor */ flags = 0; - if (DMA64_ENAB(di) && DMA64_MODE(di)) { - if (rxout == (di->nrxd - 1)) - flags = D64_CTRL1_EOT; + if (rxout == (di->nrxd - 1)) + flags = D64_CTRL1_EOT; - dma64_dd_upd(di, di->rxd64, pa, rxout, &flags, - di->rxbufsize); - } else - ASSERT(0); + dma64_dd_upd(di, di->rxd64, pa, rxout, &flags, + di->rxbufsize); rxout = NEXTRXD(rxout); } di->rxout = rxout; /* update the chip lastdscr pointer */ - if (DMA64_ENAB(di) && DMA64_MODE(di)) { - W_REG(di->osh, &di->d64rxregs->ptr, - di->rcvptrbase + I2B(rxout, dma64dd_t)); - } else - ASSERT(0); + W_REG(di->osh, &di->d64rxregs->ptr, + di->rcvptrbase + I2B(rxout, dma64dd_t)); return ring_empty; } @@ -1072,13 +1019,10 @@ static void *_dma_peeknexttxp(dma_info_t *di) if (di->ntxd == 0) return NULL; - if (DMA64_ENAB(di) && DMA64_MODE(di)) { - end = - B2I(((R_REG(di->osh, &di->d64txregs->status0) & - D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK, - dma64dd_t); - } else - ASSERT(0); + end = + B2I(((R_REG(di->osh, &di->d64txregs->status0) & + D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK, + dma64dd_t); for (i = di->txin; i != end; i = NEXTTXD(i)) if (di->txp[i]) @@ -1095,13 +1039,10 @@ static void *_dma_peeknextrxp(dma_info_t *di) if (di->nrxd == 0) return NULL; - if (DMA64_ENAB(di) && DMA64_MODE(di)) { - end = - B2I(((R_REG(di->osh, &di->d64rxregs->status0) & - D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK, - dma64dd_t); - } else - ASSERT(0); + end = + B2I(((R_REG(di->osh, &di->d64rxregs->status0) & + D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK, + dma64dd_t); for (i = di->rxin; i != end; i = NEXTRXD(i)) if (di->rxp[i]) @@ -1125,10 +1066,7 @@ static void *BCMFASTPATH _dma_getnextrxp(dma_info_t *di, bool forceall) if (di->nrxd == 0) return NULL; - if (DMA64_ENAB(di) && DMA64_MODE(di)) { - return dma64_getnextrxp(di, forceall); - } else - ASSERT(0); + return dma64_getnextrxp(di, forceall); } static void _dma_txblock(dma_info_t *di) @@ -1150,13 +1088,10 @@ static uint _dma_txpending(dma_info_t *di) { uint curr; - if (DMA64_ENAB(di) && DMA64_MODE(di)) { - curr = - B2I(((R_REG(di->osh, &di->d64txregs->status0) & - D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK, - dma64dd_t); - } else - ASSERT(0); + curr = + B2I(((R_REG(di->osh, &di->d64txregs->status0) & + D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK, + dma64dd_t); return NTXDACTIVE(curr, di->txout); } @@ -1169,10 +1104,7 @@ static uint _dma_txcommitted(dma_info_t *di) if (txin == di->txout) return 0; - if (DMA64_ENAB(di) && DMA64_MODE(di)) { - ptr = B2I(R_REG(di->osh, &di->d64txregs->ptr), dma64dd_t); - } else - ASSERT(0); + ptr = B2I(R_REG(di->osh, &di->d64txregs->ptr), dma64dd_t); return NTXDACTIVE(di->txin, ptr); } @@ -1208,22 +1140,19 @@ static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags) if (dmactrlflags & DMA_CTRL_PEN) { u32 control; - if (DMA64_ENAB(di) && DMA64_MODE(di)) { - control = R_REG(di->osh, &di->d64txregs->control); + control = R_REG(di->osh, &di->d64txregs->control); + W_REG(di->osh, &di->d64txregs->control, + control | D64_XC_PD); + if (R_REG(di->osh, &di->d64txregs->control) & D64_XC_PD) { + /* We *can* disable it so it is supported, + * restore control register + */ W_REG(di->osh, &di->d64txregs->control, - control | D64_XC_PD); - if (R_REG(di->osh, &di->d64txregs->control) & D64_XC_PD) { - /* We *can* disable it so it is supported, - * restore control register - */ - W_REG(di->osh, &di->d64txregs->control, - control); - } else { - /* Not supported, don't allow it to be enabled */ - dmactrlflags &= ~DMA_CTRL_PEN; - } - } else - ASSERT(0); + control); + } else { + /* Not supported, don't allow it to be enabled */ + dmactrlflags &= ~DMA_CTRL_PEN; + } } di->hnddma.dmactrlflags = dmactrlflags; @@ -2561,3 +2490,4 @@ uint dma_addrwidth(si_t *sih, void *dmaregs) /* Fallthru */ return DMADDRWIDTH_30; } + -- cgit v1.2.3 From 6b4ba667b7c4bb396e85e99fccbb4c92606f9209 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 1 Feb 2011 10:32:30 +0100 Subject: staging: brcm80211: removed 32 bit DMA functions Code cleanup. Removed unused functions. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/util/hnddma.c | 687 +------------------------------- 1 file changed, 2 insertions(+), 685 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index ae82e6bd0122..b5dd4cd22918 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -213,28 +213,6 @@ static void *dma_ringalloc(struct osl_info *osh, u32 boundary, uint size, u16 *alignbits, uint *alloced, dmaaddr_t *descpa, osldma_t **dmah); -/* Prototypes for 32-bit routines */ -static bool dma32_alloc(dma_info_t *di, uint direction); -static bool dma32_txreset(dma_info_t *di); -static bool dma32_rxreset(dma_info_t *di); -static bool dma32_txsuspendedidle(dma_info_t *di); -static int dma32_txfast(dma_info_t *di, struct sk_buff *p0, bool commit); -static void *dma32_getnexttxp(dma_info_t *di, txd_range_t range); -static void *dma32_getnextrxp(dma_info_t *di, bool forceall); -static void dma32_txrotate(dma_info_t *di); -static bool dma32_rxidle(dma_info_t *di); -static void dma32_txinit(dma_info_t *di); -static bool dma32_txenabled(dma_info_t *di); -static void dma32_txsuspend(dma_info_t *di); -static void dma32_txresume(dma_info_t *di); -static bool dma32_txsuspended(dma_info_t *di); -static void dma32_txreclaim(dma_info_t *di, txd_range_t range); -static bool dma32_txstopped(dma_info_t *di); -static bool dma32_rxstopped(dma_info_t *di); -static bool dma32_rxenabled(dma_info_t *di); - -static bool _dma32_addrext(struct osl_info *osh, dma32regs_t *dma32regs); - /* Prototypes for 64-bit routines */ static bool dma64_alloc(dma_info_t *di, uint direction); static bool dma64_txreset(dma_info_t *di); @@ -308,53 +286,6 @@ const di_fcn_t dma64proc = { 39 }; -static const di_fcn_t dma32proc = { - (di_detach_t) _dma_detach, - (di_txinit_t) dma32_txinit, - (di_txreset_t) dma32_txreset, - (di_txenabled_t) dma32_txenabled, - (di_txsuspend_t) dma32_txsuspend, - (di_txresume_t) dma32_txresume, - (di_txsuspended_t) dma32_txsuspended, - (di_txsuspendedidle_t) dma32_txsuspendedidle, - (di_txfast_t) dma32_txfast, - NULL, - NULL, - (di_txstopped_t) dma32_txstopped, - (di_txreclaim_t) dma32_txreclaim, - (di_getnexttxp_t) dma32_getnexttxp, - (di_peeknexttxp_t) _dma_peeknexttxp, - (di_txblock_t) _dma_txblock, - (di_txunblock_t) _dma_txunblock, - (di_txactive_t) _dma_txactive, - (di_txrotate_t) dma32_txrotate, - - (di_rxinit_t) _dma_rxinit, - (di_rxreset_t) dma32_rxreset, - (di_rxidle_t) dma32_rxidle, - (di_rxstopped_t) dma32_rxstopped, - (di_rxenable_t) _dma_rxenable, - (di_rxenabled_t) dma32_rxenabled, - (di_rx_t) _dma_rx, - (di_rxfill_t) _dma_rxfill, - (di_rxreclaim_t) _dma_rxreclaim, - (di_getnextrxp_t) _dma_getnextrxp, - (di_peeknextrxp_t) _dma_peeknextrxp, - (di_rxparam_get_t) _dma_rx_param_get, - - (di_fifoloopbackenable_t) _dma_fifoloopbackenable, - (di_getvar_t) _dma_getvar, - (di_counterreset_t) _dma_counterreset, - (di_ctrlflags_t) _dma_ctrlflags, - NULL, - NULL, - NULL, - (di_rxactive_t) _dma_rxactive, - (di_txpending_t) _dma_txpending, - (di_txcommitted_t) _dma_txcommitted, - 39 -}; - struct hnddma_pub *dma_attach(struct osl_info *osh, char *name, si_t *sih, void *dmaregstx, void *dmaregsrx, uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, @@ -543,32 +474,6 @@ struct hnddma_pub *dma_attach(struct osl_info *osh, char *name, si_t *sih, return NULL; } -/* init the tx or rx descriptor */ -static inline void -dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, dmaaddr_t pa, uint outidx, - u32 *flags, u32 bufcount) -{ - /* dma32 uses 32-bit control to fit both flags and bufcounter */ - *flags = *flags | (bufcount & CTRL_BC_MASK); - - if ((di->dataoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) { - W_SM(&ddring[outidx].addr, - BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow)); - W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags)); - } else { - /* address extension */ - u32 ae; - ASSERT(di->addrext); - ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; - PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH; - - *flags |= (ae << CTRL_AE_SHIFT); - W_SM(&ddring[outidx].addr, - BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow)); - W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags)); - } -} - /* Check for odd number of 1's */ static inline u32 parity32(u32 data) { @@ -629,16 +534,6 @@ dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, dmaaddr_t pa, uint outidx, } } -static bool _dma32_addrext(struct osl_info *osh, dma32regs_t *dma32regs) -{ - u32 w; - - OR_REG(osh, &dma32regs->control, XC_AE); - w = R_REG(osh, &dma32regs->control); - AND_REG(osh, &dma32regs->control, ~XC_AE); - return (w & XC_AE) == XC_AE; -} - static bool _dma_alloc(dma_info_t *di, uint direction) { return dma64_alloc(di, direction); @@ -1171,11 +1066,6 @@ static unsigned long _dma_getvar(dma_info_t *di, const char *name) return 0; } -void dma_txpioloopback(struct osl_info *osh, dma32regs_t *regs) -{ - OR_REG(osh, ®s->control, XC_LE); -} - static u8 dma_align_sizetobits(uint size) { @@ -1218,562 +1108,6 @@ static void *dma_ringalloc(struct osl_info *osh, u32 boundary, uint size, return va; } -/* 32-bit DMA functions */ - -static void dma32_txinit(dma_info_t *di) -{ - u32 control = XC_XE; - - DMA_TRACE(("%s: dma_txinit\n", di->name)); - - if (di->ntxd == 0) - return; - - di->txin = di->txout = 0; - di->hnddma.txavail = di->ntxd - 1; - - /* clear tx descriptor ring */ - memset((void *)di->txd32, '\0', (di->ntxd * sizeof(dma32dd_t))); - - if ((di->hnddma.dmactrlflags & DMA_CTRL_PEN) == 0) - control |= XC_PD; - W_REG(di->osh, &di->d32txregs->control, control); - _dma_ddtable_init(di, DMA_TX, di->txdpa); -} - -static bool dma32_txenabled(dma_info_t *di) -{ - u32 xc; - - /* If the chip is dead, it is not enabled :-) */ - xc = R_REG(di->osh, &di->d32txregs->control); - return (xc != 0xffffffff) && (xc & XC_XE); -} - -static void dma32_txsuspend(dma_info_t *di) -{ - DMA_TRACE(("%s: dma_txsuspend\n", di->name)); - - if (di->ntxd == 0) - return; - - OR_REG(di->osh, &di->d32txregs->control, XC_SE); -} - -static void dma32_txresume(dma_info_t *di) -{ - DMA_TRACE(("%s: dma_txresume\n", di->name)); - - if (di->ntxd == 0) - return; - - AND_REG(di->osh, &di->d32txregs->control, ~XC_SE); -} - -static bool dma32_txsuspended(dma_info_t *di) -{ - return (di->ntxd == 0) - || ((R_REG(di->osh, &di->d32txregs->control) & XC_SE) == XC_SE); -} - -static void dma32_txreclaim(dma_info_t *di, txd_range_t range) -{ - void *p; - - DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, - (range == HNDDMA_RANGE_ALL) ? "all" : - ((range == - HNDDMA_RANGE_TRANSMITTED) ? "transmitted" : - "transfered"))); - - if (di->txin == di->txout) - return; - - while ((p = dma32_getnexttxp(di, range))) - pkt_buf_free_skb(di->osh, p, true); -} - -static bool dma32_txstopped(dma_info_t *di) -{ - return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) == - XS_XS_STOPPED); -} - -static bool dma32_rxstopped(dma_info_t *di) -{ - return ((R_REG(di->osh, &di->d32rxregs->status) & RS_RS_MASK) == - RS_RS_STOPPED); -} - -static bool dma32_alloc(dma_info_t *di, uint direction) -{ - uint size; - uint ddlen; - void *va; - uint alloced; - u16 align; - u16 align_bits; - - ddlen = sizeof(dma32dd_t); - - size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); - - alloced = 0; - align_bits = di->dmadesc_align; - align = (1 << align_bits); - - if (direction == DMA_TX) { - va = dma_ringalloc(di->osh, D32RINGALIGN, size, &align_bits, - &alloced, &di->txdpaorig, &di->tx_dmah); - if (va == NULL) { - DMA_ERROR(("%s: dma_alloc: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name)); - return false; - } - - PHYSADDRHISET(di->txdpa, 0); - ASSERT(PHYSADDRHI(di->txdpaorig) == 0); - di->txd32 = (dma32dd_t *) roundup((unsigned long)va, align); - di->txdalign = - (uint) ((s8 *)di->txd32 - (s8 *) va); - - PHYSADDRLOSET(di->txdpa, - PHYSADDRLO(di->txdpaorig) + di->txdalign); - /* Make sure that alignment didn't overflow */ - ASSERT(PHYSADDRLO(di->txdpa) >= PHYSADDRLO(di->txdpaorig)); - - di->txdalloc = alloced; - ASSERT(IS_ALIGNED((unsigned long)di->txd32, align)); - } else { - va = dma_ringalloc(di->osh, D32RINGALIGN, size, &align_bits, - &alloced, &di->rxdpaorig, &di->rx_dmah); - if (va == NULL) { - DMA_ERROR(("%s: dma_alloc: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name)); - return false; - } - - PHYSADDRHISET(di->rxdpa, 0); - ASSERT(PHYSADDRHI(di->rxdpaorig) == 0); - di->rxd32 = (dma32dd_t *) roundup((unsigned long)va, align); - di->rxdalign = - (uint) ((s8 *)di->rxd32 - (s8 *) va); - - PHYSADDRLOSET(di->rxdpa, - PHYSADDRLO(di->rxdpaorig) + di->rxdalign); - /* Make sure that alignment didn't overflow */ - ASSERT(PHYSADDRLO(di->rxdpa) >= PHYSADDRLO(di->rxdpaorig)); - di->rxdalloc = alloced; - ASSERT(IS_ALIGNED((unsigned long)di->rxd32, align)); - } - - return true; -} - -static bool dma32_txreset(dma_info_t *di) -{ - u32 status; - - if (di->ntxd == 0) - return true; - - /* suspend tx DMA first */ - W_REG(di->osh, &di->d32txregs->control, XC_SE); - SPINWAIT(((status = - (R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK)) - != XS_XS_DISABLED) && (status != XS_XS_IDLE) - && (status != XS_XS_STOPPED), (10000)); - - W_REG(di->osh, &di->d32txregs->control, 0); - SPINWAIT(((status = (R_REG(di->osh, - &di->d32txregs->status) & XS_XS_MASK)) != - XS_XS_DISABLED), 10000); - - /* wait for the last transaction to complete */ - udelay(300); - - return status == XS_XS_DISABLED; -} - -static bool dma32_rxidle(dma_info_t *di) -{ - DMA_TRACE(("%s: dma_rxidle\n", di->name)); - - if (di->nrxd == 0) - return true; - - return ((R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK) == - R_REG(di->osh, &di->d32rxregs->ptr)); -} - -static bool dma32_rxreset(dma_info_t *di) -{ - u32 status; - - if (di->nrxd == 0) - return true; - - W_REG(di->osh, &di->d32rxregs->control, 0); - SPINWAIT(((status = (R_REG(di->osh, - &di->d32rxregs->status) & RS_RS_MASK)) != - RS_RS_DISABLED), 10000); - - return status == RS_RS_DISABLED; -} - -static bool dma32_rxenabled(dma_info_t *di) -{ - u32 rc; - - rc = R_REG(di->osh, &di->d32rxregs->control); - return (rc != 0xffffffff) && (rc & RC_RE); -} - -static bool dma32_txsuspendedidle(dma_info_t *di) -{ - if (di->ntxd == 0) - return true; - - if (!(R_REG(di->osh, &di->d32txregs->control) & XC_SE)) - return 0; - - if ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE) - return 0; - - udelay(2); - return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) == - XS_XS_IDLE); -} - -/* !! tx entry routine - * supports full 32bit dma engine buffer addressing so - * dma buffers can cross 4 Kbyte page boundaries. - * - * WARNING: call must check the return value for error. - * the error(toss frames) could be fatal and cause many subsequent hard to debug problems - */ -static int dma32_txfast(dma_info_t *di, struct sk_buff *p0, bool commit) -{ - struct sk_buff *p, *next; - unsigned char *data; - uint len; - u16 txout; - u32 flags = 0; - dmaaddr_t pa; - - DMA_TRACE(("%s: dma_txfast\n", di->name)); - - txout = di->txout; - - /* - * Walk the chain of packet buffers - * allocating and initializing transmit descriptor entries. - */ - for (p = p0; p; p = next) { - uint nsegs, j; - hnddma_seg_map_t *map; - - data = p->data; - len = p->len; -#ifdef BCM_DMAPAD - len += PKTDMAPAD(di->osh, p); -#endif - next = p->next; - - /* return nonzero if out of tx descriptors */ - if (NEXTTXD(txout) == di->txin) - goto outoftxd; - - if (len == 0) - continue; - - if (DMASGLIST_ENAB) - memset(&di->txp_dmah[txout], 0, - sizeof(hnddma_seg_map_t)); - - /* get physical address of buffer start */ - pa = DMA_MAP(di->osh, data, len, DMA_TX, p, - &di->txp_dmah[txout]); - - if (DMASGLIST_ENAB) { - map = &di->txp_dmah[txout]; - - /* See if all the segments can be accounted for */ - if (map->nsegs > - (uint) (di->ntxd - NTXDACTIVE(di->txin, di->txout) - - 1)) - goto outoftxd; - - nsegs = map->nsegs; - } else - nsegs = 1; - - for (j = 1; j <= nsegs; j++) { - flags = 0; - if (p == p0 && j == 1) - flags |= CTRL_SOF; - - /* With a DMA segment list, Descriptor table is filled - * using the segment list instead of looping over - * buffers in multi-chain DMA. Therefore, EOF for SGLIST is when - * end of segment list is reached. - */ - if ((!DMASGLIST_ENAB && next == NULL) || - (DMASGLIST_ENAB && j == nsegs)) - flags |= (CTRL_IOC | CTRL_EOF); - if (txout == (di->ntxd - 1)) - flags |= CTRL_EOT; - - if (DMASGLIST_ENAB) { - len = map->segs[j - 1].length; - pa = map->segs[j - 1].addr; - } - ASSERT(PHYSADDRHI(pa) == 0); - - dma32_dd_upd(di, di->txd32, pa, txout, &flags, len); - ASSERT(di->txp[txout] == NULL); - - txout = NEXTTXD(txout); - } - - /* See above. No need to loop over individual buffers */ - if (DMASGLIST_ENAB) - break; - } - - /* if last txd eof not set, fix it */ - if (!(flags & CTRL_EOF)) - W_SM(&di->txd32[PREVTXD(txout)].ctrl, - BUS_SWAP32(flags | CTRL_IOC | CTRL_EOF)); - - /* save the packet */ - di->txp[PREVTXD(txout)] = p0; - - /* bump the tx descriptor index */ - di->txout = txout; - - /* kick the chip */ - if (commit) - W_REG(di->osh, &di->d32txregs->ptr, I2B(txout, dma32dd_t)); - - /* tx flow control */ - di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; - - return 0; - - outoftxd: - DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); - pkt_buf_free_skb(di->osh, p0, true); - di->hnddma.txavail = 0; - di->hnddma.txnobuf++; - return -1; -} - -/* - * Reclaim next completed txd (txds if using chained buffers) in the range - * specified and return associated packet. - * If range is HNDDMA_RANGE_TRANSMITTED, reclaim descriptors that have be - * transmitted as noted by the hardware "CurrDescr" pointer. - * If range is HNDDMA_RANGE_TRANSFERED, reclaim descriptors that have be - * transfered by the DMA as noted by the hardware "ActiveDescr" pointer. - * If range is HNDDMA_RANGE_ALL, reclaim all txd(s) posted to the ring and - * return associated packet regardless of the value of hardware pointers. - */ -static void *dma32_getnexttxp(dma_info_t *di, txd_range_t range) -{ - u16 start, end, i; - u16 active_desc; - void *txp; - - DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, - (range == HNDDMA_RANGE_ALL) ? "all" : - ((range == - HNDDMA_RANGE_TRANSMITTED) ? "transmitted" : - "transfered"))); - - if (di->ntxd == 0) - return NULL; - - txp = NULL; - - start = di->txin; - if (range == HNDDMA_RANGE_ALL) - end = di->txout; - else { - dma32regs_t *dregs = di->d32txregs; - - end = - (u16) B2I(R_REG(di->osh, &dregs->status) & XS_CD_MASK, - dma32dd_t); - - if (range == HNDDMA_RANGE_TRANSFERED) { - active_desc = - (u16) ((R_REG(di->osh, &dregs->status) & - XS_AD_MASK) >> XS_AD_SHIFT); - active_desc = (u16) B2I(active_desc, dma32dd_t); - if (end != active_desc) - end = PREVTXD(active_desc); - } - } - - if ((start == 0) && (end > di->txout)) - goto bogus; - - for (i = start; i != end && !txp; i = NEXTTXD(i)) { - dmaaddr_t pa; - hnddma_seg_map_t *map = NULL; - uint size, j, nsegs; - - PHYSADDRLOSET(pa, - (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - - di->dataoffsetlow)); - PHYSADDRHISET(pa, 0); - - if (DMASGLIST_ENAB) { - map = &di->txp_dmah[i]; - size = map->origsize; - nsegs = map->nsegs; - } else { - size = - (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & - CTRL_BC_MASK); - nsegs = 1; - } - - for (j = nsegs; j > 0; j--) { - W_SM(&di->txd32[i].addr, 0xdeadbeef); - - txp = di->txp[i]; - di->txp[i] = NULL; - if (j > 1) - i = NEXTTXD(i); - } - - DMA_UNMAP(di->osh, pa, size, DMA_TX, txp, map); - } - - di->txin = i; - - /* tx flow control */ - di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; - - return txp; - - bogus: - DMA_NONE(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", start, end, di->txout, forceall)); - return NULL; -} - -static void *dma32_getnextrxp(dma_info_t *di, bool forceall) -{ - uint i, curr; - void *rxp; - dmaaddr_t pa; - /* if forcing, dma engine must be disabled */ - ASSERT(!forceall || !dma32_rxenabled(di)); - - i = di->rxin; - - /* return if no packets posted */ - if (i == di->rxout) - return NULL; - - curr = - B2I(R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK, dma32dd_t); - - /* ignore curr if forceall */ - if (!forceall && (i == curr)) - return NULL; - - /* get the packet pointer that corresponds to the rx descriptor */ - rxp = di->rxp[i]; - ASSERT(rxp); - di->rxp[i] = NULL; - - PHYSADDRLOSET(pa, - (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - - di->dataoffsetlow)); - PHYSADDRHISET(pa, 0); - - /* clear this packet from the descriptor ring */ - DMA_UNMAP(di->osh, pa, di->rxbufsize, DMA_RX, rxp, &di->rxp_dmah[i]); - - W_SM(&di->rxd32[i].addr, 0xdeadbeef); - - di->rxin = NEXTRXD(i); - - return rxp; -} - -/* - * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). - */ -static void dma32_txrotate(dma_info_t *di) -{ - u16 ad; - uint nactive; - uint rot; - u16 old, new; - u32 w; - u16 first, last; - - ASSERT(dma32_txsuspendedidle(di)); - - nactive = _dma_txactive(di); - ad = (u16) (B2I - (((R_REG(di->osh, &di->d32txregs->status) & XS_AD_MASK) - >> XS_AD_SHIFT), dma32dd_t)); - rot = TXD(ad - di->txin); - - ASSERT(rot < di->ntxd); - - /* full-ring case is a lot harder - don't worry about this */ - if (rot >= (di->ntxd - nactive)) { - DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); - return; - } - - first = di->txin; - last = PREVTXD(di->txout); - - /* move entries starting at last and moving backwards to first */ - for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { - new = TXD(old + rot); - - /* - * Move the tx dma descriptor. - * EOT is set only in the last entry in the ring. - */ - w = BUS_SWAP32(R_SM(&di->txd32[old].ctrl)) & ~CTRL_EOT; - if (new == (di->ntxd - 1)) - w |= CTRL_EOT; - W_SM(&di->txd32[new].ctrl, BUS_SWAP32(w)); - W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr)); - - /* zap the old tx dma descriptor address field */ - W_SM(&di->txd32[old].addr, BUS_SWAP32(0xdeadbeef)); - - /* move the corresponding txp[] entry */ - ASSERT(di->txp[new] == NULL); - di->txp[new] = di->txp[old]; - - /* Move the segment map as well */ - if (DMASGLIST_ENAB) { - bcopy(&di->txp_dmah[old], &di->txp_dmah[new], - sizeof(hnddma_seg_map_t)); - memset(&di->txp_dmah[old], 0, sizeof(hnddma_seg_map_t)); - } - - di->txp[old] = NULL; - } - - /* update txin and txout */ - di->txin = ad; - di->txout = TXD(di->txout + rot); - di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; - - /* kick the chip */ - W_REG(di->osh, &di->d32txregs->ptr, I2B(di->txout, dma32dd_t)); -} - /* 64-bit DMA functions */ static void dma64_txinit(dma_info_t *di) @@ -2455,7 +1789,6 @@ static void dma64_txrotate(dma_info_t *di) uint dma_addrwidth(si_t *sih, void *dmaregs) { - dma32regs_t *dma32regs; struct osl_info *osh; osh = si_osh(sih); @@ -2470,24 +1803,8 @@ uint dma_addrwidth(si_t *sih, void *dmaregs) ((sih->bustype == PCI_BUS) && (sih->buscoretype == PCIE_CORE_ID))) return DMADDRWIDTH_64; - - /* DMA64 is always 32-bit capable, AE is always true */ - ASSERT(_dma64_addrext(osh, (dma64regs_t *) dmaregs)); - - return DMADDRWIDTH_32; } - - /* Start checking for 32-bit / 30-bit addressing */ - dma32regs = (dma32regs_t *) dmaregs; - - /* For System Backplane, PCIE bus or addrext feature, 32-bits ok */ - if ((sih->bustype == SI_BUS) || - ((sih->bustype == PCI_BUS) - && sih->buscoretype == PCIE_CORE_ID) - || (_dma32_addrext(osh, dma32regs))) - return DMADDRWIDTH_32; - - /* Fallthru */ - return DMADDRWIDTH_30; + ASSERT(0); /* DMA hardware not supported by this driver*/ + return DMADDRWIDTH_64; } -- cgit v1.2.3 From 360ac683f78bd52a430d6937380449dc401f9539 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 1 Feb 2011 10:32:31 +0100 Subject: staging: brcm80211: removed references to 32 bit DMA registers Code cleanup. Removed unused references. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/d11.h | 7 ------- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 7 ++----- drivers/staging/brcm80211/include/hnddma.h | 3 --- drivers/staging/brcm80211/util/hnddma.c | 11 ----------- 4 files changed, 2 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/d11.h b/drivers/staging/brcm80211/brcmsmac/d11.h index 50883af62496..841e9402ed2b 100644 --- a/drivers/staging/brcm80211/brcmsmac/d11.h +++ b/drivers/staging/brcm80211/brcmsmac/d11.h @@ -76,12 +76,6 @@ typedef volatile union { pio4regp_t b4; /* >= corerev 8 */ } u_pioreg_t; -/* dma/pio corerev < 11 */ -typedef volatile struct { - dma32regp_t dmaregs[8]; /* 0x200 - 0x2fc */ - u_pioreg_t pioregs[8]; /* 0x300 */ -} fifo32_t; - /* dma/pio corerev >= 11 */ typedef volatile struct { dma64regs_t dmaxmt; /* dma tx */ @@ -168,7 +162,6 @@ typedef volatile struct _d11regs { /* 0x200-0x37F dma/pio registers */ volatile union { - fifo32_t f32regs; /* tx fifos 6-7 and rx fifos 1-3 (corerev < 5) */ fifo64_t f64regs[6]; /* on corerev >= 11 */ } fifo; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 631ee733b9f5..8d9aca5651f8 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -86,13 +86,10 @@ #endif /* BMAC_DUP_TO_REMOVE */ -#define DMAREG(wlc_hw, direction, fifonum) (D11REV_LT(wlc_hw->corerev, 11) ? \ - ((direction == DMA_TX) ? \ - (void *)&(wlc_hw->regs->fifo.f32regs.dmaregs[fifonum].xmt) : \ - (void *)&(wlc_hw->regs->fifo.f32regs.dmaregs[fifonum].rcv)) : \ +#define DMAREG(wlc_hw, direction, fifonum) \ ((direction == DMA_TX) ? \ (void *)&(wlc_hw->regs->fifo.f64regs[fifonum].dmaxmt) : \ - (void *)&(wlc_hw->regs->fifo.f64regs[fifonum].dmarcv))) + (void *)&(wlc_hw->regs->fifo.f64regs[fifonum].dmarcv)) /* * The following table lists the buffer memory allocated to xmt fifos in HW. diff --git a/drivers/staging/brcm80211/include/hnddma.h b/drivers/staging/brcm80211/include/hnddma.h index 002c118fdc9e..17fa166f3968 100644 --- a/drivers/staging/brcm80211/include/hnddma.h +++ b/drivers/staging/brcm80211/include/hnddma.h @@ -199,7 +199,4 @@ extern const di_fcn_t dma64proc; */ extern uint dma_addrwidth(si_t *sih, void *dmaregs); -/* pio helpers */ -extern void dma_txpioloopback(struct osl_info *osh, dma32regs_t *); - #endif /* _hnddma_h_ */ diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index b5dd4cd22918..2fc916624807 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -56,11 +56,6 @@ #define DMA_NONE(args) -#define d32txregs dregs.d32_u.txregs_32 -#define d32rxregs dregs.d32_u.rxregs_32 -#define txd32 dregs.d32_u.txd_32 -#define rxd32 dregs.d32_u.rxd_32 - #define d64txregs dregs.d64_u.txregs_64 #define d64rxregs dregs.d64_u.rxregs_64 #define txd64 dregs.d64_u.txd_64 @@ -89,12 +84,6 @@ typedef struct dma_info { bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ union { - struct { - dma32regs_t *txregs_32; /* 32-bit dma tx engine registers */ - dma32regs_t *rxregs_32; /* 32-bit dma rx engine registers */ - dma32dd_t *txd_32; /* pointer to dma32 tx descriptor ring */ - dma32dd_t *rxd_32; /* pointer to dma32 rx descriptor ring */ - } d32_u; struct { dma64regs_t *txregs_64; /* 64-bit dma tx engine registers */ dma64regs_t *rxregs_64; /* 64-bit dma rx engine registers */ -- cgit v1.2.3 From 90441bebbaa70d8ba114861319d92eaaa65cb425 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Tue, 1 Feb 2011 21:07:28 -0800 Subject: staging: brcm80211: sbsdio.h: change a typo comamnd to command The below patch fixes a typo comamnd to command. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/sbsdio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/sbsdio.h b/drivers/staging/brcm80211/include/sbsdio.h index 6afdbbe67e19..c7facd3795a0 100644 --- a/drivers/staging/brcm80211/include/sbsdio.h +++ b/drivers/staging/brcm80211/include/sbsdio.h @@ -144,7 +144,7 @@ */ #define SBSDIO_BYTEMODE_DATALEN_MAX 64 /* sdio byte mode: maximum length of one - * data comamnd + * data command */ #define SBSDIO_CORE_ADDR_MASK 0x1FFFF /* sdio core function one address mask */ -- cgit v1.2.3 From 4b906e58a1f0a29ce1da4ed832cc6f17e5889772 Mon Sep 17 00:00:00 2001 From: Sutharsan Ramamoorthy Date: Tue, 1 Feb 2011 22:45:04 -0800 Subject: Staging: Westbridge: added ioremap_nocache instead of phys_to_virt This patch removes phys_to_virt() and adds ioremap_nocache() for memory mapping the GPMC registers. Signed-off-by: Sutharsan Ramamoorthy Signed-off-by: Greg Kroah-Hartman --- .../westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c b/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c index ad0c61db9937..ea9b733c3926 100644 --- a/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c +++ b/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c @@ -347,11 +347,8 @@ static int cy_as_hal_gpmc_init(void) u32 tmp32; int err; struct gpmc_timings timings; - /* - * get GPMC i/o registers base(already been i/o mapped - * in kernel, no need for separate i/o remap) - */ - gpmc_base = phys_to_virt(OMAP34XX_GPMC_BASE); + + gpmc_base = (u32)ioremap_nocache(OMAP34XX_GPMC_BASE, BLKSZ_4K); DBGPRN(KERN_INFO "kernel has gpmc_base=%x , val@ the base=%x", gpmc_base, __raw_readl(gpmc_base) ); -- cgit v1.2.3 From 37af07d19a53924a70ae42faebf968c04a631c8c Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Wed, 2 Feb 2011 21:29:31 +0300 Subject: staging: rts_pstor: potential NULL dereference pci_get_bus_and_slot() may return NULL, but the caller checks wrong variable. Signed-off-by: Vasiliy Kulikov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts_pstor/rtsx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rts_pstor/rtsx.c b/drivers/staging/rts_pstor/rtsx.c index 9864b1a47116..2b1837999d7d 100644 --- a/drivers/staging/rts_pstor/rtsx.c +++ b/drivers/staging/rts_pstor/rtsx.c @@ -334,7 +334,7 @@ int rtsx_read_pci_cfg_byte(u8 bus, u8 dev, u8 func, u8 offset, u8 *val) u8 devfn = (dev << 3) | func; pdev = pci_get_bus_and_slot(bus, devfn); - if (!dev) + if (!pdev) return -1; pci_read_config_byte(pdev, offset, &data); -- cgit v1.2.3 From 7d3864d1f6a496108c377f5580a2125c2f8d9014 Mon Sep 17 00:00:00 2001 From: Bas van den Berg Date: Thu, 3 Feb 2011 21:37:16 +0100 Subject: Staging: wlan-ng: fixed packed checkpatch warnings Signed-off-by: Bas van den Berg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/hfa384x.h | 156 ++++++++++++++--------------- drivers/staging/wlan-ng/p80211conv.h | 6 +- drivers/staging/wlan-ng/p80211hdr.h | 6 +- drivers/staging/wlan-ng/p80211ioctl.h | 2 +- drivers/staging/wlan-ng/p80211metastruct.h | 30 +++--- drivers/staging/wlan-ng/p80211mgmt.h | 18 ++-- drivers/staging/wlan-ng/p80211msg.h | 2 +- drivers/staging/wlan-ng/p80211types.h | 34 +++---- 8 files changed, 127 insertions(+), 127 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h index fa94a7cc86cf..5631ad0a7237 100644 --- a/drivers/staging/wlan-ng/hfa384x.h +++ b/drivers/staging/wlan-ng/hfa384x.h @@ -352,12 +352,12 @@ PD Record codes typedef struct hfa384x_bytestr { u16 len; u8 data[0]; -} __attribute__ ((packed)) hfa384x_bytestr_t; +} __packed hfa384x_bytestr_t; typedef struct hfa384x_bytestr32 { u16 len; u8 data[32]; -} __attribute__ ((packed)) hfa384x_bytestr32_t; +} __packed hfa384x_bytestr32_t; /*-------------------------------------------------------------------- Configuration Record Structures: @@ -370,7 +370,7 @@ typedef struct hfa384x_compident { u16 variant; u16 major; u16 minor; -} __attribute__ ((packed)) hfa384x_compident_t; +} __packed hfa384x_compident_t; typedef struct hfa384x_caplevel { u16 role; @@ -378,7 +378,7 @@ typedef struct hfa384x_caplevel { u16 variant; u16 bottom; u16 top; -} __attribute__ ((packed)) hfa384x_caplevel_t; +} __packed hfa384x_caplevel_t; /*-- Configuration Record: cnfAuthentication --*/ #define HFA384x_CNFAUTHENTICATION_OPENSYSTEM 0x0001 @@ -397,26 +397,26 @@ typedef struct hfa384x_HostScanRequest_data { u16 channelList; u16 txRate; hfa384x_bytestr32_t ssid; -} __attribute__ ((packed)) hfa384x_HostScanRequest_data_t; +} __packed hfa384x_HostScanRequest_data_t; /*-- Configuration Record: JoinRequest (data portion only) --*/ typedef struct hfa384x_JoinRequest_data { u8 bssid[WLAN_BSSID_LEN]; u16 channel; -} __attribute__ ((packed)) hfa384x_JoinRequest_data_t; +} __packed hfa384x_JoinRequest_data_t; /*-- Configuration Record: authenticateStation (data portion only) --*/ typedef struct hfa384x_authenticateStation_data { u8 address[ETH_ALEN]; u16 status; u16 algorithm; -} __attribute__ ((packed)) hfa384x_authenticateStation_data_t; +} __packed hfa384x_authenticateStation_data_t; /*-- Configuration Record: WPAData (data portion only) --*/ typedef struct hfa384x_WPAData { u16 datalen; u8 data[0]; /* max 80 */ -} __attribute__ ((packed)) hfa384x_WPAData_t; +} __packed hfa384x_WPAData_t; /*-------------------------------------------------------------------- Information Record Structures: NIC Information @@ -428,7 +428,7 @@ typedef struct hfa384x_downloadbuffer { u16 page; u16 offset; u16 len; -} __attribute__ ((packed)) hfa384x_downloadbuffer_t; +} __packed hfa384x_downloadbuffer_t; /*-------------------------------------------------------------------- Information Record Structures: NIC Information @@ -441,14 +441,14 @@ typedef struct hfa384x_commsquality { u16 CQ_currBSS; u16 ASL_currBSS; u16 ANL_currFC; -} __attribute__ ((packed)) hfa384x_commsquality_t; +} __packed hfa384x_commsquality_t; /*-- Information Record: dmbcommsquality --*/ typedef struct hfa384x_dbmcommsquality { u16 CQdbm_currBSS; u16 ASLdbm_currBSS; u16 ANLdbm_currFC; -} __attribute__ ((packed)) hfa384x_dbmcommsquality_t; +} __packed hfa384x_dbmcommsquality_t; /*-------------------------------------------------------------------- FRAME STRUCTURES: Communication Frames @@ -481,7 +481,7 @@ typedef struct hfa384x_tx_frame { u8 dest_addr[6]; u8 src_addr[6]; u16 data_length; /* big endian format */ -} __attribute__ ((packed)) hfa384x_tx_frame_t; +} __packed hfa384x_tx_frame_t; /*-------------------------------------------------------------------- Communication Frames: Field Masks for Transmit Frames --------------------------------------------------------------------*/ @@ -543,7 +543,7 @@ typedef struct hfa384x_rx_frame { u8 dest_addr[6]; u8 src_addr[6]; u16 data_length; /* IEEE? (big endian) format */ -} __attribute__ ((packed)) hfa384x_rx_frame_t; +} __packed hfa384x_rx_frame_t; /*-------------------------------------------------------------------- Communication Frames: Field Masks for Receive Frames --------------------------------------------------------------------*/ @@ -607,7 +607,7 @@ typedef struct hfa384x_CommTallies16 { u16 rxdiscardswepundecr; u16 rxmsginmsgfrag; u16 rxmsginbadmsgfrag; -} __attribute__ ((packed)) hfa384x_CommTallies16_t; +} __packed hfa384x_CommTallies16_t; typedef struct hfa384x_CommTallies32 { u32 txunicastframes; @@ -631,7 +631,7 @@ typedef struct hfa384x_CommTallies32 { u32 rxdiscardswepundecr; u32 rxmsginmsgfrag; u32 rxmsginbadmsgfrag; -} __attribute__ ((packed)) hfa384x_CommTallies32_t; +} __packed hfa384x_CommTallies32_t; /*-- Inquiry Frame, Diagnose: Scan Results & Subfields--*/ typedef struct hfa384x_ScanResultSub { @@ -644,13 +644,13 @@ typedef struct hfa384x_ScanResultSub { hfa384x_bytestr32_t ssid; u8 supprates[10]; /* 802.11 info element */ u16 proberesp_rate; -} __attribute__ ((packed)) hfa384x_ScanResultSub_t; +} __packed hfa384x_ScanResultSub_t; typedef struct hfa384x_ScanResult { u16 rsvd; u16 scanreason; hfa384x_ScanResultSub_t result[HFA384x_SCANRESULT_MAX]; -} __attribute__ ((packed)) hfa384x_ScanResult_t; +} __packed hfa384x_ScanResult_t; /*-- Inquiry Frame, Diagnose: ChInfo Results & Subfields--*/ typedef struct hfa384x_ChInfoResultSub { @@ -658,7 +658,7 @@ typedef struct hfa384x_ChInfoResultSub { u16 anl; u16 pnl; u16 active; -} __attribute__ ((packed)) hfa384x_ChInfoResultSub_t; +} __packed hfa384x_ChInfoResultSub_t; #define HFA384x_CHINFORESULT_BSSACTIVE BIT(0) #define HFA384x_CHINFORESULT_PCFACTIVE BIT(1) @@ -666,7 +666,7 @@ typedef struct hfa384x_ChInfoResultSub { typedef struct hfa384x_ChInfoResult { u16 scanchannels; hfa384x_ChInfoResultSub_t result[HFA384x_CHINFORESULT_MAX]; -} __attribute__ ((packed)) hfa384x_ChInfoResult_t; +} __packed hfa384x_ChInfoResult_t; /*-- Inquiry Frame, Diagnose: Host Scan Results & Subfields--*/ typedef struct hfa384x_HScanResultSub { @@ -680,13 +680,13 @@ typedef struct hfa384x_HScanResultSub { u8 supprates[10]; /* 802.11 info element */ u16 proberesp_rate; u16 atim; -} __attribute__ ((packed)) hfa384x_HScanResultSub_t; +} __packed hfa384x_HScanResultSub_t; typedef struct hfa384x_HScanResult { u16 nresult; u16 rsvd; hfa384x_HScanResultSub_t result[HFA384x_HSCANRESULT_MAX]; -} __attribute__ ((packed)) hfa384x_HScanResult_t; +} __packed hfa384x_HScanResult_t; /*-- Unsolicited Frame, MAC Mgmt: LinkStatus --*/ @@ -700,7 +700,7 @@ typedef struct hfa384x_HScanResult { typedef struct hfa384x_LinkStatus { u16 linkstatus; -} __attribute__ ((packed)) hfa384x_LinkStatus_t; +} __packed hfa384x_LinkStatus_t; /*-- Unsolicited Frame, MAC Mgmt: AssociationStatus (--*/ @@ -715,25 +715,25 @@ typedef struct hfa384x_AssocStatus { u8 old_ap_addr[ETH_ALEN]; u16 reason; u16 reserved; -} __attribute__ ((packed)) hfa384x_AssocStatus_t; +} __packed hfa384x_AssocStatus_t; /*-- Unsolicited Frame, MAC Mgmt: AuthRequest (AP Only) --*/ typedef struct hfa384x_AuthRequest { u8 sta_addr[ETH_ALEN]; u16 algorithm; -} __attribute__ ((packed)) hfa384x_AuthReq_t; +} __packed hfa384x_AuthReq_t; /*-- Unsolicited Frame, MAC Mgmt: PSUserCount (AP Only) --*/ typedef struct hfa384x_PSUserCount { u16 usercnt; -} __attribute__ ((packed)) hfa384x_PSUserCount_t; +} __packed hfa384x_PSUserCount_t; typedef struct hfa384x_KeyIDChanged { u8 sta_addr[ETH_ALEN]; u16 keyid; -} __attribute__ ((packed)) hfa384x_KeyIDChanged_t; +} __packed hfa384x_KeyIDChanged_t; /*-- Collection of all Inf frames ---------------*/ typedef union hfa384x_infodata { @@ -747,13 +747,13 @@ typedef union hfa384x_infodata { hfa384x_AuthReq_t authreq; hfa384x_PSUserCount_t psusercnt; hfa384x_KeyIDChanged_t keyidchanged; -} __attribute__ ((packed)) hfa384x_infodata_t; +} __packed hfa384x_infodata_t; typedef struct hfa384x_InfFrame { u16 framelen; u16 infotype; hfa384x_infodata_t info; -} __attribute__ ((packed)) hfa384x_InfFrame_t; +} __packed hfa384x_InfFrame_t; /*-------------------------------------------------------------------- USB Packet structures and constants. @@ -785,7 +785,7 @@ USB Packet structures and constants. typedef struct hfa384x_usb_txfrm { hfa384x_tx_frame_t desc; u8 data[WLAN_DATA_MAXLEN]; -} __attribute__ ((packed)) hfa384x_usb_txfrm_t; +} __packed hfa384x_usb_txfrm_t; typedef struct hfa384x_usb_cmdreq { u16 type; @@ -794,21 +794,21 @@ typedef struct hfa384x_usb_cmdreq { u16 parm1; u16 parm2; u8 pad[54]; -} __attribute__ ((packed)) hfa384x_usb_cmdreq_t; +} __packed hfa384x_usb_cmdreq_t; typedef struct hfa384x_usb_wridreq { u16 type; u16 frmlen; u16 rid; u8 data[HFA384x_RIDDATA_MAXLEN]; -} __attribute__ ((packed)) hfa384x_usb_wridreq_t; +} __packed hfa384x_usb_wridreq_t; typedef struct hfa384x_usb_rridreq { u16 type; u16 frmlen; u16 rid; u8 pad[58]; -} __attribute__ ((packed)) hfa384x_usb_rridreq_t; +} __packed hfa384x_usb_rridreq_t; typedef struct hfa384x_usb_wmemreq { u16 type; @@ -816,7 +816,7 @@ typedef struct hfa384x_usb_wmemreq { u16 offset; u16 page; u8 data[HFA384x_USB_RWMEM_MAXLEN]; -} __attribute__ ((packed)) hfa384x_usb_wmemreq_t; +} __packed hfa384x_usb_wmemreq_t; typedef struct hfa384x_usb_rmemreq { u16 type; @@ -824,7 +824,7 @@ typedef struct hfa384x_usb_rmemreq { u16 offset; u16 page; u8 pad[56]; -} __attribute__ ((packed)) hfa384x_usb_rmemreq_t; +} __packed hfa384x_usb_rmemreq_t; /*------------------------------------*/ /* Response (bulk IN) packet contents */ @@ -832,12 +832,12 @@ typedef struct hfa384x_usb_rmemreq { typedef struct hfa384x_usb_rxfrm { hfa384x_rx_frame_t desc; u8 data[WLAN_DATA_MAXLEN]; -} __attribute__ ((packed)) hfa384x_usb_rxfrm_t; +} __packed hfa384x_usb_rxfrm_t; typedef struct hfa384x_usb_infofrm { u16 type; hfa384x_InfFrame_t info; -} __attribute__ ((packed)) hfa384x_usb_infofrm_t; +} __packed hfa384x_usb_infofrm_t; typedef struct hfa384x_usb_statusresp { u16 type; @@ -845,7 +845,7 @@ typedef struct hfa384x_usb_statusresp { u16 resp0; u16 resp1; u16 resp2; -} __attribute__ ((packed)) hfa384x_usb_cmdresp_t; +} __packed hfa384x_usb_cmdresp_t; typedef hfa384x_usb_cmdresp_t hfa384x_usb_wridresp_t; @@ -854,7 +854,7 @@ typedef struct hfa384x_usb_rridresp { u16 frmlen; u16 rid; u8 data[HFA384x_RIDDATA_MAXLEN]; -} __attribute__ ((packed)) hfa384x_usb_rridresp_t; +} __packed hfa384x_usb_rridresp_t; typedef hfa384x_usb_cmdresp_t hfa384x_usb_wmemresp_t; @@ -862,17 +862,17 @@ typedef struct hfa384x_usb_rmemresp { u16 type; u16 frmlen; u8 data[HFA384x_USB_RWMEM_MAXLEN]; -} __attribute__ ((packed)) hfa384x_usb_rmemresp_t; +} __packed hfa384x_usb_rmemresp_t; typedef struct hfa384x_usb_bufavail { u16 type; u16 frmlen; -} __attribute__ ((packed)) hfa384x_usb_bufavail_t; +} __packed hfa384x_usb_bufavail_t; typedef struct hfa384x_usb_error { u16 type; u16 errortype; -} __attribute__ ((packed)) hfa384x_usb_error_t; +} __packed hfa384x_usb_error_t; /*----------------------------------------------------------*/ /* Unions for packaging all the known packet types together */ @@ -885,7 +885,7 @@ typedef union hfa384x_usbout { hfa384x_usb_rridreq_t rridreq; hfa384x_usb_wmemreq_t wmemreq; hfa384x_usb_rmemreq_t rmemreq; -} __attribute__ ((packed)) hfa384x_usbout_t; +} __packed hfa384x_usbout_t; typedef union hfa384x_usbin { u16 type; @@ -900,7 +900,7 @@ typedef union hfa384x_usbin { hfa384x_usb_bufavail_t bufavail; hfa384x_usb_error_t usberror; u8 boguspad[3000]; -} __attribute__ ((packed)) hfa384x_usbin_t; +} __packed hfa384x_usbin_t; /*-------------------------------------------------------------------- PD record structures. @@ -908,15 +908,15 @@ PD record structures. typedef struct hfa384x_pdr_pcb_partnum { u8 num[8]; -} __attribute__ ((packed)) hfa384x_pdr_pcb_partnum_t; +} __packed hfa384x_pdr_pcb_partnum_t; typedef struct hfa384x_pdr_pcb_tracenum { u8 num[8]; -} __attribute__ ((packed)) hfa384x_pdr_pcb_tracenum_t; +} __packed hfa384x_pdr_pcb_tracenum_t; typedef struct hfa384x_pdr_nic_serial { u8 num[12]; -} __attribute__ ((packed)) hfa384x_pdr_nic_serial_t; +} __packed hfa384x_pdr_nic_serial_t; typedef struct hfa384x_pdr_mkk_measurements { double carrier_freq; @@ -934,138 +934,138 @@ typedef struct hfa384x_pdr_mkk_measurements { double rx_spur_f2; double rx_spur_l1; double rx_spur_l2; -} __attribute__ ((packed)) hfa384x_pdr_mkk_measurements_t; +} __packed hfa384x_pdr_mkk_measurements_t; typedef struct hfa384x_pdr_nic_ramsize { u8 size[12]; /* units of KB */ -} __attribute__ ((packed)) hfa384x_pdr_nic_ramsize_t; +} __packed hfa384x_pdr_nic_ramsize_t; typedef struct hfa384x_pdr_mfisuprange { u16 id; u16 variant; u16 bottom; u16 top; -} __attribute__ ((packed)) hfa384x_pdr_mfisuprange_t; +} __packed hfa384x_pdr_mfisuprange_t; typedef struct hfa384x_pdr_cfisuprange { u16 id; u16 variant; u16 bottom; u16 top; -} __attribute__ ((packed)) hfa384x_pdr_cfisuprange_t; +} __packed hfa384x_pdr_cfisuprange_t; typedef struct hfa384x_pdr_nicid { u16 id; u16 variant; u16 major; u16 minor; -} __attribute__ ((packed)) hfa384x_pdr_nicid_t; +} __packed hfa384x_pdr_nicid_t; typedef struct hfa384x_pdr_refdac_measurements { u16 value[0]; -} __attribute__ ((packed)) hfa384x_pdr_refdac_measurements_t; +} __packed hfa384x_pdr_refdac_measurements_t; typedef struct hfa384x_pdr_vgdac_measurements { u16 value[0]; -} __attribute__ ((packed)) hfa384x_pdr_vgdac_measurements_t; +} __packed hfa384x_pdr_vgdac_measurements_t; typedef struct hfa384x_pdr_level_comp_measurements { u16 value[0]; -} __attribute__ ((packed)) hfa384x_pdr_level_compc_measurements_t; +} __packed hfa384x_pdr_level_compc_measurements_t; typedef struct hfa384x_pdr_mac_address { u8 addr[6]; -} __attribute__ ((packed)) hfa384x_pdr_mac_address_t; +} __packed hfa384x_pdr_mac_address_t; typedef struct hfa384x_pdr_mkk_callname { u8 callname[8]; -} __attribute__ ((packed)) hfa384x_pdr_mkk_callname_t; +} __packed hfa384x_pdr_mkk_callname_t; typedef struct hfa384x_pdr_regdomain { u16 numdomains; u16 domain[5]; -} __attribute__ ((packed)) hfa384x_pdr_regdomain_t; +} __packed hfa384x_pdr_regdomain_t; typedef struct hfa384x_pdr_allowed_channel { u16 ch_bitmap; -} __attribute__ ((packed)) hfa384x_pdr_allowed_channel_t; +} __packed hfa384x_pdr_allowed_channel_t; typedef struct hfa384x_pdr_default_channel { u16 channel; -} __attribute__ ((packed)) hfa384x_pdr_default_channel_t; +} __packed hfa384x_pdr_default_channel_t; typedef struct hfa384x_pdr_privacy_option { u16 available; -} __attribute__ ((packed)) hfa384x_pdr_privacy_option_t; +} __packed hfa384x_pdr_privacy_option_t; typedef struct hfa384x_pdr_temptype { u16 type; -} __attribute__ ((packed)) hfa384x_pdr_temptype_t; +} __packed hfa384x_pdr_temptype_t; typedef struct hfa384x_pdr_refdac_setup { u16 ch_value[14]; -} __attribute__ ((packed)) hfa384x_pdr_refdac_setup_t; +} __packed hfa384x_pdr_refdac_setup_t; typedef struct hfa384x_pdr_vgdac_setup { u16 ch_value[14]; -} __attribute__ ((packed)) hfa384x_pdr_vgdac_setup_t; +} __packed hfa384x_pdr_vgdac_setup_t; typedef struct hfa384x_pdr_level_comp_setup { u16 ch_value[14]; -} __attribute__ ((packed)) hfa384x_pdr_level_comp_setup_t; +} __packed hfa384x_pdr_level_comp_setup_t; typedef struct hfa384x_pdr_trimdac_setup { u16 trimidac; u16 trimqdac; -} __attribute__ ((packed)) hfa384x_pdr_trimdac_setup_t; +} __packed hfa384x_pdr_trimdac_setup_t; typedef struct hfa384x_pdr_ifr_setting { u16 value[3]; -} __attribute__ ((packed)) hfa384x_pdr_ifr_setting_t; +} __packed hfa384x_pdr_ifr_setting_t; typedef struct hfa384x_pdr_rfr_setting { u16 value[3]; -} __attribute__ ((packed)) hfa384x_pdr_rfr_setting_t; +} __packed hfa384x_pdr_rfr_setting_t; typedef struct hfa384x_pdr_hfa3861_baseline { u16 value[50]; -} __attribute__ ((packed)) hfa384x_pdr_hfa3861_baseline_t; +} __packed hfa384x_pdr_hfa3861_baseline_t; typedef struct hfa384x_pdr_hfa3861_shadow { u32 value[32]; -} __attribute__ ((packed)) hfa384x_pdr_hfa3861_shadow_t; +} __packed hfa384x_pdr_hfa3861_shadow_t; typedef struct hfa384x_pdr_hfa3861_ifrf { u32 value[20]; -} __attribute__ ((packed)) hfa384x_pdr_hfa3861_ifrf_t; +} __packed hfa384x_pdr_hfa3861_ifrf_t; typedef struct hfa384x_pdr_hfa3861_chcalsp { u16 value[14]; -} __attribute__ ((packed)) hfa384x_pdr_hfa3861_chcalsp_t; +} __packed hfa384x_pdr_hfa3861_chcalsp_t; typedef struct hfa384x_pdr_hfa3861_chcali { u16 value[17]; -} __attribute__ ((packed)) hfa384x_pdr_hfa3861_chcali_t; +} __packed hfa384x_pdr_hfa3861_chcali_t; typedef struct hfa384x_pdr_hfa3861_nic_config { u16 config_bitmap; -} __attribute__ ((packed)) hfa384x_pdr_nic_config_t; +} __packed hfa384x_pdr_nic_config_t; typedef struct hfa384x_pdr_hfo_delay { u8 hfo_delay; -} __attribute__ ((packed)) hfa384x_hfo_delay_t; +} __packed hfa384x_hfo_delay_t; typedef struct hfa384x_pdr_hfa3861_manf_testsp { u16 value[30]; -} __attribute__ ((packed)) hfa384x_pdr_hfa3861_manf_testsp_t; +} __packed hfa384x_pdr_hfa3861_manf_testsp_t; typedef struct hfa384x_pdr_hfa3861_manf_testi { u16 value[30]; -} __attribute__ ((packed)) hfa384x_pdr_hfa3861_manf_testi_t; +} __packed hfa384x_pdr_hfa3861_manf_testi_t; typedef struct hfa384x_end_of_pda { u16 crc; -} __attribute__ ((packed)) hfa384x_pdr_end_of_pda_t; +} __packed hfa384x_pdr_end_of_pda_t; typedef struct hfa384x_pdrec { u16 len; /* in words */ @@ -1107,7 +1107,7 @@ typedef struct hfa384x_pdrec { hfa384x_pdr_end_of_pda_t end_of_pda; } data; -} __attribute__ ((packed)) hfa384x_pdrec_t; +} __packed hfa384x_pdrec_t; #ifdef __KERNEL__ /*-------------------------------------------------------------------- diff --git a/drivers/staging/wlan-ng/p80211conv.h b/drivers/staging/wlan-ng/p80211conv.h index ea493aa74f00..e031a74d2ad4 100644 --- a/drivers/staging/wlan-ng/p80211conv.h +++ b/drivers/staging/wlan-ng/p80211conv.h @@ -134,20 +134,20 @@ struct wlan_ethhdr { u8 daddr[WLAN_ETHADDR_LEN]; u8 saddr[WLAN_ETHADDR_LEN]; u16 type; -} __attribute__ ((packed)); +} __packed; /* local llc header type */ struct wlan_llc { u8 dsap; u8 ssap; u8 ctl; -} __attribute__ ((packed)); +} __packed; /* local snap header type */ struct wlan_snap { u8 oui[WLAN_IEEE_OUI_LEN]; u16 type; -} __attribute__ ((packed)); +} __packed; /* Circular include trick */ struct wlandevice; diff --git a/drivers/staging/wlan-ng/p80211hdr.h b/drivers/staging/wlan-ng/p80211hdr.h index 1f6e4ebc6eb9..66b5e201d418 100644 --- a/drivers/staging/wlan-ng/p80211hdr.h +++ b/drivers/staging/wlan-ng/p80211hdr.h @@ -154,7 +154,7 @@ struct p80211_hdr_a3 { u8 a2[ETH_ALEN]; u8 a3[ETH_ALEN]; u16 seq; -} __attribute__ ((packed)); +} __packed; struct p80211_hdr_a4 { u16 fc; @@ -164,12 +164,12 @@ struct p80211_hdr_a4 { u8 a3[ETH_ALEN]; u16 seq; u8 a4[ETH_ALEN]; -} __attribute__ ((packed)); +} __packed; union p80211_hdr { struct p80211_hdr_a3 a3; struct p80211_hdr_a4 a4; -} __attribute__ ((packed)); +} __packed; /* Frame and header length macros */ diff --git a/drivers/staging/wlan-ng/p80211ioctl.h b/drivers/staging/wlan-ng/p80211ioctl.h index 0d47765452ee..06c5e36649a7 100644 --- a/drivers/staging/wlan-ng/p80211ioctl.h +++ b/drivers/staging/wlan-ng/p80211ioctl.h @@ -84,6 +84,6 @@ struct p80211ioctl_req { u32 magic; u16 len; u32 result; -} __attribute__ ((packed)); +} __packed; #endif /* _P80211IOCTL_H */ diff --git a/drivers/staging/wlan-ng/p80211metastruct.h b/drivers/staging/wlan-ng/p80211metastruct.h index a8a4e3b5ffef..c501162c3020 100644 --- a/drivers/staging/wlan-ng/p80211metastruct.h +++ b/drivers/staging/wlan-ng/p80211metastruct.h @@ -53,7 +53,7 @@ struct p80211msg_dot11req_mibget { u8 devname[WLAN_DEVNAMELEN_MAX]; p80211item_unk392_t mibattribute; p80211item_uint32_t resultcode; -} __attribute__ ((packed)); +} __packed; struct p80211msg_dot11req_mibset { u32 msgcode; @@ -61,7 +61,7 @@ struct p80211msg_dot11req_mibset { u8 devname[WLAN_DEVNAMELEN_MAX]; p80211item_unk392_t mibattribute; p80211item_uint32_t resultcode; -} __attribute__ ((packed)); +} __packed; struct p80211msg_dot11req_scan { u32 msgcode; @@ -81,7 +81,7 @@ struct p80211msg_dot11req_scan { p80211item_uint32_t resultcode; p80211item_uint32_t numbss; p80211item_uint32_t append; -} __attribute__ ((packed)); +} __packed; struct p80211msg_dot11req_scan_results { u32 msgcode; @@ -130,7 +130,7 @@ struct p80211msg_dot11req_scan_results { p80211item_uint32_t supprate6; p80211item_uint32_t supprate7; p80211item_uint32_t supprate8; -} __attribute__ ((packed)); +} __packed; struct p80211msg_dot11req_start { u32 msgcode; @@ -168,7 +168,7 @@ struct p80211msg_dot11req_start { p80211item_uint32_t operationalrate7; p80211item_uint32_t operationalrate8; p80211item_uint32_t resultcode; -} __attribute__ ((packed)); +} __packed; struct p80211msg_lnxreq_ifstate { u32 msgcode; @@ -176,7 +176,7 @@ struct p80211msg_lnxreq_ifstate { u8 devname[WLAN_DEVNAMELEN_MAX]; p80211item_uint32_t ifstate; p80211item_uint32_t resultcode; -} __attribute__ ((packed)); +} __packed; struct p80211msg_lnxreq_wlansniff { u32 msgcode; @@ -190,7 +190,7 @@ struct p80211msg_lnxreq_wlansniff { p80211item_uint32_t stripfcs; p80211item_uint32_t packet_trunc; p80211item_uint32_t resultcode; -} __attribute__ ((packed)); +} __packed; struct p80211msg_lnxreq_hostwep { u32 msgcode; @@ -199,7 +199,7 @@ struct p80211msg_lnxreq_hostwep { p80211item_uint32_t resultcode; p80211item_uint32_t decrypt; p80211item_uint32_t encrypt; -} __attribute__ ((packed)); +} __packed; struct p80211msg_lnxreq_commsquality { u32 msgcode; @@ -211,7 +211,7 @@ struct p80211msg_lnxreq_commsquality { p80211item_uint32_t level; p80211item_uint32_t noise; p80211item_uint32_t txrate; -} __attribute__ ((packed)); +} __packed; struct p80211msg_lnxreq_autojoin { u32 msgcode; @@ -221,7 +221,7 @@ struct p80211msg_lnxreq_autojoin { u8 pad_19D[3]; p80211item_uint32_t authtype; p80211item_uint32_t resultcode; -} __attribute__ ((packed)); +} __packed; struct p80211msg_p2req_readpda { u32 msgcode; @@ -229,7 +229,7 @@ struct p80211msg_p2req_readpda { u8 devname[WLAN_DEVNAMELEN_MAX]; p80211item_unk1024_t pda; p80211item_uint32_t resultcode; -} __attribute__ ((packed)); +} __packed; struct p80211msg_p2req_ramdl_state { u32 msgcode; @@ -238,7 +238,7 @@ struct p80211msg_p2req_ramdl_state { p80211item_uint32_t enable; p80211item_uint32_t exeaddr; p80211item_uint32_t resultcode; -} __attribute__ ((packed)); +} __packed; struct p80211msg_p2req_ramdl_write { u32 msgcode; @@ -248,7 +248,7 @@ struct p80211msg_p2req_ramdl_write { p80211item_uint32_t len; p80211item_unk4096_t data; p80211item_uint32_t resultcode; -} __attribute__ ((packed)); +} __packed; struct p80211msg_p2req_flashdl_state { u32 msgcode; @@ -256,7 +256,7 @@ struct p80211msg_p2req_flashdl_state { u8 devname[WLAN_DEVNAMELEN_MAX]; p80211item_uint32_t enable; p80211item_uint32_t resultcode; -} __attribute__ ((packed)); +} __packed; struct p80211msg_p2req_flashdl_write { u32 msgcode; @@ -266,6 +266,6 @@ struct p80211msg_p2req_flashdl_write { p80211item_uint32_t len; p80211item_unk4096_t data; p80211item_uint32_t resultcode; -} __attribute__ ((packed)); +} __packed; #endif diff --git a/drivers/staging/wlan-ng/p80211mgmt.h b/drivers/staging/wlan-ng/p80211mgmt.h index 3b5e8113ad17..2610824d36d7 100644 --- a/drivers/staging/wlan-ng/p80211mgmt.h +++ b/drivers/staging/wlan-ng/p80211mgmt.h @@ -222,21 +222,21 @@ typedef struct wlan_ie { u8 eid; u8 len; -} __attribute__ ((packed)) wlan_ie_t; +} __packed wlan_ie_t; /*-- Service Set Identity (SSID) -----------------*/ typedef struct wlan_ie_ssid { u8 eid; u8 len; u8 ssid[1]; /* may be zero, ptrs may overlap */ -} __attribute__ ((packed)) wlan_ie_ssid_t; +} __packed wlan_ie_ssid_t; /*-- Supported Rates -----------------------------*/ typedef struct wlan_ie_supp_rates { u8 eid; u8 len; u8 rates[1]; /* had better be at LEAST one! */ -} __attribute__ ((packed)) wlan_ie_supp_rates_t; +} __packed wlan_ie_supp_rates_t; /*-- FH Parameter Set ----------------------------*/ typedef struct wlan_ie_fh_parms { @@ -246,14 +246,14 @@ typedef struct wlan_ie_fh_parms { u8 hopset; u8 hoppattern; u8 hopindex; -} __attribute__ ((packed)) wlan_ie_fh_parms_t; +} __packed wlan_ie_fh_parms_t; /*-- DS Parameter Set ----------------------------*/ typedef struct wlan_ie_ds_parms { u8 eid; u8 len; u8 curr_ch; -} __attribute__ ((packed)) wlan_ie_ds_parms_t; +} __packed wlan_ie_ds_parms_t; /*-- CF Parameter Set ----------------------------*/ @@ -264,7 +264,7 @@ typedef struct wlan_ie_cf_parms { u8 cfp_period; u16 cfp_maxdur; u16 cfp_durremaining; -} __attribute__ ((packed)) wlan_ie_cf_parms_t; +} __packed wlan_ie_cf_parms_t; /*-- TIM ------------------------------------------*/ typedef struct wlan_ie_tim { @@ -274,21 +274,21 @@ typedef struct wlan_ie_tim { u8 dtim_period; u8 bitmap_ctl; u8 virt_bm[1]; -} __attribute__ ((packed)) wlan_ie_tim_t; +} __packed wlan_ie_tim_t; /*-- IBSS Parameter Set ---------------------------*/ typedef struct wlan_ie_ibss_parms { u8 eid; u8 len; u16 atim_win; -} __attribute__ ((packed)) wlan_ie_ibss_parms_t; +} __packed wlan_ie_ibss_parms_t; /*-- Challenge Text ------------------------------*/ typedef struct wlan_ie_challenge { u8 eid; u8 len; u8 challenge[1]; -} __attribute__ ((packed)) wlan_ie_challenge_t; +} __packed wlan_ie_challenge_t; /*-------------------------------------------------*/ /* Frame Types */ diff --git a/drivers/staging/wlan-ng/p80211msg.h b/drivers/staging/wlan-ng/p80211msg.h index 8e0f9a0cd74a..43d2f971e2cd 100644 --- a/drivers/staging/wlan-ng/p80211msg.h +++ b/drivers/staging/wlan-ng/p80211msg.h @@ -54,6 +54,6 @@ struct p80211msg { u32 msgcode; u32 msglen; u8 devname[WLAN_DEVNAMELEN_MAX]; -} __attribute__ ((packed)); +} __packed; #endif /* _P80211MSG_H */ diff --git a/drivers/staging/wlan-ng/p80211types.h b/drivers/staging/wlan-ng/p80211types.h index 9dec8596f451..f043090ef86d 100644 --- a/drivers/staging/wlan-ng/p80211types.h +++ b/drivers/staging/wlan-ng/p80211types.h @@ -217,49 +217,49 @@ typedef struct p80211enum { /* Template pascal string */ typedef struct p80211pstr { u8 len; -} __attribute__ ((packed)) p80211pstr_t; +} __packed p80211pstr_t; typedef struct p80211pstrd { u8 len; u8 data[0]; -} __attribute__ ((packed)) p80211pstrd_t; +} __packed p80211pstrd_t; /* Maximum pascal string */ typedef struct p80211pstr255 { u8 len; u8 data[MAXLEN_PSTR255]; -} __attribute__ ((packed)) p80211pstr255_t; +} __packed p80211pstr255_t; /* pascal string for macaddress and bssid */ typedef struct p80211pstr6 { u8 len; u8 data[MAXLEN_PSTR6]; -} __attribute__ ((packed)) p80211pstr6_t; +} __packed p80211pstr6_t; /* pascal string for channel list */ typedef struct p80211pstr14 { u8 len; u8 data[MAXLEN_PSTR14]; -} __attribute__ ((packed)) p80211pstr14_t; +} __packed p80211pstr14_t; /* pascal string for ssid */ typedef struct p80211pstr32 { u8 len; u8 data[MAXLEN_PSTR32]; -} __attribute__ ((packed)) p80211pstr32_t; +} __packed p80211pstr32_t; /* MAC address array */ typedef struct p80211macarray { u32 cnt; u8 data[1][MAXLEN_PSTR6]; -} __attribute__ ((packed)) p80211macarray_t; +} __packed p80211macarray_t; /* prototype template */ typedef struct p80211item { u32 did; u16 status; u16 len; -} __attribute__ ((packed)) p80211item_t; +} __packed p80211item_t; /* prototype template w/ data item */ typedef struct p80211itemd { @@ -267,7 +267,7 @@ typedef struct p80211itemd { u16 status; u16 len; u8 data[0]; -} __attribute__ ((packed)) p80211itemd_t; +} __packed p80211itemd_t; /* message data item for int, BOUNDEDINT, ENUMINT */ typedef struct p80211item_uint32 { @@ -275,7 +275,7 @@ typedef struct p80211item_uint32 { u16 status; u16 len; u32 data; -} __attribute__ ((packed)) p80211item_uint32_t; +} __packed p80211item_uint32_t; /* message data item for OCTETSTR, DISPLAYSTR */ typedef struct p80211item_pstr6 { @@ -283,7 +283,7 @@ typedef struct p80211item_pstr6 { u16 status; u16 len; p80211pstr6_t data; -} __attribute__ ((packed)) p80211item_pstr6_t; +} __packed p80211item_pstr6_t; /* message data item for OCTETSTR, DISPLAYSTR */ typedef struct p80211item_pstr14 { @@ -291,7 +291,7 @@ typedef struct p80211item_pstr14 { u16 status; u16 len; p80211pstr14_t data; -} __attribute__ ((packed)) p80211item_pstr14_t; +} __packed p80211item_pstr14_t; /* message data item for OCTETSTR, DISPLAYSTR */ typedef struct p80211item_pstr32 { @@ -299,7 +299,7 @@ typedef struct p80211item_pstr32 { u16 status; u16 len; p80211pstr32_t data; -} __attribute__ ((packed)) p80211item_pstr32_t; +} __packed p80211item_pstr32_t; /* message data item for OCTETSTR, DISPLAYSTR */ typedef struct p80211item_pstr255 { @@ -307,7 +307,7 @@ typedef struct p80211item_pstr255 { u16 status; u16 len; p80211pstr255_t data; -} __attribute__ ((packed)) p80211item_pstr255_t; +} __packed p80211item_pstr255_t; /* message data item for UNK 392, namely mib items */ typedef struct p80211item_unk392 { @@ -315,7 +315,7 @@ typedef struct p80211item_unk392 { u16 status; u16 len; u8 data[MAXLEN_MIBATTRIBUTE]; -} __attribute__ ((packed)) p80211item_unk392_t; +} __packed p80211item_unk392_t; /* message data item for UNK 1025, namely p2 pdas */ typedef struct p80211item_unk1024 { @@ -323,7 +323,7 @@ typedef struct p80211item_unk1024 { u16 status; u16 len; u8 data[1024]; -} __attribute__ ((packed)) p80211item_unk1024_t; +} __packed p80211item_unk1024_t; /* message data item for UNK 4096, namely p2 download chunks */ typedef struct p80211item_unk4096 { @@ -331,7 +331,7 @@ typedef struct p80211item_unk4096 { u16 status; u16 len; u8 data[4096]; -} __attribute__ ((packed)) p80211item_unk4096_t; +} __packed p80211item_unk4096_t; struct catlistitem; -- cgit v1.2.3 From 3ad4e219606fa317f778b26553889520aed7925c Mon Sep 17 00:00:00 2001 From: Micha Hergarden Date: Wed, 2 Feb 2011 21:25:07 +0100 Subject: staging: comedi: fix coding style issue in drivers.c This is a patch to the drivers.c file that fixes up a braces around single statement warning found by the checkpatch.pl tool Signed-off-by: Micha Hergarden Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index dca861ee0466..6d60e91b3a85 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -471,9 +471,9 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, async->buf_page_list = vzalloc(sizeof(struct comedi_buf_page) * n_pages); - if (async->buf_page_list) { + if (async->buf_page_list) pages = vmalloc(sizeof(struct page *) * n_pages); - } + if (pages) { for (i = 0; i < n_pages; i++) { if (s->async_dma_dir != DMA_NONE) { -- cgit v1.2.3 From a90dcd4f7dfc3e664e7d08790a8b39d052e21a2e Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 3 Feb 2011 14:22:08 +0100 Subject: staging: oplc_dcon: Fix compilation warning. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix compilation warning: drivers/staging/olpc_dcon/olpc_dcon.c: In function ‘dcon_probe’: drivers/staging/olpc_dcon/olpc_dcon.c:704:21: warning: ignoring return value of ‘device_create_file’, declared with attribute warn_unused_result and add cleaning of created files when creation of one failed. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 56a283d1a74d..7221bb886857 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -674,7 +674,7 @@ static int dcon_detect(struct i2c_client *client, struct i2c_board_info *info) static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) { - int rc, i; + int rc, i, j; if (num_registered_fb >= 1) fbinfo = registered_fb[0]; @@ -700,8 +700,14 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) goto edev; } - for(i = 0; i < ARRAY_SIZE(dcon_device_files); i++) - device_create_file(&dcon_device->dev, &dcon_device_files[i]); + for(i = 0; i < ARRAY_SIZE(dcon_device_files); i++) { + rc = device_create_file(&dcon_device->dev, + &dcon_device_files[i]); + if (rc) { + dev_err(&dcon_device->dev, "Cannot create sysfs file\n"); + goto ecreate; + } + } /* Add the backlight device for the DCON */ @@ -728,6 +734,9 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) return 0; + ecreate: + for (j = 0; j < i; j++) + device_remove_file(&dcon_device->dev, &dcon_device_files[j]); edev: platform_device_unregister(dcon_device); dcon_device = NULL; -- cgit v1.2.3 From e107e6ebdda9b56be21951a7c58c2fa90d6e685b Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 3 Feb 2011 16:22:52 +0100 Subject: staging: olpc_dcon: checkpatch.pl fixes for olpc_dcon.c file. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon.c | 84 +++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 7221bb886857..b19cd349f933 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -87,14 +87,14 @@ static unsigned short dcon_disp_mode; /* Variables used during switches */ static int dcon_switched; static struct timespec dcon_irq_time; -static struct timespec dcon_load_time; +static struct timespec dcon_load_time; static DECLARE_WAIT_QUEUE_HEAD(dcon_wait_queue); static unsigned short normal_i2c[] = { 0x0d, I2C_CLIENT_END }; -#define dcon_write(reg,val) i2c_smbus_write_word_data(dcon_client,reg,val) -#define dcon_read(reg) i2c_smbus_read_word_data(dcon_client,reg) +#define dcon_write(reg, val) i2c_smbus_write_word_data(dcon_client, reg, val) +#define dcon_read(reg) i2c_smbus_read_word_data(dcon_client, reg) /* The current backlight value - this saves us some smbus traffic */ static int bl_val = -1; @@ -117,7 +117,8 @@ static int dcon_hw_init(struct i2c_client *client, int is_init) if (is_init) { printk(KERN_INFO "olpc-dcon: Discovered DCON version %x\n", ver & 0xFF); - if ((rc = pdata->init()) != 0) { + rc = pdata->init(); + if (rc != 0) { printk(KERN_ERR "olpc-dcon: Unable to init.\n"); goto err; } @@ -133,14 +134,13 @@ static int dcon_hw_init(struct i2c_client *client, int is_init) i2c_smbus_write_word_data(client, 0x0b, 0x007a); i2c_smbus_write_word_data(client, 0x36, 0x025c); i2c_smbus_write_word_data(client, 0x37, 0x025e); - + /* Initialise SDRAM */ i2c_smbus_write_word_data(client, 0x3b, 0x002b); i2c_smbus_write_word_data(client, 0x41, 0x0101); i2c_smbus_write_word_data(client, 0x42, 0x0101); - } - else if (!noinit) { + } else if (!noinit) { /* SDRAM setup/hold time */ i2c_smbus_write_word_data(client, 0x3a, 0xc040); i2c_smbus_write_word_data(client, 0x41, 0x0000); @@ -181,14 +181,15 @@ static int dcon_bus_stabilize(struct i2c_client *client, int is_powered_down) power_up: if (is_powered_down) { x = 1; - if ((x = olpc_ec_cmd(0x26, (unsigned char *) &x, 1, NULL, 0))) { + x = olpc_ec_cmd(0x26, (unsigned char *) &x, 1, NULL, 0); + if (x) { printk(KERN_WARNING "olpc-dcon: unable to force dcon " "to power up: %d!\n", x); return x; } msleep(10); /* we'll be conservative */ } - + pdata->bus_stabilize_wiggle(); for (x = -1, timeout = 50; timeout && x < 0; timeout--) { @@ -261,8 +262,7 @@ static int dcon_set_output(int arg) if (arg == DCON_OUTPUT_MONO) { dcon_disp_mode &= ~(MODE_CSWIZZLE | MODE_COL_AA); dcon_disp_mode |= MODE_MONO_LUMA; - } - else { + } else { dcon_disp_mode &= ~(MODE_MONO_LUMA); dcon_disp_mode |= MODE_CSWIZZLE; if (useaa) @@ -291,18 +291,18 @@ static void dcon_sleep(int state) if (state == DCON_SLEEP) { x = 0; - if ((x = olpc_ec_cmd(0x26, (unsigned char *) &x, 1, NULL, 0))) + x = olpc_ec_cmd(0x26, (unsigned char *) &x, 1, NULL, 0); + if (x) printk(KERN_WARNING "olpc-dcon: unable to force dcon " "to power down: %d!\n", x); else dcon_sleep_val = state; - } - else { + } else { /* Only re-enable the backlight if the backlight value is set */ if (bl_val != 0) dcon_disp_mode |= MODE_BL_ENABLE; - - if ((x=dcon_bus_stabilize(dcon_client, 1))) + x = dcon_bus_stabilize(dcon_client, 1); + if (x) printk(KERN_WARNING "olpc-dcon: unable to reinit dcon" " hardware: %d!\n", x); else @@ -316,14 +316,14 @@ static void dcon_sleep(int state) } /* the DCON seems to get confused if we change DCONLOAD too - * frequently -- i.e., approximately faster than frame time. + * frequently -- i.e., approximately faster than frame time. * normally we don't change it this fast, so in general we won't * delay here. */ void dcon_load_holdoff(void) { struct timespec delta_t, now; - while(1) { + while (1) { getnstimeofday(&now); delta_t = timespec_sub(now, dcon_load_time); if (delta_t.tv_sec != 0 || @@ -352,10 +352,12 @@ static void dcon_source_switch(struct work_struct *work) printk("dcon_source_switch to CPU\n"); /* Enable the scanline interrupt bit */ if (dcon_write(DCON_REG_MODE, dcon_disp_mode | MODE_SCAN_INT)) - printk(KERN_ERR "olpc-dcon: couldn't enable scanline interrupt!\n"); + printk(KERN_ERR + "olpc-dcon: couldn't enable scanline interrupt!\n"); else { /* Wait up to one second for the scanline interrupt */ - wait_event_timeout(dcon_wait_queue, dcon_switched == 1, HZ); + wait_event_timeout(dcon_wait_queue, + dcon_switched == 1, HZ); } if (!dcon_switched) @@ -396,7 +398,7 @@ static void dcon_source_switch(struct work_struct *work) int t; struct timespec delta_t; - printk("dcon_source_switch to DCON\n"); + printk(KERN_INFO "dcon_source_switch to DCON\n"); add_wait_queue(&dcon_wait_queue, &wait); set_current_state(TASK_UNINTERRUPTIBLE); @@ -420,7 +422,7 @@ static void dcon_source_switch(struct work_struct *work) * the time between asserting DCONLOAD and the IRQ -- * if it's less than 20msec, then the DCON couldn't * have seen two VSYNC pulses. in that case we - * deassert and reassert, and hope for the best. + * deassert and reassert, and hope for the best. * see http://dev.laptop.org/ticket/9664 */ delta_t = timespec_sub(dcon_irq_time, dcon_load_time); @@ -471,7 +473,8 @@ static void dcon_set_source_sync(int arg) flush_scheduled_work(); } -static int dconbl_set(struct backlight_device *dev) { +static int dconbl_set(struct backlight_device *dev) +{ int level = dev->props.brightness; @@ -482,7 +485,8 @@ static int dconbl_set(struct backlight_device *dev) { return 0; } -static int dconbl_get(struct backlight_device *dev) { +static int dconbl_get(struct backlight_device *dev) +{ return dcon_get_backlight(); } @@ -521,7 +525,7 @@ static int _strtoul(const char *buf, int len, unsigned int *val) { char *endp; - unsigned int output = simple_strtoul(buf, &endp, 0); + unsigned int output = strict_strtoul(buf, &endp, 0); int size = endp - buf; if (*endp && isspace(*endp)) @@ -559,7 +563,7 @@ static ssize_t dcon_freeze_store(struct device *dev, if (_strtoul(buf, count, &output)) return -EINVAL; - printk("dcon_freeze_store: %d\n", output); + printk(KERN_INFO "dcon_freeze_store: %d\n", output); switch (output) { case 0: @@ -568,7 +572,7 @@ static ssize_t dcon_freeze_store(struct device *dev, case 1: dcon_set_source_sync(DCON_SOURCE_DCON); break; - case 2: // normally unused + case 2: /* normally unused */ dcon_set_source(DCON_SOURCE_DCON); break; default: @@ -620,7 +624,8 @@ static const struct backlight_ops dcon_bl_ops = { }; -static int dcon_reboot_notify(struct notifier_block *nb, unsigned long foo, void *bar) +static int dcon_reboot_notify(struct notifier_block *nb, + unsigned long foo, void *bar) { if (dcon_client == NULL) return 0; @@ -636,7 +641,8 @@ static struct notifier_block dcon_nb = { .priority = -1, }; -static int unfreeze_on_panic(struct notifier_block *nb, unsigned long e, void *p) +static int unfreeze_on_panic(struct notifier_block *nb, + unsigned long e, void *p) { pdata->set_dconload(1); return NOTIFY_DONE; @@ -650,7 +656,8 @@ static struct notifier_block dcon_panic_nb = { * When the framebuffer sleeps due to external sources (e.g. user idle), power * down the DCON as well. Power it back up when the fb comes back to life. */ -static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) +static int fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) { struct fb_event *evdata = data; int *blank = (int *) evdata->data; @@ -688,19 +695,20 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) dcon_device = platform_device_alloc("dcon", -1); if (dcon_device == NULL) { - printk("dcon: Unable to create the DCON device\n"); + printk(KERN_ERR "dcon: Unable to create the DCON device\n"); rc = -ENOMEM; goto eirq; } /* Place holder...*/ i2c_set_clientdata(client, dcon_device); + rc = platform_device_add(dcon_device); - if ((rc = platform_device_add(dcon_device))) { - printk("dcon: Unable to add the DCON device\n"); + if (rc) { + printk(KERN_ERR "dcon: Unable to add the DCON device\n"); goto edev; } - for(i = 0; i < ARRAY_SIZE(dcon_device_files); i++) { + for (i = 0; i < ARRAY_SIZE(dcon_device_files); i++) { rc = device_create_file(&dcon_device->dev, &dcon_device_files[i]); if (rc) { @@ -717,10 +725,10 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) NULL, &dcon_bl_ops, NULL); if (IS_ERR(dcon_bl_dev)) { - printk("Could not register the backlight device for the DCON (%ld)\n", PTR_ERR(dcon_bl_dev)); + printk(KERN_ERR "Cannot register the backlight device (%ld)\n", + PTR_ERR(dcon_bl_dev)); dcon_bl_dev = NULL; - } - else { + } else { dcon_bl_dev->props.max_brightness = 15; dcon_bl_dev->props.power = FB_BLANK_UNBLANK; dcon_bl_dev->props.brightness = dcon_get_backlight(); -- cgit v1.2.3 From 8a6257fbd8af8105149c15f0af91e8355bd51034 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 25 Jan 2011 14:32:03 +0100 Subject: staging: brcm80211: fix compiler warning in fullmac driver Since 2.6.38-rc1 we are getting a compiler warning due to changed API in net/cfg80211.h. This change fixes the warning but driver will need to be modified later to handle the additional parameters. Cc: Brett Rudley Cc: Henry Ptasinski Cc: Roland Vossen Cc: Dowan Kim Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 6962f5eea1a8..fa2316bcf510 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -87,8 +87,8 @@ static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy, s32 dbm); static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm); static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy, - struct net_device *dev, - u8 key_idx); + struct net_device *dev, u8 key_idx, + bool unicast, bool multicast); static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx, bool pairwise, const u8 *mac_addr, struct key_params *params); @@ -1492,7 +1492,7 @@ static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx) + u8 key_idx, bool unicast, bool multicast) { u32 index; s32 wsec; -- cgit v1.2.3 From 2ea0f6fa6570f6271909fee852474414ba04679d Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 25 Jan 2011 16:53:39 +0100 Subject: staging: brcm80211: allow both driver are created in single build This patch allows to build both drivers. Previous patch for this failed using -j option. This has been fixed by adding files with include statement for the fullmac driver. Verified this is working using -j4 option. Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/Kconfig | 14 +++++++------- drivers/staging/brcm80211/Makefile | 5 +++-- drivers/staging/brcm80211/brcmfmac/Makefile | 23 +++++++++++++---------- drivers/staging/brcm80211/brcmfmac/aiutils.c | 1 + drivers/staging/brcm80211/brcmfmac/bcmutils.c | 1 + drivers/staging/brcm80211/brcmfmac/bcmwifi.c | 1 + drivers/staging/brcm80211/brcmfmac/hndpmu.c | 1 + drivers/staging/brcm80211/brcmfmac/linux_osl.c | 1 + drivers/staging/brcm80211/brcmfmac/sbutils.c | 1 + drivers/staging/brcm80211/brcmfmac/siutils.c | 1 + drivers/staging/brcm80211/brcmsmac/Makefile | 3 +-- 11 files changed, 31 insertions(+), 21 deletions(-) create mode 100644 drivers/staging/brcm80211/brcmfmac/aiutils.c create mode 100644 drivers/staging/brcm80211/brcmfmac/bcmutils.c create mode 100644 drivers/staging/brcm80211/brcmfmac/bcmwifi.c create mode 100644 drivers/staging/brcm80211/brcmfmac/hndpmu.c create mode 100644 drivers/staging/brcm80211/brcmfmac/linux_osl.c create mode 100644 drivers/staging/brcm80211/brcmfmac/sbutils.c create mode 100644 drivers/staging/brcm80211/brcmfmac/siutils.c (limited to 'drivers') diff --git a/drivers/staging/brcm80211/Kconfig b/drivers/staging/brcm80211/Kconfig index 3208352465af..b6f86354b69f 100644 --- a/drivers/staging/brcm80211/Kconfig +++ b/drivers/staging/brcm80211/Kconfig @@ -2,12 +2,6 @@ menuconfig BRCM80211 tristate "Broadcom IEEE802.11n WLAN drivers" depends on WLAN -choice - prompt "Broadcom IEEE802.11n driver style" - depends on BRCM80211 - help - Select the appropriate driver style from the list below. - config BRCMSMAC bool "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver" depends on PCI @@ -30,4 +24,10 @@ config BRCMFMAC Broadcom IEEE802.11n FullMAC chipsets. This driver uses the kernel's wireless extensions subsystem. If you choose to build a module, it'll be called brcmfmac.ko. -endchoice + +config BRCMDBG + bool "Broadcom driver debug functions" + default n + depends on BRCM80211 + ---help--- + Selecting this enables additional code for debug purposes. diff --git a/drivers/staging/brcm80211/Makefile b/drivers/staging/brcm80211/Makefile index 5caaea597d50..c064cdf47f0d 100644 --- a/drivers/staging/brcm80211/Makefile +++ b/drivers/staging/brcm80211/Makefile @@ -15,8 +15,9 @@ # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# one and only common flag -subdir-ccflags-y := -DBCMDBG +# common flags +subdir-ccflags-y := -DBCMDMA32 +subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG -DBCMDBG_ASSERT obj-$(CONFIG_BRCMFMAC) += brcmfmac/ obj-$(CONFIG_BRCMSMAC) += brcmsmac/ diff --git a/drivers/staging/brcm80211/brcmfmac/Makefile b/drivers/staging/brcm80211/brcmfmac/Makefile index b3931b03f8d7..040f4a72dad8 100644 --- a/drivers/staging/brcm80211/brcmfmac/Makefile +++ b/drivers/staging/brcm80211/brcmfmac/Makefile @@ -22,7 +22,6 @@ ccflags-y := \ -DBCMSDIO \ -DBDC \ -DBRCM_FULLMAC \ - -DDHD_DEBUG \ -DDHD_FIRSTREAD=64 \ -DDHD_SCHED \ -DDHD_SDALIGN=64 \ @@ -31,8 +30,12 @@ ccflags-y := \ -DMMC_SDIO_ABORT \ -DPKT_FILTER_SUPPORT \ -DSHOW_EVENTS \ - -DTOE \ - -Idrivers/staging/brcm80211/brcmfmac \ + -DTOE + +ccflags-$(CONFIG_BRCMDBG) += -DDHD_DEBUG + +ccflags-y += \ + -Idrivers/staging/brcm80211/brcmfmac \ -Idrivers/staging/brcm80211/include \ -Idrivers/staging/brcm80211/util @@ -49,13 +52,13 @@ DHDOFILES = \ bcmsdh_linux.o \ bcmsdh_sdmmc.o \ bcmsdh_sdmmc_linux.o \ - ../util/linux_osl.o \ - ../util/aiutils.o \ - ../util/siutils.o \ - ../util/sbutils.o \ - ../util/bcmutils.o \ - ../util/bcmwifi.o \ - ../util/hndpmu.o + linux_osl.o \ + aiutils.o \ + siutils.o \ + sbutils.o \ + bcmutils.o \ + bcmwifi.o \ + hndpmu.o obj-m += brcmfmac.o brcmfmac-objs += $(DHDOFILES) diff --git a/drivers/staging/brcm80211/brcmfmac/aiutils.c b/drivers/staging/brcm80211/brcmfmac/aiutils.c new file mode 100644 index 000000000000..e64808648ce3 --- /dev/null +++ b/drivers/staging/brcm80211/brcmfmac/aiutils.c @@ -0,0 +1 @@ +#include "../util/aiutils.c" diff --git a/drivers/staging/brcm80211/brcmfmac/bcmutils.c b/drivers/staging/brcm80211/brcmfmac/bcmutils.c new file mode 100644 index 000000000000..8e1296a0009e --- /dev/null +++ b/drivers/staging/brcm80211/brcmfmac/bcmutils.c @@ -0,0 +1 @@ +#include "../util/bcmutils.c" diff --git a/drivers/staging/brcm80211/brcmfmac/bcmwifi.c b/drivers/staging/brcm80211/brcmfmac/bcmwifi.c new file mode 100644 index 000000000000..9fe988c1b940 --- /dev/null +++ b/drivers/staging/brcm80211/brcmfmac/bcmwifi.c @@ -0,0 +1 @@ +#include "../util/bcmwifi.c" diff --git a/drivers/staging/brcm80211/brcmfmac/hndpmu.c b/drivers/staging/brcm80211/brcmfmac/hndpmu.c new file mode 100644 index 000000000000..e841da6fb03d --- /dev/null +++ b/drivers/staging/brcm80211/brcmfmac/hndpmu.c @@ -0,0 +1 @@ +#include "../util/hndpmu.c" diff --git a/drivers/staging/brcm80211/brcmfmac/linux_osl.c b/drivers/staging/brcm80211/brcmfmac/linux_osl.c new file mode 100644 index 000000000000..a4d338dc94a3 --- /dev/null +++ b/drivers/staging/brcm80211/brcmfmac/linux_osl.c @@ -0,0 +1 @@ +#include "../util/linux_osl.c" diff --git a/drivers/staging/brcm80211/brcmfmac/sbutils.c b/drivers/staging/brcm80211/brcmfmac/sbutils.c new file mode 100644 index 000000000000..64496b8ca2cd --- /dev/null +++ b/drivers/staging/brcm80211/brcmfmac/sbutils.c @@ -0,0 +1 @@ +#include "../util/sbutils.c" diff --git a/drivers/staging/brcm80211/brcmfmac/siutils.c b/drivers/staging/brcm80211/brcmfmac/siutils.c new file mode 100644 index 000000000000..f428e992a11f --- /dev/null +++ b/drivers/staging/brcm80211/brcmfmac/siutils.c @@ -0,0 +1 @@ +#include "../util/siutils.c" diff --git a/drivers/staging/brcm80211/brcmsmac/Makefile b/drivers/staging/brcm80211/brcmsmac/Makefile index ea297023c614..5da39be0f769 100644 --- a/drivers/staging/brcm80211/brcmsmac/Makefile +++ b/drivers/staging/brcm80211/brcmsmac/Makefile @@ -15,14 +15,13 @@ # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -ccflags-y := \ +ccflags-y := \ -DWLC_HIGH \ -DWLC_LOW \ -DSTA \ -DWME \ -DWL11N \ -DDBAND \ - -DBCMDMA32 \ -DBCMNVRAMR \ -Idrivers/staging/brcm80211/brcmsmac \ -Idrivers/staging/brcm80211/brcmsmac/phy \ -- cgit v1.2.3 From db3f94c5a44ebe356c3850bf2c04ea0bd5d2443e Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 25 Jan 2011 16:53:40 +0100 Subject: staging: brcm80211: align common dirver code Remove differences in util sources for the two supported drivers. Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/util/aiutils.c | 4 ---- drivers/staging/brcm80211/util/hndpmu.c | 11 +++++------ 2 files changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/util/aiutils.c b/drivers/staging/brcm80211/util/aiutils.c index b6e7a9e97379..e4842c12ccf7 100644 --- a/drivers/staging/brcm80211/util/aiutils.c +++ b/drivers/staging/brcm80211/util/aiutils.c @@ -131,10 +131,8 @@ void ai_scan(si_t *sih, void *regs, uint devid) eromptr = regs; break; -#ifdef BCMSDIO case SPI_BUS: case SDIO_BUS: -#endif /* BCMSDIO */ eromptr = (u32 *)(unsigned long)erombase; break; @@ -355,10 +353,8 @@ void *ai_setcoreidx(si_t *sih, uint coreidx) pci_write_config_dword(sii->osh->pdev, PCI_BAR0_WIN2, wrap); break; -#ifdef BCMSDIO case SPI_BUS: case SDIO_BUS: -#endif /* BCMSDIO */ sii->curmap = regs = (void *)(unsigned long)addr; sii->curwrap = (void *)(unsigned long)wrap; break; diff --git a/drivers/staging/brcm80211/util/hndpmu.c b/drivers/staging/brcm80211/util/hndpmu.c index 49d19a121f7b..2678d799f7fd 100644 --- a/drivers/staging/brcm80211/util/hndpmu.c +++ b/drivers/staging/brcm80211/util/hndpmu.c @@ -32,6 +32,10 @@ #ifdef BCMDBG #define PMU_MSG(args) printf args + +/* debug-only definitions */ +/* #define BCMDBG_FORCEHT */ +/* #define CHIPC_UART_ALWAYS_ON */ #else #define PMU_MSG(args) #endif /* BCMDBG */ @@ -2504,12 +2508,7 @@ bool si_pmu_is_otp_powered(si_t *sih, struct osl_info *osh) return st; } -void -#if defined(BCMDBG) -si_pmu_sprom_enable(si_t *sih, struct osl_info *osh, bool enable) -#else -si_pmu_sprom_enable(si_t *sih, struct osl_info *osh, bool enable) -#endif +void si_pmu_sprom_enable(si_t *sih, struct osl_info *osh, bool enable) { chipcregs_t *cc; uint origidx; -- cgit v1.2.3 From 49ba9d2d1c6d5523ee4e9e5b31dd89445727a977 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 25 Jan 2011 16:53:41 +0100 Subject: staging: brcm80211: remove driver message upon initialization removed the message from the driver to avoid polluting the kernel log with messages indicating nothing is wrong. Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 10 +--------- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 7 ------- 2 files changed, 1 insertion(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 29fff596c168..7100d815163c 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -387,12 +387,6 @@ module_param(dhd_pktgen_len, uint, 0); #define DHD_COMPILED #endif -static char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR -#ifdef DHD_DEBUG -"\nCompiled in " " on " __DATE__ " at " __TIME__ -#endif -; - #if defined(CONFIG_WIRELESS_EXT) struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev); #endif /* defined(CONFIG_WIRELESS_EXT) */ @@ -2466,9 +2460,7 @@ static int __init dhd_module_init(void) error = dhd_bus_register(); - if (!error) - printf("\n%s\n", dhd_version); - else { + if (error) { DHD_ERROR(("%s: sdio_register_driver failed\n", __func__)); goto faild; } diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 5ce0f0701d0e..b339d714aaa2 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -762,13 +762,6 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, WL_ERROR("%s: regulatory_hint failed, status %d\n", __func__, err); } - WL_ERROR("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver (" PHY_VERSION_STR ")", - unit); - -#ifdef BCMDBG - printf(" (Compiled at " __TIME__ " on " __DATE__ ")"); -#endif /* BCMDBG */ - printf("\n"); wl_found++; return wl; -- cgit v1.2.3 From f3bc232c2eb1dac5ac3dbaca0099ce51a615a478 Mon Sep 17 00:00:00 2001 From: Robert Jennings Date: Fri, 28 Jan 2011 08:57:27 -0600 Subject: zram/vmalloc: Correct tunings to enable use with 64K pages xvmalloc will not currently function with 64K pages. Newly allocated pages will be inserted at an offset beyond the end of the first-level index. This tuning is needed to properly size the allocator for 64K pages. The default 3 byte shift results in a second level list size which can not be indexed using the 64 bits of the flbitmap in the xv_pool structure. The shift must increase to 4 bytes between second level list entries to fit the size of the first level bitmap. Here are a few statistics for structure sizes on 32- and 64-bit CPUs with 4KB and 64KB page sizes. bits_per_long 32 64 64 page_size 4,096 4,096 65,535 xv_align 4 8 8 fl_delta 3 3 4 num_free_lists 508 508 4,094 xv_pool size 4,144b 8,216b 66,040b per object overhead 32 64 64 zram struct 0.5GB disk 512KB 1024KB 64KB This patch maintains the current tunings for 4K pages, adds an optimal sizing for 64K pages and adds a safe tuning for any other page sizes. Signed-off-by: Robert Jennings Reviewed-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/xvmalloc_int.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zram/xvmalloc_int.h b/drivers/staging/zram/xvmalloc_int.h index e23ed5c8b8e4..82a31fb99574 100644 --- a/drivers/staging/zram/xvmalloc_int.h +++ b/drivers/staging/zram/xvmalloc_int.h @@ -19,7 +19,11 @@ /* User configurable params */ /* Must be power of two */ +#ifdef CONFIG_64BIT +#define XV_ALIGN_SHIFT 3 +#else #define XV_ALIGN_SHIFT 2 +#endif #define XV_ALIGN (1 << XV_ALIGN_SHIFT) #define XV_ALIGN_MASK (XV_ALIGN - 1) @@ -27,8 +31,16 @@ #define XV_MIN_ALLOC_SIZE 32 #define XV_MAX_ALLOC_SIZE (PAGE_SIZE - XV_ALIGN) -/* Free lists are separated by FL_DELTA bytes */ -#define FL_DELTA_SHIFT 3 +/* + * Free lists are separated by FL_DELTA bytes + * This value is 3 for 4k pages and 4 for 64k pages, for any + * other page size, a conservative (PAGE_SHIFT - 9) is used. + */ +#if PAGE_SHIFT == 16 +#define FL_DELTA_SHIFT 4 +#else +#define FL_DELTA_SHIFT (PAGE_SHIFT - 9) +#endif #define FL_DELTA (1 << FL_DELTA_SHIFT) #define FL_DELTA_MASK (FL_DELTA - 1) #define NUM_FREE_LISTS ((XV_MAX_ALLOC_SIZE - XV_MIN_ALLOC_SIZE) \ -- cgit v1.2.3 From 7b19b8d45b216ff3186f066b31937bdbde066f08 Mon Sep 17 00:00:00 2001 From: Robert Jennings Date: Fri, 28 Jan 2011 08:58:17 -0600 Subject: zram: Prevent overflow in logical block size On a 64K page kernel, the value PAGE_SIZE passed to blk_queue_logical_block_size would overflow the logical block size argument (resulting in setting it to 0). This patch sets the logical block size to 4096, using a new ZRAM_LOGICAL_BLOCK_SIZE constant. Signed-off-by: Robert Jennings Reviewed-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/zram_drv.c | 3 ++- drivers/staging/zram/zram_drv.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 5ed4e75dc218..3c8ecab70e97 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -616,7 +616,8 @@ static int create_device(struct zram *zram, int device_id) * and n*PAGE_SIZED sized I/O requests. */ blk_queue_physical_block_size(zram->disk->queue, PAGE_SIZE); - blk_queue_logical_block_size(zram->disk->queue, PAGE_SIZE); + blk_queue_logical_block_size(zram->disk->queue, + ZRAM_LOGICAL_BLOCK_SIZE); blk_queue_io_min(zram->disk->queue, PAGE_SIZE); blk_queue_io_opt(zram->disk->queue, PAGE_SIZE); diff --git a/drivers/staging/zram/zram_drv.h b/drivers/staging/zram/zram_drv.h index a48155112b1e..408b2c067fc9 100644 --- a/drivers/staging/zram/zram_drv.h +++ b/drivers/staging/zram/zram_drv.h @@ -61,6 +61,7 @@ static const unsigned max_zpage_size = PAGE_SIZE / 4 * 3; #define SECTOR_SIZE (1 << SECTOR_SHIFT) #define SECTORS_PER_PAGE_SHIFT (PAGE_SHIFT - SECTOR_SHIFT) #define SECTORS_PER_PAGE (1 << SECTORS_PER_PAGE_SHIFT) +#define ZRAM_LOGICAL_BLOCK_SIZE 4096 /* Flags for zram pages (table[page_no].flags) */ enum zram_pageflags { -- cgit v1.2.3 From e3f201b541ff6748db77b857d2ae69fc9dbbee11 Mon Sep 17 00:00:00 2001 From: Robert Jennings Date: Fri, 28 Jan 2011 08:58:54 -0600 Subject: zram/xvmalloc: free bit block insertion optimization This change is in a conditional block which is entered only when there is an existing data block on the freelist where the insert has taken place. The new block is pushed onto the freelist stack and this conditional block is updating links in the prior stack head to point to the new stack head. After this conditional block the first-/second-level indices are updated to indicate that there is a free block at this location. This patch adds an immediate return from the conditional block to avoid setting bits again to indicate a free block on this freelist. The bits would already be set because there was an existing free block on this freelist. Signed-off-by: Robert Jennings Reviewed-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/xvmalloc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/zram/xvmalloc.c b/drivers/staging/zram/xvmalloc.c index 3ed744ba7ba0..9cbe04a496e1 100644 --- a/drivers/staging/zram/xvmalloc.c +++ b/drivers/staging/zram/xvmalloc.c @@ -200,6 +200,8 @@ static void insert_block(struct xv_pool *pool, struct page *page, u32 offset, nextblock->link.prev_page = page; nextblock->link.prev_offset = offset; put_ptr_atomic(nextblock, KM_USER1); + /* If there was a next page then the free bits are set. */ + return; } __set_bit(slindex % BITS_PER_LONG, &pool->slbitmap[flindex]); -- cgit v1.2.3 From b1f5b81ebeee3974a8c793cafacace991d9a864d Mon Sep 17 00:00:00 2001 From: Robert Jennings Date: Fri, 28 Jan 2011 08:59:26 -0600 Subject: zram/xvmalloc: create CONFIG_ZRAM_DEBUG for debug code Add a debug config flag to enable debug printk output and future debug code. Signed-off-by: Robert Jennings Reviewed-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/Kconfig | 8 ++++++++ drivers/staging/zram/xvmalloc.c | 4 ++++ drivers/staging/zram/zram_drv.c | 4 ++++ 3 files changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/zram/Kconfig b/drivers/staging/zram/Kconfig index d3982e6fdb40..2f3b484ce5a4 100644 --- a/drivers/staging/zram/Kconfig +++ b/drivers/staging/zram/Kconfig @@ -15,3 +15,11 @@ config ZRAM See zram.txt for more information. Project home: http://compcache.googlecode.com/ + +config ZRAM_DEBUG + bool "Compressed RAM block device debug support" + depends on ZRAM + default n + help + This option adds additional debugging code to the compressed + RAM block device driver. diff --git a/drivers/staging/zram/xvmalloc.c b/drivers/staging/zram/xvmalloc.c index 9cbe04a496e1..4f6cb8de6865 100644 --- a/drivers/staging/zram/xvmalloc.c +++ b/drivers/staging/zram/xvmalloc.c @@ -10,6 +10,10 @@ * Released under the terms of GNU General Public License Version 2.0 */ +#ifdef CONFIG_ZRAM_DEBUG +#define DEBUG +#endif + #include #include #include diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 3c8ecab70e97..7d11c595c7d2 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -15,6 +15,10 @@ #define KMSG_COMPONENT "zram" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#ifdef CONFIG_ZRAM_DEBUG +#define DEBUG +#endif + #include #include #include -- cgit v1.2.3 From 37700965858a099d250bca531ca1c99b22c8708d Mon Sep 17 00:00:00 2001 From: Robert Jennings Date: Fri, 28 Jan 2011 09:00:03 -0600 Subject: zram/xvmalloc: Close 32byte hole on 64bit CPUs By swapping the total_pages statistic with the lock we close a hole in the structure for 64-bit CPUs. Signed-off-by: Robert Jennings Reviewed-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/xvmalloc_int.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zram/xvmalloc_int.h b/drivers/staging/zram/xvmalloc_int.h index 82a31fb99574..b5f1f7febcf6 100644 --- a/drivers/staging/zram/xvmalloc_int.h +++ b/drivers/staging/zram/xvmalloc_int.h @@ -87,12 +87,9 @@ struct block_header { struct xv_pool { ulong flbitmap; ulong slbitmap[MAX_FLI]; - spinlock_t lock; - + u64 total_pages; /* stats */ struct freelist_entry freelist[NUM_FREE_LISTS]; - - /* stats */ - u64 total_pages; + spinlock_t lock; }; #endif -- cgit v1.2.3 From 2787f959d6c5fb258d964218ac75346019f49ee9 Mon Sep 17 00:00:00 2001 From: Robert Jennings Date: Fri, 28 Jan 2011 09:00:42 -0600 Subject: zram: Return zero'd pages on new reads Currently zram will do nothing to the page in the bvec when that page has not been previously written. This allows random data to leak to user space. That can be seen by doing the following: ## Load the module and create a 256Mb zram device called /dev/zram0 # modprobe zram # echo $((256*1024*1024)) > /sys/class/block/zram0/disksize ## Initialize the device by writing zero to the first block # dd if=/dev/zero of=/dev/zram0 bs=512 count=1 ## Read ~256Mb of memory into a file and hope for something interesting # dd if=/dev/zram0 of=file This patch will treat an unwritten page as a zero-filled page. If a page is read before a write has occurred the data returned is all 0's. Signed-off-by: Robert Jennings Reviewed-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/zram_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 7d11c595c7d2..1017d6df17d1 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -237,7 +237,7 @@ static void zram_read(struct zram *zram, struct bio *bio) if (unlikely(!zram->table[index].page)) { pr_debug("Read before write: sector=%lu, size=%u", (ulong)(bio->bi_sector), bio->bi_size); - /* Do nothing */ + handle_zero_page(page); continue; } -- cgit v1.2.3 From 939b3f0b1415755d534a20f4067e6b367e1e4021 Mon Sep 17 00:00:00 2001 From: Robert Jennings Date: Fri, 28 Jan 2011 09:01:55 -0600 Subject: zram/xvmalloc: combine duplicate block delete code This patch eliminates duplicate code. The remove_block_head function is a special case of remove_block which can be contained in remove_block without confusion. The portion of code in remove_block_head which was noted as "DEBUG ONLY" is now mandatory. Doing this provides consistent management of the double linked list of blocks under a freelist and makes this consolidation of delete block code safe. The first and last blocks will have NULL pointers in their previous and next page pointers respectively. Additionally, any time a block is removed from a free list the next and previous pointers will be set to NULL to avoid misuse outside xvmalloc. Signed-off-by: Robert Jennings Reviewed-by: Pekka Enberg Acked-by: Nitin Gupta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/xvmalloc.c | 73 +++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zram/xvmalloc.c b/drivers/staging/zram/xvmalloc.c index 4f6cb8de6865..ae0623a65ab9 100644 --- a/drivers/staging/zram/xvmalloc.c +++ b/drivers/staging/zram/xvmalloc.c @@ -212,55 +212,15 @@ static void insert_block(struct xv_pool *pool, struct page *page, u32 offset, __set_bit(flindex, &pool->flbitmap); } -/* - * Remove block from head of freelist. Index 'slindex' identifies the freelist. - */ -static void remove_block_head(struct xv_pool *pool, - struct block_header *block, u32 slindex) -{ - struct block_header *tmpblock; - u32 flindex = slindex / BITS_PER_LONG; - - pool->freelist[slindex].page = block->link.next_page; - pool->freelist[slindex].offset = block->link.next_offset; - block->link.prev_page = NULL; - block->link.prev_offset = 0; - - if (!pool->freelist[slindex].page) { - __clear_bit(slindex % BITS_PER_LONG, &pool->slbitmap[flindex]); - if (!pool->slbitmap[flindex]) - __clear_bit(flindex, &pool->flbitmap); - } else { - /* - * DEBUG ONLY: We need not reinitialize freelist head previous - * pointer to 0 - we never depend on its value. But just for - * sanity, lets do it. - */ - tmpblock = get_ptr_atomic(pool->freelist[slindex].page, - pool->freelist[slindex].offset, KM_USER1); - tmpblock->link.prev_page = NULL; - tmpblock->link.prev_offset = 0; - put_ptr_atomic(tmpblock, KM_USER1); - } -} - /* * Remove block from freelist. Index 'slindex' identifies the freelist. */ static void remove_block(struct xv_pool *pool, struct page *page, u32 offset, struct block_header *block, u32 slindex) { - u32 flindex; + u32 flindex = slindex / BITS_PER_LONG; struct block_header *tmpblock; - if (pool->freelist[slindex].page == page - && pool->freelist[slindex].offset == offset) { - remove_block_head(pool, block, slindex); - return; - } - - flindex = slindex / BITS_PER_LONG; - if (block->link.prev_page) { tmpblock = get_ptr_atomic(block->link.prev_page, block->link.prev_offset, KM_USER1); @@ -276,6 +236,35 @@ static void remove_block(struct xv_pool *pool, struct page *page, u32 offset, tmpblock->link.prev_offset = block->link.prev_offset; put_ptr_atomic(tmpblock, KM_USER1); } + + /* Is this block is at the head of the freelist? */ + if (pool->freelist[slindex].page == page + && pool->freelist[slindex].offset == offset) { + + pool->freelist[slindex].page = block->link.next_page; + pool->freelist[slindex].offset = block->link.next_offset; + + if (pool->freelist[slindex].page) { + struct block_header *tmpblock; + tmpblock = get_ptr_atomic(pool->freelist[slindex].page, + pool->freelist[slindex].offset, + KM_USER1); + tmpblock->link.prev_page = NULL; + tmpblock->link.prev_offset = 0; + put_ptr_atomic(tmpblock, KM_USER1); + } else { + /* This freelist bucket is empty */ + __clear_bit(slindex % BITS_PER_LONG, + &pool->slbitmap[flindex]); + if (!pool->slbitmap[flindex]) + __clear_bit(flindex, &pool->flbitmap); + } + } + + block->link.prev_page = NULL; + block->link.prev_offset = 0; + block->link.next_page = NULL; + block->link.next_offset = 0; } /* @@ -384,7 +373,7 @@ int xv_malloc(struct xv_pool *pool, u32 size, struct page **page, block = get_ptr_atomic(*page, *offset, KM_USER0); - remove_block_head(pool, block, index); + remove_block(pool, *page, *offset, block, index); /* Split the block if required */ tmpoffset = *offset + size + XV_ALIGN; -- cgit v1.2.3 From 78fc800f06a72c25842e585fd747fa6a98f3f0e5 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:47:08 +0200 Subject: zd1211rw: use urb anchors for tx and fix tx-queue disabling When stress testing AP-mode I hit OOPS when unpluging or rmmodding driver. It appears that when tx-queue is disabled, tx-urbs might be left pending. These can cause ehci to call non-existing tx_urb_complete() (after rmmod) or uninitialized/reseted private structure (after disconnect()). Add skb queue for submitted packets and unlink pending urbs on zd_usb_disable_tx(). Part of the problem seems to be usb->free_urb_list that isn't always working as it should, causing machine freeze when trying to free the list in zd_usb_disable_tx(). Caching free urbs isn't what other drivers seem to be doing (usbnet for example) so strip free_usb_list. Patch makes tx-urb handling saner with use of urb anchors. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_usb.c | 108 +++++++++++---------------------- drivers/net/wireless/zd1211rw/zd_usb.h | 8 +-- 2 files changed, 41 insertions(+), 75 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 06041cb1c422..c32a2472eb44 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -779,19 +779,20 @@ void zd_usb_disable_tx(struct zd_usb *usb) { struct zd_usb_tx *tx = &usb->tx; unsigned long flags; - struct list_head *pos, *n; + + atomic_set(&tx->enabled, 0); + + /* kill all submitted tx-urbs */ + usb_kill_anchored_urbs(&tx->submitted); spin_lock_irqsave(&tx->lock, flags); - list_for_each_safe(pos, n, &tx->free_urb_list) { - list_del(pos); - usb_free_urb(list_entry(pos, struct urb, urb_list)); - } - tx->enabled = 0; + WARN_ON(tx->submitted_urbs != 0); tx->submitted_urbs = 0; + spin_unlock_irqrestore(&tx->lock, flags); + /* The stopped state is ignored, relying on ieee80211_wake_queues() * in a potentionally following zd_usb_enable_tx(). */ - spin_unlock_irqrestore(&tx->lock, flags); } /** @@ -807,63 +808,13 @@ void zd_usb_enable_tx(struct zd_usb *usb) struct zd_usb_tx *tx = &usb->tx; spin_lock_irqsave(&tx->lock, flags); - tx->enabled = 1; + atomic_set(&tx->enabled, 1); tx->submitted_urbs = 0; ieee80211_wake_queues(zd_usb_to_hw(usb)); tx->stopped = 0; spin_unlock_irqrestore(&tx->lock, flags); } -/** - * alloc_tx_urb - provides an tx URB - * @usb: a &struct zd_usb pointer - * - * Allocates a new URB. If possible takes the urb from the free list in - * usb->tx. - */ -static struct urb *alloc_tx_urb(struct zd_usb *usb) -{ - struct zd_usb_tx *tx = &usb->tx; - unsigned long flags; - struct list_head *entry; - struct urb *urb; - - spin_lock_irqsave(&tx->lock, flags); - if (list_empty(&tx->free_urb_list)) { - urb = usb_alloc_urb(0, GFP_ATOMIC); - goto out; - } - entry = tx->free_urb_list.next; - list_del(entry); - urb = list_entry(entry, struct urb, urb_list); -out: - spin_unlock_irqrestore(&tx->lock, flags); - return urb; -} - -/** - * free_tx_urb - frees a used tx URB - * @usb: a &struct zd_usb pointer - * @urb: URB to be freed - * - * Frees the transmission URB, which means to put it on the free URB - * list. - */ -static void free_tx_urb(struct zd_usb *usb, struct urb *urb) -{ - struct zd_usb_tx *tx = &usb->tx; - unsigned long flags; - - spin_lock_irqsave(&tx->lock, flags); - if (!tx->enabled) { - usb_free_urb(urb); - goto out; - } - list_add(&urb->urb_list, &tx->free_urb_list); -out: - spin_unlock_irqrestore(&tx->lock, flags); -} - static void tx_dec_submitted_urbs(struct zd_usb *usb) { struct zd_usb_tx *tx = &usb->tx; @@ -905,6 +856,16 @@ static void tx_urb_complete(struct urb *urb) struct sk_buff *skb; struct ieee80211_tx_info *info; struct zd_usb *usb; + struct zd_usb_tx *tx; + + skb = (struct sk_buff *)urb->context; + info = IEEE80211_SKB_CB(skb); + /* + * grab 'usb' pointer before handing off the skb (since + * it might be freed by zd_mac_tx_to_dev or mac80211) + */ + usb = &zd_hw_mac(info->rate_driver_data[0])->chip.usb; + tx = &usb->tx; switch (urb->status) { case 0: @@ -922,20 +883,15 @@ static void tx_urb_complete(struct urb *urb) goto resubmit; } free_urb: - skb = (struct sk_buff *)urb->context; - /* - * grab 'usb' pointer before handing off the skb (since - * it might be freed by zd_mac_tx_to_dev or mac80211) - */ - info = IEEE80211_SKB_CB(skb); - usb = &zd_hw_mac(info->rate_driver_data[0])->chip.usb; zd_mac_tx_to_dev(skb, urb->status); - free_tx_urb(usb, urb); + usb_free_urb(urb); tx_dec_submitted_urbs(usb); return; resubmit: + usb_anchor_urb(urb, &tx->submitted); r = usb_submit_urb(urb, GFP_ATOMIC); if (r) { + usb_unanchor_urb(urb); dev_dbg_f(urb_dev(urb), "error resubmit urb %p %d\n", urb, r); goto free_urb; } @@ -958,8 +914,14 @@ int zd_usb_tx(struct zd_usb *usb, struct sk_buff *skb) int r; struct usb_device *udev = zd_usb_to_usbdev(usb); struct urb *urb; + struct zd_usb_tx *tx = &usb->tx; - urb = alloc_tx_urb(usb); + if (!atomic_read(&tx->enabled)) { + r = -ENOENT; + goto out; + } + + urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { r = -ENOMEM; goto out; @@ -968,13 +930,16 @@ int zd_usb_tx(struct zd_usb *usb, struct sk_buff *skb) usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_DATA_OUT), skb->data, skb->len, tx_urb_complete, skb); + usb_anchor_urb(urb, &tx->submitted); r = usb_submit_urb(urb, GFP_ATOMIC); - if (r) + if (r) { + usb_unanchor_urb(urb); goto error; + } tx_inc_submitted_urbs(usb); return 0; error: - free_tx_urb(usb, urb); + usb_free_urb(urb); out: return r; } @@ -1005,9 +970,9 @@ static inline void init_usb_tx(struct zd_usb *usb) { struct zd_usb_tx *tx = &usb->tx; spin_lock_init(&tx->lock); - tx->enabled = 0; + atomic_set(&tx->enabled, 0); tx->stopped = 0; - INIT_LIST_HEAD(&tx->free_urb_list); + init_usb_anchor(&tx->submitted); tx->submitted_urbs = 0; } @@ -1240,6 +1205,7 @@ static void disconnect(struct usb_interface *intf) ieee80211_unregister_hw(hw); /* Just in case something has gone wrong! */ + zd_usb_disable_tx(usb); zd_usb_disable_rx(usb); zd_usb_disable_int(usb); diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index 1b1655cb7cb4..233ce825b71c 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h @@ -184,18 +184,18 @@ struct zd_usb_rx { /** * struct zd_usb_tx - structure used for transmitting frames + * @enabled: atomic enabled flag, indicates whether tx is enabled * @lock: lock for transmission - * @free_urb_list: list of free URBs, contains all the URBs, which can be used + * @submitted: anchor for URBs sent to device * @submitted_urbs: atomic integer that counts the URBs having sent to the * device, which haven't been completed - * @enabled: enabled flag, indicates whether tx is enabled * @stopped: indicates whether higher level tx queues are stopped */ struct zd_usb_tx { + atomic_t enabled; spinlock_t lock; - struct list_head free_urb_list; + struct usb_anchor submitted; int submitted_urbs; - int enabled; int stopped; }; -- cgit v1.2.3 From d741900d404b3a34bf478673f76ee9f16dad3f90 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:47:17 +0200 Subject: zd1211rw: cancel process_intr work on zd_chip_disable_int() OOPS if worker is running and disconnect() is called (triggered by unpluging device). Much harder to trigger at this stage but later when we have AP beacon work in process_intr it happens very easy. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_chip.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 6a9b66051cf7..b644ced848e7 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -1407,6 +1407,9 @@ void zd_chip_disable_int(struct zd_chip *chip) mutex_lock(&chip->mutex); zd_usb_disable_int(&chip->usb); mutex_unlock(&chip->mutex); + + /* cancel pending interrupt work */ + cancel_work_sync(&zd_chip_to_mac(chip)->process_intr); } int zd_chip_enable_rxtx(struct zd_chip *chip) -- cgit v1.2.3 From 8b17f75ced1d45af9faed767f4cfafb13c0fe05e Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:47:27 +0200 Subject: zd1211rw: add locking for mac->process_intr Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 6 +++++- drivers/net/wireless/zd1211rw/zd_usb.c | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 6107304cb94c..8b3d779d80dc 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -911,9 +911,13 @@ static int zd_op_config(struct ieee80211_hw *hw, u32 changed) static void zd_process_intr(struct work_struct *work) { u16 int_status; + unsigned long flags; struct zd_mac *mac = container_of(work, struct zd_mac, process_intr); - int_status = le16_to_cpu(*(__le16 *)(mac->intr_buffer+4)); + spin_lock_irqsave(&mac->lock, flags); + int_status = le16_to_cpu(*(__le16 *)(mac->intr_buffer + 4)); + spin_unlock_irqrestore(&mac->lock, flags); + if (int_status & INT_CFG_NEXT_BCN) dev_dbg_f_limit(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n"); else diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index c32a2472eb44..9493ab86a41e 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -377,8 +377,10 @@ static inline void handle_regs_int(struct urb *urb) int_num = le16_to_cpu(*(__le16 *)(urb->transfer_buffer+2)); if (int_num == CR_INTERRUPT) { struct zd_mac *mac = zd_hw_mac(zd_usb_to_hw(urb->context)); + spin_lock(&mac->lock); memcpy(&mac->intr_buffer, urb->transfer_buffer, USB_MAX_EP_INT_BUFFER); + spin_unlock(&mac->lock); schedule_work(&mac->process_intr); } else if (intr->read_regs_enabled) { intr->read_regs.length = len = urb->actual_length; -- cgit v1.2.3 From 88a1159a376995e1f9ca6e9b1d4f2e4c44d79d13 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:47:36 +0200 Subject: zd1211rw: fix beacon interval setup Vendor driver uses CR_BNC_INTERVAL at various places, one is HW_EnableBeacon() that combinies beacon interval with BSS-type flag and DTIM value in upper 16bit of u32. The other one is HW_UpdateBcnInterval() that set_aw_pt_bi() appears to be based on. HW_UpdateBcnInterval() takes interval argument as u16 and uses that for calculations, set_aw_pt_bi() uses u32 value that has flags and dtim in upper part. This clearly seems wrong. Also HW_UpdateBcnInterval() updates only lower 16bit part of CR_BNC_INTERVAL. So make set_aw_pt_bi() do calculations on only lower u16 part of s->beacon_interval. Also set 32bit beacon interval register before reading values from device, as HW_EnableBeacon() on vendor driver does. This is required to make beacon work on AP-mode, simply reading and then writing updated values is not enough at least with zd1211b. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_chip.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index b644ced848e7..447f2360b0ca 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -849,11 +849,12 @@ static int get_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s) static int set_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s) { struct zd_ioreq32 reqs[3]; + u16 b_interval = s->beacon_interval & 0xffff; - if (s->beacon_interval <= 5) - s->beacon_interval = 5; - if (s->pre_tbtt < 4 || s->pre_tbtt >= s->beacon_interval) - s->pre_tbtt = s->beacon_interval - 1; + if (b_interval <= 5) + b_interval = 5; + if (s->pre_tbtt < 4 || s->pre_tbtt >= b_interval) + s->pre_tbtt = b_interval - 1; if (s->atim_wnd_period >= s->pre_tbtt) s->atim_wnd_period = s->pre_tbtt - 1; @@ -862,7 +863,7 @@ static int set_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s) reqs[1].addr = CR_PRE_TBTT; reqs[1].value = s->pre_tbtt; reqs[2].addr = CR_BCN_INTERVAL; - reqs[2].value = s->beacon_interval; + reqs[2].value = (s->beacon_interval & ~0xffff) | b_interval; return zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs)); } @@ -874,10 +875,13 @@ static int set_beacon_interval(struct zd_chip *chip, u32 interval) struct aw_pt_bi s; ZD_ASSERT(mutex_is_locked(&chip->mutex)); + + r = zd_iowrite32_locked(chip, interval, CR_BCN_INTERVAL); + if (r) + return r; r = get_aw_pt_bi(chip, &s); if (r) return r; - s.beacon_interval = interval; return set_aw_pt_bi(chip, &s); } -- cgit v1.2.3 From a6fb071bbf420841481e1c1bcdb65b3ffb33fc8a Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:47:46 +0200 Subject: zd1211rw: move set_multicast_hash and set_rx_filter from workers to configure_filter Workers not needed anymore since configure_filter may sleep. Keep mac->multicast_hash for later use (hw reset). Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 38 +++++++--------------------------- drivers/net/wireless/zd1211rw/zd_mac.h | 2 -- 2 files changed, 7 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 8b3d779d80dc..75d9a137f318 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -927,31 +927,6 @@ static void zd_process_intr(struct work_struct *work) } -static void set_multicast_hash_handler(struct work_struct *work) -{ - struct zd_mac *mac = - container_of(work, struct zd_mac, set_multicast_hash_work); - struct zd_mc_hash hash; - - spin_lock_irq(&mac->lock); - hash = mac->multicast_hash; - spin_unlock_irq(&mac->lock); - - zd_chip_set_multicast_hash(&mac->chip, &hash); -} - -static void set_rx_filter_handler(struct work_struct *work) -{ - struct zd_mac *mac = - container_of(work, struct zd_mac, set_rx_filter_work); - int r; - - dev_dbg_f(zd_mac_dev(mac), "\n"); - r = set_rx_filter(mac); - if (r) - dev_err(zd_mac_dev(mac), "set_rx_filter_handler error %d\n", r); -} - static u64 zd_op_prepare_multicast(struct ieee80211_hw *hw, struct netdev_hw_addr_list *mc_list) { @@ -983,6 +958,7 @@ static void zd_op_configure_filter(struct ieee80211_hw *hw, }; struct zd_mac *mac = zd_hw_mac(hw); unsigned long flags; + int r; /* Only deal with supported flags */ changed_flags &= SUPPORTED_FIF_FLAGS; @@ -1004,11 +980,13 @@ static void zd_op_configure_filter(struct ieee80211_hw *hw, mac->multicast_hash = hash; spin_unlock_irqrestore(&mac->lock, flags); - /* XXX: these can be called here now, can sleep now! */ - queue_work(zd_workqueue, &mac->set_multicast_hash_work); + zd_chip_set_multicast_hash(&mac->chip, &hash); - if (changed_flags & FIF_CONTROL) - queue_work(zd_workqueue, &mac->set_rx_filter_work); + if (changed_flags & FIF_CONTROL) { + r = set_rx_filter(mac); + if (r) + dev_err(zd_mac_dev(mac), "set_rx_filter error %d\n", r); + } /* no handling required for FIF_OTHER_BSS as we don't currently * do BSSID filtering */ @@ -1164,9 +1142,7 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) zd_chip_init(&mac->chip, hw, intf); housekeeping_init(mac); - INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler); INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work); - INIT_WORK(&mac->set_rx_filter_work, set_rx_filter_handler); INIT_WORK(&mac->process_intr, zd_process_intr); SET_IEEE80211_DEV(hw, &intf->dev); diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index a6d86b996c79..f28ecb94c2a4 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h @@ -173,9 +173,7 @@ struct zd_mac { spinlock_t intr_lock; struct ieee80211_hw *hw; struct housekeeping housekeeping; - struct work_struct set_multicast_hash_work; struct work_struct set_rts_cts_work; - struct work_struct set_rx_filter_work; struct work_struct process_intr; struct zd_mc_hash multicast_hash; u8 intr_buffer[USB_MAX_EP_INT_BUFFER]; -- cgit v1.2.3 From 5cf6cf819bfffd89fc8c7c3a7406f54da4945a34 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:47:56 +0200 Subject: zd1211rw: move set_rts_cts_work to bss_info_changed As bss_info_changed may sleep, we can as well set RTS_CTS register right away. Keep mac->short_preamble for later use (hw reset). Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 27 +++++---------------------- drivers/net/wireless/zd1211rw/zd_mac.h | 3 --- 2 files changed, 5 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 75d9a137f318..487ed33e951d 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -998,20 +998,9 @@ static void zd_op_configure_filter(struct ieee80211_hw *hw, * time. */ } -static void set_rts_cts_work(struct work_struct *work) +static void set_rts_cts(struct zd_mac *mac, unsigned int short_preamble) { - struct zd_mac *mac = - container_of(work, struct zd_mac, set_rts_cts_work); - unsigned long flags; - unsigned int short_preamble; - mutex_lock(&mac->chip.mutex); - - spin_lock_irqsave(&mac->lock, flags); - mac->updating_rts_rate = 0; - short_preamble = mac->short_preamble; - spin_unlock_irqrestore(&mac->lock, flags); - zd_chip_set_rts_cts_rate_locked(&mac->chip, short_preamble); mutex_unlock(&mac->chip.mutex); } @@ -1022,7 +1011,6 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw, u32 changes) { struct zd_mac *mac = zd_hw_mac(hw); - unsigned long flags; int associated; dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes); @@ -1060,15 +1048,11 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw, /* TODO: do hardware bssid filtering */ if (changes & BSS_CHANGED_ERP_PREAMBLE) { - spin_lock_irqsave(&mac->lock, flags); + spin_lock_irq(&mac->lock); mac->short_preamble = bss_conf->use_short_preamble; - if (!mac->updating_rts_rate) { - mac->updating_rts_rate = 1; - /* FIXME: should disable TX here, until work has - * completed and RTS_CTS reg is updated */ - queue_work(zd_workqueue, &mac->set_rts_cts_work); - } - spin_unlock_irqrestore(&mac->lock, flags); + spin_unlock_irq(&mac->lock); + + set_rts_cts(mac, bss_conf->use_short_preamble); } } @@ -1142,7 +1126,6 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) zd_chip_init(&mac->chip, hw, intf); housekeeping_init(mac); - INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work); INIT_WORK(&mac->process_intr, zd_process_intr); SET_IEEE80211_DEV(hw, &intf->dev); diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index f28ecb94c2a4..ff7ef30372a1 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h @@ -189,9 +189,6 @@ struct zd_mac { /* Short preamble (used for RTS/CTS) */ unsigned int short_preamble:1; - /* flags to indicate update in progress */ - unsigned int updating_rts_rate:1; - /* whether to pass frames with CRC errors to stack */ unsigned int pass_failed_fcs:1; -- cgit v1.2.3 From c2fadcb3b16b294d7de509c42f1390f672510667 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:48:06 +0200 Subject: zd1211rw: support setting BSSID for AP mode Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_chip.c | 39 ++++++++++++++++++++++++--------- drivers/net/wireless/zd1211rw/zd_chip.h | 1 + drivers/net/wireless/zd1211rw/zd_mac.c | 25 ++++++++++++++++++++- drivers/net/wireless/zd1211rw/zd_mac.h | 1 + 4 files changed, 55 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 447f2360b0ca..71d3cdebca14 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -370,16 +370,12 @@ error: return r; } -/* MAC address: if custom mac addresses are to be used CR_MAC_ADDR_P1 and - * CR_MAC_ADDR_P2 must be overwritten - */ -int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr) +static int zd_write_mac_addr_common(struct zd_chip *chip, const u8 *mac_addr, + const struct zd_ioreq32 *in_reqs, + const char *type) { int r; - struct zd_ioreq32 reqs[2] = { - [0] = { .addr = CR_MAC_ADDR_P1 }, - [1] = { .addr = CR_MAC_ADDR_P2 }, - }; + struct zd_ioreq32 reqs[2] = {in_reqs[0], in_reqs[1]}; if (mac_addr) { reqs[0].value = (mac_addr[3] << 24) @@ -388,9 +384,9 @@ int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr) | mac_addr[0]; reqs[1].value = (mac_addr[5] << 8) | mac_addr[4]; - dev_dbg_f(zd_chip_dev(chip), "mac addr %pM\n", mac_addr); + dev_dbg_f(zd_chip_dev(chip), "%s addr %pM\n", type, mac_addr); } else { - dev_dbg_f(zd_chip_dev(chip), "set NULL mac\n"); + dev_dbg_f(zd_chip_dev(chip), "set NULL %s\n", type); } mutex_lock(&chip->mutex); @@ -399,6 +395,29 @@ int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr) return r; } +/* MAC address: if custom mac addresses are to be used CR_MAC_ADDR_P1 and + * CR_MAC_ADDR_P2 must be overwritten + */ +int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr) +{ + static const struct zd_ioreq32 reqs[2] = { + [0] = { .addr = CR_MAC_ADDR_P1 }, + [1] = { .addr = CR_MAC_ADDR_P2 }, + }; + + return zd_write_mac_addr_common(chip, mac_addr, reqs, "mac"); +} + +int zd_write_bssid(struct zd_chip *chip, const u8 *bssid) +{ + static const struct zd_ioreq32 reqs[2] = { + [0] = { .addr = CR_BSSID_P1 }, + [1] = { .addr = CR_BSSID_P2 }, + }; + + return zd_write_mac_addr_common(chip, bssid, reqs, "bssid"); +} + int zd_read_regdomain(struct zd_chip *chip, u8 *regdomain) { int r; diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index f8bbf7d302ae..7b0c58ce7056 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h @@ -881,6 +881,7 @@ static inline u8 _zd_chip_get_channel(struct zd_chip *chip) u8 zd_chip_get_channel(struct zd_chip *chip); int zd_read_regdomain(struct zd_chip *chip, u8 *regdomain); int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr); +int zd_write_bssid(struct zd_chip *chip, const u8 *bssid); int zd_chip_switch_radio_on(struct zd_chip *chip); int zd_chip_switch_radio_off(struct zd_chip *chip); int zd_chip_enable_int(struct zd_chip *chip); diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 487ed33e951d..ab0d1b9a08ec 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -231,6 +231,26 @@ static int set_rx_filter(struct zd_mac *mac) return zd_iowrite32(&mac->chip, CR_RX_FILTER, filter); } +static int set_mac_and_bssid(struct zd_mac *mac) +{ + int r; + + if (!mac->vif) + return -1; + + r = zd_write_mac_addr(&mac->chip, mac->vif->addr); + if (r) + return r; + + /* Vendor driver after setting MAC either sets BSSID for AP or + * filter for other modes. + */ + if (mac->type != NL80211_IFTYPE_AP) + return set_rx_filter(mac); + else + return zd_write_bssid(&mac->chip, mac->vif->addr); +} + static int set_mc_hash(struct zd_mac *mac) { struct zd_mc_hash hash; @@ -888,7 +908,9 @@ static int zd_op_add_interface(struct ieee80211_hw *hw, return -EOPNOTSUPP; } - return zd_write_mac_addr(&mac->chip, vif->addr); + mac->vif = vif; + + return set_mac_and_bssid(mac); } static void zd_op_remove_interface(struct ieee80211_hw *hw, @@ -896,6 +918,7 @@ static void zd_op_remove_interface(struct ieee80211_hw *hw, { struct zd_mac *mac = zd_hw_mac(hw); mac->type = NL80211_IFTYPE_UNSPECIFIED; + mac->vif = NULL; zd_set_beacon_interval(&mac->chip, 0); zd_write_mac_addr(&mac->chip, NULL); } diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index ff7ef30372a1..0ec6bde0b37c 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h @@ -172,6 +172,7 @@ struct zd_mac { spinlock_t lock; spinlock_t intr_lock; struct ieee80211_hw *hw; + struct ieee80211_vif *vif; struct housekeeping housekeeping; struct work_struct set_rts_cts_work; struct work_struct process_intr; -- cgit v1.2.3 From f773e409b959677170b3cf1d573dafc4a0a3e34e Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:48:16 +0200 Subject: zd1211rw: fix ack_pending in filter_ack causing tx-packet ordering problem on monitor For reasons not very clear yet to me, filter_ack leaves matching tx-packet pending with 'ack_pending'. This causes tx-packet to be passed back to upper layer after next packet has been transfered and tx-packets might end up coming come out of monitor interface in wrong order vs. rx. Because of this when enable AP-mode, hostapd monitor interface would get packets in wrong order causing problems in WPA association. So don't use mac->ack_pending when in AP-mode. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index ab0d1b9a08ec..84ac95eb59fa 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -799,6 +799,13 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, mac->ack_pending = 1; mac->ack_signal = stats->signal; + + /* Prevent pending tx-packet on AP-mode */ + if (mac->type == NL80211_IFTYPE_AP) { + skb = __skb_dequeue(q); + zd_mac_tx_status(hw, skb, mac->ack_signal, NULL); + mac->ack_pending = 0; + } } spin_unlock_irqrestore(&q->lock, flags); -- cgit v1.2.3 From b91a515dbb4f824169755e071014230b57f0c1e1 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:48:25 +0200 Subject: zd1211rw: let zd_set_beacon_interval() set dtim_period and add AP-beacon flag Add support for AP-mode beacon. Also disable beacon when interface is set down as otherwise hw will keep flooding NEXT_BCN interrupts. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_chip.c | 33 ++++++++++++++++++++++++++++----- drivers/net/wireless/zd1211rw/zd_chip.h | 4 +++- drivers/net/wireless/zd1211rw/zd_mac.c | 17 +++++++++-------- 3 files changed, 40 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 71d3cdebca14..d8dc92711f40 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -888,14 +888,36 @@ static int set_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s) } -static int set_beacon_interval(struct zd_chip *chip, u32 interval) +static int set_beacon_interval(struct zd_chip *chip, u16 interval, + u8 dtim_period, int type) { int r; struct aw_pt_bi s; + u32 b_interval, mode_flag; ZD_ASSERT(mutex_is_locked(&chip->mutex)); - r = zd_iowrite32_locked(chip, interval, CR_BCN_INTERVAL); + if (interval > 0) { + switch (type) { + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_MESH_POINT: + mode_flag = BCN_MODE_IBSS; + break; + case NL80211_IFTYPE_AP: + mode_flag = BCN_MODE_AP; + break; + default: + mode_flag = 0; + break; + } + } else { + dtim_period = 0; + mode_flag = 0; + } + + b_interval = mode_flag | (dtim_period << 16) | interval; + + r = zd_iowrite32_locked(chip, b_interval, CR_BCN_INTERVAL); if (r) return r; r = get_aw_pt_bi(chip, &s); @@ -904,12 +926,13 @@ static int set_beacon_interval(struct zd_chip *chip, u32 interval) return set_aw_pt_bi(chip, &s); } -int zd_set_beacon_interval(struct zd_chip *chip, u32 interval) +int zd_set_beacon_interval(struct zd_chip *chip, u16 interval, u8 dtim_period, + int type) { int r; mutex_lock(&chip->mutex); - r = set_beacon_interval(chip, interval); + r = set_beacon_interval(chip, interval, dtim_period, type); mutex_unlock(&chip->mutex); return r; } @@ -928,7 +951,7 @@ static int hw_init(struct zd_chip *chip) if (r) return r; - return set_beacon_interval(chip, 100); + return set_beacon_interval(chip, 100, 0, NL80211_IFTYPE_UNSPECIFIED); } static zd_addr_t fw_reg_addr(struct zd_chip *chip, u16 offset) diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index 7b0c58ce7056..14e4402a6111 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h @@ -546,6 +546,7 @@ enum { #define RX_FILTER_CTRL (RX_FILTER_RTS | RX_FILTER_CTS | \ RX_FILTER_CFEND | RX_FILTER_CFACK) +#define BCN_MODE_AP 0x1000000 #define BCN_MODE_IBSS 0x2000000 /* Monitor mode sets filter to 0xfffff */ @@ -921,7 +922,8 @@ enum led_status { int zd_chip_control_leds(struct zd_chip *chip, enum led_status status); -int zd_set_beacon_interval(struct zd_chip *chip, u32 interval); +int zd_set_beacon_interval(struct zd_chip *chip, u16 interval, u8 dtim_period, + int type); static inline int zd_get_beacon_interval(struct zd_chip *chip, u32 *interval) { diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 84ac95eb59fa..1bd275bc6084 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -926,7 +926,7 @@ static void zd_op_remove_interface(struct ieee80211_hw *hw, struct zd_mac *mac = zd_hw_mac(hw); mac->type = NL80211_IFTYPE_UNSPECIFIED; mac->vif = NULL; - zd_set_beacon_interval(&mac->chip, 0); + zd_set_beacon_interval(&mac->chip, 0, 0, NL80211_IFTYPE_UNSPECIFIED); zd_write_mac_addr(&mac->chip, NULL); } @@ -1058,15 +1058,16 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw, } if (changes & BSS_CHANGED_BEACON_ENABLED) { - u32 interval; + u16 interval = 0; + u8 period = 0; - if (bss_conf->enable_beacon) - interval = BCN_MODE_IBSS | - bss_conf->beacon_int; - else - interval = 0; + if (bss_conf->enable_beacon) { + period = bss_conf->dtim_period; + interval = bss_conf->beacon_int; + } - zd_set_beacon_interval(&mac->chip, interval); + zd_set_beacon_interval(&mac->chip, interval, period, + mac->type); } } else associated = is_valid_ether_addr(bss_conf->bssid); -- cgit v1.2.3 From 4099e2f4404762add8ef2b0dadef3c5122117210 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:48:35 +0200 Subject: zd1211rw: implement beacon fetching and handling ieee80211_get_buffered_bc() Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 39 ++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 1bd275bc6084..49ab3c357100 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -938,6 +938,34 @@ static int zd_op_config(struct ieee80211_hw *hw, u32 changed) return zd_chip_set_channel(&mac->chip, conf->channel->hw_value); } +static void zd_beacon_done(struct zd_mac *mac) +{ + struct sk_buff *skb, *beacon; + + if (!mac->vif || mac->vif->type != NL80211_IFTYPE_AP) + return; + + /* + * Send out buffered broad- and multicast frames. + */ + while (!ieee80211_queue_stopped(mac->hw, 0)) { + skb = ieee80211_get_buffered_bc(mac->hw, mac->vif); + if (!skb) + break; + zd_op_tx(mac->hw, skb); + } + + /* + * Fetch next beacon so that tim_count is updated. + */ + beacon = ieee80211_beacon_get(mac->hw, mac->vif); + if (!beacon) + return; + + zd_mac_config_beacon(mac->hw, beacon); + kfree_skb(beacon); +} + static void zd_process_intr(struct work_struct *work) { u16 int_status; @@ -948,10 +976,12 @@ static void zd_process_intr(struct work_struct *work) int_status = le16_to_cpu(*(__le16 *)(mac->intr_buffer + 4)); spin_unlock_irqrestore(&mac->lock, flags); - if (int_status & INT_CFG_NEXT_BCN) - dev_dbg_f_limit(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n"); - else + if (int_status & INT_CFG_NEXT_BCN) { + /*dev_dbg_f_limit(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");*/ + zd_beacon_done(mac); + } else { dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n"); + } zd_chip_enable_hwint(&mac->chip); } @@ -1135,7 +1165,8 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band; hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_SIGNAL_UNSPEC; + IEEE80211_HW_SIGNAL_UNSPEC | + IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_MESH_POINT) | -- cgit v1.2.3 From 9be232563666b7d1bd424780aef7ee2aa261ba04 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:48:55 +0200 Subject: zd1211rw: add beacon watchdog and setting HW beacon more failsafe When doing tx/rx at high packet rate (for example simply using ping -f), device starts to fail to respond to control messages. On non-AP modes this only causes problems for LED updating code but when we are running in AP-mode we are writing new beacon to HW usually every 100ms. Now if control message fails in HW beacon setup, device lock is kept locked and beacon data partially written. This can and usually does cause: 1. HW beacon setup fail now on, as driver cannot acquire device lock. 2. Beacon-done interrupt stop working as device has incomplete beacon. Therefore make zd_mac_config_beacon() always try to release device lock and add beacon watchdog to restart beaconing when stall is detected. Also fix zd_mac_config_beacon() try acquiring device lock for max 500ms, as what old code appeared to be trying to do using loop and msleep(1). Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 188 +++++++++++++++++++++++++++------ drivers/net/wireless/zd1211rw/zd_mac.h | 13 +++ 2 files changed, 170 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 49ab3c357100..78c8f8ba50f6 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -138,6 +138,9 @@ static const struct ieee80211_channel zd_channels[] = { static void housekeeping_init(struct zd_mac *mac); static void housekeeping_enable(struct zd_mac *mac); static void housekeeping_disable(struct zd_mac *mac); +static void beacon_init(struct zd_mac *mac); +static void beacon_enable(struct zd_mac *mac); +static void beacon_disable(struct zd_mac *mac); static int zd_reg2alpha2(u8 regdomain, char *alpha2) { @@ -295,6 +298,8 @@ static int zd_op_start(struct ieee80211_hw *hw) goto disable_rxtx; housekeeping_enable(mac); + beacon_enable(mac); + set_bit(ZD_DEVICE_RUNNING, &mac->flags); return 0; disable_rxtx: zd_chip_disable_rxtx(chip); @@ -313,12 +318,15 @@ static void zd_op_stop(struct ieee80211_hw *hw) struct sk_buff *skb; struct sk_buff_head *ack_wait_queue = &mac->ack_wait_queue; + clear_bit(ZD_DEVICE_RUNNING, &mac->flags); + /* The order here deliberately is a little different from the open() * method, since we need to make sure there is no opportunity for RX * frames to be processed by mac80211 after we have stopped it. */ zd_chip_disable_rxtx(chip); + beacon_disable(mac); housekeeping_disable(mac); flush_workqueue(zd_workqueue); @@ -594,64 +602,99 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) { struct zd_mac *mac = zd_hw_mac(hw); - int r; + int r, ret; u32 tmp, j = 0; /* 4 more bytes for tail CRC */ u32 full_len = beacon->len + 4; + unsigned long end_jiffies, message_jiffies; + + mutex_lock(&mac->chip.mutex); - r = zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 0); + r = zd_iowrite32_locked(&mac->chip, 0, CR_BCN_FIFO_SEMAPHORE); if (r < 0) - return r; - r = zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp); + goto out; + r = zd_ioread32_locked(&mac->chip, &tmp, CR_BCN_FIFO_SEMAPHORE); if (r < 0) - return r; + goto release_sema; + end_jiffies = jiffies + HZ / 2; /*~500ms*/ + message_jiffies = jiffies + HZ / 10; /*~100ms*/ while (tmp & 0x2) { - r = zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp); + r = zd_ioread32_locked(&mac->chip, &tmp, CR_BCN_FIFO_SEMAPHORE); if (r < 0) - return r; - if ((++j % 100) == 0) { - printk(KERN_ERR "CR_BCN_FIFO_SEMAPHORE not ready\n"); - if (j >= 500) { - printk(KERN_ERR "Giving up beacon config.\n"); - return -ETIMEDOUT; + goto release_sema; + if (time_is_before_eq_jiffies(message_jiffies)) { + message_jiffies = jiffies + HZ / 10; + dev_err(zd_mac_dev(mac), + "CR_BCN_FIFO_SEMAPHORE not ready\n"); + if (time_is_before_eq_jiffies(end_jiffies)) { + dev_err(zd_mac_dev(mac), + "Giving up beacon config.\n"); + r = -ETIMEDOUT; + goto release_sema; } } - msleep(1); + msleep(20); } - r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, full_len - 1); + r = zd_iowrite32_locked(&mac->chip, full_len - 1, CR_BCN_FIFO); if (r < 0) - return r; + goto release_sema; if (zd_chip_is_zd1211b(&mac->chip)) { - r = zd_iowrite32(&mac->chip, CR_BCN_LENGTH, full_len - 1); + r = zd_iowrite32_locked(&mac->chip, full_len - 1, + CR_BCN_LENGTH); if (r < 0) - return r; + goto release_sema; } for (j = 0 ; j < beacon->len; j++) { - r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, - *((u8 *)(beacon->data + j))); + r = zd_iowrite32_locked(&mac->chip, *((u8 *)(beacon->data + j)), + CR_BCN_FIFO); if (r < 0) - return r; + goto release_sema; } for (j = 0; j < 4; j++) { - r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, 0x0); + r = zd_iowrite32_locked(&mac->chip, 0x0, CR_BCN_FIFO); if (r < 0) - return r; + goto release_sema; } - r = zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 1); - if (r < 0) - return r; +release_sema: + /* + * Try very hard to release device beacon semaphore, as otherwise + * device/driver can be left in unusable state. + */ + end_jiffies = jiffies + HZ / 2; /*~500ms*/ + ret = zd_iowrite32_locked(&mac->chip, 1, CR_BCN_FIFO_SEMAPHORE); + while (ret < 0) { + if (time_is_before_eq_jiffies(end_jiffies)) { + ret = -ETIMEDOUT; + break; + } + + msleep(20); + ret = zd_iowrite32_locked(&mac->chip, 1, CR_BCN_FIFO_SEMAPHORE); + } + + if (ret < 0) + dev_err(zd_mac_dev(mac), "Could not release " + "CR_BCN_FIFO_SEMAPHORE!\n"); + if (r < 0 || ret < 0) { + if (r >= 0) + r = ret; + goto out; + } /* 802.11b/g 2.4G CCK 1Mb * 802.11a, not yet implemented, uses different values (see GPL vendor * driver) */ - return zd_iowrite32(&mac->chip, CR_BCN_PLCP_CFG, 0x00000400 | - (full_len << 19)); + r = zd_iowrite32_locked(&mac->chip, 0x00000400 | (full_len << 19), + CR_BCN_PLCP_CFG); +out: + mutex_unlock(&mac->chip.mutex); + return r; } static int fill_ctrlset(struct zd_mac *mac, @@ -942,6 +985,8 @@ static void zd_beacon_done(struct zd_mac *mac) { struct sk_buff *skb, *beacon; + if (!test_bit(ZD_DEVICE_RUNNING, &mac->flags)) + return; if (!mac->vif || mac->vif->type != NL80211_IFTYPE_AP) return; @@ -959,11 +1004,14 @@ static void zd_beacon_done(struct zd_mac *mac) * Fetch next beacon so that tim_count is updated. */ beacon = ieee80211_beacon_get(mac->hw, mac->vif); - if (!beacon) - return; + if (beacon) { + zd_mac_config_beacon(mac->hw, beacon); + kfree_skb(beacon); + } - zd_mac_config_beacon(mac->hw, beacon); - kfree_skb(beacon); + spin_lock_irq(&mac->lock); + mac->beacon.last_update = jiffies; + spin_unlock_irq(&mac->lock); } static void zd_process_intr(struct work_struct *work) @@ -1082,7 +1130,9 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw, struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); if (beacon) { + zd_chip_disable_hwint(&mac->chip); zd_mac_config_beacon(hw, beacon); + zd_chip_enable_hwint(&mac->chip); kfree_skb(beacon); } } @@ -1096,6 +1146,12 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw, interval = bss_conf->beacon_int; } + spin_lock_irq(&mac->lock); + mac->beacon.period = period; + mac->beacon.interval = interval; + mac->beacon.last_update = jiffies; + spin_unlock_irq(&mac->lock); + zd_set_beacon_interval(&mac->chip, interval, period, mac->type); } @@ -1188,12 +1244,82 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) zd_chip_init(&mac->chip, hw, intf); housekeeping_init(mac); + beacon_init(mac); INIT_WORK(&mac->process_intr, zd_process_intr); SET_IEEE80211_DEV(hw, &intf->dev); return hw; } +#define BEACON_WATCHDOG_DELAY round_jiffies_relative(HZ) + +static void beacon_watchdog_handler(struct work_struct *work) +{ + struct zd_mac *mac = + container_of(work, struct zd_mac, beacon.watchdog_work.work); + struct sk_buff *beacon; + unsigned long timeout; + int interval, period; + + if (!test_bit(ZD_DEVICE_RUNNING, &mac->flags)) + goto rearm; + if (mac->type != NL80211_IFTYPE_AP || !mac->vif) + goto rearm; + + spin_lock_irq(&mac->lock); + interval = mac->beacon.interval; + period = mac->beacon.period; + timeout = mac->beacon.last_update + msecs_to_jiffies(interval) + HZ; + spin_unlock_irq(&mac->lock); + + if (interval > 0 && time_is_before_jiffies(timeout)) { + dev_dbg_f(zd_mac_dev(mac), "beacon interrupt stalled, " + "restarting. " + "(interval: %d, dtim: %d)\n", + interval, period); + + zd_chip_disable_hwint(&mac->chip); + + beacon = ieee80211_beacon_get(mac->hw, mac->vif); + if (beacon) { + zd_mac_config_beacon(mac->hw, beacon); + kfree_skb(beacon); + } + + zd_set_beacon_interval(&mac->chip, interval, period, mac->type); + + zd_chip_enable_hwint(&mac->chip); + + spin_lock_irq(&mac->lock); + mac->beacon.last_update = jiffies; + spin_unlock_irq(&mac->lock); + } + +rearm: + queue_delayed_work(zd_workqueue, &mac->beacon.watchdog_work, + BEACON_WATCHDOG_DELAY); +} + +static void beacon_init(struct zd_mac *mac) +{ + INIT_DELAYED_WORK(&mac->beacon.watchdog_work, beacon_watchdog_handler); +} + +static void beacon_enable(struct zd_mac *mac) +{ + dev_dbg_f(zd_mac_dev(mac), "\n"); + + mac->beacon.last_update = jiffies; + queue_delayed_work(zd_workqueue, &mac->beacon.watchdog_work, + BEACON_WATCHDOG_DELAY); +} + +static void beacon_disable(struct zd_mac *mac) +{ + dev_dbg_f(zd_mac_dev(mac), "\n"); + cancel_delayed_work_sync(&mac->beacon.watchdog_work); +} + #define LINK_LED_WORK_DELAY HZ static void link_led_handler(struct work_struct *work) diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index 0ec6bde0b37c..281b3079311a 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h @@ -163,6 +163,17 @@ struct housekeeping { struct delayed_work link_led_work; }; +struct beacon { + struct delayed_work watchdog_work; + unsigned long last_update; + u16 interval; + u8 period; +}; + +enum zd_device_flags { + ZD_DEVICE_RUNNING, +}; + #define ZD_MAC_STATS_BUFFER_SIZE 16 #define ZD_MAC_MAX_ACK_WAITERS 50 @@ -174,6 +185,7 @@ struct zd_mac { struct ieee80211_hw *hw; struct ieee80211_vif *vif; struct housekeeping housekeeping; + struct beacon beacon; struct work_struct set_rts_cts_work; struct work_struct process_intr; struct zd_mc_hash multicast_hash; @@ -182,6 +194,7 @@ struct zd_mac { u8 default_regdomain; int type; int associated; + unsigned long flags; struct sk_buff_head ack_wait_queue; struct ieee80211_channel channels[14]; struct ieee80211_rate rates[12]; -- cgit v1.2.3 From 51272292926bc4fff61ba812d5816922b980655b Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:49:05 +0200 Subject: zd1211rw: batch beacon config commands together Beacon config function writes beacon to hw one write per byte. This is very slow (usually taking more than 100ms to finish) and causes high CPU usage when in AP-mode (kworker at ~50% on Intel Atom N270). By batching commands together zd_mac_config_beacon() runtime can be lowered to 1/5th and lower CPU usage to saner levels (<10% on Atom). Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 40 +++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 78c8f8ba50f6..84ee1b886912 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -602,11 +602,18 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) { struct zd_mac *mac = zd_hw_mac(hw); - int r, ret; + int r, ret, num_cmds, req_pos = 0; u32 tmp, j = 0; /* 4 more bytes for tail CRC */ u32 full_len = beacon->len + 4; unsigned long end_jiffies, message_jiffies; + struct zd_ioreq32 *ioreqs; + + /* Alloc memory for full beacon write at once. */ + num_cmds = 1 + zd_chip_is_zd1211b(&mac->chip) + full_len; + ioreqs = kmalloc(num_cmds * sizeof(struct zd_ioreq32), GFP_KERNEL); + if (!ioreqs) + return -ENOMEM; mutex_lock(&mac->chip.mutex); @@ -637,29 +644,31 @@ static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) msleep(20); } - r = zd_iowrite32_locked(&mac->chip, full_len - 1, CR_BCN_FIFO); - if (r < 0) - goto release_sema; + ioreqs[req_pos].addr = CR_BCN_FIFO; + ioreqs[req_pos].value = full_len - 1; + req_pos++; if (zd_chip_is_zd1211b(&mac->chip)) { - r = zd_iowrite32_locked(&mac->chip, full_len - 1, - CR_BCN_LENGTH); - if (r < 0) - goto release_sema; + ioreqs[req_pos].addr = CR_BCN_LENGTH; + ioreqs[req_pos].value = full_len - 1; + req_pos++; } for (j = 0 ; j < beacon->len; j++) { - r = zd_iowrite32_locked(&mac->chip, *((u8 *)(beacon->data + j)), - CR_BCN_FIFO); - if (r < 0) - goto release_sema; + ioreqs[req_pos].addr = CR_BCN_FIFO; + ioreqs[req_pos].value = *((u8 *)(beacon->data + j)); + req_pos++; } for (j = 0; j < 4; j++) { - r = zd_iowrite32_locked(&mac->chip, 0x0, CR_BCN_FIFO); - if (r < 0) - goto release_sema; + ioreqs[req_pos].addr = CR_BCN_FIFO; + ioreqs[req_pos].value = 0x0; + req_pos++; } + BUG_ON(req_pos != num_cmds); + + r = zd_iowrite32a_locked(&mac->chip, ioreqs, num_cmds); + release_sema: /* * Try very hard to release device beacon semaphore, as otherwise @@ -694,6 +703,7 @@ release_sema: CR_BCN_PLCP_CFG); out: mutex_unlock(&mac->chip.mutex); + kfree(ioreqs); return r; } -- cgit v1.2.3 From 9bca0c3b540188e2beea9c2583fa16c46d209888 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:49:14 +0200 Subject: zd1211rw: use stack and preallocated memory for small cmd-buffers Use stack for allocing small < 64 byte arrays in zd_chip.c and preallocated buffer in zd_usb.c. This might lower CPU usage for beacon setup. v2: - Do not use stack buffers in zd_usb.c as they would be used for urb transfer_buffer. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_chip.c | 43 ++++++++++----------------------- drivers/net/wireless/zd1211rw/zd_usb.c | 41 ++++++++++++++++++++----------- drivers/net/wireless/zd1211rw/zd_usb.h | 1 + 3 files changed, 41 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index d8dc92711f40..907e6562cb59 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -108,25 +108,17 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr { int r; int i; - zd_addr_t *a16; - u16 *v16; + zd_addr_t a16[USB_MAX_IOREAD32_COUNT * 2]; + u16 v16[USB_MAX_IOREAD32_COUNT * 2]; unsigned int count16; if (count > USB_MAX_IOREAD32_COUNT) return -EINVAL; - /* Allocate a single memory block for values and addresses. */ - count16 = 2*count; - /* zd_addr_t is __nocast, so the kmalloc needs an explicit cast */ - a16 = (zd_addr_t *) kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)), - GFP_KERNEL); - if (!a16) { - dev_dbg_f(zd_chip_dev(chip), - "error ENOMEM in allocation of a16\n"); - r = -ENOMEM; - goto out; - } - v16 = (u16 *)(a16 + count16); + /* Use stack for values and addresses. */ + count16 = 2 * count; + BUG_ON(count16 * sizeof(zd_addr_t) > sizeof(a16)); + BUG_ON(count16 * sizeof(u16) > sizeof(v16)); for (i = 0; i < count; i++) { int j = 2*i; @@ -139,7 +131,7 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr if (r) { dev_dbg_f(zd_chip_dev(chip), "error: zd_ioread16v_locked. Error number %d\n", r); - goto out; + return r; } for (i = 0; i < count; i++) { @@ -147,18 +139,18 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr values[i] = (v16[j] << 16) | v16[j+1]; } -out: - kfree((void *)a16); - return r; + return 0; } int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, unsigned int count) { int i, j, r; - struct zd_ioreq16 *ioreqs16; + struct zd_ioreq16 ioreqs16[USB_MAX_IOWRITE32_COUNT * 2]; unsigned int count16; + /* Use stack for values and addresses. */ + ZD_ASSERT(mutex_is_locked(&chip->mutex)); if (count == 0) @@ -166,15 +158,8 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, if (count > USB_MAX_IOWRITE32_COUNT) return -EINVAL; - /* Allocate a single memory block for values and addresses. */ - count16 = 2*count; - ioreqs16 = kmalloc(count16 * sizeof(struct zd_ioreq16), GFP_KERNEL); - if (!ioreqs16) { - r = -ENOMEM; - dev_dbg_f(zd_chip_dev(chip), - "error %d in ioreqs16 allocation\n", r); - goto out; - } + count16 = 2 * count; + BUG_ON(count16 * sizeof(struct zd_ioreq16) > sizeof(ioreqs16)); for (i = 0; i < count; i++) { j = 2*i; @@ -192,8 +177,6 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, "error %d in zd_usb_write16v\n", r); } #endif /* DEBUG */ -out: - kfree(ioreqs16); return r; } diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 9493ab86a41e..bf1de04dc9f2 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -1361,15 +1361,20 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, return -EWOULDBLOCK; } if (!usb_int_enabled(usb)) { - dev_dbg_f(zd_usb_dev(usb), + dev_dbg_f(zd_usb_dev(usb), "error: usb interrupt not enabled\n"); return -EWOULDBLOCK; } + ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); + BUILD_BUG_ON(sizeof(struct usb_req_read_regs) + USB_MAX_IOREAD16_COUNT * + sizeof(__le16) > sizeof(usb->req_buf)); + BUG_ON(sizeof(struct usb_req_read_regs) + count * sizeof(__le16) > + sizeof(usb->req_buf)); + req_len = sizeof(struct usb_req_read_regs) + count * sizeof(__le16); - req = kmalloc(req_len, GFP_KERNEL); - if (!req) - return -ENOMEM; + req = (void *)usb->req_buf; + req->id = cpu_to_le16(USB_REQ_READ_REGS); for (i = 0; i < count; i++) req->addr[i] = cpu_to_le16((u16)addresses[i]); @@ -1402,7 +1407,6 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, r = get_results(usb, values, req, count); error: - kfree(req); return r; } @@ -1428,11 +1432,17 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, return -EWOULDBLOCK; } + ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); + BUILD_BUG_ON(sizeof(struct usb_req_write_regs) + + USB_MAX_IOWRITE16_COUNT * sizeof(struct reg_data) > + sizeof(usb->req_buf)); + BUG_ON(sizeof(struct usb_req_write_regs) + + count * sizeof(struct reg_data) > + sizeof(usb->req_buf)); + req_len = sizeof(struct usb_req_write_regs) + count * sizeof(struct reg_data); - req = kmalloc(req_len, GFP_KERNEL); - if (!req) - return -ENOMEM; + req = (void *)usb->req_buf; req->id = cpu_to_le16(USB_REQ_WRITE_REGS); for (i = 0; i < count; i++) { @@ -1460,7 +1470,6 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, /* FALL-THROUGH with r == 0 */ error: - kfree(req); return r; } @@ -1505,14 +1514,19 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits) if (r) { dev_dbg_f(zd_usb_dev(usb), "error %d: Couldn't read CR203\n", r); - goto out; + return r; } bit_value_template &= ~(RF_IF_LE|RF_CLK|RF_DATA); + ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); + BUILD_BUG_ON(sizeof(struct usb_req_rfwrite) + + USB_MAX_RFWRITE_BIT_COUNT * sizeof(__le16) > + sizeof(usb->req_buf)); + BUG_ON(sizeof(struct usb_req_rfwrite) + bits * sizeof(__le16) > + sizeof(usb->req_buf)); + req_len = sizeof(struct usb_req_rfwrite) + bits * sizeof(__le16); - req = kmalloc(req_len, GFP_KERNEL); - if (!req) - return -ENOMEM; + req = (void *)usb->req_buf; req->id = cpu_to_le16(USB_REQ_WRITE_RF); /* 1: 3683a, but not used in ZYDAS driver */ @@ -1544,6 +1558,5 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits) /* FALL-THROUGH with r == 0 */ out: - kfree(req); return r; } diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index 233ce825b71c..2ed48ae3e604 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h @@ -207,6 +207,7 @@ struct zd_usb { struct zd_usb_rx rx; struct zd_usb_tx tx; struct usb_interface *intf; + u8 req_buf[64]; /* zd_usb_iowrite16v needs 62 bytes */ u8 is_zd1211b:1, initialized:1; }; -- cgit v1.2.3 From 4a3b0874a481573bfd95d54c883248b4c4622572 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:49:24 +0200 Subject: zd1211rw: change interrupt URB buffer to DMA buffer As might lower beacon update CPU usage. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_usb.c | 36 ++++++++++++++++++++++------------ drivers/net/wireless/zd1211rw/zd_usb.h | 2 ++ 2 files changed, 25 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index bf1de04dc9f2..ccdf81ebc4f5 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -411,7 +411,7 @@ static void int_urb_complete(struct urb *urb) case -ENOENT: case -ECONNRESET: case -EPIPE: - goto kfree; + return; default: goto resubmit; } @@ -443,12 +443,11 @@ static void int_urb_complete(struct urb *urb) resubmit: r = usb_submit_urb(urb, GFP_ATOMIC); if (r) { - dev_dbg_f(urb_dev(urb), "resubmit urb %p\n", urb); - goto kfree; + dev_dbg_f(urb_dev(urb), "error: resubmit urb %p err code %d\n", + urb, r); + /* TODO: add worker to reset intr->urb */ } return; -kfree: - kfree(urb->transfer_buffer); } static inline int int_urb_interval(struct usb_device *udev) @@ -479,9 +478,8 @@ static inline int usb_int_enabled(struct zd_usb *usb) int zd_usb_enable_int(struct zd_usb *usb) { int r; - struct usb_device *udev; + struct usb_device *udev = zd_usb_to_usbdev(usb); struct zd_usb_interrupt *intr = &usb->intr; - void *transfer_buffer = NULL; struct urb *urb; dev_dbg_f(zd_usb_dev(usb), "\n"); @@ -502,20 +500,21 @@ int zd_usb_enable_int(struct zd_usb *usb) intr->urb = urb; spin_unlock_irq(&intr->lock); - /* TODO: make it a DMA buffer */ r = -ENOMEM; - transfer_buffer = kmalloc(USB_MAX_EP_INT_BUFFER, GFP_KERNEL); - if (!transfer_buffer) { + intr->buffer = usb_alloc_coherent(udev, USB_MAX_EP_INT_BUFFER, + GFP_KERNEL, &intr->buffer_dma); + if (!intr->buffer) { dev_dbg_f(zd_usb_dev(usb), "couldn't allocate transfer_buffer\n"); goto error_set_urb_null; } - udev = zd_usb_to_usbdev(usb); usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, EP_INT_IN), - transfer_buffer, USB_MAX_EP_INT_BUFFER, + intr->buffer, USB_MAX_EP_INT_BUFFER, int_urb_complete, usb, intr->interval); + urb->transfer_dma = intr->buffer_dma; + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; dev_dbg_f(zd_usb_dev(usb), "submit urb %p\n", intr->urb); r = usb_submit_urb(urb, GFP_KERNEL); @@ -527,7 +526,8 @@ int zd_usb_enable_int(struct zd_usb *usb) return 0; error: - kfree(transfer_buffer); + usb_free_coherent(udev, USB_MAX_EP_INT_BUFFER, + intr->buffer, intr->buffer_dma); error_set_urb_null: spin_lock_irq(&intr->lock); intr->urb = NULL; @@ -541,8 +541,11 @@ out: void zd_usb_disable_int(struct zd_usb *usb) { unsigned long flags; + struct usb_device *udev = zd_usb_to_usbdev(usb); struct zd_usb_interrupt *intr = &usb->intr; struct urb *urb; + void *buffer; + dma_addr_t buffer_dma; spin_lock_irqsave(&intr->lock, flags); urb = intr->urb; @@ -551,11 +554,18 @@ void zd_usb_disable_int(struct zd_usb *usb) return; } intr->urb = NULL; + buffer = intr->buffer; + buffer_dma = intr->buffer_dma; + intr->buffer = NULL; spin_unlock_irqrestore(&intr->lock, flags); usb_kill_urb(urb); dev_dbg_f(zd_usb_dev(usb), "urb %p killed\n", urb); usb_free_urb(urb); + + if (buffer) + usb_free_coherent(udev, USB_MAX_EP_INT_BUFFER, + buffer, buffer_dma); } static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index 2ed48ae3e604..24db0dd68421 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h @@ -162,6 +162,8 @@ struct zd_usb_interrupt { struct read_regs_int read_regs; spinlock_t lock; struct urb *urb; + void *buffer; + dma_addr_t buffer_dma; int interval; u8 read_regs_enabled:1; }; -- cgit v1.2.3 From 8f2d8f869af5088d4e4866c8286f0599e83cc963 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:49:33 +0200 Subject: zd1211rw: lower hw command timeouts Device command timeouts are set up very high (1 sec) and this causes AP beacon to lock up for long for example. Checking timeouts on device it's easy to see that 1 sec timeout is not needed, when device fails to response longer timeout doesn't help: [ 473.074419] zd1211rw 1-1:1.0: print_times() Read times: [ 473.175163] zd1211rw 1-1:1.0: print_time() 0 - 10 msec: 1506 [ 473.176429] zd1211rw 1-1:1.0: print_time() 11 - 50 msec: 0 [ 473.177955] zd1211rw 1-1:1.0: print_time() 51 - 100 msec: 0 [ 473.180703] zd1211rw 1-1:1.0: print_time() 101 - 250 msec: 0 [ 473.182101] zd1211rw 1-1:1.0: print_time() 251 - 500 msec: 0 [ 473.183221] zd1211rw 1-1:1.0: print_time() 500 - 1000 msec: 20 [ 473.184381] zd1211rw 1-1:1.0: print_time() 1000 - ... msec: 18 Also vendor driver doesn't use this long timeout. Therefore change timeout to 50msec. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_usb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index ccdf81ebc4f5..861dad192871 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -1392,7 +1392,7 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, udev = zd_usb_to_usbdev(usb); prepare_read_regs_int(usb); r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT), - req, req_len, &actual_req_len, 1000 /* ms */); + req, req_len, &actual_req_len, 50 /* ms */); if (r) { dev_dbg_f(zd_usb_dev(usb), "error in usb_bulk_msg(). Error number %d\n", r); @@ -1407,7 +1407,7 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, } timeout = wait_for_completion_timeout(&usb->intr.read_regs.completion, - msecs_to_jiffies(1000)); + msecs_to_jiffies(50)); if (!timeout) { disable_read_regs_int(usb); dev_dbg_f(zd_usb_dev(usb), "read timed out\n"); @@ -1463,7 +1463,7 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, udev = zd_usb_to_usbdev(usb); r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT), - req, req_len, &actual_req_len, 1000 /* ms */); + req, req_len, &actual_req_len, 50 /* ms */); if (r) { dev_dbg_f(zd_usb_dev(usb), "error in usb_bulk_msg(). Error number %d\n", r); @@ -1552,7 +1552,7 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits) udev = zd_usb_to_usbdev(usb); r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT), - req, req_len, &actual_req_len, 1000 /* ms */); + req, req_len, &actual_req_len, 50 /* ms */); if (r) { dev_dbg_f(zd_usb_dev(usb), "error in usb_bulk_msg(). Error number %d\n", r); -- cgit v1.2.3 From 212e1a5b9df0a51d54d7841467f3f01baa1b82f1 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:49:43 +0200 Subject: zd1211rw: collect driver settings and add function to restore theim We need HW hard reset later in patchset to reset device after TX-stall. Collect all settings that we have set to driver for later reset and add restore function. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 69 ++++++++++++++++++++++++++++++++++ drivers/net/wireless/zd1211rw/zd_mac.h | 3 ++ 2 files changed, 72 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 84ee1b886912..e82f0075ed93 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -141,6 +141,9 @@ static void housekeeping_disable(struct zd_mac *mac); static void beacon_init(struct zd_mac *mac); static void beacon_enable(struct zd_mac *mac); static void beacon_disable(struct zd_mac *mac); +static void set_rts_cts(struct zd_mac *mac, unsigned int short_preamble); +static int zd_mac_config_beacon(struct ieee80211_hw *hw, + struct sk_buff *beacon); static int zd_reg2alpha2(u8 regdomain, char *alpha2) { @@ -339,6 +342,68 @@ static void zd_op_stop(struct ieee80211_hw *hw) dev_kfree_skb_any(skb); } +int zd_restore_settings(struct zd_mac *mac) +{ + struct sk_buff *beacon; + struct zd_mc_hash multicast_hash; + unsigned int short_preamble; + int r, beacon_interval, beacon_period; + u8 channel; + + dev_dbg_f(zd_mac_dev(mac), "\n"); + + spin_lock_irq(&mac->lock); + multicast_hash = mac->multicast_hash; + short_preamble = mac->short_preamble; + beacon_interval = mac->beacon.interval; + beacon_period = mac->beacon.period; + channel = mac->channel; + spin_unlock_irq(&mac->lock); + + r = set_mac_and_bssid(mac); + if (r < 0) { + dev_dbg_f(zd_mac_dev(mac), "set_mac_and_bssid failed, %d\n", r); + return r; + } + + r = zd_chip_set_channel(&mac->chip, channel); + if (r < 0) { + dev_dbg_f(zd_mac_dev(mac), "zd_chip_set_channel failed, %d\n", + r); + return r; + } + + set_rts_cts(mac, short_preamble); + + r = zd_chip_set_multicast_hash(&mac->chip, &multicast_hash); + if (r < 0) { + dev_dbg_f(zd_mac_dev(mac), + "zd_chip_set_multicast_hash failed, %d\n", r); + return r; + } + + if (mac->type == NL80211_IFTYPE_MESH_POINT || + mac->type == NL80211_IFTYPE_ADHOC || + mac->type == NL80211_IFTYPE_AP) { + if (mac->vif != NULL) { + beacon = ieee80211_beacon_get(mac->hw, mac->vif); + if (beacon) { + zd_mac_config_beacon(mac->hw, beacon); + kfree_skb(beacon); + } + } + + zd_set_beacon_interval(&mac->chip, beacon_interval, + beacon_period, mac->type); + + spin_lock_irq(&mac->lock); + mac->beacon.last_update = jiffies; + spin_unlock_irq(&mac->lock); + } + + return 0; +} + /** * zd_mac_tx_status - reports tx status of a packet if required * @hw - a &struct ieee80211_hw pointer @@ -988,6 +1053,10 @@ static int zd_op_config(struct ieee80211_hw *hw, u32 changed) struct zd_mac *mac = zd_hw_mac(hw); struct ieee80211_conf *conf = &hw->conf; + spin_lock_irq(&mac->lock); + mac->channel = conf->channel->hw_value; + spin_unlock_irq(&mac->lock); + return zd_chip_set_channel(&mac->chip, conf->channel->hw_value); } diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index 281b3079311a..c0f239e40bcd 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h @@ -192,6 +192,7 @@ struct zd_mac { u8 intr_buffer[USB_MAX_EP_INT_BUFFER]; u8 regdomain; u8 default_regdomain; + u8 channel; int type; int associated; unsigned long flags; @@ -313,6 +314,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length); void zd_mac_tx_failed(struct urb *urb); void zd_mac_tx_to_dev(struct sk_buff *skb, int error); +int zd_restore_settings(struct zd_mac *mac); + #ifdef DEBUG void zd_dump_rx_status(const struct rx_status *status); #else -- cgit v1.2.3 From a0fd751f0924e0eefa36592f1d358c4ab18b44c5 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:49:52 +0200 Subject: zd1211rw: add TX watchdog and device resetting When doing transfers at high speed for long time, tx queue can freeze. So add tx watchdog. TX-watchdog checks for locked tx-urbs and reset hardware when such is detected. Merely unlinking urb was not enough, device have to be reseted. Hw settings are restored so that any open link will stay on after reset. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_chip.c | 2 + drivers/net/wireless/zd1211rw/zd_mac.c | 8 +- drivers/net/wireless/zd1211rw/zd_mac.h | 2 + drivers/net/wireless/zd1211rw/zd_usb.c | 161 ++++++++++++++++++++++++++++++++ drivers/net/wireless/zd1211rw/zd_usb.h | 12 ++- 5 files changed, 181 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 907e6562cb59..54f68f134ea7 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -1448,6 +1448,7 @@ int zd_chip_enable_rxtx(struct zd_chip *chip) mutex_lock(&chip->mutex); zd_usb_enable_tx(&chip->usb); r = zd_usb_enable_rx(&chip->usb); + zd_tx_watchdog_enable(&chip->usb); mutex_unlock(&chip->mutex); return r; } @@ -1455,6 +1456,7 @@ int zd_chip_enable_rxtx(struct zd_chip *chip) void zd_chip_disable_rxtx(struct zd_chip *chip) { mutex_lock(&chip->mutex); + zd_tx_watchdog_disable(&chip->usb); zd_usb_disable_rx(&chip->usb); zd_usb_disable_tx(&chip->usb); mutex_unlock(&chip->mutex); diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index e82f0075ed93..a590a94cb6fa 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -264,7 +264,7 @@ static int set_mc_hash(struct zd_mac *mac) return zd_chip_set_multicast_hash(&mac->chip, &hash); } -static int zd_op_start(struct ieee80211_hw *hw) +int zd_op_start(struct ieee80211_hw *hw) { struct zd_mac *mac = zd_hw_mac(hw); struct zd_chip *chip = &mac->chip; @@ -314,7 +314,7 @@ out: return r; } -static void zd_op_stop(struct ieee80211_hw *hw) +void zd_op_stop(struct ieee80211_hw *hw) { struct zd_mac *mac = zd_hw_mac(hw); struct zd_chip *chip = &mac->chip; @@ -1409,6 +1409,9 @@ static void link_led_handler(struct work_struct *work) int is_associated; int r; + if (!test_bit(ZD_DEVICE_RUNNING, &mac->flags)) + goto requeue; + spin_lock_irq(&mac->lock); is_associated = mac->associated; spin_unlock_irq(&mac->lock); @@ -1418,6 +1421,7 @@ static void link_led_handler(struct work_struct *work) if (r) dev_dbg_f(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r); +requeue: queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work, LINK_LED_WORK_DELAY); } diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index c0f239e40bcd..f8c93c3fe755 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h @@ -314,6 +314,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length); void zd_mac_tx_failed(struct urb *urb); void zd_mac_tx_to_dev(struct sk_buff *skb, int error); +int zd_op_start(struct ieee80211_hw *hw); +void zd_op_stop(struct ieee80211_hw *hw); int zd_restore_settings(struct zd_mac *mac); #ifdef DEBUG diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 861dad192871..178d794be3fd 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -798,6 +798,7 @@ void zd_usb_disable_tx(struct zd_usb *usb) usb_kill_anchored_urbs(&tx->submitted); spin_lock_irqsave(&tx->lock, flags); + WARN_ON(!skb_queue_empty(&tx->submitted_skbs)); WARN_ON(tx->submitted_urbs != 0); tx->submitted_urbs = 0; spin_unlock_irqrestore(&tx->lock, flags); @@ -895,6 +896,7 @@ static void tx_urb_complete(struct urb *urb) goto resubmit; } free_urb: + skb_unlink(skb, &usb->tx.submitted_skbs); zd_mac_tx_to_dev(skb, urb->status); usb_free_urb(urb); tx_dec_submitted_urbs(usb); @@ -924,6 +926,7 @@ resubmit: int zd_usb_tx(struct zd_usb *usb, struct sk_buff *skb) { int r; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct usb_device *udev = zd_usb_to_usbdev(usb); struct urb *urb; struct zd_usb_tx *tx = &usb->tx; @@ -942,10 +945,14 @@ int zd_usb_tx(struct zd_usb *usb, struct sk_buff *skb) usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_DATA_OUT), skb->data, skb->len, tx_urb_complete, skb); + info->rate_driver_data[1] = (void *)jiffies; + skb_queue_tail(&tx->submitted_skbs, skb); usb_anchor_urb(urb, &tx->submitted); + r = usb_submit_urb(urb, GFP_ATOMIC); if (r) { usb_unanchor_urb(urb); + skb_unlink(skb, &tx->submitted_skbs); goto error; } tx_inc_submitted_urbs(usb); @@ -956,6 +963,76 @@ out: return r; } +static bool zd_tx_timeout(struct zd_usb *usb) +{ + struct zd_usb_tx *tx = &usb->tx; + struct sk_buff_head *q = &tx->submitted_skbs; + struct sk_buff *skb, *skbnext; + struct ieee80211_tx_info *info; + unsigned long flags, trans_start; + bool have_timedout = false; + + spin_lock_irqsave(&q->lock, flags); + skb_queue_walk_safe(q, skb, skbnext) { + info = IEEE80211_SKB_CB(skb); + trans_start = (unsigned long)info->rate_driver_data[1]; + + if (time_is_before_jiffies(trans_start + ZD_TX_TIMEOUT)) { + have_timedout = true; + break; + } + } + spin_unlock_irqrestore(&q->lock, flags); + + return have_timedout; +} + +static void zd_tx_watchdog_handler(struct work_struct *work) +{ + struct zd_usb *usb = + container_of(work, struct zd_usb, tx.watchdog_work.work); + struct zd_usb_tx *tx = &usb->tx; + + if (!atomic_read(&tx->enabled) || !tx->watchdog_enabled) + goto out; + if (!zd_tx_timeout(usb)) + goto out; + + /* TX halted, try reset */ + dev_warn(zd_usb_dev(usb), "TX-stall detected, reseting device..."); + + usb_queue_reset_device(usb->intf); + + /* reset will stop this worker, don't rearm */ + return; +out: + queue_delayed_work(zd_workqueue, &tx->watchdog_work, + ZD_TX_WATCHDOG_INTERVAL); +} + +void zd_tx_watchdog_enable(struct zd_usb *usb) +{ + struct zd_usb_tx *tx = &usb->tx; + + if (!tx->watchdog_enabled) { + dev_dbg_f(zd_usb_dev(usb), "\n"); + queue_delayed_work(zd_workqueue, &tx->watchdog_work, + ZD_TX_WATCHDOG_INTERVAL); + tx->watchdog_enabled = 1; + } +} + +void zd_tx_watchdog_disable(struct zd_usb *usb) +{ + struct zd_usb_tx *tx = &usb->tx; + + if (tx->watchdog_enabled) { + dev_dbg_f(zd_usb_dev(usb), "\n"); + tx->watchdog_enabled = 0; + cancel_delayed_work_sync(&tx->watchdog_work); + } +} + static inline void init_usb_interrupt(struct zd_usb *usb) { struct zd_usb_interrupt *intr = &usb->intr; @@ -984,8 +1061,11 @@ static inline void init_usb_tx(struct zd_usb *usb) spin_lock_init(&tx->lock); atomic_set(&tx->enabled, 0); tx->stopped = 0; + skb_queue_head_init(&tx->submitted_skbs); init_usb_anchor(&tx->submitted); tx->submitted_urbs = 0; + tx->watchdog_enabled = 0; + INIT_DELAYED_WORK(&tx->watchdog_work, zd_tx_watchdog_handler); } void zd_usb_init(struct zd_usb *usb, struct ieee80211_hw *hw, @@ -1233,11 +1313,92 @@ static void disconnect(struct usb_interface *intf) dev_dbg(&intf->dev, "disconnected\n"); } +static void zd_usb_resume(struct zd_usb *usb) +{ + struct zd_mac *mac = zd_usb_to_mac(usb); + int r; + + dev_dbg_f(zd_usb_dev(usb), "\n"); + + r = zd_op_start(zd_usb_to_hw(usb)); + if (r < 0) { + dev_warn(zd_usb_dev(usb), "Device resume failed " + "with error code %d. Retrying...\n", r); + if (usb->was_running) + set_bit(ZD_DEVICE_RUNNING, &mac->flags); + usb_queue_reset_device(usb->intf); + return; + } + + if (mac->type != NL80211_IFTYPE_UNSPECIFIED) { + r = zd_restore_settings(mac); + if (r < 0) { + dev_dbg(zd_usb_dev(usb), + "failed to restore settings, %d\n", r); + return; + } + } +} + +static void zd_usb_stop(struct zd_usb *usb) +{ + dev_dbg_f(zd_usb_dev(usb), "\n"); + + zd_op_stop(zd_usb_to_hw(usb)); + + zd_usb_disable_tx(usb); + zd_usb_disable_rx(usb); + zd_usb_disable_int(usb); + + usb->initialized = 0; +} + +static int pre_reset(struct usb_interface *intf) +{ + struct ieee80211_hw *hw = usb_get_intfdata(intf); + struct zd_mac *mac; + struct zd_usb *usb; + + if (!hw || intf->condition != USB_INTERFACE_BOUND) + return 0; + + mac = zd_hw_mac(hw); + usb = &mac->chip.usb; + + usb->was_running = test_bit(ZD_DEVICE_RUNNING, &mac->flags); + + zd_usb_stop(usb); + + mutex_lock(&mac->chip.mutex); + return 0; +} + +static int post_reset(struct usb_interface *intf) +{ + struct ieee80211_hw *hw = usb_get_intfdata(intf); + struct zd_mac *mac; + struct zd_usb *usb; + + if (!hw || intf->condition != USB_INTERFACE_BOUND) + return 0; + + mac = zd_hw_mac(hw); + usb = &mac->chip.usb; + + mutex_unlock(&mac->chip.mutex); + + if (usb->was_running) + zd_usb_resume(usb); + return 0; +} + static struct usb_driver driver = { .name = KBUILD_MODNAME, .id_table = usb_ids, .probe = probe, .disconnect = disconnect, + .pre_reset = pre_reset, + .post_reset = post_reset, }; struct workqueue_struct *zd_workqueue; diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index 24db0dd68421..98f09c2dde7e 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h @@ -32,6 +32,9 @@ #define ZD_USB_TX_HIGH 5 #define ZD_USB_TX_LOW 2 +#define ZD_TX_TIMEOUT (HZ * 5) +#define ZD_TX_WATCHDOG_INTERVAL round_jiffies_relative(HZ) + enum devicetype { DEVICE_ZD1211 = 0, DEVICE_ZD1211B = 1, @@ -196,9 +199,11 @@ struct zd_usb_rx { struct zd_usb_tx { atomic_t enabled; spinlock_t lock; + struct delayed_work watchdog_work; + struct sk_buff_head submitted_skbs; struct usb_anchor submitted; int submitted_urbs; - int stopped; + u8 stopped:1, watchdog_enabled:1; }; /* Contains the usb parts. The structure doesn't require a lock because intf @@ -210,7 +215,7 @@ struct zd_usb { struct zd_usb_tx tx; struct usb_interface *intf; u8 req_buf[64]; /* zd_usb_iowrite16v needs 62 bytes */ - u8 is_zd1211b:1, initialized:1; + u8 is_zd1211b:1, initialized:1, was_running:1; }; #define zd_usb_dev(usb) (&usb->intf->dev) @@ -237,6 +242,9 @@ void zd_usb_clear(struct zd_usb *usb); int zd_usb_scnprint_id(struct zd_usb *usb, char *buffer, size_t size); +void zd_tx_watchdog_enable(struct zd_usb *usb); +void zd_tx_watchdog_disable(struct zd_usb *usb); + int zd_usb_enable_int(struct zd_usb *usb); void zd_usb_disable_int(struct zd_usb *usb); -- cgit v1.2.3 From 3985a46543d47a50b94e839e0a16e67d959ab092 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:50:02 +0200 Subject: zd1211rw: reset device when CR_BCN_FIFO_SEMAPHORE freezes in beacon setup When driver fails to acquire device semaphore lock, device usually freezes soon afterwards. So failing to acquire lock indicates us that not everything is going right in device/fw. So reset device when this happens. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index a590a94cb6fa..beaa969f7426 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -703,7 +703,7 @@ static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) dev_err(zd_mac_dev(mac), "Giving up beacon config.\n"); r = -ETIMEDOUT; - goto release_sema; + goto reset_device; } } msleep(20); @@ -770,6 +770,17 @@ out: mutex_unlock(&mac->chip.mutex); kfree(ioreqs); return r; + +reset_device: + mutex_unlock(&mac->chip.mutex); + kfree(ioreqs); + + /* semaphore stuck, reset device to avoid fw freeze later */ + dev_warn(zd_mac_dev(mac), "CR_BCN_FIFO_SEMAPHORE stuck, " + "reseting device..."); + usb_queue_reset_device(mac->chip.usb.intf); + + return r; } static int fill_ctrlset(struct zd_mac *mac, -- cgit v1.2.3 From 1f6cccccea3fe96464f7dbc39723d70165f1eef1 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:50:12 +0200 Subject: zd1211rw: reset rx urbs after idle period of 30 seconds RX appears to freeze while idle. Resetting rx-urbs appears to be enough to fix this. Do reset 30 seconds after last rx. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_usb.c | 79 +++++++++++++++++++++++++++++++++- drivers/net/wireless/zd1211rw/zd_usb.h | 7 ++- 2 files changed, 83 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 178d794be3fd..0631be6a53ac 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -638,6 +638,8 @@ static void rx_urb_complete(struct urb *urb) usb = urb->context; rx = &usb->rx; + zd_usb_reset_rx_idle_timer(usb); + if (length%rx->usb_packet_size > rx->usb_packet_size-4) { /* If there is an old first fragment, we don't care. */ dev_dbg_f(urb_dev(urb), "*** first fragment ***\n"); @@ -702,7 +704,7 @@ static void free_rx_urb(struct urb *urb) usb_free_urb(urb); } -int zd_usb_enable_rx(struct zd_usb *usb) +static int __zd_usb_enable_rx(struct zd_usb *usb) { int i, r; struct zd_usb_rx *rx = &usb->rx; @@ -754,7 +756,21 @@ error: return r; } -void zd_usb_disable_rx(struct zd_usb *usb) +int zd_usb_enable_rx(struct zd_usb *usb) +{ + int r; + struct zd_usb_rx *rx = &usb->rx; + + mutex_lock(&rx->setup_mutex); + r = __zd_usb_enable_rx(usb); + mutex_unlock(&rx->setup_mutex); + + zd_usb_reset_rx_idle_timer(usb); + + return r; +} + +static void __zd_usb_disable_rx(struct zd_usb *usb) { int i; unsigned long flags; @@ -781,6 +797,40 @@ void zd_usb_disable_rx(struct zd_usb *usb) spin_unlock_irqrestore(&rx->lock, flags); } +void zd_usb_disable_rx(struct zd_usb *usb) +{ + struct zd_usb_rx *rx = &usb->rx; + + mutex_lock(&rx->setup_mutex); + __zd_usb_disable_rx(usb); + mutex_unlock(&rx->setup_mutex); + + cancel_delayed_work_sync(&rx->idle_work); +} + +static void zd_usb_reset_rx(struct zd_usb *usb) +{ + bool do_reset; + struct zd_usb_rx *rx = &usb->rx; + unsigned long flags; + + mutex_lock(&rx->setup_mutex); + + spin_lock_irqsave(&rx->lock, flags); + do_reset = rx->urbs != NULL; + spin_unlock_irqrestore(&rx->lock, flags); + + if (do_reset) { + __zd_usb_disable_rx(usb); + __zd_usb_enable_rx(usb); + } + + mutex_unlock(&rx->setup_mutex); + + if (do_reset) + zd_usb_reset_rx_idle_timer(usb); +} + /** * zd_usb_disable_tx - disable transmission * @usb: the zd1211rw-private USB structure @@ -1033,6 +1083,29 @@ void zd_tx_watchdog_disable(struct zd_usb *usb) } } +static void zd_rx_idle_timer_handler(struct work_struct *work) +{ + struct zd_usb *usb = + container_of(work, struct zd_usb, rx.idle_work.work); + struct zd_mac *mac = zd_usb_to_mac(usb); + + if (!test_bit(ZD_DEVICE_RUNNING, &mac->flags)) + return; + + dev_dbg_f(zd_usb_dev(usb), "\n"); + + /* 30 seconds since last rx, reset rx */ + zd_usb_reset_rx(usb); +} + +void zd_usb_reset_rx_idle_timer(struct zd_usb *usb) +{ + struct zd_usb_rx *rx = &usb->rx; + + cancel_delayed_work(&rx->idle_work); + queue_delayed_work(zd_workqueue, &rx->idle_work, ZD_RX_IDLE_INTERVAL); +} + static inline void init_usb_interrupt(struct zd_usb *usb) { struct zd_usb_interrupt *intr = &usb->intr; @@ -1047,12 +1120,14 @@ static inline void init_usb_rx(struct zd_usb *usb) { struct zd_usb_rx *rx = &usb->rx; spin_lock_init(&rx->lock); + mutex_init(&rx->setup_mutex); if (interface_to_usbdev(usb->intf)->speed == USB_SPEED_HIGH) { rx->usb_packet_size = 512; } else { rx->usb_packet_size = 64; } ZD_ASSERT(rx->fragment_length == 0); + INIT_DELAYED_WORK(&rx->idle_work, zd_rx_idle_timer_handler); } static inline void init_usb_tx(struct zd_usb *usb) diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index 98f09c2dde7e..2d688f48a34c 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h @@ -34,6 +34,7 @@ #define ZD_TX_TIMEOUT (HZ * 5) #define ZD_TX_WATCHDOG_INTERVAL round_jiffies_relative(HZ) +#define ZD_RX_IDLE_INTERVAL round_jiffies_relative(30 * HZ) enum devicetype { DEVICE_ZD1211 = 0, @@ -180,7 +181,9 @@ static inline struct usb_int_regs *get_read_regs(struct zd_usb_interrupt *intr) struct zd_usb_rx { spinlock_t lock; - u8 fragment[2*USB_MAX_RX_SIZE]; + struct mutex setup_mutex; + struct delayed_work idle_work; + u8 fragment[2 * USB_MAX_RX_SIZE]; unsigned int fragment_length; unsigned int usb_packet_size; struct urb **urbs; @@ -251,6 +254,8 @@ void zd_usb_disable_int(struct zd_usb *usb); int zd_usb_enable_rx(struct zd_usb *usb); void zd_usb_disable_rx(struct zd_usb *usb); +void zd_usb_reset_rx_idle_timer(struct zd_usb *usb); + void zd_usb_enable_tx(struct zd_usb *usb); void zd_usb_disable_tx(struct zd_usb *usb); -- cgit v1.2.3 From ab419e9bda10efced0db980478c3e40a1ad18ba3 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:50:21 +0200 Subject: zd1211rw: enable NL80211_IFTYPE_AP It should be safe to enable AP-mode now. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index beaa969f7426..74a269ebbeb9 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -1038,6 +1038,7 @@ static int zd_op_add_interface(struct ieee80211_hw *hw, case NL80211_IFTYPE_MESH_POINT: case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_AP: mac->type = vif->type; break; default: @@ -1214,7 +1215,8 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw, dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes); if (mac->type == NL80211_IFTYPE_MESH_POINT || - mac->type == NL80211_IFTYPE_ADHOC) { + mac->type == NL80211_IFTYPE_ADHOC || + mac->type == NL80211_IFTYPE_AP) { associated = true; if (changes & BSS_CHANGED_BEACON) { struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); @@ -1317,7 +1319,8 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_MESH_POINT) | BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC); + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_AP); hw->max_signal = 100; hw->queues = 1; -- cgit v1.2.3 From 24d24c627cadcbff682fbf8448a775851bef833c Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 31 Jan 2011 20:50:31 +0200 Subject: zd1211rw: add useful debug output Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_usb.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 0631be6a53ac..f6df3665fdb6 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -411,8 +411,10 @@ static void int_urb_complete(struct urb *urb) case -ENOENT: case -ECONNRESET: case -EPIPE: + dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status); return; default: + dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status); goto resubmit; } @@ -613,6 +615,7 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, static void rx_urb_complete(struct urb *urb) { + int r; struct zd_usb *usb; struct zd_usb_rx *rx; const u8 *buffer; @@ -627,6 +630,7 @@ static void rx_urb_complete(struct urb *urb) case -ENOENT: case -ECONNRESET: case -EPIPE: + dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status); return; default: dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status); @@ -668,7 +672,9 @@ static void rx_urb_complete(struct urb *urb) } resubmit: - usb_submit_urb(urb, GFP_ATOMIC); + r = usb_submit_urb(urb, GFP_ATOMIC); + if (r) + dev_dbg_f(urb_dev(urb), "urb %p resubmit error %d\n", urb, r); } static struct urb *alloc_rx_urb(struct zd_usb *usb) @@ -1001,6 +1007,7 @@ int zd_usb_tx(struct zd_usb *usb, struct sk_buff *skb) r = usb_submit_urb(urb, GFP_ATOMIC); if (r) { + dev_dbg_f(zd_usb_dev(usb), "error submit urb %p %d\n", urb, r); usb_unanchor_urb(urb); skb_unlink(skb, &tx->submitted_skbs); goto error; -- cgit v1.2.3 From 8e5461041f4498e3c8f4e0a51187f608f0a18b08 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 4 Feb 2011 13:51:28 +0200 Subject: ath: Fix clearing of secondary key cache entry for TKIP All register writes to the key cache have to be done in pairs. However, the clearing of a separate MIC entry with hardware revisions that use combined MIC key layout did not do that with one of the registers. Add the matching register write to the following register to make the KEY4 register write actually complete. This is mostly a fix for a theoretical issue since the incorrect entry that could potentially be left behind in the key cache would not match with received frames. Anyway, better make this code clean the entry correctly using paired register writes. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath/key.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index 5d465e5fcf24..37b8e115375a 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c @@ -58,8 +58,11 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry) REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0); REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); - if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) + if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) { REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0); + REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), + AR_KEYTABLE_TYPE_CLR); + } } -- cgit v1.2.3 From cb8d61de2d7f074654057b2b924da1efbf625ad4 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 4 Feb 2011 20:09:25 +0100 Subject: ath9k: add additional checks for the baseband hang detection Since even with the latest changes the false positive issue of the baseband hang check is not fully solved yet, additional checks are needed. If the baseband hang occurs, the rx_clear signal will be stuck to high, so we can use the cycle counters to confirm it. With this patch, a hardware reset is only triggered if the baseband hang check returned true three times in a row, with a beacon interval between each check and if the busy time was also 99% or more during the check intervals. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 ++ drivers/net/wireless/ath/ath9k/main.c | 45 +++++++++++++++++++++++++++------- 2 files changed, 38 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index bd85e311c51b..7c8409e53598 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -602,6 +602,8 @@ struct ath_softc { struct completion paprd_complete; bool paprd_pending; + unsigned int hw_busy_count; + u32 intrstatus; u32 sc_flags; /* SC_OP_* */ u16 ps_flags; /* PS_* */ diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index e5c695d73025..2d4e9b861b60 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -153,7 +153,12 @@ static void ath_update_survey_nf(struct ath_softc *sc, int channel) } } -static void ath_update_survey_stats(struct ath_softc *sc) +/* + * Updates the survey statistics and returns the busy time since last + * update in %, if the measurement duration was long enough for the + * result to be useful, -1 otherwise. + */ +static int ath_update_survey_stats(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); @@ -161,9 +166,10 @@ static void ath_update_survey_stats(struct ath_softc *sc) struct survey_info *survey = &sc->survey[pos]; struct ath_cycle_counters *cc = &common->cc_survey; unsigned int div = common->clockrate * 1000; + int ret = 0; if (!ah->curchan) - return; + return -1; if (ah->power_mode == ATH9K_PM_AWAKE) ath_hw_cycle_counters_update(common); @@ -178,9 +184,18 @@ static void ath_update_survey_stats(struct ath_softc *sc) survey->channel_time_rx += cc->rx_frame / div; survey->channel_time_tx += cc->tx_frame / div; } + + if (cc->cycles < div) + return -1; + + if (cc->cycles > 0) + ret = cc->rx_busy * 100 / cc->cycles; + memset(cc, 0, sizeof(*cc)); ath_update_survey_nf(sc, pos); + + return ret; } /* @@ -202,6 +217,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, if (sc->sc_flags & SC_OP_INVALID) return -EIO; + sc->hw_busy_count = 0; + del_timer_sync(&common->ani.timer); cancel_work_sync(&sc->paprd_work); cancel_work_sync(&sc->hw_check_work); @@ -569,17 +586,25 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) void ath_hw_check(struct work_struct *work) { struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work); - int i; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + unsigned long flags; + int busy; ath9k_ps_wakeup(sc); + if (ath9k_hw_check_alive(sc->sc_ah)) + goto out; - for (i = 0; i < 3; i++) { - if (ath9k_hw_check_alive(sc->sc_ah)) - goto out; + spin_lock_irqsave(&common->cc_lock, flags); + busy = ath_update_survey_stats(sc); + spin_unlock_irqrestore(&common->cc_lock, flags); - msleep(1); - } - ath_reset(sc, true); + ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, " + "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1); + if (busy >= 99) { + if (++sc->hw_busy_count >= 3) + ath_reset(sc, true); + } else if (busy >= 0) + sc->hw_busy_count = 0; out: ath9k_ps_restore(sc); @@ -930,6 +955,8 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) struct ieee80211_hw *hw = sc->hw; int r; + sc->hw_busy_count = 0; + /* Stop ANI */ del_timer_sync(&common->ani.timer); -- cgit v1.2.3 From 4097c4968cd60bf5c690455466731d11149fe43f Mon Sep 17 00:00:00 2001 From: "Guzman Lugo, Fernando" Date: Tue, 26 Oct 2010 00:51:46 +0000 Subject: staging: tidspbridge: make sync_wait_on_event interruptible So that avoid non-killable process. Signed-off-by: Fernando Guzman Lugo Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/include/dspbridge/sync.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/include/dspbridge/sync.h b/drivers/staging/tidspbridge/include/dspbridge/sync.h index e2651e7b1c42..df05b8f8e230 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/sync.h +++ b/drivers/staging/tidspbridge/include/dspbridge/sync.h @@ -80,13 +80,22 @@ void sync_set_event(struct sync_object *event); * This functios will wait until @event is set or until timeout. In case of * success the function will return 0 and * in case of timeout the function will return -ETIME + * in case of signal the function will return -ERESTARTSYS */ static inline int sync_wait_on_event(struct sync_object *event, unsigned timeout) { - return wait_for_completion_timeout(&event->comp, - msecs_to_jiffies(timeout)) ? 0 : -ETIME; + int res; + + res = wait_for_completion_interruptible_timeout(&event->comp, + msecs_to_jiffies(timeout)); + if (!res) + res = -ETIME; + else if (res > 0) + res = 0; + + return res; } /** -- cgit v1.2.3 From 98d0ba892536141ba047ecbe60b32e34c11834df Mon Sep 17 00:00:00 2001 From: "Sapiens, Rene" Date: Thu, 4 Nov 2010 00:31:24 +0000 Subject: staging: tidspbridge: overwrite DSP error codes When calling the DSP's remote functions, the DSP returns error codes different from the ones managed by the kernel, the function's return value is shared with the MPU using a shared structure. This patch overwrites those error codes by kernel specifics and deletes unnecessary code. Signed-off-by: Rene Sapiens Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/rmgr/disp.c | 44 ++++++--------------------------- 1 file changed, 8 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/rmgr/disp.c b/drivers/staging/tidspbridge/rmgr/disp.c index b7ce4353e06b..560069aade5a 100644 --- a/drivers/staging/tidspbridge/rmgr/disp.c +++ b/drivers/staging/tidspbridge/rmgr/disp.c @@ -460,17 +460,6 @@ int disp_node_create(struct disp_object *disp_obj, DBC_ASSERT(ul_bytes < (RMS_COMMANDBUFSIZE * sizeof(rms_word))); status = send_message(disp_obj, node_get_timeout(hnode), ul_bytes, node_env); - if (status >= 0) { - /* - * Message successfully received from RMS. - * Return the status of the Node's create function - * on the DSP-side - */ - status = (((rms_word *) (disp_obj->pbuf))[0]); - if (status < 0) - dev_dbg(bridge, "%s: DSP-side failed: 0x%x\n", - __func__, status); - } } func_end: return status; @@ -513,18 +502,6 @@ int disp_node_delete(struct disp_object *disp_obj, status = send_message(disp_obj, node_get_timeout(hnode), sizeof(struct rms_command), &dw_arg); - if (status >= 0) { - /* - * Message successfully received from RMS. - * Return the status of the Node's delete - * function on the DSP-side - */ - status = (((rms_word *) (disp_obj->pbuf))[0]); - if (status < 0) - dev_dbg(bridge, "%s: DSP-side failed: " - "0x%x\n", __func__, status); - } - } } return status; @@ -566,18 +543,6 @@ int disp_node_run(struct disp_object *disp_obj, status = send_message(disp_obj, node_get_timeout(hnode), sizeof(struct rms_command), &dw_arg); - if (status >= 0) { - /* - * Message successfully received from RMS. - * Return the status of the Node's execute - * function on the DSP-side - */ - status = (((rms_word *) (disp_obj->pbuf))[0]); - if (status < 0) - dev_dbg(bridge, "%s: DSP-side failed: " - "0x%x\n", __func__, status); - } - } } @@ -739,7 +704,14 @@ static int send_message(struct disp_object *disp_obj, u32 timeout, } else { if (CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) { DBC_ASSERT(chnl_ioc_obj.pbuf == pbuf); - status = (*((rms_word *) chnl_ioc_obj.pbuf)); + if (*((int *)chnl_ioc_obj.pbuf) < 0) { + /* Translate DSP's to kernel error */ + status = -EREMOTEIO; + dev_dbg(bridge, "%s: DSP-side failed:" + " DSP errcode = 0x%x, Kernel " + "errcode = %d\n", __func__, + *(int *)pbuf, status); + } *pdw_arg = (((rms_word *) (chnl_ioc_obj.pbuf))[1]); } else { -- cgit v1.2.3 From 81ea18ec22e9526b4af81e2213747e5afc48f364 Mon Sep 17 00:00:00 2001 From: Armando Uribe Date: Mon, 1 Nov 2010 17:15:50 -0600 Subject: staging: tidspbridge: Eliminate direct manipulation of OMAP_SYSC_BASE Eliminates Bridge direct manipulation of OMAP_SYSC_BASE registers Signed-off-by: Armando Uribe Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/core/dsp-clock.c | 52 +--------------------- drivers/staging/tidspbridge/core/tiomap3430.c | 3 -- .../tidspbridge/include/dspbridge/cfgdefs.h | 1 - .../staging/tidspbridge/include/dspbridge/drv.h | 3 -- drivers/staging/tidspbridge/rmgr/drv.c | 1 - 5 files changed, 2 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/dsp-clock.c b/drivers/staging/tidspbridge/core/dsp-clock.c index 46d17c777b88..589a0554332e 100644 --- a/drivers/staging/tidspbridge/core/dsp-clock.c +++ b/drivers/staging/tidspbridge/core/dsp-clock.c @@ -146,54 +146,6 @@ void dsp_clk_init(void) ssi.sst_fck, ssi.ssr_fck, ssi.ick); } -#ifdef CONFIG_OMAP_MCBSP -static void mcbsp_clk_prepare(bool flag, u8 id) -{ - struct cfg_hostres *resources; - struct dev_object *hdev_object = NULL; - struct bridge_dev_context *bridge_context = NULL; - u32 val; - - hdev_object = (struct dev_object *)drv_get_first_dev_object(); - if (!hdev_object) - return; - - dev_get_bridge_context(hdev_object, &bridge_context); - if (!bridge_context) - return; - - resources = bridge_context->resources; - if (!resources) - return; - - if (flag) { - if (id == DSP_CLK_MCBSP1) { - /* set MCBSP1_CLKS, on McBSP1 ON */ - val = __raw_readl(resources->dw_sys_ctrl_base + 0x274); - val |= 1 << 2; - __raw_writel(val, resources->dw_sys_ctrl_base + 0x274); - } else if (id == DSP_CLK_MCBSP2) { - /* set MCBSP2_CLKS, on McBSP2 ON */ - val = __raw_readl(resources->dw_sys_ctrl_base + 0x274); - val |= 1 << 6; - __raw_writel(val, resources->dw_sys_ctrl_base + 0x274); - } - } else { - if (id == DSP_CLK_MCBSP1) { - /* clear MCBSP1_CLKS, on McBSP1 OFF */ - val = __raw_readl(resources->dw_sys_ctrl_base + 0x274); - val &= ~(1 << 2); - __raw_writel(val, resources->dw_sys_ctrl_base + 0x274); - } else if (id == DSP_CLK_MCBSP2) { - /* clear MCBSP2_CLKS, on McBSP2 OFF */ - val = __raw_readl(resources->dw_sys_ctrl_base + 0x274); - val &= ~(1 << 6); - __raw_writel(val, resources->dw_sys_ctrl_base + 0x274); - } - } -} -#endif - /** * dsp_gpt_wait_overflow - set gpt overflow and wait for fixed timeout * @clk_id: GP Timer clock id. @@ -257,9 +209,9 @@ int dsp_clk_enable(enum dsp_clk_id clk_id) break; #ifdef CONFIG_OMAP_MCBSP case MCBSP_CLK: - mcbsp_clk_prepare(true, clk_id); omap_mcbsp_set_io_type(MCBSP_ID(clk_id), OMAP_MCBSP_POLL_IO); omap_mcbsp_request(MCBSP_ID(clk_id)); + omap2_mcbsp_set_clks_src(MCBSP_ID(clk_id), MCBSP_CLKS_PAD_SRC); break; #endif case WDT_CLK: @@ -334,7 +286,7 @@ int dsp_clk_disable(enum dsp_clk_id clk_id) break; #ifdef CONFIG_OMAP_MCBSP case MCBSP_CLK: - mcbsp_clk_prepare(false, clk_id); + omap2_mcbsp_set_clks_src(MCBSP_ID(clk_id), MCBSP_CLKS_PRCM_SRC); omap_mcbsp_free(MCBSP_ID(clk_id)); break; #endif diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index a3f69f6f505f..2ae7e44819e8 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -1036,15 +1036,12 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt) iounmap((void *)host_res->dw_per_pm_base); if (host_res->dw_core_pm_base) iounmap((void *)host_res->dw_core_pm_base); - if (host_res->dw_sys_ctrl_base) - iounmap(host_res->dw_sys_ctrl_base); host_res->dw_mem_base[0] = (u32) NULL; host_res->dw_mem_base[2] = (u32) NULL; host_res->dw_mem_base[3] = (u32) NULL; host_res->dw_mem_base[4] = (u32) NULL; host_res->dw_dmmu_base = NULL; - host_res->dw_sys_ctrl_base = NULL; kfree(host_res); } diff --git a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h index 38122dbf877a..f403c01b5d3a 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h @@ -69,7 +69,6 @@ struct cfg_hostres { u32 dw_per_pm_base; u32 dw_core_pm_base; void __iomem *dw_dmmu_base; - void __iomem *dw_sys_ctrl_base; }; struct cfg_dspmemdesc { diff --git a/drivers/staging/tidspbridge/include/dspbridge/drv.h b/drivers/staging/tidspbridge/include/dspbridge/drv.h index c1f363ec9afa..37f5a45b5410 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/drv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/drv.h @@ -65,9 +65,6 @@ #define OMAP_CORE_PRM_BASE 0x48306A00 #define OMAP_CORE_PRM_SIZE 0x1000 -#define OMAP_SYSC_BASE 0x48002000 -#define OMAP_SYSC_SIZE 0x1000 - #define OMAP_DMMU_BASE 0x5D000000 #define OMAP_DMMU_SIZE 0x1000 diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c index 81b1b9013550..c50579ca31e7 100644 --- a/drivers/staging/tidspbridge/rmgr/drv.c +++ b/drivers/staging/tidspbridge/rmgr/drv.c @@ -740,7 +740,6 @@ static int request_bridge_resources(struct cfg_hostres *res) host_res->num_mem_windows = 2; /* First window is for DSP internal memory */ - host_res->dw_sys_ctrl_base = ioremap(OMAP_SYSC_BASE, OMAP_SYSC_SIZE); dev_dbg(bridge, "dw_mem_base[0] 0x%x\n", host_res->dw_mem_base[0]); dev_dbg(bridge, "dw_mem_base[3] 0x%x\n", host_res->dw_mem_base[3]); dev_dbg(bridge, "dw_dmmu_base %p\n", host_res->dw_dmmu_base); -- cgit v1.2.3 From d723818e7c8f20af0a665f5b0c2eda909e069ffa Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Fri, 5 Nov 2010 17:01:48 +0000 Subject: staging: tidspbridge: fix mgr_enum_node_info The current code was always returning a non-zero status value to userspace applications when this ioctl was called. The error code was ENODATA, which isn't actually an error, it's always returned by dcd_enumerate_object() when it hits the end of list. Signed-off-by: Felipe Contreras Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/rmgr/mgr.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/rmgr/mgr.c b/drivers/staging/tidspbridge/rmgr/mgr.c index 0ea89a1bb77c..2eab6a56ab22 100644 --- a/drivers/staging/tidspbridge/rmgr/mgr.c +++ b/drivers/staging/tidspbridge/rmgr/mgr.c @@ -169,6 +169,11 @@ int mgr_enum_node_info(u32 node_id, struct dsp_ndbprops *pndb_props, } } + + /* the last status is not 0, but neither an error */ + if (status > 0) + status = 0; + if (!status) { if (node_id > (node_index - 1)) { status = -EINVAL; -- cgit v1.2.3 From 59403c21afdcd2e89aeadc73b99ccd82d32733b3 Mon Sep 17 00:00:00 2001 From: Ionut Nicu Date: Fri, 5 Nov 2010 17:01:49 +0000 Subject: staging: tidspbridge: mgr_enum_node_info cleanup Reorganized mgr_enum_node_info code to increase its readability. Signed-off-by: Ionut Nicu Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/rmgr/mgr.c | 51 +++++++++++----------------------- 1 file changed, 16 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/rmgr/mgr.c b/drivers/staging/tidspbridge/rmgr/mgr.c index 2eab6a56ab22..16410a5a9b6f 100644 --- a/drivers/staging/tidspbridge/rmgr/mgr.c +++ b/drivers/staging/tidspbridge/rmgr/mgr.c @@ -134,8 +134,7 @@ int mgr_enum_node_info(u32 node_id, struct dsp_ndbprops *pndb_props, u32 undb_props_size, u32 *pu_num_nodes) { int status = 0; - struct dsp_uuid node_uuid, temp_uuid; - u32 temp_index = 0; + struct dsp_uuid node_uuid; u32 node_index = 0; struct dcd_genericobj gen_obj; struct mgr_object *pmgr_obj = NULL; @@ -149,24 +148,27 @@ int mgr_enum_node_info(u32 node_id, struct dsp_ndbprops *pndb_props, *pu_num_nodes = 0; /* Get the Manager Object from the driver data */ if (!drv_datap || !drv_datap->mgr_object) { - status = -ENODATA; pr_err("%s: Failed to retrieve the object handle\n", __func__); - goto func_cont; - } else { - pmgr_obj = drv_datap->mgr_object; + return -ENODATA; } + pmgr_obj = drv_datap->mgr_object; DBC_ASSERT(pmgr_obj); /* Forever loop till we hit failed or no more items in the * Enumeration. We will exit the loop other than 0; */ - while (status == 0) { - status = dcd_enumerate_object(temp_index++, DSP_DCDNODETYPE, - &temp_uuid); - if (status == 0) { - node_index++; - if (node_id == (node_index - 1)) - node_uuid = temp_uuid; - + while (!status) { + status = dcd_enumerate_object(node_index++, DSP_DCDNODETYPE, + &node_uuid); + if (status) + break; + *pu_num_nodes = node_index; + if (node_id == (node_index - 1)) { + status = dcd_get_object_def(pmgr_obj->hdcd_mgr, + &node_uuid, DSP_DCDNODETYPE, &gen_obj); + if (status) + break; + /* Get the Obj def */ + *pndb_props = gen_obj.obj_data.node_obj.ndb_props; } } @@ -174,27 +176,6 @@ int mgr_enum_node_info(u32 node_id, struct dsp_ndbprops *pndb_props, if (status > 0) status = 0; - if (!status) { - if (node_id > (node_index - 1)) { - status = -EINVAL; - } else { - status = dcd_get_object_def(pmgr_obj->hdcd_mgr, - (struct dsp_uuid *) - &node_uuid, DSP_DCDNODETYPE, - &gen_obj); - if (!status) { - /* Get the Obj def */ - *pndb_props = - gen_obj.obj_data.node_obj.ndb_props; - *pu_num_nodes = node_index; - } - } - } - -func_cont: - DBC_ENSURE((!status && *pu_num_nodes > 0) || - (status && *pu_num_nodes == 0)); - return status; } -- cgit v1.2.3 From 74c2d1f63f6fff26503f538ddacf0e45feb15f0d Mon Sep 17 00:00:00 2001 From: Ionut Nicu Date: Fri, 5 Nov 2010 17:01:50 +0000 Subject: staging: tidspbridge: fix kernel oops in bridge_io_get_proc_load The DSP shared memory area gets initialized only when a COFF file is loaded. If bridge_io_get_proc_load is called before loading a base image into the DSP, the shared_mem member of the io manager will be NULL, resulting in a kernel oops when it's dereferenced. Also made some coding style changes to bridge_io_create. Signed-off-by: Ionut Nicu Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/core/io_sm.c | 78 ++++++++++++-------------------- 1 file changed, 30 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 27e0aa81a584..9cea3eacf1a8 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -167,57 +167,41 @@ int bridge_io_create(struct io_mgr **io_man, struct dev_object *hdev_obj, const struct io_attrs *mgr_attrts) { - int status = 0; struct io_mgr *pio_mgr = NULL; - struct shm *shared_mem = NULL; struct bridge_dev_context *hbridge_context = NULL; struct cfg_devnode *dev_node_obj; struct chnl_mgr *hchnl_mgr; u8 dev_type; /* Check requirements */ - if (!io_man || !mgr_attrts || mgr_attrts->word_size == 0) { - status = -EFAULT; - goto func_end; - } + if (!io_man || !mgr_attrts || mgr_attrts->word_size == 0) + return -EFAULT; + + *io_man = NULL; + dev_get_chnl_mgr(hdev_obj, &hchnl_mgr); - if (!hchnl_mgr || hchnl_mgr->hio_mgr) { - status = -EFAULT; - goto func_end; - } + if (!hchnl_mgr || hchnl_mgr->hio_mgr) + return -EFAULT; + /* * Message manager will be created when a file is loaded, since * size of message buffer in shared memory is configurable in * the base image. */ dev_get_bridge_context(hdev_obj, &hbridge_context); - if (!hbridge_context) { - status = -EFAULT; - goto func_end; - } + if (!hbridge_context) + return -EFAULT; + dev_get_dev_type(hdev_obj, &dev_type); - /* - * DSP shared memory area will get set properly when - * a program is loaded. They are unknown until a COFF file is - * loaded. I chose the value -1 because it was less likely to be - * a valid address than 0. - */ - shared_mem = (struct shm *)-1; /* Allocate IO manager object */ pio_mgr = kzalloc(sizeof(struct io_mgr), GFP_KERNEL); - if (pio_mgr == NULL) { - status = -ENOMEM; - goto func_end; - } + if (!pio_mgr) + return -ENOMEM; /* Initialize chnl_mgr object */ -#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG) - pio_mgr->pmsg = NULL; -#endif pio_mgr->hchnl_mgr = hchnl_mgr; pio_mgr->word_size = mgr_attrts->word_size; - pio_mgr->shared_mem = shared_mem; if (dev_type == DSP_UNIT) { /* Create an IO DPC */ @@ -229,29 +213,24 @@ int bridge_io_create(struct io_mgr **io_man, spin_lock_init(&pio_mgr->dpc_lock); - status = dev_get_dev_node(hdev_obj, &dev_node_obj); + if (dev_get_dev_node(hdev_obj, &dev_node_obj)) { + bridge_io_destroy(pio_mgr); + return -EIO; + } } - if (!status) { - pio_mgr->hbridge_context = hbridge_context; - pio_mgr->shared_irq = mgr_attrts->irq_shared; - if (dsp_wdt_init()) - status = -EPERM; - } else { - status = -EIO; - } -func_end: - if (status) { - /* Cleanup */ + pio_mgr->hbridge_context = hbridge_context; + pio_mgr->shared_irq = mgr_attrts->irq_shared; + if (dsp_wdt_init()) { bridge_io_destroy(pio_mgr); - if (io_man) - *io_man = NULL; - } else { - /* Return IO manager object to caller... */ - hchnl_mgr->hio_mgr = pio_mgr; - *io_man = pio_mgr; + return -EPERM; } - return status; + + /* Return IO manager object to caller... */ + hchnl_mgr->hio_mgr = pio_mgr; + *io_man = pio_mgr; + + return 0; } /* @@ -1714,6 +1693,9 @@ int io_sh_msetting(struct io_mgr *hio_mgr, u8 desc, void *pargs) int bridge_io_get_proc_load(struct io_mgr *hio_mgr, struct dsp_procloadstat *proc_lstat) { + if (!hio_mgr->shared_mem) + return -EFAULT; + proc_lstat->curr_load = hio_mgr->shared_mem->load_mon_info.curr_dsp_load; proc_lstat->predicted_load = -- cgit v1.2.3 From 31de278078aeb869467cbde0877d7f1027ab844c Mon Sep 17 00:00:00 2001 From: Ionut Nicu Date: Sun, 21 Nov 2010 10:46:19 +0000 Subject: staging: tidspbridge: remove gs memory allocator Remove unnecessary wrappers for linux kernel memory allocation primitives. Signed-off-by: Ionut Nicu Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/Makefile | 2 +- drivers/staging/tidspbridge/gen/gb.c | 11 ++- drivers/staging/tidspbridge/gen/gh.c | 38 +++------- drivers/staging/tidspbridge/gen/gs.c | 88 ---------------------- drivers/staging/tidspbridge/include/dspbridge/gs.h | 59 --------------- 5 files changed, 15 insertions(+), 183 deletions(-) delete mode 100644 drivers/staging/tidspbridge/gen/gs.c delete mode 100644 drivers/staging/tidspbridge/include/dspbridge/gs.h (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/Makefile b/drivers/staging/tidspbridge/Makefile index 41c644c3318f..648e392ce7ab 100644 --- a/drivers/staging/tidspbridge/Makefile +++ b/drivers/staging/tidspbridge/Makefile @@ -1,6 +1,6 @@ obj-$(CONFIG_TIDSPBRIDGE) += bridgedriver.o -libgen = gen/gb.o gen/gs.o gen/gh.o gen/uuidutil.o +libgen = gen/gb.o gen/gh.o gen/uuidutil.o libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \ core/tiomap3430_pwr.o core/tiomap_io.o \ core/ue_deh.o core/wdt.o core/dsp-clock.o core/sync.o diff --git a/drivers/staging/tidspbridge/gen/gb.c b/drivers/staging/tidspbridge/gen/gb.c index 9f590230473b..3c0e04cc2b0f 100644 --- a/drivers/staging/tidspbridge/gen/gb.c +++ b/drivers/staging/tidspbridge/gen/gb.c @@ -19,7 +19,6 @@ /* ----------------------------------- DSP/BIOS Bridge */ #include /* ----------------------------------- This */ -#include #include struct gb_t_map { @@ -52,17 +51,17 @@ struct gb_t_map *gb_create(u32 len) { struct gb_t_map *map; u32 i; - map = (struct gb_t_map *)gs_alloc(sizeof(struct gb_t_map)); + map = kzalloc(sizeof(struct gb_t_map), GFP_KERNEL); if (map != NULL) { map->len = len; map->wcnt = len / BITS_PER_LONG + 1; - map->words = (u32 *) gs_alloc(map->wcnt * sizeof(u32)); + map->words = kzalloc(map->wcnt * sizeof(u32), GFP_KERNEL); if (map->words != NULL) { for (i = 0; i < map->wcnt; i++) map->words[i] = 0L; } else { - gs_frees(map, sizeof(struct gb_t_map)); + kfree(map); map = NULL; } } @@ -78,8 +77,8 @@ struct gb_t_map *gb_create(u32 len) void gb_delete(struct gb_t_map *map) { - gs_frees(map->words, map->wcnt * sizeof(u32)); - gs_frees(map, sizeof(struct gb_t_map)); + kfree(map->words); + kfree(map); } /* diff --git a/drivers/staging/tidspbridge/gen/gh.c b/drivers/staging/tidspbridge/gen/gh.c index f72d943c4806..cd725033f274 100644 --- a/drivers/staging/tidspbridge/gen/gh.c +++ b/drivers/staging/tidspbridge/gen/gh.c @@ -17,9 +17,6 @@ #include #include - -#include - #include struct element { @@ -37,8 +34,6 @@ struct gh_t_hash_tab { }; static void noop(void *p); -static s32 cur_init; -static void myfree(void *ptr, s32 size); /* * ======== gh_create ======== @@ -51,8 +46,7 @@ struct gh_t_hash_tab *gh_create(u16 max_bucket, u16 val_size, { struct gh_t_hash_tab *hash_tab; u16 i; - hash_tab = - (struct gh_t_hash_tab *)gs_alloc(sizeof(struct gh_t_hash_tab)); + hash_tab = kzalloc(sizeof(struct gh_t_hash_tab), GFP_KERNEL); if (hash_tab == NULL) return NULL; hash_tab->max_bucket = max_bucket; @@ -62,7 +56,7 @@ struct gh_t_hash_tab *gh_create(u16 max_bucket, u16 val_size, hash_tab->delete = delete == NULL ? noop : delete; hash_tab->buckets = (struct element **) - gs_alloc(sizeof(struct element *) * max_bucket); + kzalloc(sizeof(struct element *) * max_bucket, GFP_KERNEL); if (hash_tab->buckets == NULL) { gh_delete(hash_tab); return NULL; @@ -89,17 +83,14 @@ void gh_delete(struct gh_t_hash_tab *hash_tab) elem = next) { next = elem->next; (*hash_tab->delete) (elem->data); - myfree(elem, - sizeof(struct element) - 1 + - hash_tab->val_size); + kfree(elem); } } - myfree(hash_tab->buckets, sizeof(struct element *) - * hash_tab->max_bucket); + kfree(hash_tab->buckets); } - myfree(hash_tab, sizeof(struct gh_t_hash_tab)); + kfree(hash_tab); } } @@ -109,9 +100,7 @@ void gh_delete(struct gh_t_hash_tab *hash_tab) void gh_exit(void) { - if (cur_init-- == 1) - gs_exit(); - + /* Do nothing */ } /* @@ -138,8 +127,7 @@ void *gh_find(struct gh_t_hash_tab *hash_tab, void *key) void gh_init(void) { - if (cur_init++ == 0) - gs_init(); + /* Do nothing */ } /* @@ -152,8 +140,8 @@ void *gh_insert(struct gh_t_hash_tab *hash_tab, void *key, void *value) u16 i; char *src, *dst; - elem = (struct element *)gs_alloc(sizeof(struct element) - 1 + - hash_tab->val_size); + elem = kzalloc(sizeof(struct element) - 1 + hash_tab->val_size, + GFP_KERNEL); if (elem != NULL) { dst = (char *)elem->data; @@ -180,14 +168,6 @@ static void noop(void *p) p = p; /* stifle compiler warning */ } -/* - * ======== myfree ======== - */ -static void myfree(void *ptr, s32 size) -{ - gs_free(ptr); -} - #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE /** * gh_iterate() - This function goes through all the elements in the hash table diff --git a/drivers/staging/tidspbridge/gen/gs.c b/drivers/staging/tidspbridge/gen/gs.c deleted file mode 100644 index 8335bf5e2744..000000000000 --- a/drivers/staging/tidspbridge/gen/gs.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * gs.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * General storage memory allocator services. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include -/* ----------------------------------- DSP/BIOS Bridge */ -#include - -/* ----------------------------------- This */ -#include - -#include - -/* ----------------------------------- Globals */ -static u32 cumsize; - -/* - * ======== gs_alloc ======== - * purpose: - * Allocates memory of the specified size. - */ -void *gs_alloc(u32 size) -{ - void *p; - - p = kzalloc(size, GFP_KERNEL); - if (p == NULL) - return NULL; - cumsize += size; - return p; -} - -/* - * ======== gs_exit ======== - * purpose: - * Discontinue the usage of the GS module. - */ -void gs_exit(void) -{ - /* Do nothing */ -} - -/* - * ======== gs_free ======== - * purpose: - * Frees the memory. - */ -void gs_free(void *ptr) -{ - kfree(ptr); - /* ack! no size info */ - /* cumsize -= size; */ -} - -/* - * ======== gs_frees ======== - * purpose: - * Frees the memory. - */ -void gs_frees(void *ptr, u32 size) -{ - kfree(ptr); - cumsize -= size; -} - -/* - * ======== gs_init ======== - * purpose: - * Initializes the GS module. - */ -void gs_init(void) -{ - /* Do nothing */ -} diff --git a/drivers/staging/tidspbridge/include/dspbridge/gs.h b/drivers/staging/tidspbridge/include/dspbridge/gs.h deleted file mode 100644 index f32d8d9af415..000000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/gs.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * gs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Memory allocation/release wrappers. This module allows clients to - * avoid OS spacific issues related to memory allocation. It also provides - * simple diagnostic capabilities to assist in the detection of memory - * leaks. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef GS_ -#define GS_ - -/* - * ======== gs_alloc ======== - * Alloc size bytes of space. Returns pointer to space - * allocated, otherwise NULL. - */ -extern void *gs_alloc(u32 size); - -/* - * ======== gs_exit ======== - * Module exit. Do not change to "#define gs_init()"; in - * some environments this operation must actually do some work! - */ -extern void gs_exit(void); - -/* - * ======== gs_free ======== - * Free space allocated by gs_alloc() or GS_calloc(). - */ -extern void gs_free(void *ptr); - -/* - * ======== gs_frees ======== - * Free space allocated by gs_alloc() or GS_calloc() and assert that - * the size of the allocation is size bytes. - */ -extern void gs_frees(void *ptr, u32 size); - -/* - * ======== gs_init ======== - * Module initialization. Do not change to "#define gs_init()"; in - * some environments this operation must actually do some work! - */ -extern void gs_init(void); - -#endif /*GS_ */ -- cgit v1.2.3 From ad4adcc495363fb2506d82c9cab0f71dea83ea9b Mon Sep 17 00:00:00 2001 From: Ionut Nicu Date: Sun, 21 Nov 2010 10:46:20 +0000 Subject: staging: tidspbridge: remove utildefs Remove a header file that was not very useful to the dspbridge driver. Signed-off-by: Ionut Nicu Signed-off-by: Omar Ramirez Luna --- .../tidspbridge/include/dspbridge/utildefs.h | 39 ---------------------- drivers/staging/tidspbridge/pmgr/cmm.c | 9 +---- 2 files changed, 1 insertion(+), 47 deletions(-) delete mode 100644 drivers/staging/tidspbridge/include/dspbridge/utildefs.h (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/include/dspbridge/utildefs.h b/drivers/staging/tidspbridge/include/dspbridge/utildefs.h deleted file mode 100644 index 8fe5414824ce..000000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/utildefs.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * utildefs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Global UTIL constants and types, shared between DSP API and DSPSYS. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef UTILDEFS_ -#define UTILDEFS_ - -/* constants taken from configmg.h */ -#define UTIL_MAXMEMREGS 9 -#define UTIL_MAXIOPORTS 20 -#define UTIL_MAXIRQS 7 -#define UTIL_MAXDMACHNLS 7 - -/* misc. constants */ -#define UTIL_MAXARGVS 10 - -/* Platform specific important info */ -struct util_sysinfo { - /* Granularity of page protection; usually 1k or 4k */ - u32 dw_page_size; - u32 dw_allocation_granularity; /* VM granularity, usually 64K */ - u32 dw_number_of_processors; /* Used as sanity check */ -}; - -#endif /* UTILDEFS_ */ diff --git a/drivers/staging/tidspbridge/pmgr/cmm.c b/drivers/staging/tidspbridge/pmgr/cmm.c index 93a7c4fd57e4..8dbdd20c4e9e 100644 --- a/drivers/staging/tidspbridge/pmgr/cmm.c +++ b/drivers/staging/tidspbridge/pmgr/cmm.c @@ -40,7 +40,6 @@ /* ----------------------------------- OS Adaptation Layer */ #include #include -#include /* ----------------------------------- Platform Manager */ #include @@ -245,7 +244,6 @@ int cmm_create(struct cmm_object **ph_cmm_mgr, { struct cmm_object *cmm_obj = NULL; int status = 0; - struct util_sysinfo sys_info; DBC_REQUIRE(refs > 0); DBC_REQUIRE(ph_cmm_mgr != NULL); @@ -261,12 +259,7 @@ int cmm_create(struct cmm_object **ph_cmm_mgr, DBC_ASSERT(mgr_attrts->ul_min_block_size >= 4); /* save away smallest block allocation for this cmm mgr */ cmm_obj->ul_min_block_size = mgr_attrts->ul_min_block_size; - /* save away the systems memory page size */ - sys_info.dw_page_size = PAGE_SIZE; - sys_info.dw_allocation_granularity = PAGE_SIZE; - sys_info.dw_number_of_processors = 1; - - cmm_obj->dw_page_size = sys_info.dw_page_size; + cmm_obj->dw_page_size = PAGE_SIZE; /* Note: DSP SM seg table(aDSPSMSegTab[]) zero'd by * MEM_ALLOC_OBJECT */ -- cgit v1.2.3 From b5a38abad033f6075e2c4cbfc4507cc7e82c36d2 Mon Sep 17 00:00:00 2001 From: Ionut Nicu Date: Sun, 21 Nov 2010 10:46:21 +0000 Subject: staging: tidspbridge: switch to linux bitmap API Replace the tidspbridge generic bitmap operations with the linux standard bitmap implementation. Signed-off-by: Ionut Nicu Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/rmgr/node.c | 164 ++++++++++++++------------------ 1 file changed, 73 insertions(+), 91 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index 1562f3c1281c..ab35806591da 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -17,6 +17,7 @@ */ #include +#include /* ----------------------------------- Host OS */ #include @@ -50,7 +51,6 @@ #include /* ----------------------------------- Others */ -#include #include /* ----------------------------------- This */ @@ -132,11 +132,14 @@ struct node_mgr { struct lst_list *node_list; /* List of all allocated nodes */ u32 num_nodes; /* Number of nodes in node_list */ u32 num_created; /* Number of nodes *created* on DSP */ - struct gb_t_map *pipe_map; /* Pipe connection bit map */ - struct gb_t_map *pipe_done_map; /* Pipes that are half free */ - struct gb_t_map *chnl_map; /* Channel allocation bit map */ - struct gb_t_map *dma_chnl_map; /* DMA Channel allocation bit map */ - struct gb_t_map *zc_chnl_map; /* Zero-Copy Channel alloc bit map */ + DECLARE_BITMAP(pipe_map, MAXPIPES); /* Pipe connection bitmap */ + DECLARE_BITMAP(pipe_done_map, MAXPIPES); /* Pipes that are half free */ + /* Channel allocation bitmap */ + DECLARE_BITMAP(chnl_map, CHNL_MAXCHANNELS); + /* DMA Channel allocation bitmap */ + DECLARE_BITMAP(dma_chnl_map, CHNL_MAXCHANNELS); + /* Zero-Copy Channel alloc bitmap */ + DECLARE_BITMAP(zc_chnl_map, CHNL_MAXCHANNELS); struct ntfy_object *ntfy_obj; /* Manages registered notifications */ struct mutex node_mgr_lock; /* For critical sections */ u32 ul_fxn_addrs[NUMRMSFXNS]; /* RMS function addresses */ @@ -847,8 +850,8 @@ int node_connect(struct node_object *node1, u32 stream1, struct node_object *dev_node_obj; struct node_object *hnode; struct stream_chnl *pstream; - u32 pipe_id = GB_NOBITS; - u32 chnl_id = GB_NOBITS; + u32 pipe_id; + u32 chnl_id; s8 chnl_mode; u32 dw_length; int status = 0; @@ -951,10 +954,11 @@ int node_connect(struct node_object *node1, u32 stream1, && (node2_type == NODE_TASK || node2_type == NODE_DAISSOCKET))) { /* Find available pipe */ - pipe_id = gb_findandset(hnode_mgr->pipe_map); - if (pipe_id == GB_NOBITS) { + pipe_id = find_first_zero_bit(hnode_mgr->pipe_map, MAXPIPES); + if (pipe_id == MAXPIPES) { status = -ECONNREFUSED; } else { + set_bit(pipe_id, hnode_mgr->pipe_map); node1->outputs[stream1].type = NODECONNECT; node2->inputs[stream2].type = NODECONNECT; node1->outputs[stream1].dev_id = pipe_id; @@ -971,7 +975,7 @@ int node_connect(struct node_object *node1, u32 stream1, output->sz_device = NULL; input->sz_device = NULL; - gb_clear(hnode_mgr->pipe_map, pipe_id); + clear_bit(pipe_id, hnode_mgr->pipe_map); status = -ENOMEM; } else { /* Copy "/dbpipe" name to device names */ @@ -996,34 +1000,47 @@ int node_connect(struct node_object *node1, u32 stream1, * called for this node. */ if (pattrs) { if (pattrs->strm_mode == STRMMODE_RDMA) { - chnl_id = - gb_findandset(hnode_mgr->dma_chnl_map); + chnl_id = find_first_zero_bit( + hnode_mgr->dma_chnl_map, + CHNL_MAXCHANNELS); /* dma chans are 2nd transport chnl set * ids(e.g. 16-31) */ - (chnl_id != GB_NOBITS) ? - (chnl_id = - chnl_id + - hnode_mgr->ul_num_chnls) : chnl_id; + if (chnl_id != CHNL_MAXCHANNELS) { + set_bit(chnl_id, + hnode_mgr->dma_chnl_map); + chnl_id = chnl_id + + hnode_mgr->ul_num_chnls; + } } else if (pattrs->strm_mode == STRMMODE_ZEROCOPY) { - chnl_id = gb_findandset(hnode_mgr->zc_chnl_map); + chnl_id = find_first_zero_bit( + hnode_mgr->zc_chnl_map, + CHNL_MAXCHANNELS); /* zero-copy chans are 3nd transport set * (e.g. 32-47) */ - (chnl_id != GB_NOBITS) ? (chnl_id = chnl_id + - (2 * - hnode_mgr-> - ul_num_chnls)) - : chnl_id; + if (chnl_id != CHNL_MAXCHANNELS) { + set_bit(chnl_id, + hnode_mgr->zc_chnl_map); + chnl_id = chnl_id + + (2 * hnode_mgr->ul_num_chnls); + } } else { /* must be PROCCOPY */ DBC_ASSERT(pattrs->strm_mode == STRMMODE_PROCCOPY); - chnl_id = gb_findandset(hnode_mgr->chnl_map); + chnl_id = find_first_zero_bit( + hnode_mgr->chnl_map, + CHNL_MAXCHANNELS); /* e.g. 0-15 */ + if (chnl_id != CHNL_MAXCHANNELS) + set_bit(chnl_id, hnode_mgr->chnl_map); } } else { /* default to PROCCOPY */ - chnl_id = gb_findandset(hnode_mgr->chnl_map); + chnl_id = find_first_zero_bit(hnode_mgr->chnl_map, + CHNL_MAXCHANNELS); + if (chnl_id != CHNL_MAXCHANNELS) + set_bit(chnl_id, hnode_mgr->chnl_map); } - if (chnl_id == GB_NOBITS) { + if (chnl_id == CHNL_MAXCHANNELS) { status = -ECONNREFUSED; goto func_cont2; } @@ -1033,18 +1050,19 @@ int node_connect(struct node_object *node1, u32 stream1, if (pattrs) { if (pattrs->strm_mode == STRMMODE_RDMA) { - gb_clear(hnode_mgr->dma_chnl_map, chnl_id - - hnode_mgr->ul_num_chnls); + clear_bit(chnl_id - hnode_mgr->ul_num_chnls, + hnode_mgr->dma_chnl_map); } else if (pattrs->strm_mode == STRMMODE_ZEROCOPY) { - gb_clear(hnode_mgr->zc_chnl_map, chnl_id - - (2 * hnode_mgr->ul_num_chnls)); + clear_bit(chnl_id - + (2 * hnode_mgr->ul_num_chnls), + hnode_mgr->zc_chnl_map); } else { DBC_ASSERT(pattrs->strm_mode == STRMMODE_PROCCOPY); - gb_clear(hnode_mgr->chnl_map, chnl_id); + clear_bit(chnl_id, hnode_mgr->chnl_map); } } else { - gb_clear(hnode_mgr->chnl_map, chnl_id); + clear_bit(chnl_id, hnode_mgr->chnl_map); } status = -ENOMEM; func_cont2: @@ -1321,22 +1339,14 @@ int node_create_mgr(struct node_mgr **node_man, if (node_mgr_obj) { node_mgr_obj->hdev_obj = hdev_obj; node_mgr_obj->node_list = kzalloc(sizeof(struct lst_list), - GFP_KERNEL); - node_mgr_obj->pipe_map = gb_create(MAXPIPES); - node_mgr_obj->pipe_done_map = gb_create(MAXPIPES); - if (node_mgr_obj->node_list == NULL - || node_mgr_obj->pipe_map == NULL - || node_mgr_obj->pipe_done_map == NULL) { - status = -ENOMEM; - } else { - INIT_LIST_HEAD(&node_mgr_obj->node_list->head); - node_mgr_obj->ntfy_obj = kmalloc( + GFP_KERNEL); + INIT_LIST_HEAD(&node_mgr_obj->node_list->head); + node_mgr_obj->ntfy_obj = kmalloc( sizeof(struct ntfy_object), GFP_KERNEL); - if (node_mgr_obj->ntfy_obj) - ntfy_init(node_mgr_obj->ntfy_obj); - else - status = -ENOMEM; - } + if (node_mgr_obj->ntfy_obj) + ntfy_init(node_mgr_obj->ntfy_obj); + else + status = -ENOMEM; node_mgr_obj->num_created = 0; } else { status = -ENOMEM; @@ -1372,27 +1382,14 @@ int node_create_mgr(struct node_mgr **node_man, /* Get msg_ctrl queue manager */ dev_get_msg_mgr(hdev_obj, &node_mgr_obj->msg_mgr_obj); mutex_init(&node_mgr_obj->node_mgr_lock); - node_mgr_obj->chnl_map = gb_create(node_mgr_obj->ul_num_chnls); - /* dma chnl map. ul_num_chnls is # per transport */ - node_mgr_obj->dma_chnl_map = - gb_create(node_mgr_obj->ul_num_chnls); - node_mgr_obj->zc_chnl_map = - gb_create(node_mgr_obj->ul_num_chnls); - if ((node_mgr_obj->chnl_map == NULL) - || (node_mgr_obj->dma_chnl_map == NULL) - || (node_mgr_obj->zc_chnl_map == NULL)) { - status = -ENOMEM; - } else { - /* Block out reserved channels */ - for (i = 0; i < node_mgr_obj->ul_chnl_offset; i++) - gb_set(node_mgr_obj->chnl_map, i); + /* Block out reserved channels */ + for (i = 0; i < node_mgr_obj->ul_chnl_offset; i++) + set_bit(i, node_mgr_obj->chnl_map); - /* Block out channels reserved for RMS */ - gb_set(node_mgr_obj->chnl_map, - node_mgr_obj->ul_chnl_offset); - gb_set(node_mgr_obj->chnl_map, - node_mgr_obj->ul_chnl_offset + 1); - } + /* Block out channels reserved for RMS */ + set_bit(node_mgr_obj->ul_chnl_offset, node_mgr_obj->chnl_map); + set_bit(node_mgr_obj->ul_chnl_offset + 1, + node_mgr_obj->chnl_map); } if (!status) { /* NO RM Server on the IVA */ @@ -2657,21 +2654,6 @@ static void delete_node_mgr(struct node_mgr *hnode_mgr) kfree(hnode_mgr->ntfy_obj); } - if (hnode_mgr->pipe_map) - gb_delete(hnode_mgr->pipe_map); - - if (hnode_mgr->pipe_done_map) - gb_delete(hnode_mgr->pipe_done_map); - - if (hnode_mgr->chnl_map) - gb_delete(hnode_mgr->chnl_map); - - if (hnode_mgr->dma_chnl_map) - gb_delete(hnode_mgr->dma_chnl_map); - - if (hnode_mgr->zc_chnl_map) - gb_delete(hnode_mgr->zc_chnl_map); - if (hnode_mgr->disp_obj) disp_delete(hnode_mgr->disp_obj); @@ -2786,25 +2768,25 @@ static void free_stream(struct node_mgr *hnode_mgr, struct stream_chnl stream) { /* Free up the pipe id unless other node has not yet been deleted. */ if (stream.type == NODECONNECT) { - if (gb_test(hnode_mgr->pipe_done_map, stream.dev_id)) { + if (test_bit(stream.dev_id, hnode_mgr->pipe_done_map)) { /* The other node has already been deleted */ - gb_clear(hnode_mgr->pipe_done_map, stream.dev_id); - gb_clear(hnode_mgr->pipe_map, stream.dev_id); + clear_bit(stream.dev_id, hnode_mgr->pipe_done_map); + clear_bit(stream.dev_id, hnode_mgr->pipe_map); } else { /* The other node has not been deleted yet */ - gb_set(hnode_mgr->pipe_done_map, stream.dev_id); + set_bit(stream.dev_id, hnode_mgr->pipe_done_map); } } else if (stream.type == HOSTCONNECT) { if (stream.dev_id < hnode_mgr->ul_num_chnls) { - gb_clear(hnode_mgr->chnl_map, stream.dev_id); + clear_bit(stream.dev_id, hnode_mgr->chnl_map); } else if (stream.dev_id < (2 * hnode_mgr->ul_num_chnls)) { /* dsp-dma */ - gb_clear(hnode_mgr->dma_chnl_map, stream.dev_id - - (1 * hnode_mgr->ul_num_chnls)); + clear_bit(stream.dev_id - (1 * hnode_mgr->ul_num_chnls), + hnode_mgr->dma_chnl_map); } else if (stream.dev_id < (3 * hnode_mgr->ul_num_chnls)) { /* zero-copy */ - gb_clear(hnode_mgr->zc_chnl_map, stream.dev_id - - (2 * hnode_mgr->ul_num_chnls)); + clear_bit(stream.dev_id - (2 * hnode_mgr->ul_num_chnls), + hnode_mgr->zc_chnl_map); } } } -- cgit v1.2.3 From 6d7e925b88cd8436b1284158876580ea431cb954 Mon Sep 17 00:00:00 2001 From: Ionut Nicu Date: Sun, 21 Nov 2010 10:46:22 +0000 Subject: staging: tidspbridge: remove gb bitmap implementation Now that all users of gb have been converted to the standard linux bitmap API, we can remove it from the gen library. Signed-off-by: Ionut Nicu Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/Makefile | 2 +- drivers/staging/tidspbridge/gen/gb.c | 165 --------------------- drivers/staging/tidspbridge/include/dspbridge/gb.h | 79 ---------- 3 files changed, 1 insertion(+), 245 deletions(-) delete mode 100644 drivers/staging/tidspbridge/gen/gb.c delete mode 100644 drivers/staging/tidspbridge/include/dspbridge/gb.h (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/Makefile b/drivers/staging/tidspbridge/Makefile index 648e392ce7ab..fd6a2761cc3b 100644 --- a/drivers/staging/tidspbridge/Makefile +++ b/drivers/staging/tidspbridge/Makefile @@ -1,6 +1,6 @@ obj-$(CONFIG_TIDSPBRIDGE) += bridgedriver.o -libgen = gen/gb.o gen/gh.o gen/uuidutil.o +libgen = gen/gh.o gen/uuidutil.o libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \ core/tiomap3430_pwr.o core/tiomap_io.o \ core/ue_deh.o core/wdt.o core/dsp-clock.o core/sync.o diff --git a/drivers/staging/tidspbridge/gen/gb.c b/drivers/staging/tidspbridge/gen/gb.c deleted file mode 100644 index 3c0e04cc2b0f..000000000000 --- a/drivers/staging/tidspbridge/gen/gb.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * gb.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Generic bitmap operations. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -/* ----------------------------------- DSP/BIOS Bridge */ -#include -/* ----------------------------------- This */ -#include - -struct gb_t_map { - u32 len; - u32 wcnt; - u32 *words; -}; - -/* - * ======== gb_clear ======== - * purpose: - * Clears a bit in the bit map. - */ - -void gb_clear(struct gb_t_map *map, u32 bitn) -{ - u32 mask; - - mask = 1L << (bitn % BITS_PER_LONG); - map->words[bitn / BITS_PER_LONG] &= ~mask; -} - -/* - * ======== gb_create ======== - * purpose: - * Creates a bit map. - */ - -struct gb_t_map *gb_create(u32 len) -{ - struct gb_t_map *map; - u32 i; - map = kzalloc(sizeof(struct gb_t_map), GFP_KERNEL); - if (map != NULL) { - map->len = len; - map->wcnt = len / BITS_PER_LONG + 1; - map->words = kzalloc(map->wcnt * sizeof(u32), GFP_KERNEL); - if (map->words != NULL) { - for (i = 0; i < map->wcnt; i++) - map->words[i] = 0L; - - } else { - kfree(map); - map = NULL; - } - } - - return map; -} - -/* - * ======== gb_delete ======== - * purpose: - * Frees a bit map. - */ - -void gb_delete(struct gb_t_map *map) -{ - kfree(map->words); - kfree(map); -} - -/* - * ======== gb_findandset ======== - * purpose: - * Finds a free bit and sets it. - */ -u32 gb_findandset(struct gb_t_map *map) -{ - u32 bitn; - - bitn = gb_minclear(map); - - if (bitn != GB_NOBITS) - gb_set(map, bitn); - - return bitn; -} - -/* - * ======== gb_minclear ======== - * purpose: - * returns the location of the first unset bit in the bit map. - */ -u32 gb_minclear(struct gb_t_map *map) -{ - u32 bit_location = 0; - u32 bit_acc = 0; - u32 i; - u32 bit; - u32 *word; - - for (word = map->words, i = 0; i < map->wcnt; word++, i++) { - if (~*word) { - for (bit = 0; bit < BITS_PER_LONG; bit++, bit_acc++) { - if (bit_acc == map->len) - return GB_NOBITS; - - if (~*word & (1L << bit)) { - bit_location = i * BITS_PER_LONG + bit; - return bit_location; - } - - } - } else { - bit_acc += BITS_PER_LONG; - } - } - - return GB_NOBITS; -} - -/* - * ======== gb_set ======== - * purpose: - * Sets a bit in the bit map. - */ - -void gb_set(struct gb_t_map *map, u32 bitn) -{ - u32 mask; - - mask = 1L << (bitn % BITS_PER_LONG); - map->words[bitn / BITS_PER_LONG] |= mask; -} - -/* - * ======== gb_test ======== - * purpose: - * Returns true if the bit is set in the specified location. - */ - -bool gb_test(struct gb_t_map *map, u32 bitn) -{ - bool state; - u32 mask; - u32 word; - - mask = 1L << (bitn % BITS_PER_LONG); - word = map->words[bitn / BITS_PER_LONG]; - state = word & mask ? true : false; - - return state; -} diff --git a/drivers/staging/tidspbridge/include/dspbridge/gb.h b/drivers/staging/tidspbridge/include/dspbridge/gb.h deleted file mode 100644 index fda783aa160c..000000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/gb.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * gb.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Generic bitmap manager. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef GB_ -#define GB_ - -#define GB_NOBITS (~0) -#include - -struct gb_t_map; - -/* - * ======== gb_clear ======== - * Clear the bit in position bitn in the bitmap map. Bit positions are - * zero based. - */ - -extern void gb_clear(struct gb_t_map *map, u32 bitn); - -/* - * ======== gb_create ======== - * Create a bit map with len bits. Initially all bits are cleared. - */ - -extern struct gb_t_map *gb_create(u32 len); - -/* - * ======== gb_delete ======== - * Delete previously created bit map - */ - -extern void gb_delete(struct gb_t_map *map); - -/* - * ======== gb_findandset ======== - * Finds a clear bit, sets it, and returns the position - */ - -extern u32 gb_findandset(struct gb_t_map *map); - -/* - * ======== gb_minclear ======== - * gb_minclear returns the minimum clear bit position. If no bit is - * clear, gb_minclear returns -1. - */ -extern u32 gb_minclear(struct gb_t_map *map); - -/* - * ======== gb_set ======== - * Set the bit in position bitn in the bitmap map. Bit positions are - * zero based. - */ - -extern void gb_set(struct gb_t_map *map, u32 bitn); - -/* - * ======== gb_test ======== - * Returns TRUE if the bit in position bitn is set in map; otherwise - * gb_test returns FALSE. Bit positions are zero based. - */ - -extern bool gb_test(struct gb_t_map *map, u32 bitn); - -#endif /*GB_ */ -- cgit v1.2.3 From 3c6bf30f1e520b250242da39a493986b8b2cef53 Mon Sep 17 00:00:00 2001 From: Ionut Nicu Date: Sun, 21 Nov 2010 10:46:24 +0000 Subject: staging: tidspbridge: convert core to list_head Convert the core module of the tidspbridge driver to use struct list_head instead of struct lst_list. Signed-off-by: Ionut Nicu Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/core/_msg_sm.h | 12 +- drivers/staging/tidspbridge/core/chnl_sm.c | 245 +++++++++------------ drivers/staging/tidspbridge/core/io_sm.c | 142 ++++++------ drivers/staging/tidspbridge/core/msg_sm.c | 236 ++++++++------------ .../tidspbridge/include/dspbridge/_chnl_sm.h | 8 +- .../tidspbridge/include/dspbridge/cmmdefs.h | 1 - .../staging/tidspbridge/include/dspbridge/sync.h | 1 + 7 files changed, 264 insertions(+), 381 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/_msg_sm.h b/drivers/staging/tidspbridge/core/_msg_sm.h index 556de5c025dd..b78d1a655300 100644 --- a/drivers/staging/tidspbridge/core/_msg_sm.h +++ b/drivers/staging/tidspbridge/core/_msg_sm.h @@ -20,7 +20,7 @@ #ifndef _MSG_SM_ #define _MSG_SM_ -#include +#include #include /* @@ -86,12 +86,12 @@ struct msg_mgr { struct bridge_drv_interface *intf_fxns; struct io_mgr *hio_mgr; /* IO manager */ - struct lst_list *queue_list; /* List of MSG_QUEUEs */ + struct list_head queue_list; /* List of MSG_QUEUEs */ spinlock_t msg_mgr_lock; /* For critical sections */ /* Signalled when MsgFrame is available */ struct sync_object *sync_event; - struct lst_list *msg_free_list; /* Free MsgFrames ready to be filled */ - struct lst_list *msg_used_list; /* MsgFrames ready to go to DSP */ + struct list_head msg_free_list; /* Free MsgFrames ready to be filled */ + struct list_head msg_used_list; /* MsgFrames ready to go to DSP */ u32 msgs_pending; /* # of queued messages to go to DSP */ u32 max_msgs; /* Max # of msgs that fit in buffer */ msg_onexit on_exit; /* called when RMS_EXIT is received */ @@ -111,9 +111,9 @@ struct msg_queue { struct msg_mgr *hmsg_mgr; u32 max_msgs; /* Node message depth */ u32 msgq_id; /* Node environment pointer */ - struct lst_list *msg_free_list; /* Free MsgFrames ready to be filled */ + struct list_head msg_free_list; /* Free MsgFrames ready to be filled */ /* Filled MsgFramess waiting to be read */ - struct lst_list *msg_used_list; + struct list_head msg_used_list; void *arg; /* Handle passed to mgr on_exit callback */ struct sync_object *sync_event; /* Signalled when message is ready */ struct sync_object *sync_done; /* For synchronizing cleanup */ diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c index 662a5b5a58e3..f9550363b94f 100644 --- a/drivers/staging/tidspbridge/core/chnl_sm.c +++ b/drivers/staging/tidspbridge/core/chnl_sm.c @@ -37,9 +37,9 @@ * which may cause timeouts and/or failure offunction sync_wait_on_event. * This invariant condition is: * - * LST_Empty(pchnl->pio_completions) ==> pchnl->sync_event is reset + * list_empty(&pchnl->pio_completions) ==> pchnl->sync_event is reset * and - * !LST_Empty(pchnl->pio_completions) ==> pchnl->sync_event is set. + * !list_empty(&pchnl->pio_completions) ==> pchnl->sync_event is set. */ #include @@ -73,11 +73,9 @@ #define MAILBOX_IRQ INT_MAIL_MPU_IRQ /* ----------------------------------- Function Prototypes */ -static struct lst_list *create_chirp_list(u32 chirps); +static int create_chirp_list(struct list_head *list, u32 chirps); -static void free_chirp_list(struct lst_list *chirp_list); - -static struct chnl_irp *make_new_chirp(void); +static void free_chirp_list(struct list_head *list); static int search_free_channel(struct chnl_mgr *chnl_mgr_obj, u32 *chnl); @@ -179,10 +177,14 @@ func_cont: } if (!status) { /* Get a free chirp: */ - chnl_packet_obj = - (struct chnl_irp *)lst_get_head(pchnl->free_packets_list); - if (chnl_packet_obj == NULL) + if (!list_empty(&pchnl->free_packets_list)) { + chnl_packet_obj = list_first_entry( + &pchnl->free_packets_list, + struct chnl_irp, link); + list_del(&chnl_packet_obj->link); + } else { status = -EIO; + } } if (!status) { @@ -206,8 +208,7 @@ func_cont: chnl_packet_obj->dw_arg = dw_arg; chnl_packet_obj->status = (is_eos ? CHNL_IOCSTATEOS : CHNL_IOCSTATCOMPLETE); - lst_put_tail(pchnl->pio_requests, - (struct list_head *)chnl_packet_obj); + list_add_tail(&chnl_packet_obj->link, &pchnl->pio_requests); pchnl->cio_reqs++; DBC_ASSERT(pchnl->cio_reqs <= pchnl->chnl_packets); /* @@ -254,7 +255,7 @@ int bridge_chnl_cancel_io(struct chnl_object *chnl_obj) struct chnl_object *pchnl = (struct chnl_object *)chnl_obj; u32 chnl_id = -1; s8 chnl_mode; - struct chnl_irp *chnl_packet_obj; + struct chnl_irp *chirp, *tmp; struct chnl_mgr *chnl_mgr_obj = NULL; /* Check args: */ @@ -272,7 +273,7 @@ int bridge_chnl_cancel_io(struct chnl_object *chnl_obj) * IORequests or dispatching. */ spin_lock_bh(&chnl_mgr_obj->chnl_mgr_lock); pchnl->dw_state |= CHNL_STATECANCEL; - if (LST_IS_EMPTY(pchnl->pio_requests)) + if (list_empty(&pchnl->pio_requests)) goto func_cont; if (pchnl->chnl_type == CHNL_PCPY) { @@ -286,18 +287,14 @@ int bridge_chnl_cancel_io(struct chnl_object *chnl_obj) } } /* Move all IOR's to IOC queue: */ - while (!LST_IS_EMPTY(pchnl->pio_requests)) { - chnl_packet_obj = - (struct chnl_irp *)lst_get_head(pchnl->pio_requests); - if (chnl_packet_obj) { - chnl_packet_obj->byte_size = 0; - chnl_packet_obj->status |= CHNL_IOCSTATCANCEL; - lst_put_tail(pchnl->pio_completions, - (struct list_head *)chnl_packet_obj); - pchnl->cio_cs++; - pchnl->cio_reqs--; - DBC_ASSERT(pchnl->cio_reqs >= 0); - } + list_for_each_entry_safe(chirp, tmp, &pchnl->pio_requests, link) { + list_del(&chirp->link); + chirp->byte_size = 0; + chirp->status |= CHNL_IOCSTATCANCEL; + list_add_tail(&chirp->link, &pchnl->pio_completions); + pchnl->cio_cs++; + pchnl->cio_reqs--; + DBC_ASSERT(pchnl->cio_reqs >= 0); } func_cont: spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock); @@ -353,20 +350,14 @@ func_cont: pchnl->sync_event = NULL; } /* Free I/O request and I/O completion queues: */ - if (pchnl->pio_completions) { - free_chirp_list(pchnl->pio_completions); - pchnl->pio_completions = NULL; - pchnl->cio_cs = 0; - } - if (pchnl->pio_requests) { - free_chirp_list(pchnl->pio_requests); - pchnl->pio_requests = NULL; - pchnl->cio_reqs = 0; - } - if (pchnl->free_packets_list) { - free_chirp_list(pchnl->free_packets_list); - pchnl->free_packets_list = NULL; - } + free_chirp_list(&pchnl->pio_completions); + pchnl->cio_cs = 0; + + free_chirp_list(&pchnl->pio_requests); + pchnl->cio_reqs = 0; + + free_chirp_list(&pchnl->free_packets_list); + /* Release channel object. */ kfree(pchnl); pchnl = NULL; @@ -505,7 +496,7 @@ int bridge_chnl_flush_io(struct chnl_object *chnl_obj, u32 timeout) && (pchnl->chnl_type == CHNL_PCPY)) { /* Wait for IO completions, up to the specified * timeout: */ - while (!LST_IS_EMPTY(pchnl->pio_requests) && !status) { + while (!list_empty(&pchnl->pio_requests) && !status) { status = bridge_chnl_get_ioc(chnl_obj, timeout, &chnl_ioc_obj); if (status) @@ -521,7 +512,7 @@ int bridge_chnl_flush_io(struct chnl_object *chnl_obj, u32 timeout) pchnl->dw_state &= ~CHNL_STATECANCEL; } } - DBC_ENSURE(status || LST_IS_EMPTY(pchnl->pio_requests)); + DBC_ENSURE(status || list_empty(&pchnl->pio_requests)); return status; } @@ -581,7 +572,7 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, if (!chan_ioc || !pchnl) { status = -EFAULT; } else if (timeout == CHNL_IOCNOWAIT) { - if (LST_IS_EMPTY(pchnl->pio_completions)) + if (list_empty(&pchnl->pio_completions)) status = -EREMOTEIO; } @@ -596,7 +587,7 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, ioc.status = CHNL_IOCSTATCOMPLETE; if (timeout != - CHNL_IOCNOWAIT && LST_IS_EMPTY(pchnl->pio_completions)) { + CHNL_IOCNOWAIT && list_empty(&pchnl->pio_completions)) { if (timeout == CHNL_IOCINFINITE) timeout = SYNC_INFINITE; @@ -611,7 +602,7 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, * fails due to unkown causes. */ /* Even though Wait failed, there may be something in * the Q: */ - if (LST_IS_EMPTY(pchnl->pio_completions)) { + if (list_empty(&pchnl->pio_completions)) { ioc.status |= CHNL_IOCSTATCANCEL; dequeue_ioc = false; } @@ -622,30 +613,26 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, omap_mbox_disable_irq(dev_ctxt->mbox, IRQ_RX); if (dequeue_ioc) { /* Dequeue IOC and set chan_ioc; */ - DBC_ASSERT(!LST_IS_EMPTY(pchnl->pio_completions)); - chnl_packet_obj = - (struct chnl_irp *)lst_get_head(pchnl->pio_completions); + DBC_ASSERT(!list_empty(&pchnl->pio_completions)); + chnl_packet_obj = list_first_entry(&pchnl->pio_completions, + struct chnl_irp, link); + list_del(&chnl_packet_obj->link); /* Update chan_ioc from channel state and chirp: */ - if (chnl_packet_obj) { - pchnl->cio_cs--; - /* If this is a zero-copy channel, then set IOC's pbuf - * to the DSP's address. This DSP address will get - * translated to user's virtual addr later. */ - { - host_sys_buf = chnl_packet_obj->host_sys_buf; - ioc.pbuf = chnl_packet_obj->host_user_buf; - } - ioc.byte_size = chnl_packet_obj->byte_size; - ioc.buf_size = chnl_packet_obj->buf_size; - ioc.dw_arg = chnl_packet_obj->dw_arg; - ioc.status |= chnl_packet_obj->status; - /* Place the used chirp on the free list: */ - lst_put_tail(pchnl->free_packets_list, - (struct list_head *)chnl_packet_obj); - } else { - ioc.pbuf = NULL; - ioc.byte_size = 0; - } + pchnl->cio_cs--; + /* + * If this is a zero-copy channel, then set IOC's pbuf + * to the DSP's address. This DSP address will get + * translated to user's virtual addr later. + */ + host_sys_buf = chnl_packet_obj->host_sys_buf; + ioc.pbuf = chnl_packet_obj->host_user_buf; + ioc.byte_size = chnl_packet_obj->byte_size; + ioc.buf_size = chnl_packet_obj->buf_size; + ioc.dw_arg = chnl_packet_obj->dw_arg; + ioc.status |= chnl_packet_obj->status; + /* Place the used chirp on the free list: */ + list_add_tail(&chnl_packet_obj->link, + &pchnl->free_packets_list); } else { ioc.pbuf = NULL; ioc.byte_size = 0; @@ -653,7 +640,7 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, ioc.buf_size = 0; } /* Ensure invariant: If any IOC's are queued for this channel... */ - if (!LST_IS_EMPTY(pchnl->pio_completions)) { + if (!list_empty(&pchnl->pio_completions)) { /* Since DSPStream_Reclaim() does not take a timeout * parameter, we pass the stream's timeout value to * bridge_chnl_get_ioc. We cannot determine whether or not @@ -818,9 +805,16 @@ int bridge_chnl_open(struct chnl_object **chnl, /* Protect queues from io_dpc: */ pchnl->dw_state = CHNL_STATECANCEL; /* Allocate initial IOR and IOC queues: */ - pchnl->free_packets_list = create_chirp_list(pattrs->uio_reqs); - pchnl->pio_requests = create_chirp_list(0); - pchnl->pio_completions = create_chirp_list(0); + status = create_chirp_list(&pchnl->free_packets_list, + pattrs->uio_reqs); + if (status) { + kfree(pchnl); + goto func_end; + } + + INIT_LIST_HEAD(&pchnl->pio_requests); + INIT_LIST_HEAD(&pchnl->pio_completions); + pchnl->chnl_packets = pattrs->uio_reqs; pchnl->cio_cs = 0; pchnl->cio_reqs = 0; @@ -840,40 +834,26 @@ int bridge_chnl_open(struct chnl_object **chnl, } if (!status) { - if (pchnl->pio_completions && pchnl->pio_requests && - pchnl->free_packets_list) { - /* Initialize CHNL object fields: */ - pchnl->chnl_mgr_obj = chnl_mgr_obj; - pchnl->chnl_id = ch_id; - pchnl->chnl_mode = chnl_mode; - pchnl->user_event = sync_event; - pchnl->sync_event = sync_event; - /* Get the process handle */ - pchnl->process = current->tgid; - pchnl->pcb_arg = 0; - pchnl->bytes_moved = 0; - /* Default to proc-copy */ - pchnl->chnl_type = CHNL_PCPY; - } else { - status = -ENOMEM; - } + /* Initialize CHNL object fields: */ + pchnl->chnl_mgr_obj = chnl_mgr_obj; + pchnl->chnl_id = ch_id; + pchnl->chnl_mode = chnl_mode; + pchnl->user_event = sync_event; + pchnl->sync_event = sync_event; + /* Get the process handle */ + pchnl->process = current->tgid; + pchnl->pcb_arg = 0; + pchnl->bytes_moved = 0; + /* Default to proc-copy */ + pchnl->chnl_type = CHNL_PCPY; } if (status) { /* Free memory */ - if (pchnl->pio_completions) { - free_chirp_list(pchnl->pio_completions); - pchnl->pio_completions = NULL; - pchnl->cio_cs = 0; - } - if (pchnl->pio_requests) { - free_chirp_list(pchnl->pio_requests); - pchnl->pio_requests = NULL; - } - if (pchnl->free_packets_list) { - free_chirp_list(pchnl->free_packets_list); - pchnl->free_packets_list = NULL; - } + free_chirp_list(&pchnl->pio_completions); + pchnl->cio_cs = 0; + free_chirp_list(&pchnl->pio_requests); + free_chirp_list(&pchnl->free_packets_list); kfree(sync_event); sync_event = NULL; @@ -924,37 +904,35 @@ int bridge_chnl_register_notify(struct chnl_object *chnl_obj, * Purpose: * Initialize a queue of channel I/O Request/Completion packets. * Parameters: + * list: Pointer to a list_head * chirps: Number of Chirps to allocate. * Returns: - * Pointer to queue of IRPs, or NULL. + * 0 if successful, error code otherwise. * Requires: * Ensures: */ -static struct lst_list *create_chirp_list(u32 chirps) +static int create_chirp_list(struct list_head *list, u32 chirps) { - struct lst_list *chirp_list; - struct chnl_irp *chnl_packet_obj; + struct chnl_irp *chirp; u32 i; - chirp_list = kzalloc(sizeof(struct lst_list), GFP_KERNEL); + INIT_LIST_HEAD(list); - if (chirp_list) { - INIT_LIST_HEAD(&chirp_list->head); - /* Make N chirps and place on queue. */ - for (i = 0; (i < chirps) - && ((chnl_packet_obj = make_new_chirp()) != NULL); i++) { - lst_put_tail(chirp_list, - (struct list_head *)chnl_packet_obj); - } + /* Make N chirps and place on queue. */ + for (i = 0; i < chirps; i++) { + chirp = kzalloc(sizeof(struct chnl_irp), GFP_KERNEL); + if (!chirp) + break; + list_add_tail(&chirp->link, list); + } - /* If we couldn't allocate all chirps, free those allocated: */ - if (i != chirps) { - free_chirp_list(chirp_list); - chirp_list = NULL; - } + /* If we couldn't allocate all chirps, free those allocated: */ + if (i != chirps) { + free_chirp_list(list); + return -ENOMEM; } - return chirp_list; + return 0; } /* @@ -962,31 +940,16 @@ static struct lst_list *create_chirp_list(u32 chirps) * Purpose: * Free the queue of Chirps. */ -static void free_chirp_list(struct lst_list *chirp_list) +static void free_chirp_list(struct list_head *chirp_list) { - DBC_REQUIRE(chirp_list != NULL); - - while (!LST_IS_EMPTY(chirp_list)) - kfree(lst_get_head(chirp_list)); + struct chnl_irp *chirp, *tmp; - kfree(chirp_list); -} - -/* - * ======== make_new_chirp ======== - * Allocate the memory for a new channel IRP. - */ -static struct chnl_irp *make_new_chirp(void) -{ - struct chnl_irp *chnl_packet_obj; + DBC_REQUIRE(chirp_list != NULL); - chnl_packet_obj = kzalloc(sizeof(struct chnl_irp), GFP_KERNEL); - if (chnl_packet_obj != NULL) { - /* lst_init_elem only resets the list's member values. */ - lst_init_elem(&chnl_packet_obj->link); + list_for_each_entry_safe(chirp, tmp, chirp_list, link) { + list_del(&chirp->link); + kfree(chirp); } - - return chnl_packet_obj; } /* diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 9cea3eacf1a8..2a48f3db0e2d 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -24,6 +24,7 @@ * function. */ #include +#include /* Host OS */ #include @@ -1092,15 +1093,17 @@ static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, pchnl = chnl_mgr_obj->ap_channel[chnl_id]; if ((pchnl != NULL) && CHNL_IS_INPUT(pchnl->chnl_mode)) { if ((pchnl->dw_state & ~CHNL_STATEEOS) == CHNL_STATEREADY) { - if (!pchnl->pio_requests) - goto func_end; /* Get the I/O request, and attempt a transfer */ - chnl_packet_obj = (struct chnl_irp *) - lst_get_head(pchnl->pio_requests); - if (chnl_packet_obj) { - pchnl->cio_reqs--; - if (pchnl->cio_reqs < 0) + if (!list_empty(&pchnl->pio_requests)) { + if (!pchnl->cio_reqs) goto func_end; + + chnl_packet_obj = list_first_entry( + &pchnl->pio_requests, + struct chnl_irp, link); + list_del(&chnl_packet_obj->link); + pchnl->cio_reqs--; + /* * Ensure we don't overflow the client's * buffer. @@ -1127,21 +1130,18 @@ static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, * the channel state. */ chnl_packet_obj->status |= - CHNL_IOCSTATEOS; + CHNL_IOCSTATEOS; pchnl->dw_state |= CHNL_STATEEOS; /* * Notify that end of stream has * occurred. */ ntfy_notify(pchnl->ntfy_obj, - DSP_STREAMDONE); + DSP_STREAMDONE); } /* Tell DSP if no more I/O buffers available */ - if (!pchnl->pio_requests) - goto func_end; - if (LST_IS_EMPTY(pchnl->pio_requests)) { + if (list_empty(&pchnl->pio_requests)) set_chnl_free(sm, pchnl->chnl_id); - } clear_chnl = true; notify_client = true; } else { @@ -1213,21 +1213,18 @@ static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr) msg.msgq_id = read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr); msg_input += sizeof(struct msg_dspmsg); - if (!hmsg_mgr->queue_list) - goto func_end; /* Determine which queue to put the message in */ - msg_queue_obj = - (struct msg_queue *)lst_first(hmsg_mgr->queue_list); dev_dbg(bridge, "input msg: dw_cmd=0x%x dw_arg1=0x%x " - "dw_arg2=0x%x msgq_id=0x%x \n", msg.msg.dw_cmd, + "dw_arg2=0x%x msgq_id=0x%x\n", msg.msg.dw_cmd, msg.msg.dw_arg1, msg.msg.dw_arg2, msg.msgq_id); /* * Interrupt may occur before shared memory and message * input locations have been set up. If all nodes were * cleaned up, hmsg_mgr->max_msgs should be 0. */ - while (msg_queue_obj != NULL) { + list_for_each_entry(msg_queue_obj, &hmsg_mgr->queue_list, + list_elem) { if (msg.msgq_id == msg_queue_obj->msgq_id) { /* Found it */ if (msg.msg.dw_cmd == RMS_EXITACK) { @@ -1237,47 +1234,39 @@ static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr) * queued. */ (*hmsg_mgr->on_exit) ((void *) - msg_queue_obj->arg, - msg.msg.dw_arg1); + msg_queue_obj->arg, + msg.msg.dw_arg1); + break; + } + /* + * Not an exit acknowledgement, queue + * the message. + */ + if (!list_empty(&msg_queue_obj-> + msg_free_list)) { + pmsg = list_first_entry( + &msg_queue_obj->msg_free_list, + struct msg_frame, list_elem); + list_del(&pmsg->list_elem); + pmsg->msg_data = msg; + list_add_tail(&pmsg->list_elem, + &msg_queue_obj->msg_used_list); + ntfy_notify + (msg_queue_obj->ntfy_obj, + DSP_NODEMESSAGEREADY); + sync_set_event + (msg_queue_obj->sync_event); } else { /* - * Not an exit acknowledgement, queue - * the message. + * No free frame to copy the + * message into. */ - if (!msg_queue_obj->msg_free_list) - goto func_end; - pmsg = (struct msg_frame *)lst_get_head - (msg_queue_obj->msg_free_list); - if (msg_queue_obj->msg_used_list - && pmsg) { - pmsg->msg_data = msg; - lst_put_tail - (msg_queue_obj->msg_used_list, - (struct list_head *)pmsg); - ntfy_notify - (msg_queue_obj->ntfy_obj, - DSP_NODEMESSAGEREADY); - sync_set_event - (msg_queue_obj->sync_event); - } else { - /* - * No free frame to copy the - * message into. - */ - pr_err("%s: no free msg frames," - " discarding msg\n", - __func__); - } + pr_err("%s: no free msg frames," + " discarding msg\n", + __func__); } break; } - - if (!hmsg_mgr->queue_list || !msg_queue_obj) - goto func_end; - msg_queue_obj = - (struct msg_queue *)lst_next(hmsg_mgr->queue_list, - (struct list_head *) - msg_queue_obj); } } /* Set the post SWI flag */ @@ -1301,8 +1290,7 @@ static void notify_chnl_complete(struct chnl_object *pchnl, { bool signal_event; - if (!pchnl || !pchnl->sync_event || - !pchnl->pio_completions || !chnl_packet_obj) + if (!pchnl || !pchnl->sync_event || !chnl_packet_obj) goto func_end; /* @@ -1311,10 +1299,9 @@ static void notify_chnl_complete(struct chnl_object *pchnl, * signalled by the only IO completion list consumer: * bridge_chnl_get_ioc(). */ - signal_event = LST_IS_EMPTY(pchnl->pio_completions); + signal_event = list_empty(&pchnl->pio_completions); /* Enqueue the IO completion info for the client */ - lst_put_tail(pchnl->pio_completions, - (struct list_head *)chnl_packet_obj); + list_add_tail(&chnl_packet_obj->link, &pchnl->pio_completions); pchnl->cio_cs++; if (pchnl->cio_cs > pchnl->chnl_packets) @@ -1361,21 +1348,23 @@ static void output_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, goto func_end; pchnl = chnl_mgr_obj->ap_channel[chnl_id]; - if (!pchnl || !pchnl->pio_requests) { + if (!pchnl || list_empty(&pchnl->pio_requests)) { /* Shouldn't get here */ goto func_end; } - /* Get the I/O request, and attempt a transfer */ - chnl_packet_obj = (struct chnl_irp *)lst_get_head(pchnl->pio_requests); - if (!chnl_packet_obj) + + if (!pchnl->cio_reqs) goto func_end; + /* Get the I/O request, and attempt a transfer */ + chnl_packet_obj = list_first_entry(&pchnl->pio_requests, + struct chnl_irp, link); + list_del(&chnl_packet_obj->link); + pchnl->cio_reqs--; - if (pchnl->cio_reqs < 0 || !pchnl->pio_requests) - goto func_end; /* Record fact that no more I/O buffers available */ - if (LST_IS_EMPTY(pchnl->pio_requests)) + if (list_empty(&pchnl->pio_requests)) chnl_mgr_obj->dw_output_mask &= ~(1 << chnl_id); /* Transfer buffer to DSP side */ @@ -1436,14 +1425,11 @@ static void output_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr) msg_output = pio_mgr->msg_output; /* Copy num_msgs messages into shared memory */ for (i = 0; i < num_msgs; i++) { - if (!hmsg_mgr->msg_used_list) { - pmsg = NULL; - goto func_end; - } else { - pmsg = (struct msg_frame *) - lst_get_head(hmsg_mgr->msg_used_list); - } - if (pmsg != NULL) { + if (!list_empty(&hmsg_mgr->msg_used_list)) { + pmsg = list_first_entry( + &hmsg_mgr->msg_used_list, + struct msg_frame, list_elem); + list_del(&pmsg->list_elem); val = (pmsg->msg_data).msgq_id; addr = (u32) &(((struct msg_dspmsg *) msg_output)->msgq_id); @@ -1465,10 +1451,8 @@ static void output_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr) write_ext32_bit_dsp_data( pio_mgr->hbridge_context, addr, val); msg_output += sizeof(struct msg_dspmsg); - if (!hmsg_mgr->msg_free_list) - goto func_end; - lst_put_tail(hmsg_mgr->msg_free_list, - (struct list_head *)pmsg); + list_add_tail(&pmsg->list_elem, + &hmsg_mgr->msg_free_list); sync_set_event(hmsg_mgr->sync_event); } } @@ -1492,8 +1476,6 @@ static void output_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr) MBX_PCPY_CLASS); } } -func_end: - return; } /* diff --git a/drivers/staging/tidspbridge/core/msg_sm.c b/drivers/staging/tidspbridge/core/msg_sm.c index 87712e24dfb1..de2cb835fbb9 100644 --- a/drivers/staging/tidspbridge/core/msg_sm.c +++ b/drivers/staging/tidspbridge/core/msg_sm.c @@ -24,7 +24,6 @@ #include /* ----------------------------------- OS Adaptation Layer */ -#include #include /* ----------------------------------- Platform Manager */ @@ -38,10 +37,10 @@ #include /* ----------------------------------- Function Prototypes */ -static int add_new_msg(struct lst_list *msg_list); +static int add_new_msg(struct list_head *msg_list); static void delete_msg_mgr(struct msg_mgr *hmsg_mgr); static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp); -static void free_msg_list(struct lst_list *msg_list); +static void free_msg_list(struct list_head *msg_list); /* * ======== bridge_msg_create ======== @@ -73,25 +72,13 @@ int bridge_msg_create(struct msg_mgr **msg_man, msg_mgr_obj->on_exit = msg_callback; msg_mgr_obj->hio_mgr = hio_mgr; /* List of MSG_QUEUEs */ - msg_mgr_obj->queue_list = kzalloc(sizeof(struct lst_list), - GFP_KERNEL); + INIT_LIST_HEAD(&msg_mgr_obj->queue_list); /* Queues of message frames for messages to the DSP. Message * frames will only be added to the free queue when a * msg_queue object is created. */ - msg_mgr_obj->msg_free_list = kzalloc(sizeof(struct lst_list), - GFP_KERNEL); - msg_mgr_obj->msg_used_list = kzalloc(sizeof(struct lst_list), - GFP_KERNEL); - if (msg_mgr_obj->queue_list == NULL || - msg_mgr_obj->msg_free_list == NULL || - msg_mgr_obj->msg_used_list == NULL) { - status = -ENOMEM; - } else { - INIT_LIST_HEAD(&msg_mgr_obj->queue_list->head); - INIT_LIST_HEAD(&msg_mgr_obj->msg_free_list->head); - INIT_LIST_HEAD(&msg_mgr_obj->msg_used_list->head); - spin_lock_init(&msg_mgr_obj->msg_mgr_lock); - } + INIT_LIST_HEAD(&msg_mgr_obj->msg_free_list); + INIT_LIST_HEAD(&msg_mgr_obj->msg_used_list); + spin_lock_init(&msg_mgr_obj->msg_mgr_lock); /* Create an event to be used by bridge_msg_put() in waiting * for an available free frame from the message manager. */ @@ -128,7 +115,7 @@ int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr, struct msg_queue *msg_q; int status = 0; - if (!hmsg_mgr || msgq == NULL || !hmsg_mgr->msg_free_list) { + if (!hmsg_mgr || msgq == NULL) { status = -EFAULT; goto func_end; } @@ -140,20 +127,13 @@ int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr, status = -ENOMEM; goto func_end; } - lst_init_elem((struct list_head *)msg_q); msg_q->max_msgs = max_msgs; msg_q->hmsg_mgr = hmsg_mgr; msg_q->arg = arg; /* Node handle */ msg_q->msgq_id = msgq_id; /* Node env (not valid yet) */ /* Queues of Message frames for messages from the DSP */ - msg_q->msg_free_list = kzalloc(sizeof(struct lst_list), GFP_KERNEL); - msg_q->msg_used_list = kzalloc(sizeof(struct lst_list), GFP_KERNEL); - if (msg_q->msg_free_list == NULL || msg_q->msg_used_list == NULL) - status = -ENOMEM; - else { - INIT_LIST_HEAD(&msg_q->msg_free_list->head); - INIT_LIST_HEAD(&msg_q->msg_used_list->head); - } + INIT_LIST_HEAD(&msg_q->msg_free_list); + INIT_LIST_HEAD(&msg_q->msg_used_list); /* Create event that will be signalled when a message from * the DSP is available. */ @@ -204,10 +184,10 @@ int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr, spin_lock_bh(&hmsg_mgr->msg_mgr_lock); /* Initialize message frames and put in appropriate queues */ for (i = 0; i < max_msgs && !status; i++) { - status = add_new_msg(hmsg_mgr->msg_free_list); + status = add_new_msg(&hmsg_mgr->msg_free_list); if (!status) { num_allocated++; - status = add_new_msg(msg_q->msg_free_list); + status = add_new_msg(&msg_q->msg_free_list); } } if (status) { @@ -215,11 +195,11 @@ int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr, * of the newly allocated message frames. */ delete_msg_queue(msg_q, num_allocated); } else { - lst_put_tail(hmsg_mgr->queue_list, - (struct list_head *)msg_q); + list_add_tail(&msg_q->list_elem, + &hmsg_mgr->queue_list); *msgq = msg_q; /* Signal that free frames are now available */ - if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list)) + if (!list_empty(&hmsg_mgr->msg_free_list)) sync_set_event(hmsg_mgr->sync_event); } @@ -267,15 +247,12 @@ void bridge_msg_delete_queue(struct msg_queue *msg_queue_obj) } /* Remove message queue from hmsg_mgr->queue_list */ spin_lock_bh(&hmsg_mgr->msg_mgr_lock); - lst_remove_elem(hmsg_mgr->queue_list, - (struct list_head *)msg_queue_obj); + list_del(&msg_queue_obj->list_elem); /* Free the message queue object */ delete_msg_queue(msg_queue_obj, msg_queue_obj->max_msgs); - if (!hmsg_mgr->msg_free_list) - goto func_cont; - if (LST_IS_EMPTY(hmsg_mgr->msg_free_list)) + if (list_empty(&hmsg_mgr->msg_free_list)) sync_reset_event(hmsg_mgr->sync_event); -func_cont: + spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); func_end: return; @@ -301,26 +278,21 @@ int bridge_msg_get(struct msg_queue *msg_queue_obj, } hmsg_mgr = msg_queue_obj->hmsg_mgr; - if (!msg_queue_obj->msg_used_list) { - status = -EFAULT; - goto func_end; - } /* Enter critical section */ spin_lock_bh(&hmsg_mgr->msg_mgr_lock); /* If a message is already there, get it */ - if (!LST_IS_EMPTY(msg_queue_obj->msg_used_list)) { - msg_frame_obj = (struct msg_frame *) - lst_get_head(msg_queue_obj->msg_used_list); - if (msg_frame_obj != NULL) { - *pmsg = msg_frame_obj->msg_data.msg; - lst_put_tail(msg_queue_obj->msg_free_list, - (struct list_head *)msg_frame_obj); - if (LST_IS_EMPTY(msg_queue_obj->msg_used_list)) - sync_reset_event(msg_queue_obj->sync_event); - - got_msg = true; - } + if (!list_empty(&msg_queue_obj->msg_used_list)) { + msg_frame_obj = list_first_entry(&msg_queue_obj->msg_used_list, + struct msg_frame, list_elem); + list_del(&msg_frame_obj->list_elem); + *pmsg = msg_frame_obj->msg_data.msg; + list_add_tail(&msg_frame_obj->list_elem, + &msg_queue_obj->msg_free_list); + if (list_empty(&msg_queue_obj->msg_used_list)) + sync_reset_event(msg_queue_obj->sync_event); + + got_msg = true; } else { if (msg_queue_obj->done) status = -EPERM; @@ -349,25 +321,22 @@ int bridge_msg_get(struct msg_queue *msg_queue_obj, (void)sync_set_event(msg_queue_obj->sync_done_ack); status = -EPERM; } else { - if (!status) { - DBC_ASSERT(!LST_IS_EMPTY - (msg_queue_obj->msg_used_list)); + if (!status && !list_empty(&msg_queue_obj-> + msg_used_list)) { /* Get msg from used list */ - msg_frame_obj = (struct msg_frame *) - lst_get_head(msg_queue_obj->msg_used_list); + msg_frame_obj = list_first_entry( + &msg_queue_obj->msg_used_list, + struct msg_frame, list_elem); + list_del(&msg_frame_obj->list_elem); /* Copy message into pmsg and put frame on the * free list */ - if (msg_frame_obj != NULL) { - *pmsg = msg_frame_obj->msg_data.msg; - lst_put_tail - (msg_queue_obj->msg_free_list, - (struct list_head *) - msg_frame_obj); - } + *pmsg = msg_frame_obj->msg_data.msg; + list_add_tail(&msg_frame_obj->list_elem, + &msg_queue_obj->msg_free_list); } msg_queue_obj->io_msg_pend--; /* Reset the event if there are still queued messages */ - if (!LST_IS_EMPTY(msg_queue_obj->msg_used_list)) + if (!list_empty(&msg_queue_obj->msg_used_list)) sync_set_event(msg_queue_obj->sync_event); /* Exit critical section */ @@ -397,27 +366,22 @@ int bridge_msg_put(struct msg_queue *msg_queue_obj, goto func_end; } hmsg_mgr = msg_queue_obj->hmsg_mgr; - if (!hmsg_mgr->msg_free_list) { - status = -EFAULT; - goto func_end; - } spin_lock_bh(&hmsg_mgr->msg_mgr_lock); /* If a message frame is available, use it */ - if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list)) { - msg_frame_obj = - (struct msg_frame *)lst_get_head(hmsg_mgr->msg_free_list); - if (msg_frame_obj != NULL) { - msg_frame_obj->msg_data.msg = *pmsg; - msg_frame_obj->msg_data.msgq_id = - msg_queue_obj->msgq_id; - lst_put_tail(hmsg_mgr->msg_used_list, - (struct list_head *)msg_frame_obj); - hmsg_mgr->msgs_pending++; - put_msg = true; - } - if (LST_IS_EMPTY(hmsg_mgr->msg_free_list)) + if (!list_empty(&hmsg_mgr->msg_free_list)) { + msg_frame_obj = list_first_entry(&hmsg_mgr->msg_free_list, + struct msg_frame, list_elem); + list_del(&msg_frame_obj->list_elem); + msg_frame_obj->msg_data.msg = *pmsg; + msg_frame_obj->msg_data.msgq_id = + msg_queue_obj->msgq_id; + list_add_tail(&msg_frame_obj->list_elem, + &hmsg_mgr->msg_used_list); + hmsg_mgr->msgs_pending++; + put_msg = true; + if (list_empty(&hmsg_mgr->msg_free_list)) sync_reset_event(hmsg_mgr->sync_event); /* Release critical section before scheduling DPC */ @@ -452,34 +416,34 @@ int bridge_msg_put(struct msg_queue *msg_queue_obj, (void)sync_set_event(msg_queue_obj->sync_done_ack); status = -EPERM; } else { - if (LST_IS_EMPTY(hmsg_mgr->msg_free_list)) { + if (list_empty(&hmsg_mgr->msg_free_list)) { status = -EFAULT; goto func_cont; } /* Get msg from free list */ - msg_frame_obj = (struct msg_frame *) - lst_get_head(hmsg_mgr->msg_free_list); + msg_frame_obj = list_first_entry( + &hmsg_mgr->msg_free_list, + struct msg_frame, list_elem); + list_del(&msg_frame_obj->list_elem); /* * Copy message into pmsg and put frame on the * used list. */ - if (msg_frame_obj) { - msg_frame_obj->msg_data.msg = *pmsg; - msg_frame_obj->msg_data.msgq_id = - msg_queue_obj->msgq_id; - lst_put_tail(hmsg_mgr->msg_used_list, - (struct list_head *)msg_frame_obj); - hmsg_mgr->msgs_pending++; - /* - * Schedule a DPC, to do the actual - * data transfer. - */ - iosm_schedule(hmsg_mgr->hio_mgr); - } + msg_frame_obj->msg_data.msg = *pmsg; + msg_frame_obj->msg_data.msgq_id = + msg_queue_obj->msgq_id; + list_add_tail(&msg_frame_obj->list_elem, + &hmsg_mgr->msg_used_list); + hmsg_mgr->msgs_pending++; + /* + * Schedule a DPC, to do the actual + * data transfer. + */ + iosm_schedule(hmsg_mgr->hio_mgr); msg_queue_obj->io_msg_pend--; /* Reset event if there are still frames available */ - if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list)) + if (!list_empty(&hmsg_mgr->msg_free_list)) sync_set_event(hmsg_mgr->sync_event); func_cont: /* Exit critical section */ @@ -551,15 +515,14 @@ void bridge_msg_set_queue_id(struct msg_queue *msg_queue_obj, u32 msgq_id) * ======== add_new_msg ======== * Must be called in message manager critical section. */ -static int add_new_msg(struct lst_list *msg_list) +static int add_new_msg(struct list_head *msg_list) { struct msg_frame *pmsg; int status = 0; pmsg = kzalloc(sizeof(struct msg_frame), GFP_ATOMIC); if (pmsg != NULL) { - lst_init_elem((struct list_head *)pmsg); - lst_put_tail(msg_list, (struct list_head *)pmsg); + list_add_tail(&pmsg->list_elem, msg_list); } else { status = -ENOMEM; } @@ -575,22 +538,9 @@ static void delete_msg_mgr(struct msg_mgr *hmsg_mgr) if (!hmsg_mgr) goto func_end; - if (hmsg_mgr->queue_list) { - if (LST_IS_EMPTY(hmsg_mgr->queue_list)) { - kfree(hmsg_mgr->queue_list); - hmsg_mgr->queue_list = NULL; - } - } - - if (hmsg_mgr->msg_free_list) { - free_msg_list(hmsg_mgr->msg_free_list); - hmsg_mgr->msg_free_list = NULL; - } - - if (hmsg_mgr->msg_used_list) { - free_msg_list(hmsg_mgr->msg_used_list); - hmsg_mgr->msg_used_list = NULL; - } + /* FIXME: free elements from queue_list? */ + free_msg_list(&hmsg_mgr->msg_free_list); + free_msg_list(&hmsg_mgr->msg_used_list); kfree(hmsg_mgr->sync_event); @@ -605,37 +555,26 @@ func_end: static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp) { struct msg_mgr *hmsg_mgr; - struct msg_frame *pmsg; + struct msg_frame *pmsg, *tmp; u32 i; - if (!msg_queue_obj || - !msg_queue_obj->hmsg_mgr || !msg_queue_obj->hmsg_mgr->msg_free_list) + if (!msg_queue_obj || !msg_queue_obj->hmsg_mgr) goto func_end; hmsg_mgr = msg_queue_obj->hmsg_mgr; /* Pull off num_to_dsp message frames from Msg manager and free */ - for (i = 0; i < num_to_dsp; i++) { - - if (!LST_IS_EMPTY(hmsg_mgr->msg_free_list)) { - pmsg = (struct msg_frame *) - lst_get_head(hmsg_mgr->msg_free_list); - kfree(pmsg); - } else { - /* Cannot free all of the message frames */ + i = 0; + list_for_each_entry_safe(pmsg, tmp, &hmsg_mgr->msg_free_list, + list_elem) { + list_del(&pmsg->list_elem); + kfree(pmsg); + if (i++ >= num_to_dsp) break; - } } - if (msg_queue_obj->msg_free_list) { - free_msg_list(msg_queue_obj->msg_free_list); - msg_queue_obj->msg_free_list = NULL; - } - - if (msg_queue_obj->msg_used_list) { - free_msg_list(msg_queue_obj->msg_used_list); - msg_queue_obj->msg_used_list = NULL; - } + free_msg_list(&msg_queue_obj->msg_free_list); + free_msg_list(&msg_queue_obj->msg_used_list); if (msg_queue_obj->ntfy_obj) { ntfy_delete(msg_queue_obj->ntfy_obj); @@ -655,19 +594,18 @@ func_end: /* * ======== free_msg_list ======== */ -static void free_msg_list(struct lst_list *msg_list) +static void free_msg_list(struct list_head *msg_list) { - struct msg_frame *pmsg; + struct msg_frame *pmsg, *tmp; if (!msg_list) goto func_end; - while ((pmsg = (struct msg_frame *)lst_get_head(msg_list)) != NULL) + list_for_each_entry_safe(pmsg, tmp, msg_list, list_elem) { + list_del(&pmsg->list_elem); kfree(pmsg); + } - DBC_ASSERT(LST_IS_EMPTY(msg_list)); - - kfree(msg_list); func_end: return; } diff --git a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h b/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h index 8efd1fba2f6d..8a22317e5b5c 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h +++ b/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h @@ -26,7 +26,7 @@ #include #include -#include +#include #include /* @@ -148,13 +148,13 @@ struct chnl_object { struct sync_object *sync_event; u32 process; /* Process which created this channel */ u32 pcb_arg; /* Argument to use with callback */ - struct lst_list *pio_requests; /* List of IOR's to driver */ + struct list_head pio_requests; /* List of IOR's to driver */ s32 cio_cs; /* Number of IOC's in queue */ s32 cio_reqs; /* Number of IORequests in queue */ s32 chnl_packets; /* Initial number of free Irps */ /* List of IOC's from driver */ - struct lst_list *pio_completions; - struct lst_list *free_packets_list; /* List of free Irps */ + struct list_head pio_completions; + struct list_head free_packets_list; /* List of free Irps */ struct ntfy_object *ntfy_obj; u32 bytes_moved; /* Total number of bytes transfered */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h index fbff372d2f51..e748ba8d6cab 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h @@ -19,7 +19,6 @@ #ifndef CMMDEFS_ #define CMMDEFS_ -#include /* Cmm attributes used in cmm_create() */ struct cmm_mgrattrs { diff --git a/drivers/staging/tidspbridge/include/dspbridge/sync.h b/drivers/staging/tidspbridge/include/dspbridge/sync.h index df05b8f8e230..b1e75eb8847c 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/sync.h +++ b/drivers/staging/tidspbridge/include/dspbridge/sync.h @@ -20,6 +20,7 @@ #define _SYNC_H #include +#include /* Special timeout value indicating an infinite wait: */ -- cgit v1.2.3 From 5fb45dac37615f0c33b59741d42b0853125c6f7d Mon Sep 17 00:00:00 2001 From: Ionut Nicu Date: Sun, 21 Nov 2010 10:46:25 +0000 Subject: staging: tidspbridge: convert pmgr to list_head Convert the pmgr module of the tidspbridge driver to use struct list_head instead of struct lst_list. Signed-off-by: Ionut Nicu Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/pmgr/cmm.c | 237 +++++++++++---------------------- drivers/staging/tidspbridge/pmgr/dev.c | 61 ++++----- 2 files changed, 100 insertions(+), 198 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/pmgr/cmm.c b/drivers/staging/tidspbridge/pmgr/cmm.c index 8dbdd20c4e9e..d7ca2a44250b 100644 --- a/drivers/staging/tidspbridge/pmgr/cmm.c +++ b/drivers/staging/tidspbridge/pmgr/cmm.c @@ -12,7 +12,7 @@ * describes a block of physically contiguous shared memory used for * future allocations by CMM. * - * Memory is coelesced back to the appropriate heap when a buffer is + * Memory is coalesced back to the appropriate heap when a buffer is * freed. * * Notes: @@ -30,6 +30,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include +#include /* ----------------------------------- DSP/BIOS Bridge */ #include @@ -38,7 +39,6 @@ #include /* ----------------------------------- OS Adaptation Layer */ -#include #include /* ----------------------------------- Platform Manager */ @@ -73,9 +73,9 @@ struct cmm_allocator { /* sma */ u32 ul_dsp_size; /* DSP seg size in bytes */ struct cmm_object *hcmm_mgr; /* back ref to parent mgr */ /* node list of available memory */ - struct lst_list *free_list_head; + struct list_head free_list; /* node list of memory in use */ - struct lst_list *in_use_list_head; + struct list_head in_use_list; }; struct cmm_xlator { /* Pa<->Va translator object */ @@ -97,7 +97,7 @@ struct cmm_object { * Cmm Lock is used to serialize access mem manager for multi-threads. */ struct mutex cmm_lock; /* Lock to access cmm mgr */ - struct lst_list *node_free_list_head; /* Free list of memory nodes */ + struct list_head node_free_list; /* Free list of memory nodes */ u32 ul_min_block_size; /* Min SM block; default 16 bytes */ u32 dw_page_size; /* Memory Page size (1k/4k) */ /* GPP SM segment ptrs */ @@ -215,8 +215,7 @@ void *cmm_calloc_buf(struct cmm_object *hcmm_mgr, u32 usize, pnode->client_proc = current->tgid; /* put our node on InUse list */ - lst_put_tail(allocator->in_use_list_head, - (struct list_head *)pnode); + list_add_tail(&pnode->link, &allocator->in_use_list); buf_pa = (void *)pnode->dw_pa; /* physical address */ /* clear mem */ pbyte = (u8 *) pnode->dw_va; @@ -265,18 +264,9 @@ int cmm_create(struct cmm_object **ph_cmm_mgr, * MEM_ALLOC_OBJECT */ /* create node free list */ - cmm_obj->node_free_list_head = - kzalloc(sizeof(struct lst_list), - GFP_KERNEL); - if (cmm_obj->node_free_list_head == NULL) { - status = -ENOMEM; - cmm_destroy(cmm_obj, true); - } else { - INIT_LIST_HEAD(&cmm_obj-> - node_free_list_head->head); - mutex_init(&cmm_obj->cmm_lock); - *ph_cmm_mgr = cmm_obj; - } + INIT_LIST_HEAD(&cmm_obj->node_free_list); + mutex_init(&cmm_obj->cmm_lock); + *ph_cmm_mgr = cmm_obj; } else { status = -ENOMEM; } @@ -294,7 +284,7 @@ int cmm_destroy(struct cmm_object *hcmm_mgr, bool force) struct cmm_info temp_info; int status = 0; s32 slot_seg; - struct cmm_mnode *pnode; + struct cmm_mnode *node, *tmp; DBC_REQUIRE(refs > 0); if (!hcmm_mgr) { @@ -324,15 +314,10 @@ int cmm_destroy(struct cmm_object *hcmm_mgr, bool force) } } } - if (cmm_mgr_obj->node_free_list_head != NULL) { - /* Free the free nodes */ - while (!LST_IS_EMPTY(cmm_mgr_obj->node_free_list_head)) { - pnode = (struct cmm_mnode *) - lst_get_head(cmm_mgr_obj->node_free_list_head); - kfree(pnode); - } - /* delete NodeFreeList list */ - kfree(cmm_mgr_obj->node_free_list_head); + list_for_each_entry_safe(node, tmp, &cmm_mgr_obj->node_free_list, + link) { + list_del(&node->link); + kfree(node); } mutex_unlock(&cmm_mgr_obj->cmm_lock); if (!status) { @@ -366,7 +351,7 @@ int cmm_free_buf(struct cmm_object *hcmm_mgr, void *buf_pa, { struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr; int status = -EFAULT; - struct cmm_mnode *mnode_obj = NULL; + struct cmm_mnode *curr, *tmp; struct cmm_allocator *allocator = NULL; struct cmm_attrs *pattrs; @@ -385,22 +370,14 @@ int cmm_free_buf(struct cmm_object *hcmm_mgr, void *buf_pa, allocator = get_allocator(cmm_mgr_obj, ul_seg_id); if (allocator != NULL) { mutex_lock(&cmm_mgr_obj->cmm_lock); - mnode_obj = - (struct cmm_mnode *)lst_first(allocator->in_use_list_head); - while (mnode_obj) { - if ((u32) buf_pa == mnode_obj->dw_pa) { - /* Found it */ - lst_remove_elem(allocator->in_use_list_head, - (struct list_head *)mnode_obj); - /* back to freelist */ - add_to_free_list(allocator, mnode_obj); - status = 0; /* all right! */ + list_for_each_entry_safe(curr, tmp, &allocator->in_use_list, + link) { + if (curr->dw_pa == (u32) buf_pa) { + list_del(&curr->link); + add_to_free_list(allocator, curr); + status = 0; break; } - /* next node. */ - mnode_obj = (struct cmm_mnode *) - lst_next(allocator->in_use_list_head, - (struct list_head *)mnode_obj); } mutex_unlock(&cmm_mgr_obj->cmm_lock); } @@ -443,7 +420,7 @@ int cmm_get_info(struct cmm_object *hcmm_mgr, u32 ul_seg; int status = 0; struct cmm_allocator *altr; - struct cmm_mnode *mnode_obj = NULL; + struct cmm_mnode *curr; DBC_REQUIRE(cmm_info_obj != NULL); @@ -478,17 +455,11 @@ int cmm_get_info(struct cmm_object *hcmm_mgr, cmm_info_obj->seg_info[ul_seg - 1].dw_seg_base_va = altr->dw_vm_base - altr->ul_dsp_size; cmm_info_obj->seg_info[ul_seg - 1].ul_in_use_cnt = 0; - mnode_obj = (struct cmm_mnode *) - lst_first(altr->in_use_list_head); /* Count inUse blocks */ - while (mnode_obj) { + list_for_each_entry(curr, &altr->in_use_list, link) { cmm_info_obj->ul_total_in_use_cnt++; cmm_info_obj->seg_info[ul_seg - 1].ul_in_use_cnt++; - /* next node. */ - mnode_obj = (struct cmm_mnode *) - lst_next(altr->in_use_list_head, - (struct list_head *)mnode_obj); } } } /* end for */ @@ -578,30 +549,17 @@ int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr, /* return the actual segment identifier */ *sgmt_id = (u32) slot_seg + 1; /* create memory free list */ - psma->free_list_head = kzalloc(sizeof(struct lst_list), - GFP_KERNEL); - if (psma->free_list_head == NULL) { - status = -ENOMEM; - goto func_end; - } - INIT_LIST_HEAD(&psma->free_list_head->head); + INIT_LIST_HEAD(&psma->free_list); /* create memory in-use list */ - psma->in_use_list_head = kzalloc(sizeof(struct - lst_list), GFP_KERNEL); - if (psma->in_use_list_head == NULL) { - status = -ENOMEM; - goto func_end; - } - INIT_LIST_HEAD(&psma->in_use_list_head->head); + INIT_LIST_HEAD(&psma->in_use_list); /* Get a mem node for this hunk-o-memory */ new_node = get_node(cmm_mgr_obj, dw_gpp_base_pa, psma->dw_vm_base, ul_size); /* Place node on the SM allocator's free list */ if (new_node) { - lst_put_tail(psma->free_list_head, - (struct list_head *)new_node); + list_add_tail(&new_node->link, &psma->free_list); } else { status = -ENOMEM; goto func_end; @@ -680,41 +638,22 @@ int cmm_un_register_gppsm_seg(struct cmm_object *hcmm_mgr, */ static void un_register_gppsm_seg(struct cmm_allocator *psma) { - struct cmm_mnode *mnode_obj = NULL; - struct cmm_mnode *next_node = NULL; + struct cmm_mnode *curr, *tmp; DBC_REQUIRE(psma != NULL); - if (psma->free_list_head != NULL) { - /* free nodes on free list */ - mnode_obj = (struct cmm_mnode *)lst_first(psma->free_list_head); - while (mnode_obj) { - next_node = - (struct cmm_mnode *)lst_next(psma->free_list_head, - (struct list_head *) - mnode_obj); - lst_remove_elem(psma->free_list_head, - (struct list_head *)mnode_obj); - kfree((void *)mnode_obj); - /* next node. */ - mnode_obj = next_node; - } - kfree(psma->free_list_head); /* delete freelist */ - /* free nodes on InUse list */ - mnode_obj = - (struct cmm_mnode *)lst_first(psma->in_use_list_head); - while (mnode_obj) { - next_node = - (struct cmm_mnode *)lst_next(psma->in_use_list_head, - (struct list_head *) - mnode_obj); - lst_remove_elem(psma->in_use_list_head, - (struct list_head *)mnode_obj); - kfree((void *)mnode_obj); - /* next node. */ - mnode_obj = next_node; - } - kfree(psma->in_use_list_head); /* delete InUse list */ + + /* free nodes on free list */ + list_for_each_entry_safe(curr, tmp, &psma->free_list, link) { + list_del(&curr->link); + kfree(curr); } + + /* free nodes on InUse list */ + list_for_each_entry_safe(curr, tmp, &psma->in_use_list, link) { + list_del(&curr->link); + kfree(curr); + } + if ((void *)psma->dw_vm_base != NULL) MEM_UNMAP_LINEAR_ADDRESS((void *)psma->dw_vm_base); @@ -758,15 +697,15 @@ static struct cmm_mnode *get_node(struct cmm_object *cmm_mgr_obj, u32 dw_pa, DBC_REQUIRE(dw_va != 0); DBC_REQUIRE(ul_size != 0); /* Check cmm mgr's node freelist */ - if (LST_IS_EMPTY(cmm_mgr_obj->node_free_list_head)) { + if (list_empty(&cmm_mgr_obj->node_free_list)) { pnode = kzalloc(sizeof(struct cmm_mnode), GFP_KERNEL); } else { /* surely a valid element */ - pnode = (struct cmm_mnode *) - lst_get_head(cmm_mgr_obj->node_free_list_head); + pnode = list_first_entry(&cmm_mgr_obj->node_free_list, + struct cmm_mnode, link); + list_del(&pnode->link); } if (pnode) { - lst_init_elem((struct list_head *)pnode); /* set self */ pnode->dw_pa = dw_pa; /* Physical addr of start of block */ pnode->dw_va = dw_va; /* Virtual " " */ pnode->ul_size = ul_size; /* Size of block */ @@ -783,9 +722,7 @@ static struct cmm_mnode *get_node(struct cmm_object *cmm_mgr_obj, u32 dw_pa, static void delete_node(struct cmm_object *cmm_mgr_obj, struct cmm_mnode *pnode) { DBC_REQUIRE(pnode != NULL); - lst_init_elem((struct list_head *)pnode); /* init .self ptr */ - lst_put_tail(cmm_mgr_obj->node_free_list_head, - (struct list_head *)pnode); + list_add_tail(&pnode->link, &cmm_mgr_obj->node_free_list); } /* @@ -797,28 +734,26 @@ static void delete_node(struct cmm_object *cmm_mgr_obj, struct cmm_mnode *pnode) static struct cmm_mnode *get_free_block(struct cmm_allocator *allocator, u32 usize) { - if (allocator) { - struct cmm_mnode *mnode_obj = (struct cmm_mnode *) - lst_first(allocator->free_list_head); - while (mnode_obj) { - if (usize <= (u32) mnode_obj->ul_size) { - lst_remove_elem(allocator->free_list_head, - (struct list_head *)mnode_obj); - return mnode_obj; - } - /* next node. */ - mnode_obj = (struct cmm_mnode *) - lst_next(allocator->free_list_head, - (struct list_head *)mnode_obj); + struct cmm_mnode *node, *tmp; + + if (!allocator) + return NULL; + + list_for_each_entry_safe(node, tmp, &allocator->free_list, link) { + if (usize <= (u32) node->ul_size) { + list_del(&node->link); + return node; } + } + return NULL; } /* * ======== add_to_free_list ======== * Purpose: - * Coelesce node into the freelist in ascending size order. + * Coalesce node into the freelist in ascending size order. */ static void add_to_free_list(struct cmm_allocator *allocator, struct cmm_mnode *pnode) @@ -829,71 +764,51 @@ static void add_to_free_list(struct cmm_allocator *allocator, u32 dw_this_pa; u32 dw_next_pa; - DBC_REQUIRE(pnode != NULL); - DBC_REQUIRE(allocator != NULL); + if (!pnode) { + pr_err("%s: failed - pnode is NULL\n", __func__); + return; + } + dw_this_pa = pnode->dw_pa; dw_next_pa = NEXT_PA(pnode); - mnode_obj = (struct cmm_mnode *)lst_first(allocator->free_list_head); - while (mnode_obj) { + list_for_each_entry(mnode_obj, &allocator->free_list, link) { if (dw_this_pa == NEXT_PA(mnode_obj)) { /* found the block ahead of this one */ node_prev = mnode_obj; } else if (dw_next_pa == mnode_obj->dw_pa) { node_next = mnode_obj; } - if ((node_prev == NULL) || (node_next == NULL)) { - /* next node. */ - mnode_obj = (struct cmm_mnode *) - lst_next(allocator->free_list_head, - (struct list_head *)mnode_obj); - } else { - /* got 'em */ + if ((node_prev != NULL) && (node_next != NULL)) break; - } - } /* while */ + } if (node_prev != NULL) { /* combine with previous block */ - lst_remove_elem(allocator->free_list_head, - (struct list_head *)node_prev); + list_del(&node_prev->link); /* grow node to hold both */ pnode->ul_size += node_prev->ul_size; pnode->dw_pa = node_prev->dw_pa; pnode->dw_va = node_prev->dw_va; /* place node on mgr nodeFreeList */ - delete_node((struct cmm_object *)allocator->hcmm_mgr, - node_prev); + delete_node(allocator->hcmm_mgr, node_prev); } if (node_next != NULL) { /* combine with next block */ - lst_remove_elem(allocator->free_list_head, - (struct list_head *)node_next); + list_del(&node_next->link); /* grow da node */ pnode->ul_size += node_next->ul_size; /* place node on mgr nodeFreeList */ - delete_node((struct cmm_object *)allocator->hcmm_mgr, - node_next); + delete_node(allocator->hcmm_mgr, node_next); } /* Now, let's add to freelist in increasing size order */ - mnode_obj = (struct cmm_mnode *)lst_first(allocator->free_list_head); - while (mnode_obj) { - if (pnode->ul_size <= mnode_obj->ul_size) - break; - - /* next node. */ - mnode_obj = - (struct cmm_mnode *)lst_next(allocator->free_list_head, - (struct list_head *)mnode_obj); - } - /* if mnode_obj is NULL then add our pnode to the end of the freelist */ - if (mnode_obj == NULL) { - lst_put_tail(allocator->free_list_head, - (struct list_head *)pnode); - } else { - /* insert our node before the current traversed node */ - lst_insert_before(allocator->free_list_head, - (struct list_head *)pnode, - (struct list_head *)mnode_obj); + list_for_each_entry(mnode_obj, &allocator->free_list, link) { + if (pnode->ul_size <= mnode_obj->ul_size) { + /* insert our node before the current traversed node */ + list_add_tail(&pnode->link, &mnode_obj->link); + return; + } } + /* add our pnode to the end of the freelist */ + list_add_tail(&pnode->link, &allocator->free_list); } /* diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c index 132e960967b9..6ce3493003c9 100644 --- a/drivers/staging/tidspbridge/pmgr/dev.c +++ b/drivers/staging/tidspbridge/pmgr/dev.c @@ -16,6 +16,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include +#include /* ----------------------------------- Host OS */ #include @@ -28,7 +29,6 @@ /* ----------------------------------- OS Adaptation Layer */ #include -#include /* ----------------------------------- Platform Manager */ #include @@ -60,7 +60,6 @@ /* The Bridge device object: */ struct dev_object { - /* LST requires "link" to be first field! */ struct list_head link; /* Link to next dev_object. */ u8 dev_type; /* Device Type */ struct cfg_devnode *dev_node_obj; /* Platform specific dev id */ @@ -79,7 +78,7 @@ struct dev_object { struct ldr_module *module_obj; /* Bridge Module handle. */ u32 word_size; /* DSP word size: quick access. */ struct drv_object *hdrv_obj; /* Driver Object */ - struct lst_list *proc_list; /* List of Proceeosr attached to + struct list_head proc_list; /* List of Processor attached to * this device */ struct node_mgr *hnode_mgr; }; @@ -255,19 +254,12 @@ int dev_create_device(struct dev_object **device_obj, (struct dev_object *)dev_obj, NULL); } /* Add the new DEV_Object to the global list: */ - if (!status) { - lst_init_elem(&dev_obj->link); + if (!status) status = drv_insert_dev_object(hdrv_obj, dev_obj); - } + /* Create the Processor List */ - if (!status) { - dev_obj->proc_list = kzalloc(sizeof(struct lst_list), - GFP_KERNEL); - if (!(dev_obj->proc_list)) - status = -EPERM; - else - INIT_LIST_HEAD(&dev_obj->proc_list->head); - } + if (!status) + INIT_LIST_HEAD(&dev_obj->proc_list); leave: /* If all went well, return a handle to the dev object; * else, cleanup and return NULL in the OUT parameter. */ @@ -275,7 +267,6 @@ leave: *device_obj = dev_obj; } else { if (dev_obj) { - kfree(dev_obj->proc_list); if (dev_obj->cod_mgr) cod_delete(dev_obj->cod_mgr); if (dev_obj->dmm_mgr) @@ -403,9 +394,6 @@ int dev_destroy_device(struct dev_object *hdev_obj) } else status = -EPERM; if (!status) { - kfree(dev_obj->proc_list); - dev_obj->proc_list = NULL; - /* Remove this DEV_Object from the global list: */ drv_remove_dev_object(dev_obj->hdrv_obj, dev_obj); /* Free The library * LDR_FreeModule @@ -801,18 +789,17 @@ bool dev_init(void) */ int dev_notify_clients(struct dev_object *hdev_obj, u32 ret) { - int status = 0; - struct dev_object *dev_obj = hdev_obj; - void *proc_obj; + struct list_head *curr; - for (proc_obj = (void *)lst_first(dev_obj->proc_list); - proc_obj != NULL; - proc_obj = (void *)lst_next(dev_obj->proc_list, - (struct list_head *)proc_obj)) - proc_notify_clients(proc_obj, (u32) ret); + /* + * FIXME: this code needs struct proc_object to have a list_head + * at the begining. If not, this can go horribly wrong. + */ + list_for_each(curr, &dev_obj->proc_list) + proc_notify_clients((void *)curr, (u32) ret); - return status; + return 0; } /* @@ -1000,15 +987,18 @@ int dev_insert_proc_object(struct dev_object *hdev_obj, DBC_REQUIRE(refs > 0); DBC_REQUIRE(dev_obj); DBC_REQUIRE(proc_obj != 0); - DBC_REQUIRE(dev_obj->proc_list != NULL); DBC_REQUIRE(already_attached != NULL); - if (!LST_IS_EMPTY(dev_obj->proc_list)) + if (!list_empty(&dev_obj->proc_list)) *already_attached = true; /* Add DevObject to tail. */ - lst_put_tail(dev_obj->proc_list, (struct list_head *)proc_obj); + /* + * FIXME: this code needs struct proc_object to have a list_head + * at the begining. If not, this can go horribly wrong. + */ + list_add_tail((struct list_head *)proc_obj, &dev_obj->proc_list); - DBC_ENSURE(!status && !LST_IS_EMPTY(dev_obj->proc_list)); + DBC_ENSURE(!status && !list_empty(&dev_obj->proc_list)); return status; } @@ -1039,15 +1029,12 @@ int dev_remove_proc_object(struct dev_object *hdev_obj, u32 proc_obj) DBC_REQUIRE(dev_obj); DBC_REQUIRE(proc_obj != 0); - DBC_REQUIRE(dev_obj->proc_list != NULL); - DBC_REQUIRE(!LST_IS_EMPTY(dev_obj->proc_list)); + DBC_REQUIRE(!list_empty(&dev_obj->proc_list)); /* Search list for dev_obj: */ - for (cur_elem = lst_first(dev_obj->proc_list); cur_elem != NULL; - cur_elem = lst_next(dev_obj->proc_list, cur_elem)) { - /* If found, remove it. */ + list_for_each(cur_elem, &dev_obj->proc_list) { if ((u32) cur_elem == proc_obj) { - lst_remove_elem(dev_obj->proc_list, cur_elem); + list_del(cur_elem); status = 0; break; } -- cgit v1.2.3 From 0005391f30a9b36e10cc9a4b6e0fa12b1db680c0 Mon Sep 17 00:00:00 2001 From: Ionut Nicu Date: Sun, 21 Nov 2010 10:46:26 +0000 Subject: staging: tidspbridge: convert rmgr to list_head Convert the rmgr module of the tidspbridge driver to use struct list_head instead of struct lst_list. Signed-off-by: Ionut Nicu Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/rmgr/drv.c | 115 +++++++++----------------------- drivers/staging/tidspbridge/rmgr/node.c | 50 +++++--------- drivers/staging/tidspbridge/rmgr/proc.c | 2 - drivers/staging/tidspbridge/rmgr/rmm.c | 75 +++++++-------------- 4 files changed, 72 insertions(+), 170 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c index c50579ca31e7..e0fc8956a96d 100644 --- a/drivers/staging/tidspbridge/rmgr/drv.c +++ b/drivers/staging/tidspbridge/rmgr/drv.c @@ -16,6 +16,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include +#include /* ----------------------------------- Host OS */ #include @@ -26,9 +27,6 @@ /* ----------------------------------- Trace & Debug */ #include -/* ----------------------------------- OS Adaptation Layer */ -#include - /* ----------------------------------- This */ #include #include @@ -42,8 +40,8 @@ /* ----------------------------------- Defines, Data Structures, Typedefs */ struct drv_object { - struct lst_list *dev_list; - struct lst_list *dev_node_string; + struct list_head dev_list; + struct list_head dev_node_string; }; /* @@ -316,22 +314,8 @@ int drv_create(struct drv_object **drv_obj) pdrv_object = kzalloc(sizeof(struct drv_object), GFP_KERNEL); if (pdrv_object) { /* Create and Initialize List of device objects */ - pdrv_object->dev_list = kzalloc(sizeof(struct lst_list), - GFP_KERNEL); - if (pdrv_object->dev_list) { - /* Create and Initialize List of device Extension */ - pdrv_object->dev_node_string = - kzalloc(sizeof(struct lst_list), GFP_KERNEL); - if (!(pdrv_object->dev_node_string)) { - status = -EPERM; - } else { - INIT_LIST_HEAD(&pdrv_object-> - dev_node_string->head); - INIT_LIST_HEAD(&pdrv_object->dev_list->head); - } - } else { - status = -ENOMEM; - } + INIT_LIST_HEAD(&pdrv_object->dev_list); + INIT_LIST_HEAD(&pdrv_object->dev_node_string); } else { status = -ENOMEM; } @@ -348,8 +332,6 @@ int drv_create(struct drv_object **drv_obj) if (!status) { *drv_obj = pdrv_object; } else { - kfree(pdrv_object->dev_list); - kfree(pdrv_object->dev_node_string); /* Free the DRV Object */ kfree(pdrv_object); } @@ -386,13 +368,6 @@ int drv_destroy(struct drv_object *driver_obj) DBC_REQUIRE(refs > 0); DBC_REQUIRE(pdrv_object); - /* - * Delete the List if it exists.Should not come here - * as the drv_remove_dev_object and the Last drv_request_resources - * removes the list if the lists are empty. - */ - kfree(pdrv_object->dev_list); - kfree(pdrv_object->dev_node_string); kfree(pdrv_object); /* Update the DRV Object in the driver data */ if (drv_datap) { @@ -424,7 +399,7 @@ int drv_get_dev_object(u32 index, struct drv_object *hdrv_obj, DBC_REQUIRE(device_obj != NULL); DBC_REQUIRE(index >= 0); DBC_REQUIRE(refs > 0); - DBC_ASSERT(!(LST_IS_EMPTY(pdrv_obj->dev_list))); + DBC_ASSERT(!(list_empty(&pdrv_obj->dev_list))); dev_obj = (struct dev_object *)drv_get_first_dev_object(); for (i = 0; i < index; i++) { @@ -455,9 +430,8 @@ u32 drv_get_first_dev_object(void) if (drv_datap && drv_datap->drv_object) { pdrv_obj = drv_datap->drv_object; - if ((pdrv_obj->dev_list != NULL) && - !LST_IS_EMPTY(pdrv_obj->dev_list)) - dw_dev_object = (u32) lst_first(pdrv_obj->dev_list); + if (!list_empty(&pdrv_obj->dev_list)) + dw_dev_object = (u32) pdrv_obj->dev_list.next; } else { pr_err("%s: Failed to retrieve the object handle\n", __func__); } @@ -479,10 +453,9 @@ u32 drv_get_first_dev_extension(void) if (drv_datap && drv_datap->drv_object) { pdrv_obj = drv_datap->drv_object; - if ((pdrv_obj->dev_node_string != NULL) && - !LST_IS_EMPTY(pdrv_obj->dev_node_string)) { + if (!list_empty(&pdrv_obj->dev_node_string)) { dw_dev_extension = - (u32) lst_first(pdrv_obj->dev_node_string); + (u32) pdrv_obj->dev_node_string.next; } } else { pr_err("%s: Failed to retrieve the object handle\n", __func__); @@ -503,16 +476,15 @@ u32 drv_get_next_dev_object(u32 hdev_obj) u32 dw_next_dev_object = 0; struct drv_object *pdrv_obj; struct drv_data *drv_datap = dev_get_drvdata(bridge); - - DBC_REQUIRE(hdev_obj != 0); + struct list_head *curr; if (drv_datap && drv_datap->drv_object) { pdrv_obj = drv_datap->drv_object; - if ((pdrv_obj->dev_list != NULL) && - !LST_IS_EMPTY(pdrv_obj->dev_list)) { - dw_next_dev_object = (u32) lst_next(pdrv_obj->dev_list, - (struct list_head *) - hdev_obj); + if (!list_empty(&pdrv_obj->dev_list)) { + curr = (struct list_head *)hdev_obj; + if (list_is_last(curr, &pdrv_obj->dev_list)) + return 0; + dw_next_dev_object = (u32) curr->next; } } else { pr_err("%s: Failed to retrieve the object handle\n", __func__); @@ -534,16 +506,15 @@ u32 drv_get_next_dev_extension(u32 dev_extension) u32 dw_dev_extension = 0; struct drv_object *pdrv_obj; struct drv_data *drv_datap = dev_get_drvdata(bridge); - - DBC_REQUIRE(dev_extension != 0); + struct list_head *curr; if (drv_datap && drv_datap->drv_object) { pdrv_obj = drv_datap->drv_object; - if ((pdrv_obj->dev_node_string != NULL) && - !LST_IS_EMPTY(pdrv_obj->dev_node_string)) { - dw_dev_extension = - (u32) lst_next(pdrv_obj->dev_node_string, - (struct list_head *)dev_extension); + if (!list_empty(&pdrv_obj->dev_node_string)) { + curr = (struct list_head *)dev_extension; + if (list_is_last(curr, &pdrv_obj->dev_node_string)) + return 0; + dw_dev_extension = (u32) curr->next; } } else { pr_err("%s: Failed to retrieve the object handle\n", __func__); @@ -584,11 +555,8 @@ int drv_insert_dev_object(struct drv_object *driver_obj, DBC_REQUIRE(refs > 0); DBC_REQUIRE(hdev_obj != NULL); DBC_REQUIRE(pdrv_object); - DBC_ASSERT(pdrv_object->dev_list); - - lst_put_tail(pdrv_object->dev_list, (struct list_head *)hdev_obj); - DBC_ENSURE(!LST_IS_EMPTY(pdrv_object->dev_list)); + list_add_tail((struct list_head *)hdev_obj, &pdrv_object->dev_list); return 0; } @@ -610,26 +578,17 @@ int drv_remove_dev_object(struct drv_object *driver_obj, DBC_REQUIRE(pdrv_object); DBC_REQUIRE(hdev_obj != NULL); - DBC_REQUIRE(pdrv_object->dev_list != NULL); - DBC_REQUIRE(!LST_IS_EMPTY(pdrv_object->dev_list)); + DBC_REQUIRE(!list_empty(&pdrv_object->dev_list)); /* Search list for p_proc_object: */ - for (cur_elem = lst_first(pdrv_object->dev_list); cur_elem != NULL; - cur_elem = lst_next(pdrv_object->dev_list, cur_elem)) { + list_for_each(cur_elem, &pdrv_object->dev_list) { /* If found, remove it. */ if ((struct dev_object *)cur_elem == hdev_obj) { - lst_remove_elem(pdrv_object->dev_list, cur_elem); + list_del(cur_elem); status = 0; break; } } - /* Remove list if empty. */ - if (LST_IS_EMPTY(pdrv_object->dev_list)) { - kfree(pdrv_object->dev_list); - pdrv_object->dev_list = NULL; - } - DBC_ENSURE((pdrv_object->dev_list == NULL) || - !LST_IS_EMPTY(pdrv_object->dev_list)); return status; } @@ -663,14 +622,13 @@ int drv_request_resources(u32 dw_context, u32 *dev_node_strg) if (!status) { pszdev_node = kzalloc(sizeof(struct drv_ext), GFP_KERNEL); if (pszdev_node) { - lst_init_elem(&pszdev_node->link); strncpy(pszdev_node->sz_string, (char *)dw_context, MAXREGPATHLENGTH - 1); pszdev_node->sz_string[MAXREGPATHLENGTH - 1] = '\0'; /* Update the Driver Object List */ *dev_node_strg = (u32) pszdev_node->sz_string; - lst_put_tail(pdrv_object->dev_node_string, - (struct list_head *)pszdev_node); + list_add_tail(&pszdev_node->link, + &pdrv_object->dev_node_string); } else { status = -ENOMEM; *dev_node_strg = 0; @@ -682,7 +640,7 @@ int drv_request_resources(u32 dw_context, u32 *dev_node_strg) } DBC_ENSURE((!status && dev_node_strg != NULL && - !LST_IS_EMPTY(pdrv_object->dev_node_string)) || + !list_empty(&pdrv_object->dev_node_string)) || (status && *dev_node_strg == 0)); return status; @@ -696,7 +654,6 @@ int drv_request_resources(u32 dw_context, u32 *dev_node_strg) int drv_release_resources(u32 dw_context, struct drv_object *hdrv_obj) { int status = 0; - struct drv_object *pdrv_object = (struct drv_object *)hdrv_obj; struct drv_ext *pszdev_node; /* @@ -706,23 +663,13 @@ int drv_release_resources(u32 dw_context, struct drv_object *hdrv_obj) for (pszdev_node = (struct drv_ext *)drv_get_first_dev_extension(); pszdev_node != NULL; pszdev_node = (struct drv_ext *) drv_get_next_dev_extension((u32) pszdev_node)) { - if (!pdrv_object->dev_node_string) { - /* When this could happen? */ - continue; - } if ((u32) pszdev_node == dw_context) { /* Found it */ /* Delete from the Driver object list */ - lst_remove_elem(pdrv_object->dev_node_string, - (struct list_head *)pszdev_node); - kfree((void *)pszdev_node); + list_del(&pszdev_node->link); + kfree(pszdev_node); break; } - /* Delete the List if it is empty */ - if (LST_IS_EMPTY(pdrv_object->dev_node_string)) { - kfree(pdrv_object->dev_node_string); - pdrv_object->dev_node_string = NULL; - } } return status; } diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index ab35806591da..62d5c31de41f 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -18,6 +18,8 @@ #include #include +#include + /* ----------------------------------- Host OS */ #include @@ -28,7 +30,6 @@ #include /* ----------------------------------- OS Adaptation Layer */ -#include #include #include #include @@ -129,7 +130,7 @@ struct node_mgr { struct bridge_drv_interface *intf_fxns; struct dcd_manager *hdcd_mgr; /* Proc/Node data manager */ struct disp_object *disp_obj; /* Node dispatcher */ - struct lst_list *node_list; /* List of all allocated nodes */ + struct list_head node_list; /* List of all allocated nodes */ u32 num_nodes; /* Number of nodes in node_list */ u32 num_created; /* Number of nodes *created* on DSP */ DECLARE_BITMAP(pipe_map, MAXPIPES); /* Pipe connection bitmap */ @@ -640,13 +641,12 @@ func_cont: if (!status) { /* Add the node to the node manager's list of allocated * nodes. */ - lst_init_elem((struct list_head *)pnode); NODE_SET_STATE(pnode, NODE_ALLOCATED); mutex_lock(&hnode_mgr->node_mgr_lock); - lst_put_tail(hnode_mgr->node_list, (struct list_head *) pnode); - ++(hnode_mgr->num_nodes); + list_add_tail(&pnode->list_elem, &hnode_mgr->node_list); + ++(hnode_mgr->num_nodes); /* Exit critical section */ mutex_unlock(&hnode_mgr->node_mgr_lock); @@ -1338,9 +1338,7 @@ int node_create_mgr(struct node_mgr **node_man, node_mgr_obj = kzalloc(sizeof(struct node_mgr), GFP_KERNEL); if (node_mgr_obj) { node_mgr_obj->hdev_obj = hdev_obj; - node_mgr_obj->node_list = kzalloc(sizeof(struct lst_list), - GFP_KERNEL); - INIT_LIST_HEAD(&node_mgr_obj->node_list->head); + INIT_LIST_HEAD(&node_mgr_obj->node_list); node_mgr_obj->ntfy_obj = kmalloc( sizeof(struct ntfy_object), GFP_KERNEL); if (node_mgr_obj->ntfy_obj) @@ -1563,7 +1561,7 @@ func_cont1: } /* Free host side resources even if a failure occurred */ /* Remove node from hnode_mgr->node_list */ - lst_remove_elem(hnode_mgr->node_list, (struct list_head *)pnode); + list_del(&pnode->list_elem); hnode_mgr->num_nodes--; /* Decrement count of nodes created on DSP */ if ((state != NODE_ALLOCATED) || ((state == NODE_ALLOCATED) && @@ -1617,7 +1615,7 @@ int node_enum_nodes(struct node_mgr *hnode_mgr, void **node_tab, u32 *pu_allocated) { struct node_object *hnode; - u32 i; + u32 i = 0; int status = 0; DBC_REQUIRE(refs > 0); DBC_REQUIRE(node_tab != NULL || node_tab_size == 0); @@ -1636,15 +1634,8 @@ int node_enum_nodes(struct node_mgr *hnode_mgr, void **node_tab, *pu_num_nodes = 0; status = -EINVAL; } else { - hnode = (struct node_object *)lst_first(hnode_mgr-> - node_list); - for (i = 0; i < hnode_mgr->num_nodes; i++) { - DBC_ASSERT(hnode); - node_tab[i] = hnode; - hnode = (struct node_object *)lst_next - (hnode_mgr->node_list, - (struct list_head *)hnode); - } + list_for_each_entry(hnode, &hnode_mgr->node_list, list_elem) + node_tab[i++] = hnode; *pu_allocated = *pu_num_nodes = hnode_mgr->num_nodes; } /* end of sync_enter_cs */ @@ -2632,7 +2623,7 @@ func_end: */ static void delete_node_mgr(struct node_mgr *hnode_mgr) { - struct node_object *hnode; + struct node_object *hnode, *tmp; if (hnode_mgr) { /* Free resources */ @@ -2640,13 +2631,10 @@ static void delete_node_mgr(struct node_mgr *hnode_mgr) dcd_destroy_manager(hnode_mgr->hdcd_mgr); /* Remove any elements remaining in lists */ - if (hnode_mgr->node_list) { - while ((hnode = (struct node_object *) - lst_get_head(hnode_mgr->node_list))) - delete_node(hnode, NULL); - - DBC_ASSERT(LST_IS_EMPTY(hnode_mgr->node_list)); - kfree(hnode_mgr->node_list); + list_for_each_entry_safe(hnode, tmp, &hnode_mgr->node_list, + list_elem) { + list_del(&hnode->list_elem); + delete_node(hnode, NULL); } mutex_destroy(&hnode_mgr->node_mgr_lock); if (hnode_mgr->ntfy_obj) { @@ -3186,23 +3174,17 @@ int node_find_addr(struct node_mgr *node_mgr, u32 sym_addr, { struct node_object *node_obj; int status = -ENOENT; - u32 n; pr_debug("%s(0x%x, 0x%x, 0x%x, 0x%x, %s)\n", __func__, (unsigned int) node_mgr, sym_addr, offset_range, (unsigned int) sym_addr_output, sym_name); - node_obj = (struct node_object *)(node_mgr->node_list->head.next); - - for (n = 0; n < node_mgr->num_nodes; n++) { + list_for_each_entry(node_obj, &node_mgr->node_list, list_elem) { status = nldr_find_addr(node_obj->nldr_node_obj, sym_addr, offset_range, sym_addr_output, sym_name); - if (!status) break; - - node_obj = (struct node_object *) (node_obj->list_elem.next); } return status; diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c index b47d7aa747b1..d5f6719774d8 100644 --- a/drivers/staging/tidspbridge/rmgr/proc.c +++ b/drivers/staging/tidspbridge/rmgr/proc.c @@ -29,7 +29,6 @@ #include /* ----------------------------------- OS Adaptation Layer */ -#include #include #include /* ----------------------------------- Bridge Driver */ @@ -357,7 +356,6 @@ proc_attach(u32 processor_id, * Return handle to this Processor Object: * Find out if the Device is already attached to a * Processor. If so, return AlreadyAttached status */ - lst_init_elem(&p_proc_object->link); status = dev_insert_proc_object(p_proc_object->hdev_obj, (u32) p_proc_object, &p_proc_object-> diff --git a/drivers/staging/tidspbridge/rmgr/rmm.c b/drivers/staging/tidspbridge/rmgr/rmm.c index 761e8f4fa46b..aae86570035b 100644 --- a/drivers/staging/tidspbridge/rmgr/rmm.c +++ b/drivers/staging/tidspbridge/rmgr/rmm.c @@ -38,6 +38,10 @@ */ #include +#include + +/* ----------------------------------- Host OS */ +#include /* ----------------------------------- DSP/BIOS Bridge */ #include @@ -45,9 +49,6 @@ /* ----------------------------------- Trace & Debug */ #include -/* ----------------------------------- OS Adaptation Layer */ -#include - /* ----------------------------------- This */ #include @@ -79,7 +80,7 @@ struct rmm_target_obj { struct rmm_segment *seg_tab; struct rmm_header **free_list; u32 num_segs; - struct lst_list *ovly_list; /* List of overlay memory in use */ + struct list_head ovly_list; /* List of overlay memory in use */ }; static u32 refs; /* module reference count */ @@ -95,8 +96,7 @@ static bool free_block(struct rmm_target_obj *target, u32 segid, u32 addr, int rmm_alloc(struct rmm_target_obj *target, u32 segid, u32 size, u32 align, u32 *dsp_address, bool reserve) { - struct rmm_ovly_sect *sect; - struct rmm_ovly_sect *prev_sect = NULL; + struct rmm_ovly_sect *sect, *prev_sect = NULL; struct rmm_ovly_sect *new_sect; u32 addr; int status = 0; @@ -120,10 +120,9 @@ int rmm_alloc(struct rmm_target_obj *target, u32 segid, u32 size, /* An overlay section - See if block is already in use. If not, * insert into the list in ascending address size. */ addr = *dsp_address; - sect = (struct rmm_ovly_sect *)lst_first(target->ovly_list); /* Find place to insert new list element. List is sorted from * smallest to largest address. */ - while (sect != NULL) { + list_for_each_entry(sect, &target->ovly_list, list_elem) { if (addr <= sect->addr) { /* Check for overlap with sect */ if ((addr + size > sect->addr) || (prev_sect && @@ -135,9 +134,6 @@ int rmm_alloc(struct rmm_target_obj *target, u32 segid, u32 size, break; } prev_sect = sect; - sect = (struct rmm_ovly_sect *)lst_next(target->ovly_list, - (struct list_head *) - sect); } if (!status) { /* No overlap - allocate list element for new section. */ @@ -145,20 +141,17 @@ int rmm_alloc(struct rmm_target_obj *target, u32 segid, u32 size, if (new_sect == NULL) { status = -ENOMEM; } else { - lst_init_elem((struct list_head *)new_sect); new_sect->addr = addr; new_sect->size = size; new_sect->page = segid; - if (sect == NULL) { + if (list_is_last(sect, &target->ovly_list)) /* Put new section at the end of the list */ - lst_put_tail(target->ovly_list, - (struct list_head *)new_sect); - } else { + list_add_tail(&new_sect->list_elem, + &target->ovly_list); + else /* Put new section just before sect */ - lst_insert_before(target->ovly_list, - (struct list_head *)new_sect, - (struct list_head *)sect); - } + list_add_tail(&new_sect->list_elem, + §->list_elem); } } func_end: @@ -230,14 +223,8 @@ int rmm_create(struct rmm_target_obj **target_obj, } func_cont: /* Initialize overlay memory list */ - if (!status) { - target->ovly_list = kzalloc(sizeof(struct lst_list), - GFP_KERNEL); - if (target->ovly_list == NULL) - status = -ENOMEM; - else - INIT_LIST_HEAD(&target->ovly_list->head); - } + if (!status) + INIT_LIST_HEAD(&target->ovly_list); if (!status) { *target_obj = target; @@ -259,7 +246,7 @@ func_cont: */ void rmm_delete(struct rmm_target_obj *target) { - struct rmm_ovly_sect *ovly_section; + struct rmm_ovly_sect *sect, *tmp; struct rmm_header *hptr; struct rmm_header *next; u32 i; @@ -268,13 +255,9 @@ void rmm_delete(struct rmm_target_obj *target) kfree(target->seg_tab); - if (target->ovly_list) { - while ((ovly_section = (struct rmm_ovly_sect *)lst_get_head - (target->ovly_list))) { - kfree(ovly_section); - } - DBC_ASSERT(LST_IS_EMPTY(target->ovly_list)); - kfree(target->ovly_list); + list_for_each_entry_safe(sect, tmp, &target->ovly_list, list_elem) { + list_del(§->list_elem); + kfree(sect); } if (target->free_list != NULL) { @@ -311,8 +294,8 @@ void rmm_exit(void) bool rmm_free(struct rmm_target_obj *target, u32 segid, u32 dsp_addr, u32 size, bool reserved) { - struct rmm_ovly_sect *sect; - bool ret = true; + struct rmm_ovly_sect *sect, *tmp; + bool ret = false; DBC_REQUIRE(target); @@ -333,24 +316,16 @@ bool rmm_free(struct rmm_target_obj *target, u32 segid, u32 dsp_addr, u32 size, } else { /* Unreserve memory */ - sect = (struct rmm_ovly_sect *)lst_first(target->ovly_list); - while (sect != NULL) { + list_for_each_entry_safe(sect, tmp, &target->ovly_list, + list_elem) { if (dsp_addr == sect->addr) { DBC_ASSERT(size == sect->size); /* Remove from list */ - lst_remove_elem(target->ovly_list, - (struct list_head *)sect); + list_del(§->list_elem); kfree(sect); - break; + return true; } - sect = - (struct rmm_ovly_sect *)lst_next(target->ovly_list, - (struct list_head - *)sect); } - if (sect == NULL) - ret = false; - } return ret; } -- cgit v1.2.3 From edbeef96473fac02c7aa21db0c9de23cb6299288 Mon Sep 17 00:00:00 2001 From: Ionut Nicu Date: Sun, 21 Nov 2010 10:46:27 +0000 Subject: staging: tidspbridge: remove custom linked list Now that all users of lst_list have been converted to the standard linux list_head API, we can remove the associated header file. Signed-off-by: Ionut Nicu Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/TODO | 1 - .../staging/tidspbridge/include/dspbridge/list.h | 225 --------------------- 2 files changed, 226 deletions(-) delete mode 100644 drivers/staging/tidspbridge/include/dspbridge/list.h (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/TODO b/drivers/staging/tidspbridge/TODO index 187363f2bdc8..1c51e2dc7b56 100644 --- a/drivers/staging/tidspbridge/TODO +++ b/drivers/staging/tidspbridge/TODO @@ -6,7 +6,6 @@ * Eliminate general services and libraries - use or extend existing kernel libraries instead (e.g. gcf/lcm in nldr.c, global helpers in gen/) * Eliminate direct manipulation of OMAP_SYSC_BASE -* Eliminate list.h : seem like a redundant wrapper to existing kernel lists * Eliminate DSP_SUCCEEDED macros and their imposed redundant indentations (adopt the kernel way of checking for return values) * Audit interfaces exposed to user space diff --git a/drivers/staging/tidspbridge/include/dspbridge/list.h b/drivers/staging/tidspbridge/include/dspbridge/list.h deleted file mode 100644 index 6837b614073a..000000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/list.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - * list.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Declarations of list management control structures and definitions - * of inline list management functions. - * - * Copyright (C) 2008 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef LIST_ -#define LIST_ - -#include -#include - -#define LST_IS_EMPTY(l) list_empty(&(l)->head) - -struct lst_list { - struct list_head head; -}; - -/* - * ======== lst_first ======== - * Purpose: - * Returns a pointer to the first element of the list, or NULL if the list - * is empty. - * Parameters: - * lst: Pointer to list control structure. - * Returns: - * Pointer to first list element, or NULL. - * Requires: - * - LST initialized. - * - lst != NULL. - * Ensures: - */ -static inline struct list_head *lst_first(struct lst_list *lst) -{ - if (lst && !list_empty(&lst->head)) - return lst->head.next; - return NULL; -} - -/* - * ======== lst_get_head ======== - * Purpose: - * Pops the head off the list and returns a pointer to it. - * Details: - * If the list is empty, returns NULL. - * Else, removes the element at the head of the list, making the next - * element the head of the list. - * The head is removed by making the tail element of the list point its - * "next" pointer at the next element after the head, and by making the - * "prev" pointer of the next element after the head point at the tail - * element. So the next element after the head becomes the new head of - * the list. - * Parameters: - * lst: Pointer to list control structure of list whose head - * element is to be removed - * Returns: - * Pointer to element that was at the head of the list (success) - * NULL No elements in list - * Requires: - * - LST initialized. - * - lst != NULL. - * Ensures: - * Notes: - * Because the tail of the list points forward (its "next" pointer) to - * the head of the list, and the head of the list points backward (its - * "prev" pointer) to the tail of the list, this list is circular. - */ -static inline struct list_head *lst_get_head(struct lst_list *lst) -{ - struct list_head *elem_list; - - if (!lst || list_empty(&lst->head)) - return NULL; - - elem_list = lst->head.next; - lst->head.next = elem_list->next; - elem_list->next->prev = &lst->head; - - return elem_list; -} - -/* - * ======== lst_init_elem ======== - * Purpose: - * Initializes a list element to default (cleared) values - * Details: - * Parameters: - * elem_list: Pointer to list element to be reset - * Returns: - * Requires: - * LST initialized. - * Ensures: - * Notes: - * This function must not be called to "reset" an element in the middle - * of a list chain -- that would break the chain. - * - */ -static inline void lst_init_elem(struct list_head *elem_list) -{ - if (elem_list) { - elem_list->next = NULL; - elem_list->prev = NULL; - } -} - -/* - * ======== lst_insert_before ======== - * Purpose: - * Insert the element before the existing element. - * Parameters: - * lst: Pointer to list control structure. - * elem_list: Pointer to element in list to insert. - * elem_existing: Pointer to existing list element. - * Returns: - * Requires: - * - LST initialized. - * - lst != NULL. - * - elem_list != NULL. - * - elem_existing != NULL. - * Ensures: - */ -static inline void lst_insert_before(struct lst_list *lst, - struct list_head *elem_list, - struct list_head *elem_existing) -{ - if (lst && elem_list && elem_existing) - list_add_tail(elem_list, elem_existing); -} - -/* - * ======== lst_next ======== - * Purpose: - * Returns a pointer to the next element of the list, or NULL if the next - * element is the head of the list or the list is empty. - * Parameters: - * lst: Pointer to list control structure. - * cur_elem: Pointer to element in list to remove. - * Returns: - * Pointer to list element, or NULL. - * Requires: - * - LST initialized. - * - lst != NULL. - * - cur_elem != NULL. - * Ensures: - */ -static inline struct list_head *lst_next(struct lst_list *lst, - struct list_head *cur_elem) -{ - if (lst && !list_empty(&lst->head) && cur_elem && - (cur_elem->next != &lst->head)) - return cur_elem->next; - return NULL; -} - -/* - * ======== lst_put_tail ======== - * Purpose: - * Adds the specified element to the tail of the list - * Details: - * Sets new element's "prev" pointer to the address previously held by - * the head element's prev pointer. This is the previous tail member of - * the list. - * Sets the new head's prev pointer to the address of the element. - * Sets next pointer of the previous tail member of the list to point to - * the new element (rather than the head, which it had been pointing at). - * Sets new element's next pointer to the address of the head element. - * Sets head's prev pointer to the address of the new element. - * Parameters: - * lst: Pointer to list control structure to which *elem_list will be - * added - * elem_list: Pointer to list element to be added - * Returns: - * Void - * Requires: - * *elem_list and *lst must both exist. - * LST initialized. - * Ensures: - * Notes: - * Because the tail is always "just before" the head of the list (the - * tail's "next" pointer points at the head of the list, and the head's - * "prev" pointer points at the tail of the list), the list is circular. - */ -static inline void lst_put_tail(struct lst_list *lst, - struct list_head *elem_list) -{ - if (lst && elem_list) - list_add_tail(elem_list, &lst->head); -} - -/* - * ======== lst_remove_elem ======== - * Purpose: - * Removes (unlinks) the given element from the list, if the list is not - * empty. Does not free the list element. - * Parameters: - * lst: Pointer to list control structure. - * cur_elem: Pointer to element in list to remove. - * Returns: - * Requires: - * - LST initialized. - * - lst != NULL. - * - cur_elem != NULL. - * Ensures: - */ -static inline void lst_remove_elem(struct lst_list *lst, - struct list_head *cur_elem) -{ - if (lst && !list_empty(&lst->head) && cur_elem) - list_del_init(cur_elem); -} - -#endif /* LIST_ */ -- cgit v1.2.3 From d65c14b3611ca5e0ed64305faddd39e604f618da Mon Sep 17 00:00:00 2001 From: Ionut Nicu Date: Sun, 21 Nov 2010 10:46:28 +0000 Subject: staging: tidspbridge: core code cleanup Reorganized some code in the core module to increase its readability. Most of the changes reduce the code indentation level and simplifiy the code. No functional changes were done. Signed-off-by: Ionut Nicu Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/core/chnl_sm.c | 449 +++++++++++++--------------- drivers/staging/tidspbridge/core/io_sm.c | 192 ++++++------ drivers/staging/tidspbridge/core/msg_sm.c | 453 +++++++++++++---------------- 3 files changed, 501 insertions(+), 593 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c index f9550363b94f..2d06bb0989ac 100644 --- a/drivers/staging/tidspbridge/core/chnl_sm.c +++ b/drivers/staging/tidspbridge/core/chnl_sm.c @@ -105,35 +105,31 @@ int bridge_chnl_add_io_req(struct chnl_object *chnl_obj, void *host_buf, is_eos = (byte_size == 0); /* Validate args */ - if (!host_buf || !pchnl) { - status = -EFAULT; - } else if (is_eos && CHNL_IS_INPUT(pchnl->chnl_mode)) { - status = -EPERM; - } else { - /* - * Check the channel state: only queue chirp if channel state - * allows it. - */ - dw_state = pchnl->dw_state; - if (dw_state != CHNL_STATEREADY) { - if (dw_state & CHNL_STATECANCEL) - status = -ECANCELED; - else if ((dw_state & CHNL_STATEEOS) && - CHNL_IS_OUTPUT(pchnl->chnl_mode)) - status = -EPIPE; - else - /* No other possible states left */ - DBC_ASSERT(0); - } + if (!host_buf || !pchnl) + return -EFAULT; + + if (is_eos && CHNL_IS_INPUT(pchnl->chnl_mode)) + return -EPERM; + + /* + * Check the channel state: only queue chirp if channel state + * allows it. + */ + dw_state = pchnl->dw_state; + if (dw_state != CHNL_STATEREADY) { + if (dw_state & CHNL_STATECANCEL) + return -ECANCELED; + if ((dw_state & CHNL_STATEEOS) && + CHNL_IS_OUTPUT(pchnl->chnl_mode)) + return -EPIPE; + /* No other possible states left */ + DBC_ASSERT(0); } dev_obj = dev_get_first(); dev_get_bridge_context(dev_obj, &dev_ctxt); if (!dev_ctxt) - status = -EFAULT; - - if (status) - goto func_end; + return -EFAULT; if (pchnl->chnl_type == CHNL_PCPY && pchnl->chnl_id > 1 && host_buf) { if (!(host_buf < (void *)USERMODE_ADDR)) { @@ -142,18 +138,16 @@ int bridge_chnl_add_io_req(struct chnl_object *chnl_obj, void *host_buf, } /* if addr in user mode, then copy to kernel space */ host_sys_buf = kmalloc(buf_size, GFP_KERNEL); - if (host_sys_buf == NULL) { - status = -ENOMEM; - goto func_end; - } + if (host_sys_buf == NULL) + return -ENOMEM; + if (CHNL_IS_OUTPUT(pchnl->chnl_mode)) { status = copy_from_user(host_sys_buf, host_buf, - buf_size); + buf_size); if (status) { kfree(host_sys_buf); host_sys_buf = NULL; - status = -EFAULT; - goto func_end; + return -EFAULT; } } } @@ -167,66 +161,62 @@ func_cont: omap_mbox_disable_irq(dev_ctxt->mbox, IRQ_RX); if (pchnl->chnl_type == CHNL_PCPY) { /* This is a processor-copy channel. */ - if (!status && CHNL_IS_OUTPUT(pchnl->chnl_mode)) { + if (CHNL_IS_OUTPUT(pchnl->chnl_mode)) { /* Check buffer size on output channels for fit. */ - if (byte_size > - io_buf_size(pchnl->chnl_mgr_obj->hio_mgr)) + if (byte_size > io_buf_size( + pchnl->chnl_mgr_obj->hio_mgr)) { status = -EINVAL; - - } - } - if (!status) { - /* Get a free chirp: */ - if (!list_empty(&pchnl->free_packets_list)) { - chnl_packet_obj = list_first_entry( - &pchnl->free_packets_list, - struct chnl_irp, link); - list_del(&chnl_packet_obj->link); - } else { - status = -EIO; + goto out; + } } - } - if (!status) { - /* Enqueue the chirp on the chnl's IORequest queue: */ - chnl_packet_obj->host_user_buf = chnl_packet_obj->host_sys_buf = - host_buf; - if (pchnl->chnl_type == CHNL_PCPY && pchnl->chnl_id > 1) - chnl_packet_obj->host_sys_buf = host_sys_buf; - - /* - * Note: for dma chans dw_dsp_addr contains dsp address - * of SM buffer. - */ - DBC_ASSERT(chnl_mgr_obj->word_size != 0); - /* DSP address */ - chnl_packet_obj->dsp_tx_addr = - dw_dsp_addr / chnl_mgr_obj->word_size; - chnl_packet_obj->byte_size = byte_size; - chnl_packet_obj->buf_size = buf_size; - /* Only valid for output channel */ - chnl_packet_obj->dw_arg = dw_arg; - chnl_packet_obj->status = (is_eos ? CHNL_IOCSTATEOS : - CHNL_IOCSTATCOMPLETE); - list_add_tail(&chnl_packet_obj->link, &pchnl->pio_requests); - pchnl->cio_reqs++; - DBC_ASSERT(pchnl->cio_reqs <= pchnl->chnl_packets); - /* - * If end of stream, update the channel state to prevent - * more IOR's. - */ - if (is_eos) - pchnl->dw_state |= CHNL_STATEEOS; - /* Legacy DSM Processor-Copy */ - DBC_ASSERT(pchnl->chnl_type == CHNL_PCPY); - /* Request IO from the DSP */ - io_request_chnl(chnl_mgr_obj->hio_mgr, pchnl, - (CHNL_IS_INPUT(pchnl->chnl_mode) ? IO_INPUT : - IO_OUTPUT), &mb_val); - sched_dpc = true; - - } + /* Get a free chirp: */ + if (list_empty(&pchnl->free_packets_list)) { + status = -EIO; + goto out; + } + chnl_packet_obj = list_first_entry(&pchnl->free_packets_list, + struct chnl_irp, link); + list_del(&chnl_packet_obj->link); + + /* Enqueue the chirp on the chnl's IORequest queue: */ + chnl_packet_obj->host_user_buf = chnl_packet_obj->host_sys_buf = + host_buf; + if (pchnl->chnl_type == CHNL_PCPY && pchnl->chnl_id > 1) + chnl_packet_obj->host_sys_buf = host_sys_buf; + + /* + * Note: for dma chans dw_dsp_addr contains dsp address + * of SM buffer. + */ + DBC_ASSERT(chnl_mgr_obj->word_size != 0); + /* DSP address */ + chnl_packet_obj->dsp_tx_addr = dw_dsp_addr / chnl_mgr_obj->word_size; + chnl_packet_obj->byte_size = byte_size; + chnl_packet_obj->buf_size = buf_size; + /* Only valid for output channel */ + chnl_packet_obj->dw_arg = dw_arg; + chnl_packet_obj->status = (is_eos ? CHNL_IOCSTATEOS : + CHNL_IOCSTATCOMPLETE); + list_add_tail(&chnl_packet_obj->link, &pchnl->pio_requests); + pchnl->cio_reqs++; + DBC_ASSERT(pchnl->cio_reqs <= pchnl->chnl_packets); + /* + * If end of stream, update the channel state to prevent + * more IOR's. + */ + if (is_eos) + pchnl->dw_state |= CHNL_STATEEOS; + + /* Legacy DSM Processor-Copy */ + DBC_ASSERT(pchnl->chnl_type == CHNL_PCPY); + /* Request IO from the DSP */ + io_request_chnl(chnl_mgr_obj->hio_mgr, pchnl, + (CHNL_IS_INPUT(pchnl->chnl_mode) ? IO_INPUT : + IO_OUTPUT), &mb_val); + sched_dpc = true; +out: omap_mbox_enable_irq(dev_ctxt->mbox, IRQ_RX); spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock); if (mb_val != 0) @@ -236,7 +226,6 @@ func_cont: if (sched_dpc) iosm_schedule(chnl_mgr_obj->hio_mgr); -func_end: return status; } @@ -251,7 +240,6 @@ func_end: */ int bridge_chnl_cancel_io(struct chnl_object *chnl_obj) { - int status = 0; struct chnl_object *pchnl = (struct chnl_object *)chnl_obj; u32 chnl_id = -1; s8 chnl_mode; @@ -259,22 +247,23 @@ int bridge_chnl_cancel_io(struct chnl_object *chnl_obj) struct chnl_mgr *chnl_mgr_obj = NULL; /* Check args: */ - if (pchnl && pchnl->chnl_mgr_obj) { - chnl_id = pchnl->chnl_id; - chnl_mode = pchnl->chnl_mode; - chnl_mgr_obj = pchnl->chnl_mgr_obj; - } else { - status = -EFAULT; - } - if (status) - goto func_end; + if (!pchnl || !pchnl->chnl_mgr_obj) + return -EFAULT; + + chnl_id = pchnl->chnl_id; + chnl_mode = pchnl->chnl_mode; + chnl_mgr_obj = pchnl->chnl_mgr_obj; /* Mark this channel as cancelled, to prevent further IORequests or * IORequests or dispatching. */ spin_lock_bh(&chnl_mgr_obj->chnl_mgr_lock); + pchnl->dw_state |= CHNL_STATECANCEL; - if (list_empty(&pchnl->pio_requests)) - goto func_cont; + + if (list_empty(&pchnl->pio_requests)) { + spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock); + return 0; + } if (pchnl->chnl_type == CHNL_PCPY) { /* Indicate we have no more buffers available for transfer: */ @@ -296,10 +285,10 @@ int bridge_chnl_cancel_io(struct chnl_object *chnl_obj) pchnl->cio_reqs--; DBC_ASSERT(pchnl->cio_reqs >= 0); } -func_cont: + spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock); -func_end: - return status; + + return 0; } /* @@ -316,53 +305,43 @@ int bridge_chnl_close(struct chnl_object *chnl_obj) struct chnl_object *pchnl = (struct chnl_object *)chnl_obj; /* Check args: */ - if (!pchnl) { - status = -EFAULT; - goto func_cont; + if (!pchnl) + return -EFAULT; + /* Cancel IO: this ensures no further IO requests or notifications */ + status = bridge_chnl_cancel_io(chnl_obj); + if (status) + return status; + /* Assert I/O on this channel is now cancelled: Protects from io_dpc */ + DBC_ASSERT((pchnl->dw_state & CHNL_STATECANCEL)); + /* Invalidate channel object: Protects from CHNL_GetIOCompletion() */ + /* Free the slot in the channel manager: */ + pchnl->chnl_mgr_obj->ap_channel[pchnl->chnl_id] = NULL; + spin_lock_bh(&pchnl->chnl_mgr_obj->chnl_mgr_lock); + pchnl->chnl_mgr_obj->open_channels -= 1; + spin_unlock_bh(&pchnl->chnl_mgr_obj->chnl_mgr_lock); + if (pchnl->ntfy_obj) { + ntfy_delete(pchnl->ntfy_obj); + kfree(pchnl->ntfy_obj); + pchnl->ntfy_obj = NULL; } - { - /* Cancel IO: this ensures no further IO requests or - * notifications. */ - status = bridge_chnl_cancel_io(chnl_obj); + /* Reset channel event: (NOTE: user_event freed in user context) */ + if (pchnl->sync_event) { + sync_reset_event(pchnl->sync_event); + kfree(pchnl->sync_event); + pchnl->sync_event = NULL; } -func_cont: - if (!status) { - /* Assert I/O on this channel is now cancelled: Protects - * from io_dpc. */ - DBC_ASSERT((pchnl->dw_state & CHNL_STATECANCEL)); - /* Invalidate channel object: Protects from - * CHNL_GetIOCompletion(). */ - /* Free the slot in the channel manager: */ - pchnl->chnl_mgr_obj->ap_channel[pchnl->chnl_id] = NULL; - spin_lock_bh(&pchnl->chnl_mgr_obj->chnl_mgr_lock); - pchnl->chnl_mgr_obj->open_channels -= 1; - spin_unlock_bh(&pchnl->chnl_mgr_obj->chnl_mgr_lock); - if (pchnl->ntfy_obj) { - ntfy_delete(pchnl->ntfy_obj); - kfree(pchnl->ntfy_obj); - pchnl->ntfy_obj = NULL; - } - /* Reset channel event: (NOTE: user_event freed in user - * context.). */ - if (pchnl->sync_event) { - sync_reset_event(pchnl->sync_event); - kfree(pchnl->sync_event); - pchnl->sync_event = NULL; - } - /* Free I/O request and I/O completion queues: */ - free_chirp_list(&pchnl->pio_completions); - pchnl->cio_cs = 0; + /* Free I/O request and I/O completion queues: */ + free_chirp_list(&pchnl->pio_completions); + pchnl->cio_cs = 0; - free_chirp_list(&pchnl->pio_requests); - pchnl->cio_reqs = 0; + free_chirp_list(&pchnl->pio_requests); + pchnl->cio_reqs = 0; - free_chirp_list(&pchnl->free_packets_list); + free_chirp_list(&pchnl->free_packets_list); + + /* Release channel object. */ + kfree(pchnl); - /* Release channel object. */ - kfree(pchnl); - pchnl = NULL; - } - DBC_ENSURE(status || !pchnl); return status; } @@ -697,32 +676,22 @@ func_end: int bridge_chnl_get_mgr_info(struct chnl_mgr *hchnl_mgr, u32 ch_id, struct chnl_mgrinfo *mgr_info) { - int status = 0; struct chnl_mgr *chnl_mgr_obj = (struct chnl_mgr *)hchnl_mgr; - if (mgr_info != NULL) { - if (ch_id <= CHNL_MAXCHANNELS) { - if (hchnl_mgr) { - /* Return the requested information: */ - mgr_info->chnl_obj = - chnl_mgr_obj->ap_channel[ch_id]; - mgr_info->open_channels = - chnl_mgr_obj->open_channels; - mgr_info->dw_type = chnl_mgr_obj->dw_type; - /* total # of chnls */ - mgr_info->max_channels = - chnl_mgr_obj->max_channels; - } else { - status = -EFAULT; - } - } else { - status = -ECHRNG; - } - } else { - status = -EFAULT; - } + if (!mgr_info || !hchnl_mgr) + return -EFAULT; - return status; + if (ch_id > CHNL_MAXCHANNELS) + return -ECHRNG; + + /* Return the requested information: */ + mgr_info->chnl_obj = chnl_mgr_obj->ap_channel[ch_id]; + mgr_info->open_channels = chnl_mgr_obj->open_channels; + mgr_info->dw_type = chnl_mgr_obj->dw_type; + /* total # of chnls */ + mgr_info->max_channels = chnl_mgr_obj->max_channels; + + return 0; } /* @@ -772,45 +741,41 @@ int bridge_chnl_open(struct chnl_object **chnl, DBC_REQUIRE(pattrs != NULL); DBC_REQUIRE(hchnl_mgr != NULL); *chnl = NULL; + /* Validate Args: */ - if (pattrs->uio_reqs == 0) { - status = -EINVAL; + if (!pattrs->uio_reqs) + return -EINVAL; + + if (!hchnl_mgr) + return -EFAULT; + + if (ch_id != CHNL_PICKFREE) { + if (ch_id >= chnl_mgr_obj->max_channels) + return -ECHRNG; + if (chnl_mgr_obj->ap_channel[ch_id] != NULL) + return -EALREADY; } else { - if (!hchnl_mgr) { - status = -EFAULT; - } else { - if (ch_id != CHNL_PICKFREE) { - if (ch_id >= chnl_mgr_obj->max_channels) - status = -ECHRNG; - else if (chnl_mgr_obj->ap_channel[ch_id] != - NULL) - status = -EALREADY; - } else { - /* Check for free channel */ - status = - search_free_channel(chnl_mgr_obj, &ch_id); - } - } + /* Check for free channel */ + status = search_free_channel(chnl_mgr_obj, &ch_id); + if (status) + return status; } - if (status) - goto func_end; DBC_ASSERT(ch_id < chnl_mgr_obj->max_channels); + /* Create channel object: */ pchnl = kzalloc(sizeof(struct chnl_object), GFP_KERNEL); - if (!pchnl) { - status = -ENOMEM; - goto func_end; - } + if (!pchnl) + return -ENOMEM; + /* Protect queues from io_dpc: */ pchnl->dw_state = CHNL_STATECANCEL; + /* Allocate initial IOR and IOC queues: */ status = create_chirp_list(&pchnl->free_packets_list, pattrs->uio_reqs); - if (status) { - kfree(pchnl); - goto func_end; - } + if (status) + goto out_err; INIT_LIST_HEAD(&pchnl->pio_requests); INIT_LIST_HEAD(&pchnl->pio_completions); @@ -818,63 +783,61 @@ int bridge_chnl_open(struct chnl_object **chnl, pchnl->chnl_packets = pattrs->uio_reqs; pchnl->cio_cs = 0; pchnl->cio_reqs = 0; + sync_event = kzalloc(sizeof(struct sync_object), GFP_KERNEL); - if (sync_event) - sync_init_event(sync_event); - else + if (!sync_event) { status = -ENOMEM; - - if (!status) { - pchnl->ntfy_obj = kmalloc(sizeof(struct ntfy_object), - GFP_KERNEL); - if (pchnl->ntfy_obj) - ntfy_init(pchnl->ntfy_obj); - else - status = -ENOMEM; + goto out_err; } + sync_init_event(sync_event); - if (!status) { - /* Initialize CHNL object fields: */ - pchnl->chnl_mgr_obj = chnl_mgr_obj; - pchnl->chnl_id = ch_id; - pchnl->chnl_mode = chnl_mode; - pchnl->user_event = sync_event; - pchnl->sync_event = sync_event; - /* Get the process handle */ - pchnl->process = current->tgid; - pchnl->pcb_arg = 0; - pchnl->bytes_moved = 0; - /* Default to proc-copy */ - pchnl->chnl_type = CHNL_PCPY; - } + pchnl->ntfy_obj = kmalloc(sizeof(struct ntfy_object), GFP_KERNEL); + if (!pchnl->ntfy_obj) { + status = -ENOMEM; + goto out_err; + } + ntfy_init(pchnl->ntfy_obj); + + /* Initialize CHNL object fields: */ + pchnl->chnl_mgr_obj = chnl_mgr_obj; + pchnl->chnl_id = ch_id; + pchnl->chnl_mode = chnl_mode; + pchnl->user_event = sync_event; + pchnl->sync_event = sync_event; + /* Get the process handle */ + pchnl->process = current->tgid; + pchnl->pcb_arg = 0; + pchnl->bytes_moved = 0; + /* Default to proc-copy */ + pchnl->chnl_type = CHNL_PCPY; + + /* Insert channel object in channel manager: */ + chnl_mgr_obj->ap_channel[pchnl->chnl_id] = pchnl; + spin_lock_bh(&chnl_mgr_obj->chnl_mgr_lock); + chnl_mgr_obj->open_channels++; + spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock); + /* Return result... */ + pchnl->dw_state = CHNL_STATEREADY; + *chnl = pchnl; - if (status) { - /* Free memory */ - free_chirp_list(&pchnl->pio_completions); - pchnl->cio_cs = 0; - free_chirp_list(&pchnl->pio_requests); - free_chirp_list(&pchnl->free_packets_list); + return status; + +out_err: + /* Free memory */ + free_chirp_list(&pchnl->pio_completions); + free_chirp_list(&pchnl->pio_requests); + free_chirp_list(&pchnl->free_packets_list); + + if (sync_event) kfree(sync_event); - sync_event = NULL; - if (pchnl->ntfy_obj) { - ntfy_delete(pchnl->ntfy_obj); - kfree(pchnl->ntfy_obj); - pchnl->ntfy_obj = NULL; - } - kfree(pchnl); - } else { - /* Insert channel object in channel manager: */ - chnl_mgr_obj->ap_channel[pchnl->chnl_id] = pchnl; - spin_lock_bh(&chnl_mgr_obj->chnl_mgr_lock); - chnl_mgr_obj->open_channels++; - spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock); - /* Return result... */ - pchnl->dw_state = CHNL_STATEREADY; - *chnl = pchnl; + if (pchnl->ntfy_obj) { + ntfy_delete(pchnl->ntfy_obj); + kfree(pchnl->ntfy_obj); + pchnl->ntfy_obj = NULL; } -func_end: - DBC_ENSURE((!status && pchnl) || (*chnl == NULL)); + kfree(pchnl); + return status; } diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 2a48f3db0e2d..042a46507544 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -1195,29 +1195,29 @@ static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr) input_empty = msg_ctr_obj->buf_empty; num_msgs = msg_ctr_obj->size; if (input_empty) - goto func_end; + return; msg_input = pio_mgr->msg_input; for (i = 0; i < num_msgs; i++) { /* Read the next message */ addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.dw_cmd); msg.msg.dw_cmd = - read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr); + read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr); addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.dw_arg1); msg.msg.dw_arg1 = - read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr); + read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr); addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.dw_arg2); msg.msg.dw_arg2 = - read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr); + read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr); addr = (u32) &(((struct msg_dspmsg *)msg_input)->msgq_id); msg.msgq_id = - read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr); + read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr); msg_input += sizeof(struct msg_dspmsg); /* Determine which queue to put the message in */ dev_dbg(bridge, "input msg: dw_cmd=0x%x dw_arg1=0x%x " - "dw_arg2=0x%x msgq_id=0x%x\n", msg.msg.dw_cmd, - msg.msg.dw_arg1, msg.msg.dw_arg2, msg.msgq_id); + "dw_arg2=0x%x msgq_id=0x%x\n", msg.msg.dw_cmd, + msg.msg.dw_arg1, msg.msg.dw_arg2, msg.msgq_id); /* * Interrupt may occur before shared memory and message * input locations have been set up. If all nodes were @@ -1225,48 +1225,43 @@ static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr) */ list_for_each_entry(msg_queue_obj, &hmsg_mgr->queue_list, list_elem) { - if (msg.msgq_id == msg_queue_obj->msgq_id) { - /* Found it */ - if (msg.msg.dw_cmd == RMS_EXITACK) { - /* - * Call the node exit notification. - * The exit message does not get - * queued. - */ - (*hmsg_mgr->on_exit) ((void *) - msg_queue_obj->arg, - msg.msg.dw_arg1); - break; - } + if (msg.msgq_id != msg_queue_obj->msgq_id) + continue; + /* Found it */ + if (msg.msg.dw_cmd == RMS_EXITACK) { /* - * Not an exit acknowledgement, queue - * the message. + * Call the node exit notification. + * The exit message does not get + * queued. */ - if (!list_empty(&msg_queue_obj-> - msg_free_list)) { - pmsg = list_first_entry( - &msg_queue_obj->msg_free_list, - struct msg_frame, list_elem); - list_del(&pmsg->list_elem); - pmsg->msg_data = msg; - list_add_tail(&pmsg->list_elem, - &msg_queue_obj->msg_used_list); - ntfy_notify - (msg_queue_obj->ntfy_obj, - DSP_NODEMESSAGEREADY); - sync_set_event - (msg_queue_obj->sync_event); - } else { - /* - * No free frame to copy the - * message into. - */ - pr_err("%s: no free msg frames," - " discarding msg\n", - __func__); - } + (*hmsg_mgr->on_exit)(msg_queue_obj->arg, + msg.msg.dw_arg1); break; } + /* + * Not an exit acknowledgement, queue + * the message. + */ + if (list_empty(&msg_queue_obj->msg_free_list)) { + /* + * No free frame to copy the + * message into. + */ + pr_err("%s: no free msg frames," + " discarding msg\n", + __func__); + break; + } + + pmsg = list_first_entry(&msg_queue_obj->msg_free_list, + struct msg_frame, list_elem); + list_del(&pmsg->list_elem); + pmsg->msg_data = msg; + list_add_tail(&pmsg->list_elem, + &msg_queue_obj->msg_used_list); + ntfy_notify(msg_queue_obj->ntfy_obj, + DSP_NODEMESSAGEREADY); + sync_set_event(msg_queue_obj->sync_event); } } /* Set the post SWI flag */ @@ -1276,8 +1271,6 @@ static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr) msg_ctr_obj->post_swi = true; sm_interrupt_dsp(pio_mgr->hbridge_context, MBX_PCPY_CLASS); } -func_end: - return; } /* @@ -1408,73 +1401,68 @@ static void output_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr) { u32 num_msgs = 0; u32 i; - u8 *msg_output; + struct msg_dspmsg *msg_output; struct msg_frame *pmsg; struct msg_ctrl *msg_ctr_obj; - u32 output_empty; u32 val; u32 addr; msg_ctr_obj = pio_mgr->msg_output_ctrl; /* Check if output has been cleared */ - output_empty = msg_ctr_obj->buf_empty; - if (output_empty) { - num_msgs = (hmsg_mgr->msgs_pending > hmsg_mgr->max_msgs) ? - hmsg_mgr->max_msgs : hmsg_mgr->msgs_pending; - msg_output = pio_mgr->msg_output; - /* Copy num_msgs messages into shared memory */ - for (i = 0; i < num_msgs; i++) { - if (!list_empty(&hmsg_mgr->msg_used_list)) { - pmsg = list_first_entry( - &hmsg_mgr->msg_used_list, - struct msg_frame, list_elem); - list_del(&pmsg->list_elem); - val = (pmsg->msg_data).msgq_id; - addr = (u32) &(((struct msg_dspmsg *) - msg_output)->msgq_id); - write_ext32_bit_dsp_data( - pio_mgr->hbridge_context, addr, val); - val = (pmsg->msg_data).msg.dw_cmd; - addr = (u32) &((((struct msg_dspmsg *) - msg_output)->msg).dw_cmd); - write_ext32_bit_dsp_data( - pio_mgr->hbridge_context, addr, val); - val = (pmsg->msg_data).msg.dw_arg1; - addr = (u32) &((((struct msg_dspmsg *) - msg_output)->msg).dw_arg1); - write_ext32_bit_dsp_data( - pio_mgr->hbridge_context, addr, val); - val = (pmsg->msg_data).msg.dw_arg2; - addr = (u32) &((((struct msg_dspmsg *) - msg_output)->msg).dw_arg2); - write_ext32_bit_dsp_data( - pio_mgr->hbridge_context, addr, val); - msg_output += sizeof(struct msg_dspmsg); - list_add_tail(&pmsg->list_elem, - &hmsg_mgr->msg_free_list); - sync_set_event(hmsg_mgr->sync_event); - } - } + if (!msg_ctr_obj->buf_empty) + return; + + num_msgs = (hmsg_mgr->msgs_pending > hmsg_mgr->max_msgs) ? + hmsg_mgr->max_msgs : hmsg_mgr->msgs_pending; + msg_output = (struct msg_dspmsg *) pio_mgr->msg_output; + + /* Copy num_msgs messages into shared memory */ + for (i = 0; i < num_msgs; i++) { + if (list_empty(&hmsg_mgr->msg_used_list)) + continue; + + pmsg = list_first_entry(&hmsg_mgr->msg_used_list, + struct msg_frame, list_elem); + list_del(&pmsg->list_elem); + + val = (pmsg->msg_data).msgq_id; + addr = (u32) &msg_output->msgq_id; + write_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr, val); + + val = (pmsg->msg_data).msg.dw_cmd; + addr = (u32) &msg_output->msg.dw_cmd; + write_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr, val); + + val = (pmsg->msg_data).msg.dw_arg1; + addr = (u32) &msg_output->msg.dw_arg1; + write_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr, val); + + val = (pmsg->msg_data).msg.dw_arg2; + addr = (u32) &msg_output->msg.dw_arg2; + write_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr, val); - if (num_msgs > 0) { - hmsg_mgr->msgs_pending -= num_msgs; + msg_output++; + list_add_tail(&pmsg->list_elem, &hmsg_mgr->msg_free_list); + sync_set_event(hmsg_mgr->sync_event); + } + + if (num_msgs > 0) { + hmsg_mgr->msgs_pending -= num_msgs; #if _CHNL_WORDSIZE == 2 - /* - * Access can be different SM access word size - * (e.g. 16/32 bit words) - */ - msg_ctr_obj->size = (u16) num_msgs; + /* + * Access can be different SM access word size + * (e.g. 16/32 bit words) + */ + msg_ctr_obj->size = (u16) num_msgs; #else - msg_ctr_obj->size = num_msgs; + msg_ctr_obj->size = num_msgs; #endif - msg_ctr_obj->buf_empty = false; - /* Set the post SWI flag */ - msg_ctr_obj->post_swi = true; - /* Tell the DSP we have written the output. */ - sm_interrupt_dsp(pio_mgr->hbridge_context, - MBX_PCPY_CLASS); - } + msg_ctr_obj->buf_empty = false; + /* Set the post SWI flag */ + msg_ctr_obj->post_swi = true; + /* Tell the DSP we have written the output. */ + sm_interrupt_dsp(pio_mgr->hbridge_context, MBX_PCPY_CLASS); } } diff --git a/drivers/staging/tidspbridge/core/msg_sm.c b/drivers/staging/tidspbridge/core/msg_sm.c index de2cb835fbb9..07103f229134 100644 --- a/drivers/staging/tidspbridge/core/msg_sm.c +++ b/drivers/staging/tidspbridge/core/msg_sm.c @@ -55,49 +55,46 @@ int bridge_msg_create(struct msg_mgr **msg_man, struct io_mgr *hio_mgr; int status = 0; - if (!msg_man || !msg_callback || !hdev_obj) { - status = -EFAULT; - goto func_end; - } + if (!msg_man || !msg_callback || !hdev_obj) + return -EFAULT; + dev_get_io_mgr(hdev_obj, &hio_mgr); - if (!hio_mgr) { - status = -EFAULT; - goto func_end; - } + if (!hio_mgr) + return -EFAULT; + *msg_man = NULL; /* Allocate msg_ctrl manager object */ msg_mgr_obj = kzalloc(sizeof(struct msg_mgr), GFP_KERNEL); + if (!msg_mgr_obj) + return -ENOMEM; - if (msg_mgr_obj) { - msg_mgr_obj->on_exit = msg_callback; - msg_mgr_obj->hio_mgr = hio_mgr; - /* List of MSG_QUEUEs */ - INIT_LIST_HEAD(&msg_mgr_obj->queue_list); - /* Queues of message frames for messages to the DSP. Message - * frames will only be added to the free queue when a - * msg_queue object is created. */ - INIT_LIST_HEAD(&msg_mgr_obj->msg_free_list); - INIT_LIST_HEAD(&msg_mgr_obj->msg_used_list); - spin_lock_init(&msg_mgr_obj->msg_mgr_lock); - - /* Create an event to be used by bridge_msg_put() in waiting - * for an available free frame from the message manager. */ - msg_mgr_obj->sync_event = - kzalloc(sizeof(struct sync_object), GFP_KERNEL); - if (!msg_mgr_obj->sync_event) - status = -ENOMEM; - else - sync_init_event(msg_mgr_obj->sync_event); - - if (!status) - *msg_man = msg_mgr_obj; - else - delete_msg_mgr(msg_mgr_obj); - - } else { - status = -ENOMEM; + msg_mgr_obj->on_exit = msg_callback; + msg_mgr_obj->hio_mgr = hio_mgr; + /* List of MSG_QUEUEs */ + INIT_LIST_HEAD(&msg_mgr_obj->queue_list); + /* + * Queues of message frames for messages to the DSP. Message + * frames will only be added to the free queue when a + * msg_queue object is created. + */ + INIT_LIST_HEAD(&msg_mgr_obj->msg_free_list); + INIT_LIST_HEAD(&msg_mgr_obj->msg_used_list); + spin_lock_init(&msg_mgr_obj->msg_mgr_lock); + + /* + * Create an event to be used by bridge_msg_put() in waiting + * for an available free frame from the message manager. + */ + msg_mgr_obj->sync_event = + kzalloc(sizeof(struct sync_object), GFP_KERNEL); + if (!msg_mgr_obj->sync_event) { + kfree(msg_mgr_obj); + return -ENOMEM; } -func_end: + sync_init_event(msg_mgr_obj->sync_event); + + *msg_man = msg_mgr_obj; + return status; } @@ -106,8 +103,7 @@ func_end: * Create a msg_queue for sending/receiving messages to/from a node * on the DSP. */ -int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr, - struct msg_queue **msgq, +int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr, struct msg_queue **msgq, u32 msgq_id, u32 max_msgs, void *arg) { u32 i; @@ -115,18 +111,15 @@ int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr, struct msg_queue *msg_q; int status = 0; - if (!hmsg_mgr || msgq == NULL) { - status = -EFAULT; - goto func_end; - } + if (!hmsg_mgr || msgq == NULL) + return -EFAULT; *msgq = NULL; /* Allocate msg_queue object */ msg_q = kzalloc(sizeof(struct msg_queue), GFP_KERNEL); - if (!msg_q) { - status = -ENOMEM; - goto func_end; - } + if (!msg_q) + return -ENOMEM; + msg_q->max_msgs = max_msgs; msg_q->hmsg_mgr = hmsg_mgr; msg_q->arg = arg; /* Node handle */ @@ -137,78 +130,68 @@ int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr, /* Create event that will be signalled when a message from * the DSP is available. */ - if (!status) { - msg_q->sync_event = kzalloc(sizeof(struct sync_object), - GFP_KERNEL); - if (msg_q->sync_event) - sync_init_event(msg_q->sync_event); - else - status = -ENOMEM; + msg_q->sync_event = kzalloc(sizeof(struct sync_object), GFP_KERNEL); + if (!msg_q->sync_event) { + status = -ENOMEM; + goto out_err; + } + sync_init_event(msg_q->sync_event); /* Create a notification list for message ready notification. */ - if (!status) { - msg_q->ntfy_obj = kmalloc(sizeof(struct ntfy_object), - GFP_KERNEL); - if (msg_q->ntfy_obj) - ntfy_init(msg_q->ntfy_obj); - else - status = -ENOMEM; + msg_q->ntfy_obj = kmalloc(sizeof(struct ntfy_object), GFP_KERNEL); + if (!msg_q->ntfy_obj) { + status = -ENOMEM; + goto out_err; } + ntfy_init(msg_q->ntfy_obj); /* Create events that will be used to synchronize cleanup * when the object is deleted. sync_done will be set to * unblock threads in MSG_Put() or MSG_Get(). sync_done_ack * will be set by the unblocked thread to signal that it * is unblocked and will no longer reference the object. */ - if (!status) { - msg_q->sync_done = kzalloc(sizeof(struct sync_object), - GFP_KERNEL); - if (msg_q->sync_done) - sync_init_event(msg_q->sync_done); - else - status = -ENOMEM; + msg_q->sync_done = kzalloc(sizeof(struct sync_object), GFP_KERNEL); + if (!msg_q->sync_done) { + status = -ENOMEM; + goto out_err; } + sync_init_event(msg_q->sync_done); - if (!status) { - msg_q->sync_done_ack = kzalloc(sizeof(struct sync_object), - GFP_KERNEL); - if (msg_q->sync_done_ack) - sync_init_event(msg_q->sync_done_ack); - else - status = -ENOMEM; + msg_q->sync_done_ack = kzalloc(sizeof(struct sync_object), GFP_KERNEL); + if (!msg_q->sync_done_ack) { + status = -ENOMEM; + goto out_err; } + sync_init_event(msg_q->sync_done_ack); - if (!status) { - /* Enter critical section */ - spin_lock_bh(&hmsg_mgr->msg_mgr_lock); - /* Initialize message frames and put in appropriate queues */ - for (i = 0; i < max_msgs && !status; i++) { - status = add_new_msg(&hmsg_mgr->msg_free_list); - if (!status) { - num_allocated++; - status = add_new_msg(&msg_q->msg_free_list); - } - } - if (status) { - /* Stay inside CS to prevent others from taking any - * of the newly allocated message frames. */ - delete_msg_queue(msg_q, num_allocated); - } else { - list_add_tail(&msg_q->list_elem, - &hmsg_mgr->queue_list); - *msgq = msg_q; - /* Signal that free frames are now available */ - if (!list_empty(&hmsg_mgr->msg_free_list)) - sync_set_event(hmsg_mgr->sync_event); - + /* Enter critical section */ + spin_lock_bh(&hmsg_mgr->msg_mgr_lock); + /* Initialize message frames and put in appropriate queues */ + for (i = 0; i < max_msgs && !status; i++) { + status = add_new_msg(&hmsg_mgr->msg_free_list); + if (!status) { + num_allocated++; + status = add_new_msg(&msg_q->msg_free_list); } - /* Exit critical section */ + } + if (status) { spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); - } else { - delete_msg_queue(msg_q, 0); + goto out_err; } -func_end: + + list_add_tail(&msg_q->list_elem, &hmsg_mgr->queue_list); + *msgq = msg_q; + /* Signal that free frames are now available */ + if (!list_empty(&hmsg_mgr->msg_free_list)) + sync_set_event(hmsg_mgr->sync_event); + + /* Exit critical section */ + spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); + + return 0; +out_err: + delete_msg_queue(msg_q, num_allocated); return status; } @@ -232,7 +215,7 @@ void bridge_msg_delete_queue(struct msg_queue *msg_queue_obj) u32 io_msg_pend; if (!msg_queue_obj || !msg_queue_obj->hmsg_mgr) - goto func_end; + return; hmsg_mgr = msg_queue_obj->hmsg_mgr; msg_queue_obj->done = true; @@ -252,10 +235,7 @@ void bridge_msg_delete_queue(struct msg_queue *msg_queue_obj) delete_msg_queue(msg_queue_obj, msg_queue_obj->max_msgs); if (list_empty(&hmsg_mgr->msg_free_list)) sync_reset_event(hmsg_mgr->sync_event); - spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); -func_end: - return; } /* @@ -267,19 +247,15 @@ int bridge_msg_get(struct msg_queue *msg_queue_obj, { struct msg_frame *msg_frame_obj; struct msg_mgr *hmsg_mgr; - bool got_msg = false; struct sync_object *syncs[2]; u32 index; int status = 0; - if (!msg_queue_obj || pmsg == NULL) { - status = -ENOMEM; - goto func_end; - } + if (!msg_queue_obj || pmsg == NULL) + return -ENOMEM; hmsg_mgr = msg_queue_obj->hmsg_mgr; - /* Enter critical section */ spin_lock_bh(&hmsg_mgr->msg_mgr_lock); /* If a message is already there, get it */ if (!list_empty(&msg_queue_obj->msg_used_list)) { @@ -291,59 +267,54 @@ int bridge_msg_get(struct msg_queue *msg_queue_obj, &msg_queue_obj->msg_free_list); if (list_empty(&msg_queue_obj->msg_used_list)) sync_reset_event(msg_queue_obj->sync_event); + spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); + return 0; + } - got_msg = true; - } else { - if (msg_queue_obj->done) - status = -EPERM; - else - msg_queue_obj->io_msg_pend++; - + if (msg_queue_obj->done) { + spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); + return -EPERM; } - /* Exit critical section */ + msg_queue_obj->io_msg_pend++; spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); - if (!status && !got_msg) { - /* Wait til message is available, timeout, or done. We don't - * have to schedule the DPC, since the DSP will send messages - * when they are available. */ - syncs[0] = msg_queue_obj->sync_event; - syncs[1] = msg_queue_obj->sync_done; - status = sync_wait_on_multiple_events(syncs, 2, utimeout, - &index); - /* Enter critical section */ - spin_lock_bh(&hmsg_mgr->msg_mgr_lock); - if (msg_queue_obj->done) { - msg_queue_obj->io_msg_pend--; - /* Exit critical section */ - spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); - /* Signal that we're not going to access msg_queue_obj - * anymore, so it can be deleted. */ - (void)sync_set_event(msg_queue_obj->sync_done_ack); - status = -EPERM; - } else { - if (!status && !list_empty(&msg_queue_obj-> - msg_used_list)) { - /* Get msg from used list */ - msg_frame_obj = list_first_entry( - &msg_queue_obj->msg_used_list, - struct msg_frame, list_elem); - list_del(&msg_frame_obj->list_elem); - /* Copy message into pmsg and put frame on the - * free list */ - *pmsg = msg_frame_obj->msg_data.msg; - list_add_tail(&msg_frame_obj->list_elem, - &msg_queue_obj->msg_free_list); - } - msg_queue_obj->io_msg_pend--; - /* Reset the event if there are still queued messages */ - if (!list_empty(&msg_queue_obj->msg_used_list)) - sync_set_event(msg_queue_obj->sync_event); - - /* Exit critical section */ - spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); - } + + /* + * Wait til message is available, timeout, or done. We don't + * have to schedule the DPC, since the DSP will send messages + * when they are available. + */ + syncs[0] = msg_queue_obj->sync_event; + syncs[1] = msg_queue_obj->sync_done; + status = sync_wait_on_multiple_events(syncs, 2, utimeout, &index); + + spin_lock_bh(&hmsg_mgr->msg_mgr_lock); + if (msg_queue_obj->done) { + msg_queue_obj->io_msg_pend--; + spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); + /* + * Signal that we're not going to access msg_queue_obj + * anymore, so it can be deleted. + */ + sync_set_event(msg_queue_obj->sync_done_ack); + return -EPERM; } -func_end: + if (!status && !list_empty(&msg_queue_obj->msg_used_list)) { + /* Get msg from used list */ + msg_frame_obj = list_first_entry(&msg_queue_obj->msg_used_list, + struct msg_frame, list_elem); + list_del(&msg_frame_obj->list_elem); + /* Copy message into pmsg and put frame on the free list */ + *pmsg = msg_frame_obj->msg_data.msg; + list_add_tail(&msg_frame_obj->list_elem, + &msg_queue_obj->msg_free_list); + } + msg_queue_obj->io_msg_pend--; + /* Reset the event if there are still queued messages */ + if (!list_empty(&msg_queue_obj->msg_used_list)) + sync_set_event(msg_queue_obj->sync_event); + + spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); + return status; } @@ -356,15 +327,13 @@ int bridge_msg_put(struct msg_queue *msg_queue_obj, { struct msg_frame *msg_frame_obj; struct msg_mgr *hmsg_mgr; - bool put_msg = false; struct sync_object *syncs[2]; u32 index; - int status = 0; + int status; + + if (!msg_queue_obj || !pmsg || !msg_queue_obj->hmsg_mgr) + return -EFAULT; - if (!msg_queue_obj || !pmsg || !msg_queue_obj->hmsg_mgr) { - status = -ENOMEM; - goto func_end; - } hmsg_mgr = msg_queue_obj->hmsg_mgr; spin_lock_bh(&hmsg_mgr->msg_mgr_lock); @@ -380,7 +349,7 @@ int bridge_msg_put(struct msg_queue *msg_queue_obj, list_add_tail(&msg_frame_obj->list_elem, &hmsg_mgr->msg_used_list); hmsg_mgr->msgs_pending++; - put_msg = true; + if (list_empty(&hmsg_mgr->msg_free_list)) sync_reset_event(hmsg_mgr->sync_event); @@ -388,70 +357,70 @@ int bridge_msg_put(struct msg_queue *msg_queue_obj, spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); /* Schedule a DPC, to do the actual data transfer: */ iosm_schedule(hmsg_mgr->hio_mgr); - } else { - if (msg_queue_obj->done) - status = -EPERM; - else - msg_queue_obj->io_msg_pend++; + return 0; + } + if (msg_queue_obj->done) { spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); + return -EPERM; } - if (!status && !put_msg) { - /* Wait til a free message frame is available, timeout, - * or done */ - syncs[0] = hmsg_mgr->sync_event; - syncs[1] = msg_queue_obj->sync_done; - status = sync_wait_on_multiple_events(syncs, 2, utimeout, - &index); - if (status) - goto func_end; - /* Enter critical section */ - spin_lock_bh(&hmsg_mgr->msg_mgr_lock); - if (msg_queue_obj->done) { - msg_queue_obj->io_msg_pend--; - /* Exit critical section */ - spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); - /* Signal that we're not going to access msg_queue_obj - * anymore, so it can be deleted. */ - (void)sync_set_event(msg_queue_obj->sync_done_ack); - status = -EPERM; - } else { - if (list_empty(&hmsg_mgr->msg_free_list)) { - status = -EFAULT; - goto func_cont; - } - /* Get msg from free list */ - msg_frame_obj = list_first_entry( - &hmsg_mgr->msg_free_list, - struct msg_frame, list_elem); - list_del(&msg_frame_obj->list_elem); - /* - * Copy message into pmsg and put frame on the - * used list. - */ - msg_frame_obj->msg_data.msg = *pmsg; - msg_frame_obj->msg_data.msgq_id = - msg_queue_obj->msgq_id; - list_add_tail(&msg_frame_obj->list_elem, - &hmsg_mgr->msg_used_list); - hmsg_mgr->msgs_pending++; - /* - * Schedule a DPC, to do the actual - * data transfer. - */ - iosm_schedule(hmsg_mgr->hio_mgr); - - msg_queue_obj->io_msg_pend--; - /* Reset event if there are still frames available */ - if (!list_empty(&hmsg_mgr->msg_free_list)) - sync_set_event(hmsg_mgr->sync_event); -func_cont: - /* Exit critical section */ - spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); - } + msg_queue_obj->io_msg_pend++; + + spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); + + /* Wait til a free message frame is available, timeout, or done */ + syncs[0] = hmsg_mgr->sync_event; + syncs[1] = msg_queue_obj->sync_done; + status = sync_wait_on_multiple_events(syncs, 2, utimeout, &index); + if (status) + return status; + + /* Enter critical section */ + spin_lock_bh(&hmsg_mgr->msg_mgr_lock); + if (msg_queue_obj->done) { + msg_queue_obj->io_msg_pend--; + /* Exit critical section */ + spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); + /* + * Signal that we're not going to access msg_queue_obj + * anymore, so it can be deleted. + */ + sync_set_event(msg_queue_obj->sync_done_ack); + return -EPERM; } -func_end: - return status; + + if (list_empty(&hmsg_mgr->msg_free_list)) { + spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); + return -EFAULT; + } + + /* Get msg from free list */ + msg_frame_obj = list_first_entry(&hmsg_mgr->msg_free_list, + struct msg_frame, list_elem); + /* + * Copy message into pmsg and put frame on the + * used list. + */ + list_del(&msg_frame_obj->list_elem); + msg_frame_obj->msg_data.msg = *pmsg; + msg_frame_obj->msg_data.msgq_id = msg_queue_obj->msgq_id; + list_add_tail(&msg_frame_obj->list_elem, &hmsg_mgr->msg_used_list); + hmsg_mgr->msgs_pending++; + /* + * Schedule a DPC, to do the actual + * data transfer. + */ + iosm_schedule(hmsg_mgr->hio_mgr); + + msg_queue_obj->io_msg_pend--; + /* Reset event if there are still frames available */ + if (!list_empty(&hmsg_mgr->msg_free_list)) + sync_set_event(hmsg_mgr->sync_event); + + /* Exit critical section */ + spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); + + return 0; } /* @@ -518,16 +487,14 @@ void bridge_msg_set_queue_id(struct msg_queue *msg_queue_obj, u32 msgq_id) static int add_new_msg(struct list_head *msg_list) { struct msg_frame *pmsg; - int status = 0; pmsg = kzalloc(sizeof(struct msg_frame), GFP_ATOMIC); - if (pmsg != NULL) { - list_add_tail(&pmsg->list_elem, msg_list); - } else { - status = -ENOMEM; - } + if (!pmsg) + return -ENOMEM; - return status; + list_add_tail(&pmsg->list_elem, msg_list); + + return 0; } /* @@ -536,17 +503,13 @@ static int add_new_msg(struct list_head *msg_list) static void delete_msg_mgr(struct msg_mgr *hmsg_mgr) { if (!hmsg_mgr) - goto func_end; + return; /* FIXME: free elements from queue_list? */ free_msg_list(&hmsg_mgr->msg_free_list); free_msg_list(&hmsg_mgr->msg_used_list); - kfree(hmsg_mgr->sync_event); - kfree(hmsg_mgr); -func_end: - return; } /* @@ -559,7 +522,7 @@ static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp) u32 i; if (!msg_queue_obj || !msg_queue_obj->hmsg_mgr) - goto func_end; + return; hmsg_mgr = msg_queue_obj->hmsg_mgr; @@ -586,9 +549,6 @@ static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp) kfree(msg_queue_obj->sync_done_ack); kfree(msg_queue_obj); -func_end: - return; - } /* @@ -599,13 +559,10 @@ static void free_msg_list(struct list_head *msg_list) struct msg_frame *pmsg, *tmp; if (!msg_list) - goto func_end; + return; list_for_each_entry_safe(pmsg, tmp, msg_list, list_elem) { list_del(&pmsg->list_elem); kfree(pmsg); } - -func_end: - return; } -- cgit v1.2.3 From ba44df6f8875c0e56d5923d742face59d81b8dc7 Mon Sep 17 00:00:00 2001 From: Ionut Nicu Date: Sun, 21 Nov 2010 10:46:29 +0000 Subject: staging: tidspbridge: pmgr code cleanup Reorganized some code in the pmgr module to increase its readability. No functional changes were done. Signed-off-by: Ionut Nicu Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/pmgr/cmm.c | 357 +++++++++++++++------------------ drivers/staging/tidspbridge/pmgr/dev.c | 22 +- 2 files changed, 168 insertions(+), 211 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/pmgr/cmm.c b/drivers/staging/tidspbridge/pmgr/cmm.c index d7ca2a44250b..babe66f759ca 100644 --- a/drivers/staging/tidspbridge/pmgr/cmm.c +++ b/drivers/staging/tidspbridge/pmgr/cmm.c @@ -250,26 +250,23 @@ int cmm_create(struct cmm_object **ph_cmm_mgr, *ph_cmm_mgr = NULL; /* create, zero, and tag a cmm mgr object */ cmm_obj = kzalloc(sizeof(struct cmm_object), GFP_KERNEL); - if (cmm_obj != NULL) { - if (mgr_attrts == NULL) - mgr_attrts = &cmm_dfltmgrattrs; /* set defaults */ - - /* 4 bytes minimum */ - DBC_ASSERT(mgr_attrts->ul_min_block_size >= 4); - /* save away smallest block allocation for this cmm mgr */ - cmm_obj->ul_min_block_size = mgr_attrts->ul_min_block_size; - cmm_obj->dw_page_size = PAGE_SIZE; - - /* Note: DSP SM seg table(aDSPSMSegTab[]) zero'd by - * MEM_ALLOC_OBJECT */ - - /* create node free list */ - INIT_LIST_HEAD(&cmm_obj->node_free_list); - mutex_init(&cmm_obj->cmm_lock); - *ph_cmm_mgr = cmm_obj; - } else { - status = -ENOMEM; - } + if (!cmm_obj) + return -ENOMEM; + + if (mgr_attrts == NULL) + mgr_attrts = &cmm_dfltmgrattrs; /* set defaults */ + + /* 4 bytes minimum */ + DBC_ASSERT(mgr_attrts->ul_min_block_size >= 4); + /* save away smallest block allocation for this cmm mgr */ + cmm_obj->ul_min_block_size = mgr_attrts->ul_min_block_size; + cmm_obj->dw_page_size = PAGE_SIZE; + + /* create node free list */ + INIT_LIST_HEAD(&cmm_obj->node_free_list); + mutex_init(&cmm_obj->cmm_lock); + *ph_cmm_mgr = cmm_obj; + return status; } @@ -346,13 +343,12 @@ void cmm_exit(void) * Purpose: * Free the given buffer. */ -int cmm_free_buf(struct cmm_object *hcmm_mgr, void *buf_pa, - u32 ul_seg_id) +int cmm_free_buf(struct cmm_object *hcmm_mgr, void *buf_pa, u32 ul_seg_id) { struct cmm_object *cmm_mgr_obj = (struct cmm_object *)hcmm_mgr; int status = -EFAULT; struct cmm_mnode *curr, *tmp; - struct cmm_allocator *allocator = NULL; + struct cmm_allocator *allocator; struct cmm_attrs *pattrs; DBC_REQUIRE(refs > 0); @@ -366,21 +362,22 @@ int cmm_free_buf(struct cmm_object *hcmm_mgr, void *buf_pa, status = -EFAULT; return status; } - /* get the allocator for this segment id */ + allocator = get_allocator(cmm_mgr_obj, ul_seg_id); - if (allocator != NULL) { - mutex_lock(&cmm_mgr_obj->cmm_lock); - list_for_each_entry_safe(curr, tmp, &allocator->in_use_list, - link) { - if (curr->dw_pa == (u32) buf_pa) { - list_del(&curr->link); - add_to_free_list(allocator, curr); - status = 0; - break; - } + if (!allocator) + return status; + + mutex_lock(&cmm_mgr_obj->cmm_lock); + list_for_each_entry_safe(curr, tmp, &allocator->in_use_list, link) { + if (curr->dw_pa == (u32) buf_pa) { + list_del(&curr->link); + add_to_free_list(allocator, curr); + status = 0; + break; } - mutex_unlock(&cmm_mgr_obj->cmm_lock); } + mutex_unlock(&cmm_mgr_obj->cmm_lock); + return status; } @@ -438,31 +435,30 @@ int cmm_get_info(struct cmm_object *hcmm_mgr, for (ul_seg = 1; ul_seg <= CMM_MAXGPPSEGS; ul_seg++) { /* get the allocator object for this segment id */ altr = get_allocator(cmm_mgr_obj, ul_seg); - if (altr != NULL) { - cmm_info_obj->ul_num_gppsm_segs++; - cmm_info_obj->seg_info[ul_seg - 1].dw_seg_base_pa = - altr->shm_base - altr->ul_dsp_size; - cmm_info_obj->seg_info[ul_seg - 1].ul_total_seg_size = - altr->ul_dsp_size + altr->ul_sm_size; - cmm_info_obj->seg_info[ul_seg - 1].dw_gpp_base_pa = - altr->shm_base; - cmm_info_obj->seg_info[ul_seg - 1].ul_gpp_size = - altr->ul_sm_size; - cmm_info_obj->seg_info[ul_seg - 1].dw_dsp_base_va = - altr->dw_dsp_base; - cmm_info_obj->seg_info[ul_seg - 1].ul_dsp_size = - altr->ul_dsp_size; - cmm_info_obj->seg_info[ul_seg - 1].dw_seg_base_va = - altr->dw_vm_base - altr->ul_dsp_size; - cmm_info_obj->seg_info[ul_seg - 1].ul_in_use_cnt = 0; - /* Count inUse blocks */ - list_for_each_entry(curr, &altr->in_use_list, link) { - cmm_info_obj->ul_total_in_use_cnt++; - cmm_info_obj->seg_info[ul_seg - - 1].ul_in_use_cnt++; - } + if (!altr) + continue; + cmm_info_obj->ul_num_gppsm_segs++; + cmm_info_obj->seg_info[ul_seg - 1].dw_seg_base_pa = + altr->shm_base - altr->ul_dsp_size; + cmm_info_obj->seg_info[ul_seg - 1].ul_total_seg_size = + altr->ul_dsp_size + altr->ul_sm_size; + cmm_info_obj->seg_info[ul_seg - 1].dw_gpp_base_pa = + altr->shm_base; + cmm_info_obj->seg_info[ul_seg - 1].ul_gpp_size = + altr->ul_sm_size; + cmm_info_obj->seg_info[ul_seg - 1].dw_dsp_base_va = + altr->dw_dsp_base; + cmm_info_obj->seg_info[ul_seg - 1].ul_dsp_size = + altr->ul_dsp_size; + cmm_info_obj->seg_info[ul_seg - 1].dw_seg_base_va = + altr->dw_vm_base - altr->ul_dsp_size; + cmm_info_obj->seg_info[ul_seg - 1].ul_in_use_cnt = 0; + + list_for_each_entry(curr, &altr->in_use_list, link) { + cmm_info_obj->ul_total_in_use_cnt++; + cmm_info_obj->seg_info[ul_seg - 1].ul_in_use_cnt++; } - } /* end for */ + } mutex_unlock(&cmm_mgr_obj->cmm_lock); return status; } @@ -508,23 +504,25 @@ int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr, DBC_REQUIRE(dw_gpp_base_pa != 0); DBC_REQUIRE(gpp_base_va != 0); DBC_REQUIRE((c_factor <= CMM_ADDTODSPPA) && - (c_factor >= CMM_SUBFROMDSPPA)); + (c_factor >= CMM_SUBFROMDSPPA)); + dev_dbg(bridge, "%s: dw_gpp_base_pa %x ul_size %x dsp_addr_offset %x " - "dw_dsp_base %x ul_dsp_size %x gpp_base_va %x\n", __func__, - dw_gpp_base_pa, ul_size, dsp_addr_offset, dw_dsp_base, - ul_dsp_size, gpp_base_va); - if (!hcmm_mgr) { - status = -EFAULT; - return status; - } + "dw_dsp_base %x ul_dsp_size %x gpp_base_va %x\n", + __func__, dw_gpp_base_pa, ul_size, dsp_addr_offset, + dw_dsp_base, ul_dsp_size, gpp_base_va); + + if (!hcmm_mgr) + return -EFAULT; + /* make sure we have room for another allocator */ mutex_lock(&cmm_mgr_obj->cmm_lock); + slot_seg = get_slot(cmm_mgr_obj); if (slot_seg < 0) { - /* get a slot number */ status = -EPERM; goto func_end; } + /* Check if input ul_size is big enough to alloc at least one block */ if (ul_size < cmm_mgr_obj->ul_min_block_size) { status = -EINVAL; @@ -533,37 +531,35 @@ int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr, /* create, zero, and tag an SM allocator object */ psma = kzalloc(sizeof(struct cmm_allocator), GFP_KERNEL); - if (psma != NULL) { - psma->hcmm_mgr = hcmm_mgr; /* ref to parent */ - psma->shm_base = dw_gpp_base_pa; /* SM Base phys */ - psma->ul_sm_size = ul_size; /* SM segment size in bytes */ - psma->dw_vm_base = gpp_base_va; - psma->dw_dsp_phys_addr_offset = dsp_addr_offset; - psma->c_factor = c_factor; - psma->dw_dsp_base = dw_dsp_base; - psma->ul_dsp_size = ul_dsp_size; - if (psma->dw_vm_base == 0) { - status = -EPERM; - goto func_end; - } - /* return the actual segment identifier */ - *sgmt_id = (u32) slot_seg + 1; - /* create memory free list */ - INIT_LIST_HEAD(&psma->free_list); - - /* create memory in-use list */ - INIT_LIST_HEAD(&psma->in_use_list); - - /* Get a mem node for this hunk-o-memory */ - new_node = get_node(cmm_mgr_obj, dw_gpp_base_pa, - psma->dw_vm_base, ul_size); - /* Place node on the SM allocator's free list */ - if (new_node) { - list_add_tail(&new_node->link, &psma->free_list); - } else { - status = -ENOMEM; - goto func_end; - } + if (!psma) { + status = -ENOMEM; + goto func_end; + } + + psma->hcmm_mgr = hcmm_mgr; /* ref to parent */ + psma->shm_base = dw_gpp_base_pa; /* SM Base phys */ + psma->ul_sm_size = ul_size; /* SM segment size in bytes */ + psma->dw_vm_base = gpp_base_va; + psma->dw_dsp_phys_addr_offset = dsp_addr_offset; + psma->c_factor = c_factor; + psma->dw_dsp_base = dw_dsp_base; + psma->ul_dsp_size = ul_dsp_size; + if (psma->dw_vm_base == 0) { + status = -EPERM; + goto func_end; + } + /* return the actual segment identifier */ + *sgmt_id = (u32) slot_seg + 1; + + INIT_LIST_HEAD(&psma->free_list); + INIT_LIST_HEAD(&psma->in_use_list); + + /* Get a mem node for this hunk-o-memory */ + new_node = get_node(cmm_mgr_obj, dw_gpp_base_pa, + psma->dw_vm_base, ul_size); + /* Place node on the SM allocator's free list */ + if (new_node) { + list_add_tail(&new_node->link, &psma->free_list); } else { status = -ENOMEM; goto func_end; @@ -572,12 +568,11 @@ int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr, cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg] = psma; func_end: - if (status && psma) { - /* Cleanup allocator */ + /* Cleanup allocator */ + if (status && psma) un_register_gppsm_seg(psma); - } - mutex_unlock(&cmm_mgr_obj->cmm_lock); + return status; } @@ -595,36 +590,36 @@ int cmm_un_register_gppsm_seg(struct cmm_object *hcmm_mgr, u32 ul_id = ul_seg_id; DBC_REQUIRE(ul_seg_id > 0); - if (hcmm_mgr) { - if (ul_seg_id == CMM_ALLSEGMENTS) - ul_id = 1; - - if ((ul_id > 0) && (ul_id <= CMM_MAXGPPSEGS)) { - while (ul_id <= CMM_MAXGPPSEGS) { - mutex_lock(&cmm_mgr_obj->cmm_lock); - /* slot = seg_id-1 */ - psma = cmm_mgr_obj->pa_gppsm_seg_tab[ul_id - 1]; - if (psma != NULL) { - un_register_gppsm_seg(psma); - /* Set alctr ptr to NULL for future - * reuse */ - cmm_mgr_obj->pa_gppsm_seg_tab[ul_id - - 1] = NULL; - } else if (ul_seg_id != CMM_ALLSEGMENTS) { - status = -EPERM; - } - mutex_unlock(&cmm_mgr_obj->cmm_lock); - if (ul_seg_id != CMM_ALLSEGMENTS) - break; - - ul_id++; - } /* end while */ - } else { - status = -EINVAL; + if (!hcmm_mgr) + return -EFAULT; + + if (ul_seg_id == CMM_ALLSEGMENTS) + ul_id = 1; + + if ((ul_id <= 0) || (ul_id > CMM_MAXGPPSEGS)) + return -EINVAL; + + /* + * FIXME: CMM_MAXGPPSEGS == 1. why use a while cycle? Seems to me like + * the ul_seg_id is not needed here. It must be always 1. + */ + while (ul_id <= CMM_MAXGPPSEGS) { + mutex_lock(&cmm_mgr_obj->cmm_lock); + /* slot = seg_id-1 */ + psma = cmm_mgr_obj->pa_gppsm_seg_tab[ul_id - 1]; + if (psma != NULL) { + un_register_gppsm_seg(psma); + /* Set alctr ptr to NULL for future reuse */ + cmm_mgr_obj->pa_gppsm_seg_tab[ul_id - 1] = NULL; + } else if (ul_seg_id != CMM_ALLSEGMENTS) { + status = -EPERM; } - } else { - status = -EFAULT; - } + mutex_unlock(&cmm_mgr_obj->cmm_lock); + if (ul_seg_id != CMM_ALLSEGMENTS) + break; + + ul_id++; + } /* end while */ return status; } @@ -690,26 +685,29 @@ static s32 get_slot(struct cmm_object *cmm_mgr_obj) static struct cmm_mnode *get_node(struct cmm_object *cmm_mgr_obj, u32 dw_pa, u32 dw_va, u32 ul_size) { - struct cmm_mnode *pnode = NULL; + struct cmm_mnode *pnode; DBC_REQUIRE(cmm_mgr_obj != NULL); DBC_REQUIRE(dw_pa != 0); DBC_REQUIRE(dw_va != 0); DBC_REQUIRE(ul_size != 0); + /* Check cmm mgr's node freelist */ if (list_empty(&cmm_mgr_obj->node_free_list)) { pnode = kzalloc(sizeof(struct cmm_mnode), GFP_KERNEL); + if (!pnode) + return NULL; } else { /* surely a valid element */ pnode = list_first_entry(&cmm_mgr_obj->node_free_list, struct cmm_mnode, link); - list_del(&pnode->link); - } - if (pnode) { - pnode->dw_pa = dw_pa; /* Physical addr of start of block */ - pnode->dw_va = dw_va; /* Virtual " " */ - pnode->ul_size = ul_size; /* Size of block */ + list_del_init(&pnode->link); } + + pnode->dw_pa = dw_pa; + pnode->dw_va = dw_va; + pnode->ul_size = ul_size; + return pnode; } @@ -740,11 +738,10 @@ static struct cmm_mnode *get_free_block(struct cmm_allocator *allocator, return NULL; list_for_each_entry_safe(node, tmp, &allocator->free_list, link) { - if (usize <= (u32) node->ul_size) { + if (usize <= node->ul_size) { list_del(&node->link); return node; } - } return NULL; @@ -756,59 +753,36 @@ static struct cmm_mnode *get_free_block(struct cmm_allocator *allocator, * Coalesce node into the freelist in ascending size order. */ static void add_to_free_list(struct cmm_allocator *allocator, - struct cmm_mnode *pnode) + struct cmm_mnode *node) { - struct cmm_mnode *node_prev = NULL; - struct cmm_mnode *node_next = NULL; - struct cmm_mnode *mnode_obj; - u32 dw_this_pa; - u32 dw_next_pa; - - if (!pnode) { - pr_err("%s: failed - pnode is NULL\n", __func__); + struct cmm_mnode *curr; + + if (!node) { + pr_err("%s: failed - node is NULL\n", __func__); return; } - dw_this_pa = pnode->dw_pa; - dw_next_pa = NEXT_PA(pnode); - list_for_each_entry(mnode_obj, &allocator->free_list, link) { - if (dw_this_pa == NEXT_PA(mnode_obj)) { - /* found the block ahead of this one */ - node_prev = mnode_obj; - } else if (dw_next_pa == mnode_obj->dw_pa) { - node_next = mnode_obj; + list_for_each_entry(curr, &allocator->free_list, link) { + if (NEXT_PA(curr) == node->dw_pa) { + curr->ul_size += node->ul_size; + delete_node(allocator->hcmm_mgr, node); + return; + } + if (curr->dw_pa == NEXT_PA(node)) { + curr->dw_pa = node->dw_pa; + curr->dw_va = node->dw_va; + curr->ul_size += node->ul_size; + delete_node(allocator->hcmm_mgr, node); + return; } - if ((node_prev != NULL) && (node_next != NULL)) - break; - } - if (node_prev != NULL) { - /* combine with previous block */ - list_del(&node_prev->link); - /* grow node to hold both */ - pnode->ul_size += node_prev->ul_size; - pnode->dw_pa = node_prev->dw_pa; - pnode->dw_va = node_prev->dw_va; - /* place node on mgr nodeFreeList */ - delete_node(allocator->hcmm_mgr, node_prev); - } - if (node_next != NULL) { - /* combine with next block */ - list_del(&node_next->link); - /* grow da node */ - pnode->ul_size += node_next->ul_size; - /* place node on mgr nodeFreeList */ - delete_node(allocator->hcmm_mgr, node_next); } - /* Now, let's add to freelist in increasing size order */ - list_for_each_entry(mnode_obj, &allocator->free_list, link) { - if (pnode->ul_size <= mnode_obj->ul_size) { - /* insert our node before the current traversed node */ - list_add_tail(&pnode->link, &mnode_obj->link); + list_for_each_entry(curr, &allocator->free_list, link) { + if (curr->ul_size >= node->ul_size) { + list_add_tail(&node->link, &curr->link); return; } } - /* add our pnode to the end of the freelist */ - list_add_tail(&pnode->link, &allocator->free_list); + list_add_tail(&node->link, &allocator->free_list); } /* @@ -820,19 +794,10 @@ static void add_to_free_list(struct cmm_allocator *allocator, static struct cmm_allocator *get_allocator(struct cmm_object *cmm_mgr_obj, u32 ul_seg_id) { - struct cmm_allocator *allocator = NULL; - DBC_REQUIRE(cmm_mgr_obj != NULL); DBC_REQUIRE((ul_seg_id > 0) && (ul_seg_id <= CMM_MAXGPPSEGS)); - allocator = cmm_mgr_obj->pa_gppsm_seg_tab[ul_seg_id - 1]; - if (allocator != NULL) { - /* make sure it's for real */ - if (!allocator) { - allocator = NULL; - DBC_ASSERT(false); - } - } - return allocator; + + return cmm_mgr_obj->pa_gppsm_seg_tab[ul_seg_id - 1]; } /* diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c index 6ce3493003c9..b160b0032eb3 100644 --- a/drivers/staging/tidspbridge/pmgr/dev.c +++ b/drivers/staging/tidspbridge/pmgr/dev.c @@ -78,8 +78,8 @@ struct dev_object { struct ldr_module *module_obj; /* Bridge Module handle. */ u32 word_size; /* DSP word size: quick access. */ struct drv_object *hdrv_obj; /* Driver Object */ - struct list_head proc_list; /* List of Processor attached to - * this device */ + /* List of Processors attached to this device */ + struct list_head proc_list; struct node_mgr *hnode_mgr; }; @@ -787,9 +787,8 @@ bool dev_init(void) * Purpose: * Notify all clients of this device of a change in device status. */ -int dev_notify_clients(struct dev_object *hdev_obj, u32 ret) +int dev_notify_clients(struct dev_object *dev_obj, u32 ret) { - struct dev_object *dev_obj = hdev_obj; struct list_head *curr; /* @@ -797,7 +796,7 @@ int dev_notify_clients(struct dev_object *hdev_obj, u32 ret) * at the begining. If not, this can go horribly wrong. */ list_for_each(curr, &dev_obj->proc_list) - proc_notify_clients((void *)curr, (u32) ret); + proc_notify_clients((void *)curr, ret); return 0; } @@ -981,7 +980,6 @@ static int init_cod_mgr(struct dev_object *dev_obj) int dev_insert_proc_object(struct dev_object *hdev_obj, u32 proc_obj, bool *already_attached) { - int status = 0; struct dev_object *dev_obj = (struct dev_object *)hdev_obj; DBC_REQUIRE(refs > 0); @@ -998,9 +996,7 @@ int dev_insert_proc_object(struct dev_object *hdev_obj, */ list_add_tail((struct list_head *)proc_obj, &dev_obj->proc_list); - DBC_ENSURE(!status && !list_empty(&dev_obj->proc_list)); - - return status; + return 0; } /* @@ -1043,14 +1039,10 @@ int dev_remove_proc_object(struct dev_object *hdev_obj, u32 proc_obj) return status; } -int dev_get_dev_type(struct dev_object *device_obj, u8 *dev_type) +int dev_get_dev_type(struct dev_object *dev_obj, u8 *dev_type) { - int status = 0; - struct dev_object *dev_obj = (struct dev_object *)device_obj; - *dev_type = dev_obj->dev_type; - - return status; + return 0; } /* -- cgit v1.2.3 From a994b051b6cb246bb8843b3fbb7dea4185a01399 Mon Sep 17 00:00:00 2001 From: Omar Ramirez Luna Date: Wed, 8 Dec 2010 22:20:23 +0000 Subject: staging: tidspbridge: use the right type for list_is_last Removes the following warning: CC [M] drivers/staging/tidspbridge/rmgr/rmm.o drivers/staging/tidspbridge/rmgr/rmm.c: In function 'rmm_alloc': drivers/staging/tidspbridge/rmgr/rmm.c:147: warning: passing argument 1 of 'list_is_last' from incompatible pointer type include/linux/list.h:170: note: expected 'const struct list_head *' but argument is of type 'struct rmm_ovly_sect *' Signed-off-by: Omar Ramirez Luna Acked-by: Laurent Pinchart Acked-by: Ionut Nicu --- drivers/staging/tidspbridge/rmgr/rmm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/rmgr/rmm.c b/drivers/staging/tidspbridge/rmgr/rmm.c index aae86570035b..5a3f09c4574f 100644 --- a/drivers/staging/tidspbridge/rmgr/rmm.c +++ b/drivers/staging/tidspbridge/rmgr/rmm.c @@ -144,7 +144,7 @@ int rmm_alloc(struct rmm_target_obj *target, u32 segid, u32 size, new_sect->addr = addr; new_sect->size = size; new_sect->page = segid; - if (list_is_last(sect, &target->ovly_list)) + if (list_is_last(§->list_elem, &target->ovly_list)) /* Put new section at the end of the list */ list_add_tail(&new_sect->list_elem, &target->ovly_list); -- cgit v1.2.3 From 57104f0fbe5bb35694eb470530850a71ef2f8063 Mon Sep 17 00:00:00 2001 From: Ionut Nicu Date: Thu, 9 Dec 2010 21:47:37 +0000 Subject: staging: tidspbridge: rmgr/node.c code cleanup Reorganized some code in rmgr/node.c to increase its readability. Most of the changes reduce the code indentation level and simplifiy the code. No functional changes were done. Signed-off-by: Ionut Nicu Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/rmgr/node.c | 605 +++++++++++++++----------------- 1 file changed, 282 insertions(+), 323 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index 62d5c31de41f..b196a7af8414 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -236,9 +236,9 @@ struct node_object { /* Default buffer attributes */ static struct dsp_bufferattr node_dfltbufattrs = { - 0, /* cb_struct */ - 1, /* segment_id */ - 0, /* buf_alignment */ + .cb_struct = 0, + .segment_id = 1, + .buf_alignment = 0, }; static void delete_node(struct node_object *hnode, @@ -284,8 +284,7 @@ enum node_state node_get_state(void *hnode) struct node_object *pnode = (struct node_object *)hnode; if (!pnode) return -1; - else - return pnode->node_state; + return pnode->node_state; } /* @@ -844,6 +843,7 @@ int node_connect(struct node_object *node1, u32 stream1, char *pstr_dev_name = NULL; enum node_type node1_type = NODE_TASK; enum node_type node2_type = NODE_TASK; + enum dsp_strmmode strm_mode; struct node_strmdef *pstrm_def; struct node_strmdef *input = NULL; struct node_strmdef *output = NULL; @@ -857,60 +857,49 @@ int node_connect(struct node_object *node1, u32 stream1, int status = 0; DBC_REQUIRE(refs > 0); - if ((node1 != (struct node_object *)DSP_HGPPNODE && !node1) || - (node2 != (struct node_object *)DSP_HGPPNODE && !node2)) - status = -EFAULT; + if (!node1 || !node2) + return -EFAULT; - if (!status) { - /* The two nodes must be on the same processor */ - if (node1 != (struct node_object *)DSP_HGPPNODE && - node2 != (struct node_object *)DSP_HGPPNODE && - node1->hnode_mgr != node2->hnode_mgr) - status = -EPERM; - /* Cannot connect a node to itself */ - if (node1 == node2) - status = -EPERM; + /* The two nodes must be on the same processor */ + if (node1 != (struct node_object *)DSP_HGPPNODE && + node2 != (struct node_object *)DSP_HGPPNODE && + node1->hnode_mgr != node2->hnode_mgr) + return -EPERM; - } - if (!status) { - /* node_get_type() will return NODE_GPP if hnode = - * DSP_HGPPNODE. */ - node1_type = node_get_type(node1); - node2_type = node_get_type(node2); - /* Check stream indices ranges */ - if ((node1_type != NODE_GPP && node1_type != NODE_DEVICE && - stream1 >= MAX_OUTPUTS(node1)) || (node2_type != NODE_GPP - && node2_type != - NODE_DEVICE - && stream2 >= - MAX_INPUTS(node2))) - status = -EINVAL; - } - if (!status) { - /* - * Only the following types of connections are allowed: - * task/dais socket < == > task/dais socket - * task/dais socket < == > device - * task/dais socket < == > GPP - * - * ie, no message nodes, and at least one task or dais - * socket node. - */ - if (node1_type == NODE_MESSAGE || node2_type == NODE_MESSAGE || - (node1_type != NODE_TASK && node1_type != NODE_DAISSOCKET && - node2_type != NODE_TASK && node2_type != NODE_DAISSOCKET)) - status = -EPERM; - } + /* Cannot connect a node to itself */ + if (node1 == node2) + return -EPERM; + + /* node_get_type() will return NODE_GPP if hnode = DSP_HGPPNODE. */ + node1_type = node_get_type(node1); + node2_type = node_get_type(node2); + /* Check stream indices ranges */ + if ((node1_type != NODE_GPP && node1_type != NODE_DEVICE && + stream1 >= MAX_OUTPUTS(node1)) || + (node2_type != NODE_GPP && node2_type != NODE_DEVICE && + stream2 >= MAX_INPUTS(node2))) + return -EINVAL; + + /* + * Only the following types of connections are allowed: + * task/dais socket < == > task/dais socket + * task/dais socket < == > device + * task/dais socket < == > GPP + * + * ie, no message nodes, and at least one task or dais + * socket node. + */ + if (node1_type == NODE_MESSAGE || node2_type == NODE_MESSAGE || + (node1_type != NODE_TASK && + node1_type != NODE_DAISSOCKET && + node2_type != NODE_TASK && + node2_type != NODE_DAISSOCKET)) + return -EPERM; /* * Check stream mode. Default is STRMMODE_PROCCOPY. */ - if (!status && pattrs) { - if (pattrs->strm_mode != STRMMODE_PROCCOPY) - status = -EPERM; /* illegal stream mode */ - - } - if (status) - goto func_end; + if (pattrs && pattrs->strm_mode != STRMMODE_PROCCOPY) + return -EPERM; /* illegal stream mode */ if (node1_type != NODE_GPP) { hnode_mgr = node1->hnode_mgr; @@ -918,170 +907,145 @@ int node_connect(struct node_object *node1, u32 stream1, DBC_ASSERT(node2 != (struct node_object *)DSP_HGPPNODE); hnode_mgr = node2->hnode_mgr; } + /* Enter critical section */ mutex_lock(&hnode_mgr->node_mgr_lock); /* Nodes must be in the allocated state */ - if (node1_type != NODE_GPP && node_get_state(node1) != NODE_ALLOCATED) + if (node1_type != NODE_GPP && + node_get_state(node1) != NODE_ALLOCATED) { status = -EBADR; + goto out_unlock; + } - if (node2_type != NODE_GPP && node_get_state(node2) != NODE_ALLOCATED) + if (node2_type != NODE_GPP && + node_get_state(node2) != NODE_ALLOCATED) { status = -EBADR; + goto out_unlock; + } - if (!status) { - /* Check that stream indices for task and dais socket nodes - * are not already be used. (Device nodes checked later) */ - if (node1_type == NODE_TASK || node1_type == NODE_DAISSOCKET) { - output = - &(node1->create_args.asa. - task_arg_obj.strm_out_def[stream1]); - if (output->sz_device != NULL) - status = -EISCONN; - + /* + * Check that stream indices for task and dais socket nodes + * are not already be used. (Device nodes checked later) + */ + if (node1_type == NODE_TASK || node1_type == NODE_DAISSOCKET) { + output = &(node1->create_args.asa. + task_arg_obj.strm_out_def[stream1]); + if (output->sz_device) { + status = -EISCONN; + goto out_unlock; } - if (node2_type == NODE_TASK || node2_type == NODE_DAISSOCKET) { - input = - &(node2->create_args.asa. - task_arg_obj.strm_in_def[stream2]); - if (input->sz_device != NULL) - status = -EISCONN; + } + if (node2_type == NODE_TASK || node2_type == NODE_DAISSOCKET) { + input = &(node2->create_args.asa. + task_arg_obj.strm_in_def[stream2]); + if (input->sz_device) { + status = -EISCONN; + goto out_unlock; } + } /* Connecting two task nodes? */ - if (!status && ((node1_type == NODE_TASK || - node1_type == NODE_DAISSOCKET) - && (node2_type == NODE_TASK - || node2_type == NODE_DAISSOCKET))) { + if ((node1_type == NODE_TASK || node1_type == NODE_DAISSOCKET) && + (node2_type == NODE_TASK || + node2_type == NODE_DAISSOCKET)) { /* Find available pipe */ pipe_id = find_first_zero_bit(hnode_mgr->pipe_map, MAXPIPES); if (pipe_id == MAXPIPES) { status = -ECONNREFUSED; - } else { - set_bit(pipe_id, hnode_mgr->pipe_map); - node1->outputs[stream1].type = NODECONNECT; - node2->inputs[stream2].type = NODECONNECT; - node1->outputs[stream1].dev_id = pipe_id; - node2->inputs[stream2].dev_id = pipe_id; - output->sz_device = kzalloc(PIPENAMELEN + 1, - GFP_KERNEL); - input->sz_device = kzalloc(PIPENAMELEN + 1, GFP_KERNEL); - if (output->sz_device == NULL || - input->sz_device == NULL) { - /* Undo the connection */ - kfree(output->sz_device); - - kfree(input->sz_device); - - output->sz_device = NULL; - input->sz_device = NULL; - clear_bit(pipe_id, hnode_mgr->pipe_map); - status = -ENOMEM; - } else { - /* Copy "/dbpipe" name to device names */ - sprintf(output->sz_device, "%s%d", - PIPEPREFIX, pipe_id); - strcpy(input->sz_device, output->sz_device); - } + goto out_unlock; } + set_bit(pipe_id, hnode_mgr->pipe_map); + node1->outputs[stream1].type = NODECONNECT; + node2->inputs[stream2].type = NODECONNECT; + node1->outputs[stream1].dev_id = pipe_id; + node2->inputs[stream2].dev_id = pipe_id; + output->sz_device = kzalloc(PIPENAMELEN + 1, GFP_KERNEL); + input->sz_device = kzalloc(PIPENAMELEN + 1, GFP_KERNEL); + if (!output->sz_device || !input->sz_device) { + /* Undo the connection */ + kfree(output->sz_device); + kfree(input->sz_device); + clear_bit(pipe_id, hnode_mgr->pipe_map); + status = -ENOMEM; + goto out_unlock; + } + /* Copy "/dbpipe" name to device names */ + sprintf(output->sz_device, "%s%d", PIPEPREFIX, pipe_id); + strcpy(input->sz_device, output->sz_device); } /* Connecting task node to host? */ - if (!status && (node1_type == NODE_GPP || - node2_type == NODE_GPP)) { - if (node1_type == NODE_GPP) { - chnl_mode = CHNL_MODETODSP; - } else { - DBC_ASSERT(node2_type == NODE_GPP); - chnl_mode = CHNL_MODEFROMDSP; + if (node1_type == NODE_GPP || node2_type == NODE_GPP) { + pstr_dev_name = kzalloc(HOSTNAMELEN + 1, GFP_KERNEL); + if (!pstr_dev_name) { + status = -ENOMEM; + goto out_unlock; } - /* Reserve a channel id. We need to put the name "/host" + + DBC_ASSERT((node1_type == NODE_GPP) || + (node2_type == NODE_GPP)); + + chnl_mode = (node1_type == NODE_GPP) ? + CHNL_MODETODSP : CHNL_MODEFROMDSP; + + /* + * Reserve a channel id. We need to put the name "/host" * in the node's create_args, but the host * side channel will not be opened until DSPStream_Open is - * called for this node. */ - if (pattrs) { - if (pattrs->strm_mode == STRMMODE_RDMA) { - chnl_id = find_first_zero_bit( - hnode_mgr->dma_chnl_map, - CHNL_MAXCHANNELS); + * called for this node. + */ + strm_mode = pattrs ? pattrs->strm_mode : STRMMODE_PROCCOPY; + switch (strm_mode) { + case STRMMODE_RDMA: + chnl_id = find_first_zero_bit(hnode_mgr->dma_chnl_map, + CHNL_MAXCHANNELS); + if (chnl_id < CHNL_MAXCHANNELS) { + set_bit(chnl_id, hnode_mgr->dma_chnl_map); /* dma chans are 2nd transport chnl set * ids(e.g. 16-31) */ - if (chnl_id != CHNL_MAXCHANNELS) { - set_bit(chnl_id, - hnode_mgr->dma_chnl_map); - chnl_id = chnl_id + - hnode_mgr->ul_num_chnls; - } - } else if (pattrs->strm_mode == STRMMODE_ZEROCOPY) { - chnl_id = find_first_zero_bit( - hnode_mgr->zc_chnl_map, - CHNL_MAXCHANNELS); + chnl_id = chnl_id + hnode_mgr->ul_num_chnls; + } + break; + case STRMMODE_ZEROCOPY: + chnl_id = find_first_zero_bit(hnode_mgr->zc_chnl_map, + CHNL_MAXCHANNELS); + if (chnl_id < CHNL_MAXCHANNELS) { + set_bit(chnl_id, hnode_mgr->zc_chnl_map); /* zero-copy chans are 3nd transport set * (e.g. 32-47) */ - if (chnl_id != CHNL_MAXCHANNELS) { - set_bit(chnl_id, - hnode_mgr->zc_chnl_map); - chnl_id = chnl_id + - (2 * hnode_mgr->ul_num_chnls); - } - } else { /* must be PROCCOPY */ - DBC_ASSERT(pattrs->strm_mode == - STRMMODE_PROCCOPY); - chnl_id = find_first_zero_bit( - hnode_mgr->chnl_map, - CHNL_MAXCHANNELS); - /* e.g. 0-15 */ - if (chnl_id != CHNL_MAXCHANNELS) - set_bit(chnl_id, hnode_mgr->chnl_map); + chnl_id = chnl_id + + (2 * hnode_mgr->ul_num_chnls); } - } else { - /* default to PROCCOPY */ + break; + case STRMMODE_PROCCOPY: chnl_id = find_first_zero_bit(hnode_mgr->chnl_map, CHNL_MAXCHANNELS); - if (chnl_id != CHNL_MAXCHANNELS) + if (chnl_id < CHNL_MAXCHANNELS) set_bit(chnl_id, hnode_mgr->chnl_map); + break; + default: + status = -EINVAL; + goto out_unlock; } if (chnl_id == CHNL_MAXCHANNELS) { status = -ECONNREFUSED; - goto func_cont2; + goto out_unlock; } - pstr_dev_name = kzalloc(HOSTNAMELEN + 1, GFP_KERNEL); - if (pstr_dev_name != NULL) - goto func_cont2; - - if (pattrs) { - if (pattrs->strm_mode == STRMMODE_RDMA) { - clear_bit(chnl_id - hnode_mgr->ul_num_chnls, - hnode_mgr->dma_chnl_map); - } else if (pattrs->strm_mode == STRMMODE_ZEROCOPY) { - clear_bit(chnl_id - - (2 * hnode_mgr->ul_num_chnls), - hnode_mgr->zc_chnl_map); - } else { - DBC_ASSERT(pattrs->strm_mode == - STRMMODE_PROCCOPY); - clear_bit(chnl_id, hnode_mgr->chnl_map); - } + + if (node1 == (struct node_object *)DSP_HGPPNODE) { + node2->inputs[stream2].type = HOSTCONNECT; + node2->inputs[stream2].dev_id = chnl_id; + input->sz_device = pstr_dev_name; } else { - clear_bit(chnl_id, hnode_mgr->chnl_map); - } - status = -ENOMEM; -func_cont2: - if (!status) { - if (node1 == (struct node_object *)DSP_HGPPNODE) { - node2->inputs[stream2].type = HOSTCONNECT; - node2->inputs[stream2].dev_id = chnl_id; - input->sz_device = pstr_dev_name; - } else { - node1->outputs[stream1].type = HOSTCONNECT; - node1->outputs[stream1].dev_id = chnl_id; - output->sz_device = pstr_dev_name; - } - sprintf(pstr_dev_name, "%s%d", HOSTPREFIX, chnl_id); + node1->outputs[stream1].type = HOSTCONNECT; + node1->outputs[stream1].dev_id = chnl_id; + output->sz_device = pstr_dev_name; } + sprintf(pstr_dev_name, "%s%d", HOSTPREFIX, chnl_id); } /* Connecting task node to device node? */ - if (!status && ((node1_type == NODE_DEVICE) || - (node2_type == NODE_DEVICE))) { + if ((node1_type == NODE_DEVICE) || (node2_type == NODE_DEVICE)) { if (node2_type == NODE_DEVICE) { /* node1 == > device */ dev_node_obj = node2; @@ -1098,60 +1062,58 @@ func_cont2: /* Set up create args */ pstream->type = DEVICECONNECT; dw_length = strlen(dev_node_obj->pstr_dev_name); - if (conn_param != NULL) { + if (conn_param) pstrm_def->sz_device = kzalloc(dw_length + 1 + - conn_param->cb_data, - GFP_KERNEL); - } else { + conn_param->cb_data, + GFP_KERNEL); + else pstrm_def->sz_device = kzalloc(dw_length + 1, - GFP_KERNEL); - } - if (pstrm_def->sz_device == NULL) { + GFP_KERNEL); + if (!pstrm_def->sz_device) { status = -ENOMEM; - } else { - /* Copy device name */ - strncpy(pstrm_def->sz_device, + goto out_unlock; + } + /* Copy device name */ + strncpy(pstrm_def->sz_device, dev_node_obj->pstr_dev_name, dw_length); - if (conn_param != NULL) { - strncat(pstrm_def->sz_device, + if (conn_param) + strncat(pstrm_def->sz_device, (char *)conn_param->node_data, (u32) conn_param->cb_data); - } - dev_node_obj->device_owner = hnode; - } + dev_node_obj->device_owner = hnode; } - if (!status) { - /* Fill in create args */ - if (node1_type == NODE_TASK || node1_type == NODE_DAISSOCKET) { - node1->create_args.asa.task_arg_obj.num_outputs++; - fill_stream_def(node1, output, pattrs); - } - if (node2_type == NODE_TASK || node2_type == NODE_DAISSOCKET) { - node2->create_args.asa.task_arg_obj.num_inputs++; - fill_stream_def(node2, input, pattrs); - } - /* Update node1 and node2 stream_connect */ - if (node1_type != NODE_GPP && node1_type != NODE_DEVICE) { - node1->num_outputs++; - if (stream1 > node1->max_output_index) - node1->max_output_index = stream1; + /* Fill in create args */ + if (node1_type == NODE_TASK || node1_type == NODE_DAISSOCKET) { + node1->create_args.asa.task_arg_obj.num_outputs++; + fill_stream_def(node1, output, pattrs); + } + if (node2_type == NODE_TASK || node2_type == NODE_DAISSOCKET) { + node2->create_args.asa.task_arg_obj.num_inputs++; + fill_stream_def(node2, input, pattrs); + } + /* Update node1 and node2 stream_connect */ + if (node1_type != NODE_GPP && node1_type != NODE_DEVICE) { + node1->num_outputs++; + if (stream1 > node1->max_output_index) + node1->max_output_index = stream1; - } - if (node2_type != NODE_GPP && node2_type != NODE_DEVICE) { - node2->num_inputs++; - if (stream2 > node2->max_input_index) - node2->max_input_index = stream2; + } + if (node2_type != NODE_GPP && node2_type != NODE_DEVICE) { + node2->num_inputs++; + if (stream2 > node2->max_input_index) + node2->max_input_index = stream2; - } - fill_stream_connect(node1, node2, stream1, stream2); } + fill_stream_connect(node1, node2, stream1, stream2); /* end of sync_enter_cs */ /* Exit critical section */ +out_unlock: + if (status && pstr_dev_name) + kfree(pstr_dev_name); mutex_unlock(&hnode_mgr->node_mgr_lock); -func_end: dev_dbg(bridge, "%s: node1: %p stream1: %d node2: %p stream2: %d" - "pattrs: %p status: 0x%x\n", __func__, node1, - stream1, node2, stream2, pattrs, status); + "pattrs: %p status: 0x%x\n", __func__, node1, + stream1, node2, stream2, pattrs, status); return status; } @@ -1329,6 +1291,7 @@ int node_create_mgr(struct node_mgr **node_man, struct nldr_attrs nldr_attrs_obj; int status = 0; u8 dev_type; + DBC_REQUIRE(refs > 0); DBC_REQUIRE(node_man != NULL); DBC_REQUIRE(hdev_obj != NULL); @@ -1336,89 +1299,88 @@ int node_create_mgr(struct node_mgr **node_man, *node_man = NULL; /* Allocate Node manager object */ node_mgr_obj = kzalloc(sizeof(struct node_mgr), GFP_KERNEL); - if (node_mgr_obj) { - node_mgr_obj->hdev_obj = hdev_obj; - INIT_LIST_HEAD(&node_mgr_obj->node_list); - node_mgr_obj->ntfy_obj = kmalloc( - sizeof(struct ntfy_object), GFP_KERNEL); - if (node_mgr_obj->ntfy_obj) - ntfy_init(node_mgr_obj->ntfy_obj); - else - status = -ENOMEM; - node_mgr_obj->num_created = 0; - } else { + if (!node_mgr_obj) + return -ENOMEM; + + node_mgr_obj->hdev_obj = hdev_obj; + + node_mgr_obj->ntfy_obj = kmalloc(sizeof(struct ntfy_object), + GFP_KERNEL); + if (!node_mgr_obj->ntfy_obj) { status = -ENOMEM; + goto out_err; } - /* get devNodeType */ - if (!status) - status = dev_get_dev_type(hdev_obj, &dev_type); + ntfy_init(node_mgr_obj->ntfy_obj); - /* Create the DCD Manager */ - if (!status) { - status = - dcd_create_manager(sz_zl_file, &node_mgr_obj->hdcd_mgr); - if (!status) - status = get_proc_props(node_mgr_obj, hdev_obj); + INIT_LIST_HEAD(&node_mgr_obj->node_list); + + dev_get_dev_type(hdev_obj, &dev_type); + + status = dcd_create_manager(sz_zl_file, &node_mgr_obj->hdcd_mgr); + if (status) + goto out_err; + + status = get_proc_props(node_mgr_obj, hdev_obj); + if (status) + goto out_err; - } /* Create NODE Dispatcher */ - if (!status) { - disp_attr_obj.ul_chnl_offset = node_mgr_obj->ul_chnl_offset; - disp_attr_obj.ul_chnl_buf_size = node_mgr_obj->ul_chnl_buf_size; - disp_attr_obj.proc_family = node_mgr_obj->proc_family; - disp_attr_obj.proc_type = node_mgr_obj->proc_type; - status = - disp_create(&node_mgr_obj->disp_obj, hdev_obj, - &disp_attr_obj); - } + disp_attr_obj.ul_chnl_offset = node_mgr_obj->ul_chnl_offset; + disp_attr_obj.ul_chnl_buf_size = node_mgr_obj->ul_chnl_buf_size; + disp_attr_obj.proc_family = node_mgr_obj->proc_family; + disp_attr_obj.proc_type = node_mgr_obj->proc_type; + + status = disp_create(&node_mgr_obj->disp_obj, hdev_obj, &disp_attr_obj); + if (status) + goto out_err; + /* Create a STRM Manager */ - if (!status) - status = strm_create(&node_mgr_obj->strm_mgr_obj, hdev_obj); + status = strm_create(&node_mgr_obj->strm_mgr_obj, hdev_obj); + if (status) + goto out_err; - if (!status) { - dev_get_intf_fxns(hdev_obj, &node_mgr_obj->intf_fxns); - /* Get msg_ctrl queue manager */ - dev_get_msg_mgr(hdev_obj, &node_mgr_obj->msg_mgr_obj); - mutex_init(&node_mgr_obj->node_mgr_lock); - /* Block out reserved channels */ - for (i = 0; i < node_mgr_obj->ul_chnl_offset; i++) - set_bit(i, node_mgr_obj->chnl_map); - - /* Block out channels reserved for RMS */ - set_bit(node_mgr_obj->ul_chnl_offset, node_mgr_obj->chnl_map); - set_bit(node_mgr_obj->ul_chnl_offset + 1, - node_mgr_obj->chnl_map); - } - if (!status) { - /* NO RM Server on the IVA */ - if (dev_type != IVA_UNIT) { - /* Get addresses of any RMS functions loaded */ - status = get_rms_fxns(node_mgr_obj); - } + dev_get_intf_fxns(hdev_obj, &node_mgr_obj->intf_fxns); + /* Get msg_ctrl queue manager */ + dev_get_msg_mgr(hdev_obj, &node_mgr_obj->msg_mgr_obj); + mutex_init(&node_mgr_obj->node_mgr_lock); + + /* Block out reserved channels */ + for (i = 0; i < node_mgr_obj->ul_chnl_offset; i++) + set_bit(i, node_mgr_obj->chnl_map); + + /* Block out channels reserved for RMS */ + set_bit(node_mgr_obj->ul_chnl_offset, node_mgr_obj->chnl_map); + set_bit(node_mgr_obj->ul_chnl_offset + 1, node_mgr_obj->chnl_map); + + /* NO RM Server on the IVA */ + if (dev_type != IVA_UNIT) { + /* Get addresses of any RMS functions loaded */ + status = get_rms_fxns(node_mgr_obj); + if (status) + goto out_err; } /* Get loader functions and create loader */ - if (!status) - node_mgr_obj->nldr_fxns = nldr_fxns; /* Dyn loader funcs */ + node_mgr_obj->nldr_fxns = nldr_fxns; /* Dyn loader funcs */ + + nldr_attrs_obj.pfn_ovly = ovly; + nldr_attrs_obj.pfn_write = mem_write; + nldr_attrs_obj.us_dsp_word_size = node_mgr_obj->udsp_word_size; + nldr_attrs_obj.us_dsp_mau_size = node_mgr_obj->udsp_mau_size; + node_mgr_obj->loader_init = node_mgr_obj->nldr_fxns.pfn_init(); + status = node_mgr_obj->nldr_fxns.pfn_create(&node_mgr_obj->nldr_obj, + hdev_obj, + &nldr_attrs_obj); + if (status) + goto out_err; - if (!status) { - nldr_attrs_obj.pfn_ovly = ovly; - nldr_attrs_obj.pfn_write = mem_write; - nldr_attrs_obj.us_dsp_word_size = node_mgr_obj->udsp_word_size; - nldr_attrs_obj.us_dsp_mau_size = node_mgr_obj->udsp_mau_size; - node_mgr_obj->loader_init = node_mgr_obj->nldr_fxns.pfn_init(); - status = - node_mgr_obj->nldr_fxns.pfn_create(&node_mgr_obj->nldr_obj, - hdev_obj, - &nldr_attrs_obj); - } - if (!status) - *node_man = node_mgr_obj; - else - delete_node_mgr(node_mgr_obj); + *node_man = node_mgr_obj; DBC_ENSURE((status && *node_man == NULL) || (!status && *node_man)); + return status; +out_err: + delete_node_mgr(node_mgr_obj); return status; } @@ -1593,16 +1555,14 @@ func_end: */ int node_delete_mgr(struct node_mgr *hnode_mgr) { - int status = 0; - DBC_REQUIRE(refs > 0); - if (hnode_mgr) - delete_node_mgr(hnode_mgr); - else - status = -EFAULT; + if (!hnode_mgr) + return -EFAULT; - return status; + delete_node_mgr(hnode_mgr); + + return 0; } /* @@ -1710,38 +1670,37 @@ int node_get_attr(struct node_object *hnode, struct dsp_nodeattr *pattr, u32 attr_size) { struct node_mgr *hnode_mgr; - int status = 0; DBC_REQUIRE(refs > 0); DBC_REQUIRE(pattr != NULL); DBC_REQUIRE(attr_size >= sizeof(struct dsp_nodeattr)); - if (!hnode) { - status = -EFAULT; - } else { - hnode_mgr = hnode->hnode_mgr; - /* Enter hnode_mgr critical section (since we're accessing - * data that could be changed by node_change_priority() and - * node_connect(). */ - mutex_lock(&hnode_mgr->node_mgr_lock); - pattr->cb_struct = sizeof(struct dsp_nodeattr); - /* dsp_nodeattrin */ - pattr->in_node_attr_in.cb_struct = - sizeof(struct dsp_nodeattrin); - pattr->in_node_attr_in.prio = hnode->prio; - pattr->in_node_attr_in.utimeout = hnode->utimeout; - pattr->in_node_attr_in.heap_size = - hnode->create_args.asa.task_arg_obj.heap_size; - pattr->in_node_attr_in.pgpp_virt_addr = (void *) - hnode->create_args.asa.task_arg_obj.ugpp_heap_addr; - pattr->node_attr_inputs = hnode->num_gpp_inputs; - pattr->node_attr_outputs = hnode->num_gpp_outputs; - /* dsp_nodeinfo */ - get_node_info(hnode, &(pattr->node_info)); - /* end of sync_enter_cs */ - /* Exit critical section */ - mutex_unlock(&hnode_mgr->node_mgr_lock); - } - return status; + if (!hnode) + return -EFAULT; + + hnode_mgr = hnode->hnode_mgr; + /* Enter hnode_mgr critical section (since we're accessing + * data that could be changed by node_change_priority() and + * node_connect(). */ + mutex_lock(&hnode_mgr->node_mgr_lock); + pattr->cb_struct = sizeof(struct dsp_nodeattr); + /* dsp_nodeattrin */ + pattr->in_node_attr_in.cb_struct = + sizeof(struct dsp_nodeattrin); + pattr->in_node_attr_in.prio = hnode->prio; + pattr->in_node_attr_in.utimeout = hnode->utimeout; + pattr->in_node_attr_in.heap_size = + hnode->create_args.asa.task_arg_obj.heap_size; + pattr->in_node_attr_in.pgpp_virt_addr = (void *) + hnode->create_args.asa.task_arg_obj.ugpp_heap_addr; + pattr->node_attr_inputs = hnode->num_gpp_inputs; + pattr->node_attr_outputs = hnode->num_gpp_outputs; + /* dsp_nodeinfo */ + get_node_info(hnode, &(pattr->node_info)); + /* end of sync_enter_cs */ + /* Exit critical section */ + mutex_unlock(&hnode_mgr->node_mgr_lock); + + return 0; } /* -- cgit v1.2.3 From c378204afacc627330a9a1aeb5b5cd6e3d821717 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 12 Dec 2010 13:39:37 +0000 Subject: staging: tidspbridge: Fix atoi to support hexadecimal numbers correctly For some strange reason, the DSP base image node/object properties description string stores hexadecimal numbers with a 'h' or 'H' suffix instead of a '0x' prefix. This causes parsing issue because the dspbridge atoi() implementation relies on strict_strtoul(), which will return an error because of the trailing 'h' character. As the atoi() return value is never checked for an error anyway, replace strict_strtoul() with simple_strtoul() to ignore the suffix. This fix gets rid of the following assertion failed messages that were printed when running the dsp-dummy test application. drivers/staging/tidspbridge/rmgr/nldr.c, line 1691: Assertion (segid == MEMINTERNALID || segid == MEMEXTERNALID) failed. Signed-off-by: Laurent Pinchart Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/rmgr/dbdcd.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/rmgr/dbdcd.c b/drivers/staging/tidspbridge/rmgr/dbdcd.c index 3581a55ed4dd..b76f26caeab2 100644 --- a/drivers/staging/tidspbridge/rmgr/dbdcd.c +++ b/drivers/staging/tidspbridge/rmgr/dbdcd.c @@ -1020,8 +1020,6 @@ static s32 atoi(char *psz_buf) { char *pch = psz_buf; s32 base = 0; - unsigned long res; - int ret_val; while (isspace(*pch)) pch++; @@ -1033,9 +1031,7 @@ static s32 atoi(char *psz_buf) base = 16; } - ret_val = strict_strtoul(pch, base, &res); - - return ret_val ? : res; + return simple_strtoul(pch, NULL, base); } /* -- cgit v1.2.3 From 2c36fac48587265311b015b7a36b2b860cf21ccd Mon Sep 17 00:00:00 2001 From: Armando Uribe Date: Fri, 17 Dec 2010 01:18:29 -0600 Subject: staging: tidspbridge: Remove unused defined constants Remove defined constants not being used. Signed-off-by: Armando Uribe Signed-off-by: Omar Ramirez Luna --- .../tidspbridge/include/dspbridge/brddefs.h | 2 -- .../tidspbridge/include/dspbridge/cfgdefs.h | 13 ------- .../tidspbridge/include/dspbridge/chnldefs.h | 3 -- .../tidspbridge/include/dspbridge/chnlpriv.h | 13 ------- .../staging/tidspbridge/include/dspbridge/cod.h | 3 -- .../staging/tidspbridge/include/dspbridge/dbdefs.h | 26 -------------- .../tidspbridge/include/dspbridge/dbldefs.h | 11 ------ .../tidspbridge/include/dspbridge/dehdefs.h | 1 - .../staging/tidspbridge/include/dspbridge/drv.h | 15 -------- .../tidspbridge/include/dspbridge/dspdefs.h | 6 ---- .../staging/tidspbridge/include/dspbridge/dspdrv.h | 2 -- .../tidspbridge/include/dspbridge/dspioctl.h | 5 --- .../tidspbridge/include/dspbridge/dynamic_loader.h | 2 -- .../staging/tidspbridge/include/dspbridge/io_sm.h | 1 - .../staging/tidspbridge/include/dspbridge/iodefs.h | 2 -- .../staging/tidspbridge/include/dspbridge/mbx_sh.h | 40 ---------------------- .../staging/tidspbridge/include/dspbridge/pwr_sh.h | 4 --- .../staging/tidspbridge/include/dspbridge/rms_sh.h | 9 ----- .../tidspbridge/include/dspbridge/strmdefs.h | 2 -- drivers/staging/tidspbridge/pmgr/dev.c | 2 +- 20 files changed, 1 insertion(+), 161 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/include/dspbridge/brddefs.h b/drivers/staging/tidspbridge/include/dspbridge/brddefs.h index f80d9a5f05a3..725d7b37414c 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/brddefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/brddefs.h @@ -24,9 +24,7 @@ #define BRD_IDLE 0x1 /* Monitor Loaded, but suspended. */ #define BRD_RUNNING 0x2 /* Monitor loaded, and executing. */ #define BRD_UNKNOWN 0x3 /* Board state is indeterminate. */ -#define BRD_SYNCINIT 0x4 #define BRD_LOADED 0x5 -#define BRD_LASTSTATE BRD_LOADED /* Set to highest legal board state. */ #define BRD_SLEEP_TRANSITION 0x6 /* Sleep transition in progress */ #define BRD_HIBERNATION 0x7 /* MPU initiated hibernation */ #define BRD_RETENTION 0x8 /* Retention mode */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h index f403c01b5d3a..c3f04f874204 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h @@ -19,25 +19,12 @@ #ifndef CFGDEFS_ #define CFGDEFS_ -/* Maximum length of module search path. */ -#define CFG_MAXSEARCHPATHLEN 255 - -/* Maximum length of general paths. */ -#define CFG_MAXPATH 255 - /* Host Resources: */ #define CFG_MAXMEMREGISTERS 9 -#define CFG_MAXIOPORTS 20 -#define CFG_MAXIRQS 7 -#define CFG_MAXDMACHANNELS 7 /* IRQ flag */ #define CFG_IRQSHARED 0x01 /* IRQ can be shared */ -/* DSP Resources: */ -#define CFG_DSPMAXMEMTYPES 10 -#define CFG_DEFAULT_NUM_WINDOWS 1 /* We support only one window. */ - /* A platform-related device handle: */ struct cfg_devnode; diff --git a/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h b/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h index 5bf5f6b0b7b4..8f8f9ece8d49 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h @@ -22,9 +22,6 @@ /* Channel id option. */ #define CHNL_PICKFREE (~0UL) /* Let manager pick a free channel. */ -/* Channel manager limits: */ -#define CHNL_INITIOREQS 4 /* Default # of I/O requests. */ - /* Channel modes */ #define CHNL_MODETODSP 0 /* Data streaming to the DSP. */ #define CHNL_MODEFROMDSP 1 /* Data streaming from the DSP. */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h b/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h index 9292100b1c04..1785c3e83719 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h @@ -39,12 +39,6 @@ */ #define CHNL_PCPY 0 /* Proc-copy transport 0 */ -#define CHNL_MAXIRQ 0xff /* Arbitrarily large number. */ - -/* The following modes are private: */ -#define CHNL_MODEUSEREVENT 0x1000 /* User provided the channel event. */ -#define CHNL_MODEMASK 0x1001 - /* Higher level channel states: */ #define CHNL_STATEREADY 0 /* Channel ready for I/O. */ #define CHNL_STATECANCEL 1 /* I/O was cancelled. */ @@ -56,13 +50,6 @@ /* Types of channel class libraries: */ #define CHNL_TYPESM 1 /* Shared memory driver. */ -#define CHNL_TYPEBM 2 /* Bus Mastering driver. */ - -/* Max string length of channel I/O completion event name - change if needed */ -#define CHNL_MAXEVTNAMELEN 32 - -/* Max memory pages lockable in CHNL_PrepareBuffer() - change if needed */ -#define CHNL_MAXLOCKPAGES 64 /* Channel info. */ struct chnl_info { diff --git a/drivers/staging/tidspbridge/include/dspbridge/cod.h b/drivers/staging/tidspbridge/include/dspbridge/cod.h index 42bce2eec80a..5efea91625b2 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cod.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cod.h @@ -27,9 +27,6 @@ #define COD_TRACEBEG "SYS_PUTCBEG" #define COD_TRACEEND "SYS_PUTCEND" #define COD_TRACECURPOS "BRIDGE_SYS_PUTC_current" -#define COD_TRACESECT "trace" -#define COD_TRACEBEGOLD "PUTCBEG" -#define COD_TRACEENDOLD "PUTCEND" #define COD_NOLOAD DBLL_NOLOAD #define COD_SYMB DBLL_SYMB diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h index 5af075def871..38fffebd0c0c 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h @@ -31,9 +31,6 @@ /* API return value and calling convention */ #define DBAPI int -/* Infinite time value for the utimeout parameter to DSPStream_Select() */ -#define DSP_FOREVER (-1) - /* Maximum length of node name, used in dsp_ndbprops */ #define DSP_MAXNAMELEN 32 @@ -74,16 +71,9 @@ #define DSP_NODE_MIN_PRIORITY 1 #define DSP_NODE_MAX_PRIORITY 15 -/* Pre-Defined Message Command Codes available to user: */ -#define DSP_RMSUSERCODESTART RMS_USER /* Start of RMS user cmd codes */ -/* end of user codes */ -#define DSP_RMSUSERCODEEND (RMS_USER + RMS_MAXUSERCODES); /* msg_ctrl contains SM buffer description */ #define DSP_RMSBUFDESC RMS_BUFDESC -/* Shared memory identifier for MEM segment named "SHMSEG0" */ -#define DSP_SHMSEG0 (u32)(-1) - /* Processor ID numbers */ #define DSP_UNIT 0 #define IVA_UNIT 1 @@ -91,15 +81,6 @@ #define DSPWORD unsigned char #define DSPWORDSIZE sizeof(DSPWORD) -/* Power control enumerations */ -#define PROC_PWRCONTROL 0x8070 - -#define PROC_PWRMGT_ENABLE (PROC_PWRCONTROL + 0x3) -#define PROC_PWRMGT_DISABLE (PROC_PWRCONTROL + 0x4) - -/* Bridge Code Version */ -#define BRIDGE_VERSION_CODE 333 - #define MAX_PROFILES 16 /* DSP chip type */ @@ -501,13 +482,6 @@ bit 15 - Output (writeable) buffer #define DSPPROCTYPE_C64 6410 #define IVAPROCTYPE_ARM7 470 -#define REG_MGR_OBJECT 1 -#define REG_DRV_OBJECT 2 - -/* registry */ -#define DRVOBJECT "DrvObject" -#define MGROBJECT "MgrObject" - /* Max registry path length. Also the max registry value length. */ #define MAXREGPATHLENGTH 255 diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbldefs.h b/drivers/staging/tidspbridge/include/dspbridge/dbldefs.h index bf4fb99529ae..9973098ea64b 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dbldefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dbldefs.h @@ -17,17 +17,6 @@ #ifndef DBLDEFS_ #define DBLDEFS_ -/* - * Bit masks for dbl_flags. - */ -#define DBL_NOLOAD 0x0 /* Don't load symbols, code, or data */ -#define DBL_SYMB 0x1 /* load symbols */ -#define DBL_CODE 0x2 /* load code */ -#define DBL_DATA 0x4 /* load data */ -#define DBL_DYNAMIC 0x8 /* dynamic load */ -#define DBL_BSS 0x20 /* Unitialized section */ - -#define DBL_MAXPATHLENGTH 255 /* * ======== dbl_flags ======== diff --git a/drivers/staging/tidspbridge/include/dspbridge/dehdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dehdefs.h index 09f8bf83ab0a..53414716f298 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dehdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dehdefs.h @@ -26,7 +26,6 @@ struct deh_mgr; /* Magic code used to determine if DSP signaled exception. */ #define DEH_BASE MBX_DEH_BASE -#define DEH_USERS_BASE MBX_DEH_USERS_BASE #define DEH_LIMIT MBX_DEH_LIMIT #endif /* _DEHDEFS_H */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/drv.h b/drivers/staging/tidspbridge/include/dspbridge/drv.h index 37f5a45b5410..adb28ec946bb 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/drv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/drv.h @@ -26,9 +26,6 @@ #include #include -#define DRV_ASSIGN 1 -#define DRV_RELEASE 0 - /* Provide the DSP Internal memory windows that can be accessed from L3 address * space */ @@ -38,23 +35,14 @@ /* MEM1 is L2 RAM + L2 Cache space */ #define OMAP_DSP_MEM1_BASE 0x5C7F8000 #define OMAP_DSP_MEM1_SIZE 0x18000 -#define OMAP_DSP_GEM1_BASE 0x107F8000 /* MEM2 is L1P RAM/CACHE space */ #define OMAP_DSP_MEM2_BASE 0x5CE00000 #define OMAP_DSP_MEM2_SIZE 0x8000 -#define OMAP_DSP_GEM2_BASE 0x10E00000 /* MEM3 is L1D RAM/CACHE space */ #define OMAP_DSP_MEM3_BASE 0x5CF04000 #define OMAP_DSP_MEM3_SIZE 0x14000 -#define OMAP_DSP_GEM3_BASE 0x10F04000 - -#define OMAP_IVA2_PRM_BASE 0x48306000 -#define OMAP_IVA2_PRM_SIZE 0x1000 - -#define OMAP_IVA2_CM_BASE 0x48004000 -#define OMAP_IVA2_CM_SIZE 0x1000 #define OMAP_PER_CM_BASE 0x48005000 #define OMAP_PER_CM_SIZE 0x1000 @@ -68,9 +56,6 @@ #define OMAP_DMMU_BASE 0x5D000000 #define OMAP_DMMU_SIZE 0x1000 -#define OMAP_PRCM_VDD1_DOMAIN 1 -#define OMAP_PRCM_VDD2_DOMAIN 2 - /* GPP PROCESS CLEANUP Data structures */ /* New structure (member of process context) abstracts NODE resource info */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h index 0ae7d1646a1b..2acbbb34bff3 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h @@ -37,12 +37,6 @@ #include #include -/* - * Any IOCTLS at or above this value are reserved for standard Bridge driver - * interfaces. - */ -#define BRD_RESERVEDIOCTLBASE 0x8000 - /* Handle to Bridge driver's private device context. */ struct bridge_dev_context; diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdrv.h b/drivers/staging/tidspbridge/include/dspbridge/dspdrv.h index 0bb250f95bad..7adf1e705314 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspdrv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspdrv.h @@ -20,8 +20,6 @@ #if !defined _DSPDRV_H_ #define _DSPDRV_H_ -#define MAX_DEV 10 /* Max support of 10 devices */ - /* * ======== dsp_deinit ======== * Purpose: diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h index 41e0594dff34..54552a73d932 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h @@ -31,9 +31,6 @@ #define BRDIOCTL_CHNLREAD (BRDIOCTL_RESERVEDBASE + 0x10) #define BRDIOCTL_CHNLWRITE (BRDIOCTL_RESERVEDBASE + 0x20) -#define BRDIOCTL_GETINTRCOUNT (BRDIOCTL_RESERVEDBASE + 0x30) -#define BRDIOCTL_RESETINTRCOUNT (BRDIOCTL_RESERVEDBASE + 0x40) -#define BRDIOCTL_INTERRUPTDSP (BRDIOCTL_RESERVEDBASE + 0x50) /* DMMU */ #define BRDIOCTL_SETMMUCONFIG (BRDIOCTL_RESERVEDBASE + 0x60) /* PWR */ @@ -47,8 +44,6 @@ #define BRDIOCTL_DEEPSLEEP (BRDIOCTL_PWRCONTROL + 0x0) #define BRDIOCTL_EMERGENCYSLEEP (BRDIOCTL_PWRCONTROL + 0x1) #define BRDIOCTL_WAKEUP (BRDIOCTL_PWRCONTROL + 0x2) -#define BRDIOCTL_PWRENABLE (BRDIOCTL_PWRCONTROL + 0x3) -#define BRDIOCTL_PWRDISABLE (BRDIOCTL_PWRCONTROL + 0x4) #define BRDIOCTL_CLK_CTRL (BRDIOCTL_PWRCONTROL + 0x7) /* DSP Initiated Hibernate */ #define BRDIOCTL_PWR_HIBERNATE (BRDIOCTL_PWRCONTROL + 0x8) diff --git a/drivers/staging/tidspbridge/include/dspbridge/dynamic_loader.h b/drivers/staging/tidspbridge/include/dspbridge/dynamic_loader.h index 4b109d173b18..052d27ee8b1a 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dynamic_loader.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dynamic_loader.h @@ -46,8 +46,6 @@ struct dynamic_loader_initialize; * Option flags to modify the behavior of module loading */ #define DLOAD_INITBSS 0x1 /* initialize BSS sections to zero */ -#define DLOAD_BIGEND 0x2 /* require big-endian load module */ -#define DLOAD_LITTLE 0x4 /* require little-endian load module */ /***************************************************************************** * Procedure dynamic_load_module diff --git a/drivers/staging/tidspbridge/include/dspbridge/io_sm.h b/drivers/staging/tidspbridge/include/dspbridge/io_sm.h index 8242c70e09dd..056606a10a47 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/io_sm.h +++ b/drivers/staging/tidspbridge/include/dspbridge/io_sm.h @@ -28,7 +28,6 @@ #define IO_INPUT 0 #define IO_OUTPUT 1 #define IO_SERVICE 2 -#define IO_MAXSERVICE IO_SERVICE #ifdef CONFIG_TIDSPBRIDGE_DVFS /* The maximum number of OPPs that are supported */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/iodefs.h b/drivers/staging/tidspbridge/include/dspbridge/iodefs.h index 8bd10a04200a..31cbc9a71816 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/iodefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/iodefs.h @@ -19,8 +19,6 @@ #ifndef IODEFS_ #define IODEFS_ -#define IO_MAXIRQ 0xff /* Arbitrarily large number. */ - /* IO Objects: */ struct io_mgr; diff --git a/drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h b/drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h index 5d165cd932f0..7424c888d637 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h +++ b/drivers/staging/tidspbridge/include/dspbridge/mbx_sh.h @@ -110,13 +110,7 @@ #ifndef _MBX_SH_H #define _MBX_SH_H -#define MBX_CLASS_MSK 0xFC00 /* Class bits are 10 thru 15 */ -#define MBX_VALUE_MSK 0x03FF /* Value is 0 thru 9 */ - -#define MBX_DEH_CLASS 0x0000 /* DEH owns Mbx INTR */ -#define MBX_DDMA_CLASS 0x0400 /* DSP-DMA link drvr chnls owns INTR */ #define MBX_PCPY_CLASS 0x0800 /* PROC-COPY " */ -#define MBX_ZCPY_CLASS 0x1000 /* ZERO-COPY " */ #define MBX_PM_CLASS 0x2000 /* Power Management */ #define MBX_DBG_CLASS 0x4000 /* For debugging purpose */ @@ -128,55 +122,21 @@ #define MBX_DEH_USERS_BASE 0x100 /* 256 */ #define MBX_DEH_LIMIT 0x3FF /* 1023 */ #define MBX_DEH_RESET 0x101 /* DSP RESET (DEH) */ -#define MBX_DEH_EMMU 0X103 /*DSP MMU FAULT RECOVERY */ /* * Link driver command/status codes. */ -/* DSP-DMA */ -#define MBX_DDMA_NUMCHNLBITS 5 /* # chnl Id: # bits available */ -#define MBX_DDMA_CHNLSHIFT 0 /* # of bits to shift */ -#define MBX_DDMA_CHNLMSK 0x01F /* bits 0 thru 4 */ - -#define MBX_DDMA_NUMBUFBITS 5 /* buffer index: # of bits avail */ -#define MBX_DDMA_BUFSHIFT (MBX_DDMA_NUMCHNLBITS + MBX_DDMA_CHNLSHIFT) -#define MBX_DDMA_BUFMSK 0x3E0 /* bits 5 thru 9 */ - -/* Zero-Copy */ -#define MBX_ZCPY_NUMCHNLBITS 5 /* # chnl Id: # bits available */ -#define MBX_ZCPY_CHNLSHIFT 0 /* # of bits to shift */ -#define MBX_ZCPY_CHNLMSK 0x01F /* bits 0 thru 4 */ /* Power Management Commands */ #define MBX_PM_DSPIDLE (MBX_PM_CLASS + 0x0) #define MBX_PM_DSPWAKEUP (MBX_PM_CLASS + 0x1) #define MBX_PM_EMERGENCYSLEEP (MBX_PM_CLASS + 0x2) -#define MBX_PM_SLEEPUNTILRESTART (MBX_PM_CLASS + 0x3) -#define MBX_PM_DSPGLOBALIDLE_OFF (MBX_PM_CLASS + 0x4) -#define MBX_PM_DSPGLOBALIDLE_ON (MBX_PM_CLASS + 0x5) #define MBX_PM_SETPOINT_PRENOTIFY (MBX_PM_CLASS + 0x6) #define MBX_PM_SETPOINT_POSTNOTIFY (MBX_PM_CLASS + 0x7) -#define MBX_PM_DSPRETN (MBX_PM_CLASS + 0x8) #define MBX_PM_DSPRETENTION (MBX_PM_CLASS + 0x8) #define MBX_PM_DSPHIBERNATE (MBX_PM_CLASS + 0x9) #define MBX_PM_HIBERNATE_EN (MBX_PM_CLASS + 0xA) #define MBX_PM_OPP_REQ (MBX_PM_CLASS + 0xB) -#define MBX_PM_OPP_CHG (MBX_PM_CLASS + 0xC) - -#define MBX_PM_TYPE_MASK 0x0300 -#define MBX_PM_TYPE_PWR_CHNG 0x0100 -#define MBX_PM_TYPE_OPP_PRECHNG 0x0200 -#define MBX_PM_TYPE_OPP_POSTCHNG 0x0300 -#define MBX_PM_TYPE_OPP_MASK 0x0300 -#define MBX_PM_OPP_PRECHNG (MBX_PM_CLASS | MBX_PM_TYPE_OPP_PRECHNG) -/* DSP to MPU */ -#define MBX_PM_OPP_CHNG(OPP) (MBX_PM_CLASS | MBX_PM_TYPE_OPP_PRECHNG | (OPP)) -#define MBX_PM_RET (MBX_PM_CLASS | MBX_PM_TYPE_PWR_CHNG | 0x0006) -#define MBX_PM_HIB (MBX_PM_CLASS | MBX_PM_TYPE_PWR_CHNG | 0x0002) -#define MBX_PM_OPP1 0 -#define MBX_PM_OPP2 1 -#define MBX_PM_OPP3 2 -#define MBX_PM_OPP4 3 /* Bridge Debug Commands */ #define MBX_DBG_SYSPRINTF (MBX_DBG_CLASS + 0x0) diff --git a/drivers/staging/tidspbridge/include/dspbridge/pwr_sh.h b/drivers/staging/tidspbridge/include/dspbridge/pwr_sh.h index 1b4a090abe78..c78a1b151015 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/pwr_sh.h +++ b/drivers/staging/tidspbridge/include/dspbridge/pwr_sh.h @@ -24,10 +24,6 @@ /* valid sleep command codes that can be sent by GPP via mailbox: */ #define PWR_DEEPSLEEP MBX_PM_DSPIDLE #define PWR_EMERGENCYDEEPSLEEP MBX_PM_EMERGENCYSLEEP -#define PWR_SLEEPUNTILRESTART MBX_PM_SLEEPUNTILRESTART #define PWR_WAKEUP MBX_PM_DSPWAKEUP -#define PWR_AUTOENABLE MBX_PM_PWRENABLE -#define PWR_AUTODISABLE MBX_PM_PWRDISABLE -#define PWR_RETENTION MBX_PM_DSPRETN #endif /* PWR_SH_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/rms_sh.h b/drivers/staging/tidspbridge/include/dspbridge/rms_sh.h index 7bc5574342aa..ba7f47845673 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/rms_sh.h +++ b/drivers/staging/tidspbridge/include/dspbridge/rms_sh.h @@ -22,27 +22,18 @@ #include -/* Node Types: */ -#define RMS_TASK 1 /* Task node */ -#define RMS_DAIS 2 /* xDAIS socket node */ -#define RMS_MSG 3 /* Message node */ - /* Memory Types: */ #define RMS_CODE 0 /* Program space */ #define RMS_DATA 1 /* Data space */ -#define RMS_IO 2 /* I/O space */ /* RM Server Command and Response Buffer Sizes: */ #define RMS_COMMANDBUFSIZE 256 /* Size of command buffer */ -#define RMS_RESPONSEBUFSIZE 16 /* Size of response buffer */ /* Pre-Defined Command/Response Codes: */ #define RMS_EXIT 0x80000000 /* GPP->Node: shutdown */ #define RMS_EXITACK 0x40000000 /* Node->GPP: ack shutdown */ #define RMS_BUFDESC 0x20000000 /* Arg1 SM buf, Arg2 SM size */ #define RMS_KILLTASK 0x10000000 /* GPP->Node: Kill Task */ -#define RMS_USER 0x0 /* Start of user-defined msg codes */ -#define RMS_MAXUSERCODES 0xfff /* Maximum user defined C/R Codes */ /* RM Server RPC Command Structure: */ struct rms_command { diff --git a/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h b/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h index b363f794de33..c6abbf366e3c 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h @@ -19,8 +19,6 @@ #ifndef STRMDEFS_ #define STRMDEFS_ -#define STRM_MAXEVTNAMELEN 32 - struct strm_mgr; struct strm_object; diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c index b160b0032eb3..b95cd206c1fd 100644 --- a/drivers/staging/tidspbridge/pmgr/dev.c +++ b/drivers/staging/tidspbridge/pmgr/dev.c @@ -880,7 +880,7 @@ int dev_start_device(struct cfg_devnode *dev_node_obj) { struct dev_object *hdev_obj = NULL; /* handle to 'Bridge Device */ /* Bridge driver filename */ - char bridge_file_name[CFG_MAXSEARCHPATHLEN] = "UMA"; + char *bridge_file_name = "UMA"; int status; struct mgr_object *hmgr_obj = NULL; struct drv_data *drv_datap = dev_get_drvdata(bridge); -- cgit v1.2.3 From 57e6a9f2a8472493fe407227b047f5284d8a4540 Mon Sep 17 00:00:00 2001 From: Armando Uribe Date: Fri, 17 Dec 2010 01:18:30 -0600 Subject: staging: tidspbridge: Remove unused functions Remove functions that are not used at all, also remove the dependencies of this functions like struct members, comments and calls. Signed-off-by: Armando Uribe Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/core/io_sm.c | 4 - drivers/staging/tidspbridge/core/tiomap3430.c | 2 - .../staging/tidspbridge/include/dspbridge/chnl.h | 21 ---- .../staging/tidspbridge/include/dspbridge/dbll.h | 6 - .../tidspbridge/include/dspbridge/dblldefs.h | 3 - .../staging/tidspbridge/include/dspbridge/dev.h | 55 --------- .../staging/tidspbridge/include/dspbridge/dspio.h | 1 - .../tidspbridge/include/dspbridge/host_os.h | 9 -- drivers/staging/tidspbridge/include/dspbridge/io.h | 16 --- .../staging/tidspbridge/include/dspbridge/io_sm.h | 135 --------------------- .../staging/tidspbridge/include/dspbridge/node.h | 18 --- .../include/dspbridge/resourcecleanup.h | 11 -- .../staging/tidspbridge/include/dspbridge/strm.h | 62 ---------- drivers/staging/tidspbridge/pmgr/cod.c | 3 - drivers/staging/tidspbridge/pmgr/dbll.c | 41 ------- drivers/staging/tidspbridge/rmgr/nldr.c | 3 - 16 files changed, 390 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 042a46507544..d4b9e141f3d5 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -1682,10 +1682,6 @@ int bridge_io_get_proc_load(struct io_mgr *hio_mgr, return 0; } -void io_sm_init(void) -{ - /* Do nothing */ -} #if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG) void print_dsp_debug_trace(struct io_mgr *hio_mgr) diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 2ae7e44819e8..ec713ed74413 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -259,8 +259,6 @@ void bridge_drv_entry(struct bridge_drv_interface **drv_intf, DBC_REQUIRE(driver_file_name != NULL); - io_sm_init(); /* Initialization of io_sm module */ - if (strcmp(driver_file_name, "UMA") == 0) *drv_intf = &drv_interface_fxns; else diff --git a/drivers/staging/tidspbridge/include/dspbridge/chnl.h b/drivers/staging/tidspbridge/include/dspbridge/chnl.h index 8733b3b81931..92f6a13424f2 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/chnl.h +++ b/drivers/staging/tidspbridge/include/dspbridge/chnl.h @@ -24,27 +24,6 @@ #include -/* - * ======== chnl_close ======== - * Purpose: - * Ensures all pending I/O on this channel is cancelled, discards all - * queued I/O completion notifications, then frees the resources allocated - * for this channel, and makes the corresponding logical channel id - * available for subsequent use. - * Parameters: - * chnl_obj: Channel object handle. - * Returns: - * 0: Success; - * -EFAULT: Invalid chnl_obj. - * Requires: - * chnl_init(void) called. - * No thread must be blocked on this channel's I/O completion event. - * Ensures: - * 0: The I/O completion event for this channel is freed. - * chnl_obj is no longer valid. - */ -extern int chnl_close(struct chnl_object *chnl_obj); - /* * ======== chnl_create ======== * Purpose: diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbll.h b/drivers/staging/tidspbridge/include/dspbridge/dbll.h index b0186761466c..46a9e0027ea5 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dbll.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dbll.h @@ -42,18 +42,12 @@ extern bool dbll_init(void); extern int dbll_load(struct dbll_library_obj *lib, dbll_flags flags, struct dbll_attrs *attrs, u32 * entry); -extern int dbll_load_sect(struct dbll_library_obj *zl_lib, - char *sec_name, struct dbll_attrs *attrs); extern int dbll_open(struct dbll_tar_obj *target, char *file, dbll_flags flags, struct dbll_library_obj **lib_obj); extern int dbll_read_sect(struct dbll_library_obj *lib, char *name, char *buf, u32 size); -extern void dbll_set_attrs(struct dbll_tar_obj *target, - struct dbll_attrs *pattrs); extern void dbll_unload(struct dbll_library_obj *lib, struct dbll_attrs *attrs); -extern int dbll_unload_sect(struct dbll_library_obj *lib, - char *sect_name, struct dbll_attrs *attrs); #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE bool dbll_find_dsp_symbol(struct dbll_library_obj *zl_lib, u32 address, u32 offset_range, u32 *sym_addr_output, char *name_output); diff --git a/drivers/staging/tidspbridge/include/dspbridge/dblldefs.h b/drivers/staging/tidspbridge/include/dspbridge/dblldefs.h index d2b4fda34291..81821e554cc8 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dblldefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dblldefs.h @@ -485,12 +485,9 @@ struct dbll_fxns { dbll_get_sect_fxn get_sect_fxn; dbll_init_fxn init_fxn; dbll_load_fxn load_fxn; - dbll_load_sect_fxn load_sect_fxn; dbll_open_fxn open_fxn; dbll_read_sect_fxn read_sect_fxn; - dbll_set_attrs_fxn set_attrs_fxn; dbll_unload_fxn unload_fxn; - dbll_unload_sect_fxn unload_sect_fxn; }; #endif /* DBLDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dev.h b/drivers/staging/tidspbridge/include/dspbridge/dev.h index 357458fadd2a..4d4196b0221c 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dev.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dev.h @@ -94,43 +94,6 @@ extern int dev_create_device(struct dev_object const char *driver_file_name, struct cfg_devnode *dev_node_obj); -/* - * ======== dev_create_iva_device ======== - * Purpose: - * Called by the operating system to load the Bridge Driver for IVA. - * Parameters: - * device_obj: Ptr to location to receive the device object handle. - * driver_file_name: Name of Bridge driver PE DLL file to load. If the - * absolute path is not provided, the file is loaded - * through 'Bridge's module search path. - * host_config: Host configuration information, to be passed down - * to the Bridge driver when bridge_dev_create() is called. - * pDspConfig: DSP resources, to be passed down to the Bridge driver - * when bridge_dev_create() is called. - * dev_node_obj: Platform specific device node. - * Returns: - * 0: Module is loaded, device object has been created - * -ENOMEM: Insufficient memory to create needed resources. - * -EPERM: Unable to find Bridge driver entry point function. - * -ESPIPE: Unable to load ZL DLL. - * Requires: - * DEV Initialized. - * device_obj != NULL. - * driver_file_name != NULL. - * host_config != NULL. - * pDspConfig != NULL. - * Ensures: - * 0: *device_obj will contain handle to the new device object. - * Otherwise, does not create the device object, ensures the Bridge driver - * module is unloaded, and sets *device_obj to NULL. - */ -extern int dev_create_iva_device(struct dev_object - **device_obj, - const char *driver_file_name, - const struct cfg_hostres - *host_config, - struct cfg_devnode *dev_node_obj); - /* * ======== dev_create2 ======== * Purpose: @@ -541,24 +504,6 @@ extern void dev_exit(void); */ extern bool dev_init(void); -/* - * ======== dev_is_locked ======== - * Purpose: - * Predicate function to determine if the device has been - * locked by a client for exclusive access. - * Parameters: - * hdev_obj: Handle to device object created with - * dev_create_device(). - * Returns: - * 0: TRUE: device has been locked. - * 0: FALSE: device not locked. - * -EFAULT: hdev_obj was invalid. - * Requires: - * DEV Initialized. - * Ensures: - */ -extern int dev_is_locked(struct dev_object *hdev_obj); - /* * ======== dev_insert_proc_object ======== * Purpose: diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspio.h b/drivers/staging/tidspbridge/include/dspbridge/dspio.h index 88f5f90fe922..5c666b80463e 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspio.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspio.h @@ -34,7 +34,6 @@ extern int bridge_io_destroy(struct io_mgr *hio_mgr); extern int bridge_io_on_loaded(struct io_mgr *hio_mgr); -extern int iva_io_on_loaded(struct io_mgr *hio_mgr); extern int bridge_io_get_proc_load(struct io_mgr *hio_mgr, struct dsp_procloadstat *proc_lstat); diff --git a/drivers/staging/tidspbridge/include/dspbridge/host_os.h b/drivers/staging/tidspbridge/include/dspbridge/host_os.h index 6549898ac636..b1b8acb5d3c3 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/host_os.h +++ b/drivers/staging/tidspbridge/include/dspbridge/host_os.h @@ -57,13 +57,4 @@ extern struct platform_device *omap_dspbridge_dev; extern struct device *bridge; -#if defined(CONFIG_TIDSPBRIDGE) || defined(CONFIG_TIDSPBRIDGE_MODULE) -extern void dspbridge_reserve_sdram(void); -#else -static inline void dspbridge_reserve_sdram(void) -{ -} -#endif - -extern unsigned long dspbridge_get_mempool_base(void); #endif diff --git a/drivers/staging/tidspbridge/include/dspbridge/io.h b/drivers/staging/tidspbridge/include/dspbridge/io.h index bc346f9a01c1..da4683c87b38 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/io.h +++ b/drivers/staging/tidspbridge/include/dspbridge/io.h @@ -95,20 +95,4 @@ extern void io_exit(void); */ extern bool io_init(void); -/* - * ======== io_on_loaded ======== - * Purpose: - * Called when a program is loaded so IO manager can update its - * internal state. - * Parameters: - * hio_mgr: IOmanager object. - * Returns: - * 0: Success. - * -EFAULT: hio_mgr was invalid. - * Requires: - * io_init(void) called. - * Ensures: - */ -extern int io_on_loaded(struct io_mgr *hio_mgr); - #endif /* CHNL_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/io_sm.h b/drivers/staging/tidspbridge/include/dspbridge/io_sm.h index 056606a10a47..6a4c441269d7 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/io_sm.h +++ b/drivers/staging/tidspbridge/include/dspbridge/io_sm.h @@ -114,122 +114,6 @@ extern void io_request_chnl(struct io_mgr *io_manager, */ extern void iosm_schedule(struct io_mgr *io_manager); -/* - * DSP-DMA IO functions - */ - -/* - * ======== io_ddma_init_chnl_desc ======== - * Purpose: - * Initialize DSP DMA channel descriptor. - * Parameters: - * hio_mgr: Handle to a I/O manager. - * ddma_chnl_id: DDMA channel identifier. - * num_desc: Number of buffer descriptors(equals # of IOReqs & - * Chirps) - * dsp: Dsp address; - * Returns: - * Requires: - * ddma_chnl_id < DDMA_MAXDDMACHNLS - * num_desc > 0 - * pVa != NULL - * pDspPa != NULL - * - * Ensures: - */ -extern void io_ddma_init_chnl_desc(struct io_mgr *hio_mgr, u32 ddma_chnl_id, - u32 num_desc, void *dsp); - -/* - * ======== io_ddma_clear_chnl_desc ======== - * Purpose: - * Clear DSP DMA channel descriptor. - * Parameters: - * hio_mgr: Handle to a I/O manager. - * ddma_chnl_id: DDMA channel identifier. - * Returns: - * Requires: - * ddma_chnl_id < DDMA_MAXDDMACHNLS - * Ensures: - */ -extern void io_ddma_clear_chnl_desc(struct io_mgr *hio_mgr, u32 ddma_chnl_id); - -/* - * ======== io_ddma_request_chnl ======== - * Purpose: - * Request channel DSP-DMA from the DSP. Sets up SM descriptors and - * control fields in shared memory. - * Parameters: - * hio_mgr: Handle to a I/O manager. - * pchnl: Ptr to channel object - * chnl_packet_obj: Ptr to channel i/o request packet. - * Returns: - * Requires: - * pchnl != NULL - * pchnl->cio_reqs > 0 - * chnl_packet_obj != NULL - * Ensures: - */ -extern void io_ddma_request_chnl(struct io_mgr *hio_mgr, - struct chnl_object *pchnl, - struct chnl_irp *chnl_packet_obj, - u16 *mbx_val); - -/* - * Zero-copy IO functions - */ - -/* - * ======== io_ddzc_init_chnl_desc ======== - * Purpose: - * Initialize ZCPY channel descriptor. - * Parameters: - * hio_mgr: Handle to a I/O manager. - * zid: zero-copy channel identifier. - * Returns: - * Requires: - * ddma_chnl_id < DDMA_MAXZCPYCHNLS - * hio_mgr != Null - * Ensures: - */ -extern void io_ddzc_init_chnl_desc(struct io_mgr *hio_mgr, u32 zid); - -/* - * ======== io_ddzc_clear_chnl_desc ======== - * Purpose: - * Clear DSP ZC channel descriptor. - * Parameters: - * hio_mgr: Handle to a I/O manager. - * ch_id: ZC channel identifier. - * Returns: - * Requires: - * hio_mgr is valid - * ch_id < DDMA_MAXZCPYCHNLS - * Ensures: - */ -extern void io_ddzc_clear_chnl_desc(struct io_mgr *hio_mgr, u32 ch_id); - -/* - * ======== io_ddzc_request_chnl ======== - * Purpose: - * Request zero-copy channel transfer. Sets up SM descriptors and - * control fields in shared memory. - * Parameters: - * hio_mgr: Handle to a I/O manager. - * pchnl: Ptr to channel object - * chnl_packet_obj: Ptr to channel i/o request packet. - * Returns: - * Requires: - * pchnl != NULL - * pchnl->cio_reqs > 0 - * chnl_packet_obj != NULL - * Ensures: - */ -extern void io_ddzc_request_chnl(struct io_mgr *hio_mgr, - struct chnl_object *pchnl, - struct chnl_irp *chnl_packet_obj, - u16 *mbx_val); - /* * ======== io_sh_msetting ======== * Purpose: @@ -253,25 +137,6 @@ extern int io_sh_msetting(struct io_mgr *hio_mgr, u8 desc, void *pargs); /* Maximum channel bufsize that can be used. */ extern u32 io_buf_size(struct io_mgr *hio_mgr); -extern u32 io_read_value(struct bridge_dev_context *dev_ctxt, u32 dsp_addr); - -extern void io_write_value(struct bridge_dev_context *dev_ctxt, - u32 dsp_addr, u32 value); - -extern u32 io_read_value_long(struct bridge_dev_context *dev_ctxt, - u32 dsp_addr); - -extern void io_write_value_long(struct bridge_dev_context *dev_ctxt, - u32 dsp_addr, u32 value); - -extern void io_or_set_value(struct bridge_dev_context *dev_ctxt, - u32 dsp_addr, u32 value); - -extern void io_and_set_value(struct bridge_dev_context *dev_ctxt, - u32 dsp_addr, u32 value); - -extern void io_sm_init(void); - #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE /* * ========print_dsp_trace_buffer ======== diff --git a/drivers/staging/tidspbridge/include/dspbridge/node.h b/drivers/staging/tidspbridge/include/dspbridge/node.h index 49ed5c1128e5..4c5558c6ecb4 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/node.h +++ b/drivers/staging/tidspbridge/include/dspbridge/node.h @@ -112,24 +112,6 @@ extern int node_alloc_msg_buf(struct node_object *hnode, */ extern int node_change_priority(struct node_object *hnode, s32 prio); -/* - * ======== node_close_orphans ======== - * Purpose: - * Delete all nodes whose owning processor is being destroyed. - * Parameters: - * hnode_mgr: Node manager object. - * proc: Handle to processor object being destroyed. - * Returns: - * 0: Success. - * -EPERM: Unable to delete all nodes belonging to proc. - * Requires: - * Valid hnode_mgr. - * proc != NULL. - * Ensures: - */ -extern int node_close_orphans(struct node_mgr *hnode_mgr, - struct proc_object *proc); - /* * ======== node_connect ======== * Purpose: diff --git a/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h b/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h index dfaf0c6c06f1..8c9c902a0432 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h +++ b/drivers/staging/tidspbridge/include/dspbridge/resourcecleanup.h @@ -17,23 +17,12 @@ #include #include -extern int drv_get_proc_ctxt_list(struct process_context **pctxt, - struct drv_object *hdrv_obj); - -extern int drv_insert_proc_context(struct drv_object *driver_obj, - void *process_ctxt); - extern int drv_remove_all_dmm_res_elements(void *process_ctxt); extern int drv_remove_all_node_res_elements(void *process_ctxt); -extern int drv_proc_set_pid(void *ctxt, s32 process); - extern int drv_remove_all_resources(void *process_ctxt); -extern int drv_remove_proc_context(struct drv_object *driver_obj, - void *pr_ctxt); - extern int drv_insert_node_res_element(void *hnode, void *node_resource, void *process_ctxt); diff --git a/drivers/staging/tidspbridge/include/dspbridge/strm.h b/drivers/staging/tidspbridge/include/dspbridge/strm.h index 3e4671e7f91b..613fe53dd239 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/strm.h +++ b/drivers/staging/tidspbridge/include/dspbridge/strm.h @@ -141,25 +141,6 @@ extern int strm_free_buffer(struct strm_res_object *strmres, u8 **ap_buffer, u32 num_bufs, struct process_context *pr_ctxt); -/* - * ======== strm_get_event_handle ======== - * Purpose: - * Get stream's user event handle. This function is used when closing - * a stream, so the event can be closed. - * Parameter: - * stream_obj: Stream handle returned from strm_open(). - * ph_event: Location to store event handle on output. - * Returns: - * 0: Success. - * -EFAULT: Invalid stream_obj. - * Requires: - * strm_init(void) called. - * ph_event != NULL. - * Ensures: - */ -extern int strm_get_event_handle(struct strm_object *stream_obj, - void **ph_event); - /* * ======== strm_get_info ======== * Purpose: @@ -275,27 +256,6 @@ extern int strm_open(struct node_object *hnode, u32 dir, struct strm_res_object **strmres, struct process_context *pr_ctxt); -/* - * ======== strm_prepare_buffer ======== - * Purpose: - * Prepare a data buffer not allocated by DSPStream_AllocateBuffers() - * for use with a stream. - * Parameter: - * stream_obj: Stream handle returned from strm_open(). - * usize: Size (GPP bytes) of the buffer. - * pbuffer: Buffer address. - * Returns: - * 0: Success. - * -EFAULT: Invalid stream_obj. - * -EPERM: Failure occurred, unable to prepare buffer. - * Requires: - * strm_init(void) called. - * pbuffer != NULL. - * Ensures: - */ -extern int strm_prepare_buffer(struct strm_object *stream_obj, - u32 usize, u8 *pbuffer); - /* * ======== strm_reclaim ======== * Purpose: @@ -379,26 +339,4 @@ extern int strm_register_notify(struct strm_object *stream_obj, extern int strm_select(struct strm_object **strm_tab, u32 strms, u32 *pmask, u32 utimeout); -/* - * ======== strm_unprepare_buffer ======== - * Purpose: - * Unprepare a data buffer that was previously prepared for a stream - * with DSPStream_PrepareBuffer(), and that will no longer be used with - * the stream. - * Parameter: - * stream_obj: Stream handle returned from strm_open(). - * usize: Size (GPP bytes) of the buffer. - * pbuffer: Buffer address. - * Returns: - * 0: Success. - * -EFAULT: Invalid stream_obj. - * -EPERM: Failure occurred, unable to unprepare buffer. - * Requires: - * strm_init(void) called. - * pbuffer != NULL. - * Ensures: - */ -extern int strm_unprepare_buffer(struct strm_object *stream_obj, - u32 usize, u8 *pbuffer); - #endif /* STRM_ */ diff --git a/drivers/staging/tidspbridge/pmgr/cod.c b/drivers/staging/tidspbridge/pmgr/cod.c index 52989ab67cfb..db29a1955cbb 100644 --- a/drivers/staging/tidspbridge/pmgr/cod.c +++ b/drivers/staging/tidspbridge/pmgr/cod.c @@ -78,12 +78,9 @@ static struct dbll_fxns ldr_fxns = { (dbll_get_sect_fxn) dbll_get_sect, (dbll_init_fxn) dbll_init, (dbll_load_fxn) dbll_load, - (dbll_load_sect_fxn) dbll_load_sect, (dbll_open_fxn) dbll_open, (dbll_read_sect_fxn) dbll_read_sect, - (dbll_set_attrs_fxn) dbll_set_attrs, (dbll_unload_fxn) dbll_unload, - (dbll_unload_sect_fxn) dbll_unload_sect, }; static bool no_op(void); diff --git a/drivers/staging/tidspbridge/pmgr/dbll.c b/drivers/staging/tidspbridge/pmgr/dbll.c index 878aa50718ee..2f46b0603d21 100644 --- a/drivers/staging/tidspbridge/pmgr/dbll.c +++ b/drivers/staging/tidspbridge/pmgr/dbll.c @@ -567,18 +567,6 @@ int dbll_load(struct dbll_library_obj *lib, dbll_flags flags, return status; } -/* - * ======== dbll_load_sect ======== - * Not supported for COFF. - */ -int dbll_load_sect(struct dbll_library_obj *zl_lib, char *sec_name, - struct dbll_attrs *attrs) -{ - DBC_REQUIRE(zl_lib); - - return -ENOSYS; -} - /* * ======== dbll_open ======== */ @@ -793,22 +781,6 @@ func_cont: return status; } -/* - * ======== dbll_set_attrs ======== - * Set the attributes of the target. - */ -void dbll_set_attrs(struct dbll_tar_obj *target, struct dbll_attrs *pattrs) -{ - struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(zl_target); - DBC_REQUIRE(pattrs != NULL); - - if ((pattrs != NULL) && (zl_target != NULL)) - zl_target->attrs = *pattrs; - -} - /* * ======== dbll_unload ======== */ @@ -847,19 +819,6 @@ func_end: DBC_ENSURE(zl_lib->load_ref >= 0); } -/* - * ======== dbll_unload_sect ======== - * Not supported for COFF. - */ -int dbll_unload_sect(struct dbll_library_obj *lib, char *sec_name, - struct dbll_attrs *attrs) -{ - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(sec_name != NULL); - - return -ENOSYS; -} - /* * ======== dof_close ======== */ diff --git a/drivers/staging/tidspbridge/rmgr/nldr.c b/drivers/staging/tidspbridge/rmgr/nldr.c index 28354bbf1aeb..d19cdb0f0860 100644 --- a/drivers/staging/tidspbridge/rmgr/nldr.c +++ b/drivers/staging/tidspbridge/rmgr/nldr.c @@ -260,12 +260,9 @@ static struct dbll_fxns ldr_fxns = { (dbll_get_sect_fxn) dbll_get_sect, (dbll_init_fxn) dbll_init, (dbll_load_fxn) dbll_load, - (dbll_load_sect_fxn) dbll_load_sect, (dbll_open_fxn) dbll_open, (dbll_read_sect_fxn) dbll_read_sect, - (dbll_set_attrs_fxn) dbll_set_attrs, (dbll_unload_fxn) dbll_unload, - (dbll_unload_sect_fxn) dbll_unload_sect, }; static u32 refs; /* module reference count */ -- cgit v1.2.3 From 5db9e2bf44ec0dcf36e513499c77a294a9dc2774 Mon Sep 17 00:00:00 2001 From: Armando Uribe Date: Fri, 17 Dec 2010 01:18:31 -0600 Subject: staging: tidspbridge: Remove unused structs Remove unused structs and its dependencies, like references in other structs or as arguments of certain functions. Signed-off-by: Armando Uribe Signed-off-by: Omar Ramirez Luna --- .../tidspbridge/include/dspbridge/cfgdefs.h | 6 --- .../staging/tidspbridge/include/dspbridge/cod.h | 10 +---- .../tidspbridge/include/dspbridge/dbldefs.h | 49 ---------------------- .../staging/tidspbridge/include/dspbridge/drv.h | 14 ------- .../tidspbridge/include/dspbridge/dspapi-ioctl.h | 8 ---- .../staging/tidspbridge/include/dspbridge/ldr.h | 29 ------------- drivers/staging/tidspbridge/pmgr/cod.c | 11 +---- drivers/staging/tidspbridge/pmgr/dev.c | 8 +--- drivers/staging/tidspbridge/rmgr/dbdcd.c | 2 +- 9 files changed, 4 insertions(+), 133 deletions(-) delete mode 100644 drivers/staging/tidspbridge/include/dspbridge/ldr.h (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h index c3f04f874204..0589a0a80f50 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h @@ -58,10 +58,4 @@ struct cfg_hostres { void __iomem *dw_dmmu_base; }; -struct cfg_dspmemdesc { - u32 mem_type; /* Type of memory. */ - u32 ul_min; /* Minimum amount of memory of this type. */ - u32 ul_max; /* Maximum amount of memory of this type. */ -}; - #endif /* CFGDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/cod.h b/drivers/staging/tidspbridge/include/dspbridge/cod.h index 5efea91625b2..53bd4bb8b0bb 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cod.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cod.h @@ -37,11 +37,6 @@ struct cod_manager; /* COD library handle */ struct cod_libraryobj; -/* COD attributes */ -struct cod_attrs { - u32 ul_reserved; -}; - /* * Function prototypes for writing memory to a DSP system, allocating * and freeing DSP memory. @@ -76,8 +71,6 @@ extern void cod_close(struct cod_libraryobj *lib); * Parameters: * manager: created manager object * str_zl_file: ZL DLL filename, of length < COD_MAXPATHLENGTH. - * attrs: attributes to be used by this object. A NULL value - * will cause default attrs to be used. * Returns: * 0: Success. * -ESPIPE: ZL_Create failed. @@ -89,8 +82,7 @@ extern void cod_close(struct cod_libraryobj *lib); * Ensures: */ extern int cod_create(struct cod_manager **mgr, - char *str_zl_file, - const struct cod_attrs *attrs); + char *str_zl_file); /* * ======== cod_delete ======== diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbldefs.h b/drivers/staging/tidspbridge/include/dspbridge/dbldefs.h index 9973098ea64b..5cf9dad8b0a5 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dbldefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dbldefs.h @@ -24,26 +24,6 @@ */ typedef s32 dbl_flags; -/* - * ======== dbl_sect_info ======== - * For collecting info on overlay sections - */ -struct dbl_sect_info { - const char *name; /* name of section */ - u32 sect_run_addr; /* run address of section */ - u32 sect_load_addr; /* load address of section */ - u32 size; /* size of section (target MAUs) */ - dbl_flags type; /* Code, data, or BSS */ -}; - -/* - * ======== dbl_symbol ======== - * (Needed for dynamic load library) - */ -struct dbl_symbol { - u32 value; -}; - /* * ======== dbl_alloc_fxn ======== * Allocate memory function. Allocate or reserve (if reserved == TRUE) @@ -98,33 +78,4 @@ typedef bool(*dbl_sym_lookup) (void *handle, void *parg, void *rmm_handle, typedef s32(*dbl_write_fxn) (void *hdl, u32 dsp_address, void *buf, u32 n, s32 mtype); -/* - * ======== dbl_attrs ======== - */ -struct dbl_attrs { - dbl_alloc_fxn alloc; - dbl_free_fxn free; - void *rmm_handle; /* Handle to pass to alloc, free functions */ - dbl_write_fxn write; - void *input_params; /* Handle to pass to write, cinit function */ - - dbl_log_write_fxn log_write; - void *log_write_handle; - - /* Symbol matching function and handle to pass to it */ - dbl_sym_lookup sym_lookup; - void *sym_handle; - void *sym_arg; - - /* - * These file manipulation functions should be compatible with the - * "C" run time library functions of the same name. - */ - s32(*fread) (void *, size_t, size_t, void *); - s32(*fseek) (void *, long, int); - s32(*ftell) (void *); - s32(*fclose) (void *); - void *(*fopen) (const char *, const char *); -}; - #endif /* DBLDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/drv.h b/drivers/staging/tidspbridge/include/dspbridge/drv.h index adb28ec946bb..26972ad86bba 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/drv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/drv.h @@ -96,17 +96,6 @@ struct dmm_rsv_object { u32 dsp_reserved_addr; }; -/* New structure (member of process context) abstracts DMM resource info */ -struct dspheap_res_object { - s32 heap_allocated; /* DMM status */ - u32 ul_mpu_addr; - u32 ul_dsp_addr; - u32 ul_dsp_res_addr; - u32 heap_size; - void *hprocessor; - struct dspheap_res_object *next; -}; - /* New structure (member of process context) abstracts stream resource info */ struct strm_res_object { s32 stream_allocated; /* Stream status */ @@ -151,9 +140,6 @@ struct process_context { struct list_head dmm_rsv_list; spinlock_t dmm_rsv_lock; - /* DSP Heap resources */ - struct dspheap_res_object *pdspheap_list; - /* Stream resources */ struct idr *stream_id; }; diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h index 8da5bd8ede85..8ad9ace1a82a 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h @@ -118,10 +118,6 @@ union trapped_args { struct dsp_notification __user *hnotification; } args_proc_register_notify; - struct { - void *hprocessor; - } args_proc_start; - struct { void *hprocessor; u32 ul_size; @@ -163,10 +159,6 @@ union trapped_args { u32 ul_flags; } args_proc_flushmemory; - struct { - void *hprocessor; - } args_proc_stop; - struct { void *hprocessor; void *pmpu_addr; diff --git a/drivers/staging/tidspbridge/include/dspbridge/ldr.h b/drivers/staging/tidspbridge/include/dspbridge/ldr.h deleted file mode 100644 index 6a0269cd07ef..000000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/ldr.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * ldr.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Provide module loading services and symbol export services. - * - * Notes: - * This service is meant to be used by modules of the DSP/BIOS Bridge - * driver. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef LDR_ -#define LDR_ - -/* Loader objects: */ -struct ldr_module; - -#endif /* LDR_ */ diff --git a/drivers/staging/tidspbridge/pmgr/cod.c b/drivers/staging/tidspbridge/pmgr/cod.c index db29a1955cbb..17ea57d0d48b 100644 --- a/drivers/staging/tidspbridge/pmgr/cod.c +++ b/drivers/staging/tidspbridge/pmgr/cod.c @@ -33,9 +33,6 @@ /* ----------------------------------- Trace & Debug */ #include -/* ----------------------------------- OS Adaptation Layer */ -#include - /* ----------------------------------- Platform Manager */ /* Include appropriate loader header file */ #include @@ -51,7 +48,6 @@ struct cod_manager { struct dbll_library_obj *base_lib; bool loaded; /* Base library loaded? */ u32 ul_entry; - struct ldr_module *dll_obj; struct dbll_fxns fxns; struct dbll_attrs attrs; char sz_zl_file[COD_MAXPATHLENGTH]; @@ -206,8 +202,7 @@ void cod_close(struct cod_libraryobj *lib) * dynamically loaded object files. * */ -int cod_create(struct cod_manager **mgr, char *str_zl_file, - const struct cod_attrs *attrs) +int cod_create(struct cod_manager **mgr, char *str_zl_file) { struct cod_manager *mgr_new; struct dbll_attrs zl_attrs; @@ -219,10 +214,6 @@ int cod_create(struct cod_manager **mgr, char *str_zl_file, /* assume failure */ *mgr = NULL; - /* we don't support non-default attrs yet */ - if (attrs != NULL) - return -ENOSYS; - mgr_new = kzalloc(sizeof(struct cod_manager), GFP_KERNEL); if (mgr_new == NULL) return -ENOMEM; diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c index b95cd206c1fd..0f10a50cf6f9 100644 --- a/drivers/staging/tidspbridge/pmgr/dev.c +++ b/drivers/staging/tidspbridge/pmgr/dev.c @@ -27,9 +27,6 @@ /* ----------------------------------- Trace & Debug */ #include -/* ----------------------------------- OS Adaptation Layer */ -#include - /* ----------------------------------- Platform Manager */ #include #include @@ -75,7 +72,6 @@ struct dev_object { struct io_mgr *hio_mgr; /* IO manager (CHNL, msg_ctrl) */ struct cmm_object *hcmm_mgr; /* SM memory manager. */ struct dmm_object *dmm_mgr; /* Dynamic memory manager. */ - struct ldr_module *module_obj; /* Bridge Module handle. */ u32 word_size; /* DSP word size: quick access. */ struct drv_object *hdrv_obj; /* Driver Object */ /* List of Processors attached to this device */ @@ -139,7 +135,6 @@ int dev_create_device(struct dev_object **device_obj, struct cfg_devnode *dev_node_obj) { struct cfg_hostres *host_res; - struct ldr_module *module_obj = NULL; struct bridge_drv_interface *drv_fxns = NULL; struct dev_object *dev_obj = NULL; struct chnl_mgrattrs mgr_attrs; @@ -179,7 +174,6 @@ int dev_create_device(struct dev_object **device_obj, if (dev_obj) { /* Fill out the rest of the Dev Object structure: */ dev_obj->dev_node_obj = dev_node_obj; - dev_obj->module_obj = module_obj; dev_obj->cod_mgr = NULL; dev_obj->hchnl_mgr = NULL; dev_obj->hdeh_mgr = NULL; @@ -953,7 +947,7 @@ static int init_cod_mgr(struct dev_object *dev_obj) DBC_REQUIRE(refs > 0); DBC_REQUIRE(!dev_obj || (dev_obj->cod_mgr == NULL)); - status = cod_create(&dev_obj->cod_mgr, sz_dummy_file, NULL); + status = cod_create(&dev_obj->cod_mgr, sz_dummy_file); return status; } diff --git a/drivers/staging/tidspbridge/rmgr/dbdcd.c b/drivers/staging/tidspbridge/rmgr/dbdcd.c index b76f26caeab2..9e12a2c07f41 100644 --- a/drivers/staging/tidspbridge/rmgr/dbdcd.c +++ b/drivers/staging/tidspbridge/rmgr/dbdcd.c @@ -134,7 +134,7 @@ int dcd_create_manager(char *sz_zl_dll_name, DBC_REQUIRE(refs >= 0); DBC_REQUIRE(dcd_mgr); - status = cod_create(&cod_mgr, sz_zl_dll_name, NULL); + status = cod_create(&cod_mgr, sz_zl_dll_name); if (status) goto func_end; -- cgit v1.2.3 From 77927240749e7248fd637c5dadb6893f6b0381ab Mon Sep 17 00:00:00 2001 From: Armando Uribe Date: Fri, 17 Dec 2010 01:18:32 -0600 Subject: staging: tidspbridge: Remove unused typedefs Unsed typedefs are removed, because of there are not used or because previous clean ups. Signed-off-by: Armando Uribe Signed-off-by: Omar Ramirez Luna --- .../tidspbridge/include/dspbridge/dbldefs.h | 81 ---------------------- .../tidspbridge/include/dspbridge/dblldefs.h | 62 ----------------- 2 files changed, 143 deletions(-) delete mode 100644 drivers/staging/tidspbridge/include/dspbridge/dbldefs.h (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbldefs.h b/drivers/staging/tidspbridge/include/dspbridge/dbldefs.h deleted file mode 100644 index 5cf9dad8b0a5..000000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dbldefs.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * dbldefs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef DBLDEFS_ -#define DBLDEFS_ - - -/* - * ======== dbl_flags ======== - * Specifies whether to load code, data, or symbols - */ -typedef s32 dbl_flags; - -/* - * ======== dbl_alloc_fxn ======== - * Allocate memory function. Allocate or reserve (if reserved == TRUE) - * "size" bytes of memory from segment "space" and return the address in - * *dsp_address (or starting at *dsp_address if reserve == TRUE). Returns 0 on - * success, or an error code on failure. - */ -typedef s32(*dbl_alloc_fxn) (void *hdl, s32 space, u32 size, u32 align, - u32 *dsp_address, s32 seg_id, s32 req, - bool reserved); - -/* - * ======== dbl_free_fxn ======== - * Free memory function. Free, or unreserve (if reserved == TRUE) "size" - * bytes of memory from segment "space" - */ -typedef bool(*dbl_free_fxn) (void *hdl, u32 addr, s32 space, u32 size, - bool reserved); - -/* - * ======== dbl_log_write_fxn ======== - * Function to call when writing data from a section, to log the info. - * Can be NULL if no logging is required. - */ -typedef int(*dbl_log_write_fxn) (void *handle, - struct dbl_sect_info *sect, u32 addr, - u32 bytes); - -/* - * ======== dbl_sym_lookup ======== - * Symbol lookup function - Find the symbol name and return its value. - * - * Parameters: - * handle - Opaque handle - * parg - Opaque argument. - * name - Name of symbol to lookup. - * sym - Location to store address of symbol structure. - * - * Returns: - * TRUE: Success (symbol was found). - * FALSE: Failed to find symbol. - */ -typedef bool(*dbl_sym_lookup) (void *handle, void *parg, void *rmm_handle, - const char *name, struct dbl_symbol ** sym); - -/* - * ======== dbl_write_fxn ======== - * Write memory function. Write "n" HOST bytes of memory to segment "mtype" - * starting at address "dsp_address" from the buffer "buf". The buffer is - * formatted as an array of words appropriate for the DSP. - */ -typedef s32(*dbl_write_fxn) (void *hdl, u32 dsp_address, void *buf, - u32 n, s32 mtype); - -#endif /* DBLDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dblldefs.h b/drivers/staging/tidspbridge/include/dspbridge/dblldefs.h index 81821e554cc8..30e0aa0540de 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dblldefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dblldefs.h @@ -348,29 +348,6 @@ typedef bool(*dbll_init_fxn) (void); typedef int(*dbll_load_fxn) (struct dbll_library_obj *lib, dbll_flags flags, struct dbll_attrs *attrs, u32 *entry); - -/* - * ======== dbll_load_sect ======== - * Load a named section from an library (for overlay support). - * Parameters: - * lib - Handle returned from dbll_open(). - * sec_name - Name of section to load. - * attrs - Contains write function and handle to pass to it. - * Returns: - * 0: Success. - * -ENXIO: Section not found. - * -ENOSYS: Function not implemented. - * Requires: - * Valid lib. - * sec_name != NULL. - * attrs != NULL. - * attrs->write != NULL. - * Ensures: - */ -typedef int(*dbll_load_sect_fxn) (struct dbll_library_obj *lib, - char *sz_sect_name, - struct dbll_attrs *attrs); - /* * ======== dbll_open ======== * dbll_open() returns a library handle that can be used to load/unload @@ -421,23 +398,6 @@ typedef int(*dbll_open_fxn) (struct dbll_tar_obj *target, char *file, typedef int(*dbll_read_sect_fxn) (struct dbll_library_obj *lib, char *name, char *content, u32 cont_size); - -/* - * ======== dbll_set_attrs ======== - * Set the attributes of the target. - * Parameters: - * target - Handle returned from dbll_create(). - * pattrs - New attributes. - * Returns: - * Requires: - * DBL initialized. - * Valid target. - * pattrs != NULL. - * Ensures: - */ -typedef void (*dbll_set_attrs_fxn) (struct dbll_tar_obj *target, - struct dbll_attrs *attrs); - /* * ======== dbll_unload ======== * Unload library loaded with dbll_load(). @@ -452,28 +412,6 @@ typedef void (*dbll_set_attrs_fxn) (struct dbll_tar_obj *target, */ typedef void (*dbll_unload_fxn) (struct dbll_library_obj *library, struct dbll_attrs *attrs); - -/* - * ======== dbll_unload_sect ======== - * Unload a named section from an library (for overlay support). - * Parameters: - * lib - Handle returned from dbll_open(). - * sec_name - Name of section to load. - * attrs - Contains free() function and handle to pass to it. - * Returns: - * 0: Success. - * -ENXIO: Named section not found. - * -ENOSYS - * Requires: - * DBL initialized. - * Valid lib. - * sec_name != NULL. - * Ensures: - */ -typedef int(*dbll_unload_sect_fxn) (struct dbll_library_obj *lib, - char *sz_sect_name, - struct dbll_attrs *attrs); - struct dbll_fxns { dbll_close_fxn close_fxn; dbll_create_fxn create_fxn; -- cgit v1.2.3 From 157bc26dacc2f30ee64fc7eea2babbdc65052803 Mon Sep 17 00:00:00 2001 From: Armando Uribe Date: Fri, 17 Dec 2010 01:18:33 -0600 Subject: staging: tidspbridge: Remove trivial header files Remove the header files that contains few declarations and can be merged onto more generic headers. Signed-off-by: Armando Uribe Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/core/tiomap3430_pwr.c | 4 +-- .../tidspbridge/include/dspbridge/dehdefs.h | 31 ------------------- .../staging/tidspbridge/include/dspbridge/dev.h | 4 +-- .../staging/tidspbridge/include/dspbridge/disp.h | 15 +++++++++- .../tidspbridge/include/dspbridge/dispdefs.h | 35 ---------------------- .../staging/tidspbridge/include/dspbridge/drv.h | 4 ++- .../tidspbridge/include/dspbridge/drvdefs.h | 25 ---------------- .../tidspbridge/include/dspbridge/dspdefs.h | 4 +-- .../staging/tidspbridge/include/dspbridge/dspio.h | 3 +- drivers/staging/tidspbridge/include/dspbridge/io.h | 13 +++++++- .../staging/tidspbridge/include/dspbridge/io_sm.h | 7 ++++- .../staging/tidspbridge/include/dspbridge/iodefs.h | 34 --------------------- .../staging/tidspbridge/include/dspbridge/node.h | 2 +- .../staging/tidspbridge/include/dspbridge/pwr.h | 8 ++++- .../staging/tidspbridge/include/dspbridge/pwr_sh.h | 29 ------------------ drivers/staging/tidspbridge/pmgr/io.c | 1 - drivers/staging/tidspbridge/rmgr/drv_interface.c | 1 - drivers/staging/tidspbridge/rmgr/node.c | 1 - 18 files changed, 51 insertions(+), 170 deletions(-) delete mode 100644 drivers/staging/tidspbridge/include/dspbridge/dehdefs.h delete mode 100644 drivers/staging/tidspbridge/include/dspbridge/dispdefs.h delete mode 100644 drivers/staging/tidspbridge/include/dspbridge/drvdefs.h delete mode 100644 drivers/staging/tidspbridge/include/dspbridge/iodefs.h delete mode 100644 drivers/staging/tidspbridge/include/dspbridge/pwr_sh.h (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c index fb9026e1403c..8e2b50ff3dde 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c +++ b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c @@ -29,13 +29,13 @@ /* ----------------------------------- Platform Manager */ #include #include -#include +#include /* ------------------------------------ Hardware Abstraction Layer */ #include #include -#include +#include /* ----------------------------------- Bridge Driver */ #include diff --git a/drivers/staging/tidspbridge/include/dspbridge/dehdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dehdefs.h deleted file mode 100644 index 53414716f298..000000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dehdefs.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * dehdefs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Definition for Bridge driver module DEH. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef DEHDEFS_ -#define DEHDEFS_ - -#include /* shared mailbox codes */ - -/* DEH object manager */ -struct deh_mgr; - -/* Magic code used to determine if DSP signaled exception. */ -#define DEH_BASE MBX_DEH_BASE -#define DEH_LIMIT MBX_DEH_LIMIT - -#endif /* _DEHDEFS_H */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dev.h b/drivers/staging/tidspbridge/include/dspbridge/dev.h index 4d4196b0221c..37d1fff3cb95 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dev.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dev.h @@ -23,9 +23,9 @@ #include #include #include -#include +#include #include -#include +#include #include #include #include diff --git a/drivers/staging/tidspbridge/include/dspbridge/disp.h b/drivers/staging/tidspbridge/include/dspbridge/disp.h index 82bf721447a9..41738c5b268e 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/disp.h +++ b/drivers/staging/tidspbridge/include/dspbridge/disp.h @@ -22,7 +22,20 @@ #include #include #include -#include + +struct disp_object; + +/* Node Dispatcher attributes */ +struct disp_attr { + u32 ul_chnl_offset; /* Offset of channel ids reserved for RMS */ + /* Size of buffer for sending data to RMS */ + u32 ul_chnl_buf_size; + int proc_family; /* eg, 5000 */ + int proc_type; /* eg, 5510 */ + void *reserved1; /* Reserved for future use. */ + u32 reserved2; /* Reserved for future use. */ +}; + /* * ======== disp_create ======== diff --git a/drivers/staging/tidspbridge/include/dspbridge/dispdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dispdefs.h deleted file mode 100644 index 946551a3dbb2..000000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/dispdefs.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * dispdefs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Global DISP constants and types, shared by PROCESSOR, NODE, and DISP. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef DISPDEFS_ -#define DISPDEFS_ - -struct disp_object; - -/* Node Dispatcher attributes */ -struct disp_attr { - u32 ul_chnl_offset; /* Offset of channel ids reserved for RMS */ - /* Size of buffer for sending data to RMS */ - u32 ul_chnl_buf_size; - int proc_family; /* eg, 5000 */ - int proc_type; /* eg, 5510 */ - void *reserved1; /* Reserved for future use. */ - u32 reserved2; /* Reserved for future use. */ -}; - -#endif /* DISPDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/drv.h b/drivers/staging/tidspbridge/include/dspbridge/drv.h index 26972ad86bba..bcb28171132b 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/drv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/drv.h @@ -23,9 +23,11 @@ #include -#include #include +/* Bridge Driver Object */ +struct drv_object; + /* Provide the DSP Internal memory windows that can be accessed from L3 address * space */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/drvdefs.h b/drivers/staging/tidspbridge/include/dspbridge/drvdefs.h deleted file mode 100644 index 2920917bbc5f..000000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/drvdefs.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * drvdefs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Definition of common struct between dspdefs.h and drv.h. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef DRVDEFS_ -#define DRVDEFS_ - -/* Bridge Driver Object */ -struct drv_object; - -#endif /* DRVDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h index 2acbbb34bff3..4eaeb21727b7 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h @@ -32,9 +32,9 @@ #include #include #include -#include +#include #include -#include +#include #include /* Handle to Bridge driver's private device context. */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspio.h b/drivers/staging/tidspbridge/include/dspbridge/dspio.h index 5c666b80463e..66b64fadf197 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspio.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspio.h @@ -24,7 +24,8 @@ #define DSPIO_ #include -#include +#include + extern int bridge_io_create(struct io_mgr **io_man, struct dev_object *hdev_obj, diff --git a/drivers/staging/tidspbridge/include/dspbridge/io.h b/drivers/staging/tidspbridge/include/dspbridge/io.h index da4683c87b38..961598060f95 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/io.h +++ b/drivers/staging/tidspbridge/include/dspbridge/io.h @@ -22,7 +22,18 @@ #include #include -#include +/* IO Objects: */ +struct io_mgr; + +/* IO manager attributes: */ +struct io_attrs { + u8 birq; /* Channel's I/O IRQ number. */ + bool irq_shared; /* TRUE if the IRQ is shareable. */ + u32 word_size; /* DSP Word size. */ + u32 shm_base; /* Physical base address of shared memory. */ + u32 usm_length; /* Size (in bytes) of shared memory. */ +}; + /* * ======== io_create ======== diff --git a/drivers/staging/tidspbridge/include/dspbridge/io_sm.h b/drivers/staging/tidspbridge/include/dspbridge/io_sm.h index 6a4c441269d7..a054dad21333 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/io_sm.h +++ b/drivers/staging/tidspbridge/include/dspbridge/io_sm.h @@ -23,7 +23,12 @@ #include #include -#include +#include +#include /* shared mailbox codes */ + +/* Magic code used to determine if DSP signaled exception. */ +#define DEH_BASE MBX_DEH_BASE +#define DEH_LIMIT MBX_DEH_LIMIT #define IO_INPUT 0 #define IO_OUTPUT 1 diff --git a/drivers/staging/tidspbridge/include/dspbridge/iodefs.h b/drivers/staging/tidspbridge/include/dspbridge/iodefs.h deleted file mode 100644 index 31cbc9a71816..000000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/iodefs.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * iodefs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * System-wide channel objects and constants. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef IODEFS_ -#define IODEFS_ - -/* IO Objects: */ -struct io_mgr; - -/* IO manager attributes: */ -struct io_attrs { - u8 birq; /* Channel's I/O IRQ number. */ - bool irq_shared; /* TRUE if the IRQ is shareable. */ - u32 word_size; /* DSP Word size. */ - u32 shm_base; /* Physical base address of shared memory. */ - u32 usm_length; /* Size (in bytes) of shared memory. */ -}; - -#endif /* IODEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/node.h b/drivers/staging/tidspbridge/include/dspbridge/node.h index 4c5558c6ecb4..63739c8ffe0b 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/node.h +++ b/drivers/staging/tidspbridge/include/dspbridge/node.h @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include diff --git a/drivers/staging/tidspbridge/include/dspbridge/pwr.h b/drivers/staging/tidspbridge/include/dspbridge/pwr.h index a6dc783904ef..5e3ab2123aaa 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/pwr.h +++ b/drivers/staging/tidspbridge/include/dspbridge/pwr.h @@ -18,7 +18,13 @@ #define PWR_ #include -#include +#include + +/* valid sleep command codes that can be sent by GPP via mailbox: */ +#define PWR_DEEPSLEEP MBX_PM_DSPIDLE +#define PWR_EMERGENCYDEEPSLEEP MBX_PM_EMERGENCYSLEEP +#define PWR_WAKEUP MBX_PM_DSPWAKEUP + /* * ======== pwr_sleep_dsp ======== diff --git a/drivers/staging/tidspbridge/include/dspbridge/pwr_sh.h b/drivers/staging/tidspbridge/include/dspbridge/pwr_sh.h deleted file mode 100644 index c78a1b151015..000000000000 --- a/drivers/staging/tidspbridge/include/dspbridge/pwr_sh.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * pwr_sh.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Power Manager shared definitions (used on both GPP and DSP sides). - * - * Copyright (C) 2008 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef PWR_SH_ -#define PWR_SH_ - -#include - -/* valid sleep command codes that can be sent by GPP via mailbox: */ -#define PWR_DEEPSLEEP MBX_PM_DSPIDLE -#define PWR_EMERGENCYDEEPSLEEP MBX_PM_EMERGENCYSLEEP -#define PWR_WAKEUP MBX_PM_DSPWAKEUP - -#endif /* PWR_SH_ */ diff --git a/drivers/staging/tidspbridge/pmgr/io.c b/drivers/staging/tidspbridge/pmgr/io.c index 20cbb9fe40c2..0e8843fe31c2 100644 --- a/drivers/staging/tidspbridge/pmgr/io.c +++ b/drivers/staging/tidspbridge/pmgr/io.c @@ -31,7 +31,6 @@ /* ----------------------------------- This */ #include -#include #include /* ----------------------------------- Globals */ diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index 324fcdffb3b3..c43c7e3421c8 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c @@ -59,7 +59,6 @@ #include #include #include -#include #include #ifdef CONFIG_TIDSPBRIDGE_DVFS diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index b196a7af8414..27af99d512d0 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -64,7 +64,6 @@ #include #include -#include #include #include <_tiomap.h> -- cgit v1.2.3 From 92d0293038e49151367e38f751f327c8f2c066f6 Mon Sep 17 00:00:00 2001 From: "Ramos Falcon, Ernesto" Date: Mon, 20 Dec 2010 21:23:08 +0000 Subject: staging: tidspbridge: remove code referred by OPT_ZERO_COPY_LOADER Remove code referred by OPT_ZERO_COPY_LOADER since it is not used. Signed-off-by: Ernesto Ramos Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/dynload/cload.c | 60 ++++++++++------------------- 1 file changed, 20 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/dynload/cload.c b/drivers/staging/tidspbridge/dynload/cload.c index c85a5e88361d..d0cd4453f175 100644 --- a/drivers/staging/tidspbridge/dynload/cload.c +++ b/drivers/staging/tidspbridge/dynload/cload.c @@ -1131,9 +1131,6 @@ static void dload_data(struct dload_state *dlthis) u16 curr_sect; struct doff_scnhdr_t *sptr = dlthis->sect_hdrs; struct ldr_section_info *lptr = dlthis->ldr_sections; -#ifdef OPT_ZERO_COPY_LOADER - bool zero_copy = false; -#endif u8 *dest; struct { @@ -1192,17 +1189,6 @@ static void dload_data(struct dload_state *dlthis) return; } dest = ibuf.bufr; -#ifdef OPT_ZERO_COPY_LOADER - zero_copy = false; - if (!dload_check_type(sptr, DLOAD_CINIT) { - dlthis->myio->writemem(dlthis->myio, - &dest, - lptr->load_addr + - image_offset, - lptr, 0); - zero_copy = (dest != ibuf.bufr); - } -#endif /* End of determination */ if (dlthis->strm->read_buffer(dlthis->strm, @@ -1266,33 +1252,27 @@ static void dload_data(struct dload_state *dlthis) &ibuf.ipacket); cinit_processed = true; } else { -#ifdef OPT_ZERO_COPY_LOADER - if (!zero_copy) { -#endif - /* FIXME */ - if (!dlthis->myio-> - writemem(dlthis-> - myio, - ibuf.bufr, - lptr-> - load_addr + - image_offset, - lptr, - BYTE_TO_HOST - (ibuf. - ipacket. - packet_size))) { - DL_ERROR - ("Write to " - FMT_UI32 - " failed", - lptr-> - load_addr + - image_offset); - } -#ifdef OPT_ZERO_COPY_LOADER + /* FIXME */ + if (!dlthis->myio-> + writemem(dlthis-> + myio, + ibuf.bufr, + lptr-> + load_addr + + image_offset, + lptr, + BYTE_TO_HOST + (ibuf. + ipacket. + packet_size))) { + DL_ERROR + ("Write to " + FMT_UI32 + " failed", + lptr-> + load_addr + + image_offset); } -#endif } } image_offset += -- cgit v1.2.3 From b4da7fc381c51d42c231f97de912b89dbabe8928 Mon Sep 17 00:00:00 2001 From: Rene Sapiens Date: Tue, 18 Jan 2011 03:19:03 +0000 Subject: staging: tidspbridge: set1 remove hungarian from structs hungarian notation will be removed from the elements inside structures, the next varibles will be renamed: dw_api_reg_base api_reg_base dw_brd_state brd_state dw_chnl_buf_size chnl_buf_size dw_chnl_offset chnl_offset dw_cmd cmd dw_core_pm_base core_pm_base dw_dsp_base dsp_base dw_dsp_base_va dsp_base_va dw_dsp_bufs dsp_bufs dw_dsp_buf_size dsp_buf_size dw_dsp_clk_m2_base dsp_clk_m2_base dw_dsp_ext_base_addr dsp_ext_base_addr dw_dsp_phys_addr_offset dsp_phys_addr_offset dw_dsp_start_add dsp_start_add dw_err_mask err_mask dw_gpp_base_pa gpp_base_pa dw_api_clk_base api_clk_base dw_api_reg_base api_reg_base dw_arg arg dw_arg1 arg1 dw_arg2 arg2 dw_chnl_buf_size chnl_buf_size Signed-off-by: Rene Sapiens Signed-off-by: Armando Uribe Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/core/_tiomap.h | 14 +++--- drivers/staging/tidspbridge/core/chnl_sm.c | 6 +-- drivers/staging/tidspbridge/core/io_sm.c | 38 ++++++++-------- drivers/staging/tidspbridge/core/tiomap3430.c | 50 +++++++++++----------- drivers/staging/tidspbridge/core/tiomap3430_pwr.c | 38 ++++++++-------- drivers/staging/tidspbridge/core/tiomap_io.c | 42 +++++++++--------- drivers/staging/tidspbridge/core/ue_deh.c | 4 +- .../tidspbridge/include/dspbridge/_chnl_sm.h | 2 +- .../tidspbridge/include/dspbridge/cfgdefs.h | 10 ++--- .../tidspbridge/include/dspbridge/chnldefs.h | 2 +- .../tidspbridge/include/dspbridge/cmmdefs.h | 8 ++-- .../staging/tidspbridge/include/dspbridge/dbdefs.h | 8 ++-- .../tidspbridge/include/dspbridge/dspapi-ioctl.h | 4 +- drivers/staging/tidspbridge/pmgr/cmm.c | 22 +++++----- drivers/staging/tidspbridge/pmgr/dspapi.c | 4 +- drivers/staging/tidspbridge/rmgr/drv.c | 10 ++--- drivers/staging/tidspbridge/rmgr/node.c | 28 ++++++------ drivers/staging/tidspbridge/rmgr/strm.c | 2 +- 18 files changed, 146 insertions(+), 146 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index 1159a500f49d..80bc4755df10 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -320,22 +320,22 @@ static const struct bpwr_clk_t bpwr_clks[] = { /* This Bridge driver's device context: */ struct bridge_dev_context { struct dev_object *hdev_obj; /* Handle to Bridge device object. */ - u32 dw_dsp_base_addr; /* Arm's API to DSP virt base addr */ + u32 dsp_base_addr; /* Arm's API to DSP virt base addr */ /* * DSP External memory prog address as seen virtually by the OS on * the host side. */ - u32 dw_dsp_ext_base_addr; /* See the comment above */ - u32 dw_api_reg_base; /* API mem map'd registers */ + u32 dsp_ext_base_addr; /* See the comment above */ + u32 api_reg_base; /* API mem map'd registers */ void __iomem *dw_dsp_mmu_base; /* DSP MMU Mapped registers */ - u32 dw_api_clk_base; /* CLK Registers */ - u32 dw_dsp_clk_m2_base; /* DSP Clock Module m2 */ + u32 api_clk_base; /* CLK Registers */ + u32 dsp_clk_m2_base; /* DSP Clock Module m2 */ u32 dw_public_rhea; /* Pub Rhea */ u32 dw_int_addr; /* MB INTR reg */ u32 dw_tc_endianism; /* TC Endianism register */ u32 dw_test_base; /* DSP MMU Mapped registers */ u32 dw_self_loop; /* Pointer to the selfloop */ - u32 dw_dsp_start_add; /* API Boot vector */ + u32 dsp_start_add; /* API Boot vector */ u32 dw_internal_size; /* Internal memory size */ struct omap_mbox *mbox; /* Mail box handle */ @@ -348,7 +348,7 @@ struct bridge_dev_context { */ /* DMMU TLB entries */ struct bridge_ioctl_extproc atlb_entry[BRDIOCTL_NUMOFMMUTLB]; - u32 dw_brd_state; /* Last known board state. */ + u32 brd_state; /* Last known board state. */ /* TC Settings */ bool tc_word_swap_on; /* Traffic Controller Word Swap */ diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c index 2d06bb0989ac..a52262728755 100644 --- a/drivers/staging/tidspbridge/core/chnl_sm.c +++ b/drivers/staging/tidspbridge/core/chnl_sm.c @@ -196,7 +196,7 @@ func_cont: chnl_packet_obj->byte_size = byte_size; chnl_packet_obj->buf_size = buf_size; /* Only valid for output channel */ - chnl_packet_obj->dw_arg = dw_arg; + chnl_packet_obj->arg = dw_arg; chnl_packet_obj->status = (is_eos ? CHNL_IOCSTATEOS : CHNL_IOCSTATCOMPLETE); list_add_tail(&chnl_packet_obj->link, &pchnl->pio_requests); @@ -607,7 +607,7 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, ioc.pbuf = chnl_packet_obj->host_user_buf; ioc.byte_size = chnl_packet_obj->byte_size; ioc.buf_size = chnl_packet_obj->buf_size; - ioc.dw_arg = chnl_packet_obj->dw_arg; + ioc.arg = chnl_packet_obj->arg; ioc.status |= chnl_packet_obj->status; /* Place the used chirp on the free list: */ list_add_tail(&chnl_packet_obj->link, @@ -615,7 +615,7 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, } else { ioc.pbuf = NULL; ioc.byte_size = 0; - ioc.dw_arg = 0; + ioc.arg = 0; ioc.buf_size = 0; } /* Ensure invariant: If any IOC's are queued for this channel... */ diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index d4b9e141f3d5..913c7681d804 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -1113,7 +1113,7 @@ static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, pio_mgr->input, bytes); pchnl->bytes_moved += bytes; chnl_packet_obj->byte_size = bytes; - chnl_packet_obj->dw_arg = dw_arg; + chnl_packet_obj->arg = dw_arg; chnl_packet_obj->status = CHNL_IOCSTATCOMPLETE; if (bytes == 0) { @@ -1200,14 +1200,14 @@ static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr) msg_input = pio_mgr->msg_input; for (i = 0; i < num_msgs; i++) { /* Read the next message */ - addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.dw_cmd); - msg.msg.dw_cmd = + addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.cmd); + msg.msg.cmd = read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr); - addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.dw_arg1); - msg.msg.dw_arg1 = + addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.arg1); + msg.msg.arg1 = read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr); - addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.dw_arg2); - msg.msg.dw_arg2 = + addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.arg2); + msg.msg.arg2 = read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr); addr = (u32) &(((struct msg_dspmsg *)msg_input)->msgq_id); msg.msgq_id = @@ -1215,9 +1215,9 @@ static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr) msg_input += sizeof(struct msg_dspmsg); /* Determine which queue to put the message in */ - dev_dbg(bridge, "input msg: dw_cmd=0x%x dw_arg1=0x%x " - "dw_arg2=0x%x msgq_id=0x%x\n", msg.msg.dw_cmd, - msg.msg.dw_arg1, msg.msg.dw_arg2, msg.msgq_id); + dev_dbg(bridge, "input msg: cmd=0x%x arg1=0x%x " + "arg2=0x%x msgq_id=0x%x\n", msg.msg.cmd, + msg.msg.arg1, msg.msg.arg2, msg.msgq_id); /* * Interrupt may occur before shared memory and message * input locations have been set up. If all nodes were @@ -1228,14 +1228,14 @@ static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr) if (msg.msgq_id != msg_queue_obj->msgq_id) continue; /* Found it */ - if (msg.msg.dw_cmd == RMS_EXITACK) { + if (msg.msg.cmd == RMS_EXITACK) { /* * Call the node exit notification. * The exit message does not get * queued. */ (*hmsg_mgr->on_exit)(msg_queue_obj->arg, - msg.msg.dw_arg1); + msg.msg.arg1); break; } /* @@ -1367,7 +1367,7 @@ static void output_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, chnl_packet_obj->byte_size); pchnl->bytes_moved += chnl_packet_obj->byte_size; /* Write all 32 bits of arg */ - sm->arg = chnl_packet_obj->dw_arg; + sm->arg = chnl_packet_obj->arg; #if _CHNL_WORDSIZE == 2 /* Access can be different SM access word size (e.g. 16/32 bit words) */ sm->output_id = (u16) chnl_id; @@ -1430,16 +1430,16 @@ static void output_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr) addr = (u32) &msg_output->msgq_id; write_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr, val); - val = (pmsg->msg_data).msg.dw_cmd; - addr = (u32) &msg_output->msg.dw_cmd; + val = (pmsg->msg_data).msg.cmd; + addr = (u32) &msg_output->msg.cmd; write_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr, val); - val = (pmsg->msg_data).msg.dw_arg1; - addr = (u32) &msg_output->msg.dw_arg1; + val = (pmsg->msg_data).msg.arg1; + addr = (u32) &msg_output->msg.arg1; write_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr, val); - val = (pmsg->msg_data).msg.dw_arg2; - addr = (u32) &msg_output->msg.dw_arg2; + val = (pmsg->msg_data).msg.arg2; + addr = (u32) &msg_output->msg.arg2; write_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr, val); msg_output++; diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index ec713ed74413..ce0556d026c3 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -229,8 +229,8 @@ static struct notifier_block dsp_mbox_notifier = { static inline void flush_all(struct bridge_dev_context *dev_context) { - if (dev_context->dw_brd_state == BRD_DSP_HIBERNATION || - dev_context->dw_brd_state == BRD_HIBERNATION) + if (dev_context->brd_state == BRD_DSP_HIBERNATION || + dev_context->brd_state == BRD_HIBERNATION) wake_dsp(dev_context, NULL); hw_mmu_tlb_flush_all(dev_context->dw_dsp_mmu_base); @@ -306,7 +306,7 @@ static int bridge_brd_monitor(struct bridge_dev_context *dev_ctxt) dsp_clk_enable(DSP_CLK_IVA2); /* set the device state to IDLE */ - dev_context->dw_brd_state = BRD_IDLE; + dev_context->brd_state = BRD_IDLE; return 0; } @@ -323,16 +323,16 @@ static int bridge_brd_read(struct bridge_dev_context *dev_ctxt, int status = 0; struct bridge_dev_context *dev_context = dev_ctxt; u32 offset; - u32 dsp_base_addr = dev_ctxt->dw_dsp_base_addr; + u32 dsp_base_addr = dev_ctxt->dsp_base_addr; - if (dsp_addr < dev_context->dw_dsp_start_add) { + if (dsp_addr < dev_context->dsp_start_add) { status = -EPERM; return status; } /* change here to account for the 3 bands of the DSP internal memory */ - if ((dsp_addr - dev_context->dw_dsp_start_add) < + if ((dsp_addr - dev_context->dsp_start_add) < dev_context->dw_internal_size) { - offset = dsp_addr - dev_context->dw_dsp_start_add; + offset = dsp_addr - dev_context->dsp_start_add; } else { status = read_ext_dsp_data(dev_context, host_buff, dsp_addr, ul_num_bytes, mem_type); @@ -354,7 +354,7 @@ static int bridge_brd_set_state(struct bridge_dev_context *dev_ctxt, int status = 0; struct bridge_dev_context *dev_context = dev_ctxt; - dev_context->dw_brd_state = brd_state; + dev_context->brd_state = brd_state; return status; } @@ -616,10 +616,10 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, __raw_writel(0XCAFECAFE, dw_sync_addr); /* update board state */ - dev_context->dw_brd_state = BRD_RUNNING; + dev_context->brd_state = BRD_RUNNING; /* (void)chnlsm_enable_interrupt(dev_context); */ } else { - dev_context->dw_brd_state = BRD_UNKNOWN; + dev_context->brd_state = BRD_UNKNOWN; } } return status; @@ -642,7 +642,7 @@ static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt) struct omap_dsp_platform_data *pdata = omap_dspbridge_dev->dev.platform_data; - if (dev_context->dw_brd_state == BRD_STOPPED) + if (dev_context->brd_state == BRD_STOPPED) return status; /* as per TRM, it is advised to first drive the IVA2 to 'Standby' mode, @@ -667,10 +667,10 @@ static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt) udelay(10); /* Release the Ext Base virtual Address as the next DSP Program * may have a different load address */ - if (dev_context->dw_dsp_ext_base_addr) - dev_context->dw_dsp_ext_base_addr = 0; + if (dev_context->dsp_ext_base_addr) + dev_context->dsp_ext_base_addr = 0; - dev_context->dw_brd_state = BRD_STOPPED; /* update board state */ + dev_context->brd_state = BRD_STOPPED; /* update board state */ dsp_wdt_enable(false); @@ -706,7 +706,7 @@ static int bridge_brd_status(struct bridge_dev_context *dev_ctxt, int *board_state) { struct bridge_dev_context *dev_context = dev_ctxt; - *board_state = dev_context->dw_brd_state; + *board_state = dev_context->brd_state; return 0; } @@ -721,11 +721,11 @@ static int bridge_brd_write(struct bridge_dev_context *dev_ctxt, int status = 0; struct bridge_dev_context *dev_context = dev_ctxt; - if (dsp_addr < dev_context->dw_dsp_start_add) { + if (dsp_addr < dev_context->dsp_start_add) { status = -EPERM; return status; } - if ((dsp_addr - dev_context->dw_dsp_start_add) < + if ((dsp_addr - dev_context->dsp_start_add) < dev_context->dw_internal_size) { status = write_dsp_data(dev_ctxt, host_buff, dsp_addr, ul_num_bytes, mem_type); @@ -764,7 +764,7 @@ static int bridge_dev_create(struct bridge_dev_context goto func_end; } - dev_context->dw_dsp_start_add = (u32) OMAP_GEM_BASE; + dev_context->dsp_start_add = (u32) OMAP_GEM_BASE; dev_context->dw_self_loop = (u32) NULL; dev_context->dsp_per_clks = 0; dev_context->dw_internal_size = OMAP_DSP_SIZE; @@ -774,14 +774,14 @@ static int bridge_dev_create(struct bridge_dev_context dev_context->atlb_entry[entry_ndx].ul_gpp_pa = dev_context->atlb_entry[entry_ndx].ul_dsp_va = 0; } - dev_context->dw_dsp_base_addr = (u32) MEM_LINEAR_ADDRESS((void *) + dev_context->dsp_base_addr = (u32) MEM_LINEAR_ADDRESS((void *) (config_param-> dw_mem_base [3]), config_param-> dw_mem_length [3]); - if (!dev_context->dw_dsp_base_addr) + if (!dev_context->dsp_base_addr) status = -EPERM; pt_attrs = kzalloc(sizeof(struct pg_table_attrs), GFP_KERNEL); @@ -874,7 +874,7 @@ static int bridge_dev_create(struct bridge_dev_context if (!status) { dev_context->hdev_obj = hdev_obj; /* Store current board state. */ - dev_context->dw_brd_state = BRD_UNKNOWN; + dev_context->brd_state = BRD_UNKNOWN; dev_context->resources = resources; dsp_clk_enable(DSP_CLK_IVA2); bridge_brd_stop(dev_context); @@ -1032,8 +1032,8 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt) iounmap(host_res->dw_per_base); if (host_res->dw_per_pm_base) iounmap((void *)host_res->dw_per_pm_base); - if (host_res->dw_core_pm_base) - iounmap((void *)host_res->dw_core_pm_base); + if (host_res->core_pm_base) + iounmap((void *)host_res->core_pm_base); host_res->dw_mem_base[0] = (u32) NULL; host_res->dw_mem_base[2] = (u32) NULL; @@ -1070,7 +1070,7 @@ static int bridge_brd_mem_copy(struct bridge_dev_context *dev_ctxt, status = read_ext_dsp_data(dev_ctxt, host_buf, src_addr, copy_bytes, mem_type); if (!status) { - if (dest_addr < (dev_context->dw_dsp_start_add + + if (dest_addr < (dev_context->dsp_start_add + dev_context->dw_internal_size)) { /* Write to Internal memory */ status = write_dsp_data(dev_ctxt, host_buf, @@ -1104,7 +1104,7 @@ static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt, while (ul_remain_bytes > 0 && !status) { ul_bytes = ul_remain_bytes > BUFFERSIZE ? BUFFERSIZE : ul_remain_bytes; - if (dsp_addr < (dev_context->dw_dsp_start_add + + if (dsp_addr < (dev_context->dsp_start_add + dev_context->dw_internal_size)) { status = write_dsp_data(dev_ctxt, host_buff, dsp_addr, diff --git a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c index 8e2b50ff3dde..fff27d4392d9 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c +++ b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c @@ -118,7 +118,7 @@ int handle_hibernation_from_dsp(struct bridge_dev_context *dev_context) if (!status) { /* Update the Bridger Driver state */ - dev_context->dw_brd_state = BRD_DSP_HIBERNATION; + dev_context->brd_state = BRD_DSP_HIBERNATION; #ifdef CONFIG_TIDSPBRIDGE_DVFS status = dev_get_io_mgr(dev_context->hdev_obj, &hio_mgr); @@ -163,7 +163,7 @@ int sleep_dsp(struct bridge_dev_context *dev_context, u32 dw_cmd, if ((dw_cmd != PWR_DEEPSLEEP) && (dw_cmd != PWR_EMERGENCYDEEPSLEEP)) return -EINVAL; - switch (dev_context->dw_brd_state) { + switch (dev_context->brd_state) { case BRD_RUNNING: omap_mbox_save_ctx(dev_context->mbox); if (dsp_test_sleepstate == PWRDM_POWER_OFF) { @@ -223,9 +223,9 @@ int sleep_dsp(struct bridge_dev_context *dev_context, u32 dw_cmd, } else { /* Update the Bridger Driver state */ if (dsp_test_sleepstate == PWRDM_POWER_OFF) - dev_context->dw_brd_state = BRD_HIBERNATION; + dev_context->brd_state = BRD_HIBERNATION; else - dev_context->dw_brd_state = BRD_RETENTION; + dev_context->brd_state = BRD_RETENTION; /* Disable wdt on hibernation. */ dsp_wdt_enable(false); @@ -258,8 +258,8 @@ int wake_dsp(struct bridge_dev_context *dev_context, void *pargs) #ifdef CONFIG_PM /* Check the board state, if it is not 'SLEEP' then return */ - if (dev_context->dw_brd_state == BRD_RUNNING || - dev_context->dw_brd_state == BRD_STOPPED) { + if (dev_context->brd_state == BRD_RUNNING || + dev_context->brd_state == BRD_STOPPED) { /* The Device is in 'RET' or 'OFF' state and Bridge state is not * 'SLEEP', this means state inconsistency, so return */ return 0; @@ -269,7 +269,7 @@ int wake_dsp(struct bridge_dev_context *dev_context, void *pargs) sm_interrupt_dsp(dev_context, MBX_PM_DSPWAKEUP); /* Set the device state to RUNNIG */ - dev_context->dw_brd_state = BRD_RUNNING; + dev_context->brd_state = BRD_RUNNING; #endif /* CONFIG_PM */ return status; } @@ -351,12 +351,12 @@ int pre_scale_dsp(struct bridge_dev_context *dev_context, void *pargs) dev_dbg(bridge, "OPP: %s voltage_domain = %x, level = 0x%x\n", __func__, voltage_domain, level); - if ((dev_context->dw_brd_state == BRD_HIBERNATION) || - (dev_context->dw_brd_state == BRD_RETENTION) || - (dev_context->dw_brd_state == BRD_DSP_HIBERNATION)) { + if ((dev_context->brd_state == BRD_HIBERNATION) || + (dev_context->brd_state == BRD_RETENTION) || + (dev_context->brd_state == BRD_DSP_HIBERNATION)) { dev_dbg(bridge, "OPP: %s IVA in sleep. No message to DSP\n"); return 0; - } else if ((dev_context->dw_brd_state == BRD_RUNNING)) { + } else if ((dev_context->brd_state == BRD_RUNNING)) { /* Send a prenotificatio to DSP */ dev_dbg(bridge, "OPP: %s sent notification to DSP\n", __func__); sm_interrupt_dsp(dev_context, MBX_PM_SETPOINT_PRENOTIFY); @@ -390,14 +390,14 @@ int post_scale_dsp(struct bridge_dev_context *dev_context, level = *((u32 *) pargs + 1); dev_dbg(bridge, "OPP: %s voltage_domain = %x, level = 0x%x\n", __func__, voltage_domain, level); - if ((dev_context->dw_brd_state == BRD_HIBERNATION) || - (dev_context->dw_brd_state == BRD_RETENTION) || - (dev_context->dw_brd_state == BRD_DSP_HIBERNATION)) { + if ((dev_context->brd_state == BRD_HIBERNATION) || + (dev_context->brd_state == BRD_RETENTION) || + (dev_context->brd_state == BRD_DSP_HIBERNATION)) { /* Update the OPP value in shared memory */ io_sh_msetting(hio_mgr, SHM_CURROPP, &level); dev_dbg(bridge, "OPP: %s IVA in sleep. Wrote to shm\n", __func__); - } else if ((dev_context->dw_brd_state == BRD_RUNNING)) { + } else if ((dev_context->brd_state == BRD_RUNNING)) { /* Update the OPP value in shared memory */ io_sh_msetting(hio_mgr, SHM_CURROPP, &level); /* Send a post notification to DSP */ @@ -486,8 +486,8 @@ void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable) writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4); break; case BPWR_MCBSP1: - iva2_grpsel = readl(resources->dw_core_pm_base + 0xA8); - mpu_grpsel = readl(resources->dw_core_pm_base + 0xA4); + iva2_grpsel = readl(resources->core_pm_base + 0xA8); + mpu_grpsel = readl(resources->core_pm_base + 0xA4); if (enable) { iva2_grpsel |= OMAP3430_GRPSEL_MCBSP1_MASK; mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP1_MASK; @@ -495,8 +495,8 @@ void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable) mpu_grpsel |= OMAP3430_GRPSEL_MCBSP1_MASK; iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP1_MASK; } - writel(iva2_grpsel, resources->dw_core_pm_base + 0xA8); - writel(mpu_grpsel, resources->dw_core_pm_base + 0xA4); + writel(iva2_grpsel, resources->core_pm_base + 0xA8); + writel(mpu_grpsel, resources->core_pm_base + 0xA4); break; case BPWR_MCBSP2: iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8); diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c index ba2961049dad..09c9e873ce7c 100644 --- a/drivers/staging/tidspbridge/core/tiomap_io.c +++ b/drivers/staging/tidspbridge/core/tiomap_io.c @@ -61,7 +61,7 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt, u32 ul_tlb_base_virt = 0; u32 ul_shm_offset_virt = 0; u32 dw_ext_prog_virt_mem; - u32 dw_base_addr = dev_context->dw_dsp_ext_base_addr; + u32 dw_base_addr = dev_context->dsp_ext_base_addr; bool trace_read = false; if (!ul_shm_base_virt) { @@ -92,7 +92,7 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt, /* If reading from TRACE, force remap/unmap */ if (trace_read && dw_base_addr) { dw_base_addr = 0; - dev_context->dw_dsp_ext_base_addr = 0; + dev_context->dsp_ext_base_addr = 0; } if (!dw_base_addr) { @@ -148,14 +148,14 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt, dw_ext_prog_virt_mem -= ul_shm_offset_virt; dw_ext_prog_virt_mem += (ul_ext_base - ul_dyn_ext_base); - dev_context->dw_dsp_ext_base_addr = + dev_context->dsp_ext_base_addr = dw_ext_prog_virt_mem; /* - * This dw_dsp_ext_base_addr will get cleared + * This dsp_ext_base_addr will get cleared * only when the board is stopped. */ - if (!dev_context->dw_dsp_ext_base_addr) + if (!dev_context->dsp_ext_base_addr) status = -EPERM; } @@ -184,7 +184,7 @@ int write_dsp_data(struct bridge_dev_context *dev_context, u32 mem_type) { u32 offset; - u32 dw_base_addr = dev_context->dw_dsp_base_addr; + u32 dw_base_addr = dev_context->dsp_base_addr; struct cfg_hostres *resources = dev_context->resources; int status = 0; u32 base1, base2, base3; @@ -195,7 +195,7 @@ int write_dsp_data(struct bridge_dev_context *dev_context, if (!resources) return -EPERM; - offset = dsp_addr - dev_context->dw_dsp_start_add; + offset = dsp_addr - dev_context->dsp_start_add; if (offset < base1) { dw_base_addr = MEM_LINEAR_ADDRESS(resources->dw_mem_base[2], resources->dw_mem_length[2]); @@ -230,7 +230,7 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, u32 ul_num_bytes, u32 mem_type, bool dynamic_load) { - u32 dw_base_addr = dev_context->dw_dsp_ext_base_addr; + u32 dw_base_addr = dev_context->dsp_ext_base_addr; u32 dw_offset = 0; u8 temp_byte1, temp_byte2; u8 remain_byte[4]; @@ -263,8 +263,8 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, if ((dynamic_load || trace_load) && dw_base_addr) { dw_base_addr = 0; MEM_UNMAP_LINEAR_ADDRESS((void *) - dev_context->dw_dsp_ext_base_addr); - dev_context->dw_dsp_ext_base_addr = 0x0; + dev_context->dsp_ext_base_addr); + dev_context->dsp_ext_base_addr = 0x0; } if (!dw_base_addr) { if (symbols_reloaded) @@ -344,14 +344,14 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, (ul_ext_base - ul_dyn_ext_base); } - dev_context->dw_dsp_ext_base_addr = + dev_context->dsp_ext_base_addr = (u32) MEM_LINEAR_ADDRESS((void *) dw_ext_prog_virt_mem, ul_ext_end - ul_ext_base); - dw_base_addr += dev_context->dw_dsp_ext_base_addr; - /* This dw_dsp_ext_base_addr will get cleared only when + dw_base_addr += dev_context->dsp_ext_base_addr; + /* This dsp_ext_base_addr will get cleared only when * the board is stopped. */ - if (!dev_context->dw_dsp_ext_base_addr) + if (!dev_context->dsp_ext_base_addr) ret = -EPERM; } } @@ -375,10 +375,10 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, *((u32 *) host_buff) = dw_base_addr + dw_offset; } /* Unmap here to force remap for other Ext loads */ - if ((dynamic_load || trace_load) && dev_context->dw_dsp_ext_base_addr) { + if ((dynamic_load || trace_load) && dev_context->dsp_ext_base_addr) { MEM_UNMAP_LINEAR_ADDRESS((void *) - dev_context->dw_dsp_ext_base_addr); - dev_context->dw_dsp_ext_base_addr = 0x0; + dev_context->dsp_ext_base_addr); + dev_context->dsp_ext_base_addr = 0x0; } symbols_reloaded = false; return ret; @@ -401,8 +401,8 @@ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val) if (!resources) return -EPERM; - if (dev_context->dw_brd_state == BRD_DSP_HIBERNATION || - dev_context->dw_brd_state == BRD_HIBERNATION) { + if (dev_context->brd_state == BRD_DSP_HIBERNATION || + dev_context->brd_state == BRD_HIBERNATION) { #ifdef CONFIG_TIDSPBRIDGE_DVFS if (pdata->dsp_get_opp) opplevel = (*pdata->dsp_get_opp) (); @@ -439,8 +439,8 @@ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val) /* Access MMU SYS CONFIG register to generate a short wakeup */ temp = readl(resources->dw_dmmu_base + 0x10); - dev_context->dw_brd_state = BRD_RUNNING; - } else if (dev_context->dw_brd_state == BRD_RETENTION) { + dev_context->brd_state = BRD_RUNNING; + } else if (dev_context->brd_state == BRD_RETENTION) { /* Restart the peripheral clocks */ dsp_clock_enable_all(dev_context->dsp_per_clks); } diff --git a/drivers/staging/tidspbridge/core/ue_deh.c b/drivers/staging/tidspbridge/core/ue_deh.c index 3430418190da..875a65c7f6de 100644 --- a/drivers/staging/tidspbridge/core/ue_deh.c +++ b/drivers/staging/tidspbridge/core/ue_deh.c @@ -254,7 +254,7 @@ void bridge_deh_notify(struct deh_mgr *deh, int event, int info) } /* Filter subsequent notifications when an error occurs */ - if (dev_context->dw_brd_state != BRD_ERROR) { + if (dev_context->brd_state != BRD_ERROR) { ntfy_notify(deh->ntfy_obj, event); #ifdef CONFIG_TIDSPBRIDGE_RECOVERY bridge_recover_schedule(); @@ -262,7 +262,7 @@ void bridge_deh_notify(struct deh_mgr *deh, int event, int info) } /* Set the Board state as ERROR */ - dev_context->dw_brd_state = BRD_ERROR; + dev_context->brd_state = BRD_ERROR; /* Disable all the clocks that were enabled by DSP */ dsp_clock_disable_all(dev_context->dsp_per_clks); /* diff --git a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h b/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h index 8a22317e5b5c..14b0567e5314 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h +++ b/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h @@ -171,7 +171,7 @@ struct chnl_irp { u8 *host_user_buf; /* Buffer to be filled/emptied. (System) */ u8 *host_sys_buf; - u32 dw_arg; /* Issue/Reclaim argument. */ + u32 arg; /* Issue/Reclaim argument. */ u32 dsp_tx_addr; /* Transfer address on DSP side. */ u32 byte_size; /* Bytes transferred. */ u32 buf_size; /* Actual buffer size when allocated. */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h index 0589a0a80f50..f7c105af3da9 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h @@ -43,18 +43,18 @@ struct cfg_hostres { * dw_mem_base + this offset */ /* * Info needed by NODE for allocating channels to communicate with RMS: - * dw_chnl_offset: Offset of RMS channels. Lower channels are + * chnl_offset: Offset of RMS channels. Lower channels are * reserved. - * dw_chnl_buf_size: Size of channel buffer to send to RMS + * chnl_buf_size: Size of channel buffer to send to RMS * dw_num_chnls: Total number of channels * (including reserved). */ - u32 dw_chnl_offset; - u32 dw_chnl_buf_size; + u32 chnl_offset; + u32 chnl_buf_size; u32 dw_num_chnls; void __iomem *dw_per_base; u32 dw_per_pm_base; - u32 dw_core_pm_base; + u32 core_pm_base; void __iomem *dw_dmmu_base; }; diff --git a/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h b/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h index 8f8f9ece8d49..2cc27b5bcd0f 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h @@ -57,7 +57,7 @@ struct chnl_ioc { u32 byte_size; /* Bytes transferred. */ u32 buf_size; /* Actual buffer size in bytes */ u32 status; /* Status of IO completion. */ - u32 dw_arg; /* User argument associated with pbuf. */ + u32 arg; /* User argument associated with pbuf. */ }; #endif /* CHNLDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h index e748ba8d6cab..943d91f809e3 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h @@ -54,9 +54,9 @@ struct cmm_seginfo { u32 dw_seg_base_pa; /* Start Phys address of SM segment */ /* Total size in bytes of segment: DSP+GPP */ u32 ul_total_seg_size; - u32 dw_gpp_base_pa; /* Start Phys addr of Gpp SM seg */ + u32 gpp_base_pa; /* Start Phys addr of Gpp SM seg */ u32 ul_gpp_size; /* Size of Gpp SM seg in bytes */ - u32 dw_dsp_base_va; /* DSP virt base byte address */ + u32 dsp_base_va; /* DSP virt base byte address */ u32 ul_dsp_size; /* DSP seg size in bytes */ /* # of current GPP allocations from this segment */ u32 ul_in_use_cnt; @@ -79,8 +79,8 @@ struct cmm_info { /* XlatorCreate attributes */ struct cmm_xlatorattrs { u32 ul_seg_id; /* segment Id used for SM allocations */ - u32 dw_dsp_bufs; /* # of DSP-side bufs */ - u32 dw_dsp_buf_size; /* size of DSP-side bufs in GPP bytes */ + u32 dsp_bufs; /* # of DSP-side bufs */ + u32 dsp_buf_size; /* size of DSP-side bufs in GPP bytes */ /* Vm base address alloc'd in client process context */ void *vm_base; /* dw_vm_size must be >= (dwMaxNumBufs * dwMaxSize) */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h index 38fffebd0c0c..6ba66c500e79 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h @@ -244,9 +244,9 @@ struct dsp_cbdata { /* The dsp_msg structure */ struct dsp_msg { - u32 dw_cmd; - u32 dw_arg1; - u32 dw_arg2; + u32 cmd; + u32 arg1; + u32 arg2; }; /* The dsp_resourcereqmts structure for node's resource requirements */ @@ -368,7 +368,7 @@ struct dsp_processorinfo { /* Error information of last DSP exception signalled to the GPP */ struct dsp_errorinfo { - u32 dw_err_mask; + u32 err_mask; u32 dw_val1; u32 dw_val2; u32 dw_val3; diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h index 8ad9ace1a82a..bd3f885dbe65 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h @@ -68,7 +68,7 @@ union trapped_args { struct { void *hprocessor; - u32 dw_cmd; + u32 cmd; struct dsp_cbdata __user *pargs; } args_proc_ctrl; @@ -293,7 +293,7 @@ union trapped_args { u8 *pbuffer; u32 dw_bytes; u32 dw_buf_size; - u32 dw_arg; + u32 arg; } args_strm_issue; struct { diff --git a/drivers/staging/tidspbridge/pmgr/cmm.c b/drivers/staging/tidspbridge/pmgr/cmm.c index babe66f759ca..f7542a5b10d6 100644 --- a/drivers/staging/tidspbridge/pmgr/cmm.c +++ b/drivers/staging/tidspbridge/pmgr/cmm.c @@ -66,10 +66,10 @@ struct cmm_allocator { /* sma */ u32 ul_sm_size; /* Size of SM block in bytes */ unsigned int dw_vm_base; /* Start of VM block. (Dev driver * context for 'sma') */ - u32 dw_dsp_phys_addr_offset; /* DSP PA to GPP PA offset for this + u32 dsp_phys_addr_offset; /* DSP PA to GPP PA offset for this * SM space */ s8 c_factor; /* DSPPa to GPPPa Conversion Factor */ - unsigned int dw_dsp_base; /* DSP virt base byte address */ + unsigned int dsp_base; /* DSP virt base byte address */ u32 ul_dsp_size; /* DSP seg size in bytes */ struct cmm_object *hcmm_mgr; /* back ref to parent mgr */ /* node list of available memory */ @@ -119,8 +119,8 @@ static struct cmm_attrs cmm_dfltalctattrs = { static struct cmm_xlatorattrs cmm_dfltxlatorattrs = { /* ul_seg_id, does not have to match cmm_dfltalctattrs ul_seg_id */ 1, - 0, /* dw_dsp_bufs */ - 0, /* dw_dsp_buf_size */ + 0, /* dsp_bufs */ + 0, /* dsp_buf_size */ NULL, /* vm_base */ 0, /* dw_vm_size */ }; @@ -442,12 +442,12 @@ int cmm_get_info(struct cmm_object *hcmm_mgr, altr->shm_base - altr->ul_dsp_size; cmm_info_obj->seg_info[ul_seg - 1].ul_total_seg_size = altr->ul_dsp_size + altr->ul_sm_size; - cmm_info_obj->seg_info[ul_seg - 1].dw_gpp_base_pa = + cmm_info_obj->seg_info[ul_seg - 1].gpp_base_pa = altr->shm_base; cmm_info_obj->seg_info[ul_seg - 1].ul_gpp_size = altr->ul_sm_size; - cmm_info_obj->seg_info[ul_seg - 1].dw_dsp_base_va = - altr->dw_dsp_base; + cmm_info_obj->seg_info[ul_seg - 1].dsp_base_va = + altr->dsp_base; cmm_info_obj->seg_info[ul_seg - 1].ul_dsp_size = altr->ul_dsp_size; cmm_info_obj->seg_info[ul_seg - 1].dw_seg_base_va = @@ -540,9 +540,9 @@ int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr, psma->shm_base = dw_gpp_base_pa; /* SM Base phys */ psma->ul_sm_size = ul_size; /* SM segment size in bytes */ psma->dw_vm_base = gpp_base_va; - psma->dw_dsp_phys_addr_offset = dsp_addr_offset; + psma->dsp_phys_addr_offset = dsp_addr_offset; psma->c_factor = c_factor; - psma->dw_dsp_base = dw_dsp_base; + psma->dsp_base = dw_dsp_base; psma->ul_dsp_size = ul_dsp_size; if (psma->dw_vm_base == 0) { status = -EPERM; @@ -994,14 +994,14 @@ void *cmm_xlator_translate(struct cmm_xlatorobject *xlator, void *paddr, dw_addr_xlate = GPPPA2DSPPA((allocator->shm_base - allocator->ul_dsp_size), dw_addr_xlate, - allocator->dw_dsp_phys_addr_offset * + allocator->dsp_phys_addr_offset * allocator->c_factor); } else if (xtype == CMM_DSPPA2PA) { /* Got DSP Pa, convert to GPP Pa */ dw_addr_xlate = DSPPA2GPPPA(allocator->shm_base - allocator->ul_dsp_size, dw_addr_xlate, - allocator->dw_dsp_phys_addr_offset * + allocator->dsp_phys_addr_offset * allocator->c_factor); } loop_cont: diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c index 86ca785f1913..3efe1d50a4cd 100644 --- a/drivers/staging/tidspbridge/pmgr/dspapi.c +++ b/drivers/staging/tidspbridge/pmgr/dspapi.c @@ -639,7 +639,7 @@ u32 procwrap_ctrl(union trapped_args *args, void *pr_ctxt) } if (!status) { status = proc_ctrl(hprocessor, - args->args_proc_ctrl.dw_cmd, + args->args_proc_ctrl.cmd, (struct dsp_cbdata *)pargs); } @@ -1717,7 +1717,7 @@ u32 strmwrap_issue(union trapped_args *args, void *pr_ctxt) args->args_strm_issue.pbuffer, args->args_strm_issue.dw_bytes, args->args_strm_issue.dw_buf_size, - args->args_strm_issue.dw_arg); + args->args_strm_issue.arg); return status; } diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c index e0fc8956a96d..2e7330272b18 100644 --- a/drivers/staging/tidspbridge/rmgr/drv.c +++ b/drivers/staging/tidspbridge/rmgr/drv.c @@ -699,10 +699,10 @@ static int request_bridge_resources(struct cfg_hostres *res) host_res->birq_registers = 0; host_res->birq_attrib = 0; host_res->dw_offset_for_monitor = 0; - host_res->dw_chnl_offset = 0; + host_res->chnl_offset = 0; /* CHNL_MAXCHANNELS */ host_res->dw_num_chnls = CHNL_MAXCHANNELS; - host_res->dw_chnl_buf_size = 0x400; + host_res->chnl_buf_size = 0x400; return 0; } @@ -741,7 +741,7 @@ int drv_request_bridge_res_dsp(void **phost_resources) OMAP_PER_CM_SIZE); host_res->dw_per_pm_base = (u32) ioremap(OMAP_PER_PRM_BASE, OMAP_PER_PRM_SIZE); - host_res->dw_core_pm_base = (u32) ioremap(OMAP_CORE_PRM_BASE, + host_res->core_pm_base = (u32) ioremap(OMAP_CORE_PRM_BASE, OMAP_CORE_PRM_SIZE); host_res->dw_dmmu_base = ioremap(OMAP_DMMU_BASE, OMAP_DMMU_SIZE); @@ -783,10 +783,10 @@ int drv_request_bridge_res_dsp(void **phost_resources) host_res->birq_registers = 0; host_res->birq_attrib = 0; host_res->dw_offset_for_monitor = 0; - host_res->dw_chnl_offset = 0; + host_res->chnl_offset = 0; /* CHNL_MAXCHANNELS */ host_res->dw_num_chnls = CHNL_MAXCHANNELS; - host_res->dw_chnl_buf_size = 0x400; + host_res->chnl_buf_size = 0x400; dw_buff_size = sizeof(struct cfg_hostres); } *phost_resources = host_res; diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index 27af99d512d0..5a045c75c56b 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -1795,12 +1795,12 @@ int node_get_message(struct node_object *hnode, status = (*intf_fxns->pfn_msg_get) (hnode->msg_queue_obj, message, utimeout); /* Check if message contains SM descriptor */ - if (status || !(message->dw_cmd & DSP_RMSBUFDESC)) + if (status || !(message->cmd & DSP_RMSBUFDESC)) goto func_end; /* Translate DSP byte addr to GPP Va. */ tmp_buf = cmm_xlator_translate(hnode->xlator, - (void *)(message->dw_arg1 * + (void *)(message->arg1 * hnode->hnode_mgr-> udsp_word_size), CMM_DSPPA2PA); if (tmp_buf != NULL) { @@ -1809,8 +1809,8 @@ int node_get_message(struct node_object *hnode, CMM_PA2VA); if (tmp_buf != NULL) { /* Adjust SM size in msg */ - message->dw_arg1 = (u32) tmp_buf; - message->dw_arg2 *= hnode->hnode_mgr->udsp_word_size; + message->arg1 = (u32) tmp_buf; + message->arg2 *= hnode->hnode_mgr->udsp_word_size; } else { status = -ESRCH; } @@ -2100,19 +2100,19 @@ int node_put_message(struct node_object *hnode, /* assign pmsg values to new msg */ new_msg = *pmsg; /* Now, check if message contains a SM buffer descriptor */ - if (pmsg->dw_cmd & DSP_RMSBUFDESC) { + if (pmsg->cmd & DSP_RMSBUFDESC) { /* Translate GPP Va to DSP physical buf Ptr. */ tmp_buf = cmm_xlator_translate(hnode->xlator, - (void *)new_msg.dw_arg1, + (void *)new_msg.arg1, CMM_VA2DSPPA); if (tmp_buf != NULL) { /* got translation, convert to MAUs in msg */ if (hnode->hnode_mgr->udsp_word_size != 0) { - new_msg.dw_arg1 = + new_msg.arg1 = (u32) tmp_buf / hnode->hnode_mgr->udsp_word_size; /* MAUs */ - new_msg.dw_arg2 /= hnode->hnode_mgr-> + new_msg.arg2 /= hnode->hnode_mgr-> udsp_word_size; } else { pr_err("%s: udsp_word_size is zero!\n", @@ -2378,10 +2378,10 @@ int node_terminate(struct node_object *hnode, int *pstatus) goto func_cont; } - msg.dw_cmd = RMS_EXIT; - msg.dw_arg1 = hnode->node_env; - killmsg.dw_cmd = RMS_KILLTASK; - killmsg.dw_arg1 = hnode->node_env; + msg.cmd = RMS_EXIT; + msg.arg1 = hnode->node_env; + killmsg.cmd = RMS_KILLTASK; + killmsg.arg1 = hnode->node_env; intf_fxns = hnode_mgr->intf_fxns; if (hnode->utimeout > MAXTIMEOUT) @@ -2902,8 +2902,8 @@ static int get_proc_props(struct node_mgr *hnode_mgr, host_res = pbridge_context->resources; if (!host_res) return -EPERM; - hnode_mgr->ul_chnl_offset = host_res->dw_chnl_offset; - hnode_mgr->ul_chnl_buf_size = host_res->dw_chnl_buf_size; + hnode_mgr->ul_chnl_offset = host_res->chnl_offset; + hnode_mgr->ul_chnl_buf_size = host_res->chnl_buf_size; hnode_mgr->ul_num_chnls = host_res->dw_num_chnls; /* diff --git a/drivers/staging/tidspbridge/rmgr/strm.c b/drivers/staging/tidspbridge/rmgr/strm.c index 2e427149fb6c..d36b31659890 100644 --- a/drivers/staging/tidspbridge/rmgr/strm.c +++ b/drivers/staging/tidspbridge/rmgr/strm.c @@ -639,7 +639,7 @@ int strm_reclaim(struct strm_object *stream_obj, u8 ** buf_ptr, if (buff_size) *buff_size = chnl_ioc_obj.buf_size; - *pdw_arg = chnl_ioc_obj.dw_arg; + *pdw_arg = chnl_ioc_obj.arg; if (!CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) { if (CHNL_IS_TIMED_OUT(chnl_ioc_obj)) { status = -ETIME; -- cgit v1.2.3 From 5108de0ae06190f2ab54b9a1da315b77b33be1e2 Mon Sep 17 00:00:00 2001 From: Rene Sapiens Date: Tue, 18 Jan 2011 03:19:04 +0000 Subject: staging: tidspbridge: set2 remove hungarian from structs hungarian notation will be removed from the elements inside structures, the next varibles will be renamed: Original: Replacement: dw_dsp_base_addr dsp_base_addr dw_dmmu_base dmmu_base dw_index index dw_int_addr int_addr dw_internal_size internal_size dw_last_output last_output dw_mem_base mem_base dw_mem_length mem_length dw_mem_phys mem_phys dw_mode mode dw_num_chnls num_chnls dw_offset_for_monitor offset_for_monitor dw_output_mask output_mask dw_page_size page_size dw_pa pa dw_per_base per_base dw_per_pm_base per_pm_base dw_public_rhea public_rhea dw_seg_base_pa seg_base_pa Signed-off-by: Rene Sapiens Signed-off-by: Armando Uribe Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/core/_tiomap.h | 8 +- drivers/staging/tidspbridge/core/chnl_sm.c | 8 +- drivers/staging/tidspbridge/core/io_sm.c | 18 ++-- drivers/staging/tidspbridge/core/tiomap3430.c | 104 ++++++++++----------- drivers/staging/tidspbridge/core/tiomap3430_pwr.c | 64 ++++++------- drivers/staging/tidspbridge/core/tiomap_io.c | 16 ++-- drivers/staging/tidspbridge/core/ue_deh.c | 18 ++-- .../tidspbridge/include/dspbridge/_chnl_sm.h | 4 +- .../tidspbridge/include/dspbridge/cfgdefs.h | 20 ++-- .../tidspbridge/include/dspbridge/chnlpriv.h | 2 +- .../tidspbridge/include/dspbridge/cmmdefs.h | 2 +- drivers/staging/tidspbridge/pmgr/cmm.c | 24 ++--- drivers/staging/tidspbridge/pmgr/dev.c | 8 +- drivers/staging/tidspbridge/pmgr/dspapi.c | 2 +- drivers/staging/tidspbridge/rmgr/drv.c | 60 ++++++------ drivers/staging/tidspbridge/rmgr/node.c | 4 +- 16 files changed, 181 insertions(+), 181 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index 80bc4755df10..5a14e6f80509 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -327,16 +327,16 @@ struct bridge_dev_context { */ u32 dsp_ext_base_addr; /* See the comment above */ u32 api_reg_base; /* API mem map'd registers */ - void __iomem *dw_dsp_mmu_base; /* DSP MMU Mapped registers */ + void __iomem *dsp_mmu_base; /* DSP MMU Mapped registers */ u32 api_clk_base; /* CLK Registers */ u32 dsp_clk_m2_base; /* DSP Clock Module m2 */ - u32 dw_public_rhea; /* Pub Rhea */ - u32 dw_int_addr; /* MB INTR reg */ + u32 public_rhea; /* Pub Rhea */ + u32 int_addr; /* MB INTR reg */ u32 dw_tc_endianism; /* TC Endianism register */ u32 dw_test_base; /* DSP MMU Mapped registers */ u32 dw_self_loop; /* Pointer to the selfloop */ u32 dsp_start_add; /* API Boot vector */ - u32 dw_internal_size; /* Internal memory size */ + u32 internal_size; /* Internal memory size */ struct omap_mbox *mbox; /* Mail box handle */ diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c index a52262728755..59b8d5569395 100644 --- a/drivers/staging/tidspbridge/core/chnl_sm.c +++ b/drivers/staging/tidspbridge/core/chnl_sm.c @@ -272,7 +272,7 @@ int bridge_chnl_cancel_io(struct chnl_object *chnl_obj) } else { /* Record that we no longer have output buffers * available: */ - chnl_mgr_obj->dw_output_mask &= ~(1 << chnl_id); + chnl_mgr_obj->output_mask &= ~(1 << chnl_id); } } /* Move all IOR's to IOC queue: */ @@ -386,8 +386,8 @@ int bridge_chnl_create(struct chnl_mgr **channel_mgr, /* Total # chnls supported */ chnl_mgr_obj->max_channels = max_channels; chnl_mgr_obj->open_channels = 0; - chnl_mgr_obj->dw_output_mask = 0; - chnl_mgr_obj->dw_last_output = 0; + chnl_mgr_obj->output_mask = 0; + chnl_mgr_obj->last_output = 0; chnl_mgr_obj->hdev_obj = hdev_obj; spin_lock_init(&chnl_mgr_obj->chnl_mgr_lock); } else { @@ -511,7 +511,7 @@ int bridge_chnl_get_info(struct chnl_object *chnl_obj, channel_info->hchnl_mgr = pchnl->chnl_mgr_obj; channel_info->event_obj = pchnl->user_event; channel_info->cnhl_id = pchnl->chnl_id; - channel_info->dw_mode = pchnl->chnl_mode; + channel_info->mode = pchnl->chnl_mode; channel_info->bytes_tx = pchnl->bytes_moved; channel_info->process = pchnl->process; channel_info->sync_event = pchnl->sync_event; diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 913c7681d804..e89052c8c0e2 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -417,8 +417,8 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) /* The first MMU TLB entry(TLB_0) in DCD is ShmBase. */ ndx = 0; - ul_gpp_pa = host_res->dw_mem_phys[1]; - ul_gpp_va = host_res->dw_mem_base[1]; + ul_gpp_pa = host_res->mem_phys[1]; + ul_gpp_va = host_res->mem_base[1]; /* This is the virtual uncached ioremapped address!!! */ /* Why can't we directly take the DSPVA from the symbols? */ ul_dsp_va = hio_mgr->ext_proc_info.ty_tlb[0].ul_dsp_virt; @@ -441,9 +441,9 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) ul_dyn_ext_base, ul_ext_end, ul_seg_size, ul_seg1_size); if ((ul_seg_size + ul_seg1_size + ul_pad_size) > - host_res->dw_mem_length[1]) { + host_res->mem_length[1]) { pr_err("%s: shm Error, reserved 0x%x required 0x%x\n", - __func__, host_res->dw_mem_length[1], + __func__, host_res->mem_length[1], ul_seg_size + ul_seg1_size + ul_pad_size); status = -ENOMEM; } @@ -993,7 +993,7 @@ void io_request_chnl(struct io_mgr *io_manager, struct chnl_object *pchnl, * Record the fact that we have a buffer available for * output. */ - chnl_mgr_obj->dw_output_mask |= (1 << pchnl->chnl_id); + chnl_mgr_obj->output_mask |= (1 << pchnl->chnl_id); } else { DBC_ASSERT(io_mode); /* Shouldn't get here. */ } @@ -1036,7 +1036,7 @@ static u32 find_ready_output(struct chnl_mgr *chnl_mgr_obj, u32 shift; id = (pchnl != - NULL ? pchnl->chnl_id : (chnl_mgr_obj->dw_last_output + 1)); + NULL ? pchnl->chnl_id : (chnl_mgr_obj->last_output + 1)); id = ((id == CHNL_MAXCHANNELS) ? 0 : id); if (id >= CHNL_MAXCHANNELS) goto func_end; @@ -1047,7 +1047,7 @@ static u32 find_ready_output(struct chnl_mgr *chnl_mgr_obj, if (mask & shift) { ret = id; if (pchnl == NULL) - chnl_mgr_obj->dw_last_output = id; + chnl_mgr_obj->last_output = id; break; } id = id + 1; @@ -1336,7 +1336,7 @@ static void output_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, dw_dsp_f_mask = sm->dsp_free_mask; chnl_id = find_ready_output(chnl_mgr_obj, pchnl, - (chnl_mgr_obj->dw_output_mask & dw_dsp_f_mask)); + (chnl_mgr_obj->output_mask & dw_dsp_f_mask)); if (chnl_id == OUTPUTNOTREADY) goto func_end; @@ -1358,7 +1358,7 @@ static void output_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, /* Record fact that no more I/O buffers available */ if (list_empty(&pchnl->pio_requests)) - chnl_mgr_obj->dw_output_mask &= ~(1 << chnl_id); + chnl_mgr_obj->output_mask &= ~(1 << chnl_id); /* Transfer buffer to DSP side */ chnl_packet_obj->byte_size = min(pio_mgr->usm_buf_size, diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index ce0556d026c3..5964a13d0b84 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -233,7 +233,7 @@ static inline void flush_all(struct bridge_dev_context *dev_context) dev_context->brd_state == BRD_HIBERNATION) wake_dsp(dev_context, NULL); - hw_mmu_tlb_flush_all(dev_context->dw_dsp_mmu_base); + hw_mmu_tlb_flush_all(dev_context->dsp_mmu_base); } static void bad_page_dump(u32 pa, struct page *pg) @@ -331,7 +331,7 @@ static int bridge_brd_read(struct bridge_dev_context *dev_ctxt, } /* change here to account for the 3 bands of the DSP internal memory */ if ((dsp_addr - dev_context->dsp_start_add) < - dev_context->dw_internal_size) { + dev_context->internal_size) { offset = dsp_addr - dev_context->dsp_start_add; } else { status = read_ext_dsp_data(dev_context, host_buff, dsp_addr, @@ -452,9 +452,9 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, udelay(100); /* Disbale the DSP MMU */ - hw_mmu_disable(resources->dw_dmmu_base); + hw_mmu_disable(resources->dmmu_base); /* Disable TWL */ - hw_mmu_twl_disable(resources->dw_dmmu_base); + hw_mmu_twl_disable(resources->dmmu_base); /* Only make TLB entry if both addresses are non-zero */ for (entry_ndx = 0; entry_ndx < BRDIOCTL_NUMOFMMUTLB; @@ -476,7 +476,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, e->ul_dsp_va, e->ul_size); - hw_mmu_tlb_add(dev_context->dw_dsp_mmu_base, + hw_mmu_tlb_add(dev_context->dsp_mmu_base, e->ul_gpp_pa, e->ul_dsp_va, e->ul_size, @@ -490,19 +490,19 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, /* Lock the above TLB entries and get the BIOS and load monitor timer * information */ if (!status) { - hw_mmu_num_locked_set(resources->dw_dmmu_base, itmp_entry_ndx); - hw_mmu_victim_num_set(resources->dw_dmmu_base, itmp_entry_ndx); - hw_mmu_ttb_set(resources->dw_dmmu_base, + hw_mmu_num_locked_set(resources->dmmu_base, itmp_entry_ndx); + hw_mmu_victim_num_set(resources->dmmu_base, itmp_entry_ndx); + hw_mmu_ttb_set(resources->dmmu_base, dev_context->pt_attrs->l1_base_pa); - hw_mmu_twl_enable(resources->dw_dmmu_base); + hw_mmu_twl_enable(resources->dmmu_base); /* Enable the SmartIdle and AutoIdle bit for MMU_SYSCONFIG */ - temp = __raw_readl((resources->dw_dmmu_base) + 0x10); + temp = __raw_readl((resources->dmmu_base) + 0x10); temp = (temp & 0xFFFFFFEF) | 0x11; - __raw_writel(temp, (resources->dw_dmmu_base) + 0x10); + __raw_writel(temp, (resources->dmmu_base) + 0x10); /* Let the DSP MMU run */ - hw_mmu_enable(resources->dw_dmmu_base); + hw_mmu_enable(resources->dmmu_base); /* Enable the BIOS clock */ (void)dev_get_symbol(dev_context->hdev_obj, @@ -566,18 +566,18 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, } if (!status) { /*PM_IVA2GRPSEL_PER = 0xC0;*/ - temp = readl(resources->dw_per_pm_base + 0xA8); + temp = readl(resources->per_pm_base + 0xA8); temp = (temp & 0xFFFFFF30) | 0xC0; - writel(temp, resources->dw_per_pm_base + 0xA8); + writel(temp, resources->per_pm_base + 0xA8); /*PM_MPUGRPSEL_PER &= 0xFFFFFF3F; */ - temp = readl(resources->dw_per_pm_base + 0xA4); + temp = readl(resources->per_pm_base + 0xA4); temp = (temp & 0xFFFFFF3F); - writel(temp, resources->dw_per_pm_base + 0xA4); + writel(temp, resources->per_pm_base + 0xA4); /*CM_SLEEPDEP_PER |= 0x04; */ - temp = readl(resources->dw_per_base + 0x44); + temp = readl(resources->per_base + 0x44); temp = (temp & 0xFFFFFFFB) | 0x04; - writel(temp, resources->dw_per_base + 0x44); + writel(temp, resources->per_base + 0x44); /*CM_CLKSTCTRL_IVA2 = 0x00000003 -To Allow automatic transitions */ (*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, @@ -586,7 +586,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, /* Let DSP go */ dev_dbg(bridge, "%s Unreset\n", __func__); /* Enable DSP MMU Interrupts */ - hw_mmu_event_enable(resources->dw_dmmu_base, + hw_mmu_event_enable(resources->dmmu_base, HW_MMU_ALL_INTERRUPTS); /* release the RST1, DSP starts executing now .. */ (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, 0, @@ -726,7 +726,7 @@ static int bridge_brd_write(struct bridge_dev_context *dev_ctxt, return status; } if ((dsp_addr - dev_context->dsp_start_add) < - dev_context->dw_internal_size) { + dev_context->internal_size) { status = write_dsp_data(dev_ctxt, host_buff, dsp_addr, ul_num_bytes, mem_type); } else { @@ -767,7 +767,7 @@ static int bridge_dev_create(struct bridge_dev_context dev_context->dsp_start_add = (u32) OMAP_GEM_BASE; dev_context->dw_self_loop = (u32) NULL; dev_context->dsp_per_clks = 0; - dev_context->dw_internal_size = OMAP_DSP_SIZE; + dev_context->internal_size = OMAP_DSP_SIZE; /* Clear dev context MMU table entries. * These get set on bridge_io_on_loaded() call after program loaded. */ for (entry_ndx = 0; entry_ndx < BRDIOCTL_NUMOFMMUTLB; entry_ndx++) { @@ -776,10 +776,10 @@ static int bridge_dev_create(struct bridge_dev_context } dev_context->dsp_base_addr = (u32) MEM_LINEAR_ADDRESS((void *) (config_param-> - dw_mem_base + mem_base [3]), config_param-> - dw_mem_length + mem_length [3]); if (!dev_context->dsp_base_addr) status = -EPERM; @@ -869,7 +869,7 @@ static int bridge_dev_create(struct bridge_dev_context udelay(5); /* MMU address is obtained from the host * resources struct */ - dev_context->dw_dsp_mmu_base = resources->dw_dmmu_base; + dev_context->dsp_mmu_base = resources->dmmu_base; } if (!status) { dev_context->hdev_obj = hdev_obj; @@ -1001,12 +1001,12 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt) host_res = dev_context->resources; shm_size = drv_datap->shm_size; if (shm_size >= 0x10000) { - if ((host_res->dw_mem_base[1]) && - (host_res->dw_mem_phys[1])) { + if ((host_res->mem_base[1]) && + (host_res->mem_phys[1])) { mem_free_phys_mem((void *) - host_res->dw_mem_base + host_res->mem_base [1], - host_res->dw_mem_phys + host_res->mem_phys [1], shm_size); } } else { @@ -1015,31 +1015,31 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt) "mem_free_phys_mem\n", __func__, status); } - host_res->dw_mem_base[1] = 0; - host_res->dw_mem_phys[1] = 0; - - if (host_res->dw_mem_base[0]) - iounmap((void *)host_res->dw_mem_base[0]); - if (host_res->dw_mem_base[2]) - iounmap((void *)host_res->dw_mem_base[2]); - if (host_res->dw_mem_base[3]) - iounmap((void *)host_res->dw_mem_base[3]); - if (host_res->dw_mem_base[4]) - iounmap((void *)host_res->dw_mem_base[4]); - if (host_res->dw_dmmu_base) - iounmap(host_res->dw_dmmu_base); - if (host_res->dw_per_base) - iounmap(host_res->dw_per_base); - if (host_res->dw_per_pm_base) - iounmap((void *)host_res->dw_per_pm_base); + host_res->mem_base[1] = 0; + host_res->mem_phys[1] = 0; + + if (host_res->mem_base[0]) + iounmap((void *)host_res->mem_base[0]); + if (host_res->mem_base[2]) + iounmap((void *)host_res->mem_base[2]); + if (host_res->mem_base[3]) + iounmap((void *)host_res->mem_base[3]); + if (host_res->mem_base[4]) + iounmap((void *)host_res->mem_base[4]); + if (host_res->dmmu_base) + iounmap(host_res->dmmu_base); + if (host_res->per_base) + iounmap(host_res->per_base); + if (host_res->per_pm_base) + iounmap((void *)host_res->per_pm_base); if (host_res->core_pm_base) iounmap((void *)host_res->core_pm_base); - host_res->dw_mem_base[0] = (u32) NULL; - host_res->dw_mem_base[2] = (u32) NULL; - host_res->dw_mem_base[3] = (u32) NULL; - host_res->dw_mem_base[4] = (u32) NULL; - host_res->dw_dmmu_base = NULL; + host_res->mem_base[0] = (u32) NULL; + host_res->mem_base[2] = (u32) NULL; + host_res->mem_base[3] = (u32) NULL; + host_res->mem_base[4] = (u32) NULL; + host_res->dmmu_base = NULL; kfree(host_res); } @@ -1071,7 +1071,7 @@ static int bridge_brd_mem_copy(struct bridge_dev_context *dev_ctxt, copy_bytes, mem_type); if (!status) { if (dest_addr < (dev_context->dsp_start_add + - dev_context->dw_internal_size)) { + dev_context->internal_size)) { /* Write to Internal memory */ status = write_dsp_data(dev_ctxt, host_buf, dest_addr, copy_bytes, @@ -1105,7 +1105,7 @@ static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt, ul_bytes = ul_remain_bytes > BUFFERSIZE ? BUFFERSIZE : ul_remain_bytes; if (dsp_addr < (dev_context->dsp_start_add + - dev_context->dw_internal_size)) { + dev_context->internal_size)) { status = write_dsp_data(dev_ctxt, host_buff, dsp_addr, ul_bytes, mem_type); diff --git a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c index fff27d4392d9..64ca2d246c2f 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c +++ b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c @@ -434,8 +434,8 @@ void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable) switch (clock_id) { case BPWR_GP_TIMER5: - iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8); - mpu_grpsel = readl(resources->dw_per_pm_base + 0xA4); + iva2_grpsel = readl(resources->per_pm_base + 0xA8); + mpu_grpsel = readl(resources->per_pm_base + 0xA4); if (enable) { iva2_grpsel |= OMAP3430_GRPSEL_GPT5_MASK; mpu_grpsel &= ~OMAP3430_GRPSEL_GPT5_MASK; @@ -443,12 +443,12 @@ void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable) mpu_grpsel |= OMAP3430_GRPSEL_GPT5_MASK; iva2_grpsel &= ~OMAP3430_GRPSEL_GPT5_MASK; } - writel(iva2_grpsel, resources->dw_per_pm_base + 0xA8); - writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4); + writel(iva2_grpsel, resources->per_pm_base + 0xA8); + writel(mpu_grpsel, resources->per_pm_base + 0xA4); break; case BPWR_GP_TIMER6: - iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8); - mpu_grpsel = readl(resources->dw_per_pm_base + 0xA4); + iva2_grpsel = readl(resources->per_pm_base + 0xA8); + mpu_grpsel = readl(resources->per_pm_base + 0xA4); if (enable) { iva2_grpsel |= OMAP3430_GRPSEL_GPT6_MASK; mpu_grpsel &= ~OMAP3430_GRPSEL_GPT6_MASK; @@ -456,12 +456,12 @@ void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable) mpu_grpsel |= OMAP3430_GRPSEL_GPT6_MASK; iva2_grpsel &= ~OMAP3430_GRPSEL_GPT6_MASK; } - writel(iva2_grpsel, resources->dw_per_pm_base + 0xA8); - writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4); + writel(iva2_grpsel, resources->per_pm_base + 0xA8); + writel(mpu_grpsel, resources->per_pm_base + 0xA4); break; case BPWR_GP_TIMER7: - iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8); - mpu_grpsel = readl(resources->dw_per_pm_base + 0xA4); + iva2_grpsel = readl(resources->per_pm_base + 0xA8); + mpu_grpsel = readl(resources->per_pm_base + 0xA4); if (enable) { iva2_grpsel |= OMAP3430_GRPSEL_GPT7_MASK; mpu_grpsel &= ~OMAP3430_GRPSEL_GPT7_MASK; @@ -469,12 +469,12 @@ void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable) mpu_grpsel |= OMAP3430_GRPSEL_GPT7_MASK; iva2_grpsel &= ~OMAP3430_GRPSEL_GPT7_MASK; } - writel(iva2_grpsel, resources->dw_per_pm_base + 0xA8); - writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4); + writel(iva2_grpsel, resources->per_pm_base + 0xA8); + writel(mpu_grpsel, resources->per_pm_base + 0xA4); break; case BPWR_GP_TIMER8: - iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8); - mpu_grpsel = readl(resources->dw_per_pm_base + 0xA4); + iva2_grpsel = readl(resources->per_pm_base + 0xA8); + mpu_grpsel = readl(resources->per_pm_base + 0xA4); if (enable) { iva2_grpsel |= OMAP3430_GRPSEL_GPT8_MASK; mpu_grpsel &= ~OMAP3430_GRPSEL_GPT8_MASK; @@ -482,8 +482,8 @@ void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable) mpu_grpsel |= OMAP3430_GRPSEL_GPT8_MASK; iva2_grpsel &= ~OMAP3430_GRPSEL_GPT8_MASK; } - writel(iva2_grpsel, resources->dw_per_pm_base + 0xA8); - writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4); + writel(iva2_grpsel, resources->per_pm_base + 0xA8); + writel(mpu_grpsel, resources->per_pm_base + 0xA4); break; case BPWR_MCBSP1: iva2_grpsel = readl(resources->core_pm_base + 0xA8); @@ -499,8 +499,8 @@ void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable) writel(mpu_grpsel, resources->core_pm_base + 0xA4); break; case BPWR_MCBSP2: - iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8); - mpu_grpsel = readl(resources->dw_per_pm_base + 0xA4); + iva2_grpsel = readl(resources->per_pm_base + 0xA8); + mpu_grpsel = readl(resources->per_pm_base + 0xA4); if (enable) { iva2_grpsel |= OMAP3430_GRPSEL_MCBSP2_MASK; mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP2_MASK; @@ -508,12 +508,12 @@ void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable) mpu_grpsel |= OMAP3430_GRPSEL_MCBSP2_MASK; iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP2_MASK; } - writel(iva2_grpsel, resources->dw_per_pm_base + 0xA8); - writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4); + writel(iva2_grpsel, resources->per_pm_base + 0xA8); + writel(mpu_grpsel, resources->per_pm_base + 0xA4); break; case BPWR_MCBSP3: - iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8); - mpu_grpsel = readl(resources->dw_per_pm_base + 0xA4); + iva2_grpsel = readl(resources->per_pm_base + 0xA8); + mpu_grpsel = readl(resources->per_pm_base + 0xA4); if (enable) { iva2_grpsel |= OMAP3430_GRPSEL_MCBSP3_MASK; mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP3_MASK; @@ -521,12 +521,12 @@ void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable) mpu_grpsel |= OMAP3430_GRPSEL_MCBSP3_MASK; iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP3_MASK; } - writel(iva2_grpsel, resources->dw_per_pm_base + 0xA8); - writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4); + writel(iva2_grpsel, resources->per_pm_base + 0xA8); + writel(mpu_grpsel, resources->per_pm_base + 0xA4); break; case BPWR_MCBSP4: - iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8); - mpu_grpsel = readl(resources->dw_per_pm_base + 0xA4); + iva2_grpsel = readl(resources->per_pm_base + 0xA8); + mpu_grpsel = readl(resources->per_pm_base + 0xA4); if (enable) { iva2_grpsel |= OMAP3430_GRPSEL_MCBSP4_MASK; mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP4_MASK; @@ -534,12 +534,12 @@ void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable) mpu_grpsel |= OMAP3430_GRPSEL_MCBSP4_MASK; iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP4_MASK; } - writel(iva2_grpsel, resources->dw_per_pm_base + 0xA8); - writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4); + writel(iva2_grpsel, resources->per_pm_base + 0xA8); + writel(mpu_grpsel, resources->per_pm_base + 0xA4); break; case BPWR_MCBSP5: - iva2_grpsel = readl(resources->dw_per_pm_base + 0xA8); - mpu_grpsel = readl(resources->dw_per_pm_base + 0xA4); + iva2_grpsel = readl(resources->per_pm_base + 0xA8); + mpu_grpsel = readl(resources->per_pm_base + 0xA4); if (enable) { iva2_grpsel |= OMAP3430_GRPSEL_MCBSP5_MASK; mpu_grpsel &= ~OMAP3430_GRPSEL_MCBSP5_MASK; @@ -547,8 +547,8 @@ void dsp_clk_wakeup_event_ctrl(u32 clock_id, bool enable) mpu_grpsel |= OMAP3430_GRPSEL_MCBSP5_MASK; iva2_grpsel &= ~OMAP3430_GRPSEL_MCBSP5_MASK; } - writel(iva2_grpsel, resources->dw_per_pm_base + 0xA8); - writel(mpu_grpsel, resources->dw_per_pm_base + 0xA4); + writel(iva2_grpsel, resources->per_pm_base + 0xA8); + writel(mpu_grpsel, resources->per_pm_base + 0xA4); break; } } diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c index 09c9e873ce7c..574feade6efc 100644 --- a/drivers/staging/tidspbridge/core/tiomap_io.c +++ b/drivers/staging/tidspbridge/core/tiomap_io.c @@ -197,16 +197,16 @@ int write_dsp_data(struct bridge_dev_context *dev_context, offset = dsp_addr - dev_context->dsp_start_add; if (offset < base1) { - dw_base_addr = MEM_LINEAR_ADDRESS(resources->dw_mem_base[2], - resources->dw_mem_length[2]); + dw_base_addr = MEM_LINEAR_ADDRESS(resources->mem_base[2], + resources->mem_length[2]); } else if (offset > base1 && offset < base2 + OMAP_DSP_MEM2_SIZE) { - dw_base_addr = MEM_LINEAR_ADDRESS(resources->dw_mem_base[3], - resources->dw_mem_length[3]); + dw_base_addr = MEM_LINEAR_ADDRESS(resources->mem_base[3], + resources->mem_length[3]); offset = offset - base2; } else if (offset >= base2 + OMAP_DSP_MEM2_SIZE && offset < base3 + OMAP_DSP_MEM3_SIZE) { - dw_base_addr = MEM_LINEAR_ADDRESS(resources->dw_mem_base[4], - resources->dw_mem_length[4]); + dw_base_addr = MEM_LINEAR_ADDRESS(resources->mem_base[4], + resources->mem_length[4]); offset = offset - base3; } else { return -EPERM; @@ -339,7 +339,7 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, dw_ext_prog_virt_mem = dev_context->atlb_entry[0].ul_gpp_va; } else { - dw_ext_prog_virt_mem = host_res->dw_mem_base[1]; + dw_ext_prog_virt_mem = host_res->mem_base[1]; dw_ext_prog_virt_mem += (ul_ext_base - ul_dyn_ext_base); } @@ -437,7 +437,7 @@ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val) omap_mbox_restore_ctx(dev_context->mbox); /* Access MMU SYS CONFIG register to generate a short wakeup */ - temp = readl(resources->dw_dmmu_base + 0x10); + temp = readl(resources->dmmu_base + 0x10); dev_context->brd_state = BRD_RUNNING; } else if (dev_context->brd_state == BRD_RETENTION) { diff --git a/drivers/staging/tidspbridge/core/ue_deh.c b/drivers/staging/tidspbridge/core/ue_deh.c index 875a65c7f6de..bc2feff662b4 100644 --- a/drivers/staging/tidspbridge/core/ue_deh.c +++ b/drivers/staging/tidspbridge/core/ue_deh.c @@ -59,9 +59,9 @@ static irqreturn_t mmu_fault_isr(int irq, void *data) return IRQ_HANDLED; } - hw_mmu_event_status(resources->dw_dmmu_base, &event); + hw_mmu_event_status(resources->dmmu_base, &event); if (event == HW_MMU_TRANSLATION_FAULT) { - hw_mmu_fault_addr_read(resources->dw_dmmu_base, &fault_addr); + hw_mmu_fault_addr_read(resources->dmmu_base, &fault_addr); dev_dbg(bridge, "%s: event=0x%x, fault_addr=0x%x\n", __func__, event, fault_addr); /* @@ -73,10 +73,10 @@ static irqreturn_t mmu_fault_isr(int irq, void *data) /* Disable the MMU events, else once we clear it will * start to raise INTs again */ - hw_mmu_event_disable(resources->dw_dmmu_base, + hw_mmu_event_disable(resources->dmmu_base, HW_MMU_TRANSLATION_FAULT); } else { - hw_mmu_event_disable(resources->dw_dmmu_base, + hw_mmu_event_disable(resources->dmmu_base, HW_MMU_ALL_INTERRUPTS); } return IRQ_HANDLED; @@ -185,10 +185,10 @@ static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) * access entry #0. Then add a new entry so that the DSP OS * can continue in order to dump the stack. */ - hw_mmu_twl_disable(resources->dw_dmmu_base); - hw_mmu_tlb_flush_all(resources->dw_dmmu_base); + hw_mmu_twl_disable(resources->dmmu_base); + hw_mmu_tlb_flush_all(resources->dmmu_base); - hw_mmu_tlb_add(resources->dw_dmmu_base, + hw_mmu_tlb_add(resources->dmmu_base, virt_to_phys(dummy_va_addr), fault_addr, HW_PAGE_SIZE4KB, 1, &map_attrs, HW_SET, HW_SET); @@ -198,12 +198,12 @@ static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffffffe); /* Clear MMU interrupt */ - hw_mmu_event_ack(resources->dw_dmmu_base, + hw_mmu_event_ack(resources->dmmu_base, HW_MMU_TRANSLATION_FAULT); dump_dsp_stack(dev_context); dsp_clk_disable(DSP_CLK_GPT8); - hw_mmu_disable(resources->dw_dmmu_base); + hw_mmu_disable(resources->dmmu_base); free_page((unsigned long)dummy_va_addr); } #endif diff --git a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h b/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h index 14b0567e5314..ea547380012b 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h +++ b/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h @@ -119,8 +119,8 @@ struct chnl_mgr { struct dev_object *hdev_obj; /* These fields initialized in bridge_chnl_create(): */ - u32 dw_output_mask; /* Host output channels w/ full buffers */ - u32 dw_last_output; /* Last output channel fired from DPC */ + u32 output_mask; /* Host output channels w/ full buffers */ + u32 last_output; /* Last output channel fired from DPC */ /* Critical section object handle */ spinlock_t chnl_mgr_lock; u32 word_size; /* Size in bytes of DSP word */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h index f7c105af3da9..60a278136bdf 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h @@ -34,28 +34,28 @@ struct cfg_devnode; struct cfg_hostres { u32 num_mem_windows; /* Set to default */ /* This is the base.memory */ - u32 dw_mem_base[CFG_MAXMEMREGISTERS]; /* shm virtual address */ - u32 dw_mem_length[CFG_MAXMEMREGISTERS]; /* Length of the Base */ - u32 dw_mem_phys[CFG_MAXMEMREGISTERS]; /* shm Physical address */ + u32 mem_base[CFG_MAXMEMREGISTERS]; /* shm virtual address */ + u32 mem_length[CFG_MAXMEMREGISTERS]; /* Length of the Base */ + u32 mem_phys[CFG_MAXMEMREGISTERS]; /* shm Physical address */ u8 birq_registers; /* IRQ Number */ u8 birq_attrib; /* IRQ Attribute */ - u32 dw_offset_for_monitor; /* The Shared memory starts from - * dw_mem_base + this offset */ + u32 offset_for_monitor; /* The Shared memory starts from + * mem_base + this offset */ /* * Info needed by NODE for allocating channels to communicate with RMS: * chnl_offset: Offset of RMS channels. Lower channels are * reserved. * chnl_buf_size: Size of channel buffer to send to RMS - * dw_num_chnls: Total number of channels + * num_chnls: Total number of channels * (including reserved). */ u32 chnl_offset; u32 chnl_buf_size; - u32 dw_num_chnls; - void __iomem *dw_per_base; - u32 dw_per_pm_base; + u32 num_chnls; + void __iomem *per_base; + u32 per_pm_base; u32 core_pm_base; - void __iomem *dw_dmmu_base; + void __iomem *dmmu_base; }; #endif /* CFGDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h b/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h index 1785c3e83719..29e66dd525e8 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h @@ -58,7 +58,7 @@ struct chnl_info { void *event_obj; /* Channel I/O completion event. */ /*Abstraction of I/O completion event. */ struct sync_object *sync_event; - s8 dw_mode; /* Channel mode. */ + s8 mode; /* Channel mode. */ u8 dw_state; /* Current channel state. */ u32 bytes_tx; /* Total bytes transferred. */ u32 cio_cs; /* Number of IOCs in queue. */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h index 943d91f809e3..8cd1494ccc84 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h @@ -51,7 +51,7 @@ struct cmm_attrs { */ struct cmm_seginfo { - u32 dw_seg_base_pa; /* Start Phys address of SM segment */ + u32 seg_base_pa; /* Start Phys address of SM segment */ /* Total size in bytes of segment: DSP+GPP */ u32 ul_total_seg_size; u32 gpp_base_pa; /* Start Phys addr of Gpp SM seg */ diff --git a/drivers/staging/tidspbridge/pmgr/cmm.c b/drivers/staging/tidspbridge/pmgr/cmm.c index f7542a5b10d6..d2fb6a4c0e3b 100644 --- a/drivers/staging/tidspbridge/pmgr/cmm.c +++ b/drivers/staging/tidspbridge/pmgr/cmm.c @@ -49,7 +49,7 @@ #include /* ----------------------------------- Defines, Data Structures, Typedefs */ -#define NEXT_PA(pnode) (pnode->dw_pa + pnode->ul_size) +#define NEXT_PA(pnode) (pnode->pa + pnode->ul_size) /* Other bus/platform translations */ #define DSPPA2GPPPA(base, x, y) ((x)+(y)) @@ -99,7 +99,7 @@ struct cmm_object { struct mutex cmm_lock; /* Lock to access cmm mgr */ struct list_head node_free_list; /* Free list of memory nodes */ u32 ul_min_block_size; /* Min SM block; default 16 bytes */ - u32 dw_page_size; /* Memory Page size (1k/4k) */ + u32 page_size; /* Memory Page size (1k/4k) */ /* GPP SM segment ptrs */ struct cmm_allocator *pa_gppsm_seg_tab[CMM_MAXGPPSEGS]; }; @@ -128,7 +128,7 @@ static struct cmm_xlatorattrs cmm_dfltxlatorattrs = { /* SM node representing a block of memory. */ struct cmm_mnode { struct list_head link; /* must be 1st element */ - u32 dw_pa; /* Phys addr */ + u32 pa; /* Phys addr */ u32 dw_va; /* Virtual address in device process context */ u32 ul_size; /* SM block size in bytes */ u32 client_proc; /* Process that allocated this mem block */ @@ -199,7 +199,7 @@ void *cmm_calloc_buf(struct cmm_object *hcmm_mgr, u32 usize, /* create a new block with the leftovers and * add to freelist */ new_node = - get_node(cmm_mgr_obj, pnode->dw_pa + usize, + get_node(cmm_mgr_obj, pnode->pa + usize, pnode->dw_va + usize, (u32) delta_size); /* leftovers go free */ @@ -216,7 +216,7 @@ void *cmm_calloc_buf(struct cmm_object *hcmm_mgr, u32 usize, /* put our node on InUse list */ list_add_tail(&pnode->link, &allocator->in_use_list); - buf_pa = (void *)pnode->dw_pa; /* physical address */ + buf_pa = (void *)pnode->pa; /* physical address */ /* clear mem */ pbyte = (u8 *) pnode->dw_va; for (cnt = 0; cnt < (s32) usize; cnt++, pbyte++) @@ -260,7 +260,7 @@ int cmm_create(struct cmm_object **ph_cmm_mgr, DBC_ASSERT(mgr_attrts->ul_min_block_size >= 4); /* save away smallest block allocation for this cmm mgr */ cmm_obj->ul_min_block_size = mgr_attrts->ul_min_block_size; - cmm_obj->dw_page_size = PAGE_SIZE; + cmm_obj->page_size = PAGE_SIZE; /* create node free list */ INIT_LIST_HEAD(&cmm_obj->node_free_list); @@ -369,7 +369,7 @@ int cmm_free_buf(struct cmm_object *hcmm_mgr, void *buf_pa, u32 ul_seg_id) mutex_lock(&cmm_mgr_obj->cmm_lock); list_for_each_entry_safe(curr, tmp, &allocator->in_use_list, link) { - if (curr->dw_pa == (u32) buf_pa) { + if (curr->pa == (u32) buf_pa) { list_del(&curr->link); add_to_free_list(allocator, curr); status = 0; @@ -438,7 +438,7 @@ int cmm_get_info(struct cmm_object *hcmm_mgr, if (!altr) continue; cmm_info_obj->ul_num_gppsm_segs++; - cmm_info_obj->seg_info[ul_seg - 1].dw_seg_base_pa = + cmm_info_obj->seg_info[ul_seg - 1].seg_base_pa = altr->shm_base - altr->ul_dsp_size; cmm_info_obj->seg_info[ul_seg - 1].ul_total_seg_size = altr->ul_dsp_size + altr->ul_sm_size; @@ -704,7 +704,7 @@ static struct cmm_mnode *get_node(struct cmm_object *cmm_mgr_obj, u32 dw_pa, list_del_init(&pnode->link); } - pnode->dw_pa = dw_pa; + pnode->pa = dw_pa; pnode->dw_va = dw_va; pnode->ul_size = ul_size; @@ -763,13 +763,13 @@ static void add_to_free_list(struct cmm_allocator *allocator, } list_for_each_entry(curr, &allocator->free_list, link) { - if (NEXT_PA(curr) == node->dw_pa) { + if (NEXT_PA(curr) == node->pa) { curr->ul_size += node->ul_size; delete_node(allocator->hcmm_mgr, node); return; } - if (curr->dw_pa == NEXT_PA(node)) { - curr->dw_pa = node->dw_pa; + if (curr->pa == NEXT_PA(node)) { + curr->pa = node->pa; curr->dw_va = node->dw_va; curr->ul_size += node->ul_size; delete_node(allocator->hcmm_mgr, node); diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c index 0f10a50cf6f9..e328dc1e1690 100644 --- a/drivers/staging/tidspbridge/pmgr/dev.c +++ b/drivers/staging/tidspbridge/pmgr/dev.c @@ -213,11 +213,11 @@ int dev_create_device(struct dev_object **device_obj, num_windows = host_res->num_mem_windows; if (num_windows) { /* Assume last memory window is for CHNL */ - io_mgr_attrs.shm_base = host_res->dw_mem_base[1] + - host_res->dw_offset_for_monitor; + io_mgr_attrs.shm_base = host_res->mem_base[1] + + host_res->offset_for_monitor; io_mgr_attrs.usm_length = - host_res->dw_mem_length[1] - - host_res->dw_offset_for_monitor; + host_res->mem_length[1] - + host_res->offset_for_monitor; } else { io_mgr_attrs.shm_base = 0; io_mgr_attrs.usm_length = 0; diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c index 3efe1d50a4cd..575243882d0b 100644 --- a/drivers/staging/tidspbridge/pmgr/dspapi.c +++ b/drivers/staging/tidspbridge/pmgr/dspapi.c @@ -68,7 +68,7 @@ /* Device IOCtl function pointer */ struct api_cmd { u32(*fxn) (union trapped_args *args, void *pr_ctxt); - u32 dw_index; + u32 index; }; /* ----------------------------------- Globals */ diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c index 2e7330272b18..9aacbcb38eb6 100644 --- a/drivers/staging/tidspbridge/rmgr/drv.c +++ b/drivers/staging/tidspbridge/rmgr/drv.c @@ -687,9 +687,9 @@ static int request_bridge_resources(struct cfg_hostres *res) host_res->num_mem_windows = 2; /* First window is for DSP internal memory */ - dev_dbg(bridge, "dw_mem_base[0] 0x%x\n", host_res->dw_mem_base[0]); - dev_dbg(bridge, "dw_mem_base[3] 0x%x\n", host_res->dw_mem_base[3]); - dev_dbg(bridge, "dw_dmmu_base %p\n", host_res->dw_dmmu_base); + dev_dbg(bridge, "mem_base[0] 0x%x\n", host_res->mem_base[0]); + dev_dbg(bridge, "mem_base[3] 0x%x\n", host_res->mem_base[3]); + dev_dbg(bridge, "dmmu_base %p\n", host_res->dmmu_base); /* for 24xx base port is not mapping the mamory for DSP * internal memory TODO Do a ioremap here */ @@ -698,10 +698,10 @@ static int request_bridge_resources(struct cfg_hostres *res) /* These are hard-coded values */ host_res->birq_registers = 0; host_res->birq_attrib = 0; - host_res->dw_offset_for_monitor = 0; + host_res->offset_for_monitor = 0; host_res->chnl_offset = 0; /* CHNL_MAXCHANNELS */ - host_res->dw_num_chnls = CHNL_MAXCHANNELS; + host_res->num_chnls = CHNL_MAXCHANNELS; host_res->chnl_buf_size = 0x400; return 0; @@ -730,51 +730,51 @@ int drv_request_bridge_res_dsp(void **phost_resources) /* num_mem_windows must not be more than CFG_MAXMEMREGISTERS */ host_res->num_mem_windows = 4; - host_res->dw_mem_base[0] = 0; - host_res->dw_mem_base[2] = (u32) ioremap(OMAP_DSP_MEM1_BASE, + host_res->mem_base[0] = 0; + host_res->mem_base[2] = (u32) ioremap(OMAP_DSP_MEM1_BASE, OMAP_DSP_MEM1_SIZE); - host_res->dw_mem_base[3] = (u32) ioremap(OMAP_DSP_MEM2_BASE, + host_res->mem_base[3] = (u32) ioremap(OMAP_DSP_MEM2_BASE, OMAP_DSP_MEM2_SIZE); - host_res->dw_mem_base[4] = (u32) ioremap(OMAP_DSP_MEM3_BASE, + host_res->mem_base[4] = (u32) ioremap(OMAP_DSP_MEM3_BASE, OMAP_DSP_MEM3_SIZE); - host_res->dw_per_base = ioremap(OMAP_PER_CM_BASE, + host_res->per_base = ioremap(OMAP_PER_CM_BASE, OMAP_PER_CM_SIZE); - host_res->dw_per_pm_base = (u32) ioremap(OMAP_PER_PRM_BASE, + host_res->per_pm_base = (u32) ioremap(OMAP_PER_PRM_BASE, OMAP_PER_PRM_SIZE); host_res->core_pm_base = (u32) ioremap(OMAP_CORE_PRM_BASE, OMAP_CORE_PRM_SIZE); - host_res->dw_dmmu_base = ioremap(OMAP_DMMU_BASE, + host_res->dmmu_base = ioremap(OMAP_DMMU_BASE, OMAP_DMMU_SIZE); - dev_dbg(bridge, "dw_mem_base[0] 0x%x\n", - host_res->dw_mem_base[0]); - dev_dbg(bridge, "dw_mem_base[1] 0x%x\n", - host_res->dw_mem_base[1]); - dev_dbg(bridge, "dw_mem_base[2] 0x%x\n", - host_res->dw_mem_base[2]); - dev_dbg(bridge, "dw_mem_base[3] 0x%x\n", - host_res->dw_mem_base[3]); - dev_dbg(bridge, "dw_mem_base[4] 0x%x\n", - host_res->dw_mem_base[4]); - dev_dbg(bridge, "dw_dmmu_base %p\n", host_res->dw_dmmu_base); + dev_dbg(bridge, "mem_base[0] 0x%x\n", + host_res->mem_base[0]); + dev_dbg(bridge, "mem_base[1] 0x%x\n", + host_res->mem_base[1]); + dev_dbg(bridge, "mem_base[2] 0x%x\n", + host_res->mem_base[2]); + dev_dbg(bridge, "mem_base[3] 0x%x\n", + host_res->mem_base[3]); + dev_dbg(bridge, "mem_base[4] 0x%x\n", + host_res->mem_base[4]); + dev_dbg(bridge, "dmmu_base %p\n", host_res->dmmu_base); shm_size = drv_datap->shm_size; if (shm_size >= 0x10000) { /* Allocate Physically contiguous, * non-cacheable memory */ - host_res->dw_mem_base[1] = + host_res->mem_base[1] = (u32) mem_alloc_phys_mem(shm_size, 0x100000, &dma_addr); - if (host_res->dw_mem_base[1] == 0) { + if (host_res->mem_base[1] == 0) { status = -ENOMEM; pr_err("shm reservation Failed\n"); } else { - host_res->dw_mem_length[1] = shm_size; - host_res->dw_mem_phys[1] = dma_addr; + host_res->mem_length[1] = shm_size; + host_res->mem_phys[1] = dma_addr; dev_dbg(bridge, "%s: Bridge shm address 0x%x " "dma_addr %x size %x\n", __func__, - host_res->dw_mem_base[1], + host_res->mem_base[1], dma_addr, shm_size); } } @@ -782,10 +782,10 @@ int drv_request_bridge_res_dsp(void **phost_resources) /* These are hard-coded values */ host_res->birq_registers = 0; host_res->birq_attrib = 0; - host_res->dw_offset_for_monitor = 0; + host_res->offset_for_monitor = 0; host_res->chnl_offset = 0; /* CHNL_MAXCHANNELS */ - host_res->dw_num_chnls = CHNL_MAXCHANNELS; + host_res->num_chnls = CHNL_MAXCHANNELS; host_res->chnl_buf_size = 0x400; dw_buff_size = sizeof(struct cfg_hostres); } diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index 5a045c75c56b..454fcc82584b 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -621,7 +621,7 @@ func_cont: goto func_end; } - ul_gpp_mem_base = (u32) host_res->dw_mem_base[1]; + ul_gpp_mem_base = (u32) host_res->mem_base[1]; off_set = pul_value - dynext_base; ul_stack_seg_addr = ul_gpp_mem_base + off_set; ul_stack_seg_val = readl(ul_stack_seg_addr); @@ -2904,7 +2904,7 @@ static int get_proc_props(struct node_mgr *hnode_mgr, return -EPERM; hnode_mgr->ul_chnl_offset = host_res->chnl_offset; hnode_mgr->ul_chnl_buf_size = host_res->chnl_buf_size; - hnode_mgr->ul_num_chnls = host_res->dw_num_chnls; + hnode_mgr->ul_num_chnls = host_res->num_chnls; /* * PROC will add an API to get dsp_processorinfo. -- cgit v1.2.3 From 3c882de542f67d0a7768f2e64c017e3657b519b3 Mon Sep 17 00:00:00 2001 From: Rene Sapiens Date: Tue, 18 Jan 2011 03:19:05 +0000 Subject: staging: tidspbridge: set3 remove hungarian from structs hungarian notation will be removed from the elements inside structures, the next varibles will be renamed: Original: Replacement: dw_seg_base_va seg_base_va dw_self_loop self_loop dw_state state dw_tc_endianism tc_endianism dw_test_base test_base dw_type type dw_val1 val1 dw_val2 val2 dw_val3 val3 dw_va va dw_virt_base virt_base dw_vm_base vm_base dw_vm_size vm_size pfn_allocate allocate pfn_brd_mem_copy brd_mem_copy pfn_brd_mem_map brd_mem_map pfn_brd_mem_un_map brd_mem_un_map pfn_brd_mem_write brd_mem_write pfn_brd_monitor brd_monitor pfn_brd_read brd_read Signed-off-by: Rene Sapiens Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/core/_tiomap.h | 6 +-- drivers/staging/tidspbridge/core/chnl_sm.c | 22 +++++------ drivers/staging/tidspbridge/core/io_sm.c | 34 ++++++++--------- drivers/staging/tidspbridge/core/tiomap3430.c | 2 +- .../tidspbridge/include/dspbridge/_chnl_sm.h | 4 +- .../tidspbridge/include/dspbridge/chnlpriv.h | 4 +- .../tidspbridge/include/dspbridge/cmmdefs.h | 6 +-- .../staging/tidspbridge/include/dspbridge/dbdefs.h | 6 +-- .../tidspbridge/include/dspbridge/dspdefs.h | 12 +++--- .../tidspbridge/include/dspbridge/nldrdefs.h | 2 +- drivers/staging/tidspbridge/pmgr/cmm.c | 44 +++++++++++----------- drivers/staging/tidspbridge/pmgr/dev.c | 16 ++++---- drivers/staging/tidspbridge/rmgr/node.c | 6 +-- drivers/staging/tidspbridge/rmgr/proc.c | 6 +-- drivers/staging/tidspbridge/rmgr/strm.c | 2 +- 15 files changed, 86 insertions(+), 86 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index 5a14e6f80509..60d98764af19 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -332,9 +332,9 @@ struct bridge_dev_context { u32 dsp_clk_m2_base; /* DSP Clock Module m2 */ u32 public_rhea; /* Pub Rhea */ u32 int_addr; /* MB INTR reg */ - u32 dw_tc_endianism; /* TC Endianism register */ - u32 dw_test_base; /* DSP MMU Mapped registers */ - u32 dw_self_loop; /* Pointer to the selfloop */ + u32 tc_endianism; /* TC Endianism register */ + u32 test_base; /* DSP MMU Mapped registers */ + u32 self_loop; /* Pointer to the selfloop */ u32 dsp_start_add; /* API Boot vector */ u32 internal_size; /* Internal memory size */ diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c index 59b8d5569395..c20431553aa7 100644 --- a/drivers/staging/tidspbridge/core/chnl_sm.c +++ b/drivers/staging/tidspbridge/core/chnl_sm.c @@ -115,7 +115,7 @@ int bridge_chnl_add_io_req(struct chnl_object *chnl_obj, void *host_buf, * Check the channel state: only queue chirp if channel state * allows it. */ - dw_state = pchnl->dw_state; + dw_state = pchnl->state; if (dw_state != CHNL_STATEREADY) { if (dw_state & CHNL_STATECANCEL) return -ECANCELED; @@ -207,7 +207,7 @@ func_cont: * more IOR's. */ if (is_eos) - pchnl->dw_state |= CHNL_STATEEOS; + pchnl->state |= CHNL_STATEEOS; /* Legacy DSM Processor-Copy */ DBC_ASSERT(pchnl->chnl_type == CHNL_PCPY); @@ -258,7 +258,7 @@ int bridge_chnl_cancel_io(struct chnl_object *chnl_obj) * IORequests or dispatching. */ spin_lock_bh(&chnl_mgr_obj->chnl_mgr_lock); - pchnl->dw_state |= CHNL_STATECANCEL; + pchnl->state |= CHNL_STATECANCEL; if (list_empty(&pchnl->pio_requests)) { spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock); @@ -312,7 +312,7 @@ int bridge_chnl_close(struct chnl_object *chnl_obj) if (status) return status; /* Assert I/O on this channel is now cancelled: Protects from io_dpc */ - DBC_ASSERT((pchnl->dw_state & CHNL_STATECANCEL)); + DBC_ASSERT((pchnl->state & CHNL_STATECANCEL)); /* Invalidate channel object: Protects from CHNL_GetIOCompletion() */ /* Free the slot in the channel manager: */ pchnl->chnl_mgr_obj->ap_channel[pchnl->chnl_id] = NULL; @@ -381,7 +381,7 @@ int bridge_chnl_create(struct chnl_mgr **channel_mgr, * max_channels, GFP_KERNEL); if (chnl_mgr_obj->ap_channel) { /* Initialize chnl_mgr object */ - chnl_mgr_obj->dw_type = CHNL_TYPESM; + chnl_mgr_obj->type = CHNL_TYPESM; chnl_mgr_obj->word_size = mgr_attrts->word_size; /* Total # chnls supported */ chnl_mgr_obj->max_channels = max_channels; @@ -488,7 +488,7 @@ int bridge_chnl_flush_io(struct chnl_object *chnl_obj, u32 timeout) } else { status = bridge_chnl_cancel_io(chnl_obj); /* Now, leave the channel in the ready state: */ - pchnl->dw_state &= ~CHNL_STATECANCEL; + pchnl->state &= ~CHNL_STATECANCEL; } } DBC_ENSURE(status || list_empty(&pchnl->pio_requests)); @@ -517,7 +517,7 @@ int bridge_chnl_get_info(struct chnl_object *chnl_obj, channel_info->sync_event = pchnl->sync_event; channel_info->cio_cs = pchnl->cio_cs; channel_info->cio_reqs = pchnl->cio_reqs; - channel_info->dw_state = pchnl->dw_state; + channel_info->state = pchnl->state; } else { status = -EFAULT; } @@ -687,7 +687,7 @@ int bridge_chnl_get_mgr_info(struct chnl_mgr *hchnl_mgr, u32 ch_id, /* Return the requested information: */ mgr_info->chnl_obj = chnl_mgr_obj->ap_channel[ch_id]; mgr_info->open_channels = chnl_mgr_obj->open_channels; - mgr_info->dw_type = chnl_mgr_obj->dw_type; + mgr_info->type = chnl_mgr_obj->type; /* total # of chnls */ mgr_info->max_channels = chnl_mgr_obj->max_channels; @@ -718,7 +718,7 @@ int bridge_chnl_idle(struct chnl_object *chnl_obj, u32 timeout, /* Reset the byte count and put channel back in ready state. */ chnl_obj->bytes_moved = 0; - chnl_obj->dw_state &= ~CHNL_STATECANCEL; + chnl_obj->state &= ~CHNL_STATECANCEL; } return status; @@ -769,7 +769,7 @@ int bridge_chnl_open(struct chnl_object **chnl, return -ENOMEM; /* Protect queues from io_dpc: */ - pchnl->dw_state = CHNL_STATECANCEL; + pchnl->state = CHNL_STATECANCEL; /* Allocate initial IOR and IOC queues: */ status = create_chirp_list(&pchnl->free_packets_list, @@ -817,7 +817,7 @@ int bridge_chnl_open(struct chnl_object **chnl, chnl_mgr_obj->open_channels++; spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock); /* Return result... */ - pchnl->dw_state = CHNL_STATEREADY; + pchnl->state = CHNL_STATEREADY; *chnl = pchnl; return status; diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index e89052c8c0e2..38c59dee50aa 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -483,7 +483,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) 1)) == 0)) { status = hio_mgr->intf_fxns-> - pfn_brd_mem_map(hio_mgr->hbridge_context, + brd_mem_map(hio_mgr->hbridge_context, pa_curr, va_curr, page_size[i], map_attrs, NULL); @@ -549,7 +549,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) } else { status = hio_mgr->intf_fxns-> - pfn_brd_mem_map(hio_mgr->hbridge_context, + brd_mem_map(hio_mgr->hbridge_context, pa_curr, va_curr, page_size[i], map_attrs, NULL); @@ -615,7 +615,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) ae_proc[ndx].ul_dsp_va); ndx++; } else { - status = hio_mgr->intf_fxns->pfn_brd_mem_map + status = hio_mgr->intf_fxns->brd_mem_map (hio_mgr->hbridge_context, hio_mgr->ext_proc_info.ty_tlb[i]. ul_gpp_phys, @@ -637,7 +637,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) /* Map the L4 peripherals */ i = 0; while (l4_peripheral_table[i].phys_addr) { - status = hio_mgr->intf_fxns->pfn_brd_mem_map + status = hio_mgr->intf_fxns->brd_mem_map (hio_mgr->hbridge_context, l4_peripheral_table[i].phys_addr, l4_peripheral_table[i].dsp_virt_addr, HW_PAGE_SIZE4KB, map_attrs, NULL); @@ -977,8 +977,8 @@ void io_request_chnl(struct io_mgr *io_manager, struct chnl_object *pchnl, * Assertion fires if CHNL_AddIOReq() called on a stream * which was cancelled, or attached to a dead board. */ - DBC_ASSERT((pchnl->dw_state == CHNL_STATEREADY) || - (pchnl->dw_state == CHNL_STATEEOS)); + DBC_ASSERT((pchnl->state == CHNL_STATEREADY) || + (pchnl->state == CHNL_STATEEOS)); /* Indicate to the DSP we have a buffer available for input */ set_chnl_busy(sm, pchnl->chnl_id); *mbx_val = MBX_PCPY_CLASS; @@ -987,7 +987,7 @@ void io_request_chnl(struct io_mgr *io_manager, struct chnl_object *pchnl, * This assertion fails if CHNL_AddIOReq() was called on a * stream which was cancelled, or attached to a dead board. */ - DBC_ASSERT((pchnl->dw_state & ~CHNL_STATEEOS) == + DBC_ASSERT((pchnl->state & ~CHNL_STATEEOS) == CHNL_STATEREADY); /* * Record the fact that we have a buffer available for @@ -1092,7 +1092,7 @@ static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, } pchnl = chnl_mgr_obj->ap_channel[chnl_id]; if ((pchnl != NULL) && CHNL_IS_INPUT(pchnl->chnl_mode)) { - if ((pchnl->dw_state & ~CHNL_STATEEOS) == CHNL_STATEREADY) { + if ((pchnl->state & ~CHNL_STATEEOS) == CHNL_STATEREADY) { /* Get the I/O request, and attempt a transfer */ if (!list_empty(&pchnl->pio_requests)) { if (!pchnl->cio_reqs) @@ -1122,7 +1122,7 @@ static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, * sends EOS more than once on this * channel. */ - if (pchnl->dw_state & CHNL_STATEEOS) + if (pchnl->state & CHNL_STATEEOS) goto func_end; /* * Zero bytes indicates EOS. Update @@ -1131,7 +1131,7 @@ static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, */ chnl_packet_obj->status |= CHNL_IOCSTATEOS; - pchnl->dw_state |= CHNL_STATEEOS; + pchnl->state |= CHNL_STATEEOS; /* * Notify that end of stream has * occurred. @@ -1329,7 +1329,7 @@ static void output_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, if (sm->output_full) goto func_end; - if (pchnl && !((pchnl->dw_state & ~CHNL_STATEEOS) == CHNL_STATEREADY)) + if (pchnl && !((pchnl->state & ~CHNL_STATEEOS) == CHNL_STATEREADY)) goto func_end; /* Look to see if both a PC and DSP output channel are ready */ @@ -1810,7 +1810,7 @@ int print_dsp_trace_buffer(struct bridge_dev_context *hbridge_context) psz_buf = kzalloc(ul_num_bytes + 2, GFP_ATOMIC); if (psz_buf != NULL) { /* Read trace buffer data */ - status = (*intf_fxns->pfn_brd_read)(pbridge_context, + status = (*intf_fxns->brd_read)(pbridge_context, (u8 *)psz_buf, (u32)ul_trace_begin, ul_num_bytes, 0); @@ -1825,7 +1825,7 @@ int print_dsp_trace_buffer(struct bridge_dev_context *hbridge_context) __func__, psz_buf); /* Read the value at the DSP address in trace_cur_pos. */ - status = (*intf_fxns->pfn_brd_read)(pbridge_context, + status = (*intf_fxns->brd_read)(pbridge_context, (u8 *)&trace_cur_pos, (u32)trace_cur_pos, 4, 0); if (status) @@ -1992,7 +1992,7 @@ int dump_dsp_stack(struct bridge_dev_context *bridge_context) poll_cnt < POLL_MAX) { /* Read DSP dump size from the DSP trace buffer... */ - status = (*intf_fxns->pfn_brd_read)(bridge_context, + status = (*intf_fxns->brd_read)(bridge_context, (u8 *)&mmu_fault_dbg_info, (u32)trace_begin, sizeof(mmu_fault_dbg_info), 0); @@ -2028,7 +2028,7 @@ int dump_dsp_stack(struct bridge_dev_context *bridge_context) buffer_end = buffer + total_size / 4; /* Read bytes from the DSP trace buffer... */ - status = (*intf_fxns->pfn_brd_read)(bridge_context, + status = (*intf_fxns->brd_read)(bridge_context, (u8 *)buffer, (u32)trace_begin, total_size, 0); if (status) { @@ -2189,7 +2189,7 @@ void dump_dl_modules(struct bridge_dev_context *bridge_context) pr_debug("%s: _DLModules at 0x%x\n", __func__, module_dsp_addr); /* Copy the modules_header structure from DSP memory. */ - status = (*intf_fxns->pfn_brd_read)(bridge_context, (u8 *) &modules_hdr, + status = (*intf_fxns->brd_read)(bridge_context, (u8 *) &modules_hdr, (u32) module_dsp_addr, sizeof(modules_hdr), 0); if (status) { @@ -2224,7 +2224,7 @@ void dump_dl_modules(struct bridge_dev_context *bridge_context) goto func_end; } /* Copy the dll_module structure from DSP memory */ - status = (*intf_fxns->pfn_brd_read)(bridge_context, + status = (*intf_fxns->brd_read)(bridge_context, (u8 *)module_struct, module_dsp_addr, module_size, 0); if (status) { diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 5964a13d0b84..8f39e11e726a 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -765,7 +765,7 @@ static int bridge_dev_create(struct bridge_dev_context } dev_context->dsp_start_add = (u32) OMAP_GEM_BASE; - dev_context->dw_self_loop = (u32) NULL; + dev_context->self_loop = (u32) NULL; dev_context->dsp_per_clks = 0; dev_context->internal_size = OMAP_DSP_SIZE; /* Clear dev context MMU table entries. diff --git a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h b/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h index ea547380012b..318f6b007d59 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h +++ b/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h @@ -127,7 +127,7 @@ struct chnl_mgr { u8 max_channels; /* Total number of channels */ u8 open_channels; /* Total number of open channels */ struct chnl_object **ap_channel; /* Array of channels */ - u8 dw_type; /* Type of channel class library */ + u8 type; /* Type of channel class library */ /* If no shm syms, return for CHNL_Open */ int chnl_open_status; }; @@ -140,7 +140,7 @@ struct chnl_object { /* Pointer back to channel manager */ struct chnl_mgr *chnl_mgr_obj; u32 chnl_id; /* Channel id */ - u8 dw_state; /* Current channel state */ + u8 state; /* Current channel state */ s8 chnl_mode; /* Chnl mode and attributes */ /* Chnl I/O completion event (user mode) */ void *user_event; diff --git a/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h b/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h index 29e66dd525e8..e79cbd583c0b 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h @@ -59,7 +59,7 @@ struct chnl_info { /*Abstraction of I/O completion event. */ struct sync_object *sync_event; s8 mode; /* Channel mode. */ - u8 dw_state; /* Current channel state. */ + u8 state; /* Current channel state. */ u32 bytes_tx; /* Total bytes transferred. */ u32 cio_cs; /* Number of IOCs in queue. */ u32 cio_reqs; /* Number of IO Requests in queue. */ @@ -68,7 +68,7 @@ struct chnl_info { /* Channel manager info: */ struct chnl_mgrinfo { - u8 dw_type; /* Type of channel class library. */ + u8 type; /* Type of channel class library. */ /* Channel handle, given the channel id. */ struct chnl_object *chnl_obj; u8 open_channels; /* Number of open channels. */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h index 8cd1494ccc84..719628e0e600 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h @@ -60,7 +60,7 @@ struct cmm_seginfo { u32 ul_dsp_size; /* DSP seg size in bytes */ /* # of current GPP allocations from this segment */ u32 ul_in_use_cnt; - u32 dw_seg_base_va; /* Start Virt address of SM seg */ + u32 seg_base_va; /* Start Virt address of SM seg */ }; @@ -83,8 +83,8 @@ struct cmm_xlatorattrs { u32 dsp_buf_size; /* size of DSP-side bufs in GPP bytes */ /* Vm base address alloc'd in client process context */ void *vm_base; - /* dw_vm_size must be >= (dwMaxNumBufs * dwMaxSize) */ - u32 dw_vm_size; + /* vm_size must be >= (dwMaxNumBufs * dwMaxSize) */ + u32 vm_size; }; /* diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h index 6ba66c500e79..7a0573dd91f6 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h @@ -369,9 +369,9 @@ struct dsp_processorinfo { /* Error information of last DSP exception signalled to the GPP */ struct dsp_errorinfo { u32 err_mask; - u32 dw_val1; - u32 dw_val2; - u32 dw_val3; + u32 val1; + u32 val2; + u32 val3; }; /* The dsp_processorstate structure describes the state of a DSP processor */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h index 4eaeb21727b7..380d88843076 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h @@ -978,17 +978,17 @@ struct bridge_drv_interface { fxn_dev_create pfn_dev_create; /* Create device context */ fxn_dev_destroy pfn_dev_destroy; /* Destroy device context */ fxn_dev_ctrl pfn_dev_cntrl; /* Optional vendor interface */ - fxn_brd_monitor pfn_brd_monitor; /* Load and/or start monitor */ + fxn_brd_monitor brd_monitor; /* Load and/or start monitor */ fxn_brd_start pfn_brd_start; /* Start DSP program. */ fxn_brd_stop pfn_brd_stop; /* Stop/reset board. */ fxn_brd_status pfn_brd_status; /* Get current board status. */ - fxn_brd_read pfn_brd_read; /* Read board memory */ + fxn_brd_read brd_read; /* Read board memory */ fxn_brd_write pfn_brd_write; /* Write board memory. */ fxn_brd_setstate pfn_brd_set_state; /* Sets the Board State */ - fxn_brd_memcopy pfn_brd_mem_copy; /* Copies DSP Memory */ - fxn_brd_memwrite pfn_brd_mem_write; /* Write DSP Memory w/o halt */ - fxn_brd_memmap pfn_brd_mem_map; /* Maps MPU mem to DSP mem */ - fxn_brd_memunmap pfn_brd_mem_un_map; /* Unmaps MPU mem to DSP mem */ + fxn_brd_memcopy brd_mem_copy; /* Copies DSP Memory */ + fxn_brd_memwrite brd_mem_write; /* Write DSP Memory w/o halt */ + fxn_brd_memmap brd_mem_map; /* Maps MPU mem to DSP mem */ + fxn_brd_memunmap brd_mem_un_map; /* Unmaps MPU mem to DSP mem */ fxn_chnl_create pfn_chnl_create; /* Create channel manager. */ fxn_chnl_destroy pfn_chnl_destroy; /* Destroy channel manager. */ fxn_chnl_open pfn_chnl_open; /* Create a new channel. */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h b/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h index c85d3da3fe25..b1a9072a1ffc 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h @@ -280,7 +280,7 @@ typedef int(*nldr_unloadfxn) (struct nldr_nodeobject *nldr_node_obj, * ======== node_ldr_fxns ======== */ struct node_ldr_fxns { - nldr_allocatefxn pfn_allocate; + nldr_allocatefxn allocate; nldr_createfxn pfn_create; nldr_deletefxn pfn_delete; nldr_exitfxn pfn_exit; diff --git a/drivers/staging/tidspbridge/pmgr/cmm.c b/drivers/staging/tidspbridge/pmgr/cmm.c index d2fb6a4c0e3b..bc8571b53be9 100644 --- a/drivers/staging/tidspbridge/pmgr/cmm.c +++ b/drivers/staging/tidspbridge/pmgr/cmm.c @@ -64,7 +64,7 @@ struct cmm_allocator { /* sma */ unsigned int shm_base; /* Start of physical SM block */ u32 ul_sm_size; /* Size of SM block in bytes */ - unsigned int dw_vm_base; /* Start of VM block. (Dev driver + unsigned int vm_base; /* Start of VM block. (Dev driver * context for 'sma') */ u32 dsp_phys_addr_offset; /* DSP PA to GPP PA offset for this * SM space */ @@ -86,7 +86,7 @@ struct cmm_xlator { /* Pa<->Va translator object */ * base address for translator's ul_seg_id. * Only 1 segment ID currently supported. */ - unsigned int dw_virt_base; /* virtual base address */ + unsigned int virt_base; /* virtual base address */ u32 ul_virt_size; /* size of virt space in bytes */ u32 ul_seg_id; /* Segment Id */ }; @@ -122,14 +122,14 @@ static struct cmm_xlatorattrs cmm_dfltxlatorattrs = { 0, /* dsp_bufs */ 0, /* dsp_buf_size */ NULL, /* vm_base */ - 0, /* dw_vm_size */ + 0, /* vm_size */ }; /* SM node representing a block of memory. */ struct cmm_mnode { struct list_head link; /* must be 1st element */ u32 pa; /* Phys addr */ - u32 dw_va; /* Virtual address in device process context */ + u32 va; /* Virtual address in device process context */ u32 ul_size; /* SM block size in bytes */ u32 client_proc; /* Process that allocated this mem block */ }; @@ -200,7 +200,7 @@ void *cmm_calloc_buf(struct cmm_object *hcmm_mgr, u32 usize, * add to freelist */ new_node = get_node(cmm_mgr_obj, pnode->pa + usize, - pnode->dw_va + usize, + pnode->va + usize, (u32) delta_size); /* leftovers go free */ add_to_free_list(allocator, new_node); @@ -218,13 +218,13 @@ void *cmm_calloc_buf(struct cmm_object *hcmm_mgr, u32 usize, list_add_tail(&pnode->link, &allocator->in_use_list); buf_pa = (void *)pnode->pa; /* physical address */ /* clear mem */ - pbyte = (u8 *) pnode->dw_va; + pbyte = (u8 *) pnode->va; for (cnt = 0; cnt < (s32) usize; cnt++, pbyte++) *pbyte = 0; if (pp_buf_va != NULL) { /* Virtual address */ - *pp_buf_va = (void *)pnode->dw_va; + *pp_buf_va = (void *)pnode->va; } } mutex_unlock(&cmm_mgr_obj->cmm_lock); @@ -450,8 +450,8 @@ int cmm_get_info(struct cmm_object *hcmm_mgr, altr->dsp_base; cmm_info_obj->seg_info[ul_seg - 1].ul_dsp_size = altr->ul_dsp_size; - cmm_info_obj->seg_info[ul_seg - 1].dw_seg_base_va = - altr->dw_vm_base - altr->ul_dsp_size; + cmm_info_obj->seg_info[ul_seg - 1].seg_base_va = + altr->vm_base - altr->ul_dsp_size; cmm_info_obj->seg_info[ul_seg - 1].ul_in_use_cnt = 0; list_for_each_entry(curr, &altr->in_use_list, link) { @@ -539,12 +539,12 @@ int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr, psma->hcmm_mgr = hcmm_mgr; /* ref to parent */ psma->shm_base = dw_gpp_base_pa; /* SM Base phys */ psma->ul_sm_size = ul_size; /* SM segment size in bytes */ - psma->dw_vm_base = gpp_base_va; + psma->vm_base = gpp_base_va; psma->dsp_phys_addr_offset = dsp_addr_offset; psma->c_factor = c_factor; psma->dsp_base = dw_dsp_base; psma->ul_dsp_size = ul_dsp_size; - if (psma->dw_vm_base == 0) { + if (psma->vm_base == 0) { status = -EPERM; goto func_end; } @@ -556,7 +556,7 @@ int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr, /* Get a mem node for this hunk-o-memory */ new_node = get_node(cmm_mgr_obj, dw_gpp_base_pa, - psma->dw_vm_base, ul_size); + psma->vm_base, ul_size); /* Place node on the SM allocator's free list */ if (new_node) { list_add_tail(&new_node->link, &psma->free_list); @@ -649,8 +649,8 @@ static void un_register_gppsm_seg(struct cmm_allocator *psma) kfree(curr); } - if ((void *)psma->dw_vm_base != NULL) - MEM_UNMAP_LINEAR_ADDRESS((void *)psma->dw_vm_base); + if ((void *)psma->vm_base != NULL) + MEM_UNMAP_LINEAR_ADDRESS((void *)psma->vm_base); /* Free allocator itself */ kfree(psma); @@ -705,7 +705,7 @@ static struct cmm_mnode *get_node(struct cmm_object *cmm_mgr_obj, u32 dw_pa, } pnode->pa = dw_pa; - pnode->dw_va = dw_va; + pnode->va = dw_va; pnode->ul_size = ul_size; return pnode; @@ -770,7 +770,7 @@ static void add_to_free_list(struct cmm_allocator *allocator, } if (curr->pa == NEXT_PA(node)) { curr->pa = node->pa; - curr->dw_va = node->dw_va; + curr->va = node->va; curr->ul_size += node->ul_size; delete_node(allocator->hcmm_mgr, node); return; @@ -925,10 +925,10 @@ int cmm_xlator_info(struct cmm_xlatorobject *xlator, u8 ** paddr, if (xlator_obj) { if (set_info) { /* set translators virtual address range */ - xlator_obj->dw_virt_base = (u32) *paddr; + xlator_obj->virt_base = (u32) *paddr; xlator_obj->ul_virt_size = ul_size; } else { /* return virt base address */ - *paddr = (u8 *) xlator_obj->dw_virt_base; + *paddr = (u8 *) xlator_obj->virt_base; } } else { status = -EFAULT; @@ -969,18 +969,18 @@ void *cmm_xlator_translate(struct cmm_xlatorobject *xlator, void *paddr, dw_offset = (u8 *) paddr - (u8 *) (allocator->shm_base - allocator-> ul_dsp_size); - dw_addr_xlate = xlator_obj->dw_virt_base + dw_offset; + dw_addr_xlate = xlator_obj->virt_base + dw_offset; /* Check if translated Va base is in range */ - if ((dw_addr_xlate < xlator_obj->dw_virt_base) || + if ((dw_addr_xlate < xlator_obj->virt_base) || (dw_addr_xlate >= - (xlator_obj->dw_virt_base + + (xlator_obj->virt_base + xlator_obj->ul_virt_size))) { dw_addr_xlate = 0; /* bad address */ } } else { /* Gpp PA = Gpp Base + offset */ dw_offset = - (u8 *) paddr - (u8 *) xlator_obj->dw_virt_base; + (u8 *) paddr - (u8 *) xlator_obj->virt_base; dw_addr_xlate = allocator->shm_base - allocator->ul_dsp_size + dw_offset; diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c index e328dc1e1690..63ca8c7c550c 100644 --- a/drivers/staging/tidspbridge/pmgr/dev.c +++ b/drivers/staging/tidspbridge/pmgr/dev.c @@ -1082,17 +1082,17 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns, STORE_FXN(fxn_dev_create, pfn_dev_create); STORE_FXN(fxn_dev_destroy, pfn_dev_destroy); STORE_FXN(fxn_dev_ctrl, pfn_dev_cntrl); - STORE_FXN(fxn_brd_monitor, pfn_brd_monitor); + STORE_FXN(fxn_brd_monitor, brd_monitor); STORE_FXN(fxn_brd_start, pfn_brd_start); STORE_FXN(fxn_brd_stop, pfn_brd_stop); STORE_FXN(fxn_brd_status, pfn_brd_status); - STORE_FXN(fxn_brd_read, pfn_brd_read); + STORE_FXN(fxn_brd_read, brd_read); STORE_FXN(fxn_brd_write, pfn_brd_write); STORE_FXN(fxn_brd_setstate, pfn_brd_set_state); - STORE_FXN(fxn_brd_memcopy, pfn_brd_mem_copy); - STORE_FXN(fxn_brd_memwrite, pfn_brd_mem_write); - STORE_FXN(fxn_brd_memmap, pfn_brd_mem_map); - STORE_FXN(fxn_brd_memunmap, pfn_brd_mem_un_map); + STORE_FXN(fxn_brd_memcopy, brd_mem_copy); + STORE_FXN(fxn_brd_memwrite, brd_mem_write); + STORE_FXN(fxn_brd_memmap, brd_mem_map); + STORE_FXN(fxn_brd_memunmap, brd_mem_un_map); STORE_FXN(fxn_chnl_create, pfn_chnl_create); STORE_FXN(fxn_chnl_destroy, pfn_chnl_destroy); STORE_FXN(fxn_chnl_open, pfn_chnl_open); @@ -1123,11 +1123,11 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns, DBC_ENSURE(intf_fxns->pfn_dev_create != NULL); DBC_ENSURE(intf_fxns->pfn_dev_destroy != NULL); DBC_ENSURE(intf_fxns->pfn_dev_cntrl != NULL); - DBC_ENSURE(intf_fxns->pfn_brd_monitor != NULL); + DBC_ENSURE(intf_fxns->brd_monitor != NULL); DBC_ENSURE(intf_fxns->pfn_brd_start != NULL); DBC_ENSURE(intf_fxns->pfn_brd_stop != NULL); DBC_ENSURE(intf_fxns->pfn_brd_status != NULL); - DBC_ENSURE(intf_fxns->pfn_brd_read != NULL); + DBC_ENSURE(intf_fxns->brd_read != NULL); DBC_ENSURE(intf_fxns->pfn_brd_write != NULL); DBC_ENSURE(intf_fxns->pfn_chnl_create != NULL); DBC_ENSURE(intf_fxns->pfn_chnl_destroy != NULL); diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index 454fcc82584b..8dd05783059c 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -575,7 +575,7 @@ func_cont: if (!status) { /* Create object for dynamic loading */ - status = hnode_mgr->nldr_fxns.pfn_allocate(hnode_mgr->nldr_obj, + status = hnode_mgr->nldr_fxns.allocate(hnode_mgr->nldr_obj, (void *)pnode, &pnode->dcd_props. obj_data.node_obj, @@ -3075,7 +3075,7 @@ static u32 ovly(void *priv_ref, u32 dsp_run_addr, u32 dsp_load_addr, status = dev_get_bridge_context(hnode_mgr->hdev_obj, &hbridge_context); if (!status) { status = - (*intf_fxns->pfn_brd_mem_copy) (hbridge_context, + (*intf_fxns->brd_mem_copy) (hbridge_context, dsp_run_addr, dsp_load_addr, ul_num_bytes, (u32) mem_space); if (!status) @@ -3117,7 +3117,7 @@ static u32 mem_write(void *priv_ref, u32 dsp_add, void *pbuf, /* Call new MemWrite function */ intf_fxns = hnode_mgr->intf_fxns; status = dev_get_bridge_context(hnode_mgr->hdev_obj, &hbridge_context); - status = (*intf_fxns->pfn_brd_mem_write) (hbridge_context, pbuf, + status = (*intf_fxns->brd_mem_write) (hbridge_context, pbuf, dsp_add, ul_num_bytes, mem_sect_type); return ul_num_bytes; diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c index d5f6719774d8..03bc21403250 100644 --- a/drivers/staging/tidspbridge/rmgr/proc.c +++ b/drivers/staging/tidspbridge/rmgr/proc.c @@ -1397,7 +1397,7 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size, if (!map_obj) status = -ENOMEM; else - status = (*p_proc_object->intf_fxns->pfn_brd_mem_map) + status = (*p_proc_object->intf_fxns->brd_mem_map) (p_proc_object->hbridge_context, pa_align, va_align, size_align, ul_map_attr, map_obj->pages); } @@ -1720,7 +1720,7 @@ int proc_un_map(void *hprocessor, void *map_addr, status = dmm_un_map_memory(dmm_mgr, (u32) va_align, &size_align); /* Remove mapping from the page tables. */ if (!status) { - status = (*p_proc_object->intf_fxns->pfn_brd_mem_un_map) + status = (*p_proc_object->intf_fxns->brd_mem_un_map) (p_proc_object->hbridge_context, va_align, size_align); } @@ -1828,7 +1828,7 @@ static int proc_monitor(struct proc_object *proc_obj) } } /* Place the Board in the Monitor State */ - if (!((*proc_obj->intf_fxns->pfn_brd_monitor) + if (!((*proc_obj->intf_fxns->brd_monitor) (proc_obj->hbridge_context))) { status = 0; if (!((*proc_obj->intf_fxns->pfn_brd_status) diff --git a/drivers/staging/tidspbridge/rmgr/strm.c b/drivers/staging/tidspbridge/rmgr/strm.c index d36b31659890..4adb7a00cf70 100644 --- a/drivers/staging/tidspbridge/rmgr/strm.c +++ b/drivers/staging/tidspbridge/rmgr/strm.c @@ -344,7 +344,7 @@ int strm_get_info(struct strm_object *stream_obj, stream_info->user_strm->ul_number_bytes = chnl_info_obj.bytes_tx; stream_info->user_strm->sync_object_handle = chnl_info_obj.event_obj; /* Determine stream state based on channel state and info */ - if (chnl_info_obj.dw_state & CHNL_STATEEOS) { + if (chnl_info_obj.state & CHNL_STATEEOS) { stream_info->user_strm->ss_stream_state = STREAM_DONE; } else { if (chnl_info_obj.cio_cs > 0) -- cgit v1.2.3 From e17ba7f2020a38b3e5bc3f7cafc595d0ac639094 Mon Sep 17 00:00:00 2001 From: Rene Sapiens Date: Tue, 18 Jan 2011 03:19:06 +0000 Subject: staging: tidspbridge: set4 remove hungarian from structs hungarian notation will be removed from the elements inside structures, the next varibles will be renamed: Original: Replacement: pfn_brd_set_state brd_set_state pfn_brd_start brd_start pfn_brd_status brd_status pfn_brd_stop brd_stop pfn_brd_write brd_write pfn_chnl_add_io_req chnl_add_io_req pfn_chnl_cancel_io chnl_cancel_io pfn_chnl_close chnl_close pfn_chnl_create chnl_create pfn_chnl_destroy chnl_destroy pfn_chnl_flush_io chnl_flush_io pfn_chnl_get_info chnl_get_info pfn_chnl_get_ioc chnl_get_ioc pfn_chnl_get_mgr_info chnl_get_mgr_info pfn_chnl_idle chnl_idle pfn_chnl_open chnl_open pfn_chnl_register_notify chnl_register_notify pfn_create create pfn_delete delete pfn_dev_cntrl dev_cntrl Signed-off-by: Rene Sapiens Signed-off-by: Armando Uribe Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/core/io_sm.c | 8 +-- .../tidspbridge/include/dspbridge/dspdefs.h | 36 +++++------ .../tidspbridge/include/dspbridge/nldrdefs.h | 4 +- drivers/staging/tidspbridge/pmgr/chnl.c | 4 +- drivers/staging/tidspbridge/pmgr/dev.c | 72 +++++++++++----------- drivers/staging/tidspbridge/rmgr/disp.c | 16 ++--- drivers/staging/tidspbridge/rmgr/node.c | 4 +- drivers/staging/tidspbridge/rmgr/proc.c | 20 +++--- drivers/staging/tidspbridge/rmgr/pwr.c | 8 +-- drivers/staging/tidspbridge/rmgr/strm.c | 20 +++--- 10 files changed, 96 insertions(+), 96 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 38c59dee50aa..77ae2da11fd8 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -683,7 +683,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) */ status = - hio_mgr->intf_fxns->pfn_dev_cntrl(hio_mgr->hbridge_context, + hio_mgr->intf_fxns->dev_cntrl(hio_mgr->hbridge_context, BRDIOCTL_SETMMUCONFIG, ae_proc); if (status) @@ -829,7 +829,7 @@ static void io_dispatch_pm(struct io_mgr *pio_mgr) if (parg[0] == MBX_PM_HIBERNATE_EN) { dev_dbg(bridge, "PM: Hibernate command\n"); status = pio_mgr->intf_fxns-> - pfn_dev_cntrl(pio_mgr->hbridge_context, + dev_cntrl(pio_mgr->hbridge_context, BRDIOCTL_PWR_HIBERNATE, parg); if (status) pr_err("%s: hibernate cmd failed 0x%x\n", @@ -838,7 +838,7 @@ static void io_dispatch_pm(struct io_mgr *pio_mgr) parg[1] = pio_mgr->shared_mem->opp_request.rqst_opp_pt; dev_dbg(bridge, "PM: Requested OPP = 0x%x\n", parg[1]); status = pio_mgr->intf_fxns-> - pfn_dev_cntrl(pio_mgr->hbridge_context, + dev_cntrl(pio_mgr->hbridge_context, BRDIOCTL_CONSTRAINT_REQUEST, parg); if (status) dev_dbg(bridge, "PM: Failed to set constraint " @@ -847,7 +847,7 @@ static void io_dispatch_pm(struct io_mgr *pio_mgr) dev_dbg(bridge, "PM: clk control value of msg = 0x%x\n", parg[0]); status = pio_mgr->intf_fxns-> - pfn_dev_cntrl(pio_mgr->hbridge_context, + dev_cntrl(pio_mgr->hbridge_context, BRDIOCTL_CLK_CTRL, parg); if (status) dev_dbg(bridge, "PM: Failed to ctrl the DSP clk" diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h index 380d88843076..749c25e4ff64 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h @@ -977,32 +977,32 @@ struct bridge_drv_interface { u32 brd_api_minor_version; /* Set to BRD_API_MINOR_VERSION. */ fxn_dev_create pfn_dev_create; /* Create device context */ fxn_dev_destroy pfn_dev_destroy; /* Destroy device context */ - fxn_dev_ctrl pfn_dev_cntrl; /* Optional vendor interface */ + fxn_dev_ctrl dev_cntrl; /* Optional vendor interface */ fxn_brd_monitor brd_monitor; /* Load and/or start monitor */ - fxn_brd_start pfn_brd_start; /* Start DSP program. */ - fxn_brd_stop pfn_brd_stop; /* Stop/reset board. */ - fxn_brd_status pfn_brd_status; /* Get current board status. */ + fxn_brd_start brd_start; /* Start DSP program. */ + fxn_brd_stop brd_stop; /* Stop/reset board. */ + fxn_brd_status brd_status; /* Get current board status. */ fxn_brd_read brd_read; /* Read board memory */ - fxn_brd_write pfn_brd_write; /* Write board memory. */ - fxn_brd_setstate pfn_brd_set_state; /* Sets the Board State */ + fxn_brd_write brd_write; /* Write board memory. */ + fxn_brd_setstate brd_set_state; /* Sets the Board State */ fxn_brd_memcopy brd_mem_copy; /* Copies DSP Memory */ fxn_brd_memwrite brd_mem_write; /* Write DSP Memory w/o halt */ fxn_brd_memmap brd_mem_map; /* Maps MPU mem to DSP mem */ fxn_brd_memunmap brd_mem_un_map; /* Unmaps MPU mem to DSP mem */ - fxn_chnl_create pfn_chnl_create; /* Create channel manager. */ - fxn_chnl_destroy pfn_chnl_destroy; /* Destroy channel manager. */ - fxn_chnl_open pfn_chnl_open; /* Create a new channel. */ - fxn_chnl_close pfn_chnl_close; /* Close a channel. */ - fxn_chnl_addioreq pfn_chnl_add_io_req; /* Req I/O on a channel. */ - fxn_chnl_getioc pfn_chnl_get_ioc; /* Wait for I/O completion. */ - fxn_chnl_cancelio pfn_chnl_cancel_io; /* Cancl I/O on a channel. */ - fxn_chnl_flushio pfn_chnl_flush_io; /* Flush I/O. */ - fxn_chnl_getinfo pfn_chnl_get_info; /* Get channel specific info */ + fxn_chnl_create chnl_create; /* Create channel manager. */ + fxn_chnl_destroy chnl_destroy; /* Destroy channel manager. */ + fxn_chnl_open chnl_open; /* Create a new channel. */ + fxn_chnl_close chnl_close; /* Close a channel. */ + fxn_chnl_addioreq chnl_add_io_req; /* Req I/O on a channel. */ + fxn_chnl_getioc chnl_get_ioc; /* Wait for I/O completion. */ + fxn_chnl_cancelio chnl_cancel_io; /* Cancl I/O on a channel. */ + fxn_chnl_flushio chnl_flush_io; /* Flush I/O. */ + fxn_chnl_getinfo chnl_get_info; /* Get channel specific info */ /* Get channel manager info. */ - fxn_chnl_getmgrinfo pfn_chnl_get_mgr_info; - fxn_chnl_idle pfn_chnl_idle; /* Idle the channel */ + fxn_chnl_getmgrinfo chnl_get_mgr_info; + fxn_chnl_idle chnl_idle; /* Idle the channel */ /* Register for notif. */ - fxn_chnl_registernotify pfn_chnl_register_notify; + fxn_chnl_registernotify chnl_register_notify; fxn_io_create pfn_io_create; /* Create IO manager */ fxn_io_destroy pfn_io_destroy; /* Destroy IO manager */ fxn_io_onloaded pfn_io_on_loaded; /* Notify of program loaded */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h b/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h index b1a9072a1ffc..b4610af942a7 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h @@ -281,8 +281,8 @@ typedef int(*nldr_unloadfxn) (struct nldr_nodeobject *nldr_node_obj, */ struct node_ldr_fxns { nldr_allocatefxn allocate; - nldr_createfxn pfn_create; - nldr_deletefxn pfn_delete; + nldr_createfxn create; + nldr_deletefxn delete; nldr_exitfxn pfn_exit; nldr_getfxnaddrfxn pfn_get_fxn_addr; nldr_initfxn pfn_init; diff --git a/drivers/staging/tidspbridge/pmgr/chnl.c b/drivers/staging/tidspbridge/pmgr/chnl.c index 78b0d0f303d7..245de82e2d67 100644 --- a/drivers/staging/tidspbridge/pmgr/chnl.c +++ b/drivers/staging/tidspbridge/pmgr/chnl.c @@ -87,7 +87,7 @@ int chnl_create(struct chnl_mgr **channel_mgr, struct bridge_drv_interface *intf_fxns; dev_get_intf_fxns(hdev_obj, &intf_fxns); /* Let Bridge channel module finish the create: */ - status = (*intf_fxns->pfn_chnl_create) (&hchnl_mgr, hdev_obj, + status = (*intf_fxns->chnl_create) (&hchnl_mgr, hdev_obj, mgr_attrts); if (!status) { /* Fill in DSP API channel module's fields of the @@ -120,7 +120,7 @@ int chnl_destroy(struct chnl_mgr *hchnl_mgr) if (chnl_mgr_obj) { intf_fxns = chnl_mgr_obj->intf_fxns; /* Let Bridge channel module destroy the chnl_mgr: */ - status = (*intf_fxns->pfn_chnl_destroy) (hchnl_mgr); + status = (*intf_fxns->chnl_destroy) (hchnl_mgr); } else { status = -EFAULT; } diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c index 63ca8c7c550c..0cc64168f226 100644 --- a/drivers/staging/tidspbridge/pmgr/dev.c +++ b/drivers/staging/tidspbridge/pmgr/dev.c @@ -111,7 +111,7 @@ u32 dev_brd_write_fxn(void *arb, u32 dsp_add, void *host_buf, if (dev_obj) { /* Require of BrdWrite() */ DBC_ASSERT(dev_obj->hbridge_context != NULL); - status = (*dev_obj->bridge_interface.pfn_brd_write) ( + status = (*dev_obj->bridge_interface.brd_write) ( dev_obj->hbridge_context, host_buf, dsp_add, ul_num_bytes, mem_space); /* Special case of getting the address only */ @@ -1081,30 +1081,30 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns, if (bridge_version > 0) { STORE_FXN(fxn_dev_create, pfn_dev_create); STORE_FXN(fxn_dev_destroy, pfn_dev_destroy); - STORE_FXN(fxn_dev_ctrl, pfn_dev_cntrl); + STORE_FXN(fxn_dev_ctrl, dev_cntrl); STORE_FXN(fxn_brd_monitor, brd_monitor); - STORE_FXN(fxn_brd_start, pfn_brd_start); - STORE_FXN(fxn_brd_stop, pfn_brd_stop); - STORE_FXN(fxn_brd_status, pfn_brd_status); + STORE_FXN(fxn_brd_start, brd_start); + STORE_FXN(fxn_brd_stop, brd_stop); + STORE_FXN(fxn_brd_status, brd_status); STORE_FXN(fxn_brd_read, brd_read); - STORE_FXN(fxn_brd_write, pfn_brd_write); - STORE_FXN(fxn_brd_setstate, pfn_brd_set_state); + STORE_FXN(fxn_brd_write, brd_write); + STORE_FXN(fxn_brd_setstate, brd_set_state); STORE_FXN(fxn_brd_memcopy, brd_mem_copy); STORE_FXN(fxn_brd_memwrite, brd_mem_write); STORE_FXN(fxn_brd_memmap, brd_mem_map); STORE_FXN(fxn_brd_memunmap, brd_mem_un_map); - STORE_FXN(fxn_chnl_create, pfn_chnl_create); - STORE_FXN(fxn_chnl_destroy, pfn_chnl_destroy); - STORE_FXN(fxn_chnl_open, pfn_chnl_open); - STORE_FXN(fxn_chnl_close, pfn_chnl_close); - STORE_FXN(fxn_chnl_addioreq, pfn_chnl_add_io_req); - STORE_FXN(fxn_chnl_getioc, pfn_chnl_get_ioc); - STORE_FXN(fxn_chnl_cancelio, pfn_chnl_cancel_io); - STORE_FXN(fxn_chnl_flushio, pfn_chnl_flush_io); - STORE_FXN(fxn_chnl_getinfo, pfn_chnl_get_info); - STORE_FXN(fxn_chnl_getmgrinfo, pfn_chnl_get_mgr_info); - STORE_FXN(fxn_chnl_idle, pfn_chnl_idle); - STORE_FXN(fxn_chnl_registernotify, pfn_chnl_register_notify); + STORE_FXN(fxn_chnl_create, chnl_create); + STORE_FXN(fxn_chnl_destroy, chnl_destroy); + STORE_FXN(fxn_chnl_open, chnl_open); + STORE_FXN(fxn_chnl_close, chnl_close); + STORE_FXN(fxn_chnl_addioreq, chnl_add_io_req); + STORE_FXN(fxn_chnl_getioc, chnl_get_ioc); + STORE_FXN(fxn_chnl_cancelio, chnl_cancel_io); + STORE_FXN(fxn_chnl_flushio, chnl_flush_io); + STORE_FXN(fxn_chnl_getinfo, chnl_get_info); + STORE_FXN(fxn_chnl_getmgrinfo, chnl_get_mgr_info); + STORE_FXN(fxn_chnl_idle, chnl_idle); + STORE_FXN(fxn_chnl_registernotify, chnl_register_notify); STORE_FXN(fxn_io_create, pfn_io_create); STORE_FXN(fxn_io_destroy, pfn_io_destroy); STORE_FXN(fxn_io_onloaded, pfn_io_on_loaded); @@ -1122,25 +1122,25 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns, /* Ensure postcondition: */ DBC_ENSURE(intf_fxns->pfn_dev_create != NULL); DBC_ENSURE(intf_fxns->pfn_dev_destroy != NULL); - DBC_ENSURE(intf_fxns->pfn_dev_cntrl != NULL); + DBC_ENSURE(intf_fxns->dev_cntrl != NULL); DBC_ENSURE(intf_fxns->brd_monitor != NULL); - DBC_ENSURE(intf_fxns->pfn_brd_start != NULL); - DBC_ENSURE(intf_fxns->pfn_brd_stop != NULL); - DBC_ENSURE(intf_fxns->pfn_brd_status != NULL); + DBC_ENSURE(intf_fxns->brd_start != NULL); + DBC_ENSURE(intf_fxns->brd_stop != NULL); + DBC_ENSURE(intf_fxns->brd_status != NULL); DBC_ENSURE(intf_fxns->brd_read != NULL); - DBC_ENSURE(intf_fxns->pfn_brd_write != NULL); - DBC_ENSURE(intf_fxns->pfn_chnl_create != NULL); - DBC_ENSURE(intf_fxns->pfn_chnl_destroy != NULL); - DBC_ENSURE(intf_fxns->pfn_chnl_open != NULL); - DBC_ENSURE(intf_fxns->pfn_chnl_close != NULL); - DBC_ENSURE(intf_fxns->pfn_chnl_add_io_req != NULL); - DBC_ENSURE(intf_fxns->pfn_chnl_get_ioc != NULL); - DBC_ENSURE(intf_fxns->pfn_chnl_cancel_io != NULL); - DBC_ENSURE(intf_fxns->pfn_chnl_flush_io != NULL); - DBC_ENSURE(intf_fxns->pfn_chnl_get_info != NULL); - DBC_ENSURE(intf_fxns->pfn_chnl_get_mgr_info != NULL); - DBC_ENSURE(intf_fxns->pfn_chnl_idle != NULL); - DBC_ENSURE(intf_fxns->pfn_chnl_register_notify != NULL); + DBC_ENSURE(intf_fxns->brd_write != NULL); + DBC_ENSURE(intf_fxns->chnl_create != NULL); + DBC_ENSURE(intf_fxns->chnl_destroy != NULL); + DBC_ENSURE(intf_fxns->chnl_open != NULL); + DBC_ENSURE(intf_fxns->chnl_close != NULL); + DBC_ENSURE(intf_fxns->chnl_add_io_req != NULL); + DBC_ENSURE(intf_fxns->chnl_get_ioc != NULL); + DBC_ENSURE(intf_fxns->chnl_cancel_io != NULL); + DBC_ENSURE(intf_fxns->chnl_flush_io != NULL); + DBC_ENSURE(intf_fxns->chnl_get_info != NULL); + DBC_ENSURE(intf_fxns->chnl_get_mgr_info != NULL); + DBC_ENSURE(intf_fxns->chnl_idle != NULL); + DBC_ENSURE(intf_fxns->chnl_register_notify != NULL); DBC_ENSURE(intf_fxns->pfn_io_create != NULL); DBC_ENSURE(intf_fxns->pfn_io_destroy != NULL); DBC_ENSURE(intf_fxns->pfn_io_on_loaded != NULL); diff --git a/drivers/staging/tidspbridge/rmgr/disp.c b/drivers/staging/tidspbridge/rmgr/disp.c index 560069aade5a..02fc425eb6d9 100644 --- a/drivers/staging/tidspbridge/rmgr/disp.c +++ b/drivers/staging/tidspbridge/rmgr/disp.c @@ -141,7 +141,7 @@ int disp_create(struct disp_object **dispatch_obj, chnl_attr_obj.uio_reqs = CHNLIOREQS; chnl_attr_obj.event_obj = NULL; ul_chnl_id = disp_attrs->ul_chnl_offset + CHNLTORMSOFFSET; - status = (*intf_fxns->pfn_chnl_open) (&(disp_obj->chnl_to_dsp), + status = (*intf_fxns->chnl_open) (&(disp_obj->chnl_to_dsp), disp_obj->hchnl_mgr, CHNL_MODETODSP, ul_chnl_id, &chnl_attr_obj); @@ -149,7 +149,7 @@ int disp_create(struct disp_object **dispatch_obj, if (!status) { ul_chnl_id = disp_attrs->ul_chnl_offset + CHNLFROMRMSOFFSET; status = - (*intf_fxns->pfn_chnl_open) (&(disp_obj->chnl_from_dsp), + (*intf_fxns->chnl_open) (&(disp_obj->chnl_from_dsp), disp_obj->hchnl_mgr, CHNL_MODEFROMDSP, ul_chnl_id, &chnl_attr_obj); @@ -566,7 +566,7 @@ static void delete_disp(struct disp_object *disp_obj) if (disp_obj->chnl_from_dsp) { /* Channel close can fail only if the channel handle * is invalid. */ - status = (*intf_fxns->pfn_chnl_close) + status = (*intf_fxns->chnl_close) (disp_obj->chnl_from_dsp); if (status) { dev_dbg(bridge, "%s: Failed to close channel " @@ -575,7 +575,7 @@ static void delete_disp(struct disp_object *disp_obj) } if (disp_obj->chnl_to_dsp) { status = - (*intf_fxns->pfn_chnl_close) (disp_obj-> + (*intf_fxns->chnl_close) (disp_obj-> chnl_to_dsp); if (status) { dev_dbg(bridge, "%s: Failed to close channel to" @@ -667,13 +667,13 @@ static int send_message(struct disp_object *disp_obj, u32 timeout, pbuf = disp_obj->pbuf; /* Send the command */ - status = (*intf_fxns->pfn_chnl_add_io_req) (chnl_obj, pbuf, ul_bytes, 0, + status = (*intf_fxns->chnl_add_io_req) (chnl_obj, pbuf, ul_bytes, 0, 0L, dw_arg); if (status) goto func_end; status = - (*intf_fxns->pfn_chnl_get_ioc) (chnl_obj, timeout, &chnl_ioc_obj); + (*intf_fxns->chnl_get_ioc) (chnl_obj, timeout, &chnl_ioc_obj); if (!status) { if (!CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) { if (CHNL_IS_TIMED_OUT(chnl_ioc_obj)) @@ -688,13 +688,13 @@ static int send_message(struct disp_object *disp_obj, u32 timeout, chnl_obj = disp_obj->chnl_from_dsp; ul_bytes = REPLYSIZE; - status = (*intf_fxns->pfn_chnl_add_io_req) (chnl_obj, pbuf, ul_bytes, + status = (*intf_fxns->chnl_add_io_req) (chnl_obj, pbuf, ul_bytes, 0, 0L, dw_arg); if (status) goto func_end; status = - (*intf_fxns->pfn_chnl_get_ioc) (chnl_obj, timeout, &chnl_ioc_obj); + (*intf_fxns->chnl_get_ioc) (chnl_obj, timeout, &chnl_ioc_obj); if (!status) { if (CHNL_IS_TIMED_OUT(chnl_ioc_obj)) { status = -ETIME; diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index 8dd05783059c..bb7d3071c907 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -1367,7 +1367,7 @@ int node_create_mgr(struct node_mgr **node_man, nldr_attrs_obj.us_dsp_word_size = node_mgr_obj->udsp_word_size; nldr_attrs_obj.us_dsp_mau_size = node_mgr_obj->udsp_mau_size; node_mgr_obj->loader_init = node_mgr_obj->nldr_fxns.pfn_init(); - status = node_mgr_obj->nldr_fxns.pfn_create(&node_mgr_obj->nldr_obj, + status = node_mgr_obj->nldr_fxns.create(&node_mgr_obj->nldr_obj, hdev_obj, &nldr_attrs_obj); if (status) @@ -2608,7 +2608,7 @@ static void delete_node_mgr(struct node_mgr *hnode_mgr) /* Delete the loader */ if (hnode_mgr->nldr_obj) - hnode_mgr->nldr_fxns.pfn_delete(hnode_mgr->nldr_obj); + hnode_mgr->nldr_fxns.delete(hnode_mgr->nldr_obj); if (hnode_mgr->loader_init) hnode_mgr->nldr_fxns.pfn_exit(); diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c index 03bc21403250..8bc69243c0c9 100644 --- a/drivers/staging/tidspbridge/rmgr/proc.c +++ b/drivers/staging/tidspbridge/rmgr/proc.c @@ -540,7 +540,7 @@ int proc_ctrl(void *hprocessor, u32 dw_cmd, struct dsp_cbdata * arg) /* timeout = arg->cb_data; */ status = pwr_wake_dsp(timeout); } else - if (!((*p_proc_object->intf_fxns->pfn_dev_cntrl) + if (!((*p_proc_object->intf_fxns->dev_cntrl) (p_proc_object->hbridge_context, dw_cmd, arg))) { status = 0; @@ -995,7 +995,7 @@ int proc_get_state(void *hprocessor, if (p_proc_object) { /* First, retrieve BRD state information */ - status = (*p_proc_object->intf_fxns->pfn_brd_status) + status = (*p_proc_object->intf_fxns->brd_status) (p_proc_object->hbridge_context, &brd_status); if (!status) { switch (brd_status) { @@ -1262,7 +1262,7 @@ int proc_load(void *hprocessor, const s32 argc_index, } if (!status) { /* Update the Processor status to loaded */ - status = (*p_proc_object->intf_fxns->pfn_brd_set_state) + status = (*p_proc_object->intf_fxns->brd_set_state) (p_proc_object->hbridge_context, BRD_LOADED); if (!status) { p_proc_object->proc_state = PROC_LOADED; @@ -1304,7 +1304,7 @@ int proc_load(void *hprocessor, const s32 argc_index, kfree(new_envp); user_args[0] = pargv0; if (!status) { - if (!((*p_proc_object->intf_fxns->pfn_brd_status) + if (!((*p_proc_object->intf_fxns->brd_status) (p_proc_object->hbridge_context, &brd_state))) { pr_info("%s: Processor Loaded %s\n", __func__, pargv0); kfree(drv_datap->base_img); @@ -1580,7 +1580,7 @@ int proc_start(void *hprocessor) if (status) goto func_cont; - status = (*p_proc_object->intf_fxns->pfn_brd_start) + status = (*p_proc_object->intf_fxns->brd_start) (p_proc_object->hbridge_context, dw_dsp_addr); if (status) goto func_cont; @@ -1601,12 +1601,12 @@ int proc_start(void *hprocessor) /* Failed to Create Node Manager and DISP Object * Stop the Processor from running. Put it in STOPPED State */ (void)(*p_proc_object->intf_fxns-> - pfn_brd_stop) (p_proc_object->hbridge_context); + brd_stop) (p_proc_object->hbridge_context); p_proc_object->proc_state = PROC_STOPPED; } func_cont: if (!status) { - if (!((*p_proc_object->intf_fxns->pfn_brd_status) + if (!((*p_proc_object->intf_fxns->brd_status) (p_proc_object->hbridge_context, &brd_state))) { pr_info("%s: dsp in running state\n", __func__); DBC_ASSERT(brd_state != BRD_HIBERNATION); @@ -1659,7 +1659,7 @@ int proc_stop(void *hprocessor) /* It is OK to stop a device that does n't have nodes OR not started */ status = (*p_proc_object->intf_fxns-> - pfn_brd_stop) (p_proc_object->hbridge_context); + brd_stop) (p_proc_object->hbridge_context); if (!status) { dev_dbg(bridge, "%s: processor in standby mode\n", __func__); p_proc_object->proc_state = PROC_STOPPED; @@ -1672,7 +1672,7 @@ int proc_stop(void *hprocessor) dev_set_msg_mgr(p_proc_object->hdev_obj, NULL); } if (!((*p_proc_object-> - intf_fxns->pfn_brd_status) (p_proc_object-> + intf_fxns->brd_status) (p_proc_object-> hbridge_context, &brd_state))) DBC_ASSERT(brd_state == BRD_STOPPED); @@ -1831,7 +1831,7 @@ static int proc_monitor(struct proc_object *proc_obj) if (!((*proc_obj->intf_fxns->brd_monitor) (proc_obj->hbridge_context))) { status = 0; - if (!((*proc_obj->intf_fxns->pfn_brd_status) + if (!((*proc_obj->intf_fxns->brd_status) (proc_obj->hbridge_context, &brd_state))) DBC_ASSERT(brd_state == BRD_IDLE); } diff --git a/drivers/staging/tidspbridge/rmgr/pwr.c b/drivers/staging/tidspbridge/rmgr/pwr.c index 85cb1a2bc0b1..17748df351b9 100644 --- a/drivers/staging/tidspbridge/rmgr/pwr.c +++ b/drivers/staging/tidspbridge/rmgr/pwr.c @@ -67,7 +67,7 @@ int pwr_sleep_dsp(const u32 sleep_code, const u32 timeout) status = -EINVAL; if (status != -EINVAL) { - status = (*intf_fxns->pfn_dev_cntrl) (dw_context, + status = (*intf_fxns->dev_cntrl) (dw_context, ioctlcode, (void *)&arg); } @@ -97,7 +97,7 @@ int pwr_wake_dsp(const u32 timeout) if (!(dev_get_intf_fxns(hdev_obj, (struct bridge_drv_interface **)&intf_fxns))) { status = - (*intf_fxns->pfn_dev_cntrl) (dw_context, + (*intf_fxns->dev_cntrl) (dw_context, BRDIOCTL_WAKEUP, (void *)&arg); } @@ -131,7 +131,7 @@ int pwr_pm_pre_scale(u16 voltage_domain, u32 level) if (!(dev_get_intf_fxns(hdev_obj, (struct bridge_drv_interface **)&intf_fxns))) { status = - (*intf_fxns->pfn_dev_cntrl) (dw_context, + (*intf_fxns->dev_cntrl) (dw_context, BRDIOCTL_PRESCALE_NOTIFY, (void *)&arg); } @@ -165,7 +165,7 @@ int pwr_pm_post_scale(u16 voltage_domain, u32 level) if (!(dev_get_intf_fxns(hdev_obj, (struct bridge_drv_interface **)&intf_fxns))) { status = - (*intf_fxns->pfn_dev_cntrl) (dw_context, + (*intf_fxns->dev_cntrl) (dw_context, BRDIOCTL_POSTSCALE_NOTIFY, (void *)&arg); } diff --git a/drivers/staging/tidspbridge/rmgr/strm.c b/drivers/staging/tidspbridge/rmgr/strm.c index 4adb7a00cf70..66c32f171f30 100644 --- a/drivers/staging/tidspbridge/rmgr/strm.c +++ b/drivers/staging/tidspbridge/rmgr/strm.c @@ -165,7 +165,7 @@ int strm_close(struct strm_res_object *strmres, * -EPIPE */ intf_fxns = stream_obj->strm_mgr_obj->intf_fxns; status = - (*intf_fxns->pfn_chnl_get_info) (stream_obj->chnl_obj, + (*intf_fxns->chnl_get_info) (stream_obj->chnl_obj, &chnl_info_obj); DBC_ASSERT(!status); @@ -323,7 +323,7 @@ int strm_get_info(struct strm_object *stream_obj, intf_fxns = stream_obj->strm_mgr_obj->intf_fxns; status = - (*intf_fxns->pfn_chnl_get_info) (stream_obj->chnl_obj, + (*intf_fxns->chnl_get_info) (stream_obj->chnl_obj, &chnl_info_obj); if (status) goto func_end; @@ -377,7 +377,7 @@ int strm_idle(struct strm_object *stream_obj, bool flush_data) } else { intf_fxns = stream_obj->strm_mgr_obj->intf_fxns; - status = (*intf_fxns->pfn_chnl_idle) (stream_obj->chnl_obj, + status = (*intf_fxns->chnl_idle) (stream_obj->chnl_obj, stream_obj->utimeout, flush_data); } @@ -435,7 +435,7 @@ int strm_issue(struct strm_object *stream_obj, u8 *pbuf, u32 ul_bytes, } if (!status) { - status = (*intf_fxns->pfn_chnl_add_io_req) + status = (*intf_fxns->chnl_add_io_req) (stream_obj->chnl_obj, pbuf, ul_bytes, ul_buf_size, (u32) tmp_buf, dw_arg); } @@ -557,7 +557,7 @@ func_cont: chnl_mode = (dir == DSP_TONODE) ? CHNL_MODETODSP : CHNL_MODEFROMDSP; intf_fxns = strm_mgr_obj->intf_fxns; - status = (*intf_fxns->pfn_chnl_open) (&(strm_obj->chnl_obj), + status = (*intf_fxns->chnl_open) (&(strm_obj->chnl_obj), strm_mgr_obj->hchnl_mgr, chnl_mode, ul_chnl_id, &chnl_attr_obj); @@ -631,7 +631,7 @@ int strm_reclaim(struct strm_object *stream_obj, u8 ** buf_ptr, intf_fxns = stream_obj->strm_mgr_obj->intf_fxns; status = - (*intf_fxns->pfn_chnl_get_ioc) (stream_obj->chnl_obj, + (*intf_fxns->chnl_get_ioc) (stream_obj->chnl_obj, stream_obj->utimeout, &chnl_ioc_obj); if (!status) { @@ -719,7 +719,7 @@ int strm_register_notify(struct strm_object *stream_obj, u32 event_mask, intf_fxns = stream_obj->strm_mgr_obj->intf_fxns; status = - (*intf_fxns->pfn_chnl_register_notify) (stream_obj-> + (*intf_fxns->chnl_register_notify) (stream_obj-> chnl_obj, event_mask, notify_type, @@ -765,7 +765,7 @@ int strm_select(struct strm_object **strm_tab, u32 strms, /* Determine which channels have IO ready */ for (i = 0; i < strms; i++) { intf_fxns = strm_tab[i]->strm_mgr_obj->intf_fxns; - status = (*intf_fxns->pfn_chnl_get_info) (strm_tab[i]->chnl_obj, + status = (*intf_fxns->chnl_get_info) (strm_tab[i]->chnl_obj, &chnl_info_obj); if (status) { break; @@ -786,7 +786,7 @@ int strm_select(struct strm_object **strm_tab, u32 strms, for (i = 0; i < strms; i++) { intf_fxns = strm_tab[i]->strm_mgr_obj->intf_fxns; - status = (*intf_fxns->pfn_chnl_get_info) + status = (*intf_fxns->chnl_get_info) (strm_tab[i]->chnl_obj, &chnl_info_obj); if (status) break; @@ -832,7 +832,7 @@ static int delete_strm(struct strm_object *stream_obj) intf_fxns = stream_obj->strm_mgr_obj->intf_fxns; /* Channel close can fail only if the channel handle * is invalid. */ - status = (*intf_fxns->pfn_chnl_close) + status = (*intf_fxns->chnl_close) (stream_obj->chnl_obj); } /* Free all SM address translator resources */ -- cgit v1.2.3 From 09f133045c57c479cad02d44791534df3b5b056e Mon Sep 17 00:00:00 2001 From: Rene Sapiens Date: Tue, 18 Jan 2011 03:19:07 +0000 Subject: staging: tidspbridge: set5 remove hungarian from structs hungarian notation will be removed from the elements inside structures, the next varibles will be renamed: Original: Replacement: pfn_dev_create by dev_create pfn_dev_destroy dev_destroy pfn_exit exit pfn_get_fxn_addr get_fxn_addr pfn_init init pfn_io_create io_create pfn_io_destroy io_destroy pfn_io_get_proc_load io_get_proc_load pfn_io_on_loaded io_on_loaded pfn_load load pfn_msg_create msg_create pfn_msg_create_queue msg_create_queue pfn_msg_delete msg_delete pfn_msg_delete_queue msg_delete_queue pfn_msg_get msg_get pfn_msg_put msg_put pfn_msg_register_notify msg_register_notify pfn_msg_set_queue_id msg_set_queue_id pfn_ovly ovly pfn_unload unload Signed-off-by: Rene Sapiens Signed-off-by: Armando Uribe Signed-off-by: Omar Ramirez Luna --- .../tidspbridge/include/dspbridge/dspdefs.h | 28 ++++++------- .../tidspbridge/include/dspbridge/nldrdefs.h | 12 +++--- drivers/staging/tidspbridge/pmgr/dev.c | 46 +++++++++++----------- drivers/staging/tidspbridge/pmgr/io.c | 4 +- drivers/staging/tidspbridge/pmgr/msg.c | 4 +- drivers/staging/tidspbridge/rmgr/nldr.c | 4 +- drivers/staging/tidspbridge/rmgr/node.c | 46 +++++++++++----------- drivers/staging/tidspbridge/rmgr/proc.c | 4 +- 8 files changed, 74 insertions(+), 74 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h index 749c25e4ff64..7ba08cad1faf 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h @@ -975,8 +975,8 @@ typedef void (*fxn_msg_setqueueid) (struct msg_queue *msg_queue_obj, struct bridge_drv_interface { u32 brd_api_major_version; /* Set to BRD_API_MAJOR_VERSION. */ u32 brd_api_minor_version; /* Set to BRD_API_MINOR_VERSION. */ - fxn_dev_create pfn_dev_create; /* Create device context */ - fxn_dev_destroy pfn_dev_destroy; /* Destroy device context */ + fxn_dev_create dev_create; /* Create device context */ + fxn_dev_destroy dev_destroy; /* Destroy device context */ fxn_dev_ctrl dev_cntrl; /* Optional vendor interface */ fxn_brd_monitor brd_monitor; /* Load and/or start monitor */ fxn_brd_start brd_start; /* Start DSP program. */ @@ -1003,23 +1003,23 @@ struct bridge_drv_interface { fxn_chnl_idle chnl_idle; /* Idle the channel */ /* Register for notif. */ fxn_chnl_registernotify chnl_register_notify; - fxn_io_create pfn_io_create; /* Create IO manager */ - fxn_io_destroy pfn_io_destroy; /* Destroy IO manager */ - fxn_io_onloaded pfn_io_on_loaded; /* Notify of program loaded */ + fxn_io_create io_create; /* Create IO manager */ + fxn_io_destroy io_destroy; /* Destroy IO manager */ + fxn_io_onloaded io_on_loaded; /* Notify of program loaded */ /* Get Processor's current and predicted load */ - fxn_io_getprocload pfn_io_get_proc_load; - fxn_msg_create pfn_msg_create; /* Create message manager */ + fxn_io_getprocload io_get_proc_load; + fxn_msg_create msg_create; /* Create message manager */ /* Create message queue */ - fxn_msg_createqueue pfn_msg_create_queue; - fxn_msg_delete pfn_msg_delete; /* Delete message manager */ + fxn_msg_createqueue msg_create_queue; + fxn_msg_delete msg_delete; /* Delete message manager */ /* Delete message queue */ - fxn_msg_deletequeue pfn_msg_delete_queue; - fxn_msg_get pfn_msg_get; /* Get a message */ - fxn_msg_put pfn_msg_put; /* Send a message */ + fxn_msg_deletequeue msg_delete_queue; + fxn_msg_get msg_get; /* Get a message */ + fxn_msg_put msg_put; /* Send a message */ /* Register for notif. */ - fxn_msg_registernotify pfn_msg_register_notify; + fxn_msg_registernotify msg_register_notify; /* Set message queue id */ - fxn_msg_setqueueid pfn_msg_set_queue_id; + fxn_msg_setqueueid msg_set_queue_id; }; /* diff --git a/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h b/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h index b4610af942a7..b1cd1a48e00f 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h @@ -82,7 +82,7 @@ typedef u32(*nldr_writefxn) (void *priv_ref, * Attributes passed to nldr_create function. */ struct nldr_attrs { - nldr_ovlyfxn pfn_ovly; + nldr_ovlyfxn ovly; nldr_writefxn pfn_write; u16 us_dsp_word_size; u16 us_dsp_mau_size; @@ -283,11 +283,11 @@ struct node_ldr_fxns { nldr_allocatefxn allocate; nldr_createfxn create; nldr_deletefxn delete; - nldr_exitfxn pfn_exit; - nldr_getfxnaddrfxn pfn_get_fxn_addr; - nldr_initfxn pfn_init; - nldr_loadfxn pfn_load; - nldr_unloadfxn pfn_unload; + nldr_exitfxn exit; + nldr_getfxnaddrfxn get_fxn_addr; + nldr_initfxn init; + nldr_loadfxn load; + nldr_unloadfxn unload; }; #endif /* NLDRDEFS_ */ diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c index 0cc64168f226..b855e440daf2 100644 --- a/drivers/staging/tidspbridge/pmgr/dev.c +++ b/drivers/staging/tidspbridge/pmgr/dev.c @@ -188,7 +188,7 @@ int dev_create_device(struct dev_object **device_obj, /* Call fxn_dev_create() to get the Bridge's device * context handle. */ - status = (dev_obj->bridge_interface.pfn_dev_create) + status = (dev_obj->bridge_interface.dev_create) (&dev_obj->hbridge_context, dev_obj, host_res); /* Assert bridge_dev_create()'s ensure clause: */ @@ -382,7 +382,7 @@ int dev_destroy_device(struct dev_object *hdev_obj) /* Call the driver's bridge_dev_destroy() function: */ /* Require of DevDestroy */ if (dev_obj->hbridge_context) { - status = (*dev_obj->bridge_interface.pfn_dev_destroy) + status = (*dev_obj->bridge_interface.dev_destroy) (dev_obj->hbridge_context); dev_obj->hbridge_context = NULL; } else @@ -1079,8 +1079,8 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns, intf_fxns->brd_api_minor_version = drv_fxns->brd_api_minor_version; /* Install functions up to DSP API version .80 (first alpha): */ if (bridge_version > 0) { - STORE_FXN(fxn_dev_create, pfn_dev_create); - STORE_FXN(fxn_dev_destroy, pfn_dev_destroy); + STORE_FXN(fxn_dev_create, dev_create); + STORE_FXN(fxn_dev_destroy, dev_destroy); STORE_FXN(fxn_dev_ctrl, dev_cntrl); STORE_FXN(fxn_brd_monitor, brd_monitor); STORE_FXN(fxn_brd_start, brd_start); @@ -1105,23 +1105,23 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns, STORE_FXN(fxn_chnl_getmgrinfo, chnl_get_mgr_info); STORE_FXN(fxn_chnl_idle, chnl_idle); STORE_FXN(fxn_chnl_registernotify, chnl_register_notify); - STORE_FXN(fxn_io_create, pfn_io_create); - STORE_FXN(fxn_io_destroy, pfn_io_destroy); - STORE_FXN(fxn_io_onloaded, pfn_io_on_loaded); - STORE_FXN(fxn_io_getprocload, pfn_io_get_proc_load); - STORE_FXN(fxn_msg_create, pfn_msg_create); - STORE_FXN(fxn_msg_createqueue, pfn_msg_create_queue); - STORE_FXN(fxn_msg_delete, pfn_msg_delete); - STORE_FXN(fxn_msg_deletequeue, pfn_msg_delete_queue); - STORE_FXN(fxn_msg_get, pfn_msg_get); - STORE_FXN(fxn_msg_put, pfn_msg_put); - STORE_FXN(fxn_msg_registernotify, pfn_msg_register_notify); - STORE_FXN(fxn_msg_setqueueid, pfn_msg_set_queue_id); + STORE_FXN(fxn_io_create, io_create); + STORE_FXN(fxn_io_destroy, io_destroy); + STORE_FXN(fxn_io_onloaded, io_on_loaded); + STORE_FXN(fxn_io_getprocload, io_get_proc_load); + STORE_FXN(fxn_msg_create, msg_create); + STORE_FXN(fxn_msg_createqueue, msg_create_queue); + STORE_FXN(fxn_msg_delete, msg_delete); + STORE_FXN(fxn_msg_deletequeue, msg_delete_queue); + STORE_FXN(fxn_msg_get, msg_get); + STORE_FXN(fxn_msg_put, msg_put); + STORE_FXN(fxn_msg_registernotify, msg_register_notify); + STORE_FXN(fxn_msg_setqueueid, msg_set_queue_id); } /* Add code for any additional functions in newerBridge versions here */ /* Ensure postcondition: */ - DBC_ENSURE(intf_fxns->pfn_dev_create != NULL); - DBC_ENSURE(intf_fxns->pfn_dev_destroy != NULL); + DBC_ENSURE(intf_fxns->dev_create != NULL); + DBC_ENSURE(intf_fxns->dev_destroy != NULL); DBC_ENSURE(intf_fxns->dev_cntrl != NULL); DBC_ENSURE(intf_fxns->brd_monitor != NULL); DBC_ENSURE(intf_fxns->brd_start != NULL); @@ -1141,11 +1141,11 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns, DBC_ENSURE(intf_fxns->chnl_get_mgr_info != NULL); DBC_ENSURE(intf_fxns->chnl_idle != NULL); DBC_ENSURE(intf_fxns->chnl_register_notify != NULL); - DBC_ENSURE(intf_fxns->pfn_io_create != NULL); - DBC_ENSURE(intf_fxns->pfn_io_destroy != NULL); - DBC_ENSURE(intf_fxns->pfn_io_on_loaded != NULL); - DBC_ENSURE(intf_fxns->pfn_io_get_proc_load != NULL); - DBC_ENSURE(intf_fxns->pfn_msg_set_queue_id != NULL); + DBC_ENSURE(intf_fxns->io_create != NULL); + DBC_ENSURE(intf_fxns->io_destroy != NULL); + DBC_ENSURE(intf_fxns->io_on_loaded != NULL); + DBC_ENSURE(intf_fxns->io_get_proc_load != NULL); + DBC_ENSURE(intf_fxns->msg_set_queue_id != NULL); #undef STORE_FXN } diff --git a/drivers/staging/tidspbridge/pmgr/io.c b/drivers/staging/tidspbridge/pmgr/io.c index 0e8843fe31c2..01ef637c31dd 100644 --- a/drivers/staging/tidspbridge/pmgr/io.c +++ b/drivers/staging/tidspbridge/pmgr/io.c @@ -67,7 +67,7 @@ int io_create(struct io_mgr **io_man, struct dev_object *hdev_obj, dev_get_intf_fxns(hdev_obj, &intf_fxns); /* Let Bridge channel module finish the create: */ - status = (*intf_fxns->pfn_io_create) (&hio_mgr, hdev_obj, + status = (*intf_fxns->io_create) (&hio_mgr, hdev_obj, mgr_attrts); if (!status) { @@ -99,7 +99,7 @@ int io_destroy(struct io_mgr *hio_mgr) intf_fxns = pio_mgr->intf_fxns; /* Let Bridge channel module destroy the io_mgr: */ - status = (*intf_fxns->pfn_io_destroy) (hio_mgr); + status = (*intf_fxns->io_destroy) (hio_mgr); return status; } diff --git a/drivers/staging/tidspbridge/pmgr/msg.c b/drivers/staging/tidspbridge/pmgr/msg.c index abd436590627..a6916039eed6 100644 --- a/drivers/staging/tidspbridge/pmgr/msg.c +++ b/drivers/staging/tidspbridge/pmgr/msg.c @@ -64,7 +64,7 @@ int msg_create(struct msg_mgr **msg_man, /* Let Bridge message module finish the create: */ status = - (*intf_fxns->pfn_msg_create) (&hmsg_mgr, hdev_obj, msg_callback); + (*intf_fxns->msg_create) (&hmsg_mgr, hdev_obj, msg_callback); if (!status) { /* Fill in DSP API message module's fields of the msg_mgr @@ -96,7 +96,7 @@ void msg_delete(struct msg_mgr *hmsg_mgr) intf_fxns = msg_mgr_obj->intf_fxns; /* Let Bridge message module destroy the msg_mgr: */ - (*intf_fxns->pfn_msg_delete) (hmsg_mgr); + (*intf_fxns->msg_delete) (hmsg_mgr); } else { dev_dbg(bridge, "%s: Error hmsg_mgr handle: %p\n", __func__, hmsg_mgr); diff --git a/drivers/staging/tidspbridge/rmgr/nldr.c b/drivers/staging/tidspbridge/rmgr/nldr.c index d19cdb0f0860..0537346bcb6c 100644 --- a/drivers/staging/tidspbridge/rmgr/nldr.c +++ b/drivers/staging/tidspbridge/rmgr/nldr.c @@ -429,7 +429,7 @@ int nldr_create(struct nldr_object **nldr, DBC_REQUIRE(nldr != NULL); DBC_REQUIRE(hdev_obj != NULL); DBC_REQUIRE(pattrs != NULL); - DBC_REQUIRE(pattrs->pfn_ovly != NULL); + DBC_REQUIRE(pattrs->ovly != NULL); DBC_REQUIRE(pattrs->pfn_write != NULL); /* Allocate dynamic loader object */ @@ -534,7 +534,7 @@ int nldr_create(struct nldr_object **nldr, new_attrs.sym_lookup = (dbll_sym_lookup) get_symbol_value; new_attrs.sym_handle = nldr_obj; new_attrs.write = (dbll_write_fxn) pattrs->pfn_write; - nldr_obj->ovly_fxn = pattrs->pfn_ovly; + nldr_obj->ovly_fxn = pattrs->ovly; nldr_obj->write_fxn = pattrs->pfn_write; nldr_obj->ldr_attrs = new_attrs; } diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index bb7d3071c907..8008a5c0022b 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -564,7 +564,7 @@ func_cont: /* Create a message queue for this node */ intf_fxns = hnode_mgr->intf_fxns; status = - (*intf_fxns->pfn_msg_create_queue) (hnode_mgr->msg_mgr_obj, + (*intf_fxns->msg_create_queue) (hnode_mgr->msg_mgr_obj, &pnode->msg_queue_obj, 0, pnode->create_args.asa. @@ -596,7 +596,7 @@ func_cont: stack_seg_name, STACKSEGLABEL) == 0) { status = hnode_mgr->nldr_fxns. - pfn_get_fxn_addr(pnode->nldr_node_obj, "DYNEXT_BEG", + get_fxn_addr(pnode->nldr_node_obj, "DYNEXT_BEG", &dynext_base); if (status) pr_err("%s: Failed to get addr for DYNEXT_BEG" @@ -604,7 +604,7 @@ func_cont: status = hnode_mgr->nldr_fxns. - pfn_get_fxn_addr(pnode->nldr_node_obj, + get_fxn_addr(pnode->nldr_node_obj, "L1DSRAM_HEAP", &pul_value); if (status) @@ -1190,7 +1190,7 @@ int node_create(struct node_object *hnode) if (pdata->cpu_set_freq) (*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP3]); #endif - status = hnode_mgr->nldr_fxns.pfn_load(hnode->nldr_node_obj, + status = hnode_mgr->nldr_fxns.load(hnode->nldr_node_obj, NLDR_CREATE); /* Get address of node's create function */ if (!status) { @@ -1211,7 +1211,7 @@ int node_create(struct node_object *hnode) /* Get address of iAlg functions, if socket node */ if (!status) { if (node_type == NODE_DAISSOCKET) { - status = hnode_mgr->nldr_fxns.pfn_get_fxn_addr + status = hnode_mgr->nldr_fxns.get_fxn_addr (hnode->nldr_node_obj, hnode->dcd_props.obj_data.node_obj. pstr_i_alg_name, @@ -1232,7 +1232,7 @@ int node_create(struct node_object *hnode) /* Set the message queue id to the node env * pointer */ intf_fxns = hnode_mgr->intf_fxns; - (*intf_fxns->pfn_msg_set_queue_id) (hnode-> + (*intf_fxns->msg_set_queue_id) (hnode-> msg_queue_obj, hnode->node_env); } @@ -1243,7 +1243,7 @@ int node_create(struct node_object *hnode) if (hnode->loaded && hnode->phase_split) { /* If create code was dynamically loaded, we can now unload * it. */ - status1 = hnode_mgr->nldr_fxns.pfn_unload(hnode->nldr_node_obj, + status1 = hnode_mgr->nldr_fxns.unload(hnode->nldr_node_obj, NLDR_CREATE); hnode->loaded = false; } @@ -1362,11 +1362,11 @@ int node_create_mgr(struct node_mgr **node_man, /* Get loader functions and create loader */ node_mgr_obj->nldr_fxns = nldr_fxns; /* Dyn loader funcs */ - nldr_attrs_obj.pfn_ovly = ovly; + nldr_attrs_obj.ovly = ovly; nldr_attrs_obj.pfn_write = mem_write; nldr_attrs_obj.us_dsp_word_size = node_mgr_obj->udsp_word_size; nldr_attrs_obj.us_dsp_mau_size = node_mgr_obj->udsp_mau_size; - node_mgr_obj->loader_init = node_mgr_obj->nldr_fxns.pfn_init(); + node_mgr_obj->loader_init = node_mgr_obj->nldr_fxns.init(); status = node_mgr_obj->nldr_fxns.create(&node_mgr_obj->nldr_obj, hdev_obj, &nldr_attrs_obj); @@ -1450,7 +1450,7 @@ int node_delete(struct node_res_object *noderes, * is not * running */ status1 = hnode_mgr->nldr_fxns. - pfn_unload(pnode->nldr_node_obj, + unload(pnode->nldr_node_obj, NLDR_EXECUTE); pnode->loaded = false; NODE_SET_STATE(pnode, NODE_DONE); @@ -1461,7 +1461,7 @@ int node_delete(struct node_res_object *noderes, pnode->phase_split) { status = hnode_mgr->nldr_fxns. - pfn_load(pnode->nldr_node_obj, NLDR_DELETE); + load(pnode->nldr_node_obj, NLDR_DELETE); if (!status) pnode->loaded = true; else @@ -1502,7 +1502,7 @@ func_cont1: pnode->phase_split) { status1 = hnode_mgr->nldr_fxns. - pfn_unload(pnode->nldr_node_obj, + unload(pnode->nldr_node_obj, NLDR_EXECUTE); } if (status1) @@ -1510,7 +1510,7 @@ func_cont1: " 0x%x\n", __func__, status1); status1 = - hnode_mgr->nldr_fxns.pfn_unload(pnode-> + hnode_mgr->nldr_fxns.unload(pnode-> nldr_node_obj, NLDR_DELETE); pnode->loaded = false; @@ -1793,7 +1793,7 @@ int node_get_message(struct node_object *hnode, * available. */ intf_fxns = hnode_mgr->intf_fxns; status = - (*intf_fxns->pfn_msg_get) (hnode->msg_queue_obj, message, utimeout); + (*intf_fxns->msg_get) (hnode->msg_queue_obj, message, utimeout); /* Check if message contains SM descriptor */ if (status || !(message->cmd & DSP_RMSBUFDESC)) goto func_end; @@ -1942,7 +1942,7 @@ void node_on_exit(struct node_object *hnode, s32 node_status) NODE_SET_STATE(hnode, NODE_DONE); hnode->exit_status = node_status; if (hnode->loaded && hnode->phase_split) { - (void)hnode->hnode_mgr->nldr_fxns.pfn_unload(hnode-> + (void)hnode->hnode_mgr->nldr_fxns.unload(hnode-> nldr_node_obj, NLDR_EXECUTE); hnode->loaded = false; @@ -2125,7 +2125,7 @@ int node_put_message(struct node_object *hnode, } if (!status) { intf_fxns = hnode_mgr->intf_fxns; - status = (*intf_fxns->pfn_msg_put) (hnode->msg_queue_obj, + status = (*intf_fxns->msg_put) (hnode->msg_queue_obj, &new_msg, utimeout); } func_end: @@ -2173,7 +2173,7 @@ int node_register_notify(struct node_object *hnode, u32 event_mask, } else { /* Send Message part of event mask to msg_ctrl */ intf_fxns = hnode->hnode_mgr->intf_fxns; - status = (*intf_fxns->pfn_msg_register_notify) + status = (*intf_fxns->msg_register_notify) (hnode->msg_queue_obj, event_mask & DSP_NODEMESSAGEREADY, notify_type, hnotification); @@ -2255,7 +2255,7 @@ int node_run(struct node_object *hnode) /* If node's execute function is not loaded, load it */ if (!(hnode->loaded) && hnode->phase_split) { status = - hnode_mgr->nldr_fxns.pfn_load(hnode->nldr_node_obj, + hnode_mgr->nldr_fxns.load(hnode->nldr_node_obj, NLDR_EXECUTE); if (!status) { hnode->loaded = true; @@ -2389,7 +2389,7 @@ int node_terminate(struct node_object *hnode, int *pstatus) else kill_time_out = (hnode->utimeout) * 2; - status = (*intf_fxns->pfn_msg_put) (hnode->msg_queue_obj, &msg, + status = (*intf_fxns->msg_put) (hnode->msg_queue_obj, &msg, hnode->utimeout); if (status) goto func_cont; @@ -2405,7 +2405,7 @@ int node_terminate(struct node_object *hnode, int *pstatus) if (status != ETIME) goto func_cont; - status = (*intf_fxns->pfn_msg_put)(hnode->msg_queue_obj, + status = (*intf_fxns->msg_put)(hnode->msg_queue_obj, &killmsg, hnode->utimeout); if (status) goto func_cont; @@ -2477,7 +2477,7 @@ static void delete_node(struct node_object *hnode, /* Free msg_ctrl queue */ if (hnode->msg_queue_obj) { intf_fxns = hnode_mgr->intf_fxns; - (*intf_fxns->pfn_msg_delete_queue) (hnode-> + (*intf_fxns->msg_delete_queue) (hnode-> msg_queue_obj); hnode->msg_queue_obj = NULL; } @@ -2611,7 +2611,7 @@ static void delete_node_mgr(struct node_mgr *hnode_mgr) hnode_mgr->nldr_fxns.delete(hnode_mgr->nldr_obj); if (hnode_mgr->loader_init) - hnode_mgr->nldr_fxns.pfn_exit(); + hnode_mgr->nldr_fxns.exit(); kfree(hnode_mgr); } @@ -2772,7 +2772,7 @@ static int get_fxn_address(struct node_object *hnode, u32 * fxn_addr, } status = - hnode_mgr->nldr_fxns.pfn_get_fxn_addr(hnode->nldr_node_obj, + hnode_mgr->nldr_fxns.get_fxn_addr(hnode->nldr_node_obj, pstr_fxn_name, fxn_addr); return status; diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c index 8bc69243c0c9..6840d29cfc95 100644 --- a/drivers/staging/tidspbridge/rmgr/proc.c +++ b/drivers/staging/tidspbridge/rmgr/proc.c @@ -917,7 +917,7 @@ int proc_get_resource_info(void *hprocessor, u32 resource_type, if (hio_mgr) status = p_proc_object->intf_fxns-> - pfn_io_get_proc_load(hio_mgr, + io_get_proc_load(hio_mgr, (struct dsp_procloadstat *) &(resource_info->result. proc_load_stat)); @@ -1227,7 +1227,7 @@ int proc_load(void *hprocessor, const s32 argc_index, /* Set the Device object's message manager */ status = dev_get_io_mgr(p_proc_object->hdev_obj, &hio_mgr); if (hio_mgr) - status = (*p_proc_object->intf_fxns->pfn_io_on_loaded) + status = (*p_proc_object->intf_fxns->io_on_loaded) (hio_mgr); else status = -EFAULT; -- cgit v1.2.3 From dab7f7fee09b28034af3cac527b16927e4e2a193 Mon Sep 17 00:00:00 2001 From: Rene Sapiens Date: Tue, 18 Jan 2011 03:19:08 +0000 Subject: staging: tidspbridge: set6 remove hungarian from structs hungarian notation will be removed from the elements inside structures, the next varibles will be renamed: Original: Replacement: pfn_write write pf_phase_split phase_split ul_alignment alignment ul_bufsize bufsize ul_bufsize_rms bufsize_rms ul_chnl_buf_size chnl_buf_size ul_chnl_offset chnl_offset ul_code_mem_seg_mask code_mem_seg_mask ul_dais_arg dais_arg ul_data1 data1 ul_data_mem_seg_mask data_mem_seg_mask ul_dsp_addr dsp_addr ul_dsp_res_addr dsp_res_addr ul_dsp_size dsp_size ul_dsp_va dsp_va ul_dsp_virt dsp_virt ul_entry entry ul_external_mem_size external_mem_size ul_fxn_addrs fxn_addrs ul_gpp_pa gpp_pa Signed-off-by: Rene Sapiens Signed-off-by: Armando Uribe Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/core/io_sm.c | 50 ++++++++++----------- drivers/staging/tidspbridge/core/tiomap3430.c | 16 +++---- drivers/staging/tidspbridge/core/tiomap_io.c | 4 +- drivers/staging/tidspbridge/gen/uuidutil.c | 4 +- .../tidspbridge/include/dspbridge/cmmdefs.h | 4 +- .../tidspbridge/include/dspbridge/dbdcddef.h | 4 +- .../staging/tidspbridge/include/dspbridge/dbdefs.h | 4 +- .../staging/tidspbridge/include/dspbridge/disp.h | 4 +- .../tidspbridge/include/dspbridge/dspioctl.h | 4 +- .../tidspbridge/include/dspbridge/mgrpriv.h | 2 +- .../tidspbridge/include/dspbridge/nldrdefs.h | 2 +- .../tidspbridge/include/dspbridge/nodepriv.h | 2 +- drivers/staging/tidspbridge/pmgr/cmm.c | 22 ++++----- drivers/staging/tidspbridge/pmgr/cod.c | 6 +-- drivers/staging/tidspbridge/rmgr/dbdcd.c | 8 ++-- drivers/staging/tidspbridge/rmgr/disp.c | 18 ++++---- drivers/staging/tidspbridge/rmgr/nldr.c | 52 +++++++++++----------- drivers/staging/tidspbridge/rmgr/node.c | 40 ++++++++--------- 18 files changed, 123 insertions(+), 123 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 77ae2da11fd8..5be6e0f9f57e 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -121,7 +121,7 @@ struct io_mgr { u32 ul_gpp_read_pointer; /* GPP Read pointer to Trace buffer */ u8 *pmsg; u32 ul_gpp_va; - u32 ul_dsp_va; + u32 dsp_va; #endif /* IO Dpc */ u32 dpc_req; /* Number of requested DPC's. */ @@ -421,7 +421,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) ul_gpp_va = host_res->mem_base[1]; /* This is the virtual uncached ioremapped address!!! */ /* Why can't we directly take the DSPVA from the symbols? */ - ul_dsp_va = hio_mgr->ext_proc_info.ty_tlb[0].ul_dsp_virt; + ul_dsp_va = hio_mgr->ext_proc_info.ty_tlb[0].dsp_virt; ul_seg_size = (shm0_end - ul_dsp_va) * hio_mgr->word_size; ul_seg1_size = (ul_ext_end - ul_dyn_ext_base) * hio_mgr->word_size; @@ -527,13 +527,13 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) * This is the physical address written to * DSP MMU. */ - ae_proc[ndx].ul_gpp_pa = pa_curr; + ae_proc[ndx].gpp_pa = pa_curr; /* * This is the virtual uncached ioremapped * address!!! */ ae_proc[ndx].ul_gpp_va = gpp_va_curr; - ae_proc[ndx].ul_dsp_va = + ae_proc[ndx].dsp_va = va_curr / hio_mgr->word_size; ae_proc[ndx].ul_size = page_size[i]; ae_proc[ndx].endianism = HW_LITTLE_ENDIAN; @@ -541,9 +541,9 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) ae_proc[ndx].mixed_mode = HW_MMU_CPUES; dev_dbg(bridge, "shm MMU TLB entry PA %x" " VA %x DSP_VA %x Size %x\n", - ae_proc[ndx].ul_gpp_pa, + ae_proc[ndx].gpp_pa, ae_proc[ndx].ul_gpp_va, - ae_proc[ndx].ul_dsp_va * + ae_proc[ndx].dsp_va * hio_mgr->word_size, page_size[i]); ndx++; } else { @@ -556,9 +556,9 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) dev_dbg(bridge, "shm MMU PTE entry PA %x" " VA %x DSP_VA %x Size %x\n", - ae_proc[ndx].ul_gpp_pa, + ae_proc[ndx].gpp_pa, ae_proc[ndx].ul_gpp_va, - ae_proc[ndx].ul_dsp_va * + ae_proc[ndx].dsp_va * hio_mgr->word_size, page_size[i]); if (status) goto func_end; @@ -587,32 +587,32 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) ul_gpp_pa - 0x100000 && hio_mgr->ext_proc_info.ty_tlb[i].ul_gpp_phys <= ul_gpp_pa + ul_seg_size) - || (hio_mgr->ext_proc_info.ty_tlb[i].ul_dsp_virt > + || (hio_mgr->ext_proc_info.ty_tlb[i].dsp_virt > ul_dsp_va - 0x100000 / hio_mgr->word_size - && hio_mgr->ext_proc_info.ty_tlb[i].ul_dsp_virt <= + && hio_mgr->ext_proc_info.ty_tlb[i].dsp_virt <= ul_dsp_va + ul_seg_size / hio_mgr->word_size)) { dev_dbg(bridge, "CDB MMU entry %d conflicts with " "shm.\n\tCDB: GppPa %x, DspVa %x.\n\tSHM: " "GppPa %x, DspVa %x, Bytes %x.\n", i, hio_mgr->ext_proc_info.ty_tlb[i].ul_gpp_phys, - hio_mgr->ext_proc_info.ty_tlb[i].ul_dsp_virt, + hio_mgr->ext_proc_info.ty_tlb[i].dsp_virt, ul_gpp_pa, ul_dsp_va, ul_seg_size); status = -EPERM; } else { if (ndx < MAX_LOCK_TLB_ENTRIES) { - ae_proc[ndx].ul_dsp_va = + ae_proc[ndx].dsp_va = hio_mgr->ext_proc_info.ty_tlb[i]. - ul_dsp_virt; - ae_proc[ndx].ul_gpp_pa = + dsp_virt; + ae_proc[ndx].gpp_pa = hio_mgr->ext_proc_info.ty_tlb[i]. ul_gpp_phys; ae_proc[ndx].ul_gpp_va = 0; /* 1 MB */ ae_proc[ndx].ul_size = 0x100000; dev_dbg(bridge, "shm MMU entry PA %x " - "DSP_VA 0x%x\n", ae_proc[ndx].ul_gpp_pa, - ae_proc[ndx].ul_dsp_va); + "DSP_VA 0x%x\n", ae_proc[ndx].gpp_pa, + ae_proc[ndx].dsp_va); ndx++; } else { status = hio_mgr->intf_fxns->brd_mem_map @@ -620,7 +620,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) hio_mgr->ext_proc_info.ty_tlb[i]. ul_gpp_phys, hio_mgr->ext_proc_info.ty_tlb[i]. - ul_dsp_virt, 0x100000, map_attrs, + dsp_virt, 0x100000, map_attrs, NULL); } } @@ -647,8 +647,8 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) } for (i = ndx; i < BRDIOCTL_NUMOFMMUTLB; i++) { - ae_proc[i].ul_dsp_va = 0; - ae_proc[i].ul_gpp_pa = 0; + ae_proc[i].dsp_va = 0; + ae_proc[i].gpp_pa = 0; ae_proc[i].ul_gpp_va = 0; ae_proc[i].ul_size = 0; } @@ -668,12 +668,12 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) status = -EFAULT; goto func_end; } else { - if (ae_proc[0].ul_dsp_va > ul_shm_base) { + if (ae_proc[0].dsp_va > ul_shm_base) { status = -EPERM; goto func_end; } /* ul_shm_base may not be at ul_dsp_va address */ - ul_shm_base_offset = (ul_shm_base - ae_proc[0].ul_dsp_va) * + ul_shm_base_offset = (ul_shm_base - ae_proc[0].dsp_va) * hio_mgr->word_size; /* * bridge_dev_ctrl() will set dev context dsp-mmu info. In @@ -698,7 +698,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) } /* Register SM */ status = - register_shm_segs(hio_mgr, cod_man, ae_proc[0].ul_gpp_pa); + register_shm_segs(hio_mgr, cod_man, ae_proc[0].gpp_pa); } hio_mgr->shared_mem = (struct shm *)ul_shm_base; @@ -771,7 +771,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) if (!hio_mgr->pmsg) status = -ENOMEM; - hio_mgr->ul_dsp_va = ul_dsp_va; + hio_mgr->dsp_va = ul_dsp_va; hio_mgr->ul_gpp_va = (ul_gpp_va + ul_seg1_size + ul_pad_size); #endif @@ -1544,7 +1544,7 @@ static int register_shm_segs(struct io_mgr *hio_mgr, ul_gpp_phys = hio_mgr->ext_proc_info.ty_tlb[0].ul_gpp_phys; /* Get size in bytes */ ul_dsp_virt = - hio_mgr->ext_proc_info.ty_tlb[0].ul_dsp_virt * + hio_mgr->ext_proc_info.ty_tlb[0].dsp_virt * hio_mgr->word_size; /* * Calc byte offset used to convert GPP phys <-> DSP byte @@ -1694,7 +1694,7 @@ void print_dsp_debug_trace(struct io_mgr *hio_mgr) *(u32 *) (hio_mgr->ul_trace_buffer_current); ul_gpp_cur_pointer = hio_mgr->ul_gpp_va + (ul_gpp_cur_pointer - - hio_mgr->ul_dsp_va); + hio_mgr->dsp_va); /* No new debug messages available yet */ if (ul_gpp_cur_pointer == hio_mgr->ul_gpp_read_pointer) { diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 8f39e11e726a..87160bb13518 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -401,7 +401,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, ul_shm_base_virt *= DSPWORDSIZE; DBC_ASSERT(ul_shm_base_virt != 0); /* DSP Virtual address */ - ul_tlb_base_virt = dev_context->atlb_entry[0].ul_dsp_va; + ul_tlb_base_virt = dev_context->atlb_entry[0].dsp_va; DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt); ul_shm_offset_virt = ul_shm_base_virt - (ul_tlb_base_virt * DSPWORDSIZE); @@ -466,19 +466,19 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, .mixed_size = e->mixed_mode, }; - if (!e->ul_gpp_pa || !e->ul_dsp_va) + if (!e->gpp_pa || !e->dsp_va) continue; dev_dbg(bridge, "MMU %d, pa: 0x%x, va: 0x%x, size: 0x%x", itmp_entry_ndx, - e->ul_gpp_pa, - e->ul_dsp_va, + e->gpp_pa, + e->dsp_va, e->ul_size); hw_mmu_tlb_add(dev_context->dsp_mmu_base, - e->ul_gpp_pa, - e->ul_dsp_va, + e->gpp_pa, + e->dsp_va, e->ul_size, itmp_entry_ndx, &map_attrs, 1, 1); @@ -771,8 +771,8 @@ static int bridge_dev_create(struct bridge_dev_context /* Clear dev context MMU table entries. * These get set on bridge_io_on_loaded() call after program loaded. */ for (entry_ndx = 0; entry_ndx < BRDIOCTL_NUMOFMMUTLB; entry_ndx++) { - dev_context->atlb_entry[entry_ndx].ul_gpp_pa = - dev_context->atlb_entry[entry_ndx].ul_dsp_va = 0; + dev_context->atlb_entry[entry_ndx].gpp_pa = + dev_context->atlb_entry[entry_ndx].dsp_va = 0; } dev_context->dsp_base_addr = (u32) MEM_LINEAR_ADDRESS((void *) (config_param-> diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c index 574feade6efc..c60a55d5555a 100644 --- a/drivers/staging/tidspbridge/core/tiomap_io.c +++ b/drivers/staging/tidspbridge/core/tiomap_io.c @@ -134,7 +134,7 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt, if (!status) { ul_tlb_base_virt = - dev_context->atlb_entry[0].ul_dsp_va * DSPWORDSIZE; + dev_context->atlb_entry[0].dsp_va * DSPWORDSIZE; DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt); dw_ext_prog_virt_mem = dev_context->atlb_entry[0].ul_gpp_va; @@ -319,7 +319,7 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, if (!ret) { ul_tlb_base_virt = - dev_context->atlb_entry[0].ul_dsp_va * DSPWORDSIZE; + dev_context->atlb_entry[0].dsp_va * DSPWORDSIZE; DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt); if (symbols_reloaded) { diff --git a/drivers/staging/tidspbridge/gen/uuidutil.c b/drivers/staging/tidspbridge/gen/uuidutil.c index da39c4fbf334..2aa9b64c0f88 100644 --- a/drivers/staging/tidspbridge/gen/uuidutil.c +++ b/drivers/staging/tidspbridge/gen/uuidutil.c @@ -45,7 +45,7 @@ void uuid_uuid_to_string(struct dsp_uuid *uuid_obj, char *sz_uuid, i = snprintf(sz_uuid, size, "%.8X_%.4X_%.4X_%.2X%.2X_%.2X%.2X%.2X%.2X%.2X%.2X", - uuid_obj->ul_data1, uuid_obj->us_data2, uuid_obj->us_data3, + uuid_obj->data1, uuid_obj->us_data2, uuid_obj->us_data3, uuid_obj->uc_data4, uuid_obj->uc_data5, uuid_obj->uc_data6[0], uuid_obj->uc_data6[1], uuid_obj->uc_data6[2], uuid_obj->uc_data6[3], @@ -79,7 +79,7 @@ void uuid_uuid_from_string(char *sz_uuid, struct dsp_uuid *uuid_obj) { s32 j; - uuid_obj->ul_data1 = uuid_hex_to_bin(sz_uuid, 8); + uuid_obj->data1 = uuid_hex_to_bin(sz_uuid, 8); sz_uuid += 8; /* Step over underscore */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h index 719628e0e600..c00c5192cef9 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h @@ -29,7 +29,7 @@ struct cmm_mgrattrs { /* Attributes for CMM_AllocBuf() & CMM_AllocDesc() */ struct cmm_attrs { u32 ul_seg_id; /* 1,2... are SM segments. 0 is not. */ - u32 ul_alignment; /* 0,1,2,4....ul_min_block_size */ + u32 alignment; /* 0,1,2,4....ul_min_block_size */ }; /* @@ -57,7 +57,7 @@ struct cmm_seginfo { u32 gpp_base_pa; /* Start Phys addr of Gpp SM seg */ u32 ul_gpp_size; /* Size of Gpp SM seg in bytes */ u32 dsp_base_va; /* DSP virt base byte address */ - u32 ul_dsp_size; /* DSP seg size in bytes */ + u32 dsp_size; /* DSP seg size in bytes */ /* # of current GPP allocations from this segment */ u32 ul_in_use_cnt; u32 seg_base_va; /* Start Virt address of SM seg */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h b/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h index 1daa4b57b736..fc2a736ec971 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h @@ -55,8 +55,8 @@ struct dcd_nodeprops { /* Dynamic load properties */ u16 us_load_type; /* Static, dynamic, overlay */ - u32 ul_data_mem_seg_mask; /* Data memory requirements */ - u32 ul_code_mem_seg_mask; /* Code memory requirements */ + u32 data_mem_seg_mask; /* Data memory requirements */ + u32 code_mem_seg_mask; /* Code memory requirements */ }; /* DCD Generic Object Type */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h index 7a0573dd91f6..af90b6bd1356 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h @@ -99,7 +99,7 @@ static inline bool is_valid_proc_event(u32 x) /* The Node UUID structure */ struct dsp_uuid { - u32 ul_data1; + u32 data1; u16 us_data2; u16 us_data3; u8 uc_data4; @@ -359,7 +359,7 @@ struct dsp_processorinfo { int processor_type; u32 clock_rate; u32 ul_internal_mem_size; - u32 ul_external_mem_size; + u32 external_mem_size; u32 processor_id; int ty_running_rtos; s32 node_min_priority; diff --git a/drivers/staging/tidspbridge/include/dspbridge/disp.h b/drivers/staging/tidspbridge/include/dspbridge/disp.h index 41738c5b268e..5dfdc8cfb937 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/disp.h +++ b/drivers/staging/tidspbridge/include/dspbridge/disp.h @@ -27,9 +27,9 @@ struct disp_object; /* Node Dispatcher attributes */ struct disp_attr { - u32 ul_chnl_offset; /* Offset of channel ids reserved for RMS */ + u32 chnl_offset; /* Offset of channel ids reserved for RMS */ /* Size of buffer for sending data to RMS */ - u32 ul_chnl_buf_size; + u32 chnl_buf_size; int proc_family; /* eg, 5000 */ int proc_type; /* eg, 5510 */ void *reserved1; /* Reserved for future use. */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h index 54552a73d932..bcb39bf59439 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h @@ -55,8 +55,8 @@ #define BRDIOCTL_NUMOFMMUTLB 32 struct bridge_ioctl_extproc { - u32 ul_dsp_va; /* DSP virtual address */ - u32 ul_gpp_pa; /* GPP physical address */ + u32 dsp_va; /* DSP virtual address */ + u32 gpp_pa; /* GPP physical address */ /* GPP virtual address. __va does not work for ioremapped addresses */ u32 ul_gpp_va; u32 ul_size; /* Size of the mapped memory in bytes */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/mgrpriv.h b/drivers/staging/tidspbridge/include/dspbridge/mgrpriv.h index bca4e103c7f6..3ceeaa283ae5 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/mgrpriv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/mgrpriv.h @@ -28,7 +28,7 @@ struct mgr_object; struct mgr_tlbentry { - u32 ul_dsp_virt; /* DSP virtual address */ + u32 dsp_virt; /* DSP virtual address */ u32 ul_gpp_phys; /* GPP physical address */ }; diff --git a/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h b/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h index b1cd1a48e00f..0108fae64f56 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h @@ -83,7 +83,7 @@ typedef u32(*nldr_writefxn) (void *priv_ref, */ struct nldr_attrs { nldr_ovlyfxn ovly; - nldr_writefxn pfn_write; + nldr_writefxn write; u16 us_dsp_word_size; u16 us_dsp_mau_size; }; diff --git a/drivers/staging/tidspbridge/include/dspbridge/nodepriv.h b/drivers/staging/tidspbridge/include/dspbridge/nodepriv.h index 16b0233fc5d5..b14f79ac5bb0 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/nodepriv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/nodepriv.h @@ -62,7 +62,7 @@ struct node_taskargs { u32 profile_id; /* Profile ID */ u32 num_inputs; u32 num_outputs; - u32 ul_dais_arg; /* Address of iAlg object */ + u32 dais_arg; /* Address of iAlg object */ struct node_strmdef *strm_in_def; struct node_strmdef *strm_out_def; }; diff --git a/drivers/staging/tidspbridge/pmgr/cmm.c b/drivers/staging/tidspbridge/pmgr/cmm.c index bc8571b53be9..d217dc8da534 100644 --- a/drivers/staging/tidspbridge/pmgr/cmm.c +++ b/drivers/staging/tidspbridge/pmgr/cmm.c @@ -70,7 +70,7 @@ struct cmm_allocator { /* sma */ * SM space */ s8 c_factor; /* DSPPa to GPPPa Conversion Factor */ unsigned int dsp_base; /* DSP virt base byte address */ - u32 ul_dsp_size; /* DSP seg size in bytes */ + u32 dsp_size; /* DSP seg size in bytes */ struct cmm_object *hcmm_mgr; /* back ref to parent mgr */ /* node list of available memory */ struct list_head free_list; @@ -439,19 +439,19 @@ int cmm_get_info(struct cmm_object *hcmm_mgr, continue; cmm_info_obj->ul_num_gppsm_segs++; cmm_info_obj->seg_info[ul_seg - 1].seg_base_pa = - altr->shm_base - altr->ul_dsp_size; + altr->shm_base - altr->dsp_size; cmm_info_obj->seg_info[ul_seg - 1].ul_total_seg_size = - altr->ul_dsp_size + altr->ul_sm_size; + altr->dsp_size + altr->ul_sm_size; cmm_info_obj->seg_info[ul_seg - 1].gpp_base_pa = altr->shm_base; cmm_info_obj->seg_info[ul_seg - 1].ul_gpp_size = altr->ul_sm_size; cmm_info_obj->seg_info[ul_seg - 1].dsp_base_va = altr->dsp_base; - cmm_info_obj->seg_info[ul_seg - 1].ul_dsp_size = - altr->ul_dsp_size; + cmm_info_obj->seg_info[ul_seg - 1].dsp_size = + altr->dsp_size; cmm_info_obj->seg_info[ul_seg - 1].seg_base_va = - altr->vm_base - altr->ul_dsp_size; + altr->vm_base - altr->dsp_size; cmm_info_obj->seg_info[ul_seg - 1].ul_in_use_cnt = 0; list_for_each_entry(curr, &altr->in_use_list, link) { @@ -543,7 +543,7 @@ int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr, psma->dsp_phys_addr_offset = dsp_addr_offset; psma->c_factor = c_factor; psma->dsp_base = dw_dsp_base; - psma->ul_dsp_size = ul_dsp_size; + psma->dsp_size = ul_dsp_size; if (psma->vm_base == 0) { status = -EPERM; goto func_end; @@ -968,7 +968,7 @@ void *cmm_xlator_translate(struct cmm_xlatorobject *xlator, void *paddr, /* Gpp Va = Va Base + offset */ dw_offset = (u8 *) paddr - (u8 *) (allocator->shm_base - allocator-> - ul_dsp_size); + dsp_size); dw_addr_xlate = xlator_obj->virt_base + dw_offset; /* Check if translated Va base is in range */ if ((dw_addr_xlate < xlator_obj->virt_base) || @@ -982,7 +982,7 @@ void *cmm_xlator_translate(struct cmm_xlatorobject *xlator, void *paddr, dw_offset = (u8 *) paddr - (u8 *) xlator_obj->virt_base; dw_addr_xlate = - allocator->shm_base - allocator->ul_dsp_size + + allocator->shm_base - allocator->dsp_size + dw_offset; } } else { @@ -992,14 +992,14 @@ void *cmm_xlator_translate(struct cmm_xlatorobject *xlator, void *paddr, if ((xtype == CMM_VA2DSPPA) || (xtype == CMM_PA2DSPPA)) { /* Got Gpp Pa now, convert to DSP Pa */ dw_addr_xlate = - GPPPA2DSPPA((allocator->shm_base - allocator->ul_dsp_size), + GPPPA2DSPPA((allocator->shm_base - allocator->dsp_size), dw_addr_xlate, allocator->dsp_phys_addr_offset * allocator->c_factor); } else if (xtype == CMM_DSPPA2PA) { /* Got DSP Pa, convert to GPP Pa */ dw_addr_xlate = - DSPPA2GPPPA(allocator->shm_base - allocator->ul_dsp_size, + DSPPA2GPPPA(allocator->shm_base - allocator->dsp_size, dw_addr_xlate, allocator->dsp_phys_addr_offset * allocator->c_factor); diff --git a/drivers/staging/tidspbridge/pmgr/cod.c b/drivers/staging/tidspbridge/pmgr/cod.c index 17ea57d0d48b..1a29264b5853 100644 --- a/drivers/staging/tidspbridge/pmgr/cod.c +++ b/drivers/staging/tidspbridge/pmgr/cod.c @@ -47,7 +47,7 @@ struct cod_manager { struct dbll_tar_obj *target; struct dbll_library_obj *base_lib; bool loaded; /* Base library loaded? */ - u32 ul_entry; + u32 entry; struct dbll_fxns fxns; struct dbll_attrs attrs; char sz_zl_file[COD_MAXPATHLENGTH]; @@ -346,7 +346,7 @@ int cod_get_entry(struct cod_manager *cod_mgr_obj, u32 *entry_pt) DBC_REQUIRE(cod_mgr_obj); DBC_REQUIRE(entry_pt != NULL); - *entry_pt = cod_mgr_obj->ul_entry; + *entry_pt = cod_mgr_obj->entry; return 0; } @@ -516,7 +516,7 @@ int cod_load_base(struct cod_manager *cod_mgr_obj, u32 num_argc, char *args[], flags = DBLL_CODE | DBLL_DATA | DBLL_SYMB; status = cod_mgr_obj->fxns.load_fxn(cod_mgr_obj->base_lib, flags, &new_attrs, - &cod_mgr_obj->ul_entry); + &cod_mgr_obj->entry); if (status) cod_mgr_obj->fxns.close_fxn(cod_mgr_obj->base_lib); diff --git a/drivers/staging/tidspbridge/rmgr/dbdcd.c b/drivers/staging/tidspbridge/rmgr/dbdcd.c index 9e12a2c07f41..f0b396f07d15 100644 --- a/drivers/staging/tidspbridge/rmgr/dbdcd.c +++ b/drivers/staging/tidspbridge/rmgr/dbdcd.c @@ -1227,14 +1227,14 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size, /* Dynamic load data requirements */ if (token) { - gen_obj->obj_data.node_obj.ul_data_mem_seg_mask = + gen_obj->obj_data.node_obj.data_mem_seg_mask = atoi(token); token = strsep(&psz_cur, seps); } /* Dynamic load code requirements */ if (token) { - gen_obj->obj_data.node_obj.ul_code_mem_seg_mask = + gen_obj->obj_data.node_obj.code_mem_seg_mask = atoi(token); token = strsep(&psz_cur, seps); } @@ -1288,7 +1288,7 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size, gen_obj->obj_data.proc_info.ul_internal_mem_size = atoi(token); token = strsep(&psz_cur, seps); - gen_obj->obj_data.proc_info.ul_external_mem_size = atoi(token); + gen_obj->obj_data.proc_info.external_mem_size = atoi(token); token = strsep(&psz_cur, seps); gen_obj->obj_data.proc_info.processor_id = atoi(token); @@ -1312,7 +1312,7 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size, token = strsep(&psz_cur, seps); gen_obj->obj_data.ext_proc_obj.ty_tlb[entry_id]. - ul_dsp_virt = atoi(token); + dsp_virt = atoi(token); } #endif diff --git a/drivers/staging/tidspbridge/rmgr/disp.c b/drivers/staging/tidspbridge/rmgr/disp.c index 02fc425eb6d9..49e38f36b05d 100644 --- a/drivers/staging/tidspbridge/rmgr/disp.c +++ b/drivers/staging/tidspbridge/rmgr/disp.c @@ -65,8 +65,8 @@ struct disp_object { struct chnl_object *chnl_to_dsp; /* Chnl for commands to RMS */ struct chnl_object *chnl_from_dsp; /* Chnl for replies from RMS */ u8 *pbuf; /* Buffer for commands, replies */ - u32 ul_bufsize; /* pbuf size in bytes */ - u32 ul_bufsize_rms; /* pbuf size in RMS words */ + u32 bufsize; /* buf size in bytes */ + u32 bufsize_rms; /* buf size in RMS words */ u32 char_size; /* Size of DSP character */ u32 word_size; /* Size of DSP word */ u32 data_mau_size; /* Size of DSP Data MAU */ @@ -140,14 +140,14 @@ int disp_create(struct disp_object **dispatch_obj, /* Open channels for communicating with the RMS */ chnl_attr_obj.uio_reqs = CHNLIOREQS; chnl_attr_obj.event_obj = NULL; - ul_chnl_id = disp_attrs->ul_chnl_offset + CHNLTORMSOFFSET; + ul_chnl_id = disp_attrs->chnl_offset + CHNLTORMSOFFSET; status = (*intf_fxns->chnl_open) (&(disp_obj->chnl_to_dsp), disp_obj->hchnl_mgr, CHNL_MODETODSP, ul_chnl_id, &chnl_attr_obj); if (!status) { - ul_chnl_id = disp_attrs->ul_chnl_offset + CHNLFROMRMSOFFSET; + ul_chnl_id = disp_attrs->chnl_offset + CHNLFROMRMSOFFSET; status = (*intf_fxns->chnl_open) (&(disp_obj->chnl_from_dsp), disp_obj->hchnl_mgr, @@ -156,9 +156,9 @@ int disp_create(struct disp_object **dispatch_obj, } if (!status) { /* Allocate buffer for commands, replies */ - disp_obj->ul_bufsize = disp_attrs->ul_chnl_buf_size; - disp_obj->ul_bufsize_rms = RMS_COMMANDBUFSIZE; - disp_obj->pbuf = kzalloc(disp_obj->ul_bufsize, GFP_KERNEL); + disp_obj->bufsize = disp_attrs->chnl_buf_size; + disp_obj->bufsize_rms = RMS_COMMANDBUFSIZE; + disp_obj->pbuf = kzalloc(disp_obj->bufsize, GFP_KERNEL); if (disp_obj->pbuf == NULL) status = -ENOMEM; } @@ -295,7 +295,7 @@ int disp_node_create(struct disp_object *disp_obj, DBC_REQUIRE(pargs != NULL); node_type = node_get_type(hnode); node_msg_args = pargs->asa.node_msg_args; - max = disp_obj->ul_bufsize_rms; /*Max # of RMS words that can be sent */ + max = disp_obj->bufsize_rms; /*Max # of RMS words that can be sent */ DBC_ASSERT(max == RMS_COMMANDBUFSIZE); chars_in_rms_word = sizeof(rms_word) / disp_obj->char_size; /* Number of RMS words needed to hold arg data */ @@ -404,7 +404,7 @@ int disp_node_create(struct disp_object *disp_obj, more_task_args->stack_seg = task_arg_obj.stack_seg; more_task_args->heap_addr = task_arg_obj.udsp_heap_addr; more_task_args->heap_size = task_arg_obj.heap_size; - more_task_args->misc = task_arg_obj.ul_dais_arg; + more_task_args->misc = task_arg_obj.dais_arg; more_task_args->num_input_streams = task_arg_obj.num_inputs; total += diff --git a/drivers/staging/tidspbridge/rmgr/nldr.c b/drivers/staging/tidspbridge/rmgr/nldr.c index 0537346bcb6c..688d9658ed60 100644 --- a/drivers/staging/tidspbridge/rmgr/nldr.c +++ b/drivers/staging/tidspbridge/rmgr/nldr.c @@ -220,7 +220,7 @@ struct nldr_nodeobject { struct dsp_uuid uuid; /* Node's UUID */ bool dynamic; /* Dynamically loaded node? */ bool overlay; /* Overlay node? */ - bool *pf_phase_split; /* Multiple phase libraries? */ + bool *phase_split; /* Multiple phase libraries? */ struct lib_node root; /* Library containing node phase */ struct lib_node create_lib; /* Library with create phase lib */ struct lib_node execute_lib; /* Library with execute phase lib */ @@ -326,7 +326,7 @@ int nldr_allocate(struct nldr_object *nldr_obj, void *priv_ref, if (nldr_node_obj == NULL) { status = -ENOMEM; } else { - nldr_node_obj->pf_phase_split = pf_phase_split; + nldr_node_obj->phase_split = pf_phase_split; nldr_node_obj->pers_libs = 0; nldr_node_obj->nldr_obj = nldr_obj; nldr_node_obj->priv_ref = priv_ref; @@ -344,44 +344,44 @@ int nldr_allocate(struct nldr_object *nldr_obj, void *priv_ref, */ /* Create phase */ nldr_node_obj->seg_id[CREATEDATAFLAGBIT] = (u16) - (node_props->ul_data_mem_seg_mask >> CREATEBIT) & + (node_props->data_mem_seg_mask >> CREATEBIT) & SEGMASK; nldr_node_obj->code_data_flag_mask |= - ((node_props->ul_data_mem_seg_mask >> + ((node_props->data_mem_seg_mask >> (CREATEBIT + FLAGBIT)) & 1) << CREATEDATAFLAGBIT; nldr_node_obj->seg_id[CREATECODEFLAGBIT] = (u16) - (node_props->ul_code_mem_seg_mask >> + (node_props->code_mem_seg_mask >> CREATEBIT) & SEGMASK; nldr_node_obj->code_data_flag_mask |= - ((node_props->ul_code_mem_seg_mask >> + ((node_props->code_mem_seg_mask >> (CREATEBIT + FLAGBIT)) & 1) << CREATECODEFLAGBIT; /* Execute phase */ nldr_node_obj->seg_id[EXECUTEDATAFLAGBIT] = (u16) - (node_props->ul_data_mem_seg_mask >> + (node_props->data_mem_seg_mask >> EXECUTEBIT) & SEGMASK; nldr_node_obj->code_data_flag_mask |= - ((node_props->ul_data_mem_seg_mask >> + ((node_props->data_mem_seg_mask >> (EXECUTEBIT + FLAGBIT)) & 1) << EXECUTEDATAFLAGBIT; nldr_node_obj->seg_id[EXECUTECODEFLAGBIT] = (u16) - (node_props->ul_code_mem_seg_mask >> + (node_props->code_mem_seg_mask >> EXECUTEBIT) & SEGMASK; nldr_node_obj->code_data_flag_mask |= - ((node_props->ul_code_mem_seg_mask >> + ((node_props->code_mem_seg_mask >> (EXECUTEBIT + FLAGBIT)) & 1) << EXECUTECODEFLAGBIT; /* Delete phase */ nldr_node_obj->seg_id[DELETEDATAFLAGBIT] = (u16) - (node_props->ul_data_mem_seg_mask >> DELETEBIT) & + (node_props->data_mem_seg_mask >> DELETEBIT) & SEGMASK; nldr_node_obj->code_data_flag_mask |= - ((node_props->ul_data_mem_seg_mask >> + ((node_props->data_mem_seg_mask >> (DELETEBIT + FLAGBIT)) & 1) << DELETEDATAFLAGBIT; nldr_node_obj->seg_id[DELETECODEFLAGBIT] = (u16) - (node_props->ul_code_mem_seg_mask >> + (node_props->code_mem_seg_mask >> DELETEBIT) & SEGMASK; nldr_node_obj->code_data_flag_mask |= - ((node_props->ul_code_mem_seg_mask >> + ((node_props->code_mem_seg_mask >> (DELETEBIT + FLAGBIT)) & 1) << DELETECODEFLAGBIT; } else { /* Non-dynamically loaded nodes are part of the @@ -430,7 +430,7 @@ int nldr_create(struct nldr_object **nldr, DBC_REQUIRE(hdev_obj != NULL); DBC_REQUIRE(pattrs != NULL); DBC_REQUIRE(pattrs->ovly != NULL); - DBC_REQUIRE(pattrs->pfn_write != NULL); + DBC_REQUIRE(pattrs->write != NULL); /* Allocate dynamic loader object */ nldr_obj = kzalloc(sizeof(struct nldr_object), GFP_KERNEL); @@ -533,9 +533,9 @@ int nldr_create(struct nldr_object **nldr, new_attrs.free = (dbll_free_fxn) remote_free; new_attrs.sym_lookup = (dbll_sym_lookup) get_symbol_value; new_attrs.sym_handle = nldr_obj; - new_attrs.write = (dbll_write_fxn) pattrs->pfn_write; + new_attrs.write = (dbll_write_fxn) pattrs->write; nldr_obj->ovly_fxn = pattrs->ovly; - nldr_obj->write_fxn = pattrs->pfn_write; + nldr_obj->write_fxn = pattrs->write; nldr_obj->ldr_attrs = new_attrs; } kfree(rmm_segs); @@ -678,7 +678,7 @@ int nldr_get_fxn_addr(struct nldr_nodeobject *nldr_node_obj, nldr_obj = nldr_node_obj->nldr_obj; /* Called from node_create(), node_delete(), or node_run(). */ - if (nldr_node_obj->dynamic && *nldr_node_obj->pf_phase_split) { + if (nldr_node_obj->dynamic && *nldr_node_obj->phase_split) { switch (nldr_node_obj->phase) { case NLDR_CREATE: root = nldr_node_obj->create_lib; @@ -821,7 +821,7 @@ int nldr_load(struct nldr_nodeobject *nldr_node_obj, false, nldr_node_obj->lib_path, phase, 0); if (!status) { - if (*nldr_node_obj->pf_phase_split) { + if (*nldr_node_obj->phase_split) { switch (phase) { case NLDR_CREATE: nldr_node_obj->create_lib = @@ -868,7 +868,7 @@ int nldr_unload(struct nldr_nodeobject *nldr_node_obj, if (nldr_node_obj != NULL) { if (nldr_node_obj->dynamic) { - if (*nldr_node_obj->pf_phase_split) { + if (*nldr_node_obj->phase_split) { switch (phase) { case NLDR_CREATE: root_lib = &nldr_node_obj->create_lib; @@ -1264,7 +1264,7 @@ static int load_lib(struct nldr_nodeobject *nldr_node_obj, dcd_get_library_name(nldr_node_obj->nldr_obj-> hdcd_mgr, &uuid, psz_file_name, &dw_buf_size, phase, - nldr_node_obj->pf_phase_split); + nldr_node_obj->phase_split); } else { /* Dependent libraries are registered with a phase */ status = @@ -1314,7 +1314,7 @@ static int load_lib(struct nldr_nodeobject *nldr_node_obj, } DBC_ASSERT(nd_libs >= np_libs); if (!status) { - if (!(*nldr_node_obj->pf_phase_split)) + if (!(*nldr_node_obj->phase_split)) np_libs = 0; /* nd_libs = #of dependent libraries */ @@ -1359,7 +1359,7 @@ static int load_lib(struct nldr_nodeobject *nldr_node_obj, * is, then record it. If root library IS persistent, * the deplib is already included */ if (!root_prstnt && persistent_dep_libs[i] && - *nldr_node_obj->pf_phase_split) { + *nldr_node_obj->phase_split) { if ((nldr_node_obj->pers_libs) >= MAXLIBS) { status = -EILSEQ; break; @@ -1385,11 +1385,11 @@ static int load_lib(struct nldr_nodeobject *nldr_node_obj, if (!status) { if ((status != 0) && !root_prstnt && persistent_dep_libs[i] && - *nldr_node_obj->pf_phase_split) { + *nldr_node_obj->phase_split) { (nldr_node_obj->pers_libs)++; } else { if (!persistent_dep_libs[i] || - !(*nldr_node_obj->pf_phase_split)) { + !(*nldr_node_obj->phase_split)) { nd_libs_loaded++; } } @@ -1903,7 +1903,7 @@ int nldr_find_addr(struct nldr_nodeobject *nldr_node, u32 sym_addr, pr_debug("%s(0x%x, 0x%x, 0x%x, 0x%x, %s)\n", __func__, (u32) nldr_node, sym_addr, offset_range, (u32) offset_output, sym_name); - if (nldr_node->dynamic && *nldr_node->pf_phase_split) { + if (nldr_node->dynamic && *nldr_node->phase_split) { switch (nldr_node->phase) { case NLDR_CREATE: root = nldr_node->create_lib; diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index 8008a5c0022b..4e6a63e745b1 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -142,13 +142,13 @@ struct node_mgr { DECLARE_BITMAP(zc_chnl_map, CHNL_MAXCHANNELS); struct ntfy_object *ntfy_obj; /* Manages registered notifications */ struct mutex node_mgr_lock; /* For critical sections */ - u32 ul_fxn_addrs[NUMRMSFXNS]; /* RMS function addresses */ + u32 fxn_addrs[NUMRMSFXNS]; /* RMS function addresses */ struct msg_mgr *msg_mgr_obj; /* Processor properties needed by Node Dispatcher */ u32 ul_num_chnls; /* Total number of channels */ - u32 ul_chnl_offset; /* Offset of chnl ids rsvd for RMS */ - u32 ul_chnl_buf_size; /* Buffer size for data to RMS */ + u32 chnl_offset; /* Offset of chnl ids rsvd for RMS */ + u32 chnl_buf_size; /* Buffer size for data to RMS */ int proc_family; /* eg, 5000 */ int proc_type; /* eg, 5510 */ u32 udsp_word_size; /* Size of DSP word on host bytes */ @@ -367,7 +367,7 @@ int node_allocate(struct proc_object *hprocessor, } /* Assuming that 0 is not a valid function address */ - if (hnode_mgr->ul_fxn_addrs[0] == 0) { + if (hnode_mgr->fxn_addrs[0] == 0) { /* No RMS on target - we currently can't handle this */ pr_err("%s: Failed, no RMS in base image\n", __func__); status = -EPERM; @@ -813,7 +813,7 @@ int node_change_priority(struct node_object *hnode, s32 prio) status = disp_node_change_priority(hnode_mgr->disp_obj, hnode, - hnode_mgr->ul_fxn_addrs + hnode_mgr->fxn_addrs [RMSCHANGENODEPRIORITY], hnode->node_env, prio); } @@ -1216,14 +1216,14 @@ int node_create(struct node_object *hnode) hnode->dcd_props.obj_data.node_obj. pstr_i_alg_name, &hnode->create_args.asa. - task_arg_obj.ul_dais_arg); + task_arg_obj.dais_arg); } } } if (!status) { if (node_type != NODE_DEVICE) { status = disp_node_create(hnode_mgr->disp_obj, hnode, - hnode_mgr->ul_fxn_addrs + hnode_mgr->fxn_addrs [RMSCREATENODE], ul_create_fxn, &(hnode->create_args), @@ -1324,8 +1324,8 @@ int node_create_mgr(struct node_mgr **node_man, goto out_err; /* Create NODE Dispatcher */ - disp_attr_obj.ul_chnl_offset = node_mgr_obj->ul_chnl_offset; - disp_attr_obj.ul_chnl_buf_size = node_mgr_obj->ul_chnl_buf_size; + disp_attr_obj.chnl_offset = node_mgr_obj->chnl_offset; + disp_attr_obj.chnl_buf_size = node_mgr_obj->chnl_buf_size; disp_attr_obj.proc_family = node_mgr_obj->proc_family; disp_attr_obj.proc_type = node_mgr_obj->proc_type; @@ -1344,12 +1344,12 @@ int node_create_mgr(struct node_mgr **node_man, mutex_init(&node_mgr_obj->node_mgr_lock); /* Block out reserved channels */ - for (i = 0; i < node_mgr_obj->ul_chnl_offset; i++) + for (i = 0; i < node_mgr_obj->chnl_offset; i++) set_bit(i, node_mgr_obj->chnl_map); /* Block out channels reserved for RMS */ - set_bit(node_mgr_obj->ul_chnl_offset, node_mgr_obj->chnl_map); - set_bit(node_mgr_obj->ul_chnl_offset + 1, node_mgr_obj->chnl_map); + set_bit(node_mgr_obj->chnl_offset, node_mgr_obj->chnl_map); + set_bit(node_mgr_obj->chnl_offset + 1, node_mgr_obj->chnl_map); /* NO RM Server on the IVA */ if (dev_type != IVA_UNIT) { @@ -1363,7 +1363,7 @@ int node_create_mgr(struct node_mgr **node_man, node_mgr_obj->nldr_fxns = nldr_fxns; /* Dyn loader funcs */ nldr_attrs_obj.ovly = ovly; - nldr_attrs_obj.pfn_write = mem_write; + nldr_attrs_obj.write = mem_write; nldr_attrs_obj.us_dsp_word_size = node_mgr_obj->udsp_word_size; nldr_attrs_obj.us_dsp_mau_size = node_mgr_obj->udsp_mau_size; node_mgr_obj->loader_init = node_mgr_obj->nldr_fxns.init(); @@ -1489,7 +1489,7 @@ func_cont1: status = disp_node_delete(disp_obj, pnode, hnode_mgr-> - ul_fxn_addrs + fxn_addrs [RMSDELETENODE], ul_delete_fxn, pnode->node_env); @@ -2012,7 +2012,7 @@ int node_pause(struct node_object *hnode) } status = disp_node_change_priority(hnode_mgr->disp_obj, hnode, - hnode_mgr->ul_fxn_addrs[RMSCHANGENODEPRIORITY], + hnode_mgr->fxn_addrs[RMSCHANGENODEPRIORITY], hnode->node_env, NODE_SUSPENDEDPRI); /* Update state */ @@ -2274,14 +2274,14 @@ int node_run(struct node_object *hnode) } } if (!status) { - ul_fxn_addr = hnode_mgr->ul_fxn_addrs[RMSEXECUTENODE]; + ul_fxn_addr = hnode_mgr->fxn_addrs[RMSEXECUTENODE]; status = disp_node_run(hnode_mgr->disp_obj, hnode, ul_fxn_addr, ul_execute_fxn, hnode->node_env); } } else if (state == NODE_PAUSED) { - ul_fxn_addr = hnode_mgr->ul_fxn_addrs[RMSCHANGENODEPRIORITY]; + ul_fxn_addr = hnode_mgr->fxn_addrs[RMSCHANGENODEPRIORITY]; status = disp_node_change_priority(hnode_mgr->disp_obj, hnode, ul_fxn_addr, hnode->node_env, NODE_GET_PRIORITY(hnode)); @@ -2902,8 +2902,8 @@ static int get_proc_props(struct node_mgr *hnode_mgr, host_res = pbridge_context->resources; if (!host_res) return -EPERM; - hnode_mgr->ul_chnl_offset = host_res->chnl_offset; - hnode_mgr->ul_chnl_buf_size = host_res->chnl_buf_size; + hnode_mgr->chnl_offset = host_res->chnl_offset; + hnode_mgr->chnl_buf_size = host_res->chnl_buf_size; hnode_mgr->ul_num_chnls = host_res->num_chnls; /* @@ -3024,7 +3024,7 @@ static int get_rms_fxns(struct node_mgr *hnode_mgr) for (i = 0; i < NUMRMSFXNS; i++) { status = dev_get_symbol(dev_obj, psz_fxns[i], - &(hnode_mgr->ul_fxn_addrs[i])); + &(hnode_mgr->fxn_addrs[i])); if (status) { if (status == -ESPIPE) { /* -- cgit v1.2.3 From 6c66e948d2c8254c8435f27eacb7f8657ce62dec Mon Sep 17 00:00:00 2001 From: Rene Sapiens Date: Tue, 18 Jan 2011 03:19:09 +0000 Subject: staging: tidspbridge: set7 remove hungarian from structs hungarian notation will be removed from the elements inside structures, the next varibles will be renamed: Original: Replacement: ul_gpp_phys gpp_phys ul_gpp_read_pointer gpp_read_pointer ul_gpp_size gpp_size ul_gpp_va gpp_va ul_heap_size heap_size ul_internal_mem_size internal_mem_size ul_in_use_cnt in_use_cnt ul_len_max_free_block len_max_free_block ul_max max ul_min_block_size min_block_size ul_min min ul_mpu_addr mpu_addr ul_n_bytes bytes ul_num_alloc_blocks num_alloc_blocks ul_number_bytes number_bytes ul_num_chnls num_chnls ul_num_free_blocks num_free_blocks ul_num_gppsm_segs num_gppsm_segs ul_pos pos ul_reserved reserved Signed-off-by: Rene Sapiens Signed-off-by: Armando Uribe Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/core/io_sm.c | 62 +++++++++++----------- drivers/staging/tidspbridge/core/tiomap3430.c | 2 +- drivers/staging/tidspbridge/core/tiomap_io.c | 4 +- .../staging/tidspbridge/include/dspbridge/cmm.h | 2 +- .../tidspbridge/include/dspbridge/cmmdefs.h | 12 ++--- .../staging/tidspbridge/include/dspbridge/dbdefs.h | 12 ++--- .../tidspbridge/include/dspbridge/dspioctl.h | 2 +- .../tidspbridge/include/dspbridge/mgrpriv.h | 2 +- drivers/staging/tidspbridge/pmgr/cmm.c | 30 +++++------ drivers/staging/tidspbridge/pmgr/dbll.c | 12 ++--- drivers/staging/tidspbridge/rmgr/dbdcd.c | 6 +-- drivers/staging/tidspbridge/rmgr/node.c | 18 +++---- drivers/staging/tidspbridge/rmgr/rmm.c | 12 ++--- drivers/staging/tidspbridge/rmgr/strm.c | 4 +- 14 files changed, 90 insertions(+), 90 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 5be6e0f9f57e..c923dda62a92 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -118,9 +118,9 @@ struct io_mgr { u32 ul_trace_buffer_begin; /* Trace message start address */ u32 ul_trace_buffer_end; /* Trace message end address */ u32 ul_trace_buffer_current; /* Trace message current address */ - u32 ul_gpp_read_pointer; /* GPP Read pointer to Trace buffer */ + u32 gpp_read_pointer; /* GPP Read pointer to Trace buffer */ u8 *pmsg; - u32 ul_gpp_va; + u32 gpp_va; u32 dsp_va; #endif /* IO Dpc */ @@ -532,7 +532,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) * This is the virtual uncached ioremapped * address!!! */ - ae_proc[ndx].ul_gpp_va = gpp_va_curr; + ae_proc[ndx].gpp_va = gpp_va_curr; ae_proc[ndx].dsp_va = va_curr / hio_mgr->word_size; ae_proc[ndx].ul_size = page_size[i]; @@ -542,7 +542,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) dev_dbg(bridge, "shm MMU TLB entry PA %x" " VA %x DSP_VA %x Size %x\n", ae_proc[ndx].gpp_pa, - ae_proc[ndx].ul_gpp_va, + ae_proc[ndx].gpp_va, ae_proc[ndx].dsp_va * hio_mgr->word_size, page_size[i]); ndx++; @@ -557,7 +557,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) "shm MMU PTE entry PA %x" " VA %x DSP_VA %x Size %x\n", ae_proc[ndx].gpp_pa, - ae_proc[ndx].ul_gpp_va, + ae_proc[ndx].gpp_va, ae_proc[ndx].dsp_va * hio_mgr->word_size, page_size[i]); if (status) @@ -580,12 +580,12 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) * should not conflict with shm entries on MPU or DSP side. */ for (i = 3; i < 7 && ndx < BRDIOCTL_NUMOFMMUTLB; i++) { - if (hio_mgr->ext_proc_info.ty_tlb[i].ul_gpp_phys == 0) + if (hio_mgr->ext_proc_info.ty_tlb[i].gpp_phys == 0) continue; - if ((hio_mgr->ext_proc_info.ty_tlb[i].ul_gpp_phys > + if ((hio_mgr->ext_proc_info.ty_tlb[i].gpp_phys > ul_gpp_pa - 0x100000 - && hio_mgr->ext_proc_info.ty_tlb[i].ul_gpp_phys <= + && hio_mgr->ext_proc_info.ty_tlb[i].gpp_phys <= ul_gpp_pa + ul_seg_size) || (hio_mgr->ext_proc_info.ty_tlb[i].dsp_virt > ul_dsp_va - 0x100000 / hio_mgr->word_size @@ -595,7 +595,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) "CDB MMU entry %d conflicts with " "shm.\n\tCDB: GppPa %x, DspVa %x.\n\tSHM: " "GppPa %x, DspVa %x, Bytes %x.\n", i, - hio_mgr->ext_proc_info.ty_tlb[i].ul_gpp_phys, + hio_mgr->ext_proc_info.ty_tlb[i].gpp_phys, hio_mgr->ext_proc_info.ty_tlb[i].dsp_virt, ul_gpp_pa, ul_dsp_va, ul_seg_size); status = -EPERM; @@ -606,8 +606,8 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) dsp_virt; ae_proc[ndx].gpp_pa = hio_mgr->ext_proc_info.ty_tlb[i]. - ul_gpp_phys; - ae_proc[ndx].ul_gpp_va = 0; + gpp_phys; + ae_proc[ndx].gpp_va = 0; /* 1 MB */ ae_proc[ndx].ul_size = 0x100000; dev_dbg(bridge, "shm MMU entry PA %x " @@ -618,7 +618,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) status = hio_mgr->intf_fxns->brd_mem_map (hio_mgr->hbridge_context, hio_mgr->ext_proc_info.ty_tlb[i]. - ul_gpp_phys, + gpp_phys, hio_mgr->ext_proc_info.ty_tlb[i]. dsp_virt, 0x100000, map_attrs, NULL); @@ -649,7 +649,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) for (i = ndx; i < BRDIOCTL_NUMOFMMUTLB; i++) { ae_proc[i].dsp_va = 0; ae_proc[i].gpp_pa = 0; - ae_proc[i].ul_gpp_va = 0; + ae_proc[i].gpp_va = 0; ae_proc[i].ul_size = 0; } /* @@ -657,14 +657,14 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) * to the virtual uncached ioremapped address of shm reserved * on MPU. */ - hio_mgr->ext_proc_info.ty_tlb[0].ul_gpp_phys = + hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys = (ul_gpp_va + ul_seg1_size + ul_pad_size); /* * Need shm Phys addr. IO supports only one DSP for now: * num_procs = 1. */ - if (!hio_mgr->ext_proc_info.ty_tlb[0].ul_gpp_phys || num_procs != 1) { + if (!hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys || num_procs != 1) { status = -EFAULT; goto func_end; } else { @@ -688,7 +688,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) ae_proc); if (status) goto func_end; - ul_shm_base = hio_mgr->ext_proc_info.ty_tlb[0].ul_gpp_phys; + ul_shm_base = hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys; ul_shm_base += ul_shm_base_offset; ul_shm_base = (u32) MEM_LINEAR_ADDRESS((void *)ul_shm_base, ul_mem_length); @@ -740,7 +740,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) goto func_end; } - hio_mgr->ul_gpp_read_pointer = hio_mgr->ul_trace_buffer_begin = + hio_mgr->gpp_read_pointer = hio_mgr->ul_trace_buffer_begin = (ul_gpp_va + ul_seg1_size + ul_pad_size) + (hio_mgr->ul_trace_buffer_begin - ul_dsp_va); /* Get the end address of trace buffer */ @@ -772,7 +772,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) status = -ENOMEM; hio_mgr->dsp_va = ul_dsp_va; - hio_mgr->ul_gpp_va = (ul_gpp_va + ul_seg1_size + ul_pad_size); + hio_mgr->gpp_va = (ul_gpp_va + ul_seg1_size + ul_pad_size); #endif func_end: @@ -1541,7 +1541,7 @@ static int register_shm_segs(struct io_mgr *hio_mgr, goto func_end; } /* First TLB entry reserved for Bridge SM use. */ - ul_gpp_phys = hio_mgr->ext_proc_info.ty_tlb[0].ul_gpp_phys; + ul_gpp_phys = hio_mgr->ext_proc_info.ty_tlb[0].gpp_phys; /* Get size in bytes */ ul_dsp_virt = hio_mgr->ext_proc_info.ty_tlb[0].dsp_virt * @@ -1693,48 +1693,48 @@ void print_dsp_debug_trace(struct io_mgr *hio_mgr) ul_gpp_cur_pointer = *(u32 *) (hio_mgr->ul_trace_buffer_current); ul_gpp_cur_pointer = - hio_mgr->ul_gpp_va + (ul_gpp_cur_pointer - + hio_mgr->gpp_va + (ul_gpp_cur_pointer - hio_mgr->dsp_va); /* No new debug messages available yet */ - if (ul_gpp_cur_pointer == hio_mgr->ul_gpp_read_pointer) { + if (ul_gpp_cur_pointer == hio_mgr->gpp_read_pointer) { break; - } else if (ul_gpp_cur_pointer > hio_mgr->ul_gpp_read_pointer) { + } else if (ul_gpp_cur_pointer > hio_mgr->gpp_read_pointer) { /* Continuous data */ ul_new_message_length = - ul_gpp_cur_pointer - hio_mgr->ul_gpp_read_pointer; + ul_gpp_cur_pointer - hio_mgr->gpp_read_pointer; memcpy(hio_mgr->pmsg, - (char *)hio_mgr->ul_gpp_read_pointer, + (char *)hio_mgr->gpp_read_pointer, ul_new_message_length); hio_mgr->pmsg[ul_new_message_length] = '\0'; /* * Advance the GPP trace pointer to DSP current * pointer. */ - hio_mgr->ul_gpp_read_pointer += ul_new_message_length; + hio_mgr->gpp_read_pointer += ul_new_message_length; /* Print the trace messages */ pr_info("DSPTrace: %s\n", hio_mgr->pmsg); - } else if (ul_gpp_cur_pointer < hio_mgr->ul_gpp_read_pointer) { + } else if (ul_gpp_cur_pointer < hio_mgr->gpp_read_pointer) { /* Handle trace buffer wraparound */ memcpy(hio_mgr->pmsg, - (char *)hio_mgr->ul_gpp_read_pointer, + (char *)hio_mgr->gpp_read_pointer, hio_mgr->ul_trace_buffer_end - - hio_mgr->ul_gpp_read_pointer); + hio_mgr->gpp_read_pointer); ul_new_message_length = ul_gpp_cur_pointer - hio_mgr->ul_trace_buffer_begin; memcpy(&hio_mgr->pmsg[hio_mgr->ul_trace_buffer_end - - hio_mgr->ul_gpp_read_pointer], + hio_mgr->gpp_read_pointer], (char *)hio_mgr->ul_trace_buffer_begin, ul_new_message_length); hio_mgr->pmsg[hio_mgr->ul_trace_buffer_end - - hio_mgr->ul_gpp_read_pointer + + hio_mgr->gpp_read_pointer + ul_new_message_length] = '\0'; /* * Advance the GPP trace pointer to DSP current * pointer. */ - hio_mgr->ul_gpp_read_pointer = + hio_mgr->gpp_read_pointer = hio_mgr->ul_trace_buffer_begin + ul_new_message_length; /* Print the trace messages */ diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 87160bb13518..2c15b03d9639 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -406,7 +406,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, ul_shm_offset_virt = ul_shm_base_virt - (ul_tlb_base_virt * DSPWORDSIZE); /* Kernel logical address */ - ul_shm_base = dev_context->atlb_entry[0].ul_gpp_va + ul_shm_offset_virt; + ul_shm_base = dev_context->atlb_entry[0].gpp_va + ul_shm_offset_virt; DBC_ASSERT(ul_shm_base != 0); /* 2nd wd is used as sync field */ diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c index c60a55d5555a..257052a52dc6 100644 --- a/drivers/staging/tidspbridge/core/tiomap_io.c +++ b/drivers/staging/tidspbridge/core/tiomap_io.c @@ -137,7 +137,7 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt, dev_context->atlb_entry[0].dsp_va * DSPWORDSIZE; DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt); dw_ext_prog_virt_mem = - dev_context->atlb_entry[0].ul_gpp_va; + dev_context->atlb_entry[0].gpp_va; if (!trace_read) { ul_shm_offset_virt = @@ -337,7 +337,7 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, ul_shm_base_virt - ul_tlb_base_virt; if (trace_load) { dw_ext_prog_virt_mem = - dev_context->atlb_entry[0].ul_gpp_va; + dev_context->atlb_entry[0].gpp_va; } else { dw_ext_prog_virt_mem = host_res->mem_base[1]; dw_ext_prog_virt_mem += diff --git a/drivers/staging/tidspbridge/include/dspbridge/cmm.h b/drivers/staging/tidspbridge/include/dspbridge/cmm.h index 6ad313fbc66d..27a21b5f3ff0 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cmm.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cmm.h @@ -81,7 +81,7 @@ extern void *cmm_calloc_buf(struct cmm_object *hcmm_mgr, * Requires: * cmm_init(void) called. * ph_cmm_mgr != NULL. - * mgr_attrts->ul_min_block_size >= 4 bytes. + * mgr_attrts->min_block_size >= 4 bytes. * Ensures: * */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h index c00c5192cef9..c995596a04a5 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h @@ -23,13 +23,13 @@ /* Cmm attributes used in cmm_create() */ struct cmm_mgrattrs { /* Minimum SM allocation; default 32 bytes. */ - u32 ul_min_block_size; + u32 min_block_size; }; /* Attributes for CMM_AllocBuf() & CMM_AllocDesc() */ struct cmm_attrs { u32 ul_seg_id; /* 1,2... are SM segments. 0 is not. */ - u32 alignment; /* 0,1,2,4....ul_min_block_size */ + u32 alignment; /* 0,1,2,4....min_block_size */ }; /* @@ -55,11 +55,11 @@ struct cmm_seginfo { /* Total size in bytes of segment: DSP+GPP */ u32 ul_total_seg_size; u32 gpp_base_pa; /* Start Phys addr of Gpp SM seg */ - u32 ul_gpp_size; /* Size of Gpp SM seg in bytes */ + u32 gpp_size; /* Size of Gpp SM seg in bytes */ u32 dsp_base_va; /* DSP virt base byte address */ u32 dsp_size; /* DSP seg size in bytes */ /* # of current GPP allocations from this segment */ - u32 ul_in_use_cnt; + u32 in_use_cnt; u32 seg_base_va; /* Start Virt address of SM seg */ }; @@ -67,11 +67,11 @@ struct cmm_seginfo { /* CMM useful information */ struct cmm_info { /* # of SM segments registered with this Cmm. */ - u32 ul_num_gppsm_segs; + u32 num_gppsm_segs; /* Total # of allocations outstanding for CMM */ u32 ul_total_in_use_cnt; /* Min SM block size allocation from cmm_create() */ - u32 ul_min_block_size; + u32 min_block_size; /* Info per registered SM segment. */ struct cmm_seginfo seg_info[CMM_MAXGPPSEGS]; }; diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h index af90b6bd1356..efd731df2bd9 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h @@ -210,9 +210,9 @@ enum dsp_flushtype { struct dsp_memstat { u32 ul_size; u32 ul_total_free_size; - u32 ul_len_max_free_block; - u32 ul_num_free_blocks; - u32 ul_num_alloc_blocks; + u32 len_max_free_block; + u32 num_free_blocks; + u32 num_alloc_blocks; }; /* Processor Load information Values */ @@ -276,7 +276,7 @@ struct dsp_streamconnect { }; struct dsp_nodeprofs { - u32 ul_heap_size; + u32 heap_size; }; /* The dsp_ndbprops structure reports the attributes of a node */ @@ -358,7 +358,7 @@ struct dsp_processorinfo { int processor_family; int processor_type; u32 clock_rate; - u32 ul_internal_mem_size; + u32 internal_mem_size; u32 external_mem_size; u32 processor_id; int ty_running_rtos; @@ -425,7 +425,7 @@ struct dsp_streaminfo { u32 cb_struct; u32 number_bufs_allowed; u32 number_bufs_in_stream; - u32 ul_number_bytes; + u32 number_bytes; void *sync_object_handle; enum dsp_streamstate ss_stream_state; }; diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h index bcb39bf59439..307d1a09b218 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h @@ -58,7 +58,7 @@ struct bridge_ioctl_extproc { u32 dsp_va; /* DSP virtual address */ u32 gpp_pa; /* GPP physical address */ /* GPP virtual address. __va does not work for ioremapped addresses */ - u32 ul_gpp_va; + u32 gpp_va; u32 ul_size; /* Size of the mapped memory in bytes */ enum hw_endianism_t endianism; enum hw_mmu_mixed_size_t mixed_mode; diff --git a/drivers/staging/tidspbridge/include/dspbridge/mgrpriv.h b/drivers/staging/tidspbridge/include/dspbridge/mgrpriv.h index 3ceeaa283ae5..3a4e337c040d 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/mgrpriv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/mgrpriv.h @@ -29,7 +29,7 @@ struct mgr_object; struct mgr_tlbentry { u32 dsp_virt; /* DSP virtual address */ - u32 ul_gpp_phys; /* GPP physical address */ + u32 gpp_phys; /* GPP physical address */ }; /* diff --git a/drivers/staging/tidspbridge/pmgr/cmm.c b/drivers/staging/tidspbridge/pmgr/cmm.c index d217dc8da534..4142e9afd543 100644 --- a/drivers/staging/tidspbridge/pmgr/cmm.c +++ b/drivers/staging/tidspbridge/pmgr/cmm.c @@ -98,7 +98,7 @@ struct cmm_object { */ struct mutex cmm_lock; /* Lock to access cmm mgr */ struct list_head node_free_list; /* Free list of memory nodes */ - u32 ul_min_block_size; /* Min SM block; default 16 bytes */ + u32 min_block_size; /* Min SM block; default 16 bytes */ u32 page_size; /* Memory Page size (1k/4k) */ /* GPP SM segment ptrs */ struct cmm_allocator *pa_gppsm_seg_tab[CMM_MAXGPPSEGS]; @@ -106,7 +106,7 @@ struct cmm_object { /* Default CMM Mgr attributes */ static struct cmm_mgrattrs cmm_dfltmgrattrs = { - /* ul_min_block_size, min block size(bytes) allocated by cmm mgr */ + /* min_block_size, min block size(bytes) allocated by cmm mgr */ 16 }; @@ -185,17 +185,17 @@ void *cmm_calloc_buf(struct cmm_object *hcmm_mgr, u32 usize, /* get the allocator object for this segment id */ allocator = get_allocator(cmm_mgr_obj, pattrs->ul_seg_id); - /* keep block size a multiple of ul_min_block_size */ + /* keep block size a multiple of min_block_size */ usize = - ((usize - 1) & ~(cmm_mgr_obj->ul_min_block_size - + ((usize - 1) & ~(cmm_mgr_obj->min_block_size - 1)) - + cmm_mgr_obj->ul_min_block_size; + + cmm_mgr_obj->min_block_size; mutex_lock(&cmm_mgr_obj->cmm_lock); pnode = get_free_block(allocator, usize); } if (pnode) { delta_size = (pnode->ul_size - usize); - if (delta_size >= cmm_mgr_obj->ul_min_block_size) { + if (delta_size >= cmm_mgr_obj->min_block_size) { /* create a new block with the leftovers and * add to freelist */ new_node = @@ -257,9 +257,9 @@ int cmm_create(struct cmm_object **ph_cmm_mgr, mgr_attrts = &cmm_dfltmgrattrs; /* set defaults */ /* 4 bytes minimum */ - DBC_ASSERT(mgr_attrts->ul_min_block_size >= 4); + DBC_ASSERT(mgr_attrts->min_block_size >= 4); /* save away smallest block allocation for this cmm mgr */ - cmm_obj->ul_min_block_size = mgr_attrts->ul_min_block_size; + cmm_obj->min_block_size = mgr_attrts->min_block_size; cmm_obj->page_size = PAGE_SIZE; /* create node free list */ @@ -426,25 +426,25 @@ int cmm_get_info(struct cmm_object *hcmm_mgr, return status; } mutex_lock(&cmm_mgr_obj->cmm_lock); - cmm_info_obj->ul_num_gppsm_segs = 0; /* # of SM segments */ + cmm_info_obj->num_gppsm_segs = 0; /* # of SM segments */ /* Total # of outstanding alloc */ cmm_info_obj->ul_total_in_use_cnt = 0; /* min block size */ - cmm_info_obj->ul_min_block_size = cmm_mgr_obj->ul_min_block_size; + cmm_info_obj->min_block_size = cmm_mgr_obj->min_block_size; /* check SM memory segments */ for (ul_seg = 1; ul_seg <= CMM_MAXGPPSEGS; ul_seg++) { /* get the allocator object for this segment id */ altr = get_allocator(cmm_mgr_obj, ul_seg); if (!altr) continue; - cmm_info_obj->ul_num_gppsm_segs++; + cmm_info_obj->num_gppsm_segs++; cmm_info_obj->seg_info[ul_seg - 1].seg_base_pa = altr->shm_base - altr->dsp_size; cmm_info_obj->seg_info[ul_seg - 1].ul_total_seg_size = altr->dsp_size + altr->ul_sm_size; cmm_info_obj->seg_info[ul_seg - 1].gpp_base_pa = altr->shm_base; - cmm_info_obj->seg_info[ul_seg - 1].ul_gpp_size = + cmm_info_obj->seg_info[ul_seg - 1].gpp_size = altr->ul_sm_size; cmm_info_obj->seg_info[ul_seg - 1].dsp_base_va = altr->dsp_base; @@ -452,11 +452,11 @@ int cmm_get_info(struct cmm_object *hcmm_mgr, altr->dsp_size; cmm_info_obj->seg_info[ul_seg - 1].seg_base_va = altr->vm_base - altr->dsp_size; - cmm_info_obj->seg_info[ul_seg - 1].ul_in_use_cnt = 0; + cmm_info_obj->seg_info[ul_seg - 1].in_use_cnt = 0; list_for_each_entry(curr, &altr->in_use_list, link) { cmm_info_obj->ul_total_in_use_cnt++; - cmm_info_obj->seg_info[ul_seg - 1].ul_in_use_cnt++; + cmm_info_obj->seg_info[ul_seg - 1].in_use_cnt++; } } mutex_unlock(&cmm_mgr_obj->cmm_lock); @@ -524,7 +524,7 @@ int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr, } /* Check if input ul_size is big enough to alloc at least one block */ - if (ul_size < cmm_mgr_obj->ul_min_block_size) { + if (ul_size < cmm_mgr_obj->min_block_size) { status = -EINVAL; goto func_end; } diff --git a/drivers/staging/tidspbridge/pmgr/dbll.c b/drivers/staging/tidspbridge/pmgr/dbll.c index 2f46b0603d21..2e20f78e2c31 100644 --- a/drivers/staging/tidspbridge/pmgr/dbll.c +++ b/drivers/staging/tidspbridge/pmgr/dbll.c @@ -123,7 +123,7 @@ struct dbll_library_obj { u32 open_ref; /* Number of times opened */ u32 load_ref; /* Number of times loaded */ struct gh_t_hash_tab *sym_tab; /* Hash table of symbols */ - u32 ul_pos; + u32 pos; }; /* @@ -398,7 +398,7 @@ int dbll_get_sect(struct dbll_library_obj *lib, char *name, u32 *paddr, } else { (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, - zl_lib->ul_pos, + zl_lib->pos, SEEK_SET); } } else { @@ -522,7 +522,7 @@ int dbll_load(struct dbll_library_obj *lib, dbll_flags flags, } if (!status) { - zl_lib->ul_pos = (*(zl_lib->target_obj->attrs.ftell)) + zl_lib->pos = (*(zl_lib->target_obj->attrs.ftell)) (zl_lib->fp); /* Reset file cursor */ (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, @@ -599,7 +599,7 @@ int dbll_open(struct dbll_tar_obj *target, char *file, dbll_flags flags, if (zl_lib == NULL) { status = -ENOMEM; } else { - zl_lib->ul_pos = 0; + zl_lib->pos = 0; /* Increment ref count to allow close on failure * later on */ zl_lib->open_ref++; @@ -649,7 +649,7 @@ int dbll_open(struct dbll_tar_obj *target, char *file, dbll_flags flags, if (!status && zl_lib->fp == NULL) status = dof_open(zl_lib); - zl_lib->ul_pos = (*(zl_lib->target_obj->attrs.ftell)) (zl_lib->fp); + zl_lib->pos = (*(zl_lib->target_obj->attrs.ftell)) (zl_lib->fp); (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, (long)0, SEEK_SET); /* Create a hash table for symbols if flag is set */ if (zl_lib->sym_tab != NULL || !(flags & DBLL_SYMB)) @@ -738,7 +738,7 @@ int dbll_read_sect(struct dbll_library_obj *lib, char *name, } else { (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, - zl_lib->ul_pos, + zl_lib->pos, SEEK_SET); } } else { diff --git a/drivers/staging/tidspbridge/rmgr/dbdcd.c b/drivers/staging/tidspbridge/rmgr/dbdcd.c index f0b396f07d15..98b88b187b0f 100644 --- a/drivers/staging/tidspbridge/rmgr/dbdcd.c +++ b/drivers/staging/tidspbridge/rmgr/dbdcd.c @@ -1253,7 +1253,7 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size, /* Heap Size for the node */ gen_obj->obj_data.node_obj. ndb_props.node_profiles[i]. - ul_heap_size = atoi(token); + heap_size = atoi(token); } } } @@ -1285,7 +1285,7 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size, gen_obj->obj_data.proc_info.clock_rate = atoi(token); token = strsep(&psz_cur, seps); - gen_obj->obj_data.proc_info.ul_internal_mem_size = atoi(token); + gen_obj->obj_data.proc_info.internal_mem_size = atoi(token); token = strsep(&psz_cur, seps); gen_obj->obj_data.proc_info.external_mem_size = atoi(token); @@ -1308,7 +1308,7 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size, for (entry_id = 0; entry_id < 7; entry_id++) { token = strsep(&psz_cur, seps); gen_obj->obj_data.ext_proc_obj.ty_tlb[entry_id]. - ul_gpp_phys = atoi(token); + gpp_phys = atoi(token); token = strsep(&psz_cur, seps); gen_obj->obj_data.ext_proc_obj.ty_tlb[entry_id]. diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index 4e6a63e745b1..76166c18669e 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -146,7 +146,7 @@ struct node_mgr { struct msg_mgr *msg_mgr_obj; /* Processor properties needed by Node Dispatcher */ - u32 ul_num_chnls; /* Total number of channels */ + u32 num_chnls; /* Total number of channels */ u32 chnl_offset; /* Offset of chnl ids rsvd for RMS */ u32 chnl_buf_size; /* Buffer size for data to RMS */ int proc_family; /* eg, 5000 */ @@ -1003,7 +1003,7 @@ int node_connect(struct node_object *node1, u32 stream1, set_bit(chnl_id, hnode_mgr->dma_chnl_map); /* dma chans are 2nd transport chnl set * ids(e.g. 16-31) */ - chnl_id = chnl_id + hnode_mgr->ul_num_chnls; + chnl_id = chnl_id + hnode_mgr->num_chnls; } break; case STRMMODE_ZEROCOPY: @@ -1014,7 +1014,7 @@ int node_connect(struct node_object *node1, u32 stream1, /* zero-copy chans are 3nd transport set * (e.g. 32-47) */ chnl_id = chnl_id + - (2 * hnode_mgr->ul_num_chnls); + (2 * hnode_mgr->num_chnls); } break; case STRMMODE_PROCCOPY: @@ -2723,15 +2723,15 @@ static void free_stream(struct node_mgr *hnode_mgr, struct stream_chnl stream) set_bit(stream.dev_id, hnode_mgr->pipe_done_map); } } else if (stream.type == HOSTCONNECT) { - if (stream.dev_id < hnode_mgr->ul_num_chnls) { + if (stream.dev_id < hnode_mgr->num_chnls) { clear_bit(stream.dev_id, hnode_mgr->chnl_map); - } else if (stream.dev_id < (2 * hnode_mgr->ul_num_chnls)) { + } else if (stream.dev_id < (2 * hnode_mgr->num_chnls)) { /* dsp-dma */ - clear_bit(stream.dev_id - (1 * hnode_mgr->ul_num_chnls), + clear_bit(stream.dev_id - (1 * hnode_mgr->num_chnls), hnode_mgr->dma_chnl_map); - } else if (stream.dev_id < (3 * hnode_mgr->ul_num_chnls)) { + } else if (stream.dev_id < (3 * hnode_mgr->num_chnls)) { /* zero-copy */ - clear_bit(stream.dev_id - (2 * hnode_mgr->ul_num_chnls), + clear_bit(stream.dev_id - (2 * hnode_mgr->num_chnls), hnode_mgr->zc_chnl_map); } } @@ -2904,7 +2904,7 @@ static int get_proc_props(struct node_mgr *hnode_mgr, return -EPERM; hnode_mgr->chnl_offset = host_res->chnl_offset; hnode_mgr->chnl_buf_size = host_res->chnl_buf_size; - hnode_mgr->ul_num_chnls = host_res->num_chnls; + hnode_mgr->num_chnls = host_res->num_chnls; /* * PROC will add an API to get dsp_processorinfo. diff --git a/drivers/staging/tidspbridge/rmgr/rmm.c b/drivers/staging/tidspbridge/rmgr/rmm.c index 5a3f09c4574f..5d5feee1fa3d 100644 --- a/drivers/staging/tidspbridge/rmgr/rmm.c +++ b/drivers/staging/tidspbridge/rmgr/rmm.c @@ -371,17 +371,17 @@ bool rmm_stat(struct rmm_target_obj *target, enum dsp_memtype segid, /* ul_size */ mem_stat_buf->ul_size = target->seg_tab[segid].length; - /* ul_num_free_blocks */ - mem_stat_buf->ul_num_free_blocks = free_blocks; + /* num_free_blocks */ + mem_stat_buf->num_free_blocks = free_blocks; /* ul_total_free_size */ mem_stat_buf->ul_total_free_size = total_free_size; - /* ul_len_max_free_block */ - mem_stat_buf->ul_len_max_free_block = max_free_size; + /* len_max_free_block */ + mem_stat_buf->len_max_free_block = max_free_size; - /* ul_num_alloc_blocks */ - mem_stat_buf->ul_num_alloc_blocks = + /* num_alloc_blocks */ + mem_stat_buf->num_alloc_blocks = target->seg_tab[segid].number; ret = true; diff --git a/drivers/staging/tidspbridge/rmgr/strm.c b/drivers/staging/tidspbridge/rmgr/strm.c index 66c32f171f30..a8e3fe5c4a24 100644 --- a/drivers/staging/tidspbridge/rmgr/strm.c +++ b/drivers/staging/tidspbridge/rmgr/strm.c @@ -71,7 +71,7 @@ struct strm_object { u32 utimeout; u32 num_bufs; /* Max # of bufs allowed in stream */ u32 un_bufs_in_strm; /* Current # of bufs in stream */ - u32 ul_n_bytes; /* bytes transferred since idled */ + u32 bytes; /* bytes transferred since idled */ /* STREAM_IDLE, STREAM_READY, ... */ enum dsp_streamstate strm_state; void *user_event; /* Saved for strm_get_info() */ @@ -341,7 +341,7 @@ int strm_get_info(struct strm_object *stream_obj, stream_info->user_strm->number_bufs_in_stream = chnl_info_obj.cio_cs + chnl_info_obj.cio_reqs; /* # of bytes transferred since last call to DSPStream_Idle() */ - stream_info->user_strm->ul_number_bytes = chnl_info_obj.bytes_tx; + stream_info->user_strm->number_bytes = chnl_info_obj.bytes_tx; stream_info->user_strm->sync_object_handle = chnl_info_obj.event_obj; /* Determine stream state based on channel state and info */ if (chnl_info_obj.state & CHNL_STATEEOS) { -- cgit v1.2.3 From 085467b8f5e60a2fe9ef85031ab40bd8724fcac6 Mon Sep 17 00:00:00 2001 From: Rene Sapiens Date: Mon, 17 Jan 2011 18:36:52 -0600 Subject: staging: tidspbridge: set8 remove hungarian from structs hungarian notation will be removed from the elements inside structures, the next varibles will be renamed: Original: Replacement: hbridge_context bridge_context hchnl_mgr chnl_mgr hcmm_mgr cmm_mgr hdcd_mgr dcd_mgr hdeh_mgr deh_mgr hdev_obj dev_obj hdrv_obj drv_obj hmgr_obj mgr_obj hmsg_mgr msg_mgr hnode_mgr node_mgr psz_last_coff last_coff ul_resource resource ul_seg_id seg_id ul_size size ul_sm_size sm_size ul_total_free_size total_free_size ul_total_in_use_cnt total_in_use_cnt ul_total_seg_size total_seg_size ul_trace_buffer_begin trace_buffer_begin ul_trace_buffer_current trace_buffer_current ul_trace_buffer_end trace_buffer_end ul_unit unit ul_virt_size virt_size us_dsp_mau_size dsp_mau_size us_dsp_word_size dsp_word_size Signed-off-by: Rene Sapiens Signed-off-by: Armando Uribe Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/core/_deh.h | 2 +- drivers/staging/tidspbridge/core/_msg_sm.h | 2 +- drivers/staging/tidspbridge/core/_tiomap.h | 2 +- drivers/staging/tidspbridge/core/chnl_sm.c | 6 +- drivers/staging/tidspbridge/core/io_sm.c | 138 ++++++++++----------- drivers/staging/tidspbridge/core/msg_sm.c | 16 +-- drivers/staging/tidspbridge/core/tiomap3430.c | 16 +-- drivers/staging/tidspbridge/core/tiomap3430_pwr.c | 6 +- drivers/staging/tidspbridge/core/tiomap_io.c | 30 ++--- drivers/staging/tidspbridge/core/ue_deh.c | 6 +- .../tidspbridge/include/dspbridge/_chnl_sm.h | 2 +- .../tidspbridge/include/dspbridge/chnlpriv.h | 2 +- .../tidspbridge/include/dspbridge/cmmdefs.h | 8 +- .../staging/tidspbridge/include/dspbridge/dbdefs.h | 6 +- .../staging/tidspbridge/include/dspbridge/dev.h | 6 +- .../tidspbridge/include/dspbridge/dspapi-ioctl.h | 20 +-- .../tidspbridge/include/dspbridge/dspioctl.h | 2 +- .../tidspbridge/include/dspbridge/nldrdefs.h | 4 +- .../tidspbridge/include/dspbridge/strmdefs.h | 2 +- drivers/staging/tidspbridge/pmgr/cmm.c | 88 ++++++------- drivers/staging/tidspbridge/pmgr/dev.c | 110 ++++++++-------- drivers/staging/tidspbridge/pmgr/dspapi.c | 20 +-- drivers/staging/tidspbridge/pmgr/io.c | 2 +- drivers/staging/tidspbridge/pmgr/ioobj.h | 4 +- drivers/staging/tidspbridge/rmgr/disp.c | 18 +-- drivers/staging/tidspbridge/rmgr/mgr.c | 16 +-- drivers/staging/tidspbridge/rmgr/nldr.c | 44 +++---- drivers/staging/tidspbridge/rmgr/node.c | 88 ++++++------- drivers/staging/tidspbridge/rmgr/proc.c | 126 +++++++++---------- drivers/staging/tidspbridge/rmgr/rmm.c | 6 +- drivers/staging/tidspbridge/rmgr/strm.c | 12 +- 31 files changed, 405 insertions(+), 405 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/_deh.h b/drivers/staging/tidspbridge/core/_deh.h index 16723cd34831..025d34320e7e 100644 --- a/drivers/staging/tidspbridge/core/_deh.h +++ b/drivers/staging/tidspbridge/core/_deh.h @@ -25,7 +25,7 @@ /* DEH Manager: only one created per board: */ struct deh_mgr { - struct bridge_dev_context *hbridge_context; /* Bridge context. */ + struct bridge_dev_context *bridge_context; /* Bridge context. */ struct ntfy_object *ntfy_obj; /* NTFY object */ /* MMU Fault DPC */ diff --git a/drivers/staging/tidspbridge/core/_msg_sm.h b/drivers/staging/tidspbridge/core/_msg_sm.h index b78d1a655300..25414e05dfa5 100644 --- a/drivers/staging/tidspbridge/core/_msg_sm.h +++ b/drivers/staging/tidspbridge/core/_msg_sm.h @@ -108,7 +108,7 @@ struct msg_mgr { */ struct msg_queue { struct list_head list_elem; - struct msg_mgr *hmsg_mgr; + struct msg_mgr *msg_mgr; u32 max_msgs; /* Node message depth */ u32 msgq_id; /* Node environment pointer */ struct list_head msg_free_list; /* Free MsgFrames ready to be filled */ diff --git a/drivers/staging/tidspbridge/core/_tiomap.h b/drivers/staging/tidspbridge/core/_tiomap.h index 60d98764af19..1e0273e50d2b 100644 --- a/drivers/staging/tidspbridge/core/_tiomap.h +++ b/drivers/staging/tidspbridge/core/_tiomap.h @@ -319,7 +319,7 @@ static const struct bpwr_clk_t bpwr_clks[] = { /* This Bridge driver's device context: */ struct bridge_dev_context { - struct dev_object *hdev_obj; /* Handle to Bridge device object. */ + struct dev_object *dev_obj; /* Handle to Bridge device object. */ u32 dsp_base_addr; /* Arm's API to DSP virt base addr */ /* * DSP External memory prog address as seen virtually by the OS on diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c index c20431553aa7..c9470d331505 100644 --- a/drivers/staging/tidspbridge/core/chnl_sm.c +++ b/drivers/staging/tidspbridge/core/chnl_sm.c @@ -388,7 +388,7 @@ int bridge_chnl_create(struct chnl_mgr **channel_mgr, chnl_mgr_obj->open_channels = 0; chnl_mgr_obj->output_mask = 0; chnl_mgr_obj->last_output = 0; - chnl_mgr_obj->hdev_obj = hdev_obj; + chnl_mgr_obj->dev_obj = hdev_obj; spin_lock_init(&chnl_mgr_obj->chnl_mgr_lock); } else { status = -ENOMEM; @@ -434,7 +434,7 @@ int bridge_chnl_destroy(struct chnl_mgr *hchnl_mgr) kfree(chnl_mgr_obj->ap_channel); /* Set hchnl_mgr to NULL in device object. */ - dev_set_chnl_mgr(chnl_mgr_obj->hdev_obj, NULL); + dev_set_chnl_mgr(chnl_mgr_obj->dev_obj, NULL); /* Free this Chnl Mgr object: */ kfree(hchnl_mgr); } else { @@ -508,7 +508,7 @@ int bridge_chnl_get_info(struct chnl_object *chnl_obj, if (channel_info != NULL) { if (pchnl) { /* Return the requested information: */ - channel_info->hchnl_mgr = pchnl->chnl_mgr_obj; + channel_info->chnl_mgr = pchnl->chnl_mgr_obj; channel_info->event_obj = pchnl->user_event; channel_info->cnhl_id = pchnl->chnl_id; channel_info->mode = pchnl->chnl_mode; diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index c923dda62a92..96dbe1ae8c26 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -89,17 +89,17 @@ struct io_mgr { /* These four fields must be the first fields in a io_mgr_ struct */ /* Bridge device context */ - struct bridge_dev_context *hbridge_context; + struct bridge_dev_context *bridge_context; /* Function interface to Bridge driver */ struct bridge_drv_interface *intf_fxns; - struct dev_object *hdev_obj; /* Device this board represents */ + struct dev_object *dev_obj; /* Device this board represents */ /* These fields initialized in bridge_io_create() */ - struct chnl_mgr *hchnl_mgr; + struct chnl_mgr *chnl_mgr; struct shm *shared_mem; /* Shared Memory control */ u8 *input; /* Address of input channel */ u8 *output; /* Address of output channel */ - struct msg_mgr *hmsg_mgr; /* Message manager */ + struct msg_mgr *msg_mgr; /* Message manager */ /* Msg control for from DSP messages */ struct msg_ctrl *msg_input_ctrl; /* Msg control for to DSP messages */ @@ -112,12 +112,12 @@ struct io_mgr { u16 intr_val; /* Interrupt value */ /* Private extnd proc info; mmu setup */ struct mgr_processorextinfo ext_proc_info; - struct cmm_object *hcmm_mgr; /* Shared Mem Mngr */ + struct cmm_object *cmm_mgr; /* Shared Mem Mngr */ struct work_struct io_workq; /* workqueue */ #if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG) - u32 ul_trace_buffer_begin; /* Trace message start address */ - u32 ul_trace_buffer_end; /* Trace message end address */ - u32 ul_trace_buffer_current; /* Trace message current address */ + u32 trace_buffer_begin; /* Trace message start address */ + u32 trace_buffer_end; /* Trace message end address */ + u32 trace_buffer_current; /* Trace message current address */ u32 gpp_read_pointer; /* GPP Read pointer to Trace buffer */ u8 *pmsg; u32 gpp_va; @@ -201,7 +201,7 @@ int bridge_io_create(struct io_mgr **io_man, return -ENOMEM; /* Initialize chnl_mgr object */ - pio_mgr->hchnl_mgr = hchnl_mgr; + pio_mgr->chnl_mgr = hchnl_mgr; pio_mgr->word_size = mgr_attrts->word_size; if (dev_type == DSP_UNIT) { @@ -220,7 +220,7 @@ int bridge_io_create(struct io_mgr **io_man, } } - pio_mgr->hbridge_context = hbridge_context; + pio_mgr->bridge_context = hbridge_context; pio_mgr->shared_irq = mgr_attrts->irq_shared; if (dsp_wdt_init()) { bridge_io_destroy(pio_mgr); @@ -306,7 +306,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) HW_PAGE_SIZE64KB, HW_PAGE_SIZE4KB }; - status = dev_get_bridge_context(hio_mgr->hdev_obj, &pbridge_context); + status = dev_get_bridge_context(hio_mgr->dev_obj, &pbridge_context); if (!pbridge_context) { status = -EFAULT; goto func_end; @@ -317,15 +317,15 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) status = -EFAULT; goto func_end; } - status = dev_get_cod_mgr(hio_mgr->hdev_obj, &cod_man); + status = dev_get_cod_mgr(hio_mgr->dev_obj, &cod_man); if (!cod_man) { status = -EFAULT; goto func_end; } - hchnl_mgr = hio_mgr->hchnl_mgr; + hchnl_mgr = hio_mgr->chnl_mgr; /* The message manager is destroyed when the board is stopped. */ - dev_get_msg_mgr(hio_mgr->hdev_obj, &hio_mgr->hmsg_mgr); - hmsg_mgr = hio_mgr->hmsg_mgr; + dev_get_msg_mgr(hio_mgr->dev_obj, &hio_mgr->msg_mgr); + hmsg_mgr = hio_mgr->msg_mgr; if (!hchnl_mgr || !hmsg_mgr) { status = -EFAULT; goto func_end; @@ -483,7 +483,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) 1)) == 0)) { status = hio_mgr->intf_fxns-> - brd_mem_map(hio_mgr->hbridge_context, + brd_mem_map(hio_mgr->bridge_context, pa_curr, va_curr, page_size[i], map_attrs, NULL); @@ -535,7 +535,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) ae_proc[ndx].gpp_va = gpp_va_curr; ae_proc[ndx].dsp_va = va_curr / hio_mgr->word_size; - ae_proc[ndx].ul_size = page_size[i]; + ae_proc[ndx].size = page_size[i]; ae_proc[ndx].endianism = HW_LITTLE_ENDIAN; ae_proc[ndx].elem_size = HW_ELEM_SIZE16BIT; ae_proc[ndx].mixed_mode = HW_MMU_CPUES; @@ -549,7 +549,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) } else { status = hio_mgr->intf_fxns-> - brd_mem_map(hio_mgr->hbridge_context, + brd_mem_map(hio_mgr->bridge_context, pa_curr, va_curr, page_size[i], map_attrs, NULL); @@ -609,14 +609,14 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) gpp_phys; ae_proc[ndx].gpp_va = 0; /* 1 MB */ - ae_proc[ndx].ul_size = 0x100000; + ae_proc[ndx].size = 0x100000; dev_dbg(bridge, "shm MMU entry PA %x " "DSP_VA 0x%x\n", ae_proc[ndx].gpp_pa, ae_proc[ndx].dsp_va); ndx++; } else { status = hio_mgr->intf_fxns->brd_mem_map - (hio_mgr->hbridge_context, + (hio_mgr->bridge_context, hio_mgr->ext_proc_info.ty_tlb[i]. gpp_phys, hio_mgr->ext_proc_info.ty_tlb[i]. @@ -638,7 +638,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) i = 0; while (l4_peripheral_table[i].phys_addr) { status = hio_mgr->intf_fxns->brd_mem_map - (hio_mgr->hbridge_context, l4_peripheral_table[i].phys_addr, + (hio_mgr->bridge_context, l4_peripheral_table[i].phys_addr, l4_peripheral_table[i].dsp_virt_addr, HW_PAGE_SIZE4KB, map_attrs, NULL); if (status) @@ -650,7 +650,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) ae_proc[i].dsp_va = 0; ae_proc[i].gpp_pa = 0; ae_proc[i].gpp_va = 0; - ae_proc[i].ul_size = 0; + ae_proc[i].size = 0; } /* * Set the shm physical address entry (grayed out in CDB file) @@ -683,7 +683,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) */ status = - hio_mgr->intf_fxns->dev_cntrl(hio_mgr->hbridge_context, + hio_mgr->intf_fxns->dev_cntrl(hio_mgr->bridge_context, BRDIOCTL_SETMMUCONFIG, ae_proc); if (status) @@ -734,39 +734,39 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) #if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG) /* Get the start address of trace buffer */ status = cod_get_sym_value(cod_man, SYS_PUTCBEG, - &hio_mgr->ul_trace_buffer_begin); + &hio_mgr->trace_buffer_begin); if (status) { status = -EFAULT; goto func_end; } - hio_mgr->gpp_read_pointer = hio_mgr->ul_trace_buffer_begin = + hio_mgr->gpp_read_pointer = hio_mgr->trace_buffer_begin = (ul_gpp_va + ul_seg1_size + ul_pad_size) + - (hio_mgr->ul_trace_buffer_begin - ul_dsp_va); + (hio_mgr->trace_buffer_begin - ul_dsp_va); /* Get the end address of trace buffer */ status = cod_get_sym_value(cod_man, SYS_PUTCEND, - &hio_mgr->ul_trace_buffer_end); + &hio_mgr->trace_buffer_end); if (status) { status = -EFAULT; goto func_end; } - hio_mgr->ul_trace_buffer_end = + hio_mgr->trace_buffer_end = (ul_gpp_va + ul_seg1_size + ul_pad_size) + - (hio_mgr->ul_trace_buffer_end - ul_dsp_va); + (hio_mgr->trace_buffer_end - ul_dsp_va); /* Get the current address of DSP write pointer */ status = cod_get_sym_value(cod_man, BRIDGE_SYS_PUTC_CURRENT, - &hio_mgr->ul_trace_buffer_current); + &hio_mgr->trace_buffer_current); if (status) { status = -EFAULT; goto func_end; } - hio_mgr->ul_trace_buffer_current = + hio_mgr->trace_buffer_current = (ul_gpp_va + ul_seg1_size + ul_pad_size) + - (hio_mgr->ul_trace_buffer_current - ul_dsp_va); + (hio_mgr->trace_buffer_current - ul_dsp_va); /* Calculate the size of trace buffer */ kfree(hio_mgr->pmsg); - hio_mgr->pmsg = kmalloc(((hio_mgr->ul_trace_buffer_end - - hio_mgr->ul_trace_buffer_begin) * + hio_mgr->pmsg = kmalloc(((hio_mgr->trace_buffer_end - + hio_mgr->trace_buffer_begin) * hio_mgr->word_size) + 2, GFP_KERNEL); if (!hio_mgr->pmsg) status = -ENOMEM; @@ -807,7 +807,7 @@ void io_cancel_chnl(struct io_mgr *hio_mgr, u32 chnl) /* Inform DSP that we have no more buffers on this channel */ set_chnl_free(sm, chnl); - sm_interrupt_dsp(pio_mgr->hbridge_context, MBX_PCPY_CLASS); + sm_interrupt_dsp(pio_mgr->bridge_context, MBX_PCPY_CLASS); func_end: return; } @@ -829,7 +829,7 @@ static void io_dispatch_pm(struct io_mgr *pio_mgr) if (parg[0] == MBX_PM_HIBERNATE_EN) { dev_dbg(bridge, "PM: Hibernate command\n"); status = pio_mgr->intf_fxns-> - dev_cntrl(pio_mgr->hbridge_context, + dev_cntrl(pio_mgr->bridge_context, BRDIOCTL_PWR_HIBERNATE, parg); if (status) pr_err("%s: hibernate cmd failed 0x%x\n", @@ -838,7 +838,7 @@ static void io_dispatch_pm(struct io_mgr *pio_mgr) parg[1] = pio_mgr->shared_mem->opp_request.rqst_opp_pt; dev_dbg(bridge, "PM: Requested OPP = 0x%x\n", parg[1]); status = pio_mgr->intf_fxns-> - dev_cntrl(pio_mgr->hbridge_context, + dev_cntrl(pio_mgr->bridge_context, BRDIOCTL_CONSTRAINT_REQUEST, parg); if (status) dev_dbg(bridge, "PM: Failed to set constraint " @@ -847,7 +847,7 @@ static void io_dispatch_pm(struct io_mgr *pio_mgr) dev_dbg(bridge, "PM: clk control value of msg = 0x%x\n", parg[0]); status = pio_mgr->intf_fxns-> - dev_cntrl(pio_mgr->hbridge_context, + dev_cntrl(pio_mgr->bridge_context, BRDIOCTL_CLK_CTRL, parg); if (status) dev_dbg(bridge, "PM: Failed to ctrl the DSP clk" @@ -872,9 +872,9 @@ void io_dpc(unsigned long ref_data) if (!pio_mgr) goto func_end; - chnl_mgr_obj = pio_mgr->hchnl_mgr; - dev_get_msg_mgr(pio_mgr->hdev_obj, &msg_mgr_obj); - dev_get_deh_mgr(pio_mgr->hdev_obj, &hdeh_mgr); + chnl_mgr_obj = pio_mgr->chnl_mgr; + dev_get_msg_mgr(pio_mgr->dev_obj, &msg_mgr_obj); + dev_get_deh_mgr(pio_mgr->dev_obj, &hdeh_mgr); if (!chnl_mgr_obj) goto func_end; @@ -970,7 +970,7 @@ void io_request_chnl(struct io_mgr *io_manager, struct chnl_object *pchnl, if (!pchnl || !mbx_val) goto func_end; - chnl_mgr_obj = io_manager->hchnl_mgr; + chnl_mgr_obj = io_manager->chnl_mgr; sm = io_manager->shared_mem; if (io_mode == IO_INPUT) { /* @@ -1076,7 +1076,7 @@ static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, bool notify_client = false; sm = pio_mgr->shared_mem; - chnl_mgr_obj = pio_mgr->hchnl_mgr; + chnl_mgr_obj = pio_mgr->chnl_mgr; /* Attempt to perform input */ if (!sm->input_full) @@ -1164,7 +1164,7 @@ static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, if (clear_chnl) { /* Indicate to the DSP we have read the input */ sm->input_full = 0; - sm_interrupt_dsp(pio_mgr->hbridge_context, MBX_PCPY_CLASS); + sm_interrupt_dsp(pio_mgr->bridge_context, MBX_PCPY_CLASS); } if (notify_client) { /* Notify client with IO completion record */ @@ -1202,16 +1202,16 @@ static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr) /* Read the next message */ addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.cmd); msg.msg.cmd = - read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr); + read_ext32_bit_dsp_data(pio_mgr->bridge_context, addr); addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.arg1); msg.msg.arg1 = - read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr); + read_ext32_bit_dsp_data(pio_mgr->bridge_context, addr); addr = (u32) &(((struct msg_dspmsg *)msg_input)->msg.arg2); msg.msg.arg2 = - read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr); + read_ext32_bit_dsp_data(pio_mgr->bridge_context, addr); addr = (u32) &(((struct msg_dspmsg *)msg_input)->msgq_id); msg.msgq_id = - read_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr); + read_ext32_bit_dsp_data(pio_mgr->bridge_context, addr); msg_input += sizeof(struct msg_dspmsg); /* Determine which queue to put the message in */ @@ -1269,7 +1269,7 @@ static void input_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr) /* Tell the DSP we've read the messages */ msg_ctr_obj->buf_empty = true; msg_ctr_obj->post_swi = true; - sm_interrupt_dsp(pio_mgr->hbridge_context, MBX_PCPY_CLASS); + sm_interrupt_dsp(pio_mgr->bridge_context, MBX_PCPY_CLASS); } } @@ -1323,7 +1323,7 @@ static void output_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, struct chnl_irp *chnl_packet_obj; u32 dw_dsp_f_mask; - chnl_mgr_obj = pio_mgr->hchnl_mgr; + chnl_mgr_obj = pio_mgr->chnl_mgr; sm = pio_mgr->shared_mem; /* Attempt to perform output */ if (sm->output_full) @@ -1381,7 +1381,7 @@ static void output_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, #endif sm->output_full = 1; /* Indicate to the DSP we have written the output */ - sm_interrupt_dsp(pio_mgr->hbridge_context, MBX_PCPY_CLASS); + sm_interrupt_dsp(pio_mgr->bridge_context, MBX_PCPY_CLASS); /* Notify client with IO completion record (keep EOS) */ chnl_packet_obj->status &= CHNL_IOCSTATEOS; notify_chnl_complete(pchnl, chnl_packet_obj); @@ -1428,19 +1428,19 @@ static void output_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr) val = (pmsg->msg_data).msgq_id; addr = (u32) &msg_output->msgq_id; - write_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr, val); + write_ext32_bit_dsp_data(pio_mgr->bridge_context, addr, val); val = (pmsg->msg_data).msg.cmd; addr = (u32) &msg_output->msg.cmd; - write_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr, val); + write_ext32_bit_dsp_data(pio_mgr->bridge_context, addr, val); val = (pmsg->msg_data).msg.arg1; addr = (u32) &msg_output->msg.arg1; - write_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr, val); + write_ext32_bit_dsp_data(pio_mgr->bridge_context, addr, val); val = (pmsg->msg_data).msg.arg2; addr = (u32) &msg_output->msg.arg2; - write_ext32_bit_dsp_data(pio_mgr->hbridge_context, addr, val); + write_ext32_bit_dsp_data(pio_mgr->bridge_context, addr, val); msg_output++; list_add_tail(&pmsg->list_elem, &hmsg_mgr->msg_free_list); @@ -1462,7 +1462,7 @@ static void output_msg(struct io_mgr *pio_mgr, struct msg_mgr *hmsg_mgr) /* Set the post SWI flag */ msg_ctr_obj->post_swi = true; /* Tell the DSP we have written the output. */ - sm_interrupt_dsp(pio_mgr->hbridge_context, MBX_PCPY_CLASS); + sm_interrupt_dsp(pio_mgr->bridge_context, MBX_PCPY_CLASS); } } @@ -1518,9 +1518,9 @@ static int register_shm_segs(struct io_mgr *hio_mgr, } /* Register with CMM */ if (!status) { - status = dev_get_cmm_mgr(hio_mgr->hdev_obj, &hio_mgr->hcmm_mgr); + status = dev_get_cmm_mgr(hio_mgr->dev_obj, &hio_mgr->cmm_mgr); if (!status) { - status = cmm_un_register_gppsm_seg(hio_mgr->hcmm_mgr, + status = cmm_un_register_gppsm_seg(hio_mgr->cmm_mgr, CMM_ALLSEGMENTS); } } @@ -1575,7 +1575,7 @@ static int register_shm_segs(struct io_mgr *hio_mgr, ul_dsp_virt; /* Register SM Segment 0. */ status = - cmm_register_gppsm_seg(hio_mgr->hcmm_mgr, dw_gpp_base_pa, + cmm_register_gppsm_seg(hio_mgr->cmm_mgr, dw_gpp_base_pa, ul_rsrvd_size, dw_offset, (dw_gpp_base_pa > ul_dsp_virt) ? CMM_ADDTODSPPA : @@ -1691,7 +1691,7 @@ void print_dsp_debug_trace(struct io_mgr *hio_mgr) while (true) { /* Get the DSP current pointer */ ul_gpp_cur_pointer = - *(u32 *) (hio_mgr->ul_trace_buffer_current); + *(u32 *) (hio_mgr->trace_buffer_current); ul_gpp_cur_pointer = hio_mgr->gpp_va + (ul_gpp_cur_pointer - hio_mgr->dsp_va); @@ -1719,15 +1719,15 @@ void print_dsp_debug_trace(struct io_mgr *hio_mgr) /* Handle trace buffer wraparound */ memcpy(hio_mgr->pmsg, (char *)hio_mgr->gpp_read_pointer, - hio_mgr->ul_trace_buffer_end - + hio_mgr->trace_buffer_end - hio_mgr->gpp_read_pointer); ul_new_message_length = - ul_gpp_cur_pointer - hio_mgr->ul_trace_buffer_begin; - memcpy(&hio_mgr->pmsg[hio_mgr->ul_trace_buffer_end - + ul_gpp_cur_pointer - hio_mgr->trace_buffer_begin; + memcpy(&hio_mgr->pmsg[hio_mgr->trace_buffer_end - hio_mgr->gpp_read_pointer], - (char *)hio_mgr->ul_trace_buffer_begin, + (char *)hio_mgr->trace_buffer_begin, ul_new_message_length); - hio_mgr->pmsg[hio_mgr->ul_trace_buffer_end - + hio_mgr->pmsg[hio_mgr->trace_buffer_end - hio_mgr->gpp_read_pointer + ul_new_message_length] = '\0'; /* @@ -1735,7 +1735,7 @@ void print_dsp_debug_trace(struct io_mgr *hio_mgr) * pointer. */ hio_mgr->gpp_read_pointer = - hio_mgr->ul_trace_buffer_begin + + hio_mgr->trace_buffer_begin + ul_new_message_length; /* Print the trace messages */ pr_info("DSPTrace: %s\n", hio_mgr->pmsg); @@ -1776,7 +1776,7 @@ int print_dsp_trace_buffer(struct bridge_dev_context *hbridge_context) struct bridge_dev_context *pbridge_context = hbridge_context; struct bridge_drv_interface *intf_fxns; struct dev_object *dev_obj = (struct dev_object *) - pbridge_context->hdev_obj; + pbridge_context->dev_obj; status = dev_get_cod_mgr(dev_obj, &cod_mgr); @@ -1949,7 +1949,7 @@ int dump_dsp_stack(struct bridge_dev_context *bridge_context) "ILC", "RILC", "IER", "CSR"}; const char *exec_ctxt[] = {"Task", "SWI", "HWI", "Unknown"}; struct bridge_drv_interface *intf_fxns; - struct dev_object *dev_object = bridge_context->hdev_obj; + struct dev_object *dev_object = bridge_context->dev_obj; status = dev_get_cod_mgr(dev_object, &code_mgr); if (!code_mgr) { @@ -2155,7 +2155,7 @@ void dump_dl_modules(struct bridge_dev_context *bridge_context) struct cod_manager *code_mgr; struct bridge_drv_interface *intf_fxns; struct bridge_dev_context *bridge_ctxt = bridge_context; - struct dev_object *dev_object = bridge_ctxt->hdev_obj; + struct dev_object *dev_object = bridge_ctxt->dev_obj; struct modules_header modules_hdr; struct dll_module *module_struct = NULL; u32 module_dsp_addr; diff --git a/drivers/staging/tidspbridge/core/msg_sm.c b/drivers/staging/tidspbridge/core/msg_sm.c index 07103f229134..807d55624ceb 100644 --- a/drivers/staging/tidspbridge/core/msg_sm.c +++ b/drivers/staging/tidspbridge/core/msg_sm.c @@ -121,7 +121,7 @@ int bridge_msg_create_queue(struct msg_mgr *hmsg_mgr, struct msg_queue **msgq, return -ENOMEM; msg_q->max_msgs = max_msgs; - msg_q->hmsg_mgr = hmsg_mgr; + msg_q->msg_mgr = hmsg_mgr; msg_q->arg = arg; /* Node handle */ msg_q->msgq_id = msgq_id; /* Node env (not valid yet) */ /* Queues of Message frames for messages from the DSP */ @@ -214,10 +214,10 @@ void bridge_msg_delete_queue(struct msg_queue *msg_queue_obj) struct msg_mgr *hmsg_mgr; u32 io_msg_pend; - if (!msg_queue_obj || !msg_queue_obj->hmsg_mgr) + if (!msg_queue_obj || !msg_queue_obj->msg_mgr) return; - hmsg_mgr = msg_queue_obj->hmsg_mgr; + hmsg_mgr = msg_queue_obj->msg_mgr; msg_queue_obj->done = true; /* Unblock all threads blocked in MSG_Get() or MSG_Put(). */ io_msg_pend = msg_queue_obj->io_msg_pend; @@ -254,7 +254,7 @@ int bridge_msg_get(struct msg_queue *msg_queue_obj, if (!msg_queue_obj || pmsg == NULL) return -ENOMEM; - hmsg_mgr = msg_queue_obj->hmsg_mgr; + hmsg_mgr = msg_queue_obj->msg_mgr; spin_lock_bh(&hmsg_mgr->msg_mgr_lock); /* If a message is already there, get it */ @@ -331,10 +331,10 @@ int bridge_msg_put(struct msg_queue *msg_queue_obj, u32 index; int status; - if (!msg_queue_obj || !pmsg || !msg_queue_obj->hmsg_mgr) + if (!msg_queue_obj || !pmsg || !msg_queue_obj->msg_mgr) return -EFAULT; - hmsg_mgr = msg_queue_obj->hmsg_mgr; + hmsg_mgr = msg_queue_obj->msg_mgr; spin_lock_bh(&hmsg_mgr->msg_mgr_lock); @@ -521,10 +521,10 @@ static void delete_msg_queue(struct msg_queue *msg_queue_obj, u32 num_to_dsp) struct msg_frame *pmsg, *tmp; u32 i; - if (!msg_queue_obj || !msg_queue_obj->hmsg_mgr) + if (!msg_queue_obj || !msg_queue_obj->msg_mgr) return; - hmsg_mgr = msg_queue_obj->hmsg_mgr; + hmsg_mgr = msg_queue_obj->msg_mgr; /* Pull off num_to_dsp message frames from Msg manager and free */ i = 0; diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 2c15b03d9639..e1c4492a7105 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -396,7 +396,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, * last dsp base image was loaded. The first entry is always * SHMMEM base. */ /* Get SHM_BEG - convert to byte address */ - (void)dev_get_symbol(dev_context->hdev_obj, SHMBASENAME, + (void)dev_get_symbol(dev_context->dev_obj, SHMBASENAME, &ul_shm_base_virt); ul_shm_base_virt *= DSPWORDSIZE; DBC_ASSERT(ul_shm_base_virt != 0); @@ -474,12 +474,12 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, itmp_entry_ndx, e->gpp_pa, e->dsp_va, - e->ul_size); + e->size); hw_mmu_tlb_add(dev_context->dsp_mmu_base, e->gpp_pa, e->dsp_va, - e->ul_size, + e->size, itmp_entry_ndx, &map_attrs, 1, 1); @@ -505,9 +505,9 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, hw_mmu_enable(resources->dmmu_base); /* Enable the BIOS clock */ - (void)dev_get_symbol(dev_context->hdev_obj, + (void)dev_get_symbol(dev_context->dev_obj, BRIDGEINIT_BIOSGPTIMER, &ul_bios_gp_timer); - (void)dev_get_symbol(dev_context->hdev_obj, + (void)dev_get_symbol(dev_context->dev_obj, BRIDGEINIT_LOADMON_GPTIMER, &ul_load_monitor_timer); } @@ -536,7 +536,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, if (!status) { /* Set the DSP clock rate */ - (void)dev_get_symbol(dev_context->hdev_obj, + (void)dev_get_symbol(dev_context->dev_obj, "_BRIDGEINIT_DSP_FREQ", &ul_dsp_clk_addr); /*Set Autoidle Mode for IVA2 PLL */ (*pdata->dsp_cm_write)(1 << OMAP3430_AUTO_IVA2_DPLL_SHIFT, @@ -607,7 +607,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, dsp_wdt_sm_set((void *)ul_shm_base); dsp_wdt_enable(true); - status = dev_get_io_mgr(dev_context->hdev_obj, &hio_mgr); + status = dev_get_io_mgr(dev_context->dev_obj, &hio_mgr); if (hio_mgr) { io_sh_msetting(hio_mgr, SHM_OPPINFO, NULL); /* Write the synchronization bit to indicate the @@ -872,7 +872,7 @@ static int bridge_dev_create(struct bridge_dev_context dev_context->dsp_mmu_base = resources->dmmu_base; } if (!status) { - dev_context->hdev_obj = hdev_obj; + dev_context->dev_obj = hdev_obj; /* Store current board state. */ dev_context->brd_state = BRD_UNKNOWN; dev_context->resources = resources; diff --git a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c index 64ca2d246c2f..02dd4391309a 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c +++ b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c @@ -121,7 +121,7 @@ int handle_hibernation_from_dsp(struct bridge_dev_context *dev_context) dev_context->brd_state = BRD_DSP_HIBERNATION; #ifdef CONFIG_TIDSPBRIDGE_DVFS status = - dev_get_io_mgr(dev_context->hdev_obj, &hio_mgr); + dev_get_io_mgr(dev_context->dev_obj, &hio_mgr); if (!hio_mgr) { status = DSP_EHANDLE; return status; @@ -216,7 +216,7 @@ int sleep_dsp(struct bridge_dev_context *dev_context, u32 dw_cmd, pr_err("%s: Timed out waiting for DSP off mode, state %x\n", __func__, pwr_state); #ifdef CONFIG_TIDSPBRIDGE_NTFY_PWRERR - dev_get_deh_mgr(dev_context->hdev_obj, &hdeh_mgr); + dev_get_deh_mgr(dev_context->dev_obj, &hdeh_mgr); bridge_deh_notify(hdeh_mgr, DSP_PWRERROR, 0); #endif /* CONFIG_TIDSPBRIDGE_NTFY_PWRERR */ return -ETIMEDOUT; @@ -382,7 +382,7 @@ int post_scale_dsp(struct bridge_dev_context *dev_context, u32 voltage_domain; struct io_mgr *hio_mgr; - status = dev_get_io_mgr(dev_context->hdev_obj, &hio_mgr); + status = dev_get_io_mgr(dev_context->dev_obj, &hio_mgr); if (!hio_mgr) return -EFAULT; diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c index 257052a52dc6..dfb356eb6723 100644 --- a/drivers/staging/tidspbridge/core/tiomap_io.c +++ b/drivers/staging/tidspbridge/core/tiomap_io.c @@ -65,20 +65,20 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt, bool trace_read = false; if (!ul_shm_base_virt) { - status = dev_get_symbol(dev_context->hdev_obj, + status = dev_get_symbol(dev_context->dev_obj, SHMBASENAME, &ul_shm_base_virt); } DBC_ASSERT(ul_shm_base_virt != 0); /* Check if it is a read of Trace section */ if (!status && !ul_trace_sec_beg) { - status = dev_get_symbol(dev_context->hdev_obj, + status = dev_get_symbol(dev_context->dev_obj, DSP_TRACESEC_BEG, &ul_trace_sec_beg); } DBC_ASSERT(ul_trace_sec_beg != 0); if (!status && !ul_trace_sec_end) { - status = dev_get_symbol(dev_context->hdev_obj, + status = dev_get_symbol(dev_context->dev_obj, DSP_TRACESEC_END, &ul_trace_sec_end); } DBC_ASSERT(ul_trace_sec_end != 0); @@ -102,19 +102,19 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt, /* Get DYNEXT_BEG, EXT_BEG and EXT_END. */ if (!status && !ul_dyn_ext_base) { - status = dev_get_symbol(dev_context->hdev_obj, + status = dev_get_symbol(dev_context->dev_obj, DYNEXTBASE, &ul_dyn_ext_base); } DBC_ASSERT(ul_dyn_ext_base != 0); if (!status) { - status = dev_get_symbol(dev_context->hdev_obj, + status = dev_get_symbol(dev_context->dev_obj, EXTBASE, &ul_ext_base); } DBC_ASSERT(ul_ext_base != 0); if (!status) { - status = dev_get_symbol(dev_context->hdev_obj, + status = dev_get_symbol(dev_context->dev_obj, EXTEND, &ul_ext_end); } DBC_ASSERT(ul_ext_end != 0); @@ -246,10 +246,10 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, if (symbols_reloaded) { /* Check if it is a load to Trace section */ - ret = dev_get_symbol(dev_context->hdev_obj, + ret = dev_get_symbol(dev_context->dev_obj, DSP_TRACESEC_BEG, &ul_trace_sec_beg); if (!ret) - ret = dev_get_symbol(dev_context->hdev_obj, + ret = dev_get_symbol(dev_context->dev_obj, DSP_TRACESEC_END, &ul_trace_sec_end); } @@ -269,7 +269,7 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, if (!dw_base_addr) { if (symbols_reloaded) /* Get SHM_BEG EXT_BEG and EXT_END. */ - ret = dev_get_symbol(dev_context->hdev_obj, + ret = dev_get_symbol(dev_context->dev_obj, SHMBASENAME, &ul_shm_base_virt); DBC_ASSERT(ul_shm_base_virt != 0); if (dynamic_load) { @@ -277,7 +277,7 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, if (symbols_reloaded) ret = dev_get_symbol - (dev_context->hdev_obj, DYNEXTBASE, + (dev_context->dev_obj, DYNEXTBASE, &ul_ext_base); } DBC_ASSERT(ul_ext_base != 0); @@ -289,7 +289,7 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, if (symbols_reloaded) ret = dev_get_symbol - (dev_context->hdev_obj, EXTEND, + (dev_context->dev_obj, EXTEND, &ul_ext_end); } } else { @@ -297,13 +297,13 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, if (!ret) ret = dev_get_symbol - (dev_context->hdev_obj, EXTBASE, + (dev_context->dev_obj, EXTBASE, &ul_ext_base); DBC_ASSERT(ul_ext_base != 0); if (!ret) ret = dev_get_symbol - (dev_context->hdev_obj, EXTEND, + (dev_context->dev_obj, EXTEND, &ul_ext_end); } } @@ -324,12 +324,12 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, if (symbols_reloaded) { ret = dev_get_symbol - (dev_context->hdev_obj, + (dev_context->dev_obj, DSP_TRACESEC_END, &shm0_end); if (!ret) { ret = dev_get_symbol - (dev_context->hdev_obj, DYNEXTBASE, + (dev_context->dev_obj, DYNEXTBASE, &ul_dyn_ext_base); } } diff --git a/drivers/staging/tidspbridge/core/ue_deh.c b/drivers/staging/tidspbridge/core/ue_deh.c index bc2feff662b4..006ffd752895 100644 --- a/drivers/staging/tidspbridge/core/ue_deh.c +++ b/drivers/staging/tidspbridge/core/ue_deh.c @@ -52,7 +52,7 @@ static irqreturn_t mmu_fault_isr(int irq, void *data) if (!deh) return IRQ_HANDLED; - resources = deh->hbridge_context->resources; + resources = deh->bridge_context->resources; if (!resources) { dev_dbg(bridge, "%s: Failed to get Host Resources\n", __func__); @@ -113,7 +113,7 @@ int bridge_deh_create(struct deh_mgr **ret_deh, tasklet_init(&deh->dpc_tasklet, mmu_fault_dpc, (u32) deh); /* Fill in context structure */ - deh->hbridge_context = hbridge_context; + deh->bridge_context = hbridge_context; /* Install ISR function for DSP MMU fault */ status = request_irq(INT_DSP_MMU_IRQ, mmu_fault_isr, 0, @@ -228,7 +228,7 @@ void bridge_deh_notify(struct deh_mgr *deh, int event, int info) return; dev_dbg(bridge, "%s: device exception", __func__); - dev_context = deh->hbridge_context; + dev_context = deh->bridge_context; switch (event) { case DSP_SYSERROR: diff --git a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h b/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h index 318f6b007d59..49326a643f06 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h +++ b/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h @@ -116,7 +116,7 @@ struct chnl_mgr { struct bridge_drv_interface *intf_fxns; struct io_mgr *hio_mgr; /* IO manager */ /* Device this board represents */ - struct dev_object *hdev_obj; + struct dev_object *dev_obj; /* These fields initialized in bridge_chnl_create(): */ u32 output_mask; /* Host output channels w/ full buffers */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h b/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h index e79cbd583c0b..4114c79e2466 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/chnlpriv.h @@ -53,7 +53,7 @@ /* Channel info. */ struct chnl_info { - struct chnl_mgr *hchnl_mgr; /* Owning channel manager. */ + struct chnl_mgr *chnl_mgr; /* Owning channel manager. */ u32 cnhl_id; /* Channel ID. */ void *event_obj; /* Channel I/O completion event. */ /*Abstraction of I/O completion event. */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h b/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h index c995596a04a5..a264fa69a4fc 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/cmmdefs.h @@ -28,7 +28,7 @@ struct cmm_mgrattrs { /* Attributes for CMM_AllocBuf() & CMM_AllocDesc() */ struct cmm_attrs { - u32 ul_seg_id; /* 1,2... are SM segments. 0 is not. */ + u32 seg_id; /* 1,2... are SM segments. 0 is not. */ u32 alignment; /* 0,1,2,4....min_block_size */ }; @@ -53,7 +53,7 @@ struct cmm_attrs { struct cmm_seginfo { u32 seg_base_pa; /* Start Phys address of SM segment */ /* Total size in bytes of segment: DSP+GPP */ - u32 ul_total_seg_size; + u32 total_seg_size; u32 gpp_base_pa; /* Start Phys addr of Gpp SM seg */ u32 gpp_size; /* Size of Gpp SM seg in bytes */ u32 dsp_base_va; /* DSP virt base byte address */ @@ -69,7 +69,7 @@ struct cmm_info { /* # of SM segments registered with this Cmm. */ u32 num_gppsm_segs; /* Total # of allocations outstanding for CMM */ - u32 ul_total_in_use_cnt; + u32 total_in_use_cnt; /* Min SM block size allocation from cmm_create() */ u32 min_block_size; /* Info per registered SM segment. */ @@ -78,7 +78,7 @@ struct cmm_info { /* XlatorCreate attributes */ struct cmm_xlatorattrs { - u32 ul_seg_id; /* segment Id used for SM allocations */ + u32 seg_id; /* segment Id used for SM allocations */ u32 dsp_bufs; /* # of DSP-side bufs */ u32 dsp_buf_size; /* size of DSP-side bufs in GPP bytes */ /* Vm base address alloc'd in client process context */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h index efd731df2bd9..82e2439eb3f1 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h @@ -208,8 +208,8 @@ enum dsp_flushtype { /* Memory Segment Status Values */ struct dsp_memstat { - u32 ul_size; - u32 ul_total_free_size; + u32 size; + u32 total_free_size; u32 len_max_free_block; u32 num_free_blocks; u32 num_alloc_blocks; @@ -388,7 +388,7 @@ struct dsp_resourceinfo { u32 cb_struct; enum dsp_resourceinfotype resource_type; union { - u32 ul_resource; + u32 resource; struct dsp_memstat mem_stat; struct dsp_procloadstat proc_load_stat; } result; diff --git a/drivers/staging/tidspbridge/include/dspbridge/dev.h b/drivers/staging/tidspbridge/include/dspbridge/dev.h index 37d1fff3cb95..f41e4783157f 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dev.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dev.h @@ -109,8 +109,8 @@ extern int dev_create_device(struct dev_object * DEV Initialized * Valid hdev_obj * Ensures: - * 0 and hdev_obj->hnode_mgr != NULL - * else hdev_obj->hnode_mgr == NULL + * 0 and hdev_obj->node_mgr != NULL + * else hdev_obj->node_mgr == NULL */ extern int dev_create2(struct dev_object *hdev_obj); @@ -127,7 +127,7 @@ extern int dev_create2(struct dev_object *hdev_obj); * DEV Initialized * Valid hdev_obj * Ensures: - * 0 and hdev_obj->hnode_mgr == NULL + * 0 and hdev_obj->node_mgr == NULL * else -EPERM. */ extern int dev_destroy2(struct dev_object *hdev_obj); diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h index bd3f885dbe65..ab20062f3a53 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h @@ -120,20 +120,20 @@ union trapped_args { struct { void *hprocessor; - u32 ul_size; + u32 size; void *__user *pp_rsv_addr; } args_proc_rsvmem; struct { void *hprocessor; - u32 ul_size; + u32 size; void *prsv_addr; } args_proc_unrsvmem; struct { void *hprocessor; void *pmpu_addr; - u32 ul_size; + u32 size; void *req_addr; void *__user *pp_map_addr; u32 ul_map_attr; @@ -141,28 +141,28 @@ union trapped_args { struct { void *hprocessor; - u32 ul_size; + u32 size; void *map_addr; } args_proc_unmapmem; struct { void *hprocessor; void *pmpu_addr; - u32 ul_size; + u32 size; u32 dir; } args_proc_dma; struct { void *hprocessor; void *pmpu_addr; - u32 ul_size; + u32 size; u32 ul_flags; } args_proc_flushmemory; struct { void *hprocessor; void *pmpu_addr; - u32 ul_size; + u32 size; } args_proc_invalidatememory; /* NODE Module */ @@ -328,14 +328,14 @@ union trapped_args { /* CMM Module */ struct { - struct cmm_object *hcmm_mgr; + struct cmm_object *cmm_mgr; u32 usize; struct cmm_attrs *pattrs; void **pp_buf_va; } args_cmm_allocbuf; struct { - struct cmm_object *hcmm_mgr; + struct cmm_object *cmm_mgr; void *buf_pa; u32 ul_seg_id; } args_cmm_freebuf; @@ -346,7 +346,7 @@ union trapped_args { } args_cmm_gethandle; struct { - struct cmm_object *hcmm_mgr; + struct cmm_object *cmm_mgr; struct cmm_info __user *cmm_info_obj; } args_cmm_getinfo; diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h index 307d1a09b218..0c7ec04448f1 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h @@ -59,7 +59,7 @@ struct bridge_ioctl_extproc { u32 gpp_pa; /* GPP physical address */ /* GPP virtual address. __va does not work for ioremapped addresses */ u32 gpp_va; - u32 ul_size; /* Size of the mapped memory in bytes */ + u32 size; /* Size of the mapped memory in bytes */ enum hw_endianism_t endianism; enum hw_mmu_mixed_size_t mixed_mode; enum hw_element_size_t elem_size; diff --git a/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h b/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h index 0108fae64f56..ee3a85f08fc3 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/nldrdefs.h @@ -84,8 +84,8 @@ typedef u32(*nldr_writefxn) (void *priv_ref, struct nldr_attrs { nldr_ovlyfxn ovly; nldr_writefxn write; - u16 us_dsp_word_size; - u16 us_dsp_mau_size; + u16 dsp_word_size; + u16 dsp_mau_size; }; /* diff --git a/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h b/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h index c6abbf366e3c..046259cdf445 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h @@ -28,7 +28,7 @@ struct strm_attr { char *pstr_event_name; void *virt_base; /* Process virtual base address of * mapped SM */ - u32 ul_virt_size; /* Size of virtual space in bytes */ + u32 virt_size; /* Size of virtual space in bytes */ struct dsp_streamattrin *stream_attr_in; }; diff --git a/drivers/staging/tidspbridge/pmgr/cmm.c b/drivers/staging/tidspbridge/pmgr/cmm.c index 4142e9afd543..e6b2c8962f81 100644 --- a/drivers/staging/tidspbridge/pmgr/cmm.c +++ b/drivers/staging/tidspbridge/pmgr/cmm.c @@ -49,7 +49,7 @@ #include /* ----------------------------------- Defines, Data Structures, Typedefs */ -#define NEXT_PA(pnode) (pnode->pa + pnode->ul_size) +#define NEXT_PA(pnode) (pnode->pa + pnode->size) /* Other bus/platform translations */ #define DSPPA2GPPPA(base, x, y) ((x)+(y)) @@ -63,7 +63,7 @@ */ struct cmm_allocator { /* sma */ unsigned int shm_base; /* Start of physical SM block */ - u32 ul_sm_size; /* Size of SM block in bytes */ + u32 sm_size; /* Size of SM block in bytes */ unsigned int vm_base; /* Start of VM block. (Dev driver * context for 'sma') */ u32 dsp_phys_addr_offset; /* DSP PA to GPP PA offset for this @@ -71,7 +71,7 @@ struct cmm_allocator { /* sma */ s8 c_factor; /* DSPPa to GPPPa Conversion Factor */ unsigned int dsp_base; /* DSP virt base byte address */ u32 dsp_size; /* DSP seg size in bytes */ - struct cmm_object *hcmm_mgr; /* back ref to parent mgr */ + struct cmm_object *cmm_mgr; /* back ref to parent mgr */ /* node list of available memory */ struct list_head free_list; /* node list of memory in use */ @@ -80,15 +80,15 @@ struct cmm_allocator { /* sma */ struct cmm_xlator { /* Pa<->Va translator object */ /* CMM object this translator associated */ - struct cmm_object *hcmm_mgr; + struct cmm_object *cmm_mgr; /* * Client process virtual base address that corresponds to phys SM - * base address for translator's ul_seg_id. + * base address for translator's seg_id. * Only 1 segment ID currently supported. */ unsigned int virt_base; /* virtual base address */ - u32 ul_virt_size; /* size of virt space in bytes */ - u32 ul_seg_id; /* Segment Id */ + u32 virt_size; /* size of virt space in bytes */ + u32 seg_id; /* Segment Id */ }; /* CMM Mgr */ @@ -112,12 +112,12 @@ static struct cmm_mgrattrs cmm_dfltmgrattrs = { /* Default allocation attributes */ static struct cmm_attrs cmm_dfltalctattrs = { - 1 /* ul_seg_id, default segment Id for allocator */ + 1 /* seg_id, default segment Id for allocator */ }; /* Address translator default attrs */ static struct cmm_xlatorattrs cmm_dfltxlatorattrs = { - /* ul_seg_id, does not have to match cmm_dfltalctattrs ul_seg_id */ + /* seg_id, does not have to match cmm_dfltalctattrs ul_seg_id */ 1, 0, /* dsp_bufs */ 0, /* dsp_buf_size */ @@ -130,7 +130,7 @@ struct cmm_mnode { struct list_head link; /* must be 1st element */ u32 pa; /* Phys addr */ u32 va; /* Virtual address in device process context */ - u32 ul_size; /* SM block size in bytes */ + u32 size; /* SM block size in bytes */ u32 client_proc; /* Process that allocated this mem block */ }; @@ -180,11 +180,11 @@ void *cmm_calloc_buf(struct cmm_object *hcmm_mgr, u32 usize, *pp_buf_va = NULL; if (cmm_mgr_obj && (usize != 0)) { - if (pattrs->ul_seg_id > 0) { + if (pattrs->seg_id > 0) { /* SegId > 0 is SM */ /* get the allocator object for this segment id */ allocator = - get_allocator(cmm_mgr_obj, pattrs->ul_seg_id); + get_allocator(cmm_mgr_obj, pattrs->seg_id); /* keep block size a multiple of min_block_size */ usize = ((usize - 1) & ~(cmm_mgr_obj->min_block_size - @@ -194,7 +194,7 @@ void *cmm_calloc_buf(struct cmm_object *hcmm_mgr, u32 usize, pnode = get_free_block(allocator, usize); } if (pnode) { - delta_size = (pnode->ul_size - usize); + delta_size = (pnode->size - usize); if (delta_size >= cmm_mgr_obj->min_block_size) { /* create a new block with the leftovers and * add to freelist */ @@ -205,7 +205,7 @@ void *cmm_calloc_buf(struct cmm_object *hcmm_mgr, u32 usize, /* leftovers go free */ add_to_free_list(allocator, new_node); /* adjust our node's size */ - pnode->ul_size = usize; + pnode->size = usize; } /* Tag node with client process requesting allocation * We'll need to free up a process's alloc'd SM if the @@ -294,7 +294,7 @@ int cmm_destroy(struct cmm_object *hcmm_mgr, bool force) /* Check for outstanding memory allocations */ status = cmm_get_info(hcmm_mgr, &temp_info); if (!status) { - if (temp_info.ul_total_in_use_cnt > 0) { + if (temp_info.total_in_use_cnt > 0) { /* outstanding allocations */ status = -EPERM; } @@ -356,7 +356,7 @@ int cmm_free_buf(struct cmm_object *hcmm_mgr, void *buf_pa, u32 ul_seg_id) if (ul_seg_id == 0) { pattrs = &cmm_dfltalctattrs; - ul_seg_id = pattrs->ul_seg_id; + ul_seg_id = pattrs->seg_id; } if (!hcmm_mgr || !(ul_seg_id > 0)) { status = -EFAULT; @@ -428,7 +428,7 @@ int cmm_get_info(struct cmm_object *hcmm_mgr, mutex_lock(&cmm_mgr_obj->cmm_lock); cmm_info_obj->num_gppsm_segs = 0; /* # of SM segments */ /* Total # of outstanding alloc */ - cmm_info_obj->ul_total_in_use_cnt = 0; + cmm_info_obj->total_in_use_cnt = 0; /* min block size */ cmm_info_obj->min_block_size = cmm_mgr_obj->min_block_size; /* check SM memory segments */ @@ -440,12 +440,12 @@ int cmm_get_info(struct cmm_object *hcmm_mgr, cmm_info_obj->num_gppsm_segs++; cmm_info_obj->seg_info[ul_seg - 1].seg_base_pa = altr->shm_base - altr->dsp_size; - cmm_info_obj->seg_info[ul_seg - 1].ul_total_seg_size = - altr->dsp_size + altr->ul_sm_size; + cmm_info_obj->seg_info[ul_seg - 1].total_seg_size = + altr->dsp_size + altr->sm_size; cmm_info_obj->seg_info[ul_seg - 1].gpp_base_pa = altr->shm_base; cmm_info_obj->seg_info[ul_seg - 1].gpp_size = - altr->ul_sm_size; + altr->sm_size; cmm_info_obj->seg_info[ul_seg - 1].dsp_base_va = altr->dsp_base; cmm_info_obj->seg_info[ul_seg - 1].dsp_size = @@ -455,7 +455,7 @@ int cmm_get_info(struct cmm_object *hcmm_mgr, cmm_info_obj->seg_info[ul_seg - 1].in_use_cnt = 0; list_for_each_entry(curr, &altr->in_use_list, link) { - cmm_info_obj->ul_total_in_use_cnt++; + cmm_info_obj->total_in_use_cnt++; cmm_info_obj->seg_info[ul_seg - 1].in_use_cnt++; } } @@ -536,9 +536,9 @@ int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr, goto func_end; } - psma->hcmm_mgr = hcmm_mgr; /* ref to parent */ + psma->cmm_mgr = hcmm_mgr; /* ref to parent */ psma->shm_base = dw_gpp_base_pa; /* SM Base phys */ - psma->ul_sm_size = ul_size; /* SM segment size in bytes */ + psma->sm_size = ul_size; /* SM segment size in bytes */ psma->vm_base = gpp_base_va; psma->dsp_phys_addr_offset = dsp_addr_offset; psma->c_factor = c_factor; @@ -706,7 +706,7 @@ static struct cmm_mnode *get_node(struct cmm_object *cmm_mgr_obj, u32 dw_pa, pnode->pa = dw_pa; pnode->va = dw_va; - pnode->ul_size = ul_size; + pnode->size = ul_size; return pnode; } @@ -738,7 +738,7 @@ static struct cmm_mnode *get_free_block(struct cmm_allocator *allocator, return NULL; list_for_each_entry_safe(node, tmp, &allocator->free_list, link) { - if (usize <= node->ul_size) { + if (usize <= node->size) { list_del(&node->link); return node; } @@ -764,20 +764,20 @@ static void add_to_free_list(struct cmm_allocator *allocator, list_for_each_entry(curr, &allocator->free_list, link) { if (NEXT_PA(curr) == node->pa) { - curr->ul_size += node->ul_size; - delete_node(allocator->hcmm_mgr, node); + curr->size += node->size; + delete_node(allocator->cmm_mgr, node); return; } if (curr->pa == NEXT_PA(node)) { curr->pa = node->pa; curr->va = node->va; - curr->ul_size += node->ul_size; - delete_node(allocator->hcmm_mgr, node); + curr->size += node->size; + delete_node(allocator->cmm_mgr, node); return; } } list_for_each_entry(curr, &allocator->free_list, link) { - if (curr->ul_size >= node->ul_size) { + if (curr->size >= node->size) { list_add_tail(&node->link, &curr->link); return; } @@ -828,9 +828,9 @@ int cmm_xlator_create(struct cmm_xlatorobject **xlator, xlator_object = kzalloc(sizeof(struct cmm_xlator), GFP_KERNEL); if (xlator_object != NULL) { - xlator_object->hcmm_mgr = hcmm_mgr; /* ref back to CMM */ + xlator_object->cmm_mgr = hcmm_mgr; /* ref back to CMM */ /* SM seg_id */ - xlator_object->ul_seg_id = xlator_attrs->ul_seg_id; + xlator_object->seg_id = xlator_attrs->seg_id; } else { status = -ENOMEM; } @@ -853,17 +853,17 @@ void *cmm_xlator_alloc_buf(struct cmm_xlatorobject *xlator, void *va_buf, DBC_REQUIRE(refs > 0); DBC_REQUIRE(xlator != NULL); - DBC_REQUIRE(xlator_obj->hcmm_mgr != NULL); + DBC_REQUIRE(xlator_obj->cmm_mgr != NULL); DBC_REQUIRE(va_buf != NULL); DBC_REQUIRE(pa_size > 0); - DBC_REQUIRE(xlator_obj->ul_seg_id > 0); + DBC_REQUIRE(xlator_obj->seg_id > 0); if (xlator_obj) { - attrs.ul_seg_id = xlator_obj->ul_seg_id; + attrs.seg_id = xlator_obj->seg_id; __raw_writel(0, va_buf); /* Alloc SM */ pbuf = - cmm_calloc_buf(xlator_obj->hcmm_mgr, pa_size, &attrs, NULL); + cmm_calloc_buf(xlator_obj->cmm_mgr, pa_size, &attrs, NULL); if (pbuf) { /* convert to translator(node/strm) process Virtual * address */ @@ -889,14 +889,14 @@ int cmm_xlator_free_buf(struct cmm_xlatorobject *xlator, void *buf_va) DBC_REQUIRE(refs > 0); DBC_REQUIRE(buf_va != NULL); - DBC_REQUIRE(xlator_obj->ul_seg_id > 0); + DBC_REQUIRE(xlator_obj->seg_id > 0); if (xlator_obj) { /* convert Va to Pa so we can free it. */ buf_pa = cmm_xlator_translate(xlator, buf_va, CMM_VA2PA); if (buf_pa) { - status = cmm_free_buf(xlator_obj->hcmm_mgr, buf_pa, - xlator_obj->ul_seg_id); + status = cmm_free_buf(xlator_obj->cmm_mgr, buf_pa, + xlator_obj->seg_id); if (status) { /* Uh oh, this shouldn't happen. Descriptor * gone! */ @@ -926,7 +926,7 @@ int cmm_xlator_info(struct cmm_xlatorobject *xlator, u8 ** paddr, if (set_info) { /* set translators virtual address range */ xlator_obj->virt_base = (u32) *paddr; - xlator_obj->ul_virt_size = ul_size; + xlator_obj->virt_size = ul_size; } else { /* return virt base address */ *paddr = (u8 *) xlator_obj->virt_base; } @@ -955,10 +955,10 @@ void *cmm_xlator_translate(struct cmm_xlatorobject *xlator, void *paddr, if (!xlator_obj) goto loop_cont; - cmm_mgr_obj = (struct cmm_object *)xlator_obj->hcmm_mgr; + cmm_mgr_obj = (struct cmm_object *)xlator_obj->cmm_mgr; /* get this translator's default SM allocator */ - DBC_ASSERT(xlator_obj->ul_seg_id > 0); - allocator = cmm_mgr_obj->pa_gppsm_seg_tab[xlator_obj->ul_seg_id - 1]; + DBC_ASSERT(xlator_obj->seg_id > 0); + allocator = cmm_mgr_obj->pa_gppsm_seg_tab[xlator_obj->seg_id - 1]; if (!allocator) goto loop_cont; @@ -974,7 +974,7 @@ void *cmm_xlator_translate(struct cmm_xlatorobject *xlator, void *paddr, if ((dw_addr_xlate < xlator_obj->virt_base) || (dw_addr_xlate >= (xlator_obj->virt_base + - xlator_obj->ul_virt_size))) { + xlator_obj->virt_size))) { dw_addr_xlate = 0; /* bad address */ } } else { diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c index b855e440daf2..ce7360f5111b 100644 --- a/drivers/staging/tidspbridge/pmgr/dev.c +++ b/drivers/staging/tidspbridge/pmgr/dev.c @@ -61,22 +61,22 @@ struct dev_object { u8 dev_type; /* Device Type */ struct cfg_devnode *dev_node_obj; /* Platform specific dev id */ /* Bridge Context Handle */ - struct bridge_dev_context *hbridge_context; + struct bridge_dev_context *bridge_context; /* Function interface to Bridge driver. */ struct bridge_drv_interface bridge_interface; struct brd_object *lock_owner; /* Client with exclusive access. */ struct cod_manager *cod_mgr; /* Code manager handle. */ - struct chnl_mgr *hchnl_mgr; /* Channel manager. */ - struct deh_mgr *hdeh_mgr; /* DEH manager. */ - struct msg_mgr *hmsg_mgr; /* Message manager. */ + struct chnl_mgr *chnl_mgr; /* Channel manager. */ + struct deh_mgr *deh_mgr; /* DEH manager. */ + struct msg_mgr *msg_mgr; /* Message manager. */ struct io_mgr *hio_mgr; /* IO manager (CHNL, msg_ctrl) */ - struct cmm_object *hcmm_mgr; /* SM memory manager. */ + struct cmm_object *cmm_mgr; /* SM memory manager. */ struct dmm_object *dmm_mgr; /* Dynamic memory manager. */ u32 word_size; /* DSP word size: quick access. */ - struct drv_object *hdrv_obj; /* Driver Object */ + struct drv_object *drv_obj; /* Driver Object */ /* List of Processors attached to this device */ struct list_head proc_list; - struct node_mgr *hnode_mgr; + struct node_mgr *node_mgr; }; struct drv_ext { @@ -110,9 +110,9 @@ u32 dev_brd_write_fxn(void *arb, u32 dsp_add, void *host_buf, DBC_REQUIRE(host_buf != NULL); /* Required of BrdWrite(). */ if (dev_obj) { /* Require of BrdWrite() */ - DBC_ASSERT(dev_obj->hbridge_context != NULL); + DBC_ASSERT(dev_obj->bridge_context != NULL); status = (*dev_obj->bridge_interface.brd_write) ( - dev_obj->hbridge_context, host_buf, + dev_obj->bridge_context, host_buf, dsp_add, ul_num_bytes, mem_space); /* Special case of getting the address only */ if (ul_num_bytes == 0) @@ -175,11 +175,11 @@ int dev_create_device(struct dev_object **device_obj, /* Fill out the rest of the Dev Object structure: */ dev_obj->dev_node_obj = dev_node_obj; dev_obj->cod_mgr = NULL; - dev_obj->hchnl_mgr = NULL; - dev_obj->hdeh_mgr = NULL; + dev_obj->chnl_mgr = NULL; + dev_obj->deh_mgr = NULL; dev_obj->lock_owner = NULL; dev_obj->word_size = DSPWORDSIZE; - dev_obj->hdrv_obj = hdrv_obj; + dev_obj->drv_obj = hdrv_obj; dev_obj->dev_type = DSP_UNIT; /* Store this Bridge's interface functions, based on its * version. */ @@ -189,11 +189,11 @@ int dev_create_device(struct dev_object **device_obj, /* Call fxn_dev_create() to get the Bridge's device * context handle. */ status = (dev_obj->bridge_interface.dev_create) - (&dev_obj->hbridge_context, dev_obj, + (&dev_obj->bridge_context, dev_obj, host_res); /* Assert bridge_dev_create()'s ensure clause: */ DBC_ASSERT(status - || (dev_obj->hbridge_context != NULL)); + || (dev_obj->bridge_context != NULL)); } else { status = -ENOMEM; } @@ -224,24 +224,24 @@ int dev_create_device(struct dev_object **device_obj, pr_err("%s: No memory reserved for shared structures\n", __func__); } - status = chnl_create(&dev_obj->hchnl_mgr, dev_obj, &mgr_attrs); + status = chnl_create(&dev_obj->chnl_mgr, dev_obj, &mgr_attrs); if (status == -ENOSYS) { /* It's OK for a device not to have a channel * manager: */ status = 0; } /* Create CMM mgr even if Msg Mgr not impl. */ - status = cmm_create(&dev_obj->hcmm_mgr, + status = cmm_create(&dev_obj->cmm_mgr, (struct dev_object *)dev_obj, NULL); /* Only create IO manager if we have a channel manager */ - if (!status && dev_obj->hchnl_mgr) { + if (!status && dev_obj->chnl_mgr) { status = io_create(&dev_obj->hio_mgr, dev_obj, &io_mgr_attrs); } /* Only create DEH manager if we have an IO manager */ if (!status) { /* Instantiate the DEH module */ - status = bridge_deh_create(&dev_obj->hdeh_mgr, dev_obj); + status = bridge_deh_create(&dev_obj->deh_mgr, dev_obj); } /* Create DMM mgr . */ status = dmm_create(&dev_obj->dmm_mgr, @@ -291,13 +291,13 @@ int dev_create2(struct dev_object *hdev_obj) DBC_REQUIRE(hdev_obj); /* There can be only one Node Manager per DEV object */ - DBC_ASSERT(!dev_obj->hnode_mgr); - status = node_create_mgr(&dev_obj->hnode_mgr, hdev_obj); + DBC_ASSERT(!dev_obj->node_mgr); + status = node_create_mgr(&dev_obj->node_mgr, hdev_obj); if (status) - dev_obj->hnode_mgr = NULL; + dev_obj->node_mgr = NULL; - DBC_ENSURE((!status && dev_obj->hnode_mgr != NULL) - || (status && dev_obj->hnode_mgr == NULL)); + DBC_ENSURE((!status && dev_obj->node_mgr != NULL) + || (status && dev_obj->node_mgr == NULL)); return status; } @@ -314,15 +314,15 @@ int dev_destroy2(struct dev_object *hdev_obj) DBC_REQUIRE(refs > 0); DBC_REQUIRE(hdev_obj); - if (dev_obj->hnode_mgr) { - if (node_delete_mgr(dev_obj->hnode_mgr)) + if (dev_obj->node_mgr) { + if (node_delete_mgr(dev_obj->node_mgr)) status = -EPERM; else - dev_obj->hnode_mgr = NULL; + dev_obj->node_mgr = NULL; } - DBC_ENSURE((!status && dev_obj->hnode_mgr == NULL) || status); + DBC_ENSURE((!status && dev_obj->node_mgr == NULL) || status); return status; } @@ -345,9 +345,9 @@ int dev_destroy_device(struct dev_object *hdev_obj) dev_obj->cod_mgr = NULL; } - if (dev_obj->hnode_mgr) { - node_delete_mgr(dev_obj->hnode_mgr); - dev_obj->hnode_mgr = NULL; + if (dev_obj->node_mgr) { + node_delete_mgr(dev_obj->node_mgr); + dev_obj->node_mgr = NULL; } /* Free the io, channel, and message managers for this board: */ @@ -355,23 +355,23 @@ int dev_destroy_device(struct dev_object *hdev_obj) io_destroy(dev_obj->hio_mgr); dev_obj->hio_mgr = NULL; } - if (dev_obj->hchnl_mgr) { - chnl_destroy(dev_obj->hchnl_mgr); - dev_obj->hchnl_mgr = NULL; + if (dev_obj->chnl_mgr) { + chnl_destroy(dev_obj->chnl_mgr); + dev_obj->chnl_mgr = NULL; } - if (dev_obj->hmsg_mgr) { - msg_delete(dev_obj->hmsg_mgr); - dev_obj->hmsg_mgr = NULL; + if (dev_obj->msg_mgr) { + msg_delete(dev_obj->msg_mgr); + dev_obj->msg_mgr = NULL; } - if (dev_obj->hdeh_mgr) { + if (dev_obj->deh_mgr) { /* Uninitialize DEH module. */ - bridge_deh_destroy(dev_obj->hdeh_mgr); - dev_obj->hdeh_mgr = NULL; + bridge_deh_destroy(dev_obj->deh_mgr); + dev_obj->deh_mgr = NULL; } - if (dev_obj->hcmm_mgr) { - cmm_destroy(dev_obj->hcmm_mgr, true); - dev_obj->hcmm_mgr = NULL; + if (dev_obj->cmm_mgr) { + cmm_destroy(dev_obj->cmm_mgr, true); + dev_obj->cmm_mgr = NULL; } if (dev_obj->dmm_mgr) { @@ -381,15 +381,15 @@ int dev_destroy_device(struct dev_object *hdev_obj) /* Call the driver's bridge_dev_destroy() function: */ /* Require of DevDestroy */ - if (dev_obj->hbridge_context) { + if (dev_obj->bridge_context) { status = (*dev_obj->bridge_interface.dev_destroy) - (dev_obj->hbridge_context); - dev_obj->hbridge_context = NULL; + (dev_obj->bridge_context); + dev_obj->bridge_context = NULL; } else status = -EPERM; if (!status) { /* Remove this DEV_Object from the global list: */ - drv_remove_dev_object(dev_obj->hdrv_obj, dev_obj); + drv_remove_dev_object(dev_obj->drv_obj, dev_obj); /* Free The library * LDR_FreeModule * (dev_obj->module_obj); */ /* Free this dev object: */ @@ -419,7 +419,7 @@ int dev_get_chnl_mgr(struct dev_object *hdev_obj, DBC_REQUIRE(mgr != NULL); if (hdev_obj) { - *mgr = dev_obj->hchnl_mgr; + *mgr = dev_obj->chnl_mgr; } else { *mgr = NULL; status = -EFAULT; @@ -445,7 +445,7 @@ int dev_get_cmm_mgr(struct dev_object *hdev_obj, DBC_REQUIRE(mgr != NULL); if (hdev_obj) { - *mgr = dev_obj->hcmm_mgr; + *mgr = dev_obj->cmm_mgr; } else { *mgr = NULL; status = -EFAULT; @@ -518,7 +518,7 @@ int dev_get_deh_mgr(struct dev_object *hdev_obj, DBC_REQUIRE(deh_manager != NULL); DBC_REQUIRE(hdev_obj); if (hdev_obj) { - *deh_manager = hdev_obj->hdeh_mgr; + *deh_manager = hdev_obj->deh_mgr; } else { *deh_manager = NULL; status = -EFAULT; @@ -642,7 +642,7 @@ void dev_get_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr **msg_man) DBC_REQUIRE(msg_man != NULL); DBC_REQUIRE(hdev_obj); - *msg_man = hdev_obj->hmsg_mgr; + *msg_man = hdev_obj->msg_mgr; } /* @@ -660,7 +660,7 @@ int dev_get_node_manager(struct dev_object *hdev_obj, DBC_REQUIRE(node_man != NULL); if (hdev_obj) { - *node_man = dev_obj->hnode_mgr; + *node_man = dev_obj->node_mgr; } else { *node_man = NULL; status = -EFAULT; @@ -710,7 +710,7 @@ int dev_get_bridge_context(struct dev_object *hdev_obj, DBC_REQUIRE(phbridge_context != NULL); if (hdev_obj) { - *phbridge_context = dev_obj->hbridge_context; + *phbridge_context = dev_obj->bridge_context; } else { *phbridge_context = NULL; status = -EFAULT; @@ -844,11 +844,11 @@ int dev_set_chnl_mgr(struct dev_object *hdev_obj, DBC_REQUIRE(refs > 0); if (hdev_obj) - dev_obj->hchnl_mgr = hmgr; + dev_obj->chnl_mgr = hmgr; else status = -EFAULT; - DBC_ENSURE(status || (dev_obj->hchnl_mgr == hmgr)); + DBC_ENSURE(status || (dev_obj->chnl_mgr == hmgr)); return status; } @@ -862,7 +862,7 @@ void dev_set_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr *hmgr) DBC_REQUIRE(refs > 0); DBC_REQUIRE(hdev_obj); - hdev_obj->hmsg_mgr = hmgr; + hdev_obj->msg_mgr = hmgr; } /* diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c index 575243882d0b..b7ff37810555 100644 --- a/drivers/staging/tidspbridge/pmgr/dspapi.c +++ b/drivers/staging/tidspbridge/pmgr/dspapi.c @@ -695,7 +695,7 @@ u32 procwrap_end_dma(union trapped_args *args, void *pr_ctxt) status = proc_end_dma(pr_ctxt, args->args_proc_dma.pmpu_addr, - args->args_proc_dma.ul_size, + args->args_proc_dma.size, args->args_proc_dma.dir); return status; } @@ -709,7 +709,7 @@ u32 procwrap_begin_dma(union trapped_args *args, void *pr_ctxt) status = proc_begin_dma(pr_ctxt, args->args_proc_dma.pmpu_addr, - args->args_proc_dma.ul_size, + args->args_proc_dma.size, args->args_proc_dma.dir); return status; } @@ -727,7 +727,7 @@ u32 procwrap_flush_memory(union trapped_args *args, void *pr_ctxt) status = proc_flush_memory(pr_ctxt, args->args_proc_flushmemory.pmpu_addr, - args->args_proc_flushmemory.ul_size, + args->args_proc_flushmemory.size, args->args_proc_flushmemory.ul_flags); return status; } @@ -742,7 +742,7 @@ u32 procwrap_invalidate_memory(union trapped_args *args, void *pr_ctxt) status = proc_invalidate_memory(pr_ctxt, args->args_proc_invalidatememory.pmpu_addr, - args->args_proc_invalidatememory.ul_size); + args->args_proc_invalidatememory.size); return status; } @@ -950,12 +950,12 @@ u32 procwrap_map(union trapped_args *args, void *pr_ctxt) void *map_addr; void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; - if (!args->args_proc_mapmem.ul_size) + if (!args->args_proc_mapmem.size) return -EINVAL; status = proc_map(args->args_proc_mapmem.hprocessor, args->args_proc_mapmem.pmpu_addr, - args->args_proc_mapmem.ul_size, + args->args_proc_mapmem.size, args->args_proc_mapmem.req_addr, &map_addr, args->args_proc_mapmem.ul_map_attr, pr_ctxt); if (!status) { @@ -999,12 +999,12 @@ u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt) void *prsv_addr; void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; - if ((args->args_proc_rsvmem.ul_size <= 0) || - (args->args_proc_rsvmem.ul_size & (PG_SIZE4K - 1)) != 0) + if ((args->args_proc_rsvmem.size <= 0) || + (args->args_proc_rsvmem.size & (PG_SIZE4K - 1)) != 0) return -EINVAL; status = proc_reserve_memory(hprocessor, - args->args_proc_rsvmem.ul_size, &prsv_addr, + args->args_proc_rsvmem.size, &prsv_addr, pr_ctxt); if (!status) { if (put_user(prsv_addr, args->args_proc_rsvmem.pp_rsv_addr)) { @@ -1905,7 +1905,7 @@ u32 cmmwrap_get_info(union trapped_args *args, void *pr_ctxt) int status = 0; struct cmm_info cmm_info_obj; - status = cmm_get_info(args->args_cmm_getinfo.hcmm_mgr, &cmm_info_obj); + status = cmm_get_info(args->args_cmm_getinfo.cmm_mgr, &cmm_info_obj); CP_TO_USR(args->args_cmm_getinfo.cmm_info_obj, &cmm_info_obj, status, 1); diff --git a/drivers/staging/tidspbridge/pmgr/io.c b/drivers/staging/tidspbridge/pmgr/io.c index 01ef637c31dd..b05a772d8d99 100644 --- a/drivers/staging/tidspbridge/pmgr/io.c +++ b/drivers/staging/tidspbridge/pmgr/io.c @@ -73,7 +73,7 @@ int io_create(struct io_mgr **io_man, struct dev_object *hdev_obj, if (!status) { pio_mgr = (struct io_mgr_ *)hio_mgr; pio_mgr->intf_fxns = intf_fxns; - pio_mgr->hdev_obj = hdev_obj; + pio_mgr->dev_obj = hdev_obj; /* Return the new channel manager handle: */ *io_man = hio_mgr; diff --git a/drivers/staging/tidspbridge/pmgr/ioobj.h b/drivers/staging/tidspbridge/pmgr/ioobj.h index f46355fa7b29..7defd9481458 100644 --- a/drivers/staging/tidspbridge/pmgr/ioobj.h +++ b/drivers/staging/tidspbridge/pmgr/ioobj.h @@ -29,10 +29,10 @@ */ struct io_mgr_ { /* These must be the first fields in a io_mgr struct: */ - struct bridge_dev_context *hbridge_context; /* Bridge context. */ + struct bridge_dev_context *bridge_context; /* Bridge context. */ /* Function interface to Bridge driver. */ struct bridge_drv_interface *intf_fxns; - struct dev_object *hdev_obj; /* Device this board represents. */ + struct dev_object *dev_obj; /* Device this board represents. */ }; #endif /* IOOBJ_ */ diff --git a/drivers/staging/tidspbridge/rmgr/disp.c b/drivers/staging/tidspbridge/rmgr/disp.c index 49e38f36b05d..e5af59e844d9 100644 --- a/drivers/staging/tidspbridge/rmgr/disp.c +++ b/drivers/staging/tidspbridge/rmgr/disp.c @@ -58,10 +58,10 @@ * ======== disp_object ======== */ struct disp_object { - struct dev_object *hdev_obj; /* Device for this processor */ + struct dev_object *dev_obj; /* Device for this processor */ /* Function interface to Bridge driver */ struct bridge_drv_interface *intf_fxns; - struct chnl_mgr *hchnl_mgr; /* Channel manager */ + struct chnl_mgr *chnl_mgr; /* Channel manager */ struct chnl_object *chnl_to_dsp; /* Chnl for commands to RMS */ struct chnl_object *chnl_from_dsp; /* Chnl for replies from RMS */ u8 *pbuf; /* Buffer for commands, replies */ @@ -108,11 +108,11 @@ int disp_create(struct disp_object **dispatch_obj, if (disp_obj == NULL) status = -ENOMEM; else - disp_obj->hdev_obj = hdev_obj; + disp_obj->dev_obj = hdev_obj; /* Get Channel manager and Bridge function interface */ if (!status) { - status = dev_get_chnl_mgr(hdev_obj, &(disp_obj->hchnl_mgr)); + status = dev_get_chnl_mgr(hdev_obj, &(disp_obj->chnl_mgr)); if (!status) { (void)dev_get_intf_fxns(hdev_obj, &intf_fxns); disp_obj->intf_fxns = intf_fxns; @@ -142,7 +142,7 @@ int disp_create(struct disp_object **dispatch_obj, chnl_attr_obj.event_obj = NULL; ul_chnl_id = disp_attrs->chnl_offset + CHNLTORMSOFFSET; status = (*intf_fxns->chnl_open) (&(disp_obj->chnl_to_dsp), - disp_obj->hchnl_mgr, + disp_obj->chnl_mgr, CHNL_MODETODSP, ul_chnl_id, &chnl_attr_obj); @@ -150,7 +150,7 @@ int disp_create(struct disp_object **dispatch_obj, ul_chnl_id = disp_attrs->chnl_offset + CHNLFROMRMSOFFSET; status = (*intf_fxns->chnl_open) (&(disp_obj->chnl_from_dsp), - disp_obj->hchnl_mgr, + disp_obj->chnl_mgr, CHNL_MODEFROMDSP, ul_chnl_id, &chnl_attr_obj); } @@ -282,7 +282,7 @@ int disp_node_create(struct disp_object *disp_obj, DBC_REQUIRE(node_get_type(hnode) != NODE_DEVICE); DBC_REQUIRE(node_env != NULL); - status = dev_get_dev_type(disp_obj->hdev_obj, &dev_type); + status = dev_get_dev_type(disp_obj->dev_obj, &dev_type); if (status) goto func_end; @@ -484,7 +484,7 @@ int disp_node_delete(struct disp_object *disp_obj, DBC_REQUIRE(disp_obj); DBC_REQUIRE(hnode != NULL); - status = dev_get_dev_type(disp_obj->hdev_obj, &dev_type); + status = dev_get_dev_type(disp_obj->dev_obj, &dev_type); if (!status) { @@ -525,7 +525,7 @@ int disp_node_run(struct disp_object *disp_obj, DBC_REQUIRE(disp_obj); DBC_REQUIRE(hnode != NULL); - status = dev_get_dev_type(disp_obj->hdev_obj, &dev_type); + status = dev_get_dev_type(disp_obj->dev_obj, &dev_type); if (!status) { diff --git a/drivers/staging/tidspbridge/rmgr/mgr.c b/drivers/staging/tidspbridge/rmgr/mgr.c index 16410a5a9b6f..d635c01c015e 100644 --- a/drivers/staging/tidspbridge/rmgr/mgr.c +++ b/drivers/staging/tidspbridge/rmgr/mgr.c @@ -44,7 +44,7 @@ #define ZLDLLNAME "" struct mgr_object { - struct dcd_manager *hdcd_mgr; /* Proc/Node data manager */ + struct dcd_manager *dcd_mgr; /* Proc/Node data manager */ }; /* ----------------------------------- Globals */ @@ -67,7 +67,7 @@ int mgr_create(struct mgr_object **mgr_obj, pmgr_obj = kzalloc(sizeof(struct mgr_object), GFP_KERNEL); if (pmgr_obj) { - status = dcd_create_manager(ZLDLLNAME, &pmgr_obj->hdcd_mgr); + status = dcd_create_manager(ZLDLLNAME, &pmgr_obj->dcd_mgr); if (!status) { /* If succeeded store the handle in the MGR Object */ if (drv_datap) { @@ -81,7 +81,7 @@ int mgr_create(struct mgr_object **mgr_obj, if (!status) { *mgr_obj = pmgr_obj; } else { - dcd_destroy_manager(pmgr_obj->hdcd_mgr); + dcd_destroy_manager(pmgr_obj->dcd_mgr); kfree(pmgr_obj); } } else { @@ -110,8 +110,8 @@ int mgr_destroy(struct mgr_object *hmgr_obj) DBC_REQUIRE(hmgr_obj); /* Free resources */ - if (hmgr_obj->hdcd_mgr) - dcd_destroy_manager(hmgr_obj->hdcd_mgr); + if (hmgr_obj->dcd_mgr) + dcd_destroy_manager(hmgr_obj->dcd_mgr); kfree(pmgr_obj); /* Update the driver data with NULL for MGR Object */ @@ -163,7 +163,7 @@ int mgr_enum_node_info(u32 node_id, struct dsp_ndbprops *pndb_props, break; *pu_num_nodes = node_index; if (node_id == (node_index - 1)) { - status = dcd_get_object_def(pmgr_obj->hdcd_mgr, + status = dcd_get_object_def(pmgr_obj->dcd_mgr, &node_uuid, DSP_DCDNODETYPE, &gen_obj); if (status) break; @@ -258,7 +258,7 @@ int mgr_enum_processor_info(u32 processor_id, if (proc_detect != false) continue; - status2 = dcd_get_object_def(pmgr_obj->hdcd_mgr, + status2 = dcd_get_object_def(pmgr_obj->dcd_mgr, (struct dsp_uuid *)&temp_uuid, DSP_DCDPROCESSORTYPE, &gen_obj); if (!status2) { @@ -333,7 +333,7 @@ int mgr_get_dcd_handle(struct mgr_object *mgr_handle, *dcd_handle = (u32) NULL; if (pmgr_obj) { - *dcd_handle = (u32) pmgr_obj->hdcd_mgr; + *dcd_handle = (u32) pmgr_obj->dcd_mgr; status = 0; } DBC_ENSURE((!status && *dcd_handle != (u32) NULL) || diff --git a/drivers/staging/tidspbridge/rmgr/nldr.c b/drivers/staging/tidspbridge/rmgr/nldr.c index 688d9658ed60..7a15f636fea5 100644 --- a/drivers/staging/tidspbridge/rmgr/nldr.c +++ b/drivers/staging/tidspbridge/rmgr/nldr.c @@ -190,8 +190,8 @@ struct ovly_node { * Overlay loader object. */ struct nldr_object { - struct dev_object *hdev_obj; /* Device object */ - struct dcd_manager *hdcd_mgr; /* Proc/Node data manager */ + struct dev_object *dev_obj; /* Device object */ + struct dcd_manager *dcd_mgr; /* Proc/Node data manager */ struct dbll_tar_obj *dbll; /* The DBL loader */ struct dbll_library_obj *base_lib; /* Base image library */ struct rmm_target_obj *rmm; /* Remote memory manager for DSP */ @@ -206,8 +206,8 @@ struct nldr_object { u32 *seg_table; /* memtypes of dynamic memory segs * indexed by segid */ - u16 us_dsp_mau_size; /* Size of DSP MAU */ - u16 us_dsp_word_size; /* Size of DSP word */ + u16 dsp_mau_size; /* Size of DSP MAU */ + u16 dsp_word_size; /* Size of DSP word */ }; /* @@ -435,7 +435,7 @@ int nldr_create(struct nldr_object **nldr, /* Allocate dynamic loader object */ nldr_obj = kzalloc(sizeof(struct nldr_object), GFP_KERNEL); if (nldr_obj) { - nldr_obj->hdev_obj = hdev_obj; + nldr_obj->dev_obj = hdev_obj; /* warning, lazy status checking alert! */ dev_get_cod_mgr(hdev_obj, &cod_mgr); if (cod_mgr) { @@ -450,8 +450,8 @@ int nldr_create(struct nldr_object **nldr, } status = 0; /* end lazy status checking */ - nldr_obj->us_dsp_mau_size = pattrs->us_dsp_mau_size; - nldr_obj->us_dsp_word_size = pattrs->us_dsp_word_size; + nldr_obj->dsp_mau_size = pattrs->dsp_mau_size; + nldr_obj->dsp_word_size = pattrs->dsp_word_size; nldr_obj->ldr_fxns = ldr_fxns; if (!(nldr_obj->ldr_fxns.init_fxn())) status = -ENOMEM; @@ -461,7 +461,7 @@ int nldr_create(struct nldr_object **nldr, } /* Create the DCD Manager */ if (!status) - status = dcd_create_manager(NULL, &nldr_obj->hdcd_mgr); + status = dcd_create_manager(NULL, &nldr_obj->dcd_mgr); /* Get dynamic loading memory sections from base lib */ if (!status) { @@ -471,7 +471,7 @@ int nldr_create(struct nldr_object **nldr, &ul_len); if (!status) { psz_coff_buf = - kzalloc(ul_len * nldr_obj->us_dsp_mau_size, + kzalloc(ul_len * nldr_obj->dsp_mau_size, GFP_KERNEL); if (!psz_coff_buf) status = -ENOMEM; @@ -550,7 +550,7 @@ int nldr_create(struct nldr_object **nldr, DBC_ASSERT(!status); /* First count number of overlay nodes */ status = - dcd_get_objects(nldr_obj->hdcd_mgr, sz_zl_file, + dcd_get_objects(nldr_obj->dcd_mgr, sz_zl_file, add_ovly_node, (void *)nldr_obj); /* Now build table of overlay nodes */ if (!status && nldr_obj->ovly_nodes > 0) { @@ -560,7 +560,7 @@ int nldr_create(struct nldr_object **nldr, nldr_obj->ovly_nodes, GFP_KERNEL); /* Put overlay nodes in the table */ nldr_obj->ovly_nid = 0; - status = dcd_get_objects(nldr_obj->hdcd_mgr, sz_zl_file, + status = dcd_get_objects(nldr_obj->dcd_mgr, sz_zl_file, add_ovly_node, (void *)nldr_obj); } @@ -604,8 +604,8 @@ void nldr_delete(struct nldr_object *nldr_obj) kfree(nldr_obj->seg_table); - if (nldr_obj->hdcd_mgr) - dcd_destroy_manager(nldr_obj->hdcd_mgr); + if (nldr_obj->dcd_mgr) + dcd_destroy_manager(nldr_obj->dcd_mgr); /* Free overlay node information */ if (nldr_obj->ovly_table) { @@ -1005,7 +1005,7 @@ static int add_ovly_node(struct dsp_uuid *uuid_obj, goto func_end; status = - dcd_get_object_def(nldr_obj->hdcd_mgr, uuid_obj, obj_type, + dcd_get_object_def(nldr_obj->dcd_mgr, uuid_obj, obj_type, &obj_def); if (status) goto func_end; @@ -1262,14 +1262,14 @@ static int load_lib(struct nldr_nodeobject *nldr_node_obj, if (depth == 0) { status = dcd_get_library_name(nldr_node_obj->nldr_obj-> - hdcd_mgr, &uuid, psz_file_name, + dcd_mgr, &uuid, psz_file_name, &dw_buf_size, phase, nldr_node_obj->phase_split); } else { /* Dependent libraries are registered with a phase */ status = dcd_get_library_name(nldr_node_obj->nldr_obj-> - hdcd_mgr, &uuid, psz_file_name, + dcd_mgr, &uuid, psz_file_name, &dw_buf_size, NLDR_NOPHASE, NULL); } @@ -1309,7 +1309,7 @@ static int load_lib(struct nldr_nodeobject *nldr_node_obj, depth++; /* Get number of dependent libraries */ status = - dcd_get_num_dep_libs(nldr_node_obj->nldr_obj->hdcd_mgr, + dcd_get_num_dep_libs(nldr_node_obj->nldr_obj->dcd_mgr, &uuid, &nd_libs, &np_libs, phase); } DBC_ASSERT(nd_libs >= np_libs); @@ -1342,7 +1342,7 @@ static int load_lib(struct nldr_nodeobject *nldr_node_obj, /* Get the dependent library UUIDs */ status = dcd_get_dep_libs(nldr_node_obj-> - nldr_obj->hdcd_mgr, &uuid, + nldr_obj->dcd_mgr, &uuid, nd_libs, dep_lib_uui_ds, persistent_dep_libs, phase); @@ -1630,8 +1630,8 @@ static int remote_alloc(void **ref, u16 mem_sect, u32 size, rmm = nldr_obj->rmm; /* Convert size to DSP words */ word_size = - (size + nldr_obj->us_dsp_word_size - - 1) / nldr_obj->us_dsp_word_size; + (size + nldr_obj->dsp_word_size - + 1) / nldr_obj->dsp_word_size; /* Modify memory 'align' to account for DSP cache line size */ align = lcm(GEM_CACHE_LINE_SIZE, align); dev_dbg(bridge, "%s: memory align to 0x%x\n", __func__, align); @@ -1742,8 +1742,8 @@ static int remote_free(void **ref, u16 space, u32 dsp_address, /* Convert size to DSP words */ word_size = - (size + nldr_obj->us_dsp_word_size - - 1) / nldr_obj->us_dsp_word_size; + (size + nldr_obj->dsp_word_size - + 1) / nldr_obj->dsp_word_size; if (rmm_free(rmm, space, dsp_address, word_size, reserve)) status = 0; diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index 76166c18669e..2bfbd16c4343 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -124,10 +124,10 @@ * ======== node_mgr ======== */ struct node_mgr { - struct dev_object *hdev_obj; /* Device object */ + struct dev_object *dev_obj; /* Device object */ /* Function interface to Bridge driver */ struct bridge_drv_interface *intf_fxns; - struct dcd_manager *hdcd_mgr; /* Proc/Node data manager */ + struct dcd_manager *dcd_mgr; /* Proc/Node data manager */ struct disp_object *disp_obj; /* Node dispatcher */ struct list_head node_list; /* List of all allocated nodes */ u32 num_nodes; /* Number of nodes in node_list */ @@ -188,7 +188,7 @@ struct stream_chnl { */ struct node_object { struct list_head list_elem; - struct node_mgr *hnode_mgr; /* The manager of this node */ + struct node_mgr *node_mgr; /* The manager of this node */ struct proc_object *hprocessor; /* Back pointer to processor */ struct dsp_uuid node_uuid; /* Node's ID */ s32 prio; /* Node's current priority */ @@ -389,12 +389,12 @@ int node_allocate(struct proc_object *hprocessor, status = -ENOMEM; goto func_end; } - pnode->hnode_mgr = hnode_mgr; + pnode->node_mgr = hnode_mgr; /* This critical section protects get_node_props */ mutex_lock(&hnode_mgr->node_mgr_lock); /* Get dsp_ndbprops from node database */ - status = get_node_props(hnode_mgr->hdcd_mgr, pnode, node_uuid, + status = get_node_props(hnode_mgr->dcd_mgr, pnode, node_uuid, &(pnode->dcd_props)); if (status) goto func_cont; @@ -784,10 +784,10 @@ int node_change_priority(struct node_object *hnode, s32 prio) DBC_REQUIRE(refs > 0); - if (!hnode || !hnode->hnode_mgr) { + if (!hnode || !hnode->node_mgr) { status = -EFAULT; } else { - hnode_mgr = hnode->hnode_mgr; + hnode_mgr = hnode->node_mgr; node_type = node_get_type(hnode); if (node_type != NODE_TASK && node_type != NODE_DAISSOCKET) status = -EPERM; @@ -862,7 +862,7 @@ int node_connect(struct node_object *node1, u32 stream1, /* The two nodes must be on the same processor */ if (node1 != (struct node_object *)DSP_HGPPNODE && node2 != (struct node_object *)DSP_HGPPNODE && - node1->hnode_mgr != node2->hnode_mgr) + node1->node_mgr != node2->node_mgr) return -EPERM; /* Cannot connect a node to itself */ @@ -901,10 +901,10 @@ int node_connect(struct node_object *node1, u32 stream1, return -EPERM; /* illegal stream mode */ if (node1_type != NODE_GPP) { - hnode_mgr = node1->hnode_mgr; + hnode_mgr = node1->node_mgr; } else { DBC_ASSERT(node2 != (struct node_object *)DSP_HGPPNODE); - hnode_mgr = node2->hnode_mgr; + hnode_mgr = node2->node_mgr; } /* Enter critical section */ @@ -1158,7 +1158,7 @@ int node_create(struct node_object *hnode) /* create struct dsp_cbdata struct for PWR calls */ cb_data.cb_data = PWR_TIMEOUT; node_type = node_get_type(hnode); - hnode_mgr = hnode->hnode_mgr; + hnode_mgr = hnode->node_mgr; intf_fxns = hnode_mgr->intf_fxns; /* Get access to node dispatcher */ mutex_lock(&hnode_mgr->node_mgr_lock); @@ -1301,7 +1301,7 @@ int node_create_mgr(struct node_mgr **node_man, if (!node_mgr_obj) return -ENOMEM; - node_mgr_obj->hdev_obj = hdev_obj; + node_mgr_obj->dev_obj = hdev_obj; node_mgr_obj->ntfy_obj = kmalloc(sizeof(struct ntfy_object), GFP_KERNEL); @@ -1315,7 +1315,7 @@ int node_create_mgr(struct node_mgr **node_man, dev_get_dev_type(hdev_obj, &dev_type); - status = dcd_create_manager(sz_zl_file, &node_mgr_obj->hdcd_mgr); + status = dcd_create_manager(sz_zl_file, &node_mgr_obj->dcd_mgr); if (status) goto out_err; @@ -1364,8 +1364,8 @@ int node_create_mgr(struct node_mgr **node_man, nldr_attrs_obj.ovly = ovly; nldr_attrs_obj.write = mem_write; - nldr_attrs_obj.us_dsp_word_size = node_mgr_obj->udsp_word_size; - nldr_attrs_obj.us_dsp_mau_size = node_mgr_obj->udsp_mau_size; + nldr_attrs_obj.dsp_word_size = node_mgr_obj->udsp_word_size; + nldr_attrs_obj.dsp_mau_size = node_mgr_obj->udsp_mau_size; node_mgr_obj->loader_init = node_mgr_obj->nldr_fxns.init(); status = node_mgr_obj->nldr_fxns.create(&node_mgr_obj->nldr_obj, hdev_obj, @@ -1417,7 +1417,7 @@ int node_delete(struct node_res_object *noderes, } /* create struct dsp_cbdata struct for PWR call */ cb_data.cb_data = PWR_TIMEOUT; - hnode_mgr = pnode->hnode_mgr; + hnode_mgr = pnode->node_mgr; hprocessor = pnode->hprocessor; disp_obj = hnode_mgr->disp_obj; node_type = node_get_type(pnode); @@ -1676,7 +1676,7 @@ int node_get_attr(struct node_object *hnode, if (!hnode) return -EFAULT; - hnode_mgr = hnode->hnode_mgr; + hnode_mgr = hnode->node_mgr; /* Enter hnode_mgr critical section (since we're accessing * data that could be changed by node_change_priority() and * node_connect(). */ @@ -1779,7 +1779,7 @@ int node_get_message(struct node_object *hnode, status = -EPERM; goto func_end; } - hnode_mgr = hnode->hnode_mgr; + hnode_mgr = hnode->node_mgr; node_type = node_get_type(hnode); if (node_type != NODE_MESSAGE && node_type != NODE_TASK && node_type != NODE_DAISSOCKET) { @@ -1801,7 +1801,7 @@ int node_get_message(struct node_object *hnode, /* Translate DSP byte addr to GPP Va. */ tmp_buf = cmm_xlator_translate(hnode->xlator, (void *)(message->arg1 * - hnode->hnode_mgr-> + hnode->node_mgr-> udsp_word_size), CMM_DSPPA2PA); if (tmp_buf != NULL) { /* now convert this GPP Pa to Va */ @@ -1810,7 +1810,7 @@ int node_get_message(struct node_object *hnode, if (tmp_buf != NULL) { /* Adjust SM size in msg */ message->arg1 = (u32) tmp_buf; - message->arg2 *= hnode->hnode_mgr->udsp_word_size; + message->arg2 *= hnode->node_mgr->udsp_word_size; } else { status = -ESRCH; } @@ -1857,7 +1857,7 @@ int node_get_strm_mgr(struct node_object *hnode, if (!hnode) status = -EFAULT; else - *strm_man = hnode->hnode_mgr->strm_mgr_obj; + *strm_man = hnode->node_mgr->strm_mgr_obj; return status; } @@ -1942,7 +1942,7 @@ void node_on_exit(struct node_object *hnode, s32 node_status) NODE_SET_STATE(hnode, NODE_DONE); hnode->exit_status = node_status; if (hnode->loaded && hnode->phase_split) { - (void)hnode->hnode_mgr->nldr_fxns.unload(hnode-> + (void)hnode->node_mgr->nldr_fxns.unload(hnode-> nldr_node_obj, NLDR_EXECUTE); hnode->loaded = false; @@ -1988,7 +1988,7 @@ int node_pause(struct node_object *hnode) status = -ENOSYS; if (!status) { - hnode_mgr = hnode->hnode_mgr; + hnode_mgr = hnode->node_mgr; /* Enter critical section */ mutex_lock(&hnode_mgr->node_mgr_lock); @@ -2072,7 +2072,7 @@ int node_put_message(struct node_object *hnode, status = -EPERM; goto func_end; } - hnode_mgr = hnode->hnode_mgr; + hnode_mgr = hnode->node_mgr; node_type = node_get_type(hnode); if (node_type != NODE_MESSAGE && node_type != NODE_TASK && node_type != NODE_DAISSOCKET) @@ -2107,12 +2107,12 @@ int node_put_message(struct node_object *hnode, CMM_VA2DSPPA); if (tmp_buf != NULL) { /* got translation, convert to MAUs in msg */ - if (hnode->hnode_mgr->udsp_word_size != 0) { + if (hnode->node_mgr->udsp_word_size != 0) { new_msg.arg1 = (u32) tmp_buf / - hnode->hnode_mgr->udsp_word_size; + hnode->node_mgr->udsp_word_size; /* MAUs */ - new_msg.arg2 /= hnode->hnode_mgr-> + new_msg.arg2 /= hnode->node_mgr-> udsp_word_size; } else { pr_err("%s: udsp_word_size is zero!\n", @@ -2172,7 +2172,7 @@ int node_register_notify(struct node_object *hnode, u32 event_mask, notify_type); } else { /* Send Message part of event mask to msg_ctrl */ - intf_fxns = hnode->hnode_mgr->intf_fxns; + intf_fxns = hnode->node_mgr->intf_fxns; status = (*intf_fxns->msg_register_notify) (hnode->msg_queue_obj, event_mask & DSP_NODEMESSAGEREADY, notify_type, @@ -2229,7 +2229,7 @@ int node_run(struct node_object *hnode) if (status) goto func_end; - hnode_mgr = hnode->hnode_mgr; + hnode_mgr = hnode->node_mgr; if (!hnode_mgr) { status = -EFAULT; goto func_end; @@ -2329,7 +2329,7 @@ int node_terminate(struct node_object *hnode, int *pstatus) DBC_REQUIRE(refs > 0); DBC_REQUIRE(pstatus != NULL); - if (!hnode || !hnode->hnode_mgr) { + if (!hnode || !hnode->node_mgr) { status = -EFAULT; goto func_end; } @@ -2340,7 +2340,7 @@ int node_terminate(struct node_object *hnode, int *pstatus) status = proc_get_processor_id(pnode->hprocessor, &proc_id); if (!status) { - hnode_mgr = hnode->hnode_mgr; + hnode_mgr = hnode->node_mgr; node_type = node_get_type(hnode); if (node_type != NODE_TASK && node_type != NODE_DAISSOCKET) status = -EPERM; @@ -2416,7 +2416,7 @@ int node_terminate(struct node_object *hnode, int *pstatus) * Here it goes the part of the simulation of * the DSP exception. */ - dev_get_deh_mgr(hnode_mgr->hdev_obj, &hdeh_mgr); + dev_get_deh_mgr(hnode_mgr->dev_obj, &hdeh_mgr); if (!hdeh_mgr) goto func_cont; @@ -2465,7 +2465,7 @@ static void delete_node(struct node_object *hnode, int status; if (!hnode) goto func_end; - hnode_mgr = hnode->hnode_mgr; + hnode_mgr = hnode->node_mgr; if (!hnode_mgr) goto func_end; @@ -2567,7 +2567,7 @@ static void delete_node(struct node_object *hnode, kfree(hnode->xlator); kfree(hnode->nldr_node_obj); hnode->nldr_node_obj = NULL; - hnode->hnode_mgr = NULL; + hnode->node_mgr = NULL; kfree(hnode); hnode = NULL; func_end: @@ -2585,8 +2585,8 @@ static void delete_node_mgr(struct node_mgr *hnode_mgr) if (hnode_mgr) { /* Free resources */ - if (hnode_mgr->hdcd_mgr) - dcd_destroy_manager(hnode_mgr->hdcd_mgr); + if (hnode_mgr->dcd_mgr) + dcd_destroy_manager(hnode_mgr->dcd_mgr); /* Remove any elements remaining in lists */ list_for_each_entry_safe(hnode, tmp, &hnode_mgr->node_list, @@ -2686,7 +2686,7 @@ static void fill_stream_def(struct node_object *hnode, struct node_strmdef *pstrm_def, struct dsp_strmattr *pattrs) { - struct node_mgr *hnode_mgr = hnode->hnode_mgr; + struct node_mgr *hnode_mgr = hnode->node_mgr; if (pattrs != NULL) { pstrm_def->num_bufs = pattrs->num_bufs; @@ -2746,7 +2746,7 @@ static int get_fxn_address(struct node_object *hnode, u32 * fxn_addr, u32 phase) { char *pstr_fxn_name = NULL; - struct node_mgr *hnode_mgr = hnode->hnode_mgr; + struct node_mgr *hnode_mgr = hnode->node_mgr; int status = 0; DBC_REQUIRE(node_get_type(hnode) == NODE_TASK || node_get_type(hnode) == NODE_DAISSOCKET || @@ -2979,7 +2979,7 @@ int node_get_uuid_props(void *hprocessor, dcd_node_props.pstr_delete_phase_fxn = NULL; dcd_node_props.pstr_i_alg_name = NULL; - status = dcd_get_object_def(hnode_mgr->hdcd_mgr, + status = dcd_get_object_def(hnode_mgr->dcd_mgr, (struct dsp_uuid *)node_uuid, DSP_DCDNODETYPE, (struct dcd_genericobj *)&dcd_node_props); @@ -3007,7 +3007,7 @@ func_end: static int get_rms_fxns(struct node_mgr *hnode_mgr) { s32 i; - struct dev_object *dev_obj = hnode_mgr->hdev_obj; + struct dev_object *dev_obj = hnode_mgr->dev_obj; int status = 0; static char *psz_fxns[NUMRMSFXNS] = { @@ -3065,14 +3065,14 @@ static u32 ovly(void *priv_ref, u32 dsp_run_addr, u32 dsp_load_addr, DBC_REQUIRE(hnode); - hnode_mgr = hnode->hnode_mgr; + hnode_mgr = hnode->node_mgr; ul_size = ul_num_bytes / hnode_mgr->udsp_word_size; ul_timeout = hnode->utimeout; /* Call new MemCopy function */ intf_fxns = hnode_mgr->intf_fxns; - status = dev_get_bridge_context(hnode_mgr->hdev_obj, &hbridge_context); + status = dev_get_bridge_context(hnode_mgr->dev_obj, &hbridge_context); if (!status) { status = (*intf_fxns->brd_mem_copy) (hbridge_context, @@ -3109,14 +3109,14 @@ static u32 mem_write(void *priv_ref, u32 dsp_add, void *pbuf, DBC_REQUIRE(hnode); DBC_REQUIRE(mem_space & DBLL_CODE || mem_space & DBLL_DATA); - hnode_mgr = hnode->hnode_mgr; + hnode_mgr = hnode->node_mgr; ul_timeout = hnode->utimeout; mem_sect_type = (mem_space & DBLL_CODE) ? RMS_CODE : RMS_DATA; /* Call new MemWrite function */ intf_fxns = hnode_mgr->intf_fxns; - status = dev_get_bridge_context(hnode_mgr->hdev_obj, &hbridge_context); + status = dev_get_bridge_context(hnode_mgr->dev_obj, &hbridge_context); status = (*intf_fxns->brd_mem_write) (hbridge_context, pbuf, dsp_add, ul_num_bytes, mem_sect_type); diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c index 6840d29cfc95..fddbcea32f53 100644 --- a/drivers/staging/tidspbridge/rmgr/proc.c +++ b/drivers/staging/tidspbridge/rmgr/proc.c @@ -80,24 +80,24 @@ extern struct device *bridge; /* The proc_object structure. */ struct proc_object { struct list_head link; /* Link to next proc_object */ - struct dev_object *hdev_obj; /* Device this PROC represents */ + struct dev_object *dev_obj; /* Device this PROC represents */ u32 process; /* Process owning this Processor */ - struct mgr_object *hmgr_obj; /* Manager Object Handle */ + struct mgr_object *mgr_obj; /* Manager Object Handle */ u32 attach_count; /* Processor attach count */ u32 processor_id; /* Processor number */ u32 utimeout; /* Time out count */ enum dsp_procstate proc_state; /* Processor state */ - u32 ul_unit; /* DDSP unit number */ + u32 unit; /* DDSP unit number */ bool is_already_attached; /* * True if the Device below has * GPP Client attached */ struct ntfy_object *ntfy_obj; /* Manages notifications */ /* Bridge Context Handle */ - struct bridge_dev_context *hbridge_context; + struct bridge_dev_context *bridge_context; /* Function interface to Bridge driver */ struct bridge_drv_interface *intf_fxns; - char *psz_last_coff; + char *last_coff; struct list_head proc_list; }; @@ -315,8 +315,8 @@ proc_attach(u32 processor_id, status = -ENOMEM; goto func_end; } - p_proc_object->hdev_obj = hdev_obj; - p_proc_object->hmgr_obj = hmgr_obj; + p_proc_object->dev_obj = hdev_obj; + p_proc_object->mgr_obj = hmgr_obj; p_proc_object->processor_id = dev_type; /* Store TGID instead of process handle */ p_proc_object->process = current->tgid; @@ -331,7 +331,7 @@ proc_attach(u32 processor_id, status = dev_get_intf_fxns(hdev_obj, &p_proc_object->intf_fxns); if (!status) { status = dev_get_bridge_context(hdev_obj, - &p_proc_object->hbridge_context); + &p_proc_object->bridge_context); if (status) kfree(p_proc_object); } else @@ -356,7 +356,7 @@ proc_attach(u32 processor_id, * Return handle to this Processor Object: * Find out if the Device is already attached to a * Processor. If so, return AlreadyAttached status */ - status = dev_insert_proc_object(p_proc_object->hdev_obj, + status = dev_insert_proc_object(p_proc_object->dev_obj, (u32) p_proc_object, &p_proc_object-> is_already_attached); @@ -463,12 +463,12 @@ int proc_auto_start(struct cfg_devnode *dev_node_obj, status = -ENOMEM; goto func_end; } - p_proc_object->hdev_obj = hdev_obj; - p_proc_object->hmgr_obj = hmgr_obj; + p_proc_object->dev_obj = hdev_obj; + p_proc_object->mgr_obj = hmgr_obj; status = dev_get_intf_fxns(hdev_obj, &p_proc_object->intf_fxns); if (!status) status = dev_get_bridge_context(hdev_obj, - &p_proc_object->hbridge_context); + &p_proc_object->bridge_context); if (status) goto func_cont; @@ -491,8 +491,8 @@ int proc_auto_start(struct cfg_devnode *dev_node_obj, if (!status) status = proc_start(p_proc_object); } - kfree(p_proc_object->psz_last_coff); - p_proc_object->psz_last_coff = NULL; + kfree(p_proc_object->last_coff); + p_proc_object->last_coff = NULL; func_cont: kfree(p_proc_object); func_end: @@ -541,7 +541,7 @@ int proc_ctrl(void *hprocessor, u32 dw_cmd, struct dsp_cbdata * arg) status = pwr_wake_dsp(timeout); } else if (!((*p_proc_object->intf_fxns->dev_cntrl) - (p_proc_object->hbridge_context, dw_cmd, + (p_proc_object->bridge_context, dw_cmd, arg))) { status = 0; } else { @@ -578,10 +578,10 @@ int proc_detach(struct process_context *pr_ctxt) kfree(p_proc_object->ntfy_obj); } - kfree(p_proc_object->psz_last_coff); - p_proc_object->psz_last_coff = NULL; + kfree(p_proc_object->last_coff); + p_proc_object->last_coff = NULL; /* Remove the Proc from the DEV List */ - (void)dev_remove_proc_object(p_proc_object->hdev_obj, + (void)dev_remove_proc_object(p_proc_object->dev_obj, (u32) p_proc_object); /* Free the Processor Object */ kfree(p_proc_object); @@ -613,7 +613,7 @@ int proc_enum_nodes(void *hprocessor, void **node_tab, DBC_REQUIRE(pu_allocated != NULL); if (p_proc_object) { - if (!(dev_get_node_manager(p_proc_object->hdev_obj, + if (!(dev_get_node_manager(p_proc_object->dev_obj, &hnode_mgr))) { if (hnode_mgr) { status = node_enum_nodes(hnode_mgr, node_tab, @@ -890,7 +890,7 @@ int proc_get_resource_info(void *hprocessor, u32 resource_type, case DSP_RESOURCE_DYNSARAM: case DSP_RESOURCE_DYNEXTERNAL: case DSP_RESOURCE_DYNSRAM: - status = dev_get_node_manager(p_proc_object->hdev_obj, + status = dev_get_node_manager(p_proc_object->dev_obj, &hnode_mgr); if (!hnode_mgr) { status = -EFAULT; @@ -913,7 +913,7 @@ int proc_get_resource_info(void *hprocessor, u32 resource_type, } break; case DSP_RESOURCE_PROCLOAD: - status = dev_get_io_mgr(p_proc_object->hdev_obj, &hio_mgr); + status = dev_get_io_mgr(p_proc_object->dev_obj, &hio_mgr); if (hio_mgr) status = p_proc_object->intf_fxns-> @@ -963,7 +963,7 @@ int proc_get_dev_object(void *hprocessor, DBC_REQUIRE(device_obj != NULL); if (p_proc_object) { - *device_obj = p_proc_object->hdev_obj; + *device_obj = p_proc_object->dev_obj; status = 0; } else { *device_obj = NULL; @@ -996,7 +996,7 @@ int proc_get_state(void *hprocessor, if (p_proc_object) { /* First, retrieve BRD state information */ status = (*p_proc_object->intf_fxns->brd_status) - (p_proc_object->hbridge_context, &brd_status); + (p_proc_object->bridge_context, &brd_status); if (!status) { switch (brd_status) { case BRD_STOPPED: @@ -1115,7 +1115,7 @@ int proc_load(void *hprocessor, const s32 argc_index, status = -EFAULT; goto func_end; } - dev_get_cod_mgr(p_proc_object->hdev_obj, &cod_mgr); + dev_get_cod_mgr(p_proc_object->dev_obj, &cod_mgr); if (!cod_mgr) { status = -EPERM; goto func_end; @@ -1147,7 +1147,7 @@ int proc_load(void *hprocessor, const s32 argc_index, prepend_envp(new_envp, (char **)user_envp, envp_elems, cnew_envp, sz_proc_id); /* Get the DCD Handle */ - status = mgr_get_dcd_handle(p_proc_object->hmgr_obj, + status = mgr_get_dcd_handle(p_proc_object->mgr_obj, (u32 *) &hdcd_handle); if (!status) { /* Before proceeding with new load, @@ -1156,16 +1156,16 @@ int proc_load(void *hprocessor, const s32 argc_index, * If yes, unregister nodes in previously * registered COFF. If any error occurred, * set previously registered COFF to NULL. */ - if (p_proc_object->psz_last_coff != NULL) { + if (p_proc_object->last_coff != NULL) { status = dcd_auto_unregister(hdcd_handle, p_proc_object-> - psz_last_coff); + last_coff); /* Regardless of auto unregister status, * free previously allocated * memory. */ - kfree(p_proc_object->psz_last_coff); - p_proc_object->psz_last_coff = NULL; + kfree(p_proc_object->last_coff); + p_proc_object->last_coff = NULL; } } /* On success, do cod_open_base() */ @@ -1178,7 +1178,7 @@ int proc_load(void *hprocessor, const s32 argc_index, if (!status) { /* Auto-register data base */ /* Get the DCD Handle */ - status = mgr_get_dcd_handle(p_proc_object->hmgr_obj, + status = mgr_get_dcd_handle(p_proc_object->mgr_obj, (u32 *) &hdcd_handle); if (!status) { /* Auto register nodes in specified COFF @@ -1195,15 +1195,15 @@ int proc_load(void *hprocessor, const s32 argc_index, if (status) { status = -EPERM; } else { - DBC_ASSERT(p_proc_object->psz_last_coff == + DBC_ASSERT(p_proc_object->last_coff == NULL); /* Allocate memory for pszLastCoff */ - p_proc_object->psz_last_coff = + p_proc_object->last_coff = kzalloc((strlen(user_args[0]) + 1), GFP_KERNEL); /* If memory allocated, save COFF file name */ - if (p_proc_object->psz_last_coff) { - strncpy(p_proc_object->psz_last_coff, + if (p_proc_object->last_coff) { + strncpy(p_proc_object->last_coff, (char *)user_args[0], (strlen((char *)user_args[0]) + 1)); @@ -1215,17 +1215,17 @@ int proc_load(void *hprocessor, const s32 argc_index, if (!status) { /* Create the message manager. This must be done * before calling the IOOnLoaded function. */ - dev_get_msg_mgr(p_proc_object->hdev_obj, &hmsg_mgr); + dev_get_msg_mgr(p_proc_object->dev_obj, &hmsg_mgr); if (!hmsg_mgr) { - status = msg_create(&hmsg_mgr, p_proc_object->hdev_obj, + status = msg_create(&hmsg_mgr, p_proc_object->dev_obj, (msg_onexit) node_on_exit); DBC_ASSERT(!status); - dev_set_msg_mgr(p_proc_object->hdev_obj, hmsg_mgr); + dev_set_msg_mgr(p_proc_object->dev_obj, hmsg_mgr); } } if (!status) { /* Set the Device object's message manager */ - status = dev_get_io_mgr(p_proc_object->hdev_obj, &hio_mgr); + status = dev_get_io_mgr(p_proc_object->dev_obj, &hio_mgr); if (hio_mgr) status = (*p_proc_object->intf_fxns->io_on_loaded) (hio_mgr); @@ -1242,7 +1242,7 @@ int proc_load(void *hprocessor, const s32 argc_index, #endif status = cod_load_base(cod_mgr, argc_index, (char **)user_args, dev_brd_write_fxn, - p_proc_object->hdev_obj, NULL); + p_proc_object->dev_obj, NULL); if (status) { if (status == -EBADF) { dev_dbg(bridge, "%s: Failure to Load the EXE\n", @@ -1263,7 +1263,7 @@ int proc_load(void *hprocessor, const s32 argc_index, if (!status) { /* Update the Processor status to loaded */ status = (*p_proc_object->intf_fxns->brd_set_state) - (p_proc_object->hbridge_context, BRD_LOADED); + (p_proc_object->bridge_context, BRD_LOADED); if (!status) { p_proc_object->proc_state = PROC_LOADED; if (p_proc_object->ntfy_obj) @@ -1283,7 +1283,7 @@ int proc_load(void *hprocessor, const s32 argc_index, /* Reset DMM structs and add an initial free chunk */ if (!status) { status = - dev_get_dmm_mgr(p_proc_object->hdev_obj, + dev_get_dmm_mgr(p_proc_object->dev_obj, &dmm_mgr); if (dmm_mgr) { /* Set dw_ext_end to DMM START u8 @@ -1305,7 +1305,7 @@ int proc_load(void *hprocessor, const s32 argc_index, user_args[0] = pargv0; if (!status) { if (!((*p_proc_object->intf_fxns->brd_status) - (p_proc_object->hbridge_context, &brd_state))) { + (p_proc_object->bridge_context, &brd_state))) { pr_info("%s: Processor Loaded %s\n", __func__, pargv0); kfree(drv_datap->base_img); drv_datap->base_img = kmalloc(strlen(pargv0) + 1, @@ -1398,7 +1398,7 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size, status = -ENOMEM; else status = (*p_proc_object->intf_fxns->brd_mem_map) - (p_proc_object->hbridge_context, pa_align, va_align, + (p_proc_object->bridge_context, pa_align, va_align, size_align, ul_map_attr, map_obj->pages); } if (!status) { @@ -1475,7 +1475,7 @@ int proc_register_notify(void *hprocessor, u32 event_mask, */ if ((event_mask == 0) && status) { status = - dev_get_deh_mgr(p_proc_object->hdev_obj, + dev_get_deh_mgr(p_proc_object->dev_obj, &hdeh_mgr); status = bridge_deh_register_notify(hdeh_mgr, @@ -1484,7 +1484,7 @@ int proc_register_notify(void *hprocessor, u32 event_mask, hnotification); } } else { - status = dev_get_deh_mgr(p_proc_object->hdev_obj, + status = dev_get_deh_mgr(p_proc_object->dev_obj, &hdeh_mgr); status = bridge_deh_register_notify(hdeh_mgr, @@ -1570,7 +1570,7 @@ int proc_start(void *hprocessor) status = -EBADR; goto func_end; } - status = dev_get_cod_mgr(p_proc_object->hdev_obj, &cod_mgr); + status = dev_get_cod_mgr(p_proc_object->dev_obj, &cod_mgr); if (!cod_mgr) { status = -EFAULT; goto func_cont; @@ -1581,12 +1581,12 @@ int proc_start(void *hprocessor) goto func_cont; status = (*p_proc_object->intf_fxns->brd_start) - (p_proc_object->hbridge_context, dw_dsp_addr); + (p_proc_object->bridge_context, dw_dsp_addr); if (status) goto func_cont; /* Call dev_create2 */ - status = dev_create2(p_proc_object->hdev_obj); + status = dev_create2(p_proc_object->dev_obj); if (!status) { p_proc_object->proc_state = PROC_RUNNING; /* Deep sleep switces off the peripheral clocks. @@ -1601,13 +1601,13 @@ int proc_start(void *hprocessor) /* Failed to Create Node Manager and DISP Object * Stop the Processor from running. Put it in STOPPED State */ (void)(*p_proc_object->intf_fxns-> - brd_stop) (p_proc_object->hbridge_context); + brd_stop) (p_proc_object->bridge_context); p_proc_object->proc_state = PROC_STOPPED; } func_cont: if (!status) { if (!((*p_proc_object->intf_fxns->brd_status) - (p_proc_object->hbridge_context, &brd_state))) { + (p_proc_object->bridge_context, &brd_state))) { pr_info("%s: dsp in running state\n", __func__); DBC_ASSERT(brd_state != BRD_HIBERNATION); } @@ -1645,7 +1645,7 @@ int proc_stop(void *hprocessor) goto func_end; } /* check if there are any running nodes */ - status = dev_get_node_manager(p_proc_object->hdev_obj, &hnode_mgr); + status = dev_get_node_manager(p_proc_object->dev_obj, &hnode_mgr); if (!status && hnode_mgr) { status = node_enum_nodes(hnode_mgr, &hnode, node_tab_size, &num_nodes, &nodes_allocated); @@ -1659,21 +1659,21 @@ int proc_stop(void *hprocessor) /* It is OK to stop a device that does n't have nodes OR not started */ status = (*p_proc_object->intf_fxns-> - brd_stop) (p_proc_object->hbridge_context); + brd_stop) (p_proc_object->bridge_context); if (!status) { dev_dbg(bridge, "%s: processor in standby mode\n", __func__); p_proc_object->proc_state = PROC_STOPPED; /* Destory the Node Manager, msg_ctrl Manager */ - if (!(dev_destroy2(p_proc_object->hdev_obj))) { + if (!(dev_destroy2(p_proc_object->dev_obj))) { /* Destroy the msg_ctrl by calling msg_delete */ - dev_get_msg_mgr(p_proc_object->hdev_obj, &hmsg_mgr); + dev_get_msg_mgr(p_proc_object->dev_obj, &hmsg_mgr); if (hmsg_mgr) { msg_delete(hmsg_mgr); - dev_set_msg_mgr(p_proc_object->hdev_obj, NULL); + dev_set_msg_mgr(p_proc_object->dev_obj, NULL); } if (!((*p_proc_object-> intf_fxns->brd_status) (p_proc_object-> - hbridge_context, + bridge_context, &brd_state))) DBC_ASSERT(brd_state == BRD_STOPPED); } @@ -1721,7 +1721,7 @@ int proc_un_map(void *hprocessor, void *map_addr, /* Remove mapping from the page tables. */ if (!status) { status = (*p_proc_object->intf_fxns->brd_mem_un_map) - (p_proc_object->hbridge_context, va_align, size_align); + (p_proc_object->bridge_context, va_align, size_align); } mutex_unlock(&proc_lock); @@ -1819,20 +1819,20 @@ static int proc_monitor(struct proc_object *proc_obj) /* This is needed only when Device is loaded when it is * already 'ACTIVE' */ /* Destory the Node Manager, msg_ctrl Manager */ - if (!dev_destroy2(proc_obj->hdev_obj)) { + if (!dev_destroy2(proc_obj->dev_obj)) { /* Destroy the msg_ctrl by calling msg_delete */ - dev_get_msg_mgr(proc_obj->hdev_obj, &hmsg_mgr); + dev_get_msg_mgr(proc_obj->dev_obj, &hmsg_mgr); if (hmsg_mgr) { msg_delete(hmsg_mgr); - dev_set_msg_mgr(proc_obj->hdev_obj, NULL); + dev_set_msg_mgr(proc_obj->dev_obj, NULL); } } /* Place the Board in the Monitor State */ if (!((*proc_obj->intf_fxns->brd_monitor) - (proc_obj->hbridge_context))) { + (proc_obj->bridge_context))) { status = 0; if (!((*proc_obj->intf_fxns->brd_status) - (proc_obj->hbridge_context, &brd_state))) + (proc_obj->bridge_context, &brd_state))) DBC_ASSERT(brd_state == BRD_IDLE); } @@ -1929,7 +1929,7 @@ int proc_notify_all_clients(void *proc, u32 events) goto func_end; } - dev_notify_clients(p_proc_object->hdev_obj, events); + dev_notify_clients(p_proc_object->dev_obj, events); func_end: return status; diff --git a/drivers/staging/tidspbridge/rmgr/rmm.c b/drivers/staging/tidspbridge/rmgr/rmm.c index 5d5feee1fa3d..f3dc0ddbfacc 100644 --- a/drivers/staging/tidspbridge/rmgr/rmm.c +++ b/drivers/staging/tidspbridge/rmgr/rmm.c @@ -369,13 +369,13 @@ bool rmm_stat(struct rmm_target_obj *target, enum dsp_memtype segid, } /* ul_size */ - mem_stat_buf->ul_size = target->seg_tab[segid].length; + mem_stat_buf->size = target->seg_tab[segid].length; /* num_free_blocks */ mem_stat_buf->num_free_blocks = free_blocks; - /* ul_total_free_size */ - mem_stat_buf->ul_total_free_size = total_free_size; + /* total_free_size */ + mem_stat_buf->total_free_size = total_free_size; /* len_max_free_block */ mem_stat_buf->len_max_free_block = max_free_size; diff --git a/drivers/staging/tidspbridge/rmgr/strm.c b/drivers/staging/tidspbridge/rmgr/strm.c index a8e3fe5c4a24..9498b6747e72 100644 --- a/drivers/staging/tidspbridge/rmgr/strm.c +++ b/drivers/staging/tidspbridge/rmgr/strm.c @@ -55,7 +55,7 @@ */ struct strm_mgr { struct dev_object *dev_obj; /* Device for this processor */ - struct chnl_mgr *hchnl_mgr; /* Channel manager */ + struct chnl_mgr *chnl_mgr; /* Channel manager */ /* Function interface to Bridge driver */ struct bridge_drv_interface *intf_fxns; }; @@ -213,7 +213,7 @@ int strm_create(struct strm_mgr **strm_man, /* Get Channel manager and Bridge function interface */ if (!status) { - status = dev_get_chnl_mgr(dev_obj, &(strm_mgr_obj->hchnl_mgr)); + status = dev_get_chnl_mgr(dev_obj, &(strm_mgr_obj->chnl_mgr)); if (!status) { (void)dev_get_intf_fxns(dev_obj, &(strm_mgr_obj->intf_fxns)); @@ -532,7 +532,7 @@ int strm_open(struct node_object *hnode, u32 dir, u32 index, if (status) goto func_cont; - if ((pattr->virt_base == NULL) || !(pattr->ul_virt_size > 0)) + if ((pattr->virt_base == NULL) || !(pattr->virt_size > 0)) goto func_cont; /* No System DMA */ @@ -547,7 +547,7 @@ int strm_open(struct node_object *hnode, u32 dir, u32 index, /* Set translators Virt Addr attributes */ status = cmm_xlator_info(strm_obj->xlator, (u8 **) &pattr->virt_base, - pattr->ul_virt_size, + pattr->virt_size, strm_obj->segment_id, true); } } @@ -558,7 +558,7 @@ func_cont: CHNL_MODETODSP : CHNL_MODEFROMDSP; intf_fxns = strm_mgr_obj->intf_fxns; status = (*intf_fxns->chnl_open) (&(strm_obj->chnl_obj), - strm_mgr_obj->hchnl_mgr, + strm_mgr_obj->chnl_mgr, chnl_mode, ul_chnl_id, &chnl_attr_obj); if (status) { @@ -572,7 +572,7 @@ func_cont: * We got a status that's not return-able. * Assert that we got something we were * expecting (-EFAULT isn't acceptable, - * strm_mgr_obj->hchnl_mgr better be valid or we + * strm_mgr_obj->chnl_mgr better be valid or we * assert here), and then return -EPERM. */ DBC_ASSERT(status == -ENOSR || -- cgit v1.2.3 From a534f17bd50834188b24e0a573c22c3285e7b1bb Mon Sep 17 00:00:00 2001 From: Rene Sapiens Date: Tue, 18 Jan 2011 03:19:11 +0000 Subject: staging: tidspbridge: set9 remove hungarian from structs hungarian notation will be removed from the elements inside structures, the next varibles will be renamed: Original: Replacement: hprocessor processor udma_priority dma_priority udsp_data_mau_size dsp_data_mau_size udsp_heap_addr dsp_heap_addr udsp_heap_res_addr dsp_heap_res_addr udsp_heap_virt_addr dsp_heap_virt_addr udsp_mau_size dsp_mau_size udsp_word_size dsp_word_size ugpp_heap_addr gpp_heap_addr ugpp_heap_virt_addr gpp_heap_virt_addr us_data2 data2 us_data3 data3 uc_data4 data4 uc_data5 data5 uc_data6 data6 us_load_type load_type usm_length sm_length utimeout timeout uwc_deadline wc_deadline uwc_execution_time wc_execution_time uwc_period wc_period Signed-off-by: Rene Sapiens Signed-off-by: Armando Uribe Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/gen/uuidutil.c | 20 +-- .../tidspbridge/include/dspbridge/dbdcddef.h | 2 +- .../staging/tidspbridge/include/dspbridge/dbdefs.h | 30 ++--- .../staging/tidspbridge/include/dspbridge/drv.h | 2 +- .../tidspbridge/include/dspbridge/dspapi-ioctl.h | 44 +++---- .../tidspbridge/include/dspbridge/dspdefs.h | 2 +- drivers/staging/tidspbridge/include/dspbridge/io.h | 2 +- .../tidspbridge/include/dspbridge/nodepriv.h | 8 +- drivers/staging/tidspbridge/pmgr/dev.c | 4 +- drivers/staging/tidspbridge/pmgr/dspapi.c | 44 +++---- drivers/staging/tidspbridge/pmgr/io.c | 2 +- drivers/staging/tidspbridge/rmgr/dbdcd.c | 12 +- drivers/staging/tidspbridge/rmgr/disp.c | 8 +- drivers/staging/tidspbridge/rmgr/drv.c | 4 +- drivers/staging/tidspbridge/rmgr/nldr.c | 6 +- drivers/staging/tidspbridge/rmgr/node.c | 138 ++++++++++----------- drivers/staging/tidspbridge/rmgr/proc.c | 16 +-- drivers/staging/tidspbridge/rmgr/strm.c | 22 ++-- 18 files changed, 183 insertions(+), 183 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/gen/uuidutil.c b/drivers/staging/tidspbridge/gen/uuidutil.c index 2aa9b64c0f88..ff6ebadf98f4 100644 --- a/drivers/staging/tidspbridge/gen/uuidutil.c +++ b/drivers/staging/tidspbridge/gen/uuidutil.c @@ -45,11 +45,11 @@ void uuid_uuid_to_string(struct dsp_uuid *uuid_obj, char *sz_uuid, i = snprintf(sz_uuid, size, "%.8X_%.4X_%.4X_%.2X%.2X_%.2X%.2X%.2X%.2X%.2X%.2X", - uuid_obj->data1, uuid_obj->us_data2, uuid_obj->us_data3, - uuid_obj->uc_data4, uuid_obj->uc_data5, - uuid_obj->uc_data6[0], uuid_obj->uc_data6[1], - uuid_obj->uc_data6[2], uuid_obj->uc_data6[3], - uuid_obj->uc_data6[4], uuid_obj->uc_data6[5]); + uuid_obj->data1, uuid_obj->data2, uuid_obj->data3, + uuid_obj->data4, uuid_obj->data5, + uuid_obj->data6[0], uuid_obj->data6[1], + uuid_obj->data6[2], uuid_obj->data6[3], + uuid_obj->data6[4], uuid_obj->data6[5]); DBC_ENSURE(i != -1); } @@ -85,29 +85,29 @@ void uuid_uuid_from_string(char *sz_uuid, struct dsp_uuid *uuid_obj) /* Step over underscore */ sz_uuid++; - uuid_obj->us_data2 = (u16) uuid_hex_to_bin(sz_uuid, 4); + uuid_obj->data2 = (u16) uuid_hex_to_bin(sz_uuid, 4); sz_uuid += 4; /* Step over underscore */ sz_uuid++; - uuid_obj->us_data3 = (u16) uuid_hex_to_bin(sz_uuid, 4); + uuid_obj->data3 = (u16) uuid_hex_to_bin(sz_uuid, 4); sz_uuid += 4; /* Step over underscore */ sz_uuid++; - uuid_obj->uc_data4 = (u8) uuid_hex_to_bin(sz_uuid, 2); + uuid_obj->data4 = (u8) uuid_hex_to_bin(sz_uuid, 2); sz_uuid += 2; - uuid_obj->uc_data5 = (u8) uuid_hex_to_bin(sz_uuid, 2); + uuid_obj->data5 = (u8) uuid_hex_to_bin(sz_uuid, 2); sz_uuid += 2; /* Step over underscore */ sz_uuid++; for (j = 0; j < 6; j++) { - uuid_obj->uc_data6[j] = (u8) uuid_hex_to_bin(sz_uuid, 2); + uuid_obj->data6[j] = (u8) uuid_hex_to_bin(sz_uuid, 2); sz_uuid += 2; } } diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h b/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h index fc2a736ec971..f97266c33e9b 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h @@ -54,7 +54,7 @@ struct dcd_nodeprops { char *pstr_i_alg_name; /* Dynamic load properties */ - u16 us_load_type; /* Static, dynamic, overlay */ + u16 load_type; /* Static, dynamic, overlay */ u32 data_mem_seg_mask; /* Data memory requirements */ u32 code_mem_seg_mask; /* Code memory requirements */ }; diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h index 82e2439eb3f1..592c16d6a97f 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h @@ -100,11 +100,11 @@ static inline bool is_valid_proc_event(u32 x) /* The Node UUID structure */ struct dsp_uuid { u32 data1; - u16 us_data2; - u16 us_data3; - u8 uc_data4; - u8 uc_data5; - u8 uc_data6[6]; + u16 data2; + u16 data3; + u8 data4; + u8 data5; + u8 data6[6]; }; /* DCD types */ @@ -229,11 +229,11 @@ struct dsp_strmattr { u32 buf_size; /* Buffer size (DSP words) */ u32 num_bufs; /* Number of buffers */ u32 buf_alignment; /* Buffer alignment */ - u32 utimeout; /* Timeout for blocking STRM calls */ + u32 timeout; /* Timeout for blocking STRM calls */ enum dsp_strmmode strm_mode; /* mode of stream when opened */ /* DMA chnl id if dsp_strmmode is LDMA or RDMA */ u32 udma_chnl_id; - u32 udma_priority; /* DMA channel priority 0=lowest, >0=high */ + u32 dma_priority; /* DMA channel priority 0=lowest, >0=high */ }; /* The dsp_cbdata structure */ @@ -255,9 +255,9 @@ struct dsp_resourcereqmts { u32 static_data_size; u32 global_data_size; u32 program_mem_size; - u32 uwc_execution_time; - u32 uwc_period; - u32 uwc_deadline; + u32 wc_execution_time; + u32 wc_period; + u32 wc_deadline; u32 avg_exection_time; u32 minimum_period; }; @@ -294,7 +294,7 @@ struct dsp_ndbprops { u32 message_depth; u32 num_input_streams; u32 num_output_streams; - u32 utimeout; + u32 timeout; u32 count_profiles; /* Number of supported profiles */ /* Array of profiles */ struct dsp_nodeprofs node_profiles[MAX_PROFILES]; @@ -306,7 +306,7 @@ struct dsp_ndbprops { struct dsp_nodeattrin { u32 cb_struct; s32 prio; - u32 utimeout; + u32 timeout; u32 profile_id; /* Reserved, for Bridge Internal use only */ u32 heap_size; @@ -347,7 +347,7 @@ struct dsp_notification { /* The dsp_processorattrin structure describes the attributes of a processor */ struct dsp_processorattrin { u32 cb_struct; - u32 utimeout; + u32 timeout; }; /* * The dsp_processorinfo structure describes basic capabilities of a @@ -401,13 +401,13 @@ struct dsp_resourceinfo { */ struct dsp_streamattrin { u32 cb_struct; - u32 utimeout; + u32 timeout; u32 segment_id; u32 buf_alignment; u32 num_bufs; enum dsp_strmmode strm_mode; u32 udma_chnl_id; - u32 udma_priority; + u32 dma_priority; }; /* The dsp_bufferattr structure describes the attributes of a data buffer */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/drv.h b/drivers/staging/tidspbridge/include/dspbridge/drv.h index bcb28171132b..3b98c1a41da6 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/drv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/drv.h @@ -129,7 +129,7 @@ struct process_context { enum gpp_proc_res_state res_state; /* Handle to Processor */ - void *hprocessor; + void *processor; /* DSP Node resources */ struct idr *node_id; diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h index ab20062f3a53..1511922a7470 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h @@ -56,7 +56,7 @@ union trapped_args { struct dsp_notification __user *__user *anotifications; u32 count; u32 __user *pu_index; - u32 utimeout; + u32 timeout; } args_mgr_wait; /* PROC Module */ @@ -67,17 +67,17 @@ union trapped_args { } args_proc_attach; struct { - void *hprocessor; + void *processor; u32 cmd; struct dsp_cbdata __user *pargs; } args_proc_ctrl; struct { - void *hprocessor; + void *processor; } args_proc_detach; struct { - void *hprocessor; + void *processor; void *__user *node_tab; u32 node_tab_size; u32 __user *pu_num_nodes; @@ -85,53 +85,53 @@ union trapped_args { } args_proc_enumnode_info; struct { - void *hprocessor; + void *processor; u32 resource_type; struct dsp_resourceinfo *resource_info; u32 resource_info_size; } args_proc_enumresources; struct { - void *hprocessor; + void *processor; struct dsp_processorstate __user *proc_state_obj; u32 state_info_size; } args_proc_getstate; struct { - void *hprocessor; + void *processor; u8 __user *pbuf; u8 __user *psize; u32 max_size; } args_proc_gettrace; struct { - void *hprocessor; + void *processor; s32 argc_index; char __user *__user *user_args; char *__user *user_envp; } args_proc_load; struct { - void *hprocessor; + void *processor; u32 event_mask; u32 notify_type; struct dsp_notification __user *hnotification; } args_proc_register_notify; struct { - void *hprocessor; + void *processor; u32 size; void *__user *pp_rsv_addr; } args_proc_rsvmem; struct { - void *hprocessor; + void *processor; u32 size; void *prsv_addr; } args_proc_unrsvmem; struct { - void *hprocessor; + void *processor; void *pmpu_addr; u32 size; void *req_addr; @@ -140,34 +140,34 @@ union trapped_args { } args_proc_mapmem; struct { - void *hprocessor; + void *processor; u32 size; void *map_addr; } args_proc_unmapmem; struct { - void *hprocessor; + void *processor; void *pmpu_addr; u32 size; u32 dir; } args_proc_dma; struct { - void *hprocessor; + void *processor; void *pmpu_addr; u32 size; u32 ul_flags; } args_proc_flushmemory; struct { - void *hprocessor; + void *processor; void *pmpu_addr; u32 size; } args_proc_invalidatememory; /* NODE Module */ struct { - void *hprocessor; + void *processor; struct dsp_uuid __user *node_id_ptr; struct dsp_cbdata __user *pargs; struct dsp_nodeattrin __user *attr_in; @@ -218,7 +218,7 @@ union trapped_args { struct { void *hnode; struct dsp_msg __user *message; - u32 utimeout; + u32 timeout; } args_node_getmessage; struct { @@ -228,7 +228,7 @@ union trapped_args { struct { void *hnode; struct dsp_msg __user *message; - u32 utimeout; + u32 timeout; } args_node_putmessage; struct { @@ -248,7 +248,7 @@ union trapped_args { } args_node_terminate; struct { - void *hprocessor; + void *processor; struct dsp_uuid __user *node_id_ptr; struct dsp_ndbprops __user *node_props; } args_node_getuuidprops; @@ -323,7 +323,7 @@ union trapped_args { void *__user *stream_tab; u32 strm_num; u32 __user *pmask; - u32 utimeout; + u32 timeout; } args_strm_select; /* CMM Module */ @@ -341,7 +341,7 @@ union trapped_args { } args_cmm_freebuf; struct { - void *hprocessor; + void *processor; struct cmm_object *__user *ph_cmm_mgr; } args_cmm_gethandle; diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h index 7ba08cad1faf..c2ba26c09308 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h @@ -300,7 +300,7 @@ typedef int(*fxn_brd_write) (struct bridge_dev_context *dev_ctxt, * mgr_attrts->irq_shared: TRUE if the IRQ is shareable. * mgr_attrts->word_size: DSP Word size in equivalent PC bytes.. * mgr_attrts->shm_base: Base physical address of shared memory, if any. - * mgr_attrts->usm_length: Bytes of shared memory block. + * mgr_attrts->sm_length: Bytes of shared memory block. * Returns: * 0: Success; * -ENOMEM: Insufficient memory for requested resources. diff --git a/drivers/staging/tidspbridge/include/dspbridge/io.h b/drivers/staging/tidspbridge/include/dspbridge/io.h index 961598060f95..500bbd71684d 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/io.h +++ b/drivers/staging/tidspbridge/include/dspbridge/io.h @@ -31,7 +31,7 @@ struct io_attrs { bool irq_shared; /* TRUE if the IRQ is shareable. */ u32 word_size; /* DSP Word size. */ u32 shm_base; /* Physical base address of shared memory. */ - u32 usm_length; /* Size (in bytes) of shared memory. */ + u32 sm_length; /* Size (in bytes) of shared memory. */ }; diff --git a/drivers/staging/tidspbridge/include/dspbridge/nodepriv.h b/drivers/staging/tidspbridge/include/dspbridge/nodepriv.h index b14f79ac5bb0..9c1e06758c89 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/nodepriv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/nodepriv.h @@ -43,7 +43,7 @@ struct node_strmdef { u32 buf_size; /* Size of buffers for SIO stream */ u32 num_bufs; /* max # of buffers in SIO stream at once */ u32 seg_id; /* Memory segment id to allocate buffers */ - u32 utimeout; /* Timeout for blocking SIO calls */ + u32 timeout; /* Timeout for blocking SIO calls */ u32 buf_alignment; /* Buffer alignment */ char *sz_device; /* Device name for stream */ }; @@ -55,10 +55,10 @@ struct node_taskargs { u32 stack_size; u32 sys_stack_size; u32 stack_seg; - u32 udsp_heap_res_addr; /* DSP virtual heap address */ - u32 udsp_heap_addr; /* DSP virtual heap address */ + u32 dsp_heap_res_addr; /* DSP virtual heap address */ + u32 dsp_heap_addr; /* DSP virtual heap address */ u32 heap_size; /* Heap size */ - u32 ugpp_heap_addr; /* GPP virtual heap address */ + u32 gpp_heap_addr; /* GPP virtual heap address */ u32 profile_id; /* Profile ID */ u32 num_inputs; u32 num_outputs; diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c index ce7360f5111b..d35b2ad53c99 100644 --- a/drivers/staging/tidspbridge/pmgr/dev.c +++ b/drivers/staging/tidspbridge/pmgr/dev.c @@ -215,12 +215,12 @@ int dev_create_device(struct dev_object **device_obj, /* Assume last memory window is for CHNL */ io_mgr_attrs.shm_base = host_res->mem_base[1] + host_res->offset_for_monitor; - io_mgr_attrs.usm_length = + io_mgr_attrs.sm_length = host_res->mem_length[1] - host_res->offset_for_monitor; } else { io_mgr_attrs.shm_base = 0; - io_mgr_attrs.usm_length = 0; + io_mgr_attrs.sm_length = 0; pr_err("%s: No memory reserved for shared structures\n", __func__); } diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c index b7ff37810555..912a1f94fde7 100644 --- a/drivers/staging/tidspbridge/pmgr/dspapi.c +++ b/drivers/staging/tidspbridge/pmgr/dspapi.c @@ -569,7 +569,7 @@ u32 mgrwrap_wait_for_bridge_events(union trapped_args *args, void *pr_ctxt) status = mgr_wait_for_bridge_events(anotifications, count, &index, args->args_mgr_wait. - utimeout); + timeout); } CP_TO_USR(args->args_mgr_wait.pu_index, &index, status, 1); return status; @@ -620,7 +620,7 @@ u32 procwrap_ctrl(union trapped_args *args, void *pr_ctxt) args->args_proc_ctrl.pargs; u8 *pargs = NULL; int status = 0; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; + void *hprocessor = ((struct process_context *)pr_ctxt)->processor; if (psize) { if (get_user(cb_data_size, psize)) { @@ -668,7 +668,7 @@ u32 procwrap_enum_node_info(union trapped_args *args, void *pr_ctxt) void *node_tab[MAX_NODES]; u32 num_nodes; u32 alloc_cnt; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; + void *hprocessor = ((struct process_context *)pr_ctxt)->processor; if (!args->args_proc_enumnode_info.node_tab_size) return -EINVAL; @@ -753,7 +753,7 @@ u32 procwrap_enum_resources(union trapped_args *args, void *pr_ctxt) { int status = 0; struct dsp_resourceinfo resource_info; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; + void *hprocessor = ((struct process_context *)pr_ctxt)->processor; if (args->args_proc_enumresources.resource_info_size < sizeof(struct dsp_resourceinfo)) @@ -780,7 +780,7 @@ u32 procwrap_get_state(union trapped_args *args, void *pr_ctxt) { int status; struct dsp_processorstate proc_state; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; + void *hprocessor = ((struct process_context *)pr_ctxt)->processor; if (args->args_proc_getstate.state_info_size < sizeof(struct dsp_processorstate)) @@ -801,7 +801,7 @@ u32 procwrap_get_trace(union trapped_args *args, void *pr_ctxt) { int status; u8 *pbuf; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; + void *hprocessor = ((struct process_context *)pr_ctxt)->processor; if (args->args_proc_gettrace.max_size > MAX_TRACEBUFLEN) return -EINVAL; @@ -830,7 +830,7 @@ u32 procwrap_load(union trapped_args *args, void *pr_ctxt) char *temp; s32 count = args->args_proc_load.argc_index; u8 **argv = NULL, **envp = NULL; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; + void *hprocessor = ((struct process_context *)pr_ctxt)->processor; if (count <= 0 || count > MAX_LOADARGS) { status = -EINVAL; @@ -948,12 +948,12 @@ u32 procwrap_map(union trapped_args *args, void *pr_ctxt) { int status; void *map_addr; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; + void *hprocessor = ((struct process_context *)pr_ctxt)->processor; if (!args->args_proc_mapmem.size) return -EINVAL; - status = proc_map(args->args_proc_mapmem.hprocessor, + status = proc_map(args->args_proc_mapmem.processor, args->args_proc_mapmem.pmpu_addr, args->args_proc_mapmem.size, args->args_proc_mapmem.req_addr, &map_addr, @@ -975,7 +975,7 @@ u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt) { int status; struct dsp_notification notification; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; + void *hprocessor = ((struct process_context *)pr_ctxt)->processor; /* Initialize the notification data structure */ notification.ps_name = NULL; @@ -997,7 +997,7 @@ u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt) { int status; void *prsv_addr; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; + void *hprocessor = ((struct process_context *)pr_ctxt)->processor; if ((args->args_proc_rsvmem.size <= 0) || (args->args_proc_rsvmem.size & (PG_SIZE4K - 1)) != 0) @@ -1010,7 +1010,7 @@ u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt) if (put_user(prsv_addr, args->args_proc_rsvmem.pp_rsv_addr)) { status = -EINVAL; proc_un_reserve_memory(args->args_proc_rsvmem. - hprocessor, prsv_addr, pr_ctxt); + processor, prsv_addr, pr_ctxt); } } return status; @@ -1023,7 +1023,7 @@ u32 procwrap_start(union trapped_args *args, void *pr_ctxt) { u32 ret; - ret = proc_start(((struct process_context *)pr_ctxt)->hprocessor); + ret = proc_start(((struct process_context *)pr_ctxt)->processor); return ret; } @@ -1034,7 +1034,7 @@ u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt) { int status; - status = proc_un_map(((struct process_context *)pr_ctxt)->hprocessor, + status = proc_un_map(((struct process_context *)pr_ctxt)->processor, args->args_proc_unmapmem.map_addr, pr_ctxt); return status; } @@ -1045,7 +1045,7 @@ u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt) u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt) { int status; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; + void *hprocessor = ((struct process_context *)pr_ctxt)->processor; status = proc_un_reserve_memory(hprocessor, args->args_proc_unrsvmem.prsv_addr, @@ -1060,7 +1060,7 @@ u32 procwrap_stop(union trapped_args *args, void *pr_ctxt) { u32 ret; - ret = proc_stop(((struct process_context *)pr_ctxt)->hprocessor); + ret = proc_stop(((struct process_context *)pr_ctxt)->processor); return ret; } @@ -1092,7 +1092,7 @@ u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt) struct dsp_nodeattrin proc_attr_in, *attr_in = NULL; struct node_res_object *node_res; int nodeid; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; + void *hprocessor = ((struct process_context *)pr_ctxt)->processor; /* Optional argument */ if (psize) { @@ -1378,7 +1378,7 @@ u32 nodewrap_get_message(union trapped_args *args, void *pr_ctxt) return -EFAULT; status = node_get_message(node_res->hnode, &msg, - args->args_node_getmessage.utimeout); + args->args_node_getmessage.timeout); CP_TO_USR(args->args_node_getmessage.message, &msg, status, 1); @@ -1422,7 +1422,7 @@ u32 nodewrap_put_message(union trapped_args *args, void *pr_ctxt) if (!status) { status = node_put_message(node_res->hnode, &msg, - args->args_node_putmessage.utimeout); + args->args_node_putmessage.timeout); } return status; @@ -1508,7 +1508,7 @@ u32 nodewrap_get_uuid_props(union trapped_args *args, void *pr_ctxt) int status = 0; struct dsp_uuid node_uuid; struct dsp_ndbprops *pnode_props = NULL; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; + void *hprocessor = ((struct process_context *)pr_ctxt)->processor; CP_FM_USR(&node_uuid, args->args_node_getuuidprops.node_id_ptr, status, 1); @@ -1853,7 +1853,7 @@ u32 strmwrap_select(union trapped_args *args, void *pr_ctxt) if (!status) { status = strm_select(strm_tab, args->args_strm_select.strm_num, - &mask, args->args_strm_select.utimeout); + &mask, args->args_strm_select.timeout); } CP_TO_USR(args->args_strm_select.pmask, &mask, status, 1); return status; @@ -1888,7 +1888,7 @@ u32 cmmwrap_get_handle(union trapped_args *args, void *pr_ctxt) { int status = 0; struct cmm_object *hcmm_mgr; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; + void *hprocessor = ((struct process_context *)pr_ctxt)->processor; status = cmm_get_handle(hprocessor, &hcmm_mgr); diff --git a/drivers/staging/tidspbridge/pmgr/io.c b/drivers/staging/tidspbridge/pmgr/io.c index b05a772d8d99..65245f310f89 100644 --- a/drivers/staging/tidspbridge/pmgr/io.c +++ b/drivers/staging/tidspbridge/pmgr/io.c @@ -57,7 +57,7 @@ int io_create(struct io_mgr **io_man, struct dev_object *hdev_obj, *io_man = NULL; /* A memory base of 0 implies no memory base: */ - if ((mgr_attrts->shm_base != 0) && (mgr_attrts->usm_length == 0)) + if ((mgr_attrts->shm_base != 0) && (mgr_attrts->sm_length == 0)) status = -EINVAL; if (mgr_attrts->word_size == 0) diff --git a/drivers/staging/tidspbridge/rmgr/dbdcd.c b/drivers/staging/tidspbridge/rmgr/dbdcd.c index 98b88b187b0f..1e77c12be404 100644 --- a/drivers/staging/tidspbridge/rmgr/dbdcd.c +++ b/drivers/staging/tidspbridge/rmgr/dbdcd.c @@ -1112,14 +1112,14 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size, dsp_resource_reqmts.program_mem_size = atoi(token); token = strsep(&psz_cur, seps); gen_obj->obj_data.node_obj.ndb_props. - dsp_resource_reqmts.uwc_execution_time = atoi(token); + dsp_resource_reqmts.wc_execution_time = atoi(token); token = strsep(&psz_cur, seps); gen_obj->obj_data.node_obj.ndb_props. - dsp_resource_reqmts.uwc_period = atoi(token); + dsp_resource_reqmts.wc_period = atoi(token); token = strsep(&psz_cur, seps); gen_obj->obj_data.node_obj.ndb_props. - dsp_resource_reqmts.uwc_deadline = atoi(token); + dsp_resource_reqmts.wc_deadline = atoi(token); token = strsep(&psz_cur, seps); gen_obj->obj_data.node_obj.ndb_props. @@ -1162,8 +1162,8 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size, atoi(token); token = strsep(&psz_cur, seps); - /* u32 utimeout */ - gen_obj->obj_data.node_obj.ndb_props.utimeout = atoi(token); + /* u32 timeout */ + gen_obj->obj_data.node_obj.ndb_props.timeout = atoi(token); token = strsep(&psz_cur, seps); /* char *pstr_create_phase_fxn */ @@ -1221,7 +1221,7 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size, /* Load type (static, dynamic, or overlay) */ if (token) { - gen_obj->obj_data.node_obj.us_load_type = atoi(token); + gen_obj->obj_data.node_obj.load_type = atoi(token); token = strsep(&psz_cur, seps); } diff --git a/drivers/staging/tidspbridge/rmgr/disp.c b/drivers/staging/tidspbridge/rmgr/disp.c index e5af59e844d9..d38ea2d159f1 100644 --- a/drivers/staging/tidspbridge/rmgr/disp.c +++ b/drivers/staging/tidspbridge/rmgr/disp.c @@ -402,7 +402,7 @@ int disp_node_create(struct disp_object *disp_obj, more_task_args->sysstack_size = task_arg_obj.sys_stack_size; more_task_args->stack_seg = task_arg_obj.stack_seg; - more_task_args->heap_addr = task_arg_obj.udsp_heap_addr; + more_task_args->heap_addr = task_arg_obj.dsp_heap_addr; more_task_args->heap_size = task_arg_obj.heap_size; more_task_args->misc = task_arg_obj.dais_arg; more_task_args->num_input_streams = @@ -410,8 +410,8 @@ int disp_node_create(struct disp_object *disp_obj, total += sizeof(struct rms_more_task_args) / sizeof(rms_word); - dev_dbg(bridge, "%s: udsp_heap_addr %x, heap_size %x\n", - __func__, task_arg_obj.udsp_heap_addr, + dev_dbg(bridge, "%s: dsp_heap_addr %x, heap_size %x\n", + __func__, task_arg_obj.dsp_heap_addr, task_arg_obj.heap_size); /* Keep track of pSIOInDef[] and pSIOOutDef[] * positions in the buffer, since this needs to be @@ -611,7 +611,7 @@ static int fill_stream_def(rms_word *pdw_buf, u32 *ptotal, u32 offset, strm_def_obj->nbufs = strm_def.num_bufs; strm_def_obj->segid = strm_def.seg_id; strm_def_obj->align = strm_def.buf_alignment; - strm_def_obj->timeout = strm_def.utimeout; + strm_def_obj->timeout = strm_def.timeout; } if (!status) { diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c index 9aacbcb38eb6..ce5f398f6480 100644 --- a/drivers/staging/tidspbridge/rmgr/drv.c +++ b/drivers/staging/tidspbridge/rmgr/drv.c @@ -148,7 +148,7 @@ int drv_remove_all_dmm_res_elements(void *process_ctxt) /* Free DMM mapped memory resources */ list_for_each_entry_safe(map_obj, temp_map, &ctxt->dmm_map_list, link) { - status = proc_un_map(ctxt->hprocessor, + status = proc_un_map(ctxt->processor, (void *)map_obj->dsp_addr, ctxt); if (status) pr_err("%s: proc_un_map failed!" @@ -157,7 +157,7 @@ int drv_remove_all_dmm_res_elements(void *process_ctxt) /* Free DMM reserved memory resources */ list_for_each_entry_safe(rsv_obj, temp_rsv, &ctxt->dmm_rsv_list, link) { - status = proc_un_reserve_memory(ctxt->hprocessor, (void *) + status = proc_un_reserve_memory(ctxt->processor, (void *) rsv_obj->dsp_reserved_addr, ctxt); if (status) diff --git a/drivers/staging/tidspbridge/rmgr/nldr.c b/drivers/staging/tidspbridge/rmgr/nldr.c index 7a15f636fea5..e711970b160f 100644 --- a/drivers/staging/tidspbridge/rmgr/nldr.c +++ b/drivers/staging/tidspbridge/rmgr/nldr.c @@ -336,7 +336,7 @@ int nldr_allocate(struct nldr_object *nldr_obj, void *priv_ref, * Determine if node is a dynamically loaded node from * ndb_props. */ - if (node_props->us_load_type == NLDR_DYNAMICLOAD) { + if (node_props->load_type == NLDR_DYNAMICLOAD) { /* Dynamic node */ nldr_node_obj->dynamic = true; /* @@ -388,7 +388,7 @@ int nldr_allocate(struct nldr_object *nldr_obj, void *priv_ref, * base image */ nldr_node_obj->root.lib = nldr_obj->base_lib; /* Check for overlay node */ - if (node_props->us_load_type == NLDR_OVLYLOAD) + if (node_props->load_type == NLDR_OVLYLOAD) nldr_node_obj->overlay = true; } @@ -1011,7 +1011,7 @@ static int add_ovly_node(struct dsp_uuid *uuid_obj, goto func_end; /* If overlay node, add to the list */ - if (obj_def.obj_data.node_obj.us_load_type == NLDR_OVLYLOAD) { + if (obj_def.obj_data.node_obj.load_type == NLDR_OVLYLOAD) { if (nldr_obj->ovly_table == NULL) { nldr_obj->ovly_nodes++; } else { diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index 2bfbd16c4343..c627560a6c40 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -151,9 +151,9 @@ struct node_mgr { u32 chnl_buf_size; /* Buffer size for data to RMS */ int proc_family; /* eg, 5000 */ int proc_type; /* eg, 5510 */ - u32 udsp_word_size; /* Size of DSP word on host bytes */ - u32 udsp_data_mau_size; /* Size of DSP data MAU */ - u32 udsp_mau_size; /* Size of MAU */ + u32 dsp_word_size; /* Size of DSP word on host bytes */ + u32 dsp_data_mau_size; /* Size of DSP data MAU */ + u32 dsp_mau_size; /* Size of MAU */ s32 min_pri; /* Minimum runtime priority for node */ s32 max_pri; /* Maximum runtime priority for node */ @@ -189,13 +189,13 @@ struct stream_chnl { struct node_object { struct list_head list_elem; struct node_mgr *node_mgr; /* The manager of this node */ - struct proc_object *hprocessor; /* Back pointer to processor */ + struct proc_object *processor; /* Back pointer to processor */ struct dsp_uuid node_uuid; /* Node's ID */ s32 prio; /* Node's current priority */ - u32 utimeout; /* Timeout for blocking NODE calls */ + u32 timeout; /* Timeout for blocking NODE calls */ u32 heap_size; /* Heap Size */ - u32 udsp_heap_virt_addr; /* Heap Size */ - u32 ugpp_heap_virt_addr; /* Heap Size */ + u32 dsp_heap_virt_addr; /* Heap Size */ + u32 gpp_heap_virt_addr; /* Heap Size */ enum node_type ntype; /* Type of node: message, task, etc */ enum node_state node_state; /* NODE_ALLOCATED, NODE_CREATED, ... */ u32 num_inputs; /* Current number of inputs */ @@ -400,17 +400,17 @@ int node_allocate(struct proc_object *hprocessor, goto func_cont; pnode->node_uuid = *node_uuid; - pnode->hprocessor = hprocessor; + pnode->processor = hprocessor; pnode->ntype = pnode->dcd_props.obj_data.node_obj.ndb_props.ntype; - pnode->utimeout = pnode->dcd_props.obj_data.node_obj.ndb_props.utimeout; + pnode->timeout = pnode->dcd_props.obj_data.node_obj.ndb_props.timeout; pnode->prio = pnode->dcd_props.obj_data.node_obj.ndb_props.prio; /* Currently only C64 DSP builds support Node Dynamic * heaps */ /* Allocate memory for node heap */ pnode->create_args.asa.task_arg_obj.heap_size = 0; - pnode->create_args.asa.task_arg_obj.udsp_heap_addr = 0; - pnode->create_args.asa.task_arg_obj.udsp_heap_res_addr = 0; - pnode->create_args.asa.task_arg_obj.ugpp_heap_addr = 0; + pnode->create_args.asa.task_arg_obj.dsp_heap_addr = 0; + pnode->create_args.asa.task_arg_obj.dsp_heap_res_addr = 0; + pnode->create_args.asa.task_arg_obj.gpp_heap_addr = 0; if (!attr_in) goto func_cont; @@ -426,7 +426,7 @@ int node_allocate(struct proc_object *hprocessor, } else { pnode->create_args.asa.task_arg_obj.heap_size = attr_in->heap_size; - pnode->create_args.asa.task_arg_obj.ugpp_heap_addr = + pnode->create_args.asa.task_arg_obj.gpp_heap_addr = (u32) attr_in->pgpp_virt_addr; } if (status) @@ -436,7 +436,7 @@ int node_allocate(struct proc_object *hprocessor, pnode->create_args.asa.task_arg_obj. heap_size + PAGE_SIZE, (void **)&(pnode->create_args.asa. - task_arg_obj.udsp_heap_res_addr), + task_arg_obj.dsp_heap_res_addr), pr_ctxt); if (status) { pr_err("%s: Failed to reserve memory for heap: 0x%x\n", @@ -459,20 +459,20 @@ int node_allocate(struct proc_object *hprocessor, status = proc_map(hprocessor, (void *)attr_in->pgpp_virt_addr, pnode->create_args.asa.task_arg_obj.heap_size, (void *)pnode->create_args.asa.task_arg_obj. - udsp_heap_res_addr, (void **)&mapped_addr, map_attrs, + dsp_heap_res_addr, (void **)&mapped_addr, map_attrs, pr_ctxt); if (status) pr_err("%s: Failed to map memory for Heap: 0x%x\n", __func__, status); else - pnode->create_args.asa.task_arg_obj.udsp_heap_addr = + pnode->create_args.asa.task_arg_obj.dsp_heap_addr = (u32) mapped_addr; func_cont: mutex_unlock(&hnode_mgr->node_mgr_lock); if (attr_in != NULL) { /* Overrides of NBD properties */ - pnode->utimeout = attr_in->utimeout; + pnode->timeout = attr_in->timeout; pnode->prio = attr_in->prio; } /* Create object to manage notifications */ @@ -712,7 +712,7 @@ DBAPI node_alloc_msg_buf(struct node_object *hnode, u32 usize, if (pattr == NULL) pattr = &node_dfltbufattrs; /* set defaults */ - status = proc_get_processor_id(pnode->hprocessor, &proc_id); + status = proc_get_processor_id(pnode->processor, &proc_id); if (proc_id != DSP_UNIT) { DBC_ASSERT(NULL); goto func_end; @@ -808,7 +808,7 @@ int node_change_priority(struct node_object *hnode, s32 prio) status = -EBADR; goto func_cont; } - status = proc_get_processor_id(pnode->hprocessor, &proc_id); + status = proc_get_processor_id(pnode->processor, &proc_id); if (proc_id == DSP_UNIT) { status = disp_node_change_priority(hnode_mgr->disp_obj, @@ -1144,7 +1144,7 @@ int node_create(struct node_object *hnode) status = -EFAULT; goto func_end; } - hprocessor = hnode->hprocessor; + hprocessor = hnode->processor; status = proc_get_state(hprocessor, &proc_state, sizeof(struct dsp_processorstate)); if (status) @@ -1168,7 +1168,7 @@ int node_create(struct node_object *hnode) status = -EBADR; if (!status) - status = proc_get_processor_id(pnode->hprocessor, &proc_id); + status = proc_get_processor_id(pnode->processor, &proc_id); if (status) goto func_cont2; @@ -1266,7 +1266,7 @@ func_cont: mutex_unlock(&hnode_mgr->node_mgr_lock); func_end: if (status >= 0) { - proc_notify_clients(hnode->hprocessor, DSP_NODESTATECHANGE); + proc_notify_clients(hnode->processor, DSP_NODESTATECHANGE); ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE); } @@ -1364,8 +1364,8 @@ int node_create_mgr(struct node_mgr **node_man, nldr_attrs_obj.ovly = ovly; nldr_attrs_obj.write = mem_write; - nldr_attrs_obj.dsp_word_size = node_mgr_obj->udsp_word_size; - nldr_attrs_obj.dsp_mau_size = node_mgr_obj->udsp_mau_size; + nldr_attrs_obj.dsp_word_size = node_mgr_obj->dsp_word_size; + nldr_attrs_obj.dsp_mau_size = node_mgr_obj->dsp_mau_size; node_mgr_obj->loader_init = node_mgr_obj->nldr_fxns.init(); status = node_mgr_obj->nldr_fxns.create(&node_mgr_obj->nldr_obj, hdev_obj, @@ -1418,7 +1418,7 @@ int node_delete(struct node_res_object *noderes, /* create struct dsp_cbdata struct for PWR call */ cb_data.cb_data = PWR_TIMEOUT; hnode_mgr = pnode->node_mgr; - hprocessor = pnode->hprocessor; + hprocessor = pnode->processor; disp_obj = hnode_mgr->disp_obj; node_type = node_get_type(pnode); intf_fxns = hnode_mgr->intf_fxns; @@ -1433,7 +1433,7 @@ int node_delete(struct node_res_object *noderes, * code must be executed. */ if (!(state == NODE_ALLOCATED && pnode->node_env == (u32) NULL) && node_type != NODE_DEVICE) { - status = proc_get_processor_id(pnode->hprocessor, &proc_id); + status = proc_get_processor_id(pnode->processor, &proc_id); if (status) goto func_cont1; @@ -1638,7 +1638,7 @@ int node_free_msg_buf(struct node_object *hnode, u8 * pbuffer, status = -EFAULT; goto func_end; } - status = proc_get_processor_id(pnode->hprocessor, &proc_id); + status = proc_get_processor_id(pnode->processor, &proc_id); if (proc_id == DSP_UNIT) { if (!status) { if (pattr == NULL) { @@ -1686,11 +1686,11 @@ int node_get_attr(struct node_object *hnode, pattr->in_node_attr_in.cb_struct = sizeof(struct dsp_nodeattrin); pattr->in_node_attr_in.prio = hnode->prio; - pattr->in_node_attr_in.utimeout = hnode->utimeout; + pattr->in_node_attr_in.timeout = hnode->timeout; pattr->in_node_attr_in.heap_size = hnode->create_args.asa.task_arg_obj.heap_size; pattr->in_node_attr_in.pgpp_virt_addr = (void *) - hnode->create_args.asa.task_arg_obj.ugpp_heap_addr; + hnode->create_args.asa.task_arg_obj.gpp_heap_addr; pattr->node_attr_inputs = hnode->num_gpp_inputs; pattr->node_attr_outputs = hnode->num_gpp_outputs; /* dsp_nodeinfo */ @@ -1768,7 +1768,7 @@ int node_get_message(struct node_object *hnode, status = -EFAULT; goto func_end; } - hprocessor = hnode->hprocessor; + hprocessor = hnode->processor; status = proc_get_state(hprocessor, &proc_state, sizeof(struct dsp_processorstate)); if (status) @@ -1802,7 +1802,7 @@ int node_get_message(struct node_object *hnode, tmp_buf = cmm_xlator_translate(hnode->xlator, (void *)(message->arg1 * hnode->node_mgr-> - udsp_word_size), CMM_DSPPA2PA); + dsp_word_size), CMM_DSPPA2PA); if (tmp_buf != NULL) { /* now convert this GPP Pa to Va */ tmp_buf = cmm_xlator_translate(hnode->xlator, tmp_buf, @@ -1810,7 +1810,7 @@ int node_get_message(struct node_object *hnode, if (tmp_buf != NULL) { /* Adjust SM size in msg */ message->arg1 = (u32) tmp_buf; - message->arg2 *= hnode->node_mgr->udsp_word_size; + message->arg2 *= hnode->node_mgr->dsp_word_size; } else { status = -ESRCH; } @@ -1873,7 +1873,7 @@ enum nldr_loadtype node_get_load_type(struct node_object *hnode) dev_dbg(bridge, "%s: Failed. hnode: %p\n", __func__, hnode); return -1; } else { - return hnode->dcd_props.obj_data.node_obj.us_load_type; + return hnode->dcd_props.obj_data.node_obj.load_type; } } @@ -1890,7 +1890,7 @@ u32 node_get_timeout(struct node_object *hnode) dev_dbg(bridge, "%s: failed. hnode: %p\n", __func__, hnode); return 0; } else { - return hnode->utimeout; + return hnode->timeout; } } @@ -1950,7 +1950,7 @@ void node_on_exit(struct node_object *hnode, s32 node_status) /* Unblock call to node_terminate */ (void)sync_set_event(hnode->sync_done); /* Notify clients */ - proc_notify_clients(hnode->hprocessor, DSP_NODESTATECHANGE); + proc_notify_clients(hnode->processor, DSP_NODESTATECHANGE); ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE); } @@ -1982,7 +1982,7 @@ int node_pause(struct node_object *hnode) if (status) goto func_end; - status = proc_get_processor_id(pnode->hprocessor, &proc_id); + status = proc_get_processor_id(pnode->processor, &proc_id); if (proc_id == IVA_UNIT) status = -ENOSYS; @@ -1999,7 +1999,7 @@ int node_pause(struct node_object *hnode) if (status) goto func_cont; - hprocessor = hnode->hprocessor; + hprocessor = hnode->processor; status = proc_get_state(hprocessor, &proc_state, sizeof(struct dsp_processorstate)); if (status) @@ -2024,7 +2024,7 @@ func_cont: /* Leave critical section */ mutex_unlock(&hnode_mgr->node_mgr_lock); if (status >= 0) { - proc_notify_clients(hnode->hprocessor, + proc_notify_clients(hnode->processor, DSP_NODESTATECHANGE); ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE); } @@ -2061,7 +2061,7 @@ int node_put_message(struct node_object *hnode, status = -EFAULT; goto func_end; } - hprocessor = hnode->hprocessor; + hprocessor = hnode->processor; status = proc_get_state(hprocessor, &proc_state, sizeof(struct dsp_processorstate)); if (status) @@ -2107,15 +2107,15 @@ int node_put_message(struct node_object *hnode, CMM_VA2DSPPA); if (tmp_buf != NULL) { /* got translation, convert to MAUs in msg */ - if (hnode->node_mgr->udsp_word_size != 0) { + if (hnode->node_mgr->dsp_word_size != 0) { new_msg.arg1 = (u32) tmp_buf / - hnode->node_mgr->udsp_word_size; + hnode->node_mgr->dsp_word_size; /* MAUs */ new_msg.arg2 /= hnode->node_mgr-> - udsp_word_size; + dsp_word_size; } else { - pr_err("%s: udsp_word_size is zero!\n", + pr_err("%s: dsp_word_size is zero!\n", __func__); status = -EPERM; /* bad DSPWordSize */ } @@ -2213,7 +2213,7 @@ int node_run(struct node_object *hnode) status = -EFAULT; goto func_end; } - hprocessor = hnode->hprocessor; + hprocessor = hnode->processor; status = proc_get_state(hprocessor, &proc_state, sizeof(struct dsp_processorstate)); if (status) @@ -2243,7 +2243,7 @@ int node_run(struct node_object *hnode) status = -EBADR; if (!status) - status = proc_get_processor_id(pnode->hprocessor, &proc_id); + status = proc_get_processor_id(pnode->processor, &proc_id); if (status) goto func_cont1; @@ -2299,7 +2299,7 @@ func_cont1: /* Exit critical section */ mutex_unlock(&hnode_mgr->node_mgr_lock); if (status >= 0) { - proc_notify_clients(hnode->hprocessor, DSP_NODESTATECHANGE); + proc_notify_clients(hnode->processor, DSP_NODESTATECHANGE); ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE); } func_end: @@ -2333,11 +2333,11 @@ int node_terminate(struct node_object *hnode, int *pstatus) status = -EFAULT; goto func_end; } - if (pnode->hprocessor == NULL) { + if (pnode->processor == NULL) { status = -EFAULT; goto func_end; } - status = proc_get_processor_id(pnode->hprocessor, &proc_id); + status = proc_get_processor_id(pnode->processor, &proc_id); if (!status) { hnode_mgr = hnode->node_mgr; @@ -2367,7 +2367,7 @@ int node_terminate(struct node_object *hnode, int *pstatus) * Send exit message. Do not change state to NODE_DONE * here. That will be done in callback. */ - status = proc_get_state(pnode->hprocessor, &proc_state, + status = proc_get_state(pnode->processor, &proc_state, sizeof(struct dsp_processorstate)); if (status) goto func_cont; @@ -2384,13 +2384,13 @@ int node_terminate(struct node_object *hnode, int *pstatus) killmsg.arg1 = hnode->node_env; intf_fxns = hnode_mgr->intf_fxns; - if (hnode->utimeout > MAXTIMEOUT) + if (hnode->timeout > MAXTIMEOUT) kill_time_out = MAXTIMEOUT; else - kill_time_out = (hnode->utimeout) * 2; + kill_time_out = (hnode->timeout) * 2; status = (*intf_fxns->msg_put) (hnode->msg_queue_obj, &msg, - hnode->utimeout); + hnode->timeout); if (status) goto func_cont; @@ -2406,7 +2406,7 @@ int node_terminate(struct node_object *hnode, int *pstatus) goto func_cont; status = (*intf_fxns->msg_put)(hnode->msg_queue_obj, - &killmsg, hnode->utimeout); + &killmsg, hnode->timeout); if (status) goto func_cont; status = sync_wait_on_event(hnode->sync_done, @@ -2460,7 +2460,7 @@ static void delete_node(struct node_object *hnode, #ifdef DSP_DMM_DEBUG struct dmm_object *dmm_mgr; struct proc_object *p_proc_object = - (struct proc_object *)hnode->hprocessor; + (struct proc_object *)hnode->processor; #endif int status; if (!hnode) @@ -2518,15 +2518,15 @@ static void delete_node(struct node_object *hnode, kfree(task_arg_obj.strm_out_def); task_arg_obj.strm_out_def = NULL; } - if (task_arg_obj.udsp_heap_res_addr) { - status = proc_un_map(hnode->hprocessor, (void *) - task_arg_obj.udsp_heap_addr, + if (task_arg_obj.dsp_heap_res_addr) { + status = proc_un_map(hnode->processor, (void *) + task_arg_obj.dsp_heap_addr, pr_ctxt); - status = proc_un_reserve_memory(hnode->hprocessor, + status = proc_un_reserve_memory(hnode->processor, (void *) task_arg_obj. - udsp_heap_res_addr, + dsp_heap_res_addr, pr_ctxt); #ifdef DSP_DMM_DEBUG status = dmm_get_handle(p_proc_object, &dmm_mgr); @@ -2691,17 +2691,17 @@ static void fill_stream_def(struct node_object *hnode, if (pattrs != NULL) { pstrm_def->num_bufs = pattrs->num_bufs; pstrm_def->buf_size = - pattrs->buf_size / hnode_mgr->udsp_data_mau_size; + pattrs->buf_size / hnode_mgr->dsp_data_mau_size; pstrm_def->seg_id = pattrs->seg_id; pstrm_def->buf_alignment = pattrs->buf_alignment; - pstrm_def->utimeout = pattrs->utimeout; + pstrm_def->timeout = pattrs->timeout; } else { pstrm_def->num_bufs = DEFAULTNBUFS; pstrm_def->buf_size = - DEFAULTBUFSIZE / hnode_mgr->udsp_data_mau_size; + DEFAULTBUFSIZE / hnode_mgr->dsp_data_mau_size; pstrm_def->seg_id = DEFAULTSEGID; pstrm_def->buf_alignment = DEFAULTALIGNMENT; - pstrm_def->utimeout = DEFAULTTIMEOUT; + pstrm_def->timeout = DEFAULTTIMEOUT; } } @@ -2915,9 +2915,9 @@ static int get_proc_props(struct node_mgr *hnode_mgr, hnode_mgr->proc_type = 6410; hnode_mgr->min_pri = DSP_NODE_MIN_PRIORITY; hnode_mgr->max_pri = DSP_NODE_MAX_PRIORITY; - hnode_mgr->udsp_word_size = DSPWORDSIZE; - hnode_mgr->udsp_data_mau_size = DSPWORDSIZE; - hnode_mgr->udsp_mau_size = 1; + hnode_mgr->dsp_word_size = DSPWORDSIZE; + hnode_mgr->dsp_data_mau_size = DSPWORDSIZE; + hnode_mgr->dsp_mau_size = 1; } return status; @@ -3067,8 +3067,8 @@ static u32 ovly(void *priv_ref, u32 dsp_run_addr, u32 dsp_load_addr, hnode_mgr = hnode->node_mgr; - ul_size = ul_num_bytes / hnode_mgr->udsp_word_size; - ul_timeout = hnode->utimeout; + ul_size = ul_num_bytes / hnode_mgr->dsp_word_size; + ul_timeout = hnode->timeout; /* Call new MemCopy function */ intf_fxns = hnode_mgr->intf_fxns; @@ -3111,7 +3111,7 @@ static u32 mem_write(void *priv_ref, u32 dsp_add, void *pbuf, hnode_mgr = hnode->node_mgr; - ul_timeout = hnode->utimeout; + ul_timeout = hnode->timeout; mem_sect_type = (mem_space & DBLL_CODE) ? RMS_CODE : RMS_DATA; /* Call new MemWrite function */ diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c index fddbcea32f53..54f61336d778 100644 --- a/drivers/staging/tidspbridge/rmgr/proc.c +++ b/drivers/staging/tidspbridge/rmgr/proc.c @@ -85,7 +85,7 @@ struct proc_object { struct mgr_object *mgr_obj; /* Manager Object Handle */ u32 attach_count; /* Processor attach count */ u32 processor_id; /* Processor number */ - u32 utimeout; /* Time out count */ + u32 timeout; /* Time out count */ enum dsp_procstate proc_state; /* Processor state */ u32 unit; /* DDSP unit number */ bool is_already_attached; /* @@ -284,8 +284,8 @@ proc_attach(u32 processor_id, DBC_REQUIRE(refs > 0); DBC_REQUIRE(ph_processor != NULL); - if (pr_ctxt->hprocessor) { - *ph_processor = pr_ctxt->hprocessor; + if (pr_ctxt->processor) { + *ph_processor = pr_ctxt->processor; return status; } @@ -324,9 +324,9 @@ proc_attach(u32 processor_id, INIT_LIST_HEAD(&p_proc_object->proc_list); if (attr_in) - p_proc_object->utimeout = attr_in->utimeout; + p_proc_object->timeout = attr_in->timeout; else - p_proc_object->utimeout = PROC_DFLT_TIMEOUT; + p_proc_object->timeout = PROC_DFLT_TIMEOUT; status = dev_get_intf_fxns(hdev_obj, &p_proc_object->intf_fxns); if (!status) { @@ -373,7 +373,7 @@ proc_attach(u32 processor_id, } if (!status) { *ph_processor = (void *)p_proc_object; - pr_ctxt->hprocessor = *ph_processor; + pr_ctxt->processor = *ph_processor; (void)proc_notify_clients(p_proc_object, DSP_PROCESSORATTACH); } @@ -567,7 +567,7 @@ int proc_detach(struct process_context *pr_ctxt) DBC_REQUIRE(refs > 0); - p_proc_object = (struct proc_object *)pr_ctxt->hprocessor; + p_proc_object = (struct proc_object *)pr_ctxt->processor; if (p_proc_object) { /* Notify the Client */ @@ -585,7 +585,7 @@ int proc_detach(struct process_context *pr_ctxt) (u32) p_proc_object); /* Free the Processor Object */ kfree(p_proc_object); - pr_ctxt->hprocessor = NULL; + pr_ctxt->processor = NULL; } else { status = -EFAULT; } diff --git a/drivers/staging/tidspbridge/rmgr/strm.c b/drivers/staging/tidspbridge/rmgr/strm.c index 9498b6747e72..cc7370c45d14 100644 --- a/drivers/staging/tidspbridge/rmgr/strm.c +++ b/drivers/staging/tidspbridge/rmgr/strm.c @@ -68,7 +68,7 @@ struct strm_object { struct strm_mgr *strm_mgr_obj; struct chnl_object *chnl_obj; u32 dir; /* DSP_TONODE or DSP_FROMNODE */ - u32 utimeout; + u32 timeout; u32 num_bufs; /* Max # of bufs allowed in stream */ u32 un_bufs_in_strm; /* Current # of bufs in stream */ u32 bytes; /* bytes transferred since idled */ @@ -77,7 +77,7 @@ struct strm_object { void *user_event; /* Saved for strm_get_info() */ enum dsp_strmmode strm_mode; /* STRMMODE_[PROCCOPY][ZEROCOPY]... */ u32 udma_chnl_id; /* DMA chnl id */ - u32 udma_priority; /* DMA priority:DMAPRI_[LOW][HIGH] */ + u32 dma_priority; /* DMA priority:DMAPRI_[LOW][HIGH] */ u32 segment_id; /* >0 is SM segment.=0 is local heap */ u32 buf_alignment; /* Alignment for stream bufs */ /* Stream's SM address translator */ @@ -378,7 +378,7 @@ int strm_idle(struct strm_object *stream_obj, bool flush_data) intf_fxns = stream_obj->strm_mgr_obj->intf_fxns; status = (*intf_fxns->chnl_idle) (stream_obj->chnl_obj, - stream_obj->utimeout, + stream_obj->timeout, flush_data); } @@ -494,8 +494,8 @@ int strm_open(struct node_object *hnode, u32 dir, u32 index, strm_obj->strm_state = STREAM_IDLE; strm_obj->user_event = pattr->user_event; if (pattr->stream_attr_in != NULL) { - strm_obj->utimeout = - pattr->stream_attr_in->utimeout; + strm_obj->timeout = + pattr->stream_attr_in->timeout; strm_obj->num_bufs = pattr->stream_attr_in->num_bufs; strm_obj->strm_mode = @@ -506,23 +506,23 @@ int strm_open(struct node_object *hnode, u32 dir, u32 index, pattr->stream_attr_in->buf_alignment; strm_obj->udma_chnl_id = pattr->stream_attr_in->udma_chnl_id; - strm_obj->udma_priority = - pattr->stream_attr_in->udma_priority; + strm_obj->dma_priority = + pattr->stream_attr_in->dma_priority; chnl_attr_obj.uio_reqs = pattr->stream_attr_in->num_bufs; } else { - strm_obj->utimeout = DEFAULTTIMEOUT; + strm_obj->timeout = DEFAULTTIMEOUT; strm_obj->num_bufs = DEFAULTNUMBUFS; strm_obj->strm_mode = STRMMODE_PROCCOPY; strm_obj->segment_id = 0; /* local mem */ strm_obj->buf_alignment = 0; strm_obj->udma_chnl_id = 0; - strm_obj->udma_priority = 0; + strm_obj->dma_priority = 0; chnl_attr_obj.uio_reqs = DEFAULTNUMBUFS; } chnl_attr_obj.reserved1 = NULL; /* DMA chnl flush timeout */ - chnl_attr_obj.reserved2 = strm_obj->utimeout; + chnl_attr_obj.reserved2 = strm_obj->timeout; chnl_attr_obj.event_obj = NULL; if (pattr->user_event != NULL) chnl_attr_obj.event_obj = pattr->user_event; @@ -632,7 +632,7 @@ int strm_reclaim(struct strm_object *stream_obj, u8 ** buf_ptr, status = (*intf_fxns->chnl_get_ioc) (stream_obj->chnl_obj, - stream_obj->utimeout, + stream_obj->timeout, &chnl_ioc_obj); if (!status) { *nbytes = chnl_ioc_obj.byte_size; -- cgit v1.2.3 From ee4317f78c24cf85efd067f4c09319e281c4fa4a Mon Sep 17 00:00:00 2001 From: Rene Sapiens Date: Tue, 18 Jan 2011 03:19:12 +0000 Subject: staging: tidspbridge: set10 remove hungarian from structs hungarian notation will be removed from the elements inside structures, the next varibles will be renamed: Original: Replacement: hnext next hnode node hprev prev hroot root hstream stream pbuf buf pcb_arg cb_arg pdspheap_list dspheap_list pmsg msg ps_name name pstr_create_phase_fxn str_create_phase_fxn pstr_delete_phase_fxn str_delete_phase_fxn pstr_dev_name str_dev_name pstr_event_name str_event_name pstr_execute_phase_fxn str_execute_phase_fxn pstr_i_alg_name str_i_alg_name udma_chnl_id dma_chnl_id un_bufs_in_strm bufs_in_strm usm_buf_size sm_buf_size Signed-off-by: Rene Sapiens Signed-off-by: Armando Uribe Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/core/chnl_sm.c | 12 +-- drivers/staging/tidspbridge/core/io_sm.c | 32 +++--- drivers/staging/tidspbridge/dynload/cload.c | 42 ++++---- .../staging/tidspbridge/dynload/dload_internal.h | 6 +- .../tidspbridge/include/dspbridge/_chnl_sm.h | 2 +- .../tidspbridge/include/dspbridge/chnldefs.h | 6 +- .../tidspbridge/include/dspbridge/dbdcddef.h | 8 +- .../staging/tidspbridge/include/dspbridge/dbdefs.h | 6 +- .../staging/tidspbridge/include/dspbridge/drv.h | 4 +- .../tidspbridge/include/dspbridge/dspapi-ioctl.h | 54 +++++------ .../tidspbridge/include/dspbridge/strmdefs.h | 2 +- drivers/staging/tidspbridge/pmgr/dspapi.c | 108 ++++++++++----------- drivers/staging/tidspbridge/rmgr/dbdcd.c | 32 +++--- drivers/staging/tidspbridge/rmgr/disp.c | 24 ++--- drivers/staging/tidspbridge/rmgr/drv.c | 12 +-- drivers/staging/tidspbridge/rmgr/nldr.c | 8 +- drivers/staging/tidspbridge/rmgr/node.c | 58 +++++------ drivers/staging/tidspbridge/rmgr/strm.c | 24 ++--- 18 files changed, 220 insertions(+), 220 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c index c9470d331505..0986d8785e1b 100644 --- a/drivers/staging/tidspbridge/core/chnl_sm.c +++ b/drivers/staging/tidspbridge/core/chnl_sm.c @@ -604,7 +604,7 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, * translated to user's virtual addr later. */ host_sys_buf = chnl_packet_obj->host_sys_buf; - ioc.pbuf = chnl_packet_obj->host_user_buf; + ioc.buf = chnl_packet_obj->host_user_buf; ioc.byte_size = chnl_packet_obj->byte_size; ioc.buf_size = chnl_packet_obj->buf_size; ioc.arg = chnl_packet_obj->arg; @@ -613,7 +613,7 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, list_add_tail(&chnl_packet_obj->link, &pchnl->free_packets_list); } else { - ioc.pbuf = NULL; + ioc.buf = NULL; ioc.byte_size = 0; ioc.arg = 0; ioc.buf_size = 0; @@ -640,11 +640,11 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, spin_unlock_bh(&pchnl->chnl_mgr_obj->chnl_mgr_lock); if (dequeue_ioc && (pchnl->chnl_type == CHNL_PCPY && pchnl->chnl_id > 1)) { - if (!(ioc.pbuf < (void *)USERMODE_ADDR)) + if (!(ioc.buf < (void *)USERMODE_ADDR)) goto func_cont; /* If the addr is in user mode, then copy it */ - if (!host_sys_buf || !ioc.pbuf) { + if (!host_sys_buf || !ioc.buf) { status = -EFAULT; goto func_cont; } @@ -652,7 +652,7 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, goto func_cont1; /*host_user_buf */ - status = copy_to_user(ioc.pbuf, host_sys_buf, ioc.byte_size); + status = copy_to_user(ioc.buf, host_sys_buf, ioc.byte_size); if (status) { if (current->flags & PF_EXITING) status = 0; @@ -806,7 +806,7 @@ int bridge_chnl_open(struct chnl_object **chnl, pchnl->sync_event = sync_event; /* Get the process handle */ pchnl->process = current->tgid; - pchnl->pcb_arg = 0; + pchnl->cb_arg = 0; pchnl->bytes_moved = 0; /* Default to proc-copy */ pchnl->chnl_type = CHNL_PCPY; diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 96dbe1ae8c26..db8a43871e39 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -106,7 +106,7 @@ struct io_mgr { struct msg_ctrl *msg_output_ctrl; u8 *msg_input; /* Address of input messages */ u8 *msg_output; /* Address of output messages */ - u32 usm_buf_size; /* Size of a shared memory I/O channel */ + u32 sm_buf_size; /* Size of a shared memory I/O channel */ bool shared_irq; /* Is this IRQ shared? */ u32 word_size; /* Size in bytes of DSP word */ u16 intr_val; /* Interrupt value */ @@ -119,7 +119,7 @@ struct io_mgr { u32 trace_buffer_end; /* Trace message end address */ u32 trace_buffer_current; /* Trace message current address */ u32 gpp_read_pointer; /* GPP Read pointer to Trace buffer */ - u8 *pmsg; + u8 *msg; u32 gpp_va; u32 dsp_va; #endif @@ -247,7 +247,7 @@ int bridge_io_destroy(struct io_mgr *hio_mgr) tasklet_kill(&hio_mgr->dpc_tasklet); #if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG) - kfree(hio_mgr->pmsg); + kfree(hio_mgr->msg); #endif dsp_wdt_exit(); /* Free this IO manager object */ @@ -705,7 +705,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) hio_mgr->input = (u8 *) hio_mgr->shared_mem + sizeof(struct shm); hio_mgr->output = hio_mgr->input + (ul_shm_length - sizeof(struct shm)) / 2; - hio_mgr->usm_buf_size = hio_mgr->output - hio_mgr->input; + hio_mgr->sm_buf_size = hio_mgr->output - hio_mgr->input; /* Set up Shared memory addresses for messaging. */ hio_mgr->msg_input_ctrl = (struct msg_ctrl *)((u8 *) hio_mgr->shared_mem @@ -764,11 +764,11 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) (ul_gpp_va + ul_seg1_size + ul_pad_size) + (hio_mgr->trace_buffer_current - ul_dsp_va); /* Calculate the size of trace buffer */ - kfree(hio_mgr->pmsg); - hio_mgr->pmsg = kmalloc(((hio_mgr->trace_buffer_end - + kfree(hio_mgr->msg); + hio_mgr->msg = kmalloc(((hio_mgr->trace_buffer_end - hio_mgr->trace_buffer_begin) * hio_mgr->word_size) + 2, GFP_KERNEL); - if (!hio_mgr->pmsg) + if (!hio_mgr->msg) status = -ENOMEM; hio_mgr->dsp_va = ul_dsp_va; @@ -786,7 +786,7 @@ func_end: u32 io_buf_size(struct io_mgr *hio_mgr) { if (hio_mgr) - return hio_mgr->usm_buf_size; + return hio_mgr->sm_buf_size; else return 0; } @@ -1361,7 +1361,7 @@ static void output_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, chnl_mgr_obj->output_mask &= ~(1 << chnl_id); /* Transfer buffer to DSP side */ - chnl_packet_obj->byte_size = min(pio_mgr->usm_buf_size, + chnl_packet_obj->byte_size = min(pio_mgr->sm_buf_size, chnl_packet_obj->byte_size); memcpy(pio_mgr->output, chnl_packet_obj->host_sys_buf, chnl_packet_obj->byte_size); @@ -1704,30 +1704,30 @@ void print_dsp_debug_trace(struct io_mgr *hio_mgr) ul_new_message_length = ul_gpp_cur_pointer - hio_mgr->gpp_read_pointer; - memcpy(hio_mgr->pmsg, + memcpy(hio_mgr->msg, (char *)hio_mgr->gpp_read_pointer, ul_new_message_length); - hio_mgr->pmsg[ul_new_message_length] = '\0'; + hio_mgr->msg[ul_new_message_length] = '\0'; /* * Advance the GPP trace pointer to DSP current * pointer. */ hio_mgr->gpp_read_pointer += ul_new_message_length; /* Print the trace messages */ - pr_info("DSPTrace: %s\n", hio_mgr->pmsg); + pr_info("DSPTrace: %s\n", hio_mgr->msg); } else if (ul_gpp_cur_pointer < hio_mgr->gpp_read_pointer) { /* Handle trace buffer wraparound */ - memcpy(hio_mgr->pmsg, + memcpy(hio_mgr->msg, (char *)hio_mgr->gpp_read_pointer, hio_mgr->trace_buffer_end - hio_mgr->gpp_read_pointer); ul_new_message_length = ul_gpp_cur_pointer - hio_mgr->trace_buffer_begin; - memcpy(&hio_mgr->pmsg[hio_mgr->trace_buffer_end - + memcpy(&hio_mgr->msg[hio_mgr->trace_buffer_end - hio_mgr->gpp_read_pointer], (char *)hio_mgr->trace_buffer_begin, ul_new_message_length); - hio_mgr->pmsg[hio_mgr->trace_buffer_end - + hio_mgr->msg[hio_mgr->trace_buffer_end - hio_mgr->gpp_read_pointer + ul_new_message_length] = '\0'; /* @@ -1738,7 +1738,7 @@ void print_dsp_debug_trace(struct io_mgr *hio_mgr) hio_mgr->trace_buffer_begin + ul_new_message_length; /* Print the trace messages */ - pr_info("DSPTrace: %s\n", hio_mgr->pmsg); + pr_info("DSPTrace: %s\n", hio_mgr->msg); } } } diff --git a/drivers/staging/tidspbridge/dynload/cload.c b/drivers/staging/tidspbridge/dynload/cload.c index d0cd4453f175..390040984e03 100644 --- a/drivers/staging/tidspbridge/dynload/cload.c +++ b/drivers/staging/tidspbridge/dynload/cload.c @@ -498,8 +498,8 @@ static void allocate_sections(struct dload_state *dlthis) return; } /* initialize the handle header */ - hndl->dm.hnext = hndl->dm.hprev = hndl; /* circular list */ - hndl->dm.hroot = NULL; + hndl->dm.next = hndl->dm.prev = hndl; /* circular list */ + hndl->dm.root = NULL; hndl->dm.dbthis = 0; dlthis->myhandle = hndl; /* save away for return */ /* pointer to the section list of allocated sections */ @@ -1626,7 +1626,7 @@ static void init_module_handle(struct dload_state *dlthis) DL_ERROR(err_alloc, sizeof(struct dbg_mirror_root)); return; } - mlst->hnext = NULL; + mlst->next = NULL; mlst->changes = 0; mlst->refcount = 0; mlst->dbthis = TDATA_TO_TADDR(dlmodsym->value); @@ -1651,7 +1651,7 @@ static void init_module_handle(struct dload_state *dlthis) #else mlist = (struct dbg_mirror_root *)&debug_list_header; #endif - hndl->dm.hroot = mlist; /* set pointer to root into our handle */ + hndl->dm.root = mlist; /* set pointer to root into our handle */ if (!dlthis->allocated_secn_count) return; /* no load addresses to be recorded */ /* reuse temporary symbol storage */ @@ -1702,9 +1702,9 @@ static void init_module_handle(struct dload_state *dlthis) dllview_info.context = 0; hndl->dm.context = 0; /* fill in next pointer and size */ - if (mlist->hnext) { - dbmod->next_module = TADDR_TO_TDATA(mlist->hnext->dm.dbthis); - dbmod->next_module_size = mlist->hnext->dm.dbsiz; + if (mlist->next) { + dbmod->next_module = TADDR_TO_TDATA(mlist->next->dm.dbthis); + dbmod->next_module_size = mlist->next->dm.dbsiz; } else { dbmod->next_module_size = 0; dbmod->next_module = 0; @@ -1750,11 +1750,11 @@ static void init_module_handle(struct dload_state *dlthis) } /* Add the module handle to this processor's list of handles with debug info */ - hndl->dm.hnext = mlist->hnext; - if (hndl->dm.hnext) - hndl->dm.hnext->dm.hprev = hndl; - hndl->dm.hprev = (struct my_handle *)mlist; - mlist->hnext = hndl; /* insert after root */ + hndl->dm.next = mlist->next; + if (hndl->dm.next) + hndl->dm.next->dm.prev = hndl; + hndl->dm.prev = (struct my_handle *)mlist; + mlist->next = hndl; /* insert after root */ } /* init_module_handle */ /************************************************************************* @@ -1810,7 +1810,7 @@ int dynamic_unload_module(void *mhandle, asecs->name = NULL; alloc->dload_deallocate(alloc, asecs++); } - root = hndl->dm.hroot; + root = hndl->dm.root; if (!root) { /* there is a debug list containing this module */ goto func_end; @@ -1820,20 +1820,20 @@ int dynamic_unload_module(void *mhandle, } /* Retrieve memory context in which .dllview was allocated */ dllview_info.context = hndl->dm.context; - if (hndl->dm.hprev == hndl) + if (hndl->dm.prev == hndl) goto exitunltgt; /* target-side dllview record is in list */ /* dequeue this record from our GPP-side mirror list */ - hndl->dm.hprev->dm.hnext = hndl->dm.hnext; - if (hndl->dm.hnext) - hndl->dm.hnext->dm.hprev = hndl->dm.hprev; + hndl->dm.prev->dm.next = hndl->dm.next; + if (hndl->dm.next) + hndl->dm.next->dm.prev = hndl->dm.prev; /* Update next_module of previous entry in target list * We are using mhdr here as a surrogate for either a struct modules_header or a dll_module */ - if (hndl->dm.hnext) { - mhdr.first_module = TADDR_TO_TDATA(hndl->dm.hnext->dm.dbthis); - mhdr.first_module_size = hndl->dm.hnext->dm.dbsiz; + if (hndl->dm.next) { + mhdr.first_module = TADDR_TO_TDATA(hndl->dm.next->dm.dbthis); + mhdr.first_module_size = hndl->dm.next->dm.dbsiz; } else { mhdr.first_module = 0; mhdr.first_module_size = 0; @@ -1851,7 +1851,7 @@ int dynamic_unload_module(void *mhandle, swap_words(&mhdr, sizeof(struct modules_header) - sizeof(u16), MODULES_HEADER_BITMAP); } - if (!init->writemem(init, &mhdr, hndl->dm.hprev->dm.dbthis, + if (!init->writemem(init, &mhdr, hndl->dm.prev->dm.dbthis, &dllview_info, sizeof(struct modules_header) - sizeof(mhdr.update_flag))) { dload_syms_error(syms, dlvwrite); diff --git a/drivers/staging/tidspbridge/dynload/dload_internal.h b/drivers/staging/tidspbridge/dynload/dload_internal.h index 302a7c53e12c..7b77573fba53 100644 --- a/drivers/staging/tidspbridge/dynload/dload_internal.h +++ b/drivers/staging/tidspbridge/dynload/dload_internal.h @@ -78,15 +78,15 @@ struct my_handle; struct dbg_mirror_root { /* must be same as dbg_mirror_list; __DLModules address on target */ u32 dbthis; - struct my_handle *hnext; /* must be same as dbg_mirror_list */ + struct my_handle *next; /* must be same as dbg_mirror_list */ u16 changes; /* change counter */ u16 refcount; /* number of modules referencing this root */ }; struct dbg_mirror_list { u32 dbthis; - struct my_handle *hnext, *hprev; - struct dbg_mirror_root *hroot; + struct my_handle *next, *prev; + struct dbg_mirror_root *root; u16 dbsiz; u32 context; /* Save context for .dllview memory allocation */ }; diff --git a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h b/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h index 49326a643f06..9110cab6d637 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h +++ b/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h @@ -147,7 +147,7 @@ struct chnl_object { /* Abstract syncronization object */ struct sync_object *sync_event; u32 process; /* Process which created this channel */ - u32 pcb_arg; /* Argument to use with callback */ + u32 cb_arg; /* Argument to use with callback */ struct list_head pio_requests; /* List of IOR's to driver */ s32 cio_cs; /* Number of IOC's in queue */ s32 cio_reqs; /* Number of IORequests in queue */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h b/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h index 2cc27b5bcd0f..cb67c309b6ca 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/chnldefs.h @@ -45,7 +45,7 @@ struct chnl_attr { u32 uio_reqs; /* Max # of preallocated I/O requests. */ void *event_obj; /* User supplied auto-reset event object. */ - char *pstr_event_name; /* Ptr to name of user event object. */ + char *str_event_name; /* Ptr to name of user event object. */ void *reserved1; /* Reserved for future use. */ u32 reserved2; /* Reserved for future use. */ @@ -53,11 +53,11 @@ struct chnl_attr { /* I/O completion record: */ struct chnl_ioc { - void *pbuf; /* Buffer to be filled/emptied. */ + void *buf; /* Buffer to be filled/emptied. */ u32 byte_size; /* Bytes transferred. */ u32 buf_size; /* Actual buffer size in bytes */ u32 status; /* Status of IO completion. */ - u32 arg; /* User argument associated with pbuf. */ + u32 arg; /* User argument associated with buf. */ }; #endif /* CHNLDEFS_ */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h b/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h index f97266c33e9b..bc201b329033 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dbdcddef.h @@ -48,10 +48,10 @@ struct dcd_nodeprops { struct dsp_ndbprops ndb_props; u32 msg_segid; u32 msg_notify_type; - char *pstr_create_phase_fxn; - char *pstr_delete_phase_fxn; - char *pstr_execute_phase_fxn; - char *pstr_i_alg_name; + char *str_create_phase_fxn; + char *str_delete_phase_fxn; + char *str_execute_phase_fxn; + char *str_i_alg_name; /* Dynamic load properties */ u16 load_type; /* Static, dynamic, overlay */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h b/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h index 592c16d6a97f..c8f464505efc 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dbdefs.h @@ -232,7 +232,7 @@ struct dsp_strmattr { u32 timeout; /* Timeout for blocking STRM calls */ enum dsp_strmmode strm_mode; /* mode of stream when opened */ /* DMA chnl id if dsp_strmmode is LDMA or RDMA */ - u32 udma_chnl_id; + u32 dma_chnl_id; u32 dma_priority; /* DMA channel priority 0=lowest, >0=high */ }; @@ -340,7 +340,7 @@ struct dsp_nodeattr { * window handle. */ struct dsp_notification { - char *ps_name; + char *name; void *handle; }; @@ -406,7 +406,7 @@ struct dsp_streamattrin { u32 buf_alignment; u32 num_bufs; enum dsp_strmmode strm_mode; - u32 udma_chnl_id; + u32 dma_chnl_id; u32 dma_priority; }; diff --git a/drivers/staging/tidspbridge/include/dspbridge/drv.h b/drivers/staging/tidspbridge/include/dspbridge/drv.h index 3b98c1a41da6..bb044097323d 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/drv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/drv.h @@ -62,7 +62,7 @@ struct drv_object; /* New structure (member of process context) abstracts NODE resource info */ struct node_res_object { - void *hnode; + void *node; s32 node_allocated; /* Node status */ s32 heap_allocated; /* Heap status */ s32 streams_allocated; /* Streams status */ @@ -101,7 +101,7 @@ struct dmm_rsv_object { /* New structure (member of process context) abstracts stream resource info */ struct strm_res_object { s32 stream_allocated; /* Stream status */ - void *hstream; + void *stream; u32 num_bufs; u32 dir; int id; diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h index 1511922a7470..f43b3edb4be5 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h @@ -99,7 +99,7 @@ union trapped_args { struct { void *processor; - u8 __user *pbuf; + u8 __user *buf; u8 __user *psize; u32 max_size; } args_proc_gettrace; @@ -175,19 +175,19 @@ union trapped_args { } args_node_allocate; struct { - void *hnode; + void *node; u32 usize; struct dsp_bufferattr __user *pattr; - u8 *__user *pbuffer; + u8 *__user *buffer; } args_node_allocmsgbuf; struct { - void *hnode; + void *node; s32 prio; } args_node_changepriority; struct { - void *hnode; + void *node; u32 stream_id; void *other_node; u32 other_stream; @@ -196,54 +196,54 @@ union trapped_args { } args_node_connect; struct { - void *hnode; + void *node; } args_node_create; struct { - void *hnode; + void *node; } args_node_delete; struct { - void *hnode; + void *node; struct dsp_bufferattr __user *pattr; - u8 *pbuffer; + u8 *buffer; } args_node_freemsgbuf; struct { - void *hnode; + void *node; struct dsp_nodeattr __user *pattr; u32 attr_size; } args_node_getattr; struct { - void *hnode; + void *node; struct dsp_msg __user *message; u32 timeout; } args_node_getmessage; struct { - void *hnode; + void *node; } args_node_pause; struct { - void *hnode; + void *node; struct dsp_msg __user *message; u32 timeout; } args_node_putmessage; struct { - void *hnode; + void *node; u32 event_mask; u32 notify_type; struct dsp_notification __user *hnotification; } args_node_registernotify; struct { - void *hnode; + void *node; } args_node_run; struct { - void *hnode; + void *node; int __user *pstatus; } args_node_terminate; @@ -256,48 +256,48 @@ union trapped_args { /* STRM module */ struct { - void *hstream; + void *stream; u32 usize; u8 *__user *ap_buffer; u32 num_bufs; } args_strm_allocatebuffer; struct { - void *hstream; + void *stream; } args_strm_close; struct { - void *hstream; + void *stream; u8 *__user *ap_buffer; u32 num_bufs; } args_strm_freebuffer; struct { - void *hstream; + void *stream; void **ph_event; } args_strm_geteventhandle; struct { - void *hstream; + void *stream; struct stream_info __user *stream_info; u32 stream_info_size; } args_strm_getinfo; struct { - void *hstream; + void *stream; bool flush_flag; } args_strm_idle; struct { - void *hstream; - u8 *pbuffer; + void *stream; + u8 *buffer; u32 dw_bytes; u32 dw_buf_size; u32 arg; } args_strm_issue; struct { - void *hnode; + void *node; u32 direction; u32 index; struct strm_attr __user *attr_in; @@ -305,7 +305,7 @@ union trapped_args { } args_strm_open; struct { - void *hstream; + void *stream; u8 *__user *buf_ptr; u32 __user *bytes; u32 __user *buf_size_ptr; @@ -313,7 +313,7 @@ union trapped_args { } args_strm_reclaim; struct { - void *hstream; + void *stream; u32 event_mask; u32 notify_type; struct dsp_notification __user *hnotification; diff --git a/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h b/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h index 046259cdf445..4f90e6ba69ef 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h +++ b/drivers/staging/tidspbridge/include/dspbridge/strmdefs.h @@ -25,7 +25,7 @@ struct strm_object; struct strm_attr { void *user_event; - char *pstr_event_name; + char *str_event_name; void *virt_base; /* Process virtual base address of * mapped SM */ u32 virt_size; /* Size of virtual space in bytes */ diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c index 912a1f94fde7..1d86bd19d591 100644 --- a/drivers/staging/tidspbridge/pmgr/dspapi.c +++ b/drivers/staging/tidspbridge/pmgr/dspapi.c @@ -813,7 +813,7 @@ u32 procwrap_get_trace(union trapped_args *args, void *pr_ctxt) } else { status = -ENOMEM; } - CP_TO_USR(args->args_proc_gettrace.pbuf, pbuf, status, + CP_TO_USR(args->args_proc_gettrace.buf, pbuf, status, args->args_proc_gettrace.max_size); kfree(pbuf); @@ -978,7 +978,7 @@ u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt) void *hprocessor = ((struct process_context *)pr_ctxt)->processor; /* Initialize the notification data structure */ - notification.ps_name = NULL; + notification.name = NULL; notification.handle = NULL; status = proc_register_notify(hprocessor, @@ -1154,7 +1154,7 @@ u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt) struct node_res_object *node_res; find_node_handle(&node_res, pr_ctxt, - args->args_node_allocmsgbuf.hnode); + args->args_node_allocmsgbuf.node); if (!node_res) return -EFAULT; @@ -1169,13 +1169,13 @@ u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt) } /* argument */ - CP_FM_USR(&pbuffer, args->args_node_allocmsgbuf.pbuffer, status, 1); + CP_FM_USR(&pbuffer, args->args_node_allocmsgbuf.buffer, status, 1); if (!status) { - status = node_alloc_msg_buf(node_res->hnode, + status = node_alloc_msg_buf(node_res->node, args->args_node_allocmsgbuf.usize, pattr, &pbuffer); } - CP_TO_USR(args->args_node_allocmsgbuf.pbuffer, &pbuffer, status, 1); + CP_TO_USR(args->args_node_allocmsgbuf.buffer, &pbuffer, status, 1); return status; } @@ -1188,12 +1188,12 @@ u32 nodewrap_change_priority(union trapped_args *args, void *pr_ctxt) struct node_res_object *node_res; find_node_handle(&node_res, pr_ctxt, - args->args_node_changepriority.hnode); + args->args_node_changepriority.node); if (!node_res) return -EFAULT; - ret = node_change_priority(node_res->hnode, + ret = node_change_priority(node_res->node, args->args_node_changepriority.prio); return ret; @@ -1213,20 +1213,20 @@ u32 nodewrap_connect(union trapped_args *args, void *pr_ctxt) struct node_res_object *node_res1, *node_res2; struct node_object *node1 = NULL, *node2 = NULL; - if ((int)args->args_node_connect.hnode != DSP_HGPPNODE) { + if ((int)args->args_node_connect.node != DSP_HGPPNODE) { find_node_handle(&node_res1, pr_ctxt, - args->args_node_connect.hnode); + args->args_node_connect.node); if (node_res1) - node1 = node_res1->hnode; + node1 = node_res1->node; } else { - node1 = args->args_node_connect.hnode; + node1 = args->args_node_connect.node; } if ((int)args->args_node_connect.other_node != DSP_HGPPNODE) { find_node_handle(&node_res2, pr_ctxt, args->args_node_connect.other_node); if (node_res2) - node2 = node_res2->hnode; + node2 = node_res2->node; } else { node2 = args->args_node_connect.other_node; } @@ -1280,12 +1280,12 @@ u32 nodewrap_create(union trapped_args *args, void *pr_ctxt) u32 ret; struct node_res_object *node_res; - find_node_handle(&node_res, pr_ctxt, args->args_node_create.hnode); + find_node_handle(&node_res, pr_ctxt, args->args_node_create.node); if (!node_res) return -EFAULT; - ret = node_create(node_res->hnode); + ret = node_create(node_res->node); return ret; } @@ -1298,7 +1298,7 @@ u32 nodewrap_delete(union trapped_args *args, void *pr_ctxt) u32 ret; struct node_res_object *node_res; - find_node_handle(&node_res, pr_ctxt, args->args_node_delete.hnode); + find_node_handle(&node_res, pr_ctxt, args->args_node_delete.node); if (!node_res) return -EFAULT; @@ -1318,7 +1318,7 @@ u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt) struct dsp_bufferattr attr; struct node_res_object *node_res; - find_node_handle(&node_res, pr_ctxt, args->args_node_freemsgbuf.hnode); + find_node_handle(&node_res, pr_ctxt, args->args_node_freemsgbuf.node); if (!node_res) return -EFAULT; @@ -1330,12 +1330,12 @@ u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt) } - if (!args->args_node_freemsgbuf.pbuffer) + if (!args->args_node_freemsgbuf.buffer) return -EFAULT; if (!status) { - status = node_free_msg_buf(node_res->hnode, - args->args_node_freemsgbuf.pbuffer, + status = node_free_msg_buf(node_res->node, + args->args_node_freemsgbuf.buffer, pattr); } @@ -1351,12 +1351,12 @@ u32 nodewrap_get_attr(union trapped_args *args, void *pr_ctxt) struct dsp_nodeattr attr; struct node_res_object *node_res; - find_node_handle(&node_res, pr_ctxt, args->args_node_getattr.hnode); + find_node_handle(&node_res, pr_ctxt, args->args_node_getattr.node); if (!node_res) return -EFAULT; - status = node_get_attr(node_res->hnode, &attr, + status = node_get_attr(node_res->node, &attr, args->args_node_getattr.attr_size); CP_TO_USR(args->args_node_getattr.pattr, &attr, status, 1); @@ -1372,12 +1372,12 @@ u32 nodewrap_get_message(union trapped_args *args, void *pr_ctxt) struct dsp_msg msg; struct node_res_object *node_res; - find_node_handle(&node_res, pr_ctxt, args->args_node_getmessage.hnode); + find_node_handle(&node_res, pr_ctxt, args->args_node_getmessage.node); if (!node_res) return -EFAULT; - status = node_get_message(node_res->hnode, &msg, + status = node_get_message(node_res->node, &msg, args->args_node_getmessage.timeout); CP_TO_USR(args->args_node_getmessage.message, &msg, status, 1); @@ -1393,12 +1393,12 @@ u32 nodewrap_pause(union trapped_args *args, void *pr_ctxt) u32 ret; struct node_res_object *node_res; - find_node_handle(&node_res, pr_ctxt, args->args_node_pause.hnode); + find_node_handle(&node_res, pr_ctxt, args->args_node_pause.node); if (!node_res) return -EFAULT; - ret = node_pause(node_res->hnode); + ret = node_pause(node_res->node); return ret; } @@ -1412,7 +1412,7 @@ u32 nodewrap_put_message(union trapped_args *args, void *pr_ctxt) struct dsp_msg msg; struct node_res_object *node_res; - find_node_handle(&node_res, pr_ctxt, args->args_node_putmessage.hnode); + find_node_handle(&node_res, pr_ctxt, args->args_node_putmessage.node); if (!node_res) return -EFAULT; @@ -1421,7 +1421,7 @@ u32 nodewrap_put_message(union trapped_args *args, void *pr_ctxt) if (!status) { status = - node_put_message(node_res->hnode, &msg, + node_put_message(node_res->node, &msg, args->args_node_putmessage.timeout); } @@ -1438,13 +1438,13 @@ u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt) struct node_res_object *node_res; find_node_handle(&node_res, pr_ctxt, - args->args_node_registernotify.hnode); + args->args_node_registernotify.node); if (!node_res) return -EFAULT; /* Initialize the notification data structure */ - notification.ps_name = NULL; + notification.name = NULL; notification.handle = NULL; if (!args->args_proc_register_notify.event_mask) @@ -1452,7 +1452,7 @@ u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt) args->args_proc_register_notify.hnotification, status, 1); - status = node_register_notify(node_res->hnode, + status = node_register_notify(node_res->node, args->args_node_registernotify.event_mask, args->args_node_registernotify. notify_type, ¬ification); @@ -1469,12 +1469,12 @@ u32 nodewrap_run(union trapped_args *args, void *pr_ctxt) u32 ret; struct node_res_object *node_res; - find_node_handle(&node_res, pr_ctxt, args->args_node_run.hnode); + find_node_handle(&node_res, pr_ctxt, args->args_node_run.node); if (!node_res) return -EFAULT; - ret = node_run(node_res->hnode); + ret = node_run(node_res->node); return ret; } @@ -1488,12 +1488,12 @@ u32 nodewrap_terminate(union trapped_args *args, void *pr_ctxt) int tempstatus; struct node_res_object *node_res; - find_node_handle(&node_res, pr_ctxt, args->args_node_terminate.hnode); + find_node_handle(&node_res, pr_ctxt, args->args_node_terminate.node); if (!node_res) return -EFAULT; - status = node_terminate(node_res->hnode, &tempstatus); + status = node_terminate(node_res->node, &tempstatus); CP_TO_USR(args->args_node_terminate.pstatus, &tempstatus, status, 1); @@ -1551,7 +1551,7 @@ u32 strmwrap_allocate_buffer(union trapped_args *args, void *pr_ctxt) struct strm_res_object *strm_res; find_strm_handle(&strm_res, pr_ctxt, - args->args_strm_allocatebuffer.hstream); + args->args_strm_allocatebuffer.stream); if (!strm_res) return -EFAULT; @@ -1587,7 +1587,7 @@ u32 strmwrap_close(union trapped_args *args, void *pr_ctxt) { struct strm_res_object *strm_res; - find_strm_handle(&strm_res, pr_ctxt, args->args_strm_close.hstream); + find_strm_handle(&strm_res, pr_ctxt, args->args_strm_close.stream); if (!strm_res) return -EFAULT; @@ -1606,7 +1606,7 @@ u32 strmwrap_free_buffer(union trapped_args *args, void *pr_ctxt) struct strm_res_object *strm_res; find_strm_handle(&strm_res, pr_ctxt, - args->args_strm_freebuffer.hstream); + args->args_strm_freebuffer.stream); if (!strm_res) return -EFAULT; @@ -1654,7 +1654,7 @@ u32 strmwrap_get_info(union trapped_args *args, void *pr_ctxt) struct strm_res_object *strm_res; find_strm_handle(&strm_res, pr_ctxt, - args->args_strm_getinfo.hstream); + args->args_strm_getinfo.stream); if (!strm_res) return -EFAULT; @@ -1665,7 +1665,7 @@ u32 strmwrap_get_info(union trapped_args *args, void *pr_ctxt) strm_info.user_strm = &user; if (!status) { - status = strm_get_info(strm_res->hstream, + status = strm_get_info(strm_res->stream, &strm_info, args->args_strm_getinfo. stream_info_size); @@ -1684,12 +1684,12 @@ u32 strmwrap_idle(union trapped_args *args, void *pr_ctxt) u32 ret; struct strm_res_object *strm_res; - find_strm_handle(&strm_res, pr_ctxt, args->args_strm_idle.hstream); + find_strm_handle(&strm_res, pr_ctxt, args->args_strm_idle.stream); if (!strm_res) return -EFAULT; - ret = strm_idle(strm_res->hstream, args->args_strm_idle.flush_flag); + ret = strm_idle(strm_res->stream, args->args_strm_idle.flush_flag); return ret; } @@ -1702,19 +1702,19 @@ u32 strmwrap_issue(union trapped_args *args, void *pr_ctxt) int status = 0; struct strm_res_object *strm_res; - find_strm_handle(&strm_res, pr_ctxt, args->args_strm_issue.hstream); + find_strm_handle(&strm_res, pr_ctxt, args->args_strm_issue.stream); if (!strm_res) return -EFAULT; - if (!args->args_strm_issue.pbuffer) + if (!args->args_strm_issue.buffer) return -EFAULT; /* No need of doing CP_FM_USR for the user buffer (pbuffer) as this is done in Bridge internal function bridge_chnl_add_io_req in chnl_sm.c */ - status = strm_issue(strm_res->hstream, - args->args_strm_issue.pbuffer, + status = strm_issue(strm_res->stream, + args->args_strm_issue.buffer, args->args_strm_issue.dw_bytes, args->args_strm_issue.dw_buf_size, args->args_strm_issue.arg); @@ -1734,7 +1734,7 @@ u32 strmwrap_open(union trapped_args *args, void *pr_ctxt) struct node_res_object *node_res; int strmid; - find_node_handle(&node_res, pr_ctxt, args->args_strm_open.hnode); + find_node_handle(&node_res, pr_ctxt, args->args_strm_open.node); if (!node_res) return -EFAULT; @@ -1750,7 +1750,7 @@ u32 strmwrap_open(union trapped_args *args, void *pr_ctxt) } } - status = strm_open(node_res->hnode, + status = strm_open(node_res->node, args->args_strm_open.direction, args->args_strm_open.index, &attr, &strm_res_obj, pr_ctxt); @@ -1773,12 +1773,12 @@ u32 strmwrap_reclaim(union trapped_args *args, void *pr_ctxt) u32 ul_buf_size; struct strm_res_object *strm_res; - find_strm_handle(&strm_res, pr_ctxt, args->args_strm_reclaim.hstream); + find_strm_handle(&strm_res, pr_ctxt, args->args_strm_reclaim.stream); if (!strm_res) return -EFAULT; - status = strm_reclaim(strm_res->hstream, &buf_ptr, + status = strm_reclaim(strm_res->stream, &buf_ptr, &ul_bytes, &ul_buf_size, &dw_arg); CP_TO_USR(args->args_strm_reclaim.buf_ptr, &buf_ptr, status, 1); CP_TO_USR(args->args_strm_reclaim.bytes, &ul_bytes, status, 1); @@ -1802,16 +1802,16 @@ u32 strmwrap_register_notify(union trapped_args *args, void *pr_ctxt) struct strm_res_object *strm_res; find_strm_handle(&strm_res, pr_ctxt, - args->args_strm_registernotify.hstream); + args->args_strm_registernotify.stream); if (!strm_res) return -EFAULT; /* Initialize the notification data structure */ - notification.ps_name = NULL; + notification.name = NULL; notification.handle = NULL; - status = strm_register_notify(strm_res->hstream, + status = strm_register_notify(strm_res->stream, args->args_strm_registernotify.event_mask, args->args_strm_registernotify. notify_type, ¬ification); @@ -1848,7 +1848,7 @@ u32 strmwrap_select(union trapped_args *args, void *pr_ctxt) if (!strm_res) return -EFAULT; - strm_tab[i] = strm_res->hstream; + strm_tab[i] = strm_res->stream; } if (!status) { diff --git a/drivers/staging/tidspbridge/rmgr/dbdcd.c b/drivers/staging/tidspbridge/rmgr/dbdcd.c index 1e77c12be404..a7e407e25187 100644 --- a/drivers/staging/tidspbridge/rmgr/dbdcd.c +++ b/drivers/staging/tidspbridge/rmgr/dbdcd.c @@ -1166,36 +1166,36 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size, gen_obj->obj_data.node_obj.ndb_props.timeout = atoi(token); token = strsep(&psz_cur, seps); - /* char *pstr_create_phase_fxn */ + /* char *str_create_phase_fxn */ DBC_REQUIRE(token); token_len = strlen(token); - gen_obj->obj_data.node_obj.pstr_create_phase_fxn = + gen_obj->obj_data.node_obj.str_create_phase_fxn = kzalloc(token_len + 1, GFP_KERNEL); - strncpy(gen_obj->obj_data.node_obj.pstr_create_phase_fxn, + strncpy(gen_obj->obj_data.node_obj.str_create_phase_fxn, token, token_len); - gen_obj->obj_data.node_obj.pstr_create_phase_fxn[token_len] = + gen_obj->obj_data.node_obj.str_create_phase_fxn[token_len] = '\0'; token = strsep(&psz_cur, seps); - /* char *pstr_execute_phase_fxn */ + /* char *str_execute_phase_fxn */ DBC_REQUIRE(token); token_len = strlen(token); - gen_obj->obj_data.node_obj.pstr_execute_phase_fxn = + gen_obj->obj_data.node_obj.str_execute_phase_fxn = kzalloc(token_len + 1, GFP_KERNEL); - strncpy(gen_obj->obj_data.node_obj.pstr_execute_phase_fxn, + strncpy(gen_obj->obj_data.node_obj.str_execute_phase_fxn, token, token_len); - gen_obj->obj_data.node_obj.pstr_execute_phase_fxn[token_len] = + gen_obj->obj_data.node_obj.str_execute_phase_fxn[token_len] = '\0'; token = strsep(&psz_cur, seps); - /* char *pstr_delete_phase_fxn */ + /* char *str_delete_phase_fxn */ DBC_REQUIRE(token); token_len = strlen(token); - gen_obj->obj_data.node_obj.pstr_delete_phase_fxn = + gen_obj->obj_data.node_obj.str_delete_phase_fxn = kzalloc(token_len + 1, GFP_KERNEL); - strncpy(gen_obj->obj_data.node_obj.pstr_delete_phase_fxn, + strncpy(gen_obj->obj_data.node_obj.str_delete_phase_fxn, token, token_len); - gen_obj->obj_data.node_obj.pstr_delete_phase_fxn[token_len] = + gen_obj->obj_data.node_obj.str_delete_phase_fxn[token_len] = '\0'; token = strsep(&psz_cur, seps); @@ -1207,14 +1207,14 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size, gen_obj->obj_data.node_obj.msg_notify_type = atoi(token); token = strsep(&psz_cur, seps); - /* char *pstr_i_alg_name */ + /* char *str_i_alg_name */ if (token) { token_len = strlen(token); - gen_obj->obj_data.node_obj.pstr_i_alg_name = + gen_obj->obj_data.node_obj.str_i_alg_name = kzalloc(token_len + 1, GFP_KERNEL); - strncpy(gen_obj->obj_data.node_obj.pstr_i_alg_name, + strncpy(gen_obj->obj_data.node_obj.str_i_alg_name, token, token_len); - gen_obj->obj_data.node_obj.pstr_i_alg_name[token_len] = + gen_obj->obj_data.node_obj.str_i_alg_name[token_len] = '\0'; token = strsep(&psz_cur, seps); } diff --git a/drivers/staging/tidspbridge/rmgr/disp.c b/drivers/staging/tidspbridge/rmgr/disp.c index d38ea2d159f1..a9aa22f3b4f6 100644 --- a/drivers/staging/tidspbridge/rmgr/disp.c +++ b/drivers/staging/tidspbridge/rmgr/disp.c @@ -64,7 +64,7 @@ struct disp_object { struct chnl_mgr *chnl_mgr; /* Channel manager */ struct chnl_object *chnl_to_dsp; /* Chnl for commands to RMS */ struct chnl_object *chnl_from_dsp; /* Chnl for replies from RMS */ - u8 *pbuf; /* Buffer for commands, replies */ + u8 *buf; /* Buffer for commands, replies */ u32 bufsize; /* buf size in bytes */ u32 bufsize_rms; /* buf size in RMS words */ u32 char_size; /* Size of DSP character */ @@ -158,8 +158,8 @@ int disp_create(struct disp_object **dispatch_obj, /* Allocate buffer for commands, replies */ disp_obj->bufsize = disp_attrs->chnl_buf_size; disp_obj->bufsize_rms = RMS_COMMANDBUFSIZE; - disp_obj->pbuf = kzalloc(disp_obj->bufsize, GFP_KERNEL); - if (disp_obj->pbuf == NULL) + disp_obj->buf = kzalloc(disp_obj->bufsize, GFP_KERNEL); + if (disp_obj->buf == NULL) status = -ENOMEM; } func_cont: @@ -232,7 +232,7 @@ int disp_node_change_priority(struct disp_object *disp_obj, DBC_REQUIRE(hnode != NULL); /* Send message to RMS to change priority */ - rms_cmd = (struct rms_command *)(disp_obj->pbuf); + rms_cmd = (struct rms_command *)(disp_obj->buf); rms_cmd->fxn = (rms_word) (rms_fxn); rms_cmd->arg1 = (rms_word) node_env; rms_cmd->arg2 = prio; @@ -347,7 +347,7 @@ int disp_node_create(struct disp_object *disp_obj, */ if (!status) { total = 0; /* Total number of words in buffer so far */ - pdw_buf = (rms_word *) disp_obj->pbuf; + pdw_buf = (rms_word *) disp_obj->buf; rms_cmd = (struct rms_command *)pdw_buf; rms_cmd->fxn = (rms_word) (rms_fxn); rms_cmd->arg1 = (rms_word) (ul_create_fxn); @@ -493,7 +493,7 @@ int disp_node_delete(struct disp_object *disp_obj, /* * Fill in buffer to send to RMS */ - rms_cmd = (struct rms_command *)disp_obj->pbuf; + rms_cmd = (struct rms_command *)disp_obj->buf; rms_cmd->fxn = (rms_word) (rms_fxn); rms_cmd->arg1 = (rms_word) node_env; rms_cmd->arg2 = (rms_word) (ul_delete_fxn); @@ -534,7 +534,7 @@ int disp_node_run(struct disp_object *disp_obj, /* * Fill in buffer to send to RMS. */ - rms_cmd = (struct rms_command *)disp_obj->pbuf; + rms_cmd = (struct rms_command *)disp_obj->buf; rms_cmd->fxn = (rms_word) (rms_fxn); rms_cmd->arg1 = (rms_word) node_env; rms_cmd->arg2 = (rms_word) (ul_execute_fxn); @@ -582,7 +582,7 @@ static void delete_disp(struct disp_object *disp_obj) " RMS: 0x%x\n", __func__, status); } } - kfree(disp_obj->pbuf); + kfree(disp_obj->buf); kfree(disp_obj); } @@ -664,7 +664,7 @@ static int send_message(struct disp_object *disp_obj, u32 timeout, *pdw_arg = (u32) NULL; intf_fxns = disp_obj->intf_fxns; chnl_obj = disp_obj->chnl_to_dsp; - pbuf = disp_obj->pbuf; + pbuf = disp_obj->buf; /* Send the command */ status = (*intf_fxns->chnl_add_io_req) (chnl_obj, pbuf, ul_bytes, 0, @@ -703,8 +703,8 @@ static int send_message(struct disp_object *disp_obj, u32 timeout, status = -EPERM; } else { if (CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) { - DBC_ASSERT(chnl_ioc_obj.pbuf == pbuf); - if (*((int *)chnl_ioc_obj.pbuf) < 0) { + DBC_ASSERT(chnl_ioc_obj.buf == pbuf); + if (*((int *)chnl_ioc_obj.buf) < 0) { /* Translate DSP's to kernel error */ status = -EREMOTEIO; dev_dbg(bridge, "%s: DSP-side failed:" @@ -713,7 +713,7 @@ static int send_message(struct disp_object *disp_obj, u32 timeout, *(int *)pbuf, status); } *pdw_arg = - (((rms_word *) (chnl_ioc_obj.pbuf))[1]); + (((rms_word *) (chnl_ioc_obj.buf))[1]); } else { status = -EPERM; } diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c index ce5f398f6480..8c88583364eb 100644 --- a/drivers/staging/tidspbridge/rmgr/drv.c +++ b/drivers/staging/tidspbridge/rmgr/drv.c @@ -89,7 +89,7 @@ int drv_insert_node_res_element(void *hnode, void *node_resource, goto func_end; } - (*node_res_obj)->hnode = hnode; + (*node_res_obj)->node = hnode; retval = idr_get_new(ctxt->node_id, *node_res_obj, &(*node_res_obj)->id); if (retval == -EAGAIN) { @@ -123,13 +123,13 @@ static int drv_proc_free_node_res(int id, void *p, void *data) u32 node_state; if (node_res_obj->node_allocated) { - node_state = node_get_state(node_res_obj->hnode); + node_state = node_get_state(node_res_obj->node); if (node_state <= NODE_DELETING) { if ((node_state == NODE_RUNNING) || (node_state == NODE_PAUSED) || (node_state == NODE_TERMINATING)) node_terminate - (node_res_obj->hnode, &status); + (node_res_obj->node, &status); node_delete(node_res_obj, ctxt); } @@ -216,7 +216,7 @@ int drv_proc_insert_strm_res_element(void *stream_obj, goto func_end; } - (*pstrm_res)->hstream = stream_obj; + (*pstrm_res)->stream = stream_obj; retval = idr_get_new(ctxt->stream_id, *pstrm_res, &(*pstrm_res)->id); if (retval == -EAGAIN) { @@ -263,9 +263,9 @@ static int drv_proc_free_strm_res(int id, void *p, void *process_ctxt) } strm_info.user_strm = &user; user.number_bufs_in_stream = 0; - strm_get_info(strm_res->hstream, &strm_info, sizeof(strm_info)); + strm_get_info(strm_res->stream, &strm_info, sizeof(strm_info)); while (user.number_bufs_in_stream--) - strm_reclaim(strm_res->hstream, &buf_ptr, &ul_bytes, + strm_reclaim(strm_res->stream, &buf_ptr, &ul_bytes, (u32 *) &ul_buf_size, &dw_arg); strm_close(strm_res, ctxt); return 0; diff --git a/drivers/staging/tidspbridge/rmgr/nldr.c b/drivers/staging/tidspbridge/rmgr/nldr.c index e711970b160f..fb5c2ba01d47 100644 --- a/drivers/staging/tidspbridge/rmgr/nldr.c +++ b/drivers/staging/tidspbridge/rmgr/nldr.c @@ -1035,13 +1035,13 @@ static int add_ovly_node(struct dsp_uuid *uuid_obj, } } /* These were allocated in dcd_get_object_def */ - kfree(obj_def.obj_data.node_obj.pstr_create_phase_fxn); + kfree(obj_def.obj_data.node_obj.str_create_phase_fxn); - kfree(obj_def.obj_data.node_obj.pstr_execute_phase_fxn); + kfree(obj_def.obj_data.node_obj.str_execute_phase_fxn); - kfree(obj_def.obj_data.node_obj.pstr_delete_phase_fxn); + kfree(obj_def.obj_data.node_obj.str_delete_phase_fxn); - kfree(obj_def.obj_data.node_obj.pstr_i_alg_name); + kfree(obj_def.obj_data.node_obj.str_i_alg_name); func_end: return status; diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index c627560a6c40..565383774b6e 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -209,7 +209,7 @@ struct node_object { struct dcd_genericobj dcd_props; /* Node properties from DCD */ struct dsp_cbdata *pargs; /* Optional args to pass to node */ struct ntfy_object *ntfy_obj; /* Manages registered notifications */ - char *pstr_dev_name; /* device name, if device node */ + char *str_dev_name; /* device name, if device node */ struct sync_object *sync_done; /* Synchronize node_terminate */ s32 exit_status; /* execute function return status */ @@ -1060,7 +1060,7 @@ int node_connect(struct node_object *node1, u32 stream1, } /* Set up create args */ pstream->type = DEVICECONNECT; - dw_length = strlen(dev_node_obj->pstr_dev_name); + dw_length = strlen(dev_node_obj->str_dev_name); if (conn_param) pstrm_def->sz_device = kzalloc(dw_length + 1 + conn_param->cb_data, @@ -1074,7 +1074,7 @@ int node_connect(struct node_object *node1, u32 stream1, } /* Copy device name */ strncpy(pstrm_def->sz_device, - dev_node_obj->pstr_dev_name, dw_length); + dev_node_obj->str_dev_name, dw_length); if (conn_param) strncat(pstrm_def->sz_device, (char *)conn_param->node_data, @@ -1214,7 +1214,7 @@ int node_create(struct node_object *hnode) status = hnode_mgr->nldr_fxns.get_fxn_addr (hnode->nldr_node_obj, hnode->dcd_props.obj_data.node_obj. - pstr_i_alg_name, + str_i_alg_name, &hnode->create_args.asa. task_arg_obj.dais_arg); } @@ -1393,7 +1393,7 @@ out_err: int node_delete(struct node_res_object *noderes, struct process_context *pr_ctxt) { - struct node_object *pnode = noderes->hnode; + struct node_object *pnode = noderes->node; struct node_mgr *hnode_mgr; struct proc_object *hprocessor; struct disp_object *disp_obj; @@ -2541,8 +2541,8 @@ static void delete_node(struct node_object *hnode, kfree(hnode->stream_connect); hnode->stream_connect = NULL; } - kfree(hnode->pstr_dev_name); - hnode->pstr_dev_name = NULL; + kfree(hnode->str_dev_name); + hnode->str_dev_name = NULL; if (hnode->ntfy_obj) { ntfy_delete(hnode->ntfy_obj); @@ -2551,17 +2551,17 @@ static void delete_node(struct node_object *hnode, } /* These were allocated in dcd_get_object_def (via node_allocate) */ - kfree(hnode->dcd_props.obj_data.node_obj.pstr_create_phase_fxn); - hnode->dcd_props.obj_data.node_obj.pstr_create_phase_fxn = NULL; + kfree(hnode->dcd_props.obj_data.node_obj.str_create_phase_fxn); + hnode->dcd_props.obj_data.node_obj.str_create_phase_fxn = NULL; - kfree(hnode->dcd_props.obj_data.node_obj.pstr_execute_phase_fxn); - hnode->dcd_props.obj_data.node_obj.pstr_execute_phase_fxn = NULL; + kfree(hnode->dcd_props.obj_data.node_obj.str_execute_phase_fxn); + hnode->dcd_props.obj_data.node_obj.str_execute_phase_fxn = NULL; - kfree(hnode->dcd_props.obj_data.node_obj.pstr_delete_phase_fxn); - hnode->dcd_props.obj_data.node_obj.pstr_delete_phase_fxn = NULL; + kfree(hnode->dcd_props.obj_data.node_obj.str_delete_phase_fxn); + hnode->dcd_props.obj_data.node_obj.str_delete_phase_fxn = NULL; - kfree(hnode->dcd_props.obj_data.node_obj.pstr_i_alg_name); - hnode->dcd_props.obj_data.node_obj.pstr_i_alg_name = NULL; + kfree(hnode->dcd_props.obj_data.node_obj.str_i_alg_name); + hnode->dcd_props.obj_data.node_obj.str_i_alg_name = NULL; /* Free all SM address translator resources */ kfree(hnode->xlator); @@ -2755,15 +2755,15 @@ static int get_fxn_address(struct node_object *hnode, u32 * fxn_addr, switch (phase) { case CREATEPHASE: pstr_fxn_name = - hnode->dcd_props.obj_data.node_obj.pstr_create_phase_fxn; + hnode->dcd_props.obj_data.node_obj.str_create_phase_fxn; break; case EXECUTEPHASE: pstr_fxn_name = - hnode->dcd_props.obj_data.node_obj.pstr_execute_phase_fxn; + hnode->dcd_props.obj_data.node_obj.str_execute_phase_fxn; break; case DELETEPHASE: pstr_fxn_name = - hnode->dcd_props.obj_data.node_obj.pstr_delete_phase_fxn; + hnode->dcd_props.obj_data.node_obj.str_delete_phase_fxn; break; default: /* Should never get here */ @@ -2851,11 +2851,11 @@ static int get_node_props(struct dcd_manager *hdcd_mgr, DBC_REQUIRE(pndb_props->ac_name); len = strlen(pndb_props->ac_name); DBC_ASSERT(len < MAXDEVNAMELEN); - hnode->pstr_dev_name = kzalloc(len + 1, GFP_KERNEL); - if (hnode->pstr_dev_name == NULL) { + hnode->str_dev_name = kzalloc(len + 1, GFP_KERNEL); + if (hnode->str_dev_name == NULL) { status = -ENOMEM; } else { - strncpy(hnode->pstr_dev_name, + strncpy(hnode->str_dev_name, pndb_props->ac_name, len); } } @@ -2974,10 +2974,10 @@ int node_get_uuid_props(void *hprocessor, */ mutex_lock(&hnode_mgr->node_mgr_lock); - dcd_node_props.pstr_create_phase_fxn = NULL; - dcd_node_props.pstr_execute_phase_fxn = NULL; - dcd_node_props.pstr_delete_phase_fxn = NULL; - dcd_node_props.pstr_i_alg_name = NULL; + dcd_node_props.str_create_phase_fxn = NULL; + dcd_node_props.str_execute_phase_fxn = NULL; + dcd_node_props.str_delete_phase_fxn = NULL; + dcd_node_props.str_i_alg_name = NULL; status = dcd_get_object_def(hnode_mgr->dcd_mgr, (struct dsp_uuid *)node_uuid, DSP_DCDNODETYPE, @@ -2985,13 +2985,13 @@ int node_get_uuid_props(void *hprocessor, if (!status) { *node_props = dcd_node_props.ndb_props; - kfree(dcd_node_props.pstr_create_phase_fxn); + kfree(dcd_node_props.str_create_phase_fxn); - kfree(dcd_node_props.pstr_execute_phase_fxn); + kfree(dcd_node_props.str_execute_phase_fxn); - kfree(dcd_node_props.pstr_delete_phase_fxn); + kfree(dcd_node_props.str_delete_phase_fxn); - kfree(dcd_node_props.pstr_i_alg_name); + kfree(dcd_node_props.str_i_alg_name); } /* Leave the critical section, we're done. */ mutex_unlock(&hnode_mgr->node_mgr_lock); diff --git a/drivers/staging/tidspbridge/rmgr/strm.c b/drivers/staging/tidspbridge/rmgr/strm.c index cc7370c45d14..3fae0e9f511e 100644 --- a/drivers/staging/tidspbridge/rmgr/strm.c +++ b/drivers/staging/tidspbridge/rmgr/strm.c @@ -70,13 +70,13 @@ struct strm_object { u32 dir; /* DSP_TONODE or DSP_FROMNODE */ u32 timeout; u32 num_bufs; /* Max # of bufs allowed in stream */ - u32 un_bufs_in_strm; /* Current # of bufs in stream */ + u32 bufs_in_strm; /* Current # of bufs in stream */ u32 bytes; /* bytes transferred since idled */ /* STREAM_IDLE, STREAM_READY, ... */ enum dsp_streamstate strm_state; void *user_event; /* Saved for strm_get_info() */ enum dsp_strmmode strm_mode; /* STRMMODE_[PROCCOPY][ZEROCOPY]... */ - u32 udma_chnl_id; /* DMA chnl id */ + u32 dma_chnl_id; /* DMA chnl id */ u32 dma_priority; /* DMA priority:DMAPRI_[LOW][HIGH] */ u32 segment_id; /* >0 is SM segment.=0 is local heap */ u32 buf_alignment; /* Alignment for stream bufs */ @@ -102,7 +102,7 @@ int strm_allocate_buffer(struct strm_res_object *strmres, u32 usize, int status = 0; u32 alloc_cnt = 0; u32 i; - struct strm_object *stream_obj = strmres->hstream; + struct strm_object *stream_obj = strmres->stream; DBC_REQUIRE(refs > 0); DBC_REQUIRE(ap_buffer != NULL); @@ -154,7 +154,7 @@ int strm_close(struct strm_res_object *strmres, struct bridge_drv_interface *intf_fxns; struct chnl_info chnl_info_obj; int status = 0; - struct strm_object *stream_obj = strmres->hstream; + struct strm_object *stream_obj = strmres->stream; DBC_REQUIRE(refs > 0); @@ -268,7 +268,7 @@ int strm_free_buffer(struct strm_res_object *strmres, u8 ** ap_buffer, { int status = 0; u32 i = 0; - struct strm_object *stream_obj = strmres->hstream; + struct strm_object *stream_obj = strmres->stream; DBC_REQUIRE(refs > 0); DBC_REQUIRE(ap_buffer != NULL); @@ -504,8 +504,8 @@ int strm_open(struct node_object *hnode, u32 dir, u32 index, pattr->stream_attr_in->segment_id; strm_obj->buf_alignment = pattr->stream_attr_in->buf_alignment; - strm_obj->udma_chnl_id = - pattr->stream_attr_in->udma_chnl_id; + strm_obj->dma_chnl_id = + pattr->stream_attr_in->dma_chnl_id; strm_obj->dma_priority = pattr->stream_attr_in->dma_priority; chnl_attr_obj.uio_reqs = @@ -516,7 +516,7 @@ int strm_open(struct node_object *hnode, u32 dir, u32 index, strm_obj->strm_mode = STRMMODE_PROCCOPY; strm_obj->segment_id = 0; /* local mem */ strm_obj->buf_alignment = 0; - strm_obj->udma_chnl_id = 0; + strm_obj->dma_chnl_id = 0; strm_obj->dma_priority = 0; chnl_attr_obj.uio_reqs = DEFAULTNUMBUFS; } @@ -655,14 +655,14 @@ int strm_reclaim(struct strm_object *stream_obj, u8 ** buf_ptr, && (!CHNL_IS_IO_CANCELLED(chnl_ioc_obj)) && (stream_obj->strm_mode == STRMMODE_ZEROCOPY)) { /* - * This is a zero-copy channel so chnl_ioc_obj.pbuf + * This is a zero-copy channel so chnl_ioc_obj.buf * contains the DSP address of SM. We need to * translate it to a virtual address for the user * thread to access. * Note: Could add CMM_DSPPA2VA to CMM in the future. */ tmp_buf = cmm_xlator_translate(stream_obj->xlator, - chnl_ioc_obj.pbuf, + chnl_ioc_obj.buf, CMM_DSPPA2PA); if (tmp_buf != NULL) { /* now convert this GPP Pa to Va */ @@ -674,9 +674,9 @@ int strm_reclaim(struct strm_object *stream_obj, u8 ** buf_ptr, if (tmp_buf == NULL) status = -ESRCH; - chnl_ioc_obj.pbuf = tmp_buf; + chnl_ioc_obj.buf = tmp_buf; } - *buf_ptr = chnl_ioc_obj.pbuf; + *buf_ptr = chnl_ioc_obj.buf; } func_end: /* ensure we return a documented return code */ -- cgit v1.2.3 From 121e8f9b9fca6a05602cea1245450e653f0d4ba1 Mon Sep 17 00:00:00 2001 From: Rene Sapiens Date: Tue, 18 Jan 2011 03:19:13 +0000 Subject: staging: tidspbridge: set11 remove hungarian from structs hungarian notation will be removed from the elements inside structures, the next varibles will be renamed: Original: Replacement: hio_mgr io_mgr dw_api_reg_base api_reg_base dw_api_clk_base api_clk_base ap_channel channels pio_requests io_requests pio_completions io_completions pndb_props ndb_props pndb_props_size ndb_props_size pu_num_nodes num_nodes pu_num_procs num_procs psz_path_name sz_path_name pu_index index pargs args pu_allocated allocated psize size hnotification notification pp_rsv_addr rsv_addr prsv_addr rsv_addr pmpu_addr mpu_addr pp_map_addr map_addr ul_map_attr map_attr undb_props_size ndb_props_size Signed-off-by: Rene Sapiens Signed-off-by: Armando Uribe Signed-off-by: Omar Ramirez Luna --- drivers/staging/tidspbridge/core/_msg_sm.h | 2 +- drivers/staging/tidspbridge/core/chnl_sm.c | 66 +++++++++++----------- drivers/staging/tidspbridge/core/io_sm.c | 24 ++++---- drivers/staging/tidspbridge/core/msg_sm.c | 6 +- .../tidspbridge/include/dspbridge/_chnl_sm.h | 8 +-- .../tidspbridge/include/dspbridge/dspapi-ioctl.h | 44 +++++++-------- drivers/staging/tidspbridge/pmgr/dev.c | 12 ++-- drivers/staging/tidspbridge/pmgr/dspapi.c | 54 +++++++++--------- drivers/staging/tidspbridge/rmgr/node.c | 2 +- 9 files changed, 109 insertions(+), 109 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/_msg_sm.h b/drivers/staging/tidspbridge/core/_msg_sm.h index 25414e05dfa5..f6e58e3f3b48 100644 --- a/drivers/staging/tidspbridge/core/_msg_sm.h +++ b/drivers/staging/tidspbridge/core/_msg_sm.h @@ -85,7 +85,7 @@ struct msg_mgr { /* Function interface to Bridge driver */ struct bridge_drv_interface *intf_fxns; - struct io_mgr *hio_mgr; /* IO manager */ + struct io_mgr *iomgr; /* IO manager */ struct list_head queue_list; /* List of MSG_QUEUEs */ spinlock_t msg_mgr_lock; /* For critical sections */ /* Signalled when MsgFrame is available */ diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c index 0986d8785e1b..3c05d7cb9c94 100644 --- a/drivers/staging/tidspbridge/core/chnl_sm.c +++ b/drivers/staging/tidspbridge/core/chnl_sm.c @@ -37,9 +37,9 @@ * which may cause timeouts and/or failure offunction sync_wait_on_event. * This invariant condition is: * - * list_empty(&pchnl->pio_completions) ==> pchnl->sync_event is reset + * list_empty(&pchnl->io_completions) ==> pchnl->sync_event is reset * and - * !list_empty(&pchnl->pio_completions) ==> pchnl->sync_event is set. + * !list_empty(&pchnl->io_completions) ==> pchnl->sync_event is set. */ #include @@ -164,7 +164,7 @@ func_cont: if (CHNL_IS_OUTPUT(pchnl->chnl_mode)) { /* Check buffer size on output channels for fit. */ if (byte_size > io_buf_size( - pchnl->chnl_mgr_obj->hio_mgr)) { + pchnl->chnl_mgr_obj->iomgr)) { status = -EINVAL; goto out; } @@ -199,7 +199,7 @@ func_cont: chnl_packet_obj->arg = dw_arg; chnl_packet_obj->status = (is_eos ? CHNL_IOCSTATEOS : CHNL_IOCSTATCOMPLETE); - list_add_tail(&chnl_packet_obj->link, &pchnl->pio_requests); + list_add_tail(&chnl_packet_obj->link, &pchnl->io_requests); pchnl->cio_reqs++; DBC_ASSERT(pchnl->cio_reqs <= pchnl->chnl_packets); /* @@ -212,7 +212,7 @@ func_cont: /* Legacy DSM Processor-Copy */ DBC_ASSERT(pchnl->chnl_type == CHNL_PCPY); /* Request IO from the DSP */ - io_request_chnl(chnl_mgr_obj->hio_mgr, pchnl, + io_request_chnl(chnl_mgr_obj->iomgr, pchnl, (CHNL_IS_INPUT(pchnl->chnl_mode) ? IO_INPUT : IO_OUTPUT), &mb_val); sched_dpc = true; @@ -224,7 +224,7 @@ out: /* Schedule a DPC, to do the actual data transfer */ if (sched_dpc) - iosm_schedule(chnl_mgr_obj->hio_mgr); + iosm_schedule(chnl_mgr_obj->iomgr); return status; } @@ -260,7 +260,7 @@ int bridge_chnl_cancel_io(struct chnl_object *chnl_obj) pchnl->state |= CHNL_STATECANCEL; - if (list_empty(&pchnl->pio_requests)) { + if (list_empty(&pchnl->io_requests)) { spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock); return 0; } @@ -268,7 +268,7 @@ int bridge_chnl_cancel_io(struct chnl_object *chnl_obj) if (pchnl->chnl_type == CHNL_PCPY) { /* Indicate we have no more buffers available for transfer: */ if (CHNL_IS_INPUT(pchnl->chnl_mode)) { - io_cancel_chnl(chnl_mgr_obj->hio_mgr, chnl_id); + io_cancel_chnl(chnl_mgr_obj->iomgr, chnl_id); } else { /* Record that we no longer have output buffers * available: */ @@ -276,11 +276,11 @@ int bridge_chnl_cancel_io(struct chnl_object *chnl_obj) } } /* Move all IOR's to IOC queue: */ - list_for_each_entry_safe(chirp, tmp, &pchnl->pio_requests, link) { + list_for_each_entry_safe(chirp, tmp, &pchnl->io_requests, link) { list_del(&chirp->link); chirp->byte_size = 0; chirp->status |= CHNL_IOCSTATCANCEL; - list_add_tail(&chirp->link, &pchnl->pio_completions); + list_add_tail(&chirp->link, &pchnl->io_completions); pchnl->cio_cs++; pchnl->cio_reqs--; DBC_ASSERT(pchnl->cio_reqs >= 0); @@ -315,7 +315,7 @@ int bridge_chnl_close(struct chnl_object *chnl_obj) DBC_ASSERT((pchnl->state & CHNL_STATECANCEL)); /* Invalidate channel object: Protects from CHNL_GetIOCompletion() */ /* Free the slot in the channel manager: */ - pchnl->chnl_mgr_obj->ap_channel[pchnl->chnl_id] = NULL; + pchnl->chnl_mgr_obj->channels[pchnl->chnl_id] = NULL; spin_lock_bh(&pchnl->chnl_mgr_obj->chnl_mgr_lock); pchnl->chnl_mgr_obj->open_channels -= 1; spin_unlock_bh(&pchnl->chnl_mgr_obj->chnl_mgr_lock); @@ -331,10 +331,10 @@ int bridge_chnl_close(struct chnl_object *chnl_obj) pchnl->sync_event = NULL; } /* Free I/O request and I/O completion queues: */ - free_chirp_list(&pchnl->pio_completions); + free_chirp_list(&pchnl->io_completions); pchnl->cio_cs = 0; - free_chirp_list(&pchnl->pio_requests); + free_chirp_list(&pchnl->io_requests); pchnl->cio_reqs = 0; free_chirp_list(&pchnl->free_packets_list); @@ -377,9 +377,9 @@ int bridge_chnl_create(struct chnl_mgr **channel_mgr, DBC_ASSERT(mgr_attrts->max_channels == CHNL_MAXCHANNELS); max_channels = CHNL_MAXCHANNELS + CHNL_MAXCHANNELS * CHNL_PCPY; /* Create array of channels */ - chnl_mgr_obj->ap_channel = kzalloc(sizeof(struct chnl_object *) + chnl_mgr_obj->channels = kzalloc(sizeof(struct chnl_object *) * max_channels, GFP_KERNEL); - if (chnl_mgr_obj->ap_channel) { + if (chnl_mgr_obj->channels) { /* Initialize chnl_mgr object */ chnl_mgr_obj->type = CHNL_TYPESM; chnl_mgr_obj->word_size = mgr_attrts->word_size; @@ -423,7 +423,7 @@ int bridge_chnl_destroy(struct chnl_mgr *hchnl_mgr) for (chnl_id = 0; chnl_id < chnl_mgr_obj->max_channels; chnl_id++) { status = - bridge_chnl_close(chnl_mgr_obj->ap_channel + bridge_chnl_close(chnl_mgr_obj->channels [chnl_id]); if (status) dev_dbg(bridge, "%s: Error status 0x%x\n", @@ -431,7 +431,7 @@ int bridge_chnl_destroy(struct chnl_mgr *hchnl_mgr) } /* Free channel manager object: */ - kfree(chnl_mgr_obj->ap_channel); + kfree(chnl_mgr_obj->channels); /* Set hchnl_mgr to NULL in device object. */ dev_set_chnl_mgr(chnl_mgr_obj->dev_obj, NULL); @@ -475,7 +475,7 @@ int bridge_chnl_flush_io(struct chnl_object *chnl_obj, u32 timeout) && (pchnl->chnl_type == CHNL_PCPY)) { /* Wait for IO completions, up to the specified * timeout: */ - while (!list_empty(&pchnl->pio_requests) && !status) { + while (!list_empty(&pchnl->io_requests) && !status) { status = bridge_chnl_get_ioc(chnl_obj, timeout, &chnl_ioc_obj); if (status) @@ -491,7 +491,7 @@ int bridge_chnl_flush_io(struct chnl_object *chnl_obj, u32 timeout) pchnl->state &= ~CHNL_STATECANCEL; } } - DBC_ENSURE(status || list_empty(&pchnl->pio_requests)); + DBC_ENSURE(status || list_empty(&pchnl->io_requests)); return status; } @@ -551,7 +551,7 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, if (!chan_ioc || !pchnl) { status = -EFAULT; } else if (timeout == CHNL_IOCNOWAIT) { - if (list_empty(&pchnl->pio_completions)) + if (list_empty(&pchnl->io_completions)) status = -EREMOTEIO; } @@ -566,7 +566,7 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, ioc.status = CHNL_IOCSTATCOMPLETE; if (timeout != - CHNL_IOCNOWAIT && list_empty(&pchnl->pio_completions)) { + CHNL_IOCNOWAIT && list_empty(&pchnl->io_completions)) { if (timeout == CHNL_IOCINFINITE) timeout = SYNC_INFINITE; @@ -581,7 +581,7 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, * fails due to unkown causes. */ /* Even though Wait failed, there may be something in * the Q: */ - if (list_empty(&pchnl->pio_completions)) { + if (list_empty(&pchnl->io_completions)) { ioc.status |= CHNL_IOCSTATCANCEL; dequeue_ioc = false; } @@ -592,8 +592,8 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, omap_mbox_disable_irq(dev_ctxt->mbox, IRQ_RX); if (dequeue_ioc) { /* Dequeue IOC and set chan_ioc; */ - DBC_ASSERT(!list_empty(&pchnl->pio_completions)); - chnl_packet_obj = list_first_entry(&pchnl->pio_completions, + DBC_ASSERT(!list_empty(&pchnl->io_completions)); + chnl_packet_obj = list_first_entry(&pchnl->io_completions, struct chnl_irp, link); list_del(&chnl_packet_obj->link); /* Update chan_ioc from channel state and chirp: */ @@ -619,7 +619,7 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout, ioc.buf_size = 0; } /* Ensure invariant: If any IOC's are queued for this channel... */ - if (!list_empty(&pchnl->pio_completions)) { + if (!list_empty(&pchnl->io_completions)) { /* Since DSPStream_Reclaim() does not take a timeout * parameter, we pass the stream's timeout value to * bridge_chnl_get_ioc. We cannot determine whether or not @@ -685,7 +685,7 @@ int bridge_chnl_get_mgr_info(struct chnl_mgr *hchnl_mgr, u32 ch_id, return -ECHRNG; /* Return the requested information: */ - mgr_info->chnl_obj = chnl_mgr_obj->ap_channel[ch_id]; + mgr_info->chnl_obj = chnl_mgr_obj->channels[ch_id]; mgr_info->open_channels = chnl_mgr_obj->open_channels; mgr_info->type = chnl_mgr_obj->type; /* total # of chnls */ @@ -752,7 +752,7 @@ int bridge_chnl_open(struct chnl_object **chnl, if (ch_id != CHNL_PICKFREE) { if (ch_id >= chnl_mgr_obj->max_channels) return -ECHRNG; - if (chnl_mgr_obj->ap_channel[ch_id] != NULL) + if (chnl_mgr_obj->channels[ch_id] != NULL) return -EALREADY; } else { /* Check for free channel */ @@ -777,8 +777,8 @@ int bridge_chnl_open(struct chnl_object **chnl, if (status) goto out_err; - INIT_LIST_HEAD(&pchnl->pio_requests); - INIT_LIST_HEAD(&pchnl->pio_completions); + INIT_LIST_HEAD(&pchnl->io_requests); + INIT_LIST_HEAD(&pchnl->io_completions); pchnl->chnl_packets = pattrs->uio_reqs; pchnl->cio_cs = 0; @@ -812,7 +812,7 @@ int bridge_chnl_open(struct chnl_object **chnl, pchnl->chnl_type = CHNL_PCPY; /* Insert channel object in channel manager: */ - chnl_mgr_obj->ap_channel[pchnl->chnl_id] = pchnl; + chnl_mgr_obj->channels[pchnl->chnl_id] = pchnl; spin_lock_bh(&chnl_mgr_obj->chnl_mgr_lock); chnl_mgr_obj->open_channels++; spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock); @@ -824,8 +824,8 @@ int bridge_chnl_open(struct chnl_object **chnl, out_err: /* Free memory */ - free_chirp_list(&pchnl->pio_completions); - free_chirp_list(&pchnl->pio_requests); + free_chirp_list(&pchnl->io_completions); + free_chirp_list(&pchnl->io_requests); free_chirp_list(&pchnl->free_packets_list); if (sync_event) @@ -928,7 +928,7 @@ static int search_free_channel(struct chnl_mgr *chnl_mgr_obj, DBC_REQUIRE(chnl_mgr_obj); for (i = 0; i < chnl_mgr_obj->max_channels; i++) { - if (chnl_mgr_obj->ap_channel[i] == NULL) { + if (chnl_mgr_obj->channels[i] == NULL) { status = 0; *chnl = i; break; diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index db8a43871e39..694c0e5e55cc 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -181,7 +181,7 @@ int bridge_io_create(struct io_mgr **io_man, *io_man = NULL; dev_get_chnl_mgr(hdev_obj, &hchnl_mgr); - if (!hchnl_mgr || hchnl_mgr->hio_mgr) + if (!hchnl_mgr || hchnl_mgr->iomgr) return -EFAULT; /* @@ -228,7 +228,7 @@ int bridge_io_create(struct io_mgr **io_man, } /* Return IO manager object to caller... */ - hchnl_mgr->hio_mgr = pio_mgr; + hchnl_mgr->iomgr = pio_mgr; *io_man = pio_mgr; return 0; @@ -1090,16 +1090,16 @@ static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, DBC_ASSERT(chnl_id); goto func_end; } - pchnl = chnl_mgr_obj->ap_channel[chnl_id]; + pchnl = chnl_mgr_obj->channels[chnl_id]; if ((pchnl != NULL) && CHNL_IS_INPUT(pchnl->chnl_mode)) { if ((pchnl->state & ~CHNL_STATEEOS) == CHNL_STATEREADY) { /* Get the I/O request, and attempt a transfer */ - if (!list_empty(&pchnl->pio_requests)) { + if (!list_empty(&pchnl->io_requests)) { if (!pchnl->cio_reqs) goto func_end; chnl_packet_obj = list_first_entry( - &pchnl->pio_requests, + &pchnl->io_requests, struct chnl_irp, link); list_del(&chnl_packet_obj->link); pchnl->cio_reqs--; @@ -1140,7 +1140,7 @@ static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, DSP_STREAMDONE); } /* Tell DSP if no more I/O buffers available */ - if (list_empty(&pchnl->pio_requests)) + if (list_empty(&pchnl->io_requests)) set_chnl_free(sm, pchnl->chnl_id); clear_chnl = true; notify_client = true; @@ -1292,9 +1292,9 @@ static void notify_chnl_complete(struct chnl_object *pchnl, * signalled by the only IO completion list consumer: * bridge_chnl_get_ioc(). */ - signal_event = list_empty(&pchnl->pio_completions); + signal_event = list_empty(&pchnl->io_completions); /* Enqueue the IO completion info for the client */ - list_add_tail(&chnl_packet_obj->link, &pchnl->pio_completions); + list_add_tail(&chnl_packet_obj->link, &pchnl->io_completions); pchnl->cio_cs++; if (pchnl->cio_cs > pchnl->chnl_packets) @@ -1340,8 +1340,8 @@ static void output_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, if (chnl_id == OUTPUTNOTREADY) goto func_end; - pchnl = chnl_mgr_obj->ap_channel[chnl_id]; - if (!pchnl || list_empty(&pchnl->pio_requests)) { + pchnl = chnl_mgr_obj->channels[chnl_id]; + if (!pchnl || list_empty(&pchnl->io_requests)) { /* Shouldn't get here */ goto func_end; } @@ -1350,14 +1350,14 @@ static void output_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl, goto func_end; /* Get the I/O request, and attempt a transfer */ - chnl_packet_obj = list_first_entry(&pchnl->pio_requests, + chnl_packet_obj = list_first_entry(&pchnl->io_requests, struct chnl_irp, link); list_del(&chnl_packet_obj->link); pchnl->cio_reqs--; /* Record fact that no more I/O buffers available */ - if (list_empty(&pchnl->pio_requests)) + if (list_empty(&pchnl->io_requests)) chnl_mgr_obj->output_mask &= ~(1 << chnl_id); /* Transfer buffer to DSP side */ diff --git a/drivers/staging/tidspbridge/core/msg_sm.c b/drivers/staging/tidspbridge/core/msg_sm.c index 807d55624ceb..94d9e04a22fa 100644 --- a/drivers/staging/tidspbridge/core/msg_sm.c +++ b/drivers/staging/tidspbridge/core/msg_sm.c @@ -69,7 +69,7 @@ int bridge_msg_create(struct msg_mgr **msg_man, return -ENOMEM; msg_mgr_obj->on_exit = msg_callback; - msg_mgr_obj->hio_mgr = hio_mgr; + msg_mgr_obj->iomgr = hio_mgr; /* List of MSG_QUEUEs */ INIT_LIST_HEAD(&msg_mgr_obj->queue_list); /* @@ -356,7 +356,7 @@ int bridge_msg_put(struct msg_queue *msg_queue_obj, /* Release critical section before scheduling DPC */ spin_unlock_bh(&hmsg_mgr->msg_mgr_lock); /* Schedule a DPC, to do the actual data transfer: */ - iosm_schedule(hmsg_mgr->hio_mgr); + iosm_schedule(hmsg_mgr->iomgr); return 0; } @@ -410,7 +410,7 @@ int bridge_msg_put(struct msg_queue *msg_queue_obj, * Schedule a DPC, to do the actual * data transfer. */ - iosm_schedule(hmsg_mgr->hio_mgr); + iosm_schedule(hmsg_mgr->iomgr); msg_queue_obj->io_msg_pend--; /* Reset event if there are still frames available */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h b/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h index 9110cab6d637..d60e25258020 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h +++ b/drivers/staging/tidspbridge/include/dspbridge/_chnl_sm.h @@ -114,7 +114,7 @@ struct shm { struct chnl_mgr { /* Function interface to Bridge driver */ struct bridge_drv_interface *intf_fxns; - struct io_mgr *hio_mgr; /* IO manager */ + struct io_mgr *iomgr; /* IO manager */ /* Device this board represents */ struct dev_object *dev_obj; @@ -126,7 +126,7 @@ struct chnl_mgr { u32 word_size; /* Size in bytes of DSP word */ u8 max_channels; /* Total number of channels */ u8 open_channels; /* Total number of open channels */ - struct chnl_object **ap_channel; /* Array of channels */ + struct chnl_object **channels; /* Array of channels */ u8 type; /* Type of channel class library */ /* If no shm syms, return for CHNL_Open */ int chnl_open_status; @@ -148,12 +148,12 @@ struct chnl_object { struct sync_object *sync_event; u32 process; /* Process which created this channel */ u32 cb_arg; /* Argument to use with callback */ - struct list_head pio_requests; /* List of IOR's to driver */ + struct list_head io_requests; /* List of IOR's to driver */ s32 cio_cs; /* Number of IOC's in queue */ s32 cio_reqs; /* Number of IORequests in queue */ s32 chnl_packets; /* Initial number of free Irps */ /* List of IOC's from driver */ - struct list_head pio_completions; + struct list_head io_completions; struct list_head free_packets_list; /* List of free Irps */ struct ntfy_object *ntfy_obj; u32 bytes_moved; /* Total number of bytes transfered */ diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h index f43b3edb4be5..6d1e33e75687 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h @@ -29,22 +29,22 @@ union trapped_args { /* MGR Module */ struct { u32 node_id; - struct dsp_ndbprops __user *pndb_props; - u32 undb_props_size; - u32 __user *pu_num_nodes; + struct dsp_ndbprops __user *ndb_props; + u32 ndb_props_size; + u32 __user *num_nodes; } args_mgr_enumnode_info; struct { u32 processor_id; struct dsp_processorinfo __user *processor_info; u32 processor_info_size; - u32 __user *pu_num_procs; + u32 __user *num_procs; } args_mgr_enumproc_info; struct { struct dsp_uuid *uuid_obj; enum dsp_dcdobjtype obj_type; - char *psz_path_name; + char *sz_path_name; } args_mgr_registerobject; struct { @@ -55,7 +55,7 @@ union trapped_args { struct { struct dsp_notification __user *__user *anotifications; u32 count; - u32 __user *pu_index; + u32 __user *index; u32 timeout; } args_mgr_wait; @@ -69,7 +69,7 @@ union trapped_args { struct { void *processor; u32 cmd; - struct dsp_cbdata __user *pargs; + struct dsp_cbdata __user *args; } args_proc_ctrl; struct { @@ -80,8 +80,8 @@ union trapped_args { void *processor; void *__user *node_tab; u32 node_tab_size; - u32 __user *pu_num_nodes; - u32 __user *pu_allocated; + u32 __user *num_nodes; + u32 __user *allocated; } args_proc_enumnode_info; struct { @@ -100,7 +100,7 @@ union trapped_args { struct { void *processor; u8 __user *buf; - u8 __user *psize; + u8 __user *size; u32 max_size; } args_proc_gettrace; @@ -115,28 +115,28 @@ union trapped_args { void *processor; u32 event_mask; u32 notify_type; - struct dsp_notification __user *hnotification; + struct dsp_notification __user *notification; } args_proc_register_notify; struct { void *processor; u32 size; - void *__user *pp_rsv_addr; + void *__user *rsv_addr; } args_proc_rsvmem; struct { void *processor; u32 size; - void *prsv_addr; + void *rsv_addr; } args_proc_unrsvmem; struct { void *processor; - void *pmpu_addr; + void *mpu_addr; u32 size; void *req_addr; - void *__user *pp_map_addr; - u32 ul_map_attr; + void *__user *map_addr; + u32 map_attr; } args_proc_mapmem; struct { @@ -147,21 +147,21 @@ union trapped_args { struct { void *processor; - void *pmpu_addr; + void *mpu_addr; u32 size; u32 dir; } args_proc_dma; struct { void *processor; - void *pmpu_addr; + void *mpu_addr; u32 size; u32 ul_flags; } args_proc_flushmemory; struct { void *processor; - void *pmpu_addr; + void *mpu_addr; u32 size; } args_proc_invalidatememory; @@ -169,7 +169,7 @@ union trapped_args { struct { void *processor; struct dsp_uuid __user *node_id_ptr; - struct dsp_cbdata __user *pargs; + struct dsp_cbdata __user *args; struct dsp_nodeattrin __user *attr_in; void *__user *ph_node; } args_node_allocate; @@ -235,7 +235,7 @@ union trapped_args { void *node; u32 event_mask; u32 notify_type; - struct dsp_notification __user *hnotification; + struct dsp_notification __user *notification; } args_node_registernotify; struct { @@ -316,7 +316,7 @@ union trapped_args { void *stream; u32 event_mask; u32 notify_type; - struct dsp_notification __user *hnotification; + struct dsp_notification __user *notification; } args_strm_registernotify; struct { diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c index d35b2ad53c99..9a38d86a84a0 100644 --- a/drivers/staging/tidspbridge/pmgr/dev.c +++ b/drivers/staging/tidspbridge/pmgr/dev.c @@ -69,7 +69,7 @@ struct dev_object { struct chnl_mgr *chnl_mgr; /* Channel manager. */ struct deh_mgr *deh_mgr; /* DEH manager. */ struct msg_mgr *msg_mgr; /* Message manager. */ - struct io_mgr *hio_mgr; /* IO manager (CHNL, msg_ctrl) */ + struct io_mgr *iomgr; /* IO manager (CHNL, msg_ctrl) */ struct cmm_object *cmm_mgr; /* SM memory manager. */ struct dmm_object *dmm_mgr; /* Dynamic memory manager. */ u32 word_size; /* DSP word size: quick access. */ @@ -235,7 +235,7 @@ int dev_create_device(struct dev_object **device_obj, (struct dev_object *)dev_obj, NULL); /* Only create IO manager if we have a channel manager */ if (!status && dev_obj->chnl_mgr) { - status = io_create(&dev_obj->hio_mgr, dev_obj, + status = io_create(&dev_obj->iomgr, dev_obj, &io_mgr_attrs); } /* Only create DEH manager if we have an IO manager */ @@ -351,9 +351,9 @@ int dev_destroy_device(struct dev_object *hdev_obj) } /* Free the io, channel, and message managers for this board: */ - if (dev_obj->hio_mgr) { - io_destroy(dev_obj->hio_mgr); - dev_obj->hio_mgr = NULL; + if (dev_obj->iomgr) { + io_destroy(dev_obj->iomgr); + dev_obj->iomgr = NULL; } if (dev_obj->chnl_mgr) { chnl_destroy(dev_obj->chnl_mgr); @@ -605,7 +605,7 @@ int dev_get_io_mgr(struct dev_object *hdev_obj, DBC_REQUIRE(hdev_obj); if (hdev_obj) { - *io_man = hdev_obj->hio_mgr; + *io_man = hdev_obj->iomgr; } else { *io_man = NULL; status = -EFAULT; diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c index 1d86bd19d591..52717d9cb383 100644 --- a/drivers/staging/tidspbridge/pmgr/dspapi.c +++ b/drivers/staging/tidspbridge/pmgr/dspapi.c @@ -416,7 +416,7 @@ u32 mgrwrap_enum_node_info(union trapped_args *args, void *pr_ctxt) u8 *pndb_props; u32 num_nodes; int status = 0; - u32 size = args->args_mgr_enumnode_info.undb_props_size; + u32 size = args->args_mgr_enumnode_info.ndb_props_size; if (size < sizeof(struct dsp_ndbprops)) return -EINVAL; @@ -431,9 +431,9 @@ u32 mgrwrap_enum_node_info(union trapped_args *args, void *pr_ctxt) (struct dsp_ndbprops *)pndb_props, size, &num_nodes); } - CP_TO_USR(args->args_mgr_enumnode_info.pndb_props, pndb_props, status, + CP_TO_USR(args->args_mgr_enumnode_info.ndb_props, pndb_props, status, size); - CP_TO_USR(args->args_mgr_enumnode_info.pu_num_nodes, &num_nodes, status, + CP_TO_USR(args->args_mgr_enumnode_info.num_nodes, &num_nodes, status, 1); kfree(pndb_props); @@ -466,7 +466,7 @@ u32 mgrwrap_enum_proc_info(union trapped_args *args, void *pr_ctxt) } CP_TO_USR(args->args_mgr_enumproc_info.processor_info, processor_info, status, size); - CP_TO_USR(args->args_mgr_enumproc_info.pu_num_procs, &num_procs, + CP_TO_USR(args->args_mgr_enumproc_info.num_procs, &num_procs, status, 1); kfree(processor_info); @@ -490,7 +490,7 @@ u32 mgrwrap_register_object(union trapped_args *args, void *pr_ctxt) goto func_end; /* path_size is increased by 1 to accommodate NULL */ path_size = strlen_user((char *) - args->args_mgr_registerobject.psz_path_name) + + args->args_mgr_registerobject.sz_path_name) + 1; psz_path_name = kmalloc(path_size, GFP_KERNEL); if (!psz_path_name) { @@ -499,7 +499,7 @@ u32 mgrwrap_register_object(union trapped_args *args, void *pr_ctxt) } ret = strncpy_from_user(psz_path_name, (char *)args->args_mgr_registerobject. - psz_path_name, path_size); + sz_path_name, path_size); if (!ret) { status = -EFAULT; goto func_end; @@ -571,7 +571,7 @@ u32 mgrwrap_wait_for_bridge_events(union trapped_args *args, void *pr_ctxt) args->args_mgr_wait. timeout); } - CP_TO_USR(args->args_mgr_wait.pu_index, &index, status, 1); + CP_TO_USR(args->args_mgr_wait.index, &index, status, 1); return status; } @@ -617,7 +617,7 @@ func_end: u32 procwrap_ctrl(union trapped_args *args, void *pr_ctxt) { u32 cb_data_size, __user * psize = (u32 __user *) - args->args_proc_ctrl.pargs; + args->args_proc_ctrl.args; u8 *pargs = NULL; int status = 0; void *hprocessor = ((struct process_context *)pr_ctxt)->processor; @@ -634,7 +634,7 @@ u32 procwrap_ctrl(union trapped_args *args, void *pr_ctxt) goto func_end; } - CP_FM_USR(pargs, args->args_proc_ctrl.pargs, status, + CP_FM_USR(pargs, args->args_proc_ctrl.args, status, cb_data_size); } if (!status) { @@ -643,7 +643,7 @@ u32 procwrap_ctrl(union trapped_args *args, void *pr_ctxt) (struct dsp_cbdata *)pargs); } - /* CP_TO_USR(args->args_proc_ctrl.pargs, pargs, status, 1); */ + /* CP_TO_USR(args->args_proc_ctrl.args, pargs, status, 1); */ kfree(pargs); func_end: return status; @@ -679,9 +679,9 @@ u32 procwrap_enum_node_info(union trapped_args *args, void *pr_ctxt) &num_nodes, &alloc_cnt); CP_TO_USR(args->args_proc_enumnode_info.node_tab, node_tab, status, num_nodes); - CP_TO_USR(args->args_proc_enumnode_info.pu_num_nodes, &num_nodes, + CP_TO_USR(args->args_proc_enumnode_info.num_nodes, &num_nodes, status, 1); - CP_TO_USR(args->args_proc_enumnode_info.pu_allocated, &alloc_cnt, + CP_TO_USR(args->args_proc_enumnode_info.allocated, &alloc_cnt, status, 1); return status; } @@ -694,7 +694,7 @@ u32 procwrap_end_dma(union trapped_args *args, void *pr_ctxt) return -EINVAL; status = proc_end_dma(pr_ctxt, - args->args_proc_dma.pmpu_addr, + args->args_proc_dma.mpu_addr, args->args_proc_dma.size, args->args_proc_dma.dir); return status; @@ -708,7 +708,7 @@ u32 procwrap_begin_dma(union trapped_args *args, void *pr_ctxt) return -EINVAL; status = proc_begin_dma(pr_ctxt, - args->args_proc_dma.pmpu_addr, + args->args_proc_dma.mpu_addr, args->args_proc_dma.size, args->args_proc_dma.dir); return status; @@ -726,7 +726,7 @@ u32 procwrap_flush_memory(union trapped_args *args, void *pr_ctxt) return -EINVAL; status = proc_flush_memory(pr_ctxt, - args->args_proc_flushmemory.pmpu_addr, + args->args_proc_flushmemory.mpu_addr, args->args_proc_flushmemory.size, args->args_proc_flushmemory.ul_flags); return status; @@ -741,7 +741,7 @@ u32 procwrap_invalidate_memory(union trapped_args *args, void *pr_ctxt) status = proc_invalidate_memory(pr_ctxt, - args->args_proc_invalidatememory.pmpu_addr, + args->args_proc_invalidatememory.mpu_addr, args->args_proc_invalidatememory.size); return status; } @@ -954,12 +954,12 @@ u32 procwrap_map(union trapped_args *args, void *pr_ctxt) return -EINVAL; status = proc_map(args->args_proc_mapmem.processor, - args->args_proc_mapmem.pmpu_addr, + args->args_proc_mapmem.mpu_addr, args->args_proc_mapmem.size, args->args_proc_mapmem.req_addr, &map_addr, - args->args_proc_mapmem.ul_map_attr, pr_ctxt); + args->args_proc_mapmem.map_attr, pr_ctxt); if (!status) { - if (put_user(map_addr, args->args_proc_mapmem.pp_map_addr)) { + if (put_user(map_addr, args->args_proc_mapmem.map_addr)) { status = -EINVAL; proc_un_map(hprocessor, map_addr, pr_ctxt); } @@ -985,7 +985,7 @@ u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt) args->args_proc_register_notify.event_mask, args->args_proc_register_notify.notify_type, ¬ification); - CP_TO_USR(args->args_proc_register_notify.hnotification, ¬ification, + CP_TO_USR(args->args_proc_register_notify.notification, ¬ification, status, 1); return status; } @@ -1007,7 +1007,7 @@ u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt) args->args_proc_rsvmem.size, &prsv_addr, pr_ctxt); if (!status) { - if (put_user(prsv_addr, args->args_proc_rsvmem.pp_rsv_addr)) { + if (put_user(prsv_addr, args->args_proc_rsvmem.rsv_addr)) { status = -EINVAL; proc_un_reserve_memory(args->args_proc_rsvmem. processor, prsv_addr, pr_ctxt); @@ -1048,7 +1048,7 @@ u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt) void *hprocessor = ((struct process_context *)pr_ctxt)->processor; status = proc_un_reserve_memory(hprocessor, - args->args_proc_unrsvmem.prsv_addr, + args->args_proc_unrsvmem.rsv_addr, pr_ctxt); return status; } @@ -1087,7 +1087,7 @@ u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt) int status = 0; struct dsp_uuid node_uuid; u32 cb_data_size = 0; - u32 __user *psize = (u32 __user *) args->args_node_allocate.pargs; + u32 __user *psize = (u32 __user *) args->args_node_allocate.args; u8 *pargs = NULL; struct dsp_nodeattrin proc_attr_in, *attr_in = NULL; struct node_res_object *node_res; @@ -1106,7 +1106,7 @@ u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt) status = -ENOMEM; } - CP_FM_USR(pargs, args->args_node_allocate.pargs, status, + CP_FM_USR(pargs, args->args_node_allocate.args, status, cb_data_size); } CP_FM_USR(&node_uuid, args->args_node_allocate.node_id_ptr, status, 1); @@ -1449,14 +1449,14 @@ u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt) if (!args->args_proc_register_notify.event_mask) CP_FM_USR(¬ification, - args->args_proc_register_notify.hnotification, + args->args_proc_register_notify.notification, status, 1); status = node_register_notify(node_res->node, args->args_node_registernotify.event_mask, args->args_node_registernotify. notify_type, ¬ification); - CP_TO_USR(args->args_node_registernotify.hnotification, ¬ification, + CP_TO_USR(args->args_node_registernotify.notification, ¬ification, status, 1); return status; } @@ -1815,7 +1815,7 @@ u32 strmwrap_register_notify(union trapped_args *args, void *pr_ctxt) args->args_strm_registernotify.event_mask, args->args_strm_registernotify. notify_type, ¬ification); - CP_TO_USR(args->args_strm_registernotify.hnotification, ¬ification, + CP_TO_USR(args->args_strm_registernotify.notification, ¬ification, status, 1); return status; diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index 565383774b6e..5dadaa445ad9 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c @@ -207,7 +207,7 @@ struct node_object { struct node_createargs create_args; /* Args for node create func */ nodeenv node_env; /* Environment returned by RMS */ struct dcd_genericobj dcd_props; /* Node properties from DCD */ - struct dsp_cbdata *pargs; /* Optional args to pass to node */ + struct dsp_cbdata *args; /* Optional args to pass to node */ struct ntfy_object *ntfy_obj; /* Manages registered notifications */ char *str_dev_name; /* device name, if device node */ struct sync_object *sync_done; /* Synchronize node_terminate */ -- cgit v1.2.3 From fbbb4959eee4762a2fa60c6352be2284ebb1cb67 Mon Sep 17 00:00:00 2001 From: Rene Sapiens Date: Tue, 18 Jan 2011 03:19:14 +0000 Subject: staging: tidspbridge: set12 remove hungarian from structs hungarian notation will be removed from the elements inside structures, the next varibles will be renamed: Original: Replacement: dw_buf_size buf_size dw_bytes bytes pattr attr pdw_arg arg ph_cmm_mgr cmm_mgr ph_event event ph_node node ph_stream stream pmask mask pp_argv argv pp_buf_va buf_va pstatus status ul_flags flags ul_seg_id seg_id usize size Signed-off-by: Rene Sapiens Signed-off-by: Armando Uribe Signed-off-by: Omar Ramirez Luna --- .../tidspbridge/include/dspbridge/dspapi-ioctl.h | 42 +++++++++++----------- drivers/staging/tidspbridge/pmgr/dspapi.c | 40 ++++++++++----------- 2 files changed, 41 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h b/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h index 6d1e33e75687..6ff808297c10 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h +++ b/drivers/staging/tidspbridge/include/dspbridge/dspapi-ioctl.h @@ -156,7 +156,7 @@ union trapped_args { void *processor; void *mpu_addr; u32 size; - u32 ul_flags; + u32 flags; } args_proc_flushmemory; struct { @@ -171,13 +171,13 @@ union trapped_args { struct dsp_uuid __user *node_id_ptr; struct dsp_cbdata __user *args; struct dsp_nodeattrin __user *attr_in; - void *__user *ph_node; + void *__user *node; } args_node_allocate; struct { void *node; - u32 usize; - struct dsp_bufferattr __user *pattr; + u32 size; + struct dsp_bufferattr __user *attr; u8 *__user *buffer; } args_node_allocmsgbuf; @@ -191,7 +191,7 @@ union trapped_args { u32 stream_id; void *other_node; u32 other_stream; - struct dsp_strmattr __user *pattrs; + struct dsp_strmattr __user *attrs; struct dsp_cbdata __user *conn_param; } args_node_connect; @@ -205,13 +205,13 @@ union trapped_args { struct { void *node; - struct dsp_bufferattr __user *pattr; + struct dsp_bufferattr __user *attr; u8 *buffer; } args_node_freemsgbuf; struct { void *node; - struct dsp_nodeattr __user *pattr; + struct dsp_nodeattr __user *attr; u32 attr_size; } args_node_getattr; @@ -244,7 +244,7 @@ union trapped_args { struct { void *node; - int __user *pstatus; + int __user *status; } args_node_terminate; struct { @@ -257,7 +257,7 @@ union trapped_args { struct { void *stream; - u32 usize; + u32 size; u8 *__user *ap_buffer; u32 num_bufs; } args_strm_allocatebuffer; @@ -274,7 +274,7 @@ union trapped_args { struct { void *stream; - void **ph_event; + void **event; } args_strm_geteventhandle; struct { @@ -291,8 +291,8 @@ union trapped_args { struct { void *stream; u8 *buffer; - u32 dw_bytes; - u32 dw_buf_size; + u32 bytes; + u32 buf_size; u32 arg; } args_strm_issue; @@ -301,7 +301,7 @@ union trapped_args { u32 direction; u32 index; struct strm_attr __user *attr_in; - void *__user *ph_stream; + void *__user *stream; } args_strm_open; struct { @@ -309,7 +309,7 @@ union trapped_args { u8 *__user *buf_ptr; u32 __user *bytes; u32 __user *buf_size_ptr; - u32 __user *pdw_arg; + u32 __user *arg; } args_strm_reclaim; struct { @@ -322,27 +322,27 @@ union trapped_args { struct { void *__user *stream_tab; u32 strm_num; - u32 __user *pmask; + u32 __user *mask; u32 timeout; } args_strm_select; /* CMM Module */ struct { struct cmm_object *cmm_mgr; - u32 usize; - struct cmm_attrs *pattrs; - void **pp_buf_va; + u32 size; + struct cmm_attrs *attrs; + void **buf_va; } args_cmm_allocbuf; struct { struct cmm_object *cmm_mgr; void *buf_pa; - u32 ul_seg_id; + u32 seg_id; } args_cmm_freebuf; struct { void *processor; - struct cmm_object *__user *ph_cmm_mgr; + struct cmm_object *__user *cmm_mgr; } args_cmm_gethandle; struct { @@ -353,7 +353,7 @@ union trapped_args { /* UTIL module */ struct { s32 util_argc; - char **pp_argv; + char **argv; } args_util_testdll; }; diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c index 52717d9cb383..767ffe270ed6 100644 --- a/drivers/staging/tidspbridge/pmgr/dspapi.c +++ b/drivers/staging/tidspbridge/pmgr/dspapi.c @@ -721,14 +721,14 @@ u32 procwrap_flush_memory(union trapped_args *args, void *pr_ctxt) { int status; - if (args->args_proc_flushmemory.ul_flags > + if (args->args_proc_flushmemory.flags > PROC_WRITEBACK_INVALIDATE_MEM) return -EINVAL; status = proc_flush_memory(pr_ctxt, args->args_proc_flushmemory.mpu_addr, args->args_proc_flushmemory.size, - args->args_proc_flushmemory.ul_flags); + args->args_proc_flushmemory.flags); return status; } @@ -1129,7 +1129,7 @@ u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt) } if (!status) { nodeid = node_res->id + 1; - CP_TO_USR(args->args_node_allocate.ph_node, &nodeid, + CP_TO_USR(args->args_node_allocate.node, &nodeid, status, 1); if (status) { status = -EFAULT; @@ -1159,11 +1159,11 @@ u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt) if (!node_res) return -EFAULT; - if (!args->args_node_allocmsgbuf.usize) + if (!args->args_node_allocmsgbuf.size) return -EINVAL; - if (args->args_node_allocmsgbuf.pattr) { /* Optional argument */ - CP_FM_USR(&attr, args->args_node_allocmsgbuf.pattr, status, 1); + if (args->args_node_allocmsgbuf.attr) { /* Optional argument */ + CP_FM_USR(&attr, args->args_node_allocmsgbuf.attr, status, 1); if (!status) pattr = &attr; @@ -1172,7 +1172,7 @@ u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt) CP_FM_USR(&pbuffer, args->args_node_allocmsgbuf.buffer, status, 1); if (!status) { status = node_alloc_msg_buf(node_res->node, - args->args_node_allocmsgbuf.usize, + args->args_node_allocmsgbuf.size, pattr, &pbuffer); } CP_TO_USR(args->args_node_allocmsgbuf.buffer, &pbuffer, status, 1); @@ -1253,8 +1253,8 @@ u32 nodewrap_connect(union trapped_args *args, void *pr_ctxt) if (status) goto func_cont; } - if (args->args_node_connect.pattrs) { /* Optional argument */ - CP_FM_USR(&attrs, args->args_node_connect.pattrs, status, 1); + if (args->args_node_connect.attrs) { /* Optional argument */ + CP_FM_USR(&attrs, args->args_node_connect.attrs, status, 1); if (!status) pattrs = &attrs; @@ -1323,8 +1323,8 @@ u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt) if (!node_res) return -EFAULT; - if (args->args_node_freemsgbuf.pattr) { /* Optional argument */ - CP_FM_USR(&attr, args->args_node_freemsgbuf.pattr, status, 1); + if (args->args_node_freemsgbuf.attr) { /* Optional argument */ + CP_FM_USR(&attr, args->args_node_freemsgbuf.attr, status, 1); if (!status) pattr = &attr; @@ -1358,7 +1358,7 @@ u32 nodewrap_get_attr(union trapped_args *args, void *pr_ctxt) status = node_get_attr(node_res->node, &attr, args->args_node_getattr.attr_size); - CP_TO_USR(args->args_node_getattr.pattr, &attr, status, 1); + CP_TO_USR(args->args_node_getattr.attr, &attr, status, 1); return status; } @@ -1495,7 +1495,7 @@ u32 nodewrap_terminate(union trapped_args *args, void *pr_ctxt) status = node_terminate(node_res->node, &tempstatus); - CP_TO_USR(args->args_node_terminate.pstatus, &tempstatus, status, 1); + CP_TO_USR(args->args_node_terminate.status, &tempstatus, status, 1); return status; } @@ -1564,7 +1564,7 @@ u32 strmwrap_allocate_buffer(union trapped_args *args, void *pr_ctxt) return -ENOMEM; status = strm_allocate_buffer(strm_res, - args->args_strm_allocatebuffer.usize, + args->args_strm_allocatebuffer.size, ap_buffer, num_bufs, pr_ctxt); if (!status) { CP_TO_USR(args->args_strm_allocatebuffer.ap_buffer, ap_buffer, @@ -1715,8 +1715,8 @@ u32 strmwrap_issue(union trapped_args *args, void *pr_ctxt) in chnl_sm.c */ status = strm_issue(strm_res->stream, args->args_strm_issue.buffer, - args->args_strm_issue.dw_bytes, - args->args_strm_issue.dw_buf_size, + args->args_strm_issue.bytes, + args->args_strm_issue.buf_size, args->args_strm_issue.arg); return status; @@ -1756,7 +1756,7 @@ u32 strmwrap_open(union trapped_args *args, void *pr_ctxt) pr_ctxt); if (!status) { strmid = strm_res_obj->id + 1; - CP_TO_USR(args->args_strm_open.ph_stream, &strmid, status, 1); + CP_TO_USR(args->args_strm_open.stream, &strmid, status, 1); } return status; } @@ -1782,7 +1782,7 @@ u32 strmwrap_reclaim(union trapped_args *args, void *pr_ctxt) &ul_bytes, &ul_buf_size, &dw_arg); CP_TO_USR(args->args_strm_reclaim.buf_ptr, &buf_ptr, status, 1); CP_TO_USR(args->args_strm_reclaim.bytes, &ul_bytes, status, 1); - CP_TO_USR(args->args_strm_reclaim.pdw_arg, &dw_arg, status, 1); + CP_TO_USR(args->args_strm_reclaim.arg, &dw_arg, status, 1); if (args->args_strm_reclaim.buf_size_ptr != NULL) { CP_TO_USR(args->args_strm_reclaim.buf_size_ptr, &ul_buf_size, @@ -1855,7 +1855,7 @@ u32 strmwrap_select(union trapped_args *args, void *pr_ctxt) status = strm_select(strm_tab, args->args_strm_select.strm_num, &mask, args->args_strm_select.timeout); } - CP_TO_USR(args->args_strm_select.pmask, &mask, status, 1); + CP_TO_USR(args->args_strm_select.mask, &mask, status, 1); return status; } @@ -1892,7 +1892,7 @@ u32 cmmwrap_get_handle(union trapped_args *args, void *pr_ctxt) status = cmm_get_handle(hprocessor, &hcmm_mgr); - CP_TO_USR(args->args_cmm_gethandle.ph_cmm_mgr, &hcmm_mgr, status, 1); + CP_TO_USR(args->args_cmm_gethandle.cmm_mgr, &hcmm_mgr, status, 1); return status; } -- cgit v1.2.3 From 72389a33b8878e6091f7ab8080f5ed07054c7c39 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 6 Feb 2011 15:50:52 +0000 Subject: drm/i915/lvds: Restore dithering on native modes for gen2/3 A regression introduced in bee17e5 cleared the dithering bit for native modes on gen2/3. Bugzilla: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/711568 Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_lvds.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index ace8d5d30dd2..bcdba7bd5cfa 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -261,12 +261,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, return true; } - /* Make sure pre-965s set dither correctly */ - if (INTEL_INFO(dev)->gen < 4) { - if (dev_priv->lvds_dither) - pfit_control |= PANEL_8TO6_DITHER_ENABLE; - } - /* Native modes don't need fitting */ if (adjusted_mode->hdisplay == mode->hdisplay && adjusted_mode->vdisplay == mode->vdisplay) @@ -374,10 +368,16 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, } out: + /* If not enabling scaling, be consistent and always use 0. */ if ((pfit_control & PFIT_ENABLE) == 0) { pfit_control = 0; pfit_pgm_ratios = 0; } + + /* Make sure pre-965 set dither correctly */ + if (INTEL_INFO(dev)->gen < 4 && dev_priv->lvds_dither) + pfit_control |= PANEL_8TO6_DITHER_ENABLE; + if (pfit_control != intel_lvds->pfit_control || pfit_pgm_ratios != intel_lvds->pfit_pgm_ratios) { intel_lvds->pfit_control = pfit_control; -- cgit v1.2.3 From 2f115cf24ea3f5010f7361d2098545edf7a07add Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 4 Feb 2011 06:57:45 -0800 Subject: iwlwifi: remove unnecessary locking This code, and the places that set the variable is_internal_short_scan and the vif pointers are all protected by the mutex, there's no point in locking the spinlock here as well (any more). Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 3 --- drivers/net/wireless/iwlwifi/iwl3945-base.c | 3 --- 2 files changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index d4ba3357b628..3aa486437509 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1395,15 +1395,12 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) u32 extra; u32 suspend_time = 100; u32 scan_suspend_time = 100; - unsigned long flags; IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); - spin_lock_irqsave(&priv->lock, flags); if (priv->is_internal_short_scan) interval = 0; else interval = vif->bss_conf.beacon_int; - spin_unlock_irqrestore(&priv->lock, flags); scan->suspend_time = 0; scan->max_out_time = cpu_to_le32(200 * 1024); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 76fae81ddc4b..adcef735180a 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2860,16 +2860,13 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) u32 extra; u32 suspend_time = 100; u32 scan_suspend_time = 100; - unsigned long flags; IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); - spin_lock_irqsave(&priv->lock, flags); if (priv->is_internal_short_scan) interval = 0; else interval = vif->bss_conf.beacon_int; - spin_unlock_irqrestore(&priv->lock, flags); scan->suspend_time = 0; scan->max_out_time = cpu_to_le32(200 * 1024); -- cgit v1.2.3 From 80b38fffab9a2d86c252addce5a520dcf8f2fc66 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 4 Feb 2011 10:46:41 -0800 Subject: iwlwifi: fix compiling error with different configuration When .config has different configuration, it might fail to compile iwlwifi. fix it Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index a5daf6447178..096f8ad0f1b1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3771,7 +3771,7 @@ static void iwlagn_disable_roc(struct iwl_priv *priv) priv->_agn.hw_roc_channel = NULL; - iwlagn_commit_rxon(priv, ctx); + iwlcore_commit_rxon(priv, ctx); ctx->is_active = false; } @@ -3787,6 +3787,7 @@ static void iwlagn_bg_roc_done(struct work_struct *work) mutex_unlock(&priv->mutex); } +#ifdef CONFIG_IWL5000 static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_channel *channel, enum nl80211_channel_type channel_type, @@ -3814,7 +3815,7 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw, priv->_agn.hw_roc_channel = channel; priv->_agn.hw_roc_chantype = channel_type; priv->_agn.hw_roc_duration = DIV_ROUND_UP(duration * 1000, 1024); - iwlagn_commit_rxon(priv, &priv->contexts[IWL_RXON_CTX_PAN]); + iwlcore_commit_rxon(priv, &priv->contexts[IWL_RXON_CTX_PAN]); queue_delayed_work(priv->workqueue, &priv->_agn.hw_roc_work, msecs_to_jiffies(duration + 20)); @@ -3842,6 +3843,7 @@ static int iwl_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) return 0; } +#endif /***************************************************************************** * -- cgit v1.2.3 From a8c94b9188bf6012d9b6c3d37f324bd6c7d2924e Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Sun, 6 Feb 2011 11:21:02 -0800 Subject: bnx2x: MTU for FCoE L2 ring Always configure an FCoE L2 ring with a mini-jumbo MTU size (2500). To do that we had to move the rx_buf_size parameter from per function level to a per ring level. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 7 +++++- drivers/net/bnx2x/bnx2x_cmn.c | 53 ++++++++++++++++++++++++++++----------- drivers/net/bnx2x/bnx2x_cmn.h | 6 ++--- drivers/net/bnx2x/bnx2x_ethtool.c | 2 +- drivers/net/bnx2x/bnx2x_main.c | 10 ++++++-- 5 files changed, 57 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index ff87ec33d00e..c29b37e5e743 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -341,6 +341,8 @@ struct bnx2x_fastpath { /* chip independed shortcut into rx_prods_offset memory */ u32 ustorm_rx_prods_offset; + u32 rx_buf_size; + dma_addr_t status_blk_mapping; struct sw_tx_bd *tx_buf_ring; @@ -428,6 +430,10 @@ struct bnx2x_fastpath { }; #define bnx2x_fp(bp, nr, var) (bp->fp[nr].var) + +/* Use 2500 as a mini-jumbo MTU for FCoE */ +#define BNX2X_FCOE_MINI_JUMBO_MTU 2500 + #ifdef BCM_CNIC /* FCoE L2 `fastpath' is right after the eth entries */ #define FCOE_IDX BNX2X_NUM_ETH_QUEUES(bp) @@ -911,7 +917,6 @@ struct bnx2x { int tx_ring_size; u32 rx_csum; - u32 rx_buf_size; /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */ #define ETH_OVREHEAD (ETH_HLEN + 8 + 8) #define ETH_MIN_PACKET_SIZE 60 diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 710ce5d04c53..844afcec79b4 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -232,7 +232,7 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, /* move empty skb from pool to prod and map it */ prod_rx_buf->skb = fp->tpa_pool[queue].skb; mapping = dma_map_single(&bp->pdev->dev, fp->tpa_pool[queue].skb->data, - bp->rx_buf_size, DMA_FROM_DEVICE); + fp->rx_buf_size, DMA_FROM_DEVICE); dma_unmap_addr_set(prod_rx_buf, mapping, mapping); /* move partial skb from cons to pool (don't unmap yet) */ @@ -333,13 +333,13 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, struct sw_rx_bd *rx_buf = &fp->tpa_pool[queue]; struct sk_buff *skb = rx_buf->skb; /* alloc new skb */ - struct sk_buff *new_skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size); + struct sk_buff *new_skb = netdev_alloc_skb(bp->dev, fp->rx_buf_size); /* Unmap skb in the pool anyway, as we are going to change pool entry status to BNX2X_TPA_STOP even if new skb allocation fails. */ dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping), - bp->rx_buf_size, DMA_FROM_DEVICE); + fp->rx_buf_size, DMA_FROM_DEVICE); if (likely(new_skb)) { /* fix ip xsum and give it to the stack */ @@ -349,10 +349,10 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, prefetch(((char *)(skb)) + L1_CACHE_BYTES); #ifdef BNX2X_STOP_ON_ERROR - if (pad + len > bp->rx_buf_size) { + if (pad + len > fp->rx_buf_size) { BNX2X_ERR("skb_put is about to fail... " "pad %d len %d rx_buf_size %d\n", - pad, len, bp->rx_buf_size); + pad, len, fp->rx_buf_size); bnx2x_panic(); return; } @@ -582,7 +582,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) if (likely(bnx2x_alloc_rx_skb(bp, fp, bd_prod) == 0)) { dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping), - bp->rx_buf_size, + fp->rx_buf_size, DMA_FROM_DEVICE); skb_reserve(skb, pad); skb_put(skb, len); @@ -821,19 +821,16 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) u16 ring_prod; int i, j; - bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN + - IP_HEADER_ALIGNMENT_PADDING; - - DP(NETIF_MSG_IFUP, - "mtu %d rx_buf_size %d\n", bp->dev->mtu, bp->rx_buf_size); - for_each_rx_queue(bp, j) { struct bnx2x_fastpath *fp = &bp->fp[j]; + DP(NETIF_MSG_IFUP, + "mtu %d rx_buf_size %d\n", bp->dev->mtu, fp->rx_buf_size); + if (!fp->disable_tpa) { for (i = 0; i < max_agg_queues; i++) { fp->tpa_pool[i].skb = - netdev_alloc_skb(bp->dev, bp->rx_buf_size); + netdev_alloc_skb(bp->dev, fp->rx_buf_size); if (!fp->tpa_pool[i].skb) { BNX2X_ERR("Failed to allocate TPA " "skb pool for queue[%d] - " @@ -941,7 +938,7 @@ static void bnx2x_free_rx_skbs(struct bnx2x *bp) dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping), - bp->rx_buf_size, DMA_FROM_DEVICE); + fp->rx_buf_size, DMA_FROM_DEVICE); rx_buf->skb = NULL; dev_kfree_skb(skb); @@ -1249,6 +1246,31 @@ static inline int bnx2x_set_real_num_queues(struct bnx2x *bp) return rc; } +static inline void bnx2x_set_rx_buf_size(struct bnx2x *bp) +{ + int i; + + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + + /* Always use a mini-jumbo MTU for the FCoE L2 ring */ + if (IS_FCOE_IDX(i)) + /* + * Although there are no IP frames expected to arrive to + * this ring we still want to add an + * IP_HEADER_ALIGNMENT_PADDING to prevent a buffer + * overrun attack. + */ + fp->rx_buf_size = + BNX2X_FCOE_MINI_JUMBO_MTU + ETH_OVREHEAD + + BNX2X_RX_ALIGN + IP_HEADER_ALIGNMENT_PADDING; + else + fp->rx_buf_size = + bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN + + IP_HEADER_ALIGNMENT_PADDING; + } +} + /* must be called with rtnl_lock */ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) { @@ -1272,6 +1294,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) /* must be called before memory allocation and HW init */ bnx2x_ilt_set_info(bp); + /* Set the receive queues buffer size */ + bnx2x_set_rx_buf_size(bp); + if (bnx2x_alloc_mem(bp)) return -ENOMEM; diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 03eb4d68e6bb..f062d5d20fa9 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -822,11 +822,11 @@ static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, struct eth_rx_bd *rx_bd = &fp->rx_desc_ring[index]; dma_addr_t mapping; - skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size); + skb = netdev_alloc_skb(bp->dev, fp->rx_buf_size); if (unlikely(skb == NULL)) return -ENOMEM; - mapping = dma_map_single(&bp->pdev->dev, skb->data, bp->rx_buf_size, + mapping = dma_map_single(&bp->pdev->dev, skb->data, fp->rx_buf_size, DMA_FROM_DEVICE); if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { dev_kfree_skb(skb); @@ -892,7 +892,7 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp, if (fp->tpa_state[i] == BNX2X_TPA_START) dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping), - bp->rx_buf_size, DMA_FROM_DEVICE); + fp->rx_buf_size, DMA_FROM_DEVICE); dev_kfree_skb(skb); rx_buf->skb = NULL; diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 5b44a8b48509..816fef6d3844 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -1618,7 +1618,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) /* prepare the loopback packet */ pkt_size = (((bp->dev->mtu < ETH_MAX_PACKET_SIZE) ? bp->dev->mtu : ETH_MAX_PACKET_SIZE) + ETH_HLEN); - skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size); + skb = netdev_alloc_skb(bp->dev, fp_rx->rx_buf_size); if (!skb) { rc = -ENOMEM; goto test_loopback_exit; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 5e3f94878153..722450631302 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -2473,8 +2473,14 @@ static void bnx2x_pf_rx_cl_prep(struct bnx2x *bp, rxq_init->sge_map = fp->rx_sge_mapping; rxq_init->rcq_map = fp->rx_comp_mapping; rxq_init->rcq_np_map = fp->rx_comp_mapping + BCM_PAGE_SIZE; - rxq_init->mtu = bp->dev->mtu; - rxq_init->buf_sz = bp->rx_buf_size; + + /* Always use mini-jumbo MTU for FCoE L2 ring */ + if (IS_FCOE_FP(fp)) + rxq_init->mtu = BNX2X_FCOE_MINI_JUMBO_MTU; + else + rxq_init->mtu = bp->dev->mtu; + + rxq_init->buf_sz = fp->rx_buf_size; rxq_init->cl_qzone_id = fp->cl_qzone_id; rxq_init->cl_id = fp->cl_id; rxq_init->spcl_id = fp->cl_id; -- cgit v1.2.3 From 6e30dd4e3935ddb4e7dd27d5be7a6e5504e64a27 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Sun, 6 Feb 2011 11:25:41 -0800 Subject: bnx2x: Proper netdev->ndo_set_rx_mode() implementation. Completed the bnx2x_set_rx_mode() to a proper netdev->ndo_set_rx_mode implementation: - Added a missing configuration of a unicast MAC addresses list. - Changed bp->dma_lock from being a mutex to a spinlock as long as it's taken under netdev->addr_list_lock now. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 13 +- drivers/net/bnx2x/bnx2x_cmn.c | 17 +- drivers/net/bnx2x/bnx2x_main.c | 444 ++++++++++++++++++++++++++++++++--------- 3 files changed, 369 insertions(+), 105 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index c29b37e5e743..236d79a80624 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -129,6 +129,7 @@ void bnx2x_panic_dump(struct bnx2x *bp); #endif #define bnx2x_mc_addr(ha) ((ha)->addr) +#define bnx2x_uc_addr(ha) ((ha)->addr) #define U64_LO(x) (u32)(((u64)(x)) & 0xffffffff) #define U64_HI(x) (u32)(((u64)(x)) >> 32) @@ -816,6 +817,7 @@ struct bnx2x_slowpath { struct eth_stats_query fw_stats; struct mac_configuration_cmd mac_config; struct mac_configuration_cmd mcast_config; + struct mac_configuration_cmd uc_mac_config; struct client_init_ramrod_data client_init_data; /* used by dmae command executer */ @@ -944,7 +946,7 @@ struct bnx2x { struct eth_spe *spq_prod_bd; struct eth_spe *spq_last_bd; __le16 *dsb_sp_prod; - atomic_t spq_left; /* serialize spq */ + atomic_t cq_spq_left; /* ETH_XXX ramrods credit */ /* used to synchronize spq accesses */ spinlock_t spq_lock; @@ -954,6 +956,7 @@ struct bnx2x { u16 eq_prod; u16 eq_cons; __le16 *eq_cons_sb; + atomic_t eq_spq_left; /* COMMON_XXX ramrods credit */ /* Flags for marking that there is a STAT_QUERY or SET_MAC ramrod pending */ @@ -1139,7 +1142,7 @@ struct bnx2x { int dmae_ready; /* used to synchronize dmae accesses */ - struct mutex dmae_mutex; + spinlock_t dmae_lock; /* used to protect the FW mail box */ struct mutex fw_mb_mutex; @@ -1455,6 +1458,12 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param); void bnx2x_calc_fc_adv(struct bnx2x *bp); int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, u32 data_hi, u32 data_lo, int common); + +/* Clears multicast and unicast list configuration in the chip. */ +void bnx2x_invalidate_e1_mc_list(struct bnx2x *bp); +void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp); +void bnx2x_invalidate_uc_list(struct bnx2x *bp); + void bnx2x_update_coalesce(struct bnx2x *bp); int bnx2x_get_link_cfg_idx(struct bnx2x *bp); diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 844afcec79b4..6fac8e183c59 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1452,28 +1452,35 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bnx2x_set_eth_mac(bp, 1); + /* Clear MC configuration */ + if (CHIP_IS_E1(bp)) + bnx2x_invalidate_e1_mc_list(bp); + else + bnx2x_invalidate_e1h_mc_list(bp); + + /* Clear UC lists configuration */ + bnx2x_invalidate_uc_list(bp); + if (bp->port.pmf) bnx2x_initial_phy_init(bp, load_mode); + /* Initialize Rx filtering */ + bnx2x_set_rx_mode(bp->dev); + /* Start fast path */ switch (load_mode) { case LOAD_NORMAL: /* Tx queue should be only reenabled */ netif_tx_wake_all_queues(bp->dev); /* Initialize the receive filter. */ - bnx2x_set_rx_mode(bp->dev); break; case LOAD_OPEN: netif_tx_start_all_queues(bp->dev); smp_mb__after_clear_bit(); - /* Initialize the receive filter. */ - bnx2x_set_rx_mode(bp->dev); break; case LOAD_DIAG: - /* Initialize the receive filter. */ - bnx2x_set_rx_mode(bp->dev); bp->state = BNX2X_STATE_DIAG; break; diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 722450631302..ccf2c8c61a61 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -586,7 +586,7 @@ static int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]); /* lock the dmae channel */ - mutex_lock(&bp->dmae_mutex); + spin_lock_bh(&bp->dmae_lock); /* reset completion */ *wb_comp = 0; @@ -617,7 +617,7 @@ static int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]); unlock: - mutex_unlock(&bp->dmae_mutex); + spin_unlock_bh(&bp->dmae_lock); return rc; } @@ -1397,7 +1397,7 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp, } smp_mb__before_atomic_inc(); - atomic_inc(&bp->spq_left); + atomic_inc(&bp->cq_spq_left); /* push the change in fp->state and towards the memory */ smp_wmb(); @@ -2732,11 +2732,18 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, spin_lock_bh(&bp->spq_lock); - if (!atomic_read(&bp->spq_left)) { - BNX2X_ERR("BUG! SPQ ring full!\n"); - spin_unlock_bh(&bp->spq_lock); - bnx2x_panic(); - return -EBUSY; + if (common) { + if (!atomic_read(&bp->eq_spq_left)) { + BNX2X_ERR("BUG! EQ ring full!\n"); + spin_unlock_bh(&bp->spq_lock); + bnx2x_panic(); + return -EBUSY; + } + } else if (!atomic_read(&bp->cq_spq_left)) { + BNX2X_ERR("BUG! SPQ ring full!\n"); + spin_unlock_bh(&bp->spq_lock); + bnx2x_panic(); + return -EBUSY; } spe = bnx2x_sp_get_next(bp); @@ -2767,20 +2774,26 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, spe->data.update_data_addr.lo = cpu_to_le32(data_lo); /* stats ramrod has it's own slot on the spq */ - if (command != RAMROD_CMD_ID_COMMON_STAT_QUERY) + if (command != RAMROD_CMD_ID_COMMON_STAT_QUERY) { /* It's ok if the actual decrement is issued towards the memory * somewhere between the spin_lock and spin_unlock. Thus no * more explict memory barrier is needed. */ - atomic_dec(&bp->spq_left); + if (common) + atomic_dec(&bp->eq_spq_left); + else + atomic_dec(&bp->cq_spq_left); + } + DP(BNX2X_MSG_SP/*NETIF_MSG_TIMER*/, "SPQE[%x] (%x:%x) command %d hw_cid %x data (%x:%x) " - "type(0x%x) left %x\n", + "type(0x%x) left (ETH, COMMON) (%x,%x)\n", bp->spq_prod_idx, (u32)U64_HI(bp->spq_mapping), (u32)(U64_LO(bp->spq_mapping) + (void *)bp->spq_prod_bd - (void *)bp->spq), command, - HW_CID(bp, cid), data_hi, data_lo, type, atomic_read(&bp->spq_left)); + HW_CID(bp, cid), data_hi, data_lo, type, + atomic_read(&bp->cq_spq_left), atomic_read(&bp->eq_spq_left)); bnx2x_sp_prod_update(bp); spin_unlock_bh(&bp->spq_lock); @@ -3692,8 +3705,8 @@ static void bnx2x_eq_int(struct bnx2x *bp) sw_cons = bp->eq_cons; sw_prod = bp->eq_prod; - DP(BNX2X_MSG_SP, "EQ: hw_cons %u sw_cons %u bp->spq_left %u\n", - hw_cons, sw_cons, atomic_read(&bp->spq_left)); + DP(BNX2X_MSG_SP, "EQ: hw_cons %u sw_cons %u bp->cq_spq_left %u\n", + hw_cons, sw_cons, atomic_read(&bp->eq_spq_left)); for (; sw_cons != hw_cons; sw_prod = NEXT_EQ_IDX(sw_prod), sw_cons = NEXT_EQ_IDX(sw_cons)) { @@ -3758,13 +3771,15 @@ static void bnx2x_eq_int(struct bnx2x *bp) case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_OPEN): case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_DIAG): DP(NETIF_MSG_IFUP, "got set mac ramrod\n"); - bp->set_mac_pending = 0; + if (elem->message.data.set_mac_event.echo) + bp->set_mac_pending = 0; break; case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT): DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n"); - bp->set_mac_pending = 0; + if (elem->message.data.set_mac_event.echo) + bp->set_mac_pending = 0; break; default: /* unknown event log error and continue */ @@ -3776,7 +3791,7 @@ next_spqe: } /* for */ smp_mb__before_atomic_inc(); - atomic_add(spqe_cnt, &bp->spq_left); + atomic_add(spqe_cnt, &bp->eq_spq_left); bp->eq_cons = sw_cons; bp->eq_prod = sw_prod; @@ -4209,7 +4224,7 @@ void bnx2x_update_coalesce(struct bnx2x *bp) static void bnx2x_init_sp_ring(struct bnx2x *bp) { spin_lock_init(&bp->spq_lock); - atomic_set(&bp->spq_left, MAX_SPQ_PENDING); + atomic_set(&bp->cq_spq_left, MAX_SPQ_PENDING); bp->spq_prod_idx = 0; bp->dsb_sp_prod = BNX2X_SP_DSB_INDEX; @@ -4234,6 +4249,9 @@ static void bnx2x_init_eq_ring(struct bnx2x *bp) bp->eq_cons = 0; bp->eq_prod = NUM_EQ_DESC; bp->eq_cons_sb = BNX2X_EQ_INDEX; + /* we want a warning message before it gets rought... */ + atomic_set(&bp->eq_spq_left, + min_t(int, MAX_SP_DESC_CNT - MAX_SPQ_PENDING, NUM_EQ_DESC) - 1); } static void bnx2x_init_ind_table(struct bnx2x *bp) @@ -5832,7 +5850,7 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) BP_ABS_FUNC(bp), load_code); bp->dmae_ready = 0; - mutex_init(&bp->dmae_mutex); + spin_lock_init(&bp->dmae_lock); rc = bnx2x_gunzip_init(bp); if (rc) return rc; @@ -6167,12 +6185,14 @@ static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, const u8 *mac, int ramrod_flags = WAIT_RAMROD_COMMON; bp->set_mac_pending = 1; - smp_wmb(); config->hdr.length = 1; config->hdr.offset = cam_offset; config->hdr.client_id = 0xff; - config->hdr.reserved1 = 0; + /* Mark the single MAC configuration ramrod as opposed to a + * UC/MC list configuration). + */ + config->hdr.echo = 1; /* primary MAC */ config->config_table[0].msb_mac_addr = @@ -6204,6 +6224,8 @@ static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, const u8 *mac, config->config_table[0].middle_mac_addr, config->config_table[0].lsb_mac_addr, BP_FUNC(bp), cl_bit_vec); + mb(); + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, U64_HI(bnx2x_sp_mapping(bp, mac_config)), U64_LO(bnx2x_sp_mapping(bp, mac_config)), 1); @@ -6268,20 +6290,15 @@ static u8 bnx2x_e1h_cam_offset(struct bnx2x *bp, u8 rel_offset) if (CHIP_IS_E1H(bp)) return E1H_FUNC_MAX * rel_offset + BP_FUNC(bp); else if (CHIP_MODE_IS_4_PORT(bp)) - return BP_FUNC(bp) * 32 + rel_offset; + return E2_FUNC_MAX * rel_offset + BP_FUNC(bp); else - return BP_VN(bp) * 32 + rel_offset; + return E2_FUNC_MAX * rel_offset + BP_VN(bp); } /** * LLH CAM line allocations: currently only iSCSI and ETH macs are * relevant. In addition, current implementation is tuned for a * single ETH MAC. - * - * When multiple unicast ETH MACs PF configuration in switch - * independent mode is required (NetQ, multiple netdev MACs, - * etc.), consider better utilisation of 16 per function MAC - * entries in the LLH memory. */ enum { LLH_CAM_ISCSI_ETH_LINE = 0, @@ -6356,14 +6373,37 @@ void bnx2x_set_eth_mac(struct bnx2x *bp, int set) bnx2x_set_mac_addr_gen(bp, set, bcast, 0, cam_offset + 1, 1); } } -static void bnx2x_set_e1_mc_list(struct bnx2x *bp, u8 offset) + +static inline u8 bnx2x_e1_cam_mc_offset(struct bnx2x *bp) +{ + return CHIP_REV_IS_SLOW(bp) ? + (BNX2X_MAX_EMUL_MULTI * (1 + BP_PORT(bp))) : + (BNX2X_MAX_MULTICAST * (1 + BP_PORT(bp))); +} + +/* set mc list, do not wait as wait implies sleep and + * set_rx_mode can be invoked from non-sleepable context. + * + * Instead we use the same ramrod data buffer each time we need + * to configure a list of addresses, and use the fact that the + * list of MACs is changed in an incremental way and that the + * function is called under the netif_addr_lock. A temporary + * inconsistent CAM configuration (possible in case of a very fast + * sequence of add/del/add on the host side) will shortly be + * restored by the handler of the last ramrod. + */ +static int bnx2x_set_e1_mc_list(struct bnx2x *bp) { int i = 0, old; struct net_device *dev = bp->dev; + u8 offset = bnx2x_e1_cam_mc_offset(bp); struct netdev_hw_addr *ha; struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config); dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config); + if (netdev_mc_count(dev) > BNX2X_MAX_MULTICAST) + return -EINVAL; + netdev_for_each_mc_addr(ha, dev) { /* copy mac */ config_cmd->config_table[i].msb_mac_addr = @@ -6404,32 +6444,47 @@ static void bnx2x_set_e1_mc_list(struct bnx2x *bp, u8 offset) } } + wmb(); + config_cmd->hdr.length = i; config_cmd->hdr.offset = offset; config_cmd->hdr.client_id = 0xff; - config_cmd->hdr.reserved1 = 0; + /* Mark that this ramrod doesn't use bp->set_mac_pending for + * synchronization. + */ + config_cmd->hdr.echo = 0; - bp->set_mac_pending = 1; - smp_wmb(); + mb(); - bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, + return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); } -static void bnx2x_invlidate_e1_mc_list(struct bnx2x *bp) + +void bnx2x_invalidate_e1_mc_list(struct bnx2x *bp) { int i; struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config); dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config); int ramrod_flags = WAIT_RAMROD_COMMON; + u8 offset = bnx2x_e1_cam_mc_offset(bp); - bp->set_mac_pending = 1; - smp_wmb(); - - for (i = 0; i < config_cmd->hdr.length; i++) + for (i = 0; i < BNX2X_MAX_MULTICAST; i++) SET_FLAG(config_cmd->config_table[i].flags, MAC_CONFIGURATION_ENTRY_ACTION_TYPE, T_ETH_MAC_COMMAND_INVALIDATE); + wmb(); + + config_cmd->hdr.length = BNX2X_MAX_MULTICAST; + config_cmd->hdr.offset = offset; + config_cmd->hdr.client_id = 0xff; + /* We'll wait for a completion this time... */ + config_cmd->hdr.echo = 1; + + bp->set_mac_pending = 1; + + mb(); + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); @@ -6439,6 +6494,44 @@ static void bnx2x_invlidate_e1_mc_list(struct bnx2x *bp) } +/* Accept one or more multicasts */ +static int bnx2x_set_e1h_mc_list(struct bnx2x *bp) +{ + struct net_device *dev = bp->dev; + struct netdev_hw_addr *ha; + u32 mc_filter[MC_HASH_SIZE]; + u32 crc, bit, regidx; + int i; + + memset(mc_filter, 0, 4 * MC_HASH_SIZE); + + netdev_for_each_mc_addr(ha, dev) { + DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n", + bnx2x_mc_addr(ha)); + + crc = crc32c_le(0, bnx2x_mc_addr(ha), + ETH_ALEN); + bit = (crc >> 24) & 0xff; + regidx = bit >> 5; + bit &= 0x1f; + mc_filter[regidx] |= (1 << bit); + } + + for (i = 0; i < MC_HASH_SIZE; i++) + REG_WR(bp, MC_HASH_OFFSET(bp, i), + mc_filter[i]); + + return 0; +} + +void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp) +{ + int i; + + for (i = 0; i < MC_HASH_SIZE; i++) + REG_WR(bp, MC_HASH_OFFSET(bp, i), 0); +} + #ifdef BCM_CNIC /** * Set iSCSI MAC(s) at the next enties in the CAM after the ETH @@ -7105,20 +7198,15 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) /* Give HW time to discard old tx messages */ msleep(1); - if (CHIP_IS_E1(bp)) { - /* invalidate mc list, - * wait and poll (interrupts are off) - */ - bnx2x_invlidate_e1_mc_list(bp); - bnx2x_set_eth_mac(bp, 0); - - } else { - REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0); + bnx2x_set_eth_mac(bp, 0); - bnx2x_set_eth_mac(bp, 0); + bnx2x_invalidate_uc_list(bp); - for (i = 0; i < MC_HASH_SIZE; i++) - REG_WR(bp, MC_HASH_OFFSET(bp, i), 0); + if (CHIP_IS_E1(bp)) + bnx2x_invalidate_e1_mc_list(bp); + else { + bnx2x_invalidate_e1h_mc_list(bp); + REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0); } #ifdef BCM_CNIC @@ -8890,12 +8978,197 @@ static int bnx2x_close(struct net_device *dev) return 0; } +#define E1_MAX_UC_LIST 29 +#define E1H_MAX_UC_LIST 30 +#define E2_MAX_UC_LIST 14 +static inline u8 bnx2x_max_uc_list(struct bnx2x *bp) +{ + if (CHIP_IS_E1(bp)) + return E1_MAX_UC_LIST; + else if (CHIP_IS_E1H(bp)) + return E1H_MAX_UC_LIST; + else + return E2_MAX_UC_LIST; +} + + +static inline u8 bnx2x_uc_list_cam_offset(struct bnx2x *bp) +{ + if (CHIP_IS_E1(bp)) + /* CAM Entries for Port0: + * 0 - prim ETH MAC + * 1 - BCAST MAC + * 2 - iSCSI L2 ring ETH MAC + * 3-31 - UC MACs + * + * Port1 entries are allocated the same way starting from + * entry 32. + */ + return 3 + 32 * BP_PORT(bp); + else if (CHIP_IS_E1H(bp)) { + /* CAM Entries: + * 0-7 - prim ETH MAC for each function + * 8-15 - iSCSI L2 ring ETH MAC for each function + * 16 till 255 UC MAC lists for each function + * + * Remark: There is no FCoE support for E1H, thus FCoE related + * MACs are not considered. + */ + return E1H_FUNC_MAX * (CAM_ISCSI_ETH_LINE + 1) + + bnx2x_max_uc_list(bp) * BP_FUNC(bp); + } else { + /* CAM Entries (there is a separate CAM per engine): + * 0-4 - prim ETH MAC for each function + * 4-7 - iSCSI L2 ring ETH MAC for each function + * 8-11 - FIP ucast L2 MAC for each function + * 12-15 - ALL_ENODE_MACS mcast MAC for each function + * 16 till 71 UC MAC lists for each function + */ + u8 func_idx = + (CHIP_MODE_IS_4_PORT(bp) ? BP_FUNC(bp) : BP_VN(bp)); + + return E2_FUNC_MAX * (CAM_MAX_PF_LINE + 1) + + bnx2x_max_uc_list(bp) * func_idx; + } +} + +/* set uc list, do not wait as wait implies sleep and + * set_rx_mode can be invoked from non-sleepable context. + * + * Instead we use the same ramrod data buffer each time we need + * to configure a list of addresses, and use the fact that the + * list of MACs is changed in an incremental way and that the + * function is called under the netif_addr_lock. A temporary + * inconsistent CAM configuration (possible in case of very fast + * sequence of add/del/add on the host side) will shortly be + * restored by the handler of the last ramrod. + */ +static int bnx2x_set_uc_list(struct bnx2x *bp) +{ + int i = 0, old; + struct net_device *dev = bp->dev; + u8 offset = bnx2x_uc_list_cam_offset(bp); + struct netdev_hw_addr *ha; + struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, uc_mac_config); + dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, uc_mac_config); + + if (netdev_uc_count(dev) > bnx2x_max_uc_list(bp)) + return -EINVAL; + + netdev_for_each_uc_addr(ha, dev) { + /* copy mac */ + config_cmd->config_table[i].msb_mac_addr = + swab16(*(u16 *)&bnx2x_uc_addr(ha)[0]); + config_cmd->config_table[i].middle_mac_addr = + swab16(*(u16 *)&bnx2x_uc_addr(ha)[2]); + config_cmd->config_table[i].lsb_mac_addr = + swab16(*(u16 *)&bnx2x_uc_addr(ha)[4]); + + config_cmd->config_table[i].vlan_id = 0; + config_cmd->config_table[i].pf_id = BP_FUNC(bp); + config_cmd->config_table[i].clients_bit_vector = + cpu_to_le32(1 << BP_L_ID(bp)); + + SET_FLAG(config_cmd->config_table[i].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_SET); + + DP(NETIF_MSG_IFUP, + "setting UCAST[%d] (%04x:%04x:%04x)\n", i, + config_cmd->config_table[i].msb_mac_addr, + config_cmd->config_table[i].middle_mac_addr, + config_cmd->config_table[i].lsb_mac_addr); + + i++; + + /* Set uc MAC in NIG */ + bnx2x_set_mac_in_nig(bp, 1, bnx2x_uc_addr(ha), + LLH_CAM_ETH_LINE + i); + } + old = config_cmd->hdr.length; + if (old > i) { + for (; i < old; i++) { + if (CAM_IS_INVALID(config_cmd-> + config_table[i])) { + /* already invalidated */ + break; + } + /* invalidate */ + SET_FLAG(config_cmd->config_table[i].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_INVALIDATE); + } + } + + wmb(); + + config_cmd->hdr.length = i; + config_cmd->hdr.offset = offset; + config_cmd->hdr.client_id = 0xff; + /* Mark that this ramrod doesn't use bp->set_mac_pending for + * synchronization. + */ + config_cmd->hdr.echo = 0; + + mb(); + + return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, + U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); + +} + +void bnx2x_invalidate_uc_list(struct bnx2x *bp) +{ + int i; + struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, uc_mac_config); + dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, uc_mac_config); + int ramrod_flags = WAIT_RAMROD_COMMON; + u8 offset = bnx2x_uc_list_cam_offset(bp); + u8 max_list_size = bnx2x_max_uc_list(bp); + + for (i = 0; i < max_list_size; i++) { + SET_FLAG(config_cmd->config_table[i].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_INVALIDATE); + bnx2x_set_mac_in_nig(bp, 0, NULL, LLH_CAM_ETH_LINE + 1 + i); + } + + wmb(); + + config_cmd->hdr.length = max_list_size; + config_cmd->hdr.offset = offset; + config_cmd->hdr.client_id = 0xff; + /* We'll wait for a completion this time... */ + config_cmd->hdr.echo = 1; + + bp->set_mac_pending = 1; + + mb(); + + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, + U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); + + /* Wait for a completion */ + bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, + ramrod_flags); + +} + +static inline int bnx2x_set_mc_list(struct bnx2x *bp) +{ + /* some multicasts */ + if (CHIP_IS_E1(bp)) { + return bnx2x_set_e1_mc_list(bp); + } else { /* E1H and newer */ + return bnx2x_set_e1h_mc_list(bp); + } +} + /* called with netif_tx_lock from dev_mcast.c */ void bnx2x_set_rx_mode(struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); u32 rx_mode = BNX2X_RX_MODE_NORMAL; - int port = BP_PORT(bp); if (bp->state != BNX2X_STATE_OPEN) { DP(NETIF_MSG_IFUP, "state is %x, returning\n", bp->state); @@ -8906,47 +9179,16 @@ void bnx2x_set_rx_mode(struct net_device *dev) if (dev->flags & IFF_PROMISC) rx_mode = BNX2X_RX_MODE_PROMISC; - else if ((dev->flags & IFF_ALLMULTI) || - ((netdev_mc_count(dev) > BNX2X_MAX_MULTICAST) && - CHIP_IS_E1(bp))) + else if (dev->flags & IFF_ALLMULTI) rx_mode = BNX2X_RX_MODE_ALLMULTI; - else { /* some multicasts */ - if (CHIP_IS_E1(bp)) { - /* - * set mc list, do not wait as wait implies sleep - * and set_rx_mode can be invoked from non-sleepable - * context - */ - u8 offset = (CHIP_REV_IS_SLOW(bp) ? - BNX2X_MAX_EMUL_MULTI*(1 + port) : - BNX2X_MAX_MULTICAST*(1 + port)); - - bnx2x_set_e1_mc_list(bp, offset); - } else { /* E1H */ - /* Accept one or more multicasts */ - struct netdev_hw_addr *ha; - u32 mc_filter[MC_HASH_SIZE]; - u32 crc, bit, regidx; - int i; - - memset(mc_filter, 0, 4 * MC_HASH_SIZE); - - netdev_for_each_mc_addr(ha, dev) { - DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n", - bnx2x_mc_addr(ha)); - - crc = crc32c_le(0, bnx2x_mc_addr(ha), - ETH_ALEN); - bit = (crc >> 24) & 0xff; - regidx = bit >> 5; - bit &= 0x1f; - mc_filter[regidx] |= (1 << bit); - } + else { + /* some multicasts */ + if (bnx2x_set_mc_list(bp)) + rx_mode = BNX2X_RX_MODE_ALLMULTI; - for (i = 0; i < MC_HASH_SIZE; i++) - REG_WR(bp, MC_HASH_OFFSET(bp, i), - mc_filter[i]); - } + /* some unicasts */ + if (bnx2x_set_uc_list(bp)) + rx_mode = BNX2X_RX_MODE_PROMISC; } bp->rx_mode = rx_mode; @@ -9027,7 +9269,7 @@ static const struct net_device_ops bnx2x_netdev_ops = { .ndo_stop = bnx2x_close, .ndo_start_xmit = bnx2x_start_xmit, .ndo_select_queue = bnx2x_select_queue, - .ndo_set_multicast_list = bnx2x_set_rx_mode, + .ndo_set_rx_mode = bnx2x_set_rx_mode, .ndo_set_mac_address = bnx2x_change_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = bnx2x_ioctl, @@ -9853,15 +10095,21 @@ static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count) HW_CID(bp, BNX2X_ISCSI_ETH_CID)); } - /* There may be not more than 8 L2 and COMMON SPEs and not more - * than 8 L5 SPEs in the air. + /* There may be not more than 8 L2 and not more than 8 L5 SPEs + * We also check that the number of outstanding + * COMMON ramrods is not more than the EQ and SPQ can + * accommodate. */ - if ((type == NONE_CONNECTION_TYPE) || - (type == ETH_CONNECTION_TYPE)) { - if (!atomic_read(&bp->spq_left)) + if (type == ETH_CONNECTION_TYPE) { + if (!atomic_read(&bp->cq_spq_left)) + break; + else + atomic_dec(&bp->cq_spq_left); + } else if (type == NONE_CONNECTION_TYPE) { + if (!atomic_read(&bp->eq_spq_left)) break; else - atomic_dec(&bp->spq_left); + atomic_dec(&bp->eq_spq_left); } else if ((type == ISCSI_CONNECTION_TYPE) || (type == FCOE_CONNECTION_TYPE)) { if (bp->cnic_spq_pending >= @@ -10054,7 +10302,7 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) int count = ctl->data.credit.credit_count; smp_mb__before_atomic_inc(); - atomic_add(count, &bp->spq_left); + atomic_add(count, &bp->cq_spq_left); smp_mb__after_atomic_inc(); break; } -- cgit v1.2.3 From 8a375557e303e4d082612bc3d79b23502a2a2a38 Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Fri, 4 Feb 2011 12:57:16 +0000 Subject: enic: Decouple mac address registration and deregistration from port profile set operation This patch removes VM mac address registration and deregistration code during port profile set operation. We can delay mac address registration until enic_open. Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: Christian Benvenuti Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 2 +- drivers/net/enic/enic_main.c | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index ca3be4f15556..44865bb10c96 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "2.1.1.2" +#define DRV_VERSION "2.1.1.2a" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 89664c670972..37f907b32d68 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1381,9 +1381,6 @@ static int enic_set_vf_port(struct net_device *netdev, int vf, if (is_zero_ether_addr(netdev->dev_addr)) random_ether_addr(netdev->dev_addr); - } else if (new_pp.request == PORT_REQUEST_DISASSOCIATE) { - if (!is_zero_ether_addr(enic->pp.mac_addr)) - enic_dev_del_addr(enic, enic->pp.mac_addr); } memcpy(&enic->pp, &new_pp, sizeof(struct enic_port_profile)); @@ -1392,9 +1389,6 @@ static int enic_set_vf_port(struct net_device *netdev, int vf, if (err) goto set_port_profile_cleanup; - if (!is_zero_ether_addr(enic->pp.mac_addr)) - enic_dev_add_addr(enic, enic->pp.mac_addr); - set_port_profile_cleanup: memset(enic->pp.vf_mac, 0, ETH_ALEN); -- cgit v1.2.3 From 519874619f642afaf61530b0f4df3cd1e9a319e4 Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Fri, 4 Feb 2011 16:17:05 +0000 Subject: enic: Clean up: Organize devcmd wrapper routines Organize the wrapper routines for firmware devcmds into a separate file. Signed-off-by: Christian Benvenuti Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/Makefile | 2 +- drivers/net/enic/enic.h | 2 +- drivers/net/enic/enic_dev.c | 230 +++++++++++++++++++++++++++++++++++++++++++ drivers/net/enic/enic_dev.h | 42 ++++++++ drivers/net/enic/enic_main.c | 207 +------------------------------------- 5 files changed, 275 insertions(+), 208 deletions(-) create mode 100644 drivers/net/enic/enic_dev.c create mode 100644 drivers/net/enic/enic_dev.h (limited to 'drivers') diff --git a/drivers/net/enic/Makefile b/drivers/net/enic/Makefile index e7b6c31880ba..2e573be16c13 100644 --- a/drivers/net/enic/Makefile +++ b/drivers/net/enic/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_ENIC) := enic.o enic-y := enic_main.o vnic_cq.o vnic_intr.o vnic_wq.o \ - enic_res.o vnic_dev.o vnic_rq.o vnic_vic.o + enic_res.o enic_dev.o vnic_dev.o vnic_rq.o vnic_vic.o diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 44865bb10c96..1385a609ed49 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "2.1.1.2a" +#define DRV_VERSION "2.1.1.3" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 diff --git a/drivers/net/enic/enic_dev.c b/drivers/net/enic/enic_dev.c new file mode 100644 index 000000000000..a52dbd2b3c63 --- /dev/null +++ b/drivers/net/enic/enic_dev.c @@ -0,0 +1,230 @@ +/* + * Copyright 2011 Cisco Systems, Inc. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#include +#include + +#include "vnic_dev.h" +#include "vnic_vic.h" +#include "enic_res.h" +#include "enic.h" +#include "enic_dev.h" + +int enic_dev_fw_info(struct enic *enic, struct vnic_devcmd_fw_info **fw_info) +{ + int err; + + spin_lock(&enic->devcmd_lock); + err = vnic_dev_fw_info(enic->vdev, fw_info); + spin_unlock(&enic->devcmd_lock); + + return err; +} + +int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats) +{ + int err; + + spin_lock(&enic->devcmd_lock); + err = vnic_dev_stats_dump(enic->vdev, vstats); + spin_unlock(&enic->devcmd_lock); + + return err; +} + +int enic_dev_add_station_addr(struct enic *enic) +{ + int err = 0; + + if (is_valid_ether_addr(enic->netdev->dev_addr)) { + spin_lock(&enic->devcmd_lock); + err = vnic_dev_add_addr(enic->vdev, enic->netdev->dev_addr); + spin_unlock(&enic->devcmd_lock); + } + + return err; +} + +int enic_dev_del_station_addr(struct enic *enic) +{ + int err = 0; + + if (is_valid_ether_addr(enic->netdev->dev_addr)) { + spin_lock(&enic->devcmd_lock); + err = vnic_dev_del_addr(enic->vdev, enic->netdev->dev_addr); + spin_unlock(&enic->devcmd_lock); + } + + return err; +} + +int enic_dev_packet_filter(struct enic *enic, int directed, int multicast, + int broadcast, int promisc, int allmulti) +{ + int err; + + spin_lock(&enic->devcmd_lock); + err = vnic_dev_packet_filter(enic->vdev, directed, + multicast, broadcast, promisc, allmulti); + spin_unlock(&enic->devcmd_lock); + + return err; +} + +int enic_dev_add_addr(struct enic *enic, u8 *addr) +{ + int err; + + spin_lock(&enic->devcmd_lock); + err = vnic_dev_add_addr(enic->vdev, addr); + spin_unlock(&enic->devcmd_lock); + + return err; +} + +int enic_dev_del_addr(struct enic *enic, u8 *addr) +{ + int err; + + spin_lock(&enic->devcmd_lock); + err = vnic_dev_del_addr(enic->vdev, addr); + spin_unlock(&enic->devcmd_lock); + + return err; +} + +int enic_dev_hw_version(struct enic *enic, enum vnic_dev_hw_version *hw_ver) +{ + int err; + + spin_lock(&enic->devcmd_lock); + err = vnic_dev_hw_version(enic->vdev, hw_ver); + spin_unlock(&enic->devcmd_lock); + + return err; +} + +int enic_dev_notify_unset(struct enic *enic) +{ + int err; + + spin_lock(&enic->devcmd_lock); + err = vnic_dev_notify_unset(enic->vdev); + spin_unlock(&enic->devcmd_lock); + + return err; +} + +int enic_dev_hang_notify(struct enic *enic) +{ + int err; + + spin_lock(&enic->devcmd_lock); + err = vnic_dev_hang_notify(enic->vdev); + spin_unlock(&enic->devcmd_lock); + + return err; +} + +int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic) +{ + int err; + + spin_lock(&enic->devcmd_lock); + err = vnic_dev_set_ig_vlan_rewrite_mode(enic->vdev, + IG_VLAN_REWRITE_MODE_PRIORITY_TAG_DEFAULT_VLAN); + spin_unlock(&enic->devcmd_lock); + + return err; +} + +int enic_dev_enable(struct enic *enic) +{ + int err; + + spin_lock(&enic->devcmd_lock); + err = vnic_dev_enable_wait(enic->vdev); + spin_unlock(&enic->devcmd_lock); + + return err; +} + +int enic_dev_disable(struct enic *enic) +{ + int err; + + spin_lock(&enic->devcmd_lock); + err = vnic_dev_disable(enic->vdev); + spin_unlock(&enic->devcmd_lock); + + return err; +} + +int enic_vnic_dev_deinit(struct enic *enic) +{ + int err; + + spin_lock(&enic->devcmd_lock); + err = vnic_dev_deinit(enic->vdev); + spin_unlock(&enic->devcmd_lock); + + return err; +} + +int enic_dev_init_prov(struct enic *enic, struct vic_provinfo *vp) +{ + int err; + + spin_lock(&enic->devcmd_lock); + err = vnic_dev_init_prov(enic->vdev, + (u8 *)vp, vic_provinfo_size(vp)); + spin_unlock(&enic->devcmd_lock); + + return err; +} + +int enic_dev_init_done(struct enic *enic, int *done, int *error) +{ + int err; + + spin_lock(&enic->devcmd_lock); + err = vnic_dev_init_done(enic->vdev, done, error); + spin_unlock(&enic->devcmd_lock); + + return err; +} + +/* rtnl lock is held */ +void enic_vlan_rx_add_vid(struct net_device *netdev, u16 vid) +{ + struct enic *enic = netdev_priv(netdev); + + spin_lock(&enic->devcmd_lock); + enic_add_vlan(enic, vid); + spin_unlock(&enic->devcmd_lock); +} + +/* rtnl lock is held */ +void enic_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) +{ + struct enic *enic = netdev_priv(netdev); + + spin_lock(&enic->devcmd_lock); + enic_del_vlan(enic, vid); + spin_unlock(&enic->devcmd_lock); +} diff --git a/drivers/net/enic/enic_dev.h b/drivers/net/enic/enic_dev.h new file mode 100644 index 000000000000..3ac6ba1db25b --- /dev/null +++ b/drivers/net/enic/enic_dev.h @@ -0,0 +1,42 @@ +/* + * Copyright 2011 Cisco Systems, Inc. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#ifndef _ENIC_DEV_H_ +#define _ENIC_DEV_H_ + +int enic_dev_fw_info(struct enic *enic, struct vnic_devcmd_fw_info **fw_info); +int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats); +int enic_dev_add_station_addr(struct enic *enic); +int enic_dev_del_station_addr(struct enic *enic); +int enic_dev_packet_filter(struct enic *enic, int directed, int multicast, + int broadcast, int promisc, int allmulti); +int enic_dev_add_addr(struct enic *enic, u8 *addr); +int enic_dev_del_addr(struct enic *enic, u8 *addr); +void enic_vlan_rx_add_vid(struct net_device *netdev, u16 vid); +void enic_vlan_rx_kill_vid(struct net_device *netdev, u16 vid); +int enic_dev_hw_version(struct enic *enic, enum vnic_dev_hw_version *hw_ver); +int enic_dev_notify_unset(struct enic *enic); +int enic_dev_hang_notify(struct enic *enic); +int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic); +int enic_dev_enable(struct enic *enic); +int enic_dev_disable(struct enic *enic); +int enic_vnic_dev_deinit(struct enic *enic); +int enic_dev_init_prov(struct enic *enic, struct vic_provinfo *vp); +int enic_dev_init_done(struct enic *enic, int *done, int *error); + +#endif /* _ENIC_DEV_H_ */ diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 37f907b32d68..3893370d95a8 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -44,6 +44,7 @@ #include "vnic_vic.h" #include "enic_res.h" #include "enic.h" +#include "enic_dev.h" #define ENIC_NOTIFY_TIMER_PERIOD (2 * HZ) #define WQ_ENET_MAX_DESC_LEN (1 << WQ_ENET_LEN_BITS) @@ -190,18 +191,6 @@ static int enic_get_settings(struct net_device *netdev, return 0; } -static int enic_dev_fw_info(struct enic *enic, - struct vnic_devcmd_fw_info **fw_info) -{ - int err; - - spin_lock(&enic->devcmd_lock); - err = vnic_dev_fw_info(enic->vdev, fw_info); - spin_unlock(&enic->devcmd_lock); - - return err; -} - static void enic_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) { @@ -246,17 +235,6 @@ static int enic_get_sset_count(struct net_device *netdev, int sset) } } -static int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats) -{ - int err; - - spin_lock(&enic->devcmd_lock); - err = vnic_dev_stats_dump(enic->vdev, vstats); - spin_unlock(&enic->devcmd_lock); - - return err; -} - static void enic_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, u64 *data) { @@ -919,32 +897,6 @@ static int enic_set_mac_addr(struct net_device *netdev, char *addr) return 0; } -static int enic_dev_add_station_addr(struct enic *enic) -{ - int err = 0; - - if (is_valid_ether_addr(enic->netdev->dev_addr)) { - spin_lock(&enic->devcmd_lock); - err = vnic_dev_add_addr(enic->vdev, enic->netdev->dev_addr); - spin_unlock(&enic->devcmd_lock); - } - - return err; -} - -static int enic_dev_del_station_addr(struct enic *enic) -{ - int err = 0; - - if (is_valid_ether_addr(enic->netdev->dev_addr)) { - spin_lock(&enic->devcmd_lock); - err = vnic_dev_del_addr(enic->vdev, enic->netdev->dev_addr); - spin_unlock(&enic->devcmd_lock); - } - - return err; -} - static int enic_set_mac_address_dynamic(struct net_device *netdev, void *p) { struct enic *enic = netdev_priv(netdev); @@ -989,41 +941,6 @@ static int enic_set_mac_address(struct net_device *netdev, void *p) return enic_dev_add_station_addr(enic); } -static int enic_dev_packet_filter(struct enic *enic, int directed, - int multicast, int broadcast, int promisc, int allmulti) -{ - int err; - - spin_lock(&enic->devcmd_lock); - err = vnic_dev_packet_filter(enic->vdev, directed, - multicast, broadcast, promisc, allmulti); - spin_unlock(&enic->devcmd_lock); - - return err; -} - -static int enic_dev_add_addr(struct enic *enic, u8 *addr) -{ - int err; - - spin_lock(&enic->devcmd_lock); - err = vnic_dev_add_addr(enic->vdev, addr); - spin_unlock(&enic->devcmd_lock); - - return err; -} - -static int enic_dev_del_addr(struct enic *enic, u8 *addr) -{ - int err; - - spin_lock(&enic->devcmd_lock); - err = vnic_dev_del_addr(enic->vdev, addr); - spin_unlock(&enic->devcmd_lock); - - return err; -} - static void enic_add_multicast_addr_list(struct enic *enic) { struct net_device *netdev = enic->netdev; @@ -1170,26 +1087,6 @@ static void enic_vlan_rx_register(struct net_device *netdev, enic->vlan_group = vlan_group; } -/* rtnl lock is held */ -static void enic_vlan_rx_add_vid(struct net_device *netdev, u16 vid) -{ - struct enic *enic = netdev_priv(netdev); - - spin_lock(&enic->devcmd_lock); - enic_add_vlan(enic, vid); - spin_unlock(&enic->devcmd_lock); -} - -/* rtnl lock is held */ -static void enic_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) -{ - struct enic *enic = netdev_priv(netdev); - - spin_lock(&enic->devcmd_lock); - enic_del_vlan(enic, vid); - spin_unlock(&enic->devcmd_lock); -} - /* netif_tx_lock held, BHs disabled */ static void enic_tx_timeout(struct net_device *netdev) { @@ -1197,40 +1094,6 @@ static void enic_tx_timeout(struct net_device *netdev) schedule_work(&enic->reset); } -static int enic_vnic_dev_deinit(struct enic *enic) -{ - int err; - - spin_lock(&enic->devcmd_lock); - err = vnic_dev_deinit(enic->vdev); - spin_unlock(&enic->devcmd_lock); - - return err; -} - -static int enic_dev_init_prov(struct enic *enic, struct vic_provinfo *vp) -{ - int err; - - spin_lock(&enic->devcmd_lock); - err = vnic_dev_init_prov(enic->vdev, - (u8 *)vp, vic_provinfo_size(vp)); - spin_unlock(&enic->devcmd_lock); - - return err; -} - -static int enic_dev_init_done(struct enic *enic, int *done, int *error) -{ - int err; - - spin_lock(&enic->devcmd_lock); - err = vnic_dev_init_done(enic->vdev, done, error); - spin_unlock(&enic->devcmd_lock); - - return err; -} - static int enic_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) { struct enic *enic = netdev_priv(netdev); @@ -1505,18 +1368,6 @@ static int enic_rq_alloc_buf_a1(struct vnic_rq *rq) return 0; } -static int enic_dev_hw_version(struct enic *enic, - enum vnic_dev_hw_version *hw_ver) -{ - int err; - - spin_lock(&enic->devcmd_lock); - err = vnic_dev_hw_version(enic->vdev, hw_ver); - spin_unlock(&enic->devcmd_lock); - - return err; -} - static int enic_set_rq_alloc_buf(struct enic *enic) { enum vnic_dev_hw_version hw_ver; @@ -1897,39 +1748,6 @@ static int enic_dev_notify_set(struct enic *enic) return err; } -static int enic_dev_notify_unset(struct enic *enic) -{ - int err; - - spin_lock(&enic->devcmd_lock); - err = vnic_dev_notify_unset(enic->vdev); - spin_unlock(&enic->devcmd_lock); - - return err; -} - -static int enic_dev_enable(struct enic *enic) -{ - int err; - - spin_lock(&enic->devcmd_lock); - err = vnic_dev_enable_wait(enic->vdev); - spin_unlock(&enic->devcmd_lock); - - return err; -} - -static int enic_dev_disable(struct enic *enic) -{ - int err; - - spin_lock(&enic->devcmd_lock); - err = vnic_dev_disable(enic->vdev); - spin_unlock(&enic->devcmd_lock); - - return err; -} - static void enic_notify_timer_start(struct enic *enic) { switch (vnic_dev_get_intr_mode(enic->vdev)) { @@ -2281,29 +2099,6 @@ static int enic_set_rss_nic_cfg(struct enic *enic) rss_hash_bits, rss_base_cpu, rss_enable); } -static int enic_dev_hang_notify(struct enic *enic) -{ - int err; - - spin_lock(&enic->devcmd_lock); - err = vnic_dev_hang_notify(enic->vdev); - spin_unlock(&enic->devcmd_lock); - - return err; -} - -static int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic) -{ - int err; - - spin_lock(&enic->devcmd_lock); - err = vnic_dev_set_ig_vlan_rewrite_mode(enic->vdev, - IG_VLAN_REWRITE_MODE_PRIORITY_TAG_DEFAULT_VLAN); - spin_unlock(&enic->devcmd_lock); - - return err; -} - static void enic_reset(struct work_struct *work) { struct enic *enic = container_of(work, struct enic, reset); -- cgit v1.2.3 From 115d56f723c45088ddf46fac1ebba7c333039150 Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Fri, 4 Feb 2011 16:17:10 +0000 Subject: enic: Bug Fix: Fix return values of enic_add/del_station_addr routines Fix enic_add/del_station_addr routines to return appropriate error code when an invalid address is added or deleted. Signed-off-by: Christian Benvenuti Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 2 +- drivers/net/enic/enic_dev.c | 26 ++++++++++++++------------ 2 files changed, 15 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 1385a609ed49..f38ad634989c 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "2.1.1.3" +#define DRV_VERSION "2.1.1.4" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 diff --git a/drivers/net/enic/enic_dev.c b/drivers/net/enic/enic_dev.c index a52dbd2b3c63..382626628b1b 100644 --- a/drivers/net/enic/enic_dev.c +++ b/drivers/net/enic/enic_dev.c @@ -49,26 +49,28 @@ int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats) int enic_dev_add_station_addr(struct enic *enic) { - int err = 0; + int err; + + if (!is_valid_ether_addr(enic->netdev->dev_addr)) + return -EADDRNOTAVAIL; - if (is_valid_ether_addr(enic->netdev->dev_addr)) { - spin_lock(&enic->devcmd_lock); - err = vnic_dev_add_addr(enic->vdev, enic->netdev->dev_addr); - spin_unlock(&enic->devcmd_lock); - } + spin_lock(&enic->devcmd_lock); + err = vnic_dev_add_addr(enic->vdev, enic->netdev->dev_addr); + spin_unlock(&enic->devcmd_lock); return err; } int enic_dev_del_station_addr(struct enic *enic) { - int err = 0; + int err; + + if (!is_valid_ether_addr(enic->netdev->dev_addr)) + return -EADDRNOTAVAIL; - if (is_valid_ether_addr(enic->netdev->dev_addr)) { - spin_lock(&enic->devcmd_lock); - err = vnic_dev_del_addr(enic->vdev, enic->netdev->dev_addr); - spin_unlock(&enic->devcmd_lock); - } + spin_lock(&enic->devcmd_lock); + err = vnic_dev_del_addr(enic->vdev, enic->netdev->dev_addr); + spin_unlock(&enic->devcmd_lock); return err; } -- cgit v1.2.3 From 69161425800ac6cc28ac448bef5f21d09cb4f92a Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Fri, 4 Feb 2011 16:17:16 +0000 Subject: enic: Bug Fix: Reorder firmware devcmds - CMD_INIT and CMD_IG_VLAN_REWRITE_MODE Firmware requires CMD_IG_VLAN_REWRITE_MODE be issued before a CMD_INIT. Signed-off-by: Christian Benvenuti Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 2 +- drivers/net/enic/enic_main.c | 28 ++++++++++++++++------------ 2 files changed, 17 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index f38ad634989c..7316267e3ade 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "2.1.1.4" +#define DRV_VERSION "2.1.1.5" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 3893370d95a8..d6cdecc7d1e6 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -2359,13 +2359,6 @@ static int enic_dev_init(struct enic *enic) goto err_out_free_vnic_resources; } - err = enic_dev_set_ig_vlan_rewrite_mode(enic); - if (err) { - dev_err(dev, - "Failed to set ingress vlan rewrite mode, aborting.\n"); - goto err_out_free_vnic_resources; - } - switch (vnic_dev_get_intr_mode(enic->vdev)) { default: netif_napi_add(netdev, &enic->napi[0], enic_poll, 64); @@ -2504,6 +2497,22 @@ static int __devinit enic_probe(struct pci_dev *pdev, goto err_out_vnic_unregister; } + /* Setup devcmd lock + */ + + spin_lock_init(&enic->devcmd_lock); + + /* + * Set ingress vlan rewrite mode before vnic initialization + */ + + err = enic_dev_set_ig_vlan_rewrite_mode(enic); + if (err) { + dev_err(dev, + "Failed to set ingress vlan rewrite mode, aborting.\n"); + goto err_out_dev_close; + } + /* Issue device init to initialize the vnic-to-switch link. * We'll start with carrier off and wait for link UP * notification later to turn on carrier. We don't need @@ -2527,11 +2536,6 @@ static int __devinit enic_probe(struct pci_dev *pdev, } } - /* Setup devcmd lock - */ - - spin_lock_init(&enic->devcmd_lock); - err = enic_dev_init(enic); if (err) { dev_err(dev, "Device initialization failed, aborting\n"); -- cgit v1.2.3 From 0eb2602238e5aa33e0571a76aaf51a30bf32c3c2 Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Fri, 4 Feb 2011 16:17:21 +0000 Subject: enic: Clean up: Remove support for an older version of hardware Remove support for an older version (A1) of hardware Signed-off-by: Christian Benvenuti Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 3 +-- drivers/net/enic/enic_dev.c | 11 --------- drivers/net/enic/enic_dev.h | 1 - drivers/net/enic/enic_main.c | 56 +++----------------------------------------- drivers/net/enic/vnic_dev.c | 19 --------------- drivers/net/enic/vnic_dev.h | 8 ------- drivers/net/enic/vnic_rq.h | 5 ---- 7 files changed, 4 insertions(+), 99 deletions(-) (limited to 'drivers') diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 7316267e3ade..57fcaeea94f7 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "2.1.1.5" +#define DRV_VERSION "2.1.1.6" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 @@ -101,7 +101,6 @@ struct enic { /* receive queue cache line section */ ____cacheline_aligned struct vnic_rq rq[ENIC_RQ_MAX]; unsigned int rq_count; - int (*rq_alloc_buf)(struct vnic_rq *rq); u64 rq_truncated_pkts; u64 rq_bad_fcs; struct napi_struct napi[ENIC_RQ_MAX]; diff --git a/drivers/net/enic/enic_dev.c b/drivers/net/enic/enic_dev.c index 382626628b1b..37ad3a1c82ee 100644 --- a/drivers/net/enic/enic_dev.c +++ b/drivers/net/enic/enic_dev.c @@ -110,17 +110,6 @@ int enic_dev_del_addr(struct enic *enic, u8 *addr) return err; } -int enic_dev_hw_version(struct enic *enic, enum vnic_dev_hw_version *hw_ver) -{ - int err; - - spin_lock(&enic->devcmd_lock); - err = vnic_dev_hw_version(enic->vdev, hw_ver); - spin_unlock(&enic->devcmd_lock); - - return err; -} - int enic_dev_notify_unset(struct enic *enic) { int err; diff --git a/drivers/net/enic/enic_dev.h b/drivers/net/enic/enic_dev.h index 3ac6ba1db25b..495f57fcb887 100644 --- a/drivers/net/enic/enic_dev.h +++ b/drivers/net/enic/enic_dev.h @@ -29,7 +29,6 @@ int enic_dev_add_addr(struct enic *enic, u8 *addr); int enic_dev_del_addr(struct enic *enic, u8 *addr); void enic_vlan_rx_add_vid(struct net_device *netdev, u16 vid); void enic_vlan_rx_kill_vid(struct net_device *netdev, u16 vid); -int enic_dev_hw_version(struct enic *enic, enum vnic_dev_hw_version *hw_ver); int enic_dev_notify_unset(struct enic *enic); int enic_dev_hang_notify(struct enic *enic); int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic); diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index d6cdecc7d1e6..0c243704ca40 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1348,50 +1348,6 @@ static int enic_rq_alloc_buf(struct vnic_rq *rq) return 0; } -static int enic_rq_alloc_buf_a1(struct vnic_rq *rq) -{ - struct rq_enet_desc *desc = vnic_rq_next_desc(rq); - - if (vnic_rq_posting_soon(rq)) { - - /* SW workaround for A0 HW erratum: if we're just about - * to write posted_index, insert a dummy desc - * of type resvd - */ - - rq_enet_desc_enc(desc, 0, RQ_ENET_TYPE_RESV2, 0); - vnic_rq_post(rq, 0, 0, 0, 0); - } else { - return enic_rq_alloc_buf(rq); - } - - return 0; -} - -static int enic_set_rq_alloc_buf(struct enic *enic) -{ - enum vnic_dev_hw_version hw_ver; - int err; - - err = enic_dev_hw_version(enic, &hw_ver); - if (err) - return err; - - switch (hw_ver) { - case VNIC_DEV_HW_VER_A1: - enic->rq_alloc_buf = enic_rq_alloc_buf_a1; - break; - case VNIC_DEV_HW_VER_A2: - case VNIC_DEV_HW_VER_UNKNOWN: - enic->rq_alloc_buf = enic_rq_alloc_buf; - break; - default: - return -ENODEV; - } - - return 0; -} - static void enic_rq_indicate_buf(struct vnic_rq *rq, struct cq_desc *cq_desc, struct vnic_rq_buf *buf, int skipped, void *opaque) @@ -1528,7 +1484,7 @@ static int enic_poll(struct napi_struct *napi, int budget) 0 /* don't unmask intr */, 0 /* don't reset intr timer */); - err = vnic_rq_fill(&enic->rq[0], enic->rq_alloc_buf); + err = vnic_rq_fill(&enic->rq[0], enic_rq_alloc_buf); /* Buffer allocation failed. Stay in polling * mode so we can try to fill the ring again. @@ -1578,7 +1534,7 @@ static int enic_poll_msix(struct napi_struct *napi, int budget) 0 /* don't unmask intr */, 0 /* don't reset intr timer */); - err = vnic_rq_fill(&enic->rq[rq], enic->rq_alloc_buf); + err = vnic_rq_fill(&enic->rq[rq], enic_rq_alloc_buf); /* Buffer allocation failed. Stay in polling mode * so we can try to fill the ring again. @@ -1781,7 +1737,7 @@ static int enic_open(struct net_device *netdev) } for (i = 0; i < enic->rq_count; i++) { - vnic_rq_fill(&enic->rq[i], enic->rq_alloc_buf); + vnic_rq_fill(&enic->rq[i], enic_rq_alloc_buf); /* Need at least one buffer on ring to get going */ if (vnic_rq_desc_used(&enic->rq[i]) == 0) { netdev_err(netdev, "Unable to alloc receive buffers\n"); @@ -2347,12 +2303,6 @@ static int enic_dev_init(struct enic *enic) enic_init_vnic_resources(enic); - err = enic_set_rq_alloc_buf(enic); - if (err) { - dev_err(dev, "Failed to set RQ buffer allocator, aborting\n"); - goto err_out_free_vnic_resources; - } - err = enic_set_rss_nic_cfg(enic); if (err) { dev_err(dev, "Failed to config nic, aborting\n"); diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c index fb35d8b17668..c489e72107de 100644 --- a/drivers/net/enic/vnic_dev.c +++ b/drivers/net/enic/vnic_dev.c @@ -419,25 +419,6 @@ int vnic_dev_fw_info(struct vnic_dev *vdev, return err; } -int vnic_dev_hw_version(struct vnic_dev *vdev, enum vnic_dev_hw_version *hw_ver) -{ - struct vnic_devcmd_fw_info *fw_info; - int err; - - err = vnic_dev_fw_info(vdev, &fw_info); - if (err) - return err; - - if (strncmp(fw_info->hw_version, "A1", sizeof("A1")) == 0) - *hw_ver = VNIC_DEV_HW_VER_A1; - else if (strncmp(fw_info->hw_version, "A2", sizeof("A2")) == 0) - *hw_ver = VNIC_DEV_HW_VER_A2; - else - *hw_ver = VNIC_DEV_HW_VER_UNKNOWN; - - return 0; -} - int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size, void *value) { diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h index 05f9a24cd459..e837546213a8 100644 --- a/drivers/net/enic/vnic_dev.h +++ b/drivers/net/enic/vnic_dev.h @@ -44,12 +44,6 @@ static inline void writeq(u64 val, void __iomem *reg) #undef pr_fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -enum vnic_dev_hw_version { - VNIC_DEV_HW_VER_UNKNOWN, - VNIC_DEV_HW_VER_A1, - VNIC_DEV_HW_VER_A2, -}; - enum vnic_dev_intr_mode { VNIC_DEV_INTR_MODE_UNKNOWN, VNIC_DEV_INTR_MODE_INTX, @@ -93,8 +87,6 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, u64 *a0, u64 *a1, int wait); int vnic_dev_fw_info(struct vnic_dev *vdev, struct vnic_devcmd_fw_info **fw_info); -int vnic_dev_hw_version(struct vnic_dev *vdev, - enum vnic_dev_hw_version *hw_ver); int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size, void *value); int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats); diff --git a/drivers/net/enic/vnic_rq.h b/drivers/net/enic/vnic_rq.h index 37f08de2454a..2056586f4d4b 100644 --- a/drivers/net/enic/vnic_rq.h +++ b/drivers/net/enic/vnic_rq.h @@ -141,11 +141,6 @@ static inline void vnic_rq_post(struct vnic_rq *rq, } } -static inline int vnic_rq_posting_soon(struct vnic_rq *rq) -{ - return (rq->to_use->index & VNIC_RQ_RETURN_RATE) == 0; -} - static inline void vnic_rq_return_descs(struct vnic_rq *rq, unsigned int count) { rq->ring.desc_avail += count; -- cgit v1.2.3 From c210de8f88215db31cf3529c9763fc3124d6e09d Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Fri, 4 Feb 2011 01:41:02 +0200 Subject: ath5k: Fix fast channel switching Fast channel change fixes: a) Always set OFDM timings b) Don't re-activate PHY c) Enable only NF calibration, not AGC Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 142 +++++++++++++++++++++-------------- 1 file changed, 87 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 78c26fdccad1..d673ab2f6cda 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -282,6 +282,34 @@ int ath5k_hw_phy_disable(struct ath5k_hw *ah) return 0; } +/* + * Wait for synth to settle + */ +static void ath5k_hw_wait_for_synth(struct ath5k_hw *ah, + struct ieee80211_channel *channel) +{ + /* + * On 5211+ read activation -> rx delay + * and use it (100ns steps). + */ + if (ah->ah_version != AR5K_AR5210) { + u32 delay; + delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & + AR5K_PHY_RX_DELAY_M; + delay = (channel->hw_value & CHANNEL_CCK) ? + ((delay << 2) / 22) : (delay / 10); + if (ah->ah_bwmode == AR5K_BWMODE_10MHZ) + delay = delay << 1; + if (ah->ah_bwmode == AR5K_BWMODE_5MHZ) + delay = delay << 2; + /* XXX: /2 on turbo ? Let's be safe + * for now */ + udelay(100 + delay); + } else { + mdelay(1); + } +} + /**********************\ * RF Gain optimization * @@ -3237,6 +3265,13 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, /* Failed */ if (i >= 100) return -EIO; + + /* Set channel and wait for synth */ + ret = ath5k_hw_channel(ah, channel); + if (ret) + return ret; + + ath5k_hw_wait_for_synth(ah, channel); } /* @@ -3251,13 +3286,53 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, if (ret) return ret; + /* Write OFDM timings on 5212*/ + if (ah->ah_version == AR5K_AR5212 && + channel->hw_value & CHANNEL_OFDM) { + + ret = ath5k_hw_write_ofdm_timings(ah, channel); + if (ret) + return ret; + + /* Spur info is available only from EEPROM versions + * greater than 5.3, but the EEPROM routines will use + * static values for older versions */ + if (ah->ah_mac_srev >= AR5K_SREV_AR5424) + ath5k_hw_set_spur_mitigation_filter(ah, + channel); + } + + /* If we used fast channel switching + * we are done, release RF bus and + * fire up NF calibration. + * + * Note: Only NF calibration due to + * channel change, not AGC calibration + * since AGC is still running ! + */ + if (fast) { + /* + * Release RF Bus grant + */ + AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ, + AR5K_PHY_RFBUS_REQ_REQUEST); + + /* + * Start NF calibration + */ + AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, + AR5K_PHY_AGCCTL_NF); + + return ret; + } + /* * For 5210 we do all initialization using * initvals, so we don't have to modify * any settings (5210 also only supports * a/aturbo modes) */ - if ((ah->ah_version != AR5K_AR5210) && !fast) { + if (ah->ah_version != AR5K_AR5210) { /* * Write initial RF gain settings @@ -3276,22 +3351,6 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, if (ret) return ret; - /* Write OFDM timings on 5212*/ - if (ah->ah_version == AR5K_AR5212 && - channel->hw_value & CHANNEL_OFDM) { - - ret = ath5k_hw_write_ofdm_timings(ah, channel); - if (ret) - return ret; - - /* Spur info is available only from EEPROM versions - * greater than 5.3, but the EEPROM routines will use - * static values for older versions */ - if (ah->ah_mac_srev >= AR5K_SREV_AR5424) - ath5k_hw_set_spur_mitigation_filter(ah, - channel); - } - /*Enable/disable 802.11b mode on 5111 (enable 2111 frequency converter + CCK)*/ if (ah->ah_radio == AR5K_RF5111) { @@ -3322,47 +3381,20 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, */ ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); + ath5k_hw_wait_for_synth(ah, channel); + /* - * On 5211+ read activation -> rx delay - * and use it. + * Perform ADC test to see if baseband is ready + * Set tx hold and check adc test register */ - if (ah->ah_version != AR5K_AR5210) { - u32 delay; - delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & - AR5K_PHY_RX_DELAY_M; - delay = (channel->hw_value & CHANNEL_CCK) ? - ((delay << 2) / 22) : (delay / 10); - if (ah->ah_bwmode == AR5K_BWMODE_10MHZ) - delay = delay << 1; - if (ah->ah_bwmode == AR5K_BWMODE_5MHZ) - delay = delay << 2; - /* XXX: /2 on turbo ? Let's be safe - * for now */ - udelay(100 + delay); - } else { - mdelay(1); - } - - if (fast) - /* - * Release RF Bus grant - */ - AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ, - AR5K_PHY_RFBUS_REQ_REQUEST); - else { - /* - * Perform ADC test to see if baseband is ready - * Set tx hold and check adc test register - */ - phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); - ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); - for (i = 0; i <= 20; i++) { - if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) - break; - udelay(200); - } - ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1); + phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); + ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); + for (i = 0; i <= 20; i++) { + if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) + break; + udelay(200); } + ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1); /* * Start automatic gain control calibration -- cgit v1.2.3 From 3a2329f2680796b0c09ff207803ea880a481c3a4 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Mon, 7 Feb 2011 21:08:28 +0530 Subject: ath9k: Update comments for not parsing DTIM period Add few comments for not parsing DTIM period from mac80211 Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 87ba44c06692..fcb36abfc309 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -721,8 +721,9 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) cur_conf->beacon_interval = 100; /* - * Some times we dont parse dtim period from mac80211, in that case - * use a default value + * We don't parse dtim period from mac80211 during the driver + * initialization as it breaks association with hidden-ssid + * AP and it causes latency in roaming */ if (cur_conf->dtim_period == 0) cur_conf->dtim_period = 1; -- cgit v1.2.3 From 180e9d19eed63b0b153aff9f300b913f48788e37 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 5 Feb 2011 10:46:28 +0000 Subject: platform-drivers: x86: pmic: Fix up bogus irq hackery commit 456dc301([PATCH] intel_pmic_gpio: modify EOI handling following change of kernel irq subsystem) changes - desc->chip->eoi(irq); + + if (desc->chip->irq_eoi) + desc->chip->irq_eoi(irq_get_irq_data(irq)); + else + dev_warn(pg->chip.dev, "missing EOI handler for irq %d\n", irq); With the following explanation: "Latest kernel has many changes in IRQ subsystem and its interfaces, like adding irq_eoi" for struct irq_chip, this patch will make it support both the new and old interface." This is completely bogus. #1) The changelog does not match the patch at all #2) This driver relies on the assumption that it sits behind an eoi capable interrupt line. If the implementation of the underlying chip changes from eoi to irq_eoi then this driver has to follow that change and not add a total bogosity. Remove the sillyness and retrieve the interrupt data from irq_desc directly. No need to got through circles to look it up. Signed-off-by: Thomas Gleixner Cc: Feng Tang Cc: Matthew Garrett Cc: Alan Cox Cc: Alek Du Signed-off-by: Matthew Garrett --- drivers/platform/x86/intel_pmic_gpio.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/intel_pmic_gpio.c b/drivers/platform/x86/intel_pmic_gpio.c index 930e62762365..4eed130e7c18 100644 --- a/drivers/platform/x86/intel_pmic_gpio.c +++ b/drivers/platform/x86/intel_pmic_gpio.c @@ -244,11 +244,7 @@ static void pmic_irq_handler(unsigned irq, struct irq_desc *desc) generic_handle_irq(pg->irq_base + gpio); } } - - if (desc->chip->irq_eoi) - desc->chip->irq_eoi(irq_get_irq_data(irq)); - else - dev_warn(pg->chip.dev, "missing EOI handler for irq %d\n", irq); + desc->chip->irq_eoi(get_irq_desc_chip_data(desc)); } static int __devinit platform_pmic_gpio_probe(struct platform_device *pdev) -- cgit v1.2.3 From cb8e5e6a60cab5a90afd45d49655458c6e1db78c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 5 Feb 2011 10:46:30 +0000 Subject: platform-drivers: x86: Convert pmic to new irq_chip functions Old functions will go away soon. Remove the stray semicolons while at it. Signed-off-by: Thomas Gleixner Cc: Feng Tang Cc: Matthew Garrett Cc: Alan Cox Cc: Alek Du Signed-off-by: Matthew Garrett --- drivers/platform/x86/intel_pmic_gpio.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/intel_pmic_gpio.c b/drivers/platform/x86/intel_pmic_gpio.c index 4eed130e7c18..9134d9d07569 100644 --- a/drivers/platform/x86/intel_pmic_gpio.c +++ b/drivers/platform/x86/intel_pmic_gpio.c @@ -190,10 +190,10 @@ static void pmic_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 1 << (offset - 16)); } -static int pmic_irq_type(unsigned irq, unsigned type) +static int pmic_irq_type(struct irq_data *data, unsigned type) { - struct pmic_gpio *pg = get_irq_chip_data(irq); - u32 gpio = irq - pg->irq_base; + struct pmic_gpio *pg = irq_data_get_irq_chip_data(data); + u32 gpio = data->irq - pg->irq_base; unsigned long flags; if (gpio >= pg->chip.ngpio) @@ -207,8 +207,6 @@ static int pmic_irq_type(unsigned irq, unsigned type) return 0; } - - static int pmic_gpio_to_irq(struct gpio_chip *chip, unsigned offset) { struct pmic_gpio *pg = container_of(chip, struct pmic_gpio, chip); @@ -217,19 +215,15 @@ static int pmic_gpio_to_irq(struct gpio_chip *chip, unsigned offset) } /* the gpiointr register is read-clear, so just do nothing. */ -static void pmic_irq_unmask(unsigned irq) -{ -}; +static void pmic_irq_unmask(struct irq_data *data) { } -static void pmic_irq_mask(unsigned irq) -{ -}; +static void pmic_irq_mask(struct irq_data *data) { } static struct irq_chip pmic_irqchip = { .name = "PMIC-GPIO", - .mask = pmic_irq_mask, - .unmask = pmic_irq_unmask, - .set_type = pmic_irq_type, + .irq_mask = pmic_irq_mask, + .irq_unmask = pmic_irq_unmask, + .irq_set_type = pmic_irq_type, }; static void pmic_irq_handler(unsigned irq, struct irq_desc *desc) -- cgit v1.2.3 From d4b7de612d193e1c8fdeee9902e5a582e746dfe9 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 5 Feb 2011 10:46:32 +0000 Subject: platform-drivers: x86: pmic: Use irq_chip buslock mechanism The set_type function of the pmic irq chip is a horrible hack. It schedules work because it cannot access the scu chip from the set_type function. That breaks the assumption, that the type is set after set_type has returned. irq_chips provide buslock functions to avoid the above. Convert the driver to use the proper model. Signed-off-by: Thomas Gleixner Cc: Feng Tang Cc: Matthew Garrett Cc: Alan Cox Cc: Alek Du Signed-off-by: Matthew Garrett --- drivers/platform/x86/intel_pmic_gpio.c | 80 ++++++++++++++-------------------- 1 file changed, 32 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/intel_pmic_gpio.c b/drivers/platform/x86/intel_pmic_gpio.c index 9134d9d07569..df244c83681d 100644 --- a/drivers/platform/x86/intel_pmic_gpio.c +++ b/drivers/platform/x86/intel_pmic_gpio.c @@ -60,23 +60,18 @@ enum pmic_gpio_register { #define GPOSW_DOU 0x08 #define GPOSW_RDRV 0x30 +#define GPIO_UPDATE_TYPE 0x80000000 #define NUM_GPIO 24 -struct pmic_gpio_irq { - spinlock_t lock; - u32 trigger[NUM_GPIO]; - u32 dirty; - struct work_struct work; -}; - - struct pmic_gpio { + struct mutex buslock; struct gpio_chip chip; - struct pmic_gpio_irq irqtypes; void *gpiointr; int irq; unsigned irq_base; + unsigned int update_type; + u32 trigger_type; }; static void pmic_program_irqtype(int gpio, int type) @@ -92,37 +87,6 @@ static void pmic_program_irqtype(int gpio, int type) intel_scu_ipc_update_register(GPIO0 + gpio, 0x00, 0x10); }; -static void pmic_irqtype_work(struct work_struct *work) -{ - struct pmic_gpio_irq *t = - container_of(work, struct pmic_gpio_irq, work); - unsigned long flags; - int i; - u16 type; - - spin_lock_irqsave(&t->lock, flags); - /* As we drop the lock, we may need multiple scans if we race the - pmic_irq_type function */ - while (t->dirty) { - /* - * For each pin that has the dirty bit set send an IPC - * message to configure the hardware via the PMIC - */ - for (i = 0; i < NUM_GPIO; i++) { - if (!(t->dirty & (1 << i))) - continue; - t->dirty &= ~(1 << i); - /* We can't trust the array entry or dirty - once the lock is dropped */ - type = t->trigger[i]; - spin_unlock_irqrestore(&t->lock, flags); - pmic_program_irqtype(i, type); - spin_lock_irqsave(&t->lock, flags); - } - } - spin_unlock_irqrestore(&t->lock, flags); -} - static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { if (offset > 8) { @@ -190,20 +154,21 @@ static void pmic_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 1 << (offset - 16)); } +/* + * This is called from genirq with pg->buslock locked and + * irq_desc->lock held. We can not access the scu bus here, so we + * store the change and update in the bus_sync_unlock() function below + */ static int pmic_irq_type(struct irq_data *data, unsigned type) { struct pmic_gpio *pg = irq_data_get_irq_chip_data(data); u32 gpio = data->irq - pg->irq_base; - unsigned long flags; if (gpio >= pg->chip.ngpio) return -EINVAL; - spin_lock_irqsave(&pg->irqtypes.lock, flags); - pg->irqtypes.trigger[gpio] = type; - pg->irqtypes.dirty |= (1 << gpio); - spin_unlock_irqrestore(&pg->irqtypes.lock, flags); - schedule_work(&pg->irqtypes.work); + pg->trigger_type = type; + pg->update_type = gpio | GPIO_UPDATE_TYPE; return 0; } @@ -214,6 +179,26 @@ static int pmic_gpio_to_irq(struct gpio_chip *chip, unsigned offset) return pg->irq_base + offset; } +static void pmic_bus_lock(struct irq_data *data) +{ + struct pmic_gpio *pg = irq_data_get_irq_chip_data(data); + + mutex_lock(&pg->buslock); +} + +static void pmic_bus_sync_unlock(struct irq_data *data) +{ + struct pmic_gpio *pg = irq_data_get_irq_chip_data(data); + + if (pg->update_type) { + unsigned int gpio = pg->update_type & ~GPIO_UPDATE_TYPE; + + pmic_program_irqtype(gpio, pg->trigger_type); + pg->update_type = 0; + } + mutex_unlock(&pg->buslock); +} + /* the gpiointr register is read-clear, so just do nothing. */ static void pmic_irq_unmask(struct irq_data *data) { } @@ -287,8 +272,7 @@ static int __devinit platform_pmic_gpio_probe(struct platform_device *pdev) pg->chip.can_sleep = 1; pg->chip.dev = dev; - INIT_WORK(&pg->irqtypes.work, pmic_irqtype_work); - spin_lock_init(&pg->irqtypes.lock); + mutex_init(&pg->buslock); pg->chip.dev = dev; retval = gpiochip_add(&pg->chip); -- cgit v1.2.3 From 84f0e17f78471857104a20dfc57711409f68d7bf Mon Sep 17 00:00:00 2001 From: Rogério Brito Date: Thu, 3 Feb 2011 01:42:05 -0200 Subject: Bluetooth: ath3k: Avoid duplication of code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In commit 86e09287e4f8c81831b4d4118a48597565f0d21b, to reduce memory usage, the functions of the ath3k module were rewritten to release the firmware blob after it has been loaded (successfully or not). The resuting code has some redundancy and the compiler can potentially produce better code if we omit a function call that is unconditionally executed in ,---- | if (ath3k_load_firmware(udev, firmware)) { | release_firmware(firmware); | return -EIO; | } | release_firmware(firmware); | | return 0; | } `---- It may also be argued that the rewritten code becomes easier to read, and also to see the code coverage of the snippet in question. Signed-off-by: Rogério Brito Cc: Alexander Holler Cc: "Gustavo F. Padovan" Cc: Miguel Ojeda Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/ath3k.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 333c21289d97..41dadacd3d15 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -108,6 +108,7 @@ static int ath3k_probe(struct usb_interface *intf, { const struct firmware *firmware; struct usb_device *udev = interface_to_usbdev(intf); + int ret; BT_DBG("intf %p id %p", intf, id); @@ -118,13 +119,10 @@ static int ath3k_probe(struct usb_interface *intf, return -EIO; } - if (ath3k_load_firmware(udev, firmware)) { - release_firmware(firmware); - return -EIO; - } + ret = ath3k_load_firmware(udev, firmware); release_firmware(firmware); - return 0; + return ret; } static void ath3k_disconnect(struct usb_interface *intf) -- cgit v1.2.3 From 73020415564a3fe4931f3f70f500a5db13eea946 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sat, 22 Jan 2011 22:35:38 +0100 Subject: m68knommu: Remove dependencies on nonexistent M68KNOMMU M68KNOMMU is set nowhere. Signed-off-by: Geert Uytterhoeven Signed-off-by: Greg Ungerer --- drivers/net/can/mscan/Kconfig | 2 +- lib/Kconfig.debug | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/mscan/Kconfig b/drivers/net/can/mscan/Kconfig index 27d1d398e25e..d38706958af6 100644 --- a/drivers/net/can/mscan/Kconfig +++ b/drivers/net/can/mscan/Kconfig @@ -1,5 +1,5 @@ config CAN_MSCAN - depends on CAN_DEV && (PPC || M68K || M68KNOMMU) + depends on CAN_DEV && (PPC || M68K) tristate "Support for Freescale MSCAN based chips" ---help--- The Motorola Scalable Controller Area Network (MSCAN) definition diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 3967c2356e37..2b97418c67e2 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -805,7 +805,7 @@ config ARCH_WANT_FRAME_POINTERS config FRAME_POINTER bool "Compile the kernel with frame pointers" depends on DEBUG_KERNEL && \ - (CRIS || M68K || M68KNOMMU || FRV || UML || \ + (CRIS || M68K || FRV || UML || \ AVR32 || SUPERH || BLACKFIN || MN10300) || \ ARCH_WANT_FRAME_POINTERS default y if (DEBUG_INFO && UML) || ARCH_WANT_FRAME_POINTERS -- cgit v1.2.3 From 9b9c63ff1f3b09af8e0c66180a904bdbebe92634 Mon Sep 17 00:00:00 2001 From: Philippe De Muyter Date: Sat, 22 Jan 2011 00:21:24 +0100 Subject: m68knommu: fix m548x_wdt.c compilation after headers renaming m548x headers were renamed to m54xx, but m548x_wdt.c still uses the old names. Fix that. Signed-off-by: Philippe De Muyter Signed-off-by: Greg Ungerer --- drivers/watchdog/m548x_wdt.c | 50 ++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/m548x_wdt.c b/drivers/watchdog/m548x_wdt.c index cabbcfe1c847..4d43286074aa 100644 --- a/drivers/watchdog/m548x_wdt.c +++ b/drivers/watchdog/m548x_wdt.c @@ -1,7 +1,7 @@ /* - * drivers/watchdog/m548x_wdt.c + * drivers/watchdog/m54xx_wdt.c * - * Watchdog driver for ColdFire MCF548x processors + * Watchdog driver for ColdFire MCF547x & MCF548x processors * Copyright 2010 (c) Philippe De Muyter * * Adapted from the IXP4xx watchdog driver, which carries these notices: @@ -29,8 +29,8 @@ #include #include -#include -#include +#include +#include static int nowayout = WATCHDOG_NOWAYOUT; static unsigned int heartbeat = 30; /* (secs) Default is 0.5 minute */ @@ -76,7 +76,7 @@ static void wdt_keepalive(void) __raw_writel(gms0, MCF_MBAR + MCF_GPT_GMS0); } -static int m548x_wdt_open(struct inode *inode, struct file *file) +static int m54xx_wdt_open(struct inode *inode, struct file *file) { if (test_and_set_bit(WDT_IN_USE, &wdt_status)) return -EBUSY; @@ -86,7 +86,7 @@ static int m548x_wdt_open(struct inode *inode, struct file *file) return nonseekable_open(inode, file); } -static ssize_t m548x_wdt_write(struct file *file, const char *data, +static ssize_t m54xx_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) { if (len) { @@ -112,10 +112,10 @@ static ssize_t m548x_wdt_write(struct file *file, const char *data, static const struct watchdog_info ident = { .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, - .identity = "Coldfire M548x Watchdog", + .identity = "Coldfire M54xx Watchdog", }; -static long m548x_wdt_ioctl(struct file *file, unsigned int cmd, +static long m54xx_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int ret = -ENOTTY; @@ -161,7 +161,7 @@ static long m548x_wdt_ioctl(struct file *file, unsigned int cmd, return ret; } -static int m548x_wdt_release(struct inode *inode, struct file *file) +static int m54xx_wdt_release(struct inode *inode, struct file *file) { if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) wdt_disable(); @@ -177,45 +177,45 @@ static int m548x_wdt_release(struct inode *inode, struct file *file) } -static const struct file_operations m548x_wdt_fops = { +static const struct file_operations m54xx_wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, - .write = m548x_wdt_write, - .unlocked_ioctl = m548x_wdt_ioctl, - .open = m548x_wdt_open, - .release = m548x_wdt_release, + .write = m54xx_wdt_write, + .unlocked_ioctl = m54xx_wdt_ioctl, + .open = m54xx_wdt_open, + .release = m54xx_wdt_release, }; -static struct miscdevice m548x_wdt_miscdev = { +static struct miscdevice m54xx_wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", - .fops = &m548x_wdt_fops, + .fops = &m54xx_wdt_fops, }; -static int __init m548x_wdt_init(void) +static int __init m54xx_wdt_init(void) { if (!request_mem_region(MCF_MBAR + MCF_GPT_GCIR0, 4, - "Coldfire M548x Watchdog")) { + "Coldfire M54xx Watchdog")) { printk(KERN_WARNING - "Coldfire M548x Watchdog : I/O region busy\n"); + "Coldfire M54xx Watchdog : I/O region busy\n"); return -EBUSY; } printk(KERN_INFO "ColdFire watchdog driver is loaded.\n"); - return misc_register(&m548x_wdt_miscdev); + return misc_register(&m54xx_wdt_miscdev); } -static void __exit m548x_wdt_exit(void) +static void __exit m54xx_wdt_exit(void) { - misc_deregister(&m548x_wdt_miscdev); + misc_deregister(&m54xx_wdt_miscdev); release_mem_region(MCF_MBAR + MCF_GPT_GCIR0, 4); } -module_init(m548x_wdt_init); -module_exit(m548x_wdt_exit); +module_init(m54xx_wdt_init); +module_exit(m54xx_wdt_exit); MODULE_AUTHOR("Philippe De Muyter "); -MODULE_DESCRIPTION("Coldfire M548x Watchdog"); +MODULE_DESCRIPTION("Coldfire M54xx Watchdog"); module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds (default 30s)"); -- cgit v1.2.3 From 4157a04d5d7def8661559cd98eb285a520d50075 Mon Sep 17 00:00:00 2001 From: Philippe De Muyter Date: Sat, 22 Jan 2011 00:21:25 +0100 Subject: m68knommu: Rename m548x_wdt.c to m54xx_wdt.c All m548x files were renamed to m54xx, except m548x_wdt.c. Fix that. Signed-off-by: Philippe De Muyter Signed-off-by: Greg Ungerer --- drivers/watchdog/Kconfig | 6 +- drivers/watchdog/Makefile | 2 +- drivers/watchdog/m548x_wdt.c | 227 ------------------------------------------- drivers/watchdog/m54xx_wdt.c | 227 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 231 insertions(+), 231 deletions(-) delete mode 100644 drivers/watchdog/m548x_wdt.c create mode 100644 drivers/watchdog/m54xx_wdt.c (limited to 'drivers') diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 2e2400e7322e..31649b7b672f 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -862,12 +862,12 @@ config SBC_EPX_C3_WATCHDOG # M68K Architecture -config M548x_WATCHDOG - tristate "MCF548x watchdog support" +config M54xx_WATCHDOG + tristate "MCF54xx watchdog support" depends on M548x help To compile this driver as a module, choose M here: the - module will be called m548x_wdt. + module will be called m54xx_wdt. # MIPS Architecture diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index dd776651917c..20e44c4782b3 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -106,7 +106,7 @@ obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o # M32R Architecture # M68K Architecture -obj-$(CONFIG_M548x_WATCHDOG) += m548x_wdt.o +obj-$(CONFIG_M54xx_WATCHDOG) += m54xx_wdt.o # MIPS Architecture obj-$(CONFIG_ATH79_WDT) += ath79_wdt.o diff --git a/drivers/watchdog/m548x_wdt.c b/drivers/watchdog/m548x_wdt.c deleted file mode 100644 index 4d43286074aa..000000000000 --- a/drivers/watchdog/m548x_wdt.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * drivers/watchdog/m54xx_wdt.c - * - * Watchdog driver for ColdFire MCF547x & MCF548x processors - * Copyright 2010 (c) Philippe De Muyter - * - * Adapted from the IXP4xx watchdog driver, which carries these notices: - * - * Author: Deepak Saxena - * - * Copyright 2004 (c) MontaVista, Software, Inc. - * Based on sa1100 driver, Copyright (C) 2000 Oleg Drokin - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static int nowayout = WATCHDOG_NOWAYOUT; -static unsigned int heartbeat = 30; /* (secs) Default is 0.5 minute */ -static unsigned long wdt_status; - -#define WDT_IN_USE 0 -#define WDT_OK_TO_CLOSE 1 - -static void wdt_enable(void) -{ - unsigned int gms0; - - /* preserve GPIO usage, if any */ - gms0 = __raw_readl(MCF_MBAR + MCF_GPT_GMS0); - if (gms0 & MCF_GPT_GMS_TMS_GPIO) - gms0 &= (MCF_GPT_GMS_TMS_GPIO | MCF_GPT_GMS_GPIO_MASK - | MCF_GPT_GMS_OD); - else - gms0 = MCF_GPT_GMS_TMS_GPIO | MCF_GPT_GMS_OD; - __raw_writel(gms0, MCF_MBAR + MCF_GPT_GMS0); - __raw_writel(MCF_GPT_GCIR_PRE(heartbeat*(MCF_BUSCLK/0xffff)) | - MCF_GPT_GCIR_CNT(0xffff), MCF_MBAR + MCF_GPT_GCIR0); - gms0 |= MCF_GPT_GMS_OCPW(0xA5) | MCF_GPT_GMS_WDEN | MCF_GPT_GMS_CE; - __raw_writel(gms0, MCF_MBAR + MCF_GPT_GMS0); -} - -static void wdt_disable(void) -{ - unsigned int gms0; - - /* disable watchdog */ - gms0 = __raw_readl(MCF_MBAR + MCF_GPT_GMS0); - gms0 &= ~(MCF_GPT_GMS_WDEN | MCF_GPT_GMS_CE); - __raw_writel(gms0, MCF_MBAR + MCF_GPT_GMS0); -} - -static void wdt_keepalive(void) -{ - unsigned int gms0; - - gms0 = __raw_readl(MCF_MBAR + MCF_GPT_GMS0); - gms0 |= MCF_GPT_GMS_OCPW(0xA5); - __raw_writel(gms0, MCF_MBAR + MCF_GPT_GMS0); -} - -static int m54xx_wdt_open(struct inode *inode, struct file *file) -{ - if (test_and_set_bit(WDT_IN_USE, &wdt_status)) - return -EBUSY; - - clear_bit(WDT_OK_TO_CLOSE, &wdt_status); - wdt_enable(); - return nonseekable_open(inode, file); -} - -static ssize_t m54xx_wdt_write(struct file *file, const char *data, - size_t len, loff_t *ppos) -{ - if (len) { - if (!nowayout) { - size_t i; - - clear_bit(WDT_OK_TO_CLOSE, &wdt_status); - - for (i = 0; i != len; i++) { - char c; - - if (get_user(c, data + i)) - return -EFAULT; - if (c == 'V') - set_bit(WDT_OK_TO_CLOSE, &wdt_status); - } - } - wdt_keepalive(); - } - return len; -} - -static const struct watchdog_info ident = { - .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | - WDIOF_KEEPALIVEPING, - .identity = "Coldfire M54xx Watchdog", -}; - -static long m54xx_wdt_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - int ret = -ENOTTY; - int time; - - switch (cmd) { - case WDIOC_GETSUPPORT: - ret = copy_to_user((struct watchdog_info *)arg, &ident, - sizeof(ident)) ? -EFAULT : 0; - break; - - case WDIOC_GETSTATUS: - ret = put_user(0, (int *)arg); - break; - - case WDIOC_GETBOOTSTATUS: - ret = put_user(0, (int *)arg); - break; - - case WDIOC_KEEPALIVE: - wdt_keepalive(); - ret = 0; - break; - - case WDIOC_SETTIMEOUT: - ret = get_user(time, (int *)arg); - if (ret) - break; - - if (time <= 0 || time > 30) { - ret = -EINVAL; - break; - } - - heartbeat = time; - wdt_enable(); - /* Fall through */ - - case WDIOC_GETTIMEOUT: - ret = put_user(heartbeat, (int *)arg); - break; - } - return ret; -} - -static int m54xx_wdt_release(struct inode *inode, struct file *file) -{ - if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) - wdt_disable(); - else { - printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " - "timer will not stop\n"); - wdt_keepalive(); - } - clear_bit(WDT_IN_USE, &wdt_status); - clear_bit(WDT_OK_TO_CLOSE, &wdt_status); - - return 0; -} - - -static const struct file_operations m54xx_wdt_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .write = m54xx_wdt_write, - .unlocked_ioctl = m54xx_wdt_ioctl, - .open = m54xx_wdt_open, - .release = m54xx_wdt_release, -}; - -static struct miscdevice m54xx_wdt_miscdev = { - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &m54xx_wdt_fops, -}; - -static int __init m54xx_wdt_init(void) -{ - if (!request_mem_region(MCF_MBAR + MCF_GPT_GCIR0, 4, - "Coldfire M54xx Watchdog")) { - printk(KERN_WARNING - "Coldfire M54xx Watchdog : I/O region busy\n"); - return -EBUSY; - } - printk(KERN_INFO "ColdFire watchdog driver is loaded.\n"); - - return misc_register(&m54xx_wdt_miscdev); -} - -static void __exit m54xx_wdt_exit(void) -{ - misc_deregister(&m54xx_wdt_miscdev); - release_mem_region(MCF_MBAR + MCF_GPT_GCIR0, 4); -} - -module_init(m54xx_wdt_init); -module_exit(m54xx_wdt_exit); - -MODULE_AUTHOR("Philippe De Muyter "); -MODULE_DESCRIPTION("Coldfire M54xx Watchdog"); - -module_param(heartbeat, int, 0); -MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds (default 30s)"); - -module_param(nowayout, int, 0); -MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); - -MODULE_LICENSE("GPL"); -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); diff --git a/drivers/watchdog/m54xx_wdt.c b/drivers/watchdog/m54xx_wdt.c new file mode 100644 index 000000000000..4d43286074aa --- /dev/null +++ b/drivers/watchdog/m54xx_wdt.c @@ -0,0 +1,227 @@ +/* + * drivers/watchdog/m54xx_wdt.c + * + * Watchdog driver for ColdFire MCF547x & MCF548x processors + * Copyright 2010 (c) Philippe De Muyter + * + * Adapted from the IXP4xx watchdog driver, which carries these notices: + * + * Author: Deepak Saxena + * + * Copyright 2004 (c) MontaVista, Software, Inc. + * Based on sa1100 driver, Copyright (C) 2000 Oleg Drokin + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static int nowayout = WATCHDOG_NOWAYOUT; +static unsigned int heartbeat = 30; /* (secs) Default is 0.5 minute */ +static unsigned long wdt_status; + +#define WDT_IN_USE 0 +#define WDT_OK_TO_CLOSE 1 + +static void wdt_enable(void) +{ + unsigned int gms0; + + /* preserve GPIO usage, if any */ + gms0 = __raw_readl(MCF_MBAR + MCF_GPT_GMS0); + if (gms0 & MCF_GPT_GMS_TMS_GPIO) + gms0 &= (MCF_GPT_GMS_TMS_GPIO | MCF_GPT_GMS_GPIO_MASK + | MCF_GPT_GMS_OD); + else + gms0 = MCF_GPT_GMS_TMS_GPIO | MCF_GPT_GMS_OD; + __raw_writel(gms0, MCF_MBAR + MCF_GPT_GMS0); + __raw_writel(MCF_GPT_GCIR_PRE(heartbeat*(MCF_BUSCLK/0xffff)) | + MCF_GPT_GCIR_CNT(0xffff), MCF_MBAR + MCF_GPT_GCIR0); + gms0 |= MCF_GPT_GMS_OCPW(0xA5) | MCF_GPT_GMS_WDEN | MCF_GPT_GMS_CE; + __raw_writel(gms0, MCF_MBAR + MCF_GPT_GMS0); +} + +static void wdt_disable(void) +{ + unsigned int gms0; + + /* disable watchdog */ + gms0 = __raw_readl(MCF_MBAR + MCF_GPT_GMS0); + gms0 &= ~(MCF_GPT_GMS_WDEN | MCF_GPT_GMS_CE); + __raw_writel(gms0, MCF_MBAR + MCF_GPT_GMS0); +} + +static void wdt_keepalive(void) +{ + unsigned int gms0; + + gms0 = __raw_readl(MCF_MBAR + MCF_GPT_GMS0); + gms0 |= MCF_GPT_GMS_OCPW(0xA5); + __raw_writel(gms0, MCF_MBAR + MCF_GPT_GMS0); +} + +static int m54xx_wdt_open(struct inode *inode, struct file *file) +{ + if (test_and_set_bit(WDT_IN_USE, &wdt_status)) + return -EBUSY; + + clear_bit(WDT_OK_TO_CLOSE, &wdt_status); + wdt_enable(); + return nonseekable_open(inode, file); +} + +static ssize_t m54xx_wdt_write(struct file *file, const char *data, + size_t len, loff_t *ppos) +{ + if (len) { + if (!nowayout) { + size_t i; + + clear_bit(WDT_OK_TO_CLOSE, &wdt_status); + + for (i = 0; i != len; i++) { + char c; + + if (get_user(c, data + i)) + return -EFAULT; + if (c == 'V') + set_bit(WDT_OK_TO_CLOSE, &wdt_status); + } + } + wdt_keepalive(); + } + return len; +} + +static const struct watchdog_info ident = { + .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | + WDIOF_KEEPALIVEPING, + .identity = "Coldfire M54xx Watchdog", +}; + +static long m54xx_wdt_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int ret = -ENOTTY; + int time; + + switch (cmd) { + case WDIOC_GETSUPPORT: + ret = copy_to_user((struct watchdog_info *)arg, &ident, + sizeof(ident)) ? -EFAULT : 0; + break; + + case WDIOC_GETSTATUS: + ret = put_user(0, (int *)arg); + break; + + case WDIOC_GETBOOTSTATUS: + ret = put_user(0, (int *)arg); + break; + + case WDIOC_KEEPALIVE: + wdt_keepalive(); + ret = 0; + break; + + case WDIOC_SETTIMEOUT: + ret = get_user(time, (int *)arg); + if (ret) + break; + + if (time <= 0 || time > 30) { + ret = -EINVAL; + break; + } + + heartbeat = time; + wdt_enable(); + /* Fall through */ + + case WDIOC_GETTIMEOUT: + ret = put_user(heartbeat, (int *)arg); + break; + } + return ret; +} + +static int m54xx_wdt_release(struct inode *inode, struct file *file) +{ + if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) + wdt_disable(); + else { + printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " + "timer will not stop\n"); + wdt_keepalive(); + } + clear_bit(WDT_IN_USE, &wdt_status); + clear_bit(WDT_OK_TO_CLOSE, &wdt_status); + + return 0; +} + + +static const struct file_operations m54xx_wdt_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .write = m54xx_wdt_write, + .unlocked_ioctl = m54xx_wdt_ioctl, + .open = m54xx_wdt_open, + .release = m54xx_wdt_release, +}; + +static struct miscdevice m54xx_wdt_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &m54xx_wdt_fops, +}; + +static int __init m54xx_wdt_init(void) +{ + if (!request_mem_region(MCF_MBAR + MCF_GPT_GCIR0, 4, + "Coldfire M54xx Watchdog")) { + printk(KERN_WARNING + "Coldfire M54xx Watchdog : I/O region busy\n"); + return -EBUSY; + } + printk(KERN_INFO "ColdFire watchdog driver is loaded.\n"); + + return misc_register(&m54xx_wdt_miscdev); +} + +static void __exit m54xx_wdt_exit(void) +{ + misc_deregister(&m54xx_wdt_miscdev); + release_mem_region(MCF_MBAR + MCF_GPT_GCIR0, 4); +} + +module_init(m54xx_wdt_init); +module_exit(m54xx_wdt_exit); + +MODULE_AUTHOR("Philippe De Muyter "); +MODULE_DESCRIPTION("Coldfire M54xx Watchdog"); + +module_param(heartbeat, int, 0); +MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds (default 30s)"); + +module_param(nowayout, int, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); -- cgit v1.2.3 From 884b821fa27a5e3714d4871976d3e7c3abfa0d1b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 8 Feb 2011 23:37:16 +0100 Subject: ACPI: Fix acpi_os_read_memory() and acpi_os_write_memory() (v2) The functions acpi_os_read_memory() and acpi_os_write_memory() do two wrong things. First, they shouldn't call rcu_read_unlock() before the looked up address is actually used for I/O, because in that case the iomap it belongs to may be removed before the I/O is done. Second, if they have to create a new mapping, they should check the returned virtual address and tell the caller that the operation failed if it is NULL (in fact, I think they even should not attempt to map an address that's not present in one of the existing ACPI iomaps, because that may cause problems to happen when they are called from nonpreemptible context and their callers ought to know what they are doing and map the requisite memory regions beforehand). Make these functions call rcu_read_unlock() when the I/O is complete (or if it's necessary to map the given address "on the fly") and return an error code if the requested physical address is not present in the existing ACPI iomaps and cannot be mapped. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/osl.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index b0931818cf98..c90c76aa7f8b 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -636,17 +636,21 @@ EXPORT_SYMBOL(acpi_os_write_port); acpi_status acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) { - u32 dummy; void __iomem *virt_addr; - int size = width / 8, unmap = 0; + unsigned int size = width / 8; + bool unmap = false; + u32 dummy; rcu_read_lock(); virt_addr = acpi_map_vaddr_lookup(phys_addr, size); - rcu_read_unlock(); if (!virt_addr) { + rcu_read_unlock(); virt_addr = acpi_os_ioremap(phys_addr, size); - unmap = 1; + if (!virt_addr) + return AE_BAD_ADDRESS; + unmap = true; } + if (!value) value = &dummy; @@ -666,6 +670,8 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) if (unmap) iounmap(virt_addr); + else + rcu_read_unlock(); return AE_OK; } @@ -674,14 +680,17 @@ acpi_status acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) { void __iomem *virt_addr; - int size = width / 8, unmap = 0; + unsigned int size = width / 8; + bool unmap = false; rcu_read_lock(); virt_addr = acpi_map_vaddr_lookup(phys_addr, size); - rcu_read_unlock(); if (!virt_addr) { + rcu_read_unlock(); virt_addr = acpi_os_ioremap(phys_addr, size); - unmap = 1; + if (!virt_addr) + return AE_BAD_ADDRESS; + unmap = true; } switch (width) { @@ -700,6 +709,8 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) if (unmap) iounmap(virt_addr); + else + rcu_read_unlock(); return AE_OK; } -- cgit v1.2.3 From 8d13a2a9fb3e5e3f68e9d3ec0de3c8fcfa56a224 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 8 Feb 2011 16:17:55 -0800 Subject: net: Kill NETEVENT_PMTU_UPDATE. Nobody actually does anything in response to the event, so just kill it off. Signed-off-by: David S. Miller --- drivers/net/cxgb3/cxgb3_offload.c | 2 -- drivers/net/cxgb4/cxgb4_main.c | 1 - include/net/netevent.h | 1 - net/ipv4/route.c | 1 - net/ipv6/route.c | 1 - 5 files changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index ef02aa68c926..7ea94b5205f8 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c @@ -967,8 +967,6 @@ static int nb_callback(struct notifier_block *self, unsigned long event, cxgb_neigh_update((struct neighbour *)ctx); break; } - case (NETEVENT_PMTU_UPDATE): - break; case (NETEVENT_REDIRECT):{ struct netevent_redirect *nr = ctx; cxgb_redirect(nr->old, nr->new); diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index ec35d458102c..5352c8a23f4d 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -2471,7 +2471,6 @@ static int netevent_cb(struct notifier_block *nb, unsigned long event, case NETEVENT_NEIGH_UPDATE: check_neigh_update(data); break; - case NETEVENT_PMTU_UPDATE: case NETEVENT_REDIRECT: default: break; diff --git a/include/net/netevent.h b/include/net/netevent.h index e82b7bab3ff3..22b239c17eaa 100644 --- a/include/net/netevent.h +++ b/include/net/netevent.h @@ -21,7 +21,6 @@ struct netevent_redirect { enum netevent_notif_type { NETEVENT_NEIGH_UPDATE = 1, /* arg is struct neighbour ptr */ - NETEVENT_PMTU_UPDATE, /* arg is struct dst_entry ptr */ NETEVENT_REDIRECT, /* arg is struct netevent_redirect ptr */ }; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 2e225dafc4f8..0455af851751 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1762,7 +1762,6 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) } dst_metric_set(dst, RTAX_MTU, mtu); dst_set_expires(dst, ip_rt_mtu_expires); - call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst); } } diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 0a63d44e6f48..12ec83d48806 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -965,7 +965,6 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu) dst_metric_set(dst, RTAX_FEATURES, features); } dst_metric_set(dst, RTAX_MTU, mtu); - call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst); } } -- cgit v1.2.3 From ee60833a4f887a09e87be52cdf1247a4963b0aef Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 2 Feb 2011 09:59:34 +0200 Subject: wl12xx: mcp2.5 - add config_ps acx mcp2.5 uses this acx to configure the fw only once, rather than passing the params in every enter psm command. Signed-off-by: Eliad Peller Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 30 ++++++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/acx.h | 11 +++++++++++ drivers/net/wireless/wl12xx/conf.h | 8 ++++++++ drivers/net/wireless/wl12xx/main.c | 1 + 4 files changed, 50 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index afdc601aa7ea..84d94b259900 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -1476,3 +1476,33 @@ out: kfree(acx); return ret; } + +int wl1271_acx_config_ps(struct wl1271 *wl) +{ + struct wl1271_acx_config_ps *config_ps; + int ret; + + wl1271_debug(DEBUG_ACX, "acx config ps"); + + config_ps = kzalloc(sizeof(*config_ps), GFP_KERNEL); + if (!config_ps) { + ret = -ENOMEM; + goto out; + } + + config_ps->exit_retries = wl->conf.conn.psm_exit_retries; + config_ps->enter_retries = wl->conf.conn.psm_entry_retries; + config_ps->null_data_rate = cpu_to_le32(wl->basic_rate); + + ret = wl1271_cmd_configure(wl, ACX_CONFIG_PS, config_ps, + sizeof(*config_ps)); + + if (ret < 0) { + wl1271_warning("acx config ps failed: %d", ret); + goto out; + } + +out: + kfree(config_ps); + return ret; +} diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index 4bbaf04f434e..5bc0ca97bec4 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h @@ -1136,6 +1136,15 @@ struct wl1271_acx_max_tx_retry { u8 padding_1[2]; } __packed; +struct wl1271_acx_config_ps { + struct acx_header header; + + u8 exit_retries; + u8 enter_retries; + u8 padding[2]; + __le32 null_data_rate; +} __packed; + enum { ACX_WAKE_UP_CONDITIONS = 0x0002, ACX_MEM_CFG = 0x0003, @@ -1200,6 +1209,7 @@ enum { DOT11_RTS_THRESHOLD = 0x1013, DOT11_GROUP_ADDRESS_TBL = 0x1014, ACX_PM_CONFIG = 0x1016, + ACX_CONFIG_PS = 0x1017, MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL, @@ -1269,5 +1279,6 @@ int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn, bool enable); int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); int wl1271_acx_max_tx_retry(struct wl1271 *wl); +int wl1271_acx_config_ps(struct wl1271 *wl); #endif /* __WL1271_ACX_H__ */ diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index fd1dac9ab4db..c81aecd755e5 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h @@ -959,6 +959,14 @@ struct conf_conn_settings { */ u8 psm_entry_retries; + /* + * Specifies the maximum number of times to try PSM exit if it fails + * (if sending the appropriate null-func message fails.) + * + * Range 0 - 255 + */ + u8 psm_exit_retries; + /* * Specifies the maximum number of times to try transmit the PSM entry * null-func frame for each PSM entry attempt diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 254b7daccee1..522bb09c9535 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -256,6 +256,7 @@ static struct conf_drv_settings default_conf = { .bet_enable = CONF_BET_MODE_ENABLE, .bet_max_consecutive = 10, .psm_entry_retries = 5, + .psm_exit_retries = 255, .psm_entry_nullfunc_retries = 3, .psm_entry_hangover_period = 1, .keep_alive_interval = 55000, -- cgit v1.2.3 From c8bde243421d759844264cf11e4248e7862c2722 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 2 Feb 2011 09:59:35 +0200 Subject: wl12xx: move to new firmware (6.1.3.50.49) This patch adds support for the new wl12xx firmware (Rev 6.1.3.50.49) Since this fw is not backward compatible with previous fw versions, a new fw (with different name) is being fetched. (the patch is big because it contains all the required fw api changes. splitting it into multiple patches will result in corrupted intermediate commits) Signed-off-by: Eliad Peller Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 44 +++++++++++++++++++++++++++++++----- drivers/net/wireless/wl12xx/acx.h | 26 ++++++++++++++++----- drivers/net/wireless/wl12xx/cmd.c | 13 +++++++---- drivers/net/wireless/wl12xx/cmd.h | 14 ++++-------- drivers/net/wireless/wl12xx/conf.h | 29 ++++++++++++++++++++++++ drivers/net/wireless/wl12xx/event.c | 14 ------------ drivers/net/wireless/wl12xx/event.h | 2 -- drivers/net/wireless/wl12xx/init.c | 13 +++++++++++ drivers/net/wireless/wl12xx/main.c | 22 ++++++++++++++---- drivers/net/wireless/wl12xx/ps.c | 6 ++--- drivers/net/wireless/wl12xx/rx.c | 6 ++--- drivers/net/wireless/wl12xx/rx.h | 2 +- drivers/net/wireless/wl12xx/wl12xx.h | 31 +++++++++++++++++++++---- 13 files changed, 162 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index 84d94b259900..f2fbda06a129 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -947,9 +947,9 @@ out: return ret; } -int wl1271_acx_mem_cfg(struct wl1271 *wl) +int wl1271_acx_ap_mem_cfg(struct wl1271 *wl) { - struct wl1271_acx_config_memory *mem_conf; + struct wl1271_acx_ap_config_memory *mem_conf; int ret; wl1271_debug(DEBUG_ACX, "wl1271 mem cfg"); @@ -979,13 +979,45 @@ out: return ret; } -int wl1271_acx_init_mem_config(struct wl1271 *wl) +int wl1271_acx_sta_mem_cfg(struct wl1271 *wl) { + struct wl1271_acx_sta_config_memory *mem_conf; int ret; - ret = wl1271_acx_mem_cfg(wl); - if (ret < 0) - return ret; + wl1271_debug(DEBUG_ACX, "wl1271 mem cfg"); + + mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL); + if (!mem_conf) { + ret = -ENOMEM; + goto out; + } + + /* memory config */ + mem_conf->num_stations = DEFAULT_NUM_STATIONS; + mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS; + mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS; + mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES; + mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); + mem_conf->dyn_mem_enable = wl->conf.mem.dynamic_memory; + mem_conf->tx_free_req = wl->conf.mem.min_req_tx_blocks; + mem_conf->rx_free_req = wl->conf.mem.min_req_rx_blocks; + mem_conf->tx_min = wl->conf.mem.tx_min; + + ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf, + sizeof(*mem_conf)); + if (ret < 0) { + wl1271_warning("wl1271 mem config failed: %d", ret); + goto out; + } + +out: + kfree(mem_conf); + return ret; +} + +int wl1271_acx_init_mem_config(struct wl1271 *wl) +{ + int ret; wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map), GFP_KERNEL); diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index 5bc0ca97bec4..537fab40ed12 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h @@ -802,7 +802,7 @@ struct acx_tx_config_options { #define ACX_TX_DESCRIPTORS 32 #define ACX_NUM_SSID_PROFILES 1 -struct wl1271_acx_config_memory { +struct wl1271_acx_ap_config_memory { struct acx_header header; u8 rx_mem_block_num; @@ -812,6 +812,20 @@ struct wl1271_acx_config_memory { __le32 total_tx_descriptors; } __packed; +struct wl1271_acx_sta_config_memory { + struct acx_header header; + + u8 rx_mem_block_num; + u8 tx_min_mem_block_num; + u8 num_stations; + u8 num_ssid_profiles; + __le32 total_tx_descriptors; + u8 dyn_mem_enable; + u8 tx_free_req; + u8 rx_free_req; + u8 tx_min; +} __packed; + struct wl1271_acx_mem_map { struct acx_header header; @@ -1202,6 +1216,8 @@ enum { ACX_HT_BSS_OPERATION = 0x0058, ACX_COEX_ACTIVITY = 0x0059, ACX_SET_DCO_ITRIM_PARAMS = 0x0061, + ACX_GEN_FW_CMD = 0x0070, + ACX_HOST_IF_CFG_BITMAP = 0x0071, ACX_MAX_TX_FAILURE = 0x0072, DOT11_RX_MSDU_LIFE_TIME = 0x1004, DOT11_CUR_TX_PWR = 0x100D, @@ -1210,10 +1226,7 @@ enum { DOT11_GROUP_ADDRESS_TBL = 0x1014, ACX_PM_CONFIG = 0x1016, ACX_CONFIG_PS = 0x1017, - - MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL, - - MAX_IE = 0xFFFF + ACX_CONFIG_HANGOVER = 0x1018, }; @@ -1255,7 +1268,8 @@ int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type, u32 apsd_conf0, u32 apsd_conf1); int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold); int wl1271_acx_tx_config_options(struct wl1271 *wl); -int wl1271_acx_mem_cfg(struct wl1271 *wl); +int wl1271_acx_ap_mem_cfg(struct wl1271 *wl); +int wl1271_acx_sta_mem_cfg(struct wl1271 *wl); int wl1271_acx_init_mem_config(struct wl1271 *wl); int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); int wl1271_acx_smart_reflex(struct wl1271 *wl); diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 1bb8be5e805b..66d15e77da38 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -286,6 +286,13 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) join->rx_filter_options = cpu_to_le32(wl->rx_filter); join->bss_type = bss_type; join->basic_rate_set = cpu_to_le32(wl->basic_rate_set); + /* + * for supported_rate_set, we should use wl->rate_set. however, + * it seems that acx_rate_policies doesn't affect full_rate, and + * since we want to avoid additional join, we'll use a 0xffffffff value, + * and let the fw find the actual supported rates + */ + join->supported_rate_set = cpu_to_le32(0xffffffff); if (wl->band == IEEE80211_BAND_5GHZ) join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ; @@ -454,7 +461,7 @@ out: return ret; } -int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send) +int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode) { struct wl1271_cmd_ps_params *ps_params = NULL; int ret = 0; @@ -468,10 +475,6 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send) } ps_params->ps_mode = ps_mode; - ps_params->send_null_data = send; - ps_params->retries = wl->conf.conn.psm_entry_nullfunc_retries; - ps_params->hang_over_period = wl->conf.conn.psm_entry_hangover_period; - ps_params->null_data_rate = cpu_to_le32(rates); ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, sizeof(*ps_params), 0); diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h index 751281414006..54c12e71417e 100644 --- a/drivers/net/wireless/wl12xx/cmd.h +++ b/drivers/net/wireless/wl12xx/cmd.h @@ -39,7 +39,7 @@ int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); int wl1271_cmd_data_path(struct wl1271 *wl, bool enable); -int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send); +int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode); int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, size_t len); int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, @@ -140,6 +140,7 @@ enum cmd_templ { * For CTS-to-self (FastCTS) mechanism * for BT/WLAN coexistence (SoftGemini). */ CMD_TEMPL_ARP_RSP, + CMD_TEMPL_LINK_MEASUREMENT_REPORT, /* AP-mode specific */ CMD_TEMPL_AP_BEACON = 13, @@ -216,6 +217,7 @@ struct wl1271_cmd_join { * ACK or CTS frames). */ __le32 basic_rate_set; + __le32 supported_rate_set; u8 dtim_interval; /* * bits 0-2: This bitwise field specifies the type @@ -278,15 +280,7 @@ struct wl1271_cmd_ps_params { struct wl1271_cmd_header header; u8 ps_mode; /* STATION_* */ - u8 send_null_data; /* Do we have to send NULL data packet ? */ - u8 retries; /* Number of retires for the initial NULL data packet */ - - /* - * TUs during which the target stays awake after switching - * to power save mode. - */ - u8 hang_over_period; - __le32 null_data_rate; + u8 padding[3]; } __packed; /* HW encryption keys */ diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index c81aecd755e5..d8c124919382 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h @@ -1151,6 +1151,34 @@ struct conf_ht_setting { u16 inactivity_timeout; }; +struct conf_memory_settings { + /* Disable/Enable dynamic memory */ + u8 dynamic_memory; + + /* + * Minimum required free tx memory blocks in order to assure optimum + * performence + * + * Range: 0-120 + */ + u8 min_req_tx_blocks; + + /* + * Minimum required free rx memory blocks in order to assure optimum + * performence + * + * Range: 0-120 + */ + u8 min_req_rx_blocks; + + /* + * Minimum number of mem blocks (free+used) guaranteed for TX + * + * Range: 0-120 + */ + u8 tx_min; +}; + struct conf_drv_settings { struct conf_sg_settings sg; struct conf_rx_settings rx; @@ -1162,6 +1190,7 @@ struct conf_drv_settings { struct conf_scan_settings scan; struct conf_rf_settings rf; struct conf_ht_setting ht; + struct conf_memory_settings mem; }; #endif diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index 3376a5de09d7..1b170c5cc595 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c @@ -135,20 +135,6 @@ static int wl1271_event_ps_report(struct wl1271 *wl, /* go to extremely low power mode */ wl1271_ps_elp_sleep(wl); break; - case EVENT_EXIT_POWER_SAVE_FAIL: - wl1271_debug(DEBUG_PSM, "PSM exit failed"); - - if (test_bit(WL1271_FLAG_PSM, &wl->flags)) { - wl->psm_entry_retry = 0; - break; - } - - /* make sure the firmware goes to active mode - the frame to - be sent next will indicate to the AP, that we are active. */ - ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, - wl->basic_rate, false); - break; - case EVENT_EXIT_POWER_SAVE_SUCCESS: default: break; } diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h index 1d5ef670d480..0e80886f3031 100644 --- a/drivers/net/wireless/wl12xx/event.h +++ b/drivers/net/wireless/wl12xx/event.h @@ -75,8 +75,6 @@ enum { enum { EVENT_ENTER_POWER_SAVE_FAIL = 0, EVENT_ENTER_POWER_SAVE_SUCCESS, - EVENT_EXIT_POWER_SAVE_FAIL, - EVENT_EXIT_POWER_SAVE_SUCCESS, }; struct event_debug_report { diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index 70b3dc88a219..62dc9839dd31 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c @@ -325,6 +325,11 @@ static int wl1271_sta_hw_init(struct wl1271 *wl) if (ret < 0) return ret; + /* PS config */ + ret = wl1271_acx_config_ps(wl); + if (ret < 0) + return ret; + ret = wl1271_sta_init_templates_config(wl); if (ret < 0) return ret; @@ -367,6 +372,10 @@ static int wl1271_sta_hw_init(struct wl1271 *wl) if (ret < 0) return ret; + ret = wl1271_acx_sta_mem_cfg(wl); + if (ret < 0) + return ret; + return 0; } @@ -433,6 +442,10 @@ static int wl1271_ap_hw_init(struct wl1271 *wl) if (ret < 0) return ret; + ret = wl1271_acx_ap_mem_cfg(wl); + if (ret < 0) + return ret; + return 0; } diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 522bb09c9535..91d681221286 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -298,6 +298,12 @@ static struct conf_drv_settings default_conf = { .tx_ba_win_size = 64, .inactivity_timeout = 10000, }, + .mem = { + .dynamic_memory = 0, + .min_req_tx_blocks = 104, + .min_req_rx_blocks = 22, + .tx_min = 27, + } }; static void __wl1271_op_remove_interface(struct wl1271 *wl); @@ -524,13 +530,19 @@ static int wl1271_plt_init(struct wl1271 *wl) } static void wl1271_fw_status(struct wl1271 *wl, - struct wl1271_fw_status *status) + struct wl1271_fw_full_status *full_status) { + struct wl1271_fw_common_status *status = &full_status->common; struct timespec ts; u32 total = 0; int i; - wl1271_raw_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false); + if (wl->bss_type == BSS_TYPE_AP_BSS) + wl1271_raw_read(wl, FW_STATUS_ADDR, status, + sizeof(struct wl1271_fw_ap_status), false); + else + wl1271_raw_read(wl, FW_STATUS_ADDR, status, + sizeof(struct wl1271_fw_sta_status), false); wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " "drv_rx_counter = %d, tx_results_counter = %d)", @@ -589,7 +601,7 @@ static void wl1271_irq_work(struct work_struct *work) loopcount--; wl1271_fw_status(wl, wl->fw_status); - intr = le32_to_cpu(wl->fw_status->intr); + intr = le32_to_cpu(wl->fw_status->common.intr); if (!intr) { wl1271_debug(DEBUG_IRQ, "Zero interrupt received."); spin_lock_irqsave(&wl->wl_lock, flags); @@ -611,7 +623,7 @@ static void wl1271_irq_work(struct work_struct *work) wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); /* check for tx results */ - if (wl->fw_status->tx_results_counter != + if (wl->fw_status->common.tx_results_counter != (wl->tx_results_count & 0xff)) wl1271_tx_complete(wl); @@ -625,7 +637,7 @@ static void wl1271_irq_work(struct work_struct *work) wl1271_tx_work_locked(wl); } - wl1271_rx(wl, wl->fw_status); + wl1271_rx(wl, &wl->fw_status->common); } if (intr & WL1271_ACX_INTR_EVENT_A) { diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index 60a3738eadb0..2d3086ae6338 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c @@ -139,8 +139,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, return ret; } - ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE, - rates, send); + ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE); if (ret < 0) return ret; @@ -163,8 +162,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, if (ret < 0) return ret; - ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE, - rates, send); + ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE); if (ret < 0) return ret; diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c index b0c6ddc2a945..00d250d8da18 100644 --- a/drivers/net/wireless/wl12xx/rx.c +++ b/drivers/net/wireless/wl12xx/rx.c @@ -29,14 +29,14 @@ #include "rx.h" #include "io.h" -static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status, +static u8 wl1271_rx_get_mem_block(struct wl1271_fw_common_status *status, u32 drv_rx_counter) { return le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & RX_MEM_BLOCK_MASK; } -static u32 wl1271_rx_get_buf_size(struct wl1271_fw_status *status, +static u32 wl1271_rx_get_buf_size(struct wl1271_fw_common_status *status, u32 drv_rx_counter) { return (le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & @@ -134,7 +134,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) return 0; } -void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status) +void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status) { struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map; u32 buf_size; diff --git a/drivers/net/wireless/wl12xx/rx.h b/drivers/net/wireless/wl12xx/rx.h index 8d048b36bbba..4cef8fa3dee1 100644 --- a/drivers/net/wireless/wl12xx/rx.h +++ b/drivers/net/wireless/wl12xx/rx.h @@ -119,7 +119,7 @@ struct wl1271_rx_descriptor { u8 reserved; } __packed; -void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status); +void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status); u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); void wl1271_set_default_filters(struct wl1271 *wl); diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index d1de13fe7d9a..140e26f3bae9 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -130,7 +130,7 @@ extern u32 wl12xx_debug_level; -#define WL1271_FW_NAME "wl1271-fw.bin" +#define WL1271_FW_NAME "wl1271-fw-2.bin" #define WL1271_AP_FW_NAME "wl1271-fw-ap.bin" #define WL1271_NVS_NAME "wl1271-nvs.bin" @@ -214,8 +214,8 @@ struct wl1271_stats { /* Broadcast and Global links + links to stations */ #define AP_MAX_LINKS (AP_MAX_STATIONS + 2) -/* FW status registers */ -struct wl1271_fw_status { +/* FW status registers common for AP/STA */ +struct wl1271_fw_common_status { __le32 intr; u8 fw_rx_counter; u8 drv_rx_counter; @@ -224,6 +224,11 @@ struct wl1271_fw_status { __le32 rx_pkt_descs[NUM_RX_PKT_DESC]; __le32 tx_released_blks[NUM_TX_QUEUES]; __le32 fw_localtime; +} __packed; + +/* FW status registers for AP */ +struct wl1271_fw_ap_status { + struct wl1271_fw_common_status common; /* Next fields valid only in AP FW */ @@ -238,6 +243,24 @@ struct wl1271_fw_status { u8 padding_1[1]; } __packed; +/* FW status registers for STA */ +struct wl1271_fw_sta_status { + struct wl1271_fw_common_status common; + + u8 tx_total; + u8 reserved1; + __le16 reserved2; +} __packed; + +struct wl1271_fw_full_status { + union { + struct wl1271_fw_common_status common; + struct wl1271_fw_sta_status sta; + struct wl1271_fw_ap_status ap; + }; +} __packed; + + struct wl1271_rx_mem_pool_addr { u32 addr; u32 addr_extra; @@ -445,7 +468,7 @@ struct wl1271 { u32 buffer_cmd; u32 buffer_busyword[WL1271_BUSY_WORD_CNT]; - struct wl1271_fw_status *fw_status; + struct wl1271_fw_full_status *fw_status; struct wl1271_tx_hw_res_if *tx_res_if; struct ieee80211_vif *vif; -- cgit v1.2.3 From fe5ef090660de340b52823de7cb65b899bb4f012 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 2 Feb 2011 09:59:36 +0200 Subject: wl12xx: use the conf struct instead of macros for memory configuration make the configuration management more flexible by using the conf struct, rather than predefined macros. Signed-off-by: Eliad Peller Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 16 ++++++++-------- drivers/net/wireless/wl12xx/acx.h | 4 ---- drivers/net/wireless/wl12xx/conf.h | 12 ++++++++++++ drivers/net/wireless/wl12xx/main.c | 4 ++++ 4 files changed, 24 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index f2fbda06a129..6ea19d75cecc 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -961,10 +961,10 @@ int wl1271_acx_ap_mem_cfg(struct wl1271 *wl) } /* memory config */ - mem_conf->num_stations = DEFAULT_NUM_STATIONS; - mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS; - mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS; - mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES; + mem_conf->num_stations = wl->conf.mem.num_stations; + mem_conf->rx_mem_block_num = wl->conf.mem.rx_block_num; + mem_conf->tx_min_mem_block_num = wl->conf.mem.tx_min_block_num; + mem_conf->num_ssid_profiles = wl->conf.mem.ssid_profiles; mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf, @@ -993,10 +993,10 @@ int wl1271_acx_sta_mem_cfg(struct wl1271 *wl) } /* memory config */ - mem_conf->num_stations = DEFAULT_NUM_STATIONS; - mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS; - mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS; - mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES; + mem_conf->num_stations = wl->conf.mem.num_stations; + mem_conf->rx_mem_block_num = wl->conf.mem.rx_block_num; + mem_conf->tx_min_mem_block_num = wl->conf.mem.tx_min_block_num; + mem_conf->num_ssid_profiles = wl->conf.mem.ssid_profiles; mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); mem_conf->dyn_mem_enable = wl->conf.mem.dynamic_memory; mem_conf->tx_free_req = wl->conf.mem.min_req_tx_blocks; diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index 537fab40ed12..4e301de916bb 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h @@ -133,7 +133,6 @@ enum { #define DEFAULT_UCAST_PRIORITY 0 #define DEFAULT_RX_Q_PRIORITY 0 -#define DEFAULT_NUM_STATIONS 1 #define DEFAULT_RXQ_PRIORITY 0 /* low 0 .. 15 high */ #define DEFAULT_RXQ_TYPE 0x07 /* All frames, Data/Ctrl/Mgmt */ #define TRACE_BUFFER_MAX_SIZE 256 @@ -797,10 +796,7 @@ struct acx_tx_config_options { __le16 tx_compl_threshold; /* number of packets */ } __packed; -#define ACX_RX_MEM_BLOCKS 70 -#define ACX_TX_MIN_MEM_BLOCKS 40 #define ACX_TX_DESCRIPTORS 32 -#define ACX_NUM_SSID_PROFILES 1 struct wl1271_acx_ap_config_memory { struct acx_header header; diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index d8c124919382..856a8a2fff4f 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h @@ -1152,6 +1152,18 @@ struct conf_ht_setting { }; struct conf_memory_settings { + /* Number of stations supported in IBSS mode */ + u8 num_stations; + + /* Number of ssid profiles used in IBSS mode */ + u8 ssid_profiles; + + /* Number of memory buffers allocated to rx pool */ + u8 rx_block_num; + + /* Minimum number of blocks allocated to tx pool */ + u8 tx_min_block_num; + /* Disable/Enable dynamic memory */ u8 dynamic_memory; diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 91d681221286..24cdc78c00b3 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -299,6 +299,10 @@ static struct conf_drv_settings default_conf = { .inactivity_timeout = 10000, }, .mem = { + .num_stations = 1, + .ssid_profiles = 1, + .rx_block_num = 70, + .tx_min_block_num = 40, .dynamic_memory = 0, .min_req_tx_blocks = 104, .min_req_rx_blocks = 22, -- cgit v1.2.3 From 72c2d9e511846a4f2759389b38ed8a5553579eb3 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 2 Feb 2011 09:59:37 +0200 Subject: wl12xx: set supported_rates after association Instead of looking for supported_rates change on every tx packet, just extract the supported_rates after association completes (station only). Remove wl1271.sta_rate_set and WL1271_FLAG_STA_RATES_CHANGED which are not used anymore. Signed-off-by: Eliad Peller Reviewed-by: Juuso Oikarinen Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 4 ++ drivers/net/wireless/wl12xx/cmd.c | 11 ++-- drivers/net/wireless/wl12xx/main.c | 116 ++++++++++++++--------------------- drivers/net/wireless/wl12xx/tx.c | 22 ------- drivers/net/wireless/wl12xx/wl12xx.h | 35 ++++++----- 5 files changed, 73 insertions(+), 115 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index 6ea19d75cecc..33840d95d17d 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -783,6 +783,10 @@ int wl1271_acx_sta_rate_policies(struct wl1271 *wl) acx->rate_class_cnt = cpu_to_le32(ACX_TX_RATE_POLICY_CNT); + wl1271_debug(DEBUG_ACX, "basic_rate: 0x%x, full_rate: 0x%x", + acx->rate_class[ACX_TX_BASIC_RATE].enabled_rates, + acx->rate_class[ACX_TX_AP_FULL_RATE].enabled_rates); + ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); if (ret < 0) { wl1271_warning("Setting of rate policies failed: %d", ret); diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 66d15e77da38..97ffd7aa57a8 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -286,13 +286,7 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) join->rx_filter_options = cpu_to_le32(wl->rx_filter); join->bss_type = bss_type; join->basic_rate_set = cpu_to_le32(wl->basic_rate_set); - /* - * for supported_rate_set, we should use wl->rate_set. however, - * it seems that acx_rate_policies doesn't affect full_rate, and - * since we want to avoid additional join, we'll use a 0xffffffff value, - * and let the fw find the actual supported rates - */ - join->supported_rate_set = cpu_to_le32(0xffffffff); + join->supported_rate_set = cpu_to_le32(wl->rate_set); if (wl->band == IEEE80211_BAND_5GHZ) join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ; @@ -310,6 +304,9 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) wl->tx_security_last_seq = 0; wl->tx_security_seq = 0; + wl1271_debug(DEBUG_CMD, "cmd join: basic_rate_set=0x%x, rate_set=0x%x", + join->basic_rate_set, join->supported_rate_set); + ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0); if (ret < 0) { wl1271_error("failed to initiate cmd join"); diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 24cdc78c00b3..61dea73f5fdc 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -978,39 +978,10 @@ int wl1271_plt_stop(struct wl1271 *wl) static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct wl1271 *wl = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); - struct ieee80211_sta *sta = txinfo->control.sta; unsigned long flags; int q; - /* - * peek into the rates configured in the STA entry. - * The rates set after connection stage, The first block only BG sets: - * the compare is for bit 0-16 of sta_rate_set. The second block add - * HT rates in case of HT supported. - */ spin_lock_irqsave(&wl->wl_lock, flags); - if (sta && - (sta->supp_rates[conf->channel->band] != - (wl->sta_rate_set & HW_BG_RATES_MASK)) && - wl->bss_type != BSS_TYPE_AP_BSS) { - wl->sta_rate_set = sta->supp_rates[conf->channel->band]; - set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags); - } - -#ifdef CONFIG_WL12XX_HT - if (sta && - sta->ht_cap.ht_supported && - ((wl->sta_rate_set >> HW_HT_RATES_OFFSET) != - sta->ht_cap.mcs.rx_mask[0])) { - /* Clean MCS bits before setting them */ - wl->sta_rate_set &= HW_BG_RATES_MASK; - wl->sta_rate_set |= - (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET); - set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags); - } -#endif wl->tx_queue_count++; spin_unlock_irqrestore(&wl->wl_lock, flags); @@ -1245,7 +1216,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl) wl->time_offset = 0; wl->session_counter = 0; wl->rate_set = CONF_TX_RATE_MASK_BASIC; - wl->sta_rate_set = 0; wl->flags = 0; wl->vif = NULL; wl->filters = 0; @@ -1432,7 +1402,6 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, bool idle) goto out; } wl->rate_set = wl1271_tx_min_rate_get(wl); - wl->sta_rate_set = 0; ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) goto out; @@ -2246,6 +2215,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, { bool do_join = false, set_assoc = false; bool is_ibss = (wl->bss_type == BSS_TYPE_IBSS); + u32 sta_rate_set = 0; int ret; struct ieee80211_sta *sta; @@ -2311,6 +2281,49 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, } } + rcu_read_lock(); + sta = ieee80211_find_sta(vif, bss_conf->bssid); + if (sta) { + /* save the supp_rates of the ap */ + sta_rate_set = sta->supp_rates[wl->hw->conf.channel->band]; + if (sta->ht_cap.ht_supported) + sta_rate_set |= + (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET); + + /* handle new association with HT and HT information change */ + if ((changed & BSS_CHANGED_HT) && + (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { + ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, + true); + if (ret < 0) { + wl1271_warning("Set ht cap true failed %d", + ret); + rcu_read_unlock(); + goto out; + } + ret = wl1271_acx_set_ht_information(wl, + bss_conf->ht_operation_mode); + if (ret < 0) { + wl1271_warning("Set ht information failed %d", + ret); + rcu_read_unlock(); + goto out; + } + } + /* handle new association without HT and disassociation */ + else if (changed & BSS_CHANGED_ASSOC) { + ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, + false); + if (ret < 0) { + wl1271_warning("Set ht cap false failed %d", + ret); + rcu_read_unlock(); + goto out; + } + } + } + rcu_read_unlock(); + if ((changed & BSS_CHANGED_ASSOC)) { if (bss_conf->assoc) { u32 rates; @@ -2328,6 +2341,9 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates); wl->basic_rate = wl1271_tx_min_rate_get(wl); + if (sta_rate_set) + wl->rate_set = wl1271_tx_enabled_rates_get(wl, + sta_rate_set); ret = wl1271_acx_sta_rate_policies(wl); if (ret < 0) goto out; @@ -2406,43 +2422,6 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, if (ret < 0) goto out; - rcu_read_lock(); - sta = ieee80211_find_sta(vif, bss_conf->bssid); - if (sta) { - /* handle new association with HT and HT information change */ - if ((changed & BSS_CHANGED_HT) && - (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { - ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, - true); - if (ret < 0) { - wl1271_warning("Set ht cap true failed %d", - ret); - rcu_read_unlock(); - goto out; - } - ret = wl1271_acx_set_ht_information(wl, - bss_conf->ht_operation_mode); - if (ret < 0) { - wl1271_warning("Set ht information failed %d", - ret); - rcu_read_unlock(); - goto out; - } - } - /* handle new association without HT and disassociation */ - else if (changed & BSS_CHANGED_ASSOC) { - ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, - false); - if (ret < 0) { - wl1271_warning("Set ht cap false failed %d", - ret); - rcu_read_unlock(); - goto out; - } - } - } - rcu_read_unlock(); - if (changed & BSS_CHANGED_ARP_FILTER) { __be32 addr = bss_conf->arp_addr_list[0]; WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS); @@ -3330,7 +3309,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void) wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC; wl->basic_rate = CONF_TX_RATE_MASK_BASIC; wl->rate_set = CONF_TX_RATE_MASK_BASIC; - wl->sta_rate_set = 0; wl->band = IEEE80211_BAND_2GHZ; wl->vif = NULL; wl->flags = 0; diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 3507c81c7500..67a00946e3dd 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -334,35 +334,13 @@ void wl1271_tx_work_locked(struct wl1271 *wl) { struct sk_buff *skb; bool woken_up = false; - u32 sta_rates = 0; u32 buf_offset = 0; bool sent_packets = false; int ret; - /* check if the rates supported by the AP have changed */ - if (unlikely(test_and_clear_bit(WL1271_FLAG_STA_RATES_CHANGED, - &wl->flags))) { - unsigned long flags; - - spin_lock_irqsave(&wl->wl_lock, flags); - sta_rates = wl->sta_rate_set; - spin_unlock_irqrestore(&wl->wl_lock, flags); - } - if (unlikely(wl->state == WL1271_STATE_OFF)) goto out; - /* if rates have changed, re-configure the rate policy */ - if (unlikely(sta_rates)) { - ret = wl1271_ps_elp_wakeup(wl, false); - if (ret < 0) - goto out; - woken_up = true; - - wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates); - wl1271_acx_sta_rate_policies(wl); - } - while ((skb = wl1271_skb_dequeue(wl))) { if (!woken_up) { ret = wl1271_ps_elp_wakeup(wl, false); diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 140e26f3bae9..1d6c94304b1a 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -301,6 +301,24 @@ struct wl1271_ap_key { u16 tx_seq_16; }; +enum wl12xx_flags { + WL1271_FLAG_STA_ASSOCIATED, + WL1271_FLAG_JOINED, + WL1271_FLAG_GPIO_POWER, + WL1271_FLAG_TX_QUEUE_STOPPED, + WL1271_FLAG_IN_ELP, + WL1271_FLAG_PSM, + WL1271_FLAG_PSM_REQUESTED, + WL1271_FLAG_IRQ_PENDING, + WL1271_FLAG_IRQ_RUNNING, + WL1271_FLAG_IDLE, + WL1271_FLAG_IDLE_REQUESTED, + WL1271_FLAG_PSPOLL_FAILURE, + WL1271_FLAG_STA_STATE_SENT, + WL1271_FLAG_FW_TX_BUSY, + WL1271_FLAG_AP_STARTED +}; + struct wl1271 { struct platform_device *plat_dev; struct ieee80211_hw *hw; @@ -319,22 +337,6 @@ struct wl1271 { enum wl1271_state state; struct mutex mutex; -#define WL1271_FLAG_STA_RATES_CHANGED (0) -#define WL1271_FLAG_STA_ASSOCIATED (1) -#define WL1271_FLAG_JOINED (2) -#define WL1271_FLAG_GPIO_POWER (3) -#define WL1271_FLAG_TX_QUEUE_STOPPED (4) -#define WL1271_FLAG_IN_ELP (5) -#define WL1271_FLAG_PSM (6) -#define WL1271_FLAG_PSM_REQUESTED (7) -#define WL1271_FLAG_IRQ_PENDING (8) -#define WL1271_FLAG_IRQ_RUNNING (9) -#define WL1271_FLAG_IDLE (10) -#define WL1271_FLAG_IDLE_REQUESTED (11) -#define WL1271_FLAG_PSPOLL_FAILURE (12) -#define WL1271_FLAG_STA_STATE_SENT (13) -#define WL1271_FLAG_FW_TX_BUSY (14) -#define WL1271_FLAG_AP_STARTED (15) unsigned long flags; struct wl1271_partition_set part; @@ -428,7 +430,6 @@ struct wl1271 { * bits 16-23 - 802.11n MCS index mask * support only 1 stream, thus only 8 bits for the MCS rates (0-7). */ - u32 sta_rate_set; u32 basic_rate_set; u32 basic_rate; u32 rate_set; -- cgit v1.2.3 From ac66808814036b4c33dd98091b2176ae6157f1a8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 9 Feb 2011 16:15:32 +0000 Subject: drm/i915: Disable RC6 on Ironlake The automatic powersaving feature is once again causing havoc, with 100% reliable hangs on boot and resume on affected machines. Reported-by: Francesco Allertsen Reported-by: Gui Rui Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=28582 Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.c | 5 +- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_display.c | 92 ++++++++++++++++++++---------------- drivers/gpu/drm/i915/intel_drv.h | 1 - 4 files changed, 55 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index cfb56d0ff367..0ad533f06af9 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -46,6 +46,9 @@ module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); unsigned int i915_powersave = 1; module_param_named(powersave, i915_powersave, int, 0600); +unsigned int i915_enable_rc6 = 0; +module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); + unsigned int i915_lvds_downclock = 0; module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); @@ -360,7 +363,7 @@ static int i915_drm_thaw(struct drm_device *dev) /* Resume the modeset for every activated CRTC */ drm_helper_resume_force_mode(dev); - if (dev_priv->renderctx && dev_priv->pwrctx) + if (IS_IRONLAKE_M(dev)) ironlake_enable_rc6(dev); } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a0149c619cdd..65dfe81d0035 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -958,6 +958,7 @@ extern unsigned int i915_fbpercrtc; extern unsigned int i915_powersave; extern unsigned int i915_lvds_downclock; extern unsigned int i915_panel_use_ssc; +extern unsigned int i915_enable_rc6; extern int i915_suspend(struct drm_device *dev, pm_message_t state); extern int i915_resume(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7e42aa586504..94622e3a202e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6463,52 +6463,60 @@ void intel_enable_clock_gating(struct drm_device *dev) } } -void intel_disable_clock_gating(struct drm_device *dev) +static void ironlake_teardown_rc6(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; if (dev_priv->renderctx) { - struct drm_i915_gem_object *obj = dev_priv->renderctx; - - I915_WRITE(CCID, 0); - POSTING_READ(CCID); - - i915_gem_object_unpin(obj); - drm_gem_object_unreference(&obj->base); + i915_gem_object_unpin(dev_priv->renderctx); + drm_gem_object_unreference(&dev_priv->renderctx->base); dev_priv->renderctx = NULL; } if (dev_priv->pwrctx) { - struct drm_i915_gem_object *obj = dev_priv->pwrctx; + i915_gem_object_unpin(dev_priv->pwrctx); + drm_gem_object_unreference(&dev_priv->pwrctx->base); + dev_priv->pwrctx = NULL; + } +} + +static void ironlake_disable_rc6(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (I915_READ(PWRCTXA)) { + /* Wake the GPU, prevent RC6, then restore RSTDBYCTL */ + I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) | RCX_SW_EXIT); + wait_for(((I915_READ(RSTDBYCTL) & RSX_STATUS_MASK) == RSX_STATUS_ON), + 50); I915_WRITE(PWRCTXA, 0); POSTING_READ(PWRCTXA); - i915_gem_object_unpin(obj); - drm_gem_object_unreference(&obj->base); - dev_priv->pwrctx = NULL; + I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); + POSTING_READ(RSTDBYCTL); } + + ironlake_disable_rc6(dev); } -static void ironlake_disable_rc6(struct drm_device *dev) +static int ironlake_setup_rc6(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - /* Wake the GPU, prevent RC6, then restore RSTDBYCTL */ - I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) | RCX_SW_EXIT); - wait_for(((I915_READ(RSTDBYCTL) & RSX_STATUS_MASK) == RSX_STATUS_ON), - 10); - POSTING_READ(CCID); - I915_WRITE(PWRCTXA, 0); - POSTING_READ(PWRCTXA); - I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); - POSTING_READ(RSTDBYCTL); - i915_gem_object_unpin(dev_priv->renderctx); - drm_gem_object_unreference(&dev_priv->renderctx->base); - dev_priv->renderctx = NULL; - i915_gem_object_unpin(dev_priv->pwrctx); - drm_gem_object_unreference(&dev_priv->pwrctx->base); - dev_priv->pwrctx = NULL; + if (dev_priv->renderctx == NULL) + dev_priv->renderctx = intel_alloc_context_page(dev); + if (!dev_priv->renderctx) + return -ENOMEM; + + if (dev_priv->pwrctx == NULL) + dev_priv->pwrctx = intel_alloc_context_page(dev); + if (!dev_priv->pwrctx) { + ironlake_teardown_rc6(dev); + return -ENOMEM; + } + + return 0; } void ironlake_enable_rc6(struct drm_device *dev) @@ -6516,15 +6524,26 @@ void ironlake_enable_rc6(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; int ret; + /* rc6 disabled by default due to repeated reports of hanging during + * boot and resume. + */ + if (!i915_enable_rc6) + return; + + ret = ironlake_setup_rc6(dev); + if (ret) + return; + /* * GPU can automatically power down the render unit if given a page * to save state. */ ret = BEGIN_LP_RING(6); if (ret) { - ironlake_disable_rc6(dev); + ironlake_teardown_rc6(dev); return; } + OUT_RING(MI_SUSPEND_FLUSH | MI_SUSPEND_FLUSH_EN); OUT_RING(MI_SET_CONTEXT); OUT_RING(dev_priv->renderctx->gtt_offset | @@ -6541,6 +6560,7 @@ void ironlake_enable_rc6(struct drm_device *dev) I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); } + /* Set up chip specific display functions */ static void intel_init_display(struct drm_device *dev) { @@ -6783,21 +6803,9 @@ void intel_modeset_init(struct drm_device *dev) if (IS_GEN6(dev)) gen6_enable_rps(dev_priv); - if (IS_IRONLAKE_M(dev)) { - dev_priv->renderctx = intel_alloc_context_page(dev); - if (!dev_priv->renderctx) - goto skip_rc6; - dev_priv->pwrctx = intel_alloc_context_page(dev); - if (!dev_priv->pwrctx) { - i915_gem_object_unpin(dev_priv->renderctx); - drm_gem_object_unreference(&dev_priv->renderctx->base); - dev_priv->renderctx = NULL; - goto skip_rc6; - } + if (IS_IRONLAKE_M(dev)) ironlake_enable_rc6(dev); - } -skip_rc6: INIT_WORK(&dev_priv->idle_work, intel_idle_update); setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, (unsigned long)dev); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 74db2557d644..2c431049963c 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -298,7 +298,6 @@ extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue, int regno); extern void intel_enable_clock_gating(struct drm_device *dev); -extern void intel_disable_clock_gating(struct drm_device *dev); extern void ironlake_enable_drps(struct drm_device *dev); extern void ironlake_disable_drps(struct drm_device *dev); extern void gen6_enable_rps(struct drm_i915_private *dev_priv); -- cgit v1.2.3 From fd821d1e8a8a4d21324c79c1d54b1131170c0721 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 8 Feb 2011 14:39:13 +0100 Subject: staging: brcm80211: implement mac80211 callback set_rts_threshold adds implementation for allowing configuration of dot11RTSThreshold as defined in the 802.11 standards. The mac80211 module will use callback set_rts_threshold to configure this in the driver. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 6 +++++- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 18 ++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index b339d714aaa2..54bfe22ec128 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -461,7 +461,11 @@ wl_ops_get_stats(struct ieee80211_hw *hw, static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value) { - WL_ERROR("%s: Enter\n", __func__); + struct wl_info *wl = hw->priv; + + WL_LOCK(wl); + wlc_iovar_setint(wl->wlc, "rtsthresh", value & 0xFFFF); + WL_UNLOCK(wl); return 0; } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index bba84ebe4d5b..d64171ff12aa 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -140,16 +140,17 @@ static struct wlc_info *wlc_info_dbg = (struct wlc_info *) (NULL); */ enum { IOV_MPC = 1, + IOV_RTSTHRESH, IOV_QTXPOWER, IOV_BCN_LI_BCN, /* Beacon listen interval in # of beacons */ IOV_LAST /* In case of a need to check max ID number */ }; const bcm_iovar_t wlc_iovars[] = { - {"mpc", IOV_MPC, (IOVF_OPEN_ALLOW), IOVT_BOOL, 0}, - {"qtxpower", IOV_QTXPOWER, (IOVF_WHL | IOVF_OPEN_ALLOW), IOVT_UINT32, - 0}, - {"bcn_li_bcn", IOV_BCN_LI_BCN, 0, IOVT_UINT8, 0}, + {"mpc", IOV_MPC, (0), IOVT_BOOL, 0}, + {"rtsthresh", IOV_RTSTHRESH, (IOVF_WHL), IOVT_UINT16, 0}, + {"qtxpower", IOV_QTXPOWER, (IOVF_WHL), IOVT_UINT32, 0}, + {"bcn_li_bcn", IOV_BCN_LI_BCN, (0), IOVT_UINT8, 0}, {NULL, 0, 0, 0, 0} }; @@ -239,6 +240,7 @@ static u16 BCMFASTPATH wlc_d11hdrs_mac80211(struct wlc_info *wlc, wsec_key_t *key, ratespec_t rspec_override); +static void wlc_ctrupd_cache(u16 cur_stat, u16 *macstat_snapshot, u32 *macstat); static void wlc_bss_default_init(struct wlc_info *wlc); static void wlc_ucode_mac_upd(struct wlc_info *wlc); static ratespec_t mac80211_wlc_set_nrate(struct wlc_info *wlc, @@ -4577,6 +4579,9 @@ wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, wlc->pub->unit, __func__, IOV_ID(actionid)); /* Do the actual parameter implementation */ switch (actionid) { + case IOV_SVAL(IOV_RTSTHRESH): + wlc->RTSThresh = int_val; + break; case IOV_GVAL(IOV_QTXPOWER):{ uint qdbm; @@ -5970,6 +5975,11 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, txrate[0]->count = 0; txrate[1]->count = 0; + /* (2) PROTECTION, may change rspec */ + if ((ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) && + (phylen > wlc->RTSThresh) && !is_multicast_ether_addr(h->addr1)) + use_rts = true; + /* (3) PLCP: determine PLCP header and MAC duration, fill d11txh_t */ wlc_compute_plcp(wlc, rspec[0], phylen, plcp); wlc_compute_plcp(wlc, rspec[1], phylen, plcp_fallback); -- cgit v1.2.3 From c8a0064cb7c9f12220f37ba52f4616a78bf9ddd5 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 6 Feb 2011 22:52:52 +0900 Subject: staging: rtl8192e: Remove duplicate header Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211.h | 2682 ---------------------------------- 1 file changed, 2682 deletions(-) delete mode 100644 drivers/staging/rtl8192e/ieee80211.h (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211.h b/drivers/staging/rtl8192e/ieee80211.h deleted file mode 100644 index ffa4d7bd1105..000000000000 --- a/drivers/staging/rtl8192e/ieee80211.h +++ /dev/null @@ -1,2682 +0,0 @@ -/* - * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11 - * remains copyright by the original authors - * - * Portions of the merged code are based on Host AP (software wireless - * LAN access point) driver for Intersil Prism2/2.5/3. - * - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * - * Copyright (c) 2002-2003, Jouni Malinen - * - * Adaption to a generic IEEE 802.11 stack by James Ketrenos - * - * Copyright (c) 2004, Intel Corporation - * - * Modified for Realtek's wi-fi cards by Andrea Merello - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See README and COPYING for - * more details. - */ -#ifndef IEEE80211_H -#define IEEE80211_H -#include /* ETH_ALEN */ -#include /* ARRAY_SIZE */ -#include -#include -#include -#include -#include - -#include -#include - -#include "ieee80211/rtl819x_HT.h" -#include "ieee80211/rtl819x_BA.h" -#include "ieee80211/rtl819x_TS.h" - -#ifndef IW_MODE_MONITOR -#define IW_MODE_MONITOR 6 -#endif - -#ifndef IWEVCUSTOM -#define IWEVCUSTOM 0x8c02 -#endif - -#ifndef container_of -/** - * container_of - cast a member of a structure out to the containing structure - * - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - * - */ -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) -#endif - -#define KEY_TYPE_NA 0x0 -#define KEY_TYPE_WEP40 0x1 -#define KEY_TYPE_TKIP 0x2 -#define KEY_TYPE_CCMP 0x4 -#define KEY_TYPE_WEP104 0x5 - -/* added for rtl819x tx procedure */ -#define MAX_QUEUE_SIZE 0x10 - -// -// 8190 queue mapping -// -#define BK_QUEUE 0 -#define BE_QUEUE 1 -#define VI_QUEUE 2 -#define VO_QUEUE 3 -#define HCCA_QUEUE 4 -#define TXCMD_QUEUE 5 -#define MGNT_QUEUE 6 -#define HIGH_QUEUE 7 -#define BEACON_QUEUE 8 - -#define LOW_QUEUE BE_QUEUE -#define NORMAL_QUEUE MGNT_QUEUE - -//added by amy for ps -#define SWRF_TIMEOUT 50 - -//added by amy for LEAP related -#define IE_CISCO_FLAG_POSITION 0x08 // Flag byte: byte 8, numbered from 0. -#define SUPPORT_CKIP_MIC 0x08 // bit3 -#define SUPPORT_CKIP_PK 0x10 // bit4 -/* defined for skb cb field */ -/* At most 28 byte */ -typedef struct cb_desc { - /* Tx Desc Related flags (8-9) */ - u8 bLastIniPkt:1; - u8 bCmdOrInit:1; - u8 bFirstSeg:1; - u8 bLastSeg:1; - u8 bEncrypt:1; - u8 bTxDisableRateFallBack:1; - u8 bTxUseDriverAssingedRate:1; - u8 bHwSec:1; //indicate whether use Hw security. WB - - u8 reserved1; - - /* Tx Firmware Relaged flags (10-11)*/ - u8 bCTSEnable:1; - u8 bRTSEnable:1; - u8 bUseShortGI:1; - u8 bUseShortPreamble:1; - u8 bTxEnableFwCalcDur:1; - u8 bAMPDUEnable:1; - u8 bRTSSTBC:1; - u8 RTSSC:1; - - u8 bRTSBW:1; - u8 bPacketBW:1; - u8 bRTSUseShortPreamble:1; - u8 bRTSUseShortGI:1; - u8 bMulticast:1; - u8 bBroadcast:1; - //u8 reserved2:2; - u8 drv_agg_enable:1; - u8 reserved2:1; - - /* Tx Desc related element(12-19) */ - u8 rata_index; - u8 queue_index; - //u8 reserved3; - //u8 reserved4; - u16 txbuf_size; - //u8 reserved5; - u8 RATRIndex; - u8 reserved6; - u8 reserved7; - u8 reserved8; - - /* Tx firmware related element(20-27) */ - u8 data_rate; - u8 rts_rate; - u8 ampdu_factor; - u8 ampdu_density; - //u8 reserved9; - //u8 reserved10; - //u8 reserved11; - u8 DrvAggrNum; - u16 pkt_size; - u8 reserved12; -}cb_desc, *pcb_desc; - -/*--------------------------Define -------------------------------------------*/ -#define MGN_1M 0x02 -#define MGN_2M 0x04 -#define MGN_5_5M 0x0b -#define MGN_11M 0x16 - -#define MGN_6M 0x0c -#define MGN_9M 0x12 -#define MGN_12M 0x18 -#define MGN_18M 0x24 -#define MGN_24M 0x30 -#define MGN_36M 0x48 -#define MGN_48M 0x60 -#define MGN_54M 0x6c - -#define MGN_MCS0 0x80 -#define MGN_MCS1 0x81 -#define MGN_MCS2 0x82 -#define MGN_MCS3 0x83 -#define MGN_MCS4 0x84 -#define MGN_MCS5 0x85 -#define MGN_MCS6 0x86 -#define MGN_MCS7 0x87 -#define MGN_MCS8 0x88 -#define MGN_MCS9 0x89 -#define MGN_MCS10 0x8a -#define MGN_MCS11 0x8b -#define MGN_MCS12 0x8c -#define MGN_MCS13 0x8d -#define MGN_MCS14 0x8e -#define MGN_MCS15 0x8f - -//---------------------------------------------------------------------------- -// 802.11 Management frame Reason Code field -//---------------------------------------------------------------------------- -enum _ReasonCode{ - unspec_reason = 0x1, - auth_not_valid = 0x2, - deauth_lv_ss = 0x3, - inactivity = 0x4, - ap_overload = 0x5, - class2_err = 0x6, - class3_err = 0x7, - disas_lv_ss = 0x8, - asoc_not_auth = 0x9, - - //----MIC_CHECK - mic_failure = 0xe, - //----END MIC_CHECK - - // Reason code defined in 802.11i D10.0 p.28. - invalid_IE = 0x0d, - four_way_tmout = 0x0f, - two_way_tmout = 0x10, - IE_dismatch = 0x11, - invalid_Gcipher = 0x12, - invalid_Pcipher = 0x13, - invalid_AKMP = 0x14, - unsup_RSNIEver = 0x15, - invalid_RSNIE = 0x16, - auth_802_1x_fail= 0x17, - ciper_reject = 0x18, - - // Reason code defined in 7.3.1.7, 802.1e D13.0, p.42. Added by Annie, 2005-11-15. - QoS_unspec = 0x20, // 32 - QAP_bandwidth = 0x21, // 33 - poor_condition = 0x22, // 34 - no_facility = 0x23, // 35 - // Where is 36??? - req_declined = 0x25, // 37 - invalid_param = 0x26, // 38 - req_not_honored= 0x27, // 39 - TS_not_created = 0x2F, // 47 - DL_not_allowed = 0x30, // 48 - dest_not_exist = 0x31, // 49 - dest_not_QSTA = 0x32, // 50 -}; - - - -#define aSifsTime (((priv->ieee80211->current_network.mode == IEEE_A)||(priv->ieee80211->current_network.mode == IEEE_N_24G)||(priv->ieee80211->current_network.mode == IEEE_N_5G))? 16 : 10) - -#define MGMT_QUEUE_NUM 5 - -#define IEEE_CMD_SET_WPA_PARAM 1 -#define IEEE_CMD_SET_WPA_IE 2 -#define IEEE_CMD_SET_ENCRYPTION 3 -#define IEEE_CMD_MLME 4 - -#define IEEE_PARAM_WPA_ENABLED 1 -#define IEEE_PARAM_TKIP_COUNTERMEASURES 2 -#define IEEE_PARAM_DROP_UNENCRYPTED 3 -#define IEEE_PARAM_PRIVACY_INVOKED 4 -#define IEEE_PARAM_AUTH_ALGS 5 -#define IEEE_PARAM_IEEE_802_1X 6 -//It should consistent with the driver_XXX.c -// David, 2006.9.26 -#define IEEE_PARAM_WPAX_SELECT 7 -//Added for notify the encryption type selection -// David, 2006.9.26 -#define IEEE_PROTO_WPA 1 -#define IEEE_PROTO_RSN 2 -//Added for notify the encryption type selection -// David, 2006.9.26 -#define IEEE_WPAX_USEGROUP 0 -#define IEEE_WPAX_WEP40 1 -#define IEEE_WPAX_TKIP 2 -#define IEEE_WPAX_WRAP 3 -#define IEEE_WPAX_CCMP 4 -#define IEEE_WPAX_WEP104 5 - -#define IEEE_KEY_MGMT_IEEE8021X 1 -#define IEEE_KEY_MGMT_PSK 2 - -#define IEEE_MLME_STA_DEAUTH 1 -#define IEEE_MLME_STA_DISASSOC 2 - - -#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2 -#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3 -#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4 -#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5 -#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6 -#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7 - - -#define IEEE_CRYPT_ALG_NAME_LEN 16 - -#define MAX_IE_LEN 0xff - -// added for kernel conflict -#define ieee80211_crypt_deinit_entries ieee80211_crypt_deinit_entries_rsl -#define ieee80211_crypt_deinit_handler ieee80211_crypt_deinit_handler_rsl -#define ieee80211_crypt_delayed_deinit ieee80211_crypt_delayed_deinit_rsl -#define ieee80211_register_crypto_ops ieee80211_register_crypto_ops_rsl -#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rsl -#define ieee80211_get_crypto_ops ieee80211_get_crypto_ops_rsl - -#define ieee80211_ccmp_null ieee80211_ccmp_null_rsl - -#define ieee80211_tkip_null ieee80211_tkip_null_rsl - -#define ieee80211_wep_null ieee80211_wep_null_rsl - -#define free_ieee80211 free_ieee80211_rsl -#define alloc_ieee80211 alloc_ieee80211_rsl - -#define ieee80211_rx ieee80211_rx_rsl -#define ieee80211_rx_mgt ieee80211_rx_mgt_rsl - -#define ieee80211_get_beacon ieee80211_get_beacon_rsl -#define ieee80211_rtl_wake_queue ieee80211_rtl_wake_queue_rsl -#define ieee80211_rtl_stop_queue ieee80211_rtl_stop_queue_rsl -#define ieee80211_reset_queue ieee80211_reset_queue_rsl -#define ieee80211_softmac_stop_protocol ieee80211_softmac_stop_protocol_rsl -#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl -#define ieee80211_is_shortslot ieee80211_is_shortslot_rsl -#define ieee80211_is_54g ieee80211_is_54g_rsl -#define ieee80211_wpa_supplicant_ioctl ieee80211_wpa_supplicant_ioctl_rsl -#define ieee80211_ps_tx_ack ieee80211_ps_tx_ack_rsl -#define ieee80211_softmac_xmit ieee80211_softmac_xmit_rsl -#define ieee80211_stop_send_beacons ieee80211_stop_send_beacons_rsl -#define notify_wx_assoc_event notify_wx_assoc_event_rsl -#define SendDisassociation SendDisassociation_rsl -#define ieee80211_disassociate ieee80211_disassociate_rsl -#define ieee80211_start_send_beacons ieee80211_start_send_beacons_rsl -#define ieee80211_stop_scan ieee80211_stop_scan_rsl -#define ieee80211_send_probe_requests ieee80211_send_probe_requests_rsl -#define ieee80211_softmac_scan_syncro ieee80211_softmac_scan_syncro_rsl -#define ieee80211_start_scan_syncro ieee80211_start_scan_syncro_rsl - -#define ieee80211_wx_get_essid ieee80211_wx_get_essid_rsl -#define ieee80211_wx_set_essid ieee80211_wx_set_essid_rsl -#define ieee80211_wx_set_rate ieee80211_wx_set_rate_rsl -#define ieee80211_wx_get_rate ieee80211_wx_get_rate_rsl -#define ieee80211_wx_set_wap ieee80211_wx_set_wap_rsl -#define ieee80211_wx_get_wap ieee80211_wx_get_wap_rsl -#define ieee80211_wx_set_mode ieee80211_wx_set_mode_rsl -#define ieee80211_wx_get_mode ieee80211_wx_get_mode_rsl -#define ieee80211_wx_set_scan ieee80211_wx_set_scan_rsl -#define ieee80211_wx_get_freq ieee80211_wx_get_freq_rsl -#define ieee80211_wx_set_freq ieee80211_wx_set_freq_rsl -#define ieee80211_wx_set_rawtx ieee80211_wx_set_rawtx_rsl -#define ieee80211_wx_get_name ieee80211_wx_get_name_rsl -#define ieee80211_wx_set_power ieee80211_wx_set_power_rsl -#define ieee80211_wx_get_power ieee80211_wx_get_power_rsl -#define ieee80211_wlan_frequencies ieee80211_wlan_frequencies_rsl -#define ieee80211_wx_set_rts ieee80211_wx_set_rts_rsl -#define ieee80211_wx_get_rts ieee80211_wx_get_rts_rsl - -#define ieee80211_txb_free ieee80211_txb_free_rsl - -#define ieee80211_wx_set_gen_ie ieee80211_wx_set_gen_ie_rsl -#define ieee80211_wx_get_scan ieee80211_wx_get_scan_rsl -#define ieee80211_wx_set_encode ieee80211_wx_set_encode_rsl -#define ieee80211_wx_get_encode ieee80211_wx_get_encode_rsl -#if WIRELESS_EXT >= 18 -#define ieee80211_wx_set_mlme ieee80211_wx_set_mlme_rsl -#define ieee80211_wx_set_auth ieee80211_wx_set_auth_rsl -#define ieee80211_wx_set_encode_ext ieee80211_wx_set_encode_ext_rsl -#define ieee80211_wx_get_encode_ext ieee80211_wx_get_encode_ext_rsl -#endif - - -typedef struct ieee_param { - u32 cmd; - u8 sta_addr[ETH_ALEN]; - union { - struct { - u8 name; - u32 value; - } wpa_param; - struct { - u32 len; - u8 reserved[32]; - u8 data[0]; - } wpa_ie; - struct{ - int command; - int reason_code; - } mlme; - struct { - u8 alg[IEEE_CRYPT_ALG_NAME_LEN]; - u8 set_tx; - u32 err; - u8 idx; - u8 seq[8]; /* sequence counter (set: RX, get: TX) */ - u16 key_len; - u8 key[0]; - } crypt; - } u; -}ieee_param; - - -#if WIRELESS_EXT < 17 -#define IW_QUAL_QUAL_INVALID 0x10 -#define IW_QUAL_LEVEL_INVALID 0x20 -#define IW_QUAL_NOISE_INVALID 0x40 -#define IW_QUAL_QUAL_UPDATED 0x1 -#define IW_QUAL_LEVEL_UPDATED 0x2 -#define IW_QUAL_NOISE_UPDATED 0x4 -#endif - -#define MSECS(t) msecs_to_jiffies(t) -#define msleep_interruptible_rsl msleep_interruptible - -#define IEEE80211_DATA_LEN 2304 -/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section - 6.2.1.1.2. - - The figure in section 7.1.2 suggests a body size of up to 2312 - bytes is allowed, which is a bit confusing, I suspect this - represents the 2304 bytes of real data, plus a possible 8 bytes of - WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */ -#define IEEE80211_1ADDR_LEN 10 -#define IEEE80211_2ADDR_LEN 16 -#define IEEE80211_3ADDR_LEN 24 -#define IEEE80211_4ADDR_LEN 30 -#define IEEE80211_FCS_LEN 4 -#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) -#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) -#define IEEE80211_MGMT_HDR_LEN 24 -#define IEEE80211_DATA_HDR3_LEN 24 -#define IEEE80211_DATA_HDR4_LEN 30 - -#define MIN_FRAG_THRESHOLD 256U -#define MAX_FRAG_THRESHOLD 2346U - - -/* Frame control field constants */ -#define IEEE80211_FCTL_VERS 0x0003 -#define IEEE80211_FCTL_FTYPE 0x000c -#define IEEE80211_FCTL_STYPE 0x00f0 -#define IEEE80211_FCTL_FRAMETYPE 0x00fc -#define IEEE80211_FCTL_TODS 0x0100 -#define IEEE80211_FCTL_FROMDS 0x0200 -#define IEEE80211_FCTL_DSTODS 0x0300 //added by david -#define IEEE80211_FCTL_MOREFRAGS 0x0400 -#define IEEE80211_FCTL_RETRY 0x0800 -#define IEEE80211_FCTL_PM 0x1000 -#define IEEE80211_FCTL_MOREDATA 0x2000 -#define IEEE80211_FCTL_WEP 0x4000 -#define IEEE80211_FCTL_ORDER 0x8000 - -#define IEEE80211_FTYPE_MGMT 0x0000 -#define IEEE80211_FTYPE_CTL 0x0004 -#define IEEE80211_FTYPE_DATA 0x0008 - -/* management */ -#define IEEE80211_STYPE_ASSOC_REQ 0x0000 -#define IEEE80211_STYPE_ASSOC_RESP 0x0010 -#define IEEE80211_STYPE_REASSOC_REQ 0x0020 -#define IEEE80211_STYPE_REASSOC_RESP 0x0030 -#define IEEE80211_STYPE_PROBE_REQ 0x0040 -#define IEEE80211_STYPE_PROBE_RESP 0x0050 -#define IEEE80211_STYPE_BEACON 0x0080 -#define IEEE80211_STYPE_ATIM 0x0090 -#define IEEE80211_STYPE_DISASSOC 0x00A0 -#define IEEE80211_STYPE_AUTH 0x00B0 -#define IEEE80211_STYPE_DEAUTH 0x00C0 -#define IEEE80211_STYPE_MANAGE_ACT 0x00D0 - -/* control */ -#define IEEE80211_STYPE_PSPOLL 0x00A0 -#define IEEE80211_STYPE_RTS 0x00B0 -#define IEEE80211_STYPE_CTS 0x00C0 -#define IEEE80211_STYPE_ACK 0x00D0 -#define IEEE80211_STYPE_CFEND 0x00E0 -#define IEEE80211_STYPE_CFENDACK 0x00F0 -#define IEEE80211_STYPE_BLOCKACK 0x0094 - -/* data */ -#define IEEE80211_STYPE_DATA 0x0000 -#define IEEE80211_STYPE_DATA_CFACK 0x0010 -#define IEEE80211_STYPE_DATA_CFPOLL 0x0020 -#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030 -#define IEEE80211_STYPE_NULLFUNC 0x0040 -#define IEEE80211_STYPE_CFACK 0x0050 -#define IEEE80211_STYPE_CFPOLL 0x0060 -#define IEEE80211_STYPE_CFACKPOLL 0x0070 -#define IEEE80211_STYPE_QOS_DATA 0x0080 //added for WMM 2006/8/2 -#define IEEE80211_STYPE_QOS_NULL 0x00C0 - -#define IEEE80211_SCTL_FRAG 0x000F -#define IEEE80211_SCTL_SEQ 0xFFF0 - -/* QOS control */ -#define IEEE80211_QCTL_TID 0x000F - -#define FC_QOS_BIT BIT7 -#define IsDataFrame(pdu) ( ((pdu[0] & 0x0C)==0x08) ? true : false ) -#define IsLegacyDataFrame(pdu) (IsDataFrame(pdu) && (!(pdu[0]&FC_QOS_BIT)) ) -//added by wb. Is this right? -#define IsQoSDataFrame(pframe) ((*(u16*)pframe&(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) == (IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) -#define Frame_Order(pframe) (*(u16*)pframe&IEEE80211_FCTL_ORDER) -#define SN_LESS(a, b) (((a-b)&0x800)!=0) -#define SN_EQUAL(a, b) (a == b) -#define MAX_DEV_ADDR_SIZE 8 -typedef enum _ACT_CATEGORY{ - ACT_CAT_QOS = 1, - ACT_CAT_DLS = 2, - ACT_CAT_BA = 3, - ACT_CAT_HT = 7, - ACT_CAT_WMM = 17, -} ACT_CATEGORY, *PACT_CATEGORY; - -typedef enum _TS_ACTION{ - ACT_ADDTSREQ = 0, - ACT_ADDTSRSP = 1, - ACT_DELTS = 2, - ACT_SCHEDULE = 3, -} TS_ACTION, *PTS_ACTION; - -typedef enum _BA_ACTION{ - ACT_ADDBAREQ = 0, - ACT_ADDBARSP = 1, - ACT_DELBA = 2, -} BA_ACTION, *PBA_ACTION; - -typedef enum _InitialGainOpType{ - IG_Backup=0, - IG_Restore, - IG_Max -}InitialGainOpType; - -/* debug macros */ -#define CONFIG_IEEE80211_DEBUG -#ifdef CONFIG_IEEE80211_DEBUG -extern u32 ieee80211_debug_level; -#define IEEE80211_DEBUG(level, fmt, args...) \ -do { if (ieee80211_debug_level & (level)) \ - printk(KERN_DEBUG "ieee80211: " fmt, ## args); } while (0) -//wb added to debug out data buf -//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA -#define IEEE80211_DEBUG_DATA(level, data, datalen) \ - do{ if ((ieee80211_debug_level & (level)) == (level)) \ - { \ - int i; \ - u8* pdata = (u8*) data; \ - printk(KERN_DEBUG "ieee80211: %s()\n", __FUNCTION__); \ - for(i=0; i<(int)(datalen); i++) \ - { \ - printk("%2x ", pdata[i]); \ - if ((i+1)%16 == 0) printk("\n"); \ - } \ - printk("\n"); \ - } \ - } while (0) -#else -#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0) -#define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while(0) -#endif /* CONFIG_IEEE80211_DEBUG */ - -/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */ - -/* - * To use the debug system; - * - * If you are defining a new debug classification, simply add it to the #define - * list here in the form of: - * - * #define IEEE80211_DL_xxxx VALUE - * - * shifting value to the left one bit from the previous entry. xxxx should be - * the name of the classification (for example, WEP) - * - * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your - * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want - * to send output to that classification. - * - * To add your debug level to the list of levels seen when you perform - * - * % cat /proc/net/ipw/debug_level - * - * you simply need to add your entry to the ipw_debug_levels array. - * - * If you do not see debug_level in /proc/net/ipw then you do not have - * CONFIG_IEEE80211_DEBUG defined in your kernel configuration - * - */ - -#define IEEE80211_DL_INFO (1<<0) -#define IEEE80211_DL_WX (1<<1) -#define IEEE80211_DL_SCAN (1<<2) -#define IEEE80211_DL_STATE (1<<3) -#define IEEE80211_DL_MGMT (1<<4) -#define IEEE80211_DL_FRAG (1<<5) -#define IEEE80211_DL_EAP (1<<6) -#define IEEE80211_DL_DROP (1<<7) - -#define IEEE80211_DL_TX (1<<8) -#define IEEE80211_DL_RX (1<<9) - -#define IEEE80211_DL_HT (1<<10) //HT -#define IEEE80211_DL_BA (1<<11) //ba -#define IEEE80211_DL_TS (1<<12) //TS -#define IEEE80211_DL_QOS (1<<13) -#define IEEE80211_DL_REORDER (1<<14) -#define IEEE80211_DL_IOT (1<<15) -#define IEEE80211_DL_IPS (1<<16) -#define IEEE80211_DL_TRACE (1<<29) //trace function, need to user net_ratelimit() together in order not to print too much to the screen -#define IEEE80211_DL_DATA (1<<30) //use this flag to control whether print data buf out. -#define IEEE80211_DL_ERR (1<<31) //always open -#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a) -#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a) -#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a) - -#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a) -#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a) -#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a) -#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a) -#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a) -#define IEEE80211_DEBUG_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a) -#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a) -#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a) -#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a) -#define IEEE80211_DEBUG_QOS(f, a...) IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a) - -#ifdef CONFIG_IEEE80211_DEBUG -/* Added by Annie, 2005-11-22. */ -#define MAX_STR_LEN 64 -/* I want to see ASCII 33 to 126 only. Otherwise, I print '?'. Annie, 2005-11-22.*/ -#define PRINTABLE(_ch) (_ch>'!' && _ch<'~') -#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len) \ - if((_Comp) & level) \ - { \ - int __i; \ - u8 buffer[MAX_STR_LEN]; \ - int length = (_Len\n", _Len, buffer); \ - } -#else -#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len) do {} while (0) -#endif - -#include -#include /* ARPHRD_ETHER */ - -#ifndef WIRELESS_SPY -#define WIRELESS_SPY // enable iwspy support -#endif -#include // new driver API - -#ifndef ETH_P_PAE -#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ -#endif /* ETH_P_PAE */ - -#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */ - -#ifndef ETH_P_80211_RAW -#define ETH_P_80211_RAW (ETH_P_ECONET + 1) -#endif - -/* IEEE 802.11 defines */ - -#define P80211_OUI_LEN 3 - -struct ieee80211_snap_hdr { - - u8 dsap; /* always 0xAA */ - u8 ssap; /* always 0xAA */ - u8 ctrl; /* always 0x03 */ - u8 oui[P80211_OUI_LEN]; /* organizational universal id */ - -} __attribute__ ((packed)); - -#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr) - -#define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS) -#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE) -#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE) - -#define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & IEEE80211_FCTL_FRAMETYPE) -#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG) -#define WLAN_GET_SEQ_SEQ(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) - -/* Authentication algorithms */ -#define WLAN_AUTH_OPEN 0 -#define WLAN_AUTH_SHARED_KEY 1 -#define WLAN_AUTH_LEAP 2 - -#define WLAN_AUTH_CHALLENGE_LEN 128 - -#define WLAN_CAPABILITY_BSS (1<<0) -#define WLAN_CAPABILITY_IBSS (1<<1) -#define WLAN_CAPABILITY_CF_POLLABLE (1<<2) -#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) -#define WLAN_CAPABILITY_PRIVACY (1<<4) -#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) -#define WLAN_CAPABILITY_PBCC (1<<6) -#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) -#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8) -#define WLAN_CAPABILITY_QOS (1<<9) -#define WLAN_CAPABILITY_SHORT_SLOT (1<<10) -#define WLAN_CAPABILITY_DSSS_OFDM (1<<13) - -/* 802.11g ERP information element */ -#define WLAN_ERP_NON_ERP_PRESENT (1<<0) -#define WLAN_ERP_USE_PROTECTION (1<<1) -#define WLAN_ERP_BARKER_PREAMBLE (1<<2) - -/* Status codes */ -enum ieee80211_statuscode { - WLAN_STATUS_SUCCESS = 0, - WLAN_STATUS_UNSPECIFIED_FAILURE = 1, - WLAN_STATUS_CAPS_UNSUPPORTED = 10, - WLAN_STATUS_REASSOC_NO_ASSOC = 11, - WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12, - WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13, - WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14, - WLAN_STATUS_CHALLENGE_FAIL = 15, - WLAN_STATUS_AUTH_TIMEOUT = 16, - WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17, - WLAN_STATUS_ASSOC_DENIED_RATES = 18, - /* 802.11b */ - WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19, - WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20, - WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21, - /* 802.11h */ - WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22, - WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23, - WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24, - /* 802.11g */ - WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25, - WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26, - /* 802.11i */ - WLAN_STATUS_INVALID_IE = 40, - WLAN_STATUS_INVALID_GROUP_CIPHER = 41, - WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42, - WLAN_STATUS_INVALID_AKMP = 43, - WLAN_STATUS_UNSUPP_RSN_VERSION = 44, - WLAN_STATUS_INVALID_RSN_IE_CAP = 45, - WLAN_STATUS_CIPHER_SUITE_REJECTED = 46, -}; - -/* Reason codes */ -enum ieee80211_reasoncode { - WLAN_REASON_UNSPECIFIED = 1, - WLAN_REASON_PREV_AUTH_NOT_VALID = 2, - WLAN_REASON_DEAUTH_LEAVING = 3, - WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4, - WLAN_REASON_DISASSOC_AP_BUSY = 5, - WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6, - WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7, - WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8, - WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9, - /* 802.11h */ - WLAN_REASON_DISASSOC_BAD_POWER = 10, - WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11, - /* 802.11i */ - WLAN_REASON_INVALID_IE = 13, - WLAN_REASON_MIC_FAILURE = 14, - WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, - WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16, - WLAN_REASON_IE_DIFFERENT = 17, - WLAN_REASON_INVALID_GROUP_CIPHER = 18, - WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19, - WLAN_REASON_INVALID_AKMP = 20, - WLAN_REASON_UNSUPP_RSN_VERSION = 21, - WLAN_REASON_INVALID_RSN_IE_CAP = 22, - WLAN_REASON_IEEE8021X_FAILED = 23, - WLAN_REASON_CIPHER_SUITE_REJECTED = 24, -}; - -#define IEEE80211_STATMASK_SIGNAL (1<<0) -#define IEEE80211_STATMASK_RSSI (1<<1) -#define IEEE80211_STATMASK_NOISE (1<<2) -#define IEEE80211_STATMASK_RATE (1<<3) -#define IEEE80211_STATMASK_WEMASK 0x7 - -#define IEEE80211_CCK_MODULATION (1<<0) -#define IEEE80211_OFDM_MODULATION (1<<1) - -#define IEEE80211_24GHZ_BAND (1<<0) -#define IEEE80211_52GHZ_BAND (1<<1) - -#define IEEE80211_CCK_RATE_LEN 4 -#define IEEE80211_CCK_RATE_1MB 0x02 -#define IEEE80211_CCK_RATE_2MB 0x04 -#define IEEE80211_CCK_RATE_5MB 0x0B -#define IEEE80211_CCK_RATE_11MB 0x16 -#define IEEE80211_OFDM_RATE_LEN 8 -#define IEEE80211_OFDM_RATE_6MB 0x0C -#define IEEE80211_OFDM_RATE_9MB 0x12 -#define IEEE80211_OFDM_RATE_12MB 0x18 -#define IEEE80211_OFDM_RATE_18MB 0x24 -#define IEEE80211_OFDM_RATE_24MB 0x30 -#define IEEE80211_OFDM_RATE_36MB 0x48 -#define IEEE80211_OFDM_RATE_48MB 0x60 -#define IEEE80211_OFDM_RATE_54MB 0x6C -#define IEEE80211_BASIC_RATE_MASK 0x80 - -#define IEEE80211_CCK_RATE_1MB_MASK (1<<0) -#define IEEE80211_CCK_RATE_2MB_MASK (1<<1) -#define IEEE80211_CCK_RATE_5MB_MASK (1<<2) -#define IEEE80211_CCK_RATE_11MB_MASK (1<<3) -#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4) -#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5) -#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6) -#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7) -#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8) -#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9) -#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10) -#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11) - -#define IEEE80211_CCK_RATES_MASK 0x0000000F -#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \ - IEEE80211_CCK_RATE_2MB_MASK) -#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \ - IEEE80211_CCK_RATE_5MB_MASK | \ - IEEE80211_CCK_RATE_11MB_MASK) - -#define IEEE80211_OFDM_RATES_MASK 0x00000FF0 -#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \ - IEEE80211_OFDM_RATE_12MB_MASK | \ - IEEE80211_OFDM_RATE_24MB_MASK) -#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \ - IEEE80211_OFDM_RATE_9MB_MASK | \ - IEEE80211_OFDM_RATE_18MB_MASK | \ - IEEE80211_OFDM_RATE_36MB_MASK | \ - IEEE80211_OFDM_RATE_48MB_MASK | \ - IEEE80211_OFDM_RATE_54MB_MASK) -#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \ - IEEE80211_CCK_DEFAULT_RATES_MASK) - -#define IEEE80211_NUM_OFDM_RATES 8 -#define IEEE80211_NUM_CCK_RATES 4 -#define IEEE80211_OFDM_SHIFT_MASK_A 4 - - -/* this is stolen and modified from the madwifi driver*/ -#define IEEE80211_FC0_TYPE_MASK 0x0c -#define IEEE80211_FC0_TYPE_DATA 0x08 -#define IEEE80211_FC0_SUBTYPE_MASK 0xB0 -#define IEEE80211_FC0_SUBTYPE_QOS 0x80 - -#define IEEE80211_QOS_HAS_SEQ(fc) \ - (((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \ - (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS)) - -/* this is stolen from ipw2200 driver */ -#define IEEE_IBSS_MAC_HASH_SIZE 31 -struct ieee_ibss_seq { - u8 mac[ETH_ALEN]; - u16 seq_num[17]; - u16 frag_num[17]; - unsigned long packet_time[17]; - struct list_head list; -}; - -/* NOTE: This data is for statistical purposes; not all hardware provides this - * information for frames received. Not setting these will not cause - * any adverse affects. */ -struct ieee80211_rx_stats { -#if 1 - u32 mac_time[2]; - s8 rssi; - u8 signal; - u8 noise; - u16 rate; /* in 100 kbps */ - u8 received_channel; - u8 control; - u8 mask; - u8 freq; - u16 len; - u64 tsf; - u32 beacon_time; - u16 Length; - // u8 DataRate; // In 0.5 Mbps - u8 SignalQuality; // in 0-100 index. - s32 RecvSignalPower; // Real power in dBm for this packet, no beautification and aggregation. - s8 RxPower; // in dBm Translate from PWdB - u8 SignalStrength; // in 0-100 index. - u16 bHwError:1; - u16 bCRC:1; - u16 bICV:1; - u16 bShortPreamble:1; - u16 Antenna:1; //for rtl8185 - u16 Decrypted:1; //for rtl8185, rtl8187 - u16 Wakeup:1; //for rtl8185 - u16 Reserved0:1; //for rtl8185 - u8 AGC; - u32 TimeStampLow; - u32 TimeStampHigh; - bool bShift; - bool bIsQosData; // Added by Annie, 2005-12-22. - u8 UserPriority; - - //1!!!!!!!!!!!!!!!!!!!!!!!!!!! - //1Attention Please!!!<11n or 8190 specific code should be put below this line> - //1!!!!!!!!!!!!!!!!!!!!!!!!!!! - - u8 RxDrvInfoSize; - u8 RxBufShift; - bool bIsAMPDU; - bool bFirstMPDU; - bool bContainHTC; - bool RxIs40MHzPacket; - u32 RxPWDBAll; - u8 RxMIMOSignalStrength[4]; // in 0~100 index - s8 RxMIMOSignalQuality[2]; - bool bPacketMatchBSSID; - bool bIsCCK; - bool bPacketToSelf; - //added by amy - u8* virtual_address; - u16 packetlength; // Total packet length: Must equal to sum of all FragLength - u16 fraglength; // FragLength should equal to PacketLength in non-fragment case - u16 fragoffset; // Data offset for this fragment - u16 ntotalfrag; - bool bisrxaggrsubframe; - bool bPacketBeacon; //cosa add for rssi - bool bToSelfBA; //cosa add for rssi - char cck_adc_pwdb[4]; //cosa add for rx path selection - u16 Seq_Num; -#endif - -}; - -/* IEEE 802.11 requires that STA supports concurrent reception of at least - * three fragmented frames. This define can be increased to support more - * concurrent frames, but it should be noted that each entry can consume about - * 2 kB of RAM and increasing cache size will slow down frame reassembly. */ -#define IEEE80211_FRAG_CACHE_LEN 4 - -struct ieee80211_frag_entry { - unsigned long first_frag_time; - unsigned int seq; - unsigned int last_frag; - struct sk_buff *skb; - u8 src_addr[ETH_ALEN]; - u8 dst_addr[ETH_ALEN]; -}; - -struct ieee80211_stats { - unsigned int tx_unicast_frames; - unsigned int tx_multicast_frames; - unsigned int tx_fragments; - unsigned int tx_unicast_octets; - unsigned int tx_multicast_octets; - unsigned int tx_deferred_transmissions; - unsigned int tx_single_retry_frames; - unsigned int tx_multiple_retry_frames; - unsigned int tx_retry_limit_exceeded; - unsigned int tx_discards; - unsigned int rx_unicast_frames; - unsigned int rx_multicast_frames; - unsigned int rx_fragments; - unsigned int rx_unicast_octets; - unsigned int rx_multicast_octets; - unsigned int rx_fcs_errors; - unsigned int rx_discards_no_buffer; - unsigned int tx_discards_wrong_sa; - unsigned int rx_discards_undecryptable; - unsigned int rx_message_in_msg_fragments; - unsigned int rx_message_in_bad_msg_fragments; -}; - -struct ieee80211_device; - -#include "ieee80211_crypt.h" - -#define SEC_KEY_1 (1<<0) -#define SEC_KEY_2 (1<<1) -#define SEC_KEY_3 (1<<2) -#define SEC_KEY_4 (1<<3) -#define SEC_ACTIVE_KEY (1<<4) -#define SEC_AUTH_MODE (1<<5) -#define SEC_UNICAST_GROUP (1<<6) -#define SEC_LEVEL (1<<7) -#define SEC_ENABLED (1<<8) -#define SEC_ENCRYPT (1<<9) - -#define SEC_LEVEL_0 0 /* None */ -#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */ -#define SEC_LEVEL_2 2 /* Level 1 + TKIP */ -#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */ -#define SEC_LEVEL_3 4 /* Level 2 + CCMP */ - -#define SEC_ALG_NONE 0 -#define SEC_ALG_WEP 1 -#define SEC_ALG_TKIP 2 -#define SEC_ALG_CCMP 3 - -#define WEP_KEYS 4 -#define WEP_KEY_LEN 13 -#define SCM_KEY_LEN 32 -#define SCM_TEMPORAL_KEY_LENGTH 16 - -struct ieee80211_security { - u16 active_key:2, - enabled:1, - auth_mode:2, - auth_algo:4, - unicast_uses_group:1, - encrypt:1; - u8 key_sizes[WEP_KEYS]; - u8 keys[WEP_KEYS][SCM_KEY_LEN]; - u8 level; - u16 flags; -} __attribute__ ((packed)); - - -/* - 802.11 data frame from AP - ,-------------------------------------------------------------------. -Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | - |------|------|---------|---------|---------|------|---------|------| -Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs | - | | tion | (BSSID) | | | ence | data | | - `-------------------------------------------------------------------' -Total: 28-2340 bytes -*/ - -/* Management Frame Information Element Types */ -enum ieee80211_mfie { - MFIE_TYPE_SSID = 0, - MFIE_TYPE_RATES = 1, - MFIE_TYPE_FH_SET = 2, - MFIE_TYPE_DS_SET = 3, - MFIE_TYPE_CF_SET = 4, - MFIE_TYPE_TIM = 5, - MFIE_TYPE_IBSS_SET = 6, - MFIE_TYPE_COUNTRY = 7, - MFIE_TYPE_HOP_PARAMS = 8, - MFIE_TYPE_HOP_TABLE = 9, - MFIE_TYPE_REQUEST = 10, - MFIE_TYPE_CHALLENGE = 16, - MFIE_TYPE_POWER_CONSTRAINT = 32, - MFIE_TYPE_POWER_CAPABILITY = 33, - MFIE_TYPE_TPC_REQUEST = 34, - MFIE_TYPE_TPC_REPORT = 35, - MFIE_TYPE_SUPP_CHANNELS = 36, - MFIE_TYPE_CSA = 37, - MFIE_TYPE_MEASURE_REQUEST = 38, - MFIE_TYPE_MEASURE_REPORT = 39, - MFIE_TYPE_QUIET = 40, - MFIE_TYPE_IBSS_DFS = 41, - MFIE_TYPE_ERP = 42, - MFIE_TYPE_RSN = 48, - MFIE_TYPE_RATES_EX = 50, - MFIE_TYPE_HT_CAP= 45, - MFIE_TYPE_HT_INFO= 61, - MFIE_TYPE_AIRONET=133, - MFIE_TYPE_GENERIC = 221, - MFIE_TYPE_QOS_PARAMETER = 222, -}; - -/* Minimal header; can be used for passing 802.11 frames with sufficient - * information to determine what type of underlying data type is actually - * stored in the data. */ -struct ieee80211_hdr { - __le16 frame_ctl; - __le16 duration_id; - u8 payload[0]; -} __attribute__ ((packed)); - -struct ieee80211_hdr_1addr { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 payload[0]; -} __attribute__ ((packed)); - -struct ieee80211_hdr_2addr { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 payload[0]; -} __attribute__ ((packed)); - -struct ieee80211_hdr_3addr { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctl; - u8 payload[0]; -} __attribute__ ((packed)); - -struct ieee80211_hdr_4addr { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctl; - u8 addr4[ETH_ALEN]; - u8 payload[0]; -} __attribute__ ((packed)); - -struct ieee80211_hdr_3addrqos { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctl; - u8 payload[0]; - __le16 qos_ctl; -} __attribute__ ((packed)); - -struct ieee80211_hdr_4addrqos { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctl; - u8 addr4[ETH_ALEN]; - u8 payload[0]; - __le16 qos_ctl; -} __attribute__ ((packed)); - -struct ieee80211_info_element { - u8 id; - u8 len; - u8 data[0]; -} __attribute__ ((packed)); - -struct ieee80211_authentication { - struct ieee80211_hdr_3addr header; - __le16 algorithm; - __le16 transaction; - __le16 status; - /*challenge*/ - struct ieee80211_info_element info_element[0]; -} __attribute__ ((packed)); - -struct ieee80211_disassoc { - struct ieee80211_hdr_3addr header; - __le16 reason; -} __attribute__ ((packed)); - -struct ieee80211_probe_request { - struct ieee80211_hdr_3addr header; - /* SSID, supported rates */ - struct ieee80211_info_element info_element[0]; -} __attribute__ ((packed)); - -struct ieee80211_probe_response { - struct ieee80211_hdr_3addr header; - u32 time_stamp[2]; - __le16 beacon_interval; - __le16 capability; - /* SSID, supported rates, FH params, DS params, - * CF params, IBSS params, TIM (if beacon), RSN */ - struct ieee80211_info_element info_element[0]; -} __attribute__ ((packed)); - -/* Alias beacon for probe_response */ -#define ieee80211_beacon ieee80211_probe_response - -struct ieee80211_assoc_request_frame { - struct ieee80211_hdr_3addr header; - __le16 capability; - __le16 listen_interval; - /* SSID, supported rates, RSN */ - struct ieee80211_info_element info_element[0]; -} __attribute__ ((packed)); - -struct ieee80211_reassoc_request_frame { - struct ieee80211_hdr_3addr header; - __le16 capability; - __le16 listen_interval; - u8 current_ap[ETH_ALEN]; - /* SSID, supported rates, RSN */ - struct ieee80211_info_element info_element[0]; -} __attribute__ ((packed)); - -struct ieee80211_assoc_response_frame { - struct ieee80211_hdr_3addr header; - __le16 capability; - __le16 status; - __le16 aid; - struct ieee80211_info_element info_element[0]; /* supported rates */ -} __attribute__ ((packed)); - -struct ieee80211_txb { - u8 nr_frags; - u8 encrypted; - u8 queue_index; - u8 rts_included; - u16 reserved; - __le16 frag_size; - __le16 payload_size; - struct sk_buff *fragments[0]; -}; - -#define MAX_TX_AGG_COUNT 16 -struct ieee80211_drv_agg_txb { - u8 nr_drv_agg_frames; - struct sk_buff *tx_agg_frames[MAX_TX_AGG_COUNT]; -}__attribute__((packed)); - -#define MAX_SUBFRAME_COUNT 64 -struct ieee80211_rxb { - u8 nr_subframes; - struct sk_buff *subframes[MAX_SUBFRAME_COUNT]; - u8 dst[ETH_ALEN]; - u8 src[ETH_ALEN]; -}__attribute__((packed)); - -typedef union _frameqos { - u16 shortdata; - u8 chardata[2]; - struct { - u16 tid:4; - u16 eosp:1; - u16 ack_policy:2; - u16 reserved:1; - u16 txop:8; - }field; -}frameqos,*pframeqos; - -/* SWEEP TABLE ENTRIES NUMBER*/ -#define MAX_SWEEP_TAB_ENTRIES 42 -#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7 -/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs - * only use 8, and then use extended rates for the remaining supported - * rates. Other APs, however, stick all of their supported rates on the - * main rates information element... */ -#define MAX_RATES_LENGTH ((u8)12) -#define MAX_RATES_EX_LENGTH ((u8)16) -#define MAX_NETWORK_COUNT 128 - -#define MAX_CHANNEL_NUMBER 161 -#define IEEE80211_SOFTMAC_SCAN_TIME 100 -//(HZ / 2) -#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2) - -#define CRC_LENGTH 4U - -#define MAX_WPA_IE_LEN 64 - -#define NETWORK_EMPTY_ESSID (1<<0) -#define NETWORK_HAS_OFDM (1<<1) -#define NETWORK_HAS_CCK (1<<2) - -/* QoS structure */ -#define NETWORK_HAS_QOS_PARAMETERS (1<<3) -#define NETWORK_HAS_QOS_INFORMATION (1<<4) -#define NETWORK_HAS_QOS_MASK (NETWORK_HAS_QOS_PARAMETERS | \ - NETWORK_HAS_QOS_INFORMATION) -/* 802.11h */ -#define NETWORK_HAS_POWER_CONSTRAINT (1<<5) -#define NETWORK_HAS_CSA (1<<6) -#define NETWORK_HAS_QUIET (1<<7) -#define NETWORK_HAS_IBSS_DFS (1<<8) -#define NETWORK_HAS_TPC_REPORT (1<<9) - -#define NETWORK_HAS_ERP_VALUE (1<<10) - -#define QOS_QUEUE_NUM 4 -#define QOS_OUI_LEN 3 -#define QOS_OUI_TYPE 2 -#define QOS_ELEMENT_ID 221 -#define QOS_OUI_INFO_SUB_TYPE 0 -#define QOS_OUI_PARAM_SUB_TYPE 1 -#define QOS_VERSION_1 1 -#define QOS_AIFSN_MIN_VALUE 2 -#if 1 -struct ieee80211_qos_information_element { - u8 elementID; - u8 length; - u8 qui[QOS_OUI_LEN]; - u8 qui_type; - u8 qui_subtype; - u8 version; - u8 ac_info; -} __attribute__ ((packed)); - -struct ieee80211_qos_ac_parameter { - u8 aci_aifsn; - u8 ecw_min_max; - __le16 tx_op_limit; -} __attribute__ ((packed)); - -struct ieee80211_qos_parameter_info { - struct ieee80211_qos_information_element info_element; - u8 reserved; - struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM]; -} __attribute__ ((packed)); - -struct ieee80211_qos_parameters { - __le16 cw_min[QOS_QUEUE_NUM]; - __le16 cw_max[QOS_QUEUE_NUM]; - u8 aifs[QOS_QUEUE_NUM]; - u8 flag[QOS_QUEUE_NUM]; - __le16 tx_op_limit[QOS_QUEUE_NUM]; -} __attribute__ ((packed)); - -struct ieee80211_qos_data { - struct ieee80211_qos_parameters parameters; - int active; - int supported; - u8 param_count; - u8 old_param_count; -}; - -struct ieee80211_tim_parameters { - u8 tim_count; - u8 tim_period; -} __attribute__ ((packed)); - -//#else -struct ieee80211_wmm_ac_param { - u8 ac_aci_acm_aifsn; - u8 ac_ecwmin_ecwmax; - u16 ac_txop_limit; -}; - -struct ieee80211_wmm_ts_info { - u8 ac_dir_tid; - u8 ac_up_psb; - u8 reserved; -} __attribute__ ((packed)); - -struct ieee80211_wmm_tspec_elem { - struct ieee80211_wmm_ts_info ts_info; - u16 norm_msdu_size; - u16 max_msdu_size; - u32 min_serv_inter; - u32 max_serv_inter; - u32 inact_inter; - u32 suspen_inter; - u32 serv_start_time; - u32 min_data_rate; - u32 mean_data_rate; - u32 peak_data_rate; - u32 max_burst_size; - u32 delay_bound; - u32 min_phy_rate; - u16 surp_band_allow; - u16 medium_time; -}__attribute__((packed)); -#endif -enum eap_type { - EAP_PACKET = 0, - EAPOL_START, - EAPOL_LOGOFF, - EAPOL_KEY, - EAPOL_ENCAP_ASF_ALERT -}; - -static const char *eap_types[] = { - [EAP_PACKET] = "EAP-Packet", - [EAPOL_START] = "EAPOL-Start", - [EAPOL_LOGOFF] = "EAPOL-Logoff", - [EAPOL_KEY] = "EAPOL-Key", - [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert" -}; - -static inline const char *eap_get_type(int type) -{ - return ((u32)type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type]; -} -//added by amy for reorder -static inline u8 Frame_QoSTID(u8* buf) -{ - struct ieee80211_hdr_3addr *hdr; - u16 fc; - hdr = (struct ieee80211_hdr_3addr *)buf; - fc = le16_to_cpu(hdr->frame_ctl); - return (u8)((frameqos*)(buf + (((fc & IEEE80211_FCTL_TODS)&&(fc & IEEE80211_FCTL_FROMDS))? 30 : 24)))->field.tid; -} - -//added by amy for reorder - -struct eapol { - u8 snap[6]; - u16 ethertype; - u8 version; - u8 type; - u16 length; -} __attribute__ ((packed)); - -struct ieee80211_softmac_stats{ - unsigned int rx_ass_ok; - unsigned int rx_ass_err; - unsigned int rx_probe_rq; - unsigned int tx_probe_rs; - unsigned int tx_beacons; - unsigned int rx_auth_rq; - unsigned int rx_auth_rs_ok; - unsigned int rx_auth_rs_err; - unsigned int tx_auth_rq; - unsigned int no_auth_rs; - unsigned int no_ass_rs; - unsigned int tx_ass_rq; - unsigned int rx_ass_rq; - unsigned int tx_probe_rq; - unsigned int reassoc; - unsigned int swtxstop; - unsigned int swtxawake; - unsigned char CurrentShowTxate; - unsigned char last_packet_rate; - unsigned int txretrycount; -}; - -#define BEACON_PROBE_SSID_ID_POSITION 12 - -struct ieee80211_info_element_hdr { - u8 id; - u8 len; -} __attribute__ ((packed)); - -/* - * These are the data types that can make up management packets - * - u16 auth_algorithm; - u16 auth_sequence; - u16 beacon_interval; - u16 capability; - u8 current_ap[ETH_ALEN]; - u16 listen_interval; - struct { - u16 association_id:14, reserved:2; - } __attribute__ ((packed)); - u32 time_stamp[2]; - u16 reason; - u16 status; -*/ - -#define IEEE80211_DEFAULT_TX_ESSID "Penguin" -#define IEEE80211_DEFAULT_BASIC_RATE 2 //1Mbps - -enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame}; -#define MAX_SP_Len (WMM_all_frame << 4) -#define IEEE80211_QOS_TID 0x0f -#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5) - -#define IEEE80211_DTIM_MBCAST 4 -#define IEEE80211_DTIM_UCAST 2 -#define IEEE80211_DTIM_VALID 1 -#define IEEE80211_DTIM_INVALID 0 - -#define IEEE80211_PS_DISABLED 0 -#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST -#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST - -//added by David for QoS 2006/6/30 -//#define WMM_Hang_8187 -#ifdef WMM_Hang_8187 -#undef WMM_Hang_8187 -#endif - -#define WME_AC_BK 0x00 -#define WME_AC_BE 0x01 -#define WME_AC_VI 0x02 -#define WME_AC_VO 0x03 -#define WME_ACI_MASK 0x03 -#define WME_AIFSN_MASK 0x03 -#define WME_AC_PRAM_LEN 16 - -#define MAX_RECEIVE_BUFFER_SIZE 9100 - -//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP -//#define UP2AC(up) ((up<3) ? ((up==0)?1:0) : (up>>1)) -#if 1 -#define UP2AC(up) ( \ - ((up) < 1) ? WME_AC_BE : \ - ((up) < 3) ? WME_AC_BK : \ - ((up) < 4) ? WME_AC_BE : \ - ((up) < 6) ? WME_AC_VI : \ - WME_AC_VO) -#endif -//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue -#define AC2UP(_ac) ( \ - ((_ac) == WME_AC_VO) ? 6 : \ - ((_ac) == WME_AC_VI) ? 5 : \ - ((_ac) == WME_AC_BK) ? 1 : \ - 0) - -#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */ -#define ETHERNET_HEADER_SIZE 14 /* length of two Ethernet address plus ether type*/ - -struct ether_header { - u8 ether_dhost[ETHER_ADDR_LEN]; - u8 ether_shost[ETHER_ADDR_LEN]; - u16 ether_type; -} __attribute__((packed)); - -#ifndef ETHERTYPE_PAE -#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */ -#endif -#ifndef ETHERTYPE_IP -#define ETHERTYPE_IP 0x0800 /* IP protocol */ -#endif - -typedef struct _bss_ht{ - - bool support_ht; - - // HT related elements - u8 ht_cap_buf[32]; - u16 ht_cap_len; - u8 ht_info_buf[32]; - u16 ht_info_len; - - HT_SPEC_VER ht_spec_ver; - //HT_CAPABILITY_ELE bdHTCapEle; - //HT_INFORMATION_ELE bdHTInfoEle; - - bool aggregation; - bool long_slot_time; -}bss_ht, *pbss_ht; - -typedef enum _erp_t{ - ERP_NonERPpresent = 0x01, - ERP_UseProtection = 0x02, - ERP_BarkerPreambleMode = 0x04, -} erp_t; - - -struct ieee80211_network { - /* These entries are used to identify a unique network */ - u8 bssid[ETH_ALEN]; - u8 channel; - /* Ensure null-terminated for any debug msgs */ - u8 ssid[IW_ESSID_MAX_SIZE + 1]; - u8 ssid_len; -#if 1 - struct ieee80211_qos_data qos_data; -#else - // Qos related. Added by Annie, 2005-11-01. - BSS_QOS BssQos; -#endif - - //added by amy for LEAP - bool bWithAironetIE; - bool bCkipSupported; - bool bCcxRmEnable; - u16 CcxRmState[2]; - // CCXv4 S59, MBSSID. - bool bMBssidValid; - u8 MBssidMask; - u8 MBssid[6]; - // CCX 2 S38, WLAN Device Version Number element. Annie, 2006-08-20. - bool bWithCcxVerNum; - u8 BssCcxVerNumber; - /* These are network statistics */ - struct ieee80211_rx_stats stats; - u16 capability; - u8 rates[MAX_RATES_LENGTH]; - u8 rates_len; - u8 rates_ex[MAX_RATES_EX_LENGTH]; - u8 rates_ex_len; - unsigned long last_scanned; - u8 mode; - u32 flags; - u32 last_associate; - u32 time_stamp[2]; - u16 beacon_interval; - u16 listen_interval; - u16 atim_window; - u8 erp_value; - u8 wpa_ie[MAX_WPA_IE_LEN]; - size_t wpa_ie_len; - u8 rsn_ie[MAX_WPA_IE_LEN]; - size_t rsn_ie_len; - - struct ieee80211_tim_parameters tim; - u8 dtim_period; - u8 dtim_data; - u32 last_dtim_sta_time[2]; - - //appeded for QoS - u8 wmm_info; - struct ieee80211_wmm_ac_param wmm_param[4]; - u8 QoS_Enable; -#ifdef THOMAS_TURBO - u8 Turbo_Enable;//enable turbo mode, added by thomas -#endif -#ifdef ENABLE_DOT11D - u16 CountryIeLen; - u8 CountryIeBuf[MAX_IE_LEN]; -#endif - // HT Related, by amy, 2008.04.29 - BSS_HT bssht; - // Add to handle broadcom AP management frame CCK rate. - bool broadcom_cap_exist; - bool ralink_cap_exist; - bool atheros_cap_exist; - bool cisco_cap_exist; - bool unknown_cap_exist; -// u8 berp_info; - bool berp_info_valid; - bool buseprotection; - //put at the end of the structure. - struct list_head list; -}; - -#if 1 -enum ieee80211_state { - - /* the card is not linked at all */ - IEEE80211_NOLINK = 0, - - /* IEEE80211_ASSOCIATING* are for BSS client mode - * the driver shall not perform RX filtering unless - * the state is LINKED. - * The driver shall just check for the state LINKED and - * defaults to NOLINK for ALL the other states (including - * LINKED_SCANNING) - */ - - /* the association procedure will start (wq scheduling)*/ - IEEE80211_ASSOCIATING, - IEEE80211_ASSOCIATING_RETRY, - - /* the association procedure is sending AUTH request*/ - IEEE80211_ASSOCIATING_AUTHENTICATING, - - /* the association procedure has successfully authentcated - * and is sending association request - */ - IEEE80211_ASSOCIATING_AUTHENTICATED, - - /* the link is ok. the card associated to a BSS or linked - * to a ibss cell or acting as an AP and creating the bss - */ - IEEE80211_LINKED, - - /* same as LINKED, but the driver shall apply RX filter - * rules as we are in NO_LINK mode. As the card is still - * logically linked, but it is doing a syncro site survey - * then it will be back to LINKED state. - */ - IEEE80211_LINKED_SCANNING, - -}; -#else -enum ieee80211_state { - IEEE80211_UNINITIALIZED = 0, - IEEE80211_INITIALIZED, - IEEE80211_ASSOCIATING, - IEEE80211_ASSOCIATED, - IEEE80211_AUTHENTICATING, - IEEE80211_AUTHENTICATED, - IEEE80211_SHUTDOWN -}; -#endif - -#define DEFAULT_MAX_SCAN_AGE (15 * HZ) -#define DEFAULT_FTS 2346 - -#define CFG_IEEE80211_RESERVE_FCS (1<<0) -#define CFG_IEEE80211_COMPUTE_FCS (1<<1) -#define CFG_IEEE80211_RTS (1<<2) - -#define IEEE80211_24GHZ_MIN_CHANNEL 1 -#define IEEE80211_24GHZ_MAX_CHANNEL 14 -#define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \ - IEEE80211_24GHZ_MIN_CHANNEL + 1) - -#define IEEE80211_52GHZ_MIN_CHANNEL 34 -#define IEEE80211_52GHZ_MAX_CHANNEL 165 -#define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \ - IEEE80211_52GHZ_MIN_CHANNEL + 1) - -typedef struct tx_pending_t{ - int frag; - struct ieee80211_txb *txb; -}tx_pending_t; - -typedef struct _bandwidth_autoswitch -{ - long threshold_20Mhzto40Mhz; - long threshold_40Mhzto20Mhz; - bool bforced_tx20Mhz; - bool bautoswitch_enable; -}bandwidth_autoswitch,*pbandwidth_autoswitch; - - -//added by amy for order - -#define REORDER_WIN_SIZE 128 -#define REORDER_ENTRY_NUM 128 -typedef struct _RX_REORDER_ENTRY -{ - struct list_head List; - u16 SeqNum; - struct ieee80211_rxb* prxb; -} RX_REORDER_ENTRY, *PRX_REORDER_ENTRY; -//added by amy for order -typedef enum _Fsync_State{ - Default_Fsync, - HW_Fsync, - SW_Fsync -}Fsync_State; - -// Power save mode configured. -typedef enum _RT_PS_MODE -{ - eActive, // Active/Continuous access. - eMaxPs, // Max power save mode. - eFastPs // Fast power save mode. -}RT_PS_MODE; - -typedef enum _IPS_CALLBACK_FUNCION -{ - IPS_CALLBACK_NONE = 0, - IPS_CALLBACK_MGNT_LINK_REQUEST = 1, - IPS_CALLBACK_JOIN_REQUEST = 2, -}IPS_CALLBACK_FUNCION; - -typedef enum _RT_JOIN_ACTION{ - RT_JOIN_INFRA = 1, - RT_JOIN_IBSS = 2, - RT_START_IBSS = 3, - RT_NO_ACTION = 4, -}RT_JOIN_ACTION; - -typedef struct _IbssParms{ - u16 atimWin; -}IbssParms, *PIbssParms; -#define MAX_NUM_RATES 264 // Max num of support rates element: 8, Max num of ext. support rate: 255. 061122, by rcnjko. - -// RF state. -typedef enum _RT_RF_POWER_STATE -{ - eRfOn, - eRfSleep, - eRfOff -}RT_RF_POWER_STATE; - -typedef struct _RT_POWER_SAVE_CONTROL -{ - - // - // Inactive Power Save(IPS) : Disable RF when disconnected - // - bool bInactivePs; - bool bIPSModeBackup; - bool bSwRfProcessing; - RT_RF_POWER_STATE eInactivePowerState; - struct work_struct InactivePsWorkItem; - struct timer_list InactivePsTimer; - - // Return point for join action - IPS_CALLBACK_FUNCION ReturnPoint; - - // Recored Parameters for rescheduled JoinRequest - bool bTmpBssDesc; - RT_JOIN_ACTION tmpJoinAction; - struct ieee80211_network tmpBssDesc; - - // Recored Parameters for rescheduled MgntLinkRequest - bool bTmpScanOnly; - bool bTmpActiveScan; - bool bTmpFilterHiddenAP; - bool bTmpUpdateParms; - u8 tmpSsidBuf[33]; - OCTET_STRING tmpSsid2Scan; - bool bTmpSsid2Scan; - u8 tmpNetworkType; - u8 tmpChannelNumber; - u16 tmpBcnPeriod; - u8 tmpDtimPeriod; - u16 tmpmCap; - OCTET_STRING tmpSuppRateSet; - u8 tmpSuppRateBuf[MAX_NUM_RATES]; - bool bTmpSuppRate; - IbssParms tmpIbpm; - bool bTmpIbpm; - - // - // Leisre Poswer Save : Disable RF if connected but traffic is not busy - // - bool bLeisurePs; - -}RT_POWER_SAVE_CONTROL,*PRT_POWER_SAVE_CONTROL; - -typedef u32 RT_RF_CHANGE_SOURCE; -#define RF_CHANGE_BY_SW BIT31 -#define RF_CHANGE_BY_HW BIT30 -#define RF_CHANGE_BY_PS BIT29 -#define RF_CHANGE_BY_IPS BIT28 -#define RF_CHANGE_BY_INIT 0 // Do not change the RFOff reason. Defined by Bruce, 2008-01-17. - -#ifdef ENABLE_DOT11D -typedef enum -{ - COUNTRY_CODE_FCC = 0, - COUNTRY_CODE_IC = 1, - COUNTRY_CODE_ETSI = 2, - COUNTRY_CODE_SPAIN = 3, - COUNTRY_CODE_FRANCE = 4, - COUNTRY_CODE_MKK = 5, - COUNTRY_CODE_MKK1 = 6, - COUNTRY_CODE_ISRAEL = 7, - COUNTRY_CODE_TELEC, - COUNTRY_CODE_MIC, - COUNTRY_CODE_GLOBAL_DOMAIN -}country_code_type_t; -#endif - -#define RT_MAX_LD_SLOT_NUM 10 -typedef struct _RT_LINK_DETECT_T{ - - u32 NumRecvBcnInPeriod; - u32 NumRecvDataInPeriod; - - u32 RxBcnNum[RT_MAX_LD_SLOT_NUM]; // number of Rx beacon / CheckForHang_period to determine link status - u32 RxDataNum[RT_MAX_LD_SLOT_NUM]; // number of Rx data / CheckForHang_period to determine link status - u16 SlotNum; // number of CheckForHang period to determine link status - u16 SlotIndex; - - u32 NumTxOkInPeriod; - u32 NumRxOkInPeriod; - bool bBusyTraffic; -}RT_LINK_DETECT_T, *PRT_LINK_DETECT_T; - - -struct ieee80211_device { - struct net_device *dev; - struct ieee80211_security sec; - - //hw security related -// u8 hwsec_support; //support? - u8 hwsec_active; //hw security active. - bool is_silent_reset; - bool is_roaming; - bool ieee_up; - //added by amy - bool bSupportRemoteWakeUp; - RT_PS_MODE dot11PowerSaveMode; // Power save mode configured. - bool actscanning; - bool beinretry; - RT_RF_POWER_STATE eRFPowerState; - RT_RF_CHANGE_SOURCE RfOffReason; - bool is_set_key; - //11n spec related I wonder if These info structure need to be moved out of ieee80211_device - - //11n HT below - PRT_HIGH_THROUGHPUT pHTInfo; - //struct timer_list SwBwTimer; -// spinlock_t chnlop_spinlock; - spinlock_t bw_spinlock; - - spinlock_t reorder_spinlock; - // for HT operation rate set. we use this one for HT data rate to separate different descriptors - //the way fill this is the same as in the IE - u8 Regdot11HTOperationalRateSet[16]; //use RATR format - u8 dot11HTOperationalRateSet[16]; //use RATR format - u8 RegHTSuppRateSet[16]; - u8 HTCurrentOperaRate; - u8 HTHighestOperaRate; - //wb added for rate operation mode to firmware - u8 bTxDisableRateFallBack; - u8 bTxUseDriverAssingedRate; - atomic_t atm_chnlop; - atomic_t atm_swbw; -// u8 HTHighestOperaRate; -// u8 HTCurrentOperaRate; - - // 802.11e and WMM Traffic Stream Info (TX) - struct list_head Tx_TS_Admit_List; - struct list_head Tx_TS_Pending_List; - struct list_head Tx_TS_Unused_List; - TX_TS_RECORD TxTsRecord[TOTAL_TS_NUM]; - // 802.11e and WMM Traffic Stream Info (RX) - struct list_head Rx_TS_Admit_List; - struct list_head Rx_TS_Pending_List; - struct list_head Rx_TS_Unused_List; - RX_TS_RECORD RxTsRecord[TOTAL_TS_NUM]; -//#ifdef TO_DO_LIST - RX_REORDER_ENTRY RxReorderEntry[128]; - struct list_head RxReorder_Unused_List; -//#endif - // Qos related. Added by Annie, 2005-11-01. -// PSTA_QOS pStaQos; - u8 ForcedPriority; // Force per-packet priority 1~7. (default: 0, not to force it.) - - - /* Bookkeeping structures */ - struct net_device_stats stats; - struct ieee80211_stats ieee_stats; - struct ieee80211_softmac_stats softmac_stats; - - /* Probe / Beacon management */ - struct list_head network_free_list; - struct list_head network_list; - struct ieee80211_network *networks; - int scans; - int scan_age; - - int iw_mode; /* operating mode (IW_MODE_*) */ - struct iw_spy_data spy_data; - - spinlock_t lock; - spinlock_t wpax_suitlist_lock; - - int tx_headroom; /* Set to size of any additional room needed at front - * of allocated Tx SKBs */ - u32 config; - - /* WEP and other encryption related settings at the device level */ - int open_wep; /* Set to 1 to allow unencrypted frames */ - int auth_mode; - int reset_on_keychange; /* Set to 1 if the HW needs to be reset on - * WEP key changes */ - - /* If the host performs {en,de}cryption, then set to 1 */ - int host_encrypt; - int host_encrypt_msdu; - int host_decrypt; - /* host performs multicast decryption */ - int host_mc_decrypt; - - /* host should strip IV and ICV from protected frames */ - /* meaningful only when hardware decryption is being used */ - int host_strip_iv_icv; - - int host_open_frag; - int host_build_iv; - int ieee802_1x; /* is IEEE 802.1X used */ - - /* WPA data */ - bool bHalfWirelessN24GMode; - int wpa_enabled; - int drop_unencrypted; - int tkip_countermeasures; - int privacy_invoked; - size_t wpa_ie_len; - u8 *wpa_ie; - u8 ap_mac_addr[6]; - u16 pairwise_key_type; - u16 group_key_type; - struct list_head crypt_deinit_list; - struct ieee80211_crypt_data *crypt[WEP_KEYS]; - int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */ - struct timer_list crypt_deinit_timer; - int crypt_quiesced; - - int bcrx_sta_key; /* use individual keys to override default keys even - * with RX of broad/multicast frames */ - - /* Fragmentation structures */ - // each streaming contain a entry - struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN]; - unsigned int frag_next_idx[17]; - u16 fts; /* Fragmentation Threshold */ -#define DEFAULT_RTS_THRESHOLD 2346U -#define MIN_RTS_THRESHOLD 1 -#define MAX_RTS_THRESHOLD 2346U - u16 rts; /* RTS threshold */ - - /* Association info */ - u8 bssid[ETH_ALEN]; - - /* This stores infos for the current network. - * Either the network we are associated in INFRASTRUCTURE - * or the network that we are creating in MASTER mode. - * ad-hoc is a mixture ;-). - * Note that in infrastructure mode, even when not associated, - * fields bssid and essid may be valid (if wpa_set and essid_set - * are true) as thy carry the value set by the user via iwconfig - */ - struct ieee80211_network current_network; - - enum ieee80211_state state; - - int short_slot; - int reg_mode; - int mode; /* A, B, G */ - int modulation; /* CCK, OFDM */ - int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */ - int abg_true; /* ABG flag */ - - /* used for forcing the ibss workqueue to terminate - * without wait for the syncro scan to terminate - */ - short sync_scan_hurryup; - - int perfect_rssi; - int worst_rssi; - - u16 prev_seq_ctl; /* used to drop duplicate frames */ - - /* map of allowed channels. 0 is dummy */ - // FIXME: remeber to default to a basic channel plan depending of the PHY type -#ifdef ENABLE_DOT11D - void* pDot11dInfo; - bool bGlobalDomain; -#else - int channel_map[MAX_CHANNEL_NUMBER+1]; -#endif - int rate; /* current rate */ - int basic_rate; - //FIXME: pleace callback, see if redundant with softmac_features - short active_scan; - - /* this contains flags for selectively enable softmac support */ - u16 softmac_features; - - /* if the sequence control field is not filled by HW */ - u16 seq_ctrl[5]; - - /* association procedure transaction sequence number */ - u16 associate_seq; - - /* AID for RTXed association responses */ - u16 assoc_id; - - /* power save mode related*/ - u8 ack_tx_to_ieee; - short ps; - short sta_sleep; - int ps_timeout; - int ps_period; - struct tasklet_struct ps_task; - u32 ps_th; - u32 ps_tl; - - short raw_tx; - /* used if IEEE_SOFTMAC_TX_QUEUE is set */ - short queue_stop; - short scanning; - short proto_started; - - struct semaphore wx_sem; - struct semaphore scan_sem; - - spinlock_t mgmt_tx_lock; - spinlock_t beacon_lock; - - short beacon_txing; - - short wap_set; - short ssid_set; - - u8 wpax_type_set; //{added by David, 2006.9.28} - u32 wpax_type_notify; //{added by David, 2006.9.26} - - /* QoS related flag */ - char init_wmmparam_flag; - /* set on initialization */ - u8 qos_support; - - /* for discarding duplicated packets in IBSS */ - struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE]; - - /* for discarding duplicated packets in BSS */ - u16 last_rxseq_num[17]; /* rx seq previous per-tid */ - u16 last_rxfrag_num[17];/* tx frag previous per-tid */ - unsigned long last_packet_time[17]; - - /* for PS mode */ - unsigned long last_rx_ps_time; - - /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */ - struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM]; - int mgmt_queue_head; - int mgmt_queue_tail; -//{ added for rtl819x -#define IEEE80211_QUEUE_LIMIT 128 - u8 AsocRetryCount; - unsigned int hw_header; - struct sk_buff_head skb_waitQ[MAX_QUEUE_SIZE]; - struct sk_buff_head skb_aggQ[MAX_QUEUE_SIZE]; - struct sk_buff_head skb_drv_aggQ[MAX_QUEUE_SIZE]; - u32 sta_edca_param[4]; - bool aggregation; - // Enable/Disable Rx immediate BA capability. - bool enable_rx_imm_BA; - bool bibsscoordinator; - - //+by amy for DM ,080515 - //Dynamic Tx power for near/far range enable/Disable , by amy , 2008-05-15 - bool bdynamic_txpower_enable; - - bool bCTSToSelfEnable; - u8 CTSToSelfTH; - - u32 fsync_time_interval; - u32 fsync_rate_bitmap; - u8 fsync_rssi_threshold; - bool bfsync_enable; - - u8 fsync_multiple_timeinterval; // FsyncMultipleTimeInterval * FsyncTimeInterval - u32 fsync_firstdiff_ratethreshold; // low threshold - u32 fsync_seconddiff_ratethreshold; // decrease threshold - Fsync_State fsync_state; - bool bis_any_nonbepkts; - //20Mhz 40Mhz AutoSwitch Threshold - bandwidth_autoswitch bandwidth_auto_switch; - //for txpower tracking - bool FwRWRF; - - //added by amy for AP roaming - RT_LINK_DETECT_T LinkDetectInfo; - //added by amy for ps - RT_POWER_SAVE_CONTROL PowerSaveControl; -//} - /* used if IEEE_SOFTMAC_TX_QUEUE is set */ - struct tx_pending_t tx_pending; - - /* used if IEEE_SOFTMAC_ASSOCIATE is set */ - struct timer_list associate_timer; - - /* used if IEEE_SOFTMAC_BEACONS is set */ - struct timer_list beacon_timer; - - struct work_struct associate_complete_wq; - struct work_struct associate_procedure_wq; - struct delayed_work softmac_scan_wq; - struct delayed_work associate_retry_wq; - struct delayed_work start_ibss_wq; - struct delayed_work hw_wakeup_wq; - struct delayed_work hw_sleep_wq; - struct work_struct wx_sync_scan_wq; - struct workqueue_struct *wq; - // Qos related. Added by Annie, 2005-11-01. - //STA_QOS StaQos; - - //u32 STA_EDCA_PARAM[4]; - //CHANNEL_ACCESS_SETTING ChannelAccessSetting; - - - /* Callback functions */ - void (*set_security)(struct net_device *dev, - struct ieee80211_security *sec); - - /* Used to TX data frame by using txb structs. - * this is not used if in the softmac_features - * is set the flag IEEE_SOFTMAC_TX_QUEUE - */ - int (*hard_start_xmit)(struct ieee80211_txb *txb, - struct net_device *dev); - - int (*reset_port)(struct net_device *dev); - int (*is_queue_full) (struct net_device * dev, int pri); - - int (*handle_management) (struct net_device * dev, - struct ieee80211_network * network, u16 type); - int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb); - - /* Softmac-generated frames (mamagement) are TXed via this - * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is - * not set. As some cards may have different HW queues that - * one might want to use for data and management frames - * the option to have two callbacks might be useful. - * This fucntion can't sleep. - */ - int (*softmac_hard_start_xmit)(struct sk_buff *skb, - struct net_device *dev); - - /* used instead of hard_start_xmit (not softmac_hard_start_xmit) - * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data - * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set - * then also management frames are sent via this callback. - * This function can't sleep. - */ - void (*softmac_data_hard_start_xmit)(struct sk_buff *skb, - struct net_device *dev,int rate); - - /* stops the HW queue for DATA frames. Useful to avoid - * waste time to TX data frame when we are reassociating - * This function can sleep. - */ - void (*data_hard_stop)(struct net_device *dev); - - /* OK this is complementar to data_poll_hard_stop */ - void (*data_hard_resume)(struct net_device *dev); - - /* ask to the driver to retune the radio . - * This function can sleep. the driver should ensure - * the radio has been swithced before return. - */ - void (*set_chan)(struct net_device *dev,short ch); - - /* These are not used if the ieee stack takes care of - * scanning (IEEE_SOFTMAC_SCAN feature set). - * In this case only the set_chan is used. - * - * The syncro version is similar to the start_scan but - * does not return until all channels has been scanned. - * this is called in user context and should sleep, - * it is called in a work_queue when swithcing to ad-hoc mode - * or in behalf of iwlist scan when the card is associated - * and root user ask for a scan. - * the fucntion stop_scan should stop both the syncro and - * background scanning and can sleep. - * The fucntion start_scan should initiate the background - * scanning and can't sleep. - */ - void (*scan_syncro)(struct net_device *dev); - void (*start_scan)(struct net_device *dev); - void (*stop_scan)(struct net_device *dev); - - /* indicate the driver that the link state is changed - * for example it may indicate the card is associated now. - * Driver might be interested in this to apply RX filter - * rules or simply light the LINK led - */ - void (*link_change)(struct net_device *dev); - - /* these two function indicates to the HW when to start - * and stop to send beacons. This is used when the - * IEEE_SOFTMAC_BEACONS is not set. For now the - * stop_send_bacons is NOT guaranteed to be called only - * after start_send_beacons. - */ - void (*start_send_beacons) (struct net_device *dev); - void (*stop_send_beacons) (struct net_device *dev); - - /* power save mode related */ - void (*sta_wake_up) (struct net_device *dev); -// void (*ps_request_tx_ack) (struct net_device *dev); - void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl); - short (*ps_is_queue_empty) (struct net_device *dev); -#if 0 - /* Typical STA methods */ - int (*handle_auth) (struct net_device * dev, - struct ieee80211_auth * auth); - int (*handle_deauth) (struct net_device * dev, - struct ieee80211_deauth * auth); - int (*handle_action) (struct net_device * dev, - struct ieee80211_action * action, - struct ieee80211_rx_stats * stats); - int (*handle_disassoc) (struct net_device * dev, - struct ieee80211_disassoc * assoc); -#endif - int (*handle_beacon) (struct net_device * dev, struct ieee80211_beacon * beacon, struct ieee80211_network * network); -#if 0 - int (*handle_probe_response) (struct net_device * dev, - struct ieee80211_probe_response * resp, - struct ieee80211_network * network); - int (*handle_probe_request) (struct net_device * dev, - struct ieee80211_probe_request * req, - struct ieee80211_rx_stats * stats); -#endif - int (*handle_assoc_response) (struct net_device * dev, struct ieee80211_assoc_response_frame * resp, struct ieee80211_network * network); - -#if 0 - /* Typical AP methods */ - int (*handle_assoc_request) (struct net_device * dev); - int (*handle_reassoc_request) (struct net_device * dev, - struct ieee80211_reassoc_request * req); -#endif - - /* check whether Tx hw resouce available */ - short (*check_nic_enough_desc)(struct net_device *dev, int queue_index); - //added by wb for HT related -// void (*SwChnlByTimerHandler)(struct net_device *dev, int channel); - void (*SetBWModeHandler)(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); -// void (*UpdateHalRATRTableHandler)(struct net_device* dev, u8* pMcsRate); - bool (*GetNmodeSupportBySecCfg)(struct net_device* dev); - void (*SetWirelessMode)(struct net_device* dev, u8 wireless_mode); - bool (*GetHalfNmodeSupportByAPsHandler)(struct net_device* dev); - void (*InitialGainHandler)(struct net_device *dev, u8 Operation); - - /* This must be the last item so that it points to the data - * allocated beyond this structure by alloc_ieee80211 */ - u8 priv[0]; -}; - -#define IEEE_A (1<<0) -#define IEEE_B (1<<1) -#define IEEE_G (1<<2) -#define IEEE_N_24G (1<<4) -#define IEEE_N_5G (1<<5) -#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G) - -/* Generate a 802.11 header */ - -/* Uses the channel change callback directly - * instead of [start/stop] scan callbacks - */ -#define IEEE_SOFTMAC_SCAN (1<<2) - -/* Perform authentication and association handshake */ -#define IEEE_SOFTMAC_ASSOCIATE (1<<3) - -/* Generate probe requests */ -#define IEEE_SOFTMAC_PROBERQ (1<<4) - -/* Generate respones to probe requests */ -#define IEEE_SOFTMAC_PROBERS (1<<5) - -/* The ieee802.11 stack will manages the netif queue - * wake/stop for the driver, taking care of 802.11 - * fragmentation. See softmac.c for details. */ -#define IEEE_SOFTMAC_TX_QUEUE (1<<7) - -/* Uses only the softmac_data_hard_start_xmit - * even for TX management frames. - */ -#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8) - -/* Generate beacons. The stack will enqueue beacons - * to the card - */ -#define IEEE_SOFTMAC_BEACONS (1<<6) - -static inline void *ieee80211_priv(struct net_device *dev) -{ - return ((struct ieee80211_device *)netdev_priv(dev))->priv; -} - -extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len) -{ - /* Single white space is for Linksys APs */ - if (essid_len == 1 && essid[0] == ' ') - return 1; - - /* Otherwise, if the entire essid is 0, we assume it is hidden */ - while (essid_len) { - essid_len--; - if (essid[essid_len] != '\0') - return 0; - } - - return 1; -} - -extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode) -{ - /* - * It is possible for both access points and our device to support - * combinations of modes, so as long as there is one valid combination - * of ap/device supported modes, then return success - * - */ - if ((mode & IEEE_A) && - (ieee->modulation & IEEE80211_OFDM_MODULATION) && - (ieee->freq_band & IEEE80211_52GHZ_BAND)) - return 1; - - if ((mode & IEEE_G) && - (ieee->modulation & IEEE80211_OFDM_MODULATION) && - (ieee->freq_band & IEEE80211_24GHZ_BAND)) - return 1; - - if ((mode & IEEE_B) && - (ieee->modulation & IEEE80211_CCK_MODULATION) && - (ieee->freq_band & IEEE80211_24GHZ_BAND)) - return 1; - - return 0; -} - -extern inline int ieee80211_get_hdrlen(u16 fc) -{ - int hdrlen = IEEE80211_3ADDR_LEN; - - switch (WLAN_FC_GET_TYPE(fc)) { - case IEEE80211_FTYPE_DATA: - if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS)) - hdrlen = IEEE80211_4ADDR_LEN; /* Addr4 */ - if(IEEE80211_QOS_HAS_SEQ(fc)) - hdrlen += 2; /* QOS ctrl*/ - break; - case IEEE80211_FTYPE_CTL: - switch (WLAN_FC_GET_STYPE(fc)) { - case IEEE80211_STYPE_CTS: - case IEEE80211_STYPE_ACK: - hdrlen = IEEE80211_1ADDR_LEN; - break; - default: - hdrlen = IEEE80211_2ADDR_LEN; - break; - } - break; - } - - return hdrlen; -} - -static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr) -{ - switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) { - case IEEE80211_1ADDR_LEN: - return ((struct ieee80211_hdr_1addr *)hdr)->payload; - case IEEE80211_2ADDR_LEN: - return ((struct ieee80211_hdr_2addr *)hdr)->payload; - case IEEE80211_3ADDR_LEN: - return ((struct ieee80211_hdr_3addr *)hdr)->payload; - case IEEE80211_4ADDR_LEN: - return ((struct ieee80211_hdr_4addr *)hdr)->payload; - } - return NULL; -} - -static inline int ieee80211_is_ofdm_rate(u8 rate) -{ - switch (rate & ~IEEE80211_BASIC_RATE_MASK) { - case IEEE80211_OFDM_RATE_6MB: - case IEEE80211_OFDM_RATE_9MB: - case IEEE80211_OFDM_RATE_12MB: - case IEEE80211_OFDM_RATE_18MB: - case IEEE80211_OFDM_RATE_24MB: - case IEEE80211_OFDM_RATE_36MB: - case IEEE80211_OFDM_RATE_48MB: - case IEEE80211_OFDM_RATE_54MB: - return 1; - } - return 0; -} - -static inline int ieee80211_is_cck_rate(u8 rate) -{ - switch (rate & ~IEEE80211_BASIC_RATE_MASK) { - case IEEE80211_CCK_RATE_1MB: - case IEEE80211_CCK_RATE_2MB: - case IEEE80211_CCK_RATE_5MB: - case IEEE80211_CCK_RATE_11MB: - return 1; - } - return 0; -} - - -/* ieee80211.c */ -void free_ieee80211(struct net_device *dev); -struct net_device *alloc_ieee80211(int sizeof_priv); - -int ieee80211_set_encryption(struct ieee80211_device *ieee); - -/* ieee80211_tx.c */ - -int ieee80211_encrypt_fragment( - struct ieee80211_device *ieee, - struct sk_buff *frag, - int hdr_len); - -int ieee80211_rtl_xmit(struct sk_buff *skb, - struct net_device *dev); -void ieee80211_txb_free(struct ieee80211_txb *); - - -/* ieee80211_rx.c */ -int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats); -void ieee80211_rx_mgt(struct ieee80211_device *ieee, - struct ieee80211_hdr_4addr *header, - struct ieee80211_rx_stats *stats); - -/* ieee80211_wx.c */ -int ieee80211_wx_get_scan(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key); -int ieee80211_wx_set_encode(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key); -int ieee80211_wx_get_encode(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key); -#if WIRELESS_EXT >= 18 -int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data* wrqu, char *extra); -int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data* wrqu, char *extra); -int ieee80211_wx_set_auth(struct ieee80211_device *ieee, - struct iw_request_info *info, - struct iw_param *data, char *extra); -int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); -#endif -int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len); - -/* ieee80211_softmac.c */ -short ieee80211_is_54g(struct ieee80211_network net); -short ieee80211_is_shortslot(struct ieee80211_network net); -int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats, u16 type, - u16 stype); -void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net); - -void SendDisassociation(struct ieee80211_device *ieee, u8* asSta, u8 asRsn); -void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee); - -void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); -void notify_wx_assoc_event(struct ieee80211_device *ieee); -void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee); -void ieee80211_start_bss(struct ieee80211_device *ieee); -void ieee80211_start_master_bss(struct ieee80211_device *ieee); -void ieee80211_start_ibss(struct ieee80211_device *ieee); -void ieee80211_softmac_init(struct ieee80211_device *ieee); -void ieee80211_softmac_free(struct ieee80211_device *ieee); -void ieee80211_associate_abort(struct ieee80211_device *ieee); -void ieee80211_disassociate(struct ieee80211_device *ieee); -void ieee80211_stop_scan(struct ieee80211_device *ieee); -void ieee80211_start_scan_syncro(struct ieee80211_device *ieee); -void ieee80211_check_all_nets(struct ieee80211_device *ieee); -void ieee80211_start_protocol(struct ieee80211_device *ieee); -void ieee80211_stop_protocol(struct ieee80211_device *ieee); -void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); -void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); -void ieee80211_reset_queue(struct ieee80211_device *ieee); -void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee); -void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee); -struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); -void ieee80211_start_send_beacons(struct ieee80211_device *ieee); -void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); -int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p); -void notify_wx_assoc_event(struct ieee80211_device *ieee); -void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success); - -void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee); - -/* ieee80211_crypt_ccmp&tkip&wep.c */ -void ieee80211_tkip_null(void); -void ieee80211_wep_null(void); -void ieee80211_ccmp_null(void); - -/* ieee80211_softmac_wx.c */ - -int ieee80211_wx_get_wap(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *ext); - -int ieee80211_wx_set_wap(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *awrq, - char *extra); - -int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b); - -int ieee80211_wx_set_rate(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_get_rate(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -int ieee80211_wx_set_essid(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -void ieee80211_wx_sync_scan_wq(struct work_struct *work); - - -int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_get_name(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_set_power(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_get_power(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_set_rts(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_get_rts(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); -//HT -#define MAX_RECEIVE_BUFFER_SIZE 9100 // -void HTDebugHTCapability(u8* CapIE, u8* TitleString ); -void HTDebugHTInfo(u8* InfoIE, u8* TitleString); - -void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); -void HTUpdateDefaultSetting(struct ieee80211_device* ieee); -void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 isEncrypt); -void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 isEncrypt); -void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len); -void HTOnAssocRsp(struct ieee80211_device *ieee); -void HTInitializeHTInfo(struct ieee80211_device* ieee); -void HTInitializeBssDesc(PBSS_HT pBssHT); -void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork); -void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork); -u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter); -extern u8 MCS_FILTER_ALL[]; -extern u16 MCS_DATA_RATE[2][2][77] ; -u8 HTCCheck(struct ieee80211_device* ieee, u8* pFrame); -//extern void HTSetConnectBwModeCallback(unsigned long data); -void HTResetIOTSetting(PRT_HIGH_THROUGHPUT pHTInfo); -bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee); -u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee, u8 nMcsRate); -u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate); -u16 TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate); -//function in BAPROC.c -int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb); -int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb); -int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb); -void TsInitAddBA( struct ieee80211_device* ieee, PTX_TS_RECORD pTS, u8 Policy, u8 bOverwritePending); -void TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect); -void BaSetupTimeOut(unsigned long data); -void TxBaInactTimeout(unsigned long data); -void RxBaInactTimeout(unsigned long data); -void ResetBaEntry( PBA_RECORD pBA); -//function in TS.c -bool GetTs( - struct ieee80211_device* ieee, - PTS_COMMON_INFO *ppTS, - u8* Addr, - u8 TID, - TR_SELECT TxRxSelect, //Rx:1, Tx:0 - bool bAddNewTs - ); -void TSInitialize(struct ieee80211_device *ieee); -void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD pTxTS); -void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr); -void RemoveAllTS(struct ieee80211_device* ieee); -void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee); - -extern const long ieee80211_wlan_frequencies[]; - -extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee) -{ - ieee->scans++; -} - -extern inline int ieee80211_get_scans(struct ieee80211_device *ieee) -{ - return ieee->scans; -} - -static inline const char *escape_essid(const char *essid, u8 essid_len) { - static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; - const char *s = essid; - char *d = escaped; - - if (ieee80211_is_empty_essid(essid, essid_len)) { - memcpy(escaped, "", sizeof("")); - return escaped; - } - - essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE); - while (essid_len--) { - if (*s == '\0') { - *d++ = '\\'; - *d++ = '0'; - s++; - } else { - *d++ = *s++; - } - } - *d = '\0'; - return escaped; -} - -/* For the function is more related to hardware setting, it's better to use the - * ieee handler to refer to it. - */ -short check_nic_enough_desc(struct net_device *dev, int queue_index); -int ieee80211_data_xmit(struct sk_buff *skb, struct net_device *dev); -int ieee80211_parse_info_param(struct ieee80211_device *ieee, - struct ieee80211_info_element *info_element, - u16 length, - struct ieee80211_network *network, - struct ieee80211_rx_stats *stats); - -void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8 index); -#define RT_ASOC_RETRY_LIMIT 5 -#endif /* IEEE80211_H */ -- cgit v1.2.3 From 427bf120b67a098f0ab4ebb84ee238afcfc0c689 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 6 Feb 2011 22:53:12 +0900 Subject: staging: rtl8192e: Remove redundant externs Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 222 ++++++++++++------------- 1 file changed, 109 insertions(+), 113 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index 933c800d6402..9a5f788d97ce 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -2587,205 +2587,202 @@ static inline int ieee80211_is_cck_rate(u8 rate) /* ieee80211.c */ -extern void free_ieee80211(struct net_device *dev); -extern struct net_device *alloc_ieee80211(int sizeof_priv); +void free_ieee80211(struct net_device *dev); +struct net_device *alloc_ieee80211(int sizeof_priv); -extern int ieee80211_set_encryption(struct ieee80211_device *ieee); +int ieee80211_set_encryption(struct ieee80211_device *ieee); /* ieee80211_tx.c */ -extern int ieee80211_encrypt_fragment( +int ieee80211_encrypt_fragment( struct ieee80211_device *ieee, struct sk_buff *frag, int hdr_len); -extern int ieee80211_rtl_xmit(struct sk_buff *skb, +int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev); -extern void ieee80211_txb_free(struct ieee80211_txb *); +void ieee80211_txb_free(struct ieee80211_txb *); /* ieee80211_rx.c */ -extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, +int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats); -extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, +void ieee80211_rx_mgt(struct ieee80211_device *ieee, struct ieee80211_hdr_4addr *header, struct ieee80211_rx_stats *stats); /* ieee80211_wx.c */ -extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee, +int ieee80211_wx_get_scan(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *key); -extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee, +int ieee80211_wx_set_encode(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *key); -extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee, +int ieee80211_wx_get_encode(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *key); #if WIRELESS_EXT >= 18 -extern int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee, +int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data* wrqu, char *extra); -extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, +int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data* wrqu, char *extra); -extern int ieee80211_wx_set_auth(struct ieee80211_device *ieee, +int ieee80211_wx_set_auth(struct ieee80211_device *ieee, struct iw_request_info *info, struct iw_param *data, char *extra); -extern int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, +int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); #endif -extern int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len); +int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len); /* ieee80211_softmac.c */ -extern short ieee80211_is_54g(struct ieee80211_network net); -extern short ieee80211_is_shortslot(struct ieee80211_network net); -extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, +short ieee80211_is_54g(struct ieee80211_network net); +short ieee80211_is_shortslot(struct ieee80211_network net); +int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats, u16 type, u16 stype); -extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net); +void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net); void SendDisassociation(struct ieee80211_device *ieee, u8* asSta, u8 asRsn); -extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee); - -extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); -extern void notify_wx_assoc_event(struct ieee80211_device *ieee); -extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee); -extern void ieee80211_start_bss(struct ieee80211_device *ieee); -extern void ieee80211_start_master_bss(struct ieee80211_device *ieee); -extern void ieee80211_start_ibss(struct ieee80211_device *ieee); -extern void ieee80211_softmac_init(struct ieee80211_device *ieee); -extern void ieee80211_softmac_free(struct ieee80211_device *ieee); -extern void ieee80211_associate_abort(struct ieee80211_device *ieee); -extern void ieee80211_disassociate(struct ieee80211_device *ieee); -extern void ieee80211_stop_scan(struct ieee80211_device *ieee); -extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee); -extern void ieee80211_check_all_nets(struct ieee80211_device *ieee); -extern void ieee80211_start_protocol(struct ieee80211_device *ieee); -extern void ieee80211_stop_protocol(struct ieee80211_device *ieee,u8 shutdown); -extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); -extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee,u8 shutdown); -extern void ieee80211_reset_queue(struct ieee80211_device *ieee); -extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee); -extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee); -extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); -extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); -extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); -extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p); -extern void notify_wx_assoc_event(struct ieee80211_device *ieee); -extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success); - -extern void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee); +void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee); + +void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); +void notify_wx_assoc_event(struct ieee80211_device *ieee); +void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee); +void ieee80211_start_bss(struct ieee80211_device *ieee); +void ieee80211_start_master_bss(struct ieee80211_device *ieee); +void ieee80211_start_ibss(struct ieee80211_device *ieee); +void ieee80211_softmac_init(struct ieee80211_device *ieee); +void ieee80211_softmac_free(struct ieee80211_device *ieee); +void ieee80211_associate_abort(struct ieee80211_device *ieee); +void ieee80211_disassociate(struct ieee80211_device *ieee); +void ieee80211_stop_scan(struct ieee80211_device *ieee); +void ieee80211_start_scan_syncro(struct ieee80211_device *ieee); +void ieee80211_check_all_nets(struct ieee80211_device *ieee); +void ieee80211_start_protocol(struct ieee80211_device *ieee); +void ieee80211_stop_protocol(struct ieee80211_device *ieee,u8 shutdown); +void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); +void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee,u8 shutdown); +void ieee80211_reset_queue(struct ieee80211_device *ieee); +void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee); +void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee); +struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); +void ieee80211_start_send_beacons(struct ieee80211_device *ieee); +void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); +int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p); +void notify_wx_assoc_event(struct ieee80211_device *ieee); +void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success); + +void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee); /* ieee80211_crypt_ccmp&tkip&wep.c */ -extern void ieee80211_tkip_null(void); -extern void ieee80211_wep_null(void); -extern void ieee80211_ccmp_null(void); +void ieee80211_tkip_null(void); +void ieee80211_wep_null(void); +void ieee80211_ccmp_null(void); /* ieee80211_softmac_wx.c */ -extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee, +int ieee80211_wx_get_wap(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *ext); -extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee, +int ieee80211_wx_set_wap(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *awrq, char *extra); -extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b); +int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b); -extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee, +int ieee80211_wx_set_rate(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); -extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee, +int ieee80211_wx_get_rate(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); -extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a, +int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a, union iwreq_data *wrqu, char *b); -extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a, +int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a, union iwreq_data *wrqu, char *b); -extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee, +int ieee80211_wx_set_essid(struct ieee80211_device *ieee, struct iw_request_info *a, union iwreq_data *wrqu, char *extra); -extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a, +int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a, union iwreq_data *wrqu, char *b); -extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a, +int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a, union iwreq_data *wrqu, char *b); -extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a, +int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a, union iwreq_data *wrqu, char *b); -//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee); -extern void ieee80211_wx_sync_scan_wq(struct work_struct *work); +void ieee80211_wx_sync_scan_wq(struct work_struct *work); - -extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, +int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); -extern int ieee80211_wx_get_name(struct ieee80211_device *ieee, +int ieee80211_wx_get_name(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); -extern int ieee80211_wx_set_power(struct ieee80211_device *ieee, +int ieee80211_wx_set_power(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); -extern int ieee80211_wx_get_power(struct ieee80211_device *ieee, +int ieee80211_wx_get_power(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); -extern int ieee80211_wx_set_rts(struct ieee80211_device *ieee, +int ieee80211_wx_set_rts(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); -extern int ieee80211_wx_get_rts(struct ieee80211_device *ieee, +int ieee80211_wx_get_rts(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); //HT -#define MAX_RECEIVE_BUFFER_SIZE 9100 // -extern void HTDebugHTCapability(u8* CapIE, u8* TitleString ); -extern void HTDebugHTInfo(u8* InfoIE, u8* TitleString); - -void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); -extern void HTUpdateDefaultSetting(struct ieee80211_device* ieee); -extern void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 isEncrypt); -extern void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 isEncrypt); -extern void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len); -extern void HTOnAssocRsp(struct ieee80211_device *ieee); -extern void HTInitializeHTInfo(struct ieee80211_device* ieee); -extern void HTInitializeBssDesc(PBSS_HT pBssHT); -extern void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork); -extern void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork); -extern u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter); +#define MAX_RECEIVE_BUFFER_SIZE 9100 +void HTDebugHTCapability(u8 *CapIE, u8 *TitleString ); +void HTDebugHTInfo(u8 *InfoIE, u8 *TitleString); + +void HTSetConnectBwMode(struct ieee80211_device *ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); +void HTUpdateDefaultSetting(struct ieee80211_device *ieee); +void HTConstructCapabilityElement(struct ieee80211_device *ieee, u8 *posHTCap, u8 *len, u8 isEncrypt); +void HTConstructInfoElement(struct ieee80211_device *ieee, u8 *posHTInfo, u8 *len, u8 isEncrypt); +void HTConstructRT2RTAggElement(struct ieee80211_device *ieee, u8 *posRT2RTAgg, u8 *len); +void HTOnAssocRsp(struct ieee80211_device *ieee); +void HTInitializeHTInfo(struct ieee80211_device *ieee); +void HTInitializeBssDesc(PBSS_HT pBssHT); +void HTResetSelfAndSavePeerSetting(struct ieee80211_device *ieee, struct ieee80211_network *pNetwork); +void HTUpdateSelfAndPeerSetting(struct ieee80211_device *ieee, struct ieee80211_network *pNetwork); +u8 HTGetHighestMCSRate(struct ieee80211_device *ieee, u8 *pMCSRateSet, u8 *pMCSFilter); extern u8 MCS_FILTER_ALL[]; extern u16 MCS_DATA_RATE[2][2][77] ; -extern u8 HTCCheck(struct ieee80211_device* ieee, u8* pFrame); -//extern void HTSetConnectBwModeCallback(unsigned long data); -extern void HTResetIOTSetting(PRT_HIGH_THROUGHPUT pHTInfo); -extern bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee); -extern u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee, u8 nMcsRate); -extern u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate); -extern u16 TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate); -//function in BAPROC.c -extern int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb); -extern int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb); -extern int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb); -extern void TsInitAddBA( struct ieee80211_device* ieee, PTX_TS_RECORD pTS, u8 Policy, u8 bOverwritePending); -extern void TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect); -extern void BaSetupTimeOut(unsigned long data); -extern void TxBaInactTimeout(unsigned long data); -extern void RxBaInactTimeout(unsigned long data); -extern void ResetBaEntry( PBA_RECORD pBA); + +u8 HTCCheck(struct ieee80211_device *ieee, u8 *pFrame); +void HTResetIOTSetting(PRT_HIGH_THROUGHPUT pHTInfo); +bool IsHTHalfNmodeAPs(struct ieee80211_device *ieee); +u16 HTHalfMcsToDataRate(struct ieee80211_device *ieee, u8 nMcsRate); +u16 HTMcsToDataRate( struct ieee80211_device *ieee, u8 nMcsRate); +u16 TxCountToDataRate( struct ieee80211_device *ieee, u8 nDataRate); +int ieee80211_rx_ADDBAReq( struct ieee80211_device *ieee, struct sk_buff *skb); +int ieee80211_rx_ADDBARsp( struct ieee80211_device *ieee, struct sk_buff *skb); +int ieee80211_rx_DELBA(struct ieee80211_device *ieee, struct sk_buff *skb); +void TsInitAddBA( struct ieee80211_device *ieee, PTX_TS_RECORD pTS, u8 Policy, u8 bOverwritePending); +void TsInitDelBA( struct ieee80211_device *ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect); +void BaSetupTimeOut(unsigned long data); +void TxBaInactTimeout(unsigned long data); +void RxBaInactTimeout(unsigned long data); +void ResetBaEntry( PBA_RECORD pBA); //function in TS.c -extern bool GetTs( +bool GetTs( struct ieee80211_device* ieee, PTS_COMMON_INFO *ppTS, u8* Addr, @@ -2793,10 +2790,10 @@ extern bool GetTs( TR_SELECT TxRxSelect, //Rx:1, Tx:0 bool bAddNewTs ); -extern void TSInitialize(struct ieee80211_device *ieee); -extern void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD pTxTS); -extern void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr); -extern void RemoveAllTS(struct ieee80211_device* ieee); +void TSInitialize(struct ieee80211_device *ieee); +void TsStartAddBaProcess(struct ieee80211_device *ieee, PTX_TS_RECORD pTxTS); +void RemovePeerTS(struct ieee80211_device *ieee, u8 *Addr); +void RemoveAllTS(struct ieee80211_device *ieee); void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee); extern const long ieee80211_wlan_frequencies[]; @@ -2838,9 +2835,8 @@ static inline const char *escape_essid(const char *essid, u8 essid_len) { /* For the function is more related to hardware setting, it's better to use the * ieee handler to refer to it. */ -extern short check_nic_enough_desc(struct net_device *dev, int queue_index); -extern int ieee80211_data_xmit(struct sk_buff *skb, struct net_device *dev); -extern int ieee80211_parse_info_param(struct ieee80211_device *ieee, +int ieee80211_data_xmit(struct sk_buff *skb, struct net_device *dev); +int ieee80211_parse_info_param(struct ieee80211_device *ieee, struct ieee80211_info_element *info_element, u16 length, struct ieee80211_network *network, -- cgit v1.2.3 From 3f9ab1ee8a44240e280f511a219ed101b9095697 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 6 Feb 2011 22:53:26 +0900 Subject: staging: rtl8192e: Use private structure in IO functions The current ieee80211 library does not pass net_device structures around. Switch code to use private data structure to get I/O addresses. Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8180_93cx6.c | 58 +++--- drivers/staging/rtl8192e/r8190_rtl8256.c | 36 ++-- drivers/staging/rtl8192e/r8192E.h | 18 +- drivers/staging/rtl8192e/r8192E_core.c | 282 +++++++++++++++-------------- drivers/staging/rtl8192e/r8192E_dm.c | 236 ++++++++++++------------ drivers/staging/rtl8192e/r8192E_wx.c | 2 +- drivers/staging/rtl8192e/r8192_pm.c | 20 +- drivers/staging/rtl8192e/r819xE_firmware.c | 12 +- drivers/staging/rtl8192e/r819xE_phy.c | 109 +++++------ 9 files changed, 397 insertions(+), 376 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8180_93cx6.c b/drivers/staging/rtl8192e/r8180_93cx6.c index c38dd176987d..ba4712f482a5 100644 --- a/drivers/staging/rtl8192e/r8180_93cx6.c +++ b/drivers/staging/rtl8192e/r8180_93cx6.c @@ -20,49 +20,49 @@ #include "r8180_93cx6.h" -static void eprom_cs(struct net_device *dev, short bit) +static void eprom_cs(struct r8192_priv *priv, short bit) { if (bit) - write_nic_byte(dev, EPROM_CMD, + write_nic_byte(priv, EPROM_CMD, (1<Bssid, 6 ); for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i]= 0x55; priv->OpMode = RT_OP_MODE_NO_LINK; - write_nic_word(dev, BSSIDR, ((u16*)priv->ieee80211->current_network.bssid)[0]); - write_nic_dword(dev, BSSIDR+2, ((u32*)(priv->ieee80211->current_network.bssid+2))[0]); + write_nic_word(priv, BSSIDR, ((u16*)priv->ieee80211->current_network.bssid)[0]); + write_nic_dword(priv, BSSIDR+2, ((u32*)(priv->ieee80211->current_network.bssid+2))[0]); { RT_OP_MODE OpMode = priv->OpMode; //LED_CTL_MODE LedAction = LED_CTL_NO_LINK; - u8 btMsr = read_nic_byte(dev, MSR); + u8 btMsr = read_nic_byte(priv, MSR); btMsr &= 0xfc; @@ -805,7 +805,7 @@ MgntDisconnectIBSS( break; } - write_nic_byte(dev, MSR, btMsr); + write_nic_byte(priv, MSR, btMsr); // LED control //Adapter->HalFunc.LedControlHandler(Adapter, LedAction); @@ -817,7 +817,7 @@ MgntDisconnectIBSS( { u32 RegRCR, Type; Type = bFilterOutNonAssociatedBSSID; - RegRCR = read_nic_dword(dev,RCR); + RegRCR = read_nic_dword(priv, RCR); priv->ReceiveConfig = RegRCR; if (Type == true) RegRCR |= (RCR_CBSSID); @@ -825,7 +825,7 @@ MgntDisconnectIBSS( RegRCR &= (~RCR_CBSSID); { - write_nic_dword(dev, RCR,RegRCR); + write_nic_dword(priv, RCR, RegRCR); priv->ReceiveConfig = RegRCR; } @@ -862,7 +862,7 @@ MlmeDisassociateRequest( { RT_OP_MODE OpMode = priv->OpMode; //LED_CTL_MODE LedAction = LED_CTL_NO_LINK; - u8 btMsr = read_nic_byte(dev, MSR); + u8 btMsr = read_nic_byte(priv, MSR); btMsr &= 0xfc; @@ -888,15 +888,15 @@ MlmeDisassociateRequest( break; } - write_nic_byte(dev, MSR, btMsr); + write_nic_byte(priv, MSR, btMsr); // LED control //Adapter->HalFunc.LedControlHandler(Adapter, LedAction); } ieee80211_disassociate(priv->ieee80211); - write_nic_word(dev, BSSIDR, ((u16*)priv->ieee80211->current_network.bssid)[0]); - write_nic_dword(dev, BSSIDR+2, ((u32*)(priv->ieee80211->current_network.bssid+2))[0]); + write_nic_word(priv, BSSIDR, ((u16*)priv->ieee80211->current_network.bssid)[0]); + write_nic_dword(priv, BSSIDR+2, ((u32*)(priv->ieee80211->current_network.bssid+2))[0]); } @@ -935,7 +935,7 @@ MgntDisconnectAP( Type = bFilterOutNonAssociatedBSSID; //Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RCR, (pu1Byte)(&RegRCR)); - RegRCR = read_nic_dword(dev,RCR); + RegRCR = read_nic_dword(priv, RCR); priv->ReceiveConfig = RegRCR; if (Type == true) @@ -943,7 +943,7 @@ MgntDisconnectAP( else if (Type == false) RegRCR &= (~RCR_CBSSID); - write_nic_dword(dev, RCR,RegRCR); + write_nic_dword(priv, RCR, RegRCR); priv->ReceiveConfig = RegRCR; diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 515f492b214d..b2c44a7af0cf 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1052,16 +1052,16 @@ typedef struct r8192_priv bool init_firmware(struct net_device *dev); short rtl8192_tx(struct net_device *dev, struct sk_buff* skb); -u32 read_cam(struct net_device *dev, u8 addr); -void write_cam(struct net_device *dev, u8 addr, u32 data); -u8 read_nic_byte(struct net_device *dev, int x); +u32 read_cam(struct r8192_priv *priv, u8 addr); +void write_cam(struct r8192_priv *priv, u8 addr, u32 data); +u8 read_nic_byte(struct r8192_priv *priv, int x); u8 read_nic_byte_E(struct net_device *dev, int x); -u32 read_nic_dword(struct net_device *dev, int x); -u16 read_nic_word(struct net_device *dev, int x) ; -void write_nic_byte(struct net_device *dev, int x,u8 y); -void write_nic_byte_E(struct net_device *dev, int x,u8 y); -void write_nic_word(struct net_device *dev, int x,u16 y); -void write_nic_dword(struct net_device *dev, int x,u32 y); +u32 read_nic_dword(struct r8192_priv *priv, int x); +u16 read_nic_word(struct r8192_priv *priv, int x) ; +void write_nic_byte(struct r8192_priv *priv, int x,u8 y); +void write_nic_byte_E(struct net_device *priv, int x,u8 y); +void write_nic_word(struct r8192_priv *priv, int x,u16 y); +void write_nic_dword(struct r8192_priv *priv, int x,u32 y); void rtl8192_halt_adapter(struct net_device *dev, bool reset); void rtl8192_rx_enable(struct net_device *); diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 2c17b57aac8f..6190cdd3fb38 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -247,84 +247,97 @@ static inline bool rx_hal_is_cck_rate(prx_fwinfo_819x_pci pdrvinfo) void CamResetAllEntry(struct net_device *dev) { - write_nic_dword(dev, RWCAM, BIT31|BIT30); + struct r8192_priv* priv = ieee80211_priv(dev); + write_nic_dword(priv, RWCAM, BIT31|BIT30); } - -void write_cam(struct net_device *dev, u8 addr, u32 data) +void write_cam(struct r8192_priv *priv, u8 addr, u32 data) { - write_nic_dword(dev, WCAMI, data); - write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) ); + write_nic_dword(priv, WCAMI, data); + write_nic_dword(priv, RWCAM, BIT31|BIT16|(addr&0xff) ); } -u32 read_cam(struct net_device *dev, u8 addr) + +u32 read_cam(struct r8192_priv *priv, u8 addr) { - write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) ); - return read_nic_dword(dev, 0xa8); + write_nic_dword(priv, RWCAM, 0x80000000|(addr&0xff) ); + return read_nic_dword(priv, 0xa8); } #ifdef CONFIG_RTL8180_IO_MAP -u8 read_nic_byte(struct net_device *dev, int x) +u8 read_nic_byte(struct r8192_priv *priv, int x) { + struct net_device *dev = priv->ieee80211->dev; return 0xff&inb(dev->base_addr +x); } -u32 read_nic_dword(struct net_device *dev, int x) +u32 read_nic_dword(struct r8192_priv *priv, int x) { + struct net_device *dev = priv->ieee80211->dev; return inl(dev->base_addr +x); } -u16 read_nic_word(struct net_device *dev, int x) +u16 read_nic_word(struct r8192_priv *priv, int x) { + struct net_device *dev = priv->ieee80211->dev; return inw(dev->base_addr +x); } -void write_nic_byte(struct net_device *dev, int x,u8 y) +void write_nic_byte(struct r8192_priv *priv, int x,u8 y) { + struct net_device *dev = priv->ieee80211->dev; outb(y&0xff,dev->base_addr +x); } -void write_nic_word(struct net_device *dev, int x,u16 y) +void write_nic_word(struct r8192_priv *priv, int x,u16 y) { + struct net_device *dev = priv->ieee80211->dev; outw(y,dev->base_addr +x); } -void write_nic_dword(struct net_device *dev, int x,u32 y) +void write_nic_dword(struct r8192_priv *priv, int x,u32 y) { + struct net_device *dev = priv->ieee80211->dev; outl(y,dev->base_addr +x); } #else /* RTL_IO_MAP */ -u8 read_nic_byte(struct net_device *dev, int x) +u8 read_nic_byte(struct r8192_priv *priv, int x) { + struct net_device *dev = priv->ieee80211->dev; return 0xff&readb((u8*)dev->mem_start +x); } -u32 read_nic_dword(struct net_device *dev, int x) +u32 read_nic_dword(struct r8192_priv *priv, int x) { + struct net_device *dev = priv->ieee80211->dev; return readl((u8*)dev->mem_start +x); } -u16 read_nic_word(struct net_device *dev, int x) +u16 read_nic_word(struct r8192_priv *priv, int x) { + struct net_device *dev = priv->ieee80211->dev; return readw((u8*)dev->mem_start +x); } -void write_nic_byte(struct net_device *dev, int x,u8 y) +void write_nic_byte(struct r8192_priv *priv, int x,u8 y) { + struct net_device *dev = priv->ieee80211->dev; writeb(y,(u8*)dev->mem_start +x); udelay(20); } -void write_nic_dword(struct net_device *dev, int x,u32 y) +void write_nic_dword(struct r8192_priv *priv, int x,u32 y) { + struct net_device *dev = priv->ieee80211->dev; writel(y,(u8*)dev->mem_start +x); udelay(20); } -void write_nic_word(struct net_device *dev, int x,u16 y) +void write_nic_word(struct r8192_priv *priv, int x,u16 y) { + struct net_device *dev = priv->ieee80211->dev; writew(y,(u8*)dev->mem_start +x); udelay(20); } @@ -370,14 +383,14 @@ rtl8192e_SetHwReg(struct net_device *dev,u8 variable,u8* val) { case HW_VAR_BSSID: - write_nic_dword(dev, BSSIDR, ((u32*)(val))[0]); - write_nic_word(dev, BSSIDR+2, ((u16*)(val+2))[0]); + write_nic_dword(priv, BSSIDR, ((u32*)(val))[0]); + write_nic_word(priv, BSSIDR+2, ((u16*)(val+2))[0]); break; case HW_VAR_MEDIA_STATUS: { RT_OP_MODE OpMode = *((RT_OP_MODE *)(val)); - u8 btMsr = read_nic_byte(dev, MSR); + u8 btMsr = read_nic_byte(priv, MSR); btMsr &= 0xfc; @@ -400,7 +413,7 @@ rtl8192e_SetHwReg(struct net_device *dev,u8 variable,u8* val) break; } - write_nic_byte(dev, MSR, btMsr); + write_nic_byte(priv, MSR, btMsr); } break; @@ -409,7 +422,7 @@ rtl8192e_SetHwReg(struct net_device *dev,u8 variable,u8* val) u32 RegRCR, Type; Type = ((u8*)(val))[0]; - RegRCR = read_nic_dword(dev,RCR); + RegRCR = read_nic_dword(priv, RCR); priv->ReceiveConfig = RegRCR; if (Type == true) @@ -417,7 +430,7 @@ rtl8192e_SetHwReg(struct net_device *dev,u8 variable,u8* val) else if (Type == false) RegRCR &= (~RCR_CBSSID); - write_nic_dword(dev, RCR,RegRCR); + write_nic_dword(priv, RCR,RegRCR); priv->ReceiveConfig = RegRCR; } @@ -426,7 +439,7 @@ rtl8192e_SetHwReg(struct net_device *dev,u8 variable,u8* val) case HW_VAR_SLOT_TIME: { priv->slot_time = val[0]; - write_nic_byte(dev, SLOT_TIME, val[0]); + write_nic_byte(priv, SLOT_TIME, val[0]); } break; @@ -438,12 +451,12 @@ rtl8192e_SetHwReg(struct net_device *dev,u8 variable,u8* val) regTmp = priv->basic_rate; if (priv->short_preamble) regTmp |= BRSR_AckShortPmb; - write_nic_dword(dev, RRSR, regTmp); + write_nic_dword(priv, RRSR, regTmp); } break; case HW_VAR_CPU_RST: - write_nic_dword(dev, CPU_GEN, ((u32*)(val))[0]); + write_nic_dword(priv, CPU_GEN, ((u32*)(val))[0]); break; default: @@ -489,6 +502,7 @@ static int proc_get_registers(char *page, char **start, int *eof, void *data) { struct net_device *dev = data; + struct r8192_priv *priv = ieee80211_priv(dev); int len = 0; int i,n; int max=0xff; @@ -504,7 +518,7 @@ static int proc_get_registers(char *page, char **start, for(i=0;i<16 && n<=max;i++,n++) len += snprintf(page + len, count - len, - "%2x ",read_nic_byte(dev,n)); + "%2x ",read_nic_byte(priv,n)); } len += snprintf(page + len, count - len,"\n"); len += snprintf(page + len, count - len, @@ -516,7 +530,7 @@ static int proc_get_registers(char *page, char **start, for(i=0;i<16 && n<=max;i++,n++) len += snprintf(page + len, count - len, - "%2x ",read_nic_byte(dev,0x100|n)); + "%2x ",read_nic_byte(priv,0x100|n)); } len += snprintf(page + len, count - len, @@ -528,7 +542,7 @@ static int proc_get_registers(char *page, char **start, for(i=0;i<16 && n<=max;i++,n++) len += snprintf(page + len, count - len, - "%2x ",read_nic_byte(dev,0x300|n)); + "%2x ",read_nic_byte(priv,0x300|n)); } *eof = 1; @@ -705,14 +719,14 @@ static void rtl8192_irq_enable(struct net_device *dev) { struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); priv->irq_enabled = 1; - write_nic_dword(dev,INTA_MASK, priv->irq_mask); + write_nic_dword(priv, INTA_MASK, priv->irq_mask); } void rtl8192_irq_disable(struct net_device *dev) { struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - write_nic_dword(dev,INTA_MASK,0); + write_nic_dword(priv, INTA_MASK, 0); priv->irq_enabled = 0; } @@ -721,7 +735,7 @@ void rtl8192_update_msr(struct net_device *dev) struct r8192_priv *priv = ieee80211_priv(dev); u8 msr; - msr = read_nic_byte(dev, MSR); + msr = read_nic_byte(priv, MSR); msr &= ~ MSR_LINK_MASK; /* do not change in link_state != WLAN_LINK_ASSOCIATED. @@ -741,7 +755,7 @@ void rtl8192_update_msr(struct net_device *dev) }else msr |= (MSR_LINK_NONE<rx_ring_dma); + write_nic_dword(priv, RDQDA,priv->rx_ring_dma); } /* the TX_DESC_BASE setting is according to the following queue index @@ -781,7 +795,7 @@ void rtl8192_tx_enable(struct net_device *dev) u32 i; for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) - write_nic_dword(dev, TX_DESC_BASE[i], priv->tx_ring[i].dma); + write_nic_dword(priv, TX_DESC_BASE[i], priv->tx_ring[i].dma); ieee80211_reset_queue(priv->ieee80211); } @@ -830,6 +844,8 @@ static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio) void PHY_SetRtl8192eRfOff(struct net_device* dev) { + struct r8192_priv *priv = ieee80211_priv(dev); + //disable RF-Chip A/B rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0); //analog to digital off, for power save @@ -844,7 +860,7 @@ void PHY_SetRtl8192eRfOff(struct net_device* dev) rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0); rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x0); // Analog parameter!!Change bias and Lbus control. - write_nic_byte(dev, ANAPAR_FOR_8192PciE, 0x07); + write_nic_byte(priv, ANAPAR_FOR_8192PciE, 0x07); } @@ -863,7 +879,7 @@ void rtl8192_halt_adapter(struct net_device *dev, bool reset) * disable tx/rx. In 8185 we write 0x10 (Reset bit), * but here we make reference to WMAC and wirte 0x0 */ - write_nic_byte(dev, CMDR, 0); + write_nic_byte(priv, CMDR, 0); } mdelay(20); @@ -881,19 +897,19 @@ void rtl8192_halt_adapter(struct net_device *dev, bool reset) */ if (!priv->ieee80211->bSupportRemoteWakeUp) { PHY_SetRtl8192eRfOff(dev); - ulRegRead = read_nic_dword(dev,CPU_GEN); + ulRegRead = read_nic_dword(priv, CPU_GEN); ulRegRead |= CPU_GEN_SYSTEM_RESET; - write_nic_dword(dev,CPU_GEN, ulRegRead); + write_nic_dword(priv,CPU_GEN, ulRegRead); } else { /* for WOL */ - write_nic_dword(dev, WFCRC0, 0xffffffff); - write_nic_dword(dev, WFCRC1, 0xffffffff); - write_nic_dword(dev, WFCRC2, 0xffffffff); + write_nic_dword(priv, WFCRC0, 0xffffffff); + write_nic_dword(priv, WFCRC1, 0xffffffff); + write_nic_dword(priv, WFCRC2, 0xffffffff); /* Write PMR register */ - write_nic_byte(dev, PMR, 0x5); + write_nic_byte(priv, PMR, 0x5); /* Disable tx, enanble rx */ - write_nic_byte(dev, MacBlkCtrl, 0xa); + write_nic_byte(priv, MacBlkCtrl, 0xa); } } @@ -1102,7 +1118,7 @@ static void rtl8192_update_cap(struct net_device* dev, u16 cap) tmp = priv->basic_rate; if (priv->short_preamble) tmp |= BRSR_AckShortPmb; - write_nic_dword(dev, RRSR, tmp); + write_nic_dword(priv, RRSR, tmp); if (net->mode & (IEEE_G|IEEE_N_24G)) { @@ -1114,7 +1130,7 @@ static void rtl8192_update_cap(struct net_device* dev, u16 cap) else //long slot time slot_time = NON_SHORT_SLOT_TIME; priv->slot_time = slot_time; - write_nic_byte(dev, SLOT_TIME, slot_time); + write_nic_byte(priv, SLOT_TIME, slot_time); } } @@ -1139,25 +1155,25 @@ static void rtl8192_net_update(struct net_device *dev) priv->basic_rate = rate_config &= 0x15f; /* BSSID */ - write_nic_dword(dev, BSSIDR, ((u32 *)net->bssid)[0]); - write_nic_word(dev, BSSIDR+4, ((u16 *)net->bssid)[2]); + write_nic_dword(priv, BSSIDR, ((u32 *)net->bssid)[0]); + write_nic_word(priv, BSSIDR+4, ((u16 *)net->bssid)[2]); if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) { - write_nic_word(dev, ATIMWND, 2); - write_nic_word(dev, BCN_DMATIME, 256); - write_nic_word(dev, BCN_INTERVAL, net->beacon_interval); + write_nic_word(priv, ATIMWND, 2); + write_nic_word(priv, BCN_DMATIME, 256); + write_nic_word(priv, BCN_INTERVAL, net->beacon_interval); /* * BIT15 of BCN_DRV_EARLY_INT will indicate * whether software beacon or hw beacon is applied. */ - write_nic_word(dev, BCN_DRV_EARLY_INT, 10); - write_nic_byte(dev, BCN_ERR_THRESH, 100); + write_nic_word(priv, BCN_DRV_EARLY_INT, 10); + write_nic_byte(priv, BCN_ERR_THRESH, 100); BcnTimeCfg |= (BcnCW<queue, skb); spin_unlock_irqrestore(&priv->irq_th_lock,flags); - write_nic_byte(dev, TPPoll, TPPoll_CQ); + write_nic_byte(priv, TPPoll, TPPoll_CQ); return; } @@ -1465,7 +1481,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff* skb) pdesc->OWN = 1; spin_unlock_irqrestore(&priv->irq_th_lock, flags); dev->trans_start = jiffies; - write_nic_word(dev, TPPoll, 0x01<queue_index); + write_nic_word(priv, TPPoll, 0x01<queue_index); return 0; } @@ -1601,7 +1617,7 @@ static void rtl8192_link_change(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); struct ieee80211_device* ieee = priv->ieee80211; - //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval); + //write_nic_word(priv, BCN_INTR_ITV, net->beacon_interval); if (ieee->state == IEEE80211_LINKED) { rtl8192_net_update(dev); @@ -1613,7 +1629,7 @@ static void rtl8192_link_change(struct net_device *dev) } else { - write_nic_byte(dev, 0x173, 0); + write_nic_byte(priv, 0x173, 0); } /*update timing params*/ //rtl8192_set_chan(dev, priv->chan); @@ -1625,12 +1641,12 @@ static void rtl8192_link_change(struct net_device *dev) if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) { u32 reg = 0; - reg = read_nic_dword(dev, RCR); + reg = read_nic_dword(priv, RCR); if (priv->ieee80211->state == IEEE80211_LINKED) priv->ReceiveConfig = reg |= RCR_CBSSID; else priv->ReceiveConfig = reg &= ~RCR_CBSSID; - write_nic_dword(dev, RCR, reg); + write_nic_dword(priv, RCR, reg); } } @@ -1663,7 +1679,6 @@ static const int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_ static void rtl8192_qos_activate(struct work_struct * work) { struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate); - struct net_device *dev = priv->ieee80211->dev; struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters; u8 mode = priv->ieee80211->current_network.mode; u8 u1bAIFS; @@ -1684,8 +1699,8 @@ static void rtl8192_qos_activate(struct work_struct * work) (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)| (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)| ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET)); - write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam); - //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332); + write_nic_dword(priv, WDCAPARA_ADD[i], u4bAcParam); + //write_nic_dword(priv, WDCAPARA_ADD[i], 0x005e4332); } success: @@ -1855,8 +1870,8 @@ static void rtl8192_update_ratr_table(struct net_device* dev) }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){ ratr_value |= 0x80000000; } - write_nic_dword(dev, RATR0+rate_index*4, ratr_value); - write_nic_byte(dev, UFWP, 1); + write_nic_dword(priv, RATR0+rate_index*4, ratr_value); + write_nic_byte(priv, UFWP, 1); } static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev) @@ -2255,7 +2270,7 @@ static void rtl8192_get_eeprom_size(struct net_device* dev) u16 curCR = 0; struct r8192_priv *priv = ieee80211_priv(dev); RT_TRACE(COMP_INIT, "===========>%s()\n", __FUNCTION__); - curCR = read_nic_dword(dev, EPROM_CMD); + curCR = read_nic_dword(priv, EPROM_CMD); RT_TRACE(COMP_INIT, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD, curCR); //whether need I consider BIT5? priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EPROM_93c56 : EPROM_93c46; @@ -2266,10 +2281,9 @@ static void rtl8192_get_eeprom_size(struct net_device* dev) * Adapter->EEPROMAddressSize should be set before this function call. * EEPROM address size can be got through GetEEPROMSize8185() */ -static void rtl8192_read_eeprom_info(struct net_device* dev) +static void rtl8192_read_eeprom_info(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); - + struct net_device *dev = priv->ieee80211->dev; u8 tempval; #ifdef RTL8192E u8 ICVer8192, ICVer8256; @@ -2794,7 +2808,7 @@ static short rtl8192_init(struct net_device *dev) rtl8192_init_priv_lock(priv); rtl8192_init_priv_task(dev); rtl8192_get_eeprom_size(dev); - rtl8192_read_eeprom_info(dev); + rtl8192_read_eeprom_info(priv); rtl8192_get_channel_map(dev); init_hal_dm(dev); init_timer(&priv->watch_dog_timer); @@ -2862,7 +2876,7 @@ static void rtl8192_hwconfig(struct net_device* dev) break; } - write_nic_byte(dev, BW_OPMODE, regBwOpMode); + write_nic_byte(priv, BW_OPMODE, regBwOpMode); { u32 ratr_value = 0; ratr_value = regRATR; @@ -2870,17 +2884,17 @@ static void rtl8192_hwconfig(struct net_device* dev) { ratr_value &= ~(RATE_ALL_OFDM_2SS); } - write_nic_dword(dev, RATR0, ratr_value); - write_nic_byte(dev, UFWP, 1); + write_nic_dword(priv, RATR0, ratr_value); + write_nic_byte(priv, UFWP, 1); } - regTmp = read_nic_byte(dev, 0x313); + regTmp = read_nic_byte(priv, 0x313); regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff); - write_nic_dword(dev, RRSR, regRRSR); + write_nic_dword(priv, RRSR, regRRSR); // // Set Retry Limit here // - write_nic_word(dev, RETRY_LIMIT, + write_nic_word(priv, RETRY_LIMIT, priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT); // Set Contention Window here @@ -2922,7 +2936,7 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) //dPLL on if(priv->ResetProgress == RESET_TYPE_NORESET) { - write_nic_byte(dev, ANAPAR, 0x37); + write_nic_byte(priv, ANAPAR, 0x37); // Accordign to designer's explain, LBUS active will never > 10ms. We delay 10ms // Joseph increae the time to prevent firmware download fail mdelay(500); @@ -2936,7 +2950,7 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) //3 //Config CPUReset Register //3// //3 Firmware Reset Or Not - ulRegRead = read_nic_dword(dev, CPU_GEN); + ulRegRead = read_nic_dword(priv, CPU_GEN); if(priv->pFirmware->firmware_status == FW_STATUS_0_INIT) { //called from MPInitialized. do nothing ulRegRead |= CPU_GEN_SYSTEM_RESET; @@ -2950,7 +2964,7 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) ulRegRead &= (~(CPU_GEN_GPIO_UART)); #endif - write_nic_dword(dev, CPU_GEN, ulRegRead); + write_nic_dword(priv, CPU_GEN, ulRegRead); //mdelay(100); #ifdef RTL8192E @@ -2959,18 +2973,18 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) //3 //Fix the issue of E-cut high temperature issue //3// // TODO: E cut only - ICVersion = read_nic_byte(dev, IC_VERRSION); + ICVersion = read_nic_byte(priv, IC_VERRSION); if(ICVersion >= 0x4) //E-cut only { // HW SD suggest that we should not wirte this register too often, so driver // should readback this register. This register will be modified only when // power on reset - SwitchingRegulatorOutput = read_nic_byte(dev, SWREGULATOR); + SwitchingRegulatorOutput = read_nic_byte(priv, SWREGULATOR); if(SwitchingRegulatorOutput != 0xb8) { - write_nic_byte(dev, SWREGULATOR, 0xa8); + write_nic_byte(priv, SWREGULATOR, 0xa8); mdelay(1); - write_nic_byte(dev, SWREGULATOR, 0xb8); + write_nic_byte(priv, SWREGULATOR, 0xb8); } } #endif @@ -2997,7 +3011,7 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) //priv->LoopbackMode = RTL819X_MAC_LOOPBACK; if(priv->ResetProgress == RESET_TYPE_NORESET) { - ulRegRead = read_nic_dword(dev, CPU_GEN); + ulRegRead = read_nic_dword(priv, CPU_GEN); if(priv->LoopbackMode == RTL819X_NO_LOOPBACK) { ulRegRead = ((ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET); @@ -3013,7 +3027,7 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) //2008.06.03, for WOL //ulRegRead &= (~(CPU_GEN_GPIO_UART)); - write_nic_dword(dev, CPU_GEN, ulRegRead); + write_nic_dword(priv, CPU_GEN, ulRegRead); // 2006.11.29. After reset cpu, we sholud wait for a second, otherwise, it may fail to write registers. Emily udelay(500); @@ -3025,24 +3039,24 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) //2======================================================= // If there is changes, please make sure it applies to all of the FPGA version //3 Turn on Tx/Rx - write_nic_byte(dev, CMDR, CR_RE|CR_TE); + write_nic_byte(priv, CMDR, CR_RE|CR_TE); //2Set Tx dma burst #ifdef RTL8190P - write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<dev_addr)[0]); - write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]); + write_nic_dword(priv, MAC0, ((u32*)dev->dev_addr)[0]); + write_nic_word(priv, MAC4, ((u16*)(dev->dev_addr + 4))[0]); //set RCR - write_nic_dword(dev, RCR, priv->ReceiveConfig); + write_nic_dword(priv, RCR, priv->ReceiveConfig); //3 Initialize Number of Reserved Pages in Firmware Queue #ifdef TO_DO_LIST @@ -3060,12 +3074,12 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) else #endif { - write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT | + write_nic_dword(priv, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT | NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | NUM_OF_PAGE_IN_FW_QUEUE_VO <RegWirelessMode); if(priv->ResetProgress == RESET_TYPE_NORESET) @@ -3097,19 +3111,19 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) SECR_value |= SCR_TxEncEnable; SECR_value |= SCR_RxDecEnable; SECR_value |= SCR_NoSKMC; - write_nic_byte(dev, SECR, SECR_value); + write_nic_byte(priv, SECR, SECR_value); } //3Beacon related - write_nic_word(dev, ATIMWND, 2); - write_nic_word(dev, BCN_INTERVAL, 100); + write_nic_word(priv, ATIMWND, 2); + write_nic_word(priv, BCN_INTERVAL, 100); for (i=0; iIC_Cut = tmpvalue; RT_TRACE(COMP_INIT, "priv->IC_Cut = 0x%x\n", priv->IC_Cut); if(priv->IC_Cut >= IC_VersionCut_D) @@ -3173,17 +3187,17 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) #ifdef RTL8192E //Enable Led - write_nic_byte(dev, 0x87, 0x0); + write_nic_byte(priv, 0x87, 0x0); #endif #ifdef RTL8190P //2008.06.03, for WOL - ucRegRead = read_nic_byte(dev, GPE); + ucRegRead = read_nic_byte(priv, GPE); ucRegRead |= BIT0; - write_nic_byte(dev, GPE, ucRegRead); + write_nic_byte(priv, GPE, ucRegRead); - ucRegRead = read_nic_byte(dev, GPO); + ucRegRead = read_nic_byte(priv, GPO); ucRegRead &= ~BIT0; - write_nic_byte(dev, GPO, ucRegRead); + write_nic_byte(priv, GPO, ucRegRead); #endif //2======================================================= @@ -3376,34 +3390,34 @@ static void rtl8192_start_beacon(struct net_device *dev) //rtl8192_beacon_tx_enable(dev); /* ATIM window */ - write_nic_word(dev, ATIMWND, 2); + write_nic_word(priv, ATIMWND, 2); /* Beacon interval (in unit of TU) */ - write_nic_word(dev, BCN_INTERVAL, net->beacon_interval); + write_nic_word(priv, BCN_INTERVAL, net->beacon_interval); /* * DrvErlyInt (in unit of TU). * (Time to send interrupt to notify driver to c * hange beacon content) * */ - write_nic_word(dev, BCN_DRV_EARLY_INT, 10); + write_nic_word(priv, BCN_DRV_EARLY_INT, 10); /* * BcnDMATIM(in unit of us). * Indicates the time before TBTT to perform beacon queue DMA * */ - write_nic_word(dev, BCN_DMATIME, 256); + write_nic_word(priv, BCN_DMATIME, 256); /* * Force beacon frame transmission even after receiving * beacon frame from other ad hoc STA * */ - write_nic_byte(dev, BCN_ERR_THRESH, 100); + write_nic_byte(priv, BCN_ERR_THRESH, 100); /* Set CW and IFS */ BcnTimeCfg |= BcnCW<TxCounter); if(priv->TxCounter==RegTxCounter) @@ -3467,7 +3481,7 @@ TxCheckStuck(struct net_device *dev) static bool HalRxCheckStuck8190Pci(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); - u16 RegRxCounter = read_nic_word(dev, 0x130); + u16 RegRxCounter = read_nic_word(priv, 0x130); bool bStuck = FALSE; RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter); @@ -3829,7 +3843,7 @@ RESET_START: priv->bResetInProgress = false; // For test --> force write UFWP. - write_nic_byte(dev, UFWP, 1); + write_nic_byte(priv, UFWP, 1); RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count); } } @@ -4463,7 +4477,7 @@ static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key); } if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){ - write_nic_byte(dev, 0x173, 1); //fix aes bug + write_nic_byte(priv, 0x173, 1); //fix aes bug } } @@ -5419,7 +5433,7 @@ static void rtl8192_rx(struct net_device *dev) stats.bFirstMPDU = (pDrvInfo->PartAggr==1) && (pDrvInfo->FirstAGGR==1); stats.TimeStampLow = pDrvInfo->TSFL; - stats.TimeStampHigh = read_nic_dword(dev, TSFR+4); + stats.TimeStampHigh = read_nic_dword(priv, TSFR+4); UpdateRxPktTimeStamp8190(dev, &stats); @@ -5490,7 +5504,7 @@ static void rtl8192_irq_rx_tasklet(struct r8192_priv *priv) { rtl8192_rx(priv->ieee80211->dev); /* unmask RDU */ - write_nic_dword(priv->ieee80211->dev, INTA_MASK,read_nic_dword(priv->ieee80211->dev, INTA_MASK) | IMR_RDU); + write_nic_dword(priv, INTA_MASK, read_nic_dword(priv, INTA_MASK) | IMR_RDU); } static const struct net_device_ops rtl8192_netdev_ops = { @@ -5810,8 +5824,8 @@ static irqreturn_t rtl8192_interrupt(int irq, void *netdev) /* ISR: 4bytes */ - inta = read_nic_dword(dev, ISR); /* & priv->IntrMask; */ - write_nic_dword(dev, ISR, inta); /* reset int situation */ + inta = read_nic_dword(priv, ISR); /* & priv->IntrMask; */ + write_nic_dword(priv, ISR, inta); /* reset int situation */ if (!inta) { /* @@ -5867,7 +5881,7 @@ static irqreturn_t rtl8192_interrupt(int irq, void *netdev) RT_TRACE(COMP_INTR, "rx descriptor unavailable!\n"); priv->stats.rxrdu++; /* reset int situation */ - write_nic_dword(dev, INTA_MASK, read_nic_dword(dev, INTA_MASK) & ~IMR_RDU); + write_nic_dword(priv, INTA_MASK, read_nic_dword(priv, INTA_MASK) & ~IMR_RDU); tasklet_schedule(&priv->irq_rx_tasklet); } @@ -5945,7 +5959,7 @@ void EnableHWSecurityConfig8192(struct net_device *dev) RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, ieee->hwsec_active, ieee->pairwise_key_type, SECR_value); { - write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK ); + write_nic_byte(priv, SECR, SECR_value);//SECR_value | SCR_UseDK ); } } @@ -6005,22 +6019,22 @@ void setKey( struct net_device *dev, (u32)(*(MacAddr+1)) << 24| (u32)usConfig; - write_nic_dword(dev, WCAMI, TargetContent); - write_nic_dword(dev, RWCAM, TargetCommand); + write_nic_dword(priv, WCAMI, TargetContent); + write_nic_dword(priv, RWCAM, TargetCommand); } else if(i==1){//MAC TargetContent = (u32)(*(MacAddr+2)) | (u32)(*(MacAddr+3)) << 8| (u32)(*(MacAddr+4)) << 16| (u32)(*(MacAddr+5)) << 24; - write_nic_dword(dev, WCAMI, TargetContent); - write_nic_dword(dev, RWCAM, TargetCommand); + write_nic_dword(priv, WCAMI, TargetContent); + write_nic_dword(priv, RWCAM, TargetCommand); } else { //Key Material if(KeyContent != NULL) { - write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) ); - write_nic_dword(dev, RWCAM, TargetCommand); + write_nic_dword(priv, WCAMI, (u32)(*(KeyContent+i-2)) ); + write_nic_dword(priv, RWCAM, TargetCommand); } } } diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index 01a7ba613408..d328d6766a77 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -198,7 +198,7 @@ void dm_CheckRxAggregation(struct net_device *dev) { if(curTxOkCnt > 4*curRxOkCnt) { if (priv->bCurrentRxAggrEnable) { - write_nic_dword(dev, 0x1a8, 0); + write_nic_dword(priv, 0x1a8, 0); priv->bCurrentRxAggrEnable = false; } }else{ @@ -211,7 +211,7 @@ void dm_CheckRxAggregation(struct net_device *dev) { * when anyone of three threshold conditions above is reached, * firmware will send aggregated packet to driver. */ - write_nic_dword(dev, 0x1a8, ulValue); + write_nic_dword(priv, 0x1a8, ulValue); priv->bCurrentRxAggrEnable = true; } } @@ -450,7 +450,7 @@ static void dm_check_rate_adaptive(struct net_device * dev) // // Check whether updating of RATR0 is required // - currentRATR = read_nic_dword(dev, RATR0); + currentRATR = read_nic_dword(priv, RATR0); if( targetRATR != currentRATR ) { u32 ratr_value; @@ -460,8 +460,8 @@ static void dm_check_rate_adaptive(struct net_device * dev) { ratr_value &= ~(RATE_ALL_OFDM_2SS); } - write_nic_dword(dev, RATR0, ratr_value); - write_nic_byte(dev, UFWP, 1); + write_nic_dword(priv, RATR0, ratr_value); + write_nic_byte(priv, UFWP, 1); pra->last_ratr = targetRATR; } @@ -580,9 +580,9 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) // bool rtStatus = true; u32 delta=0; RT_TRACE(COMP_POWER_TRACKING,"%s()\n",__FUNCTION__); -// write_nic_byte(dev, 0x1ba, 0); - write_nic_byte(dev, Pw_Track_Flag, 0); - write_nic_byte(dev, FW_Busy_Flag, 0); +// write_nic_byte(priv, 0x1ba, 0); + write_nic_byte(priv, Pw_Track_Flag, 0); + write_nic_byte(priv, FW_Busy_Flag, 0); priv->ieee80211->bdynamic_txpower_enable = false; bHighpowerstate = priv->bDynamicTxHighPower; @@ -611,7 +611,7 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) for(i = 0;i <= 30; i++) { - Pwr_Flag = read_nic_byte(dev, Pw_Track_Flag); + Pwr_Flag = read_nic_byte(priv, Pw_Track_Flag); if (Pwr_Flag == 0) { @@ -619,21 +619,21 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) continue; } - Avg_TSSI_Meas = read_nic_word(dev, Tssi_Mea_Value); + Avg_TSSI_Meas = read_nic_word(priv, Tssi_Mea_Value); if(Avg_TSSI_Meas == 0) { - write_nic_byte(dev, Pw_Track_Flag, 0); - write_nic_byte(dev, FW_Busy_Flag, 0); + write_nic_byte(priv, Pw_Track_Flag, 0); + write_nic_byte(priv, FW_Busy_Flag, 0); return; } for(k = 0;k < 5; k++) { if(k !=4) - tmp_report[k] = read_nic_byte(dev, Tssi_Report_Value1+k); + tmp_report[k] = read_nic_byte(priv, Tssi_Report_Value1+k); else - tmp_report[k] = read_nic_byte(dev, Tssi_Report_Value2); + tmp_report[k] = read_nic_byte(priv, Tssi_Report_Value2); RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]); } @@ -649,7 +649,7 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) } if(viviflag ==TRUE) { - write_nic_byte(dev, Pw_Track_Flag, 0); + write_nic_byte(priv, Pw_Track_Flag, 0); viviflag = FALSE; RT_TRACE(COMP_POWER_TRACKING, "we filted this data\n"); for(k = 0;k < 5; k++) @@ -677,8 +677,8 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) if(delta <= E_FOR_TX_POWER_TRACK) { priv->ieee80211->bdynamic_txpower_enable = TRUE; - write_nic_byte(dev, Pw_Track_Flag, 0); - write_nic_byte(dev, FW_Busy_Flag, 0); + write_nic_byte(priv, Pw_Track_Flag, 0); + write_nic_byte(priv, FW_Busy_Flag, 0); RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n"); RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex); RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real); @@ -811,24 +811,24 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) if (priv->CCKPresentAttentuation_difference <= -12||priv->CCKPresentAttentuation_difference >= 24) { priv->ieee80211->bdynamic_txpower_enable = TRUE; - write_nic_byte(dev, Pw_Track_Flag, 0); - write_nic_byte(dev, FW_Busy_Flag, 0); + write_nic_byte(priv, Pw_Track_Flag, 0); + write_nic_byte(priv, FW_Busy_Flag, 0); RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n"); return; } } - write_nic_byte(dev, Pw_Track_Flag, 0); + write_nic_byte(priv, Pw_Track_Flag, 0); Avg_TSSI_Meas_from_driver = 0; for(k = 0;k < 5; k++) tmp_report[k] = 0; break; } - write_nic_byte(dev, FW_Busy_Flag, 0); + write_nic_byte(priv, FW_Busy_Flag, 0); } priv->ieee80211->bdynamic_txpower_enable = TRUE; - write_nic_byte(dev, Pw_Track_Flag, 0); + write_nic_byte(priv, Pw_Track_Flag, 0); } #ifndef RTL8190P static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev) @@ -1114,7 +1114,7 @@ static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev) struct r8192_priv *priv = ieee80211_priv(dev); static u32 tx_power_track_counter = 0; RT_TRACE(COMP_POWER_TRACKING,"%s()\n",__FUNCTION__); - if(read_nic_byte(dev, 0x11e) ==1) + if(read_nic_byte(priv, 0x11e) ==1) return; if(!priv->btxpower_tracking) return; @@ -1360,8 +1360,8 @@ void dm_restore_dynamic_mechanism_state(struct net_device *dev) { ratr_value &=~ (RATE_ALL_OFDM_2SS); } - write_nic_dword(dev, RATR0, ratr_value); - write_nic_byte(dev, UFWP, 1); + write_nic_dword(priv, RATR0, ratr_value); + write_nic_byte(priv, UFWP, 1); } //Resore TX Power Tracking Index if(priv->btxpower_trackingInit && priv->btxpower_tracking){ @@ -1653,10 +1653,10 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite. // 1.2 Set initial gain. - write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x17); - write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x17); - write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x17); - write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x17); + write_nic_byte(priv, rOFDM0_XAAGCCore1, 0x17); + write_nic_byte(priv, rOFDM0_XBAGCCore1, 0x17); + write_nic_byte(priv, rOFDM0_XCAGCCore1, 0x17); + write_nic_byte(priv, rOFDM0_XDAGCCore1, 0x17); // 1.3 Lower PD_TH for OFDM. if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) @@ -1664,9 +1664,9 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. #ifdef RTL8190P - write_nic_byte(dev, rOFDM0_RxDetector1, 0x40); + write_nic_byte(priv, rOFDM0_RxDetector1, 0x40); #else - write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00); + write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x00); #endif /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) write_nic_byte(pAdapter, rOFDM0_RxDetector1, 0x40); @@ -1678,10 +1678,10 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( //PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x40); } else - write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); + write_nic_byte(priv, rOFDM0_RxDetector1, 0x42); // 1.4 Lower CS ratio for CCK. - write_nic_byte(dev, 0xa0a, 0x08); + write_nic_byte(priv, 0xa0a, 0x08); // 1.5 Higher EDCCA. //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325); @@ -1715,17 +1715,17 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( // 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment. if (reset_flag == 1) { - write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x2c); - write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x2c); - write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x2c); - write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x2c); + write_nic_byte(priv, rOFDM0_XAAGCCore1, 0x2c); + write_nic_byte(priv, rOFDM0_XBAGCCore1, 0x2c); + write_nic_byte(priv, rOFDM0_XCAGCCore1, 0x2c); + write_nic_byte(priv, rOFDM0_XDAGCCore1, 0x2c); } else { - write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x20); - write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x20); - write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x20); - write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x20); + write_nic_byte(priv, rOFDM0_XAAGCCore1, 0x20); + write_nic_byte(priv, rOFDM0_XBAGCCore1, 0x20); + write_nic_byte(priv, rOFDM0_XCAGCCore1, 0x20); + write_nic_byte(priv, rOFDM0_XDAGCCore1, 0x20); } // 2.2 Higher PD_TH for OFDM. @@ -1734,9 +1734,9 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. #ifdef RTL8190P - write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); + write_nic_byte(priv, rOFDM0_RxDetector1, 0x42); #else - write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20); + write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20); #endif /* else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) @@ -1748,10 +1748,10 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( //PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x42); } else - write_nic_byte(dev, rOFDM0_RxDetector1, 0x44); + write_nic_byte(priv, rOFDM0_RxDetector1, 0x44); // 2.3 Higher CS ratio for CCK. - write_nic_byte(dev, 0xa0a, 0xcd); + write_nic_byte(priv, 0xa0a, 0xcd); // 2.4 Lower EDCCA. /* 2008/01/11 MH 90/92 series are the same. */ @@ -1794,18 +1794,18 @@ static void dm_ctrl_initgain_byrssi_highpwr( if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) { #ifdef RTL8190P - write_nic_byte(dev, rOFDM0_RxDetector1, 0x41); + write_nic_byte(priv, rOFDM0_RxDetector1, 0x41); #else - write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10); + write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x10); #endif /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) - write_nic_byte(dev, rOFDM0_RxDetector1, 0x41); + write_nic_byte(priv, rOFDM0_RxDetector1, 0x41); */ } else - write_nic_byte(dev, rOFDM0_RxDetector1, 0x43); + write_nic_byte(priv, rOFDM0_RxDetector1, 0x43); } else { @@ -1822,17 +1822,17 @@ static void dm_ctrl_initgain_byrssi_highpwr( if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) { #ifdef RTL8190P - write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); + write_nic_byte(priv, rOFDM0_RxDetector1, 0x42); #else - write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20); + write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20); #endif /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) - write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); + write_nic_byte(priv, rOFDM0_RxDetector1, 0x42); */ } else - write_nic_byte(dev, rOFDM0_RxDetector1, 0x44); + write_nic_byte(priv, rOFDM0_RxDetector1, 0x44); } } @@ -1887,7 +1887,7 @@ static void dm_initial_gain( reset_cnt = priv->reset_count; } - if(dm_digtable.pre_ig_value != read_nic_byte(dev, rOFDM0_XAAGCCore1)) + if(dm_digtable.pre_ig_value != read_nic_byte(priv, rOFDM0_XAAGCCore1)) force_write = 1; { @@ -1896,10 +1896,10 @@ static void dm_initial_gain( { initial_gain = (u8)dm_digtable.cur_ig_value; // Set initial gain. - write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain); - write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain); - write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain); - write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain); + write_nic_byte(priv, rOFDM0_XAAGCCore1, initial_gain); + write_nic_byte(priv, rOFDM0_XBAGCCore1, initial_gain); + write_nic_byte(priv, rOFDM0_XCAGCCore1, initial_gain); + write_nic_byte(priv, rOFDM0_XDAGCCore1, initial_gain); dm_digtable.pre_ig_value = dm_digtable.cur_ig_value; initialized = 1; force_write = 0; @@ -1963,16 +1963,16 @@ static void dm_pd_th( /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. #ifdef RTL8190P - write_nic_byte(dev, rOFDM0_RxDetector1, 0x40); + write_nic_byte(priv, rOFDM0_RxDetector1, 0x40); #else - write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00); + write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x00); #endif /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) write_nic_byte(dev, rOFDM0_RxDetector1, 0x40); */ } else - write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); + write_nic_byte(priv, rOFDM0_RxDetector1, 0x42); } else if(dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER) { @@ -1982,16 +1982,16 @@ static void dm_pd_th( /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. #ifdef RTL8190P - write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); + write_nic_byte(priv, rOFDM0_RxDetector1, 0x42); #else - write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20); + write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20); #endif /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) - write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); + write_nic_byte(priv, rOFDM0_RxDetector1, 0x42); */ } else - write_nic_byte(dev, rOFDM0_RxDetector1, 0x44); + write_nic_byte(priv, rOFDM0_RxDetector1, 0x44); } else if(dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) { @@ -1999,16 +1999,16 @@ static void dm_pd_th( if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) { #ifdef RTL8190P - write_nic_byte(dev, rOFDM0_RxDetector1, 0x41); + write_nic_byte(priv, rOFDM0_RxDetector1, 0x41); #else - write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10); + write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x10); #endif /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) - write_nic_byte(dev, rOFDM0_RxDetector1, 0x41); + write_nic_byte(priv, rOFDM0_RxDetector1, 0x41); */ } else - write_nic_byte(dev, rOFDM0_RxDetector1, 0x43); + write_nic_byte(priv, rOFDM0_RxDetector1, 0x43); } dm_digtable.prepd_thstate = dm_digtable.curpd_thstate; if(initialized <= 3) @@ -2066,12 +2066,12 @@ static void dm_cs_ratio( if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER) { // Lower CS ratio for CCK. - write_nic_byte(dev, 0xa0a, 0x08); + write_nic_byte(priv, 0xa0a, 0x08); } else if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER) { // Higher CS ratio for CCK. - write_nic_byte(dev, 0xa0a, 0xcd); + write_nic_byte(priv, 0xa0a, 0xcd); } dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state; initialized = 1; @@ -2124,7 +2124,7 @@ static void dm_check_edca_turbo( { if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) { - write_nic_dword(dev, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]); + write_nic_dword(priv, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]); priv->bis_cur_rdlstate = true; } } @@ -2132,7 +2132,7 @@ static void dm_check_edca_turbo( { if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) { - write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]); + write_nic_dword(priv, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]); priv->bis_cur_rdlstate = false; } @@ -2164,7 +2164,7 @@ static void dm_check_edca_turbo( ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET)); printk("===>u4bAcParam:%x, ", u4bAcParam); //write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam); - write_nic_dword(dev, EDCAPARA_BE, u4bAcParam); + write_nic_dword(priv, EDCAPARA_BE, u4bAcParam); // Check ACM bit. // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13. @@ -2172,7 +2172,7 @@ static void dm_check_edca_turbo( // TODO: Modified this part and try to set acm control in only 1 IO processing!! PACI_AIFSN pAciAifsn = (PACI_AIFSN)&(qos_parameters->aifs[0]); - u8 AcmCtrl = read_nic_byte( dev, AcmHwCtrl ); + u8 AcmCtrl = read_nic_byte(priv, AcmHwCtrl ); if( pAciAifsn->f.ACM ) { // ACM bit is 1. AcmCtrl |= AcmHw_BeqEn; @@ -2183,7 +2183,7 @@ static void dm_check_edca_turbo( } RT_TRACE( COMP_QOS,"SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl ) ; - write_nic_byte(dev, AcmHwCtrl, AcmCtrl ); + write_nic_byte(priv, AcmHwCtrl, AcmCtrl ); } } priv->bcurrent_turbo_EDCA = false; @@ -2292,7 +2292,7 @@ static void dm_check_pbc_gpio(struct net_device *dev) u8 tmp1byte; - tmp1byte = read_nic_byte(dev,GPI); + tmp1byte = read_nic_byte(priv, GPI); if(tmp1byte == 0xff) return; @@ -2323,7 +2323,7 @@ void dm_gpio_change_rf_callback(struct work_struct *work) } else { // 0x108 GPIO input register is read only //set 0x108 B1= 1: RF-ON; 0: RF-OFF. - tmp1byte = read_nic_byte(dev,GPI); + tmp1byte = read_nic_byte(priv, GPI); eRfPowerStateToSet = (tmp1byte&BIT1) ? eRfOn : eRfOff; @@ -2362,7 +2362,7 @@ void dm_rf_pathcheck_workitemcallback(struct work_struct *work) /* 2008/01/30 MH After discussing with SD3 Jerry, 0xc04/0xd04 register will always be the same. We only read 0xc04 now. */ - rfpath = read_nic_byte(dev, 0xc04); + rfpath = read_nic_byte(priv, 0xc04); // Check Bit 0-3, it means if RF A-D is enabled. for (i = 0; i < RF90_PATH_MAX; i++) @@ -2418,12 +2418,12 @@ static void dm_rxpath_sel_byrssi(struct net_device * dev) if(!cck_Rx_Path_initialized) { - DM_RxPathSelTable.cck_Rx_path = (read_nic_byte(dev, 0xa07)&0xf); + DM_RxPathSelTable.cck_Rx_path = (read_nic_byte(priv, 0xa07)&0xf); cck_Rx_Path_initialized = 1; } DM_RxPathSelTable.disabledRF = 0xf; - DM_RxPathSelTable.disabledRF &=~ (read_nic_byte(dev, 0xc04)); + DM_RxPathSelTable.disabledRF &=~ (read_nic_byte(priv, 0xc04)); if(priv->ieee80211->mode == WIRELESS_MODE_B) { @@ -2700,7 +2700,6 @@ static void dm_deInit_fsync(struct net_device *dev) void dm_fsync_timer_callback(unsigned long data) { - struct net_device *dev = (struct net_device *)data; struct r8192_priv *priv = ieee80211_priv((struct net_device *)data); u32 rate_index, rate_count = 0, rate_count_diff=0; bool bSwitchFromCountDiff = false; @@ -2763,20 +2762,20 @@ void dm_fsync_timer_callback(unsigned long data) if(priv->bswitch_fsync) { #ifdef RTL8190P - write_nic_byte(dev,0xC36, 0x00); + write_nic_byte(priv,0xC36, 0x00); #else - write_nic_byte(dev,0xC36, 0x1c); + write_nic_byte(priv,0xC36, 0x1c); #endif - write_nic_byte(dev, 0xC3e, 0x90); + write_nic_byte(priv, 0xC3e, 0x90); } else { #ifdef RTL8190P - write_nic_byte(dev, 0xC36, 0x40); + write_nic_byte(priv, 0xC36, 0x40); #else - write_nic_byte(dev, 0xC36, 0x5c); + write_nic_byte(priv, 0xC36, 0x5c); #endif - write_nic_byte(dev, 0xC3e, 0x96); + write_nic_byte(priv, 0xC3e, 0x96); } } else if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold) @@ -2785,11 +2784,11 @@ void dm_fsync_timer_callback(unsigned long data) { priv->bswitch_fsync = false; #ifdef RTL8190P - write_nic_byte(dev, 0xC36, 0x40); + write_nic_byte(priv, 0xC36, 0x40); #else - write_nic_byte(dev, 0xC36, 0x5c); + write_nic_byte(priv, 0xC36, 0x5c); #endif - write_nic_byte(dev, 0xC3e, 0x96); + write_nic_byte(priv, 0xC3e, 0x96); } } if(bDoubleTimeInterval){ @@ -2812,17 +2811,17 @@ void dm_fsync_timer_callback(unsigned long data) { priv->bswitch_fsync = false; #ifdef RTL8190P - write_nic_byte(dev, 0xC36, 0x40); + write_nic_byte(priv, 0xC36, 0x40); #else - write_nic_byte(dev, 0xC36, 0x5c); + write_nic_byte(priv, 0xC36, 0x5c); #endif - write_nic_byte(dev, 0xC3e, 0x96); + write_nic_byte(priv, 0xC3e, 0x96); } priv->ContiuneDiffCount = 0; #ifdef RTL8190P - write_nic_dword(dev, rOFDM0_RxDetector2, 0x164052cd); + write_nic_dword(priv, rOFDM0_RxDetector2, 0x164052cd); #else - write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); + write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd); #endif } RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount); @@ -2831,9 +2830,11 @@ void dm_fsync_timer_callback(unsigned long data) static void dm_StartHWFsync(struct net_device *dev) { + struct r8192_priv *priv = ieee80211_priv(dev); + RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__); - write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cf); - write_nic_byte(dev, 0xc3b, 0x41); + write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c12cf); + write_nic_byte(priv, 0xc3b, 0x41); } static void dm_EndSWFsync(struct net_device *dev) @@ -2849,17 +2850,17 @@ static void dm_EndSWFsync(struct net_device *dev) priv->bswitch_fsync = false; #ifdef RTL8190P - write_nic_byte(dev, 0xC36, 0x40); + write_nic_byte(priv, 0xC36, 0x40); #else - write_nic_byte(dev, 0xC36, 0x5c); + write_nic_byte(priv, 0xC36, 0x5c); #endif - write_nic_byte(dev, 0xC3e, 0x96); + write_nic_byte(priv, 0xC3e, 0x96); } priv->ContiuneDiffCount = 0; #ifndef RTL8190P - write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); + write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd); #endif } @@ -2900,17 +2901,18 @@ static void dm_StartSWFsync(struct net_device *dev) add_timer(&priv->fsync_timer); #ifndef RTL8190P - write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd); + write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c12cd); #endif } static void dm_EndHWFsync(struct net_device *dev) { - RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__); - write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); - write_nic_byte(dev, 0xc3b, 0x49); + struct r8192_priv *priv = ieee80211_priv(dev); + RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__); + write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd); + write_nic_byte(priv, 0xc3b, 0x49); } void dm_check_fsync(struct net_device *dev) @@ -2971,9 +2973,9 @@ void dm_check_fsync(struct net_device *dev) if(reg_c38_State != RegC38_Fsync_AP_BCM) { //For broadcom AP we write different default value #ifdef RTL8190P - write_nic_byte(dev, rOFDM0_RxDetector3, 0x15); + write_nic_byte(priv, rOFDM0_RxDetector3, 0x15); #else - write_nic_byte(dev, rOFDM0_RxDetector3, 0x95); + write_nic_byte(priv, rOFDM0_RxDetector3, 0x95); #endif reg_c38_State = RegC38_Fsync_AP_BCM; @@ -3006,9 +3008,9 @@ void dm_check_fsync(struct net_device *dev) if(reg_c38_State != RegC38_NonFsync_Other_AP) { #ifdef RTL8190P - write_nic_byte(dev, rOFDM0_RxDetector3, 0x10); + write_nic_byte(priv, rOFDM0_RxDetector3, 0x10); #else - write_nic_byte(dev, rOFDM0_RxDetector3, 0x90); + write_nic_byte(priv, rOFDM0_RxDetector3, 0x90); #endif reg_c38_State = RegC38_NonFsync_Other_AP; @@ -3018,7 +3020,7 @@ void dm_check_fsync(struct net_device *dev) { if(reg_c38_State) { - write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); + write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync); reg_c38_State = RegC38_Default; } } @@ -3027,7 +3029,7 @@ void dm_check_fsync(struct net_device *dev) { if(reg_c38_State) { - write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); + write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync); reg_c38_State = RegC38_Default; } } @@ -3037,7 +3039,7 @@ void dm_check_fsync(struct net_device *dev) { if(priv->reset_count != reset_cnt) { //After silent reset, the reg_c38_State will be returned to default value - write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); + write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync); reg_c38_State = RegC38_Default; reset_cnt = priv->reset_count; } @@ -3046,7 +3048,7 @@ void dm_check_fsync(struct net_device *dev) { if(reg_c38_State) { - write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync); + write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync); reg_c38_State = RegC38_Default; } } @@ -3143,9 +3145,9 @@ static void dm_check_txrateandretrycount(struct net_device * dev) struct r8192_priv *priv = ieee80211_priv(dev); struct ieee80211_device* ieee = priv->ieee80211; //for initial tx rate - ieee->softmac_stats.last_packet_rate = read_nic_byte(dev ,Initial_Tx_Rate_Reg); + ieee->softmac_stats.last_packet_rate = read_nic_byte(priv ,Initial_Tx_Rate_Reg); //for tx tx retry count - ieee->softmac_stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg); + ieee->softmac_stats.txretrycount = read_nic_dword(priv, Tx_Retry_Count_Reg); } static void dm_send_rssi_tofw(struct net_device *dev) @@ -3156,7 +3158,7 @@ static void dm_send_rssi_tofw(struct net_device *dev) // If we test chariot, we should stop the TX command ? // Because 92E will always silent reset when we send tx command. We use register // 0x1e0(byte) to botify driver. - write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb); + write_nic_byte(priv, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb); return; #if 1 tx_cmd.Op = TXCMD_SET_RX_RSSI; diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c index 7b5ac0d26812..c6239bba10e2 100644 --- a/drivers/staging/rtl8192e/r8192E_wx.c +++ b/drivers/staging/rtl8192e/r8192E_wx.c @@ -985,7 +985,7 @@ static int r8192_wx_set_enc_ext(struct net_device *dev, else //pairwise key { if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){ - write_nic_byte(dev, 0x173, 1); //fix aes bug + write_nic_byte(priv, 0x173, 1); //fix aes bug } setKey( dev, 4,//EntryNo diff --git a/drivers/staging/rtl8192e/r8192_pm.c b/drivers/staging/rtl8192e/r8192_pm.c index c691bc9d88bb..75e16289d7fc 100644 --- a/drivers/staging/rtl8192e/r8192_pm.c +++ b/drivers/staging/rtl8192e/r8192_pm.c @@ -43,7 +43,7 @@ int rtl8192E_suspend (struct pci_dev *pdev, pm_message_t state) ieee80211_softmac_stop_protocol(priv->ieee80211); - write_nic_byte(dev,MSR,(read_nic_byte(dev,MSR)&0xfc)|MSR_LINK_NONE); + write_nic_byte(priv, MSR,(read_nic_byte(dev,MSR)&0xfc)|MSR_LINK_NONE); if(!priv->ieee80211->bSupportRemoteWakeUp) { /* disable tx/rx. In 8185 we write 0x10 (Reset bit), * but here we make reference to WMAC and wirte 0x0. @@ -76,24 +76,24 @@ pHalData->bHwRfOffAction = 2; if(!priv->ieee80211->bSupportRemoteWakeUp) { MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT); // 2006.11.30. System reset bit - ulRegRead = read_nic_dword(dev, CPU_GEN); + ulRegRead = read_nic_dword(priv, CPU_GEN); ulRegRead|=CPU_GEN_SYSTEM_RESET; - write_nic_dword(dev, CPU_GEN, ulRegRead); + write_nic_dword(priv, CPU_GEN, ulRegRead); } else { //2008.06.03 for WOL - write_nic_dword(dev, WFCRC0, 0xffffffff); - write_nic_dword(dev, WFCRC1, 0xffffffff); - write_nic_dword(dev, WFCRC2, 0xffffffff); + write_nic_dword(priv, WFCRC0, 0xffffffff); + write_nic_dword(priv, WFCRC1, 0xffffffff); + write_nic_dword(priv, WFCRC2, 0xffffffff); #ifdef RTL8190P //GPIO 0 = TRUE - ucRegRead = read_nic_byte(dev, GPO); + ucRegRead = read_nic_byte(priv, GPO); ucRegRead |= BIT0; - write_nic_byte(dev, GPO, ucRegRead); + write_nic_byte(priv, GPO, ucRegRead); #endif //Write PMR register - write_nic_byte(dev, PMR, 0x5); + write_nic_byte(priv, PMR, 0x5); //Disable tx, enanble rx - write_nic_byte(dev, MacBlkCtrl, 0xa); + write_nic_byte(priv, MacBlkCtrl, 0xa); } out_pci_suspend: diff --git a/drivers/staging/rtl8192e/r819xE_firmware.c b/drivers/staging/rtl8192e/r819xE_firmware.c index e335b815ca00..d1da2697cfe7 100644 --- a/drivers/staging/rtl8192e/r819xE_firmware.c +++ b/drivers/staging/rtl8192e/r819xE_firmware.c @@ -115,6 +115,7 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, */ static bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev) { + struct r8192_priv *priv = ieee80211_priv(dev); unsigned long timeout; bool rt_status = true; u32 CPU_status = 0; @@ -122,7 +123,7 @@ static bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev) /* Check whether put code OK */ timeout = jiffies + msecs_to_jiffies(20); while (time_before(jiffies, timeout)) { - CPU_status = read_nic_dword(dev, CPU_GEN); + CPU_status = read_nic_dword(priv, CPU_GEN); if (CPU_status & CPU_GEN_PUT_CODE_OK) break; @@ -137,15 +138,15 @@ static bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev) } /* Turn On CPU */ - CPU_status = read_nic_dword(dev, CPU_GEN); - write_nic_byte(dev, CPU_GEN, + CPU_status = read_nic_dword(priv, CPU_GEN); + write_nic_byte(priv, CPU_GEN, (u8)((CPU_status | CPU_GEN_PWR_STB_CPU) & 0xff)); mdelay(1); /* Check whether CPU boot OK */ timeout = jiffies + msecs_to_jiffies(20); while (time_before(jiffies, timeout)) { - CPU_status = read_nic_dword(dev, CPU_GEN); + CPU_status = read_nic_dword(priv, CPU_GEN); if (CPU_status & CPU_GEN_BOOT_RDY) break; @@ -167,6 +168,7 @@ CPUCheckMainCodeOKAndTurnOnCPU_Fail: static bool CPUcheck_firmware_ready(struct net_device *dev) { + struct r8192_priv *priv = ieee80211_priv(dev); unsigned long timeout; bool rt_status = true; u32 CPU_status = 0; @@ -174,7 +176,7 @@ static bool CPUcheck_firmware_ready(struct net_device *dev) /* Check Firmware Ready */ timeout = jiffies + msecs_to_jiffies(20); while (time_before(jiffies, timeout)) { - CPU_status = read_nic_dword(dev, CPU_GEN); + CPU_status = read_nic_dword(priv, CPU_GEN); if (CPU_status & CPU_GEN_FIRM_RDY) break; diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c index f75c907fd002..bcd1eda77952 100644 --- a/drivers/staging/rtl8192e/r819xE_phy.c +++ b/drivers/staging/rtl8192e/r819xE_phy.c @@ -1466,17 +1466,17 @@ u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath) * ****************************************************************************/ void rtl8192_setBBreg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask, u32 dwData) { - + struct r8192_priv *priv = ieee80211_priv(dev); u32 OriginalValue, BitShift, NewValue; if(dwBitMask!= bMaskDWord) {//if not "double word" write - OriginalValue = read_nic_dword(dev, dwRegAddr); + OriginalValue = read_nic_dword(priv, dwRegAddr); BitShift = rtl8192_CalculateBitShift(dwBitMask); NewValue = (((OriginalValue) & (~dwBitMask)) | (dwData << BitShift)); - write_nic_dword(dev, dwRegAddr, NewValue); + write_nic_dword(priv, dwRegAddr, NewValue); }else - write_nic_dword(dev, dwRegAddr, dwData); + write_nic_dword(priv, dwRegAddr, dwData); } /****************************************************************************** *function: This function reads specific bits from BB register @@ -1489,9 +1489,10 @@ void rtl8192_setBBreg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask, u32 * ****************************************************************************/ u32 rtl8192_QueryBBReg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask) { + struct r8192_priv *priv = ieee80211_priv(dev); u32 OriginalValue, BitShift; - OriginalValue = read_nic_dword(dev, dwRegAddr); + OriginalValue = read_nic_dword(priv, dwRegAddr); BitShift = rtl8192_CalculateBitShift(dwBitMask); return (OriginalValue & dwBitMask) >> BitShift; } @@ -1808,6 +1809,7 @@ static u32 phy_FwRFSerialRead( RF90_RADIO_PATH_E eRFPath, u32 Offset ) { + struct r8192_priv *priv = ieee80211_priv(dev); u32 Data = 0; u8 time = 0; //DbgPrint("FW RF CTRL\n\r"); @@ -1825,7 +1827,7 @@ static u32 phy_FwRFSerialRead( // 5. Trigger Fw to operate the command. bit 31 Data |= 0x80000000; // 6. We can not execute read operation if bit 31 is 1. - while (read_nic_dword(dev, QPNR)&0x80000000) + while (read_nic_dword(priv, QPNR)&0x80000000) { // If FW can not finish RF-R/W for more than ?? times. We must reset FW. if (time++ < 100) @@ -1837,9 +1839,9 @@ static u32 phy_FwRFSerialRead( break; } // 7. Execute read operation. - write_nic_dword(dev, QPNR, Data); + write_nic_dword(priv, QPNR, Data); // 8. Check if firmawre send back RF content. - while (read_nic_dword(dev, QPNR)&0x80000000) + while (read_nic_dword(priv, QPNR)&0x80000000) { // If FW can not finish RF-R/W for more than ?? times. We must reset FW. if (time++ < 100) @@ -1850,7 +1852,7 @@ static u32 phy_FwRFSerialRead( else return 0; } - return read_nic_dword(dev, RF_DATA); + return read_nic_dword(priv, RF_DATA); } /****************************************************************************** @@ -1867,6 +1869,7 @@ phy_FwRFSerialWrite( u32 Offset, u32 Data ) { + struct r8192_priv *priv = ieee80211_priv(dev); u8 time = 0; //DbgPrint("N FW RF CTRL RF-%d OF%02x DATA=%03x\n\r", eRFPath, Offset, Data); @@ -1886,7 +1889,7 @@ phy_FwRFSerialWrite( Data |= 0x80000000; // 6. Write operation. We can not write if bit 31 is 1. - while (read_nic_dword(dev, QPNR)&0x80000000) + while (read_nic_dword(priv, QPNR)&0x80000000) { // If FW can not finish RF-R/W for more than ?? times. We must reset FW. if (time++ < 100) @@ -1899,7 +1902,7 @@ phy_FwRFSerialWrite( } // 7. No matter check bit. We always force the write. Because FW will // not accept the command. - write_nic_dword(dev, QPNR, Data); + write_nic_dword(priv, QPNR, Data); /* 2007/11/02 MH Acoording to test, we must delay 20us to wait firmware to finish RF write operation. */ /* 2008/01/17 MH We support delay in firmware side now. */ @@ -2151,7 +2154,7 @@ static void rtl8192_InitBBRFRegDef(struct net_device* dev) * ***************************************************************************/ RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath) { - //struct r8192_priv *priv = ieee80211_priv(dev); + struct r8192_priv *priv = ieee80211_priv(dev); // BB_REGISTER_DEFINITION_T *pPhyReg = &priv->PHYRegDef[eRFPath]; RT_STATUS ret = RT_STATUS_SUCCESS; u32 i, CheckTimes = 4, dwRegRead = 0; @@ -2177,8 +2180,8 @@ RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlo case HW90_BLOCK_PHY0: case HW90_BLOCK_PHY1: - write_nic_dword(dev, WriteAddr[CheckBlock], WriteData[i]); - dwRegRead = read_nic_dword(dev, WriteAddr[CheckBlock]); + write_nic_dword(priv, WriteAddr[CheckBlock], WriteData[i]); + dwRegRead = read_nic_dword(priv, WriteAddr[CheckBlock]); break; case HW90_BLOCK_RF: @@ -2230,12 +2233,12 @@ static RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device* dev) **************************************/ /*--set BB Global Reset--*/ - bRegValue = read_nic_byte(dev, BB_GLOBAL_RESET); - write_nic_byte(dev, BB_GLOBAL_RESET,(bRegValue|BB_GLOBAL_RESET_BIT)); + bRegValue = read_nic_byte(priv, BB_GLOBAL_RESET); + write_nic_byte(priv, BB_GLOBAL_RESET,(bRegValue|BB_GLOBAL_RESET_BIT)); /*---set BB reset Active---*/ - dwRegValue = read_nic_dword(dev, CPU_GEN); - write_nic_dword(dev, CPU_GEN, (dwRegValue&(~CPU_GEN_BB_RST))); + dwRegValue = read_nic_dword(priv, CPU_GEN); + write_nic_dword(priv, CPU_GEN, (dwRegValue&(~CPU_GEN_BB_RST))); /*----Ckeck FPGAPHY0 and PHY1 board is OK----*/ // TODO: this function should be removed on ASIC , Emily 2007.2.2 @@ -2255,8 +2258,8 @@ static RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device* dev) rtl8192_phyConfigBB(dev, BaseBand_Config_PHY_REG); /*----Set BB reset de-Active----*/ - dwRegValue = read_nic_dword(dev, CPU_GEN); - write_nic_dword(dev, CPU_GEN, (dwRegValue|CPU_GEN_BB_RST)); + dwRegValue = read_nic_dword(priv, CPU_GEN); + write_nic_dword(priv, CPU_GEN, (dwRegValue|CPU_GEN_BB_RST)); /*----BB AGC table Initialization----*/ //==m==>Set PHY REG From Header<==m== @@ -2324,44 +2327,44 @@ void rtl8192_phy_getTxPower(struct net_device* dev) struct r8192_priv *priv = ieee80211_priv(dev); #ifdef RTL8190P priv->MCSTxPowerLevelOriginalOffset[0] = - read_nic_dword(dev, MCS_TXAGC); + read_nic_dword(priv, MCS_TXAGC); priv->MCSTxPowerLevelOriginalOffset[1] = - read_nic_dword(dev, (MCS_TXAGC+4)); + read_nic_dword(priv, (MCS_TXAGC+4)); priv->CCKTxPowerLevelOriginalOffset = - read_nic_dword(dev, CCK_TXAGC); + read_nic_dword(priv, CCK_TXAGC); #else #ifdef RTL8192E priv->MCSTxPowerLevelOriginalOffset[0] = - read_nic_dword(dev, rTxAGC_Rate18_06); + read_nic_dword(priv, rTxAGC_Rate18_06); priv->MCSTxPowerLevelOriginalOffset[1] = - read_nic_dword(dev, rTxAGC_Rate54_24); + read_nic_dword(priv, rTxAGC_Rate54_24); priv->MCSTxPowerLevelOriginalOffset[2] = - read_nic_dword(dev, rTxAGC_Mcs03_Mcs00); + read_nic_dword(priv, rTxAGC_Mcs03_Mcs00); priv->MCSTxPowerLevelOriginalOffset[3] = - read_nic_dword(dev, rTxAGC_Mcs07_Mcs04); + read_nic_dword(priv, rTxAGC_Mcs07_Mcs04); priv->MCSTxPowerLevelOriginalOffset[4] = - read_nic_dword(dev, rTxAGC_Mcs11_Mcs08); + read_nic_dword(priv, rTxAGC_Mcs11_Mcs08); priv->MCSTxPowerLevelOriginalOffset[5] = - read_nic_dword(dev, rTxAGC_Mcs15_Mcs12); + read_nic_dword(priv, rTxAGC_Mcs15_Mcs12); #endif #endif // read rx initial gain - priv->DefaultInitialGain[0] = read_nic_byte(dev, rOFDM0_XAAGCCore1); - priv->DefaultInitialGain[1] = read_nic_byte(dev, rOFDM0_XBAGCCore1); - priv->DefaultInitialGain[2] = read_nic_byte(dev, rOFDM0_XCAGCCore1); - priv->DefaultInitialGain[3] = read_nic_byte(dev, rOFDM0_XDAGCCore1); + priv->DefaultInitialGain[0] = read_nic_byte(priv, rOFDM0_XAAGCCore1); + priv->DefaultInitialGain[1] = read_nic_byte(priv, rOFDM0_XBAGCCore1); + priv->DefaultInitialGain[2] = read_nic_byte(priv, rOFDM0_XCAGCCore1); + priv->DefaultInitialGain[3] = read_nic_byte(priv, rOFDM0_XDAGCCore1); RT_TRACE(COMP_INIT, "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x) \n", priv->DefaultInitialGain[0], priv->DefaultInitialGain[1], priv->DefaultInitialGain[2], priv->DefaultInitialGain[3]); // read framesync - priv->framesync = read_nic_byte(dev, rOFDM0_RxDetector3); - priv->framesyncC34 = read_nic_dword(dev, rOFDM0_RxDetector2); + priv->framesync = read_nic_byte(priv, rOFDM0_RxDetector3); + priv->framesyncC34 = read_nic_dword(priv, rOFDM0_RxDetector2); RT_TRACE(COMP_INIT, "Default framesync (0x%x) = 0x%x \n", rOFDM0_RxDetector3, priv->framesync); // read SIFS (save the value read fome MACPHY_REG.txt) - priv->SifsTime = read_nic_word(dev, SIFS); + priv->SifsTime = read_nic_word(priv, SIFS); } /****************************************************************************** @@ -2807,13 +2810,13 @@ static u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, u8* s rtl8192_SetTxPowerLevel(dev,channel); break; case CmdID_WritePortUlong: - write_nic_dword(dev, CurrentCmd->Para1, CurrentCmd->Para2); + write_nic_dword(priv, CurrentCmd->Para1, CurrentCmd->Para2); break; case CmdID_WritePortUshort: - write_nic_word(dev, CurrentCmd->Para1, (u16)CurrentCmd->Para2); + write_nic_word(priv, CurrentCmd->Para1, (u16)CurrentCmd->Para2); break; case CmdID_WritePortUchar: - write_nic_byte(dev, CurrentCmd->Para1, (u8)CurrentCmd->Para2); + write_nic_byte(priv, CurrentCmd->Para1, (u8)CurrentCmd->Para2); break; case CmdID_RF_WriteReg: for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) @@ -3080,20 +3083,20 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) return; } //<1>Set MAC register - regBwOpMode = read_nic_byte(dev, BW_OPMODE); + regBwOpMode = read_nic_byte(priv, BW_OPMODE); switch(priv->CurrentChannelBW) { case HT_CHANNEL_WIDTH_20: regBwOpMode |= BW_OPMODE_20MHZ; // 2007/02/07 Mark by Emily becasue we have not verify whether this register works - write_nic_byte(dev, BW_OPMODE, regBwOpMode); + write_nic_byte(priv, BW_OPMODE, regBwOpMode); break; case HT_CHANNEL_WIDTH_20_40: regBwOpMode &= ~BW_OPMODE_20MHZ; // 2007/02/07 Mark by Emily becasue we have not verify whether this register works - write_nic_byte(dev, BW_OPMODE, regBwOpMode); + write_nic_byte(priv, BW_OPMODE, regBwOpMode); break; default: @@ -3116,9 +3119,9 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) // write_nic_dword(dev, rCCK0_DebugPort, 0x00000204); if(!priv->btxpower_tracking) { - write_nic_dword(dev, rCCK0_TxFilter1, 0x1a1b0000); - write_nic_dword(dev, rCCK0_TxFilter2, 0x090e1317); - write_nic_dword(dev, rCCK0_DebugPort, 0x00000204); + write_nic_dword(priv, rCCK0_TxFilter1, 0x1a1b0000); + write_nic_dword(priv, rCCK0_TxFilter2, 0x090e1317); + write_nic_dword(priv, rCCK0_DebugPort, 0x00000204); } else CCK_Tx_Power_Track_BW_Switch(dev); @@ -3147,9 +3150,9 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) //write_nic_dword(dev, rCCK0_DebugPort, 0x00000409); if(!priv->btxpower_tracking) { - write_nic_dword(dev, rCCK0_TxFilter1, 0x35360000); - write_nic_dword(dev, rCCK0_TxFilter2, 0x121c252e); - write_nic_dword(dev, rCCK0_DebugPort, 0x00000409); + write_nic_dword(priv, rCCK0_TxFilter1, 0x35360000); + write_nic_dword(priv, rCCK0_TxFilter2, 0x121c252e); + write_nic_dword(priv, rCCK0_DebugPort, 0x00000409); } else CCK_Tx_Power_Track_BW_Switch(dev); @@ -3288,12 +3291,12 @@ void InitialGain819xPci(struct net_device *dev, u8 Operation) RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca); RT_TRACE(COMP_SCAN, "Write scan initial gain = 0x%x \n", initial_gain); - write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain); - write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain); - write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain); - write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain); + write_nic_byte(priv, rOFDM0_XAAGCCore1, initial_gain); + write_nic_byte(priv, rOFDM0_XBAGCCore1, initial_gain); + write_nic_byte(priv, rOFDM0_XCAGCCore1, initial_gain); + write_nic_byte(priv, rOFDM0_XDAGCCore1, initial_gain); RT_TRACE(COMP_SCAN, "Write scan 0xa0a = 0x%x \n", POWER_DETECTION_TH); - write_nic_byte(dev, 0xa0a, POWER_DETECTION_TH); + write_nic_byte(priv, 0xa0a, POWER_DETECTION_TH); break; case IG_Restore: RT_TRACE(COMP_SCAN, "IG_Restore, restore the initial gain.\n"); -- cgit v1.2.3 From 679b5f674f989c95c9e591dc6c429a60226e3659 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 6 Feb 2011 22:53:45 +0900 Subject: staging: rtl8192e: Remove dead code Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_dm.c | 29 ----------------- drivers/staging/rtl8192e/r8192E_wx.c | 56 +------------------------------- drivers/staging/rtl8192e/r8192_pm.c | 38 ---------------------- drivers/staging/rtl8192e/r819xE_cmdpkt.c | 51 +---------------------------- 4 files changed, 2 insertions(+), 172 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index d328d6766a77..20d9c0b8a127 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -440,12 +440,9 @@ static void dm_check_rate_adaptive(struct net_device * dev) } } - // 2008.04.01 -#if 1 // For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7. if(priv->ieee80211->GetHalfNmodeSupportByAPsHandler(dev)) targetRATR &= 0xf00fffff; -#endif // // Check whether updating of RATR0 is required @@ -2088,7 +2085,6 @@ void dm_init_edca_turbo(struct net_device *dev) priv->bis_cur_rdlstate = false; } -#if 1 static void dm_check_edca_turbo( struct net_device * dev) { @@ -2106,10 +2102,8 @@ static void dm_check_edca_turbo( // Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters // should follow the settings from QAP. By Bruce, 2007-12-07. // - #if 1 if(priv->ieee80211->state != IEEE80211_LINKED) goto dm_CheckEdcaTurbo_EXIT; - #endif // We do not turn on EDCA turbo mode for some AP that has IOT issue if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO) goto dm_CheckEdcaTurbo_EXIT; @@ -2197,7 +2191,6 @@ dm_CheckEdcaTurbo_EXIT: lastTxOkCnt = priv->stats.txbytesunicast; lastRxOkCnt = priv->stats.rxbytesunicast; } -#endif static void dm_init_ctstoself(struct net_device * dev) { @@ -2237,18 +2230,7 @@ static void dm_ctstoself(struct net_device *dev) } else //uplink { - #if 1 pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF; - #else - if(priv->undecorated_smoothed_pwdb < priv->ieee80211->CTSToSelfTH) // disable CTS to self - { - pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF; - } - else if(priv->undecorated_smoothed_pwdb >= (priv->ieee80211->CTSToSelfTH+5)) // enable CTS to self - { - pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF; - } - #endif } lastTxOkCnt = priv->stats.txbytesunicast; @@ -2259,7 +2241,6 @@ static void dm_ctstoself(struct net_device *dev) /* Copy 8187B template for 9xseries */ -#if 1 static void dm_check_rfctrl_gpio(struct net_device * dev) { #ifdef RTL8192E @@ -2283,7 +2264,6 @@ static void dm_check_rfctrl_gpio(struct net_device * dev) } -#endif /* Check if PBC button is pressed. */ static void dm_check_pbc_gpio(struct net_device *dev) { @@ -3152,7 +3132,6 @@ static void dm_check_txrateandretrycount(struct net_device * dev) static void dm_send_rssi_tofw(struct net_device *dev) { - DCMD_TXCMD_T tx_cmd; struct r8192_priv *priv = ieee80211_priv(dev); // If we test chariot, we should stop the TX command ? @@ -3160,13 +3139,5 @@ static void dm_send_rssi_tofw(struct net_device *dev) // 0x1e0(byte) to botify driver. write_nic_byte(priv, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb); return; -#if 1 - tx_cmd.Op = TXCMD_SET_RX_RSSI; - tx_cmd.Length = 4; - tx_cmd.Value = priv->undecorated_smoothed_pwdb; - - cmpk_message_handle_tx(dev, (u8*)&tx_cmd, - DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T)); -#endif } diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c index c6239bba10e2..a2e943293a79 100644 --- a/drivers/staging/rtl8192e/r8192E_wx.c +++ b/drivers/staging/rtl8192e/r8192E_wx.c @@ -693,20 +693,6 @@ static int r8192_wx_set_enc(struct net_device *dev, zero_addr[key_idx], 0, //DefaultKey hwkey); //KeyContent - -#if 0 - if(key_idx == 0){ - - //write_nic_byte(dev, SECR, 7); - setKey( dev, - 4, //EntryNo - key_idx, //KeyIndex - KEY_TYPE_WEP40, //KeyType - broadcast_addr, //addr - 0, //DefaultKey - hwkey); //KeyContent - } -#endif } else if(wrqu->encoding.length==0xd){ @@ -719,43 +705,9 @@ static int r8192_wx_set_enc(struct net_device *dev, zero_addr[key_idx], 0, //DefaultKey hwkey); //KeyContent -#if 0 - if(key_idx == 0){ - - //write_nic_byte(dev, SECR, 7); - setKey( dev, - 4, //EntryNo - key_idx, //KeyIndex - KEY_TYPE_WEP104, //KeyType - broadcast_addr, //addr - 0, //DefaultKey - hwkey); //KeyContent - } -#endif } else printk("wrong type in WEP, not WEP40 and WEP104\n"); - - - } - -#if 0 - //consider the setting different key index situation - //wrqu->encoding.flags = 801 means that we set key with index "1" - if(wrqu->encoding.length==0 && (wrqu->encoding.flags >>8) == 0x8 ){ - printk("===>1\n"); - //write_nic_byte(dev, SECR, 7); - EnableHWSecurityConfig8192(dev); - //copy wpa config from default key(key0~key3) to broadcast key(key5) - // - key_idx = (wrqu->encoding.flags & 0xf)-1 ; - write_cam(dev, (4*6), 0xffff0000|read_cam(dev, key_idx*6) ); - write_cam(dev, (4*6)+1, 0xffffffff); - write_cam(dev, (4*6)+2, read_cam(dev, (key_idx*6)+2) ); - write_cam(dev, (4*6)+3, read_cam(dev, (key_idx*6)+3) ); - write_cam(dev, (4*6)+4, read_cam(dev, (key_idx*6)+4) ); - write_cam(dev, (4*6)+5, read_cam(dev, (key_idx*6)+5) ); } -#endif priv->ieee80211->wx_set_enc = 0; @@ -929,14 +881,8 @@ static int r8192_wx_set_enc_ext(struct net_device *dev, u32 key[4] = {0}; struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; struct iw_point *encoding = &wrqu->encoding; -#if 0 - static u8 CAM_CONST_ADDR[4][6] = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}}; -#endif u8 idx = 0, alg = 0, group = 0; + if ((encoding->flags & IW_ENCODE_DISABLED) || ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01 { diff --git a/drivers/staging/rtl8192e/r8192_pm.c b/drivers/staging/rtl8192e/r8192_pm.c index 75e16289d7fc..8781735d5a35 100644 --- a/drivers/staging/rtl8192e/r8192_pm.c +++ b/drivers/staging/rtl8192e/r8192_pm.c @@ -36,43 +36,8 @@ int rtl8192E_suspend (struct pci_dev *pdev, pm_message_t state) if (dev->netdev_ops->ndo_stop) dev->netdev_ops->ndo_stop(dev); -// dev->stop(dev); -#if 0 - netif_carrier_off(dev); - - ieee80211_softmac_stop_protocol(priv->ieee80211); - - write_nic_byte(priv, MSR,(read_nic_byte(dev,MSR)&0xfc)|MSR_LINK_NONE); - if(!priv->ieee80211->bSupportRemoteWakeUp) { - /* disable tx/rx. In 8185 we write 0x10 (Reset bit), - * but here we make reference to WMAC and wirte 0x0. - * 2006.11.21 Emily - */ - write_nic_byte(dev, CMDR, 0); - } - //disable interrupt - write_nic_dword(dev,INTA_MASK,0); - priv->irq_enabled = 0; - write_nic_dword(dev,ISR,read_nic_dword(dev, ISR)); - - /* need to free DM related functions */ - cancel_work_sync(&priv->reset_wq); - del_timer_sync(&priv->fsync_timer); - del_timer_sync(&priv->watch_dog_timer); - cancel_delayed_work(&priv->watch_dog_wq); - cancel_delayed_work(&priv->update_beacon_wq); - cancel_work_sync(&priv->qos_activate); - - /* TODO -#if ((DEV_BUS_TYPE == PCI_INTERFACE) && (HAL_CODE_BASE == RTL8192)) -pHalData->bHwRfOffAction = 2; -#endif -*/ -#endif // Call MgntActSet_RF_State instead to prevent RF config race condition. - // By Bruce, 2008-01-17. - // if(!priv->ieee80211->bSupportRemoteWakeUp) { MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT); // 2006.11.30. System reset bit @@ -114,8 +79,6 @@ out_pci_suspend: int rtl8192E_resume (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); - //struct r8192_priv *priv = ieee80211_priv(dev); - //union iwreq_data wrqu; int err; u32 val; @@ -155,7 +118,6 @@ int rtl8192E_resume (struct pci_dev *pdev) if (dev->netdev_ops->ndo_open) dev->netdev_ops->ndo_open(dev); -// dev->open(dev); out: RT_TRACE(COMP_POWER, "<================r8192E resume call.\n"); return 0; diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.c b/drivers/staging/rtl8192e/r819xE_cmdpkt.c index 76beaa3beb7f..11ad7cf16f71 100644 --- a/drivers/staging/rtl8192e/r819xE_cmdpkt.c +++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.c @@ -189,55 +189,9 @@ cmpk_handle_tx_feedback( priv->stats.txfeedback++; - /* 0. Display received message. */ - //cmpk_Display_Message(CMPK_RX_TX_FB_SIZE, pMsg); - - /* 1. Extract TX feedback info from RFD to temp structure buffer. */ - /* It seems that FW use big endian(MIPS) and DRV use little endian in - windows OS. So we have to read the content byte by byte or transfer - endian type before copy the message copy. */ -#if 0 // The TX FEEDBACK packet element address - //rx_tx_fb.Element_ID = pMsg[0]; - //rx_tx_fb.Length = pMsg[1]; - rx_tx_fb.TOK = pMsg[2]>>7; - rx_tx_fb.Fail_Reason = (pMsg[2] & 0x70) >> 4; - rx_tx_fb.TID = (pMsg[2] & 0x0F); - rx_tx_fb.Qos_Pkt = pMsg[3] >> 7; - rx_tx_fb.Bandwidth = (pMsg[3] & 0x40) >> 6; - rx_tx_fb.Retry_Cnt = pMsg[5]; - rx_tx_fb.Pkt_ID = (pMsg[6] << 8) | pMsg[7]; - rx_tx_fb.Seq_Num = (pMsg[8] << 8) | pMsg[9]; - rx_tx_fb.S_Rate = pMsg[10]; - rx_tx_fb.F_Rate = pMsg[11]; - rx_tx_fb.S_RTS_Rate = pMsg[12]; - rx_tx_fb.F_RTS_Rate = pMsg[13]; - rx_tx_fb.pkt_length = (pMsg[14] << 8) | pMsg[15]; -#endif - /* 2007/07/05 MH Use pointer to transfer structure memory. */ - //memcpy((UINT8 *)&rx_tx_fb, pMsg, sizeof(CMPK_TXFB_T)); memcpy((u8*)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t)); - /* 2. Use tx feedback info to count TX statistics. */ + /* Use tx feedback info to count TX statistics. */ cmpk_count_txstatistic(dev, &rx_tx_fb); -#if 0 - /* 2007/07/11 MH Assign current operate rate. */ - if (pAdapter->RegWirelessMode == WIRELESS_MODE_A || - pAdapter->RegWirelessMode == WIRELESS_MODE_B || - pAdapter->RegWirelessMode == WIRELESS_MODE_G) - { - pMgntInfo->CurrentOperaRate = (rx_tx_fb.F_Rate & 0x7F); - } - else if (pAdapter->RegWirelessMode == WIRELESS_MODE_N_24G || - pAdapter->RegWirelessMode == WIRELESS_MODE_N_5G) - { - pMgntInfo->HTCurrentOperaRate = (rx_tx_fb.F_Rate & 0x8F); - } -#endif - /* 2007/01/17 MH Comment previous method for TX statistic function. */ - /* Collect info TX feedback packet to fill TCB. */ - /* We can not know the packet length and transmit type: broadcast or uni - or multicast. */ - //CountTxStatistics( pAdapter, &tcb ); - } @@ -257,9 +211,6 @@ cmpk_handle_interrupt_status( DMESG("---> cmpk_Handle_Interrupt_Status()\n"); - /* 0. Display received message. */ - //cmpk_Display_Message(CMPK_RX_BEACON_STATE_SIZE, pMsg); - /* 1. Extract TX feedback info from RFD to temp structure buffer. */ /* It seems that FW use big endian(MIPS) and DRV use little endian in windows OS. So we have to read the content byte by byte or transfer -- cgit v1.2.3 From aebbafddf78e148378eee71f9063f510e9a1cf05 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 6 Feb 2011 22:53:57 +0900 Subject: staging: rtl8192e: Remove dead code Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index b2c44a7af0cf..f177ad6d7843 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1055,11 +1055,9 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff* skb); u32 read_cam(struct r8192_priv *priv, u8 addr); void write_cam(struct r8192_priv *priv, u8 addr, u32 data); u8 read_nic_byte(struct r8192_priv *priv, int x); -u8 read_nic_byte_E(struct net_device *dev, int x); u32 read_nic_dword(struct r8192_priv *priv, int x); u16 read_nic_word(struct r8192_priv *priv, int x) ; void write_nic_byte(struct r8192_priv *priv, int x,u8 y); -void write_nic_byte_E(struct net_device *priv, int x,u8 y); void write_nic_word(struct r8192_priv *priv, int x,u16 y); void write_nic_dword(struct r8192_priv *priv, int x,u32 y); @@ -1067,11 +1065,6 @@ void rtl8192_halt_adapter(struct net_device *dev, bool reset); void rtl8192_rx_enable(struct net_device *); void rtl8192_tx_enable(struct net_device *); -void rtl8192_disassociate(struct net_device *dev); -void rtl8185_set_rf_pins_enable(struct net_device *dev,u32 a); - -void rtl8192_set_anaparam(struct net_device *dev,u32 a); -void rtl8185_set_anaparam2(struct net_device *dev,u32 a); void rtl8192_update_msr(struct net_device *dev); int rtl8192_down(struct net_device *dev); int rtl8192_up(struct net_device *dev); @@ -1080,8 +1073,6 @@ void rtl8192_set_chan(struct net_device *dev,short ch); void write_phy(struct net_device *dev, u8 adr, u8 data); void write_phy_cck(struct net_device *dev, u8 adr, u32 data); void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data); -void rtl8185_tx_antenna(struct net_device *dev, u8 ant); -void rtl8187_set_rxconf(struct net_device *dev); void CamResetAllEntry(struct net_device* dev); void EnableHWSecurityConfig8192(struct net_device *dev); void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent ); -- cgit v1.2.3 From 4803ef77da6ac74b0288be1fd15bdc7fe240acfa Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 6 Feb 2011 22:54:29 +0900 Subject: staging: rtl8192e: Remove RTL8192P and RTL8192U ifdefs Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8190_rtl8256.c | 200 +------ drivers/staging/rtl8192e/r8190_rtl8256.h | 4 - drivers/staging/rtl8192e/r8192E_core.c | 316 +--------- drivers/staging/rtl8192e/r8192E_dm.c | 383 +----------- drivers/staging/rtl8192e/r8192E_hw.h | 18 +- drivers/staging/rtl8192e/r8192_pm.c | 9 - drivers/staging/rtl8192e/r819xE_cmdpkt.c | 14 - drivers/staging/rtl8192e/r819xE_phy.c | 960 +------------------------------ drivers/staging/rtl8192e/r819xE_phy.h | 20 - 9 files changed, 42 insertions(+), 1882 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index d911eddd0577..4c1a5c849b89 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -59,13 +59,6 @@ void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth) rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3ff); rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x0e1); - //cosa add for sd3's request 01/23/2008 - #if 0 - if(priv->chan == 3 || priv->chan == 9) //I need to set priv->chan whenever current channel changes - rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x59b); - else - rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab); - #endif } else { @@ -241,41 +234,6 @@ void PHY_SetRF8256CCKTxPower(struct net_device* dev, u8 powerlevel) { u32 TxAGC=0; struct r8192_priv *priv = ieee80211_priv(dev); -#ifdef RTL8190P - u8 byte0, byte1; - - TxAGC |= ((powerlevel<<8)|powerlevel); - TxAGC += priv->CCKTxPowerLevelOriginalOffset; - - if(priv->bDynamicTxLowPower == true //cosa 04282008 for cck long range - /*pMgntInfo->bScanInProgress == TRUE*/ ) //cosa 05/22/2008 for scan - { - if(priv->CustomerID == RT_CID_819x_Netcore) - TxAGC = 0x2222; - else - TxAGC += ((priv->CckPwEnl<<8)|priv->CckPwEnl); - } - - byte0 = (u8)(TxAGC & 0xff); - byte1 = (u8)((TxAGC & 0xff00)>>8); - if(byte0 > 0x24) - byte0 = 0x24; - if(byte1 > 0x24) - byte1 = 0x24; - if(priv->rf_type == RF_2T4R) //Only 2T4R you have to care the Antenna Tx Power offset - { // check antenna C over the max index 0x24 - if(priv->RF_C_TxPwDiff > 0) - { - if( (byte0 + (u8)priv->RF_C_TxPwDiff) > 0x24) - byte0 = 0x24 - priv->RF_C_TxPwDiff; - if( (byte1 + (u8)priv->RF_C_TxPwDiff) > 0x24) - byte1 = 0x24 - priv->RF_C_TxPwDiff; - } - } - TxAGC = (byte1<<8) |byte0; - write_nic_dword(priv, CCK_TXAGC, TxAGC); -#else - #ifdef RTL8192E TxAGC = powerlevel; if(priv->bDynamicTxLowPower == true)//cosa 04282008 for cck long range @@ -288,86 +246,13 @@ void PHY_SetRF8256CCKTxPower(struct net_device* dev, u8 powerlevel) if(TxAGC > 0x24) TxAGC = 0x24; rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC); - #endif -#endif } void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel) { struct r8192_priv *priv = ieee80211_priv(dev); - //Joseph TxPower for 8192 testing -#ifdef RTL8190P - u32 TxAGC1=0, TxAGC2=0, TxAGC2_tmp = 0; - u8 i, byteVal1[4], byteVal2[4], byteVal3[4]; - - if(priv->bDynamicTxHighPower == true) //Add by Jacken 2008/03/06 - { - TxAGC1 |= ((powerlevel<<24)|(powerlevel<<16)|(powerlevel<<8)|powerlevel); - //for tx power track - TxAGC2_tmp = TxAGC1; - - TxAGC1 += priv->MCSTxPowerLevelOriginalOffset[0]; - TxAGC2 =0x03030303; - - //for tx power track - TxAGC2_tmp += priv->MCSTxPowerLevelOriginalOffset[1]; - } - else - { - TxAGC1 |= ((powerlevel<<24)|(powerlevel<<16)|(powerlevel<<8)|powerlevel); - TxAGC2 = TxAGC1; - - TxAGC1 += priv->MCSTxPowerLevelOriginalOffset[0]; - TxAGC2 += priv->MCSTxPowerLevelOriginalOffset[1]; - - TxAGC2_tmp = TxAGC2; - - } - for(i=0; i<4; i++) - { - byteVal1[i] = (u8)( (TxAGC1 & (0xff<<(i*8))) >>(i*8) ); - if(byteVal1[i] > 0x24) - byteVal1[i] = 0x24; - byteVal2[i] = (u8)( (TxAGC2 & (0xff<<(i*8))) >>(i*8) ); - if(byteVal2[i] > 0x24) - byteVal2[i] = 0x24; - - //for tx power track - byteVal3[i] = (u8)( (TxAGC2_tmp & (0xff<<(i*8))) >>(i*8) ); - if(byteVal3[i] > 0x24) - byteVal3[i] = 0x24; - } - - if(priv->rf_type == RF_2T4R) //Only 2T4R you have to care the Antenna Tx Power offset - { // check antenna C over the max index 0x24 - if(priv->RF_C_TxPwDiff > 0) - { - for(i=0; i<4; i++) - { - if( (byteVal1[i] + (u8)priv->RF_C_TxPwDiff) > 0x24) - byteVal1[i] = 0x24 - priv->RF_C_TxPwDiff; - if( (byteVal2[i] + (u8)priv->RF_C_TxPwDiff) > 0x24) - byteVal2[i] = 0x24 - priv->RF_C_TxPwDiff; - if( (byteVal3[i] + (u8)priv->RF_C_TxPwDiff) > 0x24) - byteVal3[i] = 0x24 - priv->RF_C_TxPwDiff; - } - } - } - - TxAGC1 = (byteVal1[3]<<24) | (byteVal1[2]<<16) |(byteVal1[1]<<8) |byteVal1[0]; - TxAGC2 = (byteVal2[3]<<24) | (byteVal2[2]<<16) |(byteVal2[1]<<8) |byteVal2[0]; - //for tx power track - TxAGC2_tmp = (byteVal3[3]<<24) | (byteVal3[2]<<16) |(byteVal3[1]<<8) |byteVal3[0]; - priv->Pwr_Track = TxAGC2_tmp; - //DbgPrint("TxAGC2_tmp = 0x%x\n", TxAGC2_tmp); - - //DbgPrint("TxAGC1/TxAGC2 = 0x%x/0x%x\n", TxAGC1, TxAGC2); - write_nic_dword(priv, MCS_TXAGC, TxAGC1); - write_nic_dword(priv, MCS_TXAGC+4, TxAGC2); -#else -#ifdef RTL8192E u32 writeVal, powerBase0, powerBase1, writeVal_tmp; u8 index = 0; u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c}; @@ -410,9 +295,6 @@ void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel) } rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal); } - -#endif -#endif } #define MAX_DOZE_WAITING_TIMES_9x 64 @@ -443,56 +325,7 @@ SetRFPowerState8190( //RXTX enable control: On //for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) // PHY_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x2); -#ifdef RTL8190P - if(priv->rf_type == RF_2T4R) - { - //enable RF-Chip A/B - rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4] - //enable RF-Chip C/D - rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x1); // 0x868[4] - //analog to digital on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0xf);// 0x88c[11:8] - //digital to analog on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e0, 0xf); // 0x880[8:5] - //rx antenna on - rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0xf);// 0xc04[3:0] - //rx antenna on - rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0xf);// 0xd04[3:0] - //analog to digital part2 on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e00, 0xf); // 0x880[12:9] - } - else if(priv->rf_type == RF_1T2R) //RF-C, RF-D - { - //enable RF-Chip C/D - rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x1); // 0x868[4] - //analog to digital on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xc00, 0x3);// 0x88c[11:10] - //digital to analog on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x180, 0x3); // 0x880[8:7] - //rx antenna on - rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xc, 0x3);// 0xc04[3:2] - //rx antenna on - rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xc, 0x3);// 0xd04[3:2] - //analog to digital part2 on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1800, 0x3); // 0x880[12:11] - } - else if(priv->rf_type == RF_1T1R) //RF-C - { - //enable RF-Chip C/D - rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x1); // 0x868[4] - //analog to digital on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x400, 0x1);// 0x88c[10] - //digital to analog on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x80, 0x1); // 0x880[7] - //rx antenna on - rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x4, 0x1);// 0xc04[2] - //rx antenna on - rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x4, 0x1);// 0xd04[2] - //analog to digital part2 on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x800, 0x1); // 0x880[11] - } -#elif defined RTL8192E // turn on RF if((priv->ieee80211->eRFPowerState == eRfOff) && RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) { // The current RF state is OFF and the RF OFF level is halting the NIC, re-initialize the NIC. @@ -561,7 +394,6 @@ SetRFPowerState8190( } - #endif break; // @@ -603,17 +435,7 @@ SetRFPowerState8190( } } - //if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P) -#ifdef RTL8190P - { - PHY_SetRtl8190pRfOff(dev); - } - //else if(Adapter->HardwareType == HARDWARE_TYPE_RTL8192E) -#elif defined RTL8192E - { - PHY_SetRtl8192eRfOff(dev); - } -#endif + PHY_SetRtl8192eRfOff(dev); } break; @@ -649,13 +471,6 @@ SetRFPowerState8190( } } - //if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P) -#if defined RTL8190P - { - PHY_SetRtl8190pRfOff(dev); - } - //else if(Adapter->HardwareType == HARDWARE_TYPE_RTL8192E) -#elif defined RTL8192E { //if(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC) && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS) if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) @@ -687,14 +502,7 @@ SetRFPowerState8190( PHY_SetRtl8192eRfOff(dev); } } -#else - else - { - RT_TRACE(COMP_DBG,DBG_TRACE,("It is not 8190Pci and 8192PciE \n")); - } - #endif - - break; + break; default: bResult = false; @@ -742,11 +550,7 @@ SetRFPowerState( bool bResult = false; RT_TRACE(COMP_RF,"---------> SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState); -#ifdef RTL8192E if(eRFPowerState == priv->ieee80211->eRFPowerState && priv->bHwRfOffAction == 0) -#else - if(eRFPowerState == priv->ieee80211->eRFPowerState) -#endif { RT_TRACE(COMP_POWER, "<--------- SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState); return bResult; diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.h b/drivers/staging/rtl8192e/r8190_rtl8256.h index a50b14092cb8..d9347fa4615c 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.h +++ b/drivers/staging/rtl8192e/r8190_rtl8256.h @@ -10,11 +10,7 @@ #ifndef RTL8225_H #define RTL8225_H -#ifdef RTL8190P -#define RTL819X_TOTAL_RF_PATH 4 -#else #define RTL819X_TOTAL_RF_PATH 2 /* for 8192E */ -#endif void PHY_SetRF8256Bandwidth(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth); diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 6190cdd3fb38..d3046afce0dd 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1,6 +1,6 @@ /****************************************************************************** * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8190P / RTL8192E + * Linux device driver for RTL8192E * * Based on the r8180 driver, which is: * Copyright 2004-2005 Andrea Merello , et al. @@ -90,21 +90,12 @@ u32 rt_global_debug_component = COMP_ERR ; //always open err flags on static DEFINE_PCI_DEVICE_TABLE(rtl8192_pci_id_tbl) = { -#ifdef RTL8190P - /* Realtek */ - /* Dlink */ - { PCI_DEVICE(0x10ec, 0x8190) }, - /* Corega */ - { PCI_DEVICE(0x07aa, 0x0045) }, - { PCI_DEVICE(0x07aa, 0x0046) }, -#else /* Realtek */ { PCI_DEVICE(0x10ec, 0x8192) }, /* Corega */ { PCI_DEVICE(0x07aa, 0x0044) }, { PCI_DEVICE(0x07aa, 0x0047) }, -#endif {} }; @@ -887,9 +878,7 @@ void rtl8192_halt_adapter(struct net_device *dev, bool reset) if (!reset) { mdelay(150); -#ifdef RTL8192E priv->bHwRfOffAction = 2; -#endif /* * Call MgntActSet_RF_State instead to @@ -1396,12 +1385,8 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff* skb) if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40) { if (tcb_desc->bPacketBW) { pTxFwInfo->TxBandwidth = 1; -#ifdef RTL8190P - pTxFwInfo->TxSubCarrier = 3; -#else /* use duplicated mode */ pTxFwInfo->TxSubCarrier = 0; -#endif } else { pTxFwInfo->TxBandwidth = 0; pTxFwInfo->TxSubCarrier = priv->nCur40MhzPrimeSC; @@ -2285,15 +2270,9 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) { struct net_device *dev = priv->ieee80211->dev; u8 tempval; -#ifdef RTL8192E u8 ICVer8192, ICVer8256; -#endif u16 i,usValue, IC_Version; u16 EEPROMId; -#ifdef RTL8190P - u8 offset; - u8 EepromTxPower[100]; -#endif u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01}; RT_TRACE(COMP_INIT, "====> rtl8192_read_eeprom_info\n"); @@ -2328,10 +2307,6 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) priv->eeprom_ChannelPlan = usValue&0xff; IC_Version = ((usValue&0xff00)>>8); -#ifdef RTL8190P - priv->card_8192_version = (VERSION_8190)(IC_Version); -#else - #ifdef RTL8192E ICVer8192 = (IC_Version&0xf); //bit0~3; 1:A cut, 2:B cut, 3:C cut... ICVer8256 = ((IC_Version&0xf0)>>4);//bit4~6, bit7 reserved for other RF chip; 1:A cut, 2:B cut, 3:C cut... RT_TRACE(COMP_INIT, "\nICVer8192 = 0x%x\n", ICVer8192); @@ -2341,8 +2316,7 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) if(ICVer8256 == 0x5) //E-cut priv->card_8192_version= VERSION_8190_BE; } - #endif -#endif + switch(priv->card_8192_version) { case VERSION_8190_BD: @@ -2476,82 +2450,7 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelOFDM24G[i+1]); } } - else if(priv->epromtype== EPROM_93c56) - { - #ifdef RTL8190P - // Read CrystalCap from EEPROM - if(!priv->AutoloadFailFlag) - { - priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff; - priv->EEPROMCrystalCap = (u8)(((eprom_read(dev, (EEPROM_C56_CrystalCap>>1))) & 0xf000)>>12); - } - else - { - priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff; - priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap; - } - RT_TRACE(COMP_INIT,"EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff); - RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap); - - // Get Tx Power Level by Channel - if(!priv->AutoloadFailFlag) - { - // Read Tx power of Channel 1 ~ 14 from EEPROM. - for(i = 0; i < 12; i+=2) - { - if (i <6) - offset = EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex + i; - else - offset = EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex + i - 6; - usValue = eprom_read(dev, (offset>>1)); - *((u16*)(&EepromTxPower[i])) = usValue; - } - - for(i = 0; i < 12; i++) - { - if (i <= 2) - priv->EEPROMRfACCKChnl1TxPwLevel[i] = EepromTxPower[i]; - else if ((i >=3 )&&(i <= 5)) - priv->EEPROMRfAOfdmChnlTxPwLevel[i-3] = EepromTxPower[i]; - else if ((i >=6 )&&(i <= 8)) - priv->EEPROMRfCCCKChnl1TxPwLevel[i-6] = EepromTxPower[i]; - else - priv->EEPROMRfCOfdmChnlTxPwLevel[i-9] = EepromTxPower[i]; - } - } - else - { - priv->EEPROMRfACCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel; - priv->EEPROMRfACCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel; - priv->EEPROMRfACCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel; - priv->EEPROMRfAOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel; - priv->EEPROMRfAOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel; - priv->EEPROMRfAOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel; - - priv->EEPROMRfCCCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel; - priv->EEPROMRfCCCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel; - priv->EEPROMRfCCCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel; - - priv->EEPROMRfCOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel; - priv->EEPROMRfCOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel; - priv->EEPROMRfCOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel; - } - RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[0]); - RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[1]); - RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[2]); - RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[0]); - RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[1]); - RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[2]); - RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[0]); - RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[1]); - RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[2]); - RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[0]); - RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[1]); - RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[2]); -#endif - - } // // Update HAL variables. // @@ -2711,13 +2610,7 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) switch(priv->CustomerID) { case RT_CID_DEFAULT: - #ifdef RTL8190P - priv->LedStrategy = HW_LED; - #else - #ifdef RTL8192E priv->LedStrategy = SW_LED_MODE1; - #endif - #endif break; case RT_CID_819x_CAMEO: @@ -2745,13 +2638,7 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) //break; default: - #ifdef RTL8190P - priv->LedStrategy = HW_LED; - #else - #ifdef RTL8192E priv->LedStrategy = SW_LED_MODE1; - #endif - #endif break; } @@ -2917,13 +2804,8 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) RT_STATUS rtStatus = RT_STATUS_SUCCESS; //u8 eRFPath; u8 tmpvalue; -#ifdef RTL8192E u8 ICVersion,SwitchingRegulatorOutput; -#endif bool bfirmwareok = true; -#ifdef RTL8190P - u8 ucRegRead; -#endif u32 tmpRegA, tmpRegC, TempCCk; int i =0; @@ -2932,7 +2814,7 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) rtl8192_pci_resetdescring(dev); // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W. priv->Rf_Mode = RF_OP_By_SW_3wire; -#ifdef RTL8192E + //dPLL on if(priv->ResetProgress == RESET_TYPE_NORESET) { @@ -2941,7 +2823,7 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) // Joseph increae the time to prevent firmware download fail mdelay(500); } -#endif + //PlatformSleepUs(10000); // For any kind of InitializeAdapter process, we shall use system now!! priv->pFirmware->firmware_status = FW_STATUS_0_INIT; @@ -2959,16 +2841,9 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) else RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status); -#ifdef RTL8190P - //2008.06.03, for WOL 90 hw bug - ulRegRead &= (~(CPU_GEN_GPIO_UART)); -#endif - write_nic_dword(priv, CPU_GEN, ulRegRead); //mdelay(100); -#ifdef RTL8192E - //3// //3 //Fix the issue of E-cut high temperature issue //3// @@ -2987,8 +2862,6 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) write_nic_byte(priv, SWREGULATOR, 0xb8); } } -#endif - //3// //3// Initialize BB before MAC @@ -3042,16 +2915,9 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) write_nic_byte(priv, CMDR, CR_RE|CR_TE); //2Set Tx dma burst -#ifdef RTL8190P - write_nic_byte(priv, PCIF, ((MXDMA2_NoLimit<dev_addr)[0]); write_nic_word(priv, MAC4, ((u16*)(dev->dev_addr + 4))[0]); @@ -3185,20 +3051,8 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1); rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1); -#ifdef RTL8192E //Enable Led write_nic_byte(priv, 0x87, 0x0); -#endif -#ifdef RTL8190P - //2008.06.03, for WOL - ucRegRead = read_nic_byte(priv, GPE); - ucRegRead |= BIT0; - write_nic_byte(priv, GPE, ucRegRead); - - ucRegRead = read_nic_byte(priv, GPO); - ucRegRead &= ~BIT0; - write_nic_byte(priv, GPO, ucRegRead); -#endif //2======================================================= // RF Power Save @@ -3236,69 +3090,12 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) } } #endif - if(1){ -#ifdef RTL8192E - // We can force firmware to do RF-R/W - if(priv->ieee80211->FwRWRF) - priv->Rf_Mode = RF_OP_By_FW; - else - priv->Rf_Mode = RF_OP_By_SW_3wire; -#else - priv->Rf_Mode = RF_OP_By_SW_3wire; -#endif - } -#ifdef RTL8190P - if(priv->ResetProgress == RESET_TYPE_NORESET) - { - dm_initialize_txpower_tracking(dev); - - tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord); - tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord); - - if(priv->rf_type == RF_2T4R){ - for(i = 0; itxbbgain_table[i].txbbgain_value) - { - priv->rfa_txpowertrackingindex= (u8)i; - priv->rfa_txpowertrackingindex_real= (u8)i; - priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex; - break; - } - } - } - for(i = 0; itxbbgain_table[i].txbbgain_value) - { - priv->rfc_txpowertrackingindex= (u8)i; - priv->rfc_txpowertrackingindex_real= (u8)i; - priv->rfc_txpowertracking_default = priv->rfc_txpowertrackingindex; - break; - } - } - TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2); + // We can force firmware to do RF-R/W + if(priv->ieee80211->FwRWRF) + priv->Rf_Mode = RF_OP_By_FW; + else + priv->Rf_Mode = RF_OP_By_SW_3wire; - for(i=0 ; icck_txbbgain_table[i].ccktxbb_valuearray[0]) - { - priv->CCKPresentAttentuation_20Mdefault =(u8) i; - break; - } - } - priv->CCKPresentAttentuation_40Mdefault = 0; - priv->CCKPresentAttentuation_difference = 0; - priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault; - RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex); - RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real); - RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_initial = %d\n", priv->rfc_txpowertrackingindex); - RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real_initial = %d\n", priv->rfc_txpowertrackingindex_real); - RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference); - RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation); - } -#else - #ifdef RTL8192E if(priv->ResetProgress == RESET_TYPE_NORESET) { dm_initialize_txpower_tracking(dev); @@ -3338,8 +3135,7 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) priv->btxpower_tracking = FALSE;//TEMPLY DISABLE } } - #endif -#endif + rtl8192_irq_enable(dev); priv->being_init_adapter = false; return rtStatus; @@ -4260,10 +4056,10 @@ static int _rtl8192_up(struct net_device *dev) return -1; } RT_TRACE(COMP_INIT, "start adapter finished\n"); -#ifdef RTL8192E + if(priv->ieee80211->eRFPowerState!=eRfOn) MgntActSet_RF_State(dev, eRfOn, priv->ieee80211->RfOffReason); -#endif + if(priv->ieee80211->state != IEEE80211_LINKED) ieee80211_softmac_start_protocol(priv->ieee80211); ieee80211_reset_queue(priv->ieee80211); @@ -4603,67 +4399,6 @@ static long rtl819x_translate_todbm(u8 signal_strength_index)// 0-100 index. return signal_power; } -static void -rtl8190_process_cck_rxpathsel( - struct r8192_priv * priv, - struct ieee80211_rx_stats * pprevious_stats - ) -{ -#ifdef RTL8190P //Only 90P 2T4R need to check - char last_cck_adc_pwdb[4]={0,0,0,0}; - u8 i; -//cosa add for Rx path selection - if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable) - { - if(pprevious_stats->bIsCCK && - (pprevious_stats->bPacketToSelf ||pprevious_stats->bPacketBeacon)) - { - /* record the cck adc_pwdb to the sliding window. */ - if(priv->stats.cck_adc_pwdb.TotalNum++ >= PHY_RSSI_SLID_WIN_MAX) - { - priv->stats.cck_adc_pwdb.TotalNum = PHY_RSSI_SLID_WIN_MAX; - for(i=RF90_PATH_A; istats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index]; - priv->stats.cck_adc_pwdb.TotalVal[i] -= last_cck_adc_pwdb[i]; - } - } - for(i=RF90_PATH_A; istats.cck_adc_pwdb.TotalVal[i] += pprevious_stats->cck_adc_pwdb[i]; - priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index] = pprevious_stats->cck_adc_pwdb[i]; - } - priv->stats.cck_adc_pwdb.index++; - if(priv->stats.cck_adc_pwdb.index >= PHY_RSSI_SLID_WIN_MAX) - priv->stats.cck_adc_pwdb.index = 0; - - for(i=RF90_PATH_A; istats.cck_adc_pwdb.TotalVal[i]/priv->stats.cck_adc_pwdb.TotalNum; - } - - for(i=RF90_PATH_A; icck_adc_pwdb[i] > (char)priv->undecorated_smoothed_cck_adc_pwdb[i]) - { - priv->undecorated_smoothed_cck_adc_pwdb[i] = - ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) + - (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor); - priv->undecorated_smoothed_cck_adc_pwdb[i] = priv->undecorated_smoothed_cck_adc_pwdb[i] + 1; - } - else - { - priv->undecorated_smoothed_cck_adc_pwdb[i] = - ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) + - (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor); - } - } - } - } -#endif -} - - /* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to be a local static. Otherwise, it may increase when we return from S3/S4. The value will be kept in memory or disk. We must delcare the value in adapter @@ -4730,8 +4465,6 @@ static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct if(!bcheck) return; - rtl8190_process_cck_rxpathsel(priv,pprevious_stats); - // <2> Showed on UI for engineering // hardware does not provide rssi information for each rf path in CCK if(!pprevious_stats->bIsCCK && pprevious_stats->bPacketToSelf) @@ -5019,23 +4752,6 @@ static void rtl8192_query_rxphystatus( // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) // u8 report;//, cck_agc_rpt; -#ifdef RTL8190P - u8 tmp_pwdb; - char cck_adc_pwdb[4]; -#endif - -#ifdef RTL8190P //Only 90P 2T4R need to check - if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable && bpacket_match_bssid) - { - for(i=RF90_PATH_A; iadc_pwdb_X[i]; - cck_adc_pwdb[i] = (char)tmp_pwdb; - cck_adc_pwdb[i] /= 2; - pstats->cck_adc_pwdb[i] = precord_stats->cck_adc_pwdb[i] = cck_adc_pwdb[i]; - } - } -#endif if (!priv->phy_reg824_bit9) { @@ -5126,11 +4842,7 @@ static void rtl8192_query_rxphystatus( //Fixed by Jacken from Bryant 2008-03-20 //Original value is 106 -#ifdef RTL8190P //Modify by Jacken 2008/03/31 - rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106; -#else rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 110; -#endif //Get Rx snr value in DB tmp_rxsnr = pofdm_buf->rxsnr_X[i]; @@ -5699,9 +5411,7 @@ static void rtl8192_cancel_deferred_work(struct r8192_priv* priv) cancel_delayed_work(&priv->update_beacon_wq); cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq); cancel_delayed_work(&priv->ieee80211->hw_sleep_wq); -#ifdef RTL8192E cancel_delayed_work(&priv->gpio_change_rf_wq); -#endif cancel_work_sync(&priv->reset_wq); cancel_work_sync(&priv->qos_activate); //cancel_work_sync(&priv->SetBWModeWorkItem); diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index 20d9c0b8a127..1ade3672546e 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -25,24 +25,10 @@ Major Change History: // // Indicate different AP vendor for IOT issue. // -#ifdef RTL8190P -static const u32 edca_setting_DL[HT_IOT_PEER_MAX] = -{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5e4322, 0x5e4322}; -static const u32 edca_setting_UL[HT_IOT_PEER_MAX] = -{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5e4322, 0x5e4322, 0x5e4322}; -#else -#ifdef RTL8192E static const u32 edca_setting_DL[HT_IOT_PEER_MAX] = { 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5e4322, 0x5e4322}; static const u32 edca_setting_UL[HT_IOT_PEER_MAX] = { 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5e4322, 0x5e4322, 0x5e4322}; -#else -static const u32 edca_setting_DL[HT_IOT_PEER_MAX] = -{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5ea44f, 0x5e4322}; -static const u32 edca_setting_UL[HT_IOT_PEER_MAX] = -{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5ea44f, 0x5ea44f, 0x5e4322}; -#endif -#endif #define RTK_UL_EDCA 0xa44f #define RTK_DL_EDCA 0x5e4322 @@ -82,9 +68,7 @@ extern void dm_fsync_timer_callback(unsigned long data); extern void dm_check_fsync(struct net_device *dev); extern void dm_initialize_txpower_tracking(struct net_device *dev); -#ifdef RTL8192E extern void dm_gpio_change_rf_callback(struct work_struct *work); -#endif // DM --> Rate Adaptive @@ -97,14 +81,6 @@ static void dm_bandwidth_autoswitch( struct net_device *dev); // DM --> TX power control static void dm_check_txpower_tracking(struct net_device *dev); -// DM --> BB init gain restore -#ifndef RTL8192U -static void dm_bb_initialgain_restore(struct net_device *dev); - -// DM --> BB init gain backup -static void dm_bb_initialgain_backup(struct net_device *dev); -#endif - // DM --> Dynamic Init Gain by RSSI static void dm_dig_init(struct net_device *dev); static void dm_ctrl_initgain_byrssi(struct net_device *dev); @@ -166,9 +142,7 @@ void init_hal_dm(struct net_device *dev) dm_init_fsync(dev); dm_init_rxpath_selection(dev); dm_init_ctstoself(dev); -#ifdef RTL8192E INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, dm_gpio_change_rf_callback); -#endif } @@ -503,7 +477,6 @@ static void dm_bandwidth_autoswitch(struct net_device * dev) } //OFDM default at 0db, index=6. -#ifndef RTL8190P static const u32 OFDMSwingTable[OFDM_Table_Length] = { 0x7f8001fe, // 0, +6db 0x71c001c7, // 1, +5db @@ -554,7 +527,7 @@ static const u8 CCKSwingTable_Ch14[CCK_Table_length][8] = { {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, // 10, -10db {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00} // 11, -11db }; -#endif + #define Pw_Track_Flag 0x11d #define Tssi_Mea_Value 0x13c #define Tssi_Report_Value1 0x134 @@ -571,9 +544,6 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) u32 Value; u8 Pwr_Flag; u16 Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver=0; -#ifdef RTL8192U - RT_STATUS rtStatus = RT_STATUS_SUCCESS; -#endif // bool rtStatus = true; u32 delta=0; RT_TRACE(COMP_POWER_TRACKING,"%s()\n",__FUNCTION__); @@ -595,15 +565,7 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) tx_cmd.Op = TXCMD_SET_TX_PWR_TRACKING; tx_cmd.Length = 4; tx_cmd.Value = Value; -#ifdef RTL8192U - rtStatus = SendTxCommandPacket(dev, &tx_cmd, 12); - if (rtStatus == RT_STATUS_FAILURE) - { - RT_TRACE(COMP_POWER_TRACKING, "Set configuration with tx cmd queue fail!\n"); - } -#else cmpk_message_handle_tx(dev, (u8*)&tx_cmd, DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T)); -#endif mdelay(1); for(i = 0;i <= 30; i++) @@ -679,10 +641,6 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n"); RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex); RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real); -#ifdef RTL8190P - RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex = %d\n", priv->rfc_txpowertrackingindex); - RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real = %d\n", priv->rfc_txpowertrackingindex_real); -#endif RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference = %d\n", priv->CCKPresentAttentuation_difference); RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation); return; @@ -798,10 +756,6 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) } RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex); RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real); -#ifdef RTL8190P - RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex = %d\n", priv->rfc_txpowertrackingindex); - RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real = %d\n", priv->rfc_txpowertrackingindex_real); -#endif RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference = %d\n", priv->CCKPresentAttentuation_difference); RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation); @@ -827,7 +781,7 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) priv->ieee80211->bdynamic_txpower_enable = TRUE; write_nic_byte(priv, Pw_Track_Flag, 0); } -#ifndef RTL8190P + static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev) { #define ThermalMeterVal 9 @@ -941,22 +895,17 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev) } priv->txpower_count = 0; } -#endif + void dm_txpower_trackingcallback(struct work_struct *work) { struct delayed_work *dwork = container_of(work,struct delayed_work,work); struct r8192_priv *priv = container_of(dwork,struct r8192_priv,txpower_tracking_wq); struct net_device *dev = priv->ieee80211->dev; -#ifdef RTL8190P - dm_TXPowerTrackingCallback_TSSI(dev); -#else - //if(priv->bDcut == TRUE) if(priv->IC_Cut >= IC_VersionCut_D) dm_TXPowerTrackingCallback_TSSI(dev); else dm_TXPowerTrackingCallback_ThermalMeter(dev); -#endif } @@ -1073,7 +1022,7 @@ static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev) priv->btxpower_trackingInit = FALSE; } -#ifndef RTL8190P + static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); @@ -1088,21 +1037,15 @@ static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev) priv->txpower_count = 0; priv->btxpower_trackingInit = FALSE; } -#endif void dm_initialize_txpower_tracking(struct net_device *dev) { -#ifndef RTL8190P struct r8192_priv *priv = ieee80211_priv(dev); -#endif -#ifdef RTL8190P - dm_InitializeTXPowerTracking_TSSI(dev); -#else + if(priv->IC_Cut >= IC_VersionCut_D) dm_InitializeTXPowerTracking_TSSI(dev); else dm_InitializeTXPowerTracking_ThermalMeter(dev); -#endif } @@ -1123,7 +1066,6 @@ static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev) } } -#ifndef RTL8190P static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); @@ -1156,24 +1098,15 @@ static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev) TM_Trigger = 0; } } -#endif static void dm_check_txpower_tracking(struct net_device *dev) { -#ifndef RTL8190P struct r8192_priv *priv = ieee80211_priv(dev); - //static u32 tx_power_track_counter = 0; -#endif -#ifdef RTL8190P - dm_CheckTXPowerTracking_TSSI(dev); -#else - //if(priv->bDcut == TRUE) + if(priv->IC_Cut >= IC_VersionCut_D) dm_CheckTXPowerTracking_TSSI(dev); else dm_CheckTXPowerTracking_ThermalMeter(dev); -#endif - } @@ -1226,7 +1159,7 @@ static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14) } -#ifndef RTL8190P + static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH14) { u32 TempVal; @@ -1288,158 +1221,17 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH rCCK0_DebugPort, TempVal); } } -#endif - void dm_cck_txpower_adjust(struct net_device *dev, bool binch14) { -#ifndef RTL8190P struct r8192_priv *priv = ieee80211_priv(dev); -#endif -#ifdef RTL8190P - dm_CCKTxPowerAdjust_TSSI(dev, binch14); -#else + if(priv->IC_Cut >= IC_VersionCut_D) dm_CCKTxPowerAdjust_TSSI(dev, binch14); else dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14); -#endif -} - - -#ifndef RTL8192U -static void dm_txpower_reset_recovery( - struct net_device *dev -) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n"); - rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value); - RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n",priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value); - RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n",priv->rfa_txpowertrackingindex); - RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF A I/Q Amplify Gain is %ld\n",priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbb_iq_amplifygain); - RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: CCK Attenuation is %d dB\n",priv->CCKPresentAttentuation); - dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); - - rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value); - RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n",priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value); - RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n",priv->rfc_txpowertrackingindex); - RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF C I/Q Amplify Gain is %ld\n",priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbb_iq_amplifygain); - } -void dm_restore_dynamic_mechanism_state(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u32 reg_ratr = priv->rate_adaptive.last_ratr; - - if(!priv->up) - { - RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n"); - return; - } - - // - // Restore previous state for rate adaptive - // - if(priv->rate_adaptive.rate_adaptive_disabled) - return; - // TODO: Only 11n mode is implemented currently, - if( !(priv->ieee80211->mode==WIRELESS_MODE_N_24G || - priv->ieee80211->mode==WIRELESS_MODE_N_5G)) - return; - { - /* 2007/11/15 MH Copy from 8190PCI. */ - u32 ratr_value; - ratr_value = reg_ratr; - if(priv->rf_type == RF_1T2R) // 1T2R, Spatial Stream 2 should be disabled - { - ratr_value &=~ (RATE_ALL_OFDM_2SS); - } - write_nic_dword(priv, RATR0, ratr_value); - write_nic_byte(priv, UFWP, 1); - } - //Resore TX Power Tracking Index - if(priv->btxpower_trackingInit && priv->btxpower_tracking){ - dm_txpower_reset_recovery(dev); - } - - // - //Restore BB Initial Gain - // - dm_bb_initialgain_restore(dev); - -} - -static void dm_bb_initialgain_restore(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u32 bit_mask = 0x7f; //Bit0~ Bit6 - - if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) - return; - - //Disable Initial Gain - //PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800); - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite. - rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, (u32)priv->initgain_backup.xaagccore1); - rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, (u32)priv->initgain_backup.xbagccore1); - rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, (u32)priv->initgain_backup.xcagccore1); - rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bit_mask, (u32)priv->initgain_backup.xdagccore1); - bit_mask = bMaskByte2; - rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, (u32)priv->initgain_backup.cca); - - RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n",priv->initgain_backup.xaagccore1); - RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n",priv->initgain_backup.xbagccore1); - RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n",priv->initgain_backup.xcagccore1); - RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n",priv->initgain_backup.xdagccore1); - RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n",priv->initgain_backup.cca); - //Enable Initial Gain - //PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x100); - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite. - -} - - -void dm_backup_dynamic_mechanism_state(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - // Fsync to avoid reset - priv->bswitch_fsync = false; - //Backup BB InitialGain - dm_bb_initialgain_backup(dev); - -} - - -static void dm_bb_initialgain_backup(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u32 bit_mask = bMaskByte0; //Bit0~ Bit6 - - if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) - return; - - //PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800); - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite. - priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bit_mask); - priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bit_mask); - priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bit_mask); - priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bit_mask); - bit_mask = bMaskByte2; - priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bit_mask); - - RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n",priv->initgain_backup.xaagccore1); - RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n",priv->initgain_backup.xbagccore1); - RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n",priv->initgain_backup.xcagccore1); - RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n",priv->initgain_backup.xdagccore1); - RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca); - -} - -#endif void dm_change_dynamic_initgain_thresh(struct net_device *dev, u32 dm_type, u32 dm_value) { @@ -1660,19 +1452,7 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( { /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. - #ifdef RTL8190P - write_nic_byte(priv, rOFDM0_RxDetector1, 0x40); - #else - write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x00); - #endif - /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) - write_nic_byte(pAdapter, rOFDM0_RxDetector1, 0x40); - */ - //else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E) - - - //else - //PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x40); + write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x00); } else write_nic_byte(priv, rOFDM0_RxDetector1, 0x42); @@ -1730,19 +1510,7 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( { /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. - #ifdef RTL8190P - write_nic_byte(priv, rOFDM0_RxDetector1, 0x42); - #else - write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20); - #endif - /* - else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) - write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); - */ - //else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E) - - //else - //PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x42); + write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20); } else write_nic_byte(priv, rOFDM0_RxDetector1, 0x44); @@ -1790,16 +1558,7 @@ static void dm_ctrl_initgain_byrssi_highpwr( // 3.1 Higher PD_TH for OFDM for high power state. if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) { - #ifdef RTL8190P - write_nic_byte(priv, rOFDM0_RxDetector1, 0x41); - #else - write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x10); - #endif - - /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) - write_nic_byte(priv, rOFDM0_RxDetector1, 0x41); - */ - + write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x10); } else write_nic_byte(priv, rOFDM0_RxDetector1, 0x43); @@ -1818,15 +1577,7 @@ static void dm_ctrl_initgain_byrssi_highpwr( // 3.2 Recover PD_TH for OFDM for normal power region. if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) { - #ifdef RTL8190P - write_nic_byte(priv, rOFDM0_RxDetector1, 0x42); - #else - write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20); - #endif - /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) - write_nic_byte(priv, rOFDM0_RxDetector1, 0x42); - */ - + write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20); } else write_nic_byte(priv, rOFDM0_RxDetector1, 0x44); @@ -1959,14 +1710,7 @@ static void dm_pd_th( { /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. - #ifdef RTL8190P - write_nic_byte(priv, rOFDM0_RxDetector1, 0x40); - #else - write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x00); - #endif - /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) - write_nic_byte(dev, rOFDM0_RxDetector1, 0x40); - */ + write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x00); } else write_nic_byte(priv, rOFDM0_RxDetector1, 0x42); @@ -1978,14 +1722,7 @@ static void dm_pd_th( { /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. - #ifdef RTL8190P - write_nic_byte(priv, rOFDM0_RxDetector1, 0x42); - #else - write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20); - #endif - /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) - write_nic_byte(priv, rOFDM0_RxDetector1, 0x42); - */ + write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20); } else write_nic_byte(priv, rOFDM0_RxDetector1, 0x44); @@ -1995,14 +1732,7 @@ static void dm_pd_th( // Higher PD_TH for OFDM for high power state. if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) { - #ifdef RTL8190P - write_nic_byte(priv, rOFDM0_RxDetector1, 0x41); - #else - write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x10); - #endif - /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P) - write_nic_byte(priv, rOFDM0_RxDetector1, 0x41); - */ + write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x10); } else write_nic_byte(priv, rOFDM0_RxDetector1, 0x43); @@ -2243,51 +1973,21 @@ static void dm_ctstoself(struct net_device *dev) /* Copy 8187B template for 9xseries */ static void dm_check_rfctrl_gpio(struct net_device * dev) { -#ifdef RTL8192E struct r8192_priv *priv = ieee80211_priv(dev); -#endif // Walk around for DTM test, we will not enable HW - radio on/off because r/w // page 1 register before Lextra bus is enabled cause system fails when resuming // from S4. 20080218, Emily // Stop to execute workitem to prevent S3/S4 bug. -#ifdef RTL8190P - return; -#endif -#ifdef RTL8192U - return; -#endif -#ifdef RTL8192E - queue_delayed_work(priv->priv_wq,&priv->gpio_change_rf_wq,0); -#endif - + queue_delayed_work(priv->priv_wq,&priv->gpio_change_rf_wq,0); } /* Check if PBC button is pressed. */ static void dm_check_pbc_gpio(struct net_device *dev) { -#ifdef RTL8192U - struct r8192_priv *priv = ieee80211_priv(dev); - u8 tmp1byte; - - - tmp1byte = read_nic_byte(priv, GPI); - if(tmp1byte == 0xff) - return; - - if (tmp1byte&BIT6 || tmp1byte&BIT0) - { - // Here we only set bPbcPressed to TRUE - // After trigger PBC, the variable will be set to FALSE - RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n"); - } -#endif - } -#ifdef RTL8192E - /* PCI will not support workitem call back HW radio on-off control. */ void dm_gpio_change_rf_callback(struct work_struct *work) { @@ -2328,8 +2028,6 @@ void dm_gpio_change_rf_callback(struct work_struct *work) } } -#endif - /* Check if Current RF RX path is enabled */ void dm_rf_pathcheck_workitemcallback(struct work_struct *work) { @@ -2655,11 +2353,7 @@ static void dm_init_fsync (struct net_device *dev) priv->ieee80211->fsync_time_interval = 500; priv->ieee80211->fsync_rate_bitmap = 0x0f000800; priv->ieee80211->fsync_rssi_threshold = 30; -#ifdef RTL8190P - priv->ieee80211->bfsync_enable = true; -#else priv->ieee80211->bfsync_enable = false; -#endif priv->ieee80211->fsync_multiple_timeinterval = 3; priv->ieee80211->fsync_firstdiff_ratethreshold= 100; priv->ieee80211->fsync_seconddiff_ratethreshold= 200; @@ -2741,20 +2435,12 @@ void dm_fsync_timer_callback(unsigned long data) priv->bswitch_fsync = !priv->bswitch_fsync; if(priv->bswitch_fsync) { - #ifdef RTL8190P - write_nic_byte(priv,0xC36, 0x00); - #else write_nic_byte(priv,0xC36, 0x1c); - #endif write_nic_byte(priv, 0xC3e, 0x90); } else { - #ifdef RTL8190P - write_nic_byte(priv, 0xC36, 0x40); - #else write_nic_byte(priv, 0xC36, 0x5c); - #endif write_nic_byte(priv, 0xC3e, 0x96); } } @@ -2763,11 +2449,7 @@ void dm_fsync_timer_callback(unsigned long data) if(priv->bswitch_fsync) { priv->bswitch_fsync = false; - #ifdef RTL8190P - write_nic_byte(priv, 0xC36, 0x40); - #else write_nic_byte(priv, 0xC36, 0x5c); - #endif write_nic_byte(priv, 0xC3e, 0x96); } } @@ -2790,19 +2472,11 @@ void dm_fsync_timer_callback(unsigned long data) if(priv->bswitch_fsync) { priv->bswitch_fsync = false; - #ifdef RTL8190P - write_nic_byte(priv, 0xC36, 0x40); - #else write_nic_byte(priv, 0xC36, 0x5c); - #endif write_nic_byte(priv, 0xC3e, 0x96); } priv->ContiuneDiffCount = 0; - #ifdef RTL8190P - write_nic_dword(priv, rOFDM0_RxDetector2, 0x164052cd); - #else write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd); - #endif } RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount); RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync); @@ -2829,20 +2503,14 @@ static void dm_EndSWFsync(struct net_device *dev) { priv->bswitch_fsync = false; - #ifdef RTL8190P - write_nic_byte(priv, 0xC36, 0x40); - #else - write_nic_byte(priv, 0xC36, 0x5c); -#endif + write_nic_byte(priv, 0xC36, 0x40); write_nic_byte(priv, 0xC3e, 0x96); } priv->ContiuneDiffCount = 0; -#ifndef RTL8190P - write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd); -#endif + write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd); } static void dm_StartSWFsync(struct net_device *dev) @@ -2880,10 +2548,7 @@ static void dm_StartSWFsync(struct net_device *dev) priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval); add_timer(&priv->fsync_timer); -#ifndef RTL8190P write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c12cd); -#endif - } static void dm_EndHWFsync(struct net_device *dev) @@ -2952,11 +2617,7 @@ void dm_check_fsync(struct net_device *dev) { if(reg_c38_State != RegC38_Fsync_AP_BCM) { //For broadcom AP we write different default value - #ifdef RTL8190P - write_nic_byte(priv, rOFDM0_RxDetector3, 0x15); - #else - write_nic_byte(priv, rOFDM0_RxDetector3, 0x95); - #endif + write_nic_byte(priv, rOFDM0_RxDetector3, 0x95); reg_c38_State = RegC38_Fsync_AP_BCM; } @@ -2987,11 +2648,7 @@ void dm_check_fsync(struct net_device *dev) { if(reg_c38_State != RegC38_NonFsync_Other_AP) { - #ifdef RTL8190P - write_nic_byte(priv, rOFDM0_RxDetector3, 0x10); - #else - write_nic_byte(priv, rOFDM0_RxDetector3, 0x90); - #endif + write_nic_byte(priv, rOFDM0_RxDetector3, 0x90); reg_c38_State = RegC38_NonFsync_Other_AP; } diff --git a/drivers/staging/rtl8192e/r8192E_hw.h b/drivers/staging/rtl8192e/r8192E_hw.h index 346bfb18e2b0..7c1cd5d18675 100644 --- a/drivers/staging/rtl8192e/r8192E_hw.h +++ b/drivers/staging/rtl8192e/r8192E_hw.h @@ -95,27 +95,13 @@ typedef enum _RT_RF_TYPE_819xU{ #define EEPROM_Default_TxPower 0x1010 #define EEPROM_ICVersion_ChannelPlan 0x7C //0x7C:ChannelPlan, 0x7D:IC_Version #define EEPROM_Customer_ID 0x7B //0x7B:CustomerID -#ifdef RTL8190P -#define EEPROM_RFInd_PowerDiff 0x14 -#define EEPROM_ThermalMeter 0x15 -#define EEPROM_TxPwDiff_CrystalCap 0x16 -#define EEPROM_TxPwIndex_CCK 0x18 //0x18~0x25 -#define EEPROM_TxPwIndex_OFDM_24G 0x26 //0x26~0x33 -#define EEPROM_TxPwIndex_OFDM_5G 0x34 //0x34~0x7B -#define EEPROM_C56_CrystalCap 0x17 //0x17 -#define EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex 0x80 //0x80 -#define EEPROM_C56_RfA_HT_OFDM_TxPwIndex 0x81 //0x81~0x83 -#define EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex 0xbc //0xb8 -#define EEPROM_C56_RfC_HT_OFDM_TxPwIndex 0xb9 //0xb9~0xbb -#else -#ifdef RTL8192E + #define EEPROM_RFInd_PowerDiff 0x28 #define EEPROM_ThermalMeter 0x29 #define EEPROM_TxPwDiff_CrystalCap 0x2A //0x2A~0x2B #define EEPROM_TxPwIndex_CCK 0x2C //0x23 #define EEPROM_TxPwIndex_OFDM_24G 0x3A //0x24~0x26 -#endif -#endif + #define EEPROM_Default_TxPowerLevel 0x10 //#define EEPROM_ChannelPlan 0x7c //0x7C #define EEPROM_IC_VER 0x7d //0x7D diff --git a/drivers/staging/rtl8192e/r8192_pm.c b/drivers/staging/rtl8192e/r8192_pm.c index 8781735d5a35..5679c8ba370d 100644 --- a/drivers/staging/rtl8192e/r8192_pm.c +++ b/drivers/staging/rtl8192e/r8192_pm.c @@ -25,9 +25,6 @@ int rtl8192E_suspend (struct pci_dev *pdev, pm_message_t state) { struct net_device *dev = pci_get_drvdata(pdev); struct r8192_priv *priv = ieee80211_priv(dev); -#ifdef RTL8190P - u8 ucRegRead; -#endif u32 ulRegRead; RT_TRACE(COMP_POWER, "============> r8192E suspend call.\n"); @@ -49,12 +46,6 @@ int rtl8192E_suspend (struct pci_dev *pdev, pm_message_t state) write_nic_dword(priv, WFCRC0, 0xffffffff); write_nic_dword(priv, WFCRC1, 0xffffffff); write_nic_dword(priv, WFCRC2, 0xffffffff); -#ifdef RTL8190P - //GPIO 0 = TRUE - ucRegRead = read_nic_byte(priv, GPO); - ucRegRead |= BIT0; - write_nic_byte(priv, GPO, ucRegRead); -#endif //Write PMR register write_nic_byte(priv, PMR, 0x5); //Disable tx, enanble rx diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.c b/drivers/staging/rtl8192e/r819xE_cmdpkt.c index 11ad7cf16f71..ef6f2deb3049 100644 --- a/drivers/staging/rtl8192e/r819xE_cmdpkt.c +++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.c @@ -40,9 +40,6 @@ RT_STATUS cmpk_message_handle_tx( { RT_STATUS rt_status = RT_STATUS_SUCCESS; -#ifdef RTL8192U - return rt_status; -#else struct r8192_priv *priv = ieee80211_priv(dev); u16 frag_threshold; u16 frag_length = 0, frag_offset = 0; @@ -74,11 +71,7 @@ RT_STATUS cmpk_message_handle_tx( /* Allocate skb buffer to contain firmware info and tx descriptor info * add 4 to avoid packet appending overflow. * */ -#ifdef RTL8192U - skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4); -#else skb = dev_alloc_skb(frag_length + priv->ieee80211->tx_headroom + 4); -#endif if(skb == NULL) { rt_status = RT_STATUS_FAILURE; goto Failed; @@ -91,10 +84,6 @@ RT_STATUS cmpk_message_handle_tx( tcb_desc->bLastIniPkt = bLastIniPkt; tcb_desc->pkt_size = frag_length; -#ifdef RTL8192U - skb_reserve(skb, USB_HWDESC_HEADER_LEN); -#endif - //seg_ptr = skb_put(skb, frag_length + priv->ieee80211->tx_headroom); seg_ptr = skb_put(skb, priv->ieee80211->tx_headroom); @@ -126,9 +115,6 @@ RT_STATUS cmpk_message_handle_tx( Failed: //spin_unlock_irqrestore(&priv->tx_lock,flags); return rt_status; - - -#endif } static void diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c index bcd1eda77952..a1312d8f7511 100644 --- a/drivers/staging/rtl8192e/r819xE_phy.c +++ b/drivers/staging/rtl8192e/r819xE_phy.c @@ -24,839 +24,7 @@ static const u32 RF_CHANNEL_TABLE_ZEBRA[] = { 0x0e5c, //2472 13 0x0f72, //2484 }; -#ifdef RTL8190P -u32 Rtl8190PciMACPHY_Array[] = { -0x03c,0xffff0000,0x00000f0f, -0x340,0xffffffff,0x161a1a1a, -0x344,0xffffffff,0x12121416, -0x348,0x0000ffff,0x00001818, -0x12c,0xffffffff,0x04000802, -0x318,0x00000fff,0x00000800, -}; -u32 Rtl8190PciMACPHY_Array_PG[] = { -0x03c,0xffff0000,0x00000f0f, -0x340,0xffffffff,0x0a0c0d0f, -0x344,0xffffffff,0x06070809, -0x344,0xffffffff,0x06070809, -0x348,0x0000ffff,0x00000000, -0x12c,0xffffffff,0x04000802, -0x318,0x00000fff,0x00000800, -}; - -u32 Rtl8190PciAGCTAB_Array[AGCTAB_ArrayLength] = { -0xc78,0x7d000001, -0xc78,0x7d010001, -0xc78,0x7d020001, -0xc78,0x7d030001, -0xc78,0x7c040001, -0xc78,0x7b050001, -0xc78,0x7a060001, -0xc78,0x79070001, -0xc78,0x78080001, -0xc78,0x77090001, -0xc78,0x760a0001, -0xc78,0x750b0001, -0xc78,0x740c0001, -0xc78,0x730d0001, -0xc78,0x720e0001, -0xc78,0x710f0001, -0xc78,0x70100001, -0xc78,0x6f110001, -0xc78,0x6e120001, -0xc78,0x6d130001, -0xc78,0x6c140001, -0xc78,0x6b150001, -0xc78,0x6a160001, -0xc78,0x69170001, -0xc78,0x68180001, -0xc78,0x67190001, -0xc78,0x661a0001, -0xc78,0x651b0001, -0xc78,0x641c0001, -0xc78,0x491d0001, -0xc78,0x481e0001, -0xc78,0x471f0001, -0xc78,0x46200001, -0xc78,0x45210001, -0xc78,0x44220001, -0xc78,0x43230001, -0xc78,0x28240001, -0xc78,0x27250001, -0xc78,0x26260001, -0xc78,0x25270001, -0xc78,0x24280001, -0xc78,0x23290001, -0xc78,0x222a0001, -0xc78,0x212b0001, -0xc78,0x202c0001, -0xc78,0x0a2d0001, -0xc78,0x082e0001, -0xc78,0x062f0001, -0xc78,0x05300001, -0xc78,0x04310001, -0xc78,0x03320001, -0xc78,0x02330001, -0xc78,0x01340001, -0xc78,0x00350001, -0xc78,0x00360001, -0xc78,0x00370001, -0xc78,0x00380001, -0xc78,0x00390001, -0xc78,0x003a0001, -0xc78,0x003b0001, -0xc78,0x003c0001, -0xc78,0x003d0001, -0xc78,0x003e0001, -0xc78,0x003f0001, -0xc78,0x7d400001, -0xc78,0x7d410001, -0xc78,0x7d420001, -0xc78,0x7d430001, -0xc78,0x7c440001, -0xc78,0x7b450001, -0xc78,0x7a460001, -0xc78,0x79470001, -0xc78,0x78480001, -0xc78,0x77490001, -0xc78,0x764a0001, -0xc78,0x754b0001, -0xc78,0x744c0001, -0xc78,0x734d0001, -0xc78,0x724e0001, -0xc78,0x714f0001, -0xc78,0x70500001, -0xc78,0x6f510001, -0xc78,0x6e520001, -0xc78,0x6d530001, -0xc78,0x6c540001, -0xc78,0x6b550001, -0xc78,0x6a560001, -0xc78,0x69570001, -0xc78,0x68580001, -0xc78,0x67590001, -0xc78,0x665a0001, -0xc78,0x655b0001, -0xc78,0x645c0001, -0xc78,0x495d0001, -0xc78,0x485e0001, -0xc78,0x475f0001, -0xc78,0x46600001, -0xc78,0x45610001, -0xc78,0x44620001, -0xc78,0x43630001, -0xc78,0x28640001, -0xc78,0x27650001, -0xc78,0x26660001, -0xc78,0x25670001, -0xc78,0x24680001, -0xc78,0x23690001, -0xc78,0x226a0001, -0xc78,0x216b0001, -0xc78,0x206c0001, -0xc78,0x0a6d0001, -0xc78,0x086e0001, -0xc78,0x066f0001, -0xc78,0x05700001, -0xc78,0x04710001, -0xc78,0x03720001, -0xc78,0x02730001, -0xc78,0x01740001, -0xc78,0x00750001, -0xc78,0x00760001, -0xc78,0x00770001, -0xc78,0x00780001, -0xc78,0x00790001, -0xc78,0x007a0001, -0xc78,0x007b0001, -0xc78,0x007c0001, -0xc78,0x007d0001, -0xc78,0x007e0001, -0xc78,0x007f0001, -0xc78,0x3600001e, -0xc78,0x3601001e, -0xc78,0x3602001e, -0xc78,0x3603001e, -0xc78,0x3604001e, -0xc78,0x3605001e, -0xc78,0x3a06001e, -0xc78,0x3c07001e, -0xc78,0x3e08001e, -0xc78,0x4209001e, -0xc78,0x430a001e, -0xc78,0x450b001e, -0xc78,0x470c001e, -0xc78,0x480d001e, -0xc78,0x490e001e, -0xc78,0x4b0f001e, -0xc78,0x4c10001e, -0xc78,0x4d11001e, -0xc78,0x4d12001e, -0xc78,0x4e13001e, -0xc78,0x4f14001e, -0xc78,0x5015001e, -0xc78,0x5116001e, -0xc78,0x5117001e, -0xc78,0x5218001e, -0xc78,0x5219001e, -0xc78,0x531a001e, -0xc78,0x541b001e, -0xc78,0x541c001e, -0xc78,0x551d001e, -0xc78,0x561e001e, -0xc78,0x561f001e, -0xc78,0x5720001e, -0xc78,0x5821001e, -0xc78,0x5822001e, -0xc78,0x5923001e, -0xc78,0x5924001e, -0xc78,0x5a25001e, -0xc78,0x5b26001e, -0xc78,0x5b27001e, -0xc78,0x5c28001e, -0xc78,0x5c29001e, -0xc78,0x5d2a001e, -0xc78,0x5d2b001e, -0xc78,0x5e2c001e, -0xc78,0x5e2d001e, -0xc78,0x5f2e001e, -0xc78,0x602f001e, -0xc78,0x6030001e, -0xc78,0x6131001e, -0xc78,0x6132001e, -0xc78,0x6233001e, -0xc78,0x6234001e, -0xc78,0x6335001e, -0xc78,0x6336001e, -0xc78,0x6437001e, -0xc78,0x6538001e, -0xc78,0x6639001e, -0xc78,0x663a001e, -0xc78,0x673b001e, -0xc78,0x683c001e, -0xc78,0x693d001e, -0xc78,0x6a3e001e, -0xc78,0x6b3f001e, -}; - -u32 Rtl8190PciPHY_REGArray[PHY_REGArrayLength] = { -0x800,0x00050060, -0x804,0x00000005, -0x808,0x0000fc00, -0x80c,0x0000001c, -0x810,0x801010aa, -0x814,0x000908c0, -0x818,0x00000000, -0x81c,0x00000000, -0x820,0x00000004, -0x824,0x00690000, -0x828,0x00000004, -0x82c,0x00e90000, -0x830,0x00000004, -0x834,0x00690000, -0x838,0x00000004, -0x83c,0x00e90000, -0x840,0x00000000, -0x844,0x00000000, -0x848,0x00000000, -0x84c,0x00000000, -0x850,0x00000000, -0x854,0x00000000, -0x858,0x65a965a9, -0x85c,0x65a965a9, -0x860,0x001f0010, -0x864,0x007f0010, -0x868,0x001f0010, -0x86c,0x007f0010, -0x870,0x0f100f70, -0x874,0x0f100f70, -0x878,0x00000000, -0x87c,0x00000000, -0x880,0x5c385eb8, -0x884,0x6357060d, -0x888,0x0460c341, -0x88c,0x0000ff00, -0x890,0x00000000, -0x894,0xfffffffe, -0x898,0x4c42382f, -0x89c,0x00656056, -0x8b0,0x00000000, -0x8e0,0x00000000, -0x8e4,0x00000000, -0x900,0x00000000, -0x904,0x00000023, -0x908,0x00000000, -0x90c,0x35541545, -0xa00,0x00d0c7d8, -0xa04,0xab1f0008, -0xa08,0x80cd8300, -0xa0c,0x2e62740f, -0xa10,0x95009b78, -0xa14,0x11145008, -0xa18,0x00881117, -0xa1c,0x89140fa0, -0xa20,0x1a1b0000, -0xa24,0x090e1317, -0xa28,0x00000204, -0xa2c,0x00000000, -0xc00,0x00000040, -0xc04,0x0000500f, -0xc08,0x000000e4, -0xc0c,0x6c6c6c6c, -0xc10,0x08000000, -0xc14,0x40000100, -0xc18,0x08000000, -0xc1c,0x40000100, -0xc20,0x08000000, -0xc24,0x40000100, -0xc28,0x08000000, -0xc2c,0x40000100, -0xc30,0x6de9ac44, -0xc34,0x164052cd, -0xc38,0x00070a14, -0xc3c,0x0a969764, -0xc40,0x1f7c403f, -0xc44,0x000100b7, -0xc48,0xec020000, -0xc4c,0x00000300, -0xc50,0x69543420, -0xc54,0x433c0094, -0xc58,0x69543420, -0xc5c,0x433c0094, -0xc60,0x69543420, -0xc64,0x433c0094, -0xc68,0x69543420, -0xc6c,0x433c0094, -0xc70,0x2c7f000d, -0xc74,0x0186175b, -0xc78,0x0000001f, -0xc7c,0x00b91612, -0xc80,0x40000100, -0xc84,0x00000000, -0xc88,0x40000100, -0xc8c,0x08000000, -0xc90,0x40000100, -0xc94,0x00000000, -0xc98,0x40000100, -0xc9c,0x00000000, -0xca0,0x00492492, -0xca4,0x00000000, -0xca8,0x00000000, -0xcac,0x00000000, -0xcb0,0x00000000, -0xcb4,0x00000000, -0xcb8,0x00000000, -0xcbc,0x00492492, -0xcc0,0x00000000, -0xcc4,0x00000000, -0xcc8,0x00000000, -0xccc,0x00000000, -0xcd0,0x00000000, -0xcd4,0x00000000, -0xcd8,0x64b22427, -0xcdc,0x00766932, -0xce0,0x00222222, -0xd00,0x00000740, -0xd04,0x0000040f, -0xd08,0x0000803f, -0xd0c,0x00000001, -0xd10,0xa0633333, -0xd14,0x33333c63, -0xd18,0x6a8f5b6b, -0xd1c,0x00000000, -0xd20,0x00000000, -0xd24,0x00000000, -0xd28,0x00000000, -0xd2c,0xcc979975, -0xd30,0x00000000, -0xd34,0x00000000, -0xd38,0x00000000, -0xd3c,0x00027293, -0xd40,0x00000000, -0xd44,0x00000000, -0xd48,0x00000000, -0xd4c,0x00000000, -0xd50,0x6437140a, -0xd54,0x024dbd02, -0xd58,0x00000000, -0xd5c,0x14032064, -}; -u32 Rtl8190PciPHY_REG_1T2RArray[PHY_REG_1T2RArrayLength] = { -0x800,0x00050060, -0x804,0x00000004, -0x808,0x0000fc00, -0x80c,0x0000001c, -0x810,0x801010aa, -0x814,0x000908c0, -0x818,0x00000000, -0x81c,0x00000000, -0x820,0x00000004, -0x824,0x00690000, -0x828,0x00000004, -0x82c,0x00e90000, -0x830,0x00000004, -0x834,0x00690000, -0x838,0x00000004, -0x83c,0x00e90000, -0x840,0x00000000, -0x844,0x00000000, -0x848,0x00000000, -0x84c,0x00000000, -0x850,0x00000000, -0x854,0x00000000, -0x858,0x65a965a9, -0x85c,0x65a965a9, -0x860,0x001f0000, -0x864,0x007f0000, -0x868,0x001f0010, -0x86c,0x007f0010, -0x870,0x0f100f70, -0x874,0x0f100f70, -0x878,0x00000000, -0x87c,0x00000000, -0x880,0x5c385898, -0x884,0x6357060d, -0x888,0x0460c341, -0x88c,0x0000fc00, -0x890,0x00000000, -0x894,0xfffffffe, -0x898,0x4c42382f, -0x89c,0x00656056, -0x8b0,0x00000000, -0x8e0,0x00000000, -0x8e4,0x00000000, -0x900,0x00000000, -0x904,0x00000023, -0x908,0x00000000, -0x90c,0x34441444, -0xa00,0x00d0c7d8, -0xa04,0x2b1f0008, -0xa08,0x80cd8300, -0xa0c,0x2e62740f, -0xa10,0x95009b78, -0xa14,0x11145008, -0xa18,0x00881117, -0xa1c,0x89140fa0, -0xa20,0x1a1b0000, -0xa24,0x090e1317, -0xa28,0x00000204, -0xa2c,0x00000000, -0xc00,0x00000040, -0xc04,0x0000500c, -0xc08,0x000000e4, -0xc0c,0x6c6c6c6c, -0xc10,0x08000000, -0xc14,0x40000100, -0xc18,0x08000000, -0xc1c,0x40000100, -0xc20,0x08000000, -0xc24,0x40000100, -0xc28,0x08000000, -0xc2c,0x40000100, -0xc30,0x6de9ac44, -0xc34,0x164052cd, -0xc38,0x00070a14, -0xc3c,0x0a969764, -0xc40,0x1f7c403f, -0xc44,0x000100b7, -0xc48,0xec020000, -0xc4c,0x00000300, -0xc50,0x69543420, -0xc54,0x433c0094, -0xc58,0x69543420, -0xc5c,0x433c0094, -0xc60,0x69543420, -0xc64,0x433c0094, -0xc68,0x69543420, -0xc6c,0x433c0094, -0xc70,0x2c7f000d, -0xc74,0x0186175b, -0xc78,0x0000001f, -0xc7c,0x00b91612, -0xc80,0x40000100, -0xc84,0x00000000, -0xc88,0x40000100, -0xc8c,0x08000000, -0xc90,0x40000100, -0xc94,0x00000000, -0xc98,0x40000100, -0xc9c,0x00000000, -0xca0,0x00492492, -0xca4,0x00000000, -0xca8,0x00000000, -0xcac,0x00000000, -0xcb0,0x00000000, -0xcb4,0x00000000, -0xcb8,0x00000000, -0xcbc,0x00492492, -0xcc0,0x00000000, -0xcc4,0x00000000, -0xcc8,0x00000000, -0xccc,0x00000000, -0xcd0,0x00000000, -0xcd4,0x00000000, -0xcd8,0x64b22427, -0xcdc,0x00766932, -0xce0,0x00222222, -0xd00,0x00000740, -0xd04,0x0000040c, -0xd08,0x0000803f, -0xd0c,0x00000001, -0xd10,0xa0633333, -0xd14,0x33333c63, -0xd18,0x6a8f5b6b, -0xd1c,0x00000000, -0xd20,0x00000000, -0xd24,0x00000000, -0xd28,0x00000000, -0xd2c,0xcc979975, -0xd30,0x00000000, -0xd34,0x00000000, -0xd38,0x00000000, -0xd3c,0x00027293, -0xd40,0x00000000, -0xd44,0x00000000, -0xd48,0x00000000, -0xd4c,0x00000000, -0xd50,0x6437140a, -0xd54,0x024dbd02, -0xd58,0x00000000, -0xd5c,0x14032064, -}; - -u32 Rtl8190PciRadioA_Array[RadioA_ArrayLength] = { -0x019,0x00000003, -0x000,0x000000bf, -0x001,0x00000ee0, -0x002,0x0000004c, -0x003,0x000007f1, -0x004,0x00000975, -0x005,0x00000c58, -0x006,0x00000ae6, -0x007,0x000000ca, -0x008,0x00000e1c, -0x009,0x000007f0, -0x00a,0x000009d0, -0x00b,0x000001ba, -0x00c,0x00000240, -0x00e,0x00000020, -0x00f,0x00000990, -0x012,0x00000806, -0x014,0x000005ab, -0x015,0x00000f80, -0x016,0x00000020, -0x017,0x00000597, -0x018,0x0000050a, -0x01a,0x00000f80, -0x01b,0x00000f5e, -0x01c,0x00000008, -0x01d,0x00000607, -0x01e,0x000006cc, -0x01f,0x00000000, -0x020,0x000001a5, -0x01f,0x00000001, -0x020,0x00000165, -0x01f,0x00000002, -0x020,0x000000c6, -0x01f,0x00000003, -0x020,0x00000086, -0x01f,0x00000004, -0x020,0x00000046, -0x01f,0x00000005, -0x020,0x000001e6, -0x01f,0x00000006, -0x020,0x000001a6, -0x01f,0x00000007, -0x020,0x00000166, -0x01f,0x00000008, -0x020,0x000000c7, -0x01f,0x00000009, -0x020,0x00000087, -0x01f,0x0000000a, -0x020,0x000000f7, -0x01f,0x0000000b, -0x020,0x000000d7, -0x01f,0x0000000c, -0x020,0x000000b7, -0x01f,0x0000000d, -0x020,0x00000097, -0x01f,0x0000000e, -0x020,0x00000077, -0x01f,0x0000000f, -0x020,0x00000057, -0x01f,0x00000010, -0x020,0x00000037, -0x01f,0x00000011, -0x020,0x000000fb, -0x01f,0x00000012, -0x020,0x000000db, -0x01f,0x00000013, -0x020,0x000000bb, -0x01f,0x00000014, -0x020,0x000000ff, -0x01f,0x00000015, -0x020,0x000000e3, -0x01f,0x00000016, -0x020,0x000000c3, -0x01f,0x00000017, -0x020,0x000000a3, -0x01f,0x00000018, -0x020,0x00000083, -0x01f,0x00000019, -0x020,0x00000063, -0x01f,0x0000001a, -0x020,0x00000043, -0x01f,0x0000001b, -0x020,0x00000023, -0x01f,0x0000001c, -0x020,0x00000003, -0x01f,0x0000001d, -0x020,0x000001e3, -0x01f,0x0000001e, -0x020,0x000001c3, -0x01f,0x0000001f, -0x020,0x000001a3, -0x01f,0x00000020, -0x020,0x00000183, -0x01f,0x00000021, -0x020,0x00000163, -0x01f,0x00000022, -0x020,0x00000143, -0x01f,0x00000023, -0x020,0x00000123, -0x01f,0x00000024, -0x020,0x00000103, -0x023,0x00000203, -0x024,0x00000200, -0x00b,0x000001ba, -0x02c,0x000003d7, -0x02d,0x00000ff0, -0x000,0x00000037, -0x004,0x00000160, -0x007,0x00000080, -0x002,0x0000088d, -0x0fe,0x00000000, -0x0fe,0x00000000, -0x016,0x00000200, -0x016,0x00000380, -0x016,0x00000020, -0x016,0x000001a0, -0x000,0x000000bf, -0x00d,0x0000001f, -0x00d,0x00000c9f, -0x002,0x0000004d, -0x000,0x00000cbf, -0x004,0x00000975, -0x007,0x00000700, -}; -u32 Rtl8190PciRadioB_Array[RadioB_ArrayLength] = { -0x019,0x00000003, -0x000,0x000000bf, -0x001,0x000006e0, -0x002,0x0000004c, -0x003,0x000007f1, -0x004,0x00000975, -0x005,0x00000c58, -0x006,0x00000ae6, -0x007,0x000000ca, -0x008,0x00000e1c, -0x000,0x000000b7, -0x00a,0x00000850, -0x000,0x000000bf, -0x00b,0x000001ba, -0x00c,0x00000240, -0x00e,0x00000020, -0x015,0x00000f80, -0x016,0x00000020, -0x017,0x00000597, -0x018,0x0000050a, -0x01a,0x00000e00, -0x01b,0x00000f5e, -0x01d,0x00000607, -0x01e,0x000006cc, -0x00b,0x000001ba, -0x023,0x00000203, -0x024,0x00000200, -0x000,0x00000037, -0x004,0x00000160, -0x016,0x00000200, -0x016,0x00000380, -0x016,0x00000020, -0x016,0x000001a0, -0x00d,0x00000ccc, -0x000,0x000000bf, -0x002,0x0000004d, -0x000,0x00000cbf, -0x004,0x00000975, -0x007,0x00000700, -}; -u32 Rtl8190PciRadioC_Array[RadioC_ArrayLength] = { -0x019,0x00000003, -0x000,0x000000bf, -0x001,0x00000ee0, -0x002,0x0000004c, -0x003,0x000007f1, -0x004,0x00000975, -0x005,0x00000c58, -0x006,0x00000ae6, -0x007,0x000000ca, -0x008,0x00000e1c, -0x009,0x000007f0, -0x00a,0x000009d0, -0x00b,0x000001ba, -0x00c,0x00000240, -0x00e,0x00000020, -0x00f,0x00000990, -0x012,0x00000806, -0x014,0x000005ab, -0x015,0x00000f80, -0x016,0x00000020, -0x017,0x00000597, -0x018,0x0000050a, -0x01a,0x00000f80, -0x01b,0x00000f5e, -0x01c,0x00000008, -0x01d,0x00000607, -0x01e,0x000006cc, -0x01f,0x00000000, -0x020,0x000001a5, -0x01f,0x00000001, -0x020,0x00000165, -0x01f,0x00000002, -0x020,0x000000c6, -0x01f,0x00000003, -0x020,0x00000086, -0x01f,0x00000004, -0x020,0x00000046, -0x01f,0x00000005, -0x020,0x000001e6, -0x01f,0x00000006, -0x020,0x000001a6, -0x01f,0x00000007, -0x020,0x00000166, -0x01f,0x00000008, -0x020,0x000000c7, -0x01f,0x00000009, -0x020,0x00000087, -0x01f,0x0000000a, -0x020,0x000000f7, -0x01f,0x0000000b, -0x020,0x000000d7, -0x01f,0x0000000c, -0x020,0x000000b7, -0x01f,0x0000000d, -0x020,0x00000097, -0x01f,0x0000000e, -0x020,0x00000077, -0x01f,0x0000000f, -0x020,0x00000057, -0x01f,0x00000010, -0x020,0x00000037, -0x01f,0x00000011, -0x020,0x000000fb, -0x01f,0x00000012, -0x020,0x000000db, -0x01f,0x00000013, -0x020,0x000000bb, -0x01f,0x00000014, -0x020,0x000000ff, -0x01f,0x00000015, -0x020,0x000000e3, -0x01f,0x00000016, -0x020,0x000000c3, -0x01f,0x00000017, -0x020,0x000000a3, -0x01f,0x00000018, -0x020,0x00000083, -0x01f,0x00000019, -0x020,0x00000063, -0x01f,0x0000001a, -0x020,0x00000043, -0x01f,0x0000001b, -0x020,0x00000023, -0x01f,0x0000001c, -0x020,0x00000003, -0x01f,0x0000001d, -0x020,0x000001e3, -0x01f,0x0000001e, -0x020,0x000001c3, -0x01f,0x0000001f, -0x020,0x000001a3, -0x01f,0x00000020, -0x020,0x00000183, -0x01f,0x00000021, -0x020,0x00000163, -0x01f,0x00000022, -0x020,0x00000143, -0x01f,0x00000023, -0x020,0x00000123, -0x01f,0x00000024, -0x020,0x00000103, -0x023,0x00000203, -0x024,0x00000200, -0x00b,0x000001ba, -0x02c,0x000003d7, -0x02d,0x00000ff0, -0x000,0x00000037, -0x004,0x00000160, -0x007,0x00000080, -0x002,0x0000088d, -0x0fe,0x00000000, -0x0fe,0x00000000, -0x016,0x00000200, -0x016,0x00000380, -0x016,0x00000020, -0x016,0x000001a0, -0x000,0x000000bf, -0x00d,0x0000001f, -0x00d,0x00000c9f, -0x002,0x0000004d, -0x000,0x00000cbf, -0x004,0x00000975, -0x007,0x00000700, -}; -u32 Rtl8190PciRadioD_Array[RadioD_ArrayLength] = { -0x019,0x00000003, -0x000,0x000000bf, -0x001,0x000006e0, -0x002,0x0000004c, -0x003,0x000007f1, -0x004,0x00000975, -0x005,0x00000c58, -0x006,0x00000ae6, -0x007,0x000000ca, -0x008,0x00000e1c, -0x000,0x000000b7, -0x00a,0x00000850, -0x000,0x000000bf, -0x00b,0x000001ba, -0x00c,0x00000240, -0x00e,0x00000020, -0x015,0x00000f80, -0x016,0x00000020, -0x017,0x00000597, -0x018,0x0000050a, -0x01a,0x00000e00, -0x01b,0x00000f5e, -0x01d,0x00000607, -0x01e,0x000006cc, -0x00b,0x000001ba, -0x023,0x00000203, -0x024,0x00000200, -0x000,0x00000037, -0x004,0x00000160, -0x016,0x00000200, -0x016,0x00000380, -0x016,0x00000020, -0x016,0x000001a0, -0x00d,0x00000ccc, -0x000,0x000000bf, -0x002,0x0000004d, -0x000,0x00000cbf, -0x004,0x00000975, -0x007,0x00000700, -}; -#endif -#ifdef RTL8192E + static u32 Rtl8192PciEMACPHY_Array[] = { 0x03c,0xffff0000,0x00000f0f, 0x340,0xffffffff,0x161a1a1a, @@ -1393,7 +561,6 @@ static u32 Rtl8192PciERadioC_Array[RadioC_ArrayLength] = { 0x0, }; static u32 Rtl8192PciERadioD_Array[RadioD_ArrayLength] = { 0x0, }; -#endif /*************************Define local function prototype**********************/ @@ -1427,20 +594,7 @@ u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath) { u8 ret = 1; struct r8192_priv *priv = ieee80211_priv(dev); -#ifdef RTL8190P - if(priv->rf_type == RF_2T4R) - { - ret= 1; - } - else if (priv->rf_type == RF_1T2R) - { - if(eRFPath == RF90_PATH_A || eRFPath == RF90_PATH_B) - ret = 0; - else if(eRFPath == RF90_PATH_C || eRFPath == RF90_PATH_D) - ret = 1; - } -#else - #ifdef RTL8192E + if (priv->rf_type == RF_2T4R) ret = 0; else if (priv->rf_type == RF_1T2R) @@ -1450,8 +604,7 @@ u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath) else if (eRFPath == RF90_PATH_C || eRFPath == RF90_PATH_D) ret = 0; } - #endif -#endif + return ret; } /****************************************************************************** @@ -1518,15 +671,8 @@ static u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eR //switch page for 8256 RF IC if (priv->rf_chip == RF_8256) { -#ifdef RTL8190P - //analog to digital off, for protection - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] -#else - #ifdef RTL8192E //analog to digital off, for protection rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] - #endif -#endif if (Offset >= 31) { priv->RfReg0Value[eRFPath] |= 0x140; @@ -1577,23 +723,8 @@ static u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eR bMaskDWord, (priv->RfReg0Value[eRFPath] << 16)); -#ifdef RTL8190P - if(priv->rf_type == RF_2T4R) - { - //analog to digital on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0xf);// 0x88c[11:8] - } - else if(priv->rf_type == RF_1T2R) - { - //analog to digital on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xc00, 0x3);// 0x88c[11:10] - } -#else - #ifdef RTL8192E //analog to digital on rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] - #endif -#endif } @@ -1631,15 +762,8 @@ static void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E if (priv->rf_chip == RF_8256) { -#ifdef RTL8190P - //analog to digital off, for protection - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] -#else - #ifdef RTL8192E //analog to digital off, for protection rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] - #endif -#endif if (Offset >= 31) { @@ -1685,23 +809,8 @@ static void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E bMaskDWord, (priv->RfReg0Value[eRFPath] << 16)); } -#ifdef RTL8190P - if(priv->rf_type == RF_2T4R) - { - //analog to digital on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0xf);// 0x88c[11:8] - } - else if(priv->rf_type == RF_1T2R) - { - //analog to digital on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xc00, 0x3);// 0x88c[11:10] - } -#else - #ifdef RTL8192E //analog to digital on rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] - #endif -#endif } } @@ -1724,10 +833,8 @@ void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) return; -#ifdef RTL8192E if(priv->ieee80211->eRFPowerState != eRfOn && !priv->being_init_adapter) return; -#endif //down(&priv->rf_sem); RT_TRACE(COMP_PHY, "FW RF CTRL is not ready now\n"); @@ -1775,10 +882,8 @@ u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u3 struct r8192_priv *priv = ieee80211_priv(dev); if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) return 0; -#ifdef RTL8192E if(priv->ieee80211->eRFPowerState != eRfOn && !priv->being_init_adapter) return 0; -#endif down(&priv->rf_sem); if (priv->Rf_Mode == RF_OP_By_FW) { @@ -2281,18 +1386,8 @@ static RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device* dev) //XSTALLCap -#ifdef RTL8190P - dwRegValue = priv->CrystalCap & 0x3; // bit0~1 of crystal cap - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bXtalCap01, dwRegValue); - dwRegValue = ((priv->CrystalCap & 0xc)>>2); // bit2~3 of crystal cap - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, bXtalCap23, dwRegValue); -#else - #ifdef RTL8192E dwRegValue = priv->CrystalCap; rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bXtalCap92x, dwRegValue); - #endif -#endif - } // Check if the CCK HighPower is turned ON. @@ -2325,15 +1420,7 @@ RT_STATUS rtl8192_BBConfig(struct net_device* dev) void rtl8192_phy_getTxPower(struct net_device* dev) { struct r8192_priv *priv = ieee80211_priv(dev); -#ifdef RTL8190P - priv->MCSTxPowerLevelOriginalOffset[0] = - read_nic_dword(priv, MCS_TXAGC); - priv->MCSTxPowerLevelOriginalOffset[1] = - read_nic_dword(priv, (MCS_TXAGC+4)); - priv->CCKTxPowerLevelOriginalOffset = - read_nic_dword(priv, CCK_TXAGC); -#else - #ifdef RTL8192E + priv->MCSTxPowerLevelOriginalOffset[0] = read_nic_dword(priv, rTxAGC_Rate18_06); priv->MCSTxPowerLevelOriginalOffset[1] = @@ -2346,8 +1433,6 @@ void rtl8192_phy_getTxPower(struct net_device* dev) read_nic_dword(priv, rTxAGC_Mcs11_Mcs08); priv->MCSTxPowerLevelOriginalOffset[5] = read_nic_dword(priv, rTxAGC_Mcs15_Mcs12); - #endif -#endif // read rx initial gain priv->DefaultInitialGain[0] = read_nic_byte(priv, rOFDM0_XAAGCCore1); @@ -3002,7 +2087,6 @@ static void CCK_Tx_Power_Track_BW_Switch_TSSI(struct net_device *dev ) } } -#ifndef RTL8190P static void CCK_Tx_Power_Track_BW_Switch_ThermalMeter(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); @@ -3031,23 +2115,16 @@ static void CCK_Tx_Power_Track_BW_Switch_ThermalMeter(struct net_device *dev) } dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); } -#endif static void CCK_Tx_Power_Track_BW_Switch(struct net_device *dev) { -#ifdef RTL8192E struct r8192_priv *priv = ieee80211_priv(dev); -#endif -#ifdef RTL8190P - CCK_Tx_Power_Track_BW_Switch_TSSI(dev); -#else //if(pHalData->bDcut == TRUE) if(priv->IC_Cut >= IC_VersionCut_D) CCK_Tx_Power_Track_BW_Switch_TSSI(dev); else CCK_Tx_Power_Track_BW_Switch_ThermalMeter(dev); -#endif } @@ -3126,15 +2203,7 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) else CCK_Tx_Power_Track_BW_Switch(dev); -#ifdef RTL8190P - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bADClkPhase, 1); - rtl8192_setBBreg(dev, rOFDM0_RxDetector1, bMaskByte0, 0x44); // 0xc30 is for 8190 only, Emily -#else - #ifdef RTL8192E rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 1); - #endif -#endif - break; case HT_CHANNEL_WIDTH_20_40: // Add by Vivi 20071119 @@ -3162,25 +2231,7 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC); -#ifdef RTL8190P - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bADClkPhase, 0); - rtl8192_setBBreg(dev, rOFDM0_RxDetector1, bMaskByte0, 0x42); // 0xc30 is for 8190 only, Emily - - // Set whether CCK should be sent in upper or lower channel. Suggest by YN. 20071207 - // It is set in Tx descriptor for 8192x series - if(priv->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) - { - rtl8192_setBBreg(dev, rFPGA0_RFMOD, (BIT6|BIT5), 0x01); - }else if(priv->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) - { - rtl8192_setBBreg(dev, rFPGA0_RFMOD, (BIT6|BIT5), 0x02); - } - -#else - #ifdef RTL8192E rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 0); - #endif -#endif break; default: RT_TRACE(COMP_ERR, "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n" ,priv->CurrentChannelBW); @@ -3189,7 +2240,6 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) } //Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315 -#if 1 //<3>Set RF related register switch( priv->rf_chip ) { @@ -3215,7 +2265,7 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip); break; } -#endif + atomic_dec(&(priv->ieee80211->atm_swbw)); priv->SetBWModeInProgress= false; diff --git a/drivers/staging/rtl8192e/r819xE_phy.h b/drivers/staging/rtl8192e/r819xE_phy.h index 95a509fa35f8..c676c3ad0c88 100644 --- a/drivers/staging/rtl8192e/r819xE_phy.h +++ b/drivers/staging/rtl8192e/r819xE_phy.h @@ -6,25 +6,6 @@ #define MAX_RFDEPENDCMD_CNT 16 #define MAX_POSTCMD_CNT 16 -#ifdef RTL8190P -#define MACPHY_Array_PGLength 21 -#define Rtl819XMACPHY_Array_PG Rtl8190PciMACPHY_Array_PG -#define Rtl819XMACPHY_Array Rtl8190PciMACPHY_Array -#define RadioC_ArrayLength 246 -#define RadioD_ArrayLength 78 -#define Rtl819XRadioA_Array Rtl8190PciRadioA_Array -#define Rtl819XRadioB_Array Rtl8190PciRadioB_Array -#define Rtl819XRadioC_Array Rtl8190PciRadioC_Array -#define Rtl819XRadioD_Array Rtl8190PciRadioD_Array -#define Rtl819XAGCTAB_Array Rtl8190PciAGCTAB_Array -#define PHY_REGArrayLength 280 -#define Rtl819XPHY_REGArray Rtl8190PciPHY_REGArray -#define PHY_REG_1T2RArrayLength 280 -#define Rtl819XPHY_REG_1T2RArray Rtl8190PciPHY_REG_1T2RArray -#endif - - -#ifdef RTL8192E #define MACPHY_Array_PGLength 30 #define Rtl819XMACPHY_Array_PG Rtl8192PciEMACPHY_Array_PG #define Rtl819XMACPHY_Array Rtl8192PciEMACPHY_Array @@ -39,7 +20,6 @@ #define Rtl819XPHY_REGArray Rtl8192PciEPHY_REGArray #define PHY_REG_1T2RArrayLength 296 #define Rtl819XPHY_REG_1T2RArray Rtl8192PciEPHY_REG_1T2RArray -#endif #define AGCTAB_ArrayLength 384 #define MACPHY_ArrayLength 18 -- cgit v1.2.3 From 57be9583360bcbcc6e712dc881763b1f2e597f50 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 6 Feb 2011 22:54:48 +0900 Subject: staging: rtl8192e: Remove unused debug code Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 42 +--------------------------------- 1 file changed, 1 insertion(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index d3046afce0dd..56d3aed46dfd 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -24,26 +24,6 @@ * Jerry chuang */ - -#undef RX_DONT_PASS_UL -#undef DEBUG_EPROM -#undef DEBUG_RX_VERBOSE -#undef DUMMY_RX -#undef DEBUG_ZERO_RX -#undef DEBUG_RX_SKB -#undef DEBUG_TX_FRAG -#undef DEBUG_RX_FRAG -#undef DEBUG_TX_FILLDESC -#undef DEBUG_TX -#undef DEBUG_IRQ -#undef DEBUG_RX -#undef DEBUG_RXALLOC -#undef DEBUG_REGISTERS -#undef DEBUG_RING -#undef DEBUG_IRQ_TASKLET -#undef DEBUG_TX_ALLOC -#undef DEBUG_TX_DESC - //#define CONFIG_RTL8192_IO_MAP #include #include @@ -67,27 +47,7 @@ #endif //set here to open your trace code. //WB -u32 rt_global_debug_component = - // COMP_INIT | - // COMP_EPROM | - // COMP_PHY | - // COMP_RF | -// COMP_FIRMWARE | - // COMP_TRACE | - // COMP_DOWN | - // COMP_SWBW | - // COMP_SEC | -// COMP_QOS | -// COMP_RATE | - // COMP_RECV | - // COMP_SEND | - // COMP_POWER | - // COMP_EVENTS | - // COMP_RESET | - // COMP_CMDPKT | - // COMP_POWER_TRACKING | - // COMP_INTR | - COMP_ERR ; //always open err flags on +u32 rt_global_debug_component = COMP_ERR ; //always open err flags on static DEFINE_PCI_DEVICE_TABLE(rtl8192_pci_id_tbl) = { /* Realtek */ -- cgit v1.2.3 From 109ded2b46c6cf07256837202fe6ee3c06815923 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 6 Feb 2011 22:54:57 +0900 Subject: staging: rtl8192e: Simplify r8192_set_multicast Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 56d3aed46dfd..b0ae008dbfca 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -4135,23 +4135,8 @@ static void rtl8192_restart(struct work_struct *work) static void r8192_set_multicast(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); - short promisc; - //down(&priv->wx_sem); - - /* FIXME FIXME */ - - promisc = (dev->flags & IFF_PROMISC) ? 1:0; - - if (promisc != priv->promisc) { - ; - // rtl8192_commit(dev); - } - - priv->promisc = promisc; - - //schedule_work(&priv->reset_wq); - //up(&priv->wx_sem); + priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0; } -- cgit v1.2.3 From 79b03af67a7db3622aefe2da8c250775c81fd623 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 6 Feb 2011 22:55:06 +0900 Subject: staging: rtl8192e: Simplify flow of control in rtl8192_rx Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index b0ae008dbfca..a63c6e59b2e9 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -5038,15 +5038,17 @@ static void rtl8192_rx(struct net_device *dev) .freq = IEEE80211_24GHZ_BAND, }; unsigned int count = priv->rxringcount; + prx_fwinfo_819x_pci pDrvInfo = NULL; + struct sk_buff *new_skb; while (count--) { rx_desc_819x_pci *pdesc = &priv->rx_ring[priv->rx_idx];//rx descriptor struct sk_buff *skb = priv->rx_buf[priv->rx_idx];//rx pkt - if (pdesc->OWN){ + if (pdesc->OWN) /* wait data to be filled by hardware */ return; - } else { + stats.bICV = pdesc->ICV; stats.bCRC = pdesc->CRC32; stats.bHwError = pdesc->CRC32 | pdesc->ICV; @@ -5058,13 +5060,12 @@ static void rtl8192_rx(struct net_device *dev) if(stats.bHwError) { stats.bShift = false; goto done; - } else { - prx_fwinfo_819x_pci pDrvInfo = NULL; - struct sk_buff *new_skb = dev_alloc_skb(priv->rxbuffersize); + } + pDrvInfo = NULL; + new_skb = dev_alloc_skb(priv->rxbuffersize); - if (unlikely(!new_skb)) { + if (unlikely(!new_skb)) goto done; - } stats.RxDrvInfoSize = pdesc->RxDrvInfoSize; stats.RxBufShift = ((pdesc->Shift)&0x03); @@ -5143,9 +5144,7 @@ static void rtl8192_rx(struct net_device *dev) skb = new_skb; priv->rx_buf[priv->rx_idx] = skb; *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE); - } - } done: pdesc->BufferAddress = cpu_to_le32(*((dma_addr_t *)skb->cb)); pdesc->OWN = 1; -- cgit v1.2.3 From 1348dc08a912c0bdfc8680df8919dd79de8c3b9a Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 6 Feb 2011 22:55:16 +0900 Subject: staging: rtl8192e: Don't call ieee80211_ps_tx_ack in interrupt context Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index a63c6e59b2e9..d9e47d0d1017 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -988,14 +988,6 @@ static void rtl8192_tx_isr(struct net_device *dev, int prio) kfree_skb(skb); } - if (prio == MGNT_QUEUE) { - if (priv->ieee80211->ack_tx_to_ieee) { - if (rtl8192_is_tx_queue_empty(dev)) { - priv->ieee80211->ack_tx_to_ieee = 0; - ieee80211_ps_tx_ack(priv->ieee80211, 1); - } - } - } if (prio != BEACON_QUEUE) { /* try to deal with the pending packets */ @@ -4957,7 +4949,23 @@ static void rtl8192_tx_resume(struct net_device *dev) static void rtl8192_irq_tx_tasklet(struct r8192_priv *priv) { - rtl8192_tx_resume(priv->ieee80211->dev); + struct rtl8192_tx_ring *mgnt_ring = &priv->tx_ring[MGNT_QUEUE]; + struct net_device *dev = priv->ieee80211->dev; + unsigned long flags; + + /* check if we need to report that the management queue is drained */ + spin_lock_irqsave(&priv->irq_th_lock, flags); + + if (!skb_queue_len(&mgnt_ring->queue) && + priv->ieee80211->ack_tx_to_ieee && + rtl8192_is_tx_queue_empty(dev)) { + priv->ieee80211->ack_tx_to_ieee = 0; + ieee80211_ps_tx_ack(priv->ieee80211, 1); + } + + spin_unlock_irqrestore(&priv->irq_th_lock, flags); + + rtl8192_tx_resume(dev); } /* Record the received data rate */ -- cgit v1.2.3 From 80a4dead575f118267f35afc722a182c0edc9bcf Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 6 Feb 2011 22:55:26 +0900 Subject: staging: rtl8192e: Avoid casting function pointers Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 2 +- drivers/staging/rtl8192e/r8192E_core.c | 41 +++++++++++++++++----------------- 2 files changed, 21 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index f177ad6d7843..de5649285a8c 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1086,7 +1086,7 @@ short rtl8192_is_tx_queue_empty(struct net_device *dev); void IPSEnter(struct net_device *dev); void IPSLeave(struct net_device *dev); void InactivePsWorkItemCallback(struct net_device *dev); -void IPSLeave_wq(void *data); +void IPSLeave_wq(struct work_struct *work); void ieee80211_ips_leave_wq(struct net_device *dev); void ieee80211_ips_leave(struct net_device *dev); #endif diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index d9e47d0d1017..37105848b4c1 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -99,9 +99,9 @@ static struct pci_driver rtl8192_pci_driver = { static void rtl8192_start_beacon(struct net_device *dev); static void rtl8192_stop_beacon(struct net_device *dev); static void rtl819x_watchdog_wqcallback(struct work_struct *work); -static void rtl8192_irq_rx_tasklet(struct r8192_priv *priv); -static void rtl8192_irq_tx_tasklet(struct r8192_priv *priv); -static void rtl8192_prepare_beacon(struct r8192_priv *priv); +static void rtl8192_irq_rx_tasklet(unsigned long arg); +static void rtl8192_irq_tx_tasklet(unsigned long arg); +static void rtl8192_prepare_beacon(unsigned long arg); static irqreturn_t rtl8192_interrupt(int irq, void *netdev); static void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb); static void rtl8192_update_ratr_table(struct net_device* dev); @@ -2175,7 +2175,7 @@ static void rtl8192_init_priv_task(struct net_device* dev) priv->priv_wq = create_workqueue(DRV_NAME); #ifdef ENABLE_IPS - INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq); + INIT_WORK(&priv->ieee80211->ips_leave_wq, IPSLeave_wq); #endif // INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart); @@ -2188,18 +2188,15 @@ static void rtl8192_init_priv_task(struct net_device* dev) //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem); //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem); INIT_WORK(&priv->qos_activate, rtl8192_qos_activate); - INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq); - INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq); + INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq, rtl8192_hw_wakeup_wq); + INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq, rtl8192_hw_sleep_wq); - tasklet_init(&priv->irq_rx_tasklet, - (void(*)(unsigned long))rtl8192_irq_rx_tasklet, - (unsigned long)priv); - tasklet_init(&priv->irq_tx_tasklet, - (void(*)(unsigned long))rtl8192_irq_tx_tasklet, - (unsigned long)priv); - tasklet_init(&priv->irq_prepare_beacon_tasklet, - (void(*)(unsigned long))rtl8192_prepare_beacon, - (unsigned long)priv); + tasklet_init(&priv->irq_rx_tasklet, rtl8192_irq_rx_tasklet, + (unsigned long) priv); + tasklet_init(&priv->irq_tx_tasklet, rtl8192_irq_tx_tasklet, + (unsigned long) priv); + tasklet_init(&priv->irq_prepare_beacon_tasklet, rtl8192_prepare_beacon, + (unsigned long) priv); } static void rtl8192_get_eeprom_size(struct net_device* dev) @@ -3094,8 +3091,9 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) } -static void rtl8192_prepare_beacon(struct r8192_priv *priv) +static void rtl8192_prepare_beacon(unsigned long arg) { + struct r8192_priv *priv = (struct r8192_priv*) arg; struct sk_buff *skb; //unsigned long flags; cb_desc *tcb_desc; @@ -3133,7 +3131,6 @@ static void rtl8192_start_beacon(struct net_device *dev) u16 BcnIFS = 0xf; DMESG("Enabling beacon TX"); - //rtl8192_prepare_beacon(dev); rtl8192_irq_disable(dev); //rtl8192_beacon_tx_enable(dev); @@ -3784,9 +3781,9 @@ IPSLeave(struct net_device *dev) } } -void IPSLeave_wq(void *data) +void IPSLeave_wq(struct work_struct *work) { - struct ieee80211_device *ieee = container_of(data,struct ieee80211_device,ips_leave_wq); + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ips_leave_wq); struct net_device *dev = ieee->dev; struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); @@ -4947,8 +4944,9 @@ static void rtl8192_tx_resume(struct net_device *dev) } } -static void rtl8192_irq_tx_tasklet(struct r8192_priv *priv) +static void rtl8192_irq_tx_tasklet(unsigned long arg) { + struct r8192_priv *priv = (struct r8192_priv*) arg; struct rtl8192_tx_ring *mgnt_ring = &priv->tx_ring[MGNT_QUEUE]; struct net_device *dev = priv->ieee80211->dev; unsigned long flags; @@ -5164,8 +5162,9 @@ done: } -static void rtl8192_irq_rx_tasklet(struct r8192_priv *priv) +static void rtl8192_irq_rx_tasklet(unsigned long arg) { + struct r8192_priv *priv = (struct r8192_priv*) arg; rtl8192_rx(priv->ieee80211->dev); /* unmask RDU */ write_nic_dword(priv, INTA_MASK, read_nic_dword(priv, INTA_MASK) | IMR_RDU); -- cgit v1.2.3 From fb53c2b73f4fc1cfd3d5548b6efbb00b1d7de3a7 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 6 Feb 2011 22:55:39 +0900 Subject: staging: rtl8192e: Delete dead code Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 37105848b4c1..4f19ac483e95 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -5375,12 +5375,13 @@ static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct r8192_priv *priv ; + u32 i; - if(dev){ + if (dev) { unregister_netdev(dev); - priv=ieee80211_priv(dev); + priv = ieee80211_priv(dev); rtl8192_proc_remove_one(dev); @@ -5390,27 +5391,17 @@ static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev) vfree(priv->pFirmware); priv->pFirmware = NULL; } - // priv->rf_close(dev); - // rtl8192_usb_deleteendpoints(dev); destroy_workqueue(priv->priv_wq); - /* redundant with rtl8192_down */ - // rtl8192_irq_disable(dev); - // rtl8192_reset(dev); - // mdelay(10); - { - u32 i; - /* free tx/rx rings */ - rtl8192_free_rx_ring(dev); - for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) { - rtl8192_free_tx_ring(dev, i); - } - } - if(priv->irq){ + /* free tx/rx rings */ + rtl8192_free_rx_ring(dev); + for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) + rtl8192_free_tx_ring(dev, i); + + if (priv->irq) { printk("Freeing irq %d\n",dev->irq); free_irq(dev->irq, dev); priv->irq=0; - } #ifdef CONFIG_RTL8180_IO_MAP -- cgit v1.2.3 From 9236928f155e9e4ae19310359518cedab4e64450 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 6 Feb 2011 22:55:52 +0900 Subject: staging: rtl8192e: Use spin_lock, just one exit path Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 4f19ac483e95..29c36c489016 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1977,11 +1977,10 @@ void rtl8192_hw_wakeup_wq (struct work_struct *work) static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl) { struct r8192_priv *priv = ieee80211_priv(dev); - + u32 tmp; u32 rb = jiffies; - unsigned long flags; - spin_lock_irqsave(&priv->ps_lock,flags); + spin_lock(&priv->ps_lock); // Writing HW register with 0 equals to disable // the timer, that is not really what we want @@ -1994,28 +1993,25 @@ static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl) // if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME)) ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) { - spin_unlock_irqrestore(&priv->ps_lock,flags); printk("too short to sleep::%x, %x, %lx\n",tl, rb, MSECS(MIN_SLEEP_TIME)); - return; + goto out_unlock; } if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))|| ((tl < rb) && (tl>MSECS(69)) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))|| ((tlMSECS(MAX_SLEEP_TIME)))) { printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME)); - spin_unlock_irqrestore(&priv->ps_lock,flags); - return; - } - { - u32 tmp = (tl>rb)?(tl-rb):(rb-tl); - queue_delayed_work(priv->ieee80211->wq, - &priv->ieee80211->hw_wakeup_wq,tmp); - //PowerSave not supported when kernel version less 2.6.20 + goto out_unlock; } + + tmp = (tl>rb)?(tl-rb):(rb-tl); queue_delayed_work(priv->ieee80211->wq, - (void *)&priv->ieee80211->hw_sleep_wq,0); - spin_unlock_irqrestore(&priv->ps_lock,flags); + &priv->ieee80211->hw_wakeup_wq,tmp); + queue_delayed_work(priv->ieee80211->wq, + (void *)&priv->ieee80211->hw_sleep_wq,0); +out_unlock: + spin_unlock(&priv->ps_lock); } static void rtl8192_init_priv_variable(struct net_device* dev) -- cgit v1.2.3 From d2bddcf8c6c6a3450432e93f9ba0746f85e21a39 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 6 Feb 2011 22:56:08 +0900 Subject: staging: rtl8192e: Remove dead code from SetRFPowerState8190 Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8190_rtl8256.c | 72 +++----------------------------- 1 file changed, 6 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index 4c1a5c849b89..7e948daac055 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -307,9 +307,7 @@ SetRFPowerState8190( struct r8192_priv *priv = ieee80211_priv(dev); PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); bool bResult = true; - //u8 eRFPath; u8 i = 0, QueueID = 0; - //ptx_ring head=NULL,tail=NULL; struct rtl8192_tx_ring *ring = NULL; if(priv->SetRFPowerStateInProgress == true) @@ -322,9 +320,6 @@ SetRFPowerState8190( switch( eRFPowerState ) { case eRfOn: - //RXTX enable control: On - //for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) - // PHY_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x2); // turn on RF if((priv->ieee80211->eRFPowerState == eRfOff) && RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) @@ -347,12 +342,10 @@ SetRFPowerState8190( RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); } else { write_nic_byte(priv, ANAPAR, 0x37);//160MHz - //write_nic_byte(priv, MacBlkCtrl, 0x17); // 0x403 mdelay(1); //enable clock 80/88 MHz rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x1); // 0x880[2] priv->bHwRfOffAction = 0; - //} //RF-A, RF-B //enable RF-Chip A/B @@ -368,49 +361,20 @@ SetRFPowerState8190( //analog to digital part2 on rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5] - // Baseband reset 2008.09.30 add - //write_nic_byte(priv, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0)); - - //2 AFE - // 2008.09.30 add - //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x1); // 0x884 - //analog to digital part2 on - //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5] - - - //digital to analog on - //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x13); // 0x880[4:3] - //analog to digital on - //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0xf03);// 0x88c[9:8] - //rx antenna on - //PHY_SetBBReg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0] - //rx antenna on 2008.09.30 mark - //PHY_SetBBReg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0] - - //2 RF - //enable RF-Chip A/B - //rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4] - //rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x1); // 0x864[4] - } - break; + break; // // In current solution, RFSleep=RFOff in order to save power under 802.11 power save. // By Bruce, 2008-01-16. // case eRfSleep: - { + // HW setting had been configured with deeper mode. if(priv->ieee80211->eRFPowerState == eRfOff) break; - // Update current RF state variable. - //priv->ieee80211->eRFPowerState = eRFPowerState; - - //if (pPSC->bLeisurePs) - { for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) { ring = &priv->tx_ring[QueueID]; @@ -433,16 +397,12 @@ SetRFPowerState8190( break; } } - } PHY_SetRtl8192eRfOff(dev); - } - break; - case eRfOff: + break; - // Update current RF state variable. - //priv->ieee80211->eRFPowerState = eRFPowerState; + case eRfOff: // // Disconnect with Any AP or STA. @@ -469,30 +429,11 @@ SetRFPowerState8190( RT_TRACE(COMP_POWER, "\n\n\n SetZebraRFPowerState8185B(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID); break; } - } + } + - { - //if(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC) && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS) if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) { // Disable all components. - // - // Note: - // NicIFSetLinkStatus is a big problem when we indicate the status to OS, - // the OS(XP) will reset. But now, we cnnot find why the NIC is hard to receive - // packets after RF ON. Just keep this function here and still work to find out the root couse. - // By Bruce, 2009-05-01. - // - //NicIFSetLinkStatus( Adapter, RT_MEDIA_DISCONNECT ); - //if HW radio of , need to indicate scan complete first for not be reset. - //if(MgntScanInProgress(pMgntInfo)) - // MgntResetScanProcess( Adapter ); - - // <1> Disable Interrupt - //rtl8192_irq_disable(dev); - // <2> Stop all timer - //MgntCancelAllTimer(Adapter); - // <3> Disable Adapter - //NicIFHaltAdapter(Adapter, false); NicIFDisableNIC(dev); RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); } @@ -501,7 +442,6 @@ SetRFPowerState8190( // IPS should go to this. PHY_SetRtl8192eRfOff(dev); } - } break; default: -- cgit v1.2.3 From 6f304eb29125858abff1f87755900e3f89c48aee Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 6 Feb 2011 22:56:37 +0900 Subject: staging: rtl8192e: Remove rf_chip variable, hardcode to RF_8256 Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8190_rtl8256.c | 246 ++++++++++++++---------------- drivers/staging/rtl8192e/r8192E.h | 10 -- drivers/staging/rtl8192e/r8192E_core.c | 34 +---- drivers/staging/rtl8192e/r819xE_phy.c | 254 ++++++++----------------------- 4 files changed, 185 insertions(+), 359 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index 7e948daac055..6f63f9cd1154 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -299,10 +299,7 @@ void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel) #define MAX_DOZE_WAITING_TIMES_9x 64 static bool -SetRFPowerState8190( - struct net_device* dev, - RT_RF_POWER_STATE eRFPowerState - ) +SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) { struct r8192_priv *priv = ieee80211_priv(dev); PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); @@ -314,147 +311,138 @@ SetRFPowerState8190( return false; priv->SetRFPowerStateInProgress = true; - switch(priv->rf_chip) + switch( eRFPowerState ) { - case RF_8256: - switch( eRFPowerState ) + case eRfOn: + + // turn on RF + if((priv->ieee80211->eRFPowerState == eRfOff) && RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) + { // The current RF state is OFF and the RF OFF level is halting the NIC, re-initialize the NIC. + bool rtstatus = true; + u32 InitializeCount = 3; + do + { + InitializeCount--; + rtstatus = NicIFEnableNIC(dev); + }while( (rtstatus != true) &&(InitializeCount >0) ); + + if(rtstatus != true) + { + RT_TRACE(COMP_ERR,"%s():Initialize Adapter fail,return\n",__FUNCTION__); + priv->SetRFPowerStateInProgress = false; + return false; + } + + RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); + } else { + write_nic_byte(priv, ANAPAR, 0x37);//160MHz + mdelay(1); + //enable clock 80/88 MHz + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x1); // 0x880[2] + priv->bHwRfOffAction = 0; + + //RF-A, RF-B + //enable RF-Chip A/B + rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4] + //analog to digital on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] + //digital to analog on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x3); // 0x880[4:3] + //rx antenna on + rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0] + //rx antenna on + rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0] + //analog to digital part2 on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5] + + } + + break; + + // + // In current solution, RFSleep=RFOff in order to save power under 802.11 power save. + // By Bruce, 2008-01-16. + // + case eRfSleep: + + // HW setting had been configured with deeper mode. + if(priv->ieee80211->eRFPowerState == eRfOff) + break; + + for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) { - case eRfOn: - - // turn on RF - if((priv->ieee80211->eRFPowerState == eRfOff) && RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) - { // The current RF state is OFF and the RF OFF level is halting the NIC, re-initialize the NIC. - bool rtstatus = true; - u32 InitializeCount = 3; - do - { - InitializeCount--; - rtstatus = NicIFEnableNIC(dev); - }while( (rtstatus != true) &&(InitializeCount >0) ); - - if(rtstatus != true) - { - RT_TRACE(COMP_ERR,"%s():Initialize Adapter fail,return\n",__FUNCTION__); - priv->SetRFPowerStateInProgress = false; - return false; - } - - RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); - } else { - write_nic_byte(priv, ANAPAR, 0x37);//160MHz - mdelay(1); - //enable clock 80/88 MHz - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x1); // 0x880[2] - priv->bHwRfOffAction = 0; - - //RF-A, RF-B - //enable RF-Chip A/B - rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4] - //analog to digital on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] - //digital to analog on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x3); // 0x880[4:3] - //rx antenna on - rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0] - //rx antenna on - rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0] - //analog to digital part2 on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5] + ring = &priv->tx_ring[QueueID]; - } + if(skb_queue_len(&ring->queue) == 0) + { + QueueID++; + continue; + } + else + { + RT_TRACE((COMP_POWER|COMP_RF), "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (i+1), QueueID); + udelay(10); + i++; + } + if(i >= MAX_DOZE_WAITING_TIMES_9x) + { + RT_TRACE(COMP_POWER, "\n\n\n TimeOut!! SetRFPowerState8190(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID); break; + } + } - // - // In current solution, RFSleep=RFOff in order to save power under 802.11 power save. - // By Bruce, 2008-01-16. - // - case eRfSleep: - - // HW setting had been configured with deeper mode. - if(priv->ieee80211->eRFPowerState == eRfOff) - break; - - for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) - { - ring = &priv->tx_ring[QueueID]; - - if(skb_queue_len(&ring->queue) == 0) - { - QueueID++; - continue; - } - else - { - RT_TRACE((COMP_POWER|COMP_RF), "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (i+1), QueueID); - udelay(10); - i++; - } - - if(i >= MAX_DOZE_WAITING_TIMES_9x) - { - RT_TRACE(COMP_POWER, "\n\n\n TimeOut!! SetRFPowerState8190(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID); - break; - } - } - - PHY_SetRtl8192eRfOff(dev); + PHY_SetRtl8192eRfOff(dev); - break; + break; - case eRfOff: + case eRfOff: - // - // Disconnect with Any AP or STA. - // - for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) - { - ring = &priv->tx_ring[QueueID]; - - if(skb_queue_len(&ring->queue) == 0) - { - QueueID++; - continue; - } - else - { - RT_TRACE(COMP_POWER, - "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (i+1), QueueID); - udelay(10); - i++; - } - - if(i >= MAX_DOZE_WAITING_TIMES_9x) - { - RT_TRACE(COMP_POWER, "\n\n\n SetZebraRFPowerState8185B(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID); - break; - } - } + // + // Disconnect with Any AP or STA. + // + for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) + { + ring = &priv->tx_ring[QueueID]; + if(skb_queue_len(&ring->queue) == 0) + { + QueueID++; + continue; + } + else + { + RT_TRACE(COMP_POWER, + "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (i+1), QueueID); + udelay(10); + i++; + } - if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) - { // Disable all components. - NicIFDisableNIC(dev); - RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); - } - else if (!(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC)) - { // Normal case. - // IPS should go to this. - PHY_SetRtl8192eRfOff(dev); - } + if(i >= MAX_DOZE_WAITING_TIMES_9x) + { + RT_TRACE(COMP_POWER, "\n\n\n SetZebraRFPowerState8185B(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID); break; - - default: - bResult = false; - RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknow state to set: 0x%X!!!\n", eRFPowerState); - break; + } } + + if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) + { + /* Disable all components. */ + NicIFDisableNIC(dev); + RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); + } + else if (!(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC)) + { + /* Normal case - IPS should go to this. */ + PHY_SetRtl8192eRfOff(dev); + } break; - default: - RT_TRACE(COMP_ERR, "SetRFPowerState8190(): Unknown RF type\n"); - break; + default: + bResult = false; + RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknow state to set: 0x%X!!!\n", eRFPowerState); + break; } if(bResult) diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index de5649285a8c..81aea8816d35 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -543,15 +543,6 @@ typedef struct _BB_REGISTER_DEFINITION{ u32 rfLSSIReadBack; //LSSI RF readback data // 0x8a0~0x8af [16 bytes] }BB_REGISTER_DEFINITION_T, *PBB_REGISTER_DEFINITION_T; -typedef enum _RT_RF_TYPE_819xU{ - RF_TYPE_MIN = 0, - RF_8225, - RF_8256, - RF_8258, - RF_PSEUDO_11N = 4, -}RT_RF_TYPE_819xU, *PRT_RF_TYPE_819xU; - - typedef struct _rate_adaptive { u8 rate_adaptive_disabled; @@ -852,7 +843,6 @@ typedef struct r8192_priv struct semaphore wx_sem; struct semaphore rf_sem; //used to lock rf write operation added by wb, modified by david u8 rf_type; /* 0 means 1T2R, 1 means 2T4R */ - RT_RF_TYPE_819xU rf_chip; short (*rf_set_sens)(struct net_device *dev,short sens); u8 (*rf_set_chan)(struct net_device *dev,u8 ch); diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 29c36c489016..84b56cc27ff7 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -152,15 +152,9 @@ static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv) Dot11d_Init(ieee); ieee->bGlobalDomain = false; //acturally 8225 & 8256 rf chip only support B,G,24N mode - if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256)) - { - min_chan = 1; - max_chan = 14; - } - else - { - RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__); - } + min_chan = 1; + max_chan = 14; + if (ChannelPlan[channel_plan].Len != 0){ // Clear old channel map memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map)); @@ -1832,25 +1826,9 @@ static void rtl8192_refresh_supportrate(struct r8192_priv* priv) memset(ieee->Regdot11HTOperationalRateSet, 0, 16); } -static u8 rtl8192_getSupportedWireleeMode(struct net_device*dev) +static u8 rtl8192_getSupportedWireleeMode(struct net_device *dev) { - struct r8192_priv *priv = ieee80211_priv(dev); - u8 ret = 0; - switch(priv->rf_chip) - { - case RF_8225: - case RF_8256: - case RF_PSEUDO_11N: - ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B); - break; - case RF_8258: - ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G); - break; - default: - ret = WIRELESS_MODE_B; - break; - } - return ret; + return (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B); } static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode) @@ -2480,8 +2458,6 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) //1 Make a copy for following variables and we can change them if we want - priv->rf_chip= RF_8256; - if(priv->RegChannelPlan == 0xf) { priv->ChannelPlan = priv->eeprom_ChannelPlan; diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c index a1312d8f7511..ef23b0eaf659 100644 --- a/drivers/staging/rtl8192e/r819xE_phy.c +++ b/drivers/staging/rtl8192e/r819xE_phy.c @@ -669,35 +669,28 @@ static u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eR Offset &= 0x3f; //switch page for 8256 RF IC - if (priv->rf_chip == RF_8256) + //analog to digital off, for protection + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] + if (Offset >= 31) { - //analog to digital off, for protection - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] - if (Offset >= 31) - { - priv->RfReg0Value[eRFPath] |= 0x140; - //Switch to Reg_Mode2 for Reg 31-45 - rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16) ); - //modify offset - NewOffset = Offset -30; - } - else if (Offset >= 16) - { - priv->RfReg0Value[eRFPath] |= 0x100; - priv->RfReg0Value[eRFPath] &= (~0x40); - //Switch to Reg_Mode 1 for Reg16-30 - rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16) ); + priv->RfReg0Value[eRFPath] |= 0x140; + //Switch to Reg_Mode2 for Reg 31-45 + rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16) ); + //modify offset + NewOffset = Offset -30; + } + else if (Offset >= 16) + { + priv->RfReg0Value[eRFPath] |= 0x100; + priv->RfReg0Value[eRFPath] &= (~0x40); + //Switch to Reg_Mode 1 for Reg16-30 + rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16) ); - NewOffset = Offset - 15; - } - else - NewOffset = Offset; + NewOffset = Offset - 15; } else - { - RT_TRACE((COMP_PHY|COMP_ERR), "check RF type here, need to be 8256\n"); NewOffset = Offset; - } + //put desired read addr to LSSI control Register rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadAddress, NewOffset); //Issue a posedge trigger @@ -713,23 +706,18 @@ static u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eR // Switch back to Reg_Mode0; - if(priv->rf_chip == RF_8256) - { - priv->RfReg0Value[eRFPath] &= 0xebf; - - rtl8192_setBBreg( - dev, - pPhyReg->rf3wireOffset, - bMaskDWord, - (priv->RfReg0Value[eRFPath] << 16)); + priv->RfReg0Value[eRFPath] &= 0xebf; - //analog to digital on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] - } + rtl8192_setBBreg( + dev, + pPhyReg->rf3wireOffset, + bMaskDWord, + (priv->RfReg0Value[eRFPath] << 16)); + //analog to digital on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] return ret; - } /****************************************************************************** @@ -759,33 +747,25 @@ static void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E BB_REGISTER_DEFINITION_T *pPhyReg = &priv->PHYRegDef[eRFPath]; Offset &= 0x3f; - if (priv->rf_chip == RF_8256) - { - //analog to digital off, for protection - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] + //analog to digital off, for protection + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] - if (Offset >= 31) - { - priv->RfReg0Value[eRFPath] |= 0x140; - rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath] << 16)); - NewOffset = Offset - 30; - } - else if (Offset >= 16) - { - priv->RfReg0Value[eRFPath] |= 0x100; - priv->RfReg0Value[eRFPath] &= (~0x40); - rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16)); - NewOffset = Offset - 15; - } - else - NewOffset = Offset; + if (Offset >= 31) + { + priv->RfReg0Value[eRFPath] |= 0x140; + rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath] << 16)); + NewOffset = Offset - 30; } - else + else if (Offset >= 16) { - RT_TRACE((COMP_PHY|COMP_ERR), "check RF type here, need to be 8256\n"); - NewOffset = Offset; + priv->RfReg0Value[eRFPath] |= 0x100; + priv->RfReg0Value[eRFPath] &= (~0x40); + rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16)); + NewOffset = Offset - 15; } + else + NewOffset = Offset; // Put write addr in [5:0] and write data in [31:16] DataAndAddr = (Data<<16) | (NewOffset&0x3f); @@ -798,20 +778,17 @@ static void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E priv->RfReg0Value[eRFPath] = Data; // Switch back to Reg_Mode0; - if(priv->rf_chip == RF_8256) + if(Offset != 0) { - if(Offset != 0) - { - priv->RfReg0Value[eRFPath] &= 0xebf; - rtl8192_setBBreg( - dev, - pPhyReg->rf3wireOffset, - bMaskDWord, - (priv->RfReg0Value[eRFPath] << 16)); - } - //analog to digital on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] + priv->RfReg0Value[eRFPath] &= 0xebf; + rtl8192_setBBreg( + dev, + pPhyReg->rf3wireOffset, + bMaskDWord, + (priv->RfReg0Value[eRFPath] << 16)); } + //analog to digital on + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] } /****************************************************************************** @@ -1555,22 +1532,8 @@ void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel) pHalData->CurrentCckTxPwrIdx = powerlevel; pHalData->CurrentOfdm24GTxPwrIdx = powerlevelOFDM24G; #endif - switch(priv->rf_chip) - { - case RF_8225: - // PHY_SetRF8225CckTxPower(Adapter, powerlevel); - // PHY_SetRF8225OfdmTxPower(Adapter, powerlevelOFDM24G); - break; - case RF_8256: - PHY_SetRF8256CCKTxPower(dev, powerlevel); //need further implement - PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G); - break; - case RF_8258: - break; - default: - RT_TRACE(COMP_ERR, "unknown rf chip in funtion %s()\n", __FUNCTION__); - break; - } + PHY_SetRF8256CCKTxPower(dev, powerlevel); //need further implement + PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G); } /****************************************************************************** @@ -1581,28 +1544,7 @@ void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel) * ***************************************************************************/ RT_STATUS rtl8192_phy_RFConfig(struct net_device* dev) { - struct r8192_priv *priv = ieee80211_priv(dev); - RT_STATUS rtStatus = RT_STATUS_SUCCESS; - switch(priv->rf_chip) - { - case RF_8225: -// rtStatus = PHY_RF8225_Config(Adapter); - break; - case RF_8256: - rtStatus = PHY_RF8256_Config(dev); - break; - - case RF_8258: - break; - case RF_PSEUDO_11N: - //rtStatus = PHY_RF8225_Config(Adapter); - break; - - default: - RT_TRACE(COMP_ERR, "error chip id\n"); - break; - } - return rtStatus; + return PHY_RF8256_Config(dev); } /****************************************************************************** @@ -1699,27 +1641,10 @@ static void rtl8192_SetTxPowerLevel(struct net_device *dev, u8 channel) u8 powerlevel = priv->TxPowerLevelCCK[channel-1]; u8 powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1]; - switch(priv->rf_chip) - { - case RF_8225: -#ifdef TO_DO_LIST - PHY_SetRF8225CckTxPower(Adapter, powerlevel); - PHY_SetRF8225OfdmTxPower(Adapter, powerlevelOFDM24G); -#endif - break; - - case RF_8256: - PHY_SetRF8256CCKTxPower(dev, powerlevel); - PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G); - break; - - case RF_8258: - break; - default: - RT_TRACE(COMP_ERR, "unknown rf chip ID in rtl8192_SetTxPowerLevel()\n"); - break; - } + PHY_SetRF8256CCKTxPower(dev, powerlevel); + PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G); } + /**************************************************************************************** *function: This function set command table variable(struct SwChnlCmd). * input: SwChnlCmd* CmdTable //table to be set. @@ -1823,42 +1748,17 @@ static u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, u8* s // <3> Fill up RF dependent command. RfDependCmdCnt = 0; - switch( priv->rf_chip ) - { - case RF_8225: - if (!(channel >= 1 && channel <= 14)) - { - RT_TRACE(COMP_ERR, "illegal channel for Zebra 8225: %d\n", channel); - return false; - } - rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, - CmdID_RF_WriteReg, rZebra1_Channel, RF_CHANNEL_TABLE_ZEBRA[channel], 10); - rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, - CmdID_End, 0, 0, 0); - break; - - case RF_8256: - // TEST!! This is not the table for 8256!! - if (!(channel >= 1 && channel <= 14)) - { - RT_TRACE(COMP_ERR, "illegal channel for Zebra 8256: %d\n", channel); - return false; - } - rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, - CmdID_RF_WriteReg, rZebra1_Channel, channel, 10); - rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, - CmdID_End, 0, 0, 0); - break; - - case RF_8258: - break; - default: - RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip); + // TEST!! This is not the table for 8256!! + if (!(channel >= 1 && channel <= 14)) + { + RT_TRACE(COMP_ERR, "illegal channel for Zebra 8256: %d\n", channel); return false; - break; } - + rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, + CmdID_RF_WriteReg, rZebra1_Channel, channel, 10); + rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, + CmdID_End, 0, 0, 0); do{ switch(*stage) @@ -2149,11 +2049,6 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz") - if(priv->rf_chip== RF_PSEUDO_11N) - { - priv->SetBWModeInProgress= false; - return; - } if(!priv->up) { priv->SetBWModeInProgress= false; @@ -2241,30 +2136,7 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) //Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315 //<3>Set RF related register - switch( priv->rf_chip ) - { - case RF_8225: -#ifdef TO_DO_LIST - PHY_SetRF8225Bandwidth(Adapter, pHalData->CurrentChannelBW); -#endif - break; - - case RF_8256: - PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW); - break; - - case RF_8258: - // PHY_SetRF8258Bandwidth(); - break; - - case RF_PSEUDO_11N: - // Do Nothing - break; - - default: - RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip); - break; - } + PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW); atomic_dec(&(priv->ieee80211->atm_swbw)); priv->SetBWModeInProgress= false; -- cgit v1.2.3 From ea66f752c003beed8839ecc07f187169309d9afd Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 6 Feb 2011 22:56:57 +0900 Subject: staging: rtl8192e: Remove dead code from MgntActSet_RF_State Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8190_rtl8256.c | 46 +++++--------------------------- 1 file changed, 7 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index 6f63f9cd1154..1b1034bf7e54 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -812,11 +812,6 @@ MgntActSet_RF_State( switch(StateToSet) { case eRfOn: - // - // Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or - // the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02. - // - priv->ieee80211->RfOffReason &= (~ChangeSource); if(! priv->ieee80211->RfOffReason) @@ -837,21 +832,11 @@ MgntActSet_RF_State( case eRfOff: - if (priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS) - { - // - // 060808, Annie: - // Disconnect to current BSS when radio off. Asked by QuanTa. - // - // Set all link status falg, by Bruce, 2007-06-26. - //MgntActSet_802_11_DISASSOCIATE( Adapter, disas_lv_ss ); - MgntDisconnect(dev, disas_lv_ss); - - // Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI. - // 2007.05.28, by shien chang. - - } - + if (priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS) + { + // Disconnect to current BSS when radio off. Asked by QuanTa. + MgntDisconnect(dev, disas_lv_ss); + } priv->ieee80211->RfOffReason |= ChangeSource; bActionAllowed = true; @@ -861,30 +846,13 @@ MgntActSet_RF_State( priv->ieee80211->RfOffReason |= ChangeSource; bActionAllowed = true; break; - - default: - break; } - if(bActionAllowed) + if (bActionAllowed) { RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->ieee80211->RfOffReason); - // Config HW to the specified mode. + // Config HW to the specified mode. SetRFPowerState(dev, StateToSet); - // Turn on RF. - if(StateToSet == eRfOn) - { - //Adapter->HalFunc.HalEnableRxHandler(Adapter); - if(bConnectBySSID) - { - //MgntActSet_802_11_SSID(Adapter, Adapter->MgntInfo.Ssid.Octet, Adapter->MgntInfo.Ssid.Length, TRUE ); - } - } - // Turn off RF. - else if(StateToSet == eRfOff) - { - //Adapter->HalFunc.HalDisableRxHandler(Adapter); - } } else { -- cgit v1.2.3 From ec984e0cabfa1726a3166dff0ef8e04aafc57a71 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 6 Feb 2011 22:57:18 +0900 Subject: staging: rtl8192e: Clean up MlmeDisassociateRequest Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8190_rtl8256.c | 53 ++++++++------------------------ 1 file changed, 13 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index 1b1034bf7e54..b4c315eb4987 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -635,57 +635,30 @@ MlmeDisassociateRequest( } -static void -MgntDisconnectAP( - struct net_device* dev, - u8 asRsn -) +static void MgntDisconnectAP(struct net_device *dev, u8 asRsn) { struct r8192_priv *priv = ieee80211_priv(dev); bool bFilterOutNonAssociatedBSSID = false; + u32 RegRCR, Type; -// -// Commented out by rcnjko, 2005.01.27: -// I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE(). -// -// //2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success -// SecClearAllKeys(Adapter); - - // In WPA WPA2 need to Clear all key ... because new key will set after new handshaking. -#ifdef TO_DO - if( pMgntInfo->SecurityInfo.AuthMode > RT_802_11AuthModeAutoSwitch || - (pMgntInfo->bAPSuportCCKM && pMgntInfo->bCCX8021xenable) ) // In CCKM mode will Clear key - { - SecClearAllKeys(Adapter); - RT_TRACE(COMP_SEC, DBG_LOUD,("======>CCKM clear key...")) - } -#endif - // If disconnect, clear RCR CBSSID bit + /* If disconnect, clear RCR CBSSID bit */ bFilterOutNonAssociatedBSSID = false; - { - u32 RegRCR, Type; - - Type = bFilterOutNonAssociatedBSSID; - //Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RCR, (pu1Byte)(&RegRCR)); - RegRCR = read_nic_dword(priv, RCR); - priv->ReceiveConfig = RegRCR; - if (Type == true) - RegRCR |= (RCR_CBSSID); - else if (Type == false) - RegRCR &= (~RCR_CBSSID); + Type = bFilterOutNonAssociatedBSSID; + RegRCR = read_nic_dword(priv, RCR); + priv->ReceiveConfig = RegRCR; - write_nic_dword(priv, RCR, RegRCR); - priv->ReceiveConfig = RegRCR; + if (Type == true) + RegRCR |= (RCR_CBSSID); + else if (Type == false) + RegRCR &= (~RCR_CBSSID); + write_nic_dword(priv, RCR, RegRCR); + priv->ReceiveConfig = RegRCR; - } - // 2004.10.11, by rcnjko. - //MlmeDisassociateRequest( Adapter, pMgntInfo->Bssid, disas_lv_ss ); - MlmeDisassociateRequest( dev, priv->ieee80211->current_network.bssid, asRsn ); + MlmeDisassociateRequest(dev, priv->ieee80211->current_network.bssid, asRsn); priv->ieee80211->state = IEEE80211_NOLINK; - //pMgntInfo->AsocTimestamp = 0; } -- cgit v1.2.3 From 11a861d9dec8528b1111efdcc7c70618b8cd9d9b Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 6 Feb 2011 22:57:48 +0900 Subject: staging: rtl8192e: Remove dead code Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 93 +--------------------------------- 1 file changed, 2 insertions(+), 91 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 84b56cc27ff7..630b1c7c8e72 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -577,15 +577,10 @@ static void rtl8192_proc_remove_one(struct net_device *dev) printk("dev name=======> %s\n",dev->name); if (priv->dir_dev) { - // remove_proc_entry("stats-hw", priv->dir_dev); remove_proc_entry("stats-tx", priv->dir_dev); remove_proc_entry("stats-rx", priv->dir_dev); - // remove_proc_entry("stats-ieee", priv->dir_dev); remove_proc_entry("stats-ap", priv->dir_dev); remove_proc_entry("registers", priv->dir_dev); - // remove_proc_entry("cck-registers",priv->dir_dev); - // remove_proc_entry("ofdm-registers",priv->dir_dev); - //remove_proc_entry(dev->name, rtl8192_proc); remove_proc_entry("wlan0", rtl8192_proc); priv->dir_dev = NULL; } @@ -1548,7 +1543,7 @@ static void rtl8192_link_change(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); struct ieee80211_device* ieee = priv->ieee80211; - //write_nic_word(priv, BCN_INTR_ITV, net->beacon_interval); + if (ieee->state == IEEE80211_LINKED) { rtl8192_net_update(dev); @@ -1562,9 +1557,7 @@ static void rtl8192_link_change(struct net_device *dev) { write_nic_byte(priv, 0x173, 0); } - /*update timing params*/ - //rtl8192_set_chan(dev, priv->chan); - //MSR + rtl8192_update_msr(dev); // 2007/10/16 MH MAC Will update TSF according to all received beacon, so we have @@ -1631,7 +1624,6 @@ static void rtl8192_qos_activate(struct work_struct * work) (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)| ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET)); write_nic_dword(priv, WDCAPARA_ADD[i], u4bAcParam); - //write_nic_dword(priv, WDCAPARA_ADD[i], 0x005e4332); } success: @@ -2054,8 +2046,6 @@ static void rtl8192_init_priv_variable(struct net_device* dev) priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION; priv->ieee80211->host_encrypt = 1; priv->ieee80211->host_decrypt = 1; - //priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604 - //priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604 priv->ieee80211->start_send_beacons = rtl8192_start_beacon;//+by david 081107 priv->ieee80211->stop_send_beacons = rtl8192_stop_beacon;//+by david 081107 priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit; @@ -2070,22 +2060,17 @@ static void rtl8192_init_priv_variable(struct net_device* dev) priv->ieee80211->tx_headroom = sizeof(TX_FWINFO_8190PCI); priv->ieee80211->qos_support = 1; priv->ieee80211->dot11PowerSaveMode = 0; - //added by WB -// priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl; priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode; priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response; priv->ieee80211->handle_beacon = rtl8192_handle_beacon; priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup; -// priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack; priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep; priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty; - //added by david priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8190Pci; priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode; priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xPci; - //added by amy priv->ieee80211->InitialGainHandler = InitialGain819xPci; #ifdef ENABLE_IPS @@ -2152,15 +2137,11 @@ static void rtl8192_init_priv_task(struct net_device* dev) INIT_WORK(&priv->ieee80211->ips_leave_wq, IPSLeave_wq); #endif -// INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart); INIT_WORK(&priv->reset_wq, rtl8192_restart); -// INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog); INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback); INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback); INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback); INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon); - //INIT_WORK(&priv->SwChnlWorkItem, rtl8192_SwChnl_WorkItem); - //INIT_WORK(&priv->SetBWModeWorkItem, rtl8192_SetBWModeWorkItem); INIT_WORK(&priv->qos_activate, rtl8192_qos_activate); INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq, rtl8192_hw_wakeup_wq); INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq, rtl8192_hw_sleep_wq); @@ -2399,10 +2380,6 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) } else if(priv->epromtype == EPROM_93c56) { - //char cck_pwr_diff_a=0, cck_pwr_diff_c=0; - - //cck_pwr_diff_a = pHalData->EEPROMRfACCKChnl7TxPwLevel - pHalData->EEPROMRfAOfdmChnlTxPwLevel[1]; - //cck_pwr_diff_c = pHalData->EEPROMRfCCCKChnl7TxPwLevel - pHalData->EEPROMRfCOfdmChnlTxPwLevel[1]; for(i=0; i<3; i++) // channel 1~3 use the same Tx Power Level. { priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[0]; @@ -2509,15 +2486,6 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) break; case EEPROM_CID_WHQL: - //Adapter->bInHctTest = TRUE;//do not supported - - //priv->bSupportTurboMode = FALSE; - //priv->bAutoTurboBy8186 = FALSE; - - //pMgntInfo->PowerSaveControl.bInactivePs = FALSE; - //pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE; - //pMgntInfo->PowerSaveControl.bLeisurePs = FALSE; - break; default: // value from RegCustomerID @@ -2634,8 +2602,6 @@ static short rtl8192_init(struct net_device *dev) return -1; } - //rtl8192_rx_enable(dev); - //rtl8192_adapter_start(dev); return 0; } @@ -2720,10 +2686,8 @@ static void rtl8192_hwconfig(struct net_device* dev) static RT_STATUS rtl8192_adapter_start(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); -// struct ieee80211_device *ieee = priv->ieee80211; u32 ulRegRead; RT_STATUS rtStatus = RT_STATUS_SUCCESS; - //u8 eRFPath; u8 tmpvalue; u8 ICVersion,SwitchingRegulatorOutput; bool bfirmwareok = true; @@ -2763,7 +2727,6 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status); write_nic_dword(priv, CPU_GEN, ulRegRead); - //mdelay(100); //3// //3 //Fix the issue of E-cut high temperature issue @@ -2802,7 +2765,6 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) // because setting of System_Reset bit reset MAC to default transmission mode. //Loopback mode or not priv->LoopbackMode = RTL819X_NO_LOOPBACK; - //priv->LoopbackMode = RTL819X_MAC_LOOPBACK; if(priv->ResetProgress == RESET_TYPE_NORESET) { ulRegRead = read_nic_dword(priv, CPU_GEN); @@ -2846,21 +2808,6 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) write_nic_dword(priv, RCR, priv->ReceiveConfig); //3 Initialize Number of Reserved Pages in Firmware Queue - #ifdef TO_DO_LIST - if(priv->bInHctTest) - { - PlatformEFIOWrite4Byte(Adapter, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM << RSVD_FW_QUEUE_PAGE_BK_SHIFT | - NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM << RSVD_FW_QUEUE_PAGE_BE_SHIFT | - NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM << RSVD_FW_QUEUE_PAGE_VI_SHIFT | - NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM <RegWirelessMode); if(priv->ResetProgress == RESET_TYPE_NORESET) rtl8192_SetWirelessMode(dev, priv->ieee80211->mode); //----------------------------------------------------------------------------- @@ -2996,18 +2941,6 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): RF-ON \n",__FUNCTION__); priv->ieee80211->eRFPowerState = eRfOn; priv->ieee80211->RfOffReason = 0; - //DrvIFIndicateCurrentPhyStatus(Adapter); - // LED control - //Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_ON); - - // - // If inactive power mode is enabled, disable rf while in disconnected state. - // But we should still tell upper layer we are in rf on state. - // 2007.07.16, by shien chang. - // - //if(!Adapter->bInHctTest) - //IPSEnter(Adapter); - } } #endif @@ -3627,7 +3560,6 @@ bool MgntActSet_802_11_PowerSaveMode(struct net_device *dev, u8 rtPsMode) { unsigned long flags; - //PlatformSetTimer(Adapter, &(pMgntInfo->AwakeTimer), 0); // Notify the AP we awke. rtl8192_hw_wakeup(dev); priv->ieee80211->sta_sleep = 0; @@ -3647,10 +3579,6 @@ void LeisurePSEnter(struct net_device *dev) struct r8192_priv *priv = ieee80211_priv(dev); PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); - //RT_TRACE(COMP_PS, "LeisurePSEnter()...\n"); - //RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d,pPSC->LpsIdleCount is %d,RT_CHECK_FOR_HANG_PERIOD is %d\n", - // pPSC->bLeisurePs, priv->ieee80211->ps,pPSC->LpsIdleCount,RT_CHECK_FOR_HANG_PERIOD); - if(!((priv->ieee80211->iw_mode == IW_MODE_INFRA) && (priv->ieee80211->state == IEEE80211_LINKED)) || (priv->ieee80211->iw_mode == IW_MODE_ADHOC) || @@ -3665,8 +3593,6 @@ void LeisurePSEnter(struct net_device *dev) if(priv->ieee80211->ps == IEEE80211_PS_DISABLED) { - - //RT_TRACE(COMP_LPS, "LeisurePSEnter(): Enter 802.11 power save mode...\n"); MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST); } @@ -3688,7 +3614,6 @@ void LeisurePSLeave(struct net_device *dev) if(priv->ieee80211->ps != IEEE80211_PS_DISABLED) { // move to lps_wakecomplete() - //RT_TRACE(COMP_LPS, "LeisurePSLeave(): Busy Traffic , Leave 802.11 power save..\n"); MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_DISABLED); } @@ -3747,7 +3672,6 @@ IPSLeave(struct net_device *dev) { RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n"); pPSC->eInactivePowerState = eRfOn; -// queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem)); InactivePsWorkItemCallback(dev); } } @@ -3840,7 +3764,6 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) (!ieee->proto_stoppping) && !ieee->wx_set_enc){ if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){ IPSEnter(dev); - //ieee80211_stop_scan(priv->ieee80211); } } } @@ -3880,7 +3803,6 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) else { #ifdef ENABLE_LPS - //RT_TRACE(COMP_LPS,"====>no link LPS leave\n"); LeisurePSLeave(dev); #endif } @@ -3893,8 +3815,6 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) //added by amy for AP roaming - if (1) - { if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA) { u32 TotalRxBcnNum = 0; @@ -3919,7 +3839,6 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) ieee->LinkDetectInfo.NumRecvBcnInPeriod=0; ieee->LinkDetectInfo.NumRecvDataInPeriod=0; - } //check if reset the driver spin_lock_irqsave(&priv->tx_lock,flags); if (priv->watchdog_check_reset_cnt++ >= 3 && !ieee->is_roaming && @@ -3963,7 +3882,6 @@ void watch_dog_timer_callback(unsigned long data) static int _rtl8192_up(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); - //int i; RT_STATUS init_status = RT_STATUS_SUCCESS; priv->up=1; priv->ieee80211->ieee_up=1; @@ -4314,13 +4232,9 @@ static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct bool bcheck = false; u8 rfpath; u32 nspatial_stream, tmp_val; - //u8 i; static u32 slide_rssi_index=0, slide_rssi_statistics=0; static u32 slide_evm_index=0, slide_evm_statistics=0; static u32 last_rssi=0, last_evm=0; - //cosa add for rx path selection -// static long slide_cck_adc_pwdb_index=0, slide_cck_adc_pwdb_statistics=0; -// static char last_cck_adc_pwdb[4]={0,0,0,0}; //cosa add for beacon rssi smoothing static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0; static u32 last_beacon_adc_pwdb=0; @@ -5337,9 +5251,6 @@ static void rtl8192_cancel_deferred_work(struct r8192_priv* priv) cancel_delayed_work(&priv->gpio_change_rf_wq); cancel_work_sync(&priv->reset_wq); cancel_work_sync(&priv->qos_activate); - //cancel_work_sync(&priv->SetBWModeWorkItem); - //cancel_work_sync(&priv->SwChnlWorkItem); - } -- cgit v1.2.3 From ec42dc2c7f6a530d16562a061cb3d00a63f8a612 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sun, 6 Feb 2011 22:58:07 +0900 Subject: staging: rtl8192e: Factor out common code Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8190_rtl8256.c | 74 ++++++++++++-------------------- 1 file changed, 27 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index b4c315eb4987..4af8f12bad66 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -298,14 +298,37 @@ void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel) } #define MAX_DOZE_WAITING_TIMES_9x 64 +static void r8192e_drain_tx_queues(struct r8192_priv *priv) +{ + u8 i, QueueID; + + for (QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) + { + struct rtl8192_tx_ring *ring = &priv->tx_ring[QueueID]; + + if(skb_queue_len(&ring->queue) == 0) + { + QueueID++; + continue; + } + + udelay(10); + i++; + + if (i >= MAX_DOZE_WAITING_TIMES_9x) + { + RT_TRACE(COMP_POWER, "r8192e_drain_tx_queues() timeout queue %d\n", QueueID); + break; + } + } +} + static bool SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) { struct r8192_priv *priv = ieee80211_priv(dev); PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); bool bResult = true; - u8 i = 0, QueueID = 0; - struct rtl8192_tx_ring *ring = NULL; if(priv->SetRFPowerStateInProgress == true) return false; @@ -369,28 +392,7 @@ SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) if(priv->ieee80211->eRFPowerState == eRfOff) break; - for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) - { - ring = &priv->tx_ring[QueueID]; - - if(skb_queue_len(&ring->queue) == 0) - { - QueueID++; - continue; - } - else - { - RT_TRACE((COMP_POWER|COMP_RF), "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (i+1), QueueID); - udelay(10); - i++; - } - - if(i >= MAX_DOZE_WAITING_TIMES_9x) - { - RT_TRACE(COMP_POWER, "\n\n\n TimeOut!! SetRFPowerState8190(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID); - break; - } - } + r8192e_drain_tx_queues(priv); PHY_SetRtl8192eRfOff(dev); @@ -401,29 +403,7 @@ SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) // // Disconnect with Any AP or STA. // - for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) - { - ring = &priv->tx_ring[QueueID]; - - if(skb_queue_len(&ring->queue) == 0) - { - QueueID++; - continue; - } - else - { - RT_TRACE(COMP_POWER, - "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (i+1), QueueID); - udelay(10); - i++; - } - - if(i >= MAX_DOZE_WAITING_TIMES_9x) - { - RT_TRACE(COMP_POWER, "\n\n\n SetZebraRFPowerState8185B(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID); - break; - } - } + r8192e_drain_tx_queues(priv); if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) -- cgit v1.2.3 From d936435f2082788748ae5783cf2c006367d04bb8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 9 Feb 2011 01:45:13 +0300 Subject: Staging: rtl8712: fix math errors in snprintf() The original code had calls to snprintf(p, 7, "wpa_ie=") but that string is 8 characters (because snprintf() puts a NUL terminator on the end). So instead of an '=' the what gets written to buf is a NUL terminator followed by the rest of the string. And actually the %02x formats are three chars as well when you include the terminator. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_ioctl_linux.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index 0d288c159c1d..221be81c85eb 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -281,18 +281,20 @@ static inline char *translate_scan(struct _adapter *padapter, /* parsing WPA/WPA2 IE */ { u16 wpa_len = 0, rsn_len = 0; - u8 *p; + int n; sint out_len = 0; out_len = r8712_get_sec_ie(pnetwork->network.IEs, pnetwork->network. IELength, rsn_ie, &rsn_len, wpa_ie, &wpa_len); if (wpa_len > 0) { - p = buf; memset(buf, 0, MAX_WPA_IE_LEN); - p += snprintf(p, 7, "wpa_ie="); - for (i = 0; i < wpa_len; i++) - p += snprintf(p, 2, "%02x", wpa_ie[i]); + n = sprintf(buf, "wpa_ie="); + for (i = 0; i < wpa_len; i++) { + n += snprintf(buf + n, MAX_WPA_IE_LEN - n, "%02x", wpa_ie[i]); + if (n >= MAX_WPA_IE_LEN) + break; + } memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVCUSTOM; iwe.u.data.length = (u16)strlen(buf); @@ -305,11 +307,13 @@ static inline char *translate_scan(struct _adapter *padapter, &iwe, wpa_ie); } if (rsn_len > 0) { - p = buf; memset(buf, 0, MAX_WPA_IE_LEN); - p += snprintf(p, 7, "rsn_ie="); - for (i = 0; i < rsn_len; i++) - p += snprintf(p, 2, "%02x", rsn_ie[i]); + n = sprintf(buf, "rsn_ie="); + for (i = 0; i < rsn_len; i++) { + n += snprintf(buf + n, MAX_WPA_IE_LEN - n, "%02x", rsn_ie[i]); + if (n >= MAX_WPA_IE_LEN) + break; + } memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVCUSTOM; iwe.u.data.length = strlen(buf); -- cgit v1.2.3 From 66681fb74e3d2f4dbf40f1e22b315a3807408eaf Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 7 Feb 2011 09:41:47 +0200 Subject: staging/easycap: fix build when SND is not enabled Fix easycap build when CONFIG_SOUND is enabled but CONFIG_SND is not enabled. use choice construct to select between ALSA and OSS API binding drivers/built-in.o: In function `easycap_usb_disconnect': easycap_main.c:(.text+0x2aba20): undefined reference to `snd_card_free' drivers/built-in.o: In function `easycap_alsa_probe': (.text+0x2b784b): undefined reference to `snd_card_create' drivers/built-in.o: In function `easycap_alsa_probe': (.text+0x2b78fb): undefined reference to `snd_pcm_new' drivers/built-in.o: In function `easycap_alsa_probe': (.text+0x2b7916): undefined reference to `snd_pcm_set_ops' drivers/built-in.o: In function `easycap_alsa_probe': (.text+0x2b795b): undefined reference to `snd_card_register' drivers/built-in.o: In function `easycap_alsa_probe': (.text+0x2b79d8): undefined reference to `snd_card_free' drivers/built-in.o: In function `easycap_alsa_probe': (.text+0x2b7a78): undefined reference to `snd_card_free' drivers/built-in.o: In function `easycap_alsa_complete': (.text+0x2b7e68): undefined reference to `snd_pcm_period_elapsed' drivers/built-in.o:(.data+0x2cae8): undefined reference to `snd_pcm_lib_ioctl' Reported-by: Randy Dunlap Cc: R.M. Thomas Signed-off-by: Tomas Winkler Acked-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/Kconfig | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/Kconfig b/drivers/staging/easycap/Kconfig index 5072cf8a5da0..6ed208c61855 100644 --- a/drivers/staging/easycap/Kconfig +++ b/drivers/staging/easycap/Kconfig @@ -1,6 +1,6 @@ config EASYCAP tristate "EasyCAP USB ID 05e1:0408 support" - depends on USB && VIDEO_DEV && SOUND + depends on USB && VIDEO_DEV && (SND || SOUND_OSS_CORE) ---help--- This is an integrated audio/video driver for EasyCAP cards with @@ -15,9 +15,25 @@ config EASYCAP To compile this driver as a module, choose M here: the module will be called easycap +choice + prompt "Sound Interface" + depends on EASYCAP + default EASYCAP_SND + ---help--- + +config EASYCAP_SND + bool "ALSA" + depends on SND + select SND_PCM + + ---help--- + Say 'Y' if you want to use ALSA interface + + This will disable Open Sound System (OSS) binding. + config EASYCAP_OSS bool "OSS (DEPRECATED)" - depends on EASYCAP && SOUND_OSS_CORE + depends on SOUND_OSS_CORE ---help--- Say 'Y' if you prefer Open Sound System (OSS) interface @@ -26,6 +42,7 @@ config EASYCAP_OSS Once binding to ALSA interface will be stable this option will be removed. +endchoice config EASYCAP_DEBUG bool "Enable EasyCAP driver debugging" -- cgit v1.2.3 From ee99aa4928129d4aad9087988db6b7815ecdc1d5 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Feb 2011 01:12:40 +0200 Subject: staging/easycap: remove paranoid argument checks in usb probe/disconnect remove checks for NULL for usb_interface. USB bus won't call these functions with NULL Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_main.c | 29 +++-------------------------- 1 file changed, 3 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 396f56b1e419..cfdbb575322d 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -3145,7 +3145,7 @@ static const struct v4l2_file_operations v4l2_fops = { static int easycap_usb_probe(struct usb_interface *pusb_interface, const struct usb_device_id *pusb_device_id) { - struct usb_device *pusb_device, *pusb_device1; + struct usb_device *pusb_device; struct usb_host_interface *pusb_host_interface; struct usb_endpoint_descriptor *pepd; struct usb_interface_descriptor *pusb_interface_descriptor; @@ -3182,32 +3182,13 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/* setup modules params */ - - if (NULL == pusb_interface) { - SAY("ERROR: pusb_interface is NULL\n"); - return -EFAULT; - } /*---------------------------------------------------------------------------*/ /* * GET POINTER TO STRUCTURE usb_device */ /*---------------------------------------------------------------------------*/ - pusb_device1 = container_of(pusb_interface->dev.parent, - struct usb_device, dev); - if (NULL == pusb_device1) { - SAY("ERROR: pusb_device1 is NULL\n"); - return -EFAULT; - } - pusb_device = usb_get_dev(pusb_device1); - if (NULL == pusb_device) { - SAY("ERROR: pusb_device is NULL\n"); - return -EFAULT; - } - if ((unsigned long int)pusb_device1 != (unsigned long int)pusb_device) { - JOT(4, "ERROR: pusb_device1 != pusb_device\n"); - return -EFAULT; - } + pusb_device = interface_to_usbdev(pusb_interface); + JOT(4, "bNumConfigurations=%i\n", pusb_device->descriptor.bNumConfigurations); /*---------------------------------------------------------------------------*/ pusb_host_interface = pusb_interface->cur_altsetting; @@ -4568,10 +4549,6 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) JOT(4, "\n"); - if (NULL == pusb_interface) { - JOT(4, "ERROR: pusb_interface is NULL\n"); - return; - } pusb_host_interface = pusb_interface->cur_altsetting; if (NULL == pusb_host_interface) { JOT(4, "ERROR: pusb_host_interface is NULL\n"); -- cgit v1.2.3 From aff512c8a4582c7f74af57bb09a9979edf92b6d8 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Feb 2011 01:12:41 +0200 Subject: staging/easycap: prefer printk over SAY in module entry functions Use INFO level when registering driver and ERR for error. Drop messages from oneliner exit function Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_main.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index cfdbb575322d..4385236b2883 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -4829,10 +4829,10 @@ static int __init easycap_module_init(void) { int k, rc; - SAY("========easycap=======\n"); + printk(KERN_INFO "Easycap version: "EASYCAP_DRIVER_VERSION "\n"); + JOT(4, "begins. %i=debug %i=bars %i=gain\n", easycap_debug, easycap_bars, easycap_gain); - SAY("version: " EASYCAP_DRIVER_VERSION "\n"); mutex_init(&mutex_dongle); for (k = 0; k < DONGLE_MANY; k++) { @@ -4840,22 +4840,16 @@ static int __init easycap_module_init(void) mutex_init(&easycapdc60_dongle[k].mutex_video); mutex_init(&easycapdc60_dongle[k].mutex_audio); } - JOT(4, "registering driver easycap\n"); rc = usb_register(&easycap_usb_driver); if (rc) - SAY("ERROR: usb_register returned %i\n", rc); + printk(KERN_ERR "Easycap: usb_register failed rc=%d\n", rc); - JOT(4, "ends\n"); return rc; } /*****************************************************************************/ static void __exit easycap_module_exit(void) { - JOT(4, "begins\n"); - usb_deregister(&easycap_usb_driver); - - JOT(4, "ends\n"); } /*****************************************************************************/ -- cgit v1.2.3 From 8d6139547ca349f9acea6536dd6b7f6140d3507f Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Feb 2011 01:12:42 +0200 Subject: stagine/easycap: use module paramter for default encoding instead of ifdef remove PREFER_NTSC ifdef as it cannot be possible put into Kconfig Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 1 - drivers/staging/easycap/easycap_main.c | 14 +++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index da77e3ee6230..00669b60aa42 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -49,7 +49,6 @@ */ /*---------------------------------------------------------------------------*/ #define PATIENCE 500 -#undef PREFER_NTSC #define PERSEVERE /*---------------------------------------------------------------------------*/ /* diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 4385236b2883..2887f014274b 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -51,6 +51,10 @@ static int easycap_gain = 16; module_param_named(gain, easycap_gain, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(gain, "Audio gain: 0,...,16(default),...31"); +static bool easycap_ntsc; +module_param_named(ntsc, easycap_ntsc, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(ntsc, "NTCS default encoding (default PAL)"); + struct easycap_dongle easycapdc60_dongle[DONGLE_MANY]; @@ -4102,13 +4106,9 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, * BEWARE. */ /*---------------------------------------------------------------------------*/ -#ifdef PREFER_NTSC - peasycap->ntsc = true; - JOM(8, "defaulting initially to NTSC\n"); -#else - peasycap->ntsc = false; - JOM(8, "defaulting initially to PAL\n"); -#endif /*PREFER_NTSC*/ + peasycap->ntsc = easycap_ntsc; + JOM(8, "defaulting initially to %s\n", + easycap_ntsc ? "NTSC" : "PAL"); rc = reset(peasycap); if (rc) { SAM("ERROR: reset() returned %i\n", rc); -- cgit v1.2.3 From 5dd00908be5220477993002896a8c382fa67681a Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Feb 2011 01:12:43 +0200 Subject: staging/easycap: replace one more EASYCAP_NEEDS_ALSA with CONFIG_EASYCAP_OSS Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_ioctl.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 304376f08f5c..a5c6d8ef4f07 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -2389,12 +2389,13 @@ case VIDIOC_STREAMOFF: { /*---------------------------------------------------------------------------*/ JOM(8, "calling wake_up on wq_video and wq_audio\n"); wake_up_interruptible(&(peasycap->wq_video)); -#ifdef EASYCAP_NEEDS_ALSA +#ifdef CONFIG_EASYCAP_OSS + wake_up_interruptible(&(peasycap->wq_audio)); + +#else if (NULL != peasycap->psubstream) snd_pcm_period_elapsed(peasycap->psubstream); -#else - wake_up_interruptible(&(peasycap->wq_audio)); -#endif /*EASYCAP_NEEDS_ALSA*/ +#endif /* CONFIG_EASYCAP_OSS */ /*---------------------------------------------------------------------------*/ break; } -- cgit v1.2.3 From f62bc44e055712fc8ccf34654a79137dd4a4d8af Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Feb 2011 01:12:44 +0200 Subject: staging/easycap: remove obsolete VIDIOC_S_CTRL_OLD ioctl Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_ioctl.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index a5c6d8ef4f07..cbcf3944732c 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -1387,11 +1387,6 @@ case VIDIOC_G_CTRL: { break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -#ifdef VIDIOC_S_CTRL_OLD -case VIDIOC_S_CTRL_OLD: { - JOM(8, "VIDIOC_S_CTRL_OLD required at least for xawtv\n"); -} -#endif /*VIDIOC_S_CTRL_OLD*/ case VIDIOC_S_CTRL: { struct v4l2_control v4l2_control; -- cgit v1.2.3 From 6ae2dbec4d9673ae0935233e42dc890659702dfb Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Feb 2011 01:12:45 +0200 Subject: staging/easycap: remove AUDIOTIME feature remove code guarded by AUDIOTIME define This was experimental code in which I tried improve audio-video synchronization but it didn't work well Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_ioctl.c | 42 --------------------------------- 1 file changed, 42 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index cbcf3944732c..d6d0b725256e 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -2151,13 +2151,6 @@ case VIDIOC_QBUF: { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_DQBUF: { -#ifdef AUDIOTIME - struct signed_div_result sdr; - long long int above, below, dnbydt, fudge, sll; - unsigned long long int ull; - struct timeval timeval8; - struct timeval timeval1; -#endif /*AUDIOTIME*/ struct timeval timeval, timeval2; int i, j; struct v4l2_buffer v4l2_buffer; @@ -2264,41 +2257,6 @@ case VIDIOC_DQBUF: do_gettimeofday(&timeval); timeval2 = timeval; -#ifdef AUDIOTIME - if (!peasycap->timeval0.tv_sec) { - timeval8 = timeval; - timeval1 = timeval; - timeval2 = timeval; - dnbydt = 192000; - peasycap->timeval0 = timeval8; - } else { - dnbydt = peasycap->dnbydt; - timeval1 = peasycap->timeval1; - above = dnbydt * MICROSECONDS(timeval, timeval1); - below = 192000; - sdr = signed_div(above, below); - - above = sdr.quotient + timeval1.tv_usec - 350000; - - below = 1000000; - sdr = signed_div(above, below); - timeval2.tv_usec = sdr.remainder; - timeval2.tv_sec = timeval1.tv_sec + sdr.quotient; - } - if (!(peasycap->isequence % 500)) { - fudge = ((long long int)(1000000)) * - ((long long int)(timeval.tv_sec - - timeval2.tv_sec)) + - (long long int)(timeval.tv_usec - - timeval2.tv_usec); - sdr = signed_div(fudge, 1000); - sll = sdr.quotient; - ull = sdr.remainder; - - SAM("%5lli.%-3lli=ms timestamp fudge\n", sll, ull); - } -#endif /*AUDIOTIME*/ - v4l2_buffer.timestamp = timeval2; v4l2_buffer.sequence = peasycap->isequence++; v4l2_buffer.memory = V4L2_MEMORY_MMAP; -- cgit v1.2.3 From a78392aa3458d93c81201bcc431f166d348cfac6 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Feb 2011 01:12:46 +0200 Subject: staging/easycap: remove EASYCAP_SILENT option This has simulated a fault condition of probing for audio capability Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 1 - drivers/staging/easycap/easycap_low.c | 8 -------- drivers/staging/easycap/easycap_main.c | 6 ------ 3 files changed, 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 00669b60aa42..4753d434867e 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -33,7 +33,6 @@ * EASYCAP_NEEDS_USBVIDEO_H * EASYCAP_NEEDS_V4L2_DEVICE_H * EASYCAP_NEEDS_V4L2_FOPS - * EASYCAP_SILENT * * IF REQUIRED THEY MUST BE EXTERNALLY DEFINED, FOR EXAMPLE AS COMPILER * OPTIONS. diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index f3dc1fc7e255..06ccd19d8457 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -133,11 +133,7 @@ static const struct saa7113config{ int set; } saa7113configPAL[256] = { {0x01, 0x08}, -#ifdef ANTIALIAS - {0x02, 0xC0}, -#else {0x02, 0x80}, -#endif /*ANTIALIAS*/ {0x03, 0x33}, {0x04, 0x00}, {0x05, 0x00}, @@ -191,11 +187,7 @@ static const struct saa7113config{ /*--------------------------------------------------------------------------*/ static const struct saa7113config saa7113configNTSC[256] = { {0x01, 0x08}, -#ifdef ANTIALIAS - {0x02, 0xC0}, -#else {0x02, 0x80}, -#endif /*ANTIALIAS*/ {0x03, 0x33}, {0x04, 0x00}, {0x05, 0x00}, diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 2887f014274b..997e75574f5f 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -4188,9 +4188,6 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, */ /*--------------------------------------------------------------------------*/ case 1: { -#ifdef EASYCAP_SILENT - return -ENOENT; -#endif /*EASYCAP_SILENT*/ if (!peasycap) { SAM("MISTAKE: peasycap is NULL\n"); return -EFAULT; @@ -4207,9 +4204,6 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, } /*--------------------------------------------------------------------------*/ case 2: { -#ifdef EASYCAP_SILENT - return -ENOENT; -#endif /*EASYCAP_SILENT*/ if (!peasycap) { SAM("MISTAKE: peasycap is NULL\n"); return -EFAULT; -- cgit v1.2.3 From 5e7a55c30b52353a4eaca24041dbc3d32a3e3819 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Feb 2011 01:12:47 +0200 Subject: staging/easycap: remove TESTONE and EASYCAP_TESTTONE No longer needed feature for testing driver's handling of the audio stream independently of the urb completion routine Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 3 - drivers/staging/easycap/easycap_sound_oss.c | 10 -- drivers/staging/easycap/easycap_testcard.c | 269 ---------------------------- 3 files changed, 282 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 4753d434867e..7ce3444ab569 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -55,9 +55,6 @@ */ /*---------------------------------------------------------------------------*/ #undef EASYCAP_TESTCARD -#ifdef CONFIG_EASYCAP_OSS -#undef EASYCAP_TESTTONE -#endif /* CONFIG_EASYCAP_OSS */ /*---------------------------------------------------------------------------*/ #include #include diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c index ab1b3ccf4147..0b6065de9656 100644 --- a/drivers/staging/easycap/easycap_sound_oss.c +++ b/drivers/staging/easycap/easycap_sound_oss.c @@ -119,11 +119,6 @@ for (i = 0; i < purb->number_of_packets; i++) { more = purb->iso_frame_desc[i].actual_length; -#ifdef TESTTONE - if (!more) - more = purb->iso_frame_desc[i].length; -#endif - if (!more) peasycap->audio_mt++; else { @@ -167,11 +162,6 @@ for (i = 0; i < purb->number_of_packets; i++) { if (PAGE_SIZE == (paudio_buffer->pto - paudio_buffer->pgo)) { -#ifdef TESTTONE - easyoss_testtone(peasycap, - peasycap->audio_fill); -#endif /*TESTTONE*/ - paudio_buffer->pto = paudio_buffer->pgo; (peasycap->audio_fill)++; diff --git a/drivers/staging/easycap/easycap_testcard.c b/drivers/staging/easycap/easycap_testcard.c index 9f21fc8c1390..e3aa95f9508e 100644 --- a/drivers/staging/easycap/easycap_testcard.c +++ b/drivers/staging/easycap/easycap_testcard.c @@ -150,272 +150,3 @@ for (line = 0; line < (barheight / 2); line++) { } return; } -/*****************************************************************************/ -#ifdef EASYCAP_TESTTONE -/*----------------------------------------------------------------------------- -THE tones[] ARRAY BELOW IS THE OUTPUT OF THIS PROGRAM, -COMPILED gcc -o prog -lm prog.c -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#include -#include - -int main(void); -int -main(void) -{ -int i1, i2, last; -double d1, d2; - -last = 1024 - 1; -d1 = 10.0*3.14159265/1024.0; -printf("int tones[2048] =\n{\n"); -for (i1 = 0; i1 <= last; i1++) - { - d2 = ((double)i1) * d1; - i2 = (int)(16384.0*sin(d2)); - - if (last != i1) - { - printf("%6i, ", i2); printf("%6i, ", i2); - if (!((i1 + 1)%5)) printf("\n"); - } - else - { - printf("%6i, ", i2); printf("%6i\n};\n", i2); - } - } -return 0; -} ------------------------------------------------------------------------------*/ -int tones[2048] = { -0, 0, 502, 502, 1004, 1004, 1505, 1505, 2005, 2005, -2503, 2503, 2998, 2998, 3491, 3491, 3980, 3980, 4466, 4466, -4948, 4948, 5424, 5424, 5896, 5896, 6362, 6362, 6822, 6822, -7276, 7276, 7723, 7723, 8162, 8162, 8594, 8594, 9018, 9018, -9434, 9434, 9840, 9840, 10237, 10237, 10625, 10625, 11002, 11002, -11370, 11370, 11726, 11726, 12072, 12072, 12406, 12406, 12728, 12728, -13038, 13038, 13337, 13337, 13622, 13622, 13895, 13895, 14155, 14155, -14401, 14401, 14634, 14634, 14853, 14853, 15058, 15058, 15249, 15249, -15426, 15426, 15588, 15588, 15735, 15735, 15868, 15868, 15985, 15985, -16088, 16088, 16175, 16175, 16248, 16248, 16305, 16305, 16346, 16346, -16372, 16372, 16383, 16383, 16379, 16379, 16359, 16359, 16323, 16323, -16272, 16272, 16206, 16206, 16125, 16125, 16028, 16028, 15917, 15917, -15790, 15790, 15649, 15649, 15492, 15492, 15322, 15322, 15136, 15136, -14937, 14937, 14723, 14723, 14496, 14496, 14255, 14255, 14001, 14001, -13733, 13733, 13452, 13452, 13159, 13159, 12854, 12854, 12536, 12536, -12207, 12207, 11866, 11866, 11513, 11513, 11150, 11150, 10777, 10777, -10393, 10393, 10000, 10000, 9597, 9597, 9185, 9185, 8765, 8765, -8336, 8336, 7900, 7900, 7456, 7456, 7005, 7005, 6547, 6547, -6083, 6083, 5614, 5614, 5139, 5139, 4659, 4659, 4175, 4175, -3687, 3687, 3196, 3196, 2701, 2701, 2204, 2204, 1705, 1705, -1205, 1205, 703, 703, 201, 201, -301, -301, -803, -803, --1305, -1305, -1805, -1805, -2304, -2304, -2801, -2801, -3294, -3294, --3785, -3785, -4272, -4272, -4756, -4756, -5234, -5234, -5708, -5708, --6176, -6176, -6639, -6639, -7095, -7095, -7545, -7545, -7988, -7988, --8423, -8423, -8850, -8850, -9268, -9268, -9679, -9679, -10079, -10079, --10471, -10471, -10853, -10853, -11224, -11224, -11585, -11585, -11935, -11935, --12273, -12273, -12600, -12600, -12916, -12916, -13219, -13219, -13510, -13510, --13788, -13788, -14053, -14053, -14304, -14304, -14543, -14543, -14767, -14767, --14978, -14978, -15175, -15175, -15357, -15357, -15525, -15525, -15678, -15678, --15817, -15817, -15940, -15940, -16049, -16049, -16142, -16142, -16221, -16221, --16284, -16284, -16331, -16331, -16364, -16364, -16381, -16381, -16382, -16382, --16368, -16368, -16339, -16339, -16294, -16294, -16234, -16234, -16159, -16159, --16069, -16069, -15963, -15963, -15842, -15842, -15707, -15707, -15557, -15557, --15392, -15392, -15212, -15212, -15018, -15018, -14810, -14810, -14589, -14589, --14353, -14353, -14104, -14104, -13842, -13842, -13566, -13566, -13278, -13278, --12977, -12977, -12665, -12665, -12340, -12340, -12003, -12003, -11656, -11656, --11297, -11297, -10928, -10928, -10548, -10548, -10159, -10159, -9759, -9759, --9351, -9351, -8934, -8934, -8509, -8509, -8075, -8075, -7634, -7634, --7186, -7186, -6731, -6731, -6269, -6269, -5802, -5802, -5329, -5329, --4852, -4852, -4369, -4369, -3883, -3883, -3393, -3393, -2900, -2900, --2404, -2404, -1905, -1905, -1405, -1405, -904, -904, -402, -402, -100, 100, 603, 603, 1105, 1105, 1605, 1605, 2105, 2105, -2602, 2602, 3097, 3097, 3589, 3589, 4078, 4078, 4563, 4563, -5043, 5043, 5519, 5519, 5990, 5990, 6455, 6455, 6914, 6914, -7366, 7366, 7811, 7811, 8249, 8249, 8680, 8680, 9102, 9102, -9516, 9516, 9920, 9920, 10315, 10315, 10701, 10701, 11077, 11077, -11442, 11442, 11796, 11796, 12139, 12139, 12471, 12471, 12791, 12791, -13099, 13099, 13395, 13395, 13678, 13678, 13948, 13948, 14205, 14205, -14449, 14449, 14679, 14679, 14895, 14895, 15098, 15098, 15286, 15286, -15459, 15459, 15618, 15618, 15763, 15763, 15892, 15892, 16007, 16007, -16107, 16107, 16191, 16191, 16260, 16260, 16314, 16314, 16353, 16353, -16376, 16376, 16384, 16384, 16376, 16376, 16353, 16353, 16314, 16314, -16260, 16260, 16191, 16191, 16107, 16107, 16007, 16007, 15892, 15892, -15763, 15763, 15618, 15618, 15459, 15459, 15286, 15286, 15098, 15098, -14895, 14895, 14679, 14679, 14449, 14449, 14205, 14205, 13948, 13948, -13678, 13678, 13395, 13395, 13099, 13099, 12791, 12791, 12471, 12471, -12139, 12139, 11796, 11796, 11442, 11442, 11077, 11077, 10701, 10701, -10315, 10315, 9920, 9920, 9516, 9516, 9102, 9102, 8680, 8680, -8249, 8249, 7811, 7811, 7366, 7366, 6914, 6914, 6455, 6455, -5990, 5990, 5519, 5519, 5043, 5043, 4563, 4563, 4078, 4078, -3589, 3589, 3097, 3097, 2602, 2602, 2105, 2105, 1605, 1605, -1105, 1105, 603, 603, 100, 100, -402, -402, -904, -904, --1405, -1405, -1905, -1905, -2404, -2404, -2900, -2900, -3393, -3393, --3883, -3883, -4369, -4369, -4852, -4852, -5329, -5329, -5802, -5802, --6269, -6269, -6731, -6731, -7186, -7186, -7634, -7634, -8075, -8075, --8509, -8509, -8934, -8934, -9351, -9351, -9759, -9759, -10159, -10159, --10548, -10548, -10928, -10928, -11297, -11297, -11656, -11656, -12003, -12003, --12340, -12340, -12665, -12665, -12977, -12977, -13278, -13278, -13566, -13566, --13842, -13842, -14104, -14104, -14353, -14353, -14589, -14589, -14810, -14810, --15018, -15018, -15212, -15212, -15392, -15392, -15557, -15557, -15707, -15707, --15842, -15842, -15963, -15963, -16069, -16069, -16159, -16159, -16234, -16234, --16294, -16294, -16339, -16339, -16368, -16368, -16382, -16382, -16381, -16381, --16364, -16364, -16331, -16331, -16284, -16284, -16221, -16221, -16142, -16142, --16049, -16049, -15940, -15940, -15817, -15817, -15678, -15678, -15525, -15525, --15357, -15357, -15175, -15175, -14978, -14978, -14767, -14767, -14543, -14543, --14304, -14304, -14053, -14053, -13788, -13788, -13510, -13510, -13219, -13219, --12916, -12916, -12600, -12600, -12273, -12273, -11935, -11935, -11585, -11585, --11224, -11224, -10853, -10853, -10471, -10471, -10079, -10079, -9679, -9679, --9268, -9268, -8850, -8850, -8423, -8423, -7988, -7988, -7545, -7545, --7095, -7095, -6639, -6639, -6176, -6176, -5708, -5708, -5234, -5234, --4756, -4756, -4272, -4272, -3785, -3785, -3294, -3294, -2801, -2801, --2304, -2304, -1805, -1805, -1305, -1305, -803, -803, -301, -301, -201, 201, 703, 703, 1205, 1205, 1705, 1705, 2204, 2204, -2701, 2701, 3196, 3196, 3687, 3687, 4175, 4175, 4659, 4659, -5139, 5139, 5614, 5614, 6083, 6083, 6547, 6547, 7005, 7005, -7456, 7456, 7900, 7900, 8336, 8336, 8765, 8765, 9185, 9185, -9597, 9597, 10000, 10000, 10393, 10393, 10777, 10777, 11150, 11150, -11513, 11513, 11866, 11866, 12207, 12207, 12536, 12536, 12854, 12854, -13159, 13159, 13452, 13452, 13733, 13733, 14001, 14001, 14255, 14255, -14496, 14496, 14723, 14723, 14937, 14937, 15136, 15136, 15322, 15322, -15492, 15492, 15649, 15649, 15790, 15790, 15917, 15917, 16028, 16028, -16125, 16125, 16206, 16206, 16272, 16272, 16323, 16323, 16359, 16359, -16379, 16379, 16383, 16383, 16372, 16372, 16346, 16346, 16305, 16305, -16248, 16248, 16175, 16175, 16088, 16088, 15985, 15985, 15868, 15868, -15735, 15735, 15588, 15588, 15426, 15426, 15249, 15249, 15058, 15058, -14853, 14853, 14634, 14634, 14401, 14401, 14155, 14155, 13895, 13895, -13622, 13622, 13337, 13337, 13038, 13038, 12728, 12728, 12406, 12406, -12072, 12072, 11726, 11726, 11370, 11370, 11002, 11002, 10625, 10625, -10237, 10237, 9840, 9840, 9434, 9434, 9018, 9018, 8594, 8594, -8162, 8162, 7723, 7723, 7276, 7276, 6822, 6822, 6362, 6362, -5896, 5896, 5424, 5424, 4948, 4948, 4466, 4466, 3980, 3980, -3491, 3491, 2998, 2998, 2503, 2503, 2005, 2005, 1505, 1505, -1004, 1004, 502, 502, 0, 0, -502, -502, -1004, -1004, --1505, -1505, -2005, -2005, -2503, -2503, -2998, -2998, -3491, -3491, --3980, -3980, -4466, -4466, -4948, -4948, -5424, -5424, -5896, -5896, --6362, -6362, -6822, -6822, -7276, -7276, -7723, -7723, -8162, -8162, --8594, -8594, -9018, -9018, -9434, -9434, -9840, -9840, -10237, -10237, --10625, -10625, -11002, -11002, -11370, -11370, -11726, -11726, -12072, -12072, --12406, -12406, -12728, -12728, -13038, -13038, -13337, -13337, -13622, -13622, --13895, -13895, -14155, -14155, -14401, -14401, -14634, -14634, -14853, -14853, --15058, -15058, -15249, -15249, -15426, -15426, -15588, -15588, -15735, -15735, --15868, -15868, -15985, -15985, -16088, -16088, -16175, -16175, -16248, -16248, --16305, -16305, -16346, -16346, -16372, -16372, -16383, -16383, -16379, -16379, --16359, -16359, -16323, -16323, -16272, -16272, -16206, -16206, -16125, -16125, --16028, -16028, -15917, -15917, -15790, -15790, -15649, -15649, -15492, -15492, --15322, -15322, -15136, -15136, -14937, -14937, -14723, -14723, -14496, -14496, --14255, -14255, -14001, -14001, -13733, -13733, -13452, -13452, -13159, -13159, --12854, -12854, -12536, -12536, -12207, -12207, -11866, -11866, -11513, -11513, --11150, -11150, -10777, -10777, -10393, -10393, -10000, -10000, -9597, -9597, --9185, -9185, -8765, -8765, -8336, -8336, -7900, -7900, -7456, -7456, --7005, -7005, -6547, -6547, -6083, -6083, -5614, -5614, -5139, -5139, --4659, -4659, -4175, -4175, -3687, -3687, -3196, -3196, -2701, -2701, --2204, -2204, -1705, -1705, -1205, -1205, -703, -703, -201, -201, -301, 301, 803, 803, 1305, 1305, 1805, 1805, 2304, 2304, -2801, 2801, 3294, 3294, 3785, 3785, 4272, 4272, 4756, 4756, -5234, 5234, 5708, 5708, 6176, 6176, 6639, 6639, 7095, 7095, -7545, 7545, 7988, 7988, 8423, 8423, 8850, 8850, 9268, 9268, -9679, 9679, 10079, 10079, 10471, 10471, 10853, 10853, 11224, 11224, -11585, 11585, 11935, 11935, 12273, 12273, 12600, 12600, 12916, 12916, -13219, 13219, 13510, 13510, 13788, 13788, 14053, 14053, 14304, 14304, -14543, 14543, 14767, 14767, 14978, 14978, 15175, 15175, 15357, 15357, -15525, 15525, 15678, 15678, 15817, 15817, 15940, 15940, 16049, 16049, -16142, 16142, 16221, 16221, 16284, 16284, 16331, 16331, 16364, 16364, -16381, 16381, 16382, 16382, 16368, 16368, 16339, 16339, 16294, 16294, -16234, 16234, 16159, 16159, 16069, 16069, 15963, 15963, 15842, 15842, -15707, 15707, 15557, 15557, 15392, 15392, 15212, 15212, 15018, 15018, -14810, 14810, 14589, 14589, 14353, 14353, 14104, 14104, 13842, 13842, -13566, 13566, 13278, 13278, 12977, 12977, 12665, 12665, 12340, 12340, -12003, 12003, 11656, 11656, 11297, 11297, 10928, 10928, 10548, 10548, -10159, 10159, 9759, 9759, 9351, 9351, 8934, 8934, 8509, 8509, -8075, 8075, 7634, 7634, 7186, 7186, 6731, 6731, 6269, 6269, -5802, 5802, 5329, 5329, 4852, 4852, 4369, 4369, 3883, 3883, -3393, 3393, 2900, 2900, 2404, 2404, 1905, 1905, 1405, 1405, -904, 904, 402, 402, -100, -100, -603, -603, -1105, -1105, --1605, -1605, -2105, -2105, -2602, -2602, -3097, -3097, -3589, -3589, --4078, -4078, -4563, -4563, -5043, -5043, -5519, -5519, -5990, -5990, --6455, -6455, -6914, -6914, -7366, -7366, -7811, -7811, -8249, -8249, --8680, -8680, -9102, -9102, -9516, -9516, -9920, -9920, -10315, -10315, --10701, -10701, -11077, -11077, -11442, -11442, -11796, -11796, -12139, -12139, --12471, -12471, -12791, -12791, -13099, -13099, -13395, -13395, -13678, -13678, --13948, -13948, -14205, -14205, -14449, -14449, -14679, -14679, -14895, -14895, --15098, -15098, -15286, -15286, -15459, -15459, -15618, -15618, -15763, -15763, --15892, -15892, -16007, -16007, -16107, -16107, -16191, -16191, -16260, -16260, --16314, -16314, -16353, -16353, -16376, -16376, -16383, -16383, -16376, -16376, --16353, -16353, -16314, -16314, -16260, -16260, -16191, -16191, -16107, -16107, --16007, -16007, -15892, -15892, -15763, -15763, -15618, -15618, -15459, -15459, --15286, -15286, -15098, -15098, -14895, -14895, -14679, -14679, -14449, -14449, --14205, -14205, -13948, -13948, -13678, -13678, -13395, -13395, -13099, -13099, --12791, -12791, -12471, -12471, -12139, -12139, -11796, -11796, -11442, -11442, --11077, -11077, -10701, -10701, -10315, -10315, -9920, -9920, -9516, -9516, --9102, -9102, -8680, -8680, -8249, -8249, -7811, -7811, -7366, -7366, --6914, -6914, -6455, -6455, -5990, -5990, -5519, -5519, -5043, -5043, --4563, -4563, -4078, -4078, -3589, -3589, -3097, -3097, -2602, -2602, --2105, -2105, -1605, -1605, -1105, -1105, -603, -603, -100, -100, -402, 402, 904, 904, 1405, 1405, 1905, 1905, 2404, 2404, -2900, 2900, 3393, 3393, 3883, 3883, 4369, 4369, 4852, 4852, -5329, 5329, 5802, 5802, 6269, 6269, 6731, 6731, 7186, 7186, -7634, 7634, 8075, 8075, 8509, 8509, 8934, 8934, 9351, 9351, -9759, 9759, 10159, 10159, 10548, 10548, 10928, 10928, 11297, 11297, -11656, 11656, 12003, 12003, 12340, 12340, 12665, 12665, 12977, 12977, -13278, 13278, 13566, 13566, 13842, 13842, 14104, 14104, 14353, 14353, -14589, 14589, 14810, 14810, 15018, 15018, 15212, 15212, 15392, 15392, -15557, 15557, 15707, 15707, 15842, 15842, 15963, 15963, 16069, 16069, -16159, 16159, 16234, 16234, 16294, 16294, 16339, 16339, 16368, 16368, -16382, 16382, 16381, 16381, 16364, 16364, 16331, 16331, 16284, 16284, -16221, 16221, 16142, 16142, 16049, 16049, 15940, 15940, 15817, 15817, -15678, 15678, 15525, 15525, 15357, 15357, 15175, 15175, 14978, 14978, -14767, 14767, 14543, 14543, 14304, 14304, 14053, 14053, 13788, 13788, -13510, 13510, 13219, 13219, 12916, 12916, 12600, 12600, 12273, 12273, -11935, 11935, 11585, 11585, 11224, 11224, 10853, 10853, 10471, 10471, -10079, 10079, 9679, 9679, 9268, 9268, 8850, 8850, 8423, 8423, -7988, 7988, 7545, 7545, 7095, 7095, 6639, 6639, 6176, 6176, -5708, 5708, 5234, 5234, 4756, 4756, 4272, 4272, 3785, 3785, -3294, 3294, 2801, 2801, 2304, 2304, 1805, 1805, 1305, 1305, -803, 803, 301, 301, -201, -201, -703, -703, -1205, -1205, --1705, -1705, -2204, -2204, -2701, -2701, -3196, -3196, -3687, -3687, --4175, -4175, -4659, -4659, -5139, -5139, -5614, -5614, -6083, -6083, --6547, -6547, -7005, -7005, -7456, -7456, -7900, -7900, -8336, -8336, --8765, -8765, -9185, -9185, -9597, -9597, -10000, -10000, -10393, -10393, --10777, -10777, -11150, -11150, -11513, -11513, -11866, -11866, -12207, -12207, --12536, -12536, -12854, -12854, -13159, -13159, -13452, -13452, -13733, -13733, --14001, -14001, -14255, -14255, -14496, -14496, -14723, -14723, -14937, -14937, --15136, -15136, -15322, -15322, -15492, -15492, -15649, -15649, -15790, -15790, --15917, -15917, -16028, -16028, -16125, -16125, -16206, -16206, -16272, -16272, --16323, -16323, -16359, -16359, -16379, -16379, -16383, -16383, -16372, -16372, --16346, -16346, -16305, -16305, -16248, -16248, -16175, -16175, -16088, -16088, --15985, -15985, -15868, -15868, -15735, -15735, -15588, -15588, -15426, -15426, --15249, -15249, -15058, -15058, -14853, -14853, -14634, -14634, -14401, -14401, --14155, -14155, -13895, -13895, -13622, -13622, -13337, -13337, -13038, -13038, --12728, -12728, -12406, -12406, -12072, -12072, -11726, -11726, -11370, -11370, --11002, -11002, -10625, -10625, -10237, -10237, -9840, -9840, -9434, -9434, --9018, -9018, -8594, -8594, -8162, -8162, -7723, -7723, -7276, -7276, --6822, -6822, -6362, -6362, -5896, -5896, -5424, -5424, -4948, -4948, --4466, -4466, -3980, -3980, -3491, -3491, -2998, -2998, -2503, -2503, --2005, -2005, -1505, -1505, -1004, -1004, -502, -502 -}; -/*****************************************************************************/ -void -easyoss_testtone(struct easycap *peasycap, int audio_fill) -{ -int i1; -unsigned char *p2; -struct data_buffer *paudio_buffer; - -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return; -} -JOM(8, "%i=audio_fill\n", audio_fill); -paudio_buffer = &peasycap->audio_buffer[audio_fill]; -p2 = (unsigned char *)(paudio_buffer->pgo); -for (i1 = 0; i1 < PAGE_SIZE; i1 += 4, p2 += 4) { - *p2 = (unsigned char) (0x00FF & tones[i1/2]); - *(p2 + 1) = (unsigned char)((0xFF00 & tones[i1/2]) >> 8); - *(p2 + 2) = (unsigned char) (0x00FF & tones[i1/2 + 1]); - *(p2 + 3) = (unsigned char)((0xFF00 & tones[i1/2 + 1]) >> 8); - } -return; -} -#endif /*EASYCAP_TESTTONE*/ -/*****************************************************************************/ -- cgit v1.2.3 From 4d59fde3d18a8adc8d35ff595daf1253783d3847 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Feb 2011 01:12:48 +0200 Subject: staging/easycap: add first level indentation to regget/set functions Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_low.c | 132 +++++++++++++++++----------------- 1 file changed, 66 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index 06ccd19d8457..1ed90f94171d 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -903,86 +903,86 @@ for (k = 0; k < max; k++) { return -1; } /****************************************************************************/ -int -regset(struct usb_device *pusb_device, u16 index, u16 value) +int regset(struct usb_device *pusb_device, u16 index, u16 value) { -u16 igot; -int rc0, rc1; + u16 igot; + int rc0, rc1; -if (!pusb_device) - return -ENODEV; -rc1 = 0; igot = 0; -rc0 = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), - (u8)0x01, - (u8)(USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE), - (u16)value, - (u16)index, - NULL, - (u16)0, - (int)500); + if (!pusb_device) + return -ENODEV; + + rc1 = 0; igot = 0; + rc0 = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), + (u8)0x01, + (u8)(USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE), + (u16)value, + (u16)index, + NULL, + (u16)0, + (int)500); #ifdef NOREADBACK # #else -rc1 = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), - (u8)0x00, - (u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), - (u16)0x00, - (u16)index, - (void *)&igot, - (u16)sizeof(u16), - (int)50000); -igot = 0xFF & igot; -switch (index) { -case 0x000: -case 0x500: -case 0x502: -case 0x503: -case 0x504: -case 0x506: -case 0x507: { - break; -} -case 0x204: -case 0x205: -case 0x350: -case 0x351: { - if (0 != (0xFF & igot)) { - JOT(8, "unexpected 0x%02X for STK register 0x%03X\n", + rc1 = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), + (u8)0x00, + (u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), + (u16)0x00, + (u16)index, + (void *)&igot, + (u16)sizeof(u16), + (int)50000); + igot = 0xFF & igot; + switch (index) { + case 0x000: + case 0x500: + case 0x502: + case 0x503: + case 0x504: + case 0x506: + case 0x507: + break; + + case 0x204: + case 0x205: + case 0x350: + case 0x351: + if (0 != (0xFF & igot)) { + JOT(8, "unexpected 0x%02X for STK register 0x%03X\n", igot, index); + } + break; + + default: + if ((0xFF & value) != (0xFF & igot)) { + JOT(8, "unexpected 0x%02X != 0x%02X " + "for STK register 0x%03X\n", + igot, value, index); + } + break; } -break; -} -default: { - if ((0xFF & value) != (0xFF & igot)) { - JOT(8, "unexpected 0x%02X != 0x%02X " - "for STK register 0x%03X\n", - igot, value, index); - } -break; -} -} #endif /* ! NOREADBACK*/ -return (0 > rc0) ? rc0 : rc1; + return (0 > rc0) ? rc0 : rc1; } /*****************************************************************************/ -int -regget(struct usb_device *pusb_device, u16 index, void *pvoid) +int regget(struct usb_device *pusb_device, u16 index, void *pvoid) { -int ir; + int rc; -if (!pusb_device) - return -ENODEV; -ir = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), - (u8)0x00, - (u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), - (u16)0x00, - (u16)index, - (void *)pvoid, - sizeof(u8), - (int)50000); -return 0xFF & ir; + if (!pusb_device) + return -ENODEV; + + rc = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), + (u8)0x00, + (u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), + (u16)0x00, + (u16)index, + (void *)pvoid, + sizeof(u8), + (int)50000); + + return 0xFF & rc; } /*****************************************************************************/ int -- cgit v1.2.3 From 73132ce45a011ef76340e3d6393e79d8377e4312 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Feb 2011 01:12:49 +0200 Subject: stagine/easycap: make functions regset and regget static regget and regset functions are used only from within easycap_low.c so they can be static Move the functions to avoid forward declarations Move GET and SET macro definitions into the c-file Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 23 ----- drivers/staging/easycap/easycap_low.c | 182 +++++++++++++++++++--------------- 2 files changed, 100 insertions(+), 105 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 7ce3444ab569..0ee60af6ccd9 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -575,8 +575,6 @@ int stop_100(struct usb_device *); int write_300(struct usb_device *); int read_vt(struct usb_device *, u16); int write_vt(struct usb_device *, u16, u16); -int regset(struct usb_device *, u16, u16); -int regget(struct usb_device *, u16, void *); int isdongle(struct easycap *); /*---------------------------------------------------------------------------*/ struct signed_div_result { @@ -585,27 +583,6 @@ struct signed_div_result { } signed_div(long long int, long long int); -/*---------------------------------------------------------------------------*/ -/* - * MACROS - */ -/*---------------------------------------------------------------------------*/ -#define GET(X, Y, Z) do { \ - int __rc; \ - *(Z) = (u16)0; \ - __rc = regget(X, Y, Z); \ - if (0 > __rc) { \ - JOT(8, ":-(%i\n", __LINE__); return __rc; \ - } \ -} while (0) - -#define SET(X, Y, Z) do { \ - int __rc; \ - __rc = regset(X, Y, Z); \ - if (0 > __rc) { \ - JOT(8, ":-(%i\n", __LINE__); return __rc; \ - } \ -} while (0) /*---------------------------------------------------------------------------*/ /* * MACROS SAM(...) AND JOM(...) ALLOW DIAGNOSTIC OUTPUT TO BE TAGGED WITH diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index 1ed90f94171d..39e22d51910b 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -40,6 +40,23 @@ #include "easycap.h" +#define GET(X, Y, Z) do { \ + int __rc; \ + *(Z) = (u16)0; \ + __rc = regget(X, Y, Z); \ + if (0 > __rc) { \ + JOT(8, ":-(%i\n", __LINE__); return __rc; \ + } \ +} while (0) + +#define SET(X, Y, Z) do { \ + int __rc; \ + __rc = regset(X, Y, Z); \ + if (0 > __rc) { \ + JOT(8, ":-(%i\n", __LINE__); return __rc; \ + } \ +} while (0) + /*--------------------------------------------------------------------------*/ static const struct stk1160config { int reg; @@ -238,7 +255,89 @@ static const struct saa7113config saa7113configNTSC[256] = { {0xFF, 0xFF} }; -/*--------------------------------------------------------------------------*/ + +static int regget(struct usb_device *pusb_device, u16 index, void *pvoid) +{ + int rc; + + if (!pusb_device) + return -ENODEV; + + rc = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), + (u8)0x00, + (u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), + (u16)0x00, + (u16)index, + (void *)pvoid, + sizeof(u8), + (int)50000); + + return 0xFF & rc; +} + +static int regset(struct usb_device *pusb_device, u16 index, u16 value) +{ + u16 igot; + int rc0, rc1; + + if (!pusb_device) + return -ENODEV; + + rc1 = 0; igot = 0; + rc0 = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), + (u8)0x01, + (u8)(USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE), + (u16)value, + (u16)index, + NULL, + (u16)0, + (int)500); + +#ifdef NOREADBACK +# +#else + rc1 = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), + (u8)0x00, + (u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), + (u16)0x00, + (u16)index, + (void *)&igot, + (u16)sizeof(u16), + (int)50000); + igot = 0xFF & igot; + switch (index) { + case 0x000: + case 0x500: + case 0x502: + case 0x503: + case 0x504: + case 0x506: + case 0x507: + break; + + case 0x204: + case 0x205: + case 0x350: + case 0x351: + if (0 != (0xFF & igot)) { + JOT(8, "unexpected 0x%02X for STK register 0x%03X\n", + igot, index); + } + break; + + default: + if ((0xFF & value) != (0xFF & igot)) { + JOT(8, "unexpected 0x%02X != 0x%02X " + "for STK register 0x%03X\n", + igot, value, index); + } + break; + } +#endif /* ! NOREADBACK*/ + + return (0 > rc0) ? rc0 : rc1; +} +/*****************************************************************************/ /****************************************************************************/ int @@ -903,87 +1002,6 @@ for (k = 0; k < max; k++) { return -1; } /****************************************************************************/ -int regset(struct usb_device *pusb_device, u16 index, u16 value) -{ - u16 igot; - int rc0, rc1; - - if (!pusb_device) - return -ENODEV; - - rc1 = 0; igot = 0; - rc0 = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), - (u8)0x01, - (u8)(USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE), - (u16)value, - (u16)index, - NULL, - (u16)0, - (int)500); - -#ifdef NOREADBACK -# -#else - rc1 = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), - (u8)0x00, - (u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), - (u16)0x00, - (u16)index, - (void *)&igot, - (u16)sizeof(u16), - (int)50000); - igot = 0xFF & igot; - switch (index) { - case 0x000: - case 0x500: - case 0x502: - case 0x503: - case 0x504: - case 0x506: - case 0x507: - break; - - case 0x204: - case 0x205: - case 0x350: - case 0x351: - if (0 != (0xFF & igot)) { - JOT(8, "unexpected 0x%02X for STK register 0x%03X\n", - igot, index); - } - break; - - default: - if ((0xFF & value) != (0xFF & igot)) { - JOT(8, "unexpected 0x%02X != 0x%02X " - "for STK register 0x%03X\n", - igot, value, index); - } - break; - } -#endif /* ! NOREADBACK*/ - - return (0 > rc0) ? rc0 : rc1; -} -/*****************************************************************************/ -int regget(struct usb_device *pusb_device, u16 index, void *pvoid) -{ - int rc; - - if (!pusb_device) - return -ENODEV; - - rc = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), - (u8)0x00, - (u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), - (u16)0x00, - (u16)index, - (void *)pvoid, - sizeof(u8), - (int)50000); - - return 0xFF & rc; -} /*****************************************************************************/ int wakeup_device(struct usb_device *pusb_device) -- cgit v1.2.3 From 32851b325e32bf9de72500d77488ffd9f7120395 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Feb 2011 01:12:50 +0200 Subject: staging/easycap: use regget for register back reading Use regget to reading back what was written to a register. This required changning size argument to regget signature On the way remove usless variable casting Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_low.c | 37 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index 39e22d51910b..b44c3841ee86 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -43,7 +43,7 @@ #define GET(X, Y, Z) do { \ int __rc; \ *(Z) = (u16)0; \ - __rc = regget(X, Y, Z); \ + __rc = regget(X, Y, Z, sizeof(u8)); \ if (0 > __rc) { \ JOT(8, ":-(%i\n", __LINE__); return __rc; \ } \ @@ -256,7 +256,8 @@ static const struct saa7113config saa7113configNTSC[256] = { {0xFF, 0xFF} }; -static int regget(struct usb_device *pusb_device, u16 index, void *pvoid) +static int regget(struct usb_device *pusb_device, + u16 index, void *reg, int reg_size) { int rc; @@ -264,46 +265,32 @@ static int regget(struct usb_device *pusb_device, u16 index, void *pvoid) return -ENODEV; rc = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), - (u8)0x00, - (u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), - (u16)0x00, - (u16)index, - (void *)pvoid, - sizeof(u8), - (int)50000); + 0x00, + (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), + 0x00, + index, reg, reg_size, 50000); return 0xFF & rc; } static int regset(struct usb_device *pusb_device, u16 index, u16 value) { - u16 igot; int rc0, rc1; + u16 igot; if (!pusb_device) return -ENODEV; rc1 = 0; igot = 0; rc0 = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), - (u8)0x01, - (u8)(USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE), - (u16)value, - (u16)index, - NULL, - (u16)0, - (int)500); + 0x01, + (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE), + value, index, NULL, 0, 500); #ifdef NOREADBACK # #else - rc1 = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), - (u8)0x00, - (u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), - (u16)0x00, - (u16)index, - (void *)&igot, - (u16)sizeof(u16), - (int)50000); + rc1 = regget(pusb_device, index, &igot, sizeof(igot)); igot = 0xFF & igot; switch (index) { case 0x000: -- cgit v1.2.3 From 2ef0c05e80cf59315f6f0a4e5a950899f169f2d0 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 9 Feb 2011 01:12:51 +0200 Subject: staging/easycap: replace NOREADBACK with moduel parameter NOREADBACK doesn't justify Kconfig option so we use module paramter for it. Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 1 + drivers/staging/easycap/easycap_low.c | 67 +++++++++++++++++----------------- drivers/staging/easycap/easycap_main.c | 4 ++ 3 files changed, 38 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 0ee60af6ccd9..55b1a14fa518 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -657,6 +657,7 @@ extern int easycap_debug; */ /*---------------------------------------------------------------------------*/ +extern bool easycap_readback; extern const struct easycap_standard easycap_standard[]; extern struct easycap_format easycap_format[]; extern struct v4l2_queryctrl easycap_control[]; diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index b44c3841ee86..a345a1bc69d0 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -275,54 +275,53 @@ static int regget(struct usb_device *pusb_device, static int regset(struct usb_device *pusb_device, u16 index, u16 value) { - int rc0, rc1; - u16 igot; + int rc; if (!pusb_device) return -ENODEV; - rc1 = 0; igot = 0; - rc0 = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), + rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), 0x01, (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE), value, index, NULL, 0, 500); -#ifdef NOREADBACK -# -#else - rc1 = regget(pusb_device, index, &igot, sizeof(igot)); - igot = 0xFF & igot; - switch (index) { - case 0x000: - case 0x500: - case 0x502: - case 0x503: - case 0x504: - case 0x506: - case 0x507: - break; + if (rc < 0) + return rc; + + if (easycap_readback) { + u16 igot = 0; + rc = regget(pusb_device, index, &igot, sizeof(igot)); + igot = 0xFF & igot; + switch (index) { + case 0x000: + case 0x500: + case 0x502: + case 0x503: + case 0x504: + case 0x506: + case 0x507: + break; - case 0x204: - case 0x205: - case 0x350: - case 0x351: - if (0 != (0xFF & igot)) { - JOT(8, "unexpected 0x%02X for STK register 0x%03X\n", - igot, index); - } - break; + case 0x204: + case 0x205: + case 0x350: + case 0x351: + if (igot) + JOT(8, "unexpected 0x%02X " + "for STK register 0x%03X\n", + igot, index); + break; - default: - if ((0xFF & value) != (0xFF & igot)) { - JOT(8, "unexpected 0x%02X != 0x%02X " - "for STK register 0x%03X\n", + default: + if ((0xFF & value) != igot) + JOT(8, "unexpected 0x%02X != 0x%02X " + "for STK register 0x%03X\n", igot, value, index); + break; } - break; } -#endif /* ! NOREADBACK*/ - return (0 > rc0) ? rc0 : rc1; + return rc; } /*****************************************************************************/ diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 997e75574f5f..340d4cff7f8e 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -42,6 +42,10 @@ module_param_named(debug, easycap_debug, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Debug level: 0(default),1,2,...,9"); #endif /* CONFIG_EASYCAP_DEBUG */ +bool easycap_readback; +module_param_named(readback, easycap_readback, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(readback, "read back written registers: (default false)"); + static int easycap_bars = 1; module_param_named(bars, easycap_bars, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(bars, -- cgit v1.2.3 From fe2d5b43807ebb38e0e8c7b269ff08fcd4011726 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Sun, 6 Feb 2011 14:38:16 -0800 Subject: staging: olpc_dcon: revert strtoul change On Fri, 4 Feb 2011 15:44:43 -0800 From: Andres Salomon The s/simple_strtoul/strict_strtoul/ from commit e107e6eb added a build warning, as well as an oops. This reverts that change. Signed-off-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index b19cd349f933..d6ad5d7a1457 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -525,7 +525,7 @@ static int _strtoul(const char *buf, int len, unsigned int *val) { char *endp; - unsigned int output = strict_strtoul(buf, &endp, 0); + unsigned int output = simple_strtoul(buf, &endp, 0); int size = endp - buf; if (*endp && isspace(*endp)) -- cgit v1.2.3 From 8d2d3dd1b4589299ec17b15130fbadfc69996df4 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Sun, 6 Feb 2011 15:28:30 -0800 Subject: staging: olpc_dcon: get rid of global i2c_client, create a dcon_priv struct Rather than using the global i2c_client variable, create a dcon_priv struct, store in the drvdata portion of the dev, and pass that around. In order to access dcon struct from various callbacks, include the reboot notifier and source switching work struct in the dcon struct. Signed-off-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon.c | 163 +++++++++++++++++++++------------- 1 file changed, 99 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index d6ad5d7a1457..f43c4ec95f91 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -53,10 +53,16 @@ struct dcon_platform_data { static struct dcon_platform_data *pdata; +struct dcon_priv { + struct i2c_client *client; + + struct work_struct switch_source; + struct notifier_block reboot_nb; +}; + /* I2C structures */ static struct i2c_driver dcon_driver; -static struct i2c_client *dcon_client; /* Platform devices */ static struct platform_device *dcon_device; @@ -93,16 +99,24 @@ static DECLARE_WAIT_QUEUE_HEAD(dcon_wait_queue); static unsigned short normal_i2c[] = { 0x0d, I2C_CLIENT_END }; -#define dcon_write(reg, val) i2c_smbus_write_word_data(dcon_client, reg, val) -#define dcon_read(reg) i2c_smbus_read_word_data(dcon_client, reg) +static s32 dcon_write(struct dcon_priv *dcon, u8 reg, u16 val) +{ + return i2c_smbus_write_word_data(dcon->client, reg, val); +} + +static s32 dcon_read(struct dcon_priv *dcon, u8 reg) +{ + return i2c_smbus_read_word_data(dcon->client, reg); +} /* The current backlight value - this saves us some smbus traffic */ static int bl_val = -1; /* ===== API functions - these are called by a variety of users ==== */ -static int dcon_hw_init(struct i2c_client *client, int is_init) +static int dcon_hw_init(struct dcon_priv *dcon, int is_init) { + struct i2c_client *client = dcon->client; uint16_t ver; int rc = 0; @@ -173,7 +187,7 @@ err: * smbus. For newer models, we simply BUG(); we want to know if this * still happens despite the power fixes that have been made! */ -static int dcon_bus_stabilize(struct i2c_client *client, int is_powered_down) +static int dcon_bus_stabilize(struct dcon_priv *dcon, int is_powered_down) { unsigned long timeout; int x; @@ -194,7 +208,7 @@ power_up: for (x = -1, timeout = 50; timeout && x < 0; timeout--) { msleep(1); - x = dcon_read(DCON_REG_ID); + x = dcon_read(dcon, DCON_REG_ID); } if (x < 0) { printk(KERN_ERR "olpc-dcon: unable to stabilize dcon's " @@ -208,51 +222,51 @@ power_up: } if (is_powered_down) - return dcon_hw_init(client, 0); + return dcon_hw_init(dcon, 0); return 0; } -static int dcon_get_backlight(void) +static int dcon_get_backlight(struct dcon_priv *dcon) { - if (dcon_client == NULL) + if (!dcon || !dcon->client) return 0; if (bl_val == -1) - bl_val = dcon_read(DCON_REG_BRIGHT) & 0x0F; + bl_val = dcon_read(dcon, DCON_REG_BRIGHT) & 0x0F; return bl_val; } -static void dcon_set_backlight_hw(int level) +static void dcon_set_backlight_hw(struct dcon_priv *dcon, int level) { bl_val = level & 0x0F; - dcon_write(DCON_REG_BRIGHT, bl_val); + dcon_write(dcon, DCON_REG_BRIGHT, bl_val); /* Purposely turn off the backlight when we go to level 0 */ if (bl_val == 0) { dcon_disp_mode &= ~MODE_BL_ENABLE; - dcon_write(DCON_REG_MODE, dcon_disp_mode); + dcon_write(dcon, DCON_REG_MODE, dcon_disp_mode); } else if (!(dcon_disp_mode & MODE_BL_ENABLE)) { dcon_disp_mode |= MODE_BL_ENABLE; - dcon_write(DCON_REG_MODE, dcon_disp_mode); + dcon_write(dcon, DCON_REG_MODE, dcon_disp_mode); } } -static void dcon_set_backlight(int level) +static void dcon_set_backlight(struct dcon_priv *dcon, int level) { - if (dcon_client == NULL) + if (!dcon || !dcon->client) return; if (bl_val == (level & 0x0F)) return; - dcon_set_backlight_hw(level); + dcon_set_backlight_hw(dcon, level); } /* Set the output type to either color or mono */ -static int dcon_set_output(int arg) +static int dcon_set_output(struct dcon_priv *dcon, int arg) { if (dcon_output == arg) return 0; @@ -269,7 +283,7 @@ static int dcon_set_output(int arg) dcon_disp_mode |= MODE_COL_AA; } - dcon_write(DCON_REG_MODE, dcon_disp_mode); + dcon_write(dcon, DCON_REG_MODE, dcon_disp_mode); return 0; } @@ -277,7 +291,7 @@ static int dcon_set_output(int arg) * DCONLOAD works in a sleep and account for it accordingly */ -static void dcon_sleep(int state) +static void dcon_sleep(struct dcon_priv *dcon, int state) { int x; @@ -301,7 +315,7 @@ static void dcon_sleep(int state) /* Only re-enable the backlight if the backlight value is set */ if (bl_val != 0) dcon_disp_mode |= MODE_BL_ENABLE; - x = dcon_bus_stabilize(dcon_client, 1); + x = dcon_bus_stabilize(dcon, 1); if (x) printk(KERN_WARNING "olpc-dcon: unable to reinit dcon" " hardware: %d!\n", x); @@ -309,7 +323,7 @@ static void dcon_sleep(int state) dcon_sleep_val = state; /* Restore backlight */ - dcon_set_backlight_hw(bl_val); + dcon_set_backlight_hw(dcon, bl_val); } /* We should turn off some stuff in the framebuffer - but what? */ @@ -337,6 +351,8 @@ void dcon_load_holdoff(void) static void dcon_source_switch(struct work_struct *work) { + struct dcon_priv *dcon = container_of(work, struct dcon_priv, + switch_source); DECLARE_WAITQUEUE(wait, current); int source = dcon_pending; @@ -351,7 +367,8 @@ static void dcon_source_switch(struct work_struct *work) case DCON_SOURCE_CPU: printk("dcon_source_switch to CPU\n"); /* Enable the scanline interrupt bit */ - if (dcon_write(DCON_REG_MODE, dcon_disp_mode | MODE_SCAN_INT)) + if (dcon_write(dcon, DCON_REG_MODE, + dcon_disp_mode | MODE_SCAN_INT)) printk(KERN_ERR "olpc-dcon: couldn't enable scanline interrupt!\n"); else { @@ -364,7 +381,7 @@ static void dcon_source_switch(struct work_struct *work) printk(KERN_ERR "olpc-dcon: Timeout entering CPU mode; expect a screen glitch.\n"); /* Turn off the scanline interrupt */ - if (dcon_write(DCON_REG_MODE, dcon_disp_mode)) + if (dcon_write(dcon, DCON_REG_MODE, dcon_disp_mode)) printk(KERN_ERR "olpc-dcon: couldn't disable scanline interrupt!\n"); /* @@ -454,40 +471,39 @@ static void dcon_source_switch(struct work_struct *work) dcon_source = source; } -static DECLARE_WORK(dcon_work, dcon_source_switch); - -static void dcon_set_source(int arg) +static void dcon_set_source(struct dcon_priv *dcon, int arg) { if (dcon_pending == arg) return; dcon_pending = arg; - if ((dcon_source != arg) && !work_pending(&dcon_work)) - schedule_work(&dcon_work); + if ((dcon_source != arg) && !work_pending(&dcon->switch_source)) + schedule_work(&dcon->switch_source); } -static void dcon_set_source_sync(int arg) +static void dcon_set_source_sync(struct dcon_priv *dcon, int arg) { - dcon_set_source(arg); + dcon_set_source(dcon, arg); flush_scheduled_work(); } static int dconbl_set(struct backlight_device *dev) { - + struct dcon_priv *dcon = bl_get_data(dev); int level = dev->props.brightness; if (dev->props.power != FB_BLANK_UNBLANK) level = 0; - dcon_set_backlight(level); + dcon_set_backlight(dcon, level); return 0; } static int dconbl_get(struct backlight_device *dev) { - return dcon_get_backlight(); + struct dcon_priv *dcon = bl_get_data(dev); + return dcon_get_backlight(dcon); } static ssize_t dcon_mode_show(struct device *dev, @@ -548,7 +564,7 @@ static ssize_t dcon_output_store(struct device *dev, return -EINVAL; if (output == DCON_OUTPUT_COLOR || output == DCON_OUTPUT_MONO) { - dcon_set_output(output); + dcon_set_output(dev_get_drvdata(dev), output); rc = count; } @@ -558,6 +574,7 @@ static ssize_t dcon_output_store(struct device *dev, static ssize_t dcon_freeze_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { + struct dcon_priv *dcon = dev_get_drvdata(dev); int output; if (_strtoul(buf, count, &output)) @@ -567,13 +584,13 @@ static ssize_t dcon_freeze_store(struct device *dev, switch (output) { case 0: - dcon_set_source(DCON_SOURCE_CPU); + dcon_set_source(dcon, DCON_SOURCE_CPU); break; case 1: - dcon_set_source_sync(DCON_SOURCE_DCON); + dcon_set_source_sync(dcon, DCON_SOURCE_DCON); break; case 2: /* normally unused */ - dcon_set_source(DCON_SOURCE_DCON); + dcon_set_source(dcon, DCON_SOURCE_DCON); break; default: return -EINVAL; @@ -592,7 +609,7 @@ static ssize_t dcon_resumeline_store(struct device *dev, return rc; resumeline = rl; - dcon_write(DCON_REG_SCAN_INT, resumeline); + dcon_write(dev_get_drvdata(dev), DCON_REG_SCAN_INT, resumeline); rc = count; return rc; @@ -606,7 +623,7 @@ static ssize_t dcon_sleep_store(struct device *dev, if (_strtoul(buf, count, &output)) return -EINVAL; - dcon_sleep(output ? DCON_SLEEP : DCON_ACTIVE); + dcon_sleep(dev_get_drvdata(dev), output ? DCON_SLEEP : DCON_ACTIVE); return count; } @@ -627,20 +644,17 @@ static const struct backlight_ops dcon_bl_ops = { static int dcon_reboot_notify(struct notifier_block *nb, unsigned long foo, void *bar) { - if (dcon_client == NULL) + struct dcon_priv *dcon = container_of(nb, struct dcon_priv, reboot_nb); + + if (!dcon || !dcon->client) return 0; /* Turn off the DCON. Entirely. */ - dcon_write(DCON_REG_MODE, 0x39); - dcon_write(DCON_REG_MODE, 0x32); + dcon_write(dcon, DCON_REG_MODE, 0x39); + dcon_write(dcon, DCON_REG_MODE, 0x32); return 0; } -static struct notifier_block dcon_nb = { - .notifier_call = dcon_reboot_notify, - .priority = -1, -}; - static int unfreeze_on_panic(struct notifier_block *nb, unsigned long e, void *p) { @@ -660,11 +674,14 @@ static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) { struct fb_event *evdata = data; + struct backlight_device *bl = container_of(self, + struct backlight_device, fb_notif); + struct dcon_priv *dcon = bl_get_data(bl); int *blank = (int *) evdata->data; if (((event != FB_EVENT_BLANK) && (event != FB_EVENT_CONBLANK)) || ignore_fb_events) return 0; - dcon_sleep((*blank) ? DCON_SLEEP : DCON_ACTIVE); + dcon_sleep(dcon, (*blank) ? DCON_SLEEP : DCON_ACTIVE); return 0; } @@ -681,12 +698,24 @@ static int dcon_detect(struct i2c_client *client, struct i2c_board_info *info) static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) { + struct dcon_priv *dcon; int rc, i, j; + dcon = kzalloc(sizeof(*dcon), GFP_KERNEL); + if (!dcon) + return -ENOMEM; + + dcon->client = client; + INIT_WORK(&dcon->switch_source, dcon_source_switch); + dcon->reboot_nb.notifier_call = dcon_reboot_notify; + dcon->reboot_nb.priority = -1; + + i2c_set_clientdata(client, dcon); + if (num_registered_fb >= 1) fbinfo = registered_fb[0]; - rc = dcon_hw_init(client, 1); + rc = dcon_hw_init(dcon, 1); if (rc) goto einit; @@ -699,9 +728,8 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) rc = -ENOMEM; goto eirq; } - /* Place holder...*/ - i2c_set_clientdata(client, dcon_device); rc = platform_device_add(dcon_device); + platform_set_drvdata(dcon_device, dcon); if (rc) { printk(KERN_ERR "dcon: Unable to add the DCON device\n"); @@ -718,11 +746,8 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) } /* Add the backlight device for the DCON */ - - dcon_client = client; - dcon_bl_dev = backlight_device_register("dcon-bl", &dcon_device->dev, - NULL, &dcon_bl_ops, NULL); + dcon, &dcon_bl_ops, NULL); if (IS_ERR(dcon_bl_dev)) { printk(KERN_ERR "Cannot register the backlight device (%ld)\n", @@ -731,12 +756,12 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) } else { dcon_bl_dev->props.max_brightness = 15; dcon_bl_dev->props.power = FB_BLANK_UNBLANK; - dcon_bl_dev->props.brightness = dcon_get_backlight(); + dcon_bl_dev->props.brightness = dcon_get_backlight(dcon); backlight_update_status(dcon_bl_dev); } - register_reboot_notifier(&dcon_nb); + register_reboot_notifier(&dcon->reboot_nb); atomic_notifier_chain_register(&panic_notifier_list, &dcon_panic_nb); fb_register_client(&fb_nb); @@ -751,15 +776,19 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) eirq: free_irq(DCON_IRQ, &dcon_driver); einit: + i2c_set_clientdata(client, NULL); + kfree(dcon); return rc; } static int dcon_remove(struct i2c_client *client) { - dcon_client = NULL; + struct dcon_priv *dcon = i2c_get_clientdata(client); + + i2c_set_clientdata(client, NULL); fb_unregister_client(&fb_nb); - unregister_reboot_notifier(&dcon_nb); + unregister_reboot_notifier(&dcon->reboot_nb); atomic_notifier_chain_unregister(&panic_notifier_list, &dcon_panic_nb); free_irq(DCON_IRQ, &dcon_driver); @@ -769,7 +798,9 @@ static int dcon_remove(struct i2c_client *client) if (dcon_device != NULL) platform_device_unregister(dcon_device); - cancel_work_sync(&dcon_work); + cancel_work_sync(&dcon->switch_source); + + kfree(dcon); return 0; } @@ -777,9 +808,11 @@ static int dcon_remove(struct i2c_client *client) #ifdef CONFIG_PM static int dcon_suspend(struct i2c_client *client, pm_message_t state) { + struct dcon_priv *dcon = i2c_get_clientdata(client); + if (dcon_sleep_val == DCON_ACTIVE) { /* Set up the DCON to have the source */ - dcon_set_source_sync(DCON_SOURCE_DCON); + dcon_set_source_sync(dcon, DCON_SOURCE_DCON); } return 0; @@ -787,9 +820,11 @@ static int dcon_suspend(struct i2c_client *client, pm_message_t state) static int dcon_resume(struct i2c_client *client) { + struct dcon_priv *dcon = i2c_get_clientdata(client); + if (dcon_sleep_val == DCON_ACTIVE) { - dcon_bus_stabilize(client, 0); - dcon_set_source(DCON_SOURCE_CPU); + dcon_bus_stabilize(dcon, 0); + dcon_set_source(dcon, DCON_SOURCE_CPU); } return 0; -- cgit v1.2.3 From bb4103544e455e11d9a4379326406a60429b9888 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Sun, 6 Feb 2011 15:28:39 -0800 Subject: staging: olpc_dcon: change sysfs 'output' toggle to be clearer... ..and store it in dcon_priv. This renames it to 'monochrome', which I think is much clearer. Previously, "echo 1 > output" toggled mono mode, while "echo 0 > output" enabled color. "Echo 1 > monochrome" makes more sense to me. Signed-off-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon.c | 34 ++++++++++++++++------------------ drivers/staging/olpc_dcon/olpc_dcon.h | 4 ---- 2 files changed, 16 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index f43c4ec95f91..a81e325f1102 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -58,6 +58,9 @@ struct dcon_priv { struct work_struct switch_source; struct notifier_block reboot_nb; + + /* Current output type; true == mono, false == color */ + bool mono:1; }; /* I2C structures */ @@ -81,9 +84,6 @@ static int dcon_source; /* Desired source */ static int dcon_pending; -/* Current output type */ -static int dcon_output = DCON_OUTPUT_COLOR; - /* Current sleep status (not yet implemented) */ static int dcon_sleep_val = DCON_ACTIVE; @@ -265,15 +265,14 @@ static void dcon_set_backlight(struct dcon_priv *dcon, int level) } /* Set the output type to either color or mono */ - -static int dcon_set_output(struct dcon_priv *dcon, int arg) +static int dcon_set_mono_mode(struct dcon_priv *dcon, bool enable_mono) { - if (dcon_output == arg) + if (dcon->mono == enable_mono) return 0; - dcon_output = arg; + dcon->mono = enable_mono; - if (arg == DCON_OUTPUT_MONO) { + if (enable_mono) { dcon_disp_mode &= ~(MODE_CSWIZZLE | MODE_COL_AA); dcon_disp_mode |= MODE_MONO_LUMA; } else { @@ -525,10 +524,11 @@ static ssize_t dcon_freeze_show(struct device *dev, return sprintf(buf, "%d\n", dcon_source == DCON_SOURCE_DCON ? 1 : 0); } -static ssize_t dcon_output_show(struct device *dev, +static ssize_t dcon_mono_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "%d\n", dcon_output); + struct dcon_priv *dcon = dev_get_drvdata(dev); + return sprintf(buf, "%d\n", dcon->mono ? 1 : 0); } static ssize_t dcon_resumeline_show(struct device *dev, @@ -554,19 +554,17 @@ static int _strtoul(const char *buf, int len, unsigned int *val) return 0; } -static ssize_t dcon_output_store(struct device *dev, +static ssize_t dcon_mono_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - int output; + int enable_mono; int rc = -EINVAL; - if (_strtoul(buf, count, &output)) + if (_strtoul(buf, count, &enable_mono)) return -EINVAL; - if (output == DCON_OUTPUT_COLOR || output == DCON_OUTPUT_MONO) { - dcon_set_output(dev_get_drvdata(dev), output); - rc = count; - } + dcon_set_mono_mode(dev_get_drvdata(dev), enable_mono ? 1 : 0); + rc = count; return rc; } @@ -631,7 +629,7 @@ static struct device_attribute dcon_device_files[] = { __ATTR(mode, 0444, dcon_mode_show, NULL), __ATTR(sleep, 0644, dcon_sleep_show, dcon_sleep_store), __ATTR(freeze, 0644, dcon_freeze_show, dcon_freeze_store), - __ATTR(output, 0644, dcon_output_show, dcon_output_store), + __ATTR(monochrome, 0644, dcon_mono_show, dcon_mono_store), __ATTR(resumeline, 0644, dcon_resumeline_show, dcon_resumeline_store), }; diff --git a/drivers/staging/olpc_dcon/olpc_dcon.h b/drivers/staging/olpc_dcon/olpc_dcon.h index e566d213da2a..77dcbd1934fa 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.h +++ b/drivers/staging/olpc_dcon/olpc_dcon.h @@ -41,10 +41,6 @@ #define DCON_SOURCE_DCON 0 #define DCON_SOURCE_CPU 1 -/* Output values */ -#define DCON_OUTPUT_COLOR 0 -#define DCON_OUTPUT_MONO 1 - /* Sleep values */ #define DCON_ACTIVE 0 #define DCON_SLEEP 1 -- cgit v1.2.3 From bada46e5ab10b09b0f86e8b8ede009e759a16adf Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Sun, 6 Feb 2011 15:28:46 -0800 Subject: staging: olpc_dcon: move more variables into dcon_priv Global variables for display mode and the current sleep state can go into dcon_priv as well. Signed-off-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon.c | 69 ++++++++++++++++++----------------- drivers/staging/olpc_dcon/olpc_dcon.h | 4 -- 2 files changed, 35 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index a81e325f1102..5d85d779952d 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -59,8 +59,12 @@ struct dcon_priv { struct work_struct switch_source; struct notifier_block reboot_nb; + /* Shadow register for the DCON_REG_MODE register */ + u8 disp_mode; + /* Current output type; true == mono, false == color */ bool mono:1; + bool asleep:1; }; /* I2C structures */ @@ -84,12 +88,6 @@ static int dcon_source; /* Desired source */ static int dcon_pending; -/* Current sleep status (not yet implemented) */ -static int dcon_sleep_val = DCON_ACTIVE; - -/* Shadow register for the DCON_REG_MODE register */ -static unsigned short dcon_disp_mode; - /* Variables used during switches */ static int dcon_switched; static struct timespec dcon_irq_time; @@ -164,11 +162,12 @@ static int dcon_hw_init(struct dcon_priv *dcon, int is_init) /* Colour swizzle, AA, no passthrough, backlight */ if (is_init) { - dcon_disp_mode = MODE_PASSTHRU | MODE_BL_ENABLE | MODE_CSWIZZLE; + dcon->disp_mode = MODE_PASSTHRU | MODE_BL_ENABLE | + MODE_CSWIZZLE; if (useaa) - dcon_disp_mode |= MODE_COL_AA; + dcon->disp_mode |= MODE_COL_AA; } - i2c_smbus_write_word_data(client, DCON_REG_MODE, dcon_disp_mode); + i2c_smbus_write_word_data(client, DCON_REG_MODE, dcon->disp_mode); /* Set the scanline to interrupt on during resume */ @@ -245,11 +244,11 @@ static void dcon_set_backlight_hw(struct dcon_priv *dcon, int level) /* Purposely turn off the backlight when we go to level 0 */ if (bl_val == 0) { - dcon_disp_mode &= ~MODE_BL_ENABLE; - dcon_write(dcon, DCON_REG_MODE, dcon_disp_mode); - } else if (!(dcon_disp_mode & MODE_BL_ENABLE)) { - dcon_disp_mode |= MODE_BL_ENABLE; - dcon_write(dcon, DCON_REG_MODE, dcon_disp_mode); + dcon->disp_mode &= ~MODE_BL_ENABLE; + dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode); + } else if (!(dcon->disp_mode & MODE_BL_ENABLE)) { + dcon->disp_mode |= MODE_BL_ENABLE; + dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode); } } @@ -273,16 +272,16 @@ static int dcon_set_mono_mode(struct dcon_priv *dcon, bool enable_mono) dcon->mono = enable_mono; if (enable_mono) { - dcon_disp_mode &= ~(MODE_CSWIZZLE | MODE_COL_AA); - dcon_disp_mode |= MODE_MONO_LUMA; + dcon->disp_mode &= ~(MODE_CSWIZZLE | MODE_COL_AA); + dcon->disp_mode |= MODE_MONO_LUMA; } else { - dcon_disp_mode &= ~(MODE_MONO_LUMA); - dcon_disp_mode |= MODE_CSWIZZLE; + dcon->disp_mode &= ~(MODE_MONO_LUMA); + dcon->disp_mode |= MODE_CSWIZZLE; if (useaa) - dcon_disp_mode |= MODE_COL_AA; + dcon->disp_mode |= MODE_COL_AA; } - dcon_write(dcon, DCON_REG_MODE, dcon_disp_mode); + dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode); return 0; } @@ -290,36 +289,36 @@ static int dcon_set_mono_mode(struct dcon_priv *dcon, bool enable_mono) * DCONLOAD works in a sleep and account for it accordingly */ -static void dcon_sleep(struct dcon_priv *dcon, int state) +static void dcon_sleep(struct dcon_priv *dcon, bool sleep) { int x; /* Turn off the backlight and put the DCON to sleep */ - if (state == dcon_sleep_val) + if (dcon->asleep == sleep) return; if (!olpc_board_at_least(olpc_board(0xc2))) return; - if (state == DCON_SLEEP) { + if (sleep) { x = 0; x = olpc_ec_cmd(0x26, (unsigned char *) &x, 1, NULL, 0); if (x) printk(KERN_WARNING "olpc-dcon: unable to force dcon " "to power down: %d!\n", x); else - dcon_sleep_val = state; + dcon->asleep = sleep; } else { /* Only re-enable the backlight if the backlight value is set */ if (bl_val != 0) - dcon_disp_mode |= MODE_BL_ENABLE; + dcon->disp_mode |= MODE_BL_ENABLE; x = dcon_bus_stabilize(dcon, 1); if (x) printk(KERN_WARNING "olpc-dcon: unable to reinit dcon" " hardware: %d!\n", x); else - dcon_sleep_val = state; + dcon->asleep = sleep; /* Restore backlight */ dcon_set_backlight_hw(dcon, bl_val); @@ -367,7 +366,7 @@ static void dcon_source_switch(struct work_struct *work) printk("dcon_source_switch to CPU\n"); /* Enable the scanline interrupt bit */ if (dcon_write(dcon, DCON_REG_MODE, - dcon_disp_mode | MODE_SCAN_INT)) + dcon->disp_mode | MODE_SCAN_INT)) printk(KERN_ERR "olpc-dcon: couldn't enable scanline interrupt!\n"); else { @@ -380,7 +379,7 @@ static void dcon_source_switch(struct work_struct *work) printk(KERN_ERR "olpc-dcon: Timeout entering CPU mode; expect a screen glitch.\n"); /* Turn off the scanline interrupt */ - if (dcon_write(dcon, DCON_REG_MODE, dcon_disp_mode)) + if (dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode)) printk(KERN_ERR "olpc-dcon: couldn't disable scanline interrupt!\n"); /* @@ -508,14 +507,16 @@ static int dconbl_get(struct backlight_device *dev) static ssize_t dcon_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "%4.4X\n", dcon_disp_mode); + struct dcon_priv *dcon = dev_get_drvdata(dev); + return sprintf(buf, "%4.4X\n", dcon->disp_mode); } static ssize_t dcon_sleep_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "%d\n", dcon_sleep_val); + struct dcon_priv *dcon = dev_get_drvdata(dev); + return sprintf(buf, "%d\n", dcon->asleep ? 1 : 0); } static ssize_t dcon_freeze_show(struct device *dev, @@ -621,7 +622,7 @@ static ssize_t dcon_sleep_store(struct device *dev, if (_strtoul(buf, count, &output)) return -EINVAL; - dcon_sleep(dev_get_drvdata(dev), output ? DCON_SLEEP : DCON_ACTIVE); + dcon_sleep(dev_get_drvdata(dev), output ? true : false); return count; } @@ -679,7 +680,7 @@ static int fb_notifier_callback(struct notifier_block *self, if (((event != FB_EVENT_BLANK) && (event != FB_EVENT_CONBLANK)) || ignore_fb_events) return 0; - dcon_sleep(dcon, (*blank) ? DCON_SLEEP : DCON_ACTIVE); + dcon_sleep(dcon, *blank ? true : false); return 0; } @@ -808,7 +809,7 @@ static int dcon_suspend(struct i2c_client *client, pm_message_t state) { struct dcon_priv *dcon = i2c_get_clientdata(client); - if (dcon_sleep_val == DCON_ACTIVE) { + if (!dcon->asleep) { /* Set up the DCON to have the source */ dcon_set_source_sync(dcon, DCON_SOURCE_DCON); } @@ -820,7 +821,7 @@ static int dcon_resume(struct i2c_client *client) { struct dcon_priv *dcon = i2c_get_clientdata(client); - if (dcon_sleep_val == DCON_ACTIVE) { + if (!dcon->asleep) { dcon_bus_stabilize(dcon, 0); dcon_set_source(dcon, DCON_SOURCE_CPU); } diff --git a/drivers/staging/olpc_dcon/olpc_dcon.h b/drivers/staging/olpc_dcon/olpc_dcon.h index 77dcbd1934fa..cef2473bccf3 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.h +++ b/drivers/staging/olpc_dcon/olpc_dcon.h @@ -41,10 +41,6 @@ #define DCON_SOURCE_DCON 0 #define DCON_SOURCE_CPU 1 -/* Sleep values */ -#define DCON_ACTIVE 0 -#define DCON_SLEEP 1 - /* Interrupt */ #define DCON_IRQ 6 -- cgit v1.2.3 From 56463de05a56b80b43d21a442cf2a6e0037762e8 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Sun, 6 Feb 2011 15:28:53 -0800 Subject: staging: olpc_dcon: actually return the value of i2c_add_driver It's nice to actually check for errors. :) Signed-off-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 5d85d779952d..eec10e78faba 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -872,7 +872,7 @@ static irqreturn_t dcon_interrupt(int irq, void *id) return IRQ_HANDLED; } -static struct i2c_device_id dcon_idtable[] = { +static const struct i2c_device_id dcon_idtable[] = { { "olpc_dcon", 0 }, { } }; @@ -901,8 +901,7 @@ static int __init olpc_dcon_init(void) { pdata = &dcon_pdata_xo_1; - i2c_add_driver(&dcon_driver); - return 0; + return i2c_add_driver(&dcon_driver); } static void __exit olpc_dcon_exit(void) -- cgit v1.2.3 From 3c4a94132b78f3143ef8f63f8450d2385dafb429 Mon Sep 17 00:00:00 2001 From: Timo von Holtz Date: Tue, 8 Feb 2011 15:52:21 +0100 Subject: Staging: hv: replaced __attribute((packed)) with __packed Replaced __attribute((packed)) with __packed as it's preferred Signed-off-by: Timo von Holtz Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel.h | 4 ++-- drivers/staging/hv/channel_mgmt.h | 36 ++++++++++++++-------------- drivers/staging/hv/netvsc.h | 26 ++++++++++---------- drivers/staging/hv/ring_buffer.h | 2 +- drivers/staging/hv/utils.h | 14 +++++------ drivers/staging/hv/vmbus_channel_interface.h | 2 +- drivers/staging/hv/vmbus_packet_format.h | 20 ++++++++-------- drivers/staging/hv/vstorage.h | 6 ++--- 8 files changed, 55 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/channel.h b/drivers/staging/hv/channel.h index 7997056734d7..de4f867de171 100644 --- a/drivers/staging/hv/channel.h +++ b/drivers/staging/hv/channel.h @@ -37,7 +37,7 @@ struct vmbus_channel_packet_page_buffer { u32 reserved; u32 rangecount; struct hv_page_buffer range[MAX_PAGE_BUFFER_COUNT]; -} __attribute__((packed)); +} __packed; /* The format must be the same as struct vmdata_gpa_direct */ struct vmbus_channel_packet_multipage_buffer { @@ -49,7 +49,7 @@ struct vmbus_channel_packet_multipage_buffer { u32 reserved; u32 rangecount; /* Always 1 in this case */ struct hv_multipage_buffer range; -} __attribute__((packed)); +} __packed; extern int vmbus_open(struct vmbus_channel *channel, diff --git a/drivers/staging/hv/channel_mgmt.h b/drivers/staging/hv/channel_mgmt.h index de6b2a0ebf70..fe40bf2706d2 100644 --- a/drivers/staging/hv/channel_mgmt.h +++ b/drivers/staging/hv/channel_mgmt.h @@ -60,19 +60,19 @@ enum vmbus_channel_message_type { struct vmbus_channel_message_header { enum vmbus_channel_message_type msgtype; u32 padding; -} __attribute__((packed)); +} __packed; /* Query VMBus Version parameters */ struct vmbus_channel_query_vmbus_version { struct vmbus_channel_message_header header; u32 version; -} __attribute__((packed)); +} __packed; /* VMBus Version Supported parameters */ struct vmbus_channel_version_supported { struct vmbus_channel_message_header header; bool version_supported; -} __attribute__((packed)); +} __packed; /* Offer Channel parameters */ struct vmbus_channel_offer_channel { @@ -81,13 +81,13 @@ struct vmbus_channel_offer_channel { u32 child_relid; u8 monitorid; bool monitor_allocated; -} __attribute__((packed)); +} __packed; /* Rescind Offer parameters */ struct vmbus_channel_rescind_offer { struct vmbus_channel_message_header header; u32 child_relid; -} __attribute__((packed)); +} __packed; /* * Request Offer -- no parameters, SynIC message contains the partition ID @@ -123,7 +123,7 @@ struct vmbus_channel_open_channel { /* User-specific data to be passed along to the server endpoint. */ unsigned char userdata[MAX_USER_DEFINED_BYTES]; -} __attribute__((packed)); +} __packed; /* Open Channel Result parameters */ struct vmbus_channel_open_result { @@ -131,13 +131,13 @@ struct vmbus_channel_open_result { u32 child_relid; u32 openid; u32 status; -} __attribute__((packed)); +} __packed; /* Close channel parameters; */ struct vmbus_channel_close_channel { struct vmbus_channel_message_header header; u32 child_relid; -} __attribute__((packed)); +} __packed; /* Channel Message GPADL */ #define GPADL_TYPE_RING_BUFFER 1 @@ -157,7 +157,7 @@ struct vmbus_channel_gpadl_header { u16 range_buflen; u16 rangecount; struct gpa_range range[0]; -} __attribute__((packed)); +} __packed; /* This is the followup packet that contains more PFNs. */ struct vmbus_channel_gpadl_body { @@ -165,25 +165,25 @@ struct vmbus_channel_gpadl_body { u32 msgnumber; u32 gpadl; u64 pfn[0]; -} __attribute__((packed)); +} __packed; struct vmbus_channel_gpadl_created { struct vmbus_channel_message_header header; u32 child_relid; u32 gpadl; u32 creation_status; -} __attribute__((packed)); +} __packed; struct vmbus_channel_gpadl_teardown { struct vmbus_channel_message_header header; u32 child_relid; u32 gpadl; -} __attribute__((packed)); +} __packed; struct vmbus_channel_gpadl_torndown { struct vmbus_channel_message_header header; u32 gpadl; -} __attribute__((packed)); +} __packed; #ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD struct vmbus_channel_view_range_add { @@ -191,19 +191,19 @@ struct vmbus_channel_view_range_add { PHYSICAL_ADDRESS viewrange_base; u64 viewrange_length; u32 child_relid; -} __attribute__((packed)); +} __packed; struct vmbus_channel_view_range_remove { struct vmbus_channel_message_header header; PHYSICAL_ADDRESS viewrange_base; u32 child_relid; -} __attribute__((packed)); +} __packed; #endif struct vmbus_channel_relid_released { struct vmbus_channel_message_header header; u32 child_relid; -} __attribute__((packed)); +} __packed; struct vmbus_channel_initiate_contact { struct vmbus_channel_message_header header; @@ -212,12 +212,12 @@ struct vmbus_channel_initiate_contact { u64 interrupt_page; u64 monitor_page1; u64 monitor_page2; -} __attribute__((packed)); +} __packed; struct vmbus_channel_version_response { struct vmbus_channel_message_header header; bool version_supported; -} __attribute__((packed)); +} __packed; enum vmbus_channel_state { CHANNEL_OFFER_STATE, diff --git a/drivers/staging/hv/netvsc.h b/drivers/staging/hv/netvsc.h index 932a77ccdc04..5f6dcf15fa29 100644 --- a/drivers/staging/hv/netvsc.h +++ b/drivers/staging/hv/netvsc.h @@ -92,7 +92,7 @@ struct nvsp_message_header { struct nvsp_message_init { u32 min_protocol_ver; u32 max_protocol_ver; -} __attribute__((packed)); +} __packed; /* * This message is used by the VSP to complete the initialization of the @@ -103,12 +103,12 @@ struct nvsp_message_init_complete { u32 negotiated_protocol_ver; u32 max_mdl_chain_len; u32 status; -} __attribute__((packed)); +} __packed; union nvsp_message_init_uber { struct nvsp_message_init init; struct nvsp_message_init_complete init_complete; -} __attribute__((packed)); +} __packed; /* Version 1 Messages */ @@ -119,7 +119,7 @@ union nvsp_message_init_uber { struct nvsp_1_message_send_ndis_version { u32 ndis_major_ver; u32 ndis_minor_ver; -} __attribute__((packed)); +} __packed; /* * This message is used by the VSC to send a receive buffer to the VSP. The VSP @@ -128,14 +128,14 @@ struct nvsp_1_message_send_ndis_version { struct nvsp_1_message_send_receive_buffer { u32 gpadl_handle; u16 id; -} __attribute__((packed)); +} __packed; struct nvsp_1_receive_buffer_section { u32 offset; u32 sub_alloc_size; u32 num_sub_allocs; u32 end_offset; -} __attribute__((packed)); +} __packed; /* * This message is used by the VSP to acknowledge a receive buffer send by the @@ -166,7 +166,7 @@ struct nvsp_1_message_send_receive_buffer_complete { */ struct nvsp_1_receive_buffer_section sections[1]; -} __attribute__((packed)); +} __packed; /* * This message is sent by the VSC to revoke the receive buffer. After the VSP @@ -184,7 +184,7 @@ struct nvsp_1_message_revoke_receive_buffer { struct nvsp_1_message_send_send_buffer { u32 gpadl_handle; u16 id; -} __attribute__((packed)); +} __packed; /* * This message is used by the VSP to acknowledge a send buffer sent by the @@ -201,7 +201,7 @@ struct nvsp_1_message_send_send_buffer_complete { * decreases. */ u32 section_size; -} __attribute__((packed)); +} __packed; /* * This message is sent by the VSC to revoke the send buffer. After the VSP @@ -231,7 +231,7 @@ struct nvsp_1_message_send_rndis_packet { */ u32 send_buf_section_index; u32 send_buf_section_size; -} __attribute__((packed)); +} __packed; /* * This message is used by both the VSP and the VSC to complete a RNDIS message @@ -257,18 +257,18 @@ union nvsp_1_message_uber { struct nvsp_1_message_send_rndis_packet send_rndis_pkt; struct nvsp_1_message_send_rndis_packet_complete send_rndis_pkt_complete; -} __attribute__((packed)); +} __packed; union nvsp_all_messages { union nvsp_message_init_uber init_msg; union nvsp_1_message_uber v1_msg; -} __attribute__((packed)); +} __packed; /* ALL Messages */ struct nvsp_message { struct nvsp_message_header hdr; union nvsp_all_messages msg; -} __attribute__((packed)); +} __packed; diff --git a/drivers/staging/hv/ring_buffer.h b/drivers/staging/hv/ring_buffer.h index 7bd6ecf2f015..7bf20d67187b 100644 --- a/drivers/staging/hv/ring_buffer.h +++ b/drivers/staging/hv/ring_buffer.h @@ -51,7 +51,7 @@ struct hv_ring_buffer { * !!! DO NOT place any fields below this !!! */ u8 buffer[0]; -} __attribute__((packed)); +} __packed; struct hv_ring_buffer_info { struct hv_ring_buffer *ring_buffer; diff --git a/drivers/staging/hv/utils.h b/drivers/staging/hv/utils.h index 6d27d15ab525..acebbbf888b0 100644 --- a/drivers/staging/hv/utils.h +++ b/drivers/staging/hv/utils.h @@ -43,12 +43,12 @@ struct vmbuspipe_hdr { u32 flags; u32 msgsize; -} __attribute__((packed)); +} __packed; struct ic_version { u16 major; u16 minor; -} __attribute__((packed)); +} __packed; struct icmsg_hdr { struct ic_version icverframe; @@ -59,26 +59,26 @@ struct icmsg_hdr { u8 ictransaction_id; u8 icflags; u8 reserved[2]; -} __attribute__((packed)); +} __packed; struct icmsg_negotiate { u16 icframe_vercnt; u16 icmsg_vercnt; u32 reserved; struct ic_version icversion_data[1]; /* any size array */ -} __attribute__((packed)); +} __packed; struct shutdown_msg_data { u32 reason_code; u32 timeout_seconds; u32 flags; u8 display_message[2048]; -} __attribute__((packed)); +} __packed; struct heartbeat_msg_data { u64 seq_num; u32 reserved[8]; -} __attribute__((packed)); +} __packed; /* Time Sync IC defs */ #define ICTIMESYNCFLAG_PROBE 0 @@ -96,7 +96,7 @@ struct ictimesync_data{ u64 childtime; u64 roundtriptime; u8 flags; -} __attribute__((packed)); +} __packed; /* Index for each IC struct in array hv_cb_utils[] */ #define HV_SHUTDOWN_MSG 0 diff --git a/drivers/staging/hv/vmbus_channel_interface.h b/drivers/staging/hv/vmbus_channel_interface.h index fbfad5e8b92d..20ae258e5f9c 100644 --- a/drivers/staging/hv/vmbus_channel_interface.h +++ b/drivers/staging/hv/vmbus_channel_interface.h @@ -75,7 +75,7 @@ struct vmbus_channel_offer { } pipe; } u; u32 padding; -} __attribute__((packed)); +} __packed; /* Server Flags */ #define VMBUS_CHANNEL_ENUMERATE_DEVICE_INTERFACE 1 diff --git a/drivers/staging/hv/vmbus_packet_format.h b/drivers/staging/hv/vmbus_packet_format.h index 5cb13e523c48..c0b2c2b11646 100644 --- a/drivers/staging/hv/vmbus_packet_format.h +++ b/drivers/staging/hv/vmbus_packet_format.h @@ -30,17 +30,17 @@ struct vmpacket_descriptor { u16 len8; u16 flags; u64 trans_id; -} __attribute__((packed)); +} __packed; struct vmpacket_header { u32 prev_pkt_start_offset; struct vmpacket_descriptor descriptor; -} __attribute__((packed)); +} __packed; struct vmtransfer_page_range { u32 byte_count; u32 byte_offset; -} __attribute__((packed)); +} __packed; struct vmtransfer_page_packet_header { struct vmpacket_descriptor d; @@ -49,20 +49,20 @@ struct vmtransfer_page_packet_header { u8 reserved; u32 range_cnt; struct vmtransfer_page_range ranges[1]; -} __attribute__((packed)); +} __packed; struct vmgpadl_packet_header { struct vmpacket_descriptor d; u32 gpadl; u32 reserved; -} __attribute__((packed)); +} __packed; struct vmadd_remove_transfer_page_set { struct vmpacket_descriptor d; u32 gpadl; u16 xfer_pageset_id; u16 reserved; -} __attribute__((packed)); +} __packed; /* * This structure defines a range in guest physical space that can be made to @@ -86,7 +86,7 @@ struct vmestablish_gpadl { u32 gpadl; u32 range_cnt; struct gpa_range range[1]; -} __attribute__((packed)); +} __packed; /* * This is the format for a Teardown Gpadl packet, which indicates that the @@ -96,7 +96,7 @@ struct vmteardown_gpadl { struct vmpacket_descriptor d; u32 gpadl; u32 reserved; /* for alignment to a 8-byte boundary */ -} __attribute__((packed)); +} __packed; /* * This is the format for a GPA-Direct packet, which contains a set of GPA @@ -107,7 +107,7 @@ struct vmdata_gpa_direct { u32 reserved; u32 range_cnt; struct gpa_range range[1]; -} __attribute__((packed)); +} __packed; /* This is the format for a Additional Data Packet. */ struct vmadditional_data { @@ -116,7 +116,7 @@ struct vmadditional_data { u32 offset; u32 byte_cnt; unsigned char data[1]; -} __attribute__((packed)); +} __packed; union vmpacket_largest_possible_header { struct vmpacket_descriptor simple_hdr; diff --git a/drivers/staging/hv/vstorage.h b/drivers/staging/hv/vstorage.h index ae8be84394d5..ebb4d671c424 100644 --- a/drivers/staging/hv/vstorage.h +++ b/drivers/staging/hv/vstorage.h @@ -135,7 +135,7 @@ struct vmstorage_channel_properties { /* This id is unique for each channel and will correspond with */ /* vendor specific data in the inquirydata */ unsigned long long unique_id; -} __attribute__((packed)); +} __packed; /* This structure is sent during the storage protocol negotiations. */ struct vmstorage_protocol_version { @@ -149,7 +149,7 @@ struct vmstorage_protocol_version { * builds. */ unsigned short revision; -} __attribute__((packed)); +} __packed; /* Channel Property Flags */ #define STORAGE_CHANNEL_REMOVABLE_FLAG 0x1 @@ -179,7 +179,7 @@ struct vstor_packet { /* Used during version negotiations. */ struct vmstorage_protocol_version version; }; -} __attribute__((packed)); +} __packed; /* Packet flags */ /* -- cgit v1.2.3 From 581de3b0a538aa18181602008aa222f51dcf1ec3 Mon Sep 17 00:00:00 2001 From: Timo von Holtz Date: Tue, 8 Feb 2011 15:55:49 +0100 Subject: Staging: hv: moved assignments out of if conditions Moved all assignments in if conditions to the preceeding line Signed-off-by: Timo von Holtz Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/netvsc_drv.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 95fa810255ed..6b8fd0c2b0da 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -126,7 +126,8 @@ static void netvsc_xmit_completion(void *context) dev_kfree_skb_any(skb); - if ((net_device_ctx->avail += num_pages) >= PACKET_PAGES_HIWATER) + net_device_ctx->avail += num_pages; + if (net_device_ctx->avail >= PACKET_PAGES_HIWATER) netif_wake_queue(net); } } @@ -207,7 +208,8 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) net->stats.tx_packets, net->stats.tx_bytes); - if ((net_device_ctx->avail -= num_pages) < PACKET_PAGES_LOWATER) + net_device_ctx->avail -= num_pages; + if (net_device_ctx->avail < PACKET_PAGES_LOWATER) netif_stop_queue(net); } else { /* we are shutting down or bus overloaded, just drop packet */ -- cgit v1.2.3 From 7e79f78b331632c1812ce9c07443550aa2b6c0fe Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 9 Feb 2011 12:40:12 +0300 Subject: Staging: rts_pstor: fix read past end of buffer We read one space past the end of the buffer because we add 1. Also I changed it to use ARRAY_SIZE() instead of manually calculating the size. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts_pstor/ms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rts_pstor/ms.c b/drivers/staging/rts_pstor/ms.c index dd5993168598..a624f40fd914 100644 --- a/drivers/staging/rts_pstor/ms.c +++ b/drivers/staging/rts_pstor/ms.c @@ -3361,7 +3361,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 log_blk = (u16)(start_sector >> ms_card->block_shift); start_page = (u8)(start_sector & ms_card->page_off); - for (seg_no = 0; seg_no < sizeof(ms_start_idx)/2; seg_no++) { + for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1; seg_no++) { if (log_blk < ms_start_idx[seg_no+1]) break; } -- cgit v1.2.3 From f94fdeaa58e54c41eb6a2d8b86585e858d44c88f Mon Sep 17 00:00:00 2001 From: Timo von Holtz Date: Tue, 8 Feb 2011 20:41:19 +0100 Subject: Staging: quickstart: fixed coding style issues Fixed the Following coding Style Issues: drivers/staging/quickstart/quickstart.c:8: ERROR: trailing whitespace drivers/staging/quickstart/quickstart.c:144: ERROR: spaces required around that '?' (ctx:VxV) drivers/staging/quickstart/quickstart.c:144: ERROR: spaces required around that ':' (ctx:VxV) Signed-off-by: Timo von Holtz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quickstart/quickstart.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index d83bec876d2e..c60911c6ab3f 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c @@ -5,7 +5,7 @@ * Copyright (C) 2007-2010 Angelo Arrifano * * Information gathered from disassebled dsdt and from here: - * + * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -141,7 +141,8 @@ static ssize_t pressed_button_show(struct device *dev, char *buf) { return snprintf(buf, PAGE_SIZE, "%s\n", - (quickstart_data.pressed?quickstart_data.pressed->name:"none")); + (quickstart_data.pressed ? + quickstart_data.pressed->name : "none")); } -- cgit v1.2.3 From 988a29bf3dfb2bb9a85c21987e2cc63dadf523c3 Mon Sep 17 00:00:00 2001 From: Ingmar Steen Date: Mon, 7 Feb 2011 14:32:31 +0100 Subject: staging: samsung-laptop: Extend samsung-laptop platform driver to support another flavor of its platform BIOS. There are currently two implementations of the Samsung BIOS that controls the rfkill switch, backlight brightness / power and performance level. The samsung-laptop driver implements the BIOS flavor with the SECLINUX signature, this patch implements talking to the other BIOS with 'SwSmi@' signature. Both expose very similar functionality and way of accessing the commands. The differences are mostly offsets, command identifiers and some values. This patch introduces a sabi_config structure that contains information on identifying and accessing specific SABI flavors. Signed-off-by: Ingmar Steen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 392 ++++++++++++++++-------- 1 file changed, 265 insertions(+), 127 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index 701e8d52a9fa..4b7525fa02b2 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -33,51 +33,6 @@ */ #define MAX_BRIGHT 0x07 -/* Brightness is 0 - 8, as described above. Value 0 is for the BIOS to use */ -#define GET_BRIGHTNESS 0x00 -#define SET_BRIGHTNESS 0x01 - -/* first byte: - * 0x00 - wireless is off - * 0x01 - wireless is on - * second byte: - * 0x02 - 3G is off - * 0x03 - 3G is on - * TODO, verify 3G is correct, that doesn't seem right... - */ -#define GET_WIRELESS_BUTTON 0x02 -#define SET_WIRELESS_BUTTON 0x03 - -/* 0 is off, 1 is on */ -#define GET_BACKLIGHT 0x04 -#define SET_BACKLIGHT 0x05 - -/* - * 0x80 or 0x00 - no action - * 0x81 - recovery key pressed - */ -#define GET_RECOVERY_METHOD 0x06 -#define SET_RECOVERY_METHOD 0x07 - -/* 0 is low, 1 is high */ -#define GET_PERFORMANCE_LEVEL 0x08 -#define SET_PERFORMANCE_LEVEL 0x09 - -/* - * Tell the BIOS that Linux is running on this machine. - * 81 is on, 80 is off - */ -#define SET_LINUX 0x0a - - -#define MAIN_FUNCTION 0x4c49 - -#define SABI_HEADER_PORT 0x00 -#define SABI_HEADER_RE_MEM 0x02 -#define SABI_HEADER_IFACEFUNC 0x03 -#define SABI_HEADER_EN_MEM 0x04 -#define SABI_HEADER_DATA_OFFSET 0x05 -#define SABI_HEADER_DATA_SEGMENT 0x07 #define SABI_IFACE_MAIN 0x00 #define SABI_IFACE_SUB 0x02 @@ -89,6 +44,169 @@ struct sabi_retval { u8 retval[20]; }; +struct sabi_header_offsets { + u8 port; + u8 re_mem; + u8 iface_func; + u8 en_mem; + u8 data_offset; + u8 data_segment; +}; + +struct sabi_commands { + /* Brightness is 0 - 8, as described above. Value 0 is for the BIOS to use */ + u8 get_brightness; + u8 set_brightness; + + /* first byte: + * 0x00 - wireless is off + * 0x01 - wireless is on + * second byte: + * 0x02 - 3G is off + * 0x03 - 3G is on + * TODO, verify 3G is correct, that doesn't seem right... + */ + u8 get_wireless_button; + u8 set_wireless_button; + + /* 0 is off, 1 is on */ + u8 get_backlight; + u8 set_backlight; + + /* + * 0x80 or 0x00 - no action + * 0x81 - recovery key pressed + */ + u8 get_recovery_mode; + u8 set_recovery_mode; + + /* + * on seclinux: 0 is low, 1 is high, + * on swsmi: 0 is normal, 1 is silent, 2 is turbo + */ + u8 get_performance_level; + u8 set_performance_level; + + /* + * Tell the BIOS that Linux is running on this machine. + * 81 is on, 80 is off + */ + u8 set_linux; +}; + +struct sabi_performance_level { + const char *name; + u8 value; +}; + +struct sabi_config { + const char *test_string; + u16 main_function; + struct sabi_header_offsets header_offsets; + struct sabi_commands commands; + struct sabi_performance_level performance_levels[4]; +}; + +static struct sabi_config sabi_configs[] = { + { + test_string: "SECLINUX", + + main_function: 0x4c59, + + header_offsets: { + port: 0x00, + re_mem: 0x02, + iface_func: 0x03, + en_mem: 0x04, + data_offset: 0x05, + data_segment: 0x07, + }, + + commands: { + get_brightness: 0x00, + set_brightness: 0x01, + + get_wireless_button: 0x02, + set_wireless_button: 0x03, + + get_backlight: 0x04, + set_backlight: 0x05, + + get_recovery_mode: 0x06, + set_recovery_mode: 0x07, + + get_performance_level: 0x08, + set_performance_level: 0x09, + + set_linux: 0x0a, + }, + + performance_levels: { + { + name: "silent", + value: 0, + }, + { + name: "normal", + value: 1, + }, + { }, + }, + }, + { + test_string: "SwSmi@", + + main_function: 0x5843, + + header_offsets: { + port: 0x00, + re_mem: 0x04, + iface_func: 0x02, + en_mem: 0x03, + data_offset: 0x05, + data_segment: 0x07, + }, + + commands: { + get_brightness: 0x10, + set_brightness: 0x11, + + get_wireless_button: 0x12, + set_wireless_button: 0x13, + + get_backlight: 0x2d, + set_backlight: 0x2e, + + get_recovery_mode: 0xff, + set_recovery_mode: 0xff, + + get_performance_level: 0x31, + set_performance_level: 0x32, + + set_linux: 0xff, + }, + + performance_levels: { + { + name: "normal", + value: 0, + }, + { + name: "silent", + value: 1, + }, + { + name: "overclock", + value: 2, + }, + { }, + }, + }, + { }, +}; + +static struct sabi_config *sabi_config; + static void __iomem *sabi; static void __iomem *sabi_iface; static void __iomem *f0000_segment; @@ -109,21 +227,21 @@ MODULE_PARM_DESC(debug, "Debug enabled or not"); static int sabi_get_command(u8 command, struct sabi_retval *sretval) { int retval = 0; - u16 port = readw(sabi + SABI_HEADER_PORT); + u16 port = readw(sabi + sabi_config->header_offsets.port); mutex_lock(&sabi_mutex); /* enable memory to be able to write to it */ - outb(readb(sabi + SABI_HEADER_EN_MEM), port); + outb(readb(sabi + sabi_config->header_offsets.en_mem), port); /* write out the command */ - writew(MAIN_FUNCTION, sabi_iface + SABI_IFACE_MAIN); + writew(sabi_config->main_function, sabi_iface + SABI_IFACE_MAIN); writew(command, sabi_iface + SABI_IFACE_SUB); writeb(0, sabi_iface + SABI_IFACE_COMPLETE); - outb(readb(sabi + SABI_HEADER_IFACEFUNC), port); + outb(readb(sabi + sabi_config->header_offsets.iface_func), port); /* write protect memory to make it safe */ - outb(readb(sabi + SABI_HEADER_RE_MEM), port); + outb(readb(sabi + sabi_config->header_offsets.re_mem), port); /* see if the command actually succeeded */ if (readb(sabi_iface + SABI_IFACE_COMPLETE) == 0xaa && @@ -156,22 +274,22 @@ exit: static int sabi_set_command(u8 command, u8 data) { int retval = 0; - u16 port = readw(sabi + SABI_HEADER_PORT); + u16 port = readw(sabi + sabi_config->header_offsets.port); mutex_lock(&sabi_mutex); /* enable memory to be able to write to it */ - outb(readb(sabi + SABI_HEADER_EN_MEM), port); + outb(readb(sabi + sabi_config->header_offsets.en_mem), port); /* write out the command */ - writew(MAIN_FUNCTION, sabi_iface + SABI_IFACE_MAIN); + writew(sabi_config->main_function, sabi_iface + SABI_IFACE_MAIN); writew(command, sabi_iface + SABI_IFACE_SUB); writeb(0, sabi_iface + SABI_IFACE_COMPLETE); writeb(data, sabi_iface + SABI_IFACE_DATA); - outb(readb(sabi + SABI_HEADER_IFACEFUNC), port); + outb(readb(sabi + sabi_config->header_offsets.iface_func), port); /* write protect memory to make it safe */ - outb(readb(sabi + SABI_HEADER_RE_MEM), port); + outb(readb(sabi + sabi_config->header_offsets.re_mem), port); /* see if the command actually succeeded */ if (readb(sabi_iface + SABI_IFACE_COMPLETE) == 0xaa && @@ -194,21 +312,21 @@ static void test_backlight(void) { struct sabi_retval sretval; - sabi_get_command(GET_BACKLIGHT, &sretval); + sabi_get_command(sabi_config->commands.get_backlight, &sretval); printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]); - sabi_set_command(SET_BACKLIGHT, 0); + sabi_set_command(sabi_config->commands.set_backlight, 0); printk(KERN_DEBUG "backlight should be off\n"); - sabi_get_command(GET_BACKLIGHT, &sretval); + sabi_get_command(sabi_config->commands.get_backlight, &sretval); printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]); msleep(1000); - sabi_set_command(SET_BACKLIGHT, 1); + sabi_set_command(sabi_config->commands.set_backlight, 1); printk(KERN_DEBUG "backlight should be on\n"); - sabi_get_command(GET_BACKLIGHT, &sretval); + sabi_get_command(sabi_config->commands.get_backlight, &sretval); printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]); } @@ -216,21 +334,21 @@ static void test_wireless(void) { struct sabi_retval sretval; - sabi_get_command(GET_WIRELESS_BUTTON, &sretval); + sabi_get_command(sabi_config->commands.get_wireless_button, &sretval); printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]); - sabi_set_command(SET_WIRELESS_BUTTON, 0); + sabi_set_command(sabi_config->commands.set_wireless_button, 0); printk(KERN_DEBUG "wireless led should be off\n"); - sabi_get_command(GET_WIRELESS_BUTTON, &sretval); + sabi_get_command(sabi_config->commands.get_wireless_button, &sretval); printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]); msleep(1000); - sabi_set_command(SET_WIRELESS_BUTTON, 1); + sabi_set_command(sabi_config->commands.set_wireless_button, 1); printk(KERN_DEBUG "wireless led should be on\n"); - sabi_get_command(GET_WIRELESS_BUTTON, &sretval); + sabi_get_command(sabi_config->commands.get_wireless_button, &sretval); printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]); } @@ -240,7 +358,7 @@ static u8 read_brightness(void) int user_brightness = 0; int retval; - retval = sabi_get_command(GET_BRIGHTNESS, &sretval); + retval = sabi_get_command(sabi_config->commands.get_brightness, &sretval); if (!retval) user_brightness = sretval.retval[0]; if (user_brightness != 0) @@ -250,7 +368,7 @@ static u8 read_brightness(void) static void set_brightness(u8 user_brightness) { - sabi_set_command(SET_BRIGHTNESS, user_brightness + 1); + sabi_set_command(sabi_config->commands.set_brightness, user_brightness + 1); } static int get_brightness(struct backlight_device *bd) @@ -263,9 +381,9 @@ static int update_status(struct backlight_device *bd) set_brightness(bd->props.brightness); if (bd->props.power == FB_BLANK_UNBLANK) - sabi_set_command(SET_BACKLIGHT, 1); + sabi_set_command(sabi_config->commands.set_backlight, 1); else - sabi_set_command(SET_BACKLIGHT, 0); + sabi_set_command(sabi_config->commands.set_backlight, 0); return 0; } @@ -282,9 +400,9 @@ static int rfkill_set(void *data, bool blocked) * blocked == true is off */ if (blocked) - sabi_set_command(SET_WIRELESS_BUTTON, 0); + sabi_set_command(sabi_config->commands.set_wireless_button, 0); else - sabi_set_command(SET_WIRELESS_BUTTON, 1); + sabi_set_command(sabi_config->commands.set_wireless_button, 1); return 0; } @@ -317,47 +435,51 @@ static void destroy_wireless(void) rfkill_destroy(rfk); } -static ssize_t get_silent_state(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t get_performance_level(struct device *dev, + struct device_attribute *attr, char *buf) { struct sabi_retval sretval; int retval; + int pLevel; /* Read the state */ - retval = sabi_get_command(GET_PERFORMANCE_LEVEL, &sretval); + retval = sabi_get_command(sabi_config->commands.get_performance_level, &sretval); if (retval) return retval; /* The logic is backwards, yeah, lots of fun... */ - if (sretval.retval[0] == 0) - retval = 1; - else - retval = 0; - return sprintf(buf, "%d\n", retval); + for (pLevel = 0; sabi_config->performance_levels[pLevel].name; ++pLevel) + { + if (sretval.retval[0] == sabi_config->performance_levels[pLevel].value) + return sprintf(buf, "%s\n", sabi_config->performance_levels[pLevel].name); + } + return sprintf(buf, "%s\n", "unknown"); } -static ssize_t set_silent_state(struct device *dev, +static ssize_t set_performance_level(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - char value; - if (count >= 1) { - value = buf[0]; - if ((value == '0') || (value == 'n') || (value == 'N')) { - /* Turn speed up */ - sabi_set_command(SET_PERFORMANCE_LEVEL, 0x01); - } else if ((value == '1') || (value == 'y') || (value == 'Y')) { - /* Turn speed down */ - sabi_set_command(SET_PERFORMANCE_LEVEL, 0x00); - } else { - return -EINVAL; + int pLevel; + for (pLevel = 0; sabi_config->performance_levels[pLevel].name; ++pLevel) + { + struct sabi_performance_level *level = + &sabi_config->performance_levels[pLevel]; + if (!strncasecmp(level->name, buf, strlen(level->name))) + { + sabi_set_command(sabi_config->commands.set_performance_level, + level->value); + break; + } } + if (!sabi_config->performance_levels[pLevel].name) + return -EINVAL; } return count; } -static DEVICE_ATTR(silent, S_IWUSR | S_IRUGO, - get_silent_state, set_silent_state); +static DEVICE_ATTR(performance_level, S_IWUSR | S_IRUGO, + get_performance_level, set_performance_level); static int __init dmi_check_cb(const struct dmi_system_id *id) @@ -392,14 +514,31 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }; MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); +static int find_signature(void __iomem *memcheck, const char *testStr) +{ + int pStr; + int loca; + pStr = 0; + for (loca = 0; loca < 0xffff; loca++) { + char temp = readb(memcheck + loca); + + if (temp == testStr[pStr]) { + if (pStr == strlen(testStr)-1) + break; + ++pStr; + } else { + pStr = 0; + } + } + return loca; +} + static int __init samsung_init(void) { struct backlight_properties props; struct sabi_retval sretval; - const char *testStr = "SECLINUX"; - void __iomem *memcheck; unsigned int ifaceP; - int pStr; + int pConfig; int loca; int retval; @@ -414,50 +553,45 @@ static int __init samsung_init(void) return -EINVAL; } - /* Try to find the signature "SECLINUX" in memory to find the header */ - pStr = 0; - memcheck = f0000_segment; - for (loca = 0; loca < 0xffff; loca++) { - char temp = readb(memcheck + loca); - - if (temp == testStr[pStr]) { - if (pStr == strlen(testStr)-1) - break; - ++pStr; - } else { - pStr = 0; - } + /* Try to find one of the signatures in memory to find the header */ + for (pConfig = 0; sabi_configs[pConfig].test_string != 0; ++pConfig) + { + sabi_config = &sabi_configs[pConfig]; + loca = find_signature(f0000_segment, sabi_config->test_string); + if (loca != 0xffff) + break; } + if (loca == 0xffff) { printk(KERN_ERR "This computer does not support SABI\n"); goto error_no_signature; - } + } /* point to the SMI port Number */ loca += 1; - sabi = (memcheck + loca); + sabi = (f0000_segment + loca); if (debug) { printk(KERN_DEBUG "This computer supports SABI==%x\n", loca + 0xf0000 - 6); printk(KERN_DEBUG "SABI header:\n"); printk(KERN_DEBUG " SMI Port Number = 0x%04x\n", - readw(sabi + SABI_HEADER_PORT)); + readw(sabi + sabi_config->header_offsets.port)); printk(KERN_DEBUG " SMI Interface Function = 0x%02x\n", - readb(sabi + SABI_HEADER_IFACEFUNC)); + readb(sabi + sabi_config->header_offsets.iface_func)); printk(KERN_DEBUG " SMI enable memory buffer = 0x%02x\n", - readb(sabi + SABI_HEADER_EN_MEM)); + readb(sabi + sabi_config->header_offsets.en_mem)); printk(KERN_DEBUG " SMI restore memory buffer = 0x%02x\n", - readb(sabi + SABI_HEADER_RE_MEM)); + readb(sabi + sabi_config->header_offsets.re_mem)); printk(KERN_DEBUG " SABI data offset = 0x%04x\n", - readw(sabi + SABI_HEADER_DATA_OFFSET)); + readw(sabi + sabi_config->header_offsets.data_offset)); printk(KERN_DEBUG " SABI data segment = 0x%04x\n", - readw(sabi + SABI_HEADER_DATA_SEGMENT)); + readw(sabi + sabi_config->header_offsets.data_segment)); } /* Get a pointer to the SABI Interface */ - ifaceP = (readw(sabi + SABI_HEADER_DATA_SEGMENT) & 0x0ffff) << 4; - ifaceP += readw(sabi + SABI_HEADER_DATA_OFFSET) & 0x0ffff; + ifaceP = (readw(sabi + sabi_config->header_offsets.data_segment) & 0x0ffff) << 4; + ifaceP += readw(sabi + sabi_config->header_offsets.data_offset) & 0x0ffff; sabi_iface = ioremap(ifaceP, 16); if (!sabi_iface) { printk(KERN_ERR "Can't remap %x\n", ifaceP); @@ -470,15 +604,18 @@ static int __init samsung_init(void) test_backlight(); test_wireless(); - retval = sabi_get_command(GET_BRIGHTNESS, &sretval); + retval = sabi_get_command(sabi_config->commands.get_brightness, &sretval); printk(KERN_DEBUG "brightness = 0x%02x\n", sretval.retval[0]); } /* Turn on "Linux" mode in the BIOS */ - retval = sabi_set_command(SET_LINUX, 0x81); - if (retval) { - printk(KERN_ERR KBUILD_MODNAME ": Linux mode was not set!\n"); - goto error_no_platform; + if (sabi_config->commands.set_linux != 0xff) + { + retval = sabi_set_command(sabi_config->commands.set_linux, 0x81); + if (retval) { + printk(KERN_ERR KBUILD_MODNAME ": Linux mode was not set!\n"); + goto error_no_platform; + } } /* knock up a platform device to hang stuff off of */ @@ -503,7 +640,7 @@ static int __init samsung_init(void) if (retval) goto error_no_rfk; - retval = device_create_file(&sdev->dev, &dev_attr_silent); + retval = device_create_file(&sdev->dev, &dev_attr_performance_level); if (retval) goto error_file_create; @@ -530,9 +667,10 @@ error_no_signature: static void __exit samsung_exit(void) { /* Turn off "Linux" mode in the BIOS */ - sabi_set_command(SET_LINUX, 0x80); + if (sabi_config->commands.set_linux != 0xff) + sabi_set_command(sabi_config->commands.set_linux, 0x80); - device_remove_file(&sdev->dev, &dev_attr_silent); + device_remove_file(&sdev->dev, &dev_attr_performance_level); backlight_device_unregister(backlight_device); destroy_wireless(); iounmap(sabi_iface); -- cgit v1.2.3 From 837b03cd182f2bcb715cba8844cf82baa8b48170 Mon Sep 17 00:00:00 2001 From: Ingmar Steen Date: Mon, 7 Feb 2011 14:32:32 +0100 Subject: staging: samsung-laptop: Added Samsung X125 DMI info. Signed-off-by: Ingmar Steen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index 4b7525fa02b2..1a3458a8dfaf 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -510,6 +510,16 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, .callback = dmi_check_cb, }, + { + .ident = "X125", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "X125"), + DMI_MATCH(DMI_BOARD_NAME, "X125"), + }, + .callback = dmi_check_cb, + }, { }, }; MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); -- cgit v1.2.3 From 27f55e920d66cb0af6bc7bab73e7c63505d908ed Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 9 Feb 2011 12:19:45 -0800 Subject: Staging: samsung-laptop: fix up space/tab coding style issues These were introduced with the patch, "staging: samsung-laptop: Extend samsung-laptop platform driver to support another flavor of its platform BIOS." Cc: Ingmar Steen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 34 ++++++++++++------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index 1a3458a8dfaf..b38c8d817e8e 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -111,15 +111,15 @@ static struct sabi_config sabi_configs[] = { { test_string: "SECLINUX", - main_function: 0x4c59, - - header_offsets: { - port: 0x00, - re_mem: 0x02, - iface_func: 0x03, - en_mem: 0x04, - data_offset: 0x05, - data_segment: 0x07, + main_function: 0x4c59, + + header_offsets: { + port: 0x00, + re_mem: 0x02, + iface_func: 0x03, + en_mem: 0x04, + data_offset: 0x05, + data_segment: 0x07, }, commands: { @@ -156,15 +156,15 @@ static struct sabi_config sabi_configs[] = { { test_string: "SwSmi@", - main_function: 0x5843, + main_function: 0x5843, - header_offsets: { - port: 0x00, - re_mem: 0x04, - iface_func: 0x02, - en_mem: 0x03, - data_offset: 0x05, - data_segment: 0x07, + header_offsets: { + port: 0x00, + re_mem: 0x04, + iface_func: 0x02, + en_mem: 0x03, + data_offset: 0x05, + data_segment: 0x07, }, commands: { -- cgit v1.2.3 From 3e55eb376ec32efea478035516c80529a83383d5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 9 Feb 2011 12:22:41 -0800 Subject: Staging: samsung-laptop: fix up brace coding style issues These were introduced with the patch, "staging: samsung-laptop: Extend samsung-laptop platform driver to support another flavor of its platform BIOS." Cc: Ingmar Steen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index b38c8d817e8e..a221947c82ab 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -448,8 +448,7 @@ static ssize_t get_performance_level(struct device *dev, return retval; /* The logic is backwards, yeah, lots of fun... */ - for (pLevel = 0; sabi_config->performance_levels[pLevel].name; ++pLevel) - { + for (pLevel = 0; sabi_config->performance_levels[pLevel].name; ++pLevel) { if (sretval.retval[0] == sabi_config->performance_levels[pLevel].value) return sprintf(buf, "%s\n", sabi_config->performance_levels[pLevel].name); } @@ -462,12 +461,10 @@ static ssize_t set_performance_level(struct device *dev, { if (count >= 1) { int pLevel; - for (pLevel = 0; sabi_config->performance_levels[pLevel].name; ++pLevel) - { + for (pLevel = 0; sabi_config->performance_levels[pLevel].name; ++pLevel) { struct sabi_performance_level *level = &sabi_config->performance_levels[pLevel]; - if (!strncasecmp(level->name, buf, strlen(level->name))) - { + if (!strncasecmp(level->name, buf, strlen(level->name))) { sabi_set_command(sabi_config->commands.set_performance_level, level->value); break; @@ -564,8 +561,7 @@ static int __init samsung_init(void) } /* Try to find one of the signatures in memory to find the header */ - for (pConfig = 0; sabi_configs[pConfig].test_string != 0; ++pConfig) - { + for (pConfig = 0; sabi_configs[pConfig].test_string != 0; ++pConfig) { sabi_config = &sabi_configs[pConfig]; loca = find_signature(f0000_segment, sabi_config->test_string); if (loca != 0xffff) @@ -619,8 +615,7 @@ static int __init samsung_init(void) } /* Turn on "Linux" mode in the BIOS */ - if (sabi_config->commands.set_linux != 0xff) - { + if (sabi_config->commands.set_linux != 0xff) { retval = sabi_set_command(sabi_config->commands.set_linux, 0x81); if (retval) { printk(KERN_ERR KBUILD_MODNAME ": Linux mode was not set!\n"); -- cgit v1.2.3 From 1540e350ddef5e6bfd27c222684ca8fdec4ad2f8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 9 Feb 2011 12:30:00 -0800 Subject: Staging: samsung-laptop: change sabi_configs to be in C99 format This makes the coding style checker a lot happier. Cc: Ingmar Steen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 108 ++++++++++++------------ 1 file changed, 54 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index a221947c82ab..798aaebd3972 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -109,95 +109,95 @@ struct sabi_config { static struct sabi_config sabi_configs[] = { { - test_string: "SECLINUX", + .test_string = "SECLINUX", - main_function: 0x4c59, + .main_function = 0x4c59, - header_offsets: { - port: 0x00, - re_mem: 0x02, - iface_func: 0x03, - en_mem: 0x04, - data_offset: 0x05, - data_segment: 0x07, + .header_offsets = { + .port = 0x00, + .re_mem = 0x02, + .iface_func = 0x03, + .en_mem = 0x04, + .data_offset = 0x05, + .data_segment = 0x07, }, - commands: { - get_brightness: 0x00, - set_brightness: 0x01, + .commands = { + .get_brightness = 0x00, + .set_brightness = 0x01, - get_wireless_button: 0x02, - set_wireless_button: 0x03, + .get_wireless_button = 0x02, + .set_wireless_button = 0x03, - get_backlight: 0x04, - set_backlight: 0x05, + .get_backlight = 0x04, + .set_backlight = 0x05, - get_recovery_mode: 0x06, - set_recovery_mode: 0x07, + .get_recovery_mode = 0x06, + .set_recovery_mode = 0x07, - get_performance_level: 0x08, - set_performance_level: 0x09, + .get_performance_level = 0x08, + .set_performance_level = 0x09, - set_linux: 0x0a, + .set_linux = 0x0a, }, - performance_levels: { + .performance_levels = { { - name: "silent", - value: 0, + .name = "silent", + .value = 0, }, { - name: "normal", - value: 1, + .name = "normal", + .value = 1, }, { }, }, }, { - test_string: "SwSmi@", + .test_string = "SwSmi@", - main_function: 0x5843, + .main_function = 0x5843, - header_offsets: { - port: 0x00, - re_mem: 0x04, - iface_func: 0x02, - en_mem: 0x03, - data_offset: 0x05, - data_segment: 0x07, + .header_offsets = { + .port = 0x00, + .re_mem = 0x04, + .iface_func = 0x02, + .en_mem = 0x03, + .data_offset = 0x05, + .data_segment = 0x07, }, - commands: { - get_brightness: 0x10, - set_brightness: 0x11, + .commands = { + .get_brightness = 0x10, + .set_brightness = 0x11, - get_wireless_button: 0x12, - set_wireless_button: 0x13, + .get_wireless_button = 0x12, + .set_wireless_button = 0x13, - get_backlight: 0x2d, - set_backlight: 0x2e, + .get_backlight = 0x2d, + .set_backlight = 0x2e, - get_recovery_mode: 0xff, - set_recovery_mode: 0xff, + .get_recovery_mode = 0xff, + .set_recovery_mode = 0xff, - get_performance_level: 0x31, - set_performance_level: 0x32, + .get_performance_level = 0x31, + .set_performance_level = 0x32, - set_linux: 0xff, + .set_linux = 0xff, }, - performance_levels: { + .performance_levels = { { - name: "normal", - value: 0, + .name = "normal", + .value = 0, }, { - name: "silent", - value: 1, + .name = "silent", + .value = 1, }, { - name: "overclock", - value: 2, + .name = "overclock", + .value = 2, }, { }, }, -- cgit v1.2.3 From 55bb5f4bf26ca968ff7ee026fed1ad377803ce03 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 9 Feb 2011 12:34:28 -0800 Subject: Staging: samsung-laptop: fix up a few more minor coding style issues Cc: Ingmar Steen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index 798aaebd3972..2911effbaa35 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -54,11 +54,15 @@ struct sabi_header_offsets { }; struct sabi_commands { - /* Brightness is 0 - 8, as described above. Value 0 is for the BIOS to use */ + /* + * Brightness is 0 - 8, as described above. + * Value 0 is for the BIOS to use + */ u8 get_brightness; u8 set_brightness; - /* first byte: + /* + * first byte: * 0x00 - wireless is off * 0x01 - wireless is on * second byte: @@ -358,7 +362,8 @@ static u8 read_brightness(void) int user_brightness = 0; int retval; - retval = sabi_get_command(sabi_config->commands.get_brightness, &sretval); + retval = sabi_get_command(sabi_config->commands.get_brightness, + &sretval); if (!retval) user_brightness = sretval.retval[0]; if (user_brightness != 0) @@ -368,7 +373,8 @@ static u8 read_brightness(void) static void set_brightness(u8 user_brightness) { - sabi_set_command(sabi_config->commands.set_brightness, user_brightness + 1); + sabi_set_command(sabi_config->commands.set_brightness, + user_brightness + 1); } static int get_brightness(struct backlight_device *bd) @@ -443,7 +449,8 @@ static ssize_t get_performance_level(struct device *dev, int pLevel; /* Read the state */ - retval = sabi_get_command(sabi_config->commands.get_performance_level, &sretval); + retval = sabi_get_command(sabi_config->commands.get_performance_level, + &sretval); if (retval) return retval; @@ -466,7 +473,7 @@ static ssize_t set_performance_level(struct device *dev, &sabi_config->performance_levels[pLevel]; if (!strncasecmp(level->name, buf, strlen(level->name))) { sabi_set_command(sabi_config->commands.set_performance_level, - level->value); + level->value); break; } } @@ -610,13 +617,15 @@ static int __init samsung_init(void) test_backlight(); test_wireless(); - retval = sabi_get_command(sabi_config->commands.get_brightness, &sretval); + retval = sabi_get_command(sabi_config->commands.get_brightness, + &sretval); printk(KERN_DEBUG "brightness = 0x%02x\n", sretval.retval[0]); } /* Turn on "Linux" mode in the BIOS */ if (sabi_config->commands.set_linux != 0xff) { - retval = sabi_set_command(sabi_config->commands.set_linux, 0x81); + retval = sabi_set_command(sabi_config->commands.set_linux, + 0x81); if (retval) { printk(KERN_ERR KBUILD_MODNAME ": Linux mode was not set!\n"); goto error_no_platform; -- cgit v1.2.3 From c91d01556f52255a31575be0cb1981c92a2a5028 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 9 Feb 2011 08:46:06 +0100 Subject: iwl3945: remove plcp check Patch fixes: https://bugzilla.redhat.com/show_bug.cgi?id=654599 Many users report very low speed problem on 3945 devices, this patch fixes problem, but only for some of them. For unknown reason, sometimes after hw scanning, device is not able to receive frames at high rate. Since plcp health check may request hw scan to "reset radio", performance problem start to be observable after update kernel to .35, where plcp check was introduced. Bug reporter confirmed that removing plcp check fixed problem for him. Reported-and-tested-by: SilvioTO Cc: stable@kernel.org # 2.6.35+ Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index a9b852be4509..3eb14fd2204b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2734,7 +2734,6 @@ static struct iwl_lib_ops iwl3945_lib = { .isr_ops = { .isr = iwl_isr_legacy, }, - .check_plcp_health = iwl3945_good_plcp_health, .debugfs_ops = { .rx_stats_read = iwl3945_ucode_rx_stats_read, -- cgit v1.2.3 From 5bf8b724d206d8e46da504eda847a1d2f9ad4e70 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 9 Feb 2011 12:39:01 -0800 Subject: Staging: samsung-laptop: fix up some variable nameing No camelcase in the Linux kernel please. Cc: Ingmar Steen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 34 ++++++++++++------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index 2911effbaa35..ca11535e8974 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -446,7 +446,7 @@ static ssize_t get_performance_level(struct device *dev, { struct sabi_retval sretval; int retval; - int pLevel; + int i; /* Read the state */ retval = sabi_get_command(sabi_config->commands.get_performance_level, @@ -455,9 +455,9 @@ static ssize_t get_performance_level(struct device *dev, return retval; /* The logic is backwards, yeah, lots of fun... */ - for (pLevel = 0; sabi_config->performance_levels[pLevel].name; ++pLevel) { - if (sretval.retval[0] == sabi_config->performance_levels[pLevel].value) - return sprintf(buf, "%s\n", sabi_config->performance_levels[pLevel].name); + for (i = 0; sabi_config->performance_levels[i].name; ++i) { + if (sretval.retval[0] == sabi_config->performance_levels[i].value) + return sprintf(buf, "%s\n", sabi_config->performance_levels[i].name); } return sprintf(buf, "%s\n", "unknown"); } @@ -467,17 +467,17 @@ static ssize_t set_performance_level(struct device *dev, size_t count) { if (count >= 1) { - int pLevel; - for (pLevel = 0; sabi_config->performance_levels[pLevel].name; ++pLevel) { + int i; + for (i = 0; sabi_config->performance_levels[i].name; ++i) { struct sabi_performance_level *level = - &sabi_config->performance_levels[pLevel]; + &sabi_config->performance_levels[i]; if (!strncasecmp(level->name, buf, strlen(level->name))) { sabi_set_command(sabi_config->commands.set_performance_level, level->value); break; } } - if (!sabi_config->performance_levels[pLevel].name) + if (!sabi_config->performance_levels[i].name) return -EINVAL; } return count; @@ -530,18 +530,18 @@ MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); static int find_signature(void __iomem *memcheck, const char *testStr) { - int pStr; + int i = 0; int loca; - pStr = 0; + for (loca = 0; loca < 0xffff; loca++) { char temp = readb(memcheck + loca); - if (temp == testStr[pStr]) { - if (pStr == strlen(testStr)-1) + if (temp == testStr[i]) { + if (i == strlen(testStr)-1) break; - ++pStr; + ++i; } else { - pStr = 0; + i = 0; } } return loca; @@ -552,7 +552,7 @@ static int __init samsung_init(void) struct backlight_properties props; struct sabi_retval sretval; unsigned int ifaceP; - int pConfig; + int i; int loca; int retval; @@ -568,8 +568,8 @@ static int __init samsung_init(void) } /* Try to find one of the signatures in memory to find the header */ - for (pConfig = 0; sabi_configs[pConfig].test_string != 0; ++pConfig) { - sabi_config = &sabi_configs[pConfig]; + for (i = 0; sabi_configs[i].test_string != 0; ++i) { + sabi_config = &sabi_configs[i]; loca = find_signature(f0000_segment, sabi_config->test_string); if (loca != 0xffff) break; -- cgit v1.2.3 From d3c291169eecc2943d8fb0fea45fa58a88afbf2d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 9 Feb 2011 13:07:23 -0800 Subject: Staging: samsung-laptop: Added support for Samsung NC10 laptop Info was provided by Soeren Sonnenburg Cc: Soeren Sonnenburg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index ca11535e8974..47ffdfb819c7 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -524,6 +524,16 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, .callback = dmi_check_cb, }, + { + .ident = "NC10", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), + DMI_MATCH(DMI_BOARD_NAME, "NC10"), + }, + .callback = dmi_check_cb, + }, { }, }; MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); -- cgit v1.2.3 From 78a2fcb4fe1b3dc626da56fac7912e7091425892 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 9 Feb 2011 13:09:26 -0800 Subject: Staging: samsung-laptop: add support for NP-Q45 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support for the Samsung NP-Q45 from Jérémie Huchet added Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index 47ffdfb819c7..5b2059d8da1d 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -534,6 +534,16 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, .callback = dmi_check_cb, }, + { + .ident = "NP-Q45", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"), + DMI_MATCH(DMI_BOARD_NAME, "SQ45S70S"), + }, + .callback = dmi_check_cb, + }, { }, }; MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); -- cgit v1.2.3 From 8c79a61095936f81cb05e99062185cb987d524ab Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Mon, 7 Feb 2011 13:44:33 -0800 Subject: ath9k: Print channel-type in chan-change dbg message. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 2d4e9b861b60..d998aabf39ac 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1678,8 +1678,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) else sc->sc_flags &= ~SC_OP_OFFCHANNEL; - ath_dbg(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", - curchan->center_freq); + ath_dbg(common, ATH_DBG_CONFIG, + "Set channel: %d MHz type: %d\n", + curchan->center_freq, conf->channel_type); ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos], curchan, conf->channel_type); -- cgit v1.2.3 From 603b3eefb92e0886ed4dd5f73d4c07b304405b40 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Mon, 7 Feb 2011 13:44:37 -0800 Subject: ath9k: Add debug info for configuring power level. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index d998aabf39ac..12e0ac688274 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1726,6 +1726,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) } if (changed & IEEE80211_CONF_CHANGE_POWER) { + ath_dbg(common, ATH_DBG_CONFIG, + "Set power: %d\n", conf->power_level); sc->config.txpowlimit = 2 * conf->power_level; ath9k_ps_wakeup(sc); ath9k_cmn_update_txpow(ah, sc->curtxpow, -- cgit v1.2.3 From 9814f6b34be5179849c0872e81eb99286ef4b051 Mon Sep 17 00:00:00 2001 From: Steve Brown Date: Mon, 7 Feb 2011 17:10:39 -0700 Subject: ath9k: Remove redundant beacon_interval The variable appears in both ath_softc and ath_beacon_config. The struct ath_beacon_config is embedded in ath_softc. The redundant variable was added by commit id 57c4d7b4c4986037be51476b8e3025d5ba18d8b8. Signed-off-by: Steve Brown Reviewed-by: Mohammed Shafi Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 4 +--- drivers/net/wireless/ath/ath9k/beacon.c | 6 ++++-- drivers/net/wireless/ath/ath9k/main.c | 3 ++- drivers/net/wireless/ath/ath9k/xmit.c | 3 ++- 4 files changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 7c8409e53598..56dee3719f95 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -370,7 +370,7 @@ struct ath_vif { #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) struct ath_beacon_config { - u16 beacon_interval; + int beacon_interval; u16 listen_interval; u16 dtim_period; u16 bmiss_timeout; @@ -633,8 +633,6 @@ struct ath_softc { struct ath9k_hw_cal_data caldata; int last_rssi; - int beacon_interval; - #ifdef CONFIG_ATH9K_DEBUGFS struct ath9k_debug debug; spinlock_t nodes_lock; diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index fcb36abfc309..ed6e7d66fc38 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -226,6 +226,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif) struct ath_vif *avp; struct ath_buf *bf; struct sk_buff *skb; + struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; __le64 tstamp; avp = (void *)vif->drv_priv; @@ -282,7 +283,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif) u64 tsfadjust; int intval; - intval = sc->beacon_interval ? : ATH_DEFAULT_BINTVAL; + intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL; /* * Calculate the TSF offset for this beacon slot, i.e., the @@ -346,6 +347,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp) void ath_beacon_tasklet(unsigned long data) { struct ath_softc *sc = (struct ath_softc *)data; + struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct ath_buf *bf = NULL; @@ -393,7 +395,7 @@ void ath_beacon_tasklet(unsigned long data) * on the tsf to safeguard against missing an swba. */ - intval = sc->beacon_interval ? : ATH_DEFAULT_BINTVAL; + intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL; tsf = ath9k_hw_gettsf64(ah); tsftu = TSF_TO_TU(tsf>>32, tsf); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 12e0ac688274..8469d7c8744a 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1891,6 +1891,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, u32 changed) { struct ath_softc *sc = hw->priv; + struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct ath_vif *avp = (void *)vif->drv_priv; @@ -1949,7 +1950,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); if (changed & BSS_CHANGED_BEACON_INT) { - sc->beacon_interval = bss_conf->beacon_int; + cur_conf->beacon_interval = bss_conf->beacon_int; /* * In case of AP mode, the HW TSF has to be reset * when the beacon interval changes. diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 68a1c7612e9b..8d89aa958f1b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1055,6 +1055,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum, int ath_cabq_update(struct ath_softc *sc) { struct ath9k_tx_queue_info qi; + struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; int qnum = sc->beacon.cabq->axq_qnum; ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi); @@ -1066,7 +1067,7 @@ int ath_cabq_update(struct ath_softc *sc) else if (sc->config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND) sc->config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND; - qi.tqi_readyTime = (sc->beacon_interval * + qi.tqi_readyTime = (cur_conf->beacon_interval * sc->config.cabqReadytime) / 100; ath_txq_update(sc, qnum, &qi); -- cgit v1.2.3 From ca3d9389642946072ed448b2b7386f9e5d3f296b Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 8 Feb 2011 09:31:55 +0100 Subject: iwlwifi: cleanup iwl_recover_from_statistics No functional change, make recover from statistics code easies to read. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-rx.c | 37 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 87a6fd84d4d2..bc89393fb696 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -234,33 +234,20 @@ EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif); void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt) { - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status) || + !iwl_is_any_associated(priv)) return; - if (iwl_is_any_associated(priv)) { - if (priv->cfg->ops->lib->check_ack_health) { - if (!priv->cfg->ops->lib->check_ack_health( - priv, pkt)) { - /* - * low ack count detected - * restart Firmware - */ - IWL_ERR(priv, "low ack count detected, " - "restart firmware\n"); - if (!iwl_force_reset(priv, IWL_FW_RESET, false)) - return; - } - } - if (priv->cfg->ops->lib->check_plcp_health) { - if (!priv->cfg->ops->lib->check_plcp_health( - priv, pkt)) { - /* - * high plcp error detected - * reset Radio - */ - iwl_force_reset(priv, IWL_RF_RESET, false); - } - } + + if (priv->cfg->ops->lib->check_ack_health && + !priv->cfg->ops->lib->check_ack_health(priv, pkt)) { + IWL_ERR(priv, "low ack count detected, restart firmware\n"); + if (!iwl_force_reset(priv, IWL_FW_RESET, false)) + return; } + + if (priv->cfg->ops->lib->check_plcp_health && + !priv->cfg->ops->lib->check_plcp_health(priv, pkt)) + iwl_force_reset(priv, IWL_RF_RESET, false); } EXPORT_SYMBOL(iwl_recover_from_statistics); -- cgit v1.2.3 From f266526da4d78b7af639e98777d453888b039c00 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 8 Feb 2011 09:31:57 +0100 Subject: iwlwifi: cleanup iwl_good_ack_health Make ack health code easies to read. Compared to previous code, we do not print debug messages when expected_ack_cnt_delta == 0 and also do check against negative deltas. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 69 +++++++++++++++++----------------- 1 file changed, 35 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 096f8ad0f1b1..50be23b5fea2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1407,34 +1407,37 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) /** * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries. * - * When the ACK count ratio is 0 and aggregated BA timeout retries exceeding + * When the ACK count ratio is low and aggregated BA timeout retries exceeding * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal * operation state. */ -bool iwl_good_ack_health(struct iwl_priv *priv, - struct iwl_rx_packet *pkt) +bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt) { - bool rc = true; - int actual_ack_cnt_delta, expected_ack_cnt_delta; - int ba_timeout_delta; - - actual_ack_cnt_delta = - le32_to_cpu(pkt->u.stats.tx.actual_ack_cnt) - - le32_to_cpu(priv->_agn.statistics.tx.actual_ack_cnt); - expected_ack_cnt_delta = - le32_to_cpu(pkt->u.stats.tx.expected_ack_cnt) - - le32_to_cpu(priv->_agn.statistics.tx.expected_ack_cnt); - ba_timeout_delta = - le32_to_cpu(pkt->u.stats.tx.agg.ba_timeout) - - le32_to_cpu(priv->_agn.statistics.tx.agg.ba_timeout); - if ((priv->_agn.agg_tids_count > 0) && - (expected_ack_cnt_delta > 0) && - (((actual_ack_cnt_delta * 100) / expected_ack_cnt_delta) - < ACK_CNT_RATIO) && - (ba_timeout_delta > BA_TIMEOUT_CNT)) { - IWL_DEBUG_RADIO(priv, "actual_ack_cnt delta = %d," - " expected_ack_cnt = %d\n", - actual_ack_cnt_delta, expected_ack_cnt_delta); + int actual_delta, expected_delta, ba_timeout_delta; + struct statistics_tx *cur, *old; + + if (priv->_agn.agg_tids_count) + return true; + + cur = &pkt->u.stats.tx; + old = &priv->_agn.statistics.tx; + + actual_delta = le32_to_cpu(cur->actual_ack_cnt) - + le32_to_cpu(old->actual_ack_cnt); + expected_delta = le32_to_cpu(cur->expected_ack_cnt) - + le32_to_cpu(old->expected_ack_cnt); + + /* Values should not be negative, but we do not trust the firmware */ + if (actual_delta <= 0 || expected_delta <= 0) + return true; + + ba_timeout_delta = le32_to_cpu(cur->agg.ba_timeout) - + le32_to_cpu(old->agg.ba_timeout); + + if ((actual_delta * 100 / expected_delta) < ACK_CNT_RATIO && + ba_timeout_delta > BA_TIMEOUT_CNT) { + IWL_DEBUG_RADIO(priv, "deltas: actual %d expected %d ba_timeout %d\n", + actual_delta, expected_delta, ba_timeout_delta); #ifdef CONFIG_IWLWIFI_DEBUGFS /* @@ -1442,20 +1445,18 @@ bool iwl_good_ack_health(struct iwl_priv *priv, * statistics aren't available. If DEBUGFS is set but * DEBUG is not, these will just compile out. */ - IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta = %d\n", + IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n", priv->_agn.delta_statistics.tx.rx_detected_cnt); IWL_DEBUG_RADIO(priv, - "ack_or_ba_timeout_collision delta = %d\n", - priv->_agn.delta_statistics.tx. - ack_or_ba_timeout_collision); + "ack_or_ba_timeout_collision delta %d\n", + priv->_agn.delta_statistics.tx.ack_or_ba_timeout_collision); #endif - IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n", - ba_timeout_delta); - if (!actual_ack_cnt_delta && - (ba_timeout_delta >= BA_TIMEOUT_MAX)) - rc = false; + + if (ba_timeout_delta >= BA_TIMEOUT_MAX) + return false; } - return rc; + + return true; } -- cgit v1.2.3 From 67acad5fe5df591e8f629050667912b0db2c72e7 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 8 Feb 2011 09:31:58 +0100 Subject: iwlwifi: fix ack health for WiFi/BT combo devices Combo devices have TX statistics on different place, because struct statistics_rx_bt and struct statistics_rx have different size. User proper values on combo devices instead of random data. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 50be23b5fea2..a3af656aab3d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1419,8 +1419,13 @@ bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt) if (priv->_agn.agg_tids_count) return true; - cur = &pkt->u.stats.tx; - old = &priv->_agn.statistics.tx; + if (iwl_bt_statistics(priv)) { + cur = &pkt->u.stats_bt.tx; + old = &priv->_agn.statistics_bt.tx; + } else { + cur = &pkt->u.stats.tx; + old = &priv->_agn.statistics.tx; + } actual_delta = le32_to_cpu(cur->actual_ack_cnt) - le32_to_cpu(old->actual_ack_cnt); -- cgit v1.2.3 From 6d1d4ea4a82f8c17a3ff7c2f677bc3d41ea7484b Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 8 Feb 2011 23:32:17 +0100 Subject: ssb: extract boardflags2 for SPROMs rev 4 and 5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/ssb/pci.c | 4 ++++ include/linux/ssb/ssb_regs.h | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 158449e55044..5b33b3b06f7f 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -468,10 +468,14 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0); SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0); SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0); + SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0); + SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0); } else { SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0); SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0); SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0); + SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0); + SPEX(boardflags2_hi, SSB_SPROM5_BFL2HI, 0xFFFF, 0); } SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A, SSB_SPROM4_ANTAVAIL_A_SHIFT); diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h index 489f7b6d61c5..df9211a84634 100644 --- a/include/linux/ssb/ssb_regs.h +++ b/include/linux/ssb/ssb_regs.h @@ -268,6 +268,8 @@ /* SPROM Revision 4 */ #define SSB_SPROM4_BFLLO 0x0044 /* Boardflags (low 16 bits) */ #define SSB_SPROM4_BFLHI 0x0046 /* Board Flags Hi */ +#define SSB_SPROM4_BFL2LO 0x0048 /* Board flags 2 (low 16 bits) */ +#define SSB_SPROM4_BFL2HI 0x004A /* Board flags 2 Hi */ #define SSB_SPROM4_IL0MAC 0x004C /* 6 byte MAC address for a/b/g/n */ #define SSB_SPROM4_CCODE 0x0052 /* Country Code (2 bytes) */ #define SSB_SPROM4_GPIOA 0x0056 /* Gen. Purpose IO # 0 and 1 */ @@ -358,6 +360,8 @@ #define SSB_SPROM5_CCODE 0x0044 /* Country Code (2 bytes) */ #define SSB_SPROM5_BFLLO 0x004A /* Boardflags (low 16 bits) */ #define SSB_SPROM5_BFLHI 0x004C /* Board Flags Hi */ +#define SSB_SPROM5_BFL2LO 0x004E /* Board flags 2 (low 16 bits) */ +#define SSB_SPROM5_BFL2HI 0x0050 /* Board flags 2 Hi */ #define SSB_SPROM5_IL0MAC 0x0052 /* 6 byte MAC address for a/b/g/n */ #define SSB_SPROM5_GPIOA 0x0076 /* Gen. Purpose IO # 0 and 1 */ #define SSB_SPROM5_GPIOA_P0 0x00FF /* Pin 0 */ -- cgit v1.2.3 From aa72eb0778be48edfeacc51c24c9617f1a1947b5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 9 Feb 2011 13:19:03 -0800 Subject: Staging: samsung-laptop: add a bunch more laptop DMI signatures Taken from the fork of the driver at: http://code.google.com/p/easy-slow-down-manager/ which should no longer be needed now that the in-kernel driver now supports these laptops. Cc: Kobelkov Sergey Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 50 ++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index 5b2059d8da1d..51ec6216b1ea 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -1,5 +1,5 @@ /* - * Samsung N130 Laptop driver + * Samsung Laptop driver * * Copyright (C) 2009 Greg Kroah-Hartman (gregkh@suse.de) * Copyright (C) 2009 Novell Inc. @@ -544,6 +544,54 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, .callback = dmi_check_cb, }, + { + .ident = "X360", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "X360"), + DMI_MATCH(DMI_BOARD_NAME, "X360"), + }, + .callback = dmi_check_cb, + }, + { + .ident = "R518", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "R518"), + DMI_MATCH(DMI_BOARD_NAME, "R518"), + }, + .callback = dmi_check_cb, + }, + { + .ident = "N150/N210/N220", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220"), + DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220"), + }, + .callback = dmi_check_cb, + }, + { + .ident = "R530/R730", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "R530/R730"), + DMI_MATCH(DMI_BOARD_NAME, "R530/R730"), + }, + .callback = dmi_check_cb, + }, + { + .ident = "NF110/NF210/NF310", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "NF110/NF210/NF310"), + DMI_MATCH(DMI_BOARD_NAME, "NF110/NF210/NF310"), + }, + .callback = dmi_check_cb, + }, { }, }; MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); -- cgit v1.2.3 From 139467433e50926d22338e9dc754feaaf94b9db0 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 9 Feb 2011 20:01:16 +0000 Subject: drm/i915/sdvo: If we have an EDID confirm it matches the mode of the connection If we have an EDID for a digital panel, but we are probing a non-TMDS connector then we know that this is a false detection, and vice versa. This should reduce the number of bogus outputs on multi-function adapters that report the same output on multiple connectors. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=34101 Reported-by: Sebastien Caty Tested-by: Sebastien Caty Signed-off-by: Chris Wilson Cc: stable@kernel.org --- drivers/gpu/drm/i915/intel_sdvo.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 6a09c1413d60..d2dd90a9a101 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -46,6 +46,7 @@ SDVO_TV_MASK) #define IS_TV(c) (c->output_flag & SDVO_TV_MASK) +#define IS_TMDS(c) (c->output_flag & SDVO_TMDS_MASK) #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) #define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK)) @@ -1359,7 +1360,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid); intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid); } - } + } else + status = connector_status_disconnected; connector->display_info.raw_edid = NULL; kfree(edid); } @@ -1407,10 +1409,25 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) if ((intel_sdvo_connector->output_flag & response) == 0) ret = connector_status_disconnected; - else if (response & SDVO_TMDS_MASK) + else if (IS_TMDS(intel_sdvo_connector)) ret = intel_sdvo_hdmi_sink_detect(connector); - else - ret = connector_status_connected; + else { + struct edid *edid; + + /* if we have an edid check it matches the connection */ + edid = intel_sdvo_get_edid(connector); + if (edid == NULL) + edid = intel_sdvo_get_analog_edid(connector); + if (edid != NULL) { + if (edid->input & DRM_EDID_INPUT_DIGITAL) + ret = connector_status_disconnected; + else + ret = connector_status_connected; + connector->display_info.raw_edid = NULL; + kfree(edid); + } else + ret = connector_status_connected; + } /* May update encoder flag for like clock for SDVO TV, etc.*/ if (ret == connector_status_connected) { @@ -1446,10 +1463,15 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) edid = intel_sdvo_get_analog_edid(connector); if (edid != NULL) { - if (edid->input & DRM_EDID_INPUT_DIGITAL) { + struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); + bool monitor_is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); + bool connector_is_digital = !!IS_TMDS(intel_sdvo_connector); + + if (connector_is_digital == monitor_is_digital) { drm_mode_connector_update_edid_property(connector, edid); drm_add_edid_modes(connector, edid); } + connector->display_info.raw_edid = NULL; kfree(edid); } -- cgit v1.2.3 From 537a20aba6127a048fbb15ce31cc824fb879a132 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 9 Feb 2011 15:02:34 +0100 Subject: staging: ft1000: Fix coding style in ft1000_control function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 41 +++++++-------------------- 1 file changed, 11 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 643a63794ade..bb28a2baf57e 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -65,45 +65,26 @@ static u8 tempbuffer[1600]; // Notes: // //--------------------------------------------------------------------------- -static int ft1000_control(struct ft1000_device *ft1000dev,unsigned int pipe, - u8 request, - u8 requesttype, - u16 value, - u16 index, - void *data, - u16 size, - int timeout) +static int ft1000_control(struct ft1000_device *ft1000dev, unsigned int pipe, + u8 request, u8 requesttype, u16 value, u16 index, + void *data, u16 size, int timeout) { u16 ret; - if (ft1000dev == NULL ) - { - DEBUG("NULL ft1000dev, failure\n"); - return -ENODEV; - } - else if ( ft1000dev->dev == NULL ) - { - DEBUG("NULL ft1000dev->dev, failure\n"); - return -ENODEV; - } + if ((ft1000dev == NULL) || (ft1000dev->dev == NULL)) { + DEBUG("ft1000dev or ft1000dev->dev == NULL, failure\n"); + return -ENODEV; + } - ret = usb_control_msg(ft1000dev->dev, - pipe, - request, - requesttype, - value, - index, - data, - size, - LARGE_TIMEOUT); + ret = usb_control_msg(ft1000dev->dev, pipe, request, requesttype, + value, index, data, size, LARGE_TIMEOUT); if (ret > 0) ret = 0; - return ret; - - + return ret; } + //--------------------------------------------------------------------------- // Function: ft1000_read_register // -- cgit v1.2.3 From dc080fdaca4c0fb379b62bffef2db5c74a883728 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 9 Feb 2011 15:02:35 +0100 Subject: staging: ft1000: Remove unused header ft1000_hw.h Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.h | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 drivers/staging/ft1000/ft1000-usb/ft1000_hw.h (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.h b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.h deleted file mode 100644 index ab9312f9f326..000000000000 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.h +++ /dev/null @@ -1,10 +0,0 @@ - -#ifndef _FT1000_HW_H_ -#define _FT1000_HW_H_ - -#include "ft1000_usb.h" - -extern u16 ft1000_read_register(struct usb_device *dev, u16 *Data, u8 nRegIndx); -extern u16 ft1000_write_register(struct usb_device *dev, u16 value, u8 nRegIndx); - -#endif -- cgit v1.2.3 From 4a526fca849f942426ed1017c9a8060a503c3883 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 9 Feb 2011 15:02:36 +0100 Subject: staging: ft1000: Fix return values type. Change return values type from u16 to int because all functions use ft1000_control function which return int. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 32 ++++++++++++------------- drivers/staging/ft1000/ft1000-usb/ft1000_proc.c | 2 +- drivers/staging/ft1000/ft1000-usb/ft1000_usb.h | 16 ++++++------- 3 files changed, 25 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index bb28a2baf57e..e9d79e89c121 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -101,9 +101,9 @@ static int ft1000_control(struct ft1000_device *ft1000dev, unsigned int pipe, // //--------------------------------------------------------------------------- -u16 ft1000_read_register(struct ft1000_device *ft1000dev, u16* Data, u16 nRegIndx) +int ft1000_read_register(struct ft1000_device *ft1000dev, u16* Data, u16 nRegIndx) { - u16 ret = STATUS_SUCCESS; + int ret = STATUS_SUCCESS; //DEBUG("ft1000_read_register: reg index is %d\n", nRegIndx); //DEBUG("ft1000_read_register: spin_lock locked\n"); @@ -140,9 +140,9 @@ u16 ft1000_read_register(struct ft1000_device *ft1000dev, u16* Data, u16 nRegInd // Notes: // //--------------------------------------------------------------------------- -u16 ft1000_write_register(struct ft1000_device *ft1000dev, u16 value, u16 nRegIndx) +int ft1000_write_register(struct ft1000_device *ft1000dev, u16 value, u16 nRegIndx) { - u16 ret = STATUS_SUCCESS; + int ret = STATUS_SUCCESS; //DEBUG("ft1000_write_register: value is: %d, reg index is: %d\n", value, nRegIndx); @@ -176,9 +176,9 @@ u16 ft1000_write_register(struct ft1000_device *ft1000dev, u16 value, u16 nRegIn // //--------------------------------------------------------------------------- -u16 ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u16 cnt) +int ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u16 cnt) { - u16 ret = STATUS_SUCCESS; + int ret = STATUS_SUCCESS; //DEBUG("ft1000_read_dpram32: indx: %d cnt: %d\n", indx, cnt); ret =ft1000_control(ft1000dev, @@ -215,9 +215,9 @@ u16 ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u // Notes: // //--------------------------------------------------------------------------- -u16 ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u16 cnt) +int ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u16 cnt) { - u16 ret = STATUS_SUCCESS; + int ret = STATUS_SUCCESS; //DEBUG("ft1000_write_dpram32: indx: %d buffer: %x cnt: %d\n", indx, buffer, cnt); if ( cnt % 4) @@ -252,9 +252,9 @@ u16 ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, // Notes: // //--------------------------------------------------------------------------- -u16 ft1000_read_dpram16(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u8 highlow) +int ft1000_read_dpram16(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u8 highlow) { - u16 ret = STATUS_SUCCESS; + int ret = STATUS_SUCCESS; //DEBUG("ft1000_read_dpram16: indx: %d hightlow: %d\n", indx, highlow); @@ -300,9 +300,9 @@ u16 ft1000_read_dpram16(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u // Notes: // //--------------------------------------------------------------------------- -u16 ft1000_write_dpram16(struct ft1000_device *ft1000dev, u16 indx, u16 value, u8 highlow) +int ft1000_write_dpram16(struct ft1000_device *ft1000dev, u16 indx, u16 value, u8 highlow) { - u16 ret = STATUS_SUCCESS; + int ret = STATUS_SUCCESS; @@ -345,11 +345,11 @@ u16 ft1000_write_dpram16(struct ft1000_device *ft1000dev, u16 indx, u16 value, u // Notes: // //--------------------------------------------------------------------------- -u16 fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer) +int fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer) { u8 buf[16]; u16 pos; - u16 ret = STATUS_SUCCESS; + int ret = STATUS_SUCCESS; //DEBUG("fix_ft1000_read_dpram32: indx: %d \n", indx); pos = (indx / 4)*4; @@ -394,7 +394,7 @@ u16 fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffe // Notes: // //--------------------------------------------------------------------------- -u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer) +int fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer) { u16 pos1; u16 pos2; @@ -402,7 +402,7 @@ u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buff u8 buf[32]; u8 resultbuffer[32]; u8 *pdata; - u16 ret = STATUS_SUCCESS; + int ret = STATUS_SUCCESS; //DEBUG("fix_ft1000_write_dpram32: Entered:\n"); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c index b87542abbe86..5ae396716136 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c @@ -51,7 +51,7 @@ #define FTNET_PROC init_net.proc_net -u16 ft1000_read_dpram16 (struct ft1000_device *ft1000dev, u16 indx, +int ft1000_read_dpram16 (struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u8 highlow); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index a143e9ca4f08..88183fe142a2 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -560,14 +560,14 @@ struct dpram_blk { u16 *pbuffer; } __attribute__ ((packed)); -u16 ft1000_read_register(struct ft1000_device *ft1000dev, u16* Data, u16 nRegIndx); -u16 ft1000_write_register(struct ft1000_device *ft1000dev, u16 value, u16 nRegIndx); -u16 ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u16 cnt); -u16 ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u16 cnt); -u16 ft1000_read_dpram16(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u8 highlow); -u16 ft1000_write_dpram16(struct ft1000_device *ft1000dev, u16 indx, u16 value, u8 highlow); -u16 fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer); -u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer); +int ft1000_read_register(struct ft1000_device *ft1000dev, u16* Data, u16 nRegIndx); +int ft1000_write_register(struct ft1000_device *ft1000dev, u16 value, u16 nRegIndx); +int ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u16 cnt); +int ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u16 cnt); +int ft1000_read_dpram16(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u8 highlow); +int ft1000_write_dpram16(struct ft1000_device *ft1000dev, u16 indx, u16 value, u8 highlow); +int fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer); +int fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer); extern void *pFileStart; extern size_t FileLength; -- cgit v1.2.3 From 31da7c09de2cdfcd5ad0c87b78b00637402545bd Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 9 Feb 2011 15:02:37 +0100 Subject: staging: ft1000: Fix coding style in ft1000_write/read_register functions. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 63 ++++++++++++--------------- 1 file changed, 28 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index e9d79e89c121..9b982658df4a 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -101,28 +101,22 @@ static int ft1000_control(struct ft1000_device *ft1000dev, unsigned int pipe, // //--------------------------------------------------------------------------- -int ft1000_read_register(struct ft1000_device *ft1000dev, u16* Data, u16 nRegIndx) +int ft1000_read_register(struct ft1000_device *ft1000dev, u16* Data, + u16 nRegIndx) { - int ret = STATUS_SUCCESS; - - //DEBUG("ft1000_read_register: reg index is %d\n", nRegIndx); - //DEBUG("ft1000_read_register: spin_lock locked\n"); - ret = ft1000_control(ft1000dev, - usb_rcvctrlpipe(ft1000dev->dev,0), - HARLEY_READ_REGISTER, //request --READ_REGISTER - HARLEY_READ_OPERATION, //requestType - 0, //value - nRegIndx, //index - Data, //data - 2, //data size - LARGE_TIMEOUT ); //timeout - - //DEBUG("ft1000_read_register: ret is %d \n", ret); - - //DEBUG("ft1000_read_register: data is %x \n", *Data); - - return ret; + int ret = STATUS_SUCCESS; + + ret = ft1000_control(ft1000dev, + usb_rcvctrlpipe(ft1000dev->dev, 0), + HARLEY_READ_REGISTER, + HARLEY_READ_OPERATION, + 0, + nRegIndx, + Data, + 2, + LARGE_TIMEOUT); + return ret; } //--------------------------------------------------------------------------- @@ -140,23 +134,22 @@ int ft1000_read_register(struct ft1000_device *ft1000dev, u16* Data, u16 nRegInd // Notes: // //--------------------------------------------------------------------------- -int ft1000_write_register(struct ft1000_device *ft1000dev, u16 value, u16 nRegIndx) +int ft1000_write_register(struct ft1000_device *ft1000dev, u16 value, + u16 nRegIndx) { - int ret = STATUS_SUCCESS; - - //DEBUG("ft1000_write_register: value is: %d, reg index is: %d\n", value, nRegIndx); - - ret = ft1000_control(ft1000dev, - usb_sndctrlpipe(ft1000dev->dev, 0), - HARLEY_WRITE_REGISTER, //request -- WRITE_REGISTER - HARLEY_WRITE_OPERATION, //requestType - value, - nRegIndx, - NULL, - 0, - LARGE_TIMEOUT ); + int ret = STATUS_SUCCESS; + + ret = ft1000_control(ft1000dev, + usb_sndctrlpipe(ft1000dev->dev, 0), + HARLEY_WRITE_REGISTER, + HARLEY_WRITE_OPERATION, + value, + nRegIndx, + NULL, + 0, + LARGE_TIMEOUT); - return ret; + return ret; } //--------------------------------------------------------------------------- -- cgit v1.2.3 From e3fc923d4d84d6327e92f7b4cc8f6906ebc2719f Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 9 Feb 2011 15:02:38 +0100 Subject: staging: ft1000: Fix coding style in ft1000_read/write_dpram32 functions. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 61 ++++++++++++--------------- 1 file changed, 28 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 9b982658df4a..be07b42431c5 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -169,27 +169,22 @@ int ft1000_write_register(struct ft1000_device *ft1000dev, u16 value, // //--------------------------------------------------------------------------- -int ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u16 cnt) +int ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, + u16 cnt) { - int ret = STATUS_SUCCESS; - - //DEBUG("ft1000_read_dpram32: indx: %d cnt: %d\n", indx, cnt); - ret =ft1000_control(ft1000dev, - usb_rcvctrlpipe(ft1000dev->dev,0), - HARLEY_READ_DPRAM_32, //request --READ_DPRAM_32 - HARLEY_READ_OPERATION, //requestType - 0, //value - indx, //index - buffer, //data - cnt, //data size - LARGE_TIMEOUT ); //timeout - - //DEBUG("ft1000_read_dpram32: ret is %d \n", ret); - - //DEBUG("ft1000_read_dpram32: ret=%d \n", ret); + int ret = STATUS_SUCCESS; - return ret; + ret = ft1000_control(ft1000dev, + usb_rcvctrlpipe(ft1000dev->dev, 0), + HARLEY_READ_DPRAM_32, + HARLEY_READ_OPERATION, + 0, + indx, + buffer, + cnt, + LARGE_TIMEOUT); + return ret; } //--------------------------------------------------------------------------- @@ -208,25 +203,25 @@ int ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u // Notes: // //--------------------------------------------------------------------------- -int ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u16 cnt) +int ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, + u16 cnt) { - int ret = STATUS_SUCCESS; + int ret = STATUS_SUCCESS; - //DEBUG("ft1000_write_dpram32: indx: %d buffer: %x cnt: %d\n", indx, buffer, cnt); - if ( cnt % 4) - cnt += cnt - (cnt % 4); + if (cnt % 4) + cnt += cnt - (cnt % 4); - ret = ft1000_control(ft1000dev, - usb_sndctrlpipe(ft1000dev->dev, 0), - HARLEY_WRITE_DPRAM_32, //request -- WRITE_DPRAM_32 - HARLEY_WRITE_OPERATION, //requestType - 0, //value - indx, //index - buffer, //buffer - cnt, //buffer size - LARGE_TIMEOUT ); + ret = ft1000_control(ft1000dev, + usb_sndctrlpipe(ft1000dev->dev, 0), + HARLEY_WRITE_DPRAM_32, + HARLEY_WRITE_OPERATION, + 0, + indx, + buffer, + cnt, + LARGE_TIMEOUT); - return ret; + return ret; } //--------------------------------------------------------------------------- -- cgit v1.2.3 From 460bd5ddabe5ff4474292864097a7b527cdd0e9c Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 9 Feb 2011 15:02:39 +0100 Subject: staging: ft1000: Fix coding style in ft1000_read/write_dpram16 functions. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 82 +++++++++++---------------- 1 file changed, 34 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index be07b42431c5..aa4ad7b36b3f 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -240,36 +240,28 @@ int ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, // Notes: // //--------------------------------------------------------------------------- -int ft1000_read_dpram16(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u8 highlow) +int ft1000_read_dpram16(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, + u8 highlow) { - int ret = STATUS_SUCCESS; - - //DEBUG("ft1000_read_dpram16: indx: %d hightlow: %d\n", indx, highlow); - - u8 request; - - if (highlow == 0 ) - request = HARLEY_READ_DPRAM_LOW; - else - request = HARLEY_READ_DPRAM_HIGH; - - ret = ft1000_control(ft1000dev, - usb_rcvctrlpipe(ft1000dev->dev,0), - request, //request --READ_DPRAM_H/L - HARLEY_READ_OPERATION, //requestType - 0, //value - indx, //index - buffer, //data - 2, //data size - LARGE_TIMEOUT ); //timeout - - //DEBUG("ft1000_read_dpram16: ret is %d \n", ret); - + int ret = STATUS_SUCCESS; + u8 request; - //DEBUG("ft1000_read_dpram16: data is %x \n", *buffer); + if (highlow == 0) + request = HARLEY_READ_DPRAM_LOW; + else + request = HARLEY_READ_DPRAM_HIGH; - return ret; + ret = ft1000_control(ft1000dev, + usb_rcvctrlpipe(ft1000dev->dev, 0), + request, + HARLEY_READ_OPERATION, + 0, + indx, + buffer, + 2, + LARGE_TIMEOUT); + return ret; } //--------------------------------------------------------------------------- @@ -290,31 +282,25 @@ int ft1000_read_dpram16(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u //--------------------------------------------------------------------------- int ft1000_write_dpram16(struct ft1000_device *ft1000dev, u16 indx, u16 value, u8 highlow) { - int ret = STATUS_SUCCESS; - - - - //DEBUG("ft1000_write_dpram16: indx: %d value: %d highlow: %d\n", indx, value, highlow); - - u8 request; - + int ret = STATUS_SUCCESS; + u8 request; - if ( highlow == 0 ) - request = HARLEY_WRITE_DPRAM_LOW; - else - request = HARLEY_WRITE_DPRAM_HIGH; + if (highlow == 0) + request = HARLEY_WRITE_DPRAM_LOW; + else + request = HARLEY_WRITE_DPRAM_HIGH; - ret = ft1000_control(ft1000dev, - usb_sndctrlpipe(ft1000dev->dev, 0), - request, //request -- WRITE_DPRAM_H/L - HARLEY_WRITE_OPERATION, //requestType - value, //value - indx, //index - NULL, //buffer - 0, //buffer size - LARGE_TIMEOUT ); + ret = ft1000_control(ft1000dev, + usb_sndctrlpipe(ft1000dev->dev, 0), + request, + HARLEY_WRITE_OPERATION, + value, + indx, + NULL, + 0, + LARGE_TIMEOUT); - return ret; + return ret; } //--------------------------------------------------------------------------- -- cgit v1.2.3 From 71e3335d5593b202ad266b828927efe1b88d88d2 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 9 Feb 2011 15:02:40 +0100 Subject: staging: ft1000: Fix coding style in fix_ft1000_read_dpram32 function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 47 ++++++++++++--------------- 1 file changed, 21 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index aa4ad7b36b3f..6195ee90b9e3 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -319,36 +319,31 @@ int ft1000_write_dpram16(struct ft1000_device *ft1000dev, u16 indx, u16 value, u // Notes: // //--------------------------------------------------------------------------- -int fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer) +int fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, + u8 *buffer) { - u8 buf[16]; - u16 pos; - int ret = STATUS_SUCCESS; - - //DEBUG("fix_ft1000_read_dpram32: indx: %d \n", indx); - pos = (indx / 4)*4; - ret = ft1000_read_dpram32(ft1000dev, pos, buf, 16); - if (ret == STATUS_SUCCESS) - { - pos = (indx % 4)*4; - *buffer++ = buf[pos++]; - *buffer++ = buf[pos++]; - *buffer++ = buf[pos++]; - *buffer++ = buf[pos++]; - } - else - { - DEBUG("fix_ft1000_read_dpram32: DPRAM32 Read failed\n"); - *buffer++ = 0; - *buffer++ = 0; - *buffer++ = 0; - *buffer++ = 0; + u8 buf[16]; + u16 pos; + int ret = STATUS_SUCCESS; - } + pos = (indx / 4) * 4; + ret = ft1000_read_dpram32(ft1000dev, pos, buf, 16); - //DEBUG("fix_ft1000_read_dpram32: data is %x \n", *buffer); - return ret; + if (ret == STATUS_SUCCESS) { + pos = (indx % 4) * 4; + *buffer++ = buf[pos++]; + *buffer++ = buf[pos++]; + *buffer++ = buf[pos++]; + *buffer++ = buf[pos++]; + } else { + DEBUG("fix_ft1000_read_dpram32: DPRAM32 Read failed\n"); + *buffer++ = 0; + *buffer++ = 0; + *buffer++ = 0; + *buffer++ = 0; + } + return ret; } -- cgit v1.2.3 From 8bfef502595acf6a8b6f8f77f0cf919f94021c08 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 9 Feb 2011 15:02:41 +0100 Subject: staging: ft1000: Fix coding style in fix_ft1000_write_dpram32 fucntion. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 104 ++++++++++++-------------- 1 file changed, 47 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 6195ee90b9e3..437aee3c2ba7 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -365,68 +365,58 @@ int fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, //--------------------------------------------------------------------------- int fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer) { - u16 pos1; - u16 pos2; - u16 i; - u8 buf[32]; - u8 resultbuffer[32]; - u8 *pdata; - int ret = STATUS_SUCCESS; - - //DEBUG("fix_ft1000_write_dpram32: Entered:\n"); - - pos1 = (indx / 4)*4; - pdata = buffer; - ret = ft1000_read_dpram32(ft1000dev, pos1, buf, 16); - if (ret == STATUS_SUCCESS) - { - pos2 = (indx % 4)*4; - buf[pos2++] = *buffer++; - buf[pos2++] = *buffer++; - buf[pos2++] = *buffer++; - buf[pos2++] = *buffer++; - ret = ft1000_write_dpram32(ft1000dev, pos1, buf, 16); - } - else - { - DEBUG("fix_ft1000_write_dpram32: DPRAM32 Read failed\n"); + u16 pos1; + u16 pos2; + u16 i; + u8 buf[32]; + u8 resultbuffer[32]; + u8 *pdata; + int ret = STATUS_SUCCESS; + + pos1 = (indx / 4) * 4; + pdata = buffer; + ret = ft1000_read_dpram32(ft1000dev, pos1, buf, 16); - return ret; - } - - ret = ft1000_read_dpram32(ft1000dev, pos1, (u8 *)&resultbuffer[0], 16); - if (ret == STATUS_SUCCESS) - { - buffer = pdata; - for (i=0; i<16; i++) - { - if (buf[i] != resultbuffer[i]){ + if (ret == STATUS_SUCCESS) { + pos2 = (indx % 4)*4; + buf[pos2++] = *buffer++; + buf[pos2++] = *buffer++; + buf[pos2++] = *buffer++; + buf[pos2++] = *buffer++; + ret = ft1000_write_dpram32(ft1000dev, pos1, buf, 16); + } else { + DEBUG("fix_ft1000_write_dpram32: DPRAM32 Read failed\n"); + return ret; + } - ret = STATUS_FAILURE; - } - } - } + ret = ft1000_read_dpram32(ft1000dev, pos1, (u8 *)&resultbuffer[0], 16); - if (ret == STATUS_FAILURE) - { - ret = ft1000_write_dpram32(ft1000dev, pos1, (u8 *)&tempbuffer[0], 16); - ret = ft1000_read_dpram32(ft1000dev, pos1, (u8 *)&resultbuffer[0], 16); - if (ret == STATUS_SUCCESS) - { - buffer = pdata; - for (i=0; i<16; i++) - { - if (tempbuffer[i] != resultbuffer[i]) - { - ret = STATUS_FAILURE; - DEBUG("fix_ft1000_write_dpram32 Failed to write\n"); - } - } - } - } + if (ret == STATUS_SUCCESS) { + buffer = pdata; + for (i = 0; i < 16; i++) { + if (buf[i] != resultbuffer[i]) + ret = STATUS_FAILURE; + } + } - return ret; + if (ret == STATUS_FAILURE) { + ret = ft1000_write_dpram32(ft1000dev, pos1, + (u8 *)&tempbuffer[0], 16); + ret = ft1000_read_dpram32(ft1000dev, pos1, + (u8 *)&resultbuffer[0], 16); + if (ret == STATUS_SUCCESS) { + buffer = pdata; + for (i = 0; i < 16; i++) { + if (tempbuffer[i] != resultbuffer[i]) { + ret = STATUS_FAILURE; + DEBUG("%s Failed to write\n", + __func__); + } + } + } + } + return ret; } -- cgit v1.2.3 From 677aaa430669861f39bd43c02bdbc2e8f7f7ad2c Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 9 Feb 2011 15:02:42 +0100 Subject: staging: ft1000: Fix coding style in card_reset_dsp function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 59 +++++++++++++++------------ 1 file changed, 33 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 437aee3c2ba7..e3b99347ff78 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -430,33 +430,40 @@ int fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buff // // Returns: None //----------------------------------------------------------------------- -static void card_reset_dsp (struct ft1000_device *ft1000dev, bool value) +static void card_reset_dsp(struct ft1000_device *ft1000dev, bool value) { - u16 status = STATUS_SUCCESS; - u16 tempword; - - status = ft1000_write_register (ft1000dev, HOST_INTF_BE, FT1000_REG_SUP_CTRL); - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_SUP_CTRL); - if (value) - { - DEBUG("Reset DSP\n"); - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_RESET); - tempword |= DSP_RESET_BIT; - status = ft1000_write_register(ft1000dev, tempword, FT1000_REG_RESET); - } - else - { - DEBUG("Activate DSP\n"); - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_RESET); - tempword |= DSP_ENCRYPTED; - tempword &= ~DSP_UNENCRYPTED; - status = ft1000_write_register(ft1000dev, tempword, FT1000_REG_RESET); - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_RESET); - tempword &= ~EFUSE_MEM_DISABLE; - tempword &= ~DSP_RESET_BIT; - status = ft1000_write_register(ft1000dev, tempword, FT1000_REG_RESET); - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_RESET); - } + u16 status = STATUS_SUCCESS; + u16 tempword; + + status = ft1000_write_register(ft1000dev, HOST_INTF_BE, + FT1000_REG_SUP_CTRL); + status = ft1000_read_register(ft1000dev, &tempword, + FT1000_REG_SUP_CTRL); + + if (value) { + DEBUG("Reset DSP\n"); + status = ft1000_read_register(ft1000dev, &tempword, + FT1000_REG_RESET); + tempword |= DSP_RESET_BIT; + status = ft1000_write_register(ft1000dev, tempword, + FT1000_REG_RESET); + } else { + DEBUG("Activate DSP\n"); + status = ft1000_read_register(ft1000dev, &tempword, + FT1000_REG_RESET); + tempword |= DSP_ENCRYPTED; + tempword &= ~DSP_UNENCRYPTED; + status = ft1000_write_register(ft1000dev, tempword, + FT1000_REG_RESET); + status = ft1000_read_register(ft1000dev, &tempword, + FT1000_REG_RESET); + tempword &= ~EFUSE_MEM_DISABLE; + tempword &= ~DSP_RESET_BIT; + status = ft1000_write_register(ft1000dev, tempword, + FT1000_REG_RESET); + status = ft1000_read_register(ft1000dev, &tempword, + FT1000_REG_RESET); + } } //--------------------------------------------------------------------------- -- cgit v1.2.3 From bcd2d92e62254320d012c8e879d651eeaa350661 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 8 Feb 2011 14:41:38 +0100 Subject: staging: ft1000: Remove unnecessary check in write_blk_fifo(). byte_length = word_length * 4; if (byte_length % 4) ... word_length * 4 is always aligned at 4 bytes. Remove pointless check. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_download.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 1797c4da91df..8e622425aa13 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -644,16 +644,9 @@ static u32 write_blk_fifo(struct ft1000_device *ft1000dev, u16 **pUsFile, { u32 Status = STATUS_SUCCESS; int byte_length; - long aligncnt; byte_length = word_length * 4; - if (byte_length % 4) - aligncnt = 4 - (byte_length % 4); - else - aligncnt = 0; - byte_length += aligncnt; - if (byte_length && ((byte_length % 64) == 0)) byte_length += 4; -- cgit v1.2.3 From f9a7e9b2f074218ef7e3afcdaa71f6804fd36c84 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 7 Feb 2011 11:05:46 +0100 Subject: Staging: IIO: TRIGGER: New sysfs based trigger This patch adds a new trigger that can be invoked by writing the sysfs file: trigger_now. This approach can be valuable during automated testing or in situations, where other trigger methods are not applicable. For example no RTC or spare GPIOs. Last but not least we can allow user space applications to produce triggers. IIO: TRIGGER: Apply review feedback by Greg Kroah-Hartman Changes since v1: Add sysfs documentation. Change license notice. Add module alias. Add more Kconfig help text Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- .../iio/Documentation/sysfs-bus-iio-trigger-sysfs | 11 +++ drivers/staging/iio/trigger/Kconfig | 10 ++ drivers/staging/iio/trigger/Makefile | 1 + drivers/staging/iio/trigger/iio-trig-sysfs.c | 108 +++++++++++++++++++++ 4 files changed, 130 insertions(+) create mode 100644 drivers/staging/iio/Documentation/sysfs-bus-iio-trigger-sysfs create mode 100644 drivers/staging/iio/trigger/iio-trig-sysfs.c (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-trigger-sysfs b/drivers/staging/iio/Documentation/sysfs-bus-iio-trigger-sysfs new file mode 100644 index 000000000000..5235e6c749ab --- /dev/null +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio-trigger-sysfs @@ -0,0 +1,11 @@ +What: /sys/bus/iio/devices/triggerX/trigger_now +KernelVersion: 2.6.38 +Contact: linux-iio@vger.kernel.org +Description: + This file is provided by the iio-trig-sysfs stand-alone trigger + driver. Writing this file with any value triggers an event + driven driver, associated with this trigger, to capture data + into an in kernel buffer. This approach can be valuable during + automated testing or in situations, where other trigger methods + are not applicable. For example no RTC or spare GPIOs. + X is the IIO index of the trigger. diff --git a/drivers/staging/iio/trigger/Kconfig b/drivers/staging/iio/trigger/Kconfig index d842a584a3af..3a82013e2b8b 100644 --- a/drivers/staging/iio/trigger/Kconfig +++ b/drivers/staging/iio/trigger/Kconfig @@ -18,4 +18,14 @@ config IIO_GPIO_TRIGGER help Provides support for using GPIO pins as IIO triggers. +config IIO_SYSFS_TRIGGER + tristate "SYSFS trigger" + depends on SYSFS + help + Provides support for using SYSFS entry as IIO triggers. + If unsure, say N (but it's safe to say "Y"). + + To compile this driver as a module, choose M here: the + module will be called iio-trig-sysfs. + endif # IIO_TRIGGER diff --git a/drivers/staging/iio/trigger/Makefile b/drivers/staging/iio/trigger/Makefile index 10aeca5e347a..504b9c07970c 100644 --- a/drivers/staging/iio/trigger/Makefile +++ b/drivers/staging/iio/trigger/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_IIO_PERIODIC_RTC_TRIGGER) += iio-trig-periodic-rtc.o obj-$(CONFIG_IIO_GPIO_TRIGGER) += iio-trig-gpio.o +obj-$(CONFIG_IIO_SYSFS_TRIGGER) += iio-trig-sysfs.o diff --git a/drivers/staging/iio/trigger/iio-trig-sysfs.c b/drivers/staging/iio/trigger/iio-trig-sysfs.c new file mode 100644 index 000000000000..127a2a33e4db --- /dev/null +++ b/drivers/staging/iio/trigger/iio-trig-sysfs.c @@ -0,0 +1,108 @@ +/* + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + * + */ + +#include +#include +#include +#include + +#include "../iio.h" +#include "../trigger.h" + +static ssize_t iio_sysfs_trigger_poll(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct iio_trigger *trig = dev_get_drvdata(dev); + iio_trigger_poll(trig, 0); + + return count; +} + +static DEVICE_ATTR(trigger_now, S_IWUSR, NULL, iio_sysfs_trigger_poll); +static IIO_TRIGGER_NAME_ATTR; + +static struct attribute *iio_sysfs_trigger_attrs[] = { + &dev_attr_trigger_now.attr, + &dev_attr_name.attr, + NULL, +}; + +static const struct attribute_group iio_sysfs_trigger_attr_group = { + .attrs = iio_sysfs_trigger_attrs, +}; + +static int __devinit iio_sysfs_trigger_probe(struct platform_device *pdev) +{ + struct iio_trigger *trig; + int ret; + + trig = iio_allocate_trigger(); + if (!trig) { + ret = -ENOMEM; + goto out1; + } + + trig->control_attrs = &iio_sysfs_trigger_attr_group; + trig->owner = THIS_MODULE; + trig->name = kasprintf(GFP_KERNEL, "sysfstrig%d", pdev->id); + if (trig->name == NULL) { + ret = -ENOMEM; + goto out2; + } + + ret = iio_trigger_register(trig); + if (ret) + goto out3; + + platform_set_drvdata(pdev, trig); + + return 0; +out3: + kfree(trig->name); +out2: + iio_put_trigger(trig); +out1: + + return ret; +} + +static int __devexit iio_sysfs_trigger_remove(struct platform_device *pdev) +{ + struct iio_trigger *trig = platform_get_drvdata(pdev); + + iio_trigger_unregister(trig); + kfree(trig->name); + iio_put_trigger(trig); + + return 0; +} + +static struct platform_driver iio_sysfs_trigger_driver = { + .driver = { + .name = "iio_sysfs_trigger", + .owner = THIS_MODULE, + }, + .probe = iio_sysfs_trigger_probe, + .remove = __devexit_p(iio_sysfs_trigger_remove), +}; + +static int __init iio_sysfs_trig_init(void) +{ + return platform_driver_register(&iio_sysfs_trigger_driver); +} +module_init(iio_sysfs_trig_init); + +static void __exit iio_sysfs_trig_exit(void) +{ + platform_driver_unregister(&iio_sysfs_trigger_driver); +} +module_exit(iio_sysfs_trig_exit); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Sysfs based trigger for the iio subsystem"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:iio-trig-sysfs"); -- cgit v1.2.3 From ea707584bac187c9c6c64c4eacd1c09bcc08f37b Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Wed, 9 Feb 2011 11:03:29 +0100 Subject: Staging: IIO: DDS: AD9832 / AD9835 driver This is a complete rewrite of the AD9832/35 driver. Purpose was to move this driver to the recently created API for such devices. Changes since V1: IIO: DDS: AD9832 / AD9835 driver: Apply review feedback Save a few bytes, use union for data allocated for spi buffers. Remove use of device IDs. Fix comments. Make master clock mclk always type unsigned long. Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dds/Kconfig | 5 +- drivers/staging/iio/dds/ad9832.c | 488 ++++++++++++++++++++++++--------------- drivers/staging/iio/dds/ad9832.h | 128 ++++++++++ 3 files changed, 436 insertions(+), 185 deletions(-) create mode 100644 drivers/staging/iio/dds/ad9832.h (limited to 'drivers') diff --git a/drivers/staging/iio/dds/Kconfig b/drivers/staging/iio/dds/Kconfig index a047da62daf0..06b6f3a8e420 100644 --- a/drivers/staging/iio/dds/Kconfig +++ b/drivers/staging/iio/dds/Kconfig @@ -15,7 +15,10 @@ config AD9832 depends on SPI help Say yes here to build support for Analog Devices DDS chip - ad9832 and ad9835, provides direct access via sysfs. + AD9832 and AD9835, provides direct access via sysfs. + + To compile this driver as a module, choose M here: the + module will be called ad9832. config AD9834 tristate "Analog Devices ad9833/4/ driver" diff --git a/drivers/staging/iio/dds/ad9832.c b/drivers/staging/iio/dds/ad9832.c index e911893b3db0..3e8491f60cfe 100644 --- a/drivers/staging/iio/dds/ad9832.c +++ b/drivers/staging/iio/dds/ad9832.c @@ -1,228 +1,336 @@ /* - * Driver for ADI Direct Digital Synthesis ad9832 + * AD9832 SPI DDS driver * - * Copyright (c) 2010 Analog Devices Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. + * Copyright 2011 Analog Devices Inc. * + * Licensed under the GPL-2. */ -#include -#include + #include -#include +#include #include #include +#include +#include +#include +#include #include "../iio.h" #include "../sysfs.h" +#include "dds.h" -#define DRV_NAME "ad9832" - -#define value_mask (u16)0xf000 -#define cmd_shift 12 -#define add_shift 8 -#define AD9832_SYNC (1 << 13) -#define AD9832_SELSRC (1 << 12) -#define AD9832_SLEEP (1 << 13) -#define AD9832_RESET (1 << 12) -#define AD9832_CLR (1 << 11) - -#define ADD_FREQ0LL 0x0 -#define ADD_FREQ0HL 0x1 -#define ADD_FREQ0LM 0x2 -#define ADD_FREQ0HM 0x3 -#define ADD_FREQ1LL 0x4 -#define ADD_FREQ1HL 0x5 -#define ADD_FREQ1LM 0x6 -#define ADD_FREQ1HM 0x7 -#define ADD_PHASE0L 0x8 -#define ADD_PHASE0H 0x9 -#define ADD_PHASE1L 0xa -#define ADD_PHASE1H 0xb -#define ADD_PHASE2L 0xc -#define ADD_PHASE2H 0xd -#define ADD_PHASE3L 0xe -#define ADD_PHASE3H 0xf - -#define CMD_PHA8BITSW 0x1 -#define CMD_PHA16BITSW 0x0 -#define CMD_FRE8BITSW 0x3 -#define CMD_FRE16BITSW 0x2 -#define CMD_SELBITSCTL 0x6 - -struct ad9832_setting { - u16 freq0[4]; - u16 freq1[4]; - u16 phase0[2]; - u16 phase1[2]; - u16 phase2[2]; - u16 phase3[2]; -}; +#include "ad9832.h" -struct ad9832_state { - struct mutex lock; - struct iio_dev *idev; - struct spi_device *sdev; -}; - -static ssize_t ad9832_set_parameter(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) +static unsigned long ad9832_calc_freqreg(unsigned long mclk, unsigned long fout) { - struct spi_message msg; - struct spi_transfer xfer; - int ret; - struct ad9832_setting config; - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad9832_state *st = idev->dev_data; - - config.freq0[0] = (CMD_FRE8BITSW << add_shift | ADD_FREQ0LL << add_shift | buf[0]); - config.freq0[1] = (CMD_FRE16BITSW << add_shift | ADD_FREQ0HL << add_shift | buf[1]); - config.freq0[2] = (CMD_FRE8BITSW << add_shift | ADD_FREQ0LM << add_shift | buf[2]); - config.freq0[3] = (CMD_FRE16BITSW << add_shift | ADD_FREQ0HM << add_shift | buf[3]); - config.freq1[0] = (CMD_FRE8BITSW << add_shift | ADD_FREQ1LL << add_shift | buf[4]); - config.freq1[1] = (CMD_FRE16BITSW << add_shift | ADD_FREQ1HL << add_shift | buf[5]); - config.freq1[2] = (CMD_FRE8BITSW << add_shift | ADD_FREQ1LM << add_shift | buf[6]); - config.freq1[3] = (CMD_FRE16BITSW << add_shift | ADD_FREQ1HM << add_shift | buf[7]); - - config.phase0[0] = (CMD_PHA8BITSW << add_shift | ADD_PHASE0L << add_shift | buf[9]); - config.phase0[1] = (CMD_PHA16BITSW << add_shift | ADD_PHASE0H << add_shift | buf[10]); - config.phase1[0] = (CMD_PHA8BITSW << add_shift | ADD_PHASE1L << add_shift | buf[11]); - config.phase1[1] = (CMD_PHA16BITSW << add_shift | ADD_PHASE1H << add_shift | buf[12]); - config.phase2[0] = (CMD_PHA8BITSW << add_shift | ADD_PHASE2L << add_shift | buf[13]); - config.phase2[1] = (CMD_PHA16BITSW << add_shift | ADD_PHASE2H << add_shift | buf[14]); - config.phase3[0] = (CMD_PHA8BITSW << add_shift | ADD_PHASE3L << add_shift | buf[15]); - config.phase3[1] = (CMD_PHA16BITSW << add_shift | ADD_PHASE3H << add_shift | buf[16]); - - xfer.len = 2 * len; - xfer.tx_buf = &config; - mutex_lock(&st->lock); - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; -error_ret: - mutex_unlock(&st->lock); + unsigned long long freqreg = (u64) fout * + (u64) ((u64) 1L << AD9832_FREQ_BITS); + do_div(freqreg, mclk); + return freqreg; +} - return ret ? ret : len; +static int ad9832_write_frequency(struct ad9832_state *st, + unsigned addr, unsigned long fout) +{ + unsigned long regval; + + if (fout > (st->mclk / 2)) + return -EINVAL; + + regval = ad9832_calc_freqreg(st->mclk, fout); + + st->freq_data[0] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) | + (addr << ADD_SHIFT) | + ((regval >> 24) & 0xFF)); + st->freq_data[1] = cpu_to_be16((AD9832_CMD_FRE16BITSW << CMD_SHIFT) | + ((addr - 1) << ADD_SHIFT) | + ((regval >> 16) & 0xFF)); + st->freq_data[2] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) | + ((addr - 2) << ADD_SHIFT) | + ((regval >> 8) & 0xFF)); + st->freq_data[3] = cpu_to_be16((AD9832_CMD_FRE16BITSW << CMD_SHIFT) | + ((addr - 3) << ADD_SHIFT) | + ((regval >> 0) & 0xFF)); + + return spi_sync(st->spi, &st->freq_msg);; } -static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9832_set_parameter, 0); +static int ad9832_write_phase(struct ad9832_state *st, + unsigned long addr, unsigned long phase) +{ + if (phase > (1 << AD9832_PHASE_BITS)) + return -EINVAL; -static struct attribute *ad9832_attributes[] = { - &iio_dev_attr_dds.dev_attr.attr, - NULL, -}; + st->phase_data[0] = cpu_to_be16((AD9832_CMD_PHA8BITSW << CMD_SHIFT) | + (addr << ADD_SHIFT) | + ((phase >> 8) & 0xFF)); + st->phase_data[1] = cpu_to_be16((AD9832_CMD_PHA16BITSW << CMD_SHIFT) | + ((addr - 1) << ADD_SHIFT) | + (phase & 0xFF)); -static const struct attribute_group ad9832_attribute_group = { - .name = DRV_NAME, - .attrs = ad9832_attributes, -}; + return spi_sync(st->spi, &st->phase_msg); +} -static void ad9832_init(struct ad9832_state *st) +static ssize_t ad9832_write(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) { - struct spi_message msg; - struct spi_transfer xfer; + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad9832_state *st = dev_info->dev_data; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret; - u16 config = 0; - - config = 0x3 << 14 | AD9832_SLEEP | AD9832_RESET | AD9832_CLR; + long val; - mutex_lock(&st->lock); - - xfer.len = 2; - xfer.tx_buf = &config; - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); + ret = strict_strtoul(buf, 10, &val); if (ret) goto error_ret; - config = 0x2 << 14 | AD9832_SYNC | AD9832_SELSRC; - xfer.len = 2; - xfer.tx_buf = &config; + mutex_lock(&dev_info->mlock); + switch (this_attr->address) { + case AD9832_FREQ0HM: + case AD9832_FREQ1HM: + ret = ad9832_write_frequency(st, this_attr->address, val); + break; + case AD9832_PHASE0H: + case AD9832_PHASE1H: + case AD9832_PHASE2H: + case AD9832_PHASE3H: + ret = ad9832_write_phase(st, this_attr->address, val); + break; + case AD9832_PINCTRL_EN: + if (val) + st->ctrl_ss &= ~AD9832_SELSRC; + else + st->ctrl_ss |= AD9832_SELSRC; + st->data = cpu_to_be16((AD9832_CMD_SYNCSELSRC << CMD_SHIFT) | + st->ctrl_ss); + ret = spi_sync(st->spi, &st->msg); + break; + case AD9832_FREQ_SYM: + if (val == 1) + st->ctrl_fp |= AD9832_FREQ; + else if (val == 0) + st->ctrl_fp &= ~AD9832_FREQ; + else { + ret = -EINVAL; + break; + } + st->data = cpu_to_be16((AD9832_CMD_FPSELECT << CMD_SHIFT) | + st->ctrl_fp); + ret = spi_sync(st->spi, &st->msg); + break; + case AD9832_PHASE_SYM: + if (val < 0 || val > 3) { + ret = -EINVAL; + break; + } + + st->ctrl_fp &= ~AD9832_PHASE(3); + st->ctrl_fp |= AD9832_PHASE(val); + + st->data = cpu_to_be16((AD9832_CMD_FPSELECT << CMD_SHIFT) | + st->ctrl_fp); + ret = spi_sync(st->spi, &st->msg); + break; + case AD9832_OUTPUT_EN: + if (val) + st->ctrl_src &= ~(AD9832_RESET | AD9832_SLEEP | + AD9832_CLR); + else + st->ctrl_src |= AD9832_RESET; + + st->data = cpu_to_be16((AD9832_CMD_SLEEPRESCLR << CMD_SHIFT) | + st->ctrl_src); + ret = spi_sync(st->spi, &st->msg); + break; + default: + ret = -ENODEV; + } + mutex_unlock(&dev_info->mlock); - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; +error_ret: + return ret ? ret : len; +} - config = CMD_SELBITSCTL << cmd_shift; - xfer.len = 2; - xfer.tx_buf = &config; +static ssize_t ad9832_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad9832_state *st = iio_dev_get_devdata(dev_info); - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; + return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name); +} +static IIO_DEVICE_ATTR(name, S_IRUGO, ad9832_show_name, NULL, 0); - config = 0x3 << 14; +/** + * see dds.h for further information + */ - xfer.len = 2; - xfer.tx_buf = &config; +static IIO_DEV_ATTR_FREQ(0, 0, S_IWUSR, NULL, ad9832_write, AD9832_FREQ0HM); +static IIO_DEV_ATTR_FREQ(0, 1, S_IWUSR, NULL, ad9832_write, AD9832_FREQ1HM); +static IIO_DEV_ATTR_FREQSYMBOL(0, S_IWUSR, NULL, ad9832_write, AD9832_FREQ_SYM); +static IIO_CONST_ATTR_FREQ_SCALE(0, "1"); /* 1Hz */ - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; -error_ret: - mutex_unlock(&st->lock); +static IIO_DEV_ATTR_PHASE(0, 0, S_IWUSR, NULL, ad9832_write, AD9832_PHASE0H); +static IIO_DEV_ATTR_PHASE(0, 1, S_IWUSR, NULL, ad9832_write, AD9832_PHASE1H); +static IIO_DEV_ATTR_PHASE(0, 2, S_IWUSR, NULL, ad9832_write, AD9832_PHASE2H); +static IIO_DEV_ATTR_PHASE(0, 3, S_IWUSR, NULL, ad9832_write, AD9832_PHASE3H); +static IIO_DEV_ATTR_PHASESYMBOL(0, S_IWUSR, NULL, + ad9832_write, AD9832_PHASE_SYM); +static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/ +static IIO_DEV_ATTR_PINCONTROL_EN(0, S_IWUSR, NULL, + ad9832_write, AD9832_PINCTRL_EN); +static IIO_DEV_ATTR_OUT_ENABLE(0, S_IWUSR, NULL, + ad9832_write, AD9832_OUTPUT_EN); +static struct attribute *ad9832_attributes[] = { + &iio_dev_attr_dds0_freq0.dev_attr.attr, + &iio_dev_attr_dds0_freq1.dev_attr.attr, + &iio_const_attr_dds0_freq_scale.dev_attr.attr, + &iio_dev_attr_dds0_phase0.dev_attr.attr, + &iio_dev_attr_dds0_phase1.dev_attr.attr, + &iio_dev_attr_dds0_phase2.dev_attr.attr, + &iio_dev_attr_dds0_phase3.dev_attr.attr, + &iio_const_attr_dds0_phase_scale.dev_attr.attr, + &iio_dev_attr_dds0_pincontrol_en.dev_attr.attr, + &iio_dev_attr_dds0_freqsymbol.dev_attr.attr, + &iio_dev_attr_dds0_phasesymbol.dev_attr.attr, + &iio_dev_attr_dds0_out_enable.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; -} +static const struct attribute_group ad9832_attribute_group = { + .attrs = ad9832_attributes, +}; static int __devinit ad9832_probe(struct spi_device *spi) { + struct ad9832_platform_data *pdata = spi->dev.platform_data; struct ad9832_state *st; - int ret = 0; + int ret; + + if (!pdata) { + dev_dbg(&spi->dev, "no platform data?\n"); + return -ENODEV; + } st = kzalloc(sizeof(*st), GFP_KERNEL); if (st == NULL) { ret = -ENOMEM; goto error_ret; } - spi_set_drvdata(spi, st); - mutex_init(&st->lock); - st->sdev = spi; + st->reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + } + + st->mclk = pdata->mclk; + + spi_set_drvdata(spi, st); + st->spi = spi; - st->idev = iio_allocate_device(); - if (st->idev == NULL) { + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { ret = -ENOMEM; - goto error_free_st; + goto error_disable_reg; } - st->idev->dev.parent = &spi->dev; - st->idev->num_interrupt_lines = 0; - st->idev->event_attrs = NULL; - st->idev->attrs = &ad9832_attribute_group; - st->idev->dev_data = (void *)(st); - st->idev->driver_module = THIS_MODULE; - st->idev->modes = INDIO_DIRECT_MODE; + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->attrs = &ad9832_attribute_group; + st->indio_dev->dev_data = (void *) st; + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + /* Setup default messages */ + + st->xfer.tx_buf = &st->data; + st->xfer.len = 2; + + spi_message_init(&st->msg); + spi_message_add_tail(&st->xfer, &st->msg); + + st->freq_xfer[0].tx_buf = &st->freq_data[0]; + st->freq_xfer[0].len = 2; + st->freq_xfer[0].cs_change = 1; + st->freq_xfer[1].tx_buf = &st->freq_data[1]; + st->freq_xfer[1].len = 2; + st->freq_xfer[1].cs_change = 1; + st->freq_xfer[2].tx_buf = &st->freq_data[2]; + st->freq_xfer[2].len = 2; + st->freq_xfer[2].cs_change = 1; + st->freq_xfer[3].tx_buf = &st->freq_data[3]; + st->freq_xfer[3].len = 2; + + spi_message_init(&st->freq_msg); + spi_message_add_tail(&st->freq_xfer[0], &st->freq_msg); + spi_message_add_tail(&st->freq_xfer[1], &st->freq_msg); + spi_message_add_tail(&st->freq_xfer[2], &st->freq_msg); + spi_message_add_tail(&st->freq_xfer[3], &st->freq_msg); + + st->phase_xfer[0].tx_buf = &st->phase_data[0]; + st->phase_xfer[0].len = 2; + st->phase_xfer[0].cs_change = 1; + st->phase_xfer[1].tx_buf = &st->phase_data[1]; + st->phase_xfer[1].len = 2; + + spi_message_init(&st->phase_msg); + spi_message_add_tail(&st->phase_xfer[0], &st->phase_msg); + spi_message_add_tail(&st->phase_xfer[1], &st->phase_msg); + + st->ctrl_src = AD9832_SLEEP | AD9832_RESET | AD9832_CLR; + st->data = cpu_to_be16((AD9832_CMD_SLEEPRESCLR << CMD_SHIFT) | + st->ctrl_src); + ret = spi_sync(st->spi, &st->msg); + if (ret) { + dev_err(&spi->dev, "device init failed\n"); + goto error_free_device; + } + + ret = ad9832_write_frequency(st, AD9832_FREQ0HM, pdata->freq0); + if (ret) + goto error_free_device; + + ret = ad9832_write_frequency(st, AD9832_FREQ1HM, pdata->freq1); + if (ret) + goto error_free_device; + + ret = ad9832_write_phase(st, AD9832_PHASE0H, pdata->phase0); + if (ret) + goto error_free_device; + + ret = ad9832_write_phase(st, AD9832_PHASE1H, pdata->phase1); + if (ret) + goto error_free_device; - ret = iio_device_register(st->idev); + ret = ad9832_write_phase(st, AD9832_PHASE2H, pdata->phase2); if (ret) - goto error_free_dev; - spi->max_speed_hz = 2000000; - spi->mode = SPI_MODE_3; - spi->bits_per_word = 16; - spi_setup(spi); - ad9832_init(st); + goto error_free_device; + + ret = ad9832_write_phase(st, AD9832_PHASE3H, pdata->phase3); + if (ret) + goto error_free_device; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_free_device; + return 0; -error_free_dev: - iio_free_device(st->idev); -error_free_st: +error_free_device: + iio_free_device(st->indio_dev); +error_disable_reg: + if (!IS_ERR(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR(st->reg)) + regulator_put(st->reg); kfree(st); error_ret: return ret; @@ -232,33 +340,45 @@ static int __devexit ad9832_remove(struct spi_device *spi) { struct ad9832_state *st = spi_get_drvdata(spi); - iio_device_unregister(st->idev); + iio_device_unregister(st->indio_dev); + if (!IS_ERR(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); + } kfree(st); - return 0; } +static const struct spi_device_id ad9832_id[] = { + {"ad9832", 0}, + {"ad9835", 0}, + {} +}; + static struct spi_driver ad9832_driver = { .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, + .name = "ad9832", + .bus = &spi_bus_type, + .owner = THIS_MODULE, }, - .probe = ad9832_probe, - .remove = __devexit_p(ad9832_remove), + .probe = ad9832_probe, + .remove = __devexit_p(ad9832_remove), + .id_table = ad9832_id, }; -static __init int ad9832_spi_init(void) +static int __init ad9832_init(void) { return spi_register_driver(&ad9832_driver); } -module_init(ad9832_spi_init); +module_init(ad9832_init); -static __exit void ad9832_spi_exit(void) +static void __exit ad9832_exit(void) { spi_unregister_driver(&ad9832_driver); } -module_exit(ad9832_spi_exit); +module_exit(ad9832_exit); -MODULE_AUTHOR("Cliff Cai"); -MODULE_DESCRIPTION("Analog Devices ad9832 driver"); +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD9832/AD9835 DDS"); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("spi:ad9832"); diff --git a/drivers/staging/iio/dds/ad9832.h b/drivers/staging/iio/dds/ad9832.h new file mode 100644 index 000000000000..5d474543dfce --- /dev/null +++ b/drivers/staging/iio/dds/ad9832.h @@ -0,0 +1,128 @@ +/* + * AD9832 SPI DDS driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ +#ifndef IIO_DDS_AD9832_H_ +#define IIO_DDS_AD9832_H_ + +/* Registers */ + +#define AD9832_FREQ0LL 0x0 +#define AD9832_FREQ0HL 0x1 +#define AD9832_FREQ0LM 0x2 +#define AD9832_FREQ0HM 0x3 +#define AD9832_FREQ1LL 0x4 +#define AD9832_FREQ1HL 0x5 +#define AD9832_FREQ1LM 0x6 +#define AD9832_FREQ1HM 0x7 +#define AD9832_PHASE0L 0x8 +#define AD9832_PHASE0H 0x9 +#define AD9832_PHASE1L 0xA +#define AD9832_PHASE1H 0xB +#define AD9832_PHASE2L 0xC +#define AD9832_PHASE2H 0xD +#define AD9832_PHASE3L 0xE +#define AD9832_PHASE3H 0xF + +#define AD9832_PHASE_SYM 0x10 +#define AD9832_FREQ_SYM 0x11 +#define AD9832_PINCTRL_EN 0x12 +#define AD9832_OUTPUT_EN 0x13 + +/* Command Control Bits */ + +#define AD9832_CMD_PHA8BITSW 0x1 +#define AD9832_CMD_PHA16BITSW 0x0 +#define AD9832_CMD_FRE8BITSW 0x3 +#define AD9832_CMD_FRE16BITSW 0x2 +#define AD9832_CMD_FPSELECT 0x6 +#define AD9832_CMD_SYNCSELSRC 0x8 +#define AD9832_CMD_SLEEPRESCLR 0xC + +#define AD9832_FREQ (1 << 11) +#define AD9832_PHASE(x) (((x) & 3) << 9) +#define AD9832_SYNC (1 << 13) +#define AD9832_SELSRC (1 << 12) +#define AD9832_SLEEP (1 << 13) +#define AD9832_RESET (1 << 12) +#define AD9832_CLR (1 << 11) +#define CMD_SHIFT 12 +#define ADD_SHIFT 8 +#define AD9832_FREQ_BITS 32 +#define AD9832_PHASE_BITS 12 +#define RES_MASK(bits) ((1 << (bits)) - 1) + +/** + * struct ad9832_state - driver instance specific data + * @indio_dev: the industrial I/O device + * @spi: spi_device + * @reg: supply regulator + * @mclk: external master clock + * @ctrl_fp: cached frequency/phase control word + * @ctrl_ss: cached sync/selsrc control word + * @ctrl_src: cached sleep/reset/clr word + * @xfer: default spi transfer + * @msg: default spi message + * @freq_xfer: tuning word spi transfer + * @freq_msg: tuning word spi message + * @phase_xfer: tuning word spi transfer + * @phase_msg: tuning word spi message + * @data: spi transmit buffer + * @phase_data: tuning word spi transmit buffer + * @freq_data: tuning word spi transmit buffer + */ + +struct ad9832_state { + struct iio_dev *indio_dev; + struct spi_device *spi; + struct regulator *reg; + unsigned long mclk; + unsigned short ctrl_fp; + unsigned short ctrl_ss; + unsigned short ctrl_src; + struct spi_transfer xfer; + struct spi_message msg; + struct spi_transfer freq_xfer[4]; + struct spi_message freq_msg; + struct spi_transfer phase_xfer[2]; + struct spi_message phase_msg; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + union { + unsigned short freq_data[4]____cacheline_aligned; + unsigned short phase_data[2]; + unsigned short data; + }; +}; + +/* + * TODO: struct ad9832_platform_data needs to go into include/linux/iio + */ + +/** + * struct ad9832_platform_data - platform specific information + * @mclk: master clock in Hz + * @freq0: power up freq0 tuning word in Hz + * @freq1: power up freq1 tuning word in Hz + * @phase0: power up phase0 value [0..4095] correlates with 0..2PI + * @phase1: power up phase1 value [0..4095] correlates with 0..2PI + * @phase2: power up phase2 value [0..4095] correlates with 0..2PI + * @phase3: power up phase3 value [0..4095] correlates with 0..2PI + */ + +struct ad9832_platform_data { + unsigned long mclk; + unsigned long freq0; + unsigned long freq1; + unsigned short phase0; + unsigned short phase1; + unsigned short phase2; + unsigned short phase3; +}; + +#endif /* IIO_DDS_AD9832_H_ */ -- cgit v1.2.3 From daa6afa6d920a389015bb8f1ea519cef0636f528 Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Sun, 6 Feb 2011 19:25:08 -0800 Subject: staging: zcache: in-kernel tmem code [PATCH V2 1/3] drivers/staging: zcache: in-kernel tmem code Transcendent memory ("tmem") is a clean API/ABI that provides for an efficient address translation and a set of highly concurrent access methods to copy data between a page-oriented data source (e.g. cleancache or frontswap) and a page-addressable memory ("PAM") data store. Of critical importance, the PAM data store is of unknown (and possibly varying) size so any individual access may succeed or fail as defined by the API/ABI. Tmem exports a basic set of access methods (e.g. put, get, flush, flush object, new pool, and destroy pool) which are normally called from a "host" (e.g. zcache). To be functional, two sets of "ops" must be registered by the host, one to provide "host services" (memory allocation) and one to provide page-addressable memory ("PAM") hooks. Tmem supports one or more "clients", each which can provide a set of "pools" to partition pages. Each pool contains a set of "objects"; each object holds pointers to some number of PAM page descriptors ("pampd"), indexed by an "index" number. This triple is sometimes referred to as a "handle". Tmem's primary function is to essentially provide address translation of handles into pampds and move data appropriately. As an example, for cleancache, a pool maps to a filesystem, an object maps to a file, and the index is the page offset into the file. And in this patch, zcache is the host and each PAM descriptor points to a compressed page of data. Tmem supports two kinds of pages: "ephemeral" and "persistent". Ephemeral pages may be asynchronously reclaimed "bottoms up" so the data structures and concurrency model must allow for this. For example, each pampd must retain sufficient information to invalidate tmem's handle-to-pampd translation. its containing object so that, on reclaim, all tmem data structures can be made consistent. Signed-off-by: Dan Magenheimer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/tmem.c | 710 ++++++++++++++++++++++++++++++++++++++++++ drivers/staging/zcache/tmem.h | 195 ++++++++++++ 2 files changed, 905 insertions(+) create mode 100644 drivers/staging/zcache/tmem.c create mode 100644 drivers/staging/zcache/tmem.h (limited to 'drivers') diff --git a/drivers/staging/zcache/tmem.c b/drivers/staging/zcache/tmem.c new file mode 100644 index 000000000000..e954d405b138 --- /dev/null +++ b/drivers/staging/zcache/tmem.c @@ -0,0 +1,710 @@ +/* + * In-kernel transcendent memory (generic implementation) + * + * Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp. + * + * The primary purpose of Transcedent Memory ("tmem") is to map object-oriented + * "handles" (triples containing a pool id, and object id, and an index), to + * pages in a page-accessible memory (PAM). Tmem references the PAM pages via + * an abstract "pampd" (PAM page-descriptor), which can be operated on by a + * set of functions (pamops). Each pampd contains some representation of + * PAGE_SIZE bytes worth of data. Tmem must support potentially millions of + * pages and must be able to insert, find, and delete these pages at a + * potential frequency of thousands per second concurrently across many CPUs, + * (and, if used with KVM, across many vcpus across many guests). + * Tmem is tracked with a hierarchy of data structures, organized by + * the elements in a handle-tuple: pool_id, object_id, and page index. + * One or more "clients" (e.g. guests) each provide one or more tmem_pools. + * Each pool, contains a hash table of rb_trees of tmem_objs. Each + * tmem_obj contains a radix-tree-like tree of pointers, with intermediate + * nodes called tmem_objnodes. Each leaf pointer in this tree points to + * a pampd, which is accessible only through a small set of callbacks + * registered by the PAM implementation (see tmem_register_pamops). Tmem + * does all memory allocation via a set of callbacks registered by the tmem + * host implementation (e.g. see tmem_register_hostops). + */ + +#include +#include +#include + +#include "tmem.h" + +/* data structure sentinels used for debugging... see tmem.h */ +#define POOL_SENTINEL 0x87658765 +#define OBJ_SENTINEL 0x12345678 +#define OBJNODE_SENTINEL 0xfedcba09 + +/* + * A tmem host implementation must use this function to register callbacks + * for memory allocation. + */ +static struct tmem_hostops tmem_hostops; + +static void tmem_objnode_tree_init(void); + +void tmem_register_hostops(struct tmem_hostops *m) +{ + tmem_objnode_tree_init(); + tmem_hostops = *m; +} + +/* + * A tmem host implementation must use this function to register + * callbacks for a page-accessible memory (PAM) implementation + */ +static struct tmem_pamops tmem_pamops; + +void tmem_register_pamops(struct tmem_pamops *m) +{ + tmem_pamops = *m; +} + +/* + * Oid's are potentially very sparse and tmem_objs may have an indeterminately + * short life, being added and deleted at a relatively high frequency. + * So an rb_tree is an ideal data structure to manage tmem_objs. But because + * of the potentially huge number of tmem_objs, each pool manages a hashtable + * of rb_trees to reduce search, insert, delete, and rebalancing time. + * Each hashbucket also has a lock to manage concurrent access. + * + * The following routines manage tmem_objs. When any tmem_obj is accessed, + * the hashbucket lock must be held. + */ + +/* searches for object==oid in pool, returns locked object if found */ +static struct tmem_obj *tmem_obj_find(struct tmem_hashbucket *hb, + struct tmem_oid *oidp) +{ + struct rb_node *rbnode; + struct tmem_obj *obj; + + rbnode = hb->obj_rb_root.rb_node; + while (rbnode) { + BUG_ON(RB_EMPTY_NODE(rbnode)); + obj = rb_entry(rbnode, struct tmem_obj, rb_tree_node); + switch (tmem_oid_compare(oidp, &obj->oid)) { + case 0: /* equal */ + goto out; + case -1: + rbnode = rbnode->rb_left; + break; + case 1: + rbnode = rbnode->rb_right; + break; + } + } + obj = NULL; +out: + return obj; +} + +static void tmem_pampd_destroy_all_in_obj(struct tmem_obj *); + +/* free an object that has no more pampds in it */ +static void tmem_obj_free(struct tmem_obj *obj, struct tmem_hashbucket *hb) +{ + struct tmem_pool *pool; + + BUG_ON(obj == NULL); + ASSERT_SENTINEL(obj, OBJ); + BUG_ON(obj->pampd_count > 0); + pool = obj->pool; + BUG_ON(pool == NULL); + if (obj->objnode_tree_root != NULL) /* may be "stump" with no leaves */ + tmem_pampd_destroy_all_in_obj(obj); + BUG_ON(obj->objnode_tree_root != NULL); + BUG_ON((long)obj->objnode_count != 0); + atomic_dec(&pool->obj_count); + BUG_ON(atomic_read(&pool->obj_count) < 0); + INVERT_SENTINEL(obj, OBJ); + obj->pool = NULL; + tmem_oid_set_invalid(&obj->oid); + rb_erase(&obj->rb_tree_node, &hb->obj_rb_root); +} + +/* + * initialize, and insert an tmem_object_root (called only if find failed) + */ +static void tmem_obj_init(struct tmem_obj *obj, struct tmem_hashbucket *hb, + struct tmem_pool *pool, + struct tmem_oid *oidp) +{ + struct rb_root *root = &hb->obj_rb_root; + struct rb_node **new = &(root->rb_node), *parent = NULL; + struct tmem_obj *this; + + BUG_ON(pool == NULL); + atomic_inc(&pool->obj_count); + obj->objnode_tree_height = 0; + obj->objnode_tree_root = NULL; + obj->pool = pool; + obj->oid = *oidp; + obj->objnode_count = 0; + obj->pampd_count = 0; + SET_SENTINEL(obj, OBJ); + while (*new) { + BUG_ON(RB_EMPTY_NODE(*new)); + this = rb_entry(*new, struct tmem_obj, rb_tree_node); + parent = *new; + switch (tmem_oid_compare(oidp, &this->oid)) { + case 0: + BUG(); /* already present; should never happen! */ + break; + case -1: + new = &(*new)->rb_left; + break; + case 1: + new = &(*new)->rb_right; + break; + } + } + rb_link_node(&obj->rb_tree_node, parent, new); + rb_insert_color(&obj->rb_tree_node, root); +} + +/* + * Tmem is managed as a set of tmem_pools with certain attributes, such as + * "ephemeral" vs "persistent". These attributes apply to all tmem_objs + * and all pampds that belong to a tmem_pool. A tmem_pool is created + * or deleted relatively rarely (for example, when a filesystem is + * mounted or unmounted. + */ + +/* flush all data from a pool and, optionally, free it */ +static void tmem_pool_flush(struct tmem_pool *pool, bool destroy) +{ + struct rb_node *rbnode; + struct tmem_obj *obj; + struct tmem_hashbucket *hb = &pool->hashbucket[0]; + int i; + + BUG_ON(pool == NULL); + for (i = 0; i < TMEM_HASH_BUCKETS; i++, hb++) { + spin_lock(&hb->lock); + rbnode = rb_first(&hb->obj_rb_root); + while (rbnode != NULL) { + obj = rb_entry(rbnode, struct tmem_obj, rb_tree_node); + rbnode = rb_next(rbnode); + tmem_pampd_destroy_all_in_obj(obj); + tmem_obj_free(obj, hb); + (*tmem_hostops.obj_free)(obj, pool); + } + spin_unlock(&hb->lock); + } + if (destroy) + list_del(&pool->pool_list); +} + +/* + * A tmem_obj contains a radix-tree-like tree in which the intermediate + * nodes are called tmem_objnodes. (The kernel lib/radix-tree.c implementation + * is very specialized and tuned for specific uses and is not particularly + * suited for use from this code, though some code from the core algorithms has + * been reused, thus the copyright notices below). Each tmem_objnode contains + * a set of pointers which point to either a set of intermediate tmem_objnodes + * or a set of of pampds. + * + * Portions Copyright (C) 2001 Momchil Velikov + * Portions Copyright (C) 2001 Christoph Hellwig + * Portions Copyright (C) 2005 SGI, Christoph Lameter + */ + +struct tmem_objnode_tree_path { + struct tmem_objnode *objnode; + int offset; +}; + +/* objnode height_to_maxindex translation */ +static unsigned long tmem_objnode_tree_h2max[OBJNODE_TREE_MAX_PATH + 1]; + +static void tmem_objnode_tree_init(void) +{ + unsigned int ht, tmp; + + for (ht = 0; ht < ARRAY_SIZE(tmem_objnode_tree_h2max); ht++) { + tmp = ht * OBJNODE_TREE_MAP_SHIFT; + if (tmp >= OBJNODE_TREE_INDEX_BITS) + tmem_objnode_tree_h2max[ht] = ~0UL; + else + tmem_objnode_tree_h2max[ht] = + (~0UL >> (OBJNODE_TREE_INDEX_BITS - tmp - 1)) >> 1; + } +} + +static struct tmem_objnode *tmem_objnode_alloc(struct tmem_obj *obj) +{ + struct tmem_objnode *objnode; + + ASSERT_SENTINEL(obj, OBJ); + BUG_ON(obj->pool == NULL); + ASSERT_SENTINEL(obj->pool, POOL); + objnode = (*tmem_hostops.objnode_alloc)(obj->pool); + if (unlikely(objnode == NULL)) + goto out; + objnode->obj = obj; + SET_SENTINEL(objnode, OBJNODE); + memset(&objnode->slots, 0, sizeof(objnode->slots)); + objnode->slots_in_use = 0; + obj->objnode_count++; +out: + return objnode; +} + +static void tmem_objnode_free(struct tmem_objnode *objnode) +{ + struct tmem_pool *pool; + int i; + + BUG_ON(objnode == NULL); + for (i = 0; i < OBJNODE_TREE_MAP_SIZE; i++) + BUG_ON(objnode->slots[i] != NULL); + ASSERT_SENTINEL(objnode, OBJNODE); + INVERT_SENTINEL(objnode, OBJNODE); + BUG_ON(objnode->obj == NULL); + ASSERT_SENTINEL(objnode->obj, OBJ); + pool = objnode->obj->pool; + BUG_ON(pool == NULL); + ASSERT_SENTINEL(pool, POOL); + objnode->obj->objnode_count--; + objnode->obj = NULL; + (*tmem_hostops.objnode_free)(objnode, pool); +} + +/* + * lookup index in object and return associated pampd (or NULL if not found) + */ +static void *tmem_pampd_lookup_in_obj(struct tmem_obj *obj, uint32_t index) +{ + unsigned int height, shift; + struct tmem_objnode **slot = NULL; + + BUG_ON(obj == NULL); + ASSERT_SENTINEL(obj, OBJ); + BUG_ON(obj->pool == NULL); + ASSERT_SENTINEL(obj->pool, POOL); + + height = obj->objnode_tree_height; + if (index > tmem_objnode_tree_h2max[obj->objnode_tree_height]) + goto out; + if (height == 0 && obj->objnode_tree_root) { + slot = &obj->objnode_tree_root; + goto out; + } + shift = (height-1) * OBJNODE_TREE_MAP_SHIFT; + slot = &obj->objnode_tree_root; + while (height > 0) { + if (*slot == NULL) + goto out; + slot = (struct tmem_objnode **) + ((*slot)->slots + + ((index >> shift) & OBJNODE_TREE_MAP_MASK)); + shift -= OBJNODE_TREE_MAP_SHIFT; + height--; + } +out: + return slot != NULL ? *slot : NULL; +} + +static int tmem_pampd_add_to_obj(struct tmem_obj *obj, uint32_t index, + void *pampd) +{ + int ret = 0; + struct tmem_objnode *objnode = NULL, *newnode, *slot; + unsigned int height, shift; + int offset = 0; + + /* if necessary, extend the tree to be higher */ + if (index > tmem_objnode_tree_h2max[obj->objnode_tree_height]) { + height = obj->objnode_tree_height + 1; + if (index > tmem_objnode_tree_h2max[height]) + while (index > tmem_objnode_tree_h2max[height]) + height++; + if (obj->objnode_tree_root == NULL) { + obj->objnode_tree_height = height; + goto insert; + } + do { + newnode = tmem_objnode_alloc(obj); + if (!newnode) { + ret = -ENOMEM; + goto out; + } + newnode->slots[0] = obj->objnode_tree_root; + newnode->slots_in_use = 1; + obj->objnode_tree_root = newnode; + obj->objnode_tree_height++; + } while (height > obj->objnode_tree_height); + } +insert: + slot = obj->objnode_tree_root; + height = obj->objnode_tree_height; + shift = (height-1) * OBJNODE_TREE_MAP_SHIFT; + while (height > 0) { + if (slot == NULL) { + /* add a child objnode. */ + slot = tmem_objnode_alloc(obj); + if (!slot) { + ret = -ENOMEM; + goto out; + } + if (objnode) { + + objnode->slots[offset] = slot; + objnode->slots_in_use++; + } else + obj->objnode_tree_root = slot; + } + /* go down a level */ + offset = (index >> shift) & OBJNODE_TREE_MAP_MASK; + objnode = slot; + slot = objnode->slots[offset]; + shift -= OBJNODE_TREE_MAP_SHIFT; + height--; + } + BUG_ON(slot != NULL); + if (objnode) { + objnode->slots_in_use++; + objnode->slots[offset] = pampd; + } else + obj->objnode_tree_root = pampd; + obj->pampd_count++; +out: + return ret; +} + +static void *tmem_pampd_delete_from_obj(struct tmem_obj *obj, uint32_t index) +{ + struct tmem_objnode_tree_path path[OBJNODE_TREE_MAX_PATH + 1]; + struct tmem_objnode_tree_path *pathp = path; + struct tmem_objnode *slot = NULL; + unsigned int height, shift; + int offset; + + BUG_ON(obj == NULL); + ASSERT_SENTINEL(obj, OBJ); + BUG_ON(obj->pool == NULL); + ASSERT_SENTINEL(obj->pool, POOL); + height = obj->objnode_tree_height; + if (index > tmem_objnode_tree_h2max[height]) + goto out; + slot = obj->objnode_tree_root; + if (height == 0 && obj->objnode_tree_root) { + obj->objnode_tree_root = NULL; + goto out; + } + shift = (height - 1) * OBJNODE_TREE_MAP_SHIFT; + pathp->objnode = NULL; + do { + if (slot == NULL) + goto out; + pathp++; + offset = (index >> shift) & OBJNODE_TREE_MAP_MASK; + pathp->offset = offset; + pathp->objnode = slot; + slot = slot->slots[offset]; + shift -= OBJNODE_TREE_MAP_SHIFT; + height--; + } while (height > 0); + if (slot == NULL) + goto out; + while (pathp->objnode) { + pathp->objnode->slots[pathp->offset] = NULL; + pathp->objnode->slots_in_use--; + if (pathp->objnode->slots_in_use) { + if (pathp->objnode == obj->objnode_tree_root) { + while (obj->objnode_tree_height > 0 && + obj->objnode_tree_root->slots_in_use == 1 && + obj->objnode_tree_root->slots[0]) { + struct tmem_objnode *to_free = + obj->objnode_tree_root; + + obj->objnode_tree_root = + to_free->slots[0]; + obj->objnode_tree_height--; + to_free->slots[0] = NULL; + to_free->slots_in_use = 0; + tmem_objnode_free(to_free); + } + } + goto out; + } + tmem_objnode_free(pathp->objnode); /* 0 slots used, free it */ + pathp--; + } + obj->objnode_tree_height = 0; + obj->objnode_tree_root = NULL; + +out: + if (slot != NULL) + obj->pampd_count--; + BUG_ON(obj->pampd_count < 0); + return slot; +} + +/* recursively walk the objnode_tree destroying pampds and objnodes */ +static void tmem_objnode_node_destroy(struct tmem_obj *obj, + struct tmem_objnode *objnode, + unsigned int ht) +{ + int i; + + if (ht == 0) + return; + for (i = 0; i < OBJNODE_TREE_MAP_SIZE; i++) { + if (objnode->slots[i]) { + if (ht == 1) { + obj->pampd_count--; + (*tmem_pamops.free)(objnode->slots[i], + obj->pool); + objnode->slots[i] = NULL; + continue; + } + tmem_objnode_node_destroy(obj, objnode->slots[i], ht-1); + tmem_objnode_free(objnode->slots[i]); + objnode->slots[i] = NULL; + } + } +} + +static void tmem_pampd_destroy_all_in_obj(struct tmem_obj *obj) +{ + if (obj->objnode_tree_root == NULL) + return; + if (obj->objnode_tree_height == 0) { + obj->pampd_count--; + (*tmem_pamops.free)(obj->objnode_tree_root, obj->pool); + } else { + tmem_objnode_node_destroy(obj, obj->objnode_tree_root, + obj->objnode_tree_height); + tmem_objnode_free(obj->objnode_tree_root); + obj->objnode_tree_height = 0; + } + obj->objnode_tree_root = NULL; +} + +/* + * Tmem is operated on by a set of well-defined actions: + * "put", "get", "flush", "flush_object", "new pool" and "destroy pool". + * (The tmem ABI allows for subpages and exchanges but these operations + * are not included in this implementation.) + * + * These "tmem core" operations are implemented in the following functions. + */ + +/* + * "Put" a page, e.g. copy a page from the kernel into newly allocated + * PAM space (if such space is available). Tmem_put is complicated by + * a corner case: What if a page with matching handle already exists in + * tmem? To guarantee coherency, one of two actions is necessary: Either + * the data for the page must be overwritten, or the page must be + * "flushed" so that the data is not accessible to a subsequent "get". + * Since these "duplicate puts" are relatively rare, this implementation + * always flushes for simplicity. + */ +int tmem_put(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, + struct page *page) +{ + struct tmem_obj *obj = NULL, *objfound = NULL, *objnew = NULL; + void *pampd = NULL, *pampd_del = NULL; + int ret = -ENOMEM; + bool ephemeral; + struct tmem_hashbucket *hb; + + ephemeral = is_ephemeral(pool); + hb = &pool->hashbucket[tmem_oid_hash(oidp)]; + spin_lock(&hb->lock); + obj = objfound = tmem_obj_find(hb, oidp); + if (obj != NULL) { + pampd = tmem_pampd_lookup_in_obj(objfound, index); + if (pampd != NULL) { + /* if found, is a dup put, flush the old one */ + pampd_del = tmem_pampd_delete_from_obj(obj, index); + BUG_ON(pampd_del != pampd); + (*tmem_pamops.free)(pampd, pool); + if (obj->pampd_count == 0) { + objnew = obj; + objfound = NULL; + } + pampd = NULL; + } + } else { + obj = objnew = (*tmem_hostops.obj_alloc)(pool); + if (unlikely(obj == NULL)) { + ret = -ENOMEM; + goto out; + } + tmem_obj_init(obj, hb, pool, oidp); + } + BUG_ON(obj == NULL); + BUG_ON(((objnew != obj) && (objfound != obj)) || (objnew == objfound)); + pampd = (*tmem_pamops.create)(obj->pool, &obj->oid, index, page); + if (unlikely(pampd == NULL)) + goto free; + ret = tmem_pampd_add_to_obj(obj, index, pampd); + if (unlikely(ret == -ENOMEM)) + /* may have partially built objnode tree ("stump") */ + goto delete_and_free; + goto out; + +delete_and_free: + (void)tmem_pampd_delete_from_obj(obj, index); +free: + if (pampd) + (*tmem_pamops.free)(pampd, pool); + if (objnew) { + tmem_obj_free(objnew, hb); + (*tmem_hostops.obj_free)(objnew, pool); + } +out: + spin_unlock(&hb->lock); + return ret; +} + +/* + * "Get" a page, e.g. if one can be found, copy the tmem page with the + * matching handle from PAM space to the kernel. By tmem definition, + * when a "get" is successful on an ephemeral page, the page is "flushed", + * and when a "get" is successful on a persistent page, the page is retained + * in tmem. Note that to preserve + * coherency, "get" can never be skipped if tmem contains the data. + * That is, if a get is done with a certain handle and fails, any + * subsequent "get" must also fail (unless of course there is a + * "put" done with the same handle). + + */ +int tmem_get(struct tmem_pool *pool, struct tmem_oid *oidp, + uint32_t index, struct page *page) +{ + struct tmem_obj *obj; + void *pampd; + bool ephemeral = is_ephemeral(pool); + uint32_t ret = -1; + struct tmem_hashbucket *hb; + + hb = &pool->hashbucket[tmem_oid_hash(oidp)]; + spin_lock(&hb->lock); + obj = tmem_obj_find(hb, oidp); + if (obj == NULL) + goto out; + ephemeral = is_ephemeral(pool); + if (ephemeral) + pampd = tmem_pampd_delete_from_obj(obj, index); + else + pampd = tmem_pampd_lookup_in_obj(obj, index); + if (pampd == NULL) + goto out; + ret = (*tmem_pamops.get_data)(page, pampd, pool); + if (ret < 0) + goto out; + if (ephemeral) { + (*tmem_pamops.free)(pampd, pool); + if (obj->pampd_count == 0) { + tmem_obj_free(obj, hb); + (*tmem_hostops.obj_free)(obj, pool); + obj = NULL; + } + } + ret = 0; +out: + spin_unlock(&hb->lock); + return ret; +} + +/* + * If a page in tmem matches the handle, "flush" this page from tmem such + * that any subsequent "get" does not succeed (unless, of course, there + * was another "put" with the same handle). + */ +int tmem_flush_page(struct tmem_pool *pool, + struct tmem_oid *oidp, uint32_t index) +{ + struct tmem_obj *obj; + void *pampd; + int ret = -1; + struct tmem_hashbucket *hb; + + hb = &pool->hashbucket[tmem_oid_hash(oidp)]; + spin_lock(&hb->lock); + obj = tmem_obj_find(hb, oidp); + if (obj == NULL) + goto out; + pampd = tmem_pampd_delete_from_obj(obj, index); + if (pampd == NULL) + goto out; + (*tmem_pamops.free)(pampd, pool); + if (obj->pampd_count == 0) { + tmem_obj_free(obj, hb); + (*tmem_hostops.obj_free)(obj, pool); + } + ret = 0; + +out: + spin_unlock(&hb->lock); + return ret; +} + +/* + * "Flush" all pages in tmem matching this oid. + */ +int tmem_flush_object(struct tmem_pool *pool, struct tmem_oid *oidp) +{ + struct tmem_obj *obj; + struct tmem_hashbucket *hb; + int ret = -1; + + hb = &pool->hashbucket[tmem_oid_hash(oidp)]; + spin_lock(&hb->lock); + obj = tmem_obj_find(hb, oidp); + if (obj == NULL) + goto out; + tmem_pampd_destroy_all_in_obj(obj); + tmem_obj_free(obj, hb); + (*tmem_hostops.obj_free)(obj, pool); + ret = 0; + +out: + spin_unlock(&hb->lock); + return ret; +} + +/* + * "Flush" all pages (and tmem_objs) from this tmem_pool and disable + * all subsequent access to this tmem_pool. + */ +int tmem_destroy_pool(struct tmem_pool *pool) +{ + int ret = -1; + + if (pool == NULL) + goto out; + tmem_pool_flush(pool, 1); + ret = 0; +out: + return ret; +} + +static LIST_HEAD(tmem_global_pool_list); + +/* + * Create a new tmem_pool with the provided flag and return + * a pool id provided by the tmem host implementation. + */ +void tmem_new_pool(struct tmem_pool *pool, uint32_t flags) +{ + int persistent = flags & TMEM_POOL_PERSIST; + int shared = flags & TMEM_POOL_SHARED; + struct tmem_hashbucket *hb = &pool->hashbucket[0]; + int i; + + for (i = 0; i < TMEM_HASH_BUCKETS; i++, hb++) { + hb->obj_rb_root = RB_ROOT; + spin_lock_init(&hb->lock); + } + INIT_LIST_HEAD(&pool->pool_list); + atomic_set(&pool->obj_count, 0); + SET_SENTINEL(pool, POOL); + list_add_tail(&pool->pool_list, &tmem_global_pool_list); + pool->persistent = persistent; + pool->shared = shared; +} diff --git a/drivers/staging/zcache/tmem.h b/drivers/staging/zcache/tmem.h new file mode 100644 index 000000000000..2e07e217d51f --- /dev/null +++ b/drivers/staging/zcache/tmem.h @@ -0,0 +1,195 @@ +/* + * tmem.h + * + * Transcendent memory + * + * Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp. + */ + +#ifndef _TMEM_H_ +#define _TMEM_H_ + +#include +#include +#include +#include + +/* + * These are pre-defined by the Xen<->Linux ABI + */ +#define TMEM_PUT_PAGE 4 +#define TMEM_GET_PAGE 5 +#define TMEM_FLUSH_PAGE 6 +#define TMEM_FLUSH_OBJECT 7 +#define TMEM_POOL_PERSIST 1 +#define TMEM_POOL_SHARED 2 +#define TMEM_POOL_PRECOMPRESSED 4 +#define TMEM_POOL_PAGESIZE_SHIFT 4 +#define TMEM_POOL_PAGESIZE_MASK 0xf +#define TMEM_POOL_RESERVED_BITS 0x00ffff00 + +/* + * sentinels have proven very useful for debugging but can be removed + * or disabled before final merge. + */ +#define SENTINELS +#ifdef SENTINELS +#define DECL_SENTINEL uint32_t sentinel; +#define SET_SENTINEL(_x, _y) (_x->sentinel = _y##_SENTINEL) +#define INVERT_SENTINEL(_x, _y) (_x->sentinel = ~_y##_SENTINEL) +#define ASSERT_SENTINEL(_x, _y) WARN_ON(_x->sentinel != _y##_SENTINEL) +#define ASSERT_INVERTED_SENTINEL(_x, _y) WARN_ON(_x->sentinel != ~_y##_SENTINEL) +#else +#define DECL_SENTINEL +#define SET_SENTINEL(_x, _y) do { } while (0) +#define INVERT_SENTINEL(_x, _y) do { } while (0) +#define ASSERT_SENTINEL(_x, _y) do { } while (0) +#define ASSERT_INVERTED_SENTINEL(_x, _y) do { } while (0) +#endif + +#define ASSERT_SPINLOCK(_l) WARN_ON(!spin_is_locked(_l)) + +/* + * A pool is the highest-level data structure managed by tmem and + * usually corresponds to a large independent set of pages such as + * a filesystem. Each pool has an id, and certain attributes and counters. + * It also contains a set of hash buckets, each of which contains an rbtree + * of objects and a lock to manage concurrency within the pool. + */ + +#define TMEM_HASH_BUCKET_BITS 8 +#define TMEM_HASH_BUCKETS (1<persistent) +#define is_ephemeral(_p) (!(_p->persistent)) + +/* + * An object id ("oid") is large: 192-bits (to ensure, for example, files + * in a modern filesystem can be uniquely identified). + */ + +struct tmem_oid { + uint64_t oid[3]; +}; + +static inline void tmem_oid_set_invalid(struct tmem_oid *oidp) +{ + oidp->oid[0] = oidp->oid[1] = oidp->oid[2] = -1UL; +} + +static inline bool tmem_oid_valid(struct tmem_oid *oidp) +{ + return oidp->oid[0] != -1UL || oidp->oid[1] != -1UL || + oidp->oid[2] != -1UL; +} + +static inline int tmem_oid_compare(struct tmem_oid *left, + struct tmem_oid *right) +{ + int ret; + + if (left->oid[2] == right->oid[2]) { + if (left->oid[1] == right->oid[1]) { + if (left->oid[0] == right->oid[0]) + ret = 0; + else if (left->oid[0] < right->oid[0]) + ret = -1; + else + return 1; + } else if (left->oid[1] < right->oid[1]) + ret = -1; + else + ret = 1; + } else if (left->oid[2] < right->oid[2]) + ret = -1; + else + ret = 1; + return ret; +} + +static inline unsigned tmem_oid_hash(struct tmem_oid *oidp) +{ + return hash_long(oidp->oid[0] ^ oidp->oid[1] ^ oidp->oid[2], + TMEM_HASH_BUCKET_BITS); +} + +/* + * A tmem_obj contains an identifier (oid), pointers to the parent + * pool and the rb_tree to which it belongs, counters, and an ordered + * set of pampds, structured in a radix-tree-like tree. The intermediate + * nodes of the tree are called tmem_objnodes. + */ + +struct tmem_objnode; + +struct tmem_obj { + struct tmem_oid oid; + struct tmem_pool *pool; + struct rb_node rb_tree_node; + struct tmem_objnode *objnode_tree_root; + unsigned int objnode_tree_height; + unsigned long objnode_count; + long pampd_count; + DECL_SENTINEL +}; + +#define OBJNODE_TREE_MAP_SHIFT 6 +#define OBJNODE_TREE_MAP_SIZE (1UL << OBJNODE_TREE_MAP_SHIFT) +#define OBJNODE_TREE_MAP_MASK (OBJNODE_TREE_MAP_SIZE-1) +#define OBJNODE_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long)) +#define OBJNODE_TREE_MAX_PATH \ + (OBJNODE_TREE_INDEX_BITS/OBJNODE_TREE_MAP_SHIFT + 2) + +struct tmem_objnode { + struct tmem_obj *obj; + DECL_SENTINEL + void *slots[OBJNODE_TREE_MAP_SIZE]; + unsigned int slots_in_use; +}; + +/* pampd abstract datatype methods provided by the PAM implementation */ +struct tmem_pamops { + void *(*create)(struct tmem_pool *, struct tmem_oid *, uint32_t, + struct page *); + int (*get_data)(struct page *, void *, struct tmem_pool *); + void (*free)(void *, struct tmem_pool *); +}; +extern void tmem_register_pamops(struct tmem_pamops *m); + +/* memory allocation methods provided by the host implementation */ +struct tmem_hostops { + struct tmem_obj *(*obj_alloc)(struct tmem_pool *); + void (*obj_free)(struct tmem_obj *, struct tmem_pool *); + struct tmem_objnode *(*objnode_alloc)(struct tmem_pool *); + void (*objnode_free)(struct tmem_objnode *, struct tmem_pool *); +}; +extern void tmem_register_hostops(struct tmem_hostops *m); + +/* core tmem accessor functions */ +extern int tmem_put(struct tmem_pool *, struct tmem_oid *, uint32_t index, + struct page *page); +extern int tmem_get(struct tmem_pool *, struct tmem_oid *, uint32_t index, + struct page *page); +extern int tmem_flush_page(struct tmem_pool *, struct tmem_oid *, + uint32_t index); +extern int tmem_flush_object(struct tmem_pool *, struct tmem_oid *); +extern int tmem_destroy_pool(struct tmem_pool *); +extern void tmem_new_pool(struct tmem_pool *, uint32_t); +#endif /* _TMEM_H */ -- cgit v1.2.3 From 9cc06bf88d554dd527ded26eab28eec6a0d0e3df Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Sun, 6 Feb 2011 19:26:08 -0800 Subject: staging: zcache: host services and PAM services [PATCH V2 2/3] drivers/staging: zcache: host services and PAM services Zcache provides host services (memory allocation) for tmem, a "shim" to interface cleancache and frontswap to tmem, and two different page-addressable memory implemenations using lzo1x compression. The first, "compression buddies" ("zbud") compresses pairs of pages and supplies a shrinker interface that allows entire pages to be reclaimed. The second is a shim to xvMalloc which is more space-efficient but less receptive to page reclamation. The first is used for ephemeral pools and the second for persistent pools. All ephemeral pools share the same memory, that is, even pages from different pools can share the same page. Signed-off-by: Dan Magenheimer Signed-off-by: Nitin Gupta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/zcache.c | 1657 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 1657 insertions(+) create mode 100644 drivers/staging/zcache/zcache.c (limited to 'drivers') diff --git a/drivers/staging/zcache/zcache.c b/drivers/staging/zcache/zcache.c new file mode 100644 index 000000000000..61be8498fb06 --- /dev/null +++ b/drivers/staging/zcache/zcache.c @@ -0,0 +1,1657 @@ +/* + * zcache.c + * + * Copyright (c) 2010,2011, Dan Magenheimer, Oracle Corp. + * Copyright (c) 2010,2011, Nitin Gupta + * + * Zcache provides an in-kernel "host implementation" for transcendent memory + * and, thus indirectly, for cleancache and frontswap. Zcache includes two + * page-accessible memory [1] interfaces, both utilizing lzo1x compression: + * 1) "compression buddies" ("zbud") is used for ephemeral pages + * 2) xvmalloc is used for persistent pages. + * Xvmalloc (based on the TLSF allocator) has very low fragmentation + * so maximizes space efficiency, while zbud allows pairs (and potentially, + * in the future, more than a pair of) compressed pages to be closely linked + * so that reclaiming can be done via the kernel's physical-page-oriented + * "shrinker" interface. + * + * [1] For a definition of page-accessible memory (aka PAM), see: + * http://marc.info/?l=linux-mm&m=127811271605009 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "tmem.h" + +#include "../zram/xvmalloc.h" /* if built in drivers/staging */ + +#if (!defined(CONFIG_CLEANCACHE) && !defined(CONFIG_FRONTSWAP)) +#error "zcache is useless without CONFIG_CLEANCACHE or CONFIG_FRONTSWAP" +#endif +#ifdef CONFIG_CLEANCACHE +#include +#endif +#ifdef CONFIG_FRONTSWAP +#include +#endif + +#if 0 +/* this is more aggressive but may cause other problems? */ +#define ZCACHE_GFP_MASK (GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN) +#else +#define ZCACHE_GFP_MASK \ + (__GFP_FS | __GFP_NORETRY | __GFP_NOWARN | __GFP_NOMEMALLOC) +#endif + +/********** + * Compression buddies ("zbud") provides for packing two (or, possibly + * in the future, more) compressed ephemeral pages into a single "raw" + * (physical) page and tracking them with data structures so that + * the raw pages can be easily reclaimed. + * + * A zbud page ("zbpg") is an aligned page containing a list_head, + * a lock, and two "zbud headers". The remainder of the physical + * page is divided up into aligned 64-byte "chunks" which contain + * the compressed data for zero, one, or two zbuds. Each zbpg + * resides on: (1) an "unused list" if it has no zbuds; (2) a + * "buddied" list if it is fully populated with two zbuds; or + * (3) one of PAGE_SIZE/64 "unbuddied" lists indexed by how many chunks + * the one unbuddied zbud uses. The data inside a zbpg cannot be + * read or written unless the zbpg's lock is held. + */ + +#define ZBH_SENTINEL 0x43214321 +#define ZBPG_SENTINEL 0xdeadbeef + +#define ZBUD_MAX_BUDS 2 + +struct zbud_hdr { + uint32_t pool_id; + struct tmem_oid oid; + uint32_t index; + uint16_t size; /* compressed size in bytes, zero means unused */ + DECL_SENTINEL +}; + +struct zbud_page { + struct list_head bud_list; + spinlock_t lock; + struct zbud_hdr buddy[ZBUD_MAX_BUDS]; + DECL_SENTINEL + /* followed by NUM_CHUNK aligned CHUNK_SIZE-byte chunks */ +}; + +#define CHUNK_SHIFT 6 +#define CHUNK_SIZE (1 << CHUNK_SHIFT) +#define CHUNK_MASK (~(CHUNK_SIZE-1)) +#define NCHUNKS (((PAGE_SIZE - sizeof(struct zbud_page)) & \ + CHUNK_MASK) >> CHUNK_SHIFT) +#define MAX_CHUNK (NCHUNKS-1) + +static struct { + struct list_head list; + unsigned count; +} zbud_unbuddied[NCHUNKS]; +/* list N contains pages with N chunks USED and NCHUNKS-N unused */ +/* element 0 is never used but optimizing that isn't worth it */ +static unsigned long zbud_cumul_chunk_counts[NCHUNKS]; + +struct list_head zbud_buddied_list; +static unsigned long zcache_zbud_buddied_count; + +/* protects the buddied list and all unbuddied lists */ +static DEFINE_SPINLOCK(zbud_budlists_spinlock); + +static LIST_HEAD(zbpg_unused_list); +static unsigned long zcache_zbpg_unused_list_count; + +/* protects the unused page list */ +static DEFINE_SPINLOCK(zbpg_unused_list_spinlock); + +static atomic_t zcache_zbud_curr_raw_pages; +static atomic_t zcache_zbud_curr_zpages; +static unsigned long zcache_zbud_curr_zbytes; +static unsigned long zcache_zbud_cumul_zpages; +static unsigned long zcache_zbud_cumul_zbytes; +static unsigned long zcache_compress_poor; + +/* forward references */ +static void *zcache_get_free_page(void); +static void zcache_free_page(void *p); + +/* + * zbud helper functions + */ + +static inline unsigned zbud_max_buddy_size(void) +{ + return MAX_CHUNK << CHUNK_SHIFT; +} + +static inline unsigned zbud_size_to_chunks(unsigned size) +{ + BUG_ON(size == 0 || size > zbud_max_buddy_size()); + return (size + CHUNK_SIZE - 1) >> CHUNK_SHIFT; +} + +static inline int zbud_budnum(struct zbud_hdr *zh) +{ + unsigned offset = (unsigned long)zh & (PAGE_SIZE - 1); + struct zbud_page *zbpg = NULL; + unsigned budnum = -1U; + int i; + + for (i = 0; i < ZBUD_MAX_BUDS; i++) + if (offset == offsetof(typeof(*zbpg), buddy[i])) { + budnum = i; + break; + } + BUG_ON(budnum == -1U); + return budnum; +} + +static char *zbud_data(struct zbud_hdr *zh, unsigned size) +{ + struct zbud_page *zbpg; + char *p; + unsigned budnum; + + ASSERT_SENTINEL(zh, ZBH); + budnum = zbud_budnum(zh); + BUG_ON(size == 0 || size > zbud_max_buddy_size()); + zbpg = container_of(zh, struct zbud_page, buddy[budnum]); + ASSERT_SPINLOCK(&zbpg->lock); + p = (char *)zbpg; + if (budnum == 0) + p += ((sizeof(struct zbud_page) + CHUNK_SIZE - 1) & + CHUNK_MASK); + else if (budnum == 1) + p += PAGE_SIZE - ((size + CHUNK_SIZE - 1) & CHUNK_MASK); + return p; +} + +/* + * zbud raw page management + */ + +static struct zbud_page *zbud_alloc_raw_page(void) +{ + struct zbud_page *zbpg = NULL; + struct zbud_hdr *zh0, *zh1; + bool recycled = 0; + + /* if any pages on the zbpg list, use one */ + spin_lock(&zbpg_unused_list_spinlock); + if (!list_empty(&zbpg_unused_list)) { + zbpg = list_first_entry(&zbpg_unused_list, + struct zbud_page, bud_list); + list_del_init(&zbpg->bud_list); + zcache_zbpg_unused_list_count--; + recycled = 1; + } + spin_unlock(&zbpg_unused_list_spinlock); + if (zbpg == NULL) + /* none on zbpg list, try to get a kernel page */ + zbpg = zcache_get_free_page(); + if (likely(zbpg != NULL)) { + INIT_LIST_HEAD(&zbpg->bud_list); + zh0 = &zbpg->buddy[0]; zh1 = &zbpg->buddy[1]; + spin_lock_init(&zbpg->lock); + if (recycled) { + ASSERT_INVERTED_SENTINEL(zbpg, ZBPG); + SET_SENTINEL(zbpg, ZBPG); + BUG_ON(zh0->size != 0 || tmem_oid_valid(&zh0->oid)); + BUG_ON(zh1->size != 0 || tmem_oid_valid(&zh1->oid)); + } else { + atomic_inc(&zcache_zbud_curr_raw_pages); + INIT_LIST_HEAD(&zbpg->bud_list); + SET_SENTINEL(zbpg, ZBPG); + zh0->size = 0; zh1->size = 0; + tmem_oid_set_invalid(&zh0->oid); + tmem_oid_set_invalid(&zh1->oid); + } + } + return zbpg; +} + +static void zbud_free_raw_page(struct zbud_page *zbpg) +{ + struct zbud_hdr *zh0 = &zbpg->buddy[0], *zh1 = &zbpg->buddy[1]; + + ASSERT_SENTINEL(zbpg, ZBPG); + BUG_ON(!list_empty(&zbpg->bud_list)); + ASSERT_SPINLOCK(&zbpg->lock); + BUG_ON(zh0->size != 0 || tmem_oid_valid(&zh0->oid)); + BUG_ON(zh1->size != 0 || tmem_oid_valid(&zh1->oid)); + INVERT_SENTINEL(zbpg, ZBPG); + spin_unlock(&zbpg->lock); + spin_lock(&zbpg_unused_list_spinlock); + list_add(&zbpg->bud_list, &zbpg_unused_list); + zcache_zbpg_unused_list_count++; + spin_unlock(&zbpg_unused_list_spinlock); +} + +/* + * core zbud handling routines + */ + +static unsigned zbud_free(struct zbud_hdr *zh) +{ + unsigned size; + + ASSERT_SENTINEL(zh, ZBH); + BUG_ON(!tmem_oid_valid(&zh->oid)); + size = zh->size; + BUG_ON(zh->size == 0 || zh->size > zbud_max_buddy_size()); + zh->size = 0; + tmem_oid_set_invalid(&zh->oid); + INVERT_SENTINEL(zh, ZBH); + zcache_zbud_curr_zbytes -= size; + atomic_dec(&zcache_zbud_curr_zpages); + return size; +} + +static void zbud_free_and_delist(struct zbud_hdr *zh) +{ + unsigned chunks; + struct zbud_hdr *zh_other; + unsigned budnum = zbud_budnum(zh), size; + struct zbud_page *zbpg = + container_of(zh, struct zbud_page, buddy[budnum]); + + spin_lock(&zbpg->lock); + if (list_empty(&zbpg->bud_list)) { + /* ignore zombie page... see zbud_evict_pages() */ + spin_unlock(&zbpg->lock); + return; + } + size = zbud_free(zh); + ASSERT_SPINLOCK(&zbpg->lock); + zh_other = &zbpg->buddy[(budnum == 0) ? 1 : 0]; + if (zh_other->size == 0) { /* was unbuddied: unlist and free */ + chunks = zbud_size_to_chunks(size) ; + spin_lock(&zbud_budlists_spinlock); + BUG_ON(list_empty(&zbud_unbuddied[chunks].list)); + list_del_init(&zbpg->bud_list); + zbud_unbuddied[chunks].count--; + spin_unlock(&zbud_budlists_spinlock); + zbud_free_raw_page(zbpg); + } else { /* was buddied: move remaining buddy to unbuddied list */ + chunks = zbud_size_to_chunks(zh_other->size) ; + spin_lock(&zbud_budlists_spinlock); + list_del_init(&zbpg->bud_list); + zcache_zbud_buddied_count--; + list_add_tail(&zbpg->bud_list, &zbud_unbuddied[chunks].list); + zbud_unbuddied[chunks].count++; + spin_unlock(&zbud_budlists_spinlock); + spin_unlock(&zbpg->lock); + } +} + +static struct zbud_hdr *zbud_create(uint32_t pool_id, struct tmem_oid *oid, + uint32_t index, struct page *page, + void *cdata, unsigned size) +{ + struct zbud_hdr *zh0, *zh1, *zh = NULL; + struct zbud_page *zbpg = NULL, *ztmp; + unsigned nchunks; + char *to; + int i, found_good_buddy = 0; + + nchunks = zbud_size_to_chunks(size) ; + for (i = MAX_CHUNK - nchunks + 1; i > 0; i--) { + spin_lock(&zbud_budlists_spinlock); + if (!list_empty(&zbud_unbuddied[i].list)) { + list_for_each_entry_safe(zbpg, ztmp, + &zbud_unbuddied[i].list, bud_list) { + if (spin_trylock(&zbpg->lock)) { + found_good_buddy = i; + goto found_unbuddied; + } + } + } + spin_unlock(&zbud_budlists_spinlock); + } + /* didn't find a good buddy, try allocating a new page */ + zbpg = zbud_alloc_raw_page(); + if (unlikely(zbpg == NULL)) + goto out; + /* ok, have a page, now compress the data before taking locks */ + spin_lock(&zbpg->lock); + spin_lock(&zbud_budlists_spinlock); + list_add_tail(&zbpg->bud_list, &zbud_unbuddied[nchunks].list); + zbud_unbuddied[nchunks].count++; + zh = &zbpg->buddy[0]; + goto init_zh; + +found_unbuddied: + ASSERT_SPINLOCK(&zbpg->lock); + zh0 = &zbpg->buddy[0]; zh1 = &zbpg->buddy[1]; + BUG_ON(!((zh0->size == 0) ^ (zh1->size == 0))); + if (zh0->size != 0) { /* buddy0 in use, buddy1 is vacant */ + ASSERT_SENTINEL(zh0, ZBH); + zh = zh1; + } else if (zh1->size != 0) { /* buddy1 in use, buddy0 is vacant */ + ASSERT_SENTINEL(zh1, ZBH); + zh = zh0; + } else + BUG(); + list_del_init(&zbpg->bud_list); + zbud_unbuddied[found_good_buddy].count--; + list_add_tail(&zbpg->bud_list, &zbud_buddied_list); + zcache_zbud_buddied_count++; + +init_zh: + SET_SENTINEL(zh, ZBH); + zh->size = size; + zh->index = index; + zh->oid = *oid; + zh->pool_id = pool_id; + /* can wait to copy the data until the list locks are dropped */ + spin_unlock(&zbud_budlists_spinlock); + + to = zbud_data(zh, size); + memcpy(to, cdata, size); + spin_unlock(&zbpg->lock); + zbud_cumul_chunk_counts[nchunks]++; + atomic_inc(&zcache_zbud_curr_zpages); + zcache_zbud_cumul_zpages++; + zcache_zbud_curr_zbytes += size; + zcache_zbud_cumul_zbytes += size; +out: + return zh; +} + +static int zbud_decompress(struct page *page, struct zbud_hdr *zh) +{ + struct zbud_page *zbpg; + unsigned budnum = zbud_budnum(zh); + size_t out_len = PAGE_SIZE; + char *to_va, *from_va; + unsigned size; + int ret = 0; + + zbpg = container_of(zh, struct zbud_page, buddy[budnum]); + spin_lock(&zbpg->lock); + if (list_empty(&zbpg->bud_list)) { + /* ignore zombie page... see zbud_evict_pages() */ + ret = -EINVAL; + goto out; + } + ASSERT_SENTINEL(zh, ZBH); + BUG_ON(zh->size == 0 || zh->size > zbud_max_buddy_size()); + to_va = kmap_atomic(page, KM_USER0); + size = zh->size; + from_va = zbud_data(zh, size); + ret = lzo1x_decompress_safe(from_va, size, to_va, &out_len); + BUG_ON(ret != LZO_E_OK); + BUG_ON(out_len != PAGE_SIZE); + kunmap_atomic(to_va, KM_USER0); +out: + spin_unlock(&zbpg->lock); + return ret; +} + +/* + * The following routines handle shrinking of ephemeral pages by evicting + * pages "least valuable" first. + */ + +static unsigned long zcache_evicted_raw_pages; +static unsigned long zcache_evicted_buddied_pages; +static unsigned long zcache_evicted_unbuddied_pages; + +static struct tmem_pool *zcache_get_pool_by_id(uint32_t poolid); +static void zcache_put_pool(struct tmem_pool *pool); + +/* + * Flush and free all zbuds in a zbpg, then free the pageframe + */ +static void zbud_evict_zbpg(struct zbud_page *zbpg) +{ + struct zbud_hdr *zh; + int i, j; + uint32_t pool_id[ZBUD_MAX_BUDS], index[ZBUD_MAX_BUDS]; + struct tmem_oid oid[ZBUD_MAX_BUDS]; + struct tmem_pool *pool; + + ASSERT_SPINLOCK(&zbpg->lock); + BUG_ON(!list_empty(&zbpg->bud_list)); + for (i = 0, j = 0; i < ZBUD_MAX_BUDS; i++) { + zh = &zbpg->buddy[i]; + if (zh->size) { + pool_id[j] = zh->pool_id; + oid[j] = zh->oid; + index[j] = zh->index; + j++; + zbud_free(zh); + } + } + spin_unlock(&zbpg->lock); + for (i = 0; i < j; i++) { + pool = zcache_get_pool_by_id(pool_id[i]); + if (pool != NULL) { + tmem_flush_page(pool, &oid[i], index[i]); + zcache_put_pool(pool); + } + } + ASSERT_SENTINEL(zbpg, ZBPG); + spin_lock(&zbpg->lock); + zbud_free_raw_page(zbpg); +} + +/* + * Free nr pages. This code is funky because we want to hold the locks + * protecting various lists for as short a time as possible, and in some + * circumstances the list may change asynchronously when the list lock is + * not held. In some cases we also trylock not only to avoid waiting on a + * page in use by another cpu, but also to avoid potential deadlock due to + * lock inversion. + */ +static void zbud_evict_pages(int nr) +{ + struct zbud_page *zbpg; + int i; + + /* first try freeing any pages on unused list */ +retry_unused_list: + spin_lock_bh(&zbpg_unused_list_spinlock); + if (!list_empty(&zbpg_unused_list)) { + /* can't walk list here, since it may change when unlocked */ + zbpg = list_first_entry(&zbpg_unused_list, + struct zbud_page, bud_list); + list_del_init(&zbpg->bud_list); + zcache_zbpg_unused_list_count--; + atomic_dec(&zcache_zbud_curr_raw_pages); + spin_unlock_bh(&zbpg_unused_list_spinlock); + zcache_free_page(zbpg); + zcache_evicted_raw_pages++; + if (--nr <= 0) + goto out; + goto retry_unused_list; + } + spin_unlock_bh(&zbpg_unused_list_spinlock); + + /* now try freeing unbuddied pages, starting with least space avail */ + for (i = 0; i < MAX_CHUNK; i++) { +retry_unbud_list_i: + spin_lock_bh(&zbud_budlists_spinlock); + if (list_empty(&zbud_unbuddied[i].list)) { + spin_unlock_bh(&zbud_budlists_spinlock); + continue; + } + list_for_each_entry(zbpg, &zbud_unbuddied[i].list, bud_list) { + if (unlikely(!spin_trylock(&zbpg->lock))) + continue; + list_del_init(&zbpg->bud_list); + zbud_unbuddied[i].count--; + spin_unlock(&zbud_budlists_spinlock); + zcache_evicted_unbuddied_pages++; + /* want budlists unlocked when doing zbpg eviction */ + zbud_evict_zbpg(zbpg); + local_bh_enable(); + if (--nr <= 0) + goto out; + goto retry_unbud_list_i; + } + spin_unlock_bh(&zbud_budlists_spinlock); + } + + /* as a last resort, free buddied pages */ +retry_bud_list: + spin_lock_bh(&zbud_budlists_spinlock); + if (list_empty(&zbud_buddied_list)) { + spin_unlock_bh(&zbud_budlists_spinlock); + goto out; + } + list_for_each_entry(zbpg, &zbud_buddied_list, bud_list) { + if (unlikely(!spin_trylock(&zbpg->lock))) + continue; + list_del_init(&zbpg->bud_list); + zcache_zbud_buddied_count--; + spin_unlock(&zbud_budlists_spinlock); + zcache_evicted_buddied_pages++; + /* want budlists unlocked when doing zbpg eviction */ + zbud_evict_zbpg(zbpg); + local_bh_enable(); + if (--nr <= 0) + goto out; + goto retry_bud_list; + } + spin_unlock_bh(&zbud_budlists_spinlock); +out: + return; +} + +static void zbud_init(void) +{ + int i; + + INIT_LIST_HEAD(&zbud_buddied_list); + zcache_zbud_buddied_count = 0; + for (i = 0; i < NCHUNKS; i++) { + INIT_LIST_HEAD(&zbud_unbuddied[i].list); + zbud_unbuddied[i].count = 0; + } +} + +#ifdef CONFIG_SYSFS +/* + * These sysfs routines show a nice distribution of how many zbpg's are + * currently (and have ever been placed) in each unbuddied list. It's fun + * to watch but can probably go away before final merge. + */ +static int zbud_show_unbuddied_list_counts(char *buf) +{ + int i; + char *p = buf; + + for (i = 0; i < NCHUNKS - 1; i++) + p += sprintf(p, "%u ", zbud_unbuddied[i].count); + p += sprintf(p, "%d\n", zbud_unbuddied[i].count); + return p - buf; +} + +static int zbud_show_cumul_chunk_counts(char *buf) +{ + unsigned long i, chunks = 0, total_chunks = 0, sum_total_chunks = 0; + unsigned long total_chunks_lte_21 = 0, total_chunks_lte_32 = 0; + unsigned long total_chunks_lte_42 = 0; + char *p = buf; + + for (i = 0; i < NCHUNKS; i++) { + p += sprintf(p, "%lu ", zbud_cumul_chunk_counts[i]); + chunks += zbud_cumul_chunk_counts[i]; + total_chunks += zbud_cumul_chunk_counts[i]; + sum_total_chunks += i * zbud_cumul_chunk_counts[i]; + if (i == 21) + total_chunks_lte_21 = total_chunks; + if (i == 32) + total_chunks_lte_32 = total_chunks; + if (i == 42) + total_chunks_lte_42 = total_chunks; + } + p += sprintf(p, "<=21:%lu <=32:%lu <=42:%lu, mean:%lu\n", + total_chunks_lte_21, total_chunks_lte_32, total_chunks_lte_42, + chunks == 0 ? 0 : sum_total_chunks / chunks); + return p - buf; +} +#endif + +/********** + * This "zv" PAM implementation combines the TLSF-based xvMalloc + * with lzo1x compression to maximize the amount of data that can + * be packed into a physical page. + * + * Zv represents a PAM page with the index and object (plus a "size" value + * necessary for decompression) immediately preceding the compressed data. + */ + +#define ZVH_SENTINEL 0x43214321 + +struct zv_hdr { + uint32_t pool_id; + struct tmem_oid oid; + uint32_t index; + DECL_SENTINEL +}; + +static const int zv_max_page_size = (PAGE_SIZE / 8) * 7; + +static struct zv_hdr *zv_create(struct xv_pool *xvpool, uint32_t pool_id, + struct tmem_oid *oid, uint32_t index, + void *cdata, unsigned clen) +{ + struct page *page; + struct zv_hdr *zv = NULL; + uint32_t offset; + int ret; + + BUG_ON(!irqs_disabled()); + ret = xv_malloc(xvpool, clen + sizeof(struct zv_hdr), + &page, &offset, ZCACHE_GFP_MASK); + if (unlikely(ret)) + goto out; + zv = kmap_atomic(page, KM_USER0) + offset; + zv->index = index; + zv->oid = *oid; + zv->pool_id = pool_id; + SET_SENTINEL(zv, ZVH); + memcpy((char *)zv + sizeof(struct zv_hdr), cdata, clen); + kunmap_atomic(zv, KM_USER0); +out: + return zv; +} + +static void zv_free(struct xv_pool *xvpool, struct zv_hdr *zv) +{ + unsigned long flags; + struct page *page; + uint32_t offset; + uint16_t size; + + ASSERT_SENTINEL(zv, ZVH); + size = xv_get_object_size(zv) - sizeof(*zv); + BUG_ON(size == 0 || size > zv_max_page_size); + INVERT_SENTINEL(zv, ZVH); + page = virt_to_page(zv); + offset = (unsigned long)zv & ~PAGE_MASK; + local_irq_save(flags); + xv_free(xvpool, page, offset); + local_irq_restore(flags); +} + +static void zv_decompress(struct page *page, struct zv_hdr *zv) +{ + size_t clen = PAGE_SIZE; + char *to_va; + unsigned size; + int ret; + + ASSERT_SENTINEL(zv, ZVH); + size = xv_get_object_size(zv) - sizeof(*zv); + BUG_ON(size == 0 || size > zv_max_page_size); + to_va = kmap_atomic(page, KM_USER0); + ret = lzo1x_decompress_safe((char *)zv + sizeof(*zv), + size, to_va, &clen); + kunmap_atomic(to_va, KM_USER0); + BUG_ON(ret != LZO_E_OK); + BUG_ON(clen != PAGE_SIZE); +} + +/* + * zcache core code starts here + */ + +/* useful stats not collected by cleancache or frontswap */ +static unsigned long zcache_flush_total; +static unsigned long zcache_flush_found; +static unsigned long zcache_flobj_total; +static unsigned long zcache_flobj_found; +static unsigned long zcache_failed_eph_puts; +static unsigned long zcache_failed_pers_puts; + +#define MAX_POOLS_PER_CLIENT 16 + +static struct { + struct tmem_pool *tmem_pools[MAX_POOLS_PER_CLIENT]; + struct xv_pool *xvpool; +} zcache_client; + +/* + * Tmem operations assume the poolid implies the invoking client. + * Zcache only has one client (the kernel itself), so translate + * the poolid into the tmem_pool allocated for it. A KVM version + * of zcache would have one client per guest and each client might + * have a poolid==N. + */ +static struct tmem_pool *zcache_get_pool_by_id(uint32_t poolid) +{ + struct tmem_pool *pool = NULL; + + if (poolid >= 0) { + pool = zcache_client.tmem_pools[poolid]; + if (pool != NULL) + atomic_inc(&pool->refcount); + } + return pool; +} + +static void zcache_put_pool(struct tmem_pool *pool) +{ + if (pool != NULL) + atomic_dec(&pool->refcount); +} + +/* counters for debugging */ +static unsigned long zcache_failed_get_free_pages; +static unsigned long zcache_failed_alloc; +static unsigned long zcache_put_to_flush; +static unsigned long zcache_aborted_preload; +static unsigned long zcache_aborted_shrink; + +/* + * Ensure that memory allocation requests in zcache don't result + * in direct reclaim requests via the shrinker, which would cause + * an infinite loop. Maybe a GFP flag would be better? + */ +static DEFINE_SPINLOCK(zcache_direct_reclaim_lock); + +/* + * for now, used named slabs so can easily track usage; later can + * either just use kmalloc, or perhaps add a slab-like allocator + * to more carefully manage total memory utilization + */ +static struct kmem_cache *zcache_objnode_cache; +static struct kmem_cache *zcache_obj_cache; +static atomic_t zcache_curr_obj_count = ATOMIC_INIT(0); +static unsigned long zcache_curr_obj_count_max; +static atomic_t zcache_curr_objnode_count = ATOMIC_INIT(0); +static unsigned long zcache_curr_objnode_count_max; + +/* + * to avoid memory allocation recursion (e.g. due to direct reclaim), we + * preload all necessary data structures so the hostops callbacks never + * actually do a malloc + */ +struct zcache_preload { + void *page; + struct tmem_obj *obj; + int nr; + struct tmem_objnode *objnodes[OBJNODE_TREE_MAX_PATH]; +}; +static DEFINE_PER_CPU(struct zcache_preload, zcache_preloads) = { 0, }; + +static int zcache_do_preload(struct tmem_pool *pool) +{ + struct zcache_preload *kp; + struct tmem_objnode *objnode; + struct tmem_obj *obj; + void *page; + int ret = -ENOMEM; + + if (unlikely(zcache_objnode_cache == NULL)) + goto out; + if (unlikely(zcache_obj_cache == NULL)) + goto out; + if (!spin_trylock(&zcache_direct_reclaim_lock)) { + zcache_aborted_preload++; + goto out; + } + preempt_disable(); + kp = &__get_cpu_var(zcache_preloads); + while (kp->nr < ARRAY_SIZE(kp->objnodes)) { + preempt_enable_no_resched(); + objnode = kmem_cache_alloc(zcache_objnode_cache, + ZCACHE_GFP_MASK); + if (unlikely(objnode == NULL)) { + zcache_failed_alloc++; + goto unlock_out; + } + preempt_disable(); + kp = &__get_cpu_var(zcache_preloads); + if (kp->nr < ARRAY_SIZE(kp->objnodes)) + kp->objnodes[kp->nr++] = objnode; + else + kmem_cache_free(zcache_objnode_cache, objnode); + } + preempt_enable_no_resched(); + obj = kmem_cache_alloc(zcache_obj_cache, ZCACHE_GFP_MASK); + if (unlikely(obj == NULL)) { + zcache_failed_alloc++; + goto unlock_out; + } + page = (void *)__get_free_page(ZCACHE_GFP_MASK); + if (unlikely(page == NULL)) { + zcache_failed_get_free_pages++; + goto unlock_out; + } + preempt_disable(); + kp = &__get_cpu_var(zcache_preloads); + if (kp->obj == NULL) + kp->obj = obj; + else + kmem_cache_free(zcache_obj_cache, obj); + if (kp->page == NULL) + kp->page = page; + else + free_page((unsigned long)page); + ret = 0; +unlock_out: + spin_unlock(&zcache_direct_reclaim_lock); +out: + return ret; +} + +static void *zcache_get_free_page(void) +{ + struct zcache_preload *kp; + void *page; + + kp = &__get_cpu_var(zcache_preloads); + page = kp->page; + BUG_ON(page == NULL); + kp->page = NULL; + return page; +} + +static void zcache_free_page(void *p) +{ + free_page((unsigned long)p); +} + +/* + * zcache implementation for tmem host ops + */ + +static struct tmem_objnode *zcache_objnode_alloc(struct tmem_pool *pool) +{ + struct tmem_objnode *objnode = NULL; + unsigned long count; + struct zcache_preload *kp; + + kp = &__get_cpu_var(zcache_preloads); + if (kp->nr <= 0) + goto out; + objnode = kp->objnodes[kp->nr - 1]; + BUG_ON(objnode == NULL); + kp->objnodes[kp->nr - 1] = NULL; + kp->nr--; + count = atomic_inc_return(&zcache_curr_objnode_count); + if (count > zcache_curr_objnode_count_max) + zcache_curr_objnode_count_max = count; +out: + return objnode; +} + +static void zcache_objnode_free(struct tmem_objnode *objnode, + struct tmem_pool *pool) +{ + atomic_dec(&zcache_curr_objnode_count); + BUG_ON(atomic_read(&zcache_curr_objnode_count) < 0); + kmem_cache_free(zcache_objnode_cache, objnode); +} + +static struct tmem_obj *zcache_obj_alloc(struct tmem_pool *pool) +{ + struct tmem_obj *obj = NULL; + unsigned long count; + struct zcache_preload *kp; + + kp = &__get_cpu_var(zcache_preloads); + obj = kp->obj; + BUG_ON(obj == NULL); + kp->obj = NULL; + count = atomic_inc_return(&zcache_curr_obj_count); + if (count > zcache_curr_obj_count_max) + zcache_curr_obj_count_max = count; + return obj; +} + +static void zcache_obj_free(struct tmem_obj *obj, struct tmem_pool *pool) +{ + atomic_dec(&zcache_curr_obj_count); + BUG_ON(atomic_read(&zcache_curr_obj_count) < 0); + kmem_cache_free(zcache_obj_cache, obj); +} + +static struct tmem_hostops zcache_hostops = { + .obj_alloc = zcache_obj_alloc, + .obj_free = zcache_obj_free, + .objnode_alloc = zcache_objnode_alloc, + .objnode_free = zcache_objnode_free, +}; + +/* + * zcache implementations for PAM page descriptor ops + */ + +static atomic_t zcache_curr_eph_pampd_count = ATOMIC_INIT(0); +static unsigned long zcache_curr_eph_pampd_count_max; +static atomic_t zcache_curr_pers_pampd_count = ATOMIC_INIT(0); +static unsigned long zcache_curr_pers_pampd_count_max; + +/* forward reference */ +static int zcache_compress(struct page *from, void **out_va, size_t *out_len); + +static void *zcache_pampd_create(struct tmem_pool *pool, struct tmem_oid *oid, + uint32_t index, struct page *page) +{ + void *pampd = NULL, *cdata; + size_t clen; + int ret; + bool ephemeral = is_ephemeral(pool); + unsigned long count; + + if (ephemeral) { + ret = zcache_compress(page, &cdata, &clen); + if (ret == 0) + + goto out; + if (clen == 0 || clen > zbud_max_buddy_size()) { + zcache_compress_poor++; + goto out; + } + pampd = (void *)zbud_create(pool->pool_id, oid, index, + page, cdata, clen); + if (pampd != NULL) { + count = atomic_inc_return(&zcache_curr_eph_pampd_count); + if (count > zcache_curr_eph_pampd_count_max) + zcache_curr_eph_pampd_count_max = count; + } + } else { + /* + * FIXME: This is all the "policy" there is for now. + * 3/4 totpages should allow ~37% of RAM to be filled with + * compressed frontswap pages + */ + if (atomic_read(&zcache_curr_pers_pampd_count) > + 3 * totalram_pages / 4) + goto out; + ret = zcache_compress(page, &cdata, &clen); + if (ret == 0) + goto out; + if (clen > zv_max_page_size) { + zcache_compress_poor++; + goto out; + } + pampd = (void *)zv_create(zcache_client.xvpool, pool->pool_id, + oid, index, cdata, clen); + if (pampd == NULL) + goto out; + count = atomic_inc_return(&zcache_curr_pers_pampd_count); + if (count > zcache_curr_pers_pampd_count_max) + zcache_curr_pers_pampd_count_max = count; + } +out: + return pampd; +} + +/* + * fill the pageframe corresponding to the struct page with the data + * from the passed pampd + */ +static int zcache_pampd_get_data(struct page *page, void *pampd, + struct tmem_pool *pool) +{ + int ret = 0; + + if (is_ephemeral(pool)) + ret = zbud_decompress(page, pampd); + else + zv_decompress(page, pampd); + return ret; +} + +/* + * free the pampd and remove it from any zcache lists + * pampd must no longer be pointed to from any tmem data structures! + */ +static void zcache_pampd_free(void *pampd, struct tmem_pool *pool) +{ + if (is_ephemeral(pool)) { + zbud_free_and_delist((struct zbud_hdr *)pampd); + atomic_dec(&zcache_curr_eph_pampd_count); + BUG_ON(atomic_read(&zcache_curr_eph_pampd_count) < 0); + } else { + zv_free(zcache_client.xvpool, (struct zv_hdr *)pampd); + atomic_dec(&zcache_curr_pers_pampd_count); + BUG_ON(atomic_read(&zcache_curr_pers_pampd_count) < 0); + } +} + +static struct tmem_pamops zcache_pamops = { + .create = zcache_pampd_create, + .get_data = zcache_pampd_get_data, + .free = zcache_pampd_free, +}; + +/* + * zcache compression/decompression and related per-cpu stuff + */ + +#define LZO_WORKMEM_BYTES LZO1X_1_MEM_COMPRESS +#define LZO_DSTMEM_PAGE_ORDER 1 +static DEFINE_PER_CPU(unsigned char *, zcache_workmem); +static DEFINE_PER_CPU(unsigned char *, zcache_dstmem); + +static int zcache_compress(struct page *from, void **out_va, size_t *out_len) +{ + int ret = 0; + unsigned char *dmem = __get_cpu_var(zcache_dstmem); + unsigned char *wmem = __get_cpu_var(zcache_workmem); + char *from_va; + + BUG_ON(!irqs_disabled()); + if (unlikely(dmem == NULL || wmem == NULL)) + goto out; /* no buffer, so can't compress */ + from_va = kmap_atomic(from, KM_USER0); + mb(); + ret = lzo1x_1_compress(from_va, PAGE_SIZE, dmem, out_len, wmem); + BUG_ON(ret != LZO_E_OK); + *out_va = dmem; + kunmap_atomic(from_va, KM_USER0); + ret = 1; +out: + return ret; +} + + +static int zcache_cpu_notifier(struct notifier_block *nb, + unsigned long action, void *pcpu) +{ + int cpu = (long)pcpu; + struct zcache_preload *kp; + + switch (action) { + case CPU_UP_PREPARE: + per_cpu(zcache_dstmem, cpu) = (void *)__get_free_pages( + GFP_KERNEL | __GFP_REPEAT, + LZO_DSTMEM_PAGE_ORDER), + per_cpu(zcache_workmem, cpu) = + kzalloc(LZO1X_MEM_COMPRESS, + GFP_KERNEL | __GFP_REPEAT); + break; + case CPU_DEAD: + case CPU_UP_CANCELED: + free_pages((unsigned long)per_cpu(zcache_dstmem, cpu), + LZO_DSTMEM_PAGE_ORDER); + per_cpu(zcache_dstmem, cpu) = NULL; + kfree(per_cpu(zcache_workmem, cpu)); + per_cpu(zcache_workmem, cpu) = NULL; + kp = &per_cpu(zcache_preloads, cpu); + while (kp->nr) { + kmem_cache_free(zcache_objnode_cache, + kp->objnodes[kp->nr - 1]); + kp->objnodes[kp->nr - 1] = NULL; + kp->nr--; + } + kmem_cache_free(zcache_obj_cache, kp->obj); + free_page((unsigned long)kp->page); + break; + default: + break; + } + return NOTIFY_OK; +} + +static struct notifier_block zcache_cpu_notifier_block = { + .notifier_call = zcache_cpu_notifier +}; + +#ifdef CONFIG_SYSFS +#define ZCACHE_SYSFS_RO(_name) \ + static ssize_t zcache_##_name##_show(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf) \ + { \ + return sprintf(buf, "%lu\n", zcache_##_name); \ + } \ + static struct kobj_attribute zcache_##_name##_attr = { \ + .attr = { .name = __stringify(_name), .mode = 0444 }, \ + .show = zcache_##_name##_show, \ + } + +#define ZCACHE_SYSFS_RO_ATOMIC(_name) \ + static ssize_t zcache_##_name##_show(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf) \ + { \ + return sprintf(buf, "%d\n", atomic_read(&zcache_##_name)); \ + } \ + static struct kobj_attribute zcache_##_name##_attr = { \ + .attr = { .name = __stringify(_name), .mode = 0444 }, \ + .show = zcache_##_name##_show, \ + } + +#define ZCACHE_SYSFS_RO_CUSTOM(_name, _func) \ + static ssize_t zcache_##_name##_show(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf) \ + { \ + return _func(buf); \ + } \ + static struct kobj_attribute zcache_##_name##_attr = { \ + .attr = { .name = __stringify(_name), .mode = 0444 }, \ + .show = zcache_##_name##_show, \ + } + +ZCACHE_SYSFS_RO(curr_obj_count_max); +ZCACHE_SYSFS_RO(curr_objnode_count_max); +ZCACHE_SYSFS_RO(flush_total); +ZCACHE_SYSFS_RO(flush_found); +ZCACHE_SYSFS_RO(flobj_total); +ZCACHE_SYSFS_RO(flobj_found); +ZCACHE_SYSFS_RO(failed_eph_puts); +ZCACHE_SYSFS_RO(failed_pers_puts); +ZCACHE_SYSFS_RO(zbud_curr_zbytes); +ZCACHE_SYSFS_RO(zbud_cumul_zpages); +ZCACHE_SYSFS_RO(zbud_cumul_zbytes); +ZCACHE_SYSFS_RO(zbud_buddied_count); +ZCACHE_SYSFS_RO(zbpg_unused_list_count); +ZCACHE_SYSFS_RO(evicted_raw_pages); +ZCACHE_SYSFS_RO(evicted_unbuddied_pages); +ZCACHE_SYSFS_RO(evicted_buddied_pages); +ZCACHE_SYSFS_RO(failed_get_free_pages); +ZCACHE_SYSFS_RO(failed_alloc); +ZCACHE_SYSFS_RO(put_to_flush); +ZCACHE_SYSFS_RO(aborted_preload); +ZCACHE_SYSFS_RO(aborted_shrink); +ZCACHE_SYSFS_RO(compress_poor); +ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_raw_pages); +ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_zpages); +ZCACHE_SYSFS_RO_ATOMIC(curr_obj_count); +ZCACHE_SYSFS_RO_ATOMIC(curr_objnode_count); +ZCACHE_SYSFS_RO_CUSTOM(zbud_unbuddied_list_counts, + zbud_show_unbuddied_list_counts); +ZCACHE_SYSFS_RO_CUSTOM(zbud_cumul_chunk_counts, + zbud_show_cumul_chunk_counts); + +static struct attribute *zcache_attrs[] = { + &zcache_curr_obj_count_attr.attr, + &zcache_curr_obj_count_max_attr.attr, + &zcache_curr_objnode_count_attr.attr, + &zcache_curr_objnode_count_max_attr.attr, + &zcache_flush_total_attr.attr, + &zcache_flobj_total_attr.attr, + &zcache_flush_found_attr.attr, + &zcache_flobj_found_attr.attr, + &zcache_failed_eph_puts_attr.attr, + &zcache_failed_pers_puts_attr.attr, + &zcache_compress_poor_attr.attr, + &zcache_zbud_curr_raw_pages_attr.attr, + &zcache_zbud_curr_zpages_attr.attr, + &zcache_zbud_curr_zbytes_attr.attr, + &zcache_zbud_cumul_zpages_attr.attr, + &zcache_zbud_cumul_zbytes_attr.attr, + &zcache_zbud_buddied_count_attr.attr, + &zcache_zbpg_unused_list_count_attr.attr, + &zcache_evicted_raw_pages_attr.attr, + &zcache_evicted_unbuddied_pages_attr.attr, + &zcache_evicted_buddied_pages_attr.attr, + &zcache_failed_get_free_pages_attr.attr, + &zcache_failed_alloc_attr.attr, + &zcache_put_to_flush_attr.attr, + &zcache_aborted_preload_attr.attr, + &zcache_aborted_shrink_attr.attr, + &zcache_zbud_unbuddied_list_counts_attr.attr, + &zcache_zbud_cumul_chunk_counts_attr.attr, + NULL, +}; + +static struct attribute_group zcache_attr_group = { + .attrs = zcache_attrs, + .name = "zcache", +}; + +#endif /* CONFIG_SYSFS */ +/* + * When zcache is disabled ("frozen"), pools can be created and destroyed, + * but all puts (and thus all other operations that require memory allocation) + * must fail. If zcache is unfrozen, accepts puts, then frozen again, + * data consistency requires all puts while frozen to be converted into + * flushes. + */ +static bool zcache_freeze; + +/* + * zcache shrinker interface (only useful for ephemeral pages, so zbud only) + */ +static int shrink_zcache_memory(struct shrinker *shrink, int nr, gfp_t gfp_mask) +{ + int ret = -1; + + if (nr >= 0) { + if (!(gfp_mask & __GFP_FS)) + /* does this case really need to be skipped? */ + goto out; + if (spin_trylock(&zcache_direct_reclaim_lock)) { + zbud_evict_pages(nr); + spin_unlock(&zcache_direct_reclaim_lock); + } else + zcache_aborted_shrink++; + } + ret = (int)atomic_read(&zcache_zbud_curr_raw_pages); +out: + return ret; +} + +static struct shrinker zcache_shrinker = { + .shrink = shrink_zcache_memory, + .seeks = DEFAULT_SEEKS, +}; + +/* + * zcache shims between cleancache/frontswap ops and tmem + */ + +static int zcache_put_page(int pool_id, struct tmem_oid *oidp, + uint32_t index, struct page *page) +{ + struct tmem_pool *pool; + int ret = -1; + + BUG_ON(!irqs_disabled()); + pool = zcache_get_pool_by_id(pool_id); + if (unlikely(pool == NULL)) + goto out; + if (!zcache_freeze && zcache_do_preload(pool) == 0) { + /* preload does preempt_disable on success */ + ret = tmem_put(pool, oidp, index, page); + if (ret < 0) { + if (is_ephemeral(pool)) + zcache_failed_eph_puts++; + else + zcache_failed_pers_puts++; + } + zcache_put_pool(pool); + preempt_enable_no_resched(); + } else { + zcache_put_to_flush++; + if (atomic_read(&pool->obj_count) > 0) + /* the put fails whether the flush succeeds or not */ + (void)tmem_flush_page(pool, oidp, index); + zcache_put_pool(pool); + } +out: + return ret; +} + +static int zcache_get_page(int pool_id, struct tmem_oid *oidp, + uint32_t index, struct page *page) +{ + struct tmem_pool *pool; + int ret = -1; + unsigned long flags; + + local_irq_save(flags); + pool = zcache_get_pool_by_id(pool_id); + if (likely(pool != NULL)) { + if (atomic_read(&pool->obj_count) > 0) + ret = tmem_get(pool, oidp, index, page); + zcache_put_pool(pool); + } + local_irq_restore(flags); + return ret; +} + +static int zcache_flush_page(int pool_id, struct tmem_oid *oidp, uint32_t index) +{ + struct tmem_pool *pool; + int ret = -1; + unsigned long flags; + + local_irq_save(flags); + zcache_flush_total++; + pool = zcache_get_pool_by_id(pool_id); + if (likely(pool != NULL)) { + if (atomic_read(&pool->obj_count) > 0) + ret = tmem_flush_page(pool, oidp, index); + zcache_put_pool(pool); + } + if (ret >= 0) + zcache_flush_found++; + local_irq_restore(flags); + return ret; +} + +static int zcache_flush_object(int pool_id, struct tmem_oid *oidp) +{ + struct tmem_pool *pool; + int ret = -1; + unsigned long flags; + + local_irq_save(flags); + zcache_flobj_total++; + pool = zcache_get_pool_by_id(pool_id); + if (likely(pool != NULL)) { + if (atomic_read(&pool->obj_count) > 0) + ret = tmem_flush_object(pool, oidp); + zcache_put_pool(pool); + } + if (ret >= 0) + zcache_flobj_found++; + local_irq_restore(flags); + return ret; +} + +static int zcache_destroy_pool(int pool_id) +{ + struct tmem_pool *pool = NULL; + int ret = -1; + + if (pool_id < 0) + goto out; + pool = zcache_client.tmem_pools[pool_id]; + if (pool == NULL) + goto out; + zcache_client.tmem_pools[pool_id] = NULL; + /* wait for pool activity on other cpus to quiesce */ + while (atomic_read(&pool->refcount) != 0) + ; + local_bh_disable(); + ret = tmem_destroy_pool(pool); + local_bh_enable(); + kfree(pool); + pr_info("zcache: destroyed pool id=%d\n", pool_id); +out: + return ret; +} + +static int zcache_new_pool(uint32_t flags) +{ + int poolid = -1; + struct tmem_pool *pool; + + pool = kmalloc(sizeof(struct tmem_pool), GFP_KERNEL); + if (pool == NULL) { + pr_info("zcache: pool creation failed: out of memory\n"); + goto out; + } + + for (poolid = 0; poolid < MAX_POOLS_PER_CLIENT; poolid++) + if (zcache_client.tmem_pools[poolid] == NULL) + break; + if (poolid >= MAX_POOLS_PER_CLIENT) { + pr_info("zcache: pool creation failed: max exceeded\n"); + kfree(pool); + poolid = -1; + goto out; + } + atomic_set(&pool->refcount, 0); + pool->client = &zcache_client; + pool->pool_id = poolid; + tmem_new_pool(pool, flags); + zcache_client.tmem_pools[poolid] = pool; + pr_info("zcache: created %s tmem pool, id=%d\n", + flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral", + poolid); +out: + return poolid; +} + +/********** + * Two kernel functionalities currently can be layered on top of tmem. + * These are "cleancache" which is used as a second-chance cache for clean + * page cache pages; and "frontswap" which is used for swap pages + * to avoid writes to disk. A generic "shim" is provided here for each + * to translate in-kernel semantics to zcache semantics. + */ + +#ifdef CONFIG_CLEANCACHE +static void zcache_cleancache_put_page(int pool_id, + struct cleancache_filekey key, + pgoff_t index, struct page *page) +{ + u32 ind = (u32) index; + struct tmem_oid oid = *(struct tmem_oid *)&key; + + if (likely(ind == index)) + (void)zcache_put_page(pool_id, &oid, index, page); +} + +static int zcache_cleancache_get_page(int pool_id, + struct cleancache_filekey key, + pgoff_t index, struct page *page) +{ + u32 ind = (u32) index; + struct tmem_oid oid = *(struct tmem_oid *)&key; + int ret = -1; + + if (likely(ind == index)) + ret = zcache_get_page(pool_id, &oid, index, page); + return ret; +} + +static void zcache_cleancache_flush_page(int pool_id, + struct cleancache_filekey key, + pgoff_t index) +{ + u32 ind = (u32) index; + struct tmem_oid oid = *(struct tmem_oid *)&key; + + if (likely(ind == index)) + (void)zcache_flush_page(pool_id, &oid, ind); +} + +static void zcache_cleancache_flush_inode(int pool_id, + struct cleancache_filekey key) +{ + struct tmem_oid oid = *(struct tmem_oid *)&key; + + (void)zcache_flush_object(pool_id, &oid); +} + +static void zcache_cleancache_flush_fs(int pool_id) +{ + if (pool_id >= 0) + (void)zcache_destroy_pool(pool_id); +} + +static int zcache_cleancache_init_fs(size_t pagesize) +{ + BUG_ON(sizeof(struct cleancache_filekey) != + sizeof(struct tmem_oid)); + BUG_ON(pagesize != PAGE_SIZE); + return zcache_new_pool(0); +} + +static int zcache_cleancache_init_shared_fs(char *uuid, size_t pagesize) +{ + /* shared pools are unsupported and map to private */ + BUG_ON(sizeof(struct cleancache_filekey) != + sizeof(struct tmem_oid)); + BUG_ON(pagesize != PAGE_SIZE); + return zcache_new_pool(0); +} + +static struct cleancache_ops zcache_cleancache_ops = { + .put_page = zcache_cleancache_put_page, + .get_page = zcache_cleancache_get_page, + .flush_page = zcache_cleancache_flush_page, + .flush_inode = zcache_cleancache_flush_inode, + .flush_fs = zcache_cleancache_flush_fs, + .init_shared_fs = zcache_cleancache_init_shared_fs, + .init_fs = zcache_cleancache_init_fs +}; + +struct cleancache_ops zcache_cleancache_register_ops(void) +{ + struct cleancache_ops old_ops = + cleancache_register_ops(&zcache_cleancache_ops); + + return old_ops; +} +#endif + +#ifdef CONFIG_FRONTSWAP +/* a single tmem poolid is used for all frontswap "types" (swapfiles) */ +static int zcache_frontswap_poolid = -1; + +/* + * Swizzling increases objects per swaptype, increasing tmem concurrency + * for heavy swaploads. Later, larger nr_cpus -> larger SWIZ_BITS + */ +#define SWIZ_BITS 4 +#define SWIZ_MASK ((1 << SWIZ_BITS) - 1) +#define _oswiz(_type, _ind) ((_type << SWIZ_BITS) | (_ind & SWIZ_MASK)) +#define iswiz(_ind) (_ind >> SWIZ_BITS) + +static inline struct tmem_oid oswiz(unsigned type, u32 ind) +{ + struct tmem_oid oid = { .oid = { 0 } }; + oid.oid[0] = _oswiz(type, ind); + return oid; +} + +static int zcache_frontswap_put_page(unsigned type, pgoff_t offset, + struct page *page) +{ + u64 ind64 = (u64)offset; + u32 ind = (u32)offset; + struct tmem_oid oid = oswiz(type, ind); + int ret = -1; + unsigned long flags; + + BUG_ON(!PageLocked(page)); + if (likely(ind64 == ind)) { + local_irq_save(flags); + ret = zcache_put_page(zcache_frontswap_poolid, &oid, + iswiz(ind), page); + local_irq_restore(flags); + } + return ret; +} + +/* returns 0 if the page was successfully gotten from frontswap, -1 if + * was not present (should never happen!) */ +static int zcache_frontswap_get_page(unsigned type, pgoff_t offset, + struct page *page) +{ + u64 ind64 = (u64)offset; + u32 ind = (u32)offset; + struct tmem_oid oid = oswiz(type, ind); + int ret = -1; + + BUG_ON(!PageLocked(page)); + if (likely(ind64 == ind)) + ret = zcache_get_page(zcache_frontswap_poolid, &oid, + iswiz(ind), page); + return ret; +} + +/* flush a single page from frontswap */ +static void zcache_frontswap_flush_page(unsigned type, pgoff_t offset) +{ + u64 ind64 = (u64)offset; + u32 ind = (u32)offset; + struct tmem_oid oid = oswiz(type, ind); + + if (likely(ind64 == ind)) + (void)zcache_flush_page(zcache_frontswap_poolid, &oid, + iswiz(ind)); +} + +/* flush all pages from the passed swaptype */ +static void zcache_frontswap_flush_area(unsigned type) +{ + struct tmem_oid oid; + int ind; + + for (ind = SWIZ_MASK; ind >= 0; ind--) { + oid = oswiz(type, ind); + (void)zcache_flush_object(zcache_frontswap_poolid, &oid); + } +} + +static void zcache_frontswap_init(unsigned ignored) +{ + /* a single tmem poolid is used for all frontswap "types" (swapfiles) */ + if (zcache_frontswap_poolid < 0) + zcache_frontswap_poolid = zcache_new_pool(TMEM_POOL_PERSIST); +} + +static struct frontswap_ops zcache_frontswap_ops = { + .put_page = zcache_frontswap_put_page, + .get_page = zcache_frontswap_get_page, + .flush_page = zcache_frontswap_flush_page, + .flush_area = zcache_frontswap_flush_area, + .init = zcache_frontswap_init +}; + +struct frontswap_ops zcache_frontswap_register_ops(void) +{ + struct frontswap_ops old_ops = + frontswap_register_ops(&zcache_frontswap_ops); + + return old_ops; +} +#endif + +/* + * zcache initialization + * NOTE FOR NOW zcache MUST BE PROVIDED AS A KERNEL BOOT PARAMETER OR + * NOTHING HAPPENS! + */ + +static int zcache_enabled; + +static int __init enable_zcache(char *s) +{ + zcache_enabled = 1; + return 1; +} +__setup("zcache", enable_zcache); + +/* allow independent dynamic disabling of cleancache and frontswap */ + +static int use_cleancache = 1; + +static int __init no_cleancache(char *s) +{ + use_cleancache = 0; + return 1; +} + +__setup("nocleancache", no_cleancache); + +static int use_frontswap = 1; + +static int __init no_frontswap(char *s) +{ + use_frontswap = 0; + return 1; +} + +__setup("nofrontswap", no_frontswap); + +static int __init zcache_init(void) +{ +#ifdef CONFIG_SYSFS + int ret = 0; + + ret = sysfs_create_group(mm_kobj, &zcache_attr_group); + if (ret) { + pr_err("zcache: can't create sysfs\n"); + goto out; + } +#endif /* CONFIG_SYSFS */ +#if defined(CONFIG_CLEANCACHE) || defined(CONFIG_FRONTSWAP) + if (zcache_enabled) { + unsigned int cpu; + + tmem_register_hostops(&zcache_hostops); + tmem_register_pamops(&zcache_pamops); + ret = register_cpu_notifier(&zcache_cpu_notifier_block); + if (ret) { + pr_err("zcache: can't register cpu notifier\n"); + goto out; + } + for_each_online_cpu(cpu) { + void *pcpu = (void *)(long)cpu; + zcache_cpu_notifier(&zcache_cpu_notifier_block, + CPU_UP_PREPARE, pcpu); + } + } + zcache_objnode_cache = kmem_cache_create("zcache_objnode", + sizeof(struct tmem_objnode), 0, 0, NULL); + zcache_obj_cache = kmem_cache_create("zcache_obj", + sizeof(struct tmem_obj), 0, 0, NULL); +#endif +#ifdef CONFIG_CLEANCACHE + if (zcache_enabled && use_cleancache) { + struct cleancache_ops old_ops; + + zbud_init(); + register_shrinker(&zcache_shrinker); + old_ops = zcache_cleancache_register_ops(); + pr_info("zcache: cleancache enabled using kernel " + "transcendent memory and compression buddies\n"); + if (old_ops.init_fs != NULL) + pr_warning("zcache: cleancache_ops overridden"); + } +#endif +#ifdef CONFIG_FRONTSWAP + if (zcache_enabled && use_frontswap) { + struct frontswap_ops old_ops; + + zcache_client.xvpool = xv_create_pool(); + if (zcache_client.xvpool == NULL) { + pr_err("zcache: can't create xvpool\n"); + goto out; + } + old_ops = zcache_frontswap_register_ops(); + pr_info("zcache: frontswap enabled using kernel " + "transcendent memory and xvmalloc\n"); + if (old_ops.init != NULL) + pr_warning("ktmem: frontswap_ops overridden"); + } +#endif +out: + return ret; +} + +module_init(zcache_init) -- cgit v1.2.3 From 6630889735ec3d950b4f1496ada77df287d8ee1b Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Sun, 6 Feb 2011 19:27:09 -0800 Subject: staging: zcache: misc build/config [PATCH V2 3/3] drivers/staging: zcache: misc build/config Makefiles and Kconfigs to build zcache in drivers/staging There is a dependency on xvmalloc.* which in 2.6.37 resides in drivers/staging/zram. Should this move or disappear, some Makefile/Kconfig changes will be required. Signed-off-by: Dan Magenheimer Signed-off-by: Nitin Gupta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 ++ drivers/staging/Makefile | 1 + drivers/staging/zcache/Kconfig | 13 +++++++++++++ drivers/staging/zcache/Makefile | 1 + 4 files changed, 17 insertions(+) create mode 100644 drivers/staging/zcache/Kconfig create mode 100644 drivers/staging/zcache/Makefile (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index b80755da5394..118bf525b931 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -127,6 +127,8 @@ source "drivers/staging/cs5535_gpio/Kconfig" source "drivers/staging/zram/Kconfig" +source "drivers/staging/zcache/Kconfig" + source "drivers/staging/wlags49_h2/Kconfig" source "drivers/staging/wlags49_h25/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index fd26509e5efa..625bae215eda 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_DX_SEP) += sep/ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio/ obj-$(CONFIG_ZRAM) += zram/ +obj-$(CONFIG_ZCACHE) += zcache/ obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/ obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop/ diff --git a/drivers/staging/zcache/Kconfig b/drivers/staging/zcache/Kconfig new file mode 100644 index 000000000000..7fabcb2bc80d --- /dev/null +++ b/drivers/staging/zcache/Kconfig @@ -0,0 +1,13 @@ +config ZCACHE + tristate "Dynamic compression of swap pages and clean pagecache pages" + depends on CLEANCACHE || FRONTSWAP + select XVMALLOC + select LZO_COMPRESS + select LZO_DECOMPRESS + default n + help + Zcache doubles RAM efficiency while providing a significant + performance boosts on many workloads. Zcache uses lzo1x + compression and an in-kernel implementation of transcendent + memory to store clean page cache pages and swap in RAM, + providing a noticeable reduction in disk I/O. diff --git a/drivers/staging/zcache/Makefile b/drivers/staging/zcache/Makefile new file mode 100644 index 000000000000..7f64de4dff3b --- /dev/null +++ b/drivers/staging/zcache/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_ZCACHE) += zcache.o tmem.o -- cgit v1.2.3 From 26e805544a5dfd22b3def27b4c2363cd81a40467 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Wed, 9 Feb 2011 21:21:39 +0100 Subject: staging: brcm80211: fix build with BCMDBG unset. These changes are fixing some build problem I had when compiling without BCMDBG being set. Signed-off-by: Hauke Mehrtens Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdbus.h | 2 +- drivers/staging/brcm80211/brcmfmac/dhd_common.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 6 ++++++ drivers/staging/brcm80211/include/bcmsdh.h | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h b/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h index 89059dd8088b..b020a301341f 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h @@ -58,7 +58,7 @@ extern SDIOH_API_RC sdioh_interrupt_query(sdioh_info_t *si, bool *onoff); /* enable or disable SD interrupt */ extern SDIOH_API_RC sdioh_interrupt_set(sdioh_info_t *si, bool enable_disable); -#if defined(BCMDBG) +#if defined(DHD_DEBUG) extern bool sdioh_interrupt_pending(sdioh_info_t *si); #endif diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index 5165251cfe2f..eeabbc3334d4 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -57,8 +57,8 @@ void dhd_iscan_unlock(void); #error DHD_SDALIGN is not a power of 2! #endif -#ifdef DHD_DEBUG #define EPI_VERSION_STR "4.218.248.5" +#ifdef DHD_DEBUG const char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR "\nCompiled on " __DATE__ " at " __TIME__; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index d64171ff12aa..b05a491f3f62 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -6327,6 +6327,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, (u16) newfragthresh; } } +#if defined(BCMDBG) } else WL_ERROR("wl%d: %s txop invalid for rate %d\n", wlc->pub->unit, fifo_names[queue], @@ -6338,6 +6339,9 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, fifo_names[queue], phylen, wlc->fragthresh[queue], dur, wlc->edcf_txop[ac]); +#else + } +#endif } } @@ -6607,7 +6611,9 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) if (txs->phyerr) { WL_ERROR("phyerr 0x%x, rate 0x%x\n", txs->phyerr, txh->MainRates); +#if defined(BCMDBG) wlc_print_txdesc(txh); +#endif wlc_print_txstatus(txs); } diff --git a/drivers/staging/brcm80211/include/bcmsdh.h b/drivers/staging/brcm80211/include/bcmsdh.h index 90a600de7a3a..aa5f372d58cc 100644 --- a/drivers/staging/brcm80211/include/bcmsdh.h +++ b/drivers/staging/brcm80211/include/bcmsdh.h @@ -58,7 +58,7 @@ extern int bcmsdh_intr_disable(void *sdh); extern int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh); extern int bcmsdh_intr_dereg(void *sdh); -#if defined(BCMDBG) +#if defined(DHD_DEBUG) /* Query pending interrupt status from the host controller */ extern bool bcmsdh_intr_pending(void *sdh); #endif -- cgit v1.2.3 From 414ed90cee32486c50f91b28990443e0dc21c868 Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Thu, 10 Feb 2011 14:11:28 +0000 Subject: IB/qib: Fix double add_timer() The following panic BUG_ON occurs during qib testing: Kernel BUG at include/linux/timer.h:82 RIP [] :ib_qib:start_timer+0x73/0x89 RSP <0>Kernel panic - not syncing: Fatal exception <0>Dumping qib trace buffer from panic qib_set_lid INFO: IB0:1 got a lid: 0xf8 Done dumping qib trace buffer BUG: warning at kernel/panic.c:137/panic() (Tainted: G The flaw is due to a missing state test when processing responses that results in an add_timer() call when the same timer is already queued. This code was executing in parallel with a QP destroy on another CPU that had changed the state to reset, but the missing test caused to response handling code to run on into the panic. Signed-off-by: Mike Marciniszyn Signed-off-by: Roland Dreier --- drivers/infiniband/hw/qib/qib_rc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/hw/qib/qib_rc.c b/drivers/infiniband/hw/qib/qib_rc.c index 8245237b67ce..31e09b05a1a7 100644 --- a/drivers/infiniband/hw/qib/qib_rc.c +++ b/drivers/infiniband/hw/qib/qib_rc.c @@ -1439,6 +1439,8 @@ static void qib_rc_rcv_resp(struct qib_ibport *ibp, } spin_lock_irqsave(&qp->s_lock, flags); + if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) + goto ack_done; /* Ignore invalid responses. */ if (qib_cmp24(psn, qp->s_next_psn) >= 0) -- cgit v1.2.3 From 2866d956fe0ad8fc8d8a7c54104ccc879b49406d Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Thu, 10 Feb 2011 20:06:46 -0800 Subject: tg3: Expand 5719 workaround As a precautionary measure, expand the fix submitted in commit 4d163b75e979833979cc401ae433cb1d7743d57e entitled "tg3: Fix 5719 A0 tx completion bug" to apply to all 5719 revisions. Signed-off-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index cc069528b322..ecb3eb099bf6 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -13318,7 +13318,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) } /* Determine TSO capabilities */ - if (tp->pci_chip_rev_id == CHIPREV_ID_5719_A0) + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) ; /* Do nothing. HW bug. */ else if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) tp->tg3_flags2 |= TG3_FLG2_HW_TSO_3; @@ -13372,7 +13372,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) } if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) && - tp->pci_chip_rev_id != CHIPREV_ID_5719_A0) + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719) tp->tg3_flags3 |= TG3_FLG3_USE_JUMBO_BDFLAG; if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) || -- cgit v1.2.3 From 0fbc9fdb7e747500111dcc4a5f5f3ceed0360d71 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 4 Feb 2011 00:37:26 -0800 Subject: Input: ads7846 - check proper condition when freeing gpio When driver uses custom pendown detection method gpio_pendown is not set up and so we should not try to free it, otherwise we are presented with: ------------[ cut here ]------------ WARNING: at drivers/gpio/gpiolib.c:1258 gpio_free+0x100/0x12c() Modules linked in: [] (unwind_backtrace+0x0/0xe4) from [](warn_slowpath_common+0x4c/0x64) [] (warn_slowpath_common+0x4c/0x64) from [](warn_slowpath_null+0x18/0x1c) [] (warn_slowpath_null+0x18/0x1c) from [](gpio_free+0x100/0x12c) [] (gpio_free+0x100/0x12c) from [](ads7846_probe+0xa38/0xc5c) [] (ads7846_probe+0xa38/0xc5c) from [](spi_drv_probe+0x18/0x1c) [] (spi_drv_probe+0x18/0x1c) from [](driver_probe_device+0xc8/0x184) [] (driver_probe_device+0xc8/0x184) from [](__driver_attach+0x68/0x8c) [] (__driver_attach+0x68/0x8c) from [](bus_for_each_dev+0x48/0x74) [] (bus_for_each_dev+0x48/0x74) from [](bus_add_driver+0xa0/0x220) [] (bus_add_driver+0xa0/0x220) from [](driver_register+0xa8/0x134) [] (driver_register+0xa8/0x134) from [](do_one_initcall+0xcc/0x1a4) [] (do_one_initcall+0xcc/0x1a4) from [](kernel_init+0x14c/0x214) [] (kernel_init+0x14c/0x214) from [](kernel_thread_exit+0x0/0x8) ---[ end trace 4053287f8a5ec18f ]--- Also rearrange ads7846_setup_pendown() to have only one exit point returning success. Reported-by: Sourav Poddar Acked-by: Wolfram Sang Reviewed-by: Charulatha V Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ads7846.c | 38 +++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 14ea54b78e46..4bf2316e3284 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -941,28 +941,29 @@ static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads784 struct ads7846_platform_data *pdata = spi->dev.platform_data; int err; - /* REVISIT when the irq can be triggered active-low, or if for some + /* + * REVISIT when the irq can be triggered active-low, or if for some * reason the touchscreen isn't hooked up, we don't need to access * the pendown state. */ - if (!pdata->get_pendown_state && !gpio_is_valid(pdata->gpio_pendown)) { - dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); - return -EINVAL; - } if (pdata->get_pendown_state) { ts->get_pendown_state = pdata->get_pendown_state; - return 0; - } + } else if (gpio_is_valid(pdata->gpio_pendown)) { - err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); - if (err) { - dev_err(&spi->dev, "failed to request pendown GPIO%d\n", - pdata->gpio_pendown); - return err; - } + err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); + if (err) { + dev_err(&spi->dev, "failed to request pendown GPIO%d\n", + pdata->gpio_pendown); + return err; + } - ts->gpio_pendown = pdata->gpio_pendown; + ts->gpio_pendown = pdata->gpio_pendown; + + } else { + dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); + return -EINVAL; + } return 0; } @@ -1353,7 +1354,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) err_put_regulator: regulator_put(ts->reg); err_free_gpio: - if (ts->gpio_pendown != -1) + if (!ts->get_pendown_state) gpio_free(ts->gpio_pendown); err_cleanup_filter: if (ts->filter_cleanup) @@ -1383,8 +1384,13 @@ static int __devexit ads7846_remove(struct spi_device *spi) regulator_disable(ts->reg); regulator_put(ts->reg); - if (ts->gpio_pendown != -1) + if (!ts->get_pendown_state) { + /* + * If we are not using specialized pendown method we must + * have been relying on gpio we set up ourselves. + */ gpio_free(ts->gpio_pendown); + } if (ts->filter_cleanup) ts->filter_cleanup(ts->filter_data); -- cgit v1.2.3 From 4b6d44344000ff3e62faf595e5f89fd8d9e52a94 Mon Sep 17 00:00:00 2001 From: Alexander Strakh Date: Fri, 11 Feb 2011 00:44:41 -0800 Subject: Input: wacom - fix error path in wacom_probe() If we fail to retrieve HID descriptor we need to free allocated URB so jump to proper label to do that. Signed-off-by: Alexander Strakh Acked-by: Henrik Rydberg Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index fc381498b798..cf8fb9f5d4a8 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -519,7 +519,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i /* Retrieve the physical and logical size for OEM devices */ error = wacom_retrieve_hid_descriptor(intf, features); if (error) - goto fail2; + goto fail3; wacom_setup_device_quirks(features); -- cgit v1.2.3 From 1aad7ac0458f40e2d0365d488620084f3965f6e7 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 9 Feb 2011 18:46:58 +0000 Subject: drm/i915: Trigger modesetting if force-audio changes If the user changes the force-audio property and it no longer reflects the current configuration, then we need to trigger a mode set in order to update the registers. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_dp.c | 36 ++++++++++++++++++++++++++++++------ drivers/gpu/drm/i915/intel_hdmi.c | 39 +++++++++++++++++++++++++++++++++------ drivers/gpu/drm/i915/intel_sdvo.c | 34 ++++++++++++++++++++++++++++------ 3 files changed, 91 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1f4242b682c8..51cb4e36997f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1639,6 +1639,24 @@ static int intel_dp_get_modes(struct drm_connector *connector) return 0; } +static bool +intel_dp_detect_audio(struct drm_connector *connector) +{ + struct intel_dp *intel_dp = intel_attached_dp(connector); + struct edid *edid; + bool has_audio = false; + + edid = drm_get_edid(connector, &intel_dp->adapter); + if (edid) { + has_audio = drm_detect_monitor_audio(edid); + + connector->display_info.raw_edid = NULL; + kfree(edid); + } + + return has_audio; +} + static int intel_dp_set_property(struct drm_connector *connector, struct drm_property *property, @@ -1652,17 +1670,23 @@ intel_dp_set_property(struct drm_connector *connector, return ret; if (property == intel_dp->force_audio_property) { - if (val == intel_dp->force_audio) + int i = val; + bool has_audio; + + if (i == intel_dp->force_audio) return 0; - intel_dp->force_audio = val; + intel_dp->force_audio = i; - if (val > 0 && intel_dp->has_audio) - return 0; - if (val < 0 && !intel_dp->has_audio) + if (i == 0) + has_audio = intel_dp_detect_audio(connector); + else + has_audio = i > 0; + + if (has_audio == intel_dp->has_audio) return 0; - intel_dp->has_audio = val > 0; + intel_dp->has_audio = has_audio; goto done; } diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 0d0273e7b029..c635c9e357b9 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -251,6 +251,27 @@ static int intel_hdmi_get_modes(struct drm_connector *connector) &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter); } +static bool +intel_hdmi_detect_audio(struct drm_connector *connector) +{ + struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); + struct drm_i915_private *dev_priv = connector->dev->dev_private; + struct edid *edid; + bool has_audio = false; + + edid = drm_get_edid(connector, + &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter); + if (edid) { + if (edid->input & DRM_EDID_INPUT_DIGITAL) + has_audio = drm_detect_monitor_audio(edid); + + connector->display_info.raw_edid = NULL; + kfree(edid); + } + + return has_audio; +} + static int intel_hdmi_set_property(struct drm_connector *connector, struct drm_property *property, @@ -264,17 +285,23 @@ intel_hdmi_set_property(struct drm_connector *connector, return ret; if (property == intel_hdmi->force_audio_property) { - if (val == intel_hdmi->force_audio) + int i = val; + bool has_audio; + + if (i == intel_hdmi->force_audio) return 0; - intel_hdmi->force_audio = val; + intel_hdmi->force_audio = i; - if (val > 0 && intel_hdmi->has_audio) - return 0; - if (val < 0 && !intel_hdmi->has_audio) + if (i == 0) + has_audio = intel_hdmi_detect_audio(connector); + else + has_audio = i > 0; + + if (has_audio == intel_hdmi->has_audio) return 0; - intel_hdmi->has_audio = val > 0; + intel_hdmi->has_audio = has_audio; goto done; } diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d2dd90a9a101..7c50cdce84f0 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1690,6 +1690,22 @@ static void intel_sdvo_destroy(struct drm_connector *connector) kfree(connector); } +static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector) +{ + struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); + struct edid *edid; + bool has_audio = false; + + if (!intel_sdvo->is_hdmi) + return false; + + edid = intel_sdvo_get_edid(connector); + if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL) + has_audio = drm_detect_monitor_audio(edid); + + return has_audio; +} + static int intel_sdvo_set_property(struct drm_connector *connector, struct drm_property *property, @@ -1706,17 +1722,23 @@ intel_sdvo_set_property(struct drm_connector *connector, return ret; if (property == intel_sdvo_connector->force_audio_property) { - if (val == intel_sdvo_connector->force_audio) + int i = val; + bool has_audio; + + if (i == intel_sdvo_connector->force_audio) return 0; - intel_sdvo_connector->force_audio = val; + intel_sdvo_connector->force_audio = i; - if (val > 0 && intel_sdvo->has_hdmi_audio) - return 0; - if (val < 0 && !intel_sdvo->has_hdmi_audio) + if (i == 0) + has_audio = intel_sdvo_detect_hdmi_audio(connector); + else + has_audio = i > 0; + + if (has_audio == intel_sdvo->has_hdmi_audio) return 0; - intel_sdvo->has_hdmi_audio = val > 0; + intel_sdvo->has_hdmi_audio = has_audio; goto done; } -- cgit v1.2.3 From 8102e126c0827b5336065fd86d3d313b60fde23a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 10 Feb 2011 10:05:35 +0000 Subject: drm/i915/tv: Use polling rather than interrupt-based hotplug The documentation recommends that we should use a polling method for TV detection as this is more power efficient than the interrupt based mechanism (as the encoder can be completely switched off). A secondary effect is that leaving the hotplug enabled seems to be causing pipe underruns as reported by Hugh Dickins on his Crestline. Tested-by: Hugh Dickins Signed-off-by: Chris Wilson [This is a candidate for stable, but needs minor porting to 2.6.37] --- drivers/gpu/drm/i915/intel_tv.c | 43 ++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 93206e4eaa6f..fe4a53a50b83 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -1234,7 +1234,8 @@ static const struct drm_display_mode reported_modes[] = { * \return false if TV is disconnected. */ static int -intel_tv_detect_type (struct intel_tv *intel_tv) +intel_tv_detect_type (struct intel_tv *intel_tv, + struct drm_connector *connector) { struct drm_encoder *encoder = &intel_tv->base.base; struct drm_device *dev = encoder->dev; @@ -1245,11 +1246,13 @@ intel_tv_detect_type (struct intel_tv *intel_tv) int type; /* Disable TV interrupts around load detect or we'll recurse */ - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - i915_disable_pipestat(dev_priv, 0, - PIPE_HOTPLUG_INTERRUPT_ENABLE | - PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + if (connector->polled & DRM_CONNECTOR_POLL_HPD) { + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + i915_disable_pipestat(dev_priv, 0, + PIPE_HOTPLUG_INTERRUPT_ENABLE | + PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + } save_tv_dac = tv_dac = I915_READ(TV_DAC); save_tv_ctl = tv_ctl = I915_READ(TV_CTL); @@ -1302,11 +1305,13 @@ intel_tv_detect_type (struct intel_tv *intel_tv) I915_WRITE(TV_CTL, save_tv_ctl); /* Restore interrupt config */ - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - i915_enable_pipestat(dev_priv, 0, - PIPE_HOTPLUG_INTERRUPT_ENABLE | - PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + if (connector->polled & DRM_CONNECTOR_POLL_HPD) { + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + i915_enable_pipestat(dev_priv, 0, + PIPE_HOTPLUG_INTERRUPT_ENABLE | + PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + } return type; } @@ -1356,7 +1361,7 @@ intel_tv_detect(struct drm_connector *connector, bool force) drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); if (intel_tv->base.base.crtc && intel_tv->base.base.crtc->enabled) { - type = intel_tv_detect_type(intel_tv); + type = intel_tv_detect_type(intel_tv, connector); } else if (force) { struct drm_crtc *crtc; int dpms_mode; @@ -1364,7 +1369,7 @@ intel_tv_detect(struct drm_connector *connector, bool force) crtc = intel_get_load_detect_pipe(&intel_tv->base, connector, &mode, &dpms_mode); if (crtc) { - type = intel_tv_detect_type(intel_tv); + type = intel_tv_detect_type(intel_tv, connector); intel_release_load_detect_pipe(&intel_tv->base, connector, dpms_mode); } else @@ -1658,6 +1663,18 @@ intel_tv_init(struct drm_device *dev) intel_encoder = &intel_tv->base; connector = &intel_connector->base; + /* The documentation, for the older chipsets at least, recommend + * using a polling method rather than hotplug detection for TVs. + * This is because in order to perform the hotplug detection, the PLLs + * for the TV must be kept alive increasing power drain and starving + * bandwidth from other encoders. Notably for instance, it causes + * pipe underruns on Crestline when this encoder is supposedly idle. + * + * More recent chipsets favour HDMI rather than integrated S-Video. + */ + connector->polled = + DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; + drm_connector_init(dev, connector, &intel_tv_connector_funcs, DRM_MODE_CONNECTOR_SVIDEO); -- cgit v1.2.3 From 04dbff52600719017598f7439bf42e5a72e7de3b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 10 Feb 2011 17:38:35 +0000 Subject: drm/i915: Fix resume regression from 5d1d0cc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The irony of the patch to fix the resume regression on PineView causing a further regression on Ironlake is not lost on me. Reported-by: Jeff Chua Reported-by: Björn Schließmann Tested-by: Björn Schließmann Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=28802 Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 94622e3a202e..3b006536b3d2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5558,9 +5558,7 @@ static void intel_crtc_reset(struct drm_crtc *crtc) /* Reset flags back to the 'unknown' status so that they * will be correctly set on the initial modeset. */ - intel_crtc->cursor_addr = 0; intel_crtc->dpms_mode = -1; - intel_crtc->active = true; /* force the pipe off on setup_init_config */ } static struct drm_crtc_helper_funcs intel_helper_funcs = { @@ -5666,6 +5664,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; intel_crtc_reset(&intel_crtc->base); + intel_crtc->active = true; /* force the pipe off on setup_init_config */ if (HAS_PCH_SPLIT(dev)) { intel_helper_funcs.prepare = ironlake_crtc_prepare; -- cgit v1.2.3 From 79f5e840143703b258717aab12647018320f4a5f Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 19 Jan 2011 04:20:59 +0000 Subject: e1000e: replace unbounded sprintf with snprintf Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/netdev.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 6025d5fb12a4..7cedfeb505b2 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -1843,7 +1843,9 @@ static int e1000_request_msix(struct e1000_adapter *adapter) int err = 0, vector = 0; if (strlen(netdev->name) < (IFNAMSIZ - 5)) - sprintf(adapter->rx_ring->name, "%s-rx-0", netdev->name); + snprintf(adapter->rx_ring->name, + sizeof(adapter->rx_ring->name) - 1, + "%s-rx-0", netdev->name); else memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ); err = request_irq(adapter->msix_entries[vector].vector, @@ -1856,7 +1858,9 @@ static int e1000_request_msix(struct e1000_adapter *adapter) vector++; if (strlen(netdev->name) < (IFNAMSIZ - 5)) - sprintf(adapter->tx_ring->name, "%s-tx-0", netdev->name); + snprintf(adapter->tx_ring->name, + sizeof(adapter->tx_ring->name) - 1, + "%s-tx-0", netdev->name); else memcpy(adapter->tx_ring->name, netdev->name, IFNAMSIZ); err = request_irq(adapter->msix_entries[vector].vector, -- cgit v1.2.3 From 5c1bda0aa32e4614c32a45ce5662ed6914bae38a Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 19 Jan 2011 04:23:39 +0000 Subject: e1000e: use correct pointer when memcpy'ing a 2-dimensional array *e1000_gstrings_test is not the same size as e1000_gstrings_test. Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index daa7fe4b9fdd..0c0859925468 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -2006,7 +2006,7 @@ static void e1000_get_strings(struct net_device *netdev, u32 stringset, switch (stringset) { case ETH_SS_TEST: - memcpy(data, *e1000_gstrings_test, sizeof(e1000_gstrings_test)); + memcpy(data, e1000_gstrings_test, sizeof(e1000_gstrings_test)); break; case ETH_SS_STATS: for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { -- cgit v1.2.3 From 5962bc21ceaaba81e04fa1bb5671c65251805d3e Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Thu, 20 Jan 2011 06:58:07 +0000 Subject: e1000e: return appropriate errors for 'ethtool -r' ...when invoked while interface is not up or when auto-negotiation is disabled as done by other drivers. Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/ethtool.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 0c0859925468..65ef9b5548d8 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -1963,8 +1963,15 @@ static int e1000_set_coalesce(struct net_device *netdev, static int e1000_nway_reset(struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); - if (netif_running(netdev)) - e1000e_reinit_locked(adapter); + + if (!netif_running(netdev)) + return -EAGAIN; + + if (!adapter->hw.mac.autoneg) + return -EINVAL; + + e1000e_reinit_locked(adapter); + return 0; } -- cgit v1.2.3 From 6b78bb1d46cfae6502826ec31a6e9f7222ab3cb4 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Thu, 20 Jan 2011 06:40:45 +0000 Subject: igb: Enable PF side of SR-IOV support for i350 devices This patch adds full support for SR-IOV by enabling the PF side. VF side has already been committed. Signed-off-by: Carolyn Wyborny Signed-off-by: Jeff Kirsher --- drivers/net/igb/e1000_82575.c | 10 ++++++++-- drivers/net/igb/e1000_mbx.c | 38 ++++++++++++++++++-------------------- drivers/net/igb/igb_main.c | 9 +++++++-- 3 files changed, 33 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index c1552b6f4a68..65c1833244f7 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -238,9 +238,15 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) size = 14; nvm->word_size = 1 << size; - /* if 82576 then initialize mailbox parameters */ - if (mac->type == e1000_82576) + /* if part supports SR-IOV then initialize mailbox parameters */ + switch (mac->type) { + case e1000_82576: + case e1000_i350: igb_init_mbx_params_pf(hw); + break; + default: + break; + } /* setup PHY parameters */ if (phy->media_type != e1000_media_type_copper) { diff --git a/drivers/net/igb/e1000_mbx.c b/drivers/net/igb/e1000_mbx.c index c474cdb70047..78d48c7fa859 100644 --- a/drivers/net/igb/e1000_mbx.c +++ b/drivers/net/igb/e1000_mbx.c @@ -422,26 +422,24 @@ s32 igb_init_mbx_params_pf(struct e1000_hw *hw) { struct e1000_mbx_info *mbx = &hw->mbx; - if (hw->mac.type == e1000_82576) { - mbx->timeout = 0; - mbx->usec_delay = 0; - - mbx->size = E1000_VFMAILBOX_SIZE; - - mbx->ops.read = igb_read_mbx_pf; - mbx->ops.write = igb_write_mbx_pf; - mbx->ops.read_posted = igb_read_posted_mbx; - mbx->ops.write_posted = igb_write_posted_mbx; - mbx->ops.check_for_msg = igb_check_for_msg_pf; - mbx->ops.check_for_ack = igb_check_for_ack_pf; - mbx->ops.check_for_rst = igb_check_for_rst_pf; - - mbx->stats.msgs_tx = 0; - mbx->stats.msgs_rx = 0; - mbx->stats.reqs = 0; - mbx->stats.acks = 0; - mbx->stats.rsts = 0; - } + mbx->timeout = 0; + mbx->usec_delay = 0; + + mbx->size = E1000_VFMAILBOX_SIZE; + + mbx->ops.read = igb_read_mbx_pf; + mbx->ops.write = igb_write_mbx_pf; + mbx->ops.read_posted = igb_read_posted_mbx; + mbx->ops.write_posted = igb_write_posted_mbx; + mbx->ops.check_for_msg = igb_check_for_msg_pf; + mbx->ops.check_for_ack = igb_check_for_ack_pf; + mbx->ops.check_for_rst = igb_check_for_rst_pf; + + mbx->stats.msgs_tx = 0; + mbx->stats.msgs_rx = 0; + mbx->stats.reqs = 0; + mbx->stats.acks = 0; + mbx->stats.rsts = 0; return 0; } diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 200cc3209672..cb6bf7b815ae 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -2287,9 +2287,14 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter) spin_lock_init(&adapter->stats64_lock); #ifdef CONFIG_PCI_IOV - if (hw->mac.type == e1000_82576) + switch (hw->mac.type) { + case e1000_82576: + case e1000_i350: adapter->vfs_allocated_count = (max_vfs > 7) ? 7 : max_vfs; - + break; + default: + break; + } #endif /* CONFIG_PCI_IOV */ adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES, num_online_cpus()); -- cgit v1.2.3 From 53bb9f80b3be855a369a8a580621cda8e3bbaae2 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 1 Feb 2011 02:10:20 +0000 Subject: ixgbe: DCB, only reprogram HW if the FCoE priority is changed If the FCoE priority is not changing do not set the RESET and APP_UPCHG bits. This causes unneeded HW resets and which can cause unneeded LLDP frames and negotiations. The current check is not sufficient because the FCoE priority can change twice during a negotiation which results in the bits being set. This occurs when the switch changes the priority or when the link is reset with switches that do not include the APP priority until after PFC has been negotiated. This results in set_app being called with the local APP priority. Then the negotiation completes and set_app is called again with the peer APP priority. The check fails so the device is reset and the above occurs again resulting in an endless loop of resets. By only resetting the device if the APP priority has really changed we short circuit the loop. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb_nl.c | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index bf566e8a455e..48058359ba69 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -353,6 +353,7 @@ static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority, static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); + bool do_reset; int ret; if (!adapter->dcb_set_bitmap) @@ -368,7 +369,9 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) * Only take down the adapter if the configuration change * requires a reset. */ - if (adapter->dcb_set_bitmap & BIT_RESETLINK) { + do_reset = adapter->dcb_set_bitmap & (BIT_RESETLINK | BIT_APP_UPCHG); + + if (do_reset) { while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) msleep(1); @@ -408,7 +411,7 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) } } - if (adapter->dcb_set_bitmap & BIT_RESETLINK) { + if (do_reset) { if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) { ixgbe_init_interrupt_scheme(adapter); if (netif_running(netdev)) @@ -430,7 +433,7 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) if (adapter->dcb_cfg.pfc_mode_enable) adapter->hw.fc.current_mode = ixgbe_fc_pfc; - if (adapter->dcb_set_bitmap & BIT_RESETLINK) + if (do_reset) clear_bit(__IXGBE_RESETTING, &adapter->state); adapter->dcb_set_bitmap = 0x00; return ret; @@ -568,18 +571,29 @@ static u8 ixgbe_dcbnl_setapp(struct net_device *netdev, case DCB_APP_IDTYPE_ETHTYPE: #ifdef IXGBE_FCOE if (id == ETH_P_FCOE) { - u8 tc; - struct ixgbe_adapter *adapter; + u8 old_tc; + struct ixgbe_adapter *adapter = netdev_priv(netdev); - adapter = netdev_priv(netdev); - tc = adapter->fcoe.tc; + /* Get current programmed tc */ + old_tc = adapter->fcoe.tc; rval = ixgbe_fcoe_setapp(adapter, up); - if ((!rval) && (tc != adapter->fcoe.tc) && - (adapter->flags & IXGBE_FLAG_DCB_ENABLED) && - (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) { + + if (rval || + !(adapter->flags & IXGBE_FLAG_DCB_ENABLED) || + !(adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) + break; + + /* The FCoE application priority may be changed multiple + * times in quick sucession with switches that build up + * TLVs. To avoid creating uneeded device resets this + * checks the actual HW configuration and clears + * BIT_APP_UPCHG if a HW configuration change is not + * need + */ + if (old_tc == adapter->fcoe.tc) + adapter->dcb_set_bitmap &= ~BIT_APP_UPCHG; + else adapter->dcb_set_bitmap |= BIT_APP_UPCHG; - adapter->dcb_set_bitmap |= BIT_RESETLINK; - } } #endif break; -- cgit v1.2.3 From 39a7e587ec76db9f157fce653235b20f5283b003 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Wed, 5 Jan 2011 04:47:38 +0000 Subject: ixgbe: DCB, remove round robin mode on 82598 devices Remove round robin configuration code for 82598 parts it is not settable and is always false. If we need/want this in the future we can add it back properly. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb.h | 1 - drivers/net/ixgbe/ixgbe_dcb_82598.c | 6 ++---- drivers/net/ixgbe/ixgbe_main.c | 1 - 3 files changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_dcb.h b/drivers/net/ixgbe/ixgbe_dcb.h index 1cfe38ee1644..d0b2450781a2 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.h +++ b/drivers/net/ixgbe/ixgbe_dcb.h @@ -139,7 +139,6 @@ struct ixgbe_dcb_config { struct tc_configuration tc_config[MAX_TRAFFIC_CLASS]; u8 bw_percentage[2][MAX_BW_GROUP]; /* One each for Tx/Rx */ bool pfc_mode_enable; - bool round_robin_enable; enum dcb_rx_pba_cfg rx_pba_cfg; diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c index 9a5e89c12e05..19aa80640f68 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c @@ -146,10 +146,8 @@ static s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, /* Enable arbiter */ reg &= ~IXGBE_DPMCS_ARBDIS; - if (!(dcb_config->round_robin_enable)) { - /* Enable DFP and Recycle mode */ - reg |= (IXGBE_DPMCS_TDPAC | IXGBE_DPMCS_TRM); - } + /* Enable DFP and Recycle mode */ + reg |= (IXGBE_DPMCS_TDPAC | IXGBE_DPMCS_TRM); reg |= IXGBE_DPMCS_TSOEF; /* Configure Max TSO packet size 34KB including payload and headers */ reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index fbae703b46d7..1e4814875945 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -5173,7 +5173,6 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->dcb_cfg.bw_percentage[DCB_RX_CONFIG][0] = 100; adapter->dcb_cfg.rx_pba_cfg = pba_equal; adapter->dcb_cfg.pfc_mode_enable = false; - adapter->dcb_cfg.round_robin_enable = false; adapter->dcb_set_bitmap = 0x00; ixgbe_copy_dcb_cfg(&adapter->dcb_cfg, &adapter->temp_dcb_cfg, adapter->ring_feature[RING_F_DCB].indices); -- cgit v1.2.3 From 55320cb58baebd1795ec92f4550a1e8b38bf9ddf Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Wed, 5 Jan 2011 04:47:43 +0000 Subject: ixgbe: DCB, abstract out dcb_config from DCB hardware configuration Currently the routines that configure the HW for DCB require a ixgbe_dcb_config structure. This structure was designed to support the CEE standard and does not match the IEEE standard well. This patch changes the HW routines in ixgbe_dcb_8259x.{ch} to use raw pfc and bandwidth values. This requires some parsing of the DCB configuration but makes the HW routines independent of the data structure that contains the DCB configuration. The primary advantage to doing this is we can do HW setup directly from the 802.1Qaz ops without having to arbitrarily encapsulate this data into the CEE structure. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb.c | 74 ++++++++++++++++++++++- drivers/net/ixgbe/ixgbe_dcb.h | 1 + drivers/net/ixgbe/ixgbe_dcb_82598.c | 86 ++++++++++++++------------- drivers/net/ixgbe/ixgbe_dcb_82598.h | 23 +++++++- drivers/net/ixgbe/ixgbe_dcb_82599.c | 115 ++++++++++++++++++++---------------- drivers/net/ixgbe/ixgbe_dcb_82599.h | 24 +++++++- drivers/net/ixgbe/ixgbe_dcb_nl.c | 9 +-- 7 files changed, 230 insertions(+), 102 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c index d16c260c1f50..d9bb670ae258 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.c +++ b/drivers/net/ixgbe/ixgbe_dcb.c @@ -141,6 +141,59 @@ out: return ret_val; } +void ixgbe_dcb_unpack_pfc(struct ixgbe_dcb_config *cfg, u8 *pfc_en) +{ + int i; + + *pfc_en = 0; + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) + *pfc_en |= (cfg->tc_config[i].dcb_pfc & 0xF) << i; +} + +void ixgbe_dcb_unpack_refill(struct ixgbe_dcb_config *cfg, int direction, + u16 *refill) +{ + struct tc_bw_alloc *p; + int i; + + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { + p = &cfg->tc_config[i].path[direction]; + refill[i] = p->data_credits_refill; + } +} + +void ixgbe_dcb_unpack_max(struct ixgbe_dcb_config *cfg, u16 *max) +{ + int i; + + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) + max[i] = cfg->tc_config[i].desc_credits_max; +} + +void ixgbe_dcb_unpack_bwgid(struct ixgbe_dcb_config *cfg, int direction, + u8 *bwgid) +{ + struct tc_bw_alloc *p; + int i; + + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { + p = &cfg->tc_config[i].path[direction]; + bwgid[i] = p->bwg_id; + } +} + +void ixgbe_dcb_unpack_prio(struct ixgbe_dcb_config *cfg, int direction, + u8 *ptype) +{ + struct tc_bw_alloc *p; + int i; + + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { + p = &cfg->tc_config[i].path[direction]; + ptype[i] = p->prio_type; + } +} + /** * ixgbe_dcb_hw_config - Config and enable DCB * @hw: pointer to hardware structure @@ -152,13 +205,30 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config) { s32 ret = 0; + u8 pfc_en; + u8 ptype[MAX_TRAFFIC_CLASS]; + u8 bwgid[MAX_TRAFFIC_CLASS]; + u16 refill[MAX_TRAFFIC_CLASS]; + u16 max[MAX_TRAFFIC_CLASS]; + + /* Unpack CEE standard containers */ + ixgbe_dcb_unpack_pfc(dcb_config, &pfc_en); + ixgbe_dcb_unpack_refill(dcb_config, DCB_TX_CONFIG, refill); + ixgbe_dcb_unpack_max(dcb_config, max); + ixgbe_dcb_unpack_bwgid(dcb_config, DCB_TX_CONFIG, bwgid); + ixgbe_dcb_unpack_prio(dcb_config, DCB_TX_CONFIG, ptype); + switch (hw->mac.type) { case ixgbe_mac_82598EB: - ret = ixgbe_dcb_hw_config_82598(hw, dcb_config); + ret = ixgbe_dcb_hw_config_82598(hw, dcb_config->rx_pba_cfg, + pfc_en, refill, max, bwgid, + ptype); break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: - ret = ixgbe_dcb_hw_config_82599(hw, dcb_config); + ret = ixgbe_dcb_hw_config_82599(hw, dcb_config->rx_pba_cfg, + pfc_en, refill, max, bwgid, + ptype); break; default: break; diff --git a/drivers/net/ixgbe/ixgbe_dcb.h b/drivers/net/ixgbe/ixgbe_dcb.h index d0b2450781a2..aa6cb5f9ebf4 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.h +++ b/drivers/net/ixgbe/ixgbe_dcb.h @@ -147,6 +147,7 @@ struct ixgbe_dcb_config { }; /* DCB driver APIs */ +void ixgbe_dcb_unpack_pfc(struct ixgbe_dcb_config *cfg, u8 *pfc_en); /* DCB credits calculation */ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *, diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c index 19aa80640f68..d1288060cbd0 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c @@ -38,15 +38,14 @@ * * Configure packet buffers for DCB mode. */ -static s32 ixgbe_dcb_config_packet_buffers_82598(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) +static s32 ixgbe_dcb_config_packet_buffers_82598(struct ixgbe_hw *hw, u8 rx_pba) { s32 ret_val = 0; u32 value = IXGBE_RXPBSIZE_64KB; u8 i = 0; /* Setup Rx packet buffer sizes */ - switch (dcb_config->rx_pba_cfg) { + switch (rx_pba) { case pba_80_48: /* Setup the first four at 80KB */ value = IXGBE_RXPBSIZE_80KB; @@ -78,10 +77,11 @@ static s32 ixgbe_dcb_config_packet_buffers_82598(struct ixgbe_hw *hw, * * Configure Rx Data Arbiter and credits for each traffic class. */ -static s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) +s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, + u16 *refill, + u16 *max, + u8 *prio_type) { - struct tc_bw_alloc *p; u32 reg = 0; u32 credit_refill = 0; u32 credit_max = 0; @@ -102,13 +102,12 @@ static s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, /* Configure traffic class credits and priority */ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { - p = &dcb_config->tc_config[i].path[DCB_RX_CONFIG]; - credit_refill = p->data_credits_refill; - credit_max = p->data_credits_max; + credit_refill = refill[i]; + credit_max = max[i]; reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT); - if (p->prio_type == prio_link) + if (prio_type[i] == prio_link) reg |= IXGBE_RT2CR_LSP; IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg); @@ -135,10 +134,12 @@ static s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, * * Configure Tx Descriptor Arbiter and credits for each traffic class. */ -static s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) +s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, + u16 *refill, + u16 *max, + u8 *bwg_id, + u8 *prio_type) { - struct tc_bw_alloc *p; u32 reg, max_credits; u8 i; @@ -156,16 +157,15 @@ static s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, /* Configure traffic class credits and priority */ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { - p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG]; - max_credits = dcb_config->tc_config[i].desc_credits_max; + max_credits = max[i]; reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT; - reg |= p->data_credits_refill; - reg |= (u32)(p->bwg_id) << IXGBE_TDTQ2TCCR_BWG_SHIFT; + reg |= refill[i]; + reg |= (u32)(bwg_id[i]) << IXGBE_TDTQ2TCCR_BWG_SHIFT; - if (p->prio_type == prio_group) + if (prio_type[i] == prio_group) reg |= IXGBE_TDTQ2TCCR_GSP; - if (p->prio_type == prio_link) + if (prio_type[i] == prio_link) reg |= IXGBE_TDTQ2TCCR_LSP; IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg); @@ -181,10 +181,12 @@ static s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, * * Configure Tx Data Arbiter and credits for each traffic class. */ -static s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) +s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, + u16 *refill, + u16 *max, + u8 *bwg_id, + u8 *prio_type) { - struct tc_bw_alloc *p; u32 reg; u8 i; @@ -198,15 +200,14 @@ static s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, /* Configure traffic class credits and priority */ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { - p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG]; - reg = p->data_credits_refill; - reg |= (u32)(p->data_credits_max) << IXGBE_TDPT2TCCR_MCL_SHIFT; - reg |= (u32)(p->bwg_id) << IXGBE_TDPT2TCCR_BWG_SHIFT; + reg = refill[i]; + reg |= (u32)(max[i]) << IXGBE_TDPT2TCCR_MCL_SHIFT; + reg |= (u32)(bwg_id[i]) << IXGBE_TDPT2TCCR_BWG_SHIFT; - if (p->prio_type == prio_group) + if (prio_type[i] == prio_group) reg |= IXGBE_TDPT2TCCR_GSP; - if (p->prio_type == prio_link) + if (prio_type[i] == prio_link) reg |= IXGBE_TDPT2TCCR_LSP; IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg); @@ -227,13 +228,12 @@ static s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, * * Configure Priority Flow Control for each traffic class. */ -s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) +s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en) { u32 reg, rx_pba_size; u8 i; - if (!dcb_config->pfc_mode_enable) + if (!pfc_en) goto out; /* Enable Transmit Priority Flow Control */ @@ -254,19 +254,20 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, * for each traffic class. */ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { + int enabled = pfc_en & (1 << i); rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)); rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT; reg = (rx_pba_size - hw->fc.low_water) << 10; - if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx || - dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full) + if (enabled == pfc_enabled_tx || + enabled == pfc_enabled_full) reg |= IXGBE_FCRTL_XONE; IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), reg); reg = (rx_pba_size - hw->fc.high_water) << 10; - if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx || - dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full) + if (enabled == pfc_enabled_tx || + enabled == pfc_enabled_full) reg |= IXGBE_FCRTH_FCEN; IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg); @@ -323,13 +324,16 @@ static s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw) * Configure dcb settings and enable dcb mode. */ s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) + u8 rx_pba, u8 pfc_en, u16 *refill, + u16 *max, u8 *bwg_id, u8 *prio_type) { - ixgbe_dcb_config_packet_buffers_82598(hw, dcb_config); - ixgbe_dcb_config_rx_arbiter_82598(hw, dcb_config); - ixgbe_dcb_config_tx_desc_arbiter_82598(hw, dcb_config); - ixgbe_dcb_config_tx_data_arbiter_82598(hw, dcb_config); - ixgbe_dcb_config_pfc_82598(hw, dcb_config); + ixgbe_dcb_config_packet_buffers_82598(hw, rx_pba); + ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, prio_type); + ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, + bwg_id, prio_type); + ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, + bwg_id, prio_type); + ixgbe_dcb_config_pfc_82598(hw, pfc_en); ixgbe_dcb_config_tc_stats_82598(hw); return 0; diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.h b/drivers/net/ixgbe/ixgbe_dcb_82598.h index abc03ccfa088..0d2a758effce 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.h +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.h @@ -71,9 +71,28 @@ /* DCB hardware-specific driver APIs */ /* DCB PFC functions */ -s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *, struct ixgbe_dcb_config *); +s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *, u8 pfc_en); /* DCB hw initialization */ -s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *, struct ixgbe_dcb_config *); +s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, + u16 *refill, + u16 *max, + u8 *prio_type); + +s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, + u16 *refill, + u16 *max, + u8 *bwg_id, + u8 *prio_type); + +s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, + u16 *refill, + u16 *max, + u8 *bwg_id, + u8 *prio_type); + +s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, + u8 rx_pba, u8 pfc_en, u16 *refill, + u16 *max, u8 *bwg_id, u8 *prio_type); #endif /* _DCB_82598_CONFIG_H */ diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c index 374e1f74d0f5..b0d97a98c84d 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c @@ -33,19 +33,18 @@ /** * ixgbe_dcb_config_packet_buffers_82599 - Configure DCB packet buffers * @hw: pointer to hardware structure - * @dcb_config: pointer to ixgbe_dcb_config structure + * @rx_pba: method to distribute packet buffer * * Configure packet buffers for DCB mode. */ -static s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) +static s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw, u8 rx_pba) { s32 ret_val = 0; u32 value = IXGBE_RXPBSIZE_64KB; u8 i = 0; /* Setup Rx packet buffer sizes */ - switch (dcb_config->rx_pba_cfg) { + switch (rx_pba) { case pba_80_48: /* Setup the first four at 80KB */ value = IXGBE_RXPBSIZE_80KB; @@ -75,14 +74,19 @@ static s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw, /** * ixgbe_dcb_config_rx_arbiter_82599 - Config Rx Data arbiter * @hw: pointer to hardware structure - * @dcb_config: pointer to ixgbe_dcb_config structure + * @refill: refill credits index by traffic class + * @max: max credits index by traffic class + * @bwg_id: bandwidth grouping indexed by traffic class + * @prio_type: priority type indexed by traffic class * * Configure Rx Packet Arbiter and credits for each traffic class. */ -static s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) +s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, + u16 *refill, + u16 *max, + u8 *bwg_id, + u8 *prio_type) { - struct tc_bw_alloc *p; u32 reg = 0; u32 credit_refill = 0; u32 credit_max = 0; @@ -103,15 +107,13 @@ static s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, /* Configure traffic class credits and priority */ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { - p = &dcb_config->tc_config[i].path[DCB_RX_CONFIG]; - - credit_refill = p->data_credits_refill; - credit_max = p->data_credits_max; + credit_refill = refill[i]; + credit_max = max[i]; reg = credit_refill | (credit_max << IXGBE_RTRPT4C_MCL_SHIFT); - reg |= (u32)(p->bwg_id) << IXGBE_RTRPT4C_BWG_SHIFT; + reg |= (u32)(bwg_id[i]) << IXGBE_RTRPT4C_BWG_SHIFT; - if (p->prio_type == prio_link) + if (prio_type[i] == prio_link) reg |= IXGBE_RTRPT4C_LSP; IXGBE_WRITE_REG(hw, IXGBE_RTRPT4C(i), reg); @@ -130,14 +132,19 @@ static s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, /** * ixgbe_dcb_config_tx_desc_arbiter_82599 - Config Tx Desc. arbiter * @hw: pointer to hardware structure - * @dcb_config: pointer to ixgbe_dcb_config structure + * @refill: refill credits index by traffic class + * @max: max credits index by traffic class + * @bwg_id: bandwidth grouping indexed by traffic class + * @prio_type: priority type indexed by traffic class * * Configure Tx Descriptor Arbiter and credits for each traffic class. */ -static s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) +s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, + u16 *refill, + u16 *max, + u8 *bwg_id, + u8 *prio_type) { - struct tc_bw_alloc *p; u32 reg, max_credits; u8 i; @@ -149,16 +156,15 @@ static s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, /* Configure traffic class credits and priority */ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { - p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG]; - max_credits = dcb_config->tc_config[i].desc_credits_max; + max_credits = max[i]; reg = max_credits << IXGBE_RTTDT2C_MCL_SHIFT; - reg |= p->data_credits_refill; - reg |= (u32)(p->bwg_id) << IXGBE_RTTDT2C_BWG_SHIFT; + reg |= refill[i]; + reg |= (u32)(bwg_id[i]) << IXGBE_RTTDT2C_BWG_SHIFT; - if (p->prio_type == prio_group) + if (prio_type[i] == prio_group) reg |= IXGBE_RTTDT2C_GSP; - if (p->prio_type == prio_link) + if (prio_type[i] == prio_link) reg |= IXGBE_RTTDT2C_LSP; IXGBE_WRITE_REG(hw, IXGBE_RTTDT2C(i), reg); @@ -177,14 +183,19 @@ static s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, /** * ixgbe_dcb_config_tx_data_arbiter_82599 - Config Tx Data arbiter * @hw: pointer to hardware structure - * @dcb_config: pointer to ixgbe_dcb_config structure + * @refill: refill credits index by traffic class + * @max: max credits index by traffic class + * @bwg_id: bandwidth grouping indexed by traffic class + * @prio_type: priority type indexed by traffic class * * Configure Tx Packet Arbiter and credits for each traffic class. */ -static s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) +s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, + u16 *refill, + u16 *max, + u8 *bwg_id, + u8 *prio_type) { - struct tc_bw_alloc *p; u32 reg; u8 i; @@ -205,15 +216,14 @@ static s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, /* Configure traffic class credits and priority */ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { - p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG]; - reg = p->data_credits_refill; - reg |= (u32)(p->data_credits_max) << IXGBE_RTTPT2C_MCL_SHIFT; - reg |= (u32)(p->bwg_id) << IXGBE_RTTPT2C_BWG_SHIFT; + reg = refill[i]; + reg |= (u32)(max[i]) << IXGBE_RTTPT2C_MCL_SHIFT; + reg |= (u32)(bwg_id[i]) << IXGBE_RTTPT2C_BWG_SHIFT; - if (p->prio_type == prio_group) + if (prio_type[i] == prio_group) reg |= IXGBE_RTTPT2C_GSP; - if (p->prio_type == prio_link) + if (prio_type[i] == prio_link) reg |= IXGBE_RTTPT2C_LSP; IXGBE_WRITE_REG(hw, IXGBE_RTTPT2C(i), reg); @@ -233,17 +243,16 @@ static s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, /** * ixgbe_dcb_config_pfc_82599 - Configure priority flow control * @hw: pointer to hardware structure - * @dcb_config: pointer to ixgbe_dcb_config structure + * @pfc_en: enabled pfc bitmask * * Configure Priority Flow Control (PFC) for each traffic class. */ -s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) +s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en) { u32 i, reg, rx_pba_size; /* If PFC is disabled globally then fall back to LFC. */ - if (!dcb_config->pfc_mode_enable) { + if (!pfc_en) { for (i = 0; i < MAX_TRAFFIC_CLASS; i++) hw->mac.ops.fc_enable(hw, i); goto out; @@ -251,19 +260,18 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, /* Configure PFC Tx thresholds per TC */ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { + int enabled = pfc_en & (1 << i); rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)); rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT; reg = (rx_pba_size - hw->fc.low_water) << 10; - if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full || - dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx) + if (enabled) reg |= IXGBE_FCRTL_XONE; IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg); reg = (rx_pba_size - hw->fc.high_water) << 10; - if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full || - dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx) + if (enabled) reg |= IXGBE_FCRTH_FCEN; IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg); } @@ -349,7 +357,6 @@ static s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw) /** * ixgbe_dcb_config_82599 - Configure general DCB parameters * @hw: pointer to hardware structure - * @dcb_config: pointer to ixgbe_dcb_config structure * * Configure general DCB parameters. */ @@ -406,19 +413,27 @@ static s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw) /** * ixgbe_dcb_hw_config_82599 - Configure and enable DCB * @hw: pointer to hardware structure - * @dcb_config: pointer to ixgbe_dcb_config structure + * @rx_pba: method to distribute packet buffer + * @refill: refill credits index by traffic class + * @max: max credits index by traffic class + * @bwg_id: bandwidth grouping indexed by traffic class + * @prio_type: priority type indexed by traffic class + * @pfc_en: enabled pfc bitmask * * Configure dcb settings and enable dcb mode. */ s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) + u8 rx_pba, u8 pfc_en, u16 *refill, + u16 *max, u8 *bwg_id, u8 *prio_type) { - ixgbe_dcb_config_packet_buffers_82599(hw, dcb_config); + ixgbe_dcb_config_packet_buffers_82599(hw, rx_pba); ixgbe_dcb_config_82599(hw); - ixgbe_dcb_config_rx_arbiter_82599(hw, dcb_config); - ixgbe_dcb_config_tx_desc_arbiter_82599(hw, dcb_config); - ixgbe_dcb_config_tx_data_arbiter_82599(hw, dcb_config); - ixgbe_dcb_config_pfc_82599(hw, dcb_config); + ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id, prio_type); + ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, + bwg_id, prio_type); + ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, + bwg_id, prio_type); + ixgbe_dcb_config_pfc_82599(hw, pfc_en); ixgbe_dcb_config_tc_stats_82599(hw); return 0; diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.h b/drivers/net/ixgbe/ixgbe_dcb_82599.h index 3841649fb954..5b0ca85614d1 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.h +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.h @@ -102,11 +102,29 @@ /* DCB hardware-specific driver APIs */ /* DCB PFC functions */ -s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config); +s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en); /* DCB hw initialization */ +s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, + u16 *refill, + u16 *max, + u8 *bwg_id, + u8 *prio_type); + +s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, + u16 *refill, + u16 *max, + u8 *bwg_id, + u8 *prio_type); + +s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, + u16 *refill, + u16 *max, + u8 *bwg_id, + u8 *prio_type); + s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *config); + u8 rx_pba, u8 pfc_en, u16 *refill, + u16 *max, u8 *bwg_id, u8 *prio_type); #endif /* _DCB_82599_CONFIG_H */ diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index 48058359ba69..6ab1f1abaa01 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -422,12 +422,13 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) } ret = DCB_HW_CHG_RST; } else if (adapter->dcb_set_bitmap & BIT_PFC) { + u8 pfc_en; + ixgbe_dcb_unpack_pfc(&adapter->dcb_cfg, &pfc_en); + if (adapter->hw.mac.type == ixgbe_mac_82598EB) - ixgbe_dcb_config_pfc_82598(&adapter->hw, - &adapter->dcb_cfg); + ixgbe_dcb_config_pfc_82598(&adapter->hw, pfc_en); else if (adapter->hw.mac.type == ixgbe_mac_82599EB) - ixgbe_dcb_config_pfc_82599(&adapter->hw, - &adapter->dcb_cfg); + ixgbe_dcb_config_pfc_82599(&adapter->hw, pfc_en); ret = DCB_HW_CHG; } if (adapter->dcb_cfg.pfc_mode_enable) -- cgit v1.2.3 From d033d526a465c4bb8a499a0b5df65b3e7cf4da6f Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Thu, 10 Feb 2011 14:40:01 +0000 Subject: ixgbe: DCB, implement 802.1Qaz routines Implements 802.1Qaz support for ixgbe driver. Additionally, this adds IEEE_8021QAZ_TSA_{} defines to dcbnl.h this is to avoid having to use cryptic numeric codes for the TSA type. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 4 ++ drivers/net/ixgbe/ixgbe_dcb.c | 103 ++++++++++++++++++++++++++++++++++++ drivers/net/ixgbe/ixgbe_dcb.h | 4 ++ drivers/net/ixgbe/ixgbe_dcb_82598.c | 2 +- drivers/net/ixgbe/ixgbe_dcb_nl.c | 91 +++++++++++++++++++++++++++++++ drivers/net/ixgbe/ixgbe_main.c | 4 ++ include/linux/dcbnl.h | 5 ++ 7 files changed, 212 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 3b8c92463617..d04afdeee035 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -334,6 +334,10 @@ struct ixgbe_adapter { u16 bd_number; struct work_struct reset_task; struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS]; + + /* DCB parameters */ + struct ieee_pfc *ixgbe_ieee_pfc; + struct ieee_ets *ixgbe_ieee_ets; struct ixgbe_dcb_config dcb_cfg; struct ixgbe_dcb_config temp_dcb_cfg; u8 dcb_set_bitmap; diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c index d9bb670ae258..13c962efbfc9 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.c +++ b/drivers/net/ixgbe/ixgbe_dcb.c @@ -33,6 +33,42 @@ #include "ixgbe_dcb_82598.h" #include "ixgbe_dcb_82599.h" +/** + * ixgbe_ieee_credits - This calculates the ieee traffic class + * credits from the configured bandwidth percentages. Credits + * are the smallest unit programable into the underlying + * hardware. The IEEE 802.1Qaz specification do not use bandwidth + * groups so this is much simplified from the CEE case. + */ +s32 ixgbe_ieee_credits(__u8 *bw, __u16 *refill, __u16 *max, int max_frame) +{ + int min_percent = 100; + int min_credit, multiplier; + int i; + + min_credit = ((max_frame / 2) + DCB_CREDIT_QUANTUM - 1) / + DCB_CREDIT_QUANTUM; + + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { + if (bw[i] < min_percent && bw[i]) + min_percent = bw[i]; + } + + multiplier = (min_credit / min_percent) + 1; + + /* Find out the hw credits for each TC */ + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { + int val = min(bw[i] * multiplier, MAX_CREDIT_REFILL); + + if (val < min_credit) + val = min_credit; + refill[i] = val; + + max[i] = (bw[i] * MAX_CREDIT)/100; + } + return 0; +} + /** * ixgbe_dcb_calculate_tc_credits - Calculates traffic class credits * @ixgbe_dcb_config: Struct containing DCB settings. @@ -236,3 +272,70 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, return ret; } +/* Helper routines to abstract HW specifics from DCB netlink ops */ +s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en) +{ + int ret = -EINVAL; + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en); + break; + default: + break; + } + return ret; +} + +s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw, + u16 *refill, u16 *max, u8 *bwg_id, u8 *tsa) +{ + int i; + u8 prio_type[IEEE_8021QAZ_MAX_TCS]; + + /* Map TSA onto CEE prio type */ + for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { + switch (tsa[i]) { + case IEEE_8021QAZ_TSA_STRICT: + prio_type[i] = 2; + break; + case IEEE_8021QAZ_TSA_ETS: + prio_type[i] = 0; + break; + default: + /* Hardware only supports priority strict or + * ETS transmission selection algorithms if + * we receive some other value from dcbnl + * throw an error + */ + return -EINVAL; + } + } + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, + prio_type); + ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, + bwg_id, prio_type); + ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, + bwg_id, prio_type); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, + bwg_id, prio_type); + ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, + bwg_id, prio_type); + ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, + bwg_id, prio_type); + break; + default: + break; + } + return 0; +} diff --git a/drivers/net/ixgbe/ixgbe_dcb.h b/drivers/net/ixgbe/ixgbe_dcb.h index aa6cb5f9ebf4..4e4a641f3d53 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.h +++ b/drivers/net/ixgbe/ixgbe_dcb.h @@ -150,10 +150,14 @@ struct ixgbe_dcb_config { void ixgbe_dcb_unpack_pfc(struct ixgbe_dcb_config *cfg, u8 *pfc_en); /* DCB credits calculation */ +s32 ixgbe_ieee_credits(__u8 *bw, __u16 *refill, __u16 *max, int max_frame); s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *, struct ixgbe_dcb_config *, int, u8); /* DCB hw initialization */ +s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw, + u16 *refill, u16 *max, u8 *bwg_id, u8 *prio_type); +s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en); s32 ixgbe_dcb_hw_config(struct ixgbe_hw *, struct ixgbe_dcb_config *); /* DCB definitions for credit calculation */ diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c index d1288060cbd0..2965edcdac7b 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c @@ -291,7 +291,7 @@ out: * Configure queue statistics registers, all queues belonging to same traffic * class uses a single set of queue statistics counters. */ -static s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw) +s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw) { u32 reg = 0; u8 i = 0; diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index 6ab1f1abaa01..e75a3c91198d 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -606,7 +606,98 @@ static u8 ixgbe_dcbnl_setapp(struct net_device *netdev, return rval; } +static int ixgbe_dcbnl_ieee_getets(struct net_device *dev, + struct ieee_ets *ets) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ieee_ets *my_ets = adapter->ixgbe_ieee_ets; + + /* No IEEE PFC settings available */ + if (!my_ets) + return -EINVAL; + + ets->ets_cap = MAX_TRAFFIC_CLASS; + ets->cbs = my_ets->cbs; + memcpy(ets->tc_tx_bw, my_ets->tc_tx_bw, sizeof(ets->tc_tx_bw)); + memcpy(ets->tc_rx_bw, my_ets->tc_rx_bw, sizeof(ets->tc_rx_bw)); + memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa)); + memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc)); + return 0; +} + +static int ixgbe_dcbnl_ieee_setets(struct net_device *dev, + struct ieee_ets *ets) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + __u16 refill[IEEE_8021QAZ_MAX_TCS], max[IEEE_8021QAZ_MAX_TCS]; + int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN; + int err; + /* naively give each TC a bwg to map onto CEE hardware */ + __u8 bwg_id[IEEE_8021QAZ_MAX_TCS] = {0, 1, 2, 3, 4, 5, 6, 7}; + + if (!adapter->ixgbe_ieee_ets) { + adapter->ixgbe_ieee_ets = kmalloc(sizeof(struct ieee_ets), + GFP_KERNEL); + if (!adapter->ixgbe_ieee_ets) + return -ENOMEM; + } + + + memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets)); + + ixgbe_ieee_credits(ets->tc_tx_bw, refill, max, max_frame); + err = ixgbe_dcb_hw_ets_config(&adapter->hw, refill, max, + bwg_id, ets->tc_tsa); + return err; +} + +static int ixgbe_dcbnl_ieee_getpfc(struct net_device *dev, + struct ieee_pfc *pfc) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ieee_pfc *my_pfc = adapter->ixgbe_ieee_pfc; + int i; + + /* No IEEE PFC settings available */ + if (!my_pfc) + return -EINVAL; + + pfc->pfc_cap = MAX_TRAFFIC_CLASS; + pfc->pfc_en = my_pfc->pfc_en; + pfc->mbc = my_pfc->mbc; + pfc->delay = my_pfc->delay; + + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { + pfc->requests[i] = adapter->stats.pxoffrxc[i]; + pfc->indications[i] = adapter->stats.pxofftxc[i]; + } + + return 0; +} + +static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev, + struct ieee_pfc *pfc) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + int err; + + if (!adapter->ixgbe_ieee_pfc) { + adapter->ixgbe_ieee_pfc = kmalloc(sizeof(struct ieee_pfc), + GFP_KERNEL); + if (!adapter->ixgbe_ieee_pfc) + return -ENOMEM; + } + + memcpy(adapter->ixgbe_ieee_pfc, pfc, sizeof(*adapter->ixgbe_ieee_pfc)); + err = ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc->pfc_en); + return err; +} + const struct dcbnl_rtnl_ops dcbnl_ops = { + .ieee_getets = ixgbe_dcbnl_ieee_getets, + .ieee_setets = ixgbe_dcbnl_ieee_setets, + .ieee_getpfc = ixgbe_dcbnl_ieee_getpfc, + .ieee_setpfc = ixgbe_dcbnl_ieee_setpfc, .getstate = ixgbe_dcbnl_get_state, .setstate = ixgbe_dcbnl_set_state, .getpermhwaddr = ixgbe_dcbnl_get_perm_hw_addr, diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 1e4814875945..c2e09b9cff46 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -5609,6 +5609,10 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) } ixgbe_clear_interrupt_scheme(adapter); +#ifdef CONFIG_DCB + kfree(adapter->ixgbe_ieee_pfc); + kfree(adapter->ixgbe_ieee_ets); +#endif #ifdef CONFIG_PM retval = pci_save_state(pdev); diff --git a/include/linux/dcbnl.h b/include/linux/dcbnl.h index 68cd248f6d3e..cd8d518efa3b 100644 --- a/include/linux/dcbnl.h +++ b/include/linux/dcbnl.h @@ -25,6 +25,11 @@ /* IEEE 802.1Qaz std supported values */ #define IEEE_8021QAZ_MAX_TCS 8 +#define IEEE_8021QAZ_TSA_STRICT 0 +#define IEEE_8021QAZ_TSA_CB_SHABER 1 +#define IEEE_8021QAZ_TSA_ETS 2 +#define IEEE_8021QAZ_TSA_VENDOR 255 + /* This structure contains the IEEE 802.1Qaz ETS managed object * * @willing: willing bit in ETS configuratin TLV -- cgit v1.2.3 From d43f5c21d6bab7f58cb6723a57a66883cee0a905 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Sat, 22 Jan 2011 06:07:05 +0000 Subject: ixgbe: DCB, do not reset on CEE pg changes The 82599 and 82598 devices do not require hardware resets to configure CEE pg settings. This patch changes DCB configuration to set the CEE pg values directly from the dcbnl ops routine. This reduces the number of resets seen on the wire and allows LLDP to reach a steady state faster. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb.h | 4 ++++ drivers/net/ixgbe/ixgbe_dcb_nl.c | 48 +++++++++++++++++++++++++++++----------- 2 files changed, 39 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_dcb.h b/drivers/net/ixgbe/ixgbe_dcb.h index 4e4a641f3d53..e5935114815e 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.h +++ b/drivers/net/ixgbe/ixgbe_dcb.h @@ -148,6 +148,10 @@ struct ixgbe_dcb_config { /* DCB driver APIs */ void ixgbe_dcb_unpack_pfc(struct ixgbe_dcb_config *cfg, u8 *pfc_en); +void ixgbe_dcb_unpack_refill(struct ixgbe_dcb_config *, int, u16 *); +void ixgbe_dcb_unpack_max(struct ixgbe_dcb_config *, u16 *); +void ixgbe_dcb_unpack_bwgid(struct ixgbe_dcb_config *, int, u8 *); +void ixgbe_dcb_unpack_prio(struct ixgbe_dcb_config *, int, u8 *); /* DCB credits calculation */ s32 ixgbe_ieee_credits(__u8 *bw, __u16 *refill, __u16 *max, int max_frame); diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index e75a3c91198d..b3a8d24afdd0 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -225,10 +225,8 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc, (adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_percent != adapter->dcb_cfg.tc_config[tc].path[0].bwg_percent) || (adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap != - adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap)) { + adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap)) adapter->dcb_set_bitmap |= BIT_PG_TX; - adapter->dcb_set_bitmap |= BIT_RESETLINK; - } } static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id, @@ -239,10 +237,8 @@ static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id, adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] = bw_pct; if (adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] != - adapter->dcb_cfg.bw_percentage[0][bwg_id]) { + adapter->dcb_cfg.bw_percentage[0][bwg_id]) adapter->dcb_set_bitmap |= BIT_PG_TX; - adapter->dcb_set_bitmap |= BIT_RESETLINK; - } } static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc, @@ -269,10 +265,8 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc, (adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_percent != adapter->dcb_cfg.tc_config[tc].path[1].bwg_percent) || (adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap != - adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap)) { + adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap)) adapter->dcb_set_bitmap |= BIT_PG_RX; - adapter->dcb_set_bitmap |= BIT_RESETLINK; - } } static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id, @@ -283,10 +277,8 @@ static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id, adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] = bw_pct; if (adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] != - adapter->dcb_cfg.bw_percentage[1][bwg_id]) { + adapter->dcb_cfg.bw_percentage[1][bwg_id]) adapter->dcb_set_bitmap |= BIT_PG_RX; - adapter->dcb_set_bitmap |= BIT_RESETLINK; - } } static void ixgbe_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int tc, @@ -421,7 +413,9 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) ixgbe_up(adapter); } ret = DCB_HW_CHG_RST; - } else if (adapter->dcb_set_bitmap & BIT_PFC) { + } + + if (adapter->dcb_set_bitmap & BIT_PFC) { u8 pfc_en; ixgbe_dcb_unpack_pfc(&adapter->dcb_cfg, &pfc_en); @@ -431,6 +425,34 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) ixgbe_dcb_config_pfc_82599(&adapter->hw, pfc_en); ret = DCB_HW_CHG; } + + if (adapter->dcb_set_bitmap & (BIT_PG_TX|BIT_PG_RX)) { + u16 refill[MAX_TRAFFIC_CLASS], max[MAX_TRAFFIC_CLASS]; + u8 bwg_id[MAX_TRAFFIC_CLASS], prio_type[MAX_TRAFFIC_CLASS]; + int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN; + +#ifdef CONFIG_FCOE + if (adapter->netdev->features & NETIF_F_FCOE_MTU) + max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE); +#endif + + ixgbe_dcb_calculate_tc_credits(&adapter->hw, &adapter->dcb_cfg, + max_frame, DCB_TX_CONFIG); + ixgbe_dcb_calculate_tc_credits(&adapter->hw, &adapter->dcb_cfg, + max_frame, DCB_RX_CONFIG); + + ixgbe_dcb_unpack_refill(&adapter->dcb_cfg, + DCB_TX_CONFIG, refill); + ixgbe_dcb_unpack_max(&adapter->dcb_cfg, max); + ixgbe_dcb_unpack_bwgid(&adapter->dcb_cfg, + DCB_TX_CONFIG, bwg_id); + ixgbe_dcb_unpack_prio(&adapter->dcb_cfg, + DCB_TX_CONFIG, prio_type); + + ixgbe_dcb_hw_ets_config(&adapter->hw, refill, max, + bwg_id, prio_type); + } + if (adapter->dcb_cfg.pfc_mode_enable) adapter->hw.fc.current_mode = ixgbe_fc_pfc; -- cgit v1.2.3 From d37e1d0eba2e508b8ac499497db216c67df65c3c Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Fri, 7 Jan 2011 15:30:46 +0000 Subject: ixgbe: DCB, remove RESET bit it is no longer needed This removes the RESET bit previously used to force a device reset when DCB bandwidth configurations were changed. This can now be done dynamically without a reset so the bit is no longer needed. The only remaining operations that force a device reset are DCB enable/disable and FCoE application priority changes. DCB enable/disable is a hardware requirement. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb_nl.c | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index b3a8d24afdd0..c94adec5bc3b 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -37,7 +37,6 @@ #define BIT_PG_RX 0x04 #define BIT_PG_TX 0x08 #define BIT_APP_UPCHG 0x10 -#define BIT_RESETLINK 0x40 #define BIT_LINKSPEED 0x80 /* Responses for the DCB_C_SET_ALL command */ @@ -345,7 +344,6 @@ static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority, static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - bool do_reset; int ret; if (!adapter->dcb_set_bitmap) @@ -358,23 +356,17 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) return DCB_NO_HW_CHG; /* - * Only take down the adapter if the configuration change - * requires a reset. + * Only take down the adapter if an app change occured. FCoE + * may shuffle tx rings in this case and this can not be done + * without a reset currently. */ - do_reset = adapter->dcb_set_bitmap & (BIT_RESETLINK | BIT_APP_UPCHG); - - if (do_reset) { + if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) { while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) msleep(1); - if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) { - if (netif_running(netdev)) - netdev->netdev_ops->ndo_stop(netdev); - ixgbe_clear_interrupt_scheme(adapter); - } else { - if (netif_running(netdev)) - ixgbe_down(adapter); - } + if (netif_running(netdev)) + netdev->netdev_ops->ndo_stop(netdev); + ixgbe_clear_interrupt_scheme(adapter); } if (adapter->dcb_cfg.pfc_mode_enable) { @@ -403,15 +395,10 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) } } - if (do_reset) { - if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) { - ixgbe_init_interrupt_scheme(adapter); - if (netif_running(netdev)) - netdev->netdev_ops->ndo_open(netdev); - } else { - if (netif_running(netdev)) - ixgbe_up(adapter); - } + if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) { + ixgbe_init_interrupt_scheme(adapter); + if (netif_running(netdev)) + netdev->netdev_ops->ndo_open(netdev); ret = DCB_HW_CHG_RST; } @@ -456,7 +443,7 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) if (adapter->dcb_cfg.pfc_mode_enable) adapter->hw.fc.current_mode = ixgbe_fc_pfc; - if (do_reset) + if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) clear_bit(__IXGBE_RESETTING, &adapter->state); adapter->dcb_set_bitmap = 0x00; return ret; -- cgit v1.2.3 From 5977deaa6dde87dc6557570cb1088537e55b9646 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Wed, 5 Jan 2011 04:48:45 +0000 Subject: ixgbe: DCB, use hardware independent routines This consolidates hardware specifics to ixgbe_dcb.c this simplifies code that was previously branching based on hardware type. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb_nl.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index c94adec5bc3b..a977df3fe81b 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -405,11 +405,7 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) if (adapter->dcb_set_bitmap & BIT_PFC) { u8 pfc_en; ixgbe_dcb_unpack_pfc(&adapter->dcb_cfg, &pfc_en); - - if (adapter->hw.mac.type == ixgbe_mac_82598EB) - ixgbe_dcb_config_pfc_82598(&adapter->hw, pfc_en); - else if (adapter->hw.mac.type == ixgbe_mac_82599EB) - ixgbe_dcb_config_pfc_82599(&adapter->hw, pfc_en); + ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc_en); ret = DCB_HW_CHG; } -- cgit v1.2.3 From 3b2ee94300277220452332d2ebadf5b5699947b5 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Fri, 28 Jan 2011 02:28:26 +0000 Subject: ixgbe: fix namespace issue with ixgbe_dcb_txq_to_tc We didn't need the prototype and it was causing namespace complaints so I made it static. Signed-off-by: Don Skidmore Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 1 - drivers/net/ixgbe/ixgbe_main.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index d04afdeee035..12769b58c2e7 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -525,7 +525,6 @@ extern void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *, extern void ixgbe_alloc_rx_buffers(struct ixgbe_ring *, u16); extern void ixgbe_write_eitr(struct ixgbe_q_vector *); extern int ethtool_ioctl(struct ifreq *ifr); -extern u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 index); extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw); extern s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc); extern s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index c2e09b9cff46..34fdda21dba3 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -648,7 +648,7 @@ void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *tx_ring, * * Returns : a tc index for use in range 0-7, or 0-3 */ -u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 reg_idx) +static u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 reg_idx) { int tc = -1; int dcb_i = adapter->ring_feature[RING_F_DCB].indices; -- cgit v1.2.3 From 32f754667e66870773e40116687b6849963152f5 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Fri, 28 Jan 2011 02:28:31 +0000 Subject: ixgbe: cleanup namespace complaint by removing little used function We had a support function that just walked a few pointers to get from the ixgbe_hw struct to the netdev pointer. This was causing a namespace warning so I removed it and just reference the pointers directly. Signed-off-by: Don Skidmore Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_common.h | 4 ++-- drivers/net/ixgbe/ixgbe_main.c | 10 ---------- 2 files changed, 2 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h index 66ed045a8cf0..90cceb4a6317 100644 --- a/drivers/net/ixgbe/ixgbe_common.h +++ b/drivers/net/ixgbe/ixgbe_common.h @@ -29,6 +29,7 @@ #define _IXGBE_COMMON_H_ #include "ixgbe_type.h" +#include "ixgbe.h" u32 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw); s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw); @@ -110,9 +111,8 @@ void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf); #define IXGBE_WRITE_FLUSH(a) IXGBE_READ_REG(a, IXGBE_STATUS) -extern struct net_device *ixgbe_get_hw_dev(struct ixgbe_hw *hw); #define hw_dbg(hw, format, arg...) \ - netdev_dbg(ixgbe_get_hw_dev(hw), format, ##arg) + netdev_dbg(((struct ixgbe_adapter *)(hw->back))->netdev, format, ##arg) #define e_dev_info(format, arg...) \ dev_info(&adapter->pdev->dev, format, ## arg) #define e_dev_warn(format, arg...) \ diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 34fdda21dba3..4a6bcb66d2a8 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -7707,16 +7707,6 @@ static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event, #endif /* CONFIG_IXGBE_DCA */ -/** - * ixgbe_get_hw_dev return device - * used by hardware layer to print debugging information - **/ -struct net_device *ixgbe_get_hw_dev(struct ixgbe_hw *hw) -{ - struct ixgbe_adapter *adapter = hw->back; - return adapter->netdev; -} - module_exit(ixgbe_exit_module); /* ixgbe_main.c */ -- cgit v1.2.3 From 8fecce62b512c1d50174e03367d6f384dd4ceb80 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Fri, 28 Jan 2011 02:28:36 +0000 Subject: ixgbe: cleanup ixgbe_init_mbx_params_pf namespace issue The function ixgbe_init_mbx_params_pf isn't used unless CONFIG_PCI_IOV is defined. This is causing namespace warnings. So I wrapped its definition in CONFIG_PCI_IOV too. Signed-off-by: Don Skidmore Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_mbx.c | 2 ++ drivers/net/ixgbe/ixgbe_mbx.h | 2 ++ 2 files changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_mbx.c b/drivers/net/ixgbe/ixgbe_mbx.c index ea82c5a1cd3e..f215c4c296c4 100644 --- a/drivers/net/ixgbe/ixgbe_mbx.c +++ b/drivers/net/ixgbe/ixgbe_mbx.c @@ -437,6 +437,7 @@ out_no_read: return ret_val; } +#ifdef CONFIG_PCI_IOV /** * ixgbe_init_mbx_params_pf - set initial values for pf mailbox * @hw: pointer to the HW structure @@ -465,6 +466,7 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw) break; } } +#endif /* CONFIG_PCI_IOV */ struct ixgbe_mbx_operations mbx_ops_generic = { .read = ixgbe_read_mbx_pf, diff --git a/drivers/net/ixgbe/ixgbe_mbx.h b/drivers/net/ixgbe/ixgbe_mbx.h index 3df9b1590218..ada0ce32a7a6 100644 --- a/drivers/net/ixgbe/ixgbe_mbx.h +++ b/drivers/net/ixgbe/ixgbe_mbx.h @@ -86,7 +86,9 @@ s32 ixgbe_write_mbx(struct ixgbe_hw *, u32 *, u16, u16); s32 ixgbe_check_for_msg(struct ixgbe_hw *, u16); s32 ixgbe_check_for_ack(struct ixgbe_hw *, u16); s32 ixgbe_check_for_rst(struct ixgbe_hw *, u16); +#ifdef CONFIG_PCI_IOV void ixgbe_init_mbx_params_pf(struct ixgbe_hw *); +#endif /* CONFIG_PCI_IOV */ extern struct ixgbe_mbx_operations mbx_ops_generic; -- cgit v1.2.3 From 1b1c0a489c1dcc1fa640c13404ca69e7beae07d9 Mon Sep 17 00:00:00 2001 From: Atita Shirwaikar Date: Wed, 5 Jan 2011 02:00:55 +0000 Subject: ixgbe: Adding 100MB FULL support in ethtool Current driver does not show 100MB support in ethtool. Adding support for the same. Signed-off-by: Atita Shirwaikar Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_ethtool.c | 34 ++++++++++++++++++++++++++++++++-- drivers/net/ixgbe/ixgbe_main.c | 5 ++++- 2 files changed, 36 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 2002ea88ca2a..309272f8f103 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -152,7 +152,17 @@ static int ixgbe_get_settings(struct net_device *netdev, ecmd->supported |= (SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg); + switch (hw->mac.type) { + case ixgbe_mac_X540: + ecmd->supported |= SUPPORTED_100baseT_Full; + break; + default: + break; + } + ecmd->advertising = ADVERTISED_Autoneg; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) + ecmd->advertising |= ADVERTISED_100baseT_Full; if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) ecmd->advertising |= ADVERTISED_10000baseT_Full; if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) @@ -167,6 +177,15 @@ static int ixgbe_get_settings(struct net_device *netdev, ecmd->advertising |= (ADVERTISED_10000baseT_Full | ADVERTISED_1000baseT_Full); + switch (hw->mac.type) { + case ixgbe_mac_X540: + if (!(ecmd->advertising & ADVERTISED_100baseT_Full)) + ecmd->advertising |= (ADVERTISED_100baseT_Full); + break; + default: + break; + } + if (hw->phy.media_type == ixgbe_media_type_copper) { ecmd->supported |= SUPPORTED_TP; ecmd->advertising |= ADVERTISED_TP; @@ -271,8 +290,19 @@ static int ixgbe_get_settings(struct net_device *netdev, hw->mac.ops.check_link(hw, &link_speed, &link_up, false); if (link_up) { - ecmd->speed = (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ? - SPEED_10000 : SPEED_1000; + switch (link_speed) { + case IXGBE_LINK_SPEED_10GB_FULL: + ecmd->speed = SPEED_10000; + break; + case IXGBE_LINK_SPEED_1GB_FULL: + ecmd->speed = SPEED_1000; + break; + case IXGBE_LINK_SPEED_100_FULL: + ecmd->speed = SPEED_100; + break; + default: + break; + } ecmd->duplex = DUPLEX_FULL; } else { ecmd->speed = -1; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 4a6bcb66d2a8..4f81b5a00775 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -6102,7 +6102,10 @@ static void ixgbe_watchdog_task(struct work_struct *work) (link_speed == IXGBE_LINK_SPEED_10GB_FULL ? "10 Gbps" : (link_speed == IXGBE_LINK_SPEED_1GB_FULL ? - "1 Gbps" : "unknown speed")), + "1 Gbps" : + (link_speed == IXGBE_LINK_SPEED_100_FULL ? + "100 Mbps" : + "unknown speed"))), ((flow_rx && flow_tx) ? "RX/TX" : (flow_rx ? "RX" : (flow_tx ? "TX" : "None")))); -- cgit v1.2.3 From d9f51b51db2064c9049bf7924318fd8c6ed852cb Mon Sep 17 00:00:00 2001 From: Bala Shanmugam Date: Fri, 11 Feb 2011 15:38:53 +0530 Subject: Bluetooth: Add firmware support for Atheros 3012 Blacklisted AR3012 PID in btusb and added the same in ath3k to load patch and sysconfig files. Signed-off-by: Bala Shanmugam Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/ath3k.c | 279 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/bluetooth/btusb.c | 3 + 2 files changed, 282 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 41dadacd3d15..e6acaba1e45c 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -31,6 +31,30 @@ #define VERSION "1.0" +#define ATH3K_DNLOAD 0x01 +#define ATH3K_GETSTATE 0x05 +#define ATH3K_SET_NORMAL_MODE 0x07 +#define ATH3K_GETVERSION 0x09 +#define USB_REG_SWITCH_VID_PID 0x0a + +#define ATH3K_MODE_MASK 0x3F +#define ATH3K_NORMAL_MODE 0x0E + +#define ATH3K_PATCH_UPDATE 0x80 +#define ATH3K_SYSCFG_UPDATE 0x40 + +#define ATH3K_XTAL_FREQ_26M 0x00 +#define ATH3K_XTAL_FREQ_40M 0x01 +#define ATH3K_XTAL_FREQ_19P2 0x02 +#define ATH3K_NAME_LEN 0xFF + +struct ath3k_version { + unsigned int rom_version; + unsigned int build_version; + unsigned int ram_version; + unsigned char ref_clock; + unsigned char reserved[0x07]; +}; static struct usb_device_id ath3k_table[] = { /* Atheros AR3011 */ @@ -41,13 +65,29 @@ static struct usb_device_id ath3k_table[] = { /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03F0, 0x311D) }, + + /* Atheros AR3012 with sflash firmware*/ + { USB_DEVICE(0x0CF3, 0x3004) }, + { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, ath3k_table); +#define BTUSB_ATH3012 0x80 +/* This table is to load patch and sysconfig files + * for AR3012 */ +static struct usb_device_id ath3k_blist_tbl[] = { + + /* Atheros AR3012 with sflash firmware*/ + { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, + + { } /* Terminating entry */ +}; + #define USB_REQ_DFU_DNLOAD 1 #define BULK_SIZE 4096 +#define FW_HDR_SIZE 20 static int ath3k_load_firmware(struct usb_device *udev, const struct firmware *firmware) @@ -103,6 +143,215 @@ error: return err; } +static int ath3k_get_state(struct usb_device *udev, unsigned char *state) +{ + int pipe = 0; + + pipe = usb_rcvctrlpipe(udev, 0); + return usb_control_msg(udev, pipe, ATH3K_GETSTATE, + USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, + state, 0x01, USB_CTRL_SET_TIMEOUT); +} + +static int ath3k_get_version(struct usb_device *udev, + struct ath3k_version *version) +{ + int pipe = 0; + + pipe = usb_rcvctrlpipe(udev, 0); + return usb_control_msg(udev, pipe, ATH3K_GETVERSION, + USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, version, + sizeof(struct ath3k_version), + USB_CTRL_SET_TIMEOUT); +} + +static int ath3k_load_fwfile(struct usb_device *udev, + const struct firmware *firmware) +{ + u8 *send_buf; + int err, pipe, len, size, count, sent = 0; + int ret; + + count = firmware->size; + + send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC); + if (!send_buf) { + BT_ERR("Can't allocate memory chunk for firmware"); + return -ENOMEM; + } + + size = min_t(uint, count, FW_HDR_SIZE); + memcpy(send_buf, firmware->data, size); + + pipe = usb_sndctrlpipe(udev, 0); + ret = usb_control_msg(udev, pipe, ATH3K_DNLOAD, + USB_TYPE_VENDOR, 0, 0, send_buf, + size, USB_CTRL_SET_TIMEOUT); + if (ret < 0) { + BT_ERR("Can't change to loading configuration err"); + kfree(send_buf); + return ret; + } + + sent += size; + count -= size; + + while (count) { + size = min_t(uint, count, BULK_SIZE); + pipe = usb_sndbulkpipe(udev, 0x02); + + memcpy(send_buf, firmware->data + sent, size); + + err = usb_bulk_msg(udev, pipe, send_buf, size, + &len, 3000); + if (err || (len != size)) { + BT_ERR("Error in firmware loading err = %d," + "len = %d, size = %d", err, len, size); + kfree(send_buf); + return err; + } + sent += size; + count -= size; + } + + kfree(send_buf); + return 0; +} + +static int ath3k_switch_pid(struct usb_device *udev) +{ + int pipe = 0; + + pipe = usb_sndctrlpipe(udev, 0); + return usb_control_msg(udev, pipe, USB_REG_SWITCH_VID_PID, + USB_TYPE_VENDOR, 0, 0, + NULL, 0, USB_CTRL_SET_TIMEOUT); +} + +static int ath3k_set_normal_mode(struct usb_device *udev) +{ + unsigned char fw_state; + int pipe = 0, ret; + + ret = ath3k_get_state(udev, &fw_state); + if (ret < 0) { + BT_ERR("Can't get state to change to normal mode err"); + return ret; + } + + if ((fw_state & ATH3K_MODE_MASK) == ATH3K_NORMAL_MODE) { + BT_DBG("firmware was already in normal mode"); + return 0; + } + + pipe = usb_sndctrlpipe(udev, 0); + return usb_control_msg(udev, pipe, ATH3K_SET_NORMAL_MODE, + USB_TYPE_VENDOR, 0, 0, + NULL, 0, USB_CTRL_SET_TIMEOUT); +} + +static int ath3k_load_patch(struct usb_device *udev) +{ + unsigned char fw_state; + char filename[ATH3K_NAME_LEN] = {0}; + const struct firmware *firmware; + struct ath3k_version fw_version, pt_version; + int ret; + + ret = ath3k_get_state(udev, &fw_state); + if (ret < 0) { + BT_ERR("Can't get state to change to load ram patch err"); + return ret; + } + + if (fw_state & ATH3K_PATCH_UPDATE) { + BT_DBG("Patch was already downloaded"); + return 0; + } + + ret = ath3k_get_version(udev, &fw_version); + if (ret < 0) { + BT_ERR("Can't get version to change to load ram patch err"); + return ret; + } + + snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu", + fw_version.rom_version); + + ret = request_firmware(&firmware, filename, &udev->dev); + if (ret < 0) { + BT_ERR("Patch file not found %s", filename); + return ret; + } + + pt_version.rom_version = *(int *)(firmware->data + firmware->size - 8); + pt_version.build_version = *(int *) + (firmware->data + firmware->size - 4); + + if ((pt_version.rom_version != fw_version.rom_version) || + (pt_version.build_version <= fw_version.build_version)) { + BT_ERR("Patch file version did not match with firmware"); + release_firmware(firmware); + return -EINVAL; + } + + ret = ath3k_load_fwfile(udev, firmware); + release_firmware(firmware); + + return ret; +} + +static int ath3k_load_syscfg(struct usb_device *udev) +{ + unsigned char fw_state; + char filename[ATH3K_NAME_LEN] = {0}; + const struct firmware *firmware; + struct ath3k_version fw_version; + int clk_value, ret; + + ret = ath3k_get_state(udev, &fw_state); + if (ret < 0) { + BT_ERR("Can't get state to change to load configration err"); + return -EBUSY; + } + + ret = ath3k_get_version(udev, &fw_version); + if (ret < 0) { + BT_ERR("Can't get version to change to load ram patch err"); + return ret; + } + + switch (fw_version.ref_clock) { + + case ATH3K_XTAL_FREQ_26M: + clk_value = 26; + break; + case ATH3K_XTAL_FREQ_40M: + clk_value = 40; + break; + case ATH3K_XTAL_FREQ_19P2: + clk_value = 19; + break; + default: + clk_value = 0; + break; + } + + snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s", + fw_version.rom_version, clk_value, ".dfu"); + + ret = request_firmware(&firmware, filename, &udev->dev); + if (ret < 0) { + BT_ERR("Configuration file not found %s", filename); + return ret; + } + + ret = ath3k_load_fwfile(udev, firmware); + release_firmware(firmware); + + return ret; +} + static int ath3k_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -115,7 +364,37 @@ static int ath3k_probe(struct usb_interface *intf, if (intf->cur_altsetting->desc.bInterfaceNumber != 0) return -ENODEV; + /* match device ID in ath3k blacklist table */ + if (!id->driver_info) { + const struct usb_device_id *match; + match = usb_match_id(intf, ath3k_blist_tbl); + if (match) + id = match; + } + + /* load patch and sysconfig files for AR3012 */ + if (id->driver_info & BTUSB_ATH3012) { + ret = ath3k_load_patch(udev); + if (ret < 0) { + BT_ERR("Loading patch file failed"); + return ret; + } + ret = ath3k_load_syscfg(udev); + if (ret < 0) { + BT_ERR("Loading sysconfig file failed"); + return ret; + } + ret = ath3k_set_normal_mode(udev); + if (ret < 0) { + BT_ERR("Set normal mode failed"); + return ret; + } + ath3k_switch_pid(udev); + return 0; + } + if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) { + BT_ERR("Error loading firmware"); return -EIO; } diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 4cefa91e6c34..fa84109f1bdd 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -105,6 +105,9 @@ static struct usb_device_id blacklist_table[] = { /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, + /* Atheros 3012 with sflash firmware */ + { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_IGNORE }, + /* Broadcom BCM2035 */ { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, -- cgit v1.2.3 From 43067ed8aecac4410a0a629e504629ebece35206 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 10 Feb 2011 06:53:09 +0000 Subject: tg3: Avoid setting power.can_wakeup for devices that cannot wake up The tg3 driver uses device_init_wakeup() in such a way that the device's power.can_wakeup flag may be set even though the PCI subsystem cleared it before, in which case the device cannot wake up the system from sleep states. Modify the driver to only change the power.can_wakeup flag if the device is not capable of generating wakeup signals. Signed-off-by: Rafael J. Wysocki Acked-by: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/tg3.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index ecb3eb099bf6..6be418591df9 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -12463,9 +12463,11 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) tp->tg3_flags3 |= TG3_FLG3_RGMII_EXT_IBND_TX_EN; } done: - device_init_wakeup(&tp->pdev->dev, tp->tg3_flags & TG3_FLAG_WOL_CAP); - device_set_wakeup_enable(&tp->pdev->dev, + if (tp->tg3_flags & TG3_FLAG_WOL_CAP) + device_set_wakeup_enable(&tp->pdev->dev, tp->tg3_flags & TG3_FLAG_WOL_ENABLE); + else + device_set_wakeup_capable(&tp->pdev->dev, false); } static int __devinit tg3_issue_otp_command(struct tg3 *tp, u32 cmd) -- cgit v1.2.3 From 0303adeee3d6740cd78a71c0f40946b4886ceaa3 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 10 Feb 2011 06:54:04 +0000 Subject: atl1c: Do not call device_init_wakeup() in atl1c_probe() The atl1c driver shouldn't call device_init_wakeup() in its probe routine with the second argument equal to 1, because for PCI devices the wakeup capability setting is initialized as appropriate by the PCI subsystem. Remove the potentially harmful call. Signed-off-by: Rafael J. Wysocki Signed-off-by: David S. Miller --- drivers/net/atl1c/atl1c_main.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 3824382faecc..e60595f0247c 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -2718,7 +2718,6 @@ static int __devinit atl1c_probe(struct pci_dev *pdev, goto err_reset; } - device_init_wakeup(&pdev->dev, 1); /* reset the controller to * put the device in a known good starting state */ err = atl1c_phy_init(&adapter->hw); -- cgit v1.2.3 From dd68153def6b890a23288776cbd5bd2bad223a3f Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 10 Feb 2011 06:55:19 +0000 Subject: atl1: Do not use legacy PCI power management The atl1 driver uses the legacy PCI power management, so it has to do some PCI-specific things in its ->suspend() and ->resume() callbacks, which isn't necessary and should better be done by the PCI subsystem-level power management code. Convert atl1 to the new PCI power management framework and make it let the PCI subsystem take care of all the PCI-specific aspects of device handling during system power transitions. Tested-by: Thomas Fjellstrom Signed-off-by: Rafael J. Wysocki Signed-off-by: David S. Miller --- drivers/net/atlx/atl1.c | 77 ++++++++++++++++++++----------------------------- 1 file changed, 31 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 3b527687c28f..67f40b9c16ed 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -950,6 +950,7 @@ static int __devinit atl1_sw_init(struct atl1_adapter *adapter) hw->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; adapter->wol = 0; + device_set_wakeup_enable(&adapter->pdev->dev, false); adapter->rx_buffer_len = (hw->max_frame_size + 7) & ~7; adapter->ict = 50000; /* 100ms */ adapter->link_speed = SPEED_0; /* hardware init */ @@ -2735,15 +2736,15 @@ static int atl1_close(struct net_device *netdev) } #ifdef CONFIG_PM -static int atl1_suspend(struct pci_dev *pdev, pm_message_t state) +static int atl1_suspend(struct device *dev) { + struct pci_dev *pdev = to_pci_dev(dev); struct net_device *netdev = pci_get_drvdata(pdev); struct atl1_adapter *adapter = netdev_priv(netdev); struct atl1_hw *hw = &adapter->hw; u32 ctrl = 0; u32 wufc = adapter->wol; u32 val; - int retval; u16 speed; u16 duplex; @@ -2751,17 +2752,15 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state) if (netif_running(netdev)) atl1_down(adapter); - retval = pci_save_state(pdev); - if (retval) - return retval; - atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl); val = ctrl & BMSR_LSTATUS; if (val) wufc &= ~ATLX_WUFC_LNKC; + if (!wufc) + goto disable_wol; - if (val && wufc) { + if (val) { val = atl1_get_speed_and_duplex(hw, &speed, &duplex); if (val) { if (netif_msg_ifdown(adapter)) @@ -2798,23 +2797,18 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state) ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC); ioread32(hw->hw_addr + REG_PCIE_PHYMISC); - - pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); - goto exit; - } - - if (!val && wufc) { + } else { ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN); iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL); ioread32(hw->hw_addr + REG_WOL_CTRL); iowrite32(0, hw->hw_addr + REG_MAC_CTRL); ioread32(hw->hw_addr + REG_MAC_CTRL); hw->phy_configured = false; - pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); - goto exit; } -disable_wol: + return 0; + + disable_wol: iowrite32(0, hw->hw_addr + REG_WOL_CTRL); ioread32(hw->hw_addr + REG_WOL_CTRL); ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC); @@ -2822,37 +2816,17 @@ disable_wol: iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC); ioread32(hw->hw_addr + REG_PCIE_PHYMISC); hw->phy_configured = false; - pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); -exit: - if (netif_running(netdev)) - pci_disable_msi(adapter->pdev); - pci_disable_device(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); return 0; } -static int atl1_resume(struct pci_dev *pdev) +static int atl1_resume(struct device *dev) { + struct pci_dev *pdev = to_pci_dev(dev); struct net_device *netdev = pci_get_drvdata(pdev); struct atl1_adapter *adapter = netdev_priv(netdev); - u32 err; - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - - err = pci_enable_device(pdev); - if (err) { - if (netif_msg_ifup(adapter)) - dev_printk(KERN_DEBUG, &pdev->dev, - "error enabling pci device\n"); - return err; - } - - pci_set_master(pdev); iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL); - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); atl1_reset_hw(&adapter->hw); @@ -2864,16 +2838,25 @@ static int atl1_resume(struct pci_dev *pdev) return 0; } + +static SIMPLE_DEV_PM_OPS(atl1_pm_ops, atl1_suspend, atl1_resume); +#define ATL1_PM_OPS (&atl1_pm_ops) + #else -#define atl1_suspend NULL -#define atl1_resume NULL + +static int atl1_suspend(struct device *dev) { return 0; } + +#define ATL1_PM_OPS NULL #endif static void atl1_shutdown(struct pci_dev *pdev) { -#ifdef CONFIG_PM - atl1_suspend(pdev, PMSG_SUSPEND); -#endif + struct net_device *netdev = pci_get_drvdata(pdev); + struct atl1_adapter *adapter = netdev_priv(netdev); + + atl1_suspend(&pdev->dev); + pci_wake_from_d3(pdev, adapter->wol); + pci_set_power_state(pdev, PCI_D3hot); } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -3117,9 +3100,8 @@ static struct pci_driver atl1_driver = { .id_table = atl1_pci_tbl, .probe = atl1_probe, .remove = __devexit_p(atl1_remove), - .suspend = atl1_suspend, - .resume = atl1_resume, - .shutdown = atl1_shutdown + .shutdown = atl1_shutdown, + .driver.pm = ATL1_PM_OPS, }; /* @@ -3409,6 +3391,9 @@ static int atl1_set_wol(struct net_device *netdev, adapter->wol = 0; if (wol->wolopts & WAKE_MAGIC) adapter->wol |= ATLX_WUFC_MAG; + + device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); + return 0; } -- cgit v1.2.3 From b052181a985592f81767f631f9f42accb4b436cd Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 11 Feb 2011 15:23:56 +0000 Subject: xen: events: mark cpu_evtchn_mask_p as __refdata This variable starts out pointing at init_evtchn_mask which is marked __initdata but is set to point to a non-init data region in xen_init_IRQ which is itself an __init function so this is safe. Signed-off-by: Ian Campbell Tested-and-acked-by: Andrew Jones Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 74681478100a..a31389036b15 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -114,7 +114,7 @@ struct cpu_evtchn_s { static __initdata struct cpu_evtchn_s init_evtchn_mask = { .bits[0 ... (NR_EVENT_CHANNELS/BITS_PER_LONG)-1] = ~0ul, }; -static struct cpu_evtchn_s *cpu_evtchn_mask_p = &init_evtchn_mask; +static struct cpu_evtchn_s __refdata *cpu_evtchn_mask_p = &init_evtchn_mask; static inline unsigned long *cpu_evtchn_mask(int cpu) { -- cgit v1.2.3 From c4197c6298750d308fc819c0525902f49ab920fb Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sun, 6 Feb 2011 08:56:35 -0800 Subject: iwlagn: donot process bt update when bt coex disable If bt coex is disabled, do not process any bt related information from uCode even received. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 3aa486437509..325ff5c89ee8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1832,7 +1832,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) * IBSS mode (no proper uCode support for coex then). */ if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) { - bt_cmd.flags = 0; + bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_DISABLED; } else { bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_3W << IWLAGN_BT_FLAG_COEX_MODE_SHIFT; @@ -1869,6 +1869,11 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) struct iwl_rxon_context *ctx; int smps_request = -1; + if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) { + /* bt coex disabled */ + return; + } + /* * Note: bt_traffic_load can be overridden by scan complete and * coex profile notifications. Ignore that since only bad consequence @@ -2022,6 +2027,11 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; + if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) { + /* bt coex disabled */ + return; + } + IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status); IWL_DEBUG_NOTIF(priv, " traffic load: %d\n", coex->bt_traffic_load); -- cgit v1.2.3 From caebbb7a4ac3e31b259954b757b15b8f0ac708d5 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sun, 6 Feb 2011 11:29:42 -0800 Subject: iwlagn: handle bt defer work in 2000 series For 2000 series, need to handle bt traffic changes when receive notification from uCode Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-2000.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 3c5dd36ff417..30483e27ce5c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -265,7 +265,8 @@ static struct iwl_lib_ops iwl2000_lib = { .txq_free_tfd = iwl_hw_txq_free_tfd, .txq_init = iwl_hw_tx_queue_init, .rx_handler_setup = iwlagn_rx_handler_setup, - .setup_deferred_work = iwlagn_setup_deferred_work, + .setup_deferred_work = iwlagn_bt_setup_deferred_work, + .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, .load_ucode = iwlagn_load_ucode, .dump_nic_event_log = iwl_dump_nic_event_log, -- cgit v1.2.3 From 62e63975f47fcc0ebcaca04669098fe3ca7b20a2 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 11 Feb 2011 14:27:46 -0600 Subject: rtlwifi: Modify core routines The rtlwifi core needs some changes before inclusion of a driver for the RTL8192CU USB device. Signed-off-by: Larry Finger Signed-off-by: Signed-off-by: Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.h | 1 + drivers/net/wireless/rtlwifi/debug.h | 1 + drivers/net/wireless/rtlwifi/pci.c | 85 ++++-------------------------------- drivers/net/wireless/rtlwifi/pci.h | 12 ++--- drivers/net/wireless/rtlwifi/wifi.h | 45 ++++++++++++++++--- 5 files changed, 56 insertions(+), 88 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h index 3de5a14745f1..c95982b030da 100644 --- a/drivers/net/wireless/rtlwifi/base.h +++ b/drivers/net/wireless/rtlwifi/base.h @@ -30,6 +30,7 @@ #define __RTL_BASE_H__ #define RTL_DUMMY_OFFSET 0 +#define RTL_RX_DESC_SIZE 24 #define RTL_DUMMY_UNIT 8 #define RTL_TX_DUMMY_SIZE (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT) #define RTL_TX_DESC_SIZE 32 diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index 08bdec2ceda4..e4aa8687408c 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h @@ -105,6 +105,7 @@ #define COMP_MAC80211 BIT(26) #define COMP_REGD BIT(27) #define COMP_CHAN BIT(28) +#define COMP_USB BIT(29) /*-------------------------------------------------------------- Define the rt_print components diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 1758d4463247..a508ea51a1f8 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -690,75 +690,6 @@ done: } -void _rtl_pci_tx_interrupt(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - int prio; - - for (prio = 0; prio < RTL_PCI_MAX_TX_QUEUE_COUNT; prio++) { - struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio]; - - while (skb_queue_len(&ring->queue)) { - struct rtl_tx_desc *entry = &ring->desc[ring->idx]; - struct sk_buff *skb; - struct ieee80211_tx_info *info; - u8 own; - - /* - *beacon packet will only use the first - *descriptor defautly, and the own may not - *be cleared by the hardware, and - *beacon will free in prepare beacon - */ - if (prio == BEACON_QUEUE || prio == TXCMD_QUEUE || - prio == HCCA_QUEUE) - break; - - own = (u8)rtlpriv->cfg->ops->get_desc((u8 *)entry, - true, - HW_DESC_OWN); - - if (own) - break; - - skb = __skb_dequeue(&ring->queue); - pci_unmap_single(rtlpci->pdev, - le32_to_cpu(rtlpriv->cfg->ops-> - get_desc((u8 *) entry, - true, - HW_DESC_TXBUFF_ADDR)), - skb->len, PCI_DMA_TODEVICE); - - ring->idx = (ring->idx + 1) % ring->entries; - - info = IEEE80211_SKB_CB(skb); - ieee80211_tx_info_clear_status(info); - - info->flags |= IEEE80211_TX_STAT_ACK; - /*info->status.rates[0].count = 1; */ - - ieee80211_tx_status_irqsafe(hw, skb); - - if ((ring->entries - skb_queue_len(&ring->queue)) - == 2 && prio != BEACON_QUEUE) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("more desc left, wake " - "skb_queue@%d,ring->idx = %d," - "skb_queue_len = 0x%d\n", - prio, ring->idx, - skb_queue_len(&ring->queue))); - - ieee80211_wake_queue(hw, - skb_get_queue_mapping - (skb)); - } - - skb = NULL; - } - } -} - static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) { struct ieee80211_hw *hw = dev_id; @@ -1273,7 +1204,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) return 0; } -unsigned int _rtl_mac_to_hwqueue(u16 fc, +static unsigned int _rtl_mac_to_hwqueue(u16 fc, unsigned int mac80211_queue_index) { unsigned int hw_queue_index; @@ -1312,7 +1243,7 @@ out: return hw_queue_index; } -int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); @@ -1429,7 +1360,7 @@ int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb) return 0; } -void rtl_pci_deinit(struct ieee80211_hw *hw) +static void rtl_pci_deinit(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); @@ -1444,7 +1375,7 @@ void rtl_pci_deinit(struct ieee80211_hw *hw) } -int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) +static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) { struct rtl_priv *rtlpriv = rtl_priv(hw); int err; @@ -1461,7 +1392,7 @@ int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) return 1; } -int rtl_pci_start(struct ieee80211_hw *hw) +static int rtl_pci_start(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); @@ -1496,7 +1427,7 @@ int rtl_pci_start(struct ieee80211_hw *hw) return 0; } -void rtl_pci_stop(struct ieee80211_hw *hw) +static void rtl_pci_stop(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); @@ -1838,7 +1769,7 @@ fail3: ieee80211_free_hw(hw); if (rtlpriv->io.pci_mem_start != 0) - pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start); + pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); fail2: pci_release_regions(pdev); @@ -1888,7 +1819,7 @@ void rtl_pci_disconnect(struct pci_dev *pdev) } if (rtlpriv->io.pci_mem_start != 0) { - pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start); + pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); pci_release_regions(pdev); } diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h index d36a66939958..0caa81429726 100644 --- a/drivers/net/wireless/rtlwifi/pci.h +++ b/drivers/net/wireless/rtlwifi/pci.h @@ -244,34 +244,34 @@ int rtl_pci_resume(struct pci_dev *pdev); static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr) { - return 0xff & readb((u8 *) rtlpriv->io.pci_mem_start + addr); + return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr); } static inline u16 pci_read16_sync(struct rtl_priv *rtlpriv, u32 addr) { - return readw((u8 *) rtlpriv->io.pci_mem_start + addr); + return readw((u8 __iomem *) rtlpriv->io.pci_mem_start + addr); } static inline u32 pci_read32_sync(struct rtl_priv *rtlpriv, u32 addr) { - return readl((u8 *) rtlpriv->io.pci_mem_start + addr); + return readl((u8 __iomem *) rtlpriv->io.pci_mem_start + addr); } static inline void pci_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val) { - writeb(val, (u8 *) rtlpriv->io.pci_mem_start + addr); + writeb(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr); } static inline void pci_write16_async(struct rtl_priv *rtlpriv, u32 addr, u16 val) { - writew(val, (u8 *) rtlpriv->io.pci_mem_start + addr); + writew(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr); } static inline void pci_write32_async(struct rtl_priv *rtlpriv, u32 addr, u32 val) { - writel(val, (u8 *) rtlpriv->io.pci_mem_start + addr); + writel(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr); } static inline void rtl_pci_raw_write_port_ulong(u32 port, u32 val) diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index d44d79613d2d..ef44b75a66d2 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include "debug.h" @@ -118,6 +119,9 @@ enum hardware_type { HARDWARE_TYPE_NUM }; +#define IS_HARDWARE_TYPE_8192CE(rtlhal) \ + (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) + enum scan_operation_backup_opt { SCAN_OPT_BACKUP = 0, SCAN_OPT_RESTORE, @@ -768,6 +772,7 @@ struct rtl_tid_data { struct rtl_priv; struct rtl_io { struct device *dev; + struct mutex bb_mutex; /*PCI MEM map */ unsigned long pci_mem_end; /*shared mem end */ @@ -779,10 +784,14 @@ struct rtl_io { void (*write8_async) (struct rtl_priv *rtlpriv, u32 addr, u8 val); void (*write16_async) (struct rtl_priv *rtlpriv, u32 addr, u16 val); void (*write32_async) (struct rtl_priv *rtlpriv, u32 addr, u32 val); + int (*writeN_async) (struct rtl_priv *rtlpriv, u32 addr, u16 len, + u8 *pdata); u8(*read8_sync) (struct rtl_priv *rtlpriv, u32 addr); u16(*read16_sync) (struct rtl_priv *rtlpriv, u32 addr); u32(*read32_sync) (struct rtl_priv *rtlpriv, u32 addr); + int (*readN_sync) (struct rtl_priv *rtlpriv, u32 addr, u16 len, + u8 *pdata); }; @@ -1101,6 +1110,7 @@ struct rtl_tcb_desc { struct rtl_hal_ops { int (*init_sw_vars) (struct ieee80211_hw *hw); void (*deinit_sw_vars) (struct ieee80211_hw *hw); + void (*read_chip_version)(struct ieee80211_hw *hw); void (*read_eeprom_info) (struct ieee80211_hw *hw); void (*interrupt_recognized) (struct ieee80211_hw *hw, u32 *p_inta, u32 *p_intb); @@ -1129,7 +1139,8 @@ struct rtl_hal_ops { void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc, bool b_firstseg, bool b_lastseg, struct sk_buff *skb); - bool(*query_rx_desc) (struct ieee80211_hw *hw, + bool (*cmd_send_packet)(struct ieee80211_hw *hw, struct sk_buff *skb); + bool(*query_rx_desc) (struct ieee80211_hw *hw, struct rtl_stats *stats, struct ieee80211_rx_status *rx_status, u8 *pdesc, struct sk_buff *skb); @@ -1166,6 +1177,7 @@ struct rtl_intf_ops { int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb); int (*reset_trx_ring) (struct ieee80211_hw *hw); + bool (*waitq_insert) (struct ieee80211_hw *hw, struct sk_buff *skb); /*pci */ void (*disable_aspm) (struct ieee80211_hw *hw); @@ -1179,11 +1191,35 @@ struct rtl_mod_params { int sw_crypto; }; +struct rtl_hal_usbint_cfg { + /* data - rx */ + u32 in_ep_num; + u32 rx_urb_num; + u32 rx_max_size; + + /* op - rx */ + void (*usb_rx_hdl)(struct ieee80211_hw *, struct sk_buff *); + void (*usb_rx_segregate_hdl)(struct ieee80211_hw *, struct sk_buff *, + struct sk_buff_head *); + + /* tx */ + void (*usb_tx_cleanup)(struct ieee80211_hw *, struct sk_buff *); + int (*usb_tx_post_hdl)(struct ieee80211_hw *, struct urb *, + struct sk_buff *); + struct sk_buff *(*usb_tx_aggregate_hdl)(struct ieee80211_hw *, + struct sk_buff_head *); + + /* endpoint mapping */ + int (*usb_endpoint_mapping)(struct ieee80211_hw *hw); + u16 (*usb_mq_to_hwq)(u16 fc, u16 mac80211_queue_index); +}; + struct rtl_hal_cfg { char *name; char *fw_name; struct rtl_hal_ops *ops; struct rtl_mod_params *mod_params; + struct rtl_hal_usbint_cfg *usb_interface_cfg; /*this map used for some registers or vars defined int HAL but used in MAIN */ @@ -1202,6 +1238,7 @@ struct rtl_locks { spinlock_t rf_ps_lock; spinlock_t rf_lock; spinlock_t lps_lock; + spinlock_t tx_urb_lock; }; struct rtl_works { @@ -1437,10 +1474,8 @@ Set subfield of little-endian 4-byte value to specified value. */ (_os).octet = (u8 *)(_octet); \ (_os).length = (_len); -#define CP_MACADDR(des, src) \ - ((des)[0] = (src)[0], (des)[1] = (src)[1],\ - (des)[2] = (src)[2], (des)[3] = (src)[3],\ - (des)[4] = (src)[4], (des)[5] = (src)[5]) +#define CP_MACADDR(des, src) \ + memcpy((des), (src), ETH_ALEN) static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr) { -- cgit v1.2.3 From 2ca20f79e0d895489ae2f79fa321077e5ee2981d Mon Sep 17 00:00:00 2001 From: George Date: Fri, 11 Feb 2011 14:27:49 -0600 Subject: rtlwifi: Add usb driver Signed-off-by: Larry Finger Signed-off-by: George Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/Makefile | 3 +- drivers/net/wireless/rtlwifi/usb.c | 1035 +++++++++++++++++++++++++++++++++ drivers/net/wireless/rtlwifi/usb.h | 164 ++++++ 3 files changed, 1201 insertions(+), 1 deletion(-) create mode 100644 drivers/net/wireless/rtlwifi/usb.c create mode 100644 drivers/net/wireless/rtlwifi/usb.h (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile index 2a7a4384f8ee..efbff2f478bf 100644 --- a/drivers/net/wireless/rtlwifi/Makefile +++ b/drivers/net/wireless/rtlwifi/Makefile @@ -8,6 +8,7 @@ rtlwifi-objs := \ pci.o \ ps.o \ rc.o \ - regd.o + regd.o \ + usb.o obj-$(CONFIG_RTL8192CE) += rtl8192ce/ diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c new file mode 100644 index 000000000000..fbf24a0f9054 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -0,0 +1,1035 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + *****************************************************************************/ +#include +#include "core.h" +#include "wifi.h" +#include "usb.h" +#include "base.h" +#include "ps.h" + +#define REALTEK_USB_VENQT_READ 0xC0 +#define REALTEK_USB_VENQT_WRITE 0x40 +#define REALTEK_USB_VENQT_CMD_REQ 0x05 +#define REALTEK_USB_VENQT_CMD_IDX 0x00 + +#define REALTEK_USB_VENQT_MAX_BUF_SIZE 254 + +static void usbctrl_async_callback(struct urb *urb) +{ + if (urb) + kfree(urb->context); +} + +static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request, + u16 value, u16 index, void *pdata, + u16 len) +{ + int rc; + unsigned int pipe; + u8 reqtype; + struct usb_ctrlrequest *dr; + struct urb *urb; + struct rtl819x_async_write_data { + u8 data[REALTEK_USB_VENQT_MAX_BUF_SIZE]; + struct usb_ctrlrequest dr; + } *buf; + + pipe = usb_sndctrlpipe(udev, 0); /* write_out */ + reqtype = REALTEK_USB_VENQT_WRITE; + + buf = kmalloc(sizeof(*buf), GFP_ATOMIC); + if (!buf) + return -ENOMEM; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) { + kfree(buf); + return -ENOMEM; + } + + dr = &buf->dr; + + dr->bRequestType = reqtype; + dr->bRequest = request; + dr->wValue = cpu_to_le16(value); + dr->wIndex = cpu_to_le16(index); + dr->wLength = cpu_to_le16(len); + memcpy(buf, pdata, len); + usb_fill_control_urb(urb, udev, pipe, + (unsigned char *)dr, buf, len, + usbctrl_async_callback, buf); + rc = usb_submit_urb(urb, GFP_ATOMIC); + if (rc < 0) + kfree(buf); + usb_free_urb(urb); + return rc; +} + +static int _usbctrl_vendorreq_sync_read(struct usb_device *udev, u8 request, + u16 value, u16 index, void *pdata, + u16 len) +{ + unsigned int pipe; + int status; + u8 reqtype; + + pipe = usb_rcvctrlpipe(udev, 0); /* read_in */ + reqtype = REALTEK_USB_VENQT_READ; + + status = usb_control_msg(udev, pipe, request, reqtype, value, index, + pdata, len, 0); /* max. timeout */ + + if (status < 0) + printk(KERN_ERR "reg 0x%x, usbctrl_vendorreq TimeOut! " + "status:0x%x value=0x%x\n", value, status, + *(u32 *)pdata); + return status; +} + +static u32 _usb_read_sync(struct usb_device *udev, u32 addr, u16 len) +{ + u8 request; + u16 wvalue; + u16 index; + u32 *data; + u32 ret; + + data = kmalloc(sizeof(u32), GFP_KERNEL); + if (!data) + return -ENOMEM; + request = REALTEK_USB_VENQT_CMD_REQ; + index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */ + + wvalue = (u16)addr; + _usbctrl_vendorreq_sync_read(udev, request, wvalue, index, data, len); + ret = le32_to_cpu(*data); + kfree(data); + return ret; +} + +static u8 _usb_read8_sync(struct rtl_priv *rtlpriv, u32 addr) +{ + struct device *dev = rtlpriv->io.dev; + + return (u8)_usb_read_sync(to_usb_device(dev), addr, 1); +} + +static u16 _usb_read16_sync(struct rtl_priv *rtlpriv, u32 addr) +{ + struct device *dev = rtlpriv->io.dev; + + return (u16)_usb_read_sync(to_usb_device(dev), addr, 2); +} + +static u32 _usb_read32_sync(struct rtl_priv *rtlpriv, u32 addr) +{ + struct device *dev = rtlpriv->io.dev; + + return _usb_read_sync(to_usb_device(dev), addr, 4); +} + +static void _usb_write_async(struct usb_device *udev, u32 addr, u32 val, + u16 len) +{ + u8 request; + u16 wvalue; + u16 index; + u32 data; + + request = REALTEK_USB_VENQT_CMD_REQ; + index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */ + wvalue = (u16)(addr&0x0000ffff); + data = cpu_to_le32(val); + _usbctrl_vendorreq_async_write(udev, request, wvalue, index, &data, + len); +} + +static void _usb_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val) +{ + struct device *dev = rtlpriv->io.dev; + + _usb_write_async(to_usb_device(dev), addr, val, 1); +} + +static void _usb_write16_async(struct rtl_priv *rtlpriv, u32 addr, u16 val) +{ + struct device *dev = rtlpriv->io.dev; + + _usb_write_async(to_usb_device(dev), addr, val, 2); +} + +static void _usb_write32_async(struct rtl_priv *rtlpriv, u32 addr, u32 val) +{ + struct device *dev = rtlpriv->io.dev; + + _usb_write_async(to_usb_device(dev), addr, val, 4); +} + +static int _usb_nbytes_read_write(struct usb_device *udev, bool read, u32 addr, + u16 len, u8 *pdata) +{ + int status; + u8 request; + u16 wvalue; + u16 index; + + request = REALTEK_USB_VENQT_CMD_REQ; + index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */ + wvalue = (u16)addr; + if (read) + status = _usbctrl_vendorreq_sync_read(udev, request, wvalue, + index, pdata, len); + else + status = _usbctrl_vendorreq_async_write(udev, request, wvalue, + index, pdata, len); + return status; +} + +static int _usb_readN_sync(struct rtl_priv *rtlpriv, u32 addr, u16 len, + u8 *pdata) +{ + struct device *dev = rtlpriv->io.dev; + + return _usb_nbytes_read_write(to_usb_device(dev), true, addr, len, + pdata); +} + +static int _usb_writeN_async(struct rtl_priv *rtlpriv, u32 addr, u16 len, + u8 *pdata) +{ + struct device *dev = rtlpriv->io.dev; + + return _usb_nbytes_read_write(to_usb_device(dev), false, addr, len, + pdata); +} + +static void _rtl_usb_io_handler_init(struct device *dev, + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->io.dev = dev; + mutex_init(&rtlpriv->io.bb_mutex); + rtlpriv->io.write8_async = _usb_write8_async; + rtlpriv->io.write16_async = _usb_write16_async; + rtlpriv->io.write32_async = _usb_write32_async; + rtlpriv->io.writeN_async = _usb_writeN_async; + rtlpriv->io.read8_sync = _usb_read8_sync; + rtlpriv->io.read16_sync = _usb_read16_sync; + rtlpriv->io.read32_sync = _usb_read32_sync; + rtlpriv->io.readN_sync = _usb_readN_sync; +} + +static void _rtl_usb_io_handler_release(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + mutex_destroy(&rtlpriv->io.bb_mutex); +} + +/** + * + * Default aggregation handler. Do nothing and just return the oldest skb. + */ +static struct sk_buff *_none_usb_tx_aggregate_hdl(struct ieee80211_hw *hw, + struct sk_buff_head *list) +{ + return skb_dequeue(list); +} + +#define IS_HIGH_SPEED_USB(udev) \ + ((USB_SPEED_HIGH == (udev)->speed) ? true : false) + +static int _rtl_usb_init_tx(struct ieee80211_hw *hw) +{ + u32 i; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + rtlusb->max_bulk_out_size = IS_HIGH_SPEED_USB(rtlusb->udev) + ? USB_HIGH_SPEED_BULK_SIZE + : USB_FULL_SPEED_BULK_SIZE; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("USB Max Bulk-out Size=%d\n", + rtlusb->max_bulk_out_size)); + + for (i = 0; i < __RTL_TXQ_NUM; i++) { + u32 ep_num = rtlusb->ep_map.ep_mapping[i]; + if (!ep_num) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("Invalid endpoint map setting!\n")); + return -EINVAL; + } + } + + rtlusb->usb_tx_post_hdl = + rtlpriv->cfg->usb_interface_cfg->usb_tx_post_hdl; + rtlusb->usb_tx_cleanup = + rtlpriv->cfg->usb_interface_cfg->usb_tx_cleanup; + rtlusb->usb_tx_aggregate_hdl = + (rtlpriv->cfg->usb_interface_cfg->usb_tx_aggregate_hdl) + ? rtlpriv->cfg->usb_interface_cfg->usb_tx_aggregate_hdl + : &_none_usb_tx_aggregate_hdl; + + init_usb_anchor(&rtlusb->tx_submitted); + for (i = 0; i < RTL_USB_MAX_EP_NUM; i++) { + skb_queue_head_init(&rtlusb->tx_skb_queue[i]); + init_usb_anchor(&rtlusb->tx_pending[i]); + } + return 0; +} + +static int _rtl_usb_init_rx(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); + + rtlusb->rx_max_size = rtlpriv->cfg->usb_interface_cfg->rx_max_size; + rtlusb->rx_urb_num = rtlpriv->cfg->usb_interface_cfg->rx_urb_num; + rtlusb->in_ep = rtlpriv->cfg->usb_interface_cfg->in_ep_num; + rtlusb->usb_rx_hdl = rtlpriv->cfg->usb_interface_cfg->usb_rx_hdl; + rtlusb->usb_rx_segregate_hdl = + rtlpriv->cfg->usb_interface_cfg->usb_rx_segregate_hdl; + + printk(KERN_INFO "rtl8192cu: rx_max_size %d, rx_urb_num %d, in_ep %d\n", + rtlusb->rx_max_size, rtlusb->rx_urb_num, rtlusb->in_ep); + init_usb_anchor(&rtlusb->rx_submitted); + return 0; +} + +static int _rtl_usb_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); + int err; + u8 epidx; + struct usb_interface *usb_intf = rtlusb->intf; + u8 epnums = usb_intf->cur_altsetting->desc.bNumEndpoints; + + rtlusb->out_ep_nums = rtlusb->in_ep_nums = 0; + for (epidx = 0; epidx < epnums; epidx++) { + struct usb_endpoint_descriptor *pep_desc; + pep_desc = &usb_intf->cur_altsetting->endpoint[epidx].desc; + + if (usb_endpoint_dir_in(pep_desc)) + rtlusb->in_ep_nums++; + else if (usb_endpoint_dir_out(pep_desc)) + rtlusb->out_ep_nums++; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("USB EP(0x%02x), MaxPacketSize=%d ,Interval=%d.\n", + pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize, + pep_desc->bInterval)); + } + if (rtlusb->in_ep_nums < rtlpriv->cfg->usb_interface_cfg->in_ep_num) + return -EINVAL ; + + /* usb endpoint mapping */ + err = rtlpriv->cfg->usb_interface_cfg->usb_endpoint_mapping(hw); + rtlusb->usb_mq_to_hwq = rtlpriv->cfg->usb_interface_cfg->usb_mq_to_hwq; + _rtl_usb_init_tx(hw); + _rtl_usb_init_rx(hw); + return err; +} + +static int _rtl_usb_init_sw(struct ieee80211_hw *hw) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + rtlhal->hw = hw; + ppsc->b_inactiveps = false; + ppsc->b_leisure_ps = false; + ppsc->b_fwctrl_lps = false; + ppsc->b_reg_fwctrl_lps = 3; + ppsc->reg_max_lps_awakeintvl = 5; + ppsc->fwctrl_psmode = FW_PS_DTIM_MODE; + + /* IBSS */ + mac->beacon_interval = 100; + + /* AMPDU */ + mac->min_space_cfg = 0; + mac->max_mss_density = 0; + + /* set sane AMPDU defaults */ + mac->current_ampdu_density = 7; + mac->current_ampdu_factor = 3; + + /* QOS */ + rtlusb->acm_method = eAcmWay2_SW; + + /* IRQ */ + /* HIMR - turn all on */ + rtlusb->irq_mask[0] = 0xFFFFFFFF; + /* HIMR_EX - turn all on */ + rtlusb->irq_mask[1] = 0xFFFFFFFF; + rtlusb->disableHWSM = true; + return 0; +} + +#define __RADIO_TAP_SIZE_RSV 32 + +static void _rtl_rx_completed(struct urb *urb); + +static struct sk_buff *_rtl_prep_rx_urb(struct ieee80211_hw *hw, + struct rtl_usb *rtlusb, + struct urb *urb, + gfp_t gfp_mask) +{ + struct sk_buff *skb; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + skb = __dev_alloc_skb((rtlusb->rx_max_size + __RADIO_TAP_SIZE_RSV), + gfp_mask); + if (!skb) { + RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, + ("Failed to __dev_alloc_skb!!\n")) + return ERR_PTR(-ENOMEM); + } + + /* reserve some space for mac80211's radiotap */ + skb_reserve(skb, __RADIO_TAP_SIZE_RSV); + usb_fill_bulk_urb(urb, rtlusb->udev, + usb_rcvbulkpipe(rtlusb->udev, rtlusb->in_ep), + skb->data, min(skb_tailroom(skb), + (int)rtlusb->rx_max_size), + _rtl_rx_completed, skb); + + _rtl_install_trx_info(rtlusb, skb, rtlusb->in_ep); + return skb; +} + +#undef __RADIO_TAP_SIZE_RSV + +static void _rtl_usb_rx_process_agg(struct ieee80211_hw *hw, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 *rxdesc = skb->data; + struct ieee80211_hdr *hdr; + bool unicast = false; + u16 fc; + struct ieee80211_rx_status rx_status = {0}; + struct rtl_stats stats = { + .signal = 0, + .noise = -98, + .rate = 0, + }; + + skb_pull(skb, RTL_RX_DESC_SIZE); + rtlpriv->cfg->ops->query_rx_desc(hw, &stats, &rx_status, rxdesc, skb); + skb_pull(skb, (stats.rx_drvinfo_size + stats.rx_bufshift)); + hdr = (struct ieee80211_hdr *)(skb->data); + fc = le16_to_cpu(hdr->frame_control); + if (!stats.b_crc) { + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); + + if (is_broadcast_ether_addr(hdr->addr1)) { + /*TODO*/; + } else if (is_multicast_ether_addr(hdr->addr1)) { + /*TODO*/ + } else { + unicast = true; + rtlpriv->stats.rxbytesunicast += skb->len; + } + + rtl_is_special_data(hw, skb, false); + + if (ieee80211_is_data(fc)) { + rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); + + if (unicast) + rtlpriv->link_info.num_rx_inperiod++; + } + } +} + +static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 *rxdesc = skb->data; + struct ieee80211_hdr *hdr; + bool unicast = false; + u16 fc; + struct ieee80211_rx_status rx_status = {0}; + struct rtl_stats stats = { + .signal = 0, + .noise = -98, + .rate = 0, + }; + + skb_pull(skb, RTL_RX_DESC_SIZE); + rtlpriv->cfg->ops->query_rx_desc(hw, &stats, &rx_status, rxdesc, skb); + skb_pull(skb, (stats.rx_drvinfo_size + stats.rx_bufshift)); + hdr = (struct ieee80211_hdr *)(skb->data); + fc = le16_to_cpu(hdr->frame_control); + if (!stats.b_crc) { + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); + + if (is_broadcast_ether_addr(hdr->addr1)) { + /*TODO*/; + } else if (is_multicast_ether_addr(hdr->addr1)) { + /*TODO*/ + } else { + unicast = true; + rtlpriv->stats.rxbytesunicast += skb->len; + } + + rtl_is_special_data(hw, skb, false); + + if (ieee80211_is_data(fc)) { + rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); + + if (unicast) + rtlpriv->link_info.num_rx_inperiod++; + } + if (likely(rtl_action_proc(hw, skb, false))) { + struct sk_buff *uskb = NULL; + u8 *pdata; + + uskb = dev_alloc_skb(skb->len + 128); + memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, + sizeof(rx_status)); + pdata = (u8 *)skb_put(uskb, skb->len); + memcpy(pdata, skb->data, skb->len); + dev_kfree_skb_any(skb); + ieee80211_rx_irqsafe(hw, uskb); + } else { + dev_kfree_skb_any(skb); + } + } +} + +static void _rtl_rx_pre_process(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct sk_buff *_skb; + struct sk_buff_head rx_queue; + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + skb_queue_head_init(&rx_queue); + if (rtlusb->usb_rx_segregate_hdl) + rtlusb->usb_rx_segregate_hdl(hw, skb, &rx_queue); + WARN_ON(skb_queue_empty(&rx_queue)); + while (!skb_queue_empty(&rx_queue)) { + _skb = skb_dequeue(&rx_queue); + _rtl_usb_rx_process_agg(hw, skb); + ieee80211_rx_irqsafe(hw, skb); + } +} + +static void _rtl_rx_completed(struct urb *_urb) +{ + struct sk_buff *skb = (struct sk_buff *)_urb->context; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct rtl_usb *rtlusb = (struct rtl_usb *)info->rate_driver_data[0]; + struct ieee80211_hw *hw = usb_get_intfdata(rtlusb->intf); + struct rtl_priv *rtlpriv = rtl_priv(hw); + int err = 0; + + if (unlikely(IS_USB_STOP(rtlusb))) + goto free; + + if (likely(0 == _urb->status)) { + /* If this code were moved to work queue, would CPU + * utilization be improved? NOTE: We shall allocate another skb + * and reuse the original one. + */ + skb_put(skb, _urb->actual_length); + + if (likely(!rtlusb->usb_rx_segregate_hdl)) { + struct sk_buff *_skb; + _rtl_usb_rx_process_noagg(hw, skb); + _skb = _rtl_prep_rx_urb(hw, rtlusb, _urb, GFP_ATOMIC); + if (IS_ERR(_skb)) { + err = PTR_ERR(_skb); + RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, + ("Can't allocate skb for bulk IN!\n")); + return; + } + skb = _skb; + } else{ + /* TO DO */ + _rtl_rx_pre_process(hw, skb); + printk(KERN_ERR "rtlwifi: rx agg not supported\n"); + } + goto resubmit; + } + + switch (_urb->status) { + /* disconnect */ + case -ENOENT: + case -ECONNRESET: + case -ENODEV: + case -ESHUTDOWN: + goto free; + default: + break; + } + +resubmit: + skb_reset_tail_pointer(skb); + skb_trim(skb, 0); + + usb_anchor_urb(_urb, &rtlusb->rx_submitted); + err = usb_submit_urb(_urb, GFP_ATOMIC); + if (unlikely(err)) { + usb_unanchor_urb(_urb); + goto free; + } + return; + +free: + dev_kfree_skb_irq(skb); +} + +static int _rtl_usb_receive(struct ieee80211_hw *hw) +{ + struct urb *urb; + struct sk_buff *skb; + int err; + int i; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + WARN_ON(0 == rtlusb->rx_urb_num); + /* 1600 == 1514 + max WLAN header + rtk info */ + WARN_ON(rtlusb->rx_max_size < 1600); + + for (i = 0; i < rtlusb->rx_urb_num; i++) { + err = -ENOMEM; + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) { + RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, + ("Failed to alloc URB!!\n")) + goto err_out; + } + + skb = _rtl_prep_rx_urb(hw, rtlusb, urb, GFP_KERNEL); + if (IS_ERR(skb)) { + RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, + ("Failed to prep_rx_urb!!\n")) + err = PTR_ERR(skb); + goto err_out; + } + + usb_anchor_urb(urb, &rtlusb->rx_submitted); + err = usb_submit_urb(urb, GFP_KERNEL); + if (err) + goto err_out; + usb_free_urb(urb); + } + return 0; + +err_out: + usb_kill_anchored_urbs(&rtlusb->rx_submitted); + return err; +} + +static int rtl_usb_start(struct ieee80211_hw *hw) +{ + int err; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + err = rtlpriv->cfg->ops->hw_init(hw); + rtl_init_rx_config(hw); + + /* Enable software */ + SET_USB_START(rtlusb); + /* should after adapter start and interrupt enable. */ + set_hal_start(rtlhal); + + /* Start bulk IN */ + _rtl_usb_receive(hw); + + return err; +} +/** + * + * + */ + +/*======================= tx =========================================*/ +static void rtl_usb_cleanup(struct ieee80211_hw *hw) +{ + u32 i; + struct sk_buff *_skb; + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + struct ieee80211_tx_info *txinfo; + + SET_USB_STOP(rtlusb); + + /* clean up rx stuff. */ + usb_kill_anchored_urbs(&rtlusb->rx_submitted); + + /* clean up tx stuff */ + for (i = 0; i < RTL_USB_MAX_EP_NUM; i++) { + while ((_skb = skb_dequeue(&rtlusb->tx_skb_queue[i]))) { + rtlusb->usb_tx_cleanup(hw, _skb); + txinfo = IEEE80211_SKB_CB(_skb); + ieee80211_tx_info_clear_status(txinfo); + txinfo->flags |= IEEE80211_TX_STAT_ACK; + ieee80211_tx_status_irqsafe(hw, _skb); + } + usb_kill_anchored_urbs(&rtlusb->tx_pending[i]); + } + usb_kill_anchored_urbs(&rtlusb->tx_submitted); +} + +/** + * + * We may add some struct into struct rtl_usb later. Do deinit here. + * + */ +static void rtl_usb_deinit(struct ieee80211_hw *hw) +{ + rtl_usb_cleanup(hw); +} + +static void rtl_usb_stop(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + /* should after adapter start and interrupt enable. */ + set_hal_stop(rtlhal); + /* Enable software */ + SET_USB_STOP(rtlusb); + rtl_usb_deinit(hw); + rtlpriv->cfg->ops->hw_disable(hw); +} + +static void _rtl_submit_tx_urb(struct ieee80211_hw *hw, struct urb *_urb) +{ + int err; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + usb_anchor_urb(_urb, &rtlusb->tx_submitted); + err = usb_submit_urb(_urb, GFP_ATOMIC); + if (err < 0) { + struct sk_buff *skb; + + RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, + ("Failed to submit urb.\n")); + usb_unanchor_urb(_urb); + skb = (struct sk_buff *)_urb->context; + kfree_skb(skb); + } + usb_free_urb(_urb); +} + +static int _usb_tx_post(struct ieee80211_hw *hw, struct urb *urb, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + struct ieee80211_tx_info *txinfo; + + rtlusb->usb_tx_post_hdl(hw, urb, skb); + skb_pull(skb, RTL_TX_HEADER_SIZE); + txinfo = IEEE80211_SKB_CB(skb); + ieee80211_tx_info_clear_status(txinfo); + txinfo->flags |= IEEE80211_TX_STAT_ACK; + + if (urb->status) { + RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, + ("Urb has error status 0x%X\n", urb->status)); + goto out; + } + /* TODO: statistics */ +out: + ieee80211_tx_status_irqsafe(hw, skb); + return urb->status; +} + +static void _rtl_tx_complete(struct urb *urb) +{ + struct sk_buff *skb = (struct sk_buff *)urb->context; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct rtl_usb *rtlusb = (struct rtl_usb *)info->rate_driver_data[0]; + struct ieee80211_hw *hw = usb_get_intfdata(rtlusb->intf); + int err; + + if (unlikely(IS_USB_STOP(rtlusb))) + return; + err = _usb_tx_post(hw, urb, skb); + if (err) { + /* Ignore error and keep issuiing other urbs */ + return; + } +} + +static struct urb *_rtl_usb_tx_urb_setup(struct ieee80211_hw *hw, + struct sk_buff *skb, u32 ep_num) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + struct urb *_urb; + + WARN_ON(NULL == skb); + _urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!_urb) { + RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, + ("Can't allocate URB for bulk out!\n")); + kfree_skb(skb); + return NULL; + } + _rtl_install_trx_info(rtlusb, skb, ep_num); + usb_fill_bulk_urb(_urb, rtlusb->udev, usb_sndbulkpipe(rtlusb->udev, + ep_num), skb->data, skb->len, _rtl_tx_complete, skb); + _urb->transfer_flags |= URB_ZERO_PACKET; + return _urb; +} + +static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, + enum rtl_txq qnum) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + u32 ep_num; + struct urb *_urb = NULL; + struct sk_buff *_skb = NULL; + struct sk_buff_head *skb_list; + struct usb_anchor *urb_list; + + WARN_ON(NULL == rtlusb->usb_tx_aggregate_hdl); + if (unlikely(IS_USB_STOP(rtlusb))) { + RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, + ("USB device is stopping...\n")); + kfree_skb(skb); + return; + } + ep_num = rtlusb->ep_map.ep_mapping[qnum]; + skb_list = &rtlusb->tx_skb_queue[ep_num]; + _skb = skb; + _urb = _rtl_usb_tx_urb_setup(hw, _skb, ep_num); + if (unlikely(!_urb)) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Can't allocate urb. Drop skb!\n")); + return; + } + urb_list = &rtlusb->tx_pending[ep_num]; + _rtl_submit_tx_urb(hw, _urb); +} + +static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb, + u16 hw_queue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct rtl_tx_desc *pdesc = NULL; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); + u16 fc = le16_to_cpu(hdr->frame_control); + u8 *pda_addr = hdr->addr1; + /* ssn */ + u8 *qc = NULL; + u8 tid = 0; + u16 seq_number = 0; + + if (ieee80211_is_mgmt(fc)) + rtl_tx_mgmt_proc(hw, skb); + rtl_action_proc(hw, skb, true); + if (is_multicast_ether_addr(pda_addr)) + rtlpriv->stats.txbytesmulticast += skb->len; + else if (is_broadcast_ether_addr(pda_addr)) + rtlpriv->stats.txbytesbroadcast += skb->len; + else + rtlpriv->stats.txbytesunicast += skb->len; + if (ieee80211_is_data_qos(fc)) { + qc = ieee80211_get_qos_ctl(hdr); + tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; + seq_number = (le16_to_cpu(hdr->seq_ctrl) & + IEEE80211_SCTL_SEQ) >> 4; + seq_number += 1; + seq_number <<= 4; + } + rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, info, skb, + hw_queue); + if (!ieee80211_has_morefrags(hdr->frame_control)) { + if (qc) + mac->tids[tid].seq_number = seq_number; + } + if (ieee80211_is_data(fc)) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX); +} + +static int rtl_usb_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); + u16 fc = le16_to_cpu(hdr->frame_control); + u16 hw_queue; + + if (unlikely(is_hal_stop(rtlhal))) + goto err_free; + hw_queue = rtlusb->usb_mq_to_hwq(fc, skb_get_queue_mapping(skb)); + _rtl_usb_tx_preprocess(hw, skb, hw_queue); + _rtl_usb_transmit(hw, skb, hw_queue); + return NETDEV_TX_OK; + +err_free: + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; +} + +static bool rtl_usb_tx_chk_waitq_insert(struct ieee80211_hw *hw, + struct sk_buff *skb) +{ + return false; +} + +static struct rtl_intf_ops rtl_usb_ops = { + .adapter_start = rtl_usb_start, + .adapter_stop = rtl_usb_stop, + .adapter_tx = rtl_usb_tx, + .waitq_insert = rtl_usb_tx_chk_waitq_insert, +}; + +int __devinit rtl_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + int err; + struct ieee80211_hw *hw = NULL; + struct rtl_priv *rtlpriv = NULL; + struct usb_device *udev; + struct rtl_usb_priv *usb_priv; + + hw = ieee80211_alloc_hw(sizeof(struct rtl_priv) + + sizeof(struct rtl_usb_priv), &rtl_ops); + if (!hw) { + RT_ASSERT(false, ("%s : ieee80211 alloc failed\n", __func__)); + return -ENOMEM; + } + rtlpriv = hw->priv; + SET_IEEE80211_DEV(hw, &intf->dev); + udev = interface_to_usbdev(intf); + usb_get_dev(udev); + usb_priv = rtl_usbpriv(hw); + memset(usb_priv, 0, sizeof(*usb_priv)); + usb_priv->dev.intf = intf; + usb_priv->dev.udev = udev; + usb_set_intfdata(intf, hw); + /* init cfg & intf_ops */ + rtlpriv->rtlhal.interface = INTF_USB; + rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_info); + rtlpriv->intf_ops = &rtl_usb_ops; + rtl_dbgp_flag_init(hw); + /* Init IO handler */ + _rtl_usb_io_handler_init(&udev->dev, hw); + rtlpriv->cfg->ops->read_chip_version(hw); + /*like read eeprom and so on */ + rtlpriv->cfg->ops->read_eeprom_info(hw); + if (rtlpriv->cfg->ops->init_sw_vars(hw)) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Can't init_sw_vars.\n")); + goto error_out; + } + rtlpriv->cfg->ops->init_sw_leds(hw); + err = _rtl_usb_init(hw); + err = _rtl_usb_init_sw(hw); + /* Init mac80211 sw */ + err = rtl_init_core(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Can't allocate sw for mac80211.\n")); + goto error_out; + } + + /*init rfkill */ + /* rtl_init_rfkill(hw); */ + + err = ieee80211_register_hw(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, + ("Can't register mac80211 hw.\n")); + goto error_out; + } else { + rtlpriv->mac80211.mac80211_registered = 1; + } + set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); + return 0; +error_out: + rtl_deinit_core(hw); + _rtl_usb_io_handler_release(hw); + ieee80211_free_hw(hw); + usb_put_dev(udev); + return -ENODEV; +} +EXPORT_SYMBOL(rtl_usb_probe); + +void rtl_usb_disconnect(struct usb_interface *intf) +{ + struct ieee80211_hw *hw = usb_get_intfdata(intf); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + if (unlikely(!rtlpriv)) + return; + /*ieee80211_unregister_hw will call ops_stop */ + if (rtlmac->mac80211_registered == 1) { + ieee80211_unregister_hw(hw); + rtlmac->mac80211_registered = 0; + } else { + rtl_deinit_deferred_work(hw); + rtlpriv->intf_ops->adapter_stop(hw); + } + /*deinit rfkill */ + /* rtl_deinit_rfkill(hw); */ + rtl_usb_deinit(hw); + rtl_deinit_core(hw); + rtlpriv->cfg->ops->deinit_sw_leds(hw); + rtlpriv->cfg->ops->deinit_sw_vars(hw); + _rtl_usb_io_handler_release(hw); + usb_put_dev(rtlusb->udev); + usb_set_intfdata(intf, NULL); + ieee80211_free_hw(hw); +} +EXPORT_SYMBOL(rtl_usb_disconnect); + +int rtl_usb_suspend(struct usb_interface *pusb_intf, pm_message_t message) +{ + return 0; +} +EXPORT_SYMBOL(rtl_usb_suspend); + +int rtl_usb_resume(struct usb_interface *pusb_intf) +{ + return 0; +} +EXPORT_SYMBOL(rtl_usb_resume); diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h new file mode 100644 index 000000000000..c83311655104 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/usb.h @@ -0,0 +1,164 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + *****************************************************************************/ + +#ifndef __RTL_USB_H__ +#define __RTL_USB_H__ + +#include +#include + +#define RTL_USB_DEVICE(vend, prod, cfg) \ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, \ + .idVendor = (vend), \ + .idProduct = (prod), \ + .driver_info = (kernel_ulong_t)&(cfg) + +#define USB_HIGH_SPEED_BULK_SIZE 512 +#define USB_FULL_SPEED_BULK_SIZE 64 + + +#define RTL_USB_MAX_TXQ_NUM 4 /* max tx queue */ +#define RTL_USB_MAX_EP_NUM 6 /* max ep number */ +#define RTL_USB_MAX_TX_URBS_NUM 8 + +enum rtl_txq { + /* These definitions shall be consistent with value + * returned by skb_get_queue_mapping + *------------------------------------*/ + RTL_TXQ_BK, + RTL_TXQ_BE, + RTL_TXQ_VI, + RTL_TXQ_VO, + /*------------------------------------*/ + RTL_TXQ_BCN, + RTL_TXQ_MGT, + RTL_TXQ_HI, + + /* Must be last */ + __RTL_TXQ_NUM, +}; + +struct rtl_ep_map { + u32 ep_mapping[__RTL_TXQ_NUM]; +}; + +struct _trx_info { + struct rtl_usb *rtlusb; + u32 ep_num; +}; + +static inline void _rtl_install_trx_info(struct rtl_usb *rtlusb, + struct sk_buff *skb, + u32 ep_num) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + info->rate_driver_data[0] = rtlusb; + info->rate_driver_data[1] = (void *)(__kernel_size_t)ep_num; +} + + +/* Add suspend/resume later */ +enum rtl_usb_state { + USB_STATE_STOP = 0, + USB_STATE_START = 1, +}; + +#define IS_USB_STOP(rtlusb_ptr) (USB_STATE_STOP == (rtlusb_ptr)->state) +#define IS_USB_START(rtlusb_ptr) (USB_STATE_START == (rtlusb_ptr)->state) +#define SET_USB_STOP(rtlusb_ptr) \ + do { \ + (rtlusb_ptr)->state = USB_STATE_STOP; \ + } while (0) + +#define SET_USB_START(rtlusb_ptr) \ + do { \ + (rtlusb_ptr)->state = USB_STATE_START; \ + } while (0) + +struct rtl_usb { + struct usb_device *udev; + struct usb_interface *intf; + enum rtl_usb_state state; + + /* Bcn control register setting */ + u32 reg_bcn_ctrl_val; + /* for 88/92cu card disable */ + u8 disableHWSM; + /*QOS & EDCA */ + enum acm_method acm_method; + /* irq . HIMR,HIMR_EX */ + u32 irq_mask[2]; + bool irq_enabled; + + u16 (*usb_mq_to_hwq)(u16 fc, u16 mac80211_queue_index); + + /* Tx */ + u8 out_ep_nums ; + u8 out_queue_sel; + struct rtl_ep_map ep_map; + + u32 max_bulk_out_size; + u32 tx_submitted_urbs; + struct sk_buff_head tx_skb_queue[RTL_USB_MAX_EP_NUM]; + + struct usb_anchor tx_pending[RTL_USB_MAX_EP_NUM]; + struct usb_anchor tx_submitted; + + struct sk_buff *(*usb_tx_aggregate_hdl)(struct ieee80211_hw *, + struct sk_buff_head *); + int (*usb_tx_post_hdl)(struct ieee80211_hw *, + struct urb *, struct sk_buff *); + void (*usb_tx_cleanup)(struct ieee80211_hw *, struct sk_buff *); + + /* Rx */ + u8 in_ep_nums ; + u32 in_ep; /* Bulk IN endpoint number */ + u32 rx_max_size; /* Bulk IN max buffer size */ + u32 rx_urb_num; /* How many Bulk INs are submitted to host. */ + struct usb_anchor rx_submitted; + void (*usb_rx_segregate_hdl)(struct ieee80211_hw *, struct sk_buff *, + struct sk_buff_head *); + void (*usb_rx_hdl)(struct ieee80211_hw *, struct sk_buff *); +}; + +struct rtl_usb_priv { + struct rtl_usb dev; + struct rtl_led_ctl ledctl; +}; + +#define rtl_usbpriv(hw) (((struct rtl_usb_priv *)(rtl_priv(hw))->priv)) +#define rtl_usbdev(usbpriv) (&((usbpriv)->dev)) + + + +int __devinit rtl_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id); +void rtl_usb_disconnect(struct usb_interface *intf); +int rtl_usb_suspend(struct usb_interface *pusb_intf, pm_message_t message); +int rtl_usb_resume(struct usb_interface *pusb_intf); + +#endif -- cgit v1.2.3 From 8c96fcf7212bd58f28cf7e96b13b1e2161637f3b Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 11 Feb 2011 14:33:58 -0600 Subject: rtlwifi: rtl8192ce: Refactor rtl8192ce/dm To reuse as much code as possible when adding additional drivers to the rtlwifi tree, the common parts of various routines are moved to drivers/net/wireless/rtlwifi. This patch does that for the version of dm.{h,c} used by rtl8192ce. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 1388 +++++++++++++++++++++ drivers/net/wireless/rtlwifi/rtl8192ce/dm.c | 1359 +------------------- drivers/net/wireless/rtlwifi/rtl8192ce/dm.h | 1 + drivers/net/wireless/rtlwifi/wifi.h | 2 +- 4 files changed, 1392 insertions(+), 1358 deletions(-) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c new file mode 100644 index 000000000000..b08b7802f04f --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -0,0 +1,1388 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +struct dig_t dm_digtable; +static struct ps_t dm_pstable; + +static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { + 0x7f8001fe, + 0x788001e2, + 0x71c001c7, + 0x6b8001ae, + 0x65400195, + 0x5fc0017f, + 0x5a400169, + 0x55400155, + 0x50800142, + 0x4c000130, + 0x47c0011f, + 0x43c0010f, + 0x40000100, + 0x3c8000f2, + 0x390000e4, + 0x35c000d7, + 0x32c000cb, + 0x300000c0, + 0x2d4000b5, + 0x2ac000ab, + 0x288000a2, + 0x26000098, + 0x24000090, + 0x22000088, + 0x20000080, + 0x1e400079, + 0x1c800072, + 0x1b00006c, + 0x19800066, + 0x18000060, + 0x16c0005b, + 0x15800056, + 0x14400051, + 0x1300004c, + 0x12000048, + 0x11000044, + 0x10000040, +}; + +static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, + {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, + {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, + {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, + {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, + {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, + {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, + {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, + {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, + {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, + {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, + {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, + {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, + {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, + {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, + {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, + {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, + {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, + {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, + {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, + {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, + {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, + {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, + {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, + {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, + {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, + {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, + {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, + {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, + {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, + {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, + {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, + {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} +}; + +static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, + {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, + {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, + {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, + {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, + {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, + {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, + {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, + {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, + {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, + {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, + {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, + {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, + {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, + {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, + {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, + {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, + {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, + {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, + {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, + {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, + {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, + {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, + {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, + {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, + {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, + {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, + {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, + {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, + {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} +}; + +static void rtl92c_dm_diginit(struct ieee80211_hw *hw) +{ + dm_digtable.dig_enable_flag = true; + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + dm_digtable.cur_igvalue = 0x20; + dm_digtable.pre_igvalue = 0x0; + dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; + dm_digtable.presta_connectstate = DIG_STA_DISCONNECT; + dm_digtable.curmultista_connectstate = DIG_MULTISTA_DISCONNECT; + dm_digtable.rssi_lowthresh = DM_DIG_THRESH_LOW; + dm_digtable.rssi_highthresh = DM_DIG_THRESH_HIGH; + dm_digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW; + dm_digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH; + dm_digtable.rx_gain_range_max = DM_DIG_MAX; + dm_digtable.rx_gain_range_min = DM_DIG_MIN; + dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; + dm_digtable.backoff_val_range_max = DM_DIG_BACKOFF_MAX; + dm_digtable.backoff_val_range_min = DM_DIG_BACKOFF_MIN; + dm_digtable.pre_cck_pd_state = CCK_PD_STAGE_MAX; + dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; +} + +static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + long rssi_val_min = 0; + + if ((dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) && + (dm_digtable.cursta_connectctate == DIG_STA_CONNECT)) { + if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb != 0) + rssi_val_min = + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb > + rtlpriv->dm.undecorated_smoothed_pwdb) ? + rtlpriv->dm.undecorated_smoothed_pwdb : + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + else + rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; + } else if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT || + dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT) { + rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; + } else if (dm_digtable.curmultista_connectstate == + DIG_MULTISTA_CONNECT) { + rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + } + + return (u8) rssi_val_min; +} + +static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) +{ + u32 ret_value; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); + falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); + falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); + falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); + falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); + falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail; + + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); + falsealm_cnt->cnt_cck_fail = ret_value; + + ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3); + falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; + falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail + + falsealm_cnt->cnt_rate_illegal + + falsealm_cnt->cnt_crc8_fail + + falsealm_cnt->cnt_mcs_fail + + falsealm_cnt->cnt_cck_fail); + + rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1); + rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0); + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("cnt_parity_fail = %d, cnt_rate_illegal = %d, " + "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", + falsealm_cnt->cnt_parity_fail, + falsealm_cnt->cnt_rate_illegal, + falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail)); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", + falsealm_cnt->cnt_ofdm_fail, + falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all)); +} + +static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value_igi = dm_digtable.cur_igvalue; + + if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) + value_igi--; + else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1) + value_igi += 0; + else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2) + value_igi++; + else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2) + value_igi += 2; + if (value_igi > DM_DIG_FA_UPPER) + value_igi = DM_DIG_FA_UPPER; + else if (value_igi < DM_DIG_FA_LOWER) + value_igi = DM_DIG_FA_LOWER; + if (rtlpriv->falsealm_cnt.cnt_all > 10000) + value_igi = 0x32; + + dm_digtable.cur_igvalue = value_igi; + rtl92c_dm_write_dig(hw); +} + +static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable.fa_highthresh) { + if ((dm_digtable.backoff_val - 2) < + dm_digtable.backoff_val_range_min) + dm_digtable.backoff_val = + dm_digtable.backoff_val_range_min; + else + dm_digtable.backoff_val -= 2; + } else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable.fa_lowthresh) { + if ((dm_digtable.backoff_val + 2) > + dm_digtable.backoff_val_range_max) + dm_digtable.backoff_val = + dm_digtable.backoff_val_range_max; + else + dm_digtable.backoff_val += 2; + } + + if ((dm_digtable.rssi_val_min + 10 - dm_digtable.backoff_val) > + dm_digtable.rx_gain_range_max) + dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_max; + else if ((dm_digtable.rssi_val_min + 10 - + dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min) + dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_min; + else + dm_digtable.cur_igvalue = dm_digtable.rssi_val_min + 10 - + dm_digtable.backoff_val; + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("rssi_val_min = %x backoff_val %x\n", + dm_digtable.rssi_val_min, dm_digtable.backoff_val)); + + rtl92c_dm_write_dig(hw); +} + +static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) +{ + static u8 binitialized; /* initialized to false */ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + bool b_multi_sta = false; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + b_multi_sta = true; + + if ((b_multi_sta == false) || (dm_digtable.cursta_connectctate != + DIG_STA_DISCONNECT)) { + binitialized = false; + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + return; + } else if (binitialized == false) { + binitialized = true; + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; + dm_digtable.cur_igvalue = 0x20; + rtl92c_dm_write_dig(hw); + } + + if (dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) { + if ((rssi_strength < dm_digtable.rssi_lowthresh) && + (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { + + if (dm_digtable.dig_ext_port_stage == + DIG_EXT_PORT_STAGE_2) { + dm_digtable.cur_igvalue = 0x20; + rtl92c_dm_write_dig(hw); + } + + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_1; + } else if (rssi_strength > dm_digtable.rssi_highthresh) { + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_2; + rtl92c_dm_ctrl_initgain_by_fa(hw); + } + } else if (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) { + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; + dm_digtable.cur_igvalue = 0x20; + rtl92c_dm_write_dig(hw); + } + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("curmultista_connectstate = " + "%x dig_ext_port_stage %x\n", + dm_digtable.curmultista_connectstate, + dm_digtable.dig_ext_port_stage)); +} + +static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("presta_connectstate = %x," + " cursta_connectctate = %x\n", + dm_digtable.presta_connectstate, + dm_digtable.cursta_connectctate)); + + if (dm_digtable.presta_connectstate == dm_digtable.cursta_connectctate + || dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT + || dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { + + if (dm_digtable.cursta_connectctate != DIG_STA_DISCONNECT) { + dm_digtable.rssi_val_min = + rtl92c_dm_initial_gain_min_pwdb(hw); + rtl92c_dm_ctrl_initgain_by_rssi(hw); + } + } else { + dm_digtable.rssi_val_min = 0; + dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; + dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; + dm_digtable.cur_igvalue = 0x20; + dm_digtable.pre_igvalue = 0; + rtl92c_dm_write_dig(hw); + } +} + +static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { + dm_digtable.rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); + + if (dm_digtable.pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { + if (dm_digtable.rssi_val_min <= 25) + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_LowRssi; + else + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_HighRssi; + } else { + if (dm_digtable.rssi_val_min <= 20) + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_LowRssi; + else + dm_digtable.cur_cck_pd_state = + CCK_PD_STAGE_HighRssi; + } + } else { + dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; + } + + if (dm_digtable.pre_cck_pd_state != dm_digtable.cur_cck_pd_state) { + if (dm_digtable.cur_cck_pd_state == CCK_PD_STAGE_LowRssi) { + if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) + dm_digtable.cur_cck_fa_state = + CCK_FA_STAGE_High; + else + dm_digtable.cur_cck_fa_state = CCK_FA_STAGE_Low; + + if (dm_digtable.pre_cck_fa_state != + dm_digtable.cur_cck_fa_state) { + if (dm_digtable.cur_cck_fa_state == + CCK_FA_STAGE_Low) + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, + 0x83); + else + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, + 0xcd); + + dm_digtable.pre_cck_fa_state = + dm_digtable.cur_cck_fa_state; + } + + rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40); + + if (IS_92C_SERIAL(rtlhal->version)) + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, + MASKBYTE2, 0xd7); + } else { + rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); + rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47); + + if (IS_92C_SERIAL(rtlhal->version)) + rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, + MASKBYTE2, 0xd3); + } + dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state; + } + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("CCKPDStage=%x\n", dm_digtable.cur_cck_pd_state)); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, + ("is92C=%x\n", IS_92C_SERIAL(rtlhal->version))); +} + +static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + if (mac->act_scanning == true) + return; + + if ((mac->link_state > MAC80211_NOLINK) && + (mac->link_state < MAC80211_LINKED)) + dm_digtable.cursta_connectctate = DIG_STA_BEFORE_CONNECT; + else if (mac->link_state >= MAC80211_LINKED) + dm_digtable.cursta_connectctate = DIG_STA_CONNECT; + else + dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; + + rtl92c_dm_initial_gain_sta(hw); + rtl92c_dm_initial_gain_multi_sta(hw); + rtl92c_dm_cck_packet_detection_thresh(hw); + + dm_digtable.presta_connectstate = dm_digtable.cursta_connectctate; + +} + +static void rtl92c_dm_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->dm.b_dm_initialgain_enable == false) + return; + if (dm_digtable.dig_enable_flag == false) + return; + + rtl92c_dm_ctrl_initgain_by_twoport(hw); + +} + +static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.bdynamic_txpower_enable = false; + + rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; +} + +void rtl92c_dm_write_dig(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + ("cur_igvalue = 0x%x, " + "pre_igvalue = 0x%x, backoff_val = %d\n", + dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, + dm_digtable.backoff_val)); + + if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { + rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, + dm_digtable.cur_igvalue); + rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, + dm_digtable.cur_igvalue); + + dm_digtable.pre_igvalue = dm_digtable.cur_igvalue; + } +} + +static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff; + + u8 h2c_parameter[3] = { 0 }; + + return; + + if (tmpentry_max_pwdb != 0) { + rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = + tmpentry_max_pwdb; + } else { + rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = 0; + } + + if (tmpentry_min_pwdb != 0xff) { + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = + tmpentry_min_pwdb; + } else { + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = 0; + } + + h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF); + h2c_parameter[0] = 0; + + rtl92c_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter); +} + +void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + rtlpriv->dm.bcurrent_turbo_edca = false; + rtlpriv->dm.bis_any_nonbepkts = false; + rtlpriv->dm.bis_cur_rdlstate = false; +} + +static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + static u64 last_txok_cnt; + static u64 last_rxok_cnt; + u64 cur_txok_cnt; + u64 cur_rxok_cnt; + u32 edca_be_ul = 0x5ea42b; + u32 edca_be_dl = 0x5ea42b; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + goto dm_checkedcaturbo_exit; + + if (mac->link_state != MAC80211_LINKED) { + rtlpriv->dm.bcurrent_turbo_edca = false; + return; + } + + if (!mac->ht_enable) { /*FIX MERGE */ + if (!(edca_be_ul & 0xffff0000)) + edca_be_ul |= 0x005e0000; + + if (!(edca_be_dl & 0xffff0000)) + edca_be_dl |= 0x005e0000; + } + + if ((!rtlpriv->dm.bis_any_nonbepkts) && + (!rtlpriv->dm.b_disable_framebursting)) { + cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; + cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; + if (cur_rxok_cnt > 4 * cur_txok_cnt) { + if (!rtlpriv->dm.bis_cur_rdlstate || + !rtlpriv->dm.bcurrent_turbo_edca) { + rtl_write_dword(rtlpriv, + REG_EDCA_BE_PARAM, + edca_be_dl); + rtlpriv->dm.bis_cur_rdlstate = true; + } + } else { + if (rtlpriv->dm.bis_cur_rdlstate || + !rtlpriv->dm.bcurrent_turbo_edca) { + rtl_write_dword(rtlpriv, + REG_EDCA_BE_PARAM, + edca_be_ul); + rtlpriv->dm.bis_cur_rdlstate = false; + } + } + rtlpriv->dm.bcurrent_turbo_edca = true; + } else { + if (rtlpriv->dm.bcurrent_turbo_edca) { + u8 tmp = AC0_BE; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AC_PARAM, + (u8 *) (&tmp)); + rtlpriv->dm.bcurrent_turbo_edca = false; + } + } + +dm_checkedcaturbo_exit: + rtlpriv->dm.bis_any_nonbepkts = false; + last_txok_cnt = rtlpriv->stats.txbytesunicast; + last_rxok_cnt = rtlpriv->stats.rxbytesunicast; +} + +static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw + *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 thermalvalue, delta, delta_lck, delta_iqk; + long ele_a, ele_d, temp_cck, val_x, value32; + long val_y, ele_c; + u8 ofdm_index[2], cck_index, ofdm_index_old[2], cck_index_old; + int i; + bool is2t = IS_92C_SERIAL(rtlhal->version); + u8 txpwr_level[2] = {0, 0}; + u8 ofdm_min_index = 6, rf; + + rtlpriv->dm.btxpower_trackingInit = true; + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n")); + + thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f); + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " + "eeprom_thermalmeter 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter)); + + rtl92c_phy_ap_calibrate(hw, (thermalvalue - + rtlefuse->eeprom_thermalmeter)); + if (is2t) + rf = 2; + else + rf = 1; + + if (thermalvalue) { + ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD) & MASKOFDM_D; + + for (i = 0; i < OFDM_TABLE_LENGTH; i++) { + if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { + ofdm_index_old[0] = (u8) i; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Initial pathA ele_d reg0x%x = 0x%lx, " + "ofdm_index=0x%x\n", + ROFDM0_XATXIQIMBALANCE, + ele_d, ofdm_index_old[0])); + break; + } + } + + if (is2t) { + ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, + MASKDWORD) & MASKOFDM_D; + + for (i = 0; i < OFDM_TABLE_LENGTH; i++) { + if (ele_d == (ofdmswing_table[i] & + MASKOFDM_D)) { + ofdm_index_old[1] = (u8) i; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + ("Initial pathB ele_d reg0x%x = " + "0x%lx, ofdm_index=0x%x\n", + ROFDM0_XBTXIQIMBALANCE, ele_d, + ofdm_index_old[1])); + break; + } + } + } + + temp_cck = + rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK; + + for (i = 0; i < CCK_TABLE_LENGTH; i++) { + if (rtlpriv->dm.b_cck_inch14) { + if (memcmp((void *)&temp_cck, + (void *)&cckswing_table_ch14[i][2], + 4) == 0) { + cck_index_old = (u8) i; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + ("Initial reg0x%x = 0x%lx, " + "cck_index=0x%x, ch 14 %d\n", + RCCK0_TXFILTER2, temp_cck, + cck_index_old, + rtlpriv->dm.b_cck_inch14)); + break; + } + } else { + if (memcmp((void *)&temp_cck, + (void *) + &cckswing_table_ch1ch13[i][2], + 4) == 0) { + cck_index_old = (u8) i; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, + DBG_LOUD, + ("Initial reg0x%x = 0x%lx, " + "cck_index=0x%x, ch14 %d\n", + RCCK0_TXFILTER2, temp_cck, + cck_index_old, + rtlpriv->dm.b_cck_inch14)); + break; + } + } + } + + if (!rtlpriv->dm.thermalvalue) { + rtlpriv->dm.thermalvalue = + rtlefuse->eeprom_thermalmeter; + rtlpriv->dm.thermalvalue_lck = thermalvalue; + rtlpriv->dm.thermalvalue_iqk = thermalvalue; + for (i = 0; i < rf; i++) + rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i]; + rtlpriv->dm.cck_index = cck_index_old; + } + + delta = (thermalvalue > rtlpriv->dm.thermalvalue) ? + (thermalvalue - rtlpriv->dm.thermalvalue) : + (rtlpriv->dm.thermalvalue - thermalvalue); + + delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ? + (thermalvalue - rtlpriv->dm.thermalvalue_lck) : + (rtlpriv->dm.thermalvalue_lck - thermalvalue); + + delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ? + (thermalvalue - rtlpriv->dm.thermalvalue_iqk) : + (rtlpriv->dm.thermalvalue_iqk - thermalvalue); + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " + "eeprom_thermalmeter 0x%x delta 0x%x " + "delta_lck 0x%x delta_iqk 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter, delta, delta_lck, + delta_iqk)); + + if (delta_lck > 1) { + rtlpriv->dm.thermalvalue_lck = thermalvalue; + rtl92c_phy_lc_calibrate(hw); + } + + if (delta > 0 && rtlpriv->dm.txpower_track_control) { + if (thermalvalue > rtlpriv->dm.thermalvalue) { + for (i = 0; i < rf; i++) + rtlpriv->dm.ofdm_index[i] -= delta; + rtlpriv->dm.cck_index -= delta; + } else { + for (i = 0; i < rf; i++) + rtlpriv->dm.ofdm_index[i] += delta; + rtlpriv->dm.cck_index += delta; + } + + if (is2t) { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("temp OFDM_A_index=0x%x, " + "OFDM_B_index=0x%x," + "cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.ofdm_index[1], + rtlpriv->dm.cck_index)); + } else { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("temp OFDM_A_index=0x%x," + "cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.cck_index)); + } + + if (thermalvalue > rtlefuse->eeprom_thermalmeter) { + for (i = 0; i < rf; i++) + ofdm_index[i] = + rtlpriv->dm.ofdm_index[i] + + 1; + cck_index = rtlpriv->dm.cck_index + 1; + } else { + for (i = 0; i < rf; i++) + ofdm_index[i] = + rtlpriv->dm.ofdm_index[i]; + cck_index = rtlpriv->dm.cck_index; + } + + for (i = 0; i < rf; i++) { + if (txpwr_level[i] >= 0 && + txpwr_level[i] <= 26) { + if (thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + ofdm_index[i] -= 1; + + else + ofdm_index[i] -= 2; + } else if (delta > 5 && thermalvalue < + rtlefuse-> + eeprom_thermalmeter) { + ofdm_index[i] += 1; + } + } else if (txpwr_level[i] >= 27 && + txpwr_level[i] <= 32 + && thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + ofdm_index[i] -= 1; + + else + ofdm_index[i] -= 2; + } else if (txpwr_level[i] >= 32 && + txpwr_level[i] <= 38 && + thermalvalue > + rtlefuse->eeprom_thermalmeter + && delta > 5) { + ofdm_index[i] -= 1; + } + } + + if (txpwr_level[i] >= 0 && txpwr_level[i] <= 26) { + if (thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + cck_index -= 1; + + else + cck_index -= 2; + } else if (delta > 5 && thermalvalue < + rtlefuse->eeprom_thermalmeter) { + cck_index += 1; + } + } else if (txpwr_level[i] >= 27 && + txpwr_level[i] <= 32 && + thermalvalue > + rtlefuse->eeprom_thermalmeter) { + if (delta < 5) + cck_index -= 1; + + else + cck_index -= 2; + } else if (txpwr_level[i] >= 32 && + txpwr_level[i] <= 38 && + thermalvalue > rtlefuse->eeprom_thermalmeter + && delta > 5) { + cck_index -= 1; + } + + for (i = 0; i < rf; i++) { + if (ofdm_index[i] > OFDM_TABLE_SIZE - 1) + ofdm_index[i] = OFDM_TABLE_SIZE - 1; + + else if (ofdm_index[i] < ofdm_min_index) + ofdm_index[i] = ofdm_min_index; + } + + if (cck_index > CCK_TABLE_SIZE - 1) + cck_index = CCK_TABLE_SIZE - 1; + else if (cck_index < 0) + cck_index = 0; + + if (is2t) { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("new OFDM_A_index=0x%x, " + "OFDM_B_index=0x%x," + "cck_index=0x%x\n", + ofdm_index[0], ofdm_index[1], + cck_index)); + } else { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("new OFDM_A_index=0x%x," + "cck_index=0x%x\n", + ofdm_index[0], cck_index)); + } + } + + if (rtlpriv->dm.txpower_track_control && delta != 0) { + ele_d = + (ofdmswing_table[ofdm_index[0]] & 0xFFC00000) >> 22; + val_x = rtlphy->reg_e94; + val_y = rtlphy->reg_e9c; + + if (val_x != 0) { + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + ele_a = ((val_x * ele_d) >> 8) & 0x000003FF; + + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + ele_c = ((val_y * ele_d) >> 8) & 0x000003FF; + + value32 = (ele_d << 22) | + ((ele_c & 0x3F) << 16) | ele_a; + + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD, value32); + + value32 = (ele_c & 0x000003C0) >> 6; + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, + value32); + + value32 = ((val_x * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(31), value32); + + value32 = ((val_y * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(29), value32); + } else { + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD, + ofdmswing_table[ofdm_index[0]]); + + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, + 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(31) | BIT(29), 0x00); + } + + if (!rtlpriv->dm.b_cck_inch14) { + rtl_write_byte(rtlpriv, 0xa22, + cckswing_table_ch1ch13[cck_index] + [0]); + rtl_write_byte(rtlpriv, 0xa23, + cckswing_table_ch1ch13[cck_index] + [1]); + rtl_write_byte(rtlpriv, 0xa24, + cckswing_table_ch1ch13[cck_index] + [2]); + rtl_write_byte(rtlpriv, 0xa25, + cckswing_table_ch1ch13[cck_index] + [3]); + rtl_write_byte(rtlpriv, 0xa26, + cckswing_table_ch1ch13[cck_index] + [4]); + rtl_write_byte(rtlpriv, 0xa27, + cckswing_table_ch1ch13[cck_index] + [5]); + rtl_write_byte(rtlpriv, 0xa28, + cckswing_table_ch1ch13[cck_index] + [6]); + rtl_write_byte(rtlpriv, 0xa29, + cckswing_table_ch1ch13[cck_index] + [7]); + } else { + rtl_write_byte(rtlpriv, 0xa22, + cckswing_table_ch14[cck_index] + [0]); + rtl_write_byte(rtlpriv, 0xa23, + cckswing_table_ch14[cck_index] + [1]); + rtl_write_byte(rtlpriv, 0xa24, + cckswing_table_ch14[cck_index] + [2]); + rtl_write_byte(rtlpriv, 0xa25, + cckswing_table_ch14[cck_index] + [3]); + rtl_write_byte(rtlpriv, 0xa26, + cckswing_table_ch14[cck_index] + [4]); + rtl_write_byte(rtlpriv, 0xa27, + cckswing_table_ch14[cck_index] + [5]); + rtl_write_byte(rtlpriv, 0xa28, + cckswing_table_ch14[cck_index] + [6]); + rtl_write_byte(rtlpriv, 0xa29, + cckswing_table_ch14[cck_index] + [7]); + } + + if (is2t) { + ele_d = (ofdmswing_table[ofdm_index[1]] & + 0xFFC00000) >> 22; + + val_x = rtlphy->reg_eb4; + val_y = rtlphy->reg_ebc; + + if (val_x != 0) { + if ((val_x & 0x00000200) != 0) + val_x = val_x | 0xFFFFFC00; + ele_a = ((val_x * ele_d) >> 8) & + 0x000003FF; + + if ((val_y & 0x00000200) != 0) + val_y = val_y | 0xFFFFFC00; + ele_c = ((val_y * ele_d) >> 8) & + 0x00003FF; + + value32 = (ele_d << 22) | + ((ele_c & 0x3F) << 16) | ele_a; + rtl_set_bbreg(hw, + ROFDM0_XBTXIQIMBALANCE, + MASKDWORD, value32); + + value32 = (ele_c & 0x000003C0) >> 6; + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, + MASKH4BITS, value32); + + value32 = ((val_x * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(27), value32); + + value32 = ((val_y * ele_d) >> 7) & 0x01; + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(25), value32); + } else { + rtl_set_bbreg(hw, + ROFDM0_XBTXIQIMBALANCE, + MASKDWORD, + ofdmswing_table[ofdm_index + [1]]); + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, + MASKH4BITS, 0x00); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, + BIT(27) | BIT(25), 0x00); + } + + } + } + + if (delta_iqk > 3) { + rtlpriv->dm.thermalvalue_iqk = thermalvalue; + rtl92c_phy_iq_calibrate(hw, false); + } + + if (rtlpriv->dm.txpower_track_control) + rtlpriv->dm.thermalvalue = thermalvalue; + } + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n")); + +} + +static void rtl92c_dm_initialize_txpower_tracking_thermalmeter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.btxpower_tracking = true; + rtlpriv->dm.btxpower_trackingInit = false; + + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("pMgntInfo->btxpower_tracking = %d\n", + rtlpriv->dm.btxpower_tracking)); +} + +static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) +{ + rtl92c_dm_initialize_txpower_tracking_thermalmeter(hw); +} + +static void rtl92c_dm_txpower_tracking_directcall(struct ieee80211_hw *hw) +{ + rtl92c_dm_txpower_tracking_callback_thermalmeter(hw); +} + +static void rtl92c_dm_check_txpower_tracking_thermal_meter( + struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + static u8 tm_trigger; + + if (!rtlpriv->dm.btxpower_tracking) + return; + + if (!tm_trigger) { + rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK, + 0x60); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Trigger 92S Thermal Meter!!\n")); + tm_trigger = 1; + return; + } else { + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + ("Schedule TxPowerTracking direct call!!\n")); + rtl92c_dm_txpower_tracking_directcall(hw); + tm_trigger = 0; + } +} + +void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw) +{ + rtl92c_dm_check_txpower_tracking_thermal_meter(hw); +} + +void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rate_adaptive *p_ra = &(rtlpriv->ra); + + p_ra->ratr_state = DM_RATR_STA_INIT; + p_ra->pre_ratr_state = DM_RATR_STA_INIT; + + if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) + rtlpriv->dm.b_useramask = true; + else + rtlpriv->dm.b_useramask = false; + +} + +static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rate_adaptive *p_ra = &(rtlpriv->ra); + u32 low_rssithresh_for_ra, high_rssithresh_for_ra; + + if (is_hal_stop(rtlhal)) { + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("<---- driver is going to unload\n")); + return; + } + + if (!rtlpriv->dm.b_useramask) { + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("<---- driver does not control rate adaptive mask\n")); + return; + } + + if (mac->link_state == MAC80211_LINKED) { + + switch (p_ra->pre_ratr_state) { + case DM_RATR_STA_HIGH: + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 20; + break; + case DM_RATR_STA_MIDDLE: + high_rssithresh_for_ra = 55; + low_rssithresh_for_ra = 20; + break; + case DM_RATR_STA_LOW: + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 25; + break; + default: + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 20; + break; + } + + if (rtlpriv->dm.undecorated_smoothed_pwdb > + (long)high_rssithresh_for_ra) + p_ra->ratr_state = DM_RATR_STA_HIGH; + else if (rtlpriv->dm.undecorated_smoothed_pwdb > + (long)low_rssithresh_for_ra) + p_ra->ratr_state = DM_RATR_STA_MIDDLE; + else + p_ra->ratr_state = DM_RATR_STA_LOW; + + if (p_ra->pre_ratr_state != p_ra->ratr_state) { + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("RSSI = %ld\n", + rtlpriv->dm.undecorated_smoothed_pwdb)); + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("RSSI_LEVEL = %d\n", p_ra->ratr_state)); + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + ("PreState = %d, CurState = %d\n", + p_ra->pre_ratr_state, p_ra->ratr_state)); + + rtlpriv->cfg->ops->update_rate_mask(hw, + p_ra->ratr_state); + + p_ra->pre_ratr_state = p_ra->ratr_state; + } + } +} + +static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw) +{ + dm_pstable.pre_ccastate = CCA_MAX; + dm_pstable.cur_ccasate = CCA_MAX; + dm_pstable.pre_rfstate = RF_MAX; + dm_pstable.cur_rfstate = RF_MAX; + dm_pstable.rssi_val_min = 0; +} + +static void rtl92c_dm_1r_cca(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (dm_pstable.rssi_val_min != 0) { + if (dm_pstable.pre_ccastate == CCA_2R) { + if (dm_pstable.rssi_val_min >= 35) + dm_pstable.cur_ccasate = CCA_1R; + else + dm_pstable.cur_ccasate = CCA_2R; + } else { + if (dm_pstable.rssi_val_min <= 30) + dm_pstable.cur_ccasate = CCA_2R; + else + dm_pstable.cur_ccasate = CCA_1R; + } + } else { + dm_pstable.cur_ccasate = CCA_MAX; + } + + if (dm_pstable.pre_ccastate != dm_pstable.cur_ccasate) { + if (dm_pstable.cur_ccasate == CCA_1R) { + if (get_rf_type(rtlphy) == RF_2T2R) { + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, + MASKBYTE0, 0x13); + rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x20); + } else { + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, + MASKBYTE0, 0x23); + rtl_set_bbreg(hw, 0xe70, 0x7fc00000, 0x10c); + } + } else { + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, + 0x33); + rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x63); + } + dm_pstable.pre_ccastate = dm_pstable.cur_ccasate; + } + + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, ("CCAStage = %s\n", + (dm_pstable.cur_ccasate == + 0) ? "1RCCA" : "2RCCA")); +} + +void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal) +{ + static u8 initialize; + static u32 reg_874, reg_c70, reg_85c, reg_a74; + + if (initialize == 0) { + reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + MASKDWORD) & 0x1CC000) >> 14; + + reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, + MASKDWORD) & BIT(3)) >> 3; + + reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, + MASKDWORD) & 0xFF000000) >> 24; + + reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12; + + initialize = 1; + } + + if (!bforce_in_normal) { + if (dm_pstable.rssi_val_min != 0) { + if (dm_pstable.pre_rfstate == RF_NORMAL) { + if (dm_pstable.rssi_val_min >= 30) + dm_pstable.cur_rfstate = RF_SAVE; + else + dm_pstable.cur_rfstate = RF_NORMAL; + } else { + if (dm_pstable.rssi_val_min <= 25) + dm_pstable.cur_rfstate = RF_NORMAL; + else + dm_pstable.cur_rfstate = RF_SAVE; + } + } else { + dm_pstable.cur_rfstate = RF_MAX; + } + } else { + dm_pstable.cur_rfstate = RF_NORMAL; + } + + if (dm_pstable.pre_rfstate != dm_pstable.cur_rfstate) { + if (dm_pstable.cur_rfstate == RF_SAVE) { + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + 0x1C0000, 0x2); + rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0); + rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, + 0xFF000000, 0x63); + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + 0xC000, 0x2); + rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3); + rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); + rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); + } else { + rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, + 0x1CC000, reg_874); + rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), + reg_c70); + rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, + reg_85c); + rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74); + rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); + } + + dm_pstable.pre_rfstate = dm_pstable.cur_rfstate; + } +} + +static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (((mac->link_state == MAC80211_NOLINK)) && + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { + dm_pstable.rssi_val_min = 0; + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, + ("Not connected to any\n")); + } + + if (mac->link_state == MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + dm_pstable.rssi_val_min = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, + ("AP Client PWDB = 0x%lx\n", + dm_pstable.rssi_val_min)); + } else { + dm_pstable.rssi_val_min = + rtlpriv->dm.undecorated_smoothed_pwdb; + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, + ("STA Default Port PWDB = 0x%lx\n", + dm_pstable.rssi_val_min)); + } + } else { + dm_pstable.rssi_val_min = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, + ("AP Ext Port PWDB = 0x%lx\n", + dm_pstable.rssi_val_min)); + } + + if (IS_92C_SERIAL(rtlhal->version)) + rtl92c_dm_1r_cca(hw); +} + +void rtl92c_dm_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; + rtl92c_dm_diginit(hw); + rtl92c_dm_init_dynamic_txpower(hw); + rtl92c_dm_init_edca_turbo(hw); + rtl92c_dm_init_rate_adaptive_mask(hw); + rtl92c_dm_initialize_txpower_tracking(hw); + rtl92c_dm_init_dynamic_bb_powersaving(hw); +} + +void rtl92c_dm_watchdog(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool b_fw_current_inpsmode = false; + bool b_fw_ps_awake = true; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *) (&b_fw_current_inpsmode)); + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, + (u8 *) (&b_fw_ps_awake)); + + if ((ppsc->rfpwr_state == ERFON) && ((!b_fw_current_inpsmode) && + b_fw_ps_awake) + && (!ppsc->rfchange_inprogress)) { + rtl92c_dm_pwdb_monitor(hw); + rtl92c_dm_dig(hw); + rtl92c_dm_false_alarm_counter_statistics(hw); + rtl92c_dm_dynamic_bb_powersaving(hw); + rtl92c_dm_dynamic_txpower(hw); + rtl92c_dm_check_txpower_tracking(hw); + rtl92c_dm_refresh_rate_adaptive_mask(hw); + rtl92c_dm_check_edca_turbo(hw); + } +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c index 62e7c64e087b..ddf0a41a7a81 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c @@ -35,478 +35,9 @@ #include "dm.h" #include "fw.h" -struct dig_t dm_digtable; -static struct ps_t dm_pstable; +#include "../rtl8192c/dm_common.c" -static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { - 0x7f8001fe, - 0x788001e2, - 0x71c001c7, - 0x6b8001ae, - 0x65400195, - 0x5fc0017f, - 0x5a400169, - 0x55400155, - 0x50800142, - 0x4c000130, - 0x47c0011f, - 0x43c0010f, - 0x40000100, - 0x3c8000f2, - 0x390000e4, - 0x35c000d7, - 0x32c000cb, - 0x300000c0, - 0x2d4000b5, - 0x2ac000ab, - 0x288000a2, - 0x26000098, - 0x24000090, - 0x22000088, - 0x20000080, - 0x1e400079, - 0x1c800072, - 0x1b00006c, - 0x19800066, - 0x18000060, - 0x16c0005b, - 0x15800056, - 0x14400051, - 0x1300004c, - 0x12000048, - 0x11000044, - 0x10000040, -}; - -static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = { - {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, - {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, - {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, - {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, - {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, - {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, - {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, - {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, - {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, - {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, - {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, - {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, - {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, - {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, - {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, - {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, - {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, - {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, - {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, - {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, - {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, - {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, - {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, - {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, - {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, - {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, - {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, - {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, - {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, - {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, - {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, - {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, - {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} -}; - -static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = { - {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, - {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, - {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, - {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, - {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, - {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, - {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, - {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, - {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, - {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, - {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, - {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, - {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, - {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, - {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, - {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, - {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, - {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, - {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, - {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, - {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, - {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, - {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, - {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, - {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, - {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, - {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, - {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} -}; - -static void rtl92c_dm_diginit(struct ieee80211_hw *hw) -{ - dm_digtable.dig_enable_flag = true; - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; - dm_digtable.cur_igvalue = 0x20; - dm_digtable.pre_igvalue = 0x0; - dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; - dm_digtable.presta_connectstate = DIG_STA_DISCONNECT; - dm_digtable.curmultista_connectstate = DIG_MULTISTA_DISCONNECT; - dm_digtable.rssi_lowthresh = DM_DIG_THRESH_LOW; - dm_digtable.rssi_highthresh = DM_DIG_THRESH_HIGH; - dm_digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW; - dm_digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH; - dm_digtable.rx_gain_range_max = DM_DIG_MAX; - dm_digtable.rx_gain_range_min = DM_DIG_MIN; - dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; - dm_digtable.backoff_val_range_max = DM_DIG_BACKOFF_MAX; - dm_digtable.backoff_val_range_min = DM_DIG_BACKOFF_MIN; - dm_digtable.pre_cck_pd_state = CCK_PD_STAGE_MAX; - dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; -} - -static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - long rssi_val_min = 0; - - if ((dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) && - (dm_digtable.cursta_connectctate == DIG_STA_CONNECT)) { - if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb != 0) - rssi_val_min = - (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb > - rtlpriv->dm.undecorated_smoothed_pwdb) ? - rtlpriv->dm.undecorated_smoothed_pwdb : - rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; - else - rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; - } else if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT || - dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT) { - rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; - } else if (dm_digtable.curmultista_connectstate == - DIG_MULTISTA_CONNECT) { - rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; - } - - return (u8) rssi_val_min; -} - -static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) -{ - u32 ret_value; - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); - - ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); - falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); - - ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); - falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); - falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); - - ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); - falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); - falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + - falsealm_cnt->cnt_rate_illegal + - falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail; - - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); - ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); - falsealm_cnt->cnt_cck_fail = ret_value; - - ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3); - falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; - falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail + - falsealm_cnt->cnt_rate_illegal + - falsealm_cnt->cnt_crc8_fail + - falsealm_cnt->cnt_mcs_fail + - falsealm_cnt->cnt_cck_fail); - - rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1); - rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0); - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0); - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("cnt_parity_fail = %d, cnt_rate_illegal = %d, " - "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", - falsealm_cnt->cnt_parity_fail, - falsealm_cnt->cnt_rate_illegal, - falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail)); - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", - falsealm_cnt->cnt_ofdm_fail, - falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all)); -} - -static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 value_igi = dm_digtable.cur_igvalue; - - if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) - value_igi--; - else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1) - value_igi += 0; - else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2) - value_igi++; - else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2) - value_igi += 2; - if (value_igi > DM_DIG_FA_UPPER) - value_igi = DM_DIG_FA_UPPER; - else if (value_igi < DM_DIG_FA_LOWER) - value_igi = DM_DIG_FA_LOWER; - if (rtlpriv->falsealm_cnt.cnt_all > 10000) - value_igi = 0x32; - - dm_digtable.cur_igvalue = value_igi; - rtl92c_dm_write_dig(hw); -} - -static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable.fa_highthresh) { - if ((dm_digtable.backoff_val - 2) < - dm_digtable.backoff_val_range_min) - dm_digtable.backoff_val = - dm_digtable.backoff_val_range_min; - else - dm_digtable.backoff_val -= 2; - } else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable.fa_lowthresh) { - if ((dm_digtable.backoff_val + 2) > - dm_digtable.backoff_val_range_max) - dm_digtable.backoff_val = - dm_digtable.backoff_val_range_max; - else - dm_digtable.backoff_val += 2; - } - - if ((dm_digtable.rssi_val_min + 10 - dm_digtable.backoff_val) > - dm_digtable.rx_gain_range_max) - dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_max; - else if ((dm_digtable.rssi_val_min + 10 - - dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min) - dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_min; - else - dm_digtable.cur_igvalue = dm_digtable.rssi_val_min + 10 - - dm_digtable.backoff_val; - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("rssi_val_min = %x backoff_val %x\n", - dm_digtable.rssi_val_min, dm_digtable.backoff_val)); - - rtl92c_dm_write_dig(hw); -} - -static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) -{ - static u8 binitialized; /* initialized to false */ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; - bool b_multi_sta = false; - - if (mac->opmode == NL80211_IFTYPE_ADHOC) - b_multi_sta = true; - - if ((b_multi_sta == false) || (dm_digtable.cursta_connectctate != - DIG_STA_DISCONNECT)) { - binitialized = false; - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; - return; - } else if (binitialized == false) { - binitialized = true; - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; - dm_digtable.cur_igvalue = 0x20; - rtl92c_dm_write_dig(hw); - } - - if (dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) { - if ((rssi_strength < dm_digtable.rssi_lowthresh) && - (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { - - if (dm_digtable.dig_ext_port_stage == - DIG_EXT_PORT_STAGE_2) { - dm_digtable.cur_igvalue = 0x20; - rtl92c_dm_write_dig(hw); - } - - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_1; - } else if (rssi_strength > dm_digtable.rssi_highthresh) { - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_2; - rtl92c_dm_ctrl_initgain_by_fa(hw); - } - } else if (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) { - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; - dm_digtable.cur_igvalue = 0x20; - rtl92c_dm_write_dig(hw); - } - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("curmultista_connectstate = " - "%x dig_ext_port_stage %x\n", - dm_digtable.curmultista_connectstate, - dm_digtable.dig_ext_port_stage)); -} - -static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("presta_connectstate = %x," - " cursta_connectctate = %x\n", - dm_digtable.presta_connectstate, - dm_digtable.cursta_connectctate)); - - if (dm_digtable.presta_connectstate == dm_digtable.cursta_connectctate - || dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT - || dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { - - if (dm_digtable.cursta_connectctate != DIG_STA_DISCONNECT) { - dm_digtable.rssi_val_min = - rtl92c_dm_initial_gain_min_pwdb(hw); - rtl92c_dm_ctrl_initgain_by_rssi(hw); - } - } else { - dm_digtable.rssi_val_min = 0; - dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; - dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; - dm_digtable.cur_igvalue = 0x20; - dm_digtable.pre_igvalue = 0; - rtl92c_dm_write_dig(hw); - } -} - -static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { - dm_digtable.rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); - - if (dm_digtable.pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { - if (dm_digtable.rssi_val_min <= 25) - dm_digtable.cur_cck_pd_state = - CCK_PD_STAGE_LowRssi; - else - dm_digtable.cur_cck_pd_state = - CCK_PD_STAGE_HighRssi; - } else { - if (dm_digtable.rssi_val_min <= 20) - dm_digtable.cur_cck_pd_state = - CCK_PD_STAGE_LowRssi; - else - dm_digtable.cur_cck_pd_state = - CCK_PD_STAGE_HighRssi; - } - } else { - dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; - } - - if (dm_digtable.pre_cck_pd_state != dm_digtable.cur_cck_pd_state) { - if (dm_digtable.cur_cck_pd_state == CCK_PD_STAGE_LowRssi) { - if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) - dm_digtable.cur_cck_fa_state = - CCK_FA_STAGE_High; - else - dm_digtable.cur_cck_fa_state = CCK_FA_STAGE_Low; - - if (dm_digtable.pre_cck_fa_state != - dm_digtable.cur_cck_fa_state) { - if (dm_digtable.cur_cck_fa_state == - CCK_FA_STAGE_Low) - rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, - 0x83); - else - rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, - 0xcd); - - dm_digtable.pre_cck_fa_state = - dm_digtable.cur_cck_fa_state; - } - - rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40); - - if (IS_92C_SERIAL(rtlhal->version)) - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, - MASKBYTE2, 0xd7); - } else { - rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); - rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47); - - if (IS_92C_SERIAL(rtlhal->version)) - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, - MASKBYTE2, 0xd3); - } - dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state; - } - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("CCKPDStage=%x\n", dm_digtable.cur_cck_pd_state)); - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("is92C=%x\n", IS_92C_SERIAL(rtlhal->version))); -} - -static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) -{ - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - - if (mac->act_scanning == true) - return; - - if ((mac->link_state > MAC80211_NOLINK) && - (mac->link_state < MAC80211_LINKED)) - dm_digtable.cursta_connectctate = DIG_STA_BEFORE_CONNECT; - else if (mac->link_state >= MAC80211_LINKED) - dm_digtable.cursta_connectctate = DIG_STA_CONNECT; - else - dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; - - rtl92c_dm_initial_gain_sta(hw); - rtl92c_dm_initial_gain_multi_sta(hw); - rtl92c_dm_cck_packet_detection_thresh(hw); - - dm_digtable.presta_connectstate = dm_digtable.cursta_connectctate; - -} - -static void rtl92c_dm_dig(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (rtlpriv->dm.b_dm_initialgain_enable == false) - return; - if (dm_digtable.dig_enable_flag == false) - return; - - rtl92c_dm_ctrl_initgain_by_twoport(hw); - -} - -static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->dm.bdynamic_txpower_enable = false; - - rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; -} - -static void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) +void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); @@ -584,890 +115,4 @@ static void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; } -void rtl92c_dm_write_dig(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("cur_igvalue = 0x%x, " - "pre_igvalue = 0x%x, backoff_val = %d\n", - dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, - dm_digtable.backoff_val)); - - if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { - rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, - dm_digtable.cur_igvalue); - rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, - dm_digtable.cur_igvalue); - - dm_digtable.pre_igvalue = dm_digtable.cur_igvalue; - } -} - -static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff; - - u8 h2c_parameter[3] = { 0 }; - - return; - - if (tmpentry_max_pwdb != 0) { - rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = - tmpentry_max_pwdb; - } else { - rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = 0; - } - - if (tmpentry_min_pwdb != 0xff) { - rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = - tmpentry_min_pwdb; - } else { - rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = 0; - } - - h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF); - h2c_parameter[0] = 0; - - rtl92c_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter); -} - -void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - rtlpriv->dm.bcurrent_turbo_edca = false; - rtlpriv->dm.bis_any_nonbepkts = false; - rtlpriv->dm.bis_cur_rdlstate = false; -} - -static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - static u64 last_txok_cnt; - static u64 last_rxok_cnt; - u64 cur_txok_cnt; - u64 cur_rxok_cnt; - u32 edca_be_ul = 0x5ea42b; - u32 edca_be_dl = 0x5ea42b; - - if (mac->opmode == NL80211_IFTYPE_ADHOC) - goto dm_checkedcaturbo_exit; - - if (mac->link_state != MAC80211_LINKED) { - rtlpriv->dm.bcurrent_turbo_edca = false; - return; - } - - if (!mac->ht_enable) { /*FIX MERGE */ - if (!(edca_be_ul & 0xffff0000)) - edca_be_ul |= 0x005e0000; - - if (!(edca_be_dl & 0xffff0000)) - edca_be_dl |= 0x005e0000; - } - - if ((!rtlpriv->dm.bis_any_nonbepkts) && - (!rtlpriv->dm.b_disable_framebursting)) { - cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; - cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; - if (cur_rxok_cnt > 4 * cur_txok_cnt) { - if (!rtlpriv->dm.bis_cur_rdlstate || - !rtlpriv->dm.bcurrent_turbo_edca) { - rtl_write_dword(rtlpriv, - REG_EDCA_BE_PARAM, - edca_be_dl); - rtlpriv->dm.bis_cur_rdlstate = true; - } - } else { - if (rtlpriv->dm.bis_cur_rdlstate || - !rtlpriv->dm.bcurrent_turbo_edca) { - rtl_write_dword(rtlpriv, - REG_EDCA_BE_PARAM, - edca_be_ul); - rtlpriv->dm.bis_cur_rdlstate = false; - } - } - rtlpriv->dm.bcurrent_turbo_edca = true; - } else { - if (rtlpriv->dm.bcurrent_turbo_edca) { - u8 tmp = AC0_BE; - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_AC_PARAM, - (u8 *) (&tmp)); - rtlpriv->dm.bcurrent_turbo_edca = false; - } - } - -dm_checkedcaturbo_exit: - rtlpriv->dm.bis_any_nonbepkts = false; - last_txok_cnt = rtlpriv->stats.txbytesunicast; - last_rxok_cnt = rtlpriv->stats.rxbytesunicast; -} - -static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw - *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 thermalvalue, delta, delta_lck, delta_iqk; - long ele_a, ele_d, temp_cck, val_x, value32; - long val_y, ele_c; - u8 ofdm_index[2], cck_index, ofdm_index_old[2], cck_index_old; - int i; - bool is2t = IS_92C_SERIAL(rtlhal->version); - u8 txpwr_level[2] = {0, 0}; - u8 ofdm_min_index = 6, rf; - - rtlpriv->dm.btxpower_trackingInit = true; - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n")); - - thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f); - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " - "eeprom_thermalmeter 0x%x\n", - thermalvalue, rtlpriv->dm.thermalvalue, - rtlefuse->eeprom_thermalmeter)); - - rtl92c_phy_ap_calibrate(hw, (thermalvalue - - rtlefuse->eeprom_thermalmeter)); - if (is2t) - rf = 2; - else - rf = 1; - - if (thermalvalue) { - ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, - MASKDWORD) & MASKOFDM_D; - - for (i = 0; i < OFDM_TABLE_LENGTH; i++) { - if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { - ofdm_index_old[0] = (u8) i; - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Initial pathA ele_d reg0x%x = 0x%lx, " - "ofdm_index=0x%x\n", - ROFDM0_XATXIQIMBALANCE, - ele_d, ofdm_index_old[0])); - break; - } - } - - if (is2t) { - ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, - MASKDWORD) & MASKOFDM_D; - - for (i = 0; i < OFDM_TABLE_LENGTH; i++) { - if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { - ofdm_index_old[1] = (u8) i; - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, - DBG_LOUD, - ("Initial pathB ele_d reg0x%x = " - "0x%lx, ofdm_index=0x%x\n", - ROFDM0_XBTXIQIMBALANCE, ele_d, - ofdm_index_old[1])); - break; - } - } - } - - temp_cck = - rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK; - - for (i = 0; i < CCK_TABLE_LENGTH; i++) { - if (rtlpriv->dm.b_cck_inch14) { - if (memcmp((void *)&temp_cck, - (void *)&cckswing_table_ch14[i][2], - 4) == 0) { - cck_index_old = (u8) i; - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, - DBG_LOUD, - ("Initial reg0x%x = 0x%lx, " - "cck_index=0x%x, ch 14 %d\n", - RCCK0_TXFILTER2, temp_cck, - cck_index_old, - rtlpriv->dm.b_cck_inch14)); - break; - } - } else { - if (memcmp((void *)&temp_cck, - (void *) - &cckswing_table_ch1ch13[i][2], - 4) == 0) { - cck_index_old = (u8) i; - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, - DBG_LOUD, - ("Initial reg0x%x = 0x%lx, " - "cck_index=0x%x, ch14 %d\n", - RCCK0_TXFILTER2, temp_cck, - cck_index_old, - rtlpriv->dm.b_cck_inch14)); - break; - } - } - } - - if (!rtlpriv->dm.thermalvalue) { - rtlpriv->dm.thermalvalue = - rtlefuse->eeprom_thermalmeter; - rtlpriv->dm.thermalvalue_lck = thermalvalue; - rtlpriv->dm.thermalvalue_iqk = thermalvalue; - for (i = 0; i < rf; i++) - rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i]; - rtlpriv->dm.cck_index = cck_index_old; - } - - delta = (thermalvalue > rtlpriv->dm.thermalvalue) ? - (thermalvalue - rtlpriv->dm.thermalvalue) : - (rtlpriv->dm.thermalvalue - thermalvalue); - - delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ? - (thermalvalue - rtlpriv->dm.thermalvalue_lck) : - (rtlpriv->dm.thermalvalue_lck - thermalvalue); - - delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ? - (thermalvalue - rtlpriv->dm.thermalvalue_iqk) : - (rtlpriv->dm.thermalvalue_iqk - thermalvalue); - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " - "eeprom_thermalmeter 0x%x delta 0x%x " - "delta_lck 0x%x delta_iqk 0x%x\n", - thermalvalue, rtlpriv->dm.thermalvalue, - rtlefuse->eeprom_thermalmeter, delta, delta_lck, - delta_iqk)); - - if (delta_lck > 1) { - rtlpriv->dm.thermalvalue_lck = thermalvalue; - rtl92c_phy_lc_calibrate(hw); - } - - if (delta > 0 && rtlpriv->dm.txpower_track_control) { - if (thermalvalue > rtlpriv->dm.thermalvalue) { - for (i = 0; i < rf; i++) - rtlpriv->dm.ofdm_index[i] -= delta; - rtlpriv->dm.cck_index -= delta; - } else { - for (i = 0; i < rf; i++) - rtlpriv->dm.ofdm_index[i] += delta; - rtlpriv->dm.cck_index += delta; - } - - if (is2t) { - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("temp OFDM_A_index=0x%x, " - "OFDM_B_index=0x%x," - "cck_index=0x%x\n", - rtlpriv->dm.ofdm_index[0], - rtlpriv->dm.ofdm_index[1], - rtlpriv->dm.cck_index)); - } else { - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("temp OFDM_A_index=0x%x," - "cck_index=0x%x\n", - rtlpriv->dm.ofdm_index[0], - rtlpriv->dm.cck_index)); - } - - if (thermalvalue > rtlefuse->eeprom_thermalmeter) { - for (i = 0; i < rf; i++) - ofdm_index[i] = - rtlpriv->dm.ofdm_index[i] - + 1; - cck_index = rtlpriv->dm.cck_index + 1; - } else { - for (i = 0; i < rf; i++) - ofdm_index[i] = - rtlpriv->dm.ofdm_index[i]; - cck_index = rtlpriv->dm.cck_index; - } - - for (i = 0; i < rf; i++) { - if (txpwr_level[i] >= 0 && - txpwr_level[i] <= 26) { - if (thermalvalue > - rtlefuse->eeprom_thermalmeter) { - if (delta < 5) - ofdm_index[i] -= 1; - - else - ofdm_index[i] -= 2; - } else if (delta > 5 && thermalvalue < - rtlefuse-> - eeprom_thermalmeter) { - ofdm_index[i] += 1; - } - } else if (txpwr_level[i] >= 27 && - txpwr_level[i] <= 32 - && thermalvalue > - rtlefuse->eeprom_thermalmeter) { - if (delta < 5) - ofdm_index[i] -= 1; - - else - ofdm_index[i] -= 2; - } else if (txpwr_level[i] >= 32 && - txpwr_level[i] <= 38 && - thermalvalue > - rtlefuse->eeprom_thermalmeter - && delta > 5) { - ofdm_index[i] -= 1; - } - } - - if (txpwr_level[i] >= 0 && txpwr_level[i] <= 26) { - if (thermalvalue > - rtlefuse->eeprom_thermalmeter) { - if (delta < 5) - cck_index -= 1; - - else - cck_index -= 2; - } else if (delta > 5 && thermalvalue < - rtlefuse->eeprom_thermalmeter) { - cck_index += 1; - } - } else if (txpwr_level[i] >= 27 && - txpwr_level[i] <= 32 && - thermalvalue > - rtlefuse->eeprom_thermalmeter) { - if (delta < 5) - cck_index -= 1; - - else - cck_index -= 2; - } else if (txpwr_level[i] >= 32 && - txpwr_level[i] <= 38 && - thermalvalue > rtlefuse->eeprom_thermalmeter - && delta > 5) { - cck_index -= 1; - } - - for (i = 0; i < rf; i++) { - if (ofdm_index[i] > OFDM_TABLE_SIZE - 1) - ofdm_index[i] = OFDM_TABLE_SIZE - 1; - - else if (ofdm_index[i] < ofdm_min_index) - ofdm_index[i] = ofdm_min_index; - } - - if (cck_index > CCK_TABLE_SIZE - 1) - cck_index = CCK_TABLE_SIZE - 1; - else if (cck_index < 0) - cck_index = 0; - - if (is2t) { - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("new OFDM_A_index=0x%x, " - "OFDM_B_index=0x%x," - "cck_index=0x%x\n", - ofdm_index[0], ofdm_index[1], - cck_index)); - } else { - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("new OFDM_A_index=0x%x," - "cck_index=0x%x\n", - ofdm_index[0], cck_index)); - } - } - - if (rtlpriv->dm.txpower_track_control && delta != 0) { - ele_d = - (ofdmswing_table[ofdm_index[0]] & 0xFFC00000) >> 22; - val_x = rtlphy->reg_e94; - val_y = rtlphy->reg_e9c; - - if (val_x != 0) { - if ((val_x & 0x00000200) != 0) - val_x = val_x | 0xFFFFFC00; - ele_a = ((val_x * ele_d) >> 8) & 0x000003FF; - - if ((val_y & 0x00000200) != 0) - val_y = val_y | 0xFFFFFC00; - ele_c = ((val_y * ele_d) >> 8) & 0x000003FF; - - value32 = (ele_d << 22) | - ((ele_c & 0x3F) << 16) | ele_a; - - rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, - MASKDWORD, value32); - - value32 = (ele_c & 0x000003C0) >> 6; - rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, - value32); - - value32 = ((val_x * ele_d) >> 7) & 0x01; - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, - BIT(31), value32); - - value32 = ((val_y * ele_d) >> 7) & 0x01; - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, - BIT(29), value32); - } else { - rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, - MASKDWORD, - ofdmswing_table[ofdm_index[0]]); - - rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, - 0x00); - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, - BIT(31) | BIT(29), 0x00); - } - - if (!rtlpriv->dm.b_cck_inch14) { - rtl_write_byte(rtlpriv, 0xa22, - cckswing_table_ch1ch13[cck_index] - [0]); - rtl_write_byte(rtlpriv, 0xa23, - cckswing_table_ch1ch13[cck_index] - [1]); - rtl_write_byte(rtlpriv, 0xa24, - cckswing_table_ch1ch13[cck_index] - [2]); - rtl_write_byte(rtlpriv, 0xa25, - cckswing_table_ch1ch13[cck_index] - [3]); - rtl_write_byte(rtlpriv, 0xa26, - cckswing_table_ch1ch13[cck_index] - [4]); - rtl_write_byte(rtlpriv, 0xa27, - cckswing_table_ch1ch13[cck_index] - [5]); - rtl_write_byte(rtlpriv, 0xa28, - cckswing_table_ch1ch13[cck_index] - [6]); - rtl_write_byte(rtlpriv, 0xa29, - cckswing_table_ch1ch13[cck_index] - [7]); - } else { - rtl_write_byte(rtlpriv, 0xa22, - cckswing_table_ch14[cck_index] - [0]); - rtl_write_byte(rtlpriv, 0xa23, - cckswing_table_ch14[cck_index] - [1]); - rtl_write_byte(rtlpriv, 0xa24, - cckswing_table_ch14[cck_index] - [2]); - rtl_write_byte(rtlpriv, 0xa25, - cckswing_table_ch14[cck_index] - [3]); - rtl_write_byte(rtlpriv, 0xa26, - cckswing_table_ch14[cck_index] - [4]); - rtl_write_byte(rtlpriv, 0xa27, - cckswing_table_ch14[cck_index] - [5]); - rtl_write_byte(rtlpriv, 0xa28, - cckswing_table_ch14[cck_index] - [6]); - rtl_write_byte(rtlpriv, 0xa29, - cckswing_table_ch14[cck_index] - [7]); - } - - if (is2t) { - ele_d = (ofdmswing_table[ofdm_index[1]] & - 0xFFC00000) >> 22; - - val_x = rtlphy->reg_eb4; - val_y = rtlphy->reg_ebc; - - if (val_x != 0) { - if ((val_x & 0x00000200) != 0) - val_x = val_x | 0xFFFFFC00; - ele_a = ((val_x * ele_d) >> 8) & - 0x000003FF; - - if ((val_y & 0x00000200) != 0) - val_y = val_y | 0xFFFFFC00; - ele_c = ((val_y * ele_d) >> 8) & - 0x00003FF; - - value32 = (ele_d << 22) | - ((ele_c & 0x3F) << 16) | ele_a; - rtl_set_bbreg(hw, - ROFDM0_XBTXIQIMBALANCE, - MASKDWORD, value32); - - value32 = (ele_c & 0x000003C0) >> 6; - rtl_set_bbreg(hw, ROFDM0_XDTXAFE, - MASKH4BITS, value32); - - value32 = ((val_x * ele_d) >> 7) & 0x01; - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, - BIT(27), value32); - - value32 = ((val_y * ele_d) >> 7) & 0x01; - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, - BIT(25), value32); - } else { - rtl_set_bbreg(hw, - ROFDM0_XBTXIQIMBALANCE, - MASKDWORD, - ofdmswing_table[ofdm_index - [1]]); - rtl_set_bbreg(hw, ROFDM0_XDTXAFE, - MASKH4BITS, 0x00); - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, - BIT(27) | BIT(25), 0x00); - } - - } - } - - if (delta_iqk > 3) { - rtlpriv->dm.thermalvalue_iqk = thermalvalue; - rtl92c_phy_iq_calibrate(hw, false); - } - - if (rtlpriv->dm.txpower_track_control) - rtlpriv->dm.thermalvalue = thermalvalue; - } - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n")); - -} - -static void rtl92c_dm_initialize_txpower_tracking_thermalmeter( - struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->dm.btxpower_tracking = true; - rtlpriv->dm.btxpower_trackingInit = false; - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("pMgntInfo->btxpower_tracking = %d\n", - rtlpriv->dm.btxpower_tracking)); -} - -static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) -{ - rtl92c_dm_initialize_txpower_tracking_thermalmeter(hw); -} - -static void rtl92c_dm_txpower_tracking_directcall(struct ieee80211_hw *hw) -{ - rtl92c_dm_txpower_tracking_callback_thermalmeter(hw); -} - -static void rtl92c_dm_check_txpower_tracking_thermal_meter( - struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - static u8 tm_trigger; - - if (!rtlpriv->dm.btxpower_tracking) - return; - - if (!tm_trigger) { - rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK, - 0x60); - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Trigger 92S Thermal Meter!!\n")); - tm_trigger = 1; - return; - } else { - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Schedule TxPowerTracking direct call!!\n")); - rtl92c_dm_txpower_tracking_directcall(hw); - tm_trigger = 0; - } -} - -void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw) -{ - rtl92c_dm_check_txpower_tracking_thermal_meter(hw); -} - -void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rate_adaptive *p_ra = &(rtlpriv->ra); - - p_ra->ratr_state = DM_RATR_STA_INIT; - p_ra->pre_ratr_state = DM_RATR_STA_INIT; - - if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) - rtlpriv->dm.b_useramask = true; - else - rtlpriv->dm.b_useramask = false; - -} - -static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rate_adaptive *p_ra = &(rtlpriv->ra); - u32 low_rssithresh_for_ra, high_rssithresh_for_ra; - - if (is_hal_stop(rtlhal)) { - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("<---- driver is going to unload\n")); - return; - } - - if (!rtlpriv->dm.b_useramask) { - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("<---- driver does not control rate adaptive mask\n")); - return; - } - - if (mac->link_state == MAC80211_LINKED) { - - switch (p_ra->pre_ratr_state) { - case DM_RATR_STA_HIGH: - high_rssithresh_for_ra = 50; - low_rssithresh_for_ra = 20; - break; - case DM_RATR_STA_MIDDLE: - high_rssithresh_for_ra = 55; - low_rssithresh_for_ra = 20; - break; - case DM_RATR_STA_LOW: - high_rssithresh_for_ra = 50; - low_rssithresh_for_ra = 25; - break; - default: - high_rssithresh_for_ra = 50; - low_rssithresh_for_ra = 20; - break; - } - - if (rtlpriv->dm.undecorated_smoothed_pwdb > - (long)high_rssithresh_for_ra) - p_ra->ratr_state = DM_RATR_STA_HIGH; - else if (rtlpriv->dm.undecorated_smoothed_pwdb > - (long)low_rssithresh_for_ra) - p_ra->ratr_state = DM_RATR_STA_MIDDLE; - else - p_ra->ratr_state = DM_RATR_STA_LOW; - - if (p_ra->pre_ratr_state != p_ra->ratr_state) { - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("RSSI = %ld\n", - rtlpriv->dm.undecorated_smoothed_pwdb)); - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("RSSI_LEVEL = %d\n", p_ra->ratr_state)); - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("PreState = %d, CurState = %d\n", - p_ra->pre_ratr_state, p_ra->ratr_state)); - - rtlpriv->cfg->ops->update_rate_mask(hw, - p_ra->ratr_state); - - p_ra->pre_ratr_state = p_ra->ratr_state; - } - } -} - -static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw) -{ - dm_pstable.pre_ccastate = CCA_MAX; - dm_pstable.cur_ccasate = CCA_MAX; - dm_pstable.pre_rfstate = RF_MAX; - dm_pstable.cur_rfstate = RF_MAX; - dm_pstable.rssi_val_min = 0; -} - -static void rtl92c_dm_1r_cca(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - if (dm_pstable.rssi_val_min != 0) { - if (dm_pstable.pre_ccastate == CCA_2R) { - if (dm_pstable.rssi_val_min >= 35) - dm_pstable.cur_ccasate = CCA_1R; - else - dm_pstable.cur_ccasate = CCA_2R; - } else { - if (dm_pstable.rssi_val_min <= 30) - dm_pstable.cur_ccasate = CCA_2R; - else - dm_pstable.cur_ccasate = CCA_1R; - } - } else { - dm_pstable.cur_ccasate = CCA_MAX; - } - - if (dm_pstable.pre_ccastate != dm_pstable.cur_ccasate) { - if (dm_pstable.cur_ccasate == CCA_1R) { - if (get_rf_type(rtlphy) == RF_2T2R) { - rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, - MASKBYTE0, 0x13); - rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x20); - } else { - rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, - MASKBYTE0, 0x23); - rtl_set_bbreg(hw, 0xe70, 0x7fc00000, 0x10c); - } - } else { - rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, - 0x33); - rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x63); - } - dm_pstable.pre_ccastate = dm_pstable.cur_ccasate; - } - - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, ("CCAStage = %s\n", - (dm_pstable.cur_ccasate == - 0) ? "1RCCA" : "2RCCA")); -} - -void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal) -{ - static u8 initialize; - static u32 reg_874, reg_c70, reg_85c, reg_a74; - - if (initialize == 0) { - reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - MASKDWORD) & 0x1CC000) >> 14; - - reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, - MASKDWORD) & BIT(3)) >> 3; - - reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, - MASKDWORD) & 0xFF000000) >> 24; - - reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12; - - initialize = 1; - } - - if (!bforce_in_normal) { - if (dm_pstable.rssi_val_min != 0) { - if (dm_pstable.pre_rfstate == RF_NORMAL) { - if (dm_pstable.rssi_val_min >= 30) - dm_pstable.cur_rfstate = RF_SAVE; - else - dm_pstable.cur_rfstate = RF_NORMAL; - } else { - if (dm_pstable.rssi_val_min <= 25) - dm_pstable.cur_rfstate = RF_NORMAL; - else - dm_pstable.cur_rfstate = RF_SAVE; - } - } else { - dm_pstable.cur_rfstate = RF_MAX; - } - } else { - dm_pstable.cur_rfstate = RF_NORMAL; - } - - if (dm_pstable.pre_rfstate != dm_pstable.cur_rfstate) { - if (dm_pstable.cur_rfstate == RF_SAVE) { - rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - 0x1C0000, 0x2); - rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0); - rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, - 0xFF000000, 0x63); - rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - 0xC000, 0x2); - rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3); - rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); - rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); - } else { - rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - 0x1CC000, reg_874); - rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), - reg_c70); - rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, - reg_85c); - rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74); - rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); - } - - dm_pstable.pre_rfstate = dm_pstable.cur_rfstate; - } -} - -static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (((mac->link_state == MAC80211_NOLINK)) && - (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { - dm_pstable.rssi_val_min = 0; - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("Not connected to any\n")); - } - - if (mac->link_state == MAC80211_LINKED) { - if (mac->opmode == NL80211_IFTYPE_ADHOC) { - dm_pstable.rssi_val_min = - rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - dm_pstable.rssi_val_min)); - } else { - dm_pstable.rssi_val_min = - rtlpriv->dm.undecorated_smoothed_pwdb; - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - dm_pstable.rssi_val_min)); - } - } else { - dm_pstable.rssi_val_min = - rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; - - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - dm_pstable.rssi_val_min)); - } - - if (IS_92C_SERIAL(rtlhal->version)) - rtl92c_dm_1r_cca(hw); -} - -void rtl92c_dm_init(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; - rtl92c_dm_diginit(hw); - rtl92c_dm_init_dynamic_txpower(hw); - rtl92c_dm_init_edca_turbo(hw); - rtl92c_dm_init_rate_adaptive_mask(hw); - rtl92c_dm_initialize_txpower_tracking(hw); - rtl92c_dm_init_dynamic_bb_powersaving(hw); -} - -void rtl92c_dm_watchdog(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - bool b_fw_current_inpsmode = false; - bool b_fw_ps_awake = true; - - rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, - (u8 *) (&b_fw_current_inpsmode)); - rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, - (u8 *) (&b_fw_ps_awake)); - - if ((ppsc->rfpwr_state == ERFON) && ((!b_fw_current_inpsmode) && - b_fw_ps_awake) - && (!ppsc->rfchange_inprogress)) { - rtl92c_dm_pwdb_monitor(hw); - rtl92c_dm_dig(hw); - rtl92c_dm_false_alarm_counter_statistics(hw); - rtl92c_dm_dynamic_bb_powersaving(hw); - rtl92c_dm_dynamic_txpower(hw); - rtl92c_dm_check_txpower_tracking(hw); - rtl92c_dm_refresh_rate_adaptive_mask(hw); - rtl92c_dm_check_edca_turbo(hw); - } -} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h index 463439e4074c..5911d52a24ac 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h @@ -192,5 +192,6 @@ void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw); void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw); void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); +void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw); #endif diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index ef44b75a66d2..ae55efad7a19 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -896,7 +896,7 @@ struct rtl_security { }; struct rtl_dm { - /*PHY status for DM */ + /*PHY status for DM (dynamic management) */ long entry_min_undecoratedsmoothed_pwdb; long undecorated_smoothed_pwdb; /*out dm */ long entry_max_undecoratedsmoothed_pwdb; -- cgit v1.2.3 From 25b2bc30865e3ca1a9a2116788bb2e82be5b1a99 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 11 Feb 2011 14:34:03 -0600 Subject: rtlwifi: rtl8192ce: Refactor rtl8192ce/fw Make rtlwifi/rtl8192ce/fw.{h,c} match what will be needed for rtlwifi/rtl8192cu.{h,c}. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ce/fw.c | 49 ++++------------------------ drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 1 + drivers/net/wireless/rtlwifi/rtl8192ce/sw.h | 2 ++ drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 33 +++++++++++++++++++ drivers/net/wireless/rtlwifi/rtl8192ce/trx.h | 2 ++ 5 files changed, 45 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c index 11dd22b987e7..b0776a34b817 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c @@ -133,17 +133,15 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - bool is_version_b; u8 *bufferPtr = (u8 *) buffer; RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size)); - is_version_b = IS_CHIP_VER_B(version); - if (is_version_b) { + if (IS_CHIP_VER_B(version)) { u32 pageNums, remainSize; u32 page, offset; - if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) + if (IS_HARDWARE_TYPE_8192CE(rtlhal)) _rtl92c_fill_dummy(bufferPtr, &size); pageNums = size / FW_8192C_PAGE_SIZE; @@ -231,14 +229,14 @@ int rtl92c_download_fw(struct ieee80211_hw *hw) u32 fwsize; int err; enum version_8192c version = rtlhal->version; + const struct firmware *firmware; - const struct firmware *firmware = NULL; - + printk(KERN_INFO "rtl8192cu: Loading firmware file %s\n", + rtlpriv->cfg->fw_name); err = request_firmware(&firmware, rtlpriv->cfg->fw_name, rtlpriv->io.dev); if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to request firmware!\n")); + printk(KERN_ERR "rtl8192cu: Firmware loading failed\n"); return 1; } @@ -560,39 +558,6 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) } -static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, - struct sk_buff *skb) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl8192_tx_ring *ring; - struct rtl_tx_desc *pdesc; - u8 own; - unsigned long flags; - struct sk_buff *pskb = NULL; - - ring = &rtlpci->tx_ring[BEACON_QUEUE]; - - pskb = __skb_dequeue(&ring->queue); - if (pskb) - kfree_skb(pskb); - - spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); - - pdesc = &ring->desc[0]; - own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); - - rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); - - __skb_queue_tail(&ring->queue, skb); - - spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); - - rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); - - return true; -} - #define BEACON_PG 0 /*->1*/ #define PSPOLL_PG 2 #define NULL_PG 3 @@ -776,7 +741,7 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) memcpy((u8 *) skb_put(skb, totalpacketlen), &reserved_page_packet, totalpacketlen); - rtstatus = _rtl92c_cmd_send_packet(hw, skb); + rtstatus = rtlpriv->cfg->ops->cmd_send_packet(hw, skb); if (rtstatus) b_dlok = true; diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index b366e8862929..a8b3d0605abd 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -135,6 +135,7 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = { .set_bbreg = rtl92c_phy_set_bb_reg, .get_rfreg = rtl92c_phy_query_rf_reg, .set_rfreg = rtl92c_phy_set_rf_reg, + .cmd_send_packet = _rtl92c_cmd_send_packet, }; static struct rtl_mod_params rtl92ce_mod_params = { diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h index de1198c38d4e..0568d6dc83d7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h @@ -33,5 +33,7 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw); void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw); void rtl92c_init_var_map(struct ieee80211_hw *hw); +bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, + struct sk_buff *skb); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index bf5852f2d634..003bf108193f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -1029,3 +1029,36 @@ void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue) BIT(0) << (hw_queue)); } } + +bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring; + struct rtl_tx_desc *pdesc; + u8 own; + unsigned long flags; + struct sk_buff *pskb = NULL; + + ring = &rtlpci->tx_ring[BEACON_QUEUE]; + + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + + pskb = __skb_dequeue(&ring->queue); + if (pskb) + kfree_skb(pskb); + + pdesc = &ring->desc[0]; + own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); + + rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); + + __skb_queue_tail(&ring->queue, skb); + + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + + rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); + + return true; +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h index 53d0e0a5af5c..a5fcdfb69cda 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h @@ -711,4 +711,6 @@ void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue); void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, bool b_firstseg, bool b_lastseg, struct sk_buff *skb); +bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb); + #endif -- cgit v1.2.3 From a3dc5e881a8a5199bf371fdd4530cfa18280ca83 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 11 Feb 2011 14:27:58 -0600 Subject: rtlwifi: rtl8192ce: Rework rtl8192ce/phy.c Make the phy.c codes for rtl8192ce and rtl8192cu be as alike as possible. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | 99 ++++++++++------------------ 1 file changed, 35 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 45044117139a..05f7a45b30e1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -37,6 +37,9 @@ #include "dm.h" #include "table.h" +/* Define macro to shorten lines */ +#define MCS_TXPWR mcs_txpwrlevel_origoffset + static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset); static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, @@ -480,161 +483,129 @@ static void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, struct rtl_phy *rtlphy = &(rtlpriv->phy); if (regaddr == RTXAGC_A_RATE18_06) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] = - data; + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][0])); + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0])); } if (regaddr == RTXAGC_A_RATE54_24) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] = - data; + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][1])); + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1])); } if (regaddr == RTXAGC_A_CCK1_MCS32) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] = - data; + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][6])); + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6])); } if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] = - data; + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][7])); + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7])); } if (regaddr == RTXAGC_A_MCS03_MCS00) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] = - data; + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][2])); + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2])); } if (regaddr == RTXAGC_A_MCS07_MCS04) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] = - data; + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][3])); + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3])); } if (regaddr == RTXAGC_A_MCS11_MCS08) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] = - data; + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][4])); + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4])); } if (regaddr == RTXAGC_A_MCS15_MCS12) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] = - data; + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][5])); + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5])); } if (regaddr == RTXAGC_B_RATE18_06) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] = - data; + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][8])); + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8])); } if (regaddr == RTXAGC_B_RATE54_24) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] = - data; + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][9])); + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9])); } if (regaddr == RTXAGC_B_CCK1_55_MCS32) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] = - data; + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][14])); + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14])); } if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] = - data; + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][15])); + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15])); } if (regaddr == RTXAGC_B_MCS03_MCS00) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] = - data; + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][10])); + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10])); } if (regaddr == RTXAGC_B_MCS07_MCS04) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] = - data; + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][11])); + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11])); } if (regaddr == RTXAGC_B_MCS11_MCS08) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] = - data; + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][12])); + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12])); } if (regaddr == RTXAGC_B_MCS15_MCS12) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] = - data; + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> - pwrgroup_cnt][13])); + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13])); rtlphy->pwrgroup_cnt++; } -- cgit v1.2.3 From 2d55951368faa32ff098398c56780ebb6405a3d9 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 12 Feb 2011 01:39:15 +0100 Subject: ACPI / ACPICA: Avoid crashing if _PRW is defined for the root object Some ACPI BIOSes define _PRW for the root object which causes acpi_setup_gpe_for_wake() to crash when trying to dereference the bogus device_node pointer. Avoid the crash by checking if wake_device is not the root object before attempting to set up the "implicit notify" mechanism for it. The problem was introduced by commit bba63a296ffab20e08d9e8252d2f0d99 (ACPICA: Implicit notify support) that added the wake_device argument to acpi_setup_gpe_for_wake(). Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/evxfgpe.c | 49 +++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index e9562a7cb2f9..3b20a3401b64 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c @@ -212,37 +212,40 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device, return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* Validate wake_device is of type Device */ - - device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device); - if (device_node->type != ACPI_TYPE_DEVICE) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); /* Ensure that we have a valid GPE number */ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); - if (gpe_event_info) { - /* - * If there is no method or handler for this GPE, then the - * wake_device will be notified whenever this GPE fires (aka - * "implicit notify") Note: The GPE is assumed to be - * level-triggered (for windows compatibility). - */ - if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == - ACPI_GPE_DISPATCH_NONE) { - gpe_event_info->flags = - (ACPI_GPE_DISPATCH_NOTIFY | - ACPI_GPE_LEVEL_TRIGGERED); - gpe_event_info->dispatch.device_node = device_node; - } + if (!gpe_event_info) { + goto unlock_and_exit; + } + + /* + * If there is no method or handler for this GPE, then the + * wake_device will be notified whenever this GPE fires (aka + * "implicit notify") Note: The GPE is assumed to be + * level-triggered (for windows compatibility). + */ + if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == + ACPI_GPE_DISPATCH_NONE) && (wake_device != ACPI_ROOT_OBJECT)) { - gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; - status = AE_OK; + /* Validate wake_device is of type Device */ + + device_node = ACPI_CAST_PTR(struct acpi_namespace_node, + wake_device); + if (device_node->type != ACPI_TYPE_DEVICE) { + goto unlock_and_exit; + } + gpe_event_info->flags = (ACPI_GPE_DISPATCH_NOTIFY | + ACPI_GPE_LEVEL_TRIGGERED); + gpe_event_info->dispatch.device_node = device_node; } + gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; + status = AE_OK; + + unlock_and_exit: acpi_os_release_lock(acpi_gbl_gpe_lock, flags); return_ACPI_STATUS(status); } -- cgit v1.2.3 From 2a5d24286e8bdafdc272b37ec5bdd9e977b3767c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 12 Feb 2011 01:39:53 +0100 Subject: ACPI / Wakeup: Enable button GPEs unconditionally during initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 9630bdd (ACPI: Use GPE reference counting to support shared GPEs) introduced a suspend regression where boxes resume immediately after being suspended due to the lid or sleep button wakeup status not being cleared properly. This happens if the GPEs corresponding to those devices are not enabled all the time, which apparently is expected by some BIOSes. To fix this problem, enable button and lid GPEs unconditionally during initialization and keep them enabled all the time, regardless of whether or not the ACPI button driver is used. References: https://bugzilla.kernel.org/show_bug.cgi?id=27372 Reported-and-tested-by: Ferenc Wágner Cc: stable@kernel.org Signed-off-by: Rafael J. Wysocki --- drivers/acpi/wakeup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index ed6501452507..7bfbe40bc43b 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c @@ -86,8 +86,12 @@ int __init acpi_wakeup_device_init(void) struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list); - if (device_can_wakeup(&dev->dev)) + if (device_can_wakeup(&dev->dev)) { + /* Button GPEs are supposed to be always enabled. */ + acpi_enable_gpe(dev->wakeup.gpe_device, + dev->wakeup.gpe_number); device_set_wakeup_enable(&dev->dev, true); + } } mutex_unlock(&acpi_device_lock); return 0; -- cgit v1.2.3 From ed764e7ca042dbf4cc1c7f4e12cd842c7789f133 Mon Sep 17 00:00:00 2001 From: Michael Karcher Date: Sat, 12 Feb 2011 01:40:16 +0100 Subject: ACPI / Video: Probe for output switch method when searching video devices. This patch reverts one hunk of 677bd810eedce61edf15452491781ff046b92edc "ACPI video: remove output switching control", namely the removal of probing for _DOS/_DOD when searching for video devices. This is needed on some Fujitsu Laptops (at least S7110, P8010) for the ACPI backlight interface to work, as an these machines, neither ROM nor posting methods are available, and after removal of output switching, none of the caps triggers, which prevents the backlight search from being entered. Tested on a Fujitsu Lifebook S7110 and Fujitsu Lifebook P8010. This probably fixes https://bugzilla.kernel.org/show_bug.cgi?id=27312 for the people who have no entry in /sys/class/backlight. This is the complete list of public (starting with "_") methods implemented on the S7110, BIOS rev 1.34: \_SB_.PCI0.GFX0._ADR \_SB_.PCI0.GFX0._DOS \_SB_.PCI0.GFX0._DOD \_SB_.PCI0.GFX0.CRT._ADR \_SB_.PCI0.GFX0.CRT._DCS \_SB_.PCI0.GFX0.CRT._DGS \_SB_.PCI0.GFX0.CRT._DSS \_SB_.PCI0.GFX0.LCD._ADR \_SB_.PCI0.GFX0.LCD._BCL \_SB_.PCI0.GFX0.LCD._BCM \_SB_.PCI0.GFX0.LCD._BQC \_SB_.PCI0.GFX0.LCD._DCS \_SB_.PCI0.GFX0.LCD._DGS \_SB_.PCI0.GFX0.LCD._DSS \_SB_.PCI0.GFX0.LCD._PS0 \_SB_.PCI0.GFX0.LCD._PS3 \_SB_.PCI0.GFX0.TV._ADR \_SB_.PCI0.GFX0.TV._DCS \_SB_.PCI0.GFX0.TV._DGS \_SB_.PCI0.GFX0.TV._DSS \_SB_.PCI0.GFX0.DVI._ADR \_SB_.PCI0.GFX0.DVI._DCS \_SB_.PCI0.GFX0.DVI._DGS \_SB_.PCI0.GFX0.DVI._DSS Signed-off-by: Michael Karcher Acked-by: Zhang Rui Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video_detect.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 42d3d72dae85..5af3479714f6 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -82,6 +82,11 @@ long acpi_is_video_device(struct acpi_device *device) if (!device) return 0; + /* Is this device able to support video switching ? */ + if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) || + ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy))) + video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING; + /* Is this device able to retrieve a video ROM ? */ if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy))) video_caps |= ACPI_VIDEO_ROM_AVAILABLE; -- cgit v1.2.3 From 856c40125acf63f93aab5bc18ff9e627beeb0a3d Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 11 Feb 2011 13:32:32 +0000 Subject: be2net: While configuring QOS for VF, pass proper domain id While configuring QOS for VFs, the VF number should be translated to domain number correctly. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 82b2df8e12cf..4c73dceaeedf 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -820,7 +820,7 @@ static int be_set_vf_tx_rate(struct net_device *netdev, rate = 10000; adapter->vf_cfg[vf].vf_tx_rate = rate; - status = be_cmd_set_qos(adapter, rate / 10, vf); + status = be_cmd_set_qos(adapter, rate / 10, vf + 1); if (status) dev_info(&adapter->pdev->dev, -- cgit v1.2.3 From 6bff57a7a6b97f2bf98cb96e56db1ec02a29d135 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 11 Feb 2011 13:33:02 +0000 Subject: be2net: endianness fix in be_cmd_set_qos(). Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index a179cc6d79f2..d3b671d9e027 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -1868,8 +1868,8 @@ int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain) OPCODE_COMMON_SET_QOS, sizeof(*req)); req->hdr.domain = domain; - req->valid_bits = BE_QOS_BITS_NIC; - req->max_bps_nic = bps; + req->valid_bits = cpu_to_le32(BE_QOS_BITS_NIC); + req->max_bps_nic = cpu_to_le32(bps); status = be_mcc_notify_wait(adapter); -- cgit v1.2.3 From 658681f72589b95b7ab340b4f644783d263b5200 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 11 Feb 2011 13:34:46 +0000 Subject: be2net: Use domain id when be_cmd_if_destroy is called. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.c | 3 ++- drivers/net/benet/be_cmds.h | 3 ++- drivers/net/benet/be_main.c | 7 ++++--- 3 files changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index d3b671d9e027..be2981aa5857 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -995,7 +995,7 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, } /* Uses mbox */ -int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id) +int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id, u32 domain) { struct be_mcc_wrb *wrb; struct be_cmd_req_if_destroy *req; @@ -1016,6 +1016,7 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id) be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, OPCODE_COMMON_NTWK_INTERFACE_DESTROY, sizeof(*req)); + req->hdr.domain = domain; req->interface_id = cpu_to_le32(interface_id); status = be_mbox_notify_wait(adapter); diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 83d15c8a9fa3..02540bd9569d 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -1004,7 +1004,8 @@ extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id); extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, u8 *mac, bool pmac_invalid, u32 *if_handle, u32 *pmac_id, u32 domain); -extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle); +extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle, + u32 domain); extern int be_cmd_eq_create(struct be_adapter *adapter, struct be_queue_info *eq, int eq_delay); extern int be_cmd_cq_create(struct be_adapter *adapter, diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 4c73dceaeedf..aab464dd3063 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2335,8 +2335,9 @@ if_destroy: for (vf = 0; vf < num_vfs; vf++) if (adapter->vf_cfg[vf].vf_if_handle) be_cmd_if_destroy(adapter, - adapter->vf_cfg[vf].vf_if_handle); - be_cmd_if_destroy(adapter, adapter->if_handle); + adapter->vf_cfg[vf].vf_if_handle, + vf + 1); + be_cmd_if_destroy(adapter, adapter->if_handle, 0); do_none: return status; } @@ -2350,7 +2351,7 @@ static int be_clear(struct be_adapter *adapter) be_rx_queues_destroy(adapter); be_tx_queues_destroy(adapter); - be_cmd_if_destroy(adapter, adapter->if_handle); + be_cmd_if_destroy(adapter, adapter->if_handle, 0); /* tell fw we're done with firing cmds */ be_cmd_fw_clean(adapter); -- cgit v1.2.3 From c99ac3e7e47ffb9e504d9b08f608e9d7519a6b4f Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 11 Feb 2011 13:35:02 +0000 Subject: be2net: Initialize and cleanup sriov resources only if pci_enable_sriov has succeeded. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index aab464dd3063..c8075c1779bb 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2277,22 +2277,26 @@ static int be_setup(struct be_adapter *adapter) goto do_none; if (be_physfn(adapter)) { - while (vf < num_vfs) { - cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED - | BE_IF_FLAGS_BROADCAST; - status = be_cmd_if_create(adapter, cap_flags, en_flags, - mac, true, + if (adapter->sriov_enabled) { + while (vf < num_vfs) { + cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | + BE_IF_FLAGS_BROADCAST; + status = be_cmd_if_create(adapter, cap_flags, + en_flags, mac, true, &adapter->vf_cfg[vf].vf_if_handle, NULL, vf+1); - if (status) { - dev_err(&adapter->pdev->dev, - "Interface Create failed for VF %d\n", vf); - goto if_destroy; + if (status) { + dev_err(&adapter->pdev->dev, + "Interface Create failed for VF %d\n", + vf); + goto if_destroy; + } + adapter->vf_cfg[vf].vf_pmac_id = + BE_INVALID_PMAC_ID; + vf++; } - adapter->vf_cfg[vf].vf_pmac_id = BE_INVALID_PMAC_ID; - vf++; } - } else if (!be_physfn(adapter)) { + } else { status = be_cmd_mac_addr_query(adapter, mac, MAC_ADDRESS_TYPE_NETWORK, false, adapter->if_handle); if (!status) { @@ -2313,7 +2317,7 @@ static int be_setup(struct be_adapter *adapter) if (status != 0) goto rx_qs_destroy; - if (be_physfn(adapter)) { + if (be_physfn(adapter) && adapter->sriov_enabled) { status = be_vf_eth_addr_config(adapter); if (status) goto mcc_q_destroy; @@ -2332,9 +2336,10 @@ rx_qs_destroy: tx_qs_destroy: be_tx_queues_destroy(adapter); if_destroy: - for (vf = 0; vf < num_vfs; vf++) - if (adapter->vf_cfg[vf].vf_if_handle) - be_cmd_if_destroy(adapter, + if (be_physfn(adapter) && adapter->sriov_enabled) + for (vf = 0; vf < num_vfs; vf++) + if (adapter->vf_cfg[vf].vf_if_handle) + be_cmd_if_destroy(adapter, adapter->vf_cfg[vf].vf_if_handle, vf + 1); be_cmd_if_destroy(adapter, adapter->if_handle, 0); @@ -2344,7 +2349,7 @@ do_none: static int be_clear(struct be_adapter *adapter) { - if (be_physfn(adapter)) + if (be_physfn(adapter) && adapter->sriov_enabled) be_vf_eth_addr_rem(adapter); be_mcc_queues_destroy(adapter); -- cgit v1.2.3 From e63193652bfbea40e33b3a4cf4d338f9c82fbc05 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 11 Feb 2011 13:35:41 +0000 Subject: be2net: call be_vf_eth_addr_config() after register_netdev This is to avoid the completion processing for be_vf_eth_addr_config to consume the link status notification before netdev_register. Otherwise this causes the PF miss its first link status update. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index c8075c1779bb..48eef9e2ed94 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2317,19 +2317,10 @@ static int be_setup(struct be_adapter *adapter) if (status != 0) goto rx_qs_destroy; - if (be_physfn(adapter) && adapter->sriov_enabled) { - status = be_vf_eth_addr_config(adapter); - if (status) - goto mcc_q_destroy; - } - adapter->link_speed = -1; return 0; -mcc_q_destroy: - if (be_physfn(adapter)) - be_vf_eth_addr_rem(adapter); be_mcc_queues_destroy(adapter); rx_qs_destroy: be_rx_queues_destroy(adapter); @@ -2985,10 +2976,18 @@ static int __devinit be_probe(struct pci_dev *pdev, goto unsetup; netif_carrier_off(netdev); + if (be_physfn(adapter) && adapter->sriov_enabled) { + status = be_vf_eth_addr_config(adapter); + if (status) + goto unreg_netdev; + } + dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num); schedule_delayed_work(&adapter->work, msecs_to_jiffies(100)); return 0; +unreg_netdev: + unregister_netdev(netdev); unsetup: be_clear(adapter); msix_disable: -- cgit v1.2.3 From 7ab8b0b432cf5110624858e23ef264982e542f17 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 11 Feb 2011 13:35:56 +0000 Subject: be2net: Cleanup the VF interface handles The PF needs to cleanup all the interface handles that it created for the VFs. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 48eef9e2ed94..fc119d1f542b 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2340,6 +2340,8 @@ do_none: static int be_clear(struct be_adapter *adapter) { + int vf; + if (be_physfn(adapter) && adapter->sriov_enabled) be_vf_eth_addr_rem(adapter); @@ -2347,6 +2349,13 @@ static int be_clear(struct be_adapter *adapter) be_rx_queues_destroy(adapter); be_tx_queues_destroy(adapter); + if (be_physfn(adapter) && adapter->sriov_enabled) + for (vf = 0; vf < num_vfs; vf++) + if (adapter->vf_cfg[vf].vf_if_handle) + be_cmd_if_destroy(adapter, + adapter->vf_cfg[vf].vf_if_handle, + vf + 1); + be_cmd_if_destroy(adapter, adapter->if_handle, 0); /* tell fw we're done with firing cmds */ -- cgit v1.2.3 From 7a2414a50b071d84dae8fbca51d10009e07e535f Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 11 Feb 2011 13:36:18 +0000 Subject: be2net: For the VF MAC, use the OUI from current MAC address Currently we are always using the Emulex OUI for a VF MAC address while generating MAC for a VF. Use OUI from current MAC instead. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index add0b93350dd..3a800e2bc94b 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -450,9 +450,8 @@ static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac) mac[5] = (u8)(addr & 0xFF); mac[4] = (u8)((addr >> 8) & 0xFF); mac[3] = (u8)((addr >> 16) & 0xFF); - mac[2] = 0xC9; - mac[1] = 0x00; - mac[0] = 0x00; + /* Use the OUI from the current MAC address */ + memcpy(mac, adapter->netdev->dev_addr, 3); } extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, -- cgit v1.2.3 From f8617e0860f2b23797431b5ec3a46668eb0f7925 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 11 Feb 2011 13:36:37 +0000 Subject: be2net: pass domain numbers for pmac_add/del functions be_cmd_pmac_add/del functions need to pass domain number to the firmware. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.c | 6 ++++-- drivers/net/benet/be_cmds.h | 5 +++-- drivers/net/benet/be_main.c | 14 ++++++++------ 3 files changed, 15 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index be2981aa5857..277982babc11 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -598,7 +598,7 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, /* Uses synchronous MCCQ */ int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, - u32 if_id, u32 *pmac_id) + u32 if_id, u32 *pmac_id, u32 domain) { struct be_mcc_wrb *wrb; struct be_cmd_req_pmac_add *req; @@ -619,6 +619,7 @@ int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, OPCODE_COMMON_NTWK_PMAC_ADD, sizeof(*req)); + req->hdr.domain = domain; req->if_id = cpu_to_le32(if_id); memcpy(req->mac_address, mac_addr, ETH_ALEN); @@ -634,7 +635,7 @@ err: } /* Uses synchronous MCCQ */ -int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id) +int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id, u32 dom) { struct be_mcc_wrb *wrb; struct be_cmd_req_pmac_del *req; @@ -655,6 +656,7 @@ int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id) be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, OPCODE_COMMON_NTWK_PMAC_DEL, sizeof(*req)); + req->hdr.domain = dom; req->if_id = cpu_to_le32(if_id); req->pmac_id = cpu_to_le32(pmac_id); diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 02540bd9569d..91c5d2b09aa1 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -999,8 +999,9 @@ extern int be_cmd_POST(struct be_adapter *adapter); extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, u8 type, bool permanent, u32 if_handle); extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, - u32 if_id, u32 *pmac_id); -extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id); + u32 if_id, u32 *pmac_id, u32 domain); +extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, + u32 pmac_id, u32 domain); extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, u8 *mac, bool pmac_invalid, u32 *if_handle, u32 *pmac_id, u32 domain); diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index fc119d1f542b..f2d203637846 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -236,12 +236,13 @@ static int be_mac_addr_set(struct net_device *netdev, void *p) if (!be_physfn(adapter)) goto netdev_addr; - status = be_cmd_pmac_del(adapter, adapter->if_handle, adapter->pmac_id); + status = be_cmd_pmac_del(adapter, adapter->if_handle, + adapter->pmac_id, 0); if (status) return status; status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data, - adapter->if_handle, &adapter->pmac_id); + adapter->if_handle, &adapter->pmac_id, 0); netdev_addr: if (!status) memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); @@ -741,11 +742,11 @@ static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID) status = be_cmd_pmac_del(adapter, adapter->vf_cfg[vf].vf_if_handle, - adapter->vf_cfg[vf].vf_pmac_id); + adapter->vf_cfg[vf].vf_pmac_id, vf + 1); status = be_cmd_pmac_add(adapter, mac, adapter->vf_cfg[vf].vf_if_handle, - &adapter->vf_cfg[vf].vf_pmac_id); + &adapter->vf_cfg[vf].vf_pmac_id, vf + 1); if (status) dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed\n", @@ -2225,7 +2226,8 @@ static inline int be_vf_eth_addr_config(struct be_adapter *adapter) for (vf = 0; vf < num_vfs; vf++) { status = be_cmd_pmac_add(adapter, mac, adapter->vf_cfg[vf].vf_if_handle, - &adapter->vf_cfg[vf].vf_pmac_id); + &adapter->vf_cfg[vf].vf_pmac_id, + vf + 1); if (status) dev_err(&adapter->pdev->dev, "Mac address add failed for VF %d\n", vf); @@ -2245,7 +2247,7 @@ static inline void be_vf_eth_addr_rem(struct be_adapter *adapter) if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID) be_cmd_pmac_del(adapter, adapter->vf_cfg[vf].vf_if_handle, - adapter->vf_cfg[vf].vf_pmac_id); + adapter->vf_cfg[vf].vf_pmac_id, vf + 1); } } -- cgit v1.2.3 From a4b4dfab6ca808a5d1073cdfb7f39e8ce59f71e2 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 11 Feb 2011 13:36:57 +0000 Subject: be2net: Allow VFs to call be_cmd_reset_function. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index f2d203637846..8975340614b4 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2959,11 +2959,9 @@ static int __devinit be_probe(struct pci_dev *pdev, if (status) goto ctrl_clean; - if (be_physfn(adapter)) { - status = be_cmd_reset_function(adapter); - if (status) - goto ctrl_clean; - } + status = be_cmd_reset_function(adapter); + if (status) + goto ctrl_clean; status = be_stats_init(adapter); if (status) -- cgit v1.2.3 From 60964dd7087fa252c16022a7590e385294c5472a Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 11 Feb 2011 13:37:25 +0000 Subject: be2net: Fix broken priority setting when vlan tagging is enabled. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 277982babc11..8fa9a709d9fe 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -102,6 +102,7 @@ static void be_async_grp5_cos_priority_process(struct be_adapter *adapter, { if (evt->valid) { adapter->vlan_prio_bmap = evt->available_priority_bmap; + adapter->recommended_prio &= ~VLAN_PRIO_MASK; adapter->recommended_prio = evt->reco_default_priority << VLAN_PRIO_SHIFT; } -- cgit v1.2.3 From fae21a4da5767db0c0b481360780d6e8c7f906ae Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 11 Feb 2011 13:37:42 +0000 Subject: be2net: pass proper hdr_size while flashing redboot. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 8975340614b4..824d42002787 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2461,8 +2461,8 @@ static int be_flash_data(struct be_adapter *adapter, continue; if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) && (!be_flash_redboot(adapter, fw->data, - pflashcomp[i].offset, pflashcomp[i].size, - filehdr_size))) + pflashcomp[i].offset, pflashcomp[i].size, filehdr_size + + (num_of_images * sizeof(struct image_hdr))))) continue; p = fw->data; p += filehdr_size + pflashcomp[i].offset -- cgit v1.2.3 From a4ca055fc3124e1b6aee6b491a157cd242ee5226 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 11 Feb 2011 13:38:03 +0000 Subject: be2net: fix be_suspend/resume/shutdown > call pci msix disable in be_suspend > call pci msix enable in be_resume > stop worker thread in be_suspend > start worker thread in be_resume > stop worker thread in be_shutdown Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 824d42002787..7e83c06f913f 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -3023,6 +3023,7 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state) struct be_adapter *adapter = pci_get_drvdata(pdev); struct net_device *netdev = adapter->netdev; + cancel_delayed_work_sync(&adapter->work); if (adapter->wol) be_setup_wol(adapter, true); @@ -3035,6 +3036,7 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state) be_cmd_get_flow_control(adapter, &adapter->tx_fc, &adapter->rx_fc); be_clear(adapter); + be_msix_disable(adapter); pci_save_state(pdev); pci_disable_device(pdev); pci_set_power_state(pdev, pci_choose_state(pdev, state)); @@ -3056,6 +3058,7 @@ static int be_resume(struct pci_dev *pdev) pci_set_power_state(pdev, 0); pci_restore_state(pdev); + be_msix_enable(adapter); /* tell fw we're ready to fire cmds */ status = be_cmd_fw_init(adapter); if (status) @@ -3071,6 +3074,8 @@ static int be_resume(struct pci_dev *pdev) if (adapter->wol) be_setup_wol(adapter, false); + + schedule_delayed_work(&adapter->work, msecs_to_jiffies(100)); return 0; } @@ -3082,6 +3087,9 @@ static void be_shutdown(struct pci_dev *pdev) struct be_adapter *adapter = pci_get_drvdata(pdev); struct net_device *netdev = adapter->netdev; + if (netif_running(netdev)) + cancel_delayed_work_sync(&adapter->work); + netif_device_detach(netdev); be_cmd_reset_function(adapter); -- cgit v1.2.3 From 7acc2087fa204461871eccfdc913eef15ffd5c8f Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 11 Feb 2011 13:38:17 +0000 Subject: be2net: gracefully handle situations when UE is detected Avoid accessing the hardware when UE is detected. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.c | 15 +++++++++++++++ drivers/net/benet/be_main.c | 1 + 2 files changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 8fa9a709d9fe..619ebc24602e 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -23,6 +23,12 @@ static void be_mcc_notify(struct be_adapter *adapter) struct be_queue_info *mccq = &adapter->mcc_obj.q; u32 val = 0; + if (adapter->eeh_err) { + dev_info(&adapter->pdev->dev, + "Error in Card Detected! Cannot issue commands\n"); + return; + } + val |= mccq->id & DB_MCCQ_RING_ID_MASK; val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT; @@ -217,6 +223,9 @@ static int be_mcc_wait_compl(struct be_adapter *adapter) int i, num, status = 0; struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; + if (adapter->eeh_err) + return -EIO; + for (i = 0; i < mcc_timeout; i++) { num = be_process_mcc(adapter, &status); if (num) @@ -246,6 +255,12 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db) int msecs = 0; u32 ready; + if (adapter->eeh_err) { + dev_err(&adapter->pdev->dev, + "Error detected in card.Cannot issue commands\n"); + return -EIO; + } + do { ready = ioread32(db); if (ready == 0xffffffff) { diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 7e83c06f913f..1f5e342dd883 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1827,6 +1827,7 @@ void be_detect_dump_ue(struct be_adapter *adapter) if (ue_status_lo || ue_status_hi) { adapter->ue_detected = true; + adapter->eeh_err = true; dev_err(&adapter->pdev->dev, "UE Detected!!\n"); } -- cgit v1.2.3 From 9b037f3811acb0e613fae0fdf74e717f259b5b51 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 11 Feb 2011 13:38:29 +0000 Subject: be2net: detect a UE even when a interface is down. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 1f5e342dd883..aad7ea37d589 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1866,6 +1866,10 @@ static void be_worker(struct work_struct *work) struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; be_cq_notify(adapter, mcc_obj->cq.id, false, mcc_compl); } + + if (!adapter->ue_detected && !lancer_chip(adapter)) + be_detect_dump_ue(adapter); + goto reschedule; } -- cgit v1.2.3 From dcf96f1ff66f328fecf1e14437ac73db71b08c03 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Fri, 11 Feb 2011 13:39:30 +0000 Subject: be2net: restrict WOL to PFs only. WOL is not supported for Vrtual Functions. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_ethtool.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 0c9931473346..07b4ab902b17 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -516,12 +516,23 @@ be_phys_id(struct net_device *netdev, u32 data) return status; } +static bool +be_is_wol_supported(struct be_adapter *adapter) +{ + if (!be_physfn(adapter)) + return false; + else + return true; +} + static void be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) { struct be_adapter *adapter = netdev_priv(netdev); - wol->supported = WAKE_MAGIC; + if (be_is_wol_supported(adapter)) + wol->supported = WAKE_MAGIC; + if (adapter->wol) wol->wolopts = WAKE_MAGIC; else @@ -537,7 +548,7 @@ be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) if (wol->wolopts & ~WAKE_MAGIC) return -EINVAL; - if (wol->wolopts & WAKE_MAGIC) + if ((wol->wolopts & WAKE_MAGIC) && be_is_wol_supported(adapter)) adapter->wol = true; else adapter->wol = false; -- cgit v1.2.3 From d5e219c3a2389f31b18e4ca55c33a12adaadf565 Mon Sep 17 00:00:00 2001 From: hartleys Date: Fri, 11 Feb 2011 12:14:06 +0000 Subject: phy: Remove unneeded depends on PHYLIB Remove unneeded depends on PHYLIB. The config selection is already in an if PHYLIB / endif block. Signed-off-by: H Hartley Sweeten Cc: "David S. Miller" Signed-off-by: David S. Miller --- drivers/net/phy/Kconfig | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 35fda5ac8120..392a6c4b72e5 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -77,7 +77,6 @@ config NATIONAL_PHY Currently supports the DP83865 PHY. config STE10XP - depends on PHYLIB tristate "Driver for STMicroelectronics STe10Xp PHYs" ---help--- This is the driver for the STe100p and STe101p PHYs. -- cgit v1.2.3 From 563585ec4bf1319f193c2f51682985bcae400cb4 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Thu, 27 Jan 2011 16:12:37 -0500 Subject: [SCSI] qla2xxx: Fix race that could hang kthread_stop() There is a small race window in qla2x00_do_dpc() between checking for kthread_should_stop() and going to sleep after setting TASK_INTERRUPTIBLE. If qla2x00_free_device() is called in this window, kthread_stop will wait forever because there will be no one to wake up the process. Fix by making sure we only set TASK_INTERRUPTIBLE before checking kthread_stop(). Reported-by: Bandan Das Acked-by: Madhuranath Iyengar Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_os.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index c194c23ca1fb..15ce69eaaf4d 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -3282,10 +3282,10 @@ qla2x00_do_dpc(void *data) set_user_nice(current, -20); + set_current_state(TASK_INTERRUPTIBLE); while (!kthread_should_stop()) { DEBUG3(printk("qla2x00: DPC handler sleeping\n")); - set_current_state(TASK_INTERRUPTIBLE); schedule(); __set_current_state(TASK_RUNNING); @@ -3454,7 +3454,9 @@ qla2x00_do_dpc(void *data) qla2x00_do_dpc_all_vps(base_vha); ha->dpc_active = 0; + set_current_state(TASK_INTERRUPTIBLE); } /* End of while(1) */ + __set_current_state(TASK_RUNNING); DEBUG(printk("scsi(%ld): DPC handler exiting\n", base_vha->host_no)); -- cgit v1.2.3 From 044d78e1acb6614f5d79040e490f1fd9bfa45487 Mon Sep 17 00:00:00 2001 From: Madhuranath Iyengar Date: Fri, 28 Jan 2011 15:17:56 -0800 Subject: [SCSI] qla2xxx: Change from irq to irqsave with host_lock Make the driver safer by using irqsave/irqrestore with host_lock. Signed-off-by: Madhuranath Iyengar Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_attr.c | 5 +++-- drivers/scsi/qla2xxx/qla_init.c | 10 ++++++---- drivers/scsi/qla2xxx/qla_os.c | 5 +++-- 3 files changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 44578b56ad0a..d3e58d763b43 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -1561,6 +1561,7 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) { struct Scsi_Host *host = rport_to_shost(rport); fc_port_t *fcport = *(fc_port_t **)rport->dd_data; + unsigned long flags; if (!fcport) return; @@ -1573,10 +1574,10 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) * Transport has effectively 'deleted' the rport, clear * all local references. */ - spin_lock_irq(host->host_lock); + spin_lock_irqsave(host->host_lock, flags); fcport->rport = fcport->drport = NULL; *((fc_port_t **)rport->dd_data) = NULL; - spin_unlock_irq(host->host_lock); + spin_unlock_irqrestore(host->host_lock, flags); if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) return; diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index f948e1a73aec..d9479c3fe5f8 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -2505,11 +2505,12 @@ qla2x00_rport_del(void *data) { fc_port_t *fcport = data; struct fc_rport *rport; + unsigned long flags; - spin_lock_irq(fcport->vha->host->host_lock); + spin_lock_irqsave(fcport->vha->host->host_lock, flags); rport = fcport->drport ? fcport->drport: fcport->rport; fcport->drport = NULL; - spin_unlock_irq(fcport->vha->host->host_lock); + spin_unlock_irqrestore(fcport->vha->host->host_lock, flags); if (rport) fc_remote_port_delete(rport); } @@ -2879,6 +2880,7 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport) struct fc_rport_identifiers rport_ids; struct fc_rport *rport; struct qla_hw_data *ha = vha->hw; + unsigned long flags; qla2x00_rport_del(fcport); @@ -2893,9 +2895,9 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport) "Unable to allocate fc remote port!\n"); return; } - spin_lock_irq(fcport->vha->host->host_lock); + spin_lock_irqsave(fcport->vha->host->host_lock, flags); *((fc_port_t **)rport->dd_data) = fcport; - spin_unlock_irq(fcport->vha->host->host_lock); + spin_unlock_irqrestore(fcport->vha->host->host_lock, flags); rport->supported_classes = fcport->supported_classes; diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 15ce69eaaf4d..47208984903d 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2513,6 +2513,7 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport, { struct fc_rport *rport; scsi_qla_host_t *base_vha; + unsigned long flags; if (!fcport->rport) return; @@ -2520,9 +2521,9 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport, rport = fcport->rport; if (defer) { base_vha = pci_get_drvdata(vha->hw->pdev); - spin_lock_irq(vha->host->host_lock); + spin_lock_irqsave(vha->host->host_lock, flags); fcport->drport = rport; - spin_unlock_irq(vha->host->host_lock); + spin_unlock_irqrestore(vha->host->host_lock, flags); set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags); qla2xxx_wake_dpc(base_vha); } else -- cgit v1.2.3 From a361cc0025614fdd07f5f69aeeaa8075530870bc Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 31 Jan 2011 18:47:54 -0800 Subject: [SCSI] scsi_debug: Fix 32-bit overflow in do_device_access causing memory corruption If I create a scsi_debug device that is larger than 4GB, the multiplication of (block * scsi_debug_sector_size) can produce a 64-bit value. Unfortunately, the compiler sees two 32-bit quantities and performs a 32-bit multiplication, thus truncating the bits above 2^32. This causes the wrong memory location to be read or written. Change block and rest to be unsigned long long. Signed-off-by: Darrick J. Wong Acked-by: Douglas Gilbert Signed-off-by: James Bottomley --- drivers/scsi/scsi_debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 7b310934efed..a6b2d72022fc 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -1671,7 +1671,7 @@ static int do_device_access(struct scsi_cmnd *scmd, unsigned long long lba, unsigned int num, int write) { int ret; - unsigned int block, rest = 0; + unsigned long long block, rest = 0; int (*func)(struct scsi_cmnd *, unsigned char *, int); func = write ? fetch_to_dev_buffer : fill_from_dev_buffer; -- cgit v1.2.3 From 3ae279d25954de47c704ca713a2711ac10fcd1ee Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 9 Feb 2011 15:34:36 -0800 Subject: [SCSI] target: iblock/pscsi claim checking for NULL instead of IS_ERR blkdev_get_by_path() returns an ERR_PTR() or error and it doesn't return a NULL. It looks like this bug would be easy to trigger by mistake. Signed-off-by: Dan Carpenter Signed-off-by: Nicholas A. Bellinger Signed-off-by: James Bottomley --- drivers/target/target_core_iblock.c | 2 +- drivers/target/target_core_pscsi.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index c6e0d757e76e..34561350d5e8 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -154,7 +154,7 @@ static struct se_device *iblock_create_virtdevice( bd = blkdev_get_by_path(ib_dev->ibd_udev_path, FMODE_WRITE|FMODE_READ|FMODE_EXCL, ib_dev); - if (!(bd)) + if (IS_ERR(bd)) goto failed; /* * Setup the local scope queue_limits from struct request_queue->limits diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 742d24609a9b..f2a08477a68c 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -462,8 +462,8 @@ static struct se_device *pscsi_create_type_disk( */ bd = blkdev_get_by_path(se_dev->se_dev_udev_path, FMODE_WRITE|FMODE_READ|FMODE_EXCL, pdv); - if (!(bd)) { - printk("pSCSI: blkdev_get_by_path() failed\n"); + if (IS_ERR(bd)) { + printk(KERN_ERR "pSCSI: blkdev_get_by_path() failed\n"); scsi_device_put(sd); return NULL; } -- cgit v1.2.3 From bc66552476d3faf706ea72f5a082df717ed6c30d Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Wed, 9 Feb 2011 15:34:38 -0800 Subject: [SCSI] target/iblock: Fix failed bd claim NULL pointer dereference This patch adds an explict check for struct iblock_dev->ibd_bd in iblock_free_device() before calling blkdev_put(), which will otherwise hit the following NULL pointer dereference @ ib_dev->ibd_bd when iblock_create_virtdevice() fails to claim an already in-use struct block_device via blkdev_get_by_path(). [ 112.528578] Target_Core_ConfigFS: Allocated struct se_subsystem_dev: ffff88001e750000 se_dev_su_ptr: ffff88001dd05d70 [ 112.534681] Target_Core_ConfigFS: Calling t->free_device() for se_dev_su_ptr: ffff88001dd05d70 [ 112.535029] BUG: unable to handle kernel NULL pointer dereference at 0000000000000020 [ 112.535029] IP: [] mutex_lock+0x14/0x35 [ 112.535029] PGD 1e5d0067 PUD 1e274067 PMD 0 [ 112.535029] Oops: 0002 [#1] SMP [ 112.535029] last sysfs file: /sys/devices/pci0000:00/0000:00:07.1/host2/target2:0:0/2:0:0:0/type [ 112.535029] CPU 0 [ 112.535029] Modules linked in: iscsi_target_mod target_core_stgt scsi_tgt target_core_pscsi target_core_file target_core_iblock target_core_mod configfs sr_mod cdrom sd_mod ata_piix mptspi mptscsih libata mptbase [last unloaded: scsi_wait_scan] [ 112.535029] [ 112.535029] Pid: 3345, comm: python2.5 Not tainted 2.6.37+ #1 440BX Desktop Reference Platform/VMware Virtual Platform [ 112.535029] RIP: 0010:[] [] mutex_lock+0x14/0x35 [ 112.535029] RSP: 0018:ffff88001e6d7d58 EFLAGS: 00010246 [ 112.535029] RAX: 0000000000000000 RBX: 0000000000000020 RCX: 0000000000000082 [ 112.535029] RDX: ffff88001e6d7fd8 RSI: 0000000000000083 RDI: 0000000000000020 [ 112.535029] RBP: ffff88001e6d7d68 R08: 0000000000000000 R09: 0000000000000000 [ 112.535029] R10: ffff8800000be860 R11: ffff88001f420000 R12: 0000000000000020 [ 112.535029] R13: 0000000000000083 R14: ffff88001d809430 R15: ffff88001d8094f8 [ 112.535029] FS: 00007ff17ca7d6e0(0000) GS:ffff88001fa00000(0000) knlGS:0000000000000000 [ 112.535029] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 112.535029] CR2: 0000000000000020 CR3: 000000001e5d2000 CR4: 00000000000006f0 [ 112.535029] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 112.535029] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 112.535029] Process python2.5 (pid: 3345, threadinfo ffff88001e6d6000, task ffff88001e2d0760) [ 112.535029] Stack: [ 112.535029] ffff88001e6d7d88 0000000000000000 ffff88001e6d7d98 ffffffff811187fc [ 112.535029] ffff88001d809430 ffff88001dd05d70 ffff88001e750860 ffff88001e750000 [ 112.535029] ffff88001e6d7db8 ffffffffa00e3757 ffff88001e6d7db8 0000000000000004 [ 112.535029] Call Trace: [ 112.535029] [] blkdev_put+0x28/0x107 [ 112.535029] [] iblock_free_device+0x1d/0x36 [target_core_iblock] [ 112.535029] [] target_core_drop_subdev+0x15f/0x18d [target_core_mod] [ 112.535029] [] client_drop_item+0x25/0x31 [configfs] [ 112.535029] [] configfs_rmdir+0x1a1/0x223 [configfs] [ 112.535029] [] vfs_rmdir+0x7e/0xd3 [ 112.535029] [] do_rmdir+0xa3/0xf4 [ 112.535029] [] sys_rmdir+0x11/0x13 [ 112.535029] [] system_call_fastpath+0x16/0x1b [ 112.535029] Code: 8b 04 25 88 b5 00 00 48 2d d8 1f 00 00 48 89 43 18 31 c0 5e 5b c9 c3 55 48 89 e5 53 48 89 fb 48 83 ec 08 e8 c4 f7 ff ff 48 89 df <3e> ff 0f 79 05 e8 1e ff ff ff 65 48 8b 04 25 88 b5 00 00 48 2d [ 112.535029] RIP [] mutex_lock+0x14/0x35 [ 112.535029] RSP [ 112.535029] CR2: 0000000000000020 [ 132.679636] ---[ end trace 05754bb48eb828f0 ]--- Note it also adds an second explict check for ib_dev->ibd_bio_set before calling bioset_free() to fix the same possible NULL pointer deference during an early iblock_create_virtdevice() failure. Signed-off-by: Nicholas A. Bellinger Signed-off-by: James Bottomley --- drivers/target/target_core_iblock.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 34561350d5e8..67f0c09983c8 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -220,8 +220,10 @@ static void iblock_free_device(void *p) { struct iblock_dev *ib_dev = p; - blkdev_put(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL); - bioset_free(ib_dev->ibd_bio_set); + if (ib_dev->ibd_bd != NULL) + blkdev_put(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL); + if (ib_dev->ibd_bio_set != NULL) + bioset_free(ib_dev->ibd_bio_set); kfree(ib_dev); } -- cgit v1.2.3 From 29fe609d124d6d7478d1241bb82dc2e00509f516 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Wed, 9 Feb 2011 15:34:43 -0800 Subject: [SCSI] target: Fix demo-mode MappedLUN shutdown UA/PR breakage This patch fixes a bug in core_update_device_list_for_node() where individual demo-mode generated MappedLUN's UA + Persistent Reservations metadata where being leaked, instead of falling through and calling existing core_scsi3_ua_release_all() and core_scsi3_free_pr_reg_from_nacl() at the end of core_update_device_list_for_node(). This bug would manifest itself with the following OOPs w/ TPG demo-mode endpoints (tfo->tpg_check_demo_mode()=1), and PROUT REGISTER+RESERVE -> explict struct se_session logout -> struct se_device shutdown: [ 697.021139] LIO_iblock used greatest stack depth: 2704 bytes left [ 702.235017] general protection fault: 0000 [#1] SMP [ 702.235074] last sysfs file: /sys/devices/virtual/net/lo/operstate [ 704.372695] CPU 0 [ 704.372725] Modules linked in: crc32c target_core_stgt scsi_tgt target_core_pscsi target_core_file target_core_iblock target_core_mod configfs sr_mod cdrom sd_mod ata_piix mptspi mptscsih libata mptbase [last unloaded: iscsi_target_mod] [ 704.375442] [ 704.375563] Pid: 4964, comm: tcm_node Not tainted 2.6.37+ #1 440BX Desktop Reference Platform/VMware Virtual Platform [ 704.375912] RIP: 0010:[] [] __core_scsi3_complete_pro_release+0x31/0x133 [target_core_mod] [ 704.376017] RSP: 0018:ffff88001e5ffcb8 EFLAGS: 00010296 [ 704.376017] RAX: 6d32335b1b0a0d0a RBX: ffff88001d952cb0 RCX: 0000000000000015 [ 704.376017] RDX: ffff88001b428000 RSI: ffff88001da5a4c0 RDI: ffff88001e5ffcd8 [ 704.376017] RBP: ffff88001e5ffd28 R08: ffff88001e5ffcd8 R09: ffff88001d952080 [ 704.377116] R10: ffff88001dfc5480 R11: ffff88001df8abb0 R12: ffff88001d952cb0 [ 704.377319] R13: 0000000000000000 R14: ffff88001df8abb0 R15: ffff88001b428000 [ 704.377521] FS: 00007f033d15c6e0(0000) GS:ffff88001fa00000(0000) knlGS:0000000000000000 [ 704.377861] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 704.378043] CR2: 00007fff09281510 CR3: 000000001e5db000 CR4: 00000000000006f0 [ 704.378110] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 704.378110] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 704.378110] Process tcm_node (pid: 4964, threadinfo ffff88001e5fe000, task ffff88001d99c260) [ 704.378110] Stack: [ 704.378110] ffffea0000678980 ffff88001da5a4c0 ffffea0000678980 ffff88001f402b00 [ 704.378110] ffff88001e5ffd08 ffffffff810ea236 ffff88001e5ffd18 0000000000000282 [ 704.379772] ffff88001d952080 ffff88001d952cb0 ffff88001d952cb0 ffff88001dc79010 [ 704.380082] Call Trace: [ 704.380220] [] ? __slab_free+0x89/0x11c [ 704.380403] [] core_scsi3_free_all_registrations+0x3e/0x157 [target_core_mod] [ 704.380479] [] se_release_device_for_hba+0xa6/0xd8 [target_core_mod] [ 704.380479] [] se_free_virtual_device+0x3b/0x45 [target_core_mod] [ 704.383750] [] target_core_drop_subdev+0x13a/0x18d [target_core_mod] [ 704.384068] [] client_drop_item+0x25/0x31 [configfs] [ 704.384263] [] configfs_rmdir+0x1a1/0x223 [configfs] [ 704.384459] [] vfs_rmdir+0x7e/0xd3 [ 704.384631] [] do_rmdir+0xa3/0xf4 [ 704.384895] [] ? filp_close+0x67/0x72 [ 704.386485] [] sys_rmdir+0x11/0x13 [ 704.387893] [] system_call_fastpath+0x16/0x1b [ 704.388083] Code: 4c 8d 45 b0 41 56 49 89 d7 41 55 41 89 cd 41 54 b9 15 00 00 00 53 48 89 fb 48 83 ec 48 4c 89 c7 48 89 75 98 48 8b 86 28 01 00 00 <48> 8b 80 90 01 00 00 48 89 45 a0 31 c0 f3 aa c7 45 ac 00 00 00 [ 704.388763] RIP [] __core_scsi3_complete_pro_release+0x31/0x133 [target_core_mod] [ 704.389142] RSP [ 704.389572] ---[ end trace 2a3614f3cd6261a5 ]--- Signed-off-by: Nicholas A. Bellinger Signed-off-by: James Bottomley --- drivers/target/target_core_device.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 317ce58d426d..969d72785288 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -373,11 +373,11 @@ int core_update_device_list_for_node( /* * deve->se_lun_acl will be NULL for demo-mode created LUNs * that have not been explictly concerted to MappedLUNs -> - * struct se_lun_acl. + * struct se_lun_acl, but we remove deve->alua_port_list from + * port->sep_alua_list. This also means that active UAs and + * NodeACL context specific PR metadata for demo-mode + * MappedLUN *deve will be released below.. */ - if (!(deve->se_lun_acl)) - return 0; - spin_lock_bh(&port->sep_alua_lock); list_del(&deve->alua_port_list); spin_unlock_bh(&port->sep_alua_lock); -- cgit v1.2.3 From 85dc98d93f3dc41cce54118a7abab9e6aa616dd2 Mon Sep 17 00:00:00 2001 From: Fubo Chen Date: Wed, 9 Feb 2011 15:34:48 -0800 Subject: [SCSI] target: fixed missing lock drop in error path The struct se_node_acl->device_list_lock needs to be released if either sanity check for struct se_dev_entry->se_lun_acl or deve->se_lun fails. Signed-off-by: Fubo Chen Signed-off-by: Nicholas A. Bellinger Signed-off-by: James Bottomley --- drivers/target/target_core_device.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 969d72785288..9551ab541f03 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -395,12 +395,14 @@ int core_update_device_list_for_node( printk(KERN_ERR "struct se_dev_entry->se_lun_acl" " already set for demo mode -> explict" " LUN ACL transition\n"); + spin_unlock_irq(&nacl->device_list_lock); return -1; } if (deve->se_lun != lun) { printk(KERN_ERR "struct se_dev_entry->se_lun does" " match passed struct se_lun for demo mode" " -> explict LUN ACL transition\n"); + spin_unlock_irq(&nacl->device_list_lock); return -1; } deve->se_lun_acl = lun_acl; -- cgit v1.2.3 From 7c2bf6e925c38b8e3358f5046971b0d6086ddcf8 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Wed, 9 Feb 2011 15:34:53 -0800 Subject: [SCSI] target: Fix top-level configfs_subsystem default_group shutdown breakage This patch fixes two bugs uncovered during testing with slub_debug=FPUZ during module_exit() -> target_core_exit_configfs() with release of configfs subsystem consumer default groups, namely how this should be working with fs/configfs/dir.c:configfs_unregister_subsystem() release logic for struct config_group->default_group. The first issue involves configfs_unregister_subsystem() expecting to walk+drain the top-level subsys->su_group.default_groups directly in unlink_group(), and not directly from the configfs subsystem consumer for the top level struct config_group->default_groups. This patch drops the walk+drain of subsys->su_group.default_groups from TCM configfs subsystem consumer code, and moves the top-level ->default_groups kfree() after configfs_unregister_subsystem() has been called. The second issue involves calling core_alua_free_lu_gp(se_global->default_lu_gp) to release the default_lu_gp->lu_gp_group before configfs_unregister_subsystem() has been called. This patches also moves the core_alua_free_lu_gp() call to release default_lu_group->lu_gp_group after the subsys has been unregistered. Finally, this patch explictly clears the [lu_gp,alua,hba]_cg->default_groups pointers after kfree() to ensure that no stale memory is picked up from child struct config_group->default_group[] while configfs_unregister_subsystem() is called. Reported-by: Fubo Chen Signed-off-by: Nicholas A. Bellinger Signed-off-by: James Bottomley --- drivers/target/target_core_configfs.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 2764510798b0..1cb74d57ed5f 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -3178,8 +3178,7 @@ static void target_core_exit_configfs(void) config_item_put(item); } kfree(lu_gp_cg->default_groups); - core_alua_free_lu_gp(se_global->default_lu_gp); - se_global->default_lu_gp = NULL; + lu_gp_cg->default_groups = NULL; alua_cg = &se_global->alua_group; for (i = 0; alua_cg->default_groups[i]; i++) { @@ -3188,6 +3187,7 @@ static void target_core_exit_configfs(void) config_item_put(item); } kfree(alua_cg->default_groups); + alua_cg->default_groups = NULL; hba_cg = &se_global->target_core_hbagroup; for (i = 0; hba_cg->default_groups[i]; i++) { @@ -3196,15 +3196,17 @@ static void target_core_exit_configfs(void) config_item_put(item); } kfree(hba_cg->default_groups); - - for (i = 0; subsys->su_group.default_groups[i]; i++) { - item = &subsys->su_group.default_groups[i]->cg_item; - subsys->su_group.default_groups[i] = NULL; - config_item_put(item); - } + hba_cg->default_groups = NULL; + /* + * We expect subsys->su_group.default_groups to be released + * by configfs subsystem provider logic.. + */ + configfs_unregister_subsystem(subsys); kfree(subsys->su_group.default_groups); - configfs_unregister_subsystem(subsys); + core_alua_free_lu_gp(se_global->default_lu_gp); + se_global->default_lu_gp = NULL; + printk(KERN_INFO "TARGET_CORE[0]: Released ConfigFS Fabric" " Infrastructure\n"); -- cgit v1.2.3 From e63af95888894af6ca4112dc90083d1dff0fec29 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Wed, 9 Feb 2011 15:35:04 -0800 Subject: [SCSI] target: Fix SCF_SCSI_CONTROL_SG_IO_CDB breakage This patch fixes a bug introduced during the v4 control CDB emulation refactoring that broke SCF_SCSI_CONTROL_SG_IO_CDB operation within transport_map_control_cmd_to_task(). It moves the BUG_ON() into transport_do_se_mem_map() after the TRANSPORT(dev)->do_se_mem_map() RAMDISK_DR special case, and adds the proper struct se_mem assignment when !list_empty() for normal non RAMDISK_DR backend device cases. Reported-by: Kai-Thorsten Hambrecht Signed-off-by: Nicholas A. Bellinger Signed-off-by: James Bottomley --- drivers/target/target_core_transport.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 28b6292ff298..32dc5163b5a0 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -4827,6 +4827,8 @@ static int transport_do_se_mem_map( return ret; } + + BUG_ON(list_empty(se_mem_list)); /* * This is the normal path for all normal non BIDI and BIDI-COMMAND * WRITE payloads.. If we need to do BIDI READ passthrough for @@ -5008,7 +5010,9 @@ transport_map_control_cmd_to_task(struct se_cmd *cmd) struct se_mem *se_mem = NULL, *se_mem_lout = NULL; u32 se_mem_cnt = 0, task_offset = 0; - BUG_ON(list_empty(cmd->t_task->t_mem_list)); + if (!list_empty(T_TASK(cmd)->t_mem_list)) + se_mem = list_entry(T_TASK(cmd)->t_mem_list->next, + struct se_mem, se_list); ret = transport_do_se_mem_map(dev, task, cmd->t_task->t_mem_list, NULL, se_mem, -- cgit v1.2.3 From e89d15eeadb172bd53ca6362bf9ab6b22077224c Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Wed, 9 Feb 2011 15:35:03 -0800 Subject: [SCSI] target: Remove procfs based target_core_mib.c code This patch removes the legacy procfs based target_core_mib.c code, and moves the necessary scsi_index_tables functions and defines into target_core_transport.c and target_core_base.h code to allow existing fabric independent statistics to function. This includes the removal of a handful of 'atomic_t mib_ref_count' counters used in struct se_node_acl, se_session and se_hba to prevent removal while using seq_list procfs walking logic. [jejb: fix up compile failures] Signed-off-by: Nicholas A. Bellinger Signed-off-by: James Bottomley --- drivers/target/Makefile | 3 +- drivers/target/target_core_configfs.c | 15 - drivers/target/target_core_device.c | 3 - drivers/target/target_core_mib.c | 1078 -------------------------------- drivers/target/target_core_mib.h | 28 - drivers/target/target_core_tpg.c | 29 +- drivers/target/target_core_transport.c | 42 +- include/target/target_core_base.h | 27 +- include/target/target_core_transport.h | 2 + 9 files changed, 79 insertions(+), 1148 deletions(-) delete mode 100644 drivers/target/target_core_mib.c delete mode 100644 drivers/target/target_core_mib.h (limited to 'drivers') diff --git a/drivers/target/Makefile b/drivers/target/Makefile index 5cfd70819f08..973bb190ef57 100644 --- a/drivers/target/Makefile +++ b/drivers/target/Makefile @@ -13,8 +13,7 @@ target_core_mod-y := target_core_configfs.o \ target_core_transport.o \ target_core_cdb.o \ target_core_ua.o \ - target_core_rd.o \ - target_core_mib.o + target_core_rd.o obj-$(CONFIG_TARGET_CORE) += target_core_mod.o diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 1cb74d57ed5f..e77001b16063 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include @@ -3022,7 +3021,6 @@ static int target_core_init_configfs(void) struct config_group *target_cg, *hba_cg = NULL, *alua_cg = NULL; struct config_group *lu_gp_cg = NULL; struct configfs_subsystem *subsys; - struct proc_dir_entry *scsi_target_proc = NULL; struct t10_alua_lu_gp *lu_gp; int ret; @@ -3128,21 +3126,10 @@ static int target_core_init_configfs(void) if (core_dev_setup_virtual_lun0() < 0) goto out; - scsi_target_proc = proc_mkdir("scsi_target", 0); - if (!(scsi_target_proc)) { - printk(KERN_ERR "proc_mkdir(scsi_target, 0) failed\n"); - goto out; - } - ret = init_scsi_target_mib(); - if (ret < 0) - goto out; - return 0; out: configfs_unregister_subsystem(subsys); - if (scsi_target_proc) - remove_proc_entry("scsi_target", 0); core_dev_release_virtual_lun0(); rd_module_exit(); out_global: @@ -3210,8 +3197,6 @@ static void target_core_exit_configfs(void) printk(KERN_INFO "TARGET_CORE[0]: Released ConfigFS Fabric" " Infrastructure\n"); - remove_scsi_target_mib(); - remove_proc_entry("scsi_target", 0); core_dev_release_virtual_lun0(); rd_module_exit(); release_se_global(); diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 9551ab541f03..5da051a07fa3 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -867,9 +867,6 @@ static void se_dev_stop(struct se_device *dev) } } spin_unlock(&hba->device_lock); - - while (atomic_read(&hba->dev_mib_access_count)) - cpu_relax(); } int se_dev_check_online(struct se_device *dev) diff --git a/drivers/target/target_core_mib.c b/drivers/target/target_core_mib.c deleted file mode 100644 index d5a48aa0d2d1..000000000000 --- a/drivers/target/target_core_mib.c +++ /dev/null @@ -1,1078 +0,0 @@ -/******************************************************************************* - * Filename: target_core_mib.c - * - * Copyright (c) 2006-2007 SBE, Inc. All Rights Reserved. - * Copyright (c) 2007-2010 Rising Tide Systems - * Copyright (c) 2008-2010 Linux-iSCSI.org - * - * Nicholas A. Bellinger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - ******************************************************************************/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "target_core_hba.h" -#include "target_core_mib.h" - -/* SCSI mib table index */ -static struct scsi_index_table scsi_index_table; - -#ifndef INITIAL_JIFFIES -#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ)) -#endif - -/* SCSI Instance Table */ -#define SCSI_INST_SW_INDEX 1 -#define SCSI_TRANSPORT_INDEX 1 - -#define NONE "None" -#define ISPRINT(a) ((a >= ' ') && (a <= '~')) - -static inline int list_is_first(const struct list_head *list, - const struct list_head *head) -{ - return list->prev == head; -} - -static void *locate_hba_start( - struct seq_file *seq, - loff_t *pos) -{ - spin_lock(&se_global->g_device_lock); - return seq_list_start(&se_global->g_se_dev_list, *pos); -} - -static void *locate_hba_next( - struct seq_file *seq, - void *v, - loff_t *pos) -{ - return seq_list_next(v, &se_global->g_se_dev_list, pos); -} - -static void locate_hba_stop(struct seq_file *seq, void *v) -{ - spin_unlock(&se_global->g_device_lock); -} - -/**************************************************************************** - * SCSI MIB Tables - ****************************************************************************/ - -/* - * SCSI Instance Table - */ -static void *scsi_inst_seq_start( - struct seq_file *seq, - loff_t *pos) -{ - spin_lock(&se_global->hba_lock); - return seq_list_start(&se_global->g_hba_list, *pos); -} - -static void *scsi_inst_seq_next( - struct seq_file *seq, - void *v, - loff_t *pos) -{ - return seq_list_next(v, &se_global->g_hba_list, pos); -} - -static void scsi_inst_seq_stop(struct seq_file *seq, void *v) -{ - spin_unlock(&se_global->hba_lock); -} - -static int scsi_inst_seq_show(struct seq_file *seq, void *v) -{ - struct se_hba *hba = list_entry(v, struct se_hba, hba_list); - - if (list_is_first(&hba->hba_list, &se_global->g_hba_list)) - seq_puts(seq, "inst sw_indx\n"); - - seq_printf(seq, "%u %u\n", hba->hba_index, SCSI_INST_SW_INDEX); - seq_printf(seq, "plugin: %s version: %s\n", - hba->transport->name, TARGET_CORE_VERSION); - - return 0; -} - -static const struct seq_operations scsi_inst_seq_ops = { - .start = scsi_inst_seq_start, - .next = scsi_inst_seq_next, - .stop = scsi_inst_seq_stop, - .show = scsi_inst_seq_show -}; - -static int scsi_inst_seq_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &scsi_inst_seq_ops); -} - -static const struct file_operations scsi_inst_seq_fops = { - .owner = THIS_MODULE, - .open = scsi_inst_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -/* - * SCSI Device Table - */ -static void *scsi_dev_seq_start(struct seq_file *seq, loff_t *pos) -{ - return locate_hba_start(seq, pos); -} - -static void *scsi_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) -{ - return locate_hba_next(seq, v, pos); -} - -static void scsi_dev_seq_stop(struct seq_file *seq, void *v) -{ - locate_hba_stop(seq, v); -} - -static int scsi_dev_seq_show(struct seq_file *seq, void *v) -{ - struct se_hba *hba; - struct se_subsystem_dev *se_dev = list_entry(v, struct se_subsystem_dev, - g_se_dev_list); - struct se_device *dev = se_dev->se_dev_ptr; - char str[28]; - int k; - - if (list_is_first(&se_dev->g_se_dev_list, &se_global->g_se_dev_list)) - seq_puts(seq, "inst indx role ports\n"); - - if (!(dev)) - return 0; - - hba = dev->se_hba; - if (!(hba)) { - /* Log error ? */ - return 0; - } - - seq_printf(seq, "%u %u %s %u\n", hba->hba_index, - dev->dev_index, "Target", dev->dev_port_count); - - memcpy(&str[0], (void *)DEV_T10_WWN(dev), 28); - - /* vendor */ - for (k = 0; k < 8; k++) - str[k] = ISPRINT(DEV_T10_WWN(dev)->vendor[k]) ? - DEV_T10_WWN(dev)->vendor[k] : 0x20; - str[k] = 0x20; - - /* model */ - for (k = 0; k < 16; k++) - str[k+9] = ISPRINT(DEV_T10_WWN(dev)->model[k]) ? - DEV_T10_WWN(dev)->model[k] : 0x20; - str[k + 9] = 0; - - seq_printf(seq, "dev_alias: %s\n", str); - - return 0; -} - -static const struct seq_operations scsi_dev_seq_ops = { - .start = scsi_dev_seq_start, - .next = scsi_dev_seq_next, - .stop = scsi_dev_seq_stop, - .show = scsi_dev_seq_show -}; - -static int scsi_dev_seq_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &scsi_dev_seq_ops); -} - -static const struct file_operations scsi_dev_seq_fops = { - .owner = THIS_MODULE, - .open = scsi_dev_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -/* - * SCSI Port Table - */ -static void *scsi_port_seq_start(struct seq_file *seq, loff_t *pos) -{ - return locate_hba_start(seq, pos); -} - -static void *scsi_port_seq_next(struct seq_file *seq, void *v, loff_t *pos) -{ - return locate_hba_next(seq, v, pos); -} - -static void scsi_port_seq_stop(struct seq_file *seq, void *v) -{ - locate_hba_stop(seq, v); -} - -static int scsi_port_seq_show(struct seq_file *seq, void *v) -{ - struct se_hba *hba; - struct se_subsystem_dev *se_dev = list_entry(v, struct se_subsystem_dev, - g_se_dev_list); - struct se_device *dev = se_dev->se_dev_ptr; - struct se_port *sep, *sep_tmp; - - if (list_is_first(&se_dev->g_se_dev_list, &se_global->g_se_dev_list)) - seq_puts(seq, "inst device indx role busy_count\n"); - - if (!(dev)) - return 0; - - hba = dev->se_hba; - if (!(hba)) { - /* Log error ? */ - return 0; - } - - /* FIXME: scsiPortBusyStatuses count */ - spin_lock(&dev->se_port_lock); - list_for_each_entry_safe(sep, sep_tmp, &dev->dev_sep_list, sep_list) { - seq_printf(seq, "%u %u %u %s%u %u\n", hba->hba_index, - dev->dev_index, sep->sep_index, "Device", - dev->dev_index, 0); - } - spin_unlock(&dev->se_port_lock); - - return 0; -} - -static const struct seq_operations scsi_port_seq_ops = { - .start = scsi_port_seq_start, - .next = scsi_port_seq_next, - .stop = scsi_port_seq_stop, - .show = scsi_port_seq_show -}; - -static int scsi_port_seq_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &scsi_port_seq_ops); -} - -static const struct file_operations scsi_port_seq_fops = { - .owner = THIS_MODULE, - .open = scsi_port_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -/* - * SCSI Transport Table - */ -static void *scsi_transport_seq_start(struct seq_file *seq, loff_t *pos) -{ - return locate_hba_start(seq, pos); -} - -static void *scsi_transport_seq_next(struct seq_file *seq, void *v, loff_t *pos) -{ - return locate_hba_next(seq, v, pos); -} - -static void scsi_transport_seq_stop(struct seq_file *seq, void *v) -{ - locate_hba_stop(seq, v); -} - -static int scsi_transport_seq_show(struct seq_file *seq, void *v) -{ - struct se_hba *hba; - struct se_subsystem_dev *se_dev = list_entry(v, struct se_subsystem_dev, - g_se_dev_list); - struct se_device *dev = se_dev->se_dev_ptr; - struct se_port *se, *se_tmp; - struct se_portal_group *tpg; - struct t10_wwn *wwn; - char buf[64]; - - if (list_is_first(&se_dev->g_se_dev_list, &se_global->g_se_dev_list)) - seq_puts(seq, "inst device indx dev_name\n"); - - if (!(dev)) - return 0; - - hba = dev->se_hba; - if (!(hba)) { - /* Log error ? */ - return 0; - } - - wwn = DEV_T10_WWN(dev); - - spin_lock(&dev->se_port_lock); - list_for_each_entry_safe(se, se_tmp, &dev->dev_sep_list, sep_list) { - tpg = se->sep_tpg; - sprintf(buf, "scsiTransport%s", - TPG_TFO(tpg)->get_fabric_name()); - - seq_printf(seq, "%u %s %u %s+%s\n", - hba->hba_index, /* scsiTransportIndex */ - buf, /* scsiTransportType */ - (TPG_TFO(tpg)->tpg_get_inst_index != NULL) ? - TPG_TFO(tpg)->tpg_get_inst_index(tpg) : - 0, - TPG_TFO(tpg)->tpg_get_wwn(tpg), - (strlen(wwn->unit_serial)) ? - /* scsiTransportDevName */ - wwn->unit_serial : wwn->vendor); - } - spin_unlock(&dev->se_port_lock); - - return 0; -} - -static const struct seq_operations scsi_transport_seq_ops = { - .start = scsi_transport_seq_start, - .next = scsi_transport_seq_next, - .stop = scsi_transport_seq_stop, - .show = scsi_transport_seq_show -}; - -static int scsi_transport_seq_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &scsi_transport_seq_ops); -} - -static const struct file_operations scsi_transport_seq_fops = { - .owner = THIS_MODULE, - .open = scsi_transport_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -/* - * SCSI Target Device Table - */ -static void *scsi_tgt_dev_seq_start(struct seq_file *seq, loff_t *pos) -{ - return locate_hba_start(seq, pos); -} - -static void *scsi_tgt_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) -{ - return locate_hba_next(seq, v, pos); -} - -static void scsi_tgt_dev_seq_stop(struct seq_file *seq, void *v) -{ - locate_hba_stop(seq, v); -} - - -#define LU_COUNT 1 /* for now */ -static int scsi_tgt_dev_seq_show(struct seq_file *seq, void *v) -{ - struct se_hba *hba; - struct se_subsystem_dev *se_dev = list_entry(v, struct se_subsystem_dev, - g_se_dev_list); - struct se_device *dev = se_dev->se_dev_ptr; - int non_accessible_lus = 0; - char status[16]; - - if (list_is_first(&se_dev->g_se_dev_list, &se_global->g_se_dev_list)) - seq_puts(seq, "inst indx num_LUs status non_access_LUs" - " resets\n"); - - if (!(dev)) - return 0; - - hba = dev->se_hba; - if (!(hba)) { - /* Log error ? */ - return 0; - } - - switch (dev->dev_status) { - case TRANSPORT_DEVICE_ACTIVATED: - strcpy(status, "activated"); - break; - case TRANSPORT_DEVICE_DEACTIVATED: - strcpy(status, "deactivated"); - non_accessible_lus = 1; - break; - case TRANSPORT_DEVICE_SHUTDOWN: - strcpy(status, "shutdown"); - non_accessible_lus = 1; - break; - case TRANSPORT_DEVICE_OFFLINE_ACTIVATED: - case TRANSPORT_DEVICE_OFFLINE_DEACTIVATED: - strcpy(status, "offline"); - non_accessible_lus = 1; - break; - default: - sprintf(status, "unknown(%d)", dev->dev_status); - non_accessible_lus = 1; - } - - seq_printf(seq, "%u %u %u %s %u %u\n", - hba->hba_index, dev->dev_index, LU_COUNT, - status, non_accessible_lus, dev->num_resets); - - return 0; -} - -static const struct seq_operations scsi_tgt_dev_seq_ops = { - .start = scsi_tgt_dev_seq_start, - .next = scsi_tgt_dev_seq_next, - .stop = scsi_tgt_dev_seq_stop, - .show = scsi_tgt_dev_seq_show -}; - -static int scsi_tgt_dev_seq_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &scsi_tgt_dev_seq_ops); -} - -static const struct file_operations scsi_tgt_dev_seq_fops = { - .owner = THIS_MODULE, - .open = scsi_tgt_dev_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -/* - * SCSI Target Port Table - */ -static void *scsi_tgt_port_seq_start(struct seq_file *seq, loff_t *pos) -{ - return locate_hba_start(seq, pos); -} - -static void *scsi_tgt_port_seq_next(struct seq_file *seq, void *v, loff_t *pos) -{ - return locate_hba_next(seq, v, pos); -} - -static void scsi_tgt_port_seq_stop(struct seq_file *seq, void *v) -{ - locate_hba_stop(seq, v); -} - -static int scsi_tgt_port_seq_show(struct seq_file *seq, void *v) -{ - struct se_hba *hba; - struct se_subsystem_dev *se_dev = list_entry(v, struct se_subsystem_dev, - g_se_dev_list); - struct se_device *dev = se_dev->se_dev_ptr; - struct se_port *sep, *sep_tmp; - struct se_portal_group *tpg; - u32 rx_mbytes, tx_mbytes; - unsigned long long num_cmds; - char buf[64]; - - if (list_is_first(&se_dev->g_se_dev_list, &se_global->g_se_dev_list)) - seq_puts(seq, "inst device indx name port_index in_cmds" - " write_mbytes read_mbytes hs_in_cmds\n"); - - if (!(dev)) - return 0; - - hba = dev->se_hba; - if (!(hba)) { - /* Log error ? */ - return 0; - } - - spin_lock(&dev->se_port_lock); - list_for_each_entry_safe(sep, sep_tmp, &dev->dev_sep_list, sep_list) { - tpg = sep->sep_tpg; - sprintf(buf, "%sPort#", - TPG_TFO(tpg)->get_fabric_name()); - - seq_printf(seq, "%u %u %u %s%d %s%s%d ", - hba->hba_index, - dev->dev_index, - sep->sep_index, - buf, sep->sep_index, - TPG_TFO(tpg)->tpg_get_wwn(tpg), "+t+", - TPG_TFO(tpg)->tpg_get_tag(tpg)); - - spin_lock(&sep->sep_lun->lun_sep_lock); - num_cmds = sep->sep_stats.cmd_pdus; - rx_mbytes = (sep->sep_stats.rx_data_octets >> 20); - tx_mbytes = (sep->sep_stats.tx_data_octets >> 20); - spin_unlock(&sep->sep_lun->lun_sep_lock); - - seq_printf(seq, "%llu %u %u %u\n", num_cmds, - rx_mbytes, tx_mbytes, 0); - } - spin_unlock(&dev->se_port_lock); - - return 0; -} - -static const struct seq_operations scsi_tgt_port_seq_ops = { - .start = scsi_tgt_port_seq_start, - .next = scsi_tgt_port_seq_next, - .stop = scsi_tgt_port_seq_stop, - .show = scsi_tgt_port_seq_show -}; - -static int scsi_tgt_port_seq_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &scsi_tgt_port_seq_ops); -} - -static const struct file_operations scsi_tgt_port_seq_fops = { - .owner = THIS_MODULE, - .open = scsi_tgt_port_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -/* - * SCSI Authorized Initiator Table: - * It contains the SCSI Initiators authorized to be attached to one of the - * local Target ports. - * Iterates through all active TPGs and extracts the info from the ACLs - */ -static void *scsi_auth_intr_seq_start(struct seq_file *seq, loff_t *pos) -{ - spin_lock_bh(&se_global->se_tpg_lock); - return seq_list_start(&se_global->g_se_tpg_list, *pos); -} - -static void *scsi_auth_intr_seq_next(struct seq_file *seq, void *v, - loff_t *pos) -{ - return seq_list_next(v, &se_global->g_se_tpg_list, pos); -} - -static void scsi_auth_intr_seq_stop(struct seq_file *seq, void *v) -{ - spin_unlock_bh(&se_global->se_tpg_lock); -} - -static int scsi_auth_intr_seq_show(struct seq_file *seq, void *v) -{ - struct se_portal_group *se_tpg = list_entry(v, struct se_portal_group, - se_tpg_list); - struct se_dev_entry *deve; - struct se_lun *lun; - struct se_node_acl *se_nacl; - int j; - - if (list_is_first(&se_tpg->se_tpg_list, - &se_global->g_se_tpg_list)) - seq_puts(seq, "inst dev port indx dev_or_port intr_name " - "map_indx att_count num_cmds read_mbytes " - "write_mbytes hs_num_cmds creation_time row_status\n"); - - if (!(se_tpg)) - return 0; - - spin_lock(&se_tpg->acl_node_lock); - list_for_each_entry(se_nacl, &se_tpg->acl_node_list, acl_list) { - - atomic_inc(&se_nacl->mib_ref_count); - smp_mb__after_atomic_inc(); - spin_unlock(&se_tpg->acl_node_lock); - - spin_lock_irq(&se_nacl->device_list_lock); - for (j = 0; j < TRANSPORT_MAX_LUNS_PER_TPG; j++) { - deve = &se_nacl->device_list[j]; - if (!(deve->lun_flags & - TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) || - (!deve->se_lun)) - continue; - lun = deve->se_lun; - if (!lun->lun_se_dev) - continue; - - seq_printf(seq, "%u %u %u %u %u %s %u %u %u %u %u %u" - " %u %s\n", - /* scsiInstIndex */ - (TPG_TFO(se_tpg)->tpg_get_inst_index != NULL) ? - TPG_TFO(se_tpg)->tpg_get_inst_index(se_tpg) : - 0, - /* scsiDeviceIndex */ - lun->lun_se_dev->dev_index, - /* scsiAuthIntrTgtPortIndex */ - TPG_TFO(se_tpg)->tpg_get_tag(se_tpg), - /* scsiAuthIntrIndex */ - se_nacl->acl_index, - /* scsiAuthIntrDevOrPort */ - 1, - /* scsiAuthIntrName */ - se_nacl->initiatorname[0] ? - se_nacl->initiatorname : NONE, - /* FIXME: scsiAuthIntrLunMapIndex */ - 0, - /* scsiAuthIntrAttachedTimes */ - deve->attach_count, - /* scsiAuthIntrOutCommands */ - deve->total_cmds, - /* scsiAuthIntrReadMegaBytes */ - (u32)(deve->read_bytes >> 20), - /* scsiAuthIntrWrittenMegaBytes */ - (u32)(deve->write_bytes >> 20), - /* FIXME: scsiAuthIntrHSOutCommands */ - 0, - /* scsiAuthIntrLastCreation */ - (u32)(((u32)deve->creation_time - - INITIAL_JIFFIES) * 100 / HZ), - /* FIXME: scsiAuthIntrRowStatus */ - "Ready"); - } - spin_unlock_irq(&se_nacl->device_list_lock); - - spin_lock(&se_tpg->acl_node_lock); - atomic_dec(&se_nacl->mib_ref_count); - smp_mb__after_atomic_dec(); - } - spin_unlock(&se_tpg->acl_node_lock); - - return 0; -} - -static const struct seq_operations scsi_auth_intr_seq_ops = { - .start = scsi_auth_intr_seq_start, - .next = scsi_auth_intr_seq_next, - .stop = scsi_auth_intr_seq_stop, - .show = scsi_auth_intr_seq_show -}; - -static int scsi_auth_intr_seq_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &scsi_auth_intr_seq_ops); -} - -static const struct file_operations scsi_auth_intr_seq_fops = { - .owner = THIS_MODULE, - .open = scsi_auth_intr_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -/* - * SCSI Attached Initiator Port Table: - * It lists the SCSI Initiators attached to one of the local Target ports. - * Iterates through all active TPGs and use active sessions from each TPG - * to list the info fo this table. - */ -static void *scsi_att_intr_port_seq_start(struct seq_file *seq, loff_t *pos) -{ - spin_lock_bh(&se_global->se_tpg_lock); - return seq_list_start(&se_global->g_se_tpg_list, *pos); -} - -static void *scsi_att_intr_port_seq_next(struct seq_file *seq, void *v, - loff_t *pos) -{ - return seq_list_next(v, &se_global->g_se_tpg_list, pos); -} - -static void scsi_att_intr_port_seq_stop(struct seq_file *seq, void *v) -{ - spin_unlock_bh(&se_global->se_tpg_lock); -} - -static int scsi_att_intr_port_seq_show(struct seq_file *seq, void *v) -{ - struct se_portal_group *se_tpg = list_entry(v, struct se_portal_group, - se_tpg_list); - struct se_dev_entry *deve; - struct se_lun *lun; - struct se_node_acl *se_nacl; - struct se_session *se_sess; - unsigned char buf[64]; - int j; - - if (list_is_first(&se_tpg->se_tpg_list, - &se_global->g_se_tpg_list)) - seq_puts(seq, "inst dev port indx port_auth_indx port_name" - " port_ident\n"); - - if (!(se_tpg)) - return 0; - - spin_lock(&se_tpg->session_lock); - list_for_each_entry(se_sess, &se_tpg->tpg_sess_list, sess_list) { - if ((TPG_TFO(se_tpg)->sess_logged_in(se_sess)) || - (!se_sess->se_node_acl) || - (!se_sess->se_node_acl->device_list)) - continue; - - atomic_inc(&se_sess->mib_ref_count); - smp_mb__after_atomic_inc(); - se_nacl = se_sess->se_node_acl; - atomic_inc(&se_nacl->mib_ref_count); - smp_mb__after_atomic_inc(); - spin_unlock(&se_tpg->session_lock); - - spin_lock_irq(&se_nacl->device_list_lock); - for (j = 0; j < TRANSPORT_MAX_LUNS_PER_TPG; j++) { - deve = &se_nacl->device_list[j]; - if (!(deve->lun_flags & - TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) || - (!deve->se_lun)) - continue; - - lun = deve->se_lun; - if (!lun->lun_se_dev) - continue; - - memset(buf, 0, 64); - if (TPG_TFO(se_tpg)->sess_get_initiator_sid != NULL) - TPG_TFO(se_tpg)->sess_get_initiator_sid( - se_sess, (unsigned char *)&buf[0], 64); - - seq_printf(seq, "%u %u %u %u %u %s+i+%s\n", - /* scsiInstIndex */ - (TPG_TFO(se_tpg)->tpg_get_inst_index != NULL) ? - TPG_TFO(se_tpg)->tpg_get_inst_index(se_tpg) : - 0, - /* scsiDeviceIndex */ - lun->lun_se_dev->dev_index, - /* scsiPortIndex */ - TPG_TFO(se_tpg)->tpg_get_tag(se_tpg), - /* scsiAttIntrPortIndex */ - (TPG_TFO(se_tpg)->sess_get_index != NULL) ? - TPG_TFO(se_tpg)->sess_get_index(se_sess) : - 0, - /* scsiAttIntrPortAuthIntrIdx */ - se_nacl->acl_index, - /* scsiAttIntrPortName */ - se_nacl->initiatorname[0] ? - se_nacl->initiatorname : NONE, - /* scsiAttIntrPortIdentifier */ - buf); - } - spin_unlock_irq(&se_nacl->device_list_lock); - - spin_lock(&se_tpg->session_lock); - atomic_dec(&se_nacl->mib_ref_count); - smp_mb__after_atomic_dec(); - atomic_dec(&se_sess->mib_ref_count); - smp_mb__after_atomic_dec(); - } - spin_unlock(&se_tpg->session_lock); - - return 0; -} - -static const struct seq_operations scsi_att_intr_port_seq_ops = { - .start = scsi_att_intr_port_seq_start, - .next = scsi_att_intr_port_seq_next, - .stop = scsi_att_intr_port_seq_stop, - .show = scsi_att_intr_port_seq_show -}; - -static int scsi_att_intr_port_seq_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &scsi_att_intr_port_seq_ops); -} - -static const struct file_operations scsi_att_intr_port_seq_fops = { - .owner = THIS_MODULE, - .open = scsi_att_intr_port_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -/* - * SCSI Logical Unit Table - */ -static void *scsi_lu_seq_start(struct seq_file *seq, loff_t *pos) -{ - return locate_hba_start(seq, pos); -} - -static void *scsi_lu_seq_next(struct seq_file *seq, void *v, loff_t *pos) -{ - return locate_hba_next(seq, v, pos); -} - -static void scsi_lu_seq_stop(struct seq_file *seq, void *v) -{ - locate_hba_stop(seq, v); -} - -#define SCSI_LU_INDEX 1 -static int scsi_lu_seq_show(struct seq_file *seq, void *v) -{ - struct se_hba *hba; - struct se_subsystem_dev *se_dev = list_entry(v, struct se_subsystem_dev, - g_se_dev_list); - struct se_device *dev = se_dev->se_dev_ptr; - int j; - char str[28]; - - if (list_is_first(&se_dev->g_se_dev_list, &se_global->g_se_dev_list)) - seq_puts(seq, "inst dev indx LUN lu_name vend prod rev" - " dev_type status state-bit num_cmds read_mbytes" - " write_mbytes resets full_stat hs_num_cmds creation_time\n"); - - if (!(dev)) - return 0; - - hba = dev->se_hba; - if (!(hba)) { - /* Log error ? */ - return 0; - } - - /* Fix LU state, if we can read it from the device */ - seq_printf(seq, "%u %u %u %llu %s", hba->hba_index, - dev->dev_index, SCSI_LU_INDEX, - (unsigned long long)0, /* FIXME: scsiLuDefaultLun */ - (strlen(DEV_T10_WWN(dev)->unit_serial)) ? - /* scsiLuWwnName */ - (char *)&DEV_T10_WWN(dev)->unit_serial[0] : - "None"); - - memcpy(&str[0], (void *)DEV_T10_WWN(dev), 28); - /* scsiLuVendorId */ - for (j = 0; j < 8; j++) - str[j] = ISPRINT(DEV_T10_WWN(dev)->vendor[j]) ? - DEV_T10_WWN(dev)->vendor[j] : 0x20; - str[8] = 0; - seq_printf(seq, " %s", str); - - /* scsiLuProductId */ - for (j = 0; j < 16; j++) - str[j] = ISPRINT(DEV_T10_WWN(dev)->model[j]) ? - DEV_T10_WWN(dev)->model[j] : 0x20; - str[16] = 0; - seq_printf(seq, " %s", str); - - /* scsiLuRevisionId */ - for (j = 0; j < 4; j++) - str[j] = ISPRINT(DEV_T10_WWN(dev)->revision[j]) ? - DEV_T10_WWN(dev)->revision[j] : 0x20; - str[4] = 0; - seq_printf(seq, " %s", str); - - seq_printf(seq, " %u %s %s %llu %u %u %u %u %u %u\n", - /* scsiLuPeripheralType */ - TRANSPORT(dev)->get_device_type(dev), - (dev->dev_status == TRANSPORT_DEVICE_ACTIVATED) ? - "available" : "notavailable", /* scsiLuStatus */ - "exposed", /* scsiLuState */ - (unsigned long long)dev->num_cmds, - /* scsiLuReadMegaBytes */ - (u32)(dev->read_bytes >> 20), - /* scsiLuWrittenMegaBytes */ - (u32)(dev->write_bytes >> 20), - dev->num_resets, /* scsiLuInResets */ - 0, /* scsiLuOutTaskSetFullStatus */ - 0, /* scsiLuHSInCommands */ - (u32)(((u32)dev->creation_time - INITIAL_JIFFIES) * - 100 / HZ)); - - return 0; -} - -static const struct seq_operations scsi_lu_seq_ops = { - .start = scsi_lu_seq_start, - .next = scsi_lu_seq_next, - .stop = scsi_lu_seq_stop, - .show = scsi_lu_seq_show -}; - -static int scsi_lu_seq_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &scsi_lu_seq_ops); -} - -static const struct file_operations scsi_lu_seq_fops = { - .owner = THIS_MODULE, - .open = scsi_lu_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -/****************************************************************************/ - -/* - * Remove proc fs entries - */ -void remove_scsi_target_mib(void) -{ - remove_proc_entry("scsi_target/mib/scsi_inst", NULL); - remove_proc_entry("scsi_target/mib/scsi_dev", NULL); - remove_proc_entry("scsi_target/mib/scsi_port", NULL); - remove_proc_entry("scsi_target/mib/scsi_transport", NULL); - remove_proc_entry("scsi_target/mib/scsi_tgt_dev", NULL); - remove_proc_entry("scsi_target/mib/scsi_tgt_port", NULL); - remove_proc_entry("scsi_target/mib/scsi_auth_intr", NULL); - remove_proc_entry("scsi_target/mib/scsi_att_intr_port", NULL); - remove_proc_entry("scsi_target/mib/scsi_lu", NULL); - remove_proc_entry("scsi_target/mib", NULL); -} - -/* - * Create proc fs entries for the mib tables - */ -int init_scsi_target_mib(void) -{ - struct proc_dir_entry *dir_entry; - struct proc_dir_entry *scsi_inst_entry; - struct proc_dir_entry *scsi_dev_entry; - struct proc_dir_entry *scsi_port_entry; - struct proc_dir_entry *scsi_transport_entry; - struct proc_dir_entry *scsi_tgt_dev_entry; - struct proc_dir_entry *scsi_tgt_port_entry; - struct proc_dir_entry *scsi_auth_intr_entry; - struct proc_dir_entry *scsi_att_intr_port_entry; - struct proc_dir_entry *scsi_lu_entry; - - dir_entry = proc_mkdir("scsi_target/mib", NULL); - if (!(dir_entry)) { - printk(KERN_ERR "proc_mkdir() failed.\n"); - return -1; - } - - scsi_inst_entry = - create_proc_entry("scsi_target/mib/scsi_inst", 0, NULL); - if (scsi_inst_entry) - scsi_inst_entry->proc_fops = &scsi_inst_seq_fops; - else - goto error; - - scsi_dev_entry = - create_proc_entry("scsi_target/mib/scsi_dev", 0, NULL); - if (scsi_dev_entry) - scsi_dev_entry->proc_fops = &scsi_dev_seq_fops; - else - goto error; - - scsi_port_entry = - create_proc_entry("scsi_target/mib/scsi_port", 0, NULL); - if (scsi_port_entry) - scsi_port_entry->proc_fops = &scsi_port_seq_fops; - else - goto error; - - scsi_transport_entry = - create_proc_entry("scsi_target/mib/scsi_transport", 0, NULL); - if (scsi_transport_entry) - scsi_transport_entry->proc_fops = &scsi_transport_seq_fops; - else - goto error; - - scsi_tgt_dev_entry = - create_proc_entry("scsi_target/mib/scsi_tgt_dev", 0, NULL); - if (scsi_tgt_dev_entry) - scsi_tgt_dev_entry->proc_fops = &scsi_tgt_dev_seq_fops; - else - goto error; - - scsi_tgt_port_entry = - create_proc_entry("scsi_target/mib/scsi_tgt_port", 0, NULL); - if (scsi_tgt_port_entry) - scsi_tgt_port_entry->proc_fops = &scsi_tgt_port_seq_fops; - else - goto error; - - scsi_auth_intr_entry = - create_proc_entry("scsi_target/mib/scsi_auth_intr", 0, NULL); - if (scsi_auth_intr_entry) - scsi_auth_intr_entry->proc_fops = &scsi_auth_intr_seq_fops; - else - goto error; - - scsi_att_intr_port_entry = - create_proc_entry("scsi_target/mib/scsi_att_intr_port", 0, NULL); - if (scsi_att_intr_port_entry) - scsi_att_intr_port_entry->proc_fops = - &scsi_att_intr_port_seq_fops; - else - goto error; - - scsi_lu_entry = create_proc_entry("scsi_target/mib/scsi_lu", 0, NULL); - if (scsi_lu_entry) - scsi_lu_entry->proc_fops = &scsi_lu_seq_fops; - else - goto error; - - return 0; - -error: - printk(KERN_ERR "create_proc_entry() failed.\n"); - remove_scsi_target_mib(); - return -1; -} - -/* - * Initialize the index table for allocating unique row indexes to various mib - * tables - */ -void init_scsi_index_table(void) -{ - memset(&scsi_index_table, 0, sizeof(struct scsi_index_table)); - spin_lock_init(&scsi_index_table.lock); -} - -/* - * Allocate a new row index for the entry type specified - */ -u32 scsi_get_new_index(scsi_index_t type) -{ - u32 new_index; - - if ((type < 0) || (type >= SCSI_INDEX_TYPE_MAX)) { - printk(KERN_ERR "Invalid index type %d\n", type); - return -1; - } - - spin_lock(&scsi_index_table.lock); - new_index = ++scsi_index_table.scsi_mib_index[type]; - if (new_index == 0) - new_index = ++scsi_index_table.scsi_mib_index[type]; - spin_unlock(&scsi_index_table.lock); - - return new_index; -} -EXPORT_SYMBOL(scsi_get_new_index); diff --git a/drivers/target/target_core_mib.h b/drivers/target/target_core_mib.h deleted file mode 100644 index 277204633850..000000000000 --- a/drivers/target/target_core_mib.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef TARGET_CORE_MIB_H -#define TARGET_CORE_MIB_H - -typedef enum { - SCSI_INST_INDEX, - SCSI_DEVICE_INDEX, - SCSI_AUTH_INTR_INDEX, - SCSI_INDEX_TYPE_MAX -} scsi_index_t; - -struct scsi_index_table { - spinlock_t lock; - u32 scsi_mib_index[SCSI_INDEX_TYPE_MAX]; -} ____cacheline_aligned; - -/* SCSI Port stats */ -struct scsi_port_stats { - u64 cmd_pdus; - u64 tx_data_octets; - u64 rx_data_octets; -} ____cacheline_aligned; - -extern int init_scsi_target_mib(void); -extern void remove_scsi_target_mib(void); -extern void init_scsi_index_table(void); -extern u32 scsi_get_new_index(scsi_index_t); - -#endif /*** TARGET_CORE_MIB_H ***/ diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index abfa81a57115..c26f67467623 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -275,7 +275,6 @@ struct se_node_acl *core_tpg_check_initiator_node_acl( spin_lock_init(&acl->device_list_lock); spin_lock_init(&acl->nacl_sess_lock); atomic_set(&acl->acl_pr_ref_count, 0); - atomic_set(&acl->mib_ref_count, 0); acl->queue_depth = TPG_TFO(tpg)->tpg_get_default_depth(tpg); snprintf(acl->initiatorname, TRANSPORT_IQN_LEN, "%s", initiatorname); acl->se_tpg = tpg; @@ -318,12 +317,6 @@ void core_tpg_wait_for_nacl_pr_ref(struct se_node_acl *nacl) cpu_relax(); } -void core_tpg_wait_for_mib_ref(struct se_node_acl *nacl) -{ - while (atomic_read(&nacl->mib_ref_count) != 0) - cpu_relax(); -} - void core_tpg_clear_object_luns(struct se_portal_group *tpg) { int i, ret; @@ -480,7 +473,6 @@ int core_tpg_del_initiator_node_acl( spin_unlock_bh(&tpg->session_lock); core_tpg_wait_for_nacl_pr_ref(acl); - core_tpg_wait_for_mib_ref(acl); core_clear_initiator_node_from_tpg(acl, tpg); core_free_device_list_for_node(acl, tpg); @@ -701,6 +693,8 @@ EXPORT_SYMBOL(core_tpg_register); int core_tpg_deregister(struct se_portal_group *se_tpg) { + struct se_node_acl *nacl, *nacl_tmp; + printk(KERN_INFO "TARGET_CORE[%s]: Deallocating %s struct se_portal_group" " for endpoint: %s Portal Tag %u\n", (se_tpg->se_tpg_type == TRANSPORT_TPG_TYPE_NORMAL) ? @@ -714,6 +708,25 @@ int core_tpg_deregister(struct se_portal_group *se_tpg) while (atomic_read(&se_tpg->tpg_pr_ref_count) != 0) cpu_relax(); + /* + * Release any remaining demo-mode generated se_node_acl that have + * not been released because of TFO->tpg_check_demo_mode_cache() == 1 + * in transport_deregister_session(). + */ + spin_lock_bh(&se_tpg->acl_node_lock); + list_for_each_entry_safe(nacl, nacl_tmp, &se_tpg->acl_node_list, + acl_list) { + list_del(&nacl->acl_list); + se_tpg->num_node_acls--; + spin_unlock_bh(&se_tpg->acl_node_lock); + + core_tpg_wait_for_nacl_pr_ref(nacl); + core_free_device_list_for_node(nacl, se_tpg); + TPG_TFO(se_tpg)->tpg_release_fabric_acl(se_tpg, nacl); + + spin_lock_bh(&se_tpg->acl_node_lock); + } + spin_unlock_bh(&se_tpg->acl_node_lock); if (se_tpg->se_tpg_type == TRANSPORT_TPG_TYPE_NORMAL) core_tpg_release_virtual_lun0(se_tpg); diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 32dc5163b5a0..236e22d8cfae 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -379,6 +379,40 @@ void release_se_global(void) se_global = NULL; } +/* SCSI statistics table index */ +static struct scsi_index_table scsi_index_table; + +/* + * Initialize the index table for allocating unique row indexes to various mib + * tables. + */ +void init_scsi_index_table(void) +{ + memset(&scsi_index_table, 0, sizeof(struct scsi_index_table)); + spin_lock_init(&scsi_index_table.lock); +} + +/* + * Allocate a new row index for the entry type specified + */ +u32 scsi_get_new_index(scsi_index_t type) +{ + u32 new_index; + + if ((type < 0) || (type >= SCSI_INDEX_TYPE_MAX)) { + printk(KERN_ERR "Invalid index type %d\n", type); + return -EINVAL; + } + + spin_lock(&scsi_index_table.lock); + new_index = ++scsi_index_table.scsi_mib_index[type]; + if (new_index == 0) + new_index = ++scsi_index_table.scsi_mib_index[type]; + spin_unlock(&scsi_index_table.lock); + + return new_index; +} + void transport_init_queue_obj(struct se_queue_obj *qobj) { atomic_set(&qobj->queue_cnt, 0); @@ -437,7 +471,6 @@ struct se_session *transport_init_session(void) } INIT_LIST_HEAD(&se_sess->sess_list); INIT_LIST_HEAD(&se_sess->sess_acl_list); - atomic_set(&se_sess->mib_ref_count, 0); return se_sess; } @@ -546,12 +579,6 @@ void transport_deregister_session(struct se_session *se_sess) transport_free_session(se_sess); return; } - /* - * Wait for possible reference in drivers/target/target_core_mib.c: - * scsi_att_intr_port_seq_show() - */ - while (atomic_read(&se_sess->mib_ref_count) != 0) - cpu_relax(); spin_lock_bh(&se_tpg->session_lock); list_del(&se_sess->sess_list); @@ -574,7 +601,6 @@ void transport_deregister_session(struct se_session *se_sess) spin_unlock_bh(&se_tpg->acl_node_lock); core_tpg_wait_for_nacl_pr_ref(se_nacl); - core_tpg_wait_for_mib_ref(se_nacl); core_free_device_list_for_node(se_nacl, se_tpg); TPG_TFO(se_tpg)->tpg_release_fabric_acl(se_tpg, se_nacl); diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 07fdfb6b9a9a..9f9265569185 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -8,7 +8,6 @@ #include #include #include -#include "target_core_mib.h" #define TARGET_CORE_MOD_VERSION "v4.0.0-rc6" #define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGABRT)) @@ -195,6 +194,21 @@ typedef enum { SAM_TASK_ATTR_EMULATED } t10_task_attr_index_t; +/* + * Used for target SCSI statistics + */ +typedef enum { + SCSI_INST_INDEX, + SCSI_DEVICE_INDEX, + SCSI_AUTH_INTR_INDEX, + SCSI_INDEX_TYPE_MAX +} scsi_index_t; + +struct scsi_index_table { + spinlock_t lock; + u32 scsi_mib_index[SCSI_INDEX_TYPE_MAX]; +} ____cacheline_aligned; + struct se_cmd; struct t10_alua { @@ -578,8 +592,6 @@ struct se_node_acl { spinlock_t stats_lock; /* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */ atomic_t acl_pr_ref_count; - /* Used for MIB access */ - atomic_t mib_ref_count; struct se_dev_entry *device_list; struct se_session *nacl_sess; struct se_portal_group *se_tpg; @@ -595,8 +607,6 @@ struct se_node_acl { } ____cacheline_aligned; struct se_session { - /* Used for MIB access */ - atomic_t mib_ref_count; u64 sess_bin_isid; struct se_node_acl *se_node_acl; struct se_portal_group *se_tpg; @@ -806,7 +816,6 @@ struct se_hba { /* Virtual iSCSI devices attached. */ u32 dev_count; u32 hba_index; - atomic_t dev_mib_access_count; atomic_t load_balance_queue; atomic_t left_queue_depth; /* Maximum queue depth the HBA can handle. */ @@ -845,6 +854,12 @@ struct se_lun { #define SE_LUN(c) ((struct se_lun *)(c)->se_lun) +struct scsi_port_stats { + u64 cmd_pdus; + u64 tx_data_octets; + u64 rx_data_octets; +} ____cacheline_aligned; + struct se_port { /* RELATIVE TARGET PORT IDENTIFER */ u16 sep_rtpi; diff --git a/include/target/target_core_transport.h b/include/target/target_core_transport.h index 66f44e56eb80..246940511579 100644 --- a/include/target/target_core_transport.h +++ b/include/target/target_core_transport.h @@ -111,6 +111,8 @@ struct se_subsystem_api; extern int init_se_global(void); extern void release_se_global(void); +extern void init_scsi_index_table(void); +extern u32 scsi_get_new_index(scsi_index_t); extern void transport_init_queue_obj(struct se_queue_obj *); extern int transport_subsystem_check_init(void); extern int transport_subsystem_register(struct se_subsystem_api *); -- cgit v1.2.3 From 1f6fe7cba1c0a817a8712d7fdd0ec1b4ddd4ea2f Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Wed, 9 Feb 2011 15:34:54 -0800 Subject: [SCSI] target: fix use after free detected by SLUB poison This patch moves a large number of memory release paths inside of the configfs callback target_core_hba_item_ops->release() called from within fs/configfs/item.c: config_item_cleanup() context. This patch resolves the SLUB 'Poison overwritten' warnings. Signed-off-by: Nicholas A. Bellinger Signed-off-by: James Bottomley --- drivers/target/target_core_configfs.c | 120 +++++++++++++++++---------- drivers/target/target_core_fabric_configfs.c | 92 ++++++++++++++------ include/target/target_core_base.h | 1 + 3 files changed, 140 insertions(+), 73 deletions(-) (limited to 'drivers') diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index e77001b16063..caf8dc18ee0a 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -1970,13 +1970,35 @@ static void target_core_dev_release(struct config_item *item) { struct se_subsystem_dev *se_dev = container_of(to_config_group(item), struct se_subsystem_dev, se_dev_group); - struct config_group *dev_cg; - - if (!(se_dev)) - return; + struct se_hba *hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item); + struct se_subsystem_api *t = hba->transport; + struct config_group *dev_cg = &se_dev->se_dev_group; - dev_cg = &se_dev->se_dev_group; kfree(dev_cg->default_groups); + /* + * This pointer will set when the storage is enabled with: + *`echo 1 > $CONFIGFS/core/$HBA/$DEV/dev_enable` + */ + if (se_dev->se_dev_ptr) { + printk(KERN_INFO "Target_Core_ConfigFS: Calling se_free_" + "virtual_device() for se_dev_ptr: %p\n", + se_dev->se_dev_ptr); + + se_free_virtual_device(se_dev->se_dev_ptr, hba); + } else { + /* + * Release struct se_subsystem_dev->se_dev_su_ptr.. + */ + printk(KERN_INFO "Target_Core_ConfigFS: Calling t->free_" + "device() for se_dev_su_ptr: %p\n", + se_dev->se_dev_su_ptr); + + t->free_device(se_dev->se_dev_su_ptr); + } + + printk(KERN_INFO "Target_Core_ConfigFS: Deallocating se_subsystem" + "_dev_t: %p\n", se_dev); + kfree(se_dev); } static ssize_t target_core_dev_show(struct config_item *item, @@ -2139,7 +2161,16 @@ static struct configfs_attribute *target_core_alua_lu_gp_attrs[] = { NULL, }; +static void target_core_alua_lu_gp_release(struct config_item *item) +{ + struct t10_alua_lu_gp *lu_gp = container_of(to_config_group(item), + struct t10_alua_lu_gp, lu_gp_group); + + core_alua_free_lu_gp(lu_gp); +} + static struct configfs_item_operations target_core_alua_lu_gp_ops = { + .release = target_core_alua_lu_gp_release, .show_attribute = target_core_alua_lu_gp_attr_show, .store_attribute = target_core_alua_lu_gp_attr_store, }; @@ -2190,9 +2221,11 @@ static void target_core_alua_drop_lu_gp( printk(KERN_INFO "Target_Core_ConfigFS: Releasing ALUA Logical Unit" " Group: core/alua/lu_gps/%s, ID: %hu\n", config_item_name(item), lu_gp->lu_gp_id); - + /* + * core_alua_free_lu_gp() is called from target_core_alua_lu_gp_ops->release() + * -> target_core_alua_lu_gp_release() + */ config_item_put(item); - core_alua_free_lu_gp(lu_gp); } static struct configfs_group_operations target_core_alua_lu_gps_group_ops = { @@ -2548,7 +2581,16 @@ static struct configfs_attribute *target_core_alua_tg_pt_gp_attrs[] = { NULL, }; +static void target_core_alua_tg_pt_gp_release(struct config_item *item) +{ + struct t10_alua_tg_pt_gp *tg_pt_gp = container_of(to_config_group(item), + struct t10_alua_tg_pt_gp, tg_pt_gp_group); + + core_alua_free_tg_pt_gp(tg_pt_gp); +} + static struct configfs_item_operations target_core_alua_tg_pt_gp_ops = { + .release = target_core_alua_tg_pt_gp_release, .show_attribute = target_core_alua_tg_pt_gp_attr_show, .store_attribute = target_core_alua_tg_pt_gp_attr_store, }; @@ -2601,9 +2643,11 @@ static void target_core_alua_drop_tg_pt_gp( printk(KERN_INFO "Target_Core_ConfigFS: Releasing ALUA Target Port" " Group: alua/tg_pt_gps/%s, ID: %hu\n", config_item_name(item), tg_pt_gp->tg_pt_gp_id); - + /* + * core_alua_free_tg_pt_gp() is called from target_core_alua_tg_pt_gp_ops->release() + * -> target_core_alua_tg_pt_gp_release(). + */ config_item_put(item); - core_alua_free_tg_pt_gp(tg_pt_gp); } static struct configfs_group_operations target_core_alua_tg_pt_gps_group_ops = { @@ -2770,13 +2814,11 @@ static void target_core_drop_subdev( struct se_subsystem_api *t; struct config_item *df_item; struct config_group *dev_cg, *tg_pt_gp_cg; - int i, ret; + int i; hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item); - if (mutex_lock_interruptible(&hba->hba_access_mutex)) - goto out; - + mutex_lock(&hba->hba_access_mutex); t = hba->transport; spin_lock(&se_global->g_device_lock); @@ -2790,7 +2832,10 @@ static void target_core_drop_subdev( config_item_put(df_item); } kfree(tg_pt_gp_cg->default_groups); - core_alua_free_tg_pt_gp(T10_ALUA(se_dev)->default_tg_pt_gp); + /* + * core_alua_free_tg_pt_gp() is called from ->default_tg_pt_gp + * directly from target_core_alua_tg_pt_gp_release(). + */ T10_ALUA(se_dev)->default_tg_pt_gp = NULL; dev_cg = &se_dev->se_dev_group; @@ -2799,38 +2844,12 @@ static void target_core_drop_subdev( dev_cg->default_groups[i] = NULL; config_item_put(df_item); } - - config_item_put(item); /* - * This pointer will set when the storage is enabled with: - * `echo 1 > $CONFIGFS/core/$HBA/$DEV/dev_enable` + * The releasing of se_dev and associated se_dev->se_dev_ptr is done + * from target_core_dev_item_ops->release() ->target_core_dev_release(). */ - if (se_dev->se_dev_ptr) { - printk(KERN_INFO "Target_Core_ConfigFS: Calling se_free_" - "virtual_device() for se_dev_ptr: %p\n", - se_dev->se_dev_ptr); - - ret = se_free_virtual_device(se_dev->se_dev_ptr, hba); - if (ret < 0) - goto hba_out; - } else { - /* - * Release struct se_subsystem_dev->se_dev_su_ptr.. - */ - printk(KERN_INFO "Target_Core_ConfigFS: Calling t->free_" - "device() for se_dev_su_ptr: %p\n", - se_dev->se_dev_su_ptr); - - t->free_device(se_dev->se_dev_su_ptr); - } - - printk(KERN_INFO "Target_Core_ConfigFS: Deallocating se_subsystem" - "_dev_t: %p\n", se_dev); - -hba_out: + config_item_put(item); mutex_unlock(&hba->hba_access_mutex); -out: - kfree(se_dev); } static struct configfs_group_operations target_core_hba_group_ops = { @@ -2913,6 +2932,13 @@ SE_HBA_ATTR(hba_mode, S_IRUGO | S_IWUSR); CONFIGFS_EATTR_OPS(target_core_hba, se_hba, hba_group); +static void target_core_hba_release(struct config_item *item) +{ + struct se_hba *hba = container_of(to_config_group(item), + struct se_hba, hba_group); + core_delete_hba(hba); +} + static struct configfs_attribute *target_core_hba_attrs[] = { &target_core_hba_hba_info.attr, &target_core_hba_hba_mode.attr, @@ -2920,6 +2946,7 @@ static struct configfs_attribute *target_core_hba_attrs[] = { }; static struct configfs_item_operations target_core_hba_item_ops = { + .release = target_core_hba_release, .show_attribute = target_core_hba_attr_show, .store_attribute = target_core_hba_attr_store, }; @@ -2996,10 +3023,11 @@ static void target_core_call_delhbafromtarget( struct config_group *group, struct config_item *item) { - struct se_hba *hba = item_to_hba(item); - + /* + * core_delete_hba() is called from target_core_hba_item_ops->release() + * -> target_core_hba_release() + */ config_item_put(item); - core_delete_hba(hba); } static struct configfs_group_operations target_core_group_ops = { diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index 32b148d7e261..b65d1c8e7740 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c @@ -214,12 +214,22 @@ TCM_MAPPEDLUN_ATTR(write_protect, S_IRUGO | S_IWUSR); CONFIGFS_EATTR_OPS(target_fabric_mappedlun, se_lun_acl, se_lun_group); +static void target_fabric_mappedlun_release(struct config_item *item) +{ + struct se_lun_acl *lacl = container_of(to_config_group(item), + struct se_lun_acl, se_lun_group); + struct se_portal_group *se_tpg = lacl->se_lun_nacl->se_tpg; + + core_dev_free_initiator_node_lun_acl(se_tpg, lacl); +} + static struct configfs_attribute *target_fabric_mappedlun_attrs[] = { &target_fabric_mappedlun_write_protect.attr, NULL, }; static struct configfs_item_operations target_fabric_mappedlun_item_ops = { + .release = target_fabric_mappedlun_release, .show_attribute = target_fabric_mappedlun_attr_show, .store_attribute = target_fabric_mappedlun_attr_store, .allow_link = target_fabric_mappedlun_link, @@ -337,15 +347,21 @@ static void target_fabric_drop_mappedlun( struct config_group *group, struct config_item *item) { - struct se_lun_acl *lacl = container_of(to_config_group(item), - struct se_lun_acl, se_lun_group); - struct se_portal_group *se_tpg = lacl->se_lun_nacl->se_tpg; - config_item_put(item); - core_dev_free_initiator_node_lun_acl(se_tpg, lacl); +} + +static void target_fabric_nacl_base_release(struct config_item *item) +{ + struct se_node_acl *se_nacl = container_of(to_config_group(item), + struct se_node_acl, acl_group); + struct se_portal_group *se_tpg = se_nacl->se_tpg; + struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf; + + tf->tf_ops.fabric_drop_nodeacl(se_nacl); } static struct configfs_item_operations target_fabric_nacl_base_item_ops = { + .release = target_fabric_nacl_base_release, .show_attribute = target_fabric_nacl_base_attr_show, .store_attribute = target_fabric_nacl_base_attr_store, }; @@ -404,9 +420,6 @@ static void target_fabric_drop_nodeacl( struct config_group *group, struct config_item *item) { - struct se_portal_group *se_tpg = container_of(group, - struct se_portal_group, tpg_acl_group); - struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf; struct se_node_acl *se_nacl = container_of(to_config_group(item), struct se_node_acl, acl_group); struct config_item *df_item; @@ -419,9 +432,10 @@ static void target_fabric_drop_nodeacl( nacl_cg->default_groups[i] = NULL; config_item_put(df_item); } - + /* + * struct se_node_acl free is done in target_fabric_nacl_base_release() + */ config_item_put(item); - tf->tf_ops.fabric_drop_nodeacl(se_nacl); } static struct configfs_group_operations target_fabric_nacl_group_ops = { @@ -437,7 +451,18 @@ TF_CIT_SETUP(tpg_nacl, NULL, &target_fabric_nacl_group_ops, NULL); CONFIGFS_EATTR_OPS(target_fabric_np_base, se_tpg_np, tpg_np_group); +static void target_fabric_np_base_release(struct config_item *item) +{ + struct se_tpg_np *se_tpg_np = container_of(to_config_group(item), + struct se_tpg_np, tpg_np_group); + struct se_portal_group *se_tpg = se_tpg_np->tpg_np_parent; + struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf; + + tf->tf_ops.fabric_drop_np(se_tpg_np); +} + static struct configfs_item_operations target_fabric_np_base_item_ops = { + .release = target_fabric_np_base_release, .show_attribute = target_fabric_np_base_attr_show, .store_attribute = target_fabric_np_base_attr_store, }; @@ -466,6 +491,7 @@ static struct config_group *target_fabric_make_np( if (!(se_tpg_np) || IS_ERR(se_tpg_np)) return ERR_PTR(-EINVAL); + se_tpg_np->tpg_np_parent = se_tpg; config_group_init_type_name(&se_tpg_np->tpg_np_group, name, &TF_CIT_TMPL(tf)->tfc_tpg_np_base_cit); @@ -476,14 +502,10 @@ static void target_fabric_drop_np( struct config_group *group, struct config_item *item) { - struct se_portal_group *se_tpg = container_of(group, - struct se_portal_group, tpg_np_group); - struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf; - struct se_tpg_np *se_tpg_np = container_of(to_config_group(item), - struct se_tpg_np, tpg_np_group); - + /* + * struct se_tpg_np is released via target_fabric_np_base_release() + */ config_item_put(item); - tf->tf_ops.fabric_drop_np(se_tpg_np); } static struct configfs_group_operations target_fabric_np_group_ops = { @@ -814,7 +836,18 @@ TF_CIT_SETUP(tpg_param, &target_fabric_tpg_param_item_ops, NULL, NULL); */ CONFIGFS_EATTR_OPS(target_fabric_tpg, se_portal_group, tpg_group); +static void target_fabric_tpg_release(struct config_item *item) +{ + struct se_portal_group *se_tpg = container_of(to_config_group(item), + struct se_portal_group, tpg_group); + struct se_wwn *wwn = se_tpg->se_tpg_wwn; + struct target_fabric_configfs *tf = wwn->wwn_tf; + + tf->tf_ops.fabric_drop_tpg(se_tpg); +} + static struct configfs_item_operations target_fabric_tpg_base_item_ops = { + .release = target_fabric_tpg_release, .show_attribute = target_fabric_tpg_attr_show, .store_attribute = target_fabric_tpg_attr_store, }; @@ -872,8 +905,6 @@ static void target_fabric_drop_tpg( struct config_group *group, struct config_item *item) { - struct se_wwn *wwn = container_of(group, struct se_wwn, wwn_group); - struct target_fabric_configfs *tf = wwn->wwn_tf; struct se_portal_group *se_tpg = container_of(to_config_group(item), struct se_portal_group, tpg_group); struct config_group *tpg_cg = &se_tpg->tpg_group; @@ -890,15 +921,28 @@ static void target_fabric_drop_tpg( } config_item_put(item); - tf->tf_ops.fabric_drop_tpg(se_tpg); } +static void target_fabric_release_wwn(struct config_item *item) +{ + struct se_wwn *wwn = container_of(to_config_group(item), + struct se_wwn, wwn_group); + struct target_fabric_configfs *tf = wwn->wwn_tf; + + tf->tf_ops.fabric_drop_wwn(wwn); +} + +static struct configfs_item_operations target_fabric_tpg_item_ops = { + .release = target_fabric_release_wwn, +}; + static struct configfs_group_operations target_fabric_tpg_group_ops = { .make_group = target_fabric_make_tpg, .drop_item = target_fabric_drop_tpg, }; -TF_CIT_SETUP(tpg, NULL, &target_fabric_tpg_group_ops, NULL); +TF_CIT_SETUP(tpg, &target_fabric_tpg_item_ops, &target_fabric_tpg_group_ops, + NULL); /* End of tfc_tpg_cit */ @@ -932,13 +976,7 @@ static void target_fabric_drop_wwn( struct config_group *group, struct config_item *item) { - struct target_fabric_configfs *tf = container_of(group, - struct target_fabric_configfs, tf_group); - struct se_wwn *wwn = container_of(to_config_group(item), - struct se_wwn, wwn_group); - config_item_put(item); - tf->tf_ops.fabric_drop_wwn(wwn); } static struct configfs_group_operations target_fabric_wwn_group_ops = { diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 9f9265569185..0828b6c8610a 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -882,6 +882,7 @@ struct se_port { } ____cacheline_aligned; struct se_tpg_np { + struct se_portal_group *tpg_np_parent; struct config_group tpg_np_group; } ____cacheline_aligned; -- cgit v1.2.3 From 84857c8bf83e8aa87afc57d2956ba01f11d82386 Mon Sep 17 00:00:00 2001 From: "Kashyap, Desai" Date: Thu, 10 Feb 2011 11:52:21 +0530 Subject: [SCSI] mptfusion: mptctl_release is required in mptctl.c Added missing release callback for file_operations mptctl_fops. Without release callback there will be never freed. It remains on mptctl's eent list even after the file is closed and released. Relavent RHEL bugzilla is 660871 Cc: stable@kernel.org Signed-off-by: Kashyap Desai Signed-off-by: James Bottomley --- drivers/message/fusion/mptctl.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index a3856ed90aef..e8deb8ed0499 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -596,6 +596,13 @@ mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) return 1; } +static int +mptctl_release(struct inode *inode, struct file *filep) +{ + fasync_helper(-1, filep, 0, &async_queue); + return 0; +} + static int mptctl_fasync(int fd, struct file *filep, int mode) { @@ -2815,6 +2822,7 @@ static const struct file_operations mptctl_fops = { .llseek = no_llseek, .fasync = mptctl_fasync, .unlocked_ioctl = mptctl_ioctl, + .release = mptctl_release, #ifdef CONFIG_COMPAT .compat_ioctl = compat_mpctl_ioctl, #endif -- cgit v1.2.3 From bcfe42e98047f1935c5571c8ea77beb2d43ec19d Mon Sep 17 00:00:00 2001 From: "Kashyap, Desai" Date: Thu, 10 Feb 2011 11:53:44 +0530 Subject: [SCSI] mptfusion: Fix Incorrect return value in mptscsih_dev_reset There's a branch at the end of this function that is supposed to normalize the return value with what the mid-layer expects. In this one case, we get it wrong. Also increase the verbosity of the INFO level printk at the end of mptscsih_abort to include the actual return value and the scmd->serial_number. The reason being success or failure is actually determined by the state of the internal tag list when a TMF is issued, and not the return value of the TMF cmd. The serial_number is also used in this decision, thus it's useful to know for debugging purposes. Cc: stable@kernel.org Reported-by: Peter M. Petrakis Signed-off-by: Kashyap Desai Signed-off-by: James Bottomley --- drivers/message/fusion/mptscsih.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 59b8f53d1ece..0d9b82a44540 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -1873,8 +1873,9 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) } out: - printk(MYIOC_s_INFO_FMT "task abort: %s (sc=%p)\n", - ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), SCpnt); + printk(MYIOC_s_INFO_FMT "task abort: %s (rv=%04x) (sc=%p) (sn=%ld)\n", + ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), retval, + SCpnt, SCpnt->serial_number); return retval; } @@ -1911,7 +1912,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) vdevice = SCpnt->device->hostdata; if (!vdevice || !vdevice->vtarget) { - retval = SUCCESS; + retval = 0; goto out; } -- cgit v1.2.3 From d2b2147678a8be0144d64ec4feb759e7560eb9af Mon Sep 17 00:00:00 2001 From: "Kashyap, Desai" Date: Thu, 10 Feb 2011 11:54:29 +0530 Subject: [SCSI] mptfusion: Bump version 03.04.18 Signed-off-by: Kashyap Desai Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index f71f22948477..1735c84ff757 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -76,8 +76,8 @@ #define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR #endif -#define MPT_LINUX_VERSION_COMMON "3.04.17" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.17" +#define MPT_LINUX_VERSION_COMMON "3.04.18" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.18" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ -- cgit v1.2.3 From 1765a575334f1a232c1478accdee5c7d19f4b3e3 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Sat, 12 Feb 2011 06:48:36 +0000 Subject: net: make dev->master general dev->master is now tightly connected to bonding driver. This patch makes this pointer more general and ready to be used by others. - netdev_set_master() - bond specifics moved to new function netdev_set_bond_master() - introduced netif_is_bond_slave() to check if device is a bonding slave Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/infiniband/hw/nes/nes.c | 3 ++- drivers/infiniband/hw/nes/nes_cm.c | 2 +- drivers/net/bonding/bond_main.c | 10 ++++---- drivers/net/cxgb3/cxgb3_offload.c | 3 ++- include/linux/netdevice.h | 7 ++++++ net/core/dev.c | 49 ++++++++++++++++++++++++++++---------- 6 files changed, 54 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index 3b4ec3238ceb..3d7f3664b67b 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c @@ -153,7 +153,8 @@ static int nes_inetaddr_event(struct notifier_block *notifier, nesdev, nesdev->netdev[0]->name); netdev = nesdev->netdev[0]; nesvnic = netdev_priv(netdev); - is_bonded = (netdev->master == event_netdev); + is_bonded = netif_is_bond_slave(netdev) && + (netdev->master == event_netdev); if ((netdev == event_netdev) || is_bonded) { if (nesvnic->rdma_enabled == 0) { nes_debug(NES_DBG_NETDEV, "Returning without processing event for %s since" diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 009ec814d517..ec3aa11c36cb 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -1118,7 +1118,7 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi return rc; } - if (nesvnic->netdev->master) + if (netif_is_bond_slave(netdev)) netdev = nesvnic->netdev->master; else netdev = nesvnic->netdev; diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 1df9f0ea9184..9f877878d636 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1594,9 +1594,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) } } - res = netdev_set_master(slave_dev, bond_dev); + res = netdev_set_bond_master(slave_dev, bond_dev); if (res) { - pr_debug("Error %d calling netdev_set_master\n", res); + pr_debug("Error %d calling netdev_set_bond_master\n", res); goto err_restore_mac; } /* open the slave since the application closed it */ @@ -1812,7 +1812,7 @@ err_close: dev_close(slave_dev); err_unset_master: - netdev_set_master(slave_dev, NULL); + netdev_set_bond_master(slave_dev, NULL); err_restore_mac: if (!bond->params.fail_over_mac) { @@ -1992,7 +1992,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) netif_addr_unlock_bh(bond_dev); } - netdev_set_master(slave_dev, NULL); + netdev_set_bond_master(slave_dev, NULL); #ifdef CONFIG_NET_POLL_CONTROLLER read_lock_bh(&bond->lock); @@ -2114,7 +2114,7 @@ static int bond_release_all(struct net_device *bond_dev) netif_addr_unlock_bh(bond_dev); } - netdev_set_master(slave_dev, NULL); + netdev_set_bond_master(slave_dev, NULL); /* close slave before restoring its mac address */ dev_close(slave_dev); diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index 7ea94b5205f8..862804f32b6e 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c @@ -186,9 +186,10 @@ static struct net_device *get_iff_from_mac(struct adapter *adapter, dev = NULL; if (grp) dev = vlan_group_get_device(grp, vlan); - } else + } else if (netif_is_bond_slave(dev)) { while (dev->master) dev = dev->master; + } return dev; } } diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 5a5baeaaa50f..5a42b1003767 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2377,6 +2377,8 @@ extern int netdev_max_backlog; extern int netdev_tstamp_prequeue; extern int weight_p; extern int netdev_set_master(struct net_device *dev, struct net_device *master); +extern int netdev_set_bond_master(struct net_device *dev, + struct net_device *master); extern int skb_checksum_help(struct sk_buff *skb); extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, u32 features); #ifdef CONFIG_BUG @@ -2437,6 +2439,11 @@ static inline void netif_set_gso_max_size(struct net_device *dev, dev->gso_max_size = size; } +static inline int netif_is_bond_slave(struct net_device *dev) +{ + return dev->flags & IFF_SLAVE && dev->priv_flags & IFF_BONDING; +} + extern struct pernet_operations __net_initdata loopback_net_ops; static inline int dev_ethtool_get_settings(struct net_device *dev, diff --git a/net/core/dev.c b/net/core/dev.c index d874fd1baf49..a4132766d363 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3146,7 +3146,6 @@ static int __netif_receive_skb(struct sk_buff *skb) struct packet_type *ptype, *pt_prev; rx_handler_func_t *rx_handler; struct net_device *orig_dev; - struct net_device *master; struct net_device *null_or_orig; struct net_device *orig_or_bond; int ret = NET_RX_DROP; @@ -3173,15 +3172,19 @@ static int __netif_receive_skb(struct sk_buff *skb) */ null_or_orig = NULL; orig_dev = skb->dev; - master = ACCESS_ONCE(orig_dev->master); if (skb->deliver_no_wcard) null_or_orig = orig_dev; - else if (master) { - if (__skb_bond_should_drop(skb, master)) { - skb->deliver_no_wcard = 1; - null_or_orig = orig_dev; /* deliver only exact match */ - } else - skb->dev = master; + else if (netif_is_bond_slave(orig_dev)) { + struct net_device *bond_master = ACCESS_ONCE(orig_dev->master); + + if (likely(bond_master)) { + if (__skb_bond_should_drop(skb, bond_master)) { + skb->deliver_no_wcard = 1; + /* deliver only exact match */ + null_or_orig = orig_dev; + } else + skb->dev = bond_master; + } } __this_cpu_inc(softnet_data.processed); @@ -4346,15 +4349,14 @@ static int __init dev_proc_init(void) /** - * netdev_set_master - set up master/slave pair + * netdev_set_master - set up master pointer * @slave: slave device * @master: new master device * * Changes the master device of the slave. Pass %NULL to break the * bonding. The caller must hold the RTNL semaphore. On a failure * a negative errno code is returned. On success the reference counts - * are adjusted, %RTM_NEWLINK is sent to the routing socket and the - * function returns zero. + * are adjusted and the function returns zero. */ int netdev_set_master(struct net_device *slave, struct net_device *master) { @@ -4374,6 +4376,29 @@ int netdev_set_master(struct net_device *slave, struct net_device *master) synchronize_net(); dev_put(old); } + return 0; +} +EXPORT_SYMBOL(netdev_set_master); + +/** + * netdev_set_bond_master - set up bonding master/slave pair + * @slave: slave device + * @master: new master device + * + * Changes the master device of the slave. Pass %NULL to break the + * bonding. The caller must hold the RTNL semaphore. On a failure + * a negative errno code is returned. On success %RTM_NEWLINK is sent + * to the routing socket and the function returns zero. + */ +int netdev_set_bond_master(struct net_device *slave, struct net_device *master) +{ + int err; + + ASSERT_RTNL(); + + err = netdev_set_master(slave, master); + if (err) + return err; if (master) slave->flags |= IFF_SLAVE; else @@ -4382,7 +4407,7 @@ int netdev_set_master(struct net_device *slave, struct net_device *master) rtmsg_ifinfo(RTM_NEWLINK, slave, IFF_SLAVE); return 0; } -EXPORT_SYMBOL(netdev_set_master); +EXPORT_SYMBOL(netdev_set_bond_master); static void dev_change_rx_flags(struct net_device *dev, int flags) { -- cgit v1.2.3 From f45437efff460aa033978180da88229c5fc68455 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 9 Feb 2011 10:25:06 +0000 Subject: tlan: Fix bugs introduced by the last tlan cleanup patch Fix two bugs introduced by the commit c659c38b2796578638548b77ef626d93609ec8ac ("tlan: Code cleanup: checkpatch.pl is relatively happy now.") In that change, TLAN_CSTAT_READY was considered as a bit mask containing a single bit set while it was actually had two set instead. Many thanks to Dan Carpenter for finding the mistake. Signed-off-by: Sakari Ailus Signed-off-by: David S. Miller --- drivers/net/tlan.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index 0678e7e71f19..e48a80885343 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -1522,7 +1522,8 @@ static u32 tlan_handle_tx_eof(struct net_device *dev, u16 host_int) head_list = priv->tx_list + priv->tx_head; head_list_phys = priv->tx_list_dma + sizeof(struct tlan_list)*priv->tx_head; - if (head_list->c_stat & TLAN_CSTAT_READY) { + if ((head_list->c_stat & TLAN_CSTAT_READY) + == TLAN_CSTAT_READY) { outl(head_list_phys, dev->base_addr + TLAN_CH_PARM); ack |= TLAN_HC_GO; } else { @@ -1766,7 +1767,8 @@ static u32 tlan_handle_tx_eoc(struct net_device *dev, u16 host_int) head_list = priv->tx_list + priv->tx_head; head_list_phys = priv->tx_list_dma + sizeof(struct tlan_list)*priv->tx_head; - if (head_list->c_stat & TLAN_CSTAT_READY) { + if ((head_list->c_stat & TLAN_CSTAT_READY) + == TLAN_CSTAT_READY) { netif_stop_queue(dev); outl(head_list_phys, dev->base_addr + TLAN_CH_PARM); ack |= TLAN_HC_GO; -- cgit v1.2.3 From ab60707ffe9920b66b4fff5181b44b14cd091472 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 10 Feb 2011 10:58:45 +0000 Subject: USB Network driver infrastructure: Fix leak when usb_autopm_get_interface() returns less than zero in kevent(). We'll leak the memory allocated to 'urb' in drivers/net/usb/usbnet.c:kevent() when we 'goto fail_lowmem' and the 'urb' variable goes out of scope while still completely unused. Signed-off-by: Jesper Juhl Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index ed9a41643ff4..95c41d56631c 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -931,8 +931,10 @@ fail_halt: if (urb != NULL) { clear_bit (EVENT_RX_MEMORY, &dev->flags); status = usb_autopm_get_interface(dev->intf); - if (status < 0) + if (status < 0) { + usb_free_urb(urb); goto fail_lowmem; + } if (rx_submit (dev, urb, GFP_KERNEL) == -ENOLINK) resched = 0; usb_autopm_put_interface(dev->intf); -- cgit v1.2.3 From f7bee80945155ad0326916486dabc38428c6cdef Mon Sep 17 00:00:00 2001 From: Krzysztof Wojcik Date: Mon, 14 Feb 2011 10:01:41 +1100 Subject: md: Fix raid1->raid0 takeover Takeover raid1->raid0 not succeded. Kernel message is shown: "md/raid0:md126: too few disks (1 of 2) - aborting!" Problem was that we weren't updating ->raid_disks for that takeover, unlike all the others. Signed-off-by: Krzysztof Wojcik Signed-off-by: NeilBrown --- drivers/md/raid0.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 637a96855edb..75671dfee551 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -670,6 +670,7 @@ static void *raid0_takeover_raid1(mddev_t *mddev) mddev->new_layout = 0; mddev->new_chunk_sectors = 128; /* by default set chunk size to 64k */ mddev->delta_disks = 1 - mddev->raid_disks; + mddev->raid_disks = 1; /* make sure it will be not marked as dirty */ mddev->recovery_cp = MaxSector; -- cgit v1.2.3 From 16f9fdcbcce74102bed9a4b7ccc1fb05b5dd6ca3 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 7 Feb 2011 12:00:51 +1000 Subject: drm/radeon: fix memory debugging since d961db75ce86a84f1f04e91ad1014653ed7d9f46 The old code dereferenced a value, the new code just needs to pass the ptr. fixes an oops looking at files in debugfs. cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_ttm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 1272e4b6a1d4..e5b2cf10cbf4 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -787,9 +787,9 @@ static int radeon_ttm_debugfs_init(struct radeon_device *rdev) radeon_mem_types_list[i].show = &radeon_mm_dump_table; radeon_mem_types_list[i].driver_features = 0; if (i == 0) - radeon_mem_types_list[i].data = &rdev->mman.bdev.man[TTM_PL_VRAM].priv; + radeon_mem_types_list[i].data = rdev->mman.bdev.man[TTM_PL_VRAM].priv; else - radeon_mem_types_list[i].data = &rdev->mman.bdev.man[TTM_PL_TT].priv; + radeon_mem_types_list[i].data = rdev->mman.bdev.man[TTM_PL_TT].priv; } /* Add ttm page pool to debugfs */ -- cgit v1.2.3 From c9417bdd4c6b1b92a21608c07e83afa419c7bb62 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sun, 6 Feb 2011 14:23:26 -0500 Subject: drm/radeon/kms: fix interlaced modes on dce4+ - set scaler table clears the interleave bit, need to reset it in encoder quirks, this was already done for pre-dce4. - remove the interleave settings from set_base() functions this is now handled in the encoder quirks functions, and isn't technically part of the display base setup. - rename evergreen_do_set_base() to dce4_do_set_base() since it's used on both evergreen and NI asics. Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=28182 Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atombios_crtc.c | 22 +++++----------------- drivers/gpu/drm/radeon/radeon_encoders.c | 20 +++++++++++++++----- 2 files changed, 20 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index b1537000a104..dd4e3acf79c0 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -995,9 +995,9 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode } } -static int evergreen_crtc_do_set_base(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y, int atomic) +static int dce4_crtc_do_set_base(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + int x, int y, int atomic) { struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; @@ -1137,12 +1137,6 @@ static int evergreen_crtc_do_set_base(struct drm_crtc *crtc, WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset, (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); - if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) - WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, - EVERGREEN_INTERLEAVE_EN); - else - WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0); - if (!atomic && fb && fb != crtc->fb) { radeon_fb = to_radeon_framebuffer(fb); rbo = radeon_fb->obj->driver_private; @@ -1300,12 +1294,6 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); - if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) - WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, - AVIVO_D1MODE_INTERLEAVE_EN); - else - WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); - if (!atomic && fb && fb != crtc->fb) { radeon_fb = to_radeon_framebuffer(fb); rbo = radeon_fb->obj->driver_private; @@ -1329,7 +1317,7 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, struct radeon_device *rdev = dev->dev_private; if (ASIC_IS_DCE4(rdev)) - return evergreen_crtc_do_set_base(crtc, old_fb, x, y, 0); + return dce4_crtc_do_set_base(crtc, old_fb, x, y, 0); else if (ASIC_IS_AVIVO(rdev)) return avivo_crtc_do_set_base(crtc, old_fb, x, y, 0); else @@ -1344,7 +1332,7 @@ int atombios_crtc_set_base_atomic(struct drm_crtc *crtc, struct radeon_device *rdev = dev->dev_private; if (ASIC_IS_DCE4(rdev)) - return evergreen_crtc_do_set_base(crtc, fb, x, y, 1); + return dce4_crtc_do_set_base(crtc, fb, x, y, 1); else if (ASIC_IS_AVIVO(rdev)) return avivo_crtc_do_set_base(crtc, fb, x, y, 1); else diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index d4a542247618..5b38b73ccd12 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -1570,11 +1570,21 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder, } /* set scaler clears this on some chips */ - /* XXX check DCE4 */ - if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) { - if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE)) - WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, - AVIVO_D1MODE_INTERLEAVE_EN); + if (ASIC_IS_AVIVO(rdev) && + (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)))) { + if (ASIC_IS_DCE4(rdev)) { + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, + EVERGREEN_INTERLEAVE_EN); + else + WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0); + } else { + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, + AVIVO_D1MODE_INTERLEAVE_EN); + else + WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); + } } } -- cgit v1.2.3 From e917fd39eb35e5b2c464e67a80e759f3eb468e48 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sat, 5 Feb 2011 20:51:53 +0100 Subject: radeon mkregtable: Add missing fclose() calls drivers/gpu/drm/radeon/mkregtable.c:parser_auth() almost always remembers to fclose(file) before returning, but it misses two spots. This is not really important since the process will exit shortly after and thus close the file for us, but being explicit prevents static analysis tools from complaining about leaked memory and missing fclose() calls and it also seems to be the prefered style of the existing code to explicitly close the file. So, here's a patch to add the two missing fclose() calls. Signed-off-by: Jesper Juhl Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/mkregtable.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/mkregtable.c b/drivers/gpu/drm/radeon/mkregtable.c index 607241c6a8a9..5a82b6b75849 100644 --- a/drivers/gpu/drm/radeon/mkregtable.c +++ b/drivers/gpu/drm/radeon/mkregtable.c @@ -673,8 +673,10 @@ static int parser_auth(struct table *t, const char *filename) last_reg = strtol(last_reg_s, NULL, 16); do { - if (fgets(buf, 1024, file) == NULL) + if (fgets(buf, 1024, file) == NULL) { + fclose(file); return -1; + } len = strlen(buf); if (ftell(file) == end) done = 1; @@ -685,6 +687,7 @@ static int parser_auth(struct table *t, const char *filename) fprintf(stderr, "Error matching regular expression %d in %s\n", r, filename); + fclose(file); return -1; } else { buf[match[0].rm_eo] = 0; -- cgit v1.2.3 From 9fad321ac6bedd96f449754a1a25289ea1789a49 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 7 Feb 2011 13:15:28 -0500 Subject: drm/radeon/kms: add connector table for mac g5 9600 PPC Mac cards do not provide connector tables in their vbios. Their connector/encoder configurations must be hardcoded in the driver. verified by nyef on #radeon Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_combios.c | 47 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_mode.h | 1 + 2 files changed, 48 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index d27ef74590cd..cf7c8d5b4ec2 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -1504,6 +1504,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) (rdev->pdev->subsystem_device == 0x4a48)) { /* Mac X800 */ rdev->mode_info.connector_table = CT_MAC_X800; + } else if ((rdev->pdev->device == 0x4150) && + (rdev->pdev->subsystem_vendor == 0x1002) && + (rdev->pdev->subsystem_device == 0x4150)) { + /* Mac G5 9600 */ + rdev->mode_info.connector_table = CT_MAC_G5_9600; } else #endif /* CONFIG_PPC_PMAC */ #ifdef CONFIG_PPC64 @@ -2022,6 +2027,48 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, &hpd); break; + case CT_MAC_G5_9600: + DRM_INFO("Connector Table: %d (mac g5 9600)\n", + rdev->mode_info.connector_table); + /* DVI - tv dac, dvo */ + ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); + hpd.hpd = RADEON_HPD_1; /* ??? */ + radeon_add_legacy_encoder(dev, + radeon_get_encoder_enum(dev, + ATOM_DEVICE_DFP2_SUPPORT, + 0), + ATOM_DEVICE_DFP2_SUPPORT); + radeon_add_legacy_encoder(dev, + radeon_get_encoder_enum(dev, + ATOM_DEVICE_CRT2_SUPPORT, + 2), + ATOM_DEVICE_CRT2_SUPPORT); + radeon_add_legacy_connector(dev, 0, + ATOM_DEVICE_DFP2_SUPPORT | + ATOM_DEVICE_CRT2_SUPPORT, + DRM_MODE_CONNECTOR_DVII, &ddc_i2c, + CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, + &hpd); + /* ADC - primary dac, internal tmds */ + ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); + hpd.hpd = RADEON_HPD_2; /* ??? */ + radeon_add_legacy_encoder(dev, + radeon_get_encoder_enum(dev, + ATOM_DEVICE_DFP1_SUPPORT, + 0), + ATOM_DEVICE_DFP1_SUPPORT); + radeon_add_legacy_encoder(dev, + radeon_get_encoder_enum(dev, + ATOM_DEVICE_CRT1_SUPPORT, + 1), + ATOM_DEVICE_CRT1_SUPPORT); + radeon_add_legacy_connector(dev, 1, + ATOM_DEVICE_DFP1_SUPPORT | + ATOM_DEVICE_CRT1_SUPPORT, + DRM_MODE_CONNECTOR_DVII, &ddc_i2c, + CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, + &hpd); + break; default: DRM_INFO("Connector table: %d (invalid)\n", rdev->mode_info.connector_table); diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 6794cdf91f28..a670caaee29e 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -209,6 +209,7 @@ enum radeon_connector_table { CT_EMAC, CT_RN50_POWER, CT_MAC_X800, + CT_MAC_G5_9600, }; enum radeon_dvo_chip { -- cgit v1.2.3 From 01e2f533a234dc62d16c0d3d4fb9d71cf1ce50c3 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 11 Feb 2011 19:29:44 -0800 Subject: drm: do not leak kernel addresses via /proc/dri/*/vma In the continuing effort to avoid kernel addresses leaking to unprivileged users, this patch switches to %pK for /proc/dri/*/vma. Signed-off-by: Kees Cook Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_info.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c index 3cdbaf379bb5..be9a9c07d152 100644 --- a/drivers/gpu/drm/drm_info.c +++ b/drivers/gpu/drm/drm_info.c @@ -283,17 +283,18 @@ int drm_vma_info(struct seq_file *m, void *data) #endif mutex_lock(&dev->struct_mutex); - seq_printf(m, "vma use count: %d, high_memory = %p, 0x%08llx\n", + seq_printf(m, "vma use count: %d, high_memory = %pK, 0x%pK\n", atomic_read(&dev->vma_count), - high_memory, (u64)virt_to_phys(high_memory)); + high_memory, (void *)virt_to_phys(high_memory)); list_for_each_entry(pt, &dev->vmalist, head) { vma = pt->vma; if (!vma) continue; seq_printf(m, - "\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000", - pt->pid, vma->vm_start, vma->vm_end, + "\n%5d 0x%pK-0x%pK %c%c%c%c%c%c 0x%08lx000", + pt->pid, + (void *)vma->vm_start, (void *)vma->vm_end, vma->vm_flags & VM_READ ? 'r' : '-', vma->vm_flags & VM_WRITE ? 'w' : '-', vma->vm_flags & VM_EXEC ? 'x' : '-', -- cgit v1.2.3 From 40b4a7599d5555b408e594f4c8dae8015ccaae8f Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 12 Feb 2011 19:21:35 +0100 Subject: drm/radeon/kms: optimize CS state checking for r100->r500 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The colorbuffer, zbuffer, and texture states are checked only once when they get changed. This improves performance in the apps which emit lots of draw packets and few state changes. This drops performance in glxgears by a 1% or so, but glxgears is not a benchmark we care about. The time spent in the kernel when running Torcs dropped from 33% to 23% and the frame rate is higher, which is a good thing. r600 might need something like this as well. Signed-off-by: Marek Olšák Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r100.c | 40 +++++++++++++++++++++++++++++++++---- drivers/gpu/drm/radeon/r100_track.h | 11 ++++------ drivers/gpu/drm/radeon/r200.c | 18 +++++++++++++++++ drivers/gpu/drm/radeon/r300.c | 20 ++++++++++++++++++- 4 files changed, 77 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 5f15820efe12..fdf4bc67ae58 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -1427,6 +1427,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, } track->zb.robj = reloc->robj; track->zb.offset = idx_value; + track->zb_dirty = true; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); break; case RADEON_RB3D_COLOROFFSET: @@ -1439,6 +1440,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, } track->cb[0].robj = reloc->robj; track->cb[0].offset = idx_value; + track->cb_dirty = true; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); break; case RADEON_PP_TXOFFSET_0: @@ -1454,6 +1456,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, } ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); track->textures[i].robj = reloc->robj; + track->tex_dirty = true; break; case RADEON_PP_CUBIC_OFFSET_T0_0: case RADEON_PP_CUBIC_OFFSET_T0_1: @@ -1471,6 +1474,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, track->textures[0].cube_info[i].offset = idx_value; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); track->textures[0].cube_info[i].robj = reloc->robj; + track->tex_dirty = true; break; case RADEON_PP_CUBIC_OFFSET_T1_0: case RADEON_PP_CUBIC_OFFSET_T1_1: @@ -1488,6 +1492,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, track->textures[1].cube_info[i].offset = idx_value; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); track->textures[1].cube_info[i].robj = reloc->robj; + track->tex_dirty = true; break; case RADEON_PP_CUBIC_OFFSET_T2_0: case RADEON_PP_CUBIC_OFFSET_T2_1: @@ -1505,9 +1510,12 @@ static int r100_packet0_check(struct radeon_cs_parser *p, track->textures[2].cube_info[i].offset = idx_value; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); track->textures[2].cube_info[i].robj = reloc->robj; + track->tex_dirty = true; break; case RADEON_RE_WIDTH_HEIGHT: track->maxy = ((idx_value >> 16) & 0x7FF); + track->cb_dirty = true; + track->zb_dirty = true; break; case RADEON_RB3D_COLORPITCH: r = r100_cs_packet_next_reloc(p, &reloc); @@ -1528,9 +1536,11 @@ static int r100_packet0_check(struct radeon_cs_parser *p, ib[idx] = tmp; track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; + track->cb_dirty = true; break; case RADEON_RB3D_DEPTHPITCH: track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; + track->zb_dirty = true; break; case RADEON_RB3D_CNTL: switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { @@ -1555,6 +1565,8 @@ static int r100_packet0_check(struct radeon_cs_parser *p, return -EINVAL; } track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); + track->cb_dirty = true; + track->zb_dirty = true; break; case RADEON_RB3D_ZSTENCILCNTL: switch (idx_value & 0xf) { @@ -1572,6 +1584,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, default: break; } + track->zb_dirty = true; break; case RADEON_RB3D_ZPASS_ADDR: r = r100_cs_packet_next_reloc(p, &reloc); @@ -1588,6 +1601,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, uint32_t temp = idx_value >> 4; for (i = 0; i < track->num_texture; i++) track->textures[i].enabled = !!(temp & (1 << i)); + track->tex_dirty = true; } break; case RADEON_SE_VF_CNTL: @@ -1602,12 +1616,14 @@ static int r100_packet0_check(struct radeon_cs_parser *p, i = (reg - RADEON_PP_TEX_SIZE_0) / 8; track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; + track->tex_dirty = true; break; case RADEON_PP_TEX_PITCH_0: case RADEON_PP_TEX_PITCH_1: case RADEON_PP_TEX_PITCH_2: i = (reg - RADEON_PP_TEX_PITCH_0) / 8; track->textures[i].pitch = idx_value + 32; + track->tex_dirty = true; break; case RADEON_PP_TXFILTER_0: case RADEON_PP_TXFILTER_1: @@ -1621,6 +1637,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, tmp = (idx_value >> 27) & 0x7; if (tmp == 2 || tmp == 6) track->textures[i].roundup_h = false; + track->tex_dirty = true; break; case RADEON_PP_TXFORMAT_0: case RADEON_PP_TXFORMAT_1: @@ -1673,6 +1690,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, } track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); + track->tex_dirty = true; break; case RADEON_PP_CUBIC_FACES_0: case RADEON_PP_CUBIC_FACES_1: @@ -1683,6 +1701,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); } + track->tex_dirty = true; break; default: printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", @@ -3318,9 +3337,9 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) unsigned long size; unsigned prim_walk; unsigned nverts; - unsigned num_cb = track->num_cb; + unsigned num_cb = track->cb_dirty ? track->num_cb : 0; - if (!track->zb_cb_clear && !track->color_channel_mask && + if (num_cb && !track->zb_cb_clear && !track->color_channel_mask && !track->blend_read_enable) num_cb = 0; @@ -3341,7 +3360,9 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) return -EINVAL; } } - if (track->z_enabled) { + track->cb_dirty = false; + + if (track->zb_dirty && track->z_enabled) { if (track->zb.robj == NULL) { DRM_ERROR("[drm] No buffer for z buffer !\n"); return -EINVAL; @@ -3358,6 +3379,8 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) return -EINVAL; } } + track->zb_dirty = false; + prim_walk = (track->vap_vf_cntl >> 4) & 0x3; if (track->vap_vf_cntl & (1 << 14)) { nverts = track->vap_alt_nverts; @@ -3417,13 +3440,22 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) prim_walk); return -EINVAL; } - return r100_cs_track_texture_check(rdev, track); + + if (track->tex_dirty) { + track->tex_dirty = false; + return r100_cs_track_texture_check(rdev, track); + } + return 0; } void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track) { unsigned i, face; + track->cb_dirty = true; + track->zb_dirty = true; + track->tex_dirty = true; + if (rdev->family < CHIP_R300) { track->num_cb = 1; if (rdev->family <= CHIP_RS200) diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h index af65600e6564..ee85c4a1fc08 100644 --- a/drivers/gpu/drm/radeon/r100_track.h +++ b/drivers/gpu/drm/radeon/r100_track.h @@ -52,14 +52,7 @@ struct r100_cs_track_texture { unsigned compress_format; }; -struct r100_cs_track_limits { - unsigned num_cb; - unsigned num_texture; - unsigned max_levels; -}; - struct r100_cs_track { - struct radeon_device *rdev; unsigned num_cb; unsigned num_texture; unsigned maxy; @@ -78,6 +71,10 @@ struct r100_cs_track { bool separate_cube; bool zb_cb_clear; bool blend_read_enable; + + bool cb_dirty; + bool zb_dirty; + bool tex_dirty; }; int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track); diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index d2408c395619..f24058300413 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c @@ -184,6 +184,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, } track->zb.robj = reloc->robj; track->zb.offset = idx_value; + track->zb_dirty = true; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); break; case RADEON_RB3D_COLOROFFSET: @@ -196,6 +197,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, } track->cb[0].robj = reloc->robj; track->cb[0].offset = idx_value; + track->cb_dirty = true; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); break; case R200_PP_TXOFFSET_0: @@ -214,6 +216,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, } ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); track->textures[i].robj = reloc->robj; + track->tex_dirty = true; break; case R200_PP_CUBIC_OFFSET_F1_0: case R200_PP_CUBIC_OFFSET_F2_0: @@ -257,9 +260,12 @@ int r200_packet0_check(struct radeon_cs_parser *p, track->textures[i].cube_info[face - 1].offset = idx_value; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); track->textures[i].cube_info[face - 1].robj = reloc->robj; + track->tex_dirty = true; break; case RADEON_RE_WIDTH_HEIGHT: track->maxy = ((idx_value >> 16) & 0x7FF); + track->cb_dirty = true; + track->zb_dirty = true; break; case RADEON_RB3D_COLORPITCH: r = r100_cs_packet_next_reloc(p, &reloc); @@ -280,9 +286,11 @@ int r200_packet0_check(struct radeon_cs_parser *p, ib[idx] = tmp; track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; + track->cb_dirty = true; break; case RADEON_RB3D_DEPTHPITCH: track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; + track->zb_dirty = true; break; case RADEON_RB3D_CNTL: switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { @@ -312,6 +320,8 @@ int r200_packet0_check(struct radeon_cs_parser *p, } track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); + track->cb_dirty = true; + track->zb_dirty = true; break; case RADEON_RB3D_ZSTENCILCNTL: switch (idx_value & 0xf) { @@ -329,6 +339,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, default: break; } + track->zb_dirty = true; break; case RADEON_RB3D_ZPASS_ADDR: r = r100_cs_packet_next_reloc(p, &reloc); @@ -345,6 +356,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, uint32_t temp = idx_value >> 4; for (i = 0; i < track->num_texture; i++) track->textures[i].enabled = !!(temp & (1 << i)); + track->tex_dirty = true; } break; case RADEON_SE_VF_CNTL: @@ -369,6 +381,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, i = (reg - R200_PP_TXSIZE_0) / 32; track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; + track->tex_dirty = true; break; case R200_PP_TXPITCH_0: case R200_PP_TXPITCH_1: @@ -378,6 +391,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, case R200_PP_TXPITCH_5: i = (reg - R200_PP_TXPITCH_0) / 32; track->textures[i].pitch = idx_value + 32; + track->tex_dirty = true; break; case R200_PP_TXFILTER_0: case R200_PP_TXFILTER_1: @@ -394,6 +408,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, tmp = (idx_value >> 27) & 0x7; if (tmp == 2 || tmp == 6) track->textures[i].roundup_h = false; + track->tex_dirty = true; break; case R200_PP_TXMULTI_CTL_0: case R200_PP_TXMULTI_CTL_1: @@ -432,6 +447,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, track->textures[i].tex_coord_type = 1; break; } + track->tex_dirty = true; break; case R200_PP_TXFORMAT_0: case R200_PP_TXFORMAT_1: @@ -488,6 +504,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, } track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); + track->tex_dirty = true; break; case R200_PP_CUBIC_FACES_0: case R200_PP_CUBIC_FACES_1: @@ -501,6 +518,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); } + track->tex_dirty = true; break; default: printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 55fe5ba7def3..15f94648f274 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -667,6 +667,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, } track->cb[i].robj = reloc->robj; track->cb[i].offset = idx_value; + track->cb_dirty = true; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); break; case R300_ZB_DEPTHOFFSET: @@ -679,6 +680,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, } track->zb.robj = reloc->robj; track->zb.offset = idx_value; + track->zb_dirty = true; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); break; case R300_TX_OFFSET_0: @@ -717,6 +719,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, tmp |= tile_flags; ib[idx] = tmp; track->textures[i].robj = reloc->robj; + track->tex_dirty = true; break; /* Tracked registers */ case 0x2084: @@ -743,6 +746,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p, if (p->rdev->family < CHIP_RV515) { track->maxy -= 1440; } + track->cb_dirty = true; + track->zb_dirty = true; break; case 0x4E00: /* RB3D_CCTL */ @@ -752,6 +757,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, return -EINVAL; } track->num_cb = ((idx_value >> 5) & 0x3) + 1; + track->cb_dirty = true; break; case 0x4E38: case 0x4E3C: @@ -814,6 +820,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, ((idx_value >> 21) & 0xF)); return -EINVAL; } + track->cb_dirty = true; break; case 0x4F00: /* ZB_CNTL */ @@ -822,6 +829,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, } else { track->z_enabled = false; } + track->zb_dirty = true; break; case 0x4F10: /* ZB_FORMAT */ @@ -838,6 +846,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, (idx_value & 0xF)); return -EINVAL; } + track->zb_dirty = true; break; case 0x4F24: /* ZB_DEPTHPITCH */ @@ -861,6 +870,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, ib[idx] = tmp; track->zb.pitch = idx_value & 0x3FFC; + track->zb_dirty = true; break; case 0x4104: for (i = 0; i < 16; i++) { @@ -869,6 +879,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, enabled = !!(idx_value & (1 << i)); track->textures[i].enabled = enabled; } + track->tex_dirty = true; break; case 0x44C0: case 0x44C4: @@ -951,8 +962,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p, DRM_ERROR("Invalid texture format %u\n", (idx_value & 0x1F)); return -EINVAL; - break; } + track->tex_dirty = true; break; case 0x4400: case 0x4404: @@ -980,6 +991,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, if (tmp == 2 || tmp == 4 || tmp == 6) { track->textures[i].roundup_h = false; } + track->tex_dirty = true; break; case 0x4500: case 0x4504: @@ -1017,6 +1029,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, DRM_ERROR("Forbidden bit TXFORMAT_MSB\n"); return -EINVAL; } + track->tex_dirty = true; break; case 0x4480: case 0x4484: @@ -1046,6 +1059,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, track->textures[i].use_pitch = !!tmp; tmp = (idx_value >> 22) & 0xF; track->textures[i].txdepth = tmp; + track->tex_dirty = true; break; case R300_ZB_ZPASS_ADDR: r = r100_cs_packet_next_reloc(p, &reloc); @@ -1060,6 +1074,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, case 0x4e0c: /* RB3D_COLOR_CHANNEL_MASK */ track->color_channel_mask = idx_value; + track->cb_dirty = true; break; case 0x43a4: /* SC_HYPERZ_EN */ @@ -1073,6 +1088,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p, case 0x4f1c: /* ZB_BW_CNTL */ track->zb_cb_clear = !!(idx_value & (1 << 5)); + track->cb_dirty = true; + track->zb_dirty = true; if (p->rdev->hyperz_filp != p->filp) { if (idx_value & (R300_HIZ_ENABLE | R300_RD_COMP_ENABLE | @@ -1084,6 +1101,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, case 0x4e04: /* RB3D_BLENDCNTL */ track->blend_read_enable = !!(idx_value & (1 << 2)); + track->cb_dirty = true; break; case 0x4f28: /* ZB_DEPTHCLEARVALUE */ break; -- cgit v1.2.3 From dee54c40a1a9898bcd156436a1d3524f530b5a90 Mon Sep 17 00:00:00 2001 From: Cédric Cano Date: Fri, 11 Feb 2011 19:45:36 -0500 Subject: drm/radeon: 6xx/7xx non-kms endian fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit agd5f: minor cleanups Signed-off-by: Cédric Cano Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600_blit.c | 11 +++++++++-- drivers/gpu/drm/radeon/r600_cp.c | 31 ++++++++++++++++++++++++------- drivers/gpu/drm/radeon/radeon_drv.h | 1 + 3 files changed, 34 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r600_blit.c b/drivers/gpu/drm/radeon/r600_blit.c index ca5c29f70779..7f1043448d25 100644 --- a/drivers/gpu/drm/radeon/r600_blit.c +++ b/drivers/gpu/drm/radeon/r600_blit.c @@ -137,9 +137,9 @@ set_shaders(struct drm_device *dev) ps = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset + 256); for (i = 0; i < r6xx_vs_size; i++) - vs[i] = r6xx_vs[i]; + vs[i] = cpu_to_le32(r6xx_vs[i]); for (i = 0; i < r6xx_ps_size; i++) - ps[i] = r6xx_ps[i]; + ps[i] = cpu_to_le32(r6xx_ps[i]); dev_priv->blit_vb->used = 512; @@ -192,6 +192,9 @@ set_vtx_resource(drm_radeon_private_t *dev_priv, u64 gpu_addr) DRM_DEBUG("\n"); sq_vtx_constant_word2 = (((gpu_addr >> 32) & 0xff) | (16 << 8)); +#ifdef __BIG_ENDIAN + sq_vtx_constant_word2 |= (2 << 30); +#endif BEGIN_RING(9); OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); @@ -291,7 +294,11 @@ draw_auto(drm_radeon_private_t *dev_priv) OUT_RING(DI_PT_RECTLIST); OUT_RING(CP_PACKET3(R600_IT_INDEX_TYPE, 0)); +#ifdef __BIG_ENDIAN + OUT_RING((2 << 2) | DI_INDEX_SIZE_16_BIT); +#else OUT_RING(DI_INDEX_SIZE_16_BIT); +#endif OUT_RING(CP_PACKET3(R600_IT_NUM_INSTANCES, 0)); OUT_RING(1); diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c index 4f4cd8b286d5..c3ab959bdc7c 100644 --- a/drivers/gpu/drm/radeon/r600_cp.c +++ b/drivers/gpu/drm/radeon/r600_cp.c @@ -396,6 +396,9 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv) r600_do_cp_stop(dev_priv); RADEON_WRITE(R600_CP_RB_CNTL, +#ifdef __BIG_ENDIAN + R600_BUF_SWAP_32BIT | +#endif R600_RB_NO_UPDATE | R600_RB_BLKSZ(15) | R600_RB_BUFSZ(3)); @@ -486,9 +489,12 @@ static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv) r600_do_cp_stop(dev_priv); RADEON_WRITE(R600_CP_RB_CNTL, +#ifdef __BIG_ENDIAN + R600_BUF_SWAP_32BIT | +#endif R600_RB_NO_UPDATE | - (15 << 8) | - (3 << 0)); + R600_RB_BLKSZ(15) | + R600_RB_BUFSZ(3)); RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); RADEON_READ(R600_GRBM_SOFT_RESET); @@ -550,8 +556,12 @@ static void r600_test_writeback(drm_radeon_private_t *dev_priv) if (!dev_priv->writeback_works) { /* Disable writeback to avoid unnecessary bus master transfer */ - RADEON_WRITE(R600_CP_RB_CNTL, RADEON_READ(R600_CP_RB_CNTL) | - RADEON_RB_NO_UPDATE); + RADEON_WRITE(R600_CP_RB_CNTL, +#ifdef __BIG_ENDIAN + R600_BUF_SWAP_32BIT | +#endif + RADEON_READ(R600_CP_RB_CNTL) | + R600_RB_NO_UPDATE); RADEON_WRITE(R600_SCRATCH_UMSK, 0); } } @@ -575,7 +585,11 @@ int r600_do_engine_reset(struct drm_device *dev) RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0); cp_rb_cntl = RADEON_READ(R600_CP_RB_CNTL); - RADEON_WRITE(R600_CP_RB_CNTL, R600_RB_RPTR_WR_ENA); + RADEON_WRITE(R600_CP_RB_CNTL, +#ifdef __BIG_ENDIAN + R600_BUF_SWAP_32BIT | +#endif + R600_RB_RPTR_WR_ENA); RADEON_WRITE(R600_CP_RB_RPTR_WR, cp_ptr); RADEON_WRITE(R600_CP_RB_WPTR, cp_ptr); @@ -1838,7 +1852,10 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev, + dev_priv->gart_vm_start; } RADEON_WRITE(R600_CP_RB_RPTR_ADDR, - rptr_addr & 0xffffffff); +#ifdef __BIG_ENDIAN + (2 << 0) | +#endif + (rptr_addr & 0xfffffffc)); RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI, upper_32_bits(rptr_addr)); @@ -1889,7 +1906,7 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev, { u64 scratch_addr; - scratch_addr = RADEON_READ(R600_CP_RB_RPTR_ADDR); + scratch_addr = RADEON_READ(R600_CP_RB_RPTR_ADDR) & 0xFFFFFFFC; scratch_addr |= ((u64)RADEON_READ(R600_CP_RB_RPTR_ADDR_HI)) << 32; scratch_addr += R600_SCRATCH_REG_OFFSET; scratch_addr >>= 8; diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index 448eba89d1e6..5cba46b9779a 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h @@ -1524,6 +1524,7 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); #define R600_CP_RB_CNTL 0xc104 # define R600_RB_BUFSZ(x) ((x) << 0) # define R600_RB_BLKSZ(x) ((x) << 8) +# define R600_BUF_SWAP_32BIT (2 << 16) # define R600_RB_NO_UPDATE (1 << 27) # define R600_RB_RPTR_WR_ENA (1 << 31) #define R600_CP_RB_RPTR_WR 0xc108 -- cgit v1.2.3 From 4589433c57bd34b7e49068549e07a43c8d41e39d Mon Sep 17 00:00:00 2001 From: Cédric Cano Date: Fri, 11 Feb 2011 19:45:37 -0500 Subject: drm/radeon/kms: atombios big endian fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit agd5f: additional cleanups/fixes Signed-off-by: Cédric Cano Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atombios_crtc.c | 52 ++++++++++++++++---------------- drivers/gpu/drm/radeon/radeon_atombios.c | 48 ++++++++++++++--------------- drivers/gpu/drm/radeon/radeon_encoders.c | 4 +-- 3 files changed, 52 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index dd4e3acf79c0..1bf61220a450 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -48,29 +48,29 @@ static void atombios_overscan_setup(struct drm_crtc *crtc, switch (radeon_crtc->rmx_type) { case RMX_CENTER: - args.usOverscanTop = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; - args.usOverscanBottom = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; - args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; - args.usOverscanRight = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; + args.usOverscanTop = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2); + args.usOverscanBottom = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2); + args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2); + args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2); break; case RMX_ASPECT: a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay; a2 = adjusted_mode->crtc_vdisplay * mode->crtc_hdisplay; if (a1 > a2) { - args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2; - args.usOverscanRight = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2; + args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2); + args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2); } else if (a2 > a1) { - args.usOverscanLeft = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; - args.usOverscanRight = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; + args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2); + args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2); } break; case RMX_FULL: default: - args.usOverscanRight = radeon_crtc->h_border; - args.usOverscanLeft = radeon_crtc->h_border; - args.usOverscanBottom = radeon_crtc->v_border; - args.usOverscanTop = radeon_crtc->v_border; + args.usOverscanRight = cpu_to_le16(radeon_crtc->h_border); + args.usOverscanLeft = cpu_to_le16(radeon_crtc->h_border); + args.usOverscanBottom = cpu_to_le16(radeon_crtc->v_border); + args.usOverscanTop = cpu_to_le16(radeon_crtc->v_border); break; } atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); @@ -419,23 +419,23 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc, memset(&args, 0, sizeof(args)); if (ASIC_IS_DCE5(rdev)) { - args.v3.usSpreadSpectrumAmountFrac = 0; + args.v3.usSpreadSpectrumAmountFrac = cpu_to_le16(0); args.v3.ucSpreadSpectrumType = ss->type; switch (pll_id) { case ATOM_PPLL1: args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P1PLL; - args.v3.usSpreadSpectrumAmount = ss->amount; - args.v3.usSpreadSpectrumStep = ss->step; + args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); + args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step); break; case ATOM_PPLL2: args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P2PLL; - args.v3.usSpreadSpectrumAmount = ss->amount; - args.v3.usSpreadSpectrumStep = ss->step; + args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); + args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step); break; case ATOM_DCPLL: args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_DCPLL; - args.v3.usSpreadSpectrumAmount = 0; - args.v3.usSpreadSpectrumStep = 0; + args.v3.usSpreadSpectrumAmount = cpu_to_le16(0); + args.v3.usSpreadSpectrumStep = cpu_to_le16(0); break; case ATOM_PPLL_INVALID: return; @@ -447,18 +447,18 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc, switch (pll_id) { case ATOM_PPLL1: args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P1PLL; - args.v2.usSpreadSpectrumAmount = ss->amount; - args.v2.usSpreadSpectrumStep = ss->step; + args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); + args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step); break; case ATOM_PPLL2: args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P2PLL; - args.v2.usSpreadSpectrumAmount = ss->amount; - args.v2.usSpreadSpectrumStep = ss->step; + args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); + args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step); break; case ATOM_DCPLL: args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_DCPLL; - args.v2.usSpreadSpectrumAmount = 0; - args.v2.usSpreadSpectrumStep = 0; + args.v2.usSpreadSpectrumAmount = cpu_to_le16(0); + args.v2.usSpreadSpectrumStep = cpu_to_le16(0); break; case ATOM_PPLL_INVALID: return; @@ -721,7 +721,7 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc, * SetPixelClock provides the dividers */ args.v5.ucCRTC = ATOM_CRTC_INVALID; - args.v5.usPixelClock = dispclk; + args.v5.usPixelClock = cpu_to_le16(dispclk); args.v5.ucPpll = ATOM_DCPLL; break; case 6: diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 5c1cc7ad9a15..02d5c415f499 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -88,7 +88,7 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev /* some evergreen boards have bad data for this entry */ if (ASIC_IS_DCE4(rdev)) { if ((i == 7) && - (gpio->usClkMaskRegisterIndex == 0x1936) && + (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && (gpio->sucI2cId.ucAccess == 0)) { gpio->sucI2cId.ucAccess = 0x97; gpio->ucDataMaskShift = 8; @@ -101,7 +101,7 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev /* some DCE3 boards have bad data for this entry */ if (ASIC_IS_DCE3(rdev)) { if ((i == 4) && - (gpio->usClkMaskRegisterIndex == 0x1fda) && + (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && (gpio->sucI2cId.ucAccess == 0x94)) gpio->sucI2cId.ucAccess = 0x14; } @@ -172,7 +172,7 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) /* some evergreen boards have bad data for this entry */ if (ASIC_IS_DCE4(rdev)) { if ((i == 7) && - (gpio->usClkMaskRegisterIndex == 0x1936) && + (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && (gpio->sucI2cId.ucAccess == 0)) { gpio->sucI2cId.ucAccess = 0x97; gpio->ucDataMaskShift = 8; @@ -185,7 +185,7 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) /* some DCE3 boards have bad data for this entry */ if (ASIC_IS_DCE3(rdev)) { if ((i == 4) && - (gpio->usClkMaskRegisterIndex == 0x1fda) && + (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && (gpio->sucI2cId.ucAccess == 0x94)) gpio->sucI2cId.ucAccess = 0x14; } @@ -252,7 +252,7 @@ static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rd pin = &gpio_info->asGPIO_Pin[i]; if (id == pin->ucGPIO_ID) { gpio.id = pin->ucGPIO_ID; - gpio.reg = pin->usGpioPin_AIndex * 4; + gpio.reg = le16_to_cpu(pin->usGpioPin_AIndex) * 4; gpio.mask = (1 << pin->ucGpioPinBitShift); gpio.valid = true; break; @@ -1274,11 +1274,11 @@ bool radeon_atombios_sideport_present(struct radeon_device *rdev) data_offset); switch (crev) { case 1: - if (igp_info->info.ulBootUpMemoryClock) + if (le32_to_cpu(igp_info->info.ulBootUpMemoryClock)) return true; break; case 2: - if (igp_info->info_2.ulBootUpSidePortClock) + if (le32_to_cpu(igp_info->info_2.ulBootUpSidePortClock)) return true; break; default: @@ -1442,7 +1442,7 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, for (i = 0; i < num_indices; i++) { if ((ss_info->info.asSpreadSpectrum[i].ucClockIndication == id) && - (clock <= ss_info->info.asSpreadSpectrum[i].ulTargetClockRange)) { + (clock <= le32_to_cpu(ss_info->info.asSpreadSpectrum[i].ulTargetClockRange))) { ss->percentage = le16_to_cpu(ss_info->info.asSpreadSpectrum[i].usSpreadSpectrumPercentage); ss->type = ss_info->info.asSpreadSpectrum[i].ucSpreadSpectrumMode; @@ -1456,7 +1456,7 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2); for (i = 0; i < num_indices; i++) { if ((ss_info->info_2.asSpreadSpectrum[i].ucClockIndication == id) && - (clock <= ss_info->info_2.asSpreadSpectrum[i].ulTargetClockRange)) { + (clock <= le32_to_cpu(ss_info->info_2.asSpreadSpectrum[i].ulTargetClockRange))) { ss->percentage = le16_to_cpu(ss_info->info_2.asSpreadSpectrum[i].usSpreadSpectrumPercentage); ss->type = ss_info->info_2.asSpreadSpectrum[i].ucSpreadSpectrumMode; @@ -1470,7 +1470,7 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3); for (i = 0; i < num_indices; i++) { if ((ss_info->info_3.asSpreadSpectrum[i].ucClockIndication == id) && - (clock <= ss_info->info_3.asSpreadSpectrum[i].ulTargetClockRange)) { + (clock <= le32_to_cpu(ss_info->info_3.asSpreadSpectrum[i].ulTargetClockRange))) { ss->percentage = le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadSpectrumPercentage); ss->type = ss_info->info_3.asSpreadSpectrum[i].ucSpreadSpectrumMode; @@ -1553,8 +1553,8 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct if (misc & ATOM_DOUBLE_CLOCK_MODE) lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN; - lvds->native_mode.width_mm = lvds_info->info.sLCDTiming.usImageHSize; - lvds->native_mode.height_mm = lvds_info->info.sLCDTiming.usImageVSize; + lvds->native_mode.width_mm = le16_to_cpu(lvds_info->info.sLCDTiming.usImageHSize); + lvds->native_mode.height_mm = le16_to_cpu(lvds_info->info.sLCDTiming.usImageVSize); /* set crtc values */ drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); @@ -1569,13 +1569,13 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct lvds->linkb = false; /* parse the lcd record table */ - if (lvds_info->info.usModePatchTableOffset) { + if (le16_to_cpu(lvds_info->info.usModePatchTableOffset)) { ATOM_FAKE_EDID_PATCH_RECORD *fake_edid_record; ATOM_PANEL_RESOLUTION_PATCH_RECORD *panel_res_record; bool bad_record = false; u8 *record = (u8 *)(mode_info->atom_context->bios + data_offset + - lvds_info->info.usModePatchTableOffset); + le16_to_cpu(lvds_info->info.usModePatchTableOffset)); while (*record != ATOM_RECORD_END_TYPE) { switch (*record) { case LCD_MODE_PATCH_RECORD_MODE_TYPE: @@ -2189,7 +2189,7 @@ static u16 radeon_atombios_get_default_vddc(struct radeon_device *rdev) firmware_info = (union firmware_info *)(mode_info->atom_context->bios + data_offset); - vddc = firmware_info->info_14.usBootUpVDDCVoltage; + vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage); } return vddc; @@ -2284,7 +2284,7 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = VOLTAGE_SW; rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = - clock_info->evergreen.usVDDC; + le16_to_cpu(clock_info->evergreen.usVDDC); } else { sclk = le16_to_cpu(clock_info->r600.usEngineClockLow); sclk |= clock_info->r600.ucEngineClockHigh << 16; @@ -2295,7 +2295,7 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = VOLTAGE_SW; rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = - clock_info->r600.usVDDC; + le16_to_cpu(clock_info->r600.usVDDC); } if (rdev->flags & RADEON_IS_IGP) { @@ -2408,13 +2408,13 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); state_array = (struct StateArray *) (mode_info->atom_context->bios + data_offset + - power_info->pplib.usStateArrayOffset); + le16_to_cpu(power_info->pplib.usStateArrayOffset)); clock_info_array = (struct ClockInfoArray *) (mode_info->atom_context->bios + data_offset + - power_info->pplib.usClockInfoArrayOffset); + le16_to_cpu(power_info->pplib.usClockInfoArrayOffset)); non_clock_info_array = (struct NonClockInfoArray *) (mode_info->atom_context->bios + data_offset + - power_info->pplib.usNonClockInfoArrayOffset); + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * state_array->ucNumEntries, GFP_KERNEL); if (!rdev->pm.power_state) @@ -2533,7 +2533,7 @@ uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev) int index = GetIndexIntoMasterTable(COMMAND, GetEngineClock); atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - return args.ulReturnEngineClock; + return le32_to_cpu(args.ulReturnEngineClock); } uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev) @@ -2542,7 +2542,7 @@ uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev) int index = GetIndexIntoMasterTable(COMMAND, GetMemoryClock); atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - return args.ulReturnMemoryClock; + return le32_to_cpu(args.ulReturnMemoryClock); } void radeon_atom_set_engine_clock(struct radeon_device *rdev, @@ -2551,7 +2551,7 @@ void radeon_atom_set_engine_clock(struct radeon_device *rdev, SET_ENGINE_CLOCK_PS_ALLOCATION args; int index = GetIndexIntoMasterTable(COMMAND, SetEngineClock); - args.ulTargetEngineClock = eng_clock; /* 10 khz */ + args.ulTargetEngineClock = cpu_to_le32(eng_clock); /* 10 khz */ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } @@ -2565,7 +2565,7 @@ void radeon_atom_set_memory_clock(struct radeon_device *rdev, if (rdev->flags & RADEON_IS_IGP) return; - args.ulTargetMemoryClock = mem_clock; /* 10 khz */ + args.ulTargetMemoryClock = cpu_to_le32(mem_clock); /* 10 khz */ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 5b38b73ccd12..b4274883227f 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -910,7 +910,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t args.v1.ucAction = action; if (action == ATOM_TRANSMITTER_ACTION_INIT) { - args.v1.usInitInfo = connector_object_id; + args.v1.usInitInfo = cpu_to_le16(connector_object_id); } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { args.v1.asMode.ucLaneSel = lane_num; args.v1.asMode.ucLaneSet = lane_set; @@ -1140,7 +1140,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, case 3: args.v3.sExtEncoder.ucAction = action; if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) - args.v3.sExtEncoder.usConnectorId = connector_object_id; + args.v3.sExtEncoder.usConnectorId = cpu_to_le16(connector_object_id); else args.v3.sExtEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); args.v3.sExtEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder); -- cgit v1.2.3 From 4eace7fdfa1f8ac2f0a833e12bd07eeb453ec9ef Mon Sep 17 00:00:00 2001 From: Cédric Cano Date: Fri, 11 Feb 2011 19:45:38 -0500 Subject: drm/radeon/kms: 6xx/7xx big endian fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit agd5f: minor cleanups Signed-off-by: Cédric Cano Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600.c | 22 +++++++++++++++++----- drivers/gpu/drm/radeon/r600_blit_kms.c | 25 +++++++++++++++++++------ drivers/gpu/drm/radeon/r600_blit_shaders.c | 4 ++++ drivers/gpu/drm/radeon/r600d.h | 9 +++++---- drivers/gpu/drm/radeon/rv770.c | 6 +++++- drivers/gpu/drm/radeon/rv770d.h | 8 ++++---- 6 files changed, 54 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 650672a0f5ad..de88624d5f87 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2105,7 +2105,11 @@ static int r600_cp_load_microcode(struct radeon_device *rdev) r600_cp_stop(rdev); - WREG32(CP_RB_CNTL, RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); + WREG32(CP_RB_CNTL, +#ifdef __BIG_ENDIAN + BUF_SWAP_32BIT | +#endif + RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); /* Reset cp */ WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); @@ -2192,7 +2196,11 @@ int r600_cp_resume(struct radeon_device *rdev) WREG32(CP_RB_WPTR, 0); /* set the wb address whether it's enabled or not */ - WREG32(CP_RB_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC); + WREG32(CP_RB_RPTR_ADDR, +#ifdef __BIG_ENDIAN + RB_RPTR_SWAP(2) | +#endif + ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC)); WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); @@ -2628,7 +2636,11 @@ void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) { /* FIXME: implement */ radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); - radeon_ring_write(rdev, ib->gpu_addr & 0xFFFFFFFC); + radeon_ring_write(rdev, +#ifdef __BIG_ENDIAN + (2 << 0) | +#endif + (ib->gpu_addr & 0xFFFFFFFC)); radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF); radeon_ring_write(rdev, ib->length_dw); } @@ -3297,8 +3309,8 @@ restart_ih: while (rptr != wptr) { /* wptr/rptr are in bytes! */ ring_index = rptr / 4; - src_id = rdev->ih.ring[ring_index] & 0xff; - src_data = rdev->ih.ring[ring_index + 1] & 0xfffffff; + src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff; + src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff; switch (src_id) { case 1: /* D1 vblank/vline */ diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index 86e5aa07f0db..69d94dd4db21 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -165,6 +165,9 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) u32 sq_vtx_constant_word2; sq_vtx_constant_word2 = ((upper_32_bits(gpu_addr) & 0xff) | (16 << 8)); +#ifdef __BIG_ENDIAN + sq_vtx_constant_word2 |= (2 << 30); +#endif radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7)); radeon_ring_write(rdev, 0x460); @@ -253,7 +256,11 @@ draw_auto(struct radeon_device *rdev) radeon_ring_write(rdev, DI_PT_RECTLIST); radeon_ring_write(rdev, PACKET3(PACKET3_INDEX_TYPE, 0)); - radeon_ring_write(rdev, DI_INDEX_SIZE_16_BIT); + radeon_ring_write(rdev, +#ifdef __BIG_ENDIAN + (2 << 2) | +#endif + DI_INDEX_SIZE_16_BIT); radeon_ring_write(rdev, PACKET3(PACKET3_NUM_INSTANCES, 0)); radeon_ring_write(rdev, 1); @@ -424,7 +431,11 @@ set_default_state(struct radeon_device *rdev) dwords = ALIGN(rdev->r600_blit.state_len, 0x10); gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset; radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); - radeon_ring_write(rdev, gpu_addr & 0xFFFFFFFC); + radeon_ring_write(rdev, +#ifdef __BIG_ENDIAN + (2 << 0) | +#endif + (gpu_addr & 0xFFFFFFFC)); radeon_ring_write(rdev, upper_32_bits(gpu_addr) & 0xFF); radeon_ring_write(rdev, dwords); @@ -467,7 +478,7 @@ static inline uint32_t i2f(uint32_t input) int r600_blit_init(struct radeon_device *rdev) { u32 obj_size; - int r, dwords; + int i, r, dwords; void *ptr; u32 packet2s[16]; int num_packet2s = 0; @@ -486,7 +497,7 @@ int r600_blit_init(struct radeon_device *rdev) dwords = rdev->r600_blit.state_len; while (dwords & 0xf) { - packet2s[num_packet2s++] = PACKET2(0); + packet2s[num_packet2s++] = cpu_to_le32(PACKET2(0)); dwords++; } @@ -529,8 +540,10 @@ int r600_blit_init(struct radeon_device *rdev) if (num_packet2s) memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), packet2s, num_packet2s * 4); - memcpy(ptr + rdev->r600_blit.vs_offset, r6xx_vs, r6xx_vs_size * 4); - memcpy(ptr + rdev->r600_blit.ps_offset, r6xx_ps, r6xx_ps_size * 4); + for (i = 0; i < r6xx_vs_size; i++) + *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(r6xx_vs[i]); + for (i = 0; i < r6xx_ps_size; i++) + *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(r6xx_ps[i]); radeon_bo_kunmap(rdev->r600_blit.shader_obj); radeon_bo_unreserve(rdev->r600_blit.shader_obj); diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c index e8151c1d55b2..2d1f6c5ee2a7 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.c +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c @@ -684,7 +684,11 @@ const u32 r6xx_vs[] = 0x00000000, 0x3c000000, 0x68cd1000, +#ifdef __BIG_ENDIAN + 0x000a0000, +#else 0x00080000, +#endif 0x00000000, }; diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index a5d898b4bad2..04bac0bbd3ec 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -154,13 +154,14 @@ #define ROQ_IB2_START(x) ((x) << 8) #define CP_RB_BASE 0xC100 #define CP_RB_CNTL 0xC104 -#define RB_BUFSZ(x) ((x)<<0) -#define RB_BLKSZ(x) ((x)<<8) -#define RB_NO_UPDATE (1<<27) -#define RB_RPTR_WR_ENA (1<<31) +#define RB_BUFSZ(x) ((x) << 0) +#define RB_BLKSZ(x) ((x) << 8) +#define RB_NO_UPDATE (1 << 27) +#define RB_RPTR_WR_ENA (1 << 31) #define BUF_SWAP_32BIT (2 << 16) #define CP_RB_RPTR 0x8700 #define CP_RB_RPTR_ADDR 0xC10C +#define RB_RPTR_SWAP(x) ((x) << 0) #define CP_RB_RPTR_ADDR_HI 0xC110 #define CP_RB_RPTR_WR 0xC108 #define CP_RB_WPTR 0xC114 diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 2211a323db41..d8ba67690656 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -321,7 +321,11 @@ static int rv770_cp_load_microcode(struct radeon_device *rdev) return -EINVAL; r700_cp_stop(rdev); - WREG32(CP_RB_CNTL, RB_NO_UPDATE | (15 << 8) | (3 << 0)); + WREG32(CP_RB_CNTL, +#ifdef __BIG_ENDIAN + BUF_SWAP_32BIT | +#endif + RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); /* Reset cp */ WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index abc8cf5a3672..79fa588e9ed5 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h @@ -76,10 +76,10 @@ #define ROQ_IB1_START(x) ((x) << 0) #define ROQ_IB2_START(x) ((x) << 8) #define CP_RB_CNTL 0xC104 -#define RB_BUFSZ(x) ((x)<<0) -#define RB_BLKSZ(x) ((x)<<8) -#define RB_NO_UPDATE (1<<27) -#define RB_RPTR_WR_ENA (1<<31) +#define RB_BUFSZ(x) ((x) << 0) +#define RB_BLKSZ(x) ((x) << 8) +#define RB_NO_UPDATE (1 << 27) +#define RB_RPTR_WR_ENA (1 << 31) #define BUF_SWAP_32BIT (2 << 16) #define CP_RB_RPTR 0x8700 #define CP_RB_RPTR_ADDR 0xC10C -- cgit v1.2.3 From 0f234f5fdca1e31c7a6333c3633edc653cf3e598 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sun, 13 Feb 2011 19:06:33 -0500 Subject: drm/radeon/kms: evergreen/ni big endian fixes (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on 6xx/7xx endian fixes from Cédric Cano. v2: fix typo in shader Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 22 +++++++++++++++++----- drivers/gpu/drm/radeon/evergreen_blit_kms.c | 19 ++++++++++++++----- drivers/gpu/drm/radeon/evergreen_blit_shaders.c | 8 ++++++++ drivers/gpu/drm/radeon/evergreend.h | 1 + 4 files changed, 40 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index ffdc8332b76e..d270b3ff896b 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1192,7 +1192,11 @@ void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) radeon_ring_write(rdev, 1); /* FIXME: implement */ radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); - radeon_ring_write(rdev, ib->gpu_addr & 0xFFFFFFFC); + radeon_ring_write(rdev, +#ifdef __BIG_ENDIAN + (2 << 0) | +#endif + (ib->gpu_addr & 0xFFFFFFFC)); radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF); radeon_ring_write(rdev, ib->length_dw); } @@ -1207,7 +1211,11 @@ static int evergreen_cp_load_microcode(struct radeon_device *rdev) return -EINVAL; r700_cp_stop(rdev); - WREG32(CP_RB_CNTL, RB_NO_UPDATE | (15 << 8) | (3 << 0)); + WREG32(CP_RB_CNTL, +#ifdef __BIG_ENDIAN + BUF_SWAP_32BIT | +#endif + RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); fw_data = (const __be32 *)rdev->pfp_fw->data; WREG32(CP_PFP_UCODE_ADDR, 0); @@ -1326,7 +1334,11 @@ int evergreen_cp_resume(struct radeon_device *rdev) WREG32(CP_RB_WPTR, 0); /* set the wb address wether it's enabled or not */ - WREG32(CP_RB_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC); + WREG32(CP_RB_RPTR_ADDR, +#ifdef __BIG_ENDIAN + RB_RPTR_SWAP(2) | +#endif + ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC)); WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); @@ -2627,8 +2639,8 @@ restart_ih: while (rptr != wptr) { /* wptr/rptr are in bytes! */ ring_index = rptr / 4; - src_id = rdev->ih.ring[ring_index] & 0xff; - src_data = rdev->ih.ring[ring_index + 1] & 0xfffffff; + src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff; + src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff; switch (src_id) { case 1: /* D1 vblank/vline */ diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index a1ba4b3053d0..a7b7a33eaf3a 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c @@ -133,6 +133,9 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) /* high addr, stride */ sq_vtx_constant_word2 = ((upper_32_bits(gpu_addr) & 0xff) | (16 << 8)); +#ifdef __BIG_ENDIAN + sq_vtx_constant_word2 |= (2 << 30); +#endif /* xyzw swizzles */ sq_vtx_constant_word3 = (0 << 3) | (1 << 6) | (2 << 9) | (3 << 12); @@ -221,7 +224,11 @@ draw_auto(struct radeon_device *rdev) radeon_ring_write(rdev, DI_PT_RECTLIST); radeon_ring_write(rdev, PACKET3(PACKET3_INDEX_TYPE, 0)); - radeon_ring_write(rdev, DI_INDEX_SIZE_16_BIT); + radeon_ring_write(rdev, +#ifdef __BIG_ENDIAN + (2 << 2) | +#endif + DI_INDEX_SIZE_16_BIT); radeon_ring_write(rdev, PACKET3(PACKET3_NUM_INSTANCES, 0)); radeon_ring_write(rdev, 1); @@ -541,7 +548,7 @@ static inline uint32_t i2f(uint32_t input) int evergreen_blit_init(struct radeon_device *rdev) { u32 obj_size; - int r, dwords; + int i, r, dwords; void *ptr; u32 packet2s[16]; int num_packet2s = 0; @@ -557,7 +564,7 @@ int evergreen_blit_init(struct radeon_device *rdev) dwords = rdev->r600_blit.state_len; while (dwords & 0xf) { - packet2s[num_packet2s++] = PACKET2(0); + packet2s[num_packet2s++] = cpu_to_le32(PACKET2(0)); dwords++; } @@ -598,8 +605,10 @@ int evergreen_blit_init(struct radeon_device *rdev) if (num_packet2s) memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), packet2s, num_packet2s * 4); - memcpy(ptr + rdev->r600_blit.vs_offset, evergreen_vs, evergreen_vs_size * 4); - memcpy(ptr + rdev->r600_blit.ps_offset, evergreen_ps, evergreen_ps_size * 4); + for (i = 0; i < evergreen_vs_size; i++) + *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(evergreen_vs[i]); + for (i = 0; i < evergreen_ps_size; i++) + *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(evergreen_ps[i]); radeon_bo_kunmap(rdev->r600_blit.shader_obj); radeon_bo_unreserve(rdev->r600_blit.shader_obj); diff --git a/drivers/gpu/drm/radeon/evergreen_blit_shaders.c b/drivers/gpu/drm/radeon/evergreen_blit_shaders.c index ef1d28c07fbf..3a10399e0066 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_shaders.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_shaders.c @@ -311,11 +311,19 @@ const u32 evergreen_vs[] = 0x00000000, 0x3c000000, 0x67961001, +#ifdef __BIG_ENDIAN + 0x000a0000, +#else 0x00080000, +#endif 0x00000000, 0x1c000000, 0x67961000, +#ifdef __BIG_ENDIAN + 0x00020008, +#else 0x00000008, +#endif 0x00000000, }; diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index afec1aca2a73..eb4acf4528ff 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -98,6 +98,7 @@ #define BUF_SWAP_32BIT (2 << 16) #define CP_RB_RPTR 0x8700 #define CP_RB_RPTR_ADDR 0xC10C +#define RB_RPTR_SWAP(x) ((x) << 0) #define CP_RB_RPTR_ADDR_HI 0xC110 #define CP_RB_RPTR_WR 0xC108 #define CP_RB_WPTR 0xC114 -- cgit v1.2.3 From 8fd1b84cc9d32e7e5c44e990a9c9e27504b232ed Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 10 Feb 2011 14:46:06 +1000 Subject: drm/radeon: fix race between GPU reset and TTM delayed delete thread. My evergreen has been in a remote PC for week and reset has never once saved me from certain doom, I finally relocated to the box with a serial cable and noticed an oops when the GPU resets, and the TTM delayed delete thread tries to remove something from the GTT. This stops the delayed delete thread from executing across the GPU reset handler, and woot I can GPU reset now. Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_device.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 0d478932b1a9..4954e2d6ffa2 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -936,8 +936,11 @@ int radeon_resume_kms(struct drm_device *dev) int radeon_gpu_reset(struct radeon_device *rdev) { int r; + int resched; radeon_save_bios_scratch_regs(rdev); + /* block TTM */ + resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); radeon_suspend(rdev); r = radeon_asic_reset(rdev); @@ -946,6 +949,7 @@ int radeon_gpu_reset(struct radeon_device *rdev) radeon_resume(rdev); radeon_restore_bios_scratch_regs(rdev); drm_helper_resume_force_mode(rdev->ddev); + ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); return 0; } /* bad news, how to tell it to userspace ? */ -- cgit v1.2.3 From 1ea9dbf250ae6706400dc0e3d6e1cc7540830731 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 10 Feb 2011 14:51:33 -0500 Subject: drm/radeon/kms: use linear aligned for 6xx/7xx bo blits Not only is linear aligned supposedly more performant, linear general is only supported by the CB in single slice mode. The texture hardware doesn't support linear general, but I think the hw automatically upgrades it to linear aligned. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600_blit_kms.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index 69d94dd4db21..41f7aafc97c4 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -54,7 +54,7 @@ set_render_target(struct radeon_device *rdev, int format, if (h < 8) h = 8; - cb_color_info = ((format << 2) | (1 << 27)); + cb_color_info = ((format << 2) | (1 << 27) | (1 << 8)); pitch = (w / 8) - 1; slice = ((w * h) / 64) - 1; @@ -202,7 +202,7 @@ set_tex_resource(struct radeon_device *rdev, if (h < 1) h = 1; - sq_tex_resource_word0 = (1 << 0); + sq_tex_resource_word0 = (1 << 0) | (1 << 3); sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) | ((w - 1) << 19)); -- cgit v1.2.3 From 27dcfc102279867ef0080d3b27e0f8306cac53d1 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 10 Feb 2011 14:51:34 -0500 Subject: drm/radeon/kms: use linear aligned for evergreen/ni bo blits Not only is linear aligned supposedly more performant, linear general is only supported by the CB in single slice mode. The texture hardware doesn't support linear general, but I think the hw automatically upgrades it to linear aligned. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen_blit_kms.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index a7b7a33eaf3a..2adfb03f479b 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c @@ -55,7 +55,7 @@ set_render_target(struct radeon_device *rdev, int format, if (h < 8) h = 8; - cb_color_info = ((format << 2) | (1 << 24)); + cb_color_info = ((format << 2) | (1 << 24) | (1 << 8)); pitch = (w / 8) - 1; slice = ((w * h) / 64) - 1; @@ -176,7 +176,7 @@ set_tex_resource(struct radeon_device *rdev, sq_tex_resource_word0 = (1 << 0); /* 2D */ sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 6) | ((w - 1) << 18)); - sq_tex_resource_word1 = ((h - 1) << 0); + sq_tex_resource_word1 = ((h - 1) << 0) | (1 << 28); /* xyzw swizzles */ sq_tex_resource_word4 = (0 << 16) | (1 << 19) | (2 << 22) | (3 << 25); -- cgit v1.2.3 From 501834349e872ed4115eea3beef65ca9eeb5528e Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 14 Feb 2011 01:01:09 +0100 Subject: drm/radeon/kms: fix tracking of BLENDCNTL, COLOR_CHANNEL_MASK, and GB_Z on r300 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also move ZB_DEPTHCLEARVALUE to the list of safe regs. Signed-off-by: Marek Olšák Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r300.c | 3 +-- drivers/gpu/drm/radeon/reg_srcs/r300 | 3 +-- drivers/gpu/drm/radeon/reg_srcs/r420 | 4 +--- drivers/gpu/drm/radeon/reg_srcs/rs600 | 3 +-- drivers/gpu/drm/radeon/reg_srcs/rv515 | 4 +--- 5 files changed, 5 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 15f94648f274..862b61742b82 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -873,6 +873,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, track->zb_dirty = true; break; case 0x4104: + /* TX_ENABLE */ for (i = 0; i < 16; i++) { bool enabled; @@ -1103,8 +1104,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, track->blend_read_enable = !!(idx_value & (1 << 2)); track->cb_dirty = true; break; - case 0x4f28: /* ZB_DEPTHCLEARVALUE */ - break; case 0x4f30: /* ZB_MASK_OFFSET */ case 0x4f34: /* ZB_ZMASK_PITCH */ case 0x4f44: /* ZB_HIZ_OFFSET */ diff --git a/drivers/gpu/drm/radeon/reg_srcs/r300 b/drivers/gpu/drm/radeon/reg_srcs/r300 index b506ec1cab4b..13a94e2ee03b 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r300 +++ b/drivers/gpu/drm/radeon/reg_srcs/r300 @@ -683,9 +683,7 @@ r300 0x4f60 0x4DF4 US_ALU_CONST_G_31 0x4DF8 US_ALU_CONST_B_31 0x4DFC US_ALU_CONST_A_31 -0x4E04 RB3D_BLENDCNTL_R3 0x4E08 RB3D_ABLENDCNTL_R3 -0x4E0C RB3D_COLOR_CHANNEL_MASK 0x4E10 RB3D_CONSTANT_COLOR 0x4E14 RB3D_COLOR_CLEAR_VALUE 0x4E18 RB3D_ROPCNTL_R3 @@ -715,4 +713,5 @@ r300 0x4f60 0x4F08 ZB_STENCILREFMASK 0x4F14 ZB_ZTOP 0x4F18 ZB_ZCACHE_CTLSTAT +0x4F28 ZB_DEPTHCLEARVALUE 0x4F58 ZB_ZPASS_DATA diff --git a/drivers/gpu/drm/radeon/reg_srcs/r420 b/drivers/gpu/drm/radeon/reg_srcs/r420 index 8c1214c2390f..5c95cf87f7f2 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r420 +++ b/drivers/gpu/drm/radeon/reg_srcs/r420 @@ -130,7 +130,6 @@ r420 0x4f60 0x401C GB_SELECT 0x4020 GB_AA_CONFIG 0x4024 GB_FIFO_SIZE -0x4028 GB_Z_PEQ_CONFIG 0x4100 TX_INVALTAGS 0x4200 GA_POINT_S0 0x4204 GA_POINT_T0 @@ -750,9 +749,7 @@ r420 0x4f60 0x4DF4 US_ALU_CONST_G_31 0x4DF8 US_ALU_CONST_B_31 0x4DFC US_ALU_CONST_A_31 -0x4E04 RB3D_BLENDCNTL_R3 0x4E08 RB3D_ABLENDCNTL_R3 -0x4E0C RB3D_COLOR_CHANNEL_MASK 0x4E10 RB3D_CONSTANT_COLOR 0x4E14 RB3D_COLOR_CLEAR_VALUE 0x4E18 RB3D_ROPCNTL_R3 @@ -782,4 +779,5 @@ r420 0x4f60 0x4F08 ZB_STENCILREFMASK 0x4F14 ZB_ZTOP 0x4F18 ZB_ZCACHE_CTLSTAT +0x4F28 ZB_DEPTHCLEARVALUE 0x4F58 ZB_ZPASS_DATA diff --git a/drivers/gpu/drm/radeon/reg_srcs/rs600 b/drivers/gpu/drm/radeon/reg_srcs/rs600 index 0828d80396f2..263109c1d0c8 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rs600 +++ b/drivers/gpu/drm/radeon/reg_srcs/rs600 @@ -749,9 +749,7 @@ rs600 0x6d40 0x4DF4 US_ALU_CONST_G_31 0x4DF8 US_ALU_CONST_B_31 0x4DFC US_ALU_CONST_A_31 -0x4E04 RB3D_BLENDCNTL_R3 0x4E08 RB3D_ABLENDCNTL_R3 -0x4E0C RB3D_COLOR_CHANNEL_MASK 0x4E10 RB3D_CONSTANT_COLOR 0x4E14 RB3D_COLOR_CLEAR_VALUE 0x4E18 RB3D_ROPCNTL_R3 @@ -781,4 +779,5 @@ rs600 0x6d40 0x4F08 ZB_STENCILREFMASK 0x4F14 ZB_ZTOP 0x4F18 ZB_ZCACHE_CTLSTAT +0x4F28 ZB_DEPTHCLEARVALUE 0x4F58 ZB_ZPASS_DATA diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515 index ef422bbacfc1..eeed003f14c7 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rv515 +++ b/drivers/gpu/drm/radeon/reg_srcs/rv515 @@ -164,7 +164,6 @@ rv515 0x6d40 0x401C GB_SELECT 0x4020 GB_AA_CONFIG 0x4024 GB_FIFO_SIZE -0x4028 GB_Z_PEQ_CONFIG 0x4100 TX_INVALTAGS 0x4114 SU_TEX_WRAP_PS3 0x4118 PS3_ENABLE @@ -461,9 +460,7 @@ rv515 0x6d40 0x4DF4 US_ALU_CONST_G_31 0x4DF8 US_ALU_CONST_B_31 0x4DFC US_ALU_CONST_A_31 -0x4E04 RB3D_BLENDCNTL_R3 0x4E08 RB3D_ABLENDCNTL_R3 -0x4E0C RB3D_COLOR_CHANNEL_MASK 0x4E10 RB3D_CONSTANT_COLOR 0x4E14 RB3D_COLOR_CLEAR_VALUE 0x4E18 RB3D_ROPCNTL_R3 @@ -496,4 +493,5 @@ rv515 0x6d40 0x4F14 ZB_ZTOP 0x4F18 ZB_ZCACHE_CTLSTAT 0x4F58 ZB_ZPASS_DATA +0x4F28 ZB_DEPTHCLEARVALUE 0x4FD4 ZB_STENCILREFMASK_BF -- cgit v1.2.3 From fff1ce4dc6113b6fdc4e3a815ca5fd229408f8ef Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Mon, 14 Feb 2011 01:01:10 +0100 Subject: drm/radeon/kms: check AA resolve registers on r300 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is an important security fix because we allowed arbitrary values to be passed to AARESOLVE_OFFSET. This also puts the right buffer address in the register. Signed-off-by: Marek Olšák Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r100.c | 23 +++++++++++++++++++++++ drivers/gpu/drm/radeon/r100_track.h | 4 +++- drivers/gpu/drm/radeon/r300.c | 21 +++++++++++++++++++++ drivers/gpu/drm/radeon/r300_reg.h | 2 ++ drivers/gpu/drm/radeon/reg_srcs/r300 | 3 --- drivers/gpu/drm/radeon/reg_srcs/r420 | 3 --- drivers/gpu/drm/radeon/reg_srcs/rs600 | 3 --- drivers/gpu/drm/radeon/reg_srcs/rv515 | 3 --- 8 files changed, 49 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index fdf4bc67ae58..56deae5bf02e 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -3381,6 +3381,26 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) } track->zb_dirty = false; + if (track->aa_dirty && track->aaresolve) { + if (track->aa.robj == NULL) { + DRM_ERROR("[drm] No buffer for AA resolve buffer %d !\n", i); + return -EINVAL; + } + /* I believe the format comes from colorbuffer0. */ + size = track->aa.pitch * track->cb[0].cpp * track->maxy; + size += track->aa.offset; + if (size > radeon_bo_size(track->aa.robj)) { + DRM_ERROR("[drm] Buffer too small for AA resolve buffer %d " + "(need %lu have %lu) !\n", i, size, + radeon_bo_size(track->aa.robj)); + DRM_ERROR("[drm] AA resolve buffer %d (%u %u %u %u)\n", + i, track->aa.pitch, track->cb[0].cpp, + track->aa.offset, track->maxy); + return -EINVAL; + } + } + track->aa_dirty = false; + prim_walk = (track->vap_vf_cntl >> 4) & 0x3; if (track->vap_vf_cntl & (1 << 14)) { nverts = track->vap_alt_nverts; @@ -3455,6 +3475,7 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track track->cb_dirty = true; track->zb_dirty = true; track->tex_dirty = true; + track->aa_dirty = true; if (rdev->family < CHIP_R300) { track->num_cb = 1; @@ -3469,6 +3490,8 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track track->num_texture = 16; track->maxy = 4096; track->separate_cube = 0; + track->aaresolve = true; + track->aa.robj = NULL; } for (i = 0; i < track->num_cb; i++) { diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h index ee85c4a1fc08..2fef9de7f363 100644 --- a/drivers/gpu/drm/radeon/r100_track.h +++ b/drivers/gpu/drm/radeon/r100_track.h @@ -66,15 +66,17 @@ struct r100_cs_track { struct r100_cs_track_array arrays[11]; struct r100_cs_track_cb cb[R300_MAX_CB]; struct r100_cs_track_cb zb; + struct r100_cs_track_cb aa; struct r100_cs_track_texture textures[R300_TRACK_MAX_TEXTURE]; bool z_enabled; bool separate_cube; bool zb_cb_clear; bool blend_read_enable; - bool cb_dirty; bool zb_dirty; bool tex_dirty; + bool aa_dirty; + bool aaresolve; }; int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track); diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 862b61742b82..768c60ee4ab6 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -1104,6 +1104,27 @@ static int r300_packet0_check(struct radeon_cs_parser *p, track->blend_read_enable = !!(idx_value & (1 << 2)); track->cb_dirty = true; break; + case R300_RB3D_AARESOLVE_OFFSET: + r = r100_cs_packet_next_reloc(p, &reloc); + if (r) { + DRM_ERROR("No reloc for ib[%d]=0x%04X\n", + idx, reg); + r100_cs_dump_packet(p, pkt); + return r; + } + track->aa.robj = reloc->robj; + track->aa.offset = idx_value; + track->aa_dirty = true; + ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); + break; + case R300_RB3D_AARESOLVE_PITCH: + track->aa.pitch = idx_value & 0x3FFE; + track->aa_dirty = true; + break; + case R300_RB3D_AARESOLVE_CTL: + track->aaresolve = idx_value & 0x1; + track->aa_dirty = true; + break; case 0x4f30: /* ZB_MASK_OFFSET */ case 0x4f34: /* ZB_ZMASK_PITCH */ case 0x4f44: /* ZB_HIZ_OFFSET */ diff --git a/drivers/gpu/drm/radeon/r300_reg.h b/drivers/gpu/drm/radeon/r300_reg.h index 1a0d5362cd79..f0bce399c9f3 100644 --- a/drivers/gpu/drm/radeon/r300_reg.h +++ b/drivers/gpu/drm/radeon/r300_reg.h @@ -1371,6 +1371,8 @@ #define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */ #define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */ +#define R300_RB3D_AARESOLVE_OFFSET 0x4E80 +#define R300_RB3D_AARESOLVE_PITCH 0x4E84 #define R300_RB3D_AARESOLVE_CTL 0x4E88 /* gap */ diff --git a/drivers/gpu/drm/radeon/reg_srcs/r300 b/drivers/gpu/drm/radeon/reg_srcs/r300 index 13a94e2ee03b..e8a1786b6426 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r300 +++ b/drivers/gpu/drm/radeon/reg_srcs/r300 @@ -704,9 +704,6 @@ r300 0x4f60 0x4E74 RB3D_CMASK_WRINDEX 0x4E78 RB3D_CMASK_DWORD 0x4E7C RB3D_CMASK_RDINDEX -0x4E80 RB3D_AARESOLVE_OFFSET -0x4E84 RB3D_AARESOLVE_PITCH -0x4E88 RB3D_AARESOLVE_CTL 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD 0x4F04 ZB_ZSTENCILCNTL diff --git a/drivers/gpu/drm/radeon/reg_srcs/r420 b/drivers/gpu/drm/radeon/reg_srcs/r420 index 5c95cf87f7f2..722074e21e2f 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r420 +++ b/drivers/gpu/drm/radeon/reg_srcs/r420 @@ -770,9 +770,6 @@ r420 0x4f60 0x4E74 RB3D_CMASK_WRINDEX 0x4E78 RB3D_CMASK_DWORD 0x4E7C RB3D_CMASK_RDINDEX -0x4E80 RB3D_AARESOLVE_OFFSET -0x4E84 RB3D_AARESOLVE_PITCH -0x4E88 RB3D_AARESOLVE_CTL 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD 0x4F04 ZB_ZSTENCILCNTL diff --git a/drivers/gpu/drm/radeon/reg_srcs/rs600 b/drivers/gpu/drm/radeon/reg_srcs/rs600 index 263109c1d0c8..d9f62866bbc1 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rs600 +++ b/drivers/gpu/drm/radeon/reg_srcs/rs600 @@ -770,9 +770,6 @@ rs600 0x6d40 0x4E74 RB3D_CMASK_WRINDEX 0x4E78 RB3D_CMASK_DWORD 0x4E7C RB3D_CMASK_RDINDEX -0x4E80 RB3D_AARESOLVE_OFFSET -0x4E84 RB3D_AARESOLVE_PITCH -0x4E88 RB3D_AARESOLVE_CTL 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD 0x4F04 ZB_ZSTENCILCNTL diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515 index eeed003f14c7..911a8fbd32bb 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rv515 +++ b/drivers/gpu/drm/radeon/reg_srcs/rv515 @@ -481,9 +481,6 @@ rv515 0x6d40 0x4E74 RB3D_CMASK_WRINDEX 0x4E78 RB3D_CMASK_DWORD 0x4E7C RB3D_CMASK_RDINDEX -0x4E80 RB3D_AARESOLVE_OFFSET -0x4E84 RB3D_AARESOLVE_PITCH -0x4E88 RB3D_AARESOLVE_CTL 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD 0x4EF8 RB3D_CONSTANT_COLOR_AR -- cgit v1.2.3 From c2049b3d29f47ed3750226dc51251a3404c85876 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sun, 13 Feb 2011 18:42:41 -0500 Subject: drm/radeon/kms: improve 6xx/7xx CS error output Makes debugging CS rejections much easier. Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600_cs.c | 46 +++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 7831e0890210..153095fba62f 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -295,17 +295,18 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) } if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", - __func__, __LINE__, pitch); + dev_warn(p->dev, "%s:%d cb pitch (%d, 0x%x, %d) invalid\n", + __func__, __LINE__, pitch, pitch_align, array_mode); return -EINVAL; } if (!IS_ALIGNED(height, height_align)) { - dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", - __func__, __LINE__, height); + dev_warn(p->dev, "%s:%d cb height (%d, 0x%x, %d) invalid\n", + __func__, __LINE__, height, height_align, array_mode); return -EINVAL; } if (!IS_ALIGNED(base_offset, base_align)) { - dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset); + dev_warn(p->dev, "%s offset[%d] 0x%llx 0x%llx, %d not aligned\n", __func__, i, + base_offset, base_align, array_mode); return -EINVAL; } @@ -320,7 +321,10 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) * broken userspace. */ } else { - dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i])); + dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big\n", __func__, i, + array_mode, + track->cb_color_bo_offset[i], tmp, + radeon_bo_size(track->cb_color_bo[i])); return -EINVAL; } } @@ -455,17 +459,18 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) } if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n", - __func__, __LINE__, pitch); + dev_warn(p->dev, "%s:%d db pitch (%d, 0x%x, %d) invalid\n", + __func__, __LINE__, pitch, pitch_align, array_mode); return -EINVAL; } if (!IS_ALIGNED(height, height_align)) { - dev_warn(p->dev, "%s:%d db height (%d) invalid\n", - __func__, __LINE__, height); + dev_warn(p->dev, "%s:%d db height (%d, 0x%x, %d) invalid\n", + __func__, __LINE__, height, height_align, array_mode); return -EINVAL; } if (!IS_ALIGNED(base_offset, base_align)) { - dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset); + dev_warn(p->dev, "%s offset[%d] 0x%llx, 0x%llx, %d not aligned\n", __func__, i, + base_offset, base_align, array_mode); return -EINVAL; } @@ -473,9 +478,10 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; tmp = ntiles * bpe * 64 * nviews; if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { - dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %u have %lu)\n", - track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset, - radeon_bo_size(track->db_bo)); + dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n", + array_mode, + track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset, + radeon_bo_size(track->db_bo)); return -EINVAL; } } @@ -1227,18 +1233,18 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i /* XXX check height as well... */ if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", - __func__, __LINE__, pitch); + dev_warn(p->dev, "%s:%d tex pitch (%d, 0x%x, %d) invalid\n", + __func__, __LINE__, pitch, pitch_align, G_038000_TILE_MODE(word0)); return -EINVAL; } if (!IS_ALIGNED(base_offset, base_align)) { - dev_warn(p->dev, "%s:%d tex base offset (0x%llx) invalid\n", - __func__, __LINE__, base_offset); + dev_warn(p->dev, "%s:%d tex base offset (0x%llx, 0x%llx, %d) invalid\n", + __func__, __LINE__, base_offset, base_align, G_038000_TILE_MODE(word0)); return -EINVAL; } if (!IS_ALIGNED(mip_offset, base_align)) { - dev_warn(p->dev, "%s:%d tex mip offset (0x%llx) invalid\n", - __func__, __LINE__, mip_offset); + dev_warn(p->dev, "%s:%d tex mip offset (0x%llx, 0x%llx, %d) invalid\n", + __func__, __LINE__, mip_offset, base_align, G_038000_TILE_MODE(word0)); return -EINVAL; } -- cgit v1.2.3 From c978e7bb77dfd2cd3d1f547fa4e395cfe47f02b2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 13 Feb 2011 16:50:45 -0800 Subject: hisax: Fix unchecked alloc_skb() return. Jesper Juhl noticed that l2_pull_iqueue() does not check to see if alloc_skb() fails. Fix this by first trying to reallocate the headroom if necessary, rather than later after we've made hard to undo state changes. Reported-by: Jesper Juhl Signed-off-by: David S. Miller --- drivers/isdn/hisax/isdnl2.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c index 0858791978d8..98ac835281fe 100644 --- a/drivers/isdn/hisax/isdnl2.c +++ b/drivers/isdn/hisax/isdnl2.c @@ -1243,14 +1243,21 @@ l2_st7_tout_203(struct FsmInst *fi, int event, void *arg) st->l2.rc = 0; } +static int l2_hdr_space_needed(struct Layer2 *l2) +{ + int len = test_bit(FLG_LAPD, &l2->flag) ? 2 : 1; + + return len + (test_bit(FLG_LAPD, &l2->flag) ? 2 : 1); +} + static void l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; - struct sk_buff *skb, *oskb; + struct sk_buff *skb; struct Layer2 *l2 = &st->l2; u_char header[MAX_HEADER_LEN]; - int i; + int i, hdr_space_needed; int unsigned p1; u_long flags; @@ -1261,6 +1268,16 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) if (!skb) return; + hdr_space_needed = l2_hdr_space_needed(l2); + if (hdr_space_needed > skb_headroom(skb)) { + struct sk_buff *orig_skb = skb; + + skb = skb_realloc_headroom(skb, hdr_space_needed); + if (!skb) { + dev_kfree_skb(orig_skb); + return; + } + } spin_lock_irqsave(&l2->lock, flags); if(test_bit(FLG_MOD128, &l2->flag)) p1 = (l2->vs - l2->va) % 128; @@ -1285,19 +1302,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) l2->vs = (l2->vs + 1) % 8; } spin_unlock_irqrestore(&l2->lock, flags); - p1 = skb->data - skb->head; - if (p1 >= i) - memcpy(skb_push(skb, i), header, i); - else { - printk(KERN_WARNING - "isdl2 pull_iqueue skb header(%d/%d) too short\n", i, p1); - oskb = skb; - skb = alloc_skb(oskb->len + i, GFP_ATOMIC); - memcpy(skb_put(skb, i), header, i); - skb_copy_from_linear_data(oskb, - skb_put(skb, oskb->len), oskb->len); - dev_kfree_skb(oskb); - } + memcpy(skb_push(skb, i), header, i); st->l2.l2l1(st, PH_PULL | INDICATION, skb); test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); if (!test_and_set_bit(FLG_T200_RUN, &st->l2.flag)) { -- cgit v1.2.3 From 5b89db0e84bef81f6aa324f8f22a9258ff873de3 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 13 Feb 2011 11:15:35 +0000 Subject: Net, USB, Option, hso: Do not dereference NULL pointer In drivers/net/usb/hso.c::hso_create_bulk_serial_device() we have this code: ... serial = kzalloc(sizeof(*serial), GFP_KERNEL); if (!serial) goto exit; ... exit: hso_free_tiomget(serial); ... hso_free_tiomget() directly dereferences its argument, which in the example above is a NULL pointer, ouch. I could just add a 'if (serial)' test at the 'exit' label, but since most freeing functions in the kernel accept NULL pointers (and it seems like this was also assumed here) I opted to instead change 'hso_free_tiomget()' so that it is safe to call it with a NULL argument. I also modified the function to get rid of a pointles conditional before the call to 'usb_free_urb()' since that function already tests for NULL itself - besides fixing the NULL deref this change also buys us a few bytes in size. Before: $ size drivers/net/usb/hso.o text data bss dec hex filename 32200 592 9960 42752 a700 drivers/net/usb/hso.o After: $ size drivers/net/usb/hso.o text data bss dec hex filename 32196 592 9960 42748 a6fc drivers/net/usb/hso.o Signed-off-by: Jesper Juhl Signed-off-by: David S. Miller --- drivers/net/usb/hso.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index bed8fcedff49..6d83812603b6 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2628,15 +2628,15 @@ exit: static void hso_free_tiomget(struct hso_serial *serial) { - struct hso_tiocmget *tiocmget = serial->tiocmget; + struct hso_tiocmget *tiocmget; + if (!serial) + return; + tiocmget = serial->tiocmget; if (tiocmget) { - if (tiocmget->urb) { - usb_free_urb(tiocmget->urb); - tiocmget->urb = NULL; - } + usb_free_urb(tiocmget->urb); + tiocmget->urb = NULL; serial->tiocmget = NULL; kfree(tiocmget); - } } -- cgit v1.2.3 From da1ab3e233eb1ff4116b178006a89ddca7dcd928 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 13 Feb 2011 10:49:32 +0000 Subject: ATM, Solos PCI ADSL2+: Don't deref NULL pointer if net_ratelimit() and alloc_skb() interact badly. If alloc_skb() fails to allocate memory and returns NULL then we want to return -ENOMEM from drivers/atm/solos-pci.c::popen() regardless of the value of net_ratelimit(). The way the code is today, we may not return if net_ratelimit() returns 0, then we'll proceed to pass a NULL pointer to skb_put() which will blow up in our face. This patch ensures that we always return -ENOMEM on alloc_skb() failure and only let the dev_warn() be controlled by the value of net_ratelimit(). Signed-off-by: Jesper Juhl Signed-off-by: David S. Miller --- drivers/atm/solos-pci.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index 73fb1c4f4cd4..25ef1a4556e6 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -866,8 +866,9 @@ static int popen(struct atm_vcc *vcc) } skb = alloc_skb(sizeof(*header), GFP_ATOMIC); - if (!skb && net_ratelimit()) { - dev_warn(&card->dev->dev, "Failed to allocate sk_buff in popen()\n"); + if (!skb) { + if (net_ratelimit()) + dev_warn(&card->dev->dev, "Failed to allocate sk_buff in popen()\n"); return -ENOMEM; } header = (void *)skb_put(skb, sizeof(*header)); -- cgit v1.2.3 From 9232ecca3ecd2e32140118c8fdabd7f8fb9ef4d5 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Sun, 13 Feb 2011 09:33:01 +0000 Subject: bond: implement [add/del]_slave ops allow enslaving/releasing using netlink interface Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 9f877878d636..77e3c6a7176a 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4657,6 +4657,8 @@ static const struct net_device_ops bond_netdev_ops = { .ndo_netpoll_cleanup = bond_netpoll_cleanup, .ndo_poll_controller = bond_poll_controller, #endif + .ndo_add_slave = bond_enslave, + .ndo_del_slave = bond_release, }; static void bond_destructor(struct net_device *bond_dev) -- cgit v1.2.3 From 539c9aa5ba7c5f71794ef0948c6dd29552f033e4 Mon Sep 17 00:00:00 2001 From: Giuseppe Cavallaro Date: Sun, 13 Feb 2011 17:00:05 -0800 Subject: stmmac: enable wol via magic frame by default. This patch enables it by default when the driver starts. This has been required by many people and seems to actually be useful on STB. At any rate, the WoL modes can be selected and turned-on/off by using the ethtool at run-time by users. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index 34a0af3837f9..0e5f03135b50 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -1560,8 +1560,10 @@ static int stmmac_mac_device_setup(struct net_device *dev) priv->hw = device; - if (device_can_wakeup(priv->device)) + if (device_can_wakeup(priv->device)) { priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */ + enable_irq_wake(dev->irq); + } return 0; } -- cgit v1.2.3 From 19d96017d1b5b1c9b709bc21a398ea793256644c Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Sun, 13 Feb 2011 18:27:34 +0000 Subject: jme: Extract main and sub chip revision Get the main and sub chip revision for later workaround use. Signed-off-by: Guo-Fu Tseng Signed-off-by: David S. Miller --- drivers/net/jme.c | 8 +++++--- drivers/net/jme.h | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/jme.c b/drivers/net/jme.c index e97ebef3cf47..d44716e804b6 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -2731,6 +2731,8 @@ jme_check_hw_ver(struct jme_adapter *jme) jme->fpgaver = (chipmode & CM_FPGAVER_MASK) >> CM_FPGAVER_SHIFT; jme->chiprev = (chipmode & CM_CHIPREV_MASK) >> CM_CHIPREV_SHIFT; + jme->chip_main_rev = jme->chiprev & 0xF; + jme->chip_sub_rev = (jme->chiprev >> 4) & 0xF; } static const struct net_device_ops jme_netdev_ops = { @@ -2937,7 +2939,7 @@ jme_init_one(struct pci_dev *pdev, jme_clear_pm(jme); jme_set_phyfifoa(jme); - pci_read_config_byte(pdev, PCI_REVISION_ID, &jme->rev); + pci_read_config_byte(pdev, PCI_REVISION_ID, &jme->pcirev); if (!jme->fpgaver) jme_phy_init(jme); jme_phy_off(jme); @@ -2964,14 +2966,14 @@ jme_init_one(struct pci_dev *pdev, goto err_out_unmap; } - netif_info(jme, probe, jme->dev, "%s%s ver:%x rev:%x macaddr:%pM\n", + netif_info(jme, probe, jme->dev, "%s%s chiprev:%x pcirev:%x macaddr:%pM\n", (jme->pdev->device == PCI_DEVICE_ID_JMICRON_JMC250) ? "JMC250 Gigabit Ethernet" : (jme->pdev->device == PCI_DEVICE_ID_JMICRON_JMC260) ? "JMC260 Fast Ethernet" : "Unknown", (jme->fpgaver != 0) ? " (FPGA)" : "", (jme->fpgaver != 0) ? jme->fpgaver : jme->chiprev, - jme->rev, netdev->dev_addr); + jme->pcirev, netdev->dev_addr); return 0; diff --git a/drivers/net/jme.h b/drivers/net/jme.h index eac09264bf2a..32b2a9ddbcd6 100644 --- a/drivers/net/jme.h +++ b/drivers/net/jme.h @@ -411,8 +411,10 @@ struct jme_adapter { u32 rx_ring_mask; u8 mrrs; unsigned int fpgaver; - unsigned int chiprev; - u8 rev; + u8 chiprev; + u8 chip_main_rev; + u8 chip_sub_rev; + u8 pcirev; u32 msg_enable; struct ethtool_cmd old_ecmd; unsigned int old_mtu; @@ -1184,7 +1186,7 @@ enum jme_phy_reg17_vals { /* * Workaround */ -static inline int is_buggy250(unsigned short device, unsigned int chiprev) +static inline int is_buggy250(unsigned short device, u8 chiprev) { return device == PCI_DEVICE_ID_JMICRON_JMC250 && chiprev == 0x11; } -- cgit v1.2.3 From 4872b11fdbbf78665230b2bb5864b1611dcb4a25 Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Sun, 13 Feb 2011 18:27:35 +0000 Subject: jme: PHY Power control for new chip After main chip rev 5, the hardware support more power saving control registers. Some Non-Linux drivers might turn off the phy power with new interfaces, this patch makes it possible for Linux to turn it on again. Signed-off-by: Guo-Fu Tseng Signed-off-by: David S. Miller --- drivers/net/jme.c | 68 +++++++++++++++++++++++++++++++++++++++++++------------ drivers/net/jme.h | 52 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/jme.c b/drivers/net/jme.c index d44716e804b6..d446fdb89f68 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -1576,6 +1576,38 @@ jme_free_irq(struct jme_adapter *jme) } } +static inline void +jme_new_phy_on(struct jme_adapter *jme) +{ + u32 reg; + + reg = jread32(jme, JME_PHY_PWR); + reg &= ~(PHY_PWR_DWN1SEL | PHY_PWR_DWN1SW | + PHY_PWR_DWN2 | PHY_PWR_CLKSEL); + jwrite32(jme, JME_PHY_PWR, reg); + + pci_read_config_dword(jme->pdev, PCI_PRIV_PE1, ®); + reg &= ~PE1_GPREG0_PBG; + reg |= PE1_GPREG0_ENBG; + pci_write_config_dword(jme->pdev, PCI_PRIV_PE1, reg); +} + +static inline void +jme_new_phy_off(struct jme_adapter *jme) +{ + u32 reg; + + reg = jread32(jme, JME_PHY_PWR); + reg |= PHY_PWR_DWN1SEL | PHY_PWR_DWN1SW | + PHY_PWR_DWN2 | PHY_PWR_CLKSEL; + jwrite32(jme, JME_PHY_PWR, reg); + + pci_read_config_dword(jme->pdev, PCI_PRIV_PE1, ®); + reg &= ~PE1_GPREG0_PBG; + reg |= PE1_GPREG0_PDD3COLD; + pci_write_config_dword(jme->pdev, PCI_PRIV_PE1, reg); +} + static inline void jme_phy_on(struct jme_adapter *jme) { @@ -1584,6 +1616,22 @@ jme_phy_on(struct jme_adapter *jme) bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR); bmcr &= ~BMCR_PDOWN; jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, bmcr); + + if (new_phy_power_ctrl(jme->chip_main_rev)) + jme_new_phy_on(jme); +} + +static inline void +jme_phy_off(struct jme_adapter *jme) +{ + u32 bmcr; + + bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR); + bmcr |= BMCR_PDOWN; + jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, bmcr); + + if (new_phy_power_ctrl(jme->chip_main_rev)) + jme_new_phy_off(jme); } static int @@ -1606,12 +1654,11 @@ jme_open(struct net_device *netdev) jme_start_irq(jme); - if (test_bit(JME_FLAG_SSET, &jme->flags)) { - jme_phy_on(jme); + jme_phy_on(jme); + if (test_bit(JME_FLAG_SSET, &jme->flags)) jme_set_settings(netdev, &jme->old_ecmd); - } else { + else jme_reset_phy_processor(jme); - } jme_reset_link(jme); @@ -1657,12 +1704,6 @@ jme_wait_link(struct jme_adapter *jme) } } -static inline void -jme_phy_off(struct jme_adapter *jme) -{ - jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, BMCR_PDOWN); -} - static void jme_powersave_phy(struct jme_adapter *jme) { @@ -3068,12 +3109,11 @@ jme_resume(struct pci_dev *pdev) jme_clear_pm(jme); pci_restore_state(pdev); - if (test_bit(JME_FLAG_SSET, &jme->flags)) { - jme_phy_on(jme); + jme_phy_on(jme); + if (test_bit(JME_FLAG_SSET, &jme->flags)) jme_set_settings(netdev, &jme->old_ecmd); - } else { + else jme_reset_phy_processor(jme); - } jme_start_irq(jme); netif_device_attach(netdev); diff --git a/drivers/net/jme.h b/drivers/net/jme.h index 32b2a9ddbcd6..c3764fc151c9 100644 --- a/drivers/net/jme.h +++ b/drivers/net/jme.h @@ -103,6 +103,37 @@ enum jme_spi_op_bits { #define HALF_US 500 /* 500 ns */ #define JMESPIIOCTL SIOCDEVPRIVATE +#define PCI_PRIV_PE1 0xE4 + +enum pci_priv_pe1_bit_masks { + PE1_ASPMSUPRT = 0x00000003, /* + * RW: + * Aspm_support[1:0] + * (R/W Port of 5C[11:10]) + */ + PE1_MULTIFUN = 0x00000004, /* RW: Multi_fun_bit */ + PE1_RDYDMA = 0x00000008, /* RO: ~link.rdy_for_dma */ + PE1_ASPMOPTL = 0x00000030, /* RW: link.rx10s_option[1:0] */ + PE1_ASPMOPTH = 0x000000C0, /* RW: 10_req=[3]?HW:[2] */ + PE1_GPREG0 = 0x0000FF00, /* + * SRW: + * Cfg_gp_reg0 + * [7:6] phy_giga BG control + * [5] CREQ_N as CREQ_N1 (CPPE# as CREQ#) + * [4:0] Reserved + */ + PE1_GPREG0_PBG = 0x0000C000, /* phy_giga BG control */ + PE1_GPREG1 = 0x00FF0000, /* RW: Cfg_gp_reg1 */ + PE1_REVID = 0xFF000000, /* RO: Rev ID */ +}; + +enum pci_priv_pe1_values { + PE1_GPREG0_ENBG = 0x00000000, /* en BG */ + PE1_GPREG0_PDD3COLD = 0x00004000, /* giga_PD + d3cold */ + PE1_GPREG0_PDPCIESD = 0x00008000, /* giga_PD + pcie_shutdown */ + PE1_GPREG0_PDPCIEIDDQ = 0x0000C000, /* giga_PD + pcie_iddq */ +}; + /* * Dynamic(adaptive)/Static PCC values */ @@ -499,6 +530,7 @@ enum jme_iomap_regs { JME_PMCS = JME_MAC | 0x60, /* Power Management Control/Stat */ + JME_PHY_PWR = JME_PHY | 0x24, /* New PHY Power Ctrl Register */ JME_PHY_CS = JME_PHY | 0x28, /* PHY Ctrl and Status Register */ JME_PHY_LINK = JME_PHY | 0x30, /* PHY Link Status Register */ JME_SMBCSR = JME_PHY | 0x40, /* SMB Control and Status */ @@ -834,6 +866,21 @@ enum jme_pmcs_bit_masks { PMCS_MFEN = 0x00000001, }; +/* + * New PHY Power Control Register + */ +enum jme_phy_pwr_bit_masks { + PHY_PWR_DWN1SEL = 0x01000000, /* Phy_giga.p_PWR_DOWN1_SEL */ + PHY_PWR_DWN1SW = 0x02000000, /* Phy_giga.p_PWR_DOWN1_SW */ + PHY_PWR_DWN2 = 0x04000000, /* Phy_giga.p_PWR_DOWN2 */ + PHY_PWR_CLKSEL = 0x08000000, /* + * XTL_OUT Clock select + * (an internal free-running clock) + * 0: xtl_out = phy_giga.A_XTL25_O + * 1: xtl_out = phy_giga.PD_OSC + */ +}; + /* * Giga PHY Status Registers */ @@ -1191,6 +1238,11 @@ static inline int is_buggy250(unsigned short device, u8 chiprev) return device == PCI_DEVICE_ID_JMICRON_JMC250 && chiprev == 0x11; } +static inline int new_phy_power_ctrl(u8 chip_main_rev) +{ + return chip_main_rev >= 5; +} + /* * Function prototypes */ -- cgit v1.2.3 From 3c2368d96fd9a5828b260dfec59ae9a5352cd598 Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Sun, 13 Feb 2011 18:27:36 +0000 Subject: jme: Fix bit typo of JMC250A2 workaround Signed-off-by: Guo-Fu Tseng Signed-off-by: David S. Miller --- drivers/net/jme.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/jme.h b/drivers/net/jme.h index c3764fc151c9..dc4af5753a9e 100644 --- a/drivers/net/jme.h +++ b/drivers/net/jme.h @@ -1000,8 +1000,8 @@ enum jme_gpreg1_masks { }; enum jme_gpreg1_vals { - GPREG1_RSSPATCH = 0x00000040, - GPREG1_HALFMODEPATCH = 0x00000020, + GPREG1_HALFMODEPATCH = 0x00000040, + GPREG1_RSSPATCH = 0x00000020, GPREG1_INTDLYUNIT_16NS = 0x00000000, GPREG1_INTDLYUNIT_256NS = 0x00000008, -- cgit v1.2.3 From 51754572371491b63f70aae41dab70dfcaf771b2 Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Sun, 13 Feb 2011 18:27:37 +0000 Subject: jme: Rename phyfifo function for easier understand Signed-off-by: Guo-Fu Tseng Signed-off-by: David S. Miller --- drivers/net/jme.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/jme.c b/drivers/net/jme.c index d446fdb89f68..490bc0feff3d 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -336,13 +336,13 @@ jme_linkstat_from_phy(struct jme_adapter *jme) } static inline void -jme_set_phyfifoa(struct jme_adapter *jme) +jme_set_phyfifo_5level(struct jme_adapter *jme) { jme_mdio_write(jme->dev, jme->mii_if.phy_id, 27, 0x0004); } static inline void -jme_set_phyfifob(struct jme_adapter *jme) +jme_set_phyfifo_8level(struct jme_adapter *jme) { jme_mdio_write(jme->dev, jme->mii_if.phy_id, 27, 0x0000); } @@ -457,15 +457,15 @@ jme_check_link(struct net_device *netdev, int testonly) gpreg1 |= GPREG1_HALFMODEPATCH; switch (phylink & PHY_LINK_SPEED_MASK) { case PHY_LINK_SPEED_10M: - jme_set_phyfifoa(jme); + jme_set_phyfifo_8level(jme); gpreg1 |= GPREG1_RSSPATCH; break; case PHY_LINK_SPEED_100M: - jme_set_phyfifob(jme); + jme_set_phyfifo_5level(jme); gpreg1 |= GPREG1_RSSPATCH; break; case PHY_LINK_SPEED_1000M: - jme_set_phyfifoa(jme); + jme_set_phyfifo_8level(jme); break; default: break; @@ -2979,7 +2979,7 @@ jme_init_one(struct pci_dev *pdev, jme->mii_if.mdio_write = jme_mdio_write; jme_clear_pm(jme); - jme_set_phyfifoa(jme); + jme_set_phyfifo_5level(jme); pci_read_config_byte(pdev, PCI_REVISION_ID, &jme->pcirev); if (!jme->fpgaver) jme_phy_init(jme); -- cgit v1.2.3 From 3903c023570446303a10f152cfc120dcbf9a4ccf Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Sun, 13 Feb 2011 18:27:38 +0000 Subject: jme: Fix hardware action of full-duplex Clear Transmit Timer/Retry setting while full-duplex. Signed-off-by: Guo-Fu Tseng Signed-off-by: David S. Miller --- drivers/net/jme.c | 6 ++---- drivers/net/jme.h | 8 ++++++++ 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 490bc0feff3d..6996d04e1de4 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -439,16 +439,14 @@ jme_check_link(struct net_device *netdev, int testonly) if (phylink & PHY_LINK_DUPLEX) { jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT); + jwrite32(jme, JME_TXTRHD, TXTRHD_FULLDUPLEX); ghc |= GHC_DPX; } else { jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT | TXMCS_BACKOFF | TXMCS_CARRIERSENSE | TXMCS_COLLISION); - jwrite32(jme, JME_TXTRHD, TXTRHD_TXPEN | - ((0x2000 << TXTRHD_TXP_SHIFT) & TXTRHD_TXP) | - TXTRHD_TXREN | - ((8 << TXTRHD_TXRL_SHIFT) & TXTRHD_TXRL)); + jwrite32(jme, JME_TXTRHD, TXTRHD_HALFDUPLEX); } gpreg1 = GPREG1_DEFAULT; diff --git a/drivers/net/jme.h b/drivers/net/jme.h index dc4af5753a9e..b33bc5b0bb4e 100644 --- a/drivers/net/jme.h +++ b/drivers/net/jme.h @@ -658,6 +658,14 @@ enum jme_txtrhd_shifts { TXTRHD_TXRL_SHIFT = 0, }; +enum jme_txtrhd_values { + TXTRHD_FULLDUPLEX = 0x00000000, + TXTRHD_HALFDUPLEX = TXTRHD_TXPEN | + ((0x2000 << TXTRHD_TXP_SHIFT) & TXTRHD_TXP) | + TXTRHD_TXREN | + ((8 << TXTRHD_TXRL_SHIFT) & TXTRHD_TXRL), +}; + /* * RX Control/Status Bits */ -- cgit v1.2.3 From 854a2e7c331a36244169626ba8e11e15d134cb5f Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Sun, 13 Feb 2011 18:27:39 +0000 Subject: jme: Safer MAC processor reset sequence Adding control to clk_rx, and makes the control of clk_{rx|tx|tcp} with safer sequence. This sequence is provided by JMicron. Signed-off-by: Guo-Fu Tseng Signed-off-by: David S. Miller --- drivers/net/jme.c | 152 +++++++++++++++++++++++++++++++++++++++++------------- drivers/net/jme.h | 16 +++--- 2 files changed, 126 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 6996d04e1de4..dd4132443b7b 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -160,6 +160,67 @@ jme_setup_wakeup_frame(struct jme_adapter *jme, } } +static inline void +jme_mac_rxclk_off(struct jme_adapter *jme) +{ + jme->reg_gpreg1 |= GPREG1_RXCLKOFF; + jwrite32f(jme, JME_GPREG1, jme->reg_gpreg1); +} + +static inline void +jme_mac_rxclk_on(struct jme_adapter *jme) +{ + jme->reg_gpreg1 &= ~GPREG1_RXCLKOFF; + jwrite32f(jme, JME_GPREG1, jme->reg_gpreg1); +} + +static inline void +jme_mac_txclk_off(struct jme_adapter *jme) +{ + jme->reg_ghc &= ~(GHC_TO_CLK_SRC | GHC_TXMAC_CLK_SRC); + jwrite32f(jme, JME_GHC, jme->reg_ghc); +} + +static inline void +jme_mac_txclk_on(struct jme_adapter *jme) +{ + u32 speed = jme->reg_ghc & GHC_SPEED; + if (speed == GHC_SPEED_1000M) + jme->reg_ghc |= GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY; + else + jme->reg_ghc |= GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE; + jwrite32f(jme, JME_GHC, jme->reg_ghc); +} + +static inline void +jme_reset_ghc_speed(struct jme_adapter *jme) +{ + jme->reg_ghc &= ~(GHC_SPEED | GHC_DPX); + jwrite32f(jme, JME_GHC, jme->reg_ghc); +} + +static inline void +jme_reset_250A2_workaround(struct jme_adapter *jme) +{ + jme->reg_gpreg1 &= ~(GPREG1_HALFMODEPATCH | + GPREG1_RSSPATCH); + jwrite32(jme, JME_GPREG1, jme->reg_gpreg1); +} + +static inline void +jme_assert_ghc_reset(struct jme_adapter *jme) +{ + jme->reg_ghc |= GHC_SWRST; + jwrite32f(jme, JME_GHC, jme->reg_ghc); +} + +static inline void +jme_clear_ghc_reset(struct jme_adapter *jme) +{ + jme->reg_ghc &= ~GHC_SWRST; + jwrite32f(jme, JME_GHC, jme->reg_ghc); +} + static inline void jme_reset_mac_processor(struct jme_adapter *jme) { @@ -168,9 +229,24 @@ jme_reset_mac_processor(struct jme_adapter *jme) u32 gpreg0; int i; - jwrite32(jme, JME_GHC, jme->reg_ghc | GHC_SWRST); - udelay(2); - jwrite32(jme, JME_GHC, jme->reg_ghc); + jme_reset_ghc_speed(jme); + jme_reset_250A2_workaround(jme); + + jme_mac_rxclk_on(jme); + jme_mac_txclk_on(jme); + udelay(1); + jme_assert_ghc_reset(jme); + udelay(1); + jme_mac_rxclk_off(jme); + jme_mac_txclk_off(jme); + udelay(1); + jme_clear_ghc_reset(jme); + udelay(1); + jme_mac_rxclk_on(jme); + jme_mac_txclk_on(jme); + udelay(1); + jme_mac_rxclk_off(jme); + jme_mac_txclk_off(jme); jwrite32(jme, JME_RXDBA_LO, 0x00000000); jwrite32(jme, JME_RXDBA_HI, 0x00000000); @@ -190,14 +266,6 @@ jme_reset_mac_processor(struct jme_adapter *jme) else gpreg0 = GPREG0_DEFAULT; jwrite32(jme, JME_GPREG0, gpreg0); - jwrite32(jme, JME_GPREG1, GPREG1_DEFAULT); -} - -static inline void -jme_reset_ghc_speed(struct jme_adapter *jme) -{ - jme->reg_ghc &= ~(GHC_SPEED_1000M | GHC_DPX); - jwrite32(jme, JME_GHC, jme->reg_ghc); } static inline void @@ -351,7 +419,7 @@ static int jme_check_link(struct net_device *netdev, int testonly) { struct jme_adapter *jme = netdev_priv(netdev); - u32 phylink, ghc, cnt = JME_SPDRSV_TIMEOUT, bmcr, gpreg1; + u32 phylink, cnt = JME_SPDRSV_TIMEOUT, bmcr; char linkmsg[64]; int rc = 0; @@ -414,23 +482,21 @@ jme_check_link(struct net_device *netdev, int testonly) jme->phylink = phylink; - ghc = jme->reg_ghc & ~(GHC_SPEED | GHC_DPX | - GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE | - GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY); + /* + * The speed/duplex setting of jme->reg_ghc already cleared + * by jme_reset_mac_processor() + */ switch (phylink & PHY_LINK_SPEED_MASK) { case PHY_LINK_SPEED_10M: - ghc |= GHC_SPEED_10M | - GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE; + jme->reg_ghc |= GHC_SPEED_10M; strcat(linkmsg, "10 Mbps, "); break; case PHY_LINK_SPEED_100M: - ghc |= GHC_SPEED_100M | - GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE; + jme->reg_ghc |= GHC_SPEED_100M; strcat(linkmsg, "100 Mbps, "); break; case PHY_LINK_SPEED_1000M: - ghc |= GHC_SPEED_1000M | - GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY; + jme->reg_ghc |= GHC_SPEED_1000M; strcat(linkmsg, "1000 Mbps, "); break; default: @@ -440,7 +506,7 @@ jme_check_link(struct net_device *netdev, int testonly) if (phylink & PHY_LINK_DUPLEX) { jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT); jwrite32(jme, JME_TXTRHD, TXTRHD_FULLDUPLEX); - ghc |= GHC_DPX; + jme->reg_ghc |= GHC_DPX; } else { jwrite32(jme, JME_TXMCS, TXMCS_DEFAULT | TXMCS_BACKOFF | @@ -449,18 +515,21 @@ jme_check_link(struct net_device *netdev, int testonly) jwrite32(jme, JME_TXTRHD, TXTRHD_HALFDUPLEX); } - gpreg1 = GPREG1_DEFAULT; + jwrite32(jme, JME_GHC, jme->reg_ghc); + if (is_buggy250(jme->pdev->device, jme->chiprev)) { + jme->reg_gpreg1 &= ~(GPREG1_HALFMODEPATCH | + GPREG1_RSSPATCH); if (!(phylink & PHY_LINK_DUPLEX)) - gpreg1 |= GPREG1_HALFMODEPATCH; + jme->reg_gpreg1 |= GPREG1_HALFMODEPATCH; switch (phylink & PHY_LINK_SPEED_MASK) { case PHY_LINK_SPEED_10M: jme_set_phyfifo_8level(jme); - gpreg1 |= GPREG1_RSSPATCH; + jme->reg_gpreg1 |= GPREG1_RSSPATCH; break; case PHY_LINK_SPEED_100M: jme_set_phyfifo_5level(jme); - gpreg1 |= GPREG1_RSSPATCH; + jme->reg_gpreg1 |= GPREG1_RSSPATCH; break; case PHY_LINK_SPEED_1000M: jme_set_phyfifo_8level(jme); @@ -469,10 +538,7 @@ jme_check_link(struct net_device *netdev, int testonly) break; } } - - jwrite32(jme, JME_GPREG1, gpreg1); - jwrite32(jme, JME_GHC, ghc); - jme->reg_ghc = ghc; + jwrite32(jme, JME_GPREG1, jme->reg_gpreg1); strcat(linkmsg, (phylink & PHY_LINK_DUPLEX) ? "Full-Duplex, " : @@ -611,10 +677,14 @@ jme_enable_tx_engine(struct jme_adapter *jme) * Enable TX Engine */ wmb(); - jwrite32(jme, JME_TXCS, jme->reg_txcs | + jwrite32f(jme, JME_TXCS, jme->reg_txcs | TXCS_SELECT_QUEUE0 | TXCS_ENABLE); + /* + * Start clock for TX MAC Processor + */ + jme_mac_txclk_on(jme); } static inline void @@ -649,6 +719,11 @@ jme_disable_tx_engine(struct jme_adapter *jme) if (!i) pr_err("Disable TX engine timeout\n"); + + /* + * Stop clock for TX MAC Processor + */ + jme_mac_txclk_off(jme); } static void @@ -829,10 +904,15 @@ jme_enable_rx_engine(struct jme_adapter *jme) * Enable RX Engine */ wmb(); - jwrite32(jme, JME_RXCS, jme->reg_rxcs | + jwrite32f(jme, JME_RXCS, jme->reg_rxcs | RXCS_QUEUESEL_Q0 | RXCS_ENABLE | RXCS_QST); + + /* + * Start clock for RX MAC Processor + */ + jme_mac_rxclk_on(jme); } static inline void @@ -869,6 +949,10 @@ jme_disable_rx_engine(struct jme_adapter *jme) if (!i) pr_err("Disable RX engine timeout\n"); + /* + * Stop clock for RX MAC Processor + */ + jme_mac_rxclk_off(jme); } static int @@ -1205,7 +1289,6 @@ jme_link_change_tasklet(unsigned long arg) tasklet_disable(&jme->rxempty_task); if (netif_carrier_ok(netdev)) { - jme_reset_ghc_speed(jme); jme_disable_rx_engine(jme); jme_disable_tx_engine(jme); jme_reset_mac_processor(jme); @@ -1735,7 +1818,6 @@ jme_close(struct net_device *netdev) tasklet_disable(&jme->rxclean_task); tasklet_disable(&jme->rxempty_task); - jme_reset_ghc_speed(jme); jme_disable_rx_engine(jme); jme_disable_tx_engine(jme); jme_reset_mac_processor(jme); @@ -2921,6 +3003,7 @@ jme_init_one(struct pci_dev *pdev, jme->reg_rxmcs = RXMCS_DEFAULT; jme->reg_txpfc = 0; jme->reg_pmcs = PMCS_MFEN; + jme->reg_gpreg1 = GPREG1_DEFAULT; set_bit(JME_FLAG_TXCSUM, &jme->flags); set_bit(JME_FLAG_TSO, &jme->flags); @@ -3076,7 +3159,6 @@ jme_suspend(struct pci_dev *pdev, pm_message_t state) jme_polling_mode(jme); jme_stop_pcc_timer(jme); - jme_reset_ghc_speed(jme); jme_disable_rx_engine(jme); jme_disable_tx_engine(jme); jme_reset_mac_processor(jme); diff --git a/drivers/net/jme.h b/drivers/net/jme.h index b33bc5b0bb4e..668958c68f63 100644 --- a/drivers/net/jme.h +++ b/drivers/net/jme.h @@ -434,6 +434,7 @@ struct jme_adapter { u32 reg_rxmcs; u32 reg_ghc; u32 reg_pmcs; + u32 reg_gpreg1; u32 phylink; u32 tx_ring_size; u32 tx_ring_mask; @@ -821,6 +822,8 @@ static inline u32 smi_phy_addr(int x) */ enum jme_ghc_bit_mask { GHC_SWRST = 0x40000000, + GHC_TO_CLK_SRC = 0x00C00000, + GHC_TXMAC_CLK_SRC = 0x00300000, GHC_DPX = 0x00000040, GHC_SPEED = 0x00000030, GHC_LINK_POLL = 0x00000001, @@ -999,18 +1002,17 @@ enum jme_gpreg0_vals { /* * General Purpose REG-1 - * Note: All theses bits defined here are for - * Chip mode revision 0x11 only */ -enum jme_gpreg1_masks { +enum jme_gpreg1_bit_masks { + GPREG1_RXCLKOFF = 0x04000000, + GPREG1_PCREQN = 0x00020000, + GPREG1_HALFMODEPATCH = 0x00000040, /* For Chip revision 0x11 only */ + GPREG1_RSSPATCH = 0x00000020, /* For Chip revision 0x11 only */ GPREG1_INTRDELAYUNIT = 0x00000018, GPREG1_INTRDELAYENABLE = 0x00000007, }; enum jme_gpreg1_vals { - GPREG1_HALFMODEPATCH = 0x00000040, - GPREG1_RSSPATCH = 0x00000020, - GPREG1_INTDLYUNIT_16NS = 0x00000000, GPREG1_INTDLYUNIT_256NS = 0x00000008, GPREG1_INTDLYUNIT_1US = 0x00000010, @@ -1024,7 +1026,7 @@ enum jme_gpreg1_vals { GPREG1_INTDLYEN_6U = 0x00000006, GPREG1_INTDLYEN_7U = 0x00000007, - GPREG1_DEFAULT = 0x00000000, + GPREG1_DEFAULT = GPREG1_PCREQN, }; /* -- cgit v1.2.3 From 8b53abae582cee9a17320460e0f05474097192b6 Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Sun, 13 Feb 2011 18:27:40 +0000 Subject: jme: Refill receive unicase MAC addr after resume The value of the register which holds receive Unicast MAC Address sometimes get messed-up after resume. This patch refill it before enabling the hardware filter. Signed-off-by: Guo-Fu Tseng Signed-off-by: David S. Miller --- drivers/net/jme.c | 28 ++++++++++++++++++---------- drivers/net/jme.h | 1 + 2 files changed, 19 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/jme.c b/drivers/net/jme.c index dd4132443b7b..ed35e17f43dc 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -898,6 +898,7 @@ jme_enable_rx_engine(struct jme_adapter *jme) /* * Setup Unicast Filter */ + jme_set_unicastaddr(jme->dev); jme_set_multi(jme->dev); /* @@ -2114,27 +2115,34 @@ jme_start_xmit(struct sk_buff *skb, struct net_device *netdev) return NETDEV_TX_OK; } +static void +jme_set_unicastaddr(struct net_device *netdev) +{ + struct jme_adapter *jme = netdev_priv(netdev); + u32 val; + + val = (netdev->dev_addr[3] & 0xff) << 24 | + (netdev->dev_addr[2] & 0xff) << 16 | + (netdev->dev_addr[1] & 0xff) << 8 | + (netdev->dev_addr[0] & 0xff); + jwrite32(jme, JME_RXUMA_LO, val); + val = (netdev->dev_addr[5] & 0xff) << 8 | + (netdev->dev_addr[4] & 0xff); + jwrite32(jme, JME_RXUMA_HI, val); +} + static int jme_set_macaddr(struct net_device *netdev, void *p) { struct jme_adapter *jme = netdev_priv(netdev); struct sockaddr *addr = p; - u32 val; if (netif_running(netdev)) return -EBUSY; spin_lock_bh(&jme->macaddr_lock); memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); - - val = (addr->sa_data[3] & 0xff) << 24 | - (addr->sa_data[2] & 0xff) << 16 | - (addr->sa_data[1] & 0xff) << 8 | - (addr->sa_data[0] & 0xff); - jwrite32(jme, JME_RXUMA_LO, val); - val = (addr->sa_data[5] & 0xff) << 8 | - (addr->sa_data[4] & 0xff); - jwrite32(jme, JME_RXUMA_HI, val); + jme_set_unicastaddr(netdev); spin_unlock_bh(&jme->macaddr_lock); return 0; diff --git a/drivers/net/jme.h b/drivers/net/jme.h index 668958c68f63..b7ae0c7a7750 100644 --- a/drivers/net/jme.h +++ b/drivers/net/jme.h @@ -1258,6 +1258,7 @@ static inline int new_phy_power_ctrl(u8 chip_main_rev) */ static int jme_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd); +static void jme_set_unicastaddr(struct net_device *netdev); static void jme_set_multi(struct net_device *netdev); #endif -- cgit v1.2.3 From c00cd82641023ade3c44b4f11140a8afad460415 Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Sun, 13 Feb 2011 19:27:17 +0000 Subject: jme: Don't show UDP Checksum error if HW misjudged Some JMicron Chip treat 0 as error checksum for UDP packets. Which should be "No checksum needed". Reported-by: Adam Swift Confirmed-by: "Aries Lee" Signed-off-by: Guo-Fu Tseng Signed-off-by: David S. Miller --- drivers/net/jme.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/jme.c b/drivers/net/jme.c index ed35e17f43dc..5b441b75e138 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -956,8 +956,34 @@ jme_disable_rx_engine(struct jme_adapter *jme) jme_mac_rxclk_off(jme); } +static u16 +jme_udpsum(struct sk_buff *skb) +{ + u16 csum = 0xFFFFu; + + if (skb->len < (ETH_HLEN + sizeof(struct iphdr))) + return csum; + if (skb->protocol != htons(ETH_P_IP)) + return csum; + skb_set_network_header(skb, ETH_HLEN); + if ((ip_hdr(skb)->protocol != IPPROTO_UDP) || + (skb->len < (ETH_HLEN + + (ip_hdr(skb)->ihl << 2) + + sizeof(struct udphdr)))) { + skb_reset_network_header(skb); + return csum; + } + skb_set_transport_header(skb, + ETH_HLEN + (ip_hdr(skb)->ihl << 2)); + csum = udp_hdr(skb)->check; + skb_reset_transport_header(skb); + skb_reset_network_header(skb); + + return csum; +} + static int -jme_rxsum_ok(struct jme_adapter *jme, u16 flags) +jme_rxsum_ok(struct jme_adapter *jme, u16 flags, struct sk_buff *skb) { if (!(flags & (RXWBFLAG_TCPON | RXWBFLAG_UDPON | RXWBFLAG_IPV4))) return false; @@ -970,7 +996,7 @@ jme_rxsum_ok(struct jme_adapter *jme, u16 flags) } if (unlikely((flags & (RXWBFLAG_MF | RXWBFLAG_UDPON | RXWBFLAG_UDPCS)) - == RXWBFLAG_UDPON)) { + == RXWBFLAG_UDPON) && jme_udpsum(skb)) { if (flags & RXWBFLAG_IPV4) netif_err(jme, rx_err, jme->dev, "UDP Checksum error\n"); return false; @@ -1018,7 +1044,7 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx) skb_put(skb, framesize); skb->protocol = eth_type_trans(skb, jme->dev); - if (jme_rxsum_ok(jme, le16_to_cpu(rxdesc->descwb.flags))) + if (jme_rxsum_ok(jme, le16_to_cpu(rxdesc->descwb.flags), skb)) skb->ip_summed = CHECKSUM_UNNECESSARY; else skb_checksum_none_assert(skb); -- cgit v1.2.3 From c906041412a3b3eae2323408e26547ca60d94b89 Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Sun, 13 Feb 2011 19:27:18 +0000 Subject: jme: Advance driver version Signed-off-by: Guo-Fu Tseng Signed-off-by: David S. Miller --- drivers/net/jme.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/jme.h b/drivers/net/jme.h index b7ae0c7a7750..8bf30451e821 100644 --- a/drivers/net/jme.h +++ b/drivers/net/jme.h @@ -26,7 +26,7 @@ #define __JME_H_INCLUDED__ #define DRV_NAME "jme" -#define DRV_VERSION "1.0.7" +#define DRV_VERSION "1.0.8" #define PFX DRV_NAME ": " #define PCI_DEVICE_ID_JMICRON_JMC250 0x0250 -- cgit v1.2.3 From ac09664248e300342e92b937c9894a8149ddf189 Mon Sep 17 00:00:00 2001 From: Toshiharu Okada Date: Tue, 8 Feb 2011 22:15:59 +0000 Subject: pch_gbe: Fix the issue that the receiving data is not normal. This PCH_GBE driver had an issue that the receiving data is not normal. This driver had not removed correctly the padding data which the DMA include in receiving data. This patch fixed this issue. Signed-off-by: Toshiharu Okada Signed-off-by: David S. Miller --- drivers/net/pch_gbe/pch_gbe_main.c | 97 +++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index 4c9a7d4f3fca..f52d852569fb 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c @@ -29,6 +29,7 @@ const char pch_driver_version[] = DRV_VERSION; #define PCH_GBE_SHORT_PKT 64 #define DSC_INIT16 0xC000 #define PCH_GBE_DMA_ALIGN 0 +#define PCH_GBE_DMA_PADDING 2 #define PCH_GBE_WATCHDOG_PERIOD (1 * HZ) /* watchdog time */ #define PCH_GBE_COPYBREAK_DEFAULT 256 #define PCH_GBE_PCI_BAR 1 @@ -1365,16 +1366,13 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, struct pch_gbe_buffer *buffer_info; struct pch_gbe_rx_desc *rx_desc; u32 length; - unsigned char tmp_packet[ETH_HLEN]; unsigned int i; unsigned int cleaned_count = 0; bool cleaned = false; - struct sk_buff *skb; + struct sk_buff *skb, *new_skb; u8 dma_status; u16 gbec_status; u32 tcp_ip_status; - u8 skb_copy_flag = 0; - u8 skb_padding_flag = 0; i = rx_ring->next_to_clean; @@ -1418,55 +1416,70 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, pr_err("Receive CRC Error\n"); } else { /* get receive length */ - /* length convert[-3], padding[-2] */ - length = (rx_desc->rx_words_eob) - 3 - 2; + /* length convert[-3] */ + length = (rx_desc->rx_words_eob) - 3; /* Decide the data conversion method */ if (!adapter->rx_csum) { /* [Header:14][payload] */ - skb_padding_flag = 0; - skb_copy_flag = 1; + if (NET_IP_ALIGN) { + /* Because alignment differs, + * the new_skb is newly allocated, + * and data is copied to new_skb.*/ + new_skb = netdev_alloc_skb(netdev, + length + NET_IP_ALIGN); + if (!new_skb) { + /* dorrop error */ + pr_err("New skb allocation " + "Error\n"); + goto dorrop; + } + skb_reserve(new_skb, NET_IP_ALIGN); + memcpy(new_skb->data, skb->data, + length); + skb = new_skb; + } else { + /* DMA buffer is used as SKB as it is.*/ + buffer_info->skb = NULL; + } } else { /* [Header:14][padding:2][payload] */ - skb_padding_flag = 1; - if (length < copybreak) - skb_copy_flag = 1; - else - skb_copy_flag = 0; - } - - /* Data conversion */ - if (skb_copy_flag) { /* recycle skb */ - struct sk_buff *new_skb; - new_skb = - netdev_alloc_skb(netdev, - length + NET_IP_ALIGN); - if (new_skb) { - if (!skb_padding_flag) { - skb_reserve(new_skb, - NET_IP_ALIGN); + /* The length includes padding length */ + length = length - PCH_GBE_DMA_PADDING; + if ((length < copybreak) || + (NET_IP_ALIGN != PCH_GBE_DMA_PADDING)) { + /* Because alignment differs, + * the new_skb is newly allocated, + * and data is copied to new_skb. + * Padding data is deleted + * at the time of a copy.*/ + new_skb = netdev_alloc_skb(netdev, + length + NET_IP_ALIGN); + if (!new_skb) { + /* dorrop error */ + pr_err("New skb allocation " + "Error\n"); + goto dorrop; } + skb_reserve(new_skb, NET_IP_ALIGN); memcpy(new_skb->data, skb->data, - length); - /* save the skb - * in buffer_info as good */ + ETH_HLEN); + memcpy(&new_skb->data[ETH_HLEN], + &skb->data[ETH_HLEN + + PCH_GBE_DMA_PADDING], + length - ETH_HLEN); skb = new_skb; - } else if (!skb_padding_flag) { - /* dorrop error */ - pr_err("New skb allocation Error\n"); - goto dorrop; + } else { + /* Padding data is deleted + * by moving header data.*/ + memmove(&skb->data[PCH_GBE_DMA_PADDING], + &skb->data[0], ETH_HLEN); + skb_reserve(skb, NET_IP_ALIGN); + buffer_info->skb = NULL; } - } else { - buffer_info->skb = NULL; } - if (skb_padding_flag) { - memcpy(&tmp_packet[0], &skb->data[0], ETH_HLEN); - memcpy(&skb->data[NET_IP_ALIGN], &tmp_packet[0], - ETH_HLEN); - skb_reserve(skb, NET_IP_ALIGN); - - } - + /* The length includes FCS length */ + length = length - ETH_FCS_LEN; /* update status of driver */ adapter->stats.rx_bytes += length; adapter->stats.rx_packets++; -- cgit v1.2.3 From 881ff67ad45041f6ff08441aa17302aea77bd054 Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Sun, 13 Feb 2011 22:51:44 -0800 Subject: can: c_can: Added support for Bosch C_CAN controller Bosch C_CAN controller is a full-CAN implementation which is compliant to CAN protocol version 2.0 part A and B. Bosch C_CAN user manual can be obtained from: http://www.semiconductors.bosch.de/media/en/pdf/ipmodules_1/c_can/users_manual_c_can.pdf This patch adds the support for this controller. The following are the design choices made while writing the controller driver: 1. Interface Register set IF1 has be used only in the current design. 2. Out of the 32 Message objects available, 16 are kept aside for RX purposes and the rest for TX purposes. 3. NAPI implementation is such that both the TX and RX paths function in polling mode. Signed-off-by: Bhupesh Sharma Signed-off-by: David S. Miller --- drivers/net/can/Kconfig | 2 + drivers/net/can/Makefile | 1 + drivers/net/can/c_can/Kconfig | 15 + drivers/net/can/c_can/Makefile | 8 + drivers/net/can/c_can/c_can.c | 1158 ++++++++++++++++++++++++++++++++ drivers/net/can/c_can/c_can.h | 86 +++ drivers/net/can/c_can/c_can_platform.c | 215 ++++++ 7 files changed, 1485 insertions(+) create mode 100644 drivers/net/can/c_can/Kconfig create mode 100644 drivers/net/can/c_can/Makefile create mode 100644 drivers/net/can/c_can/c_can.c create mode 100644 drivers/net/can/c_can/c_can.h create mode 100644 drivers/net/can/c_can/c_can_platform.c (limited to 'drivers') diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 5dec456fd4a4..1d699e3df547 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -115,6 +115,8 @@ source "drivers/net/can/mscan/Kconfig" source "drivers/net/can/sja1000/Kconfig" +source "drivers/net/can/c_can/Kconfig" + source "drivers/net/can/usb/Kconfig" source "drivers/net/can/softing/Kconfig" diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile index 53c82a71778e..24ebfe8d758a 100644 --- a/drivers/net/can/Makefile +++ b/drivers/net/can/Makefile @@ -13,6 +13,7 @@ obj-y += softing/ obj-$(CONFIG_CAN_SJA1000) += sja1000/ obj-$(CONFIG_CAN_MSCAN) += mscan/ +obj-$(CONFIG_CAN_C_CAN) += c_can/ obj-$(CONFIG_CAN_AT91) += at91_can.o obj-$(CONFIG_CAN_TI_HECC) += ti_hecc.o obj-$(CONFIG_CAN_MCP251X) += mcp251x.o diff --git a/drivers/net/can/c_can/Kconfig b/drivers/net/can/c_can/Kconfig new file mode 100644 index 000000000000..ffb9773d102d --- /dev/null +++ b/drivers/net/can/c_can/Kconfig @@ -0,0 +1,15 @@ +menuconfig CAN_C_CAN + tristate "Bosch C_CAN devices" + depends on CAN_DEV && HAS_IOMEM + +if CAN_C_CAN + +config CAN_C_CAN_PLATFORM + tristate "Generic Platform Bus based C_CAN driver" + ---help--- + This driver adds support for the C_CAN chips connected to + the "platform bus" (Linux abstraction for directly to the + processor attached devices) which can be found on various + boards from ST Microelectronics (http://www.st.com) + like the SPEAr1310 and SPEAr320 evaluation boards. +endif diff --git a/drivers/net/can/c_can/Makefile b/drivers/net/can/c_can/Makefile new file mode 100644 index 000000000000..9273f6d5c4b7 --- /dev/null +++ b/drivers/net/can/c_can/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for the Bosch C_CAN controller drivers. +# + +obj-$(CONFIG_CAN_C_CAN) += c_can.o +obj-$(CONFIG_CAN_C_CAN_PLATFORM) += c_can_platform.o + +ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c new file mode 100644 index 000000000000..14050786218a --- /dev/null +++ b/drivers/net/can/c_can/c_can.c @@ -0,0 +1,1158 @@ +/* + * CAN bus driver for Bosch C_CAN controller + * + * Copyright (C) 2010 ST Microelectronics + * Bhupesh Sharma + * + * Borrowed heavily from the C_CAN driver originally written by: + * Copyright (C) 2007 + * - Sascha Hauer, Marc Kleine-Budde, Pengutronix + * - Simon Kallweit, intefo AG + * + * TX and RX NAPI implementation has been borrowed from at91 CAN driver + * written by: + * Copyright + * (C) 2007 by Hans J. Koch + * (C) 2008, 2009 by Marc Kleine-Budde + * + * Bosch C_CAN controller is compliant to CAN protocol version 2.0 part A and B. + * Bosch C_CAN user manual can be obtained from: + * http://www.semiconductors.bosch.de/media/en/pdf/ipmodules_1/c_can/ + * users_manual_c_can.pdf + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "c_can.h" + +/* control register */ +#define CONTROL_TEST BIT(7) +#define CONTROL_CCE BIT(6) +#define CONTROL_DISABLE_AR BIT(5) +#define CONTROL_ENABLE_AR (0 << 5) +#define CONTROL_EIE BIT(3) +#define CONTROL_SIE BIT(2) +#define CONTROL_IE BIT(1) +#define CONTROL_INIT BIT(0) + +/* test register */ +#define TEST_RX BIT(7) +#define TEST_TX1 BIT(6) +#define TEST_TX2 BIT(5) +#define TEST_LBACK BIT(4) +#define TEST_SILENT BIT(3) +#define TEST_BASIC BIT(2) + +/* status register */ +#define STATUS_BOFF BIT(7) +#define STATUS_EWARN BIT(6) +#define STATUS_EPASS BIT(5) +#define STATUS_RXOK BIT(4) +#define STATUS_TXOK BIT(3) + +/* error counter register */ +#define ERR_CNT_TEC_MASK 0xff +#define ERR_CNT_TEC_SHIFT 0 +#define ERR_CNT_REC_SHIFT 8 +#define ERR_CNT_REC_MASK (0x7f << ERR_CNT_REC_SHIFT) +#define ERR_CNT_RP_SHIFT 15 +#define ERR_CNT_RP_MASK (0x1 << ERR_CNT_RP_SHIFT) + +/* bit-timing register */ +#define BTR_BRP_MASK 0x3f +#define BTR_BRP_SHIFT 0 +#define BTR_SJW_SHIFT 6 +#define BTR_SJW_MASK (0x3 << BTR_SJW_SHIFT) +#define BTR_TSEG1_SHIFT 8 +#define BTR_TSEG1_MASK (0xf << BTR_TSEG1_SHIFT) +#define BTR_TSEG2_SHIFT 12 +#define BTR_TSEG2_MASK (0x7 << BTR_TSEG2_SHIFT) + +/* brp extension register */ +#define BRP_EXT_BRPE_MASK 0x0f +#define BRP_EXT_BRPE_SHIFT 0 + +/* IFx command request */ +#define IF_COMR_BUSY BIT(15) + +/* IFx command mask */ +#define IF_COMM_WR BIT(7) +#define IF_COMM_MASK BIT(6) +#define IF_COMM_ARB BIT(5) +#define IF_COMM_CONTROL BIT(4) +#define IF_COMM_CLR_INT_PND BIT(3) +#define IF_COMM_TXRQST BIT(2) +#define IF_COMM_DATAA BIT(1) +#define IF_COMM_DATAB BIT(0) +#define IF_COMM_ALL (IF_COMM_MASK | IF_COMM_ARB | \ + IF_COMM_CONTROL | IF_COMM_TXRQST | \ + IF_COMM_DATAA | IF_COMM_DATAB) + +/* IFx arbitration */ +#define IF_ARB_MSGVAL BIT(15) +#define IF_ARB_MSGXTD BIT(14) +#define IF_ARB_TRANSMIT BIT(13) + +/* IFx message control */ +#define IF_MCONT_NEWDAT BIT(15) +#define IF_MCONT_MSGLST BIT(14) +#define IF_MCONT_CLR_MSGLST (0 << 14) +#define IF_MCONT_INTPND BIT(13) +#define IF_MCONT_UMASK BIT(12) +#define IF_MCONT_TXIE BIT(11) +#define IF_MCONT_RXIE BIT(10) +#define IF_MCONT_RMTEN BIT(9) +#define IF_MCONT_TXRQST BIT(8) +#define IF_MCONT_EOB BIT(7) +#define IF_MCONT_DLC_MASK 0xf + +/* + * IFx register masks: + * allow easy operation on 16-bit registers when the + * argument is 32-bit instead + */ +#define IFX_WRITE_LOW_16BIT(x) ((x) & 0xFFFF) +#define IFX_WRITE_HIGH_16BIT(x) (((x) & 0xFFFF0000) >> 16) + +/* message object split */ +#define C_CAN_NO_OF_OBJECTS 32 +#define C_CAN_MSG_OBJ_RX_NUM 16 +#define C_CAN_MSG_OBJ_TX_NUM 16 + +#define C_CAN_MSG_OBJ_RX_FIRST 1 +#define C_CAN_MSG_OBJ_RX_LAST (C_CAN_MSG_OBJ_RX_FIRST + \ + C_CAN_MSG_OBJ_RX_NUM - 1) + +#define C_CAN_MSG_OBJ_TX_FIRST (C_CAN_MSG_OBJ_RX_LAST + 1) +#define C_CAN_MSG_OBJ_TX_LAST (C_CAN_MSG_OBJ_TX_FIRST + \ + C_CAN_MSG_OBJ_TX_NUM - 1) + +#define C_CAN_MSG_OBJ_RX_SPLIT 9 +#define C_CAN_MSG_RX_LOW_LAST (C_CAN_MSG_OBJ_RX_SPLIT - 1) + +#define C_CAN_NEXT_MSG_OBJ_MASK (C_CAN_MSG_OBJ_TX_NUM - 1) +#define RECEIVE_OBJECT_BITS 0x0000ffff + +/* status interrupt */ +#define STATUS_INTERRUPT 0x8000 + +/* global interrupt masks */ +#define ENABLE_ALL_INTERRUPTS 1 +#define DISABLE_ALL_INTERRUPTS 0 + +/* minimum timeout for checking BUSY status */ +#define MIN_TIMEOUT_VALUE 6 + +/* napi related */ +#define C_CAN_NAPI_WEIGHT C_CAN_MSG_OBJ_RX_NUM + +/* c_can lec values */ +enum c_can_lec_type { + LEC_NO_ERROR = 0, + LEC_STUFF_ERROR, + LEC_FORM_ERROR, + LEC_ACK_ERROR, + LEC_BIT1_ERROR, + LEC_BIT0_ERROR, + LEC_CRC_ERROR, + LEC_UNUSED, +}; + +/* + * c_can error types: + * Bus errors (BUS_OFF, ERROR_WARNING, ERROR_PASSIVE) are supported + */ +enum c_can_bus_error_types { + C_CAN_NO_ERROR = 0, + C_CAN_BUS_OFF, + C_CAN_ERROR_WARNING, + C_CAN_ERROR_PASSIVE, +}; + +static struct can_bittiming_const c_can_bittiming_const = { + .name = KBUILD_MODNAME, + .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */ + .tseg1_max = 16, + .tseg2_min = 1, /* Time segment 2 = phase_seg2 */ + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 1024, /* 6-bit BRP field + 4-bit BRPE field*/ + .brp_inc = 1, +}; + +static inline int get_tx_next_msg_obj(const struct c_can_priv *priv) +{ + return (priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) + + C_CAN_MSG_OBJ_TX_FIRST; +} + +static inline int get_tx_echo_msg_obj(const struct c_can_priv *priv) +{ + return (priv->tx_echo & C_CAN_NEXT_MSG_OBJ_MASK) + + C_CAN_MSG_OBJ_TX_FIRST; +} + +static u32 c_can_read_reg32(struct c_can_priv *priv, void *reg) +{ + u32 val = priv->read_reg(priv, reg); + val |= ((u32) priv->read_reg(priv, reg + 2)) << 16; + return val; +} + +static void c_can_enable_all_interrupts(struct c_can_priv *priv, + int enable) +{ + unsigned int cntrl_save = priv->read_reg(priv, + &priv->regs->control); + + if (enable) + cntrl_save |= (CONTROL_SIE | CONTROL_EIE | CONTROL_IE); + else + cntrl_save &= ~(CONTROL_EIE | CONTROL_IE | CONTROL_SIE); + + priv->write_reg(priv, &priv->regs->control, cntrl_save); +} + +static inline int c_can_msg_obj_is_busy(struct c_can_priv *priv, int iface) +{ + int count = MIN_TIMEOUT_VALUE; + + while (count && priv->read_reg(priv, + &priv->regs->ifregs[iface].com_req) & + IF_COMR_BUSY) { + count--; + udelay(1); + } + + if (!count) + return 1; + + return 0; +} + +static inline void c_can_object_get(struct net_device *dev, + int iface, int objno, int mask) +{ + struct c_can_priv *priv = netdev_priv(dev); + + /* + * As per specs, after writting the message object number in the + * IF command request register the transfer b/w interface + * register and message RAM must be complete in 6 CAN-CLK + * period. + */ + priv->write_reg(priv, &priv->regs->ifregs[iface].com_mask, + IFX_WRITE_LOW_16BIT(mask)); + priv->write_reg(priv, &priv->regs->ifregs[iface].com_req, + IFX_WRITE_LOW_16BIT(objno)); + + if (c_can_msg_obj_is_busy(priv, iface)) + netdev_err(dev, "timed out in object get\n"); +} + +static inline void c_can_object_put(struct net_device *dev, + int iface, int objno, int mask) +{ + struct c_can_priv *priv = netdev_priv(dev); + + /* + * As per specs, after writting the message object number in the + * IF command request register the transfer b/w interface + * register and message RAM must be complete in 6 CAN-CLK + * period. + */ + priv->write_reg(priv, &priv->regs->ifregs[iface].com_mask, + (IF_COMM_WR | IFX_WRITE_LOW_16BIT(mask))); + priv->write_reg(priv, &priv->regs->ifregs[iface].com_req, + IFX_WRITE_LOW_16BIT(objno)); + + if (c_can_msg_obj_is_busy(priv, iface)) + netdev_err(dev, "timed out in object put\n"); +} + +static void c_can_write_msg_object(struct net_device *dev, + int iface, struct can_frame *frame, int objno) +{ + int i; + u16 flags = 0; + unsigned int id; + struct c_can_priv *priv = netdev_priv(dev); + + if (!(frame->can_id & CAN_RTR_FLAG)) + flags |= IF_ARB_TRANSMIT; + + if (frame->can_id & CAN_EFF_FLAG) { + id = frame->can_id & CAN_EFF_MASK; + flags |= IF_ARB_MSGXTD; + } else + id = ((frame->can_id & CAN_SFF_MASK) << 18); + + flags |= IF_ARB_MSGVAL; + + priv->write_reg(priv, &priv->regs->ifregs[iface].arb1, + IFX_WRITE_LOW_16BIT(id)); + priv->write_reg(priv, &priv->regs->ifregs[iface].arb2, flags | + IFX_WRITE_HIGH_16BIT(id)); + + for (i = 0; i < frame->can_dlc; i += 2) { + priv->write_reg(priv, &priv->regs->ifregs[iface].data[i / 2], + frame->data[i] | (frame->data[i + 1] << 8)); + } + + /* enable interrupt for this message object */ + priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, + IF_MCONT_TXIE | IF_MCONT_TXRQST | IF_MCONT_EOB | + frame->can_dlc); + c_can_object_put(dev, iface, objno, IF_COMM_ALL); +} + +static inline void c_can_mark_rx_msg_obj(struct net_device *dev, + int iface, int ctrl_mask, + int obj) +{ + struct c_can_priv *priv = netdev_priv(dev); + + priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, + ctrl_mask & ~(IF_MCONT_MSGLST | IF_MCONT_INTPND)); + c_can_object_put(dev, iface, obj, IF_COMM_CONTROL); + +} + +static inline void c_can_activate_all_lower_rx_msg_obj(struct net_device *dev, + int iface, + int ctrl_mask) +{ + int i; + struct c_can_priv *priv = netdev_priv(dev); + + for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_MSG_RX_LOW_LAST; i++) { + priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, + ctrl_mask & ~(IF_MCONT_MSGLST | + IF_MCONT_INTPND | IF_MCONT_NEWDAT)); + c_can_object_put(dev, iface, i, IF_COMM_CONTROL); + } +} + +static inline void c_can_activate_rx_msg_obj(struct net_device *dev, + int iface, int ctrl_mask, + int obj) +{ + struct c_can_priv *priv = netdev_priv(dev); + + priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, + ctrl_mask & ~(IF_MCONT_MSGLST | + IF_MCONT_INTPND | IF_MCONT_NEWDAT)); + c_can_object_put(dev, iface, obj, IF_COMM_CONTROL); +} + +static void c_can_handle_lost_msg_obj(struct net_device *dev, + int iface, int objno) +{ + struct c_can_priv *priv = netdev_priv(dev); + struct net_device_stats *stats = &dev->stats; + struct sk_buff *skb; + struct can_frame *frame; + + netdev_err(dev, "msg lost in buffer %d\n", objno); + + c_can_object_get(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST); + + priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, + IF_MCONT_CLR_MSGLST); + + c_can_object_put(dev, 0, objno, IF_COMM_CONTROL); + + /* create an error msg */ + skb = alloc_can_err_skb(dev, &frame); + if (unlikely(!skb)) + return; + + frame->can_id |= CAN_ERR_CRTL; + frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; + stats->rx_errors++; + stats->rx_over_errors++; + + netif_receive_skb(skb); +} + +static int c_can_read_msg_object(struct net_device *dev, int iface, int ctrl) +{ + u16 flags, data; + int i; + unsigned int val; + struct c_can_priv *priv = netdev_priv(dev); + struct net_device_stats *stats = &dev->stats; + struct sk_buff *skb; + struct can_frame *frame; + + skb = alloc_can_skb(dev, &frame); + if (!skb) { + stats->rx_dropped++; + return -ENOMEM; + } + + frame->can_dlc = get_can_dlc(ctrl & 0x0F); + + flags = priv->read_reg(priv, &priv->regs->ifregs[iface].arb2); + val = priv->read_reg(priv, &priv->regs->ifregs[iface].arb1) | + (flags << 16); + + if (flags & IF_ARB_MSGXTD) + frame->can_id = (val & CAN_EFF_MASK) | CAN_EFF_FLAG; + else + frame->can_id = (val >> 18) & CAN_SFF_MASK; + + if (flags & IF_ARB_TRANSMIT) + frame->can_id |= CAN_RTR_FLAG; + else { + for (i = 0; i < frame->can_dlc; i += 2) { + data = priv->read_reg(priv, + &priv->regs->ifregs[iface].data[i / 2]); + frame->data[i] = data; + frame->data[i + 1] = data >> 8; + } + } + + netif_receive_skb(skb); + + stats->rx_packets++; + stats->rx_bytes += frame->can_dlc; + + return 0; +} + +static void c_can_setup_receive_object(struct net_device *dev, int iface, + int objno, unsigned int mask, + unsigned int id, unsigned int mcont) +{ + struct c_can_priv *priv = netdev_priv(dev); + + priv->write_reg(priv, &priv->regs->ifregs[iface].mask1, + IFX_WRITE_LOW_16BIT(mask)); + priv->write_reg(priv, &priv->regs->ifregs[iface].mask2, + IFX_WRITE_HIGH_16BIT(mask)); + + priv->write_reg(priv, &priv->regs->ifregs[iface].arb1, + IFX_WRITE_LOW_16BIT(id)); + priv->write_reg(priv, &priv->regs->ifregs[iface].arb2, + (IF_ARB_MSGVAL | IFX_WRITE_HIGH_16BIT(id))); + + priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, mcont); + c_can_object_put(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST); + + netdev_dbg(dev, "obj no:%d, msgval:0x%08x\n", objno, + c_can_read_reg32(priv, &priv->regs->msgval1)); +} + +static void c_can_inval_msg_object(struct net_device *dev, int iface, int objno) +{ + struct c_can_priv *priv = netdev_priv(dev); + + priv->write_reg(priv, &priv->regs->ifregs[iface].arb1, 0); + priv->write_reg(priv, &priv->regs->ifregs[iface].arb2, 0); + priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, 0); + + c_can_object_put(dev, iface, objno, IF_COMM_ARB | IF_COMM_CONTROL); + + netdev_dbg(dev, "obj no:%d, msgval:0x%08x\n", objno, + c_can_read_reg32(priv, &priv->regs->msgval1)); +} + +static inline int c_can_is_next_tx_obj_busy(struct c_can_priv *priv, int objno) +{ + int val = c_can_read_reg32(priv, &priv->regs->txrqst1); + + /* + * as transmission request register's bit n-1 corresponds to + * message object n, we need to handle the same properly. + */ + if (val & (1 << (objno - 1))) + return 1; + + return 0; +} + +static netdev_tx_t c_can_start_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + u32 msg_obj_no; + struct c_can_priv *priv = netdev_priv(dev); + struct can_frame *frame = (struct can_frame *)skb->data; + + if (can_dropped_invalid_skb(dev, skb)) + return NETDEV_TX_OK; + + msg_obj_no = get_tx_next_msg_obj(priv); + + /* prepare message object for transmission */ + c_can_write_msg_object(dev, 0, frame, msg_obj_no); + can_put_echo_skb(skb, dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); + + /* + * we have to stop the queue in case of a wrap around or + * if the next TX message object is still in use + */ + priv->tx_next++; + if (c_can_is_next_tx_obj_busy(priv, get_tx_next_msg_obj(priv)) || + (priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) == 0) + netif_stop_queue(dev); + + return NETDEV_TX_OK; +} + +static int c_can_set_bittiming(struct net_device *dev) +{ + unsigned int reg_btr, reg_brpe, ctrl_save; + u8 brp, brpe, sjw, tseg1, tseg2; + u32 ten_bit_brp; + struct c_can_priv *priv = netdev_priv(dev); + const struct can_bittiming *bt = &priv->can.bittiming; + + /* c_can provides a 6-bit brp and 4-bit brpe fields */ + ten_bit_brp = bt->brp - 1; + brp = ten_bit_brp & BTR_BRP_MASK; + brpe = ten_bit_brp >> 6; + + sjw = bt->sjw - 1; + tseg1 = bt->prop_seg + bt->phase_seg1 - 1; + tseg2 = bt->phase_seg2 - 1; + reg_btr = brp | (sjw << BTR_SJW_SHIFT) | (tseg1 << BTR_TSEG1_SHIFT) | + (tseg2 << BTR_TSEG2_SHIFT); + reg_brpe = brpe & BRP_EXT_BRPE_MASK; + + netdev_info(dev, + "setting BTR=%04x BRPE=%04x\n", reg_btr, reg_brpe); + + ctrl_save = priv->read_reg(priv, &priv->regs->control); + priv->write_reg(priv, &priv->regs->control, + ctrl_save | CONTROL_CCE | CONTROL_INIT); + priv->write_reg(priv, &priv->regs->btr, reg_btr); + priv->write_reg(priv, &priv->regs->brp_ext, reg_brpe); + priv->write_reg(priv, &priv->regs->control, ctrl_save); + + return 0; +} + +/* + * Configure C_CAN message objects for Tx and Rx purposes: + * C_CAN provides a total of 32 message objects that can be configured + * either for Tx or Rx purposes. Here the first 16 message objects are used as + * a reception FIFO. The end of reception FIFO is signified by the EoB bit + * being SET. The remaining 16 message objects are kept aside for Tx purposes. + * See user guide document for further details on configuring message + * objects. + */ +static void c_can_configure_msg_objects(struct net_device *dev) +{ + int i; + + /* first invalidate all message objects */ + for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_NO_OF_OBJECTS; i++) + c_can_inval_msg_object(dev, 0, i); + + /* setup receive message objects */ + for (i = C_CAN_MSG_OBJ_RX_FIRST; i < C_CAN_MSG_OBJ_RX_LAST; i++) + c_can_setup_receive_object(dev, 0, i, 0, 0, + (IF_MCONT_RXIE | IF_MCONT_UMASK) & ~IF_MCONT_EOB); + + c_can_setup_receive_object(dev, 0, C_CAN_MSG_OBJ_RX_LAST, 0, 0, + IF_MCONT_EOB | IF_MCONT_RXIE | IF_MCONT_UMASK); +} + +/* + * Configure C_CAN chip: + * - enable/disable auto-retransmission + * - set operating mode + * - configure message objects + */ +static void c_can_chip_config(struct net_device *dev) +{ + struct c_can_priv *priv = netdev_priv(dev); + + if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT) + /* disable automatic retransmission */ + priv->write_reg(priv, &priv->regs->control, + CONTROL_DISABLE_AR); + else + /* enable automatic retransmission */ + priv->write_reg(priv, &priv->regs->control, + CONTROL_ENABLE_AR); + + if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY & + CAN_CTRLMODE_LOOPBACK)) { + /* loopback + silent mode : useful for hot self-test */ + priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | + CONTROL_SIE | CONTROL_IE | CONTROL_TEST); + priv->write_reg(priv, &priv->regs->test, + TEST_LBACK | TEST_SILENT); + } else if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) { + /* loopback mode : useful for self-test function */ + priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | + CONTROL_SIE | CONTROL_IE | CONTROL_TEST); + priv->write_reg(priv, &priv->regs->test, TEST_LBACK); + } else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) { + /* silent mode : bus-monitoring mode */ + priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | + CONTROL_SIE | CONTROL_IE | CONTROL_TEST); + priv->write_reg(priv, &priv->regs->test, TEST_SILENT); + } else + /* normal mode*/ + priv->write_reg(priv, &priv->regs->control, + CONTROL_EIE | CONTROL_SIE | CONTROL_IE); + + /* configure message objects */ + c_can_configure_msg_objects(dev); + + /* set a `lec` value so that we can check for updates later */ + priv->write_reg(priv, &priv->regs->status, LEC_UNUSED); + + /* set bittiming params */ + c_can_set_bittiming(dev); +} + +static void c_can_start(struct net_device *dev) +{ + struct c_can_priv *priv = netdev_priv(dev); + + /* enable status change, error and module interrupts */ + c_can_enable_all_interrupts(priv, ENABLE_ALL_INTERRUPTS); + + /* basic c_can configuration */ + c_can_chip_config(dev); + + priv->can.state = CAN_STATE_ERROR_ACTIVE; + + /* reset tx helper pointers */ + priv->tx_next = priv->tx_echo = 0; +} + +static void c_can_stop(struct net_device *dev) +{ + struct c_can_priv *priv = netdev_priv(dev); + + /* disable all interrupts */ + c_can_enable_all_interrupts(priv, DISABLE_ALL_INTERRUPTS); + + /* set the state as STOPPED */ + priv->can.state = CAN_STATE_STOPPED; +} + +static int c_can_set_mode(struct net_device *dev, enum can_mode mode) +{ + switch (mode) { + case CAN_MODE_START: + c_can_start(dev); + netif_wake_queue(dev); + break; + default: + return -EOPNOTSUPP; + } + + return 0; +} + +static int c_can_get_berr_counter(const struct net_device *dev, + struct can_berr_counter *bec) +{ + unsigned int reg_err_counter; + struct c_can_priv *priv = netdev_priv(dev); + + reg_err_counter = priv->read_reg(priv, &priv->regs->err_cnt); + bec->rxerr = (reg_err_counter & ERR_CNT_REC_MASK) >> + ERR_CNT_REC_SHIFT; + bec->txerr = reg_err_counter & ERR_CNT_TEC_MASK; + + return 0; +} + +/* + * theory of operation: + * + * priv->tx_echo holds the number of the oldest can_frame put for + * transmission into the hardware, but not yet ACKed by the CAN tx + * complete IRQ. + * + * We iterate from priv->tx_echo to priv->tx_next and check if the + * packet has been transmitted, echo it back to the CAN framework. + * If we discover a not yet transmitted package, stop looking for more. + */ +static void c_can_do_tx(struct net_device *dev) +{ + u32 val; + u32 msg_obj_no; + struct c_can_priv *priv = netdev_priv(dev); + struct net_device_stats *stats = &dev->stats; + + for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) { + msg_obj_no = get_tx_echo_msg_obj(priv); + c_can_inval_msg_object(dev, 0, msg_obj_no); + val = c_can_read_reg32(priv, &priv->regs->txrqst1); + if (!(val & (1 << msg_obj_no))) { + can_get_echo_skb(dev, + msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); + stats->tx_bytes += priv->read_reg(priv, + &priv->regs->ifregs[0].msg_cntrl) + & IF_MCONT_DLC_MASK; + stats->tx_packets++; + } + } + + /* restart queue if wrap-up or if queue stalled on last pkt */ + if (((priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) != 0) || + ((priv->tx_echo & C_CAN_NEXT_MSG_OBJ_MASK) == 0)) + netif_wake_queue(dev); +} + +/* + * theory of operation: + * + * c_can core saves a received CAN message into the first free message + * object it finds free (starting with the lowest). Bits NEWDAT and + * INTPND are set for this message object indicating that a new message + * has arrived. To work-around this issue, we keep two groups of message + * objects whose partitioning is defined by C_CAN_MSG_OBJ_RX_SPLIT. + * + * To ensure in-order frame reception we use the following + * approach while re-activating a message object to receive further + * frames: + * - if the current message object number is lower than + * C_CAN_MSG_RX_LOW_LAST, do not clear the NEWDAT bit while clearing + * the INTPND bit. + * - if the current message object number is equal to + * C_CAN_MSG_RX_LOW_LAST then clear the NEWDAT bit of all lower + * receive message objects. + * - if the current message object number is greater than + * C_CAN_MSG_RX_LOW_LAST then clear the NEWDAT bit of + * only this message object. + */ +static int c_can_do_rx_poll(struct net_device *dev, int quota) +{ + u32 num_rx_pkts = 0; + unsigned int msg_obj, msg_ctrl_save; + struct c_can_priv *priv = netdev_priv(dev); + u32 val = c_can_read_reg32(priv, &priv->regs->intpnd1); + + for (msg_obj = C_CAN_MSG_OBJ_RX_FIRST; + msg_obj <= C_CAN_MSG_OBJ_RX_LAST && quota > 0; + val = c_can_read_reg32(priv, &priv->regs->intpnd1), + msg_obj++) { + /* + * as interrupt pending register's bit n-1 corresponds to + * message object n, we need to handle the same properly. + */ + if (val & (1 << (msg_obj - 1))) { + c_can_object_get(dev, 0, msg_obj, IF_COMM_ALL & + ~IF_COMM_TXRQST); + msg_ctrl_save = priv->read_reg(priv, + &priv->regs->ifregs[0].msg_cntrl); + + if (msg_ctrl_save & IF_MCONT_EOB) + return num_rx_pkts; + + if (msg_ctrl_save & IF_MCONT_MSGLST) { + c_can_handle_lost_msg_obj(dev, 0, msg_obj); + num_rx_pkts++; + quota--; + continue; + } + + if (!(msg_ctrl_save & IF_MCONT_NEWDAT)) + continue; + + /* read the data from the message object */ + c_can_read_msg_object(dev, 0, msg_ctrl_save); + + if (msg_obj < C_CAN_MSG_RX_LOW_LAST) + c_can_mark_rx_msg_obj(dev, 0, + msg_ctrl_save, msg_obj); + else if (msg_obj > C_CAN_MSG_RX_LOW_LAST) + /* activate this msg obj */ + c_can_activate_rx_msg_obj(dev, 0, + msg_ctrl_save, msg_obj); + else if (msg_obj == C_CAN_MSG_RX_LOW_LAST) + /* activate all lower message objects */ + c_can_activate_all_lower_rx_msg_obj(dev, + 0, msg_ctrl_save); + + num_rx_pkts++; + quota--; + } + } + + return num_rx_pkts; +} + +static inline int c_can_has_and_handle_berr(struct c_can_priv *priv) +{ + return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) && + (priv->current_status & LEC_UNUSED); +} + +static int c_can_handle_state_change(struct net_device *dev, + enum c_can_bus_error_types error_type) +{ + unsigned int reg_err_counter; + unsigned int rx_err_passive; + struct c_can_priv *priv = netdev_priv(dev); + struct net_device_stats *stats = &dev->stats; + struct can_frame *cf; + struct sk_buff *skb; + struct can_berr_counter bec; + + /* propogate the error condition to the CAN stack */ + skb = alloc_can_err_skb(dev, &cf); + if (unlikely(!skb)) + return 0; + + c_can_get_berr_counter(dev, &bec); + reg_err_counter = priv->read_reg(priv, &priv->regs->err_cnt); + rx_err_passive = (reg_err_counter & ERR_CNT_RP_MASK) >> + ERR_CNT_RP_SHIFT; + + switch (error_type) { + case C_CAN_ERROR_WARNING: + /* error warning state */ + priv->can.can_stats.error_warning++; + priv->can.state = CAN_STATE_ERROR_WARNING; + cf->can_id |= CAN_ERR_CRTL; + cf->data[1] = (bec.txerr > bec.rxerr) ? + CAN_ERR_CRTL_TX_WARNING : + CAN_ERR_CRTL_RX_WARNING; + cf->data[6] = bec.txerr; + cf->data[7] = bec.rxerr; + + break; + case C_CAN_ERROR_PASSIVE: + /* error passive state */ + priv->can.can_stats.error_passive++; + priv->can.state = CAN_STATE_ERROR_PASSIVE; + cf->can_id |= CAN_ERR_CRTL; + if (rx_err_passive) + cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; + if (bec.txerr > 127) + cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE; + + cf->data[6] = bec.txerr; + cf->data[7] = bec.rxerr; + break; + case C_CAN_BUS_OFF: + /* bus-off state */ + priv->can.state = CAN_STATE_BUS_OFF; + cf->can_id |= CAN_ERR_BUSOFF; + /* + * disable all interrupts in bus-off mode to ensure that + * the CPU is not hogged down + */ + c_can_enable_all_interrupts(priv, DISABLE_ALL_INTERRUPTS); + can_bus_off(dev); + break; + default: + break; + } + + netif_receive_skb(skb); + stats->rx_packets++; + stats->rx_bytes += cf->can_dlc; + + return 1; +} + +static int c_can_handle_bus_err(struct net_device *dev, + enum c_can_lec_type lec_type) +{ + struct c_can_priv *priv = netdev_priv(dev); + struct net_device_stats *stats = &dev->stats; + struct can_frame *cf; + struct sk_buff *skb; + + /* + * early exit if no lec update or no error. + * no lec update means that no CAN bus event has been detected + * since CPU wrote 0x7 value to status reg. + */ + if (lec_type == LEC_UNUSED || lec_type == LEC_NO_ERROR) + return 0; + + /* propogate the error condition to the CAN stack */ + skb = alloc_can_err_skb(dev, &cf); + if (unlikely(!skb)) + return 0; + + /* + * check for 'last error code' which tells us the + * type of the last error to occur on the CAN bus + */ + + /* common for all type of bus errors */ + priv->can.can_stats.bus_error++; + stats->rx_errors++; + cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; + cf->data[2] |= CAN_ERR_PROT_UNSPEC; + + switch (lec_type) { + case LEC_STUFF_ERROR: + netdev_dbg(dev, "stuff error\n"); + cf->data[2] |= CAN_ERR_PROT_STUFF; + break; + case LEC_FORM_ERROR: + netdev_dbg(dev, "form error\n"); + cf->data[2] |= CAN_ERR_PROT_FORM; + break; + case LEC_ACK_ERROR: + netdev_dbg(dev, "ack error\n"); + cf->data[2] |= (CAN_ERR_PROT_LOC_ACK | + CAN_ERR_PROT_LOC_ACK_DEL); + break; + case LEC_BIT1_ERROR: + netdev_dbg(dev, "bit1 error\n"); + cf->data[2] |= CAN_ERR_PROT_BIT1; + break; + case LEC_BIT0_ERROR: + netdev_dbg(dev, "bit0 error\n"); + cf->data[2] |= CAN_ERR_PROT_BIT0; + break; + case LEC_CRC_ERROR: + netdev_dbg(dev, "CRC error\n"); + cf->data[2] |= (CAN_ERR_PROT_LOC_CRC_SEQ | + CAN_ERR_PROT_LOC_CRC_DEL); + break; + default: + break; + } + + /* set a `lec` value so that we can check for updates later */ + priv->write_reg(priv, &priv->regs->status, LEC_UNUSED); + + netif_receive_skb(skb); + stats->rx_packets++; + stats->rx_bytes += cf->can_dlc; + + return 1; +} + +static int c_can_poll(struct napi_struct *napi, int quota) +{ + u16 irqstatus; + int lec_type = 0; + int work_done = 0; + struct net_device *dev = napi->dev; + struct c_can_priv *priv = netdev_priv(dev); + + irqstatus = priv->read_reg(priv, &priv->regs->interrupt); + if (!irqstatus) + goto end; + + /* status events have the highest priority */ + if (irqstatus == STATUS_INTERRUPT) { + priv->current_status = priv->read_reg(priv, + &priv->regs->status); + + /* handle Tx/Rx events */ + if (priv->current_status & STATUS_TXOK) + priv->write_reg(priv, &priv->regs->status, + priv->current_status & ~STATUS_TXOK); + + if (priv->current_status & STATUS_RXOK) + priv->write_reg(priv, &priv->regs->status, + priv->current_status & ~STATUS_RXOK); + + /* handle state changes */ + if ((priv->current_status & STATUS_EWARN) && + (!(priv->last_status & STATUS_EWARN))) { + netdev_dbg(dev, "entered error warning state\n"); + work_done += c_can_handle_state_change(dev, + C_CAN_ERROR_WARNING); + } + if ((priv->current_status & STATUS_EPASS) && + (!(priv->last_status & STATUS_EPASS))) { + netdev_dbg(dev, "entered error passive state\n"); + work_done += c_can_handle_state_change(dev, + C_CAN_ERROR_PASSIVE); + } + if ((priv->current_status & STATUS_BOFF) && + (!(priv->last_status & STATUS_BOFF))) { + netdev_dbg(dev, "entered bus off state\n"); + work_done += c_can_handle_state_change(dev, + C_CAN_BUS_OFF); + } + + /* handle bus recovery events */ + if ((!(priv->current_status & STATUS_BOFF)) && + (priv->last_status & STATUS_BOFF)) { + netdev_dbg(dev, "left bus off state\n"); + priv->can.state = CAN_STATE_ERROR_ACTIVE; + } + if ((!(priv->current_status & STATUS_EPASS)) && + (priv->last_status & STATUS_EPASS)) { + netdev_dbg(dev, "left error passive state\n"); + priv->can.state = CAN_STATE_ERROR_ACTIVE; + } + + priv->last_status = priv->current_status; + + /* handle lec errors on the bus */ + lec_type = c_can_has_and_handle_berr(priv); + if (lec_type) + work_done += c_can_handle_bus_err(dev, lec_type); + } else if ((irqstatus >= C_CAN_MSG_OBJ_RX_FIRST) && + (irqstatus <= C_CAN_MSG_OBJ_RX_LAST)) { + /* handle events corresponding to receive message objects */ + work_done += c_can_do_rx_poll(dev, (quota - work_done)); + } else if ((irqstatus >= C_CAN_MSG_OBJ_TX_FIRST) && + (irqstatus <= C_CAN_MSG_OBJ_TX_LAST)) { + /* handle events corresponding to transmit message objects */ + c_can_do_tx(dev); + } + +end: + if (work_done < quota) { + napi_complete(napi); + /* enable all IRQs */ + c_can_enable_all_interrupts(priv, ENABLE_ALL_INTERRUPTS); + } + + return work_done; +} + +static irqreturn_t c_can_isr(int irq, void *dev_id) +{ + u16 irqstatus; + struct net_device *dev = (struct net_device *)dev_id; + struct c_can_priv *priv = netdev_priv(dev); + + irqstatus = priv->read_reg(priv, &priv->regs->interrupt); + if (!irqstatus) + return IRQ_NONE; + + /* disable all interrupts and schedule the NAPI */ + c_can_enable_all_interrupts(priv, DISABLE_ALL_INTERRUPTS); + napi_schedule(&priv->napi); + + return IRQ_HANDLED; +} + +static int c_can_open(struct net_device *dev) +{ + int err; + struct c_can_priv *priv = netdev_priv(dev); + + /* open the can device */ + err = open_candev(dev); + if (err) { + netdev_err(dev, "failed to open can device\n"); + return err; + } + + /* register interrupt handler */ + err = request_irq(dev->irq, &c_can_isr, IRQF_SHARED, dev->name, + dev); + if (err < 0) { + netdev_err(dev, "failed to request interrupt\n"); + goto exit_irq_fail; + } + + /* start the c_can controller */ + c_can_start(dev); + + napi_enable(&priv->napi); + netif_start_queue(dev); + + return 0; + +exit_irq_fail: + close_candev(dev); + return err; +} + +static int c_can_close(struct net_device *dev) +{ + struct c_can_priv *priv = netdev_priv(dev); + + netif_stop_queue(dev); + napi_disable(&priv->napi); + c_can_stop(dev); + free_irq(dev->irq, dev); + close_candev(dev); + + return 0; +} + +struct net_device *alloc_c_can_dev(void) +{ + struct net_device *dev; + struct c_can_priv *priv; + + dev = alloc_candev(sizeof(struct c_can_priv), C_CAN_MSG_OBJ_TX_NUM); + if (!dev) + return NULL; + + priv = netdev_priv(dev); + netif_napi_add(dev, &priv->napi, c_can_poll, C_CAN_NAPI_WEIGHT); + + priv->dev = dev; + priv->can.bittiming_const = &c_can_bittiming_const; + priv->can.do_set_mode = c_can_set_mode; + priv->can.do_get_berr_counter = c_can_get_berr_counter; + priv->can.ctrlmode_supported = CAN_CTRLMODE_ONE_SHOT | + CAN_CTRLMODE_LOOPBACK | + CAN_CTRLMODE_LISTENONLY | + CAN_CTRLMODE_BERR_REPORTING; + + return dev; +} +EXPORT_SYMBOL_GPL(alloc_c_can_dev); + +void free_c_can_dev(struct net_device *dev) +{ + free_candev(dev); +} +EXPORT_SYMBOL_GPL(free_c_can_dev); + +static const struct net_device_ops c_can_netdev_ops = { + .ndo_open = c_can_open, + .ndo_stop = c_can_close, + .ndo_start_xmit = c_can_start_xmit, +}; + +int register_c_can_dev(struct net_device *dev) +{ + dev->flags |= IFF_ECHO; /* we support local echo */ + dev->netdev_ops = &c_can_netdev_ops; + + return register_candev(dev); +} +EXPORT_SYMBOL_GPL(register_c_can_dev); + +void unregister_c_can_dev(struct net_device *dev) +{ + struct c_can_priv *priv = netdev_priv(dev); + + /* disable all interrupts */ + c_can_enable_all_interrupts(priv, DISABLE_ALL_INTERRUPTS); + + unregister_candev(dev); +} +EXPORT_SYMBOL_GPL(unregister_c_can_dev); + +MODULE_AUTHOR("Bhupesh Sharma "); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("CAN bus driver for Bosch C_CAN controller"); diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h new file mode 100644 index 000000000000..9b7fbef3d09a --- /dev/null +++ b/drivers/net/can/c_can/c_can.h @@ -0,0 +1,86 @@ +/* + * CAN bus driver for Bosch C_CAN controller + * + * Copyright (C) 2010 ST Microelectronics + * Bhupesh Sharma + * + * Borrowed heavily from the C_CAN driver originally written by: + * Copyright (C) 2007 + * - Sascha Hauer, Marc Kleine-Budde, Pengutronix + * - Simon Kallweit, intefo AG + * + * Bosch C_CAN controller is compliant to CAN protocol version 2.0 part A and B. + * Bosch C_CAN user manual can be obtained from: + * http://www.semiconductors.bosch.de/media/en/pdf/ipmodules_1/c_can/ + * users_manual_c_can.pdf + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef C_CAN_H +#define C_CAN_H + +/* c_can IF registers */ +struct c_can_if_regs { + u16 com_req; + u16 com_mask; + u16 mask1; + u16 mask2; + u16 arb1; + u16 arb2; + u16 msg_cntrl; + u16 data[4]; + u16 _reserved[13]; +}; + +/* c_can hardware registers */ +struct c_can_regs { + u16 control; + u16 status; + u16 err_cnt; + u16 btr; + u16 interrupt; + u16 test; + u16 brp_ext; + u16 _reserved1; + struct c_can_if_regs ifregs[2]; /* [0] = IF1 and [1] = IF2 */ + u16 _reserved2[8]; + u16 txrqst1; + u16 txrqst2; + u16 _reserved3[6]; + u16 newdat1; + u16 newdat2; + u16 _reserved4[6]; + u16 intpnd1; + u16 intpnd2; + u16 _reserved5[6]; + u16 msgval1; + u16 msgval2; + u16 _reserved6[6]; +}; + +/* c_can private data structure */ +struct c_can_priv { + struct can_priv can; /* must be the first member */ + struct napi_struct napi; + struct net_device *dev; + int tx_object; + int current_status; + int last_status; + u16 (*read_reg) (struct c_can_priv *priv, void *reg); + void (*write_reg) (struct c_can_priv *priv, void *reg, u16 val); + struct c_can_regs __iomem *regs; + unsigned long irq_flags; /* for request_irq() */ + unsigned int tx_next; + unsigned int tx_echo; + void *priv; /* for board-specific data */ +}; + +struct net_device *alloc_c_can_dev(void); +void free_c_can_dev(struct net_device *dev); +int register_c_can_dev(struct net_device *dev); +void unregister_c_can_dev(struct net_device *dev); + +#endif /* C_CAN_H */ diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c new file mode 100644 index 000000000000..e629b961ae2d --- /dev/null +++ b/drivers/net/can/c_can/c_can_platform.c @@ -0,0 +1,215 @@ +/* + * Platform CAN bus driver for Bosch C_CAN controller + * + * Copyright (C) 2010 ST Microelectronics + * Bhupesh Sharma + * + * Borrowed heavily from the C_CAN driver originally written by: + * Copyright (C) 2007 + * - Sascha Hauer, Marc Kleine-Budde, Pengutronix + * - Simon Kallweit, intefo AG + * + * Bosch C_CAN controller is compliant to CAN protocol version 2.0 part A and B. + * Bosch C_CAN user manual can be obtained from: + * http://www.semiconductors.bosch.de/media/en/pdf/ipmodules_1/c_can/ + * users_manual_c_can.pdf + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "c_can.h" + +/* + * 16-bit c_can registers can be arranged differently in the memory + * architecture of different implementations. For example: 16-bit + * registers can be aligned to a 16-bit boundary or 32-bit boundary etc. + * Handle the same by providing a common read/write interface. + */ +static u16 c_can_plat_read_reg_aligned_to_16bit(struct c_can_priv *priv, + void *reg) +{ + return readw(reg); +} + +static void c_can_plat_write_reg_aligned_to_16bit(struct c_can_priv *priv, + void *reg, u16 val) +{ + writew(val, reg); +} + +static u16 c_can_plat_read_reg_aligned_to_32bit(struct c_can_priv *priv, + void *reg) +{ + return readw(reg + (long)reg - (long)priv->regs); +} + +static void c_can_plat_write_reg_aligned_to_32bit(struct c_can_priv *priv, + void *reg, u16 val) +{ + writew(val, reg + (long)reg - (long)priv->regs); +} + +static int __devinit c_can_plat_probe(struct platform_device *pdev) +{ + int ret; + void __iomem *addr; + struct net_device *dev; + struct c_can_priv *priv; + struct resource *mem, *irq; +#ifdef CONFIG_HAVE_CLK + struct clk *clk; + + /* get the appropriate clk */ + clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "no clock defined\n"); + ret = -ENODEV; + goto exit; + } +#endif + + /* get the platform data */ + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!mem || (irq <= 0)) { + ret = -ENODEV; + goto exit_free_clk; + } + + if (!request_mem_region(mem->start, resource_size(mem), + KBUILD_MODNAME)) { + dev_err(&pdev->dev, "resource unavailable\n"); + ret = -ENODEV; + goto exit_free_clk; + } + + addr = ioremap(mem->start, resource_size(mem)); + if (!addr) { + dev_err(&pdev->dev, "failed to map can port\n"); + ret = -ENOMEM; + goto exit_release_mem; + } + + /* allocate the c_can device */ + dev = alloc_c_can_dev(); + if (!dev) { + ret = -ENOMEM; + goto exit_iounmap; + } + + priv = netdev_priv(dev); + + dev->irq = irq->start; + priv->regs = addr; +#ifdef CONFIG_HAVE_CLK + priv->can.clock.freq = clk_get_rate(clk); + priv->priv = clk; +#endif + + switch (mem->flags & IORESOURCE_MEM_TYPE_MASK) { + case IORESOURCE_MEM_32BIT: + priv->read_reg = c_can_plat_read_reg_aligned_to_32bit; + priv->write_reg = c_can_plat_write_reg_aligned_to_32bit; + break; + case IORESOURCE_MEM_16BIT: + default: + priv->read_reg = c_can_plat_read_reg_aligned_to_16bit; + priv->write_reg = c_can_plat_write_reg_aligned_to_16bit; + break; + } + + platform_set_drvdata(pdev, dev); + SET_NETDEV_DEV(dev, &pdev->dev); + + ret = register_c_can_dev(dev); + if (ret) { + dev_err(&pdev->dev, "registering %s failed (err=%d)\n", + KBUILD_MODNAME, ret); + goto exit_free_device; + } + + dev_info(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n", + KBUILD_MODNAME, priv->regs, dev->irq); + return 0; + +exit_free_device: + platform_set_drvdata(pdev, NULL); + free_c_can_dev(dev); +exit_iounmap: + iounmap(addr); +exit_release_mem: + release_mem_region(mem->start, resource_size(mem)); +exit_free_clk: +#ifdef CONFIG_HAVE_CLK + clk_put(clk); +exit: +#endif + dev_err(&pdev->dev, "probe failed\n"); + + return ret; +} + +static int __devexit c_can_plat_remove(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata(pdev); + struct c_can_priv *priv = netdev_priv(dev); + struct resource *mem; + + unregister_c_can_dev(dev); + platform_set_drvdata(pdev, NULL); + + free_c_can_dev(dev); + iounmap(priv->regs); + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(mem->start, resource_size(mem)); + +#ifdef CONFIG_HAVE_CLK + clk_put(priv->priv); +#endif + + return 0; +} + +static struct platform_driver c_can_plat_driver = { + .driver = { + .name = KBUILD_MODNAME, + .owner = THIS_MODULE, + }, + .probe = c_can_plat_probe, + .remove = __devexit_p(c_can_plat_remove), +}; + +static int __init c_can_plat_init(void) +{ + return platform_driver_register(&c_can_plat_driver); +} +module_init(c_can_plat_init); + +static void __exit c_can_plat_exit(void) +{ + platform_driver_unregister(&c_can_plat_driver); +} +module_exit(c_can_plat_exit); + +MODULE_AUTHOR("Bhupesh Sharma "); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Platform CAN bus driver for Bosch C_CAN controller"); -- cgit v1.2.3 From a646bd7f0824d3e0f02ff8d7410704f965de01bc Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Mon, 31 Jan 2011 13:22:29 +0100 Subject: dma: ipu_idmac: do not lose valid received data in the irq handler Currently when two or more buffers are queued by the camera driver and so the double buffering is enabled in the idmac, we lose one frame comming from CSI since the reporting of arrival of the first frame is deferred by the DMAIC_7_EOF interrupt handler and reporting of the arrival of the last frame is not done at all. So when requesting N frames from the image sensor we actually receive N - 1 frames in user space. The reason for this behaviour is that the DMAIC_7_EOF interrupt handler misleadingly assumes that the CUR_BUF flag is pointing to the buffer used by the IDMAC. Actually it is not the case since the CUR_BUF flag will be flipped by the FSU when the FSU is sending the _NEW_FRM_RDY signal when new frame data is delivered by the CSI. When sending this singal, FSU updates the DMA_CUR_BUF and the DMA_BUFx_RDY flags: the DMA_CUR_BUF is flipped, the DMA_BUFx_RDY is cleared, indicating that the frame data is beeing written by the IDMAC to the pointed buffer. DMA_BUFx_RDY is supposed to be set to the ready state again by the MCU, when it has handled the received data. DMAIC_7_CUR_BUF flag won't be flipped here by the IPU, so waiting for this event in the EOF interrupt handler is wrong. Actually there is no spurious interrupt as described in the comments, this is the valid DMAIC_7_EOF interrupt indicating reception of the frame from CSI. The patch removes code that waits for flipping of the DMAIC_7_CUR_BUF flag in the DMAIC_7_EOF interrupt handler. As the comment in the current code denotes, this waiting doesn't help anyway. As a result of this removal the reporting of the first arrived frame is not deferred to the time of arrival of the next frame and the drivers software flag 'ichan->active_buffer' is in sync with DMAIC_7_CUR_BUF flag, so the reception of all requested frames works. This has been verified on the hardware which is triggering the image sensor by the programmable state machine, allowing to obtain exact number of frames. On this hardware we do not tolerate losing frames. This patch also removes resetting the DMA_BUFx_RDY flags of all channels in ipu_disable_channel() since transfers on other DMA channels might be triggered by other running tasks and the buffers should always be ready for data sending or reception. Signed-off-by: Anatolij Gustschin Reviewed-by: Guennadi Liakhovetski Tested-by: Guennadi Liakhovetski Signed-off-by: Dan Williams --- drivers/dma/ipu/ipu_idmac.c | 50 --------------------------------------------- 1 file changed, 50 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index cb26ee9773d6..c1a125e7d1df 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1145,29 +1145,6 @@ static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan, reg = idmac_read_icreg(ipu, IDMAC_CHA_EN); idmac_write_icreg(ipu, reg & ~chan_mask, IDMAC_CHA_EN); - /* - * Problem (observed with channel DMAIC_7): after enabling the channel - * and initialising buffers, there comes an interrupt with current still - * pointing at buffer 0, whereas it should use buffer 0 first and only - * generate an interrupt when it is done, then current should already - * point to buffer 1. This spurious interrupt also comes on channel - * DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the - * first interrupt, there comes the second with current correctly - * pointing to buffer 1 this time. But sometimes this second interrupt - * doesn't come and the channel hangs. Clearing BUFx_RDY when disabling - * the channel seems to prevent the channel from hanging, but it doesn't - * prevent the spurious interrupt. This might also be unsafe. Think - * about the IDMAC controller trying to switch to a buffer, when we - * clear the ready bit, and re-enable it a moment later. - */ - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY); - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY); - idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF0_RDY); - - reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY); - idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY); - idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF1_RDY); - spin_unlock_irqrestore(&ipu->lock, flags); return 0; @@ -1246,33 +1223,6 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id) /* Other interrupts do not interfere with this channel */ spin_lock(&ichan->lock); - if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 && - ((curbuf >> chan_id) & 1) == ichan->active_buffer && - !list_is_last(ichan->queue.next, &ichan->queue))) { - int i = 100; - - /* This doesn't help. See comment in ipu_disable_channel() */ - while (--i) { - curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); - if (((curbuf >> chan_id) & 1) != ichan->active_buffer) - break; - cpu_relax(); - } - - if (!i) { - spin_unlock(&ichan->lock); - dev_dbg(dev, - "IRQ on active buffer on channel %x, active " - "%d, ready %x, %x, current %x!\n", chan_id, - ichan->active_buffer, ready0, ready1, curbuf); - return IRQ_NONE; - } else - dev_dbg(dev, - "Buffer deactivated on channel %x, active " - "%d, ready %x, %x, current %x, rest %d!\n", chan_id, - ichan->active_buffer, ready0, ready1, curbuf, i); - } - if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) || (!ichan->active_buffer && (ready0 >> chan_id) & 1) )) { -- cgit v1.2.3 From 168202c7bf89d7a2abaf8deaf4bbed18a1f7b3a3 Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Tue, 15 Feb 2011 00:13:32 +0800 Subject: mrst/vrtc: Avoid using cmos rtc ops If we don't assign Moorestown specific wallclock init and ops function the rtc/persisent clock code will use cmos rtc for access, this will crash Moorestown in that the ioports are not present. Also in vrtc driver, should avoid using cmos access to check UIP status. [feng.tang@intel.com: use set_fixmap_offset_nocache() to simplify code] Signed-off-by: Jacob Pan Signed-off-by: Feng Tang Signed-off-by: Alan Cox Signed-off-by: Thomas Gleixner --- arch/x86/platform/mrst/mrst.c | 2 ++ arch/x86/platform/mrst/vrtc.c | 16 ++++------------ drivers/rtc/rtc-mrst.c | 13 ++++++++++++- 3 files changed, 18 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c index fee0b4914e07..4c542c757cb4 100644 --- a/arch/x86/platform/mrst/mrst.c +++ b/arch/x86/platform/mrst/mrst.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -294,6 +295,7 @@ void __init x86_mrst_early_setup(void) x86_platform.calibrate_tsc = mrst_calibrate_tsc; x86_platform.i8042_detect = mrst_i8042_detect; + x86_init.timers.wallclock_init = mrst_rtc_init; x86_init.pci.init = pci_mrst_init; x86_init.pci.fixup_irqs = x86_init_noop; diff --git a/arch/x86/platform/mrst/vrtc.c b/arch/x86/platform/mrst/vrtc.c index 32cd7edd71a0..04cf645feb92 100644 --- a/arch/x86/platform/mrst/vrtc.c +++ b/arch/x86/platform/mrst/vrtc.c @@ -100,22 +100,14 @@ int vrtc_set_mmss(unsigned long nowtime) void __init mrst_rtc_init(void) { - unsigned long rtc_paddr; - void __iomem *virt_base; + unsigned long vrtc_paddr = sfi_mrtc_array[0].phys_addr; sfi_table_parse(SFI_SIG_MRTC, NULL, NULL, sfi_parse_mrtc); - if (!sfi_mrtc_num) + if (!sfi_mrtc_num || !vrtc_paddr) return; - rtc_paddr = sfi_mrtc_array[0].phys_addr; - - /* vRTC's register address may not be page aligned */ - set_fixmap_nocache(FIX_LNW_VRTC, rtc_paddr); - - virt_base = (void __iomem *)__fix_to_virt(FIX_LNW_VRTC); - virt_base += rtc_paddr & ~PAGE_MASK; - vrtc_virt_base = virt_base; - + vrtc_virt_base = (void __iomem *)set_fixmap_offset_nocache(FIX_LNW_VRTC, + vrtc_paddr); x86_platform.get_wallclock = vrtc_get_time; x86_platform.set_wallclock = vrtc_set_mmss; } diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c index bcd0cf63eb16..28e02e7580f4 100644 --- a/drivers/rtc/rtc-mrst.c +++ b/drivers/rtc/rtc-mrst.c @@ -62,6 +62,17 @@ static inline int is_intr(u8 rtc_intr) return rtc_intr & RTC_IRQMASK; } +static inline unsigned char vrtc_is_updating(void) +{ + unsigned char uip; + unsigned long flags; + + spin_lock_irqsave(&rtc_lock, flags); + uip = (vrtc_cmos_read(RTC_FREQ_SELECT) & RTC_UIP); + spin_unlock_irqrestore(&rtc_lock, flags); + return uip; +} + /* * rtc_time's year contains the increment over 1900, but vRTC's YEAR * register can't be programmed to value larger than 0x64, so vRTC @@ -76,7 +87,7 @@ static int mrst_read_time(struct device *dev, struct rtc_time *time) { unsigned long flags; - if (rtc_is_updating()) + if (vrtc_is_updating()) mdelay(20); spin_lock_irqsave(&rtc_lock, flags); -- cgit v1.2.3 From ddfdb508866b3c07b295f6c85c271981d88afe4c Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Mon, 14 Feb 2011 11:44:01 -0800 Subject: net/can/softing: make CAN_SOFTING_CS depend on CAN_SOFTING The statement 'select CAN_SOFTING' may ignore the dependancies for CAN_SOFTING while selecting CAN_SOFTING_CS, as is therefore a bad choice. Signed-off-by: Kurt Van Dijck Acked-by: Randy Dunlap Signed-off-by: David S. Miller --- drivers/net/can/softing/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/softing/Kconfig b/drivers/net/can/softing/Kconfig index 8ba81b3ddd90..5de46a9a77bb 100644 --- a/drivers/net/can/softing/Kconfig +++ b/drivers/net/can/softing/Kconfig @@ -18,7 +18,7 @@ config CAN_SOFTING config CAN_SOFTING_CS tristate "Softing Gmbh CAN pcmcia cards" depends on PCMCIA - select CAN_SOFTING + depends on CAN_SOFTING ---help--- Support for PCMCIA cards from Softing Gmbh & some cards from Vector Gmbh. -- cgit v1.2.3 From d76dfc612b40b6a9de0a3fe57fe1fa3db7a1ae3b Mon Sep 17 00:00:00 2001 From: Seth Forshee Date: Mon, 14 Feb 2011 08:52:25 -0600 Subject: rt2x00: Check for errors from skb_pad() calls Commit 739fd94 ("rt2x00: Pad beacon to multiple of 32 bits") added calls to skb_pad() without checking the return value, which could cause problems if any of those calls does happen to fail. Add checks to prevent this from happening. Signed-off-by: Seth Forshee Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 12 ++++++++++-- drivers/net/wireless/rt2x00/rt61pci.c | 12 ++++++++++-- drivers/net/wireless/rt2x00/rt73usb.c | 12 ++++++++++-- 3 files changed, 30 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index c9bf074342ba..7a68a67c506a 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -773,13 +773,14 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); unsigned int beacon_base; unsigned int padding_len; - u32 reg; + u32 orig_reg, reg; /* * Disable beaconing while we are reloading the beacon data, * otherwise we might be sending out invalid data. */ rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); + orig_reg = reg; rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); @@ -810,7 +811,14 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) * Write entire beacon with TXWI and padding to register. */ padding_len = roundup(entry->skb->len, 4) - entry->skb->len; - skb_pad(entry->skb, padding_len); + if (padding_len && skb_pad(entry->skb, padding_len)) { + ERROR(rt2x00dev, "Failure padding beacon, aborting\n"); + /* skb freed by skb_pad() on failure */ + entry->skb = NULL; + rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg); + return; + } + beacon_base = HW_BEACON_OFFSET(entry->entry_idx); rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, entry->skb->len + padding_len); diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index dd2164d4d57b..927a4a3e0eeb 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1978,13 +1978,14 @@ static void rt61pci_write_beacon(struct queue_entry *entry, struct queue_entry_priv_pci *entry_priv = entry->priv_data; unsigned int beacon_base; unsigned int padding_len; - u32 reg; + u32 orig_reg, reg; /* * Disable beaconing while we are reloading the beacon data, * otherwise we might be sending out invalid data. */ rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); + orig_reg = reg; rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); @@ -2002,7 +2003,14 @@ static void rt61pci_write_beacon(struct queue_entry *entry, * Write entire beacon with descriptor and padding to register. */ padding_len = roundup(entry->skb->len, 4) - entry->skb->len; - skb_pad(entry->skb, padding_len); + if (padding_len && skb_pad(entry->skb, padding_len)) { + ERROR(rt2x00dev, "Failure padding beacon, aborting\n"); + /* skb freed by skb_pad() on failure */ + entry->skb = NULL; + rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, orig_reg); + return; + } + beacon_base = HW_BEACON_OFFSET(entry->entry_idx); rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, entry_priv->desc, TXINFO_SIZE); diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 5ff72deea8d4..6e9981a1dd7f 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1533,13 +1533,14 @@ static void rt73usb_write_beacon(struct queue_entry *entry, struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; unsigned int beacon_base; unsigned int padding_len; - u32 reg; + u32 orig_reg, reg; /* * Disable beaconing while we are reloading the beacon data, * otherwise we might be sending out invalid data. */ rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); + orig_reg = reg; rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); @@ -1563,7 +1564,14 @@ static void rt73usb_write_beacon(struct queue_entry *entry, * Write entire beacon with descriptor and padding to register. */ padding_len = roundup(entry->skb->len, 4) - entry->skb->len; - skb_pad(entry->skb, padding_len); + if (padding_len && skb_pad(entry->skb, padding_len)) { + ERROR(rt2x00dev, "Failure padding beacon, aborting\n"); + /* skb freed by skb_pad() on failure */ + entry->skb = NULL; + rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, orig_reg); + return; + } + beacon_base = HW_BEACON_OFFSET(entry->entry_idx); rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, entry->skb->len + padding_len); -- cgit v1.2.3 From 014cf3bb1e19a61c53666d7f990f584f1b7af364 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 9 Feb 2011 17:46:39 +0530 Subject: ath9k: disable beaconing before stopping beacon queue Beaconing should be disabled before stopping beacon queue. Not doing so could queue up beacons in hw that causes failure to stop Tx DMA, due to pending frames in hw and also unnecessary beacon tasklet schedule. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 ++ drivers/net/wireless/ath/ath9k/beacon.c | 37 ++++++++++++++++++++++++++++++++- drivers/net/wireless/ath/ath9k/main.c | 35 +++++++++++++------------------ 3 files changed, 52 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 56dee3719f95..4d60583b0f69 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -348,6 +348,7 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid struct ath_vif { int av_bslot; + bool is_bslot_active; __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ enum nl80211_iftype av_opmode; struct ath_buf *av_bcbuf; @@ -402,6 +403,7 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif); int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif); void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp); int ath_beaconq_config(struct ath_softc *sc); +void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); /*******/ /* ANI */ diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index ed6e7d66fc38..a4bdfdb043ef 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -143,7 +143,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, avp = (void *)vif->drv_priv; cabq = sc->beacon.cabq; - if (avp->av_bcbuf == NULL) + if ((avp->av_bcbuf == NULL) || !avp->is_bslot_active) return NULL; /* Release the old beacon first */ @@ -249,6 +249,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif) for (slot = 0; slot < ATH_BCBUF; slot++) if (sc->beacon.bslot[slot] == NULL) { avp->av_bslot = slot; + avp->is_bslot_active = false; /* NB: keep looking for a double slot */ if (slot == 0 || !sc->beacon.bslot[slot-1]) @@ -315,6 +316,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif) ath_err(common, "dma_mapping_error on beacon alloc\n"); return -ENOMEM; } + avp->is_bslot_active = true; return 0; } @@ -749,3 +751,36 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) sc->sc_flags |= SC_OP_BEACONS; } + +void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath_vif *avp; + int slot; + bool found = false; + + ath9k_ps_wakeup(sc); + if (status) { + for (slot = 0; slot < ATH_BCBUF; slot++) { + if (sc->beacon.bslot[slot]) { + avp = (void *)sc->beacon.bslot[slot]->drv_priv; + if (avp->is_bslot_active) { + found = true; + break; + } + } + } + if (found) { + /* Re-enable beaconing */ + ah->imask |= ATH9K_INT_SWBA; + ath9k_hw_set_interrupts(ah, ah->imask); + } + } else { + /* Disable SWBA interrupt */ + ah->imask &= ~ATH9K_INT_SWBA; + ath9k_hw_set_interrupts(ah, ah->imask); + tasklet_kill(&sc->bcon_tasklet); + ath9k_hw_stoptxdma(ah, sc->beacon.beaconq); + } + ath9k_ps_restore(sc); +} diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 8469d7c8744a..31f0fad72391 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1293,24 +1293,10 @@ static void ath9k_reclaim_beacon(struct ath_softc *sc, { struct ath_vif *avp = (void *)vif->drv_priv; - /* Disable SWBA interrupt */ - sc->sc_ah->imask &= ~ATH9K_INT_SWBA; - ath9k_ps_wakeup(sc); - ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); - ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); - tasklet_kill(&sc->bcon_tasklet); - ath9k_ps_restore(sc); - + ath9k_set_beaconing_status(sc, false); ath_beacon_return(sc, avp); + ath9k_set_beaconing_status(sc, true); sc->sc_flags &= ~SC_OP_BEACONS; - - if (sc->nbcnvifs > 0) { - /* Re-enable beaconing */ - sc->sc_ah->imask |= ATH9K_INT_SWBA; - ath9k_ps_wakeup(sc); - ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); - ath9k_ps_restore(sc); - } } static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) @@ -1438,16 +1424,17 @@ static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw, if (ath9k_uses_beacons(vif->type)) { int error; - ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); /* This may fail because upper levels do not have beacons * properly configured yet. That's OK, we assume it * will be properly configured and then we will be notified * in the info_changed method and set up beacons properly * there. */ + ath9k_set_beaconing_status(sc, false); error = ath_beacon_alloc(sc, vif); if (!error) ath_beacon_config(sc, vif); + ath9k_set_beaconing_status(sc, true); } } @@ -1920,10 +1907,11 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, /* Enable transmission of beacons (AP, IBSS, MESH) */ if ((changed & BSS_CHANGED_BEACON) || ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) { - ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); + ath9k_set_beaconing_status(sc, false); error = ath_beacon_alloc(sc, vif); if (!error) ath_beacon_config(sc, vif); + ath9k_set_beaconing_status(sc, true); } if (changed & BSS_CHANGED_ERP_SLOT) { @@ -1946,8 +1934,12 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, } /* Disable transmission of beacons */ - if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) - ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); + if ((changed & BSS_CHANGED_BEACON_ENABLED) && + !bss_conf->enable_beacon) { + ath9k_set_beaconing_status(sc, false); + avp->is_bslot_active = false; + ath9k_set_beaconing_status(sc, true); + } if (changed & BSS_CHANGED_BEACON_INT) { cur_conf->beacon_interval = bss_conf->beacon_int; @@ -1957,10 +1949,11 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, */ if (vif->type == NL80211_IFTYPE_AP) { sc->sc_flags |= SC_OP_TSF_RESET; - ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); + ath9k_set_beaconing_status(sc, false); error = ath_beacon_alloc(sc, vif); if (!error) ath_beacon_config(sc, vif); + ath9k_set_beaconing_status(sc, true); } else { ath_beacon_config(sc, vif); } -- cgit v1.2.3 From 37939810b937aba830dd751291fcdc51cae1a6cb Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Sat, 12 Feb 2011 20:43:23 +0200 Subject: zd1211rw: correct use of usb_bulk_msg on interrupt endpoints zd1211rw is using usb_bulk_msg() with usb_sndbulkpipe() on interrupt endpoint. However usb_bulk_msg() internally corrects this and makes interrupt URB. It's better to change usb_bulk_msgs in zd1211rw to usb_interrupt_msg for less confusion. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_usb.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index f6df3665fdb6..7346512158e8 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -1634,15 +1634,15 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, udev = zd_usb_to_usbdev(usb); prepare_read_regs_int(usb); - r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT), - req, req_len, &actual_req_len, 50 /* ms */); + r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT), + req, req_len, &actual_req_len, 50 /* ms */); if (r) { dev_dbg_f(zd_usb_dev(usb), - "error in usb_bulk_msg(). Error number %d\n", r); + "error in usb_interrupt_msg(). Error number %d\n", r); goto error; } if (req_len != actual_req_len) { - dev_dbg_f(zd_usb_dev(usb), "error in usb_bulk_msg()\n" + dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()\n" " req_len %d != actual_req_len %d\n", req_len, actual_req_len); r = -EIO; @@ -1705,16 +1705,16 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, } udev = zd_usb_to_usbdev(usb); - r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT), - req, req_len, &actual_req_len, 50 /* ms */); + r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT), + req, req_len, &actual_req_len, 50 /* ms */); if (r) { dev_dbg_f(zd_usb_dev(usb), - "error in usb_bulk_msg(). Error number %d\n", r); + "error in usb_interrupt_msg(). Error number %d\n", r); goto error; } if (req_len != actual_req_len) { dev_dbg_f(zd_usb_dev(usb), - "error in usb_bulk_msg()" + "error in usb_interrupt_msg()" " req_len %d != actual_req_len %d\n", req_len, actual_req_len); r = -EIO; @@ -1794,15 +1794,15 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits) } udev = zd_usb_to_usbdev(usb); - r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT), - req, req_len, &actual_req_len, 50 /* ms */); + r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT), + req, req_len, &actual_req_len, 50 /* ms */); if (r) { dev_dbg_f(zd_usb_dev(usb), - "error in usb_bulk_msg(). Error number %d\n", r); + "error in usb_interrupt_msg(). Error number %d\n", r); goto out; } if (req_len != actual_req_len) { - dev_dbg_f(zd_usb_dev(usb), "error in usb_bulk_msg()" + dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()" " req_len %d != actual_req_len %d\n", req_len, actual_req_len); r = -EIO; -- cgit v1.2.3 From eefdbec1ea8b7093d2c09d1825f68438701723cf Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Sat, 12 Feb 2011 20:43:32 +0200 Subject: zd1211rw: use async urb for write command Writing beacon to device happen through multiple write command calls. zd_usb_iowrite16v uses synchronous urb call and with multiple write commands in row causes high CPU usage. This patch makes zd_usb_iowrite16v use asynchronous urb submit within zd_usb.c. zd_usb_iowrite16v_async_start is used to initiate writing multiple commands to device using zd_usb_iowrite16v_async. Each URB is delayed and submitted to device by next zd_usb_iowrite16v_async call or by call to zd_usb_iowrite16v_async_end. URBs submitted by zd_usb_iowrite16v_async have URB_NO_INTERRUPT set and last URB send by zd_usb_iowrite16v_async_end does not. This lower CPU usage when doing writes that require multiple URBs. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_usb.c | 162 ++++++++++++++++++++++++++++----- drivers/net/wireless/zd1211rw/zd_usb.h | 5 +- 2 files changed, 142 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 7346512158e8..c98f6e7eed3d 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -1156,6 +1156,7 @@ void zd_usb_init(struct zd_usb *usb, struct ieee80211_hw *hw, memset(usb, 0, sizeof(*usb)); usb->intf = usb_get_intf(intf); usb_set_intfdata(usb->intf, hw); + init_usb_anchor(&usb->submitted_cmds); init_usb_interrupt(usb); init_usb_tx(usb); init_usb_rx(usb); @@ -1663,13 +1664,104 @@ error: return r; } -int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, - unsigned int count) +static void iowrite16v_urb_complete(struct urb *urb) +{ + struct zd_usb *usb = urb->context; + + if (urb->status && !usb->cmd_error) + usb->cmd_error = urb->status; +} + +static int zd_submit_waiting_urb(struct zd_usb *usb, bool last) +{ + int r; + struct urb *urb = usb->urb_async_waiting; + + if (!urb) + return 0; + + usb->urb_async_waiting = NULL; + + if (!last) + urb->transfer_flags |= URB_NO_INTERRUPT; + + usb_anchor_urb(urb, &usb->submitted_cmds); + r = usb_submit_urb(urb, GFP_KERNEL); + if (r) { + usb_unanchor_urb(urb); + dev_dbg_f(zd_usb_dev(usb), + "error in usb_submit_urb(). Error number %d\n", r); + goto error; + } + + /* fall-through with r == 0 */ +error: + usb_free_urb(urb); + return r; +} + +static void zd_usb_iowrite16v_async_start(struct zd_usb *usb) +{ + ZD_ASSERT(usb_anchor_empty(&usb->submitted_cmds)); + ZD_ASSERT(usb->urb_async_waiting == NULL); + ZD_ASSERT(!usb->in_async); + + ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); + + usb->in_async = 1; + usb->cmd_error = 0; + usb->urb_async_waiting = NULL; +} + +static int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout) +{ + int r; + + ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); + ZD_ASSERT(usb->in_async); + + /* Submit last iowrite16v URB */ + r = zd_submit_waiting_urb(usb, true); + if (r) { + dev_dbg_f(zd_usb_dev(usb), + "error in zd_submit_waiting_usb(). " + "Error number %d\n", r); + + usb_kill_anchored_urbs(&usb->submitted_cmds); + goto error; + } + + if (timeout) + timeout = usb_wait_anchor_empty_timeout(&usb->submitted_cmds, + timeout); + if (!timeout) { + usb_kill_anchored_urbs(&usb->submitted_cmds); + if (usb->cmd_error == -ENOENT) { + dev_dbg_f(zd_usb_dev(usb), "timed out"); + r = -ETIMEDOUT; + goto error; + } + } + + r = usb->cmd_error; +error: + usb->in_async = 0; + return r; +} + +static int zd_usb_iowrite16v_async(struct zd_usb *usb, + const struct zd_ioreq16 *ioreqs, + unsigned int count) { int r; struct usb_device *udev; struct usb_req_write_regs *req = NULL; - int i, req_len, actual_req_len; + int i, req_len; + struct urb *urb; + struct usb_host_endpoint *ep; + + ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); + ZD_ASSERT(usb->in_async); if (count == 0) return 0; @@ -1685,17 +1777,23 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, return -EWOULDBLOCK; } - ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); - BUILD_BUG_ON(sizeof(struct usb_req_write_regs) + - USB_MAX_IOWRITE16_COUNT * sizeof(struct reg_data) > - sizeof(usb->req_buf)); - BUG_ON(sizeof(struct usb_req_write_regs) + - count * sizeof(struct reg_data) > - sizeof(usb->req_buf)); + udev = zd_usb_to_usbdev(usb); + + ep = usb_pipe_endpoint(udev, usb_sndintpipe(udev, EP_REGS_OUT)); + if (!ep) + return -ENOENT; + + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) + return -ENOMEM; req_len = sizeof(struct usb_req_write_regs) + count * sizeof(struct reg_data); - req = (void *)usb->req_buf; + req = kmalloc(req_len, GFP_KERNEL); + if (!req) { + r = -ENOMEM; + goto error; + } req->id = cpu_to_le16(USB_REQ_WRITE_REGS); for (i = 0; i < count; i++) { @@ -1704,28 +1802,44 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, rw->value = cpu_to_le16(ioreqs[i].value); } - udev = zd_usb_to_usbdev(usb); - r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT), - req, req_len, &actual_req_len, 50 /* ms */); + usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT), + req, req_len, iowrite16v_urb_complete, usb, + ep->desc.bInterval); + urb->transfer_flags |= URB_FREE_BUFFER | URB_SHORT_NOT_OK; + + /* Submit previous URB */ + r = zd_submit_waiting_urb(usb, false); if (r) { dev_dbg_f(zd_usb_dev(usb), - "error in usb_interrupt_msg(). Error number %d\n", r); - goto error; - } - if (req_len != actual_req_len) { - dev_dbg_f(zd_usb_dev(usb), - "error in usb_interrupt_msg()" - " req_len %d != actual_req_len %d\n", - req_len, actual_req_len); - r = -EIO; + "error in zd_submit_waiting_usb(). " + "Error number %d\n", r); goto error; } - /* FALL-THROUGH with r == 0 */ + /* Delay submit so that URB_NO_INTERRUPT flag can be set for all URBs + * of currect batch except for very last. + */ + usb->urb_async_waiting = urb; + return 0; error: + usb_free_urb(urb); return r; } +int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, + unsigned int count) +{ + int r; + + zd_usb_iowrite16v_async_start(usb); + r = zd_usb_iowrite16v_async(usb, ioreqs, count); + if (r) { + zd_usb_iowrite16v_async_end(usb, 0); + return r; + } + return zd_usb_iowrite16v_async_end(usb, 50 /* ms */); +} + int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits) { int r; diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index 2d688f48a34c..929142692063 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h @@ -217,8 +217,11 @@ struct zd_usb { struct zd_usb_rx rx; struct zd_usb_tx tx; struct usb_interface *intf; + struct usb_anchor submitted_cmds; + struct urb *urb_async_waiting; + int cmd_error; u8 req_buf[64]; /* zd_usb_iowrite16v needs 62 bytes */ - u8 is_zd1211b:1, initialized:1, was_running:1; + u8 is_zd1211b:1, initialized:1, was_running:1, in_async:1; }; #define zd_usb_dev(usb) (&usb->intf->dev) -- cgit v1.2.3 From 8662b2518ff7995002378058488326ef7cb80de8 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Sat, 12 Feb 2011 20:43:42 +0200 Subject: zd1211rw: move async iowrite16v up to callers Writing beacon to device happen through multiple write command calls. zd_usb_iowrite16v uses synchronous urb call and with multiple write commands in row causes high CPU usage. Make asynchronous zd_usb_iowrite16v_async available outside zd_usb.c and use where possible. This lower CPU usage from ~10% to ~2% on Intel Atom when running AP-mode with 100 TU beacon interval. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_chip.c | 35 ++++++++++++++++++++++++++------- drivers/net/wireless/zd1211rw/zd_usb.c | 11 +++++------ drivers/net/wireless/zd1211rw/zd_usb.h | 4 ++++ 3 files changed, 37 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 54f68f134ea7..a73a305d3cba 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -142,8 +142,9 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr return 0; } -int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, - unsigned int count) +static int _zd_iowrite32v_async_locked(struct zd_chip *chip, + const struct zd_ioreq32 *ioreqs, + unsigned int count) { int i, j, r; struct zd_ioreq16 ioreqs16[USB_MAX_IOWRITE32_COUNT * 2]; @@ -170,7 +171,7 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, ioreqs16[j+1].addr = ioreqs[i].addr; } - r = zd_usb_iowrite16v(&chip->usb, ioreqs16, count16); + r = zd_usb_iowrite16v_async(&chip->usb, ioreqs16, count16); #ifdef DEBUG if (r) { dev_dbg_f(zd_chip_dev(chip), @@ -180,6 +181,20 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, return r; } +int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, + unsigned int count) +{ + int r; + + zd_usb_iowrite16v_async_start(&chip->usb); + r = _zd_iowrite32v_async_locked(chip, ioreqs, count); + if (r) { + zd_usb_iowrite16v_async_end(&chip->usb, 0); + return r; + } + return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */); +} + int zd_iowrite16a_locked(struct zd_chip *chip, const struct zd_ioreq16 *ioreqs, unsigned int count) { @@ -187,6 +202,8 @@ int zd_iowrite16a_locked(struct zd_chip *chip, unsigned int i, j, t, max; ZD_ASSERT(mutex_is_locked(&chip->mutex)); + zd_usb_iowrite16v_async_start(&chip->usb); + for (i = 0; i < count; i += j + t) { t = 0; max = count-i; @@ -199,8 +216,9 @@ int zd_iowrite16a_locked(struct zd_chip *chip, } } - r = zd_usb_iowrite16v(&chip->usb, &ioreqs[i], j); + r = zd_usb_iowrite16v_async(&chip->usb, &ioreqs[i], j); if (r) { + zd_usb_iowrite16v_async_end(&chip->usb, 0); dev_dbg_f(zd_chip_dev(chip), "error zd_usb_iowrite16v. Error number %d\n", r); @@ -208,7 +226,7 @@ int zd_iowrite16a_locked(struct zd_chip *chip, } } - return 0; + return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */); } /* Writes a variable number of 32 bit registers. The functions will split @@ -221,6 +239,8 @@ int zd_iowrite32a_locked(struct zd_chip *chip, int r; unsigned int i, j, t, max; + zd_usb_iowrite16v_async_start(&chip->usb); + for (i = 0; i < count; i += j + t) { t = 0; max = count-i; @@ -233,8 +253,9 @@ int zd_iowrite32a_locked(struct zd_chip *chip, } } - r = _zd_iowrite32v_locked(chip, &ioreqs[i], j); + r = _zd_iowrite32v_async_locked(chip, &ioreqs[i], j); if (r) { + zd_usb_iowrite16v_async_end(&chip->usb, 0); dev_dbg_f(zd_chip_dev(chip), "error _zd_iowrite32v_locked." " Error number %d\n", r); @@ -242,7 +263,7 @@ int zd_iowrite32a_locked(struct zd_chip *chip, } } - return 0; + return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */); } int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value) diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index c98f6e7eed3d..81e80489a052 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -1674,7 +1674,7 @@ static void iowrite16v_urb_complete(struct urb *urb) static int zd_submit_waiting_urb(struct zd_usb *usb, bool last) { - int r; + int r = 0; struct urb *urb = usb->urb_async_waiting; if (!urb) @@ -1700,7 +1700,7 @@ error: return r; } -static void zd_usb_iowrite16v_async_start(struct zd_usb *usb) +void zd_usb_iowrite16v_async_start(struct zd_usb *usb) { ZD_ASSERT(usb_anchor_empty(&usb->submitted_cmds)); ZD_ASSERT(usb->urb_async_waiting == NULL); @@ -1713,7 +1713,7 @@ static void zd_usb_iowrite16v_async_start(struct zd_usb *usb) usb->urb_async_waiting = NULL; } -static int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout) +int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout) { int r; @@ -1749,9 +1749,8 @@ error: return r; } -static int zd_usb_iowrite16v_async(struct zd_usb *usb, - const struct zd_ioreq16 *ioreqs, - unsigned int count) +int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, + unsigned int count) { int r; struct usb_device *udev; diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index 929142692063..b3df2c8116cc 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h @@ -273,6 +273,10 @@ static inline int zd_usb_ioread16(struct zd_usb *usb, u16 *value, return zd_usb_ioread16v(usb, value, (const zd_addr_t *)&addr, 1); } +void zd_usb_iowrite16v_async_start(struct zd_usb *usb); +int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout); +int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, + unsigned int count); int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, unsigned int count); -- cgit v1.2.3 From 91f71fa5da00ff50398d8592f304cfec54eed550 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Sat, 12 Feb 2011 20:43:51 +0200 Subject: zd1211rw: add unlikely to ZD_ASSERT Case assert is violated should be quite unlikely. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_def.h b/drivers/net/wireless/zd1211rw/zd_def.h index 6ac597ffd3b9..5463ca9ebc01 100644 --- a/drivers/net/wireless/zd1211rw/zd_def.h +++ b/drivers/net/wireless/zd1211rw/zd_def.h @@ -45,7 +45,7 @@ typedef u16 __nocast zd_addr_t; #ifdef DEBUG # define ZD_ASSERT(x) \ do { \ - if (!(x)) { \ + if (unlikely(!(x))) { \ pr_debug("%s:%d ASSERT %s VIOLATED!\n", \ __FILE__, __LINE__, __stringify(x)); \ dump_stack(); \ -- cgit v1.2.3 From 192abece7565ab37048dfd5eced966cfb2fda6f5 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 12 Feb 2011 21:49:38 +0100 Subject: p54: sort channel list by frequency instead of channel index Some channel indices of the low 5GHz band clash with those of the 2.4GHz band. Therefore we should go with the channel's center frequency. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/eeprom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c index 35b09aa0529b..ec7d4b86bf06 100644 --- a/drivers/net/wireless/p54/eeprom.c +++ b/drivers/net/wireless/p54/eeprom.c @@ -93,7 +93,7 @@ static int p54_compare_channels(const void *_a, const struct p54_channel_entry *a = _a; const struct p54_channel_entry *b = _b; - return a->index - b->index; + return a->freq - b->freq; } static int p54_fill_band_bitrates(struct ieee80211_hw *dev, @@ -291,7 +291,7 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev) } } - /* sort the list by the channel index */ + /* sort the channel list by frequency */ sort(list->channels, list->entries, sizeof(struct p54_channel_entry), p54_compare_channels, NULL); -- cgit v1.2.3 From a3162eed04ae76be710d895978478aa6d849de41 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 12 Feb 2011 22:14:38 +0100 Subject: p54: p54_generate_band cleanup Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/eeprom.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c index ec7d4b86bf06..360bc7810f93 100644 --- a/drivers/net/wireless/p54/eeprom.c +++ b/drivers/net/wireless/p54/eeprom.c @@ -145,25 +145,26 @@ static int p54_generate_band(struct ieee80211_hw *dev, for (i = 0, j = 0; (j < list->band_channel_num[band]) && (i < list->entries); i++) { + struct p54_channel_entry *chan = &list->channels[i]; - if (list->channels[i].band != band) + if (chan->band != band) continue; - if (list->channels[i].data != CHAN_HAS_ALL) { - wiphy_err(dev->wiphy, - "%s%s%s is/are missing for channel:%d [%d MHz].\n", - (list->channels[i].data & CHAN_HAS_CAL ? "" : + if (chan->data != CHAN_HAS_ALL) { + wiphy_err(dev->wiphy, "%s%s%s is/are missing for " + "channel:%d [%d MHz].\n", + (chan->data & CHAN_HAS_CAL ? "" : " [iqauto calibration data]"), - (list->channels[i].data & CHAN_HAS_LIMIT ? "" : + (chan->data & CHAN_HAS_LIMIT ? "" : " [output power limits]"), - (list->channels[i].data & CHAN_HAS_CURVE ? "" : + (chan->data & CHAN_HAS_CURVE ? "" : " [curve data]"), - list->channels[i].index, list->channels[i].freq); + chan->index, chan->freq); continue; } - tmp->channels[j].band = list->channels[i].band; - tmp->channels[j].center_freq = list->channels[i].freq; + tmp->channels[j].band = chan->band; + tmp->channels[j].center_freq = chan->freq; j++; } -- cgit v1.2.3 From 7a047f4f2f3a812f09f42aa784499a54dc4afcf2 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 12 Feb 2011 22:32:49 +0100 Subject: p54: enhance rssi->dBm database import This patch fixes several shortcomings of the previous implementation. Features of the rewrite include: * handles undocumented "0x0000" word at the start of the frequency table. (Affected some early? DELL 1450 USB devices and my Symbol 5GHz miniPCI card.) * supports more than just one reference point per band. (Also needed for the Symbol card.) * ships with default values in case the eeprom data is damaged, absent or unsupported. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/eeprom.c | 183 +++++++++++++++++++++++++++++++------- drivers/net/wireless/p54/eeprom.h | 7 ++ drivers/net/wireless/p54/fwio.c | 12 +-- drivers/net/wireless/p54/lmac.h | 1 + drivers/net/wireless/p54/main.c | 2 + drivers/net/wireless/p54/p54.h | 6 +- drivers/net/wireless/p54/txrx.c | 6 +- 7 files changed, 176 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c index 360bc7810f93..f54e15fcd623 100644 --- a/drivers/net/wireless/p54/eeprom.c +++ b/drivers/net/wireless/p54/eeprom.c @@ -55,6 +55,17 @@ static struct ieee80211_rate p54_arates[] = { { .bitrate = 540, .hw_value = 11, }, }; +static struct p54_rssi_db_entry p54_rssi_default = { + /* + * The defaults are taken from usb-logs of the + * vendor driver. So, they should be safe to + * use in case we can't get a match from the + * rssi <-> dBm conversion database. + */ + .mul = 130, + .add = -398, +}; + #define CHAN_HAS_CAL BIT(0) #define CHAN_HAS_LIMIT BIT(1) #define CHAN_HAS_CURVE BIT(2) @@ -87,6 +98,11 @@ static int p54_get_band_from_freq(u16 freq) return -1; } +static int same_band(u16 freq, u16 freq2) +{ + return p54_get_band_from_freq(freq) == p54_get_band_from_freq(freq2); +} + static int p54_compare_channels(const void *_a, const void *_b) { @@ -96,6 +112,15 @@ static int p54_compare_channels(const void *_a, return a->freq - b->freq; } +static int p54_compare_rssichan(const void *_a, + const void *_b) +{ + const struct p54_rssi_db_entry *a = _a; + const struct p54_rssi_db_entry *b = _b; + + return a->freq - b->freq; +} + static int p54_fill_band_bitrates(struct ieee80211_hw *dev, struct ieee80211_supported_band *band_entry, enum ieee80211_band band) @@ -411,33 +436,118 @@ static int p54_convert_rev1(struct ieee80211_hw *dev, static const char *p54_rf_chips[] = { "INVALID-0", "Duette3", "Duette2", "Frisbee", "Xbow", "Longbow", "INVALID-6", "INVALID-7" }; -static void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len, - u16 type) +static int p54_parse_rssical(struct ieee80211_hw *dev, + u8 *data, int len, u16 type) { struct p54_common *priv = dev->priv; - int offset = (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) ? 2 : 0; - int entry_size = sizeof(struct pda_rssi_cal_entry) + offset; - int num_entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2; - int i; + struct p54_rssi_db_entry *entry; + size_t db_len, entries; + int offset = 0, i; + + if (type != PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) { + entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2; + if (len != sizeof(struct pda_rssi_cal_entry) * entries) { + wiphy_err(dev->wiphy, "rssical size mismatch.\n"); + goto err_data; + } + } else { + /* + * Some devices (Dell 1450 USB, Xbow 5GHz card, etc...) + * have an empty two byte header. + */ + if (*((__le16 *)&data[offset]) == cpu_to_le16(0)) + offset += 2; - if (len != (entry_size * num_entries)) { - wiphy_err(dev->wiphy, - "unknown rssi calibration data packing type:(%x) len:%d.\n", - type, len); + entries = (len - offset) / + sizeof(struct pda_rssi_cal_ext_entry); - print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE, - data, len); + if ((len - offset) % sizeof(struct pda_rssi_cal_ext_entry) || + entries <= 0) { + wiphy_err(dev->wiphy, "invalid rssi database.\n"); + goto err_data; + } + } - wiphy_err(dev->wiphy, "please report this issue.\n"); - return; + db_len = sizeof(*entry) * entries; + priv->rssi_db = kzalloc(db_len + sizeof(*priv->rssi_db), GFP_KERNEL); + if (!priv->rssi_db) + return -ENOMEM; + + priv->rssi_db->offset = 0; + priv->rssi_db->entries = entries; + priv->rssi_db->entry_size = sizeof(*entry); + priv->rssi_db->len = db_len; + + entry = (void *)((unsigned long)priv->rssi_db->data + priv->rssi_db->offset); + if (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) { + struct pda_rssi_cal_ext_entry *cal = (void *) &data[offset]; + + for (i = 0; i < entries; i++) { + entry[i].freq = le16_to_cpu(cal[i].freq); + entry[i].mul = (s16) le16_to_cpu(cal[i].mul); + entry[i].add = (s16) le16_to_cpu(cal[i].add); + } + } else { + struct pda_rssi_cal_entry *cal = (void *) &data[offset]; + + for (i = 0; i < entries; i++) { + u16 freq; + switch (i) { + case IEEE80211_BAND_2GHZ: + freq = 2437; + break; + case IEEE80211_BAND_5GHZ: + freq = 5240; + break; + } + + entry[i].freq = freq; + entry[i].mul = (s16) le16_to_cpu(cal[i].mul); + entry[i].add = (s16) le16_to_cpu(cal[i].add); + } } - for (i = 0; i < num_entries; i++) { - struct pda_rssi_cal_entry *cal = data + - (offset + i * entry_size); - priv->rssical_db[i].mul = (s16) le16_to_cpu(cal->mul); - priv->rssical_db[i].add = (s16) le16_to_cpu(cal->add); + /* sort the list by channel frequency */ + sort(entry, entries, sizeof(*entry), p54_compare_rssichan, NULL); + return 0; + +err_data: + wiphy_err(dev->wiphy, + "rssi calibration data packing type:(%x) len:%d.\n", + type, len); + + print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE, data, len); + + wiphy_err(dev->wiphy, "please report this issue.\n"); + return -EINVAL; +} + +struct p54_rssi_db_entry *p54_rssi_find(struct p54_common *priv, const u16 freq) +{ + struct p54_rssi_db_entry *entry = (void *)(priv->rssi_db->data + + priv->rssi_db->offset); + int i, found = -1; + + for (i = 0; i < priv->rssi_db->entries; i++) { + if (!same_band(freq, entry[i].freq)) + continue; + + if (found == -1) { + found = i; + continue; + } + + /* nearest match */ + if (abs(freq - entry[i].freq) < + abs(freq - entry[found].freq)) { + found = i; + continue; + } else { + break; + } } + + return found < 0 ? &p54_rssi_default : &entry[found]; } static void p54_parse_default_country(struct ieee80211_hw *dev, @@ -628,21 +738,30 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) case PDR_RSSI_LINEAR_APPROXIMATION: case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND: case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED: - p54_parse_rssical(dev, entry->data, data_len, - le16_to_cpu(entry->code)); + err = p54_parse_rssical(dev, entry->data, data_len, + le16_to_cpu(entry->code)); + if (err) + goto err; break; - case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM: { - __le16 *src = (void *) entry->data; - s16 *dst = (void *) &priv->rssical_db; + case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2: { + struct pda_custom_wrapper *pda = (void *) entry->data; + __le16 *src; + u16 *dst; int i; - if (data_len != sizeof(priv->rssical_db)) { - err = -EINVAL; - goto err; - } - for (i = 0; i < sizeof(priv->rssical_db) / - sizeof(*src); i++) + if (priv->rssi_db || data_len < sizeof(*pda)) + break; + + priv->rssi_db = p54_convert_db(pda, data_len); + if (!priv->rssi_db) + break; + + src = (void *) priv->rssi_db->data; + dst = (void *) priv->rssi_db->data; + + for (i = 0; i < priv->rssi_db->entries; i++) *(dst++) = (s16) le16_to_cpu(*(src++)); + } break; case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: { @@ -718,6 +837,8 @@ good_eeprom: SET_IEEE80211_PERM_ADDR(dev, perm_addr); } + priv->cur_rssi = &p54_rssi_default; + wiphy_info(dev->wiphy, "hwaddr %pM, MAC:isl38%02x RF:%s\n", dev->wiphy->perm_addr, priv->version, p54_rf_chips[priv->rxhw]); @@ -728,9 +849,11 @@ err: kfree(priv->iq_autocal); kfree(priv->output_limit); kfree(priv->curve_data); + kfree(priv->rssi_db); priv->iq_autocal = NULL; priv->output_limit = NULL; priv->curve_data = NULL; + priv->rssi_db = NULL; wiphy_err(dev->wiphy, "eeprom parse failed!\n"); return err; diff --git a/drivers/net/wireless/p54/eeprom.h b/drivers/net/wireless/p54/eeprom.h index 9051aef11249..afde72b84606 100644 --- a/drivers/net/wireless/p54/eeprom.h +++ b/drivers/net/wireless/p54/eeprom.h @@ -81,6 +81,12 @@ struct pda_pa_curve_data { u8 data[0]; } __packed; +struct pda_rssi_cal_ext_entry { + __le16 freq; + __le16 mul; + __le16 add; +} __packed; + struct pda_rssi_cal_entry { __le16 mul; __le16 add; @@ -179,6 +185,7 @@ struct pda_custom_wrapper { /* used by our modificated eeprom image */ #define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM 0xDEAD +#define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2 0xCAFF #define PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM 0xBEEF #define PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM 0xB05D diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c index 92b9b1f05fd5..0d3d108f6fe2 100644 --- a/drivers/net/wireless/p54/fwio.c +++ b/drivers/net/wireless/p54/fwio.c @@ -397,9 +397,9 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell) union p54_scan_body_union *body; struct p54_scan_tail_rate *rate; struct pda_rssi_cal_entry *rssi; + struct p54_rssi_db_entry *rssi_data; unsigned int i; void *entry; - int band = priv->hw->conf.channel->band; __le16 freq = cpu_to_le16(priv->hw->conf.channel->center_freq); skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) + @@ -503,13 +503,14 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell) } rssi = (struct pda_rssi_cal_entry *) skb_put(skb, sizeof(*rssi)); - rssi->mul = cpu_to_le16(priv->rssical_db[band].mul); - rssi->add = cpu_to_le16(priv->rssical_db[band].add); + rssi_data = p54_rssi_find(priv, le16_to_cpu(freq)); + rssi->mul = cpu_to_le16(rssi_data->mul); + rssi->add = cpu_to_le16(rssi_data->add); if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) { /* Longbow frontend needs ever more */ rssi = (void *) skb_put(skb, sizeof(*rssi)); - rssi->mul = cpu_to_le16(priv->rssical_db[band].longbow_unkn); - rssi->add = cpu_to_le16(priv->rssical_db[band].longbow_unk2); + rssi->mul = cpu_to_le16(rssi_data->longbow_unkn); + rssi->add = cpu_to_le16(rssi_data->longbow_unk2); } if (priv->fw_var >= 0x509) { @@ -523,6 +524,7 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell) hdr->len = cpu_to_le16(skb->len - sizeof(*hdr)); p54_tx(priv, skb); + priv->cur_rssi = rssi_data; return 0; err: diff --git a/drivers/net/wireless/p54/lmac.h b/drivers/net/wireless/p54/lmac.h index 04b63ec80fa4..5ca117e6f95b 100644 --- a/drivers/net/wireless/p54/lmac.h +++ b/drivers/net/wireless/p54/lmac.h @@ -551,6 +551,7 @@ int p54_upload_key(struct p54_common *priv, u8 algo, int slot, /* eeprom */ int p54_download_eeprom(struct p54_common *priv, void *buf, u16 offset, u16 len); +struct p54_rssi_db_entry *p54_rssi_find(struct p54_common *p, const u16 freq); /* utility */ u8 *p54_find_ie(struct sk_buff *skb, u8 ie); diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index 622d27b6d8f2..0a78e666e2d1 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c @@ -642,10 +642,12 @@ void p54_free_common(struct ieee80211_hw *dev) kfree(priv->iq_autocal); kfree(priv->output_limit); kfree(priv->curve_data); + kfree(priv->rssi_db); kfree(priv->used_rxkeys); priv->iq_autocal = NULL; priv->output_limit = NULL; priv->curve_data = NULL; + priv->rssi_db = NULL; priv->used_rxkeys = NULL; ieee80211_free_hw(dev); } diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h index 43a3b2ead81a..f951c8f31863 100644 --- a/drivers/net/wireless/p54/p54.h +++ b/drivers/net/wireless/p54/p54.h @@ -116,7 +116,8 @@ struct p54_edcf_queue_param { __le16 txop; } __packed; -struct p54_rssi_linear_approximation { +struct p54_rssi_db_entry { + u16 freq; s16 mul; s16 add; s16 longbow_unkn; @@ -197,13 +198,14 @@ struct p54_common { u8 rx_diversity_mask; u8 tx_diversity_mask; unsigned int output_power; + struct p54_rssi_db_entry *cur_rssi; int noise; /* calibration, output power limit and rssi<->dBm conversation data */ struct pda_iq_autocal_entry *iq_autocal; unsigned int iq_autocal_len; struct p54_cal_database *curve_data; struct p54_cal_database *output_limit; - struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS]; + struct p54_cal_database *rssi_db; struct ieee80211_supported_band *band_table[IEEE80211_NUM_BANDS]; /* BBP/MAC state */ diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index f618b9623e5a..917d5d948e3c 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c @@ -273,11 +273,9 @@ void p54_tx(struct p54_common *priv, struct sk_buff *skb) static int p54_rssi_to_dbm(struct p54_common *priv, int rssi) { - int band = priv->hw->conf.channel->band; - if (priv->rxhw != 5) { - return ((rssi * priv->rssical_db[band].mul) / 64 + - priv->rssical_db[band].add) / 4; + return ((rssi * priv->cur_rssi->mul) / 64 + + priv->cur_rssi->add) / 4; } else { /* * TODO: find the correct formula -- cgit v1.2.3 From 05e051d8ae3472302ec7c510ab6d4d85551bd1ea Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 12 Feb 2011 22:53:00 +0100 Subject: p54spi: update sample eeprom Commit: "p54: enhance rssi->dBm database import" changed the way how the driver deals with the rssical data. A new data format was necessary and hence this patch. NOTE: (for users with a custom eeprom binary) I spent some time updating p54tools to support the new format too: => (git available from) http://git.kernel.org/?p=linux/kernel/git/chr/p54tools.git It now comes with a simplistic script "n800_rssi2v2.sh" which can be used to automate the conversion. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54spi_eeprom.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/p54spi_eeprom.h b/drivers/net/wireless/p54/p54spi_eeprom.h index d592cbd34d78..0b7bfb0adcf2 100644 --- a/drivers/net/wireless/p54/p54spi_eeprom.h +++ b/drivers/net/wireless/p54/p54spi_eeprom.h @@ -65,9 +65,10 @@ static unsigned char p54spi_eeprom[] = { 0x03, 0x00, 0x00, 0x11, /* PDR_ANTENNA_GAIN */ 0x08, 0x08, 0x08, 0x08, -0x09, 0x00, 0xad, 0xde, /* PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM */ - 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x0a, 0x00, 0xff, 0xca, /* PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2 */ + 0x01, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x0a, 0x00, + 0x85, 0x09, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, /* struct pda_custom_wrapper */ 0x10, 0x06, 0x5d, 0xb0, /* PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM */ @@ -671,7 +672,7 @@ static unsigned char p54spi_eeprom[] = { 0xa8, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, /* PDR_END */ - 0x67, 0x99, + 0xb6, 0x04, }; #endif /* P54SPI_EEPROM_H */ -- cgit v1.2.3 From 5d17920bd4df6802fb48ccf8283721657c5a8257 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 14 Feb 2011 13:28:00 -0800 Subject: iwlwifi: Delete iwl3945_good_plcp_health. Fixes this build warning: drivers/net/wireless/iwlwifi/iwl-3945.c:411:13: warning: 'iwl3945_good_plcp_health' defined but not used As per Johannes Berg. Signed-off-by: David S. Miller --- drivers/net/wireless/iwlwifi/iwl-3945.c | 66 --------------------------------- 1 file changed, 66 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 3eb14fd2204b..39b6f16c87fa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -402,72 +402,6 @@ static void iwl3945_accumulative_statistics(struct iwl_priv *priv, } #endif -/** - * iwl3945_good_plcp_health - checks for plcp error. - * - * When the plcp error is exceeding the thresholds, reset the radio - * to improve the throughput. - */ -static bool iwl3945_good_plcp_health(struct iwl_priv *priv, - struct iwl_rx_packet *pkt) -{ - bool rc = true; - struct iwl3945_notif_statistics current_stat; - int combined_plcp_delta; - unsigned int plcp_msec; - unsigned long plcp_received_jiffies; - - if (priv->cfg->base_params->plcp_delta_threshold == - IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { - IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); - return rc; - } - memcpy(¤t_stat, pkt->u.raw, sizeof(struct - iwl3945_notif_statistics)); - /* - * check for plcp_err and trigger radio reset if it exceeds - * the plcp error threshold plcp_delta. - */ - plcp_received_jiffies = jiffies; - plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - - (long) priv->plcp_jiffies); - priv->plcp_jiffies = plcp_received_jiffies; - /* - * check to make sure plcp_msec is not 0 to prevent division - * by zero. - */ - if (plcp_msec) { - combined_plcp_delta = - (le32_to_cpu(current_stat.rx.ofdm.plcp_err) - - le32_to_cpu(priv->_3945.statistics.rx.ofdm.plcp_err)); - - if ((combined_plcp_delta > 0) && - ((combined_plcp_delta * 100) / plcp_msec) > - priv->cfg->base_params->plcp_delta_threshold) { - /* - * if plcp_err exceed the threshold, the following - * data is printed in csv format: - * Text: plcp_err exceeded %d, - * Received ofdm.plcp_err, - * Current ofdm.plcp_err, - * combined_plcp_delta, - * plcp_msec - */ - IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " - "%u, %d, %u mSecs\n", - priv->cfg->base_params->plcp_delta_threshold, - le32_to_cpu(current_stat.rx.ofdm.plcp_err), - combined_plcp_delta, plcp_msec); - /* - * Reset the RF radio due to the high plcp - * error rate - */ - rc = false; - } - } - return rc; -} - void iwl3945_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { -- cgit v1.2.3 From 98200ec28a66c8db5839ac26e9a895984206b50f Mon Sep 17 00:00:00 2001 From: Toshiharu Okada Date: Sun, 13 Feb 2011 22:51:54 +0000 Subject: pch_gbe: Fix the MAC Address load issue. With the specification of hardware, the processing at the time of driver starting was modified. This device write automatically the MAC address read from serial ROM into a MAC Adress1A/1B register at the time of power on reset. However, when stable clock is not supplied, the writing of MAC Adress1A/1B register may not be completed. In this case, it is necessary to load MAC address to MAC Address1A/1B register by the MAC Address1 load register. This patch always does the above processing, in order not to be dependent on system environment. Signed-off-by: Toshiharu Okada Signed-off-by: David S. Miller --- drivers/net/pch_gbe/pch_gbe.h | 2 +- drivers/net/pch_gbe/pch_gbe_main.c | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/pch_gbe/pch_gbe.h b/drivers/net/pch_gbe/pch_gbe.h index a0c26a99520f..e1e33c80fb25 100644 --- a/drivers/net/pch_gbe/pch_gbe.h +++ b/drivers/net/pch_gbe/pch_gbe.h @@ -73,7 +73,7 @@ struct pch_gbe_regs { struct pch_gbe_regs_mac_adr mac_adr[16]; u32 ADDR_MASK; u32 MIIM; - u32 reserve2; + u32 MAC_ADDR_LOAD; u32 RGMII_ST; u32 RGMII_CTRL; u32 reserve3[3]; diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index f52d852569fb..b99e90aca37d 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c @@ -89,6 +89,12 @@ static unsigned int copybreak __read_mostly = PCH_GBE_COPYBREAK_DEFAULT; static int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg); static void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg, int data); + +inline void pch_gbe_mac_load_mac_addr(struct pch_gbe_hw *hw) +{ + iowrite32(0x01, &hw->reg->MAC_ADDR_LOAD); +} + /** * pch_gbe_mac_read_mac_addr - Read MAC address * @hw: Pointer to the HW structure @@ -2331,6 +2337,7 @@ static int pch_gbe_probe(struct pci_dev *pdev, netdev->features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_GRO; pch_gbe_set_ethtool_ops(netdev); + pch_gbe_mac_load_mac_addr(&adapter->hw); pch_gbe_mac_reset_hw(&adapter->hw); /* setup the private structure */ -- cgit v1.2.3 From 265aa6c8d8822c9074a2174e8c9f31a37fa02e50 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 14 Feb 2011 16:16:22 -0500 Subject: drm/radeon/kms: fix a few more atombios endian issues Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atombios_crtc.c | 2 +- drivers/gpu/drm/radeon/rs690.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 1bf61220a450..0b10b0e14945 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -728,7 +728,7 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc, /* if the default dcpll clock is specified, * SetPixelClock provides the dividers */ - args.v6.ulDispEngClkFreq = dispclk; + args.v6.ulDispEngClkFreq = cpu_to_le32(dispclk); args.v6.ucPpll = ATOM_DCPLL; break; default: diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 0137d3e3728d..6638c8e4c81b 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -77,9 +77,9 @@ void rs690_pm_info(struct radeon_device *rdev) switch (crev) { case 1: tmp.full = dfixed_const(100); - rdev->pm.igp_sideport_mclk.full = dfixed_const(info->info.ulBootUpMemoryClock); + rdev->pm.igp_sideport_mclk.full = dfixed_const(le32_to_cpu(info->info.ulBootUpMemoryClock)); rdev->pm.igp_sideport_mclk.full = dfixed_div(rdev->pm.igp_sideport_mclk, tmp); - if (info->info.usK8MemoryClock) + if (le16_to_cpu(info->info.usK8MemoryClock)) rdev->pm.igp_system_mclk.full = dfixed_const(le16_to_cpu(info->info.usK8MemoryClock)); else if (rdev->clock.default_mclk) { rdev->pm.igp_system_mclk.full = dfixed_const(rdev->clock.default_mclk); @@ -91,16 +91,16 @@ void rs690_pm_info(struct radeon_device *rdev) break; case 2: tmp.full = dfixed_const(100); - rdev->pm.igp_sideport_mclk.full = dfixed_const(info->info_v2.ulBootUpSidePortClock); + rdev->pm.igp_sideport_mclk.full = dfixed_const(le32_to_cpu(info->info_v2.ulBootUpSidePortClock)); rdev->pm.igp_sideport_mclk.full = dfixed_div(rdev->pm.igp_sideport_mclk, tmp); - if (info->info_v2.ulBootUpUMAClock) - rdev->pm.igp_system_mclk.full = dfixed_const(info->info_v2.ulBootUpUMAClock); + if (le32_to_cpu(info->info_v2.ulBootUpUMAClock)) + rdev->pm.igp_system_mclk.full = dfixed_const(le32_to_cpu(info->info_v2.ulBootUpUMAClock)); else if (rdev->clock.default_mclk) rdev->pm.igp_system_mclk.full = dfixed_const(rdev->clock.default_mclk); else rdev->pm.igp_system_mclk.full = dfixed_const(66700); rdev->pm.igp_system_mclk.full = dfixed_div(rdev->pm.igp_system_mclk, tmp); - rdev->pm.igp_ht_link_clk.full = dfixed_const(info->info_v2.ulHTLinkFreq); + rdev->pm.igp_ht_link_clk.full = dfixed_const(le32_to_cpu(info->info_v2.ulHTLinkFreq)); rdev->pm.igp_ht_link_clk.full = dfixed_div(rdev->pm.igp_ht_link_clk, tmp); rdev->pm.igp_ht_link_width.full = dfixed_const(le16_to_cpu(info->info_v2.usMinHTLinkWidth)); break; -- cgit v1.2.3 From a4b40d5d97f5c9ad0b7f4bf2818291ca184bb433 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 14 Feb 2011 11:43:10 -0500 Subject: drm/radeon/kms: add bounds checking to avivo pll algo Prevent divider overflow. Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=28932 Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_display.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 2eff98cfd728..0e657095de7c 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -793,6 +793,11 @@ static void avivo_get_fb_div(struct radeon_pll *pll, tmp *= target_clock; *fb_div = tmp / pll->reference_freq; *frac_fb_div = tmp % pll->reference_freq; + + if (*fb_div > pll->max_feedback_div) + *fb_div = pll->max_feedback_div; + else if (*fb_div < pll->min_feedback_div) + *fb_div = pll->min_feedback_div; } static u32 avivo_get_post_div(struct radeon_pll *pll, @@ -826,6 +831,11 @@ static u32 avivo_get_post_div(struct radeon_pll *pll, post_div--; } + if (post_div > pll->max_post_div) + post_div = pll->max_post_div; + else if (post_div < pll->min_post_div) + post_div = pll->min_post_div; + return post_div; } -- cgit v1.2.3 From 5b40ddf888398ce4cccbf3b9d0a18d90149ed7ff Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 14 Feb 2011 11:43:11 -0500 Subject: drm/radeon/kms: hopefully fix pll issues for real (v3) The problematic boards have a recommended reference divider to be used when spread spectrum is enabled on the laptop panel. Enable the use of the recommended reference divider along with the new pll algo. v2: testing options v3: When using the fixed reference divider with LVDS, prefer min m to max p and use fractional feedback dividers. Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=28852 https://bugzilla.kernel.org/show_bug.cgi?id=24462 https://bugzilla.kernel.org/show_bug.cgi?id=26552 MacbookPro issues reported by Justin Mattock Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atombios_crtc.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 0b10b0e14945..095bc507fb16 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -538,7 +538,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; else pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; - } list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { @@ -555,29 +554,28 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, dp_clock = dig_connector->dp_clock; } } -/* this might work properly with the new pll algo */ -#if 0 /* doesn't work properly on some laptops */ + /* use recommended ref_div for ss */ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { + pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; if (ss_enabled) { if (ss->refdiv) { pll->flags |= RADEON_PLL_USE_REF_DIV; pll->reference_div = ss->refdiv; + if (ASIC_IS_AVIVO(rdev)) + pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; } } } -#endif + if (ASIC_IS_AVIVO(rdev)) { /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) adjusted_clock = mode->clock * 2; if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; - /* rv515 needs more testing with this option */ - if (rdev->family != CHIP_RV515) { - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) - pll->flags |= RADEON_PLL_IS_LCD; - } + if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) + pll->flags |= RADEON_PLL_IS_LCD; } else { if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; @@ -957,11 +955,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode /* adjust pixel clock as needed */ adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss); - /* rv515 seems happier with the old algo */ - if (rdev->family == CHIP_RV515) - radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, - &ref_div, &post_div); - else if (ASIC_IS_AVIVO(rdev)) + if (ASIC_IS_AVIVO(rdev)) radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, &ref_div, &post_div); else -- cgit v1.2.3 From bb14a1af86d01f66dc9620725ac00a240331afec Mon Sep 17 00:00:00 2001 From: Casey Leedom Date: Mon, 14 Feb 2011 12:56:22 +0000 Subject: cxgb4vf: Check driver parameters in the right place ... Check module parameter validity in the module initialization routine instead of the PCI Device Probe routine. Signed-off-by: Casey Leedom Signed-off-by: David S. Miller --- drivers/net/cxgb4vf/cxgb4vf_main.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 56166ae2059f..072b64e49370 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -2488,17 +2488,6 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, struct port_info *pi; struct net_device *netdev; - /* - * Vet our module parameters. - */ - if (msi != MSI_MSIX && msi != MSI_MSI) { - dev_err(&pdev->dev, "bad module parameter msi=%d; must be %d" - " (MSI-X or MSI) or %d (MSI)\n", msi, MSI_MSIX, - MSI_MSI); - err = -EINVAL; - goto err_out; - } - /* * Print our driver banner the first time we're called to initialize a * device. @@ -2802,7 +2791,6 @@ err_release_regions: err_disable_device: pci_disable_device(pdev); -err_out: return err; } @@ -2915,6 +2903,17 @@ static int __init cxgb4vf_module_init(void) { int ret; + /* + * Vet our module parameters. + */ + if (msi != MSI_MSIX && msi != MSI_MSI) { + printk(KERN_WARNING KBUILD_MODNAME + ": bad module parameter msi=%d; must be %d" + " (MSI-X or MSI) or %d (MSI)\n", + msi, MSI_MSIX, MSI_MSI); + return -EINVAL; + } + /* Debugfs support is optional, just warn if this fails */ cxgb4vf_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); if (!cxgb4vf_debugfs_root) -- cgit v1.2.3 From 843635e0349be9e318be224d6241069a40e23320 Mon Sep 17 00:00:00 2001 From: Casey Leedom Date: Mon, 14 Feb 2011 12:56:23 +0000 Subject: cxgb4vf: Behave properly when CONFIG_DEBUG_FS isn't defined ... When CONFIG_DEBUG_FS we get "ERR_PTR()"s back from the debugfs routines instead of NULL. Use the right predicates to check for this. Signed-off-by: Casey Leedom Signed-off-by: David S. Miller --- drivers/net/cxgb4vf/cxgb4vf_main.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 072b64e49370..2be1088ff601 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -2040,7 +2040,7 @@ static int __devinit setup_debugfs(struct adapter *adapter) { int i; - BUG_ON(adapter->debugfs_root == NULL); + BUG_ON(IS_ERR_OR_NULL(adapter->debugfs_root)); /* * Debugfs support is best effort. @@ -2061,7 +2061,7 @@ static int __devinit setup_debugfs(struct adapter *adapter) */ static void cleanup_debugfs(struct adapter *adapter) { - BUG_ON(adapter->debugfs_root == NULL); + BUG_ON(IS_ERR_OR_NULL(adapter->debugfs_root)); /* * Unlike our sister routine cleanup_proc(), we don't need to remove @@ -2700,11 +2700,11 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, /* * Set up our debugfs entries. */ - if (cxgb4vf_debugfs_root) { + if (!IS_ERR_OR_NULL(cxgb4vf_debugfs_root)) { adapter->debugfs_root = debugfs_create_dir(pci_name(pdev), cxgb4vf_debugfs_root); - if (adapter->debugfs_root == NULL) + if (IS_ERR_OR_NULL(adapter->debugfs_root)) dev_warn(&pdev->dev, "could not create debugfs" " directory"); else @@ -2759,7 +2759,7 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, */ err_free_debugfs: - if (adapter->debugfs_root) { + if (!IS_ERR_OR_NULL(adapter->debugfs_root)) { cleanup_debugfs(adapter); debugfs_remove_recursive(adapter->debugfs_root); } @@ -2828,7 +2828,7 @@ static void __devexit cxgb4vf_pci_remove(struct pci_dev *pdev) /* * Tear down our debugfs entries. */ - if (adapter->debugfs_root) { + if (!IS_ERR_OR_NULL(adapter->debugfs_root)) { cleanup_debugfs(adapter); debugfs_remove_recursive(adapter->debugfs_root); } @@ -2916,12 +2916,12 @@ static int __init cxgb4vf_module_init(void) /* Debugfs support is optional, just warn if this fails */ cxgb4vf_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!cxgb4vf_debugfs_root) + if (IS_ERR_OR_NULL(cxgb4vf_debugfs_root)) printk(KERN_WARNING KBUILD_MODNAME ": could not create" " debugfs entry, continuing\n"); ret = pci_register_driver(&cxgb4vf_driver); - if (ret < 0) + if (ret < 0 && !IS_ERR_OR_NULL(cxgb4vf_debugfs_root)) debugfs_remove(cxgb4vf_debugfs_root); return ret; } -- cgit v1.2.3 From 7e9c26295b2ae1be1285c7c9e593c19ce7ea7eba Mon Sep 17 00:00:00 2001 From: Casey Leedom Date: Mon, 14 Feb 2011 12:56:24 +0000 Subject: cxgb4vf: Quiesce Virtual Interfaces on shutdown ... When a Virtual Machine is rebooted, KVM currently fails to issue a Function Level Reset against any "Attached PCI Devices" (AKA "PCI Passthrough"). In addition to leaving the attached device in a random state in the next booted kernel (which sort of violates the entire idea of a reboot reseting hardware state), this leaves our peer thinking that the link is still up. (Note that a bug has been filed with the KVM folks, #25332, but there's been no response on that as of yet.) So, we add a "->shutdown()" method for the Virtual Function PCI Device to handle administrative shutdowns like a reboot. Signed-off-by: Casey Leedom Signed-off-by: David S. Miller --- drivers/net/cxgb4vf/cxgb4vf_main.c | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'drivers') diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 2be1088ff601..6aad64df4dcb 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -2861,6 +2861,46 @@ static void __devexit cxgb4vf_pci_remove(struct pci_dev *pdev) pci_release_regions(pdev); } +/* + * "Shutdown" quiesce the device, stopping Ingress Packet and Interrupt + * delivery. + */ +static void __devexit cxgb4vf_pci_shutdown(struct pci_dev *pdev) +{ + struct adapter *adapter; + int pidx; + + adapter = pci_get_drvdata(pdev); + if (!adapter) + return; + + /* + * Disable all Virtual Interfaces. This will shut down the + * delivery of all ingress packets into the chip for these + * Virtual Interfaces. + */ + for_each_port(adapter, pidx) { + struct net_device *netdev; + struct port_info *pi; + + if (!test_bit(pidx, &adapter->registered_device_map)) + continue; + + netdev = adapter->port[pidx]; + if (!netdev) + continue; + + pi = netdev_priv(netdev); + t4vf_enable_vi(adapter, pi->viid, false, false); + } + + /* + * Free up all Queues which will prevent further DMA and + * Interrupts allowing various internal pathways to drain. + */ + t4vf_free_sge_resources(adapter); +} + /* * PCI Device registration data structures. */ @@ -2894,6 +2934,7 @@ static struct pci_driver cxgb4vf_driver = { .id_table = cxgb4vf_pci_tbl, .probe = cxgb4vf_pci_probe, .remove = __devexit_p(cxgb4vf_pci_remove), + .shutdown = __devexit_p(cxgb4vf_pci_shutdown), }; /* -- cgit v1.2.3 From 0550769bb7f364fb9aeeb9412229fb7790ee79c4 Mon Sep 17 00:00:00 2001 From: Casey Leedom Date: Mon, 14 Feb 2011 12:56:25 +0000 Subject: cxgb4vf: Use defined Mailbox Timeout VF Driver should use mailbox command timeout specified in t4fw_interface.h rather than hard-coded value of 500ms. Signed-off-by: Casey Leedom Signed-off-by: David S. Miller --- drivers/net/cxgb4vf/t4vf_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/cxgb4vf/t4vf_hw.c b/drivers/net/cxgb4vf/t4vf_hw.c index 0f51c80475ce..192db226ec7f 100644 --- a/drivers/net/cxgb4vf/t4vf_hw.c +++ b/drivers/net/cxgb4vf/t4vf_hw.c @@ -171,7 +171,7 @@ int t4vf_wr_mbox_core(struct adapter *adapter, const void *cmd, int size, delay_idx = 0; ms = delay[0]; - for (i = 0; i < 500; i += ms) { + for (i = 0; i < FW_CMD_MAX_TIMEOUT; i += ms) { if (sleep_ok) { ms = delay[delay_idx]; if (delay_idx < ARRAY_SIZE(delay) - 1) -- cgit v1.2.3 From d606ef3fe0c57504b8e534c58498f73a6abc049a Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Mon, 14 Feb 2011 02:05:33 +0000 Subject: phy/micrel: add ability to support 50MHz RMII clock on KZS8051RNL Platform code can now set the MICREL_PHY_50MHZ_CLK bit of dev_flags in a fixup routine (registered with phy_register_fixup_for_uid()), to make the KZS8051RNL PHY work with 50MHz RMII reference clock. Cc: David J. Choi Signed-off-by: Baruch Siach Signed-off-by: David S. Miller --- drivers/net/phy/micrel.c | 24 ++++++++++++++++-------- include/linux/micrel_phy.h | 16 ++++++++++++++++ 2 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 include/linux/micrel_phy.h (limited to 'drivers') diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 0fd1678bc5a9..590f902deb6b 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -19,13 +19,7 @@ #include #include #include - -#define PHY_ID_KSZ9021 0x00221611 -#define PHY_ID_KS8737 0x00221720 -#define PHY_ID_KS8041 0x00221510 -#define PHY_ID_KS8051 0x00221550 -/* both for ks8001 Rev. A/B, and for ks8721 Rev 3. */ -#define PHY_ID_KS8001 0x0022161A +#include /* general Interrupt control/status reg in vendor specific block. */ #define MII_KSZPHY_INTCS 0x1B @@ -46,6 +40,7 @@ #define KSZPHY_CTRL_INT_ACTIVE_HIGH (1 << 9) #define KSZ9021_CTRL_INT_ACTIVE_HIGH (1 << 14) #define KS8737_CTRL_INT_ACTIVE_HIGH (1 << 14) +#define KSZ8051_RMII_50MHZ_CLK (1 << 7) static int kszphy_ack_interrupt(struct phy_device *phydev) { @@ -106,6 +101,19 @@ static int kszphy_config_init(struct phy_device *phydev) return 0; } +static int ks8051_config_init(struct phy_device *phydev) +{ + int regval; + + if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) { + regval = phy_read(phydev, MII_KSZPHY_CTRL); + regval |= KSZ8051_RMII_50MHZ_CLK; + phy_write(phydev, MII_KSZPHY_CTRL, regval); + } + + return 0; +} + static struct phy_driver ks8737_driver = { .phy_id = PHY_ID_KS8737, .phy_id_mask = 0x00fffff0, @@ -142,7 +150,7 @@ static struct phy_driver ks8051_driver = { .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = kszphy_config_init, + .config_init = ks8051_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h new file mode 100644 index 000000000000..dd8da342a991 --- /dev/null +++ b/include/linux/micrel_phy.h @@ -0,0 +1,16 @@ +#ifndef _MICREL_PHY_H +#define _MICREL_PHY_H + +#define MICREL_PHY_ID_MASK 0x00fffff0 + +#define PHY_ID_KSZ9021 0x00221611 +#define PHY_ID_KS8737 0x00221720 +#define PHY_ID_KS8041 0x00221510 +#define PHY_ID_KS8051 0x00221550 +/* both for ks8001 Rev. A/B, and for ks8721 Rev 3. */ +#define PHY_ID_KS8001 0x0022161A + +/* struct phy_device dev_flags definitions */ +#define MICREL_PHY_50MHZ_CLK 0x00000001 + +#endif /* _MICREL_PHY_H */ -- cgit v1.2.3 From 84e383b322e5348db03be54ff64cc6da87003717 Mon Sep 17 00:00:00 2001 From: Naga Chumbalkar Date: Mon, 14 Feb 2011 22:47:17 +0000 Subject: x86, dmi, debug: Log board name (when present) in dmesg/oops output The "Type 2" SMBIOS record that contains Board Name is not strictly required and may be absent in the SMBIOS on some platforms. ( Please note that Type 2 is not listed in Table 3 in Sec 6.2 ("Required Structures and Data") of the SMBIOS v2.7 Specification. ) Use the Manufacturer Name (aka System Vendor) name. Print Board Name only when it is present. Before the fix: (i) dmesg output: DMI: /ProLiant DL380 G6, BIOS P62 01/29/2011 (ii) oops output: Pid: 2170, comm: bash Not tainted 2.6.38-rc4+ #3 /ProLiant DL380 G6 After the fix: (i) dmesg output: DMI: HP ProLiant DL380 G6, BIOS P62 01/29/2011 (ii) oops output: Pid: 2278, comm: bash Not tainted 2.6.38-rc4+ #4 HP ProLiant DL380 G6 Signed-off-by: Naga Chumbalkar Reviewed-by: Bjorn Helgaas Cc: # .3x - good for debugging, please apply as far back as it applies cleanly LKML-Reference: <20110214224423.2182.13929.sendpatchset@nchumbalkar.americas.hpqcorp.net> Signed-off-by: Ingo Molnar --- arch/x86/kernel/process.c | 22 ++++++++++++++++------ drivers/firmware/dmi_scan.c | 11 +++++++++-- 2 files changed, 25 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 3c189e9accd3..ff4554198981 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -92,21 +92,31 @@ void show_regs(struct pt_regs *regs) void show_regs_common(void) { - const char *board, *product; + const char *vendor, *product, *board; - board = dmi_get_system_info(DMI_BOARD_NAME); - if (!board) - board = ""; + vendor = dmi_get_system_info(DMI_SYS_VENDOR); + if (!vendor) + vendor = ""; product = dmi_get_system_info(DMI_PRODUCT_NAME); if (!product) product = ""; + /* Board Name is optional */ + board = dmi_get_system_info(DMI_BOARD_NAME); + printk(KERN_CONT "\n"); - printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s %s/%s\n", + printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s", current->pid, current->comm, print_tainted(), init_utsname()->release, (int)strcspn(init_utsname()->version, " "), - init_utsname()->version, board, product); + init_utsname()->version); + printk(KERN_CONT " "); + printk(KERN_CONT "%s %s", vendor, product); + if (board) { + printk(KERN_CONT "/"); + printk(KERN_CONT "%s", board); + } + printk(KERN_CONT "\n"); } void flush_thread(void) diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index e28e41668177..bcb1126e3d00 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -378,10 +378,17 @@ static void __init print_filtered(const char *info) static void __init dmi_dump_ids(void) { + const char *board; /* Board Name is optional */ + printk(KERN_DEBUG "DMI: "); - print_filtered(dmi_get_system_info(DMI_BOARD_NAME)); - printk(KERN_CONT "/"); + print_filtered(dmi_get_system_info(DMI_SYS_VENDOR)); + printk(KERN_CONT " "); print_filtered(dmi_get_system_info(DMI_PRODUCT_NAME)); + board = dmi_get_system_info(DMI_BOARD_NAME); + if (board) { + printk(KERN_CONT "/"); + print_filtered(board); + } printk(KERN_CONT ", BIOS "); print_filtered(dmi_get_system_info(DMI_BIOS_VERSION)); printk(KERN_CONT " "); -- cgit v1.2.3 From a628e7b87e100befac9702aa0c3b9848a7685e49 Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Mon, 14 Feb 2011 17:21:49 -0800 Subject: pci: use security_capable() when checking capablities during config space read This reintroduces commit 47970b1b which was subsequently reverted as f00eaeea. The original change was broken and caused X startup failures and generally made privileged processes incapable of reading device dependent config space. The normal capable() interface returns true on success, but the LSM interface returns 0 on success. This thinko is now fixed in this patch, and has been confirmed to work properly. So, once again...Eric Paris noted that commit de139a3 ("pci: check caps from sysfs file open to read device dependent config space") caused the capability check to bypass security modules and potentially auditing. Rectify this by calling security_capable() when checking the open file's capabilities for config space reads. Reported-by: Eric Paris Tested-by: Dave Young Acked-by: James Morris Cc: Dave Airlie Cc: Alex Riesen Cc: Sedat Dilek Cc: Linus Torvalds Signed-off-by: Chris Wright Signed-off-by: James Morris --- drivers/pci/pci-sysfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 8ecaac983923..ea25e5bfcf23 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include "pci.h" @@ -368,7 +369,7 @@ pci_read_config(struct file *filp, struct kobject *kobj, u8 *data = (u8*) buf; /* Several chips lock up trying to read undefined config space */ - if (cap_raised(filp->f_cred->cap_effective, CAP_SYS_ADMIN)) { + if (security_capable(filp->f_cred, CAP_SYS_ADMIN) == 0) { size = dev->cfg_size; } else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { size = 128; -- cgit v1.2.3 From 8a73b0bc86366113e13d079b3de76df6e94a4a5c Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 13 Jan 2011 21:34:31 +0100 Subject: net/fec: no need to cast arguments for memcpy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit memcpy takes a const void * as 2nd argument. So the argument is converted automatically to void * anyhow. Signed-off-by: Uwe Kleine-König --- drivers/net/fec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 2a71373719ae..3e6e923ca59b 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -284,7 +284,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) if (((unsigned long) bufaddr) & FEC_ALIGNMENT) { unsigned int index; index = bdp - fep->tx_bd_base; - memcpy(fep->tx_bounce[index], (void *)skb->data, skb->len); + memcpy(fep->tx_bounce[index], skb->data, skb->len); bufaddr = fep->tx_bounce[index]; } -- cgit v1.2.3 From 28e2188efc614c714c69dd5c3f063e066e80d3ba Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 13 Jan 2011 21:44:18 +0100 Subject: net/fec: release mem_region requested in probe in error path and remove MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Lothar Waßmann Signed-off-by: Uwe Kleine-König --- drivers/net/fec.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 3e6e923ca59b..b079826586ef 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1377,8 +1377,10 @@ fec_probe(struct platform_device *pdev) /* Init network device */ ndev = alloc_etherdev(sizeof(struct fec_enet_private)); - if (!ndev) - return -ENOMEM; + if (!ndev) { + ret = -ENOMEM; + goto failed_alloc_etherdev; + } SET_NETDEV_DEV(ndev, &pdev->dev); @@ -1456,6 +1458,8 @@ failed_irq: iounmap((void __iomem *)ndev->base_addr); failed_ioremap: free_netdev(ndev); +failed_alloc_etherdev: + release_mem_region(r->start, resource_size(r)); return ret; } @@ -1465,6 +1469,7 @@ fec_drv_remove(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); struct fec_enet_private *fep = netdev_priv(ndev); + struct resource *r; platform_set_drvdata(pdev, NULL); @@ -1475,6 +1480,11 @@ fec_drv_remove(struct platform_device *pdev) iounmap((void __iomem *)ndev->base_addr); unregister_netdev(ndev); free_netdev(ndev); + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + BUG_ON(!r); + release_mem_region(r->start, resource_size(r)); + return 0; } -- cgit v1.2.3 From b2b09ad63cc09448e49f6a4addae6e078c0e5e36 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 13 Jan 2011 21:49:05 +0100 Subject: net/fec: don't free an irq that failed to be requested MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Lothar Waßmann Signed-off-by: Uwe Kleine-König --- drivers/net/fec.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index b079826586ef..aa1db8e637cd 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1409,10 +1409,9 @@ fec_probe(struct platform_device *pdev) break; ret = request_irq(irq, fec_enet_interrupt, IRQF_DISABLED, pdev->name, ndev); if (ret) { - while (i >= 0) { + while (--i >= 0) { irq = platform_get_irq(pdev, i); free_irq(irq, ndev); - i--; } goto failed_irq; } -- cgit v1.2.3 From 04e5216d44e173fab619d03e2f746f444ea21ebd Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 13 Jan 2011 21:53:40 +0100 Subject: net/fec: no need to check for validity of ndev in suspend and resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dev_set_drvdata is called unconditionally in the probe function and so it cannot be NULL. Reported-by: Lothar Waßmann Signed-off-by: Uwe Kleine-König --- drivers/net/fec.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index aa1db8e637cd..8026a16f6b6c 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1492,16 +1492,14 @@ static int fec_suspend(struct device *dev) { struct net_device *ndev = dev_get_drvdata(dev); - struct fec_enet_private *fep; + struct fec_enet_private *fep = netdev_priv(ndev); - if (ndev) { - fep = netdev_priv(ndev); - if (netif_running(ndev)) { - fec_stop(ndev); - netif_device_detach(ndev); - } - clk_disable(fep->clk); + if (netif_running(ndev)) { + fec_stop(ndev); + netif_device_detach(ndev); } + clk_disable(fep->clk); + return 0; } @@ -1509,16 +1507,14 @@ static int fec_resume(struct device *dev) { struct net_device *ndev = dev_get_drvdata(dev); - struct fec_enet_private *fep; + struct fec_enet_private *fep = netdev_priv(ndev); - if (ndev) { - fep = netdev_priv(ndev); - clk_enable(fep->clk); - if (netif_running(ndev)) { - fec_restart(ndev, fep->full_duplex); - netif_device_attach(ndev); - } + clk_enable(fep->clk); + if (netif_running(ndev)) { + fec_restart(ndev, fep->full_duplex); + netif_device_attach(ndev); } + return 0; } -- cgit v1.2.3 From 8b06dc2b1cdc33f6426bc4b0d58b357146d739f9 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 13 Jan 2011 21:56:14 +0100 Subject: net/fec: no need to memzero private data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit alloc_etherdev internally uses kzalloc, so the private data is already zerod out. Reported-by: Lothar Waßmann Signed-off-by: Uwe Kleine-König --- drivers/net/fec.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 8026a16f6b6c..9a25e1e0a2e0 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1386,7 +1386,6 @@ fec_probe(struct platform_device *pdev) /* setup board info structure */ fep = netdev_priv(ndev); - memset(fep, 0, sizeof(*fep)); ndev->base_addr = (unsigned long)ioremap(r->start, resource_size(r)); fep->pdev = pdev; -- cgit v1.2.3 From 24e531b401752995493fa36ee8d8f10c45038e75 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 13 Jan 2011 22:29:05 +0100 Subject: net/fec: put the ioremap cookie immediately into a void __iomem pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Saving it first into struct net_device->base_addr (which is an unsigned long) is pointless and only needs to use more casts than necessary. Reported-by: Lothar Waßmann Signed-off-by: Uwe Kleine-König --- drivers/net/fec.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 9a25e1e0a2e0..14eb6604a7f5 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1170,7 +1170,6 @@ static int fec_enet_init(struct net_device *dev) spin_lock_init(&fep->hw_lock); - fep->hwp = (void __iomem *)dev->base_addr; fep->netdev = dev; /* Get the Ethernet address */ @@ -1387,10 +1386,10 @@ fec_probe(struct platform_device *pdev) /* setup board info structure */ fep = netdev_priv(ndev); - ndev->base_addr = (unsigned long)ioremap(r->start, resource_size(r)); + fep->hwp = ioremap(r->start, resource_size(r)); fep->pdev = pdev; - if (!ndev->base_addr) { + if (!fep->hwp) { ret = -ENOMEM; goto failed_ioremap; } @@ -1453,7 +1452,7 @@ failed_clk: free_irq(irq, ndev); } failed_irq: - iounmap((void __iomem *)ndev->base_addr); + iounmap(fep->hwp); failed_ioremap: free_netdev(ndev); failed_alloc_etherdev: @@ -1475,7 +1474,7 @@ fec_drv_remove(struct platform_device *pdev) fec_enet_mii_remove(fep); clk_disable(fep->clk); clk_put(fep->clk); - iounmap((void __iomem *)ndev->base_addr); + iounmap(fep->hwp); unregister_netdev(ndev); free_netdev(ndev); -- cgit v1.2.3 From 085e79ed88351d2f3cbf257ff4fc00394792da18 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 17 Jan 2011 09:52:18 +0100 Subject: net/fec: consolidate all i.MX options to CONFIG_ARM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moreover stop listing all i.MX platforms featuring a FEC, and use the platform's config symbol that selects registration of a fec device instead. This might make it easier to add new platforms. Set default = y for ARMs having a fec to reduce defconfig sizes. Signed-off-by: Uwe Kleine-König --- drivers/net/Kconfig | 3 ++- drivers/net/fec.c | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 03823327db25..65027a72ca93 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1944,7 +1944,8 @@ config 68360_ENET config FEC bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)" depends on M523x || M527x || M5272 || M528x || M520x || M532x || \ - MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28 + IMX_HAVE_PLATFORM_FEC || MXS_HAVE_PLATFORM_FEC + default IMX_HAVE_PLATFORM_FEC || MXS_HAVE_PLATFORM_FEC if ARM select PHYLIB help Say Y here if you want to use the built-in 10/100 Fast ethernet diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 14eb6604a7f5..dd4e580c7f35 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -54,7 +54,7 @@ #include "fec.h" -#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28) +#if defined(CONFIG_ARM) #define FEC_ALIGNMENT 0xf #else #define FEC_ALIGNMENT 0x3 @@ -147,8 +147,7 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address"); * account when setting it. */ #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ - defined(CONFIG_M520x) || defined(CONFIG_M532x) || \ - defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28) + defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM) #define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16) #else #define OPT_FRAME_SIZE 0 -- cgit v1.2.3 From e497ba825b60727f02d8bc21869f445c5aad34e2 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 17 Jan 2011 20:04:23 +0100 Subject: net/fec: add phy_stop to fec_enet_close MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This undoes the effects of phy_start in fec_enet_open. Reported-by: Lothar Waßmann Signed-off-by: Uwe Kleine-König --- drivers/net/fec.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index dd4e580c7f35..d3dbff514d67 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1029,8 +1029,10 @@ fec_enet_close(struct net_device *dev) netif_stop_queue(dev); fec_stop(dev); - if (fep->phy_dev) + if (fep->phy_dev) { + phy_stop(fep->phy_dev); phy_disconnect(fep->phy_dev); + } fec_enet_free_buffers(dev); -- cgit v1.2.3 From c556167f819160e157b4d73937885de8754ea53c Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 19 Jan 2011 11:58:12 +0100 Subject: net/fec: consistenly name struct net_device pointers "ndev" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A variable named "dev" usually (usually subjective) points to a struct device. Signed-off-by: Uwe Kleine-König --- drivers/net/fec.c | 242 +++++++++++++++++++++++++++--------------------------- 1 file changed, 121 insertions(+), 121 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index d3dbff514d67..c70503a065bb 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -206,11 +206,11 @@ struct fec_enet_private { }; static irqreturn_t fec_enet_interrupt(int irq, void * dev_id); -static void fec_enet_tx(struct net_device *dev); -static void fec_enet_rx(struct net_device *dev); -static int fec_enet_close(struct net_device *dev); -static void fec_restart(struct net_device *dev, int duplex); -static void fec_stop(struct net_device *dev); +static void fec_enet_tx(struct net_device *ndev); +static void fec_enet_rx(struct net_device *ndev); +static int fec_enet_close(struct net_device *ndev); +static void fec_restart(struct net_device *ndev, int duplex); +static void fec_stop(struct net_device *ndev); /* FEC MII MMFR bits definition */ #define FEC_MMFR_ST (1 << 30) @@ -238,9 +238,9 @@ static void *swap_buffer(void *bufaddr, int len) } static netdev_tx_t -fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) +fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) { - struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_private *fep = netdev_priv(ndev); const struct platform_device_id *id_entry = platform_get_device_id(fep->pdev); struct bufdesc *bdp; @@ -261,9 +261,9 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) if (status & BD_ENET_TX_READY) { /* Ooops. All transmit buffers are full. Bail out. - * This should not happen, since dev->tbusy should be set. + * This should not happen, since ndev->tbusy should be set. */ - printk("%s: tx queue full!.\n", dev->name); + printk("%s: tx queue full!.\n", ndev->name); spin_unlock_irqrestore(&fep->hw_lock, flags); return NETDEV_TX_BUSY; } @@ -298,13 +298,13 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Save skb pointer */ fep->tx_skbuff[fep->skb_cur] = skb; - dev->stats.tx_bytes += skb->len; + ndev->stats.tx_bytes += skb->len; fep->skb_cur = (fep->skb_cur+1) & TX_RING_MOD_MASK; /* Push the data cache so the CPM does not get stale memory * data. */ - bdp->cbd_bufaddr = dma_map_single(&dev->dev, bufaddr, + bdp->cbd_bufaddr = dma_map_single(&ndev->dev, bufaddr, FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE); /* Send it on its way. Tell FEC it's ready, interrupt when done, @@ -325,7 +325,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) if (bdp == fep->dirty_tx) { fep->tx_full = 1; - netif_stop_queue(dev); + netif_stop_queue(ndev); } fep->cur_tx = bdp; @@ -336,22 +336,22 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) } static void -fec_timeout(struct net_device *dev) +fec_timeout(struct net_device *ndev) { - struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_private *fep = netdev_priv(ndev); - dev->stats.tx_errors++; + ndev->stats.tx_errors++; - fec_restart(dev, fep->full_duplex); - netif_wake_queue(dev); + fec_restart(ndev, fep->full_duplex); + netif_wake_queue(ndev); } static irqreturn_t -fec_enet_interrupt(int irq, void * dev_id) +fec_enet_interrupt(int irq, void *dev_id) { - struct net_device *dev = dev_id; - struct fec_enet_private *fep = netdev_priv(dev); - uint int_events; + struct net_device *ndev = dev_id; + struct fec_enet_private *fep = netdev_priv(ndev); + uint int_events; irqreturn_t ret = IRQ_NONE; do { @@ -360,7 +360,7 @@ fec_enet_interrupt(int irq, void * dev_id) if (int_events & FEC_ENET_RXF) { ret = IRQ_HANDLED; - fec_enet_rx(dev); + fec_enet_rx(ndev); } /* Transmit OK, or non-fatal error. Update the buffer @@ -369,7 +369,7 @@ fec_enet_interrupt(int irq, void * dev_id) */ if (int_events & FEC_ENET_TXF) { ret = IRQ_HANDLED; - fec_enet_tx(dev); + fec_enet_tx(ndev); } if (int_events & FEC_ENET_MII) { @@ -383,14 +383,14 @@ fec_enet_interrupt(int irq, void * dev_id) static void -fec_enet_tx(struct net_device *dev) +fec_enet_tx(struct net_device *ndev) { struct fec_enet_private *fep; struct bufdesc *bdp; unsigned short status; struct sk_buff *skb; - fep = netdev_priv(dev); + fep = netdev_priv(ndev); spin_lock(&fep->hw_lock); bdp = fep->dirty_tx; @@ -398,7 +398,7 @@ fec_enet_tx(struct net_device *dev) if (bdp == fep->cur_tx && fep->tx_full == 0) break; - dma_unmap_single(&dev->dev, bdp->cbd_bufaddr, FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE); + dma_unmap_single(&ndev->dev, bdp->cbd_bufaddr, FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE); bdp->cbd_bufaddr = 0; skb = fep->tx_skbuff[fep->skb_dirty]; @@ -406,19 +406,19 @@ fec_enet_tx(struct net_device *dev) if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) { - dev->stats.tx_errors++; + ndev->stats.tx_errors++; if (status & BD_ENET_TX_HB) /* No heartbeat */ - dev->stats.tx_heartbeat_errors++; + ndev->stats.tx_heartbeat_errors++; if (status & BD_ENET_TX_LC) /* Late collision */ - dev->stats.tx_window_errors++; + ndev->stats.tx_window_errors++; if (status & BD_ENET_TX_RL) /* Retrans limit */ - dev->stats.tx_aborted_errors++; + ndev->stats.tx_aborted_errors++; if (status & BD_ENET_TX_UN) /* Underrun */ - dev->stats.tx_fifo_errors++; + ndev->stats.tx_fifo_errors++; if (status & BD_ENET_TX_CSL) /* Carrier lost */ - dev->stats.tx_carrier_errors++; + ndev->stats.tx_carrier_errors++; } else { - dev->stats.tx_packets++; + ndev->stats.tx_packets++; } if (status & BD_ENET_TX_READY) @@ -428,7 +428,7 @@ fec_enet_tx(struct net_device *dev) * but we eventually sent the packet OK. */ if (status & BD_ENET_TX_DEF) - dev->stats.collisions++; + ndev->stats.collisions++; /* Free the sk buffer associated with this last transmit */ dev_kfree_skb_any(skb); @@ -445,8 +445,8 @@ fec_enet_tx(struct net_device *dev) */ if (fep->tx_full) { fep->tx_full = 0; - if (netif_queue_stopped(dev)) - netif_wake_queue(dev); + if (netif_queue_stopped(ndev)) + netif_wake_queue(ndev); } } fep->dirty_tx = bdp; @@ -460,9 +460,9 @@ fec_enet_tx(struct net_device *dev) * effectively tossing the packet. */ static void -fec_enet_rx(struct net_device *dev) +fec_enet_rx(struct net_device *ndev) { - struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_private *fep = netdev_priv(ndev); const struct platform_device_id *id_entry = platform_get_device_id(fep->pdev); struct bufdesc *bdp; @@ -496,17 +496,17 @@ fec_enet_rx(struct net_device *dev) /* Check for errors. */ if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) { - dev->stats.rx_errors++; + ndev->stats.rx_errors++; if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { /* Frame too long or too short. */ - dev->stats.rx_length_errors++; + ndev->stats.rx_length_errors++; } if (status & BD_ENET_RX_NO) /* Frame alignment */ - dev->stats.rx_frame_errors++; + ndev->stats.rx_frame_errors++; if (status & BD_ENET_RX_CR) /* CRC Error */ - dev->stats.rx_crc_errors++; + ndev->stats.rx_crc_errors++; if (status & BD_ENET_RX_OV) /* FIFO overrun */ - dev->stats.rx_fifo_errors++; + ndev->stats.rx_fifo_errors++; } /* Report late collisions as a frame error. @@ -514,15 +514,15 @@ fec_enet_rx(struct net_device *dev) * have in the buffer. So, just drop this frame on the floor. */ if (status & BD_ENET_RX_CL) { - dev->stats.rx_errors++; - dev->stats.rx_frame_errors++; + ndev->stats.rx_errors++; + ndev->stats.rx_frame_errors++; goto rx_processing_done; } /* Process the incoming frame. */ - dev->stats.rx_packets++; + ndev->stats.rx_packets++; pkt_len = bdp->cbd_datlen; - dev->stats.rx_bytes += pkt_len; + ndev->stats.rx_bytes += pkt_len; data = (__u8*)__va(bdp->cbd_bufaddr); dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen, @@ -540,13 +540,13 @@ fec_enet_rx(struct net_device *dev) if (unlikely(!skb)) { printk("%s: Memory squeeze, dropping packet.\n", - dev->name); - dev->stats.rx_dropped++; + ndev->name); + ndev->stats.rx_dropped++; } else { skb_reserve(skb, NET_IP_ALIGN); skb_put(skb, pkt_len - 4); /* Make room */ skb_copy_to_linear_data(skb, data, pkt_len - 4); - skb->protocol = eth_type_trans(skb, dev); + skb->protocol = eth_type_trans(skb, ndev); netif_rx(skb); } @@ -577,9 +577,9 @@ rx_processing_done: } /* ------------------------------------------------------------------------- */ -static void __inline__ fec_get_mac(struct net_device *dev) +static void __inline__ fec_get_mac(struct net_device *ndev) { - struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_private *fep = netdev_priv(ndev); struct fec_platform_data *pdata = fep->pdev->dev.platform_data; unsigned char *iap, tmpaddr[ETH_ALEN]; @@ -615,11 +615,11 @@ static void __inline__ fec_get_mac(struct net_device *dev) iap = &tmpaddr[0]; } - memcpy(dev->dev_addr, iap, ETH_ALEN); + memcpy(ndev->dev_addr, iap, ETH_ALEN); /* Adjust MAC if using macaddr */ if (iap == macaddr) - dev->dev_addr[ETH_ALEN-1] = macaddr[ETH_ALEN-1] + fep->pdev->id; + ndev->dev_addr[ETH_ALEN-1] = macaddr[ETH_ALEN-1] + fep->pdev->id; } /* ------------------------------------------------------------------------- */ @@ -627,9 +627,9 @@ static void __inline__ fec_get_mac(struct net_device *dev) /* * Phy section */ -static void fec_enet_adjust_link(struct net_device *dev) +static void fec_enet_adjust_link(struct net_device *ndev) { - struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_private *fep = netdev_priv(ndev); struct phy_device *phy_dev = fep->phy_dev; unsigned long flags; @@ -646,7 +646,7 @@ static void fec_enet_adjust_link(struct net_device *dev) /* Duplex link change */ if (phy_dev->link) { if (fep->full_duplex != phy_dev->duplex) { - fec_restart(dev, phy_dev->duplex); + fec_restart(ndev, phy_dev->duplex); status_change = 1; } } @@ -655,9 +655,9 @@ static void fec_enet_adjust_link(struct net_device *dev) if (phy_dev->link != fep->link) { fep->link = phy_dev->link; if (phy_dev->link) - fec_restart(dev, phy_dev->duplex); + fec_restart(ndev, phy_dev->duplex); else - fec_stop(dev); + fec_stop(ndev); status_change = 1; } @@ -726,9 +726,9 @@ static int fec_enet_mdio_reset(struct mii_bus *bus) return 0; } -static int fec_enet_mii_probe(struct net_device *dev) +static int fec_enet_mii_probe(struct net_device *ndev) { - struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_private *fep = netdev_priv(ndev); struct phy_device *phy_dev = NULL; char mdio_bus_id[MII_BUS_ID_SIZE]; char phy_name[MII_BUS_ID_SIZE + 3]; @@ -753,16 +753,16 @@ static int fec_enet_mii_probe(struct net_device *dev) if (phy_id >= PHY_MAX_ADDR) { printk(KERN_INFO "%s: no PHY, assuming direct connection " - "to switch\n", dev->name); + "to switch\n", ndev->name); strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); phy_id = 0; } snprintf(phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id); - phy_dev = phy_connect(dev, phy_name, &fec_enet_adjust_link, 0, + phy_dev = phy_connect(ndev, phy_name, &fec_enet_adjust_link, 0, PHY_INTERFACE_MODE_MII); if (IS_ERR(phy_dev)) { - printk(KERN_ERR "%s: could not attach to PHY\n", dev->name); + printk(KERN_ERR "%s: could not attach to PHY\n", ndev->name); return PTR_ERR(phy_dev); } @@ -775,7 +775,7 @@ static int fec_enet_mii_probe(struct net_device *dev) fep->full_duplex = 0; printk(KERN_INFO "%s: Freescale FEC PHY driver [%s] " - "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name, + "(mii_bus:phy_addr=%s, irq=%d)\n", ndev->name, fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev), fep->phy_dev->irq); @@ -785,8 +785,8 @@ static int fec_enet_mii_probe(struct net_device *dev) static int fec_enet_mii_init(struct platform_device *pdev) { static struct mii_bus *fec0_mii_bus; - struct net_device *dev = platform_get_drvdata(pdev); - struct fec_enet_private *fep = netdev_priv(dev); + struct net_device *ndev = platform_get_drvdata(pdev); + struct fec_enet_private *fep = netdev_priv(ndev); const struct platform_device_id *id_entry = platform_get_device_id(fep->pdev); int err = -ENXIO, i; @@ -844,7 +844,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) for (i = 0; i < PHY_MAX_ADDR; i++) fep->mii_bus->irq[i] = PHY_POLL; - platform_set_drvdata(dev, fep->mii_bus); + platform_set_drvdata(ndev, fep->mii_bus); if (mdiobus_register(fep->mii_bus)) goto err_out_free_mdio_irq; @@ -872,10 +872,10 @@ static void fec_enet_mii_remove(struct fec_enet_private *fep) mdiobus_free(fep->mii_bus); } -static int fec_enet_get_settings(struct net_device *dev, +static int fec_enet_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd) { - struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_private *fep = netdev_priv(ndev); struct phy_device *phydev = fep->phy_dev; if (!phydev) @@ -884,10 +884,10 @@ static int fec_enet_get_settings(struct net_device *dev, return phy_ethtool_gset(phydev, cmd); } -static int fec_enet_set_settings(struct net_device *dev, +static int fec_enet_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd) { - struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_private *fep = netdev_priv(ndev); struct phy_device *phydev = fep->phy_dev; if (!phydev) @@ -896,14 +896,14 @@ static int fec_enet_set_settings(struct net_device *dev, return phy_ethtool_sset(phydev, cmd); } -static void fec_enet_get_drvinfo(struct net_device *dev, +static void fec_enet_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) { - struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_private *fep = netdev_priv(ndev); strcpy(info->driver, fep->pdev->dev.driver->name); strcpy(info->version, "Revision: 1.0"); - strcpy(info->bus_info, dev_name(&dev->dev)); + strcpy(info->bus_info, dev_name(&ndev->dev)); } static struct ethtool_ops fec_enet_ethtool_ops = { @@ -913,12 +913,12 @@ static struct ethtool_ops fec_enet_ethtool_ops = { .get_link = ethtool_op_get_link, }; -static int fec_enet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) { - struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_private *fep = netdev_priv(ndev); struct phy_device *phydev = fep->phy_dev; - if (!netif_running(dev)) + if (!netif_running(ndev)) return -EINVAL; if (!phydev) @@ -927,9 +927,9 @@ static int fec_enet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return phy_mii_ioctl(phydev, rq, cmd); } -static void fec_enet_free_buffers(struct net_device *dev) +static void fec_enet_free_buffers(struct net_device *ndev) { - struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_private *fep = netdev_priv(ndev); int i; struct sk_buff *skb; struct bufdesc *bdp; @@ -939,7 +939,7 @@ static void fec_enet_free_buffers(struct net_device *dev) skb = fep->rx_skbuff[i]; if (bdp->cbd_bufaddr) - dma_unmap_single(&dev->dev, bdp->cbd_bufaddr, + dma_unmap_single(&ndev->dev, bdp->cbd_bufaddr, FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE); if (skb) dev_kfree_skb(skb); @@ -951,9 +951,9 @@ static void fec_enet_free_buffers(struct net_device *dev) kfree(fep->tx_bounce[i]); } -static int fec_enet_alloc_buffers(struct net_device *dev) +static int fec_enet_alloc_buffers(struct net_device *ndev) { - struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_private *fep = netdev_priv(ndev); int i; struct sk_buff *skb; struct bufdesc *bdp; @@ -962,12 +962,12 @@ static int fec_enet_alloc_buffers(struct net_device *dev) for (i = 0; i < RX_RING_SIZE; i++) { skb = dev_alloc_skb(FEC_ENET_RX_FRSIZE); if (!skb) { - fec_enet_free_buffers(dev); + fec_enet_free_buffers(ndev); return -ENOMEM; } fep->rx_skbuff[i] = skb; - bdp->cbd_bufaddr = dma_map_single(&dev->dev, skb->data, + bdp->cbd_bufaddr = dma_map_single(&ndev->dev, skb->data, FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE); bdp->cbd_sc = BD_ENET_RX_EMPTY; bdp++; @@ -994,47 +994,47 @@ static int fec_enet_alloc_buffers(struct net_device *dev) } static int -fec_enet_open(struct net_device *dev) +fec_enet_open(struct net_device *ndev) { - struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_private *fep = netdev_priv(ndev); int ret; /* I should reset the ring buffers here, but I don't yet know * a simple way to do that. */ - ret = fec_enet_alloc_buffers(dev); + ret = fec_enet_alloc_buffers(ndev); if (ret) return ret; /* Probe and connect to PHY when open the interface */ - ret = fec_enet_mii_probe(dev); + ret = fec_enet_mii_probe(ndev); if (ret) { - fec_enet_free_buffers(dev); + fec_enet_free_buffers(ndev); return ret; } phy_start(fep->phy_dev); - netif_start_queue(dev); + netif_start_queue(ndev); fep->opened = 1; return 0; } static int -fec_enet_close(struct net_device *dev) +fec_enet_close(struct net_device *ndev) { - struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_private *fep = netdev_priv(ndev); /* Don't know what to do yet. */ fep->opened = 0; - netif_stop_queue(dev); - fec_stop(dev); + netif_stop_queue(ndev); + fec_stop(ndev); if (fep->phy_dev) { phy_stop(fep->phy_dev); phy_disconnect(fep->phy_dev); } - fec_enet_free_buffers(dev); + fec_enet_free_buffers(ndev); return 0; } @@ -1052,14 +1052,14 @@ fec_enet_close(struct net_device *dev) #define HASH_BITS 6 /* #bits in hash */ #define CRC32_POLY 0xEDB88320 -static void set_multicast_list(struct net_device *dev) +static void set_multicast_list(struct net_device *ndev) { - struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_private *fep = netdev_priv(ndev); struct netdev_hw_addr *ha; unsigned int i, bit, data, crc, tmp; unsigned char hash; - if (dev->flags & IFF_PROMISC) { + if (ndev->flags & IFF_PROMISC) { tmp = readl(fep->hwp + FEC_R_CNTRL); tmp |= 0x8; writel(tmp, fep->hwp + FEC_R_CNTRL); @@ -1070,7 +1070,7 @@ static void set_multicast_list(struct net_device *dev) tmp &= ~0x8; writel(tmp, fep->hwp + FEC_R_CNTRL); - if (dev->flags & IFF_ALLMULTI) { + if (ndev->flags & IFF_ALLMULTI) { /* Catch all multicast addresses, so set the * filter to all 1's */ @@ -1085,7 +1085,7 @@ static void set_multicast_list(struct net_device *dev) writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW); - netdev_for_each_mc_addr(ha, dev) { + netdev_for_each_mc_addr(ha, ndev) { /* Only support group multicast for now */ if (!(ha->addr[0] & 1)) continue; @@ -1093,7 +1093,7 @@ static void set_multicast_list(struct net_device *dev) /* calculate crc32 value of mac address */ crc = 0xffffffff; - for (i = 0; i < dev->addr_len; i++) { + for (i = 0; i < ndev->addr_len; i++) { data = ha->addr[i]; for (bit = 0; bit < 8; bit++, data >>= 1) { crc = (crc >> 1) ^ @@ -1120,20 +1120,20 @@ static void set_multicast_list(struct net_device *dev) /* Set a MAC change in hardware. */ static int -fec_set_mac_address(struct net_device *dev, void *p) +fec_set_mac_address(struct net_device *ndev, void *p) { - struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_private *fep = netdev_priv(ndev); struct sockaddr *addr = p; if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; - memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len); - writel(dev->dev_addr[3] | (dev->dev_addr[2] << 8) | - (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24), + writel(ndev->dev_addr[3] | (ndev->dev_addr[2] << 8) | + (ndev->dev_addr[1] << 16) | (ndev->dev_addr[0] << 24), fep->hwp + FEC_ADDR_LOW); - writel((dev->dev_addr[5] << 16) | (dev->dev_addr[4] << 24), + writel((ndev->dev_addr[5] << 16) | (ndev->dev_addr[4] << 24), fep->hwp + FEC_ADDR_HIGH); return 0; } @@ -1154,9 +1154,9 @@ static const struct net_device_ops fec_netdev_ops = { * XXX: We need to clean up on failure exits here. * */ -static int fec_enet_init(struct net_device *dev) +static int fec_enet_init(struct net_device *ndev) { - struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_private *fep = netdev_priv(ndev); struct bufdesc *cbd_base; struct bufdesc *bdp; int i; @@ -1171,19 +1171,19 @@ static int fec_enet_init(struct net_device *dev) spin_lock_init(&fep->hw_lock); - fep->netdev = dev; + fep->netdev = ndev; /* Get the Ethernet address */ - fec_get_mac(dev); + fec_get_mac(ndev); /* Set receive and transmit descriptor base. */ fep->rx_bd_base = cbd_base; fep->tx_bd_base = cbd_base + RX_RING_SIZE; /* The FEC Ethernet specific entries in the device structure */ - dev->watchdog_timeo = TX_TIMEOUT; - dev->netdev_ops = &fec_netdev_ops; - dev->ethtool_ops = &fec_enet_ethtool_ops; + ndev->watchdog_timeo = TX_TIMEOUT; + ndev->netdev_ops = &fec_netdev_ops; + ndev->ethtool_ops = &fec_enet_ethtool_ops; /* Initialize the receive buffer descriptors. */ bdp = fep->rx_bd_base; @@ -1212,7 +1212,7 @@ static int fec_enet_init(struct net_device *dev) bdp--; bdp->cbd_sc |= BD_SC_WRAP; - fec_restart(dev, 0); + fec_restart(ndev, 0); return 0; } @@ -1222,9 +1222,9 @@ static int fec_enet_init(struct net_device *dev) * duplex. */ static void -fec_restart(struct net_device *dev, int duplex) +fec_restart(struct net_device *ndev, int duplex) { - struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_private *fep = netdev_priv(ndev); const struct platform_device_id *id_entry = platform_get_device_id(fep->pdev); int i; @@ -1239,7 +1239,7 @@ fec_restart(struct net_device *dev, int duplex) * so need to reconfigure it. */ if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) { - memcpy(&temp_mac, dev->dev_addr, ETH_ALEN); + memcpy(&temp_mac, ndev->dev_addr, ETH_ALEN); writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW); writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH); } @@ -1339,9 +1339,9 @@ fec_restart(struct net_device *dev, int duplex) } static void -fec_stop(struct net_device *dev) +fec_stop(struct net_device *ndev) { - struct fec_enet_private *fep = netdev_priv(dev); + struct fec_enet_private *fep = netdev_priv(ndev); /* We cannot expect a graceful transmit stop without link !!! */ if (fep->link) { -- cgit v1.2.3 From db8880bc92657559320ba8384acb2547d4255521 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 19 Jan 2011 20:26:39 +0100 Subject: net/fec: some whitespace cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A few of these were found and reported by Lothar Waßmann. Signed-off-by: Uwe Kleine-König --- drivers/net/fec.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index c70503a065bb..4c888f1825a3 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -182,7 +182,7 @@ struct fec_enet_private { struct bufdesc *rx_bd_base; struct bufdesc *tx_bd_base; /* The next free ring entry */ - struct bufdesc *cur_rx, *cur_tx; + struct bufdesc *cur_rx, *cur_tx; /* The ring entries to be free()ed */ struct bufdesc *dirty_tx; @@ -190,15 +190,15 @@ struct fec_enet_private { /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */ spinlock_t hw_lock; - struct platform_device *pdev; + struct platform_device *pdev; int opened; /* Phylib and MDIO interface */ - struct mii_bus *mii_bus; - struct phy_device *phy_dev; - int mii_timeout; - uint phy_speed; + struct mii_bus *mii_bus; + struct phy_device *phy_dev; + int mii_timeout; + uint phy_speed; phy_interface_t phy_interface; int link; int full_duplex; @@ -525,8 +525,8 @@ fec_enet_rx(struct net_device *ndev) ndev->stats.rx_bytes += pkt_len; data = (__u8*)__va(bdp->cbd_bufaddr); - dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen, - DMA_FROM_DEVICE); + dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen, + DMA_FROM_DEVICE); if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) swap_buffer(data, pkt_len); @@ -550,7 +550,7 @@ fec_enet_rx(struct net_device *ndev) netif_rx(skb); } - bdp->cbd_bufaddr = dma_map_single(NULL, data, bdp->cbd_datlen, + bdp->cbd_bufaddr = dma_map_single(NULL, data, bdp->cbd_datlen, DMA_FROM_DEVICE); rx_processing_done: /* Clear the status flags for this buffer */ @@ -1034,7 +1034,7 @@ fec_enet_close(struct net_device *ndev) phy_disconnect(fep->phy_dev); } - fec_enet_free_buffers(ndev); + fec_enet_free_buffers(ndev); return 0; } @@ -1147,7 +1147,7 @@ static const struct net_device_ops fec_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_tx_timeout = fec_timeout, .ndo_set_mac_address = fec_set_mac_address, - .ndo_do_ioctl = fec_enet_ioctl, + .ndo_do_ioctl = fec_enet_ioctl, }; /* -- cgit v1.2.3 From 45993653bd5935dbf975bc26a834f2ff23c9f914 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 19 Jan 2011 20:47:04 +0100 Subject: net/fec: reorder functions a bit allows removing forward declarations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König --- drivers/net/fec.c | 353 +++++++++++++++++++++++++++--------------------------- 1 file changed, 174 insertions(+), 179 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 4c888f1825a3..3f5dfe2e41ac 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -205,13 +205,6 @@ struct fec_enet_private { struct completion mdio_done; }; -static irqreturn_t fec_enet_interrupt(int irq, void * dev_id); -static void fec_enet_tx(struct net_device *ndev); -static void fec_enet_rx(struct net_device *ndev); -static int fec_enet_close(struct net_device *ndev); -static void fec_restart(struct net_device *ndev, int duplex); -static void fec_stop(struct net_device *ndev); - /* FEC MII MMFR bits definition */ #define FEC_MMFR_ST (1 << 30) #define FEC_MMFR_OP_READ (2 << 28) @@ -335,53 +328,159 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) return NETDEV_TX_OK; } +/* This function is called to start or restart the FEC during a link + * change. This only happens when switching between half and full + * duplex. + */ static void -fec_timeout(struct net_device *ndev) +fec_restart(struct net_device *ndev, int duplex) { struct fec_enet_private *fep = netdev_priv(ndev); + const struct platform_device_id *id_entry = + platform_get_device_id(fep->pdev); + int i; + u32 val, temp_mac[2]; - ndev->stats.tx_errors++; + /* Whack a reset. We should wait for this. */ + writel(1, fep->hwp + FEC_ECNTRL); + udelay(10); - fec_restart(ndev, fep->full_duplex); - netif_wake_queue(ndev); -} + /* + * enet-mac reset will reset mac address registers too, + * so need to reconfigure it. + */ + if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) { + memcpy(&temp_mac, ndev->dev_addr, ETH_ALEN); + writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW); + writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH); + } -static irqreturn_t -fec_enet_interrupt(int irq, void *dev_id) -{ - struct net_device *ndev = dev_id; - struct fec_enet_private *fep = netdev_priv(ndev); - uint int_events; - irqreturn_t ret = IRQ_NONE; + /* Clear any outstanding interrupt. */ + writel(0xffc00000, fep->hwp + FEC_IEVENT); - do { - int_events = readl(fep->hwp + FEC_IEVENT); - writel(int_events, fep->hwp + FEC_IEVENT); + /* Reset all multicast. */ + writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); + writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW); +#ifndef CONFIG_M5272 + writel(0, fep->hwp + FEC_HASH_TABLE_HIGH); + writel(0, fep->hwp + FEC_HASH_TABLE_LOW); +#endif - if (int_events & FEC_ENET_RXF) { - ret = IRQ_HANDLED; - fec_enet_rx(ndev); - } + /* Set maximum receive buffer size. */ + writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE); - /* Transmit OK, or non-fatal error. Update the buffer - * descriptors. FEC handles all errors, we just discover - * them as part of the transmit process. - */ - if (int_events & FEC_ENET_TXF) { - ret = IRQ_HANDLED; - fec_enet_tx(ndev); + /* Set receive and transmit descriptor base. */ + writel(fep->bd_dma, fep->hwp + FEC_R_DES_START); + writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE, + fep->hwp + FEC_X_DES_START); + + fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; + fep->cur_rx = fep->rx_bd_base; + + /* Reset SKB transmit buffers. */ + fep->skb_cur = fep->skb_dirty = 0; + for (i = 0; i <= TX_RING_MOD_MASK; i++) { + if (fep->tx_skbuff[i]) { + dev_kfree_skb_any(fep->tx_skbuff[i]); + fep->tx_skbuff[i] = NULL; } + } - if (int_events & FEC_ENET_MII) { - ret = IRQ_HANDLED; - complete(&fep->mdio_done); + /* Enable MII mode */ + if (duplex) { + /* MII enable / FD enable */ + writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL); + writel(0x04, fep->hwp + FEC_X_CNTRL); + } else { + /* MII enable / No Rcv on Xmit */ + writel(OPT_FRAME_SIZE | 0x06, fep->hwp + FEC_R_CNTRL); + writel(0x0, fep->hwp + FEC_X_CNTRL); + } + fep->full_duplex = duplex; + + /* Set MII speed */ + writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); + + /* + * The phy interface and speed need to get configured + * differently on enet-mac. + */ + if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) { + val = readl(fep->hwp + FEC_R_CNTRL); + + /* MII or RMII */ + if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) + val |= (1 << 8); + else + val &= ~(1 << 8); + + /* 10M or 100M */ + if (fep->phy_dev && fep->phy_dev->speed == SPEED_100) + val &= ~(1 << 9); + else + val |= (1 << 9); + + writel(val, fep->hwp + FEC_R_CNTRL); + } else { +#ifdef FEC_MIIGSK_ENR + if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) { + /* disable the gasket and wait */ + writel(0, fep->hwp + FEC_MIIGSK_ENR); + while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4) + udelay(1); + + /* + * configure the gasket: + * RMII, 50 MHz, no loopback, no echo + */ + writel(1, fep->hwp + FEC_MIIGSK_CFGR); + + /* re-enable the gasket */ + writel(2, fep->hwp + FEC_MIIGSK_ENR); } - } while (int_events); +#endif + } - return ret; + /* And last, enable the transmit and receive processing */ + writel(2, fep->hwp + FEC_ECNTRL); + writel(0, fep->hwp + FEC_R_DES_ACTIVE); + + /* Enable interrupts we wish to service */ + writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); +} + +static void +fec_stop(struct net_device *ndev) +{ + struct fec_enet_private *fep = netdev_priv(ndev); + + /* We cannot expect a graceful transmit stop without link !!! */ + if (fep->link) { + writel(1, fep->hwp + FEC_X_CNTRL); /* Graceful transmit stop */ + udelay(10); + if (!(readl(fep->hwp + FEC_IEVENT) & FEC_ENET_GRA)) + printk("fec_stop : Graceful transmit stop did not complete !\n"); + } + + /* Whack a reset. We should wait for this. */ + writel(1, fep->hwp + FEC_ECNTRL); + udelay(10); + writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); + writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); } +static void +fec_timeout(struct net_device *ndev) +{ + struct fec_enet_private *fep = netdev_priv(ndev); + + ndev->stats.tx_errors++; + + fec_restart(ndev, fep->full_duplex); + netif_wake_queue(ndev); +} + static void fec_enet_tx(struct net_device *ndev) { @@ -576,6 +675,43 @@ rx_processing_done: spin_unlock(&fep->hw_lock); } +static irqreturn_t +fec_enet_interrupt(int irq, void *dev_id) +{ + struct net_device *ndev = dev_id; + struct fec_enet_private *fep = netdev_priv(ndev); + uint int_events; + irqreturn_t ret = IRQ_NONE; + + do { + int_events = readl(fep->hwp + FEC_IEVENT); + writel(int_events, fep->hwp + FEC_IEVENT); + + if (int_events & FEC_ENET_RXF) { + ret = IRQ_HANDLED; + fec_enet_rx(ndev); + } + + /* Transmit OK, or non-fatal error. Update the buffer + * descriptors. FEC handles all errors, we just discover + * them as part of the transmit process. + */ + if (int_events & FEC_ENET_TXF) { + ret = IRQ_HANDLED; + fec_enet_tx(ndev); + } + + if (int_events & FEC_ENET_MII) { + ret = IRQ_HANDLED; + complete(&fep->mdio_done); + } + } while (int_events); + + return ret; +} + + + /* ------------------------------------------------------------------------- */ static void __inline__ fec_get_mac(struct net_device *ndev) { @@ -1217,147 +1353,6 @@ static int fec_enet_init(struct net_device *ndev) return 0; } -/* This function is called to start or restart the FEC during a link - * change. This only happens when switching between half and full - * duplex. - */ -static void -fec_restart(struct net_device *ndev, int duplex) -{ - struct fec_enet_private *fep = netdev_priv(ndev); - const struct platform_device_id *id_entry = - platform_get_device_id(fep->pdev); - int i; - u32 val, temp_mac[2]; - - /* Whack a reset. We should wait for this. */ - writel(1, fep->hwp + FEC_ECNTRL); - udelay(10); - - /* - * enet-mac reset will reset mac address registers too, - * so need to reconfigure it. - */ - if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) { - memcpy(&temp_mac, ndev->dev_addr, ETH_ALEN); - writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW); - writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH); - } - - /* Clear any outstanding interrupt. */ - writel(0xffc00000, fep->hwp + FEC_IEVENT); - - /* Reset all multicast. */ - writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); - writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW); -#ifndef CONFIG_M5272 - writel(0, fep->hwp + FEC_HASH_TABLE_HIGH); - writel(0, fep->hwp + FEC_HASH_TABLE_LOW); -#endif - - /* Set maximum receive buffer size. */ - writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE); - - /* Set receive and transmit descriptor base. */ - writel(fep->bd_dma, fep->hwp + FEC_R_DES_START); - writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE, - fep->hwp + FEC_X_DES_START); - - fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; - fep->cur_rx = fep->rx_bd_base; - - /* Reset SKB transmit buffers. */ - fep->skb_cur = fep->skb_dirty = 0; - for (i = 0; i <= TX_RING_MOD_MASK; i++) { - if (fep->tx_skbuff[i]) { - dev_kfree_skb_any(fep->tx_skbuff[i]); - fep->tx_skbuff[i] = NULL; - } - } - - /* Enable MII mode */ - if (duplex) { - /* MII enable / FD enable */ - writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL); - writel(0x04, fep->hwp + FEC_X_CNTRL); - } else { - /* MII enable / No Rcv on Xmit */ - writel(OPT_FRAME_SIZE | 0x06, fep->hwp + FEC_R_CNTRL); - writel(0x0, fep->hwp + FEC_X_CNTRL); - } - fep->full_duplex = duplex; - - /* Set MII speed */ - writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); - - /* - * The phy interface and speed need to get configured - * differently on enet-mac. - */ - if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) { - val = readl(fep->hwp + FEC_R_CNTRL); - - /* MII or RMII */ - if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) - val |= (1 << 8); - else - val &= ~(1 << 8); - - /* 10M or 100M */ - if (fep->phy_dev && fep->phy_dev->speed == SPEED_100) - val &= ~(1 << 9); - else - val |= (1 << 9); - - writel(val, fep->hwp + FEC_R_CNTRL); - } else { -#ifdef FEC_MIIGSK_ENR - if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) { - /* disable the gasket and wait */ - writel(0, fep->hwp + FEC_MIIGSK_ENR); - while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4) - udelay(1); - - /* - * configure the gasket: - * RMII, 50 MHz, no loopback, no echo - */ - writel(1, fep->hwp + FEC_MIIGSK_CFGR); - - /* re-enable the gasket */ - writel(2, fep->hwp + FEC_MIIGSK_ENR); - } -#endif - } - - /* And last, enable the transmit and receive processing */ - writel(2, fep->hwp + FEC_ECNTRL); - writel(0, fep->hwp + FEC_R_DES_ACTIVE); - - /* Enable interrupts we wish to service */ - writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); -} - -static void -fec_stop(struct net_device *ndev) -{ - struct fec_enet_private *fep = netdev_priv(ndev); - - /* We cannot expect a graceful transmit stop without link !!! */ - if (fep->link) { - writel(1, fep->hwp + FEC_X_CNTRL); /* Graceful transmit stop */ - udelay(10); - if (!(readl(fep->hwp + FEC_IEVENT) & FEC_ENET_GRA)) - printk("fec_stop : Graceful transmit stop did not complete !\n"); - } - - /* Whack a reset. We should wait for this. */ - writel(1, fep->hwp + FEC_ECNTRL); - udelay(10); - writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); - writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); -} - static int __devinit fec_probe(struct platform_device *pdev) { -- cgit v1.2.3 From d1ab1f54a1b0fb0ae6479fad6e26983f09fd263a Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 20 Jan 2011 09:26:38 +0100 Subject: net/fec: provide device for dma functions and matching sizes for map and unmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes warnings when CONFIG_DMA_API_DEBUG=y: NULL NULL: DMA-API: device driver tries to free DMA memory it has not allocated [device address=0x000000004781a020] [size=64 bytes] net eth0: DMA-API: device driver frees DMA memory with different size [device address=0x000000004781a020] [map size=2048 bytes] [unmap size=64 bytes] Moreover pass the platform device to dma_{,un}map_single which makes more sense because the logical network device doesn't know anything about dma. Passing the platform device was a suggestion by Lothar Waßmann. Signed-off-by: Uwe Kleine-König --- drivers/net/fec.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 3f5dfe2e41ac..0c984d6b25f6 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -297,7 +297,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) /* Push the data cache so the CPM does not get stale memory * data. */ - bdp->cbd_bufaddr = dma_map_single(&ndev->dev, bufaddr, + bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, bufaddr, FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE); /* Send it on its way. Tell FEC it's ready, interrupt when done, @@ -497,7 +497,8 @@ fec_enet_tx(struct net_device *ndev) if (bdp == fep->cur_tx && fep->tx_full == 0) break; - dma_unmap_single(&ndev->dev, bdp->cbd_bufaddr, FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE); + dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr, + FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE); bdp->cbd_bufaddr = 0; skb = fep->tx_skbuff[fep->skb_dirty]; @@ -624,8 +625,8 @@ fec_enet_rx(struct net_device *ndev) ndev->stats.rx_bytes += pkt_len; data = (__u8*)__va(bdp->cbd_bufaddr); - dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen, - DMA_FROM_DEVICE); + dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr, + FEC_ENET_TX_FRSIZE, DMA_FROM_DEVICE); if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME) swap_buffer(data, pkt_len); @@ -649,8 +650,8 @@ fec_enet_rx(struct net_device *ndev) netif_rx(skb); } - bdp->cbd_bufaddr = dma_map_single(NULL, data, bdp->cbd_datlen, - DMA_FROM_DEVICE); + bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, data, + FEC_ENET_TX_FRSIZE, DMA_FROM_DEVICE); rx_processing_done: /* Clear the status flags for this buffer */ status &= ~BD_ENET_RX_STATS; @@ -1075,7 +1076,7 @@ static void fec_enet_free_buffers(struct net_device *ndev) skb = fep->rx_skbuff[i]; if (bdp->cbd_bufaddr) - dma_unmap_single(&ndev->dev, bdp->cbd_bufaddr, + dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr, FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE); if (skb) dev_kfree_skb(skb); @@ -1103,7 +1104,7 @@ static int fec_enet_alloc_buffers(struct net_device *ndev) } fep->rx_skbuff[i] = skb; - bdp->cbd_bufaddr = dma_map_single(&ndev->dev, skb->data, + bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, skb->data, FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE); bdp->cbd_sc = BD_ENET_RX_EMPTY; bdp++; -- cgit v1.2.3 From b3cde36cf1e19f696cb302ea426b5cf6ab4afb8a Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 25 Jan 2011 18:03:37 +0100 Subject: net/fec: postpone unsetting driver data until the hardware is stopped MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Lothar Waßmann Signed-off-by: Uwe Kleine-König --- drivers/net/fec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 0c984d6b25f6..c3229713b1e2 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1465,8 +1465,6 @@ fec_drv_remove(struct platform_device *pdev) struct fec_enet_private *fep = netdev_priv(ndev); struct resource *r; - platform_set_drvdata(pdev, NULL); - fec_stop(ndev); fec_enet_mii_remove(fep); clk_disable(fep->clk); @@ -1479,6 +1477,8 @@ fec_drv_remove(struct platform_device *pdev) BUG_ON(!r); release_mem_region(r->start, resource_size(r)); + platform_set_drvdata(pdev, NULL); + return 0; } -- cgit v1.2.3 From cd1f402c18cf31b38bb304bc0c320669762ac50b Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 25 Jan 2011 22:11:25 +0100 Subject: net/fec: enable flow control and length check on enet-mac MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also optimize not to reread the value written to FEC_R_CNTRL. Signed-off-by: Uwe Kleine-König --- drivers/net/fec.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index c3229713b1e2..74798bee672e 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -339,7 +339,8 @@ fec_restart(struct net_device *ndev, int duplex) const struct platform_device_id *id_entry = platform_get_device_id(fep->pdev); int i; - u32 val, temp_mac[2]; + u32 temp_mac[2]; + u32 rcntl = OPT_FRAME_SIZE | 0x04; /* Whack a reset. We should wait for this. */ writel(1, fep->hwp + FEC_ECNTRL); @@ -388,14 +389,14 @@ fec_restart(struct net_device *ndev, int duplex) /* Enable MII mode */ if (duplex) { - /* MII enable / FD enable */ - writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL); + /* FD enable */ writel(0x04, fep->hwp + FEC_X_CNTRL); } else { - /* MII enable / No Rcv on Xmit */ - writel(OPT_FRAME_SIZE | 0x06, fep->hwp + FEC_R_CNTRL); + /* No Rcv on Xmit */ + rcntl |= 0x02; writel(0x0, fep->hwp + FEC_X_CNTRL); } + fep->full_duplex = duplex; /* Set MII speed */ @@ -406,21 +407,21 @@ fec_restart(struct net_device *ndev, int duplex) * differently on enet-mac. */ if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) { - val = readl(fep->hwp + FEC_R_CNTRL); + /* Enable flow control and length check */ + rcntl |= 0x40000000 | 0x00000020; /* MII or RMII */ if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) - val |= (1 << 8); + rcntl |= (1 << 8); else - val &= ~(1 << 8); + rcntl &= ~(1 << 8); /* 10M or 100M */ if (fep->phy_dev && fep->phy_dev->speed == SPEED_100) - val &= ~(1 << 9); + rcntl &= ~(1 << 9); else - val |= (1 << 9); + rcntl |= (1 << 9); - writel(val, fep->hwp + FEC_R_CNTRL); } else { #ifdef FEC_MIIGSK_ENR if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) { @@ -440,6 +441,7 @@ fec_restart(struct net_device *ndev, int duplex) } #endif } + writel(rcntl, fep->hwp + FEC_R_CNTRL); /* And last, enable the transmit and receive processing */ writel(2, fep->hwp + FEC_ECNTRL); -- cgit v1.2.3 From 0f5cd45960173ba5b36727decbb4a241cbd35ef9 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Tue, 15 Feb 2011 21:29:32 +0530 Subject: ath9k: Fix ath9k prevents CPU to enter C3 states The DMA latency issue is observed only in Intel pinetrail platforms but in the driver we had a default PM-QOS value of 55. This caused unnecessary power consumption and battery drain in other platforms. Remove the pm-qos thing in the driver code and address the throughput issue in Intel pinetrail platfroms in user space using any one of the scripts in below links: http://www.kernel.org/pub/linux/kernel/people/mcgrof/scripts/cpudmalatency.c http://johannes.sipsolutions.net/files/netlatency.c.txt More details can be found in the following bugzilla link: https://bugzilla.kernel.org/show_bug.cgi?id=27532 This reverts the following commits: 98c316e348bedffa730e6f1e4baeb8a3c3e0f28b 4dc3530df7c0428b41c00399a7ee8c929406d181 10598c124ecabbbfd7522f74de19b8f7d52a1bee Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 6 ------ drivers/net/wireless/ath/ath9k/init.c | 8 -------- drivers/net/wireless/ath/ath9k/main.c | 8 -------- 3 files changed, 22 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 23838e37d45f..1a7fa6ea4cf5 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -21,7 +21,6 @@ #include #include #include -#include #include "debug.h" #include "common.h" @@ -57,8 +56,6 @@ struct ath_node; #define A_MAX(a, b) ((a) > (b) ? (a) : (b)) -#define ATH9K_PM_QOS_DEFAULT_VALUE 55 - #define TSF_TO_TU(_h,_l) \ ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) @@ -633,8 +630,6 @@ struct ath_softc { struct ath_descdma txsdma; struct ath_ant_comb ant_comb; - - struct pm_qos_request_list pm_qos_req; }; struct ath_wiphy { @@ -666,7 +661,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) extern struct ieee80211_ops ath9k_ops; extern int ath9k_modparam_nohwcrypt; extern int led_blink; -extern int ath9k_pm_qos_value; extern bool is_ath9k_unloaded; irqreturn_t ath_isr(int irq, void *dev); diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 087a6a95edd5..a033d01bf8a0 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -41,10 +41,6 @@ static int ath9k_btcoex_enable; module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444); MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); -int ath9k_pm_qos_value = ATH9K_PM_QOS_DEFAULT_VALUE; -module_param_named(pmqos, ath9k_pm_qos_value, int, S_IRUSR | S_IRGRP | S_IROTH); -MODULE_PARM_DESC(pmqos, "User specified PM-QOS value"); - bool is_ath9k_unloaded; /* We use the hw_value as an index into our private channel structure */ @@ -762,9 +758,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, ath_init_leds(sc); ath_start_rfkill_poll(sc); - pm_qos_add_request(&sc->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); - return 0; error_world: @@ -831,7 +824,6 @@ void ath9k_deinit_device(struct ath_softc *sc) } ieee80211_unregister_hw(hw); - pm_qos_remove_request(&sc->pm_qos_req); ath_rx_cleanup(sc); ath_tx_cleanup(sc); ath9k_deinit_softc(sc); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index da5c64597c1f..a09d15f7aa6e 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1173,12 +1173,6 @@ static int ath9k_start(struct ieee80211_hw *hw) ath9k_btcoex_timer_resume(sc); } - /* User has the option to provide pm-qos value as a module - * parameter rather than using the default value of - * 'ATH9K_PM_QOS_DEFAULT_VALUE'. - */ - pm_qos_update_request(&sc->pm_qos_req, ath9k_pm_qos_value); - if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en) common->bus_ops->extn_synch_en(common); @@ -1345,8 +1339,6 @@ static void ath9k_stop(struct ieee80211_hw *hw) sc->sc_flags |= SC_OP_INVALID; - pm_qos_update_request(&sc->pm_qos_req, PM_QOS_DEFAULT_VALUE); - mutex_unlock(&sc->mutex); ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n"); -- cgit v1.2.3 From 1621dbbdb90f42b7bd14aea1c44ee49b558d1b1a Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 28 Jan 2011 15:17:55 -0800 Subject: [SCSI] qla2xxx: Return DID_NO_CONNECT when FC device is lost. If the target device gets lost, this fix is needed, as it causes negative unintended responses on basic I/O tests. If the target device gets lost, the upstream qla2xxx driver returns SCSI_MLQUEUE_TARGET_BUSY which causes an immediate retry without drop in the number of allowed retries. This semantic change, as a result of removing FC_DEVICE_LOST check is reasonable, as it only extends a short transitional period, until the transport is called to notify that the rport as lost (fc_remote_port_delete()). Once transport notification is done, fc_remote_port_chkready() check will take over. Signed-off-by: Andrew Vasquez Signed-off-by: Madhuranath Iyengar Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_os.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 47208984903d..f27724d76cf6 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -562,7 +562,6 @@ qla2xxx_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *) } if (atomic_read(&fcport->state) != FCS_ONLINE) { if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || - atomic_read(&fcport->state) == FCS_DEVICE_LOST || atomic_read(&base_vha->loop_state) == LOOP_DEAD) { cmd->result = DID_NO_CONNECT << 16; goto qc24_fail_command; -- cgit v1.2.3 From 60031fcc17057e21566ed34ba23e93fffda1aa27 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 12 Jan 2011 18:39:40 +0000 Subject: sfc: Move TX queue core queue mapping into tx.c efx_hard_start_xmit() needs to implement a mapping which is the inverse of tx_queue::core_txq. Move the initialisation of tx_queue::core_txq next to efx_hard_start_xmit() to make the connection more obvious. Signed-off-by: Ben Hutchings --- drivers/net/sfc/efx.c | 6 ++---- drivers/net/sfc/efx.h | 1 + drivers/net/sfc/tx.c | 7 +++++++ 3 files changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 002bac743843..c559bc372fc1 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -1910,10 +1910,8 @@ static int efx_register_netdev(struct efx_nic *efx) efx_for_each_channel(channel, efx) { struct efx_tx_queue *tx_queue; - efx_for_each_channel_tx_queue(tx_queue, channel) { - tx_queue->core_txq = netdev_get_tx_queue( - efx->net_dev, tx_queue->queue / EFX_TXQ_TYPES); - } + efx_for_each_channel_tx_queue(tx_queue, channel) + efx_init_tx_queue_core_txq(tx_queue); } /* Always start with carrier off; PHY events will detect the link */ diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index d43a7e5212b1..116207045068 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h @@ -29,6 +29,7 @@ extern int efx_probe_tx_queue(struct efx_tx_queue *tx_queue); extern void efx_remove_tx_queue(struct efx_tx_queue *tx_queue); extern void efx_init_tx_queue(struct efx_tx_queue *tx_queue); +extern void efx_init_tx_queue_core_txq(struct efx_tx_queue *tx_queue); extern void efx_fini_tx_queue(struct efx_tx_queue *tx_queue); extern void efx_release_tx_buffers(struct efx_tx_queue *tx_queue); extern netdev_tx_t diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index 2f5e9da657bf..7e463fb19fb9 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c @@ -347,6 +347,13 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb, return efx_enqueue_skb(tx_queue, skb); } +void efx_init_tx_queue_core_txq(struct efx_tx_queue *tx_queue) +{ + /* Must be inverse of queue lookup in efx_hard_start_xmit() */ + tx_queue->core_txq = netdev_get_tx_queue( + tx_queue->efx->net_dev, tx_queue->queue / EFX_TXQ_TYPES); +} + void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) { unsigned fill_level; -- cgit v1.2.3 From 525da9072c28df815bff64bf00f3b11ab88face8 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 7 Feb 2011 23:04:38 +0000 Subject: sfc: Distinguish queue lookup from test for queue existence efx_channel_get_{rx,tx}_queue() currently return NULL if the channel isn't used for traffic in that direction. In most cases this is a bug, but some callers rely on it as an existence test. Add existence test functions efx_channel_has_{rx_queue,tx_queues}() and use them as appropriate. Change efx_channel_get_{rx,tx}_queue() to assert that the requested queue exists. Remove now-redundant initialisation from efx_set_channels(). Signed-off-by: Ben Hutchings --- drivers/net/sfc/efx.c | 17 ++--------------- drivers/net/sfc/ethtool.c | 6 +++--- drivers/net/sfc/net_driver.h | 39 ++++++++++++++++++++++++++++----------- 3 files changed, 33 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index c559bc372fc1..6189d3066018 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -1271,21 +1271,8 @@ static void efx_remove_interrupts(struct efx_nic *efx) static void efx_set_channels(struct efx_nic *efx) { - struct efx_channel *channel; - struct efx_tx_queue *tx_queue; - efx->tx_channel_offset = separate_tx_channels ? efx->n_channels - efx->n_tx_channels : 0; - - /* Channel pointers were set in efx_init_struct() but we now - * need to clear them for TX queues in any RX-only channels. */ - efx_for_each_channel(channel, efx) { - if (channel->channel - efx->tx_channel_offset >= - efx->n_tx_channels) { - efx_for_each_channel_tx_queue(tx_queue, channel) - tx_queue->channel = NULL; - } - } } static int efx_probe_nic(struct efx_nic *efx) @@ -1531,9 +1518,9 @@ void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs, efx->irq_rx_adaptive = rx_adaptive; efx->irq_rx_moderation = rx_ticks; efx_for_each_channel(channel, efx) { - if (efx_channel_get_rx_queue(channel)) + if (efx_channel_has_rx_queue(channel)) channel->irq_moderation = rx_ticks; - else if (efx_channel_get_tx_queue(channel, 0)) + else if (efx_channel_has_tx_queues(channel)) channel->irq_moderation = tx_ticks; } } diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 713969accdbd..272cfe724e1b 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -631,7 +631,7 @@ static int efx_ethtool_get_coalesce(struct net_device *net_dev, /* Find lowest IRQ moderation across all used TX queues */ coalesce->tx_coalesce_usecs_irq = ~((u32) 0); efx_for_each_channel(channel, efx) { - if (!efx_channel_get_tx_queue(channel, 0)) + if (!efx_channel_has_tx_queues(channel)) continue; if (channel->irq_moderation < coalesce->tx_coalesce_usecs_irq) { if (channel->channel < efx->n_rx_channels) @@ -676,8 +676,8 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev, /* If the channel is shared only allow RX parameters to be set */ efx_for_each_channel(channel, efx) { - if (efx_channel_get_rx_queue(channel) && - efx_channel_get_tx_queue(channel, 0) && + if (efx_channel_has_rx_queue(channel) && + efx_channel_has_tx_queues(channel) && tx_usecs) { netif_err(efx, drv, efx->net_dev, "Channel is shared. " "Only RX coalescing may be set\n"); diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index c65270241d2d..77b7ce451519 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -938,19 +938,28 @@ efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type) return &efx->channel[efx->tx_channel_offset + index]->tx_queue[type]; } +static inline bool efx_channel_has_tx_queues(struct efx_channel *channel) +{ + return channel->channel - channel->efx->tx_channel_offset < + channel->efx->n_tx_channels; +} + static inline struct efx_tx_queue * efx_channel_get_tx_queue(struct efx_channel *channel, unsigned type) { - struct efx_tx_queue *tx_queue = channel->tx_queue; - EFX_BUG_ON_PARANOID(type >= EFX_TXQ_TYPES); - return tx_queue->channel ? tx_queue + type : NULL; + EFX_BUG_ON_PARANOID(!efx_channel_has_tx_queues(channel) || + type >= EFX_TXQ_TYPES); + return &channel->tx_queue[type]; } /* Iterate over all TX queues belonging to a channel */ #define efx_for_each_channel_tx_queue(_tx_queue, _channel) \ - for (_tx_queue = efx_channel_get_tx_queue(channel, 0); \ - _tx_queue && _tx_queue < (_channel)->tx_queue + EFX_TXQ_TYPES; \ - _tx_queue++) + if (!efx_channel_has_tx_queues(_channel)) \ + ; \ + else \ + for (_tx_queue = (_channel)->tx_queue; \ + _tx_queue < (_channel)->tx_queue + EFX_TXQ_TYPES; \ + _tx_queue++) static inline struct efx_rx_queue * efx_get_rx_queue(struct efx_nic *efx, unsigned index) @@ -959,18 +968,26 @@ efx_get_rx_queue(struct efx_nic *efx, unsigned index) return &efx->channel[index]->rx_queue; } +static inline bool efx_channel_has_rx_queue(struct efx_channel *channel) +{ + return channel->channel < channel->efx->n_rx_channels; +} + static inline struct efx_rx_queue * efx_channel_get_rx_queue(struct efx_channel *channel) { - return channel->channel < channel->efx->n_rx_channels ? - &channel->rx_queue : NULL; + EFX_BUG_ON_PARANOID(!efx_channel_has_rx_queue(channel)); + return &channel->rx_queue; } /* Iterate over all RX queues belonging to a channel */ #define efx_for_each_channel_rx_queue(_rx_queue, _channel) \ - for (_rx_queue = efx_channel_get_rx_queue(channel); \ - _rx_queue; \ - _rx_queue = NULL) + if (!efx_channel_has_rx_queue(_channel)) \ + ; \ + else \ + for (_rx_queue = &(_channel)->rx_queue; \ + _rx_queue; \ + _rx_queue = NULL) static inline struct efx_channel * efx_rx_queue_channel(struct efx_rx_queue *rx_queue) -- cgit v1.2.3 From 94b274bf5fba6c75b922c8a23ad4b5639a168780 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 10 Jan 2011 21:18:20 +0000 Subject: sfc: Add TX queues for high-priority traffic Implement the ndo_setup_tc() operation with 2 traffic classes. Current Solarstorm controllers do not implement TX queue priority, but they do allow queues to be 'paced' with an enforced delay between packets. Paced and unpaced queues are scheduled in round-robin within two separate hardware bins (paced queues with a large delay may be placed into a third bin temporarily, but we won't use that). If there are queues in both bins, the TX scheduler will alternate between them. If we make high-priority queues unpaced and best-effort queues paced, and high-priority queues are mostly empty, a single high-priority queue can then instantly take 50% of the packet rate regardless of how many of the best-effort queues have descriptors outstanding. We do not actually want an enforced delay between packets on best- effort queues, so we set the pace value to a reserved value that actually results in a delay of 0. Signed-off-by: Ben Hutchings --- drivers/net/sfc/efx.c | 8 ++-- drivers/net/sfc/efx.h | 1 + drivers/net/sfc/net_driver.h | 29 ++++++++++++--- drivers/net/sfc/nic.c | 51 +++++++++++++++++++------- drivers/net/sfc/regs.h | 6 +++ drivers/net/sfc/selftest.c | 2 +- drivers/net/sfc/tx.c | 87 +++++++++++++++++++++++++++++++++++++++++--- 7 files changed, 156 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 6189d3066018..d4e04256730b 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -673,7 +673,7 @@ static void efx_fini_channels(struct efx_nic *efx) efx_for_each_channel_rx_queue(rx_queue, channel) efx_fini_rx_queue(rx_queue); - efx_for_each_channel_tx_queue(tx_queue, channel) + efx_for_each_possible_channel_tx_queue(tx_queue, channel) efx_fini_tx_queue(tx_queue); efx_fini_eventq(channel); } @@ -689,7 +689,7 @@ static void efx_remove_channel(struct efx_channel *channel) efx_for_each_channel_rx_queue(rx_queue, channel) efx_remove_rx_queue(rx_queue); - efx_for_each_channel_tx_queue(tx_queue, channel) + efx_for_each_possible_channel_tx_queue(tx_queue, channel) efx_remove_tx_queue(tx_queue); efx_remove_eventq(channel); } @@ -1836,6 +1836,7 @@ static const struct net_device_ops efx_netdev_ops = { #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = efx_netpoll, #endif + .ndo_setup_tc = efx_setup_tc, }; static void efx_update_name(struct efx_nic *efx) @@ -2386,7 +2387,8 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, int i, rc; /* Allocate and initialise a struct net_device and struct efx_nic */ - net_dev = alloc_etherdev_mq(sizeof(*efx), EFX_MAX_CORE_TX_QUEUES); + net_dev = alloc_etherdev_mqs(sizeof(*efx), EFX_MAX_CORE_TX_QUEUES, + EFX_MAX_RX_QUEUES); if (!net_dev) return -ENOMEM; net_dev->features |= (type->offload_features | NETIF_F_SG | diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index 116207045068..0cb198a64a63 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h @@ -37,6 +37,7 @@ efx_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev); extern netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb); extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index); +extern int efx_setup_tc(struct net_device *net_dev, u8 num_tc); /* RX */ extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue); diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 77b7ce451519..96e22ad34970 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -63,10 +63,12 @@ /* Checksum generation is a per-queue option in hardware, so each * queue visible to the networking core is backed by two hardware TX * queues. */ -#define EFX_MAX_CORE_TX_QUEUES EFX_MAX_CHANNELS -#define EFX_TXQ_TYPE_OFFLOAD 1 -#define EFX_TXQ_TYPES 2 -#define EFX_MAX_TX_QUEUES (EFX_TXQ_TYPES * EFX_MAX_CORE_TX_QUEUES) +#define EFX_MAX_TX_TC 2 +#define EFX_MAX_CORE_TX_QUEUES (EFX_MAX_TX_TC * EFX_MAX_CHANNELS) +#define EFX_TXQ_TYPE_OFFLOAD 1 /* flag */ +#define EFX_TXQ_TYPE_HIGHPRI 2 /* flag */ +#define EFX_TXQ_TYPES 4 +#define EFX_MAX_TX_QUEUES (EFX_TXQ_TYPES * EFX_MAX_CHANNELS) /** * struct efx_special_buffer - An Efx special buffer @@ -140,6 +142,7 @@ struct efx_tx_buffer { * @buffer: The software buffer ring * @txd: The hardware descriptor ring * @ptr_mask: The size of the ring minus 1. + * @initialised: Has hardware queue been initialised? * @flushed: Used when handling queue flushing * @read_count: Current read pointer. * This is the number of buffers that have been removed from both rings. @@ -182,6 +185,7 @@ struct efx_tx_queue { struct efx_tx_buffer *buffer; struct efx_special_buffer txd; unsigned int ptr_mask; + bool initialised; enum efx_flush_state flushed; /* Members used mainly on the completion path */ @@ -377,7 +381,7 @@ struct efx_channel { bool rx_pkt_csummed; struct efx_rx_queue rx_queue; - struct efx_tx_queue tx_queue[2]; + struct efx_tx_queue tx_queue[EFX_TXQ_TYPES]; }; enum efx_led_mode { @@ -952,15 +956,28 @@ efx_channel_get_tx_queue(struct efx_channel *channel, unsigned type) return &channel->tx_queue[type]; } +static inline bool efx_tx_queue_used(struct efx_tx_queue *tx_queue) +{ + return !(tx_queue->efx->net_dev->num_tc < 2 && + tx_queue->queue & EFX_TXQ_TYPE_HIGHPRI); +} + /* Iterate over all TX queues belonging to a channel */ #define efx_for_each_channel_tx_queue(_tx_queue, _channel) \ if (!efx_channel_has_tx_queues(_channel)) \ ; \ else \ for (_tx_queue = (_channel)->tx_queue; \ - _tx_queue < (_channel)->tx_queue + EFX_TXQ_TYPES; \ + _tx_queue < (_channel)->tx_queue + EFX_TXQ_TYPES && \ + efx_tx_queue_used(_tx_queue); \ _tx_queue++) +/* Iterate over all possible TX queues belonging to a channel */ +#define efx_for_each_possible_channel_tx_queue(_tx_queue, _channel) \ + for (_tx_queue = (_channel)->tx_queue; \ + _tx_queue < (_channel)->tx_queue + EFX_TXQ_TYPES; \ + _tx_queue++) + static inline struct efx_rx_queue * efx_get_rx_queue(struct efx_nic *efx, unsigned index) { diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index da386599ab68..1d0b8b6f25c4 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -445,8 +445,8 @@ int efx_nic_probe_tx(struct efx_tx_queue *tx_queue) void efx_nic_init_tx(struct efx_tx_queue *tx_queue) { - efx_oword_t tx_desc_ptr; struct efx_nic *efx = tx_queue->efx; + efx_oword_t reg; tx_queue->flushed = FLUSH_NONE; @@ -454,7 +454,7 @@ void efx_nic_init_tx(struct efx_tx_queue *tx_queue) efx_init_special_buffer(efx, &tx_queue->txd); /* Push TX descriptor ring to card */ - EFX_POPULATE_OWORD_10(tx_desc_ptr, + EFX_POPULATE_OWORD_10(reg, FRF_AZ_TX_DESCQ_EN, 1, FRF_AZ_TX_ISCSI_DDIG_EN, 0, FRF_AZ_TX_ISCSI_HDIG_EN, 0, @@ -470,17 +470,15 @@ void efx_nic_init_tx(struct efx_tx_queue *tx_queue) if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { int csum = tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD; - EFX_SET_OWORD_FIELD(tx_desc_ptr, FRF_BZ_TX_IP_CHKSM_DIS, !csum); - EFX_SET_OWORD_FIELD(tx_desc_ptr, FRF_BZ_TX_TCP_CHKSM_DIS, + EFX_SET_OWORD_FIELD(reg, FRF_BZ_TX_IP_CHKSM_DIS, !csum); + EFX_SET_OWORD_FIELD(reg, FRF_BZ_TX_TCP_CHKSM_DIS, !csum); } - efx_writeo_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base, + efx_writeo_table(efx, ®, efx->type->txd_ptr_tbl_base, tx_queue->queue); if (efx_nic_rev(efx) < EFX_REV_FALCON_B0) { - efx_oword_t reg; - /* Only 128 bits in this register */ BUILD_BUG_ON(EFX_MAX_TX_QUEUES > 128); @@ -491,6 +489,16 @@ void efx_nic_init_tx(struct efx_tx_queue *tx_queue) set_bit_le(tx_queue->queue, (void *)®); efx_writeo(efx, ®, FR_AA_TX_CHKSM_CFG); } + + if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { + EFX_POPULATE_OWORD_1(reg, + FRF_BZ_TX_PACE, + (tx_queue->queue & EFX_TXQ_TYPE_HIGHPRI) ? + FFE_BZ_TX_PACE_OFF : + FFE_BZ_TX_PACE_RESERVED); + efx_writeo_table(efx, ®, FR_BZ_TX_PACE_TBL, + tx_queue->queue); + } } static void efx_flush_tx_queue(struct efx_tx_queue *tx_queue) @@ -1238,8 +1246,10 @@ int efx_nic_flush_queues(struct efx_nic *efx) /* Flush all tx queues in parallel */ efx_for_each_channel(channel, efx) { - efx_for_each_channel_tx_queue(tx_queue, channel) - efx_flush_tx_queue(tx_queue); + efx_for_each_possible_channel_tx_queue(tx_queue, channel) { + if (tx_queue->initialised) + efx_flush_tx_queue(tx_queue); + } } /* The hardware supports four concurrent rx flushes, each of which may @@ -1262,8 +1272,9 @@ int efx_nic_flush_queues(struct efx_nic *efx) ++rx_pending; } } - efx_for_each_channel_tx_queue(tx_queue, channel) { - if (tx_queue->flushed != FLUSH_DONE) + efx_for_each_possible_channel_tx_queue(tx_queue, channel) { + if (tx_queue->initialised && + tx_queue->flushed != FLUSH_DONE) ++tx_pending; } } @@ -1278,8 +1289,9 @@ int efx_nic_flush_queues(struct efx_nic *efx) /* Mark the queues as all flushed. We're going to return failure * leading to a reset, or fake up success anyway */ efx_for_each_channel(channel, efx) { - efx_for_each_channel_tx_queue(tx_queue, channel) { - if (tx_queue->flushed != FLUSH_DONE) + efx_for_each_possible_channel_tx_queue(tx_queue, channel) { + if (tx_queue->initialised && + tx_queue->flushed != FLUSH_DONE) netif_err(efx, hw, efx->net_dev, "tx queue %d flush command timed out\n", tx_queue->queue); @@ -1682,6 +1694,19 @@ void efx_nic_init_common(struct efx_nic *efx) if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); efx_writeo(efx, &temp, FR_AZ_TX_RESERVED); + + if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { + EFX_POPULATE_OWORD_4(temp, + /* Default values */ + FRF_BZ_TX_PACE_SB_NOT_AF, 0x15, + FRF_BZ_TX_PACE_SB_AF, 0xb, + FRF_BZ_TX_PACE_FB_BASE, 0, + /* Allow large pace values in the + * fast bin. */ + FRF_BZ_TX_PACE_BIN_TH, + FFE_BZ_TX_PACE_RESERVED); + efx_writeo(efx, &temp, FR_BZ_TX_PACE); + } } /* Register dump */ diff --git a/drivers/net/sfc/regs.h b/drivers/net/sfc/regs.h index 96430ed81c36..8227de62014f 100644 --- a/drivers/net/sfc/regs.h +++ b/drivers/net/sfc/regs.h @@ -2907,6 +2907,12 @@ #define FRF_CZ_TMFT_SRC_MAC_HI_LBN 44 #define FRF_CZ_TMFT_SRC_MAC_HI_WIDTH 16 +/* TX_PACE_TBL */ +/* Values >20 are documented as reserved, but will result in a queue going + * into the fast bin with a pace value of zero. */ +#define FFE_BZ_TX_PACE_OFF 0 +#define FFE_BZ_TX_PACE_RESERVED 21 + /* DRIVER_EV */ /* Sub-fields of an RX flush completion event */ #define FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL_LBN 12 diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index 0ebfb99f1299..f936892aa423 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c @@ -644,7 +644,7 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests, goto out; } - /* Test both types of TX queue */ + /* Test all enabled types of TX queue */ efx_for_each_channel_tx_queue(tx_queue, channel) { state->offload_csum = (tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD); diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index 7e463fb19fb9..1a51653bb92b 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c @@ -336,22 +336,89 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb, { struct efx_nic *efx = netdev_priv(net_dev); struct efx_tx_queue *tx_queue; + unsigned index, type; if (unlikely(efx->port_inhibited)) return NETDEV_TX_BUSY; - tx_queue = efx_get_tx_queue(efx, skb_get_queue_mapping(skb), - skb->ip_summed == CHECKSUM_PARTIAL ? - EFX_TXQ_TYPE_OFFLOAD : 0); + index = skb_get_queue_mapping(skb); + type = skb->ip_summed == CHECKSUM_PARTIAL ? EFX_TXQ_TYPE_OFFLOAD : 0; + if (index >= efx->n_tx_channels) { + index -= efx->n_tx_channels; + type |= EFX_TXQ_TYPE_HIGHPRI; + } + tx_queue = efx_get_tx_queue(efx, index, type); return efx_enqueue_skb(tx_queue, skb); } void efx_init_tx_queue_core_txq(struct efx_tx_queue *tx_queue) { + struct efx_nic *efx = tx_queue->efx; + /* Must be inverse of queue lookup in efx_hard_start_xmit() */ - tx_queue->core_txq = netdev_get_tx_queue( - tx_queue->efx->net_dev, tx_queue->queue / EFX_TXQ_TYPES); + tx_queue->core_txq = + netdev_get_tx_queue(efx->net_dev, + tx_queue->queue / EFX_TXQ_TYPES + + ((tx_queue->queue & EFX_TXQ_TYPE_HIGHPRI) ? + efx->n_tx_channels : 0)); +} + +int efx_setup_tc(struct net_device *net_dev, u8 num_tc) +{ + struct efx_nic *efx = netdev_priv(net_dev); + struct efx_channel *channel; + struct efx_tx_queue *tx_queue; + unsigned tc; + int rc; + + if (efx_nic_rev(efx) < EFX_REV_FALCON_B0 || num_tc > EFX_MAX_TX_TC) + return -EINVAL; + + if (num_tc == net_dev->num_tc) + return 0; + + for (tc = 0; tc < num_tc; tc++) { + net_dev->tc_to_txq[tc].offset = tc * efx->n_tx_channels; + net_dev->tc_to_txq[tc].count = efx->n_tx_channels; + } + + if (num_tc > net_dev->num_tc) { + /* Initialise high-priority queues as necessary */ + efx_for_each_channel(channel, efx) { + efx_for_each_possible_channel_tx_queue(tx_queue, + channel) { + if (!(tx_queue->queue & EFX_TXQ_TYPE_HIGHPRI)) + continue; + if (!tx_queue->buffer) { + rc = efx_probe_tx_queue(tx_queue); + if (rc) + return rc; + } + if (!tx_queue->initialised) + efx_init_tx_queue(tx_queue); + efx_init_tx_queue_core_txq(tx_queue); + } + } + } else { + /* Reduce number of classes before number of queues */ + net_dev->num_tc = num_tc; + } + + rc = netif_set_real_num_tx_queues(net_dev, + max_t(int, num_tc, 1) * + efx->n_tx_channels); + if (rc) + return rc; + + /* Do not destroy high-priority queues when they become + * unused. We would have to flush them first, and it is + * fairly difficult to flush a subset of TX queues. Leave + * it to efx_fini_channels(). + */ + + net_dev->num_tc = num_tc; + return 0; } void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) @@ -437,6 +504,8 @@ void efx_init_tx_queue(struct efx_tx_queue *tx_queue) /* Set up TX descriptor ring */ efx_nic_init_tx(tx_queue); + + tx_queue->initialised = true; } void efx_release_tx_buffers(struct efx_tx_queue *tx_queue) @@ -459,9 +528,14 @@ void efx_release_tx_buffers(struct efx_tx_queue *tx_queue) void efx_fini_tx_queue(struct efx_tx_queue *tx_queue) { + if (!tx_queue->initialised) + return; + netif_dbg(tx_queue->efx, drv, tx_queue->efx->net_dev, "shutting down TX queue %d\n", tx_queue->queue); + tx_queue->initialised = false; + /* Flush TX queue, remove descriptor ring */ efx_nic_fini_tx(tx_queue); @@ -473,6 +547,9 @@ void efx_fini_tx_queue(struct efx_tx_queue *tx_queue) void efx_remove_tx_queue(struct efx_tx_queue *tx_queue) { + if (!tx_queue->buffer) + return; + netif_dbg(tx_queue->efx, drv, tx_queue->efx->net_dev, "destroying TX queue %d\n", tx_queue->queue); efx_nic_remove_tx(tx_queue); -- cgit v1.2.3 From 6d90e8f45697c633f522269368297d7416fd8783 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 15 Feb 2011 12:18:09 -0800 Subject: isdn: hisax: Use l2headersize() instead of dup (and buggy) func. There was a bug in my commit c978e7bb77dfd2cd3d1f547fa4e395cfe47f02b2 ("hisax: Fix unchecked alloc_skb() return.") One of the l2->flag checks is wrong. Even worse it turns out I'm duplicating an existing function, so use that instead. Reported-by: Milton Miller Signed-off-by: David S. Miller --- drivers/isdn/hisax/isdnl2.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c index 98ac835281fe..cfff0c41d298 100644 --- a/drivers/isdn/hisax/isdnl2.c +++ b/drivers/isdn/hisax/isdnl2.c @@ -1243,13 +1243,6 @@ l2_st7_tout_203(struct FsmInst *fi, int event, void *arg) st->l2.rc = 0; } -static int l2_hdr_space_needed(struct Layer2 *l2) -{ - int len = test_bit(FLG_LAPD, &l2->flag) ? 2 : 1; - - return len + (test_bit(FLG_LAPD, &l2->flag) ? 2 : 1); -} - static void l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) { @@ -1268,7 +1261,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg) if (!skb) return; - hdr_space_needed = l2_hdr_space_needed(l2); + hdr_space_needed = l2headersize(l2, 0); if (hdr_space_needed > skb_headroom(skb)) { struct sk_buff *orig_skb = skb; -- cgit v1.2.3 From 0f3e1d27a7e3f98d996d707d649128e229b65deb Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 3 Feb 2011 00:31:21 +0530 Subject: spi/pxa2xx pci: fix the release - remove race Right now the platform device and its platform data is included in one big struct which requires its custom ->release function. The problem with the release function within the driver is that it might be called after the driver was removed because someone was holding a reference to it and it was not called right after platform_device_unregister(). So we also free the platform device memory to which one might hold a reference. This patch uses the normal pdev functions so this kind of race does not occur. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Grant Likely --- drivers/spi/pxa2xx_spi_pci.c | 61 +++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/pxa2xx_spi_pci.c b/drivers/spi/pxa2xx_spi_pci.c index 351d8a375b57..19752b09e155 100644 --- a/drivers/spi/pxa2xx_spi_pci.c +++ b/drivers/spi/pxa2xx_spi_pci.c @@ -7,10 +7,9 @@ #include #include -struct awesome_struct { +struct ce4100_info { struct ssp_device ssp; - struct platform_device spi_pdev; - struct pxa2xx_spi_master spi_pdata; + struct platform_device *spi_pdev; }; static DEFINE_MUTEX(ssp_lock); @@ -51,23 +50,15 @@ void pxa_ssp_free(struct ssp_device *ssp) } EXPORT_SYMBOL_GPL(pxa_ssp_free); -static void plat_dev_release(struct device *dev) -{ - struct awesome_struct *as = container_of(dev, - struct awesome_struct, spi_pdev.dev); - - of_device_node_put(&as->spi_pdev.dev); -} - static int __devinit ce4100_spi_probe(struct pci_dev *dev, const struct pci_device_id *ent) { int ret; resource_size_t phys_beg; resource_size_t phys_len; - struct awesome_struct *spi_info; + struct ce4100_info *spi_info; struct platform_device *pdev; - struct pxa2xx_spi_master *spi_pdata; + struct pxa2xx_spi_master spi_pdata; struct ssp_device *ssp; ret = pci_enable_device(dev); @@ -84,33 +75,30 @@ static int __devinit ce4100_spi_probe(struct pci_dev *dev, return ret; } + pdev = platform_device_alloc("pxa2xx-spi", dev->devfn); spi_info = kzalloc(sizeof(*spi_info), GFP_KERNEL); - if (!spi_info) { + if (!pdev || !spi_info ) { ret = -ENOMEM; - goto err_kz; + goto err_nomem; } - ssp = &spi_info->ssp; - pdev = &spi_info->spi_pdev; - spi_pdata = &spi_info->spi_pdata; + memset(&spi_pdata, 0, sizeof(spi_pdata)); + spi_pdata.num_chipselect = dev->devfn; - pdev->name = "pxa2xx-spi"; - pdev->id = dev->devfn; - pdev->dev.parent = &dev->dev; - pdev->dev.platform_data = &spi_info->spi_pdata; + ret = platform_device_add_data(pdev, &spi_pdata, sizeof(spi_pdata)); + if (ret) + goto err_nomem; + pdev->dev.parent = &dev->dev; #ifdef CONFIG_OF pdev->dev.of_node = dev->dev.of_node; #endif - pdev->dev.release = plat_dev_release; - - spi_pdata->num_chipselect = dev->devfn; - + ssp = &spi_info->ssp; ssp->phys_base = pci_resource_start(dev, 0); ssp->mmio_base = ioremap(phys_beg, phys_len); if (!ssp->mmio_base) { dev_err(&pdev->dev, "failed to ioremap() registers\n"); ret = -EIO; - goto err_remap; + goto err_nomem; } ssp->irq = dev->irq; ssp->port_id = pdev->id; @@ -122,7 +110,7 @@ static int __devinit ce4100_spi_probe(struct pci_dev *dev, pci_set_drvdata(dev, spi_info); - ret = platform_device_register(pdev); + ret = platform_device_add(pdev); if (ret) goto err_dev_add; @@ -135,27 +123,21 @@ err_dev_add: mutex_unlock(&ssp_lock); iounmap(ssp->mmio_base); -err_remap: - kfree(spi_info); - -err_kz: +err_nomem: release_mem_region(phys_beg, phys_len); - + platform_device_put(pdev); + kfree(spi_info); return ret; } static void __devexit ce4100_spi_remove(struct pci_dev *dev) { - struct awesome_struct *spi_info; - struct platform_device *pdev; + struct ce4100_info *spi_info; struct ssp_device *ssp; spi_info = pci_get_drvdata(dev); - ssp = &spi_info->ssp; - pdev = &spi_info->spi_pdev; - - platform_device_unregister(pdev); + platform_device_unregister(spi_info->spi_pdev); iounmap(ssp->mmio_base); release_mem_region(pci_resource_start(dev, 0), @@ -171,7 +153,6 @@ static void __devexit ce4100_spi_remove(struct pci_dev *dev) } static struct pci_device_id ce4100_spi_devices[] __devinitdata = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e6a) }, { }, }; -- cgit v1.2.3 From bc0c36d3c831b5f33ca0dab39535f5deb8c55b62 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 8 Feb 2011 21:32:36 +1000 Subject: m68knommu: fix dereference of port.tty The struct_tty associated with a port is now a direct pointer from within the local private driver info struct. So fix all uses of it. Signed-off-by: Greg Ungerer --- drivers/tty/serial/68328serial.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index be0ebce36e54..de0160e3f8c4 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c @@ -262,7 +262,7 @@ static void status_handle(struct m68k_serial *info, unsigned short status) static void receive_chars(struct m68k_serial *info, unsigned short rx) { - struct tty_struct *tty = info->port.tty; + struct tty_struct *tty = info->tty; m68328_uart *uart = &uart_addr[info->line]; unsigned char ch, flag; @@ -329,7 +329,7 @@ static void transmit_chars(struct m68k_serial *info) goto clear_and_return; } - if((info->xmit_cnt <= 0) || info->port.tty->stopped) { + if((info->xmit_cnt <= 0) || info->tty->stopped) { /* That's peculiar... TX ints off */ uart->ustcnt &= ~USTCNT_TX_INTR_MASK; goto clear_and_return; @@ -383,7 +383,7 @@ static void do_softint(struct work_struct *work) struct m68k_serial *info = container_of(work, struct m68k_serial, tqueue); struct tty_struct *tty; - tty = info->port.tty; + tty = info->tty; if (!tty) return; #if 0 @@ -407,7 +407,7 @@ static void do_serial_hangup(struct work_struct *work) struct m68k_serial *info = container_of(work, struct m68k_serial, tqueue_hangup); struct tty_struct *tty; - tty = info->port.tty; + tty = info->tty; if (!tty) return; @@ -451,8 +451,8 @@ static int startup(struct m68k_serial * info) uart->ustcnt = USTCNT_UEN | USTCNT_RXEN | USTCNT_RX_INTR_MASK; #endif - if (info->port.tty) - clear_bit(TTY_IO_ERROR, &info->port.tty->flags); + if (info->tty) + clear_bit(TTY_IO_ERROR, &info->tty->flags); info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; /* @@ -486,8 +486,8 @@ static void shutdown(struct m68k_serial * info) info->xmit_buf = 0; } - if (info->port.tty) - set_bit(TTY_IO_ERROR, &info->port.tty->flags); + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); info->flags &= ~S_INITIALIZED; local_irq_restore(flags); @@ -553,9 +553,9 @@ static void change_speed(struct m68k_serial *info) unsigned cflag; int i; - if (!info->port.tty || !info->port.tty->termios) + if (!info->tty || !info->tty->termios) return; - cflag = info->port.tty->termios->c_cflag; + cflag = info->tty->termios->c_cflag; if (!(port = info->port)) return; @@ -970,7 +970,6 @@ static void send_break(struct m68k_serial * info, unsigned int duration) static int rs_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) { - int error; struct m68k_serial * info = (struct m68k_serial *)tty->driver_data; int retval; @@ -1104,7 +1103,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) tty_ldisc_flush(tty); tty->closing = 0; info->event = 0; - info->port.tty = NULL; + info->tty = NULL; #warning "This is not and has never been valid so fix it" #if 0 if (tty->ldisc.num != ldiscs[N_TTY].num) { @@ -1142,7 +1141,7 @@ void rs_hangup(struct tty_struct *tty) info->event = 0; info->count = 0; info->flags &= ~S_NORMAL_ACTIVE; - info->port.tty = NULL; + info->tty = NULL; wake_up_interruptible(&info->open_wait); } @@ -1261,7 +1260,7 @@ int rs_open(struct tty_struct *tty, struct file * filp) info->count++; tty->driver_data = info; - info->port.tty = tty; + info->tty = tty; /* * Start up serial port @@ -1338,7 +1337,7 @@ rs68328_init(void) info = &m68k_soft[i]; info->magic = SERIAL_MAGIC; info->port = (int) &uart_addr[i]; - info->port.tty = NULL; + info->tty = NULL; info->irq = uart_irqs[i]; info->custom_divisor = 16; info->close_delay = 50; -- cgit v1.2.3 From c652759b6a27be04ef5d747d81e8c36cde7f55d1 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 16 Feb 2011 13:05:54 +1100 Subject: hwrng: omap - Convert release_resource to release_region/release_mem_region Request_region should be used with release_region, not release_resource. The local variable mem, storing the result of request_mem_region, is dropped and instead the pointer res is stored in the drvdata field of the platform device. This information is retrieved in omap_rng_remove to release the region. The drvdata field is not used elsewhere. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression x,E; @@ ( *x = request_region(...) | *x = request_mem_region(...) ) ... when != release_region(x) when != x = E * release_resource(x); // Signed-off-by: Julia Lawall Signed-off-by: Herbert Xu --- drivers/char/hw_random/omap-rng.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c index 06aad0831c73..2cc755a64302 100644 --- a/drivers/char/hw_random/omap-rng.c +++ b/drivers/char/hw_random/omap-rng.c @@ -91,7 +91,7 @@ static struct hwrng omap_rng_ops = { static int __devinit omap_rng_probe(struct platform_device *pdev) { - struct resource *res, *mem; + struct resource *res; int ret; /* @@ -116,14 +116,12 @@ static int __devinit omap_rng_probe(struct platform_device *pdev) if (!res) return -ENOENT; - mem = request_mem_region(res->start, resource_size(res), - pdev->name); - if (mem == NULL) { + if (!request_mem_region(res->start, resource_size(res), pdev->name)) { ret = -EBUSY; goto err_region; } - dev_set_drvdata(&pdev->dev, mem); + dev_set_drvdata(&pdev->dev, res); rng_base = ioremap(res->start, resource_size(res)); if (!rng_base) { ret = -ENOMEM; @@ -146,7 +144,7 @@ err_register: iounmap(rng_base); rng_base = NULL; err_ioremap: - release_resource(mem); + release_mem_region(res->start, resource_size(res)); err_region: if (cpu_is_omap24xx()) { clk_disable(rng_ick); @@ -157,7 +155,7 @@ err_region: static int __exit omap_rng_remove(struct platform_device *pdev) { - struct resource *mem = dev_get_drvdata(&pdev->dev); + struct resource *res = dev_get_drvdata(&pdev->dev); hwrng_unregister(&omap_rng_ops); @@ -170,7 +168,7 @@ static int __exit omap_rng_remove(struct platform_device *pdev) clk_put(rng_ick); } - release_resource(mem); + release_mem_region(res->start, resource_size(res)); rng_base = NULL; return 0; -- cgit v1.2.3 From cbe6ef1d2622e08e272600b3cb6040bed60f0450 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 16 Feb 2011 13:58:38 +1100 Subject: md: don't set_capacity before array is active. If the desired size of an array is set (via sysfs) before the array is active (which is the normal sequence), we currrently call set_capacity immediately. This means that a subsequent 'open' (as can be caused by some udev-triggers program) will notice the new size and try to probe for partitions. However as the array isn't quite ready yet the read will fail. Then when the array is read, as the size doesn't change again we don't try to re-probe. So when setting array size via sysfs, only call set_capacity if the array is already active. Signed-off-by: NeilBrown --- drivers/md/md.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 0cc30ecda4c1..6818ff4aa8d6 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4138,10 +4138,10 @@ array_size_store(mddev_t *mddev, const char *buf, size_t len) } mddev->array_sectors = sectors; - set_capacity(mddev->gendisk, mddev->array_sectors); - if (mddev->pers) + if (mddev->pers) { + set_capacity(mddev->gendisk, mddev->array_sectors); revalidate_disk(mddev->gendisk); - + } return len; } -- cgit v1.2.3 From 8f5f02c460b7ca74ce55ce126ce0c1e58a3f923d Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 16 Feb 2011 13:58:51 +1100 Subject: md: correctly handle probe of an 'mdp' device. 'mdp' devices are md devices with preallocated device numbers for partitions. As such it is possible to mknod and open a partition before opening the whole device. this causes md_probe() to be called with a device number of a partition, which in-turn calls mddev_find with such a number. However mddev_find expects the number of a 'whole device' and does the wrong thing with partition numbers. So add code to mddev_find to remove the 'partition' part of a device number and just work with the 'whole device'. This patch addresses https://bugzilla.kernel.org/show_bug.cgi?id=28652 Reported-by: hkmaly@bigfoot.com Signed-off-by: NeilBrown Cc: --- drivers/md/md.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 6818ff4aa8d6..330addfe9b77 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -553,6 +553,9 @@ static mddev_t * mddev_find(dev_t unit) { mddev_t *mddev, *new = NULL; + if (unit && MAJOR(unit) != MD_MAJOR) + unit &= ~((1< Date: Mon, 14 Feb 2011 10:06:42 +0800 Subject: altera_ps2: Add devicetree support Add match table for device tree binding. v2: use const and add compat version. v3: change compatible vendor to ALTR. add dts binding doc. v4: condition module device table export for of. Signed-off-by: Walter Goossens Signed-off-by: Thomas Chou Acked-by: Dmitry Torokhov [dustan.bower@gmail.com: fixed missing semicolon] Signed-off-by: Grant Likely --- Documentation/devicetree/bindings/serio/altera_ps2.txt | 4 ++++ drivers/input/serio/altera_ps2.c | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/serio/altera_ps2.txt (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/serio/altera_ps2.txt b/Documentation/devicetree/bindings/serio/altera_ps2.txt new file mode 100644 index 000000000000..4d9eecc2ef7d --- /dev/null +++ b/Documentation/devicetree/bindings/serio/altera_ps2.txt @@ -0,0 +1,4 @@ +Altera UP PS/2 controller + +Required properties: +- compatible : should be "ALTR,ps2-1.0". diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c index 7998560a1904..d363dc4571a3 100644 --- a/drivers/input/serio/altera_ps2.c +++ b/drivers/input/serio/altera_ps2.c @@ -19,6 +19,7 @@ #include #include #include +#include #define DRV_NAME "altera_ps2" @@ -173,6 +174,16 @@ static int __devexit altera_ps2_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_OF +static const struct of_device_id altera_ps2_match[] = { + { .compatible = "ALTR,ps2-1.0", }, + {}, +}; +MODULE_DEVICE_TABLE(of, altera_ps2_match); +#else /* CONFIG_OF */ +#define altera_ps2_match NULL +#endif /* CONFIG_OF */ + /* * Our device driver structure */ @@ -182,6 +193,7 @@ static struct platform_driver altera_ps2_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, + .of_match_table = altera_ps2_match, }, }; @@ -189,13 +201,12 @@ static int __init altera_ps2_init(void) { return platform_driver_register(&altera_ps2_driver); } +module_init(altera_ps2_init); static void __exit altera_ps2_exit(void) { platform_driver_unregister(&altera_ps2_driver); } - -module_init(altera_ps2_init); module_exit(altera_ps2_exit); MODULE_DESCRIPTION("Altera University Program PS2 controller driver"); -- cgit v1.2.3 From 940fed2e79a15cf0d006c860d7811adbe5c19882 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 16 Feb 2011 12:13:06 +0100 Subject: x86-64, NUMA: Unify {acpi|amd}_{numa_init|scan_nodes}() arguments and return values The functions used during NUMA initialization - *_numa_init() and *_scan_nodes() - have different arguments and return values. Unify them such that they all take no argument and return 0 on success and -errno on failure. This is in preparation for further NUMA init cleanups. Signed-off-by: Tejun Heo Cc: Yinghai Lu Cc: Brian Gerst Cc: Cyrill Gorcunov Cc: Shaohui Zheng Cc: David Rientjes Cc: Ingo Molnar Cc: H. Peter Anvin --- arch/x86/include/asm/acpi.h | 2 +- arch/x86/include/asm/amd_nb.h | 2 +- arch/x86/kernel/setup.c | 4 ++-- arch/x86/mm/amdtopology_64.c | 18 +++++++++--------- arch/x86/mm/numa_64.c | 2 +- arch/x86/mm/srat_64.c | 4 ++-- drivers/acpi/numa.c | 9 ++++++--- 7 files changed, 22 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 211ca3f7fd16..4e5dff9e0b39 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -187,7 +187,7 @@ struct bootnode; extern int acpi_numa; extern void acpi_get_nodes(struct bootnode *physnodes, unsigned long start, unsigned long end); -extern int acpi_scan_nodes(unsigned long start, unsigned long end); +extern int acpi_scan_nodes(void); #define NR_NODE_MEMBLKS (MAX_NUMNODES*2) #ifdef CONFIG_NUMA_EMU diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h index 2b33c4df979f..dc3c6e34da1d 100644 --- a/arch/x86/include/asm/amd_nb.h +++ b/arch/x86/include/asm/amd_nb.h @@ -16,7 +16,7 @@ struct bootnode; extern int early_is_amd_nb(u32 value); extern int amd_cache_northbridges(void); extern void amd_flush_garts(void); -extern int amd_numa_init(unsigned long start_pfn, unsigned long end_pfn); +extern int amd_numa_init(void); extern int amd_scan_nodes(void); extern int amd_get_subcaches(int); extern int amd_set_subcaches(int, int); diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 756d640723f9..96810a3c6003 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -995,12 +995,12 @@ void __init setup_arch(char **cmdline_p) /* * Parse SRAT to discover nodes. */ - acpi = acpi_numa_init(); + acpi = !acpi_numa_init(); #endif #ifdef CONFIG_AMD_NUMA if (!acpi) - amd = !amd_numa_init(0, max_pfn); + amd = !amd_numa_init(); #endif initmem_init(acpi, amd); diff --git a/arch/x86/mm/amdtopology_64.c b/arch/x86/mm/amdtopology_64.c index 2523c3554de5..655ccffc6ee5 100644 --- a/arch/x86/mm/amdtopology_64.c +++ b/arch/x86/mm/amdtopology_64.c @@ -51,7 +51,7 @@ static __init int find_northbridge(void) return num; } - return -1; + return -ENOENT; } static __init void early_get_boot_cpu_id(void) @@ -69,17 +69,17 @@ static __init void early_get_boot_cpu_id(void) #endif } -int __init amd_numa_init(unsigned long start_pfn, unsigned long end_pfn) +int __init amd_numa_init(void) { - unsigned long start = PFN_PHYS(start_pfn); - unsigned long end = PFN_PHYS(end_pfn); + unsigned long start = PFN_PHYS(0); + unsigned long end = PFN_PHYS(max_pfn); unsigned numnodes; unsigned long prevbase; int i, nb, found = 0; u32 nodeid, reg; if (!early_pci_allowed()) - return -1; + return -EINVAL; nb = find_northbridge(); if (nb < 0) @@ -90,7 +90,7 @@ int __init amd_numa_init(unsigned long start_pfn, unsigned long end_pfn) reg = read_pci_config(0, nb, 0, 0x60); numnodes = ((reg >> 4) & 0xF) + 1; if (numnodes <= 1) - return -1; + return -ENOENT; pr_info("Number of physical nodes %d\n", numnodes); @@ -121,7 +121,7 @@ int __init amd_numa_init(unsigned long start_pfn, unsigned long end_pfn) if ((base >> 8) & 3 || (limit >> 8) & 3) { pr_err("Node %d using interleaving mode %lx/%lx\n", nodeid, (base >> 8) & 3, (limit >> 8) & 3); - return -1; + return -EINVAL; } if (node_isset(nodeid, nodes_parsed)) { pr_info("Node %d already present, skipping\n", @@ -160,7 +160,7 @@ int __init amd_numa_init(unsigned long start_pfn, unsigned long end_pfn) if (prevbase > base) { pr_err("Node map not sorted %lx,%lx\n", prevbase, base); - return -1; + return -EINVAL; } pr_info("Node %d MemBase %016lx Limit %016lx\n", @@ -177,7 +177,7 @@ int __init amd_numa_init(unsigned long start_pfn, unsigned long end_pfn) } if (!found) - return -1; + return -ENOENT; return 0; } diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c index d7e4aafd0759..a083f515f004 100644 --- a/arch/x86/mm/numa_64.c +++ b/arch/x86/mm/numa_64.c @@ -596,7 +596,7 @@ void __init initmem_init(int acpi, int amd) #endif #ifdef CONFIG_ACPI_NUMA - if (!numa_off && acpi && !acpi_scan_nodes(0, max_pfn << PAGE_SHIFT)) + if (!numa_off && acpi && !acpi_scan_nodes()) return; nodes_clear(node_possible_map); nodes_clear(node_online_map); diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index 988b0b70ff39..4f9dbf066ca4 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c @@ -359,7 +359,7 @@ void __init acpi_get_nodes(struct bootnode *physnodes, unsigned long start, #endif /* CONFIG_NUMA_EMU */ /* Use the information discovered above to actually set up the nodes. */ -int __init acpi_scan_nodes(unsigned long start, unsigned long end) +int __init acpi_scan_nodes(void) { int i; @@ -368,7 +368,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) /* First clean up the node list */ for (i = 0; i < MAX_NUMNODES; i++) - cutoff_node(i, start, end); + cutoff_node(i, 0, max_pfn << PAGE_SHIFT); /* * Join together blocks on the same node, holes between diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 5eb25eb3ea48..3b5c3189fd99 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c @@ -274,7 +274,7 @@ acpi_table_parse_srat(enum acpi_srat_type id, int __init acpi_numa_init(void) { - int ret = 0; + int cnt = 0; /* * Should not limit number with cpu num that is from NR_CPUS or nr_cpus= @@ -288,7 +288,7 @@ int __init acpi_numa_init(void) acpi_parse_x2apic_affinity, 0); acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY, acpi_parse_processor_affinity, 0); - ret = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, + cnt = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, acpi_parse_memory_affinity, NR_NODE_MEMBLKS); } @@ -297,7 +297,10 @@ int __init acpi_numa_init(void) acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit); acpi_numa_arch_fixup(); - return ret; + + if (cnt <= 0) + return cnt ?: -ENOENT; + return 0; } int acpi_get_pxm(acpi_handle h) -- cgit v1.2.3 From e866729605a43a739fc56023a8530b07a93d3458 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 16 Feb 2011 08:01:49 -0500 Subject: hwmon: (jc42) fix type mismatch In set_temp_crit_hyst(), make the variable 'val' have the correct type for strict_strtoul(). Signed-off-by: Clemens Ladisch Cc: stable@kernel.org Signed-off-by: Guenter Roeck --- drivers/hwmon/jc42.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index 340fc78c8dde..5efe2399e8f8 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -332,7 +332,7 @@ static ssize_t set_temp_crit_hyst(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); struct jc42_data *data = i2c_get_clientdata(client); - long val; + unsigned long val; int diff, hyst; int err; int ret = count; -- cgit v1.2.3 From d5622f5b6c4671d1588ccc9056705366d4eb312a Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 16 Feb 2011 08:02:08 -0500 Subject: hwmon: (jc42) more helpful documentation The documentation lists standard numbers and chip names in excruciating detail, but that's all it does. To help mere mortals in deciding whether to enable this driver, mention what this sensor is for and in which systems it might be found. Also add a link to the actual JC 42.4 specification. Signed-off-by: Clemens Ladisch Cc: stable@kernel.org Signed-off-by: Guenter Roeck --- Documentation/hwmon/jc42 | 9 +++++++-- drivers/hwmon/Kconfig | 11 ++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/Documentation/hwmon/jc42 b/Documentation/hwmon/jc42 index 0e76ef12e4c6..2a0924003f92 100644 --- a/Documentation/hwmon/jc42 +++ b/Documentation/hwmon/jc42 @@ -51,7 +51,8 @@ Supported chips: * JEDEC JC 42.4 compliant temperature sensor chips Prefix: 'jc42' Addresses scanned: I2C 0x18 - 0x1f - Datasheet: - + Datasheet: + http://www.jedec.org/sites/default/files/docs/4_01_04R19.pdf Author: Guenter Roeck @@ -60,7 +61,11 @@ Author: Description ----------- -This driver implements support for JEDEC JC 42.4 compliant temperature sensors. +This driver implements support for JEDEC JC 42.4 compliant temperature sensors, +which are used on many DDR3 memory modules for mobile devices and servers. Some +systems use the sensor to prevent memory overheating by automatically throttling +the memory controller. + The driver auto-detects the chips listed above, but can be manually instantiated to support other JC 42.4 compliant chips. diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 773e484f1646..412339451a32 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -455,13 +455,14 @@ config SENSORS_JZ4740 called jz4740-hwmon. config SENSORS_JC42 - tristate "JEDEC JC42.4 compliant temperature sensors" + tristate "JEDEC JC42.4 compliant memory module temperature sensors" depends on I2C help - If you say yes here you get support for Jedec JC42.4 compliant - temperature sensors. Support will include, but not be limited to, - ADT7408, CAT34TS02,, CAT6095, MAX6604, MCP9805, MCP98242, MCP98243, - MCP9843, SE97, SE98, STTS424, TSE2002B3, and TS3000B3. + If you say yes here, you get support for JEDEC JC42.4 compliant + temperature sensors, which are used on many DDR3 memory modules for + mobile devices and servers. Support will include, but not be limited + to, ADT7408, CAT34TS02, CAT6095, MAX6604, MCP9805, MCP98242, MCP98243, + MCP9843, SE97, SE98, STTS424(E), TSE2002B3, and TS3000B3. This driver can also be built as a module. If so, the module will be called jc42. -- cgit v1.2.3 From 2c6315da6a1657a49e03970a4084dc3d1958ad70 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 16 Feb 2011 08:02:38 -0500 Subject: hwmon: (jc42) do not allow writing to locked registers On systems where the temperature sensor is actually used, the BIOS is likely to have locked the alarm registers. In that case, all writes through the corresponding sysfs files would be silently ignored. To prevent this, detect the locks and make the affected sysfs files read-only. Signed-off-by: Clemens Ladisch Cc: stable@kernel.org Signed-off-by: Guenter Roeck --- Documentation/hwmon/jc42 | 12 ++++++++---- drivers/hwmon/jc42.c | 33 +++++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/Documentation/hwmon/jc42 b/Documentation/hwmon/jc42 index 2a0924003f92..a22ecf48f255 100644 --- a/Documentation/hwmon/jc42 +++ b/Documentation/hwmon/jc42 @@ -86,15 +86,19 @@ limits. The chip supports only a single register to configure the hysteresis, which applies to all limits. This register can be written by writing into temp1_crit_hyst. Other hysteresis attributes are read-only. +If the BIOS has configured the sensor for automatic temperature management, it +is likely that it has locked the registers, i.e., that the temperature limits +cannot be changed. + Sysfs entries ------------- temp1_input Temperature (RO) -temp1_min Minimum temperature (RW) -temp1_max Maximum temperature (RW) -temp1_crit Critical high temperature (RW) +temp1_min Minimum temperature (RO or RW) +temp1_max Maximum temperature (RO or RW) +temp1_crit Critical high temperature (RO or RW) -temp1_crit_hyst Critical hysteresis temperature (RW) +temp1_crit_hyst Critical hysteresis temperature (RO or RW) temp1_max_hyst Maximum hysteresis temperature (RO) temp1_min_alarm Temperature low alarm diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index 5efe2399e8f8..934991237061 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -53,6 +53,8 @@ static const unsigned short normal_i2c[] = { /* Configuration register defines */ #define JC42_CFG_CRIT_ONLY (1 << 2) +#define JC42_CFG_TCRIT_LOCK (1 << 6) +#define JC42_CFG_EVENT_LOCK (1 << 7) #define JC42_CFG_SHUTDOWN (1 << 8) #define JC42_CFG_HYST_SHIFT 9 #define JC42_CFG_HYST_MASK 0x03 @@ -380,14 +382,14 @@ static ssize_t show_alarm(struct device *dev, static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL); -static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit, set_temp_crit); -static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(temp1_min, S_IRUGO, show_temp_min, set_temp_min); -static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_max, set_temp_max); -static DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, +static DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, set_temp_crit_hyst); static DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_temp_max_hyst, NULL); @@ -412,8 +414,31 @@ static struct attribute *jc42_attributes[] = { NULL }; +static mode_t jc42_attribute_mode(struct kobject *kobj, + struct attribute *attr, int index) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct i2c_client *client = to_i2c_client(dev); + struct jc42_data *data = i2c_get_clientdata(client); + unsigned int config = data->config; + bool readonly; + + if (attr == &dev_attr_temp1_crit.attr) + readonly = config & JC42_CFG_TCRIT_LOCK; + else if (attr == &dev_attr_temp1_min.attr || + attr == &dev_attr_temp1_max.attr) + readonly = config & JC42_CFG_EVENT_LOCK; + else if (attr == &dev_attr_temp1_crit_hyst.attr) + readonly = config & (JC42_CFG_EVENT_LOCK | JC42_CFG_TCRIT_LOCK); + else + readonly = true; + + return S_IRUGO | (readonly ? 0 : S_IWUSR); +} + static const struct attribute_group jc42_group = { .attrs = jc42_attributes, + .is_visible = jc42_attribute_mode, }; /* Return 0 if detection is successful, -ENODEV otherwise */ -- cgit v1.2.3 From 58a69cb47ec6991bf006a3e5d202e8571b0327a4 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 16 Feb 2011 09:25:31 +0100 Subject: workqueue, freezer: unify spelling of 'freeze' + 'able' to 'freezable' There are two spellings in use for 'freeze' + 'able' - 'freezable' and 'freezeable'. The former is the more prominent one. The latter is mostly used by workqueue and in a few other odd places. Unify the spelling to 'freezable'. Signed-off-by: Tejun Heo Reported-by: Alan Stern Acked-by: "Rafael J. Wysocki" Acked-by: Greg Kroah-Hartman Acked-by: Dmitry Torokhov Cc: David Woodhouse Cc: Alex Dubov Cc: "David S. Miller" Cc: Steven Whitehouse --- Documentation/workqueue.txt | 4 ++-- drivers/memstick/core/memstick.c | 2 +- drivers/misc/tifm_core.c | 2 +- drivers/misc/vmw_balloon.c | 2 +- drivers/mtd/nand/r852.c | 2 +- drivers/mtd/sm_ftl.c | 2 +- drivers/net/can/mcp251x.c | 2 +- drivers/tty/serial/max3100.c | 2 +- drivers/tty/serial/max3107.c | 2 +- fs/gfs2/glock.c | 4 ++-- fs/gfs2/main.c | 2 +- include/linux/freezer.h | 2 +- include/linux/sched.h | 2 +- include/linux/workqueue.h | 8 ++++---- kernel/power/main.c | 2 +- kernel/power/process.c | 6 +++--- kernel/workqueue.c | 24 ++++++++++++------------ 17 files changed, 35 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/Documentation/workqueue.txt b/Documentation/workqueue.txt index 996a27d9b8db..01c513fac40e 100644 --- a/Documentation/workqueue.txt +++ b/Documentation/workqueue.txt @@ -190,9 +190,9 @@ resources, scheduled and executed. * Long running CPU intensive workloads which can be better managed by the system scheduler. - WQ_FREEZEABLE + WQ_FREEZABLE - A freezeable wq participates in the freeze phase of the system + A freezable wq participates in the freeze phase of the system suspend operations. Work items on the wq are drained and no new work item starts execution until thawed. diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index e9a3eab7b0cf..8c1d85e27be4 100644 --- a/drivers/memstick/core/memstick.c +++ b/drivers/memstick/core/memstick.c @@ -621,7 +621,7 @@ static int __init memstick_init(void) { int rc; - workqueue = create_freezeable_workqueue("kmemstick"); + workqueue = create_freezable_workqueue("kmemstick"); if (!workqueue) return -ENOMEM; diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c index 5f6852dff40b..44d4475a09dd 100644 --- a/drivers/misc/tifm_core.c +++ b/drivers/misc/tifm_core.c @@ -329,7 +329,7 @@ static int __init tifm_init(void) { int rc; - workqueue = create_freezeable_workqueue("tifm"); + workqueue = create_freezable_workqueue("tifm"); if (!workqueue) return -ENOMEM; diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c index 4d2ea8e80140..6df5a55da110 100644 --- a/drivers/misc/vmw_balloon.c +++ b/drivers/misc/vmw_balloon.c @@ -785,7 +785,7 @@ static int __init vmballoon_init(void) if (x86_hyper != &x86_hyper_vmware) return -ENODEV; - vmballoon_wq = create_freezeable_workqueue("vmmemctl"); + vmballoon_wq = create_freezable_workqueue("vmmemctl"); if (!vmballoon_wq) { pr_err("failed to create workqueue\n"); return -ENOMEM; diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c index d9d7efbc77cc..6322d1fb5d62 100644 --- a/drivers/mtd/nand/r852.c +++ b/drivers/mtd/nand/r852.c @@ -930,7 +930,7 @@ int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) init_completion(&dev->dma_done); - dev->card_workqueue = create_freezeable_workqueue(DRV_NAME); + dev->card_workqueue = create_freezable_workqueue(DRV_NAME); if (!dev->card_workqueue) goto error9; diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c index 67822cf6c025..ac0d6a8613b5 100644 --- a/drivers/mtd/sm_ftl.c +++ b/drivers/mtd/sm_ftl.c @@ -1258,7 +1258,7 @@ static struct mtd_blktrans_ops sm_ftl_ops = { static __init int sm_module_init(void) { int error = 0; - cache_flush_workqueue = create_freezeable_workqueue("smflush"); + cache_flush_workqueue = create_freezable_workqueue("smflush"); if (IS_ERR(cache_flush_workqueue)) return PTR_ERR(cache_flush_workqueue); diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 7ab534aee452..7513c4523ac4 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -940,7 +940,7 @@ static int mcp251x_open(struct net_device *net) goto open_unlock; } - priv->wq = create_freezeable_workqueue("mcp251x_wq"); + priv->wq = create_freezable_workqueue("mcp251x_wq"); INIT_WORK(&priv->tx_work, mcp251x_tx_work_handler); INIT_WORK(&priv->restart_work, mcp251x_restart_work_handler); diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c index beb1afa27d8d..7b951adac54b 100644 --- a/drivers/tty/serial/max3100.c +++ b/drivers/tty/serial/max3100.c @@ -601,7 +601,7 @@ static int max3100_startup(struct uart_port *port) s->rts = 0; sprintf(b, "max3100-%d", s->minor); - s->workqueue = create_freezeable_workqueue(b); + s->workqueue = create_freezable_workqueue(b); if (!s->workqueue) { dev_warn(&s->spi->dev, "cannot create workqueue\n"); return -EBUSY; diff --git a/drivers/tty/serial/max3107.c b/drivers/tty/serial/max3107.c index 910870edf708..750b4f627315 100644 --- a/drivers/tty/serial/max3107.c +++ b/drivers/tty/serial/max3107.c @@ -833,7 +833,7 @@ static int max3107_startup(struct uart_port *port) struct max3107_port *s = container_of(port, struct max3107_port, port); /* Initialize work queue */ - s->workqueue = create_freezeable_workqueue("max3107"); + s->workqueue = create_freezable_workqueue("max3107"); if (!s->workqueue) { dev_err(&s->spi->dev, "Workqueue creation failed\n"); return -EBUSY; diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 08a8beb152e6..7cd9a5a68d59 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1779,11 +1779,11 @@ int __init gfs2_glock_init(void) #endif glock_workqueue = alloc_workqueue("glock_workqueue", WQ_MEM_RECLAIM | - WQ_HIGHPRI | WQ_FREEZEABLE, 0); + WQ_HIGHPRI | WQ_FREEZABLE, 0); if (IS_ERR(glock_workqueue)) return PTR_ERR(glock_workqueue); gfs2_delete_workqueue = alloc_workqueue("delete_workqueue", - WQ_MEM_RECLAIM | WQ_FREEZEABLE, + WQ_MEM_RECLAIM | WQ_FREEZABLE, 0); if (IS_ERR(gfs2_delete_workqueue)) { destroy_workqueue(glock_workqueue); diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index ebef7ab6e17e..85ba027d1c4d 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c @@ -144,7 +144,7 @@ static int __init init_gfs2_fs(void) error = -ENOMEM; gfs_recovery_wq = alloc_workqueue("gfs_recovery", - WQ_MEM_RECLAIM | WQ_FREEZEABLE, 0); + WQ_MEM_RECLAIM | WQ_FREEZABLE, 0); if (!gfs_recovery_wq) goto fail_wq; diff --git a/include/linux/freezer.h b/include/linux/freezer.h index da7e52b099f3..1effc8b56b4e 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h @@ -109,7 +109,7 @@ static inline void freezer_count(void) } /* - * Check if the task should be counted as freezeable by the freezer + * Check if the task should be counted as freezable by the freezer */ static inline int freezer_should_skip(struct task_struct *p) { diff --git a/include/linux/sched.h b/include/linux/sched.h index d747f948b34e..777d8a5ed06b 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1744,7 +1744,7 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t * #define PF_MCE_EARLY 0x08000000 /* Early kill for mce process policy */ #define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */ #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */ -#define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezeable */ +#define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezable */ #define PF_FREEZER_NOSIG 0x80000000 /* Freezer won't send signals to it */ /* diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 1ac11586a2f5..f7998a3bf020 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -250,7 +250,7 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; } enum { WQ_NON_REENTRANT = 1 << 0, /* guarantee non-reentrance */ WQ_UNBOUND = 1 << 1, /* not bound to any cpu */ - WQ_FREEZEABLE = 1 << 2, /* freeze during suspend */ + WQ_FREEZABLE = 1 << 2, /* freeze during suspend */ WQ_MEM_RECLAIM = 1 << 3, /* may be used for memory reclaim */ WQ_HIGHPRI = 1 << 4, /* high priority */ WQ_CPU_INTENSIVE = 1 << 5, /* cpu instensive workqueue */ @@ -318,7 +318,7 @@ __alloc_workqueue_key(const char *name, unsigned int flags, int max_active, /** * alloc_ordered_workqueue - allocate an ordered workqueue * @name: name of the workqueue - * @flags: WQ_* flags (only WQ_FREEZEABLE and WQ_MEM_RECLAIM are meaningful) + * @flags: WQ_* flags (only WQ_FREEZABLE and WQ_MEM_RECLAIM are meaningful) * * Allocate an ordered workqueue. An ordered workqueue executes at * most one work item at any given time in the queued order. They are @@ -335,8 +335,8 @@ alloc_ordered_workqueue(const char *name, unsigned int flags) #define create_workqueue(name) \ alloc_workqueue((name), WQ_MEM_RECLAIM, 1) -#define create_freezeable_workqueue(name) \ - alloc_workqueue((name), WQ_FREEZEABLE | WQ_UNBOUND | WQ_MEM_RECLAIM, 1) +#define create_freezable_workqueue(name) \ + alloc_workqueue((name), WQ_FREEZABLE | WQ_UNBOUND | WQ_MEM_RECLAIM, 1) #define create_singlethread_workqueue(name) \ alloc_workqueue((name), WQ_UNBOUND | WQ_MEM_RECLAIM, 1) diff --git a/kernel/power/main.c b/kernel/power/main.c index 7b5db6a8561e..701853042c28 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -326,7 +326,7 @@ EXPORT_SYMBOL_GPL(pm_wq); static int __init pm_start_workqueue(void) { - pm_wq = alloc_workqueue("pm", WQ_FREEZEABLE, 0); + pm_wq = alloc_workqueue("pm", WQ_FREEZABLE, 0); return pm_wq ? 0 : -ENOMEM; } diff --git a/kernel/power/process.c b/kernel/power/process.c index d6d2a10320e0..0cf3a27a6c9d 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c @@ -22,7 +22,7 @@ */ #define TIMEOUT (20 * HZ) -static inline int freezeable(struct task_struct * p) +static inline int freezable(struct task_struct * p) { if ((p == current) || (p->flags & PF_NOFREEZE) || @@ -53,7 +53,7 @@ static int try_to_freeze_tasks(bool sig_only) todo = 0; read_lock(&tasklist_lock); do_each_thread(g, p) { - if (frozen(p) || !freezeable(p)) + if (frozen(p) || !freezable(p)) continue; if (!freeze_task(p, sig_only)) @@ -167,7 +167,7 @@ static void thaw_tasks(bool nosig_only) read_lock(&tasklist_lock); do_each_thread(g, p) { - if (!freezeable(p)) + if (!freezable(p)) continue; if (nosig_only && should_send_signal(p)) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 90a17ca2ad0b..88a3e34f51f6 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -2965,7 +2965,7 @@ struct workqueue_struct *__alloc_workqueue_key(const char *name, */ spin_lock(&workqueue_lock); - if (workqueue_freezing && wq->flags & WQ_FREEZEABLE) + if (workqueue_freezing && wq->flags & WQ_FREEZABLE) for_each_cwq_cpu(cpu, wq) get_cwq(cpu, wq)->max_active = 0; @@ -3077,7 +3077,7 @@ void workqueue_set_max_active(struct workqueue_struct *wq, int max_active) spin_lock_irq(&gcwq->lock); - if (!(wq->flags & WQ_FREEZEABLE) || + if (!(wq->flags & WQ_FREEZABLE) || !(gcwq->flags & GCWQ_FREEZING)) get_cwq(gcwq->cpu, wq)->max_active = max_active; @@ -3327,7 +3327,7 @@ static int __cpuinit trustee_thread(void *__gcwq) * want to get it over with ASAP - spam rescuers, wake up as * many idlers as necessary and create new ones till the * worklist is empty. Note that if the gcwq is frozen, there - * may be frozen works in freezeable cwqs. Don't declare + * may be frozen works in freezable cwqs. Don't declare * completion while frozen. */ while (gcwq->nr_workers != gcwq->nr_idle || @@ -3585,9 +3585,9 @@ EXPORT_SYMBOL_GPL(work_on_cpu); /** * freeze_workqueues_begin - begin freezing workqueues * - * Start freezing workqueues. After this function returns, all - * freezeable workqueues will queue new works to their frozen_works - * list instead of gcwq->worklist. + * Start freezing workqueues. After this function returns, all freezable + * workqueues will queue new works to their frozen_works list instead of + * gcwq->worklist. * * CONTEXT: * Grabs and releases workqueue_lock and gcwq->lock's. @@ -3613,7 +3613,7 @@ void freeze_workqueues_begin(void) list_for_each_entry(wq, &workqueues, list) { struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq); - if (cwq && wq->flags & WQ_FREEZEABLE) + if (cwq && wq->flags & WQ_FREEZABLE) cwq->max_active = 0; } @@ -3624,7 +3624,7 @@ void freeze_workqueues_begin(void) } /** - * freeze_workqueues_busy - are freezeable workqueues still busy? + * freeze_workqueues_busy - are freezable workqueues still busy? * * Check whether freezing is complete. This function must be called * between freeze_workqueues_begin() and thaw_workqueues(). @@ -3633,8 +3633,8 @@ void freeze_workqueues_begin(void) * Grabs and releases workqueue_lock. * * RETURNS: - * %true if some freezeable workqueues are still busy. %false if - * freezing is complete. + * %true if some freezable workqueues are still busy. %false if freezing + * is complete. */ bool freeze_workqueues_busy(void) { @@ -3654,7 +3654,7 @@ bool freeze_workqueues_busy(void) list_for_each_entry(wq, &workqueues, list) { struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq); - if (!cwq || !(wq->flags & WQ_FREEZEABLE)) + if (!cwq || !(wq->flags & WQ_FREEZABLE)) continue; BUG_ON(cwq->nr_active < 0); @@ -3699,7 +3699,7 @@ void thaw_workqueues(void) list_for_each_entry(wq, &workqueues, list) { struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq); - if (!cwq || !(wq->flags & WQ_FREEZEABLE)) + if (!cwq || !(wq->flags & WQ_FREEZABLE)) continue; /* restore max_active and repopulate worklist */ -- cgit v1.2.3 From 8efdd0cdc54f3bb5db464b3baf88f7441f54da47 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Fri, 11 Feb 2011 13:00:06 +0100 Subject: Bluetooth: fix crash with quirky dongles doing sound Quirky dongles sometimes do not use the iso interface which causes a crash with runtime PM Signed-off-by: Oliver Neukum Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/btusb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 4cefa91e6c34..664f1cc9f8d4 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -829,7 +829,7 @@ static void btusb_work(struct work_struct *work) if (hdev->conn_hash.sco_num > 0) { if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) { - err = usb_autopm_get_interface(data->isoc); + err = usb_autopm_get_interface(data->isoc ? data->isoc : data->intf); if (err < 0) { clear_bit(BTUSB_ISOC_RUNNING, &data->flags); usb_kill_anchored_urbs(&data->isoc_anchor); @@ -858,7 +858,7 @@ static void btusb_work(struct work_struct *work) __set_isoc_interface(hdev, 0); if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags)) - usb_autopm_put_interface(data->isoc); + usb_autopm_put_interface(data->isoc ? data->isoc : data->intf); } } -- cgit v1.2.3 From e9036e336a8e5640871e0006ea4a89982b25046f Mon Sep 17 00:00:00 2001 From: "Cho, Yu-Chen" Date: Tue, 15 Feb 2011 10:20:07 +0800 Subject: Bluetooth: Add Atheros BT AR5BBU12 fw supported Add the btusb.c blacklist [0489:e02c] for Atheros AR5BBU12 BT and add to ath3k.c supported this device. Signed-off-by: Cho, Yu-Chen Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/ath3k.c | 3 +++ drivers/bluetooth/btusb.c | 3 +++ 2 files changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 333c21289d97..6dcd55a74c0a 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -41,6 +41,9 @@ static struct usb_device_id ath3k_table[] = { /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03F0, 0x311D) }, + + /* Atheros AR5BBU12 with sflash firmware */ + { USB_DEVICE(0x0489, 0xE02C) }, { } /* Terminating entry */ }; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 664f1cc9f8d4..b7f2f373c631 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -105,6 +105,9 @@ static struct usb_device_id blacklist_table[] = { /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, + /* Atheros AR5BBU12 with sflash firmware */ + { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, + /* Broadcom BCM2035 */ { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, -- cgit v1.2.3 From 03c2d0e89409b59c1ec9d9511533cedc0b7aaa69 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Mon, 14 Feb 2011 18:53:43 -0300 Subject: Bluetooth: Use usb_fill_int_urb() Instead set urb structure directly we call usb_fill_int_urb() to set the values to us. Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/btusb.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index fa84109f1bdd..89b9e51eec1f 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -714,15 +714,11 @@ static int btusb_send_frame(struct sk_buff *skb) pipe = usb_sndisocpipe(data->udev, data->isoc_tx_ep->bEndpointAddress); - urb->dev = data->udev; - urb->pipe = pipe; - urb->context = skb; - urb->complete = btusb_isoc_tx_complete; - urb->interval = data->isoc_tx_ep->bInterval; + usb_fill_int_urb(urb, data->udev, pipe, + skb->data, skb->len, btusb_isoc_tx_complete, + skb, data->isoc_tx_ep->bInterval); urb->transfer_flags = URB_ISO_ASAP; - urb->transfer_buffer = skb->data; - urb->transfer_buffer_length = skb->len; __fill_isoc_descriptor(urb, skb->len, le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize)); -- cgit v1.2.3 From 7f4b2b04c88377af30c022f36c060190182850fb Mon Sep 17 00:00:00 2001 From: Andrei Warkentin Date: Fri, 11 Feb 2011 17:19:26 -0600 Subject: Bluetooth: Make hci a child of the corresponding tty device. Make /sys/class/bluetooth/hciX a symlink to path under corresponding tty. Signed-off-by: Andrei Warkentin Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/hci_ldisc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 3c6cabcb7d84..48ad2a7ab080 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -398,6 +398,7 @@ static int hci_uart_register_dev(struct hci_uart *hu) hdev->flush = hci_uart_flush; hdev->send = hci_uart_send_frame; hdev->destruct = hci_uart_destruct; + hdev->parent = hu->tty->dev; hdev->owner = THIS_MODULE; -- cgit v1.2.3 From d4726051043dd270f9a161414a8d5ced76e91dff Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 4 Jan 2011 15:22:36 +0000 Subject: sfc: Limit filter search depth further for performance hints (i.e. RFS) Signed-off-by: Ben Hutchings --- drivers/net/sfc/filter.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/filter.c b/drivers/net/sfc/filter.c index d4722c41c4ce..47a1b7984788 100644 --- a/drivers/net/sfc/filter.c +++ b/drivers/net/sfc/filter.c @@ -27,6 +27,10 @@ */ #define FILTER_CTL_SRCH_MAX 200 +/* Don't try very hard to find space for performance hints, as this is + * counter-productive. */ +#define FILTER_CTL_SRCH_HINT_MAX 5 + enum efx_filter_table_id { EFX_FILTER_TABLE_RX_IP = 0, EFX_FILTER_TABLE_RX_MAC, @@ -325,15 +329,16 @@ static int efx_filter_search(struct efx_filter_table *table, struct efx_filter_spec *spec, u32 key, bool for_insert, int *depth_required) { - unsigned hash, incr, filter_idx, depth; + unsigned hash, incr, filter_idx, depth, depth_max; struct efx_filter_spec *cmp; hash = efx_filter_hash(key); incr = efx_filter_increment(key); + depth_max = (spec->priority <= EFX_FILTER_PRI_HINT ? + FILTER_CTL_SRCH_HINT_MAX : FILTER_CTL_SRCH_MAX); for (depth = 1, filter_idx = hash & (table->size - 1); - depth <= FILTER_CTL_SRCH_MAX && - test_bit(filter_idx, table->used_bitmap); + depth <= depth_max && test_bit(filter_idx, table->used_bitmap); ++depth) { cmp = &table->spec[filter_idx]; if (efx_filter_equal(spec, cmp)) @@ -342,7 +347,7 @@ static int efx_filter_search(struct efx_filter_table *table, } if (!for_insert) return -ENOENT; - if (depth > FILTER_CTL_SRCH_MAX) + if (depth > depth_max) return -EBUSY; found: *depth_required = depth; -- cgit v1.2.3 From 812f219a0f8a74a558c35be7942a07232ba348a5 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 3 Feb 2011 01:49:33 +0100 Subject: drm/nv10: Fix crash when allocating a BO larger than half the available VRAM. Reported-by: Alex Buell Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index a7fae26f4654..98dd970cea24 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -128,6 +128,7 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, } } + nvbo->bo.mem.num_pages = size >> PAGE_SHIFT; nouveau_bo_placement_set(nvbo, flags, 0); nvbo->channel = chan; @@ -166,17 +167,17 @@ static void set_placement_range(struct nouveau_bo *nvbo, uint32_t type) { struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); + int vram_pages = dev_priv->vram_size >> PAGE_SHIFT; if (dev_priv->card_type == NV_10 && - nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM)) { + nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) && + nvbo->bo.mem.num_pages < vram_pages / 2) { /* * Make sure that the color and depth buffers are handled * by independent memory controller units. Up to a 9x * speed up when alpha-blending and depth-test are enabled * at the same time. */ - int vram_pages = dev_priv->vram_size >> PAGE_SHIFT; - if (nvbo->tile_flags & NOUVEAU_GEM_TILE_ZETA) { nvbo->placement.fpfn = vram_pages / 2; nvbo->placement.lpfn = ~0; -- cgit v1.2.3 From 87886221471495c26d517a7b3ce7c7aa56cc854f Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 3 Feb 2011 01:53:18 +0100 Subject: drm/nv04-nv40: Fix NULL dereference when we fail to find an LVDS native mode. Reported-by: Alex Buell Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv04_dfp.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index ef23550407b5..c82db37d9f41 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c @@ -342,8 +342,8 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder, if (nv_encoder->dcb->type == OUTPUT_LVDS) { bool duallink, dummy; - nouveau_bios_parse_lvds_table(dev, nv_connector->native_mode-> - clock, &duallink, &dummy); + nouveau_bios_parse_lvds_table(dev, output_mode->clock, + &duallink, &dummy); if (duallink) regp->fp_control |= (8 << 28); } else @@ -518,8 +518,6 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) return; if (nv_encoder->dcb->lvdsconf.use_power_scripts) { - struct nouveau_connector *nv_connector = nouveau_encoder_connector_get(nv_encoder); - /* when removing an output, crtc may not be set, but PANEL_OFF * must still be run */ @@ -527,12 +525,8 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) nv04_dfp_get_bound_head(dev, nv_encoder->dcb); if (mode == DRM_MODE_DPMS_ON) { - if (!nv_connector->native_mode) { - NV_ERROR(dev, "Not turning on LVDS without native mode\n"); - return; - } call_lvds_script(dev, nv_encoder->dcb, head, - LVDS_PANEL_ON, nv_connector->native_mode->clock); + LVDS_PANEL_ON, nv_encoder->mode.clock); } else /* pxclk of 0 is fine for PANEL_OFF, and for a * disconnected LVDS encoder there is no native_mode -- cgit v1.2.3 From 77b1d5dc119f9b72bcfbb49d2431fd3679382dab Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 3 Feb 2011 01:56:32 +0100 Subject: drm/nouveau: Fix detection of DDC-based LVDS on DCB15 boards. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bios.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index c85a71596688..6faf3cfc74b9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -6228,7 +6228,7 @@ parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb, entry->tvconf.has_component_output = false; break; case OUTPUT_LVDS: - if ((conn & 0x00003f00) != 0x10) + if ((conn & 0x00003f00) >> 8 != 0x10) entry->lvdsconf.use_straps_for_mode = true; entry->lvdsconf.use_power_scripts = true; break; -- cgit v1.2.3 From 0d9b6193bcc335fb05a26af5b11a0d76b70cb1a4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 7 Feb 2011 08:41:18 +1000 Subject: drm/nouveau: fix non-EDIDful native mode selection The DRM core fills this value, but at too late a stage for this to work, possibly resulting in an undesirable mode being selected. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_connector.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index a21e00076839..390d82c3c4b0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -507,6 +507,7 @@ nouveau_connector_native_mode(struct drm_connector *connector) int high_w = 0, high_h = 0, high_v = 0; list_for_each_entry(mode, &nv_connector->base.probed_modes, head) { + mode->vrefresh = drm_mode_vrefresh(mode); if (helper->mode_valid(connector, mode) != MODE_OK || (mode->flags & DRM_MODE_FLAG_INTERLACE)) continue; -- cgit v1.2.3 From 1dc32671d887f05844315e4105ad4c783299ac8f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 7 Feb 2011 10:49:39 +1000 Subject: drm/nv40: fix tiling-related setup for a number of chipsets Due to the default case handling the older chipsets, a bunch of the newer ones ended up having the wrong tiling regs used. This commit switches the default case to handle the newest chipsets. This also makes nv4e touch the "extra" tiling regs. "nv" doesn't touch them for C51 but traces of the NVIDIA binary driver show it being done there. I couldn't find NV41/NV45 traces to confirm the behaviour there, but an educated guess was taken at each of them. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv40_graph.c | 46 +++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 8870d72388c8..18d30c2c1aa6 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c @@ -211,18 +211,32 @@ nv40_graph_set_tile_region(struct drm_device *dev, int i) struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; switch (dev_priv->chipset) { + case 0x40: + case 0x41: /* guess */ + case 0x42: + case 0x43: + case 0x45: /* guess */ + case 0x4e: + nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch); + nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit); + nv_wr32(dev, NV20_PGRAPH_TILE(i), tile->addr); + nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tile->pitch); + nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tile->limit); + nv_wr32(dev, NV40_PGRAPH_TILE1(i), tile->addr); + break; case 0x44: case 0x4a: - case 0x4e: nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch); nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit); nv_wr32(dev, NV20_PGRAPH_TILE(i), tile->addr); break; - case 0x46: case 0x47: case 0x49: case 0x4b: + case 0x4c: + case 0x67: + default: nv_wr32(dev, NV47_PGRAPH_TSIZE(i), tile->pitch); nv_wr32(dev, NV47_PGRAPH_TLIMIT(i), tile->limit); nv_wr32(dev, NV47_PGRAPH_TILE(i), tile->addr); @@ -230,15 +244,6 @@ nv40_graph_set_tile_region(struct drm_device *dev, int i) nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tile->limit); nv_wr32(dev, NV40_PGRAPH_TILE1(i), tile->addr); break; - - default: - nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch); - nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit); - nv_wr32(dev, NV20_PGRAPH_TILE(i), tile->addr); - nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tile->pitch); - nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tile->limit); - nv_wr32(dev, NV40_PGRAPH_TILE1(i), tile->addr); - break; } } @@ -396,17 +401,20 @@ nv40_graph_init(struct drm_device *dev) break; default: switch (dev_priv->chipset) { - case 0x46: - case 0x47: - case 0x49: - case 0x4b: - nv_wr32(dev, 0x400DF0, nv_rd32(dev, NV04_PFB_CFG0)); - nv_wr32(dev, 0x400DF4, nv_rd32(dev, NV04_PFB_CFG1)); - break; - default: + case 0x41: + case 0x42: + case 0x43: + case 0x45: + case 0x4e: + case 0x44: + case 0x4a: nv_wr32(dev, 0x4009F0, nv_rd32(dev, NV04_PFB_CFG0)); nv_wr32(dev, 0x4009F4, nv_rd32(dev, NV04_PFB_CFG1)); break; + default: + nv_wr32(dev, 0x400DF0, nv_rd32(dev, NV04_PFB_CFG0)); + nv_wr32(dev, 0x400DF4, nv_rd32(dev, NV04_PFB_CFG1)); + break; } nv_wr32(dev, 0x4069F0, nv_rd32(dev, NV04_PFB_CFG0)); nv_wr32(dev, 0x4069F4, nv_rd32(dev, NV04_PFB_CFG1)); -- cgit v1.2.3 From b8884da6113be83f6f3b296539bcd9f602a6abd8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 14 Feb 2011 13:51:28 +1000 Subject: drm/nouveau: flips/flipd need to always set 'evict' for move_accel_cleanup() We free the temporary binding before leaving this function, so we also have to wait for the move to actually complete. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 98dd970cea24..d38a4d9f9b0b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -786,7 +786,7 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr, if (ret) goto out; - ret = ttm_bo_move_ttm(bo, evict, no_wait_reserve, no_wait_gpu, new_mem); + ret = ttm_bo_move_ttm(bo, true, no_wait_reserve, no_wait_gpu, new_mem); out: ttm_bo_mem_put(bo, &tmp_mem); return ret; @@ -812,11 +812,11 @@ nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr, if (ret) return ret; - ret = ttm_bo_move_ttm(bo, evict, no_wait_reserve, no_wait_gpu, &tmp_mem); + ret = ttm_bo_move_ttm(bo, true, no_wait_reserve, no_wait_gpu, &tmp_mem); if (ret) goto out; - ret = nouveau_bo_move_m2mf(bo, evict, intr, no_wait_reserve, no_wait_gpu, new_mem); + ret = nouveau_bo_move_m2mf(bo, true, intr, no_wait_reserve, no_wait_gpu, new_mem); if (ret) goto out; -- cgit v1.2.3 From 317495b25ec1f0beb0dbac8ee0dfec59a1addf03 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 17 Feb 2011 11:11:28 +1000 Subject: drm/nouveau: fix suspend/resume on GPUs that don't have PM support This has been broken since 2.6.37, and fixes resume on a couple of fermi boards I have access to. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c index f05c0cddfeca..4399e2f34db4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/drivers/gpu/drm/nouveau/nouveau_pm.c @@ -543,7 +543,7 @@ nouveau_pm_resume(struct drm_device *dev) struct nouveau_pm_engine *pm = &dev_priv->engine.pm; struct nouveau_pm_level *perflvl; - if (pm->cur == &pm->boot) + if (!pm->cur || pm->cur == &pm->boot) return; perflvl = pm->cur; -- cgit v1.2.3 From 16e4b8a6e44b8c736c37af370afaa428c3239fb6 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Wed, 16 Feb 2011 02:26:08 +0100 Subject: drm/radeon/kms: do not reject X16 and Y16X16 floating-point formats on r300 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marek Olšák Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r300.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 768c60ee4ab6..069efa8c8ecf 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -910,6 +910,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, track->textures[i].compress_format = R100_TRACK_COMP_NONE; break; case R300_TX_FORMAT_X16: + case R300_TX_FORMAT_FL_I16: case R300_TX_FORMAT_Y8X8: case R300_TX_FORMAT_Z5Y6X5: case R300_TX_FORMAT_Z6Y5X5: @@ -922,6 +923,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, track->textures[i].compress_format = R100_TRACK_COMP_NONE; break; case R300_TX_FORMAT_Y16X16: + case R300_TX_FORMAT_FL_I16A16: case R300_TX_FORMAT_Z11Y11X10: case R300_TX_FORMAT_Z10Y11X11: case R300_TX_FORMAT_W8Z8Y8X8: -- cgit v1.2.3 From 9f4283f49f0a96a64c5a45fe56f0f8c942885eef Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 16 Feb 2011 21:17:04 -0500 Subject: drm/radeon/kms: add missing frac fb div flag for dce4+ The fixed ref/post dividers are set by the AdjustPll table rather than the ss info table on dce4+. Make sure we enable the fractional feedback dividers when using a fixed post or ref divider on them as well. Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=29272 Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atombios_crtc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 095bc507fb16..a4e5e53e0a62 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -557,9 +557,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, /* use recommended ref_div for ss */ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { - pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; if (ss_enabled) { if (ss->refdiv) { + pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; pll->flags |= RADEON_PLL_USE_REF_DIV; pll->reference_div = ss->refdiv; if (ASIC_IS_AVIVO(rdev)) @@ -662,10 +662,12 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, index, (uint32_t *)&args); adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10; if (args.v3.sOutput.ucRefDiv) { + pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; pll->flags |= RADEON_PLL_USE_REF_DIV; pll->reference_div = args.v3.sOutput.ucRefDiv; } if (args.v3.sOutput.ucPostDiv) { + pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; pll->flags |= RADEON_PLL_USE_POST_DIV; pll->post_div = args.v3.sOutput.ucPostDiv; } -- cgit v1.2.3 From 615b32af9730def64330e4c0c95c973e90bd9c6d Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Wed, 2 Feb 2011 10:19:45 +0000 Subject: e1000e: check down flag in tasks This change is part of a fix to avoid any tasks running while the driver is exiting and deinitializing resources. Signed-off-by: Jesse Brandeburg Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/netdev.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers') diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 3065870cf2a7..174633c93325 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -937,6 +937,9 @@ static void e1000_print_hw_hang(struct work_struct *work) u16 phy_status, phy_1000t_status, phy_ext_status; u16 pci_status; + if (test_bit(__E1000_DOWN, &adapter->state)) + return; + e1e_rphy(hw, PHY_STATUS, &phy_status); e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status); e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status); @@ -1506,6 +1509,9 @@ static void e1000e_downshift_workaround(struct work_struct *work) struct e1000_adapter *adapter = container_of(work, struct e1000_adapter, downshift_task); + if (test_bit(__E1000_DOWN, &adapter->state)) + return; + e1000e_gig_downshift_workaround_ich8lan(&adapter->hw); } @@ -3765,6 +3771,10 @@ static void e1000e_update_phy_task(struct work_struct *work) { struct e1000_adapter *adapter = container_of(work, struct e1000_adapter, update_phy_task); + + if (test_bit(__E1000_DOWN, &adapter->state)) + return; + e1000_get_phy_info(&adapter->hw); } @@ -3775,6 +3785,10 @@ static void e1000e_update_phy_task(struct work_struct *work) static void e1000_update_phy_info(unsigned long data) { struct e1000_adapter *adapter = (struct e1000_adapter *) data; + + if (test_bit(__E1000_DOWN, &adapter->state)) + return; + schedule_work(&adapter->update_phy_task); } @@ -4149,6 +4163,9 @@ static void e1000_watchdog_task(struct work_struct *work) u32 link, tctl; int tx_pending = 0; + if (test_bit(__E1000_DOWN, &adapter->state)) + return; + link = e1000e_has_link(adapter); if ((netif_carrier_ok(netdev)) && link) { /* Cancel scheduled suspend requests. */ @@ -4887,6 +4904,10 @@ static void e1000_reset_task(struct work_struct *work) struct e1000_adapter *adapter; adapter = container_of(work, struct e1000_adapter, reset_task); + /* don't run the task if already down */ + if (test_bit(__E1000_DOWN, &adapter->state)) + return; + if (!((adapter->flags & FLAG_RX_NEEDS_RESTART) && (adapter->flags & FLAG_RX_RESTART_NOW))) { e1000e_dump(adapter); -- cgit v1.2.3 From 713b3c9e4c1a6da6b45da6474ed554ed0a48de69 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Wed, 2 Feb 2011 10:19:50 +0000 Subject: e1000e: flush all writebacks before unload The driver was not flushing all writebacks before unloading, possibly causing memory to be written by the hardware after the driver had reinitialized the rings. This adds missing functionality to flush any pending writebacks and is called in all spots where descriptors should be completed before the driver begins processing. Signed-off-by: Jesse Brandeburg Reviewed-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/netdev.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 174633c93325..3fa110ddb041 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -3344,6 +3344,21 @@ int e1000e_up(struct e1000_adapter *adapter) return 0; } +static void e1000e_flush_descriptors(struct e1000_adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + + if (!(adapter->flags2 & FLAG2_DMA_BURST)) + return; + + /* flush pending descriptor writebacks to memory */ + ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); + ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD); + + /* execute the writes immediately */ + e1e_flush(); +} + void e1000e_down(struct e1000_adapter *adapter) { struct net_device *netdev = adapter->netdev; @@ -3383,6 +3398,9 @@ void e1000e_down(struct e1000_adapter *adapter) if (!pci_channel_offline(adapter->pdev)) e1000e_reset(adapter); + + e1000e_flush_descriptors(adapter); + e1000_clean_tx_ring(adapter); e1000_clean_rx_ring(adapter); @@ -4354,19 +4372,12 @@ link_up: else ew32(ICS, E1000_ICS_RXDMT0); + /* flush pending descriptors to memory before detecting Tx hang */ + e1000e_flush_descriptors(adapter); + /* Force detection of hung controller every watchdog period */ adapter->detect_tx_hung = 1; - /* flush partial descriptors to memory before detecting Tx hang */ - if (adapter->flags2 & FLAG2_DMA_BURST) { - ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); - ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD); - /* - * no need to flush the writes because the timeout code does - * an er32 first thing - */ - } - /* * With 82571 controllers, LAA may be overwritten due to controller * reset from the other port. Set the appropriate LAA in RAR[0] -- cgit v1.2.3 From 4c7e604babd15db9dca3b07de167a0f93fe23bf4 Mon Sep 17 00:00:00 2001 From: Andy Gospodarek Date: Thu, 17 Feb 2011 01:13:13 -0800 Subject: ixgbe: fix panic due to uninitialised pointer Systems containing an 82599EB and running a backported driver from upstream were panicing on boot. It turns out hw->mac.ops.setup_sfp is only set for 82599, so one should check to be sure that pointer is set before continuing in ixgbe_sfp_config_module_task. I verified by inspection that the upstream driver has the same issue and also added a check before the call in ixgbe_sfp_link_config. Signed-off-by: Andy Gospodarek Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index fbae703b46d7..30f9ccfb4f87 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3728,7 +3728,8 @@ static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter) * We need to try and force an autonegotiation * session, then bring up link. */ - hw->mac.ops.setup_sfp(hw); + if (hw->mac.ops.setup_sfp) + hw->mac.ops.setup_sfp(hw); if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)) schedule_work(&adapter->multispeed_fiber_task); } else { @@ -5968,7 +5969,8 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work) unregister_netdev(adapter->netdev); return; } - hw->mac.ops.setup_sfp(hw); + if (hw->mac.ops.setup_sfp) + hw->mac.ops.setup_sfp(hw); if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)) /* This will also work for DA Twinax connections */ -- cgit v1.2.3 From c600636bd560b04973174caa5e349a72bce51637 Mon Sep 17 00:00:00 2001 From: Amir Hanania Date: Tue, 15 Feb 2011 09:11:31 +0000 Subject: ixgbe: work around for DDP last buffer size A HW limitation was recently discovered where the last buffer in a DDP offload cannot be a full buffer size in length. Fix the issue with a work around by adding another buffer with size = 1. Signed-off-by: Amir Hanania Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_fcoe.c | 51 +++++++++++++++++++++++++++++++++++++++++- drivers/net/ixgbe/ixgbe_fcoe.h | 2 ++ 2 files changed, 52 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 8753980668c7..c54a88274d51 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -159,7 +159,7 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, struct scatterlist *sg; unsigned int i, j, dmacount; unsigned int len; - static const unsigned int bufflen = 4096; + static const unsigned int bufflen = IXGBE_FCBUFF_MIN; unsigned int firstoff = 0; unsigned int lastsize; unsigned int thisoff = 0; @@ -254,6 +254,24 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, /* only the last buffer may have non-full bufflen */ lastsize = thisoff + thislen; + /* + * lastsize can not be buffer len. + * If it is then adding another buffer with lastsize = 1. + */ + if (lastsize == bufflen) { + if (j >= IXGBE_BUFFCNT_MAX) { + e_err(drv, "xid=%x:%d,%d,%d:addr=%llx " + "not enough user buffers. We need an extra " + "buffer because lastsize is bufflen.\n", + xid, i, j, dmacount, (u64)addr); + goto out_noddp_free; + } + + ddp->udl[j] = (u64)(fcoe->extra_ddp_buffer_dma); + j++; + lastsize = 1; + } + fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT); fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT); fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT); @@ -532,6 +550,24 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) e_err(drv, "failed to allocated FCoE DDP pool\n"); spin_lock_init(&fcoe->lock); + + /* Extra buffer to be shared by all DDPs for HW work around */ + fcoe->extra_ddp_buffer = kmalloc(IXGBE_FCBUFF_MIN, GFP_ATOMIC); + if (fcoe->extra_ddp_buffer == NULL) { + e_err(drv, "failed to allocated extra DDP buffer\n"); + goto out_extra_ddp_buffer_alloc; + } + + fcoe->extra_ddp_buffer_dma = + dma_map_single(&adapter->pdev->dev, + fcoe->extra_ddp_buffer, + IXGBE_FCBUFF_MIN, + DMA_FROM_DEVICE); + if (dma_mapping_error(&adapter->pdev->dev, + fcoe->extra_ddp_buffer_dma)) { + e_err(drv, "failed to map extra DDP buffer\n"); + goto out_extra_ddp_buffer_dma; + } } /* Enable L2 eth type filter for FCoE */ @@ -581,6 +617,14 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) } } #endif + + return; + +out_extra_ddp_buffer_dma: + kfree(fcoe->extra_ddp_buffer); +out_extra_ddp_buffer_alloc: + pci_pool_destroy(fcoe->pool); + fcoe->pool = NULL; } /** @@ -600,6 +644,11 @@ void ixgbe_cleanup_fcoe(struct ixgbe_adapter *adapter) if (fcoe->pool) { for (i = 0; i < IXGBE_FCOE_DDP_MAX; i++) ixgbe_fcoe_ddp_put(adapter->netdev, i); + dma_unmap_single(&adapter->pdev->dev, + fcoe->extra_ddp_buffer_dma, + IXGBE_FCBUFF_MIN, + DMA_FROM_DEVICE); + kfree(fcoe->extra_ddp_buffer); pci_pool_destroy(fcoe->pool); fcoe->pool = NULL; } diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h index 4bc2c551c8db..65cc8fb14fe7 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.h +++ b/drivers/net/ixgbe/ixgbe_fcoe.h @@ -70,6 +70,8 @@ struct ixgbe_fcoe { spinlock_t lock; struct pci_pool *pool; struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX]; + unsigned char *extra_ddp_buffer; + dma_addr_t extra_ddp_buffer_dma; }; #endif /* _IXGBE_FCOE_H */ -- cgit v1.2.3 From 8dd38383a51d0fb6b025dc330aaa3470281da3b2 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 17 Feb 2011 10:31:20 +0000 Subject: xen: suspend and resume system devices when running PVHVM Otherwise we fail to properly suspend/resume all of the emulated devices. Something between 2.6.38-rc2 and rc3 appears to have exposed this issue, but it's always been wrong not to do this. Signed-off-by: Ian Campbell Acked-by: Stefano Stabellini Acked-by: Jeremy Fitzhardinge --- drivers/xen/manage.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index db8c4c4ac880..24177272bcb8 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -37,11 +37,19 @@ static enum shutdown_state shutting_down = SHUTDOWN_INVALID; #ifdef CONFIG_PM_SLEEP static int xen_hvm_suspend(void *data) { + int err; struct sched_shutdown r = { .reason = SHUTDOWN_suspend }; int *cancelled = data; BUG_ON(!irqs_disabled()); + err = sysdev_suspend(PMSG_SUSPEND); + if (err) { + printk(KERN_ERR "xen_hvm_suspend: sysdev_suspend failed: %d\n", + err); + return err; + } + *cancelled = HYPERVISOR_sched_op(SCHEDOP_shutdown, &r); xen_hvm_post_suspend(*cancelled); @@ -53,6 +61,8 @@ static int xen_hvm_suspend(void *data) xen_timer_resume(); } + sysdev_resume(); + return 0; } -- cgit v1.2.3 From 5da24b7627ff821e154a3aaecd5d60e1d8e228a5 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Thu, 17 Feb 2011 13:13:55 +0100 Subject: [S390] dasd: correct device table The 3880 storage control unit supports a 3380 device type, but not a 3390 device type. Reported-by: Stephen Powell Signed-off-by: Stefan Haberland Signed-off-by: Martin Schwidefsky --- drivers/s390/block/dasd_eckd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 318672d05563..a9fe23d5bd0f 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -72,7 +72,7 @@ static struct dasd_discipline dasd_eckd_discipline; static struct ccw_device_id dasd_eckd_ids[] = { { CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3390, 0), .driver_info = 0x1}, { CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3390, 0), .driver_info = 0x2}, - { CCW_DEVICE_DEVTYPE (0x3880, 0, 0x3390, 0), .driver_info = 0x3}, + { CCW_DEVICE_DEVTYPE (0x3880, 0, 0x3380, 0), .driver_info = 0x3}, { CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3380, 0), .driver_info = 0x4}, { CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3380, 0), .driver_info = 0x5}, { CCW_DEVICE_DEVTYPE (0x9343, 0, 0x9345, 0), .driver_info = 0x6}, -- cgit v1.2.3 From 5990378b393429244559f4750f2ee3a50929b932 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 11 Feb 2011 10:00:02 +0200 Subject: usb: musb: fix build breakage commit 0662481855c389b75a0a54c32870cc90563d80a9 (usb: musb: disable double buffering when it's broken), introduced a compile error when gadget API is disabled. Fix it. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index d74a8113ae74..e6400be8a0f8 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -488,6 +488,15 @@ struct musb { unsigned set_address:1; unsigned test_mode:1; unsigned softconnect:1; + + u8 address; + u8 test_mode_nr; + u16 ackpend; /* ep0 */ + enum musb_g_ep0_state ep0_state; + struct usb_gadget g; /* the gadget */ + struct usb_gadget_driver *gadget_driver; /* its driver */ +#endif + /* * FIXME: Remove this flag. * @@ -501,14 +510,6 @@ struct musb { */ unsigned double_buffer_not_ok:1 __deprecated; - u8 address; - u8 test_mode_nr; - u16 ackpend; /* ep0 */ - enum musb_g_ep0_state ep0_state; - struct usb_gadget g; /* the gadget */ - struct usb_gadget_driver *gadget_driver; /* its driver */ -#endif - struct musb_hdrc_config *config; #ifdef MUSB_CONFIG_PROC_FS -- cgit v1.2.3 From b193b412e62b134adf69af286c7e7f8e99259350 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 11 Feb 2011 16:57:08 +0100 Subject: usb: musb: omap2430: fix kernel panic on reboot Cancel idle timer in musb_platform_exit. The idle timer could trigger after clock had been disabled leading to kernel panic when MUSB_DEVCTL is accessed in musb_do_idle on 2.6.37. The fault below is no longer triggered on 2.6.38-rc4 (clock is disabled later, and only if compiled as a module, and the offending memory access has moved) but the timer should be cancelled nonetheless. Rebooting... musb_hdrc musb_hdrc: remove, state 4 usb usb1: USB disconnect, address 1 musb_hdrc musb_hdrc: USB bus 1 deregistered Unhandled fault: external abort on non-linefetch (0x1028) at 0xfa0ab060 Internal error: : 1028 [#1] PREEMPT last sysfs file: /sys/kernel/uevent_seqnum Modules linked in: CPU: 0 Not tainted (2.6.37+ #6) PC is at musb_do_idle+0x24/0x138 LR is at musb_do_idle+0x18/0x138 pc : [] lr : [] psr: 80000193 sp : cf2bdd80 ip : cf2bdd80 fp : c048a20c r10: c048a60c r9 : c048a40c r8 : cf85e110 r7 : cf2bc000 r6 : 40000113 r5 : c0489800 r4 : cf85e110 r3 : 00000004 r2 : 00000006 r1 : fa0ab000 r0 : cf8a7000 Flags: Nzcv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user Control: 10c5387d Table: 8faac019 DAC: 00000015 Process reboot (pid: 769, stack limit = 0xcf2bc2f0) Stack: (0xcf2bdd80 to 0xcf2be000) dd80: 00000103 c0489800 c02377b4 c005fa34 00000555 c0071a8c c04a3858 cf2bdda8 dda0: 00000555 c048a00c cf2bdda8 cf2bdda8 1838beb0 00000103 00000004 cf2bc000 ddc0: 00000001 00000001 c04896c8 0000000a 00000000 c005ac14 00000001 c003f32c dde0: 00000000 00000025 00000000 cf2bc000 00000002 00000001 cf2bc000 00000000 de00: 00000001 c005ad08 cf2bc000 c002e07c c03ec039 ffffffff fa200000 c0033608 de20: 00000001 00000000 cf852c14 cf81f200 c045b714 c045b708 cf2bc000 c04a37e8 de40: c0033c04 cf2bc000 00000000 00000001 cf2bde68 cf2bde68 c01c3abc c004f7d8 de60: 60000013 ffffffff c0033c04 00000000 01234567 fee1dead 00000000 c006627c de80: 00000001 c00662c8 28121969 c00663ec cfa38c40 cf9f6a00 cf2bded0 cf9f6a0c dea0: 00000000 cf92f000 00008914 c02cd284 c04a55c8 c028b398 c00715c0 becf24a8 dec0: 30687465 00000000 00000000 00000000 00000002 1301a8c0 00000000 00000000 dee0: 00000002 1301a8c0 00000000 00000000 c0450494 cf527920 00011f10 cf2bdf08 df00: 00011f10 cf2bdf10 00011f10 cf2bdf18 c00f0b44 c004f7e8 cf2bdf18 cf2bdf18 df20: 00011f10 cf2bdf30 00011f10 cf2bdf38 cf401300 cf486100 00000008 c00d2b28 df40: 00011f10 cf401300 00200200 c00d3388 00011f10 cfb63a88 cfb63a80 c00c2f08 df60: 00000000 00000000 cfb63a80 00000000 cf0a3480 00000006 c0033c04 cfb63a80 df80: 00000000 c00c0104 00000003 cf0a3480 cfb63a80 00000000 00000001 00000004 dfa0: 00000058 c0033a80 00000000 00000001 fee1dead 28121969 01234567 00000000 dfc0: 00000000 00000001 00000004 00000058 00000001 00000001 00000000 00000001 dfe0: 4024d200 becf2cb0 00009210 4024d218 60000010 fee1dead 00000000 00000000 [] (musb_do_idle+0x24/0x138) from [] (run_timer_softirq+0x1a8/0x26) [] (run_timer_softirq+0x1a8/0x26c) from [] (__do_softirq+0x88/0x13) [] (__do_softirq+0x88/0x138) from [] (irq_exit+0x44/0x98) [] (irq_exit+0x44/0x98) from [] (asm_do_IRQ+0x7c/0xa0) [] (asm_do_IRQ+0x7c/0xa0) from [] (__irq_svc+0x48/0xa8) Exception stack(0xcf2bde20 to 0xcf2bde68) de20: 00000001 00000000 cf852c14 cf81f200 c045b714 c045b708 cf2bc000 c04a37e8 de40: c0033c04 cf2bc000 00000000 00000001 cf2bde68 cf2bde68 c01c3abc c004f7d8 de60: 60000013 ffffffff [] (__irq_svc+0x48/0xa8) from [] (sub_preempt_count+0x0/0xb8) Code: ebf86030 e5940098 e594108c e5902010 (e5d13060) ---[ end trace 3689c0d808f9bf7c ]--- Kernel panic - not syncing: Fatal exception in interrupt Cc: stable@kernel.org Signed-off-by: Johan Hovold Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index a3f12333fc41..bc8badd16897 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -362,6 +362,7 @@ static int omap2430_musb_init(struct musb *musb) static int omap2430_musb_exit(struct musb *musb) { + del_timer_sync(&musb_idle_timer); omap2430_low_level_exit(musb); otg_put_transceiver(musb->xceiv); -- cgit v1.2.3 From 479b46b5599b1e610630d7332e168c1f9c4ee0b4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 17 Feb 2011 09:54:16 -0800 Subject: Revert "USB host: Move AMD PLL quirk to pci-quirks.c" This reverts commit b7d5b439b7a40dd0a0202fe1c118615a3fcc3b25. It conflicts with commit baab93afc2844b68d57b0dcca5e1d34c5d7cf411 "USB: EHCI: ASPM quirk of ISOC on AMD Hudson" and merging the two just doesn't work properly. Cc: Andiry Xu Cc: David Brownell Cc: Alex He Cc: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 10 +- drivers/usb/host/ehci-pci.c | 38 +++++- drivers/usb/host/ehci-sched.c | 73 ++++++++++-- drivers/usb/host/ehci.h | 2 +- drivers/usb/host/ohci-hcd.c | 13 ++- drivers/usb/host/ohci-pci.c | 110 ++++++++++++++++-- drivers/usb/host/ohci-q.c | 4 +- drivers/usb/host/ohci.h | 4 +- drivers/usb/host/pci-quirks.c | 260 ------------------------------------------ drivers/usb/host/pci-quirks.h | 19 --- 10 files changed, 222 insertions(+), 311 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 30515d362c4b..6fee3cd58efe 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -114,11 +114,13 @@ MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us\n"); #define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT) +/* for ASPM quirk of ISOC on AMD SB800 */ +static struct pci_dev *amd_nb_dev; + /*-------------------------------------------------------------------------*/ #include "ehci.h" #include "ehci-dbg.c" -#include "pci-quirks.h" /*-------------------------------------------------------------------------*/ @@ -530,8 +532,10 @@ static void ehci_stop (struct usb_hcd *hcd) spin_unlock_irq (&ehci->lock); ehci_mem_cleanup (ehci); - if (ehci->amd_pll_fix == 1) - usb_amd_dev_put(); + if (amd_nb_dev) { + pci_dev_put(amd_nb_dev); + amd_nb_dev = NULL; + } #ifdef EHCI_STATS ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n", diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 1ec8060e8cc4..76179c39c0e3 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -44,6 +44,35 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) return 0; } +static int ehci_quirk_amd_SB800(struct ehci_hcd *ehci) +{ + struct pci_dev *amd_smbus_dev; + u8 rev = 0; + + amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, 0x4385, NULL); + if (!amd_smbus_dev) + return 0; + + pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev); + if (rev < 0x40) { + pci_dev_put(amd_smbus_dev); + amd_smbus_dev = NULL; + return 0; + } + + if (!amd_nb_dev) + amd_nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1510, NULL); + if (!amd_nb_dev) + ehci_err(ehci, "QUIRK: unable to get AMD NB device\n"); + + ehci_info(ehci, "QUIRK: Enable AMD SB800 L1 fix\n"); + + pci_dev_put(amd_smbus_dev); + amd_smbus_dev = NULL; + + return 1; +} + /* called during probe() after chip reset completes */ static int ehci_pci_setup(struct usb_hcd *hcd) { @@ -102,6 +131,9 @@ static int ehci_pci_setup(struct usb_hcd *hcd) /* cache this readonly data; minimize chip reads */ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); + if (ehci_quirk_amd_SB800(ehci)) + ehci->amd_l1_fix = 1; + retval = ehci_halt(ehci); if (retval) return retval; @@ -152,9 +184,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) } break; case PCI_VENDOR_ID_AMD: - /* AMD PLL quirk */ - if (usb_amd_find_chipset_info()) - ehci->amd_pll_fix = 1; /* AMD8111 EHCI doesn't work, according to AMD errata */ if (pdev->device == 0x7463) { ehci_info(ehci, "ignoring AMD8111 (errata)\n"); @@ -200,9 +229,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) } break; case PCI_VENDOR_ID_ATI: - /* AMD PLL quirk */ - if (usb_amd_find_chipset_info()) - ehci->amd_pll_fix = 1; /* SB600 and old version of SB700 have a bug in EHCI controller, * which causes usb devices lose response in some cases. */ diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 1543c838b3d1..30fbdbe1cf1e 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1587,6 +1587,63 @@ itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); } +#define AB_REG_BAR_LOW 0xe0 +#define AB_REG_BAR_HIGH 0xe1 +#define AB_INDX(addr) ((addr) + 0x00) +#define AB_DATA(addr) ((addr) + 0x04) +#define NB_PCIE_INDX_ADDR 0xe0 +#define NB_PCIE_INDX_DATA 0xe4 +#define NB_PIF0_PWRDOWN_0 0x01100012 +#define NB_PIF0_PWRDOWN_1 0x01100013 + +static void ehci_quirk_amd_L1(struct ehci_hcd *ehci, int disable) +{ + u32 addr, addr_low, addr_high, val; + + outb_p(AB_REG_BAR_LOW, 0xcd6); + addr_low = inb_p(0xcd7); + outb_p(AB_REG_BAR_HIGH, 0xcd6); + addr_high = inb_p(0xcd7); + addr = addr_high << 8 | addr_low; + outl_p(0x30, AB_INDX(addr)); + outl_p(0x40, AB_DATA(addr)); + outl_p(0x34, AB_INDX(addr)); + val = inl_p(AB_DATA(addr)); + + if (disable) { + val &= ~0x8; + val |= (1 << 4) | (1 << 9); + } else { + val |= 0x8; + val &= ~((1 << 4) | (1 << 9)); + } + outl_p(val, AB_DATA(addr)); + + if (amd_nb_dev) { + addr = NB_PIF0_PWRDOWN_0; + pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_ADDR, addr); + pci_read_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, &val); + if (disable) + val &= ~(0x3f << 7); + else + val |= 0x3f << 7; + + pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, val); + + addr = NB_PIF0_PWRDOWN_1; + pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_ADDR, addr); + pci_read_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, &val); + if (disable) + val &= ~(0x3f << 7); + else + val |= 0x3f << 7; + + pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, val); + } + + return; +} + /* fit urb's itds into the selected schedule slot; activate as needed */ static int itd_link_urb ( @@ -1615,8 +1672,8 @@ itd_link_urb ( } if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { - if (ehci->amd_pll_fix == 1) - usb_amd_quirk_pll_disable(); + if (ehci->amd_l1_fix == 1) + ehci_quirk_amd_L1(ehci, 1); } ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; @@ -1744,8 +1801,8 @@ itd_complete ( ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { - if (ehci->amd_pll_fix == 1) - usb_amd_quirk_pll_enable(); + if (ehci->amd_l1_fix == 1) + ehci_quirk_amd_L1(ehci, 0); } if (unlikely(list_is_singular(&stream->td_list))) { @@ -2035,8 +2092,8 @@ sitd_link_urb ( } if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { - if (ehci->amd_pll_fix == 1) - usb_amd_quirk_pll_disable(); + if (ehci->amd_l1_fix == 1) + ehci_quirk_amd_L1(ehci, 1); } ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; @@ -2140,8 +2197,8 @@ sitd_complete ( ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { - if (ehci->amd_pll_fix == 1) - usb_amd_quirk_pll_enable(); + if (ehci->amd_l1_fix == 1) + ehci_quirk_amd_L1(ehci, 0); } if (list_is_singular(&stream->td_list)) { diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index f86d3fa20214..799ac16a54b4 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -131,7 +131,7 @@ struct ehci_hcd { /* one per controller */ unsigned has_amcc_usb23:1; unsigned need_io_watchdog:1; unsigned broken_periodic:1; - unsigned amd_pll_fix:1; + unsigned amd_l1_fix:1; unsigned fs_i_thresh:1; /* Intel iso scheduling */ unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/ diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 7b791bf1e7b4..759a12ff8048 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -75,7 +75,6 @@ static const char hcd_name [] = "ohci_hcd"; #define STATECHANGE_DELAY msecs_to_jiffies(300) #include "ohci.h" -#include "pci-quirks.h" static void ohci_dump (struct ohci_hcd *ohci, int verbose); static int ohci_init (struct ohci_hcd *ohci); @@ -86,8 +85,18 @@ static int ohci_restart (struct ohci_hcd *ohci); #endif #ifdef CONFIG_PCI +static void quirk_amd_pll(int state); +static void amd_iso_dev_put(void); static void sb800_prefetch(struct ohci_hcd *ohci, int on); #else +static inline void quirk_amd_pll(int state) +{ + return; +} +static inline void amd_iso_dev_put(void) +{ + return; +} static inline void sb800_prefetch(struct ohci_hcd *ohci, int on) { return; @@ -903,7 +912,7 @@ static void ohci_stop (struct usb_hcd *hcd) if (quirk_zfmicro(ohci)) del_timer(&ohci->unlink_watchdog); if (quirk_amdiso(ohci)) - usb_amd_dev_put(); + amd_iso_dev_put(); remove_debug_files (ohci); ohci_mem_cleanup (ohci); diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 9816a2870d00..36ee9a666e93 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -22,6 +22,24 @@ #include +/* constants used to work around PM-related transfer + * glitches in some AMD 700 series southbridges + */ +#define AB_REG_BAR 0xf0 +#define AB_INDX(addr) ((addr) + 0x00) +#define AB_DATA(addr) ((addr) + 0x04) +#define AX_INDXC 0X30 +#define AX_DATAC 0x34 + +#define NB_PCIE_INDX_ADDR 0xe0 +#define NB_PCIE_INDX_DATA 0xe4 +#define PCIE_P_CNTL 0x10040 +#define BIF_NB 0x10002 + +static struct pci_dev *amd_smbus_dev; +static struct pci_dev *amd_hb_dev; +static int amd_ohci_iso_count; + /*-------------------------------------------------------------------------*/ static int broken_suspend(struct usb_hcd *hcd) @@ -150,14 +168,11 @@ static int ohci_quirk_nec(struct usb_hcd *hcd) static int ohci_quirk_amd700(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); - struct pci_dev *amd_smbus_dev; u8 rev = 0; - if (usb_amd_find_chipset_info()) - ohci->flags |= OHCI_QUIRK_AMD_PLL; - - amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, - PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); + if (!amd_smbus_dev) + amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, + PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); if (!amd_smbus_dev) return 0; @@ -169,8 +184,19 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd) ohci_dbg(ohci, "enabled AMD prefetch quirk\n"); } - pci_dev_put(amd_smbus_dev); - amd_smbus_dev = NULL; + if ((rev > 0x3b) || (rev < 0x30)) { + pci_dev_put(amd_smbus_dev); + amd_smbus_dev = NULL; + return 0; + } + + amd_ohci_iso_count++; + + if (!amd_hb_dev) + amd_hb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x9600, NULL); + + ohci->flags |= OHCI_QUIRK_AMD_ISO; + ohci_dbg(ohci, "enabled AMD ISO transfers quirk\n"); return 0; } @@ -189,6 +215,74 @@ static int ohci_quirk_nvidia_shutdown(struct usb_hcd *hcd) return 0; } +/* + * The hardware normally enables the A-link power management feature, which + * lets the system lower the power consumption in idle states. + * + * Assume the system is configured to have USB 1.1 ISO transfers going + * to or from a USB device. Without this quirk, that stream may stutter + * or have breaks occasionally. For transfers going to speakers, this + * makes a very audible mess... + * + * That audio playback corruption is due to the audio stream getting + * interrupted occasionally when the link goes in lower power state + * This USB quirk prevents the link going into that lower power state + * during audio playback or other ISO operations. + */ +static void quirk_amd_pll(int on) +{ + u32 addr; + u32 val; + u32 bit = (on > 0) ? 1 : 0; + + pci_read_config_dword(amd_smbus_dev, AB_REG_BAR, &addr); + + /* BIT names/meanings are NDA-protected, sorry ... */ + + outl(AX_INDXC, AB_INDX(addr)); + outl(0x40, AB_DATA(addr)); + outl(AX_DATAC, AB_INDX(addr)); + val = inl(AB_DATA(addr)); + val &= ~((1 << 3) | (1 << 4) | (1 << 9)); + val |= (bit << 3) | ((!bit) << 4) | ((!bit) << 9); + outl(val, AB_DATA(addr)); + + if (amd_hb_dev) { + addr = PCIE_P_CNTL; + pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_ADDR, addr); + + pci_read_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, &val); + val &= ~(1 | (1 << 3) | (1 << 4) | (1 << 9) | (1 << 12)); + val |= bit | (bit << 3) | (bit << 12); + val |= ((!bit) << 4) | ((!bit) << 9); + pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, val); + + addr = BIF_NB; + pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_ADDR, addr); + + pci_read_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, &val); + val &= ~(1 << 8); + val |= bit << 8; + pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, val); + } +} + +static void amd_iso_dev_put(void) +{ + amd_ohci_iso_count--; + if (amd_ohci_iso_count == 0) { + if (amd_smbus_dev) { + pci_dev_put(amd_smbus_dev); + amd_smbus_dev = NULL; + } + if (amd_hb_dev) { + pci_dev_put(amd_hb_dev); + amd_hb_dev = NULL; + } + } + +} + static void sb800_prefetch(struct ohci_hcd *ohci, int on) { struct pci_dev *pdev; diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index dd24fc115e48..83094d067e0f 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -52,7 +52,7 @@ __acquires(ohci->lock) ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--; if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) { if (quirk_amdiso(ohci)) - usb_amd_quirk_pll_enable(); + quirk_amd_pll(1); if (quirk_amdprefetch(ohci)) sb800_prefetch(ohci, 0); } @@ -686,7 +686,7 @@ static void td_submit_urb ( } if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) { if (quirk_amdiso(ohci)) - usb_amd_quirk_pll_disable(); + quirk_amd_pll(0); if (quirk_amdprefetch(ohci)) sb800_prefetch(ohci, 1); } diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index bad11a72c202..51facb985c84 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -401,7 +401,7 @@ struct ohci_hcd { #define OHCI_QUIRK_NEC 0x40 /* lost interrupts */ #define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */ #define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */ -#define OHCI_QUIRK_AMD_PLL 0x200 /* AMD PLL quirk*/ +#define OHCI_QUIRK_AMD_ISO 0x200 /* ISO transfers*/ #define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */ #define OHCI_QUIRK_SHUTDOWN 0x800 /* nVidia power bug */ // there are also chip quirks/bugs in init logic @@ -433,7 +433,7 @@ static inline int quirk_zfmicro(struct ohci_hcd *ohci) } static inline int quirk_amdiso(struct ohci_hcd *ohci) { - return ohci->flags & OHCI_QUIRK_AMD_PLL; + return ohci->flags & OHCI_QUIRK_AMD_ISO; } static inline int quirk_amdprefetch(struct ohci_hcd *ohci) { diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 344b25a790e1..4c502c890ebd 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -52,266 +52,6 @@ #define EHCI_USBLEGCTLSTS 4 /* legacy control/status */ #define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */ -/* AMD quirk use */ -#define AB_REG_BAR_LOW 0xe0 -#define AB_REG_BAR_HIGH 0xe1 -#define AB_REG_BAR_SB700 0xf0 -#define AB_INDX(addr) ((addr) + 0x00) -#define AB_DATA(addr) ((addr) + 0x04) -#define AX_INDXC 0x30 -#define AX_DATAC 0x34 - -#define NB_PCIE_INDX_ADDR 0xe0 -#define NB_PCIE_INDX_DATA 0xe4 -#define PCIE_P_CNTL 0x10040 -#define BIF_NB 0x10002 -#define NB_PIF0_PWRDOWN_0 0x01100012 -#define NB_PIF0_PWRDOWN_1 0x01100013 - -static struct amd_chipset_info { - struct pci_dev *nb_dev; - struct pci_dev *smbus_dev; - int nb_type; - int sb_type; - int isoc_reqs; - int probe_count; - int probe_result; -} amd_chipset; - -static DEFINE_SPINLOCK(amd_lock); - -int usb_amd_find_chipset_info(void) -{ - u8 rev = 0; - unsigned long flags; - - spin_lock_irqsave(&amd_lock, flags); - - amd_chipset.probe_count++; - /* probe only once */ - if (amd_chipset.probe_count > 1) { - spin_unlock_irqrestore(&amd_lock, flags); - return amd_chipset.probe_result; - } - - amd_chipset.smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, 0x4385, NULL); - if (amd_chipset.smbus_dev) { - pci_read_config_byte(amd_chipset.smbus_dev, - PCI_REVISION_ID, &rev); - if (rev >= 0x40) - amd_chipset.sb_type = 1; - else if (rev >= 0x30 && rev <= 0x3b) - amd_chipset.sb_type = 3; - } else { - amd_chipset.smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, - 0x780b, NULL); - if (!amd_chipset.smbus_dev) { - spin_unlock_irqrestore(&amd_lock, flags); - return 0; - } - pci_read_config_byte(amd_chipset.smbus_dev, - PCI_REVISION_ID, &rev); - if (rev >= 0x11 && rev <= 0x18) - amd_chipset.sb_type = 2; - } - - if (amd_chipset.sb_type == 0) { - if (amd_chipset.smbus_dev) { - pci_dev_put(amd_chipset.smbus_dev); - amd_chipset.smbus_dev = NULL; - } - spin_unlock_irqrestore(&amd_lock, flags); - return 0; - } - - amd_chipset.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x9601, NULL); - if (amd_chipset.nb_dev) { - amd_chipset.nb_type = 1; - } else { - amd_chipset.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, - 0x1510, NULL); - if (amd_chipset.nb_dev) { - amd_chipset.nb_type = 2; - } else { - amd_chipset.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, - 0x9600, NULL); - if (amd_chipset.nb_dev) - amd_chipset.nb_type = 3; - } - } - - amd_chipset.probe_result = 1; - printk(KERN_DEBUG "QUIRK: Enable AMD PLL fix\n"); - - spin_unlock_irqrestore(&amd_lock, flags); - return amd_chipset.probe_result; -} -EXPORT_SYMBOL_GPL(usb_amd_find_chipset_info); - -/* - * The hardware normally enables the A-link power management feature, which - * lets the system lower the power consumption in idle states. - * - * This USB quirk prevents the link going into that lower power state - * during isochronous transfers. - * - * Without this quirk, isochronous stream on OHCI/EHCI/xHCI controllers of - * some AMD platforms may stutter or have breaks occasionally. - */ -static void usb_amd_quirk_pll(int disable) -{ - u32 addr, addr_low, addr_high, val; - u32 bit = disable ? 0 : 1; - unsigned long flags; - - spin_lock_irqsave(&amd_lock, flags); - - if (disable) { - amd_chipset.isoc_reqs++; - if (amd_chipset.isoc_reqs > 1) { - spin_unlock_irqrestore(&amd_lock, flags); - return; - } - } else { - amd_chipset.isoc_reqs--; - if (amd_chipset.isoc_reqs > 0) { - spin_unlock_irqrestore(&amd_lock, flags); - return; - } - } - - if (amd_chipset.sb_type == 1 || amd_chipset.sb_type == 2) { - outb_p(AB_REG_BAR_LOW, 0xcd6); - addr_low = inb_p(0xcd7); - outb_p(AB_REG_BAR_HIGH, 0xcd6); - addr_high = inb_p(0xcd7); - addr = addr_high << 8 | addr_low; - - outl_p(0x30, AB_INDX(addr)); - outl_p(0x40, AB_DATA(addr)); - outl_p(0x34, AB_INDX(addr)); - val = inl_p(AB_DATA(addr)); - } else if (amd_chipset.sb_type == 3) { - pci_read_config_dword(amd_chipset.smbus_dev, - AB_REG_BAR_SB700, &addr); - outl(AX_INDXC, AB_INDX(addr)); - outl(0x40, AB_DATA(addr)); - outl(AX_DATAC, AB_INDX(addr)); - val = inl(AB_DATA(addr)); - } else { - spin_unlock_irqrestore(&amd_lock, flags); - return; - } - - if (disable) { - val &= ~0x08; - val |= (1 << 4) | (1 << 9); - } else { - val |= 0x08; - val &= ~((1 << 4) | (1 << 9)); - } - outl_p(val, AB_DATA(addr)); - - if (!amd_chipset.nb_dev) { - spin_unlock_irqrestore(&amd_lock, flags); - return; - } - - if (amd_chipset.nb_type == 1 || amd_chipset.nb_type == 3) { - addr = PCIE_P_CNTL; - pci_write_config_dword(amd_chipset.nb_dev, - NB_PCIE_INDX_ADDR, addr); - pci_read_config_dword(amd_chipset.nb_dev, - NB_PCIE_INDX_DATA, &val); - - val &= ~(1 | (1 << 3) | (1 << 4) | (1 << 9) | (1 << 12)); - val |= bit | (bit << 3) | (bit << 12); - val |= ((!bit) << 4) | ((!bit) << 9); - pci_write_config_dword(amd_chipset.nb_dev, - NB_PCIE_INDX_DATA, val); - - addr = BIF_NB; - pci_write_config_dword(amd_chipset.nb_dev, - NB_PCIE_INDX_ADDR, addr); - pci_read_config_dword(amd_chipset.nb_dev, - NB_PCIE_INDX_DATA, &val); - val &= ~(1 << 8); - val |= bit << 8; - - pci_write_config_dword(amd_chipset.nb_dev, - NB_PCIE_INDX_DATA, val); - } else if (amd_chipset.nb_type == 2) { - addr = NB_PIF0_PWRDOWN_0; - pci_write_config_dword(amd_chipset.nb_dev, - NB_PCIE_INDX_ADDR, addr); - pci_read_config_dword(amd_chipset.nb_dev, - NB_PCIE_INDX_DATA, &val); - if (disable) - val &= ~(0x3f << 7); - else - val |= 0x3f << 7; - - pci_write_config_dword(amd_chipset.nb_dev, - NB_PCIE_INDX_DATA, val); - - addr = NB_PIF0_PWRDOWN_1; - pci_write_config_dword(amd_chipset.nb_dev, - NB_PCIE_INDX_ADDR, addr); - pci_read_config_dword(amd_chipset.nb_dev, - NB_PCIE_INDX_DATA, &val); - if (disable) - val &= ~(0x3f << 7); - else - val |= 0x3f << 7; - - pci_write_config_dword(amd_chipset.nb_dev, - NB_PCIE_INDX_DATA, val); - } - - spin_unlock_irqrestore(&amd_lock, flags); - return; -} - -void usb_amd_quirk_pll_disable(void) -{ - usb_amd_quirk_pll(1); -} -EXPORT_SYMBOL_GPL(usb_amd_quirk_pll_disable); - -void usb_amd_quirk_pll_enable(void) -{ - usb_amd_quirk_pll(0); -} -EXPORT_SYMBOL_GPL(usb_amd_quirk_pll_enable); - -void usb_amd_dev_put(void) -{ - unsigned long flags; - - spin_lock_irqsave(&amd_lock, flags); - - amd_chipset.probe_count--; - if (amd_chipset.probe_count > 0) { - spin_unlock_irqrestore(&amd_lock, flags); - return; - } - - if (amd_chipset.nb_dev) { - pci_dev_put(amd_chipset.nb_dev); - amd_chipset.nb_dev = NULL; - } - if (amd_chipset.smbus_dev) { - pci_dev_put(amd_chipset.smbus_dev); - amd_chipset.smbus_dev = NULL; - } - amd_chipset.nb_type = 0; - amd_chipset.sb_type = 0; - amd_chipset.isoc_reqs = 0; - amd_chipset.probe_result = 0; - - spin_unlock_irqrestore(&amd_lock, flags); -} -EXPORT_SYMBOL_GPL(usb_amd_dev_put); /* * Make sure the controller is completely inactive, unable to diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index 4d2118cf1ff8..1564edfff6fe 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h @@ -1,26 +1,7 @@ #ifndef __LINUX_USB_PCI_QUIRKS_H #define __LINUX_USB_PCI_QUIRKS_H -#ifdef CONFIG_PCI void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); -int usb_amd_find_chipset_info(void); -void usb_amd_dev_put(void); -void usb_amd_quirk_pll_disable(void); -void usb_amd_quirk_pll_enable(void); -#else -static inline void usb_amd_quirk_pll_disable(void) -{ - return; -} -static inline void usb_amd_quirk_pll_enable(void) -{ - return; -} -static inline void usb_amd_dev_put(void) -{ - return; -} -#endif /* CONFIG_PCI */ #endif /* __LINUX_USB_PCI_QUIRKS_H */ -- cgit v1.2.3 From 3c18e30f87ac5466bddbb05cf955605efd7db025 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 17 Feb 2011 10:26:38 -0500 Subject: USB: add quirks entry for Keytouch QWERTY Panel This patch (as1448) adds a quirks entry for the Keytouch QWERTY Panel firmware, used in the IEC 60945 keyboard. This device crashes during enumeration when the computer asks for its configuration string descriptor. Signed-off-by: Alan Stern Tested-by: kholis CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 44c595432d6f..92ce90b83126 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -68,6 +68,10 @@ static const struct usb_device_id usb_quirk_list[] = { /* M-Systems Flash Disk Pioneers */ { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Keytouch QWERTY Panel keyboard */ + { USB_DEVICE(0x0926, 0x3333), .driver_info = + USB_QUIRK_CONFIG_INTF_STRINGS }, + /* X-Rite/Gretag-Macbeth Eye-One Pro display colorimeter */ { USB_DEVICE(0x0971, 0x2000), .driver_info = USB_QUIRK_NO_SET_INTF }, -- cgit v1.2.3 From acb52cb1613e1d3c8a8c650717cc51965c60d7d4 Mon Sep 17 00:00:00 2001 From: Maciej Szmigiero Date: Mon, 7 Feb 2011 12:42:36 +0100 Subject: USB: Add Samsung SGH-I500/Android modem ID switch to visor driver [USB]Add Samsung SGH-I500/Android modem ID switch to visor driver Samsung decided to reuse USB ID of its old CDMA phone SGH-I500 for the modem part of some of their Android phones. At least Galaxy Spica is affected. This modem needs ACM driver and does not work with visor driver which binds the conflicting ID for SGH-I500. Because SGH-I500 is pretty an old hardware its best to add switch to visor driver in cause somebody still wants to use that phone with Linux. Note that this is needed only when using the Android phone as modem, not in USB storage or ADB mode. Signed-off-by: Maciej Szmigiero Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/visor.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 15a5d89b7f39..1c11959a7d58 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "visor.h" /* @@ -479,6 +480,17 @@ static int visor_probe(struct usb_serial *serial, dbg("%s", __func__); + /* + * some Samsung Android phones in modem mode have the same ID + * as SPH-I500, but they are ACM devices, so dont bind to them + */ + if (id->idVendor == SAMSUNG_VENDOR_ID && + id->idProduct == SAMSUNG_SPH_I500_ID && + serial->dev->descriptor.bDeviceClass == USB_CLASS_COMM && + serial->dev->descriptor.bDeviceSubClass == + USB_CDC_SUBCLASS_ACM) + return -ENODEV; + if (serial->dev->actconfig->desc.bConfigurationValue != 1) { dev_err(&serial->dev->dev, "active config #%d != 1 ??\n", serial->dev->actconfig->desc.bConfigurationValue); -- cgit v1.2.3 From 72a012ce0a02c6c616676a24b40ff81d1aaeafda Mon Sep 17 00:00:00 2001 From: Maciej Szmigiero Date: Sat, 5 Feb 2011 21:52:00 +0100 Subject: USB: Add quirk for Samsung Android phone modem My Galaxy Spica needs this quirk when in modem mode, otherwise it causes endless USB bus resets and is unusable in this mode. Unfortunately Samsung decided to reuse ID of its old CDMA phone SGH-I500 for the modem part. That's why in addition to this patch the visor driver must be prevented from binding to SPH-I500 ID, so ACM driver can do that. Signed-off-by: Maciej Szmigiero Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 92ce90b83126..81ce6a8e1d94 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -48,6 +48,10 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x04b4, 0x0526), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS }, + /* Samsung Android phone modem - ID conflict with SPH-I500 */ + { USB_DEVICE(0x04e8, 0x6601), .driver_info = + USB_QUIRK_CONFIG_INTF_STRINGS }, + /* Roland SC-8820 */ { USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME }, -- cgit v1.2.3 From 637d11bfb814637ec7b81e878db3ffea6408a89a Mon Sep 17 00:00:00 2001 From: Luben Tuikov Date: Fri, 11 Feb 2011 11:33:10 -0800 Subject: USB: Reset USB 3.0 devices on (re)discovery If the device isn't reset, the XHCI HCD sends SET ADDRESS to address 0 while the device is already in Addressed state, and the request is dropped on the floor as it is addressed to the default address. This sequence of events, which this patch fixes looks like this: usb_reset_and_verify_device() hub_port_init() hub_set_address() SET_ADDRESS to 0 with 1 usb_get_device_descriptor(udev, 8) usb_get_device_descriptor(udev, 18) descriptors_changed() --> goto re_enumerate: hub_port_logical_disconnect() kick_khubd() And then: hub_events() hub_port_connect_change() usb_disconnect() usb_disable_device() new device struct sets device state to Powered choose_address() hub_port_init() <-- no reset, but SET ADDRESS to 0 with 1, timeout! The solution is to always reset the device in hub_port_init() to put it in a known state. Signed-off-by: Luben Tuikov Cc: Sarah Sharp Cc: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index d041c6826e43..0f299b7aad60 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2681,17 +2681,13 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, mutex_lock(&usb_address0_mutex); - if (!udev->config && oldspeed == USB_SPEED_SUPER) { - /* Don't reset USB 3.0 devices during an initial setup */ - usb_set_device_state(udev, USB_STATE_DEFAULT); - } else { - /* Reset the device; full speed may morph to high speed */ - /* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */ - retval = hub_port_reset(hub, port1, udev, delay); - if (retval < 0) /* error or disconnect */ - goto fail; - /* success, speed is known */ - } + /* Reset the device; full speed may morph to high speed */ + /* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */ + retval = hub_port_reset(hub, port1, udev, delay); + if (retval < 0) /* error or disconnect */ + goto fail; + /* success, speed is known */ + retval = -ENODEV; if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed) { -- cgit v1.2.3 From 38237fd2be9421c104f84cc35665097bdce89013 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 15 Feb 2011 15:55:07 +0100 Subject: USB: serial/usb_wwan, fix tty NULL dereference tty_port_tty_get may return without any problems NULL. Handle this case and do not oops in usb_wwan_indat_callback by dereferencing it. The oops: Unable to handle kernel paging request for data at address 0x000000d8 Faulting instruction address: 0xc0175b3c Oops: Kernel access of bad area, sig: 11 [#1] PowerPC 40x Platform last sysfs file: /sys/devices/pci0000:00/0000:00:00.0/0000:01:00.0/0000:02:09.2/usb1/idVendor Modules linked in: NIP: c0175b3c LR: c0175e7c CTR: c0215c90 REGS: c77f7d50 TRAP: 0300 Not tainted (2.6.37-rc5) MSR: 00021030 CR: 88482028 XER: 2000005f DEAR: 000000d8, ESR: 00000000 TASK = c7141b90[1149] 'wvdial' THREAD: c2750000 GPR00: 00021030 c77f7e00 c7141b90 00000000 0000000e 00000000 0000000e c0410680 GPR08: c683db00 00000000 00000001 c03c81f8 88482028 10073ef4 ffffffb9 ffffff94 GPR16: 00000000 fde036c0 00200200 00100100 00000001 ffffff8d c34fabcc 00000000 GPR24: c71120d4 00000000 00000000 0000000e 00021030 00000000 00000000 0000000e NIP [c0175b3c] tty_buffer_request_room+0x2c/0x194 LR [c0175e7c] tty_insert_flip_string_fixed_flag+0x3c/0xb0 Call Trace: [c77f7e00] [00000003] 0x3 (unreliable) [c77f7e30] [c0175e7c] tty_insert_flip_string_fixed_flag+0x3c/0xb0 [c77f7e60] [c0215df4] usb_wwan_indat_callback+0x164/0x170 ... References: https://bugzilla.kernel.org/show_bug.cgi?id=24582 Cc: Amit Shah Cc: baoyb Signed-off-by: Jiri Slaby Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb_wwan.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index b004b2a485c3..9c014e2ecd68 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -295,12 +295,15 @@ static void usb_wwan_indat_callback(struct urb *urb) __func__, status, endpoint); } else { tty = tty_port_tty_get(&port->port); - if (urb->actual_length) { - tty_insert_flip_string(tty, data, urb->actual_length); - tty_flip_buffer_push(tty); - } else - dbg("%s: empty read urb received", __func__); - tty_kref_put(tty); + if (tty) { + if (urb->actual_length) { + tty_insert_flip_string(tty, data, + urb->actual_length); + tty_flip_buffer_push(tty); + } else + dbg("%s: empty read urb received", __func__); + tty_kref_put(tty); + } /* Resubmit urb so we continue receiving */ if (status != -ESHUTDOWN) { -- cgit v1.2.3 From e1dc5157c574e7249dc1cd072fde2e48b3011533 Mon Sep 17 00:00:00 2001 From: Jon Thomas Date: Wed, 16 Feb 2011 11:02:34 -0500 Subject: sierra: add new ID for Airprime/Sierra USB IP modem I picked up a new Sierra usb 308 (At&t Shockwave) on 2/2011 and the vendor code is 0x0f3d Looking up vendor and product id's I see: 0f3d Airprime, Incorporated 0112 CDMA 1xEVDO PC Card, PC 5220 Sierra and Airprime are somehow related and I'm guessing the At&t usb 308 might be have some common hardware with the AirPrime SL809x. Signed-off-by: Jon Thomas Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 7481ff8a49e4..0457813eebee 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -301,6 +301,9 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist }, + { USB_DEVICE(0x0f3d, 0x68A3), /* Airprime/Sierra Wireless Direct IP modems */ + .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist + }, { USB_DEVICE(0x413C, 0x08133) }, /* Dell Computer Corp. Wireless 5720 VZW Mobile Broadband (EVDO Rev-A) Minicard GPS Port */ { } -- cgit v1.2.3 From ff085de758ebcb2309dd013fecb7cbb3cb6c7a43 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Sun, 6 Feb 2011 17:39:17 +0900 Subject: USB: Gadget: Composite: Debug interface comparison While checking valid interface number we should compare MAX_CONFIG_INTERFACES with the variable 'intf' (which holds the lower 8bits of w_index) rather than 'w_index' Signed-off-by: Jassi Brar Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/composite.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 1ba4befe336b..bbbbfb707504 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -887,7 +887,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) case USB_REQ_SET_INTERFACE: if (ctrl->bRequestType != USB_RECIP_INTERFACE) goto unknown; - if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES) + if (!cdev->config || intf >= MAX_CONFIG_INTERFACES) break; f = cdev->config->interface[intf]; if (!f) @@ -899,7 +899,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) case USB_REQ_GET_INTERFACE: if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)) goto unknown; - if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES) + if (!cdev->config || intf >= MAX_CONFIG_INTERFACES) break; f = cdev->config->interface[intf]; if (!f) @@ -928,7 +928,7 @@ unknown: */ switch (ctrl->bRequestType & USB_RECIP_MASK) { case USB_RECIP_INTERFACE: - if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES) + if (!cdev->config || intf >= MAX_CONFIG_INTERFACES) break; f = cdev->config->interface[intf]; break; -- cgit v1.2.3 From 05c3eebd50ad831c462ec264f82a87654d0ee974 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Sun, 6 Feb 2011 18:47:18 +0900 Subject: USB: Gadget: Reorder driver name assignment Reorder the driver->name assignment so the 'iProduct' could be initialized as well if both 'name' and 'iProduct' come as NULL by default. Also, remove the misplaced 'extern' keyword. Signed-off-by: Jassi Brar Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/composite.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index bbbbfb707504..53e0496c71b5 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1258,16 +1258,16 @@ static struct usb_gadget_driver composite_driver = { * while it was binding. That would usually be done in order to wait for * some userspace participation. */ -extern int usb_composite_probe(struct usb_composite_driver *driver, +int usb_composite_probe(struct usb_composite_driver *driver, int (*bind)(struct usb_composite_dev *cdev)) { if (!driver || !driver->dev || !bind || composite) return -EINVAL; - if (!driver->iProduct) - driver->iProduct = driver->name; if (!driver->name) driver->name = "composite"; + if (!driver->iProduct) + driver->iProduct = driver->name; composite_driver.function = (char *) driver->name; composite_driver.driver.name = driver->name; composite = driver; -- cgit v1.2.3 From c17f459c6ea5b569825445279fa21adb3cf3067f Mon Sep 17 00:00:00 2001 From: Toshiharu Okada Date: Mon, 7 Feb 2011 17:01:26 +0900 Subject: usb: pch_udc: Fixed issue which does not work with g_ether This PCH_UDC driver does not work normally when "Ethernet gadget" is used. This patch fixed this issue. The following was modified. - The FIFO flush process. - The descriptor creation process. - The adjustment of DMA buffer align. Currently the PCH_UDC driver can work normally with "Ethernet gadget", "Serial gadget" or "File-backed Storage Gadget". Signed-off-by: Toshiharu Okada Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/pch_udc.c | 178 +++++++++++++++++++++++++------------------ 1 file changed, 104 insertions(+), 74 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index b120dbb64d0f..3e4b35e50c24 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -367,7 +367,6 @@ struct pch_udc_dev { static const char ep0_string[] = "ep0in"; static DEFINE_SPINLOCK(udc_stall_spinlock); /* stall spin lock */ struct pch_udc_dev *pch_udc; /* pointer to device object */ - static int speed_fs; module_param_named(speed_fs, speed_fs, bool, S_IRUGO); MODULE_PARM_DESC(speed_fs, "true for Full speed operation"); @@ -383,6 +382,8 @@ MODULE_PARM_DESC(speed_fs, "true for Full speed operation"); * @dma_mapped: DMA memory mapped for request * @dma_done: DMA completed for request * @chain_len: chain length + * @buf: Buffer memory for align adjustment + * @dma: DMA memory for align adjustment */ struct pch_udc_request { struct usb_request req; @@ -394,6 +395,8 @@ struct pch_udc_request { dma_mapped:1, dma_done:1; unsigned chain_len; + void *buf; + dma_addr_t dma; }; static inline u32 pch_udc_readl(struct pch_udc_dev *dev, unsigned long reg) @@ -615,7 +618,7 @@ static inline void pch_udc_ep_set_trfr_type(struct pch_udc_ep *ep, /** * pch_udc_ep_set_bufsz() - Set the maximum packet size for the endpoint * @ep: Reference to structure of type pch_udc_ep_regs - * @buf_size: The buffer size + * @buf_size: The buffer word size */ static void pch_udc_ep_set_bufsz(struct pch_udc_ep *ep, u32 buf_size, u32 ep_in) @@ -635,7 +638,7 @@ static void pch_udc_ep_set_bufsz(struct pch_udc_ep *ep, /** * pch_udc_ep_set_maxpkt() - Set the Max packet size for the endpoint * @ep: Reference to structure of type pch_udc_ep_regs - * @pkt_size: The packet size + * @pkt_size: The packet byte size */ static void pch_udc_ep_set_maxpkt(struct pch_udc_ep *ep, u32 pkt_size) { @@ -920,25 +923,10 @@ static void pch_udc_ep_clear_nak(struct pch_udc_ep *ep) */ static void pch_udc_ep_fifo_flush(struct pch_udc_ep *ep, int dir) { - unsigned int loopcnt = 0; - struct pch_udc_dev *dev = ep->dev; - if (dir) { /* IN ep */ pch_udc_ep_bit_set(ep, UDC_EPCTL_ADDR, UDC_EPCTL_F); return; } - - if (pch_udc_read_ep_status(ep) & UDC_EPSTS_MRXFIFO_EMP) - return; - pch_udc_ep_bit_set(ep, UDC_EPCTL_ADDR, UDC_EPCTL_MRXFLUSH); - /* Wait for RxFIFO Empty */ - loopcnt = 10000; - while (!(pch_udc_read_ep_status(ep) & UDC_EPSTS_MRXFIFO_EMP) && - --loopcnt) - udelay(5); - if (!loopcnt) - dev_err(&dev->pdev->dev, "RxFIFO not Empty\n"); - pch_udc_ep_bit_clr(ep, UDC_EPCTL_ADDR, UDC_EPCTL_MRXFLUSH); } /** @@ -1220,14 +1208,31 @@ static void complete_req(struct pch_udc_ep *ep, struct pch_udc_request *req, dev = ep->dev; if (req->dma_mapped) { - if (ep->in) - dma_unmap_single(&dev->pdev->dev, req->req.dma, - req->req.length, DMA_TO_DEVICE); - else - dma_unmap_single(&dev->pdev->dev, req->req.dma, - req->req.length, DMA_FROM_DEVICE); + if (req->dma == DMA_ADDR_INVALID) { + if (ep->in) + dma_unmap_single(&dev->pdev->dev, req->req.dma, + req->req.length, + DMA_TO_DEVICE); + else + dma_unmap_single(&dev->pdev->dev, req->req.dma, + req->req.length, + DMA_FROM_DEVICE); + req->req.dma = DMA_ADDR_INVALID; + } else { + if (ep->in) + dma_unmap_single(&dev->pdev->dev, req->dma, + req->req.length, + DMA_TO_DEVICE); + else { + dma_unmap_single(&dev->pdev->dev, req->dma, + req->req.length, + DMA_FROM_DEVICE); + memcpy(req->req.buf, req->buf, req->req.length); + } + kfree(req->buf); + req->dma = DMA_ADDR_INVALID; + } req->dma_mapped = 0; - req->req.dma = DMA_ADDR_INVALID; } ep->halted = 1; spin_unlock(&dev->lock); @@ -1268,12 +1273,18 @@ static void pch_udc_free_dma_chain(struct pch_udc_dev *dev, struct pch_udc_data_dma_desc *td = req->td_data; unsigned i = req->chain_len; + dma_addr_t addr2; + dma_addr_t addr = (dma_addr_t)td->next; + td->next = 0x00; for (; i > 1; --i) { - dma_addr_t addr = (dma_addr_t)td->next; /* do not free first desc., will be done by free for request */ td = phys_to_virt(addr); + addr2 = (dma_addr_t)td->next; pci_pool_free(dev->data_requests, td, addr); + td->next = 0x00; + addr = addr2; } + req->chain_len = 1; } /** @@ -1301,23 +1312,23 @@ static int pch_udc_create_dma_chain(struct pch_udc_ep *ep, if (req->chain_len > 1) pch_udc_free_dma_chain(ep->dev, req); - for (; ; bytes -= buf_len, ++len) { - if (ep->in) - td->status = PCH_UDC_BS_HST_BSY | min(buf_len, bytes); - else - td->status = PCH_UDC_BS_HST_BSY; + if (req->dma == DMA_ADDR_INVALID) + td->dataptr = req->req.dma; + else + td->dataptr = req->dma; + td->status = PCH_UDC_BS_HST_BSY; + for (; ; bytes -= buf_len, ++len) { + td->status = PCH_UDC_BS_HST_BSY | min(buf_len, bytes); if (bytes <= buf_len) break; - last = td; td = pci_pool_alloc(ep->dev->data_requests, gfp_flags, &dma_addr); if (!td) goto nomem; - i += buf_len; - td->dataptr = req->req.dma + i; + td->dataptr = req->td_data->dataptr + i; last->next = dma_addr; } @@ -1352,28 +1363,15 @@ static int prepare_dma(struct pch_udc_ep *ep, struct pch_udc_request *req, { int retval; - req->td_data->dataptr = req->req.dma; - req->td_data->status |= PCH_UDC_DMA_LAST; /* Allocate and create a DMA chain */ retval = pch_udc_create_dma_chain(ep, req, ep->ep.maxpacket, gfp); if (retval) { - pr_err("%s: could not create DMA chain: %d\n", - __func__, retval); + pr_err("%s: could not create DMA chain:%d\n", __func__, retval); return retval; } - if (!ep->in) - return 0; - if (req->req.length <= ep->ep.maxpacket) - req->td_data->status = PCH_UDC_DMA_LAST | PCH_UDC_BS_HST_BSY | - req->req.length; - /* if bytes < max packet then tx bytes must - * be written in packet per buffer mode - */ - if ((req->req.length < ep->ep.maxpacket) || !ep->num) + if (ep->in) req->td_data->status = (req->td_data->status & - ~PCH_UDC_RXTX_BYTES) | req->req.length; - req->td_data->status = (req->td_data->status & - ~PCH_UDC_BUFF_STS) | PCH_UDC_BS_HST_BSY; + ~PCH_UDC_BUFF_STS) | PCH_UDC_BS_HST_RDY; return 0; } @@ -1529,6 +1527,7 @@ static struct usb_request *pch_udc_alloc_request(struct usb_ep *usbep, if (!req) return NULL; req->req.dma = DMA_ADDR_INVALID; + req->dma = DMA_ADDR_INVALID; INIT_LIST_HEAD(&req->queue); if (!ep->dev->dma_addr) return &req->req; @@ -1613,16 +1612,33 @@ static int pch_udc_pcd_queue(struct usb_ep *usbep, struct usb_request *usbreq, /* map the buffer for dma */ if (usbreq->length && ((usbreq->dma == DMA_ADDR_INVALID) || !usbreq->dma)) { - if (ep->in) - usbreq->dma = dma_map_single(&dev->pdev->dev, - usbreq->buf, - usbreq->length, - DMA_TO_DEVICE); - else - usbreq->dma = dma_map_single(&dev->pdev->dev, - usbreq->buf, - usbreq->length, - DMA_FROM_DEVICE); + if (!((unsigned long)(usbreq->buf) & 0x03)) { + if (ep->in) + usbreq->dma = dma_map_single(&dev->pdev->dev, + usbreq->buf, + usbreq->length, + DMA_TO_DEVICE); + else + usbreq->dma = dma_map_single(&dev->pdev->dev, + usbreq->buf, + usbreq->length, + DMA_FROM_DEVICE); + } else { + req->buf = kzalloc(usbreq->length, GFP_ATOMIC); + if (!req->buf) + return -ENOMEM; + if (ep->in) { + memcpy(req->buf, usbreq->buf, usbreq->length); + req->dma = dma_map_single(&dev->pdev->dev, + req->buf, + usbreq->length, + DMA_TO_DEVICE); + } else + req->dma = dma_map_single(&dev->pdev->dev, + req->buf, + usbreq->length, + DMA_FROM_DEVICE); + } req->dma_mapped = 1; } if (usbreq->length > 0) { @@ -1920,32 +1936,46 @@ static void pch_udc_complete_receiver(struct pch_udc_ep *ep) struct pch_udc_request *req; struct pch_udc_dev *dev = ep->dev; unsigned int count; + struct pch_udc_data_dma_desc *td; + dma_addr_t addr; if (list_empty(&ep->queue)) return; - /* next request */ req = list_entry(ep->queue.next, struct pch_udc_request, queue); - if ((req->td_data_last->status & PCH_UDC_BUFF_STS) != - PCH_UDC_BS_DMA_DONE) - return; pch_udc_clear_dma(ep->dev, DMA_DIR_RX); pch_udc_ep_set_ddptr(ep, 0); - if ((req->td_data_last->status & PCH_UDC_RXTX_STS) != - PCH_UDC_RTS_SUCC) { - dev_err(&dev->pdev->dev, "Invalid RXTX status (0x%08x) " - "epstatus=0x%08x\n", - (req->td_data_last->status & PCH_UDC_RXTX_STS), - (int)(ep->epsts)); - return; - } - count = req->td_data_last->status & PCH_UDC_RXTX_BYTES; + if ((req->td_data_last->status & PCH_UDC_BUFF_STS) == + PCH_UDC_BS_DMA_DONE) + td = req->td_data_last; + else + td = req->td_data; + while (1) { + if ((td->status & PCH_UDC_RXTX_STS) != PCH_UDC_RTS_SUCC) { + dev_err(&dev->pdev->dev, "Invalid RXTX status=0x%08x " + "epstatus=0x%08x\n", + (req->td_data->status & PCH_UDC_RXTX_STS), + (int)(ep->epsts)); + return; + } + if ((td->status & PCH_UDC_BUFF_STS) == PCH_UDC_BS_DMA_DONE) + if (td->status | PCH_UDC_DMA_LAST) { + count = td->status & PCH_UDC_RXTX_BYTES; + break; + } + if (td == req->td_data_last) { + dev_err(&dev->pdev->dev, "Not complete RX descriptor"); + return; + } + addr = (dma_addr_t)td->next; + td = phys_to_virt(addr); + } /* on 64k packets the RXBYTES field is zero */ if (!count && (req->req.length == UDC_DMA_MAXPACKET)) count = UDC_DMA_MAXPACKET; req->td_data->status |= PCH_UDC_DMA_LAST; - req->td_data_last->status |= PCH_UDC_BS_HST_BSY; + td->status |= PCH_UDC_BS_HST_BSY; req->dma_going = 0; req->req.actual = count; -- cgit v1.2.3 From 16f08a08d8148945022eb7d5ebb89e6ee8029f91 Mon Sep 17 00:00:00 2001 From: Fabian Godehardt Date: Mon, 7 Feb 2011 12:53:05 +0200 Subject: USB: s3c2410_udc: Add handling for S3C244X dual-packet mode This is a patch that seems to make the USB hangs on the S3C244X go away. At least a good amount of ping torture didn't make them come back so far. The issue is that, if there are several back-to-back packets, sometimes no interrupt is generated for one of them. This seems to be caused by the mysterious dual packet mode, which the USB hardware enters automatically if the endpoint size is half that of the FIFO. (On the 244X, this is the normal situation for bulk data endpoints.) There is also a timing factor in this. It seems that what happens is that the USB hardware automatically sends an acknowledgement if there is only one packet in the FIFO (the FIFO has space for two). If another packet arrives before the host has retrieved and acknowledged the previous one, no interrupt is generated for that second one. However, there may be an indication. There is one undocumented bit (none of the 244x manuals document it), OUT_CRS1_REG[1], that seems to be set suspiciously often when this condition occurs. There is also CLR_DATA_TOGGLE, OUT_CRS1_REG[7], which may have a function related to this. (The Samsung manual is rather terse on that, as usual.) This needs to be examined further. For now, the patch seems to do the trick. Signed-off-by: Vasily Khoruzhick Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/s3c2410_udc.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index c2448950a8d8..2b025200a69a 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -902,7 +902,7 @@ static irqreturn_t s3c2410_udc_irq(int dummy, void *_dev) int pwr_reg; int ep0csr; int i; - u32 idx; + u32 idx, idx2; unsigned long flags; spin_lock_irqsave(&dev->lock, flags); @@ -1017,6 +1017,20 @@ static irqreturn_t s3c2410_udc_irq(int dummy, void *_dev) } } + /* what else causes this interrupt? a receive! who is it? */ + if (!usb_status && !usbd_status && !pwr_reg && !ep0csr) { + for (i = 1; i < S3C2410_ENDPOINTS; i++) { + idx2 = udc_read(S3C2410_UDC_INDEX_REG); + udc_write(i, S3C2410_UDC_INDEX_REG); + + if (udc_read(S3C2410_UDC_OUT_CSR1_REG) & 0x1) + s3c2410_udc_handle_ep(&dev->ep[i]); + + /* restore index */ + udc_write(idx2, S3C2410_UDC_INDEX_REG); + } + } + dprintk(DEBUG_VERBOSE, "irq: %d s3c2410_udc_done.\n", IRQ_USBD); /* Restore old index */ -- cgit v1.2.3 From 6b2e30c07f6c1514bb9946171770af61c305b86c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 7 Feb 2011 20:01:36 +0300 Subject: usb: fusb300_udc: add more "ep%d" names We need FUSB300_MAX_NUM_EP (16) names otherwise the last 8 names get initialized to garbage values in fusb300_probe(). Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fusb300_udc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c index fd4fd69f5ad6..763d462454b9 100644 --- a/drivers/usb/gadget/fusb300_udc.c +++ b/drivers/usb/gadget/fusb300_udc.c @@ -38,7 +38,8 @@ MODULE_ALIAS("platform:fusb300_udc"); static const char udc_name[] = "fusb300_udc"; static const char * const fusb300_ep_name[] = { - "ep0", "ep1", "ep2", "ep3", "ep4", "ep5", "ep6", "ep7" + "ep0", "ep1", "ep2", "ep3", "ep4", "ep5", "ep6", "ep7", "ep8", "ep9", + "ep10", "ep11", "ep12", "ep13", "ep14", "ep15" }; static void done(struct fusb300_ep *ep, struct fusb300_request *req, -- cgit v1.2.3 From 4f9e6c64d1fc4668f3153f456b41cf40b30c730f Mon Sep 17 00:00:00 2001 From: Maksim Rayskiy Date: Tue, 8 Feb 2011 10:41:42 -0800 Subject: USB: Mark EHCI LPM functions as __maybe_unused ehci_lpm_set_da and ehci_lpm_check are EHCI 1.1 specific functions which are not used on many platforms but do generate annoying gcc warnings Signed-off-by: Maksim Rayskiy Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-lpm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-lpm.c b/drivers/usb/host/ehci-lpm.c index b4d4d63c13ed..2111627a19de 100644 --- a/drivers/usb/host/ehci-lpm.c +++ b/drivers/usb/host/ehci-lpm.c @@ -17,7 +17,8 @@ */ /* this file is part of ehci-hcd.c */ -static int ehci_lpm_set_da(struct ehci_hcd *ehci, int dev_addr, int port_num) +static int __maybe_unused ehci_lpm_set_da(struct ehci_hcd *ehci, + int dev_addr, int port_num) { u32 __iomem portsc; @@ -37,7 +38,7 @@ static int ehci_lpm_set_da(struct ehci_hcd *ehci, int dev_addr, int port_num) * this function is used to check if the device support LPM * if yes, mark the PORTSC register with PORT_LPM bit */ -static int ehci_lpm_check(struct ehci_hcd *ehci, int port) +static int __maybe_unused ehci_lpm_check(struct ehci_hcd *ehci, int port) { u32 __iomem *portsc ; u32 val32; -- cgit v1.2.3 From b14e840d04dba211fbdc930247e379085623eacd Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 8 Feb 2011 21:07:40 +0100 Subject: USB: isp1760: Implement solution for erratum 2 The document says: |2.1 Problem description | When at least two USB devices are simultaneously running, it is observed that | sometimes the INT corresponding to one of the USB devices stops occurring. This may | be observed sometimes with USB-to-serial or USB-to-network devices. | The problem is not noticed when only USB mass storage devices are running. |2.2 Implication | This issue is because of the clearing of the respective Done Map bit on reading the ATL | PTD Done Map register when an INT is generated by another PTD completion, but is not | found set on that read access. In this situation, the respective Done Map bit will remain | reset and no further INT will be asserted so the data transfer corresponding to that USB | device will stop. |2.3 Workaround | An SOF INT can be used instead of an ATL INT with polling on Done bits. A time-out can | be implemented and if a certain Done bit is never set, verification of the PTD completion | can be done by reading PTD contents (valid bit). | This is a proven workaround implemented in software. Russell King run into this with an USB-to-serial converter. This patch implements his suggestion to enable the high frequent SOF interrupt only at the time we have ATL packages queued. It goes even one step further and enables the SOF interrupt only if we have more than one ATL packet queued at the same time. Cc: # [2.6.35.x, 2.6.36.x, 2.6.37.x] Tested-by: Russell King Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp1760-hcd.c | 22 ++++++++++++++++------ drivers/usb/host/isp1760-hcd.h | 1 + 2 files changed, 17 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index bdba8c5d844a..c470cc83dbb0 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -33,6 +33,7 @@ struct isp1760_hcd { struct inter_packet_info atl_ints[32]; struct inter_packet_info int_ints[32]; struct memory_chunk memory_pool[BLOCKS]; + u32 atl_queued; /* periodic schedule support */ #define DEFAULT_I_TDPS 1024 @@ -850,6 +851,11 @@ static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, skip_map &= ~queue_entry; isp1760_writel(skip_map, hcd->regs + HC_ATL_PTD_SKIPMAP_REG); + priv->atl_queued++; + if (priv->atl_queued == 2) + isp1760_writel(INTERRUPT_ENABLE_SOT_MASK, + hcd->regs + HC_INTERRUPT_ENABLE); + buffstatus = isp1760_readl(hcd->regs + HC_BUFFER_STATUS_REG); buffstatus |= ATL_BUFFER; isp1760_writel(buffstatus, hcd->regs + HC_BUFFER_STATUS_REG); @@ -992,6 +998,7 @@ static void do_atl_int(struct usb_hcd *usb_hcd) u32 dw3; status = 0; + priv->atl_queued--; queue_entry = __ffs(done_map); done_map &= ~(1 << queue_entry); @@ -1054,11 +1061,6 @@ static void do_atl_int(struct usb_hcd *usb_hcd) * device is not able to send data fast enough. * This happens mostly on slower hardware. */ - printk(KERN_NOTICE "Reloading ptd %p/%p... qh %p read: " - "%d of %zu done: %08x cur: %08x\n", qtd, - urb, qh, PTD_XFERRED_LENGTH(dw3), - qtd->length, done_map, - (1 << queue_entry)); /* RL counter = ERR counter */ dw3 &= ~(0xf << 19); @@ -1086,6 +1088,11 @@ static void do_atl_int(struct usb_hcd *usb_hcd) priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + atl_regs, sizeof(ptd)); + priv->atl_queued++; + if (priv->atl_queued == 2) + isp1760_writel(INTERRUPT_ENABLE_SOT_MASK, + usb_hcd->regs + HC_INTERRUPT_ENABLE); + buffstatus = isp1760_readl(usb_hcd->regs + HC_BUFFER_STATUS_REG); buffstatus |= ATL_BUFFER; @@ -1191,6 +1198,9 @@ static void do_atl_int(struct usb_hcd *usb_hcd) skip_map = isp1760_readl(usb_hcd->regs + HC_ATL_PTD_SKIPMAP_REG); } + if (priv->atl_queued <= 1) + isp1760_writel(INTERRUPT_ENABLE_MASK, + usb_hcd->regs + HC_INTERRUPT_ENABLE); } static void do_intl_int(struct usb_hcd *usb_hcd) @@ -1770,7 +1780,7 @@ static irqreturn_t isp1760_irq(struct usb_hcd *usb_hcd) goto leave; isp1760_writel(imask, usb_hcd->regs + HC_INTERRUPT_REG); - if (imask & HC_ATL_INT) + if (imask & (HC_ATL_INT | HC_SOT_INT)) do_atl_int(usb_hcd); if (imask & HC_INTL_INT) diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h index 6931ef5c9650..612bce5dce03 100644 --- a/drivers/usb/host/isp1760-hcd.h +++ b/drivers/usb/host/isp1760-hcd.h @@ -69,6 +69,7 @@ void deinit_kmem_cache(void); #define HC_INTERRUPT_ENABLE 0x314 #define INTERRUPT_ENABLE_MASK (HC_INTL_INT | HC_ATL_INT | HC_EOT_INT) +#define INTERRUPT_ENABLE_SOT_MASK (HC_INTL_INT | HC_SOT_INT | HC_EOT_INT) #define HC_ISO_INT (1 << 9) #define HC_ATL_INT (1 << 8) -- cgit v1.2.3 From 8ab10400a037a516cc846c338f879e5bd62497ce Mon Sep 17 00:00:00 2001 From: Rahul Ruikar Date: Wed, 9 Feb 2011 13:44:28 +0100 Subject: usb: gadget: at91_udc: Fix error path In function at91udc_probe() call put_device() when device_register() fails. Signed-off-by: Rahul Ruikar Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/at91_udc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index bdec36acd0fa..bb8ddf0469f9 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -1798,8 +1798,10 @@ static int __init at91udc_probe(struct platform_device *pdev) } retval = device_register(&udc->gadget.dev); - if (retval < 0) + if (retval < 0) { + put_device(&udc->gadget.dev); goto fail0b; + } /* don't do anything until we have both gadget driver and VBUS */ clk_enable(udc->iclk); -- cgit v1.2.3 From c9c4558f7874676e31ea7a74caafcf09ebbc03ed Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 10 Feb 2011 15:33:10 +0100 Subject: usb_wwan: fix error in marking device busy This fixes two errors: - the device is busy if a message was recieved even if resubmission fails - the device is not busy if resubmission fails due to -EPERM Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb_wwan.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index b004b2a485c3..7bd06854f872 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -305,11 +305,16 @@ static void usb_wwan_indat_callback(struct urb *urb) /* Resubmit urb so we continue receiving */ if (status != -ESHUTDOWN) { err = usb_submit_urb(urb, GFP_ATOMIC); - if (err && err != -EPERM) - printk(KERN_ERR "%s: resubmit read urb failed. " - "(%d)", __func__, err); - else + if (err) { + if (err != -EPERM) { + printk(KERN_ERR "%s: resubmit read urb failed. " + "(%d)", __func__, err); + /* busy also in error unless we are killed */ + usb_mark_last_busy(port->serial->dev); + } + } else { usb_mark_last_busy(port->serial->dev); + } } } -- cgit v1.2.3 From 3d06bf152abcc3895a0f3afa21d762d84c9aecbc Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 10 Feb 2011 15:33:17 +0100 Subject: usb_wwan: fix runtime PM in error case An error in the write code path would permanently disable runtime PM in this driver Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb_wwan.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 7bd06854f872..07cdc6cd1064 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -261,6 +261,7 @@ int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, intfdata->in_flight--; spin_unlock_irqrestore(&intfdata->susp_lock, flags); + usb_autopm_put_interface_async(port->serial->interface); continue; } } -- cgit v1.2.3 From 433508ae30f13c0bf6905e576c42899a8535f0bb Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 10 Feb 2011 15:33:23 +0100 Subject: usb_wwan: data consistency in error case As soon as the first error happens, the write must be stopped, lest we send mutilated messages. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb_wwan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 07cdc6cd1064..84fe1b6ba11b 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -262,7 +262,7 @@ int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, spin_unlock_irqrestore(&intfdata->susp_lock, flags); usb_autopm_put_interface_async(port->serial->interface); - continue; + break; } } -- cgit v1.2.3 From 16871dcac74c63227aa92e0012f3004a648c2062 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 10 Feb 2011 15:33:29 +0100 Subject: usb_wwan: error case of resume If an error happens during resumption. The remaining data has to be cleanly discarded and the pm counters have to be adjusted. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb_wwan.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 84fe1b6ba11b..fe5e48eb9693 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -664,6 +664,18 @@ int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message) } EXPORT_SYMBOL(usb_wwan_suspend); +static void unbusy_queued_urb(struct urb *urb, struct usb_wwan_port_private *portdata) +{ + int i; + + for (i = 0; i < N_OUT_URB; i++) { + if (urb == portdata->out_urbs[i]) { + clear_bit(i, &portdata->out_busy); + break; + } + } +} + static void play_delayed(struct usb_serial_port *port) { struct usb_wwan_intf_private *data; @@ -675,8 +687,17 @@ static void play_delayed(struct usb_serial_port *port) data = port->serial->private; while ((urb = usb_get_from_anchor(&portdata->delayed))) { err = usb_submit_urb(urb, GFP_ATOMIC); - if (!err) + if (!err) { data->in_flight++; + } else { + /* we have to throw away the rest */ + do { + unbusy_queued_urb(urb, portdata); + //extremely dirty + atomic_dec(&port->serial->interface->dev.power.usage_count); + } while ((urb = usb_get_from_anchor(&portdata->delayed))); + break; + } } } -- cgit v1.2.3 From 9a91aedca2f4ef24344b7cd8f56570e620fbe4d5 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 10 Feb 2011 15:33:37 +0100 Subject: usb_wwan: fix error case in close() The device never needs to be resumed in close(). But the counters must be balanced. As resumption can fail, but the counters must be balanced, use the _no_resume() version which cannot fail. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb_wwan.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index fe5e48eb9693..817e6ff8de8b 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -424,6 +424,7 @@ int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port) spin_lock_irq(&intfdata->susp_lock); portdata->opened = 1; spin_unlock_irq(&intfdata->susp_lock); + /* this balances a get in the generic USB serial code */ usb_autopm_put_interface(serial->interface); return 0; @@ -450,7 +451,8 @@ void usb_wwan_close(struct usb_serial_port *port) usb_kill_urb(portdata->in_urbs[i]); for (i = 0; i < N_OUT_URB; i++) usb_kill_urb(portdata->out_urbs[i]); - usb_autopm_get_interface(serial->interface); + /* balancing - important as an error cannot be handled*/ + usb_autopm_get_interface_no_resume(serial->interface); serial->interface->needs_remote_wakeup = 0; } } -- cgit v1.2.3 From 5b7c1178eb94f31a0199c3b361722775c54a8db3 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Fri, 11 Feb 2011 12:56:40 +0100 Subject: USB: sierra: error handling in runtime PM resumption of devices can fail. Errors must be handled. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 7481ff8a49e4..2436796e117b 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -373,7 +373,10 @@ static int sierra_send_setup(struct usb_serial_port *port) if (!do_send) return 0; - usb_autopm_get_interface(serial->interface); + retval = usb_autopm_get_interface(serial->interface); + if (retval < 0) + return retval; + retval = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 0x22, 0x21, val, interface, NULL, 0, USB_CTRL_SET_TIMEOUT); usb_autopm_put_interface(serial->interface); @@ -808,8 +811,12 @@ static void sierra_close(struct usb_serial_port *port) mutex_lock(&serial->disc_mutex); if (!serial->disconnected) { serial->interface->needs_remote_wakeup = 0; - usb_autopm_get_interface(serial->interface); - sierra_send_setup(port); + /* odd error handling due to pm counters */ + if (!usb_autopm_get_interface(serial->interface)) + sierra_send_setup(port); + else + usb_autopm_get_interface_no_resume(serial->interface); + } mutex_unlock(&serial->disc_mutex); spin_lock_irq(&intfdata->susp_lock); @@ -862,7 +869,8 @@ static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port) /* get rid of everything as in close */ sierra_close(port); /* restore balance for autopm */ - usb_autopm_put_interface(serial->interface); + if (!serial->disconnected) + usb_autopm_put_interface(serial->interface); return err; } sierra_send_setup(port); -- cgit v1.2.3 From 9812f748a149796cc0299757c3ebf49f0915dc3c Mon Sep 17 00:00:00 2001 From: wwang Date: Tue, 15 Feb 2011 09:38:31 +0800 Subject: usb_storage: realtek_cr patch: fix sparse warning Fix some sparse warning for realtek_cr patch Signed-off-by: wwang Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/realtek_cr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c index c2bebb3731d3..4f6b25fc6bdd 100644 --- a/drivers/usb/storage/realtek_cr.c +++ b/drivers/usb/storage/realtek_cr.c @@ -141,7 +141,7 @@ static int init_realtek_cr(struct us_data *us); .driver_info = (flags)|(USB_US_TYPE_STOR<<24)\ } -struct usb_device_id realtek_cr_ids[] = { +static struct usb_device_id realtek_cr_ids[] = { # include "unusual_realtek.h" { } /* Terminating entry */ }; @@ -570,7 +570,7 @@ static void realtek_cr_destructor(void *extra) } #ifdef CONFIG_PM -void realtek_pm_hook(struct us_data *us, int pm_state) +static void realtek_pm_hook(struct us_data *us, int pm_state) { if (pm_state == US_SUSPEND) (void)config_autodelink_before_power_down(us); -- cgit v1.2.3 From 8a9e658ad3bea034d34e47acc7ea7e5e628fc893 Mon Sep 17 00:00:00 2001 From: wwang Date: Tue, 15 Feb 2011 17:02:47 +0800 Subject: usb_storage: realtek_cr patch: add const modifier Add const modifier before global variable realtek_cr_ids. Signed-off-by: wwang Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/realtek_cr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c index 4f6b25fc6bdd..d509a4a7d74f 100644 --- a/drivers/usb/storage/realtek_cr.c +++ b/drivers/usb/storage/realtek_cr.c @@ -141,7 +141,7 @@ static int init_realtek_cr(struct us_data *us); .driver_info = (flags)|(USB_US_TYPE_STOR<<24)\ } -static struct usb_device_id realtek_cr_ids[] = { +static const struct usb_device_id realtek_cr_ids[] = { # include "unusual_realtek.h" { } /* Terminating entry */ }; -- cgit v1.2.3 From 7018773aca1b46e4f29a8be2c6652448eb603099 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Tue, 15 Feb 2011 09:42:34 +0530 Subject: USB: OTG: msm: Fix compiler warning with CONFIG_PM disabled This patch fixes the below compiler warning drivers/usb/otg/msm72k_otg.c:257: warning: 'msm_otg_suspend' defined but not used Signed-off-by: Pavankumar Kondeti Signed-off-by: Greg Kroah-Hartman --- drivers/usb/otg/msm72k_otg.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/otg/msm72k_otg.c b/drivers/usb/otg/msm72k_otg.c index 1cd52edcd0c2..4d79017c16f3 100644 --- a/drivers/usb/otg/msm72k_otg.c +++ b/drivers/usb/otg/msm72k_otg.c @@ -253,6 +253,9 @@ static int msm_otg_reset(struct otg_transceiver *otg) } #define PHY_SUSPEND_TIMEOUT_USEC (500 * 1000) +#define PHY_RESUME_TIMEOUT_USEC (100 * 1000) + +#ifdef CONFIG_PM_SLEEP static int msm_otg_suspend(struct msm_otg *motg) { struct otg_transceiver *otg = &motg->otg; @@ -334,7 +337,6 @@ static int msm_otg_suspend(struct msm_otg *motg) return 0; } -#define PHY_RESUME_TIMEOUT_USEC (100 * 1000) static int msm_otg_resume(struct msm_otg *motg) { struct otg_transceiver *otg = &motg->otg; @@ -399,6 +401,7 @@ skip_phy_resume: return 0; } +#endif static void msm_otg_start_host(struct otg_transceiver *otg, int on) { @@ -972,7 +975,7 @@ static int __devexit msm_otg_remove(struct platform_device *pdev) msm_otg_debugfs_cleanup(); cancel_work_sync(&motg->sm_work); - msm_otg_resume(motg); + pm_runtime_resume(&pdev->dev); device_init_wakeup(&pdev->dev, 0); pm_runtime_disable(&pdev->dev); @@ -1050,13 +1053,9 @@ static int msm_otg_runtime_resume(struct device *dev) dev_dbg(dev, "OTG runtime resume\n"); return msm_otg_resume(motg); } -#else -#define msm_otg_runtime_idle NULL -#define msm_otg_runtime_suspend NULL -#define msm_otg_runtime_resume NULL #endif -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int msm_otg_pm_suspend(struct device *dev) { struct msm_otg *motg = dev_get_drvdata(dev); @@ -1086,25 +1085,24 @@ static int msm_otg_pm_resume(struct device *dev) return 0; } -#else -#define msm_otg_pm_suspend NULL -#define msm_otg_pm_resume NULL #endif +#ifdef CONFIG_PM static const struct dev_pm_ops msm_otg_dev_pm_ops = { - .runtime_suspend = msm_otg_runtime_suspend, - .runtime_resume = msm_otg_runtime_resume, - .runtime_idle = msm_otg_runtime_idle, - .suspend = msm_otg_pm_suspend, - .resume = msm_otg_pm_resume, + SET_SYSTEM_SLEEP_PM_OPS(msm_otg_pm_suspend, msm_otg_pm_resume) + SET_RUNTIME_PM_OPS(msm_otg_runtime_suspend, msm_otg_runtime_resume, + msm_otg_runtime_idle) }; +#endif static struct platform_driver msm_otg_driver = { .remove = __devexit_p(msm_otg_remove), .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, +#ifdef CONFIG_PM .pm = &msm_otg_dev_pm_ops, +#endif }, }; -- cgit v1.2.3 From e2904ee43c7009e6c4fc18738f15051312f22483 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Tue, 15 Feb 2011 09:42:35 +0530 Subject: USB: OTG: msm: Fix bug in msm_otg_mode_write The driver private data is retrieved incorrectly which results a crash when written into "mode" debugfs file. Signed-off-by: Pavankumar Kondeti Signed-off-by: Greg Kroah-Hartman --- drivers/usb/otg/msm72k_otg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/otg/msm72k_otg.c b/drivers/usb/otg/msm72k_otg.c index 4d79017c16f3..296598628b85 100644 --- a/drivers/usb/otg/msm72k_otg.c +++ b/drivers/usb/otg/msm72k_otg.c @@ -723,7 +723,8 @@ static int msm_otg_mode_open(struct inode *inode, struct file *file) static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) { - struct msm_otg *motg = file->private_data; + struct seq_file *s = file->private_data; + struct msm_otg *motg = s->private; char buf[16]; struct otg_transceiver *otg = &motg->otg; int status = count; -- cgit v1.2.3 From bcf40815e0cda371cecc242398fe39b873bb1047 Mon Sep 17 00:00:00 2001 From: Matthieu CASTET Date: Tue, 15 Feb 2011 18:40:28 +0100 Subject: USB: don't run ehci_reset in ehci_run for tdi device TDI driver does the ehci_reset in their reset callback. Don't reset in ehci_run because configuration settings done in platform driver will be reset. This will allow to make msm use ehci_run. Signed-off-by: Matthieu CASTET Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 7 ++++++- drivers/usb/host/ehci-orion.c | 5 +++-- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 74dcf49bd015..4c77a818fd80 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -679,7 +679,12 @@ static int ehci_run (struct usb_hcd *hcd) hcd->uses_new_polling = 1; /* EHCI spec section 4.1 */ - if ((retval = ehci_reset(ehci)) != 0) { + /* + * TDI driver does the ehci_reset in their reset callback. + * Don't reset here, because configuration settings will + * vanish. + */ + if (!ehci_is_TDI(ehci) && (retval = ehci_reset(ehci)) != 0) { ehci_mem_cleanup(ehci); return retval; } diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 0f87dc72820a..281e094e1c18 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -105,7 +105,8 @@ static int ehci_orion_setup(struct usb_hcd *hcd) struct ehci_hcd *ehci = hcd_to_ehci(hcd); int retval; - ehci_reset(ehci); + hcd->has_tt = 1; + retval = ehci_halt(ehci); if (retval) return retval; @@ -117,7 +118,7 @@ static int ehci_orion_setup(struct usb_hcd *hcd) if (retval) return retval; - hcd->has_tt = 1; + ehci_reset(ehci); ehci_port_power(ehci, 0); -- cgit v1.2.3 From 5c8d61bfcc6396f80b884e0f23f08cbd8bf10778 Mon Sep 17 00:00:00 2001 From: Matthieu CASTET Date: Tue, 15 Feb 2011 18:41:54 +0100 Subject: USB: make ehci msm driver use ehci_run. Now that ehci_run don't call ehci_reset, we can use ehci_run. Signed-off-by: Matthieu CASTET Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-msm.c | 92 +++------------------------------------------ 1 file changed, 5 insertions(+), 87 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index 413f4deca532..a80001420e3e 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -34,92 +34,6 @@ static struct otg_transceiver *otg; -/* - * ehci_run defined in drivers/usb/host/ehci-hcd.c reset the controller and - * the configuration settings in ehci_msm_reset vanish after controller is - * reset. Resetting the controler in ehci_run seems to be un-necessary - * provided HCD reset the controller before calling ehci_run. Most of the HCD - * do but some are not. So this function is same as ehci_run but we don't - * reset the controller here. - */ -static int ehci_msm_run(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - u32 temp; - u32 hcc_params; - - hcd->uses_new_polling = 1; - - ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list); - ehci_writel(ehci, (u32)ehci->async->qh_dma, &ehci->regs->async_next); - - /* - * hcc_params controls whether ehci->regs->segment must (!!!) - * be used; it constrains QH/ITD/SITD and QTD locations. - * pci_pool consistent memory always uses segment zero. - * streaming mappings for I/O buffers, like pci_map_single(), - * can return segments above 4GB, if the device allows. - * - * NOTE: the dma mask is visible through dma_supported(), so - * drivers can pass this info along ... like NETIF_F_HIGHDMA, - * Scsi_Host.highmem_io, and so forth. It's readonly to all - * host side drivers though. - */ - hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params); - if (HCC_64BIT_ADDR(hcc_params)) - ehci_writel(ehci, 0, &ehci->regs->segment); - - /* - * Philips, Intel, and maybe others need CMD_RUN before the - * root hub will detect new devices (why?); NEC doesn't - */ - ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET); - ehci->command |= CMD_RUN; - ehci_writel(ehci, ehci->command, &ehci->regs->command); - dbg_cmd(ehci, "init", ehci->command); - - /* - * Start, enabling full USB 2.0 functionality ... usb 1.1 devices - * are explicitly handed to companion controller(s), so no TT is - * involved with the root hub. (Except where one is integrated, - * and there's no companion controller unless maybe for USB OTG.) - * - * Turning on the CF flag will transfer ownership of all ports - * from the companions to the EHCI controller. If any of the - * companions are in the middle of a port reset at the time, it - * could cause trouble. Write-locking ehci_cf_port_reset_rwsem - * guarantees that no resets are in progress. After we set CF, - * a short delay lets the hardware catch up; new resets shouldn't - * be started before the port switching actions could complete. - */ - down_write(&ehci_cf_port_reset_rwsem); - hcd->state = HC_STATE_RUNNING; - ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); - ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ - usleep_range(5000, 5500); - up_write(&ehci_cf_port_reset_rwsem); - ehci->last_periodic_enable = ktime_get_real(); - - temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); - ehci_info(ehci, - "USB %x.%x started, EHCI %x.%02x%s\n", - ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), - temp >> 8, temp & 0xff, - ignore_oc ? ", overcurrent ignored" : ""); - - ehci_writel(ehci, INTR_MASK, - &ehci->regs->intr_enable); /* Turn On Interrupts */ - - /* GRR this is run-once init(), being done every time the HC starts. - * So long as they're part of class devices, we can't do it init() - * since the class device isn't created that early. - */ - create_debug_files(ehci); - create_companion_file(ehci); - - return 0; -} - static int ehci_msm_reset(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); @@ -135,6 +49,10 @@ static int ehci_msm_reset(struct usb_hcd *hcd) hcd->has_tt = 1; ehci->sbrn = HCD_USB2; + retval = ehci_halt(ehci); + if (retval) + return retval; + /* data structure init */ retval = ehci_init(hcd); if (retval) @@ -167,7 +85,7 @@ static struct hc_driver msm_hc_driver = { .flags = HCD_USB2 | HCD_MEMORY, .reset = ehci_msm_reset, - .start = ehci_msm_run, + .start = ehci_run, .stop = ehci_stop, .shutdown = ehci_shutdown, -- cgit v1.2.3 From 04b31c776f34d127b422da92899272a0b8cda21d Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Wed, 16 Feb 2011 23:47:51 +0900 Subject: usb: isp1362-hcd: use bitmap_clear() and bitmap_set() Use bitmap_set()/bitmap_clear() to fill/zero a region of a bitmap instead of doing set_bit()/clear_bit() each bit. Signed-off-by: Akinobu Mita Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp1362-hcd.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 43a39eb56cc6..02b742df332a 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c @@ -226,7 +226,6 @@ static int claim_ptd_buffers(struct isp1362_ep_queue *epq, static inline void release_ptd_buffers(struct isp1362_ep_queue *epq, struct isp1362_ep *ep) { - int index = ep->ptd_index; int last = ep->ptd_index + ep->num_ptds; if (last > epq->buf_count) @@ -236,10 +235,8 @@ static inline void release_ptd_buffers(struct isp1362_ep_queue *epq, struct isp1 epq->buf_map, epq->skip_map); BUG_ON(last > epq->buf_count); - for (; index < last; index++) { - __clear_bit(index, &epq->buf_map); - __set_bit(index, &epq->skip_map); - } + bitmap_clear(&epq->buf_map, ep->ptd_index, ep->num_ptds); + bitmap_set(&epq->skip_map, ep->ptd_index, ep->num_ptds); epq->buf_avail += ep->num_ptds; epq->ptd_count--; -- cgit v1.2.3 From 19b9a83e214d3d3ac52a56daca5ea0d033ca47bc Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 11 Feb 2011 16:57:08 +0100 Subject: USB: musb: omap2430: fix kernel panic on reboot Cancel idle timer in musb_platform_exit. The idle timer could trigger after clock had been disabled leading to kernel panic when MUSB_DEVCTL is accessed in musb_do_idle on 2.6.37. The fault below is no longer triggered on 2.6.38-rc4 (clock is disabled later, and only if compiled as a module, and the offending memory access has moved) but the timer should be cancelled nonetheless. Rebooting... musb_hdrc musb_hdrc: remove, state 4 usb usb1: USB disconnect, address 1 musb_hdrc musb_hdrc: USB bus 1 deregistered Unhandled fault: external abort on non-linefetch (0x1028) at 0xfa0ab060 Internal error: : 1028 [#1] PREEMPT last sysfs file: /sys/kernel/uevent_seqnum Modules linked in: CPU: 0 Not tainted (2.6.37+ #6) PC is at musb_do_idle+0x24/0x138 LR is at musb_do_idle+0x18/0x138 pc : [] lr : [] psr: 80000193 sp : cf2bdd80 ip : cf2bdd80 fp : c048a20c r10: c048a60c r9 : c048a40c r8 : cf85e110 r7 : cf2bc000 r6 : 40000113 r5 : c0489800 r4 : cf85e110 r3 : 00000004 r2 : 00000006 r1 : fa0ab000 r0 : cf8a7000 Flags: Nzcv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user Control: 10c5387d Table: 8faac019 DAC: 00000015 Process reboot (pid: 769, stack limit = 0xcf2bc2f0) Stack: (0xcf2bdd80 to 0xcf2be000) dd80: 00000103 c0489800 c02377b4 c005fa34 00000555 c0071a8c c04a3858 cf2bdda8 dda0: 00000555 c048a00c cf2bdda8 cf2bdda8 1838beb0 00000103 00000004 cf2bc000 ddc0: 00000001 00000001 c04896c8 0000000a 00000000 c005ac14 00000001 c003f32c dde0: 00000000 00000025 00000000 cf2bc000 00000002 00000001 cf2bc000 00000000 de00: 00000001 c005ad08 cf2bc000 c002e07c c03ec039 ffffffff fa200000 c0033608 de20: 00000001 00000000 cf852c14 cf81f200 c045b714 c045b708 cf2bc000 c04a37e8 de40: c0033c04 cf2bc000 00000000 00000001 cf2bde68 cf2bde68 c01c3abc c004f7d8 de60: 60000013 ffffffff c0033c04 00000000 01234567 fee1dead 00000000 c006627c de80: 00000001 c00662c8 28121969 c00663ec cfa38c40 cf9f6a00 cf2bded0 cf9f6a0c dea0: 00000000 cf92f000 00008914 c02cd284 c04a55c8 c028b398 c00715c0 becf24a8 dec0: 30687465 00000000 00000000 00000000 00000002 1301a8c0 00000000 00000000 dee0: 00000002 1301a8c0 00000000 00000000 c0450494 cf527920 00011f10 cf2bdf08 df00: 00011f10 cf2bdf10 00011f10 cf2bdf18 c00f0b44 c004f7e8 cf2bdf18 cf2bdf18 df20: 00011f10 cf2bdf30 00011f10 cf2bdf38 cf401300 cf486100 00000008 c00d2b28 df40: 00011f10 cf401300 00200200 c00d3388 00011f10 cfb63a88 cfb63a80 c00c2f08 df60: 00000000 00000000 cfb63a80 00000000 cf0a3480 00000006 c0033c04 cfb63a80 df80: 00000000 c00c0104 00000003 cf0a3480 cfb63a80 00000000 00000001 00000004 dfa0: 00000058 c0033a80 00000000 00000001 fee1dead 28121969 01234567 00000000 dfc0: 00000000 00000001 00000004 00000058 00000001 00000001 00000000 00000001 dfe0: 4024d200 becf2cb0 00009210 4024d218 60000010 fee1dead 00000000 00000000 [] (musb_do_idle+0x24/0x138) from [] (run_timer_softirq+0x1a8/0x26) [] (run_timer_softirq+0x1a8/0x26c) from [] (__do_softirq+0x88/0x13) [] (__do_softirq+0x88/0x138) from [] (irq_exit+0x44/0x98) [] (irq_exit+0x44/0x98) from [] (asm_do_IRQ+0x7c/0xa0) [] (asm_do_IRQ+0x7c/0xa0) from [] (__irq_svc+0x48/0xa8) Exception stack(0xcf2bde20 to 0xcf2bde68) de20: 00000001 00000000 cf852c14 cf81f200 c045b714 c045b708 cf2bc000 c04a37e8 de40: c0033c04 cf2bc000 00000000 00000001 cf2bde68 cf2bde68 c01c3abc c004f7d8 de60: 60000013 ffffffff [] (__irq_svc+0x48/0xa8) from [] (sub_preempt_count+0x0/0xb8) Code: ebf86030 e5940098 e594108c e5902010 (e5d13060) ---[ end trace 3689c0d808f9bf7c ]--- Kernel panic - not syncing: Fatal exception in interrupt Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/omap2430.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index a3f12333fc41..bc8badd16897 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -362,6 +362,7 @@ static int omap2430_musb_init(struct musb *musb) static int omap2430_musb_exit(struct musb *musb) { + del_timer_sync(&musb_idle_timer); omap2430_low_level_exit(musb); otg_put_transceiver(musb->xceiv); -- cgit v1.2.3 From 75a14b1434a0ca409bcc8ab9b6b2e680796c487e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 16 Feb 2011 12:27:54 +0200 Subject: usb: musb: do not error out if Kconfig doesn't match board mode During development, even though board is wired to e.g. OTG, we might want to compile host-only or peripheral-only configurations. Let's allow that to happen. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 25 ------------------------- 1 file changed, 25 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 54a8bd1047d6..bc296557dc1b 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1949,31 +1949,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) goto fail0; } - switch (plat->mode) { - case MUSB_HOST: -#ifdef CONFIG_USB_MUSB_HDRC_HCD - break; -#else - goto bad_config; -#endif - case MUSB_PERIPHERAL: -#ifdef CONFIG_USB_GADGET_MUSB_HDRC - break; -#else - goto bad_config; -#endif - case MUSB_OTG: -#ifdef CONFIG_USB_MUSB_OTG - break; -#else -bad_config: -#endif - default: - dev_err(dev, "incompatible Kconfig role setting\n"); - status = -EINVAL; - goto fail0; - } - /* allocate */ musb = allocate_instance(dev, plat->config, ctrl); if (!musb) { -- cgit v1.2.3 From 63eed2b52494e35aaf38ac2db537d6ea0a55b0da Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 17 Jan 2011 10:34:38 +0200 Subject: usb: musb: gadget: beautify usb_gadget_probe_driver()/usb_gadget_unregister_driver Just a few cosmetic fixes to usb_gadget_probe_driver() and usb_gadget_unregister_driver(). Decreased a few indentation levels with goto statements. While at that, also add the missing call to musb_stop(). If we don't have OTG, there's no point of leaving MUSB prepared for operation if a gadget driver fails to probe. The same is valid for usb_gadget_unregister_driver(), since we are removing the gadget driver and we don't have OTG, we can completely unconfigure MUSB. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 150 ++++++++++++++++++++++------------------- 1 file changed, 79 insertions(+), 71 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 2fe304611dcf..86decba48f28 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1801,90 +1801,95 @@ void musb_gadget_cleanup(struct musb *musb) int usb_gadget_probe_driver(struct usb_gadget_driver *driver, int (*bind)(struct usb_gadget *)) { - int retval; - unsigned long flags; - struct musb *musb = the_gadget; + struct musb *musb = the_gadget; + unsigned long flags; + int retval = -EINVAL; if (!driver || driver->speed != USB_SPEED_HIGH || !bind || !driver->setup) - return -EINVAL; + goto err0; /* driver must be initialized to support peripheral mode */ if (!musb) { DBG(1, "%s, no dev??\n", __func__); - return -ENODEV; + retval = -ENODEV; + goto err0; } DBG(3, "registering driver %s\n", driver->function); - spin_lock_irqsave(&musb->lock, flags); if (musb->gadget_driver) { DBG(1, "%s is already bound to %s\n", musb_driver_name, musb->gadget_driver->driver.name); retval = -EBUSY; - } else { - musb->gadget_driver = driver; - musb->g.dev.driver = &driver->driver; - driver->driver.bus = NULL; - musb->softconnect = 1; - retval = 0; + goto err0; } + spin_lock_irqsave(&musb->lock, flags); + musb->gadget_driver = driver; + musb->g.dev.driver = &driver->driver; + driver->driver.bus = NULL; + musb->softconnect = 1; spin_unlock_irqrestore(&musb->lock, flags); - if (retval == 0) { - retval = bind(&musb->g); - if (retval != 0) { - DBG(3, "bind to driver %s failed --> %d\n", - driver->driver.name, retval); - musb->gadget_driver = NULL; - musb->g.dev.driver = NULL; - } + retval = bind(&musb->g); + if (retval) { + DBG(3, "bind to driver %s failed --> %d\n", + driver->driver.name, retval); + goto err1; + } - spin_lock_irqsave(&musb->lock, flags); + spin_lock_irqsave(&musb->lock, flags); - otg_set_peripheral(musb->xceiv, &musb->g); - musb->xceiv->state = OTG_STATE_B_IDLE; - musb->is_active = 1; + otg_set_peripheral(musb->xceiv, &musb->g); + musb->xceiv->state = OTG_STATE_B_IDLE; + musb->is_active = 1; - /* FIXME this ignores the softconnect flag. Drivers are - * allowed hold the peripheral inactive until for example - * userspace hooks up printer hardware or DSP codecs, so - * hosts only see fully functional devices. - */ + /* + * FIXME this ignores the softconnect flag. Drivers are + * allowed hold the peripheral inactive until for example + * userspace hooks up printer hardware or DSP codecs, so + * hosts only see fully functional devices. + */ - if (!is_otg_enabled(musb)) - musb_start(musb); + if (!is_otg_enabled(musb)) + musb_start(musb); - otg_set_peripheral(musb->xceiv, &musb->g); + otg_set_peripheral(musb->xceiv, &musb->g); - spin_unlock_irqrestore(&musb->lock, flags); + spin_unlock_irqrestore(&musb->lock, flags); - if (is_otg_enabled(musb)) { - struct usb_hcd *hcd = musb_to_hcd(musb); + if (is_otg_enabled(musb)) { + struct usb_hcd *hcd = musb_to_hcd(musb); - DBG(3, "OTG startup...\n"); + DBG(3, "OTG startup...\n"); - /* REVISIT: funcall to other code, which also - * handles power budgeting ... this way also - * ensures HdrcStart is indirectly called. - */ - retval = usb_add_hcd(musb_to_hcd(musb), -1, 0); - if (retval < 0) { - DBG(1, "add_hcd failed, %d\n", retval); - spin_lock_irqsave(&musb->lock, flags); - otg_set_peripheral(musb->xceiv, NULL); - musb->gadget_driver = NULL; - musb->g.dev.driver = NULL; - spin_unlock_irqrestore(&musb->lock, flags); - } else { - hcd->self.uses_pio_for_control = 1; - } + /* REVISIT: funcall to other code, which also + * handles power budgeting ... this way also + * ensures HdrcStart is indirectly called. + */ + retval = usb_add_hcd(musb_to_hcd(musb), -1, 0); + if (retval < 0) { + DBG(1, "add_hcd failed, %d\n", retval); + goto err2; } + + hcd->self.uses_pio_for_control = 1; } + return 0; + +err2: + if (!is_otg_enabled(musb)) + musb_stop(musb); + +err1: + musb->gadget_driver = NULL; + musb->g.dev.driver = NULL; + +err0: return retval; } EXPORT_SYMBOL(usb_gadget_probe_driver); @@ -1939,14 +1944,17 @@ static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver) */ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) { - unsigned long flags; - int retval = 0; struct musb *musb = the_gadget; + unsigned long flags; if (!driver || !driver->unbind || !musb) return -EINVAL; - /* REVISIT always use otg_set_peripheral() here too; + if (!musb->gadget_driver) + return -EINVAL; + + /* + * REVISIT always use otg_set_peripheral() here too; * this needs to shut down the OTG engine. */ @@ -1956,29 +1964,26 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) musb_hnp_stop(musb); #endif - if (musb->gadget_driver == driver) { + (void) musb_gadget_vbus_draw(&musb->g, 0); - (void) musb_gadget_vbus_draw(&musb->g, 0); + musb->xceiv->state = OTG_STATE_UNDEFINED; + stop_activity(musb, driver); + otg_set_peripheral(musb->xceiv, NULL); - musb->xceiv->state = OTG_STATE_UNDEFINED; - stop_activity(musb, driver); - otg_set_peripheral(musb->xceiv, NULL); + DBG(3, "unregistering driver %s\n", driver->function); - DBG(3, "unregistering driver %s\n", driver->function); - spin_unlock_irqrestore(&musb->lock, flags); - driver->unbind(&musb->g); - spin_lock_irqsave(&musb->lock, flags); + spin_unlock_irqrestore(&musb->lock, flags); + driver->unbind(&musb->g); + spin_lock_irqsave(&musb->lock, flags); - musb->gadget_driver = NULL; - musb->g.dev.driver = NULL; + musb->gadget_driver = NULL; + musb->g.dev.driver = NULL; - musb->is_active = 0; - musb_platform_try_idle(musb, 0); - } else - retval = -EINVAL; + musb->is_active = 0; + musb_platform_try_idle(musb, 0); spin_unlock_irqrestore(&musb->lock, flags); - if (is_otg_enabled(musb) && retval == 0) { + if (is_otg_enabled(musb)) { usb_remove_hcd(musb_to_hcd(musb)); /* FIXME we need to be able to register another * gadget driver here and have everything work; @@ -1986,7 +1991,10 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) */ } - return retval; + if (!is_otg_enabled(musb)) + musb_stop(musb); + + return 0; } EXPORT_SYMBOL(usb_gadget_unregister_driver); -- cgit v1.2.3 From ad1adb89a0d9410345d573b6995a1fa9f9b7c74a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 16 Feb 2011 12:40:05 +0200 Subject: usb: musb: gadget: do not poke with gadget's list_head struct usb_request's list_head is supposed to be used only by gadget drivers, but musb is abusing that. Give struct musb_request its own list_head and prevent musb from poking into other driver's business. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.h | 4 ++-- drivers/usb/musb/musb_gadget.c | 37 ++++++++++++++++++++----------------- drivers/usb/musb/musb_gadget.h | 7 +++++-- drivers/usb/musb/musb_gadget_ep0.c | 24 ++++++++++++++---------- 4 files changed, 41 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index d74a8113ae74..2c8dde6d23e0 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -328,7 +328,7 @@ struct musb_hw_ep { #endif }; -static inline struct usb_request *next_in_request(struct musb_hw_ep *hw_ep) +static inline struct musb_request *next_in_request(struct musb_hw_ep *hw_ep) { #ifdef CONFIG_USB_GADGET_MUSB_HDRC return next_request(&hw_ep->ep_in); @@ -337,7 +337,7 @@ static inline struct usb_request *next_in_request(struct musb_hw_ep *hw_ep) #endif } -static inline struct usb_request *next_out_request(struct musb_hw_ep *hw_ep) +static inline struct musb_request *next_out_request(struct musb_hw_ep *hw_ep) { #ifdef CONFIG_USB_GADGET_MUSB_HDRC return next_request(&hw_ep->ep_out); diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 86decba48f28..0f59bf935c85 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -189,7 +189,7 @@ __acquires(ep->musb->lock) req = to_musb_request(request); - list_del(&request->list); + list_del(&req->list); if (req->request.status == -EINPROGRESS) req->request.status = status; musb = req->musb; @@ -251,9 +251,8 @@ static void nuke(struct musb_ep *ep, const int status) ep->dma = NULL; } - while (!list_empty(&(ep->req_list))) { - req = container_of(ep->req_list.next, struct musb_request, - request.list); + while (!list_empty(&ep->req_list)) { + req = list_first_entry(&ep->req_list, struct musb_request, list); musb_g_giveback(ep, &req->request, status); } } @@ -485,6 +484,7 @@ static void txstate(struct musb *musb, struct musb_request *req) void musb_g_tx(struct musb *musb, u8 epnum) { u16 csr; + struct musb_request *req; struct usb_request *request; u8 __iomem *mbase = musb->mregs; struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_in; @@ -492,7 +492,8 @@ void musb_g_tx(struct musb *musb, u8 epnum) struct dma_channel *dma; musb_ep_select(mbase, epnum); - request = next_request(musb_ep); + req = next_request(musb_ep); + request = &req->request; csr = musb_readw(epio, MUSB_TXCSR); DBG(4, "<== %s, txcsr %04x\n", musb_ep->end_point.name, csr); @@ -571,15 +572,15 @@ void musb_g_tx(struct musb *musb, u8 epnum) if (request->actual == request->length) { musb_g_giveback(musb_ep, request, 0); - request = musb_ep->desc ? next_request(musb_ep) : NULL; - if (!request) { + req = musb_ep->desc ? next_request(musb_ep) : NULL; + if (!req) { DBG(4, "%s idle now\n", musb_ep->end_point.name); return; } } - txstate(musb, to_musb_request(request)); + txstate(musb, req); } } @@ -821,6 +822,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) void musb_g_rx(struct musb *musb, u8 epnum) { u16 csr; + struct musb_request *req; struct usb_request *request; void __iomem *mbase = musb->mregs; struct musb_ep *musb_ep; @@ -835,10 +837,12 @@ void musb_g_rx(struct musb *musb, u8 epnum) musb_ep_select(mbase, epnum); - request = next_request(musb_ep); - if (!request) + req = next_request(musb_ep); + if (!req) return; + request = &req->request; + csr = musb_readw(epio, MUSB_RXCSR); dma = is_dma_capable() ? musb_ep->dma : NULL; @@ -914,15 +918,15 @@ void musb_g_rx(struct musb *musb, u8 epnum) #endif musb_g_giveback(musb_ep, request, 0); - request = next_request(musb_ep); - if (!request) + req = next_request(musb_ep); + if (!req) return; } #if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA) exit: #endif /* Analyze request */ - rxstate(musb, to_musb_request(request)); + rxstate(musb, req); } /* ------------------------------------------------------------ */ @@ -1171,7 +1175,6 @@ struct usb_request *musb_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) return NULL; } - INIT_LIST_HEAD(&request->request.list); request->request.dma = DMA_ADDR_INVALID; request->epnum = musb_ep->current_epnum; request->ep = musb_ep; @@ -1257,10 +1260,10 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req, } /* add request to the list */ - list_add_tail(&(request->request.list), &(musb_ep->req_list)); + list_add_tail(&request->list, &musb_ep->req_list); /* it this is the head of the queue, start i/o ... */ - if (!musb_ep->busy && &request->request.list == musb_ep->req_list.next) + if (!musb_ep->busy && &request->list == musb_ep->req_list.next) musb_ep_restart(musb, request); cleanup: @@ -1349,7 +1352,7 @@ static int musb_gadget_set_halt(struct usb_ep *ep, int value) musb_ep_select(mbase, epnum); - request = to_musb_request(next_request(musb_ep)); + request = next_request(musb_ep); if (value) { if (request) { DBG(3, "request in progress, cannot halt %s\n", diff --git a/drivers/usb/musb/musb_gadget.h b/drivers/usb/musb/musb_gadget.h index a55354fbccf5..66b7c5e0fb44 100644 --- a/drivers/usb/musb/musb_gadget.h +++ b/drivers/usb/musb/musb_gadget.h @@ -35,6 +35,8 @@ #ifndef __MUSB_GADGET_H #define __MUSB_GADGET_H +#include + enum buffer_map_state { UN_MAPPED = 0, PRE_MAPPED, @@ -43,6 +45,7 @@ enum buffer_map_state { struct musb_request { struct usb_request request; + struct list_head list; struct musb_ep *ep; struct musb *musb; u8 tx; /* endpoint direction */ @@ -94,13 +97,13 @@ static inline struct musb_ep *to_musb_ep(struct usb_ep *ep) return ep ? container_of(ep, struct musb_ep, end_point) : NULL; } -static inline struct usb_request *next_request(struct musb_ep *ep) +static inline struct musb_request *next_request(struct musb_ep *ep) { struct list_head *queue = &ep->req_list; if (list_empty(queue)) return NULL; - return container_of(queue->next, struct usb_request, list); + return container_of(queue->next, struct musb_request, list); } extern void musb_g_tx(struct musb *musb, u8 epnum); diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c index 6dd03f4c5f49..75a542e42fdf 100644 --- a/drivers/usb/musb/musb_gadget_ep0.c +++ b/drivers/usb/musb/musb_gadget_ep0.c @@ -304,8 +304,7 @@ __acquires(musb->lock) } /* Maybe start the first request in the queue */ - request = to_musb_request( - next_request(musb_ep)); + request = next_request(musb_ep); if (!musb_ep->busy && request) { DBG(3, "restarting the request\n"); musb_ep_restart(musb, request); @@ -491,10 +490,12 @@ stall: static void ep0_rxstate(struct musb *musb) { void __iomem *regs = musb->control_ep->regs; + struct musb_request *request; struct usb_request *req; u16 count, csr; - req = next_ep0_request(musb); + request = next_ep0_request(musb); + req = &request->request; /* read packet and ack; or stall because of gadget driver bug: * should have provided the rx buffer before setup() returned. @@ -544,17 +545,20 @@ static void ep0_rxstate(struct musb *musb) static void ep0_txstate(struct musb *musb) { void __iomem *regs = musb->control_ep->regs; - struct usb_request *request = next_ep0_request(musb); + struct musb_request *req = next_ep0_request(musb); + struct usb_request *request; u16 csr = MUSB_CSR0_TXPKTRDY; u8 *fifo_src; u8 fifo_count; - if (!request) { + if (!req) { /* WARN_ON(1); */ DBG(2, "odd; csr0 %04x\n", musb_readw(regs, MUSB_CSR0)); return; } + request = &req->request; + /* load the data */ fifo_src = (u8 *) request->buf + request->actual; fifo_count = min((unsigned) MUSB_EP0_FIFOSIZE, @@ -598,7 +602,7 @@ static void ep0_txstate(struct musb *musb) static void musb_read_setup(struct musb *musb, struct usb_ctrlrequest *req) { - struct usb_request *r; + struct musb_request *r; void __iomem *regs = musb->control_ep->regs; musb_read_fifo(&musb->endpoints[0], sizeof *req, (u8 *)req); @@ -616,7 +620,7 @@ musb_read_setup(struct musb *musb, struct usb_ctrlrequest *req) /* clean up any leftover transfers */ r = next_ep0_request(musb); if (r) - musb_g_ep0_giveback(musb, r); + musb_g_ep0_giveback(musb, &r->request); /* For zero-data requests we want to delay the STATUS stage to * avoid SETUPEND errors. If we read data (OUT), delay accepting @@ -758,11 +762,11 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb) case MUSB_EP0_STAGE_STATUSOUT: /* end of sequence #1: write to host (TX state) */ { - struct usb_request *req; + struct musb_request *req; req = next_ep0_request(musb); if (req) - musb_g_ep0_giveback(musb, req); + musb_g_ep0_giveback(musb, &req->request); } /* @@ -961,7 +965,7 @@ musb_g_ep0_queue(struct usb_ep *e, struct usb_request *r, gfp_t gfp_flags) } /* add request to the list */ - list_add_tail(&(req->request.list), &(ep->req_list)); + list_add_tail(&req->list, &ep->req_list); DBG(3, "queue to %s (%s), length=%d\n", ep->name, ep->is_in ? "IN/TX" : "OUT/RX", -- cgit v1.2.3 From 207b0e1f1655bd7008b7322cdc3f84fb171c546d Mon Sep 17 00:00:00 2001 From: Hema HK Date: Thu, 17 Feb 2011 12:07:22 +0530 Subject: usb: musb: Using runtime pm APIs for musb. Calling runtime pm APIs pm_runtime_put_sync() and pm_runtime_get_sync() for enabling/disabling the clocks, sysconfig settings. Enable clock, configure no-idle/standby when active and configure force idle/standby and disable clock when idled. This is taken care by the runtime framework when driver calls the pm_runtime_get_sync and pm_runtime_put_sync APIs. Need to configure MUSB into force standby and force idle mode when usb not used Signed-off-by: Hema HK Cc: Tony Lindgren Cc: Kevin Hilman Cc: Cousson, Benoit Cc: Paul Walmsley Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.h | 2 +- drivers/usb/musb/omap2430.c | 81 +++++++++++++------------------------------- 2 files changed, 24 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 2c8dde6d23e0..5216729bd4b2 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -360,7 +360,7 @@ struct musb_context_registers { #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ defined(CONFIG_ARCH_OMAP4) - u32 otg_sysconfig, otg_forcestandby; + u32 otg_forcestandby; #endif u8 power; u16 intrtxe, intrrxe; diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index a3f12333fc41..bb6e6cd330da 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include "musb_core.h" #include "omap2430.h" @@ -40,7 +42,6 @@ struct omap2430_glue { struct device *dev; struct platform_device *musb; - struct clk *clk; }; #define glue_to_musb(g) platform_get_drvdata(g->musb) @@ -216,20 +217,12 @@ static inline void omap2430_low_level_exit(struct musb *musb) l = musb_readl(musb->mregs, OTG_FORCESTDBY); l |= ENABLEFORCE; /* enable MSTANDBY */ musb_writel(musb->mregs, OTG_FORCESTDBY, l); - - l = musb_readl(musb->mregs, OTG_SYSCONFIG); - l |= ENABLEWAKEUP; /* enable wakeup */ - musb_writel(musb->mregs, OTG_SYSCONFIG, l); } static inline void omap2430_low_level_init(struct musb *musb) { u32 l; - l = musb_readl(musb->mregs, OTG_SYSCONFIG); - l &= ~ENABLEWAKEUP; /* disable wakeup */ - musb_writel(musb->mregs, OTG_SYSCONFIG, l); - l = musb_readl(musb->mregs, OTG_FORCESTDBY); l &= ~ENABLEFORCE; /* disable MSTANDBY */ musb_writel(musb->mregs, OTG_FORCESTDBY, l); @@ -309,21 +302,6 @@ static int omap2430_musb_init(struct musb *musb) omap2430_low_level_init(musb); - l = musb_readl(musb->mregs, OTG_SYSCONFIG); - l &= ~ENABLEWAKEUP; /* disable wakeup */ - l &= ~NOSTDBY; /* remove possible nostdby */ - l |= SMARTSTDBY; /* enable smart standby */ - l &= ~AUTOIDLE; /* disable auto idle */ - l &= ~NOIDLE; /* remove possible noidle */ - l |= SMARTIDLE; /* enable smart idle */ - /* - * MUSB AUTOIDLE don't work in 3430. - * Workaround by Richard Woodruff/TI - */ - if (!cpu_is_omap3430()) - l |= AUTOIDLE; /* enable auto idle */ - musb_writel(musb->mregs, OTG_SYSCONFIG, l); - l = musb_readl(musb->mregs, OTG_INTERFSEL); if (data->interface_type == MUSB_INTERFACE_UTMI) { @@ -386,7 +364,7 @@ static int __init omap2430_probe(struct platform_device *pdev) struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; struct omap2430_glue *glue; - struct clk *clk; + int status = 0; int ret = -ENOMEM; @@ -402,26 +380,12 @@ static int __init omap2430_probe(struct platform_device *pdev) goto err1; } - clk = clk_get(&pdev->dev, "ick"); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "failed to get clock\n"); - ret = PTR_ERR(clk); - goto err2; - } - - ret = clk_enable(clk); - if (ret) { - dev_err(&pdev->dev, "failed to enable clock\n"); - goto err3; - } - musb->dev.parent = &pdev->dev; musb->dev.dma_mask = &omap2430_dmamask; musb->dev.coherent_dma_mask = omap2430_dmamask; glue->dev = &pdev->dev; glue->musb = musb; - glue->clk = clk; pdata->platform_ops = &omap2430_ops; @@ -431,29 +395,32 @@ static int __init omap2430_probe(struct platform_device *pdev) pdev->num_resources); if (ret) { dev_err(&pdev->dev, "failed to add resources\n"); - goto err4; + goto err2; } ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); if (ret) { dev_err(&pdev->dev, "failed to add platform_data\n"); - goto err4; + goto err2; } ret = platform_device_add(musb); if (ret) { dev_err(&pdev->dev, "failed to register musb device\n"); - goto err4; + goto err2; } - return 0; + pm_runtime_enable(&pdev->dev); + status = pm_runtime_get_sync(&pdev->dev); + if (status < 0) { + dev_err(&pdev->dev, "pm_runtime_get_sync FAILED"); + goto err3; + } -err4: - clk_disable(clk); + return 0; err3: - clk_put(clk); - + pm_runtime_disable(&pdev->dev); err2: platform_device_put(musb); @@ -470,8 +437,8 @@ static int __exit omap2430_remove(struct platform_device *pdev) platform_device_del(glue->musb); platform_device_put(glue->musb); - clk_disable(glue->clk); - clk_put(glue->clk); + pm_runtime_put(&pdev->dev); + pm_runtime_disable(&pdev->dev); kfree(glue); return 0; @@ -480,13 +447,11 @@ static int __exit omap2430_remove(struct platform_device *pdev) #ifdef CONFIG_PM static void omap2430_save_context(struct musb *musb) { - musb->context.otg_sysconfig = musb_readl(musb->mregs, OTG_SYSCONFIG); musb->context.otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY); } static void omap2430_restore_context(struct musb *musb) { - musb_writel(musb->mregs, OTG_SYSCONFIG, musb->context.otg_sysconfig); musb_writel(musb->mregs, OTG_FORCESTDBY, musb->context.otg_forcestandby); } @@ -498,7 +463,10 @@ static int omap2430_suspend(struct device *dev) omap2430_low_level_exit(musb); otg_set_suspend(musb->xceiv, 1); omap2430_save_context(musb); - clk_disable(glue->clk); + + if (!pm_runtime_suspended(dev) && dev->bus && dev->bus->pm && + dev->bus->pm->runtime_suspend) + dev->bus->pm->runtime_suspend(dev); return 0; } @@ -507,13 +475,10 @@ static int omap2430_resume(struct device *dev) { struct omap2430_glue *glue = dev_get_drvdata(dev); struct musb *musb = glue_to_musb(glue); - int ret; - ret = clk_enable(glue->clk); - if (ret) { - dev_err(dev, "faled to enable clock\n"); - return ret; - } + if (!pm_runtime_suspended(dev) && dev->bus && dev->bus->pm && + dev->bus->pm->runtime_resume) + dev->bus->pm->runtime_resume(dev); omap2430_low_level_init(musb); omap2430_restore_context(musb); -- cgit v1.2.3 From 6dc2503b81a0171e68766f722a452e97a7da320b Mon Sep 17 00:00:00 2001 From: Hema HK Date: Thu, 17 Feb 2011 12:06:04 +0530 Subject: usb: otg: enable regulator only on cable/device connect Remove the regulator enable while driver loading and enable it only when the cable/device is connected and disable it when disconnected. Remove the configuration of config_state and config_trans register configuration as these registers are programmed when regulator enable/disable is called. Signed-off-by: Hema HK Cc: Tony Lindgren Cc: Paul Walmsley Signed-off-by: Felipe Balbi --- drivers/usb/otg/twl6030-usb.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c index 28f770103640..eca459126db7 100644 --- a/drivers/usb/otg/twl6030-usb.c +++ b/drivers/usb/otg/twl6030-usb.c @@ -158,8 +158,6 @@ static int twl6030_phy_init(struct otg_transceiver *x) dev = twl->dev; pdata = dev->platform_data; - regulator_enable(twl->usb3v3); - hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); if (hw_state & STS_USB_ID) @@ -180,7 +178,6 @@ static void twl6030_phy_shutdown(struct otg_transceiver *x) dev = twl->dev; pdata = dev->platform_data; pdata->phy_power(twl->dev, 0, 0); - regulator_disable(twl->usb3v3); } static int twl6030_usb_ldo_init(struct twl6030_usb *twl) @@ -199,16 +196,6 @@ static int twl6030_usb_ldo_init(struct twl6030_usb *twl) if (IS_ERR(twl->usb3v3)) return -ENODEV; - regulator_enable(twl->usb3v3); - - /* Program the VUSB_CFG_TRANS for ACTIVE state. */ - twl6030_writeb(twl, TWL_MODULE_PM_RECEIVER, 0x3F, - VUSB_CFG_TRANS); - - /* Program the VUSB_CFG_STATE register to ON on all groups. */ - twl6030_writeb(twl, TWL_MODULE_PM_RECEIVER, 0xE1, - VUSB_CFG_STATE); - /* Program the USB_VBUS_CTRL_SET and set VBUS_ACT_COMP bit */ twl6030_writeb(twl, TWL_MODULE_USB, 0x4, USB_VBUS_CTRL_SET); @@ -261,16 +248,23 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl) CONTROLLER_STAT1); if (!(hw_state & STS_USB_ID)) { if (vbus_state & VBUS_DET) { + regulator_enable(twl->usb3v3); + twl->asleep = 1; status = USB_EVENT_VBUS; twl->otg.default_a = false; twl->otg.state = OTG_STATE_B_IDLE; + twl->linkstat = status; + blocking_notifier_call_chain(&twl->otg.notifier, + status, twl->otg.gadget); } else { status = USB_EVENT_NONE; - } - if (status >= 0) { twl->linkstat = status; blocking_notifier_call_chain(&twl->otg.notifier, status, twl->otg.gadget); + if (twl->asleep) { + regulator_disable(twl->usb3v3); + twl->asleep = 0; + } } } sysfs_notify(&twl->dev->kobj, NULL, "vbus"); @@ -288,6 +282,8 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) if (hw_state & STS_USB_ID) { + regulator_enable(twl->usb3v3); + twl->asleep = 1; twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_CLR, 0x1); twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, 0x10); @@ -437,6 +433,7 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) return status; } + twl->asleep = 0; pdata->phy_init(dev); twl6030_enable_irq(&twl->otg); dev_info(&pdev->dev, "Initialized TWL6030 USB module\n"); -- cgit v1.2.3 From 31e9992ab09264ed1372ba86a0924899ab08700b Mon Sep 17 00:00:00 2001 From: Hema HK Date: Thu, 17 Feb 2011 12:06:05 +0530 Subject: usb: otg: Remove one unnecessary I2C read request. To get the ID status there was an I2C read transfer. Removed this I2C read transfer as this info can be used from existing variable(linkstat). Signed-off-by: Hema HK Cc: Tony Lindgren Cc: Paul Walmsley Signed-off-by: Felipe Balbi --- drivers/usb/otg/twl6030-usb.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c index eca459126db7..88989e61430c 100644 --- a/drivers/usb/otg/twl6030-usb.c +++ b/drivers/usb/otg/twl6030-usb.c @@ -149,7 +149,6 @@ static int twl6030_set_phy_clk(struct otg_transceiver *x, int on) static int twl6030_phy_init(struct otg_transceiver *x) { - u8 hw_state; struct twl6030_usb *twl; struct device *dev; struct twl4030_usb_data *pdata; @@ -158,9 +157,7 @@ static int twl6030_phy_init(struct otg_transceiver *x) dev = twl->dev; pdata = dev->platform_data; - hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); - - if (hw_state & STS_USB_ID) + if (twl->linkstat == USB_EVENT_ID) pdata->phy_power(twl->dev, 1, 1); else pdata->phy_power(twl->dev, 0, 1); @@ -290,6 +287,7 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) status = USB_EVENT_ID; twl->otg.default_a = true; twl->otg.state = OTG_STATE_A_IDLE; + twl->linkstat = status; blocking_notifier_call_chain(&twl->otg.notifier, status, twl->otg.gadget); } else { @@ -299,7 +297,6 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) 0x1); } twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_LATCH_CLR, status); - twl->linkstat = status; return IRQ_HANDLED; } -- cgit v1.2.3 From 9fc3de9c83565fcaa23df74c2fc414bb6e7efb0a Mon Sep 17 00:00:00 2001 From: Arthur Taylor Date: Fri, 4 Feb 2011 13:55:50 -0800 Subject: vt: Add virtual console keyboard mode OFF virtual console: add keyboard mode OFF Add a new mode for the virtual console keyboard OFF in which all input other than shift keys is ignored. Prevents vt input buffers from overflowing when a program opens but doesn't read from a tty, like X11 using evdev for input. Signed-off-by: Arthur Taylor Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/keyboard.c | 5 +++-- drivers/tty/vt/vt_ioctl.c | 3 +++ include/linux/kbd_kern.h | 3 ++- include/linux/kd.h | 1 + 4 files changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index e95d7876ca6b..6dd3c68c13ad 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c @@ -654,7 +654,8 @@ static void k_spec(struct vc_data *vc, unsigned char value, char up_flag) if (value >= ARRAY_SIZE(fn_handler)) return; if ((kbd->kbdmode == VC_RAW || - kbd->kbdmode == VC_MEDIUMRAW) && + kbd->kbdmode == VC_MEDIUMRAW || + kbd->kbdmode == VC_OFF) && value != KVAL(K_SAK)) return; /* SAK is allowed even in raw mode */ fn_handler[value](vc); @@ -1295,7 +1296,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) if (rc == NOTIFY_STOP) return; - if (raw_mode && type != KT_SPEC && type != KT_SHIFT) + if ((raw_mode || kbd->kbdmode == VC_OFF) && type != KT_SPEC && type != KT_SHIFT) return; (*k_handler[type])(vc, keysym & 0xff, !down); diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 1235ebda6e1c..6bcf05bf4978 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -688,6 +688,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, kbd->kbdmode = VC_UNICODE; compute_shiftstate(); break; + case K_OFF: + kbd->kbdmode = VC_OFF; + break; default: ret = -EINVAL; goto out; diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h index 506ad20c18f8..4b0761cc7dd9 100644 --- a/include/linux/kbd_kern.h +++ b/include/linux/kbd_kern.h @@ -50,11 +50,12 @@ struct kbd_struct { #define VC_CAPSLOCK 2 /* capslock mode */ #define VC_KANALOCK 3 /* kanalock mode */ - unsigned char kbdmode:2; /* one 2-bit value */ + unsigned char kbdmode:3; /* one 3-bit value */ #define VC_XLATE 0 /* translate keycodes using keymap */ #define VC_MEDIUMRAW 1 /* medium raw (keycode) mode */ #define VC_RAW 2 /* raw (scancode) mode */ #define VC_UNICODE 3 /* Unicode mode */ +#define VC_OFF 4 /* disabled mode */ unsigned char modeflags:5; #define VC_APPLIC 0 /* application key mode */ diff --git a/include/linux/kd.h b/include/linux/kd.h index 15f2853ea58f..c36d8476db55 100644 --- a/include/linux/kd.h +++ b/include/linux/kd.h @@ -81,6 +81,7 @@ struct unimapinit { #define K_XLATE 0x01 #define K_MEDIUMRAW 0x02 #define K_UNICODE 0x03 +#define K_OFF 0x04 #define KDGKBMODE 0x4B44 /* gets current keyboard mode */ #define KDSKBMODE 0x4B45 /* sets current keyboard mode */ -- cgit v1.2.3 From 5427bcf5e95245d3e220742ac703182bdb973769 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 4 Feb 2011 20:45:49 -0500 Subject: hvc: add Blackfin JTAG console support This converts the existing bfin_jtag_comm TTY driver to the HVC layer so that the common HVC code can worry about all of the TTY/polling crap and leave the Blackfin code to worry about the Blackfin bits. Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/char/Kconfig | 9 ++++ drivers/tty/hvc/Makefile | 1 + drivers/tty/hvc/hvc_bfin_jtag.c | 105 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 drivers/tty/hvc/hvc_bfin_jtag.c (limited to 'drivers') diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index b7980a83ce2d..17f9b968b988 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -691,6 +691,15 @@ config HVC_DCC driver. This console is used through a JTAG only on ARM. If you don't have a JTAG then you probably don't want this option. +config HVC_BFIN_JTAG + bool "Blackfin JTAG console" + depends on BLACKFIN + select HVC_DRIVER + help + This console uses the Blackfin JTAG to create a console under the + the HVC driver. If you don't have JTAG, then you probably don't + want this option. + config VIRTIO_CONSOLE tristate "Virtio console" depends on VIRTIO diff --git a/drivers/tty/hvc/Makefile b/drivers/tty/hvc/Makefile index e6bed5f177ff..7b0edbce9009 100644 --- a/drivers/tty/hvc/Makefile +++ b/drivers/tty/hvc/Makefile @@ -9,5 +9,6 @@ obj-$(CONFIG_HVC_IRQ) += hvc_irq.o obj-$(CONFIG_HVC_XEN) += hvc_xen.o obj-$(CONFIG_HVC_IUCV) += hvc_iucv.o obj-$(CONFIG_HVC_UDBG) += hvc_udbg.o +obj-$(CONFIG_HVC_BFIN_JTAG) += hvc_bfin_jtag.o obj-$(CONFIG_HVCS) += hvcs.o obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o diff --git a/drivers/tty/hvc/hvc_bfin_jtag.c b/drivers/tty/hvc/hvc_bfin_jtag.c new file mode 100644 index 000000000000..31d6cc6a77af --- /dev/null +++ b/drivers/tty/hvc/hvc_bfin_jtag.c @@ -0,0 +1,105 @@ +/* + * Console via Blackfin JTAG Communication + * + * Copyright 2008-2011 Analog Devices Inc. + * + * Enter bugs at http://blackfin.uclinux.org/ + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include + +#include "hvc_console.h" + +/* See the Debug/Emulation chapter in the HRM */ +#define EMUDOF 0x00000001 /* EMUDAT_OUT full & valid */ +#define EMUDIF 0x00000002 /* EMUDAT_IN full & valid */ +#define EMUDOOVF 0x00000004 /* EMUDAT_OUT overflow */ +#define EMUDIOVF 0x00000008 /* EMUDAT_IN overflow */ + +/* Helper functions to glue the register API to simple C operations */ +static inline uint32_t bfin_write_emudat(uint32_t emudat) +{ + __asm__ __volatile__("emudat = %0;" : : "d"(emudat)); + return emudat; +} + +static inline uint32_t bfin_read_emudat(void) +{ + uint32_t emudat; + __asm__ __volatile__("%0 = emudat;" : "=d"(emudat)); + return emudat; +} + +/* Send data to the host */ +static int hvc_bfin_put_chars(uint32_t vt, const char *buf, int count) +{ + static uint32_t outbound_len; + uint32_t emudat; + int ret; + + if (bfin_read_DBGSTAT() & EMUDOF) + return 0; + + if (!outbound_len) { + outbound_len = count; + bfin_write_emudat(outbound_len); + return 0; + } + + ret = min(outbound_len, (uint32_t)4); + memcpy(&emudat, buf, ret); + bfin_write_emudat(emudat); + outbound_len -= ret; + + return ret; +} + +/* Receive data from the host */ +static int hvc_bfin_get_chars(uint32_t vt, char *buf, int count) +{ + static uint32_t inbound_len; + uint32_t emudat; + int ret; + + if (!(bfin_read_DBGSTAT() & EMUDIF)) + return 0; + emudat = bfin_read_emudat(); + + if (!inbound_len) { + inbound_len = emudat; + return 0; + } + + ret = min(inbound_len, (uint32_t)4); + memcpy(buf, &emudat, ret); + inbound_len -= ret; + + return ret; +} + +/* Glue the HVC layers to the Blackfin layers */ +static const struct hv_ops hvc_bfin_get_put_ops = { + .get_chars = hvc_bfin_get_chars, + .put_chars = hvc_bfin_put_chars, +}; + +static int __init hvc_bfin_console_init(void) +{ + hvc_instantiate(0, 0, &hvc_bfin_get_put_ops); + return 0; +} +console_initcall(hvc_bfin_console_init); + +static int __init hvc_bfin_init(void) +{ + hvc_alloc(0, 0, &hvc_bfin_get_put_ops, 128); + return 0; +} +device_initcall(hvc_bfin_init); -- cgit v1.2.3 From 1ffdda950394b6da54d68e9643bc691ebad7a6cc Mon Sep 17 00:00:00 2001 From: Mandeep Singh Baines Date: Sun, 6 Feb 2011 09:31:53 -0800 Subject: TTY: use appropriate printk priority level printk()s without a priority level default to KERN_WARNING. To reduce noise at KERN_WARNING, this patch set the priority level appriopriately for unleveled printks()s. This should be useful to folks that look at dmesg warnings closely. Signed-off-by: Mandeep Singh Baines Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vt.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 147ede3423df..d5669ff72df4 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -2157,10 +2157,10 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co currcons = vc->vc_num; if (!vc_cons_allocated(currcons)) { - /* could this happen? */ - printk_once("con_write: tty %d not allocated\n", currcons+1); - console_unlock(); - return 0; + /* could this happen? */ + pr_warn_once("con_write: tty %d not allocated\n", currcons+1); + console_unlock(); + return 0; } himask = vc->vc_hi_font_mask; @@ -2940,7 +2940,7 @@ static int __init con_init(void) gotoxy(vc, vc->vc_x, vc->vc_y); csi_J(vc, 0); update_screen(vc); - printk("Console: %s %s %dx%d", + pr_info("Console: %s %s %dx%d", vc->vc_can_do_color ? "colour" : "mono", display_desc, vc->vc_cols, vc->vc_rows); printable = 1; @@ -3103,7 +3103,7 @@ static int bind_con_driver(const struct consw *csw, int first, int last, clear_buffer_attributes(vc); } - printk("Console: switching "); + pr_info("Console: switching "); if (!deflt) printk("consoles %d-%d ", first+1, last+1); if (j >= 0) { @@ -3809,7 +3809,8 @@ void do_unblank_screen(int leaving_gfx) return; if (!vc_cons_allocated(fg_console)) { /* impossible */ - printk("unblank_screen: tty %d not allocated ??\n", fg_console+1); + pr_warning("unblank_screen: tty %d not allocated ??\n", + fg_console+1); return; } vc = vc_cons[fg_console].d; -- cgit v1.2.3 From dc1892c4bc6960121ca4c8023a07c815cfd689be Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 7 Feb 2011 19:31:24 +0100 Subject: tty,vcs: lseek/VC-release race fix there's a race between vcs's lseek handler and VC release. The lseek handler does not hold console_lock and touches VC's size info. If during this the VC got released, there's an access violation. Following program triggers the issue for me: [SNIP] #define _BSD_SOURCE #include #include #include #include #include #include #include #include static int run_seek(void) { while(1) { int fd; fd = open("./vcs30", O_RDWR); while(lseek(fd, 0, 0) != -1); close(fd); } } static int open_ioctl_tty(void) { return open("/dev/tty1", O_RDWR); } static int do_ioctl(int fd, int req, int i) { return ioctl(fd, req, i); } #define INIT(i) do_ioctl(ioctl_fd, VT_ACTIVATE, i) #define SHUT(i) do_ioctl(ioctl_fd, VT_DISALLOCATE, i) int main(int argc, char **argv) { int ioctl_fd = open_ioctl_tty(); if (ioctl < 0) { perror("open tty1 failed\n"); return -1; } if ((-1 == mknod("vcs30", S_IFCHR|0666, makedev(7, 30))) && (errno != EEXIST)) { printf("errno %d\n", errno); perror("failed to create vcs30"); return -1; } do_ioctl(ioctl_fd, VT_LOCKSWITCH, 0); if (!fork()) run_seek(); while(1) { INIT(30); SHUT(30); } return 0; } [SNIP] Signed-off-by: Jiri Olsa Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vc_screen.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index a672ed192d33..3c27c4bc6040 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -159,7 +159,13 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) int size; mutex_lock(&con_buf_mtx); + console_lock(); size = vcs_size(file->f_path.dentry->d_inode); + console_unlock(); + if (size < 0) { + mutex_unlock(&con_buf_mtx); + return size; + } switch (orig) { default: mutex_unlock(&con_buf_mtx); @@ -237,6 +243,12 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) * could sleep. */ size = vcs_size(inode); + if (size < 0) { + if (read) + break; + ret = size; + goto unlock_out; + } if (pos >= size) break; if (count > size - pos) @@ -436,6 +448,12 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) * Return data written up to now on failure. */ size = vcs_size(inode); + if (size < 0) { + if (written) + break; + ret = size; + goto unlock_out; + } if (pos >= size) break; if (this_round > size - pos) -- cgit v1.2.3 From fcdba07ee390d9d9c15de8b2a17baef689284fcc Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 7 Feb 2011 19:31:25 +0100 Subject: tty,vcs removing con_buf/conf_buf_mtx seems there's no longer need for using con_buf/conf_buf_mtx as vcs_read/vcs_write buffer for user's data. The do_con_write function, that was the other user of this, is currently using its own kmalloc-ed buffer. Not sure when this got changed, as I was able to find this code in 2.6.9, but it's already gone as far as current git history goes - 2.6.12-rc2. AFAICS there's a behaviour change with the current change. The lseek is not completely mutually exclusive with the vcs_read/vcs_write - the file->f_pos might get updated via lseek callback during the vcs_read/vcs_write processing. I tried to find out if the prefered behaviour is to keep this in sync within read/write/lseek functions, but I did not find any pattern on different places. I guess if user end up calling write/lseek from different threads she should know what she's doing. If needed we could use dedicated fd mutex/buffer. Signed-off-by: Jiri Olsa Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vc_screen.c | 98 ++++++++++++++++++++++++---------------------- drivers/tty/vt/vt.c | 12 ------ include/linux/vt_kern.h | 8 ---- 3 files changed, 52 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 3c27c4bc6040..7b3bfbe2e6de 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -51,6 +50,8 @@ #undef addr #define HEADER_SIZE 4 +#define CON_BUF_SIZE (CONFIG_BASE_SMALL ? 256 : PAGE_SIZE) + struct vcs_poll_data { struct notifier_block notifier; unsigned int cons_num; @@ -131,21 +132,45 @@ vcs_poll_data_get(struct file *file) return poll; } +/* + * Returns VC for inode. + * Must be called with console_lock. + */ +static struct vc_data* +vcs_vc(struct inode *inode, int *viewed) +{ + unsigned int currcons = iminor(inode) & 127; + + WARN_CONSOLE_UNLOCKED(); + + if (currcons == 0) { + currcons = fg_console; + if (viewed) + *viewed = 1; + } else { + currcons--; + if (viewed) + *viewed = 0; + } + return vc_cons[currcons].d; +} + +/* + * Returns size for VC carried by inode. + * Must be called with console_lock. + */ static int vcs_size(struct inode *inode) { int size; int minor = iminor(inode); - int currcons = minor & 127; struct vc_data *vc; - if (currcons == 0) - currcons = fg_console; - else - currcons--; - if (!vc_cons_allocated(currcons)) + WARN_CONSOLE_UNLOCKED(); + + vc = vcs_vc(inode, NULL); + if (!vc) return -ENXIO; - vc = vc_cons[currcons].d; size = vc->vc_rows * vc->vc_cols; @@ -158,17 +183,13 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) { int size; - mutex_lock(&con_buf_mtx); console_lock(); size = vcs_size(file->f_path.dentry->d_inode); console_unlock(); - if (size < 0) { - mutex_unlock(&con_buf_mtx); + if (size < 0) return size; - } switch (orig) { default: - mutex_unlock(&con_buf_mtx); return -EINVAL; case 2: offset += size; @@ -179,11 +200,9 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) break; } if (offset < 0 || offset > size) { - mutex_unlock(&con_buf_mtx); return -EINVAL; } file->f_pos = offset; - mutex_unlock(&con_buf_mtx); return file->f_pos; } @@ -196,12 +215,15 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) struct vc_data *vc; struct vcs_poll_data *poll; long pos; - long viewed, attr, read; - int col, maxcol; + long attr, read; + int col, maxcol, viewed; unsigned short *org = NULL; ssize_t ret; + char *con_buf; - mutex_lock(&con_buf_mtx); + con_buf = (char *) __get_free_page(GFP_KERNEL); + if (!con_buf) + return -ENOMEM; pos = *ppos; @@ -211,18 +233,10 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) console_lock(); attr = (currcons & 128); - currcons = (currcons & 127); - if (currcons == 0) { - currcons = fg_console; - viewed = 1; - } else { - currcons--; - viewed = 0; - } ret = -ENXIO; - if (!vc_cons_allocated(currcons)) + vc = vcs_vc(inode, &viewed); + if (!vc) goto unlock_out; - vc = vc_cons[currcons].d; ret = -EINVAL; if (pos < 0) @@ -367,7 +381,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) ret = read; unlock_out: console_unlock(); - mutex_unlock(&con_buf_mtx); + free_page((unsigned long) con_buf); return ret; } @@ -378,13 +392,16 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) unsigned int currcons = iminor(inode); struct vc_data *vc; long pos; - long viewed, attr, size, written; + long attr, size, written; char *con_buf0; - int col, maxcol; + int col, maxcol, viewed; u16 *org0 = NULL, *org = NULL; size_t ret; + char *con_buf; - mutex_lock(&con_buf_mtx); + con_buf = (char *) __get_free_page(GFP_KERNEL); + if (!con_buf) + return -ENOMEM; pos = *ppos; @@ -394,19 +411,10 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) console_lock(); attr = (currcons & 128); - currcons = (currcons & 127); - - if (currcons == 0) { - currcons = fg_console; - viewed = 1; - } else { - currcons--; - viewed = 0; - } ret = -ENXIO; - if (!vc_cons_allocated(currcons)) + vc = vcs_vc(inode, &viewed); + if (!vc) goto unlock_out; - vc = vc_cons[currcons].d; size = vcs_size(inode); ret = -EINVAL; @@ -561,9 +569,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) unlock_out: console_unlock(); - - mutex_unlock(&con_buf_mtx); - + free_page((unsigned long) con_buf); return ret; } diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index d5669ff72df4..798df6f89110 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -2068,18 +2068,6 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) } } -/* This is a temporary buffer used to prepare a tty console write - * so that we can easily avoid touching user space while holding the - * console spinlock. It is allocated in con_init and is shared by - * this code and the vc_screen read/write tty calls. - * - * We have to allocate this statically in the kernel data section - * since console_init (and thus con_init) are called before any - * kernel memory allocation is available. - */ -char con_buf[CON_BUF_SIZE]; -DEFINE_MUTEX(con_buf_mtx); - /* is_double_width() is based on the wcwidth() implementation by * Markus Kuhn -- 2007-05-26 (Unicode 5.0) * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h index 6625cc1ab758..4d05e14ea60c 100644 --- a/include/linux/vt_kern.h +++ b/include/linux/vt_kern.h @@ -142,14 +142,6 @@ static inline bool vt_force_oops_output(struct vc_data *vc) return false; } -/* - * vc_screen.c shares this temporary buffer with the console write code so that - * we can easily avoid touching user space while holding the console spinlock. - */ - -#define CON_BUF_SIZE (CONFIG_BASE_SMALL ? 256 : PAGE_SIZE) -extern char con_buf[CON_BUF_SIZE]; -extern struct mutex con_buf_mtx; extern char vt_dont_switch; extern int default_utf8; extern int global_cursor_default; -- cgit v1.2.3 From b68f23b24e0013d489aaa986da0210feea00d4c1 Mon Sep 17 00:00:00 2001 From: Russ Gorby Date: Mon, 7 Feb 2011 12:02:27 -0800 Subject: serial: ifx6x60: fixed call to tty_port_init The port ops must be set AFTER calling port init as that function zeroes the structure Signed-off-by: Russ Gorby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ifx6x60.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index c42de7152eea..972c04d8c1a3 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -798,8 +798,8 @@ static int ifx_spi_create_port(struct ifx_spi_device *ifx_dev) goto error_ret; } - pport->ops = &ifx_tty_port_ops; tty_port_init(pport); + pport->ops = &ifx_tty_port_ops; ifx_dev->minor = IFX_SPI_TTY_ID; ifx_dev->tty_dev = tty_register_device(tty_drv, ifx_dev->minor, &ifx_dev->spi_dev->dev); -- cgit v1.2.3 From 5fc324952049b2e6d16a54ef89afee25611ca476 Mon Sep 17 00:00:00 2001 From: Russ Gorby Date: Mon, 7 Feb 2011 12:02:28 -0800 Subject: serial: ifx6x60: dma_alloc_coherent must use parent dev This driver is a SPI protocol driver and has no DMA ops associated with the device so the call will fail. Furthermore, the DMA allocation made here will be used by the SPI controller driver (parent dev) so it makes sense to pass that device instead. Signed-off-by: Russ Gorby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ifx6x60.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 972c04d8c1a3..bb2ff206d0ab 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -998,7 +998,7 @@ static int ifx_spi_spi_probe(struct spi_device *spi) ifx_dev->spi_slave_cts = 0; /*initialize transfer and dma buffers */ - ifx_dev->tx_buffer = dma_alloc_coherent(&ifx_dev->spi_dev->dev, + ifx_dev->tx_buffer = dma_alloc_coherent(ifx_dev->spi_dev->dev.parent, IFX_SPI_TRANSFER_SIZE, &ifx_dev->tx_bus, GFP_KERNEL); @@ -1007,7 +1007,7 @@ static int ifx_spi_spi_probe(struct spi_device *spi) ret = -ENOMEM; goto error_ret; } - ifx_dev->rx_buffer = dma_alloc_coherent(&ifx_dev->spi_dev->dev, + ifx_dev->rx_buffer = dma_alloc_coherent(ifx_dev->spi_dev->dev.parent, IFX_SPI_TRANSFER_SIZE, &ifx_dev->rx_bus, GFP_KERNEL); -- cgit v1.2.3 From f089140ea760b42542389c96f9a54d3076696b2c Mon Sep 17 00:00:00 2001 From: Russ Gorby Date: Mon, 7 Feb 2011 12:02:29 -0800 Subject: serial: ifx6x60: changed internal bpw from boolean to int driver should support 32bit SPI transfers. The boolean variable only allowed 8/16. Changed to support 8/16/32 for future enabling of 32 bpw. Signed-off-by: Russ Gorby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ifx6x60.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index bb2ff206d0ab..9161cabaec37 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -76,7 +76,7 @@ static void ifx_spi_handle_srdy(struct ifx_spi_device *ifx_dev); /* local variables */ -static int spi_b16 = 1; /* 8 or 16 bit word length */ +static int spi_bpw = 16; /* 8, 16 or 32 bit word length */ static struct tty_driver *tty_drv; static struct ifx_spi_device *saved_ifx_dev; static struct lock_class_key ifx_spi_key; @@ -724,7 +724,7 @@ static void ifx_spi_io(unsigned long data) ifx_dev->spi_xfer.cs_change = 0; ifx_dev->spi_xfer.speed_hz = 12500000; /* ifx_dev->spi_xfer.speed_hz = 390625; */ - ifx_dev->spi_xfer.bits_per_word = spi_b16 ? 16 : 8; + ifx_dev->spi_xfer.bits_per_word = spi_bpw; ifx_dev->spi_xfer.tx_buf = ifx_dev->tx_buffer; ifx_dev->spi_xfer.rx_buf = ifx_dev->rx_buffer; -- cgit v1.2.3 From 1b79b440576b80bace7b6fa012a57ed91d763b5f Mon Sep 17 00:00:00 2001 From: Russ Gorby Date: Mon, 7 Feb 2011 12:02:30 -0800 Subject: serial: ifx6x60: set SPI max_speed_hz based on platform type Platforms containing the 6260 can run up to 25Mhz. For these platforms set max_speed_hz to 25Mhz. Signed-off-by: Russ Gorby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ifx6x60.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 9161cabaec37..766f0c3aabcf 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -722,7 +722,7 @@ static void ifx_spi_io(unsigned long data) /* note len is BYTES, not transfers */ ifx_dev->spi_xfer.len = IFX_SPI_TRANSFER_SIZE; ifx_dev->spi_xfer.cs_change = 0; - ifx_dev->spi_xfer.speed_hz = 12500000; + ifx_dev->spi_xfer.speed_hz = ifx_dev->spi_dev->max_speed_hz; /* ifx_dev->spi_xfer.speed_hz = 390625; */ ifx_dev->spi_xfer.bits_per_word = spi_bpw; @@ -992,6 +992,7 @@ static int ifx_spi_spi_probe(struct spi_device *spi) ifx_dev->modem = pl_data->modem_type; ifx_dev->use_dma = pl_data->use_dma; ifx_dev->max_hz = pl_data->max_hz; + spi->max_speed_hz = ifx_dev->max_hz; /* ensure SPI protocol flags are initialized to enable transfer */ ifx_dev->spi_more = 0; -- cgit v1.2.3 From 2aff8d90a073e5a07e1ff5a94779d6a21fb72dd2 Mon Sep 17 00:00:00 2001 From: Russ Gorby Date: Mon, 7 Feb 2011 12:02:31 -0800 Subject: serial: ifx6x60: probe routine needs to call spi_setup The probe routine should call spi_setup() to configure the SPI bus so it can properly communicate with the device. E.g. the device operates in SPI mode 1. Called spi_setup to configure SPI mode, max_speed_hz, and bpw Signed-off-by: Russ Gorby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ifx6x60.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 766f0c3aabcf..59e9cb87b7de 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -67,6 +67,7 @@ #define IFX_SPI_MORE_MASK 0x10 #define IFX_SPI_MORE_BIT 12 /* bit position in u16 */ #define IFX_SPI_CTS_BIT 13 /* bit position in u16 */ +#define IFX_SPI_MODE SPI_MODE_1 #define IFX_SPI_TTY_ID 0 #define IFX_SPI_TIMEOUT_SEC 2 #define IFX_SPI_HEADER_0 (-1) @@ -992,7 +993,15 @@ static int ifx_spi_spi_probe(struct spi_device *spi) ifx_dev->modem = pl_data->modem_type; ifx_dev->use_dma = pl_data->use_dma; ifx_dev->max_hz = pl_data->max_hz; + /* initialize spi mode, etc */ spi->max_speed_hz = ifx_dev->max_hz; + spi->mode = IFX_SPI_MODE | (SPI_LOOP & spi->mode); + spi->bits_per_word = spi_bpw; + ret = spi_setup(spi); + if (ret) { + dev_err(&spi->dev, "SPI setup wasn't successful %d", ret); + return -ENODEV; + } /* ensure SPI protocol flags are initialized to enable transfer */ ifx_dev->spi_more = 0; -- cgit v1.2.3 From 8115be01462f8af2dc22dd65dd28268bb9b8bff6 Mon Sep 17 00:00:00 2001 From: Russ Gorby Date: Mon, 7 Feb 2011 12:02:32 -0800 Subject: serial: ifx6x60: minor cleanup renamed spi_driver variable to not be h/w specific set driver name to use DRVNAME define removed commented-out define Signed-off-by: Russ Gorby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ifx6x60.c | 8 ++++---- drivers/tty/serial/ifx6x60.h | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 59e9cb87b7de..b68b96f53e6c 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -1333,9 +1333,9 @@ static const struct spi_device_id ifx_id_table[] = { MODULE_DEVICE_TABLE(spi, ifx_id_table); /* spi operations */ -static const struct spi_driver ifx_spi_driver_6160 = { +static const struct spi_driver ifx_spi_driver = { .driver = { - .name = "ifx6160", + .name = DRVNAME, .bus = &spi_bus_type, .pm = &ifx_spi_pm, .owner = THIS_MODULE}, @@ -1357,7 +1357,7 @@ static void __exit ifx_spi_exit(void) { /* unregister */ tty_unregister_driver(tty_drv); - spi_unregister_driver((void *)&ifx_spi_driver_6160); + spi_unregister_driver((void *)&ifx_spi_driver); } /** @@ -1399,7 +1399,7 @@ static int __init ifx_spi_init(void) return result; } - result = spi_register_driver((void *)&ifx_spi_driver_6160); + result = spi_register_driver((void *)&ifx_spi_driver); if (result) { pr_err("%s: spi_register_driver failed(%d)", DRVNAME, result); diff --git a/drivers/tty/serial/ifx6x60.h b/drivers/tty/serial/ifx6x60.h index 0ec39b58ccc4..e8464baf9e75 100644 --- a/drivers/tty/serial/ifx6x60.h +++ b/drivers/tty/serial/ifx6x60.h @@ -29,8 +29,6 @@ #define DRVNAME "ifx6x60" #define TTYNAME "ttyIFX" -/* #define IFX_THROTTLE_CODE */ - #define IFX_SPI_MAX_MINORS 1 #define IFX_SPI_TRANSFER_SIZE 2048 #define IFX_SPI_FIFO_SIZE 4096 -- cgit v1.2.3 From 95926d2db6256e08d06b753752a0d903a0580acc Mon Sep 17 00:00:00 2001 From: Yin Kangkai Date: Wed, 9 Feb 2011 11:34:20 +0800 Subject: serial: also set the uartclk value in resume after goes to highspeed For any reason if the NS16550A was not work in high speed mode (e.g. we hold NS16550A from going to high speed mode in autoconfig_16550a()), now we are resume from suspend, we should also set the uartclk to the correct value. Otherwise it is still the old 1843200 and that will bring issues. CC: Greg Kroah-Hartman CC: David Woodhouse CC: linux-kernel@vger.kernel.org CC: stable@kernel.org Signed-off-by: Yin Kangkai Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index 3975df6f7fdb..c10a6a909c76 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c @@ -3036,6 +3036,7 @@ void serial8250_resume_port(int line) serial_outp(up, 0x04, tmp); serial_outp(up, UART_LCR, 0); + up->port.uartclk = 921600*16; } uart_resume_port(&serial8250_reg, &up->port); } -- cgit v1.2.3 From 0d0389e5414c8950b1613e8bdc74289cde3d6d98 Mon Sep 17 00:00:00 2001 From: Yin Kangkai Date: Wed, 9 Feb 2011 11:35:18 +0800 Subject: serial: change the divisor latch only when prescalar actually changed In 8250.c original ns16550 autoconfig code, we change the divisor latch when we goto to high speed mode, we're assuming the previous speed is legacy. This some times is not true. For example in a system with both CONFIG_SERIAL_8250 and CONFIG_SERIAL_8250_PNP set, in this case, the code (autoconfig) will be called twice, one in serial8250_init/probe() and the other is from serial_pnp_probe. When serial_pnp_probe calls the autoconfig for NS16550A, it's already in high speed mode, change the divisor latch (quot << 3) in this case will make the UART console garbled. CC: Greg Kroah-Hartman CC: David Woodhouse CC: linux-kernel@vger.kernel.org CC: stable@kernel.org Signed-off-by: Yin Kangkai Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index c10a6a909c76..b3b881bc4712 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c @@ -954,6 +954,23 @@ static int broken_efr(struct uart_8250_port *up) return 0; } +static inline int ns16550a_goto_highspeed(struct uart_8250_port *up) +{ + unsigned char status; + + status = serial_in(up, 0x04); /* EXCR2 */ +#define PRESL(x) ((x) & 0x30) + if (PRESL(status) == 0x10) { + /* already in high speed mode */ + return 0; + } else { + status &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ + status |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ + serial_outp(up, 0x04, status); + } + return 1; +} + /* * We know that the chip has FIFOs. Does it have an EFR? The * EFR is located in the same register position as the IIR and @@ -1025,12 +1042,8 @@ static void autoconfig_16550a(struct uart_8250_port *up) quot = serial_dl_read(up); quot <<= 3; - status1 = serial_in(up, 0x04); /* EXCR2 */ - status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ - status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ - serial_outp(up, 0x04, status1); - - serial_dl_write(up, quot); + if (ns16550a_goto_highspeed(up)) + serial_dl_write(up, quot); serial_outp(up, UART_LCR, 0); @@ -3025,15 +3038,10 @@ void serial8250_resume_port(int line) struct uart_8250_port *up = &serial8250_ports[line]; if (up->capabilities & UART_NATSEMI) { - unsigned char tmp; - /* Ensure it's still in high speed mode */ serial_outp(up, UART_LCR, 0xE0); - tmp = serial_in(up, 0x04); /* EXCR2 */ - tmp &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ - tmp |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ - serial_outp(up, 0x04, tmp); + ns16550a_goto_highspeed(up); serial_outp(up, UART_LCR, 0); up->port.uartclk = 921600*16; -- cgit v1.2.3 From daaf6ff42d12c89f179868387c0107db6625f0f3 Mon Sep 17 00:00:00 2001 From: Niranjana Vishwanathapura Date: Wed, 9 Feb 2011 11:16:34 -0800 Subject: tty: Add msm_smd_tty driver msm_smd_tty driver provides tty device interface to 'DS' and 'GPSNMEA' streaming SMD ports. Cc: Brian Swetland Signed-off-by: Niranjana Vishwanathapura Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 9 ++ drivers/tty/serial/Makefile | 1 + drivers/tty/serial/msm_smd_tty.c | 236 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 246 insertions(+) create mode 100644 drivers/tty/serial/msm_smd_tty.c (limited to 'drivers') diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index aaedbad93a75..90d939a4ee5d 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1600,4 +1600,13 @@ config SERIAL_PCH_UART Output Hub) which is for IVI(In-Vehicle Infotainment) use. ML7213 is companion chip for Intel Atom E6xx series. ML7213 is completely compatible for Intel EG20T PCH. + +config SERIAL_MSM_SMD + bool "Enable tty device interface for some SMD ports" + default n + depends on MSM_SMD + help + Enables userspace clients to read and write to some streaming SMD + ports via tty device interface for MSM chipset. + endmenu diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 8ea92e9c73b0..0c6aefb55acf 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -92,3 +92,4 @@ obj-$(CONFIG_SERIAL_MRST_MAX3110) += mrst_max3110.o obj-$(CONFIG_SERIAL_MFD_HSU) += mfd.o obj-$(CONFIG_SERIAL_IFX6X60) += ifx6x60.o obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o +obj-$(CONFIG_SERIAL_MSM_SMD) += msm_smd_tty.o diff --git a/drivers/tty/serial/msm_smd_tty.c b/drivers/tty/serial/msm_smd_tty.c new file mode 100644 index 000000000000..beeff1e86093 --- /dev/null +++ b/drivers/tty/serial/msm_smd_tty.c @@ -0,0 +1,236 @@ +/* drivers/tty/serial/msm_smd_tty.c + * + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2011, Code Aurora Forum. All rights reserved. + * Author: Brian Swetland + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define MAX_SMD_TTYS 32 + +struct smd_tty_info { + struct tty_port port; + smd_channel_t *ch; +}; + +struct smd_tty_channel_desc { + int id; + const char *name; +}; + +static struct smd_tty_info smd_tty[MAX_SMD_TTYS]; + +static const struct smd_tty_channel_desc smd_default_tty_channels[] = { + { .id = 0, .name = "SMD_DS" }, + { .id = 27, .name = "SMD_GPSNMEA" }, +}; + +static const struct smd_tty_channel_desc *smd_tty_channels = + smd_default_tty_channels; +static int smd_tty_channels_len = ARRAY_SIZE(smd_default_tty_channels); + +static void smd_tty_notify(void *priv, unsigned event) +{ + unsigned char *ptr; + int avail; + struct smd_tty_info *info = priv; + struct tty_struct *tty; + + if (event != SMD_EVENT_DATA) + return; + + tty = tty_port_tty_get(&info->port); + if (!tty) + return; + + for (;;) { + if (test_bit(TTY_THROTTLED, &tty->flags)) + break; + avail = smd_read_avail(info->ch); + if (avail == 0) + break; + + avail = tty_prepare_flip_string(tty, &ptr, avail); + + if (smd_read(info->ch, ptr, avail) != avail) { + /* shouldn't be possible since we're in interrupt + ** context here and nobody else could 'steal' our + ** characters. + */ + pr_err("OOPS - smd_tty_buffer mismatch?!"); + } + + tty_flip_buffer_push(tty); + } + + /* XXX only when writable and necessary */ + tty_wakeup(tty); + tty_kref_put(tty); +} + +static int smd_tty_port_activate(struct tty_port *tport, struct tty_struct *tty) +{ + int i, res = 0; + int n = tty->index; + const char *name = NULL; + struct smd_tty_info *info = smd_tty + n; + + for (i = 0; i < smd_tty_channels_len; i++) { + if (smd_tty_channels[i].id == n) { + name = smd_tty_channels[i].name; + break; + } + } + if (!name) + return -ENODEV; + + if (info->ch) + smd_kick(info->ch); + else + res = smd_open(name, &info->ch, info, smd_tty_notify); + + if (!res) + tty->driver_data = info; + + return res; +} + +static void smd_tty_port_shutdown(struct tty_port *tport) +{ + struct smd_tty_info *info; + struct tty_struct *tty = tty_port_tty_get(tport); + + info = tty->driver_data; + if (info->ch) { + smd_close(info->ch); + info->ch = 0; + } + + tty->driver_data = 0; + tty_kref_put(tty); +} + +static int smd_tty_open(struct tty_struct *tty, struct file *f) +{ + struct smd_tty_info *info = smd_tty + tty->index; + + return tty_port_open(&info->port, tty, f); +} + +static void smd_tty_close(struct tty_struct *tty, struct file *f) +{ + struct smd_tty_info *info = tty->driver_data; + + tty_port_close(&info->port, tty, f); +} + +static int smd_tty_write(struct tty_struct *tty, + const unsigned char *buf, int len) +{ + struct smd_tty_info *info = tty->driver_data; + int avail; + + /* if we're writing to a packet channel we will + ** never be able to write more data than there + ** is currently space for + */ + avail = smd_write_avail(info->ch); + if (len > avail) + len = avail; + + return smd_write(info->ch, buf, len); +} + +static int smd_tty_write_room(struct tty_struct *tty) +{ + struct smd_tty_info *info = tty->driver_data; + return smd_write_avail(info->ch); +} + +static int smd_tty_chars_in_buffer(struct tty_struct *tty) +{ + struct smd_tty_info *info = tty->driver_data; + return smd_read_avail(info->ch); +} + +static void smd_tty_unthrottle(struct tty_struct *tty) +{ + struct smd_tty_info *info = tty->driver_data; + smd_kick(info->ch); +} + +static const struct tty_port_operations smd_tty_port_ops = { + .shutdown = smd_tty_port_shutdown, + .activate = smd_tty_port_activate, +}; + +static const struct tty_operations smd_tty_ops = { + .open = smd_tty_open, + .close = smd_tty_close, + .write = smd_tty_write, + .write_room = smd_tty_write_room, + .chars_in_buffer = smd_tty_chars_in_buffer, + .unthrottle = smd_tty_unthrottle, +}; + +static struct tty_driver *smd_tty_driver; + +static int __init smd_tty_init(void) +{ + int ret, i; + + smd_tty_driver = alloc_tty_driver(MAX_SMD_TTYS); + if (smd_tty_driver == 0) + return -ENOMEM; + + smd_tty_driver->owner = THIS_MODULE; + smd_tty_driver->driver_name = "smd_tty_driver"; + smd_tty_driver->name = "smd"; + smd_tty_driver->major = 0; + smd_tty_driver->minor_start = 0; + smd_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; + smd_tty_driver->subtype = SERIAL_TYPE_NORMAL; + smd_tty_driver->init_termios = tty_std_termios; + smd_tty_driver->init_termios.c_iflag = 0; + smd_tty_driver->init_termios.c_oflag = 0; + smd_tty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; + smd_tty_driver->init_termios.c_lflag = 0; + smd_tty_driver->flags = TTY_DRIVER_RESET_TERMIOS | + TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + tty_set_operations(smd_tty_driver, &smd_tty_ops); + + ret = tty_register_driver(smd_tty_driver); + if (ret) + return ret; + + for (i = 0; i < smd_tty_channels_len; i++) { + tty_port_init(&smd_tty[smd_tty_channels[i].id].port); + smd_tty[smd_tty_channels[i].id].port.ops = &smd_tty_port_ops; + tty_register_device(smd_tty_driver, smd_tty_channels[i].id, 0); + } + + return 0; +} + +module_init(smd_tty_init); -- cgit v1.2.3 From 42bd7a4f68e7785dce656a379c3de0a74f5a4d84 Mon Sep 17 00:00:00 2001 From: Viktar Palstsiuk Date: Wed, 9 Feb 2011 15:26:13 +0100 Subject: atmel_serial: enable PPS support Enables PPS support in atmel serial driver to make PPS API working. Signed-off-by: Viktar Palstsiuk Signed-off-by: Nicolas Ferre Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 2a1d52fb4936..f119d1761106 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -1240,6 +1240,21 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, spin_unlock_irqrestore(&port->lock, flags); } +static void atmel_set_ldisc(struct uart_port *port, int new) +{ + int line = port->line; + + if (line >= port->state->port.tty->driver->num) + return; + + if (port->state->port.tty->ldisc->ops->num == N_PPS) { + port->flags |= UPF_HARDPPS_CD; + atmel_enable_ms(port); + } else { + port->flags &= ~UPF_HARDPPS_CD; + } +} + /* * Return string describing the specified port */ @@ -1380,6 +1395,7 @@ static struct uart_ops atmel_pops = { .shutdown = atmel_shutdown, .flush_buffer = atmel_flush_buffer, .set_termios = atmel_set_termios, + .set_ldisc = atmel_set_ldisc, .type = atmel_type, .release_port = atmel_release_port, .request_port = atmel_request_port, -- cgit v1.2.3 From d637837583163a1a70331ce48097f697cac85e32 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 11 Feb 2011 15:39:28 +0100 Subject: tty,vt: fix VT_SETACTIVATE console switch using VT_SETACTIVATE ioctl for console switch did not work, since it put wrong param to the set_console function. Also ioctl returned misleading error, because of the missing break statement. I wonder anyone has ever used this one :). Signed-off-by: Jiri Olsa Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vt_ioctl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 6bcf05bf4978..9e9a901442a3 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -1010,8 +1010,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, if (ret) break; /* Commence switch and lock */ - set_console(arg); + set_console(vsa.console); } + break; } /* -- cgit v1.2.3 From e96fabd8791aad30a3c8a03919893ae3e2e3df25 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 9 Feb 2011 10:56:52 +0100 Subject: tty: serial: altera_uart: Handle pdev->id == -1 in altera_uart_remove Commit 6b5756f176568a710d008d3b478128fafb6707f0 introduced the possibility for pdev->id being -1 but the change was not done equally in altera_uart_remove. This patch fixes this. Acked-by: Anton Vorontsov Signed-off-by: Tobias Klauser Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/altera_uart.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 721216292a50..dee7a0eb6ea1 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -561,9 +561,15 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) static int __devexit altera_uart_remove(struct platform_device *pdev) { - struct uart_port *port = &altera_uart_ports[pdev->id].port; + struct uart_port *port; + int i = pdev->id; + if (i == -1) + i = 0; + + port = &altera_uart_ports[i].port; uart_remove_one_port(&altera_uart_driver, port); + return 0; } -- cgit v1.2.3 From 2780ad42f5fe6739882603c61c8decba6e50eaa2 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 9 Feb 2011 10:57:04 +0100 Subject: tty: serial: altera_uart: Use port->regshift to store bus shift Use the regshift member of struct uart_port to store the address stride from platform data. This way we can save one dereference per call of altera_uart_readl and altera_uart_writel. This also allows us to use the driver without platform data, which is needed for device tree support in the Nios2 port. Acked-by: Anton Vorontsov Signed-off-by: Tobias Klauser Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/altera_uart.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index dee7a0eb6ea1..3a573528555e 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -86,16 +86,12 @@ struct altera_uart { static u32 altera_uart_readl(struct uart_port *port, int reg) { - struct altera_uart_platform_uart *platp = port->private_data; - - return readl(port->membase + (reg << platp->bus_shift)); + return readl(port->membase + (reg << port->regshift)); } static void altera_uart_writel(struct uart_port *port, u32 dat, int reg) { - struct altera_uart_platform_uart *platp = port->private_data; - - writel(dat, port->membase + (reg << platp->bus_shift)); + writel(dat, port->membase + (reg << port->regshift)); } static unsigned int altera_uart_tx_empty(struct uart_port *port) @@ -546,13 +542,17 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) if (!port->membase) return -ENOMEM; + if (platp) + port->regshift = platp->bus_shift; + else + port->regshift = 0; + port->line = i; port->type = PORT_ALTERA_UART; port->iotype = SERIAL_IO_MEM; port->uartclk = platp->uartclk; port->ops = &altera_uart_ops; port->flags = UPF_BOOT_AUTOCONF; - port->private_data = platp; uart_add_one_port(&altera_uart_driver, port); -- cgit v1.2.3 From 60b33c133ca0b7c0b6072c87234b63fee6e80558 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 14 Feb 2011 16:26:14 +0000 Subject: tiocmget: kill off the passing of the struct file We don't actually need this and it causes problems for internal use of this functionality. Currently there is a single use of the FILE * pointer. That is the serial core which uses it to check tty_hung_up_p. However if that is true then IO_ERROR is also already set so the check may be removed. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/char/amiserial.c | 2 +- drivers/char/cyclades.c | 2 +- drivers/char/epca.c | 4 ++-- drivers/char/ip2/ip2main.c | 4 ++-- drivers/char/isicom.c | 2 +- drivers/char/istallion.c | 2 +- drivers/char/moxa.c | 4 ++-- drivers/char/mxser.c | 2 +- drivers/char/nozomi.c | 2 +- drivers/char/pcmcia/ipwireless/tty.c | 2 +- drivers/char/pcmcia/synclink_cs.c | 4 ++-- drivers/char/riscom8.c | 2 +- drivers/char/rocket.c | 2 +- drivers/char/serial167.c | 2 +- drivers/char/specialix.c | 2 +- drivers/char/stallion.c | 2 +- drivers/char/sx.c | 2 +- drivers/char/synclink.c | 4 ++-- drivers/char/synclink_gt.c | 4 ++-- drivers/char/synclinkmp.c | 4 ++-- drivers/isdn/gigaset/interface.c | 4 ++-- drivers/isdn/i4l/isdn_tty.c | 2 +- drivers/mmc/card/sdio_uart.c | 2 +- drivers/net/usb/hso.c | 2 +- drivers/net/wan/pc300_tty.c | 4 ++-- drivers/staging/quatech_usb2/quatech_usb2.c | 2 +- drivers/staging/serqt_usb2/serqt_usb2.c | 6 +++--- drivers/tty/hvc/hvsi.c | 2 +- drivers/tty/n_gsm.c | 2 +- drivers/tty/serial/68360serial.c | 2 +- drivers/tty/serial/crisv10.c | 2 +- drivers/tty/serial/ifx6x60.c | 2 +- drivers/tty/serial/serial_core.c | 6 ++---- drivers/tty/tty_io.c | 6 +++--- drivers/usb/class/cdc-acm.c | 2 +- drivers/usb/serial/ark3116.c | 2 +- drivers/usb/serial/belkin_sa.c | 4 ++-- drivers/usb/serial/ch341.c | 2 +- drivers/usb/serial/cp210x.c | 4 ++-- drivers/usb/serial/cypress_m8.c | 4 ++-- drivers/usb/serial/digi_acceleport.c | 4 ++-- drivers/usb/serial/ftdi_sio.c | 4 ++-- drivers/usb/serial/io_edgeport.c | 4 ++-- drivers/usb/serial/io_ti.c | 2 +- drivers/usb/serial/iuu_phoenix.c | 2 +- drivers/usb/serial/keyspan.c | 2 +- drivers/usb/serial/keyspan.h | 3 +-- drivers/usb/serial/keyspan_pda.c | 2 +- drivers/usb/serial/kl5kusb105.c | 4 ++-- drivers/usb/serial/kobil_sct.c | 4 ++-- drivers/usb/serial/mct_u232.c | 4 ++-- drivers/usb/serial/mos7720.c | 4 ++-- drivers/usb/serial/mos7840.c | 2 +- drivers/usb/serial/opticon.c | 2 +- drivers/usb/serial/oti6858.c | 4 ++-- drivers/usb/serial/pl2303.c | 2 +- drivers/usb/serial/sierra.c | 2 +- drivers/usb/serial/spcp8x5.c | 2 +- drivers/usb/serial/ssu100.c | 2 +- drivers/usb/serial/ti_usb_3410_5052.c | 4 ++-- drivers/usb/serial/usb-serial.c | 4 ++-- drivers/usb/serial/usb-wwan.h | 2 +- drivers/usb/serial/usb_wwan.c | 2 +- drivers/usb/serial/whiteheat.c | 4 ++-- include/linux/tty_driver.h | 2 +- include/linux/usb/serial.h | 2 +- include/net/irda/ircomm_tty.h | 2 +- net/bluetooth/rfcomm/tty.c | 2 +- net/irda/ircomm/ircomm_tty_ioctl.c | 4 ++-- 69 files changed, 98 insertions(+), 101 deletions(-) (limited to 'drivers') diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 6ee3348bc3e4..bc67e6839059 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c @@ -1194,7 +1194,7 @@ static int get_lsr_info(struct async_struct * info, unsigned int __user *value) } -static int rs_tiocmget(struct tty_struct *tty, struct file *file) +static int rs_tiocmget(struct tty_struct *tty) { struct async_struct * info = tty->driver_data; unsigned char control, status; diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 4f152c28f40e..e7945ddacd18 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c @@ -2429,7 +2429,7 @@ static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value) return put_user(result, (unsigned long __user *)value); } -static int cy_tiocmget(struct tty_struct *tty, struct file *file) +static int cy_tiocmget(struct tty_struct *tty) { struct cyclades_port *info = tty->driver_data; struct cyclades_card *card; diff --git a/drivers/char/epca.c b/drivers/char/epca.c index d9df46aa0fba..ecf6f0a889fc 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c @@ -1982,7 +1982,7 @@ static int info_ioctl(struct tty_struct *tty, struct file *file, return 0; } -static int pc_tiocmget(struct tty_struct *tty, struct file *file) +static int pc_tiocmget(struct tty_struct *tty) { struct channel *ch = tty->driver_data; struct board_chan __iomem *bc; @@ -2074,7 +2074,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file *file, return -EINVAL; switch (cmd) { case TIOCMODG: - mflag = pc_tiocmget(tty, file); + mflag = pc_tiocmget(tty); if (put_user(mflag, (unsigned long __user *)argp)) return -EFAULT; break; diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index c3a025356b8b..476cd087118e 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c @@ -181,7 +181,7 @@ static void ip2_unthrottle(PTTY); static void ip2_stop(PTTY); static void ip2_start(PTTY); static void ip2_hangup(PTTY); -static int ip2_tiocmget(struct tty_struct *tty, struct file *file); +static int ip2_tiocmget(struct tty_struct *tty); static int ip2_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static int ip2_get_icount(struct tty_struct *tty, @@ -2038,7 +2038,7 @@ ip2_stop ( PTTY tty ) /* Device Ioctl Section */ /******************************************************************************/ -static int ip2_tiocmget(struct tty_struct *tty, struct file *file) +static int ip2_tiocmget(struct tty_struct *tty) { i2ChanStrPtr pCh = DevTable[tty->index]; #ifdef ENABLE_DSSNOW diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index c27e9d21fea9..836370bc04c2 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c @@ -1065,7 +1065,7 @@ static int isicom_send_break(struct tty_struct *tty, int length) return 0; } -static int isicom_tiocmget(struct tty_struct *tty, struct file *file) +static int isicom_tiocmget(struct tty_struct *tty) { struct isi_port *port = tty->driver_data; /* just send the port status */ diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 7c6de4c92458..7843a847b76a 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c @@ -1501,7 +1501,7 @@ static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *s /*****************************************************************************/ -static int stli_tiocmget(struct tty_struct *tty, struct file *file) +static int stli_tiocmget(struct tty_struct *tty) { struct stliport *portp = tty->driver_data; struct stlibrd *brdp; diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 107b0bd58d19..fdf069bb702f 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c @@ -199,7 +199,7 @@ static void moxa_set_termios(struct tty_struct *, struct ktermios *); static void moxa_stop(struct tty_struct *); static void moxa_start(struct tty_struct *); static void moxa_hangup(struct tty_struct *); -static int moxa_tiocmget(struct tty_struct *tty, struct file *file); +static int moxa_tiocmget(struct tty_struct *tty); static int moxa_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static void moxa_poll(unsigned long); @@ -1257,7 +1257,7 @@ static int moxa_chars_in_buffer(struct tty_struct *tty) return chars; } -static int moxa_tiocmget(struct tty_struct *tty, struct file *file) +static int moxa_tiocmget(struct tty_struct *tty) { struct moxa_port *ch = tty->driver_data; int flag = 0, dtr, rts; diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index dd9d75351cd6..4d2f03ec06cd 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c @@ -1320,7 +1320,7 @@ static int mxser_get_lsr_info(struct mxser_port *info, return put_user(result, value); } -static int mxser_tiocmget(struct tty_struct *tty, struct file *file) +static int mxser_tiocmget(struct tty_struct *tty) { struct mxser_port *info = tty->driver_data; unsigned char control, status; diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index 294d03e8c61a..0e1dff2ffb1e 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c @@ -1750,7 +1750,7 @@ static int ntty_write_room(struct tty_struct *tty) } /* Gets io control parameters */ -static int ntty_tiocmget(struct tty_struct *tty, struct file *file) +static int ntty_tiocmget(struct tty_struct *tty) { const struct port *port = tty->driver_data; const struct ctrl_dl *ctrl_dl = &port->ctrl_dl; diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c index f5eb28b6cb0f..7d2ef4909a73 100644 --- a/drivers/char/pcmcia/ipwireless/tty.c +++ b/drivers/char/pcmcia/ipwireless/tty.c @@ -395,7 +395,7 @@ static int set_control_lines(struct ipw_tty *tty, unsigned int set, return 0; } -static int ipw_tiocmget(struct tty_struct *linux_tty, struct file *file) +static int ipw_tiocmget(struct tty_struct *linux_tty) { struct ipw_tty *tty = linux_tty->driver_data; /* FIXME: Exactly how is the tty object locked here .. */ diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index eaa41992fbe2..7b68ba6609fe 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -418,7 +418,7 @@ static void bh_status(MGSLPC_INFO *info); /* * ioctl handlers */ -static int tiocmget(struct tty_struct *tty, struct file *file); +static int tiocmget(struct tty_struct *tty); static int tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static int get_stats(MGSLPC_INFO *info, struct mgsl_icount __user *user_icount); @@ -2114,7 +2114,7 @@ static int modem_input_wait(MGSLPC_INFO *info,int arg) /* return the state of the serial control and status signals */ -static int tiocmget(struct tty_struct *tty, struct file *file) +static int tiocmget(struct tty_struct *tty) { MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data; unsigned int result; diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index af4de1fe8445..5d0c98456c93 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c @@ -1086,7 +1086,7 @@ static int rc_chars_in_buffer(struct tty_struct *tty) return port->xmit_cnt; } -static int rc_tiocmget(struct tty_struct *tty, struct file *file) +static int rc_tiocmget(struct tty_struct *tty) { struct riscom_port *port = tty->driver_data; struct riscom_board *bp; diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 3e4e73a0d7c1..75e98efbc8e9 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c @@ -1169,7 +1169,7 @@ static int sGetChanRI(CHANNEL_T * ChP) * Returns the state of the serial modem control lines. These next 2 functions * are the way kernel versions > 2.5 handle modem control lines rather than IOCTLs. */ -static int rp_tiocmget(struct tty_struct *tty, struct file *file) +static int rp_tiocmget(struct tty_struct *tty) { struct r_port *info = tty->driver_data; unsigned int control, result, ChanStatus; diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index 748c3b0ecd89..fda90643ead7 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c @@ -1308,7 +1308,7 @@ check_and_exit: return startup(info); } /* set_serial_info */ -static int cy_tiocmget(struct tty_struct *tty, struct file *file) +static int cy_tiocmget(struct tty_struct *tty) { struct cyclades_port *info = tty->driver_data; int channel; diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index c2bca3f25ef3..bfecfbef0895 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c @@ -1737,7 +1737,7 @@ static int sx_chars_in_buffer(struct tty_struct *tty) return port->xmit_cnt; } -static int sx_tiocmget(struct tty_struct *tty, struct file *file) +static int sx_tiocmget(struct tty_struct *tty) { struct specialix_port *port = tty->driver_data; struct specialix_board *bp; diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 461a5a045517..8c2bf3fb5b89 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c @@ -1094,7 +1094,7 @@ static int stl_setserial(struct tty_struct *tty, struct serial_struct __user *sp /*****************************************************************************/ -static int stl_tiocmget(struct tty_struct *tty, struct file *file) +static int stl_tiocmget(struct tty_struct *tty) { struct stlport *portp; diff --git a/drivers/char/sx.c b/drivers/char/sx.c index a786326cea2f..f46214e60d0c 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c @@ -1873,7 +1873,7 @@ static int sx_break(struct tty_struct *tty, int flag) return 0; } -static int sx_tiocmget(struct tty_struct *tty, struct file *file) +static int sx_tiocmget(struct tty_struct *tty) { struct sx_port *port = tty->driver_data; return sx_getsignals(port); diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index 3a6824f12be2..d359e092904a 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c @@ -823,7 +823,7 @@ static isr_dispatch_func UscIsrTable[7] = /* * ioctl call handlers */ -static int tiocmget(struct tty_struct *tty, struct file *file); +static int tiocmget(struct tty_struct *tty); static int tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount @@ -2846,7 +2846,7 @@ static int modem_input_wait(struct mgsl_struct *info,int arg) /* return the state of the serial control and status signals */ -static int tiocmget(struct tty_struct *tty, struct file *file) +static int tiocmget(struct tty_struct *tty) { struct mgsl_struct *info = tty->driver_data; unsigned int result; diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index d01fffeac951..f18ab8af0e1c 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c @@ -512,7 +512,7 @@ static int tx_abort(struct slgt_info *info); static int rx_enable(struct slgt_info *info, int enable); static int modem_input_wait(struct slgt_info *info,int arg); static int wait_mgsl_event(struct slgt_info *info, int __user *mask_ptr); -static int tiocmget(struct tty_struct *tty, struct file *file); +static int tiocmget(struct tty_struct *tty); static int tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static int set_break(struct tty_struct *tty, int break_state); @@ -3195,7 +3195,7 @@ static int modem_input_wait(struct slgt_info *info,int arg) /* * return state of serial control and status signals */ -static int tiocmget(struct tty_struct *tty, struct file *file) +static int tiocmget(struct tty_struct *tty) { struct slgt_info *info = tty->driver_data; unsigned int result; diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index 2f9eb4b0dec1..5900213ae75b 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c @@ -546,7 +546,7 @@ static int tx_abort(SLMP_INFO *info); static int rx_enable(SLMP_INFO *info, int enable); static int modem_input_wait(SLMP_INFO *info,int arg); static int wait_mgsl_event(SLMP_INFO *info, int __user *mask_ptr); -static int tiocmget(struct tty_struct *tty, struct file *file); +static int tiocmget(struct tty_struct *tty); static int tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static int set_break(struct tty_struct *tty, int break_state); @@ -3207,7 +3207,7 @@ static int modem_input_wait(SLMP_INFO *info,int arg) /* return the state of the serial control and status signals */ -static int tiocmget(struct tty_struct *tty, struct file *file) +static int tiocmget(struct tty_struct *tty) { SLMP_INFO *info = tty->driver_data; unsigned int result; diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index bb710d16a526..e1a7c14f5f1d 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c @@ -122,7 +122,7 @@ static int if_chars_in_buffer(struct tty_struct *tty); static void if_throttle(struct tty_struct *tty); static void if_unthrottle(struct tty_struct *tty); static void if_set_termios(struct tty_struct *tty, struct ktermios *old); -static int if_tiocmget(struct tty_struct *tty, struct file *file); +static int if_tiocmget(struct tty_struct *tty); static int if_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static int if_write(struct tty_struct *tty, @@ -280,7 +280,7 @@ static int if_ioctl(struct tty_struct *tty, struct file *file, return retval; } -static int if_tiocmget(struct tty_struct *tty, struct file *file) +static int if_tiocmget(struct tty_struct *tty) { struct cardstate *cs; int retval; diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index c463162843ba..ba6c2f124b58 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -1345,7 +1345,7 @@ isdn_tty_get_lsr_info(modem_info * info, uint __user * value) static int -isdn_tty_tiocmget(struct tty_struct *tty, struct file *file) +isdn_tty_tiocmget(struct tty_struct *tty) { modem_info *info = (modem_info *) tty->driver_data; u_char control, status; diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index a0716967b7c8..86bb04d821b1 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c @@ -956,7 +956,7 @@ static int sdio_uart_break_ctl(struct tty_struct *tty, int break_state) return 0; } -static int sdio_uart_tiocmget(struct tty_struct *tty, struct file *file) +static int sdio_uart_tiocmget(struct tty_struct *tty) { struct sdio_uart_port *port = tty->driver_data; int result; diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index bed8fcedff49..7c68c456c035 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1656,7 +1656,7 @@ static int hso_get_count(struct tty_struct *tty, } -static int hso_serial_tiocmget(struct tty_struct *tty, struct file *file) +static int hso_serial_tiocmget(struct tty_struct *tty) { int retval; struct hso_serial *serial = get_serial_by_tty(tty); diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c index 515d9b8af01e..d999e54a7730 100644 --- a/drivers/net/wan/pc300_tty.c +++ b/drivers/net/wan/pc300_tty.c @@ -133,7 +133,7 @@ static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char); static int pc300_tiocmset(struct tty_struct *, struct file *, unsigned int, unsigned int); -static int pc300_tiocmget(struct tty_struct *, struct file *); +static int pc300_tiocmget(struct tty_struct *); /* functions called by PC300 driver */ void cpc_tty_init(pc300dev_t *dev); @@ -570,7 +570,7 @@ static int pc300_tiocmset(struct tty_struct *tty, struct file *file, return 0; } -static int pc300_tiocmget(struct tty_struct *tty, struct file *file) +static int pc300_tiocmget(struct tty_struct *tty) { unsigned int result; unsigned char status; diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c index ed58f482c963..1e50292aef74 100644 --- a/drivers/staging/quatech_usb2/quatech_usb2.c +++ b/drivers/staging/quatech_usb2/quatech_usb2.c @@ -1078,7 +1078,7 @@ static void qt2_set_termios(struct tty_struct *tty, } } -static int qt2_tiocmget(struct tty_struct *tty, struct file *file) +static int qt2_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct usb_serial *serial = port->serial; diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 27841ef6a568..56ded56db7b4 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -1383,7 +1383,7 @@ static void qt_break(struct tty_struct *tty, int break_state) static inline int qt_real_tiocmget(struct tty_struct *tty, struct usb_serial_port *port, - struct file *file, struct usb_serial *serial) + struct usb_serial *serial) { u8 mcr; @@ -1462,7 +1462,7 @@ static inline int qt_real_tiocmset(struct tty_struct *tty, return 0; } -static int qt_tiocmget(struct tty_struct *tty, struct file *file) +static int qt_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct usb_serial *serial = get_usb_serial(port, __func__); @@ -1480,7 +1480,7 @@ static int qt_tiocmget(struct tty_struct *tty, struct file *file) dbg("%s - port %d\n", __func__, port->number); dbg("%s - port->RxHolding = %d\n", __func__, qt_port->RxHolding); - retval = qt_real_tiocmget(tty, port, file, serial); + retval = qt_real_tiocmget(tty, port, serial); spin_unlock_irqrestore(&qt_port->lock, flags); return retval; diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index 67a75a502c01..55293105a56c 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c @@ -1095,7 +1095,7 @@ static void hvsi_unthrottle(struct tty_struct *tty) h_vio_signal(hp->vtermno, VIO_IRQ_ENABLE); } -static int hvsi_tiocmget(struct tty_struct *tty, struct file *file) +static int hvsi_tiocmget(struct tty_struct *tty) { struct hvsi_struct *hp = tty->driver_data; diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 44b8412a04e8..97e3d509ff82 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2648,7 +2648,7 @@ static void gsmtty_wait_until_sent(struct tty_struct *tty, int timeout) to do here */ } -static int gsmtty_tiocmget(struct tty_struct *tty, struct file *filp) +static int gsmtty_tiocmget(struct tty_struct *tty) { struct gsm_dlci *dlci = tty->driver_data; return dlci->modem_rx; diff --git a/drivers/tty/serial/68360serial.c b/drivers/tty/serial/68360serial.c index 88b13356ec10..2a52cf14ce50 100644 --- a/drivers/tty/serial/68360serial.c +++ b/drivers/tty/serial/68360serial.c @@ -1240,7 +1240,7 @@ static int get_lsr_info(struct async_struct * info, unsigned int *value) } #endif -static int rs_360_tiocmget(struct tty_struct *tty, struct file *file) +static int rs_360_tiocmget(struct tty_struct *tty) { ser_info_t *info = (ser_info_t *)tty->driver_data; unsigned int result = 0; diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index bcc31f2140ac..8cc5c0224b25 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c @@ -3614,7 +3614,7 @@ rs_tiocmset(struct tty_struct *tty, struct file *file, } static int -rs_tiocmget(struct tty_struct *tty, struct file *file) +rs_tiocmget(struct tty_struct *tty) { struct e100_serial *info = (struct e100_serial *)tty->driver_data; unsigned int result; diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index b68b96f53e6c..4d26d39ec344 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -245,7 +245,7 @@ static void ifx_spi_timeout(unsigned long arg) * Map the signal state into Linux modem flags and report the value * in Linux terms */ -static int ifx_spi_tiocmget(struct tty_struct *tty, struct file *filp) +static int ifx_spi_tiocmget(struct tty_struct *tty) { unsigned int value; struct ifx_spi_device *ifx_dev = tty->driver_data; diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 20563c509b21..53e490e47560 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -905,7 +905,7 @@ static int uart_get_lsr_info(struct tty_struct *tty, return put_user(result, value); } -static int uart_tiocmget(struct tty_struct *tty, struct file *file) +static int uart_tiocmget(struct tty_struct *tty) { struct uart_state *state = tty->driver_data; struct tty_port *port = &state->port; @@ -913,10 +913,8 @@ static int uart_tiocmget(struct tty_struct *tty, struct file *file) int result = -EIO; mutex_lock(&port->mutex); - if ((!file || !tty_hung_up_p(file)) && - !(tty->flags & (1 << TTY_IO_ERROR))) { + if (!(tty->flags & (1 << TTY_IO_ERROR))) { result = uport->mctrl; - spin_lock_irq(&uport->lock); result |= uport->ops->get_mctrl(uport); spin_unlock_irq(&uport->lock); diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 0065da4b11c1..fde5a4dae3dd 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2465,12 +2465,12 @@ out: * Locking: none (up to the driver) */ -static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p) +static int tty_tiocmget(struct tty_struct *tty, int __user *p) { int retval = -EINVAL; if (tty->ops->tiocmget) { - retval = tty->ops->tiocmget(tty, file); + retval = tty->ops->tiocmget(tty); if (retval >= 0) retval = put_user(retval, p); @@ -2655,7 +2655,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return send_break(tty, arg ? arg*100 : 250); case TIOCMGET: - return tty_tiocmget(tty, file, p); + return tty_tiocmget(tty, p); case TIOCMSET: case TIOCMBIC: case TIOCMBIS: diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index d6ede989ff22..2ae996b7ce7b 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -776,7 +776,7 @@ static int acm_tty_break_ctl(struct tty_struct *tty, int state) return retval; } -static int acm_tty_tiocmget(struct tty_struct *tty, struct file *file) +static int acm_tty_tiocmget(struct tty_struct *tty) { struct acm *acm = tty->driver_data; diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 8f1d4fb19d24..35b610aa3f92 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -485,7 +485,7 @@ static int ark3116_ioctl(struct tty_struct *tty, struct file *file, return -ENOIOCTLCMD; } -static int ark3116_tiocmget(struct tty_struct *tty, struct file *file) +static int ark3116_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct ark3116_private *priv = usb_get_serial_port_data(port); diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 36df35295db2..48fb3bad3cd6 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -100,7 +100,7 @@ static void belkin_sa_process_read_urb(struct urb *urb); static void belkin_sa_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios * old); static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state); -static int belkin_sa_tiocmget(struct tty_struct *tty, struct file *file); +static int belkin_sa_tiocmget(struct tty_struct *tty); static int belkin_sa_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); @@ -497,7 +497,7 @@ static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state) dev_err(&port->dev, "Set break_ctl %d\n", break_state); } -static int belkin_sa_tiocmget(struct tty_struct *tty, struct file *file) +static int belkin_sa_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct belkin_sa_private *priv = usb_get_serial_port_data(port); diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 7b8815ddf368..aa0962b72f4c 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -572,7 +572,7 @@ static int ch341_ioctl(struct tty_struct *tty, struct file *file, return -ENOIOCTLCMD; } -static int ch341_tiocmget(struct tty_struct *tty, struct file *file) +static int ch341_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct ch341_private *priv = usb_get_serial_port_data(port); diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 735ea03157ab..b3873815035c 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -41,7 +41,7 @@ static void cp210x_get_termios_port(struct usb_serial_port *port, unsigned int *cflagp, unsigned int *baudp); static void cp210x_set_termios(struct tty_struct *, struct usb_serial_port *, struct ktermios*); -static int cp210x_tiocmget(struct tty_struct *, struct file *); +static int cp210x_tiocmget(struct tty_struct *); static int cp210x_tiocmset(struct tty_struct *, struct file *, unsigned int, unsigned int); static int cp210x_tiocmset_port(struct usb_serial_port *port, struct file *, @@ -742,7 +742,7 @@ static void cp210x_dtr_rts(struct usb_serial_port *p, int on) cp210x_tiocmset_port(p, NULL, 0, TIOCM_DTR|TIOCM_RTS); } -static int cp210x_tiocmget (struct tty_struct *tty, struct file *file) +static int cp210x_tiocmget (struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; unsigned int control; diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 2edf238b00b9..9c96cff691fd 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -173,7 +173,7 @@ static int cypress_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); static void cypress_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); -static int cypress_tiocmget(struct tty_struct *tty, struct file *file); +static int cypress_tiocmget(struct tty_struct *tty); static int cypress_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static int cypress_chars_in_buffer(struct tty_struct *tty); @@ -864,7 +864,7 @@ static int cypress_write_room(struct tty_struct *tty) } -static int cypress_tiocmget(struct tty_struct *tty, struct file *file) +static int cypress_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct cypress_private *priv = usb_get_serial_port_data(port); diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 666e5a6edd82..08da46cb5825 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -445,7 +445,7 @@ static void digi_rx_unthrottle(struct tty_struct *tty); static void digi_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios); static void digi_break_ctl(struct tty_struct *tty, int break_state); -static int digi_tiocmget(struct tty_struct *tty, struct file *file); +static int digi_tiocmget(struct tty_struct *tty); static int digi_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static int digi_write(struct tty_struct *tty, struct usb_serial_port *port, @@ -1118,7 +1118,7 @@ static void digi_break_ctl(struct tty_struct *tty, int break_state) } -static int digi_tiocmget(struct tty_struct *tty, struct file *file) +static int digi_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct digi_port *priv = usb_get_serial_port_data(port); diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 4787c0cd063f..281d18141051 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -856,7 +856,7 @@ static int ftdi_prepare_write_buffer(struct usb_serial_port *port, void *dest, size_t size); static void ftdi_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); -static int ftdi_tiocmget(struct tty_struct *tty, struct file *file); +static int ftdi_tiocmget(struct tty_struct *tty); static int ftdi_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static int ftdi_ioctl(struct tty_struct *tty, struct file *file, @@ -2149,7 +2149,7 @@ static void ftdi_set_termios(struct tty_struct *tty, } } -static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) +static int ftdi_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct ftdi_private *priv = usb_get_serial_port_data(port); diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index cd769ef24f8a..e8fe4dcf72f0 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -219,7 +219,7 @@ static void edge_set_termios(struct tty_struct *tty, static int edge_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); static void edge_break(struct tty_struct *tty, int break_state); -static int edge_tiocmget(struct tty_struct *tty, struct file *file); +static int edge_tiocmget(struct tty_struct *tty); static int edge_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static int edge_get_icount(struct tty_struct *tty, @@ -1599,7 +1599,7 @@ static int edge_tiocmset(struct tty_struct *tty, struct file *file, return 0; } -static int edge_tiocmget(struct tty_struct *tty, struct file *file) +static int edge_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct edgeport_port *edge_port = usb_get_serial_port_data(port); diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 22506b095c4f..7cb9f5cb91f3 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -2477,7 +2477,7 @@ static int edge_tiocmset(struct tty_struct *tty, struct file *file, return 0; } -static int edge_tiocmget(struct tty_struct *tty, struct file *file) +static int edge_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct edgeport_port *edge_port = usb_get_serial_port_data(port); diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 99b97c04896f..1d96142f135a 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -179,7 +179,7 @@ static int iuu_tiocmset(struct tty_struct *tty, struct file *file, * When no card , the reader respond with TIOCM_CD * This is known as CD autodetect mechanism */ -static int iuu_tiocmget(struct tty_struct *tty, struct file *file) +static int iuu_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct iuu_private *priv = usb_get_serial_port_data(port); diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 0791778a66f3..1beebbb7a20a 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -301,7 +301,7 @@ static void keyspan_set_termios(struct tty_struct *tty, keyspan_send_setup(port, 0); } -static int keyspan_tiocmget(struct tty_struct *tty, struct file *file) +static int keyspan_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct keyspan_port_private *p_priv = usb_get_serial_port_data(port); diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index ce134dc28ddf..5e5fc71e68df 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h @@ -58,8 +58,7 @@ static void keyspan_set_termios (struct tty_struct *tty, struct ktermios *old); static void keyspan_break_ctl (struct tty_struct *tty, int break_state); -static int keyspan_tiocmget (struct tty_struct *tty, - struct file *file); +static int keyspan_tiocmget (struct tty_struct *tty); static int keyspan_tiocmset (struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 554a8693a463..49ad2baf77cd 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -457,7 +457,7 @@ static int keyspan_pda_set_modem_info(struct usb_serial *serial, return rc; } -static int keyspan_pda_tiocmget(struct tty_struct *tty, struct file *file) +static int keyspan_pda_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct usb_serial *serial = port->serial; diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index e8a65ce45a2f..a570f5201c73 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -68,7 +68,7 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port); static void klsi_105_close(struct usb_serial_port *port); static void klsi_105_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); -static int klsi_105_tiocmget(struct tty_struct *tty, struct file *file); +static int klsi_105_tiocmget(struct tty_struct *tty); static int klsi_105_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static void klsi_105_process_read_urb(struct urb *urb); @@ -637,7 +637,7 @@ static void mct_u232_break_ctl(struct tty_struct *tty, int break_state) } #endif -static int klsi_105_tiocmget(struct tty_struct *tty, struct file *file) +static int klsi_105_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct klsi_105_private *priv = usb_get_serial_port_data(port); diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index bd5bd8589e04..81d07fb299b8 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -77,7 +77,7 @@ static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port, static int kobil_write_room(struct tty_struct *tty); static int kobil_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); -static int kobil_tiocmget(struct tty_struct *tty, struct file *file); +static int kobil_tiocmget(struct tty_struct *tty); static int kobil_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static void kobil_read_int_callback(struct urb *urb); @@ -504,7 +504,7 @@ static int kobil_write_room(struct tty_struct *tty) } -static int kobil_tiocmget(struct tty_struct *tty, struct file *file) +static int kobil_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct kobil_private *priv; diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 2849f8c32015..27447095feae 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -101,7 +101,7 @@ static void mct_u232_read_int_callback(struct urb *urb); static void mct_u232_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); static void mct_u232_break_ctl(struct tty_struct *tty, int break_state); -static int mct_u232_tiocmget(struct tty_struct *tty, struct file *file); +static int mct_u232_tiocmget(struct tty_struct *tty); static int mct_u232_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static void mct_u232_throttle(struct tty_struct *tty); @@ -762,7 +762,7 @@ static void mct_u232_break_ctl(struct tty_struct *tty, int break_state) } /* mct_u232_break_ctl */ -static int mct_u232_tiocmget(struct tty_struct *tty, struct file *file) +static int mct_u232_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct mct_u232_private *priv = usb_get_serial_port_data(port); diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 7d3bc9a3e2b6..5d40d4151b5a 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -1833,7 +1833,7 @@ static int get_lsr_info(struct tty_struct *tty, return 0; } -static int mos7720_tiocmget(struct tty_struct *tty, struct file *file) +static int mos7720_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct moschip_port *mos7720_port = usb_get_serial_port_data(port); @@ -1865,7 +1865,7 @@ static int mos7720_tiocmset(struct tty_struct *tty, struct file *file, struct moschip_port *mos7720_port = usb_get_serial_port_data(port); unsigned int mcr ; dbg("%s - port %d", __func__, port->number); - dbg("he was at tiocmget"); + dbg("he was at tiocmset"); mcr = mos7720_port->shadowMCR; diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 5627993f9e41..ee0dc9a0890c 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -1644,7 +1644,7 @@ static void mos7840_unthrottle(struct tty_struct *tty) } } -static int mos7840_tiocmget(struct tty_struct *tty, struct file *file) +static int mos7840_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct moschip_port *mos7840_port; diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index eda1f9266c4e..e305df807396 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -352,7 +352,7 @@ static void opticon_unthrottle(struct tty_struct *tty) } } -static int opticon_tiocmget(struct tty_struct *tty, struct file *file) +static int opticon_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct opticon_private *priv = usb_get_serial_data(port->serial); diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index 73613205be7a..4cd3b0ef4e61 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -144,7 +144,7 @@ static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count); static int oti6858_write_room(struct tty_struct *tty); static int oti6858_chars_in_buffer(struct tty_struct *tty); -static int oti6858_tiocmget(struct tty_struct *tty, struct file *file); +static int oti6858_tiocmget(struct tty_struct *tty); static int oti6858_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static int oti6858_startup(struct usb_serial *serial); @@ -657,7 +657,7 @@ static int oti6858_tiocmset(struct tty_struct *tty, struct file *file, return 0; } -static int oti6858_tiocmget(struct tty_struct *tty, struct file *file) +static int oti6858_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct oti6858_private *priv = usb_get_serial_port_data(port); diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 08c9181b8e48..6cb4f503a3f1 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -531,7 +531,7 @@ static int pl2303_tiocmset(struct tty_struct *tty, struct file *file, return set_control_lines(port->serial->dev, control); } -static int pl2303_tiocmget(struct tty_struct *tty, struct file *file) +static int pl2303_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct pl2303_private *priv = usb_get_serial_port_data(port); diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 7481ff8a49e4..66437f1e9e5b 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -389,7 +389,7 @@ static void sierra_set_termios(struct tty_struct *tty, sierra_send_setup(port); } -static int sierra_tiocmget(struct tty_struct *tty, struct file *file) +static int sierra_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; unsigned int value; diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index cbfb70bffdd0..cac13009fc5c 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -618,7 +618,7 @@ static int spcp8x5_tiocmset(struct tty_struct *tty, struct file *file, return spcp8x5_set_ctrlLine(port->serial->dev, control , priv->type); } -static int spcp8x5_tiocmget(struct tty_struct *tty, struct file *file) +static int spcp8x5_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct spcp8x5_private *priv = usb_get_serial_port_data(port); diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index 8359ec798959..b21583fa825c 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c @@ -484,7 +484,7 @@ static int ssu100_attach(struct usb_serial *serial) return ssu100_initdevice(serial->dev); } -static int ssu100_tiocmget(struct tty_struct *tty, struct file *file) +static int ssu100_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct usb_device *dev = port->serial->dev; diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index b2902f307b47..223e60e31735 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -112,7 +112,7 @@ static int ti_get_icount(struct tty_struct *tty, struct serial_icounter_struct *icount); static void ti_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios); -static int ti_tiocmget(struct tty_struct *tty, struct file *file); +static int ti_tiocmget(struct tty_struct *tty); static int ti_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static void ti_break(struct tty_struct *tty, int break_state); @@ -1000,7 +1000,7 @@ static void ti_set_termios(struct tty_struct *tty, } -static int ti_tiocmget(struct tty_struct *tty, struct file *file) +static int ti_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct ti_port *tport = usb_get_serial_port_data(port); diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 546a52179bec..df105c6531a1 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -496,14 +496,14 @@ static const struct file_operations serial_proc_fops = { .release = single_release, }; -static int serial_tiocmget(struct tty_struct *tty, struct file *file) +static int serial_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; dbg("%s - port %d", __func__, port->number); if (port->serial->type->tiocmget) - return port->serial->type->tiocmget(tty, file); + return port->serial->type->tiocmget(tty); return -EINVAL; } diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h index 3ab77c5d9819..8b68fc783d5f 100644 --- a/drivers/usb/serial/usb-wwan.h +++ b/drivers/usb/serial/usb-wwan.h @@ -15,7 +15,7 @@ extern int usb_wwan_write_room(struct tty_struct *tty); extern void usb_wwan_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); -extern int usb_wwan_tiocmget(struct tty_struct *tty, struct file *file); +extern int usb_wwan_tiocmget(struct tty_struct *tty); extern int usb_wwan_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); extern int usb_wwan_ioctl(struct tty_struct *tty, struct file *file, diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index b004b2a485c3..60f942632cb4 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -79,7 +79,7 @@ void usb_wwan_set_termios(struct tty_struct *tty, } EXPORT_SYMBOL(usb_wwan_set_termios); -int usb_wwan_tiocmget(struct tty_struct *tty, struct file *file) +int usb_wwan_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; unsigned int value; diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 3f9ac88d588c..bf850139e0b8 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -156,7 +156,7 @@ static int whiteheat_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); static void whiteheat_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); -static int whiteheat_tiocmget(struct tty_struct *tty, struct file *file); +static int whiteheat_tiocmget(struct tty_struct *tty); static int whiteheat_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static void whiteheat_break_ctl(struct tty_struct *tty, int break_state); @@ -833,7 +833,7 @@ static int whiteheat_write_room(struct tty_struct *tty) return (room); } -static int whiteheat_tiocmget(struct tty_struct *tty, struct file *file) +static int whiteheat_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct whiteheat_private *info = usb_get_serial_port_data(port); diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index c3d43eb4150c..9539d74171db 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -271,7 +271,7 @@ struct tty_operations { void (*set_ldisc)(struct tty_struct *tty); void (*wait_until_sent)(struct tty_struct *tty, int timeout); void (*send_xchar)(struct tty_struct *tty, char ch); - int (*tiocmget)(struct tty_struct *tty, struct file *file); + int (*tiocmget)(struct tty_struct *tty); int (*tiocmset)(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); int (*resize)(struct tty_struct *tty, struct winsize *ws); diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index c9049139a7a5..30b945397d19 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -268,7 +268,7 @@ struct usb_serial_driver { int (*chars_in_buffer)(struct tty_struct *tty); void (*throttle)(struct tty_struct *tty); void (*unthrottle)(struct tty_struct *tty); - int (*tiocmget)(struct tty_struct *tty, struct file *file); + int (*tiocmget)(struct tty_struct *tty); int (*tiocmset)(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); int (*get_icount)(struct tty_struct *tty, diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h index eea2e6152389..fa3793b5392d 100644 --- a/include/net/irda/ircomm_tty.h +++ b/include/net/irda/ircomm_tty.h @@ -120,7 +120,7 @@ struct ircomm_tty_cb { void ircomm_tty_start(struct tty_struct *tty); void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self); -extern int ircomm_tty_tiocmget(struct tty_struct *tty, struct file *file); +extern int ircomm_tty_tiocmget(struct tty_struct *tty); extern int ircomm_tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); extern int ircomm_tty_ioctl(struct tty_struct *tty, struct file *file, diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 2575c2db6404..7f67fa4f2f5e 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -1089,7 +1089,7 @@ static void rfcomm_tty_hangup(struct tty_struct *tty) } } -static int rfcomm_tty_tiocmget(struct tty_struct *tty, struct file *filp) +static int rfcomm_tty_tiocmget(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c index 24cb3aa2bbfb..bb47caeba7e6 100644 --- a/net/irda/ircomm/ircomm_tty_ioctl.c +++ b/net/irda/ircomm/ircomm_tty_ioctl.c @@ -189,12 +189,12 @@ void ircomm_tty_set_termios(struct tty_struct *tty, } /* - * Function ircomm_tty_tiocmget (tty, file) + * Function ircomm_tty_tiocmget (tty) * * * */ -int ircomm_tty_tiocmget(struct tty_struct *tty, struct file *file) +int ircomm_tty_tiocmget(struct tty_struct *tty) { struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; unsigned int result; -- cgit v1.2.3 From 20b9d17715017ae4dd4ec87fabc36d33b9de708e Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 14 Feb 2011 16:26:50 +0000 Subject: tiocmset: kill the file pointer argument Doing tiocmget was such fun we should do tiocmset as well for the same reasons Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/char/amiserial.c | 4 ++-- drivers/char/cyclades.c | 2 +- drivers/char/epca.c | 4 ++-- drivers/char/ip2/ip2main.c | 4 ++-- drivers/char/isicom.c | 4 ++-- drivers/char/istallion.c | 2 +- drivers/char/moxa.c | 4 ++-- drivers/char/mxser.c | 2 +- drivers/char/nozomi.c | 4 ++-- drivers/char/pcmcia/ipwireless/tty.c | 2 +- drivers/char/pcmcia/synclink_cs.c | 6 +++--- drivers/char/riscom8.c | 4 ++-- drivers/char/rocket.c | 4 ++-- drivers/char/serial167.c | 3 +-- drivers/char/specialix.c | 2 +- drivers/char/stallion.c | 2 +- drivers/char/sx.c | 4 ++-- drivers/char/synclink.c | 6 +++--- drivers/char/synclink_gt.c | 6 +++--- drivers/char/synclinkmp.c | 8 ++++---- drivers/isdn/gigaset/interface.c | 4 ++-- drivers/isdn/gigaset/ser-gigaset.c | 2 +- drivers/isdn/i4l/isdn_tty.c | 2 +- drivers/mmc/card/sdio_uart.c | 2 +- drivers/net/irda/irtty-sir.c | 2 +- drivers/net/usb/hso.c | 6 +++--- drivers/net/wan/pc300_tty.c | 5 ++--- drivers/staging/quatech_usb2/quatech_usb2.c | 2 +- drivers/staging/serqt_usb2/serqt_usb2.c | 5 ++--- drivers/tty/hvc/hvsi.c | 4 ++-- drivers/tty/n_gsm.c | 2 +- drivers/tty/serial/68360serial.c | 2 +- drivers/tty/serial/crisv10.c | 3 +-- drivers/tty/serial/ifx6x60.c | 3 +-- drivers/tty/serial/serial_core.c | 6 ++---- drivers/tty/tty_io.c | 7 +++---- drivers/usb/class/cdc-acm.c | 2 +- drivers/usb/serial/ark3116.c | 2 +- drivers/usb/serial/belkin_sa.c | 4 ++-- drivers/usb/serial/ch341.c | 2 +- drivers/usb/serial/cp210x.c | 15 +++++++-------- drivers/usb/serial/cypress_m8.c | 4 ++-- drivers/usb/serial/digi_acceleport.c | 10 +++++----- drivers/usb/serial/ftdi_sio.c | 4 ++-- drivers/usb/serial/io_edgeport.c | 4 ++-- drivers/usb/serial/io_ti.c | 2 +- drivers/usb/serial/iuu_phoenix.c | 2 +- drivers/usb/serial/keyspan.c | 2 +- drivers/usb/serial/keyspan.h | 2 +- drivers/usb/serial/keyspan_pda.c | 2 +- drivers/usb/serial/kl5kusb105.c | 4 ++-- drivers/usb/serial/kobil_sct.c | 4 ++-- drivers/usb/serial/mct_u232.c | 4 ++-- drivers/usb/serial/mos7720.c | 2 +- drivers/usb/serial/mos7840.c | 2 +- drivers/usb/serial/oti6858.c | 4 ++-- drivers/usb/serial/pl2303.c | 2 +- drivers/usb/serial/sierra.c | 2 +- drivers/usb/serial/spcp8x5.c | 2 +- drivers/usb/serial/ssu100.c | 2 +- drivers/usb/serial/ti_usb_3410_5052.c | 6 +++--- drivers/usb/serial/usb-serial.c | 4 ++-- drivers/usb/serial/usb-wwan.h | 2 +- drivers/usb/serial/usb_wwan.c | 2 +- drivers/usb/serial/whiteheat.c | 4 ++-- include/linux/tty_driver.h | 2 +- include/linux/usb/serial.h | 2 +- include/net/irda/ircomm_tty.h | 2 +- net/bluetooth/rfcomm/tty.c | 2 +- net/irda/ircomm/ircomm_tty_ioctl.c | 4 ++-- 70 files changed, 120 insertions(+), 129 deletions(-) (limited to 'drivers') diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index bc67e6839059..5c15fad71ad2 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c @@ -1216,8 +1216,8 @@ static int rs_tiocmget(struct tty_struct *tty) | (!(status & SER_CTS) ? TIOCM_CTS : 0); } -static int rs_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) +static int rs_tiocmset(struct tty_struct *tty, unsigned int set, + unsigned int clear) { struct async_struct * info = tty->driver_data; unsigned long flags; diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index e7945ddacd18..942b6f2b70a4 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c @@ -2483,7 +2483,7 @@ end: } /* cy_tiomget */ static int -cy_tiocmset(struct tty_struct *tty, struct file *file, +cy_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct cyclades_port *info = tty->driver_data; diff --git a/drivers/char/epca.c b/drivers/char/epca.c index ecf6f0a889fc..e5872b59f9cd 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c @@ -2015,7 +2015,7 @@ static int pc_tiocmget(struct tty_struct *tty) return mflag; } -static int pc_tiocmset(struct tty_struct *tty, struct file *file, +static int pc_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct channel *ch = tty->driver_data; @@ -2081,7 +2081,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file *file, case TIOCMODS: if (get_user(mstat, (unsigned __user *)argp)) return -EFAULT; - return pc_tiocmset(tty, file, mstat, ~mstat); + return pc_tiocmset(tty, mstat, ~mstat); case TIOCSDTR: spin_lock_irqsave(&epca_lock, flags); ch->omodem |= ch->m_dtr; diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 476cd087118e..d5f866c7c672 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c @@ -182,7 +182,7 @@ static void ip2_stop(PTTY); static void ip2_start(PTTY); static void ip2_hangup(PTTY); static int ip2_tiocmget(struct tty_struct *tty); -static int ip2_tiocmset(struct tty_struct *tty, struct file *file, +static int ip2_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); static int ip2_get_icount(struct tty_struct *tty, struct serial_icounter_struct *icount); @@ -2085,7 +2085,7 @@ static int ip2_tiocmget(struct tty_struct *tty) | ((pCh->dataSetIn & I2_CTS) ? TIOCM_CTS : 0); } -static int ip2_tiocmset(struct tty_struct *tty, struct file *file, +static int ip2_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { i2ChanStrPtr pCh = DevTable[tty->index]; diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 836370bc04c2..60f4d8ae7a49 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c @@ -1082,8 +1082,8 @@ static int isicom_tiocmget(struct tty_struct *tty) ((status & ISI_RI ) ? TIOCM_RI : 0); } -static int isicom_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) +static int isicom_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) { struct isi_port *port = tty->driver_data; unsigned long flags; diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 7843a847b76a..763b58d58255 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c @@ -1524,7 +1524,7 @@ static int stli_tiocmget(struct tty_struct *tty) return stli_mktiocm(portp->asig.sigvalue); } -static int stli_tiocmset(struct tty_struct *tty, struct file *file, +static int stli_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct stliport *portp = tty->driver_data; diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index fdf069bb702f..9f4cd8968a5a 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c @@ -200,7 +200,7 @@ static void moxa_stop(struct tty_struct *); static void moxa_start(struct tty_struct *); static void moxa_hangup(struct tty_struct *); static int moxa_tiocmget(struct tty_struct *tty); -static int moxa_tiocmset(struct tty_struct *tty, struct file *file, +static int moxa_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); static void moxa_poll(unsigned long); static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); @@ -1277,7 +1277,7 @@ static int moxa_tiocmget(struct tty_struct *tty) return flag; } -static int moxa_tiocmset(struct tty_struct *tty, struct file *file, +static int moxa_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct moxa_port *ch; diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 4d2f03ec06cd..150a862c4989 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c @@ -1347,7 +1347,7 @@ static int mxser_tiocmget(struct tty_struct *tty) ((status & UART_MSR_CTS) ? TIOCM_CTS : 0); } -static int mxser_tiocmset(struct tty_struct *tty, struct file *file, +static int mxser_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct mxser_port *info = tty->driver_data; diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index 0e1dff2ffb1e..1b74c48c4016 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c @@ -1767,8 +1767,8 @@ static int ntty_tiocmget(struct tty_struct *tty) } /* Sets io controls parameters */ -static int ntty_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) +static int ntty_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) { struct nozomi *dc = get_dc_by_tty(tty); unsigned long flags; diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c index 7d2ef4909a73..748190dfbab0 100644 --- a/drivers/char/pcmcia/ipwireless/tty.c +++ b/drivers/char/pcmcia/ipwireless/tty.c @@ -410,7 +410,7 @@ static int ipw_tiocmget(struct tty_struct *linux_tty) } static int -ipw_tiocmset(struct tty_struct *linux_tty, struct file *file, +ipw_tiocmset(struct tty_struct *linux_tty, unsigned int set, unsigned int clear) { struct ipw_tty *tty = linux_tty->driver_data; diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 7b68ba6609fe..02127cad0980 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -419,8 +419,8 @@ static void bh_status(MGSLPC_INFO *info); * ioctl handlers */ static int tiocmget(struct tty_struct *tty); -static int tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear); +static int tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear); static int get_stats(MGSLPC_INFO *info, struct mgsl_icount __user *user_icount); static int get_params(MGSLPC_INFO *info, MGSL_PARAMS __user *user_params); static int set_params(MGSLPC_INFO *info, MGSL_PARAMS __user *new_params, struct tty_struct *tty); @@ -2139,7 +2139,7 @@ static int tiocmget(struct tty_struct *tty) /* set modem control signals (DTR/RTS) */ -static int tiocmset(struct tty_struct *tty, struct file *file, +static int tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data; diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 5d0c98456c93..3666decc6438 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c @@ -1115,8 +1115,8 @@ static int rc_tiocmget(struct tty_struct *tty) return result; } -static int rc_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) +static int rc_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) { struct riscom_port *port = tty->driver_data; unsigned long flags; diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 75e98efbc8e9..36c108811a81 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c @@ -1189,8 +1189,8 @@ static int rp_tiocmget(struct tty_struct *tty) /* * Sets the modem control lines */ -static int rp_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) +static int rp_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) { struct r_port *info = tty->driver_data; diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index fda90643ead7..89ac542ffff2 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c @@ -1331,8 +1331,7 @@ static int cy_tiocmget(struct tty_struct *tty) } /* cy_tiocmget */ static int -cy_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) +cy_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct cyclades_port *info = tty->driver_data; int channel; diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index bfecfbef0895..a6b23847e4a7 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c @@ -1778,7 +1778,7 @@ static int sx_tiocmget(struct tty_struct *tty) } -static int sx_tiocmset(struct tty_struct *tty, struct file *file, +static int sx_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct specialix_port *port = tty->driver_data; diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 8c2bf3fb5b89..c42dbffbed16 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c @@ -1107,7 +1107,7 @@ static int stl_tiocmget(struct tty_struct *tty) return stl_getsignals(portp); } -static int stl_tiocmset(struct tty_struct *tty, struct file *file, +static int stl_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct stlport *portp; diff --git a/drivers/char/sx.c b/drivers/char/sx.c index f46214e60d0c..342c6ae67da5 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c @@ -1879,8 +1879,8 @@ static int sx_tiocmget(struct tty_struct *tty) return sx_getsignals(port); } -static int sx_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) +static int sx_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) { struct sx_port *port = tty->driver_data; int rts = -1, dtr = -1; diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index d359e092904a..691e1094c20b 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c @@ -824,7 +824,7 @@ static isr_dispatch_func UscIsrTable[7] = * ioctl call handlers */ static int tiocmget(struct tty_struct *tty); -static int tiocmset(struct tty_struct *tty, struct file *file, +static int tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount __user *user_icount); @@ -2871,8 +2871,8 @@ static int tiocmget(struct tty_struct *tty) /* set modem control signals (DTR/RTS) */ -static int tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) +static int tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) { struct mgsl_struct *info = tty->driver_data; unsigned long flags; diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index f18ab8af0e1c..04da6d61dc4f 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c @@ -513,8 +513,8 @@ static int rx_enable(struct slgt_info *info, int enable); static int modem_input_wait(struct slgt_info *info,int arg); static int wait_mgsl_event(struct slgt_info *info, int __user *mask_ptr); static int tiocmget(struct tty_struct *tty); -static int tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear); +static int tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear); static int set_break(struct tty_struct *tty, int break_state); static int get_interface(struct slgt_info *info, int __user *if_mode); static int set_interface(struct slgt_info *info, int if_mode); @@ -3223,7 +3223,7 @@ static int tiocmget(struct tty_struct *tty) * TIOCMSET = set/clear signal values * value bit mask for command */ -static int tiocmset(struct tty_struct *tty, struct file *file, +static int tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct slgt_info *info = tty->driver_data; diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index 5900213ae75b..1f9de97e8cfc 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c @@ -547,8 +547,8 @@ static int rx_enable(SLMP_INFO *info, int enable); static int modem_input_wait(SLMP_INFO *info,int arg); static int wait_mgsl_event(SLMP_INFO *info, int __user *mask_ptr); static int tiocmget(struct tty_struct *tty); -static int tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear); +static int tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear); static int set_break(struct tty_struct *tty, int break_state); static void add_device(SLMP_INFO *info); @@ -3232,8 +3232,8 @@ static int tiocmget(struct tty_struct *tty) /* set modem control signals (DTR/RTS) */ -static int tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) +static int tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) { SLMP_INFO *info = tty->driver_data; unsigned long flags; diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index e1a7c14f5f1d..9b2bb491c614 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c @@ -123,7 +123,7 @@ static void if_throttle(struct tty_struct *tty); static void if_unthrottle(struct tty_struct *tty); static void if_set_termios(struct tty_struct *tty, struct ktermios *old); static int if_tiocmget(struct tty_struct *tty); -static int if_tiocmset(struct tty_struct *tty, struct file *file, +static int if_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); static int if_write(struct tty_struct *tty, const unsigned char *buf, int count); @@ -303,7 +303,7 @@ static int if_tiocmget(struct tty_struct *tty) return retval; } -static int if_tiocmset(struct tty_struct *tty, struct file *file, +static int if_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct cardstate *cs; diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c index 0ef09d0eb96b..86a5c4f7775e 100644 --- a/drivers/isdn/gigaset/ser-gigaset.c +++ b/drivers/isdn/gigaset/ser-gigaset.c @@ -440,7 +440,7 @@ static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, if (!set && !clear) return 0; gig_dbg(DEBUG_IF, "tiocmset set %x clear %x", set, clear); - return tty->ops->tiocmset(tty, NULL, set, clear); + return tty->ops->tiocmset(tty, set, clear); } static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag) diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index ba6c2f124b58..0341c69eb152 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -1372,7 +1372,7 @@ isdn_tty_tiocmget(struct tty_struct *tty) } static int -isdn_tty_tiocmset(struct tty_struct *tty, struct file *file, +isdn_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { modem_info *info = (modem_info *) tty->driver_data; diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index 86bb04d821b1..c8c9edb3d7cb 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c @@ -970,7 +970,7 @@ static int sdio_uart_tiocmget(struct tty_struct *tty) return result; } -static int sdio_uart_tiocmset(struct tty_struct *tty, struct file *file, +static int sdio_uart_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct sdio_uart_port *port = tty->driver_data; diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index ee1dde52e8fc..3352b2443e58 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c @@ -167,7 +167,7 @@ static int irtty_set_dtr_rts(struct sir_dev *dev, int dtr, int rts) * let's be careful... Jean II */ IRDA_ASSERT(priv->tty->ops->tiocmset != NULL, return -1;); - priv->tty->ops->tiocmset(priv->tty, NULL, set, clear); + priv->tty->ops->tiocmset(priv->tty, set, clear); return 0; } diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 7c68c456c035..956e1d6e72a5 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -324,7 +324,7 @@ struct hso_device { /* Prototypes */ /*****************************************************************************/ /* Serial driver functions */ -static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file, +static int hso_serial_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); static void ctrl_callback(struct urb *urb); static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial); @@ -1335,7 +1335,7 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp) /* done */ if (result) - hso_serial_tiocmset(tty, NULL, TIOCM_RTS | TIOCM_DTR, 0); + hso_serial_tiocmset(tty, TIOCM_RTS | TIOCM_DTR, 0); err_out: mutex_unlock(&serial->parent->mutex); return result; @@ -1687,7 +1687,7 @@ static int hso_serial_tiocmget(struct tty_struct *tty) return retval; } -static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file, +static int hso_serial_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { int val = 0; diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c index d999e54a7730..1c65d1c33873 100644 --- a/drivers/net/wan/pc300_tty.c +++ b/drivers/net/wan/pc300_tty.c @@ -131,8 +131,7 @@ static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx); static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char); static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char); -static int pc300_tiocmset(struct tty_struct *, struct file *, - unsigned int, unsigned int); +static int pc300_tiocmset(struct tty_struct *, unsigned int, unsigned int); static int pc300_tiocmget(struct tty_struct *); /* functions called by PC300 driver */ @@ -543,7 +542,7 @@ static int cpc_tty_chars_in_buffer(struct tty_struct *tty) return 0; } -static int pc300_tiocmset(struct tty_struct *tty, struct file *file, +static int pc300_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { st_cpc_tty_area *cpc_tty; diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c index 1e50292aef74..3734448d1b82 100644 --- a/drivers/staging/quatech_usb2/quatech_usb2.c +++ b/drivers/staging/quatech_usb2/quatech_usb2.c @@ -1121,7 +1121,7 @@ static int qt2_tiocmget(struct tty_struct *tty) } } -static int qt2_tiocmset(struct tty_struct *tty, struct file *file, +static int qt2_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 56ded56db7b4..39776c1cf10f 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -1425,7 +1425,6 @@ static inline int qt_real_tiocmget(struct tty_struct *tty, static inline int qt_real_tiocmset(struct tty_struct *tty, struct usb_serial_port *port, - struct file *file, struct usb_serial *serial, unsigned int value) { @@ -1486,7 +1485,7 @@ static int qt_tiocmget(struct tty_struct *tty) return retval; } -static int qt_tiocmset(struct tty_struct *tty, struct file *file, +static int qt_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { @@ -1506,7 +1505,7 @@ static int qt_tiocmset(struct tty_struct *tty, struct file *file, dbg("%s - port %d\n", __func__, port->number); dbg("%s - qt_port->RxHolding = %d\n", __func__, qt_port->RxHolding); - retval = qt_real_tiocmset(tty, port, file, serial, set); + retval = qt_real_tiocmset(tty, port, serial, set); spin_unlock_irqrestore(&qt_port->lock, flags); return retval; diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index 55293105a56c..8a8d6373f164 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c @@ -1103,8 +1103,8 @@ static int hvsi_tiocmget(struct tty_struct *tty) return hp->mctrl; } -static int hvsi_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) +static int hvsi_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) { struct hvsi_struct *hp = tty->driver_data; unsigned long flags; diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 97e3d509ff82..88477d16b8b7 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2654,7 +2654,7 @@ static int gsmtty_tiocmget(struct tty_struct *tty) return dlci->modem_rx; } -static int gsmtty_tiocmset(struct tty_struct *tty, struct file *filp, +static int gsmtty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct gsm_dlci *dlci = tty->driver_data; diff --git a/drivers/tty/serial/68360serial.c b/drivers/tty/serial/68360serial.c index 2a52cf14ce50..217fe1c299e0 100644 --- a/drivers/tty/serial/68360serial.c +++ b/drivers/tty/serial/68360serial.c @@ -1271,7 +1271,7 @@ static int rs_360_tiocmget(struct tty_struct *tty) return result; } -static int rs_360_tiocmset(struct tty_struct *tty, struct file *file, +static int rs_360_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { #ifdef modem_control diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index 8cc5c0224b25..b9fcd0bda60c 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c @@ -3581,8 +3581,7 @@ rs_break(struct tty_struct *tty, int break_state) } static int -rs_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) +rs_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct e100_serial *info = (struct e100_serial *)tty->driver_data; unsigned long flags; diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 4d26d39ec344..8ee5a41d340d 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -263,7 +263,6 @@ static int ifx_spi_tiocmget(struct tty_struct *tty) /** * ifx_spi_tiocmset - set modem bits * @tty: the tty structure - * @filp: file handle issuing the request * @set: bits to set * @clear: bits to clear * @@ -272,7 +271,7 @@ static int ifx_spi_tiocmget(struct tty_struct *tty) * * FIXME: do we need to kick the tranfers when we do this ? */ -static int ifx_spi_tiocmset(struct tty_struct *tty, struct file *filp, +static int ifx_spi_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct ifx_spi_device *ifx_dev = tty->driver_data; diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 53e490e47560..623d6bd911d7 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -925,8 +925,7 @@ static int uart_tiocmget(struct tty_struct *tty) } static int -uart_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) +uart_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct uart_state *state = tty->driver_data; struct uart_port *uport = state->uart_port; @@ -934,8 +933,7 @@ uart_tiocmset(struct tty_struct *tty, struct file *file, int ret = -EIO; mutex_lock(&port->mutex); - if ((!file || !tty_hung_up_p(file)) && - !(tty->flags & (1 << TTY_IO_ERROR))) { + if (!(tty->flags & (1 << TTY_IO_ERROR))) { uart_update_mctrl(uport, set, clear); ret = 0; } diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index fde5a4dae3dd..83af24ca1e5e 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2481,7 +2481,6 @@ static int tty_tiocmget(struct tty_struct *tty, int __user *p) /** * tty_tiocmset - set modem status * @tty: tty device - * @file: user file pointer * @cmd: command - clear bits, set bits or set all * @p: pointer to desired bits * @@ -2491,7 +2490,7 @@ static int tty_tiocmget(struct tty_struct *tty, int __user *p) * Locking: none (up to the driver) */ -static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int cmd, +static int tty_tiocmset(struct tty_struct *tty, unsigned int cmd, unsigned __user *p) { int retval; @@ -2518,7 +2517,7 @@ static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int } set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; - return tty->ops->tiocmset(tty, file, set, clear); + return tty->ops->tiocmset(tty, set, clear); } static int tty_tiocgicount(struct tty_struct *tty, void __user *arg) @@ -2659,7 +2658,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case TIOCMSET: case TIOCMBIC: case TIOCMBIS: - return tty_tiocmset(tty, file, cmd, p); + return tty_tiocmset(tty, cmd, p); case TIOCGICOUNT: retval = tty_tiocgicount(tty, p); /* For the moment allow fall through to the old method */ diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 2ae996b7ce7b..e9a26fbd079c 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -791,7 +791,7 @@ static int acm_tty_tiocmget(struct tty_struct *tty) TIOCM_CTS; } -static int acm_tty_tiocmset(struct tty_struct *tty, struct file *file, +static int acm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct acm *acm = tty->driver_data; diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 35b610aa3f92..2f837e983339 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -511,7 +511,7 @@ static int ark3116_tiocmget(struct tty_struct *tty) (ctrl & UART_MCR_OUT2 ? TIOCM_OUT2 : 0); } -static int ark3116_tiocmset(struct tty_struct *tty, struct file *file, +static int ark3116_tiocmset(struct tty_struct *tty, unsigned set, unsigned clr) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 48fb3bad3cd6..d6921fa1403c 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -101,7 +101,7 @@ static void belkin_sa_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios * old); static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state); static int belkin_sa_tiocmget(struct tty_struct *tty); -static int belkin_sa_tiocmset(struct tty_struct *tty, struct file *file, +static int belkin_sa_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); @@ -513,7 +513,7 @@ static int belkin_sa_tiocmget(struct tty_struct *tty) return control_state; } -static int belkin_sa_tiocmset(struct tty_struct *tty, struct file *file, +static int belkin_sa_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index aa0962b72f4c..5cbef313281e 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -431,7 +431,7 @@ out: kfree(break_reg); } -static int ch341_tiocmset(struct tty_struct *tty, struct file *file, +static int ch341_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index b3873815035c..4df3e0cecbae 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -42,9 +42,8 @@ static void cp210x_get_termios_port(struct usb_serial_port *port, static void cp210x_set_termios(struct tty_struct *, struct usb_serial_port *, struct ktermios*); static int cp210x_tiocmget(struct tty_struct *); -static int cp210x_tiocmset(struct tty_struct *, struct file *, - unsigned int, unsigned int); -static int cp210x_tiocmset_port(struct usb_serial_port *port, struct file *, +static int cp210x_tiocmset(struct tty_struct *, unsigned int, unsigned int); +static int cp210x_tiocmset_port(struct usb_serial_port *port, unsigned int, unsigned int); static void cp210x_break_ctl(struct tty_struct *, int); static int cp210x_startup(struct usb_serial *); @@ -698,14 +697,14 @@ static void cp210x_set_termios(struct tty_struct *tty, } -static int cp210x_tiocmset (struct tty_struct *tty, struct file *file, +static int cp210x_tiocmset (struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; - return cp210x_tiocmset_port(port, file, set, clear); + return cp210x_tiocmset_port(port, set, clear); } -static int cp210x_tiocmset_port(struct usb_serial_port *port, struct file *file, +static int cp210x_tiocmset_port(struct usb_serial_port *port, unsigned int set, unsigned int clear) { unsigned int control = 0; @@ -737,9 +736,9 @@ static int cp210x_tiocmset_port(struct usb_serial_port *port, struct file *file, static void cp210x_dtr_rts(struct usb_serial_port *p, int on) { if (on) - cp210x_tiocmset_port(p, NULL, TIOCM_DTR|TIOCM_RTS, 0); + cp210x_tiocmset_port(p, TIOCM_DTR|TIOCM_RTS, 0); else - cp210x_tiocmset_port(p, NULL, 0, TIOCM_DTR|TIOCM_RTS); + cp210x_tiocmset_port(p, 0, TIOCM_DTR|TIOCM_RTS); } static int cp210x_tiocmget (struct tty_struct *tty) diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 9c96cff691fd..2beb5a66180d 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -174,7 +174,7 @@ static int cypress_ioctl(struct tty_struct *tty, struct file *file, static void cypress_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); static int cypress_tiocmget(struct tty_struct *tty); -static int cypress_tiocmset(struct tty_struct *tty, struct file *file, +static int cypress_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); static int cypress_chars_in_buffer(struct tty_struct *tty); static void cypress_throttle(struct tty_struct *tty); @@ -892,7 +892,7 @@ static int cypress_tiocmget(struct tty_struct *tty) } -static int cypress_tiocmset(struct tty_struct *tty, struct file *file, +static int cypress_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 08da46cb5825..86fbba6336c9 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -446,10 +446,10 @@ static void digi_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios); static void digi_break_ctl(struct tty_struct *tty, int break_state); static int digi_tiocmget(struct tty_struct *tty); -static int digi_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear); +static int digi_tiocmset(struct tty_struct *tty, unsigned int set, + unsigned int clear); static int digi_write(struct tty_struct *tty, struct usb_serial_port *port, - const unsigned char *buf, int count); + const unsigned char *buf, int count); static void digi_write_bulk_callback(struct urb *urb); static int digi_write_room(struct tty_struct *tty); static int digi_chars_in_buffer(struct tty_struct *tty); @@ -1134,8 +1134,8 @@ static int digi_tiocmget(struct tty_struct *tty) } -static int digi_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) +static int digi_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; struct digi_port *priv = usb_get_serial_port_data(port); diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 281d18141051..f521ab1eb60f 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -857,7 +857,7 @@ static int ftdi_prepare_write_buffer(struct usb_serial_port *port, static void ftdi_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); static int ftdi_tiocmget(struct tty_struct *tty); -static int ftdi_tiocmset(struct tty_struct *tty, struct file *file, +static int ftdi_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); static int ftdi_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); @@ -2202,7 +2202,7 @@ out: return ret; } -static int ftdi_tiocmset(struct tty_struct *tty, struct file *file, +static int ftdi_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index e8fe4dcf72f0..0b8846e27a79 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -220,7 +220,7 @@ static int edge_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); static void edge_break(struct tty_struct *tty, int break_state); static int edge_tiocmget(struct tty_struct *tty); -static int edge_tiocmset(struct tty_struct *tty, struct file *file, +static int edge_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); static int edge_get_icount(struct tty_struct *tty, struct serial_icounter_struct *icount); @@ -1568,7 +1568,7 @@ static int get_lsr_info(struct edgeport_port *edge_port, return 0; } -static int edge_tiocmset(struct tty_struct *tty, struct file *file, +static int edge_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 7cb9f5cb91f3..88120523710b 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -2444,7 +2444,7 @@ static void edge_set_termios(struct tty_struct *tty, change_port_settings(tty, edge_port, old_termios); } -static int edge_tiocmset(struct tty_struct *tty, struct file *file, +static int edge_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 1d96142f135a..6aca631a407a 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -150,7 +150,7 @@ static void iuu_release(struct usb_serial *serial) } } -static int iuu_tiocmset(struct tty_struct *tty, struct file *file, +static int iuu_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 1beebbb7a20a..c6e968f24e04 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -317,7 +317,7 @@ static int keyspan_tiocmget(struct tty_struct *tty) return value; } -static int keyspan_tiocmset(struct tty_struct *tty, struct file *file, +static int keyspan_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index 5e5fc71e68df..13fa1d1cc900 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h @@ -60,7 +60,7 @@ static void keyspan_break_ctl (struct tty_struct *tty, int break_state); static int keyspan_tiocmget (struct tty_struct *tty); static int keyspan_tiocmset (struct tty_struct *tty, - struct file *file, unsigned int set, + unsigned int set, unsigned int clear); static int keyspan_fake_startup (struct usb_serial *serial); diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 49ad2baf77cd..207caabdc4ff 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -478,7 +478,7 @@ static int keyspan_pda_tiocmget(struct tty_struct *tty) return value; } -static int keyspan_pda_tiocmset(struct tty_struct *tty, struct file *file, +static int keyspan_pda_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index a570f5201c73..19373cb7c5bf 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -69,7 +69,7 @@ static void klsi_105_close(struct usb_serial_port *port); static void klsi_105_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); static int klsi_105_tiocmget(struct tty_struct *tty); -static int klsi_105_tiocmset(struct tty_struct *tty, struct file *file, +static int klsi_105_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); static void klsi_105_process_read_urb(struct urb *urb); static int klsi_105_prepare_write_buffer(struct usb_serial_port *port, @@ -661,7 +661,7 @@ static int klsi_105_tiocmget(struct tty_struct *tty) return (int)line_state; } -static int klsi_105_tiocmset(struct tty_struct *tty, struct file *file, +static int klsi_105_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { int retval = -EINVAL; diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 81d07fb299b8..22cd0c08f46f 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -78,7 +78,7 @@ static int kobil_write_room(struct tty_struct *tty); static int kobil_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); static int kobil_tiocmget(struct tty_struct *tty); -static int kobil_tiocmset(struct tty_struct *tty, struct file *file, +static int kobil_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); static void kobil_read_int_callback(struct urb *urb); static void kobil_write_callback(struct urb *purb); @@ -544,7 +544,7 @@ static int kobil_tiocmget(struct tty_struct *tty) return result; } -static int kobil_tiocmset(struct tty_struct *tty, struct file *file, +static int kobil_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 27447095feae..ef49902c5a51 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -102,7 +102,7 @@ static void mct_u232_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); static void mct_u232_break_ctl(struct tty_struct *tty, int break_state); static int mct_u232_tiocmget(struct tty_struct *tty); -static int mct_u232_tiocmset(struct tty_struct *tty, struct file *file, +static int mct_u232_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); static void mct_u232_throttle(struct tty_struct *tty); static void mct_u232_unthrottle(struct tty_struct *tty); @@ -778,7 +778,7 @@ static int mct_u232_tiocmget(struct tty_struct *tty) return control_state; } -static int mct_u232_tiocmset(struct tty_struct *tty, struct file *file, +static int mct_u232_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 5d40d4151b5a..95b1c64cac03 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -1858,7 +1858,7 @@ static int mos7720_tiocmget(struct tty_struct *tty) return result; } -static int mos7720_tiocmset(struct tty_struct *tty, struct file *file, +static int mos7720_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index ee0dc9a0890c..9424178c6689 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -1674,7 +1674,7 @@ static int mos7840_tiocmget(struct tty_struct *tty) return result; } -static int mos7840_tiocmset(struct tty_struct *tty, struct file *file, +static int mos7840_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index 4cd3b0ef4e61..63734cb0fb0f 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -145,7 +145,7 @@ static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port, static int oti6858_write_room(struct tty_struct *tty); static int oti6858_chars_in_buffer(struct tty_struct *tty); static int oti6858_tiocmget(struct tty_struct *tty); -static int oti6858_tiocmset(struct tty_struct *tty, struct file *file, +static int oti6858_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); static int oti6858_startup(struct usb_serial *serial); static void oti6858_release(struct usb_serial *serial); @@ -624,7 +624,7 @@ static void oti6858_close(struct usb_serial_port *port) usb_kill_urb(port->interrupt_in_urb); } -static int oti6858_tiocmset(struct tty_struct *tty, struct file *file, +static int oti6858_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 6cb4f503a3f1..b797992fa54b 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -505,7 +505,7 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) return 0; } -static int pl2303_tiocmset(struct tty_struct *tty, struct file *file, +static int pl2303_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 66437f1e9e5b..79ee6c79ad54 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -408,7 +408,7 @@ static int sierra_tiocmget(struct tty_struct *tty) return value; } -static int sierra_tiocmset(struct tty_struct *tty, struct file *file, +static int sierra_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index cac13009fc5c..dfbc543e0db8 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -595,7 +595,7 @@ static int spcp8x5_ioctl(struct tty_struct *tty, struct file *file, return -ENOIOCTLCMD; } -static int spcp8x5_tiocmset(struct tty_struct *tty, struct file *file, +static int spcp8x5_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index b21583fa825c..abceee9d3af9 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c @@ -517,7 +517,7 @@ mget_out: return r; } -static int ssu100_tiocmset(struct tty_struct *tty, struct file *file, +static int ssu100_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 223e60e31735..c7fea4a2a1be 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -113,7 +113,7 @@ static int ti_get_icount(struct tty_struct *tty, static void ti_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios); static int ti_tiocmget(struct tty_struct *tty); -static int ti_tiocmset(struct tty_struct *tty, struct file *file, +static int ti_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); static void ti_break(struct tty_struct *tty, int break_state); static void ti_interrupt_callback(struct urb *urb); @@ -1033,8 +1033,8 @@ static int ti_tiocmget(struct tty_struct *tty) } -static int ti_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) +static int ti_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; struct ti_port *tport = usb_get_serial_port_data(port); diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index df105c6531a1..dab679e5b7ea 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -507,7 +507,7 @@ static int serial_tiocmget(struct tty_struct *tty) return -EINVAL; } -static int serial_tiocmset(struct tty_struct *tty, struct file *file, +static int serial_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; @@ -515,7 +515,7 @@ static int serial_tiocmset(struct tty_struct *tty, struct file *file, dbg("%s - port %d", __func__, port->number); if (port->serial->type->tiocmset) - return port->serial->type->tiocmset(tty, file, set, clear); + return port->serial->type->tiocmset(tty, set, clear); return -EINVAL; } diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h index 8b68fc783d5f..4d65f1c8dd93 100644 --- a/drivers/usb/serial/usb-wwan.h +++ b/drivers/usb/serial/usb-wwan.h @@ -16,7 +16,7 @@ extern void usb_wwan_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); extern int usb_wwan_tiocmget(struct tty_struct *tty); -extern int usb_wwan_tiocmset(struct tty_struct *tty, struct file *file, +extern int usb_wwan_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); extern int usb_wwan_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 60f942632cb4..b72912027ae8 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -98,7 +98,7 @@ int usb_wwan_tiocmget(struct tty_struct *tty) } EXPORT_SYMBOL(usb_wwan_tiocmget); -int usb_wwan_tiocmset(struct tty_struct *tty, struct file *file, +int usb_wwan_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index bf850139e0b8..6e0c397e869f 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -157,7 +157,7 @@ static int whiteheat_ioctl(struct tty_struct *tty, struct file *file, static void whiteheat_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); static int whiteheat_tiocmget(struct tty_struct *tty); -static int whiteheat_tiocmset(struct tty_struct *tty, struct file *file, +static int whiteheat_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); static void whiteheat_break_ctl(struct tty_struct *tty, int break_state); static int whiteheat_chars_in_buffer(struct tty_struct *tty); @@ -850,7 +850,7 @@ static int whiteheat_tiocmget(struct tty_struct *tty) return modem_signals; } -static int whiteheat_tiocmset(struct tty_struct *tty, struct file *file, +static int whiteheat_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 9539d74171db..5dabaa2e6da3 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -272,7 +272,7 @@ struct tty_operations { void (*wait_until_sent)(struct tty_struct *tty, int timeout); void (*send_xchar)(struct tty_struct *tty, char ch); int (*tiocmget)(struct tty_struct *tty); - int (*tiocmset)(struct tty_struct *tty, struct file *file, + int (*tiocmset)(struct tty_struct *tty, unsigned int set, unsigned int clear); int (*resize)(struct tty_struct *tty, struct winsize *ws); int (*set_termiox)(struct tty_struct *tty, struct termiox *tnew); diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 30b945397d19..c1aa1b243ba3 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -269,7 +269,7 @@ struct usb_serial_driver { void (*throttle)(struct tty_struct *tty); void (*unthrottle)(struct tty_struct *tty); int (*tiocmget)(struct tty_struct *tty); - int (*tiocmset)(struct tty_struct *tty, struct file *file, + int (*tiocmset)(struct tty_struct *tty, unsigned int set, unsigned int clear); int (*get_icount)(struct tty_struct *tty, struct serial_icounter_struct *icount); diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h index fa3793b5392d..980ccb66e1b4 100644 --- a/include/net/irda/ircomm_tty.h +++ b/include/net/irda/ircomm_tty.h @@ -121,7 +121,7 @@ void ircomm_tty_start(struct tty_struct *tty); void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self); extern int ircomm_tty_tiocmget(struct tty_struct *tty); -extern int ircomm_tty_tiocmset(struct tty_struct *tty, struct file *file, +extern int ircomm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); extern int ircomm_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 7f67fa4f2f5e..8e78e7447726 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -1098,7 +1098,7 @@ static int rfcomm_tty_tiocmget(struct tty_struct *tty) return dev->modem_status; } -static int rfcomm_tty_tiocmset(struct tty_struct *tty, struct file *filp, unsigned int set, unsigned int clear) +static int rfcomm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; struct rfcomm_dlc *dlc = dev->dlc; diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c index bb47caeba7e6..5e0e718c930a 100644 --- a/net/irda/ircomm/ircomm_tty_ioctl.c +++ b/net/irda/ircomm/ircomm_tty_ioctl.c @@ -214,12 +214,12 @@ int ircomm_tty_tiocmget(struct tty_struct *tty) } /* - * Function ircomm_tty_tiocmset (tty, file, set, clear) + * Function ircomm_tty_tiocmset (tty, set, clear) * * * */ -int ircomm_tty_tiocmset(struct tty_struct *tty, struct file *file, +int ircomm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; -- cgit v1.2.3 From 00a0d0d65b61241a718d0aee96f46b9a2d93bf26 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 14 Feb 2011 16:27:06 +0000 Subject: tty: remove filp from the USB tty ioctls We don't use it so we can trim it from here as we try and stamp the file object dependencies out of the serial code. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quatech_usb2/quatech_usb2.c | 2 +- drivers/staging/serqt_usb2/serqt_usb2.c | 2 +- drivers/usb/serial/ark3116.c | 2 +- drivers/usb/serial/ch341.c | 3 +-- drivers/usb/serial/cypress_m8.c | 4 ++-- drivers/usb/serial/ftdi_sio.c | 4 ++-- drivers/usb/serial/io_edgeport.c | 4 ++-- drivers/usb/serial/io_ti.c | 2 +- drivers/usb/serial/kobil_sct.c | 4 ++-- drivers/usb/serial/mos7720.c | 2 +- drivers/usb/serial/mos7840.c | 2 +- drivers/usb/serial/opticon.c | 2 +- drivers/usb/serial/oti6858.c | 4 ++-- drivers/usb/serial/pl2303.c | 2 +- drivers/usb/serial/spcp8x5.c | 2 +- drivers/usb/serial/ssu100.c | 2 +- drivers/usb/serial/ti_usb_3410_5052.c | 4 ++-- drivers/usb/serial/usb-serial.c | 2 +- drivers/usb/serial/usb-wwan.h | 2 +- drivers/usb/serial/usb_wwan.c | 2 +- drivers/usb/serial/whiteheat.c | 4 ++-- include/linux/usb/serial.h | 2 +- 22 files changed, 29 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c index 3734448d1b82..36b18e302718 100644 --- a/drivers/staging/quatech_usb2/quatech_usb2.c +++ b/drivers/staging/quatech_usb2/quatech_usb2.c @@ -852,7 +852,7 @@ static int qt2_chars_in_buffer(struct tty_struct *tty) * TIOCMGET and TIOCMSET are filtered off to their own methods before they get * here, so we don't have to handle them. */ -static int qt2_ioctl(struct tty_struct *tty, struct file *file, +static int qt2_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 39776c1cf10f..e0aae86a8809 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -1191,7 +1191,7 @@ static int qt_write_room(struct tty_struct *tty) } -static int qt_ioctl(struct tty_struct *tty, struct file *file, +static int qt_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 2f837e983339..5cdb9d912275 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -431,7 +431,7 @@ static int ark3116_get_icount(struct tty_struct *tty, return 0; } -static int ark3116_ioctl(struct tty_struct *tty, struct file *file, +static int ark3116_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 5cbef313281e..d0b9feac5dc3 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -552,8 +552,7 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) return 0; } -/*static int ch341_ioctl(struct usb_serial_port *port, struct file *file,*/ -static int ch341_ioctl(struct tty_struct *tty, struct file *file, +static int ch341_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 2beb5a66180d..987e9bf7bd02 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -169,7 +169,7 @@ static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count); static void cypress_send(struct usb_serial_port *port); static int cypress_write_room(struct tty_struct *tty); -static int cypress_ioctl(struct tty_struct *tty, struct file *file, +static int cypress_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); static void cypress_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); @@ -917,7 +917,7 @@ static int cypress_tiocmset(struct tty_struct *tty, } -static int cypress_ioctl(struct tty_struct *tty, struct file *file, +static int cypress_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index f521ab1eb60f..e3e23a4e227d 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -859,7 +859,7 @@ static void ftdi_set_termios(struct tty_struct *tty, static int ftdi_tiocmget(struct tty_struct *tty); static int ftdi_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); -static int ftdi_ioctl(struct tty_struct *tty, struct file *file, +static int ftdi_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); static void ftdi_break_ctl(struct tty_struct *tty, int break_state); @@ -2210,7 +2210,7 @@ static int ftdi_tiocmset(struct tty_struct *tty, return update_mctrl(port, set, clear); } -static int ftdi_ioctl(struct tty_struct *tty, struct file *file, +static int ftdi_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 0b8846e27a79..ae91bcdcb2bc 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -216,7 +216,7 @@ static void edge_unthrottle(struct tty_struct *tty); static void edge_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios); -static int edge_ioctl(struct tty_struct *tty, struct file *file, +static int edge_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); static void edge_break(struct tty_struct *tty, int break_state); static int edge_tiocmget(struct tty_struct *tty); @@ -1679,7 +1679,7 @@ static int get_serial_info(struct edgeport_port *edge_port, * SerialIoctl * this function handles any ioctl calls to the driver *****************************************************************************/ -static int edge_ioctl(struct tty_struct *tty, struct file *file, +static int edge_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 88120523710b..d8434910fa7b 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -2552,7 +2552,7 @@ static int get_serial_info(struct edgeport_port *edge_port, return 0; } -static int edge_ioctl(struct tty_struct *tty, struct file *file, +static int edge_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 22cd0c08f46f..667863ef0625 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -75,7 +75,7 @@ static void kobil_close(struct usb_serial_port *port); static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count); static int kobil_write_room(struct tty_struct *tty); -static int kobil_ioctl(struct tty_struct *tty, struct file *file, +static int kobil_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); static int kobil_tiocmget(struct tty_struct *tty); static int kobil_tiocmset(struct tty_struct *tty, @@ -668,7 +668,7 @@ static void kobil_set_termios(struct tty_struct *tty, ); } -static int kobil_ioctl(struct tty_struct *tty, struct file *file, +static int kobil_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 95b1c64cac03..d8b3e8fa14e9 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -1987,7 +1987,7 @@ static int get_serial_info(struct moschip_port *mos7720_port, return 0; } -static int mos7720_ioctl(struct tty_struct *tty, struct file *file, +static int mos7720_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 9424178c6689..7b50aa122752 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -2235,7 +2235,7 @@ static int mos7840_get_icount(struct tty_struct *tty, * this function handles any ioctl calls to the driver *****************************************************************************/ -static int mos7840_ioctl(struct tty_struct *tty, struct file *file, +static int mos7840_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index e305df807396..8d603a1ca2eb 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -396,7 +396,7 @@ static int get_serial_info(struct opticon_private *priv, return 0; } -static int opticon_ioctl(struct tty_struct *tty, struct file *file, +static int opticon_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index 63734cb0fb0f..4c29e6c2bda7 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -135,7 +135,7 @@ static void oti6858_close(struct usb_serial_port *port); static void oti6858_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); static void oti6858_init_termios(struct tty_struct *tty); -static int oti6858_ioctl(struct tty_struct *tty, struct file *file, +static int oti6858_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); static void oti6858_read_int_callback(struct urb *urb); static void oti6858_read_bulk_callback(struct urb *urb); @@ -728,7 +728,7 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) return 0; } -static int oti6858_ioctl(struct tty_struct *tty, struct file *file, +static int oti6858_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index b797992fa54b..30461fcc2206 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -606,7 +606,7 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) return 0; } -static int pl2303_ioctl(struct tty_struct *tty, struct file *file, +static int pl2303_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct serial_struct ser; diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index dfbc543e0db8..180ea6c7911c 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -576,7 +576,7 @@ static int spcp8x5_wait_modem_info(struct usb_serial_port *port, return 0; } -static int spcp8x5_ioctl(struct tty_struct *tty, struct file *file, +static int spcp8x5_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index abceee9d3af9..87362e48796e 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c @@ -439,7 +439,7 @@ static int ssu100_get_icount(struct tty_struct *tty, -static int ssu100_ioctl(struct tty_struct *tty, struct file *file, +static int ssu100_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index c7fea4a2a1be..f4a57ad27db8 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -106,7 +106,7 @@ static int ti_write_room(struct tty_struct *tty); static int ti_chars_in_buffer(struct tty_struct *tty); static void ti_throttle(struct tty_struct *tty); static void ti_unthrottle(struct tty_struct *tty); -static int ti_ioctl(struct tty_struct *tty, struct file *file, +static int ti_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); static int ti_get_icount(struct tty_struct *tty, struct serial_icounter_struct *icount); @@ -818,7 +818,7 @@ static int ti_get_icount(struct tty_struct *tty, return 0; } -static int ti_ioctl(struct tty_struct *tty, struct file *file, +static int ti_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index dab679e5b7ea..b1110e136c33 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -417,7 +417,7 @@ static int serial_ioctl(struct tty_struct *tty, struct file *file, /* pass on to the driver specific version of this function if it is available */ if (port->serial->type->ioctl) { - retval = port->serial->type->ioctl(tty, file, cmd, arg); + retval = port->serial->type->ioctl(tty, cmd, arg); } else retval = -ENOIOCTLCMD; return retval; diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h index 4d65f1c8dd93..c47b6ec03063 100644 --- a/drivers/usb/serial/usb-wwan.h +++ b/drivers/usb/serial/usb-wwan.h @@ -18,7 +18,7 @@ extern void usb_wwan_set_termios(struct tty_struct *tty, extern int usb_wwan_tiocmget(struct tty_struct *tty); extern int usb_wwan_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); -extern int usb_wwan_ioctl(struct tty_struct *tty, struct file *file, +extern int usb_wwan_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); extern int usb_wwan_send_setup(struct usb_serial_port *port); extern int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index b72912027ae8..b38d77b389d4 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -178,7 +178,7 @@ static int set_serial_info(struct usb_serial_port *port, return retval; } -int usb_wwan_ioctl(struct tty_struct *tty, struct file *file, +int usb_wwan_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 6e0c397e869f..5b073bcc807b 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -152,7 +152,7 @@ static int whiteheat_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count); static int whiteheat_write_room(struct tty_struct *tty); -static int whiteheat_ioctl(struct tty_struct *tty, struct file *file, +static int whiteheat_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); static void whiteheat_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); @@ -874,7 +874,7 @@ static int whiteheat_tiocmset(struct tty_struct *tty, } -static int whiteheat_ioctl(struct tty_struct *tty, struct file *file, +static int whiteheat_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index c1aa1b243ba3..00e98ee5fba0 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -260,7 +260,7 @@ struct usb_serial_driver { const unsigned char *buf, int count); /* Called only by the tty layer */ int (*write_room)(struct tty_struct *tty); - int (*ioctl)(struct tty_struct *tty, struct file *file, + int (*ioctl)(struct tty_struct *tty, unsigned int cmd, unsigned long arg); void (*set_termios)(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old); -- cgit v1.2.3 From 6caa76b7786891b42b66a0e61e2c2fff2c884620 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 14 Feb 2011 16:27:22 +0000 Subject: tty: now phase out the ioctl file pointer for good Only oddities here are a couple of drivers that bogusly called the ldisc helpers instead of returning -ENOIOCTLCMD. Fix the bug and the rest goes away. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/char/amiserial.c | 2 +- drivers/char/cyclades.c | 2 +- drivers/char/epca.c | 8 ++++---- drivers/char/ip2/ip2main.c | 4 ++-- drivers/char/isicom.c | 2 +- drivers/char/istallion.c | 4 ++-- drivers/char/moxa.c | 2 +- drivers/char/mxser.c | 2 +- drivers/char/nozomi.c | 2 +- drivers/char/pcmcia/ipwireless/tty.c | 4 ++-- drivers/char/riscom8.c | 2 +- drivers/char/rocket.c | 2 +- drivers/char/ser_a2232.c | 6 +++--- drivers/char/serial167.c | 2 +- drivers/char/specialix.c | 2 +- drivers/char/stallion.c | 5 ++--- drivers/char/sx.c | 2 +- drivers/char/synclink.c | 3 +-- drivers/char/synclink_gt.c | 9 ++++----- drivers/char/synclinkmp.c | 5 ++--- drivers/char/ttyprintk.c | 2 +- drivers/char/vme_scc.c | 4 ++-- drivers/isdn/capi/capi.c | 10 ++-------- drivers/isdn/gigaset/interface.c | 4 ++-- drivers/isdn/i4l/isdn_tty.c | 3 +-- drivers/net/usb/hso.c | 2 +- drivers/tty/n_gsm.c | 2 +- drivers/tty/pty.c | 4 ++-- drivers/tty/serial/68328serial.c | 2 +- drivers/tty/serial/68360serial.c | 2 +- drivers/tty/serial/crisv10.c | 2 +- drivers/tty/serial/serial_core.c | 4 ++-- drivers/tty/tty_io.c | 4 ++-- drivers/tty/vt/vt_ioctl.c | 6 +++--- drivers/usb/class/cdc-acm.c | 2 +- drivers/usb/serial/usb-serial.c | 2 +- include/linux/tty.h | 2 +- include/linux/tty_driver.h | 9 ++++----- include/net/irda/ircomm_tty.h | 2 +- net/bluetooth/rfcomm/tty.c | 2 +- net/irda/ircomm/ircomm_tty_ioctl.c | 4 ++-- 41 files changed, 66 insertions(+), 78 deletions(-) (limited to 'drivers') diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 5c15fad71ad2..f214e5022472 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c @@ -1293,7 +1293,7 @@ static int rs_get_icount(struct tty_struct *tty, return 0; } -static int rs_ioctl(struct tty_struct *tty, struct file * file, +static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct async_struct * info = tty->driver_data; diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 942b6f2b70a4..c99728f0cd9f 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c @@ -2680,7 +2680,7 @@ static int cy_cflags_changed(struct cyclades_port *info, unsigned long arg, * not recognized by the driver, it should return ENOIOCTLCMD. */ static int -cy_ioctl(struct tty_struct *tty, struct file *file, +cy_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct cyclades_port *info = tty->driver_data; diff --git a/drivers/char/epca.c b/drivers/char/epca.c index e5872b59f9cd..7ad3638967ae 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c @@ -175,9 +175,9 @@ static unsigned termios2digi_i(struct channel *ch, unsigned); static unsigned termios2digi_c(struct channel *ch, unsigned); static void epcaparam(struct tty_struct *, struct channel *); static void receive_data(struct channel *, struct tty_struct *tty); -static int pc_ioctl(struct tty_struct *, struct file *, +static int pc_ioctl(struct tty_struct *, unsigned int, unsigned long); -static int info_ioctl(struct tty_struct *, struct file *, +static int info_ioctl(struct tty_struct *, unsigned int, unsigned long); static void pc_set_termios(struct tty_struct *, struct ktermios *); static void do_softint(struct work_struct *work); @@ -1919,7 +1919,7 @@ static void receive_data(struct channel *ch, struct tty_struct *tty) tty_schedule_flip(tty); } -static int info_ioctl(struct tty_struct *tty, struct file *file, +static int info_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { switch (cmd) { @@ -2057,7 +2057,7 @@ static int pc_tiocmset(struct tty_struct *tty, return 0; } -static int pc_ioctl(struct tty_struct *tty, struct file *file, +static int pc_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { digiflow_t dflow; diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index d5f866c7c672..ea7a8fb08283 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c @@ -173,7 +173,7 @@ static void ip2_flush_chars(PTTY); static int ip2_write_room(PTTY); static int ip2_chars_in_buf(PTTY); static void ip2_flush_buffer(PTTY); -static int ip2_ioctl(PTTY, struct file *, UINT, ULONG); +static int ip2_ioctl(PTTY, UINT, ULONG); static void ip2_set_termios(PTTY, struct ktermios *); static void ip2_set_line_discipline(PTTY); static void ip2_throttle(PTTY); @@ -2127,7 +2127,7 @@ static int ip2_tiocmset(struct tty_struct *tty, /* */ /******************************************************************************/ static int -ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) +ip2_ioctl ( PTTY tty, UINT cmd, ULONG arg ) { wait_queue_t wait; i2ChanStrPtr pCh = DevTable[tty->index]; diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 60f4d8ae7a49..db1cf9c328d8 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c @@ -1167,7 +1167,7 @@ static int isicom_get_serial_info(struct isi_port *port, return 0; } -static int isicom_ioctl(struct tty_struct *tty, struct file *filp, +static int isicom_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct isi_port *port = tty->driver_data; diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 763b58d58255..0b266272cccd 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c @@ -603,7 +603,7 @@ static int stli_putchar(struct tty_struct *tty, unsigned char ch); static void stli_flushchars(struct tty_struct *tty); static int stli_writeroom(struct tty_struct *tty); static int stli_charsinbuffer(struct tty_struct *tty); -static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); +static int stli_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); static void stli_settermios(struct tty_struct *tty, struct ktermios *old); static void stli_throttle(struct tty_struct *tty); static void stli_unthrottle(struct tty_struct *tty); @@ -1556,7 +1556,7 @@ static int stli_tiocmset(struct tty_struct *tty, sizeof(asysigs_t), 0); } -static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) +static int stli_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct stliport *portp; struct stlibrd *brdp; diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 9f4cd8968a5a..35b0c38590e6 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c @@ -287,7 +287,7 @@ static void moxa_low_water_check(void __iomem *ofsAddr) * TTY operations */ -static int moxa_ioctl(struct tty_struct *tty, struct file *file, +static int moxa_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct moxa_port *ch = tty->driver_data; diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 150a862c4989..d188f378684d 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c @@ -1655,7 +1655,7 @@ static int mxser_cflags_changed(struct mxser_port *info, unsigned long arg, return ret; } -static int mxser_ioctl(struct tty_struct *tty, struct file *file, +static int mxser_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct mxser_port *info = tty->driver_data; diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index 1b74c48c4016..513ba12064ea 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c @@ -1824,7 +1824,7 @@ static int ntty_tiocgicount(struct tty_struct *tty, return 0; } -static int ntty_ioctl(struct tty_struct *tty, struct file *file, +static int ntty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct port *port = tty->driver_data; diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c index 748190dfbab0..ef92869502a7 100644 --- a/drivers/char/pcmcia/ipwireless/tty.c +++ b/drivers/char/pcmcia/ipwireless/tty.c @@ -425,7 +425,7 @@ ipw_tiocmset(struct tty_struct *linux_tty, return set_control_lines(tty, set, clear); } -static int ipw_ioctl(struct tty_struct *linux_tty, struct file *file, +static int ipw_ioctl(struct tty_struct *linux_tty, unsigned int cmd, unsigned long arg) { struct ipw_tty *tty = linux_tty->driver_data; @@ -484,7 +484,7 @@ static int ipw_ioctl(struct tty_struct *linux_tty, struct file *file, return tty_perform_flush(linux_tty, arg); } } - return tty_mode_ioctl(linux_tty, file, cmd , arg); + return -ENOIOCTLCMD; } static int add_tty(int j, diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 3666decc6438..602643a40b4b 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c @@ -1236,7 +1236,7 @@ static int rc_get_serial_info(struct riscom_port *port, return copy_to_user(retinfo, &tmp, sizeof(tmp)) ? -EFAULT : 0; } -static int rc_ioctl(struct tty_struct *tty, struct file *filp, +static int rc_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct riscom_port *port = tty->driver_data; diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 36c108811a81..3780da8ad12d 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c @@ -1326,7 +1326,7 @@ static int get_version(struct r_port *info, struct rocket_version __user *retver } /* IOCTL call handler into the driver */ -static int rp_ioctl(struct tty_struct *tty, struct file *file, +static int rp_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct r_port *info = tty->driver_data; diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c index 9610861d1f5f..3f47c2ead8e5 100644 --- a/drivers/char/ser_a2232.c +++ b/drivers/char/ser_a2232.c @@ -133,8 +133,8 @@ static void a2232_hungup(void *ptr); /* END GENERIC_SERIAL PROTOTYPES */ /* Functions that the TTY driver struct expects */ -static int a2232_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg); +static int a2232_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg); static void a2232_throttle(struct tty_struct *tty); static void a2232_unthrottle(struct tty_struct *tty); static int a2232_open(struct tty_struct * tty, struct file * filp); @@ -447,7 +447,7 @@ static void a2232_hungup(void *ptr) /*** END OF REAL_DRIVER FUNCTIONS ***/ /*** BEGIN FUNCTIONS EXPECTED BY TTY DRIVER STRUCTS ***/ -static int a2232_ioctl( struct tty_struct *tty, struct file *file, +static int a2232_ioctl( struct tty_struct *tty, unsigned int cmd, unsigned long arg) { return -ENOIOCTLCMD; diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index 89ac542ffff2..674af6933978 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c @@ -1492,7 +1492,7 @@ get_default_timeout(struct cyclades_port *info, unsigned long __user * value) } static int -cy_ioctl(struct tty_struct *tty, struct file *file, +cy_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct cyclades_port *info = tty->driver_data; diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index a6b23847e4a7..47e5753f732a 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c @@ -1928,7 +1928,7 @@ static int sx_get_serial_info(struct specialix_port *port, } -static int sx_ioctl(struct tty_struct *tty, struct file *filp, +static int sx_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct specialix_port *port = tty->driver_data; diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index c42dbffbed16..4fff5cd3b163 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c @@ -1132,14 +1132,13 @@ static int stl_tiocmset(struct tty_struct *tty, return 0; } -static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) +static int stl_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct stlport *portp; int rc; void __user *argp = (void __user *)arg; - pr_debug("stl_ioctl(tty=%p,file=%p,cmd=%x,arg=%lx)\n", tty, file, cmd, - arg); + pr_debug("stl_ioctl(tty=%p,cmd=%x,arg=%lx)\n", tty, cmd, arg); portp = tty->driver_data; if (portp == NULL) diff --git a/drivers/char/sx.c b/drivers/char/sx.c index 342c6ae67da5..1291462bcddb 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c @@ -1899,7 +1899,7 @@ static int sx_tiocmset(struct tty_struct *tty, return 0; } -static int sx_ioctl(struct tty_struct *tty, struct file *filp, +static int sx_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { int rc; diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index 691e1094c20b..18888d005a0a 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c @@ -2962,13 +2962,12 @@ static int msgl_get_icount(struct tty_struct *tty, * Arguments: * * tty pointer to tty instance data - * file pointer to associated file object for device * cmd IOCTL command code * arg command argument/context * * Return Value: 0 if success, otherwise error code */ -static int mgsl_ioctl(struct tty_struct *tty, struct file * file, +static int mgsl_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct mgsl_struct * info = tty->driver_data; diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 04da6d61dc4f..a35dd549a008 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c @@ -154,7 +154,7 @@ static void flush_buffer(struct tty_struct *tty); static void tx_hold(struct tty_struct *tty); static void tx_release(struct tty_struct *tty); -static int ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); +static int ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); static int chars_in_buffer(struct tty_struct *tty); static void throttle(struct tty_struct * tty); static void unthrottle(struct tty_struct * tty); @@ -1030,13 +1030,12 @@ static void tx_release(struct tty_struct *tty) * Arguments * * tty pointer to tty instance data - * file pointer to associated file object for device * cmd IOCTL command code * arg command argument/context * * Return 0 if success, otherwise error code */ -static int ioctl(struct tty_struct *tty, struct file *file, +static int ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct slgt_info *info = tty->driver_data; @@ -1200,7 +1199,7 @@ static long set_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *ne return 0; } -static long slgt_compat_ioctl(struct tty_struct *tty, struct file *file, +static long slgt_compat_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct slgt_info *info = tty->driver_data; @@ -1239,7 +1238,7 @@ static long slgt_compat_ioctl(struct tty_struct *tty, struct file *file, case MGSL_IOCSIF: case MGSL_IOCSXSYNC: case MGSL_IOCSXCTRL: - rc = ioctl(tty, file, cmd, arg); + rc = ioctl(tty, cmd, arg); break; } diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index 1f9de97e8cfc..327343694473 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c @@ -520,7 +520,7 @@ static void flush_buffer(struct tty_struct *tty); static void tx_hold(struct tty_struct *tty); static void tx_release(struct tty_struct *tty); -static int ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); +static int ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); static int chars_in_buffer(struct tty_struct *tty); static void throttle(struct tty_struct * tty); static void unthrottle(struct tty_struct * tty); @@ -1248,13 +1248,12 @@ static void tx_release(struct tty_struct *tty) * Arguments: * * tty pointer to tty instance data - * file pointer to associated file object for device * cmd IOCTL command code * arg command argument/context * * Return Value: 0 if success, otherwise error code */ -static int ioctl(struct tty_struct *tty, struct file *file, +static int ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { SLMP_INFO *info = tty->driver_data; diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index c40c1612c8a7..a1f68af4ccf4 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c @@ -144,7 +144,7 @@ static int tpk_write_room(struct tty_struct *tty) /* * TTY operations ioctl function. */ -static int tpk_ioctl(struct tty_struct *tty, struct file *file, +static int tpk_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct ttyprintk_port *tpkp = tty->driver_data; diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c index 12de1202d22c..96838640f575 100644 --- a/drivers/char/vme_scc.c +++ b/drivers/char/vme_scc.c @@ -75,7 +75,7 @@ static void scc_hungup(void *ptr); static void scc_close(void *ptr); static int scc_chars_in_buffer(void * ptr); static int scc_open(struct tty_struct * tty, struct file * filp); -static int scc_ioctl(struct tty_struct * tty, struct file * filp, +static int scc_ioctl(struct tty_struct * tty, unsigned int cmd, unsigned long arg); static void scc_throttle(struct tty_struct *tty); static void scc_unthrottle(struct tty_struct *tty); @@ -1046,7 +1046,7 @@ static void scc_unthrottle (struct tty_struct * tty) } -static int scc_ioctl(struct tty_struct *tty, struct file *file, +static int scc_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { return -ENOIOCTLCMD; diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index f80a7c48a35f..0d7088367038 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1219,16 +1219,10 @@ static int capinc_tty_chars_in_buffer(struct tty_struct *tty) return mp->outbytes; } -static int capinc_tty_ioctl(struct tty_struct *tty, struct file * file, +static int capinc_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { - int error = 0; - switch (cmd) { - default: - error = n_tty_ioctl_helper(tty, file, cmd, arg); - break; - } - return error; + return -ENOIOCTLCMD; } static void capinc_tty_set_termios(struct tty_struct *tty, struct ktermios * old) diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 9b2bb491c614..59de638225fe 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c @@ -115,7 +115,7 @@ static int if_config(struct cardstate *cs, int *arg) static int if_open(struct tty_struct *tty, struct file *filp); static void if_close(struct tty_struct *tty, struct file *filp); -static int if_ioctl(struct tty_struct *tty, struct file *file, +static int if_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); static int if_write_room(struct tty_struct *tty); static int if_chars_in_buffer(struct tty_struct *tty); @@ -205,7 +205,7 @@ static void if_close(struct tty_struct *tty, struct file *filp) module_put(cs->driver->owner); } -static int if_ioctl(struct tty_struct *tty, struct file *file, +static int if_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct cardstate *cs; diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 0341c69eb152..3d88f15aa218 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -1413,8 +1413,7 @@ isdn_tty_tiocmset(struct tty_struct *tty, } static int -isdn_tty_ioctl(struct tty_struct *tty, struct file *file, - uint cmd, ulong arg) +isdn_tty_ioctl(struct tty_struct *tty, uint cmd, ulong arg) { modem_info *info = (modem_info *) tty->driver_data; int retval; diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 956e1d6e72a5..2ad58a0377b7 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1730,7 +1730,7 @@ static int hso_serial_tiocmset(struct tty_struct *tty, USB_CTRL_SET_TIMEOUT); } -static int hso_serial_ioctl(struct tty_struct *tty, struct file *file, +static int hso_serial_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct hso_serial *serial = get_serial_by_tty(tty); diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 88477d16b8b7..50f3ffd610b7 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2671,7 +2671,7 @@ static int gsmtty_tiocmset(struct tty_struct *tty, } -static int gsmtty_ioctl(struct tty_struct *tty, struct file *filp, +static int gsmtty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { return -ENOIOCTLCMD; diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 923a48585501..c88029af84dd 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -334,7 +334,7 @@ free_mem_out: return -ENOMEM; } -static int pty_bsd_ioctl(struct tty_struct *tty, struct file *file, +static int pty_bsd_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { switch (cmd) { @@ -489,7 +489,7 @@ static struct ctl_table pty_root_table[] = { }; -static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file, +static int pty_unix98_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { switch (cmd) { diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index a9d99856c892..1de0e8d4bde1 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c @@ -945,7 +945,7 @@ static void send_break(struct m68k_serial * info, unsigned int duration) local_irq_restore(flags); } -static int rs_ioctl(struct tty_struct *tty, struct file * file, +static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { int error; diff --git a/drivers/tty/serial/68360serial.c b/drivers/tty/serial/68360serial.c index 217fe1c299e0..514a356d8d64 100644 --- a/drivers/tty/serial/68360serial.c +++ b/drivers/tty/serial/68360serial.c @@ -1405,7 +1405,7 @@ static int rs_360_get_icount(struct tty_struct *tty, return 0; } -static int rs_360_ioctl(struct tty_struct *tty, struct file * file, +static int rs_360_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { int error; diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index b9fcd0bda60c..225123b37f19 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c @@ -3647,7 +3647,7 @@ rs_tiocmget(struct tty_struct *tty) static int -rs_ioctl(struct tty_struct *tty, struct file * file, +rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct e100_serial * info = (struct e100_serial *)tty->driver_data; diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 623d6bd911d7..733fe8e73f0f 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1099,7 +1099,7 @@ static int uart_get_icount(struct tty_struct *tty, * Called via sys_ioctl. We can use spin_lock_irq() here. */ static int -uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, +uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct uart_state *state = tty->driver_data; @@ -1152,7 +1152,7 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, mutex_lock(&port->mutex); - if (tty_hung_up_p(filp)) { + if (tty->flags & (1 << TTY_IO_ERROR)) { ret = -EIO; goto out_up; } diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 83af24ca1e5e..20a862a2a0c2 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2676,7 +2676,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } if (tty->ops->ioctl) { - retval = (tty->ops->ioctl)(tty, file, cmd, arg); + retval = (tty->ops->ioctl)(tty, cmd, arg); if (retval != -ENOIOCTLCMD) return retval; } @@ -2704,7 +2704,7 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd, return -EINVAL; if (tty->ops->compat_ioctl) { - retval = (tty->ops->compat_ioctl)(tty, file, cmd, arg); + retval = (tty->ops->compat_ioctl)(tty, cmd, arg); if (retval != -ENOIOCTLCMD) return retval; } diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 9e9a901442a3..b64804965316 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -495,7 +495,7 @@ do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_ * We handle the console-specific ioctl's here. We allow the * capability to modify any console, not just the fg_console. */ -int vt_ioctl(struct tty_struct *tty, struct file * file, +int vt_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct vc_data *vc = tty->driver_data; @@ -1495,7 +1495,7 @@ compat_unimap_ioctl(unsigned int cmd, struct compat_unimapdesc __user *user_ud, return 0; } -long vt_compat_ioctl(struct tty_struct *tty, struct file * file, +long vt_compat_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct vc_data *vc = tty->driver_data; @@ -1581,7 +1581,7 @@ out: fallback: tty_unlock(); - return vt_ioctl(tty, file, cmd, arg); + return vt_ioctl(tty, cmd, arg); } diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index e9a26fbd079c..8d994a8bdc90 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -813,7 +813,7 @@ static int acm_tty_tiocmset(struct tty_struct *tty, return acm_set_control(acm, acm->ctrlout = newctrl); } -static int acm_tty_ioctl(struct tty_struct *tty, struct file *file, +static int acm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct acm *acm = tty->driver_data; diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index b1110e136c33..a72575349744 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -406,7 +406,7 @@ static void serial_unthrottle(struct tty_struct *tty) port->serial->type->unthrottle(tty); } -static int serial_ioctl(struct tty_struct *tty, struct file *file, +static int serial_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; diff --git a/include/linux/tty.h b/include/linux/tty.h index 54e4eaaa0561..483df15146d2 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -584,7 +584,7 @@ extern int pcxe_open(struct tty_struct *tty, struct file *filp); /* vt.c */ -extern int vt_ioctl(struct tty_struct *tty, struct file *file, +extern int vt_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); extern long vt_compat_ioctl(struct tty_struct *tty, struct file * file, diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 5dabaa2e6da3..9deeac855240 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -98,8 +98,7 @@ * * Note: Do not call this function directly, call tty_write_room * - * int (*ioctl)(struct tty_struct *tty, struct file * file, - * unsigned int cmd, unsigned long arg); + * int (*ioctl)(struct tty_struct *tty, unsigned int cmd, unsigned long arg); * * This routine allows the tty driver to implement * device-specific ioctls. If the ioctl number passed in cmd @@ -107,7 +106,7 @@ * * Optional * - * long (*compat_ioctl)(struct tty_struct *tty, struct file * file, + * long (*compat_ioctl)(struct tty_struct *tty,, * unsigned int cmd, unsigned long arg); * * implement ioctl processing for 32 bit process on 64 bit system @@ -256,9 +255,9 @@ struct tty_operations { void (*flush_chars)(struct tty_struct *tty); int (*write_room)(struct tty_struct *tty); int (*chars_in_buffer)(struct tty_struct *tty); - int (*ioctl)(struct tty_struct *tty, struct file * file, + int (*ioctl)(struct tty_struct *tty, unsigned int cmd, unsigned long arg); - long (*compat_ioctl)(struct tty_struct *tty, struct file * file, + long (*compat_ioctl)(struct tty_struct *tty, unsigned int cmd, unsigned long arg); void (*set_termios)(struct tty_struct *tty, struct ktermios * old); void (*throttle)(struct tty_struct * tty); diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h index 980ccb66e1b4..59ba38bc400f 100644 --- a/include/net/irda/ircomm_tty.h +++ b/include/net/irda/ircomm_tty.h @@ -123,7 +123,7 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self); extern int ircomm_tty_tiocmget(struct tty_struct *tty); extern int ircomm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); -extern int ircomm_tty_ioctl(struct tty_struct *tty, struct file *file, +extern int ircomm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); extern void ircomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios); diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 8e78e7447726..b1805ff95415 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -830,7 +830,7 @@ static int rfcomm_tty_write_room(struct tty_struct *tty) return room; } -static int rfcomm_tty_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg) +static int rfcomm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { BT_DBG("tty %p cmd 0x%02x", tty, cmd); diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c index 5e0e718c930a..77c5e6499f8f 100644 --- a/net/irda/ircomm/ircomm_tty_ioctl.c +++ b/net/irda/ircomm/ircomm_tty_ioctl.c @@ -365,12 +365,12 @@ static int ircomm_tty_set_serial_info(struct ircomm_tty_cb *self, } /* - * Function ircomm_tty_ioctl (tty, file, cmd, arg) + * Function ircomm_tty_ioctl (tty, cmd, arg) * * * */ -int ircomm_tty_ioctl(struct tty_struct *tty, struct file *file, +int ircomm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; -- cgit v1.2.3 From 8d075b199b9a66ad90296f898f1f15c0ae1511b8 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 14 Feb 2011 16:27:53 +0000 Subject: tty: add a helper for setting termios data from kernel side This basically encapsulates the small bit of locking knowledge needed. While we are at it make sure we blow up on any more abusers and unsafe misuses of ioctl for this kind of stuff. We change the function to return an argument as at some point it needs to honour the POSIX 'I asked for changes but got none of them' error reporting corner case. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ioctl.c | 14 +++++++++----- include/linux/tty.h | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 0c1889971459..1a1135d580a2 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -486,7 +486,7 @@ int tty_termios_hw_change(struct ktermios *a, struct ktermios *b) EXPORT_SYMBOL(tty_termios_hw_change); /** - * change_termios - update termios values + * tty_set_termios - update termios values * @tty: tty to update * @new_termios: desired new value * @@ -497,7 +497,7 @@ EXPORT_SYMBOL(tty_termios_hw_change); * Locking: termios_mutex */ -static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) +int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios) { struct ktermios old_termios; struct tty_ldisc *ld; @@ -553,7 +553,9 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) tty_ldisc_deref(ld); } mutex_unlock(&tty->termios_mutex); + return 0; } +EXPORT_SYMBOL_GPL(tty_set_termios); /** * set_termios - set termios values for a tty @@ -562,7 +564,7 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) * @opt: option information * * Helper function to prepare termios data and run necessary other - * functions before using change_termios to do the actual changes. + * functions before using tty_set_termios to do the actual changes. * * Locking: * Called functions take ldisc and termios_mutex locks @@ -620,7 +622,7 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt) return -EINTR; } - change_termios(tty, &tmp_termios); + tty_set_termios(tty, &tmp_termios); /* FIXME: Arguably if tmp_termios == tty->termios AND the actual requested termios was not tmp_termios then we may @@ -797,7 +799,7 @@ static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) termios.c_ospeed); #endif mutex_unlock(&tty->termios_mutex); - change_termios(tty, &termios); + tty_set_termios(tty, &termios); return 0; } #endif @@ -951,6 +953,8 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file, int ret = 0; struct ktermios kterm; + BUG_ON(file == NULL); + if (tty->driver->type == TTY_DRIVER_TYPE_PTY && tty->driver->subtype == PTY_TYPE_MASTER) real_tty = tty->link; diff --git a/include/linux/tty.h b/include/linux/tty.h index ef1e0123573b..4e53d4641b38 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -448,6 +448,7 @@ extern void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud); extern void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old); extern int tty_termios_hw_change(struct ktermios *a, struct ktermios *b); +extern int tty_set_termios(struct tty_struct *tty, struct ktermios *kt); extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *); extern void tty_ldisc_deref(struct tty_ldisc *); -- cgit v1.2.3 From afaae08442d86402f9e0b63475c02a651c6f1387 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 14 Feb 2011 16:28:18 +0000 Subject: hci_ath: Fix the mess in this driver Was this exploitable - who knows, but it was certainly totally broken Signed-of-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/bluetooth/hci_ath.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c index 6a160c17ea94..bd34406faaae 100644 --- a/drivers/bluetooth/hci_ath.c +++ b/drivers/bluetooth/hci_ath.c @@ -51,32 +51,32 @@ struct ath_struct { static int ath_wakeup_ar3k(struct tty_struct *tty) { - struct termios settings; - int status = tty->driver->ops->tiocmget(tty, NULL); + struct ktermios ktermios; + int status = tty->driver->ops->tiocmget(tty); if (status & TIOCM_CTS) return status; /* Disable Automatic RTSCTS */ - n_tty_ioctl_helper(tty, NULL, TCGETS, (unsigned long)&settings); - settings.c_cflag &= ~CRTSCTS; - n_tty_ioctl_helper(tty, NULL, TCSETS, (unsigned long)&settings); + memcpy(&ktermios, tty->termios, sizeof(ktermios)); + ktermios.c_cflag &= ~CRTSCTS; + tty_set_termios(tty, &ktermios); /* Clear RTS first */ - status = tty->driver->ops->tiocmget(tty, NULL); - tty->driver->ops->tiocmset(tty, NULL, 0x00, TIOCM_RTS); + status = tty->driver->ops->tiocmget(tty); + tty->driver->ops->tiocmset(tty, 0x00, TIOCM_RTS); mdelay(20); /* Set RTS, wake up board */ - status = tty->driver->ops->tiocmget(tty, NULL); - tty->driver->ops->tiocmset(tty, NULL, TIOCM_RTS, 0x00); + status = tty->driver->ops->tiocmget(tty); + tty->driver->ops->tiocmset(tty, TIOCM_RTS, 0x00); mdelay(20); - status = tty->driver->ops->tiocmget(tty, NULL); + status = tty->driver->ops->tiocmget(tty); - n_tty_ioctl_helper(tty, NULL, TCGETS, (unsigned long)&settings); - settings.c_cflag |= CRTSCTS; - n_tty_ioctl_helper(tty, NULL, TCSETS, (unsigned long)&settings); + /* Disable Automatic RTSCTS */ + ktermios.c_cflag |= CRTSCTS; + status = tty_set_termios(tty, &ktermios); return status; } -- cgit v1.2.3 From 9721dbb375a9db5f7f430601b7ec0393e1c59f82 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 17 Feb 2011 21:14:15 +0100 Subject: net/fec: remove unused driver data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apart from not being used the first argument isn't even a struct platform_device *. Reported-by: Marc Kleine-Budde Signed-off-by: Uwe Kleine-König --- drivers/net/fec.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 74798bee672e..634c0daeecec 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -983,8 +983,6 @@ static int fec_enet_mii_init(struct platform_device *pdev) for (i = 0; i < PHY_MAX_ADDR; i++) fep->mii_bus->irq[i] = PHY_POLL; - platform_set_drvdata(ndev, fep->mii_bus); - if (mdiobus_register(fep->mii_bus)) goto err_out_free_mdio_irq; -- cgit v1.2.3 From ab532cf32b4055028ad095d3c1fee9eec28ed25e Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Wed, 16 Feb 2011 10:27:02 +0000 Subject: bnx2x: Support for managing RX indirection table Support fetching and retrieving RX indirection table via ethtool. Signed-off-by: Tom Herbert Acked-by: Eric Dumazet Acked-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 2 ++ drivers/net/bnx2x/bnx2x_ethtool.c | 56 +++++++++++++++++++++++++++++++++++++++ drivers/net/bnx2x/bnx2x_main.c | 22 +++++++++++---- 3 files changed, 75 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 236d79a80624..c0dd30d870ae 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1076,6 +1076,7 @@ struct bnx2x { int num_queues; int disable_tpa; int int_mode; + u32 *rx_indir_table; struct tstorm_eth_mac_filter_config mac_filters; #define BNX2X_ACCEPT_NONE 0x0000 @@ -1799,5 +1800,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, BNX2X_EXTERN int load_count[2][3]; /* per path: 0-common, 1-port0, 2-port1 */ extern void bnx2x_set_ethtool_ops(struct net_device *netdev); +void bnx2x_push_indir_table(struct bnx2x *bp); #endif /* bnx2x.h */ diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 816fef6d3844..8d19d127f796 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -2134,6 +2134,59 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data) return 0; } +static int bnx2x_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info, + void *rules __always_unused) +{ + struct bnx2x *bp = netdev_priv(dev); + + switch (info->cmd) { + case ETHTOOL_GRXRINGS: + info->data = BNX2X_NUM_ETH_QUEUES(bp); + return 0; + + default: + return -EOPNOTSUPP; + } +} + +static int bnx2x_get_rxfh_indir(struct net_device *dev, + struct ethtool_rxfh_indir *indir) +{ + struct bnx2x *bp = netdev_priv(dev); + size_t copy_size = + min_t(size_t, indir->size, TSTORM_INDIRECTION_TABLE_SIZE); + + if (bp->multi_mode == ETH_RSS_MODE_DISABLED) + return -EOPNOTSUPP; + + indir->size = TSTORM_INDIRECTION_TABLE_SIZE; + memcpy(indir->ring_index, bp->rx_indir_table, + copy_size * sizeof(bp->rx_indir_table[0])); + return 0; +} + +static int bnx2x_set_rxfh_indir(struct net_device *dev, + const struct ethtool_rxfh_indir *indir) +{ + struct bnx2x *bp = netdev_priv(dev); + size_t i; + + if (bp->multi_mode == ETH_RSS_MODE_DISABLED) + return -EOPNOTSUPP; + + /* Validate size and indices */ + if (indir->size != TSTORM_INDIRECTION_TABLE_SIZE) + return -EINVAL; + for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) + if (indir->ring_index[i] >= BNX2X_NUM_ETH_QUEUES(bp)) + return -EINVAL; + + memcpy(bp->rx_indir_table, indir->ring_index, + indir->size * sizeof(bp->rx_indir_table[0])); + bnx2x_push_indir_table(bp); + return 0; +} + static const struct ethtool_ops bnx2x_ethtool_ops = { .get_settings = bnx2x_get_settings, .set_settings = bnx2x_set_settings, @@ -2170,6 +2223,9 @@ static const struct ethtool_ops bnx2x_ethtool_ops = { .get_strings = bnx2x_get_strings, .phys_id = bnx2x_phys_id, .get_ethtool_stats = bnx2x_get_ethtool_stats, + .get_rxnfc = bnx2x_get_rxnfc, + .get_rxfh_indir = bnx2x_get_rxfh_indir, + .set_rxfh_indir = bnx2x_set_rxfh_indir, }; void bnx2x_set_ethtool_ops(struct net_device *netdev) diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index c238c4d65d13..6c7745eee00d 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -4254,7 +4254,7 @@ static void bnx2x_init_eq_ring(struct bnx2x *bp) min_t(int, MAX_SP_DESC_CNT - MAX_SPQ_PENDING, NUM_EQ_DESC) - 1); } -static void bnx2x_init_ind_table(struct bnx2x *bp) +void bnx2x_push_indir_table(struct bnx2x *bp) { int func = BP_FUNC(bp); int i; @@ -4262,13 +4262,20 @@ static void bnx2x_init_ind_table(struct bnx2x *bp) if (bp->multi_mode == ETH_RSS_MODE_DISABLED) return; - DP(NETIF_MSG_IFUP, - "Initializing indirection table multi_mode %d\n", bp->multi_mode); for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_INDIRECTION_TABLE_OFFSET(func) + i, - bp->fp->cl_id + (i % (bp->num_queues - - NONE_ETH_CONTEXT_USE))); + bp->fp->cl_id + bp->rx_indir_table[i]); +} + +static void bnx2x_init_ind_table(struct bnx2x *bp) +{ + int i; + + for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) + bp->rx_indir_table[i] = i % BNX2X_NUM_ETH_QUEUES(bp); + + bnx2x_push_indir_table(bp); } void bnx2x_set_storm_rx_mode(struct bnx2x *bp) @@ -6016,6 +6023,8 @@ void bnx2x_free_mem(struct bnx2x *bp) BNX2X_PCI_FREE(bp->eq_ring, bp->eq_mapping, BCM_PAGE_SIZE * NUM_EQ_PAGES); + BNX2X_FREE(bp->rx_indir_table); + #undef BNX2X_PCI_FREE #undef BNX2X_KFREE } @@ -6146,6 +6155,9 @@ int bnx2x_alloc_mem(struct bnx2x *bp) /* EQ */ BNX2X_PCI_ALLOC(bp->eq_ring, &bp->eq_mapping, BCM_PAGE_SIZE * NUM_EQ_PAGES); + + BNX2X_ALLOC(bp->rx_indir_table, sizeof(bp->rx_indir_table[0]) * + TSTORM_INDIRECTION_TABLE_SIZE); return 0; alloc_mem_err: -- cgit v1.2.3 From 64d8ad6d745bbb596bfce3c5d0157267feba7e26 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 5 Jan 2011 00:50:41 +0000 Subject: sfc: Implement hardware acceleration of RFS Use the existing filter management functions to insert TCP/IPv4 and UDP/IPv4 4-tuple filters for Receive Flow Steering. For each channel, track how many RFS filters are being added during processing of received packets and scan the corresponding number of table entries for filters that may be reclaimed. Do this in batches to reduce lock overhead. Signed-off-by: Ben Hutchings --- drivers/net/sfc/efx.c | 49 +++++++++++++++++++- drivers/net/sfc/efx.h | 15 +++++++ drivers/net/sfc/filter.c | 104 +++++++++++++++++++++++++++++++++++++++++++ drivers/net/sfc/net_driver.h | 3 ++ 4 files changed, 169 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index d4e04256730b..35b7bc52a2d1 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "net_driver.h" #include "efx.h" #include "nic.h" @@ -307,6 +308,8 @@ static int efx_poll(struct napi_struct *napi, int budget) channel->irq_mod_score = 0; } + efx_filter_rfs_expire(channel); + /* There is no race here; although napi_disable() will * only wait for napi_complete(), this isn't a problem * since efx_channel_processed() will have no effect if @@ -1175,10 +1178,32 @@ static int efx_wanted_channels(void) return count; } +static int +efx_init_rx_cpu_rmap(struct efx_nic *efx, struct msix_entry *xentries) +{ +#ifdef CONFIG_RFS_ACCEL + int i, rc; + + efx->net_dev->rx_cpu_rmap = alloc_irq_cpu_rmap(efx->n_rx_channels); + if (!efx->net_dev->rx_cpu_rmap) + return -ENOMEM; + for (i = 0; i < efx->n_rx_channels; i++) { + rc = irq_cpu_rmap_add(efx->net_dev->rx_cpu_rmap, + xentries[i].vector); + if (rc) { + free_irq_cpu_rmap(efx->net_dev->rx_cpu_rmap); + efx->net_dev->rx_cpu_rmap = NULL; + return rc; + } + } +#endif + return 0; +} + /* Probe the number and type of interrupts we are able to obtain, and * the resulting numbers of channels and RX queues. */ -static void efx_probe_interrupts(struct efx_nic *efx) +static int efx_probe_interrupts(struct efx_nic *efx) { int max_channels = min_t(int, efx->type->phys_addr_channels, EFX_MAX_CHANNELS); @@ -1220,6 +1245,11 @@ static void efx_probe_interrupts(struct efx_nic *efx) efx->n_tx_channels = efx->n_channels; efx->n_rx_channels = efx->n_channels; } + rc = efx_init_rx_cpu_rmap(efx, xentries); + if (rc) { + pci_disable_msix(efx->pci_dev); + return rc; + } for (i = 0; i < n_channels; i++) efx_get_channel(efx, i)->irq = xentries[i].vector; @@ -1253,6 +1283,8 @@ static void efx_probe_interrupts(struct efx_nic *efx) efx->n_tx_channels = 1; efx->legacy_irq = efx->pci_dev->irq; } + + return 0; } static void efx_remove_interrupts(struct efx_nic *efx) @@ -1289,7 +1321,9 @@ static int efx_probe_nic(struct efx_nic *efx) /* Determine the number of channels and queues by trying to hook * in MSI-X interrupts. */ - efx_probe_interrupts(efx); + rc = efx_probe_interrupts(efx); + if (rc) + goto fail; if (efx->n_channels > 1) get_random_bytes(&efx->rx_hash_key, sizeof(efx->rx_hash_key)); @@ -1304,6 +1338,10 @@ static int efx_probe_nic(struct efx_nic *efx) efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec, true); return 0; + +fail: + efx->type->remove(efx); + return rc; } static void efx_remove_nic(struct efx_nic *efx) @@ -1837,6 +1875,9 @@ static const struct net_device_ops efx_netdev_ops = { .ndo_poll_controller = efx_netpoll, #endif .ndo_setup_tc = efx_setup_tc, +#ifdef CONFIG_RFS_ACCEL + .ndo_rx_flow_steer = efx_filter_rfs, +#endif }; static void efx_update_name(struct efx_nic *efx) @@ -2274,6 +2315,10 @@ static void efx_fini_struct(struct efx_nic *efx) */ static void efx_pci_remove_main(struct efx_nic *efx) { +#ifdef CONFIG_RFS_ACCEL + free_irq_cpu_rmap(efx->net_dev->rx_cpu_rmap); + efx->net_dev->rx_cpu_rmap = NULL; +#endif efx_nic_fini_interrupt(efx); efx_fini_channels(efx); efx_fini_port(efx); diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index 0cb198a64a63..cbce62b9c996 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h @@ -76,6 +76,21 @@ extern int efx_filter_remove_filter(struct efx_nic *efx, struct efx_filter_spec *spec); extern void efx_filter_clear_rx(struct efx_nic *efx, enum efx_filter_priority priority); +#ifdef CONFIG_RFS_ACCEL +extern int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, + u16 rxq_index, u32 flow_id); +extern bool __efx_filter_rfs_expire(struct efx_nic *efx, unsigned quota); +static inline void efx_filter_rfs_expire(struct efx_channel *channel) +{ + if (channel->rfs_filters_added >= 60 && + __efx_filter_rfs_expire(channel->efx, 100)) + channel->rfs_filters_added -= 60; +} +#define efx_filter_rfs_enabled() 1 +#else +static inline void efx_filter_rfs_expire(struct efx_channel *channel) {} +#define efx_filter_rfs_enabled() 0 +#endif /* Channels */ extern void efx_process_channel_now(struct efx_channel *channel); diff --git a/drivers/net/sfc/filter.c b/drivers/net/sfc/filter.c index 47a1b7984788..95a980fd63d5 100644 --- a/drivers/net/sfc/filter.c +++ b/drivers/net/sfc/filter.c @@ -8,6 +8,7 @@ */ #include +#include #include "efx.h" #include "filter.h" #include "io.h" @@ -51,6 +52,10 @@ struct efx_filter_table { struct efx_filter_state { spinlock_t lock; struct efx_filter_table table[EFX_FILTER_TABLE_COUNT]; +#ifdef CONFIG_RFS_ACCEL + u32 *rps_flow_id; + unsigned rps_expire_index; +#endif }; /* The filter hash function is LFSR polynomial x^16 + x^3 + 1 of a 32-bit @@ -567,6 +572,13 @@ int efx_probe_filters(struct efx_nic *efx) spin_lock_init(&state->lock); if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { +#ifdef CONFIG_RFS_ACCEL + state->rps_flow_id = kcalloc(FR_BZ_RX_FILTER_TBL0_ROWS, + sizeof(*state->rps_flow_id), + GFP_KERNEL); + if (!state->rps_flow_id) + goto fail; +#endif table = &state->table[EFX_FILTER_TABLE_RX_IP]; table->id = EFX_FILTER_TABLE_RX_IP; table->offset = FR_BZ_RX_FILTER_TBL0; @@ -612,5 +624,97 @@ void efx_remove_filters(struct efx_nic *efx) kfree(state->table[table_id].used_bitmap); vfree(state->table[table_id].spec); } +#ifdef CONFIG_RFS_ACCEL + kfree(state->rps_flow_id); +#endif kfree(state); } + +#ifdef CONFIG_RFS_ACCEL + +int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, + u16 rxq_index, u32 flow_id) +{ + struct efx_nic *efx = netdev_priv(net_dev); + struct efx_channel *channel; + struct efx_filter_state *state = efx->filter_state; + struct efx_filter_spec spec; + const struct iphdr *ip; + const __be16 *ports; + int nhoff; + int rc; + + nhoff = skb_network_offset(skb); + + if (skb->protocol != htons(ETH_P_IP)) + return -EPROTONOSUPPORT; + + /* RFS must validate the IP header length before calling us */ + EFX_BUG_ON_PARANOID(!pskb_may_pull(skb, nhoff + sizeof(*ip))); + ip = (const struct iphdr *)(skb->data + nhoff); + if (ip->frag_off & htons(IP_MF | IP_OFFSET)) + return -EPROTONOSUPPORT; + EFX_BUG_ON_PARANOID(!pskb_may_pull(skb, nhoff + 4 * ip->ihl + 4)); + ports = (const __be16 *)(skb->data + nhoff + 4 * ip->ihl); + + efx_filter_init_rx(&spec, EFX_FILTER_PRI_HINT, 0, rxq_index); + rc = efx_filter_set_ipv4_full(&spec, ip->protocol, + ip->daddr, ports[1], ip->saddr, ports[0]); + if (rc) + return rc; + + rc = efx_filter_insert_filter(efx, &spec, true); + if (rc < 0) + return rc; + + /* Remember this so we can check whether to expire the filter later */ + state->rps_flow_id[rc] = flow_id; + channel = efx_get_channel(efx, skb_get_rx_queue(skb)); + ++channel->rfs_filters_added; + + netif_info(efx, rx_status, efx->net_dev, + "steering %s %pI4:%u:%pI4:%u to queue %u [flow %u filter %d]\n", + (ip->protocol == IPPROTO_TCP) ? "TCP" : "UDP", + &ip->saddr, ntohs(ports[0]), &ip->daddr, ntohs(ports[1]), + rxq_index, flow_id, rc); + + return rc; +} + +bool __efx_filter_rfs_expire(struct efx_nic *efx, unsigned quota) +{ + struct efx_filter_state *state = efx->filter_state; + struct efx_filter_table *table = &state->table[EFX_FILTER_TABLE_RX_IP]; + unsigned mask = table->size - 1; + unsigned index; + unsigned stop; + + if (!spin_trylock_bh(&state->lock)) + return false; + + index = state->rps_expire_index; + stop = (index + quota) & mask; + + while (index != stop) { + if (test_bit(index, table->used_bitmap) && + table->spec[index].priority == EFX_FILTER_PRI_HINT && + rps_may_expire_flow(efx->net_dev, + table->spec[index].dmaq_id, + state->rps_flow_id[index], index)) { + netif_info(efx, rx_status, efx->net_dev, + "expiring filter %d [flow %u]\n", + index, state->rps_flow_id[index]); + efx_filter_table_clear_entry(efx, table, index); + } + index = (index + 1) & mask; + } + + state->rps_expire_index = stop; + if (table->used == 0) + efx_filter_table_reset_search_depth(table); + + spin_unlock_bh(&state->lock); + return true; +} + +#endif /* CONFIG_RFS_ACCEL */ diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 96e22ad34970..15b9068e5b87 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -362,6 +362,9 @@ struct efx_channel { unsigned int irq_count; unsigned int irq_mod_score; +#ifdef CONFIG_RFS_ACCEL + unsigned int rfs_filters_added; +#endif int rx_alloc_level; int rx_alloc_push_pages; -- cgit v1.2.3 From db2e2e6ee9ee9ce93b04c6975fdfef304771d6ad Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 24 Jan 2011 15:43:03 +0100 Subject: xen-pcifront: don't use flush_scheduled_work() flush_scheduled_work() is scheduled for deprecation. Cancel ->op_work directly instead. Signed-off-by: Tejun Heo Cc: Ryan Wilson Cc: Jan Beulich Cc: Jesse Barnes Signed-off-by: Konrad Rzeszutek Wilk --- drivers/pci/xen-pcifront.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index 3a5a6fcc0ead..030ce3743439 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c @@ -733,8 +733,7 @@ static void free_pdev(struct pcifront_device *pdev) pcifront_free_roots(pdev); - /*For PCIE_AER error handling job*/ - flush_scheduled_work(); + cancel_work_sync(&pdev->op_work); if (pdev->irq >= 0) unbind_from_irqhandler(pdev->irq, pdev); -- cgit v1.2.3 From c0af2c057d7ce3f0b260f9380d187a82bb5cab28 Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Wed, 16 Feb 2011 15:48:25 +0000 Subject: IB/qib: Prevent double completions after a timeout or RNR error There is a double completion associated with error handling for RC QPs. The sequence is: - The do_rc_ack() routine fields an RNR nack and there are 0 rnr_retries configured on the QP. - qib_error_qp() stops the pending timer - qib_rc_send_complete() is called from sdma_complete() - qib_rc_send_complete() starts the timer because the msb of the psn just completed says an ack is needed. - a bunch of flushes occur as ipoib posts WQEs to an error'ed QP - rc_timeout() calls qib_restart_rc() - qib_restart_rc() calls qib_send_complete() with a IB_WC_RETRY_EXC_ERR on a wqe that has already been completed in the past The fix avoids starting the timer since another packet will never arrive. Signed-off-by: Mike Marciniszyn Signed-off-by: Roland Dreier --- drivers/infiniband/hw/qib/qib_rc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/qib/qib_rc.c b/drivers/infiniband/hw/qib/qib_rc.c index 31e09b05a1a7..eca0c41f1226 100644 --- a/drivers/infiniband/hw/qib/qib_rc.c +++ b/drivers/infiniband/hw/qib/qib_rc.c @@ -1005,7 +1005,8 @@ void qib_rc_send_complete(struct qib_qp *qp, struct qib_ib_header *hdr) * there are still requests that haven't been acked. */ if ((psn & IB_BTH_REQ_ACK) && qp->s_acked != qp->s_tail && - !(qp->s_flags & (QIB_S_TIMER | QIB_S_WAIT_RNR | QIB_S_WAIT_PSN))) + !(qp->s_flags & (QIB_S_TIMER | QIB_S_WAIT_RNR | QIB_S_WAIT_PSN)) && + (ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) start_timer(qp); while (qp->s_last != qp->s_acked) { -- cgit v1.2.3 From 14796fca2bd22acc73dd0887248d003b0f441d08 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Tue, 18 Jan 2011 20:48:27 -0500 Subject: intel_idle: disable NHM/WSM HW C-state auto-demotion Hardware C-state auto-demotion is a mechanism where the HW overrides the OS C-state request, instead demoting to a shallower state, which is less expensive, but saves less power. Modern Linux should generally get exactly the states it requests. In particular, when a CPU is taken off-line, it must not be demoted, else it can prevent the entire package from reaching deep C-states. https://bugzilla.kernel.org/show_bug.cgi?id=25252 Signed-off-by: Len Brown --- arch/x86/include/asm/msr-index.h | 4 ++++ drivers/idle/intel_idle.c | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) (limited to 'drivers') diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 4d0dfa0d998e..b75eeab2b1ea 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -36,6 +36,10 @@ #define MSR_IA32_PERFCTR1 0x000000c2 #define MSR_FSB_FREQ 0x000000cd +#define MSR_NHM_SNB_PKG_CST_CFG_CTL 0x000000e2 +#define NHM_C3_AUTO_DEMOTE (1UL << 25) +#define NHM_C1_AUTO_DEMOTE (1UL << 26) + #define MSR_MTRRcap 0x000000fe #define MSR_IA32_BBL_CR_CTL 0x00000119 diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 1fa091e05690..32b25bcaf865 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -62,6 +62,7 @@ #include #include #include +#include #define INTEL_IDLE_VERSION "0.4" #define PREFIX "intel_idle: " @@ -84,6 +85,12 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); static struct cpuidle_state *cpuidle_state_table; +/* + * Hardware C-state auto-demotion may not always be optimal. + * Indicate which enable bits to clear here. + */ +static unsigned long long auto_demotion_disable_flags; + /* * Set this flag for states where the HW flushes the TLB for us * and so we don't need cross-calls to keep it consistent. @@ -281,6 +288,15 @@ static struct notifier_block setup_broadcast_notifier = { .notifier_call = setup_broadcast_cpuhp_notify, }; +static void auto_demotion_disable(void *dummy) +{ + unsigned long long msr_bits; + + rdmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits); + msr_bits &= ~auto_demotion_disable_flags; + wrmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits); +} + /* * intel_idle_probe() */ @@ -324,6 +340,8 @@ static int intel_idle_probe(void) case 0x25: /* Westmere */ case 0x2C: /* Westmere */ cpuidle_state_table = nehalem_cstates; + auto_demotion_disable_flags = + (NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE); break; case 0x1C: /* 28 - Atom Processor */ @@ -436,6 +454,8 @@ static int intel_idle_cpuidle_devices_init(void) return -EIO; } } + if (auto_demotion_disable_flags) + smp_call_function(auto_demotion_disable, NULL, 1); return 0; } -- cgit v1.2.3 From bfb53ccf1c734b1907df7189eef4c08489827951 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Wed, 16 Feb 2011 01:32:48 -0500 Subject: intel_idle: disable Atom/Lincroft HW C-state auto-demotion Just as we had to disable auto-demotion for NHM/WSM, we need to do the same for Atom (Lincroft version). In particular, auto-demotion will prevent Lincroft from entering the S0i3 idle power saving state. https://bugzilla.kernel.org/show_bug.cgi?id=25252 Signed-off-by: Len Brown --- arch/x86/include/asm/msr-index.h | 1 + drivers/idle/intel_idle.c | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'drivers') diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index b75eeab2b1ea..43a18c77676d 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -39,6 +39,7 @@ #define MSR_NHM_SNB_PKG_CST_CFG_CTL 0x000000e2 #define NHM_C3_AUTO_DEMOTE (1UL << 25) #define NHM_C1_AUTO_DEMOTE (1UL << 26) +#define ATM_LNC_C6_AUTO_DEMOTE (1UL << 25) #define MSR_MTRRcap 0x000000fe #define MSR_IA32_BBL_CR_CTL 0x00000119 diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 32b25bcaf865..4a5c4a44ffb1 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -345,8 +345,12 @@ static int intel_idle_probe(void) break; case 0x1C: /* 28 - Atom Processor */ + cpuidle_state_table = atom_cstates; + break; + case 0x26: /* 38 - Lincroft Atom Processor */ cpuidle_state_table = atom_cstates; + auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE; break; case 0x2A: /* SNB */ -- cgit v1.2.3 From 0d672e9f8ac320c6d1ea9103db6df7f99ea20361 Mon Sep 17 00:00:00 2001 From: Ivan Vecera Date: Tue, 15 Feb 2011 02:08:39 +0000 Subject: drivers/net: Call netif_carrier_off at the end of the probe Without calling of netif_carrier_off at the end of the probe the operstate is unknown when the device is initially opened. By default the carrier is on so when the device is opened and netif_carrier_on is called the link watch event is not fired and operstate remains zero (unknown). This patch fixes this behavior in forcedeth and r8169. Signed-off-by: Ivan Vecera Acked-by: Francois Romieu Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 2 ++ drivers/net/r8169.c | 2 ++ 2 files changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index af09296ef0dd..9c0b1bac6af6 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -5645,6 +5645,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i goto out_error; } + netif_carrier_off(dev); + dev_info(&pci_dev->dev, "ifname %s, PHY OUI 0x%x @ %d, addr %pM\n", dev->name, np->phy_oui, np->phyaddr, dev->dev_addr); diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 59ccf0c5c610..469ab0b7ce31 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -3190,6 +3190,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (pci_dev_run_wake(pdev)) pm_runtime_put_noidle(&pdev->dev); + netif_carrier_off(dev); + out: return rc; -- cgit v1.2.3 From ed199facd070f8e551dc16a2ae1baa01d8d28ed4 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Tue, 15 Feb 2011 12:51:10 +0000 Subject: tg3: Restrict phy ioctl access If management firmware is present and the device is down, the firmware will assume control of the phy. If a phy access were allowed from the host, it will collide with firmware phy accesses, resulting in unpredictable behavior. This patch fixes the problem by disallowing phy accesses during the problematic condition. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 93b32d366611..06c0e5033656 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -11158,7 +11158,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) break; /* We have no PHY */ - if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) + if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) || + ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) && + !netif_running(dev))) return -EAGAIN; spin_lock_bh(&tp->lock); @@ -11174,7 +11176,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) break; /* We have no PHY */ - if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) + if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) || + ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) && + !netif_running(dev))) return -EAGAIN; spin_lock_bh(&tp->lock); -- cgit v1.2.3 From e0afe53fbea3823a1b1faef8d7701dd73bb74d5c Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Thu, 17 Feb 2011 08:53:12 +0000 Subject: enic: Bug fix: Reset driver count of registered unicast addresses to zero during device reset During a device reset, clear the counter for the no. of unicast addresses registered. Also, rename the routines that update unicast and multicast address lists. Signed-off-by: Christian Benvenuti Signed-off-by: Danny Guo Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 2 +- drivers/net/enic/enic_main.c | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 57fcaeea94f7..5f4eb45345c1 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "2.1.1.6" +#define DRV_VERSION "2.1.1.7" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 0c243704ca40..a625a0e09169 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -874,9 +874,10 @@ static struct net_device_stats *enic_get_stats(struct net_device *netdev) return net_stats; } -static void enic_reset_multicast_list(struct enic *enic) +static void enic_reset_addr_lists(struct enic *enic) { enic->mc_count = 0; + enic->uc_count = 0; enic->flags = 0; } @@ -941,7 +942,7 @@ static int enic_set_mac_address(struct net_device *netdev, void *p) return enic_dev_add_station_addr(enic); } -static void enic_add_multicast_addr_list(struct enic *enic) +static void enic_update_multicast_addr_list(struct enic *enic) { struct net_device *netdev = enic->netdev; struct netdev_hw_addr *ha; @@ -996,7 +997,7 @@ static void enic_add_multicast_addr_list(struct enic *enic) enic->mc_count = mc_count; } -static void enic_add_unicast_addr_list(struct enic *enic) +static void enic_update_unicast_addr_list(struct enic *enic) { struct net_device *netdev = enic->netdev; struct netdev_hw_addr *ha; @@ -1073,9 +1074,9 @@ static void enic_set_rx_mode(struct net_device *netdev) } if (!promisc) { - enic_add_unicast_addr_list(enic); + enic_update_unicast_addr_list(enic); if (!allmulti) - enic_add_multicast_addr_list(enic); + enic_update_multicast_addr_list(enic); } } @@ -2067,7 +2068,7 @@ static void enic_reset(struct work_struct *work) enic_dev_hang_notify(enic); enic_stop(enic->netdev); enic_dev_hang_reset(enic); - enic_reset_multicast_list(enic); + enic_reset_addr_lists(enic); enic_init_vnic_resources(enic); enic_set_rss_nic_cfg(enic); enic_dev_set_ig_vlan_rewrite_mode(enic); -- cgit v1.2.3 From 5990b1892bbd0bb3adfc9a09bb3bcbde32471e59 Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Thu, 17 Feb 2011 08:53:17 +0000 Subject: enic: Clean up: Remove a not needed #ifdef Signed-off-by: Christian Benvenuti Signed-off-by: Danny Guo Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 2 +- drivers/net/enic/enic_main.c | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 5f4eb45345c1..2ac891b58db3 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "2.1.1.7" +#define DRV_VERSION "2.1.1.8" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index a625a0e09169..d1aa80770541 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -2223,9 +2223,7 @@ static const struct net_device_ops enic_netdev_dynamic_ops = { .ndo_tx_timeout = enic_tx_timeout, .ndo_set_vf_port = enic_set_vf_port, .ndo_get_vf_port = enic_get_vf_port, -#ifdef IFLA_VF_MAX .ndo_set_vf_mac = enic_set_vf_mac, -#endif #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = enic_poll_controller, #endif -- cgit v1.2.3 From 3c95c985fa91ecf6a0e29622bbdd13dcfc5ce9f1 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 17 Feb 2011 18:39:28 +0100 Subject: tty: add TIOCVHANGUP to allow clean tty shutdown of all ttys This is useful for system management software so that it can kick off things like gettys and everything that's started from a tty, before we reuse it from/for something else or shut it down. Without this ioctl it would have to temporarily become the owner of the tty, then call vhangup() and then give it up again. Cc: Lennart Poettering Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- arch/alpha/include/asm/ioctls.h | 1 + arch/mips/include/asm/ioctls.h | 1 + arch/parisc/include/asm/ioctls.h | 1 + arch/powerpc/include/asm/ioctls.h | 1 + arch/sh/include/asm/ioctls.h | 1 + arch/sparc/include/asm/ioctls.h | 1 + arch/xtensa/include/asm/ioctls.h | 1 + drivers/tty/tty_io.c | 5 +++++ include/asm-generic/ioctls.h | 1 + 9 files changed, 13 insertions(+) (limited to 'drivers') diff --git a/arch/alpha/include/asm/ioctls.h b/arch/alpha/include/asm/ioctls.h index 034b6cf5d9f3..80e1cee90f1f 100644 --- a/arch/alpha/include/asm/ioctls.h +++ b/arch/alpha/include/asm/ioctls.h @@ -94,6 +94,7 @@ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ #define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */ #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ +#define TIOCVHANGUP 0x5437 #define TIOCSERCONFIG 0x5453 #define TIOCSERGWILD 0x5454 diff --git a/arch/mips/include/asm/ioctls.h b/arch/mips/include/asm/ioctls.h index d967b8997626..92403c3d6007 100644 --- a/arch/mips/include/asm/ioctls.h +++ b/arch/mips/include/asm/ioctls.h @@ -85,6 +85,7 @@ #define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */ #define TIOCGDEV _IOR('T', 0x32, unsigned int) /* Get primary device node of /dev/console */ #define TIOCSIG _IOW('T', 0x36, int) /* Generate signal on Pty slave */ +#define TIOCVHANGUP 0x5437 /* I hope the range from 0x5480 on is free ... */ #define TIOCSCTTY 0x5480 /* become controlling tty */ diff --git a/arch/parisc/include/asm/ioctls.h b/arch/parisc/include/asm/ioctls.h index 6ba80d03623a..054ec06f9e23 100644 --- a/arch/parisc/include/asm/ioctls.h +++ b/arch/parisc/include/asm/ioctls.h @@ -54,6 +54,7 @@ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ #define TIOCGDEV _IOR('T',0x32, int) /* Get primary device node of /dev/console */ #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ +#define TIOCVHANGUP 0x5437 #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX 0x5451 diff --git a/arch/powerpc/include/asm/ioctls.h b/arch/powerpc/include/asm/ioctls.h index c7dc17cf84f1..e9b78870aaab 100644 --- a/arch/powerpc/include/asm/ioctls.h +++ b/arch/powerpc/include/asm/ioctls.h @@ -96,6 +96,7 @@ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ #define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */ #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ +#define TIOCVHANGUP 0x5437 #define TIOCSERCONFIG 0x5453 #define TIOCSERGWILD 0x5454 diff --git a/arch/sh/include/asm/ioctls.h b/arch/sh/include/asm/ioctls.h index 84e85a792638..a6769f352bf6 100644 --- a/arch/sh/include/asm/ioctls.h +++ b/arch/sh/include/asm/ioctls.h @@ -87,6 +87,7 @@ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ #define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */ #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ +#define TIOCVHANGUP _IO('T', 0x37) #define TIOCSERCONFIG _IO('T', 83) /* 0x5453 */ #define TIOCSERGWILD _IOR('T', 84, int) /* 0x5454 */ diff --git a/arch/sparc/include/asm/ioctls.h b/arch/sparc/include/asm/ioctls.h index ed3807b96bb5..28d0c8b02cc3 100644 --- a/arch/sparc/include/asm/ioctls.h +++ b/arch/sparc/include/asm/ioctls.h @@ -20,6 +20,7 @@ #define TCSETSW2 _IOW('T', 14, struct termios2) #define TCSETSF2 _IOW('T', 15, struct termios2) #define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */ +#define TIOCVHANGUP _IO('T', 0x37) /* Note that all the ioctls that are not available in Linux have a * double underscore on the front to: a) avoid some programs to diff --git a/arch/xtensa/include/asm/ioctls.h b/arch/xtensa/include/asm/ioctls.h index ccf1800f0b0c..fd1d1369a407 100644 --- a/arch/xtensa/include/asm/ioctls.h +++ b/arch/xtensa/include/asm/ioctls.h @@ -100,6 +100,7 @@ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ #define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */ #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ +#define TIOCVHANGUP _IO('T', 0x37) #define TIOCSERCONFIG _IO('T', 83) #define TIOCSERGWILD _IOR('T', 84, int) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 20a862a2a0c2..8ef2d69470ec 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2626,6 +2626,11 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return put_user(tty->ldisc->ops->num, (int __user *)p); case TIOCSETD: return tiocsetd(tty, p); + case TIOCVHANGUP: + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + tty_vhangup(tty); + return 0; case TIOCGDEV: { unsigned int ret = new_encode_dev(tty_devnum(real_tty)); diff --git a/include/asm-generic/ioctls.h b/include/asm-generic/ioctls.h index 3f3f2d189fb8..199975fac395 100644 --- a/include/asm-generic/ioctls.h +++ b/include/asm-generic/ioctls.h @@ -73,6 +73,7 @@ #define TCSETXF 0x5434 #define TCSETXW 0x5435 #define TIOCSIG _IOW('T', 0x36, int) /* pty: generate signal */ +#define TIOCVHANGUP 0x5437 #define FIONCLEX 0x5450 #define FIOCLEX 0x5451 -- cgit v1.2.3 From cf0bdefd4676ad4ad59507a058821491a40ec7e6 Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Tue, 15 Feb 2011 16:59:18 +0000 Subject: loopback: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This also enables TSOv6, TSO-ECN, and UFO as loopback clearly can handle them. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/loopback.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 2d9663a1c54d..ea0dc451da9c 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -129,10 +129,6 @@ static u32 always_on(struct net_device *dev) static const struct ethtool_ops loopback_ethtool_ops = { .get_link = always_on, - .set_tso = ethtool_op_set_tso, - .get_tx_csum = always_on, - .get_sg = always_on, - .get_rx_csum = always_on, }; static int loopback_dev_init(struct net_device *dev) @@ -169,9 +165,12 @@ static void loopback_setup(struct net_device *dev) dev->type = ARPHRD_LOOPBACK; /* 0x0001*/ dev->flags = IFF_LOOPBACK; dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; + dev->hw_features = NETIF_F_ALL_TSO | NETIF_F_UFO; dev->features = NETIF_F_SG | NETIF_F_FRAGLIST - | NETIF_F_TSO + | NETIF_F_ALL_TSO + | NETIF_F_UFO | NETIF_F_NO_CSUM + | NETIF_F_RXCSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX | NETIF_F_NETNS_LOCAL; -- cgit v1.2.3 From 9ce4f80fb67b47b96c647ac6280a06dbd4bb50d2 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 17 Feb 2011 14:39:36 -0800 Subject: Revert "USB: Reset USB 3.0 devices on (re)discovery" This reverts commit 637d11bfb814637ec7b81e878db3ffea6408a89a. Sarah wants to tweak it some more before it's applied to the tree. Cc: Luben Tuikov Cc: Sarah Sharp Cc: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 0f299b7aad60..d041c6826e43 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2681,13 +2681,17 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, mutex_lock(&usb_address0_mutex); - /* Reset the device; full speed may morph to high speed */ - /* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */ - retval = hub_port_reset(hub, port1, udev, delay); - if (retval < 0) /* error or disconnect */ - goto fail; - /* success, speed is known */ - + if (!udev->config && oldspeed == USB_SPEED_SUPER) { + /* Don't reset USB 3.0 devices during an initial setup */ + usb_set_device_state(udev, USB_STATE_DEFAULT); + } else { + /* Reset the device; full speed may morph to high speed */ + /* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */ + retval = hub_port_reset(hub, port1, udev, delay); + if (retval < 0) /* error or disconnect */ + goto fail; + /* success, speed is known */ + } retval = -ENODEV; if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed) { -- cgit v1.2.3 From 516373b8b60fa4152334b6b6f2ece0f178c540ce Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 14 Feb 2011 11:33:17 +0100 Subject: RTC: Release mutex in error path of rtc_alarm_irq_enable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On hardware that doesn't support alarm interrupts, rtc_alarm_irq_enable could return without releasing the ops_lock mutex. This was introduced in aa0be0f (RTC: Propagate error handling via rtc_timer_enqueue properly) This patch corrects the issue by only returning once the mutex is released. [john.stultz: Reworded the commit log] Signed-off-by: Uwe Kleine-König Signed-off-by: John Stultz --- drivers/rtc/interface.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index a0c01967244d..413ae0537915 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -209,9 +209,8 @@ int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) } if (err) - return err; - - if (!rtc->ops) + /* nothing */; + else if (!rtc->ops) err = -ENODEV; else if (!rtc->ops->alarm_irq_enable) err = -EINVAL; -- cgit v1.2.3 From 6e57b1d6a8d8ed1998229b71c102be1997e397c6 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Fri, 11 Feb 2011 17:45:40 -0800 Subject: RTC: Revert UIE emulation removal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Uwe pointed out that my alarm based UIE emulation is not sufficient to replace the older timer/polling based UIE emulation on devices where there is no alarm irq. This causes rtc devices without alarms to return -EINVAL to UIE ioctls. The fix is to re-instate the old timer/polling method for devices without alarm irqs. This patch reverts the following commits: 042620a018afcfba1d678062b62e46 - Remove UIE emulation 1daeddd5962acad1bea55e524fc0fa - Cleanup removed UIE emulation declaration b5cc8ca1c9c3a37eaddf709b2fd3e1 - Remove Kconfig symbol for UIE emulation The emulation mode will still need to be wired-in with a following patch before it will work. CC: Uwe Kleine-König CC: Thomas Gleixner Reported-by: Uwe Kleine-König Signed-off-by: John Stultz --- drivers/rtc/Kconfig | 12 ++++++ drivers/rtc/rtc-dev.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/rtc.h | 14 +++++++ 3 files changed, 130 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index cdd97192dc69..4941cade319f 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -97,6 +97,18 @@ config RTC_INTF_DEV If unsure, say Y. +config RTC_INTF_DEV_UIE_EMUL + bool "RTC UIE emulation on dev interface" + depends on RTC_INTF_DEV + help + Provides an emulation for RTC_UIE if the underlying rtc chip + driver does not expose RTC_UIE ioctls. Those requests generate + once-per-second update interrupts, used for synchronization. + + The emulation code will read the time from the hardware + clock several times per second, please enable this option + only if you know that you really need it. + config RTC_DRV_TEST tristate "Test driver/device" help diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 37c3cc1b3dd5..dfa72c9c2687 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c @@ -46,6 +46,105 @@ static int rtc_dev_open(struct inode *inode, struct file *file) return err; } +#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL +/* + * Routine to poll RTC seconds field for change as often as possible, + * after first RTC_UIE use timer to reduce polling + */ +static void rtc_uie_task(struct work_struct *work) +{ + struct rtc_device *rtc = + container_of(work, struct rtc_device, uie_task); + struct rtc_time tm; + int num = 0; + int err; + + err = rtc_read_time(rtc, &tm); + + spin_lock_irq(&rtc->irq_lock); + if (rtc->stop_uie_polling || err) { + rtc->uie_task_active = 0; + } else if (rtc->oldsecs != tm.tm_sec) { + num = (tm.tm_sec + 60 - rtc->oldsecs) % 60; + rtc->oldsecs = tm.tm_sec; + rtc->uie_timer.expires = jiffies + HZ - (HZ/10); + rtc->uie_timer_active = 1; + rtc->uie_task_active = 0; + add_timer(&rtc->uie_timer); + } else if (schedule_work(&rtc->uie_task) == 0) { + rtc->uie_task_active = 0; + } + spin_unlock_irq(&rtc->irq_lock); + if (num) + rtc_update_irq(rtc, num, RTC_UF | RTC_IRQF); +} +static void rtc_uie_timer(unsigned long data) +{ + struct rtc_device *rtc = (struct rtc_device *)data; + unsigned long flags; + + spin_lock_irqsave(&rtc->irq_lock, flags); + rtc->uie_timer_active = 0; + rtc->uie_task_active = 1; + if ((schedule_work(&rtc->uie_task) == 0)) + rtc->uie_task_active = 0; + spin_unlock_irqrestore(&rtc->irq_lock, flags); +} + +static int clear_uie(struct rtc_device *rtc) +{ + spin_lock_irq(&rtc->irq_lock); + if (rtc->uie_irq_active) { + rtc->stop_uie_polling = 1; + if (rtc->uie_timer_active) { + spin_unlock_irq(&rtc->irq_lock); + del_timer_sync(&rtc->uie_timer); + spin_lock_irq(&rtc->irq_lock); + rtc->uie_timer_active = 0; + } + if (rtc->uie_task_active) { + spin_unlock_irq(&rtc->irq_lock); + flush_scheduled_work(); + spin_lock_irq(&rtc->irq_lock); + } + rtc->uie_irq_active = 0; + } + spin_unlock_irq(&rtc->irq_lock); + return 0; +} + +static int set_uie(struct rtc_device *rtc) +{ + struct rtc_time tm; + int err; + + err = rtc_read_time(rtc, &tm); + if (err) + return err; + spin_lock_irq(&rtc->irq_lock); + if (!rtc->uie_irq_active) { + rtc->uie_irq_active = 1; + rtc->stop_uie_polling = 0; + rtc->oldsecs = tm.tm_sec; + rtc->uie_task_active = 1; + if (schedule_work(&rtc->uie_task) == 0) + rtc->uie_task_active = 0; + } + rtc->irq_data = 0; + spin_unlock_irq(&rtc->irq_lock); + return 0; +} + +int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc, unsigned int enabled) +{ + if (enabled) + return set_uie(rtc); + else + return clear_uie(rtc); +} +EXPORT_SYMBOL(rtc_dev_update_irq_enable_emul); + +#endif /* CONFIG_RTC_INTF_DEV_UIE_EMUL */ static ssize_t rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) @@ -387,6 +486,11 @@ void rtc_dev_prepare(struct rtc_device *rtc) rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id); +#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL + INIT_WORK(&rtc->uie_task, rtc_uie_task); + setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc); +#endif + cdev_init(&rtc->char_dev, &rtc_dev_fops); rtc->char_dev.owner = rtc->owner; } diff --git a/include/linux/rtc.h b/include/linux/rtc.h index a0b639f8e805..80408e711bed 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -203,6 +203,18 @@ struct rtc_device struct hrtimer pie_timer; /* sub second exp, so needs hrtimer */ int pie_enabled; struct work_struct irqwork; + + +#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL + struct work_struct uie_task; + struct timer_list uie_timer; + /* Those fields are protected by rtc->irq_lock */ + unsigned int oldsecs; + unsigned int uie_irq_active:1; + unsigned int stop_uie_polling:1; + unsigned int uie_task_active:1; + unsigned int uie_timer_active:1; +#endif }; #define to_rtc_device(d) container_of(d, struct rtc_device, dev) @@ -235,6 +247,8 @@ extern int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq); extern int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled); extern int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled); +extern int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc, + unsigned int enabled); void rtc_aie_update_irq(void *private); void rtc_uie_update_irq(void *private); -- cgit v1.2.3 From 456d66ecd09e3bc326b93174745faafb6ac378d6 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Fri, 11 Feb 2011 18:15:23 -0800 Subject: RTC: Re-enable UIE timer/polling emulation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch re-enables UIE timer/polling emulation for rtc devices that do not support alarm irqs. CC: Uwe Kleine-König CC: Thomas Gleixner Reported-by: Uwe Kleine-König Tested-by: Uwe Kleine-König Signed-off-by: John Stultz --- drivers/rtc/interface.c | 18 +++++++++++++++++- drivers/rtc/rtc-dev.c | 2 +- include/linux/rtc.h | 1 + 3 files changed, 19 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 413ae0537915..cb2f0728fd70 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -228,6 +228,12 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) if (err) return err; +#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL + if (enabled == 0 && rtc->uie_irq_active) { + mutex_unlock(&rtc->ops_lock); + return rtc_dev_update_irq_enable_emul(rtc, 0); + } +#endif /* make sure we're changing state */ if (rtc->uie_rtctimer.enabled == enabled) goto out; @@ -247,6 +253,16 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) out: mutex_unlock(&rtc->ops_lock); +#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL + /* + * Enable emulation if the driver did not provide + * the update_irq_enable function pointer or if returned + * -EINVAL to signal that it has been configured without + * interrupts or that are not available at the moment. + */ + if (err == -EINVAL) + err = rtc_dev_update_irq_enable_emul(rtc, enabled); +#endif return err; } @@ -262,7 +278,7 @@ EXPORT_SYMBOL_GPL(rtc_update_irq_enable); * * Triggers the registered irq_task function callback. */ -static void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode) +void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode) { unsigned long flags; diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index dfa72c9c2687..d0e06edb14c5 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c @@ -76,7 +76,7 @@ static void rtc_uie_task(struct work_struct *work) } spin_unlock_irq(&rtc->irq_lock); if (num) - rtc_update_irq(rtc, num, RTC_UF | RTC_IRQF); + rtc_handle_legacy_irq(rtc, num, RTC_UF); } static void rtc_uie_timer(unsigned long data) { diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 80408e711bed..89c3e5182991 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -250,6 +250,7 @@ extern int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled); extern int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc, unsigned int enabled); +void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode); void rtc_aie_update_irq(void *private); void rtc_uie_update_irq(void *private); enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer); -- cgit v1.2.3 From 1cbb1a61d59b7552e1e3fde485d8af5699fe16e0 Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Thu, 17 Feb 2011 13:57:19 +0000 Subject: enic: Always use single transmit and single receive hardware queues per device We believe that our earlier patch for supporting multiple hardware receive queues per enic device requires more internal testing. At this point, we think that it's best to disable the use of multiple receive queues. The current patch provides an effective means for the same. Also, we continue to disallow multiple hardware transmit queues per device. But change the way we enforce this in order to maintain consistency with the way receive queues are handled. Signed-off-by: Christian Benvenuti Signed-off-by: Danny Guo Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 6 +++--- drivers/net/enic/enic_main.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 2ac891b58db3..aee5256e522b 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,13 +32,13 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "2.1.1.8" +#define DRV_VERSION "2.1.1.9" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 -#define ENIC_WQ_MAX 8 -#define ENIC_RQ_MAX 8 +#define ENIC_WQ_MAX 1 +#define ENIC_RQ_MAX 1 #define ENIC_CQ_MAX (ENIC_WQ_MAX + ENIC_RQ_MAX) #define ENIC_INTR_MAX (ENIC_CQ_MAX + 2) diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index d1aa80770541..4f1710e31eb4 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -2080,7 +2080,7 @@ static void enic_reset(struct work_struct *work) static int enic_set_intr_mode(struct enic *enic) { unsigned int n = min_t(unsigned int, enic->rq_count, ENIC_RQ_MAX); - unsigned int m = 1; + unsigned int m = min_t(unsigned int, enic->wq_count, ENIC_WQ_MAX); unsigned int i; /* Set interrupt mode (INTx, MSI, MSI-X) depending -- cgit v1.2.3 From d1ee433539ea5963a8f946f3428b335d1c5fdb20 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 14 Feb 2011 15:42:46 -0800 Subject: x86, trampoline: Use the unified trampoline setup for ACPI wakeup Use the unified trampoline allocation setup to allocate and install the ACPI wakeup code in low memory. Signed-off-by: H. Peter Anvin LKML-Reference: <4D5DFBE4.7090104@intel.com> Cc: Rafael J. Wysocki Cc: Matthieu Castet Cc: Stephen Rothwell --- arch/x86/include/asm/acpi.h | 4 +- arch/x86/include/asm/trampoline.h | 33 ++++++++++----- arch/x86/kernel/acpi/realmode/wakeup.S | 21 ++++++---- arch/x86/kernel/acpi/realmode/wakeup.h | 5 ++- arch/x86/kernel/acpi/realmode/wakeup.lds.S | 28 ++++++------- arch/x86/kernel/acpi/sleep.c | 65 ++++-------------------------- arch/x86/kernel/acpi/sleep.h | 3 -- arch/x86/kernel/acpi/wakeup_rm.S | 10 +++-- arch/x86/kernel/setup.c | 7 ---- drivers/acpi/sleep.c | 1 + 10 files changed, 69 insertions(+), 108 deletions(-) (limited to 'drivers') diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 211ca3f7fd16..4784df504d28 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -29,6 +29,7 @@ #include #include #include +#include #define COMPILER_DEPENDENT_INT64 long long #define COMPILER_DEPENDENT_UINT64 unsigned long long @@ -116,7 +117,8 @@ static inline void acpi_disable_pci(void) extern int acpi_save_state_mem(void); extern void acpi_restore_state_mem(void); -extern unsigned long acpi_wakeup_address; +extern const unsigned char acpi_wakeup_code[]; +#define acpi_wakeup_address (__pa(TRAMPOLINE_SYM(acpi_wakeup_code))) /* early initialization routine */ extern void acpi_reserve_wakeup_memory(void); diff --git a/arch/x86/include/asm/trampoline.h b/arch/x86/include/asm/trampoline.h index f4500fb3b485..feca3118a73b 100644 --- a/arch/x86/include/asm/trampoline.h +++ b/arch/x86/include/asm/trampoline.h @@ -3,25 +3,36 @@ #ifndef __ASSEMBLY__ -#ifdef CONFIG_X86_TRAMPOLINE +#include +#include + /* - * Trampoline 80x86 program as an array. + * Trampoline 80x86 program as an array. These are in the init rodata + * segment, but that's okay, because we only care about the relative + * addresses of the symbols. */ -extern const unsigned char trampoline_data []; -extern const unsigned char trampoline_end []; -extern unsigned char *trampoline_base; +extern const unsigned char x86_trampoline_start []; +extern const unsigned char x86_trampoline_end []; +extern unsigned char *x86_trampoline_base; extern unsigned long init_rsp; extern unsigned long initial_code; extern unsigned long initial_gs; -#define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE) +extern void __init setup_trampolines(void); + +extern const unsigned char trampoline_data[]; +extern const unsigned char trampoline_status[]; + +#define TRAMPOLINE_SYM(x) \ + ((void *)(x86_trampoline_base + \ + ((const unsigned char *)(x) - x86_trampoline_start))) -extern unsigned long setup_trampoline(void); -extern void __init reserve_trampoline_memory(void); -#else -static inline void reserve_trampoline_memory(void) {} -#endif /* CONFIG_X86_TRAMPOLINE */ +/* Address of the SMP trampoline */ +static inline unsigned long trampoline_address(void) +{ + return virt_to_phys(TRAMPOLINE_SYM(trampoline_data)); +} #endif /* __ASSEMBLY__ */ diff --git a/arch/x86/kernel/acpi/realmode/wakeup.S b/arch/x86/kernel/acpi/realmode/wakeup.S index 28595d6df47c..ead21b663117 100644 --- a/arch/x86/kernel/acpi/realmode/wakeup.S +++ b/arch/x86/kernel/acpi/realmode/wakeup.S @@ -6,11 +6,17 @@ #include #include #include +#include "wakeup.h" .code16 - .section ".header", "a" + .section ".jump", "ax" + .globl _start +_start: + cli + jmp wakeup_code /* This should match the structure in wakeup.h */ + .section ".header", "a" .globl wakeup_header wakeup_header: video_mode: .short 0 /* Video mode number */ @@ -30,14 +36,11 @@ wakeup_jmp: .byte 0xea /* ljmpw */ wakeup_jmp_off: .word 3f wakeup_jmp_seg: .word 0 wakeup_gdt: .quad 0, 0, 0 -signature: .long 0x51ee1111 +signature: .long WAKEUP_HEADER_SIGNATURE .text - .globl _start .code16 wakeup_code: -_start: - cli cld /* Apparently some dimwit BIOS programmers don't know how to @@ -77,12 +80,12 @@ _start: /* Check header signature... */ movl signature, %eax - cmpl $0x51ee1111, %eax + cmpl $WAKEUP_HEADER_SIGNATURE, %eax jne bogus_real_magic /* Check we really have everything... */ movl end_signature, %eax - cmpl $0x65a22c82, %eax + cmpl $WAKEUP_END_SIGNATURE, %eax jne bogus_real_magic /* Call the C code */ @@ -147,3 +150,7 @@ wakeup_heap: wakeup_stack: .space 2048 wakeup_stack_end: + + .section ".signature","a" +end_signature: + .long WAKEUP_END_SIGNATURE diff --git a/arch/x86/kernel/acpi/realmode/wakeup.h b/arch/x86/kernel/acpi/realmode/wakeup.h index 69d38d0b2b64..e1828c07e79c 100644 --- a/arch/x86/kernel/acpi/realmode/wakeup.h +++ b/arch/x86/kernel/acpi/realmode/wakeup.h @@ -35,7 +35,8 @@ struct wakeup_header { extern struct wakeup_header wakeup_header; #endif -#define HEADER_OFFSET 0x3f00 -#define WAKEUP_SIZE 0x4000 +#define WAKEUP_HEADER_OFFSET 8 +#define WAKEUP_HEADER_SIGNATURE 0x51ee1111 +#define WAKEUP_END_SIGNATURE 0x65a22c82 #endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */ diff --git a/arch/x86/kernel/acpi/realmode/wakeup.lds.S b/arch/x86/kernel/acpi/realmode/wakeup.lds.S index 060fff8f5c5b..d4f8010a5b1b 100644 --- a/arch/x86/kernel/acpi/realmode/wakeup.lds.S +++ b/arch/x86/kernel/acpi/realmode/wakeup.lds.S @@ -13,9 +13,19 @@ ENTRY(_start) SECTIONS { . = 0; + .jump : { + *(.jump) + } = 0x90909090 + + . = WAKEUP_HEADER_OFFSET; + .header : { + *(.header) + } + + . = ALIGN(16); .text : { *(.text*) - } + } = 0x90909090 . = ALIGN(16); .rodata : { @@ -33,11 +43,6 @@ SECTIONS *(.data*) } - .signature : { - end_signature = .; - LONG(0x65a22c82) - } - . = ALIGN(16); .bss : { __bss_start = .; @@ -45,20 +50,13 @@ SECTIONS __bss_end = .; } - . = HEADER_OFFSET; - .header : { - *(.header) + .signature : { + *(.signature) } - . = ALIGN(16); _end = .; /DISCARD/ : { *(.note*) } - - /* - * The ASSERT() sink to . is intentional, for binutils 2.14 compatibility: - */ - . = ASSERT(_end <= WAKEUP_SIZE, "Wakeup too big!"); } diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 68d1537b8c81..4572c58e66d5 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c @@ -18,12 +18,8 @@ #include "realmode/wakeup.h" #include "sleep.h" -unsigned long acpi_wakeup_address; unsigned long acpi_realmode_flags; -/* address in low memory of the wakeup routine. */ -static unsigned long acpi_realmode; - #if defined(CONFIG_SMP) && defined(CONFIG_64BIT) static char temp_stack[4096]; #endif @@ -33,22 +29,17 @@ static char temp_stack[4096]; * * Create an identity mapped page table and copy the wakeup routine to * low memory. - * - * Note that this is too late to change acpi_wakeup_address. */ int acpi_save_state_mem(void) { struct wakeup_header *header; + /* address in low memory of the wakeup routine. */ + char *acpi_realmode; - if (!acpi_realmode) { - printk(KERN_ERR "Could not allocate memory during boot, " - "S3 disabled\n"); - return -ENOMEM; - } - memcpy((void *)acpi_realmode, &wakeup_code_start, WAKEUP_SIZE); + acpi_realmode = TRAMPOLINE_SYM(acpi_wakeup_code); - header = (struct wakeup_header *)(acpi_realmode + HEADER_OFFSET); - if (header->signature != 0x51ee1111) { + header = (struct wakeup_header *)(acpi_realmode + WAKEUP_HEADER_OFFSET); + if (header->signature != WAKEUP_HEADER_SIGNATURE) { printk(KERN_ERR "wakeup header does not match\n"); return -EINVAL; } @@ -68,9 +59,7 @@ int acpi_save_state_mem(void) /* GDT[0]: GDT self-pointer */ header->wakeup_gdt[0] = (u64)(sizeof(header->wakeup_gdt) - 1) + - ((u64)(acpi_wakeup_address + - ((char *)&header->wakeup_gdt - (char *)acpi_realmode)) - << 16); + ((u64)__pa(&header->wakeup_gdt) << 16); /* GDT[1]: big real mode-like code segment */ header->wakeup_gdt[1] = GDT_ENTRY(0x809b, acpi_wakeup_address, 0xfffff); @@ -96,7 +85,7 @@ int acpi_save_state_mem(void) header->pmode_cr3 = (u32)__pa(&initial_page_table); saved_magic = 0x12345678; #else /* CONFIG_64BIT */ - header->trampoline_segment = setup_trampoline() >> 4; + header->trampoline_segment = trampoline_address() >> 4; #ifdef CONFIG_SMP stack_start = (unsigned long)temp_stack + sizeof(temp_stack); early_gdt_descr.address = @@ -117,46 +106,6 @@ void acpi_restore_state_mem(void) { } - -/** - * acpi_reserve_wakeup_memory - do _very_ early ACPI initialisation - * - * We allocate a page from the first 1MB of memory for the wakeup - * routine for when we come back from a sleep state. The - * runtime allocator allows specification of <16MB pages, but not - * <1MB pages. - */ -void __init acpi_reserve_wakeup_memory(void) -{ - phys_addr_t mem; - - if ((&wakeup_code_end - &wakeup_code_start) > WAKEUP_SIZE) { - printk(KERN_ERR - "ACPI: Wakeup code way too big, S3 disabled.\n"); - return; - } - - mem = memblock_find_in_range(0, 1<<20, WAKEUP_SIZE, PAGE_SIZE); - - if (mem == MEMBLOCK_ERROR) { - printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n"); - return; - } - acpi_realmode = (unsigned long) phys_to_virt(mem); - acpi_wakeup_address = mem; - memblock_x86_reserve_range(mem, mem + WAKEUP_SIZE, "ACPI WAKEUP"); -} - -int __init acpi_configure_wakeup_memory(void) -{ - if (acpi_realmode) - set_memory_x(acpi_realmode, WAKEUP_SIZE >> PAGE_SHIFT); - - return 0; -} -arch_initcall(acpi_configure_wakeup_memory); - - static int __init acpi_sleep_setup(char *str) { while ((str != NULL) && (*str != '\0')) { diff --git a/arch/x86/kernel/acpi/sleep.h b/arch/x86/kernel/acpi/sleep.h index adbcbaa6f1df..86ba1c87165b 100644 --- a/arch/x86/kernel/acpi/sleep.h +++ b/arch/x86/kernel/acpi/sleep.h @@ -4,13 +4,10 @@ #include -extern char wakeup_code_start, wakeup_code_end; - extern unsigned long saved_video_mode; extern long saved_magic; extern int wakeup_pmode_return; -extern char swsusp_pg_dir[PAGE_SIZE]; extern unsigned long acpi_copy_wakeup_routine(unsigned long); extern void wakeup_long64(void); diff --git a/arch/x86/kernel/acpi/wakeup_rm.S b/arch/x86/kernel/acpi/wakeup_rm.S index 6ff3b5730575..6ce81ee9cb03 100644 --- a/arch/x86/kernel/acpi/wakeup_rm.S +++ b/arch/x86/kernel/acpi/wakeup_rm.S @@ -2,9 +2,11 @@ * Wrapper script for the realmode binary as a transport object * before copying to low memory. */ - .section ".rodata","a" - .globl wakeup_code_start, wakeup_code_end -wakeup_code_start: +#include + + .section ".x86_trampoline","a" + .balign PAGE_SIZE + .globl acpi_wakeup_code +acpi_wakeup_code: .incbin "arch/x86/kernel/acpi/realmode/wakeup.bin" -wakeup_code_end: .size wakeup_code_start, .-wakeup_code_start diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 994ea20e177c..a089fc19ffae 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -937,13 +937,6 @@ void __init setup_arch(char **cmdline_p) setup_trampolines(); -#ifdef CONFIG_ACPI_SLEEP - /* - * Reserve low memory region for sleep support. - * even before init_memory_mapping - */ - acpi_reserve_wakeup_memory(); -#endif init_gbpages(); /* max_pfn_mapped is updated here */ diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index d6a8cd14de2e..e9fef94d1039 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -16,6 +16,7 @@ #include #include #include +#include #include -- cgit v1.2.3 From 070b8ed96e01adeb978d4f8487fb1350a28fcd0d Mon Sep 17 00:00:00 2001 From: Hema HK Date: Thu, 17 Feb 2011 12:06:08 +0530 Subject: usb: otg: TWL6030: Introduce the twl6030_phy_suspend function. Introduce the twl6030_phy_suspend function and assign to otg.set_suspend function pointer. This function is used by the musb-omap2430 platform driver during suspend/resume. Signed-off-by: Hema HK Cc: Tony Lindgren Cc: Paul Walmsley Signed-off-by: Felipe Balbi --- drivers/usb/otg/twl6030-usb.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c index 88989e61430c..b4eda02c97f7 100644 --- a/drivers/usb/otg/twl6030-usb.c +++ b/drivers/usb/otg/twl6030-usb.c @@ -177,6 +177,17 @@ static void twl6030_phy_shutdown(struct otg_transceiver *x) pdata->phy_power(twl->dev, 0, 0); } +static int twl6030_phy_suspend(struct otg_transceiver *x, int suspend) +{ + struct twl6030_usb *twl = xceiv_to_twl(x); + struct device *dev = twl->dev; + struct twl4030_usb_data *pdata = dev->platform_data; + + pdata->phy_suspend(dev, suspend); + + return 0; +} + static int twl6030_usb_ldo_init(struct twl6030_usb *twl) { @@ -388,6 +399,7 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) twl->otg.set_vbus = twl6030_set_vbus; twl->otg.init = twl6030_phy_init; twl->otg.shutdown = twl6030_phy_shutdown; + twl->otg.set_suspend = twl6030_phy_suspend; /* init spinlock for workqueue */ spin_lock_init(&twl->lock); @@ -432,6 +444,7 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) twl->asleep = 0; pdata->phy_init(dev); + twl6030_phy_suspend(&twl->otg, 0); twl6030_enable_irq(&twl->otg); dev_info(&pdev->dev, "Initialized TWL6030 USB module\n"); -- cgit v1.2.3 From 647b2d9c61fe9a842dd89eb01b5f01e9d437993c Mon Sep 17 00:00:00 2001 From: Hema HK Date: Thu, 17 Feb 2011 12:06:09 +0530 Subject: usb: otg: TWL6030 Save the last event in otg_transceiver Save the last event in the otg_transceiver so that it can used in the musb driver and gadget driver to configure the musb and enable the vbus for host mode and OTG mode, if the device is connected during boot. Signed-off-by: Hema HK Cc: Tony Lindgren Cc: Paul Walmsley Signed-off-by: Felipe Balbi --- drivers/usb/otg/twl6030-usb.c | 3 +++ include/linux/usb/otg.h | 1 + 2 files changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c index b4eda02c97f7..05f17b77d54c 100644 --- a/drivers/usb/otg/twl6030-usb.c +++ b/drivers/usb/otg/twl6030-usb.c @@ -262,11 +262,13 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl) twl->otg.default_a = false; twl->otg.state = OTG_STATE_B_IDLE; twl->linkstat = status; + twl->otg.last_event = status; blocking_notifier_call_chain(&twl->otg.notifier, status, twl->otg.gadget); } else { status = USB_EVENT_NONE; twl->linkstat = status; + twl->otg.last_event = status; blocking_notifier_call_chain(&twl->otg.notifier, status, twl->otg.gadget); if (twl->asleep) { @@ -299,6 +301,7 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) twl->otg.default_a = true; twl->otg.state = OTG_STATE_A_IDLE; twl->linkstat = status; + twl->otg.last_event = status; blocking_notifier_call_chain(&twl->otg.notifier, status, twl->otg.gadget); } else { diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index a1a1e7a73ec9..da511eec3cb8 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -66,6 +66,7 @@ struct otg_transceiver { u8 default_a; enum usb_otg_state state; + enum usb_xceiv_events last_event; struct usb_bus *host; struct usb_gadget *gadget; -- cgit v1.2.3 From 002eda1348788f623dc42231dcda5f591d753124 Mon Sep 17 00:00:00 2001 From: Hema HK Date: Thu, 17 Feb 2011 12:06:10 +0530 Subject: usb: musb: OMAP4430: Fix usb device detection if connected during boot OMAP4430 is embedded with UTMI PHY. This PHY does not support the OTG features like ID pin detection and VBUS detection. This function is exported to an external companion chip TWL6030. Software must retrieve the OTG HNP and SRP status from the TWL6030 and configure the bits inside the control module that drive the related USBOTGHS UTMI interface signals. It must also read back the UTMI signals needed to configure the TWL6030 OTG module. Can find more details in the TRM[1]. [1]:http://focus.ti.com/pdfs/wtbu/OMAP4430_ES2.0_Public_TRM_vJ.pdf In OMAP4430 musb driver VBUS and ID notifications are received from the transceiver driver. If the cable/device is connected during boot, notifications from transceiver driver will be missed till musb driver is loaded. Patch to configure the transceiver in the platform_enable/disable functions and enable the vbus in the gadget driver based on the last_event of the otg_transceiver. Signed-off-by: Hema HK Cc: Tony Lindgren Cc: Paul Walmsley Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 4 ++++ drivers/usb/musb/omap2430.c | 53 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 0f59bf935c85..95fbaccb03e1 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1877,6 +1877,10 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, if (retval < 0) { DBG(1, "add_hcd failed, %d\n", retval); goto err2; + + if ((musb->xceiv->last_event == USB_EVENT_ID) + && musb->xceiv->set_vbus) + otg_set_vbus(musb->xceiv, 1); } hcd->self.uses_pio_for_control = 1; diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index bb6e6cd330da..64cf2431c05e 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -328,16 +328,56 @@ static int omap2430_musb_init(struct musb *musb) if (status) DBG(1, "notification register failed\n"); - /* check whether cable is already connected */ - if (musb->xceiv->state ==OTG_STATE_B_IDLE) - musb_otg_notifications(&musb->nb, 1, - musb->xceiv->gadget); - setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); return 0; } +static void omap2430_musb_enable(struct musb *musb) +{ + u8 devctl; + unsigned long timeout = jiffies + msecs_to_jiffies(1000); + struct device *dev = musb->controller; + struct musb_hdrc_platform_data *pdata = dev->platform_data; + struct omap_musb_board_data *data = pdata->board_data; + + switch (musb->xceiv->last_event) { + + case USB_EVENT_ID: + otg_init(musb->xceiv); + if (data->interface_type == MUSB_INTERFACE_UTMI) { + devctl = musb_readb(musb->mregs, MUSB_DEVCTL); + /* start the session */ + devctl |= MUSB_DEVCTL_SESSION; + musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); + while (musb_readb(musb->mregs, MUSB_DEVCTL) & + MUSB_DEVCTL_BDEVICE) { + cpu_relax(); + + if (time_after(jiffies, timeout)) { + dev_err(musb->controller, + "configured as A device timeout"); + break; + } + } + } + break; + + case USB_EVENT_VBUS: + otg_init(musb->xceiv); + break; + + default: + break; + } +} + +static void omap2430_musb_disable(struct musb *musb) +{ + if (musb->xceiv->last_event) + otg_shutdown(musb->xceiv); +} + static int omap2430_musb_exit(struct musb *musb) { @@ -355,6 +395,9 @@ static const struct musb_platform_ops omap2430_ops = { .try_idle = omap2430_musb_try_idle, .set_vbus = omap2430_musb_set_vbus, + + .enable = omap2430_musb_enable, + .disable = omap2430_musb_disable, }; static u64 omap2430_dmamask = DMA_BIT_MASK(32); -- cgit v1.2.3 From cccad6d4b103e53fb3d1fc1467f654ecb572d047 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 29 Sep 2010 10:55:49 +0300 Subject: usb: otg: notifier: switch to atomic notifier most of our notifications, will be called from IRQ context, so an atomic notifier suits the job better. Signed-off-by: Felipe Balbi --- drivers/usb/otg/ab8500-usb.c | 6 +++--- drivers/usb/otg/nop-usb-xceiv.c | 2 +- drivers/usb/otg/twl4030-usb.c | 6 +++--- drivers/usb/otg/twl6030-usb.c | 8 ++++---- include/linux/usb/otg.h | 6 +++--- 5 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c index d14736b3107b..07ccea9ada40 100644 --- a/drivers/usb/otg/ab8500-usb.c +++ b/drivers/usb/otg/ab8500-usb.c @@ -212,7 +212,7 @@ static int ab8500_usb_link_status_update(struct ab8500_usb *ab) break; } - blocking_notifier_call_chain(&ab->otg.notifier, event, v); + atomic_notifier_call_chain(&ab->otg.notifier, event, v); return 0; } @@ -281,7 +281,7 @@ static int ab8500_usb_set_power(struct otg_transceiver *otg, unsigned mA) ab->vbus_draw = mA; if (mA) - blocking_notifier_call_chain(&ab->otg.notifier, + atomic_notifier_call_chain(&ab->otg.notifier, USB_EVENT_ENUMERATED, ab->otg.gadget); return 0; } @@ -500,7 +500,7 @@ static int __devinit ab8500_usb_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ab); - BLOCKING_INIT_NOTIFIER_HEAD(&ab->otg.notifier); + ATOMIC_INIT_NOTIFIER_HEAD(&ab->otg.notifier); /* v1: Wait for link status to become stable. * all: Updates form set_host and set_peripheral as they are atomic. diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index 8acf165fe13b..c1e360046435 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c @@ -132,7 +132,7 @@ static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev) platform_set_drvdata(pdev, nop); - BLOCKING_INIT_NOTIFIER_HEAD(&nop->otg.notifier); + ATOMIC_INIT_NOTIFIER_HEAD(&nop->otg.notifier); return 0; exit: diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 6ca505f333e4..2362d8352bc8 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c @@ -512,7 +512,7 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) else twl4030_phy_resume(twl); - blocking_notifier_call_chain(&twl->otg.notifier, status, + atomic_notifier_call_chain(&twl->otg.notifier, status, twl->otg.gadget); } sysfs_notify(&twl->dev->kobj, NULL, "vbus"); @@ -534,7 +534,7 @@ static void twl4030_usb_phy_init(struct twl4030_usb *twl) twl->asleep = 0; } - blocking_notifier_call_chain(&twl->otg.notifier, status, + atomic_notifier_call_chain(&twl->otg.notifier, status, twl->otg.gadget); } sysfs_notify(&twl->dev->kobj, NULL, "vbus"); @@ -623,7 +623,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) if (device_create_file(&pdev->dev, &dev_attr_vbus)) dev_warn(&pdev->dev, "could not create sysfs file\n"); - BLOCKING_INIT_NOTIFIER_HEAD(&twl->otg.notifier); + ATOMIC_INIT_NOTIFIER_HEAD(&twl->otg.notifier); /* Our job is to use irqs and status from the power module * to keep the transceiver disabled when nothing's connected. diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c index 05f17b77d54c..8a91b4b832a1 100644 --- a/drivers/usb/otg/twl6030-usb.c +++ b/drivers/usb/otg/twl6030-usb.c @@ -263,13 +263,13 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl) twl->otg.state = OTG_STATE_B_IDLE; twl->linkstat = status; twl->otg.last_event = status; - blocking_notifier_call_chain(&twl->otg.notifier, + atomic_notifier_call_chain(&twl->otg.notifier, status, twl->otg.gadget); } else { status = USB_EVENT_NONE; twl->linkstat = status; twl->otg.last_event = status; - blocking_notifier_call_chain(&twl->otg.notifier, + atomic_notifier_call_chain(&twl->otg.notifier, status, twl->otg.gadget); if (twl->asleep) { regulator_disable(twl->usb3v3); @@ -302,7 +302,7 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) twl->otg.state = OTG_STATE_A_IDLE; twl->linkstat = status; twl->otg.last_event = status; - blocking_notifier_call_chain(&twl->otg.notifier, status, + atomic_notifier_call_chain(&twl->otg.notifier, status, twl->otg.gadget); } else { twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_CLR, @@ -419,7 +419,7 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) if (device_create_file(&pdev->dev, &dev_attr_vbus)) dev_warn(&pdev->dev, "could not create sysfs file\n"); - BLOCKING_INIT_NOTIFIER_HEAD(&twl->otg.notifier); + ATOMIC_INIT_NOTIFIER_HEAD(&twl->otg.notifier); twl->irq_enabled = true; status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq, diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index da511eec3cb8..6e40718f5abe 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -75,7 +75,7 @@ struct otg_transceiver { void __iomem *io_priv; /* for notification of usb_xceiv_events */ - struct blocking_notifier_head notifier; + struct atomic_notifier_head notifier; /* to pass extra port status to the root hub */ u16 port_status; @@ -235,13 +235,13 @@ otg_start_srp(struct otg_transceiver *otg) static inline int otg_register_notifier(struct otg_transceiver *otg, struct notifier_block *nb) { - return blocking_notifier_chain_register(&otg->notifier, nb); + return atomic_notifier_chain_register(&otg->notifier, nb); } static inline void otg_unregister_notifier(struct otg_transceiver *otg, struct notifier_block *nb) { - blocking_notifier_chain_unregister(&otg->notifier, nb); + atomic_notifier_chain_unregister(&otg->notifier, nb); } /* for OTG controller drivers (and maybe other stuff) */ -- cgit v1.2.3 From aa4790a6287818078ca968164a5f0d0870326602 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 17 Feb 2011 03:22:40 -0500 Subject: hwmon: (k10temp) add support for AMD Family 12h/14h CPUs Add the PCI ID to support the internal temperature sensor of the AMD "Llano" and "Brazos" processor families. Signed-off-by: Clemens Ladisch Cc: stable@kernel.org # ca86828: x86, AMD, PCI: Add AMD northbridge PCI device Cc: stable@kernel.org Signed-off-by: Guenter Roeck --- Documentation/hwmon/k10temp | 8 +++++++- drivers/hwmon/Kconfig | 6 +++--- drivers/hwmon/k10temp.c | 5 +++-- 3 files changed, 13 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/Documentation/hwmon/k10temp b/Documentation/hwmon/k10temp index 6526eee525a6..d2b56a4fd1f5 100644 --- a/Documentation/hwmon/k10temp +++ b/Documentation/hwmon/k10temp @@ -9,6 +9,8 @@ Supported chips: Socket S1G3: Athlon II, Sempron, Turion II * AMD Family 11h processors: Socket S1G2: Athlon (X2), Sempron (X2), Turion X2 (Ultra) +* AMD Family 12h processors: "Llano" +* AMD Family 14h processors: "Brazos" (C/E/G-Series) Prefix: 'k10temp' Addresses scanned: PCI space @@ -17,10 +19,14 @@ Supported chips: http://support.amd.com/us/Processor_TechDocs/31116.pdf BIOS and Kernel Developer's Guide (BKDG) for AMD Family 11h Processors: http://support.amd.com/us/Processor_TechDocs/41256.pdf + BIOS and Kernel Developer's Guide (BKDG) for AMD Family 14h Models 00h-0Fh Processors: + http://support.amd.com/us/Processor_TechDocs/43170.pdf Revision Guide for AMD Family 10h Processors: http://support.amd.com/us/Processor_TechDocs/41322.pdf Revision Guide for AMD Family 11h Processors: http://support.amd.com/us/Processor_TechDocs/41788.pdf + Revision Guide for AMD Family 14h Models 00h-0Fh Processors: + http://support.amd.com/us/Processor_TechDocs/47534.pdf AMD Family 11h Processor Power and Thermal Data Sheet for Notebooks: http://support.amd.com/us/Processor_TechDocs/43373.pdf AMD Family 10h Server and Workstation Processor Power and Thermal Data Sheet: @@ -34,7 +40,7 @@ Description ----------- This driver permits reading of the internal temperature sensor of AMD -Family 10h and 11h processors. +Family 10h/11h/12h/14h processors. All these processors have a sensor, but on those for Socket F or AM2+, the sensor may return inconsistent values (erratum 319). The driver diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 412339451a32..5eadb007e542 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -238,13 +238,13 @@ config SENSORS_K8TEMP will be called k8temp. config SENSORS_K10TEMP - tristate "AMD Phenom/Sempron/Turion/Opteron temperature sensor" + tristate "AMD Family 10h/11h/12h/14h temperature sensor" depends on X86 && PCI help If you say yes here you get support for the temperature sensor(s) inside your CPU. Supported are later revisions of - the AMD Family 10h and all revisions of the AMD Family 11h - microarchitectures. + the AMD Family 10h and all revisions of the AMD Family 11h, + 12h (Llano), and 14h (Brazos) microarchitectures. This driver can also be built as a module. If so, the module will be called k10temp. diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index da5a2404cd3e..82bf65aa2968 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c @@ -1,5 +1,5 @@ /* - * k10temp.c - AMD Family 10h/11h processor hardware monitoring + * k10temp.c - AMD Family 10h/11h/12h/14h processor hardware monitoring * * Copyright (c) 2009 Clemens Ladisch * @@ -25,7 +25,7 @@ #include #include -MODULE_DESCRIPTION("AMD Family 10h/11h CPU core temperature monitor"); +MODULE_DESCRIPTION("AMD Family 10h/11h/12h/14h CPU core temperature monitor"); MODULE_AUTHOR("Clemens Ladisch "); MODULE_LICENSE("GPL"); @@ -208,6 +208,7 @@ static void __devexit k10temp_remove(struct pci_dev *pdev) static const struct pci_device_id k10temp_id_table[] = { { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_11H_NB_MISC) }, + { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) }, {} }; MODULE_DEVICE_TABLE(pci, k10temp_id_table); -- cgit v1.2.3 From 1d4610527bc71d3f9eea520fc51a02d54f79dcd0 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 16 Feb 2011 13:43:22 -0500 Subject: xen-pcifront: Sanity check the MSI/MSI-X values Check the returned vector values for any values that are odd or plain incorrect (say vector value zero), and if so print a warning. Also fixup the return values. This patch was precipiated by the Xen PCIBack returning the incorrect values due to how it was retrieving PIRQ values. This has been fixed in the xen-pciback by "xen/pciback: Utilize 'xen_pirq_from_irq' to get PIRQ value" patch. Reviewed-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- drivers/pci/xen-pcifront.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index 030ce3743439..5c7b6ad68056 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c @@ -277,18 +277,24 @@ static int pci_frontend_enable_msix(struct pci_dev *dev, if (likely(!err)) { if (likely(!op.value)) { /* we get the result */ - for (i = 0; i < nvec; i++) + for (i = 0; i < nvec; i++) { + if (op.msix_entries[i].vector <= 0) { + dev_warn(&dev->dev, "MSI-X entry %d is invalid: %d!\n", + i, op.msix_entries[i].vector); + err = -EINVAL; + *(*vector+i) = -1; + continue; + } *(*vector+i) = op.msix_entries[i].vector; - return 0; + } } else { printk(KERN_DEBUG "enable msix get value %x\n", op.value); - return op.value; } } else { dev_err(&dev->dev, "enable msix get err %x\n", err); - return err; } + return err; } static void pci_frontend_disable_msix(struct pci_dev *dev) @@ -325,6 +331,12 @@ static int pci_frontend_enable_msi(struct pci_dev *dev, int **vector) err = do_pci_op(pdev, &op); if (likely(!err)) { *(*vector) = op.value; + if (op.value <= 0) { + dev_warn(&dev->dev, "MSI entry is invalid: %d!\n", + op.value); + err = -EINVAL; + *(*vector) = -1; + } } else { dev_err(&dev->dev, "pci frontend enable msi failed for dev " "%x:%x\n", op.bus, op.devfn); -- cgit v1.2.3 From 4e8b65f606b9e4e6922fd17a772fe3e69cc5553b Mon Sep 17 00:00:00 2001 From: Rakesh Iyer Date: Fri, 18 Feb 2011 08:38:02 -0800 Subject: Input: tegra-kbc - add function keymap Add Fn keymap support to allow for internal processing of Fn keys. Signed-off-by: Rakesh Iyer Signed-off-by: Dmitry Torokhov --- arch/arm/mach-tegra/include/mach/kbc.h | 1 + drivers/input/keyboard/tegra-kbc.c | 62 ++++++++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-tegra/include/mach/kbc.h b/arch/arm/mach-tegra/include/mach/kbc.h index 66ad2760c621..04c779832c78 100644 --- a/arch/arm/mach-tegra/include/mach/kbc.h +++ b/arch/arm/mach-tegra/include/mach/kbc.h @@ -57,5 +57,6 @@ struct tegra_kbc_platform_data { const struct matrix_keymap_data *keymap_data; bool wakeup; + bool use_fn_map; }; #endif diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index ac471b77c18e..99ce9032d08c 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c @@ -71,8 +71,9 @@ struct tegra_kbc { spinlock_t lock; unsigned int repoll_dly; unsigned long cp_dly_jiffies; + bool use_fn_map; const struct tegra_kbc_platform_data *pdata; - unsigned short keycode[KBC_MAX_KEY]; + unsigned short keycode[KBC_MAX_KEY * 2]; unsigned short current_keys[KBC_MAX_KPENT]; unsigned int num_pressed_keys; struct timer_list timer; @@ -178,6 +179,40 @@ static const u32 tegra_kbc_default_keymap[] = { KEY(15, 5, KEY_F2), KEY(15, 6, KEY_CAPSLOCK), KEY(15, 7, KEY_F6), + + /* Software Handled Function Keys */ + KEY(20, 0, KEY_KP7), + + KEY(21, 0, KEY_KP9), + KEY(21, 1, KEY_KP8), + KEY(21, 2, KEY_KP4), + KEY(21, 4, KEY_KP1), + + KEY(22, 1, KEY_KPSLASH), + KEY(22, 2, KEY_KP6), + KEY(22, 3, KEY_KP5), + KEY(22, 4, KEY_KP3), + KEY(22, 5, KEY_KP2), + KEY(22, 7, KEY_KP0), + + KEY(27, 1, KEY_KPASTERISK), + KEY(27, 3, KEY_KPMINUS), + KEY(27, 4, KEY_KPPLUS), + KEY(27, 5, KEY_KPDOT), + + KEY(28, 5, KEY_VOLUMEUP), + + KEY(29, 3, KEY_HOME), + KEY(29, 4, KEY_END), + KEY(29, 5, KEY_BRIGHTNESSDOWN), + KEY(29, 6, KEY_VOLUMEDOWN), + KEY(29, 7, KEY_BRIGHTNESSUP), + + KEY(30, 0, KEY_NUMLOCK), + KEY(30, 1, KEY_SCROLLLOCK), + KEY(30, 2, KEY_MUTE), + + KEY(31, 4, KEY_HELP), }; static const struct matrix_keymap_data tegra_kbc_default_keymap_data = { @@ -224,6 +259,7 @@ static void tegra_kbc_report_keys(struct tegra_kbc *kbc) unsigned int i; unsigned int num_down = 0; unsigned long flags; + bool fn_keypress = false; spin_lock_irqsave(&kbc->lock, flags); for (i = 0; i < KBC_MAX_KPENT; i++) { @@ -237,11 +273,28 @@ static void tegra_kbc_report_keys(struct tegra_kbc *kbc) MATRIX_SCAN_CODE(row, col, KBC_ROW_SHIFT); scancodes[num_down] = scancode; - keycodes[num_down++] = kbc->keycode[scancode]; + keycodes[num_down] = kbc->keycode[scancode]; + /* If driver uses Fn map, do not report the Fn key. */ + if ((keycodes[num_down] == KEY_FN) && kbc->use_fn_map) + fn_keypress = true; + else + num_down++; } val >>= 8; } + + /* + * If the platform uses Fn keymaps, translate keys on a Fn keypress. + * Function keycodes are KBC_MAX_KEY apart from the plain keycodes. + */ + if (fn_keypress) { + for (i = 0; i < num_down; i++) { + scancodes[i] += KBC_MAX_KEY; + keycodes[i] = kbc->keycode[scancodes[i]]; + } + } + spin_unlock_irqrestore(&kbc->lock, flags); tegra_kbc_report_released_keys(kbc->idev, @@ -594,8 +647,11 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev) input_dev->keycode = kbc->keycode; input_dev->keycodesize = sizeof(kbc->keycode[0]); - input_dev->keycodemax = ARRAY_SIZE(kbc->keycode); + input_dev->keycodemax = KBC_MAX_KEY; + if (pdata->use_fn_map) + input_dev->keycodemax *= 2; + kbc->use_fn_map = pdata->use_fn_map; keymap_data = pdata->keymap_data ?: &tegra_kbc_default_keymap_data; matrix_keypad_build_keymap(keymap_data, KBC_ROW_SHIFT, input_dev->keycode, input_dev->keybit); -- cgit v1.2.3 From cc0f89c4a426fcd6400a89e9e34e4a8851abef76 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Thu, 17 Feb 2011 12:02:23 -0500 Subject: pci/xen: Cleanup: convert int** to int[] Cleanup code. Cosmetic change to make the code look easier to read. Reviewed-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/include/asm/xen/pci.h | 8 ++++---- arch/x86/pci/xen.c | 4 ++-- drivers/pci/xen-pcifront.c | 12 ++++++------ 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/arch/x86/include/asm/xen/pci.h b/arch/x86/include/asm/xen/pci.h index 2329b3eaf8d3..aa8620989162 100644 --- a/arch/x86/include/asm/xen/pci.h +++ b/arch/x86/include/asm/xen/pci.h @@ -27,16 +27,16 @@ static inline void __init xen_setup_pirqs(void) * its own functions. */ struct xen_pci_frontend_ops { - int (*enable_msi)(struct pci_dev *dev, int **vectors); + int (*enable_msi)(struct pci_dev *dev, int vectors[]); void (*disable_msi)(struct pci_dev *dev); - int (*enable_msix)(struct pci_dev *dev, int **vectors, int nvec); + int (*enable_msix)(struct pci_dev *dev, int vectors[], int nvec); void (*disable_msix)(struct pci_dev *dev); }; extern struct xen_pci_frontend_ops *xen_pci_frontend; static inline int xen_pci_frontend_enable_msi(struct pci_dev *dev, - int **vectors) + int vectors[]) { if (xen_pci_frontend && xen_pci_frontend->enable_msi) return xen_pci_frontend->enable_msi(dev, vectors); @@ -48,7 +48,7 @@ static inline void xen_pci_frontend_disable_msi(struct pci_dev *dev) xen_pci_frontend->disable_msi(dev); } static inline int xen_pci_frontend_enable_msix(struct pci_dev *dev, - int **vectors, int nvec) + int vectors[], int nvec) { if (xen_pci_frontend && xen_pci_frontend->enable_msix) return xen_pci_frontend->enable_msix(dev, vectors, nvec); diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 6432f751ee4f..30fdd09dea05 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -150,9 +150,9 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) return -ENOMEM; if (type == PCI_CAP_ID_MSIX) - ret = xen_pci_frontend_enable_msix(dev, &v, nvec); + ret = xen_pci_frontend_enable_msix(dev, v, nvec); else - ret = xen_pci_frontend_enable_msi(dev, &v); + ret = xen_pci_frontend_enable_msi(dev, v); if (ret) goto error; i = 0; diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index 5c7b6ad68056..492b7d807fe8 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c @@ -243,7 +243,7 @@ struct pci_ops pcifront_bus_ops = { #ifdef CONFIG_PCI_MSI static int pci_frontend_enable_msix(struct pci_dev *dev, - int **vector, int nvec) + int vector[], int nvec) { int err; int i; @@ -282,10 +282,10 @@ static int pci_frontend_enable_msix(struct pci_dev *dev, dev_warn(&dev->dev, "MSI-X entry %d is invalid: %d!\n", i, op.msix_entries[i].vector); err = -EINVAL; - *(*vector+i) = -1; + vector[i] = -1; continue; } - *(*vector+i) = op.msix_entries[i].vector; + vector[i] = op.msix_entries[i].vector; } } else { printk(KERN_DEBUG "enable msix get value %x\n", @@ -316,7 +316,7 @@ static void pci_frontend_disable_msix(struct pci_dev *dev) dev_err(&dev->dev, "pci_disable_msix get err %x\n", err); } -static int pci_frontend_enable_msi(struct pci_dev *dev, int **vector) +static int pci_frontend_enable_msi(struct pci_dev *dev, int vector[]) { int err; struct xen_pci_op op = { @@ -330,12 +330,12 @@ static int pci_frontend_enable_msi(struct pci_dev *dev, int **vector) err = do_pci_op(pdev, &op); if (likely(!err)) { - *(*vector) = op.value; + vector[0] = op.value; if (op.value <= 0) { dev_warn(&dev->dev, "MSI entry is invalid: %d!\n", op.value); err = -EINVAL; - *(*vector) = -1; + vector[0] = -1; } } else { dev_err(&dev->dev, "pci frontend enable msi failed for dev " -- cgit v1.2.3 From 7eb90a3682fc42c5607cff931e5d0f6a9d52dc03 Mon Sep 17 00:00:00 2001 From: wwang Date: Wed, 16 Feb 2011 15:56:10 +0800 Subject: staging: rts_pstor: delete a function Delete a function named rtsx_transfer_sglist which won't be called. Signed-off-by: wwang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts_pstor/rtsx_transport.c | 136 ----------------------------- 1 file changed, 136 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rts_pstor/rtsx_transport.c b/drivers/staging/rts_pstor/rtsx_transport.c index e581f15147f2..3b160dcb98b7 100644 --- a/drivers/staging/rts_pstor/rtsx_transport.c +++ b/drivers/staging/rts_pstor/rtsx_transport.c @@ -715,142 +715,6 @@ out: return err; } -int rtsx_transfer_sglist(struct rtsx_chip *chip, u8 card, - struct scatterlist *sg, int num_sg, - enum dma_data_direction dma_dir, int timeout) -{ - struct rtsx_dev *rtsx = chip->rtsx; - struct completion trans_done; - u8 dir; - int buf_cnt, i; - int err = 0; - long timeleft; - - if ((sg == NULL) || (num_sg <= 0)) - return -EIO; - - if (dma_dir == DMA_TO_DEVICE) { - dir = HOST_TO_DEVICE; - } else if (dma_dir == DMA_FROM_DEVICE) { - dir = DEVICE_TO_HOST; - } else { - return -ENXIO; - } - - if (card == SD_CARD) { - rtsx->check_card_cd = SD_EXIST; - } else if (card == MS_CARD) { - rtsx->check_card_cd = MS_EXIST; - } else if (card == XD_CARD) { - rtsx->check_card_cd = XD_EXIST; - } else { - rtsx->check_card_cd = 0; - } - - spin_lock_irq(&rtsx->reg_lock); - - /* set up data structures for the wakeup system */ - rtsx->done = &trans_done; - - rtsx->trans_state = STATE_TRANS_SG; - rtsx->trans_result = TRANS_NOT_READY; - - spin_unlock_irq(&rtsx->reg_lock); - - buf_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); - - for (i = 0; i < buf_cnt; i++) { - u32 bier = 0; - u32 val = (1 << 31); - dma_addr_t addr = sg_dma_address(sg + i); - unsigned int len = sg_dma_len(sg + i); - - RTSX_DEBUGP("dma_addr = 0x%x, dma_len = %d\n", - (unsigned int)addr, len); - - val |= (u32)(dir & 0x01) << 29; - val |= (u32)(len & 0x00FFFFFF); - - spin_lock_irq(&rtsx->reg_lock); - - init_completion(&trans_done); - - if (i == (buf_cnt - 1)) { - /* If last transfer, disable data interrupt */ - bier = rtsx_readl(chip, RTSX_BIER); - rtsx_writel(chip, RTSX_BIER, bier & 0xBFFFFFFF); - } - - rtsx_writel(chip, RTSX_HDBAR, addr); - rtsx_writel(chip, RTSX_HDBCTLR, val); - - spin_unlock_irq(&rtsx->reg_lock); - - timeleft = wait_for_completion_interruptible_timeout( - &trans_done, timeout * HZ / 1000); - if (timeleft <= 0) { - RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__); - RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); - err = -ETIMEDOUT; - if (i == (buf_cnt - 1)) - rtsx_writel(chip, RTSX_BIER, bier); - goto out; - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) { - err = -EIO; - spin_unlock_irq(&rtsx->reg_lock); - if (i == (buf_cnt - 1)) - rtsx_writel(chip, RTSX_BIER, bier); - goto out; - } - spin_unlock_irq(&rtsx->reg_lock); - - if (i == (buf_cnt - 1)) { - /* If last transfer, enable data interrupt - * after transfer finished - */ - rtsx_writel(chip, RTSX_BIER, bier); - } - } - - /* Wait for TRANS_OK_INT */ - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_NOT_READY) { - init_completion(&trans_done); - spin_unlock_irq(&rtsx->reg_lock); - timeleft = wait_for_completion_interruptible_timeout( - &trans_done, timeout * HZ / 1000); - if (timeleft <= 0) { - RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__); - RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); - err = -ETIMEDOUT; - goto out; - } - } else { - spin_unlock_irq(&rtsx->reg_lock); - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) { - err = -EIO; - } else if (rtsx->trans_result == TRANS_RESULT_OK) { - err = 0; - } - spin_unlock_irq(&rtsx->reg_lock); - -out: - rtsx->done = NULL; - rtsx->trans_state = STATE_TRANS_NONE; - dma_unmap_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); - - if (err < 0) - rtsx_stop_cmd(chip, card); - - return err; -} - int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card, void *buf, size_t len, int use_sg, unsigned int *index, unsigned int *offset, enum dma_data_direction dma_dir, -- cgit v1.2.3 From 6680d2cab316a0c0e4cea0727e6d63426a77bb12 Mon Sep 17 00:00:00 2001 From: wwang Date: Wed, 16 Feb 2011 15:56:11 +0800 Subject: staging: rts_pstor: fix sparse warning Add static modifier before some functions and global variables. Signed-off-by: wwang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts_pstor/ms.c | 2 +- drivers/staging/rts_pstor/rtsx.c | 4 +-- drivers/staging/rts_pstor/rtsx_card.c | 2 +- drivers/staging/rts_pstor/rtsx_chip.c | 8 ++--- drivers/staging/rts_pstor/rtsx_scsi.c | 8 ++--- drivers/staging/rts_pstor/rtsx_transport.c | 6 ++-- drivers/staging/rts_pstor/sd.c | 48 +++++++++++++++--------------- drivers/staging/rts_pstor/spi.c | 2 +- 8 files changed, 40 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rts_pstor/ms.c b/drivers/staging/rts_pstor/ms.c index a624f40fd914..c43f9118dca9 100644 --- a/drivers/staging/rts_pstor/ms.c +++ b/drivers/staging/rts_pstor/ms.c @@ -3594,7 +3594,7 @@ void ms_free_l2p_tbl(struct rtsx_chip *chip) #ifdef SUPPORT_MAGIC_GATE #ifdef READ_BYTES_WAIT_INT -int ms_poll_int(struct rtsx_chip *chip) +static int ms_poll_int(struct rtsx_chip *chip) { int retval; u8 val; diff --git a/drivers/staging/rts_pstor/rtsx.c b/drivers/staging/rts_pstor/rtsx.c index 2b1837999d7d..c3f33d1de465 100644 --- a/drivers/staging/rts_pstor/rtsx.c +++ b/drivers/staging/rts_pstor/rtsx.c @@ -257,7 +257,7 @@ static int bus_reset(struct scsi_cmnd *srb) * this defines our host template, with which we'll allocate hosts */ -struct scsi_host_template rtsx_host_template = { +static struct scsi_host_template rtsx_host_template = { /* basic userland interface stuff */ .name = CR_DRIVER_NAME, .proc_name = CR_DRIVER_NAME, @@ -436,7 +436,7 @@ static int rtsx_resume(struct pci_dev *pci) } #endif /* CONFIG_PM */ -void rtsx_shutdown(struct pci_dev *pci) +static void rtsx_shutdown(struct pci_dev *pci) { struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); struct rtsx_chip *chip; diff --git a/drivers/staging/rts_pstor/rtsx_card.c b/drivers/staging/rts_pstor/rtsx_card.c index fe4cce0cce29..4f971f2e930a 100644 --- a/drivers/staging/rts_pstor/rtsx_card.c +++ b/drivers/staging/rts_pstor/rtsx_card.c @@ -300,7 +300,7 @@ void do_reset_ms_card(struct rtsx_chip *chip) } } -void release_sdio(struct rtsx_chip *chip) +static void release_sdio(struct rtsx_chip *chip) { if (chip->sd_io) { rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, diff --git a/drivers/staging/rts_pstor/rtsx_chip.c b/drivers/staging/rts_pstor/rtsx_chip.c index a4d8eb2abd53..f443d97a56f8 100644 --- a/drivers/staging/rts_pstor/rtsx_chip.c +++ b/drivers/staging/rts_pstor/rtsx_chip.c @@ -657,7 +657,7 @@ static inline int check_sd_current_prior(u32 sd_current_prior) return !fake_para; } -int rts5209_init(struct rtsx_chip *chip) +static int rts5209_init(struct rtsx_chip *chip) { int retval; u32 lval = 0; @@ -805,7 +805,7 @@ int rts5209_init(struct rtsx_chip *chip) return STATUS_SUCCESS; } -int rts5208_init(struct rtsx_chip *chip) +static int rts5208_init(struct rtsx_chip *chip) { int retval; u16 reg = 0; @@ -871,7 +871,7 @@ int rts5208_init(struct rtsx_chip *chip) return STATUS_SUCCESS; } -int rts5288_init(struct rtsx_chip *chip) +static int rts5288_init(struct rtsx_chip *chip) { int retval; u8 val = 0, max_func; @@ -1097,7 +1097,7 @@ static inline void rtsx_blink_led(struct rtsx_chip *chip) } #endif -void rtsx_monitor_aspm_config(struct rtsx_chip *chip) +static void rtsx_monitor_aspm_config(struct rtsx_chip *chip) { int maybe_support_aspm, reg_changed; u32 tmp = 0; diff --git a/drivers/staging/rts_pstor/rtsx_scsi.c b/drivers/staging/rts_pstor/rtsx_scsi.c index ce9fc162d6e0..20c2464a20f9 100644 --- a/drivers/staging/rts_pstor/rtsx_scsi.c +++ b/drivers/staging/rts_pstor/rtsx_scsi.c @@ -274,7 +274,7 @@ static int test_unit_ready(struct scsi_cmnd *srb, struct rtsx_chip *chip) return TRANSPORT_GOOD; } -unsigned char formatter_inquiry_str[20] = { +static unsigned char formatter_inquiry_str[20] = { 'M', 'E', 'M', 'O', 'R', 'Y', 'S', 'T', 'I', 'C', 'K', #ifdef SUPPORT_MAGIC_GATE '-', 'M', 'G', /* Byte[47:49] */ @@ -2690,7 +2690,7 @@ static int ms_format_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) } #ifdef SUPPORT_PCGL_1P18 -int get_ms_information(struct scsi_cmnd *srb, struct rtsx_chip *chip) +static int get_ms_information(struct scsi_cmnd *srb, struct rtsx_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); unsigned int lun = SCSI_LUN(srb); @@ -2864,7 +2864,7 @@ static int sd_extention_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) #endif #ifdef SUPPORT_MAGIC_GATE -int mg_report_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) +static int mg_report_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); unsigned int lun = SCSI_LUN(srb); @@ -2962,7 +2962,7 @@ int mg_report_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) return TRANSPORT_GOOD; } -int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) +static int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); unsigned int lun = SCSI_LUN(srb); diff --git a/drivers/staging/rts_pstor/rtsx_transport.c b/drivers/staging/rts_pstor/rtsx_transport.c index 3b160dcb98b7..4e3d2c106af0 100644 --- a/drivers/staging/rts_pstor/rtsx_transport.c +++ b/drivers/staging/rts_pstor/rtsx_transport.c @@ -324,7 +324,7 @@ static inline void rtsx_add_sg_tbl( } while (len); } -int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, +static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, struct scatterlist *sg, int num_sg, unsigned int *index, unsigned int *offset, int size, enum dma_data_direction dma_dir, int timeout) @@ -485,7 +485,7 @@ out: return err; } -int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, +static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, struct scatterlist *sg, int num_sg, enum dma_data_direction dma_dir, int timeout) { @@ -632,7 +632,7 @@ out: return err; } -int rtsx_transfer_buf(struct rtsx_chip *chip, u8 card, void *buf, size_t len, +static int rtsx_transfer_buf(struct rtsx_chip *chip, u8 card, void *buf, size_t len, enum dma_data_direction dma_dir, int timeout) { struct rtsx_dev *rtsx = chip->rtsx; diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 945c95f2994f..80b61e69beef 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -32,30 +32,30 @@ #define SD_MAX_RETRY_COUNT 3 -u16 REG_SD_CFG1; -u16 REG_SD_CFG2; -u16 REG_SD_CFG3; -u16 REG_SD_STAT1; -u16 REG_SD_STAT2; -u16 REG_SD_BUS_STAT; -u16 REG_SD_PAD_CTL; -u16 REG_SD_SAMPLE_POINT_CTL; -u16 REG_SD_PUSH_POINT_CTL; -u16 REG_SD_CMD0; -u16 REG_SD_CMD1; -u16 REG_SD_CMD2; -u16 REG_SD_CMD3; -u16 REG_SD_CMD4; -u16 REG_SD_CMD5; -u16 REG_SD_BYTE_CNT_L; -u16 REG_SD_BYTE_CNT_H; -u16 REG_SD_BLOCK_CNT_L; -u16 REG_SD_BLOCK_CNT_H; -u16 REG_SD_TRANSFER; -u16 REG_SD_VPCLK0_CTL; -u16 REG_SD_VPCLK1_CTL; -u16 REG_SD_DCMPS0_CTL; -u16 REG_SD_DCMPS1_CTL; +static u16 REG_SD_CFG1; +static u16 REG_SD_CFG2; +static u16 REG_SD_CFG3; +static u16 REG_SD_STAT1; +static u16 REG_SD_STAT2; +static u16 REG_SD_BUS_STAT; +static u16 REG_SD_PAD_CTL; +static u16 REG_SD_SAMPLE_POINT_CTL; +static u16 REG_SD_PUSH_POINT_CTL; +static u16 REG_SD_CMD0; +static u16 REG_SD_CMD1; +static u16 REG_SD_CMD2; +static u16 REG_SD_CMD3; +static u16 REG_SD_CMD4; +static u16 REG_SD_CMD5; +static u16 REG_SD_BYTE_CNT_L; +static u16 REG_SD_BYTE_CNT_H; +static u16 REG_SD_BLOCK_CNT_L; +static u16 REG_SD_BLOCK_CNT_H; +static u16 REG_SD_TRANSFER; +static u16 REG_SD_VPCLK0_CTL; +static u16 REG_SD_VPCLK1_CTL; +static u16 REG_SD_DCMPS0_CTL; +static u16 REG_SD_DCMPS1_CTL; static inline void sd_set_err_code(struct rtsx_chip *chip, u8 err_code) { diff --git a/drivers/staging/rts_pstor/spi.c b/drivers/staging/rts_pstor/spi.c index e0682004756d..8a8689b327ae 100644 --- a/drivers/staging/rts_pstor/spi.c +++ b/drivers/staging/rts_pstor/spi.c @@ -221,7 +221,7 @@ static int spi_init_eeprom(struct rtsx_chip *chip) return STATUS_SUCCESS; } -int spi_eeprom_program_enable(struct rtsx_chip *chip) +static int spi_eeprom_program_enable(struct rtsx_chip *chip) { int retval; -- cgit v1.2.3 From 9ed62423033d167765a2c6385064acbeeadb2b14 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Thu, 10 Feb 2011 17:46:07 -0800 Subject: staging: olpc_dcon: don't specify single bits for bool fields Just use a regular 'bool foo', rather than 'bool foo:1'. Signed-off-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index eec10e78faba..cc121105e8c5 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -63,8 +63,8 @@ struct dcon_priv { u8 disp_mode; /* Current output type; true == mono, false == color */ - bool mono:1; - bool asleep:1; + bool mono; + bool asleep; }; /* I2C structures */ @@ -516,7 +516,7 @@ static ssize_t dcon_sleep_show(struct device *dev, { struct dcon_priv *dcon = dev_get_drvdata(dev); - return sprintf(buf, "%d\n", dcon->asleep ? 1 : 0); + return sprintf(buf, "%d\n", dcon->asleep); } static ssize_t dcon_freeze_show(struct device *dev, @@ -529,7 +529,7 @@ static ssize_t dcon_mono_show(struct device *dev, struct device_attribute *attr, char *buf) { struct dcon_priv *dcon = dev_get_drvdata(dev); - return sprintf(buf, "%d\n", dcon->mono ? 1 : 0); + return sprintf(buf, "%d\n", dcon->mono); } static ssize_t dcon_resumeline_show(struct device *dev, @@ -564,7 +564,7 @@ static ssize_t dcon_mono_store(struct device *dev, if (_strtoul(buf, count, &enable_mono)) return -EINVAL; - dcon_set_mono_mode(dev_get_drvdata(dev), enable_mono ? 1 : 0); + dcon_set_mono_mode(dev_get_drvdata(dev), enable_mono ? true : false); rc = count; return rc; -- cgit v1.2.3 From feaa98b2a5e452d95624d3f217cf1aab9cd25db0 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Thu, 10 Feb 2011 17:47:16 -0800 Subject: staging: olpc_dcon: move fb event notifier block into dcon_priv struct This also fixes a think-o where I was pulling the dcon struct out of thin air in the fb event callback. Signed-off-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index cc121105e8c5..710d88094d48 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -58,6 +58,7 @@ struct dcon_priv { struct work_struct switch_source; struct notifier_block reboot_nb; + struct notifier_block fbevent_nb; /* Shadow register for the DCON_REG_MODE register */ u8 disp_mode; @@ -669,13 +670,12 @@ static struct notifier_block dcon_panic_nb = { * When the framebuffer sleeps due to external sources (e.g. user idle), power * down the DCON as well. Power it back up when the fb comes back to life. */ -static int fb_notifier_callback(struct notifier_block *self, +static int dcon_fb_notifier(struct notifier_block *self, unsigned long event, void *data) { struct fb_event *evdata = data; - struct backlight_device *bl = container_of(self, - struct backlight_device, fb_notif); - struct dcon_priv *dcon = bl_get_data(bl); + struct dcon_priv *dcon = container_of(self, struct dcon_priv, + fbevent_nb); int *blank = (int *) evdata->data; if (((event != FB_EVENT_BLANK) && (event != FB_EVENT_CONBLANK)) || ignore_fb_events) @@ -684,10 +684,6 @@ static int fb_notifier_callback(struct notifier_block *self, return 0; } -static struct notifier_block fb_nb = { - .notifier_call = fb_notifier_callback, -}; - static int dcon_detect(struct i2c_client *client, struct i2c_board_info *info) { strlcpy(info->type, "olpc_dcon", I2C_NAME_SIZE); @@ -708,6 +704,7 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) INIT_WORK(&dcon->switch_source, dcon_source_switch); dcon->reboot_nb.notifier_call = dcon_reboot_notify; dcon->reboot_nb.priority = -1; + dcon->fbevent_nb.notifier_call = dcon_fb_notifier; i2c_set_clientdata(client, dcon); @@ -762,7 +759,7 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) register_reboot_notifier(&dcon->reboot_nb); atomic_notifier_chain_register(&panic_notifier_list, &dcon_panic_nb); - fb_register_client(&fb_nb); + fb_register_client(&dcon->fbevent_nb); return 0; @@ -786,7 +783,7 @@ static int dcon_remove(struct i2c_client *client) i2c_set_clientdata(client, NULL); - fb_unregister_client(&fb_nb); + fb_unregister_client(&dcon->fbevent_nb); unregister_reboot_notifier(&dcon->reboot_nb); atomic_notifier_chain_unregister(&panic_notifier_list, &dcon_panic_nb); -- cgit v1.2.3 From 45bfe97276856b866dd73fdadb65fb928c0c9bc1 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Thu, 10 Feb 2011 17:48:38 -0800 Subject: staging: olpc_dcon: move fb stuff info dcon_priv, and clean up fb handling - move fbinfo and ignore_fb_events into dcon_priv - add calls to {un,}lock_fb_info before calling fb_blank - fail to load the driver if there are no registered framebuffers That last one fixes a potential oops, where if the dcon driver loads without a framebuffer registered, fb_blank will end up being passed a NULL (and will attempt to dereference it). Signed-off-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon.c | 60 +++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 710d88094d48..d3c280052d16 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -55,6 +55,7 @@ static struct dcon_platform_data *pdata; struct dcon_priv { struct i2c_client *client; + struct fb_info *fbinfo; struct work_struct switch_source; struct notifier_block reboot_nb; @@ -66,6 +67,8 @@ struct dcon_priv { /* Current output type; true == mono, false == color */ bool mono; bool asleep; + /* This get set while controlling fb blank state from the driver */ + bool ignore_fb_events; }; /* I2C structures */ @@ -78,11 +81,6 @@ static struct platform_device *dcon_device; /* Backlight device */ static struct backlight_device *dcon_bl_dev; -static struct fb_info *fbinfo; - -/* set this to 1 while controlling fb blank state from this driver */ -static int ignore_fb_events = 0; - /* Current source, initialized at probe time */ static int dcon_source; @@ -346,8 +344,32 @@ void dcon_load_holdoff(void) mdelay(4); } } -/* Set the source of the display (CPU or DCON) */ +static bool dcon_blank_fb(struct dcon_priv *dcon, bool blank) +{ + int err; + + if (!lock_fb_info(dcon->fbinfo)) { + dev_err(&dcon->client->dev, "unable to lock framebuffer\n"); + return false; + } + console_lock(); + dcon->ignore_fb_events = true; + err = fb_blank(dcon->fbinfo, + blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK); + dcon->ignore_fb_events = false; + console_unlock(); + unlock_fb_info(dcon->fbinfo); + + if (err) { + dev_err(&dcon->client->dev, "couldn't %sblank framebuffer\n", + blank ? "" : "un"); + return false; + } + return true; +} + +/* Set the source of the display (CPU or DCON) */ static void dcon_source_switch(struct work_struct *work) { struct dcon_priv *dcon = container_of(work, struct dcon_priv, @@ -391,17 +413,11 @@ static void dcon_source_switch(struct work_struct *work) * * For now, we just hope.. */ - console_lock(); - ignore_fb_events = 1; - if (fb_blank(fbinfo, FB_BLANK_UNBLANK)) { - ignore_fb_events = 0; - console_unlock(); + if (!dcon_blank_fb(dcon, false)) { printk(KERN_ERR "olpc-dcon: Failed to enter CPU mode\n"); dcon_pending = DCON_SOURCE_DCON; return; } - ignore_fb_events = 0; - console_unlock(); /* And turn off the DCON */ pdata->set_dconload(1); @@ -453,13 +469,7 @@ static void dcon_source_switch(struct work_struct *work) } } - console_lock(); - ignore_fb_events = 1; - if (fb_blank(fbinfo, FB_BLANK_POWERDOWN)) - printk(KERN_ERR "olpc-dcon: couldn't blank fb!\n"); - ignore_fb_events = 0; - console_unlock(); - + dcon_blank_fb(dcon, true); printk(KERN_INFO "olpc-dcon: The DCON has control\n"); break; } @@ -678,7 +688,7 @@ static int dcon_fb_notifier(struct notifier_block *self, fbevent_nb); int *blank = (int *) evdata->data; if (((event != FB_EVENT_BLANK) && (event != FB_EVENT_CONBLANK)) || - ignore_fb_events) + dcon->ignore_fb_events) return 0; dcon_sleep(dcon, *blank ? true : false); return 0; @@ -708,8 +718,12 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) i2c_set_clientdata(client, dcon); - if (num_registered_fb >= 1) - fbinfo = registered_fb[0]; + if (num_registered_fb < 1) { + dev_err(&client->dev, "DCON driver requires a registered fb\n"); + rc = -EIO; + goto einit; + } + dcon->fbinfo = registered_fb[0]; rc = dcon_hw_init(dcon, 1); if (rc) -- cgit v1.2.3 From 31a3da4146c120e87b8d42d033760fe49704a233 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Feb 2011 17:49:24 -0800 Subject: staging: olpc_dcon: Remove _strtoul() function. olpc_dcon driver use self invented _strtoul function which make similar check like strict_strtoul just extend for space checking at last string place. Normally access to sys file looks echo 1024 > /sys/... so space could be considered as error character and we could simplify code using just strict_strtoul function instead self invented. Signed-off-by: Marek Belisko Signed-off-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon.c | 57 ++++++++++++++--------------------- 1 file changed, 22 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index d3c280052d16..52b7b306a575 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -549,48 +549,33 @@ static ssize_t dcon_resumeline_show(struct device *dev, return sprintf(buf, "%d\n", resumeline); } -static int _strtoul(const char *buf, int len, unsigned int *val) -{ - - char *endp; - unsigned int output = simple_strtoul(buf, &endp, 0); - int size = endp - buf; - - if (*endp && isspace(*endp)) - size++; - - if (size != len) - return -EINVAL; - - *val = output; - return 0; -} - static ssize_t dcon_mono_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - int enable_mono; - int rc = -EINVAL; + unsigned long enable_mono; + int rc; - if (_strtoul(buf, count, &enable_mono)) - return -EINVAL; + rc = strict_strtoul(buf, 10, &enable_mono); + if (rc) + return rc; dcon_set_mono_mode(dev_get_drvdata(dev), enable_mono ? true : false); - rc = count; - return rc; + return count; } static ssize_t dcon_freeze_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct dcon_priv *dcon = dev_get_drvdata(dev); - int output; + unsigned long output; + int ret; - if (_strtoul(buf, count, &output)) - return -EINVAL; + ret = strict_strtoul(buf, 10, &output); + if (ret) + return ret; - printk(KERN_INFO "dcon_freeze_store: %d\n", output); + printk(KERN_INFO "dcon_freeze_store: %lu\n", output); switch (output) { case 0: @@ -612,26 +597,28 @@ static ssize_t dcon_freeze_store(struct device *dev, static ssize_t dcon_resumeline_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - int rl; - int rc = -EINVAL; + unsigned long rl; + int rc; - if (_strtoul(buf, count, &rl)) + rc = strict_strtoul(buf, 10, &rl); + if (rc) return rc; resumeline = rl; dcon_write(dev_get_drvdata(dev), DCON_REG_SCAN_INT, resumeline); - rc = count; - return rc; + return count; } static ssize_t dcon_sleep_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - int output; + unsigned long output; + int ret; - if (_strtoul(buf, count, &output)) - return -EINVAL; + ret = strict_strtoul(buf, 10, &output); + if (ret) + return ret; dcon_sleep(dev_get_drvdata(dev), output ? true : false); return count; -- cgit v1.2.3 From 8f2fb16a9cd015072b3da9038084930287e11985 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Thu, 10 Feb 2011 17:49:58 -0800 Subject: staging: olpc_dcon: drop XO-1.5 prototype support Remove code related to XO-1.5 prototype boards. Signed-off-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c | 84 ++++++++-------------------- 1 file changed, 23 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c index 4f56098bb366..5ef05406a8b8 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c +++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c @@ -10,19 +10,15 @@ /* Hardware setup on the XO 1.5: * DCONLOAD connects to - * VX855_GPO12 (not nCR_PWOFF) (rev A) - * VX855_GPIO1 (not SMBCK2) (rev B) + * VX855_GPIO1 (not SMBCK2) * DCONBLANK connects to VX855_GPIO8 (not SSPICLK) unused in driver * DCONSTAT0 connects to VX855_GPI10 (not SSPISDI) * DCONSTAT1 connects to VX855_GPI11 (not nSSPISS) - * DCONIRQ connects to VX855_GPIO12 (on B3. on B2, it goes to - * SMBALRT, which doesn't work.) + * DCONIRQ connects to VX855_GPIO12 * DCONSMBDATA connects to VX855 graphics CRTSPD * DCONSMBCLK connects to VX855 graphics CRTSPCLK */ -#define TEST_B2 0 // define to test B3 paths on a modded B2 board - #define VX855_GENL_PURPOSE_OUTPUT 0x44c // PMIO_Rx4c-4f #define VX855_GPI_STATUS_CHG 0x450 // PMIO_Rx50 #define VX855_GPI_SCI_SMI 0x452 // PMIO_Rx52 @@ -30,34 +26,21 @@ #define PREFIX "OLPC DCON:" -/* - there is no support here for DCONIRQ on 1.5 boards earlier than - B3. the issue is that the DCONIRQ signal on earlier boards is - routed to SMBALRT, which turns out to to be a level sensitive - interrupt. the DCONIRQ signal is far too short (11usec) to - be detected reliably in that case. including support for - DCONIRQ functions no better than none at all. -*/ - static struct dcon_platform_data dcon_pdata_xo_1_5; static void dcon_clear_irq(void) { - if (TEST_B2 || olpc_board_at_least(olpc_board(BOARD_XO_1_5_B3))) { - // irq status will appear in PMIO_Rx50[6] (RW1C) on gpio12 - outb(BIT_GPIO12, VX855_GPI_STATUS_CHG); - } + /* irq status will appear in PMIO_Rx50[6] (RW1C) on gpio12 */ + outb(BIT_GPIO12, VX855_GPI_STATUS_CHG); } static int dcon_was_irq(void) { u_int8_t tmp; - if (TEST_B2 || olpc_board_at_least(olpc_board(BOARD_XO_1_5_B3))) { - // irq status will appear in PMIO_Rx50[6] on gpio12 - tmp = inb(VX855_GPI_STATUS_CHG); - return !!(tmp & BIT_GPIO12); - } + /* irq status will appear in PMIO_Rx50[6] on gpio12 */ + tmp = inb(VX855_GPI_STATUS_CHG); + return !!(tmp & BIT_GPIO12); return 0; } @@ -76,14 +59,8 @@ static int dcon_init_xo_1_5(void) return 1; } - if (olpc_board_at_least(olpc_board(BOARD_XO_1_5_B1))) { - pci_read_config_byte(pdev, 0x95, &tmp); - pci_write_config_byte(pdev, 0x95, tmp|0x0c); - } else { - /* Set GPO12 to GPO mode, not nCR_PWOFF */ - pci_read_config_byte(pdev, 0x9b, &tmp); - pci_write_config_byte(pdev, 0x9b, tmp|0x01); - } + pci_read_config_byte(pdev, 0x95, &tmp); + pci_write_config_byte(pdev, 0x95, tmp|0x0c); /* Set GPIO8 to GPIO mode, not SSPICLK */ pci_read_config_byte(pdev, 0xe3, &tmp); @@ -93,31 +70,22 @@ static int dcon_init_xo_1_5(void) pci_read_config_byte(pdev, 0xe4, &tmp); pci_write_config_byte(pdev, 0xe4, tmp|0x08); - if (TEST_B2 || olpc_board_at_least(olpc_board(BOARD_XO_1_5_B3))) { - // clear PMU_RxE1[6] to select SCI on GPIO12 - // clear PMU_RxE0[6] to choose falling edge - pci_read_config_byte(pdev, 0xe1, &tmp); - pci_write_config_byte(pdev, 0xe1, tmp & ~BIT_GPIO12); - pci_read_config_byte(pdev, 0xe0, &tmp); - pci_write_config_byte(pdev, 0xe0, tmp & ~BIT_GPIO12); - - dcon_clear_irq(); + /* clear PMU_RxE1[6] to select SCI on GPIO12 */ + /* clear PMU_RxE0[6] to choose falling edge */ + pci_read_config_byte(pdev, 0xe1, &tmp); + pci_write_config_byte(pdev, 0xe1, tmp & ~BIT_GPIO12); + pci_read_config_byte(pdev, 0xe0, &tmp); + pci_write_config_byte(pdev, 0xe0, tmp & ~BIT_GPIO12); - // set PMIO_Rx52[6] to enable SCI/SMI on gpio12 - outb(inb(VX855_GPI_SCI_SMI)|BIT_GPIO12, VX855_GPI_SCI_SMI); + dcon_clear_irq(); - } + /* set PMIO_Rx52[6] to enable SCI/SMI on gpio12 */ + outb(inb(VX855_GPI_SCI_SMI)|BIT_GPIO12, VX855_GPI_SCI_SMI); /* Determine the current state of DCONLOAD, likely set by firmware */ - if (olpc_board_at_least(olpc_board(BOARD_XO_1_5_B1))) { - // GPIO1 - dcon_source = (inl(VX855_GENL_PURPOSE_OUTPUT) & 0x1000) ? - DCON_SOURCE_CPU : DCON_SOURCE_DCON; - } else { - // GPO12 - dcon_source = (inl(VX855_GENL_PURPOSE_OUTPUT) & 0x04000000) ? + /* GPIO1 */ + dcon_source = (inl(VX855_GENL_PURPOSE_OUTPUT) & 0x1000) ? DCON_SOURCE_CPU : DCON_SOURCE_DCON; - } dcon_pending = dcon_source; pci_dev_put(pdev); @@ -180,19 +148,13 @@ static void dcon_wiggle_xo_1_5(void) } udelay(5); - if (TEST_B2 || olpc_board_at_least(olpc_board(BOARD_XO_1_5_B3))) { - // set PMIO_Rx52[6] to enable SCI/SMI on gpio12 - outb(inb(VX855_GPI_SCI_SMI)|BIT_GPIO12, VX855_GPI_SCI_SMI); - } + /* set PMIO_Rx52[6] to enable SCI/SMI on gpio12 */ + outb(inb(VX855_GPI_SCI_SMI)|BIT_GPIO12, VX855_GPI_SCI_SMI); } static void dcon_set_dconload_xo_1_5(int val) { - if (olpc_board_at_least(olpc_board(BOARD_XO_1_5_B1))) { - gpio_set_value(VX855_GPIO(1), val); - } else { - gpio_set_value(VX855_GPO(12), val); - } + gpio_set_value(VX855_GPIO(1), val); } static u8 dcon_read_status_xo_1_5(void) -- cgit v1.2.3 From 097cd83a4c312e1ae0d9c14526f846666cab4f3a Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Thu, 10 Feb 2011 17:53:24 -0800 Subject: staging: olpc_dcon: add config options for XO_1 and XO_1_5, drop hardcoded XO-1 stuff This adds CONFIG_FB_OLPC_DCON_1 and CONFIG_FB_OLPC_DCON_1_5 options for allowing selection of XO-1 and/or XO-1.5 DCON support. In the process, it also forces the xo_1.c and xo_1_5.c files to build as separate units, correctly selects between XO-1 and XO-1.5 at runtime, and adds some hacks to allow xo_1_5.c to build. This isn't the cleanest patch, but it'll get better as more global variables are dropped. Signed-off-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/Kconfig | 20 ++++++++++++++++ drivers/staging/olpc_dcon/Makefile | 7 +++++- drivers/staging/olpc_dcon/olpc_dcon.c | 34 ++++++++++++++-------------- drivers/staging/olpc_dcon/olpc_dcon.h | 22 ++++++++++++++++++ drivers/staging/olpc_dcon/olpc_dcon_xo_1.c | 2 +- drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c | 18 ++++++++++++--- 6 files changed, 81 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/Kconfig b/drivers/staging/olpc_dcon/Kconfig index 8be87166b54b..982273cf354f 100644 --- a/drivers/staging/olpc_dcon/Kconfig +++ b/drivers/staging/olpc_dcon/Kconfig @@ -6,3 +6,23 @@ config FB_OLPC_DCON Add support for the OLPC XO DCON controller. This controller is only available on OLPC platforms. Unless you have one of these platforms, you will want to say 'N'. + +config FB_OLPC_DCON_1 + bool "OLPC XO-1 DCON support" + depends on FB_OLPC_DCON + default y + ---help--- + Enable support for the DCON in XO-1 model laptops. The kernel + communicates with the DCON using model-specific code. If you + have an XO-1 (or if you're unsure what model you have), you should + say 'Y'. + +config FB_OLPC_DCON_1_5 + bool "OLPC XO-1.5 DCON support" + depends on FB_OLPC_DCON + default y + ---help--- + Enable support for the DCON in XO-1.5 model laptops. The kernel + communicates with the DCON using model-specific code. If you + have an XO-1.5 (or if you're unsure what model you have), you + should say 'Y'. diff --git a/drivers/staging/olpc_dcon/Makefile b/drivers/staging/olpc_dcon/Makefile index cd8f2898947d..36c7e67fec20 100644 --- a/drivers/staging/olpc_dcon/Makefile +++ b/drivers/staging/olpc_dcon/Makefile @@ -1 +1,6 @@ -obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon.o +olpc-dcon-objs += olpc_dcon.o +olpc-dcon-$(CONFIG_FB_OLPC_DCON_1) += olpc_dcon_xo_1.o +olpc-dcon-$(CONFIG_FB_OLPC_DCON_1_5) += olpc_dcon_xo_1_5.o +obj-$(CONFIG_FB_OLPC_DCON) += olpc-dcon.o + + diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 52b7b306a575..96b6fd26791b 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -4,7 +4,7 @@ * Copyright © 2006-2007 Red Hat, Inc. * Copyright © 2006-2007 Advanced Micro Devices, Inc. * Copyright © 2009 VIA Technology, Inc. - * Copyright (c) 2010 Andres Salomon + * Copyright (c) 2010-2011 Andres Salomon * * This program is free software. You can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -44,13 +44,6 @@ module_param(noinit, int, 0444); static int useaa = 1; module_param(useaa, int, 0444); -struct dcon_platform_data { - int (*init)(void); - void (*bus_stabilize_wiggle)(void); - void (*set_dconload)(int); - u8 (*read_status)(void); -}; - static struct dcon_platform_data *pdata; struct dcon_priv { @@ -73,8 +66,6 @@ struct dcon_priv { /* I2C structures */ -static struct i2c_driver dcon_driver; - /* Platform devices */ static struct platform_device *dcon_device; @@ -82,10 +73,10 @@ static struct platform_device *dcon_device; static struct backlight_device *dcon_bl_dev; /* Current source, initialized at probe time */ -static int dcon_source; +int dcon_source; /* Desired source */ -static int dcon_pending; +int dcon_pending; /* Variables used during switches */ static int dcon_switched; @@ -693,6 +684,9 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) struct dcon_priv *dcon; int rc, i, j; + if (!pdata) + return -ENXIO; + dcon = kzalloc(sizeof(*dcon), GFP_KERNEL); if (!dcon) return -ENOMEM; @@ -830,7 +824,7 @@ static int dcon_resume(struct i2c_client *client) #endif -static irqreturn_t dcon_interrupt(int irq, void *id) +irqreturn_t dcon_interrupt(int irq, void *id) { int status = pdata->read_status(); @@ -877,7 +871,7 @@ static const struct i2c_device_id dcon_idtable[] = { MODULE_DEVICE_TABLE(i2c, dcon_idtable); -static struct i2c_driver dcon_driver = { +struct i2c_driver dcon_driver = { .driver = { .name = "olpc_dcon", }, @@ -893,11 +887,17 @@ static struct i2c_driver dcon_driver = { #endif }; -#include "olpc_dcon_xo_1.c" - static int __init olpc_dcon_init(void) { - pdata = &dcon_pdata_xo_1; +#ifdef CONFIG_FB_OLPC_DCON_1_5 + /* XO-1.5 */ + if (olpc_board_at_least(olpc_board(0xd0))) + pdata = &dcon_pdata_xo_1_5; +#endif +#ifdef CONFIG_FB_OLPC_DCON_1 + if (!pdata) + pdata = &dcon_pdata_xo_1; +#endif return i2c_add_driver(&dcon_driver); } diff --git a/drivers/staging/olpc_dcon/olpc_dcon.h b/drivers/staging/olpc_dcon/olpc_dcon.h index cef2473bccf3..03ac42c5e3ca 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.h +++ b/drivers/staging/olpc_dcon/olpc_dcon.h @@ -44,4 +44,26 @@ /* Interrupt */ #define DCON_IRQ 6 +struct dcon_platform_data { + int (*init)(void); + void (*bus_stabilize_wiggle)(void); + void (*set_dconload)(int); + u8 (*read_status)(void); +}; + +#include + +extern int dcon_source; +extern int dcon_pending; +extern irqreturn_t dcon_interrupt(int irq, void *id); +extern struct i2c_driver dcon_driver; + +#ifdef CONFIG_FB_OLPC_DCON_1 +extern struct dcon_platform_data dcon_pdata_xo_1; +#endif + +#ifdef CONFIG_FB_OLPC_DCON_1_5 +extern struct dcon_platform_data dcon_pdata_xo_1_5; +#endif + #endif diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c index 043198dc6ff7..be52b6c9c50e 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c +++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c @@ -195,7 +195,7 @@ static u8 dcon_read_status_xo_1(void) return status; } -static struct dcon_platform_data dcon_pdata_xo_1 = { +struct dcon_platform_data dcon_pdata_xo_1 = { .init = dcon_init_xo_1, .bus_stabilize_wiggle = dcon_wiggle_xo_1, .set_dconload = dcon_set_dconload_1, diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c index 5ef05406a8b8..d4c2d7482c32 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c +++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c @@ -7,6 +7,20 @@ */ #include +#include +#include +#include + +/* TODO: this eventually belongs in linux/vx855.h */ +#define NR_VX855_GPI 14 +#define NR_VX855_GPO 13 +#define NR_VX855_GPIO 15 + +#define VX855_GPI(n) (n) +#define VX855_GPO(n) (NR_VX855_GPI + (n)) +#define VX855_GPIO(n) (NR_VX855_GPI + NR_VX855_GPO + (n)) + +#include "olpc_dcon.h" /* Hardware setup on the XO 1.5: * DCONLOAD connects to @@ -26,8 +40,6 @@ #define PREFIX "OLPC DCON:" -static struct dcon_platform_data dcon_pdata_xo_1_5; - static void dcon_clear_irq(void) { /* irq status will appear in PMIO_Rx50[6] (RW1C) on gpio12 */ @@ -173,7 +185,7 @@ static u8 dcon_read_status_xo_1_5(void) return status; } -static struct dcon_platform_data dcon_pdata_xo_1_5 = { +struct dcon_platform_data dcon_pdata_xo_1_5 = { .init = dcon_init_xo_1_5, .bus_stabilize_wiggle = dcon_wiggle_xo_1_5, .set_dconload = dcon_set_dconload_xo_1_5, -- cgit v1.2.3 From bbe963f1b98c90980e33086d726f0963e286d1b4 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Thu, 10 Feb 2011 17:54:24 -0800 Subject: staging: olpc_dcon: move more variables into dcon_priv This moves dcon_source and dcon_pending into the dcon_priv struct. Because these variables are used by the IRQ handler (which is registered in the model-specific callbacks), we end up needing to move dcon_priv into olpc_dcon.h. This also changes the IRQ registration to use the dcon_priv pointer as dev_id, instead of dcon_driver. Signed-off-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon.c | 51 ++++++++-------------------- drivers/staging/olpc_dcon/olpc_dcon.h | 32 ++++++++++++++--- drivers/staging/olpc_dcon/olpc_dcon_xo_1.c | 10 +++--- drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c | 9 +++-- 4 files changed, 51 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 96b6fd26791b..cdd8718a7f99 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -46,24 +45,6 @@ module_param(useaa, int, 0444); static struct dcon_platform_data *pdata; -struct dcon_priv { - struct i2c_client *client; - struct fb_info *fbinfo; - - struct work_struct switch_source; - struct notifier_block reboot_nb; - struct notifier_block fbevent_nb; - - /* Shadow register for the DCON_REG_MODE register */ - u8 disp_mode; - - /* Current output type; true == mono, false == color */ - bool mono; - bool asleep; - /* This get set while controlling fb blank state from the driver */ - bool ignore_fb_events; -}; - /* I2C structures */ /* Platform devices */ @@ -72,12 +53,6 @@ static struct platform_device *dcon_device; /* Backlight device */ static struct backlight_device *dcon_bl_dev; -/* Current source, initialized at probe time */ -int dcon_source; - -/* Desired source */ -int dcon_pending; - /* Variables used during switches */ static int dcon_switched; static struct timespec dcon_irq_time; @@ -119,7 +94,7 @@ static int dcon_hw_init(struct dcon_priv *dcon, int is_init) if (is_init) { printk(KERN_INFO "olpc-dcon: Discovered DCON version %x\n", ver & 0xFF); - rc = pdata->init(); + rc = pdata->init(dcon); if (rc != 0) { printk(KERN_ERR "olpc-dcon: Unable to init.\n"); goto err; @@ -366,9 +341,9 @@ static void dcon_source_switch(struct work_struct *work) struct dcon_priv *dcon = container_of(work, struct dcon_priv, switch_source); DECLARE_WAITQUEUE(wait, current); - int source = dcon_pending; + int source = dcon->pending_src; - if (dcon_source == source) + if (dcon->curr_src == source) return; dcon_load_holdoff(); @@ -406,7 +381,7 @@ static void dcon_source_switch(struct work_struct *work) */ if (!dcon_blank_fb(dcon, false)) { printk(KERN_ERR "olpc-dcon: Failed to enter CPU mode\n"); - dcon_pending = DCON_SOURCE_DCON; + dcon->pending_src = DCON_SOURCE_DCON; return; } @@ -468,17 +443,17 @@ static void dcon_source_switch(struct work_struct *work) BUG(); } - dcon_source = source; + dcon->curr_src = source; } static void dcon_set_source(struct dcon_priv *dcon, int arg) { - if (dcon_pending == arg) + if (dcon->pending_src == arg) return; - dcon_pending = arg; + dcon->pending_src = arg; - if ((dcon_source != arg) && !work_pending(&dcon->switch_source)) + if ((dcon->curr_src != arg) && !work_pending(&dcon->switch_source)) schedule_work(&dcon->switch_source); } @@ -524,7 +499,8 @@ static ssize_t dcon_sleep_show(struct device *dev, static ssize_t dcon_freeze_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "%d\n", dcon_source == DCON_SOURCE_DCON ? 1 : 0); + struct dcon_priv *dcon = dev_get_drvdata(dev); + return sprintf(buf, "%d\n", dcon->curr_src == DCON_SOURCE_DCON ? 1 : 0); } static ssize_t dcon_mono_show(struct device *dev, @@ -765,7 +741,7 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) platform_device_unregister(dcon_device); dcon_device = NULL; eirq: - free_irq(DCON_IRQ, &dcon_driver); + free_irq(DCON_IRQ, dcon); einit: i2c_set_clientdata(client, NULL); kfree(dcon); @@ -782,7 +758,7 @@ static int dcon_remove(struct i2c_client *client) unregister_reboot_notifier(&dcon->reboot_nb); atomic_notifier_chain_unregister(&panic_notifier_list, &dcon_panic_nb); - free_irq(DCON_IRQ, &dcon_driver); + free_irq(DCON_IRQ, dcon); if (dcon_bl_dev != NULL) backlight_device_unregister(dcon_bl_dev); @@ -826,6 +802,7 @@ static int dcon_resume(struct i2c_client *client) irqreturn_t dcon_interrupt(int irq, void *id) { + struct dcon_priv *dcon = id; int status = pdata->read_status(); if (status == -1) @@ -851,7 +828,7 @@ irqreturn_t dcon_interrupt(int irq, void *id) * of the DCON happened long before this point. * see http://dev.laptop.org/ticket/9869 */ - if (dcon_source != dcon_pending && !dcon_switched) { + if (dcon->curr_src != dcon->pending_src && !dcon_switched) { dcon_switched = 1; getnstimeofday(&dcon_irq_time); wake_up(&dcon_wait_queue); diff --git a/drivers/staging/olpc_dcon/olpc_dcon.h b/drivers/staging/olpc_dcon/olpc_dcon.h index 03ac42c5e3ca..2c06e1915c3f 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.h +++ b/drivers/staging/olpc_dcon/olpc_dcon.h @@ -1,6 +1,9 @@ #ifndef OLPC_DCON_H_ #define OLPC_DCON_H_ +#include +#include + /* DCON registers */ #define DCON_REG_ID 0 @@ -44,8 +47,32 @@ /* Interrupt */ #define DCON_IRQ 6 +struct dcon_priv { + struct i2c_client *client; + struct fb_info *fbinfo; + + struct work_struct switch_source; + struct notifier_block reboot_nb; + struct notifier_block fbevent_nb; + + /* Shadow register for the DCON_REG_MODE register */ + u8 disp_mode; + + /* Current source, initialized at probe time */ + int curr_src; + + /* Desired source */ + int pending_src; + + /* Current output type; true == mono, false == color */ + bool mono; + bool asleep; + /* This get set while controlling fb blank state from the driver */ + bool ignore_fb_events; +}; + struct dcon_platform_data { - int (*init)(void); + int (*init)(struct dcon_priv *); void (*bus_stabilize_wiggle)(void); void (*set_dconload)(int); u8 (*read_status)(void); @@ -53,10 +80,7 @@ struct dcon_platform_data { #include -extern int dcon_source; -extern int dcon_pending; extern irqreturn_t dcon_interrupt(int irq, void *id); -extern struct i2c_driver dcon_driver; #ifdef CONFIG_FB_OLPC_DCON_1 extern struct dcon_platform_data dcon_pdata_xo_1; diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c index be52b6c9c50e..b154be7a2fe6 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c +++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c @@ -16,7 +16,7 @@ #include "olpc_dcon.h" -static int dcon_init_xo_1(void) +static int dcon_init_xo_1(struct dcon_priv *dcon) { unsigned char lob; @@ -54,10 +54,10 @@ static int dcon_init_xo_1(void) * then a value is set. So, future readings of the pin can use * READ_BACK, but the first one cannot. Awesome, huh? */ - dcon_source = cs5535_gpio_isset(OLPC_GPIO_DCON_LOAD, GPIO_OUTPUT_VAL) + dcon->curr_src = cs5535_gpio_isset(OLPC_GPIO_DCON_LOAD, GPIO_OUTPUT_VAL) ? DCON_SOURCE_CPU : DCON_SOURCE_DCON; - dcon_pending = dcon_source; + dcon->pending_src = dcon->curr_src; /* Set the directions for the GPIO pins */ gpio_direction_input(OLPC_GPIO_DCON_STAT0); @@ -65,7 +65,7 @@ static int dcon_init_xo_1(void) gpio_direction_input(OLPC_GPIO_DCON_IRQ); gpio_direction_input(OLPC_GPIO_DCON_BLANK); gpio_direction_output(OLPC_GPIO_DCON_LOAD, - dcon_source == DCON_SOURCE_CPU); + dcon->curr_src == DCON_SOURCE_CPU); /* Set up the interrupt mappings */ @@ -81,7 +81,7 @@ static int dcon_init_xo_1(void) outb(lob, 0x4d0); /* Register the interupt handler */ - if (request_irq(DCON_IRQ, &dcon_interrupt, 0, "DCON", &dcon_driver)) { + if (request_irq(DCON_IRQ, &dcon_interrupt, 0, "DCON", dcon)) { printk(KERN_ERR "olpc-dcon: failed to request DCON's irq\n"); goto err_req_irq; } diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c index d4c2d7482c32..e213b63f8116 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c +++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c @@ -57,7 +57,7 @@ static int dcon_was_irq(void) return 0; } -static int dcon_init_xo_1_5(void) +static int dcon_init_xo_1_5(struct dcon_priv *dcon) { unsigned int irq; u_int8_t tmp; @@ -96,20 +96,19 @@ static int dcon_init_xo_1_5(void) /* Determine the current state of DCONLOAD, likely set by firmware */ /* GPIO1 */ - dcon_source = (inl(VX855_GENL_PURPOSE_OUTPUT) & 0x1000) ? + dcon->curr_src = (inl(VX855_GENL_PURPOSE_OUTPUT) & 0x1000) ? DCON_SOURCE_CPU : DCON_SOURCE_DCON; - dcon_pending = dcon_source; + dcon->pending_src = dcon->curr_src; pci_dev_put(pdev); /* we're sharing the IRQ with ACPI */ irq = acpi_gbl_FADT.sci_interrupt; - if (request_irq(irq, &dcon_interrupt, IRQF_SHARED, "DCON", &dcon_driver)) { + if (request_irq(irq, &dcon_interrupt, IRQF_SHARED, "DCON", dcon)) { printk(KERN_ERR PREFIX "DCON (IRQ%d) allocation failed\n", irq); return 1; } - return 0; } -- cgit v1.2.3 From 309ef2a25e8d3d5962bb0824c58ea39c12c166ef Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Thu, 10 Feb 2011 17:54:58 -0800 Subject: staging: olpc_dcon: move more global variables into dcon_priv Global variables dcon_switched, dcon_irq_time, and dcon_load_time can all be moved into the dcon_priv struct now that dcon_interrupt has access to dcon_priv. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon.c | 39 +++++++++++++++-------------------- drivers/staging/olpc_dcon/olpc_dcon.h | 5 +++++ 2 files changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index cdd8718a7f99..07abdfa4ad48 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -53,11 +53,6 @@ static struct platform_device *dcon_device; /* Backlight device */ static struct backlight_device *dcon_bl_dev; -/* Variables used during switches */ -static int dcon_switched; -static struct timespec dcon_irq_time; -static struct timespec dcon_load_time; - static DECLARE_WAIT_QUEUE_HEAD(dcon_wait_queue); static unsigned short normal_i2c[] = { 0x0d, I2C_CLIENT_END }; @@ -297,12 +292,12 @@ static void dcon_sleep(struct dcon_priv *dcon, bool sleep) * normally we don't change it this fast, so in general we won't * delay here. */ -void dcon_load_holdoff(void) +static void dcon_load_holdoff(struct dcon_priv *dcon) { struct timespec delta_t, now; while (1) { getnstimeofday(&now); - delta_t = timespec_sub(now, dcon_load_time); + delta_t = timespec_sub(now, dcon->load_time); if (delta_t.tv_sec != 0 || delta_t.tv_nsec > NSEC_PER_MSEC * 20) { break; @@ -346,9 +341,9 @@ static void dcon_source_switch(struct work_struct *work) if (dcon->curr_src == source) return; - dcon_load_holdoff(); + dcon_load_holdoff(dcon); - dcon_switched = 0; + dcon->switched = false; switch (source) { case DCON_SOURCE_CPU: @@ -361,10 +356,10 @@ static void dcon_source_switch(struct work_struct *work) else { /* Wait up to one second for the scanline interrupt */ wait_event_timeout(dcon_wait_queue, - dcon_switched == 1, HZ); + dcon->switched == true, HZ); } - if (!dcon_switched) + if (!dcon->switched) printk(KERN_ERR "olpc-dcon: Timeout entering CPU mode; expect a screen glitch.\n"); /* Turn off the scanline interrupt */ @@ -387,7 +382,7 @@ static void dcon_source_switch(struct work_struct *work) /* And turn off the DCON */ pdata->set_dconload(1); - getnstimeofday(&dcon_load_time); + getnstimeofday(&dcon->load_time); printk(KERN_INFO "olpc-dcon: The CPU has control\n"); break; @@ -403,13 +398,13 @@ static void dcon_source_switch(struct work_struct *work) /* Clear DCONLOAD - this implies that the DCON is in control */ pdata->set_dconload(0); - getnstimeofday(&dcon_load_time); + getnstimeofday(&dcon->load_time); t = schedule_timeout(HZ/2); remove_wait_queue(&dcon_wait_queue, &wait); set_current_state(TASK_RUNNING); - if (!dcon_switched) { + if (!dcon->switched) { printk(KERN_ERR "olpc-dcon: Timeout entering DCON mode; expect a screen glitch.\n"); } else { /* sometimes the DCON doesn't follow its own rules, @@ -423,14 +418,14 @@ static void dcon_source_switch(struct work_struct *work) * deassert and reassert, and hope for the best. * see http://dev.laptop.org/ticket/9664 */ - delta_t = timespec_sub(dcon_irq_time, dcon_load_time); - if (dcon_switched && delta_t.tv_sec == 0 && + delta_t = timespec_sub(dcon->irq_time, dcon->load_time); + if (dcon->switched && delta_t.tv_sec == 0 && delta_t.tv_nsec < NSEC_PER_MSEC * 20) { printk(KERN_ERR "olpc-dcon: missed loading, retrying\n"); pdata->set_dconload(1); mdelay(41); pdata->set_dconload(0); - getnstimeofday(&dcon_load_time); + getnstimeofday(&dcon->load_time); mdelay(41); } } @@ -815,8 +810,8 @@ irqreturn_t dcon_interrupt(int irq, void *id) case 2: /* switch to DCON mode */ case 1: /* switch to CPU mode */ - dcon_switched = 1; - getnstimeofday(&dcon_irq_time); + dcon->switched = true; + getnstimeofday(&dcon->irq_time); wake_up(&dcon_wait_queue); break; @@ -828,9 +823,9 @@ irqreturn_t dcon_interrupt(int irq, void *id) * of the DCON happened long before this point. * see http://dev.laptop.org/ticket/9869 */ - if (dcon->curr_src != dcon->pending_src && !dcon_switched) { - dcon_switched = 1; - getnstimeofday(&dcon_irq_time); + if (dcon->curr_src != dcon->pending_src && !dcon->switched) { + dcon->switched = true; + getnstimeofday(&dcon->irq_time); wake_up(&dcon_wait_queue); printk(KERN_DEBUG "olpc-dcon: switching w/ status 0/0\n"); } else { diff --git a/drivers/staging/olpc_dcon/olpc_dcon.h b/drivers/staging/olpc_dcon/olpc_dcon.h index 2c06e1915c3f..62bed461d582 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.h +++ b/drivers/staging/olpc_dcon/olpc_dcon.h @@ -64,6 +64,11 @@ struct dcon_priv { /* Desired source */ int pending_src; + /* Variables used during switches */ + bool switched; + struct timespec irq_time; + struct timespec load_time; + /* Current output type; true == mono, false == color */ bool mono; bool asleep; -- cgit v1.2.3 From c59eef17f1cc21a984cf077ad45a8355781881b6 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Thu, 10 Feb 2011 17:56:27 -0800 Subject: staging: olpc_dcon: clean up backlight handling - Move bl_val and bl_dev into dcon_priv struct.... - The only time we ever read the backlight val from the dcon is at probe time. Rather than calling dcon_get_backlight for that, just read from the register. - Drop dcon_get_backlight; it's just returning dcon->bl_val. - Rename dcon_set_backlight_hw to dcon_set_backlight, and drop the old dcon_set_backlight function. Move contents of old dcon_set_backlight function into dconbl_set. - Shuffle backlight_ops callbacks around to be closer to struct, and rename them. - Make use of new backlight_properties arg to backlight_device_register, drop old code that set this manually. Signed-off-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon.c | 113 +++++++++++++--------------------- drivers/staging/olpc_dcon/olpc_dcon.h | 4 ++ 2 files changed, 47 insertions(+), 70 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 07abdfa4ad48..b90c2cf3e247 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -50,9 +50,6 @@ static struct dcon_platform_data *pdata; /* Platform devices */ static struct platform_device *dcon_device; -/* Backlight device */ -static struct backlight_device *dcon_bl_dev; - static DECLARE_WAIT_QUEUE_HEAD(dcon_wait_queue); static unsigned short normal_i2c[] = { 0x0d, I2C_CLIENT_END }; @@ -67,9 +64,6 @@ static s32 dcon_read(struct dcon_priv *dcon, u8 reg) return i2c_smbus_read_word_data(dcon->client, reg); } -/* The current backlight value - this saves us some smbus traffic */ -static int bl_val = -1; - /* ===== API functions - these are called by a variety of users ==== */ static int dcon_hw_init(struct dcon_priv *dcon, int is_init) @@ -185,25 +179,13 @@ power_up: return 0; } -static int dcon_get_backlight(struct dcon_priv *dcon) +static void dcon_set_backlight(struct dcon_priv *dcon, u8 level) { - if (!dcon || !dcon->client) - return 0; - - if (bl_val == -1) - bl_val = dcon_read(dcon, DCON_REG_BRIGHT) & 0x0F; - - return bl_val; -} - - -static void dcon_set_backlight_hw(struct dcon_priv *dcon, int level) -{ - bl_val = level & 0x0F; - dcon_write(dcon, DCON_REG_BRIGHT, bl_val); + dcon->bl_val = level; + dcon_write(dcon, DCON_REG_BRIGHT, dcon->bl_val); /* Purposely turn off the backlight when we go to level 0 */ - if (bl_val == 0) { + if (dcon->bl_val == 0) { dcon->disp_mode &= ~MODE_BL_ENABLE; dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode); } else if (!(dcon->disp_mode & MODE_BL_ENABLE)) { @@ -212,17 +194,6 @@ static void dcon_set_backlight_hw(struct dcon_priv *dcon, int level) } } -static void dcon_set_backlight(struct dcon_priv *dcon, int level) -{ - if (!dcon || !dcon->client) - return; - - if (bl_val == (level & 0x0F)) - return; - - dcon_set_backlight_hw(dcon, level); -} - /* Set the output type to either color or mono */ static int dcon_set_mono_mode(struct dcon_priv *dcon, bool enable_mono) { @@ -271,7 +242,7 @@ static void dcon_sleep(struct dcon_priv *dcon, bool sleep) dcon->asleep = sleep; } else { /* Only re-enable the backlight if the backlight value is set */ - if (bl_val != 0) + if (dcon->bl_val != 0) dcon->disp_mode |= MODE_BL_ENABLE; x = dcon_bus_stabilize(dcon, 1); if (x) @@ -281,7 +252,7 @@ static void dcon_sleep(struct dcon_priv *dcon, bool sleep) dcon->asleep = sleep; /* Restore backlight */ - dcon_set_backlight_hw(dcon, bl_val); + dcon_set_backlight(dcon, dcon->bl_val); } /* We should turn off some stuff in the framebuffer - but what? */ @@ -458,24 +429,6 @@ static void dcon_set_source_sync(struct dcon_priv *dcon, int arg) flush_scheduled_work(); } -static int dconbl_set(struct backlight_device *dev) -{ - struct dcon_priv *dcon = bl_get_data(dev); - int level = dev->props.brightness; - - if (dev->props.power != FB_BLANK_UNBLANK) - level = 0; - - dcon_set_backlight(dcon, level); - return 0; -} - -static int dconbl_get(struct backlight_device *dev) -{ - struct dcon_priv *dcon = bl_get_data(dev); - return dcon_get_backlight(dcon); -} - static ssize_t dcon_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -594,11 +547,35 @@ static struct device_attribute dcon_device_files[] = { __ATTR(resumeline, 0644, dcon_resumeline_show, dcon_resumeline_store), }; +static int dcon_bl_update(struct backlight_device *dev) +{ + struct dcon_priv *dcon = bl_get_data(dev); + u8 level = dev->props.brightness & 0x0F; + + if (dev->props.power != FB_BLANK_UNBLANK) + level = 0; + + if (level != dcon->bl_val) + dcon_set_backlight(dcon, level); + + return 0; +} + +static int dcon_bl_get(struct backlight_device *dev) +{ + struct dcon_priv *dcon = bl_get_data(dev); + return dcon->bl_val; +} + static const struct backlight_ops dcon_bl_ops = { - .get_brightness = dconbl_get, - .update_status = dconbl_set + .update_status = dcon_bl_update, + .get_brightness = dcon_bl_get, }; +static struct backlight_properties dcon_bl_props = { + .max_brightness = 15, + .power = FB_BLANK_UNBLANK, +}; static int dcon_reboot_notify(struct notifier_block *nb, unsigned long foo, void *bar) @@ -707,20 +684,16 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) } } - /* Add the backlight device for the DCON */ - dcon_bl_dev = backlight_device_register("dcon-bl", &dcon_device->dev, - dcon, &dcon_bl_ops, NULL); - - if (IS_ERR(dcon_bl_dev)) { - printk(KERN_ERR "Cannot register the backlight device (%ld)\n", - PTR_ERR(dcon_bl_dev)); - dcon_bl_dev = NULL; - } else { - dcon_bl_dev->props.max_brightness = 15; - dcon_bl_dev->props.power = FB_BLANK_UNBLANK; - dcon_bl_dev->props.brightness = dcon_get_backlight(dcon); + dcon->bl_val = dcon_read(dcon, DCON_REG_BRIGHT) & 0x0F; - backlight_update_status(dcon_bl_dev); + /* Add the backlight device for the DCON */ + dcon_bl_props.brightness = dcon->bl_val; + dcon->bl_dev = backlight_device_register("dcon-bl", &dcon_device->dev, + dcon, &dcon_bl_ops, &dcon_bl_props); + if (IS_ERR(dcon->bl_dev)) { + dev_err(&client->dev, "cannot register backlight dev (%ld)\n", + PTR_ERR(dcon->bl_dev)); + dcon->bl_dev = NULL; } register_reboot_notifier(&dcon->reboot_nb); @@ -755,8 +728,8 @@ static int dcon_remove(struct i2c_client *client) free_irq(DCON_IRQ, dcon); - if (dcon_bl_dev != NULL) - backlight_device_unregister(dcon_bl_dev); + if (dcon->bl_dev) + backlight_device_unregister(dcon->bl_dev); if (dcon_device != NULL) platform_device_unregister(dcon_device); diff --git a/drivers/staging/olpc_dcon/olpc_dcon.h b/drivers/staging/olpc_dcon/olpc_dcon.h index 62bed461d582..0264c94375aa 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.h +++ b/drivers/staging/olpc_dcon/olpc_dcon.h @@ -50,6 +50,7 @@ struct dcon_priv { struct i2c_client *client; struct fb_info *fbinfo; + struct backlight_device *bl_dev; struct work_struct switch_source; struct notifier_block reboot_nb; @@ -58,6 +59,9 @@ struct dcon_priv { /* Shadow register for the DCON_REG_MODE register */ u8 disp_mode; + /* The current backlight value - this saves us some smbus traffic */ + u8 bl_val; + /* Current source, initialized at probe time */ int curr_src; -- cgit v1.2.3 From b07b846c333708ce2b95b5cd2a86f51a74331d02 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Thu, 10 Feb 2011 17:56:38 -0800 Subject: staging: olpc_dcon: drop CONFIG_BROKEN dependency DCON builds properly now; we can drop the config dep on CONFIG_BROKEN. Signed-off-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/Kconfig b/drivers/staging/olpc_dcon/Kconfig index 982273cf354f..acb0a79a949a 100644 --- a/drivers/staging/olpc_dcon/Kconfig +++ b/drivers/staging/olpc_dcon/Kconfig @@ -1,6 +1,6 @@ config FB_OLPC_DCON tristate "One Laptop Per Child Display CONtroller support" - depends on OLPC && BROKEN + depends on OLPC select I2C ---help--- Add support for the OLPC XO DCON controller. This controller is -- cgit v1.2.3 From 539874106471819d4b6e52d06e14a0c3b0770a3b Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Fri, 11 Feb 2011 08:43:34 +0900 Subject: staging: rtl8192e: Remove unused tx_lock spin lock Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 1 - drivers/staging/rtl8192e/r8192E_core.c | 7 ------- drivers/staging/rtl8192e/r819xE_cmdpkt.c | 2 -- 3 files changed, 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 81aea8816d35..33db522286df 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -807,7 +807,6 @@ typedef struct r8192_priv u8 Rf_Mode; u8 card_8192_version; /* if TCR reports card V B/C this discriminates */ spinlock_t irq_th_lock; - spinlock_t tx_lock; spinlock_t rf_ps_lock; struct mutex mutex; spinlock_t ps_lock; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 630b1c7c8e72..613fbe4508ba 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -2116,7 +2116,6 @@ static void rtl8192_init_priv_variable(struct net_device* dev) static void rtl8192_init_priv_lock(struct r8192_priv* priv) { - spin_lock_init(&priv->tx_lock); spin_lock_init(&priv->irq_th_lock); spin_lock_init(&priv->rf_ps_lock); spin_lock_init(&priv->ps_lock); @@ -3000,12 +2999,10 @@ static void rtl8192_prepare_beacon(unsigned long arg) { struct r8192_priv *priv = (struct r8192_priv*) arg; struct sk_buff *skb; - //unsigned long flags; cb_desc *tcb_desc; skb = ieee80211_get_beacon(priv->ieee80211); tcb_desc = (cb_desc *)(skb->cb + 8); - //spin_lock_irqsave(&priv->tx_lock,flags); /* prepare misc info for the beacon xmit */ tcb_desc->queue_index = BEACON_QUEUE; /* IBSS does not support HT yet, use 1M defaultly */ @@ -3018,7 +3015,6 @@ static void rtl8192_prepare_beacon(unsigned long arg) if(skb){ rtl8192_tx(priv->ieee80211->dev,skb); } - //spin_unlock_irqrestore (&priv->tx_lock, flags); } @@ -3747,7 +3743,6 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) struct net_device *dev = priv->ieee80211->dev; struct ieee80211_device* ieee = priv->ieee80211; RESET_TYPE ResetType = RESET_TYPE_NORESET; - unsigned long flags; bool bBusyTraffic = false; bool bEnterPS = false; @@ -3840,14 +3835,12 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) ieee->LinkDetectInfo.NumRecvDataInPeriod=0; //check if reset the driver - spin_lock_irqsave(&priv->tx_lock,flags); if (priv->watchdog_check_reset_cnt++ >= 3 && !ieee->is_roaming && priv->watchdog_last_time != 1) { ResetType = rtl819x_ifcheck_resetornot(dev); priv->watchdog_check_reset_cnt = 3; } - spin_unlock_irqrestore(&priv->tx_lock,flags); if(!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL) { priv->ResetProgress = RESET_TYPE_NORMAL; diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.c b/drivers/staging/rtl8192e/r819xE_cmdpkt.c index ef6f2deb3049..d5e1e7ee7c52 100644 --- a/drivers/staging/rtl8192e/r819xE_cmdpkt.c +++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.c @@ -52,7 +52,6 @@ RT_STATUS cmpk_message_handle_tx( PTX_FWINFO_8190PCI pTxFwInfo = NULL; int i; - //spin_lock_irqsave(&priv->tx_lock,flags); RT_TRACE(COMP_CMDPKT,"%s(),buffer_len is %d\n",__FUNCTION__,buffer_len); firmware_init_param(dev); //Fragmentation might be required @@ -113,7 +112,6 @@ RT_STATUS cmpk_message_handle_tx( }while(frag_offset < buffer_len); Failed: - //spin_unlock_irqrestore(&priv->tx_lock,flags); return rt_status; } -- cgit v1.2.3 From 4bbedb27d24e1f262ef3234f3faee5af0831ddb1 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Fri, 11 Feb 2011 08:43:44 +0900 Subject: staging: rtl8192e: Remove irq_enabled flag Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 1 - drivers/staging/rtl8192e/r8192E_core.c | 8 +------- 2 files changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 33db522286df..92ecfc24b74d 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -796,7 +796,6 @@ typedef struct r8192_priv LED_STRATEGY_8190 LedStrategy; u8 IC_Cut; int irq; - short irq_enabled; struct ieee80211_device *ieee80211; #ifdef ENABLE_LPS bool ps_force; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 613fbe4508ba..185d3903073d 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -658,7 +658,6 @@ static void tx_timeout(struct net_device *dev) static void rtl8192_irq_enable(struct net_device *dev) { struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - priv->irq_enabled = 1; write_nic_dword(priv, INTA_MASK, priv->irq_mask); } @@ -667,7 +666,7 @@ void rtl8192_irq_disable(struct net_device *dev) struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); write_nic_dword(priv, INTA_MASK, 0); - priv->irq_enabled = 0; + synchronize_irq(dev->irq); } void rtl8192_update_msr(struct net_device *dev) @@ -2003,7 +2002,6 @@ static void rtl8192_init_priv_variable(struct net_device* dev) priv->txringcount = 64;//32; priv->rxbuffersize = 9100;//2048;//1024; priv->rxringcount = MAX_RX_COUNT;//64; - priv->irq_enabled=0; priv->rx_skb_complete = 1; priv->chan = 1; //set to channel 1 priv->RegWirelessMode = WIRELESS_MODE_AUTO; @@ -5346,10 +5344,6 @@ static irqreturn_t rtl8192_interrupt(int irq, void *netdev) spin_lock_irqsave(&priv->irq_th_lock, flags); - /* We should return IRQ_NONE, but for now let me keep this */ - if (priv->irq_enabled == 0) - goto out_unlock; - /* ISR: 4bytes */ inta = read_nic_dword(priv, ISR); /* & priv->IntrMask; */ -- cgit v1.2.3 From 1b8b4969f59b4c6c426951d3a6ed3881625996f9 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Fri, 11 Feb 2011 08:43:57 +0900 Subject: staging: rtl8192e: Delete unused function rtl819x_ifsilentreset Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 262 --------------------------------- 1 file changed, 262 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 185d3903073d..39f8ca8373d2 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -3231,267 +3231,6 @@ rtl819x_ifcheck_resetornot(struct net_device *dev) } - -static void CamRestoreAllEntry(struct net_device *dev) -{ - u8 EntryId = 0; - struct r8192_priv *priv = ieee80211_priv(dev); - const u8* MacAddr = priv->ieee80211->current_network.bssid; - - static const u8 CAM_CONST_ADDR[4][6] = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}}; - static const u8 CAM_CONST_BROAD[] = - {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - - RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n"); - - - if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)|| - (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104)) - { - - for(EntryId=0; EntryId<4; EntryId++) - { - { - MacAddr = CAM_CONST_ADDR[EntryId]; - setKey(dev, - EntryId , - EntryId, - priv->ieee80211->pairwise_key_type, - MacAddr, - 0, - NULL); - } - } - - } - else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP) - { - - { - if(priv->ieee80211->iw_mode == IW_MODE_ADHOC) - setKey(dev, - 4, - 0, - priv->ieee80211->pairwise_key_type, - (u8*)dev->dev_addr, - 0, - NULL); - else - setKey(dev, - 4, - 0, - priv->ieee80211->pairwise_key_type, - MacAddr, - 0, - NULL); - } - } - else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP) - { - - { - if(priv->ieee80211->iw_mode == IW_MODE_ADHOC) - setKey(dev, - 4, - 0, - priv->ieee80211->pairwise_key_type, - (u8*)dev->dev_addr, - 0, - NULL); - else - setKey(dev, - 4, - 0, - priv->ieee80211->pairwise_key_type, - MacAddr, - 0, - NULL); - } - } - - - - if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP) - { - MacAddr = CAM_CONST_BROAD; - for(EntryId=1 ; EntryId<4 ; EntryId++) - { - { - setKey(dev, - EntryId, - EntryId, - priv->ieee80211->group_key_type, - MacAddr, - 0, - NULL); - } - } - if(priv->ieee80211->iw_mode == IW_MODE_ADHOC) - setKey(dev, - 0, - 0, - priv->ieee80211->group_key_type, - CAM_CONST_ADDR[0], - 0, - NULL); - } - else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP) - { - MacAddr = CAM_CONST_BROAD; - for(EntryId=1; EntryId<4 ; EntryId++) - { - { - setKey(dev, - EntryId , - EntryId, - priv->ieee80211->group_key_type, - MacAddr, - 0, - NULL); - } - } - - if(priv->ieee80211->iw_mode == IW_MODE_ADHOC) - setKey(dev, - 0 , - 0, - priv->ieee80211->group_key_type, - CAM_CONST_ADDR[0], - 0, - NULL); - } -} - -/* - * This function is used to fix Tx/Rx stop bug temporarily. - * This function will do "system reset" to NIC when Tx or Rx is stuck. - * The method checking Tx/Rx stuck of this function is supported by FW, - * which reports Tx and Rx counter to register 0x128 and 0x130. - */ -static void rtl819x_ifsilentreset(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u8 reset_times = 0; - int reset_status = 0; - struct ieee80211_device *ieee = priv->ieee80211; - - - return; - - // 2007.07.20. If we need to check CCK stop, please uncomment this line. - //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter); - - if(priv->ResetProgress==RESET_TYPE_NORESET) - { -RESET_START: -#ifdef ENABLE_LPS - //LZM for PS-Poll AID issue. 090429 - if(priv->ieee80211->state == IEEE80211_LINKED) - LeisurePSLeave(dev); -#endif - - RT_TRACE(COMP_RESET,"=========>Reset progress!! \n"); - - // Set the variable for reset. - priv->ResetProgress = RESET_TYPE_SILENT; -// rtl8192_close(dev); - - down(&priv->wx_sem); - if(priv->up == 0) - { - RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__); - up(&priv->wx_sem); - return ; - } - priv->up = 0; - RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__); - if(!netif_queue_stopped(dev)) - netif_stop_queue(dev); - - dm_backup_dynamic_mechanism_state(dev); - - rtl8192_irq_disable(dev); - rtl8192_cancel_deferred_work(priv); - deinit_hal_dm(dev); - del_timer_sync(&priv->watch_dog_timer); - ieee->sync_scan_hurryup = 1; - if(ieee->state == IEEE80211_LINKED) - { - down(&ieee->wx_sem); - printk("ieee->state is IEEE80211_LINKED\n"); - ieee80211_stop_send_beacons(priv->ieee80211); - del_timer_sync(&ieee->associate_timer); - cancel_delayed_work(&ieee->associate_retry_wq); - ieee80211_stop_scan(ieee); - up(&ieee->wx_sem); - } - else{ - printk("ieee->state is NOT LINKED\n"); - ieee80211_softmac_stop_protocol(priv->ieee80211,true); - } - rtl8192_halt_adapter(dev, true); - up(&priv->wx_sem); - RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__); - RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__); - reset_status = _rtl8192_up(dev); - - RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__); - if(reset_status == -1) - { - if(reset_times < 3) - { - reset_times++; - goto RESET_START; - } - else - { - RT_TRACE(COMP_ERR," ERR!!! %s(): Reset Failed!!\n",__FUNCTION__); - } - } - ieee->is_silent_reset = 1; - EnableHWSecurityConfig8192(dev); - if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA) - { - ieee->set_chan(ieee->dev, ieee->current_network.channel); - - queue_work(ieee->wq, &ieee->associate_complete_wq); - - } - else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC) - { - ieee->set_chan(ieee->dev, ieee->current_network.channel); - ieee->link_change(ieee->dev); - - // notify_wx_assoc_event(ieee); - - ieee80211_start_send_beacons(ieee); - - if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); - netif_carrier_on(ieee->dev); - } - - CamRestoreAllEntry(dev); - - // Restore the previous setting for all dynamic mechanism - dm_restore_dynamic_mechanism_state(dev); - - priv->ResetProgress = RESET_TYPE_NORESET; - priv->reset_count++; - - priv->bForcedSilentReset =false; - priv->bResetInProgress = false; - - // For test --> force write UFWP. - write_nic_byte(priv, UFWP, 1); - RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count); - } -} - #ifdef ENABLE_IPS void InactivePsWorkItemCallback(struct net_device *dev) { @@ -3850,7 +3589,6 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) if( ((priv->force_reset) || (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT))) // This is control by OID set in Pomelo { priv->watchdog_last_time = 1; - rtl819x_ifsilentreset(dev); } else priv->watchdog_last_time = 0; -- cgit v1.2.3 From 2b1a26f8d34d67104d634acc0799960ddad803ca Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Fri, 11 Feb 2011 08:44:09 +0900 Subject: staging: rtl8192e: Enable the NIC only once Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8190_rtl8256.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index 4af8f12bad66..db7050517931 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -339,19 +339,15 @@ SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) case eRfOn: // turn on RF - if((priv->ieee80211->eRFPowerState == eRfOff) && RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) - { // The current RF state is OFF and the RF OFF level is halting the NIC, re-initialize the NIC. - bool rtstatus = true; - u32 InitializeCount = 3; - do - { - InitializeCount--; - rtstatus = NicIFEnableNIC(dev); - }while( (rtstatus != true) &&(InitializeCount >0) ); - - if(rtstatus != true) - { - RT_TRACE(COMP_ERR,"%s():Initialize Adapter fail,return\n",__FUNCTION__); + if ((priv->ieee80211->eRFPowerState == eRfOff) && + RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) + { + /* + * The current RF state is OFF and the RF OFF level + * is halting the NIC, re-initialize the NIC. + */ + if (!NicIFEnableNIC(dev)) { + RT_TRACE(COMP_ERR, "%s(): NicIFEnableNIC failed\n",__FUNCTION__); priv->SetRFPowerStateInProgress = false; return false; } -- cgit v1.2.3 From 3b10c0a4685d95532bdc7b2e865ace808d66295c Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Fri, 11 Feb 2011 08:44:29 +0900 Subject: staging: rtl8192e: Make rtl8192_tx static Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 1 - drivers/staging/rtl8192e/r8192E_core.c | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 92ecfc24b74d..f25e97542660 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1039,7 +1039,6 @@ typedef struct r8192_priv }r8192_priv; bool init_firmware(struct net_device *dev); -short rtl8192_tx(struct net_device *dev, struct sk_buff* skb); u32 read_cam(struct r8192_priv *priv, u8 addr); void write_cam(struct r8192_priv *priv, u8 addr, u32 data); u8 read_nic_byte(struct r8192_priv *priv, int x); diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 39f8ca8373d2..1b0cd9eac5d3 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -109,6 +109,7 @@ static void rtl8192_restart(struct work_struct *work); static void watch_dog_timer_callback(unsigned long data); static int _rtl8192_up(struct net_device *dev); static void rtl8192_cancel_deferred_work(struct r8192_priv* priv); +static short rtl8192_tx(struct net_device *dev, struct sk_buff* skb); #ifdef ENABLE_DOT11D @@ -1255,7 +1256,7 @@ static u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc) * skb->cb will contain all the following information, * priority, morefrag, rate, &dev. */ -short rtl8192_tx(struct net_device *dev, struct sk_buff* skb) +static short rtl8192_tx(struct net_device *dev, struct sk_buff* skb) { struct r8192_priv *priv = ieee80211_priv(dev); struct rtl8192_tx_ring *ring; -- cgit v1.2.3 From 18c53dfe0311b6db7845a53a02985d363de77f86 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Fri, 11 Feb 2011 08:44:44 +0900 Subject: staging: rtl8192e: Remove useless TxCheckStuck function Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 56 ---------------------------------- 1 file changed, 56 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 1b0cd9eac5d3..d6af0b6b8e13 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -3069,60 +3069,6 @@ static void rtl8192_start_beacon(struct net_device *dev) rtl8192_irq_enable(dev); } -static bool HalTxCheckStuck8190Pci(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u16 RegTxCounter = read_nic_word(priv, 0x128); - bool bStuck = FALSE; - RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter); - if(priv->TxCounter==RegTxCounter) - bStuck = TRUE; - - priv->TxCounter = RegTxCounter; - - return bStuck; -} - -/* - * Assumption: RT_TX_SPINLOCK is acquired. - */ -static RESET_TYPE -TxCheckStuck(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - u8 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE; - bool bCheckFwTxCnt = false; - - // - // Decide Stuch threshold according to current power save mode - // - switch (priv->ieee80211->dot11PowerSaveMode) - { - // The threshold value may required to be adjusted . - case eActive: // Active/Continuous access. - ResetThreshold = NIC_SEND_HANG_THRESHOLD_NORMAL; - break; - case eMaxPs: // Max power save mode. - ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE; - break; - case eFastPs: // Fast power save mode. - ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE; - break; - } - - if(bCheckFwTxCnt) - { - if(HalTxCheckStuck8190Pci(dev)) - { - RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n"); - return RESET_TYPE_SILENT; - } - } - - return RESET_TYPE_NORESET; -} - - static bool HalRxCheckStuck8190Pci(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); @@ -3205,8 +3151,6 @@ rtl819x_ifcheck_resetornot(struct net_device *dev) rfState = priv->ieee80211->eRFPowerState; - TxResetType = TxCheckStuck(dev); - if( rfState != eRfOff && /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/ (priv->ieee80211->iw_mode != IW_MODE_ADHOC)) -- cgit v1.2.3 From 48f0210695ebe021b6477047794b1f004819855c Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Fri, 11 Feb 2011 08:45:03 +0900 Subject: staging: rtl8192e: rf_ps_lock doesn't need to be IRQ safe Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8190_rtl8256.c | 11 +++++------ drivers/staging/rtl8192e/r8192E_core.c | 14 ++++++-------- 2 files changed, 11 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index db7050517931..7896d23c4e20 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -716,7 +716,6 @@ MgntActSet_RF_State( bool bConnectBySSID = false; RT_RF_POWER_STATE rtState; u16 RFWaitCounter = 0; - unsigned long flag; RT_TRACE(COMP_POWER, "===>MgntActSet_RF_State(): StateToSet(%d)\n",StateToSet); //1// @@ -726,10 +725,10 @@ MgntActSet_RF_State( while(true) { - spin_lock_irqsave(&priv->rf_ps_lock,flag); + spin_lock(&priv->rf_ps_lock); if(priv->RFChangeInProgress) { - spin_unlock_irqrestore(&priv->rf_ps_lock,flag); + spin_unlock(&priv->rf_ps_lock); RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): RF Change in progress! Wait to set..StateToSet(%d).\n", StateToSet); // Set RF after the previous action is done. @@ -751,7 +750,7 @@ MgntActSet_RF_State( else { priv->RFChangeInProgress = true; - spin_unlock_irqrestore(&priv->rf_ps_lock,flag); + spin_unlock(&priv->rf_ps_lock); break; } } @@ -809,9 +808,9 @@ MgntActSet_RF_State( } // Release RF spinlock - spin_lock_irqsave(&priv->rf_ps_lock,flag); + spin_lock(&priv->rf_ps_lock); priv->RFChangeInProgress = false; - spin_unlock_irqrestore(&priv->rf_ps_lock,flag); + spin_unlock(&priv->rf_ps_lock); RT_TRACE(COMP_POWER, "<===MgntActSet_RF_State()\n"); return bActionAllowed; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index d6af0b6b8e13..f7fee51f8349 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1892,16 +1892,15 @@ short rtl8192_is_tx_queue_empty(struct net_device *dev) static void rtl8192_hw_sleep_down(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); - unsigned long flags = 0; - spin_lock_irqsave(&priv->rf_ps_lock,flags); + spin_lock(&priv->rf_ps_lock); if (priv->RFChangeInProgress) { - spin_unlock_irqrestore(&priv->rf_ps_lock,flags); + spin_unlock(&priv->rf_ps_lock); RT_TRACE(COMP_RF, "rtl8192_hw_sleep_down(): RF Change in progress! \n"); printk("rtl8192_hw_sleep_down(): RF Change in progress!\n"); return; } - spin_unlock_irqrestore(&priv->rf_ps_lock,flags); + spin_unlock(&priv->rf_ps_lock); MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS); } @@ -1918,17 +1917,16 @@ static void rtl8192_hw_sleep_wq (struct work_struct *work) static void rtl8192_hw_wakeup(struct net_device* dev) { struct r8192_priv *priv = ieee80211_priv(dev); - unsigned long flags = 0; - spin_lock_irqsave(&priv->rf_ps_lock,flags); + spin_lock(&priv->rf_ps_lock); if (priv->RFChangeInProgress) { - spin_unlock_irqrestore(&priv->rf_ps_lock,flags); + spin_unlock(&priv->rf_ps_lock); RT_TRACE(COMP_RF, "rtl8192_hw_wakeup(): RF Change in progress! \n"); printk("rtl8192_hw_wakeup(): RF Change in progress! schedule wake up task again\n"); queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->hw_wakeup_wq,MSECS(10));//PowerSave is not supported if kernel version is below 2.6.20 return; } - spin_unlock_irqrestore(&priv->rf_ps_lock,flags); + spin_unlock(&priv->rf_ps_lock); MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS); } -- cgit v1.2.3 From 4573d1459ce7e877b16800538ef57c95c759083b Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Fri, 11 Feb 2011 08:45:27 +0900 Subject: staging: rtl8192e: Refactor rtl8192_ioctl into two functions Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 136 ++++++++++++++++----------------- 1 file changed, 68 insertions(+), 68 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index f7fee51f8349..e4ffa24c935a 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -3706,15 +3706,75 @@ static int r8192_set_mac_adr(struct net_device *dev, void *mac) return 0; } +static void r8192e_set_hw_key(struct r8192_priv *priv, struct ieee_param *ipw) +{ + struct ieee80211_device *ieee = priv->ieee80211; + struct net_device *dev = priv->ieee80211->dev; + u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; + u32 key[4]; + + if (ipw->u.crypt.set_tx) { + if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) + ieee->pairwise_key_type = KEY_TYPE_CCMP; + else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) + ieee->pairwise_key_type = KEY_TYPE_TKIP; + else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) { + if (ipw->u.crypt.key_len == 13) + ieee->pairwise_key_type = KEY_TYPE_WEP104; + else if (ipw->u.crypt.key_len == 5) + ieee->pairwise_key_type = KEY_TYPE_WEP40; + } else + ieee->pairwise_key_type = KEY_TYPE_NA; + + if (ieee->pairwise_key_type) { + memcpy(key, ipw->u.crypt.key, 16); + EnableHWSecurityConfig8192(dev); + /* + * We fill both index entry and 4th entry for pairwise + * key as in IPW interface, adhoc will only get here, + * so we need index entry for its default key serching! + */ + setKey(dev, 4, ipw->u.crypt.idx, + ieee->pairwise_key_type, + (u8*)ieee->ap_mac_addr, 0, key); + + /* LEAP WEP will never set this. */ + if (ieee->auth_mode != 2) + setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, + ieee->pairwise_key_type, + (u8*)ieee->ap_mac_addr, 0, key); + } + if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && + ieee->pHTInfo->bCurrentHTSupport) { + write_nic_byte(priv, 0x173, 1); /* fix aes bug */ + } + } else { + memcpy(key, ipw->u.crypt.key, 16); + if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) + ieee->group_key_type= KEY_TYPE_CCMP; + else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) + ieee->group_key_type = KEY_TYPE_TKIP; + else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) { + if (ipw->u.crypt.key_len == 13) + ieee->group_key_type = KEY_TYPE_WEP104; + else if (ipw->u.crypt.key_len == 5) + ieee->group_key_type = KEY_TYPE_WEP40; + } else + ieee->group_key_type = KEY_TYPE_NA; + + if (ieee->group_key_type) { + setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, + ieee->group_key_type, broadcast_addr, 0, key); + } + } +} + /* based on ipw2200 driver */ static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); struct iwreq *wrq = (struct iwreq *)rq; int ret=-1; - struct ieee80211_device *ieee = priv->ieee80211; - u32 key[4]; - u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; struct iw_point *p = &wrq->u.data; struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer; @@ -3738,74 +3798,14 @@ static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } switch (cmd) { - case RTL_IOCTL_WPA_SUPPLICANT: - //parse here for HW security - if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION) - { - if (ipw->u.crypt.set_tx) - { - if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) - ieee->pairwise_key_type = KEY_TYPE_CCMP; - else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) - ieee->pairwise_key_type = KEY_TYPE_TKIP; - else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) - { - if (ipw->u.crypt.key_len == 13) - ieee->pairwise_key_type = KEY_TYPE_WEP104; - else if (ipw->u.crypt.key_len == 5) - ieee->pairwise_key_type = KEY_TYPE_WEP40; - } - else - ieee->pairwise_key_type = KEY_TYPE_NA; - - if (ieee->pairwise_key_type) - { - memcpy((u8*)key, ipw->u.crypt.key, 16); - EnableHWSecurityConfig8192(dev); - //we fill both index entry and 4th entry for pairwise key as in IPW interface, adhoc will only get here, so we need index entry for its default key serching! - //added by WB. - setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key); - if (ieee->auth_mode != 2) //LEAP WEP will never set this. - setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key); - } - if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){ - write_nic_byte(priv, 0x173, 1); //fix aes bug - } - - } - else //if (ipw->u.crypt.idx) //group key use idx > 0 - { - memcpy((u8*)key, ipw->u.crypt.key, 16); - if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) - ieee->group_key_type= KEY_TYPE_CCMP; - else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) - ieee->group_key_type = KEY_TYPE_TKIP; - else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) - { - if (ipw->u.crypt.key_len == 13) - ieee->group_key_type = KEY_TYPE_WEP104; - else if (ipw->u.crypt.key_len == 5) - ieee->group_key_type = KEY_TYPE_WEP40; - } - else - ieee->group_key_type = KEY_TYPE_NA; - - if (ieee->group_key_type) - { - setKey( dev, - ipw->u.crypt.idx, - ipw->u.crypt.idx, //KeyIndex - ieee->group_key_type, //KeyType - broadcast_addr, //MacAddr - 0, //DefaultKey - key); //KeyContent - } - } - } + case RTL_IOCTL_WPA_SUPPLICANT: + /* parse here for HW security */ + if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION) + r8192e_set_hw_key(priv, ipw); ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data); break; - default: + default: ret = -EOPNOTSUPP; break; } -- cgit v1.2.3 From 0cfc618531e68e27339ff93371da8f2c15418851 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Fri, 11 Feb 2011 08:45:45 +0900 Subject: staging: rtl8192e: Don't disable interrupts in mgmt_tx_lock Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8192e/ieee80211/ieee80211_softmac.c | 25 +++++++++++----------- drivers/staging/rtl8192e/r8192E_core.c | 6 ++---- 2 files changed, 14 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index a684743da213..2640a4f2e81f 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -249,7 +249,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee spin_unlock_irqrestore(&ieee->lock, flags); }else{ spin_unlock_irqrestore(&ieee->lock, flags); - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags); + spin_lock(&ieee->mgmt_tx_lock); header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); @@ -270,7 +270,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee } else { ieee->softmac_hard_start_xmit(skb,ieee->dev); } - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags); + spin_unlock(&ieee->mgmt_tx_lock); } } @@ -1830,8 +1830,7 @@ inline void ieee80211_sta_ps(struct ieee80211_device *ieee) u32 th,tl; short sleep; - - unsigned long flags,flags2; + unsigned long flags; spin_lock_irqsave(&ieee->lock, flags); @@ -1842,11 +1841,11 @@ inline void ieee80211_sta_ps(struct ieee80211_device *ieee) // #warning CHECK_LOCK_HERE printk("=====>%s(): no need to ps,wake up!! ieee->ps is %d,ieee->iw_mode is %d,ieee->state is %d\n", __FUNCTION__,ieee->ps,ieee->iw_mode,ieee->state); - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); + spin_lock(&ieee->mgmt_tx_lock); ieee80211_sta_wakeup(ieee, 1); - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); + spin_unlock(&ieee->mgmt_tx_lock); } sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl); @@ -1861,7 +1860,7 @@ inline void ieee80211_sta_ps(struct ieee80211_device *ieee) } else if(ieee->sta_sleep == 0){ - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); + spin_lock(&ieee->mgmt_tx_lock); if(ieee->ps_is_queue_empty(ieee->dev)){ ieee->sta_sleep = 2; @@ -1870,18 +1869,18 @@ inline void ieee80211_sta_ps(struct ieee80211_device *ieee) ieee->ps_th = th; ieee->ps_tl = tl; } - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); + spin_unlock(&ieee->mgmt_tx_lock); } ieee->bAwakePktSent = false;//after null to power save we set it to false. not listen every beacon. }else if(sleep == 2){ - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); + spin_lock(&ieee->mgmt_tx_lock); ieee80211_sta_wakeup(ieee,1); - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); + spin_unlock(&ieee->mgmt_tx_lock); } out: @@ -1933,7 +1932,7 @@ void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl) void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success) { - unsigned long flags,flags2; + unsigned long flags; spin_lock_irqsave(&ieee->lock, flags); @@ -1946,7 +1945,7 @@ void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success) } else {/* 21112005 - tx again null without PS bit if lost */ if((ieee->sta_sleep == 0) && !success){ - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); + spin_lock(&ieee->mgmt_tx_lock); //ieee80211_sta_ps_send_null_frame(ieee, 0); if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING) { @@ -1956,7 +1955,7 @@ void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success) { ieee80211_sta_ps_send_pspoll_frame(ieee); } - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); + spin_unlock(&ieee->mgmt_tx_lock); } } spin_unlock_irqrestore(&ieee->lock, flags); diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index e4ffa24c935a..28eefe5ea663 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -3234,16 +3234,14 @@ bool MgntActSet_802_11_PowerSaveMode(struct net_device *dev, u8 rtPsMode) // Awake immediately if(priv->ieee80211->sta_sleep != 0 && rtPsMode == IEEE80211_PS_DISABLED) { - unsigned long flags; - // Notify the AP we awke. rtl8192_hw_wakeup(dev); priv->ieee80211->sta_sleep = 0; - spin_lock_irqsave(&(priv->ieee80211->mgmt_tx_lock), flags); + spin_lock(&priv->ieee80211->mgmt_tx_lock); printk("LPS leave: notify AP we are awaked ++++++++++ SendNullFunctionData\n"); ieee80211_sta_ps_send_null_frame(priv->ieee80211, 0); - spin_unlock_irqrestore(&(priv->ieee80211->mgmt_tx_lock), flags); + spin_unlock(&priv->ieee80211->mgmt_tx_lock); } return true; -- cgit v1.2.3 From 97a6688aa240e8b72aa5bf6c4a7c2b09bb117342 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Fri, 11 Feb 2011 08:46:14 +0900 Subject: staging: rtl8192e: Remove unused CONFIG_RTL8180_IO_MAP Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 93 +--------------------------------- 1 file changed, 2 insertions(+), 91 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 28eefe5ea663..9b2c07ebf477 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -24,7 +24,7 @@ * Jerry chuang */ -//#define CONFIG_RTL8192_IO_MAP + #include #include #include @@ -209,46 +209,6 @@ u32 read_cam(struct r8192_priv *priv, u8 addr) return read_nic_dword(priv, 0xa8); } -#ifdef CONFIG_RTL8180_IO_MAP - -u8 read_nic_byte(struct r8192_priv *priv, int x) -{ - struct net_device *dev = priv->ieee80211->dev; - return 0xff&inb(dev->base_addr +x); -} - -u32 read_nic_dword(struct r8192_priv *priv, int x) -{ - struct net_device *dev = priv->ieee80211->dev; - return inl(dev->base_addr +x); -} - -u16 read_nic_word(struct r8192_priv *priv, int x) -{ - struct net_device *dev = priv->ieee80211->dev; - return inw(dev->base_addr +x); -} - -void write_nic_byte(struct r8192_priv *priv, int x,u8 y) -{ - struct net_device *dev = priv->ieee80211->dev; - outb(y&0xff,dev->base_addr +x); -} - -void write_nic_word(struct r8192_priv *priv, int x,u16 y) -{ - struct net_device *dev = priv->ieee80211->dev; - outw(y,dev->base_addr +x); -} - -void write_nic_dword(struct r8192_priv *priv, int x,u32 y) -{ - struct net_device *dev = priv->ieee80211->dev; - outl(y,dev->base_addr +x); -} - -#else /* RTL_IO_MAP */ - u8 read_nic_byte(struct r8192_priv *priv, int x) { struct net_device *dev = priv->ieee80211->dev; @@ -288,8 +248,6 @@ void write_nic_word(struct r8192_priv *priv, int x,u16 y) udelay(20); } -#endif /* RTL_IO_MAP */ - u8 rtl8192e_ap_sec_type(struct ieee80211_device *ieee) { static const u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04}; @@ -4744,12 +4702,7 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, struct r8192_priv *priv= NULL; u8 unit = 0; int ret = -ENODEV; - -#ifdef CONFIG_RTL8192_IO_MAP - unsigned long pio_start, pio_len, pio_flags; -#else unsigned long pmem_start, pmem_len, pmem_flags; -#endif //end #ifdef RTL_IO_MAP RT_TRACE(COMP_INIT,"Configuring chip resources"); @@ -4780,28 +4733,6 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, priv->ieee80211->bSupportRemoteWakeUp = 0; } -#ifdef CONFIG_RTL8192_IO_MAP - - pio_start = (unsigned long)pci_resource_start (pdev, 0); - pio_len = (unsigned long)pci_resource_len (pdev, 0); - pio_flags = (unsigned long)pci_resource_flags (pdev, 0); - - if (!(pio_flags & IORESOURCE_IO)) { - RT_TRACE(COMP_ERR,"region #0 not a PIO resource, aborting"); - goto fail; - } - - //DMESG("IO space @ 0x%08lx", pio_start ); - if( ! request_region( pio_start, pio_len, RTL819xE_MODULE_NAME ) ){ - RT_TRACE(COMP_ERR,"request_region failed!"); - goto fail; - } - - ioaddr = pio_start; - dev->base_addr = ioaddr; // device I/O address - -#else - pmem_start = pci_resource_start(pdev, 1); pmem_len = pci_resource_len(pdev, 1); pmem_flags = pci_resource_flags (pdev, 1); @@ -4828,8 +4759,6 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, dev->mem_start = ioaddr; // shared mem start dev->mem_end = ioaddr + pci_resource_len(pdev, 0); // shared mem end -#endif //end #ifdef RTL_IO_MAP - /* We disable the RETRY_TIMEOUT register (0x41) to keep * PCI Tx retries from interfering with C3 CPU state */ pci_write_config_byte(pdev, 0x41, 0x00); @@ -4870,20 +4799,11 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, fail1: -#ifdef CONFIG_RTL8180_IO_MAP - - if( dev->base_addr != 0 ){ - - release_region(dev->base_addr, - pci_resource_len(pdev, 0) ); - } -#else if( dev->mem_start != (unsigned long)NULL ){ iounmap( (void *)dev->mem_start ); release_mem_region( pci_resource_start(pdev, 1), pci_resource_len(pdev, 1) ); } -#endif //end #ifdef RTL_IO_MAP fail: if(dev){ @@ -4957,22 +4877,13 @@ static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev) priv->irq=0; } -#ifdef CONFIG_RTL8180_IO_MAP - - if( dev->base_addr != 0 ){ - - release_region(dev->base_addr, - pci_resource_len(pdev, 0) ); - } -#else if( dev->mem_start != (unsigned long)NULL ){ iounmap( (void *)dev->mem_start ); release_mem_region( pci_resource_start(pdev, 1), pci_resource_len(pdev, 1) ); } -#endif /*end #ifdef RTL_IO_MAP*/ - free_ieee80211(dev); + free_ieee80211(dev); } pci_disable_device(pdev); -- cgit v1.2.3 From 98ab1c9978f706c0ee081335f75636db22723307 Mon Sep 17 00:00:00 2001 From: Krzysztof Hałasa Date: Fri, 11 Feb 2011 13:10:30 +0100 Subject: staging: Solo6x10: accept WxH >= screen dimentions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes it possible to request full resolution (704x576 or 704x480) independently of the color system used (PAL or NTSC). Signed-off-by: Krzysztof Hałasa Signed-off-by: Greg Kroah-Hartman --- drivers/staging/solo6x10/solo6010-v4l2-enc.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/solo6x10/solo6010-v4l2-enc.c b/drivers/staging/solo6x10/solo6010-v4l2-enc.c index 7bbb94097d29..2b3d30b7f9fc 100644 --- a/drivers/staging/solo6x10/solo6010-v4l2-enc.c +++ b/drivers/staging/solo6x10/solo6010-v4l2-enc.c @@ -1034,13 +1034,17 @@ static int solo_enc_try_fmt_cap(struct file *file, void *priv, if (pix->width != solo_enc->width || pix->height != solo_enc->height) return -EBUSY; - } else if (!(pix->width == solo_dev->video_hsize && - pix->height == solo_dev->video_vsize << 1) && - !(pix->width == solo_dev->video_hsize >> 1 && - pix->height == solo_dev->video_vsize)) { + } + + if (pix->width < solo_dev->video_hsize || + pix->height < solo_dev->video_vsize << 1) { /* Default to CIF 1/2 size */ pix->width = solo_dev->video_hsize >> 1; pix->height = solo_dev->video_vsize; + } else { + /* Full frame */ + pix->width = solo_dev->video_hsize; + pix->height = solo_dev->video_vsize << 1; } if (pix->field == V4L2_FIELD_ANY) -- cgit v1.2.3 From c55564fdf793797dd2740a67c35a2cedc133c9ff Mon Sep 17 00:00:00 2001 From: Krzysztof Hałasa Date: Fri, 11 Feb 2011 13:25:00 +0100 Subject: staging: Solo6x10: Build MPEG4 headers on the fly. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will make them maintainable. Also, it now works on big-endian systems. This is the slow path (done every 1+ second, per channel) so I guess there is no need to cache the results. I have removed CBR-related bits from the MPEG4 VOL header since we can't do CBR (at least yet). Signed-off-by: Krzysztof Hałasa Signed-off-by: Greg Kroah-Hartman --- drivers/staging/solo6x10/solo6010-registers.h | 40 ----- drivers/staging/solo6x10/solo6010-v4l2-enc.c | 209 +++++++++++++++----------- 2 files changed, 122 insertions(+), 127 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/solo6x10/solo6010-registers.h b/drivers/staging/solo6x10/solo6010-registers.h index d39d3c636f59..a1dad570aad2 100644 --- a/drivers/staging/solo6x10/solo6010-registers.h +++ b/drivers/staging/solo6x10/solo6010-registers.h @@ -402,46 +402,6 @@ #define SOLO_DCT_INTERVAL(n) ((n)<<16) #define SOLO_VE_STATE(n) (0x0640+((n)*4)) -struct videnc_status { - union { - u32 status0; - struct { - u32 mp4_enc_code_size:20, sad_motion:1, vid_motion:1, - vop_type:2, video_channel:5, source_field_idx:1, - interlace:1, progressive:1; - } status0_st; - }; - union { - u32 status1; - struct { - u32 vsize:8, hsize:8, last_queue:4, foo1:8, scale:4; - } status1_st; - }; - union { - u32 status4; - struct { - u32 jpeg_code_size:20, interval:10, foo1:2; - } status4_st; - }; - union { - u32 status9; - struct { - u32 channel:5, foo1:27; - } status9_st; - }; - union { - u32 status10; - struct { - u32 mp4_code_size:20, foo:12; - } status10_st; - }; - union { - u32 status11; - struct { - u32 last_queue:8, foo1:24; - } status11_st; - }; -}; #define SOLO_VE_JPEG_QP_TBL 0x0670 #define SOLO_VE_JPEG_QP_CH_L 0x0674 diff --git a/drivers/staging/solo6x10/solo6010-v4l2-enc.c b/drivers/staging/solo6x10/solo6010-v4l2-enc.c index 2b3d30b7f9fc..83d89318f94a 100644 --- a/drivers/staging/solo6x10/solo6010-v4l2-enc.c +++ b/drivers/staging/solo6x10/solo6010-v4l2-enc.c @@ -50,28 +50,6 @@ struct solo_enc_fh { struct p2m_desc desc[SOLO_NR_P2M_DESC]; }; -static unsigned char vid_vop_header[] = { - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20, - 0x02, 0x48, 0x05, 0xc0, 0x00, 0x40, 0x00, 0x40, - 0x00, 0x40, 0x00, 0x80, 0x00, 0x97, 0x53, 0x04, - 0x1f, 0x4c, 0x58, 0x10, 0x78, 0x51, 0x18, 0x3f, -}; - -/* - * Things we can change around: - * - * byte 10, 4-bits 01111000 aspect - * bytes 21,22,23 16-bits 000x1111 11111111 1111x000 fps/res - * bytes 23,24,25 15-bits 00000n11 11111111 11111x00 interval - * bytes 25,26,27 13-bits 00000x11 11111111 111x0000 width - * bytes 27,28,29 13-bits 000x1111 11111111 1x000000 height - * byte 29 1-bit 0x100000 interlace - */ - -/* For aspect */ -#define XVID_PAR_43_PAL 2 -#define XVID_PAR_43_NTSC 3 - static const u32 solo_user_ctrls[] = { V4L2_CID_BRIGHTNESS, V4L2_CID_CONTRAST, @@ -106,30 +84,6 @@ static const u32 *solo_ctrl_classes[] = { NULL }; -struct vop_header { - /* VD_IDX0 */ - u32 size:20, sync_start:1, page_stop:1, vop_type:2, channel:4, - nop0:1, source_fl:1, interlace:1, progressive:1; - - /* VD_IDX1 */ - u32 vsize:8, hsize:8, frame_interop:1, nop1:7, win_id:4, scale:4; - - /* VD_IDX2 */ - u32 base_addr:16, nop2:15, hoff:1; - - /* VD_IDX3 - User set macros */ - u32 sy:12, sx:12, nop3:1, hzoom:1, read_interop:1, write_interlace:1, - scale_mode:4; - - /* VD_IDX4 - User set macros continued */ - u32 write_page:8, nop4:24; - - /* VD_IDX5 */ - u32 next_code_addr; - - u32 end_nops[10]; -} __attribute__((packed)); - static int solo_is_motion_on(struct solo_enc_dev *solo_enc) { struct solo6010_dev *solo_dev = solo_enc->solo_dev; @@ -483,13 +437,121 @@ static int solo_fill_jpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf, enc_buf->jpeg_off, size); } +static inline int vop_interlaced(__le32 *vh) +{ + return (__le32_to_cpu(vh[0]) >> 30) & 1; +} + +static inline u32 vop_size(__le32 *vh) +{ + return __le32_to_cpu(vh[0]) & 0xFFFFF; +} + +static inline u8 vop_hsize(__le32 *vh) +{ + return (__le32_to_cpu(vh[1]) >> 8) & 0xFF; +} + +static inline u8 vop_vsize(__le32 *vh) +{ + return __le32_to_cpu(vh[1]) & 0xFF; +} + +/* must be called with *bits % 8 = 0 */ +static void write_bytes(u8 **out, unsigned *bits, const u8 *src, unsigned count) +{ + memcpy(*out, src, count); + *out += count; + *bits += count * 8; +} + +static void write_bits(u8 **out, unsigned *bits, u32 value, unsigned count) +{ + + value <<= 32 - count; // shift to the right + + while (count--) { + **out <<= 1; + **out |= !!(value & (1 << 31)); /* MSB */ + value <<= 1; + if (++(*bits) % 8 == 0) + (*out)++; + } +} + +static void write_mpeg4_end(u8 **out, unsigned *bits) +{ + write_bits(out, bits, 0, 1); + /* align on 32-bit boundary */ + if (*bits % 32) + write_bits(out, bits, 0xFFFFFFFF, 32 - *bits % 32); +} + +static void mpeg4_write_vol(u8 **out, struct solo6010_dev *solo_dev, + __le32 *vh, unsigned fps, unsigned interval) +{ + static const u8 hdr[] = { + 0, 0, 1, 0x00 /* video_object_start_code */, + 0, 0, 1, 0x20 /* video_object_layer_start_code */ + }; + unsigned bits = 0; + unsigned width = vop_hsize(vh) << 4; + unsigned height = vop_vsize(vh) << 4; + unsigned interlaced = vop_interlaced(vh); + + write_bytes(out, &bits, hdr, sizeof(hdr)); + write_bits(out, &bits, 0, 1); /* random_accessible_vol */ + write_bits(out, &bits, 0x04, 8); /* video_object_type_indication: main */ + write_bits(out, &bits, 1, 1); /* is_object_layer_identifier */ + write_bits(out, &bits, 2, 4); /* video_object_layer_verid: table V2-39 */ + write_bits(out, &bits, 0, 3); /* video_object_layer_priority */ + if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) + write_bits(out, &bits, 3, 4); /* aspect_ratio_info, assuming 4:3 */ + else + write_bits(out, &bits, 2, 4); + write_bits(out, &bits, 1, 1); /* vol_control_parameters */ + write_bits(out, &bits, 1, 2); /* chroma_format: 4:2:0 */ + write_bits(out, &bits, 1, 1); /* low_delay */ + write_bits(out, &bits, 0, 1); /* vbv_parameters */ + write_bits(out, &bits, 0, 2); /* video_object_layer_shape: rectangular */ + write_bits(out, &bits, 1, 1); /* marker_bit */ + write_bits(out, &bits, fps, 16); /* vop_time_increment_resolution */ + write_bits(out, &bits, 1, 1); /* marker_bit */ + write_bits(out, &bits, 1, 1); /* fixed_vop_rate */ + write_bits(out, &bits, interval, 15); /* fixed_vop_time_increment */ + write_bits(out, &bits, 1, 1); /* marker_bit */ + write_bits(out, &bits, width, 13); /* video_object_layer_width */ + write_bits(out, &bits, 1, 1); /* marker_bit */ + write_bits(out, &bits, height, 13); /* video_object_layer_height */ + write_bits(out, &bits, 1, 1); /* marker_bit */ + write_bits(out, &bits, interlaced, 1); /* interlaced */ + write_bits(out, &bits, 1, 1); /* obmc_disable */ + write_bits(out, &bits, 0, 2); /* sprite_enable */ + write_bits(out, &bits, 0, 1); /* not_8_bit */ + write_bits(out, &bits, 1, 0); /* quant_type */ + write_bits(out, &bits, 0, 1); /* load_intra_quant_mat */ + write_bits(out, &bits, 0, 1); /* load_nonintra_quant_mat */ + write_bits(out, &bits, 0, 1); /* quarter_sample */ + write_bits(out, &bits, 1, 1); /* complexity_estimation_disable */ + write_bits(out, &bits, 1, 1); /* resync_marker_disable */ + write_bits(out, &bits, 0, 1); /* data_partitioned */ + write_bits(out, &bits, 0, 1); /* newpred_enable */ + write_bits(out, &bits, 0, 1); /* reduced_resolution_vop_enable */ + write_bits(out, &bits, 0, 1); /* scalability */ + write_mpeg4_end(out, &bits); +} + static int solo_fill_mpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf, struct videobuf_buffer *vb, struct videobuf_dmabuf *vbuf) { struct solo_enc_dev *solo_enc = fh->enc; struct solo6010_dev *solo_dev = solo_enc->solo_dev; - struct vop_header vh; + +#define VH_WORDS 16 +#define MAX_VOL_HEADER_LENGTH 64 + + __le32 vh[VH_WORDS]; int ret; int frame_size, frame_off; int skip = 0; @@ -498,50 +560,27 @@ static int solo_fill_mpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf, return -EINVAL; /* First get the hardware vop header (not real mpeg) */ - ret = enc_get_mpeg_dma(solo_dev, &vh, enc_buf->off, sizeof(vh)); + ret = enc_get_mpeg_dma(solo_dev, vh, enc_buf->off, sizeof(vh)); if (WARN_ON_ONCE(ret)) return ret; - if (WARN_ON_ONCE(vh.size > enc_buf->size)) + if (WARN_ON_ONCE(vop_size(vh) > enc_buf->size)) return -EINVAL; - vb->width = vh.hsize << 4; - vb->height = vh.vsize << 4; - vb->size = vh.size; + vb->width = vop_hsize(vh) << 4; + vb->height = vop_vsize(vh) << 4; + vb->size = vop_size(vh); /* If this is a key frame, add extra m4v header */ if (!enc_buf->vop) { - u16 fps = solo_dev->fps * 1000; - u16 interval = solo_enc->interval * 1000; - u8 p[sizeof(vid_vop_header)]; - - memcpy(p, vid_vop_header, sizeof(p)); - - if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) - p[10] |= ((XVID_PAR_43_NTSC << 3) & 0x78); - else - p[10] |= ((XVID_PAR_43_PAL << 3) & 0x78); - - /* Frame rate and interval */ - p[22] = fps >> 4; - p[23] = ((fps << 4) & 0xf0) | 0x0c | ((interval >> 13) & 0x3); - p[24] = (interval >> 5) & 0xff; - p[25] = ((interval << 3) & 0xf8) | 0x04; - - /* Width and height */ - p[26] = (vb->width >> 3) & 0xff; - p[27] = ((vb->height >> 9) & 0x0f) | 0x10; - p[28] = (vb->height >> 1) & 0xff; - - /* Interlace */ - if (vh.interlace) - p[29] |= 0x20; - - enc_write_sg(vbuf->sglist, p, sizeof(p)); + u8 header[MAX_VOL_HEADER_LENGTH], *out = header; + mpeg4_write_vol(&out, solo_dev, vh, solo_dev->fps * 1000, + solo_enc->interval * 1000); + skip = out - header; + enc_write_sg(vbuf->sglist, header, skip); /* Adjust the dma buffer past this header */ - vb->size += sizeof(vid_vop_header); - skip = sizeof(vid_vop_header); + vb->size += skip; } /* Now get the actual mpeg payload */ @@ -704,7 +743,6 @@ void solo_motion_isr(struct solo6010_dev *solo_dev) void solo_enc_v4l2_isr(struct solo6010_dev *solo_dev) { struct solo_enc_buf *enc_buf; - struct videnc_status vstatus; u32 mpeg_current, mpeg_next, mpeg_size; u32 jpeg_current, jpeg_next, jpeg_size; u32 reg_mpeg_size; @@ -714,12 +752,9 @@ void solo_enc_v4l2_isr(struct solo6010_dev *solo_dev) solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_ENCODER); - vstatus.status11 = solo_reg_read(solo_dev, SOLO_VE_STATE(11)); - cur_q = (vstatus.status11_st.last_queue + 1) % MP4_QS; + cur_q = ((solo_reg_read(solo_dev, SOLO_VE_STATE(11)) & 0xF) + 1) % MP4_QS; - vstatus.status0 = solo_reg_read(solo_dev, SOLO_VE_STATE(0)); - reg_mpeg_size = (vstatus.status0_st.mp4_enc_code_size + 64 + 32) & - (~31); + reg_mpeg_size = ((solo_reg_read(solo_dev, SOLO_VE_STATE(0)) & 0xFFFFF) + 64 + 32) & ~31; while (solo_dev->enc_idx != cur_q) { mpeg_current = solo_reg_read(solo_dev, -- cgit v1.2.3 From 856e22d3cd3c38399be796b80bcf57769eefeee3 Mon Sep 17 00:00:00 2001 From: Krzysztof Hałasa Date: Fri, 11 Feb 2011 13:29:59 +0100 Subject: staging: Solo6x10: Align MPEG video on 8-byte boundary instead of 32-byte. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Solo-6110 only supports 8-byte alignment anyway. Signed-off-by: Krzysztof Hałasa Signed-off-by: Greg Kroah-Hartman --- drivers/staging/solo6x10/solo6010-enc.c | 1 - drivers/staging/solo6x10/solo6010-v4l2-enc.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/solo6x10/solo6010-enc.c b/drivers/staging/solo6x10/solo6010-enc.c index 481a49277f77..7e28f7dbbbdd 100644 --- a/drivers/staging/solo6x10/solo6010-enc.c +++ b/drivers/staging/solo6x10/solo6010-enc.c @@ -176,7 +176,6 @@ static void solo_mp4e_config(struct solo6010_dev *solo_dev) SOLO_VE_BLOCK_BASE(SOLO_MP4E_EXT_ADDR(solo_dev) >> 16)); solo_reg_write(solo_dev, SOLO_VE_CFG1, - SOLO_VE_BYTE_ALIGN(2) | SOLO_VE_INSERT_INDEX | SOLO_VE_MOTION_MODE(0)); solo_reg_write(solo_dev, SOLO_VE_WMRK_POLY, 0); diff --git a/drivers/staging/solo6x10/solo6010-v4l2-enc.c b/drivers/staging/solo6x10/solo6010-v4l2-enc.c index 83d89318f94a..b504d594c3af 100644 --- a/drivers/staging/solo6x10/solo6010-v4l2-enc.c +++ b/drivers/staging/solo6x10/solo6010-v4l2-enc.c @@ -754,7 +754,7 @@ void solo_enc_v4l2_isr(struct solo6010_dev *solo_dev) cur_q = ((solo_reg_read(solo_dev, SOLO_VE_STATE(11)) & 0xF) + 1) % MP4_QS; - reg_mpeg_size = ((solo_reg_read(solo_dev, SOLO_VE_STATE(0)) & 0xFFFFF) + 64 + 32) & ~31; + reg_mpeg_size = ((solo_reg_read(solo_dev, SOLO_VE_STATE(0)) & 0xFFFFF) + 64 + 8) & ~7; while (solo_dev->enc_idx != cur_q) { mpeg_current = solo_reg_read(solo_dev, -- cgit v1.2.3 From 908113d8ebd26fea48e0d7b6e78b67ae6fc735ac Mon Sep 17 00:00:00 2001 From: Krzysztof Hałasa Date: Fri, 11 Feb 2011 13:32:11 +0100 Subject: staging: Solo6x10: Add support for SOLO6110 chip. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Krzysztof Hałasa Signed-off-by: Greg Kroah-Hartman --- drivers/staging/solo6x10/solo6010-core.c | 40 +++++++++++-- drivers/staging/solo6x10/solo6010-enc.c | 27 ++++++--- drivers/staging/solo6x10/solo6010-p2m.c | 16 ++--- drivers/staging/solo6x10/solo6010-registers.h | 40 +++++++++---- drivers/staging/solo6x10/solo6010-v4l2-enc.c | 86 ++++++++++++++++++++++++++- drivers/staging/solo6x10/solo6010.h | 4 ++ 6 files changed, 181 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/solo6x10/solo6010-core.c b/drivers/staging/solo6x10/solo6010-core.c index c433136f972c..c713a74691dd 100644 --- a/drivers/staging/solo6x10/solo6010-core.c +++ b/drivers/staging/solo6x10/solo6010-core.c @@ -136,6 +136,7 @@ static int __devinit solo6010_pci_probe(struct pci_dev *pdev, int ret; int sdram; u8 chip_id; + u32 reg; solo_dev = kzalloc(sizeof(*solo_dev), GFP_KERNEL); if (solo_dev == NULL) @@ -181,14 +182,43 @@ static int __devinit solo6010_pci_probe(struct pci_dev *pdev, solo_dev->nr_ext = 1; } + solo_dev->flags = id->driver_data; + /* Disable all interrupts to start */ solo6010_irq_off(solo_dev, ~0); + reg = SOLO_SYS_CFG_SDRAM64BIT; /* Initial global settings */ - solo_reg_write(solo_dev, SOLO_SYS_CFG, SOLO_SYS_CFG_SDRAM64BIT | - SOLO_SYS_CFG_INPUTDIV(25) | - SOLO_SYS_CFG_FEEDBACKDIV((SOLO_CLOCK_MHZ * 2) - 2) | - SOLO_SYS_CFG_OUTDIV(3)); + if (!(solo_dev->flags & FLAGS_6110)) + reg |= SOLO6010_SYS_CFG_INPUTDIV(25) | + SOLO6010_SYS_CFG_FEEDBACKDIV((SOLO_CLOCK_MHZ * 2) - 2) | + SOLO6010_SYS_CFG_OUTDIV(3); + solo_reg_write(solo_dev, SOLO_SYS_CFG, reg); + + if (solo_dev->flags & FLAGS_6110) { + u32 sys_clock_MHz = SOLO_CLOCK_MHZ; + u32 pll_DIVQ; + u32 pll_DIVF; + + if (sys_clock_MHz < 125) { + pll_DIVQ = 3; + pll_DIVF = (sys_clock_MHz * 4) / 3; + } else { + pll_DIVQ = 2; + pll_DIVF = (sys_clock_MHz * 2) / 3; + } + + solo_reg_write(solo_dev, SOLO6110_PLL_CONFIG, + SOLO6110_PLL_RANGE_5_10MHZ | + SOLO6110_PLL_DIVR(9) | + SOLO6110_PLL_DIVQ_EXP(pll_DIVQ) | + SOLO6110_PLL_DIVF(pll_DIVF) | SOLO6110_PLL_FSEN); + mdelay(1); // PLL Locking time (1ms) + + solo_reg_write(solo_dev, SOLO_DMA_CTRL1, 3 << 8); /* ? */ + } else + solo_reg_write(solo_dev, SOLO_DMA_CTRL1, 1 << 8); /* ? */ + solo_reg_write(solo_dev, SOLO_TIMER_CLOCK_NUM, SOLO_CLOCK_MHZ - 1); /* PLL locking time of 1ms */ @@ -264,6 +294,8 @@ static void __devexit solo6010_pci_remove(struct pci_dev *pdev) static struct pci_device_id solo6010_id_table[] = { /* 6010 based cards */ {PCI_DEVICE(PCI_VENDOR_ID_SOFTLOGIC, PCI_DEVICE_ID_SOLO6010)}, + {PCI_DEVICE(PCI_VENDOR_ID_SOFTLOGIC, PCI_DEVICE_ID_SOLO6110), + .driver_data = FLAGS_6110}, {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_4)}, {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_9)}, {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_16)}, diff --git a/drivers/staging/solo6x10/solo6010-enc.c b/drivers/staging/solo6x10/solo6010-enc.c index 7e28f7dbbbdd..743734d8e7a3 100644 --- a/drivers/staging/solo6x10/solo6010-enc.c +++ b/drivers/staging/solo6x10/solo6010-enc.c @@ -155,19 +155,26 @@ int solo_osd_print(struct solo_enc_dev *solo_enc) static void solo_jpeg_config(struct solo6010_dev *solo_dev) { - solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_TBL, - (2 << 24) | (2 << 16) | (2 << 8) | (2 << 0)); + u32 reg; + if (solo_dev->flags & FLAGS_6110) + reg = (4 << 24) | (3 << 16) | (2 << 8) | (1 << 0); + else + reg = (2 << 24) | (2 << 16) | (2 << 8) | (2 << 0); + solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_TBL, reg); solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_CH_L, 0); solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_CH_H, 0); solo_reg_write(solo_dev, SOLO_VE_JPEG_CFG, (SOLO_JPEG_EXT_SIZE(solo_dev) & 0xffff0000) | ((SOLO_JPEG_EXT_ADDR(solo_dev) >> 16) & 0x0000ffff)); solo_reg_write(solo_dev, SOLO_VE_JPEG_CTRL, 0xffffffff); + /* que limit, samp limit, pos limit */ + solo_reg_write(solo_dev, 0x0688, (0 << 16) | (30 << 8) | 60); } static void solo_mp4e_config(struct solo6010_dev *solo_dev) { int i; + u32 reg; /* We can only use VE_INTR_CTRL(0) if we want to support mjpeg */ solo_reg_write(solo_dev, SOLO_VE_CFG0, @@ -184,17 +191,21 @@ static void solo_mp4e_config(struct solo6010_dev *solo_dev) solo_reg_write(solo_dev, SOLO_VE_ENCRYP_POLY, 0); solo_reg_write(solo_dev, SOLO_VE_ENCRYP_INIT, 0); - solo_reg_write(solo_dev, SOLO_VE_ATTR, - SOLO_VE_LITTLE_ENDIAN | - SOLO_COMP_ATTR_FCODE(1) | - SOLO_COMP_TIME_INC(0) | - SOLO_COMP_TIME_WIDTH(15) | - SOLO_DCT_INTERVAL(36 / 4)); + reg = SOLO_VE_LITTLE_ENDIAN | SOLO_COMP_ATTR_FCODE(1) | + SOLO_COMP_TIME_INC(0) | SOLO_COMP_TIME_WIDTH(15); + if (solo_dev->flags & FLAGS_6110) + reg |= SOLO_DCT_INTERVAL(10); + else + reg |= SOLO_DCT_INTERVAL(36 / 4); + solo_reg_write(solo_dev, SOLO_VE_ATTR, reg); for (i = 0; i < solo_dev->nr_chans; i++) solo_reg_write(solo_dev, SOLO_VE_CH_REF_BASE(i), (SOLO_EREF_EXT_ADDR(solo_dev) + (i * SOLO_EREF_EXT_SIZE)) >> 16); + + if (solo_dev->flags & FLAGS_6110) + solo_reg_write(solo_dev, 0x0634, 0x00040008); /* ? */ } int solo_enc_init(struct solo6010_dev *solo_dev) diff --git a/drivers/staging/solo6x10/solo6010-p2m.c b/drivers/staging/solo6x10/solo6010-p2m.c index 956dea09348a..90de96348db8 100644 --- a/drivers/staging/solo6x10/solo6010-p2m.c +++ b/drivers/staging/solo6x10/solo6010-p2m.c @@ -66,18 +66,18 @@ int solo_p2m_dma_t(struct solo6010_dev *solo_dev, u8 id, int wr, void solo_p2m_push_desc(struct p2m_desc *desc, int wr, dma_addr_t dma_addr, u32 ext_addr, u32 size, int repeat, u32 ext_size) { - desc->ta = dma_addr; - desc->fa = ext_addr; + desc->ta = cpu_to_le32(dma_addr); + desc->fa = cpu_to_le32(ext_addr); - desc->ext = SOLO_P2M_COPY_SIZE(size >> 2); - desc->ctrl = SOLO_P2M_BURST_SIZE(SOLO_P2M_BURST_256) | - (wr ? SOLO_P2M_WRITE : 0) | SOLO_P2M_TRANS_ON; + desc->ext = cpu_to_le32(SOLO_P2M_COPY_SIZE(size >> 2)); + desc->ctrl = cpu_to_le32(SOLO_P2M_BURST_SIZE(SOLO_P2M_BURST_256) | + (wr ? SOLO_P2M_WRITE : 0) | SOLO_P2M_TRANS_ON); /* Ext size only matters when we're repeating */ if (repeat) { - desc->ext |= SOLO_P2M_EXT_INC(ext_size >> 2); - desc->ctrl |= SOLO_P2M_PCI_INC(size >> 2) | - SOLO_P2M_REPEAT(repeat); + desc->ext |= cpu_to_le32(SOLO_P2M_EXT_INC(ext_size >> 2)); + desc->ctrl |= cpu_to_le32(SOLO_P2M_PCI_INC(size >> 2) | + SOLO_P2M_REPEAT(repeat)); } } diff --git a/drivers/staging/solo6x10/solo6010-registers.h b/drivers/staging/solo6x10/solo6010-registers.h index a1dad570aad2..db291bf0ce99 100644 --- a/drivers/staging/solo6x10/solo6010-registers.h +++ b/drivers/staging/solo6x10/solo6010-registers.h @@ -24,16 +24,16 @@ /* Global 6010 system configuration */ #define SOLO_SYS_CFG 0x0000 -#define SOLO_SYS_CFG_FOUT_EN 0x00000001 -#define SOLO_SYS_CFG_PLL_BYPASS 0x00000002 -#define SOLO_SYS_CFG_PLL_PWDN 0x00000004 -#define SOLO_SYS_CFG_OUTDIV(__n) (((__n) & 0x003) << 3) -#define SOLO_SYS_CFG_FEEDBACKDIV(__n) (((__n) & 0x1ff) << 5) -#define SOLO_SYS_CFG_INPUTDIV(__n) (((__n) & 0x01f) << 14) +#define SOLO6010_SYS_CFG_FOUT_EN 0x00000001 /* 6010 only */ +#define SOLO6010_SYS_CFG_PLL_BYPASS 0x00000002 /* 6010 only */ +#define SOLO6010_SYS_CFG_PLL_PWDN 0x00000004 /* 6010 only */ +#define SOLO6010_SYS_CFG_OUTDIV(__n) (((__n) & 0x003) << 3) /* 6010 only */ +#define SOLO6010_SYS_CFG_FEEDBACKDIV(__n) (((__n) & 0x1ff) << 5) /* 6010 only */ +#define SOLO6010_SYS_CFG_INPUTDIV(__n) (((__n) & 0x01f) << 14) /* 6010 only */ #define SOLO_SYS_CFG_CLOCK_DIV 0x00080000 #define SOLO_SYS_CFG_NCLK_DELAY(__n) (((__n) & 0x003) << 24) #define SOLO_SYS_CFG_PCLK_DELAY(__n) (((__n) & 0x00f) << 26) -#define SOLO_SYS_CFG_SDRAM64BIT 0x40000000 +#define SOLO_SYS_CFG_SDRAM64BIT 0x40000000 /* 6110: must be set */ #define SOLO_SYS_CFG_RESET 0x80000000 #define SOLO_DMA_CTRL 0x0004 @@ -45,6 +45,7 @@ #define SOLO_DMA_CTRL_READ_DATA_SELECT (1<<3) #define SOLO_DMA_CTRL_READ_CLK_SELECT (1<<2) #define SOLO_DMA_CTRL_LATENCY(n) ((n)<<0) +#define SOLO_DMA_CTRL1 0x0008 #define SOLO_SYS_VCLK 0x000C #define SOLO_VCLK_INVERT (1<<22) @@ -81,6 +82,23 @@ #define SOLO_CHIP_OPTION 0x001C #define SOLO_CHIP_ID_MASK 0x00000007 +#define SOLO6110_PLL_CONFIG 0x0020 +#define SOLO6110_PLL_RANGE_BYPASS (0 << 20) +#define SOLO6110_PLL_RANGE_5_10MHZ (1 << 20) +#define SOLO6110_PLL_RANGE_8_16MHZ (2 << 20) +#define SOLO6110_PLL_RANGE_13_26MHZ (3 << 20) +#define SOLO6110_PLL_RANGE_21_42MHZ (4 << 20) +#define SOLO6110_PLL_RANGE_34_68MHZ (5 << 20) +#define SOLO6110_PLL_RANGE_54_108MHZ (6 << 20) +#define SOLO6110_PLL_RANGE_88_200MHZ (7 << 20) +#define SOLO6110_PLL_DIVR(x) (((x) - 1) << 15) +#define SOLO6110_PLL_DIVQ_EXP(x) ((x) << 12) +#define SOLO6110_PLL_DIVF(x) (((x) - 1) << 4) +#define SOLO6110_PLL_RESET (1 << 3) +#define SOLO6110_PLL_BYPASS (1 << 2) +#define SOLO6110_PLL_FSEN (1 << 1) +#define SOLO6110_PLL_FB (1 << 0) + #define SOLO_EEPROM_CTRL 0x0060 #define SOLO_EEPROM_ACCESS_EN (1<<7) #define SOLO_EEPROM_CS (1<<3) @@ -383,7 +401,9 @@ #define SOLO_VE_BLOCK_BASE(n) ((n)<<0) #define SOLO_VE_CFG1 0x0614 -#define SOLO_VE_BYTE_ALIGN(n) ((n)<<24) +#define SOLO6110_VE_MPEG_SIZE_H(n) ((n)<<28) /* 6110 only */ +#define SOLO6010_VE_BYTE_ALIGN(n) ((n)<<24) /* 6010 only */ +#define SOLO6110_VE_JPEG_SIZE_H(n) ((n)<<20) /* 6110 only */ #define SOLO_VE_INSERT_INDEX (1<<18) #define SOLO_VE_MOTION_MODE(n) ((n)<<16) #define SOLO_VE_MOTION_BASE(n) ((n)<<0) @@ -415,7 +435,7 @@ #define SOLO_VE_OSD_OPT 0x069C #define SOLO_VE_CH_INTL(ch) (0x0700+((ch)*4)) -#define SOLO_VE_CH_MOT(ch) (0x0740+((ch)*4)) +#define SOLO6010_VE_CH_MOT(ch) (0x0740+((ch)*4)) /* 6010 only */ #define SOLO_VE_CH_QP(ch) (0x0780+((ch)*4)) #define SOLO_VE_CH_QP_E(ch) (0x07C0+((ch)*4)) #define SOLO_VE_CH_GOP(ch) (0x0800+((ch)*4)) @@ -427,7 +447,7 @@ #define SOLO_VE_JPEG_QUE(n) (0x0A04+((n)*8)) #define SOLO_VD_CFG0 0x0900 -#define SOLO_VD_CFG_NO_WRITE_NO_WINDOW (1<<24) +#define SOLO6010_VD_CFG_NO_WRITE_NO_WINDOW (1<<24) /* 6010 only */ #define SOLO_VD_CFG_BUSY_WIAT_CODE (1<<23) #define SOLO_VD_CFG_BUSY_WIAT_REF (1<<22) #define SOLO_VD_CFG_BUSY_WIAT_RES (1<<21) diff --git a/drivers/staging/solo6x10/solo6010-v4l2-enc.c b/drivers/staging/solo6x10/solo6010-v4l2-enc.c index b504d594c3af..6fbd50e90f63 100644 --- a/drivers/staging/solo6x10/solo6010-v4l2-enc.c +++ b/drivers/staging/solo6x10/solo6010-v4l2-enc.c @@ -479,6 +479,26 @@ static void write_bits(u8 **out, unsigned *bits, u32 value, unsigned count) } } +static void write_ue(u8 **out, unsigned *bits, unsigned value) /* H.264 only */ +{ + uint32_t max = 0, cnt = 0; + + while (value > max) { + max = (max + 2) * 2 - 2; + cnt++; + } + write_bits(out, bits, 1, cnt + 1); + write_bits(out, bits, ~(max - value), cnt); +} + +static void write_se(u8 **out, unsigned *bits, int value) /* H.264 only */ +{ + if (value <= 0) + write_ue(out, bits, -value * 2); + else + write_ue(out, bits, value * 2 - 1); +} + static void write_mpeg4_end(u8 **out, unsigned *bits) { write_bits(out, bits, 0, 1); @@ -487,6 +507,16 @@ static void write_mpeg4_end(u8 **out, unsigned *bits) write_bits(out, bits, 0xFFFFFFFF, 32 - *bits % 32); } +static void write_h264_end(u8 **out, unsigned *bits, int align) +{ + write_bits(out, bits, 1, 1); + while ((*bits) % 8) + write_bits(out, bits, 0, 1); + if (align) + while ((*bits) % 32) + write_bits(out, bits, 0, 1); +} + static void mpeg4_write_vol(u8 **out, struct solo6010_dev *solo_dev, __le32 *vh, unsigned fps, unsigned interval) { @@ -541,6 +571,54 @@ static void mpeg4_write_vol(u8 **out, struct solo6010_dev *solo_dev, write_mpeg4_end(out, &bits); } +static void h264_write_vol(u8 **out, struct solo6010_dev *solo_dev, __le32 *vh) +{ + static const u8 sps[] = { + 0, 0, 0, 1 /* start code */, 0x67, 66 /* profile_idc */, + 0 /* constraints */, 30 /* level_idc */ + }; + static const u8 pps[] = { + 0, 0, 0, 1 /* start code */, 0x68 + }; + + unsigned bits = 0; + unsigned mbs_w = vop_hsize(vh); + unsigned mbs_h = vop_vsize(vh); + + write_bytes(out, &bits, sps, sizeof(sps)); + write_ue(out, &bits, 0); /* seq_parameter_set_id */ + write_ue(out, &bits, 5); /* log2_max_frame_num_minus4 */ + write_ue(out, &bits, 0); /* pic_order_cnt_type */ + write_ue(out, &bits, 6); /* log2_max_pic_order_cnt_lsb_minus4 */ + write_ue(out, &bits, 1); /* max_num_ref_frames */ + write_bits(out, &bits, 0, 1); /* gaps_in_frame_num_value_allowed_flag */ + write_ue(out, &bits, mbs_w - 1); /* pic_width_in_mbs_minus1 */ + write_ue(out, &bits, mbs_h - 1); /* pic_height_in_map_units_minus1 */ + write_bits(out, &bits, 1, 1); /* frame_mbs_only_flag */ + write_bits(out, &bits, 1, 1); /* direct_8x8_frame_field_flag */ + write_bits(out, &bits, 0, 1); /* frame_cropping_flag */ + write_bits(out, &bits, 0, 1); /* vui_parameters_present_flag */ + write_h264_end(out, &bits, 0); + + write_bytes(out, &bits, pps, sizeof(pps)); + write_ue(out, &bits, 0); /* pic_parameter_set_id */ + write_ue(out, &bits, 0); /* seq_parameter_set_id */ + write_bits(out, &bits, 0, 1); /* entropy_coding_mode_flag */ + write_bits(out, &bits, 0, 1); /* bottom_field_pic_order_in_frame_present_flag */ + write_ue(out, &bits, 0); /* num_slice_groups_minus1 */ + write_ue(out, &bits, 0); /* num_ref_idx_l0_default_active_minus1 */ + write_ue(out, &bits, 0); /* num_ref_idx_l1_default_active_minus1 */ + write_bits(out, &bits, 0, 1); /* weighted_pred_flag */ + write_bits(out, &bits, 0, 2); /* weighted_bipred_idc */ + write_se(out, &bits, 0); /* pic_init_qp_minus26 */ + write_se(out, &bits, 0); /* pic_init_qs_minus26 */ + write_se(out, &bits, 2); /* chroma_qp_index_offset */ + write_bits(out, &bits, 0, 1); /* deblocking_filter_control_present_flag */ + write_bits(out, &bits, 1, 1); /* constrained_intra_pred_flag */ + write_bits(out, &bits, 0, 1); /* redundant_pic_cnt_present_flag */ + write_h264_end(out, &bits, 1); +} + static int solo_fill_mpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf, struct videobuf_buffer *vb, struct videobuf_dmabuf *vbuf) @@ -575,8 +653,12 @@ static int solo_fill_mpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf, if (!enc_buf->vop) { u8 header[MAX_VOL_HEADER_LENGTH], *out = header; - mpeg4_write_vol(&out, solo_dev, vh, solo_dev->fps * 1000, - solo_enc->interval * 1000); + if (solo_dev->flags & FLAGS_6110) + h264_write_vol(&out, solo_dev, vh); + else + mpeg4_write_vol(&out, solo_dev, vh, + solo_dev->fps * 1000, + solo_enc->interval * 1000); skip = out - header; enc_write_sg(vbuf->sglist, header, skip); /* Adjust the dma buffer past this header */ diff --git a/drivers/staging/solo6x10/solo6010.h b/drivers/staging/solo6x10/solo6010.h index 9c930f3a017b..4532e12d91b5 100644 --- a/drivers/staging/solo6x10/solo6010.h +++ b/drivers/staging/solo6x10/solo6010.h @@ -40,6 +40,7 @@ #ifndef PCI_VENDOR_ID_SOFTLOGIC #define PCI_VENDOR_ID_SOFTLOGIC 0x9413 #define PCI_DEVICE_ID_SOLO6010 0x6010 +#define PCI_DEVICE_ID_SOLO6110 0x6110 #endif #ifndef PCI_VENDOR_ID_BLUECHERRY @@ -70,6 +71,8 @@ #define SOLO6010_VER_NUM \ KERNEL_VERSION(SOLO6010_VER_MAJOR, SOLO6010_VER_MINOR, SOLO6010_VER_SUB) +#define FLAGS_6110 1 + /* * The SOLO6010 actually has 8 i2c channels, but we only use 2. * 0 - Techwell chip(s) @@ -183,6 +186,7 @@ struct solo6010_dev { u8 __iomem *reg_base; int nr_chans; int nr_ext; + u32 flags; u32 irq_mask; u32 motion_mask; spinlock_t reg_io_lock; -- cgit v1.2.3 From 43d1136d2c6073709db3049b3661ee662911df35 Mon Sep 17 00:00:00 2001 From: Krzysztof Hałasa Date: Fri, 11 Feb 2011 13:33:26 +0100 Subject: staging: Solo6x10: remove unneeded __solo parameter from SOLO_*_EXT_ADDR macros. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Krzysztof Hałasa Signed-off-by: Greg Kroah-Hartman --- drivers/staging/solo6x10/solo6010-disp.c | 2 +- drivers/staging/solo6x10/solo6010-enc.c | 7 +++---- drivers/staging/solo6x10/solo6010-offsets.h | 16 ++++++---------- drivers/staging/solo6x10/solo6010-v4l2.c | 2 +- 4 files changed, 11 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/solo6x10/solo6010-disp.c b/drivers/staging/solo6x10/solo6010-disp.c index f866f8438175..99d14619e784 100644 --- a/drivers/staging/solo6x10/solo6010-disp.c +++ b/drivers/staging/solo6x10/solo6010-disp.c @@ -135,7 +135,7 @@ static void solo_disp_config(struct solo6010_dev *solo_dev) solo_reg_write(solo_dev, SOLO_VO_DISP_CTRL, SOLO_VO_DISP_ON | SOLO_VO_DISP_ERASE_COUNT(8) | - SOLO_VO_DISP_BASE(SOLO_DISP_EXT_ADDR(solo_dev))); + SOLO_VO_DISP_BASE(SOLO_DISP_EXT_ADDR)); solo_reg_write(solo_dev, SOLO_VO_DISP_ERASE, SOLO_VO_DISP_ERASE_ON); diff --git a/drivers/staging/solo6x10/solo6010-enc.c b/drivers/staging/solo6x10/solo6010-enc.c index 743734d8e7a3..7a3c4d59e57c 100644 --- a/drivers/staging/solo6x10/solo6010-enc.c +++ b/drivers/staging/solo6x10/solo6010-enc.c @@ -93,8 +93,7 @@ static void solo_capture_config(struct solo6010_dev *solo_dev) /* Clear OSD */ solo_reg_write(solo_dev, SOLO_VE_OSD_CH, 0); - solo_reg_write(solo_dev, SOLO_VE_OSD_BASE, - SOLO_EOSD_EXT_ADDR(solo_dev) >> 16); + solo_reg_write(solo_dev, SOLO_VE_OSD_BASE, SOLO_EOSD_EXT_ADDR >> 16); solo_reg_write(solo_dev, SOLO_VE_OSD_CLR, 0xF0 << 16 | 0x80 << 8 | 0x80); solo_reg_write(solo_dev, SOLO_VE_OSD_OPT, 0); @@ -107,7 +106,7 @@ static void solo_capture_config(struct solo6010_dev *solo_dev) for (i = 0; i < solo_dev->nr_chans; i++) { for (j = 0; j < SOLO_EOSD_EXT_SIZE; j += OSG_BUFFER_SIZE) { solo_p2m_dma(solo_dev, SOLO_P2M_DMA_ID_MP4E, 1, buf, - SOLO_EOSD_EXT_ADDR(solo_dev) + + SOLO_EOSD_EXT_ADDR + (i * SOLO_EOSD_EXT_SIZE) + j, OSG_BUFFER_SIZE); } @@ -143,7 +142,7 @@ int solo_osd_print(struct solo_enc_dev *solo_enc) } } - solo_p2m_dma(solo_dev, 0, 1, buf, SOLO_EOSD_EXT_ADDR(solo_dev) + + solo_p2m_dma(solo_dev, 0, 1, buf, SOLO_EOSD_EXT_ADDR + (solo_enc->ch * SOLO_EOSD_EXT_SIZE), SOLO_EOSD_EXT_SIZE); reg |= (1 << solo_enc->ch); solo_reg_write(solo_dev, SOLO_VE_OSD_CH, reg); diff --git a/drivers/staging/solo6x10/solo6010-offsets.h b/drivers/staging/solo6x10/solo6010-offsets.h index 2431de989c02..b176003ff383 100644 --- a/drivers/staging/solo6x10/solo6010-offsets.h +++ b/drivers/staging/solo6x10/solo6010-offsets.h @@ -21,24 +21,20 @@ #define __SOLO6010_OFFSETS_H /* Offsets and sizes of the external address */ -#define SOLO_DISP_EXT_ADDR(__solo) 0x00000000 +#define SOLO_DISP_EXT_ADDR 0x00000000 #define SOLO_DISP_EXT_SIZE 0x00480000 -#define SOLO_DEC2LIVE_EXT_ADDR(__solo) \ - (SOLO_DISP_EXT_ADDR(__solo) + SOLO_DISP_EXT_SIZE) +#define SOLO_DEC2LIVE_EXT_ADDR (SOLO_DISP_EXT_ADDR + SOLO_DISP_EXT_SIZE) #define SOLO_DEC2LIVE_EXT_SIZE 0x00240000 -#define SOLO_OSG_EXT_ADDR(__solo) \ - (SOLO_DEC2LIVE_EXT_ADDR(__solo) + SOLO_DEC2LIVE_EXT_SIZE) +#define SOLO_OSG_EXT_ADDR (SOLO_DEC2LIVE_EXT_ADDR + SOLO_DEC2LIVE_EXT_SIZE) #define SOLO_OSG_EXT_SIZE 0x00120000 -#define SOLO_EOSD_EXT_ADDR(__solo) \ - (SOLO_OSG_EXT_ADDR(__solo) + SOLO_OSG_EXT_SIZE) +#define SOLO_EOSD_EXT_ADDR (SOLO_OSG_EXT_ADDR + SOLO_OSG_EXT_SIZE) #define SOLO_EOSD_EXT_SIZE 0x00010000 -#define SOLO_MOTION_EXT_ADDR(__solo) \ - (SOLO_EOSD_EXT_ADDR(__solo) + \ - (SOLO_EOSD_EXT_SIZE * __solo->nr_chans)) +#define SOLO_MOTION_EXT_ADDR(__solo) (SOLO_EOSD_EXT_ADDR + \ + (SOLO_EOSD_EXT_SIZE * __solo->nr_chans)) #define SOLO_MOTION_EXT_SIZE 0x00080000 #define SOLO_G723_EXT_ADDR(__solo) \ diff --git a/drivers/staging/solo6x10/solo6010-v4l2.c b/drivers/staging/solo6x10/solo6010-v4l2.c index a8491dc0e914..4e24e928eb02 100644 --- a/drivers/staging/solo6x10/solo6010-v4l2.c +++ b/drivers/staging/solo6x10/solo6010-v4l2.c @@ -280,7 +280,7 @@ static void solo_fillbuf(struct solo_filehandle *fh, sg_dma = sg_dma_address(sg); sg_size_left = sg_dma_len(sg); - fdma_addr = SOLO_DISP_EXT_ADDR(solo_dev) + (fh->old_write * + fdma_addr = SOLO_DISP_EXT_ADDR + (fh->old_write * (SOLO_HW_BPL * solo_vlines(solo_dev))); for (i = 0; i < solo_vlines(solo_dev); i++) { -- cgit v1.2.3 From ae69b22c6ca7d1d7fdccf0b664dafbc777099abe Mon Sep 17 00:00:00 2001 From: Krzysztof Hałasa Date: Fri, 11 Feb 2011 13:36:27 +0100 Subject: staging: Solo6x10: Stripped "solo6010-" from file names. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver supports both Solo-6010 and Solo-6110 chips anyway. Renamed solo6010.h -> solo6x10.h. Signed-off-by: Krzysztof Hałasa Signed-off-by: Greg Kroah-Hartman --- drivers/staging/solo6x10/Makefile | 5 +- drivers/staging/solo6x10/core.c | 331 +++++ drivers/staging/solo6x10/disp.c | 270 ++++ drivers/staging/solo6x10/enc.c | 237 ++++ drivers/staging/solo6x10/g723.c | 398 ++++++ drivers/staging/solo6x10/gpio.c | 102 ++ drivers/staging/solo6x10/i2c.c | 331 +++++ drivers/staging/solo6x10/jpeg.h | 105 ++ drivers/staging/solo6x10/offsets.h | 74 + drivers/staging/solo6x10/osd-font.h | 154 +++ drivers/staging/solo6x10/p2m.c | 305 +++++ drivers/staging/solo6x10/registers.h | 637 +++++++++ drivers/staging/solo6x10/solo6010-core.c | 332 ----- drivers/staging/solo6x10/solo6010-disp.c | 271 ---- drivers/staging/solo6x10/solo6010-enc.c | 238 ---- drivers/staging/solo6x10/solo6010-g723.c | 400 ------ drivers/staging/solo6x10/solo6010-gpio.c | 103 -- drivers/staging/solo6x10/solo6010-i2c.c | 332 ----- drivers/staging/solo6x10/solo6010-jpeg.h | 105 -- drivers/staging/solo6x10/solo6010-offsets.h | 74 - drivers/staging/solo6x10/solo6010-osd-font.h | 154 --- drivers/staging/solo6x10/solo6010-p2m.c | 306 ----- drivers/staging/solo6x10/solo6010-registers.h | 637 --------- drivers/staging/solo6x10/solo6010-tw28.c | 823 ----------- drivers/staging/solo6x10/solo6010-tw28.h | 65 - drivers/staging/solo6x10/solo6010-v4l2-enc.c | 1827 ------------------------- drivers/staging/solo6x10/solo6010-v4l2.c | 966 ------------- drivers/staging/solo6x10/solo6010.h | 338 ----- drivers/staging/solo6x10/solo6x10.h | 336 +++++ drivers/staging/solo6x10/tw28.c | 822 +++++++++++ drivers/staging/solo6x10/tw28.h | 65 + drivers/staging/solo6x10/v4l2-enc.c | 1825 ++++++++++++++++++++++++ drivers/staging/solo6x10/v4l2.c | 964 +++++++++++++ 33 files changed, 6957 insertions(+), 6975 deletions(-) create mode 100644 drivers/staging/solo6x10/core.c create mode 100644 drivers/staging/solo6x10/disp.c create mode 100644 drivers/staging/solo6x10/enc.c create mode 100644 drivers/staging/solo6x10/g723.c create mode 100644 drivers/staging/solo6x10/gpio.c create mode 100644 drivers/staging/solo6x10/i2c.c create mode 100644 drivers/staging/solo6x10/jpeg.h create mode 100644 drivers/staging/solo6x10/offsets.h create mode 100644 drivers/staging/solo6x10/osd-font.h create mode 100644 drivers/staging/solo6x10/p2m.c create mode 100644 drivers/staging/solo6x10/registers.h delete mode 100644 drivers/staging/solo6x10/solo6010-core.c delete mode 100644 drivers/staging/solo6x10/solo6010-disp.c delete mode 100644 drivers/staging/solo6x10/solo6010-enc.c delete mode 100644 drivers/staging/solo6x10/solo6010-g723.c delete mode 100644 drivers/staging/solo6x10/solo6010-gpio.c delete mode 100644 drivers/staging/solo6x10/solo6010-i2c.c delete mode 100644 drivers/staging/solo6x10/solo6010-jpeg.h delete mode 100644 drivers/staging/solo6x10/solo6010-offsets.h delete mode 100644 drivers/staging/solo6x10/solo6010-osd-font.h delete mode 100644 drivers/staging/solo6x10/solo6010-p2m.c delete mode 100644 drivers/staging/solo6x10/solo6010-registers.h delete mode 100644 drivers/staging/solo6x10/solo6010-tw28.c delete mode 100644 drivers/staging/solo6x10/solo6010-tw28.h delete mode 100644 drivers/staging/solo6x10/solo6010-v4l2-enc.c delete mode 100644 drivers/staging/solo6x10/solo6010-v4l2.c delete mode 100644 drivers/staging/solo6x10/solo6010.h create mode 100644 drivers/staging/solo6x10/solo6x10.h create mode 100644 drivers/staging/solo6x10/tw28.c create mode 100644 drivers/staging/solo6x10/tw28.h create mode 100644 drivers/staging/solo6x10/v4l2-enc.c create mode 100644 drivers/staging/solo6x10/v4l2.c (limited to 'drivers') diff --git a/drivers/staging/solo6x10/Makefile b/drivers/staging/solo6x10/Makefile index 1616b5535474..72816cf16704 100644 --- a/drivers/staging/solo6x10/Makefile +++ b/drivers/staging/solo6x10/Makefile @@ -1,6 +1,3 @@ -solo6x10-y := solo6010-core.o solo6010-i2c.o solo6010-p2m.o \ - solo6010-v4l2.o solo6010-tw28.o solo6010-gpio.o \ - solo6010-disp.o solo6010-enc.o solo6010-v4l2-enc.o \ - solo6010-g723.o +solo6x10-y := core.o i2c.o p2m.o v4l2.o tw28.o gpio.o disp.o enc.o v4l2-enc.o g723.o obj-$(CONFIG_SOLO6X10) := solo6x10.o diff --git a/drivers/staging/solo6x10/core.c b/drivers/staging/solo6x10/core.c new file mode 100644 index 000000000000..37e6fda626f3 --- /dev/null +++ b/drivers/staging/solo6x10/core.c @@ -0,0 +1,331 @@ +/* + * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com + * Copyright (C) 2010 Ben Collins + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include "solo6x10.h" +#include "tw28.h" + +MODULE_DESCRIPTION("Softlogic 6010 MP4 Encoder/Decoder V4L2/ALSA Driver"); +MODULE_AUTHOR("Ben Collins "); +MODULE_VERSION(SOLO6010_VERSION); +MODULE_LICENSE("GPL"); + +void solo6010_irq_on(struct solo6010_dev *solo_dev, u32 mask) +{ + solo_dev->irq_mask |= mask; + solo_reg_write(solo_dev, SOLO_IRQ_ENABLE, solo_dev->irq_mask); +} + +void solo6010_irq_off(struct solo6010_dev *solo_dev, u32 mask) +{ + solo_dev->irq_mask &= ~mask; + solo_reg_write(solo_dev, SOLO_IRQ_ENABLE, solo_dev->irq_mask); +} + +/* XXX We should check the return value of the sub-device ISR's */ +static irqreturn_t solo6010_isr(int irq, void *data) +{ + struct solo6010_dev *solo_dev = data; + u32 status; + int i; + + status = solo_reg_read(solo_dev, SOLO_IRQ_STAT); + if (!status) + return IRQ_NONE; + + if (status & ~solo_dev->irq_mask) { + solo_reg_write(solo_dev, SOLO_IRQ_STAT, + status & ~solo_dev->irq_mask); + status &= solo_dev->irq_mask; + } + + if (status & SOLO_IRQ_PCI_ERR) { + u32 err = solo_reg_read(solo_dev, SOLO_PCI_ERR); + solo_p2m_error_isr(solo_dev, err); + solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_PCI_ERR); + } + + for (i = 0; i < SOLO_NR_P2M; i++) + if (status & SOLO_IRQ_P2M(i)) + solo_p2m_isr(solo_dev, i); + + if (status & SOLO_IRQ_IIC) + solo_i2c_isr(solo_dev); + + if (status & SOLO_IRQ_VIDEO_IN) + solo_video_in_isr(solo_dev); + + /* Call this first so enc gets detected flag set */ + if (status & SOLO_IRQ_MOTION) + solo_motion_isr(solo_dev); + + if (status & SOLO_IRQ_ENCODER) + solo_enc_v4l2_isr(solo_dev); + + if (status & SOLO_IRQ_G723) + solo_g723_isr(solo_dev); + + return IRQ_HANDLED; +} + +static void free_solo_dev(struct solo6010_dev *solo_dev) +{ + struct pci_dev *pdev; + + if (!solo_dev) + return; + + pdev = solo_dev->pdev; + + /* If we never initialized the PCI device, then nothing else + * below here needs cleanup */ + if (!pdev) { + kfree(solo_dev); + return; + } + + /* Bring down the sub-devices first */ + solo_g723_exit(solo_dev); + solo_enc_v4l2_exit(solo_dev); + solo_enc_exit(solo_dev); + solo_v4l2_exit(solo_dev); + solo_disp_exit(solo_dev); + solo_gpio_exit(solo_dev); + solo_p2m_exit(solo_dev); + solo_i2c_exit(solo_dev); + + /* Now cleanup the PCI device */ + if (solo_dev->reg_base) { + solo6010_irq_off(solo_dev, ~0); + pci_iounmap(pdev, solo_dev->reg_base); + free_irq(pdev->irq, solo_dev); + } + + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + + kfree(solo_dev); +} + +static int __devinit solo6010_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + struct solo6010_dev *solo_dev; + int ret; + int sdram; + u8 chip_id; + u32 reg; + + solo_dev = kzalloc(sizeof(*solo_dev), GFP_KERNEL); + if (solo_dev == NULL) + return -ENOMEM; + + solo_dev->pdev = pdev; + spin_lock_init(&solo_dev->reg_io_lock); + pci_set_drvdata(pdev, solo_dev); + + ret = pci_enable_device(pdev); + if (ret) + goto fail_probe; + + pci_set_master(pdev); + + ret = pci_request_regions(pdev, SOLO6010_NAME); + if (ret) + goto fail_probe; + + solo_dev->reg_base = pci_ioremap_bar(pdev, 0); + if (solo_dev->reg_base == NULL) { + ret = -ENOMEM; + goto fail_probe; + } + + chip_id = solo_reg_read(solo_dev, SOLO_CHIP_OPTION) & + SOLO_CHIP_ID_MASK; + switch (chip_id) { + case 7: + solo_dev->nr_chans = 16; + solo_dev->nr_ext = 5; + break; + case 6: + solo_dev->nr_chans = 8; + solo_dev->nr_ext = 2; + break; + default: + dev_warn(&pdev->dev, "Invalid chip_id 0x%02x, " + "defaulting to 4 channels\n", + chip_id); + case 5: + solo_dev->nr_chans = 4; + solo_dev->nr_ext = 1; + } + + solo_dev->flags = id->driver_data; + + /* Disable all interrupts to start */ + solo6010_irq_off(solo_dev, ~0); + + reg = SOLO_SYS_CFG_SDRAM64BIT; + /* Initial global settings */ + if (!(solo_dev->flags & FLAGS_6110)) + reg |= SOLO6010_SYS_CFG_INPUTDIV(25) | + SOLO6010_SYS_CFG_FEEDBACKDIV((SOLO_CLOCK_MHZ * 2) - 2) | + SOLO6010_SYS_CFG_OUTDIV(3); + solo_reg_write(solo_dev, SOLO_SYS_CFG, reg); + + if (solo_dev->flags & FLAGS_6110) { + u32 sys_clock_MHz = SOLO_CLOCK_MHZ; + u32 pll_DIVQ; + u32 pll_DIVF; + + if (sys_clock_MHz < 125) { + pll_DIVQ = 3; + pll_DIVF = (sys_clock_MHz * 4) / 3; + } else { + pll_DIVQ = 2; + pll_DIVF = (sys_clock_MHz * 2) / 3; + } + + solo_reg_write(solo_dev, SOLO6110_PLL_CONFIG, + SOLO6110_PLL_RANGE_5_10MHZ | + SOLO6110_PLL_DIVR(9) | + SOLO6110_PLL_DIVQ_EXP(pll_DIVQ) | + SOLO6110_PLL_DIVF(pll_DIVF) | SOLO6110_PLL_FSEN); + mdelay(1); // PLL Locking time (1ms) + + solo_reg_write(solo_dev, SOLO_DMA_CTRL1, 3 << 8); /* ? */ + } else + solo_reg_write(solo_dev, SOLO_DMA_CTRL1, 1 << 8); /* ? */ + + solo_reg_write(solo_dev, SOLO_TIMER_CLOCK_NUM, SOLO_CLOCK_MHZ - 1); + + /* PLL locking time of 1ms */ + mdelay(1); + + ret = request_irq(pdev->irq, solo6010_isr, IRQF_SHARED, SOLO6010_NAME, + solo_dev); + if (ret) + goto fail_probe; + + /* Handle this from the start */ + solo6010_irq_on(solo_dev, SOLO_IRQ_PCI_ERR); + + ret = solo_i2c_init(solo_dev); + if (ret) + goto fail_probe; + + /* Setup the DMA engine */ + sdram = (solo_dev->nr_chans >= 8) ? 2 : 1; + solo_reg_write(solo_dev, SOLO_DMA_CTRL, + SOLO_DMA_CTRL_REFRESH_CYCLE(1) | + SOLO_DMA_CTRL_SDRAM_SIZE(sdram) | + SOLO_DMA_CTRL_SDRAM_CLK_INVERT | + SOLO_DMA_CTRL_READ_CLK_SELECT | + SOLO_DMA_CTRL_LATENCY(1)); + + ret = solo_p2m_init(solo_dev); + if (ret) + goto fail_probe; + + ret = solo_disp_init(solo_dev); + if (ret) + goto fail_probe; + + ret = solo_gpio_init(solo_dev); + if (ret) + goto fail_probe; + + ret = solo_tw28_init(solo_dev); + if (ret) + goto fail_probe; + + ret = solo_v4l2_init(solo_dev); + if (ret) + goto fail_probe; + + ret = solo_enc_init(solo_dev); + if (ret) + goto fail_probe; + + ret = solo_enc_v4l2_init(solo_dev); + if (ret) + goto fail_probe; + + ret = solo_g723_init(solo_dev); + if (ret) + goto fail_probe; + + return 0; + +fail_probe: + free_solo_dev(solo_dev); + return ret; +} + +static void __devexit solo6010_pci_remove(struct pci_dev *pdev) +{ + struct solo6010_dev *solo_dev = pci_get_drvdata(pdev); + + free_solo_dev(solo_dev); +} + +static struct pci_device_id solo6010_id_table[] = { + /* 6010 based cards */ + {PCI_DEVICE(PCI_VENDOR_ID_SOFTLOGIC, PCI_DEVICE_ID_SOLO6010)}, + {PCI_DEVICE(PCI_VENDOR_ID_SOFTLOGIC, PCI_DEVICE_ID_SOLO6110), + .driver_data = FLAGS_6110}, + {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_4)}, + {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_9)}, + {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_16)}, + {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_SOLO_4)}, + {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_SOLO_9)}, + {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_SOLO_16)}, + /* 6110 based cards */ + {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_6110_4)}, + {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_6110_8)}, + {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_6110_16)}, + {0,} +}; + +MODULE_DEVICE_TABLE(pci, solo6010_id_table); + +static struct pci_driver solo6010_pci_driver = { + .name = SOLO6010_NAME, + .id_table = solo6010_id_table, + .probe = solo6010_pci_probe, + .remove = solo6010_pci_remove, +}; + +static int __init solo6010_module_init(void) +{ + return pci_register_driver(&solo6010_pci_driver); +} + +static void __exit solo6010_module_exit(void) +{ + pci_unregister_driver(&solo6010_pci_driver); +} + +module_init(solo6010_module_init); +module_exit(solo6010_module_exit); diff --git a/drivers/staging/solo6x10/disp.c b/drivers/staging/solo6x10/disp.c new file mode 100644 index 000000000000..1b0cfa8803eb --- /dev/null +++ b/drivers/staging/solo6x10/disp.c @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com + * Copyright (C) 2010 Ben Collins + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include "solo6x10.h" + +#define SOLO_VCLK_DELAY 3 +#define SOLO_PROGRESSIVE_VSIZE 1024 + +#define SOLO_MOT_THRESH_W 64 +#define SOLO_MOT_THRESH_H 64 +#define SOLO_MOT_THRESH_SIZE 8192 +#define SOLO_MOT_THRESH_REAL (SOLO_MOT_THRESH_W * SOLO_MOT_THRESH_H) +#define SOLO_MOT_FLAG_SIZE 512 +#define SOLO_MOT_FLAG_AREA (SOLO_MOT_FLAG_SIZE * 32) + +static unsigned video_type; +module_param(video_type, uint, 0644); +MODULE_PARM_DESC(video_type, "video_type (0 = NTSC/Default, 1 = PAL)"); + +static void solo_vin_config(struct solo6010_dev *solo_dev) +{ + solo_dev->vin_hstart = 8; + solo_dev->vin_vstart = 2; + + solo_reg_write(solo_dev, SOLO_SYS_VCLK, + SOLO_VCLK_SELECT(2) | + SOLO_VCLK_VIN1415_DELAY(SOLO_VCLK_DELAY) | + SOLO_VCLK_VIN1213_DELAY(SOLO_VCLK_DELAY) | + SOLO_VCLK_VIN1011_DELAY(SOLO_VCLK_DELAY) | + SOLO_VCLK_VIN0809_DELAY(SOLO_VCLK_DELAY) | + SOLO_VCLK_VIN0607_DELAY(SOLO_VCLK_DELAY) | + SOLO_VCLK_VIN0405_DELAY(SOLO_VCLK_DELAY) | + SOLO_VCLK_VIN0203_DELAY(SOLO_VCLK_DELAY) | + SOLO_VCLK_VIN0001_DELAY(SOLO_VCLK_DELAY)); + + solo_reg_write(solo_dev, SOLO_VI_ACT_I_P, + SOLO_VI_H_START(solo_dev->vin_hstart) | + SOLO_VI_V_START(solo_dev->vin_vstart) | + SOLO_VI_V_STOP(solo_dev->vin_vstart + + solo_dev->video_vsize)); + + solo_reg_write(solo_dev, SOLO_VI_ACT_I_S, + SOLO_VI_H_START(solo_dev->vout_hstart) | + SOLO_VI_V_START(solo_dev->vout_vstart) | + SOLO_VI_V_STOP(solo_dev->vout_vstart + + solo_dev->video_vsize)); + + solo_reg_write(solo_dev, SOLO_VI_ACT_P, + SOLO_VI_H_START(0) | + SOLO_VI_V_START(1) | + SOLO_VI_V_STOP(SOLO_PROGRESSIVE_VSIZE)); + + solo_reg_write(solo_dev, SOLO_VI_CH_FORMAT, + SOLO_VI_FD_SEL_MASK(0) | SOLO_VI_PROG_MASK(0)); + + solo_reg_write(solo_dev, SOLO_VI_FMT_CFG, 0); + solo_reg_write(solo_dev, SOLO_VI_PAGE_SW, 2); + + if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) { + solo_reg_write(solo_dev, SOLO_VI_PB_CONFIG, + SOLO_VI_PB_USER_MODE); + solo_reg_write(solo_dev, SOLO_VI_PB_RANGE_HV, + SOLO_VI_PB_HSIZE(858) | SOLO_VI_PB_VSIZE(246)); + solo_reg_write(solo_dev, SOLO_VI_PB_ACT_V, + SOLO_VI_PB_VSTART(4) | + SOLO_VI_PB_VSTOP(4 + 240)); + } else { + solo_reg_write(solo_dev, SOLO_VI_PB_CONFIG, + SOLO_VI_PB_USER_MODE | SOLO_VI_PB_PAL); + solo_reg_write(solo_dev, SOLO_VI_PB_RANGE_HV, + SOLO_VI_PB_HSIZE(864) | SOLO_VI_PB_VSIZE(294)); + solo_reg_write(solo_dev, SOLO_VI_PB_ACT_V, + SOLO_VI_PB_VSTART(4) | + SOLO_VI_PB_VSTOP(4 + 288)); + } + solo_reg_write(solo_dev, SOLO_VI_PB_ACT_H, SOLO_VI_PB_HSTART(16) | + SOLO_VI_PB_HSTOP(16 + 720)); +} + +static void solo_disp_config(struct solo6010_dev *solo_dev) +{ + solo_dev->vout_hstart = 6; + solo_dev->vout_vstart = 8; + + solo_reg_write(solo_dev, SOLO_VO_BORDER_LINE_COLOR, + (0xa0 << 24) | (0x88 << 16) | (0xa0 << 8) | 0x88); + solo_reg_write(solo_dev, SOLO_VO_BORDER_FILL_COLOR, + (0x10 << 24) | (0x8f << 16) | (0x10 << 8) | 0x8f); + solo_reg_write(solo_dev, SOLO_VO_BKG_COLOR, + (16 << 24) | (128 << 16) | (16 << 8) | 128); + + solo_reg_write(solo_dev, SOLO_VO_FMT_ENC, + solo_dev->video_type | + SOLO_VO_USER_COLOR_SET_NAV | + SOLO_VO_NA_COLOR_Y(0) | + SOLO_VO_NA_COLOR_CB(0) | + SOLO_VO_NA_COLOR_CR(0)); + + solo_reg_write(solo_dev, SOLO_VO_ACT_H, + SOLO_VO_H_START(solo_dev->vout_hstart) | + SOLO_VO_H_STOP(solo_dev->vout_hstart + + solo_dev->video_hsize)); + + solo_reg_write(solo_dev, SOLO_VO_ACT_V, + SOLO_VO_V_START(solo_dev->vout_vstart) | + SOLO_VO_V_STOP(solo_dev->vout_vstart + + solo_dev->video_vsize)); + + solo_reg_write(solo_dev, SOLO_VO_RANGE_HV, + SOLO_VO_H_LEN(solo_dev->video_hsize) | + SOLO_VO_V_LEN(solo_dev->video_vsize)); + + solo_reg_write(solo_dev, SOLO_VI_WIN_SW, 5); + + solo_reg_write(solo_dev, SOLO_VO_DISP_CTRL, SOLO_VO_DISP_ON | + SOLO_VO_DISP_ERASE_COUNT(8) | + SOLO_VO_DISP_BASE(SOLO_DISP_EXT_ADDR)); + + solo_reg_write(solo_dev, SOLO_VO_DISP_ERASE, SOLO_VO_DISP_ERASE_ON); + + /* Enable channels we support */ + solo_reg_write(solo_dev, SOLO_VI_CH_ENA, (1 << solo_dev->nr_chans) - 1); + + /* Disable the watchdog */ + solo_reg_write(solo_dev, SOLO_WATCHDOG, 0); +} + +static int solo_dma_vin_region(struct solo6010_dev *solo_dev, u32 off, + u16 val, int reg_size) +{ + u16 buf[64]; + int i; + int ret = 0; + + for (i = 0; i < sizeof(buf) >> 1; i++) + buf[i] = val; + + for (i = 0; i < reg_size; i += sizeof(buf)) + ret |= solo_p2m_dma(solo_dev, SOLO_P2M_DMA_ID_VIN, 1, buf, + SOLO_MOTION_EXT_ADDR(solo_dev) + off + i, + sizeof(buf)); + + return ret; +} + +void solo_set_motion_threshold(struct solo6010_dev *solo_dev, u8 ch, u16 val) +{ + if (ch > solo_dev->nr_chans) + return; + + solo_dma_vin_region(solo_dev, SOLO_MOT_FLAG_AREA + + (ch * SOLO_MOT_THRESH_SIZE * 2), + val, SOLO_MOT_THRESH_REAL); +} + +/* First 8k is motion flag (512 bytes * 16). Following that is an 8k+8k + * threshold and working table for each channel. Atleast that's what the + * spec says. However, this code (take from rdk) has some mystery 8k + * block right after the flag area, before the first thresh table. */ +static void solo_motion_config(struct solo6010_dev *solo_dev) +{ + int i; + + for (i = 0; i < solo_dev->nr_chans; i++) { + /* Clear motion flag area */ + solo_dma_vin_region(solo_dev, i * SOLO_MOT_FLAG_SIZE, 0x0000, + SOLO_MOT_FLAG_SIZE); + + /* Clear working cache table */ + solo_dma_vin_region(solo_dev, SOLO_MOT_FLAG_AREA + + SOLO_MOT_THRESH_SIZE + + (i * SOLO_MOT_THRESH_SIZE * 2), + 0x0000, SOLO_MOT_THRESH_REAL); + + /* Set default threshold table */ + solo_set_motion_threshold(solo_dev, i, SOLO_DEF_MOT_THRESH); + } + + /* Default motion settings */ + solo_reg_write(solo_dev, SOLO_VI_MOT_ADR, SOLO_VI_MOTION_EN(0) | + (SOLO_MOTION_EXT_ADDR(solo_dev) >> 16)); + solo_reg_write(solo_dev, SOLO_VI_MOT_CTRL, + SOLO_VI_MOTION_FRAME_COUNT(3) | + SOLO_VI_MOTION_SAMPLE_LENGTH(solo_dev->video_hsize / 16) + | /* SOLO_VI_MOTION_INTR_START_STOP | */ + SOLO_VI_MOTION_SAMPLE_COUNT(10)); + + solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER, 0); + solo_reg_write(solo_dev, SOLO_VI_MOTION_BAR, 0); +} + +int solo_disp_init(struct solo6010_dev *solo_dev) +{ + int i; + + solo_dev->video_hsize = 704; + if (video_type == 0) { + solo_dev->video_type = SOLO_VO_FMT_TYPE_NTSC; + solo_dev->video_vsize = 240; + solo_dev->fps = 30; + } else { + solo_dev->video_type = SOLO_VO_FMT_TYPE_PAL; + solo_dev->video_vsize = 288; + solo_dev->fps = 25; + } + + solo_vin_config(solo_dev); + solo_motion_config(solo_dev); + solo_disp_config(solo_dev); + + for (i = 0; i < solo_dev->nr_chans; i++) + solo_reg_write(solo_dev, SOLO_VI_WIN_ON(i), 1); + + return 0; +} + +void solo_disp_exit(struct solo6010_dev *solo_dev) +{ + int i; + + solo6010_irq_off(solo_dev, SOLO_IRQ_MOTION); + + solo_reg_write(solo_dev, SOLO_VO_DISP_CTRL, 0); + solo_reg_write(solo_dev, SOLO_VO_ZOOM_CTRL, 0); + solo_reg_write(solo_dev, SOLO_VO_FREEZE_CTRL, 0); + + for (i = 0; i < solo_dev->nr_chans; i++) { + solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL0(i), 0); + solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL1(i), 0); + solo_reg_write(solo_dev, SOLO_VI_WIN_ON(i), 0); + } + + /* Set default border */ + for (i = 0; i < 5; i++) + solo_reg_write(solo_dev, SOLO_VO_BORDER_X(i), 0); + + for (i = 0; i < 5; i++) + solo_reg_write(solo_dev, SOLO_VO_BORDER_Y(i), 0); + + solo_reg_write(solo_dev, SOLO_VO_BORDER_LINE_MASK, 0); + solo_reg_write(solo_dev, SOLO_VO_BORDER_FILL_MASK, 0); + + solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_CTRL(0), 0); + solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_START(0), 0); + solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_STOP(0), 0); + + solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_CTRL(1), 0); + solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_START(1), 0); + solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_STOP(1), 0); +} diff --git a/drivers/staging/solo6x10/enc.c b/drivers/staging/solo6x10/enc.c new file mode 100644 index 000000000000..755626c1a2ec --- /dev/null +++ b/drivers/staging/solo6x10/enc.c @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com + * Copyright (C) 2010 Ben Collins + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include "solo6x10.h" +#include "osd-font.h" + +#define CAPTURE_MAX_BANDWIDTH 32 /* D1 4channel (D1 == 4) */ +#define OSG_BUFFER_SIZE 1024 + +#define VI_PROG_HSIZE (1280 - 16) +#define VI_PROG_VSIZE (1024 - 16) + +static void solo_capture_config(struct solo6010_dev *solo_dev) +{ + int i, j; + unsigned long height; + unsigned long width; + unsigned char *buf; + + solo_reg_write(solo_dev, SOLO_CAP_BASE, + SOLO_CAP_MAX_PAGE(SOLO_CAP_EXT_MAX_PAGE * + solo_dev->nr_chans) | + SOLO_CAP_BASE_ADDR(SOLO_CAP_EXT_ADDR(solo_dev) >> 16)); + solo_reg_write(solo_dev, SOLO_CAP_BTW, + (1 << 17) | SOLO_CAP_PROG_BANDWIDTH(2) | + SOLO_CAP_MAX_BANDWIDTH(CAPTURE_MAX_BANDWIDTH)); + + /* Set scale 1, 9 dimension */ + width = solo_dev->video_hsize; + height = solo_dev->video_vsize; + solo_reg_write(solo_dev, SOLO_DIM_SCALE1, + SOLO_DIM_H_MB_NUM(width / 16) | + SOLO_DIM_V_MB_NUM_FRAME(height / 8) | + SOLO_DIM_V_MB_NUM_FIELD(height / 16)); + + /* Set scale 2, 10 dimension */ + width = solo_dev->video_hsize / 2; + height = solo_dev->video_vsize; + solo_reg_write(solo_dev, SOLO_DIM_SCALE2, + SOLO_DIM_H_MB_NUM(width / 16) | + SOLO_DIM_V_MB_NUM_FRAME(height / 8) | + SOLO_DIM_V_MB_NUM_FIELD(height / 16)); + + /* Set scale 3, 11 dimension */ + width = solo_dev->video_hsize / 2; + height = solo_dev->video_vsize / 2; + solo_reg_write(solo_dev, SOLO_DIM_SCALE3, + SOLO_DIM_H_MB_NUM(width / 16) | + SOLO_DIM_V_MB_NUM_FRAME(height / 8) | + SOLO_DIM_V_MB_NUM_FIELD(height / 16)); + + /* Set scale 4, 12 dimension */ + width = solo_dev->video_hsize / 3; + height = solo_dev->video_vsize / 3; + solo_reg_write(solo_dev, SOLO_DIM_SCALE4, + SOLO_DIM_H_MB_NUM(width / 16) | + SOLO_DIM_V_MB_NUM_FRAME(height / 8) | + SOLO_DIM_V_MB_NUM_FIELD(height / 16)); + + /* Set scale 5, 13 dimension */ + width = solo_dev->video_hsize / 4; + height = solo_dev->video_vsize / 2; + solo_reg_write(solo_dev, SOLO_DIM_SCALE5, + SOLO_DIM_H_MB_NUM(width / 16) | + SOLO_DIM_V_MB_NUM_FRAME(height / 8) | + SOLO_DIM_V_MB_NUM_FIELD(height / 16)); + + /* Progressive */ + width = VI_PROG_HSIZE; + height = VI_PROG_VSIZE; + solo_reg_write(solo_dev, SOLO_DIM_PROG, + SOLO_DIM_H_MB_NUM(width / 16) | + SOLO_DIM_V_MB_NUM_FRAME(height / 16) | + SOLO_DIM_V_MB_NUM_FIELD(height / 16)); + + /* Clear OSD */ + solo_reg_write(solo_dev, SOLO_VE_OSD_CH, 0); + solo_reg_write(solo_dev, SOLO_VE_OSD_BASE, SOLO_EOSD_EXT_ADDR >> 16); + solo_reg_write(solo_dev, SOLO_VE_OSD_CLR, + 0xF0 << 16 | 0x80 << 8 | 0x80); + solo_reg_write(solo_dev, SOLO_VE_OSD_OPT, 0); + + /* Clear OSG buffer */ + buf = kzalloc(OSG_BUFFER_SIZE, GFP_KERNEL); + if (!buf) + return; + + for (i = 0; i < solo_dev->nr_chans; i++) { + for (j = 0; j < SOLO_EOSD_EXT_SIZE; j += OSG_BUFFER_SIZE) { + solo_p2m_dma(solo_dev, SOLO_P2M_DMA_ID_MP4E, 1, buf, + SOLO_EOSD_EXT_ADDR + + (i * SOLO_EOSD_EXT_SIZE) + j, + OSG_BUFFER_SIZE); + } + } + kfree(buf); +} + +int solo_osd_print(struct solo_enc_dev *solo_enc) +{ + struct solo6010_dev *solo_dev = solo_enc->solo_dev; + char *str = solo_enc->osd_text; + u8 *buf; + u32 reg = solo_reg_read(solo_dev, SOLO_VE_OSD_CH); + int len = strlen(str); + int i, j; + int x = 1, y = 1; + + if (len == 0) { + reg &= ~(1 << solo_enc->ch); + solo_reg_write(solo_dev, SOLO_VE_OSD_CH, reg); + return 0; + } + + buf = kzalloc(SOLO_EOSD_EXT_SIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + for (i = 0; i < len; i++) { + for (j = 0; j < 16; j++) { + buf[(j*2) + (i%2) + ((x + (i/2)) * 32) + (y * 2048)] = + (solo_osd_font[(str[i] * 4) + (j / 4)] + >> ((3 - (j % 4)) * 8)) & 0xff; + } + } + + solo_p2m_dma(solo_dev, 0, 1, buf, SOLO_EOSD_EXT_ADDR + + (solo_enc->ch * SOLO_EOSD_EXT_SIZE), SOLO_EOSD_EXT_SIZE); + reg |= (1 << solo_enc->ch); + solo_reg_write(solo_dev, SOLO_VE_OSD_CH, reg); + + kfree(buf); + + return 0; +} + +static void solo_jpeg_config(struct solo6010_dev *solo_dev) +{ + u32 reg; + if (solo_dev->flags & FLAGS_6110) + reg = (4 << 24) | (3 << 16) | (2 << 8) | (1 << 0); + else + reg = (2 << 24) | (2 << 16) | (2 << 8) | (2 << 0); + solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_TBL, reg); + solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_CH_L, 0); + solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_CH_H, 0); + solo_reg_write(solo_dev, SOLO_VE_JPEG_CFG, + (SOLO_JPEG_EXT_SIZE(solo_dev) & 0xffff0000) | + ((SOLO_JPEG_EXT_ADDR(solo_dev) >> 16) & 0x0000ffff)); + solo_reg_write(solo_dev, SOLO_VE_JPEG_CTRL, 0xffffffff); + /* que limit, samp limit, pos limit */ + solo_reg_write(solo_dev, 0x0688, (0 << 16) | (30 << 8) | 60); +} + +static void solo_mp4e_config(struct solo6010_dev *solo_dev) +{ + int i; + u32 reg; + + /* We can only use VE_INTR_CTRL(0) if we want to support mjpeg */ + solo_reg_write(solo_dev, SOLO_VE_CFG0, + SOLO_VE_INTR_CTRL(0) | + SOLO_VE_BLOCK_SIZE(SOLO_MP4E_EXT_SIZE(solo_dev) >> 16) | + SOLO_VE_BLOCK_BASE(SOLO_MP4E_EXT_ADDR(solo_dev) >> 16)); + + solo_reg_write(solo_dev, SOLO_VE_CFG1, + SOLO_VE_INSERT_INDEX | SOLO_VE_MOTION_MODE(0)); + + solo_reg_write(solo_dev, SOLO_VE_WMRK_POLY, 0); + solo_reg_write(solo_dev, SOLO_VE_VMRK_INIT_KEY, 0); + solo_reg_write(solo_dev, SOLO_VE_WMRK_STRL, 0); + solo_reg_write(solo_dev, SOLO_VE_ENCRYP_POLY, 0); + solo_reg_write(solo_dev, SOLO_VE_ENCRYP_INIT, 0); + + reg = SOLO_VE_LITTLE_ENDIAN | SOLO_COMP_ATTR_FCODE(1) | + SOLO_COMP_TIME_INC(0) | SOLO_COMP_TIME_WIDTH(15); + if (solo_dev->flags & FLAGS_6110) + reg |= SOLO_DCT_INTERVAL(10); + else + reg |= SOLO_DCT_INTERVAL(36 / 4); + solo_reg_write(solo_dev, SOLO_VE_ATTR, reg); + + for (i = 0; i < solo_dev->nr_chans; i++) + solo_reg_write(solo_dev, SOLO_VE_CH_REF_BASE(i), + (SOLO_EREF_EXT_ADDR(solo_dev) + + (i * SOLO_EREF_EXT_SIZE)) >> 16); + + if (solo_dev->flags & FLAGS_6110) + solo_reg_write(solo_dev, 0x0634, 0x00040008); /* ? */ +} + +int solo_enc_init(struct solo6010_dev *solo_dev) +{ + int i; + + solo_capture_config(solo_dev); + solo_mp4e_config(solo_dev); + solo_jpeg_config(solo_dev); + + for (i = 0; i < solo_dev->nr_chans; i++) { + solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(i), 0); + solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(i), 0); + } + + solo6010_irq_on(solo_dev, SOLO_IRQ_ENCODER); + + return 0; +} + +void solo_enc_exit(struct solo6010_dev *solo_dev) +{ + int i; + + solo6010_irq_off(solo_dev, SOLO_IRQ_ENCODER); + + for (i = 0; i < solo_dev->nr_chans; i++) { + solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(i), 0); + solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(i), 0); + } +} diff --git a/drivers/staging/solo6x10/g723.c b/drivers/staging/solo6x10/g723.c new file mode 100644 index 000000000000..4aba8f3dbe60 --- /dev/null +++ b/drivers/staging/solo6x10/g723.c @@ -0,0 +1,398 @@ +/* + * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com + * Copyright (C) 2010 Ben Collins + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "solo6x10.h" +#include "tw28.h" + +#define G723_INTR_ORDER 0 +#define G723_FDMA_PAGES 32 +#define G723_PERIOD_BYTES 48 +#define G723_PERIOD_BLOCK 1024 +#define G723_FRAMES_PER_PAGE 48 + +/* Sets up channels 16-19 for decoding and 0-15 for encoding */ +#define OUTMODE_MASK 0x300 + +#define SAMPLERATE 8000 +#define BITRATE 25 + +/* The solo writes to 1k byte pages, 32 pages, in the dma. Each 1k page + * is broken down to 20 * 48 byte regions (one for each channel possible) + * with the rest of the page being dummy data. */ +#define MAX_BUFFER (G723_PERIOD_BYTES * PERIODS_MAX) +#define IRQ_PAGES 4 /* 0 - 4 */ +#define PERIODS_MIN (1 << IRQ_PAGES) +#define PERIODS_MAX G723_FDMA_PAGES + +struct solo_snd_pcm { + int on; + spinlock_t lock; + struct solo6010_dev *solo_dev; + unsigned char g723_buf[G723_PERIOD_BYTES]; +}; + +static void solo_g723_config(struct solo6010_dev *solo_dev) +{ + int clk_div; + + clk_div = SOLO_CLOCK_MHZ / (SAMPLERATE * (BITRATE * 2) * 2); + + solo_reg_write(solo_dev, SOLO_AUDIO_SAMPLE, + SOLO_AUDIO_BITRATE(BITRATE) | + SOLO_AUDIO_CLK_DIV(clk_div)); + + solo_reg_write(solo_dev, SOLO_AUDIO_FDMA_INTR, + SOLO_AUDIO_FDMA_INTERVAL(IRQ_PAGES) | + SOLO_AUDIO_INTR_ORDER(G723_INTR_ORDER) | + SOLO_AUDIO_FDMA_BASE(SOLO_G723_EXT_ADDR(solo_dev) >> 16)); + + solo_reg_write(solo_dev, SOLO_AUDIO_CONTROL, + SOLO_AUDIO_ENABLE | SOLO_AUDIO_I2S_MODE | + SOLO_AUDIO_I2S_MULTI(3) | SOLO_AUDIO_MODE(OUTMODE_MASK)); +} + +void solo_g723_isr(struct solo6010_dev *solo_dev) +{ + struct snd_pcm_str *pstr = + &solo_dev->snd_pcm->streams[SNDRV_PCM_STREAM_CAPTURE]; + struct snd_pcm_substream *ss; + struct solo_snd_pcm *solo_pcm; + + solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_G723); + + for (ss = pstr->substream; ss != NULL; ss = ss->next) { + if (snd_pcm_substream_chip(ss) == NULL) + continue; + + /* This means open() hasn't been called on this one */ + if (snd_pcm_substream_chip(ss) == solo_dev) + continue; + + /* Haven't triggered a start yet */ + solo_pcm = snd_pcm_substream_chip(ss); + if (!solo_pcm->on) + continue; + + snd_pcm_period_elapsed(ss); + } +} + +static int snd_solo_hw_params(struct snd_pcm_substream *ss, + struct snd_pcm_hw_params *hw_params) +{ + return snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw_params)); +} + +static int snd_solo_hw_free(struct snd_pcm_substream *ss) +{ + return snd_pcm_lib_free_pages(ss); +} + +static struct snd_pcm_hardware snd_solo_pcm_hw = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID), + .formats = SNDRV_PCM_FMTBIT_U8, + .rates = SNDRV_PCM_RATE_8000, + .rate_min = 8000, + .rate_max = 8000, + .channels_min = 1, + .channels_max = 1, + .buffer_bytes_max = MAX_BUFFER, + .period_bytes_min = G723_PERIOD_BYTES, + .period_bytes_max = G723_PERIOD_BYTES, + .periods_min = PERIODS_MIN, + .periods_max = PERIODS_MAX, +}; + +static int snd_solo_pcm_open(struct snd_pcm_substream *ss) +{ + struct solo6010_dev *solo_dev = snd_pcm_substream_chip(ss); + struct solo_snd_pcm *solo_pcm; + + solo_pcm = kzalloc(sizeof(*solo_pcm), GFP_KERNEL); + if (solo_pcm == NULL) + return -ENOMEM; + + spin_lock_init(&solo_pcm->lock); + solo_pcm->solo_dev = solo_dev; + ss->runtime->hw = snd_solo_pcm_hw; + + snd_pcm_substream_chip(ss) = solo_pcm; + + return 0; +} + +static int snd_solo_pcm_close(struct snd_pcm_substream *ss) +{ + struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); + + snd_pcm_substream_chip(ss) = solo_pcm->solo_dev; + kfree(solo_pcm); + + return 0; +} + +static int snd_solo_pcm_trigger(struct snd_pcm_substream *ss, int cmd) +{ + struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); + struct solo6010_dev *solo_dev = solo_pcm->solo_dev; + int ret = 0; + + spin_lock(&solo_pcm->lock); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + if (solo_pcm->on == 0) { + /* If this is the first user, switch on interrupts */ + if (atomic_inc_return(&solo_dev->snd_users) == 1) + solo6010_irq_on(solo_dev, SOLO_IRQ_G723); + solo_pcm->on = 1; + } + break; + case SNDRV_PCM_TRIGGER_STOP: + if (solo_pcm->on) { + /* If this was our last user, switch them off */ + if (atomic_dec_return(&solo_dev->snd_users) == 0) + solo6010_irq_off(solo_dev, SOLO_IRQ_G723); + solo_pcm->on = 0; + } + break; + default: + ret = -EINVAL; + } + + spin_unlock(&solo_pcm->lock); + + return ret; +} + +static int snd_solo_pcm_prepare(struct snd_pcm_substream *ss) +{ + return 0; +} + +static snd_pcm_uframes_t snd_solo_pcm_pointer(struct snd_pcm_substream *ss) +{ + struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); + struct solo6010_dev *solo_dev = solo_pcm->solo_dev; + snd_pcm_uframes_t idx = solo_reg_read(solo_dev, SOLO_AUDIO_STA) & 0x1f; + + return idx * G723_FRAMES_PER_PAGE; +} + +static int snd_solo_pcm_copy(struct snd_pcm_substream *ss, int channel, + snd_pcm_uframes_t pos, void __user *dst, + snd_pcm_uframes_t count) +{ + struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); + struct solo6010_dev *solo_dev = solo_pcm->solo_dev; + int err, i; + + for (i = 0; i < (count / G723_FRAMES_PER_PAGE); i++) { + int page = (pos / G723_FRAMES_PER_PAGE) + i; + + err = solo_p2m_dma(solo_dev, SOLO_P2M_DMA_ID_G723E, 0, + solo_pcm->g723_buf, + SOLO_G723_EXT_ADDR(solo_dev) + + (page * G723_PERIOD_BLOCK) + + (ss->number * G723_PERIOD_BYTES), + G723_PERIOD_BYTES); + if (err) + return err; + + err = copy_to_user(dst + (i * G723_PERIOD_BYTES), + solo_pcm->g723_buf, G723_PERIOD_BYTES); + + if (err) + return -EFAULT; + } + + return 0; +} + +static struct snd_pcm_ops snd_solo_pcm_ops = { + .open = snd_solo_pcm_open, + .close = snd_solo_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_solo_hw_params, + .hw_free = snd_solo_hw_free, + .prepare = snd_solo_pcm_prepare, + .trigger = snd_solo_pcm_trigger, + .pointer = snd_solo_pcm_pointer, + .copy = snd_solo_pcm_copy, +}; + +static int snd_solo_capture_volume_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *info) +{ + info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + info->count = 1; + info->value.integer.min = 0; + info->value.integer.max = 15; + info->value.integer.step = 1; + + return 0; +} + +static int snd_solo_capture_volume_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *value) +{ + struct solo6010_dev *solo_dev = snd_kcontrol_chip(kcontrol); + u8 ch = value->id.numid - 1; + + value->value.integer.value[0] = tw28_get_audio_gain(solo_dev, ch); + + return 0; +} + +static int snd_solo_capture_volume_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *value) +{ + struct solo6010_dev *solo_dev = snd_kcontrol_chip(kcontrol); + u8 ch = value->id.numid - 1; + u8 old_val; + + old_val = tw28_get_audio_gain(solo_dev, ch); + if (old_val == value->value.integer.value[0]) + return 0; + + tw28_set_audio_gain(solo_dev, ch, value->value.integer.value[0]); + + return 1; +} + +static struct snd_kcontrol_new snd_solo_capture_volume = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Volume", + .info = snd_solo_capture_volume_info, + .get = snd_solo_capture_volume_get, + .put = snd_solo_capture_volume_put, +}; + +static int solo_snd_pcm_init(struct solo6010_dev *solo_dev) +{ + struct snd_card *card = solo_dev->snd_card; + struct snd_pcm *pcm; + struct snd_pcm_substream *ss; + int ret; + int i; + + ret = snd_pcm_new(card, card->driver, 0, 0, solo_dev->nr_chans, + &pcm); + if (ret < 0) + return ret; + + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, + &snd_solo_pcm_ops); + + snd_pcm_chip(pcm) = solo_dev; + pcm->info_flags = 0; + strcpy(pcm->name, card->shortname); + + for (i = 0, ss = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; + ss; ss = ss->next, i++) + sprintf(ss->name, "Camera #%d Audio", i); + + ret = snd_pcm_lib_preallocate_pages_for_all(pcm, + SNDRV_DMA_TYPE_CONTINUOUS, + snd_dma_continuous_data(GFP_KERNEL), + MAX_BUFFER, MAX_BUFFER); + if (ret < 0) + return ret; + + solo_dev->snd_pcm = pcm; + + return 0; +} + +int solo_g723_init(struct solo6010_dev *solo_dev) +{ + static struct snd_device_ops ops = { NULL }; + struct snd_card *card; + struct snd_kcontrol_new kctl; + char name[32]; + int ret; + + atomic_set(&solo_dev->snd_users, 0); + + /* Allows for easier mapping between video and audio */ + sprintf(name, "Softlogic%d", solo_dev->vfd->num); + + ret = snd_card_create(SNDRV_DEFAULT_IDX1, name, THIS_MODULE, 0, + &solo_dev->snd_card); + if (ret < 0) + return ret; + + card = solo_dev->snd_card; + + strcpy(card->driver, SOLO6010_NAME); + strcpy(card->shortname, "SOLO-6010 Audio"); + sprintf(card->longname, "%s on %s IRQ %d", card->shortname, + pci_name(solo_dev->pdev), solo_dev->pdev->irq); + snd_card_set_dev(card, &solo_dev->pdev->dev); + + ret = snd_device_new(card, SNDRV_DEV_LOWLEVEL, solo_dev, &ops); + if (ret < 0) + goto snd_error; + + /* Mixer controls */ + strcpy(card->mixername, "SOLO-6010"); + kctl = snd_solo_capture_volume; + kctl.count = solo_dev->nr_chans; + ret = snd_ctl_add(card, snd_ctl_new1(&kctl, solo_dev)); + if (ret < 0) + return ret; + + ret = solo_snd_pcm_init(solo_dev); + if (ret < 0) + goto snd_error; + + ret = snd_card_register(card); + if (ret < 0) + goto snd_error; + + solo_g723_config(solo_dev); + + dev_info(&solo_dev->pdev->dev, "Alsa sound card as %s\n", name); + + return 0; + +snd_error: + snd_card_free(card); + return ret; +} + +void solo_g723_exit(struct solo6010_dev *solo_dev) +{ + solo_reg_write(solo_dev, SOLO_AUDIO_CONTROL, 0); + solo6010_irq_off(solo_dev, SOLO_IRQ_G723); + + snd_card_free(solo_dev->snd_card); +} diff --git a/drivers/staging/solo6x10/gpio.c b/drivers/staging/solo6x10/gpio.c new file mode 100644 index 000000000000..efd88bafcdf6 --- /dev/null +++ b/drivers/staging/solo6x10/gpio.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com + * Copyright (C) 2010 Ben Collins + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include "solo6x10.h" + +static void solo_gpio_mode(struct solo6010_dev *solo_dev, + unsigned int port_mask, unsigned int mode) +{ + int port; + unsigned int ret; + + ret = solo_reg_read(solo_dev, SOLO_GPIO_CONFIG_0); + + /* To set gpio */ + for (port = 0; port < 16; port++) { + if (!((1 << port) & port_mask)) + continue; + + ret &= (~(3 << (port << 1))); + ret |= ((mode & 3) << (port << 1)); + } + + solo_reg_write(solo_dev, SOLO_GPIO_CONFIG_0, ret); + + /* To set extended gpio - sensor */ + ret = solo_reg_read(solo_dev, SOLO_GPIO_CONFIG_1); + + for (port = 0; port < 16; port++) { + if (!((1 << (port + 16)) & port_mask)) + continue; + + if (!mode) + ret &= ~(1 << port); + else + ret |= 1 << port; + } + + solo_reg_write(solo_dev, SOLO_GPIO_CONFIG_1, ret); +} + +static void solo_gpio_set(struct solo6010_dev *solo_dev, unsigned int value) +{ + solo_reg_write(solo_dev, SOLO_GPIO_DATA_OUT, + solo_reg_read(solo_dev, SOLO_GPIO_DATA_OUT) | value); +} + +static void solo_gpio_clear(struct solo6010_dev *solo_dev, unsigned int value) +{ + solo_reg_write(solo_dev, SOLO_GPIO_DATA_OUT, + solo_reg_read(solo_dev, SOLO_GPIO_DATA_OUT) & ~value); +} + +static void solo_gpio_config(struct solo6010_dev *solo_dev) +{ + /* Video reset */ + solo_gpio_mode(solo_dev, 0x30, 1); + solo_gpio_clear(solo_dev, 0x30); + udelay(100); + solo_gpio_set(solo_dev, 0x30); + udelay(100); + + /* Warning: Don't touch the next line unless you're sure of what + * you're doing: first four gpio [0-3] are used for video. */ + solo_gpio_mode(solo_dev, 0x0f, 2); + + /* We use bit 8-15 of SOLO_GPIO_CONFIG_0 for relay purposes */ + solo_gpio_mode(solo_dev, 0xff00, 1); + + /* Initially set relay status to 0 */ + solo_gpio_clear(solo_dev, 0xff00); +} + +int solo_gpio_init(struct solo6010_dev *solo_dev) +{ + solo_gpio_config(solo_dev); + return 0; +} + +void solo_gpio_exit(struct solo6010_dev *solo_dev) +{ + solo_gpio_clear(solo_dev, 0x30); + solo_gpio_config(solo_dev); +} diff --git a/drivers/staging/solo6x10/i2c.c b/drivers/staging/solo6x10/i2c.c new file mode 100644 index 000000000000..fba424741c46 --- /dev/null +++ b/drivers/staging/solo6x10/i2c.c @@ -0,0 +1,331 @@ +/* + * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com + * Copyright (C) 2010 Ben Collins + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* XXX: The SOLO6010 i2c does not have separate interrupts for each i2c + * channel. The bus can only handle one i2c event at a time. The below handles + * this all wrong. We should be using the status registers to see if the bus + * is in use, and have a global lock to check the status register. Also, + * the bulk of the work should be handled out-of-interrupt. The ugly loops + * that occur during interrupt scare me. The ISR should merely signal + * thread context, ACK the interrupt, and move on. -- BenC */ + +#include +#include "solo6x10.h" + +u8 solo_i2c_readbyte(struct solo6010_dev *solo_dev, int id, u8 addr, u8 off) +{ + struct i2c_msg msgs[2]; + u8 data; + + msgs[0].flags = 0; + msgs[0].addr = addr; + msgs[0].len = 1; + msgs[0].buf = &off; + + msgs[1].flags = I2C_M_RD; + msgs[1].addr = addr; + msgs[1].len = 1; + msgs[1].buf = &data; + + i2c_transfer(&solo_dev->i2c_adap[id], msgs, 2); + + return data; +} + +void solo_i2c_writebyte(struct solo6010_dev *solo_dev, int id, u8 addr, + u8 off, u8 data) +{ + struct i2c_msg msgs; + u8 buf[2]; + + buf[0] = off; + buf[1] = data; + msgs.flags = 0; + msgs.addr = addr; + msgs.len = 2; + msgs.buf = buf; + + i2c_transfer(&solo_dev->i2c_adap[id], &msgs, 1); +} + +static void solo_i2c_flush(struct solo6010_dev *solo_dev, int wr) +{ + u32 ctrl; + + ctrl = SOLO_IIC_CH_SET(solo_dev->i2c_id); + + if (solo_dev->i2c_state == IIC_STATE_START) + ctrl |= SOLO_IIC_START; + + if (wr) { + ctrl |= SOLO_IIC_WRITE; + } else { + ctrl |= SOLO_IIC_READ; + if (!(solo_dev->i2c_msg->flags & I2C_M_NO_RD_ACK)) + ctrl |= SOLO_IIC_ACK_EN; + } + + if (solo_dev->i2c_msg_ptr == solo_dev->i2c_msg->len) + ctrl |= SOLO_IIC_STOP; + + solo_reg_write(solo_dev, SOLO_IIC_CTRL, ctrl); +} + +static void solo_i2c_start(struct solo6010_dev *solo_dev) +{ + u32 addr = solo_dev->i2c_msg->addr << 1; + + if (solo_dev->i2c_msg->flags & I2C_M_RD) + addr |= 1; + + solo_dev->i2c_state = IIC_STATE_START; + solo_reg_write(solo_dev, SOLO_IIC_TXD, addr); + solo_i2c_flush(solo_dev, 1); +} + +static void solo_i2c_stop(struct solo6010_dev *solo_dev) +{ + solo6010_irq_off(solo_dev, SOLO_IRQ_IIC); + solo_reg_write(solo_dev, SOLO_IIC_CTRL, 0); + solo_dev->i2c_state = IIC_STATE_STOP; + wake_up(&solo_dev->i2c_wait); +} + +static int solo_i2c_handle_read(struct solo6010_dev *solo_dev) +{ +prepare_read: + if (solo_dev->i2c_msg_ptr != solo_dev->i2c_msg->len) { + solo_i2c_flush(solo_dev, 0); + return 0; + } + + solo_dev->i2c_msg_ptr = 0; + solo_dev->i2c_msg++; + solo_dev->i2c_msg_num--; + + if (solo_dev->i2c_msg_num == 0) { + solo_i2c_stop(solo_dev); + return 0; + } + + if (!(solo_dev->i2c_msg->flags & I2C_M_NOSTART)) { + solo_i2c_start(solo_dev); + } else { + if (solo_dev->i2c_msg->flags & I2C_M_RD) + goto prepare_read; + else + solo_i2c_stop(solo_dev); + } + + return 0; +} + +static int solo_i2c_handle_write(struct solo6010_dev *solo_dev) +{ +retry_write: + if (solo_dev->i2c_msg_ptr != solo_dev->i2c_msg->len) { + solo_reg_write(solo_dev, SOLO_IIC_TXD, + solo_dev->i2c_msg->buf[solo_dev->i2c_msg_ptr]); + solo_dev->i2c_msg_ptr++; + solo_i2c_flush(solo_dev, 1); + return 0; + } + + solo_dev->i2c_msg_ptr = 0; + solo_dev->i2c_msg++; + solo_dev->i2c_msg_num--; + + if (solo_dev->i2c_msg_num == 0) { + solo_i2c_stop(solo_dev); + return 0; + } + + if (!(solo_dev->i2c_msg->flags & I2C_M_NOSTART)) { + solo_i2c_start(solo_dev); + } else { + if (solo_dev->i2c_msg->flags & I2C_M_RD) + solo_i2c_stop(solo_dev); + else + goto retry_write; + } + + return 0; +} + +int solo_i2c_isr(struct solo6010_dev *solo_dev) +{ + u32 status = solo_reg_read(solo_dev, SOLO_IIC_CTRL); + int ret = -EINVAL; + + solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_IIC); + + if (status & (SOLO_IIC_STATE_TRNS & SOLO_IIC_STATE_SIG_ERR) || + solo_dev->i2c_id < 0) { + solo_i2c_stop(solo_dev); + return -ENXIO; + } + + switch (solo_dev->i2c_state) { + case IIC_STATE_START: + if (solo_dev->i2c_msg->flags & I2C_M_RD) { + solo_dev->i2c_state = IIC_STATE_READ; + ret = solo_i2c_handle_read(solo_dev); + break; + } + + solo_dev->i2c_state = IIC_STATE_WRITE; + case IIC_STATE_WRITE: + ret = solo_i2c_handle_write(solo_dev); + break; + + case IIC_STATE_READ: + solo_dev->i2c_msg->buf[solo_dev->i2c_msg_ptr] = + solo_reg_read(solo_dev, SOLO_IIC_RXD); + solo_dev->i2c_msg_ptr++; + + ret = solo_i2c_handle_read(solo_dev); + break; + + default: + solo_i2c_stop(solo_dev); + } + + return ret; +} + +static int solo_i2c_master_xfer(struct i2c_adapter *adap, + struct i2c_msg msgs[], int num) +{ + struct solo6010_dev *solo_dev = adap->algo_data; + unsigned long timeout; + int ret; + int i; + DEFINE_WAIT(wait); + + for (i = 0; i < SOLO_I2C_ADAPTERS; i++) { + if (&solo_dev->i2c_adap[i] == adap) + break; + } + + if (i == SOLO_I2C_ADAPTERS) + return num; /* XXX Right return value for failure? */ + + mutex_lock(&solo_dev->i2c_mutex); + solo_dev->i2c_id = i; + solo_dev->i2c_msg = msgs; + solo_dev->i2c_msg_num = num; + solo_dev->i2c_msg_ptr = 0; + + solo_reg_write(solo_dev, SOLO_IIC_CTRL, 0); + solo6010_irq_on(solo_dev, SOLO_IRQ_IIC); + solo_i2c_start(solo_dev); + + timeout = HZ / 2; + + for (;;) { + prepare_to_wait(&solo_dev->i2c_wait, &wait, TASK_INTERRUPTIBLE); + + if (solo_dev->i2c_state == IIC_STATE_STOP) + break; + + timeout = schedule_timeout(timeout); + if (!timeout) + break; + + if (signal_pending(current)) + break; + } + + finish_wait(&solo_dev->i2c_wait, &wait); + ret = num - solo_dev->i2c_msg_num; + solo_dev->i2c_state = IIC_STATE_IDLE; + solo_dev->i2c_id = -1; + + mutex_unlock(&solo_dev->i2c_mutex); + + return ret; +} + +static u32 solo_i2c_functionality(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C; +} + +static struct i2c_algorithm solo_i2c_algo = { + .master_xfer = solo_i2c_master_xfer, + .functionality = solo_i2c_functionality, +}; + +int solo_i2c_init(struct solo6010_dev *solo_dev) +{ + int i; + int ret; + + solo_reg_write(solo_dev, SOLO_IIC_CFG, + SOLO_IIC_PRESCALE(8) | SOLO_IIC_ENABLE); + + solo_dev->i2c_id = -1; + solo_dev->i2c_state = IIC_STATE_IDLE; + init_waitqueue_head(&solo_dev->i2c_wait); + mutex_init(&solo_dev->i2c_mutex); + + for (i = 0; i < SOLO_I2C_ADAPTERS; i++) { + struct i2c_adapter *adap = &solo_dev->i2c_adap[i]; + + snprintf(adap->name, I2C_NAME_SIZE, "%s I2C %d", + SOLO6010_NAME, i); + adap->algo = &solo_i2c_algo; + adap->algo_data = solo_dev; + adap->retries = 1; + adap->dev.parent = &solo_dev->pdev->dev; + + ret = i2c_add_adapter(adap); + if (ret) { + adap->algo_data = NULL; + break; + } + } + + if (ret) { + for (i = 0; i < SOLO_I2C_ADAPTERS; i++) { + if (!solo_dev->i2c_adap[i].algo_data) + break; + i2c_del_adapter(&solo_dev->i2c_adap[i]); + solo_dev->i2c_adap[i].algo_data = NULL; + } + return ret; + } + + dev_info(&solo_dev->pdev->dev, "Enabled %d i2c adapters\n", + SOLO_I2C_ADAPTERS); + + return 0; +} + +void solo_i2c_exit(struct solo6010_dev *solo_dev) +{ + int i; + + for (i = 0; i < SOLO_I2C_ADAPTERS; i++) { + if (!solo_dev->i2c_adap[i].algo_data) + continue; + i2c_del_adapter(&solo_dev->i2c_adap[i]); + solo_dev->i2c_adap[i].algo_data = NULL; + } +} diff --git a/drivers/staging/solo6x10/jpeg.h b/drivers/staging/solo6x10/jpeg.h new file mode 100644 index 000000000000..fb0507ecb307 --- /dev/null +++ b/drivers/staging/solo6x10/jpeg.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com + * Copyright (C) 2010 Ben Collins + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __SOLO6010_JPEG_H +#define __SOLO6010_JPEG_H + +static unsigned char jpeg_header[] = { + 0xff, 0xd8, 0xff, 0xfe, 0x00, 0x0d, 0x42, 0x6c, + 0x75, 0x65, 0x63, 0x68, 0x65, 0x72, 0x72, 0x79, + 0x20, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x20, 0x16, + 0x18, 0x1c, 0x18, 0x14, 0x20, 0x1c, 0x1a, 0x1c, + 0x24, 0x22, 0x20, 0x26, 0x30, 0x50, 0x34, 0x30, + 0x2c, 0x2c, 0x30, 0x62, 0x46, 0x4a, 0x3a, 0x50, + 0x74, 0x66, 0x7a, 0x78, 0x72, 0x66, 0x70, 0x6e, + 0x80, 0x90, 0xb8, 0x9c, 0x80, 0x88, 0xae, 0x8a, + 0x6e, 0x70, 0xa0, 0xda, 0xa2, 0xae, 0xbe, 0xc4, + 0xce, 0xd0, 0xce, 0x7c, 0x9a, 0xe2, 0xf2, 0xe0, + 0xc8, 0xf0, 0xb8, 0xca, 0xce, 0xc6, 0xff, 0xdb, + 0x00, 0x43, 0x01, 0x22, 0x24, 0x24, 0x30, 0x2a, + 0x30, 0x5e, 0x34, 0x34, 0x5e, 0xc6, 0x84, 0x70, + 0x84, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xff, 0xc4, 0x01, 0xa2, 0x00, + 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, + 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, + 0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, + 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, + 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, + 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, + 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, + 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, + 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, + 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, + 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, + 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, + 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, + 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, + 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, + 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, + 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, + 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x01, + 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x11, 0x00, 0x02, 0x01, + 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, + 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, + 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, + 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, + 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, + 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, + 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, + 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, + 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, + 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, + 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, + 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, + 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, + 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, + 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, + 0xc0, 0x00, 0x11, 0x08, 0x00, 0xf0, 0x02, 0xc0, + 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, + 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, + 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00 +}; + +/* This is the byte marker for the start of SOF0: 0xffc0 marker */ +#define SOF0_START 575 + +#endif /* __SOLO6010_JPEG_H */ diff --git a/drivers/staging/solo6x10/offsets.h b/drivers/staging/solo6x10/offsets.h new file mode 100644 index 000000000000..b176003ff383 --- /dev/null +++ b/drivers/staging/solo6x10/offsets.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com + * Copyright (C) 2010 Ben Collins + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __SOLO6010_OFFSETS_H +#define __SOLO6010_OFFSETS_H + +/* Offsets and sizes of the external address */ +#define SOLO_DISP_EXT_ADDR 0x00000000 +#define SOLO_DISP_EXT_SIZE 0x00480000 + +#define SOLO_DEC2LIVE_EXT_ADDR (SOLO_DISP_EXT_ADDR + SOLO_DISP_EXT_SIZE) +#define SOLO_DEC2LIVE_EXT_SIZE 0x00240000 + +#define SOLO_OSG_EXT_ADDR (SOLO_DEC2LIVE_EXT_ADDR + SOLO_DEC2LIVE_EXT_SIZE) +#define SOLO_OSG_EXT_SIZE 0x00120000 + +#define SOLO_EOSD_EXT_ADDR (SOLO_OSG_EXT_ADDR + SOLO_OSG_EXT_SIZE) +#define SOLO_EOSD_EXT_SIZE 0x00010000 + +#define SOLO_MOTION_EXT_ADDR(__solo) (SOLO_EOSD_EXT_ADDR + \ + (SOLO_EOSD_EXT_SIZE * __solo->nr_chans)) +#define SOLO_MOTION_EXT_SIZE 0x00080000 + +#define SOLO_G723_EXT_ADDR(__solo) \ + (SOLO_MOTION_EXT_ADDR(__solo) + SOLO_MOTION_EXT_SIZE) +#define SOLO_G723_EXT_SIZE 0x00010000 + +#define SOLO_CAP_EXT_ADDR(__solo) \ + (SOLO_G723_EXT_ADDR(__solo) + SOLO_G723_EXT_SIZE) +#define SOLO_CAP_EXT_MAX_PAGE (18 + 15) +#define SOLO_CAP_EXT_SIZE (SOLO_CAP_EXT_MAX_PAGE * 65536) + +/* This +1 is very important -- Why?! -- BenC */ +#define SOLO_EREF_EXT_ADDR(__solo) \ + (SOLO_CAP_EXT_ADDR(__solo) + \ + (SOLO_CAP_EXT_SIZE * (__solo->nr_chans + 1))) +#define SOLO_EREF_EXT_SIZE 0x00140000 + +#define SOLO_MP4E_EXT_ADDR(__solo) \ + (SOLO_EREF_EXT_ADDR(__solo) + \ + (SOLO_EREF_EXT_SIZE * __solo->nr_chans)) +#define SOLO_MP4E_EXT_SIZE(__solo) (0x00080000 * __solo->nr_chans) + +#define SOLO_DREF_EXT_ADDR(__solo) \ + (SOLO_MP4E_EXT_ADDR(__solo) + SOLO_MP4E_EXT_SIZE(__solo)) +#define SOLO_DREF_EXT_SIZE 0x00140000 + +#define SOLO_MP4D_EXT_ADDR(__solo) \ + (SOLO_DREF_EXT_ADDR(__solo) + \ + (SOLO_DREF_EXT_SIZE * __solo->nr_chans)) +#define SOLO_MP4D_EXT_SIZE 0x00080000 + +#define SOLO_JPEG_EXT_ADDR(__solo) \ + (SOLO_MP4D_EXT_ADDR(__solo) + \ + (SOLO_MP4D_EXT_SIZE * __solo->nr_chans)) +#define SOLO_JPEG_EXT_SIZE(__solo) (0x00080000 * __solo->nr_chans) + +#endif /* __SOLO6010_OFFSETS_H */ diff --git a/drivers/staging/solo6x10/osd-font.h b/drivers/staging/solo6x10/osd-font.h new file mode 100644 index 000000000000..d72efbb3bb3d --- /dev/null +++ b/drivers/staging/solo6x10/osd-font.h @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com + * Copyright (C) 2010 Ben Collins + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __SOLO6010_OSD_FONT_H +#define __SOLO6010_OSD_FONT_H + +static const unsigned int solo_osd_font[] = { + 0x00000000, 0x0000c0c8, 0xccfefe0c, 0x08000000, + 0x00000000, 0x10103838, 0x7c7cfefe, 0x00000000, /* 0 */ + 0x00000000, 0xfefe7c7c, 0x38381010, 0x10000000, + 0x00000000, 0x7c82fefe, 0xfefefe7c, 0x00000000, + 0x00000000, 0x00001038, 0x10000000, 0x00000000, + 0x00000000, 0x0010387c, 0xfe7c3810, 0x00000000, + 0x00000000, 0x00384444, 0x44380000, 0x00000000, + 0x00000000, 0x38448282, 0x82443800, 0x00000000, + 0x00000000, 0x007c7c7c, 0x7c7c0000, 0x00000000, + 0x00000000, 0x6c6c6c6c, 0x6c6c6c6c, 0x00000000, + 0x00000000, 0x061e7efe, 0xfe7e1e06, 0x00000000, + 0x00000000, 0xc0f0fcfe, 0xfefcf0c0, 0x00000000, + 0x00000000, 0xc6cedefe, 0xfedecec6, 0x00000000, + 0x00000000, 0xc6e6f6fe, 0xfef6e6c6, 0x00000000, + 0x00000000, 0x12367efe, 0xfe7e3612, 0x00000000, + 0x00000000, 0x90d8fcfe, 0xfefcd890, 0x00000000, + 0x00000038, 0x7cc692ba, 0x92c67c38, 0x00000000, + 0x00000038, 0x7cc6aa92, 0xaac67c38, 0x00000000, + 0x00000038, 0x7830107c, 0xbaa8680c, 0x00000000, + 0x00000038, 0x3c18127c, 0xb8382c60, 0x00000000, + 0x00000044, 0xaa6c8254, 0x38eec67c, 0x00000000, + 0x00000082, 0x44288244, 0x38c6827c, 0x00000000, + 0x00000038, 0x444444fe, 0xfeeec6fe, 0x00000000, + 0x00000018, 0x78187818, 0x3c7e7e3c, 0x00000000, + 0x00000000, 0x3854929a, 0x82443800, 0x00000000, + 0x00000000, 0x00c0c8cc, 0xfefe0c08, 0x00000000, + 0x0000e0a0, 0xe040e00e, 0x8a0ea40e, 0x00000000, + 0x0000e0a0, 0xe040e00e, 0x0a8e440e, 0x00000000, + 0x0000007c, 0x82829292, 0x929282fe, 0x00000000, + 0x000000f8, 0xfc046494, 0x946404fc, 0x00000000, + 0x0000003f, 0x7f404c52, 0x524c407f, 0x00000000, + 0x0000007c, 0x82ba82ba, 0x82ba82fe, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x183c3c3c, 0x18180018, 0x18000000, /* 32 ! */ + 0x00000066, 0x66240000, 0x00000000, 0x00000000, + 0x00000000, 0x6c6cfe6c, 0x6c6cfe6c, 0x6c000000, /* 34 " # */ + 0x00001010, 0x7cd6d616, 0x7cd0d6d6, 0x7c101000, + 0x00000000, 0x0086c660, 0x30180cc6, 0xc2000000, /* 36 $ % */ + 0x00000000, 0x386c6c38, 0xdc766666, 0xdc000000, + 0x0000000c, 0x0c0c0600, 0x00000000, 0x00000000, /* 38 & ' */ + 0x00000000, 0x30180c0c, 0x0c0c0c18, 0x30000000, + 0x00000000, 0x0c183030, 0x30303018, 0x0c000000, /* 40 ( ) */ + 0x00000000, 0x0000663c, 0xff3c6600, 0x00000000, + 0x00000000, 0x00001818, 0x7e181800, 0x00000000, /* 42 * + */ + 0x00000000, 0x00000000, 0x00000e0e, 0x0c060000, + 0x00000000, 0x00000000, 0x7e000000, 0x00000000, /* 44 , - */ + 0x00000000, 0x00000000, 0x00000006, 0x06000000, + 0x00000000, 0x80c06030, 0x180c0602, 0x00000000, /* 46 . / */ + 0x0000007c, 0xc6e6f6de, 0xcec6c67c, 0x00000000, + 0x00000030, 0x383c3030, 0x303030fc, 0x00000000, /* 48 0 1 */ + 0x0000007c, 0xc6c06030, 0x180cc6fe, 0x00000000, + 0x0000007c, 0xc6c0c07c, 0xc0c0c67c, 0x00000000, /* 50 2 3 */ + 0x00000060, 0x70786c66, 0xfe6060f0, 0x00000000, + 0x000000fe, 0x0606067e, 0xc0c0c67c, 0x00000000, /* 52 4 5 */ + 0x00000038, 0x0c06067e, 0xc6c6c67c, 0x00000000, + 0x000000fe, 0xc6c06030, 0x18181818, 0x00000000, /* 54 6 7 */ + 0x0000007c, 0xc6c6c67c, 0xc6c6c67c, 0x00000000, + 0x0000007c, 0xc6c6c6fc, 0xc0c06038, 0x00000000, /* 56 8 9 */ + 0x00000000, 0x18180000, 0x00181800, 0x00000000, + 0x00000000, 0x18180000, 0x0018180c, 0x00000000, /* 58 : ; */ + 0x00000060, 0x30180c06, 0x0c183060, 0x00000000, + 0x00000000, 0x007e0000, 0x007e0000, 0x00000000, + 0x00000006, 0x0c183060, 0x30180c06, 0x00000000, + 0x0000007c, 0xc6c66030, 0x30003030, 0x00000000, + 0x0000007c, 0xc6f6d6d6, 0x7606067c, 0x00000000, + 0x00000010, 0x386cc6c6, 0xfec6c6c6, 0x00000000, /* 64 @ A */ + 0x0000007e, 0xc6c6c67e, 0xc6c6c67e, 0x00000000, + 0x00000078, 0xcc060606, 0x0606cc78, 0x00000000, /* 66 */ + 0x0000003e, 0x66c6c6c6, 0xc6c6663e, 0x00000000, + 0x000000fe, 0x0606063e, 0x060606fe, 0x00000000, /* 68 */ + 0x000000fe, 0x0606063e, 0x06060606, 0x00000000, + 0x00000078, 0xcc060606, 0xf6c6ccb8, 0x00000000, /* 70 */ + 0x000000c6, 0xc6c6c6fe, 0xc6c6c6c6, 0x00000000, + 0x0000003c, 0x18181818, 0x1818183c, 0x00000000, /* 72 */ + 0x00000060, 0x60606060, 0x6066663c, 0x00000000, + 0x000000c6, 0xc666361e, 0x3666c6c6, 0x00000000, /* 74 */ + 0x00000006, 0x06060606, 0x060606fe, 0x00000000, + 0x000000c6, 0xeefed6c6, 0xc6c6c6c6, 0x00000000, /* 76 */ + 0x000000c6, 0xcedefef6, 0xe6c6c6c6, 0x00000000, + 0x00000038, 0x6cc6c6c6, 0xc6c66c38, 0x00000000, /* 78 */ + 0x0000007e, 0xc6c6c67e, 0x06060606, 0x00000000, + 0x00000038, 0x6cc6c6c6, 0xc6d67c38, 0x60000000, /* 80 */ + 0x0000007e, 0xc6c6c67e, 0x66c6c6c6, 0x00000000, + 0x0000007c, 0xc6c60c38, 0x60c6c67c, 0x00000000, /* 82 */ + 0x0000007e, 0x18181818, 0x18181818, 0x00000000, + 0x000000c6, 0xc6c6c6c6, 0xc6c6c67c, 0x00000000, /* 84 */ + 0x000000c6, 0xc6c6c6c6, 0xc66c3810, 0x00000000, + 0x000000c6, 0xc6c6c6c6, 0xd6d6fe6c, 0x00000000, /* 86 */ + 0x000000c6, 0xc6c66c38, 0x6cc6c6c6, 0x00000000, + 0x00000066, 0x66666666, 0x3c181818, 0x00000000, /* 88 */ + 0x000000fe, 0xc0603018, 0x0c0606fe, 0x00000000, + 0x0000003c, 0x0c0c0c0c, 0x0c0c0c3c, 0x00000000, /* 90 */ + 0x00000002, 0x060c1830, 0x60c08000, 0x00000000, + 0x0000003c, 0x30303030, 0x3030303c, 0x00000000, /* 92 */ + 0x00001038, 0x6cc60000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00fe0000, + 0x00001818, 0x30000000, 0x00000000, 0x00000000, + 0x00000000, 0x00003c60, 0x7c66667c, 0x00000000, + 0x0000000c, 0x0c0c7ccc, 0xcccccc7c, 0x00000000, + 0x00000000, 0x00007cc6, 0x0606c67c, 0x00000000, + 0x00000060, 0x60607c66, 0x6666667c, 0x00000000, + 0x00000000, 0x00007cc6, 0xfe06c67c, 0x00000000, + 0x00000078, 0x0c0c0c3e, 0x0c0c0c0c, 0x00000000, + 0x00000000, 0x00007c66, 0x6666667c, 0x60603e00, + 0x0000000c, 0x0c0c7ccc, 0xcccccccc, 0x00000000, + 0x00000030, 0x30003830, 0x30303078, 0x00000000, + 0x00000030, 0x30003c30, 0x30303030, 0x30301f00, + 0x0000000c, 0x0c0ccc6c, 0x3c6ccccc, 0x00000000, + 0x00000030, 0x30303030, 0x30303030, 0x00000000, + 0x00000000, 0x000066fe, 0xd6d6d6d6, 0x00000000, + 0x00000000, 0x000078cc, 0xcccccccc, 0x00000000, + 0x00000000, 0x00007cc6, 0xc6c6c67c, 0x00000000, + 0x00000000, 0x00007ccc, 0xcccccc7c, 0x0c0c0c00, + 0x00000000, 0x00007c66, 0x6666667c, 0x60606000, + 0x00000000, 0x000076dc, 0x0c0c0c0c, 0x00000000, + 0x00000000, 0x00007cc6, 0x1c70c67c, 0x00000000, + 0x00000000, 0x1818fe18, 0x18181870, 0x00000000, + 0x00000000, 0x00006666, 0x6666663c, 0x00000000, + 0x00000000, 0x0000c6c6, 0xc66c3810, 0x00000000, + 0x00000000, 0x0000c6d6, 0xd6d6fe6c, 0x00000000, + 0x00000000, 0x0000c66c, 0x38386cc6, 0x00000000, + 0x00000000, 0x00006666, 0x6666667c, 0x60603e00, + 0x00000000, 0x0000fe60, 0x30180cfe, 0x00000000, + 0x00000070, 0x1818180e, 0x18181870, 0x00000000, + 0x00000018, 0x18181800, 0x18181818, 0x00000000, + 0x0000000e, 0x18181870, 0x1818180e, 0x00000000, + 0x000000dc, 0x76000000, 0x00000000, 0x00000000, + 0x00000000, 0x0010386c, 0xc6c6fe00, 0x00000000 +}; + +#endif /* __SOLO6010_OSD_FONT_H */ diff --git a/drivers/staging/solo6x10/p2m.c b/drivers/staging/solo6x10/p2m.c new file mode 100644 index 000000000000..1b88d1053f94 --- /dev/null +++ b/drivers/staging/solo6x10/p2m.c @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com + * Copyright (C) 2010 Ben Collins + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include "solo6x10.h" + +/* #define SOLO_TEST_P2M */ + +int solo_p2m_dma(struct solo6010_dev *solo_dev, u8 id, int wr, + void *sys_addr, u32 ext_addr, u32 size) +{ + dma_addr_t dma_addr; + int ret; + + WARN_ON(!size); + BUG_ON(id >= SOLO_NR_P2M); + + if (!size) + return -EINVAL; + + dma_addr = pci_map_single(solo_dev->pdev, sys_addr, size, + wr ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); + + ret = solo_p2m_dma_t(solo_dev, id, wr, dma_addr, ext_addr, size); + + pci_unmap_single(solo_dev->pdev, dma_addr, size, + wr ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); + + return ret; +} + +int solo_p2m_dma_t(struct solo6010_dev *solo_dev, u8 id, int wr, + dma_addr_t dma_addr, u32 ext_addr, u32 size) +{ + struct p2m_desc *desc = kzalloc(sizeof(*desc) * 2, GFP_DMA); + int ret; + + if (desc == NULL) + return -ENOMEM; + + solo_p2m_push_desc(&desc[1], wr, dma_addr, ext_addr, size, 0, 0); + ret = solo_p2m_dma_desc(solo_dev, id, desc, 2); + kfree(desc); + + return ret; +} + +void solo_p2m_push_desc(struct p2m_desc *desc, int wr, dma_addr_t dma_addr, + u32 ext_addr, u32 size, int repeat, u32 ext_size) +{ + desc->ta = cpu_to_le32(dma_addr); + desc->fa = cpu_to_le32(ext_addr); + + desc->ext = cpu_to_le32(SOLO_P2M_COPY_SIZE(size >> 2)); + desc->ctrl = cpu_to_le32(SOLO_P2M_BURST_SIZE(SOLO_P2M_BURST_256) | + (wr ? SOLO_P2M_WRITE : 0) | SOLO_P2M_TRANS_ON); + + /* Ext size only matters when we're repeating */ + if (repeat) { + desc->ext |= cpu_to_le32(SOLO_P2M_EXT_INC(ext_size >> 2)); + desc->ctrl |= cpu_to_le32(SOLO_P2M_PCI_INC(size >> 2) | + SOLO_P2M_REPEAT(repeat)); + } +} + +int solo_p2m_dma_desc(struct solo6010_dev *solo_dev, u8 id, + struct p2m_desc *desc, int desc_count) +{ + struct solo_p2m_dev *p2m_dev; + unsigned int timeout; + int ret = 0; + u32 config = 0; + dma_addr_t desc_dma = 0; + + BUG_ON(id >= SOLO_NR_P2M); + BUG_ON(!desc_count || desc_count > SOLO_NR_P2M_DESC); + + p2m_dev = &solo_dev->p2m_dev[id]; + + mutex_lock(&p2m_dev->mutex); + + solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), 0); + + INIT_COMPLETION(p2m_dev->completion); + p2m_dev->error = 0; + + /* Enable the descriptors */ + config = solo_reg_read(solo_dev, SOLO_P2M_CONFIG(id)); + desc_dma = pci_map_single(solo_dev->pdev, desc, + desc_count * sizeof(*desc), + PCI_DMA_TODEVICE); + solo_reg_write(solo_dev, SOLO_P2M_DES_ADR(id), desc_dma); + solo_reg_write(solo_dev, SOLO_P2M_DESC_ID(id), desc_count - 1); + solo_reg_write(solo_dev, SOLO_P2M_CONFIG(id), config | + SOLO_P2M_DESC_MODE); + + /* Should have all descriptors completed from one interrupt */ + timeout = wait_for_completion_timeout(&p2m_dev->completion, HZ); + + solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), 0); + + /* Reset back to non-descriptor mode */ + solo_reg_write(solo_dev, SOLO_P2M_CONFIG(id), config); + solo_reg_write(solo_dev, SOLO_P2M_DESC_ID(id), 0); + solo_reg_write(solo_dev, SOLO_P2M_DES_ADR(id), 0); + pci_unmap_single(solo_dev->pdev, desc_dma, + desc_count * sizeof(*desc), + PCI_DMA_TODEVICE); + + if (p2m_dev->error) + ret = -EIO; + else if (timeout == 0) + ret = -EAGAIN; + + mutex_unlock(&p2m_dev->mutex); + + WARN_ON_ONCE(ret); + + return ret; +} + +int solo_p2m_dma_sg(struct solo6010_dev *solo_dev, u8 id, + struct p2m_desc *pdesc, int wr, + struct scatterlist *sg, u32 sg_off, + u32 ext_addr, u32 size) +{ + int i; + int idx; + + BUG_ON(id >= SOLO_NR_P2M); + + if (WARN_ON_ONCE(!size)) + return -EINVAL; + + memset(pdesc, 0, sizeof(*pdesc)); + + /* Should rewrite this to handle > SOLO_NR_P2M_DESC transactions */ + for (i = 0, idx = 1; idx < SOLO_NR_P2M_DESC && sg && size > 0; + i++, sg = sg_next(sg)) { + struct p2m_desc *desc = &pdesc[idx]; + u32 sg_len = sg_dma_len(sg); + u32 len; + + if (sg_off >= sg_len) { + sg_off -= sg_len; + continue; + } + + sg_len -= sg_off; + len = min(sg_len, size); + + solo_p2m_push_desc(desc, wr, sg_dma_address(sg) + sg_off, + ext_addr, len, 0, 0); + + size -= len; + ext_addr += len; + idx++; + + sg_off = 0; + } + + WARN_ON_ONCE(size || i >= SOLO_NR_P2M_DESC); + + return solo_p2m_dma_desc(solo_dev, id, pdesc, idx); +} + +#ifdef SOLO_TEST_P2M + +#define P2M_TEST_CHAR 0xbe + +static unsigned long long p2m_test(struct solo6010_dev *solo_dev, u8 id, + u32 base, int size) +{ + u8 *wr_buf; + u8 *rd_buf; + int i; + unsigned long long err_cnt = 0; + + wr_buf = kmalloc(size, GFP_KERNEL); + if (!wr_buf) { + printk(SOLO6010_NAME ": Failed to malloc for p2m_test\n"); + return size; + } + + rd_buf = kmalloc(size, GFP_KERNEL); + if (!rd_buf) { + printk(SOLO6010_NAME ": Failed to malloc for p2m_test\n"); + kfree(wr_buf); + return size; + } + + memset(wr_buf, P2M_TEST_CHAR, size); + memset(rd_buf, P2M_TEST_CHAR + 1, size); + + solo_p2m_dma(solo_dev, id, 1, wr_buf, base, size); + solo_p2m_dma(solo_dev, id, 0, rd_buf, base, size); + + for (i = 0; i < size; i++) + if (wr_buf[i] != rd_buf[i]) + err_cnt++; + + kfree(wr_buf); + kfree(rd_buf); + + return err_cnt; +} + +#define TEST_CHUNK_SIZE (8 * 1024) + +static void run_p2m_test(struct solo6010_dev *solo_dev) +{ + unsigned long long errs = 0; + u32 size = SOLO_JPEG_EXT_ADDR(solo_dev) + SOLO_JPEG_EXT_SIZE(solo_dev); + int i, d; + + printk(KERN_WARNING "%s: Testing %u bytes of external ram\n", + SOLO6010_NAME, size); + + for (i = 0; i < size; i += TEST_CHUNK_SIZE) + for (d = 0; d < 4; d++) + errs += p2m_test(solo_dev, d, i, TEST_CHUNK_SIZE); + + printk(KERN_WARNING "%s: Found %llu errors during p2m test\n", + SOLO6010_NAME, errs); + + return; +} +#else +#define run_p2m_test(__solo) do {} while (0) +#endif + +void solo_p2m_isr(struct solo6010_dev *solo_dev, int id) +{ + struct solo_p2m_dev *p2m_dev = &solo_dev->p2m_dev[id]; + + solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_P2M(id)); + + complete(&p2m_dev->completion); +} + +void solo_p2m_error_isr(struct solo6010_dev *solo_dev, u32 status) +{ + struct solo_p2m_dev *p2m_dev; + int i; + + if (!(status & SOLO_PCI_ERR_P2M)) + return; + + for (i = 0; i < SOLO_NR_P2M; i++) { + p2m_dev = &solo_dev->p2m_dev[i]; + p2m_dev->error = 1; + solo_reg_write(solo_dev, SOLO_P2M_CONTROL(i), 0); + complete(&p2m_dev->completion); + } +} + +void solo_p2m_exit(struct solo6010_dev *solo_dev) +{ + int i; + + for (i = 0; i < SOLO_NR_P2M; i++) + solo6010_irq_off(solo_dev, SOLO_IRQ_P2M(i)); +} + +int solo_p2m_init(struct solo6010_dev *solo_dev) +{ + struct solo_p2m_dev *p2m_dev; + int i; + + for (i = 0; i < SOLO_NR_P2M; i++) { + p2m_dev = &solo_dev->p2m_dev[i]; + + mutex_init(&p2m_dev->mutex); + init_completion(&p2m_dev->completion); + + solo_reg_write(solo_dev, SOLO_P2M_CONTROL(i), 0); + solo_reg_write(solo_dev, SOLO_P2M_CONFIG(i), + SOLO_P2M_CSC_16BIT_565 | + SOLO_P2M_DMA_INTERVAL(3) | + SOLO_P2M_DESC_INTR_OPT | + SOLO_P2M_PCI_MASTER_MODE); + solo6010_irq_on(solo_dev, SOLO_IRQ_P2M(i)); + } + + run_p2m_test(solo_dev); + + return 0; +} diff --git a/drivers/staging/solo6x10/registers.h b/drivers/staging/solo6x10/registers.h new file mode 100644 index 000000000000..edf77e8a8e92 --- /dev/null +++ b/drivers/staging/solo6x10/registers.h @@ -0,0 +1,637 @@ +/* + * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com + * Copyright (C) 2010 Ben Collins + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __SOLO6010_REGISTERS_H +#define __SOLO6010_REGISTERS_H + +#include "offsets.h" + +/* Global 6010 system configuration */ +#define SOLO_SYS_CFG 0x0000 +#define SOLO6010_SYS_CFG_FOUT_EN 0x00000001 /* 6010 only */ +#define SOLO6010_SYS_CFG_PLL_BYPASS 0x00000002 /* 6010 only */ +#define SOLO6010_SYS_CFG_PLL_PWDN 0x00000004 /* 6010 only */ +#define SOLO6010_SYS_CFG_OUTDIV(__n) (((__n) & 0x003) << 3) /* 6010 only */ +#define SOLO6010_SYS_CFG_FEEDBACKDIV(__n) (((__n) & 0x1ff) << 5) /* 6010 only */ +#define SOLO6010_SYS_CFG_INPUTDIV(__n) (((__n) & 0x01f) << 14) /* 6010 only */ +#define SOLO_SYS_CFG_CLOCK_DIV 0x00080000 +#define SOLO_SYS_CFG_NCLK_DELAY(__n) (((__n) & 0x003) << 24) +#define SOLO_SYS_CFG_PCLK_DELAY(__n) (((__n) & 0x00f) << 26) +#define SOLO_SYS_CFG_SDRAM64BIT 0x40000000 /* 6110: must be set */ +#define SOLO_SYS_CFG_RESET 0x80000000 + +#define SOLO_DMA_CTRL 0x0004 +#define SOLO_DMA_CTRL_REFRESH_CYCLE(n) ((n)<<8) +/* 0=16/32MB, 1=32/64MB, 2=64/128MB, 3=128/256MB */ +#define SOLO_DMA_CTRL_SDRAM_SIZE(n) ((n)<<6) +#define SOLO_DMA_CTRL_SDRAM_CLK_INVERT (1<<5) +#define SOLO_DMA_CTRL_STROBE_SELECT (1<<4) +#define SOLO_DMA_CTRL_READ_DATA_SELECT (1<<3) +#define SOLO_DMA_CTRL_READ_CLK_SELECT (1<<2) +#define SOLO_DMA_CTRL_LATENCY(n) ((n)<<0) +#define SOLO_DMA_CTRL1 0x0008 + +#define SOLO_SYS_VCLK 0x000C +#define SOLO_VCLK_INVERT (1<<22) +/* 0=sys_clk/4, 1=sys_clk/2, 2=clk_in/2 of system input */ +#define SOLO_VCLK_SELECT(n) ((n)<<20) +#define SOLO_VCLK_VIN1415_DELAY(n) ((n)<<14) +#define SOLO_VCLK_VIN1213_DELAY(n) ((n)<<12) +#define SOLO_VCLK_VIN1011_DELAY(n) ((n)<<10) +#define SOLO_VCLK_VIN0809_DELAY(n) ((n)<<8) +#define SOLO_VCLK_VIN0607_DELAY(n) ((n)<<6) +#define SOLO_VCLK_VIN0405_DELAY(n) ((n)<<4) +#define SOLO_VCLK_VIN0203_DELAY(n) ((n)<<2) +#define SOLO_VCLK_VIN0001_DELAY(n) ((n)<<0) + +#define SOLO_IRQ_STAT 0x0010 +#define SOLO_IRQ_ENABLE 0x0014 +#define SOLO_IRQ_P2M(n) (1<<((n)+17)) +#define SOLO_IRQ_GPIO (1<<16) +#define SOLO_IRQ_VIDEO_LOSS (1<<15) +#define SOLO_IRQ_VIDEO_IN (1<<14) +#define SOLO_IRQ_MOTION (1<<13) +#define SOLO_IRQ_ATA_CMD (1<<12) +#define SOLO_IRQ_ATA_DIR (1<<11) +#define SOLO_IRQ_PCI_ERR (1<<10) +#define SOLO_IRQ_PS2_1 (1<<9) +#define SOLO_IRQ_PS2_0 (1<<8) +#define SOLO_IRQ_SPI (1<<7) +#define SOLO_IRQ_IIC (1<<6) +#define SOLO_IRQ_UART(n) (1<<((n) + 4)) +#define SOLO_IRQ_G723 (1<<3) +#define SOLO_IRQ_DECODER (1<<1) +#define SOLO_IRQ_ENCODER (1<<0) + +#define SOLO_CHIP_OPTION 0x001C +#define SOLO_CHIP_ID_MASK 0x00000007 + +#define SOLO6110_PLL_CONFIG 0x0020 +#define SOLO6110_PLL_RANGE_BYPASS (0 << 20) +#define SOLO6110_PLL_RANGE_5_10MHZ (1 << 20) +#define SOLO6110_PLL_RANGE_8_16MHZ (2 << 20) +#define SOLO6110_PLL_RANGE_13_26MHZ (3 << 20) +#define SOLO6110_PLL_RANGE_21_42MHZ (4 << 20) +#define SOLO6110_PLL_RANGE_34_68MHZ (5 << 20) +#define SOLO6110_PLL_RANGE_54_108MHZ (6 << 20) +#define SOLO6110_PLL_RANGE_88_200MHZ (7 << 20) +#define SOLO6110_PLL_DIVR(x) (((x) - 1) << 15) +#define SOLO6110_PLL_DIVQ_EXP(x) ((x) << 12) +#define SOLO6110_PLL_DIVF(x) (((x) - 1) << 4) +#define SOLO6110_PLL_RESET (1 << 3) +#define SOLO6110_PLL_BYPASS (1 << 2) +#define SOLO6110_PLL_FSEN (1 << 1) +#define SOLO6110_PLL_FB (1 << 0) + +#define SOLO_EEPROM_CTRL 0x0060 +#define SOLO_EEPROM_ACCESS_EN (1<<7) +#define SOLO_EEPROM_CS (1<<3) +#define SOLO_EEPROM_CLK (1<<2) +#define SOLO_EEPROM_DO (1<<1) +#define SOLO_EEPROM_DI (1<<0) +#define SOLO_EEPROM_ENABLE (EEPROM_ACCESS_EN | EEPROM_CS) + +#define SOLO_PCI_ERR 0x0070 +#define SOLO_PCI_ERR_FATAL 0x00000001 +#define SOLO_PCI_ERR_PARITY 0x00000002 +#define SOLO_PCI_ERR_TARGET 0x00000004 +#define SOLO_PCI_ERR_TIMEOUT 0x00000008 +#define SOLO_PCI_ERR_P2M 0x00000010 +#define SOLO_PCI_ERR_ATA 0x00000020 +#define SOLO_PCI_ERR_P2M_DESC 0x00000040 +#define SOLO_PCI_ERR_FSM0(__s) (((__s) >> 16) & 0x0f) +#define SOLO_PCI_ERR_FSM1(__s) (((__s) >> 20) & 0x0f) +#define SOLO_PCI_ERR_FSM2(__s) (((__s) >> 24) & 0x1f) + +#define SOLO_P2M_BASE 0x0080 + +#define SOLO_P2M_CONFIG(n) (0x0080 + ((n)*0x20)) +#define SOLO_P2M_DMA_INTERVAL(n) ((n)<<6)/* N*32 clocks */ +#define SOLO_P2M_CSC_BYTE_REORDER (1<<5) /* BGR -> RGB */ +/* 0:r=[14:10] g=[9:5] b=[4:0], 1:r=[15:11] g=[10:5] b=[4:0] */ +#define SOLO_P2M_CSC_16BIT_565 (1<<4) +#define SOLO_P2M_UV_SWAP (1<<3) +#define SOLO_P2M_PCI_MASTER_MODE (1<<2) +#define SOLO_P2M_DESC_INTR_OPT (1<<1) /* 1:Empty, 0:Each */ +#define SOLO_P2M_DESC_MODE (1<<0) + +#define SOLO_P2M_DES_ADR(n) (0x0084 + ((n)*0x20)) + +#define SOLO_P2M_DESC_ID(n) (0x0088 + ((n)*0x20)) +#define SOLO_P2M_UPDATE_ID(n) ((n)<<0) + +#define SOLO_P2M_STATUS(n) (0x008C + ((n)*0x20)) +#define SOLO_P2M_COMMAND_DONE (1<<8) +#define SOLO_P2M_CURRENT_ID(stat) (0xff & (stat)) + +#define SOLO_P2M_CONTROL(n) (0x0090 + ((n)*0x20)) +#define SOLO_P2M_PCI_INC(n) ((n)<<20) +#define SOLO_P2M_REPEAT(n) ((n)<<10) +/* 0:512, 1:256, 2:128, 3:64, 4:32, 5:128(2page) */ +#define SOLO_P2M_BURST_SIZE(n) ((n)<<7) +#define SOLO_P2M_BURST_512 0 +#define SOLO_P2M_BURST_256 1 +#define SOLO_P2M_BURST_128 2 +#define SOLO_P2M_BURST_64 3 +#define SOLO_P2M_BURST_32 4 +#define SOLO_P2M_CSC_16BIT (1<<6) /* 0:24bit, 1:16bit */ +/* 0:Y[0]<-0(OFF), 1:Y[0]<-1(ON), 2:Y[0]<-G[0], 3:Y[0]<-Bit[15] */ +#define SOLO_P2M_ALPHA_MODE(n) ((n)<<4) +#define SOLO_P2M_CSC_ON (1<<3) +#define SOLO_P2M_INTERRUPT_REQ (1<<2) +#define SOLO_P2M_WRITE (1<<1) +#define SOLO_P2M_TRANS_ON (1<<0) + +#define SOLO_P2M_EXT_CFG(n) (0x0094 + ((n)*0x20)) +#define SOLO_P2M_EXT_INC(n) ((n)<<20) +#define SOLO_P2M_COPY_SIZE(n) ((n)<<0) + +#define SOLO_P2M_TAR_ADR(n) (0x0098 + ((n)*0x20)) + +#define SOLO_P2M_EXT_ADR(n) (0x009C + ((n)*0x20)) + +#define SOLO_P2M_BUFFER(i) (0x2000 + ((i)*4)) + +#define SOLO_VI_CH_SWITCH_0 0x0100 +#define SOLO_VI_CH_SWITCH_1 0x0104 +#define SOLO_VI_CH_SWITCH_2 0x0108 + +#define SOLO_VI_CH_ENA 0x010C +#define SOLO_VI_CH_FORMAT 0x0110 +#define SOLO_VI_FD_SEL_MASK(n) ((n)<<16) +#define SOLO_VI_PROG_MASK(n) ((n)<<0) + +#define SOLO_VI_FMT_CFG 0x0114 +#define SOLO_VI_FMT_CHECK_VCOUNT (1<<31) +#define SOLO_VI_FMT_CHECK_HCOUNT (1<<30) +#define SOLO_VI_FMT_TEST_SIGNAL (1<<28) + +#define SOLO_VI_PAGE_SW 0x0118 +#define SOLO_FI_INV_DISP_LIVE(n) ((n)<<8) +#define SOLO_FI_INV_DISP_OUT(n) ((n)<<7) +#define SOLO_DISP_SYNC_FI(n) ((n)<<6) +#define SOLO_PIP_PAGE_ADD(n) ((n)<<3) +#define SOLO_NORMAL_PAGE_ADD(n) ((n)<<0) + +#define SOLO_VI_ACT_I_P 0x011C +#define SOLO_VI_ACT_I_S 0x0120 +#define SOLO_VI_ACT_P 0x0124 +#define SOLO_VI_FI_INVERT (1<<31) +#define SOLO_VI_H_START(n) ((n)<<21) +#define SOLO_VI_V_START(n) ((n)<<11) +#define SOLO_VI_V_STOP(n) ((n)<<0) + +#define SOLO_VI_STATUS0 0x0128 +#define SOLO_VI_STATUS0_PAGE(__n) ((__n) & 0x07) +#define SOLO_VI_STATUS1 0x012C + +/* XXX: Might be better off in kernel level disp.h */ +#define DISP_PAGE(stat) ((stat) & 0x07) + +#define SOLO_VI_PB_CONFIG 0x0130 +#define SOLO_VI_PB_USER_MODE (1<<1) +#define SOLO_VI_PB_PAL (1<<0) +#define SOLO_VI_PB_RANGE_HV 0x0134 +#define SOLO_VI_PB_HSIZE(h) ((h)<<12) +#define SOLO_VI_PB_VSIZE(v) ((v)<<0) +#define SOLO_VI_PB_ACT_H 0x0138 +#define SOLO_VI_PB_HSTART(n) ((n)<<12) +#define SOLO_VI_PB_HSTOP(n) ((n)<<0) +#define SOLO_VI_PB_ACT_V 0x013C +#define SOLO_VI_PB_VSTART(n) ((n)<<12) +#define SOLO_VI_PB_VSTOP(n) ((n)<<0) + +#define SOLO_VI_MOSAIC(ch) (0x0140 + ((ch)*4)) +#define SOLO_VI_MOSAIC_SX(x) ((x)<<24) +#define SOLO_VI_MOSAIC_EX(x) ((x)<<16) +#define SOLO_VI_MOSAIC_SY(x) ((x)<<8) +#define SOLO_VI_MOSAIC_EY(x) ((x)<<0) + +#define SOLO_VI_WIN_CTRL0(ch) (0x0180 + ((ch)*4)) +#define SOLO_VI_WIN_CTRL1(ch) (0x01C0 + ((ch)*4)) + +#define SOLO_VI_WIN_CHANNEL(n) ((n)<<28) + +#define SOLO_VI_WIN_PIP(n) ((n)<<27) +#define SOLO_VI_WIN_SCALE(n) ((n)<<24) + +#define SOLO_VI_WIN_SX(x) ((x)<<12) +#define SOLO_VI_WIN_EX(x) ((x)<<0) + +#define SOLO_VI_WIN_SY(x) ((x)<<12) +#define SOLO_VI_WIN_EY(x) ((x)<<0) + +#define SOLO_VI_WIN_ON(ch) (0x0200 + ((ch)*4)) + +#define SOLO_VI_WIN_SW 0x0240 +#define SOLO_VI_WIN_LIVE_AUTO_MUTE 0x0244 + +#define SOLO_VI_MOT_ADR 0x0260 +#define SOLO_VI_MOTION_EN(mask) ((mask)<<16) +#define SOLO_VI_MOT_CTRL 0x0264 +#define SOLO_VI_MOTION_FRAME_COUNT(n) ((n)<<24) +#define SOLO_VI_MOTION_SAMPLE_LENGTH(n) ((n)<<16) +#define SOLO_VI_MOTION_INTR_START_STOP (1<<15) +#define SOLO_VI_MOTION_FREEZE_DATA (1<<14) +#define SOLO_VI_MOTION_SAMPLE_COUNT(n) ((n)<<0) +#define SOLO_VI_MOT_CLEAR 0x0268 +#define SOLO_VI_MOT_STATUS 0x026C +#define SOLO_VI_MOTION_CNT(n) ((n)<<0) +#define SOLO_VI_MOTION_BORDER 0x0270 +#define SOLO_VI_MOTION_BAR 0x0274 +#define SOLO_VI_MOTION_Y_SET (1<<29) +#define SOLO_VI_MOTION_Y_ADD (1<<28) +#define SOLO_VI_MOTION_CB_SET (1<<27) +#define SOLO_VI_MOTION_CB_ADD (1<<26) +#define SOLO_VI_MOTION_CR_SET (1<<25) +#define SOLO_VI_MOTION_CR_ADD (1<<24) +#define SOLO_VI_MOTION_Y_VALUE(v) ((v)<<16) +#define SOLO_VI_MOTION_CB_VALUE(v) ((v)<<8) +#define SOLO_VI_MOTION_CR_VALUE(v) ((v)<<0) + +#define SOLO_VO_FMT_ENC 0x0300 +#define SOLO_VO_SCAN_MODE_PROGRESSIVE (1<<31) +#define SOLO_VO_FMT_TYPE_PAL (1<<30) +#define SOLO_VO_FMT_TYPE_NTSC 0 +#define SOLO_VO_USER_SET (1<<29) + +#define SOLO_VO_FI_CHANGE (1<<20) +#define SOLO_VO_USER_COLOR_SET_VSYNC (1<<19) +#define SOLO_VO_USER_COLOR_SET_HSYNC (1<<18) +#define SOLO_VO_USER_COLOR_SET_NAV (1<<17) +#define SOLO_VO_USER_COLOR_SET_NAH (1<<16) +#define SOLO_VO_NA_COLOR_Y(Y) ((Y)<<8) +#define SOLO_VO_NA_COLOR_CB(CB) (((CB)/16)<<4) +#define SOLO_VO_NA_COLOR_CR(CR) (((CR)/16)<<0) + +#define SOLO_VO_ACT_H 0x0304 +#define SOLO_VO_H_BLANK(n) ((n)<<22) +#define SOLO_VO_H_START(n) ((n)<<11) +#define SOLO_VO_H_STOP(n) ((n)<<0) + +#define SOLO_VO_ACT_V 0x0308 +#define SOLO_VO_V_BLANK(n) ((n)<<22) +#define SOLO_VO_V_START(n) ((n)<<11) +#define SOLO_VO_V_STOP(n) ((n)<<0) + +#define SOLO_VO_RANGE_HV 0x030C +#define SOLO_VO_SYNC_INVERT (1<<24) +#define SOLO_VO_HSYNC_INVERT (1<<23) +#define SOLO_VO_VSYNC_INVERT (1<<22) +#define SOLO_VO_H_LEN(n) ((n)<<11) +#define SOLO_VO_V_LEN(n) ((n)<<0) + +#define SOLO_VO_DISP_CTRL 0x0310 +#define SOLO_VO_DISP_ON (1<<31) +#define SOLO_VO_DISP_ERASE_COUNT(n) ((n&0xf)<<24) +#define SOLO_VO_DISP_DOUBLE_SCAN (1<<22) +#define SOLO_VO_DISP_SINGLE_PAGE (1<<21) +#define SOLO_VO_DISP_BASE(n) (((n)>>16) & 0xffff) + +#define SOLO_VO_DISP_ERASE 0x0314 +#define SOLO_VO_DISP_ERASE_ON (1<<0) + +#define SOLO_VO_ZOOM_CTRL 0x0318 +#define SOLO_VO_ZOOM_VER_ON (1<<24) +#define SOLO_VO_ZOOM_HOR_ON (1<<23) +#define SOLO_VO_ZOOM_V_COMP (1<<22) +#define SOLO_VO_ZOOM_SX(h) (((h)/2)<<11) +#define SOLO_VO_ZOOM_SY(v) (((v)/2)<<0) + +#define SOLO_VO_FREEZE_CTRL 0x031C +#define SOLO_VO_FREEZE_ON (1<<1) +#define SOLO_VO_FREEZE_INTERPOLATION (1<<0) + +#define SOLO_VO_BKG_COLOR 0x0320 +#define SOLO_BG_Y(y) ((y)<<16) +#define SOLO_BG_U(u) ((u)<<8) +#define SOLO_BG_V(v) ((v)<<0) + +#define SOLO_VO_DEINTERLACE 0x0324 +#define SOLO_VO_DEINTERLACE_THRESHOLD(n) ((n)<<8) +#define SOLO_VO_DEINTERLACE_EDGE_VALUE(n) ((n)<<0) + +#define SOLO_VO_BORDER_LINE_COLOR 0x0330 +#define SOLO_VO_BORDER_FILL_COLOR 0x0334 +#define SOLO_VO_BORDER_LINE_MASK 0x0338 +#define SOLO_VO_BORDER_FILL_MASK 0x033c + +#define SOLO_VO_BORDER_X(n) (0x0340+((n)*4)) +#define SOLO_VO_BORDER_Y(n) (0x0354+((n)*4)) + +#define SOLO_VO_CELL_EXT_SET 0x0368 +#define SOLO_VO_CELL_EXT_START 0x036c +#define SOLO_VO_CELL_EXT_STOP 0x0370 + +#define SOLO_VO_CELL_EXT_SET2 0x0374 +#define SOLO_VO_CELL_EXT_START2 0x0378 +#define SOLO_VO_CELL_EXT_STOP2 0x037c + +#define SOLO_VO_RECTANGLE_CTRL(n) (0x0368+((n)*12)) +#define SOLO_VO_RECTANGLE_START(n) (0x036c+((n)*12)) +#define SOLO_VO_RECTANGLE_STOP(n) (0x0370+((n)*12)) + +#define SOLO_VO_CURSOR_POS (0x0380) +#define SOLO_VO_CURSOR_CLR (0x0384) +#define SOLO_VO_CURSOR_CLR2 (0x0388) +#define SOLO_VO_CURSOR_MASK(id) (0x0390+((id)*4)) + +#define SOLO_VO_EXPANSION(id) (0x0250+((id)*4)) + +#define SOLO_OSG_CONFIG 0x03E0 +#define SOLO_VO_OSG_ON (1<<31) +#define SOLO_VO_OSG_COLOR_MUTE (1<<28) +#define SOLO_VO_OSG_ALPHA_RATE(n) ((n)<<22) +#define SOLO_VO_OSG_ALPHA_BG_RATE(n) ((n)<<16) +#define SOLO_VO_OSG_BASE(offset) (((offset)>>16)&0xffff) + +#define SOLO_OSG_ERASE 0x03E4 +#define SOLO_OSG_ERASE_ON (0x80) +#define SOLO_OSG_ERASE_OFF (0x00) + +#define SOLO_VO_OSG_BLINK 0x03E8 +#define SOLO_VO_OSG_BLINK_ON (1<<1) +#define SOLO_VO_OSG_BLINK_INTREVAL18 (1<<0) + +#define SOLO_CAP_BASE 0x0400 +#define SOLO_CAP_MAX_PAGE(n) ((n)<<16) +#define SOLO_CAP_BASE_ADDR(n) ((n)<<0) +#define SOLO_CAP_BTW 0x0404 +#define SOLO_CAP_PROG_BANDWIDTH(n) ((n)<<8) +#define SOLO_CAP_MAX_BANDWIDTH(n) ((n)<<0) + +#define SOLO_DIM_SCALE1 0x0408 +#define SOLO_DIM_SCALE2 0x040C +#define SOLO_DIM_SCALE3 0x0410 +#define SOLO_DIM_SCALE4 0x0414 +#define SOLO_DIM_SCALE5 0x0418 +#define SOLO_DIM_V_MB_NUM_FRAME(n) ((n)<<16) +#define SOLO_DIM_V_MB_NUM_FIELD(n) ((n)<<8) +#define SOLO_DIM_H_MB_NUM(n) ((n)<<0) + +#define SOLO_DIM_PROG 0x041C +#define SOLO_CAP_STATUS 0x0420 + +#define SOLO_CAP_CH_SCALE(ch) (0x0440+((ch)*4)) +#define SOLO_CAP_CH_COMP_ENA_E(ch) (0x0480+((ch)*4)) +#define SOLO_CAP_CH_INTV(ch) (0x04C0+((ch)*4)) +#define SOLO_CAP_CH_INTV_E(ch) (0x0500+((ch)*4)) + + +#define SOLO_VE_CFG0 0x0610 +#define SOLO_VE_TWO_PAGE_MODE (1<<31) +#define SOLO_VE_INTR_CTRL(n) ((n)<<24) +#define SOLO_VE_BLOCK_SIZE(n) ((n)<<16) +#define SOLO_VE_BLOCK_BASE(n) ((n)<<0) + +#define SOLO_VE_CFG1 0x0614 +#define SOLO6110_VE_MPEG_SIZE_H(n) ((n)<<28) /* 6110 only */ +#define SOLO6010_VE_BYTE_ALIGN(n) ((n)<<24) /* 6010 only */ +#define SOLO6110_VE_JPEG_SIZE_H(n) ((n)<<20) /* 6110 only */ +#define SOLO_VE_INSERT_INDEX (1<<18) +#define SOLO_VE_MOTION_MODE(n) ((n)<<16) +#define SOLO_VE_MOTION_BASE(n) ((n)<<0) + +#define SOLO_VE_WMRK_POLY 0x061C +#define SOLO_VE_VMRK_INIT_KEY 0x0620 +#define SOLO_VE_WMRK_STRL 0x0624 +#define SOLO_VE_ENCRYP_POLY 0x0628 +#define SOLO_VE_ENCRYP_INIT 0x062C +#define SOLO_VE_ATTR 0x0630 +#define SOLO_VE_LITTLE_ENDIAN (1<<31) +#define SOLO_COMP_ATTR_RN (1<<30) +#define SOLO_COMP_ATTR_FCODE(n) ((n)<<27) +#define SOLO_COMP_TIME_INC(n) ((n)<<25) +#define SOLO_COMP_TIME_WIDTH(n) ((n)<<21) +#define SOLO_DCT_INTERVAL(n) ((n)<<16) + +#define SOLO_VE_STATE(n) (0x0640+((n)*4)) + +#define SOLO_VE_JPEG_QP_TBL 0x0670 +#define SOLO_VE_JPEG_QP_CH_L 0x0674 +#define SOLO_VE_JPEG_QP_CH_H 0x0678 +#define SOLO_VE_JPEG_CFG 0x067C +#define SOLO_VE_JPEG_CTRL 0x0680 + +#define SOLO_VE_OSD_CH 0x0690 +#define SOLO_VE_OSD_BASE 0x0694 +#define SOLO_VE_OSD_CLR 0x0698 +#define SOLO_VE_OSD_OPT 0x069C + +#define SOLO_VE_CH_INTL(ch) (0x0700+((ch)*4)) +#define SOLO6010_VE_CH_MOT(ch) (0x0740+((ch)*4)) /* 6010 only */ +#define SOLO_VE_CH_QP(ch) (0x0780+((ch)*4)) +#define SOLO_VE_CH_QP_E(ch) (0x07C0+((ch)*4)) +#define SOLO_VE_CH_GOP(ch) (0x0800+((ch)*4)) +#define SOLO_VE_CH_GOP_E(ch) (0x0840+((ch)*4)) +#define SOLO_VE_CH_REF_BASE(ch) (0x0880+((ch)*4)) +#define SOLO_VE_CH_REF_BASE_E(ch) (0x08C0+((ch)*4)) + +#define SOLO_VE_MPEG4_QUE(n) (0x0A00+((n)*8)) +#define SOLO_VE_JPEG_QUE(n) (0x0A04+((n)*8)) + +#define SOLO_VD_CFG0 0x0900 +#define SOLO6010_VD_CFG_NO_WRITE_NO_WINDOW (1<<24) /* 6010 only */ +#define SOLO_VD_CFG_BUSY_WIAT_CODE (1<<23) +#define SOLO_VD_CFG_BUSY_WIAT_REF (1<<22) +#define SOLO_VD_CFG_BUSY_WIAT_RES (1<<21) +#define SOLO_VD_CFG_BUSY_WIAT_MS (1<<20) +#define SOLO_VD_CFG_SINGLE_MODE (1<<18) +#define SOLO_VD_CFG_SCAL_MANUAL (1<<17) +#define SOLO_VD_CFG_USER_PAGE_CTRL (1<<16) +#define SOLO_VD_CFG_LITTLE_ENDIAN (1<<15) +#define SOLO_VD_CFG_START_FI (1<<14) +#define SOLO_VD_CFG_ERR_LOCK (1<<13) +#define SOLO_VD_CFG_ERR_INT_ENA (1<<12) +#define SOLO_VD_CFG_TIME_WIDTH(n) ((n)<<8) +#define SOLO_VD_CFG_DCT_INTERVAL(n) ((n)<<0) + +#define SOLO_VD_CFG1 0x0904 + +#define SOLO_VD_DEINTERLACE 0x0908 +#define SOLO_VD_DEINTERLACE_THRESHOLD(n) ((n)<<8) +#define SOLO_VD_DEINTERLACE_EDGE_VALUE(n) ((n)<<0) + +#define SOLO_VD_CODE_ADR 0x090C + +#define SOLO_VD_CTRL 0x0910 +#define SOLO_VD_OPER_ON (1<<31) +#define SOLO_VD_MAX_ITEM(n) ((n)<<0) + +#define SOLO_VD_STATUS0 0x0920 +#define SOLO_VD_STATUS0_INTR_ACK (1<<22) +#define SOLO_VD_STATUS0_INTR_EMPTY (1<<21) +#define SOLO_VD_STATUS0_INTR_ERR (1<<20) + +#define SOLO_VD_STATUS1 0x0924 + +#define SOLO_VD_IDX0 0x0930 +#define SOLO_VD_IDX_INTERLACE (1<<30) +#define SOLO_VD_IDX_CHANNEL(n) ((n)<<24) +#define SOLO_VD_IDX_SIZE(n) ((n)<<0) + +#define SOLO_VD_IDX1 0x0934 +#define SOLO_VD_IDX_SRC_SCALE(n) ((n)<<28) +#define SOLO_VD_IDX_WINDOW(n) ((n)<<24) +#define SOLO_VD_IDX_DEINTERLACE (1<<16) +#define SOLO_VD_IDX_H_BLOCK(n) ((n)<<8) +#define SOLO_VD_IDX_V_BLOCK(n) ((n)<<0) + +#define SOLO_VD_IDX2 0x0938 +#define SOLO_VD_IDX_REF_BASE_SIDE (1<<31) +#define SOLO_VD_IDX_REF_BASE(n) (((n)>>16)&0xffff) + +#define SOLO_VD_IDX3 0x093C +#define SOLO_VD_IDX_DISP_SCALE(n) ((n)<<28) +#define SOLO_VD_IDX_INTERLACE_WR (1<<27) +#define SOLO_VD_IDX_INTERPOL (1<<26) +#define SOLO_VD_IDX_HOR2X (1<<25) +#define SOLO_VD_IDX_OFFSET_X(n) ((n)<<12) +#define SOLO_VD_IDX_OFFSET_Y(n) ((n)<<0) + +#define SOLO_VD_IDX4 0x0940 +#define SOLO_VD_IDX_DEC_WR_PAGE(n) ((n)<<8) +#define SOLO_VD_IDX_DISP_RD_PAGE(n) ((n)<<0) + +#define SOLO_VD_WR_PAGE(n) (0x03F0 + ((n) * 4)) + + +#define SOLO_GPIO_CONFIG_0 0x0B00 +#define SOLO_GPIO_CONFIG_1 0x0B04 +#define SOLO_GPIO_DATA_OUT 0x0B08 +#define SOLO_GPIO_DATA_IN 0x0B0C +#define SOLO_GPIO_INT_ACK_STA 0x0B10 +#define SOLO_GPIO_INT_ENA 0x0B14 +#define SOLO_GPIO_INT_CFG_0 0x0B18 +#define SOLO_GPIO_INT_CFG_1 0x0B1C + + +#define SOLO_IIC_CFG 0x0B20 +#define SOLO_IIC_ENABLE (1<<8) +#define SOLO_IIC_PRESCALE(n) ((n)<<0) + +#define SOLO_IIC_CTRL 0x0B24 +#define SOLO_IIC_AUTO_CLEAR (1<<20) +#define SOLO_IIC_STATE_RX_ACK (1<<19) +#define SOLO_IIC_STATE_BUSY (1<<18) +#define SOLO_IIC_STATE_SIG_ERR (1<<17) +#define SOLO_IIC_STATE_TRNS (1<<16) +#define SOLO_IIC_CH_SET(n) ((n)<<5) +#define SOLO_IIC_ACK_EN (1<<4) +#define SOLO_IIC_START (1<<3) +#define SOLO_IIC_STOP (1<<2) +#define SOLO_IIC_READ (1<<1) +#define SOLO_IIC_WRITE (1<<0) + +#define SOLO_IIC_TXD 0x0B28 +#define SOLO_IIC_RXD 0x0B2C + +/* + * UART REGISTER + */ +#define SOLO_UART_CONTROL(n) (0x0BA0 + ((n)*0x20)) +#define SOLO_UART_CLK_DIV(n) ((n)<<24) +#define SOLO_MODEM_CTRL_EN (1<<20) +#define SOLO_PARITY_ERROR_DROP (1<<18) +#define SOLO_IRQ_ERR_EN (1<<17) +#define SOLO_IRQ_RX_EN (1<<16) +#define SOLO_IRQ_TX_EN (1<<15) +#define SOLO_RX_EN (1<<14) +#define SOLO_TX_EN (1<<13) +#define SOLO_UART_HALF_DUPLEX (1<<12) +#define SOLO_UART_LOOPBACK (1<<11) + +#define SOLO_BAUDRATE_230400 ((0<<9)|(0<<6)) +#define SOLO_BAUDRATE_115200 ((0<<9)|(1<<6)) +#define SOLO_BAUDRATE_57600 ((0<<9)|(2<<6)) +#define SOLO_BAUDRATE_38400 ((0<<9)|(3<<6)) +#define SOLO_BAUDRATE_19200 ((0<<9)|(4<<6)) +#define SOLO_BAUDRATE_9600 ((0<<9)|(5<<6)) +#define SOLO_BAUDRATE_4800 ((0<<9)|(6<<6)) +#define SOLO_BAUDRATE_2400 ((1<<9)|(6<<6)) +#define SOLO_BAUDRATE_1200 ((2<<9)|(6<<6)) +#define SOLO_BAUDRATE_300 ((3<<9)|(6<<6)) + +#define SOLO_UART_DATA_BIT_8 (3<<4) +#define SOLO_UART_DATA_BIT_7 (2<<4) +#define SOLO_UART_DATA_BIT_6 (1<<4) +#define SOLO_UART_DATA_BIT_5 (0<<4) + +#define SOLO_UART_STOP_BIT_1 (0<<2) +#define SOLO_UART_STOP_BIT_2 (1<<2) + +#define SOLO_UART_PARITY_NONE (0<<0) +#define SOLO_UART_PARITY_EVEN (2<<0) +#define SOLO_UART_PARITY_ODD (3<<0) + +#define SOLO_UART_STATUS(n) (0x0BA4 + ((n)*0x20)) +#define SOLO_UART_CTS (1<<15) +#define SOLO_UART_RX_BUSY (1<<14) +#define SOLO_UART_OVERRUN (1<<13) +#define SOLO_UART_FRAME_ERR (1<<12) +#define SOLO_UART_PARITY_ERR (1<<11) +#define SOLO_UART_TX_BUSY (1<<5) + +#define SOLO_UART_RX_BUFF_CNT(stat) (((stat)>>6) & 0x1f) +#define SOLO_UART_RX_BUFF_SIZE 8 +#define SOLO_UART_TX_BUFF_CNT(stat) (((stat)>>0) & 0x1f) +#define SOLO_UART_TX_BUFF_SIZE 8 + +#define SOLO_UART_TX_DATA(n) (0x0BA8 + ((n)*0x20)) +#define SOLO_UART_TX_DATA_PUSH (1<<8) +#define SOLO_UART_RX_DATA(n) (0x0BAC + ((n)*0x20)) +#define SOLO_UART_RX_DATA_POP (1<<8) + +#define SOLO_TIMER_CLOCK_NUM 0x0be0 +#define SOLO_TIMER_WATCHDOG 0x0be4 +#define SOLO_TIMER_USEC 0x0be8 +#define SOLO_TIMER_SEC 0x0bec + +#define SOLO_AUDIO_CONTROL 0x0D00 +#define SOLO_AUDIO_ENABLE (1<<31) +#define SOLO_AUDIO_MASTER_MODE (1<<30) +#define SOLO_AUDIO_I2S_MODE (1<<29) +#define SOLO_AUDIO_I2S_LR_SWAP (1<<27) +#define SOLO_AUDIO_I2S_8BIT (1<<26) +#define SOLO_AUDIO_I2S_MULTI(n) ((n)<<24) +#define SOLO_AUDIO_MIX_9TO0 (1<<23) +#define SOLO_AUDIO_DEC_9TO0_VOL(n) ((n)<<20) +#define SOLO_AUDIO_MIX_19TO10 (1<<19) +#define SOLO_AUDIO_DEC_19TO10_VOL(n) ((n)<<16) +#define SOLO_AUDIO_MODE(n) ((n)<<0) +#define SOLO_AUDIO_SAMPLE 0x0D04 +#define SOLO_AUDIO_EE_MODE_ON (1<<30) +#define SOLO_AUDIO_EE_ENC_CH(ch) ((ch)<<25) +#define SOLO_AUDIO_BITRATE(n) ((n)<<16) +#define SOLO_AUDIO_CLK_DIV(n) ((n)<<0) +#define SOLO_AUDIO_FDMA_INTR 0x0D08 +#define SOLO_AUDIO_FDMA_INTERVAL(n) ((n)<<19) +#define SOLO_AUDIO_INTR_ORDER(n) ((n)<<16) +#define SOLO_AUDIO_FDMA_BASE(n) ((n)<<0) +#define SOLO_AUDIO_EVOL_0 0x0D0C +#define SOLO_AUDIO_EVOL_1 0x0D10 +#define SOLO_AUDIO_EVOL(ch, value) ((value)<<((ch)%10)) +#define SOLO_AUDIO_STA 0x0D14 + + +#define SOLO_WATCHDOG 0x0BE4 +#define WATCHDOG_STAT(status) (status<<8) +#define WATCHDOG_TIME(sec) (sec&0xff) + +#endif /* __SOLO6010_REGISTERS_H */ diff --git a/drivers/staging/solo6x10/solo6010-core.c b/drivers/staging/solo6x10/solo6010-core.c deleted file mode 100644 index c713a74691dd..000000000000 --- a/drivers/staging/solo6x10/solo6010-core.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com - * Copyright (C) 2010 Ben Collins - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include -#include - -#include "solo6010.h" -#include "solo6010-tw28.h" - -MODULE_DESCRIPTION("Softlogic 6010 MP4 Encoder/Decoder V4L2/ALSA Driver"); -MODULE_AUTHOR("Ben Collins "); -MODULE_VERSION(SOLO6010_VERSION); -MODULE_LICENSE("GPL"); - -void solo6010_irq_on(struct solo6010_dev *solo_dev, u32 mask) -{ - solo_dev->irq_mask |= mask; - solo_reg_write(solo_dev, SOLO_IRQ_ENABLE, solo_dev->irq_mask); -} - -void solo6010_irq_off(struct solo6010_dev *solo_dev, u32 mask) -{ - solo_dev->irq_mask &= ~mask; - solo_reg_write(solo_dev, SOLO_IRQ_ENABLE, solo_dev->irq_mask); -} - -/* XXX We should check the return value of the sub-device ISR's */ -static irqreturn_t solo6010_isr(int irq, void *data) -{ - struct solo6010_dev *solo_dev = data; - u32 status; - int i; - - status = solo_reg_read(solo_dev, SOLO_IRQ_STAT); - if (!status) - return IRQ_NONE; - - if (status & ~solo_dev->irq_mask) { - solo_reg_write(solo_dev, SOLO_IRQ_STAT, - status & ~solo_dev->irq_mask); - status &= solo_dev->irq_mask; - } - - if (status & SOLO_IRQ_PCI_ERR) { - u32 err = solo_reg_read(solo_dev, SOLO_PCI_ERR); - solo_p2m_error_isr(solo_dev, err); - solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_PCI_ERR); - } - - for (i = 0; i < SOLO_NR_P2M; i++) - if (status & SOLO_IRQ_P2M(i)) - solo_p2m_isr(solo_dev, i); - - if (status & SOLO_IRQ_IIC) - solo_i2c_isr(solo_dev); - - if (status & SOLO_IRQ_VIDEO_IN) - solo_video_in_isr(solo_dev); - - /* Call this first so enc gets detected flag set */ - if (status & SOLO_IRQ_MOTION) - solo_motion_isr(solo_dev); - - if (status & SOLO_IRQ_ENCODER) - solo_enc_v4l2_isr(solo_dev); - - if (status & SOLO_IRQ_G723) - solo_g723_isr(solo_dev); - - return IRQ_HANDLED; -} - -static void free_solo_dev(struct solo6010_dev *solo_dev) -{ - struct pci_dev *pdev; - - if (!solo_dev) - return; - - pdev = solo_dev->pdev; - - /* If we never initialized the PCI device, then nothing else - * below here needs cleanup */ - if (!pdev) { - kfree(solo_dev); - return; - } - - /* Bring down the sub-devices first */ - solo_g723_exit(solo_dev); - solo_enc_v4l2_exit(solo_dev); - solo_enc_exit(solo_dev); - solo_v4l2_exit(solo_dev); - solo_disp_exit(solo_dev); - solo_gpio_exit(solo_dev); - solo_p2m_exit(solo_dev); - solo_i2c_exit(solo_dev); - - /* Now cleanup the PCI device */ - if (solo_dev->reg_base) { - solo6010_irq_off(solo_dev, ~0); - pci_iounmap(pdev, solo_dev->reg_base); - free_irq(pdev->irq, solo_dev); - } - - pci_release_regions(pdev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); - - kfree(solo_dev); -} - -static int __devinit solo6010_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - struct solo6010_dev *solo_dev; - int ret; - int sdram; - u8 chip_id; - u32 reg; - - solo_dev = kzalloc(sizeof(*solo_dev), GFP_KERNEL); - if (solo_dev == NULL) - return -ENOMEM; - - solo_dev->pdev = pdev; - spin_lock_init(&solo_dev->reg_io_lock); - pci_set_drvdata(pdev, solo_dev); - - ret = pci_enable_device(pdev); - if (ret) - goto fail_probe; - - pci_set_master(pdev); - - ret = pci_request_regions(pdev, SOLO6010_NAME); - if (ret) - goto fail_probe; - - solo_dev->reg_base = pci_ioremap_bar(pdev, 0); - if (solo_dev->reg_base == NULL) { - ret = -ENOMEM; - goto fail_probe; - } - - chip_id = solo_reg_read(solo_dev, SOLO_CHIP_OPTION) & - SOLO_CHIP_ID_MASK; - switch (chip_id) { - case 7: - solo_dev->nr_chans = 16; - solo_dev->nr_ext = 5; - break; - case 6: - solo_dev->nr_chans = 8; - solo_dev->nr_ext = 2; - break; - default: - dev_warn(&pdev->dev, "Invalid chip_id 0x%02x, " - "defaulting to 4 channels\n", - chip_id); - case 5: - solo_dev->nr_chans = 4; - solo_dev->nr_ext = 1; - } - - solo_dev->flags = id->driver_data; - - /* Disable all interrupts to start */ - solo6010_irq_off(solo_dev, ~0); - - reg = SOLO_SYS_CFG_SDRAM64BIT; - /* Initial global settings */ - if (!(solo_dev->flags & FLAGS_6110)) - reg |= SOLO6010_SYS_CFG_INPUTDIV(25) | - SOLO6010_SYS_CFG_FEEDBACKDIV((SOLO_CLOCK_MHZ * 2) - 2) | - SOLO6010_SYS_CFG_OUTDIV(3); - solo_reg_write(solo_dev, SOLO_SYS_CFG, reg); - - if (solo_dev->flags & FLAGS_6110) { - u32 sys_clock_MHz = SOLO_CLOCK_MHZ; - u32 pll_DIVQ; - u32 pll_DIVF; - - if (sys_clock_MHz < 125) { - pll_DIVQ = 3; - pll_DIVF = (sys_clock_MHz * 4) / 3; - } else { - pll_DIVQ = 2; - pll_DIVF = (sys_clock_MHz * 2) / 3; - } - - solo_reg_write(solo_dev, SOLO6110_PLL_CONFIG, - SOLO6110_PLL_RANGE_5_10MHZ | - SOLO6110_PLL_DIVR(9) | - SOLO6110_PLL_DIVQ_EXP(pll_DIVQ) | - SOLO6110_PLL_DIVF(pll_DIVF) | SOLO6110_PLL_FSEN); - mdelay(1); // PLL Locking time (1ms) - - solo_reg_write(solo_dev, SOLO_DMA_CTRL1, 3 << 8); /* ? */ - } else - solo_reg_write(solo_dev, SOLO_DMA_CTRL1, 1 << 8); /* ? */ - - solo_reg_write(solo_dev, SOLO_TIMER_CLOCK_NUM, SOLO_CLOCK_MHZ - 1); - - /* PLL locking time of 1ms */ - mdelay(1); - - ret = request_irq(pdev->irq, solo6010_isr, IRQF_SHARED, SOLO6010_NAME, - solo_dev); - if (ret) - goto fail_probe; - - /* Handle this from the start */ - solo6010_irq_on(solo_dev, SOLO_IRQ_PCI_ERR); - - ret = solo_i2c_init(solo_dev); - if (ret) - goto fail_probe; - - /* Setup the DMA engine */ - sdram = (solo_dev->nr_chans >= 8) ? 2 : 1; - solo_reg_write(solo_dev, SOLO_DMA_CTRL, - SOLO_DMA_CTRL_REFRESH_CYCLE(1) | - SOLO_DMA_CTRL_SDRAM_SIZE(sdram) | - SOLO_DMA_CTRL_SDRAM_CLK_INVERT | - SOLO_DMA_CTRL_READ_CLK_SELECT | - SOLO_DMA_CTRL_LATENCY(1)); - - ret = solo_p2m_init(solo_dev); - if (ret) - goto fail_probe; - - ret = solo_disp_init(solo_dev); - if (ret) - goto fail_probe; - - ret = solo_gpio_init(solo_dev); - if (ret) - goto fail_probe; - - ret = solo_tw28_init(solo_dev); - if (ret) - goto fail_probe; - - ret = solo_v4l2_init(solo_dev); - if (ret) - goto fail_probe; - - ret = solo_enc_init(solo_dev); - if (ret) - goto fail_probe; - - ret = solo_enc_v4l2_init(solo_dev); - if (ret) - goto fail_probe; - - ret = solo_g723_init(solo_dev); - if (ret) - goto fail_probe; - - return 0; - -fail_probe: - free_solo_dev(solo_dev); - return ret; -} - -static void __devexit solo6010_pci_remove(struct pci_dev *pdev) -{ - struct solo6010_dev *solo_dev = pci_get_drvdata(pdev); - - free_solo_dev(solo_dev); -} - -static struct pci_device_id solo6010_id_table[] = { - /* 6010 based cards */ - {PCI_DEVICE(PCI_VENDOR_ID_SOFTLOGIC, PCI_DEVICE_ID_SOLO6010)}, - {PCI_DEVICE(PCI_VENDOR_ID_SOFTLOGIC, PCI_DEVICE_ID_SOLO6110), - .driver_data = FLAGS_6110}, - {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_4)}, - {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_9)}, - {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_16)}, - {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_SOLO_4)}, - {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_SOLO_9)}, - {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_SOLO_16)}, - /* 6110 based cards */ - {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_6110_4)}, - {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_6110_8)}, - {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_6110_16)}, - {0,} -}; - -MODULE_DEVICE_TABLE(pci, solo6010_id_table); - -static struct pci_driver solo6010_pci_driver = { - .name = SOLO6010_NAME, - .id_table = solo6010_id_table, - .probe = solo6010_pci_probe, - .remove = solo6010_pci_remove, -}; - -static int __init solo6010_module_init(void) -{ - return pci_register_driver(&solo6010_pci_driver); -} - -static void __exit solo6010_module_exit(void) -{ - pci_unregister_driver(&solo6010_pci_driver); -} - -module_init(solo6010_module_init); -module_exit(solo6010_module_exit); diff --git a/drivers/staging/solo6x10/solo6010-disp.c b/drivers/staging/solo6x10/solo6010-disp.c deleted file mode 100644 index 99d14619e784..000000000000 --- a/drivers/staging/solo6x10/solo6010-disp.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com - * Copyright (C) 2010 Ben Collins - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include - -#include "solo6010.h" - -#define SOLO_VCLK_DELAY 3 -#define SOLO_PROGRESSIVE_VSIZE 1024 - -#define SOLO_MOT_THRESH_W 64 -#define SOLO_MOT_THRESH_H 64 -#define SOLO_MOT_THRESH_SIZE 8192 -#define SOLO_MOT_THRESH_REAL (SOLO_MOT_THRESH_W * SOLO_MOT_THRESH_H) -#define SOLO_MOT_FLAG_SIZE 512 -#define SOLO_MOT_FLAG_AREA (SOLO_MOT_FLAG_SIZE * 32) - -static unsigned video_type; -module_param(video_type, uint, 0644); -MODULE_PARM_DESC(video_type, "video_type (0 = NTSC/Default, 1 = PAL)"); - -static void solo_vin_config(struct solo6010_dev *solo_dev) -{ - solo_dev->vin_hstart = 8; - solo_dev->vin_vstart = 2; - - solo_reg_write(solo_dev, SOLO_SYS_VCLK, - SOLO_VCLK_SELECT(2) | - SOLO_VCLK_VIN1415_DELAY(SOLO_VCLK_DELAY) | - SOLO_VCLK_VIN1213_DELAY(SOLO_VCLK_DELAY) | - SOLO_VCLK_VIN1011_DELAY(SOLO_VCLK_DELAY) | - SOLO_VCLK_VIN0809_DELAY(SOLO_VCLK_DELAY) | - SOLO_VCLK_VIN0607_DELAY(SOLO_VCLK_DELAY) | - SOLO_VCLK_VIN0405_DELAY(SOLO_VCLK_DELAY) | - SOLO_VCLK_VIN0203_DELAY(SOLO_VCLK_DELAY) | - SOLO_VCLK_VIN0001_DELAY(SOLO_VCLK_DELAY)); - - solo_reg_write(solo_dev, SOLO_VI_ACT_I_P, - SOLO_VI_H_START(solo_dev->vin_hstart) | - SOLO_VI_V_START(solo_dev->vin_vstart) | - SOLO_VI_V_STOP(solo_dev->vin_vstart + - solo_dev->video_vsize)); - - solo_reg_write(solo_dev, SOLO_VI_ACT_I_S, - SOLO_VI_H_START(solo_dev->vout_hstart) | - SOLO_VI_V_START(solo_dev->vout_vstart) | - SOLO_VI_V_STOP(solo_dev->vout_vstart + - solo_dev->video_vsize)); - - solo_reg_write(solo_dev, SOLO_VI_ACT_P, - SOLO_VI_H_START(0) | - SOLO_VI_V_START(1) | - SOLO_VI_V_STOP(SOLO_PROGRESSIVE_VSIZE)); - - solo_reg_write(solo_dev, SOLO_VI_CH_FORMAT, - SOLO_VI_FD_SEL_MASK(0) | SOLO_VI_PROG_MASK(0)); - - solo_reg_write(solo_dev, SOLO_VI_FMT_CFG, 0); - solo_reg_write(solo_dev, SOLO_VI_PAGE_SW, 2); - - if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) { - solo_reg_write(solo_dev, SOLO_VI_PB_CONFIG, - SOLO_VI_PB_USER_MODE); - solo_reg_write(solo_dev, SOLO_VI_PB_RANGE_HV, - SOLO_VI_PB_HSIZE(858) | SOLO_VI_PB_VSIZE(246)); - solo_reg_write(solo_dev, SOLO_VI_PB_ACT_V, - SOLO_VI_PB_VSTART(4) | - SOLO_VI_PB_VSTOP(4 + 240)); - } else { - solo_reg_write(solo_dev, SOLO_VI_PB_CONFIG, - SOLO_VI_PB_USER_MODE | SOLO_VI_PB_PAL); - solo_reg_write(solo_dev, SOLO_VI_PB_RANGE_HV, - SOLO_VI_PB_HSIZE(864) | SOLO_VI_PB_VSIZE(294)); - solo_reg_write(solo_dev, SOLO_VI_PB_ACT_V, - SOLO_VI_PB_VSTART(4) | - SOLO_VI_PB_VSTOP(4 + 288)); - } - solo_reg_write(solo_dev, SOLO_VI_PB_ACT_H, SOLO_VI_PB_HSTART(16) | - SOLO_VI_PB_HSTOP(16 + 720)); -} - -static void solo_disp_config(struct solo6010_dev *solo_dev) -{ - solo_dev->vout_hstart = 6; - solo_dev->vout_vstart = 8; - - solo_reg_write(solo_dev, SOLO_VO_BORDER_LINE_COLOR, - (0xa0 << 24) | (0x88 << 16) | (0xa0 << 8) | 0x88); - solo_reg_write(solo_dev, SOLO_VO_BORDER_FILL_COLOR, - (0x10 << 24) | (0x8f << 16) | (0x10 << 8) | 0x8f); - solo_reg_write(solo_dev, SOLO_VO_BKG_COLOR, - (16 << 24) | (128 << 16) | (16 << 8) | 128); - - solo_reg_write(solo_dev, SOLO_VO_FMT_ENC, - solo_dev->video_type | - SOLO_VO_USER_COLOR_SET_NAV | - SOLO_VO_NA_COLOR_Y(0) | - SOLO_VO_NA_COLOR_CB(0) | - SOLO_VO_NA_COLOR_CR(0)); - - solo_reg_write(solo_dev, SOLO_VO_ACT_H, - SOLO_VO_H_START(solo_dev->vout_hstart) | - SOLO_VO_H_STOP(solo_dev->vout_hstart + - solo_dev->video_hsize)); - - solo_reg_write(solo_dev, SOLO_VO_ACT_V, - SOLO_VO_V_START(solo_dev->vout_vstart) | - SOLO_VO_V_STOP(solo_dev->vout_vstart + - solo_dev->video_vsize)); - - solo_reg_write(solo_dev, SOLO_VO_RANGE_HV, - SOLO_VO_H_LEN(solo_dev->video_hsize) | - SOLO_VO_V_LEN(solo_dev->video_vsize)); - - solo_reg_write(solo_dev, SOLO_VI_WIN_SW, 5); - - solo_reg_write(solo_dev, SOLO_VO_DISP_CTRL, SOLO_VO_DISP_ON | - SOLO_VO_DISP_ERASE_COUNT(8) | - SOLO_VO_DISP_BASE(SOLO_DISP_EXT_ADDR)); - - solo_reg_write(solo_dev, SOLO_VO_DISP_ERASE, SOLO_VO_DISP_ERASE_ON); - - /* Enable channels we support */ - solo_reg_write(solo_dev, SOLO_VI_CH_ENA, (1 << solo_dev->nr_chans) - 1); - - /* Disable the watchdog */ - solo_reg_write(solo_dev, SOLO_WATCHDOG, 0); -} - -static int solo_dma_vin_region(struct solo6010_dev *solo_dev, u32 off, - u16 val, int reg_size) -{ - u16 buf[64]; - int i; - int ret = 0; - - for (i = 0; i < sizeof(buf) >> 1; i++) - buf[i] = val; - - for (i = 0; i < reg_size; i += sizeof(buf)) - ret |= solo_p2m_dma(solo_dev, SOLO_P2M_DMA_ID_VIN, 1, buf, - SOLO_MOTION_EXT_ADDR(solo_dev) + off + i, - sizeof(buf)); - - return ret; -} - -void solo_set_motion_threshold(struct solo6010_dev *solo_dev, u8 ch, u16 val) -{ - if (ch > solo_dev->nr_chans) - return; - - solo_dma_vin_region(solo_dev, SOLO_MOT_FLAG_AREA + - (ch * SOLO_MOT_THRESH_SIZE * 2), - val, SOLO_MOT_THRESH_REAL); -} - -/* First 8k is motion flag (512 bytes * 16). Following that is an 8k+8k - * threshold and working table for each channel. Atleast that's what the - * spec says. However, this code (take from rdk) has some mystery 8k - * block right after the flag area, before the first thresh table. */ -static void solo_motion_config(struct solo6010_dev *solo_dev) -{ - int i; - - for (i = 0; i < solo_dev->nr_chans; i++) { - /* Clear motion flag area */ - solo_dma_vin_region(solo_dev, i * SOLO_MOT_FLAG_SIZE, 0x0000, - SOLO_MOT_FLAG_SIZE); - - /* Clear working cache table */ - solo_dma_vin_region(solo_dev, SOLO_MOT_FLAG_AREA + - SOLO_MOT_THRESH_SIZE + - (i * SOLO_MOT_THRESH_SIZE * 2), - 0x0000, SOLO_MOT_THRESH_REAL); - - /* Set default threshold table */ - solo_set_motion_threshold(solo_dev, i, SOLO_DEF_MOT_THRESH); - } - - /* Default motion settings */ - solo_reg_write(solo_dev, SOLO_VI_MOT_ADR, SOLO_VI_MOTION_EN(0) | - (SOLO_MOTION_EXT_ADDR(solo_dev) >> 16)); - solo_reg_write(solo_dev, SOLO_VI_MOT_CTRL, - SOLO_VI_MOTION_FRAME_COUNT(3) | - SOLO_VI_MOTION_SAMPLE_LENGTH(solo_dev->video_hsize / 16) - | /* SOLO_VI_MOTION_INTR_START_STOP | */ - SOLO_VI_MOTION_SAMPLE_COUNT(10)); - - solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER, 0); - solo_reg_write(solo_dev, SOLO_VI_MOTION_BAR, 0); -} - -int solo_disp_init(struct solo6010_dev *solo_dev) -{ - int i; - - solo_dev->video_hsize = 704; - if (video_type == 0) { - solo_dev->video_type = SOLO_VO_FMT_TYPE_NTSC; - solo_dev->video_vsize = 240; - solo_dev->fps = 30; - } else { - solo_dev->video_type = SOLO_VO_FMT_TYPE_PAL; - solo_dev->video_vsize = 288; - solo_dev->fps = 25; - } - - solo_vin_config(solo_dev); - solo_motion_config(solo_dev); - solo_disp_config(solo_dev); - - for (i = 0; i < solo_dev->nr_chans; i++) - solo_reg_write(solo_dev, SOLO_VI_WIN_ON(i), 1); - - return 0; -} - -void solo_disp_exit(struct solo6010_dev *solo_dev) -{ - int i; - - solo6010_irq_off(solo_dev, SOLO_IRQ_MOTION); - - solo_reg_write(solo_dev, SOLO_VO_DISP_CTRL, 0); - solo_reg_write(solo_dev, SOLO_VO_ZOOM_CTRL, 0); - solo_reg_write(solo_dev, SOLO_VO_FREEZE_CTRL, 0); - - for (i = 0; i < solo_dev->nr_chans; i++) { - solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL0(i), 0); - solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL1(i), 0); - solo_reg_write(solo_dev, SOLO_VI_WIN_ON(i), 0); - } - - /* Set default border */ - for (i = 0; i < 5; i++) - solo_reg_write(solo_dev, SOLO_VO_BORDER_X(i), 0); - - for (i = 0; i < 5; i++) - solo_reg_write(solo_dev, SOLO_VO_BORDER_Y(i), 0); - - solo_reg_write(solo_dev, SOLO_VO_BORDER_LINE_MASK, 0); - solo_reg_write(solo_dev, SOLO_VO_BORDER_FILL_MASK, 0); - - solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_CTRL(0), 0); - solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_START(0), 0); - solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_STOP(0), 0); - - solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_CTRL(1), 0); - solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_START(1), 0); - solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_STOP(1), 0); -} diff --git a/drivers/staging/solo6x10/solo6010-enc.c b/drivers/staging/solo6x10/solo6010-enc.c deleted file mode 100644 index 7a3c4d59e57c..000000000000 --- a/drivers/staging/solo6x10/solo6010-enc.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com - * Copyright (C) 2010 Ben Collins - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include - -#include "solo6010.h" -#include "solo6010-osd-font.h" - -#define CAPTURE_MAX_BANDWIDTH 32 /* D1 4channel (D1 == 4) */ -#define OSG_BUFFER_SIZE 1024 - -#define VI_PROG_HSIZE (1280 - 16) -#define VI_PROG_VSIZE (1024 - 16) - -static void solo_capture_config(struct solo6010_dev *solo_dev) -{ - int i, j; - unsigned long height; - unsigned long width; - unsigned char *buf; - - solo_reg_write(solo_dev, SOLO_CAP_BASE, - SOLO_CAP_MAX_PAGE(SOLO_CAP_EXT_MAX_PAGE * - solo_dev->nr_chans) | - SOLO_CAP_BASE_ADDR(SOLO_CAP_EXT_ADDR(solo_dev) >> 16)); - solo_reg_write(solo_dev, SOLO_CAP_BTW, - (1 << 17) | SOLO_CAP_PROG_BANDWIDTH(2) | - SOLO_CAP_MAX_BANDWIDTH(CAPTURE_MAX_BANDWIDTH)); - - /* Set scale 1, 9 dimension */ - width = solo_dev->video_hsize; - height = solo_dev->video_vsize; - solo_reg_write(solo_dev, SOLO_DIM_SCALE1, - SOLO_DIM_H_MB_NUM(width / 16) | - SOLO_DIM_V_MB_NUM_FRAME(height / 8) | - SOLO_DIM_V_MB_NUM_FIELD(height / 16)); - - /* Set scale 2, 10 dimension */ - width = solo_dev->video_hsize / 2; - height = solo_dev->video_vsize; - solo_reg_write(solo_dev, SOLO_DIM_SCALE2, - SOLO_DIM_H_MB_NUM(width / 16) | - SOLO_DIM_V_MB_NUM_FRAME(height / 8) | - SOLO_DIM_V_MB_NUM_FIELD(height / 16)); - - /* Set scale 3, 11 dimension */ - width = solo_dev->video_hsize / 2; - height = solo_dev->video_vsize / 2; - solo_reg_write(solo_dev, SOLO_DIM_SCALE3, - SOLO_DIM_H_MB_NUM(width / 16) | - SOLO_DIM_V_MB_NUM_FRAME(height / 8) | - SOLO_DIM_V_MB_NUM_FIELD(height / 16)); - - /* Set scale 4, 12 dimension */ - width = solo_dev->video_hsize / 3; - height = solo_dev->video_vsize / 3; - solo_reg_write(solo_dev, SOLO_DIM_SCALE4, - SOLO_DIM_H_MB_NUM(width / 16) | - SOLO_DIM_V_MB_NUM_FRAME(height / 8) | - SOLO_DIM_V_MB_NUM_FIELD(height / 16)); - - /* Set scale 5, 13 dimension */ - width = solo_dev->video_hsize / 4; - height = solo_dev->video_vsize / 2; - solo_reg_write(solo_dev, SOLO_DIM_SCALE5, - SOLO_DIM_H_MB_NUM(width / 16) | - SOLO_DIM_V_MB_NUM_FRAME(height / 8) | - SOLO_DIM_V_MB_NUM_FIELD(height / 16)); - - /* Progressive */ - width = VI_PROG_HSIZE; - height = VI_PROG_VSIZE; - solo_reg_write(solo_dev, SOLO_DIM_PROG, - SOLO_DIM_H_MB_NUM(width / 16) | - SOLO_DIM_V_MB_NUM_FRAME(height / 16) | - SOLO_DIM_V_MB_NUM_FIELD(height / 16)); - - /* Clear OSD */ - solo_reg_write(solo_dev, SOLO_VE_OSD_CH, 0); - solo_reg_write(solo_dev, SOLO_VE_OSD_BASE, SOLO_EOSD_EXT_ADDR >> 16); - solo_reg_write(solo_dev, SOLO_VE_OSD_CLR, - 0xF0 << 16 | 0x80 << 8 | 0x80); - solo_reg_write(solo_dev, SOLO_VE_OSD_OPT, 0); - - /* Clear OSG buffer */ - buf = kzalloc(OSG_BUFFER_SIZE, GFP_KERNEL); - if (!buf) - return; - - for (i = 0; i < solo_dev->nr_chans; i++) { - for (j = 0; j < SOLO_EOSD_EXT_SIZE; j += OSG_BUFFER_SIZE) { - solo_p2m_dma(solo_dev, SOLO_P2M_DMA_ID_MP4E, 1, buf, - SOLO_EOSD_EXT_ADDR + - (i * SOLO_EOSD_EXT_SIZE) + j, - OSG_BUFFER_SIZE); - } - } - kfree(buf); -} - -int solo_osd_print(struct solo_enc_dev *solo_enc) -{ - struct solo6010_dev *solo_dev = solo_enc->solo_dev; - char *str = solo_enc->osd_text; - u8 *buf; - u32 reg = solo_reg_read(solo_dev, SOLO_VE_OSD_CH); - int len = strlen(str); - int i, j; - int x = 1, y = 1; - - if (len == 0) { - reg &= ~(1 << solo_enc->ch); - solo_reg_write(solo_dev, SOLO_VE_OSD_CH, reg); - return 0; - } - - buf = kzalloc(SOLO_EOSD_EXT_SIZE, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - for (i = 0; i < len; i++) { - for (j = 0; j < 16; j++) { - buf[(j*2) + (i%2) + ((x + (i/2)) * 32) + (y * 2048)] = - (solo_osd_font[(str[i] * 4) + (j / 4)] - >> ((3 - (j % 4)) * 8)) & 0xff; - } - } - - solo_p2m_dma(solo_dev, 0, 1, buf, SOLO_EOSD_EXT_ADDR + - (solo_enc->ch * SOLO_EOSD_EXT_SIZE), SOLO_EOSD_EXT_SIZE); - reg |= (1 << solo_enc->ch); - solo_reg_write(solo_dev, SOLO_VE_OSD_CH, reg); - - kfree(buf); - - return 0; -} - -static void solo_jpeg_config(struct solo6010_dev *solo_dev) -{ - u32 reg; - if (solo_dev->flags & FLAGS_6110) - reg = (4 << 24) | (3 << 16) | (2 << 8) | (1 << 0); - else - reg = (2 << 24) | (2 << 16) | (2 << 8) | (2 << 0); - solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_TBL, reg); - solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_CH_L, 0); - solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_CH_H, 0); - solo_reg_write(solo_dev, SOLO_VE_JPEG_CFG, - (SOLO_JPEG_EXT_SIZE(solo_dev) & 0xffff0000) | - ((SOLO_JPEG_EXT_ADDR(solo_dev) >> 16) & 0x0000ffff)); - solo_reg_write(solo_dev, SOLO_VE_JPEG_CTRL, 0xffffffff); - /* que limit, samp limit, pos limit */ - solo_reg_write(solo_dev, 0x0688, (0 << 16) | (30 << 8) | 60); -} - -static void solo_mp4e_config(struct solo6010_dev *solo_dev) -{ - int i; - u32 reg; - - /* We can only use VE_INTR_CTRL(0) if we want to support mjpeg */ - solo_reg_write(solo_dev, SOLO_VE_CFG0, - SOLO_VE_INTR_CTRL(0) | - SOLO_VE_BLOCK_SIZE(SOLO_MP4E_EXT_SIZE(solo_dev) >> 16) | - SOLO_VE_BLOCK_BASE(SOLO_MP4E_EXT_ADDR(solo_dev) >> 16)); - - solo_reg_write(solo_dev, SOLO_VE_CFG1, - SOLO_VE_INSERT_INDEX | SOLO_VE_MOTION_MODE(0)); - - solo_reg_write(solo_dev, SOLO_VE_WMRK_POLY, 0); - solo_reg_write(solo_dev, SOLO_VE_VMRK_INIT_KEY, 0); - solo_reg_write(solo_dev, SOLO_VE_WMRK_STRL, 0); - solo_reg_write(solo_dev, SOLO_VE_ENCRYP_POLY, 0); - solo_reg_write(solo_dev, SOLO_VE_ENCRYP_INIT, 0); - - reg = SOLO_VE_LITTLE_ENDIAN | SOLO_COMP_ATTR_FCODE(1) | - SOLO_COMP_TIME_INC(0) | SOLO_COMP_TIME_WIDTH(15); - if (solo_dev->flags & FLAGS_6110) - reg |= SOLO_DCT_INTERVAL(10); - else - reg |= SOLO_DCT_INTERVAL(36 / 4); - solo_reg_write(solo_dev, SOLO_VE_ATTR, reg); - - for (i = 0; i < solo_dev->nr_chans; i++) - solo_reg_write(solo_dev, SOLO_VE_CH_REF_BASE(i), - (SOLO_EREF_EXT_ADDR(solo_dev) + - (i * SOLO_EREF_EXT_SIZE)) >> 16); - - if (solo_dev->flags & FLAGS_6110) - solo_reg_write(solo_dev, 0x0634, 0x00040008); /* ? */ -} - -int solo_enc_init(struct solo6010_dev *solo_dev) -{ - int i; - - solo_capture_config(solo_dev); - solo_mp4e_config(solo_dev); - solo_jpeg_config(solo_dev); - - for (i = 0; i < solo_dev->nr_chans; i++) { - solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(i), 0); - solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(i), 0); - } - - solo6010_irq_on(solo_dev, SOLO_IRQ_ENCODER); - - return 0; -} - -void solo_enc_exit(struct solo6010_dev *solo_dev) -{ - int i; - - solo6010_irq_off(solo_dev, SOLO_IRQ_ENCODER); - - for (i = 0; i < solo_dev->nr_chans; i++) { - solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(i), 0); - solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(i), 0); - } -} diff --git a/drivers/staging/solo6x10/solo6010-g723.c b/drivers/staging/solo6x10/solo6010-g723.c deleted file mode 100644 index 254b46ab20c5..000000000000 --- a/drivers/staging/solo6x10/solo6010-g723.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com - * Copyright (C) 2010 Ben Collins - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "solo6010.h" -#include "solo6010-tw28.h" - -#define G723_INTR_ORDER 0 -#define G723_FDMA_PAGES 32 -#define G723_PERIOD_BYTES 48 -#define G723_PERIOD_BLOCK 1024 -#define G723_FRAMES_PER_PAGE 48 - -/* Sets up channels 16-19 for decoding and 0-15 for encoding */ -#define OUTMODE_MASK 0x300 - -#define SAMPLERATE 8000 -#define BITRATE 25 - -/* The solo writes to 1k byte pages, 32 pages, in the dma. Each 1k page - * is broken down to 20 * 48 byte regions (one for each channel possible) - * with the rest of the page being dummy data. */ -#define MAX_BUFFER (G723_PERIOD_BYTES * PERIODS_MAX) -#define IRQ_PAGES 4 /* 0 - 4 */ -#define PERIODS_MIN (1 << IRQ_PAGES) -#define PERIODS_MAX G723_FDMA_PAGES - -struct solo_snd_pcm { - int on; - spinlock_t lock; - struct solo6010_dev *solo_dev; - unsigned char g723_buf[G723_PERIOD_BYTES]; -}; - -static void solo_g723_config(struct solo6010_dev *solo_dev) -{ - int clk_div; - - clk_div = SOLO_CLOCK_MHZ / (SAMPLERATE * (BITRATE * 2) * 2); - - solo_reg_write(solo_dev, SOLO_AUDIO_SAMPLE, - SOLO_AUDIO_BITRATE(BITRATE) | - SOLO_AUDIO_CLK_DIV(clk_div)); - - solo_reg_write(solo_dev, SOLO_AUDIO_FDMA_INTR, - SOLO_AUDIO_FDMA_INTERVAL(IRQ_PAGES) | - SOLO_AUDIO_INTR_ORDER(G723_INTR_ORDER) | - SOLO_AUDIO_FDMA_BASE(SOLO_G723_EXT_ADDR(solo_dev) >> 16)); - - solo_reg_write(solo_dev, SOLO_AUDIO_CONTROL, - SOLO_AUDIO_ENABLE | SOLO_AUDIO_I2S_MODE | - SOLO_AUDIO_I2S_MULTI(3) | SOLO_AUDIO_MODE(OUTMODE_MASK)); -} - -void solo_g723_isr(struct solo6010_dev *solo_dev) -{ - struct snd_pcm_str *pstr = - &solo_dev->snd_pcm->streams[SNDRV_PCM_STREAM_CAPTURE]; - struct snd_pcm_substream *ss; - struct solo_snd_pcm *solo_pcm; - - solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_G723); - - for (ss = pstr->substream; ss != NULL; ss = ss->next) { - if (snd_pcm_substream_chip(ss) == NULL) - continue; - - /* This means open() hasn't been called on this one */ - if (snd_pcm_substream_chip(ss) == solo_dev) - continue; - - /* Haven't triggered a start yet */ - solo_pcm = snd_pcm_substream_chip(ss); - if (!solo_pcm->on) - continue; - - snd_pcm_period_elapsed(ss); - } -} - -static int snd_solo_hw_params(struct snd_pcm_substream *ss, - struct snd_pcm_hw_params *hw_params) -{ - return snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw_params)); -} - -static int snd_solo_hw_free(struct snd_pcm_substream *ss) -{ - return snd_pcm_lib_free_pages(ss); -} - -static struct snd_pcm_hardware snd_solo_pcm_hw = { - .info = (SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID), - .formats = SNDRV_PCM_FMTBIT_U8, - .rates = SNDRV_PCM_RATE_8000, - .rate_min = 8000, - .rate_max = 8000, - .channels_min = 1, - .channels_max = 1, - .buffer_bytes_max = MAX_BUFFER, - .period_bytes_min = G723_PERIOD_BYTES, - .period_bytes_max = G723_PERIOD_BYTES, - .periods_min = PERIODS_MIN, - .periods_max = PERIODS_MAX, -}; - -static int snd_solo_pcm_open(struct snd_pcm_substream *ss) -{ - struct solo6010_dev *solo_dev = snd_pcm_substream_chip(ss); - struct solo_snd_pcm *solo_pcm; - - solo_pcm = kzalloc(sizeof(*solo_pcm), GFP_KERNEL); - if (solo_pcm == NULL) - return -ENOMEM; - - spin_lock_init(&solo_pcm->lock); - solo_pcm->solo_dev = solo_dev; - ss->runtime->hw = snd_solo_pcm_hw; - - snd_pcm_substream_chip(ss) = solo_pcm; - - return 0; -} - -static int snd_solo_pcm_close(struct snd_pcm_substream *ss) -{ - struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); - - snd_pcm_substream_chip(ss) = solo_pcm->solo_dev; - kfree(solo_pcm); - - return 0; -} - -static int snd_solo_pcm_trigger(struct snd_pcm_substream *ss, int cmd) -{ - struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); - struct solo6010_dev *solo_dev = solo_pcm->solo_dev; - int ret = 0; - - spin_lock(&solo_pcm->lock); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - if (solo_pcm->on == 0) { - /* If this is the first user, switch on interrupts */ - if (atomic_inc_return(&solo_dev->snd_users) == 1) - solo6010_irq_on(solo_dev, SOLO_IRQ_G723); - solo_pcm->on = 1; - } - break; - case SNDRV_PCM_TRIGGER_STOP: - if (solo_pcm->on) { - /* If this was our last user, switch them off */ - if (atomic_dec_return(&solo_dev->snd_users) == 0) - solo6010_irq_off(solo_dev, SOLO_IRQ_G723); - solo_pcm->on = 0; - } - break; - default: - ret = -EINVAL; - } - - spin_unlock(&solo_pcm->lock); - - return ret; -} - -static int snd_solo_pcm_prepare(struct snd_pcm_substream *ss) -{ - return 0; -} - -static snd_pcm_uframes_t snd_solo_pcm_pointer(struct snd_pcm_substream *ss) -{ - struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); - struct solo6010_dev *solo_dev = solo_pcm->solo_dev; - snd_pcm_uframes_t idx = solo_reg_read(solo_dev, SOLO_AUDIO_STA) & 0x1f; - - return idx * G723_FRAMES_PER_PAGE; -} - -static int snd_solo_pcm_copy(struct snd_pcm_substream *ss, int channel, - snd_pcm_uframes_t pos, void __user *dst, - snd_pcm_uframes_t count) -{ - struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); - struct solo6010_dev *solo_dev = solo_pcm->solo_dev; - int err, i; - - for (i = 0; i < (count / G723_FRAMES_PER_PAGE); i++) { - int page = (pos / G723_FRAMES_PER_PAGE) + i; - - err = solo_p2m_dma(solo_dev, SOLO_P2M_DMA_ID_G723E, 0, - solo_pcm->g723_buf, - SOLO_G723_EXT_ADDR(solo_dev) + - (page * G723_PERIOD_BLOCK) + - (ss->number * G723_PERIOD_BYTES), - G723_PERIOD_BYTES); - if (err) - return err; - - err = copy_to_user(dst + (i * G723_PERIOD_BYTES), - solo_pcm->g723_buf, G723_PERIOD_BYTES); - - if (err) - return -EFAULT; - } - - return 0; -} - -static struct snd_pcm_ops snd_solo_pcm_ops = { - .open = snd_solo_pcm_open, - .close = snd_solo_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_solo_hw_params, - .hw_free = snd_solo_hw_free, - .prepare = snd_solo_pcm_prepare, - .trigger = snd_solo_pcm_trigger, - .pointer = snd_solo_pcm_pointer, - .copy = snd_solo_pcm_copy, -}; - -static int snd_solo_capture_volume_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *info) -{ - info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - info->count = 1; - info->value.integer.min = 0; - info->value.integer.max = 15; - info->value.integer.step = 1; - - return 0; -} - -static int snd_solo_capture_volume_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *value) -{ - struct solo6010_dev *solo_dev = snd_kcontrol_chip(kcontrol); - u8 ch = value->id.numid - 1; - - value->value.integer.value[0] = tw28_get_audio_gain(solo_dev, ch); - - return 0; -} - -static int snd_solo_capture_volume_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *value) -{ - struct solo6010_dev *solo_dev = snd_kcontrol_chip(kcontrol); - u8 ch = value->id.numid - 1; - u8 old_val; - - old_val = tw28_get_audio_gain(solo_dev, ch); - if (old_val == value->value.integer.value[0]) - return 0; - - tw28_set_audio_gain(solo_dev, ch, value->value.integer.value[0]); - - return 1; -} - -static struct snd_kcontrol_new snd_solo_capture_volume = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Capture Volume", - .info = snd_solo_capture_volume_info, - .get = snd_solo_capture_volume_get, - .put = snd_solo_capture_volume_put, -}; - -static int solo_snd_pcm_init(struct solo6010_dev *solo_dev) -{ - struct snd_card *card = solo_dev->snd_card; - struct snd_pcm *pcm; - struct snd_pcm_substream *ss; - int ret; - int i; - - ret = snd_pcm_new(card, card->driver, 0, 0, solo_dev->nr_chans, - &pcm); - if (ret < 0) - return ret; - - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, - &snd_solo_pcm_ops); - - snd_pcm_chip(pcm) = solo_dev; - pcm->info_flags = 0; - strcpy(pcm->name, card->shortname); - - for (i = 0, ss = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; - ss; ss = ss->next, i++) - sprintf(ss->name, "Camera #%d Audio", i); - - ret = snd_pcm_lib_preallocate_pages_for_all(pcm, - SNDRV_DMA_TYPE_CONTINUOUS, - snd_dma_continuous_data(GFP_KERNEL), - MAX_BUFFER, MAX_BUFFER); - if (ret < 0) - return ret; - - solo_dev->snd_pcm = pcm; - - return 0; -} - -int solo_g723_init(struct solo6010_dev *solo_dev) -{ - static struct snd_device_ops ops = { NULL }; - struct snd_card *card; - struct snd_kcontrol_new kctl; - char name[32]; - int ret; - - atomic_set(&solo_dev->snd_users, 0); - - /* Allows for easier mapping between video and audio */ - sprintf(name, "Softlogic%d", solo_dev->vfd->num); - - ret = snd_card_create(SNDRV_DEFAULT_IDX1, name, THIS_MODULE, 0, - &solo_dev->snd_card); - if (ret < 0) - return ret; - - card = solo_dev->snd_card; - - strcpy(card->driver, SOLO6010_NAME); - strcpy(card->shortname, "SOLO-6010 Audio"); - sprintf(card->longname, "%s on %s IRQ %d", card->shortname, - pci_name(solo_dev->pdev), solo_dev->pdev->irq); - snd_card_set_dev(card, &solo_dev->pdev->dev); - - ret = snd_device_new(card, SNDRV_DEV_LOWLEVEL, solo_dev, &ops); - if (ret < 0) - goto snd_error; - - /* Mixer controls */ - strcpy(card->mixername, "SOLO-6010"); - kctl = snd_solo_capture_volume; - kctl.count = solo_dev->nr_chans; - ret = snd_ctl_add(card, snd_ctl_new1(&kctl, solo_dev)); - if (ret < 0) - return ret; - - ret = solo_snd_pcm_init(solo_dev); - if (ret < 0) - goto snd_error; - - ret = snd_card_register(card); - if (ret < 0) - goto snd_error; - - solo_g723_config(solo_dev); - - dev_info(&solo_dev->pdev->dev, "Alsa sound card as %s\n", name); - - return 0; - -snd_error: - snd_card_free(card); - return ret; -} - -void solo_g723_exit(struct solo6010_dev *solo_dev) -{ - solo_reg_write(solo_dev, SOLO_AUDIO_CONTROL, 0); - solo6010_irq_off(solo_dev, SOLO_IRQ_G723); - - snd_card_free(solo_dev->snd_card); -} diff --git a/drivers/staging/solo6x10/solo6010-gpio.c b/drivers/staging/solo6x10/solo6010-gpio.c deleted file mode 100644 index 8869b88dc307..000000000000 --- a/drivers/staging/solo6x10/solo6010-gpio.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com - * Copyright (C) 2010 Ben Collins - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include - -#include "solo6010.h" - -static void solo_gpio_mode(struct solo6010_dev *solo_dev, - unsigned int port_mask, unsigned int mode) -{ - int port; - unsigned int ret; - - ret = solo_reg_read(solo_dev, SOLO_GPIO_CONFIG_0); - - /* To set gpio */ - for (port = 0; port < 16; port++) { - if (!((1 << port) & port_mask)) - continue; - - ret &= (~(3 << (port << 1))); - ret |= ((mode & 3) << (port << 1)); - } - - solo_reg_write(solo_dev, SOLO_GPIO_CONFIG_0, ret); - - /* To set extended gpio - sensor */ - ret = solo_reg_read(solo_dev, SOLO_GPIO_CONFIG_1); - - for (port = 0; port < 16; port++) { - if (!((1 << (port + 16)) & port_mask)) - continue; - - if (!mode) - ret &= ~(1 << port); - else - ret |= 1 << port; - } - - solo_reg_write(solo_dev, SOLO_GPIO_CONFIG_1, ret); -} - -static void solo_gpio_set(struct solo6010_dev *solo_dev, unsigned int value) -{ - solo_reg_write(solo_dev, SOLO_GPIO_DATA_OUT, - solo_reg_read(solo_dev, SOLO_GPIO_DATA_OUT) | value); -} - -static void solo_gpio_clear(struct solo6010_dev *solo_dev, unsigned int value) -{ - solo_reg_write(solo_dev, SOLO_GPIO_DATA_OUT, - solo_reg_read(solo_dev, SOLO_GPIO_DATA_OUT) & ~value); -} - -static void solo_gpio_config(struct solo6010_dev *solo_dev) -{ - /* Video reset */ - solo_gpio_mode(solo_dev, 0x30, 1); - solo_gpio_clear(solo_dev, 0x30); - udelay(100); - solo_gpio_set(solo_dev, 0x30); - udelay(100); - - /* Warning: Don't touch the next line unless you're sure of what - * you're doing: first four gpio [0-3] are used for video. */ - solo_gpio_mode(solo_dev, 0x0f, 2); - - /* We use bit 8-15 of SOLO_GPIO_CONFIG_0 for relay purposes */ - solo_gpio_mode(solo_dev, 0xff00, 1); - - /* Initially set relay status to 0 */ - solo_gpio_clear(solo_dev, 0xff00); -} - -int solo_gpio_init(struct solo6010_dev *solo_dev) -{ - solo_gpio_config(solo_dev); - return 0; -} - -void solo_gpio_exit(struct solo6010_dev *solo_dev) -{ - solo_gpio_clear(solo_dev, 0x30); - solo_gpio_config(solo_dev); -} diff --git a/drivers/staging/solo6x10/solo6010-i2c.c b/drivers/staging/solo6x10/solo6010-i2c.c deleted file mode 100644 index 60b69cd0d09d..000000000000 --- a/drivers/staging/solo6x10/solo6010-i2c.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com - * Copyright (C) 2010 Ben Collins - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* XXX: The SOLO6010 i2c does not have separate interrupts for each i2c - * channel. The bus can only handle one i2c event at a time. The below handles - * this all wrong. We should be using the status registers to see if the bus - * is in use, and have a global lock to check the status register. Also, - * the bulk of the work should be handled out-of-interrupt. The ugly loops - * that occur during interrupt scare me. The ISR should merely signal - * thread context, ACK the interrupt, and move on. -- BenC */ - -#include - -#include "solo6010.h" - -u8 solo_i2c_readbyte(struct solo6010_dev *solo_dev, int id, u8 addr, u8 off) -{ - struct i2c_msg msgs[2]; - u8 data; - - msgs[0].flags = 0; - msgs[0].addr = addr; - msgs[0].len = 1; - msgs[0].buf = &off; - - msgs[1].flags = I2C_M_RD; - msgs[1].addr = addr; - msgs[1].len = 1; - msgs[1].buf = &data; - - i2c_transfer(&solo_dev->i2c_adap[id], msgs, 2); - - return data; -} - -void solo_i2c_writebyte(struct solo6010_dev *solo_dev, int id, u8 addr, - u8 off, u8 data) -{ - struct i2c_msg msgs; - u8 buf[2]; - - buf[0] = off; - buf[1] = data; - msgs.flags = 0; - msgs.addr = addr; - msgs.len = 2; - msgs.buf = buf; - - i2c_transfer(&solo_dev->i2c_adap[id], &msgs, 1); -} - -static void solo_i2c_flush(struct solo6010_dev *solo_dev, int wr) -{ - u32 ctrl; - - ctrl = SOLO_IIC_CH_SET(solo_dev->i2c_id); - - if (solo_dev->i2c_state == IIC_STATE_START) - ctrl |= SOLO_IIC_START; - - if (wr) { - ctrl |= SOLO_IIC_WRITE; - } else { - ctrl |= SOLO_IIC_READ; - if (!(solo_dev->i2c_msg->flags & I2C_M_NO_RD_ACK)) - ctrl |= SOLO_IIC_ACK_EN; - } - - if (solo_dev->i2c_msg_ptr == solo_dev->i2c_msg->len) - ctrl |= SOLO_IIC_STOP; - - solo_reg_write(solo_dev, SOLO_IIC_CTRL, ctrl); -} - -static void solo_i2c_start(struct solo6010_dev *solo_dev) -{ - u32 addr = solo_dev->i2c_msg->addr << 1; - - if (solo_dev->i2c_msg->flags & I2C_M_RD) - addr |= 1; - - solo_dev->i2c_state = IIC_STATE_START; - solo_reg_write(solo_dev, SOLO_IIC_TXD, addr); - solo_i2c_flush(solo_dev, 1); -} - -static void solo_i2c_stop(struct solo6010_dev *solo_dev) -{ - solo6010_irq_off(solo_dev, SOLO_IRQ_IIC); - solo_reg_write(solo_dev, SOLO_IIC_CTRL, 0); - solo_dev->i2c_state = IIC_STATE_STOP; - wake_up(&solo_dev->i2c_wait); -} - -static int solo_i2c_handle_read(struct solo6010_dev *solo_dev) -{ -prepare_read: - if (solo_dev->i2c_msg_ptr != solo_dev->i2c_msg->len) { - solo_i2c_flush(solo_dev, 0); - return 0; - } - - solo_dev->i2c_msg_ptr = 0; - solo_dev->i2c_msg++; - solo_dev->i2c_msg_num--; - - if (solo_dev->i2c_msg_num == 0) { - solo_i2c_stop(solo_dev); - return 0; - } - - if (!(solo_dev->i2c_msg->flags & I2C_M_NOSTART)) { - solo_i2c_start(solo_dev); - } else { - if (solo_dev->i2c_msg->flags & I2C_M_RD) - goto prepare_read; - else - solo_i2c_stop(solo_dev); - } - - return 0; -} - -static int solo_i2c_handle_write(struct solo6010_dev *solo_dev) -{ -retry_write: - if (solo_dev->i2c_msg_ptr != solo_dev->i2c_msg->len) { - solo_reg_write(solo_dev, SOLO_IIC_TXD, - solo_dev->i2c_msg->buf[solo_dev->i2c_msg_ptr]); - solo_dev->i2c_msg_ptr++; - solo_i2c_flush(solo_dev, 1); - return 0; - } - - solo_dev->i2c_msg_ptr = 0; - solo_dev->i2c_msg++; - solo_dev->i2c_msg_num--; - - if (solo_dev->i2c_msg_num == 0) { - solo_i2c_stop(solo_dev); - return 0; - } - - if (!(solo_dev->i2c_msg->flags & I2C_M_NOSTART)) { - solo_i2c_start(solo_dev); - } else { - if (solo_dev->i2c_msg->flags & I2C_M_RD) - solo_i2c_stop(solo_dev); - else - goto retry_write; - } - - return 0; -} - -int solo_i2c_isr(struct solo6010_dev *solo_dev) -{ - u32 status = solo_reg_read(solo_dev, SOLO_IIC_CTRL); - int ret = -EINVAL; - - solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_IIC); - - if (status & (SOLO_IIC_STATE_TRNS & SOLO_IIC_STATE_SIG_ERR) || - solo_dev->i2c_id < 0) { - solo_i2c_stop(solo_dev); - return -ENXIO; - } - - switch (solo_dev->i2c_state) { - case IIC_STATE_START: - if (solo_dev->i2c_msg->flags & I2C_M_RD) { - solo_dev->i2c_state = IIC_STATE_READ; - ret = solo_i2c_handle_read(solo_dev); - break; - } - - solo_dev->i2c_state = IIC_STATE_WRITE; - case IIC_STATE_WRITE: - ret = solo_i2c_handle_write(solo_dev); - break; - - case IIC_STATE_READ: - solo_dev->i2c_msg->buf[solo_dev->i2c_msg_ptr] = - solo_reg_read(solo_dev, SOLO_IIC_RXD); - solo_dev->i2c_msg_ptr++; - - ret = solo_i2c_handle_read(solo_dev); - break; - - default: - solo_i2c_stop(solo_dev); - } - - return ret; -} - -static int solo_i2c_master_xfer(struct i2c_adapter *adap, - struct i2c_msg msgs[], int num) -{ - struct solo6010_dev *solo_dev = adap->algo_data; - unsigned long timeout; - int ret; - int i; - DEFINE_WAIT(wait); - - for (i = 0; i < SOLO_I2C_ADAPTERS; i++) { - if (&solo_dev->i2c_adap[i] == adap) - break; - } - - if (i == SOLO_I2C_ADAPTERS) - return num; /* XXX Right return value for failure? */ - - mutex_lock(&solo_dev->i2c_mutex); - solo_dev->i2c_id = i; - solo_dev->i2c_msg = msgs; - solo_dev->i2c_msg_num = num; - solo_dev->i2c_msg_ptr = 0; - - solo_reg_write(solo_dev, SOLO_IIC_CTRL, 0); - solo6010_irq_on(solo_dev, SOLO_IRQ_IIC); - solo_i2c_start(solo_dev); - - timeout = HZ / 2; - - for (;;) { - prepare_to_wait(&solo_dev->i2c_wait, &wait, TASK_INTERRUPTIBLE); - - if (solo_dev->i2c_state == IIC_STATE_STOP) - break; - - timeout = schedule_timeout(timeout); - if (!timeout) - break; - - if (signal_pending(current)) - break; - } - - finish_wait(&solo_dev->i2c_wait, &wait); - ret = num - solo_dev->i2c_msg_num; - solo_dev->i2c_state = IIC_STATE_IDLE; - solo_dev->i2c_id = -1; - - mutex_unlock(&solo_dev->i2c_mutex); - - return ret; -} - -static u32 solo_i2c_functionality(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm solo_i2c_algo = { - .master_xfer = solo_i2c_master_xfer, - .functionality = solo_i2c_functionality, -}; - -int solo_i2c_init(struct solo6010_dev *solo_dev) -{ - int i; - int ret; - - solo_reg_write(solo_dev, SOLO_IIC_CFG, - SOLO_IIC_PRESCALE(8) | SOLO_IIC_ENABLE); - - solo_dev->i2c_id = -1; - solo_dev->i2c_state = IIC_STATE_IDLE; - init_waitqueue_head(&solo_dev->i2c_wait); - mutex_init(&solo_dev->i2c_mutex); - - for (i = 0; i < SOLO_I2C_ADAPTERS; i++) { - struct i2c_adapter *adap = &solo_dev->i2c_adap[i]; - - snprintf(adap->name, I2C_NAME_SIZE, "%s I2C %d", - SOLO6010_NAME, i); - adap->algo = &solo_i2c_algo; - adap->algo_data = solo_dev; - adap->retries = 1; - adap->dev.parent = &solo_dev->pdev->dev; - - ret = i2c_add_adapter(adap); - if (ret) { - adap->algo_data = NULL; - break; - } - } - - if (ret) { - for (i = 0; i < SOLO_I2C_ADAPTERS; i++) { - if (!solo_dev->i2c_adap[i].algo_data) - break; - i2c_del_adapter(&solo_dev->i2c_adap[i]); - solo_dev->i2c_adap[i].algo_data = NULL; - } - return ret; - } - - dev_info(&solo_dev->pdev->dev, "Enabled %d i2c adapters\n", - SOLO_I2C_ADAPTERS); - - return 0; -} - -void solo_i2c_exit(struct solo6010_dev *solo_dev) -{ - int i; - - for (i = 0; i < SOLO_I2C_ADAPTERS; i++) { - if (!solo_dev->i2c_adap[i].algo_data) - continue; - i2c_del_adapter(&solo_dev->i2c_adap[i]); - solo_dev->i2c_adap[i].algo_data = NULL; - } -} diff --git a/drivers/staging/solo6x10/solo6010-jpeg.h b/drivers/staging/solo6x10/solo6010-jpeg.h deleted file mode 100644 index fb0507ecb307..000000000000 --- a/drivers/staging/solo6x10/solo6010-jpeg.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com - * Copyright (C) 2010 Ben Collins - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef __SOLO6010_JPEG_H -#define __SOLO6010_JPEG_H - -static unsigned char jpeg_header[] = { - 0xff, 0xd8, 0xff, 0xfe, 0x00, 0x0d, 0x42, 0x6c, - 0x75, 0x65, 0x63, 0x68, 0x65, 0x72, 0x72, 0x79, - 0x20, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x20, 0x16, - 0x18, 0x1c, 0x18, 0x14, 0x20, 0x1c, 0x1a, 0x1c, - 0x24, 0x22, 0x20, 0x26, 0x30, 0x50, 0x34, 0x30, - 0x2c, 0x2c, 0x30, 0x62, 0x46, 0x4a, 0x3a, 0x50, - 0x74, 0x66, 0x7a, 0x78, 0x72, 0x66, 0x70, 0x6e, - 0x80, 0x90, 0xb8, 0x9c, 0x80, 0x88, 0xae, 0x8a, - 0x6e, 0x70, 0xa0, 0xda, 0xa2, 0xae, 0xbe, 0xc4, - 0xce, 0xd0, 0xce, 0x7c, 0x9a, 0xe2, 0xf2, 0xe0, - 0xc8, 0xf0, 0xb8, 0xca, 0xce, 0xc6, 0xff, 0xdb, - 0x00, 0x43, 0x01, 0x22, 0x24, 0x24, 0x30, 0x2a, - 0x30, 0x5e, 0x34, 0x34, 0x5e, 0xc6, 0x84, 0x70, - 0x84, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, - 0xc6, 0xc6, 0xc6, 0xff, 0xc4, 0x01, 0xa2, 0x00, - 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, - 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, - 0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, - 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, - 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, - 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, - 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, - 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, - 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, - 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, - 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, - 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, - 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, - 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, - 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, - 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, - 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, - 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, - 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, - 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, - 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x01, - 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x11, 0x00, 0x02, 0x01, - 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, - 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, - 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, - 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, - 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, - 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, - 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, - 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, - 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, - 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, - 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, - 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, - 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, - 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, - 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, - 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, - 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, - 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, - 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, - 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, - 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, - 0xc0, 0x00, 0x11, 0x08, 0x00, 0xf0, 0x02, 0xc0, - 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, - 0x11, 0x01, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, - 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00 -}; - -/* This is the byte marker for the start of SOF0: 0xffc0 marker */ -#define SOF0_START 575 - -#endif /* __SOLO6010_JPEG_H */ diff --git a/drivers/staging/solo6x10/solo6010-offsets.h b/drivers/staging/solo6x10/solo6010-offsets.h deleted file mode 100644 index b176003ff383..000000000000 --- a/drivers/staging/solo6x10/solo6010-offsets.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com - * Copyright (C) 2010 Ben Collins - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef __SOLO6010_OFFSETS_H -#define __SOLO6010_OFFSETS_H - -/* Offsets and sizes of the external address */ -#define SOLO_DISP_EXT_ADDR 0x00000000 -#define SOLO_DISP_EXT_SIZE 0x00480000 - -#define SOLO_DEC2LIVE_EXT_ADDR (SOLO_DISP_EXT_ADDR + SOLO_DISP_EXT_SIZE) -#define SOLO_DEC2LIVE_EXT_SIZE 0x00240000 - -#define SOLO_OSG_EXT_ADDR (SOLO_DEC2LIVE_EXT_ADDR + SOLO_DEC2LIVE_EXT_SIZE) -#define SOLO_OSG_EXT_SIZE 0x00120000 - -#define SOLO_EOSD_EXT_ADDR (SOLO_OSG_EXT_ADDR + SOLO_OSG_EXT_SIZE) -#define SOLO_EOSD_EXT_SIZE 0x00010000 - -#define SOLO_MOTION_EXT_ADDR(__solo) (SOLO_EOSD_EXT_ADDR + \ - (SOLO_EOSD_EXT_SIZE * __solo->nr_chans)) -#define SOLO_MOTION_EXT_SIZE 0x00080000 - -#define SOLO_G723_EXT_ADDR(__solo) \ - (SOLO_MOTION_EXT_ADDR(__solo) + SOLO_MOTION_EXT_SIZE) -#define SOLO_G723_EXT_SIZE 0x00010000 - -#define SOLO_CAP_EXT_ADDR(__solo) \ - (SOLO_G723_EXT_ADDR(__solo) + SOLO_G723_EXT_SIZE) -#define SOLO_CAP_EXT_MAX_PAGE (18 + 15) -#define SOLO_CAP_EXT_SIZE (SOLO_CAP_EXT_MAX_PAGE * 65536) - -/* This +1 is very important -- Why?! -- BenC */ -#define SOLO_EREF_EXT_ADDR(__solo) \ - (SOLO_CAP_EXT_ADDR(__solo) + \ - (SOLO_CAP_EXT_SIZE * (__solo->nr_chans + 1))) -#define SOLO_EREF_EXT_SIZE 0x00140000 - -#define SOLO_MP4E_EXT_ADDR(__solo) \ - (SOLO_EREF_EXT_ADDR(__solo) + \ - (SOLO_EREF_EXT_SIZE * __solo->nr_chans)) -#define SOLO_MP4E_EXT_SIZE(__solo) (0x00080000 * __solo->nr_chans) - -#define SOLO_DREF_EXT_ADDR(__solo) \ - (SOLO_MP4E_EXT_ADDR(__solo) + SOLO_MP4E_EXT_SIZE(__solo)) -#define SOLO_DREF_EXT_SIZE 0x00140000 - -#define SOLO_MP4D_EXT_ADDR(__solo) \ - (SOLO_DREF_EXT_ADDR(__solo) + \ - (SOLO_DREF_EXT_SIZE * __solo->nr_chans)) -#define SOLO_MP4D_EXT_SIZE 0x00080000 - -#define SOLO_JPEG_EXT_ADDR(__solo) \ - (SOLO_MP4D_EXT_ADDR(__solo) + \ - (SOLO_MP4D_EXT_SIZE * __solo->nr_chans)) -#define SOLO_JPEG_EXT_SIZE(__solo) (0x00080000 * __solo->nr_chans) - -#endif /* __SOLO6010_OFFSETS_H */ diff --git a/drivers/staging/solo6x10/solo6010-osd-font.h b/drivers/staging/solo6x10/solo6010-osd-font.h deleted file mode 100644 index d72efbb3bb3d..000000000000 --- a/drivers/staging/solo6x10/solo6010-osd-font.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com - * Copyright (C) 2010 Ben Collins - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef __SOLO6010_OSD_FONT_H -#define __SOLO6010_OSD_FONT_H - -static const unsigned int solo_osd_font[] = { - 0x00000000, 0x0000c0c8, 0xccfefe0c, 0x08000000, - 0x00000000, 0x10103838, 0x7c7cfefe, 0x00000000, /* 0 */ - 0x00000000, 0xfefe7c7c, 0x38381010, 0x10000000, - 0x00000000, 0x7c82fefe, 0xfefefe7c, 0x00000000, - 0x00000000, 0x00001038, 0x10000000, 0x00000000, - 0x00000000, 0x0010387c, 0xfe7c3810, 0x00000000, - 0x00000000, 0x00384444, 0x44380000, 0x00000000, - 0x00000000, 0x38448282, 0x82443800, 0x00000000, - 0x00000000, 0x007c7c7c, 0x7c7c0000, 0x00000000, - 0x00000000, 0x6c6c6c6c, 0x6c6c6c6c, 0x00000000, - 0x00000000, 0x061e7efe, 0xfe7e1e06, 0x00000000, - 0x00000000, 0xc0f0fcfe, 0xfefcf0c0, 0x00000000, - 0x00000000, 0xc6cedefe, 0xfedecec6, 0x00000000, - 0x00000000, 0xc6e6f6fe, 0xfef6e6c6, 0x00000000, - 0x00000000, 0x12367efe, 0xfe7e3612, 0x00000000, - 0x00000000, 0x90d8fcfe, 0xfefcd890, 0x00000000, - 0x00000038, 0x7cc692ba, 0x92c67c38, 0x00000000, - 0x00000038, 0x7cc6aa92, 0xaac67c38, 0x00000000, - 0x00000038, 0x7830107c, 0xbaa8680c, 0x00000000, - 0x00000038, 0x3c18127c, 0xb8382c60, 0x00000000, - 0x00000044, 0xaa6c8254, 0x38eec67c, 0x00000000, - 0x00000082, 0x44288244, 0x38c6827c, 0x00000000, - 0x00000038, 0x444444fe, 0xfeeec6fe, 0x00000000, - 0x00000018, 0x78187818, 0x3c7e7e3c, 0x00000000, - 0x00000000, 0x3854929a, 0x82443800, 0x00000000, - 0x00000000, 0x00c0c8cc, 0xfefe0c08, 0x00000000, - 0x0000e0a0, 0xe040e00e, 0x8a0ea40e, 0x00000000, - 0x0000e0a0, 0xe040e00e, 0x0a8e440e, 0x00000000, - 0x0000007c, 0x82829292, 0x929282fe, 0x00000000, - 0x000000f8, 0xfc046494, 0x946404fc, 0x00000000, - 0x0000003f, 0x7f404c52, 0x524c407f, 0x00000000, - 0x0000007c, 0x82ba82ba, 0x82ba82fe, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x183c3c3c, 0x18180018, 0x18000000, /* 32 ! */ - 0x00000066, 0x66240000, 0x00000000, 0x00000000, - 0x00000000, 0x6c6cfe6c, 0x6c6cfe6c, 0x6c000000, /* 34 " # */ - 0x00001010, 0x7cd6d616, 0x7cd0d6d6, 0x7c101000, - 0x00000000, 0x0086c660, 0x30180cc6, 0xc2000000, /* 36 $ % */ - 0x00000000, 0x386c6c38, 0xdc766666, 0xdc000000, - 0x0000000c, 0x0c0c0600, 0x00000000, 0x00000000, /* 38 & ' */ - 0x00000000, 0x30180c0c, 0x0c0c0c18, 0x30000000, - 0x00000000, 0x0c183030, 0x30303018, 0x0c000000, /* 40 ( ) */ - 0x00000000, 0x0000663c, 0xff3c6600, 0x00000000, - 0x00000000, 0x00001818, 0x7e181800, 0x00000000, /* 42 * + */ - 0x00000000, 0x00000000, 0x00000e0e, 0x0c060000, - 0x00000000, 0x00000000, 0x7e000000, 0x00000000, /* 44 , - */ - 0x00000000, 0x00000000, 0x00000006, 0x06000000, - 0x00000000, 0x80c06030, 0x180c0602, 0x00000000, /* 46 . / */ - 0x0000007c, 0xc6e6f6de, 0xcec6c67c, 0x00000000, - 0x00000030, 0x383c3030, 0x303030fc, 0x00000000, /* 48 0 1 */ - 0x0000007c, 0xc6c06030, 0x180cc6fe, 0x00000000, - 0x0000007c, 0xc6c0c07c, 0xc0c0c67c, 0x00000000, /* 50 2 3 */ - 0x00000060, 0x70786c66, 0xfe6060f0, 0x00000000, - 0x000000fe, 0x0606067e, 0xc0c0c67c, 0x00000000, /* 52 4 5 */ - 0x00000038, 0x0c06067e, 0xc6c6c67c, 0x00000000, - 0x000000fe, 0xc6c06030, 0x18181818, 0x00000000, /* 54 6 7 */ - 0x0000007c, 0xc6c6c67c, 0xc6c6c67c, 0x00000000, - 0x0000007c, 0xc6c6c6fc, 0xc0c06038, 0x00000000, /* 56 8 9 */ - 0x00000000, 0x18180000, 0x00181800, 0x00000000, - 0x00000000, 0x18180000, 0x0018180c, 0x00000000, /* 58 : ; */ - 0x00000060, 0x30180c06, 0x0c183060, 0x00000000, - 0x00000000, 0x007e0000, 0x007e0000, 0x00000000, - 0x00000006, 0x0c183060, 0x30180c06, 0x00000000, - 0x0000007c, 0xc6c66030, 0x30003030, 0x00000000, - 0x0000007c, 0xc6f6d6d6, 0x7606067c, 0x00000000, - 0x00000010, 0x386cc6c6, 0xfec6c6c6, 0x00000000, /* 64 @ A */ - 0x0000007e, 0xc6c6c67e, 0xc6c6c67e, 0x00000000, - 0x00000078, 0xcc060606, 0x0606cc78, 0x00000000, /* 66 */ - 0x0000003e, 0x66c6c6c6, 0xc6c6663e, 0x00000000, - 0x000000fe, 0x0606063e, 0x060606fe, 0x00000000, /* 68 */ - 0x000000fe, 0x0606063e, 0x06060606, 0x00000000, - 0x00000078, 0xcc060606, 0xf6c6ccb8, 0x00000000, /* 70 */ - 0x000000c6, 0xc6c6c6fe, 0xc6c6c6c6, 0x00000000, - 0x0000003c, 0x18181818, 0x1818183c, 0x00000000, /* 72 */ - 0x00000060, 0x60606060, 0x6066663c, 0x00000000, - 0x000000c6, 0xc666361e, 0x3666c6c6, 0x00000000, /* 74 */ - 0x00000006, 0x06060606, 0x060606fe, 0x00000000, - 0x000000c6, 0xeefed6c6, 0xc6c6c6c6, 0x00000000, /* 76 */ - 0x000000c6, 0xcedefef6, 0xe6c6c6c6, 0x00000000, - 0x00000038, 0x6cc6c6c6, 0xc6c66c38, 0x00000000, /* 78 */ - 0x0000007e, 0xc6c6c67e, 0x06060606, 0x00000000, - 0x00000038, 0x6cc6c6c6, 0xc6d67c38, 0x60000000, /* 80 */ - 0x0000007e, 0xc6c6c67e, 0x66c6c6c6, 0x00000000, - 0x0000007c, 0xc6c60c38, 0x60c6c67c, 0x00000000, /* 82 */ - 0x0000007e, 0x18181818, 0x18181818, 0x00000000, - 0x000000c6, 0xc6c6c6c6, 0xc6c6c67c, 0x00000000, /* 84 */ - 0x000000c6, 0xc6c6c6c6, 0xc66c3810, 0x00000000, - 0x000000c6, 0xc6c6c6c6, 0xd6d6fe6c, 0x00000000, /* 86 */ - 0x000000c6, 0xc6c66c38, 0x6cc6c6c6, 0x00000000, - 0x00000066, 0x66666666, 0x3c181818, 0x00000000, /* 88 */ - 0x000000fe, 0xc0603018, 0x0c0606fe, 0x00000000, - 0x0000003c, 0x0c0c0c0c, 0x0c0c0c3c, 0x00000000, /* 90 */ - 0x00000002, 0x060c1830, 0x60c08000, 0x00000000, - 0x0000003c, 0x30303030, 0x3030303c, 0x00000000, /* 92 */ - 0x00001038, 0x6cc60000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00fe0000, - 0x00001818, 0x30000000, 0x00000000, 0x00000000, - 0x00000000, 0x00003c60, 0x7c66667c, 0x00000000, - 0x0000000c, 0x0c0c7ccc, 0xcccccc7c, 0x00000000, - 0x00000000, 0x00007cc6, 0x0606c67c, 0x00000000, - 0x00000060, 0x60607c66, 0x6666667c, 0x00000000, - 0x00000000, 0x00007cc6, 0xfe06c67c, 0x00000000, - 0x00000078, 0x0c0c0c3e, 0x0c0c0c0c, 0x00000000, - 0x00000000, 0x00007c66, 0x6666667c, 0x60603e00, - 0x0000000c, 0x0c0c7ccc, 0xcccccccc, 0x00000000, - 0x00000030, 0x30003830, 0x30303078, 0x00000000, - 0x00000030, 0x30003c30, 0x30303030, 0x30301f00, - 0x0000000c, 0x0c0ccc6c, 0x3c6ccccc, 0x00000000, - 0x00000030, 0x30303030, 0x30303030, 0x00000000, - 0x00000000, 0x000066fe, 0xd6d6d6d6, 0x00000000, - 0x00000000, 0x000078cc, 0xcccccccc, 0x00000000, - 0x00000000, 0x00007cc6, 0xc6c6c67c, 0x00000000, - 0x00000000, 0x00007ccc, 0xcccccc7c, 0x0c0c0c00, - 0x00000000, 0x00007c66, 0x6666667c, 0x60606000, - 0x00000000, 0x000076dc, 0x0c0c0c0c, 0x00000000, - 0x00000000, 0x00007cc6, 0x1c70c67c, 0x00000000, - 0x00000000, 0x1818fe18, 0x18181870, 0x00000000, - 0x00000000, 0x00006666, 0x6666663c, 0x00000000, - 0x00000000, 0x0000c6c6, 0xc66c3810, 0x00000000, - 0x00000000, 0x0000c6d6, 0xd6d6fe6c, 0x00000000, - 0x00000000, 0x0000c66c, 0x38386cc6, 0x00000000, - 0x00000000, 0x00006666, 0x6666667c, 0x60603e00, - 0x00000000, 0x0000fe60, 0x30180cfe, 0x00000000, - 0x00000070, 0x1818180e, 0x18181870, 0x00000000, - 0x00000018, 0x18181800, 0x18181818, 0x00000000, - 0x0000000e, 0x18181870, 0x1818180e, 0x00000000, - 0x000000dc, 0x76000000, 0x00000000, 0x00000000, - 0x00000000, 0x0010386c, 0xc6c6fe00, 0x00000000 -}; - -#endif /* __SOLO6010_OSD_FONT_H */ diff --git a/drivers/staging/solo6x10/solo6010-p2m.c b/drivers/staging/solo6x10/solo6010-p2m.c deleted file mode 100644 index 90de96348db8..000000000000 --- a/drivers/staging/solo6x10/solo6010-p2m.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com - * Copyright (C) 2010 Ben Collins - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include - -#include "solo6010.h" - -/* #define SOLO_TEST_P2M */ - -int solo_p2m_dma(struct solo6010_dev *solo_dev, u8 id, int wr, - void *sys_addr, u32 ext_addr, u32 size) -{ - dma_addr_t dma_addr; - int ret; - - WARN_ON(!size); - BUG_ON(id >= SOLO_NR_P2M); - - if (!size) - return -EINVAL; - - dma_addr = pci_map_single(solo_dev->pdev, sys_addr, size, - wr ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); - - ret = solo_p2m_dma_t(solo_dev, id, wr, dma_addr, ext_addr, size); - - pci_unmap_single(solo_dev->pdev, dma_addr, size, - wr ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); - - return ret; -} - -int solo_p2m_dma_t(struct solo6010_dev *solo_dev, u8 id, int wr, - dma_addr_t dma_addr, u32 ext_addr, u32 size) -{ - struct p2m_desc *desc = kzalloc(sizeof(*desc) * 2, GFP_DMA); - int ret; - - if (desc == NULL) - return -ENOMEM; - - solo_p2m_push_desc(&desc[1], wr, dma_addr, ext_addr, size, 0, 0); - ret = solo_p2m_dma_desc(solo_dev, id, desc, 2); - kfree(desc); - - return ret; -} - -void solo_p2m_push_desc(struct p2m_desc *desc, int wr, dma_addr_t dma_addr, - u32 ext_addr, u32 size, int repeat, u32 ext_size) -{ - desc->ta = cpu_to_le32(dma_addr); - desc->fa = cpu_to_le32(ext_addr); - - desc->ext = cpu_to_le32(SOLO_P2M_COPY_SIZE(size >> 2)); - desc->ctrl = cpu_to_le32(SOLO_P2M_BURST_SIZE(SOLO_P2M_BURST_256) | - (wr ? SOLO_P2M_WRITE : 0) | SOLO_P2M_TRANS_ON); - - /* Ext size only matters when we're repeating */ - if (repeat) { - desc->ext |= cpu_to_le32(SOLO_P2M_EXT_INC(ext_size >> 2)); - desc->ctrl |= cpu_to_le32(SOLO_P2M_PCI_INC(size >> 2) | - SOLO_P2M_REPEAT(repeat)); - } -} - -int solo_p2m_dma_desc(struct solo6010_dev *solo_dev, u8 id, - struct p2m_desc *desc, int desc_count) -{ - struct solo_p2m_dev *p2m_dev; - unsigned int timeout; - int ret = 0; - u32 config = 0; - dma_addr_t desc_dma = 0; - - BUG_ON(id >= SOLO_NR_P2M); - BUG_ON(!desc_count || desc_count > SOLO_NR_P2M_DESC); - - p2m_dev = &solo_dev->p2m_dev[id]; - - mutex_lock(&p2m_dev->mutex); - - solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), 0); - - INIT_COMPLETION(p2m_dev->completion); - p2m_dev->error = 0; - - /* Enable the descriptors */ - config = solo_reg_read(solo_dev, SOLO_P2M_CONFIG(id)); - desc_dma = pci_map_single(solo_dev->pdev, desc, - desc_count * sizeof(*desc), - PCI_DMA_TODEVICE); - solo_reg_write(solo_dev, SOLO_P2M_DES_ADR(id), desc_dma); - solo_reg_write(solo_dev, SOLO_P2M_DESC_ID(id), desc_count - 1); - solo_reg_write(solo_dev, SOLO_P2M_CONFIG(id), config | - SOLO_P2M_DESC_MODE); - - /* Should have all descriptors completed from one interrupt */ - timeout = wait_for_completion_timeout(&p2m_dev->completion, HZ); - - solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), 0); - - /* Reset back to non-descriptor mode */ - solo_reg_write(solo_dev, SOLO_P2M_CONFIG(id), config); - solo_reg_write(solo_dev, SOLO_P2M_DESC_ID(id), 0); - solo_reg_write(solo_dev, SOLO_P2M_DES_ADR(id), 0); - pci_unmap_single(solo_dev->pdev, desc_dma, - desc_count * sizeof(*desc), - PCI_DMA_TODEVICE); - - if (p2m_dev->error) - ret = -EIO; - else if (timeout == 0) - ret = -EAGAIN; - - mutex_unlock(&p2m_dev->mutex); - - WARN_ON_ONCE(ret); - - return ret; -} - -int solo_p2m_dma_sg(struct solo6010_dev *solo_dev, u8 id, - struct p2m_desc *pdesc, int wr, - struct scatterlist *sg, u32 sg_off, - u32 ext_addr, u32 size) -{ - int i; - int idx; - - BUG_ON(id >= SOLO_NR_P2M); - - if (WARN_ON_ONCE(!size)) - return -EINVAL; - - memset(pdesc, 0, sizeof(*pdesc)); - - /* Should rewrite this to handle > SOLO_NR_P2M_DESC transactions */ - for (i = 0, idx = 1; idx < SOLO_NR_P2M_DESC && sg && size > 0; - i++, sg = sg_next(sg)) { - struct p2m_desc *desc = &pdesc[idx]; - u32 sg_len = sg_dma_len(sg); - u32 len; - - if (sg_off >= sg_len) { - sg_off -= sg_len; - continue; - } - - sg_len -= sg_off; - len = min(sg_len, size); - - solo_p2m_push_desc(desc, wr, sg_dma_address(sg) + sg_off, - ext_addr, len, 0, 0); - - size -= len; - ext_addr += len; - idx++; - - sg_off = 0; - } - - WARN_ON_ONCE(size || i >= SOLO_NR_P2M_DESC); - - return solo_p2m_dma_desc(solo_dev, id, pdesc, idx); -} - -#ifdef SOLO_TEST_P2M - -#define P2M_TEST_CHAR 0xbe - -static unsigned long long p2m_test(struct solo6010_dev *solo_dev, u8 id, - u32 base, int size) -{ - u8 *wr_buf; - u8 *rd_buf; - int i; - unsigned long long err_cnt = 0; - - wr_buf = kmalloc(size, GFP_KERNEL); - if (!wr_buf) { - printk(SOLO6010_NAME ": Failed to malloc for p2m_test\n"); - return size; - } - - rd_buf = kmalloc(size, GFP_KERNEL); - if (!rd_buf) { - printk(SOLO6010_NAME ": Failed to malloc for p2m_test\n"); - kfree(wr_buf); - return size; - } - - memset(wr_buf, P2M_TEST_CHAR, size); - memset(rd_buf, P2M_TEST_CHAR + 1, size); - - solo_p2m_dma(solo_dev, id, 1, wr_buf, base, size); - solo_p2m_dma(solo_dev, id, 0, rd_buf, base, size); - - for (i = 0; i < size; i++) - if (wr_buf[i] != rd_buf[i]) - err_cnt++; - - kfree(wr_buf); - kfree(rd_buf); - - return err_cnt; -} - -#define TEST_CHUNK_SIZE (8 * 1024) - -static void run_p2m_test(struct solo6010_dev *solo_dev) -{ - unsigned long long errs = 0; - u32 size = SOLO_JPEG_EXT_ADDR(solo_dev) + SOLO_JPEG_EXT_SIZE(solo_dev); - int i, d; - - printk(KERN_WARNING "%s: Testing %u bytes of external ram\n", - SOLO6010_NAME, size); - - for (i = 0; i < size; i += TEST_CHUNK_SIZE) - for (d = 0; d < 4; d++) - errs += p2m_test(solo_dev, d, i, TEST_CHUNK_SIZE); - - printk(KERN_WARNING "%s: Found %llu errors during p2m test\n", - SOLO6010_NAME, errs); - - return; -} -#else -#define run_p2m_test(__solo) do {} while (0) -#endif - -void solo_p2m_isr(struct solo6010_dev *solo_dev, int id) -{ - struct solo_p2m_dev *p2m_dev = &solo_dev->p2m_dev[id]; - - solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_P2M(id)); - - complete(&p2m_dev->completion); -} - -void solo_p2m_error_isr(struct solo6010_dev *solo_dev, u32 status) -{ - struct solo_p2m_dev *p2m_dev; - int i; - - if (!(status & SOLO_PCI_ERR_P2M)) - return; - - for (i = 0; i < SOLO_NR_P2M; i++) { - p2m_dev = &solo_dev->p2m_dev[i]; - p2m_dev->error = 1; - solo_reg_write(solo_dev, SOLO_P2M_CONTROL(i), 0); - complete(&p2m_dev->completion); - } -} - -void solo_p2m_exit(struct solo6010_dev *solo_dev) -{ - int i; - - for (i = 0; i < SOLO_NR_P2M; i++) - solo6010_irq_off(solo_dev, SOLO_IRQ_P2M(i)); -} - -int solo_p2m_init(struct solo6010_dev *solo_dev) -{ - struct solo_p2m_dev *p2m_dev; - int i; - - for (i = 0; i < SOLO_NR_P2M; i++) { - p2m_dev = &solo_dev->p2m_dev[i]; - - mutex_init(&p2m_dev->mutex); - init_completion(&p2m_dev->completion); - - solo_reg_write(solo_dev, SOLO_P2M_CONTROL(i), 0); - solo_reg_write(solo_dev, SOLO_P2M_CONFIG(i), - SOLO_P2M_CSC_16BIT_565 | - SOLO_P2M_DMA_INTERVAL(3) | - SOLO_P2M_DESC_INTR_OPT | - SOLO_P2M_PCI_MASTER_MODE); - solo6010_irq_on(solo_dev, SOLO_IRQ_P2M(i)); - } - - run_p2m_test(solo_dev); - - return 0; -} diff --git a/drivers/staging/solo6x10/solo6010-registers.h b/drivers/staging/solo6x10/solo6010-registers.h deleted file mode 100644 index db291bf0ce99..000000000000 --- a/drivers/staging/solo6x10/solo6010-registers.h +++ /dev/null @@ -1,637 +0,0 @@ -/* - * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com - * Copyright (C) 2010 Ben Collins - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef __SOLO6010_REGISTERS_H -#define __SOLO6010_REGISTERS_H - -#include "solo6010-offsets.h" - -/* Global 6010 system configuration */ -#define SOLO_SYS_CFG 0x0000 -#define SOLO6010_SYS_CFG_FOUT_EN 0x00000001 /* 6010 only */ -#define SOLO6010_SYS_CFG_PLL_BYPASS 0x00000002 /* 6010 only */ -#define SOLO6010_SYS_CFG_PLL_PWDN 0x00000004 /* 6010 only */ -#define SOLO6010_SYS_CFG_OUTDIV(__n) (((__n) & 0x003) << 3) /* 6010 only */ -#define SOLO6010_SYS_CFG_FEEDBACKDIV(__n) (((__n) & 0x1ff) << 5) /* 6010 only */ -#define SOLO6010_SYS_CFG_INPUTDIV(__n) (((__n) & 0x01f) << 14) /* 6010 only */ -#define SOLO_SYS_CFG_CLOCK_DIV 0x00080000 -#define SOLO_SYS_CFG_NCLK_DELAY(__n) (((__n) & 0x003) << 24) -#define SOLO_SYS_CFG_PCLK_DELAY(__n) (((__n) & 0x00f) << 26) -#define SOLO_SYS_CFG_SDRAM64BIT 0x40000000 /* 6110: must be set */ -#define SOLO_SYS_CFG_RESET 0x80000000 - -#define SOLO_DMA_CTRL 0x0004 -#define SOLO_DMA_CTRL_REFRESH_CYCLE(n) ((n)<<8) -/* 0=16/32MB, 1=32/64MB, 2=64/128MB, 3=128/256MB */ -#define SOLO_DMA_CTRL_SDRAM_SIZE(n) ((n)<<6) -#define SOLO_DMA_CTRL_SDRAM_CLK_INVERT (1<<5) -#define SOLO_DMA_CTRL_STROBE_SELECT (1<<4) -#define SOLO_DMA_CTRL_READ_DATA_SELECT (1<<3) -#define SOLO_DMA_CTRL_READ_CLK_SELECT (1<<2) -#define SOLO_DMA_CTRL_LATENCY(n) ((n)<<0) -#define SOLO_DMA_CTRL1 0x0008 - -#define SOLO_SYS_VCLK 0x000C -#define SOLO_VCLK_INVERT (1<<22) -/* 0=sys_clk/4, 1=sys_clk/2, 2=clk_in/2 of system input */ -#define SOLO_VCLK_SELECT(n) ((n)<<20) -#define SOLO_VCLK_VIN1415_DELAY(n) ((n)<<14) -#define SOLO_VCLK_VIN1213_DELAY(n) ((n)<<12) -#define SOLO_VCLK_VIN1011_DELAY(n) ((n)<<10) -#define SOLO_VCLK_VIN0809_DELAY(n) ((n)<<8) -#define SOLO_VCLK_VIN0607_DELAY(n) ((n)<<6) -#define SOLO_VCLK_VIN0405_DELAY(n) ((n)<<4) -#define SOLO_VCLK_VIN0203_DELAY(n) ((n)<<2) -#define SOLO_VCLK_VIN0001_DELAY(n) ((n)<<0) - -#define SOLO_IRQ_STAT 0x0010 -#define SOLO_IRQ_ENABLE 0x0014 -#define SOLO_IRQ_P2M(n) (1<<((n)+17)) -#define SOLO_IRQ_GPIO (1<<16) -#define SOLO_IRQ_VIDEO_LOSS (1<<15) -#define SOLO_IRQ_VIDEO_IN (1<<14) -#define SOLO_IRQ_MOTION (1<<13) -#define SOLO_IRQ_ATA_CMD (1<<12) -#define SOLO_IRQ_ATA_DIR (1<<11) -#define SOLO_IRQ_PCI_ERR (1<<10) -#define SOLO_IRQ_PS2_1 (1<<9) -#define SOLO_IRQ_PS2_0 (1<<8) -#define SOLO_IRQ_SPI (1<<7) -#define SOLO_IRQ_IIC (1<<6) -#define SOLO_IRQ_UART(n) (1<<((n) + 4)) -#define SOLO_IRQ_G723 (1<<3) -#define SOLO_IRQ_DECODER (1<<1) -#define SOLO_IRQ_ENCODER (1<<0) - -#define SOLO_CHIP_OPTION 0x001C -#define SOLO_CHIP_ID_MASK 0x00000007 - -#define SOLO6110_PLL_CONFIG 0x0020 -#define SOLO6110_PLL_RANGE_BYPASS (0 << 20) -#define SOLO6110_PLL_RANGE_5_10MHZ (1 << 20) -#define SOLO6110_PLL_RANGE_8_16MHZ (2 << 20) -#define SOLO6110_PLL_RANGE_13_26MHZ (3 << 20) -#define SOLO6110_PLL_RANGE_21_42MHZ (4 << 20) -#define SOLO6110_PLL_RANGE_34_68MHZ (5 << 20) -#define SOLO6110_PLL_RANGE_54_108MHZ (6 << 20) -#define SOLO6110_PLL_RANGE_88_200MHZ (7 << 20) -#define SOLO6110_PLL_DIVR(x) (((x) - 1) << 15) -#define SOLO6110_PLL_DIVQ_EXP(x) ((x) << 12) -#define SOLO6110_PLL_DIVF(x) (((x) - 1) << 4) -#define SOLO6110_PLL_RESET (1 << 3) -#define SOLO6110_PLL_BYPASS (1 << 2) -#define SOLO6110_PLL_FSEN (1 << 1) -#define SOLO6110_PLL_FB (1 << 0) - -#define SOLO_EEPROM_CTRL 0x0060 -#define SOLO_EEPROM_ACCESS_EN (1<<7) -#define SOLO_EEPROM_CS (1<<3) -#define SOLO_EEPROM_CLK (1<<2) -#define SOLO_EEPROM_DO (1<<1) -#define SOLO_EEPROM_DI (1<<0) -#define SOLO_EEPROM_ENABLE (EEPROM_ACCESS_EN | EEPROM_CS) - -#define SOLO_PCI_ERR 0x0070 -#define SOLO_PCI_ERR_FATAL 0x00000001 -#define SOLO_PCI_ERR_PARITY 0x00000002 -#define SOLO_PCI_ERR_TARGET 0x00000004 -#define SOLO_PCI_ERR_TIMEOUT 0x00000008 -#define SOLO_PCI_ERR_P2M 0x00000010 -#define SOLO_PCI_ERR_ATA 0x00000020 -#define SOLO_PCI_ERR_P2M_DESC 0x00000040 -#define SOLO_PCI_ERR_FSM0(__s) (((__s) >> 16) & 0x0f) -#define SOLO_PCI_ERR_FSM1(__s) (((__s) >> 20) & 0x0f) -#define SOLO_PCI_ERR_FSM2(__s) (((__s) >> 24) & 0x1f) - -#define SOLO_P2M_BASE 0x0080 - -#define SOLO_P2M_CONFIG(n) (0x0080 + ((n)*0x20)) -#define SOLO_P2M_DMA_INTERVAL(n) ((n)<<6)/* N*32 clocks */ -#define SOLO_P2M_CSC_BYTE_REORDER (1<<5) /* BGR -> RGB */ -/* 0:r=[14:10] g=[9:5] b=[4:0], 1:r=[15:11] g=[10:5] b=[4:0] */ -#define SOLO_P2M_CSC_16BIT_565 (1<<4) -#define SOLO_P2M_UV_SWAP (1<<3) -#define SOLO_P2M_PCI_MASTER_MODE (1<<2) -#define SOLO_P2M_DESC_INTR_OPT (1<<1) /* 1:Empty, 0:Each */ -#define SOLO_P2M_DESC_MODE (1<<0) - -#define SOLO_P2M_DES_ADR(n) (0x0084 + ((n)*0x20)) - -#define SOLO_P2M_DESC_ID(n) (0x0088 + ((n)*0x20)) -#define SOLO_P2M_UPDATE_ID(n) ((n)<<0) - -#define SOLO_P2M_STATUS(n) (0x008C + ((n)*0x20)) -#define SOLO_P2M_COMMAND_DONE (1<<8) -#define SOLO_P2M_CURRENT_ID(stat) (0xff & (stat)) - -#define SOLO_P2M_CONTROL(n) (0x0090 + ((n)*0x20)) -#define SOLO_P2M_PCI_INC(n) ((n)<<20) -#define SOLO_P2M_REPEAT(n) ((n)<<10) -/* 0:512, 1:256, 2:128, 3:64, 4:32, 5:128(2page) */ -#define SOLO_P2M_BURST_SIZE(n) ((n)<<7) -#define SOLO_P2M_BURST_512 0 -#define SOLO_P2M_BURST_256 1 -#define SOLO_P2M_BURST_128 2 -#define SOLO_P2M_BURST_64 3 -#define SOLO_P2M_BURST_32 4 -#define SOLO_P2M_CSC_16BIT (1<<6) /* 0:24bit, 1:16bit */ -/* 0:Y[0]<-0(OFF), 1:Y[0]<-1(ON), 2:Y[0]<-G[0], 3:Y[0]<-Bit[15] */ -#define SOLO_P2M_ALPHA_MODE(n) ((n)<<4) -#define SOLO_P2M_CSC_ON (1<<3) -#define SOLO_P2M_INTERRUPT_REQ (1<<2) -#define SOLO_P2M_WRITE (1<<1) -#define SOLO_P2M_TRANS_ON (1<<0) - -#define SOLO_P2M_EXT_CFG(n) (0x0094 + ((n)*0x20)) -#define SOLO_P2M_EXT_INC(n) ((n)<<20) -#define SOLO_P2M_COPY_SIZE(n) ((n)<<0) - -#define SOLO_P2M_TAR_ADR(n) (0x0098 + ((n)*0x20)) - -#define SOLO_P2M_EXT_ADR(n) (0x009C + ((n)*0x20)) - -#define SOLO_P2M_BUFFER(i) (0x2000 + ((i)*4)) - -#define SOLO_VI_CH_SWITCH_0 0x0100 -#define SOLO_VI_CH_SWITCH_1 0x0104 -#define SOLO_VI_CH_SWITCH_2 0x0108 - -#define SOLO_VI_CH_ENA 0x010C -#define SOLO_VI_CH_FORMAT 0x0110 -#define SOLO_VI_FD_SEL_MASK(n) ((n)<<16) -#define SOLO_VI_PROG_MASK(n) ((n)<<0) - -#define SOLO_VI_FMT_CFG 0x0114 -#define SOLO_VI_FMT_CHECK_VCOUNT (1<<31) -#define SOLO_VI_FMT_CHECK_HCOUNT (1<<30) -#define SOLO_VI_FMT_TEST_SIGNAL (1<<28) - -#define SOLO_VI_PAGE_SW 0x0118 -#define SOLO_FI_INV_DISP_LIVE(n) ((n)<<8) -#define SOLO_FI_INV_DISP_OUT(n) ((n)<<7) -#define SOLO_DISP_SYNC_FI(n) ((n)<<6) -#define SOLO_PIP_PAGE_ADD(n) ((n)<<3) -#define SOLO_NORMAL_PAGE_ADD(n) ((n)<<0) - -#define SOLO_VI_ACT_I_P 0x011C -#define SOLO_VI_ACT_I_S 0x0120 -#define SOLO_VI_ACT_P 0x0124 -#define SOLO_VI_FI_INVERT (1<<31) -#define SOLO_VI_H_START(n) ((n)<<21) -#define SOLO_VI_V_START(n) ((n)<<11) -#define SOLO_VI_V_STOP(n) ((n)<<0) - -#define SOLO_VI_STATUS0 0x0128 -#define SOLO_VI_STATUS0_PAGE(__n) ((__n) & 0x07) -#define SOLO_VI_STATUS1 0x012C - -/* XXX: Might be better off in kernel level disp.h */ -#define DISP_PAGE(stat) ((stat) & 0x07) - -#define SOLO_VI_PB_CONFIG 0x0130 -#define SOLO_VI_PB_USER_MODE (1<<1) -#define SOLO_VI_PB_PAL (1<<0) -#define SOLO_VI_PB_RANGE_HV 0x0134 -#define SOLO_VI_PB_HSIZE(h) ((h)<<12) -#define SOLO_VI_PB_VSIZE(v) ((v)<<0) -#define SOLO_VI_PB_ACT_H 0x0138 -#define SOLO_VI_PB_HSTART(n) ((n)<<12) -#define SOLO_VI_PB_HSTOP(n) ((n)<<0) -#define SOLO_VI_PB_ACT_V 0x013C -#define SOLO_VI_PB_VSTART(n) ((n)<<12) -#define SOLO_VI_PB_VSTOP(n) ((n)<<0) - -#define SOLO_VI_MOSAIC(ch) (0x0140 + ((ch)*4)) -#define SOLO_VI_MOSAIC_SX(x) ((x)<<24) -#define SOLO_VI_MOSAIC_EX(x) ((x)<<16) -#define SOLO_VI_MOSAIC_SY(x) ((x)<<8) -#define SOLO_VI_MOSAIC_EY(x) ((x)<<0) - -#define SOLO_VI_WIN_CTRL0(ch) (0x0180 + ((ch)*4)) -#define SOLO_VI_WIN_CTRL1(ch) (0x01C0 + ((ch)*4)) - -#define SOLO_VI_WIN_CHANNEL(n) ((n)<<28) - -#define SOLO_VI_WIN_PIP(n) ((n)<<27) -#define SOLO_VI_WIN_SCALE(n) ((n)<<24) - -#define SOLO_VI_WIN_SX(x) ((x)<<12) -#define SOLO_VI_WIN_EX(x) ((x)<<0) - -#define SOLO_VI_WIN_SY(x) ((x)<<12) -#define SOLO_VI_WIN_EY(x) ((x)<<0) - -#define SOLO_VI_WIN_ON(ch) (0x0200 + ((ch)*4)) - -#define SOLO_VI_WIN_SW 0x0240 -#define SOLO_VI_WIN_LIVE_AUTO_MUTE 0x0244 - -#define SOLO_VI_MOT_ADR 0x0260 -#define SOLO_VI_MOTION_EN(mask) ((mask)<<16) -#define SOLO_VI_MOT_CTRL 0x0264 -#define SOLO_VI_MOTION_FRAME_COUNT(n) ((n)<<24) -#define SOLO_VI_MOTION_SAMPLE_LENGTH(n) ((n)<<16) -#define SOLO_VI_MOTION_INTR_START_STOP (1<<15) -#define SOLO_VI_MOTION_FREEZE_DATA (1<<14) -#define SOLO_VI_MOTION_SAMPLE_COUNT(n) ((n)<<0) -#define SOLO_VI_MOT_CLEAR 0x0268 -#define SOLO_VI_MOT_STATUS 0x026C -#define SOLO_VI_MOTION_CNT(n) ((n)<<0) -#define SOLO_VI_MOTION_BORDER 0x0270 -#define SOLO_VI_MOTION_BAR 0x0274 -#define SOLO_VI_MOTION_Y_SET (1<<29) -#define SOLO_VI_MOTION_Y_ADD (1<<28) -#define SOLO_VI_MOTION_CB_SET (1<<27) -#define SOLO_VI_MOTION_CB_ADD (1<<26) -#define SOLO_VI_MOTION_CR_SET (1<<25) -#define SOLO_VI_MOTION_CR_ADD (1<<24) -#define SOLO_VI_MOTION_Y_VALUE(v) ((v)<<16) -#define SOLO_VI_MOTION_CB_VALUE(v) ((v)<<8) -#define SOLO_VI_MOTION_CR_VALUE(v) ((v)<<0) - -#define SOLO_VO_FMT_ENC 0x0300 -#define SOLO_VO_SCAN_MODE_PROGRESSIVE (1<<31) -#define SOLO_VO_FMT_TYPE_PAL (1<<30) -#define SOLO_VO_FMT_TYPE_NTSC 0 -#define SOLO_VO_USER_SET (1<<29) - -#define SOLO_VO_FI_CHANGE (1<<20) -#define SOLO_VO_USER_COLOR_SET_VSYNC (1<<19) -#define SOLO_VO_USER_COLOR_SET_HSYNC (1<<18) -#define SOLO_VO_USER_COLOR_SET_NAV (1<<17) -#define SOLO_VO_USER_COLOR_SET_NAH (1<<16) -#define SOLO_VO_NA_COLOR_Y(Y) ((Y)<<8) -#define SOLO_VO_NA_COLOR_CB(CB) (((CB)/16)<<4) -#define SOLO_VO_NA_COLOR_CR(CR) (((CR)/16)<<0) - -#define SOLO_VO_ACT_H 0x0304 -#define SOLO_VO_H_BLANK(n) ((n)<<22) -#define SOLO_VO_H_START(n) ((n)<<11) -#define SOLO_VO_H_STOP(n) ((n)<<0) - -#define SOLO_VO_ACT_V 0x0308 -#define SOLO_VO_V_BLANK(n) ((n)<<22) -#define SOLO_VO_V_START(n) ((n)<<11) -#define SOLO_VO_V_STOP(n) ((n)<<0) - -#define SOLO_VO_RANGE_HV 0x030C -#define SOLO_VO_SYNC_INVERT (1<<24) -#define SOLO_VO_HSYNC_INVERT (1<<23) -#define SOLO_VO_VSYNC_INVERT (1<<22) -#define SOLO_VO_H_LEN(n) ((n)<<11) -#define SOLO_VO_V_LEN(n) ((n)<<0) - -#define SOLO_VO_DISP_CTRL 0x0310 -#define SOLO_VO_DISP_ON (1<<31) -#define SOLO_VO_DISP_ERASE_COUNT(n) ((n&0xf)<<24) -#define SOLO_VO_DISP_DOUBLE_SCAN (1<<22) -#define SOLO_VO_DISP_SINGLE_PAGE (1<<21) -#define SOLO_VO_DISP_BASE(n) (((n)>>16) & 0xffff) - -#define SOLO_VO_DISP_ERASE 0x0314 -#define SOLO_VO_DISP_ERASE_ON (1<<0) - -#define SOLO_VO_ZOOM_CTRL 0x0318 -#define SOLO_VO_ZOOM_VER_ON (1<<24) -#define SOLO_VO_ZOOM_HOR_ON (1<<23) -#define SOLO_VO_ZOOM_V_COMP (1<<22) -#define SOLO_VO_ZOOM_SX(h) (((h)/2)<<11) -#define SOLO_VO_ZOOM_SY(v) (((v)/2)<<0) - -#define SOLO_VO_FREEZE_CTRL 0x031C -#define SOLO_VO_FREEZE_ON (1<<1) -#define SOLO_VO_FREEZE_INTERPOLATION (1<<0) - -#define SOLO_VO_BKG_COLOR 0x0320 -#define SOLO_BG_Y(y) ((y)<<16) -#define SOLO_BG_U(u) ((u)<<8) -#define SOLO_BG_V(v) ((v)<<0) - -#define SOLO_VO_DEINTERLACE 0x0324 -#define SOLO_VO_DEINTERLACE_THRESHOLD(n) ((n)<<8) -#define SOLO_VO_DEINTERLACE_EDGE_VALUE(n) ((n)<<0) - -#define SOLO_VO_BORDER_LINE_COLOR 0x0330 -#define SOLO_VO_BORDER_FILL_COLOR 0x0334 -#define SOLO_VO_BORDER_LINE_MASK 0x0338 -#define SOLO_VO_BORDER_FILL_MASK 0x033c - -#define SOLO_VO_BORDER_X(n) (0x0340+((n)*4)) -#define SOLO_VO_BORDER_Y(n) (0x0354+((n)*4)) - -#define SOLO_VO_CELL_EXT_SET 0x0368 -#define SOLO_VO_CELL_EXT_START 0x036c -#define SOLO_VO_CELL_EXT_STOP 0x0370 - -#define SOLO_VO_CELL_EXT_SET2 0x0374 -#define SOLO_VO_CELL_EXT_START2 0x0378 -#define SOLO_VO_CELL_EXT_STOP2 0x037c - -#define SOLO_VO_RECTANGLE_CTRL(n) (0x0368+((n)*12)) -#define SOLO_VO_RECTANGLE_START(n) (0x036c+((n)*12)) -#define SOLO_VO_RECTANGLE_STOP(n) (0x0370+((n)*12)) - -#define SOLO_VO_CURSOR_POS (0x0380) -#define SOLO_VO_CURSOR_CLR (0x0384) -#define SOLO_VO_CURSOR_CLR2 (0x0388) -#define SOLO_VO_CURSOR_MASK(id) (0x0390+((id)*4)) - -#define SOLO_VO_EXPANSION(id) (0x0250+((id)*4)) - -#define SOLO_OSG_CONFIG 0x03E0 -#define SOLO_VO_OSG_ON (1<<31) -#define SOLO_VO_OSG_COLOR_MUTE (1<<28) -#define SOLO_VO_OSG_ALPHA_RATE(n) ((n)<<22) -#define SOLO_VO_OSG_ALPHA_BG_RATE(n) ((n)<<16) -#define SOLO_VO_OSG_BASE(offset) (((offset)>>16)&0xffff) - -#define SOLO_OSG_ERASE 0x03E4 -#define SOLO_OSG_ERASE_ON (0x80) -#define SOLO_OSG_ERASE_OFF (0x00) - -#define SOLO_VO_OSG_BLINK 0x03E8 -#define SOLO_VO_OSG_BLINK_ON (1<<1) -#define SOLO_VO_OSG_BLINK_INTREVAL18 (1<<0) - -#define SOLO_CAP_BASE 0x0400 -#define SOLO_CAP_MAX_PAGE(n) ((n)<<16) -#define SOLO_CAP_BASE_ADDR(n) ((n)<<0) -#define SOLO_CAP_BTW 0x0404 -#define SOLO_CAP_PROG_BANDWIDTH(n) ((n)<<8) -#define SOLO_CAP_MAX_BANDWIDTH(n) ((n)<<0) - -#define SOLO_DIM_SCALE1 0x0408 -#define SOLO_DIM_SCALE2 0x040C -#define SOLO_DIM_SCALE3 0x0410 -#define SOLO_DIM_SCALE4 0x0414 -#define SOLO_DIM_SCALE5 0x0418 -#define SOLO_DIM_V_MB_NUM_FRAME(n) ((n)<<16) -#define SOLO_DIM_V_MB_NUM_FIELD(n) ((n)<<8) -#define SOLO_DIM_H_MB_NUM(n) ((n)<<0) - -#define SOLO_DIM_PROG 0x041C -#define SOLO_CAP_STATUS 0x0420 - -#define SOLO_CAP_CH_SCALE(ch) (0x0440+((ch)*4)) -#define SOLO_CAP_CH_COMP_ENA_E(ch) (0x0480+((ch)*4)) -#define SOLO_CAP_CH_INTV(ch) (0x04C0+((ch)*4)) -#define SOLO_CAP_CH_INTV_E(ch) (0x0500+((ch)*4)) - - -#define SOLO_VE_CFG0 0x0610 -#define SOLO_VE_TWO_PAGE_MODE (1<<31) -#define SOLO_VE_INTR_CTRL(n) ((n)<<24) -#define SOLO_VE_BLOCK_SIZE(n) ((n)<<16) -#define SOLO_VE_BLOCK_BASE(n) ((n)<<0) - -#define SOLO_VE_CFG1 0x0614 -#define SOLO6110_VE_MPEG_SIZE_H(n) ((n)<<28) /* 6110 only */ -#define SOLO6010_VE_BYTE_ALIGN(n) ((n)<<24) /* 6010 only */ -#define SOLO6110_VE_JPEG_SIZE_H(n) ((n)<<20) /* 6110 only */ -#define SOLO_VE_INSERT_INDEX (1<<18) -#define SOLO_VE_MOTION_MODE(n) ((n)<<16) -#define SOLO_VE_MOTION_BASE(n) ((n)<<0) - -#define SOLO_VE_WMRK_POLY 0x061C -#define SOLO_VE_VMRK_INIT_KEY 0x0620 -#define SOLO_VE_WMRK_STRL 0x0624 -#define SOLO_VE_ENCRYP_POLY 0x0628 -#define SOLO_VE_ENCRYP_INIT 0x062C -#define SOLO_VE_ATTR 0x0630 -#define SOLO_VE_LITTLE_ENDIAN (1<<31) -#define SOLO_COMP_ATTR_RN (1<<30) -#define SOLO_COMP_ATTR_FCODE(n) ((n)<<27) -#define SOLO_COMP_TIME_INC(n) ((n)<<25) -#define SOLO_COMP_TIME_WIDTH(n) ((n)<<21) -#define SOLO_DCT_INTERVAL(n) ((n)<<16) - -#define SOLO_VE_STATE(n) (0x0640+((n)*4)) - -#define SOLO_VE_JPEG_QP_TBL 0x0670 -#define SOLO_VE_JPEG_QP_CH_L 0x0674 -#define SOLO_VE_JPEG_QP_CH_H 0x0678 -#define SOLO_VE_JPEG_CFG 0x067C -#define SOLO_VE_JPEG_CTRL 0x0680 - -#define SOLO_VE_OSD_CH 0x0690 -#define SOLO_VE_OSD_BASE 0x0694 -#define SOLO_VE_OSD_CLR 0x0698 -#define SOLO_VE_OSD_OPT 0x069C - -#define SOLO_VE_CH_INTL(ch) (0x0700+((ch)*4)) -#define SOLO6010_VE_CH_MOT(ch) (0x0740+((ch)*4)) /* 6010 only */ -#define SOLO_VE_CH_QP(ch) (0x0780+((ch)*4)) -#define SOLO_VE_CH_QP_E(ch) (0x07C0+((ch)*4)) -#define SOLO_VE_CH_GOP(ch) (0x0800+((ch)*4)) -#define SOLO_VE_CH_GOP_E(ch) (0x0840+((ch)*4)) -#define SOLO_VE_CH_REF_BASE(ch) (0x0880+((ch)*4)) -#define SOLO_VE_CH_REF_BASE_E(ch) (0x08C0+((ch)*4)) - -#define SOLO_VE_MPEG4_QUE(n) (0x0A00+((n)*8)) -#define SOLO_VE_JPEG_QUE(n) (0x0A04+((n)*8)) - -#define SOLO_VD_CFG0 0x0900 -#define SOLO6010_VD_CFG_NO_WRITE_NO_WINDOW (1<<24) /* 6010 only */ -#define SOLO_VD_CFG_BUSY_WIAT_CODE (1<<23) -#define SOLO_VD_CFG_BUSY_WIAT_REF (1<<22) -#define SOLO_VD_CFG_BUSY_WIAT_RES (1<<21) -#define SOLO_VD_CFG_BUSY_WIAT_MS (1<<20) -#define SOLO_VD_CFG_SINGLE_MODE (1<<18) -#define SOLO_VD_CFG_SCAL_MANUAL (1<<17) -#define SOLO_VD_CFG_USER_PAGE_CTRL (1<<16) -#define SOLO_VD_CFG_LITTLE_ENDIAN (1<<15) -#define SOLO_VD_CFG_START_FI (1<<14) -#define SOLO_VD_CFG_ERR_LOCK (1<<13) -#define SOLO_VD_CFG_ERR_INT_ENA (1<<12) -#define SOLO_VD_CFG_TIME_WIDTH(n) ((n)<<8) -#define SOLO_VD_CFG_DCT_INTERVAL(n) ((n)<<0) - -#define SOLO_VD_CFG1 0x0904 - -#define SOLO_VD_DEINTERLACE 0x0908 -#define SOLO_VD_DEINTERLACE_THRESHOLD(n) ((n)<<8) -#define SOLO_VD_DEINTERLACE_EDGE_VALUE(n) ((n)<<0) - -#define SOLO_VD_CODE_ADR 0x090C - -#define SOLO_VD_CTRL 0x0910 -#define SOLO_VD_OPER_ON (1<<31) -#define SOLO_VD_MAX_ITEM(n) ((n)<<0) - -#define SOLO_VD_STATUS0 0x0920 -#define SOLO_VD_STATUS0_INTR_ACK (1<<22) -#define SOLO_VD_STATUS0_INTR_EMPTY (1<<21) -#define SOLO_VD_STATUS0_INTR_ERR (1<<20) - -#define SOLO_VD_STATUS1 0x0924 - -#define SOLO_VD_IDX0 0x0930 -#define SOLO_VD_IDX_INTERLACE (1<<30) -#define SOLO_VD_IDX_CHANNEL(n) ((n)<<24) -#define SOLO_VD_IDX_SIZE(n) ((n)<<0) - -#define SOLO_VD_IDX1 0x0934 -#define SOLO_VD_IDX_SRC_SCALE(n) ((n)<<28) -#define SOLO_VD_IDX_WINDOW(n) ((n)<<24) -#define SOLO_VD_IDX_DEINTERLACE (1<<16) -#define SOLO_VD_IDX_H_BLOCK(n) ((n)<<8) -#define SOLO_VD_IDX_V_BLOCK(n) ((n)<<0) - -#define SOLO_VD_IDX2 0x0938 -#define SOLO_VD_IDX_REF_BASE_SIDE (1<<31) -#define SOLO_VD_IDX_REF_BASE(n) (((n)>>16)&0xffff) - -#define SOLO_VD_IDX3 0x093C -#define SOLO_VD_IDX_DISP_SCALE(n) ((n)<<28) -#define SOLO_VD_IDX_INTERLACE_WR (1<<27) -#define SOLO_VD_IDX_INTERPOL (1<<26) -#define SOLO_VD_IDX_HOR2X (1<<25) -#define SOLO_VD_IDX_OFFSET_X(n) ((n)<<12) -#define SOLO_VD_IDX_OFFSET_Y(n) ((n)<<0) - -#define SOLO_VD_IDX4 0x0940 -#define SOLO_VD_IDX_DEC_WR_PAGE(n) ((n)<<8) -#define SOLO_VD_IDX_DISP_RD_PAGE(n) ((n)<<0) - -#define SOLO_VD_WR_PAGE(n) (0x03F0 + ((n) * 4)) - - -#define SOLO_GPIO_CONFIG_0 0x0B00 -#define SOLO_GPIO_CONFIG_1 0x0B04 -#define SOLO_GPIO_DATA_OUT 0x0B08 -#define SOLO_GPIO_DATA_IN 0x0B0C -#define SOLO_GPIO_INT_ACK_STA 0x0B10 -#define SOLO_GPIO_INT_ENA 0x0B14 -#define SOLO_GPIO_INT_CFG_0 0x0B18 -#define SOLO_GPIO_INT_CFG_1 0x0B1C - - -#define SOLO_IIC_CFG 0x0B20 -#define SOLO_IIC_ENABLE (1<<8) -#define SOLO_IIC_PRESCALE(n) ((n)<<0) - -#define SOLO_IIC_CTRL 0x0B24 -#define SOLO_IIC_AUTO_CLEAR (1<<20) -#define SOLO_IIC_STATE_RX_ACK (1<<19) -#define SOLO_IIC_STATE_BUSY (1<<18) -#define SOLO_IIC_STATE_SIG_ERR (1<<17) -#define SOLO_IIC_STATE_TRNS (1<<16) -#define SOLO_IIC_CH_SET(n) ((n)<<5) -#define SOLO_IIC_ACK_EN (1<<4) -#define SOLO_IIC_START (1<<3) -#define SOLO_IIC_STOP (1<<2) -#define SOLO_IIC_READ (1<<1) -#define SOLO_IIC_WRITE (1<<0) - -#define SOLO_IIC_TXD 0x0B28 -#define SOLO_IIC_RXD 0x0B2C - -/* - * UART REGISTER - */ -#define SOLO_UART_CONTROL(n) (0x0BA0 + ((n)*0x20)) -#define SOLO_UART_CLK_DIV(n) ((n)<<24) -#define SOLO_MODEM_CTRL_EN (1<<20) -#define SOLO_PARITY_ERROR_DROP (1<<18) -#define SOLO_IRQ_ERR_EN (1<<17) -#define SOLO_IRQ_RX_EN (1<<16) -#define SOLO_IRQ_TX_EN (1<<15) -#define SOLO_RX_EN (1<<14) -#define SOLO_TX_EN (1<<13) -#define SOLO_UART_HALF_DUPLEX (1<<12) -#define SOLO_UART_LOOPBACK (1<<11) - -#define SOLO_BAUDRATE_230400 ((0<<9)|(0<<6)) -#define SOLO_BAUDRATE_115200 ((0<<9)|(1<<6)) -#define SOLO_BAUDRATE_57600 ((0<<9)|(2<<6)) -#define SOLO_BAUDRATE_38400 ((0<<9)|(3<<6)) -#define SOLO_BAUDRATE_19200 ((0<<9)|(4<<6)) -#define SOLO_BAUDRATE_9600 ((0<<9)|(5<<6)) -#define SOLO_BAUDRATE_4800 ((0<<9)|(6<<6)) -#define SOLO_BAUDRATE_2400 ((1<<9)|(6<<6)) -#define SOLO_BAUDRATE_1200 ((2<<9)|(6<<6)) -#define SOLO_BAUDRATE_300 ((3<<9)|(6<<6)) - -#define SOLO_UART_DATA_BIT_8 (3<<4) -#define SOLO_UART_DATA_BIT_7 (2<<4) -#define SOLO_UART_DATA_BIT_6 (1<<4) -#define SOLO_UART_DATA_BIT_5 (0<<4) - -#define SOLO_UART_STOP_BIT_1 (0<<2) -#define SOLO_UART_STOP_BIT_2 (1<<2) - -#define SOLO_UART_PARITY_NONE (0<<0) -#define SOLO_UART_PARITY_EVEN (2<<0) -#define SOLO_UART_PARITY_ODD (3<<0) - -#define SOLO_UART_STATUS(n) (0x0BA4 + ((n)*0x20)) -#define SOLO_UART_CTS (1<<15) -#define SOLO_UART_RX_BUSY (1<<14) -#define SOLO_UART_OVERRUN (1<<13) -#define SOLO_UART_FRAME_ERR (1<<12) -#define SOLO_UART_PARITY_ERR (1<<11) -#define SOLO_UART_TX_BUSY (1<<5) - -#define SOLO_UART_RX_BUFF_CNT(stat) (((stat)>>6) & 0x1f) -#define SOLO_UART_RX_BUFF_SIZE 8 -#define SOLO_UART_TX_BUFF_CNT(stat) (((stat)>>0) & 0x1f) -#define SOLO_UART_TX_BUFF_SIZE 8 - -#define SOLO_UART_TX_DATA(n) (0x0BA8 + ((n)*0x20)) -#define SOLO_UART_TX_DATA_PUSH (1<<8) -#define SOLO_UART_RX_DATA(n) (0x0BAC + ((n)*0x20)) -#define SOLO_UART_RX_DATA_POP (1<<8) - -#define SOLO_TIMER_CLOCK_NUM 0x0be0 -#define SOLO_TIMER_WATCHDOG 0x0be4 -#define SOLO_TIMER_USEC 0x0be8 -#define SOLO_TIMER_SEC 0x0bec - -#define SOLO_AUDIO_CONTROL 0x0D00 -#define SOLO_AUDIO_ENABLE (1<<31) -#define SOLO_AUDIO_MASTER_MODE (1<<30) -#define SOLO_AUDIO_I2S_MODE (1<<29) -#define SOLO_AUDIO_I2S_LR_SWAP (1<<27) -#define SOLO_AUDIO_I2S_8BIT (1<<26) -#define SOLO_AUDIO_I2S_MULTI(n) ((n)<<24) -#define SOLO_AUDIO_MIX_9TO0 (1<<23) -#define SOLO_AUDIO_DEC_9TO0_VOL(n) ((n)<<20) -#define SOLO_AUDIO_MIX_19TO10 (1<<19) -#define SOLO_AUDIO_DEC_19TO10_VOL(n) ((n)<<16) -#define SOLO_AUDIO_MODE(n) ((n)<<0) -#define SOLO_AUDIO_SAMPLE 0x0D04 -#define SOLO_AUDIO_EE_MODE_ON (1<<30) -#define SOLO_AUDIO_EE_ENC_CH(ch) ((ch)<<25) -#define SOLO_AUDIO_BITRATE(n) ((n)<<16) -#define SOLO_AUDIO_CLK_DIV(n) ((n)<<0) -#define SOLO_AUDIO_FDMA_INTR 0x0D08 -#define SOLO_AUDIO_FDMA_INTERVAL(n) ((n)<<19) -#define SOLO_AUDIO_INTR_ORDER(n) ((n)<<16) -#define SOLO_AUDIO_FDMA_BASE(n) ((n)<<0) -#define SOLO_AUDIO_EVOL_0 0x0D0C -#define SOLO_AUDIO_EVOL_1 0x0D10 -#define SOLO_AUDIO_EVOL(ch, value) ((value)<<((ch)%10)) -#define SOLO_AUDIO_STA 0x0D14 - - -#define SOLO_WATCHDOG 0x0BE4 -#define WATCHDOG_STAT(status) (status<<8) -#define WATCHDOG_TIME(sec) (sec&0xff) - -#endif /* __SOLO6010_REGISTERS_H */ diff --git a/drivers/staging/solo6x10/solo6010-tw28.c b/drivers/staging/solo6x10/solo6010-tw28.c deleted file mode 100644 index 905a6ad23a37..000000000000 --- a/drivers/staging/solo6x10/solo6010-tw28.c +++ /dev/null @@ -1,823 +0,0 @@ -/* - * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com - * Copyright (C) 2010 Ben Collins - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include - -#include "solo6010.h" -#include "solo6010-tw28.h" - -/* XXX: Some of these values are masked into an 8-bit regs, and shifted - * around for other 8-bit regs. What are the magic bits in these values? */ -#define DEFAULT_HDELAY_NTSC (32 - 4) -#define DEFAULT_HACTIVE_NTSC (720 + 16) -#define DEFAULT_VDELAY_NTSC (7 - 2) -#define DEFAULT_VACTIVE_NTSC (240 + 4) - -#define DEFAULT_HDELAY_PAL (32 + 4) -#define DEFAULT_HACTIVE_PAL (864-DEFAULT_HDELAY_PAL) -#define DEFAULT_VDELAY_PAL (6) -#define DEFAULT_VACTIVE_PAL (312-DEFAULT_VDELAY_PAL) - -static u8 tbl_tw2864_template[] = { - 0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, /* 0x00 */ - 0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, /* 0x10 */ - 0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, /* 0x20 */ - 0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, /* 0x30 */ - 0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x00, - 0x00, 0x02, 0x00, 0xcc, 0x00, 0x80, 0x44, 0x50, /* 0x80 */ - 0x22, 0x01, 0xd8, 0xbc, 0xb8, 0x44, 0x38, 0x00, - 0x00, 0x78, 0x72, 0x3e, 0x14, 0xa5, 0xe4, 0x05, /* 0x90 */ - 0x00, 0x28, 0x44, 0x44, 0xa0, 0x88, 0x5a, 0x01, - 0x08, 0x08, 0x08, 0x08, 0x1a, 0x1a, 0x1a, 0x1a, /* 0xa0 */ - 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0x44, - 0x44, 0x0a, 0x00, 0xff, 0xef, 0xef, 0xef, 0xef, /* 0xb0 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */ - 0x00, 0x00, 0x55, 0x00, 0xb1, 0xe4, 0x40, 0x00, - 0x77, 0x77, 0x01, 0x13, 0x57, 0x9b, 0xdf, 0x20, /* 0xd0 */ - 0x64, 0xa8, 0xec, 0xd1, 0x0f, 0x11, 0x11, 0x81, - 0x10, 0xe0, 0xbb, 0xbb, 0x00, 0x11, 0x00, 0x00, /* 0xe0 */ - 0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0x11, 0x00, - 0x83, 0xb5, 0x09, 0x78, 0x85, 0x00, 0x01, 0x20, /* 0xf0 */ - 0x64, 0x11, 0x40, 0xaf, 0xff, 0x00, 0x00, 0x00, -}; - -static u8 tbl_tw2865_ntsc_template[] = { - 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, /* 0x00 */ - 0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, /* 0x10 */ - 0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, /* 0x20 */ - 0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0xf0, 0x70, 0x48, 0x80, 0x80, 0x00, 0x02, /* 0x30 */ - 0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x00, 0x90, 0x68, 0x00, 0x38, 0x80, 0x80, /* 0x40 */ - 0x80, 0x80, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x43, - 0x08, 0x00, 0x00, 0x01, 0xf1, 0x03, 0xEF, 0x03, /* 0x70 */ - 0xE9, 0x03, 0xD9, 0x15, 0x15, 0xE4, 0xA3, 0x80, - 0x00, 0x02, 0x00, 0xCC, 0x00, 0x80, 0x44, 0x50, /* 0x80 */ - 0x22, 0x01, 0xD8, 0xBC, 0xB8, 0x44, 0x38, 0x00, - 0x00, 0x78, 0x44, 0x3D, 0x14, 0xA5, 0xE0, 0x05, /* 0x90 */ - 0x00, 0x28, 0x44, 0x44, 0xA0, 0x90, 0x52, 0x13, - 0x08, 0x08, 0x08, 0x08, 0x1A, 0x1A, 0x1B, 0x1A, /* 0xa0 */ - 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0x44, - 0x44, 0x4A, 0x00, 0xFF, 0xEF, 0xEF, 0xEF, 0xEF, /* 0xb0 */ - 0xFF, 0xE7, 0xE9, 0xE9, 0xEB, 0xFF, 0xD6, 0xD8, - 0xD8, 0xD7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */ - 0x00, 0x00, 0x55, 0x00, 0xE4, 0x39, 0x00, 0x80, - 0x77, 0x77, 0x03, 0x20, 0x57, 0x9b, 0xdf, 0x31, /* 0xd0 */ - 0x64, 0xa8, 0xec, 0xd1, 0x0f, 0x11, 0x11, 0x81, - 0x10, 0xC0, 0xAA, 0xAA, 0x00, 0x11, 0x00, 0x00, /* 0xe0 */ - 0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0x11, 0x00, - 0x83, 0xB5, 0x09, 0x78, 0x85, 0x00, 0x01, 0x20, /* 0xf0 */ - 0x64, 0x51, 0x40, 0xaf, 0xFF, 0xF0, 0x00, 0xC0, -}; - -static u8 tbl_tw2865_pal_template[] = { - 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, /* 0x00 */ - 0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f, - 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, /* 0x10 */ - 0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f, - 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, /* 0x20 */ - 0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f, - 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, /* 0x30 */ - 0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f, - 0x00, 0x94, 0x90, 0x48, 0x00, 0x38, 0x7F, 0x80, /* 0x40 */ - 0x80, 0x80, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x43, - 0x08, 0x00, 0x00, 0x01, 0xf1, 0x03, 0xEF, 0x03, /* 0x70 */ - 0xEA, 0x03, 0xD9, 0x15, 0x15, 0xE4, 0xA3, 0x80, - 0x00, 0x02, 0x00, 0xCC, 0x00, 0x80, 0x44, 0x50, /* 0x80 */ - 0x22, 0x01, 0xD8, 0xBC, 0xB8, 0x44, 0x38, 0x00, - 0x00, 0x78, 0x44, 0x3D, 0x14, 0xA5, 0xE0, 0x05, /* 0x90 */ - 0x00, 0x28, 0x44, 0x44, 0xA0, 0x90, 0x52, 0x13, - 0x08, 0x08, 0x08, 0x08, 0x1A, 0x1A, 0x1A, 0x1A, /* 0xa0 */ - 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0x44, - 0x44, 0x4A, 0x00, 0xFF, 0xEF, 0xEF, 0xEF, 0xEF, /* 0xb0 */ - 0xFF, 0xE7, 0xE9, 0xE9, 0xE9, 0xFF, 0xD7, 0xD8, - 0xD9, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */ - 0x00, 0x00, 0x55, 0x00, 0xE4, 0x39, 0x00, 0x80, - 0x77, 0x77, 0x03, 0x20, 0x57, 0x9b, 0xdf, 0x31, /* 0xd0 */ - 0x64, 0xa8, 0xec, 0xd1, 0x0f, 0x11, 0x11, 0x81, - 0x10, 0xC0, 0xAA, 0xAA, 0x00, 0x11, 0x00, 0x00, /* 0xe0 */ - 0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0x11, 0x00, - 0x83, 0xB5, 0x09, 0x00, 0xA0, 0x00, 0x01, 0x20, /* 0xf0 */ - 0x64, 0x51, 0x40, 0xaf, 0xFF, 0xF0, 0x00, 0xC0, -}; - -#define is_tw286x(__solo, __id) (!(__solo->tw2815 & (1 << __id))) - -static u8 tw_readbyte(struct solo6010_dev *solo_dev, int chip_id, u8 tw6x_off, - u8 tw_off) -{ - if (is_tw286x(solo_dev, chip_id)) - return solo_i2c_readbyte(solo_dev, SOLO_I2C_TW, - TW_CHIP_OFFSET_ADDR(chip_id), - tw6x_off); - else - return solo_i2c_readbyte(solo_dev, SOLO_I2C_TW, - TW_CHIP_OFFSET_ADDR(chip_id), - tw_off); -} - -static void tw_writebyte(struct solo6010_dev *solo_dev, int chip_id, - u8 tw6x_off, u8 tw_off, u8 val) -{ - if (is_tw286x(solo_dev, chip_id)) - solo_i2c_writebyte(solo_dev, SOLO_I2C_TW, - TW_CHIP_OFFSET_ADDR(chip_id), - tw6x_off, val); - else - solo_i2c_writebyte(solo_dev, SOLO_I2C_TW, - TW_CHIP_OFFSET_ADDR(chip_id), - tw_off, val); -} - -static void tw_write_and_verify(struct solo6010_dev *solo_dev, u8 addr, u8 off, - u8 val) -{ - int i; - - for (i = 0; i < 5; i++) { - u8 rval = solo_i2c_readbyte(solo_dev, SOLO_I2C_TW, addr, off); - if (rval == val) - return; - - solo_i2c_writebyte(solo_dev, SOLO_I2C_TW, addr, off, val); - msleep_interruptible(1); - } - -/* printk("solo6010/tw28: Error writing register: %02x->%02x [%02x]\n", - addr, off, val); */ -} - -static int tw2865_setup(struct solo6010_dev *solo_dev, u8 dev_addr) -{ - u8 tbl_tw2865_common[256]; - int i; - - if (solo_dev->video_type == SOLO_VO_FMT_TYPE_PAL) - memcpy(tbl_tw2865_common, tbl_tw2865_pal_template, - sizeof(tbl_tw2865_common)); - else - memcpy(tbl_tw2865_common, tbl_tw2865_ntsc_template, - sizeof(tbl_tw2865_common)); - - /* ALINK Mode */ - if (solo_dev->nr_chans == 4) { - tbl_tw2865_common[0xd2] = 0x01; - tbl_tw2865_common[0xcf] = 0x00; - } else if (solo_dev->nr_chans == 8) { - tbl_tw2865_common[0xd2] = 0x02; - if (dev_addr == TW_CHIP_OFFSET_ADDR(1)) - tbl_tw2865_common[0xcf] = 0x80; - } else if (solo_dev->nr_chans == 16) { - tbl_tw2865_common[0xd2] = 0x03; - if (dev_addr == TW_CHIP_OFFSET_ADDR(1)) - tbl_tw2865_common[0xcf] = 0x83; - else if (dev_addr == TW_CHIP_OFFSET_ADDR(2)) - tbl_tw2865_common[0xcf] = 0x83; - else if (dev_addr == TW_CHIP_OFFSET_ADDR(3)) - tbl_tw2865_common[0xcf] = 0x80; - } - - for (i = 0; i < 0xff; i++) { - /* Skip read only registers */ - if (i >= 0xb8 && i <= 0xc1) - continue; - if ((i & ~0x30) == 0x00 || - (i & ~0x30) == 0x0c || - (i & ~0x30) == 0x0d) - continue; - if (i >= 0xc4 && i <= 0xc7) - continue; - if (i == 0xfd) - continue; - - tw_write_and_verify(solo_dev, dev_addr, i, - tbl_tw2865_common[i]); - } - - return 0; -} - -static int tw2864_setup(struct solo6010_dev *solo_dev, u8 dev_addr) -{ - u8 tbl_tw2864_common[sizeof(tbl_tw2864_template)]; - int i; - - memcpy(tbl_tw2864_common, tbl_tw2864_template, - sizeof(tbl_tw2864_common)); - - if (solo_dev->tw2865 == 0) { - /* IRQ Mode */ - if (solo_dev->nr_chans == 4) { - tbl_tw2864_common[0xd2] = 0x01; - tbl_tw2864_common[0xcf] = 0x00; - } else if (solo_dev->nr_chans == 8) { - tbl_tw2864_common[0xd2] = 0x02; - if (dev_addr == TW_CHIP_OFFSET_ADDR(0)) - tbl_tw2864_common[0xcf] = 0x43; - else if (dev_addr == TW_CHIP_OFFSET_ADDR(1)) - tbl_tw2864_common[0xcf] = 0x40; - } else if (solo_dev->nr_chans == 16) { - tbl_tw2864_common[0xd2] = 0x03; - if (dev_addr == TW_CHIP_OFFSET_ADDR(0)) - tbl_tw2864_common[0xcf] = 0x43; - else if (dev_addr == TW_CHIP_OFFSET_ADDR(1)) - tbl_tw2864_common[0xcf] = 0x43; - else if (dev_addr == TW_CHIP_OFFSET_ADDR(2)) - tbl_tw2864_common[0xcf] = 0x43; - else if (dev_addr == TW_CHIP_OFFSET_ADDR(3)) - tbl_tw2864_common[0xcf] = 0x40; - } - } else { - /* ALINK Mode. Assumes that the first tw28xx is a - * 2865 and these are in cascade. */ - for (i = 0; i <= 4; i++) - tbl_tw2864_common[0x08 | i << 4] = 0x12; - - if (solo_dev->nr_chans == 8) { - tbl_tw2864_common[0xd2] = 0x02; - if (dev_addr == TW_CHIP_OFFSET_ADDR(1)) - tbl_tw2864_common[0xcf] = 0x80; - } else if (solo_dev->nr_chans == 16) { - tbl_tw2864_common[0xd2] = 0x03; - if (dev_addr == TW_CHIP_OFFSET_ADDR(1)) - tbl_tw2864_common[0xcf] = 0x83; - else if (dev_addr == TW_CHIP_OFFSET_ADDR(2)) - tbl_tw2864_common[0xcf] = 0x83; - else if (dev_addr == TW_CHIP_OFFSET_ADDR(3)) - tbl_tw2864_common[0xcf] = 0x80; - } - } - - /* NTSC or PAL */ - if (solo_dev->video_type == SOLO_VO_FMT_TYPE_PAL) { - for (i = 0; i < 4; i++) { - tbl_tw2864_common[0x07 | (i << 4)] |= 0x10; - tbl_tw2864_common[0x08 | (i << 4)] |= 0x06; - tbl_tw2864_common[0x0a | (i << 4)] |= 0x08; - tbl_tw2864_common[0x0b | (i << 4)] |= 0x13; - tbl_tw2864_common[0x0e | (i << 4)] |= 0x01; - } - tbl_tw2864_common[0x9d] = 0x90; - tbl_tw2864_common[0xf3] = 0x00; - tbl_tw2864_common[0xf4] = 0xa0; - } - - for (i = 0; i < 0xff; i++) { - /* Skip read only registers */ - if (i >= 0xb8 && i <= 0xc1) - continue; - if ((i & ~0x30) == 0x00 || - (i & ~0x30) == 0x0c || - (i & ~0x30) == 0x0d) - continue; - if (i == 0x74 || i == 0x77 || i == 0x78 || - i == 0x79 || i == 0x7a) - continue; - if (i == 0xfd) - continue; - - tw_write_and_verify(solo_dev, dev_addr, i, - tbl_tw2864_common[i]); - } - - return 0; -} - -static int tw2815_setup(struct solo6010_dev *solo_dev, u8 dev_addr) -{ - u8 tbl_ntsc_tw2815_common[] = { - 0x00, 0xc8, 0x20, 0xd0, 0x06, 0xf0, 0x08, 0x80, - 0x80, 0x80, 0x80, 0x02, 0x06, 0x00, 0x11, - }; - - u8 tbl_pal_tw2815_common[] = { - 0x00, 0x88, 0x20, 0xd0, 0x05, 0x20, 0x28, 0x80, - 0x80, 0x80, 0x80, 0x82, 0x06, 0x00, 0x11, - }; - - u8 tbl_tw2815_sfr[] = { - 0x00, 0x00, 0x00, 0xc0, 0x45, 0xa0, 0xd0, 0x2f, /* 0x00 */ - 0x64, 0x80, 0x80, 0x82, 0x82, 0x00, 0x00, 0x00, - 0x00, 0x0f, 0x05, 0x00, 0x00, 0x80, 0x06, 0x00, /* 0x10 */ - 0x00, 0x00, 0x00, 0xff, 0x8f, 0x00, 0x00, 0x00, - 0x88, 0x88, 0xc0, 0x00, 0x20, 0x64, 0xa8, 0xec, /* 0x20 */ - 0x31, 0x75, 0xb9, 0xfd, 0x00, 0x00, 0x88, 0x88, - 0x88, 0x11, 0x00, 0x88, 0x88, 0x00, /* 0x30 */ - }; - u8 *tbl_tw2815_common; - int i; - int ch; - - tbl_ntsc_tw2815_common[0x06] = 0; - - /* Horizontal Delay Control */ - tbl_ntsc_tw2815_common[0x02] = DEFAULT_HDELAY_NTSC & 0xff; - tbl_ntsc_tw2815_common[0x06] |= 0x03 & (DEFAULT_HDELAY_NTSC >> 8); - - /* Horizontal Active Control */ - tbl_ntsc_tw2815_common[0x03] = DEFAULT_HACTIVE_NTSC & 0xff; - tbl_ntsc_tw2815_common[0x06] |= - ((0x03 & (DEFAULT_HACTIVE_NTSC >> 8)) << 2); - - /* Vertical Delay Control */ - tbl_ntsc_tw2815_common[0x04] = DEFAULT_VDELAY_NTSC & 0xff; - tbl_ntsc_tw2815_common[0x06] |= - ((0x01 & (DEFAULT_VDELAY_NTSC >> 8)) << 4); - - /* Vertical Active Control */ - tbl_ntsc_tw2815_common[0x05] = DEFAULT_VACTIVE_NTSC & 0xff; - tbl_ntsc_tw2815_common[0x06] |= - ((0x01 & (DEFAULT_VACTIVE_NTSC >> 8)) << 5); - - tbl_pal_tw2815_common[0x06] = 0; - - /* Horizontal Delay Control */ - tbl_pal_tw2815_common[0x02] = DEFAULT_HDELAY_PAL & 0xff; - tbl_pal_tw2815_common[0x06] |= 0x03 & (DEFAULT_HDELAY_PAL >> 8); - - /* Horizontal Active Control */ - tbl_pal_tw2815_common[0x03] = DEFAULT_HACTIVE_PAL & 0xff; - tbl_pal_tw2815_common[0x06] |= - ((0x03 & (DEFAULT_HACTIVE_PAL >> 8)) << 2); - - /* Vertical Delay Control */ - tbl_pal_tw2815_common[0x04] = DEFAULT_VDELAY_PAL & 0xff; - tbl_pal_tw2815_common[0x06] |= - ((0x01 & (DEFAULT_VDELAY_PAL >> 8)) << 4); - - /* Vertical Active Control */ - tbl_pal_tw2815_common[0x05] = DEFAULT_VACTIVE_PAL & 0xff; - tbl_pal_tw2815_common[0x06] |= - ((0x01 & (DEFAULT_VACTIVE_PAL >> 8)) << 5); - - tbl_tw2815_common = - (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) ? - tbl_ntsc_tw2815_common : tbl_pal_tw2815_common; - - /* Dual ITU-R BT.656 format */ - tbl_tw2815_common[0x0d] |= 0x04; - - /* Audio configuration */ - tbl_tw2815_sfr[0x62 - 0x40] &= ~(3 << 6); - - if (solo_dev->nr_chans == 4) { - tbl_tw2815_sfr[0x63 - 0x40] |= 1; - tbl_tw2815_sfr[0x62 - 0x40] |= 3 << 6; - } else if (solo_dev->nr_chans == 8) { - tbl_tw2815_sfr[0x63 - 0x40] |= 2; - if (dev_addr == TW_CHIP_OFFSET_ADDR(0)) - tbl_tw2815_sfr[0x62 - 0x40] |= 1 << 6; - else if (dev_addr == TW_CHIP_OFFSET_ADDR(1)) - tbl_tw2815_sfr[0x62 - 0x40] |= 2 << 6; - } else if (solo_dev->nr_chans == 16) { - tbl_tw2815_sfr[0x63 - 0x40] |= 3; - if (dev_addr == TW_CHIP_OFFSET_ADDR(0)) - tbl_tw2815_sfr[0x62 - 0x40] |= 1 << 6; - else if (dev_addr == TW_CHIP_OFFSET_ADDR(1)) - tbl_tw2815_sfr[0x62 - 0x40] |= 0 << 6; - else if (dev_addr == TW_CHIP_OFFSET_ADDR(2)) - tbl_tw2815_sfr[0x62 - 0x40] |= 0 << 6; - else if (dev_addr == TW_CHIP_OFFSET_ADDR(3)) - tbl_tw2815_sfr[0x62 - 0x40] |= 2 << 6; - } - - /* Output mode of R_ADATM pin (0 mixing, 1 record) */ - /* tbl_tw2815_sfr[0x63 - 0x40] |= 0 << 2; */ - - /* 8KHz, used to be 16KHz, but changed for remote client compat */ - tbl_tw2815_sfr[0x62 - 0x40] |= 0 << 2; - tbl_tw2815_sfr[0x6c - 0x40] |= 0 << 2; - - /* Playback of right channel */ - tbl_tw2815_sfr[0x6c - 0x40] |= 1 << 5; - - /* Reserved value (XXX ??) */ - tbl_tw2815_sfr[0x5c - 0x40] |= 1 << 5; - - /* Analog output gain and mix ratio playback on full */ - tbl_tw2815_sfr[0x70 - 0x40] |= 0xff; - /* Select playback audio and mute all except */ - tbl_tw2815_sfr[0x71 - 0x40] |= 0x10; - tbl_tw2815_sfr[0x6d - 0x40] |= 0x0f; - - /* End of audio configuration */ - - for (ch = 0; ch < 4; ch++) { - tbl_tw2815_common[0x0d] &= ~3; - switch (ch) { - case 0: - tbl_tw2815_common[0x0d] |= 0x21; - break; - case 1: - tbl_tw2815_common[0x0d] |= 0x20; - break; - case 2: - tbl_tw2815_common[0x0d] |= 0x23; - break; - case 3: - tbl_tw2815_common[0x0d] |= 0x22; - break; - } - - for (i = 0; i < 0x0f; i++) { - if (i == 0x00) - continue; /* read-only */ - solo_i2c_writebyte(solo_dev, SOLO_I2C_TW, - dev_addr, (ch * 0x10) + i, - tbl_tw2815_common[i]); - } - } - - for (i = 0x40; i < 0x76; i++) { - /* Skip read-only and nop registers */ - if (i == 0x40 || i == 0x59 || i == 0x5a || - i == 0x5d || i == 0x5e || i == 0x5f) - continue; - - solo_i2c_writebyte(solo_dev, SOLO_I2C_TW, dev_addr, i, - tbl_tw2815_sfr[i - 0x40]); - } - - return 0; -} - -#define FIRST_ACTIVE_LINE 0x0008 -#define LAST_ACTIVE_LINE 0x0102 - -static void saa7128_setup(struct solo6010_dev *solo_dev) -{ - int i; - unsigned char regs[128] = { - 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1C, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, - 0x59, 0x1d, 0x75, 0x3f, 0x06, 0x3f, 0x00, 0x00, - 0x1c, 0x33, 0x00, 0x3f, 0x00, 0x00, 0x3f, 0x00, - 0x1a, 0x1a, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x68, 0x10, 0x97, 0x4c, 0x18, - 0x9b, 0x93, 0x9f, 0xff, 0x7c, 0x34, 0x3f, 0x3f, - 0x3f, 0x83, 0x83, 0x80, 0x0d, 0x0f, 0xc3, 0x06, - 0x02, 0x80, 0x71, 0x77, 0xa7, 0x67, 0x66, 0x2e, - 0x7b, 0x11, 0x4f, 0x1f, 0x7c, 0xf0, 0x21, 0x77, - 0x41, 0x88, 0x41, 0x12, 0xed, 0x10, 0x10, 0x00, - 0x41, 0xc3, 0x00, 0x3e, 0xb8, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x08, 0xff, 0x80, 0x00, 0xff, 0xff, - }; - - regs[0x7A] = FIRST_ACTIVE_LINE & 0xff; - regs[0x7B] = LAST_ACTIVE_LINE & 0xff; - regs[0x7C] = ((1 << 7) | - (((LAST_ACTIVE_LINE >> 8) & 1) << 6) | - (((FIRST_ACTIVE_LINE >> 8) & 1) << 4)); - - /* PAL: XXX: We could do a second set of regs to avoid this */ - if (solo_dev->video_type != SOLO_VO_FMT_TYPE_NTSC) { - regs[0x28] = 0xE1; - - regs[0x5A] = 0x0F; - regs[0x61] = 0x02; - regs[0x62] = 0x35; - regs[0x63] = 0xCB; - regs[0x64] = 0x8A; - regs[0x65] = 0x09; - regs[0x66] = 0x2A; - - regs[0x6C] = 0xf1; - regs[0x6E] = 0x20; - - regs[0x7A] = 0x06 + 12; - regs[0x7b] = 0x24 + 12; - regs[0x7c] |= 1 << 6; - } - - /* First 0x25 bytes are read-only? */ - for (i = 0x26; i < 128; i++) { - if (i == 0x60 || i == 0x7D) - continue; - solo_i2c_writebyte(solo_dev, SOLO_I2C_SAA, 0x46, i, regs[i]); - } - - return; -} - -int solo_tw28_init(struct solo6010_dev *solo_dev) -{ - int i; - u8 value; - - /* Detect techwell chip type */ - for (i = 0; i < TW_NUM_CHIP; i++) { - value = solo_i2c_readbyte(solo_dev, SOLO_I2C_TW, - TW_CHIP_OFFSET_ADDR(i), 0xFF); - - switch (value >> 3) { - case 0x18: - solo_dev->tw2865 |= 1 << i; - solo_dev->tw28_cnt++; - break; - case 0x0c: - solo_dev->tw2864 |= 1 << i; - solo_dev->tw28_cnt++; - break; - default: - value = solo_i2c_readbyte(solo_dev, SOLO_I2C_TW, - TW_CHIP_OFFSET_ADDR(i), 0x59); - if ((value >> 3) == 0x04) { - solo_dev->tw2815 |= 1 << i; - solo_dev->tw28_cnt++; - } - } - } - - if (!solo_dev->tw28_cnt) - return -EINVAL; - - saa7128_setup(solo_dev); - - for (i = 0; i < solo_dev->tw28_cnt; i++) { - if ((solo_dev->tw2865 & (1 << i))) - tw2865_setup(solo_dev, TW_CHIP_OFFSET_ADDR(i)); - else if ((solo_dev->tw2864 & (1 << i))) - tw2864_setup(solo_dev, TW_CHIP_OFFSET_ADDR(i)); - else - tw2815_setup(solo_dev, TW_CHIP_OFFSET_ADDR(i)); - } - - dev_info(&solo_dev->pdev->dev, "Initialized %d tw28xx chip%s:", - solo_dev->tw28_cnt, solo_dev->tw28_cnt == 1 ? "" : "s"); - - if (solo_dev->tw2865) - printk(" tw2865[%d]", hweight32(solo_dev->tw2865)); - if (solo_dev->tw2864) - printk(" tw2864[%d]", hweight32(solo_dev->tw2864)); - if (solo_dev->tw2815) - printk(" tw2815[%d]", hweight32(solo_dev->tw2815)); - printk("\n"); - - return 0; -} - -/* - * We accessed the video status signal in the Techwell chip through - * iic/i2c because the video status reported by register REG_VI_STATUS1 - * (address 0x012C) of the SOLO6010 chip doesn't give the correct video - * status signal values. - */ -int tw28_get_video_status(struct solo6010_dev *solo_dev, u8 ch) -{ - u8 val, chip_num; - - /* Get the right chip and on-chip channel */ - chip_num = ch / 4; - ch %= 4; - - val = tw_readbyte(solo_dev, chip_num, TW286X_AV_STAT_ADDR, - TW_AV_STAT_ADDR) & 0x0f; - - return val & (1 << ch) ? 1 : 0; -} - -#if 0 -/* Status of audio from up to 4 techwell chips are combined into 1 variable. - * See techwell datasheet for details. */ -u16 tw28_get_audio_status(struct solo6010_dev *solo_dev) -{ - u8 val; - u16 status = 0; - int i; - - for (i = 0; i < solo_dev->tw28_cnt; i++) { - val = (tw_readbyte(solo_dev, i, TW286X_AV_STAT_ADDR, - TW_AV_STAT_ADDR) & 0xf0) >> 4; - status |= val << (i * 4); - } - - return status; -} -#endif - -int tw28_set_ctrl_val(struct solo6010_dev *solo_dev, u32 ctrl, u8 ch, - s32 val) -{ - char sval; - u8 chip_num; - - /* Get the right chip and on-chip channel */ - chip_num = ch / 4; - ch %= 4; - - if (val > 255 || val < 0) - return -ERANGE; - - switch (ctrl) { - case V4L2_CID_SHARPNESS: - /* Only 286x has sharpness */ - if (val > 0x0f || val < 0) - return -ERANGE; - if (is_tw286x(solo_dev, chip_num)) { - u8 v = solo_i2c_readbyte(solo_dev, SOLO_I2C_TW, - TW_CHIP_OFFSET_ADDR(chip_num), - TW286x_SHARPNESS(chip_num)); - v &= 0xf0; - v |= val; - solo_i2c_writebyte(solo_dev, SOLO_I2C_TW, - TW_CHIP_OFFSET_ADDR(chip_num), - TW286x_SHARPNESS(chip_num), v); - } else if (val != 0) - return -ERANGE; - break; - - case V4L2_CID_HUE: - if (is_tw286x(solo_dev, chip_num)) - sval = val - 128; - else - sval = (char)val; - tw_writebyte(solo_dev, chip_num, TW286x_HUE_ADDR(ch), - TW_HUE_ADDR(ch), sval); - - break; - - case V4L2_CID_SATURATION: - if (is_tw286x(solo_dev, chip_num)) { - solo_i2c_writebyte(solo_dev, SOLO_I2C_TW, - TW_CHIP_OFFSET_ADDR(chip_num), - TW286x_SATURATIONU_ADDR(ch), val); - } - tw_writebyte(solo_dev, chip_num, TW286x_SATURATIONV_ADDR(ch), - TW_SATURATION_ADDR(ch), val); - - break; - - case V4L2_CID_CONTRAST: - tw_writebyte(solo_dev, chip_num, TW286x_CONTRAST_ADDR(ch), - TW_CONTRAST_ADDR(ch), val); - break; - - case V4L2_CID_BRIGHTNESS: - if (is_tw286x(solo_dev, chip_num)) - sval = val - 128; - else - sval = (char)val; - tw_writebyte(solo_dev, chip_num, TW286x_BRIGHTNESS_ADDR(ch), - TW_BRIGHTNESS_ADDR(ch), sval); - - break; - default: - return -EINVAL; - } - - return 0; -} - -int tw28_get_ctrl_val(struct solo6010_dev *solo_dev, u32 ctrl, u8 ch, - s32 *val) -{ - u8 rval, chip_num; - - /* Get the right chip and on-chip channel */ - chip_num = ch / 4; - ch %= 4; - - switch (ctrl) { - case V4L2_CID_SHARPNESS: - /* Only 286x has sharpness */ - if (is_tw286x(solo_dev, chip_num)) { - rval = solo_i2c_readbyte(solo_dev, SOLO_I2C_TW, - TW_CHIP_OFFSET_ADDR(chip_num), - TW286x_SHARPNESS(chip_num)); - *val = rval & 0x0f; - } else - *val = 0; - break; - case V4L2_CID_HUE: - rval = tw_readbyte(solo_dev, chip_num, TW286x_HUE_ADDR(ch), - TW_HUE_ADDR(ch)); - if (is_tw286x(solo_dev, chip_num)) - *val = (s32)((char)rval) + 128; - else - *val = rval; - break; - case V4L2_CID_SATURATION: - *val = tw_readbyte(solo_dev, chip_num, - TW286x_SATURATIONU_ADDR(ch), - TW_SATURATION_ADDR(ch)); - break; - case V4L2_CID_CONTRAST: - *val = tw_readbyte(solo_dev, chip_num, - TW286x_CONTRAST_ADDR(ch), - TW_CONTRAST_ADDR(ch)); - break; - case V4L2_CID_BRIGHTNESS: - rval = tw_readbyte(solo_dev, chip_num, - TW286x_BRIGHTNESS_ADDR(ch), - TW_BRIGHTNESS_ADDR(ch)); - if (is_tw286x(solo_dev, chip_num)) - *val = (s32)((char)rval) + 128; - else - *val = rval; - break; - default: - return -EINVAL; - } - - return 0; -} - -#if 0 -/* - * For audio output volume, the output channel is only 1. In this case we - * don't need to offset TW_CHIP_OFFSET_ADDR. The TW_CHIP_OFFSET_ADDR used - * is the base address of the techwell chip. - */ -void tw2815_Set_AudioOutVol(struct solo6010_dev *solo_dev, unsigned int u_val) -{ - unsigned int val; - unsigned int chip_num; - - chip_num = (solo_dev->nr_chans - 1) / 4; - - val = tw_readbyte(solo_dev, chip_num, TW286x_AUDIO_OUTPUT_VOL_ADDR, - TW_AUDIO_OUTPUT_VOL_ADDR); - - u_val = (val & 0x0f) | (u_val << 4); - - tw_writebyte(solo_dev, chip_num, TW286x_AUDIO_OUTPUT_VOL_ADDR, - TW_AUDIO_OUTPUT_VOL_ADDR, u_val); -} -#endif - -u8 tw28_get_audio_gain(struct solo6010_dev *solo_dev, u8 ch) -{ - u8 val; - u8 chip_num; - - /* Get the right chip and on-chip channel */ - chip_num = ch / 4; - ch %= 4; - - val = tw_readbyte(solo_dev, chip_num, - TW286x_AUDIO_INPUT_GAIN_ADDR(ch), - TW_AUDIO_INPUT_GAIN_ADDR(ch)); - - return (ch % 2) ? (val >> 4) : (val & 0x0f); -} - -void tw28_set_audio_gain(struct solo6010_dev *solo_dev, u8 ch, u8 val) -{ - u8 old_val; - u8 chip_num; - - /* Get the right chip and on-chip channel */ - chip_num = ch / 4; - ch %= 4; - - old_val = tw_readbyte(solo_dev, chip_num, - TW286x_AUDIO_INPUT_GAIN_ADDR(ch), - TW_AUDIO_INPUT_GAIN_ADDR(ch)); - - val = (old_val & ((ch % 2) ? 0x0f : 0xf0)) | - ((ch % 2) ? (val << 4) : val); - - tw_writebyte(solo_dev, chip_num, TW286x_AUDIO_INPUT_GAIN_ADDR(ch), - TW_AUDIO_INPUT_GAIN_ADDR(ch), val); -} diff --git a/drivers/staging/solo6x10/solo6010-tw28.h b/drivers/staging/solo6x10/solo6010-tw28.h deleted file mode 100644 index a7eecfa1a818..000000000000 --- a/drivers/staging/solo6x10/solo6010-tw28.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com - * Copyright (C) 2010 Ben Collins - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef __SOLO6010_TW28_H -#define __SOLO6010_TW28_H - -#include "solo6010.h" - -#define TW_NUM_CHIP 4 -#define TW_BASE_ADDR 0x28 -#define TW_CHIP_OFFSET_ADDR(n) (TW_BASE_ADDR + (n)) - -/* tw2815 */ -#define TW_AV_STAT_ADDR 0x5a -#define TW_HUE_ADDR(n) (0x07 | ((n) << 4)) -#define TW_SATURATION_ADDR(n) (0x08 | ((n) << 4)) -#define TW_CONTRAST_ADDR(n) (0x09 | ((n) << 4)) -#define TW_BRIGHTNESS_ADDR(n) (0x0a | ((n) << 4)) -#define TW_AUDIO_OUTPUT_VOL_ADDR 0x70 -#define TW_AUDIO_INPUT_GAIN_ADDR(n) (0x60 + ((n > 1) ? 1 : 0)) - -/* tw286x */ -#define TW286X_AV_STAT_ADDR 0xfd -#define TW286x_HUE_ADDR(n) (0x06 | ((n) << 4)) -#define TW286x_SATURATIONU_ADDR(n) (0x04 | ((n) << 4)) -#define TW286x_SATURATIONV_ADDR(n) (0x05 | ((n) << 4)) -#define TW286x_CONTRAST_ADDR(n) (0x02 | ((n) << 4)) -#define TW286x_BRIGHTNESS_ADDR(n) (0x01 | ((n) << 4)) -#define TW286x_SHARPNESS(n) (0x03 | ((n) << 4)) -#define TW286x_AUDIO_OUTPUT_VOL_ADDR 0xdf -#define TW286x_AUDIO_INPUT_GAIN_ADDR(n) (0xD0 + ((n > 1) ? 1 : 0)) - -int solo_tw28_init(struct solo6010_dev *solo_dev); - -int tw28_set_ctrl_val(struct solo6010_dev *solo_dev, u32 ctrl, u8 ch, - s32 val); -int tw28_get_ctrl_val(struct solo6010_dev *solo_dev, u32 ctrl, u8 ch, - s32 *val); - -u8 tw28_get_audio_gain(struct solo6010_dev *solo_dev, u8 ch); -void tw28_set_audio_gain(struct solo6010_dev *solo_dev, u8 ch, u8 val); -int tw28_get_video_status(struct solo6010_dev *solo_dev, u8 ch); - -#if 0 -unsigned int tw2815_get_audio_status(struct SOLO6010 *solo6010); -void tw2815_Set_AudioOutVol(struct SOLO6010 *solo6010, unsigned int u_val); -#endif - -#endif /* __SOLO6010_TW28_H */ diff --git a/drivers/staging/solo6x10/solo6010-v4l2-enc.c b/drivers/staging/solo6x10/solo6010-v4l2-enc.c deleted file mode 100644 index 6fbd50e90f63..000000000000 --- a/drivers/staging/solo6x10/solo6010-v4l2-enc.c +++ /dev/null @@ -1,1827 +0,0 @@ -/* - * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com - * Copyright (C) 2010 Ben Collins - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include "solo6010.h" -#include "solo6010-tw28.h" -#include "solo6010-jpeg.h" - -#define MIN_VID_BUFFERS 4 -#define FRAME_BUF_SIZE (128 * 1024) -#define MP4_QS 16 - -static int solo_enc_thread(void *data); - -extern unsigned video_nr; - -struct solo_enc_fh { - struct solo_enc_dev *enc; - u32 fmt; - u16 rd_idx; - u8 enc_on; - enum solo_enc_types type; - struct videobuf_queue vidq; - struct list_head vidq_active; - struct task_struct *kthread; - struct p2m_desc desc[SOLO_NR_P2M_DESC]; -}; - -static const u32 solo_user_ctrls[] = { - V4L2_CID_BRIGHTNESS, - V4L2_CID_CONTRAST, - V4L2_CID_SATURATION, - V4L2_CID_HUE, - V4L2_CID_SHARPNESS, - 0 -}; - -static const u32 solo_mpeg_ctrls[] = { - V4L2_CID_MPEG_VIDEO_ENCODING, - V4L2_CID_MPEG_VIDEO_GOP_SIZE, - 0 -}; - -static const u32 solo_private_ctrls[] = { - V4L2_CID_MOTION_ENABLE, - V4L2_CID_MOTION_THRESHOLD, - 0 -}; - -static const u32 solo_fmtx_ctrls[] = { - V4L2_CID_RDS_TX_RADIO_TEXT, - 0 -}; - -static const u32 *solo_ctrl_classes[] = { - solo_user_ctrls, - solo_mpeg_ctrls, - solo_fmtx_ctrls, - solo_private_ctrls, - NULL -}; - -static int solo_is_motion_on(struct solo_enc_dev *solo_enc) -{ - struct solo6010_dev *solo_dev = solo_enc->solo_dev; - u8 ch = solo_enc->ch; - - if (solo_dev->motion_mask & (1 << ch)) - return 1; - return 0; -} - -static void solo_motion_toggle(struct solo_enc_dev *solo_enc, int on) -{ - struct solo6010_dev *solo_dev = solo_enc->solo_dev; - u8 ch = solo_enc->ch; - - spin_lock(&solo_enc->lock); - - if (on) - solo_dev->motion_mask |= (1 << ch); - else - solo_dev->motion_mask &= ~(1 << ch); - - /* Do this regardless of if we are turning on or off */ - solo_reg_write(solo_enc->solo_dev, SOLO_VI_MOT_CLEAR, - 1 << solo_enc->ch); - solo_enc->motion_detected = 0; - - solo_reg_write(solo_dev, SOLO_VI_MOT_ADR, - SOLO_VI_MOTION_EN(solo_dev->motion_mask) | - (SOLO_MOTION_EXT_ADDR(solo_dev) >> 16)); - - if (solo_dev->motion_mask) - solo6010_irq_on(solo_dev, SOLO_IRQ_MOTION); - else - solo6010_irq_off(solo_dev, SOLO_IRQ_MOTION); - - spin_unlock(&solo_enc->lock); -} - -/* Should be called with solo_enc->lock held */ -static void solo_update_mode(struct solo_enc_dev *solo_enc) -{ - struct solo6010_dev *solo_dev = solo_enc->solo_dev; - - assert_spin_locked(&solo_enc->lock); - - solo_enc->interlaced = (solo_enc->mode & 0x08) ? 1 : 0; - solo_enc->bw_weight = max(solo_dev->fps / solo_enc->interval, 1); - - switch (solo_enc->mode) { - case SOLO_ENC_MODE_CIF: - solo_enc->width = solo_dev->video_hsize >> 1; - solo_enc->height = solo_dev->video_vsize; - break; - case SOLO_ENC_MODE_D1: - solo_enc->width = solo_dev->video_hsize; - solo_enc->height = solo_dev->video_vsize << 1; - solo_enc->bw_weight <<= 2; - break; - default: - WARN(1, "mode is unknown\n"); - } -} - -/* Should be called with solo_enc->lock held */ -static int solo_enc_on(struct solo_enc_fh *fh) -{ - struct solo_enc_dev *solo_enc = fh->enc; - u8 ch = solo_enc->ch; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; - u8 interval; - - assert_spin_locked(&solo_enc->lock); - - if (fh->enc_on) - return 0; - - solo_update_mode(solo_enc); - - /* Make sure to bw check on first reader */ - if (!atomic_read(&solo_enc->readers)) { - if (solo_enc->bw_weight > solo_dev->enc_bw_remain) - return -EBUSY; - else - solo_dev->enc_bw_remain -= solo_enc->bw_weight; - } - - fh->enc_on = 1; - fh->rd_idx = solo_enc->solo_dev->enc_wr_idx; - - if (fh->type == SOLO_ENC_TYPE_EXT) - solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(ch), 1); - - if (atomic_inc_return(&solo_enc->readers) > 1) - return 0; - - /* Disable all encoding for this channel */ - solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(ch), 0); - - /* Common for both std and ext encoding */ - solo_reg_write(solo_dev, SOLO_VE_CH_INTL(ch), - solo_enc->interlaced ? 1 : 0); - - if (solo_enc->interlaced) - interval = solo_enc->interval - 1; - else - interval = solo_enc->interval; - - /* Standard encoding only */ - solo_reg_write(solo_dev, SOLO_VE_CH_GOP(ch), solo_enc->gop); - solo_reg_write(solo_dev, SOLO_VE_CH_QP(ch), solo_enc->qp); - solo_reg_write(solo_dev, SOLO_CAP_CH_INTV(ch), interval); - - /* Extended encoding only */ - solo_reg_write(solo_dev, SOLO_VE_CH_GOP_E(ch), solo_enc->gop); - solo_reg_write(solo_dev, SOLO_VE_CH_QP_E(ch), solo_enc->qp); - solo_reg_write(solo_dev, SOLO_CAP_CH_INTV_E(ch), interval); - - /* Enables the standard encoder */ - solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(ch), solo_enc->mode); - - /* Settle down Beavis... */ - mdelay(10); - - return 0; -} - -static void solo_enc_off(struct solo_enc_fh *fh) -{ - struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; - - if (!fh->enc_on) - return; - - if (fh->kthread) { - kthread_stop(fh->kthread); - fh->kthread = NULL; - } - - solo_dev->enc_bw_remain += solo_enc->bw_weight; - fh->enc_on = 0; - - if (atomic_dec_return(&solo_enc->readers) > 0) - return; - - solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(solo_enc->ch), 0); - solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(solo_enc->ch), 0); -} - -static int solo_start_fh_thread(struct solo_enc_fh *fh) -{ - struct solo_enc_dev *solo_enc = fh->enc; - - fh->kthread = kthread_run(solo_enc_thread, fh, SOLO6010_NAME "_enc"); - - /* Oops, we had a problem */ - if (IS_ERR(fh->kthread)) { - spin_lock(&solo_enc->lock); - solo_enc_off(fh); - spin_unlock(&solo_enc->lock); - - return PTR_ERR(fh->kthread); - } - - return 0; -} - -static void enc_reset_gop(struct solo6010_dev *solo_dev, u8 ch) -{ - BUG_ON(ch >= solo_dev->nr_chans); - solo_reg_write(solo_dev, SOLO_VE_CH_GOP(ch), 1); - solo_dev->v4l2_enc[ch]->reset_gop = 1; -} - -static int enc_gop_reset(struct solo6010_dev *solo_dev, u8 ch, u8 vop) -{ - BUG_ON(ch >= solo_dev->nr_chans); - if (!solo_dev->v4l2_enc[ch]->reset_gop) - return 0; - if (vop) - return 1; - solo_dev->v4l2_enc[ch]->reset_gop = 0; - solo_reg_write(solo_dev, SOLO_VE_CH_GOP(ch), - solo_dev->v4l2_enc[ch]->gop); - return 0; -} - -static void enc_write_sg(struct scatterlist *sglist, void *buf, int size) -{ - struct scatterlist *sg; - u8 *src = buf; - - for (sg = sglist; sg && size > 0; sg = sg_next(sg)) { - u8 *p = sg_virt(sg); - size_t len = sg_dma_len(sg); - int i; - - for (i = 0; i < len && size; i++) - p[i] = *(src++); - } -} - -static int enc_get_mpeg_dma_sg(struct solo6010_dev *solo_dev, - struct p2m_desc *desc, - struct scatterlist *sglist, int skip, - unsigned int off, unsigned int size) -{ - int ret; - - if (off > SOLO_MP4E_EXT_SIZE(solo_dev)) - return -EINVAL; - - if (off + size <= SOLO_MP4E_EXT_SIZE(solo_dev)) { - return solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_MP4E, - desc, 0, sglist, skip, - SOLO_MP4E_EXT_ADDR(solo_dev) + off, size); - } - - /* Buffer wrap */ - ret = solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_MP4E, desc, 0, - sglist, skip, SOLO_MP4E_EXT_ADDR(solo_dev) + off, - SOLO_MP4E_EXT_SIZE(solo_dev) - off); - - ret |= solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_MP4E, desc, 0, - sglist, skip + SOLO_MP4E_EXT_SIZE(solo_dev) - off, - SOLO_MP4E_EXT_ADDR(solo_dev), - size + off - SOLO_MP4E_EXT_SIZE(solo_dev)); - - return ret; -} - -static int enc_get_mpeg_dma_t(struct solo6010_dev *solo_dev, - dma_addr_t buf, unsigned int off, - unsigned int size) -{ - int ret; - - if (off > SOLO_MP4E_EXT_SIZE(solo_dev)) - return -EINVAL; - - if (off + size <= SOLO_MP4E_EXT_SIZE(solo_dev)) { - return solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_MP4E, 0, buf, - SOLO_MP4E_EXT_ADDR(solo_dev) + off, size); - } - - /* Buffer wrap */ - ret = solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_MP4E, 0, buf, - SOLO_MP4E_EXT_ADDR(solo_dev) + off, - SOLO_MP4E_EXT_SIZE(solo_dev) - off); - - ret |= solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_MP4E, 0, - buf + SOLO_MP4E_EXT_SIZE(solo_dev) - off, - SOLO_MP4E_EXT_ADDR(solo_dev), - size + off - SOLO_MP4E_EXT_SIZE(solo_dev)); - - return ret; -} - -static int enc_get_mpeg_dma(struct solo6010_dev *solo_dev, void *buf, - unsigned int off, unsigned int size) -{ - int ret; - - dma_addr_t dma_addr = pci_map_single(solo_dev->pdev, buf, size, - PCI_DMA_FROMDEVICE); - ret = enc_get_mpeg_dma_t(solo_dev, dma_addr, off, size); - pci_unmap_single(solo_dev->pdev, dma_addr, size, PCI_DMA_FROMDEVICE); - - return ret; -} - -static int enc_get_jpeg_dma_sg(struct solo6010_dev *solo_dev, - struct p2m_desc *desc, - struct scatterlist *sglist, int skip, - unsigned int off, unsigned int size) -{ - int ret; - - if (off > SOLO_JPEG_EXT_SIZE(solo_dev)) - return -EINVAL; - - if (off + size <= SOLO_JPEG_EXT_SIZE(solo_dev)) { - return solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_JPEG, - desc, 0, sglist, skip, - SOLO_JPEG_EXT_ADDR(solo_dev) + off, size); - } - - /* Buffer wrap */ - ret = solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_JPEG, desc, 0, - sglist, skip, SOLO_JPEG_EXT_ADDR(solo_dev) + off, - SOLO_JPEG_EXT_SIZE(solo_dev) - off); - - ret |= solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_JPEG, desc, 0, - sglist, skip + SOLO_JPEG_EXT_SIZE(solo_dev) - off, - SOLO_JPEG_EXT_ADDR(solo_dev), - size + off - SOLO_JPEG_EXT_SIZE(solo_dev)); - - return ret; -} - -/* Returns true of __chk is within the first __range bytes of __off */ -#define OFF_IN_RANGE(__off, __range, __chk) \ - ((__off <= __chk) && ((__off + __range) >= __chk)) - -static void solo_jpeg_header(struct solo_enc_dev *solo_enc, - struct videobuf_dmabuf *vbuf) -{ - struct scatterlist *sg; - void *src = jpeg_header; - size_t copied = 0; - size_t to_copy = sizeof(jpeg_header); - - for (sg = vbuf->sglist; sg && copied < to_copy; sg = sg_next(sg)) { - size_t this_copy = min(sg_dma_len(sg), - (unsigned int)(to_copy - copied)); - u8 *p = sg_virt(sg); - - memcpy(p, src + copied, this_copy); - - if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 5)) - p[(SOF0_START + 5) - copied] = - 0xff & (solo_enc->height >> 8); - if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 6)) - p[(SOF0_START + 6) - copied] = 0xff & solo_enc->height; - if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 7)) - p[(SOF0_START + 7) - copied] = - 0xff & (solo_enc->width >> 8); - if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 8)) - p[(SOF0_START + 8) - copied] = 0xff & solo_enc->width; - - copied += this_copy; - } -} - -static int solo_fill_jpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf, - struct videobuf_buffer *vb, - struct videobuf_dmabuf *vbuf) -{ - struct solo6010_dev *solo_dev = fh->enc->solo_dev; - int size = enc_buf->jpeg_size; - - /* Copy the header first (direct write) */ - solo_jpeg_header(fh->enc, vbuf); - - vb->size = size + sizeof(jpeg_header); - - /* Grab the jpeg frame */ - return enc_get_jpeg_dma_sg(solo_dev, fh->desc, vbuf->sglist, - sizeof(jpeg_header), - enc_buf->jpeg_off, size); -} - -static inline int vop_interlaced(__le32 *vh) -{ - return (__le32_to_cpu(vh[0]) >> 30) & 1; -} - -static inline u32 vop_size(__le32 *vh) -{ - return __le32_to_cpu(vh[0]) & 0xFFFFF; -} - -static inline u8 vop_hsize(__le32 *vh) -{ - return (__le32_to_cpu(vh[1]) >> 8) & 0xFF; -} - -static inline u8 vop_vsize(__le32 *vh) -{ - return __le32_to_cpu(vh[1]) & 0xFF; -} - -/* must be called with *bits % 8 = 0 */ -static void write_bytes(u8 **out, unsigned *bits, const u8 *src, unsigned count) -{ - memcpy(*out, src, count); - *out += count; - *bits += count * 8; -} - -static void write_bits(u8 **out, unsigned *bits, u32 value, unsigned count) -{ - - value <<= 32 - count; // shift to the right - - while (count--) { - **out <<= 1; - **out |= !!(value & (1 << 31)); /* MSB */ - value <<= 1; - if (++(*bits) % 8 == 0) - (*out)++; - } -} - -static void write_ue(u8 **out, unsigned *bits, unsigned value) /* H.264 only */ -{ - uint32_t max = 0, cnt = 0; - - while (value > max) { - max = (max + 2) * 2 - 2; - cnt++; - } - write_bits(out, bits, 1, cnt + 1); - write_bits(out, bits, ~(max - value), cnt); -} - -static void write_se(u8 **out, unsigned *bits, int value) /* H.264 only */ -{ - if (value <= 0) - write_ue(out, bits, -value * 2); - else - write_ue(out, bits, value * 2 - 1); -} - -static void write_mpeg4_end(u8 **out, unsigned *bits) -{ - write_bits(out, bits, 0, 1); - /* align on 32-bit boundary */ - if (*bits % 32) - write_bits(out, bits, 0xFFFFFFFF, 32 - *bits % 32); -} - -static void write_h264_end(u8 **out, unsigned *bits, int align) -{ - write_bits(out, bits, 1, 1); - while ((*bits) % 8) - write_bits(out, bits, 0, 1); - if (align) - while ((*bits) % 32) - write_bits(out, bits, 0, 1); -} - -static void mpeg4_write_vol(u8 **out, struct solo6010_dev *solo_dev, - __le32 *vh, unsigned fps, unsigned interval) -{ - static const u8 hdr[] = { - 0, 0, 1, 0x00 /* video_object_start_code */, - 0, 0, 1, 0x20 /* video_object_layer_start_code */ - }; - unsigned bits = 0; - unsigned width = vop_hsize(vh) << 4; - unsigned height = vop_vsize(vh) << 4; - unsigned interlaced = vop_interlaced(vh); - - write_bytes(out, &bits, hdr, sizeof(hdr)); - write_bits(out, &bits, 0, 1); /* random_accessible_vol */ - write_bits(out, &bits, 0x04, 8); /* video_object_type_indication: main */ - write_bits(out, &bits, 1, 1); /* is_object_layer_identifier */ - write_bits(out, &bits, 2, 4); /* video_object_layer_verid: table V2-39 */ - write_bits(out, &bits, 0, 3); /* video_object_layer_priority */ - if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) - write_bits(out, &bits, 3, 4); /* aspect_ratio_info, assuming 4:3 */ - else - write_bits(out, &bits, 2, 4); - write_bits(out, &bits, 1, 1); /* vol_control_parameters */ - write_bits(out, &bits, 1, 2); /* chroma_format: 4:2:0 */ - write_bits(out, &bits, 1, 1); /* low_delay */ - write_bits(out, &bits, 0, 1); /* vbv_parameters */ - write_bits(out, &bits, 0, 2); /* video_object_layer_shape: rectangular */ - write_bits(out, &bits, 1, 1); /* marker_bit */ - write_bits(out, &bits, fps, 16); /* vop_time_increment_resolution */ - write_bits(out, &bits, 1, 1); /* marker_bit */ - write_bits(out, &bits, 1, 1); /* fixed_vop_rate */ - write_bits(out, &bits, interval, 15); /* fixed_vop_time_increment */ - write_bits(out, &bits, 1, 1); /* marker_bit */ - write_bits(out, &bits, width, 13); /* video_object_layer_width */ - write_bits(out, &bits, 1, 1); /* marker_bit */ - write_bits(out, &bits, height, 13); /* video_object_layer_height */ - write_bits(out, &bits, 1, 1); /* marker_bit */ - write_bits(out, &bits, interlaced, 1); /* interlaced */ - write_bits(out, &bits, 1, 1); /* obmc_disable */ - write_bits(out, &bits, 0, 2); /* sprite_enable */ - write_bits(out, &bits, 0, 1); /* not_8_bit */ - write_bits(out, &bits, 1, 0); /* quant_type */ - write_bits(out, &bits, 0, 1); /* load_intra_quant_mat */ - write_bits(out, &bits, 0, 1); /* load_nonintra_quant_mat */ - write_bits(out, &bits, 0, 1); /* quarter_sample */ - write_bits(out, &bits, 1, 1); /* complexity_estimation_disable */ - write_bits(out, &bits, 1, 1); /* resync_marker_disable */ - write_bits(out, &bits, 0, 1); /* data_partitioned */ - write_bits(out, &bits, 0, 1); /* newpred_enable */ - write_bits(out, &bits, 0, 1); /* reduced_resolution_vop_enable */ - write_bits(out, &bits, 0, 1); /* scalability */ - write_mpeg4_end(out, &bits); -} - -static void h264_write_vol(u8 **out, struct solo6010_dev *solo_dev, __le32 *vh) -{ - static const u8 sps[] = { - 0, 0, 0, 1 /* start code */, 0x67, 66 /* profile_idc */, - 0 /* constraints */, 30 /* level_idc */ - }; - static const u8 pps[] = { - 0, 0, 0, 1 /* start code */, 0x68 - }; - - unsigned bits = 0; - unsigned mbs_w = vop_hsize(vh); - unsigned mbs_h = vop_vsize(vh); - - write_bytes(out, &bits, sps, sizeof(sps)); - write_ue(out, &bits, 0); /* seq_parameter_set_id */ - write_ue(out, &bits, 5); /* log2_max_frame_num_minus4 */ - write_ue(out, &bits, 0); /* pic_order_cnt_type */ - write_ue(out, &bits, 6); /* log2_max_pic_order_cnt_lsb_minus4 */ - write_ue(out, &bits, 1); /* max_num_ref_frames */ - write_bits(out, &bits, 0, 1); /* gaps_in_frame_num_value_allowed_flag */ - write_ue(out, &bits, mbs_w - 1); /* pic_width_in_mbs_minus1 */ - write_ue(out, &bits, mbs_h - 1); /* pic_height_in_map_units_minus1 */ - write_bits(out, &bits, 1, 1); /* frame_mbs_only_flag */ - write_bits(out, &bits, 1, 1); /* direct_8x8_frame_field_flag */ - write_bits(out, &bits, 0, 1); /* frame_cropping_flag */ - write_bits(out, &bits, 0, 1); /* vui_parameters_present_flag */ - write_h264_end(out, &bits, 0); - - write_bytes(out, &bits, pps, sizeof(pps)); - write_ue(out, &bits, 0); /* pic_parameter_set_id */ - write_ue(out, &bits, 0); /* seq_parameter_set_id */ - write_bits(out, &bits, 0, 1); /* entropy_coding_mode_flag */ - write_bits(out, &bits, 0, 1); /* bottom_field_pic_order_in_frame_present_flag */ - write_ue(out, &bits, 0); /* num_slice_groups_minus1 */ - write_ue(out, &bits, 0); /* num_ref_idx_l0_default_active_minus1 */ - write_ue(out, &bits, 0); /* num_ref_idx_l1_default_active_minus1 */ - write_bits(out, &bits, 0, 1); /* weighted_pred_flag */ - write_bits(out, &bits, 0, 2); /* weighted_bipred_idc */ - write_se(out, &bits, 0); /* pic_init_qp_minus26 */ - write_se(out, &bits, 0); /* pic_init_qs_minus26 */ - write_se(out, &bits, 2); /* chroma_qp_index_offset */ - write_bits(out, &bits, 0, 1); /* deblocking_filter_control_present_flag */ - write_bits(out, &bits, 1, 1); /* constrained_intra_pred_flag */ - write_bits(out, &bits, 0, 1); /* redundant_pic_cnt_present_flag */ - write_h264_end(out, &bits, 1); -} - -static int solo_fill_mpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf, - struct videobuf_buffer *vb, - struct videobuf_dmabuf *vbuf) -{ - struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; - -#define VH_WORDS 16 -#define MAX_VOL_HEADER_LENGTH 64 - - __le32 vh[VH_WORDS]; - int ret; - int frame_size, frame_off; - int skip = 0; - - if (WARN_ON_ONCE(enc_buf->size <= sizeof(vh))) - return -EINVAL; - - /* First get the hardware vop header (not real mpeg) */ - ret = enc_get_mpeg_dma(solo_dev, vh, enc_buf->off, sizeof(vh)); - if (WARN_ON_ONCE(ret)) - return ret; - - if (WARN_ON_ONCE(vop_size(vh) > enc_buf->size)) - return -EINVAL; - - vb->width = vop_hsize(vh) << 4; - vb->height = vop_vsize(vh) << 4; - vb->size = vop_size(vh); - - /* If this is a key frame, add extra m4v header */ - if (!enc_buf->vop) { - u8 header[MAX_VOL_HEADER_LENGTH], *out = header; - - if (solo_dev->flags & FLAGS_6110) - h264_write_vol(&out, solo_dev, vh); - else - mpeg4_write_vol(&out, solo_dev, vh, - solo_dev->fps * 1000, - solo_enc->interval * 1000); - skip = out - header; - enc_write_sg(vbuf->sglist, header, skip); - /* Adjust the dma buffer past this header */ - vb->size += skip; - } - - /* Now get the actual mpeg payload */ - frame_off = (enc_buf->off + sizeof(vh)) % SOLO_MP4E_EXT_SIZE(solo_dev); - frame_size = enc_buf->size - sizeof(vh); - - ret = enc_get_mpeg_dma_sg(solo_dev, fh->desc, vbuf->sglist, - skip, frame_off, frame_size); - WARN_ON_ONCE(ret); - - return ret; -} - -static void solo_enc_fillbuf(struct solo_enc_fh *fh, - struct videobuf_buffer *vb) -{ - struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; - struct solo_enc_buf *enc_buf = NULL; - struct videobuf_dmabuf *vbuf; - int ret; - int error = 1; - u16 idx = fh->rd_idx; - - while (idx != solo_dev->enc_wr_idx) { - struct solo_enc_buf *ebuf = &solo_dev->enc_buf[idx]; - - idx = (idx + 1) % SOLO_NR_RING_BUFS; - - if (ebuf->ch != solo_enc->ch) - continue; - - if (fh->fmt == V4L2_PIX_FMT_MPEG) { - if (fh->type == ebuf->type) { - enc_buf = ebuf; - break; - } - } else { - /* For mjpeg, keep reading to the newest frame */ - enc_buf = ebuf; - } - } - - fh->rd_idx = idx; - - if (WARN_ON_ONCE(!enc_buf)) - goto buf_err; - - if ((fh->fmt == V4L2_PIX_FMT_MPEG && - vb->bsize < enc_buf->size) || - (fh->fmt == V4L2_PIX_FMT_MJPEG && - vb->bsize < (enc_buf->jpeg_size + sizeof(jpeg_header)))) { - WARN_ON_ONCE(1); - goto buf_err; - } - - vbuf = videobuf_to_dma(vb); - if (WARN_ON_ONCE(!vbuf)) - goto buf_err; - - if (fh->fmt == V4L2_PIX_FMT_MPEG) - ret = solo_fill_mpeg(fh, enc_buf, vb, vbuf); - else - ret = solo_fill_jpeg(fh, enc_buf, vb, vbuf); - - if (!ret) - error = 0; - -buf_err: - if (error) { - vb->state = VIDEOBUF_ERROR; - } else { - vb->field_count++; - vb->ts = enc_buf->ts; - vb->state = VIDEOBUF_DONE; - } - - wake_up(&vb->done); - - return; -} - -static void solo_enc_thread_try(struct solo_enc_fh *fh) -{ - struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; - struct videobuf_buffer *vb; - - for (;;) { - spin_lock(&solo_enc->lock); - - if (fh->rd_idx == solo_dev->enc_wr_idx) - break; - - if (list_empty(&fh->vidq_active)) - break; - - vb = list_first_entry(&fh->vidq_active, - struct videobuf_buffer, queue); - - if (!waitqueue_active(&vb->done)) - break; - - list_del(&vb->queue); - - spin_unlock(&solo_enc->lock); - - solo_enc_fillbuf(fh, vb); - } - - assert_spin_locked(&solo_enc->lock); - spin_unlock(&solo_enc->lock); -} - -static int solo_enc_thread(void *data) -{ - struct solo_enc_fh *fh = data; - struct solo_enc_dev *solo_enc = fh->enc; - DECLARE_WAITQUEUE(wait, current); - - set_freezable(); - add_wait_queue(&solo_enc->thread_wait, &wait); - - for (;;) { - long timeout = schedule_timeout_interruptible(HZ); - if (timeout == -ERESTARTSYS || kthread_should_stop()) - break; - solo_enc_thread_try(fh); - try_to_freeze(); - } - - remove_wait_queue(&solo_enc->thread_wait, &wait); - - return 0; -} - -void solo_motion_isr(struct solo6010_dev *solo_dev) -{ - u32 status; - int i; - - solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_MOTION); - - status = solo_reg_read(solo_dev, SOLO_VI_MOT_STATUS); - - for (i = 0; i < solo_dev->nr_chans; i++) { - struct solo_enc_dev *solo_enc = solo_dev->v4l2_enc[i]; - - BUG_ON(solo_enc == NULL); - - if (solo_enc->motion_detected) - continue; - if (!(status & (1 << i))) - continue; - - solo_enc->motion_detected = 1; - } -} - -void solo_enc_v4l2_isr(struct solo6010_dev *solo_dev) -{ - struct solo_enc_buf *enc_buf; - u32 mpeg_current, mpeg_next, mpeg_size; - u32 jpeg_current, jpeg_next, jpeg_size; - u32 reg_mpeg_size; - u8 cur_q, vop_type; - u8 ch; - enum solo_enc_types enc_type; - - solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_ENCODER); - - cur_q = ((solo_reg_read(solo_dev, SOLO_VE_STATE(11)) & 0xF) + 1) % MP4_QS; - - reg_mpeg_size = ((solo_reg_read(solo_dev, SOLO_VE_STATE(0)) & 0xFFFFF) + 64 + 8) & ~7; - - while (solo_dev->enc_idx != cur_q) { - mpeg_current = solo_reg_read(solo_dev, - SOLO_VE_MPEG4_QUE(solo_dev->enc_idx)); - jpeg_current = solo_reg_read(solo_dev, - SOLO_VE_JPEG_QUE(solo_dev->enc_idx)); - solo_dev->enc_idx = (solo_dev->enc_idx + 1) % MP4_QS; - mpeg_next = solo_reg_read(solo_dev, - SOLO_VE_MPEG4_QUE(solo_dev->enc_idx)); - jpeg_next = solo_reg_read(solo_dev, - SOLO_VE_JPEG_QUE(solo_dev->enc_idx)); - - ch = (mpeg_current >> 24) & 0x1f; - if (ch >= SOLO_MAX_CHANNELS) { - ch -= SOLO_MAX_CHANNELS; - enc_type = SOLO_ENC_TYPE_EXT; - } else - enc_type = SOLO_ENC_TYPE_STD; - - vop_type = (mpeg_current >> 29) & 3; - - mpeg_current &= 0x00ffffff; - mpeg_next &= 0x00ffffff; - jpeg_current &= 0x00ffffff; - jpeg_next &= 0x00ffffff; - - mpeg_size = (SOLO_MP4E_EXT_SIZE(solo_dev) + - mpeg_next - mpeg_current) % - SOLO_MP4E_EXT_SIZE(solo_dev); - - jpeg_size = (SOLO_JPEG_EXT_SIZE(solo_dev) + - jpeg_next - jpeg_current) % - SOLO_JPEG_EXT_SIZE(solo_dev); - - /* XXX I think this means we had a ring overflow? */ - if (mpeg_current > mpeg_next && mpeg_size != reg_mpeg_size) { - enc_reset_gop(solo_dev, ch); - continue; - } - - /* When resetting the GOP, skip frames until I-frame */ - if (enc_gop_reset(solo_dev, ch, vop_type)) - continue; - - enc_buf = &solo_dev->enc_buf[solo_dev->enc_wr_idx]; - - enc_buf->vop = vop_type; - enc_buf->ch = ch; - enc_buf->off = mpeg_current; - enc_buf->size = mpeg_size; - enc_buf->jpeg_off = jpeg_current; - enc_buf->jpeg_size = jpeg_size; - enc_buf->type = enc_type; - - do_gettimeofday(&enc_buf->ts); - - solo_dev->enc_wr_idx = (solo_dev->enc_wr_idx + 1) % - SOLO_NR_RING_BUFS; - - wake_up_interruptible(&solo_dev->v4l2_enc[ch]->thread_wait); - } - - return; -} - -static int solo_enc_buf_setup(struct videobuf_queue *vq, unsigned int *count, - unsigned int *size) -{ - *size = FRAME_BUF_SIZE; - - if (*count < MIN_VID_BUFFERS) - *count = MIN_VID_BUFFERS; - - return 0; -} - -static int solo_enc_buf_prepare(struct videobuf_queue *vq, - struct videobuf_buffer *vb, - enum v4l2_field field) -{ - struct solo_enc_fh *fh = vq->priv_data; - struct solo_enc_dev *solo_enc = fh->enc; - - vb->size = FRAME_BUF_SIZE; - if (vb->baddr != 0 && vb->bsize < vb->size) - return -EINVAL; - - /* These properties only change when queue is idle */ - vb->width = solo_enc->width; - vb->height = solo_enc->height; - vb->field = field; - - if (vb->state == VIDEOBUF_NEEDS_INIT) { - int rc = videobuf_iolock(vq, vb, NULL); - if (rc < 0) { - struct videobuf_dmabuf *dma = videobuf_to_dma(vb); - videobuf_dma_unmap(vq->dev, dma); - videobuf_dma_free(dma); - vb->state = VIDEOBUF_NEEDS_INIT; - return rc; - } - } - vb->state = VIDEOBUF_PREPARED; - - return 0; -} - -static void solo_enc_buf_queue(struct videobuf_queue *vq, - struct videobuf_buffer *vb) -{ - struct solo_enc_fh *fh = vq->priv_data; - - vb->state = VIDEOBUF_QUEUED; - list_add_tail(&vb->queue, &fh->vidq_active); - wake_up_interruptible(&fh->enc->thread_wait); -} - -static void solo_enc_buf_release(struct videobuf_queue *vq, - struct videobuf_buffer *vb) -{ - struct videobuf_dmabuf *dma = videobuf_to_dma(vb); - - videobuf_dma_unmap(vq->dev, dma); - videobuf_dma_free(dma); - vb->state = VIDEOBUF_NEEDS_INIT; -} - -static struct videobuf_queue_ops solo_enc_video_qops = { - .buf_setup = solo_enc_buf_setup, - .buf_prepare = solo_enc_buf_prepare, - .buf_queue = solo_enc_buf_queue, - .buf_release = solo_enc_buf_release, -}; - -static unsigned int solo_enc_poll(struct file *file, - struct poll_table_struct *wait) -{ - struct solo_enc_fh *fh = file->private_data; - - return videobuf_poll_stream(file, &fh->vidq, wait); -} - -static int solo_enc_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct solo_enc_fh *fh = file->private_data; - - return videobuf_mmap_mapper(&fh->vidq, vma); -} - -static int solo_enc_open(struct file *file) -{ - struct solo_enc_dev *solo_enc = video_drvdata(file); - struct solo_enc_fh *fh; - - fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (fh == NULL) - return -ENOMEM; - - fh->enc = solo_enc; - file->private_data = fh; - INIT_LIST_HEAD(&fh->vidq_active); - fh->fmt = V4L2_PIX_FMT_MPEG; - fh->type = SOLO_ENC_TYPE_STD; - - videobuf_queue_sg_init(&fh->vidq, &solo_enc_video_qops, - &solo_enc->solo_dev->pdev->dev, - &solo_enc->lock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_INTERLACED, - sizeof(struct videobuf_buffer), fh, NULL); - - return 0; -} - -static ssize_t solo_enc_read(struct file *file, char __user *data, - size_t count, loff_t *ppos) -{ - struct solo_enc_fh *fh = file->private_data; - struct solo_enc_dev *solo_enc = fh->enc; - - /* Make sure the encoder is on */ - if (!fh->enc_on) { - int ret; - - spin_lock(&solo_enc->lock); - ret = solo_enc_on(fh); - spin_unlock(&solo_enc->lock); - if (ret) - return ret; - - ret = solo_start_fh_thread(fh); - if (ret) - return ret; - } - - return videobuf_read_stream(&fh->vidq, data, count, ppos, 0, - file->f_flags & O_NONBLOCK); -} - -static int solo_enc_release(struct file *file) -{ - struct solo_enc_fh *fh = file->private_data; - struct solo_enc_dev *solo_enc = fh->enc; - - videobuf_stop(&fh->vidq); - videobuf_mmap_free(&fh->vidq); - - spin_lock(&solo_enc->lock); - solo_enc_off(fh); - spin_unlock(&solo_enc->lock); - - kfree(fh); - - return 0; -} - -static int solo_enc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct solo_enc_fh *fh = priv; - struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; - - strcpy(cap->driver, SOLO6010_NAME); - snprintf(cap->card, sizeof(cap->card), "Softlogic 6010 Enc %d", - solo_enc->ch); - snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI %s", - pci_name(solo_dev->pdev)); - cap->version = SOLO6010_VER_NUM; - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING; - return 0; -} - -static int solo_enc_enum_input(struct file *file, void *priv, - struct v4l2_input *input) -{ - struct solo_enc_fh *fh = priv; - struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; - - if (input->index) - return -EINVAL; - - snprintf(input->name, sizeof(input->name), "Encoder %d", - solo_enc->ch + 1); - input->type = V4L2_INPUT_TYPE_CAMERA; - - if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) - input->std = V4L2_STD_NTSC_M; - else - input->std = V4L2_STD_PAL_B; - - if (!tw28_get_video_status(solo_dev, solo_enc->ch)) - input->status = V4L2_IN_ST_NO_SIGNAL; - - return 0; -} - -static int solo_enc_set_input(struct file *file, void *priv, unsigned int index) -{ - if (index) - return -EINVAL; - - return 0; -} - -static int solo_enc_get_input(struct file *file, void *priv, - unsigned int *index) -{ - *index = 0; - - return 0; -} - -static int solo_enc_enum_fmt_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - switch (f->index) { - case 0: - f->pixelformat = V4L2_PIX_FMT_MPEG; - strcpy(f->description, "MPEG-4 AVC"); - break; - case 1: - f->pixelformat = V4L2_PIX_FMT_MJPEG; - strcpy(f->description, "MJPEG"); - break; - default: - return -EINVAL; - } - - f->flags = V4L2_FMT_FLAG_COMPRESSED; - - return 0; -} - -static int solo_enc_try_fmt_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct solo_enc_fh *fh = priv; - struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; - struct v4l2_pix_format *pix = &f->fmt.pix; - - if (pix->pixelformat != V4L2_PIX_FMT_MPEG && - pix->pixelformat != V4L2_PIX_FMT_MJPEG) - return -EINVAL; - - /* We cannot change width/height in mid read */ - if (atomic_read(&solo_enc->readers) > 0) { - if (pix->width != solo_enc->width || - pix->height != solo_enc->height) - return -EBUSY; - } - - if (pix->width < solo_dev->video_hsize || - pix->height < solo_dev->video_vsize << 1) { - /* Default to CIF 1/2 size */ - pix->width = solo_dev->video_hsize >> 1; - pix->height = solo_dev->video_vsize; - } else { - /* Full frame */ - pix->width = solo_dev->video_hsize; - pix->height = solo_dev->video_vsize << 1; - } - - if (pix->field == V4L2_FIELD_ANY) - pix->field = V4L2_FIELD_INTERLACED; - else if (pix->field != V4L2_FIELD_INTERLACED) - pix->field = V4L2_FIELD_INTERLACED; - - /* Just set these */ - pix->colorspace = V4L2_COLORSPACE_SMPTE170M; - pix->sizeimage = FRAME_BUF_SIZE; - - return 0; -} - -static int solo_enc_set_fmt_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct solo_enc_fh *fh = priv; - struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; - struct v4l2_pix_format *pix = &f->fmt.pix; - int ret; - - spin_lock(&solo_enc->lock); - - ret = solo_enc_try_fmt_cap(file, priv, f); - if (ret) { - spin_unlock(&solo_enc->lock); - return ret; - } - - if (pix->width == solo_dev->video_hsize) - solo_enc->mode = SOLO_ENC_MODE_D1; - else - solo_enc->mode = SOLO_ENC_MODE_CIF; - - /* This does not change the encoder at all */ - fh->fmt = pix->pixelformat; - - if (pix->priv) - fh->type = SOLO_ENC_TYPE_EXT; - ret = solo_enc_on(fh); - - spin_unlock(&solo_enc->lock); - - if (ret) - return ret; - - return solo_start_fh_thread(fh); -} - -static int solo_enc_get_fmt_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct solo_enc_fh *fh = priv; - struct solo_enc_dev *solo_enc = fh->enc; - struct v4l2_pix_format *pix = &f->fmt.pix; - - pix->width = solo_enc->width; - pix->height = solo_enc->height; - pix->pixelformat = fh->fmt; - pix->field = solo_enc->interlaced ? V4L2_FIELD_INTERLACED : - V4L2_FIELD_NONE; - pix->sizeimage = FRAME_BUF_SIZE; - pix->colorspace = V4L2_COLORSPACE_SMPTE170M; - - return 0; -} - -static int solo_enc_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *req) -{ - struct solo_enc_fh *fh = priv; - - return videobuf_reqbufs(&fh->vidq, req); -} - -static int solo_enc_querybuf(struct file *file, void *priv, - struct v4l2_buffer *buf) -{ - struct solo_enc_fh *fh = priv; - - return videobuf_querybuf(&fh->vidq, buf); -} - -static int solo_enc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) -{ - struct solo_enc_fh *fh = priv; - - return videobuf_qbuf(&fh->vidq, buf); -} - -static int solo_enc_dqbuf(struct file *file, void *priv, - struct v4l2_buffer *buf) -{ - struct solo_enc_fh *fh = priv; - struct solo_enc_dev *solo_enc = fh->enc; - int ret; - - /* Make sure the encoder is on */ - if (!fh->enc_on) { - spin_lock(&solo_enc->lock); - ret = solo_enc_on(fh); - spin_unlock(&solo_enc->lock); - if (ret) - return ret; - - ret = solo_start_fh_thread(fh); - if (ret) - return ret; - } - - ret = videobuf_dqbuf(&fh->vidq, buf, file->f_flags & O_NONBLOCK); - if (ret) - return ret; - - /* Signal motion detection */ - if (solo_is_motion_on(solo_enc)) { - buf->flags |= V4L2_BUF_FLAG_MOTION_ON; - if (solo_enc->motion_detected) { - buf->flags |= V4L2_BUF_FLAG_MOTION_DETECTED; - solo_reg_write(solo_enc->solo_dev, SOLO_VI_MOT_CLEAR, - 1 << solo_enc->ch); - solo_enc->motion_detected = 0; - } - } - - /* Check for key frame on mpeg data */ - if (fh->fmt == V4L2_PIX_FMT_MPEG) { - struct videobuf_dmabuf *vbuf = - videobuf_to_dma(fh->vidq.bufs[buf->index]); - - if (vbuf) { - u8 *p = sg_virt(vbuf->sglist); - if (p[3] == 0x00) - buf->flags |= V4L2_BUF_FLAG_KEYFRAME; - else - buf->flags |= V4L2_BUF_FLAG_PFRAME; - } - } - - return 0; -} - -static int solo_enc_streamon(struct file *file, void *priv, - enum v4l2_buf_type i) -{ - struct solo_enc_fh *fh = priv; - - if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - return videobuf_streamon(&fh->vidq); -} - -static int solo_enc_streamoff(struct file *file, void *priv, - enum v4l2_buf_type i) -{ - struct solo_enc_fh *fh = priv; - - if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - return videobuf_streamoff(&fh->vidq); -} - -static int solo_enc_s_std(struct file *file, void *priv, v4l2_std_id *i) -{ - return 0; -} - -static int solo_enum_framesizes(struct file *file, void *priv, - struct v4l2_frmsizeenum *fsize) -{ - struct solo_enc_fh *fh = priv; - struct solo6010_dev *solo_dev = fh->enc->solo_dev; - - if (fsize->pixel_format != V4L2_PIX_FMT_MPEG) - return -EINVAL; - - switch (fsize->index) { - case 0: - fsize->discrete.width = solo_dev->video_hsize >> 1; - fsize->discrete.height = solo_dev->video_vsize; - break; - case 1: - fsize->discrete.width = solo_dev->video_hsize; - fsize->discrete.height = solo_dev->video_vsize << 1; - break; - default: - return -EINVAL; - } - - fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; - - return 0; -} - -static int solo_enum_frameintervals(struct file *file, void *priv, - struct v4l2_frmivalenum *fintv) -{ - struct solo_enc_fh *fh = priv; - struct solo6010_dev *solo_dev = fh->enc->solo_dev; - - if (fintv->pixel_format != V4L2_PIX_FMT_MPEG || fintv->index) - return -EINVAL; - - fintv->type = V4L2_FRMIVAL_TYPE_STEPWISE; - - fintv->stepwise.min.numerator = solo_dev->fps; - fintv->stepwise.min.denominator = 1; - - fintv->stepwise.max.numerator = solo_dev->fps; - fintv->stepwise.max.denominator = 15; - - fintv->stepwise.step.numerator = 1; - fintv->stepwise.step.denominator = 1; - - return 0; -} - -static int solo_g_parm(struct file *file, void *priv, - struct v4l2_streamparm *sp) -{ - struct solo_enc_fh *fh = priv; - struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; - struct v4l2_captureparm *cp = &sp->parm.capture; - - cp->capability = V4L2_CAP_TIMEPERFRAME; - cp->timeperframe.numerator = solo_enc->interval; - cp->timeperframe.denominator = solo_dev->fps; - cp->capturemode = 0; - /* XXX: Shouldn't we be able to get/set this from videobuf? */ - cp->readbuffers = 2; - - return 0; -} - -static int solo_s_parm(struct file *file, void *priv, - struct v4l2_streamparm *sp) -{ - struct solo_enc_fh *fh = priv; - struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; - struct v4l2_captureparm *cp = &sp->parm.capture; - - spin_lock(&solo_enc->lock); - - if (atomic_read(&solo_enc->readers) > 0) { - spin_unlock(&solo_enc->lock); - return -EBUSY; - } - - if ((cp->timeperframe.numerator == 0) || - (cp->timeperframe.denominator == 0)) { - /* reset framerate */ - cp->timeperframe.numerator = 1; - cp->timeperframe.denominator = solo_dev->fps; - } - - if (cp->timeperframe.denominator != solo_dev->fps) - cp->timeperframe.denominator = solo_dev->fps; - - if (cp->timeperframe.numerator > 15) - cp->timeperframe.numerator = 15; - - solo_enc->interval = cp->timeperframe.numerator; - - cp->capability = V4L2_CAP_TIMEPERFRAME; - - solo_enc->gop = max(solo_dev->fps / solo_enc->interval, 1); - solo_update_mode(solo_enc); - - spin_unlock(&solo_enc->lock); - - return 0; -} - -static int solo_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qc) -{ - struct solo_enc_fh *fh = priv; - struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; - - qc->id = v4l2_ctrl_next(solo_ctrl_classes, qc->id); - if (!qc->id) - return -EINVAL; - - switch (qc->id) { - case V4L2_CID_BRIGHTNESS: - case V4L2_CID_CONTRAST: - case V4L2_CID_SATURATION: - case V4L2_CID_HUE: - return v4l2_ctrl_query_fill(qc, 0x00, 0xff, 1, 0x80); - case V4L2_CID_SHARPNESS: - return v4l2_ctrl_query_fill(qc, 0x00, 0x0f, 1, 0x00); - case V4L2_CID_MPEG_VIDEO_ENCODING: - return v4l2_ctrl_query_fill( - qc, V4L2_MPEG_VIDEO_ENCODING_MPEG_1, - V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1, - V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC); - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - return v4l2_ctrl_query_fill(qc, 1, 255, 1, solo_dev->fps); -#ifdef PRIVATE_CIDS - case V4L2_CID_MOTION_THRESHOLD: - qc->flags |= V4L2_CTRL_FLAG_SLIDER; - qc->type = V4L2_CTRL_TYPE_INTEGER; - qc->minimum = 0; - qc->maximum = 0xffff; - qc->step = 1; - qc->default_value = SOLO_DEF_MOT_THRESH; - strlcpy(qc->name, "Motion Detection Threshold", - sizeof(qc->name)); - return 0; - case V4L2_CID_MOTION_ENABLE: - qc->type = V4L2_CTRL_TYPE_BOOLEAN; - qc->minimum = 0; - qc->maximum = qc->step = 1; - qc->default_value = 0; - strlcpy(qc->name, "Motion Detection Enable", sizeof(qc->name)); - return 0; -#else - case V4L2_CID_MOTION_THRESHOLD: - return v4l2_ctrl_query_fill(qc, 0, 0xffff, 1, - SOLO_DEF_MOT_THRESH); - case V4L2_CID_MOTION_ENABLE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); -#endif - case V4L2_CID_RDS_TX_RADIO_TEXT: - qc->type = V4L2_CTRL_TYPE_STRING; - qc->minimum = 0; - qc->maximum = OSD_TEXT_MAX; - qc->step = 1; - qc->default_value = 0; - strlcpy(qc->name, "OSD Text", sizeof(qc->name)); - return 0; - } - - return -EINVAL; -} - -static int solo_querymenu(struct file *file, void *priv, - struct v4l2_querymenu *qmenu) -{ - struct v4l2_queryctrl qctrl; - int err; - - qctrl.id = qmenu->id; - err = solo_queryctrl(file, priv, &qctrl); - if (err) - return err; - - return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL); -} - -static int solo_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct solo_enc_fh *fh = priv; - struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - case V4L2_CID_CONTRAST: - case V4L2_CID_SATURATION: - case V4L2_CID_HUE: - case V4L2_CID_SHARPNESS: - return tw28_get_ctrl_val(solo_dev, ctrl->id, solo_enc->ch, - &ctrl->value); - case V4L2_CID_MPEG_VIDEO_ENCODING: - ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC; - break; - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - ctrl->value = solo_enc->gop; - break; - case V4L2_CID_MOTION_THRESHOLD: - ctrl->value = solo_enc->motion_thresh; - break; - case V4L2_CID_MOTION_ENABLE: - ctrl->value = solo_is_motion_on(solo_enc); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int solo_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct solo_enc_fh *fh = priv; - struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - case V4L2_CID_CONTRAST: - case V4L2_CID_SATURATION: - case V4L2_CID_HUE: - case V4L2_CID_SHARPNESS: - return tw28_set_ctrl_val(solo_dev, ctrl->id, solo_enc->ch, - ctrl->value); - case V4L2_CID_MPEG_VIDEO_ENCODING: - if (ctrl->value != V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC) - return -ERANGE; - break; - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - if (ctrl->value < 1 || ctrl->value > 255) - return -ERANGE; - solo_enc->gop = ctrl->value; - solo_reg_write(solo_dev, SOLO_VE_CH_GOP(solo_enc->ch), - solo_enc->gop); - solo_reg_write(solo_dev, SOLO_VE_CH_GOP_E(solo_enc->ch), - solo_enc->gop); - break; - case V4L2_CID_MOTION_THRESHOLD: - /* TODO accept value on lower 16-bits and use high - * 16-bits to assign the value to a specific block */ - if (ctrl->value < 0 || ctrl->value > 0xffff) - return -ERANGE; - solo_enc->motion_thresh = ctrl->value; - solo_set_motion_threshold(solo_dev, solo_enc->ch, ctrl->value); - break; - case V4L2_CID_MOTION_ENABLE: - solo_motion_toggle(solo_enc, ctrl->value); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int solo_s_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - struct solo_enc_fh *fh = priv; - struct solo_enc_dev *solo_enc = fh->enc; - int i; - - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = (ctrls->controls + i); - int err; - - switch (ctrl->id) { - case V4L2_CID_RDS_TX_RADIO_TEXT: - if (ctrl->size - 1 > OSD_TEXT_MAX) - err = -ERANGE; - else { - err = copy_from_user(solo_enc->osd_text, - ctrl->string, - OSD_TEXT_MAX); - solo_enc->osd_text[OSD_TEXT_MAX] = '\0'; - if (!err) - err = solo_osd_print(solo_enc); - } - break; - default: - err = -EINVAL; - } - - if (err < 0) { - ctrls->error_idx = i; - return err; - } - } - - return 0; -} - -static int solo_g_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *ctrls) -{ - struct solo_enc_fh *fh = priv; - struct solo_enc_dev *solo_enc = fh->enc; - int i; - - for (i = 0; i < ctrls->count; i++) { - struct v4l2_ext_control *ctrl = (ctrls->controls + i); - int err; - - switch (ctrl->id) { - case V4L2_CID_RDS_TX_RADIO_TEXT: - if (ctrl->size < OSD_TEXT_MAX) { - ctrl->size = OSD_TEXT_MAX; - err = -ENOSPC; - } else { - err = copy_to_user(ctrl->string, - solo_enc->osd_text, - OSD_TEXT_MAX); - } - break; - default: - err = -EINVAL; - } - - if (err < 0) { - ctrls->error_idx = i; - return err; - } - } - - return 0; -} - -static const struct v4l2_file_operations solo_enc_fops = { - .owner = THIS_MODULE, - .open = solo_enc_open, - .release = solo_enc_release, - .read = solo_enc_read, - .poll = solo_enc_poll, - .mmap = solo_enc_mmap, - .ioctl = video_ioctl2, -}; - -static const struct v4l2_ioctl_ops solo_enc_ioctl_ops = { - .vidioc_querycap = solo_enc_querycap, - .vidioc_s_std = solo_enc_s_std, - /* Input callbacks */ - .vidioc_enum_input = solo_enc_enum_input, - .vidioc_s_input = solo_enc_set_input, - .vidioc_g_input = solo_enc_get_input, - /* Video capture format callbacks */ - .vidioc_enum_fmt_vid_cap = solo_enc_enum_fmt_cap, - .vidioc_try_fmt_vid_cap = solo_enc_try_fmt_cap, - .vidioc_s_fmt_vid_cap = solo_enc_set_fmt_cap, - .vidioc_g_fmt_vid_cap = solo_enc_get_fmt_cap, - /* Streaming I/O */ - .vidioc_reqbufs = solo_enc_reqbufs, - .vidioc_querybuf = solo_enc_querybuf, - .vidioc_qbuf = solo_enc_qbuf, - .vidioc_dqbuf = solo_enc_dqbuf, - .vidioc_streamon = solo_enc_streamon, - .vidioc_streamoff = solo_enc_streamoff, - /* Frame size and interval */ - .vidioc_enum_framesizes = solo_enum_framesizes, - .vidioc_enum_frameintervals = solo_enum_frameintervals, - /* Video capture parameters */ - .vidioc_s_parm = solo_s_parm, - .vidioc_g_parm = solo_g_parm, - /* Controls */ - .vidioc_queryctrl = solo_queryctrl, - .vidioc_querymenu = solo_querymenu, - .vidioc_g_ctrl = solo_g_ctrl, - .vidioc_s_ctrl = solo_s_ctrl, - .vidioc_g_ext_ctrls = solo_g_ext_ctrls, - .vidioc_s_ext_ctrls = solo_s_ext_ctrls, -}; - -static struct video_device solo_enc_template = { - .name = SOLO6010_NAME, - .fops = &solo_enc_fops, - .ioctl_ops = &solo_enc_ioctl_ops, - .minor = -1, - .release = video_device_release, - - .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL_B, - .current_norm = V4L2_STD_NTSC_M, -}; - -static struct solo_enc_dev *solo_enc_alloc(struct solo6010_dev *solo_dev, u8 ch) -{ - struct solo_enc_dev *solo_enc; - int ret; - - solo_enc = kzalloc(sizeof(*solo_enc), GFP_KERNEL); - if (!solo_enc) - return ERR_PTR(-ENOMEM); - - solo_enc->vfd = video_device_alloc(); - if (!solo_enc->vfd) { - kfree(solo_enc); - return ERR_PTR(-ENOMEM); - } - - solo_enc->solo_dev = solo_dev; - solo_enc->ch = ch; - - *solo_enc->vfd = solo_enc_template; - solo_enc->vfd->parent = &solo_dev->pdev->dev; - ret = video_register_device(solo_enc->vfd, VFL_TYPE_GRABBER, - video_nr); - if (ret < 0) { - video_device_release(solo_enc->vfd); - kfree(solo_enc); - return ERR_PTR(ret); - } - - video_set_drvdata(solo_enc->vfd, solo_enc); - - snprintf(solo_enc->vfd->name, sizeof(solo_enc->vfd->name), - "%s-enc (%i/%i)", SOLO6010_NAME, solo_dev->vfd->num, - solo_enc->vfd->num); - - if (video_nr != -1) - video_nr++; - - spin_lock_init(&solo_enc->lock); - init_waitqueue_head(&solo_enc->thread_wait); - atomic_set(&solo_enc->readers, 0); - - solo_enc->qp = SOLO_DEFAULT_QP; - solo_enc->gop = solo_dev->fps; - solo_enc->interval = 1; - solo_enc->mode = SOLO_ENC_MODE_CIF; - solo_enc->motion_thresh = SOLO_DEF_MOT_THRESH; - - spin_lock(&solo_enc->lock); - solo_update_mode(solo_enc); - spin_unlock(&solo_enc->lock); - - return solo_enc; -} - -static void solo_enc_free(struct solo_enc_dev *solo_enc) -{ - if (solo_enc == NULL) - return; - - video_unregister_device(solo_enc->vfd); - kfree(solo_enc); -} - -int solo_enc_v4l2_init(struct solo6010_dev *solo_dev) -{ - int i; - - for (i = 0; i < solo_dev->nr_chans; i++) { - solo_dev->v4l2_enc[i] = solo_enc_alloc(solo_dev, i); - if (IS_ERR(solo_dev->v4l2_enc[i])) - break; - } - - if (i != solo_dev->nr_chans) { - int ret = PTR_ERR(solo_dev->v4l2_enc[i]); - while (i--) - solo_enc_free(solo_dev->v4l2_enc[i]); - return ret; - } - - /* D1@MAX-FPS * 4 */ - solo_dev->enc_bw_remain = solo_dev->fps * 4 * 4; - - dev_info(&solo_dev->pdev->dev, "Encoders as /dev/video%d-%d\n", - solo_dev->v4l2_enc[0]->vfd->num, - solo_dev->v4l2_enc[solo_dev->nr_chans - 1]->vfd->num); - - return 0; -} - -void solo_enc_v4l2_exit(struct solo6010_dev *solo_dev) -{ - int i; - - solo6010_irq_off(solo_dev, SOLO_IRQ_MOTION); - - for (i = 0; i < solo_dev->nr_chans; i++) - solo_enc_free(solo_dev->v4l2_enc[i]); -} diff --git a/drivers/staging/solo6x10/solo6010-v4l2.c b/drivers/staging/solo6x10/solo6010-v4l2.c deleted file mode 100644 index 4e24e928eb02..000000000000 --- a/drivers/staging/solo6x10/solo6010-v4l2.c +++ /dev/null @@ -1,966 +0,0 @@ -/* - * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com - * Copyright (C) 2010 Ben Collins - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include "solo6010.h" -#include "solo6010-tw28.h" - -#define SOLO_HW_BPL 2048 -#define SOLO_DISP_PIX_FIELD V4L2_FIELD_INTERLACED - -/* Image size is two fields, SOLO_HW_BPL is one horizontal line */ -#define solo_vlines(__solo) (__solo->video_vsize * 2) -#define solo_image_size(__solo) (solo_bytesperline(__solo) * \ - solo_vlines(__solo)) -#define solo_bytesperline(__solo) (__solo->video_hsize * 2) - -#define MIN_VID_BUFFERS 4 - -/* Simple file handle */ -struct solo_filehandle { - struct solo6010_dev *solo_dev; - struct videobuf_queue vidq; - struct task_struct *kthread; - spinlock_t slock; - int old_write; - struct list_head vidq_active; - struct p2m_desc desc[SOLO_NR_P2M_DESC]; - int desc_idx; -}; - -unsigned video_nr = -1; -module_param(video_nr, uint, 0644); -MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect (default)"); - -static void erase_on(struct solo6010_dev *solo_dev) -{ - solo_reg_write(solo_dev, SOLO_VO_DISP_ERASE, SOLO_VO_DISP_ERASE_ON); - solo_dev->erasing = 1; - solo_dev->frame_blank = 0; -} - -static int erase_off(struct solo6010_dev *solo_dev) -{ - if (!solo_dev->erasing) - return 0; - - /* First time around, assert erase off */ - if (!solo_dev->frame_blank) - solo_reg_write(solo_dev, SOLO_VO_DISP_ERASE, 0); - /* Keep the erasing flag on for 8 frames minimum */ - if (solo_dev->frame_blank++ >= 8) - solo_dev->erasing = 0; - - return 1; -} - -void solo_video_in_isr(struct solo6010_dev *solo_dev) -{ - solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_VIDEO_IN); - wake_up_interruptible(&solo_dev->disp_thread_wait); -} - -static void solo_win_setup(struct solo6010_dev *solo_dev, u8 ch, - int sx, int sy, int ex, int ey, int scale) -{ - if (ch >= solo_dev->nr_chans) - return; - - /* Here, we just keep window/channel the same */ - solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL0(ch), - SOLO_VI_WIN_CHANNEL(ch) | - SOLO_VI_WIN_SX(sx) | - SOLO_VI_WIN_EX(ex) | - SOLO_VI_WIN_SCALE(scale)); - - solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL1(ch), - SOLO_VI_WIN_SY(sy) | - SOLO_VI_WIN_EY(ey)); -} - -static int solo_v4l2_ch_ext_4up(struct solo6010_dev *solo_dev, u8 idx, int on) -{ - u8 ch = idx * 4; - - if (ch >= solo_dev->nr_chans) - return -EINVAL; - - if (!on) { - u8 i; - for (i = ch; i < ch + 4; i++) - solo_win_setup(solo_dev, i, solo_dev->video_hsize, - solo_vlines(solo_dev), - solo_dev->video_hsize, - solo_vlines(solo_dev), 0); - return 0; - } - - /* Row 1 */ - solo_win_setup(solo_dev, ch, 0, 0, solo_dev->video_hsize / 2, - solo_vlines(solo_dev) / 2, 3); - solo_win_setup(solo_dev, ch + 1, solo_dev->video_hsize / 2, 0, - solo_dev->video_hsize, solo_vlines(solo_dev) / 2, 3); - /* Row 2 */ - solo_win_setup(solo_dev, ch + 2, 0, solo_vlines(solo_dev) / 2, - solo_dev->video_hsize / 2, solo_vlines(solo_dev), 3); - solo_win_setup(solo_dev, ch + 3, solo_dev->video_hsize / 2, - solo_vlines(solo_dev) / 2, solo_dev->video_hsize, - solo_vlines(solo_dev), 3); - - return 0; -} - -static int solo_v4l2_ch_ext_16up(struct solo6010_dev *solo_dev, int on) -{ - int sy, ysize, hsize, i; - - if (!on) { - for (i = 0; i < 16; i++) - solo_win_setup(solo_dev, i, solo_dev->video_hsize, - solo_vlines(solo_dev), - solo_dev->video_hsize, - solo_vlines(solo_dev), 0); - return 0; - } - - ysize = solo_vlines(solo_dev) / 4; - hsize = solo_dev->video_hsize / 4; - - for (sy = 0, i = 0; i < 4; i++, sy += ysize) { - solo_win_setup(solo_dev, i * 4, 0, sy, hsize, - sy + ysize, 5); - solo_win_setup(solo_dev, (i * 4) + 1, hsize, sy, - hsize * 2, sy + ysize, 5); - solo_win_setup(solo_dev, (i * 4) + 2, hsize * 2, sy, - hsize * 3, sy + ysize, 5); - solo_win_setup(solo_dev, (i * 4) + 3, hsize * 3, sy, - solo_dev->video_hsize, sy + ysize, 5); - } - - return 0; -} - -static int solo_v4l2_ch(struct solo6010_dev *solo_dev, u8 ch, int on) -{ - u8 ext_ch; - - if (ch < solo_dev->nr_chans) { - solo_win_setup(solo_dev, ch, on ? 0 : solo_dev->video_hsize, - on ? 0 : solo_vlines(solo_dev), - solo_dev->video_hsize, solo_vlines(solo_dev), - on ? 1 : 0); - return 0; - } - - if (ch >= solo_dev->nr_chans + solo_dev->nr_ext) - return -EINVAL; - - ext_ch = ch - solo_dev->nr_chans; - - /* 4up's first */ - if (ext_ch < 4) - return solo_v4l2_ch_ext_4up(solo_dev, ext_ch, on); - - /* Remaining case is 16up for 16-port */ - return solo_v4l2_ch_ext_16up(solo_dev, on); -} - -static int solo_v4l2_set_ch(struct solo6010_dev *solo_dev, u8 ch) -{ - if (ch >= solo_dev->nr_chans + solo_dev->nr_ext) - return -EINVAL; - - erase_on(solo_dev); - - solo_v4l2_ch(solo_dev, solo_dev->cur_disp_ch, 0); - solo_v4l2_ch(solo_dev, ch, 1); - - solo_dev->cur_disp_ch = ch; - - return 0; -} - -static void disp_reset_desc(struct solo_filehandle *fh) -{ - /* We use desc mode, which ignores desc 0 */ - memset(fh->desc, 0, sizeof(*fh->desc)); - fh->desc_idx = 1; -} - -static int disp_flush_descs(struct solo_filehandle *fh) -{ - int ret; - - if (!fh->desc_idx) - return 0; - - ret = solo_p2m_dma_desc(fh->solo_dev, SOLO_P2M_DMA_ID_DISP, - fh->desc, fh->desc_idx); - disp_reset_desc(fh); - - return ret; -} - -static int disp_push_desc(struct solo_filehandle *fh, dma_addr_t dma_addr, - u32 ext_addr, int size, int repeat, int ext_size) -{ - if (fh->desc_idx >= SOLO_NR_P2M_DESC) { - int ret = disp_flush_descs(fh); - if (ret) - return ret; - } - - solo_p2m_push_desc(&fh->desc[fh->desc_idx], 0, dma_addr, ext_addr, - size, repeat, ext_size); - fh->desc_idx++; - - return 0; -} - -static void solo_fillbuf(struct solo_filehandle *fh, - struct videobuf_buffer *vb) -{ - struct solo6010_dev *solo_dev = fh->solo_dev; - struct videobuf_dmabuf *vbuf; - unsigned int fdma_addr; - int error = 1; - int i; - struct scatterlist *sg; - dma_addr_t sg_dma; - int sg_size_left; - - vbuf = videobuf_to_dma(vb); - if (!vbuf) - goto finish_buf; - - if (erase_off(solo_dev)) { - int i; - - /* Just blit to the entire sg list, ignoring size */ - for_each_sg(vbuf->sglist, sg, vbuf->sglen, i) { - void *p = sg_virt(sg); - size_t len = sg_dma_len(sg); - - for (i = 0; i < len; i += 2) { - ((u8 *)p)[i] = 0x80; - ((u8 *)p)[i + 1] = 0x00; - } - } - - error = 0; - goto finish_buf; - } - - disp_reset_desc(fh); - sg = vbuf->sglist; - sg_dma = sg_dma_address(sg); - sg_size_left = sg_dma_len(sg); - - fdma_addr = SOLO_DISP_EXT_ADDR + (fh->old_write * - (SOLO_HW_BPL * solo_vlines(solo_dev))); - - for (i = 0; i < solo_vlines(solo_dev); i++) { - int line_len = solo_bytesperline(solo_dev); - int lines; - - if (!sg_size_left) { - sg = sg_next(sg); - if (sg == NULL) - goto finish_buf; - sg_dma = sg_dma_address(sg); - sg_size_left = sg_dma_len(sg); - } - - /* No room for an entire line, so chunk it up */ - if (sg_size_left < line_len) { - int this_addr = fdma_addr; - - while (line_len > 0) { - int this_write; - - if (!sg_size_left) { - sg = sg_next(sg); - if (sg == NULL) - goto finish_buf; - sg_dma = sg_dma_address(sg); - sg_size_left = sg_dma_len(sg); - } - - this_write = min(sg_size_left, line_len); - - if (disp_push_desc(fh, sg_dma, this_addr, - this_write, 0, 0)) - goto finish_buf; - - line_len -= this_write; - sg_size_left -= this_write; - sg_dma += this_write; - this_addr += this_write; - } - - fdma_addr += SOLO_HW_BPL; - continue; - } - - /* Shove as many lines into a repeating descriptor as possible */ - lines = min(sg_size_left / line_len, - solo_vlines(solo_dev) - i); - - if (disp_push_desc(fh, sg_dma, fdma_addr, line_len, - lines - 1, SOLO_HW_BPL)) - goto finish_buf; - - i += lines - 1; - fdma_addr += SOLO_HW_BPL * lines; - sg_dma += lines * line_len; - sg_size_left -= lines * line_len; - } - - error = disp_flush_descs(fh); - -finish_buf: - if (error) { - vb->state = VIDEOBUF_ERROR; - } else { - vb->size = solo_vlines(solo_dev) * solo_bytesperline(solo_dev); - vb->state = VIDEOBUF_DONE; - vb->field_count++; - do_gettimeofday(&vb->ts); - } - - wake_up(&vb->done); - - return; -} - -static void solo_thread_try(struct solo_filehandle *fh) -{ - struct videobuf_buffer *vb; - unsigned int cur_write; - - for (;;) { - spin_lock(&fh->slock); - - if (list_empty(&fh->vidq_active)) - break; - - vb = list_first_entry(&fh->vidq_active, struct videobuf_buffer, - queue); - - if (!waitqueue_active(&vb->done)) - break; - - cur_write = SOLO_VI_STATUS0_PAGE(solo_reg_read(fh->solo_dev, - SOLO_VI_STATUS0)); - if (cur_write == fh->old_write) - break; - - fh->old_write = cur_write; - list_del(&vb->queue); - - spin_unlock(&fh->slock); - - solo_fillbuf(fh, vb); - } - - assert_spin_locked(&fh->slock); - spin_unlock(&fh->slock); -} - -static int solo_thread(void *data) -{ - struct solo_filehandle *fh = data; - struct solo6010_dev *solo_dev = fh->solo_dev; - DECLARE_WAITQUEUE(wait, current); - - set_freezable(); - add_wait_queue(&solo_dev->disp_thread_wait, &wait); - - for (;;) { - long timeout = schedule_timeout_interruptible(HZ); - if (timeout == -ERESTARTSYS || kthread_should_stop()) - break; - solo_thread_try(fh); - try_to_freeze(); - } - - remove_wait_queue(&solo_dev->disp_thread_wait, &wait); - - return 0; -} - -static int solo_start_thread(struct solo_filehandle *fh) -{ - fh->kthread = kthread_run(solo_thread, fh, SOLO6010_NAME "_disp"); - - if (IS_ERR(fh->kthread)) - return PTR_ERR(fh->kthread); - - return 0; -} - -static void solo_stop_thread(struct solo_filehandle *fh) -{ - if (fh->kthread) { - kthread_stop(fh->kthread); - fh->kthread = NULL; - } -} - -static int solo_buf_setup(struct videobuf_queue *vq, unsigned int *count, - unsigned int *size) -{ - struct solo_filehandle *fh = vq->priv_data; - struct solo6010_dev *solo_dev = fh->solo_dev; - - *size = solo_image_size(solo_dev); - - if (*count < MIN_VID_BUFFERS) - *count = MIN_VID_BUFFERS; - - return 0; -} - -static int solo_buf_prepare(struct videobuf_queue *vq, - struct videobuf_buffer *vb, enum v4l2_field field) -{ - struct solo_filehandle *fh = vq->priv_data; - struct solo6010_dev *solo_dev = fh->solo_dev; - - vb->size = solo_image_size(solo_dev); - if (vb->baddr != 0 && vb->bsize < vb->size) - return -EINVAL; - - /* XXX: These properties only change when queue is idle */ - vb->width = solo_dev->video_hsize; - vb->height = solo_vlines(solo_dev); - vb->bytesperline = solo_bytesperline(solo_dev); - vb->field = field; - - if (vb->state == VIDEOBUF_NEEDS_INIT) { - int rc = videobuf_iolock(vq, vb, NULL); - if (rc < 0) { - struct videobuf_dmabuf *dma = videobuf_to_dma(vb); - videobuf_dma_unmap(vq->dev, dma); - videobuf_dma_free(dma); - vb->state = VIDEOBUF_NEEDS_INIT; - return rc; - } - } - vb->state = VIDEOBUF_PREPARED; - - return 0; -} - -static void solo_buf_queue(struct videobuf_queue *vq, - struct videobuf_buffer *vb) -{ - struct solo_filehandle *fh = vq->priv_data; - struct solo6010_dev *solo_dev = fh->solo_dev; - - vb->state = VIDEOBUF_QUEUED; - list_add_tail(&vb->queue, &fh->vidq_active); - wake_up_interruptible(&solo_dev->disp_thread_wait); -} - -static void solo_buf_release(struct videobuf_queue *vq, - struct videobuf_buffer *vb) -{ - struct videobuf_dmabuf *dma = videobuf_to_dma(vb); - - videobuf_dma_unmap(vq->dev, dma); - videobuf_dma_free(dma); - vb->state = VIDEOBUF_NEEDS_INIT; -} - -static struct videobuf_queue_ops solo_video_qops = { - .buf_setup = solo_buf_setup, - .buf_prepare = solo_buf_prepare, - .buf_queue = solo_buf_queue, - .buf_release = solo_buf_release, -}; - -static unsigned int solo_v4l2_poll(struct file *file, - struct poll_table_struct *wait) -{ - struct solo_filehandle *fh = file->private_data; - - return videobuf_poll_stream(file, &fh->vidq, wait); -} - -static int solo_v4l2_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct solo_filehandle *fh = file->private_data; - - return videobuf_mmap_mapper(&fh->vidq, vma); -} - -static int solo_v4l2_open(struct file *file) -{ - struct solo6010_dev *solo_dev = video_drvdata(file); - struct solo_filehandle *fh; - int ret; - - fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (fh == NULL) - return -ENOMEM; - - spin_lock_init(&fh->slock); - INIT_LIST_HEAD(&fh->vidq_active); - fh->solo_dev = solo_dev; - file->private_data = fh; - - ret = solo_start_thread(fh); - if (ret) { - kfree(fh); - return ret; - } - - videobuf_queue_sg_init(&fh->vidq, &solo_video_qops, - &solo_dev->pdev->dev, &fh->slock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - SOLO_DISP_PIX_FIELD, - sizeof(struct videobuf_buffer), fh, NULL); - - return 0; -} - -static ssize_t solo_v4l2_read(struct file *file, char __user *data, - size_t count, loff_t *ppos) -{ - struct solo_filehandle *fh = file->private_data; - - return videobuf_read_stream(&fh->vidq, data, count, ppos, 0, - file->f_flags & O_NONBLOCK); -} - -static int solo_v4l2_release(struct file *file) -{ - struct solo_filehandle *fh = file->private_data; - - videobuf_stop(&fh->vidq); - videobuf_mmap_free(&fh->vidq); - solo_stop_thread(fh); - kfree(fh); - - return 0; -} - -static int solo_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct solo_filehandle *fh = priv; - struct solo6010_dev *solo_dev = fh->solo_dev; - - strcpy(cap->driver, SOLO6010_NAME); - strcpy(cap->card, "Softlogic 6010"); - snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI %s", - pci_name(solo_dev->pdev)); - cap->version = SOLO6010_VER_NUM; - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING; - return 0; -} - -static int solo_enum_ext_input(struct solo6010_dev *solo_dev, - struct v4l2_input *input) -{ - static const char *dispnames_1[] = { "4UP" }; - static const char *dispnames_2[] = { "4UP-1", "4UP-2" }; - static const char *dispnames_5[] = { - "4UP-1", "4UP-2", "4UP-3", "4UP-4", "16UP" - }; - const char **dispnames; - - if (input->index >= (solo_dev->nr_chans + solo_dev->nr_ext)) - return -EINVAL; - - if (solo_dev->nr_ext == 5) - dispnames = dispnames_5; - else if (solo_dev->nr_ext == 2) - dispnames = dispnames_2; - else - dispnames = dispnames_1; - - snprintf(input->name, sizeof(input->name), "Multi %s", - dispnames[input->index - solo_dev->nr_chans]); - - return 0; -} - -static int solo_enum_input(struct file *file, void *priv, - struct v4l2_input *input) -{ - struct solo_filehandle *fh = priv; - struct solo6010_dev *solo_dev = fh->solo_dev; - - if (input->index >= solo_dev->nr_chans) { - int ret = solo_enum_ext_input(solo_dev, input); - if (ret < 0) - return ret; - } else { - snprintf(input->name, sizeof(input->name), "Camera %d", - input->index + 1); - - /* We can only check this for normal inputs */ - if (!tw28_get_video_status(solo_dev, input->index)) - input->status = V4L2_IN_ST_NO_SIGNAL; - } - - input->type = V4L2_INPUT_TYPE_CAMERA; - - if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) - input->std = V4L2_STD_NTSC_M; - else - input->std = V4L2_STD_PAL_B; - - return 0; -} - -static int solo_set_input(struct file *file, void *priv, unsigned int index) -{ - struct solo_filehandle *fh = priv; - - return solo_v4l2_set_ch(fh->solo_dev, index); -} - -static int solo_get_input(struct file *file, void *priv, unsigned int *index) -{ - struct solo_filehandle *fh = priv; - - *index = fh->solo_dev->cur_disp_ch; - - return 0; -} - -static int solo_enum_fmt_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - if (f->index) - return -EINVAL; - - f->pixelformat = V4L2_PIX_FMT_UYVY; - strlcpy(f->description, "UYUV 4:2:2 Packed", sizeof(f->description)); - - return 0; -} - -static int solo_try_fmt_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct solo_filehandle *fh = priv; - struct solo6010_dev *solo_dev = fh->solo_dev; - struct v4l2_pix_format *pix = &f->fmt.pix; - int image_size = solo_image_size(solo_dev); - - /* Check supported sizes */ - if (pix->width != solo_dev->video_hsize) - pix->width = solo_dev->video_hsize; - if (pix->height != solo_vlines(solo_dev)) - pix->height = solo_vlines(solo_dev); - if (pix->sizeimage != image_size) - pix->sizeimage = image_size; - - /* Check formats */ - if (pix->field == V4L2_FIELD_ANY) - pix->field = SOLO_DISP_PIX_FIELD; - - if (pix->pixelformat != V4L2_PIX_FMT_UYVY || - pix->field != SOLO_DISP_PIX_FIELD || - pix->colorspace != V4L2_COLORSPACE_SMPTE170M) - return -EINVAL; - - return 0; -} - -static int solo_set_fmt_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct solo_filehandle *fh = priv; - - if (videobuf_queue_is_busy(&fh->vidq)) - return -EBUSY; - - /* For right now, if it doesn't match our running config, - * then fail */ - return solo_try_fmt_cap(file, priv, f); -} - -static int solo_get_fmt_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct solo_filehandle *fh = priv; - struct solo6010_dev *solo_dev = fh->solo_dev; - struct v4l2_pix_format *pix = &f->fmt.pix; - - pix->width = solo_dev->video_hsize; - pix->height = solo_vlines(solo_dev); - pix->pixelformat = V4L2_PIX_FMT_UYVY; - pix->field = SOLO_DISP_PIX_FIELD; - pix->sizeimage = solo_image_size(solo_dev); - pix->colorspace = V4L2_COLORSPACE_SMPTE170M; - pix->bytesperline = solo_bytesperline(solo_dev); - - return 0; -} - -static int solo_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *req) -{ - struct solo_filehandle *fh = priv; - - return videobuf_reqbufs(&fh->vidq, req); -} - -static int solo_querybuf(struct file *file, void *priv, struct v4l2_buffer *buf) -{ - struct solo_filehandle *fh = priv; - - return videobuf_querybuf(&fh->vidq, buf); -} - -static int solo_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) -{ - struct solo_filehandle *fh = priv; - - return videobuf_qbuf(&fh->vidq, buf); -} - -static int solo_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) -{ - struct solo_filehandle *fh = priv; - - return videobuf_dqbuf(&fh->vidq, buf, file->f_flags & O_NONBLOCK); -} - -static int solo_streamon(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct solo_filehandle *fh = priv; - - if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - return videobuf_streamon(&fh->vidq); -} - -static int solo_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct solo_filehandle *fh = priv; - - if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - return videobuf_streamoff(&fh->vidq); -} - -static int solo_s_std(struct file *file, void *priv, v4l2_std_id *i) -{ - return 0; -} - -static const u32 solo_motion_ctrls[] = { - V4L2_CID_MOTION_TRACE, - 0 -}; - -static const u32 *solo_ctrl_classes[] = { - solo_motion_ctrls, - NULL -}; - -static int solo_disp_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qc) -{ - qc->id = v4l2_ctrl_next(solo_ctrl_classes, qc->id); - if (!qc->id) - return -EINVAL; - - switch (qc->id) { -#ifdef PRIVATE_CIDS - case V4L2_CID_MOTION_TRACE: - qc->type = V4L2_CTRL_TYPE_BOOLEAN; - qc->minimum = 0; - qc->maximum = qc->step = 1; - qc->default_value = 0; - strlcpy(qc->name, "Motion Detection Trace", sizeof(qc->name)); - return 0; -#else - case V4L2_CID_MOTION_TRACE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); -#endif - } - return -EINVAL; -} - -static int solo_disp_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct solo_filehandle *fh = priv; - struct solo6010_dev *solo_dev = fh->solo_dev; - - switch (ctrl->id) { - case V4L2_CID_MOTION_TRACE: - ctrl->value = solo_reg_read(solo_dev, SOLO_VI_MOTION_BAR) - ? 1 : 0; - return 0; - } - return -EINVAL; -} - -static int solo_disp_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct solo_filehandle *fh = priv; - struct solo6010_dev *solo_dev = fh->solo_dev; - - switch (ctrl->id) { - case V4L2_CID_MOTION_TRACE: - if (ctrl->value) { - solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER, - SOLO_VI_MOTION_Y_ADD | - SOLO_VI_MOTION_Y_VALUE(0x20) | - SOLO_VI_MOTION_CB_VALUE(0x10) | - SOLO_VI_MOTION_CR_VALUE(0x10)); - solo_reg_write(solo_dev, SOLO_VI_MOTION_BAR, - SOLO_VI_MOTION_CR_ADD | - SOLO_VI_MOTION_Y_VALUE(0x10) | - SOLO_VI_MOTION_CB_VALUE(0x80) | - SOLO_VI_MOTION_CR_VALUE(0x10)); - } else { - solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER, 0); - solo_reg_write(solo_dev, SOLO_VI_MOTION_BAR, 0); - } - return 0; - } - return -EINVAL; -} - -static const struct v4l2_file_operations solo_v4l2_fops = { - .owner = THIS_MODULE, - .open = solo_v4l2_open, - .release = solo_v4l2_release, - .read = solo_v4l2_read, - .poll = solo_v4l2_poll, - .mmap = solo_v4l2_mmap, - .ioctl = video_ioctl2, -}; - -static const struct v4l2_ioctl_ops solo_v4l2_ioctl_ops = { - .vidioc_querycap = solo_querycap, - .vidioc_s_std = solo_s_std, - /* Input callbacks */ - .vidioc_enum_input = solo_enum_input, - .vidioc_s_input = solo_set_input, - .vidioc_g_input = solo_get_input, - /* Video capture format callbacks */ - .vidioc_enum_fmt_vid_cap = solo_enum_fmt_cap, - .vidioc_try_fmt_vid_cap = solo_try_fmt_cap, - .vidioc_s_fmt_vid_cap = solo_set_fmt_cap, - .vidioc_g_fmt_vid_cap = solo_get_fmt_cap, - /* Streaming I/O */ - .vidioc_reqbufs = solo_reqbufs, - .vidioc_querybuf = solo_querybuf, - .vidioc_qbuf = solo_qbuf, - .vidioc_dqbuf = solo_dqbuf, - .vidioc_streamon = solo_streamon, - .vidioc_streamoff = solo_streamoff, - /* Controls */ - .vidioc_queryctrl = solo_disp_queryctrl, - .vidioc_g_ctrl = solo_disp_g_ctrl, - .vidioc_s_ctrl = solo_disp_s_ctrl, -}; - -static struct video_device solo_v4l2_template = { - .name = SOLO6010_NAME, - .fops = &solo_v4l2_fops, - .ioctl_ops = &solo_v4l2_ioctl_ops, - .minor = -1, - .release = video_device_release, - - .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL_B, - .current_norm = V4L2_STD_NTSC_M, -}; - -int solo_v4l2_init(struct solo6010_dev *solo_dev) -{ - int ret; - int i; - - init_waitqueue_head(&solo_dev->disp_thread_wait); - - solo_dev->vfd = video_device_alloc(); - if (!solo_dev->vfd) - return -ENOMEM; - - *solo_dev->vfd = solo_v4l2_template; - solo_dev->vfd->parent = &solo_dev->pdev->dev; - - ret = video_register_device(solo_dev->vfd, VFL_TYPE_GRABBER, video_nr); - if (ret < 0) { - video_device_release(solo_dev->vfd); - solo_dev->vfd = NULL; - return ret; - } - - video_set_drvdata(solo_dev->vfd, solo_dev); - - snprintf(solo_dev->vfd->name, sizeof(solo_dev->vfd->name), "%s (%i)", - SOLO6010_NAME, solo_dev->vfd->num); - - if (video_nr != -1) - video_nr++; - - dev_info(&solo_dev->pdev->dev, "Display as /dev/video%d with " - "%d inputs (%d extended)\n", solo_dev->vfd->num, - solo_dev->nr_chans, solo_dev->nr_ext); - - /* Cycle all the channels and clear */ - for (i = 0; i < solo_dev->nr_chans; i++) { - solo_v4l2_set_ch(solo_dev, i); - while (erase_off(solo_dev)) - ;/* Do nothing */ - } - - /* Set the default display channel */ - solo_v4l2_set_ch(solo_dev, 0); - while (erase_off(solo_dev)) - ;/* Do nothing */ - - solo6010_irq_on(solo_dev, SOLO_IRQ_VIDEO_IN); - - return 0; -} - -void solo_v4l2_exit(struct solo6010_dev *solo_dev) -{ - solo6010_irq_off(solo_dev, SOLO_IRQ_VIDEO_IN); - if (solo_dev->vfd) { - video_unregister_device(solo_dev->vfd); - solo_dev->vfd = NULL; - } -} diff --git a/drivers/staging/solo6x10/solo6010.h b/drivers/staging/solo6x10/solo6010.h deleted file mode 100644 index 4532e12d91b5..000000000000 --- a/drivers/staging/solo6x10/solo6010.h +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com - * Copyright (C) 2010 Ben Collins - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef __SOLO6010_H -#define __SOLO6010_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "solo6010-registers.h" - -#ifndef PCI_VENDOR_ID_SOFTLOGIC -#define PCI_VENDOR_ID_SOFTLOGIC 0x9413 -#define PCI_DEVICE_ID_SOLO6010 0x6010 -#define PCI_DEVICE_ID_SOLO6110 0x6110 -#endif - -#ifndef PCI_VENDOR_ID_BLUECHERRY -#define PCI_VENDOR_ID_BLUECHERRY 0x1BB3 -/* Neugent Softlogic 6010 based cards */ -#define PCI_DEVICE_ID_NEUSOLO_4 0x4304 -#define PCI_DEVICE_ID_NEUSOLO_9 0x4309 -#define PCI_DEVICE_ID_NEUSOLO_16 0x4310 -/* Bluecherry Softlogic 6010 based cards */ -#define PCI_DEVICE_ID_BC_SOLO_4 0x4E04 -#define PCI_DEVICE_ID_BC_SOLO_9 0x4E09 -#define PCI_DEVICE_ID_BC_SOLO_16 0x4E10 -/* Bluecherry Softlogic 6110 based cards */ -#define PCI_DEVICE_ID_BC_6110_4 0x5304 -#define PCI_DEVICE_ID_BC_6110_8 0x5308 -#define PCI_DEVICE_ID_BC_6110_16 0x5310 -#endif /* Bluecherry */ - -#define SOLO6010_NAME "solo6010" - -#define SOLO_MAX_CHANNELS 16 - -/* Make sure these two match */ -#define SOLO6010_VERSION "2.0.0" -#define SOLO6010_VER_MAJOR 2 -#define SOLO6010_VER_MINOR 0 -#define SOLO6010_VER_SUB 0 -#define SOLO6010_VER_NUM \ - KERNEL_VERSION(SOLO6010_VER_MAJOR, SOLO6010_VER_MINOR, SOLO6010_VER_SUB) - -#define FLAGS_6110 1 - -/* - * The SOLO6010 actually has 8 i2c channels, but we only use 2. - * 0 - Techwell chip(s) - * 1 - SAA7128 - */ -#define SOLO_I2C_ADAPTERS 2 -#define SOLO_I2C_TW 0 -#define SOLO_I2C_SAA 1 - -/* DMA Engine setup */ -#define SOLO_NR_P2M 4 -#define SOLO_NR_P2M_DESC 256 -/* MPEG and JPEG share the same interrupt and locks so they must be together - * in the same dma channel. */ -#define SOLO_P2M_DMA_ID_MP4E 0 -#define SOLO_P2M_DMA_ID_JPEG 0 -#define SOLO_P2M_DMA_ID_MP4D 1 -#define SOLO_P2M_DMA_ID_G723D 1 -#define SOLO_P2M_DMA_ID_DISP 2 -#define SOLO_P2M_DMA_ID_OSG 2 -#define SOLO_P2M_DMA_ID_G723E 3 -#define SOLO_P2M_DMA_ID_VIN 3 - -/* Encoder standard modes */ -#define SOLO_ENC_MODE_CIF 2 -#define SOLO_ENC_MODE_HD1 1 -#define SOLO_ENC_MODE_D1 9 - -#define SOLO_DEFAULT_GOP 30 -#define SOLO_DEFAULT_QP 3 - -/* There is 8MB memory available for solo to buffer MPEG4 frames. - * This gives us 512 * 16kbyte queues. */ -#define SOLO_NR_RING_BUFS 512 - -#define SOLO_CLOCK_MHZ 108 - -#ifndef V4L2_BUF_FLAG_MOTION_ON -#define V4L2_BUF_FLAG_MOTION_ON 0x0400 -#define V4L2_BUF_FLAG_MOTION_DETECTED 0x0800 -#endif -#ifndef V4L2_CID_MOTION_ENABLE -#define PRIVATE_CIDS -#define V4L2_CID_MOTION_ENABLE (V4L2_CID_PRIVATE_BASE+0) -#define V4L2_CID_MOTION_THRESHOLD (V4L2_CID_PRIVATE_BASE+1) -#define V4L2_CID_MOTION_TRACE (V4L2_CID_PRIVATE_BASE+2) -#endif - -enum SOLO_I2C_STATE { - IIC_STATE_IDLE, - IIC_STATE_START, - IIC_STATE_READ, - IIC_STATE_WRITE, - IIC_STATE_STOP -}; - -struct p2m_desc { - u32 ctrl; - u32 ext; - u32 ta; - u32 fa; -}; - -struct solo_p2m_dev { - struct mutex mutex; - struct completion completion; - int error; -}; - -#define OSD_TEXT_MAX 30 - -enum solo_enc_types { - SOLO_ENC_TYPE_STD, - SOLO_ENC_TYPE_EXT, -}; - -struct solo_enc_dev { - struct solo6010_dev *solo_dev; - /* V4L2 Items */ - struct video_device *vfd; - /* General accounting */ - wait_queue_head_t thread_wait; - spinlock_t lock; - atomic_t readers; - u8 ch; - u8 mode, gop, qp, interlaced, interval; - u8 reset_gop; - u8 bw_weight; - u8 motion_detected; - u16 motion_thresh; - u16 width; - u16 height; - char osd_text[OSD_TEXT_MAX + 1]; -}; - -struct solo_enc_buf { - u8 vop; - u8 ch; - enum solo_enc_types type; - u32 off; - u32 size; - u32 jpeg_off; - u32 jpeg_size; - struct timeval ts; -}; - -/* The SOLO6010 PCI Device */ -struct solo6010_dev { - /* General stuff */ - struct pci_dev *pdev; - u8 __iomem *reg_base; - int nr_chans; - int nr_ext; - u32 flags; - u32 irq_mask; - u32 motion_mask; - spinlock_t reg_io_lock; - - /* tw28xx accounting */ - u8 tw2865, tw2864, tw2815; - u8 tw28_cnt; - - /* i2c related items */ - struct i2c_adapter i2c_adap[SOLO_I2C_ADAPTERS]; - enum SOLO_I2C_STATE i2c_state; - struct mutex i2c_mutex; - int i2c_id; - wait_queue_head_t i2c_wait; - struct i2c_msg *i2c_msg; - unsigned int i2c_msg_num; - unsigned int i2c_msg_ptr; - - /* P2M DMA Engine */ - struct solo_p2m_dev p2m_dev[SOLO_NR_P2M]; - - /* V4L2 Display items */ - struct video_device *vfd; - unsigned int erasing; - unsigned int frame_blank; - u8 cur_disp_ch; - wait_queue_head_t disp_thread_wait; - - /* V4L2 Encoder items */ - struct solo_enc_dev *v4l2_enc[SOLO_MAX_CHANNELS]; - u16 enc_bw_remain; - /* IDX into hw mp4 encoder */ - u8 enc_idx; - /* Our software ring of enc buf references */ - u16 enc_wr_idx; - struct solo_enc_buf enc_buf[SOLO_NR_RING_BUFS]; - - /* Current video settings */ - u32 video_type; - u16 video_hsize, video_vsize; - u16 vout_hstart, vout_vstart; - u16 vin_hstart, vin_vstart; - u8 fps; - - /* Audio components */ - struct snd_card *snd_card; - struct snd_pcm *snd_pcm; - atomic_t snd_users; - int g723_hw_idx; -}; - -static inline u32 solo_reg_read(struct solo6010_dev *solo_dev, int reg) -{ - unsigned long flags; - u32 ret; - u16 val; - - spin_lock_irqsave(&solo_dev->reg_io_lock, flags); - - ret = readl(solo_dev->reg_base + reg); - rmb(); - pci_read_config_word(solo_dev->pdev, PCI_STATUS, &val); - rmb(); - - spin_unlock_irqrestore(&solo_dev->reg_io_lock, flags); - - return ret; -} - -static inline void solo_reg_write(struct solo6010_dev *solo_dev, int reg, - u32 data) -{ - unsigned long flags; - u16 val; - - spin_lock_irqsave(&solo_dev->reg_io_lock, flags); - - writel(data, solo_dev->reg_base + reg); - wmb(); - pci_read_config_word(solo_dev->pdev, PCI_STATUS, &val); - rmb(); - - spin_unlock_irqrestore(&solo_dev->reg_io_lock, flags); -} - -void solo6010_irq_on(struct solo6010_dev *solo_dev, u32 mask); -void solo6010_irq_off(struct solo6010_dev *solo_dev, u32 mask); - -/* Init/exit routeines for subsystems */ -int solo_disp_init(struct solo6010_dev *solo_dev); -void solo_disp_exit(struct solo6010_dev *solo_dev); - -int solo_gpio_init(struct solo6010_dev *solo_dev); -void solo_gpio_exit(struct solo6010_dev *solo_dev); - -int solo_i2c_init(struct solo6010_dev *solo_dev); -void solo_i2c_exit(struct solo6010_dev *solo_dev); - -int solo_p2m_init(struct solo6010_dev *solo_dev); -void solo_p2m_exit(struct solo6010_dev *solo_dev); - -int solo_v4l2_init(struct solo6010_dev *solo_dev); -void solo_v4l2_exit(struct solo6010_dev *solo_dev); - -int solo_enc_init(struct solo6010_dev *solo_dev); -void solo_enc_exit(struct solo6010_dev *solo_dev); - -int solo_enc_v4l2_init(struct solo6010_dev *solo_dev); -void solo_enc_v4l2_exit(struct solo6010_dev *solo_dev); - -int solo_g723_init(struct solo6010_dev *solo_dev); -void solo_g723_exit(struct solo6010_dev *solo_dev); - -/* ISR's */ -int solo_i2c_isr(struct solo6010_dev *solo_dev); -void solo_p2m_isr(struct solo6010_dev *solo_dev, int id); -void solo_p2m_error_isr(struct solo6010_dev *solo_dev, u32 status); -void solo_enc_v4l2_isr(struct solo6010_dev *solo_dev); -void solo_g723_isr(struct solo6010_dev *solo_dev); -void solo_motion_isr(struct solo6010_dev *solo_dev); -void solo_video_in_isr(struct solo6010_dev *solo_dev); - -/* i2c read/write */ -u8 solo_i2c_readbyte(struct solo6010_dev *solo_dev, int id, u8 addr, u8 off); -void solo_i2c_writebyte(struct solo6010_dev *solo_dev, int id, u8 addr, u8 off, - u8 data); - -/* P2M DMA */ -int solo_p2m_dma_t(struct solo6010_dev *solo_dev, u8 id, int wr, - dma_addr_t dma_addr, u32 ext_addr, u32 size); -int solo_p2m_dma(struct solo6010_dev *solo_dev, u8 id, int wr, - void *sys_addr, u32 ext_addr, u32 size); -int solo_p2m_dma_sg(struct solo6010_dev *solo_dev, u8 id, - struct p2m_desc *pdesc, int wr, - struct scatterlist *sglist, u32 sg_off, - u32 ext_addr, u32 size); -void solo_p2m_push_desc(struct p2m_desc *desc, int wr, dma_addr_t dma_addr, - u32 ext_addr, u32 size, int repeat, u32 ext_size); -int solo_p2m_dma_desc(struct solo6010_dev *solo_dev, u8 id, - struct p2m_desc *desc, int desc_count); - -/* Set the threshold for motion detection */ -void solo_set_motion_threshold(struct solo6010_dev *solo_dev, u8 ch, u16 val); -#define SOLO_DEF_MOT_THRESH 0x0300 - -/* Write text on OSD */ -int solo_osd_print(struct solo_enc_dev *solo_enc); - -#endif /* __SOLO6010_H */ diff --git a/drivers/staging/solo6x10/solo6x10.h b/drivers/staging/solo6x10/solo6x10.h new file mode 100644 index 000000000000..1730f4d688d5 --- /dev/null +++ b/drivers/staging/solo6x10/solo6x10.h @@ -0,0 +1,336 @@ +/* + * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com + * Copyright (C) 2010 Ben Collins + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __SOLO6010_H +#define __SOLO6010_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "registers.h" + +#ifndef PCI_VENDOR_ID_SOFTLOGIC +#define PCI_VENDOR_ID_SOFTLOGIC 0x9413 +#define PCI_DEVICE_ID_SOLO6010 0x6010 +#define PCI_DEVICE_ID_SOLO6110 0x6110 +#endif + +#ifndef PCI_VENDOR_ID_BLUECHERRY +#define PCI_VENDOR_ID_BLUECHERRY 0x1BB3 +/* Neugent Softlogic 6010 based cards */ +#define PCI_DEVICE_ID_NEUSOLO_4 0x4304 +#define PCI_DEVICE_ID_NEUSOLO_9 0x4309 +#define PCI_DEVICE_ID_NEUSOLO_16 0x4310 +/* Bluecherry Softlogic 6010 based cards */ +#define PCI_DEVICE_ID_BC_SOLO_4 0x4E04 +#define PCI_DEVICE_ID_BC_SOLO_9 0x4E09 +#define PCI_DEVICE_ID_BC_SOLO_16 0x4E10 +/* Bluecherry Softlogic 6110 based cards */ +#define PCI_DEVICE_ID_BC_6110_4 0x5304 +#define PCI_DEVICE_ID_BC_6110_8 0x5308 +#define PCI_DEVICE_ID_BC_6110_16 0x5310 +#endif /* Bluecherry */ + +#define SOLO6010_NAME "solo6010" + +#define SOLO_MAX_CHANNELS 16 + +/* Make sure these two match */ +#define SOLO6010_VERSION "2.0.0" +#define SOLO6010_VER_MAJOR 2 +#define SOLO6010_VER_MINOR 0 +#define SOLO6010_VER_SUB 0 +#define SOLO6010_VER_NUM \ + KERNEL_VERSION(SOLO6010_VER_MAJOR, SOLO6010_VER_MINOR, SOLO6010_VER_SUB) + +#define FLAGS_6110 1 + +/* + * The SOLO6010 actually has 8 i2c channels, but we only use 2. + * 0 - Techwell chip(s) + * 1 - SAA7128 + */ +#define SOLO_I2C_ADAPTERS 2 +#define SOLO_I2C_TW 0 +#define SOLO_I2C_SAA 1 + +/* DMA Engine setup */ +#define SOLO_NR_P2M 4 +#define SOLO_NR_P2M_DESC 256 +/* MPEG and JPEG share the same interrupt and locks so they must be together + * in the same dma channel. */ +#define SOLO_P2M_DMA_ID_MP4E 0 +#define SOLO_P2M_DMA_ID_JPEG 0 +#define SOLO_P2M_DMA_ID_MP4D 1 +#define SOLO_P2M_DMA_ID_G723D 1 +#define SOLO_P2M_DMA_ID_DISP 2 +#define SOLO_P2M_DMA_ID_OSG 2 +#define SOLO_P2M_DMA_ID_G723E 3 +#define SOLO_P2M_DMA_ID_VIN 3 + +/* Encoder standard modes */ +#define SOLO_ENC_MODE_CIF 2 +#define SOLO_ENC_MODE_HD1 1 +#define SOLO_ENC_MODE_D1 9 + +#define SOLO_DEFAULT_GOP 30 +#define SOLO_DEFAULT_QP 3 + +/* There is 8MB memory available for solo to buffer MPEG4 frames. + * This gives us 512 * 16kbyte queues. */ +#define SOLO_NR_RING_BUFS 512 + +#define SOLO_CLOCK_MHZ 108 + +#ifndef V4L2_BUF_FLAG_MOTION_ON +#define V4L2_BUF_FLAG_MOTION_ON 0x0400 +#define V4L2_BUF_FLAG_MOTION_DETECTED 0x0800 +#endif +#ifndef V4L2_CID_MOTION_ENABLE +#define PRIVATE_CIDS +#define V4L2_CID_MOTION_ENABLE (V4L2_CID_PRIVATE_BASE+0) +#define V4L2_CID_MOTION_THRESHOLD (V4L2_CID_PRIVATE_BASE+1) +#define V4L2_CID_MOTION_TRACE (V4L2_CID_PRIVATE_BASE+2) +#endif + +enum SOLO_I2C_STATE { + IIC_STATE_IDLE, + IIC_STATE_START, + IIC_STATE_READ, + IIC_STATE_WRITE, + IIC_STATE_STOP +}; + +struct p2m_desc { + u32 ctrl; + u32 ext; + u32 ta; + u32 fa; +}; + +struct solo_p2m_dev { + struct mutex mutex; + struct completion completion; + int error; +}; + +#define OSD_TEXT_MAX 30 + +enum solo_enc_types { + SOLO_ENC_TYPE_STD, + SOLO_ENC_TYPE_EXT, +}; + +struct solo_enc_dev { + struct solo6010_dev *solo_dev; + /* V4L2 Items */ + struct video_device *vfd; + /* General accounting */ + wait_queue_head_t thread_wait; + spinlock_t lock; + atomic_t readers; + u8 ch; + u8 mode, gop, qp, interlaced, interval; + u8 reset_gop; + u8 bw_weight; + u8 motion_detected; + u16 motion_thresh; + u16 width; + u16 height; + char osd_text[OSD_TEXT_MAX + 1]; +}; + +struct solo_enc_buf { + u8 vop; + u8 ch; + enum solo_enc_types type; + u32 off; + u32 size; + u32 jpeg_off; + u32 jpeg_size; + struct timeval ts; +}; + +/* The SOLO6010 PCI Device */ +struct solo6010_dev { + /* General stuff */ + struct pci_dev *pdev; + u8 __iomem *reg_base; + int nr_chans; + int nr_ext; + u32 flags; + u32 irq_mask; + u32 motion_mask; + spinlock_t reg_io_lock; + + /* tw28xx accounting */ + u8 tw2865, tw2864, tw2815; + u8 tw28_cnt; + + /* i2c related items */ + struct i2c_adapter i2c_adap[SOLO_I2C_ADAPTERS]; + enum SOLO_I2C_STATE i2c_state; + struct mutex i2c_mutex; + int i2c_id; + wait_queue_head_t i2c_wait; + struct i2c_msg *i2c_msg; + unsigned int i2c_msg_num; + unsigned int i2c_msg_ptr; + + /* P2M DMA Engine */ + struct solo_p2m_dev p2m_dev[SOLO_NR_P2M]; + + /* V4L2 Display items */ + struct video_device *vfd; + unsigned int erasing; + unsigned int frame_blank; + u8 cur_disp_ch; + wait_queue_head_t disp_thread_wait; + + /* V4L2 Encoder items */ + struct solo_enc_dev *v4l2_enc[SOLO_MAX_CHANNELS]; + u16 enc_bw_remain; + /* IDX into hw mp4 encoder */ + u8 enc_idx; + /* Our software ring of enc buf references */ + u16 enc_wr_idx; + struct solo_enc_buf enc_buf[SOLO_NR_RING_BUFS]; + + /* Current video settings */ + u32 video_type; + u16 video_hsize, video_vsize; + u16 vout_hstart, vout_vstart; + u16 vin_hstart, vin_vstart; + u8 fps; + + /* Audio components */ + struct snd_card *snd_card; + struct snd_pcm *snd_pcm; + atomic_t snd_users; + int g723_hw_idx; +}; + +static inline u32 solo_reg_read(struct solo6010_dev *solo_dev, int reg) +{ + unsigned long flags; + u32 ret; + u16 val; + + spin_lock_irqsave(&solo_dev->reg_io_lock, flags); + + ret = readl(solo_dev->reg_base + reg); + rmb(); + pci_read_config_word(solo_dev->pdev, PCI_STATUS, &val); + rmb(); + + spin_unlock_irqrestore(&solo_dev->reg_io_lock, flags); + + return ret; +} + +static inline void solo_reg_write(struct solo6010_dev *solo_dev, int reg, + u32 data) +{ + unsigned long flags; + u16 val; + + spin_lock_irqsave(&solo_dev->reg_io_lock, flags); + + writel(data, solo_dev->reg_base + reg); + wmb(); + pci_read_config_word(solo_dev->pdev, PCI_STATUS, &val); + rmb(); + + spin_unlock_irqrestore(&solo_dev->reg_io_lock, flags); +} + +void solo6010_irq_on(struct solo6010_dev *solo_dev, u32 mask); +void solo6010_irq_off(struct solo6010_dev *solo_dev, u32 mask); + +/* Init/exit routeines for subsystems */ +int solo_disp_init(struct solo6010_dev *solo_dev); +void solo_disp_exit(struct solo6010_dev *solo_dev); + +int solo_gpio_init(struct solo6010_dev *solo_dev); +void solo_gpio_exit(struct solo6010_dev *solo_dev); + +int solo_i2c_init(struct solo6010_dev *solo_dev); +void solo_i2c_exit(struct solo6010_dev *solo_dev); + +int solo_p2m_init(struct solo6010_dev *solo_dev); +void solo_p2m_exit(struct solo6010_dev *solo_dev); + +int solo_v4l2_init(struct solo6010_dev *solo_dev); +void solo_v4l2_exit(struct solo6010_dev *solo_dev); + +int solo_enc_init(struct solo6010_dev *solo_dev); +void solo_enc_exit(struct solo6010_dev *solo_dev); + +int solo_enc_v4l2_init(struct solo6010_dev *solo_dev); +void solo_enc_v4l2_exit(struct solo6010_dev *solo_dev); + +int solo_g723_init(struct solo6010_dev *solo_dev); +void solo_g723_exit(struct solo6010_dev *solo_dev); + +/* ISR's */ +int solo_i2c_isr(struct solo6010_dev *solo_dev); +void solo_p2m_isr(struct solo6010_dev *solo_dev, int id); +void solo_p2m_error_isr(struct solo6010_dev *solo_dev, u32 status); +void solo_enc_v4l2_isr(struct solo6010_dev *solo_dev); +void solo_g723_isr(struct solo6010_dev *solo_dev); +void solo_motion_isr(struct solo6010_dev *solo_dev); +void solo_video_in_isr(struct solo6010_dev *solo_dev); + +/* i2c read/write */ +u8 solo_i2c_readbyte(struct solo6010_dev *solo_dev, int id, u8 addr, u8 off); +void solo_i2c_writebyte(struct solo6010_dev *solo_dev, int id, u8 addr, u8 off, + u8 data); + +/* P2M DMA */ +int solo_p2m_dma_t(struct solo6010_dev *solo_dev, u8 id, int wr, + dma_addr_t dma_addr, u32 ext_addr, u32 size); +int solo_p2m_dma(struct solo6010_dev *solo_dev, u8 id, int wr, + void *sys_addr, u32 ext_addr, u32 size); +int solo_p2m_dma_sg(struct solo6010_dev *solo_dev, u8 id, + struct p2m_desc *pdesc, int wr, + struct scatterlist *sglist, u32 sg_off, + u32 ext_addr, u32 size); +void solo_p2m_push_desc(struct p2m_desc *desc, int wr, dma_addr_t dma_addr, + u32 ext_addr, u32 size, int repeat, u32 ext_size); +int solo_p2m_dma_desc(struct solo6010_dev *solo_dev, u8 id, + struct p2m_desc *desc, int desc_count); + +/* Set the threshold for motion detection */ +void solo_set_motion_threshold(struct solo6010_dev *solo_dev, u8 ch, u16 val); +#define SOLO_DEF_MOT_THRESH 0x0300 + +/* Write text on OSD */ +int solo_osd_print(struct solo_enc_dev *solo_enc); + +#endif /* __SOLO6010_H */ diff --git a/drivers/staging/solo6x10/tw28.c b/drivers/staging/solo6x10/tw28.c new file mode 100644 index 000000000000..0f3d1e44c65a --- /dev/null +++ b/drivers/staging/solo6x10/tw28.c @@ -0,0 +1,822 @@ +/* + * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com + * Copyright (C) 2010 Ben Collins + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include "solo6x10.h" +#include "tw28.h" + +/* XXX: Some of these values are masked into an 8-bit regs, and shifted + * around for other 8-bit regs. What are the magic bits in these values? */ +#define DEFAULT_HDELAY_NTSC (32 - 4) +#define DEFAULT_HACTIVE_NTSC (720 + 16) +#define DEFAULT_VDELAY_NTSC (7 - 2) +#define DEFAULT_VACTIVE_NTSC (240 + 4) + +#define DEFAULT_HDELAY_PAL (32 + 4) +#define DEFAULT_HACTIVE_PAL (864-DEFAULT_HDELAY_PAL) +#define DEFAULT_VDELAY_PAL (6) +#define DEFAULT_VACTIVE_PAL (312-DEFAULT_VDELAY_PAL) + +static u8 tbl_tw2864_template[] = { + 0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, /* 0x00 */ + 0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, /* 0x10 */ + 0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, /* 0x20 */ + 0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, /* 0x30 */ + 0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x00, + 0x00, 0x02, 0x00, 0xcc, 0x00, 0x80, 0x44, 0x50, /* 0x80 */ + 0x22, 0x01, 0xd8, 0xbc, 0xb8, 0x44, 0x38, 0x00, + 0x00, 0x78, 0x72, 0x3e, 0x14, 0xa5, 0xe4, 0x05, /* 0x90 */ + 0x00, 0x28, 0x44, 0x44, 0xa0, 0x88, 0x5a, 0x01, + 0x08, 0x08, 0x08, 0x08, 0x1a, 0x1a, 0x1a, 0x1a, /* 0xa0 */ + 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0x44, + 0x44, 0x0a, 0x00, 0xff, 0xef, 0xef, 0xef, 0xef, /* 0xb0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */ + 0x00, 0x00, 0x55, 0x00, 0xb1, 0xe4, 0x40, 0x00, + 0x77, 0x77, 0x01, 0x13, 0x57, 0x9b, 0xdf, 0x20, /* 0xd0 */ + 0x64, 0xa8, 0xec, 0xd1, 0x0f, 0x11, 0x11, 0x81, + 0x10, 0xe0, 0xbb, 0xbb, 0x00, 0x11, 0x00, 0x00, /* 0xe0 */ + 0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0x11, 0x00, + 0x83, 0xb5, 0x09, 0x78, 0x85, 0x00, 0x01, 0x20, /* 0xf0 */ + 0x64, 0x11, 0x40, 0xaf, 0xff, 0x00, 0x00, 0x00, +}; + +static u8 tbl_tw2865_ntsc_template[] = { + 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, /* 0x00 */ + 0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, /* 0x10 */ + 0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, /* 0x20 */ + 0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0xf0, 0x70, 0x48, 0x80, 0x80, 0x00, 0x02, /* 0x30 */ + 0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0x00, 0x90, 0x68, 0x00, 0x38, 0x80, 0x80, /* 0x40 */ + 0x80, 0x80, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x43, + 0x08, 0x00, 0x00, 0x01, 0xf1, 0x03, 0xEF, 0x03, /* 0x70 */ + 0xE9, 0x03, 0xD9, 0x15, 0x15, 0xE4, 0xA3, 0x80, + 0x00, 0x02, 0x00, 0xCC, 0x00, 0x80, 0x44, 0x50, /* 0x80 */ + 0x22, 0x01, 0xD8, 0xBC, 0xB8, 0x44, 0x38, 0x00, + 0x00, 0x78, 0x44, 0x3D, 0x14, 0xA5, 0xE0, 0x05, /* 0x90 */ + 0x00, 0x28, 0x44, 0x44, 0xA0, 0x90, 0x52, 0x13, + 0x08, 0x08, 0x08, 0x08, 0x1A, 0x1A, 0x1B, 0x1A, /* 0xa0 */ + 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0x44, + 0x44, 0x4A, 0x00, 0xFF, 0xEF, 0xEF, 0xEF, 0xEF, /* 0xb0 */ + 0xFF, 0xE7, 0xE9, 0xE9, 0xEB, 0xFF, 0xD6, 0xD8, + 0xD8, 0xD7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */ + 0x00, 0x00, 0x55, 0x00, 0xE4, 0x39, 0x00, 0x80, + 0x77, 0x77, 0x03, 0x20, 0x57, 0x9b, 0xdf, 0x31, /* 0xd0 */ + 0x64, 0xa8, 0xec, 0xd1, 0x0f, 0x11, 0x11, 0x81, + 0x10, 0xC0, 0xAA, 0xAA, 0x00, 0x11, 0x00, 0x00, /* 0xe0 */ + 0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0x11, 0x00, + 0x83, 0xB5, 0x09, 0x78, 0x85, 0x00, 0x01, 0x20, /* 0xf0 */ + 0x64, 0x51, 0x40, 0xaf, 0xFF, 0xF0, 0x00, 0xC0, +}; + +static u8 tbl_tw2865_pal_template[] = { + 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, /* 0x00 */ + 0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f, + 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, /* 0x10 */ + 0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f, + 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, /* 0x20 */ + 0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f, + 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, /* 0x30 */ + 0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f, + 0x00, 0x94, 0x90, 0x48, 0x00, 0x38, 0x7F, 0x80, /* 0x40 */ + 0x80, 0x80, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x43, + 0x08, 0x00, 0x00, 0x01, 0xf1, 0x03, 0xEF, 0x03, /* 0x70 */ + 0xEA, 0x03, 0xD9, 0x15, 0x15, 0xE4, 0xA3, 0x80, + 0x00, 0x02, 0x00, 0xCC, 0x00, 0x80, 0x44, 0x50, /* 0x80 */ + 0x22, 0x01, 0xD8, 0xBC, 0xB8, 0x44, 0x38, 0x00, + 0x00, 0x78, 0x44, 0x3D, 0x14, 0xA5, 0xE0, 0x05, /* 0x90 */ + 0x00, 0x28, 0x44, 0x44, 0xA0, 0x90, 0x52, 0x13, + 0x08, 0x08, 0x08, 0x08, 0x1A, 0x1A, 0x1A, 0x1A, /* 0xa0 */ + 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0x44, + 0x44, 0x4A, 0x00, 0xFF, 0xEF, 0xEF, 0xEF, 0xEF, /* 0xb0 */ + 0xFF, 0xE7, 0xE9, 0xE9, 0xE9, 0xFF, 0xD7, 0xD8, + 0xD9, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */ + 0x00, 0x00, 0x55, 0x00, 0xE4, 0x39, 0x00, 0x80, + 0x77, 0x77, 0x03, 0x20, 0x57, 0x9b, 0xdf, 0x31, /* 0xd0 */ + 0x64, 0xa8, 0xec, 0xd1, 0x0f, 0x11, 0x11, 0x81, + 0x10, 0xC0, 0xAA, 0xAA, 0x00, 0x11, 0x00, 0x00, /* 0xe0 */ + 0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0x11, 0x00, + 0x83, 0xB5, 0x09, 0x00, 0xA0, 0x00, 0x01, 0x20, /* 0xf0 */ + 0x64, 0x51, 0x40, 0xaf, 0xFF, 0xF0, 0x00, 0xC0, +}; + +#define is_tw286x(__solo, __id) (!(__solo->tw2815 & (1 << __id))) + +static u8 tw_readbyte(struct solo6010_dev *solo_dev, int chip_id, u8 tw6x_off, + u8 tw_off) +{ + if (is_tw286x(solo_dev, chip_id)) + return solo_i2c_readbyte(solo_dev, SOLO_I2C_TW, + TW_CHIP_OFFSET_ADDR(chip_id), + tw6x_off); + else + return solo_i2c_readbyte(solo_dev, SOLO_I2C_TW, + TW_CHIP_OFFSET_ADDR(chip_id), + tw_off); +} + +static void tw_writebyte(struct solo6010_dev *solo_dev, int chip_id, + u8 tw6x_off, u8 tw_off, u8 val) +{ + if (is_tw286x(solo_dev, chip_id)) + solo_i2c_writebyte(solo_dev, SOLO_I2C_TW, + TW_CHIP_OFFSET_ADDR(chip_id), + tw6x_off, val); + else + solo_i2c_writebyte(solo_dev, SOLO_I2C_TW, + TW_CHIP_OFFSET_ADDR(chip_id), + tw_off, val); +} + +static void tw_write_and_verify(struct solo6010_dev *solo_dev, u8 addr, u8 off, + u8 val) +{ + int i; + + for (i = 0; i < 5; i++) { + u8 rval = solo_i2c_readbyte(solo_dev, SOLO_I2C_TW, addr, off); + if (rval == val) + return; + + solo_i2c_writebyte(solo_dev, SOLO_I2C_TW, addr, off, val); + msleep_interruptible(1); + } + +/* printk("solo6010/tw28: Error writing register: %02x->%02x [%02x]\n", + addr, off, val); */ +} + +static int tw2865_setup(struct solo6010_dev *solo_dev, u8 dev_addr) +{ + u8 tbl_tw2865_common[256]; + int i; + + if (solo_dev->video_type == SOLO_VO_FMT_TYPE_PAL) + memcpy(tbl_tw2865_common, tbl_tw2865_pal_template, + sizeof(tbl_tw2865_common)); + else + memcpy(tbl_tw2865_common, tbl_tw2865_ntsc_template, + sizeof(tbl_tw2865_common)); + + /* ALINK Mode */ + if (solo_dev->nr_chans == 4) { + tbl_tw2865_common[0xd2] = 0x01; + tbl_tw2865_common[0xcf] = 0x00; + } else if (solo_dev->nr_chans == 8) { + tbl_tw2865_common[0xd2] = 0x02; + if (dev_addr == TW_CHIP_OFFSET_ADDR(1)) + tbl_tw2865_common[0xcf] = 0x80; + } else if (solo_dev->nr_chans == 16) { + tbl_tw2865_common[0xd2] = 0x03; + if (dev_addr == TW_CHIP_OFFSET_ADDR(1)) + tbl_tw2865_common[0xcf] = 0x83; + else if (dev_addr == TW_CHIP_OFFSET_ADDR(2)) + tbl_tw2865_common[0xcf] = 0x83; + else if (dev_addr == TW_CHIP_OFFSET_ADDR(3)) + tbl_tw2865_common[0xcf] = 0x80; + } + + for (i = 0; i < 0xff; i++) { + /* Skip read only registers */ + if (i >= 0xb8 && i <= 0xc1) + continue; + if ((i & ~0x30) == 0x00 || + (i & ~0x30) == 0x0c || + (i & ~0x30) == 0x0d) + continue; + if (i >= 0xc4 && i <= 0xc7) + continue; + if (i == 0xfd) + continue; + + tw_write_and_verify(solo_dev, dev_addr, i, + tbl_tw2865_common[i]); + } + + return 0; +} + +static int tw2864_setup(struct solo6010_dev *solo_dev, u8 dev_addr) +{ + u8 tbl_tw2864_common[sizeof(tbl_tw2864_template)]; + int i; + + memcpy(tbl_tw2864_common, tbl_tw2864_template, + sizeof(tbl_tw2864_common)); + + if (solo_dev->tw2865 == 0) { + /* IRQ Mode */ + if (solo_dev->nr_chans == 4) { + tbl_tw2864_common[0xd2] = 0x01; + tbl_tw2864_common[0xcf] = 0x00; + } else if (solo_dev->nr_chans == 8) { + tbl_tw2864_common[0xd2] = 0x02; + if (dev_addr == TW_CHIP_OFFSET_ADDR(0)) + tbl_tw2864_common[0xcf] = 0x43; + else if (dev_addr == TW_CHIP_OFFSET_ADDR(1)) + tbl_tw2864_common[0xcf] = 0x40; + } else if (solo_dev->nr_chans == 16) { + tbl_tw2864_common[0xd2] = 0x03; + if (dev_addr == TW_CHIP_OFFSET_ADDR(0)) + tbl_tw2864_common[0xcf] = 0x43; + else if (dev_addr == TW_CHIP_OFFSET_ADDR(1)) + tbl_tw2864_common[0xcf] = 0x43; + else if (dev_addr == TW_CHIP_OFFSET_ADDR(2)) + tbl_tw2864_common[0xcf] = 0x43; + else if (dev_addr == TW_CHIP_OFFSET_ADDR(3)) + tbl_tw2864_common[0xcf] = 0x40; + } + } else { + /* ALINK Mode. Assumes that the first tw28xx is a + * 2865 and these are in cascade. */ + for (i = 0; i <= 4; i++) + tbl_tw2864_common[0x08 | i << 4] = 0x12; + + if (solo_dev->nr_chans == 8) { + tbl_tw2864_common[0xd2] = 0x02; + if (dev_addr == TW_CHIP_OFFSET_ADDR(1)) + tbl_tw2864_common[0xcf] = 0x80; + } else if (solo_dev->nr_chans == 16) { + tbl_tw2864_common[0xd2] = 0x03; + if (dev_addr == TW_CHIP_OFFSET_ADDR(1)) + tbl_tw2864_common[0xcf] = 0x83; + else if (dev_addr == TW_CHIP_OFFSET_ADDR(2)) + tbl_tw2864_common[0xcf] = 0x83; + else if (dev_addr == TW_CHIP_OFFSET_ADDR(3)) + tbl_tw2864_common[0xcf] = 0x80; + } + } + + /* NTSC or PAL */ + if (solo_dev->video_type == SOLO_VO_FMT_TYPE_PAL) { + for (i = 0; i < 4; i++) { + tbl_tw2864_common[0x07 | (i << 4)] |= 0x10; + tbl_tw2864_common[0x08 | (i << 4)] |= 0x06; + tbl_tw2864_common[0x0a | (i << 4)] |= 0x08; + tbl_tw2864_common[0x0b | (i << 4)] |= 0x13; + tbl_tw2864_common[0x0e | (i << 4)] |= 0x01; + } + tbl_tw2864_common[0x9d] = 0x90; + tbl_tw2864_common[0xf3] = 0x00; + tbl_tw2864_common[0xf4] = 0xa0; + } + + for (i = 0; i < 0xff; i++) { + /* Skip read only registers */ + if (i >= 0xb8 && i <= 0xc1) + continue; + if ((i & ~0x30) == 0x00 || + (i & ~0x30) == 0x0c || + (i & ~0x30) == 0x0d) + continue; + if (i == 0x74 || i == 0x77 || i == 0x78 || + i == 0x79 || i == 0x7a) + continue; + if (i == 0xfd) + continue; + + tw_write_and_verify(solo_dev, dev_addr, i, + tbl_tw2864_common[i]); + } + + return 0; +} + +static int tw2815_setup(struct solo6010_dev *solo_dev, u8 dev_addr) +{ + u8 tbl_ntsc_tw2815_common[] = { + 0x00, 0xc8, 0x20, 0xd0, 0x06, 0xf0, 0x08, 0x80, + 0x80, 0x80, 0x80, 0x02, 0x06, 0x00, 0x11, + }; + + u8 tbl_pal_tw2815_common[] = { + 0x00, 0x88, 0x20, 0xd0, 0x05, 0x20, 0x28, 0x80, + 0x80, 0x80, 0x80, 0x82, 0x06, 0x00, 0x11, + }; + + u8 tbl_tw2815_sfr[] = { + 0x00, 0x00, 0x00, 0xc0, 0x45, 0xa0, 0xd0, 0x2f, /* 0x00 */ + 0x64, 0x80, 0x80, 0x82, 0x82, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x05, 0x00, 0x00, 0x80, 0x06, 0x00, /* 0x10 */ + 0x00, 0x00, 0x00, 0xff, 0x8f, 0x00, 0x00, 0x00, + 0x88, 0x88, 0xc0, 0x00, 0x20, 0x64, 0xa8, 0xec, /* 0x20 */ + 0x31, 0x75, 0xb9, 0xfd, 0x00, 0x00, 0x88, 0x88, + 0x88, 0x11, 0x00, 0x88, 0x88, 0x00, /* 0x30 */ + }; + u8 *tbl_tw2815_common; + int i; + int ch; + + tbl_ntsc_tw2815_common[0x06] = 0; + + /* Horizontal Delay Control */ + tbl_ntsc_tw2815_common[0x02] = DEFAULT_HDELAY_NTSC & 0xff; + tbl_ntsc_tw2815_common[0x06] |= 0x03 & (DEFAULT_HDELAY_NTSC >> 8); + + /* Horizontal Active Control */ + tbl_ntsc_tw2815_common[0x03] = DEFAULT_HACTIVE_NTSC & 0xff; + tbl_ntsc_tw2815_common[0x06] |= + ((0x03 & (DEFAULT_HACTIVE_NTSC >> 8)) << 2); + + /* Vertical Delay Control */ + tbl_ntsc_tw2815_common[0x04] = DEFAULT_VDELAY_NTSC & 0xff; + tbl_ntsc_tw2815_common[0x06] |= + ((0x01 & (DEFAULT_VDELAY_NTSC >> 8)) << 4); + + /* Vertical Active Control */ + tbl_ntsc_tw2815_common[0x05] = DEFAULT_VACTIVE_NTSC & 0xff; + tbl_ntsc_tw2815_common[0x06] |= + ((0x01 & (DEFAULT_VACTIVE_NTSC >> 8)) << 5); + + tbl_pal_tw2815_common[0x06] = 0; + + /* Horizontal Delay Control */ + tbl_pal_tw2815_common[0x02] = DEFAULT_HDELAY_PAL & 0xff; + tbl_pal_tw2815_common[0x06] |= 0x03 & (DEFAULT_HDELAY_PAL >> 8); + + /* Horizontal Active Control */ + tbl_pal_tw2815_common[0x03] = DEFAULT_HACTIVE_PAL & 0xff; + tbl_pal_tw2815_common[0x06] |= + ((0x03 & (DEFAULT_HACTIVE_PAL >> 8)) << 2); + + /* Vertical Delay Control */ + tbl_pal_tw2815_common[0x04] = DEFAULT_VDELAY_PAL & 0xff; + tbl_pal_tw2815_common[0x06] |= + ((0x01 & (DEFAULT_VDELAY_PAL >> 8)) << 4); + + /* Vertical Active Control */ + tbl_pal_tw2815_common[0x05] = DEFAULT_VACTIVE_PAL & 0xff; + tbl_pal_tw2815_common[0x06] |= + ((0x01 & (DEFAULT_VACTIVE_PAL >> 8)) << 5); + + tbl_tw2815_common = + (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) ? + tbl_ntsc_tw2815_common : tbl_pal_tw2815_common; + + /* Dual ITU-R BT.656 format */ + tbl_tw2815_common[0x0d] |= 0x04; + + /* Audio configuration */ + tbl_tw2815_sfr[0x62 - 0x40] &= ~(3 << 6); + + if (solo_dev->nr_chans == 4) { + tbl_tw2815_sfr[0x63 - 0x40] |= 1; + tbl_tw2815_sfr[0x62 - 0x40] |= 3 << 6; + } else if (solo_dev->nr_chans == 8) { + tbl_tw2815_sfr[0x63 - 0x40] |= 2; + if (dev_addr == TW_CHIP_OFFSET_ADDR(0)) + tbl_tw2815_sfr[0x62 - 0x40] |= 1 << 6; + else if (dev_addr == TW_CHIP_OFFSET_ADDR(1)) + tbl_tw2815_sfr[0x62 - 0x40] |= 2 << 6; + } else if (solo_dev->nr_chans == 16) { + tbl_tw2815_sfr[0x63 - 0x40] |= 3; + if (dev_addr == TW_CHIP_OFFSET_ADDR(0)) + tbl_tw2815_sfr[0x62 - 0x40] |= 1 << 6; + else if (dev_addr == TW_CHIP_OFFSET_ADDR(1)) + tbl_tw2815_sfr[0x62 - 0x40] |= 0 << 6; + else if (dev_addr == TW_CHIP_OFFSET_ADDR(2)) + tbl_tw2815_sfr[0x62 - 0x40] |= 0 << 6; + else if (dev_addr == TW_CHIP_OFFSET_ADDR(3)) + tbl_tw2815_sfr[0x62 - 0x40] |= 2 << 6; + } + + /* Output mode of R_ADATM pin (0 mixing, 1 record) */ + /* tbl_tw2815_sfr[0x63 - 0x40] |= 0 << 2; */ + + /* 8KHz, used to be 16KHz, but changed for remote client compat */ + tbl_tw2815_sfr[0x62 - 0x40] |= 0 << 2; + tbl_tw2815_sfr[0x6c - 0x40] |= 0 << 2; + + /* Playback of right channel */ + tbl_tw2815_sfr[0x6c - 0x40] |= 1 << 5; + + /* Reserved value (XXX ??) */ + tbl_tw2815_sfr[0x5c - 0x40] |= 1 << 5; + + /* Analog output gain and mix ratio playback on full */ + tbl_tw2815_sfr[0x70 - 0x40] |= 0xff; + /* Select playback audio and mute all except */ + tbl_tw2815_sfr[0x71 - 0x40] |= 0x10; + tbl_tw2815_sfr[0x6d - 0x40] |= 0x0f; + + /* End of audio configuration */ + + for (ch = 0; ch < 4; ch++) { + tbl_tw2815_common[0x0d] &= ~3; + switch (ch) { + case 0: + tbl_tw2815_common[0x0d] |= 0x21; + break; + case 1: + tbl_tw2815_common[0x0d] |= 0x20; + break; + case 2: + tbl_tw2815_common[0x0d] |= 0x23; + break; + case 3: + tbl_tw2815_common[0x0d] |= 0x22; + break; + } + + for (i = 0; i < 0x0f; i++) { + if (i == 0x00) + continue; /* read-only */ + solo_i2c_writebyte(solo_dev, SOLO_I2C_TW, + dev_addr, (ch * 0x10) + i, + tbl_tw2815_common[i]); + } + } + + for (i = 0x40; i < 0x76; i++) { + /* Skip read-only and nop registers */ + if (i == 0x40 || i == 0x59 || i == 0x5a || + i == 0x5d || i == 0x5e || i == 0x5f) + continue; + + solo_i2c_writebyte(solo_dev, SOLO_I2C_TW, dev_addr, i, + tbl_tw2815_sfr[i - 0x40]); + } + + return 0; +} + +#define FIRST_ACTIVE_LINE 0x0008 +#define LAST_ACTIVE_LINE 0x0102 + +static void saa7128_setup(struct solo6010_dev *solo_dev) +{ + int i; + unsigned char regs[128] = { + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1C, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, + 0x59, 0x1d, 0x75, 0x3f, 0x06, 0x3f, 0x00, 0x00, + 0x1c, 0x33, 0x00, 0x3f, 0x00, 0x00, 0x3f, 0x00, + 0x1a, 0x1a, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x68, 0x10, 0x97, 0x4c, 0x18, + 0x9b, 0x93, 0x9f, 0xff, 0x7c, 0x34, 0x3f, 0x3f, + 0x3f, 0x83, 0x83, 0x80, 0x0d, 0x0f, 0xc3, 0x06, + 0x02, 0x80, 0x71, 0x77, 0xa7, 0x67, 0x66, 0x2e, + 0x7b, 0x11, 0x4f, 0x1f, 0x7c, 0xf0, 0x21, 0x77, + 0x41, 0x88, 0x41, 0x12, 0xed, 0x10, 0x10, 0x00, + 0x41, 0xc3, 0x00, 0x3e, 0xb8, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x08, 0xff, 0x80, 0x00, 0xff, 0xff, + }; + + regs[0x7A] = FIRST_ACTIVE_LINE & 0xff; + regs[0x7B] = LAST_ACTIVE_LINE & 0xff; + regs[0x7C] = ((1 << 7) | + (((LAST_ACTIVE_LINE >> 8) & 1) << 6) | + (((FIRST_ACTIVE_LINE >> 8) & 1) << 4)); + + /* PAL: XXX: We could do a second set of regs to avoid this */ + if (solo_dev->video_type != SOLO_VO_FMT_TYPE_NTSC) { + regs[0x28] = 0xE1; + + regs[0x5A] = 0x0F; + regs[0x61] = 0x02; + regs[0x62] = 0x35; + regs[0x63] = 0xCB; + regs[0x64] = 0x8A; + regs[0x65] = 0x09; + regs[0x66] = 0x2A; + + regs[0x6C] = 0xf1; + regs[0x6E] = 0x20; + + regs[0x7A] = 0x06 + 12; + regs[0x7b] = 0x24 + 12; + regs[0x7c] |= 1 << 6; + } + + /* First 0x25 bytes are read-only? */ + for (i = 0x26; i < 128; i++) { + if (i == 0x60 || i == 0x7D) + continue; + solo_i2c_writebyte(solo_dev, SOLO_I2C_SAA, 0x46, i, regs[i]); + } + + return; +} + +int solo_tw28_init(struct solo6010_dev *solo_dev) +{ + int i; + u8 value; + + /* Detect techwell chip type */ + for (i = 0; i < TW_NUM_CHIP; i++) { + value = solo_i2c_readbyte(solo_dev, SOLO_I2C_TW, + TW_CHIP_OFFSET_ADDR(i), 0xFF); + + switch (value >> 3) { + case 0x18: + solo_dev->tw2865 |= 1 << i; + solo_dev->tw28_cnt++; + break; + case 0x0c: + solo_dev->tw2864 |= 1 << i; + solo_dev->tw28_cnt++; + break; + default: + value = solo_i2c_readbyte(solo_dev, SOLO_I2C_TW, + TW_CHIP_OFFSET_ADDR(i), 0x59); + if ((value >> 3) == 0x04) { + solo_dev->tw2815 |= 1 << i; + solo_dev->tw28_cnt++; + } + } + } + + if (!solo_dev->tw28_cnt) + return -EINVAL; + + saa7128_setup(solo_dev); + + for (i = 0; i < solo_dev->tw28_cnt; i++) { + if ((solo_dev->tw2865 & (1 << i))) + tw2865_setup(solo_dev, TW_CHIP_OFFSET_ADDR(i)); + else if ((solo_dev->tw2864 & (1 << i))) + tw2864_setup(solo_dev, TW_CHIP_OFFSET_ADDR(i)); + else + tw2815_setup(solo_dev, TW_CHIP_OFFSET_ADDR(i)); + } + + dev_info(&solo_dev->pdev->dev, "Initialized %d tw28xx chip%s:", + solo_dev->tw28_cnt, solo_dev->tw28_cnt == 1 ? "" : "s"); + + if (solo_dev->tw2865) + printk(" tw2865[%d]", hweight32(solo_dev->tw2865)); + if (solo_dev->tw2864) + printk(" tw2864[%d]", hweight32(solo_dev->tw2864)); + if (solo_dev->tw2815) + printk(" tw2815[%d]", hweight32(solo_dev->tw2815)); + printk("\n"); + + return 0; +} + +/* + * We accessed the video status signal in the Techwell chip through + * iic/i2c because the video status reported by register REG_VI_STATUS1 + * (address 0x012C) of the SOLO6010 chip doesn't give the correct video + * status signal values. + */ +int tw28_get_video_status(struct solo6010_dev *solo_dev, u8 ch) +{ + u8 val, chip_num; + + /* Get the right chip and on-chip channel */ + chip_num = ch / 4; + ch %= 4; + + val = tw_readbyte(solo_dev, chip_num, TW286X_AV_STAT_ADDR, + TW_AV_STAT_ADDR) & 0x0f; + + return val & (1 << ch) ? 1 : 0; +} + +#if 0 +/* Status of audio from up to 4 techwell chips are combined into 1 variable. + * See techwell datasheet for details. */ +u16 tw28_get_audio_status(struct solo6010_dev *solo_dev) +{ + u8 val; + u16 status = 0; + int i; + + for (i = 0; i < solo_dev->tw28_cnt; i++) { + val = (tw_readbyte(solo_dev, i, TW286X_AV_STAT_ADDR, + TW_AV_STAT_ADDR) & 0xf0) >> 4; + status |= val << (i * 4); + } + + return status; +} +#endif + +int tw28_set_ctrl_val(struct solo6010_dev *solo_dev, u32 ctrl, u8 ch, + s32 val) +{ + char sval; + u8 chip_num; + + /* Get the right chip and on-chip channel */ + chip_num = ch / 4; + ch %= 4; + + if (val > 255 || val < 0) + return -ERANGE; + + switch (ctrl) { + case V4L2_CID_SHARPNESS: + /* Only 286x has sharpness */ + if (val > 0x0f || val < 0) + return -ERANGE; + if (is_tw286x(solo_dev, chip_num)) { + u8 v = solo_i2c_readbyte(solo_dev, SOLO_I2C_TW, + TW_CHIP_OFFSET_ADDR(chip_num), + TW286x_SHARPNESS(chip_num)); + v &= 0xf0; + v |= val; + solo_i2c_writebyte(solo_dev, SOLO_I2C_TW, + TW_CHIP_OFFSET_ADDR(chip_num), + TW286x_SHARPNESS(chip_num), v); + } else if (val != 0) + return -ERANGE; + break; + + case V4L2_CID_HUE: + if (is_tw286x(solo_dev, chip_num)) + sval = val - 128; + else + sval = (char)val; + tw_writebyte(solo_dev, chip_num, TW286x_HUE_ADDR(ch), + TW_HUE_ADDR(ch), sval); + + break; + + case V4L2_CID_SATURATION: + if (is_tw286x(solo_dev, chip_num)) { + solo_i2c_writebyte(solo_dev, SOLO_I2C_TW, + TW_CHIP_OFFSET_ADDR(chip_num), + TW286x_SATURATIONU_ADDR(ch), val); + } + tw_writebyte(solo_dev, chip_num, TW286x_SATURATIONV_ADDR(ch), + TW_SATURATION_ADDR(ch), val); + + break; + + case V4L2_CID_CONTRAST: + tw_writebyte(solo_dev, chip_num, TW286x_CONTRAST_ADDR(ch), + TW_CONTRAST_ADDR(ch), val); + break; + + case V4L2_CID_BRIGHTNESS: + if (is_tw286x(solo_dev, chip_num)) + sval = val - 128; + else + sval = (char)val; + tw_writebyte(solo_dev, chip_num, TW286x_BRIGHTNESS_ADDR(ch), + TW_BRIGHTNESS_ADDR(ch), sval); + + break; + default: + return -EINVAL; + } + + return 0; +} + +int tw28_get_ctrl_val(struct solo6010_dev *solo_dev, u32 ctrl, u8 ch, + s32 *val) +{ + u8 rval, chip_num; + + /* Get the right chip and on-chip channel */ + chip_num = ch / 4; + ch %= 4; + + switch (ctrl) { + case V4L2_CID_SHARPNESS: + /* Only 286x has sharpness */ + if (is_tw286x(solo_dev, chip_num)) { + rval = solo_i2c_readbyte(solo_dev, SOLO_I2C_TW, + TW_CHIP_OFFSET_ADDR(chip_num), + TW286x_SHARPNESS(chip_num)); + *val = rval & 0x0f; + } else + *val = 0; + break; + case V4L2_CID_HUE: + rval = tw_readbyte(solo_dev, chip_num, TW286x_HUE_ADDR(ch), + TW_HUE_ADDR(ch)); + if (is_tw286x(solo_dev, chip_num)) + *val = (s32)((char)rval) + 128; + else + *val = rval; + break; + case V4L2_CID_SATURATION: + *val = tw_readbyte(solo_dev, chip_num, + TW286x_SATURATIONU_ADDR(ch), + TW_SATURATION_ADDR(ch)); + break; + case V4L2_CID_CONTRAST: + *val = tw_readbyte(solo_dev, chip_num, + TW286x_CONTRAST_ADDR(ch), + TW_CONTRAST_ADDR(ch)); + break; + case V4L2_CID_BRIGHTNESS: + rval = tw_readbyte(solo_dev, chip_num, + TW286x_BRIGHTNESS_ADDR(ch), + TW_BRIGHTNESS_ADDR(ch)); + if (is_tw286x(solo_dev, chip_num)) + *val = (s32)((char)rval) + 128; + else + *val = rval; + break; + default: + return -EINVAL; + } + + return 0; +} + +#if 0 +/* + * For audio output volume, the output channel is only 1. In this case we + * don't need to offset TW_CHIP_OFFSET_ADDR. The TW_CHIP_OFFSET_ADDR used + * is the base address of the techwell chip. + */ +void tw2815_Set_AudioOutVol(struct solo6010_dev *solo_dev, unsigned int u_val) +{ + unsigned int val; + unsigned int chip_num; + + chip_num = (solo_dev->nr_chans - 1) / 4; + + val = tw_readbyte(solo_dev, chip_num, TW286x_AUDIO_OUTPUT_VOL_ADDR, + TW_AUDIO_OUTPUT_VOL_ADDR); + + u_val = (val & 0x0f) | (u_val << 4); + + tw_writebyte(solo_dev, chip_num, TW286x_AUDIO_OUTPUT_VOL_ADDR, + TW_AUDIO_OUTPUT_VOL_ADDR, u_val); +} +#endif + +u8 tw28_get_audio_gain(struct solo6010_dev *solo_dev, u8 ch) +{ + u8 val; + u8 chip_num; + + /* Get the right chip and on-chip channel */ + chip_num = ch / 4; + ch %= 4; + + val = tw_readbyte(solo_dev, chip_num, + TW286x_AUDIO_INPUT_GAIN_ADDR(ch), + TW_AUDIO_INPUT_GAIN_ADDR(ch)); + + return (ch % 2) ? (val >> 4) : (val & 0x0f); +} + +void tw28_set_audio_gain(struct solo6010_dev *solo_dev, u8 ch, u8 val) +{ + u8 old_val; + u8 chip_num; + + /* Get the right chip and on-chip channel */ + chip_num = ch / 4; + ch %= 4; + + old_val = tw_readbyte(solo_dev, chip_num, + TW286x_AUDIO_INPUT_GAIN_ADDR(ch), + TW_AUDIO_INPUT_GAIN_ADDR(ch)); + + val = (old_val & ((ch % 2) ? 0x0f : 0xf0)) | + ((ch % 2) ? (val << 4) : val); + + tw_writebyte(solo_dev, chip_num, TW286x_AUDIO_INPUT_GAIN_ADDR(ch), + TW_AUDIO_INPUT_GAIN_ADDR(ch), val); +} diff --git a/drivers/staging/solo6x10/tw28.h b/drivers/staging/solo6x10/tw28.h new file mode 100644 index 000000000000..4862ac90dbd9 --- /dev/null +++ b/drivers/staging/solo6x10/tw28.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com + * Copyright (C) 2010 Ben Collins + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __SOLO6010_TW28_H +#define __SOLO6010_TW28_H + +#include "solo6x10.h" + +#define TW_NUM_CHIP 4 +#define TW_BASE_ADDR 0x28 +#define TW_CHIP_OFFSET_ADDR(n) (TW_BASE_ADDR + (n)) + +/* tw2815 */ +#define TW_AV_STAT_ADDR 0x5a +#define TW_HUE_ADDR(n) (0x07 | ((n) << 4)) +#define TW_SATURATION_ADDR(n) (0x08 | ((n) << 4)) +#define TW_CONTRAST_ADDR(n) (0x09 | ((n) << 4)) +#define TW_BRIGHTNESS_ADDR(n) (0x0a | ((n) << 4)) +#define TW_AUDIO_OUTPUT_VOL_ADDR 0x70 +#define TW_AUDIO_INPUT_GAIN_ADDR(n) (0x60 + ((n > 1) ? 1 : 0)) + +/* tw286x */ +#define TW286X_AV_STAT_ADDR 0xfd +#define TW286x_HUE_ADDR(n) (0x06 | ((n) << 4)) +#define TW286x_SATURATIONU_ADDR(n) (0x04 | ((n) << 4)) +#define TW286x_SATURATIONV_ADDR(n) (0x05 | ((n) << 4)) +#define TW286x_CONTRAST_ADDR(n) (0x02 | ((n) << 4)) +#define TW286x_BRIGHTNESS_ADDR(n) (0x01 | ((n) << 4)) +#define TW286x_SHARPNESS(n) (0x03 | ((n) << 4)) +#define TW286x_AUDIO_OUTPUT_VOL_ADDR 0xdf +#define TW286x_AUDIO_INPUT_GAIN_ADDR(n) (0xD0 + ((n > 1) ? 1 : 0)) + +int solo_tw28_init(struct solo6010_dev *solo_dev); + +int tw28_set_ctrl_val(struct solo6010_dev *solo_dev, u32 ctrl, u8 ch, + s32 val); +int tw28_get_ctrl_val(struct solo6010_dev *solo_dev, u32 ctrl, u8 ch, + s32 *val); + +u8 tw28_get_audio_gain(struct solo6010_dev *solo_dev, u8 ch); +void tw28_set_audio_gain(struct solo6010_dev *solo_dev, u8 ch, u8 val); +int tw28_get_video_status(struct solo6010_dev *solo_dev, u8 ch); + +#if 0 +unsigned int tw2815_get_audio_status(struct SOLO6010 *solo6010); +void tw2815_Set_AudioOutVol(struct SOLO6010 *solo6010, unsigned int u_val); +#endif + +#endif /* __SOLO6010_TW28_H */ diff --git a/drivers/staging/solo6x10/v4l2-enc.c b/drivers/staging/solo6x10/v4l2-enc.c new file mode 100644 index 000000000000..b88192313112 --- /dev/null +++ b/drivers/staging/solo6x10/v4l2-enc.c @@ -0,0 +1,1825 @@ +/* + * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com + * Copyright (C) 2010 Ben Collins + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "solo6x10.h" +#include "tw28.h" +#include "jpeg.h" + +#define MIN_VID_BUFFERS 4 +#define FRAME_BUF_SIZE (128 * 1024) +#define MP4_QS 16 + +static int solo_enc_thread(void *data); + +extern unsigned video_nr; + +struct solo_enc_fh { + struct solo_enc_dev *enc; + u32 fmt; + u16 rd_idx; + u8 enc_on; + enum solo_enc_types type; + struct videobuf_queue vidq; + struct list_head vidq_active; + struct task_struct *kthread; + struct p2m_desc desc[SOLO_NR_P2M_DESC]; +}; + +static const u32 solo_user_ctrls[] = { + V4L2_CID_BRIGHTNESS, + V4L2_CID_CONTRAST, + V4L2_CID_SATURATION, + V4L2_CID_HUE, + V4L2_CID_SHARPNESS, + 0 +}; + +static const u32 solo_mpeg_ctrls[] = { + V4L2_CID_MPEG_VIDEO_ENCODING, + V4L2_CID_MPEG_VIDEO_GOP_SIZE, + 0 +}; + +static const u32 solo_private_ctrls[] = { + V4L2_CID_MOTION_ENABLE, + V4L2_CID_MOTION_THRESHOLD, + 0 +}; + +static const u32 solo_fmtx_ctrls[] = { + V4L2_CID_RDS_TX_RADIO_TEXT, + 0 +}; + +static const u32 *solo_ctrl_classes[] = { + solo_user_ctrls, + solo_mpeg_ctrls, + solo_fmtx_ctrls, + solo_private_ctrls, + NULL +}; + +static int solo_is_motion_on(struct solo_enc_dev *solo_enc) +{ + struct solo6010_dev *solo_dev = solo_enc->solo_dev; + u8 ch = solo_enc->ch; + + if (solo_dev->motion_mask & (1 << ch)) + return 1; + return 0; +} + +static void solo_motion_toggle(struct solo_enc_dev *solo_enc, int on) +{ + struct solo6010_dev *solo_dev = solo_enc->solo_dev; + u8 ch = solo_enc->ch; + + spin_lock(&solo_enc->lock); + + if (on) + solo_dev->motion_mask |= (1 << ch); + else + solo_dev->motion_mask &= ~(1 << ch); + + /* Do this regardless of if we are turning on or off */ + solo_reg_write(solo_enc->solo_dev, SOLO_VI_MOT_CLEAR, + 1 << solo_enc->ch); + solo_enc->motion_detected = 0; + + solo_reg_write(solo_dev, SOLO_VI_MOT_ADR, + SOLO_VI_MOTION_EN(solo_dev->motion_mask) | + (SOLO_MOTION_EXT_ADDR(solo_dev) >> 16)); + + if (solo_dev->motion_mask) + solo6010_irq_on(solo_dev, SOLO_IRQ_MOTION); + else + solo6010_irq_off(solo_dev, SOLO_IRQ_MOTION); + + spin_unlock(&solo_enc->lock); +} + +/* Should be called with solo_enc->lock held */ +static void solo_update_mode(struct solo_enc_dev *solo_enc) +{ + struct solo6010_dev *solo_dev = solo_enc->solo_dev; + + assert_spin_locked(&solo_enc->lock); + + solo_enc->interlaced = (solo_enc->mode & 0x08) ? 1 : 0; + solo_enc->bw_weight = max(solo_dev->fps / solo_enc->interval, 1); + + switch (solo_enc->mode) { + case SOLO_ENC_MODE_CIF: + solo_enc->width = solo_dev->video_hsize >> 1; + solo_enc->height = solo_dev->video_vsize; + break; + case SOLO_ENC_MODE_D1: + solo_enc->width = solo_dev->video_hsize; + solo_enc->height = solo_dev->video_vsize << 1; + solo_enc->bw_weight <<= 2; + break; + default: + WARN(1, "mode is unknown\n"); + } +} + +/* Should be called with solo_enc->lock held */ +static int solo_enc_on(struct solo_enc_fh *fh) +{ + struct solo_enc_dev *solo_enc = fh->enc; + u8 ch = solo_enc->ch; + struct solo6010_dev *solo_dev = solo_enc->solo_dev; + u8 interval; + + assert_spin_locked(&solo_enc->lock); + + if (fh->enc_on) + return 0; + + solo_update_mode(solo_enc); + + /* Make sure to bw check on first reader */ + if (!atomic_read(&solo_enc->readers)) { + if (solo_enc->bw_weight > solo_dev->enc_bw_remain) + return -EBUSY; + else + solo_dev->enc_bw_remain -= solo_enc->bw_weight; + } + + fh->enc_on = 1; + fh->rd_idx = solo_enc->solo_dev->enc_wr_idx; + + if (fh->type == SOLO_ENC_TYPE_EXT) + solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(ch), 1); + + if (atomic_inc_return(&solo_enc->readers) > 1) + return 0; + + /* Disable all encoding for this channel */ + solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(ch), 0); + + /* Common for both std and ext encoding */ + solo_reg_write(solo_dev, SOLO_VE_CH_INTL(ch), + solo_enc->interlaced ? 1 : 0); + + if (solo_enc->interlaced) + interval = solo_enc->interval - 1; + else + interval = solo_enc->interval; + + /* Standard encoding only */ + solo_reg_write(solo_dev, SOLO_VE_CH_GOP(ch), solo_enc->gop); + solo_reg_write(solo_dev, SOLO_VE_CH_QP(ch), solo_enc->qp); + solo_reg_write(solo_dev, SOLO_CAP_CH_INTV(ch), interval); + + /* Extended encoding only */ + solo_reg_write(solo_dev, SOLO_VE_CH_GOP_E(ch), solo_enc->gop); + solo_reg_write(solo_dev, SOLO_VE_CH_QP_E(ch), solo_enc->qp); + solo_reg_write(solo_dev, SOLO_CAP_CH_INTV_E(ch), interval); + + /* Enables the standard encoder */ + solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(ch), solo_enc->mode); + + /* Settle down Beavis... */ + mdelay(10); + + return 0; +} + +static void solo_enc_off(struct solo_enc_fh *fh) +{ + struct solo_enc_dev *solo_enc = fh->enc; + struct solo6010_dev *solo_dev = solo_enc->solo_dev; + + if (!fh->enc_on) + return; + + if (fh->kthread) { + kthread_stop(fh->kthread); + fh->kthread = NULL; + } + + solo_dev->enc_bw_remain += solo_enc->bw_weight; + fh->enc_on = 0; + + if (atomic_dec_return(&solo_enc->readers) > 0) + return; + + solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(solo_enc->ch), 0); + solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(solo_enc->ch), 0); +} + +static int solo_start_fh_thread(struct solo_enc_fh *fh) +{ + struct solo_enc_dev *solo_enc = fh->enc; + + fh->kthread = kthread_run(solo_enc_thread, fh, SOLO6010_NAME "_enc"); + + /* Oops, we had a problem */ + if (IS_ERR(fh->kthread)) { + spin_lock(&solo_enc->lock); + solo_enc_off(fh); + spin_unlock(&solo_enc->lock); + + return PTR_ERR(fh->kthread); + } + + return 0; +} + +static void enc_reset_gop(struct solo6010_dev *solo_dev, u8 ch) +{ + BUG_ON(ch >= solo_dev->nr_chans); + solo_reg_write(solo_dev, SOLO_VE_CH_GOP(ch), 1); + solo_dev->v4l2_enc[ch]->reset_gop = 1; +} + +static int enc_gop_reset(struct solo6010_dev *solo_dev, u8 ch, u8 vop) +{ + BUG_ON(ch >= solo_dev->nr_chans); + if (!solo_dev->v4l2_enc[ch]->reset_gop) + return 0; + if (vop) + return 1; + solo_dev->v4l2_enc[ch]->reset_gop = 0; + solo_reg_write(solo_dev, SOLO_VE_CH_GOP(ch), + solo_dev->v4l2_enc[ch]->gop); + return 0; +} + +static void enc_write_sg(struct scatterlist *sglist, void *buf, int size) +{ + struct scatterlist *sg; + u8 *src = buf; + + for (sg = sglist; sg && size > 0; sg = sg_next(sg)) { + u8 *p = sg_virt(sg); + size_t len = sg_dma_len(sg); + int i; + + for (i = 0; i < len && size; i++) + p[i] = *(src++); + } +} + +static int enc_get_mpeg_dma_sg(struct solo6010_dev *solo_dev, + struct p2m_desc *desc, + struct scatterlist *sglist, int skip, + unsigned int off, unsigned int size) +{ + int ret; + + if (off > SOLO_MP4E_EXT_SIZE(solo_dev)) + return -EINVAL; + + if (off + size <= SOLO_MP4E_EXT_SIZE(solo_dev)) { + return solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_MP4E, + desc, 0, sglist, skip, + SOLO_MP4E_EXT_ADDR(solo_dev) + off, size); + } + + /* Buffer wrap */ + ret = solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_MP4E, desc, 0, + sglist, skip, SOLO_MP4E_EXT_ADDR(solo_dev) + off, + SOLO_MP4E_EXT_SIZE(solo_dev) - off); + + ret |= solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_MP4E, desc, 0, + sglist, skip + SOLO_MP4E_EXT_SIZE(solo_dev) - off, + SOLO_MP4E_EXT_ADDR(solo_dev), + size + off - SOLO_MP4E_EXT_SIZE(solo_dev)); + + return ret; +} + +static int enc_get_mpeg_dma_t(struct solo6010_dev *solo_dev, + dma_addr_t buf, unsigned int off, + unsigned int size) +{ + int ret; + + if (off > SOLO_MP4E_EXT_SIZE(solo_dev)) + return -EINVAL; + + if (off + size <= SOLO_MP4E_EXT_SIZE(solo_dev)) { + return solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_MP4E, 0, buf, + SOLO_MP4E_EXT_ADDR(solo_dev) + off, size); + } + + /* Buffer wrap */ + ret = solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_MP4E, 0, buf, + SOLO_MP4E_EXT_ADDR(solo_dev) + off, + SOLO_MP4E_EXT_SIZE(solo_dev) - off); + + ret |= solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_MP4E, 0, + buf + SOLO_MP4E_EXT_SIZE(solo_dev) - off, + SOLO_MP4E_EXT_ADDR(solo_dev), + size + off - SOLO_MP4E_EXT_SIZE(solo_dev)); + + return ret; +} + +static int enc_get_mpeg_dma(struct solo6010_dev *solo_dev, void *buf, + unsigned int off, unsigned int size) +{ + int ret; + + dma_addr_t dma_addr = pci_map_single(solo_dev->pdev, buf, size, + PCI_DMA_FROMDEVICE); + ret = enc_get_mpeg_dma_t(solo_dev, dma_addr, off, size); + pci_unmap_single(solo_dev->pdev, dma_addr, size, PCI_DMA_FROMDEVICE); + + return ret; +} + +static int enc_get_jpeg_dma_sg(struct solo6010_dev *solo_dev, + struct p2m_desc *desc, + struct scatterlist *sglist, int skip, + unsigned int off, unsigned int size) +{ + int ret; + + if (off > SOLO_JPEG_EXT_SIZE(solo_dev)) + return -EINVAL; + + if (off + size <= SOLO_JPEG_EXT_SIZE(solo_dev)) { + return solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_JPEG, + desc, 0, sglist, skip, + SOLO_JPEG_EXT_ADDR(solo_dev) + off, size); + } + + /* Buffer wrap */ + ret = solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_JPEG, desc, 0, + sglist, skip, SOLO_JPEG_EXT_ADDR(solo_dev) + off, + SOLO_JPEG_EXT_SIZE(solo_dev) - off); + + ret |= solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_JPEG, desc, 0, + sglist, skip + SOLO_JPEG_EXT_SIZE(solo_dev) - off, + SOLO_JPEG_EXT_ADDR(solo_dev), + size + off - SOLO_JPEG_EXT_SIZE(solo_dev)); + + return ret; +} + +/* Returns true of __chk is within the first __range bytes of __off */ +#define OFF_IN_RANGE(__off, __range, __chk) \ + ((__off <= __chk) && ((__off + __range) >= __chk)) + +static void solo_jpeg_header(struct solo_enc_dev *solo_enc, + struct videobuf_dmabuf *vbuf) +{ + struct scatterlist *sg; + void *src = jpeg_header; + size_t copied = 0; + size_t to_copy = sizeof(jpeg_header); + + for (sg = vbuf->sglist; sg && copied < to_copy; sg = sg_next(sg)) { + size_t this_copy = min(sg_dma_len(sg), + (unsigned int)(to_copy - copied)); + u8 *p = sg_virt(sg); + + memcpy(p, src + copied, this_copy); + + if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 5)) + p[(SOF0_START + 5) - copied] = + 0xff & (solo_enc->height >> 8); + if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 6)) + p[(SOF0_START + 6) - copied] = 0xff & solo_enc->height; + if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 7)) + p[(SOF0_START + 7) - copied] = + 0xff & (solo_enc->width >> 8); + if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 8)) + p[(SOF0_START + 8) - copied] = 0xff & solo_enc->width; + + copied += this_copy; + } +} + +static int solo_fill_jpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf, + struct videobuf_buffer *vb, + struct videobuf_dmabuf *vbuf) +{ + struct solo6010_dev *solo_dev = fh->enc->solo_dev; + int size = enc_buf->jpeg_size; + + /* Copy the header first (direct write) */ + solo_jpeg_header(fh->enc, vbuf); + + vb->size = size + sizeof(jpeg_header); + + /* Grab the jpeg frame */ + return enc_get_jpeg_dma_sg(solo_dev, fh->desc, vbuf->sglist, + sizeof(jpeg_header), + enc_buf->jpeg_off, size); +} + +static inline int vop_interlaced(__le32 *vh) +{ + return (__le32_to_cpu(vh[0]) >> 30) & 1; +} + +static inline u32 vop_size(__le32 *vh) +{ + return __le32_to_cpu(vh[0]) & 0xFFFFF; +} + +static inline u8 vop_hsize(__le32 *vh) +{ + return (__le32_to_cpu(vh[1]) >> 8) & 0xFF; +} + +static inline u8 vop_vsize(__le32 *vh) +{ + return __le32_to_cpu(vh[1]) & 0xFF; +} + +/* must be called with *bits % 8 = 0 */ +static void write_bytes(u8 **out, unsigned *bits, const u8 *src, unsigned count) +{ + memcpy(*out, src, count); + *out += count; + *bits += count * 8; +} + +static void write_bits(u8 **out, unsigned *bits, u32 value, unsigned count) +{ + + value <<= 32 - count; // shift to the right + + while (count--) { + **out <<= 1; + **out |= !!(value & (1 << 31)); /* MSB */ + value <<= 1; + if (++(*bits) % 8 == 0) + (*out)++; + } +} + +static void write_ue(u8 **out, unsigned *bits, unsigned value) /* H.264 only */ +{ + uint32_t max = 0, cnt = 0; + + while (value > max) { + max = (max + 2) * 2 - 2; + cnt++; + } + write_bits(out, bits, 1, cnt + 1); + write_bits(out, bits, ~(max - value), cnt); +} + +static void write_se(u8 **out, unsigned *bits, int value) /* H.264 only */ +{ + if (value <= 0) + write_ue(out, bits, -value * 2); + else + write_ue(out, bits, value * 2 - 1); +} + +static void write_mpeg4_end(u8 **out, unsigned *bits) +{ + write_bits(out, bits, 0, 1); + /* align on 32-bit boundary */ + if (*bits % 32) + write_bits(out, bits, 0xFFFFFFFF, 32 - *bits % 32); +} + +static void write_h264_end(u8 **out, unsigned *bits, int align) +{ + write_bits(out, bits, 1, 1); + while ((*bits) % 8) + write_bits(out, bits, 0, 1); + if (align) + while ((*bits) % 32) + write_bits(out, bits, 0, 1); +} + +static void mpeg4_write_vol(u8 **out, struct solo6010_dev *solo_dev, + __le32 *vh, unsigned fps, unsigned interval) +{ + static const u8 hdr[] = { + 0, 0, 1, 0x00 /* video_object_start_code */, + 0, 0, 1, 0x20 /* video_object_layer_start_code */ + }; + unsigned bits = 0; + unsigned width = vop_hsize(vh) << 4; + unsigned height = vop_vsize(vh) << 4; + unsigned interlaced = vop_interlaced(vh); + + write_bytes(out, &bits, hdr, sizeof(hdr)); + write_bits(out, &bits, 0, 1); /* random_accessible_vol */ + write_bits(out, &bits, 0x04, 8); /* video_object_type_indication: main */ + write_bits(out, &bits, 1, 1); /* is_object_layer_identifier */ + write_bits(out, &bits, 2, 4); /* video_object_layer_verid: table V2-39 */ + write_bits(out, &bits, 0, 3); /* video_object_layer_priority */ + if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) + write_bits(out, &bits, 3, 4); /* aspect_ratio_info, assuming 4:3 */ + else + write_bits(out, &bits, 2, 4); + write_bits(out, &bits, 1, 1); /* vol_control_parameters */ + write_bits(out, &bits, 1, 2); /* chroma_format: 4:2:0 */ + write_bits(out, &bits, 1, 1); /* low_delay */ + write_bits(out, &bits, 0, 1); /* vbv_parameters */ + write_bits(out, &bits, 0, 2); /* video_object_layer_shape: rectangular */ + write_bits(out, &bits, 1, 1); /* marker_bit */ + write_bits(out, &bits, fps, 16); /* vop_time_increment_resolution */ + write_bits(out, &bits, 1, 1); /* marker_bit */ + write_bits(out, &bits, 1, 1); /* fixed_vop_rate */ + write_bits(out, &bits, interval, 15); /* fixed_vop_time_increment */ + write_bits(out, &bits, 1, 1); /* marker_bit */ + write_bits(out, &bits, width, 13); /* video_object_layer_width */ + write_bits(out, &bits, 1, 1); /* marker_bit */ + write_bits(out, &bits, height, 13); /* video_object_layer_height */ + write_bits(out, &bits, 1, 1); /* marker_bit */ + write_bits(out, &bits, interlaced, 1); /* interlaced */ + write_bits(out, &bits, 1, 1); /* obmc_disable */ + write_bits(out, &bits, 0, 2); /* sprite_enable */ + write_bits(out, &bits, 0, 1); /* not_8_bit */ + write_bits(out, &bits, 1, 0); /* quant_type */ + write_bits(out, &bits, 0, 1); /* load_intra_quant_mat */ + write_bits(out, &bits, 0, 1); /* load_nonintra_quant_mat */ + write_bits(out, &bits, 0, 1); /* quarter_sample */ + write_bits(out, &bits, 1, 1); /* complexity_estimation_disable */ + write_bits(out, &bits, 1, 1); /* resync_marker_disable */ + write_bits(out, &bits, 0, 1); /* data_partitioned */ + write_bits(out, &bits, 0, 1); /* newpred_enable */ + write_bits(out, &bits, 0, 1); /* reduced_resolution_vop_enable */ + write_bits(out, &bits, 0, 1); /* scalability */ + write_mpeg4_end(out, &bits); +} + +static void h264_write_vol(u8 **out, struct solo6010_dev *solo_dev, __le32 *vh) +{ + static const u8 sps[] = { + 0, 0, 0, 1 /* start code */, 0x67, 66 /* profile_idc */, + 0 /* constraints */, 30 /* level_idc */ + }; + static const u8 pps[] = { + 0, 0, 0, 1 /* start code */, 0x68 + }; + + unsigned bits = 0; + unsigned mbs_w = vop_hsize(vh); + unsigned mbs_h = vop_vsize(vh); + + write_bytes(out, &bits, sps, sizeof(sps)); + write_ue(out, &bits, 0); /* seq_parameter_set_id */ + write_ue(out, &bits, 5); /* log2_max_frame_num_minus4 */ + write_ue(out, &bits, 0); /* pic_order_cnt_type */ + write_ue(out, &bits, 6); /* log2_max_pic_order_cnt_lsb_minus4 */ + write_ue(out, &bits, 1); /* max_num_ref_frames */ + write_bits(out, &bits, 0, 1); /* gaps_in_frame_num_value_allowed_flag */ + write_ue(out, &bits, mbs_w - 1); /* pic_width_in_mbs_minus1 */ + write_ue(out, &bits, mbs_h - 1); /* pic_height_in_map_units_minus1 */ + write_bits(out, &bits, 1, 1); /* frame_mbs_only_flag */ + write_bits(out, &bits, 1, 1); /* direct_8x8_frame_field_flag */ + write_bits(out, &bits, 0, 1); /* frame_cropping_flag */ + write_bits(out, &bits, 0, 1); /* vui_parameters_present_flag */ + write_h264_end(out, &bits, 0); + + write_bytes(out, &bits, pps, sizeof(pps)); + write_ue(out, &bits, 0); /* pic_parameter_set_id */ + write_ue(out, &bits, 0); /* seq_parameter_set_id */ + write_bits(out, &bits, 0, 1); /* entropy_coding_mode_flag */ + write_bits(out, &bits, 0, 1); /* bottom_field_pic_order_in_frame_present_flag */ + write_ue(out, &bits, 0); /* num_slice_groups_minus1 */ + write_ue(out, &bits, 0); /* num_ref_idx_l0_default_active_minus1 */ + write_ue(out, &bits, 0); /* num_ref_idx_l1_default_active_minus1 */ + write_bits(out, &bits, 0, 1); /* weighted_pred_flag */ + write_bits(out, &bits, 0, 2); /* weighted_bipred_idc */ + write_se(out, &bits, 0); /* pic_init_qp_minus26 */ + write_se(out, &bits, 0); /* pic_init_qs_minus26 */ + write_se(out, &bits, 2); /* chroma_qp_index_offset */ + write_bits(out, &bits, 0, 1); /* deblocking_filter_control_present_flag */ + write_bits(out, &bits, 1, 1); /* constrained_intra_pred_flag */ + write_bits(out, &bits, 0, 1); /* redundant_pic_cnt_present_flag */ + write_h264_end(out, &bits, 1); +} + +static int solo_fill_mpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf, + struct videobuf_buffer *vb, + struct videobuf_dmabuf *vbuf) +{ + struct solo_enc_dev *solo_enc = fh->enc; + struct solo6010_dev *solo_dev = solo_enc->solo_dev; + +#define VH_WORDS 16 +#define MAX_VOL_HEADER_LENGTH 64 + + __le32 vh[VH_WORDS]; + int ret; + int frame_size, frame_off; + int skip = 0; + + if (WARN_ON_ONCE(enc_buf->size <= sizeof(vh))) + return -EINVAL; + + /* First get the hardware vop header (not real mpeg) */ + ret = enc_get_mpeg_dma(solo_dev, vh, enc_buf->off, sizeof(vh)); + if (WARN_ON_ONCE(ret)) + return ret; + + if (WARN_ON_ONCE(vop_size(vh) > enc_buf->size)) + return -EINVAL; + + vb->width = vop_hsize(vh) << 4; + vb->height = vop_vsize(vh) << 4; + vb->size = vop_size(vh); + + /* If this is a key frame, add extra m4v header */ + if (!enc_buf->vop) { + u8 header[MAX_VOL_HEADER_LENGTH], *out = header; + + if (solo_dev->flags & FLAGS_6110) + h264_write_vol(&out, solo_dev, vh); + else + mpeg4_write_vol(&out, solo_dev, vh, + solo_dev->fps * 1000, + solo_enc->interval * 1000); + skip = out - header; + enc_write_sg(vbuf->sglist, header, skip); + /* Adjust the dma buffer past this header */ + vb->size += skip; + } + + /* Now get the actual mpeg payload */ + frame_off = (enc_buf->off + sizeof(vh)) % SOLO_MP4E_EXT_SIZE(solo_dev); + frame_size = enc_buf->size - sizeof(vh); + + ret = enc_get_mpeg_dma_sg(solo_dev, fh->desc, vbuf->sglist, + skip, frame_off, frame_size); + WARN_ON_ONCE(ret); + + return ret; +} + +static void solo_enc_fillbuf(struct solo_enc_fh *fh, + struct videobuf_buffer *vb) +{ + struct solo_enc_dev *solo_enc = fh->enc; + struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct solo_enc_buf *enc_buf = NULL; + struct videobuf_dmabuf *vbuf; + int ret; + int error = 1; + u16 idx = fh->rd_idx; + + while (idx != solo_dev->enc_wr_idx) { + struct solo_enc_buf *ebuf = &solo_dev->enc_buf[idx]; + + idx = (idx + 1) % SOLO_NR_RING_BUFS; + + if (ebuf->ch != solo_enc->ch) + continue; + + if (fh->fmt == V4L2_PIX_FMT_MPEG) { + if (fh->type == ebuf->type) { + enc_buf = ebuf; + break; + } + } else { + /* For mjpeg, keep reading to the newest frame */ + enc_buf = ebuf; + } + } + + fh->rd_idx = idx; + + if (WARN_ON_ONCE(!enc_buf)) + goto buf_err; + + if ((fh->fmt == V4L2_PIX_FMT_MPEG && + vb->bsize < enc_buf->size) || + (fh->fmt == V4L2_PIX_FMT_MJPEG && + vb->bsize < (enc_buf->jpeg_size + sizeof(jpeg_header)))) { + WARN_ON_ONCE(1); + goto buf_err; + } + + vbuf = videobuf_to_dma(vb); + if (WARN_ON_ONCE(!vbuf)) + goto buf_err; + + if (fh->fmt == V4L2_PIX_FMT_MPEG) + ret = solo_fill_mpeg(fh, enc_buf, vb, vbuf); + else + ret = solo_fill_jpeg(fh, enc_buf, vb, vbuf); + + if (!ret) + error = 0; + +buf_err: + if (error) { + vb->state = VIDEOBUF_ERROR; + } else { + vb->field_count++; + vb->ts = enc_buf->ts; + vb->state = VIDEOBUF_DONE; + } + + wake_up(&vb->done); + + return; +} + +static void solo_enc_thread_try(struct solo_enc_fh *fh) +{ + struct solo_enc_dev *solo_enc = fh->enc; + struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct videobuf_buffer *vb; + + for (;;) { + spin_lock(&solo_enc->lock); + + if (fh->rd_idx == solo_dev->enc_wr_idx) + break; + + if (list_empty(&fh->vidq_active)) + break; + + vb = list_first_entry(&fh->vidq_active, + struct videobuf_buffer, queue); + + if (!waitqueue_active(&vb->done)) + break; + + list_del(&vb->queue); + + spin_unlock(&solo_enc->lock); + + solo_enc_fillbuf(fh, vb); + } + + assert_spin_locked(&solo_enc->lock); + spin_unlock(&solo_enc->lock); +} + +static int solo_enc_thread(void *data) +{ + struct solo_enc_fh *fh = data; + struct solo_enc_dev *solo_enc = fh->enc; + DECLARE_WAITQUEUE(wait, current); + + set_freezable(); + add_wait_queue(&solo_enc->thread_wait, &wait); + + for (;;) { + long timeout = schedule_timeout_interruptible(HZ); + if (timeout == -ERESTARTSYS || kthread_should_stop()) + break; + solo_enc_thread_try(fh); + try_to_freeze(); + } + + remove_wait_queue(&solo_enc->thread_wait, &wait); + + return 0; +} + +void solo_motion_isr(struct solo6010_dev *solo_dev) +{ + u32 status; + int i; + + solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_MOTION); + + status = solo_reg_read(solo_dev, SOLO_VI_MOT_STATUS); + + for (i = 0; i < solo_dev->nr_chans; i++) { + struct solo_enc_dev *solo_enc = solo_dev->v4l2_enc[i]; + + BUG_ON(solo_enc == NULL); + + if (solo_enc->motion_detected) + continue; + if (!(status & (1 << i))) + continue; + + solo_enc->motion_detected = 1; + } +} + +void solo_enc_v4l2_isr(struct solo6010_dev *solo_dev) +{ + struct solo_enc_buf *enc_buf; + u32 mpeg_current, mpeg_next, mpeg_size; + u32 jpeg_current, jpeg_next, jpeg_size; + u32 reg_mpeg_size; + u8 cur_q, vop_type; + u8 ch; + enum solo_enc_types enc_type; + + solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_ENCODER); + + cur_q = ((solo_reg_read(solo_dev, SOLO_VE_STATE(11)) & 0xF) + 1) % MP4_QS; + + reg_mpeg_size = ((solo_reg_read(solo_dev, SOLO_VE_STATE(0)) & 0xFFFFF) + 64 + 8) & ~7; + + while (solo_dev->enc_idx != cur_q) { + mpeg_current = solo_reg_read(solo_dev, + SOLO_VE_MPEG4_QUE(solo_dev->enc_idx)); + jpeg_current = solo_reg_read(solo_dev, + SOLO_VE_JPEG_QUE(solo_dev->enc_idx)); + solo_dev->enc_idx = (solo_dev->enc_idx + 1) % MP4_QS; + mpeg_next = solo_reg_read(solo_dev, + SOLO_VE_MPEG4_QUE(solo_dev->enc_idx)); + jpeg_next = solo_reg_read(solo_dev, + SOLO_VE_JPEG_QUE(solo_dev->enc_idx)); + + ch = (mpeg_current >> 24) & 0x1f; + if (ch >= SOLO_MAX_CHANNELS) { + ch -= SOLO_MAX_CHANNELS; + enc_type = SOLO_ENC_TYPE_EXT; + } else + enc_type = SOLO_ENC_TYPE_STD; + + vop_type = (mpeg_current >> 29) & 3; + + mpeg_current &= 0x00ffffff; + mpeg_next &= 0x00ffffff; + jpeg_current &= 0x00ffffff; + jpeg_next &= 0x00ffffff; + + mpeg_size = (SOLO_MP4E_EXT_SIZE(solo_dev) + + mpeg_next - mpeg_current) % + SOLO_MP4E_EXT_SIZE(solo_dev); + + jpeg_size = (SOLO_JPEG_EXT_SIZE(solo_dev) + + jpeg_next - jpeg_current) % + SOLO_JPEG_EXT_SIZE(solo_dev); + + /* XXX I think this means we had a ring overflow? */ + if (mpeg_current > mpeg_next && mpeg_size != reg_mpeg_size) { + enc_reset_gop(solo_dev, ch); + continue; + } + + /* When resetting the GOP, skip frames until I-frame */ + if (enc_gop_reset(solo_dev, ch, vop_type)) + continue; + + enc_buf = &solo_dev->enc_buf[solo_dev->enc_wr_idx]; + + enc_buf->vop = vop_type; + enc_buf->ch = ch; + enc_buf->off = mpeg_current; + enc_buf->size = mpeg_size; + enc_buf->jpeg_off = jpeg_current; + enc_buf->jpeg_size = jpeg_size; + enc_buf->type = enc_type; + + do_gettimeofday(&enc_buf->ts); + + solo_dev->enc_wr_idx = (solo_dev->enc_wr_idx + 1) % + SOLO_NR_RING_BUFS; + + wake_up_interruptible(&solo_dev->v4l2_enc[ch]->thread_wait); + } + + return; +} + +static int solo_enc_buf_setup(struct videobuf_queue *vq, unsigned int *count, + unsigned int *size) +{ + *size = FRAME_BUF_SIZE; + + if (*count < MIN_VID_BUFFERS) + *count = MIN_VID_BUFFERS; + + return 0; +} + +static int solo_enc_buf_prepare(struct videobuf_queue *vq, + struct videobuf_buffer *vb, + enum v4l2_field field) +{ + struct solo_enc_fh *fh = vq->priv_data; + struct solo_enc_dev *solo_enc = fh->enc; + + vb->size = FRAME_BUF_SIZE; + if (vb->baddr != 0 && vb->bsize < vb->size) + return -EINVAL; + + /* These properties only change when queue is idle */ + vb->width = solo_enc->width; + vb->height = solo_enc->height; + vb->field = field; + + if (vb->state == VIDEOBUF_NEEDS_INIT) { + int rc = videobuf_iolock(vq, vb, NULL); + if (rc < 0) { + struct videobuf_dmabuf *dma = videobuf_to_dma(vb); + videobuf_dma_unmap(vq->dev, dma); + videobuf_dma_free(dma); + vb->state = VIDEOBUF_NEEDS_INIT; + return rc; + } + } + vb->state = VIDEOBUF_PREPARED; + + return 0; +} + +static void solo_enc_buf_queue(struct videobuf_queue *vq, + struct videobuf_buffer *vb) +{ + struct solo_enc_fh *fh = vq->priv_data; + + vb->state = VIDEOBUF_QUEUED; + list_add_tail(&vb->queue, &fh->vidq_active); + wake_up_interruptible(&fh->enc->thread_wait); +} + +static void solo_enc_buf_release(struct videobuf_queue *vq, + struct videobuf_buffer *vb) +{ + struct videobuf_dmabuf *dma = videobuf_to_dma(vb); + + videobuf_dma_unmap(vq->dev, dma); + videobuf_dma_free(dma); + vb->state = VIDEOBUF_NEEDS_INIT; +} + +static struct videobuf_queue_ops solo_enc_video_qops = { + .buf_setup = solo_enc_buf_setup, + .buf_prepare = solo_enc_buf_prepare, + .buf_queue = solo_enc_buf_queue, + .buf_release = solo_enc_buf_release, +}; + +static unsigned int solo_enc_poll(struct file *file, + struct poll_table_struct *wait) +{ + struct solo_enc_fh *fh = file->private_data; + + return videobuf_poll_stream(file, &fh->vidq, wait); +} + +static int solo_enc_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct solo_enc_fh *fh = file->private_data; + + return videobuf_mmap_mapper(&fh->vidq, vma); +} + +static int solo_enc_open(struct file *file) +{ + struct solo_enc_dev *solo_enc = video_drvdata(file); + struct solo_enc_fh *fh; + + fh = kzalloc(sizeof(*fh), GFP_KERNEL); + if (fh == NULL) + return -ENOMEM; + + fh->enc = solo_enc; + file->private_data = fh; + INIT_LIST_HEAD(&fh->vidq_active); + fh->fmt = V4L2_PIX_FMT_MPEG; + fh->type = SOLO_ENC_TYPE_STD; + + videobuf_queue_sg_init(&fh->vidq, &solo_enc_video_qops, + &solo_enc->solo_dev->pdev->dev, + &solo_enc->lock, + V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_FIELD_INTERLACED, + sizeof(struct videobuf_buffer), fh, NULL); + + return 0; +} + +static ssize_t solo_enc_read(struct file *file, char __user *data, + size_t count, loff_t *ppos) +{ + struct solo_enc_fh *fh = file->private_data; + struct solo_enc_dev *solo_enc = fh->enc; + + /* Make sure the encoder is on */ + if (!fh->enc_on) { + int ret; + + spin_lock(&solo_enc->lock); + ret = solo_enc_on(fh); + spin_unlock(&solo_enc->lock); + if (ret) + return ret; + + ret = solo_start_fh_thread(fh); + if (ret) + return ret; + } + + return videobuf_read_stream(&fh->vidq, data, count, ppos, 0, + file->f_flags & O_NONBLOCK); +} + +static int solo_enc_release(struct file *file) +{ + struct solo_enc_fh *fh = file->private_data; + struct solo_enc_dev *solo_enc = fh->enc; + + videobuf_stop(&fh->vidq); + videobuf_mmap_free(&fh->vidq); + + spin_lock(&solo_enc->lock); + solo_enc_off(fh); + spin_unlock(&solo_enc->lock); + + kfree(fh); + + return 0; +} + +static int solo_enc_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + struct solo_enc_fh *fh = priv; + struct solo_enc_dev *solo_enc = fh->enc; + struct solo6010_dev *solo_dev = solo_enc->solo_dev; + + strcpy(cap->driver, SOLO6010_NAME); + snprintf(cap->card, sizeof(cap->card), "Softlogic 6010 Enc %d", + solo_enc->ch); + snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI %s", + pci_name(solo_dev->pdev)); + cap->version = SOLO6010_VER_NUM; + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_READWRITE | + V4L2_CAP_STREAMING; + return 0; +} + +static int solo_enc_enum_input(struct file *file, void *priv, + struct v4l2_input *input) +{ + struct solo_enc_fh *fh = priv; + struct solo_enc_dev *solo_enc = fh->enc; + struct solo6010_dev *solo_dev = solo_enc->solo_dev; + + if (input->index) + return -EINVAL; + + snprintf(input->name, sizeof(input->name), "Encoder %d", + solo_enc->ch + 1); + input->type = V4L2_INPUT_TYPE_CAMERA; + + if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) + input->std = V4L2_STD_NTSC_M; + else + input->std = V4L2_STD_PAL_B; + + if (!tw28_get_video_status(solo_dev, solo_enc->ch)) + input->status = V4L2_IN_ST_NO_SIGNAL; + + return 0; +} + +static int solo_enc_set_input(struct file *file, void *priv, unsigned int index) +{ + if (index) + return -EINVAL; + + return 0; +} + +static int solo_enc_get_input(struct file *file, void *priv, + unsigned int *index) +{ + *index = 0; + + return 0; +} + +static int solo_enc_enum_fmt_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + switch (f->index) { + case 0: + f->pixelformat = V4L2_PIX_FMT_MPEG; + strcpy(f->description, "MPEG-4 AVC"); + break; + case 1: + f->pixelformat = V4L2_PIX_FMT_MJPEG; + strcpy(f->description, "MJPEG"); + break; + default: + return -EINVAL; + } + + f->flags = V4L2_FMT_FLAG_COMPRESSED; + + return 0; +} + +static int solo_enc_try_fmt_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct solo_enc_fh *fh = priv; + struct solo_enc_dev *solo_enc = fh->enc; + struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct v4l2_pix_format *pix = &f->fmt.pix; + + if (pix->pixelformat != V4L2_PIX_FMT_MPEG && + pix->pixelformat != V4L2_PIX_FMT_MJPEG) + return -EINVAL; + + /* We cannot change width/height in mid read */ + if (atomic_read(&solo_enc->readers) > 0) { + if (pix->width != solo_enc->width || + pix->height != solo_enc->height) + return -EBUSY; + } + + if (pix->width < solo_dev->video_hsize || + pix->height < solo_dev->video_vsize << 1) { + /* Default to CIF 1/2 size */ + pix->width = solo_dev->video_hsize >> 1; + pix->height = solo_dev->video_vsize; + } else { + /* Full frame */ + pix->width = solo_dev->video_hsize; + pix->height = solo_dev->video_vsize << 1; + } + + if (pix->field == V4L2_FIELD_ANY) + pix->field = V4L2_FIELD_INTERLACED; + else if (pix->field != V4L2_FIELD_INTERLACED) + pix->field = V4L2_FIELD_INTERLACED; + + /* Just set these */ + pix->colorspace = V4L2_COLORSPACE_SMPTE170M; + pix->sizeimage = FRAME_BUF_SIZE; + + return 0; +} + +static int solo_enc_set_fmt_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct solo_enc_fh *fh = priv; + struct solo_enc_dev *solo_enc = fh->enc; + struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct v4l2_pix_format *pix = &f->fmt.pix; + int ret; + + spin_lock(&solo_enc->lock); + + ret = solo_enc_try_fmt_cap(file, priv, f); + if (ret) { + spin_unlock(&solo_enc->lock); + return ret; + } + + if (pix->width == solo_dev->video_hsize) + solo_enc->mode = SOLO_ENC_MODE_D1; + else + solo_enc->mode = SOLO_ENC_MODE_CIF; + + /* This does not change the encoder at all */ + fh->fmt = pix->pixelformat; + + if (pix->priv) + fh->type = SOLO_ENC_TYPE_EXT; + ret = solo_enc_on(fh); + + spin_unlock(&solo_enc->lock); + + if (ret) + return ret; + + return solo_start_fh_thread(fh); +} + +static int solo_enc_get_fmt_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct solo_enc_fh *fh = priv; + struct solo_enc_dev *solo_enc = fh->enc; + struct v4l2_pix_format *pix = &f->fmt.pix; + + pix->width = solo_enc->width; + pix->height = solo_enc->height; + pix->pixelformat = fh->fmt; + pix->field = solo_enc->interlaced ? V4L2_FIELD_INTERLACED : + V4L2_FIELD_NONE; + pix->sizeimage = FRAME_BUF_SIZE; + pix->colorspace = V4L2_COLORSPACE_SMPTE170M; + + return 0; +} + +static int solo_enc_reqbufs(struct file *file, void *priv, + struct v4l2_requestbuffers *req) +{ + struct solo_enc_fh *fh = priv; + + return videobuf_reqbufs(&fh->vidq, req); +} + +static int solo_enc_querybuf(struct file *file, void *priv, + struct v4l2_buffer *buf) +{ + struct solo_enc_fh *fh = priv; + + return videobuf_querybuf(&fh->vidq, buf); +} + +static int solo_enc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) +{ + struct solo_enc_fh *fh = priv; + + return videobuf_qbuf(&fh->vidq, buf); +} + +static int solo_enc_dqbuf(struct file *file, void *priv, + struct v4l2_buffer *buf) +{ + struct solo_enc_fh *fh = priv; + struct solo_enc_dev *solo_enc = fh->enc; + int ret; + + /* Make sure the encoder is on */ + if (!fh->enc_on) { + spin_lock(&solo_enc->lock); + ret = solo_enc_on(fh); + spin_unlock(&solo_enc->lock); + if (ret) + return ret; + + ret = solo_start_fh_thread(fh); + if (ret) + return ret; + } + + ret = videobuf_dqbuf(&fh->vidq, buf, file->f_flags & O_NONBLOCK); + if (ret) + return ret; + + /* Signal motion detection */ + if (solo_is_motion_on(solo_enc)) { + buf->flags |= V4L2_BUF_FLAG_MOTION_ON; + if (solo_enc->motion_detected) { + buf->flags |= V4L2_BUF_FLAG_MOTION_DETECTED; + solo_reg_write(solo_enc->solo_dev, SOLO_VI_MOT_CLEAR, + 1 << solo_enc->ch); + solo_enc->motion_detected = 0; + } + } + + /* Check for key frame on mpeg data */ + if (fh->fmt == V4L2_PIX_FMT_MPEG) { + struct videobuf_dmabuf *vbuf = + videobuf_to_dma(fh->vidq.bufs[buf->index]); + + if (vbuf) { + u8 *p = sg_virt(vbuf->sglist); + if (p[3] == 0x00) + buf->flags |= V4L2_BUF_FLAG_KEYFRAME; + else + buf->flags |= V4L2_BUF_FLAG_PFRAME; + } + } + + return 0; +} + +static int solo_enc_streamon(struct file *file, void *priv, + enum v4l2_buf_type i) +{ + struct solo_enc_fh *fh = priv; + + if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + return videobuf_streamon(&fh->vidq); +} + +static int solo_enc_streamoff(struct file *file, void *priv, + enum v4l2_buf_type i) +{ + struct solo_enc_fh *fh = priv; + + if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + return videobuf_streamoff(&fh->vidq); +} + +static int solo_enc_s_std(struct file *file, void *priv, v4l2_std_id *i) +{ + return 0; +} + +static int solo_enum_framesizes(struct file *file, void *priv, + struct v4l2_frmsizeenum *fsize) +{ + struct solo_enc_fh *fh = priv; + struct solo6010_dev *solo_dev = fh->enc->solo_dev; + + if (fsize->pixel_format != V4L2_PIX_FMT_MPEG) + return -EINVAL; + + switch (fsize->index) { + case 0: + fsize->discrete.width = solo_dev->video_hsize >> 1; + fsize->discrete.height = solo_dev->video_vsize; + break; + case 1: + fsize->discrete.width = solo_dev->video_hsize; + fsize->discrete.height = solo_dev->video_vsize << 1; + break; + default: + return -EINVAL; + } + + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + + return 0; +} + +static int solo_enum_frameintervals(struct file *file, void *priv, + struct v4l2_frmivalenum *fintv) +{ + struct solo_enc_fh *fh = priv; + struct solo6010_dev *solo_dev = fh->enc->solo_dev; + + if (fintv->pixel_format != V4L2_PIX_FMT_MPEG || fintv->index) + return -EINVAL; + + fintv->type = V4L2_FRMIVAL_TYPE_STEPWISE; + + fintv->stepwise.min.numerator = solo_dev->fps; + fintv->stepwise.min.denominator = 1; + + fintv->stepwise.max.numerator = solo_dev->fps; + fintv->stepwise.max.denominator = 15; + + fintv->stepwise.step.numerator = 1; + fintv->stepwise.step.denominator = 1; + + return 0; +} + +static int solo_g_parm(struct file *file, void *priv, + struct v4l2_streamparm *sp) +{ + struct solo_enc_fh *fh = priv; + struct solo_enc_dev *solo_enc = fh->enc; + struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct v4l2_captureparm *cp = &sp->parm.capture; + + cp->capability = V4L2_CAP_TIMEPERFRAME; + cp->timeperframe.numerator = solo_enc->interval; + cp->timeperframe.denominator = solo_dev->fps; + cp->capturemode = 0; + /* XXX: Shouldn't we be able to get/set this from videobuf? */ + cp->readbuffers = 2; + + return 0; +} + +static int solo_s_parm(struct file *file, void *priv, + struct v4l2_streamparm *sp) +{ + struct solo_enc_fh *fh = priv; + struct solo_enc_dev *solo_enc = fh->enc; + struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct v4l2_captureparm *cp = &sp->parm.capture; + + spin_lock(&solo_enc->lock); + + if (atomic_read(&solo_enc->readers) > 0) { + spin_unlock(&solo_enc->lock); + return -EBUSY; + } + + if ((cp->timeperframe.numerator == 0) || + (cp->timeperframe.denominator == 0)) { + /* reset framerate */ + cp->timeperframe.numerator = 1; + cp->timeperframe.denominator = solo_dev->fps; + } + + if (cp->timeperframe.denominator != solo_dev->fps) + cp->timeperframe.denominator = solo_dev->fps; + + if (cp->timeperframe.numerator > 15) + cp->timeperframe.numerator = 15; + + solo_enc->interval = cp->timeperframe.numerator; + + cp->capability = V4L2_CAP_TIMEPERFRAME; + + solo_enc->gop = max(solo_dev->fps / solo_enc->interval, 1); + solo_update_mode(solo_enc); + + spin_unlock(&solo_enc->lock); + + return 0; +} + +static int solo_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *qc) +{ + struct solo_enc_fh *fh = priv; + struct solo_enc_dev *solo_enc = fh->enc; + struct solo6010_dev *solo_dev = solo_enc->solo_dev; + + qc->id = v4l2_ctrl_next(solo_ctrl_classes, qc->id); + if (!qc->id) + return -EINVAL; + + switch (qc->id) { + case V4L2_CID_BRIGHTNESS: + case V4L2_CID_CONTRAST: + case V4L2_CID_SATURATION: + case V4L2_CID_HUE: + return v4l2_ctrl_query_fill(qc, 0x00, 0xff, 1, 0x80); + case V4L2_CID_SHARPNESS: + return v4l2_ctrl_query_fill(qc, 0x00, 0x0f, 1, 0x00); + case V4L2_CID_MPEG_VIDEO_ENCODING: + return v4l2_ctrl_query_fill( + qc, V4L2_MPEG_VIDEO_ENCODING_MPEG_1, + V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1, + V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC); + case V4L2_CID_MPEG_VIDEO_GOP_SIZE: + return v4l2_ctrl_query_fill(qc, 1, 255, 1, solo_dev->fps); +#ifdef PRIVATE_CIDS + case V4L2_CID_MOTION_THRESHOLD: + qc->flags |= V4L2_CTRL_FLAG_SLIDER; + qc->type = V4L2_CTRL_TYPE_INTEGER; + qc->minimum = 0; + qc->maximum = 0xffff; + qc->step = 1; + qc->default_value = SOLO_DEF_MOT_THRESH; + strlcpy(qc->name, "Motion Detection Threshold", + sizeof(qc->name)); + return 0; + case V4L2_CID_MOTION_ENABLE: + qc->type = V4L2_CTRL_TYPE_BOOLEAN; + qc->minimum = 0; + qc->maximum = qc->step = 1; + qc->default_value = 0; + strlcpy(qc->name, "Motion Detection Enable", sizeof(qc->name)); + return 0; +#else + case V4L2_CID_MOTION_THRESHOLD: + return v4l2_ctrl_query_fill(qc, 0, 0xffff, 1, + SOLO_DEF_MOT_THRESH); + case V4L2_CID_MOTION_ENABLE: + return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); +#endif + case V4L2_CID_RDS_TX_RADIO_TEXT: + qc->type = V4L2_CTRL_TYPE_STRING; + qc->minimum = 0; + qc->maximum = OSD_TEXT_MAX; + qc->step = 1; + qc->default_value = 0; + strlcpy(qc->name, "OSD Text", sizeof(qc->name)); + return 0; + } + + return -EINVAL; +} + +static int solo_querymenu(struct file *file, void *priv, + struct v4l2_querymenu *qmenu) +{ + struct v4l2_queryctrl qctrl; + int err; + + qctrl.id = qmenu->id; + err = solo_queryctrl(file, priv, &qctrl); + if (err) + return err; + + return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL); +} + +static int solo_g_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct solo_enc_fh *fh = priv; + struct solo_enc_dev *solo_enc = fh->enc; + struct solo6010_dev *solo_dev = solo_enc->solo_dev; + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + case V4L2_CID_CONTRAST: + case V4L2_CID_SATURATION: + case V4L2_CID_HUE: + case V4L2_CID_SHARPNESS: + return tw28_get_ctrl_val(solo_dev, ctrl->id, solo_enc->ch, + &ctrl->value); + case V4L2_CID_MPEG_VIDEO_ENCODING: + ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC; + break; + case V4L2_CID_MPEG_VIDEO_GOP_SIZE: + ctrl->value = solo_enc->gop; + break; + case V4L2_CID_MOTION_THRESHOLD: + ctrl->value = solo_enc->motion_thresh; + break; + case V4L2_CID_MOTION_ENABLE: + ctrl->value = solo_is_motion_on(solo_enc); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int solo_s_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct solo_enc_fh *fh = priv; + struct solo_enc_dev *solo_enc = fh->enc; + struct solo6010_dev *solo_dev = solo_enc->solo_dev; + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + case V4L2_CID_CONTRAST: + case V4L2_CID_SATURATION: + case V4L2_CID_HUE: + case V4L2_CID_SHARPNESS: + return tw28_set_ctrl_val(solo_dev, ctrl->id, solo_enc->ch, + ctrl->value); + case V4L2_CID_MPEG_VIDEO_ENCODING: + if (ctrl->value != V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC) + return -ERANGE; + break; + case V4L2_CID_MPEG_VIDEO_GOP_SIZE: + if (ctrl->value < 1 || ctrl->value > 255) + return -ERANGE; + solo_enc->gop = ctrl->value; + solo_reg_write(solo_dev, SOLO_VE_CH_GOP(solo_enc->ch), + solo_enc->gop); + solo_reg_write(solo_dev, SOLO_VE_CH_GOP_E(solo_enc->ch), + solo_enc->gop); + break; + case V4L2_CID_MOTION_THRESHOLD: + /* TODO accept value on lower 16-bits and use high + * 16-bits to assign the value to a specific block */ + if (ctrl->value < 0 || ctrl->value > 0xffff) + return -ERANGE; + solo_enc->motion_thresh = ctrl->value; + solo_set_motion_threshold(solo_dev, solo_enc->ch, ctrl->value); + break; + case V4L2_CID_MOTION_ENABLE: + solo_motion_toggle(solo_enc, ctrl->value); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int solo_s_ext_ctrls(struct file *file, void *priv, + struct v4l2_ext_controls *ctrls) +{ + struct solo_enc_fh *fh = priv; + struct solo_enc_dev *solo_enc = fh->enc; + int i; + + for (i = 0; i < ctrls->count; i++) { + struct v4l2_ext_control *ctrl = (ctrls->controls + i); + int err; + + switch (ctrl->id) { + case V4L2_CID_RDS_TX_RADIO_TEXT: + if (ctrl->size - 1 > OSD_TEXT_MAX) + err = -ERANGE; + else { + err = copy_from_user(solo_enc->osd_text, + ctrl->string, + OSD_TEXT_MAX); + solo_enc->osd_text[OSD_TEXT_MAX] = '\0'; + if (!err) + err = solo_osd_print(solo_enc); + } + break; + default: + err = -EINVAL; + } + + if (err < 0) { + ctrls->error_idx = i; + return err; + } + } + + return 0; +} + +static int solo_g_ext_ctrls(struct file *file, void *priv, + struct v4l2_ext_controls *ctrls) +{ + struct solo_enc_fh *fh = priv; + struct solo_enc_dev *solo_enc = fh->enc; + int i; + + for (i = 0; i < ctrls->count; i++) { + struct v4l2_ext_control *ctrl = (ctrls->controls + i); + int err; + + switch (ctrl->id) { + case V4L2_CID_RDS_TX_RADIO_TEXT: + if (ctrl->size < OSD_TEXT_MAX) { + ctrl->size = OSD_TEXT_MAX; + err = -ENOSPC; + } else { + err = copy_to_user(ctrl->string, + solo_enc->osd_text, + OSD_TEXT_MAX); + } + break; + default: + err = -EINVAL; + } + + if (err < 0) { + ctrls->error_idx = i; + return err; + } + } + + return 0; +} + +static const struct v4l2_file_operations solo_enc_fops = { + .owner = THIS_MODULE, + .open = solo_enc_open, + .release = solo_enc_release, + .read = solo_enc_read, + .poll = solo_enc_poll, + .mmap = solo_enc_mmap, + .ioctl = video_ioctl2, +}; + +static const struct v4l2_ioctl_ops solo_enc_ioctl_ops = { + .vidioc_querycap = solo_enc_querycap, + .vidioc_s_std = solo_enc_s_std, + /* Input callbacks */ + .vidioc_enum_input = solo_enc_enum_input, + .vidioc_s_input = solo_enc_set_input, + .vidioc_g_input = solo_enc_get_input, + /* Video capture format callbacks */ + .vidioc_enum_fmt_vid_cap = solo_enc_enum_fmt_cap, + .vidioc_try_fmt_vid_cap = solo_enc_try_fmt_cap, + .vidioc_s_fmt_vid_cap = solo_enc_set_fmt_cap, + .vidioc_g_fmt_vid_cap = solo_enc_get_fmt_cap, + /* Streaming I/O */ + .vidioc_reqbufs = solo_enc_reqbufs, + .vidioc_querybuf = solo_enc_querybuf, + .vidioc_qbuf = solo_enc_qbuf, + .vidioc_dqbuf = solo_enc_dqbuf, + .vidioc_streamon = solo_enc_streamon, + .vidioc_streamoff = solo_enc_streamoff, + /* Frame size and interval */ + .vidioc_enum_framesizes = solo_enum_framesizes, + .vidioc_enum_frameintervals = solo_enum_frameintervals, + /* Video capture parameters */ + .vidioc_s_parm = solo_s_parm, + .vidioc_g_parm = solo_g_parm, + /* Controls */ + .vidioc_queryctrl = solo_queryctrl, + .vidioc_querymenu = solo_querymenu, + .vidioc_g_ctrl = solo_g_ctrl, + .vidioc_s_ctrl = solo_s_ctrl, + .vidioc_g_ext_ctrls = solo_g_ext_ctrls, + .vidioc_s_ext_ctrls = solo_s_ext_ctrls, +}; + +static struct video_device solo_enc_template = { + .name = SOLO6010_NAME, + .fops = &solo_enc_fops, + .ioctl_ops = &solo_enc_ioctl_ops, + .minor = -1, + .release = video_device_release, + + .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL_B, + .current_norm = V4L2_STD_NTSC_M, +}; + +static struct solo_enc_dev *solo_enc_alloc(struct solo6010_dev *solo_dev, u8 ch) +{ + struct solo_enc_dev *solo_enc; + int ret; + + solo_enc = kzalloc(sizeof(*solo_enc), GFP_KERNEL); + if (!solo_enc) + return ERR_PTR(-ENOMEM); + + solo_enc->vfd = video_device_alloc(); + if (!solo_enc->vfd) { + kfree(solo_enc); + return ERR_PTR(-ENOMEM); + } + + solo_enc->solo_dev = solo_dev; + solo_enc->ch = ch; + + *solo_enc->vfd = solo_enc_template; + solo_enc->vfd->parent = &solo_dev->pdev->dev; + ret = video_register_device(solo_enc->vfd, VFL_TYPE_GRABBER, + video_nr); + if (ret < 0) { + video_device_release(solo_enc->vfd); + kfree(solo_enc); + return ERR_PTR(ret); + } + + video_set_drvdata(solo_enc->vfd, solo_enc); + + snprintf(solo_enc->vfd->name, sizeof(solo_enc->vfd->name), + "%s-enc (%i/%i)", SOLO6010_NAME, solo_dev->vfd->num, + solo_enc->vfd->num); + + if (video_nr != -1) + video_nr++; + + spin_lock_init(&solo_enc->lock); + init_waitqueue_head(&solo_enc->thread_wait); + atomic_set(&solo_enc->readers, 0); + + solo_enc->qp = SOLO_DEFAULT_QP; + solo_enc->gop = solo_dev->fps; + solo_enc->interval = 1; + solo_enc->mode = SOLO_ENC_MODE_CIF; + solo_enc->motion_thresh = SOLO_DEF_MOT_THRESH; + + spin_lock(&solo_enc->lock); + solo_update_mode(solo_enc); + spin_unlock(&solo_enc->lock); + + return solo_enc; +} + +static void solo_enc_free(struct solo_enc_dev *solo_enc) +{ + if (solo_enc == NULL) + return; + + video_unregister_device(solo_enc->vfd); + kfree(solo_enc); +} + +int solo_enc_v4l2_init(struct solo6010_dev *solo_dev) +{ + int i; + + for (i = 0; i < solo_dev->nr_chans; i++) { + solo_dev->v4l2_enc[i] = solo_enc_alloc(solo_dev, i); + if (IS_ERR(solo_dev->v4l2_enc[i])) + break; + } + + if (i != solo_dev->nr_chans) { + int ret = PTR_ERR(solo_dev->v4l2_enc[i]); + while (i--) + solo_enc_free(solo_dev->v4l2_enc[i]); + return ret; + } + + /* D1@MAX-FPS * 4 */ + solo_dev->enc_bw_remain = solo_dev->fps * 4 * 4; + + dev_info(&solo_dev->pdev->dev, "Encoders as /dev/video%d-%d\n", + solo_dev->v4l2_enc[0]->vfd->num, + solo_dev->v4l2_enc[solo_dev->nr_chans - 1]->vfd->num); + + return 0; +} + +void solo_enc_v4l2_exit(struct solo6010_dev *solo_dev) +{ + int i; + + solo6010_irq_off(solo_dev, SOLO_IRQ_MOTION); + + for (i = 0; i < solo_dev->nr_chans; i++) + solo_enc_free(solo_dev->v4l2_enc[i]); +} diff --git a/drivers/staging/solo6x10/v4l2.c b/drivers/staging/solo6x10/v4l2.c new file mode 100644 index 000000000000..e9d620ab0417 --- /dev/null +++ b/drivers/staging/solo6x10/v4l2.c @@ -0,0 +1,964 @@ +/* + * Copyright (C) 2010 Bluecherry, LLC www.bluecherrydvr.com + * Copyright (C) 2010 Ben Collins + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "solo6x10.h" +#include "tw28.h" + +#define SOLO_HW_BPL 2048 +#define SOLO_DISP_PIX_FIELD V4L2_FIELD_INTERLACED + +/* Image size is two fields, SOLO_HW_BPL is one horizontal line */ +#define solo_vlines(__solo) (__solo->video_vsize * 2) +#define solo_image_size(__solo) (solo_bytesperline(__solo) * \ + solo_vlines(__solo)) +#define solo_bytesperline(__solo) (__solo->video_hsize * 2) + +#define MIN_VID_BUFFERS 4 + +/* Simple file handle */ +struct solo_filehandle { + struct solo6010_dev *solo_dev; + struct videobuf_queue vidq; + struct task_struct *kthread; + spinlock_t slock; + int old_write; + struct list_head vidq_active; + struct p2m_desc desc[SOLO_NR_P2M_DESC]; + int desc_idx; +}; + +unsigned video_nr = -1; +module_param(video_nr, uint, 0644); +MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect (default)"); + +static void erase_on(struct solo6010_dev *solo_dev) +{ + solo_reg_write(solo_dev, SOLO_VO_DISP_ERASE, SOLO_VO_DISP_ERASE_ON); + solo_dev->erasing = 1; + solo_dev->frame_blank = 0; +} + +static int erase_off(struct solo6010_dev *solo_dev) +{ + if (!solo_dev->erasing) + return 0; + + /* First time around, assert erase off */ + if (!solo_dev->frame_blank) + solo_reg_write(solo_dev, SOLO_VO_DISP_ERASE, 0); + /* Keep the erasing flag on for 8 frames minimum */ + if (solo_dev->frame_blank++ >= 8) + solo_dev->erasing = 0; + + return 1; +} + +void solo_video_in_isr(struct solo6010_dev *solo_dev) +{ + solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_VIDEO_IN); + wake_up_interruptible(&solo_dev->disp_thread_wait); +} + +static void solo_win_setup(struct solo6010_dev *solo_dev, u8 ch, + int sx, int sy, int ex, int ey, int scale) +{ + if (ch >= solo_dev->nr_chans) + return; + + /* Here, we just keep window/channel the same */ + solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL0(ch), + SOLO_VI_WIN_CHANNEL(ch) | + SOLO_VI_WIN_SX(sx) | + SOLO_VI_WIN_EX(ex) | + SOLO_VI_WIN_SCALE(scale)); + + solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL1(ch), + SOLO_VI_WIN_SY(sy) | + SOLO_VI_WIN_EY(ey)); +} + +static int solo_v4l2_ch_ext_4up(struct solo6010_dev *solo_dev, u8 idx, int on) +{ + u8 ch = idx * 4; + + if (ch >= solo_dev->nr_chans) + return -EINVAL; + + if (!on) { + u8 i; + for (i = ch; i < ch + 4; i++) + solo_win_setup(solo_dev, i, solo_dev->video_hsize, + solo_vlines(solo_dev), + solo_dev->video_hsize, + solo_vlines(solo_dev), 0); + return 0; + } + + /* Row 1 */ + solo_win_setup(solo_dev, ch, 0, 0, solo_dev->video_hsize / 2, + solo_vlines(solo_dev) / 2, 3); + solo_win_setup(solo_dev, ch + 1, solo_dev->video_hsize / 2, 0, + solo_dev->video_hsize, solo_vlines(solo_dev) / 2, 3); + /* Row 2 */ + solo_win_setup(solo_dev, ch + 2, 0, solo_vlines(solo_dev) / 2, + solo_dev->video_hsize / 2, solo_vlines(solo_dev), 3); + solo_win_setup(solo_dev, ch + 3, solo_dev->video_hsize / 2, + solo_vlines(solo_dev) / 2, solo_dev->video_hsize, + solo_vlines(solo_dev), 3); + + return 0; +} + +static int solo_v4l2_ch_ext_16up(struct solo6010_dev *solo_dev, int on) +{ + int sy, ysize, hsize, i; + + if (!on) { + for (i = 0; i < 16; i++) + solo_win_setup(solo_dev, i, solo_dev->video_hsize, + solo_vlines(solo_dev), + solo_dev->video_hsize, + solo_vlines(solo_dev), 0); + return 0; + } + + ysize = solo_vlines(solo_dev) / 4; + hsize = solo_dev->video_hsize / 4; + + for (sy = 0, i = 0; i < 4; i++, sy += ysize) { + solo_win_setup(solo_dev, i * 4, 0, sy, hsize, + sy + ysize, 5); + solo_win_setup(solo_dev, (i * 4) + 1, hsize, sy, + hsize * 2, sy + ysize, 5); + solo_win_setup(solo_dev, (i * 4) + 2, hsize * 2, sy, + hsize * 3, sy + ysize, 5); + solo_win_setup(solo_dev, (i * 4) + 3, hsize * 3, sy, + solo_dev->video_hsize, sy + ysize, 5); + } + + return 0; +} + +static int solo_v4l2_ch(struct solo6010_dev *solo_dev, u8 ch, int on) +{ + u8 ext_ch; + + if (ch < solo_dev->nr_chans) { + solo_win_setup(solo_dev, ch, on ? 0 : solo_dev->video_hsize, + on ? 0 : solo_vlines(solo_dev), + solo_dev->video_hsize, solo_vlines(solo_dev), + on ? 1 : 0); + return 0; + } + + if (ch >= solo_dev->nr_chans + solo_dev->nr_ext) + return -EINVAL; + + ext_ch = ch - solo_dev->nr_chans; + + /* 4up's first */ + if (ext_ch < 4) + return solo_v4l2_ch_ext_4up(solo_dev, ext_ch, on); + + /* Remaining case is 16up for 16-port */ + return solo_v4l2_ch_ext_16up(solo_dev, on); +} + +static int solo_v4l2_set_ch(struct solo6010_dev *solo_dev, u8 ch) +{ + if (ch >= solo_dev->nr_chans + solo_dev->nr_ext) + return -EINVAL; + + erase_on(solo_dev); + + solo_v4l2_ch(solo_dev, solo_dev->cur_disp_ch, 0); + solo_v4l2_ch(solo_dev, ch, 1); + + solo_dev->cur_disp_ch = ch; + + return 0; +} + +static void disp_reset_desc(struct solo_filehandle *fh) +{ + /* We use desc mode, which ignores desc 0 */ + memset(fh->desc, 0, sizeof(*fh->desc)); + fh->desc_idx = 1; +} + +static int disp_flush_descs(struct solo_filehandle *fh) +{ + int ret; + + if (!fh->desc_idx) + return 0; + + ret = solo_p2m_dma_desc(fh->solo_dev, SOLO_P2M_DMA_ID_DISP, + fh->desc, fh->desc_idx); + disp_reset_desc(fh); + + return ret; +} + +static int disp_push_desc(struct solo_filehandle *fh, dma_addr_t dma_addr, + u32 ext_addr, int size, int repeat, int ext_size) +{ + if (fh->desc_idx >= SOLO_NR_P2M_DESC) { + int ret = disp_flush_descs(fh); + if (ret) + return ret; + } + + solo_p2m_push_desc(&fh->desc[fh->desc_idx], 0, dma_addr, ext_addr, + size, repeat, ext_size); + fh->desc_idx++; + + return 0; +} + +static void solo_fillbuf(struct solo_filehandle *fh, + struct videobuf_buffer *vb) +{ + struct solo6010_dev *solo_dev = fh->solo_dev; + struct videobuf_dmabuf *vbuf; + unsigned int fdma_addr; + int error = 1; + int i; + struct scatterlist *sg; + dma_addr_t sg_dma; + int sg_size_left; + + vbuf = videobuf_to_dma(vb); + if (!vbuf) + goto finish_buf; + + if (erase_off(solo_dev)) { + int i; + + /* Just blit to the entire sg list, ignoring size */ + for_each_sg(vbuf->sglist, sg, vbuf->sglen, i) { + void *p = sg_virt(sg); + size_t len = sg_dma_len(sg); + + for (i = 0; i < len; i += 2) { + ((u8 *)p)[i] = 0x80; + ((u8 *)p)[i + 1] = 0x00; + } + } + + error = 0; + goto finish_buf; + } + + disp_reset_desc(fh); + sg = vbuf->sglist; + sg_dma = sg_dma_address(sg); + sg_size_left = sg_dma_len(sg); + + fdma_addr = SOLO_DISP_EXT_ADDR + (fh->old_write * + (SOLO_HW_BPL * solo_vlines(solo_dev))); + + for (i = 0; i < solo_vlines(solo_dev); i++) { + int line_len = solo_bytesperline(solo_dev); + int lines; + + if (!sg_size_left) { + sg = sg_next(sg); + if (sg == NULL) + goto finish_buf; + sg_dma = sg_dma_address(sg); + sg_size_left = sg_dma_len(sg); + } + + /* No room for an entire line, so chunk it up */ + if (sg_size_left < line_len) { + int this_addr = fdma_addr; + + while (line_len > 0) { + int this_write; + + if (!sg_size_left) { + sg = sg_next(sg); + if (sg == NULL) + goto finish_buf; + sg_dma = sg_dma_address(sg); + sg_size_left = sg_dma_len(sg); + } + + this_write = min(sg_size_left, line_len); + + if (disp_push_desc(fh, sg_dma, this_addr, + this_write, 0, 0)) + goto finish_buf; + + line_len -= this_write; + sg_size_left -= this_write; + sg_dma += this_write; + this_addr += this_write; + } + + fdma_addr += SOLO_HW_BPL; + continue; + } + + /* Shove as many lines into a repeating descriptor as possible */ + lines = min(sg_size_left / line_len, + solo_vlines(solo_dev) - i); + + if (disp_push_desc(fh, sg_dma, fdma_addr, line_len, + lines - 1, SOLO_HW_BPL)) + goto finish_buf; + + i += lines - 1; + fdma_addr += SOLO_HW_BPL * lines; + sg_dma += lines * line_len; + sg_size_left -= lines * line_len; + } + + error = disp_flush_descs(fh); + +finish_buf: + if (error) { + vb->state = VIDEOBUF_ERROR; + } else { + vb->size = solo_vlines(solo_dev) * solo_bytesperline(solo_dev); + vb->state = VIDEOBUF_DONE; + vb->field_count++; + do_gettimeofday(&vb->ts); + } + + wake_up(&vb->done); + + return; +} + +static void solo_thread_try(struct solo_filehandle *fh) +{ + struct videobuf_buffer *vb; + unsigned int cur_write; + + for (;;) { + spin_lock(&fh->slock); + + if (list_empty(&fh->vidq_active)) + break; + + vb = list_first_entry(&fh->vidq_active, struct videobuf_buffer, + queue); + + if (!waitqueue_active(&vb->done)) + break; + + cur_write = SOLO_VI_STATUS0_PAGE(solo_reg_read(fh->solo_dev, + SOLO_VI_STATUS0)); + if (cur_write == fh->old_write) + break; + + fh->old_write = cur_write; + list_del(&vb->queue); + + spin_unlock(&fh->slock); + + solo_fillbuf(fh, vb); + } + + assert_spin_locked(&fh->slock); + spin_unlock(&fh->slock); +} + +static int solo_thread(void *data) +{ + struct solo_filehandle *fh = data; + struct solo6010_dev *solo_dev = fh->solo_dev; + DECLARE_WAITQUEUE(wait, current); + + set_freezable(); + add_wait_queue(&solo_dev->disp_thread_wait, &wait); + + for (;;) { + long timeout = schedule_timeout_interruptible(HZ); + if (timeout == -ERESTARTSYS || kthread_should_stop()) + break; + solo_thread_try(fh); + try_to_freeze(); + } + + remove_wait_queue(&solo_dev->disp_thread_wait, &wait); + + return 0; +} + +static int solo_start_thread(struct solo_filehandle *fh) +{ + fh->kthread = kthread_run(solo_thread, fh, SOLO6010_NAME "_disp"); + + if (IS_ERR(fh->kthread)) + return PTR_ERR(fh->kthread); + + return 0; +} + +static void solo_stop_thread(struct solo_filehandle *fh) +{ + if (fh->kthread) { + kthread_stop(fh->kthread); + fh->kthread = NULL; + } +} + +static int solo_buf_setup(struct videobuf_queue *vq, unsigned int *count, + unsigned int *size) +{ + struct solo_filehandle *fh = vq->priv_data; + struct solo6010_dev *solo_dev = fh->solo_dev; + + *size = solo_image_size(solo_dev); + + if (*count < MIN_VID_BUFFERS) + *count = MIN_VID_BUFFERS; + + return 0; +} + +static int solo_buf_prepare(struct videobuf_queue *vq, + struct videobuf_buffer *vb, enum v4l2_field field) +{ + struct solo_filehandle *fh = vq->priv_data; + struct solo6010_dev *solo_dev = fh->solo_dev; + + vb->size = solo_image_size(solo_dev); + if (vb->baddr != 0 && vb->bsize < vb->size) + return -EINVAL; + + /* XXX: These properties only change when queue is idle */ + vb->width = solo_dev->video_hsize; + vb->height = solo_vlines(solo_dev); + vb->bytesperline = solo_bytesperline(solo_dev); + vb->field = field; + + if (vb->state == VIDEOBUF_NEEDS_INIT) { + int rc = videobuf_iolock(vq, vb, NULL); + if (rc < 0) { + struct videobuf_dmabuf *dma = videobuf_to_dma(vb); + videobuf_dma_unmap(vq->dev, dma); + videobuf_dma_free(dma); + vb->state = VIDEOBUF_NEEDS_INIT; + return rc; + } + } + vb->state = VIDEOBUF_PREPARED; + + return 0; +} + +static void solo_buf_queue(struct videobuf_queue *vq, + struct videobuf_buffer *vb) +{ + struct solo_filehandle *fh = vq->priv_data; + struct solo6010_dev *solo_dev = fh->solo_dev; + + vb->state = VIDEOBUF_QUEUED; + list_add_tail(&vb->queue, &fh->vidq_active); + wake_up_interruptible(&solo_dev->disp_thread_wait); +} + +static void solo_buf_release(struct videobuf_queue *vq, + struct videobuf_buffer *vb) +{ + struct videobuf_dmabuf *dma = videobuf_to_dma(vb); + + videobuf_dma_unmap(vq->dev, dma); + videobuf_dma_free(dma); + vb->state = VIDEOBUF_NEEDS_INIT; +} + +static struct videobuf_queue_ops solo_video_qops = { + .buf_setup = solo_buf_setup, + .buf_prepare = solo_buf_prepare, + .buf_queue = solo_buf_queue, + .buf_release = solo_buf_release, +}; + +static unsigned int solo_v4l2_poll(struct file *file, + struct poll_table_struct *wait) +{ + struct solo_filehandle *fh = file->private_data; + + return videobuf_poll_stream(file, &fh->vidq, wait); +} + +static int solo_v4l2_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct solo_filehandle *fh = file->private_data; + + return videobuf_mmap_mapper(&fh->vidq, vma); +} + +static int solo_v4l2_open(struct file *file) +{ + struct solo6010_dev *solo_dev = video_drvdata(file); + struct solo_filehandle *fh; + int ret; + + fh = kzalloc(sizeof(*fh), GFP_KERNEL); + if (fh == NULL) + return -ENOMEM; + + spin_lock_init(&fh->slock); + INIT_LIST_HEAD(&fh->vidq_active); + fh->solo_dev = solo_dev; + file->private_data = fh; + + ret = solo_start_thread(fh); + if (ret) { + kfree(fh); + return ret; + } + + videobuf_queue_sg_init(&fh->vidq, &solo_video_qops, + &solo_dev->pdev->dev, &fh->slock, + V4L2_BUF_TYPE_VIDEO_CAPTURE, + SOLO_DISP_PIX_FIELD, + sizeof(struct videobuf_buffer), fh, NULL); + + return 0; +} + +static ssize_t solo_v4l2_read(struct file *file, char __user *data, + size_t count, loff_t *ppos) +{ + struct solo_filehandle *fh = file->private_data; + + return videobuf_read_stream(&fh->vidq, data, count, ppos, 0, + file->f_flags & O_NONBLOCK); +} + +static int solo_v4l2_release(struct file *file) +{ + struct solo_filehandle *fh = file->private_data; + + videobuf_stop(&fh->vidq); + videobuf_mmap_free(&fh->vidq); + solo_stop_thread(fh); + kfree(fh); + + return 0; +} + +static int solo_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + struct solo_filehandle *fh = priv; + struct solo6010_dev *solo_dev = fh->solo_dev; + + strcpy(cap->driver, SOLO6010_NAME); + strcpy(cap->card, "Softlogic 6010"); + snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI %s", + pci_name(solo_dev->pdev)); + cap->version = SOLO6010_VER_NUM; + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_READWRITE | + V4L2_CAP_STREAMING; + return 0; +} + +static int solo_enum_ext_input(struct solo6010_dev *solo_dev, + struct v4l2_input *input) +{ + static const char *dispnames_1[] = { "4UP" }; + static const char *dispnames_2[] = { "4UP-1", "4UP-2" }; + static const char *dispnames_5[] = { + "4UP-1", "4UP-2", "4UP-3", "4UP-4", "16UP" + }; + const char **dispnames; + + if (input->index >= (solo_dev->nr_chans + solo_dev->nr_ext)) + return -EINVAL; + + if (solo_dev->nr_ext == 5) + dispnames = dispnames_5; + else if (solo_dev->nr_ext == 2) + dispnames = dispnames_2; + else + dispnames = dispnames_1; + + snprintf(input->name, sizeof(input->name), "Multi %s", + dispnames[input->index - solo_dev->nr_chans]); + + return 0; +} + +static int solo_enum_input(struct file *file, void *priv, + struct v4l2_input *input) +{ + struct solo_filehandle *fh = priv; + struct solo6010_dev *solo_dev = fh->solo_dev; + + if (input->index >= solo_dev->nr_chans) { + int ret = solo_enum_ext_input(solo_dev, input); + if (ret < 0) + return ret; + } else { + snprintf(input->name, sizeof(input->name), "Camera %d", + input->index + 1); + + /* We can only check this for normal inputs */ + if (!tw28_get_video_status(solo_dev, input->index)) + input->status = V4L2_IN_ST_NO_SIGNAL; + } + + input->type = V4L2_INPUT_TYPE_CAMERA; + + if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) + input->std = V4L2_STD_NTSC_M; + else + input->std = V4L2_STD_PAL_B; + + return 0; +} + +static int solo_set_input(struct file *file, void *priv, unsigned int index) +{ + struct solo_filehandle *fh = priv; + + return solo_v4l2_set_ch(fh->solo_dev, index); +} + +static int solo_get_input(struct file *file, void *priv, unsigned int *index) +{ + struct solo_filehandle *fh = priv; + + *index = fh->solo_dev->cur_disp_ch; + + return 0; +} + +static int solo_enum_fmt_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + if (f->index) + return -EINVAL; + + f->pixelformat = V4L2_PIX_FMT_UYVY; + strlcpy(f->description, "UYUV 4:2:2 Packed", sizeof(f->description)); + + return 0; +} + +static int solo_try_fmt_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct solo_filehandle *fh = priv; + struct solo6010_dev *solo_dev = fh->solo_dev; + struct v4l2_pix_format *pix = &f->fmt.pix; + int image_size = solo_image_size(solo_dev); + + /* Check supported sizes */ + if (pix->width != solo_dev->video_hsize) + pix->width = solo_dev->video_hsize; + if (pix->height != solo_vlines(solo_dev)) + pix->height = solo_vlines(solo_dev); + if (pix->sizeimage != image_size) + pix->sizeimage = image_size; + + /* Check formats */ + if (pix->field == V4L2_FIELD_ANY) + pix->field = SOLO_DISP_PIX_FIELD; + + if (pix->pixelformat != V4L2_PIX_FMT_UYVY || + pix->field != SOLO_DISP_PIX_FIELD || + pix->colorspace != V4L2_COLORSPACE_SMPTE170M) + return -EINVAL; + + return 0; +} + +static int solo_set_fmt_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct solo_filehandle *fh = priv; + + if (videobuf_queue_is_busy(&fh->vidq)) + return -EBUSY; + + /* For right now, if it doesn't match our running config, + * then fail */ + return solo_try_fmt_cap(file, priv, f); +} + +static int solo_get_fmt_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct solo_filehandle *fh = priv; + struct solo6010_dev *solo_dev = fh->solo_dev; + struct v4l2_pix_format *pix = &f->fmt.pix; + + pix->width = solo_dev->video_hsize; + pix->height = solo_vlines(solo_dev); + pix->pixelformat = V4L2_PIX_FMT_UYVY; + pix->field = SOLO_DISP_PIX_FIELD; + pix->sizeimage = solo_image_size(solo_dev); + pix->colorspace = V4L2_COLORSPACE_SMPTE170M; + pix->bytesperline = solo_bytesperline(solo_dev); + + return 0; +} + +static int solo_reqbufs(struct file *file, void *priv, + struct v4l2_requestbuffers *req) +{ + struct solo_filehandle *fh = priv; + + return videobuf_reqbufs(&fh->vidq, req); +} + +static int solo_querybuf(struct file *file, void *priv, struct v4l2_buffer *buf) +{ + struct solo_filehandle *fh = priv; + + return videobuf_querybuf(&fh->vidq, buf); +} + +static int solo_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) +{ + struct solo_filehandle *fh = priv; + + return videobuf_qbuf(&fh->vidq, buf); +} + +static int solo_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) +{ + struct solo_filehandle *fh = priv; + + return videobuf_dqbuf(&fh->vidq, buf, file->f_flags & O_NONBLOCK); +} + +static int solo_streamon(struct file *file, void *priv, enum v4l2_buf_type i) +{ + struct solo_filehandle *fh = priv; + + if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + return videobuf_streamon(&fh->vidq); +} + +static int solo_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) +{ + struct solo_filehandle *fh = priv; + + if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + return videobuf_streamoff(&fh->vidq); +} + +static int solo_s_std(struct file *file, void *priv, v4l2_std_id *i) +{ + return 0; +} + +static const u32 solo_motion_ctrls[] = { + V4L2_CID_MOTION_TRACE, + 0 +}; + +static const u32 *solo_ctrl_classes[] = { + solo_motion_ctrls, + NULL +}; + +static int solo_disp_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *qc) +{ + qc->id = v4l2_ctrl_next(solo_ctrl_classes, qc->id); + if (!qc->id) + return -EINVAL; + + switch (qc->id) { +#ifdef PRIVATE_CIDS + case V4L2_CID_MOTION_TRACE: + qc->type = V4L2_CTRL_TYPE_BOOLEAN; + qc->minimum = 0; + qc->maximum = qc->step = 1; + qc->default_value = 0; + strlcpy(qc->name, "Motion Detection Trace", sizeof(qc->name)); + return 0; +#else + case V4L2_CID_MOTION_TRACE: + return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); +#endif + } + return -EINVAL; +} + +static int solo_disp_g_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct solo_filehandle *fh = priv; + struct solo6010_dev *solo_dev = fh->solo_dev; + + switch (ctrl->id) { + case V4L2_CID_MOTION_TRACE: + ctrl->value = solo_reg_read(solo_dev, SOLO_VI_MOTION_BAR) + ? 1 : 0; + return 0; + } + return -EINVAL; +} + +static int solo_disp_s_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct solo_filehandle *fh = priv; + struct solo6010_dev *solo_dev = fh->solo_dev; + + switch (ctrl->id) { + case V4L2_CID_MOTION_TRACE: + if (ctrl->value) { + solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER, + SOLO_VI_MOTION_Y_ADD | + SOLO_VI_MOTION_Y_VALUE(0x20) | + SOLO_VI_MOTION_CB_VALUE(0x10) | + SOLO_VI_MOTION_CR_VALUE(0x10)); + solo_reg_write(solo_dev, SOLO_VI_MOTION_BAR, + SOLO_VI_MOTION_CR_ADD | + SOLO_VI_MOTION_Y_VALUE(0x10) | + SOLO_VI_MOTION_CB_VALUE(0x80) | + SOLO_VI_MOTION_CR_VALUE(0x10)); + } else { + solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER, 0); + solo_reg_write(solo_dev, SOLO_VI_MOTION_BAR, 0); + } + return 0; + } + return -EINVAL; +} + +static const struct v4l2_file_operations solo_v4l2_fops = { + .owner = THIS_MODULE, + .open = solo_v4l2_open, + .release = solo_v4l2_release, + .read = solo_v4l2_read, + .poll = solo_v4l2_poll, + .mmap = solo_v4l2_mmap, + .ioctl = video_ioctl2, +}; + +static const struct v4l2_ioctl_ops solo_v4l2_ioctl_ops = { + .vidioc_querycap = solo_querycap, + .vidioc_s_std = solo_s_std, + /* Input callbacks */ + .vidioc_enum_input = solo_enum_input, + .vidioc_s_input = solo_set_input, + .vidioc_g_input = solo_get_input, + /* Video capture format callbacks */ + .vidioc_enum_fmt_vid_cap = solo_enum_fmt_cap, + .vidioc_try_fmt_vid_cap = solo_try_fmt_cap, + .vidioc_s_fmt_vid_cap = solo_set_fmt_cap, + .vidioc_g_fmt_vid_cap = solo_get_fmt_cap, + /* Streaming I/O */ + .vidioc_reqbufs = solo_reqbufs, + .vidioc_querybuf = solo_querybuf, + .vidioc_qbuf = solo_qbuf, + .vidioc_dqbuf = solo_dqbuf, + .vidioc_streamon = solo_streamon, + .vidioc_streamoff = solo_streamoff, + /* Controls */ + .vidioc_queryctrl = solo_disp_queryctrl, + .vidioc_g_ctrl = solo_disp_g_ctrl, + .vidioc_s_ctrl = solo_disp_s_ctrl, +}; + +static struct video_device solo_v4l2_template = { + .name = SOLO6010_NAME, + .fops = &solo_v4l2_fops, + .ioctl_ops = &solo_v4l2_ioctl_ops, + .minor = -1, + .release = video_device_release, + + .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL_B, + .current_norm = V4L2_STD_NTSC_M, +}; + +int solo_v4l2_init(struct solo6010_dev *solo_dev) +{ + int ret; + int i; + + init_waitqueue_head(&solo_dev->disp_thread_wait); + + solo_dev->vfd = video_device_alloc(); + if (!solo_dev->vfd) + return -ENOMEM; + + *solo_dev->vfd = solo_v4l2_template; + solo_dev->vfd->parent = &solo_dev->pdev->dev; + + ret = video_register_device(solo_dev->vfd, VFL_TYPE_GRABBER, video_nr); + if (ret < 0) { + video_device_release(solo_dev->vfd); + solo_dev->vfd = NULL; + return ret; + } + + video_set_drvdata(solo_dev->vfd, solo_dev); + + snprintf(solo_dev->vfd->name, sizeof(solo_dev->vfd->name), "%s (%i)", + SOLO6010_NAME, solo_dev->vfd->num); + + if (video_nr != -1) + video_nr++; + + dev_info(&solo_dev->pdev->dev, "Display as /dev/video%d with " + "%d inputs (%d extended)\n", solo_dev->vfd->num, + solo_dev->nr_chans, solo_dev->nr_ext); + + /* Cycle all the channels and clear */ + for (i = 0; i < solo_dev->nr_chans; i++) { + solo_v4l2_set_ch(solo_dev, i); + while (erase_off(solo_dev)) + ;/* Do nothing */ + } + + /* Set the default display channel */ + solo_v4l2_set_ch(solo_dev, 0); + while (erase_off(solo_dev)) + ;/* Do nothing */ + + solo6010_irq_on(solo_dev, SOLO_IRQ_VIDEO_IN); + + return 0; +} + +void solo_v4l2_exit(struct solo6010_dev *solo_dev) +{ + solo6010_irq_off(solo_dev, SOLO_IRQ_VIDEO_IN); + if (solo_dev->vfd) { + video_unregister_device(solo_dev->vfd); + solo_dev->vfd = NULL; + } +} -- cgit v1.2.3 From decebabf24ca179749dcac8a3fb87f7186bdf898 Mon Sep 17 00:00:00 2001 From: Krzysztof Hałasa Date: Fri, 11 Feb 2011 13:38:20 +0100 Subject: staging: Solo6x10: Changed solo6010* -> solo*, solo6x10* etc. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Krzysztof Hałasa Signed-off-by: Greg Kroah-Hartman --- drivers/staging/solo6x10/core.c | 60 +++++++++++----------- drivers/staging/solo6x10/disp.c | 16 +++--- drivers/staging/solo6x10/enc.c | 16 +++--- drivers/staging/solo6x10/g723.c | 42 ++++++++-------- drivers/staging/solo6x10/gpio.c | 12 ++--- drivers/staging/solo6x10/i2c.c | 31 ++++++------ drivers/staging/solo6x10/jpeg.h | 6 +-- drivers/staging/solo6x10/offsets.h | 6 +-- drivers/staging/solo6x10/osd-font.h | 6 +-- drivers/staging/solo6x10/p2m.c | 32 ++++++------ drivers/staging/solo6x10/registers.h | 8 +-- drivers/staging/solo6x10/solo6x10.h | 97 ++++++++++++++++++------------------ drivers/staging/solo6x10/tw28.c | 33 ++++++------ drivers/staging/solo6x10/tw28.h | 24 ++++----- drivers/staging/solo6x10/v4l2-enc.c | 84 +++++++++++++++---------------- drivers/staging/solo6x10/v4l2.c | 64 ++++++++++++------------ 16 files changed, 266 insertions(+), 271 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/solo6x10/core.c b/drivers/staging/solo6x10/core.c index 37e6fda626f3..76779949f141 100644 --- a/drivers/staging/solo6x10/core.c +++ b/drivers/staging/solo6x10/core.c @@ -25,27 +25,27 @@ #include "solo6x10.h" #include "tw28.h" -MODULE_DESCRIPTION("Softlogic 6010 MP4 Encoder/Decoder V4L2/ALSA Driver"); +MODULE_DESCRIPTION("Softlogic 6x10 MP4/H.264 Encoder/Decoder V4L2/ALSA Driver"); MODULE_AUTHOR("Ben Collins "); -MODULE_VERSION(SOLO6010_VERSION); +MODULE_VERSION(SOLO6X10_VERSION); MODULE_LICENSE("GPL"); -void solo6010_irq_on(struct solo6010_dev *solo_dev, u32 mask) +void solo_irq_on(struct solo_dev *solo_dev, u32 mask) { solo_dev->irq_mask |= mask; solo_reg_write(solo_dev, SOLO_IRQ_ENABLE, solo_dev->irq_mask); } -void solo6010_irq_off(struct solo6010_dev *solo_dev, u32 mask) +void solo_irq_off(struct solo_dev *solo_dev, u32 mask) { solo_dev->irq_mask &= ~mask; solo_reg_write(solo_dev, SOLO_IRQ_ENABLE, solo_dev->irq_mask); } /* XXX We should check the return value of the sub-device ISR's */ -static irqreturn_t solo6010_isr(int irq, void *data) +static irqreturn_t solo_isr(int irq, void *data) { - struct solo6010_dev *solo_dev = data; + struct solo_dev *solo_dev = data; u32 status; int i; @@ -88,7 +88,7 @@ static irqreturn_t solo6010_isr(int irq, void *data) return IRQ_HANDLED; } -static void free_solo_dev(struct solo6010_dev *solo_dev) +static void free_solo_dev(struct solo_dev *solo_dev) { struct pci_dev *pdev; @@ -116,7 +116,7 @@ static void free_solo_dev(struct solo6010_dev *solo_dev) /* Now cleanup the PCI device */ if (solo_dev->reg_base) { - solo6010_irq_off(solo_dev, ~0); + solo_irq_off(solo_dev, ~0); pci_iounmap(pdev, solo_dev->reg_base); free_irq(pdev->irq, solo_dev); } @@ -128,10 +128,10 @@ static void free_solo_dev(struct solo6010_dev *solo_dev) kfree(solo_dev); } -static int __devinit solo6010_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) +static int __devinit solo_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) { - struct solo6010_dev *solo_dev; + struct solo_dev *solo_dev; int ret; int sdram; u8 chip_id; @@ -151,7 +151,7 @@ static int __devinit solo6010_pci_probe(struct pci_dev *pdev, pci_set_master(pdev); - ret = pci_request_regions(pdev, SOLO6010_NAME); + ret = pci_request_regions(pdev, SOLO6X10_NAME); if (ret) goto fail_probe; @@ -184,7 +184,7 @@ static int __devinit solo6010_pci_probe(struct pci_dev *pdev, solo_dev->flags = id->driver_data; /* Disable all interrupts to start */ - solo6010_irq_off(solo_dev, ~0); + solo_irq_off(solo_dev, ~0); reg = SOLO_SYS_CFG_SDRAM64BIT; /* Initial global settings */ @@ -223,13 +223,13 @@ static int __devinit solo6010_pci_probe(struct pci_dev *pdev, /* PLL locking time of 1ms */ mdelay(1); - ret = request_irq(pdev->irq, solo6010_isr, IRQF_SHARED, SOLO6010_NAME, + ret = request_irq(pdev->irq, solo_isr, IRQF_SHARED, SOLO6X10_NAME, solo_dev); if (ret) goto fail_probe; /* Handle this from the start */ - solo6010_irq_on(solo_dev, SOLO_IRQ_PCI_ERR); + solo_irq_on(solo_dev, SOLO_IRQ_PCI_ERR); ret = solo_i2c_init(solo_dev); if (ret) @@ -283,14 +283,14 @@ fail_probe: return ret; } -static void __devexit solo6010_pci_remove(struct pci_dev *pdev) +static void __devexit solo_pci_remove(struct pci_dev *pdev) { - struct solo6010_dev *solo_dev = pci_get_drvdata(pdev); + struct solo_dev *solo_dev = pci_get_drvdata(pdev); free_solo_dev(solo_dev); } -static struct pci_device_id solo6010_id_table[] = { +static struct pci_device_id solo_id_table[] = { /* 6010 based cards */ {PCI_DEVICE(PCI_VENDOR_ID_SOFTLOGIC, PCI_DEVICE_ID_SOLO6010)}, {PCI_DEVICE(PCI_VENDOR_ID_SOFTLOGIC, PCI_DEVICE_ID_SOLO6110), @@ -308,24 +308,24 @@ static struct pci_device_id solo6010_id_table[] = { {0,} }; -MODULE_DEVICE_TABLE(pci, solo6010_id_table); +MODULE_DEVICE_TABLE(pci, solo_id_table); -static struct pci_driver solo6010_pci_driver = { - .name = SOLO6010_NAME, - .id_table = solo6010_id_table, - .probe = solo6010_pci_probe, - .remove = solo6010_pci_remove, +static struct pci_driver solo_pci_driver = { + .name = SOLO6X10_NAME, + .id_table = solo_id_table, + .probe = solo_pci_probe, + .remove = solo_pci_remove, }; -static int __init solo6010_module_init(void) +static int __init solo_module_init(void) { - return pci_register_driver(&solo6010_pci_driver); + return pci_register_driver(&solo_pci_driver); } -static void __exit solo6010_module_exit(void) +static void __exit solo_module_exit(void) { - pci_unregister_driver(&solo6010_pci_driver); + pci_unregister_driver(&solo_pci_driver); } -module_init(solo6010_module_init); -module_exit(solo6010_module_exit); +module_init(solo_module_init); +module_exit(solo_module_exit); diff --git a/drivers/staging/solo6x10/disp.c b/drivers/staging/solo6x10/disp.c index 1b0cfa8803eb..884c0eb757c4 100644 --- a/drivers/staging/solo6x10/disp.c +++ b/drivers/staging/solo6x10/disp.c @@ -37,7 +37,7 @@ static unsigned video_type; module_param(video_type, uint, 0644); MODULE_PARM_DESC(video_type, "video_type (0 = NTSC/Default, 1 = PAL)"); -static void solo_vin_config(struct solo6010_dev *solo_dev) +static void solo_vin_config(struct solo_dev *solo_dev) { solo_dev->vin_hstart = 8; solo_dev->vin_vstart = 2; @@ -97,7 +97,7 @@ static void solo_vin_config(struct solo6010_dev *solo_dev) SOLO_VI_PB_HSTOP(16 + 720)); } -static void solo_disp_config(struct solo6010_dev *solo_dev) +static void solo_disp_config(struct solo_dev *solo_dev) { solo_dev->vout_hstart = 6; solo_dev->vout_vstart = 8; @@ -145,7 +145,7 @@ static void solo_disp_config(struct solo6010_dev *solo_dev) solo_reg_write(solo_dev, SOLO_WATCHDOG, 0); } -static int solo_dma_vin_region(struct solo6010_dev *solo_dev, u32 off, +static int solo_dma_vin_region(struct solo_dev *solo_dev, u32 off, u16 val, int reg_size) { u16 buf[64]; @@ -163,7 +163,7 @@ static int solo_dma_vin_region(struct solo6010_dev *solo_dev, u32 off, return ret; } -void solo_set_motion_threshold(struct solo6010_dev *solo_dev, u8 ch, u16 val) +void solo_set_motion_threshold(struct solo_dev *solo_dev, u8 ch, u16 val) { if (ch > solo_dev->nr_chans) return; @@ -177,7 +177,7 @@ void solo_set_motion_threshold(struct solo6010_dev *solo_dev, u8 ch, u16 val) * threshold and working table for each channel. Atleast that's what the * spec says. However, this code (take from rdk) has some mystery 8k * block right after the flag area, before the first thresh table. */ -static void solo_motion_config(struct solo6010_dev *solo_dev) +static void solo_motion_config(struct solo_dev *solo_dev) { int i; @@ -209,7 +209,7 @@ static void solo_motion_config(struct solo6010_dev *solo_dev) solo_reg_write(solo_dev, SOLO_VI_MOTION_BAR, 0); } -int solo_disp_init(struct solo6010_dev *solo_dev) +int solo_disp_init(struct solo_dev *solo_dev) { int i; @@ -234,11 +234,11 @@ int solo_disp_init(struct solo6010_dev *solo_dev) return 0; } -void solo_disp_exit(struct solo6010_dev *solo_dev) +void solo_disp_exit(struct solo_dev *solo_dev) { int i; - solo6010_irq_off(solo_dev, SOLO_IRQ_MOTION); + solo_irq_off(solo_dev, SOLO_IRQ_MOTION); solo_reg_write(solo_dev, SOLO_VO_DISP_CTRL, 0); solo_reg_write(solo_dev, SOLO_VO_ZOOM_CTRL, 0); diff --git a/drivers/staging/solo6x10/enc.c b/drivers/staging/solo6x10/enc.c index 755626c1a2ec..285f7f350062 100644 --- a/drivers/staging/solo6x10/enc.c +++ b/drivers/staging/solo6x10/enc.c @@ -27,7 +27,7 @@ #define VI_PROG_HSIZE (1280 - 16) #define VI_PROG_VSIZE (1024 - 16) -static void solo_capture_config(struct solo6010_dev *solo_dev) +static void solo_capture_config(struct solo_dev *solo_dev) { int i, j; unsigned long height; @@ -115,7 +115,7 @@ static void solo_capture_config(struct solo6010_dev *solo_dev) int solo_osd_print(struct solo_enc_dev *solo_enc) { - struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct solo_dev *solo_dev = solo_enc->solo_dev; char *str = solo_enc->osd_text; u8 *buf; u32 reg = solo_reg_read(solo_dev, SOLO_VE_OSD_CH); @@ -151,7 +151,7 @@ int solo_osd_print(struct solo_enc_dev *solo_enc) return 0; } -static void solo_jpeg_config(struct solo6010_dev *solo_dev) +static void solo_jpeg_config(struct solo_dev *solo_dev) { u32 reg; if (solo_dev->flags & FLAGS_6110) @@ -169,7 +169,7 @@ static void solo_jpeg_config(struct solo6010_dev *solo_dev) solo_reg_write(solo_dev, 0x0688, (0 << 16) | (30 << 8) | 60); } -static void solo_mp4e_config(struct solo6010_dev *solo_dev) +static void solo_mp4e_config(struct solo_dev *solo_dev) { int i; u32 reg; @@ -206,7 +206,7 @@ static void solo_mp4e_config(struct solo6010_dev *solo_dev) solo_reg_write(solo_dev, 0x0634, 0x00040008); /* ? */ } -int solo_enc_init(struct solo6010_dev *solo_dev) +int solo_enc_init(struct solo_dev *solo_dev) { int i; @@ -219,16 +219,16 @@ int solo_enc_init(struct solo6010_dev *solo_dev) solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(i), 0); } - solo6010_irq_on(solo_dev, SOLO_IRQ_ENCODER); + solo_irq_on(solo_dev, SOLO_IRQ_ENCODER); return 0; } -void solo_enc_exit(struct solo6010_dev *solo_dev) +void solo_enc_exit(struct solo_dev *solo_dev) { int i; - solo6010_irq_off(solo_dev, SOLO_IRQ_ENCODER); + solo_irq_off(solo_dev, SOLO_IRQ_ENCODER); for (i = 0; i < solo_dev->nr_chans; i++) { solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(i), 0); diff --git a/drivers/staging/solo6x10/g723.c b/drivers/staging/solo6x10/g723.c index 4aba8f3dbe60..bd8eb92c94b1 100644 --- a/drivers/staging/solo6x10/g723.c +++ b/drivers/staging/solo6x10/g723.c @@ -50,13 +50,13 @@ #define PERIODS_MAX G723_FDMA_PAGES struct solo_snd_pcm { - int on; - spinlock_t lock; - struct solo6010_dev *solo_dev; - unsigned char g723_buf[G723_PERIOD_BYTES]; + int on; + spinlock_t lock; + struct solo_dev *solo_dev; + unsigned char g723_buf[G723_PERIOD_BYTES]; }; -static void solo_g723_config(struct solo6010_dev *solo_dev) +static void solo_g723_config(struct solo_dev *solo_dev) { int clk_div; @@ -76,7 +76,7 @@ static void solo_g723_config(struct solo6010_dev *solo_dev) SOLO_AUDIO_I2S_MULTI(3) | SOLO_AUDIO_MODE(OUTMODE_MASK)); } -void solo_g723_isr(struct solo6010_dev *solo_dev) +void solo_g723_isr(struct solo_dev *solo_dev) { struct snd_pcm_str *pstr = &solo_dev->snd_pcm->streams[SNDRV_PCM_STREAM_CAPTURE]; @@ -133,7 +133,7 @@ static struct snd_pcm_hardware snd_solo_pcm_hw = { static int snd_solo_pcm_open(struct snd_pcm_substream *ss) { - struct solo6010_dev *solo_dev = snd_pcm_substream_chip(ss); + struct solo_dev *solo_dev = snd_pcm_substream_chip(ss); struct solo_snd_pcm *solo_pcm; solo_pcm = kzalloc(sizeof(*solo_pcm), GFP_KERNEL); @@ -162,7 +162,7 @@ static int snd_solo_pcm_close(struct snd_pcm_substream *ss) static int snd_solo_pcm_trigger(struct snd_pcm_substream *ss, int cmd) { struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); - struct solo6010_dev *solo_dev = solo_pcm->solo_dev; + struct solo_dev *solo_dev = solo_pcm->solo_dev; int ret = 0; spin_lock(&solo_pcm->lock); @@ -172,7 +172,7 @@ static int snd_solo_pcm_trigger(struct snd_pcm_substream *ss, int cmd) if (solo_pcm->on == 0) { /* If this is the first user, switch on interrupts */ if (atomic_inc_return(&solo_dev->snd_users) == 1) - solo6010_irq_on(solo_dev, SOLO_IRQ_G723); + solo_irq_on(solo_dev, SOLO_IRQ_G723); solo_pcm->on = 1; } break; @@ -180,7 +180,7 @@ static int snd_solo_pcm_trigger(struct snd_pcm_substream *ss, int cmd) if (solo_pcm->on) { /* If this was our last user, switch them off */ if (atomic_dec_return(&solo_dev->snd_users) == 0) - solo6010_irq_off(solo_dev, SOLO_IRQ_G723); + solo_irq_off(solo_dev, SOLO_IRQ_G723); solo_pcm->on = 0; } break; @@ -201,7 +201,7 @@ static int snd_solo_pcm_prepare(struct snd_pcm_substream *ss) static snd_pcm_uframes_t snd_solo_pcm_pointer(struct snd_pcm_substream *ss) { struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); - struct solo6010_dev *solo_dev = solo_pcm->solo_dev; + struct solo_dev *solo_dev = solo_pcm->solo_dev; snd_pcm_uframes_t idx = solo_reg_read(solo_dev, SOLO_AUDIO_STA) & 0x1f; return idx * G723_FRAMES_PER_PAGE; @@ -212,7 +212,7 @@ static int snd_solo_pcm_copy(struct snd_pcm_substream *ss, int channel, snd_pcm_uframes_t count) { struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); - struct solo6010_dev *solo_dev = solo_pcm->solo_dev; + struct solo_dev *solo_dev = solo_pcm->solo_dev; int err, i; for (i = 0; i < (count / G723_FRAMES_PER_PAGE); i++) { @@ -264,7 +264,7 @@ static int snd_solo_capture_volume_info(struct snd_kcontrol *kcontrol, static int snd_solo_capture_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value) { - struct solo6010_dev *solo_dev = snd_kcontrol_chip(kcontrol); + struct solo_dev *solo_dev = snd_kcontrol_chip(kcontrol); u8 ch = value->id.numid - 1; value->value.integer.value[0] = tw28_get_audio_gain(solo_dev, ch); @@ -275,7 +275,7 @@ static int snd_solo_capture_volume_get(struct snd_kcontrol *kcontrol, static int snd_solo_capture_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value) { - struct solo6010_dev *solo_dev = snd_kcontrol_chip(kcontrol); + struct solo_dev *solo_dev = snd_kcontrol_chip(kcontrol); u8 ch = value->id.numid - 1; u8 old_val; @@ -296,7 +296,7 @@ static struct snd_kcontrol_new snd_solo_capture_volume = { .put = snd_solo_capture_volume_put, }; -static int solo_snd_pcm_init(struct solo6010_dev *solo_dev) +static int solo_snd_pcm_init(struct solo_dev *solo_dev) { struct snd_card *card = solo_dev->snd_card; struct snd_pcm *pcm; @@ -332,7 +332,7 @@ static int solo_snd_pcm_init(struct solo6010_dev *solo_dev) return 0; } -int solo_g723_init(struct solo6010_dev *solo_dev) +int solo_g723_init(struct solo_dev *solo_dev) { static struct snd_device_ops ops = { NULL }; struct snd_card *card; @@ -352,8 +352,8 @@ int solo_g723_init(struct solo6010_dev *solo_dev) card = solo_dev->snd_card; - strcpy(card->driver, SOLO6010_NAME); - strcpy(card->shortname, "SOLO-6010 Audio"); + strcpy(card->driver, SOLO6X10_NAME); + strcpy(card->shortname, "SOLO-6x10 Audio"); sprintf(card->longname, "%s on %s IRQ %d", card->shortname, pci_name(solo_dev->pdev), solo_dev->pdev->irq); snd_card_set_dev(card, &solo_dev->pdev->dev); @@ -363,7 +363,7 @@ int solo_g723_init(struct solo6010_dev *solo_dev) goto snd_error; /* Mixer controls */ - strcpy(card->mixername, "SOLO-6010"); + strcpy(card->mixername, "SOLO-6x10"); kctl = snd_solo_capture_volume; kctl.count = solo_dev->nr_chans; ret = snd_ctl_add(card, snd_ctl_new1(&kctl, solo_dev)); @@ -389,10 +389,10 @@ snd_error: return ret; } -void solo_g723_exit(struct solo6010_dev *solo_dev) +void solo_g723_exit(struct solo_dev *solo_dev) { solo_reg_write(solo_dev, SOLO_AUDIO_CONTROL, 0); - solo6010_irq_off(solo_dev, SOLO_IRQ_G723); + solo_irq_off(solo_dev, SOLO_IRQ_G723); snd_card_free(solo_dev->snd_card); } diff --git a/drivers/staging/solo6x10/gpio.c b/drivers/staging/solo6x10/gpio.c index efd88bafcdf6..0925e6f33a99 100644 --- a/drivers/staging/solo6x10/gpio.c +++ b/drivers/staging/solo6x10/gpio.c @@ -22,7 +22,7 @@ #include #include "solo6x10.h" -static void solo_gpio_mode(struct solo6010_dev *solo_dev, +static void solo_gpio_mode(struct solo_dev *solo_dev, unsigned int port_mask, unsigned int mode) { int port; @@ -57,19 +57,19 @@ static void solo_gpio_mode(struct solo6010_dev *solo_dev, solo_reg_write(solo_dev, SOLO_GPIO_CONFIG_1, ret); } -static void solo_gpio_set(struct solo6010_dev *solo_dev, unsigned int value) +static void solo_gpio_set(struct solo_dev *solo_dev, unsigned int value) { solo_reg_write(solo_dev, SOLO_GPIO_DATA_OUT, solo_reg_read(solo_dev, SOLO_GPIO_DATA_OUT) | value); } -static void solo_gpio_clear(struct solo6010_dev *solo_dev, unsigned int value) +static void solo_gpio_clear(struct solo_dev *solo_dev, unsigned int value) { solo_reg_write(solo_dev, SOLO_GPIO_DATA_OUT, solo_reg_read(solo_dev, SOLO_GPIO_DATA_OUT) & ~value); } -static void solo_gpio_config(struct solo6010_dev *solo_dev) +static void solo_gpio_config(struct solo_dev *solo_dev) { /* Video reset */ solo_gpio_mode(solo_dev, 0x30, 1); @@ -89,13 +89,13 @@ static void solo_gpio_config(struct solo6010_dev *solo_dev) solo_gpio_clear(solo_dev, 0xff00); } -int solo_gpio_init(struct solo6010_dev *solo_dev) +int solo_gpio_init(struct solo_dev *solo_dev) { solo_gpio_config(solo_dev); return 0; } -void solo_gpio_exit(struct solo6010_dev *solo_dev) +void solo_gpio_exit(struct solo_dev *solo_dev) { solo_gpio_clear(solo_dev, 0x30); solo_gpio_config(solo_dev); diff --git a/drivers/staging/solo6x10/i2c.c b/drivers/staging/solo6x10/i2c.c index fba424741c46..ef95a500b4da 100644 --- a/drivers/staging/solo6x10/i2c.c +++ b/drivers/staging/solo6x10/i2c.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* XXX: The SOLO6010 i2c does not have separate interrupts for each i2c +/* XXX: The SOLO6x10 i2c does not have separate interrupts for each i2c * channel. The bus can only handle one i2c event at a time. The below handles * this all wrong. We should be using the status registers to see if the bus * is in use, and have a global lock to check the status register. Also, @@ -28,7 +28,7 @@ #include #include "solo6x10.h" -u8 solo_i2c_readbyte(struct solo6010_dev *solo_dev, int id, u8 addr, u8 off) +u8 solo_i2c_readbyte(struct solo_dev *solo_dev, int id, u8 addr, u8 off) { struct i2c_msg msgs[2]; u8 data; @@ -48,7 +48,7 @@ u8 solo_i2c_readbyte(struct solo6010_dev *solo_dev, int id, u8 addr, u8 off) return data; } -void solo_i2c_writebyte(struct solo6010_dev *solo_dev, int id, u8 addr, +void solo_i2c_writebyte(struct solo_dev *solo_dev, int id, u8 addr, u8 off, u8 data) { struct i2c_msg msgs; @@ -64,7 +64,7 @@ void solo_i2c_writebyte(struct solo6010_dev *solo_dev, int id, u8 addr, i2c_transfer(&solo_dev->i2c_adap[id], &msgs, 1); } -static void solo_i2c_flush(struct solo6010_dev *solo_dev, int wr) +static void solo_i2c_flush(struct solo_dev *solo_dev, int wr) { u32 ctrl; @@ -87,7 +87,7 @@ static void solo_i2c_flush(struct solo6010_dev *solo_dev, int wr) solo_reg_write(solo_dev, SOLO_IIC_CTRL, ctrl); } -static void solo_i2c_start(struct solo6010_dev *solo_dev) +static void solo_i2c_start(struct solo_dev *solo_dev) { u32 addr = solo_dev->i2c_msg->addr << 1; @@ -99,15 +99,15 @@ static void solo_i2c_start(struct solo6010_dev *solo_dev) solo_i2c_flush(solo_dev, 1); } -static void solo_i2c_stop(struct solo6010_dev *solo_dev) +static void solo_i2c_stop(struct solo_dev *solo_dev) { - solo6010_irq_off(solo_dev, SOLO_IRQ_IIC); + solo_irq_off(solo_dev, SOLO_IRQ_IIC); solo_reg_write(solo_dev, SOLO_IIC_CTRL, 0); solo_dev->i2c_state = IIC_STATE_STOP; wake_up(&solo_dev->i2c_wait); } -static int solo_i2c_handle_read(struct solo6010_dev *solo_dev) +static int solo_i2c_handle_read(struct solo_dev *solo_dev) { prepare_read: if (solo_dev->i2c_msg_ptr != solo_dev->i2c_msg->len) { @@ -136,7 +136,7 @@ prepare_read: return 0; } -static int solo_i2c_handle_write(struct solo6010_dev *solo_dev) +static int solo_i2c_handle_write(struct solo_dev *solo_dev) { retry_write: if (solo_dev->i2c_msg_ptr != solo_dev->i2c_msg->len) { @@ -168,7 +168,7 @@ retry_write: return 0; } -int solo_i2c_isr(struct solo6010_dev *solo_dev) +int solo_i2c_isr(struct solo_dev *solo_dev) { u32 status = solo_reg_read(solo_dev, SOLO_IIC_CTRL); int ret = -EINVAL; @@ -212,7 +212,7 @@ int solo_i2c_isr(struct solo6010_dev *solo_dev) static int solo_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { - struct solo6010_dev *solo_dev = adap->algo_data; + struct solo_dev *solo_dev = adap->algo_data; unsigned long timeout; int ret; int i; @@ -233,7 +233,7 @@ static int solo_i2c_master_xfer(struct i2c_adapter *adap, solo_dev->i2c_msg_ptr = 0; solo_reg_write(solo_dev, SOLO_IIC_CTRL, 0); - solo6010_irq_on(solo_dev, SOLO_IRQ_IIC); + solo_irq_on(solo_dev, SOLO_IRQ_IIC); solo_i2c_start(solo_dev); timeout = HZ / 2; @@ -272,7 +272,7 @@ static struct i2c_algorithm solo_i2c_algo = { .functionality = solo_i2c_functionality, }; -int solo_i2c_init(struct solo6010_dev *solo_dev) +int solo_i2c_init(struct solo_dev *solo_dev) { int i; int ret; @@ -288,8 +288,7 @@ int solo_i2c_init(struct solo6010_dev *solo_dev) for (i = 0; i < SOLO_I2C_ADAPTERS; i++) { struct i2c_adapter *adap = &solo_dev->i2c_adap[i]; - snprintf(adap->name, I2C_NAME_SIZE, "%s I2C %d", - SOLO6010_NAME, i); + snprintf(adap->name, I2C_NAME_SIZE, "%s I2C %d", SOLO6X10_NAME, i); adap->algo = &solo_i2c_algo; adap->algo_data = solo_dev; adap->retries = 1; @@ -318,7 +317,7 @@ int solo_i2c_init(struct solo6010_dev *solo_dev) return 0; } -void solo_i2c_exit(struct solo6010_dev *solo_dev) +void solo_i2c_exit(struct solo_dev *solo_dev) { int i; diff --git a/drivers/staging/solo6x10/jpeg.h b/drivers/staging/solo6x10/jpeg.h index fb0507ecb307..50defec318cc 100644 --- a/drivers/staging/solo6x10/jpeg.h +++ b/drivers/staging/solo6x10/jpeg.h @@ -17,8 +17,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __SOLO6010_JPEG_H -#define __SOLO6010_JPEG_H +#ifndef __SOLO6X10_JPEG_H +#define __SOLO6X10_JPEG_H static unsigned char jpeg_header[] = { 0xff, 0xd8, 0xff, 0xfe, 0x00, 0x0d, 0x42, 0x6c, @@ -102,4 +102,4 @@ static unsigned char jpeg_header[] = { /* This is the byte marker for the start of SOF0: 0xffc0 marker */ #define SOF0_START 575 -#endif /* __SOLO6010_JPEG_H */ +#endif /* __SOLO6X10_JPEG_H */ diff --git a/drivers/staging/solo6x10/offsets.h b/drivers/staging/solo6x10/offsets.h index b176003ff383..3d7e569f1cf8 100644 --- a/drivers/staging/solo6x10/offsets.h +++ b/drivers/staging/solo6x10/offsets.h @@ -17,8 +17,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __SOLO6010_OFFSETS_H -#define __SOLO6010_OFFSETS_H +#ifndef __SOLO6X10_OFFSETS_H +#define __SOLO6X10_OFFSETS_H /* Offsets and sizes of the external address */ #define SOLO_DISP_EXT_ADDR 0x00000000 @@ -71,4 +71,4 @@ (SOLO_MP4D_EXT_SIZE * __solo->nr_chans)) #define SOLO_JPEG_EXT_SIZE(__solo) (0x00080000 * __solo->nr_chans) -#endif /* __SOLO6010_OFFSETS_H */ +#endif /* __SOLO6X10_OFFSETS_H */ diff --git a/drivers/staging/solo6x10/osd-font.h b/drivers/staging/solo6x10/osd-font.h index d72efbb3bb3d..591e0e82e0e8 100644 --- a/drivers/staging/solo6x10/osd-font.h +++ b/drivers/staging/solo6x10/osd-font.h @@ -17,8 +17,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __SOLO6010_OSD_FONT_H -#define __SOLO6010_OSD_FONT_H +#ifndef __SOLO6X10_OSD_FONT_H +#define __SOLO6X10_OSD_FONT_H static const unsigned int solo_osd_font[] = { 0x00000000, 0x0000c0c8, 0xccfefe0c, 0x08000000, @@ -151,4 +151,4 @@ static const unsigned int solo_osd_font[] = { 0x00000000, 0x0010386c, 0xc6c6fe00, 0x00000000 }; -#endif /* __SOLO6010_OSD_FONT_H */ +#endif /* __SOLO6X10_OSD_FONT_H */ diff --git a/drivers/staging/solo6x10/p2m.c b/drivers/staging/solo6x10/p2m.c index 1b88d1053f94..5717eabb04a4 100644 --- a/drivers/staging/solo6x10/p2m.c +++ b/drivers/staging/solo6x10/p2m.c @@ -23,7 +23,7 @@ /* #define SOLO_TEST_P2M */ -int solo_p2m_dma(struct solo6010_dev *solo_dev, u8 id, int wr, +int solo_p2m_dma(struct solo_dev *solo_dev, u8 id, int wr, void *sys_addr, u32 ext_addr, u32 size) { dma_addr_t dma_addr; @@ -46,7 +46,7 @@ int solo_p2m_dma(struct solo6010_dev *solo_dev, u8 id, int wr, return ret; } -int solo_p2m_dma_t(struct solo6010_dev *solo_dev, u8 id, int wr, +int solo_p2m_dma_t(struct solo_dev *solo_dev, u8 id, int wr, dma_addr_t dma_addr, u32 ext_addr, u32 size) { struct p2m_desc *desc = kzalloc(sizeof(*desc) * 2, GFP_DMA); @@ -80,7 +80,7 @@ void solo_p2m_push_desc(struct p2m_desc *desc, int wr, dma_addr_t dma_addr, } } -int solo_p2m_dma_desc(struct solo6010_dev *solo_dev, u8 id, +int solo_p2m_dma_desc(struct solo_dev *solo_dev, u8 id, struct p2m_desc *desc, int desc_count) { struct solo_p2m_dev *p2m_dev; @@ -136,7 +136,7 @@ int solo_p2m_dma_desc(struct solo6010_dev *solo_dev, u8 id, return ret; } -int solo_p2m_dma_sg(struct solo6010_dev *solo_dev, u8 id, +int solo_p2m_dma_sg(struct solo_dev *solo_dev, u8 id, struct p2m_desc *pdesc, int wr, struct scatterlist *sg, u32 sg_off, u32 ext_addr, u32 size) @@ -185,7 +185,7 @@ int solo_p2m_dma_sg(struct solo6010_dev *solo_dev, u8 id, #define P2M_TEST_CHAR 0xbe -static unsigned long long p2m_test(struct solo6010_dev *solo_dev, u8 id, +static unsigned long long p2m_test(struct solo_dev *solo_dev, u8 id, u32 base, int size) { u8 *wr_buf; @@ -195,13 +195,13 @@ static unsigned long long p2m_test(struct solo6010_dev *solo_dev, u8 id, wr_buf = kmalloc(size, GFP_KERNEL); if (!wr_buf) { - printk(SOLO6010_NAME ": Failed to malloc for p2m_test\n"); + printk(SOLO6X10_NAME ": Failed to malloc for p2m_test\n"); return size; } rd_buf = kmalloc(size, GFP_KERNEL); if (!rd_buf) { - printk(SOLO6010_NAME ": Failed to malloc for p2m_test\n"); + printk(SOLO6X10_NAME ": Failed to malloc for p2m_test\n"); kfree(wr_buf); return size; } @@ -224,21 +224,21 @@ static unsigned long long p2m_test(struct solo6010_dev *solo_dev, u8 id, #define TEST_CHUNK_SIZE (8 * 1024) -static void run_p2m_test(struct solo6010_dev *solo_dev) +static void run_p2m_test(struct solo_dev *solo_dev) { unsigned long long errs = 0; u32 size = SOLO_JPEG_EXT_ADDR(solo_dev) + SOLO_JPEG_EXT_SIZE(solo_dev); int i, d; printk(KERN_WARNING "%s: Testing %u bytes of external ram\n", - SOLO6010_NAME, size); + SOLO6X10_NAME, size); for (i = 0; i < size; i += TEST_CHUNK_SIZE) for (d = 0; d < 4; d++) errs += p2m_test(solo_dev, d, i, TEST_CHUNK_SIZE); printk(KERN_WARNING "%s: Found %llu errors during p2m test\n", - SOLO6010_NAME, errs); + SOLO6X10_NAME, errs); return; } @@ -246,7 +246,7 @@ static void run_p2m_test(struct solo6010_dev *solo_dev) #define run_p2m_test(__solo) do {} while (0) #endif -void solo_p2m_isr(struct solo6010_dev *solo_dev, int id) +void solo_p2m_isr(struct solo_dev *solo_dev, int id) { struct solo_p2m_dev *p2m_dev = &solo_dev->p2m_dev[id]; @@ -255,7 +255,7 @@ void solo_p2m_isr(struct solo6010_dev *solo_dev, int id) complete(&p2m_dev->completion); } -void solo_p2m_error_isr(struct solo6010_dev *solo_dev, u32 status) +void solo_p2m_error_isr(struct solo_dev *solo_dev, u32 status) { struct solo_p2m_dev *p2m_dev; int i; @@ -271,15 +271,15 @@ void solo_p2m_error_isr(struct solo6010_dev *solo_dev, u32 status) } } -void solo_p2m_exit(struct solo6010_dev *solo_dev) +void solo_p2m_exit(struct solo_dev *solo_dev) { int i; for (i = 0; i < SOLO_NR_P2M; i++) - solo6010_irq_off(solo_dev, SOLO_IRQ_P2M(i)); + solo_irq_off(solo_dev, SOLO_IRQ_P2M(i)); } -int solo_p2m_init(struct solo6010_dev *solo_dev) +int solo_p2m_init(struct solo_dev *solo_dev) { struct solo_p2m_dev *p2m_dev; int i; @@ -296,7 +296,7 @@ int solo_p2m_init(struct solo6010_dev *solo_dev) SOLO_P2M_DMA_INTERVAL(3) | SOLO_P2M_DESC_INTR_OPT | SOLO_P2M_PCI_MASTER_MODE); - solo6010_irq_on(solo_dev, SOLO_IRQ_P2M(i)); + solo_irq_on(solo_dev, SOLO_IRQ_P2M(i)); } run_p2m_test(solo_dev); diff --git a/drivers/staging/solo6x10/registers.h b/drivers/staging/solo6x10/registers.h index edf77e8a8e92..aca544472c93 100644 --- a/drivers/staging/solo6x10/registers.h +++ b/drivers/staging/solo6x10/registers.h @@ -17,12 +17,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __SOLO6010_REGISTERS_H -#define __SOLO6010_REGISTERS_H +#ifndef __SOLO6X10_REGISTERS_H +#define __SOLO6X10_REGISTERS_H #include "offsets.h" -/* Global 6010 system configuration */ +/* Global 6X10 system configuration */ #define SOLO_SYS_CFG 0x0000 #define SOLO6010_SYS_CFG_FOUT_EN 0x00000001 /* 6010 only */ #define SOLO6010_SYS_CFG_PLL_BYPASS 0x00000002 /* 6010 only */ @@ -634,4 +634,4 @@ #define WATCHDOG_STAT(status) (status<<8) #define WATCHDOG_TIME(sec) (sec&0xff) -#endif /* __SOLO6010_REGISTERS_H */ +#endif /* __SOLO6X10_REGISTERS_H */ diff --git a/drivers/staging/solo6x10/solo6x10.h b/drivers/staging/solo6x10/solo6x10.h index 1730f4d688d5..fd59b093dd4d 100644 --- a/drivers/staging/solo6x10/solo6x10.h +++ b/drivers/staging/solo6x10/solo6x10.h @@ -17,8 +17,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __SOLO6010_H -#define __SOLO6010_H +#ifndef __SOLO6X10_H +#define __SOLO6X10_H #include #include @@ -57,22 +57,22 @@ #define PCI_DEVICE_ID_BC_6110_16 0x5310 #endif /* Bluecherry */ -#define SOLO6010_NAME "solo6010" +#define SOLO6X10_NAME "solo6x10" #define SOLO_MAX_CHANNELS 16 /* Make sure these two match */ -#define SOLO6010_VERSION "2.0.0" -#define SOLO6010_VER_MAJOR 2 -#define SOLO6010_VER_MINOR 0 -#define SOLO6010_VER_SUB 0 -#define SOLO6010_VER_NUM \ - KERNEL_VERSION(SOLO6010_VER_MAJOR, SOLO6010_VER_MINOR, SOLO6010_VER_SUB) +#define SOLO6X10_VERSION "2.1.0" +#define SOLO6X10_VER_MAJOR 2 +#define SOLO6X10_VER_MINOR 0 +#define SOLO6X10_VER_SUB 0 +#define SOLO6X10_VER_NUM \ + KERNEL_VERSION(SOLO6X10_VER_MAJOR, SOLO6X10_VER_MINOR, SOLO6X10_VER_SUB) #define FLAGS_6110 1 /* - * The SOLO6010 actually has 8 i2c channels, but we only use 2. + * The SOLO6x10 actually has 8 i2c channels, but we only use 2. * 0 - Techwell chip(s) * 1 - SAA7128 */ @@ -148,7 +148,7 @@ enum solo_enc_types { }; struct solo_enc_dev { - struct solo6010_dev *solo_dev; + struct solo_dev *solo_dev; /* V4L2 Items */ struct video_device *vfd; /* General accounting */ @@ -177,8 +177,8 @@ struct solo_enc_buf { struct timeval ts; }; -/* The SOLO6010 PCI Device */ -struct solo6010_dev { +/* The SOLO6x10 PCI Device */ +struct solo_dev { /* General stuff */ struct pci_dev *pdev; u8 __iomem *reg_base; @@ -236,7 +236,7 @@ struct solo6010_dev { int g723_hw_idx; }; -static inline u32 solo_reg_read(struct solo6010_dev *solo_dev, int reg) +static inline u32 solo_reg_read(struct solo_dev *solo_dev, int reg) { unsigned long flags; u32 ret; @@ -254,8 +254,7 @@ static inline u32 solo_reg_read(struct solo6010_dev *solo_dev, int reg) return ret; } -static inline void solo_reg_write(struct solo6010_dev *solo_dev, int reg, - u32 data) +static inline void solo_reg_write(struct solo_dev *solo_dev, int reg, u32 data) { unsigned long flags; u16 val; @@ -270,67 +269,67 @@ static inline void solo_reg_write(struct solo6010_dev *solo_dev, int reg, spin_unlock_irqrestore(&solo_dev->reg_io_lock, flags); } -void solo6010_irq_on(struct solo6010_dev *solo_dev, u32 mask); -void solo6010_irq_off(struct solo6010_dev *solo_dev, u32 mask); +void solo_irq_on(struct solo_dev *solo_dev, u32 mask); +void solo_irq_off(struct solo_dev *solo_dev, u32 mask); /* Init/exit routeines for subsystems */ -int solo_disp_init(struct solo6010_dev *solo_dev); -void solo_disp_exit(struct solo6010_dev *solo_dev); +int solo_disp_init(struct solo_dev *solo_dev); +void solo_disp_exit(struct solo_dev *solo_dev); -int solo_gpio_init(struct solo6010_dev *solo_dev); -void solo_gpio_exit(struct solo6010_dev *solo_dev); +int solo_gpio_init(struct solo_dev *solo_dev); +void solo_gpio_exit(struct solo_dev *solo_dev); -int solo_i2c_init(struct solo6010_dev *solo_dev); -void solo_i2c_exit(struct solo6010_dev *solo_dev); +int solo_i2c_init(struct solo_dev *solo_dev); +void solo_i2c_exit(struct solo_dev *solo_dev); -int solo_p2m_init(struct solo6010_dev *solo_dev); -void solo_p2m_exit(struct solo6010_dev *solo_dev); +int solo_p2m_init(struct solo_dev *solo_dev); +void solo_p2m_exit(struct solo_dev *solo_dev); -int solo_v4l2_init(struct solo6010_dev *solo_dev); -void solo_v4l2_exit(struct solo6010_dev *solo_dev); +int solo_v4l2_init(struct solo_dev *solo_dev); +void solo_v4l2_exit(struct solo_dev *solo_dev); -int solo_enc_init(struct solo6010_dev *solo_dev); -void solo_enc_exit(struct solo6010_dev *solo_dev); +int solo_enc_init(struct solo_dev *solo_dev); +void solo_enc_exit(struct solo_dev *solo_dev); -int solo_enc_v4l2_init(struct solo6010_dev *solo_dev); -void solo_enc_v4l2_exit(struct solo6010_dev *solo_dev); +int solo_enc_v4l2_init(struct solo_dev *solo_dev); +void solo_enc_v4l2_exit(struct solo_dev *solo_dev); -int solo_g723_init(struct solo6010_dev *solo_dev); -void solo_g723_exit(struct solo6010_dev *solo_dev); +int solo_g723_init(struct solo_dev *solo_dev); +void solo_g723_exit(struct solo_dev *solo_dev); /* ISR's */ -int solo_i2c_isr(struct solo6010_dev *solo_dev); -void solo_p2m_isr(struct solo6010_dev *solo_dev, int id); -void solo_p2m_error_isr(struct solo6010_dev *solo_dev, u32 status); -void solo_enc_v4l2_isr(struct solo6010_dev *solo_dev); -void solo_g723_isr(struct solo6010_dev *solo_dev); -void solo_motion_isr(struct solo6010_dev *solo_dev); -void solo_video_in_isr(struct solo6010_dev *solo_dev); +int solo_i2c_isr(struct solo_dev *solo_dev); +void solo_p2m_isr(struct solo_dev *solo_dev, int id); +void solo_p2m_error_isr(struct solo_dev *solo_dev, u32 status); +void solo_enc_v4l2_isr(struct solo_dev *solo_dev); +void solo_g723_isr(struct solo_dev *solo_dev); +void solo_motion_isr(struct solo_dev *solo_dev); +void solo_video_in_isr(struct solo_dev *solo_dev); /* i2c read/write */ -u8 solo_i2c_readbyte(struct solo6010_dev *solo_dev, int id, u8 addr, u8 off); -void solo_i2c_writebyte(struct solo6010_dev *solo_dev, int id, u8 addr, u8 off, +u8 solo_i2c_readbyte(struct solo_dev *solo_dev, int id, u8 addr, u8 off); +void solo_i2c_writebyte(struct solo_dev *solo_dev, int id, u8 addr, u8 off, u8 data); /* P2M DMA */ -int solo_p2m_dma_t(struct solo6010_dev *solo_dev, u8 id, int wr, +int solo_p2m_dma_t(struct solo_dev *solo_dev, u8 id, int wr, dma_addr_t dma_addr, u32 ext_addr, u32 size); -int solo_p2m_dma(struct solo6010_dev *solo_dev, u8 id, int wr, +int solo_p2m_dma(struct solo_dev *solo_dev, u8 id, int wr, void *sys_addr, u32 ext_addr, u32 size); -int solo_p2m_dma_sg(struct solo6010_dev *solo_dev, u8 id, +int solo_p2m_dma_sg(struct solo_dev *solo_dev, u8 id, struct p2m_desc *pdesc, int wr, struct scatterlist *sglist, u32 sg_off, u32 ext_addr, u32 size); void solo_p2m_push_desc(struct p2m_desc *desc, int wr, dma_addr_t dma_addr, u32 ext_addr, u32 size, int repeat, u32 ext_size); -int solo_p2m_dma_desc(struct solo6010_dev *solo_dev, u8 id, +int solo_p2m_dma_desc(struct solo_dev *solo_dev, u8 id, struct p2m_desc *desc, int desc_count); /* Set the threshold for motion detection */ -void solo_set_motion_threshold(struct solo6010_dev *solo_dev, u8 ch, u16 val); +void solo_set_motion_threshold(struct solo_dev *solo_dev, u8 ch, u16 val); #define SOLO_DEF_MOT_THRESH 0x0300 /* Write text on OSD */ int solo_osd_print(struct solo_enc_dev *solo_enc); -#endif /* __SOLO6010_H */ +#endif /* __SOLO6X10_H */ diff --git a/drivers/staging/solo6x10/tw28.c b/drivers/staging/solo6x10/tw28.c index 0f3d1e44c65a..db56b42c56c6 100644 --- a/drivers/staging/solo6x10/tw28.c +++ b/drivers/staging/solo6x10/tw28.c @@ -140,7 +140,7 @@ static u8 tbl_tw2865_pal_template[] = { #define is_tw286x(__solo, __id) (!(__solo->tw2815 & (1 << __id))) -static u8 tw_readbyte(struct solo6010_dev *solo_dev, int chip_id, u8 tw6x_off, +static u8 tw_readbyte(struct solo_dev *solo_dev, int chip_id, u8 tw6x_off, u8 tw_off) { if (is_tw286x(solo_dev, chip_id)) @@ -153,7 +153,7 @@ static u8 tw_readbyte(struct solo6010_dev *solo_dev, int chip_id, u8 tw6x_off, tw_off); } -static void tw_writebyte(struct solo6010_dev *solo_dev, int chip_id, +static void tw_writebyte(struct solo_dev *solo_dev, int chip_id, u8 tw6x_off, u8 tw_off, u8 val) { if (is_tw286x(solo_dev, chip_id)) @@ -166,7 +166,7 @@ static void tw_writebyte(struct solo6010_dev *solo_dev, int chip_id, tw_off, val); } -static void tw_write_and_verify(struct solo6010_dev *solo_dev, u8 addr, u8 off, +static void tw_write_and_verify(struct solo_dev *solo_dev, u8 addr, u8 off, u8 val) { int i; @@ -180,11 +180,11 @@ static void tw_write_and_verify(struct solo6010_dev *solo_dev, u8 addr, u8 off, msleep_interruptible(1); } -/* printk("solo6010/tw28: Error writing register: %02x->%02x [%02x]\n", +/* printk("solo6x10/tw28: Error writing register: %02x->%02x [%02x]\n", addr, off, val); */ } -static int tw2865_setup(struct solo6010_dev *solo_dev, u8 dev_addr) +static int tw2865_setup(struct solo_dev *solo_dev, u8 dev_addr) { u8 tbl_tw2865_common[256]; int i; @@ -234,7 +234,7 @@ static int tw2865_setup(struct solo6010_dev *solo_dev, u8 dev_addr) return 0; } -static int tw2864_setup(struct solo6010_dev *solo_dev, u8 dev_addr) +static int tw2864_setup(struct solo_dev *solo_dev, u8 dev_addr) { u8 tbl_tw2864_common[sizeof(tbl_tw2864_template)]; int i; @@ -320,7 +320,7 @@ static int tw2864_setup(struct solo6010_dev *solo_dev, u8 dev_addr) return 0; } -static int tw2815_setup(struct solo6010_dev *solo_dev, u8 dev_addr) +static int tw2815_setup(struct solo_dev *solo_dev, u8 dev_addr) { u8 tbl_ntsc_tw2815_common[] = { 0x00, 0xc8, 0x20, 0xd0, 0x06, 0xf0, 0x08, 0x80, @@ -481,7 +481,7 @@ static int tw2815_setup(struct solo6010_dev *solo_dev, u8 dev_addr) #define FIRST_ACTIVE_LINE 0x0008 #define LAST_ACTIVE_LINE 0x0102 -static void saa7128_setup(struct solo6010_dev *solo_dev) +static void saa7128_setup(struct solo_dev *solo_dev) { int i; unsigned char regs[128] = { @@ -539,7 +539,7 @@ static void saa7128_setup(struct solo6010_dev *solo_dev) return; } -int solo_tw28_init(struct solo6010_dev *solo_dev) +int solo_tw28_init(struct solo_dev *solo_dev) { int i; u8 value; @@ -602,7 +602,7 @@ int solo_tw28_init(struct solo6010_dev *solo_dev) * (address 0x012C) of the SOLO6010 chip doesn't give the correct video * status signal values. */ -int tw28_get_video_status(struct solo6010_dev *solo_dev, u8 ch) +int tw28_get_video_status(struct solo_dev *solo_dev, u8 ch) { u8 val, chip_num; @@ -619,7 +619,7 @@ int tw28_get_video_status(struct solo6010_dev *solo_dev, u8 ch) #if 0 /* Status of audio from up to 4 techwell chips are combined into 1 variable. * See techwell datasheet for details. */ -u16 tw28_get_audio_status(struct solo6010_dev *solo_dev) +u16 tw28_get_audio_status(struct solo_dev *solo_dev) { u8 val; u16 status = 0; @@ -635,8 +635,7 @@ u16 tw28_get_audio_status(struct solo6010_dev *solo_dev) } #endif -int tw28_set_ctrl_val(struct solo6010_dev *solo_dev, u32 ctrl, u8 ch, - s32 val) +int tw28_set_ctrl_val(struct solo_dev *solo_dev, u32 ctrl, u8 ch, s32 val) { char sval; u8 chip_num; @@ -708,7 +707,7 @@ int tw28_set_ctrl_val(struct solo6010_dev *solo_dev, u32 ctrl, u8 ch, return 0; } -int tw28_get_ctrl_val(struct solo6010_dev *solo_dev, u32 ctrl, u8 ch, +int tw28_get_ctrl_val(struct solo_dev *solo_dev, u32 ctrl, u8 ch, s32 *val) { u8 rval, chip_num; @@ -768,7 +767,7 @@ int tw28_get_ctrl_val(struct solo6010_dev *solo_dev, u32 ctrl, u8 ch, * don't need to offset TW_CHIP_OFFSET_ADDR. The TW_CHIP_OFFSET_ADDR used * is the base address of the techwell chip. */ -void tw2815_Set_AudioOutVol(struct solo6010_dev *solo_dev, unsigned int u_val) +void tw2815_Set_AudioOutVol(struct solo_dev *solo_dev, unsigned int u_val) { unsigned int val; unsigned int chip_num; @@ -785,7 +784,7 @@ void tw2815_Set_AudioOutVol(struct solo6010_dev *solo_dev, unsigned int u_val) } #endif -u8 tw28_get_audio_gain(struct solo6010_dev *solo_dev, u8 ch) +u8 tw28_get_audio_gain(struct solo_dev *solo_dev, u8 ch) { u8 val; u8 chip_num; @@ -801,7 +800,7 @@ u8 tw28_get_audio_gain(struct solo6010_dev *solo_dev, u8 ch) return (ch % 2) ? (val >> 4) : (val & 0x0f); } -void tw28_set_audio_gain(struct solo6010_dev *solo_dev, u8 ch, u8 val) +void tw28_set_audio_gain(struct solo_dev *solo_dev, u8 ch, u8 val) { u8 old_val; u8 chip_num; diff --git a/drivers/staging/solo6x10/tw28.h b/drivers/staging/solo6x10/tw28.h index 4862ac90dbd9..a44a03afbd30 100644 --- a/drivers/staging/solo6x10/tw28.h +++ b/drivers/staging/solo6x10/tw28.h @@ -17,8 +17,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __SOLO6010_TW28_H -#define __SOLO6010_TW28_H +#ifndef __SOLO6X10_TW28_H +#define __SOLO6X10_TW28_H #include "solo6x10.h" @@ -46,20 +46,18 @@ #define TW286x_AUDIO_OUTPUT_VOL_ADDR 0xdf #define TW286x_AUDIO_INPUT_GAIN_ADDR(n) (0xD0 + ((n > 1) ? 1 : 0)) -int solo_tw28_init(struct solo6010_dev *solo_dev); +int solo_tw28_init(struct solo_dev *solo_dev); -int tw28_set_ctrl_val(struct solo6010_dev *solo_dev, u32 ctrl, u8 ch, - s32 val); -int tw28_get_ctrl_val(struct solo6010_dev *solo_dev, u32 ctrl, u8 ch, - s32 *val); +int tw28_set_ctrl_val(struct solo_dev *solo_dev, u32 ctrl, u8 ch, s32 val); +int tw28_get_ctrl_val(struct solo_dev *solo_dev, u32 ctrl, u8 ch, s32 *val); -u8 tw28_get_audio_gain(struct solo6010_dev *solo_dev, u8 ch); -void tw28_set_audio_gain(struct solo6010_dev *solo_dev, u8 ch, u8 val); -int tw28_get_video_status(struct solo6010_dev *solo_dev, u8 ch); +u8 tw28_get_audio_gain(struct solo_dev *solo_dev, u8 ch); +void tw28_set_audio_gain(struct solo_dev *solo_dev, u8 ch, u8 val); +int tw28_get_video_status(struct solo_dev *solo_dev, u8 ch); #if 0 -unsigned int tw2815_get_audio_status(struct SOLO6010 *solo6010); -void tw2815_Set_AudioOutVol(struct SOLO6010 *solo6010, unsigned int u_val); +unsigned int tw2815_get_audio_status(struct SOLO *solo); +void tw2815_Set_AudioOutVol(struct SOLO *solo, unsigned int u_val); #endif -#endif /* __SOLO6010_TW28_H */ +#endif /* __SOLO6X10_TW28_H */ diff --git a/drivers/staging/solo6x10/v4l2-enc.c b/drivers/staging/solo6x10/v4l2-enc.c index b88192313112..bee7280bbed9 100644 --- a/drivers/staging/solo6x10/v4l2-enc.c +++ b/drivers/staging/solo6x10/v4l2-enc.c @@ -84,7 +84,7 @@ static const u32 *solo_ctrl_classes[] = { static int solo_is_motion_on(struct solo_enc_dev *solo_enc) { - struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct solo_dev *solo_dev = solo_enc->solo_dev; u8 ch = solo_enc->ch; if (solo_dev->motion_mask & (1 << ch)) @@ -94,7 +94,7 @@ static int solo_is_motion_on(struct solo_enc_dev *solo_enc) static void solo_motion_toggle(struct solo_enc_dev *solo_enc, int on) { - struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct solo_dev *solo_dev = solo_enc->solo_dev; u8 ch = solo_enc->ch; spin_lock(&solo_enc->lock); @@ -114,9 +114,9 @@ static void solo_motion_toggle(struct solo_enc_dev *solo_enc, int on) (SOLO_MOTION_EXT_ADDR(solo_dev) >> 16)); if (solo_dev->motion_mask) - solo6010_irq_on(solo_dev, SOLO_IRQ_MOTION); + solo_irq_on(solo_dev, SOLO_IRQ_MOTION); else - solo6010_irq_off(solo_dev, SOLO_IRQ_MOTION); + solo_irq_off(solo_dev, SOLO_IRQ_MOTION); spin_unlock(&solo_enc->lock); } @@ -124,7 +124,7 @@ static void solo_motion_toggle(struct solo_enc_dev *solo_enc, int on) /* Should be called with solo_enc->lock held */ static void solo_update_mode(struct solo_enc_dev *solo_enc) { - struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct solo_dev *solo_dev = solo_enc->solo_dev; assert_spin_locked(&solo_enc->lock); @@ -151,7 +151,7 @@ static int solo_enc_on(struct solo_enc_fh *fh) { struct solo_enc_dev *solo_enc = fh->enc; u8 ch = solo_enc->ch; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct solo_dev *solo_dev = solo_enc->solo_dev; u8 interval; assert_spin_locked(&solo_enc->lock); @@ -212,7 +212,7 @@ static int solo_enc_on(struct solo_enc_fh *fh) static void solo_enc_off(struct solo_enc_fh *fh) { struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct solo_dev *solo_dev = solo_enc->solo_dev; if (!fh->enc_on) return; @@ -236,7 +236,7 @@ static int solo_start_fh_thread(struct solo_enc_fh *fh) { struct solo_enc_dev *solo_enc = fh->enc; - fh->kthread = kthread_run(solo_enc_thread, fh, SOLO6010_NAME "_enc"); + fh->kthread = kthread_run(solo_enc_thread, fh, SOLO6X10_NAME "_enc"); /* Oops, we had a problem */ if (IS_ERR(fh->kthread)) { @@ -250,14 +250,14 @@ static int solo_start_fh_thread(struct solo_enc_fh *fh) return 0; } -static void enc_reset_gop(struct solo6010_dev *solo_dev, u8 ch) +static void enc_reset_gop(struct solo_dev *solo_dev, u8 ch) { BUG_ON(ch >= solo_dev->nr_chans); solo_reg_write(solo_dev, SOLO_VE_CH_GOP(ch), 1); solo_dev->v4l2_enc[ch]->reset_gop = 1; } -static int enc_gop_reset(struct solo6010_dev *solo_dev, u8 ch, u8 vop) +static int enc_gop_reset(struct solo_dev *solo_dev, u8 ch, u8 vop) { BUG_ON(ch >= solo_dev->nr_chans); if (!solo_dev->v4l2_enc[ch]->reset_gop) @@ -285,7 +285,7 @@ static void enc_write_sg(struct scatterlist *sglist, void *buf, int size) } } -static int enc_get_mpeg_dma_sg(struct solo6010_dev *solo_dev, +static int enc_get_mpeg_dma_sg(struct solo_dev *solo_dev, struct p2m_desc *desc, struct scatterlist *sglist, int skip, unsigned int off, unsigned int size) @@ -314,7 +314,7 @@ static int enc_get_mpeg_dma_sg(struct solo6010_dev *solo_dev, return ret; } -static int enc_get_mpeg_dma_t(struct solo6010_dev *solo_dev, +static int enc_get_mpeg_dma_t(struct solo_dev *solo_dev, dma_addr_t buf, unsigned int off, unsigned int size) { @@ -341,7 +341,7 @@ static int enc_get_mpeg_dma_t(struct solo6010_dev *solo_dev, return ret; } -static int enc_get_mpeg_dma(struct solo6010_dev *solo_dev, void *buf, +static int enc_get_mpeg_dma(struct solo_dev *solo_dev, void *buf, unsigned int off, unsigned int size) { int ret; @@ -354,7 +354,7 @@ static int enc_get_mpeg_dma(struct solo6010_dev *solo_dev, void *buf, return ret; } -static int enc_get_jpeg_dma_sg(struct solo6010_dev *solo_dev, +static int enc_get_jpeg_dma_sg(struct solo_dev *solo_dev, struct p2m_desc *desc, struct scatterlist *sglist, int skip, unsigned int off, unsigned int size) @@ -421,7 +421,7 @@ static int solo_fill_jpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf, struct videobuf_buffer *vb, struct videobuf_dmabuf *vbuf) { - struct solo6010_dev *solo_dev = fh->enc->solo_dev; + struct solo_dev *solo_dev = fh->enc->solo_dev; int size = enc_buf->jpeg_size; /* Copy the header first (direct write) */ @@ -515,7 +515,7 @@ static void write_h264_end(u8 **out, unsigned *bits, int align) write_bits(out, bits, 0, 1); } -static void mpeg4_write_vol(u8 **out, struct solo6010_dev *solo_dev, +static void mpeg4_write_vol(u8 **out, struct solo_dev *solo_dev, __le32 *vh, unsigned fps, unsigned interval) { static const u8 hdr[] = { @@ -569,7 +569,7 @@ static void mpeg4_write_vol(u8 **out, struct solo6010_dev *solo_dev, write_mpeg4_end(out, &bits); } -static void h264_write_vol(u8 **out, struct solo6010_dev *solo_dev, __le32 *vh) +static void h264_write_vol(u8 **out, struct solo_dev *solo_dev, __le32 *vh) { static const u8 sps[] = { 0, 0, 0, 1 /* start code */, 0x67, 66 /* profile_idc */, @@ -622,7 +622,7 @@ static int solo_fill_mpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf, struct videobuf_dmabuf *vbuf) { struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct solo_dev *solo_dev = solo_enc->solo_dev; #define VH_WORDS 16 #define MAX_VOL_HEADER_LENGTH 64 @@ -678,7 +678,7 @@ static void solo_enc_fillbuf(struct solo_enc_fh *fh, struct videobuf_buffer *vb) { struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct solo_dev *solo_dev = solo_enc->solo_dev; struct solo_enc_buf *enc_buf = NULL; struct videobuf_dmabuf *vbuf; int ret; @@ -746,7 +746,7 @@ buf_err: static void solo_enc_thread_try(struct solo_enc_fh *fh) { struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct solo_dev *solo_dev = solo_enc->solo_dev; struct videobuf_buffer *vb; for (;;) { @@ -797,7 +797,7 @@ static int solo_enc_thread(void *data) return 0; } -void solo_motion_isr(struct solo6010_dev *solo_dev) +void solo_motion_isr(struct solo_dev *solo_dev) { u32 status; int i; @@ -820,7 +820,7 @@ void solo_motion_isr(struct solo6010_dev *solo_dev) } } -void solo_enc_v4l2_isr(struct solo6010_dev *solo_dev) +void solo_enc_v4l2_isr(struct solo_dev *solo_dev) { struct solo_enc_buf *enc_buf; u32 mpeg_current, mpeg_next, mpeg_size; @@ -1056,14 +1056,14 @@ static int solo_enc_querycap(struct file *file, void *priv, { struct solo_enc_fh *fh = priv; struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct solo_dev *solo_dev = solo_enc->solo_dev; - strcpy(cap->driver, SOLO6010_NAME); - snprintf(cap->card, sizeof(cap->card), "Softlogic 6010 Enc %d", + strcpy(cap->driver, SOLO6X10_NAME); + snprintf(cap->card, sizeof(cap->card), "Softlogic 6x10 Enc %d", solo_enc->ch); snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI %s", pci_name(solo_dev->pdev)); - cap->version = SOLO6010_VER_NUM; + cap->version = SOLO6X10_VER_NUM; cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; @@ -1075,7 +1075,7 @@ static int solo_enc_enum_input(struct file *file, void *priv, { struct solo_enc_fh *fh = priv; struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct solo_dev *solo_dev = solo_enc->solo_dev; if (input->index) return -EINVAL; @@ -1137,7 +1137,7 @@ static int solo_enc_try_fmt_cap(struct file *file, void *priv, { struct solo_enc_fh *fh = priv; struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct solo_dev *solo_dev = solo_enc->solo_dev; struct v4l2_pix_format *pix = &f->fmt.pix; if (pix->pixelformat != V4L2_PIX_FMT_MPEG && @@ -1179,7 +1179,7 @@ static int solo_enc_set_fmt_cap(struct file *file, void *priv, { struct solo_enc_fh *fh = priv; struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct solo_dev *solo_dev = solo_enc->solo_dev; struct v4l2_pix_format *pix = &f->fmt.pix; int ret; @@ -1335,7 +1335,7 @@ static int solo_enum_framesizes(struct file *file, void *priv, struct v4l2_frmsizeenum *fsize) { struct solo_enc_fh *fh = priv; - struct solo6010_dev *solo_dev = fh->enc->solo_dev; + struct solo_dev *solo_dev = fh->enc->solo_dev; if (fsize->pixel_format != V4L2_PIX_FMT_MPEG) return -EINVAL; @@ -1362,7 +1362,7 @@ static int solo_enum_frameintervals(struct file *file, void *priv, struct v4l2_frmivalenum *fintv) { struct solo_enc_fh *fh = priv; - struct solo6010_dev *solo_dev = fh->enc->solo_dev; + struct solo_dev *solo_dev = fh->enc->solo_dev; if (fintv->pixel_format != V4L2_PIX_FMT_MPEG || fintv->index) return -EINVAL; @@ -1386,7 +1386,7 @@ static int solo_g_parm(struct file *file, void *priv, { struct solo_enc_fh *fh = priv; struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct solo_dev *solo_dev = solo_enc->solo_dev; struct v4l2_captureparm *cp = &sp->parm.capture; cp->capability = V4L2_CAP_TIMEPERFRAME; @@ -1404,7 +1404,7 @@ static int solo_s_parm(struct file *file, void *priv, { struct solo_enc_fh *fh = priv; struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct solo_dev *solo_dev = solo_enc->solo_dev; struct v4l2_captureparm *cp = &sp->parm.capture; spin_lock(&solo_enc->lock); @@ -1444,7 +1444,7 @@ static int solo_queryctrl(struct file *file, void *priv, { struct solo_enc_fh *fh = priv; struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct solo_dev *solo_dev = solo_enc->solo_dev; qc->id = v4l2_ctrl_next(solo_ctrl_classes, qc->id); if (!qc->id) @@ -1522,7 +1522,7 @@ static int solo_g_ctrl(struct file *file, void *priv, { struct solo_enc_fh *fh = priv; struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct solo_dev *solo_dev = solo_enc->solo_dev; switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: @@ -1556,7 +1556,7 @@ static int solo_s_ctrl(struct file *file, void *priv, { struct solo_enc_fh *fh = priv; struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; + struct solo_dev *solo_dev = solo_enc->solo_dev; switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: @@ -1714,7 +1714,7 @@ static const struct v4l2_ioctl_ops solo_enc_ioctl_ops = { }; static struct video_device solo_enc_template = { - .name = SOLO6010_NAME, + .name = SOLO6X10_NAME, .fops = &solo_enc_fops, .ioctl_ops = &solo_enc_ioctl_ops, .minor = -1, @@ -1724,7 +1724,7 @@ static struct video_device solo_enc_template = { .current_norm = V4L2_STD_NTSC_M, }; -static struct solo_enc_dev *solo_enc_alloc(struct solo6010_dev *solo_dev, u8 ch) +static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev, u8 ch) { struct solo_enc_dev *solo_enc; int ret; @@ -1755,7 +1755,7 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo6010_dev *solo_dev, u8 ch) video_set_drvdata(solo_enc->vfd, solo_enc); snprintf(solo_enc->vfd->name, sizeof(solo_enc->vfd->name), - "%s-enc (%i/%i)", SOLO6010_NAME, solo_dev->vfd->num, + "%s-enc (%i/%i)", SOLO6X10_NAME, solo_dev->vfd->num, solo_enc->vfd->num); if (video_nr != -1) @@ -1787,7 +1787,7 @@ static void solo_enc_free(struct solo_enc_dev *solo_enc) kfree(solo_enc); } -int solo_enc_v4l2_init(struct solo6010_dev *solo_dev) +int solo_enc_v4l2_init(struct solo_dev *solo_dev) { int i; @@ -1814,11 +1814,11 @@ int solo_enc_v4l2_init(struct solo6010_dev *solo_dev) return 0; } -void solo_enc_v4l2_exit(struct solo6010_dev *solo_dev) +void solo_enc_v4l2_exit(struct solo_dev *solo_dev) { int i; - solo6010_irq_off(solo_dev, SOLO_IRQ_MOTION); + solo_irq_off(solo_dev, SOLO_IRQ_MOTION); for (i = 0; i < solo_dev->nr_chans; i++) solo_enc_free(solo_dev->v4l2_enc[i]); diff --git a/drivers/staging/solo6x10/v4l2.c b/drivers/staging/solo6x10/v4l2.c index e9d620ab0417..571c3a348d30 100644 --- a/drivers/staging/solo6x10/v4l2.c +++ b/drivers/staging/solo6x10/v4l2.c @@ -40,7 +40,7 @@ /* Simple file handle */ struct solo_filehandle { - struct solo6010_dev *solo_dev; + struct solo_dev *solo_dev; struct videobuf_queue vidq; struct task_struct *kthread; spinlock_t slock; @@ -54,14 +54,14 @@ unsigned video_nr = -1; module_param(video_nr, uint, 0644); MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect (default)"); -static void erase_on(struct solo6010_dev *solo_dev) +static void erase_on(struct solo_dev *solo_dev) { solo_reg_write(solo_dev, SOLO_VO_DISP_ERASE, SOLO_VO_DISP_ERASE_ON); solo_dev->erasing = 1; solo_dev->frame_blank = 0; } -static int erase_off(struct solo6010_dev *solo_dev) +static int erase_off(struct solo_dev *solo_dev) { if (!solo_dev->erasing) return 0; @@ -76,13 +76,13 @@ static int erase_off(struct solo6010_dev *solo_dev) return 1; } -void solo_video_in_isr(struct solo6010_dev *solo_dev) +void solo_video_in_isr(struct solo_dev *solo_dev) { solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_VIDEO_IN); wake_up_interruptible(&solo_dev->disp_thread_wait); } -static void solo_win_setup(struct solo6010_dev *solo_dev, u8 ch, +static void solo_win_setup(struct solo_dev *solo_dev, u8 ch, int sx, int sy, int ex, int ey, int scale) { if (ch >= solo_dev->nr_chans) @@ -100,7 +100,7 @@ static void solo_win_setup(struct solo6010_dev *solo_dev, u8 ch, SOLO_VI_WIN_EY(ey)); } -static int solo_v4l2_ch_ext_4up(struct solo6010_dev *solo_dev, u8 idx, int on) +static int solo_v4l2_ch_ext_4up(struct solo_dev *solo_dev, u8 idx, int on) { u8 ch = idx * 4; @@ -132,7 +132,7 @@ static int solo_v4l2_ch_ext_4up(struct solo6010_dev *solo_dev, u8 idx, int on) return 0; } -static int solo_v4l2_ch_ext_16up(struct solo6010_dev *solo_dev, int on) +static int solo_v4l2_ch_ext_16up(struct solo_dev *solo_dev, int on) { int sy, ysize, hsize, i; @@ -162,7 +162,7 @@ static int solo_v4l2_ch_ext_16up(struct solo6010_dev *solo_dev, int on) return 0; } -static int solo_v4l2_ch(struct solo6010_dev *solo_dev, u8 ch, int on) +static int solo_v4l2_ch(struct solo_dev *solo_dev, u8 ch, int on) { u8 ext_ch; @@ -187,7 +187,7 @@ static int solo_v4l2_ch(struct solo6010_dev *solo_dev, u8 ch, int on) return solo_v4l2_ch_ext_16up(solo_dev, on); } -static int solo_v4l2_set_ch(struct solo6010_dev *solo_dev, u8 ch) +static int solo_v4l2_set_ch(struct solo_dev *solo_dev, u8 ch) { if (ch >= solo_dev->nr_chans + solo_dev->nr_ext) return -EINVAL; @@ -242,7 +242,7 @@ static int disp_push_desc(struct solo_filehandle *fh, dma_addr_t dma_addr, static void solo_fillbuf(struct solo_filehandle *fh, struct videobuf_buffer *vb) { - struct solo6010_dev *solo_dev = fh->solo_dev; + struct solo_dev *solo_dev = fh->solo_dev; struct videobuf_dmabuf *vbuf; unsigned int fdma_addr; int error = 1; @@ -392,7 +392,7 @@ static void solo_thread_try(struct solo_filehandle *fh) static int solo_thread(void *data) { struct solo_filehandle *fh = data; - struct solo6010_dev *solo_dev = fh->solo_dev; + struct solo_dev *solo_dev = fh->solo_dev; DECLARE_WAITQUEUE(wait, current); set_freezable(); @@ -413,7 +413,7 @@ static int solo_thread(void *data) static int solo_start_thread(struct solo_filehandle *fh) { - fh->kthread = kthread_run(solo_thread, fh, SOLO6010_NAME "_disp"); + fh->kthread = kthread_run(solo_thread, fh, SOLO6X10_NAME "_disp"); if (IS_ERR(fh->kthread)) return PTR_ERR(fh->kthread); @@ -433,7 +433,7 @@ static int solo_buf_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) { struct solo_filehandle *fh = vq->priv_data; - struct solo6010_dev *solo_dev = fh->solo_dev; + struct solo_dev *solo_dev = fh->solo_dev; *size = solo_image_size(solo_dev); @@ -447,7 +447,7 @@ static int solo_buf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field) { struct solo_filehandle *fh = vq->priv_data; - struct solo6010_dev *solo_dev = fh->solo_dev; + struct solo_dev *solo_dev = fh->solo_dev; vb->size = solo_image_size(solo_dev); if (vb->baddr != 0 && vb->bsize < vb->size) @@ -478,7 +478,7 @@ static void solo_buf_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) { struct solo_filehandle *fh = vq->priv_data; - struct solo6010_dev *solo_dev = fh->solo_dev; + struct solo_dev *solo_dev = fh->solo_dev; vb->state = VIDEOBUF_QUEUED; list_add_tail(&vb->queue, &fh->vidq_active); @@ -519,7 +519,7 @@ static int solo_v4l2_mmap(struct file *file, struct vm_area_struct *vma) static int solo_v4l2_open(struct file *file) { - struct solo6010_dev *solo_dev = video_drvdata(file); + struct solo_dev *solo_dev = video_drvdata(file); struct solo_filehandle *fh; int ret; @@ -572,20 +572,20 @@ static int solo_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { struct solo_filehandle *fh = priv; - struct solo6010_dev *solo_dev = fh->solo_dev; + struct solo_dev *solo_dev = fh->solo_dev; - strcpy(cap->driver, SOLO6010_NAME); - strcpy(cap->card, "Softlogic 6010"); + strcpy(cap->driver, SOLO6X10_NAME); + strcpy(cap->card, "Softlogic 6x10"); snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI %s", pci_name(solo_dev->pdev)); - cap->version = SOLO6010_VER_NUM; + cap->version = SOLO6X10_VER_NUM; cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; return 0; } -static int solo_enum_ext_input(struct solo6010_dev *solo_dev, +static int solo_enum_ext_input(struct solo_dev *solo_dev, struct v4l2_input *input) { static const char *dispnames_1[] = { "4UP" }; @@ -615,7 +615,7 @@ static int solo_enum_input(struct file *file, void *priv, struct v4l2_input *input) { struct solo_filehandle *fh = priv; - struct solo6010_dev *solo_dev = fh->solo_dev; + struct solo_dev *solo_dev = fh->solo_dev; if (input->index >= solo_dev->nr_chans) { int ret = solo_enum_ext_input(solo_dev, input); @@ -672,7 +672,7 @@ static int solo_try_fmt_cap(struct file *file, void *priv, struct v4l2_format *f) { struct solo_filehandle *fh = priv; - struct solo6010_dev *solo_dev = fh->solo_dev; + struct solo_dev *solo_dev = fh->solo_dev; struct v4l2_pix_format *pix = &f->fmt.pix; int image_size = solo_image_size(solo_dev); @@ -713,7 +713,7 @@ static int solo_get_fmt_cap(struct file *file, void *priv, struct v4l2_format *f) { struct solo_filehandle *fh = priv; - struct solo6010_dev *solo_dev = fh->solo_dev; + struct solo_dev *solo_dev = fh->solo_dev; struct v4l2_pix_format *pix = &f->fmt.pix; pix->width = solo_dev->video_hsize; @@ -819,7 +819,7 @@ static int solo_disp_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { struct solo_filehandle *fh = priv; - struct solo6010_dev *solo_dev = fh->solo_dev; + struct solo_dev *solo_dev = fh->solo_dev; switch (ctrl->id) { case V4L2_CID_MOTION_TRACE: @@ -834,7 +834,7 @@ static int solo_disp_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { struct solo_filehandle *fh = priv; - struct solo6010_dev *solo_dev = fh->solo_dev; + struct solo_dev *solo_dev = fh->solo_dev; switch (ctrl->id) { case V4L2_CID_MOTION_TRACE: @@ -894,7 +894,7 @@ static const struct v4l2_ioctl_ops solo_v4l2_ioctl_ops = { }; static struct video_device solo_v4l2_template = { - .name = SOLO6010_NAME, + .name = SOLO6X10_NAME, .fops = &solo_v4l2_fops, .ioctl_ops = &solo_v4l2_ioctl_ops, .minor = -1, @@ -904,7 +904,7 @@ static struct video_device solo_v4l2_template = { .current_norm = V4L2_STD_NTSC_M, }; -int solo_v4l2_init(struct solo6010_dev *solo_dev) +int solo_v4l2_init(struct solo_dev *solo_dev) { int ret; int i; @@ -928,7 +928,7 @@ int solo_v4l2_init(struct solo6010_dev *solo_dev) video_set_drvdata(solo_dev->vfd, solo_dev); snprintf(solo_dev->vfd->name, sizeof(solo_dev->vfd->name), "%s (%i)", - SOLO6010_NAME, solo_dev->vfd->num); + SOLO6X10_NAME, solo_dev->vfd->num); if (video_nr != -1) video_nr++; @@ -949,14 +949,14 @@ int solo_v4l2_init(struct solo6010_dev *solo_dev) while (erase_off(solo_dev)) ;/* Do nothing */ - solo6010_irq_on(solo_dev, SOLO_IRQ_VIDEO_IN); + solo_irq_on(solo_dev, SOLO_IRQ_VIDEO_IN); return 0; } -void solo_v4l2_exit(struct solo6010_dev *solo_dev) +void solo_v4l2_exit(struct solo_dev *solo_dev) { - solo6010_irq_off(solo_dev, SOLO_IRQ_VIDEO_IN); + solo_irq_off(solo_dev, SOLO_IRQ_VIDEO_IN); if (solo_dev->vfd) { video_unregister_device(solo_dev->vfd); solo_dev->vfd = NULL; -- cgit v1.2.3 From bb29223453061b9b738e3659f7810c1f61165df2 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Thu, 17 Feb 2011 23:29:11 +0200 Subject: staging: xgifb: xgifb_probe() error paths missing framebuffer_release() framebuffer_release() is missing from error paths. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 39 ++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index ee008e5a0cbc..c245de4fafc8 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -2935,6 +2935,8 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, u16 reg16; u8 reg, reg1; u8 CR48, CR38; + int ret; + if (XGIfb_off) return -ENXIO; @@ -2966,8 +2968,10 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, printk("XGIfb: Relocate IO address: %lx [%08lx]\n", (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO); - if (pci_enable_device(pdev)) - return -EIO; + if (pci_enable_device(pdev)) { + ret = -EIO; + goto error; + } XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress); @@ -2976,7 +2980,8 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, if (reg1 != 0xa1) { /*I/O error */ printk("\nXGIfb: I/O error!!!"); - return -EIO; + ret = -EIO; + goto error; } switch (xgi_video_info.chip_id) { @@ -3011,7 +3016,8 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315; break; default: - return -ENODEV; + ret = -ENODEV; + goto error; } printk("XGIfb:chipid = %x\n", xgi_video_info.chip); @@ -3052,7 +3058,8 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, XGIhw_ext.pSR = vmalloc(sizeof(struct XGI_DSReg) * SR_BUFFER_SIZE); if (XGIhw_ext.pSR == NULL) { printk(KERN_ERR "XGIfb: Fatal error: Allocating SRReg space failed.\n"); - return -ENODEV; + ret = -ENODEV; + goto error; } XGIhw_ext.pSR[0].jIdx = XGIhw_ext.pSR[0].jVal = 0xFF; @@ -3060,7 +3067,8 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, if (XGIhw_ext.pCR == NULL) { vfree(XGIhw_ext.pSR); printk(KERN_ERR "XGIfb: Fatal error: Allocating CRReg space failed.\n"); - return -ENODEV; + ret = -ENODEV; + goto error; } XGIhw_ext.pCR[0].jIdx = XGIhw_ext.pCR[0].jVal = 0xFF; @@ -3100,7 +3108,8 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, vfree(XGIhw_ext.pSR); vfree(XGIhw_ext.pCR); printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n"); - return -ENODEV; + ret = -ENODEV; + goto error; } if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) { @@ -3118,7 +3127,8 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n"); vfree(XGIhw_ext.pSR); vfree(XGIhw_ext.pCR); - return -ENODEV; + ret = -ENODEV; + goto error; } if (!request_mem_region(xgi_video_info.mmio_base, XGIfb_mmio_size, "XGIfb MMIO")) { @@ -3126,7 +3136,8 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, release_mem_region(xgi_video_info.video_base, xgi_video_info.video_size); vfree(XGIhw_ext.pSR); vfree(XGIhw_ext.pCR); - return -ENODEV; + ret = -ENODEV; + goto error; } xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress = @@ -3413,8 +3424,10 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, printk(KERN_INFO "XGIfb: Added MTRRs\n"); #endif - if (register_framebuffer(fb_info) < 0) - return -EINVAL; + if (register_framebuffer(fb_info) < 0) { + ret = -EINVAL; + goto error; + } XGIfb_registered = 1; @@ -3426,6 +3439,10 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, dumpVGAReg(); return 0; + +error: + framebuffer_release(fb_info); + return ret; } /*****************************************************/ -- cgit v1.2.3 From 6af8172043ddcebfcfc06a0921a10a858de45106 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Thu, 17 Feb 2011 23:29:12 +0200 Subject: staging: xgifb: fix some memory leaks Some xgifb_probe() error paths are missing proper vfree()s. Move them all into a single place. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index c245de4fafc8..2328926162f2 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -3065,7 +3065,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, XGIhw_ext.pCR = vmalloc(sizeof(struct XGI_DSReg) * CR_BUFFER_SIZE); if (XGIhw_ext.pCR == NULL) { - vfree(XGIhw_ext.pSR); printk(KERN_ERR "XGIfb: Fatal error: Allocating CRReg space failed.\n"); ret = -ENODEV; goto error; @@ -3105,8 +3104,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, } #endif if (XGIfb_get_dram_size()) { - vfree(XGIhw_ext.pSR); - vfree(XGIhw_ext.pCR); printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n"); ret = -ENODEV; goto error; @@ -3125,8 +3122,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, printk("unable request memory size %x", xgi_video_info.video_size); printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n"); printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n"); - vfree(XGIhw_ext.pSR); - vfree(XGIhw_ext.pCR); ret = -ENODEV; goto error; } @@ -3134,8 +3129,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, if (!request_mem_region(xgi_video_info.mmio_base, XGIfb_mmio_size, "XGIfb MMIO")) { printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n"); release_mem_region(xgi_video_info.video_base, xgi_video_info.video_size); - vfree(XGIhw_ext.pSR); - vfree(XGIhw_ext.pCR); ret = -ENODEV; goto error; } @@ -3441,6 +3434,8 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, return 0; error: + vfree(XGIhw_ext.pSR); + vfree(XGIhw_ext.pCR); framebuffer_release(fb_info); return ret; } -- cgit v1.2.3 From 0f07d945f490d1ba8ace3b943b2a2d13daf4c49a Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Thu, 17 Feb 2011 23:29:13 +0200 Subject: staging: xgifb: copy PCI ROM properly Use proper helper functions to copy the PCI ROM. Also use dynamic memory allocation. The original code mapped incorrect amount of memory and will crash on some platforms. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 61 ++++++++++++------------------------- 1 file changed, 19 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 2328926162f2..90dca40c4494 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -54,6 +54,8 @@ int XGIfb_accel = 0; #define GPIOG_READ (1<<1) int XGIfb_GetXG21DefaultLVDSModeIdx(void); +#define XGIFB_ROM_SIZE 65536 + /* -------------------- Macro definitions ---------------------------- */ #undef XGIFBDEBUG @@ -2881,52 +2883,26 @@ XGIINITSTATIC int __init XGIfb_setup(char *options) return 0; } -static unsigned char VBIOS_BUF[65535]; - -static unsigned char *attempt_map_rom(struct pci_dev *dev, void *copy_address) +static unsigned char *xgifb_copy_rom(struct pci_dev *dev) { - u32 rom_size = 0; - u32 rom_address = 0; - int j; - - /* Get the size of the expansion rom */ - pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0xFFFFFFFF); - pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_size); - if ((rom_size & 0x01) == 0) { - printk("No ROM\n"); - return NULL; - } + void __iomem *rom_address; + unsigned char *rom_copy; + size_t rom_size; - rom_size &= 0xFFFFF800; - rom_size = (~rom_size) + 1; - - rom_address = pci_resource_start(dev, 0); - if (rom_address == 0 || rom_address == 0xFFFFFFF0) { - printk("No suitable rom address found\n"); + rom_address = pci_map_rom(dev, &rom_size); + if (rom_address == NULL) return NULL; - } - printk("ROM Size is %dK, Address is %x\n", rom_size / 1024, rom_address); + rom_copy = vzalloc(XGIFB_ROM_SIZE); + if (rom_copy == NULL) + goto done; - /* Map ROM */ - pci_write_config_dword(dev, PCI_ROM_ADDRESS, rom_address - | PCI_ROM_ADDRESS_ENABLE); + rom_size = min_t(size_t, rom_size, XGIFB_ROM_SIZE); + memcpy_fromio(rom_copy, rom_address, rom_size); - /* memcpy(copy_address, rom_address, rom_size); */ - { - unsigned char *virt_addr = ioremap(rom_address, 0x8000000); - - unsigned char *from = (unsigned char *) virt_addr; - unsigned char *to = (unsigned char *) copy_address; - for (j = 0; j < 65536 /*rom_size*/; j++) - *to++ = *from++; - } - - pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0); - - printk("Copy is done\n"); - - return copy_address; +done: + pci_unmap_rom(dev, rom_address); + return rom_copy; } static int __devinit xgifb_probe(struct pci_dev *pdev, @@ -3039,8 +3015,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, XGIhw_ext.pDevice = NULL; if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) { - XGIhw_ext.pjVirtualRomBase = attempt_map_rom(pdev, VBIOS_BUF); - + XGIhw_ext.pjVirtualRomBase = xgifb_copy_rom(pdev); if (XGIhw_ext.pjVirtualRomBase) printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n", XGIhw_ext.pjVirtualRomBase); else @@ -3434,6 +3409,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, return 0; error: + vfree(XGIhw_ext.pjVirtualRomBase); vfree(XGIhw_ext.pSR); vfree(XGIhw_ext.pCR); framebuffer_release(fb_info); @@ -3449,6 +3425,7 @@ static void __devexit xgifb_remove(struct pci_dev *pdev) /* Unregister the framebuffer */ /* if (xgi_video_info.registered) { */ unregister_framebuffer(fb_info); + vfree(XGIhw_ext.pjVirtualRomBase); framebuffer_release(fb_info); /* } */ -- cgit v1.2.3 From d80aaa01aec2d9b5e833fb9a26b83784e106a379 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Thu, 17 Feb 2011 23:29:14 +0200 Subject: staging: xgifb: replace XGINew_LCD_Wait_Time() with mdelay() XGINew_LCD_Wait_Time() is implemented using the I/O port 0x61, which is X86-specific and will fail on other platforms. The code did not make any sense, but I guess the intention has been to provide a function where the unit for the delay is milliseconds. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 47 ++++++++------------------------------ 1 file changed, 10 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index e19b932492e1..fa2cf9625598 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1,5 +1,6 @@ #include +#include #include #include #include "XGIfb.h" @@ -161,7 +162,6 @@ void XGI_GetRAMDAC2DATA(unsigned short ModeNo, unsigned short ModeIdIndex, u void XGI_UnLockCRT2(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); void XGI_LockCRT2(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); void XGINew_EnableCRT2(struct vb_device_info *pVBInfo); -void XGINew_LCD_Wait_Time(unsigned char DelayTime, struct vb_device_info *pVBInfo); void XGI_LongWait(struct vb_device_info *pVBInfo); void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1, @@ -3788,7 +3788,7 @@ void XGI_SenseCRT1(struct vb_device_info *pVBInfo) XGI_VBLongWait(pVBInfo); XGI_VBLongWait(pVBInfo); - XGINew_LCD_Wait_Time(0x01, pVBInfo); + mdelay(1); XGI_WaitDisply(pVBInfo); temp = XGINew_GetReg2(pVBInfo->P3c2); @@ -6716,16 +6716,16 @@ void XGI_SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBInfo) index = XGI_GetLCDCapPtr(pVBInfo); if (tempbl == 1) - XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S1, pVBInfo); + mdelay(pVBInfo->LCDCapList[index].PSC_S1); if (tempbl == 2) - XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S2, pVBInfo); + mdelay(pVBInfo->LCDCapList[index].PSC_S2); if (tempbl == 3) - XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S3, pVBInfo); + mdelay(pVBInfo->LCDCapList[index].PSC_S3); if (tempbl == 4) - XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S4, pVBInfo); + mdelay(pVBInfo->LCDCapList[index].PSC_S4); } /* --------------------------------------------------------------------- */ @@ -6897,20 +6897,16 @@ void XGI_XG21SetPanelDelay(unsigned short tempbl, index = XGI_GetLVDSOEMTableIndex(pVBInfo); if (tempbl == 1) - XGINew_LCD_Wait_Time(pVBInfo->XG21_LVDSCapList[index].PSC_S1, - pVBInfo); + mdelay(pVBInfo->XG21_LVDSCapList[index].PSC_S1); if (tempbl == 2) - XGINew_LCD_Wait_Time(pVBInfo->XG21_LVDSCapList[index].PSC_S2, - pVBInfo); + mdelay(pVBInfo->XG21_LVDSCapList[index].PSC_S2); if (tempbl == 3) - XGINew_LCD_Wait_Time(pVBInfo->XG21_LVDSCapList[index].PSC_S3, - pVBInfo); + mdelay(pVBInfo->XG21_LVDSCapList[index].PSC_S3); if (tempbl == 4) - XGINew_LCD_Wait_Time(pVBInfo->XG21_LVDSCapList[index].PSC_S4, - pVBInfo); + mdelay(pVBInfo->XG21_LVDSCapList[index].PSC_S4); } unsigned char XGI_XG21CheckLVDSMode(unsigned short ModeNo, @@ -8637,29 +8633,6 @@ void XGINew_EnableCRT2(struct vb_device_info *pVBInfo) XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1E, 0xFF, 0x20); } -void XGINew_LCD_Wait_Time(unsigned char DelayTime, - struct vb_device_info *pVBInfo) -{ - unsigned short i, j; - - unsigned long temp, flag; - - flag = 0; - /* printk("XGINew_LCD_Wait_Time"); */ - /* return; */ - for (i = 0; i < DelayTime; i++) { - for (j = 0; j < 66; j++) { - temp = XGINew_GetReg3(0x61); - /* temp &= 0x10000000; */ - temp &= 0x10; - if (temp == flag) - continue; - - flag = temp; - } - } -} - unsigned char XGI_BridgeIsOn(struct vb_device_info *pVBInfo) { unsigned short flag; -- cgit v1.2.3 From 5c0ef2ac365ced91b819917e56dcd6795b5bef5a Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Thu, 17 Feb 2011 23:29:15 +0200 Subject: staging: xgifb: release and unmap I/O memory Release and unmap memory on probe error paths and when the module is removed. The patch enables unloading and reloading the xgifb module. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 90dca40c4494..f69ff574767e 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -3103,9 +3103,8 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, if (!request_mem_region(xgi_video_info.mmio_base, XGIfb_mmio_size, "XGIfb MMIO")) { printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n"); - release_mem_region(xgi_video_info.video_base, xgi_video_info.video_size); ret = -ENODEV; - goto error; + goto error_0; } xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress = @@ -3394,7 +3393,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, if (register_framebuffer(fb_info) < 0) { ret = -EINVAL; - goto error; + goto error_1; } XGIfb_registered = 1; @@ -3408,6 +3407,13 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, return 0; +error_1: + iounmap(xgi_video_info.mmio_vbase); + iounmap(xgi_video_info.video_vbase); + release_mem_region(xgi_video_info.mmio_base, XGIfb_mmio_size); +error_0: + release_mem_region(xgi_video_info.video_base, + xgi_video_info.video_size); error: vfree(XGIhw_ext.pjVirtualRomBase); vfree(XGIhw_ext.pSR); @@ -3425,6 +3431,11 @@ static void __devexit xgifb_remove(struct pci_dev *pdev) /* Unregister the framebuffer */ /* if (xgi_video_info.registered) { */ unregister_framebuffer(fb_info); + iounmap(xgi_video_info.mmio_vbase); + iounmap(xgi_video_info.video_vbase); + release_mem_region(xgi_video_info.mmio_base, XGIfb_mmio_size); + release_mem_region(xgi_video_info.video_base, + xgi_video_info.video_size); vfree(XGIhw_ext.pjVirtualRomBase); framebuffer_release(fb_info); /* } */ -- cgit v1.2.3 From 45dcfaf150c4adb50149078205ad3e60bd7d789d Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Thu, 17 Feb 2011 23:29:16 +0200 Subject: staging: xgifb: clean up xgifb_remove() Delete redudant comments, blank lines and a redundant semicolon. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index f69ff574767e..6e86830cc52d 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -3428,8 +3428,6 @@ error: static void __devexit xgifb_remove(struct pci_dev *pdev) { - /* Unregister the framebuffer */ - /* if (xgi_video_info.registered) { */ unregister_framebuffer(fb_info); iounmap(xgi_video_info.mmio_vbase); iounmap(xgi_video_info.video_vbase); @@ -3438,11 +3436,8 @@ static void __devexit xgifb_remove(struct pci_dev *pdev) xgi_video_info.video_size); vfree(XGIhw_ext.pjVirtualRomBase); framebuffer_release(fb_info); - /* } */ - pci_set_drvdata(pdev, NULL); - -}; +} static struct pci_driver xgifb_driver = { .name = "xgifb", -- cgit v1.2.3 From 1b3909e5c57032d9e4d9cf6a56c9f7c46149409d Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Thu, 17 Feb 2011 23:29:17 +0200 Subject: staging: xgifb: eliminate a global variable Move the XGIfb_mmio_size global variable into the video_info struct. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main.h | 1 - drivers/staging/xgifb/XGI_main_26.c | 18 +++++++++++------- drivers/staging/xgifb/XGIfb.h | 1 + 3 files changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index 72448e88fd8b..e8e2bfe75573 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -375,7 +375,6 @@ static struct xgi_hw_device_info XGIhw_ext; static struct vb_device_info XGI_Pr; /* card parameters */ -static unsigned long XGIfb_mmio_size = 0; static u8 XGIfb_caps = 0; typedef enum _XGI_CMDTYPE { diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 6e86830cc52d..7f821ae20cf2 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1723,7 +1723,7 @@ static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con, fix->ywrapstep = 0; fix->line_length = xgi_video_info.video_linelength; fix->mmio_start = xgi_video_info.mmio_base; - fix->mmio_len = XGIfb_mmio_size; + fix->mmio_len = xgi_video_info.mmio_size; if (xgi_video_info.chip >= XG40) fix->accel = FB_ACCEL_XGI_XABRE; else @@ -2937,7 +2937,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgi_video_info.video_base = pci_resource_start(pdev, 0); xgi_video_info.mmio_base = pci_resource_start(pdev, 1); - XGIfb_mmio_size = pci_resource_len(pdev, 1); + xgi_video_info.mmio_size = pci_resource_len(pdev, 1); xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30; XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base; /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */ @@ -3101,7 +3101,9 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, goto error; } - if (!request_mem_region(xgi_video_info.mmio_base, XGIfb_mmio_size, "XGIfb MMIO")) { + if (!request_mem_region(xgi_video_info.mmio_base, + xgi_video_info.mmio_size, + "XGIfb MMIO")) { printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n"); ret = -ENODEV; goto error_0; @@ -3109,13 +3111,15 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, xgi_video_info.video_size); - xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base, XGIfb_mmio_size); + xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base, + xgi_video_info.mmio_size); printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n", xgi_video_info.video_base, xgi_video_info.video_vbase, xgi_video_info.video_size / 1024); printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n", - xgi_video_info.mmio_base, xgi_video_info.mmio_vbase, XGIfb_mmio_size / 1024); + xgi_video_info.mmio_base, xgi_video_info.mmio_vbase, + xgi_video_info.mmio_size / 1024); printk("XGIfb: XGIInitNew() ..."); if (XGIInitNew(&XGIhw_ext)) printk("OK\n"); @@ -3410,7 +3414,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, error_1: iounmap(xgi_video_info.mmio_vbase); iounmap(xgi_video_info.video_vbase); - release_mem_region(xgi_video_info.mmio_base, XGIfb_mmio_size); + release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size); error_0: release_mem_region(xgi_video_info.video_base, xgi_video_info.video_size); @@ -3431,7 +3435,7 @@ static void __devexit xgifb_remove(struct pci_dev *pdev) unregister_framebuffer(fb_info); iounmap(xgi_video_info.mmio_vbase); iounmap(xgi_video_info.video_vbase); - release_mem_region(xgi_video_info.mmio_base, XGIfb_mmio_size); + release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size); release_mem_region(xgi_video_info.video_base, xgi_video_info.video_size); vfree(XGIhw_ext.pjVirtualRomBase); diff --git a/drivers/staging/xgifb/XGIfb.h b/drivers/staging/xgifb/XGIfb.h index ef86a64d6996..bb4640abda98 100644 --- a/drivers/staging/xgifb/XGIfb.h +++ b/drivers/staging/xgifb/XGIfb.h @@ -161,6 +161,7 @@ struct video_info{ unsigned long video_base; char * video_vbase; unsigned long mmio_base; + unsigned long mmio_size; char * mmio_vbase; unsigned long vga_base; unsigned long mtrr; -- cgit v1.2.3 From 72075789ea6eba8b67516c5fc7e5c12fa1dac1c3 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 10 Feb 2011 14:55:22 +0200 Subject: staging/easycap: add first level indetnation for easycap_low.c Signed-off-by: Tomas Winkler Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_low.c | 1302 ++++++++++++++++----------------- 1 file changed, 641 insertions(+), 661 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index a345a1bc69d0..7b2de10bc68a 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -326,136 +326,132 @@ static int regset(struct usb_device *pusb_device, u16 index, u16 value) /*****************************************************************************/ /****************************************************************************/ -int -confirm_resolution(struct usb_device *p) +int confirm_resolution(struct usb_device *p) { -u8 get0, get1, get2, get3, get4, get5, get6, get7; - -if (NULL == p) - return -ENODEV; -GET(p, 0x0110, &get0); -GET(p, 0x0111, &get1); -GET(p, 0x0112, &get2); -GET(p, 0x0113, &get3); -GET(p, 0x0114, &get4); -GET(p, 0x0115, &get5); -GET(p, 0x0116, &get6); -GET(p, 0x0117, &get7); -JOT(8, "0x%03X, 0x%03X, " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X\n", - get0, get1, get2, get3, get4, get5, get6, get7); -JOT(8, "....cf PAL_720x526: " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X\n", - 0x000, 0x000, 0x001, 0x000, 0x5A0, 0x005, 0x121, 0x001); -JOT(8, "....cf PAL_704x526: " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X\n", - 0x004, 0x000, 0x001, 0x000, 0x584, 0x005, 0x121, 0x001); -JOT(8, "....cf VGA_640x480: " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X, " - "0x%03X, 0x%03X\n", - 0x008, 0x000, 0x020, 0x000, 0x508, 0x005, 0x110, 0x001); -return 0; + u8 get0, get1, get2, get3, get4, get5, get6, get7; + + if (NULL == p) + return -ENODEV; + GET(p, 0x0110, &get0); + GET(p, 0x0111, &get1); + GET(p, 0x0112, &get2); + GET(p, 0x0113, &get3); + GET(p, 0x0114, &get4); + GET(p, 0x0115, &get5); + GET(p, 0x0116, &get6); + GET(p, 0x0117, &get7); + JOT(8, "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X\n", + get0, get1, get2, get3, get4, get5, get6, get7); + JOT(8, "....cf PAL_720x526: " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X\n", + 0x000, 0x000, 0x001, 0x000, 0x5A0, 0x005, 0x121, 0x001); + JOT(8, "....cf PAL_704x526: " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X\n", + 0x004, 0x000, 0x001, 0x000, 0x584, 0x005, 0x121, 0x001); + JOT(8, "....cf VGA_640x480: " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X\n", + 0x008, 0x000, 0x020, 0x000, 0x508, 0x005, 0x110, 0x001); + return 0; } /****************************************************************************/ -int -confirm_stream(struct usb_device *p) +int confirm_stream(struct usb_device *p) { -u16 get2; -u8 igot; - -if (NULL == p) - return -ENODEV; -GET(p, 0x0100, &igot); get2 = 0x80 & igot; -if (0x80 == get2) - JOT(8, "confirm_stream: OK\n"); -else - JOT(8, "confirm_stream: STUCK\n"); -return 0; + u16 get2; + u8 igot; + + if (NULL == p) + return -ENODEV; + GET(p, 0x0100, &igot); get2 = 0x80 & igot; + if (0x80 == get2) + JOT(8, "confirm_stream: OK\n"); + else + JOT(8, "confirm_stream: STUCK\n"); + return 0; } /****************************************************************************/ -int -setup_stk(struct usb_device *p, bool ntsc) +int setup_stk(struct usb_device *p, bool ntsc) { -int i0; - -if (NULL == p) - return -ENODEV; -i0 = 0; -if (true == ntsc) { - while (0xFFF != stk1160configNTSC[i0].reg) { - SET(p, stk1160configNTSC[i0].reg, stk1160configNTSC[i0].set); - i0++; - } -} else { - while (0xFFF != stk1160configPAL[i0].reg) { - SET(p, stk1160configPAL[i0].reg, stk1160configPAL[i0].set); - i0++; + int i0; + + if (NULL == p) + return -ENODEV; + i0 = 0; + if (true == ntsc) { + while (0xFFF != stk1160configNTSC[i0].reg) { + SET(p, stk1160configNTSC[i0].reg, + stk1160configNTSC[i0].set); + i0++; + } + } else { + while (0xFFF != stk1160configPAL[i0].reg) { + SET(p, stk1160configPAL[i0].reg, + stk1160configPAL[i0].set); + i0++; + } } -} -write_300(p); + write_300(p); -return 0; + return 0; } /****************************************************************************/ -int -setup_saa(struct usb_device *p, bool ntsc) +int setup_saa(struct usb_device *p, bool ntsc) { -int i0, ir; - -if (NULL == p) - return -ENODEV; -i0 = 0; -if (true == ntsc) { - while (0xFF != saa7113configNTSC[i0].reg) { - ir = write_saa(p, saa7113configNTSC[i0].reg, - saa7113configNTSC[i0].set); - i0++; - } -} else { - while (0xFF != saa7113configPAL[i0].reg) { - ir = write_saa(p, saa7113configPAL[i0].reg, - saa7113configPAL[i0].set); - i0++; + int i0, ir; + + if (NULL == p) + return -ENODEV; + i0 = 0; + if (true == ntsc) { + while (0xFF != saa7113configNTSC[i0].reg) { + ir = write_saa(p, saa7113configNTSC[i0].reg, + saa7113configNTSC[i0].set); + i0++; + } + } else { + while (0xFF != saa7113configPAL[i0].reg) { + ir = write_saa(p, saa7113configPAL[i0].reg, + saa7113configPAL[i0].set); + i0++; + } } -} -return 0; + return 0; } /****************************************************************************/ -int -write_000(struct usb_device *p, u16 set2, u16 set0) +int write_000(struct usb_device *p, u16 set2, u16 set0) { -u8 igot0, igot2; - -if (NULL == p) - return -ENODEV; -GET(p, 0x0002, &igot2); -GET(p, 0x0000, &igot0); -SET(p, 0x0002, set2); -SET(p, 0x0000, set0); -return 0; + u8 igot0, igot2; + + if (NULL == p) + return -ENODEV; + GET(p, 0x0002, &igot2); + GET(p, 0x0000, &igot0); + SET(p, 0x0002, set2); + SET(p, 0x0000, set0); + return 0; } /****************************************************************************/ -int -write_saa(struct usb_device *p, u16 reg0, u16 set0) +int write_saa(struct usb_device *p, u16 reg0, u16 set0) { -if (NULL == p) - return -ENODEV; -SET(p, 0x200, 0x00); -SET(p, 0x204, reg0); -SET(p, 0x205, set0); -SET(p, 0x200, 0x01); -return wait_i2c(p); + if (NULL == p) + return -ENODEV; + SET(p, 0x200, 0x00); + SET(p, 0x204, reg0); + SET(p, 0x205, set0); + SET(p, 0x200, 0x01); + return wait_i2c(p); } /****************************************************************************/ /*--------------------------------------------------------------------------*/ @@ -470,30 +466,30 @@ return wait_i2c(p); int write_vt(struct usb_device *p, u16 reg0, u16 set0) { -u8 igot; -u16 got502, got503; -u16 set502, set503; + u8 igot; + u16 got502, got503; + u16 set502, set503; -if (NULL == p) - return -ENODEV; -SET(p, 0x0504, reg0); -SET(p, 0x0500, 0x008B); + if (NULL == p) + return -ENODEV; + SET(p, 0x0504, reg0); + SET(p, 0x0500, 0x008B); -GET(p, 0x0502, &igot); got502 = (0xFF & igot); -GET(p, 0x0503, &igot); got503 = (0xFF & igot); + GET(p, 0x0502, &igot); got502 = (0xFF & igot); + GET(p, 0x0503, &igot); got503 = (0xFF & igot); -JOT(16, "write_vt(., 0x%04X, 0x%04X): was 0x%04X\n", - reg0, set0, ((got503 << 8) | got502)); + JOT(16, "write_vt(., 0x%04X, 0x%04X): was 0x%04X\n", + reg0, set0, ((got503 << 8) | got502)); -set502 = (0x00FF & set0); -set503 = ((0xFF00 & set0) >> 8); + set502 = (0x00FF & set0); + set503 = ((0xFF00 & set0) >> 8); -SET(p, 0x0504, reg0); -SET(p, 0x0502, set502); -SET(p, 0x0503, set503); -SET(p, 0x0500, 0x008C); + SET(p, 0x0504, reg0); + SET(p, 0x0502, set502); + SET(p, 0x0503, set503); + SET(p, 0x0500, 0x008C); -return 0; + return 0; } /****************************************************************************/ /*--------------------------------------------------------------------------*/ @@ -505,23 +501,23 @@ return 0; * REGISTER 504: TARGET ADDRESS ON VT1612A */ /*--------------------------------------------------------------------------*/ -int -read_vt(struct usb_device *p, u16 reg0) +int read_vt(struct usb_device *p, u16 reg0) { -u8 igot; -u16 got502, got503; + u8 igot; + u16 got502, got503; -if (NULL == p) - return -ENODEV; -SET(p, 0x0504, reg0); -SET(p, 0x0500, 0x008B); + if (NULL == p) + return -ENODEV; + SET(p, 0x0504, reg0); + SET(p, 0x0500, 0x008B); -GET(p, 0x0502, &igot); got502 = (0xFF & igot); -GET(p, 0x0503, &igot); got503 = (0xFF & igot); + GET(p, 0x0502, &igot); got502 = (0xFF & igot); + GET(p, 0x0503, &igot); got503 = (0xFF & igot); -JOT(16, "read_vt(., 0x%04X): has 0x%04X\n", reg0, ((got503 << 8) | got502)); + JOT(16, "read_vt(., 0x%04X): has 0x%04X\n", + reg0, ((got503 << 8) | got502)); -return (got503 << 8) | got502; + return (got503 << 8) | got502; } /****************************************************************************/ /*--------------------------------------------------------------------------*/ @@ -529,18 +525,17 @@ return (got503 << 8) | got502; * THESE APPEAR TO HAVE NO EFFECT ON EITHER VIDEO OR AUDIO. */ /*--------------------------------------------------------------------------*/ -int -write_300(struct usb_device *p) +int write_300(struct usb_device *p) { -if (NULL == p) - return -ENODEV; -SET(p, 0x300, 0x0012); -SET(p, 0x350, 0x002D); -SET(p, 0x351, 0x0001); -SET(p, 0x352, 0x0000); -SET(p, 0x353, 0x0000); -SET(p, 0x300, 0x0080); -return 0; + if (NULL == p) + return -ENODEV; + SET(p, 0x300, 0x0012); + SET(p, 0x350, 0x002D); + SET(p, 0x351, 0x0001); + SET(p, 0x352, 0x0000); + SET(p, 0x353, 0x0000); + SET(p, 0x300, 0x0080); + return 0; } /****************************************************************************/ /*--------------------------------------------------------------------------*/ @@ -549,75 +544,72 @@ return 0; * REGISTER 0x0F, WHICH IS INVOLVED IN CHROMINANCE AUTOMATIC GAIN CONTROL. */ /*--------------------------------------------------------------------------*/ -int -check_saa(struct usb_device *p, bool ntsc) +int check_saa(struct usb_device *p, bool ntsc) { -int i0, ir, rc; - -if (NULL == p) - return -ENODEV; -i0 = 0; -rc = 0; -if (true == ntsc) { - while (0xFF != saa7113configNTSC[i0].reg) { - if (0x0F == saa7113configNTSC[i0].reg) { - i0++; - continue; - } + int i0, ir, rc; - ir = read_saa(p, saa7113configNTSC[i0].reg); - if (ir != saa7113configNTSC[i0].set) { - SAY("SAA register 0x%02X has 0x%02X, " + if (NULL == p) + return -ENODEV; + i0 = 0; + rc = 0; + if (true == ntsc) { + while (0xFF != saa7113configNTSC[i0].reg) { + if (0x0F == saa7113configNTSC[i0].reg) { + i0++; + continue; + } + + ir = read_saa(p, saa7113configNTSC[i0].reg); + if (ir != saa7113configNTSC[i0].set) { + SAY("SAA register 0x%02X has 0x%02X, " "expected 0x%02X\n", saa7113configNTSC[i0].reg, ir, saa7113configNTSC[i0].set); - rc--; - } - i0++; - } -} else { - while (0xFF != saa7113configPAL[i0].reg) { - if (0x0F == saa7113configPAL[i0].reg) { + rc--; + } i0++; - continue; } + } else { + while (0xFF != saa7113configPAL[i0].reg) { + if (0x0F == saa7113configPAL[i0].reg) { + i0++; + continue; + } - ir = read_saa(p, saa7113configPAL[i0].reg); - if (ir != saa7113configPAL[i0].set) { - SAY("SAA register 0x%02X has 0x%02X, " + ir = read_saa(p, saa7113configPAL[i0].reg); + if (ir != saa7113configPAL[i0].set) { + SAY("SAA register 0x%02X has 0x%02X, " "expected 0x%02X\n", saa7113configPAL[i0].reg, ir, saa7113configPAL[i0].set); - rc--; + rc--; + } + i0++; } - i0++; } -} -if (-8 > rc) - return rc; -else - return 0; + if (-8 > rc) + return rc; + else + return 0; } /****************************************************************************/ -int -merit_saa(struct usb_device *p) +int merit_saa(struct usb_device *p) { -int rc; - -if (NULL == p) - return -ENODEV; -rc = read_saa(p, 0x1F); -if ((0 > rc) || (0x02 & rc)) - return 1 ; -else - return 0; + int rc; + + if (NULL == p) + return -ENODEV; + rc = read_saa(p, 0x1F); + if ((0 > rc) || (0x02 & rc)) + return 1 ; + else + return 0; } /****************************************************************************/ -int -ready_saa(struct usb_device *p) +int ready_saa(struct usb_device *p) { -int j, rc, rate; -const int max = 5, marktime = PATIENCE/5; + int j, rc, rate; + const int max = 5, marktime = PATIENCE/5; /*--------------------------------------------------------------------------*/ /* * RETURNS 0 FOR INTERLACED 50 Hz @@ -626,38 +618,38 @@ const int max = 5, marktime = PATIENCE/5; * 3 FOR NON-INTERLACED 60 Hz */ /*--------------------------------------------------------------------------*/ -if (NULL == p) - return -ENODEV; -j = 0; -while (max > j) { - rc = read_saa(p, 0x1F); - if (0 <= rc) { - if (0 == (0x40 & rc)) - break; - if (1 == (0x01 & rc)) - break; - } - msleep(marktime); - j++; -} -if (max == j) - return -1; -else { - if (0x20 & rc) { - rate = 2; - JOT(8, "hardware detects 60 Hz\n"); - } else { - rate = 0; - JOT(8, "hardware detects 50 Hz\n"); + if (NULL == p) + return -ENODEV; + j = 0; + while (max > j) { + rc = read_saa(p, 0x1F); + if (0 <= rc) { + if (0 == (0x40 & rc)) + break; + if (1 == (0x01 & rc)) + break; + } + msleep(marktime); + j++; } - if (0x80 & rc) - JOT(8, "hardware detects interlacing\n"); + if (max == j) + return -1; else { - rate++; - JOT(8, "hardware detects no interlacing\n"); + if (0x20 & rc) { + rate = 2; + JOT(8, "hardware detects 60 Hz\n"); + } else { + rate = 0; + JOT(8, "hardware detects 50 Hz\n"); + } + if (0x80 & rc) + JOT(8, "hardware detects interlacing\n"); + else { + rate++; + JOT(8, "hardware detects no interlacing\n"); + } } -} -return 0; + return 0; } /****************************************************************************/ /*--------------------------------------------------------------------------*/ @@ -667,106 +659,101 @@ return 0; * REGISTER 0x100: ACCEPT ALSO (0x80 | stk1160config....[.].set) */ /*--------------------------------------------------------------------------*/ -int -check_stk(struct usb_device *p, bool ntsc) +int check_stk(struct usb_device *p, bool ntsc) { -int i0, ir; - -if (NULL == p) - return -ENODEV; -i0 = 0; -if (true == ntsc) { - while (0xFFF != stk1160configNTSC[i0].reg) { - if (0x000 == stk1160configNTSC[i0].reg) { - i0++; continue; - } - if (0x002 == stk1160configNTSC[i0].reg) { - i0++; continue; - } - ir = read_stk(p, stk1160configNTSC[i0].reg); - if (0x100 == stk1160configNTSC[i0].reg) { - if ((ir != (0xFF & stk1160configNTSC[i0].set)) && - (ir != (0x80 | (0xFF & - stk1160configNTSC[i0].set))) && - (0xFFFF != - stk1160configNTSC[i0].set)) { - SAY("STK register 0x%03X has 0x%02X, " + int i0, ir; + + if (NULL == p) + return -ENODEV; + i0 = 0; + if (true == ntsc) { + while (0xFFF != stk1160configNTSC[i0].reg) { + if (0x000 == stk1160configNTSC[i0].reg) { + i0++; continue; + } + if (0x002 == stk1160configNTSC[i0].reg) { + i0++; continue; + } + ir = read_stk(p, stk1160configNTSC[i0].reg); + if (0x100 == stk1160configNTSC[i0].reg) { + if ((ir != (0xFF & stk1160configNTSC[i0].set)) && + (ir != (0x80 | (0xFF & stk1160configNTSC[i0].set))) && + (0xFFFF != stk1160configNTSC[i0].set)) { + SAY("STK register 0x%03X has 0x%02X, " "expected 0x%02X\n", stk1160configNTSC[i0].reg, ir, stk1160configNTSC[i0].set); + } + i0++; continue; } - i0++; continue; - } - if ((ir != (0xFF & stk1160configNTSC[i0].set)) && - (0xFFFF != stk1160configNTSC[i0].set)) { - SAY("STK register 0x%03X has 0x%02X, " + if ((ir != (0xFF & stk1160configNTSC[i0].set)) && + (0xFFFF != stk1160configNTSC[i0].set)) { + SAY("STK register 0x%03X has 0x%02X, " "expected 0x%02X\n", stk1160configNTSC[i0].reg, ir, stk1160configNTSC[i0].set); + } + i0++; } - i0++; - } -} else { - while (0xFFF != stk1160configPAL[i0].reg) { - if (0x000 == stk1160configPAL[i0].reg) { - i0++; continue; - } - if (0x002 == stk1160configPAL[i0].reg) { - i0++; continue; - } - ir = read_stk(p, stk1160configPAL[i0].reg); - if (0x100 == stk1160configPAL[i0].reg) { - if ((ir != (0xFF & stk1160configPAL[i0].set)) && - (ir != (0x80 | (0xFF & - stk1160configPAL[i0].set))) && - (0xFFFF != - stk1160configPAL[i0].set)) { - SAY("STK register 0x%03X has 0x%02X, " + } else { + while (0xFFF != stk1160configPAL[i0].reg) { + if (0x000 == stk1160configPAL[i0].reg) { + i0++; continue; + } + if (0x002 == stk1160configPAL[i0].reg) { + i0++; continue; + } + ir = read_stk(p, stk1160configPAL[i0].reg); + if (0x100 == stk1160configPAL[i0].reg) { + if ((ir != (0xFF & stk1160configPAL[i0].set)) && + (ir != (0x80 | (0xFF & + stk1160configPAL[i0].set))) && + (0xFFFF != + stk1160configPAL[i0].set)) { + SAY("STK register 0x%03X has 0x%02X, " "expected 0x%02X\n", stk1160configPAL[i0].reg, ir, stk1160configPAL[i0].set); + } + i0++; continue; } - i0++; continue; - } - if ((ir != (0xFF & stk1160configPAL[i0].set)) && - (0xFFFF != stk1160configPAL[i0].set)) { - SAY("STK register 0x%03X has 0x%02X, " + if ((ir != (0xFF & stk1160configPAL[i0].set)) && + (0xFFFF != stk1160configPAL[i0].set)) { + SAY("STK register 0x%03X has 0x%02X, " "expected 0x%02X\n", stk1160configPAL[i0].reg, ir, stk1160configPAL[i0].set); + } + i0++; } - i0++; } -} -return 0; + return 0; } /****************************************************************************/ -int -read_saa(struct usb_device *p, u16 reg0) +int read_saa(struct usb_device *p, u16 reg0) { -u8 igot; + u8 igot; -if (NULL == p) - return -ENODEV; -SET(p, 0x208, reg0); -SET(p, 0x200, 0x20); -if (0 != wait_i2c(p)) - return -1; -igot = 0; -GET(p, 0x0209, &igot); -return igot; + if (NULL == p) + return -ENODEV; + SET(p, 0x208, reg0); + SET(p, 0x200, 0x20); + if (0 != wait_i2c(p)) + return -1; + igot = 0; + GET(p, 0x0209, &igot); + return igot; } /****************************************************************************/ -int -read_stk(struct usb_device *p, u32 reg0) +int read_stk(struct usb_device *p, u32 reg0) { -u8 igot; + u8 igot; -if (NULL == p) - return -ENODEV; -igot = 0; -GET(p, reg0, &igot); -return igot; + if (NULL == p) + return -ENODEV; + igot = 0; + GET(p, reg0, &igot); + return igot; } /****************************************************************************/ /*--------------------------------------------------------------------------*/ @@ -790,168 +777,165 @@ return igot; int select_input(struct usb_device *p, int input, int mode) { -int ir; - -if (NULL == p) - return -ENODEV; -stop_100(p); -switch (input) { -case 0: -case 1: { - if (0 != write_saa(p, 0x02, 0x80)) { - SAY("ERROR: failed to set SAA register 0x02 for input %i\n", - input); - } - SET(p, 0x0000, 0x0098); - SET(p, 0x0002, 0x0078); - break; -} -case 2: { - if (0 != write_saa(p, 0x02, 0x80)) { - SAY("ERROR: failed to set SAA register 0x02 for input %i\n", - input); - } - SET(p, 0x0000, 0x0090); - SET(p, 0x0002, 0x0078); - break; -} -case 3: { - if (0 != write_saa(p, 0x02, 0x80)) { - SAY("ERROR: failed to set SAA register 0x02 for input %i\n", - input); - } - SET(p, 0x0000, 0x0088); - SET(p, 0x0002, 0x0078); - break; -} -case 4: { - if (0 != write_saa(p, 0x02, 0x80)) { - SAY("ERROR: failed to set SAA register 0x02 for input %i\n", - input); - } - SET(p, 0x0000, 0x0080); - SET(p, 0x0002, 0x0078); - break; -} -case 5: { - if (9 != mode) - mode = 7; - switch (mode) { - case 7: { - if (0 != write_saa(p, 0x02, 0x87)) { + int ir; + + if (NULL == p) + return -ENODEV; + stop_100(p); + switch (input) { + case 0: + case 1: { + if (0 != write_saa(p, 0x02, 0x80)) { SAY("ERROR: failed to set SAA register 0x02 " "for input %i\n", input); } - if (0 != write_saa(p, 0x05, 0xFF)) { - SAY("ERROR: failed to set SAA register 0x05 " + SET(p, 0x0000, 0x0098); + SET(p, 0x0002, 0x0078); + break; + } + case 2: { + if (0 != write_saa(p, 0x02, 0x80)) { + SAY("ERROR: failed to set SAA register 0x02 " "for input %i\n", input); } + SET(p, 0x0000, 0x0090); + SET(p, 0x0002, 0x0078); + break; + } + case 3: { + if (0 != write_saa(p, 0x02, 0x80)) { + SAY("ERROR: failed to set SAA register 0x02 " + " for input %i\n", input); + } + SET(p, 0x0000, 0x0088); + SET(p, 0x0002, 0x0078); break; } - case 9: { - if (0 != write_saa(p, 0x02, 0x89)) { + case 4: { + if (0 != write_saa(p, 0x02, 0x80)) { SAY("ERROR: failed to set SAA register 0x02 " "for input %i\n", input); } - if (0 != write_saa(p, 0x05, 0x00)) { - SAY("ERROR: failed to set SAA register 0x05 " + SET(p, 0x0000, 0x0080); + SET(p, 0x0002, 0x0078); + break; + } + case 5: { + if (9 != mode) + mode = 7; + switch (mode) { + case 7: { + if (0 != write_saa(p, 0x02, 0x87)) { + SAY("ERROR: failed to set SAA register 0x02 " + "for input %i\n", input); + } + if (0 != write_saa(p, 0x05, 0xFF)) { + SAY("ERROR: failed to set SAA register 0x05 " "for input %i\n", input); + } + break; } - break; + case 9: { + if (0 != write_saa(p, 0x02, 0x89)) { + SAY("ERROR: failed to set SAA register 0x02 " + "for input %i\n", input); + } + if (0 != write_saa(p, 0x05, 0x00)) { + SAY("ERROR: failed to set SAA register 0x05 " + "for input %i\n", input); + } + break; + } + default: { + SAY("MISTAKE: bad mode: %i\n", mode); + return -1; + } + } + if (0 != write_saa(p, 0x04, 0x00)) { + SAY("ERROR: failed to set SAA register 0x04 " + "for input %i\n", input); + } + if (0 != write_saa(p, 0x09, 0x80)) { + SAY("ERROR: failed to set SAA register 0x09 " + "for input %i\n", input); + } + SET(p, 0x0002, 0x0093); + break; } default: { - SAY("MISTAKE: bad mode: %i\n", mode); + SAY("ERROR: bad input: %i\n", input); return -1; } } - if (0 != write_saa(p, 0x04, 0x00)) { - SAY("ERROR: failed to set SAA register 0x04 for input %i\n", - input); - } - if (0 != write_saa(p, 0x09, 0x80)) { - SAY("ERROR: failed to set SAA register 0x09 for input %i\n", - input); - } - SET(p, 0x0002, 0x0093); - break; -} -default: { - SAY("ERROR: bad input: %i\n", input); - return -1; -} -} -ir = read_stk(p, 0x00); -JOT(8, "STK register 0x00 has 0x%02X\n", ir); -ir = read_saa(p, 0x02); -JOT(8, "SAA register 0x02 has 0x%02X\n", ir); + ir = read_stk(p, 0x00); + JOT(8, "STK register 0x00 has 0x%02X\n", ir); + ir = read_saa(p, 0x02); + JOT(8, "SAA register 0x02 has 0x%02X\n", ir); -start_100(p); + start_100(p); -return 0; + return 0; } /****************************************************************************/ -int -set_resolution(struct usb_device *p, - u16 set0, u16 set1, u16 set2, u16 set3) +int set_resolution(struct usb_device *p, + u16 set0, u16 set1, u16 set2, u16 set3) { -u16 u0x0111, u0x0113, u0x0115, u0x0117; - -if (NULL == p) - return -ENODEV; -u0x0111 = ((0xFF00 & set0) >> 8); -u0x0113 = ((0xFF00 & set1) >> 8); -u0x0115 = ((0xFF00 & set2) >> 8); -u0x0117 = ((0xFF00 & set3) >> 8); - -SET(p, 0x0110, (0x00FF & set0)); -SET(p, 0x0111, u0x0111); -SET(p, 0x0112, (0x00FF & set1)); -SET(p, 0x0113, u0x0113); -SET(p, 0x0114, (0x00FF & set2)); -SET(p, 0x0115, u0x0115); -SET(p, 0x0116, (0x00FF & set3)); -SET(p, 0x0117, u0x0117); - -return 0; + u16 u0x0111, u0x0113, u0x0115, u0x0117; + + if (NULL == p) + return -ENODEV; + u0x0111 = ((0xFF00 & set0) >> 8); + u0x0113 = ((0xFF00 & set1) >> 8); + u0x0115 = ((0xFF00 & set2) >> 8); + u0x0117 = ((0xFF00 & set3) >> 8); + + SET(p, 0x0110, (0x00FF & set0)); + SET(p, 0x0111, u0x0111); + SET(p, 0x0112, (0x00FF & set1)); + SET(p, 0x0113, u0x0113); + SET(p, 0x0114, (0x00FF & set2)); + SET(p, 0x0115, u0x0115); + SET(p, 0x0116, (0x00FF & set3)); + SET(p, 0x0117, u0x0117); + + return 0; } /****************************************************************************/ -int -start_100(struct usb_device *p) +int start_100(struct usb_device *p) { -u16 get116, get117, get0; -u8 igot116, igot117, igot; - -if (NULL == p) - return -ENODEV; -GET(p, 0x0116, &igot116); -get116 = igot116; -GET(p, 0x0117, &igot117); -get117 = igot117; -SET(p, 0x0116, 0x0000); -SET(p, 0x0117, 0x0000); - -GET(p, 0x0100, &igot); -get0 = igot; -SET(p, 0x0100, (0x80 | get0)); - -SET(p, 0x0116, get116); -SET(p, 0x0117, get117); - -return 0; + u16 get116, get117, get0; + u8 igot116, igot117, igot; + + if (NULL == p) + return -ENODEV; + GET(p, 0x0116, &igot116); + get116 = igot116; + GET(p, 0x0117, &igot117); + get117 = igot117; + SET(p, 0x0116, 0x0000); + SET(p, 0x0117, 0x0000); + + GET(p, 0x0100, &igot); + get0 = igot; + SET(p, 0x0100, (0x80 | get0)); + + SET(p, 0x0116, get116); + SET(p, 0x0117, get117); + + return 0; } /****************************************************************************/ -int -stop_100(struct usb_device *p) +int stop_100(struct usb_device *p) { -u16 get0; -u8 igot; - -if (NULL == p) - return -ENODEV; -GET(p, 0x0100, &igot); -get0 = igot; -SET(p, 0x0100, (0x7F & get0)); -return 0; + u16 get0; + u8 igot; + + if (NULL == p) + return -ENODEV; + GET(p, 0x0100, &igot); + get0 = igot; + SET(p, 0x0100, (0x7F & get0)); + return 0; } /****************************************************************************/ /*--------------------------------------------------------------------------*/ @@ -959,57 +943,55 @@ return 0; * FUNCTION wait_i2c() RETURNS 0 ON SUCCESS */ /*--------------------------------------------------------------------------*/ -int -wait_i2c(struct usb_device *p) +int wait_i2c(struct usb_device *p) { -u16 get0; -u8 igot; -const int max = 2; -int k; - -if (NULL == p) - return -ENODEV; -for (k = 0; k < max; k++) { - GET(p, 0x0201, &igot); get0 = igot; - switch (get0) { - case 0x04: - case 0x01: { - return 0; - } - case 0x00: { - msleep(20); - continue; - } - default: { - return get0 - 1; - } + u16 get0; + u8 igot; + const int max = 2; + int k; + + if (NULL == p) + return -ENODEV; + for (k = 0; k < max; k++) { + GET(p, 0x0201, &igot); get0 = igot; + switch (get0) { + case 0x04: + case 0x01: { + return 0; + } + case 0x00: { + msleep(20); + continue; + } + default: { + return get0 - 1; + } + } } -} -return -1; + return -1; } /****************************************************************************/ /*****************************************************************************/ -int -wakeup_device(struct usb_device *pusb_device) +int wakeup_device(struct usb_device *pusb_device) { -if (!pusb_device) - return -ENODEV; -return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), - (u8)USB_REQ_SET_FEATURE, - (u8)(USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE), - USB_DEVICE_REMOTE_WAKEUP, - (u16)0, - (void *) NULL, - (u16)0, - (int)50000); + if (!pusb_device) + return -ENODEV; + return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), + (u8)USB_REQ_SET_FEATURE, + USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, + USB_DEVICE_REMOTE_WAKEUP, + (u16)0, + (void *) NULL, + (u16)0, + (int)50000); } /*****************************************************************************/ int audio_setup(struct easycap *peasycap) { -struct usb_device *pusb_device; -unsigned char buffer[1]; -int rc, id1, id2; + struct usb_device *pusb_device; + unsigned char buffer[1]; + int rc, id1, id2; /*---------------------------------------------------------------------------*/ /* * IMPORTANT: @@ -1018,53 +1000,54 @@ int rc, id1, id2; * TO ENABLE AUDIO THE VALUE 0x0200 MUST BE SENT. */ /*---------------------------------------------------------------------------*/ -const u8 request = 0x01; -const u8 requesttype = - (u8)(USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE); -const u16 value_unmute = 0x0200; -const u16 index = 0x0301; -const u16 length = 1; - -if (NULL == peasycap) - return -EFAULT; - -pusb_device = peasycap->pusb_device; -if (NULL == pusb_device) - return -ENODEV; - -JOM(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n", - requesttype, request, - (0x00FF & value_unmute), - (0xFF00 & value_unmute) >> 8, - (0x00FF & index), - (0xFF00 & index) >> 8, - (0x00FF & length), - (0xFF00 & length) >> 8); - -buffer[0] = 0x01; - -rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), - (u8)request, - (u8)requesttype, - (u16)value_unmute, - (u16)index, - (void *)&buffer[0], - (u16)length, - (int)50000); + const u8 request = 0x01; + const u8 requesttype = USB_DIR_OUT | + USB_TYPE_CLASS | + USB_RECIP_INTERFACE; + const u16 value_unmute = 0x0200; + const u16 index = 0x0301; + const u16 length = 1; + + if (NULL == peasycap) + return -EFAULT; + + pusb_device = peasycap->pusb_device; + if (NULL == pusb_device) + return -ENODEV; -JOT(8, "0x%02X=buffer\n", *((u8 *) &buffer[0])); -if (rc != (int)length) { - switch (rc) { - case -EPIPE: { - SAY("usb_control_msg returned -EPIPE\n"); - break; - } - default: { - SAY("ERROR: usb_control_msg returned %i\n", rc); - break; - } + JOM(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n", + requesttype, request, + (0x00FF & value_unmute), + (0xFF00 & value_unmute) >> 8, + (0x00FF & index), + (0xFF00 & index) >> 8, + (0x00FF & length), + (0xFF00 & length) >> 8); + + buffer[0] = 0x01; + + rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), + (u8)request, + (u8)requesttype, + (u16)value_unmute, + (u16)index, + (void *)&buffer[0], + (u16)length, + (int)50000); + + JOT(8, "0x%02X=buffer\n", *((u8 *) &buffer[0])); + if (rc != (int)length) { + switch (rc) { + case -EPIPE: { + SAY("usb_control_msg returned -EPIPE\n"); + break; + } + default: { + SAY("ERROR: usb_control_msg returned %i\n", rc); + break; + } + } } -} /*--------------------------------------------------------------------------*/ /* * REGISTER 500: SETTING VALUE TO 0x0094 RESETS AUDIO CONFIGURATION ??? @@ -1080,80 +1063,79 @@ if (rc != (int)length) { * THE UPPER BYTE SEEMS TO HAVE NO EFFECT. */ /*--------------------------------------------------------------------------*/ -SET(pusb_device, 0x0500, 0x0094); -SET(pusb_device, 0x0500, 0x008C); -SET(pusb_device, 0x0506, 0x0001); -SET(pusb_device, 0x0507, 0x0000); -id1 = read_vt(pusb_device, 0x007C); -id2 = read_vt(pusb_device, 0x007E); -SAM("0x%04X:0x%04X is audio vendor id\n", id1, id2); + SET(pusb_device, 0x0500, 0x0094); + SET(pusb_device, 0x0500, 0x008C); + SET(pusb_device, 0x0506, 0x0001); + SET(pusb_device, 0x0507, 0x0000); + id1 = read_vt(pusb_device, 0x007C); + id2 = read_vt(pusb_device, 0x007E); + SAM("0x%04X:0x%04X is audio vendor id\n", id1, id2); /*---------------------------------------------------------------------------*/ /* * SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN. */ /*---------------------------------------------------------------------------*/ -if (0 != audio_gainset(pusb_device, peasycap->gain)) - SAY("ERROR: audio_gainset() failed\n"); -check_vt(pusb_device); -return 0; + if (0 != audio_gainset(pusb_device, peasycap->gain)) + SAY("ERROR: audio_gainset() failed\n"); + check_vt(pusb_device); + return 0; } /*****************************************************************************/ -int -check_vt(struct usb_device *pusb_device) +int check_vt(struct usb_device *pusb_device) { -int igot; - -if (!pusb_device) - return -ENODEV; -igot = read_vt(pusb_device, 0x0002); -if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x02\n"); -if (0x8000 & igot) - SAY("register 0x%02X muted\n", 0x02); - -igot = read_vt(pusb_device, 0x000E); -if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x0E\n"); -if (0x8000 & igot) - SAY("register 0x%02X muted\n", 0x0E); - -igot = read_vt(pusb_device, 0x0010); -if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x10\n"); -if (0x8000 & igot) - SAY("register 0x%02X muted\n", 0x10); - -igot = read_vt(pusb_device, 0x0012); -if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x12\n"); -if (0x8000 & igot) - SAY("register 0x%02X muted\n", 0x12); - -igot = read_vt(pusb_device, 0x0014); -if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x14\n"); -if (0x8000 & igot) - SAY("register 0x%02X muted\n", 0x14); - -igot = read_vt(pusb_device, 0x0016); -if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x16\n"); -if (0x8000 & igot) - SAY("register 0x%02X muted\n", 0x16); - -igot = read_vt(pusb_device, 0x0018); -if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x18\n"); -if (0x8000 & igot) - SAY("register 0x%02X muted\n", 0x18); - -igot = read_vt(pusb_device, 0x001C); -if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x1C\n"); -if (0x8000 & igot) - SAY("register 0x%02X muted\n", 0x1C); - -return 0; + int igot; + + if (!pusb_device) + return -ENODEV; + igot = read_vt(pusb_device, 0x0002); + if (0 > igot) + SAY("ERROR: failed to read VT1612A register 0x02\n"); + if (0x8000 & igot) + SAY("register 0x%02X muted\n", 0x02); + + igot = read_vt(pusb_device, 0x000E); + if (0 > igot) + SAY("ERROR: failed to read VT1612A register 0x0E\n"); + if (0x8000 & igot) + SAY("register 0x%02X muted\n", 0x0E); + + igot = read_vt(pusb_device, 0x0010); + if (0 > igot) + SAY("ERROR: failed to read VT1612A register 0x10\n"); + if (0x8000 & igot) + SAY("register 0x%02X muted\n", 0x10); + + igot = read_vt(pusb_device, 0x0012); + if (0 > igot) + SAY("ERROR: failed to read VT1612A register 0x12\n"); + if (0x8000 & igot) + SAY("register 0x%02X muted\n", 0x12); + + igot = read_vt(pusb_device, 0x0014); + if (0 > igot) + SAY("ERROR: failed to read VT1612A register 0x14\n"); + if (0x8000 & igot) + SAY("register 0x%02X muted\n", 0x14); + + igot = read_vt(pusb_device, 0x0016); + if (0 > igot) + SAY("ERROR: failed to read VT1612A register 0x16\n"); + if (0x8000 & igot) + SAY("register 0x%02X muted\n", 0x16); + + igot = read_vt(pusb_device, 0x0018); + if (0 > igot) + SAY("ERROR: failed to read VT1612A register 0x18\n"); + if (0x8000 & igot) + SAY("register 0x%02X muted\n", 0x18); + + igot = read_vt(pusb_device, 0x001C); + if (0 > igot) + SAY("ERROR: failed to read VT1612A register 0x1C\n"); + if (0x8000 & igot) + SAY("register 0x%02X muted\n", 0x1C); + + return 0; } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ @@ -1170,85 +1152,83 @@ return 0; * 31 12.0 22.5 34.5 */ /*---------------------------------------------------------------------------*/ -int -audio_gainset(struct usb_device *pusb_device, s8 loud) +int audio_gainset(struct usb_device *pusb_device, s8 loud) { -int igot; -u8 tmp; -u16 mute; - -if (NULL == pusb_device) - return -ENODEV; -if (0 > loud) - loud = 0; -if (31 < loud) - loud = 31; - -write_vt(pusb_device, 0x0002, 0x8000); + int igot; + u8 tmp; + u16 mute; + + if (NULL == pusb_device) + return -ENODEV; + if (0 > loud) + loud = 0; + if (31 < loud) + loud = 31; + + write_vt(pusb_device, 0x0002, 0x8000); /*---------------------------------------------------------------------------*/ -igot = read_vt(pusb_device, 0x000E); -if (0 > igot) { - SAY("ERROR: failed to read VT1612A register 0x0E\n"); - mute = 0x0000; -} else - mute = 0x8000 & ((unsigned int)igot); -mute = 0; - -if (16 > loud) - tmp = 0x01 | (0x001F & (((u8)(15 - loud)) << 1)); -else - tmp = 0; - -JOT(8, "0x%04X=(mute|tmp) for VT1612A register 0x0E\n", mute | tmp); -write_vt(pusb_device, 0x000E, (mute | tmp)); + igot = read_vt(pusb_device, 0x000E); + if (0 > igot) { + SAY("ERROR: failed to read VT1612A register 0x0E\n"); + mute = 0x0000; + } else + mute = 0x8000 & ((unsigned int)igot); + mute = 0; + + if (16 > loud) + tmp = 0x01 | (0x001F & (((u8)(15 - loud)) << 1)); + else + tmp = 0; + + JOT(8, "0x%04X=(mute|tmp) for VT1612A register 0x0E\n", mute | tmp); + write_vt(pusb_device, 0x000E, (mute | tmp)); /*---------------------------------------------------------------------------*/ -igot = read_vt(pusb_device, 0x0010); -if (0 > igot) { - SAY("ERROR: failed to read VT1612A register 0x10\n"); - mute = 0x0000; -} else - mute = 0x8000 & ((unsigned int)igot); -mute = 0; - -JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x10,...0x18\n", + igot = read_vt(pusb_device, 0x0010); + if (0 > igot) { + SAY("ERROR: failed to read VT1612A register 0x10\n"); + mute = 0x0000; + } else + mute = 0x8000 & ((unsigned int)igot); + mute = 0; + + JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x10,...0x18\n", mute | tmp | (tmp << 8)); -write_vt(pusb_device, 0x0010, (mute | tmp | (tmp << 8))); -write_vt(pusb_device, 0x0012, (mute | tmp | (tmp << 8))); -write_vt(pusb_device, 0x0014, (mute | tmp | (tmp << 8))); -write_vt(pusb_device, 0x0016, (mute | tmp | (tmp << 8))); -write_vt(pusb_device, 0x0018, (mute | tmp | (tmp << 8))); + write_vt(pusb_device, 0x0010, (mute | tmp | (tmp << 8))); + write_vt(pusb_device, 0x0012, (mute | tmp | (tmp << 8))); + write_vt(pusb_device, 0x0014, (mute | tmp | (tmp << 8))); + write_vt(pusb_device, 0x0016, (mute | tmp | (tmp << 8))); + write_vt(pusb_device, 0x0018, (mute | tmp | (tmp << 8))); /*---------------------------------------------------------------------------*/ -igot = read_vt(pusb_device, 0x001C); -if (0 > igot) { - SAY("ERROR: failed to read VT1612A register 0x1C\n"); - mute = 0x0000; -} else - mute = 0x8000 & ((unsigned int)igot); -mute = 0; - -if (16 <= loud) - tmp = 0x000F & (u8)(loud - 16); -else - tmp = 0; - -JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x1C\n", - mute | tmp | (tmp << 8)); -write_vt(pusb_device, 0x001C, (mute | tmp | (tmp << 8))); -write_vt(pusb_device, 0x001A, 0x0404); -write_vt(pusb_device, 0x0002, 0x0000); -return 0; + igot = read_vt(pusb_device, 0x001C); + if (0 > igot) { + SAY("ERROR: failed to read VT1612A register 0x1C\n"); + mute = 0x0000; + } else + mute = 0x8000 & ((unsigned int)igot); + mute = 0; + + if (16 <= loud) + tmp = 0x000F & (u8)(loud - 16); + else + tmp = 0; + + JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x1C\n", + mute | tmp | (tmp << 8)); + write_vt(pusb_device, 0x001C, (mute | tmp | (tmp << 8))); + write_vt(pusb_device, 0x001A, 0x0404); + write_vt(pusb_device, 0x0002, 0x0000); + return 0; } /*****************************************************************************/ -int -audio_gainget(struct usb_device *pusb_device) +int audio_gainget(struct usb_device *pusb_device) { -int igot; - -if (NULL == pusb_device) - return -ENODEV; -igot = read_vt(pusb_device, 0x001C); -if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x1C\n"); -return igot; + int igot; + + if (NULL == pusb_device) + return -ENODEV; + igot = read_vt(pusb_device, 0x001C); + if (0 > igot) + SAY("ERROR: failed to read VT1612A register 0x1C\n"); + return igot; } /*****************************************************************************/ -- cgit v1.2.3 From ccb6d2e5dc37605503d0a3182dbb27981f90df94 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 10 Feb 2011 14:55:23 +0200 Subject: staging/easycap: don't mask return value of usb_control_msg() by 0xFF masking return value of usb_control_msg() will mask negative error values into positive. Cc: Mike Thomas Reported-by: Dan Carpenter Signed-off-by: Tomas Winkler Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_low.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index 7b2de10bc68a..5c41a27a683d 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -270,7 +270,7 @@ static int regget(struct usb_device *pusb_device, 0x00, index, reg, reg_size, 50000); - return 0xFF & rc; + return rc; } static int regset(struct usb_device *pusb_device, u16 index, u16 value) -- cgit v1.2.3 From 3e17e39e1129a4dad1696fb6df30af227c1815cc Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 10 Feb 2011 14:55:24 +0200 Subject: staging/easycap: style changes in easycap_low.c remove uneedet brackets in ifs and switches drop pointless castings other small fixes Cc: Mike Thomas Signed-off-by: Tomas Winkler Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_low.c | 91 +++++++++++++++-------------------- 1 file changed, 38 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index 5c41a27a683d..1f914b428c84 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -145,7 +145,7 @@ static const struct stk1160config stk1160configNTSC[256] = { {0xFFF, 0xFFFF} }; /*--------------------------------------------------------------------------*/ -static const struct saa7113config{ +static const struct saa7113config { int reg; int set; } saa7113configPAL[256] = { @@ -600,10 +600,7 @@ int merit_saa(struct usb_device *p) if (NULL == p) return -ENODEV; rc = read_saa(p, 0x1F); - if ((0 > rc) || (0x02 & rc)) - return 1 ; - else - return 0; + return ((0 > rc) || (0x02 & rc)) ? 1 : 0; } /****************************************************************************/ int ready_saa(struct usb_device *p) @@ -785,28 +782,28 @@ select_input(struct usb_device *p, int input, int mode) switch (input) { case 0: case 1: { - if (0 != write_saa(p, 0x02, 0x80)) { + if (0 != write_saa(p, 0x02, 0x80)) SAY("ERROR: failed to set SAA register 0x02 " "for input %i\n", input); - } + SET(p, 0x0000, 0x0098); SET(p, 0x0002, 0x0078); break; } case 2: { - if (0 != write_saa(p, 0x02, 0x80)) { + if (0 != write_saa(p, 0x02, 0x80)) SAY("ERROR: failed to set SAA register 0x02 " "for input %i\n", input); - } + SET(p, 0x0000, 0x0090); SET(p, 0x0002, 0x0078); break; } case 3: { - if (0 != write_saa(p, 0x02, 0x80)) { + if (0 != write_saa(p, 0x02, 0x80)) SAY("ERROR: failed to set SAA register 0x02 " " for input %i\n", input); - } + SET(p, 0x0000, 0x0088); SET(p, 0x0002, 0x0078); break; @@ -825,48 +822,48 @@ select_input(struct usb_device *p, int input, int mode) mode = 7; switch (mode) { case 7: { - if (0 != write_saa(p, 0x02, 0x87)) { + if (0 != write_saa(p, 0x02, 0x87)) SAY("ERROR: failed to set SAA register 0x02 " "for input %i\n", input); - } - if (0 != write_saa(p, 0x05, 0xFF)) { + + if (0 != write_saa(p, 0x05, 0xFF)) SAY("ERROR: failed to set SAA register 0x05 " "for input %i\n", input); - } + break; } case 9: { - if (0 != write_saa(p, 0x02, 0x89)) { + if (0 != write_saa(p, 0x02, 0x89)) SAY("ERROR: failed to set SAA register 0x02 " "for input %i\n", input); - } - if (0 != write_saa(p, 0x05, 0x00)) { + + if (0 != write_saa(p, 0x05, 0x00)) SAY("ERROR: failed to set SAA register 0x05 " "for input %i\n", input); - } - break; + + break; } - default: { + default: SAY("MISTAKE: bad mode: %i\n", mode); return -1; } - } - if (0 != write_saa(p, 0x04, 0x00)) { + + if (0 != write_saa(p, 0x04, 0x00)) SAY("ERROR: failed to set SAA register 0x04 " "for input %i\n", input); - } - if (0 != write_saa(p, 0x09, 0x80)) { + + if (0 != write_saa(p, 0x09, 0x80)) SAY("ERROR: failed to set SAA register 0x09 " "for input %i\n", input); - } + SET(p, 0x0002, 0x0093); break; } - default: { + default: SAY("ERROR: bad input: %i\n", input); return -1; } - } + ir = read_stk(p, 0x00); JOT(8, "STK register 0x00 has 0x%02X\n", ir); ir = read_saa(p, 0x02); @@ -952,21 +949,19 @@ int wait_i2c(struct usb_device *p) if (NULL == p) return -ENODEV; + for (k = 0; k < max; k++) { GET(p, 0x0201, &igot); get0 = igot; switch (get0) { case 0x04: - case 0x01: { + case 0x01: return 0; - } - case 0x00: { + case 0x00: msleep(20); continue; - } - default: { + default: return get0 - 1; } - } } return -1; } @@ -977,20 +972,17 @@ int wakeup_device(struct usb_device *pusb_device) if (!pusb_device) return -ENODEV; return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), - (u8)USB_REQ_SET_FEATURE, + USB_REQ_SET_FEATURE, USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, USB_DEVICE_REMOTE_WAKEUP, - (u16)0, - (void *) NULL, - (u16)0, - (int)50000); + 0, NULL, 0, 50000); } /*****************************************************************************/ int audio_setup(struct easycap *peasycap) { struct usb_device *pusb_device; - unsigned char buffer[1]; + u8 buffer[1]; int rc, id1, id2; /*---------------------------------------------------------------------------*/ /* @@ -1027,26 +1019,19 @@ audio_setup(struct easycap *peasycap) buffer[0] = 0x01; rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), - (u8)request, - (u8)requesttype, - (u16)value_unmute, - (u16)index, - (void *)&buffer[0], - (u16)length, - (int)50000); - - JOT(8, "0x%02X=buffer\n", *((u8 *) &buffer[0])); + request, requesttype, value_unmute, + index, &buffer[0], length, 50000); + + JOT(8, "0x%02X=buffer\n", buffer[0]); if (rc != (int)length) { switch (rc) { - case -EPIPE: { + case -EPIPE: SAY("usb_control_msg returned -EPIPE\n"); break; - } - default: { + default: SAY("ERROR: usb_control_msg returned %i\n", rc); break; } - } } /*--------------------------------------------------------------------------*/ /* -- cgit v1.2.3 From 30516058e2ad4a69ca9bdeac498ad522778bd3b5 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 15 Feb 2011 14:15:18 +0200 Subject: staging/easycap: kill EASYCAP_NEEDS_V4L2_DEVICE_H and EASYCAP_NEEDS_V4L2_FOPS EASYCAP_NEEDS_V4L2_DEVICE_H and EASYCAP_NEEDS_V4L2_FOPS are required in in-tree driver Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/Makefile | 2 -- drivers/staging/easycap/easycap.h | 6 ------ drivers/staging/easycap/easycap_main.c | 26 +------------------------- drivers/staging/easycap/easycap_sound_oss.c | 10 +--------- 4 files changed, 2 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/Makefile b/drivers/staging/easycap/Makefile index 987ccb184f57..1f9331ba4882 100644 --- a/drivers/staging/easycap/Makefile +++ b/drivers/staging/easycap/Makefile @@ -10,6 +10,4 @@ obj-$(CONFIG_EASYCAP) += easycap.o ccflags-y := -Wall ccflags-y += -DEASYCAP_IS_VIDEODEV_CLIENT -ccflags-y += -DEASYCAP_NEEDS_V4L2_DEVICE_H -ccflags-y += -DEASYCAP_NEEDS_V4L2_FOPS diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 55b1a14fa518..fe91257efeaf 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -31,8 +31,6 @@ * EASYCAP_DEBUG * EASYCAP_IS_VIDEODEV_CLIENT * EASYCAP_NEEDS_USBVIDEO_H - * EASYCAP_NEEDS_V4L2_DEVICE_H - * EASYCAP_NEEDS_V4L2_FOPS * * IF REQUIRED THEY MUST BE EXTERNALLY DEFINED, FOR EXAMPLE AS COMPILER * OPTIONS. @@ -87,9 +85,7 @@ /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #ifdef EASYCAP_IS_VIDEODEV_CLIENT #include -#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H #include -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ #include @@ -306,9 +302,7 @@ struct easycap { /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #ifdef EASYCAP_IS_VIDEODEV_CLIENT struct video_device video_device; -#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H struct v4l2_device v4l2_device; -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ int status; diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 340d4cff7f8e..fa7982e7a89f 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -3132,7 +3132,6 @@ static const struct usb_class_driver easycap_class = { }; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #ifdef EASYCAP_IS_VIDEODEV_CLIENT -#ifdef EASYCAP_NEEDS_V4L2_FOPS static const struct v4l2_file_operations v4l2_fops = { .owner = THIS_MODULE, .open = easycap_open_noinode, @@ -3141,7 +3140,6 @@ static const struct v4l2_file_operations v4l2_fops = { .poll = easycap_poll, .mmap = easycap_mmap, }; -#endif /*EASYCAP_NEEDS_V4L2_FOPS*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*****************************************************************************/ /*---------------------------------------------------------------------------*/ @@ -3184,9 +3182,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, struct easycap_format *peasycap_format; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #ifdef EASYCAP_IS_VIDEODEV_CLIENT -#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H struct v4l2_device *pv4l2_device; -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ @@ -3289,10 +3285,8 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, #ifdef EASYCAP_IS_VIDEODEV_CLIENT SAM("where 0x%08lX=&peasycap->video_device\n", (unsigned long int) &peasycap->video_device); -#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H SAM("and 0x%08lX=&peasycap->v4l2_device\n", (unsigned long int) &peasycap->v4l2_device); -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*---------------------------------------------------------------------------*/ @@ -3542,11 +3536,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, bInterfaceNumber); return -ENODEV; } -#ifndef EASYCAP_IS_VIDEODEV_CLIENT -# -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#else -#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H +#ifdef EASYCAP_IS_VIDEODEV_CLIENT /*---------------------------------------------------------------------------*/ /* * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS @@ -3564,7 +3554,6 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, peasycap = (struct easycap *) container_of(pv4l2_device, struct easycap, v4l2_device); } -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ } /*---------------------------------------------------------------------------*/ @@ -4136,7 +4125,6 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, } /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #else -#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H if (0 != (v4l2_device_register(&(pusb_interface->dev), &(peasycap->v4l2_device)))) { SAM("v4l2_device_register() failed\n"); @@ -4156,14 +4144,9 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, peasycap->video_device.v4l2_dev = NULL; /*---------------------------------------------------------------------------*/ -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ strcpy(&peasycap->video_device.name[0], "easycapdc60"); -#ifdef EASYCAP_NEEDS_V4L2_FOPS peasycap->video_device.fops = &v4l2_fops; -#else - peasycap->video_device.fops = &easycap_fops; -#endif /*EASYCAP_NEEDS_V4L2_FOPS*/ peasycap->video_device.minor = -1; peasycap->video_device.release = (void *)(&videodev_release); @@ -4539,9 +4522,7 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) int minor, m, kd; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #ifdef EASYCAP_IS_VIDEODEV_CLIENT -#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H struct v4l2_device *pv4l2_device; -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ @@ -4571,7 +4552,6 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) } /*---------------------------------------------------------------------------*/ #ifdef EASYCAP_IS_VIDEODEV_CLIENT -#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H /*---------------------------------------------------------------------------*/ /* * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS @@ -4589,8 +4569,6 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) peasycap = (struct easycap *) container_of(pv4l2_device, struct easycap, v4l2_device); } -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ -# #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*---------------------------------------------------------------------------*/ @@ -4689,7 +4667,6 @@ case 0: { } /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #else -#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H if (!peasycap->v4l2_device.name[0]) { SAM("ERROR: peasycap->v4l2_device.name is empty\n"); if (0 <= kd && DONGLE_MANY > kd) @@ -4700,7 +4677,6 @@ case 0: { JOM(4, "v4l2_device_disconnect() OK\n"); v4l2_device_unregister(&peasycap->v4l2_device); JOM(4, "v4l2_device_unregister() OK\n"); -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ video_unregister_device(&peasycap->video_device); JOM(4, "intf[%i]: video_unregister_device() OK\n", bInterfaceNumber); diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c index 0b6065de9656..b18cd351837c 100644 --- a/drivers/staging/easycap/easycap_sound_oss.c +++ b/drivers/staging/easycap/easycap_sound_oss.c @@ -308,9 +308,7 @@ struct easycap *peasycap; int subminor; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #ifdef EASYCAP_IS_VIDEODEV_CLIENT -#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H struct v4l2_device *pv4l2_device; -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ @@ -331,11 +329,7 @@ if (NULL == peasycap) { return -1; } /*---------------------------------------------------------------------------*/ -#ifndef EASYCAP_IS_VIDEODEV_CLIENT -# -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#else -#ifdef EASYCAP_NEEDS_V4L2_DEVICE_H +#ifdef EASYCAP_IS_VIDEODEV_CLIENT /*---------------------------------------------------------------------------*/ /* * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS @@ -353,8 +347,6 @@ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { peasycap = (struct easycap *) container_of(pv4l2_device, struct easycap, v4l2_device); } -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ -# #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*---------------------------------------------------------------------------*/ -- cgit v1.2.3 From 7ee7142186b9acff6a142d0ebca5cfc28c85f5b5 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 15 Feb 2011 14:15:19 +0200 Subject: staging/easycap: drop EASYCAP_NEEDS_USBVIDEO_H remove pointless compilation flag Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index fe91257efeaf..e8ef1a258341 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -30,7 +30,6 @@ * * EASYCAP_DEBUG * EASYCAP_IS_VIDEODEV_CLIENT - * EASYCAP_NEEDS_USBVIDEO_H * * IF REQUIRED THEY MUST BE EXTERNALLY DEFINED, FOR EXAMPLE AS COMPILER * OPTIONS. @@ -90,9 +89,6 @@ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ #include #include -#ifdef EASYCAP_NEEDS_USBVIDEO_H -#include -#endif /*EASYCAP_NEEDS_USBVIDEO_H*/ #ifndef PAGE_SIZE #error "PAGE_SIZE not defined" -- cgit v1.2.3 From 073f48252698e83dc9e710d354c6859aeea78cd9 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 15 Feb 2011 14:15:20 +0200 Subject: staging/easycap: use %p for printing pointers use %p instead of %X drop casting of pointer to long long int Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_main.c | 34 ++++++++++------------------- drivers/staging/easycap/easycap_sound.c | 2 +- drivers/staging/easycap/easycap_sound_oss.c | 9 ++++---- 3 files changed, 17 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index fa7982e7a89f..e306357a2e5f 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -179,15 +179,14 @@ if (NULL == peasycap) { return -EFAULT; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + SAY("ERROR: bad peasycap: %p\n", peasycap); return -EFAULT; } if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } else { - JOM(16, "0x%08lX=peasycap->pusb_device\n", - (long int)peasycap->pusb_device); + JOM(16, "peasycap->pusb_device=%p\n", peasycap->pusb_device); } file->private_data = peasycap; rc = wakeup_device(peasycap->pusb_device); @@ -746,7 +745,7 @@ if (NULL == peasycap) { return -EFAULT; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + SAY("ERROR: bad peasycap: %p\n", peasycap); return -EFAULT; } if (0 != kill_video_urbs(peasycap)) { @@ -785,7 +784,7 @@ if (NULL == peasycap) { return -EFAULT; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + SAY("ERROR: bad peasycap: %p\n", peasycap); return -EFAULT; } if (0 != kill_video_urbs(peasycap)) { @@ -825,7 +824,7 @@ if (NULL == peasycap) { return; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + SAY("ERROR: bad peasycap: %p\n", peasycap); return; } kd = isdongle(peasycap); @@ -1041,7 +1040,7 @@ if (NULL == peasycap) { return -EFAULT; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + SAY("ERROR: bad peasycap: %p\n", peasycap); return -EFAULT; } if (NULL == peasycap->pusb_device) { @@ -1078,8 +1077,7 @@ if (0 <= kd && DONGLE_MANY > kd) { return -ERESTARTSYS; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", - (unsigned long int) peasycap); + SAY("ERROR: bad peasycap: %p\n", peasycap); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; } @@ -2622,7 +2620,7 @@ if (NULL == peasycap) { return; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + SAY("ERROR: bad peasycap: %p\n", peasycap); return; } peasycap->vma_many++; @@ -2640,7 +2638,7 @@ if (NULL == peasycap) { return; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + SAY("ERROR: bad peasycap: %p\n", peasycap); return; } peasycap->vma_many--; @@ -2774,7 +2772,7 @@ if (NULL == peasycap) { return; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + SAY("ERROR: bad peasycap: %p\n", peasycap); return; } if (peasycap->video_eof) @@ -3280,15 +3278,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, SAY("ERROR: Could not allocate peasycap\n"); return -ENOMEM; } - SAM("allocated 0x%08lX=peasycap\n", (unsigned long int) peasycap); -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#ifdef EASYCAP_IS_VIDEODEV_CLIENT - SAM("where 0x%08lX=&peasycap->video_device\n", - (unsigned long int) &peasycap->video_device); - SAM("and 0x%08lX=&peasycap->v4l2_device\n", - (unsigned long int) &peasycap->v4l2_device); -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + SAM("allocated %p=peasycap\n", peasycap); /*---------------------------------------------------------------------------*/ /* * PERFORM URGENT INTIALIZATIONS ... @@ -4573,7 +4563,7 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*---------------------------------------------------------------------------*/ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + SAY("ERROR: bad peasycap: %p\n", peasycap); return; } /*---------------------------------------------------------------------------*/ diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index 626450a57140..0d647c81ed55 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -431,7 +431,7 @@ if (NULL == prt) { return -EFAULT; } if (NULL != prt->dma_area) { - JOT(8, "0x%08lX=prt->dma_area\n", (unsigned long int)prt->dma_area); + JOT(8, "prt->dma_area = %p\n", prt->dma_area); vfree(prt->dma_area); prt->dma_area = NULL; } else diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c index b18cd351837c..e817b3571885 100644 --- a/drivers/staging/easycap/easycap_sound_oss.c +++ b/drivers/staging/easycap/easycap_sound_oss.c @@ -351,7 +351,7 @@ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*---------------------------------------------------------------------------*/ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + SAY("ERROR: bad peasycap: %p\n", peasycap); return -EFAULT; } /*---------------------------------------------------------------------------*/ @@ -377,7 +377,7 @@ if (NULL == peasycap) { return -EFAULT; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + SAY("ERROR: bad peasycap: %p\n", peasycap); return -EFAULT; } if (0 != kill_audio_urbs(peasycap)) { @@ -424,7 +424,7 @@ if (NULL == peasycap) { return -EFAULT; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + SAY("ERROR: bad peasycap: %p\n", peasycap); return -EFAULT; } if (NULL == peasycap->pusb_device) { @@ -460,8 +460,7 @@ if (0 <= kd && DONGLE_MANY > kd) { return -ERESTARTSYS; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", - (unsigned long int) peasycap); + SAY("ERROR: bad peasycap: %p\n", peasycap); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; } -- cgit v1.2.3 From 3646dd971b97be600bce75c2c7bb3e1c716bfd09 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 10 Feb 2011 12:03:41 +0100 Subject: staging: brcm80211: use consistent naming for mac80211 callbacks Most mac80211 callbacks were named using prefix 'wl_ops' except for a few. These have been aligned to use the prefix as well. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 33 ++++++++++++------------ 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 745c8874036d..c283b39a3a3e 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -135,13 +135,14 @@ static void wl_ops_sta_notify(struct ieee80211_hw *hw, static int wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params); static u64 wl_ops_get_tsf(struct ieee80211_hw *hw); -static int wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +static int wl_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); -static int wl_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +static int wl_ops_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); -static int wl_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn); +static int wl_ops_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum ieee80211_ampdu_mlme_action action, + struct ieee80211_sta *sta, u16 tid, u16 *ssn); static void wl_ops_rfkill_poll(struct ieee80211_hw *hw); static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) @@ -514,8 +515,8 @@ static u64 wl_ops_get_tsf(struct ieee80211_hw *hw) } static int -wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +wl_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) { struct scb *scb; @@ -549,18 +550,18 @@ wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } static int -wl_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +wl_ops_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) { WL_NONE("%s: Enter\n", __func__); return 0; } static int -wl_ampdu_action(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn) +wl_ops_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum ieee80211_ampdu_mlme_action action, + struct ieee80211_sta *sta, u16 tid, u16 *ssn) { #if defined(BCMDBG) struct scb *scb = (struct scb *)sta->drv_priv; @@ -632,9 +633,9 @@ static const struct ieee80211_ops wl_ops = { .sta_notify = wl_ops_sta_notify, .conf_tx = wl_ops_conf_tx, .get_tsf = wl_ops_get_tsf, - .sta_add = wl_sta_add, - .sta_remove = wl_sta_remove, - .ampdu_action = wl_ampdu_action, + .sta_add = wl_ops_sta_add, + .sta_remove = wl_ops_sta_remove, + .ampdu_action = wl_ops_ampdu_action, .rfkill_poll = wl_ops_rfkill_poll, }; -- cgit v1.2.3 From 4a0791505639fcbb33b410c2a353d06688909188 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 10 Feb 2011 12:03:42 +0100 Subject: staging: brcm80211: decrease level of non-error messages Non-error messages which were printed using WL_ERROR macro were decreased to WL_NONE (which is a no_printk) or WL_TRACE level macros. mac80211 callbacks that are not handled by the driver are printed with WL_ERROR. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 65 +++++++++++------------ drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 2 +- 3 files changed, 33 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index c283b39a3a3e..46e765e2cacd 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -149,6 +149,7 @@ static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { int status; struct wl_info *wl = hw->priv; + WL_LOCK(wl); if (!wl->pub->up) { WL_ERROR("ops->tx called while down\n"); @@ -262,8 +263,6 @@ static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) WL_LOCK(wl); if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { - WL_NONE("%s: Setting listen interval to %d\n", - __func__, conf->listen_interval); if (wlc_iovar_setint (wl->wlc, "bcn_li_bcn", conf->listen_interval)) { WL_ERROR("%s: Error setting listen_interval\n", @@ -275,13 +274,15 @@ static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) ASSERT(new_int == conf->listen_interval); } if (changed & IEEE80211_CONF_CHANGE_MONITOR) - WL_NONE("Need to set monitor mode\n"); + WL_ERROR("%s: change monitor mode: %s (implement)\n", __func__, + conf->flags & IEEE80211_CONF_MONITOR ? + "true" : "false"); if (changed & IEEE80211_CONF_CHANGE_PS) - WL_NONE("Need to set Power-save mode\n"); + WL_ERROR("%s: change power-save mode: %s (implement)\n", + __func__, conf->flags & IEEE80211_CONF_PS ? + "true" : "false"); if (changed & IEEE80211_CONF_CHANGE_POWER) { - WL_NONE("%s: Setting tx power to %d dbm\n", - __func__, conf->power_level); if (wlc_iovar_setint (wl->wlc, "qtxpower", conf->power_level * 4)) { WL_ERROR("%s: Error setting power_level\n", __func__); @@ -297,10 +298,6 @@ static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) err = ieee_set_channel(hw, conf->channel, conf->channel_type); } if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { - WL_NONE("%s: srl %d, lrl %d\n", - __func__, - conf->short_frame_max_tx_count, - conf->long_frame_max_tx_count); if (wlc_set (wl->wlc, WLC_SET_SRL, conf->short_frame_max_tx_count) < 0) { @@ -329,64 +326,63 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, struct wl_info *wl = HW_TO_WL(hw); int val; - if (changed & BSS_CHANGED_ASSOC) { - WL_ERROR("Associated:\t%s\n", info->assoc ? "True" : "False"); /* association status changed (associated/disassociated) * also implies a change in the AID. */ + WL_ERROR("%s: %s: %sassociated\n", KBUILD_MODNAME, __func__, + info->assoc ? "" : "dis"); } if (changed & BSS_CHANGED_ERP_CTS_PROT) { - WL_NONE("Use_cts_prot:\t%s Implement me\n", - info->use_cts_prot ? "True" : "False"); /* CTS protection changed */ + WL_ERROR("%s: use_cts_prot: %s (implement)\n", __func__, + info->use_cts_prot ? "true" : "false"); } if (changed & BSS_CHANGED_ERP_PREAMBLE) { - WL_NONE("Short preamble:\t%s Implement me\n", - info->use_short_preamble ? "True" : "False"); /* preamble changed */ + WL_ERROR("%s: short preamble: %s (implement)\n", __func__, + info->use_short_preamble ? "true" : "false"); } if (changed & BSS_CHANGED_ERP_SLOT) { - WL_NONE("Changing short slot:\t%s\n", - info->use_short_slot ? "True" : "False"); + /* slot timing changed */ if (info->use_short_slot) val = 1; else val = 0; wlc_set(wl->wlc, WLC_SET_SHORTSLOT_OVERRIDE, val); - /* slot timing changed */ } if (changed & BSS_CHANGED_HT) { - WL_NONE("%s: HT mode - Implement me\n", __func__); /* 802.11n parameters changed */ + u16 mode = info->ht_operation_mode; + WL_NONE("%s: HT mode: 0x%04X (implement)\n", __func__, mode); } if (changed & BSS_CHANGED_BASIC_RATES) { - WL_NONE("Need to change Basic Rates:\t0x%x! Implement me\n", - (u32) info->basic_rates); /* Basic rateset changed */ + WL_ERROR("%s: Need to change Basic Rates: 0x%x (implement)\n", + __func__, (u32) info->basic_rates); } if (changed & BSS_CHANGED_BEACON_INT) { - WL_NONE("Beacon Interval:\t%d Implement me\n", - info->beacon_int); /* Beacon interval changed */ + WL_NONE("%s: Beacon Interval: %d\n", + __func__, info->beacon_int); } if (changed & BSS_CHANGED_BSSID) { + /* BSSID changed, for whatever reason (IBSS and managed mode) */ WL_NONE("new BSSID:\taid %d bss:%pM\n", info->aid, info->bssid); - /* BSSID changed, for whatever reason (IBSS and managed mode) */ /* FIXME: need to store bssid in bsscfg */ wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid); } if (changed & BSS_CHANGED_BEACON) { - WL_ERROR("BSS_CHANGED_BEACON\n"); /* Beacon data changed, retrieve new beacon (beaconing modes) */ + WL_ERROR("BSS_CHANGED_BEACON\n"); } if (changed & BSS_CHANGED_BEACON_ENABLED) { - WL_ERROR("Beacon enabled:\t%s\n", - info->enable_beacon ? "True" : "False"); /* Beaconing should be enabled/disabled (beaconing modes) */ + WL_ERROR("Beacon enabled: %s\n", + info->enable_beacon ? "true" : "false"); } return; } @@ -430,7 +426,7 @@ wl_ops_configure_filter(struct ieee80211_hw *hw, static int wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) { - WL_ERROR("%s: Enter\n", __func__); + WL_NONE("%s: Enter\n", __func__); return 0; } @@ -611,7 +607,7 @@ static void wl_ops_rfkill_poll(struct ieee80211_hw *hw) blocked = wlc_check_radio_disabled(wl->wlc); WL_UNLOCK(wl); - WL_ERROR("wl: rfkill_poll: %d\n", blocked); + WL_NONE("wl: rfkill_poll: %d\n", blocked); wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked); } @@ -641,7 +637,7 @@ static const struct ieee80211_ops wl_ops = { static int wl_set_hint(struct wl_info *wl, char *abbrev) { - WL_ERROR("%s: Sending country code %c%c to MAC80211\n", + WL_NONE("%s: Sending country code %c%c to MAC80211\n", __func__, abbrev[0], abbrev[1]); return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev); } @@ -1497,12 +1493,12 @@ static void BCMFASTPATH wl_dpc(unsigned long data) static void wl_link_up(struct wl_info *wl, char *ifname) { - WL_ERROR("wl%d: link up (%s)\n", wl->pub->unit, ifname); + WL_NONE("wl%d: link up (%s)\n", wl->pub->unit, ifname); } static void wl_link_down(struct wl_info *wl, char *ifname) { - WL_ERROR("wl%d: link down (%s)\n", wl->pub->unit, ifname); + WL_NONE("wl%d: link down (%s)\n", wl->pub->unit, ifname); } void wl_event(struct wl_info *wl, char *ifname, wlc_event_t *e) @@ -1850,7 +1846,8 @@ bool wl_rfkill_set_hw_state(struct wl_info *wl) { bool blocked = wlc_check_radio_disabled(wl->wlc); - WL_ERROR("%s: update hw state: blocked=%s\n", __func__, blocked ? "true" : "false"); + WL_NONE("%s: update hw state: blocked=%s\n", __func__, + blocked ? "true" : "false"); wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked); if (blocked) wiphy_rfkill_start_polling(wl->pub->ieee_hw->wiphy); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 8d9aca5651f8..5f0e7e6f0f8e 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -995,7 +995,7 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, goto fail; } - WL_ERROR("%s:: deviceid 0x%x nbands %d board 0x%x macaddr: %s\n", + WL_TRACE("%s:: deviceid 0x%x nbands %d board 0x%x macaddr: %s\n", __func__, wlc_hw->deviceid, wlc_hw->_nbands, wlc_hw->sih->boardtype, macaddr); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index 6debd45c7961..1909bdf556c0 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -8336,7 +8336,7 @@ void wlc_txflowcontrol(struct wlc_info *wlc, wlc_txq_info_t *qi, uint prio_bits; uint cur_bits; - WL_ERROR("%s: flow control kicks in\n", __func__); + WL_TRACE("%s: flow control kicks in\n", __func__); if (prio == ALLPRIO) { prio_bits = TXQ_STOP_FOR_PRIOFC_MASK; -- cgit v1.2.3 From 9d2c415612bc6dd300e7feffebf193243536eaea Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 10 Feb 2011 12:03:43 +0100 Subject: staging: brcm80211: return error code to mac80211 for 40MHz channels When mac80211 attempts to configure the driver for 40MHz channel it will return an error code -EIO as this is not yet supported. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 46e765e2cacd..ce115f29d79a 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -246,6 +246,7 @@ ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan, case NL80211_CHAN_HT40MINUS: case NL80211_CHAN_HT40PLUS: WL_ERROR("%s: Need to implement 40 Mhz Channels!\n", __func__); + err = 1; break; } -- cgit v1.2.3 From 0bef7748e1327f72b006ea699e8725be50685f0e Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 10 Feb 2011 12:03:44 +0100 Subject: staging: brcm80211: remove usage of printf (macro) from driver The driver contained several calls to printf which was mapped to printk using a macro. These have been changed to explicit call to printk or use an appropropriate macro. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c | 2 +- drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h | 36 +++++-- drivers/staging/brcm80211/brcmfmac/dhd_common.c | 17 +-- drivers/staging/brcm80211/brcmfmac/dhd_dbg.h | 28 ++--- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 4 +- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 20 ++-- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 8 +- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 24 ++--- drivers/staging/brcm80211/brcmsmac/wlc_channel.c | 120 ++++++++++++---------- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 119 ++++++++++----------- drivers/staging/brcm80211/include/bcmsdh.h | 12 ++- drivers/staging/brcm80211/include/osl.h | 1 - drivers/staging/brcm80211/include/siutils.h | 2 +- drivers/staging/brcm80211/util/bcmutils.c | 8 +- drivers/staging/brcm80211/util/hnddma.c | 6 +- drivers/staging/brcm80211/util/hndpmu.c | 2 +- 16 files changed, 229 insertions(+), 180 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c index 143e8604a596..deb5f46542ae 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c @@ -114,7 +114,7 @@ bool bcmsdh_chipmatch(u16 vendor, u16 device) #ifdef BCMSDIOH_SPI /* This is the PciSpiHost. */ if (device == SPIH_FPGA_ID && vendor == VENDOR_BROADCOM) { - printf("Found PCI SPI Host Controller\n"); + WL_NONE("Found PCI SPI Host Controller\n"); return true; } #endif /* BCMSDIOH_SPI */ diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h index 4d671ddb3af1..50470f6c92fa 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h @@ -18,12 +18,36 @@ #define __BCMSDH_SDMMC_H__ #ifdef BCMDBG -#define sd_err(x) do { if ((sd_msglevel & SDH_ERROR_VAL) && net_ratelimit()) printf x; } while (0) -#define sd_trace(x) do { if ((sd_msglevel & SDH_TRACE_VAL) && net_ratelimit()) printf x; } while (0) -#define sd_info(x) do { if ((sd_msglevel & SDH_INFO_VAL) && net_ratelimit()) printf x; } while (0) -#define sd_debug(x) do { if ((sd_msglevel & SDH_DEBUG_VAL) && net_ratelimit()) printf x; } while (0) -#define sd_data(x) do { if ((sd_msglevel & SDH_DATA_VAL) && net_ratelimit()) printf x; } while (0) -#define sd_ctrl(x) do { if ((sd_msglevel & SDH_CTRL_VAL) && net_ratelimit()) printf x; } while (0) +#define sd_err(x) \ + do { \ + if ((sd_msglevel & SDH_ERROR_VAL) && net_ratelimit()) \ + printk x; \ + } while (0) +#define sd_trace(x) \ + do { \ + if ((sd_msglevel & SDH_TRACE_VAL) && net_ratelimit()) \ + printk x; \ + } while (0) +#define sd_info(x) \ + do { \ + if ((sd_msglevel & SDH_INFO_VAL) && net_ratelimit()) \ + printk x; \ + } while (0) +#define sd_debug(x) \ + do { \ + if ((sd_msglevel & SDH_DEBUG_VAL) && net_ratelimit()) \ + printk x; \ + } while (0) +#define sd_data(x) \ + do { \ + if ((sd_msglevel & SDH_DATA_VAL) && net_ratelimit()) \ + printk x; \ + } while (0) +#define sd_ctrl(x) \ + do { \ + if ((sd_msglevel & SDH_CTRL_VAL) && net_ratelimit()) \ + printk x; \ + } while (0) #else #define sd_err(x) #define sd_trace(x) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index eeabbc3334d4..ad4a00871d85 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -739,10 +739,11 @@ static void wl_show_host_event(wl_event_msg_t *event, void *event_data) memcpy(&hdr, buf, MSGTRACE_HDRLEN); if (hdr.version != MSGTRACE_VERSION) { - printf + DHD_ERROR( ("\nMACEVENT: %s [unsupported version --> " "dhd version:%d dongle version:%d]\n", - event_name, MSGTRACE_VERSION, hdr.version); + event_name, MSGTRACE_VERSION, hdr.version) + ); /* Reset datalen to avoid display below */ datalen = 0; break; @@ -753,18 +754,18 @@ static void wl_show_host_event(wl_event_msg_t *event, void *event_data) if (ntoh32(hdr.discarded_bytes) || ntoh32(hdr.discarded_printf)) { - printf + DHD_ERROR( ("\nWLC_E_TRACE: [Discarded traces in dongle -->" "discarded_bytes %d discarded_printf %d]\n", ntoh32(hdr.discarded_bytes), - ntoh32(hdr.discarded_printf)); + ntoh32(hdr.discarded_printf))); } nblost = ntoh32(hdr.seqnum) - seqnum_prev - 1; if (nblost > 0) { - printf + DHD_ERROR( ("\nWLC_E_TRACE: [Event lost --> seqnum %d nblost %d\n", - ntoh32(hdr.seqnum), nblost); + ntoh32(hdr.seqnum), nblost)); } seqnum_prev = ntoh32(hdr.seqnum); @@ -775,10 +776,10 @@ static void wl_show_host_event(wl_event_msg_t *event, void *event_data) p = (char *)&buf[MSGTRACE_HDRLEN]; while ((s = strstr(p, "\n")) != NULL) { *s = '\0'; - printf("%s\n", p); + printk(KERN_DEBUG"%s\n", p); p = s + 1; } - printf("%s\n", p); + printk(KERN_DEBUG "%s\n", p); /* Reset datalen to avoid display below */ datalen = 0; diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h b/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h index cd2578ad3552..0817f1348e09 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h @@ -21,31 +21,31 @@ #define DHD_ERROR(args) \ do {if ((dhd_msg_level & DHD_ERROR_VAL) && (net_ratelimit())) \ - printf args; } while (0) + printk args; } while (0) #define DHD_TRACE(args) do {if (dhd_msg_level & DHD_TRACE_VAL) \ - printf args; } while (0) + printk args; } while (0) #define DHD_INFO(args) do {if (dhd_msg_level & DHD_INFO_VAL) \ - printf args; } while (0) + printk args; } while (0) #define DHD_DATA(args) do {if (dhd_msg_level & DHD_DATA_VAL) \ - printf args; } while (0) + printk args; } while (0) #define DHD_CTL(args) do {if (dhd_msg_level & DHD_CTL_VAL) \ - printf args; } while (0) + printk args; } while (0) #define DHD_TIMER(args) do {if (dhd_msg_level & DHD_TIMER_VAL) \ - printf args; } while (0) + printk args; } while (0) #define DHD_HDRS(args) do {if (dhd_msg_level & DHD_HDRS_VAL) \ - printf args; } while (0) + printk args; } while (0) #define DHD_BYTES(args) do {if (dhd_msg_level & DHD_BYTES_VAL) \ - printf args; } while (0) + printk args; } while (0) #define DHD_INTR(args) do {if (dhd_msg_level & DHD_INTR_VAL) \ - printf args; } while (0) + printk args; } while (0) #define DHD_GLOM(args) do {if (dhd_msg_level & DHD_GLOM_VAL) \ - printf args; } while (0) + printk args; } while (0) #define DHD_EVENT(args) do {if (dhd_msg_level & DHD_EVENT_VAL) \ - printf args; } while (0) + printk args; } while (0) #define DHD_BTA(args) do {if (dhd_msg_level & DHD_BTA_VAL) \ - printf args; } while (0) + printk args; } while (0) #define DHD_ISCAN(args) do {if (dhd_msg_level & DHD_ISCAN_VAL) \ - printf args; } while (0) + printk args; } while (0) #define DHD_ERROR_ON() (dhd_msg_level & DHD_ERROR_VAL) #define DHD_TRACE_ON() (dhd_msg_level & DHD_TRACE_VAL) @@ -63,7 +63,7 @@ #else /* (defined BCMDBG) || (defined DHD_DEBUG) */ -#define DHD_ERROR(args) do {if (net_ratelimit()) printf args; } while (0) +#define DHD_ERROR(args) do {if (net_ratelimit()) printk args; } while (0) #define DHD_TRACE(args) #define DHD_INFO(args) #define DHD_DATA(args) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 7100d815163c..2426a616807e 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -2299,7 +2299,7 @@ int dhd_net_attach(dhd_pub_t *dhdp, int ifidx) goto fail; } - printf("%s: Broadcom Dongle Host Driver\n", net->name); + DHD_INFO(("%s: Broadcom Dongle Host Driver\n", net->name)); return 0; @@ -2934,7 +2934,7 @@ int write_to_file(dhd_pub_t *dhd, u8 *buf, int size) /* open file to write */ fp = filp_open("/tmp/mem_dump", O_WRONLY | O_CREAT, 0640); if (!fp) { - printf("%s: open file error\n", __func__); + DHD_ERROR(("%s: open file error\n", __func__)); ret = -1; goto exit; } diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 383416d5a750..159c45928e74 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -1951,34 +1951,34 @@ static int dhdsdio_mem_dump(dhd_bus_t *bus) size = bus->ramsize; buf = kmalloc(size, GFP_ATOMIC); if (!buf) { - printf("%s: Out of memory (%d bytes)\n", __func__, size); + DHD_ERROR(("%s: Out of memory (%d bytes)\n", __func__, size)); return -1; } /* Read mem content */ - printf("Dump dongle memory"); + printk(KERN_DEBUG "Dump dongle memory"); databuf = buf; while (size) { read_size = min(MEMBLOCK, size); ret = dhdsdio_membytes(bus, false, start, databuf, read_size); if (ret) { - printf("%s: Error membytes %d\n", __func__, ret); + DHD_ERROR(("%s: Error membytes %d\n", __func__, ret)); if (buf) kfree(buf); return -1; } - printf("."); + printk("."); /* Decrement size and increment start address */ size -= read_size; start += read_size; databuf += read_size; } - printf("Done\n"); + printk(KERN_DEBUG "Done\n"); /* free buf before return !!! */ if (write_to_file(bus->dhd, buf, bus->ramsize)) { - printf("%s: Error writing to files\n", __func__); + DHD_ERROR(("%s: Error writing to files\n", __func__)); return -1; } @@ -2056,7 +2056,7 @@ static int dhdsdio_readconsole(dhd_bus_t *bus) if (line[n - 1] == '\r') n--; line[n] = 0; - printf("CONSOLE: %s\n", line); + printk(KERN_DEBUG "CONSOLE: %s\n", line); } } break2: @@ -4500,7 +4500,7 @@ clkwait: if (ret == 0) bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; - printf("Return_dpc value is : %d\n", ret); + DHD_INFO(("Return_dpc value is : %d\n", ret)); bus->ctrl_frame_stat = false; dhd_wait_event_wakeup(bus->dhd); } @@ -4640,7 +4640,7 @@ static void dhdsdio_pktgen(dhd_bus_t *bus) /* Display current count if appropriate */ if (bus->pktgen_print && (++bus->pktgen_ptick >= bus->pktgen_print)) { bus->pktgen_ptick = 0; - printf("%s: send attempts %d rcvd %d\n", + printk(KERN_DEBUG "%s: send attempts %d rcvd %d\n", __func__, bus->pktgen_sent, bus->pktgen_rcvd); } @@ -5237,7 +5237,7 @@ dhdsdio_probe_attach(struct dhd_bus *bus, struct osl_info *osh, void *sdh, DHD_ERROR(("%s: FAILED to return to SI_ENUM_BASE\n", __func__)); #ifdef DHD_DEBUG - printf("F1 signature read @0x18000000=0x%4x\n", + printk(KERN_DEBUG "F1 signature read @0x18000000=0x%4x\n", bcmsdh_reg_read(bus->sdh, SI_ENUM_BASE, 4)); #endif /* DHD_DEBUG */ diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index f4b1b4ecab82..1dbc94a98a47 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -3444,10 +3444,10 @@ void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) wrqu.data.length = sizeof(status) + 1; extra[0] = WLC_E_ACTION_FRAME_COMPLETE; memcpy(&extra[1], &status, sizeof(status)); - printf("wl_iw_event status %d PacketId %d\n", status, - toto); - printf("WLC_E_ACTION_FRAME_COMPLETE len %d\n", - wrqu.data.length); + WL_TRACE("wl_iw_event status %d PacketId %d\n", status, + toto); + WL_TRACE("WLC_E_ACTION_FRAME_COMPLETE len %d\n", + wrqu.data.length); } break; #endif /* WIRELESS_EXT > 14 */ diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index ce115f29d79a..c1d66995bdcb 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -711,8 +711,8 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, /* prepare ucode */ if (wl_request_fw(wl, (struct pci_dev *)btparam)) { - printf("%s: Failed to find firmware usually in %s\n", - KBUILD_MODNAME, "/lib/firmware/brcm"); + WL_ERROR("%s: Failed to find firmware usually in %s\n", + KBUILD_MODNAME, "/lib/firmware/brcm"); wl_release_fw(wl); wl_remove((struct pci_dev *)btparam); goto fail1; @@ -723,8 +723,8 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, wl->regsva, wl->bcm_bustype, btparam, &err); wl_release_fw(wl); if (!wl->wlc) { - printf("%s: wlc_attach() failed with code %d\n", - KBUILD_MODNAME, err); + WL_ERROR("%s: wlc_attach() failed with code %d\n", + KBUILD_MODNAME, err); goto fail; } wl->pub = wlc_pub(wl->wlc); @@ -1705,15 +1705,15 @@ int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx) pdata = wl->fw.fw_bin[i]->data + hdr->offset; *pbuf = kmalloc(hdr->len, GFP_ATOMIC); if (*pbuf == NULL) { - printf("fail to alloc %d bytes\n", - hdr->len); + WL_ERROR("fail to alloc %d bytes\n", + hdr->len); } bcopy(pdata, *pbuf, hdr->len); return 0; } } } - printf("ERROR: ucode buf tag:%d can not be found!\n", idx); + WL_ERROR("ERROR: ucode buf tag:%d can not be found!\n", idx); *pbuf = NULL; return -1; } @@ -1735,7 +1735,7 @@ int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx) } } } - printf("ERROR: ucode tag:%d can not be found!\n", idx); + WL_ERROR("ERROR: ucode tag:%d can not be found!\n", idx); return -1; } @@ -1755,8 +1755,8 @@ static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) WL_NONE("request fw %s\n", fw_name); status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); if (status) { - printf("%s: fail to load firmware %s\n", - KBUILD_MODNAME, fw_name); + WL_ERROR("%s: fail to load firmware %s\n", + KBUILD_MODNAME, fw_name); wl_release_fw(wl); return status; } @@ -1765,8 +1765,8 @@ static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) UCODE_LOADER_API_VER); status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); if (status) { - printf("%s: fail to load firmware %s\n", - KBUILD_MODNAME, fw_name); + WL_ERROR("%s: fail to load firmware %s\n", + KBUILD_MODNAME, fw_name); wl_release_fw(wl); return status; } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c index 2e30d9223052..06b31a0364f4 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c @@ -1144,100 +1144,114 @@ wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, static void wlc_phy_txpower_limits_dump(txpwr_limits_t *txpwr) { int i; + char buf[80]; char fraction[4][4] = { " ", ".25", ".5 ", ".75" }; - printf("CCK "); + sprintf(buf, "CCK "); for (i = 0; i < WLC_NUM_RATES_CCK; i++) { - printf(" %2d%s", txpwr->cck[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->cck[i] % WLC_TXPWR_DB_FACTOR]); + sprintf(buf[strlen(buf)], " %2d%s", + txpwr->cck[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->cck[i] % WLC_TXPWR_DB_FACTOR]); } - printf("\n"); + printk(KERN_DEBUG "%s\n", buf); - printf("20 MHz OFDM SISO "); + sprintf(buf, "20 MHz OFDM SISO "); for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { - printf(" %2d%s", txpwr->ofdm[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->ofdm[i] % WLC_TXPWR_DB_FACTOR]); + sprintf(buf[strlen(buf)], " %2d%s", + txpwr->ofdm[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->ofdm[i] % WLC_TXPWR_DB_FACTOR]); } - printf("\n"); + printk(KERN_DEBUG "%s\n", buf); - printf("20 MHz OFDM CDD "); + sprintf(buf, "20 MHz OFDM CDD "); for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { - printf(" %2d%s", txpwr->ofdm_cdd[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->ofdm_cdd[i] % WLC_TXPWR_DB_FACTOR]); + sprintf(buf[strlen(buf)], " %2d%s", + txpwr->ofdm_cdd[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->ofdm_cdd[i] % WLC_TXPWR_DB_FACTOR]); } - printf("\n"); + printk(KERN_DEBUG "%s\n", buf); - printf("40 MHz OFDM SISO "); + sprintf(buf, "40 MHz OFDM SISO "); for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { - printf(" %2d%s", txpwr->ofdm_40_siso[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->ofdm_40_siso[i] % WLC_TXPWR_DB_FACTOR]); + sprintf(buf[strlen(buf)], " %2d%s", + txpwr->ofdm_40_siso[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->ofdm_40_siso[i] % WLC_TXPWR_DB_FACTOR]); } - printf("\n"); + printk(KERN_DEBUG "%s\n", buf); - printf("40 MHz OFDM CDD "); + sprintf(buf, "40 MHz OFDM CDD "); for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { - printf(" %2d%s", txpwr->ofdm_40_cdd[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->ofdm_40_cdd[i] % WLC_TXPWR_DB_FACTOR]); + sprintf(buf[strlen(buf)], " %2d%s", + txpwr->ofdm_40_cdd[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->ofdm_40_cdd[i] % WLC_TXPWR_DB_FACTOR]); } - printf("\n"); + printk(KERN_DEBUG "%s\n", buf); - printf("20 MHz MCS0-7 SISO "); + sprintf(buf, "20 MHz MCS0-7 SISO "); for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_20_siso[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_20_siso[i] % WLC_TXPWR_DB_FACTOR]); + sprintf(buf[strlen(buf)], " %2d%s", + txpwr->mcs_20_siso[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_20_siso[i] % WLC_TXPWR_DB_FACTOR]); } - printf("\n"); + printk(KERN_DEBUG "%s\n", buf); - printf("20 MHz MCS0-7 CDD "); + sprintf(buf, "20 MHz MCS0-7 CDD "); for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_20_cdd[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_20_cdd[i] % WLC_TXPWR_DB_FACTOR]); + sprintf(buf[strlen(buf)], " %2d%s", + txpwr->mcs_20_cdd[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_20_cdd[i] % WLC_TXPWR_DB_FACTOR]); } - printf("\n"); + printk(KERN_DEBUG "%s\n", buf); - printf("20 MHz MCS0-7 STBC "); + sprintf(buf, "20 MHz MCS0-7 STBC "); for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_20_stbc[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_20_stbc[i] % WLC_TXPWR_DB_FACTOR]); + sprintf(buf[strlen(buf)], " %2d%s", + txpwr->mcs_20_stbc[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_20_stbc[i] % WLC_TXPWR_DB_FACTOR]); } - printf("\n"); + printk(KERN_DEBUG "%s\n", buf); - printf("20 MHz MCS8-15 SDM "); + sprintf(buf, "20 MHz MCS8-15 SDM "); for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_20_mimo[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_20_mimo[i] % WLC_TXPWR_DB_FACTOR]); + sprintf(buf[strlen(buf)], " %2d%s", + txpwr->mcs_20_mimo[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_20_mimo[i] % WLC_TXPWR_DB_FACTOR]); } - printf("\n"); + printk(KERN_DEBUG "%s\n", buf); - printf("40 MHz MCS0-7 SISO "); + sprintf(buf, "40 MHz MCS0-7 SISO "); for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_40_siso[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_40_siso[i] % WLC_TXPWR_DB_FACTOR]); + sprintf(buf[strlen(buf)], " %2d%s", + txpwr->mcs_40_siso[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_40_siso[i] % WLC_TXPWR_DB_FACTOR]); } - printf("\n"); + printk(KERN_DEBUG "%s\n", buf); - printf("40 MHz MCS0-7 CDD "); + sprintf(buf, "40 MHz MCS0-7 CDD "); for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_40_cdd[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_40_cdd[i] % WLC_TXPWR_DB_FACTOR]); + sprintf(buf[strlen(buf)], " %2d%s", + txpwr->mcs_40_cdd[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_40_cdd[i] % WLC_TXPWR_DB_FACTOR]); } - printf("\n"); + printk(KERN_DEBUG "%s\n", buf); - printf("40 MHz MCS0-7 STBC "); + sprintf(buf, "40 MHz MCS0-7 STBC "); for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_40_stbc[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_40_stbc[i] % WLC_TXPWR_DB_FACTOR]); + sprintf(buf[strlen(buf)], " %2d%s", + txpwr->mcs_40_stbc[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_40_stbc[i] % WLC_TXPWR_DB_FACTOR]); } - printf("\n"); + printk(KERN_DEBUG "%s\n", buf); - printf("40 MHz MCS8-15 SDM "); + sprintf(buf, "40 MHz MCS8-15 SDM "); for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) { - printf(" %2d%s", txpwr->mcs_40_mimo[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_40_mimo[i] % WLC_TXPWR_DB_FACTOR]); + sprintf(buf[strlen(buf)], " %2d%s", + txpwr->mcs_40_mimo[i] / WLC_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_40_mimo[i] % WLC_TXPWR_DB_FACTOR]); } - printf("\n"); + printk(KERN_DEBUG "%s\n", buf); - printf("MCS32 %2d%s\n", + printk(KERN_DEBUG "MCS32 %2d%s\n", txpwr->mcs32 / WLC_TXPWR_DB_FACTOR, fraction[txpwr->mcs32 % WLC_TXPWR_DB_FACTOR]); } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index 1909bdf556c0..5a6a01614116 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -4703,19 +4703,21 @@ static const char *supr_reason[] = { static void wlc_print_txs_status(u16 s) { - printf("[15:12] %d frame attempts\n", (s & TX_STATUS_FRM_RTX_MASK) >> - TX_STATUS_FRM_RTX_SHIFT); - printf(" [11:8] %d rts attempts\n", (s & TX_STATUS_RTS_RTX_MASK) >> - TX_STATUS_RTS_RTX_SHIFT); - printf(" [7] %d PM mode indicated\n", + printk(KERN_DEBUG "[15:12] %d frame attempts\n", + (s & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT); + printk(KERN_DEBUG " [11:8] %d rts attempts\n", + (s & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT); + printk(KERN_DEBUG " [7] %d PM mode indicated\n", ((s & TX_STATUS_PMINDCTD) ? 1 : 0)); - printf(" [6] %d intermediate status\n", + printk(KERN_DEBUG " [6] %d intermediate status\n", ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0)); - printf(" [5] %d AMPDU\n", (s & TX_STATUS_AMPDU) ? 1 : 0); - printf(" [4:2] %d Frame Suppressed Reason (%s)\n", + printk(KERN_DEBUG " [5] %d AMPDU\n", + (s & TX_STATUS_AMPDU) ? 1 : 0); + printk(KERN_DEBUG " [4:2] %d Frame Suppressed Reason (%s)\n", ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT), supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]); - printf(" [1] %d acked\n", ((s & TX_STATUS_ACK_RCV) ? 1 : 0)); + printk(KERN_DEBUG " [1] %d acked\n", + ((s & TX_STATUS_ACK_RCV) ? 1 : 0)); } #endif /* BCMDBG */ @@ -4725,21 +4727,22 @@ void wlc_print_txstatus(tx_status_t *txs) u16 s = txs->status; u16 ackphyrxsh = txs->ackphyrxsh; - printf("\ntxpkt (MPDU) Complete\n"); + printk(KERN_DEBUG "\ntxpkt (MPDU) Complete\n"); + + printk(KERN_DEBUG "FrameID: %04x ", txs->frameid); + printk(KERN_DEBUG "TxStatus: %04x", s); + printk(KERN_DEBUG "\n"); - printf("FrameID: %04x ", txs->frameid); - printf("TxStatus: %04x", s); - printf("\n"); -#ifdef BCMDBG wlc_print_txs_status(s); -#endif - printf("LastTxTime: %04x ", txs->lasttxtime); - printf("Seq: %04x ", txs->sequence); - printf("PHYTxStatus: %04x ", txs->phyerr); - printf("RxAckRSSI: %04x ", + + printk(KERN_DEBUG "LastTxTime: %04x ", txs->lasttxtime); + printk(KERN_DEBUG "Seq: %04x ", txs->sequence); + printk(KERN_DEBUG "PHYTxStatus: %04x ", txs->phyerr); + printk(KERN_DEBUG "RxAckRSSI: %04x ", (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT); - printf("RxAckSQ: %04x", (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); - printf("\n"); + printk(KERN_DEBUG "RxAckSQ: %04x", + (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); + printk(KERN_DEBUG "\n"); #endif /* defined(BCMDBG) */ } @@ -4884,51 +4887,50 @@ void wlc_print_txdesc(d11txh_t *txh) /* add plcp header along with txh descriptor */ prhex("Raw TxDesc + plcp header", (unsigned char *) txh, sizeof(d11txh_t) + 48); - printf("TxCtlLow: %04x ", mtcl); - printf("TxCtlHigh: %04x ", mtch); - printf("FC: %04x ", mfc); - printf("FES Time: %04x\n", tfest); - printf("PhyCtl: %04x%s ", ptcw, + printk(KERN_DEBUG "TxCtlLow: %04x ", mtcl); + printk(KERN_DEBUG "TxCtlHigh: %04x ", mtch); + printk(KERN_DEBUG "FC: %04x ", mfc); + printk(KERN_DEBUG "FES Time: %04x\n", tfest); + printk(KERN_DEBUG "PhyCtl: %04x%s ", ptcw, (ptcw & PHY_TXC_SHORT_HDR) ? " short" : ""); - printf("PhyCtl_1: %04x ", ptcw_1); - printf("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr); - printf("PhyCtl_1_Rts: %04x ", ptcw_1_Rts); - printf("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts); - printf("MainRates: %04x ", mainrates); - printf("XtraFrameTypes: %04x ", xtraft); - printf("\n"); + printk(KERN_DEBUG "PhyCtl_1: %04x ", ptcw_1); + printk(KERN_DEBUG "PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr); + printk(KERN_DEBUG "PhyCtl_1_Rts: %04x ", ptcw_1_Rts); + printk(KERN_DEBUG "PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts); + printk(KERN_DEBUG "MainRates: %04x ", mainrates); + printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft); + printk(KERN_DEBUG "\n"); bcm_format_hex(hexbuf, iv, sizeof(txh->IV)); - printf("SecIV: %s\n", hexbuf); + printk(KERN_DEBUG "SecIV: %s\n", hexbuf); bcm_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA)); - printf("RA: %s\n", hexbuf); + printk(KERN_DEBUG "RA: %s\n", hexbuf); - printf("Fb FES Time: %04x ", tfestfb); + printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb); bcm_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback)); - printf("RTS PLCP: %s ", hexbuf); - printf("RTS DUR: %04x ", rtsdfb); + printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf); + printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb); bcm_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback)); - printf("PLCP: %s ", hexbuf); - printf("DUR: %04x", fragdfb); - printf("\n"); + printk(KERN_DEBUG "PLCP: %s ", hexbuf); + printk(KERN_DEBUG "DUR: %04x", fragdfb); + printk(KERN_DEBUG "\n"); - printf("MModeLen: %04x ", mmodelen); - printf("MModeFbrLen: %04x\n", mmodefbrlen); + printk(KERN_DEBUG "MModeLen: %04x ", mmodelen); + printk(KERN_DEBUG "MModeFbrLen: %04x\n", mmodefbrlen); - printf("FrameID: %04x\n", tfid); - printf("TxStatus: %04x\n", txs); + printk(KERN_DEBUG "FrameID: %04x\n", tfid); + printk(KERN_DEBUG "TxStatus: %04x\n", txs); - printf("MaxNumMpdu: %04x\n", mnmpdu); - printf("MaxAggbyte: %04x\n", mabyte); - printf("MaxAggbyte_fb: %04x\n", mabyte_f); - printf("MinByte: %04x\n", mmbyte); + printk(KERN_DEBUG "MaxNumMpdu: %04x\n", mnmpdu); + printk(KERN_DEBUG "MaxAggbyte: %04x\n", mabyte); + printk(KERN_DEBUG "MaxAggbyte_fb: %04x\n", mabyte_f); + printk(KERN_DEBUG "MinByte: %04x\n", mmbyte); bcm_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader)); - printf("RTS PLCP: %s ", hexbuf); + printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf); bcm_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame)); - printf("RTS Frame: %s", hexbuf); - printf("\n"); - + printk(KERN_DEBUG "RTS Frame: %s", hexbuf); + printk(KERN_DEBUG "\n"); } #endif /* defined(BCMDBG) */ @@ -4960,13 +4962,14 @@ void wlc_print_rxh(d11rxhdr_t *rxh) snprintf(lenbuf, sizeof(lenbuf), "0x%x", len); - printf("RxFrameSize: %6s (%d)%s\n", lenbuf, len, + printk(KERN_DEBUG "RxFrameSize: %6s (%d)%s\n", lenbuf, len, (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : ""); - printf("RxPHYStatus: %04x %04x %04x %04x\n", + printk(KERN_DEBUG "RxPHYStatus: %04x %04x %04x %04x\n", phystatus_0, phystatus_1, phystatus_2, phystatus_3); - printf("RxMACStatus: %x %s\n", macstatus1, flagstr); - printf("RXMACaggtype: %x\n", (macstatus2 & RXS_AGGTYPE_MASK)); - printf("RxTSFTime: %04x\n", rxh->RxTSFTime); + printk(KERN_DEBUG "RxMACStatus: %x %s\n", macstatus1, flagstr); + printk(KERN_DEBUG "RXMACaggtype: %x\n", + (macstatus2 & RXS_AGGTYPE_MASK)); + printk(KERN_DEBUG "RxTSFTime: %04x\n", rxh->RxTSFTime); } #endif /* defined(BCMDBG) */ diff --git a/drivers/staging/brcm80211/include/bcmsdh.h b/drivers/staging/brcm80211/include/bcmsdh.h index aa5f372d58cc..96c629267f14 100644 --- a/drivers/staging/brcm80211/include/bcmsdh.h +++ b/drivers/staging/brcm80211/include/bcmsdh.h @@ -23,8 +23,16 @@ extern const uint bcmsdh_msglevel; #ifdef BCMDBG -#define BCMSDH_ERROR(x) do { if ((bcmsdh_msglevel & BCMSDH_ERROR_VAL) && net_ratelimit()) printf x; } while (0) -#define BCMSDH_INFO(x) do { if ((bcmsdh_msglevel & BCMSDH_INFO_VAL) && net_ratelimit()) printf x; } while (0) +#define BCMSDH_ERROR(x) \ + do { \ + if ((bcmsdh_msglevel & BCMSDH_ERROR_VAL) && net_ratelimit()) \ + printk x; \ + } while (0) +#define BCMSDH_INFO(x) \ + do { \ + if ((bcmsdh_msglevel & BCMSDH_INFO_VAL) && net_ratelimit()) \ + printk x; \ + } while (0) #else /* BCMDBG */ #define BCMSDH_ERROR(x) #define BCMSDH_INFO(x) diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index b28235618d8b..919b12af0c81 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -106,7 +106,6 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, #define PKTBUFSZ 2048 #define OSL_SYSUPTIME() ((u32)jiffies * (1000 / HZ)) -#define printf(fmt, args...) printk(fmt , ## args) #ifdef BRCM_FULLMAC #include /* for vsn/printf's */ #include /* for mem*, str* */ diff --git a/drivers/staging/brcm80211/include/siutils.h b/drivers/staging/brcm80211/include/siutils.h index 47b6a3090960..e681d40655b9 100644 --- a/drivers/staging/brcm80211/include/siutils.h +++ b/drivers/staging/brcm80211/include/siutils.h @@ -188,7 +188,7 @@ extern void si_sprom_init(si_t *sih); #define SI_ERROR(args) #ifdef BCMDBG -#define SI_MSG(args) printf args +#define SI_MSG(args) printk args #else #define SI_MSG(args) #endif /* BCMDBG */ diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index 258fd90d9152..35c1b6d6b50e 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -414,7 +414,7 @@ void prpkt(const char *msg, struct osl_info *osh, struct sk_buff *p0) struct sk_buff *p; if (msg && (msg[0] != '\0')) - printf("%s:\n", msg); + printk(KERN_DEBUG "%s:\n", msg); for (p = p0; p; p = p->next) prhex(NULL, p->data, p->len); @@ -865,7 +865,7 @@ void prhex(const char *msg, unsigned char *buf, uint nbytes) uint i; if (msg && (msg[0] != '\0')) - printf("%s:\n", msg); + printk(KERN_DEBUG "%s:\n", msg); p = line; for (i = 0; i < nbytes; i++) { @@ -881,7 +881,7 @@ void prhex(const char *msg, unsigned char *buf, uint nbytes) } if (i % 16 == 15) { - printf("%s\n", line); /* flush line */ + printk(KERN_DEBUG "%s\n", line); /* flush line */ p = line; len = sizeof(line); } @@ -889,7 +889,7 @@ void prhex(const char *msg, unsigned char *buf, uint nbytes) /* flush last partial line */ if (p != line) - printf("%s\n", line); + printk(KERN_DEBUG "%s\n", line); } char *bcm_chipname(uint chipid, char *buf, uint len) diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 2fc916624807..47dceb302447 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -40,14 +40,14 @@ if (!(*di->msg_level & 1)) \ ; \ else \ - printf args; \ + printk args; \ } while (0) #define DMA_TRACE(args) \ do { \ if (!(*di->msg_level & 2)) \ ; \ else \ - printf args; \ + printk args; \ } while (0) #else #define DMA_ERROR(args) @@ -287,7 +287,7 @@ struct hnddma_pub *dma_attach(struct osl_info *osh, char *name, si_t *sih, di = kzalloc(sizeof(dma_info_t), GFP_ATOMIC); if (di == NULL) { #ifdef BCMDBG - printf("dma_attach: out of memory\n"); + printk(KERN_ERR "dma_attach: out of memory\n"); #endif return NULL; } diff --git a/drivers/staging/brcm80211/util/hndpmu.c b/drivers/staging/brcm80211/util/hndpmu.c index 2678d799f7fd..5240341cbad8 100644 --- a/drivers/staging/brcm80211/util/hndpmu.c +++ b/drivers/staging/brcm80211/util/hndpmu.c @@ -31,7 +31,7 @@ #define PMU_ERROR(args) #ifdef BCMDBG -#define PMU_MSG(args) printf args +#define PMU_MSG(args) printk args /* debug-only definitions */ /* #define BCMDBG_FORCEHT */ -- cgit v1.2.3 From 8746e2baaedd45b51ceb0adbcaf2ce52bbb83598 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 10 Feb 2011 12:03:45 +0100 Subject: staging: brcm80211: fix potential null pointer access handling ucode buffer Allocation of buffer in function wl_ucode_init_buf can fail. This was signalled by an error message, but code continued to access the null pointer. This is now avoided by jumping to failure label. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index c1d66995bdcb..304ae68b05b8 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -1707,6 +1707,7 @@ int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx) if (*pbuf == NULL) { WL_ERROR("fail to alloc %d bytes\n", hdr->len); + goto fail; } bcopy(pdata, *pbuf, hdr->len); return 0; @@ -1715,6 +1716,7 @@ int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx) } WL_ERROR("ERROR: ucode buf tag:%d can not be found!\n", idx); *pbuf = NULL; +fail: return -1; } -- cgit v1.2.3 From e4cf544edb1c6a6287a8ed8d924259825364d40d Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 10 Feb 2011 12:03:46 +0100 Subject: staging: brcm80211: enable driver counter functionality The 802.11 core in the chipsets provides counters that are now used to provide counter values to mac80211 through get_stats callback. Counters related to ampdu and wmm (aka. wme) are not yet incorporated. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 12 +- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 35 +++-- drivers/staging/brcm80211/brcmsmac/wlc_alloc.c | 18 +-- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 11 +- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 20 +-- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 148 +++++++++++++++++----- drivers/staging/brcm80211/brcmsmac/wlc_pub.h | 9 +- drivers/staging/brcm80211/include/wlioctl.h | 4 +- 8 files changed, 174 insertions(+), 83 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index 1dbc94a98a47..6841b3ad8113 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -3568,7 +3568,7 @@ int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) { int res = 0; - wl_cnt_t cnt; + struct wl_cnt cnt; int phy_noise; int rssi; scb_val_t scb_val; @@ -3611,11 +3611,13 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) #endif #if WIRELESS_EXT > 11 - WL_TRACE("wl_iw_get_wireless_stats counters=%zu\n", sizeof(wl_cnt_t)); + WL_TRACE("wl_iw_get_wireless_stats counters=%zu\n", + sizeof(struct wl_cnt)); - memset(&cnt, 0, sizeof(wl_cnt_t)); + memset(&cnt, 0, sizeof(struct wl_cnt)); res = - dev_wlc_bufvar_get(dev, "counters", (char *)&cnt, sizeof(wl_cnt_t)); + dev_wlc_bufvar_get(dev, "counters", (char *)&cnt, + sizeof(struct wl_cnt)); if (res) { WL_ERROR("wl_iw_get_wireless_stats counters failed error=%d\n", res); @@ -3624,7 +3626,7 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) cnt.version = dtoh16(cnt.version); if (cnt.version != WL_CNT_T_VERSION) { - WL_TRACE("\tIncorrect version of counters struct: expected %d; got %d\n", + WL_TRACE("\tIncorrect counter version: expected %d; got %d\n", WL_CNT_T_VERSION, cnt.version); goto done; } diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 304ae68b05b8..d04277bf30a2 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -461,7 +461,16 @@ static int wl_ops_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats) { - WL_ERROR("%s: Enter\n", __func__); + struct wl_info *wl = hw->priv; + struct wl_cnt *cnt; + + WL_LOCK(wl); + cnt = wl->pub->_cnt; + stats->dot11ACKFailureCount = cnt->txnoack; + stats->dot11RTSFailureCount = cnt->txnocts; + stats->dot11FCSErrorCount = cnt->rxcrc; + stats->dot11RTSSuccessCount = cnt->txrts; + WL_UNLOCK(wl); return 0; } @@ -1648,34 +1657,34 @@ void wl_free_timer(struct wl_info *wl, wl_timer_t *t) static int wl_linux_watchdog(void *ctx) { struct wl_info *wl = (struct wl_info *) ctx; + struct wl_cnt *cnt; struct net_device_stats *stats = NULL; uint id; /* refresh stats */ if (wl->pub->up) { ASSERT(wl->stats_id < 2); + cnt = wl->pub->_cnt; id = 1 - wl->stats_id; - stats = &wl->stats_watchdog[id]; - stats->rx_packets = WLCNTVAL(wl->pub->_cnt->rxframe); - stats->tx_packets = WLCNTVAL(wl->pub->_cnt->txframe); - stats->rx_bytes = WLCNTVAL(wl->pub->_cnt->rxbyte); - stats->tx_bytes = WLCNTVAL(wl->pub->_cnt->txbyte); - stats->rx_errors = WLCNTVAL(wl->pub->_cnt->rxerror); - stats->tx_errors = WLCNTVAL(wl->pub->_cnt->txerror); + stats->rx_packets = cnt->rxframe; + stats->tx_packets = cnt->txframe; + stats->rx_bytes = cnt->rxbyte; + stats->tx_bytes = cnt->txbyte; + stats->rx_errors = cnt->rxerror; + stats->tx_errors = cnt->txerror; stats->collisions = 0; stats->rx_length_errors = 0; - stats->rx_over_errors = WLCNTVAL(wl->pub->_cnt->rxoflo); - stats->rx_crc_errors = WLCNTVAL(wl->pub->_cnt->rxcrc); + stats->rx_over_errors = cnt->rxoflo; + stats->rx_crc_errors = cnt->rxcrc; stats->rx_frame_errors = 0; - stats->rx_fifo_errors = WLCNTVAL(wl->pub->_cnt->rxoflo); + stats->rx_fifo_errors = cnt->rxoflo; stats->rx_missed_errors = 0; - stats->tx_fifo_errors = WLCNTVAL(wl->pub->_cnt->txuflo); + stats->tx_fifo_errors = cnt->txuflo; wl->stats_id = id; - } return 0; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c index 7a9fdbb5daee..2db96c1e1701 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c @@ -70,13 +70,13 @@ static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, { struct wlc_pub *pub; - pub = (struct wlc_pub *) wlc_calloc(osh, unit, sizeof(struct wlc_pub)); + pub = wlc_calloc(osh, unit, sizeof(struct wlc_pub)); if (pub == NULL) { *err = 1001; goto fail; } - pub->tunables = (wlc_tunables_t *)wlc_calloc(osh, unit, + pub->tunables = wlc_calloc(osh, unit, sizeof(wlc_tunables_t)); if (pub->tunables == NULL) { *err = 1028; @@ -86,6 +86,10 @@ static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, /* need to init the tunables now */ wlc_tunables_init(pub->tunables, devid); + pub->_cnt = wlc_calloc(osh, unit, sizeof(struct wl_cnt)); + if (pub->_cnt == NULL) + goto fail; + pub->multicast = (u8 *)wlc_calloc(osh, unit, (ETH_ALEN * MAXMULTILIST)); if (pub->multicast == NULL) { @@ -105,13 +109,9 @@ static void wlc_pub_mfree(struct osl_info *osh, struct wlc_pub *pub) if (pub == NULL) return; - if (pub->multicast) - kfree(pub->multicast); - if (pub->tunables) { - kfree(pub->tunables); - pub->tunables = NULL; - } - + kfree(pub->multicast); + kfree(pub->_cnt); + kfree(pub->tunables); kfree(pub); } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index f5ca897c2dea..f6e27f66e415 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -38,6 +38,11 @@ #include #include +/* + * Disable AMPDU statistics counters for now + */ +#define WLCNTINCR(a) +#define WLCNTADD(a, b) #define AMPDU_MAX_MPDU 32 /* max number of mpdus in an ampdu */ #define AMPDU_NUM_MPDU_LEGACY 16 /* max number of mpdus in an ampdu to a legacy */ @@ -1043,10 +1048,10 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, if (supr_status == TX_STATUS_SUPR_BADCH || supr_status == TX_STATUS_SUPR_EXPTIME) { retry = false; - WLCNTINCR(wlc->pub->_cnt->txchanrej); + wlc->pub->_cnt->txchanrej++; } else if (supr_status == TX_STATUS_SUPR_EXPTIME) { - WLCNTINCR(wlc->pub->_cnt->txexptime); + wlc->pub->_cnt->txexptime++; /* TX underflow : try tuning pre-loading or ampdu size */ } else if (supr_status == TX_STATUS_SUPR_FRAG) { @@ -1060,7 +1065,7 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, } } else if (txs->phyerr) { update_rate = false; - WLCNTINCR(wlc->pub->_cnt->txphyerr); + wlc->pub->_cnt->txphyerr++; WL_ERROR("wl%d: wlc_ampdu_dotxstatus: tx phy error (0x%x)\n", wlc->pub->unit, txs->phyerr); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 5f0e7e6f0f8e..607889c4659f 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -383,7 +383,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) /* phy tx error */ if (macintstatus & MI_PHYTXERR) { - WLCNTINCR(wlc->pub->_cnt->txphyerr); + wlc->pub->_cnt->txphyerr++; } /* received data or control frame, MI_DMAINT is indication of RX_FIFO interrupt */ @@ -413,7 +413,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) __func__, wlc_hw->sih->chip, wlc_hw->sih->chiprev); - WLCNTINCR(wlc->pub->_cnt->psmwds); + wlc->pub->_cnt->psmwds++; /* big hammer */ wl_init(wlc->wl); @@ -427,7 +427,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) if (macintstatus & MI_RFDISABLE) { WL_TRACE("wl%d: BMAC Detected a change on the RF Disable Input\n", wlc_hw->unit); - WLCNTINCR(wlc->pub->_cnt->rfdisable); + wlc->pub->_cnt->rfdisable++; wl_rfkill_set_hw_state(wlc->wl); } @@ -1088,7 +1088,7 @@ void wlc_bmac_reset(struct wlc_hw_info *wlc_hw) { WL_TRACE("wl%d: wlc_bmac_reset\n", wlc_hw->unit); - WLCNTINCR(wlc_hw->wlc->pub->_cnt->reset); + wlc_hw->wlc->pub->_cnt->reset++; /* reset the core */ if (!DEVICEREMOVED(wlc_hw->wlc)) @@ -2877,40 +2877,40 @@ void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw) if (intstatus & I_RO) { WL_ERROR("wl%d: fifo %d: receive fifo overflow\n", unit, idx); - WLCNTINCR(wlc_hw->wlc->pub->_cnt->rxoflo); + wlc_hw->wlc->pub->_cnt->rxoflo++; fatal = true; } if (intstatus & I_PC) { WL_ERROR("wl%d: fifo %d: descriptor error\n", unit, idx); - WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmade); + wlc_hw->wlc->pub->_cnt->dmade++; fatal = true; } if (intstatus & I_PD) { WL_ERROR("wl%d: fifo %d: data error\n", unit, idx); - WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmada); + wlc_hw->wlc->pub->_cnt->dmada++; fatal = true; } if (intstatus & I_DE) { WL_ERROR("wl%d: fifo %d: descriptor protocol error\n", unit, idx); - WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmape); + wlc_hw->wlc->pub->_cnt->dmape++; fatal = true; } if (intstatus & I_RU) { WL_ERROR("wl%d: fifo %d: receive descriptor underflow\n", idx, unit); - WLCNTINCR(wlc_hw->wlc->pub->_cnt->rxuflo[idx]); + wlc_hw->wlc->pub->_cnt->rxuflo[idx]++; } if (intstatus & I_XU) { WL_ERROR("wl%d: fifo %d: transmit fifo underflow\n", idx, unit); - WLCNTINCR(wlc_hw->wlc->pub->_cnt->txuflo); + wlc_hw->wlc->pub->_cnt->txuflo++; fatal = true; } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index 5a6a01614116..d2b86a6453d1 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -53,6 +53,12 @@ #include #include +/* + * Disable statistics counting for WME + */ +#define WLCNTSET(a, b) +#define WLCNTINCR(a) +#define WLCNTADD(a, b) /* * WPA(2) definitions @@ -379,13 +385,11 @@ void wlc_reset(struct wlc_info *wlc) wlc->check_for_unaligned_tbtt = false; /* slurp up hw mac counters before core reset */ - if (WLC_UPDATE_STATS(wlc)) { - wlc_statsupd(wlc); + wlc_statsupd(wlc); - /* reset our snapshot of macstat counters */ - memset((char *)wlc->core->macstat_snapshot, 0, - sizeof(macstat_t)); - } + /* reset our snapshot of macstat counters */ + memset((char *)wlc->core->macstat_snapshot, 0, + sizeof(macstat_t)); wlc_bmac_reset(wlc->hw); wlc_ampdu_reset(wlc->ampdu); @@ -1947,8 +1951,8 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, wlc->cfg->wlc = wlc; pub->txmaxpkts = MAXTXPKTS; - WLCNTSET(pub->_cnt->version, WL_CNT_T_VERSION); - WLCNTSET(pub->_cnt->length, sizeof(wl_cnt_t)); + pub->_cnt->version = WL_CNT_T_VERSION; + pub->_cnt->length = sizeof(struct wl_cnt); WLCNTSET(pub->_wme_cnt->version, WL_WME_CNT_VERSION); WLCNTSET(pub->_wme_cnt->length, sizeof(wl_wme_cnt_t)); @@ -2501,8 +2505,7 @@ static void wlc_watchdog(void *arg) wlc_bmac_watchdog(wlc); /* occasionally sample mac stat counters to detect 16-bit counter wrap */ - if ((WLC_UPDATE_STATS(wlc)) - && (!(wlc->pub->now % SW_TIMER_MAC_STAT_UPD))) + if ((wlc->pub->now % SW_TIMER_MAC_STAT_UPD) == 0) wlc_statsupd(wlc); /* Manage TKIP countermeasures timers */ @@ -3855,19 +3858,18 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, case WLC_GET_PKTCNTS:{ get_pktcnt_t *pktcnt = (get_pktcnt_t *) pval; - if (WLC_UPDATE_STATS(wlc)) - wlc_statsupd(wlc); - pktcnt->rx_good_pkt = WLCNTVAL(wlc->pub->_cnt->rxframe); - pktcnt->rx_bad_pkt = WLCNTVAL(wlc->pub->_cnt->rxerror); + wlc_statsupd(wlc); + pktcnt->rx_good_pkt = wlc->pub->_cnt->rxframe; + pktcnt->rx_bad_pkt = wlc->pub->_cnt->rxerror; pktcnt->tx_good_pkt = - WLCNTVAL(wlc->pub->_cnt->txfrmsnt); + wlc->pub->_cnt->txfrmsnt; pktcnt->tx_bad_pkt = - WLCNTVAL(wlc->pub->_cnt->txerror) + - WLCNTVAL(wlc->pub->_cnt->txfail); + wlc->pub->_cnt->txerror + + wlc->pub->_cnt->txfail; if (len >= (int)sizeof(get_pktcnt_t)) { /* Be backward compatible - only if buffer is large enough */ pktcnt->rx_ocast_good_pkt = - WLCNTVAL(wlc->pub->_cnt->rxmfrmocast); + wlc->pub->_cnt->rxmfrmocast; } break; } @@ -4746,12 +4748,28 @@ void wlc_print_txstatus(tx_status_t *txs) #endif /* defined(BCMDBG) */ } +static void +wlc_ctrupd_cache(u16 cur_stat, u16 *macstat_snapshot, u32 *macstat) +{ + u16 v; + u16 delta; + + v = ltoh16(cur_stat); + delta = (u16)(v - *macstat_snapshot); + + if (delta != 0) { + *macstat += delta; + *macstat_snapshot = v; + } +} + #define MACSTATUPD(name) \ wlc_ctrupd_cache(macstats.name, &wlc->core->macstat_snapshot->name, &wlc->pub->_cnt->name) void wlc_statsupd(struct wlc_info *wlc) { int i; + macstat_t macstats; #ifdef BCMDBG u16 delta; u16 rxf0ovfl; @@ -4771,6 +4789,66 @@ void wlc_statsupd(struct wlc_info *wlc) txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i]; #endif /* BCMDBG */ + /* Read mac stats from contiguous shared memory */ + wlc_bmac_copyfrom_shm(wlc->hw, M_UCODE_MACSTAT, + &macstats, sizeof(macstat_t)); + + /* update mac stats */ + MACSTATUPD(txallfrm); + MACSTATUPD(txrtsfrm); + MACSTATUPD(txctsfrm); + MACSTATUPD(txackfrm); + MACSTATUPD(txdnlfrm); + MACSTATUPD(txbcnfrm); + for (i = 0; i < NFIFO; i++) + MACSTATUPD(txfunfl[i]); + MACSTATUPD(txtplunfl); + MACSTATUPD(txphyerr); + MACSTATUPD(rxfrmtoolong); + MACSTATUPD(rxfrmtooshrt); + MACSTATUPD(rxinvmachdr); + MACSTATUPD(rxbadfcs); + MACSTATUPD(rxbadplcp); + MACSTATUPD(rxcrsglitch); + MACSTATUPD(rxstrt); + MACSTATUPD(rxdfrmucastmbss); + MACSTATUPD(rxmfrmucastmbss); + MACSTATUPD(rxcfrmucast); + MACSTATUPD(rxrtsucast); + MACSTATUPD(rxctsucast); + MACSTATUPD(rxackucast); + MACSTATUPD(rxdfrmocast); + MACSTATUPD(rxmfrmocast); + MACSTATUPD(rxcfrmocast); + MACSTATUPD(rxrtsocast); + MACSTATUPD(rxctsocast); + MACSTATUPD(rxdfrmmcast); + MACSTATUPD(rxmfrmmcast); + MACSTATUPD(rxcfrmmcast); + MACSTATUPD(rxbeaconmbss); + MACSTATUPD(rxdfrmucastobss); + MACSTATUPD(rxbeaconobss); + MACSTATUPD(rxrsptmout); + MACSTATUPD(bcntxcancl); + MACSTATUPD(rxf0ovfl); + MACSTATUPD(rxf1ovfl); + MACSTATUPD(rxf2ovfl); + MACSTATUPD(txsfovfl); + MACSTATUPD(pmqovfl); + MACSTATUPD(rxcgprqfrm); + MACSTATUPD(rxcgprsqovfl); + MACSTATUPD(txcgprsfail); + MACSTATUPD(txcgprssuc); + MACSTATUPD(prs_timeout); + MACSTATUPD(rxnack); + MACSTATUPD(frmscons); + MACSTATUPD(txnack); + MACSTATUPD(txglitch_nack); + MACSTATUPD(txburst); + MACSTATUPD(phywatchdog); + MACSTATUPD(pktengrxducast); + MACSTATUPD(pktengrxdmcast); + #ifdef BCMDBG /* check for rx fifo 0 overflow */ delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); @@ -4828,7 +4906,7 @@ void wlc_statsupd(struct wlc_info *wlc) wlc->pub->_cnt->rxgiant + wlc->pub->_cnt->rxnoscb + wlc->pub->_cnt->rxbadsrcmac); for (i = 0; i < NFIFO; i++) - WLCNTADD(wlc->pub->_cnt->rxerror, wlc->pub->_cnt->rxuflo[i]); + wlc->pub->_cnt->rxerror += wlc->pub->_cnt->rxuflo[i]; } bool wlc_chipmatch(u16 vendor, u16 device) @@ -5075,7 +5153,7 @@ wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, ASSERT(0); pkt_buf_free_skb(wlc->osh, p, true); - WLCNTINCR(wlc->pub->_cnt->txnobuf); + wlc->pub->_cnt->txnobuf++; } /* Enqueue */ @@ -5108,7 +5186,7 @@ void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, /* ASSERT(9 == 8); *//* XXX we might hit this condtion in case packet flooding from mac80211 stack */ pkt_buf_free_skb(wlc->osh, sdu, true); - WLCNTINCR(wlc->pub->_cnt->txnobuf); + wlc->pub->_cnt->txnobuf++; } /* Check if flow control needs to be turned on after enqueuing the packet @@ -5160,7 +5238,7 @@ wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, wlc_txq_enq(wlc, scb, pkt, WLC_PRIO_TO_PREC(prio)); wlc_send_q(wlc, wlc->active_queue); - WLCNTINCR(wlc->pub->_cnt->ieee_tx); + wlc->pub->_cnt->ieee_tx++; return 0; } @@ -6207,7 +6285,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, || !IS_MCS(rspec[0])); if (RSPEC2RATE(rspec[0]) != WLC_RATE_1M) phyctl |= PHY_TXC_SHORT_HDR; - WLCNTINCR(wlc->pub->_cnt->txprshort); + wlc->pub->_cnt->txprshort++; } /* phytxant is properly bit shifted */ @@ -6355,7 +6433,7 @@ void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs) { wlc_bsscfg_t *cfg = wlc->cfg; - WLCNTINCR(wlc->pub->_cnt->tbtt); + wlc->pub->_cnt->tbtt++; if (BSSCFG_STA(cfg)) { /* run watchdog here if the watchdog timer is not armed */ @@ -6473,7 +6551,7 @@ void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus) __func__, wlc->pub->sih->chip, wlc->pub->sih->chiprev); - WLCNTINCR(wlc->pub->_cnt->psmwds); + wlc->pub->_cnt->psmwds++; /* big hammer */ wl_init(wlc->wl); @@ -6531,7 +6609,7 @@ static void *wlc_15420war(struct wlc_info *wlc, uint queue) /* if tx ring is now empty, reset and re-init the tx dma channel */ if (dma_txactive(wlc->hw->di[queue]) == 0) { - WLCNTINCR(wlc->pub->_cnt->txdmawar); + wlc->pub->_cnt->txdmawar++; if (!dma_txreset(di)) WL_ERROR("wl%d: %s: dma_txreset[%d]: cannot stop dma\n", wlc->pub->unit, __func__, queue); @@ -6633,9 +6711,9 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) if (N_ENAB(wlc->pub)) { u8 *plcp = (u8 *) (txh + 1); if (PLCP3_ISSGI(plcp[3])) - WLCNTINCR(wlc->pub->_cnt->txmpdu_sgi); + wlc->pub->_cnt->txmpdu_sgi++; if (PLCP3_ISSTBC(plcp[3])) - WLCNTINCR(wlc->pub->_cnt->txmpdu_stbc); + wlc->pub->_cnt->txmpdu_stbc++; } if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { @@ -6707,7 +6785,7 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) skb_pull(p, D11_PHY_HDR_LEN); skb_pull(p, D11_TXH_LEN); ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); - WLCNTINCR(wlc->pub->_cnt->ieee_tx_status); + wlc->pub->_cnt->ieee_tx_status++; } else { WL_ERROR("%s: Not last frame => not calling tx_status\n", __func__); @@ -6985,7 +7063,7 @@ wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, d11rxhdr_t *rxh, memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status)); ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p); - WLCNTINCR(wlc->pub->_cnt->ieee_rx); + wlc->pub->_cnt->ieee_rx++; osh->pktalloced--; return; } @@ -7041,7 +7119,7 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ if (rxh->RxStatus1 & RXS_PBPRES) { if (p->len < 2) { - WLCNTINCR(wlc->pub->_cnt->rxrunt); + wlc->pub->_cnt->rxrunt++; WL_ERROR("wl%d: wlc_recv: rcvd runt of len %d\n", wlc->pub->unit, p->len); goto toss; @@ -7066,7 +7144,7 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) if (len >= D11_PHY_HDR_LEN + sizeof(h->frame_control)) { fc = ltoh16(h->frame_control); } else { - WLCNTINCR(wlc->pub->_cnt->rxrunt); + wlc->pub->_cnt->rxrunt++; goto toss; } @@ -7082,10 +7160,10 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) WL_ERROR("wl%d: %s: dropping a frame with " "invalid src mac address, a2: %pM\n", wlc->pub->unit, __func__, h->addr2); - WLCNTINCR(wlc->pub->_cnt->rxbadsrcmac); + wlc->pub->_cnt->rxbadsrcmac++; goto toss; } - WLCNTINCR(wlc->pub->_cnt->rxfrag); + wlc->pub->_cnt->rxfrag++; } } @@ -7884,7 +7962,7 @@ int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) if ((ltoh16(txh->MacFrameControl) & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) - WLCNTINCR(wlc->pub->_cnt->txctl); + wlc->pub->_cnt->txctl++; return 0; } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h index e059ebf101c4..4d0e0b13e3a9 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h @@ -17,6 +17,7 @@ #ifndef _wlc_pub_h_ #define _wlc_pub_h_ +#include #include #include @@ -326,6 +327,8 @@ struct wlc_pub { bool _lmacproto; /* lmac protocol module included and enabled */ bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */ bool _ampdumac; /* mac assist ampdu enabled or not */ + + struct wl_cnt *_cnt; /* low-level counters in driver */ }; /* wl_monitor rx status per packet */ @@ -477,12 +480,6 @@ extern const u8 wme_fifo2ac[]; #define WLC_USE_COREFLAGS 0xffffffff /* invalid core flags, use the saved coreflags */ -#define WLC_UPDATE_STATS(wlc) 0 /* No stats support */ -#define WLCNTINCR(a) /* No stats support */ -#define WLCNTDECR(a) /* No stats support */ -#define WLCNTADD(a, delta) /* No stats support */ -#define WLCNTSET(a, value) /* No stats support */ -#define WLCNTVAL(a) 0 /* No stats support */ /* common functions for every port */ extern void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, diff --git a/drivers/staging/brcm80211/include/wlioctl.h b/drivers/staging/brcm80211/include/wlioctl.h index 0f79863d08af..2de49b84cb63 100644 --- a/drivers/staging/brcm80211/include/wlioctl.h +++ b/drivers/staging/brcm80211/include/wlioctl.h @@ -1262,7 +1262,7 @@ struct tsinfo_arg { #define WL_CNT_T_VERSION 7 /* current version of wl_cnt_t struct */ -typedef struct { +struct wl_cnt { u16 version; /* see definition of WL_CNT_T_VERSION */ u16 length; /* length of entire structure */ @@ -1492,7 +1492,7 @@ typedef struct { u32 rxmpdu_sgi; /* count for sgi received */ u32 txmpdu_stbc; /* count for stbc transmit */ u32 rxmpdu_stbc; /* count for stbc received */ -} wl_cnt_t; +}; #define WL_DELTA_STATS_T_VERSION 1 /* current version of wl_delta_stats_t struct */ -- cgit v1.2.3 From 4191e2d56458cdc9a31de68c8a8ff55a04242f9c Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 10 Feb 2011 12:03:47 +0100 Subject: staging: brcm80211: cleanup mac80211 callback bss_info_changed The implementation for bss_info_changed was not handling all changes as provided by mac80211 module. These have been added and will log message with changed parameters. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 37 +++++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index d04277bf30a2..e485280c9c5d 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -365,12 +365,12 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_BEACON_INT) { /* Beacon interval changed */ - WL_NONE("%s: Beacon Interval: %d\n", + WL_NONE("%s: Beacon Interval: %d (implement)\n", __func__, info->beacon_int); } if (changed & BSS_CHANGED_BSSID) { /* BSSID changed, for whatever reason (IBSS and managed mode) */ - WL_NONE("new BSSID:\taid %d bss:%pM\n", + WL_NONE("%s: new BSSID: aid %d bss:%pM\n", __func__, info->aid, info->bssid); /* FIXME: need to store bssid in bsscfg */ wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, @@ -378,13 +378,42 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_BEACON) { /* Beacon data changed, retrieve new beacon (beaconing modes) */ - WL_ERROR("BSS_CHANGED_BEACON\n"); + WL_ERROR("%s: beacon changed\n", __func__); } if (changed & BSS_CHANGED_BEACON_ENABLED) { /* Beaconing should be enabled/disabled (beaconing modes) */ - WL_ERROR("Beacon enabled: %s\n", + WL_ERROR("%s: Beacon enabled: %s\n", __func__, info->enable_beacon ? "true" : "false"); } + if (changed & BSS_CHANGED_CQM) { + /* Connection quality monitor config changed */ + WL_ERROR("%s: cqm change: threshold %d, hys %d (implement)\n", + __func__, info->cqm_rssi_thold, info->cqm_rssi_hyst); + } + if (changed & BSS_CHANGED_IBSS) { + /* IBSS join status changed */ + WL_ERROR("%s: IBSS joined: %s (implement)\n", __func__, + info->ibss_joined ? "true" : "false"); + } + if (changed & BSS_CHANGED_ARP_FILTER) { + /* Hardware ARP filter address list or state changed */ + WL_ERROR("%s: arp filtering: enabled %s, count %d (implement)\n", + __func__, info->arp_filter_enabled ? "true" : "false", + info->arp_addr_cnt); + } + if (changed & BSS_CHANGED_QOS) { + /* + * QoS for this association was enabled/disabled. + * Note that it is only ever disabled for station mode. + */ + WL_ERROR("%s: qos enabled: %s (implement)\n", __func__, + info->qos ? "true" : "false"); + } + if (changed & BSS_CHANGED_IDLE) { + /* Idle changed for this BSS/interface */ + WL_ERROR("%s: BSS idle: %s (implement)\n", __func__, + info->idle ? "true" : "false"); + } return; } -- cgit v1.2.3 From d8a1fb44abc3e022419ecf8c51acf53b9b78e848 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 10 Feb 2011 12:03:48 +0100 Subject: staging: brcm80211: handle change in association state from mac80211 The driver has flags for association state which are now being set according to notification from mac80211. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 1 + drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 6 ++++++ drivers/staging/brcm80211/brcmsmac/wlc_pub.h | 1 + 3 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index e485280c9c5d..a51e511ce69f 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -333,6 +333,7 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, */ WL_ERROR("%s: %s: %sassociated\n", KBUILD_MODNAME, __func__, info->assoc ? "" : "dis"); + wlc_associate_upd(wl->wlc, info->assoc); } if (changed & BSS_CHANGED_ERP_CTS_PROT) { /* CTS protection changed */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index d2b86a6453d1..76d78c18bf8a 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -8590,3 +8590,9 @@ void wlc_scan_stop(struct wlc_info *wlc) { wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false); } + +void wlc_associate_upd(struct wlc_info *wlc, bool state) +{ + wlc->pub->associated = state; + wlc->cfg->associated = state; +} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h index 4d0e0b13e3a9..4b43c3ce42e6 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h @@ -563,6 +563,7 @@ extern void wlc_enable_mac(struct wlc_info *wlc); extern u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate); extern u32 wlc_get_rspec_history(struct wlc_bsscfg *cfg); extern u32 wlc_get_current_highest_rate(struct wlc_bsscfg *cfg); +extern void wlc_associate_upd(struct wlc_info *wlc, bool state); extern void wlc_scan_start(struct wlc_info *wlc); extern void wlc_scan_stop(struct wlc_info *wlc); -- cgit v1.2.3 From e0caf15007aed3ede132847b708c2335c5c9507e Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 10 Feb 2011 12:03:49 +0100 Subject: staging: brcm80211: store HT operation mode settings from mac80211 The HT operation mode is provided by mac80211 and they are now stored in the driver. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 8 +++++++- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h | 14 -------------- drivers/staging/brcm80211/brcmsmac/wlc_pub.h | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index a51e511ce69f..d02b6bb18a18 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -357,7 +357,13 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_HT) { /* 802.11n parameters changed */ u16 mode = info->ht_operation_mode; - WL_NONE("%s: HT mode: 0x%04X (implement)\n", __func__, mode); + WL_NONE("%s: HT mode: 0x%04X\n", __func__, mode); + wlc_protection_upd(wl->wlc, WLC_PROT_N_CFG, + mode & IEEE80211_HT_OP_MODE_PROTECTION); + wlc_protection_upd(wl->wlc, WLC_PROT_N_NONGF, + mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); + wlc_protection_upd(wl->wlc, WLC_PROT_N_OBSS, + mode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT); } if (changed & BSS_CHANGED_BASIC_RATES) { /* Basic rateset changed */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h index 5817a49f460e..0aeb9c62c727 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h @@ -29,19 +29,6 @@ #define MAXCOREREV 28 /* max # supported core revisions (0 .. MAXCOREREV - 1) */ #define WLC_MAXMODULES 22 /* max # wlc_module_register() calls */ -/* network protection config */ -#define WLC_PROT_G_SPEC 1 /* SPEC g protection */ -#define WLC_PROT_G_OVR 2 /* SPEC g prot override */ -#define WLC_PROT_G_USER 3 /* gmode specified by user */ -#define WLC_PROT_OVERLAP 4 /* overlap */ -#define WLC_PROT_N_USER 10 /* nmode specified by user */ -#define WLC_PROT_N_CFG 11 /* n protection */ -#define WLC_PROT_N_CFG_OVR 12 /* n protection override */ -#define WLC_PROT_N_NONGF 13 /* non-GF protection */ -#define WLC_PROT_N_NONGF_OVR 14 /* non-GF protection override */ -#define WLC_PROT_N_PAM_OVR 15 /* n preamble override */ -#define WLC_PROT_N_OBSS 16 /* non-HT OBSS present */ - #define WLC_BITSCNT(x) bcm_bitcount((u8 *)&(x), sizeof(u8)) /* Maximum wait time for a MAC suspend */ @@ -847,7 +834,6 @@ extern void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax); extern void wlc_fifoerrors(struct wlc_info *wlc); extern void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit); extern void wlc_reset_bmac_done(struct wlc_info *wlc); -extern void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val); extern void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us); extern void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h index 4b43c3ce42e6..ded018adda69 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h @@ -481,6 +481,19 @@ extern const u8 wme_fifo2ac[]; #define WLC_USE_COREFLAGS 0xffffffff /* invalid core flags, use the saved coreflags */ +/* network protection config */ +#define WLC_PROT_G_SPEC 1 /* SPEC g protection */ +#define WLC_PROT_G_OVR 2 /* SPEC g prot override */ +#define WLC_PROT_G_USER 3 /* gmode specified by user */ +#define WLC_PROT_OVERLAP 4 /* overlap */ +#define WLC_PROT_N_USER 10 /* nmode specified by user */ +#define WLC_PROT_N_CFG 11 /* n protection */ +#define WLC_PROT_N_CFG_OVR 12 /* n protection override */ +#define WLC_PROT_N_NONGF 13 /* non-GF protection */ +#define WLC_PROT_N_NONGF_OVR 14 /* non-GF protection override */ +#define WLC_PROT_N_PAM_OVR 15 /* n preamble override */ +#define WLC_PROT_N_OBSS 16 /* non-HT OBSS present */ + /* common functions for every port */ extern void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, struct osl_info *osh, void *regsva, @@ -514,6 +527,7 @@ extern int wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, struct wlc_if *wlcif); /* helper functions */ extern void wlc_statsupd(struct wlc_info *wlc); +extern void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val); extern int wlc_get_header_len(void); extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc); extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, -- cgit v1.2.3 From c234656fa33224860f648fba3e35f0b80cbe53d4 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 10 Feb 2011 12:03:50 +0100 Subject: staging: brcm80211: set beacon interval as provided by mac80211 Driver now follows beacon interval as set by mac80211 callback. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index d02b6bb18a18..da86103665db 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -372,8 +372,9 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_BEACON_INT) { /* Beacon interval changed */ - WL_NONE("%s: Beacon Interval: %d (implement)\n", + WL_NONE("%s: Beacon Interval: %d\n", __func__, info->beacon_int); + wlc_set(wl->wlc, WLC_SET_BCNPRD, info->beacon_int); } if (changed & BSS_CHANGED_BSSID) { /* BSSID changed, for whatever reason (IBSS and managed mode) */ -- cgit v1.2.3 From 6677eaa335680f75fdc3aa1dae7557f1ed446491 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 10 Feb 2011 12:03:51 +0100 Subject: staging: brcm80211: store BSSID in driver config information When mac80211 informs about new BSSID this was configured toward the hardware device, but the information is also needed inside the driver itself. This patch takes care of that. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index da86103665db..55ea876ce5fa 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -380,7 +380,6 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, /* BSSID changed, for whatever reason (IBSS and managed mode) */ WL_NONE("%s: new BSSID: aid %d bss:%pM\n", __func__, info->aid, info->bssid); - /* FIXME: need to store bssid in bsscfg */ wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid); } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index 76d78c18bf8a..a25b9d921555 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -8342,6 +8343,8 @@ wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, const u8 *addr) { wlc_bmac_set_addrmatch(wlc->hw, match_reg_offset, addr); + if (match_reg_offset == RCM_BSSID_OFFSET) + memcpy(wlc->cfg->BSSID, addr, ETH_ALEN); } void wlc_set_rcmta(struct wlc_info *wlc, int idx, const u8 *addr) -- cgit v1.2.3 From cf60191a2d527065348bb315b1d650a086dde94b Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 10 Feb 2011 12:03:52 +0100 Subject: staging: brcm80211: remove unnecessary cast in wlc_d11hdrs_mac80211 memset prototype specifies a void pointer as buffer. Conversion from any pointer type to void pointer does not require an explicit cast. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index a25b9d921555..4515f17da41a 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -5824,7 +5824,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* add Broadcom tx descriptor header */ txh = (d11txh_t *) skb_push(p, D11_TXH_LEN); - memset((char *)txh, 0, D11_TXH_LEN); + memset(txh, 0, D11_TXH_LEN); /* setup frameid */ if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { -- cgit v1.2.3 From 77919fd72e96cb75ed1b3fc0921a6b5cef5f8042 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 10 Feb 2011 15:27:44 +0100 Subject: staging: brcm80211: remove warning introduced by rfkill implementation During rfkill implementation the content of wlc_radio_upd function was removed for testing purposes only. This ended up in the patch sent out. This commit restores the function content, which was the only function calling static function wlc_radio_enable. This removes the compilation warning observed. Reviewed-by: Brett Rudley Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index 4515f17da41a..96e6ce41fca4 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -2311,6 +2311,11 @@ void wlc_radio_mpc_upd(struct wlc_info *wlc) */ static void wlc_radio_upd(struct wlc_info *wlc) { + if (wlc->pub->radio_disabled) { + wlc_radio_disable(wlc); + } else { + wlc_radio_enable(wlc); + } } /* maintain LED behavior in down state */ -- cgit v1.2.3 From bc042b67261043a93cfe2f311ffe5568a0b29017 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 10 Feb 2011 15:27:45 +0100 Subject: staging: brcm80211: remove #ifdef BCMDBG from regular functions Under error condition debug functions are being called which only have implementation when BCMDBG is defined. This result in #ifdef BCMDBG blocks in functions. This patch fixes this by mapping the debug functions to empty macro when BCMDBG is not defined. This makes the calling function easier to read. Reviewed-by: Brett Rudley Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 4 +--- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 16 +++++++--------- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h | 2 ++ drivers/staging/brcm80211/include/bcmutils.h | 3 +++ 4 files changed, 13 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index f6e27f66e415..f344e383d5c9 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -1069,13 +1069,11 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, WL_ERROR("wl%d: wlc_ampdu_dotxstatus: tx phy error (0x%x)\n", wlc->pub->unit, txs->phyerr); -#ifdef BCMDBG if (WL_ERROR_ON()) { prpkt("txpkt (AMPDU)", wlc->osh, p); wlc_print_txdesc((d11txh_t *) p->data); - wlc_print_txstatus(txs); } -#endif /* BCMDBG */ + wlc_print_txstatus(txs); } } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index 96e6ce41fca4..bb7d74ef51c1 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -222,6 +222,8 @@ static bool in_send_q = false; static const char *fifo_names[] = { "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; const char *aci_names[] = { "AC_BE", "AC_BK", "AC_VI", "AC_VO" }; +#else +static const char fifo_names[6][0]; #endif static const u8 acbitmap2maxprio[] = { @@ -6414,7 +6416,6 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, (u16) newfragthresh; } } -#if defined(BCMDBG) } else WL_ERROR("wl%d: %s txop invalid for rate %d\n", wlc->pub->unit, fifo_names[queue], @@ -6426,9 +6427,6 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, fifo_names[queue], phylen, wlc->fragthresh[queue], dur, wlc->edcf_txop[ac]); -#else - } -#endif } } @@ -6696,11 +6694,11 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) mcl = ltoh16(txh->MacTxControlLow); if (txs->phyerr) { - WL_ERROR("phyerr 0x%x, rate 0x%x\n", - txs->phyerr, txh->MainRates); -#if defined(BCMDBG) - wlc_print_txdesc(txh); -#endif + if (WL_ERROR_ON()) { + WL_ERROR("phyerr 0x%x, rate 0x%x\n", + txs->phyerr, txh->MainRates); + wlc_print_txdesc(txh); + } wlc_print_txstatus(txs); } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h index 0aeb9c62c727..0f6fccab69af 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h @@ -842,6 +842,8 @@ extern void wlc_print_rxh(d11rxhdr_t *rxh); extern void wlc_print_hdrs(struct wlc_info *wlc, const char *prefix, u8 *frame, d11txh_t *txh, d11rxhdr_t *rxh, uint len); extern void wlc_print_txdesc(d11txh_t *txh); +#else +#define wlc_print_txdesc(a) #endif #if defined(BCMDBG) extern void wlc_print_dot11_mac_hdr(u8 *buf, int len); diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h index 8e7f2ea6f2ef..b8c800abd30e 100644 --- a/drivers/staging/brcm80211/include/bcmutils.h +++ b/drivers/staging/brcm80211/include/bcmutils.h @@ -152,7 +152,10 @@ extern struct sk_buff *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); #ifdef BCMDBG extern void prpkt(const char *msg, struct osl_info *osh, struct sk_buff *p0); +#else +#define prpkt(a, b, c) #endif /* BCMDBG */ + #define bcm_perf_enable() #define bcmstats(fmt) #define bcmlog(fmt, a1, a2) -- cgit v1.2.3 From aba0586c8af11e563f9c380ac4a0d4cbdd2e504c Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 10 Feb 2011 15:27:46 +0100 Subject: staging: brcm80211: remove declaration of unused string array The constant array declaration aci_names is not referenced anywhere in the code so it has been removed. Reviewed-by: Brett Rudley Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index bb7d74ef51c1..0c5d37bb81fb 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -221,7 +221,6 @@ static bool in_send_q = false; #ifdef BCMDBG static const char *fifo_names[] = { "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; -const char *aci_names[] = { "AC_BE", "AC_BK", "AC_VI", "AC_VO" }; #else static const char fifo_names[6][0]; #endif -- cgit v1.2.3 From 7234592364e2efe8b4ac1040c99b1d7ef01cf502 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Mon, 14 Feb 2011 12:16:45 +0100 Subject: staging: brcm80211: removal of inactive d11 code Code cleanup. Removed code that was never invoked because the mac core revision supported is always higher than 22. Signed-off-by: Roland Vossen Reviewed-by: Arend van Spriel Reviewed-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 259 ++++------------------ drivers/staging/brcm80211/brcmsmac/wlc_key.h | 5 +- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 56 +---- 3 files changed, 54 insertions(+), 266 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 607889c4659f..a11eba722abb 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -254,9 +254,6 @@ static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit) ASSERT(wlc_hw->clk); - if (D11REV_LT(wlc_hw->corerev, 17)) - tmp = R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol); - wlc_bmac_core_phy_clk(wlc_hw, OFF); wlc_setxband(wlc_hw, bandunit); @@ -467,9 +464,6 @@ void wlc_bmac_watchdog(void *arg) /* make sure RX dma has buffers */ dma_rxfill(wlc->hw->di[RX_FIFO]); - if (D11REV_IS(wlc_hw->corerev, 4)) { - dma_rxfill(wlc->hw->di[RX_TXSTATUS_FIFO]); - } wlc_phy_watchdog(wlc_hw->band->pi); } @@ -606,23 +600,11 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) */ ASSERT(TX_AC_VO_FIFO == 3); ASSERT(TX_CTL_FIFO == 3); - if (D11REV_IS(wlc_hw->corerev, 4)) { - ASSERT(RX_TXSTATUS_FIFO == 3); - wlc_hw->di[3] = dma_attach(osh, name, wlc_hw->sih, - DMAREG(wlc_hw, DMA_TX, 3), - DMAREG(wlc_hw, DMA_RX, 3), - tune->ntxd, tune->nrxd, - sizeof(tx_status_t), -1, - tune->nrxbufpost, 0, - &wl_msg_level); - dma_attach_err |= (NULL == wlc_hw->di[3]); - } else { - wlc_hw->di[3] = dma_attach(osh, name, wlc_hw->sih, - DMAREG(wlc_hw, DMA_TX, 3), - NULL, tune->ntxd, 0, 0, -1, - 0, 0, &wl_msg_level); - dma_attach_err |= (NULL == wlc_hw->di[3]); - } + wlc_hw->di[3] = dma_attach(osh, name, wlc_hw->sih, + DMAREG(wlc_hw, DMA_TX, 3), + NULL, tune->ntxd, 0, 0, -1, + 0, 0, &wl_msg_level); + dma_attach_err |= (NULL == wlc_hw->di[3]); /* Cleaner to leave this as if with AP defined */ if (dma_attach_err) { @@ -792,8 +774,7 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc_hw->boardflags = (u32) getintvar(vars, "boardflags"); wlc_hw->boardflags2 = (u32) getintvar(vars, "boardflags2"); - if (D11REV_LE(wlc_hw->corerev, 4) - || (wlc_hw->boardflags & BFL_NOPLLDOWN)) + if (wlc_hw->boardflags & BFL_NOPLLDOWN) wlc_bmac_pllreq(wlc_hw, true, WLC_PLLREQ_SHARED); if ((wlc_hw->sih->bustype == PCI_BUS) @@ -879,10 +860,8 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G; wlc->core->coreidx = si_coreidx(wlc_hw->sih); - if (D11REV_GE(wlc_hw->corerev, 13)) { - wlc_hw->machwcap = R_REG(wlc_hw->osh, ®s->machwcap); - wlc_hw->machwcap_backup = wlc_hw->machwcap; - } + wlc_hw->machwcap = R_REG(wlc_hw->osh, ®s->machwcap); + wlc_hw->machwcap_backup = wlc_hw->machwcap; /* init tx fifo size */ ASSERT((wlc_hw->corerev - XMTFIFOTBL_STARTREV) < @@ -1288,16 +1267,12 @@ int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw) void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw) { - if (D11REV_IS(wlc_hw->corerev, 4)) /* no slowclock */ - udelay(5); - else { - /* delay before first read of ucode state */ - udelay(40); + /* delay before first read of ucode state */ + udelay(40); - /* wait until ucode is no longer asleep */ - SPINWAIT((wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) == - DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly); - } + /* wait until ucode is no longer asleep */ + SPINWAIT((wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) == + DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly); ASSERT(wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) != DBGST_ASLEEP); } @@ -1362,7 +1337,7 @@ static void wlc_clkctl_clk(struct wlc_hw_info *wlc_hw, uint mode) * then use FCA to verify mac is running fast clock */ - wakeup_ucode = D11REV_LT(wlc_hw->corerev, 9); + wakeup_ucode = false; if (wlc_hw->up && wakeup_ucode) wlc_ucode_wake_override_set(wlc_hw, @@ -1370,19 +1345,8 @@ static void wlc_clkctl_clk(struct wlc_hw_info *wlc_hw, uint mode) wlc_hw->forcefastclk = si_clkctl_cc(wlc_hw->sih, mode); - if (D11REV_LT(wlc_hw->corerev, 11)) { - /* ucode WAR for old chips */ - if (wlc_hw->forcefastclk) - wlc_bmac_mhf(wlc_hw, MHF1, MHF1_FORCEFASTCLK, - MHF1_FORCEFASTCLK, WLC_BAND_ALL); - else - wlc_bmac_mhf(wlc_hw, MHF1, MHF1_FORCEFASTCLK, 0, - WLC_BAND_ALL); - } - /* check fast clock is available (if core is not in reset) */ - if (D11REV_GT(wlc_hw->corerev, 4) && wlc_hw->forcefastclk - && wlc_hw->clk) + if (wlc_hw->forcefastclk && wlc_hw->clk) ASSERT(si_core_sflags(wlc_hw->sih, 0, 0) & SISF_FCLKA); /* keep the ucode wake bit on if forcefastclk is on @@ -1803,8 +1767,6 @@ void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw) wlc_phy_bw_state_set(wlc_hw->band->pi, bw); ASSERT(wlc_hw->clk); - if (D11REV_LT(wlc_hw->corerev, 17)) - tmp = R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol); wlc_bmac_phy_reset(wlc_hw); wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi)); @@ -2170,15 +2132,11 @@ bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw) /* may need to take core out of reset first */ clk = wlc_hw->clk; if (!clk) { - if (D11REV_LE(wlc_hw->corerev, 11)) - resetbits |= SICF_PCLKE; - /* * corerev >= 18, mac no longer enables phyclk automatically when driver accesses * phyreg throughput mac. This can be skipped since only mac reg is accessed below */ - if (D11REV_GE(wlc_hw->corerev, 18)) - flags |= SICF_PCLKE; + flags |= SICF_PCLKE; /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */ if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || @@ -2249,26 +2207,6 @@ void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw) static bool wlc_dma_rxreset(struct wlc_hw_info *wlc_hw, uint fifo) { struct hnddma_pub *di = wlc_hw->di[fifo]; - struct osl_info *osh; - - if (D11REV_LT(wlc_hw->corerev, 12)) { - bool rxidle = true; - u16 rcv_frm_cnt = 0; - - osh = wlc_hw->osh; - - W_REG(osh, &wlc_hw->regs->rcv_fifo_ctl, fifo << 8); - SPINWAIT((!(rxidle = dma_rxidle(di))) && - ((rcv_frm_cnt = - R_REG(osh, &wlc_hw->regs->rcv_frm_cnt)) != 0), - 50000); - - if (!rxidle && (rcv_frm_cnt != 0)) - WL_ERROR("wl%d: %s: rxdma[%d] not idle && rcv_frm_cnt(%d) not zero\n", - wlc_hw->unit, __func__, fifo, rcv_frm_cnt); - mdelay(2); - } - return dma_rxreset(di); } @@ -2312,12 +2250,6 @@ void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags) WL_ERROR("wl%d: %s: dma_rxreset[%d]: cannot stop dma\n", wlc_hw->unit, __func__, RX_FIFO); } - if (D11REV_IS(wlc_hw->corerev, 4) - && wlc_hw->di[RX_TXSTATUS_FIFO] - && (!wlc_dma_rxreset(wlc_hw, RX_TXSTATUS_FIFO))) { - WL_ERROR("wl%d: %s: dma_rxreset[%d]: cannot stop dma\n", - wlc_hw->unit, __func__, RX_TXSTATUS_FIFO); - } } /* if noreset, just stop the psm and return */ if (wlc_hw->noreset) { @@ -2326,16 +2258,12 @@ void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags) return; } - if (D11REV_LE(wlc_hw->corerev, 11)) - resetbits |= SICF_PCLKE; - /* - * corerev >= 18, mac no longer enables phyclk automatically when driver accesses phyreg - * throughput mac, AND phy_reset is skipped at early stage when band->pi is invalid - * need to enable PHY CLK + * mac no longer enables phyclk automatically when driver accesses + * phyreg throughput mac, AND phy_reset is skipped at early stage when + * band->pi is invalid. need to enable PHY CLK */ - if (D11REV_GE(wlc_hw->corerev, 18)) - flags |= SICF_PCLKE; + flags |= SICF_PCLKE; /* reset the core * In chips with PMU, the fastclk request goes through d11 core reg 0x1e0, which @@ -2381,9 +2309,6 @@ static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw) u16 txfifo_cmd; struct osl_info *osh; - if (D11REV_LT(wlc_hw->corerev, 9)) - goto exit; - /* tx fifos start at TXFIFO_START_BLK from the Base address */ txfifo_startblk = TXFIFO_START_BLK; @@ -2403,8 +2328,7 @@ static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw) W_REG(osh, ®s->xmtfifocmd, txfifo_cmd); W_REG(osh, ®s->xmtfifodef, txfifo_def); - if (D11REV_GE(wlc_hw->corerev, 16)) - W_REG(osh, ®s->xmtfifodef1, txfifo_def1); + W_REG(osh, ®s->xmtfifodef1, txfifo_def1); W_REG(osh, ®s->xmtfifocmd, txfifo_cmd); @@ -2454,12 +2378,9 @@ static void wlc_coreinit(struct wlc_info *wlc) wlc_ucode_download(wlc_hw); /* - * FIFOSZ fixup - * 1) core5-9 use ucode 5 to save space since the PSM is the same - * 2) newer chips, driver wants to controls the fifo allocation + * FIFOSZ fixup. driver wants to controls the fifo allocation. */ - if (D11REV_GE(wlc_hw->corerev, 4)) - fifosz_fixup = true; + fifosz_fixup = true; /* let the PSM run to the suspended state, set mode to BSS STA */ W_REG(osh, ®s->macintstatus, -1); @@ -2536,12 +2457,7 @@ static void wlc_coreinit(struct wlc_info *wlc) if (err != 0) { WL_ERROR("wlc_coreinit: txfifo mismatch: ucode size %d driver size %d index %d\n", buf[i], wlc_hw->xmtfifo_sz[i], i); - /* DO NOT ASSERT corerev < 4 even there is a mismatch - * shmem, since driver don't overwrite those chip and - * ucode initialize data will be used. - */ - if (D11REV_GE(wlc_hw->corerev, 4)) - ASSERT(0); + ASSERT(0); } /* make sure we can still talk to the mac */ @@ -2555,8 +2471,6 @@ static void wlc_coreinit(struct wlc_info *wlc) /* enable one rx interrupt per received frame */ W_REG(osh, ®s->intrcvlazy[0], (1 << IRL_FC_SHIFT)); - if (D11REV_IS(wlc_hw->corerev, 4)) - W_REG(osh, ®s->intrcvlazy[3], (1 << IRL_FC_SHIFT)); /* set the station mode (BSS STA) */ wlc_bmac_mctrl(wlc_hw, @@ -2571,30 +2485,23 @@ static void wlc_coreinit(struct wlc_info *wlc) /* write interrupt mask */ W_REG(osh, ®s->intctrlregs[RX_FIFO].intmask, DEF_RXINTMASK); - if (D11REV_IS(wlc_hw->corerev, 4)) - W_REG(osh, ®s->intctrlregs[RX_TXSTATUS_FIFO].intmask, - DEF_RXINTMASK); /* allow the MAC to control the PHY clock (dynamic on/off) */ wlc_bmac_macphyclk_set(wlc_hw, ON); /* program dynamic clock control fast powerup delay register */ - if (D11REV_GT(wlc_hw->corerev, 4)) { - wlc->fastpwrup_dly = si_clkctl_fast_pwrup_delay(wlc_hw->sih); - W_REG(osh, ®s->scc_fastpwrup_dly, wlc->fastpwrup_dly); - } + wlc->fastpwrup_dly = si_clkctl_fast_pwrup_delay(wlc_hw->sih); + W_REG(osh, ®s->scc_fastpwrup_dly, wlc->fastpwrup_dly); /* tell the ucode the corerev */ wlc_bmac_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev); /* tell the ucode MAC capabilities */ - if (D11REV_GE(wlc_hw->corerev, 13)) { - wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_L, - (u16) (wlc_hw->machwcap & 0xffff)); - wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_H, - (u16) ((wlc_hw-> - machwcap >> 16) & 0xffff)); - } + wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_L, + (u16) (wlc_hw->machwcap & 0xffff)); + wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_H, + (u16) ((wlc_hw-> + machwcap >> 16) & 0xffff)); /* write retry limits to SCR, this done after PSM init */ W_REG(osh, ®s->objaddr, OBJADDR_SCR_SEL | S_DOT11_SRC_LMT); @@ -2608,10 +2515,8 @@ static void wlc_coreinit(struct wlc_info *wlc) wlc_bmac_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL); wlc_bmac_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL); - if (D11REV_GE(wlc_hw->corerev, 16)) { - AND_REG(osh, ®s->ifs_ctl, 0x0FFF); - W_REG(osh, ®s->ifs_aifsn, EDCF_AIFSN_MIN); - } + AND_REG(osh, ®s->ifs_ctl, 0x0FFF); + W_REG(osh, ®s->ifs_aifsn, EDCF_AIFSN_MIN); /* dma initializations */ wlc->txpend16165war = 0; @@ -2625,10 +2530,6 @@ static void wlc_coreinit(struct wlc_info *wlc) /* init the rx dma engine(s) and post receive buffers */ dma_rxinit(wlc_hw->di[RX_FIFO]); dma_rxfill(wlc_hw->di[RX_FIFO]); - if (D11REV_IS(wlc_hw->corerev, 4)) { - dma_rxinit(wlc_hw->di[RX_TXSTATUS_FIFO]); - dma_rxfill(wlc_hw->di[RX_TXSTATUS_FIFO]); - } } /* This function is used for changing the tsf frac register @@ -3160,45 +3061,12 @@ static inline u32 wlc_intstatus(struct wlc_info *wlc, bool in_isr) /* MI_DMAINT is indication of non-zero intstatus */ if (macintstatus & MI_DMAINT) { - if (D11REV_IS(wlc_hw->corerev, 4)) { - intstatus_rxfifo = - R_REG(osh, ®s->intctrlregs[RX_FIFO].intstatus); - intstatus_txsfifo = - R_REG(osh, - ®s->intctrlregs[RX_TXSTATUS_FIFO]. - intstatus); - WL_TRACE("wl%d: intstatus_rxfifo 0x%x, intstatus_txsfifo 0x%x\n", - wlc_hw->unit, - intstatus_rxfifo, intstatus_txsfifo); - - /* defer unsolicited interrupt hints */ - intstatus_rxfifo &= DEF_RXINTMASK; - intstatus_txsfifo &= DEF_RXINTMASK; - - /* MI_DMAINT bit in macintstatus is indication of RX_FIFO interrupt */ - /* clear interrupt hints */ - if (intstatus_rxfifo) - W_REG(osh, - ®s->intctrlregs[RX_FIFO].intstatus, - intstatus_rxfifo); - else - macintstatus &= ~MI_DMAINT; - - /* MI_TFS bit in macintstatus is encoding of RX_TXSTATUS_FIFO interrupt */ - if (intstatus_txsfifo) { - W_REG(osh, - ®s->intctrlregs[RX_TXSTATUS_FIFO]. - intstatus, intstatus_txsfifo); - macintstatus |= MI_TFS; - } - } else { - /* - * For corerevs >= 5, only fifo interrupt enabled is I_RI in RX_FIFO. - * If MI_DMAINT is set, assume it is set and clear the interrupt. - */ - W_REG(osh, ®s->intctrlregs[RX_FIFO].intstatus, - DEF_RXINTMASK); - } + /* + * only fifo interrupt enabled is I_RI in RX_FIFO. If + * MI_DMAINT is set, assume it is set and clear the interrupt. + */ + W_REG(osh, ®s->intctrlregs[RX_FIFO].intstatus, + DEF_RXINTMASK); } return macintstatus; @@ -3324,14 +3192,7 @@ wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal) WL_TRACE("wl%d: wlc_bmac_txstatus\n", wlc_hw->unit); - if (D11REV_IS(wlc_hw->corerev, 4)) { - /* to retire soon */ - *fatal = wlc_bmac_txstatus_corerev4(wlc->hw); - - if (*fatal) - return 0; - } else { - /* corerev >= 5 */ + { d11regs_t *regs; struct osl_info *osh; tx_status_t txstatus, *txs; @@ -3624,41 +3485,6 @@ bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) (void)R_REG(osh, ®s->objaddr); W_REG(osh, ®s->objdata, w); - if (D11REV_LT(wlc_hw->corerev, 11)) { - /* if 32 bit writes are split into 16 bit writes, are they in the correct order - * for our interface, low to high - */ - reg16 = (volatile u16 *)®s->tsf_cfpstart; - - /* write the CFPStart register low half explicitly, starting a buffered write */ - W_REG(osh, reg16, 0xAAAA); - - /* Write a 32 bit value to CFPStart to test the 16 bit split order. - * If the low 16 bits are written first, followed by the high 16 bits then the - * 32 bit value 0xCCCCBBBB should end up in the register. - * If the order is reversed, then the write to the high half will trigger a buffered - * write of 0xCCCCAAAA. - * If the bus is 32 bits, then this is not much of a test, and the reg should - * have the correct value 0xCCCCBBBB. - */ - W_REG(osh, ®s->tsf_cfpstart, 0xCCCCBBBB); - - /* verify with the 16 bit registers that have no side effects */ - val = R_REG(osh, ®s->tsf_cfpstrt_l); - if (val != (uint) 0xBBBB) { - WL_ERROR("wl%d: validate_chip_access: tsf_cfpstrt_l = 0x%x, expected 0x%x\n", - wlc_hw->unit, val, 0xBBBB); - return false; - } - val = R_REG(osh, ®s->tsf_cfpstrt_h); - if (val != (uint) 0xCCCC) { - WL_ERROR("wl%d: validate_chip_access: tsf_cfpstrt_h = 0x%x, expected 0x%x\n", - wlc_hw->unit, val, 0xCCCC); - return false; - } - - } - /* clear CFPStart */ W_REG(osh, ®s->tsf_cfpstart, 0); @@ -3689,9 +3515,6 @@ void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on) regs = wlc_hw->regs; osh = wlc_hw->osh; - if (D11REV_LE(wlc_hw->corerev, 16) || D11REV_IS(wlc_hw->corerev, 20)) - return; - if (on) { if ((wlc_hw->sih->chip == BCM4313_CHIP_ID)) { OR_REG(osh, ®s->clk_ctl_st, @@ -3813,8 +3636,6 @@ static void wlc_flushqueues(struct wlc_info *wlc) /* free any posted rx packets */ dma_rxreclaim(wlc_hw->di[RX_FIFO]); - if (D11REV_IS(wlc_hw->corerev, 4)) - dma_rxreclaim(wlc_hw->di[RX_TXSTATUS_FIFO]); } u16 wlc_bmac_read_shm(struct wlc_hw_info *wlc_hw, uint offset) diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_key.h b/drivers/staging/brcm80211/brcmsmac/wlc_key.h index 4991e9921de3..70d3173e9fde 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_key.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_key.h @@ -45,11 +45,10 @@ struct wlc_bsscfg; #define WLC_MAX_WSEC_HW_KEYS(wlc) WSEC_MAX_RCMTA_KEYS /* Max # of hardware TKIP MIC keys supported */ -#define WLC_MAX_TKMIC_HW_KEYS(wlc) ((D11REV_GE((wlc)->pub->corerev, 13)) ? \ - WSEC_MAX_TKMIC_ENGINE_KEYS : 0) +#define WLC_MAX_TKMIC_HW_KEYS(wlc) (WSEC_MAX_TKMIC_ENGINE_KEYS) #define WSEC_HW_TKMIC_KEY(wlc, key, bsscfg) \ - (((D11REV_GE((wlc)->pub->corerev, 13)) && ((wlc)->machwcap & MCAP_TKIPMIC)) && \ + ((((wlc)->machwcap & MCAP_TKIPMIC)) && \ (key) && ((key)->algo == CRYPTO_ALGO_TKIP) && \ !WSEC_SOFTKEY(wlc, key, bsscfg) && \ WSEC_KEY_INDEX(wlc, key) >= WLC_DEFAULT_KEYS && \ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index 0c5d37bb81fb..aa6e20585afe 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -457,7 +457,7 @@ void wlc_init(struct wlc_info *wlc) wlc_bmac_init(wlc->hw, chanspec, mute); wlc->seckeys = wlc_bmac_read_shm(wlc->hw, M_SECRXKEYS_PTR) * 2; - if (D11REV_GE(wlc->pub->corerev, 15) && (wlc->machwcap & MCAP_TKIPMIC)) + if (wlc->machwcap & MCAP_TKIPMIC) wlc->tkmickeys = wlc_bmac_read_shm(wlc->hw, M_TKMICKEYS_PTR) * 2; @@ -547,8 +547,7 @@ void wlc_init(struct wlc_info *wlc) wlc->tx_suspended = false; /* enable the RF Disable Delay timer */ - if (D11REV_GE(wlc->pub->corerev, 10)) - W_REG(wlc->osh, &wlc->regs->rfdisabledly, RFDISABLE_DEFAULT); + W_REG(wlc->osh, &wlc->regs->rfdisabledly, RFDISABLE_DEFAULT); /* initialize mpc delay */ wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; @@ -3486,15 +3485,8 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, break; } - /* 4322 supports antdiv in phy, no need to set it to ucode */ - if (WLCISNPHY(wlc->band) - && D11REV_IS(wlc->pub->corerev, 16)) { - WL_ERROR("wl%d: can't set ucantdiv for 4322\n", - wlc->pub->unit); - bcmerror = BCME_UNSUPPORTED; - } else - wlc_mhf(wlc, MHF1, MHF1_ANTDIV, - (val ? MHF1_ANTDIV : 0), WLC_BAND_AUTO); + wlc_mhf(wlc, MHF1, MHF1_ANTDIV, + (val ? MHF1_ANTDIV : 0), WLC_BAND_AUTO); break; } #endif /* defined(BCMDBG) */ @@ -6162,16 +6154,13 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, */ txh->TxStatus = htol16(status); - if (D11REV_GE(wlc->pub->corerev, 16)) { - /* extra fields for ucode AMPDU aggregation, the new fields are added to - * the END of previous structure so that it's compatible in driver. - * In old rev ucode, these fields should be ignored - */ - txh->MaxNMpdus = htol16(0); - txh->MaxABytes_MRT = htol16(0); - txh->MaxABytes_FBR = htol16(0); - txh->MinMBytes = htol16(0); - } + /* extra fields for ucode AMPDU aggregation, the new fields are added to + * the END of previous structure so that it's compatible in driver. + */ + txh->MaxNMpdus = htol16(0); + txh->MaxABytes_MRT = htol16(0); + txh->MaxABytes_FBR = htol16(0); + txh->MinMBytes = htol16(0); /* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration, furnish d11txh_t */ /* RTS PLCP header and RTS frame */ @@ -6597,28 +6586,7 @@ static void *wlc_15420war(struct wlc_info *wlc, uint queue) ASSERT(queue < NFIFO); - if ((D11REV_IS(wlc->pub->corerev, 4)) - || (D11REV_GT(wlc->pub->corerev, 6))) - return NULL; - - di = wlc->hw->di[queue]; - ASSERT(di != NULL); - - /* get next packet, ignoring XmtStatus.Curr */ - p = dma_getnexttxp(di, HNDDMA_RANGE_ALL); - - /* sw block tx dma */ - dma_txblock(di); - - /* if tx ring is now empty, reset and re-init the tx dma channel */ - if (dma_txactive(wlc->hw->di[queue]) == 0) { - wlc->pub->_cnt->txdmawar++; - if (!dma_txreset(di)) - WL_ERROR("wl%d: %s: dma_txreset[%d]: cannot stop dma\n", - wlc->pub->unit, __func__, queue); - dma_txinit(di); - } - return p; + return NULL; } static void wlc_war16165(struct wlc_info *wlc, bool tx) -- cgit v1.2.3 From 3746507af6c8f7222eafa65188d256b49288ad08 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Mon, 14 Feb 2011 12:16:46 +0100 Subject: staging: brcm80211: removed obsolete comments Code cleanup. Only mac core revisions 22 and higher are supported, therefore comment related to older mac revisions was removed. Signed-off-by: Roland Vossen Reviewed-by: Arend van Spriel Reviewed-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/d11.h | 71 +++++++++++------------ drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 17 +++--- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h | 4 +- drivers/staging/brcm80211/include/sbhnddma.h | 2 +- 4 files changed, 46 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/d11.h b/drivers/staging/brcm80211/brcmsmac/d11.h index 841e9402ed2b..e87d3a585eee 100644 --- a/drivers/staging/brcm80211/brcmsmac/d11.h +++ b/drivers/staging/brcm80211/brcmsmac/d11.h @@ -73,7 +73,7 @@ typedef volatile union { /* pio register set 2/4 bytes union for d11 fifo */ typedef volatile union { pio2regp_t b2; /* < corerev 8 */ - pio4regp_t b4; /* >= corerev 8 */ + pio4regp_t b4; } u_pioreg_t; /* dma/pio corerev >= 11 */ @@ -95,7 +95,7 @@ typedef volatile struct _d11regs { u32 biststatus; /* 0xC */ u32 biststatus2; /* 0x10 */ u32 PAD; /* 0x14 */ - u32 gptimer; /* 0x18 *//* for corerev >= 3 */ + u32 gptimer; /* 0x18 */ u32 usectimer; /* 0x1c *//* for corerev >= 26 */ /* Interrupt Control *//* 0x20 */ @@ -103,7 +103,6 @@ typedef volatile struct _d11regs { u32 PAD[40]; /* 0x60 - 0xFC */ - /* tx fifos 6-7 and rx fifos 1-3 removed in corerev 5 */ u32 intrcvlazy[4]; /* 0x100 - 0x10C */ u32 PAD[4]; /* 0x110 - 0x11c */ @@ -125,22 +124,20 @@ typedef volatile struct _d11regs { u32 PAD; /* 0x14C */ u32 chnstatus; /* 0x150 */ - u32 psmdebug; /* 0x154 *//* for corerev >= 3 */ - u32 phydebug; /* 0x158 *//* for corerev >= 3 */ - u32 machwcap; /* 0x15C *//* Corerev >= 13 */ + u32 psmdebug; /* 0x154 */ + u32 phydebug; /* 0x158 */ + u32 machwcap; /* 0x15C */ /* Extended Internal Objects */ u32 objaddr; /* 0x160 */ u32 objdata; /* 0x164 */ u32 PAD[2]; /* 0x168 - 0x16c */ - /* New txstatus registers on corerev >= 5 */ u32 frmtxstatus; /* 0x170 */ u32 frmtxstatus2; /* 0x174 */ u32 PAD[2]; /* 0x178 - 0x17c */ - /* New TSF host access on corerev >= 3 */ - + /* TSF host access */ u32 tsf_timerlow; /* 0x180 */ u32 tsf_timerhigh; /* 0x184 */ u32 tsf_cfprep; /* 0x188 */ @@ -152,17 +149,17 @@ typedef volatile struct _d11regs { u32 machwcap1; /* 0x1a4 */ u32 PAD[14]; /* 0x1a8 - 0x1dc */ - /* Clock control and hardware workarounds (corerev >= 13) */ + /* Clock control and hardware workarounds*/ u32 clk_ctl_st; /* 0x1e0 */ u32 hw_war; - u32 d11_phypllctl; /* 0x1e8 (corerev == 16), the phypll request/avail bits are - * moved to clk_ctl_st for corerev >= 17 + u32 d11_phypllctl; /* the phypll request/avail bits are + * moved to clk_ctl_st */ u32 PAD[5]; /* 0x1ec - 0x1fc */ /* 0x200-0x37F dma/pio registers */ volatile union { - fifo64_t f64regs[6]; /* on corerev >= 11 */ + fifo64_t f64regs[6]; } fifo; /* FIFO diagnostic port access */ @@ -174,7 +171,10 @@ typedef volatile struct _d11regs { u16 radioregaddr; /* 0x3d8 */ u16 radioregdata; /* 0x3da */ - /* time delay between the change on rf disable input and radio shutdown corerev 10 */ + /* + * time delay between the change on rf disable input and + * radio shutdown + */ u32 rfdisabledly; /* 0x3DC */ /* PHY register access */ @@ -341,7 +341,7 @@ typedef volatile struct _d11regs { u16 PAD[0X14]; /* 0x632 - 0x658 */ u16 tsf_random; /* 0x65A */ u16 PAD[0x05]; /* 0x65C - 0x664 */ - /* GPTimer 2 registers are corerev >= 3 */ + /* GPTimer 2 registers */ u16 tsf_gpt2_stat; /* 0x666 */ u16 tsf_gpt2_ctr_l; /* 0x668 */ u16 tsf_gpt2_ctr_h; /* 0x66A */ @@ -361,11 +361,11 @@ typedef volatile struct _d11regs { u16 ifsmedbusyctl; /* 0x692 */ u16 iftxdur; /* 0x694 */ u16 PAD[0x3]; /* 0x696 - 0x69b */ - /* EDCF support in dot11macs with corerevs >= 16 */ + /* EDCF support in dot11macs */ u16 ifs_aifsn; /* 0x69c */ u16 ifs_ctl1; /* 0x69e */ - /* New slow clock registers on corerev >= 5 */ + /* slow clock registers */ u16 scc_ctl; /* 0x6a0 */ u16 scc_timer_l; /* 0x6a2 */ u16 scc_timer_h; /* 0x6a4 */ @@ -500,12 +500,11 @@ typedef volatile struct _d11regs { #define MI_RESERVED3 (1 << 22) #define MI_RESERVED2 (1 << 23) #define MI_RESERVED1 (1 << 25) -#define MI_RFDISABLE (1 << 28) /* MAC detected a change on RF Disable input - * (corerev >= 10) - */ -#define MI_TFS (1 << 29) /* MAC has completed a TX (corerev >= 5) */ +/* MAC detected change on RF Disable input*/ +#define MI_RFDISABLE (1 << 28) +#define MI_TFS (1 << 29) /* MAC has completed a TX */ #define MI_PHYCHANGED (1 << 30) /* A phy status change wrt G mode */ -#define MI_TO (1U << 31) /* general purpose timeout (corerev >= 3) */ +#define MI_TO (1U << 31) /* general purpose timeout */ /* Mac capabilities registers */ /* machwcap */ @@ -523,7 +522,7 @@ typedef volatile struct _d11regs { #define PMQH_OFLO 0x00000004 /* pmq overflow indication */ #define PMQH_NOT_EMPTY 0x00000008 /* entries are present in pmq */ -/* phydebug (corerev >= 3) */ +/* phydebug */ #define PDBG_CRS (1 << 0) /* phy is asserting carrier sense */ #define PDBG_TXA (1 << 1) /* phy is taking xmit byte from mac this cycle */ #define PDBG_TXF (1 << 2) /* mac is instructing the phy to transmit a frame */ @@ -552,7 +551,6 @@ typedef volatile struct _d11regs { /* frmtxstatus */ #define TXS_V (1 << 0) /* valid bit */ #define TXS_STATUS_MASK 0xffff -/* sw mask to map txstatus for corerevs <= 4 to be the same as for corerev > 4 */ #define TXS_COMPAT_MASK 0x3 #define TXS_COMPAT_SHIFT 1 #define TXS_FID_MASK 0xffff0000 @@ -565,7 +563,7 @@ typedef volatile struct _d11regs { #define TXS_MU_MASK 0x01000000 #define TXS_MU_SHIFT 24 -/* clk_ctl_st, corerev >= 17 */ +/* clk_ctl_st */ #define CCS_ERSRC_REQ_D11PLL 0x00000100 /* d11 core pll request */ #define CCS_ERSRC_REQ_PHYPLL 0x00000200 /* PHY pll request */ #define CCS_ERSRC_AVAIL_D11PLL 0x01000000 /* d11 core pll available */ @@ -584,7 +582,6 @@ typedef volatile struct _d11regs { #define CFPREP_CBI_SHIFT 6 #define CFPREP_CFPP 0x00000001 -/* tx fifo sizes for corerev >= 9 */ /* tx fifo sizes values are in terms of 256 byte blocks */ #define TXFIFOCMD_RESET_MASK (1 << 15) /* reset */ #define TXFIFOCMD_FIFOSEL_SHIFT 8 /* fifo */ @@ -724,10 +721,10 @@ struct d11txh { u16 AmpduSeqCtl; /* 0x25 */ u16 TxFrameID; /* 0x26 */ u16 TxStatus; /* 0x27 */ - u16 MaxNMpdus; /* 0x28 corerev >=16 */ - u16 MaxABytes_MRT; /* 0x29 corerev >=16 */ - u16 MaxABytes_FBR; /* 0x2a corerev >=16 */ - u16 MinMBytes; /* 0x2b corerev >=16 */ + u16 MaxNMpdus; /* 0x28 */ + u16 MaxABytes_MRT; /* 0x29 */ + u16 MaxABytes_FBR; /* 0x2a */ + u16 MinMBytes; /* 0x2b */ u8 RTSPhyHeader[D11_PHY_HDR_LEN]; /* 0x2c - 0x2e */ struct ieee80211_rts rts_frame; /* 0x2f - 0x36 */ u16 PAD; /* 0x37 */ @@ -865,7 +862,7 @@ struct tx_status { #define TX_STATUS_SUPR_MASK 0x1C /* suppress status bits (4:2) */ #define TX_STATUS_SUPR_SHIFT 2 #define TX_STATUS_ACK_RCV (1 << 1) /* ACK received */ -#define TX_STATUS_VALID (1 << 0) /* Tx status valid (corerev >= 5) */ +#define TX_STATUS_VALID (1 << 0) /* Tx status valid */ #define TX_STATUS_NO_ACK 0 /* suppress status reason codes */ @@ -1612,9 +1609,9 @@ typedef struct macstat { #define SICF_PCLKE 0x0004 /* PHY clock enable */ #define SICF_PRST 0x0008 /* PHY reset */ #define SICF_MPCLKE 0x0010 /* MAC PHY clockcontrol enable */ -#define SICF_FREF 0x0020 /* PLL FreqRefSelect (corerev >= 5) */ +#define SICF_FREF 0x0020 /* PLL FreqRefSelect */ /* NOTE: the following bw bits only apply when the core is attached - * to a NPHY (and corerev >= 11 which it will always be for NPHYs). + * to a NPHY */ #define SICF_BWMASK 0x00c0 /* phy clock mask (b6 & b7) */ #define SICF_BW40 0x0080 /* 40MHz BW (160MHz phyclk) */ @@ -1623,10 +1620,10 @@ typedef struct macstat { #define SICF_GMODE 0x2000 /* gmode enable */ /* dot11 core-specific status flags */ -#define SISF_2G_PHY 0x0001 /* 2.4G capable phy (corerev >= 5) */ -#define SISF_5G_PHY 0x0002 /* 5G capable phy (corerev >= 5) */ -#define SISF_FCLKA 0x0004 /* FastClkAvailable (corerev >= 5) */ -#define SISF_DB_PHY 0x0008 /* Dualband phy (corerev >= 11) */ +#define SISF_2G_PHY 0x0001 /* 2.4G capable phy */ +#define SISF_5G_PHY 0x0002 /* 5G capable phy */ +#define SISF_FCLKA 0x0004 /* FastClkAvailable */ +#define SISF_DB_PHY 0x0008 /* Dualband phy */ /* === End of MAC reg, Beginning of PHY(b/a/g/n) reg, radio and LPPHY regs are separated === */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index a11eba722abb..135c3883ca8d 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -595,8 +595,6 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) * FIFO 3 * TX: TX_AC_VO_FIFO (TX AC Voice data packets) * (legacy) TX_CTL_FIFO (TX control & mgmt packets) - * RX: RX_TXSTATUS_FIFO (transmit-status packets) - * for corerev < 5 only */ ASSERT(TX_AC_VO_FIFO == 3); ASSERT(TX_CTL_FIFO == 3); @@ -2133,8 +2131,9 @@ bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw) clk = wlc_hw->clk; if (!clk) { /* - * corerev >= 18, mac no longer enables phyclk automatically when driver accesses - * phyreg throughput mac. This can be skipped since only mac reg is accessed below + * mac no longer enables phyclk automatically when driver + * accesses phyreg throughput mac. This can be skipped since + * only mac reg is accessed below */ flags |= SICF_PCLKE; @@ -2296,8 +2295,7 @@ void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags) wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); } -/* If the ucode that supports corerev 5 is used for corerev 9 and above, - * txfifo sizes needs to be modified(increased) since the newer cores +/* txfifo sizes needs to be modified(increased) since the newer cores * have more memory. */ static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw) @@ -2335,7 +2333,10 @@ static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw) txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu]; } exit: - /* need to propagate to shm location to be in sync since ucode/hw won't do this */ + /* + * need to propagate to shm location to be in sync since ucode/hw won't + * do this + */ wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE0, wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]); wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE1, @@ -2416,7 +2417,7 @@ static void wlc_coreinit(struct wlc_info *wlc) __func__, wlc_hw->unit, wlc_hw->corerev); } - /* For old ucode, txfifo sizes needs to be modified(increased) for Corerev >= 9 */ + /* For old ucode, txfifo sizes needs to be modified(increased) */ if (fifosz_fixup == true) { wlc_corerev_fifofixup(wlc_hw); } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h index 0f6fccab69af..1b3ac0894d67 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h @@ -420,8 +420,8 @@ struct wlc_hw_info { u16 boardrev; /* version # of particular board */ u32 boardflags; /* Board specific flags from srom */ u32 boardflags2; /* More board flags if sromrev >= 4 */ - u32 machwcap; /* MAC capabilities (corerev >= 13) */ - u32 machwcap_backup; /* backup of machwcap (corerev >= 13) */ + u32 machwcap; /* MAC capabilities */ + u32 machwcap_backup; /* backup of machwcap */ u16 ucode_dbgsel; /* dbgsel for ucode debug(config gpio) */ si_t *sih; /* SB handle (cookie for siutils calls) */ diff --git a/drivers/staging/brcm80211/include/sbhnddma.h b/drivers/staging/brcm80211/include/sbhnddma.h index 09e6d33ee579..183922136d75 100644 --- a/drivers/staging/brcm80211/include/sbhnddma.h +++ b/drivers/staging/brcm80211/include/sbhnddma.h @@ -303,7 +303,7 @@ typedef volatile struct { #define D64_RX_FRM_STS_LEN 0x0000ffff /* frame length mask */ #define D64_RX_FRM_STS_OVFL 0x00800000 /* RxOverFlow */ -#define D64_RX_FRM_STS_DSCRCNT 0x0f000000 /* no. of descriptors used - 1, d11corerev >= 22 */ +#define D64_RX_FRM_STS_DSCRCNT 0x0f000000 /* no. of descriptors used - 1 */ #define D64_RX_FRM_STS_DATATYPE 0xf0000000 /* core-dependent data type */ /* receive frame status */ -- cgit v1.2.3 From 02aed8f3d69f1aefd3f7e66780ee103183ddb2ca Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Mon, 14 Feb 2011 12:16:47 +0100 Subject: staging: brcm80211: removed unused code because of mac rev cleanup Code cleanup. Removed more defines, data structures and functions that were unused because this driver supports mac core rev 22 and up. Got rid of redundant brackets in wlc_bmac_txstatus() by moving locally defined variables above {} scope. Signed-off-by: Roland Vossen Reviewed-by: Arend van Spriel Reviewed-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/d11.h | 17 +-- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 136 +++++++--------------- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 17 --- 3 files changed, 41 insertions(+), 129 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/d11.h b/drivers/staging/brcm80211/brcmsmac/d11.h index e87d3a585eee..80a8489b8548 100644 --- a/drivers/staging/brcm80211/brcmsmac/d11.h +++ b/drivers/staging/brcm80211/brcmsmac/d11.h @@ -70,13 +70,6 @@ typedef volatile union { } w; } pmqreg_t; -/* pio register set 2/4 bytes union for d11 fifo */ -typedef volatile union { - pio2regp_t b2; /* < corerev 8 */ - pio4regp_t b4; -} u_pioreg_t; - -/* dma/pio corerev >= 11 */ typedef volatile struct { dma64regs_t dmaxmt; /* dma tx */ pio4regs_t piotx; /* pio tx */ @@ -158,9 +151,7 @@ typedef volatile struct _d11regs { u32 PAD[5]; /* 0x1ec - 0x1fc */ /* 0x200-0x37F dma/pio registers */ - volatile union { - fifo64_t f64regs[6]; - } fifo; + fifo64_t fifo64regs[6]; /* FIFO diagnostic port access */ dma32diag_t dmafifo; /* 0x380 - 0x38C */ @@ -551,8 +542,6 @@ typedef volatile struct _d11regs { /* frmtxstatus */ #define TXS_V (1 << 0) /* valid bit */ #define TXS_STATUS_MASK 0xffff -#define TXS_COMPAT_MASK 0x3 -#define TXS_COMPAT_SHIFT 1 #define TXS_FID_MASK 0xffff0000 #define TXS_FID_SHIFT 16 @@ -573,10 +562,6 @@ typedef volatile struct _d11regs { #define CCS_ERSRC_REQ_HT 0x00000010 /* HT avail request */ #define CCS_ERSRC_AVAIL_HT 0x00020000 /* HT clock available */ -/* d11_pwrctl, corerev16 only */ -#define D11_PHYPLL_AVAIL_REQ 0x000010000 /* request PHY PLL resource */ -#define D11_PHYPLL_AVAIL_STS 0x001000000 /* PHY PLL is available */ - /* tsf_cfprep register */ #define CFPREP_CBI_MASK 0xffffffc0 #define CFPREP_CBI_SHIFT 6 diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 135c3883ca8d..c21977929ff8 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -88,8 +88,8 @@ #define DMAREG(wlc_hw, direction, fifonum) \ ((direction == DMA_TX) ? \ - (void *)&(wlc_hw->regs->fifo.f64regs[fifonum].dmaxmt) : \ - (void *)&(wlc_hw->regs->fifo.f64regs[fifonum].dmarcv)) + (void *)&(wlc_hw->regs->fifo64regs[fifonum].dmaxmt) : \ + (void *)&(wlc_hw->regs->fifo64regs[fifonum].dmarcv)) /* * The following table lists the buffer memory allocated to xmt fifos in HW. @@ -123,7 +123,6 @@ static void wlc_ucode_txant_set(struct wlc_hw_info *wlc_hw); /* used by wlc_dpc() */ static bool wlc_bmac_dotxstatus(struct wlc_hw_info *wlc, tx_status_t *txs, u32 s2); -static bool wlc_bmac_txstatus_corerev4(struct wlc_hw_info *wlc); static bool wlc_bmac_txstatus(struct wlc_hw_info *wlc, bool bound, bool *fatal); static bool wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound); @@ -237,7 +236,6 @@ static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit) { struct wlc_hw_info *wlc_hw = wlc->hw; u32 macintmask; - u32 tmp; WL_TRACE("wl%d: wlc_setband_inact\n", wlc_hw->unit); @@ -1329,18 +1327,11 @@ static void wlc_clkctl_clk(struct wlc_hw_info *wlc_hw, uint mode) } wlc_hw->forcefastclk = (mode == CLK_FAST); } else { - bool wakeup_ucode; /* old chips w/o PMU, force HT through cc, * then use FCA to verify mac is running fast clock */ - wakeup_ucode = false; - - if (wlc_hw->up && wakeup_ucode) - wlc_ucode_wake_override_set(wlc_hw, - WLC_WAKE_OVERRIDE_CLKCTL); - wlc_hw->forcefastclk = si_clkctl_cc(wlc_hw->sih, mode); /* check fast clock is available (if core is not in reset) */ @@ -1362,11 +1353,6 @@ static void wlc_clkctl_clk(struct wlc_hw_info *wlc_hw, uint mode) else mboolclr(wlc_hw->wake_override, WLC_WAKE_OVERRIDE_FORCEFAST); - - /* ok to clear the wakeup now */ - if (wlc_hw->up && wakeup_ucode) - wlc_ucode_wake_override_clear(wlc_hw, - WLC_WAKE_OVERRIDE_CLKCTL); } } @@ -1635,8 +1621,6 @@ wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); - ASSERT(wlc_hw->corerev > 4); - mac_hm = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0]; @@ -1667,7 +1651,7 @@ wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset, WL_TRACE("wl%d: wlc_bmac_set_addrmatch\n", wlc_hw->unit); - ASSERT((match_reg_offset < RCM_SIZE) || (wlc_hw->corerev == 4)); + ASSERT(match_reg_offset < RCM_SIZE); regs = wlc_hw->regs; mac_l = addr[0] | (addr[1] << 8); @@ -1755,7 +1739,6 @@ void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax) void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw) { bool fastclk; - u32 tmp; /* request FAST clock if not on */ fastclk = wlc_hw->forcefastclk; @@ -2332,7 +2315,6 @@ static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw) txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu]; } - exit: /* * need to propagate to shm location to be in sync since ucode/hw won't * do this @@ -3021,7 +3003,6 @@ static inline u32 wlc_intstatus(struct wlc_info *wlc, bool in_isr) struct wlc_hw_info *wlc_hw = wlc->hw; d11regs_t *regs = wlc_hw->regs; u32 macintstatus; - u32 intstatus_rxfifo, intstatus_txsfifo; struct osl_info *osh; osh = wlc_hw->osh; @@ -3130,42 +3111,6 @@ bool BCMFASTPATH wlc_isr(struct wlc_info *wlc, bool *wantdpc) } -/* process tx completion events for corerev < 5 */ -static bool wlc_bmac_txstatus_corerev4(struct wlc_hw_info *wlc_hw) -{ - struct sk_buff *status_p; - tx_status_t *txs; - struct osl_info *osh; - bool fatal = false; - - WL_TRACE("wl%d: wlc_txstatusrecv\n", wlc_hw->unit); - - osh = wlc_hw->osh; - - while (!fatal && (status_p = dma_rx(wlc_hw->di[RX_TXSTATUS_FIFO]))) { - - txs = (tx_status_t *) status_p->data; - /* MAC uses little endian only */ - ltoh16_buf((void *)txs, sizeof(tx_status_t)); - - /* shift low bits for tx_status_t status compatibility */ - txs->status = (txs->status & ~TXS_COMPAT_MASK) - | (((txs->status & TXS_COMPAT_MASK) << TXS_COMPAT_SHIFT)); - - fatal = wlc_bmac_dotxstatus(wlc_hw, txs, 0); - - pkt_buf_free_skb(osh, status_p, false); - } - - if (fatal) - return true; - - /* post more rbufs */ - dma_rxfill(wlc_hw->di[RX_TXSTATUS_FIFO]); - - return false; -} - static bool BCMFASTPATH wlc_bmac_dotxstatus(struct wlc_hw_info *wlc_hw, tx_status_t *txs, u32 s2) { @@ -3190,52 +3135,52 @@ wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal) { bool morepending = false; struct wlc_info *wlc = wlc_hw->wlc; + d11regs_t *regs; + struct osl_info *osh; + tx_status_t txstatus, *txs; + u32 s1, s2; + uint n = 0; + /* + * Param 'max_tx_num' indicates max. # tx status to process before + * break out. + */ + uint max_tx_num = bound ? wlc->pub->tunables->txsbnd : -1; WL_TRACE("wl%d: wlc_bmac_txstatus\n", wlc_hw->unit); - { - d11regs_t *regs; - struct osl_info *osh; - tx_status_t txstatus, *txs; - u32 s1, s2; - uint n = 0; - /* Param 'max_tx_num' indicates max. # tx status to process before break out. */ - uint max_tx_num = bound ? wlc->pub->tunables->txsbnd : -1; - - txs = &txstatus; - regs = wlc_hw->regs; - osh = wlc_hw->osh; - while (!(*fatal) - && (s1 = R_REG(osh, ®s->frmtxstatus)) & TXS_V) { - - if (s1 == 0xffffffff) { - WL_ERROR("wl%d: %s: dead chip\n", - wlc_hw->unit, __func__); - ASSERT(s1 != 0xffffffff); - return morepending; - } + txs = &txstatus; + regs = wlc_hw->regs; + osh = wlc_hw->osh; + while (!(*fatal) + && (s1 = R_REG(osh, ®s->frmtxstatus)) & TXS_V) { + + if (s1 == 0xffffffff) { + WL_ERROR("wl%d: %s: dead chip\n", + wlc_hw->unit, __func__); + ASSERT(s1 != 0xffffffff); + return morepending; + } - s2 = R_REG(osh, ®s->frmtxstatus2); + s2 = R_REG(osh, ®s->frmtxstatus2); - txs->status = s1 & TXS_STATUS_MASK; - txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT; - txs->sequence = s2 & TXS_SEQ_MASK; - txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT; - txs->lasttxtime = 0; + txs->status = s1 & TXS_STATUS_MASK; + txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT; + txs->sequence = s2 & TXS_SEQ_MASK; + txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT; + txs->lasttxtime = 0; - *fatal = wlc_bmac_dotxstatus(wlc_hw, txs, s2); + *fatal = wlc_bmac_dotxstatus(wlc_hw, txs, s2); - /* !give others some time to run! */ - if (++n >= max_tx_num) - break; - } + /* !give others some time to run! */ + if (++n >= max_tx_num) + break; + } - if (*fatal) - return 0; + if (*fatal) + return 0; - if (n >= max_tx_num) - morepending = true; - } + if (n >= max_tx_num) + morepending = true; if (!pktq_empty(&wlc->active_queue->q)) wlc_send_q(wlc, wlc->active_queue); @@ -3441,7 +3386,6 @@ bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) { d11regs_t *regs; u32 w, val; - volatile u16 *reg16; struct osl_info *osh; WL_TRACE("wl%d: validate_chip_access\n", wlc_hw->unit); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index aa6e20585afe..5b2b93f2b2e5 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -326,8 +326,6 @@ void wlc_get_rcmta(struct wlc_info *wlc, int idx, u8 *addr) WL_TRACE("wl%d: %s\n", WLCWLUNIT(wlc), __func__); - ASSERT(wlc->pub->corerev > 4); - osh = wlc->osh; W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); @@ -6459,13 +6457,11 @@ void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs) /* GP timer is a freerunning 32 bit counter, decrements at 1 us rate */ void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us) { - ASSERT(wlc->pub->corerev >= 3); /* no gptimer in earlier revs */ W_REG(wlc->osh, &wlc->regs->gptimer, us); } void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc) { - ASSERT(wlc->pub->corerev >= 3); W_REG(wlc->osh, &wlc->regs->gptimer, 0); } @@ -6579,16 +6575,6 @@ void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus) ASSERT(wlc_ps_check(wlc)); } -static void *wlc_15420war(struct wlc_info *wlc, uint queue) -{ - struct hnddma_pub *di; - void *p; - - ASSERT(queue < NFIFO); - - return NULL; -} - static void wlc_war16165(struct wlc_info *wlc, bool tx) { if (tx) { @@ -6651,9 +6637,6 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) p = GETNEXTTXP(wlc, queue); if (WLC_WAR16165(wlc)) wlc_war16165(wlc, false); - if (p == NULL) - p = wlc_15420war(wlc, queue); - ASSERT(p != NULL); if (p == NULL) goto fatal; -- cgit v1.2.3 From 70de655cace24d9f2dd8a4277e65fc6da07df75b Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Tue, 15 Feb 2011 01:05:09 +0300 Subject: staging: brcm80211: use %zu instead of %d for size_t Signed-off-by: Stanislav Fomichev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 2 +- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index fa2316bcf510..c798c75a4a88 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -1375,7 +1375,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN); wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size); - WL_DBG("join_param_size %d\n", join_params_size); + WL_DBG("join_param_size %zu\n", join_params_size); if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) { WL_DBG("ssid \"%s\", len (%d)\n", diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 55ea876ce5fa..07871679daaf 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -1861,12 +1861,12 @@ int wl_check_firmwares(struct wl_info *wl) WL_ERROR("%s: invalid bin/hdr fw\n", __func__); rc = -EBADF; } else if (fw_hdr->size % sizeof(struct wl_fw_hdr)) { - WL_ERROR("%s: non integral fw hdr file size %d/%zu\n", + WL_ERROR("%s: non integral fw hdr file size %zu/%zu\n", __func__, fw_hdr->size, sizeof(struct wl_fw_hdr)); rc = -EBADF; } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) { - WL_ERROR("%s: out of bounds fw file size %d\n", + WL_ERROR("%s: out of bounds fw file size %zu\n", __func__, fw->size); rc = -EBADF; } else { -- cgit v1.2.3 From 02160695a40f915e5c0f5bbe1288365f6ac7cf8e Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Tue, 15 Feb 2011 01:05:10 +0300 Subject: staging: brcm80211: replace bcopy with memcpy Use native linux memcpy instead of legacy bcopy Signed-off-by: Stanislav Fomichev Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh.c | 2 +- drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 40 +++++----- drivers/staging/brcm80211/brcmfmac/dhd_cdc.c | 2 +- drivers/staging/brcm80211/brcmfmac/dhd_common.c | 16 ++-- .../staging/brcm80211/brcmfmac/dhd_custom_gpio.c | 5 +- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 2 +- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 72 ++++++++--------- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 57 +++++++------- .../staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c | 66 ++++++++-------- .../staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c | 5 +- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 4 +- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 4 +- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 92 +++++++++++----------- drivers/staging/brcm80211/brcmsmac/wlc_rate.c | 6 +- drivers/staging/brcm80211/brcmsmac/wlc_stf.c | 2 +- drivers/staging/brcm80211/include/osl.h | 4 - drivers/staging/brcm80211/util/bcmotp.c | 2 +- drivers/staging/brcm80211/util/bcmsrom.c | 8 +- drivers/staging/brcm80211/util/bcmutils.c | 2 +- drivers/staging/brcm80211/util/hnddma.c | 4 +- drivers/staging/brcm80211/util/nvram/nvram_ro.c | 4 +- drivers/staging/brcm80211/util/siutils.c | 2 +- 23 files changed, 196 insertions(+), 207 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c index acf43a365081..df9a139213a5 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c @@ -324,7 +324,7 @@ int bcmsdh_cis_read(void *sdh, uint func, u8 * cis, uint length) BCMSDH_ERROR(("%s: out of memory\n", __func__)); return BCME_NOMEM; } - bcopy(cis, tmp_buf, length); + memcpy(tmp_buf, cis, length); for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4); tmp_ptr++) { ptr += sprintf((char *)ptr, "%.2x ", *tmp_ptr & 0xff); diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index d399b5c76f94..6cde62ac7dfc 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -441,7 +441,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, val_size = sizeof(int); if (plen >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); + memcpy(&int_val, params, sizeof(int_val)); bool_val = (int_val != 0) ? true : false; @@ -449,7 +449,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, switch (actionid) { case IOV_GVAL(IOV_MSGLEVEL): int_val = (s32) sd_msglevel; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_MSGLEVEL): @@ -458,7 +458,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_GVAL(IOV_BLOCKMODE): int_val = (s32) si->sd_blockmode; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_BLOCKMODE): @@ -472,7 +472,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, break; } int_val = (s32) si->client_block_size[int_val]; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_BLOCKSIZE): @@ -514,12 +514,12 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_GVAL(IOV_RXCHAIN): int_val = false; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_GVAL(IOV_DMA): int_val = (s32) si->sd_use_dma; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_DMA): @@ -528,7 +528,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_GVAL(IOV_USEINTS): int_val = (s32) si->use_client_ints; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_USEINTS): @@ -542,7 +542,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_GVAL(IOV_DIVISOR): int_val = (u32) sd_divisor; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_DIVISOR): @@ -551,7 +551,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_GVAL(IOV_POWER): int_val = (u32) sd_power; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_POWER): @@ -560,7 +560,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_GVAL(IOV_CLOCK): int_val = (u32) sd_clock; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_CLOCK): @@ -569,7 +569,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_GVAL(IOV_SDMODE): int_val = (u32) sd_sdmode; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_SDMODE): @@ -578,7 +578,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_GVAL(IOV_HISPEED): int_val = (u32) sd_hiok; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_HISPEED): @@ -587,12 +587,12 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_GVAL(IOV_NUMINTS): int_val = (s32) si->intrcount; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_GVAL(IOV_NUMLOCALINTS): int_val = (s32) 0; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_GVAL(IOV_HOSTREG): @@ -621,7 +621,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, int_val = 32; /* sdioh_sdmmc_rreg(si, sd_ptr->offset); */ - bcopy(&int_val, arg, sizeof(int_val)); + memcpy(arg, &int_val, sizeof(int_val)); break; } @@ -657,7 +657,7 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, } int_val = (int)data; - bcopy(&int_val, arg, sizeof(int_val)); + memcpy(arg, &int_val, sizeof(int_val)); break; } @@ -1048,14 +1048,14 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, /* For a write, copy the buffer data into the packet. */ if (write) - bcopy(buffer, mypkt->data, buflen_u); + memcpy(mypkt->data, buffer, buflen_u); Status = sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt); /* For a read, copy the packet data back to the buffer. */ if (!write) - bcopy(mypkt->data, buffer, buflen_u); + memcpy(buffer, mypkt->data, buflen_u); pkt_buf_free_skb(sd->osh, mypkt, write ? true : false); } else if (((u32) (pkt->data) & DMA_ALIGN_MASK) != 0) { @@ -1075,14 +1075,14 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, /* For a write, copy the buffer data into the packet. */ if (write) - bcopy(pkt->data, mypkt->data, pkt->len); + memcpy(mypkt->data, pkt->data, pkt->len); Status = sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt); /* For a read, copy the packet data back to the buffer. */ if (!write) - bcopy(mypkt->data, pkt->data, mypkt->len); + memcpy(pkt->data, mypkt->data, mypkt->len); pkt_buf_free_skb(sd->osh, mypkt, write ? true : false); } else { /* case 3: We have a packet and diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c index 09461e6f7c81..ed204d535942 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c @@ -286,7 +286,7 @@ dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t *ioc, void *buf, int len) slen = strlen("wme_dp") + 1; if (len >= (int)(slen + sizeof(int))) - bcopy(((char *)buf + slen), &val, sizeof(int)); + memcpy(&val, (char *)buf + slen, sizeof(int)); dhd->wme_dp = (u8) ltoh32(val); } diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index ad4a00871d85..b2a6fb247ef9 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -214,7 +214,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, u32 actionid, goto exit; if (plen >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); + memcpy(&int_val, params, sizeof(int_val)); switch (actionid) { case IOV_GVAL(IOV_VERSION): @@ -224,7 +224,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, u32 actionid, case IOV_GVAL(IOV_MSGLEVEL): int_val = (s32) dhd_msg_level; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_MSGLEVEL): @@ -239,12 +239,12 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, u32 actionid, case IOV_GVAL(IOV_BCMERROR): int_val = (s32) dhd_pub->bcmerror; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_GVAL(IOV_WDTICK): int_val = (s32) dhd_watchdog_ms; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_WDTICK): @@ -262,7 +262,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, u32 actionid, #ifdef DHD_DEBUG case IOV_GVAL(IOV_DCONSOLE_POLL): int_val = (s32) dhd_console_ms; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_DCONSOLE_POLL): @@ -290,7 +290,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, u32 actionid, case IOV_GVAL(IOV_IOCTLTIMEOUT):{ int_val = (s32) dhd_os_get_ioctl_resp_timeout(); - bcopy(&int_val, arg, sizeof(int_val)); + memcpy(arg, &int_val, sizeof(int_val)); break; } @@ -1498,7 +1498,7 @@ int dhd_iscan_delete_bss(void *dhdp, void *addr, iscan_buf_t *iscan_skip) (bi->length)); /* if(bi && bi_new) { - bcopy(bi, bi_new, results->buflen - + memcpy(bi_new, bi, results->buflen - dtoh32(bi_new->length)); results->buflen -= dtoh32(bi_new->length); } @@ -1522,7 +1522,7 @@ int dhd_iscan_delete_bss(void *dhdp, void *addr, iscan_buf_t *iscan_skip) (wl_bss_info_t *)((unsigned long)bi + dtoh32 (bi->length)); - bcopy(bi, bi_new, + memcpy(bi_new, bi, dtoh32 (bi->length)); bi_new = diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c b/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c index 2cd80114d385..1a7a93981bff 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c @@ -149,9 +149,8 @@ int dhd_custom_get_mac_address(unsigned char *buf) #ifdef EXAMPLE_GET_MAC /* EXAMPLE code */ { - u8 ea_example[ETH_ALEN] = { - {0x00, 0x11, 0x22, 0x33, 0x44, 0xFF} }; - bcopy((char *)ea_example, buf, ETH_ALEN); + u8 ea_example[ETH_ALEN] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xFF}; + memcpy(buf, ea_example, ETH_ALEN); } #endif /* EXAMPLE_GET_MAC */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 2426a616807e..fef08b60f6f0 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -2167,7 +2167,7 @@ int dhd_bus_start(dhd_pub_t *dhdp) bcm_mkiovar("event_msgs", dhdp->eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); dhdcdc_query_ioctl(dhdp, 0, WLC_GET_VAR, iovbuf, sizeof(iovbuf)); - bcopy(iovbuf, dhdp->eventmask, WL_EVENTING_MASK_LEN); + memcpy(dhdp->eventmask, iovbuf, WL_EVENTING_MASK_LEN); setbit(dhdp->eventmask, WLC_E_SET_SSID); setbit(dhdp->eventmask, WLC_E_PRUNE); diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 159c45928e74..916c5557f7b4 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -945,7 +945,7 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, } PKTALIGN(osh, new, pkt->len, DHD_SDALIGN); - bcopy(pkt->data, new->data, pkt->len); + memcpy(new->data, pkt->data, pkt->len); if (free_pkt) pkt_buf_free_skb(osh, pkt, true); /* free the pkt if canned one is not used */ @@ -1395,7 +1395,7 @@ int dhd_bus_rxctl(struct dhd_bus *bus, unsigned char *msg, uint msglen) dhd_os_sdlock(bus->dhd); rxlen = bus->rxlen; - bcopy(bus->rxctl, msg, min(msglen, rxlen)); + memcpy(msg, bus->rxctl, min(msglen, rxlen)); bus->rxlen = 0; dhd_os_sdunlock(bus->dhd); @@ -1658,7 +1658,7 @@ static int dhdsdio_pktgen_get(dhd_bus_t *bus, u8 *arg) pktgen.mode = bus->pktgen_mode; pktgen.stop = bus->pktgen_stop; - bcopy(&pktgen, arg, sizeof(pktgen)); + memcpy(arg, &pktgen, sizeof(pktgen)); return 0; } @@ -1668,7 +1668,7 @@ static int dhdsdio_pktgen_set(dhd_bus_t *bus, u8 *arg) dhd_pktgen_t pktgen; uint oldcnt, oldmode; - bcopy(arg, &pktgen, sizeof(pktgen)); + memcpy(&pktgen, arg, sizeof(pktgen)); if (pktgen.version != DHD_PKTGEN_VERSION) return BCME_BADARG; @@ -2094,7 +2094,7 @@ int dhdsdio_downloadvars(dhd_bus_t *bus, void *arg, int len) /* Copy the passed variables, which should include the terminating double-null */ - bcopy(arg, bus->vars, bus->varsz); + memcpy(bus->vars, arg, bus->varsz); err: return bcmerror; } @@ -2117,7 +2117,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, goto exit; if (plen >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); + memcpy(&int_val, params, sizeof(int_val)); bool_val = (int_val != 0) ? true : false; @@ -2137,7 +2137,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, bcmerror = dhdsdio_bussleep(bus, bool_val); } else { int_val = (s32) bus->sleeping; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); } goto exit; } @@ -2151,7 +2151,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, switch (actionid) { case IOV_GVAL(IOV_INTR): int_val = (s32) bus->intr; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_INTR): @@ -2172,7 +2172,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, case IOV_GVAL(IOV_POLLRATE): int_val = (s32) bus->pollrate; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_POLLRATE): @@ -2182,7 +2182,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, case IOV_GVAL(IOV_IDLETIME): int_val = bus->idletime; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_IDLETIME): @@ -2194,7 +2194,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, case IOV_GVAL(IOV_IDLECLOCK): int_val = (s32) bus->idleclock; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_IDLECLOCK): @@ -2203,7 +2203,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, case IOV_GVAL(IOV_SD1IDLE): int_val = (s32) sd1idle; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_SD1IDLE): @@ -2222,8 +2222,8 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, ASSERT(plen >= 2 * sizeof(int)); address = (u32) int_val; - bcopy((char *)params + sizeof(int_val), &int_val, - sizeof(int_val)); + memcpy(&int_val, (char *)params + sizeof(int_val), + sizeof(int_val)); size = (uint) int_val; /* Do some validation */ @@ -2266,12 +2266,12 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, case IOV_GVAL(IOV_MEMSIZE): int_val = (s32) bus->ramsize; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_GVAL(IOV_SDIOD_DRIVE): int_val = (s32) dhd_sdiod_drive_strength; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_SDIOD_DRIVE): @@ -2290,7 +2290,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, case IOV_GVAL(IOV_READAHEAD): int_val = (s32) dhd_readahead; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_READAHEAD): @@ -2301,7 +2301,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, case IOV_GVAL(IOV_SDRXCHAIN): int_val = (s32) bus->use_rxchain; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_SDRXCHAIN): @@ -2312,7 +2312,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, break; case IOV_GVAL(IOV_ALIGNCTL): int_val = (s32) dhd_alignctl; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_ALIGNCTL): @@ -2321,13 +2321,13 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, case IOV_GVAL(IOV_SDALIGN): int_val = DHD_SDALIGN; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; #ifdef DHD_DEBUG case IOV_GVAL(IOV_VARS): if (bus->varsz < (uint) len) - bcopy(bus->vars, arg, bus->varsz); + memcpy(arg, bus->vars, bus->varsz); else bcmerror = BCME_BUFTOOSHORT; break; @@ -2346,7 +2346,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, int_val = (s32) bcmsdh_reg_read(bus->sdh, addr, size); if (bcmsdh_regfail(bus->sdh)) bcmerror = BCME_SDIO_ERROR; - bcopy(&int_val, arg, sizeof(s32)); + memcpy(arg, &int_val, sizeof(s32)); break; } @@ -2372,14 +2372,14 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, sdreg_t sdreg; u32 addr, size; - bcopy(params, &sdreg, sizeof(sdreg)); + memcpy(&sdreg, params, sizeof(sdreg)); addr = SI_ENUM_BASE + sdreg.offset; size = sdreg.func; int_val = (s32) bcmsdh_reg_read(bus->sdh, addr, size); if (bcmsdh_regfail(bus->sdh)) bcmerror = BCME_SDIO_ERROR; - bcopy(&int_val, arg, sizeof(s32)); + memcpy(arg, &int_val, sizeof(s32)); break; } @@ -2388,7 +2388,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, sdreg_t sdreg; u32 addr, size; - bcopy(params, &sdreg, sizeof(sdreg)); + memcpy(&sdreg, params, sizeof(sdreg)); addr = SI_ENUM_BASE + sdreg.offset; size = sdreg.func; @@ -2419,7 +2419,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, case IOV_GVAL(IOV_FORCEEVEN): int_val = (s32) forcealign; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_FORCEEVEN): @@ -2428,7 +2428,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, case IOV_GVAL(IOV_TXBOUND): int_val = (s32) dhd_txbound; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_TXBOUND): @@ -2437,7 +2437,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, case IOV_GVAL(IOV_RXBOUND): int_val = (s32) dhd_rxbound; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_RXBOUND): @@ -2446,7 +2446,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, case IOV_GVAL(IOV_TXMINMAX): int_val = (s32) dhd_txminmax; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_TXMINMAX): @@ -2457,7 +2457,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, #ifdef SDTEST case IOV_GVAL(IOV_EXTLOOP): int_val = (s32) bus->ext_loop; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_EXTLOOP): @@ -2491,7 +2491,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, /* Get its status */ int_val = (bool) bus->dhd->dongle_reset; - bcopy(&int_val, arg, val_size); + memcpy(arg, &int_val, val_size); break; @@ -2536,7 +2536,7 @@ static int dhdsdio_write_vars(dhd_bus_t *bus) return BCME_NOMEM; memset(vbuffer, 0, varsize); - bcopy(bus->vars, vbuffer, bus->varsz); + memcpy(vbuffer, bus->vars, bus->varsz); /* Write the vars list */ bcmerror = @@ -3099,13 +3099,13 @@ dhdsdio_read_control(dhd_bus_t *bus, u8 *hdr, uint len, uint doff) ASSERT(bus->rxctl >= bus->rxbuf); /* Copy the already-read portion over */ - bcopy(hdr, bus->rxctl, firstread); + memcpy(bus->rxctl, hdr, firstread); if (len <= firstread) goto gotpkt; /* Copy the full data pkt in gSPI case and process ioctl. */ if (bus->bus == SPI_BUS) { - bcopy(hdr, bus->rxctl, len); + memcpy(bus->rxctl, hdr, len); goto gotpkt; } @@ -3769,7 +3769,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) dhd_os_sdunlock_rxq(bus->dhd); /* Now check the header */ - bcopy(rxbuf, bus->rxhdr, SDPCM_HDRLEN); + memcpy(bus->rxhdr, rxbuf, SDPCM_HDRLEN); /* Extract hardware header fields */ len = ltoh16_ua(bus->rxhdr); @@ -4135,7 +4135,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) /* Copy the already-read portion */ skb_push(pkt, firstread); - bcopy(bus->rxhdr, pkt->data, firstread); + memcpy(pkt->data, bus->rxhdr, firstread); #ifdef DHD_DEBUG if (DHD_BYTES_ON() && DHD_DATA_ON()) diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index 6841b3ad8113..50cd22979d29 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -289,7 +289,7 @@ dev_wlc_bufvar_get(struct net_device *dev, char *name, char *buf, int buflen) dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)ioctlbuf, MAX_WLIW_IOCTL_LEN); if (!error) - bcopy(ioctlbuf, buf, buflen); + memcpy(buf, ioctlbuf, buflen); return error; } @@ -841,7 +841,7 @@ wl_iw_mlme(struct net_device *dev, } scbval.val = mlme->reason_code; - bcopy(&mlme->addr.sa_data, &scbval.ea, ETH_ALEN); + memcpy(&scbval.ea, &mlme->addr.sa_data, ETH_ALEN); if (mlme->cmd == IW_MLME_DISASSOC) { scbval.val = htod32(scbval.val); @@ -1078,7 +1078,7 @@ static void wl_iw_set_event_mask(struct net_device *dev) char iovbuf[WL_EVENTING_MASK_LEN + 12]; dev_iw_iovar_getbuf(dev, "event_msgs", "", 0, iovbuf, sizeof(iovbuf)); - bcopy(iovbuf, eventmask, WL_EVENTING_MASK_LEN); + memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN); setbit(eventmask, WLC_E_SCAN_COMPLETE); dev_iw_iovar_setbuf(dev, "event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); @@ -2555,8 +2555,7 @@ wl_iw_set_encodeext(struct net_device *dev, key.len = iwe->key_len; if (!is_multicast_ether_addr(iwe->addr.sa_data)) - bcopy((void *)&iwe->addr.sa_data, (char *)&key.ea, - ETH_ALEN); + memcpy(&key.ea, &iwe->addr.sa_data, ETH_ALEN); if (key.len == 0) { if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { @@ -2581,13 +2580,13 @@ wl_iw_set_encodeext(struct net_device *dev, key.flags = WL_PRIMARY_KEY; } - bcopy((void *)iwe->key, key.data, iwe->key_len); + memcpy(key.data, iwe->key, iwe->key_len); if (iwe->alg == IW_ENCODE_ALG_TKIP) { u8 keybuf[8]; - bcopy(&key.data[24], keybuf, sizeof(keybuf)); - bcopy(&key.data[16], &key.data[24], sizeof(keybuf)); - bcopy(keybuf, &key.data[16], sizeof(keybuf)); + memcpy(keybuf, &key.data[24], sizeof(keybuf)); + memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); + memcpy(&key.data[16], keybuf, sizeof(keybuf)); } if (iwe->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { @@ -2661,10 +2660,12 @@ wl_iw_set_pmksa(struct net_device *dev, uint j; pmkidptr = &pmkid; - bcopy(&iwpmksa->bssid.sa_data[0], - &pmkidptr->pmkid[0].BSSID, ETH_ALEN); - bcopy(&iwpmksa->pmkid[0], &pmkidptr->pmkid[0].PMKID, - WLAN_PMKID_LEN); + memcpy(&pmkidptr->pmkid[0].BSSID, + &iwpmksa->bssid.sa_data[0], + ETH_ALEN); + memcpy(&pmkidptr->pmkid[0].PMKID, + &iwpmksa->pmkid[0], + WLAN_PMKID_LEN); WL_WSEC("wl_iw_set_pmksa:IW_PMKSA_REMOVE:PMKID: " "%pM = ", &pmkidptr->pmkid[0].BSSID); @@ -2683,12 +2684,12 @@ wl_iw_set_pmksa(struct net_device *dev, && (i < pmkid_list.pmkids.npmkid)) { memset(&pmkid_list.pmkids.pmkid[i], 0, sizeof(pmkid_t)); for (; i < (pmkid_list.pmkids.npmkid - 1); i++) { - bcopy(&pmkid_list.pmkids.pmkid[i + 1].BSSID, - &pmkid_list.pmkids.pmkid[i].BSSID, - ETH_ALEN); - bcopy(&pmkid_list.pmkids.pmkid[i + 1].PMKID, - &pmkid_list.pmkids.pmkid[i].PMKID, - WLAN_PMKID_LEN); + memcpy(&pmkid_list.pmkids.pmkid[i].BSSID, + &pmkid_list.pmkids.pmkid[i + 1].BSSID, + ETH_ALEN); + memcpy(&pmkid_list.pmkids.pmkid[i].PMKID, + &pmkid_list.pmkids.pmkid[i + 1].PMKID, + WLAN_PMKID_LEN); } pmkid_list.pmkids.npmkid--; } else @@ -2702,12 +2703,12 @@ wl_iw_set_pmksa(struct net_device *dev, &pmkid_list.pmkids.pmkid[i].BSSID, ETH_ALEN)) break; if (i < MAXPMKID) { - bcopy(&iwpmksa->bssid.sa_data[0], - &pmkid_list.pmkids.pmkid[i].BSSID, - ETH_ALEN); - bcopy(&iwpmksa->pmkid[0], - &pmkid_list.pmkids.pmkid[i].PMKID, - WLAN_PMKID_LEN); + memcpy(&pmkid_list.pmkids.pmkid[i].BSSID, + &iwpmksa->bssid.sa_data[0], + ETH_ALEN); + memcpy(&pmkid_list.pmkids.pmkid[i].PMKID, + &iwpmksa->pmkid[0], + WLAN_PMKID_LEN); if (i == pmkid_list.pmkids.npmkid) pmkid_list.pmkids.npmkid++; } else @@ -3491,9 +3492,9 @@ void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) if (pmkidcand->preauth) iwpmkidcand->flags |= IW_PMKID_CAND_PREAUTH; - bcopy(&pmkidcand->BSSID, - &iwpmkidcand->bssid.sa_data, - ETH_ALEN); + memcpy(&iwpmkidcand->bssid.sa_data, + &pmkidcand->BSSID, + ETH_ALEN); #ifndef SANDGATE2G wireless_send_event(dev, cmd, &wrqu, extra); diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c index 3bed37cb59b8..0760d97b3ba1 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c @@ -779,7 +779,7 @@ wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, char *vars pi->vars = (char *)&pi->vars; - bcopy(&pi->pubpi, &pi->pubpi_ro, sizeof(wlc_phy_t)); + memcpy(&pi->pubpi_ro, &pi->pubpi, sizeof(wlc_phy_t)); return &pi->pubpi_ro; @@ -1619,40 +1619,36 @@ void wlc_phy_txpower_target_set(wlc_phy_t *ppi, struct txpwr_limits *txpwr) bool mac_enabled = false; phy_info_t *pi = (phy_info_t *) ppi; - bcopy(&txpwr->cck[0], &pi->tx_user_target[TXP_FIRST_CCK], - WLC_NUM_RATES_CCK); - - bcopy(&txpwr->ofdm[0], &pi->tx_user_target[TXP_FIRST_OFDM], - WLC_NUM_RATES_OFDM); - bcopy(&txpwr->ofdm_cdd[0], &pi->tx_user_target[TXP_FIRST_OFDM_20_CDD], - WLC_NUM_RATES_OFDM); - - bcopy(&txpwr->ofdm_40_siso[0], - &pi->tx_user_target[TXP_FIRST_OFDM_40_SISO], WLC_NUM_RATES_OFDM); - bcopy(&txpwr->ofdm_40_cdd[0], - &pi->tx_user_target[TXP_FIRST_OFDM_40_CDD], WLC_NUM_RATES_OFDM); - - bcopy(&txpwr->mcs_20_siso[0], - &pi->tx_user_target[TXP_FIRST_MCS_20_SISO], - WLC_NUM_RATES_MCS_1_STREAM); - bcopy(&txpwr->mcs_20_cdd[0], &pi->tx_user_target[TXP_FIRST_MCS_20_CDD], - WLC_NUM_RATES_MCS_1_STREAM); - bcopy(&txpwr->mcs_20_stbc[0], - &pi->tx_user_target[TXP_FIRST_MCS_20_STBC], - WLC_NUM_RATES_MCS_1_STREAM); - bcopy(&txpwr->mcs_20_mimo[0], &pi->tx_user_target[TXP_FIRST_MCS_20_SDM], - WLC_NUM_RATES_MCS_2_STREAM); - - bcopy(&txpwr->mcs_40_siso[0], - &pi->tx_user_target[TXP_FIRST_MCS_40_SISO], - WLC_NUM_RATES_MCS_1_STREAM); - bcopy(&txpwr->mcs_40_cdd[0], &pi->tx_user_target[TXP_FIRST_MCS_40_CDD], - WLC_NUM_RATES_MCS_1_STREAM); - bcopy(&txpwr->mcs_40_stbc[0], - &pi->tx_user_target[TXP_FIRST_MCS_40_STBC], - WLC_NUM_RATES_MCS_1_STREAM); - bcopy(&txpwr->mcs_40_mimo[0], &pi->tx_user_target[TXP_FIRST_MCS_40_SDM], - WLC_NUM_RATES_MCS_2_STREAM); + memcpy(&pi->tx_user_target[TXP_FIRST_CCK], + &txpwr->cck[0], WLC_NUM_RATES_CCK); + + memcpy(&pi->tx_user_target[TXP_FIRST_OFDM], + &txpwr->ofdm[0], WLC_NUM_RATES_OFDM); + memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_20_CDD], + &txpwr->ofdm_cdd[0], WLC_NUM_RATES_OFDM); + + memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_SISO], + &txpwr->ofdm_40_siso[0], WLC_NUM_RATES_OFDM); + memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_CDD], + &txpwr->ofdm_40_cdd[0], WLC_NUM_RATES_OFDM); + + memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SISO], + &txpwr->mcs_20_siso[0], WLC_NUM_RATES_MCS_1_STREAM); + memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_CDD], + &txpwr->mcs_20_cdd[0], WLC_NUM_RATES_MCS_1_STREAM); + memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_STBC], + &txpwr->mcs_20_stbc[0], WLC_NUM_RATES_MCS_1_STREAM); + memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SDM], + &txpwr->mcs_20_mimo[0], WLC_NUM_RATES_MCS_2_STREAM); + + memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SISO], + &txpwr->mcs_40_siso[0], WLC_NUM_RATES_MCS_1_STREAM); + memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_CDD], + &txpwr->mcs_40_cdd[0], WLC_NUM_RATES_MCS_1_STREAM); + memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_STBC], + &txpwr->mcs_40_stbc[0], WLC_NUM_RATES_MCS_1_STREAM); + memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SDM], + &txpwr->mcs_40_mimo[0], WLC_NUM_RATES_MCS_2_STREAM); if (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC) mac_enabled = true; diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c index 3ac2b49d9a9d..3fbbbb46a360 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c @@ -1965,8 +1965,9 @@ wlc_lcnphy_tx_iqlo_cal(phy_info_t *pi, tbl_iqcal_gainparams_lcnphy[band_idx][j][2]; cal_gains.pad_gain = tbl_iqcal_gainparams_lcnphy[band_idx][j][3]; - bcopy(&tbl_iqcal_gainparams_lcnphy[band_idx][j][3], - ncorr_override, sizeof(ncorr_override)); + memcpy(ncorr_override, + &tbl_iqcal_gainparams_lcnphy[band_idx][j][3], + sizeof(ncorr_override)); break; } } diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 07871679daaf..18f1ccfa0d4f 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -799,7 +799,7 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, goto fail; } - bcopy(&wl->pub->cur_etheraddr, perm, ETH_ALEN); + memcpy(perm, &wl->pub->cur_etheraddr, ETH_ALEN); ASSERT(is_valid_ether_addr(perm)); SET_IEEE80211_PERM_ADDR(hw, perm); @@ -1754,7 +1754,7 @@ int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx) hdr->len); goto fail; } - bcopy(pdata, *pbuf, hdr->len); + memcpy(*pbuf, pdata, hdr->len); return 0; } } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index f344e383d5c9..ca27e826e14f 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -1324,7 +1324,7 @@ void wlc_ampdu_macaddr_upd(struct wlc_info *wlc) /* driver needs to write the ta in the template; ta is at offset 16 */ memset(template, 0, sizeof(template)); - bcopy((char *)wlc->pub->cur_etheraddr, template, ETH_ALEN); + memcpy(template, wlc->pub->cur_etheraddr, ETH_ALEN); wlc_write_template_ram(wlc, (T_BA_TPL_BASE + 16), (T_RAM_ACCESS_SZ * 2), template); } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index c21977929ff8..ac068cdc578b 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -1275,7 +1275,7 @@ void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw) void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, u8 *ea) { - bcopy(wlc_hw->etheraddr, ea, ETH_ALEN); + memcpy(ea, wlc_hw->etheraddr, ETH_ALEN); } int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw) @@ -1698,7 +1698,7 @@ wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, int len, be_bit = (R_REG(osh, ®s->maccontrol) & MCTL_BIGEND) != 0; while (len > 0) { - bcopy((u8 *) buf, &word, sizeof(u32)); + memcpy(&word, buf, sizeof(u32)); if (be_bit) word = hton32(word); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index 5b2b93f2b2e5..cb1a8026262d 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -1005,7 +1005,7 @@ static int wlc_get_current_txpwr(struct wlc_info *wlc, void *pwr, uint len) * or convert to a tx_power_legacy_t struct */ if (!old_power) { - bcopy(&power, pwr, sizeof(tx_power_t)); + memcpy(pwr, &power, sizeof(tx_power_t)); } else { int band_idx = CHSPEC_IS2G(power.chanspec) ? 0 : 1; @@ -1855,8 +1855,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, wlc_bmac_hw_etheraddr(wlc->hw, wlc->perm_etheraddr); - bcopy((char *)&wlc->perm_etheraddr, (char *)&pub->cur_etheraddr, - ETH_ALEN); + memcpy(&pub->cur_etheraddr, &wlc->perm_etheraddr, ETH_ALEN); for (j = 0; j < NBANDS(wlc); j++) { /* Use band 1 for single band 11a */ @@ -2916,8 +2915,8 @@ int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) /* Set default bss rateset */ wlc->default_bss->rateset.count = rs.count; - bcopy((char *)rs.rates, (char *)wlc->default_bss->rateset.rates, - sizeof(wlc->default_bss->rateset.rates)); + memcpy(wlc->default_bss->rateset.rates, rs.rates, + sizeof(wlc->default_bss->rateset.rates)); return ret; } @@ -3010,7 +3009,7 @@ static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg) wlc_rateset_t rs, new; uint bandunit; - bcopy((char *)rs_arg, (char *)&rs, sizeof(wlc_rateset_t)); + memcpy(&rs, rs_arg, sizeof(wlc_rateset_t)); /* check for bad count value */ if ((rs.count == 0) || (rs.count > WLC_NUMRATES)) @@ -3018,7 +3017,7 @@ static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg) /* try the current band */ bandunit = wlc->band->bandunit; - bcopy((char *)&rs, (char *)&new, sizeof(wlc_rateset_t)); + memcpy(&new, &rs, sizeof(wlc_rateset_t)); if (wlc_rate_hwrs_filter_sort_validate (&new, &wlc->bandstate[bandunit]->hw_rateset, true, wlc->stf->txstreams)) @@ -3027,7 +3026,7 @@ static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg) /* try the other band */ if (IS_MBAND_UNLOCKED(wlc)) { bandunit = OTHERBANDUNIT(wlc); - bcopy((char *)&rs, (char *)&new, sizeof(wlc_rateset_t)); + memcpy(&new, &rs, sizeof(wlc_rateset_t)); if (wlc_rate_hwrs_filter_sort_validate(&new, &wlc-> bandstate[bandunit]-> @@ -3040,10 +3039,9 @@ static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg) good: /* apply new rateset */ - bcopy((char *)&new, (char *)&wlc->default_bss->rateset, - sizeof(wlc_rateset_t)); - bcopy((char *)&new, (char *)&wlc->bandstate[bandunit]->defrateset, - sizeof(wlc_rateset_t)); + memcpy(&wlc->default_bss->rateset, &new, sizeof(wlc_rateset_t)); + memcpy(&wlc->bandstate[bandunit]->defrateset, &new, + sizeof(wlc_rateset_t)); return 0; } @@ -3123,7 +3121,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, /* This will prevent the misaligned access */ if (pval && (u32) len >= sizeof(val)) - bcopy(pval, &val, sizeof(val)); + memcpy(&val, pval, sizeof(val)); else val = 0; @@ -3612,18 +3610,17 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, if (src_key) { key.index = src_key->id; key.len = src_key->len; - bcopy(src_key->data, key.data, key.len); + memcpy(key.data, src_key->data, key.len); key.algo = src_key->algo; if (WSEC_SOFTKEY(wlc, src_key, bsscfg)) key.flags |= WL_SOFT_KEY; if (src_key->flags & WSEC_PRIMARY_KEY) key.flags |= WL_PRIMARY_KEY; - bcopy(src_key->ea, key.ea, - ETH_ALEN); + memcpy(key.ea, src_key->ea, ETH_ALEN); } - bcopy((char *)&key, arg, sizeof(key)); + memcpy(arg, &key, sizeof(key)); } else bcmerror = BCME_BADKEYIDX; break; @@ -3674,7 +3671,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, seq[6] = 0; seq[7] = 0; - bcopy((char *)seq, arg, sizeof(seq)); + memcpy(arg, seq, sizeof(seq)); } else { bcmerror = BCME_BADKEYIDX; } @@ -3697,7 +3694,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, /* Copy only legacy rateset section */ ret_rs->count = rs->count; - bcopy(&rs->rates, &ret_rs->rates, rs->count); + memcpy(&ret_rs->rates, &rs->rates, rs->count); break; } @@ -3715,7 +3712,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, /* Copy only legacy rateset section */ ret_rs->count = rs.count; - bcopy(&rs.rates, &ret_rs->rates, rs.count); + memcpy(&ret_rs->rates, &rs.rates, rs.count); break; } @@ -3737,16 +3734,18 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, /* Copy only legacy rateset section */ rs.count = in_rs->count; - bcopy(&in_rs->rates, &rs.rates, rs.count); + memcpy(&rs.rates, &in_rs->rates, rs.count); /* merge rateset coming in with the current mcsset */ if (N_ENAB(wlc->pub)) { if (bsscfg->associated) - bcopy(¤t_bss->rateset.mcs[0], - rs.mcs, MCSSET_LEN); + memcpy(rs.mcs, + ¤t_bss->rateset.mcs[0], + MCSSET_LEN); else - bcopy(&wlc->default_bss->rateset.mcs[0], - rs.mcs, MCSSET_LEN); + memcpy(rs.mcs, + &wlc->default_bss->rateset.mcs[0], + MCSSET_LEN); } bcmerror = wlc_set_rateset(wlc, &rs); @@ -4048,7 +4047,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, bcmerror = BCME_BUFTOOSHORT; break; } - bcopy((char *)arg, (char *)&rs, sizeof(wlc_rateset_t)); + memcpy(&rs, arg, sizeof(wlc_rateset_t)); /* check for bad count value */ if (rs.count > WLC_NUMRATES) { @@ -4084,7 +4083,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, } /* apply new rateset to the override */ - bcopy((char *)&new, (char *)&wlc->sup_rates_override, + memcpy(&wlc->sup_rates_override, &new, sizeof(wlc_rateset_t)); /* update bcn and probe resp if needed */ @@ -4108,8 +4107,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, bcmerror = BCME_BUFTOOSHORT; break; } - bcopy((char *)&wlc->sup_rates_override, (char *)arg, - sizeof(wlc_rateset_t)); + memcpy(arg, &wlc->sup_rates_override, sizeof(wlc_rateset_t)); break; @@ -4518,7 +4516,7 @@ wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, void *arg, int len, case IOVT_UINT8: case IOVT_UINT16: case IOVT_UINT32: - bcopy(arg, &int_val, sizeof(int)); + memcpy(&int_val, arg, sizeof(int)); err = wlc_iovar_rangecheck(wlc, int_val, vi); break; } @@ -4562,11 +4560,12 @@ wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, /* convenience int and bool vals for first 8 bytes of buffer */ if (p_len >= (int)sizeof(int_val)) - bcopy(params, &int_val, sizeof(int_val)); + memcpy(&int_val, params, sizeof(int_val)); if (p_len >= (int)sizeof(int_val) * 2) - bcopy((void *)((unsigned long)params + sizeof(int_val)), &int_val2, - sizeof(int_val)); + memcpy(&int_val2, + (void *)((unsigned long)params + sizeof(int_val)), + sizeof(int_val)); /* convenience int ptr for 4-byte gets (requires int aligned arg) */ ret_int_ptr = (s32 *) arg; @@ -6061,8 +6060,8 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* (3) PLCP: determine PLCP header and MAC duration, fill d11txh_t */ wlc_compute_plcp(wlc, rspec[0], phylen, plcp); wlc_compute_plcp(wlc, rspec[1], phylen, plcp_fallback); - bcopy(plcp_fallback, (char *)&txh->FragPLCPFallback, - sizeof(txh->FragPLCPFallback)); + memcpy(&txh->FragPLCPFallback, + plcp_fallback, sizeof(txh->FragPLCPFallback)); /* Length field now put in CCK FBR CRC field */ if (IS_CCK(rspec[1])) { @@ -6135,14 +6134,13 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, } /* MacFrameControl */ - bcopy((char *)&h->frame_control, (char *)&txh->MacFrameControl, - sizeof(u16)); + memcpy(&txh->MacFrameControl, &h->frame_control, sizeof(u16)); txh->TxFesTimeNormal = htol16(0); txh->TxFesTimeFallback = htol16(0); /* TxFrameRA */ - bcopy((char *)&h->addr1, (char *)&txh->TxFrameRA, ETH_ALEN); + memcpy(&txh->TxFrameRA, &h->addr1, ETH_ALEN); /* TxFrameID */ txh->TxFrameID = htol16(frameid); @@ -6207,8 +6205,8 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* fallback rate version of RTS PLCP header */ wlc_compute_plcp(wlc, rts_rspec[1], rts_phylen, rts_plcp_fallback); - bcopy(rts_plcp_fallback, (char *)&txh->RTSPLCPFallback, - sizeof(txh->RTSPLCPFallback)); + memcpy(&txh->RTSPLCPFallback, rts_plcp_fallback, + sizeof(txh->RTSPLCPFallback)); /* RTS frame fields... */ rts = (struct ieee80211_rts *)&txh->rts_frame; @@ -6226,11 +6224,10 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, if (use_cts) { rts->frame_control = htol16(FC_CTS); - bcopy((char *)&h->addr2, (char *)&rts->ra, ETH_ALEN); + memcpy(&rts->ra, &h->addr2, ETH_ALEN); } else { rts->frame_control = htol16((u16) FC_RTS); - bcopy((char *)&h->addr1, (char *)&rts->ra, - 2 * ETH_ALEN); + memcpy(&rts->ra, &h->addr1, 2 * ETH_ALEN); } /* mainrate @@ -7726,10 +7723,9 @@ wlc_bcn_prb_template(struct wlc_info *wlc, uint type, ratespec_t bcn_rspec, /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */ /* A1 filled in by MAC for prb resp, broadcast for bcn */ if (type == FC_BEACON) - bcopy((const char *)ðer_bcast, (char *)&h->da, - ETH_ALEN); - bcopy((char *)&cfg->cur_etheraddr, (char *)&h->sa, ETH_ALEN); - bcopy((char *)&cfg->BSSID, (char *)&h->bssid, ETH_ALEN); + memcpy(&h->da, ðer_bcast, ETH_ALEN); + memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN); + memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN); /* SEQ filled in by MAC */ @@ -7820,7 +7816,7 @@ void wlc_shm_ssid_upd(struct wlc_info *wlc, wlc_bsscfg_t *cfg) /* padding the ssid with zero and copy it into shm */ memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN); - bcopy(ssidptr, ssidbuf, cfg->SSID_len); + memcpy(ssidbuf, ssidptr, cfg->SSID_len); wlc_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c index ab7d0bed3c0a..6904f8b19092 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c @@ -382,7 +382,7 @@ ratespec_t BCMFASTPATH wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp) /* copy rateset src to dst as-is (no masking or sorting) */ void wlc_rateset_copy(const wlc_rateset_t *src, wlc_rateset_t *dst) { - bcopy(src, dst, sizeof(wlc_rateset_t)); + memcpy(dst, src, sizeof(wlc_rateset_t)); } /* @@ -417,7 +417,7 @@ wlc_rateset_filter(wlc_rateset_t *src, wlc_rateset_t *dst, bool basic_only, dst->htphy_membership = src->htphy_membership; if (mcsallow && rates != WLC_RATES_CCK) - bcopy(&src->mcs[0], &dst->mcs[0], MCSSET_LEN); + memcpy(&dst->mcs[0], &src->mcs[0], MCSSET_LEN); else wlc_rateset_mcs_clear(dst); } @@ -487,7 +487,7 @@ void wlc_rateset_mcs_clear(wlc_rateset_t *rateset) void wlc_rateset_mcs_build(wlc_rateset_t *rateset, u8 txstreams) { - bcopy(&cck_ofdm_mimo_rates.mcs[0], &rateset->mcs[0], MCSSET_LEN); + memcpy(&rateset->mcs[0], &cck_ofdm_mimo_rates.mcs[0], MCSSET_LEN); wlc_rateset_mcs_upd(rateset, txstreams); } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c index a1a1767f1d3a..8b7620f2b880 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c @@ -489,7 +489,7 @@ void wlc_stf_phy_chain_calc(struct wlc_info *wlc) wlc->stf->rxstreams = (u8) WLC_BITSCNT(wlc->stf->hw_rxchain); /* initialize the txcore table */ - bcopy(txcore_default, wlc->stf->txcore, sizeof(wlc->stf->txcore)); + memcpy(wlc->stf->txcore, txcore_default, sizeof(wlc->stf->txcore)); /* default spatial_policy */ wlc->stf->spatial_policy = MIN_SPATIAL_EXPANSION; diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index 919b12af0c81..17fc274ef240 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -110,8 +110,6 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, #include /* for vsn/printf's */ #include /* for mem*, str* */ #endif -/* bcopy's: Linux kernel doesn't provide these (anymore) */ -#define bcopy(src, dst, len) memcpy((dst), (src), (len)) /* register access macros */ #ifndef IL_BIGENDIAN @@ -204,8 +202,6 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, } while (0) #endif /* IL_BIGENDIAN */ -#define bcopy(src, dst, len) memcpy((dst), (src), (len)) - /* packet primitives */ extern struct sk_buff *pkt_buf_get_skb(struct osl_info *osh, uint len); extern void pkt_buf_free_skb(struct osl_info *osh, struct sk_buff *skb, bool send); diff --git a/drivers/staging/brcm80211/util/bcmotp.c b/drivers/staging/brcm80211/util/bcmotp.c index d820e7b9e970..6fa04ed93501 100644 --- a/drivers/staging/brcm80211/util/bcmotp.c +++ b/drivers/staging/brcm80211/util/bcmotp.c @@ -818,7 +818,7 @@ static int hndotp_nvread(void *oh, char *data, uint *len) if (offset + dsz >= *len) { goto out; } - bcopy((char *)&rawotp[i + 2], &data[offset], dsz); + memcpy(&data[offset], &rawotp[i + 2], dsz); offset += dsz; /* Remove extra null characters at the end */ while (offset > 1 && diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index 622cd309c6a7..b26877c46023 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -1336,8 +1336,8 @@ int srom_parsecis(struct osl_info *osh, u8 *pcis[], uint ciscnt, char **vars, u8 srev = cis[i + 1 + 70]; ASSERT(srev == 3); /* make tuple value 16-bit aligned and parse it */ - bcopy(&cis[i + 1], srom, - sizeof(srom)); + memcpy(srom, &cis[i + 1], + sizeof(srom)); _initvars_srom_pci(srev, srom, SROM3_SWRGN_OFF, &b); @@ -1518,7 +1518,7 @@ static int otp_read_pci(struct osl_info *osh, si_t *sih, u16 *buf, uint bufsz) err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz); - bcopy(otp, buf, bufsz); + memcpy(buf, otp, bufsz); if (otp) kfree(otp); @@ -1562,7 +1562,7 @@ static int initvars_table(struct osl_info *osh, char *start, char *end, ASSERT(vp != NULL); if (!vp) return BCME_NOMEM; - bcopy(start, vp, c); + memcpy(vp, start, c); *vars = vp; *count = c; } else { diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index 35c1b6d6b50e..707fd0da3d36 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -50,7 +50,7 @@ uint pktfrombuf(struct osl_info *osh, struct sk_buff *p, uint offset, int len, /* copy the data */ for (; p && len; p = p->next) { n = min((uint) (p->len) - offset, (uint) len); - bcopy(buf, p->data + offset, n); + memcpy(p->data + offset, buf, n); buf += n; len -= n; ret += n; diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 47dceb302447..3f1d63ee7c48 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -1758,8 +1758,8 @@ static void dma64_txrotate(dma_info_t *di) /* Move the map */ if (DMASGLIST_ENAB) { - bcopy(&di->txp_dmah[old], &di->txp_dmah[new], - sizeof(hnddma_seg_map_t)); + memcpy(&di->txp_dmah[new], &di->txp_dmah[old], + sizeof(hnddma_seg_map_t)); memset(&di->txp_dmah[old], 0, sizeof(hnddma_seg_map_t)); } diff --git a/drivers/staging/brcm80211/util/nvram/nvram_ro.c b/drivers/staging/brcm80211/util/nvram/nvram_ro.c index e4d41ee78e2a..b2e6c0df137e 100644 --- a/drivers/staging/brcm80211/util/nvram/nvram_ro.c +++ b/drivers/staging/brcm80211/util/nvram/nvram_ro.c @@ -70,7 +70,7 @@ static void get_flash_nvram(si_t *sih, struct nvram_header *nvh) new->next = vars; vars = new; - bcopy((char *)(&nvh[1]), new->vars, nvs); + memcpy(new->vars, &nvh[1], nvs); NVR_MSG(("%s: flash nvram @ %p, copied %d bytes to %p\n", __func__, nvh, nvs, new->vars)); @@ -195,7 +195,7 @@ int nvram_getall(char *buf, int count) len = strlen(from) + 1; if (resid < (acc + len)) return BCME_BUFTOOSHORT; - bcopy(from, to, len); + memcpy(to, from, len); acc += len; from += len; to += len; diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index b0e7695097e8..5631d5b55c22 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -697,7 +697,7 @@ void si_detach(si_t *sih) uint idx; struct si_pub *si_local = NULL; - bcopy(&sih, &si_local, sizeof(si_t **)); + memcpy(&si_local, &sih, sizeof(si_t **)); sii = SI_INFO(sih); -- cgit v1.2.3 From 59909c7c296a9f75ff395db2006de0aa6f57e7a7 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 15 Feb 2011 11:13:50 +0100 Subject: staging: brcm80211: bugfix for oops on firmware load problems Upon firmware load failure, wl_release_fw() was called multiple times. This caused the driver to oops. Solution was to remove redundant wl_release_fw() calls. Signed-off-by: Roland Vossen Reviewed-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 18f1ccfa0d4f..bf98a151de6d 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -1804,7 +1804,6 @@ static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) if (status) { WL_ERROR("%s: fail to load firmware %s\n", KBUILD_MODNAME, fw_name); - wl_release_fw(wl); return status; } WL_NONE("request fw %s\n", fw_name); @@ -1814,7 +1813,6 @@ static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) if (status) { WL_ERROR("%s: fail to load firmware %s\n", KBUILD_MODNAME, fw_name); - wl_release_fw(wl); return status; } wl->fw.hdr_num_entries[i] = -- cgit v1.2.3 From 490e00f68534cd724ba8e486ff6cd6b10d1891b1 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 15 Feb 2011 11:13:51 +0100 Subject: staging: brcm80211: bugfix for stack dump on firmware load problems If there is a problem with the firmware load (eg, firmware not present in /lib/firmware/brcm), then the driver would dump its stack instead of bailing out gracefully. Root cause was an uninitialized variable (wl->pub) being dereferenced in the rfkill portion of a cleanup routine (wl_remove). Fix was to move the rfkill calls into the correct spot in wl_remove(). Signed-off-by: Roland Vossen Reviewed-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index bf98a151de6d..20afb13614ea 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -1206,15 +1206,13 @@ static void wl_remove(struct pci_dev *pdev) return; } - /* make sure rfkill is not using driver */ - wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); - wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); - if (!wlc_chipmatch(pdev->vendor, pdev->device)) { WL_ERROR("wl: wl_remove: wlc_chipmatch failed\n"); return; } if (wl->wlc) { + wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); + wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); ieee80211_unregister_hw(hw); WL_LOCK(wl); wl_down(wl); -- cgit v1.2.3 From 7249e6a17bacbb18c4baf1b0d5ca70925409120d Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 15 Feb 2011 12:35:40 +0100 Subject: staging: brcm80211: improved checks on incompatible firmware The return status of wl_ucode_init_buf() is now being used. Also a bug in firmware validation, which could lead to incompatible firmware not being rejected by the driver, has been fixed. Comment from Dan Carpenter on using negative error values has been incorporated in this commit. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 8 ++-- .../staging/brcm80211/brcmsmac/wl_ucode_loader.c | 56 ++++++++++++---------- 2 files changed, 35 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 20afb13614ea..56f5d3a26414 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -755,7 +755,7 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, spin_lock_init(&wl->isr_lock); /* prepare ucode */ - if (wl_request_fw(wl, (struct pci_dev *)btparam)) { + if (wl_request_fw(wl, (struct pci_dev *)btparam) < 0) { WL_ERROR("%s: Failed to find firmware usually in %s\n", KBUILD_MODNAME, "/lib/firmware/brcm"); wl_release_fw(wl); @@ -1760,7 +1760,7 @@ int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx) WL_ERROR("ERROR: ucode buf tag:%d can not be found!\n", idx); *pbuf = NULL; fail: - return -1; + return BCME_NOTFOUND; } int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx) @@ -1868,8 +1868,8 @@ int wl_check_firmwares(struct wl_info *wl) } else { /* check if ucode section overruns firmware image */ ucode_hdr = (struct wl_fw_hdr *)fw_hdr->data; - for (entry = 0; entry < wl->fw.hdr_num_entries[i] && rc; - entry++, ucode_hdr++) { + for (entry = 0; entry < wl->fw.hdr_num_entries[i] && + !rc; entry++, ucode_hdr++) { if (ucode_hdr->offset + ucode_hdr->len > fw->size) { WL_ERROR("%s: conflicting bin/hdr\n", diff --git a/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c b/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c index 23e10f3dec0d..c84e6a70e71d 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c @@ -41,32 +41,38 @@ int wl_ucode_data_init(struct wl_info *wl) { int rc; rc = wl_check_firmwares(wl); - if (rc < 0) - return rc; - wl_ucode_init_buf(wl, (void **)&d11lcn0bsinitvals24, - D11LCN0BSINITVALS24); - wl_ucode_init_buf(wl, (void **)&d11lcn0initvals24, D11LCN0INITVALS24); - wl_ucode_init_buf(wl, (void **)&d11lcn1bsinitvals24, - D11LCN1BSINITVALS24); - wl_ucode_init_buf(wl, (void **)&d11lcn1initvals24, D11LCN1INITVALS24); - wl_ucode_init_buf(wl, (void **)&d11lcn2bsinitvals24, - D11LCN2BSINITVALS24); - wl_ucode_init_buf(wl, (void **)&d11lcn2initvals24, D11LCN2INITVALS24); - wl_ucode_init_buf(wl, (void **)&d11n0absinitvals16, D11N0ABSINITVALS16); - wl_ucode_init_buf(wl, (void **)&d11n0bsinitvals16, D11N0BSINITVALS16); - wl_ucode_init_buf(wl, (void **)&d11n0initvals16, D11N0INITVALS16); - wl_ucode_init_buf(wl, (void **)&bcm43xx_16_mimo, - D11UCODE_OVERSIGHT16_MIMO); - wl_ucode_init_uint(wl, &bcm43xx_16_mimosz, D11UCODE_OVERSIGHT16_MIMOSZ); - wl_ucode_init_buf(wl, (void **)&bcm43xx_24_lcn, - D11UCODE_OVERSIGHT24_LCN); - wl_ucode_init_uint(wl, &bcm43xx_24_lcnsz, D11UCODE_OVERSIGHT24_LCNSZ); - wl_ucode_init_buf(wl, (void **)&bcm43xx_bommajor, - D11UCODE_OVERSIGHT_BOMMAJOR); - wl_ucode_init_buf(wl, (void **)&bcm43xx_bomminor, - D11UCODE_OVERSIGHT_BOMMINOR); - return 0; + rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn0bsinitvals24, + D11LCN0BSINITVALS24); + rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn0initvals24, + D11LCN0INITVALS24); + rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn1bsinitvals24, + D11LCN1BSINITVALS24); + rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn1initvals24, + D11LCN1INITVALS24); + rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn2bsinitvals24, + D11LCN2BSINITVALS24); + rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn2initvals24, + D11LCN2INITVALS24); + rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11n0absinitvals16, + D11N0ABSINITVALS16); + rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11n0bsinitvals16, + D11N0BSINITVALS16); + rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11n0initvals16, + D11N0INITVALS16); + rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_16_mimo, + D11UCODE_OVERSIGHT16_MIMO); + rc = rc < 0 ? rc : wl_ucode_init_uint(wl, &bcm43xx_16_mimosz, + D11UCODE_OVERSIGHT16_MIMOSZ); + rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_24_lcn, + D11UCODE_OVERSIGHT24_LCN); + rc = rc < 0 ? rc : wl_ucode_init_uint(wl, &bcm43xx_24_lcnsz, + D11UCODE_OVERSIGHT24_LCNSZ); + rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_bommajor, + D11UCODE_OVERSIGHT_BOMMAJOR); + rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_bomminor, + D11UCODE_OVERSIGHT_BOMMINOR); + return rc; } void wl_ucode_data_free(void) -- cgit v1.2.3 From df3493e0b3ba72f9b6192a91b24197cac41ce557 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Fri, 11 Feb 2011 09:59:00 -0800 Subject: Staging: hv: Use native page allocation/free functions In preperation for getting rid of the osd.[ch] files; change all page allocation/free functions to use native interfaces. Signed-off-by: K. Y. Srinivasan Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel.c | 12 +++++++----- drivers/staging/hv/connection.c | 13 ++++++++----- drivers/staging/hv/hv.c | 15 ++++++++++----- drivers/staging/hv/netvsc.c | 14 ++++++++------ 4 files changed, 33 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index ba9afdabedc1..6c292e69e991 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -180,8 +180,9 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, newchannel->channel_callback_context = context; /* Allocate the ring buffer */ - out = osd_page_alloc((send_ringbuffer_size + recv_ringbuffer_size) - >> PAGE_SHIFT); + out = (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, + get_order(send_ringbuffer_size + recv_ringbuffer_size)); + if (!out) return -ENOMEM; @@ -300,8 +301,8 @@ Cleanup: errorout: ringbuffer_cleanup(&newchannel->outbound); ringbuffer_cleanup(&newchannel->inbound); - osd_page_free(out, (send_ringbuffer_size + recv_ringbuffer_size) - >> PAGE_SHIFT); + free_pages((unsigned long)out, + get_order(send_ringbuffer_size + recv_ringbuffer_size)); kfree(openInfo); return err; } @@ -686,7 +687,8 @@ void vmbus_close(struct vmbus_channel *channel) ringbuffer_cleanup(&channel->outbound); ringbuffer_cleanup(&channel->inbound); - osd_page_free(channel->ringbuffer_pages, channel->ringbuffer_pagecount); + free_pages((unsigned long)channel->ringbuffer_pages, + get_order(channel->ringbuffer_pagecount * PAGE_SIZE)); kfree(info); diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index b3ac66e5499f..ed0976aad6f0 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -66,7 +66,8 @@ int vmbus_connect(void) * Setup the vmbus event connection for channel interrupt * abstraction stuff */ - vmbus_connection.int_page = osd_page_alloc(1); + vmbus_connection.int_page = + (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, 0); if (vmbus_connection.int_page == NULL) { ret = -1; goto Cleanup; @@ -81,7 +82,8 @@ int vmbus_connect(void) * Setup the monitor notification facility. The 1st page for * parent->child and the 2nd page for child->parent */ - vmbus_connection.monitor_pages = osd_page_alloc(2); + vmbus_connection.monitor_pages = + (void *)__get_free_pages((GFP_KERNEL|__GFP_ZERO), 1); if (vmbus_connection.monitor_pages == NULL) { ret = -1; goto Cleanup; @@ -162,12 +164,12 @@ Cleanup: destroy_workqueue(vmbus_connection.work_queue); if (vmbus_connection.int_page) { - osd_page_free(vmbus_connection.int_page, 1); + free_pages((unsigned long)vmbus_connection.int_page, 0); vmbus_connection.int_page = NULL; } if (vmbus_connection.monitor_pages) { - osd_page_free(vmbus_connection.monitor_pages, 2); + free_pages((unsigned long)vmbus_connection.monitor_pages, 1); vmbus_connection.monitor_pages = NULL; } @@ -203,7 +205,8 @@ int vmbus_disconnect(void) if (ret != 0) goto Cleanup; - osd_page_free(vmbus_connection.int_page, 1); + free_pages((unsigned long)vmbus_connection.int_page, 0); + free_pages((unsigned long)vmbus_connection.monitor_pages, 1); /* TODO: iterate thru the msg list and free up */ destroy_workqueue(vmbus_connection.work_queue); diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c index 021acbaae247..419b4d6aef63 100644 --- a/drivers/staging/hv/hv.c +++ b/drivers/staging/hv/hv.c @@ -230,7 +230,12 @@ int hv_init(void) * Allocate the hypercall page memory * virtaddr = osd_page_alloc(1); */ - virtaddr = osd_virtual_alloc_exec(PAGE_SIZE); +#ifdef __x86_64__ + virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_EXEC); +#else + virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, + __pgprot(__PAGE_KERNEL & (~_PAGE_NX))); +#endif if (!virtaddr) { DPRINT_ERR(VMBUS, @@ -462,10 +467,10 @@ void hv_synic_init(void *irqarg) Cleanup: if (hv_context.synic_event_page[cpu]) - osd_page_free(hv_context.synic_event_page[cpu], 1); + free_page((unsigned long)hv_context.synic_event_page[cpu]); if (hv_context.synic_message_page[cpu]) - osd_page_free(hv_context.synic_message_page[cpu], 1); + free_page((unsigned long)hv_context.synic_message_page[cpu]); return; } @@ -502,6 +507,6 @@ void hv_synic_cleanup(void *arg) wrmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64); - osd_page_free(hv_context.synic_message_page[cpu], 1); - osd_page_free(hv_context.synic_event_page[cpu], 1); + free_page((unsigned long)hv_context.synic_message_page[cpu]); + free_page((unsigned long)hv_context.synic_event_page[cpu]); } diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index 431936338731..a271aa790c93 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -223,7 +223,8 @@ static int netvsc_init_recv_buf(struct hv_device *device) /* ASSERT((netDevice->ReceiveBufferSize & (PAGE_SIZE - 1)) == 0); */ net_device->recv_buf = - osd_page_alloc(net_device->recv_buf_size >> PAGE_SHIFT); + (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, + get_order(net_device->recv_buf_size)); if (!net_device->recv_buf) { DPRINT_ERR(NETVSC, "unable to allocate receive buffer of size %d", @@ -360,7 +361,8 @@ static int netvsc_init_send_buf(struct hv_device *device) /* ASSERT((netDevice->SendBufferSize & (PAGE_SIZE - 1)) == 0); */ net_device->send_buf = - osd_page_alloc(net_device->send_buf_size >> PAGE_SHIFT); + (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, + get_order(net_device->send_buf_size)); if (!net_device->send_buf) { DPRINT_ERR(NETVSC, "unable to allocate send buffer of size %d", net_device->send_buf_size); @@ -498,8 +500,8 @@ static int netvsc_destroy_recv_buf(struct netvsc_device *net_device) DPRINT_INFO(NETVSC, "Freeing up receive buffer..."); /* Free up the receive buffer */ - osd_page_free(net_device->recv_buf, - net_device->recv_buf_size >> PAGE_SHIFT); + free_pages((unsigned long)net_device->recv_buf, + get_order(net_device->recv_buf_size)); net_device->recv_buf = NULL; } @@ -574,8 +576,8 @@ static int netvsc_destroy_send_buf(struct netvsc_device *net_device) DPRINT_INFO(NETVSC, "Freeing up send buffer..."); /* Free up the receive buffer */ - osd_page_free(net_device->send_buf, - net_device->send_buf_size >> PAGE_SHIFT); + free_pages((unsigned long)net_device->send_buf, + get_order(net_device->send_buf_size)); net_device->send_buf = NULL; } -- cgit v1.2.3 From 0c3b7b2f75158f9420ceeb87d5924bdbd8d0304a Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Fri, 11 Feb 2011 09:59:43 -0800 Subject: Staging: hv: Use native wait primitives In preperation for getting rid of the osd layer; change the code to use native wait interfaces. As part of this, fixed the buggy implementation in the osd_wait_primitive where the condition was cleared potentially after the condition was signalled. Signed-off-by: K. Y. Srinivasan Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel.c | 58 ++++++++++----------- drivers/staging/hv/channel_mgmt.c | 46 ++++++++--------- drivers/staging/hv/channel_mgmt.h | 4 +- drivers/staging/hv/connection.c | 28 +++++++--- drivers/staging/hv/netvsc.c | 102 +++++++++++++++++++------------------ drivers/staging/hv/netvsc.h | 3 +- drivers/staging/hv/rndis_filter.c | 38 +++++++++----- drivers/staging/hv/storvsc.c | 98 ++++++++++++++++++++--------------- drivers/staging/hv/vmbus_private.h | 3 +- 9 files changed, 208 insertions(+), 172 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index 6c292e69e991..5a0923ca565f 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -19,6 +19,8 @@ * Hank Janssen */ #include +#include +#include #include #include #include @@ -243,11 +245,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, goto errorout; } - openInfo->waitevent = osd_waitevent_create(); - if (!openInfo->waitevent) { - err = -ENOMEM; - goto errorout; - } + init_waitqueue_head(&openInfo->waitevent); openMsg = (struct vmbus_channel_open_channel *)openInfo->msg; openMsg->header.msgtype = CHANNELMSG_OPENCHANNEL; @@ -280,8 +278,15 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, goto Cleanup; } - /* FIXME: Need to time-out here */ - osd_waitevent_wait(openInfo->waitevent); + openInfo->wait_condition = 0; + wait_event_timeout(openInfo->waitevent, + openInfo->wait_condition, + msecs_to_jiffies(1000)); + if (openInfo->wait_condition == 0) { + err = -ETIMEDOUT; + goto errorout; + } + if (openInfo->response.open_result.status == 0) DPRINT_INFO(VMBUS, "channel <%p> open success!!", newchannel); @@ -294,7 +299,6 @@ Cleanup: list_del(&openInfo->msglistentry); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); - kfree(openInfo->waitevent); kfree(openInfo); return 0; @@ -509,11 +513,7 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, if (ret) return ret; - msginfo->waitevent = osd_waitevent_create(); - if (!msginfo->waitevent) { - ret = -ENOMEM; - goto Cleanup; - } + init_waitqueue_head(&msginfo->waitevent); gpadlmsg = (struct vmbus_channel_gpadl_header *)msginfo->msg; gpadlmsg->header.msgtype = CHANNELMSG_GPADL_HEADER; @@ -533,6 +533,7 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, DPRINT_DBG(VMBUS, "Sending GPADL Header - len %zd", msginfo->msgsize - sizeof(*msginfo)); + msginfo->wait_condition = 0; ret = vmbus_post_msg(gpadlmsg, msginfo->msgsize - sizeof(*msginfo)); if (ret != 0) { @@ -566,7 +567,11 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, } } - osd_waitevent_wait(msginfo->waitevent); + wait_event_timeout(msginfo->waitevent, + msginfo->wait_condition, + msecs_to_jiffies(1000)); + BUG_ON(msginfo->wait_condition == 0); + /* At this point, we received the gpadl created msg */ DPRINT_DBG(VMBUS, "Received GPADL created " @@ -582,7 +587,6 @@ Cleanup: list_del(&msginfo->msglistentry); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); - kfree(msginfo->waitevent); kfree(msginfo); return ret; } @@ -605,11 +609,7 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) if (!info) return -ENOMEM; - info->waitevent = osd_waitevent_create(); - if (!info->waitevent) { - kfree(info); - return -ENOMEM; - } + init_waitqueue_head(&info->waitevent); msg = (struct vmbus_channel_gpadl_teardown *)info->msg; @@ -621,22 +621,20 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) list_add_tail(&info->msglistentry, &vmbus_connection.chn_msg_list); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); - + info->wait_condition = 0; ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_gpadl_teardown)); - if (ret != 0) { - /* TODO: */ - /* something... */ - } - osd_waitevent_wait(info->waitevent); + BUG_ON(ret != 0); + wait_event_timeout(info->waitevent, + info->wait_condition, msecs_to_jiffies(1000)); + BUG_ON(info->wait_condition == 0); /* Received a torndown response */ spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); list_del(&info->msglistentry); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); - kfree(info->waitevent); kfree(info); return ret; } @@ -664,18 +662,14 @@ void vmbus_close(struct vmbus_channel *channel) if (!info) return; - /* info->waitEvent = osd_waitevent_create(); */ msg = (struct vmbus_channel_close_channel *)info->msg; msg->header.msgtype = CHANNELMSG_CLOSECHANNEL; msg->child_relid = channel->offermsg.child_relid; ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_close_channel)); - if (ret != 0) { - /* TODO: */ - /* something... */ - } + BUG_ON(ret != 0); /* Tear down the gpadl for the channel's ring buffer */ if (channel->ringbuffer_gpadlhandle) vmbus_teardown_gpadl(channel, diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index a9c9d49a99bb..da1e56a9c4d6 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -19,6 +19,8 @@ * Hank Janssen */ #include +#include +#include #include #include #include @@ -593,7 +595,8 @@ static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr) memcpy(&msginfo->response.open_result, result, sizeof(struct vmbus_channel_open_result)); - osd_waitevent_set(msginfo->waitevent); + msginfo->wait_condition = 1; + wake_up(&msginfo->waitevent); break; } } @@ -643,7 +646,8 @@ static void vmbus_ongpadl_created(struct vmbus_channel_message_header *hdr) memcpy(&msginfo->response.gpadl_created, gpadlcreated, sizeof(struct vmbus_channel_gpadl_created)); - osd_waitevent_set(msginfo->waitevent); + msginfo->wait_condition = 1; + wake_up(&msginfo->waitevent); break; } } @@ -689,7 +693,8 @@ static void vmbus_ongpadl_torndown( memcpy(&msginfo->response.gpadl_torndown, gpadl_torndown, sizeof(struct vmbus_channel_gpadl_torndown)); - osd_waitevent_set(msginfo->waitevent); + msginfo->wait_condition = 1; + wake_up(&msginfo->waitevent); break; } } @@ -730,7 +735,8 @@ static void vmbus_onversion_response( memcpy(&msginfo->response.version_response, version_response, sizeof(struct vmbus_channel_version_response)); - osd_waitevent_set(msginfo->waitevent); + msginfo->wait_condition = 1; + wake_up(&msginfo->waitevent); } } spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); @@ -805,44 +811,34 @@ int vmbus_request_offers(void) if (!msginfo) return -ENOMEM; - msginfo->waitevent = osd_waitevent_create(); - if (!msginfo->waitevent) { - kfree(msginfo); - return -ENOMEM; - } + init_waitqueue_head(&msginfo->waitevent); msg = (struct vmbus_channel_message_header *)msginfo->msg; msg->msgtype = CHANNELMSG_REQUESTOFFERS; - /*SpinlockAcquire(gVmbusConnection.channelMsgLock); - INSERT_TAIL_LIST(&gVmbusConnection.channelMsgList, - &msgInfo->msgListEntry); - SpinlockRelease(gVmbusConnection.channelMsgLock);*/ ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_message_header)); if (ret != 0) { DPRINT_ERR(VMBUS, "Unable to request offers - %d", ret); - /*SpinlockAcquire(gVmbusConnection.channelMsgLock); - REMOVE_ENTRY_LIST(&msgInfo->msgListEntry); - SpinlockRelease(gVmbusConnection.channelMsgLock);*/ + goto cleanup; + } - goto Cleanup; + msginfo->wait_condition = 0; + wait_event_timeout(msginfo->waitevent, msginfo->wait_condition, + msecs_to_jiffies(1000)); + if (msginfo->wait_condition == 0) { + ret = -ETIMEDOUT; + goto cleanup; } - /* osd_waitevent_wait(msgInfo->waitEvent); */ - /*SpinlockAcquire(gVmbusConnection.channelMsgLock); - REMOVE_ENTRY_LIST(&msgInfo->msgListEntry); - SpinlockRelease(gVmbusConnection.channelMsgLock);*/ -Cleanup: - if (msginfo) { - kfree(msginfo->waitevent); +cleanup: + if (msginfo) kfree(msginfo); - } return ret; } diff --git a/drivers/staging/hv/channel_mgmt.h b/drivers/staging/hv/channel_mgmt.h index fe40bf2706d2..3368bf14e3cd 100644 --- a/drivers/staging/hv/channel_mgmt.h +++ b/drivers/staging/hv/channel_mgmt.h @@ -289,8 +289,8 @@ struct vmbus_channel_msginfo { struct list_head submsglist; /* Synchronize the request/response if needed */ - struct osd_waitevent *waitevent; - + int wait_condition; + wait_queue_head_t waitevent; union { struct vmbus_channel_version_supported version_supported; struct vmbus_channel_open_result open_result; diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index ed0976aad6f0..51dd362188b7 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -21,6 +21,8 @@ * */ #include +#include +#include #include #include #include @@ -97,11 +99,7 @@ int vmbus_connect(void) goto Cleanup; } - msginfo->waitevent = osd_waitevent_create(); - if (!msginfo->waitevent) { - ret = -ENOMEM; - goto Cleanup; - } + init_waitqueue_head(&msginfo->waitevent); msg = (struct vmbus_channel_initiate_contact *)msginfo->msg; @@ -131,14 +129,30 @@ int vmbus_connect(void) ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_initiate_contact)); if (ret != 0) { + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); list_del(&msginfo->msglistentry); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, + flags); goto Cleanup; } /* Wait for the connection response */ - osd_waitevent_wait(msginfo->waitevent); + msginfo->wait_condition = 0; + wait_event_timeout(msginfo->waitevent, msginfo->wait_condition, + msecs_to_jiffies(1000)); + if (msginfo->wait_condition == 0) { + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, + flags); + list_del(&msginfo->msglistentry); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, + flags); + ret = -ETIMEDOUT; + goto Cleanup; + } + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); list_del(&msginfo->msglistentry); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); /* Check if successful */ if (msginfo->response.version_response.version_supported) { @@ -153,7 +167,6 @@ int vmbus_connect(void) goto Cleanup; } - kfree(msginfo->waitevent); kfree(msginfo); return 0; @@ -174,7 +187,6 @@ Cleanup: } if (msginfo) { - kfree(msginfo->waitevent); kfree(msginfo); } diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index a271aa790c93..7233564668e5 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -19,6 +19,8 @@ * Hank Janssen */ #include +#include +#include #include #include #include @@ -230,7 +232,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) "unable to allocate receive buffer of size %d", net_device->recv_buf_size); ret = -1; - goto Cleanup; + goto cleanup; } /* page-aligned buffer */ /* ASSERT(((unsigned long)netDevice->ReceiveBuffer & (PAGE_SIZE - 1)) == */ @@ -249,10 +251,9 @@ static int netvsc_init_recv_buf(struct hv_device *device) if (ret != 0) { DPRINT_ERR(NETVSC, "unable to establish receive buffer's gpadl"); - goto Cleanup; + goto cleanup; } - /* osd_waitevent_wait(ext->ChannelInitEvent); */ /* Notify the NetVsp of the gpadl handle */ DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendReceiveBuffer..."); @@ -268,6 +269,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) send_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID; /* Send the gpadl notification request */ + net_device->wait_condition = 0; ret = vmbus_sendpacket(device->channel, init_packet, sizeof(struct nvsp_message), (unsigned long)init_packet, @@ -276,10 +278,14 @@ static int netvsc_init_recv_buf(struct hv_device *device) if (ret != 0) { DPRINT_ERR(NETVSC, "unable to send receive buffer's gpadl to netvsp"); - goto Cleanup; + goto cleanup; } - osd_waitevent_wait(net_device->channel_init_event); + wait_event_timeout(net_device->channel_init_wait, + net_device->wait_condition, + msecs_to_jiffies(1000)); + BUG_ON(net_device->wait_condition == 0); + /* Check the response */ if (init_packet->msg.v1_msg. @@ -289,7 +295,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) init_packet->msg.v1_msg. send_recv_buf_complete.status); ret = -1; - goto Cleanup; + goto cleanup; } /* Parse the response */ @@ -303,7 +309,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) * sizeof(struct nvsp_1_receive_buffer_section), GFP_KERNEL); if (net_device->recv_section == NULL) { ret = -1; - goto Cleanup; + goto cleanup; } memcpy(net_device->recv_section, @@ -327,15 +333,15 @@ static int netvsc_init_recv_buf(struct hv_device *device) if (net_device->recv_section_cnt != 1 || net_device->recv_section->offset != 0) { ret = -1; - goto Cleanup; + goto cleanup; } - goto Exit; + goto exit; -Cleanup: +cleanup: netvsc_destroy_recv_buf(net_device); -Exit: +exit: put_net_device(device); return ret; } @@ -354,7 +360,7 @@ static int netvsc_init_send_buf(struct hv_device *device) } if (net_device->send_buf_size <= 0) { ret = -EINVAL; - goto Cleanup; + goto cleanup; } /* page-size grandularity */ @@ -367,7 +373,7 @@ static int netvsc_init_send_buf(struct hv_device *device) DPRINT_ERR(NETVSC, "unable to allocate send buffer of size %d", net_device->send_buf_size); ret = -1; - goto Cleanup; + goto cleanup; } /* page-aligned buffer */ /* ASSERT(((unsigned long)netDevice->SendBuffer & (PAGE_SIZE - 1)) == 0); */ @@ -384,11 +390,9 @@ static int netvsc_init_send_buf(struct hv_device *device) &net_device->send_buf_gpadl_handle); if (ret != 0) { DPRINT_ERR(NETVSC, "unable to establish send buffer's gpadl"); - goto Cleanup; + goto cleanup; } - /* osd_waitevent_wait(ext->ChannelInitEvent); */ - /* Notify the NetVsp of the gpadl handle */ DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendSendBuffer..."); @@ -403,6 +407,7 @@ static int netvsc_init_send_buf(struct hv_device *device) NETVSC_SEND_BUFFER_ID; /* Send the gpadl notification request */ + net_device->wait_condition = 0; ret = vmbus_sendpacket(device->channel, init_packet, sizeof(struct nvsp_message), (unsigned long)init_packet, @@ -411,10 +416,13 @@ static int netvsc_init_send_buf(struct hv_device *device) if (ret != 0) { DPRINT_ERR(NETVSC, "unable to send receive buffer's gpadl to netvsp"); - goto Cleanup; + goto cleanup; } - osd_waitevent_wait(net_device->channel_init_event); + wait_event_timeout(net_device->channel_init_wait, + net_device->wait_condition, + msecs_to_jiffies(1000)); + BUG_ON(net_device->wait_condition == 0); /* Check the response */ if (init_packet->msg.v1_msg. @@ -424,18 +432,18 @@ static int netvsc_init_send_buf(struct hv_device *device) init_packet->msg.v1_msg. send_send_buf_complete.status); ret = -1; - goto Cleanup; + goto cleanup; } net_device->send_section_size = init_packet-> msg.v1_msg.send_send_buf_complete.section_size; - goto Exit; + goto exit; -Cleanup: +cleanup: netvsc_destroy_send_buf(net_device); -Exit: +exit: put_net_device(device); return ret; } @@ -611,6 +619,7 @@ static int netvsc_connect_vsp(struct hv_device *device) DPRINT_INFO(NETVSC, "Sending NvspMessageTypeInit..."); /* Send the init request */ + net_device->wait_condition = 0; ret = vmbus_sendpacket(device->channel, init_packet, sizeof(struct nvsp_message), (unsigned long)init_packet, @@ -619,10 +628,16 @@ static int netvsc_connect_vsp(struct hv_device *device) if (ret != 0) { DPRINT_ERR(NETVSC, "unable to send NvspMessageTypeInit"); - goto Cleanup; + goto cleanup; } - osd_waitevent_wait(net_device->channel_init_event); + wait_event_timeout(net_device->channel_init_wait, + net_device->wait_condition, + msecs_to_jiffies(1000)); + if (net_device->wait_condition == 0) { + ret = -ETIMEDOUT; + goto cleanup; + } /* Now, check the response */ /* ASSERT(initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength <= MAX_MULTIPAGE_BUFFER_COUNT); */ @@ -637,7 +652,7 @@ static int netvsc_connect_vsp(struct hv_device *device) "unable to initialize with netvsp (status 0x%x)", init_packet->msg.init_msg.init_complete.status); ret = -1; - goto Cleanup; + goto cleanup; } if (init_packet->msg.init_msg.init_complete. @@ -647,7 +662,7 @@ static int netvsc_connect_vsp(struct hv_device *device) init_packet->msg.init_msg. init_complete.negotiated_protocol_ver); ret = -1; - goto Cleanup; + goto cleanup; } DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendNdisVersion..."); @@ -666,29 +681,22 @@ static int netvsc_connect_vsp(struct hv_device *device) /* Send the init request */ ret = vmbus_sendpacket(device->channel, init_packet, - sizeof(struct nvsp_message), - (unsigned long)init_packet, - VM_PKT_DATA_INBAND, 0); + sizeof(struct nvsp_message), + (unsigned long)init_packet, + VM_PKT_DATA_INBAND, 0); if (ret != 0) { DPRINT_ERR(NETVSC, "unable to send NvspMessage1TypeSendNdisVersion"); ret = -1; - goto Cleanup; + goto cleanup; } - /* - * BUGBUG - We have to wait for the above msg since the - * netvsp uses KMCL which acknowledges packet (completion - * packet) since our Vmbus always set the - * VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED flag - */ - /* osd_waitevent_wait(NetVscChannel->ChannelInitEvent); */ /* Post the big receive buffer to NetVSP */ ret = netvsc_init_recv_buf(device); if (ret == 0) ret = netvsc_init_send_buf(device); -Cleanup: +cleanup: put_net_device(device); return ret; } @@ -715,7 +723,7 @@ static int netvsc_device_add(struct hv_device *device, void *additional_info) net_device = alloc_net_device(device); if (!net_device) { ret = -1; - goto Cleanup; + goto cleanup; } DPRINT_DBG(NETVSC, "netvsc channel object allocated - %p", net_device); @@ -741,11 +749,7 @@ static int netvsc_device_add(struct hv_device *device, void *additional_info) list_add_tail(&packet->list_ent, &net_device->recv_pkt_list); } - net_device->channel_init_event = osd_waitevent_create(); - if (!net_device->channel_init_event) { - ret = -ENOMEM; - goto Cleanup; - } + init_waitqueue_head(&net_device->channel_init_wait); /* Open the channel */ ret = vmbus_open(device->channel, net_driver->ring_buf_size, @@ -755,7 +759,7 @@ static int netvsc_device_add(struct hv_device *device, void *additional_info) if (ret != 0) { DPRINT_ERR(NETVSC, "unable to open channel: %d", ret); ret = -1; - goto Cleanup; + goto cleanup; } /* Channel is opened */ @@ -778,11 +782,9 @@ close: /* Now, we can close the channel safely */ vmbus_close(device->channel); -Cleanup: +cleanup: if (net_device) { - kfree(net_device->channel_init_event); - list_for_each_entry_safe(packet, pos, &net_device->recv_pkt_list, list_ent) { @@ -847,7 +849,6 @@ static int netvsc_device_remove(struct hv_device *device) kfree(netvsc_packet); } - kfree(net_device->channel_init_event); free_net_device(net_device); return 0; } @@ -887,7 +888,8 @@ static void netvsc_send_completion(struct hv_device *device, /* Copy the response back */ memcpy(&net_device->channel_init_pkt, nvsp_packet, sizeof(struct nvsp_message)); - osd_waitevent_set(net_device->channel_init_event); + net_device->wait_condition = 1; + wake_up(&net_device->channel_init_wait); } else if (nvsp_packet->hdr.msg_type == NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE) { /* Get the send context */ diff --git a/drivers/staging/hv/netvsc.h b/drivers/staging/hv/netvsc.h index 5f6dcf15fa29..45d24b9d91a1 100644 --- a/drivers/staging/hv/netvsc.h +++ b/drivers/staging/hv/netvsc.h @@ -318,7 +318,8 @@ struct netvsc_device { struct nvsp_1_receive_buffer_section *recv_section; /* Used for NetVSP initialization protocol */ - struct osd_waitevent *channel_init_event; + int wait_condition; + wait_queue_head_t channel_init_wait; struct nvsp_message channel_init_pkt; struct nvsp_message revoke_packet; diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c index 287e12eddd89..e3bf00491d7e 100644 --- a/drivers/staging/hv/rndis_filter.c +++ b/drivers/staging/hv/rndis_filter.c @@ -19,6 +19,8 @@ * Hank Janssen */ #include +#include +#include #include #include #include @@ -57,7 +59,8 @@ struct rndis_device { struct rndis_request { struct list_head list_ent; - struct osd_waitevent *waitevent; + int wait_condition; + wait_queue_head_t wait_event; /* * FIXME: We assumed a fixed size response here. If we do ever need to @@ -129,11 +132,7 @@ static struct rndis_request *get_rndis_request(struct rndis_device *dev, if (!request) return NULL; - request->waitevent = osd_waitevent_create(); - if (!request->waitevent) { - kfree(request); - return NULL; - } + init_waitqueue_head(&request->wait_event); rndis_msg = &request->request_msg; rndis_msg->ndis_msg_type = msg_type; @@ -164,7 +163,6 @@ static void put_rndis_request(struct rndis_device *dev, list_del(&req->list_ent); spin_unlock_irqrestore(&dev->request_lock, flags); - kfree(req->waitevent); kfree(req); } @@ -321,7 +319,8 @@ static void rndis_filter_receive_response(struct rndis_device *dev, } } - osd_waitevent_set(request->waitevent); + request->wait_condition = 1; + wake_up(&request->wait_event); } else { DPRINT_ERR(NETVSC, "no rndis request found for this response " "(id 0x%x res type 0x%x)", @@ -503,11 +502,17 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid, query->info_buflen = 0; query->dev_vc_handle = 0; + request->wait_condition = 0; ret = rndis_filter_send_request(dev, request); if (ret != 0) goto Cleanup; - osd_waitevent_wait(request->waitevent); + wait_event_timeout(request->wait_event, request->wait_condition, + msecs_to_jiffies(1000)); + if (request->wait_condition == 0) { + ret = -ETIMEDOUT; + goto Cleanup; + } /* Copy the response back */ query_complete = &request->response_msg.msg.query_complete; @@ -578,12 +583,14 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev, memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request), &new_filter, sizeof(u32)); + request->wait_condition = 0; ret = rndis_filter_send_request(dev, request); if (ret != 0) goto Cleanup; - ret = osd_waitevent_waitex(request->waitevent, 2000/*2sec*/); - if (!ret) { + wait_event_timeout(request->wait_event, request->wait_condition, + msecs_to_jiffies(2000)); + if (request->wait_condition == 0) { ret = -1; DPRINT_ERR(NETVSC, "timeout before we got a set response..."); /* @@ -669,13 +676,20 @@ static int rndis_filter_init_device(struct rndis_device *dev) dev->state = RNDIS_DEV_INITIALIZING; + request->wait_condition = 0; ret = rndis_filter_send_request(dev, request); if (ret != 0) { dev->state = RNDIS_DEV_UNINITIALIZED; goto Cleanup; } - osd_waitevent_wait(request->waitevent); + + wait_event_timeout(request->wait_event, request->wait_condition, + msecs_to_jiffies(1000)); + if (request->wait_condition == 0) { + ret = -ETIMEDOUT; + goto Cleanup; + } init_complete = &request->response_msg.msg.init_complete; status = init_complete->status; diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index a6121092d47a..2560342a0b9c 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -19,6 +19,8 @@ * Hank Janssen */ #include +#include +#include #include #include #include @@ -38,7 +40,8 @@ struct storvsc_request_extension { struct hv_device *device; /* Synchronize the request/response if needed */ - struct osd_waitevent *wait_event; + int wait_condition; + wait_queue_head_t wait_event; struct vstor_packet vstor_packet; }; @@ -200,21 +203,13 @@ static int stor_vsc_channel_init(struct hv_device *device) * channel */ memset(request, 0, sizeof(struct storvsc_request_extension)); - request->wait_event = osd_waitevent_create(); - if (!request->wait_event) { - ret = -ENOMEM; - goto nomem; - } - + init_waitqueue_head(&request->wait_event); vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; - /*SpinlockAcquire(gDriverExt.packetListLock); - INSERT_TAIL_LIST(&gDriverExt.packetList, &packet->listEntry.entry); - SpinlockRelease(gDriverExt.packetListLock);*/ - DPRINT_INFO(STORVSC, "BEGIN_INITIALIZATION_OPERATION..."); + request->wait_condition = 0; ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, @@ -223,17 +218,23 @@ static int stor_vsc_channel_init(struct hv_device *device) if (ret != 0) { DPRINT_ERR(STORVSC, "unable to send BEGIN_INITIALIZATION_OPERATION"); - goto Cleanup; + goto cleanup; + } + + wait_event_timeout(request->wait_event, request->wait_condition, + msecs_to_jiffies(1000)); + if (request->wait_condition == 0) { + ret = -ETIMEDOUT; + goto cleanup; } - osd_waitevent_wait(request->wait_event); if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || vstor_packet->status != 0) { DPRINT_ERR(STORVSC, "BEGIN_INITIALIZATION_OPERATION failed " "(op %d status 0x%x)", vstor_packet->operation, vstor_packet->status); - goto Cleanup; + goto cleanup; } DPRINT_INFO(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION..."); @@ -246,6 +247,7 @@ static int stor_vsc_channel_init(struct hv_device *device) vstor_packet->version.major_minor = VMSTOR_PROTOCOL_VERSION_CURRENT; FILL_VMSTOR_REVISION(vstor_packet->version.revision); + request->wait_condition = 0; ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, @@ -254,10 +256,15 @@ static int stor_vsc_channel_init(struct hv_device *device) if (ret != 0) { DPRINT_ERR(STORVSC, "unable to send BEGIN_INITIALIZATION_OPERATION"); - goto Cleanup; + goto cleanup; } - osd_waitevent_wait(request->wait_event); + wait_event_timeout(request->wait_event, request->wait_condition, + msecs_to_jiffies(1000)); + if (request->wait_condition == 0) { + ret = -ETIMEDOUT; + goto cleanup; + } /* TODO: Check returned version */ if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || @@ -265,7 +272,7 @@ static int stor_vsc_channel_init(struct hv_device *device) DPRINT_ERR(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION failed " "(op %d status 0x%x)", vstor_packet->operation, vstor_packet->status); - goto Cleanup; + goto cleanup; } /* Query channel properties */ @@ -277,6 +284,7 @@ static int stor_vsc_channel_init(struct hv_device *device) vstor_packet->storage_channel_properties.port_number = stor_device->port_number; + request->wait_condition = 0; ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, @@ -286,10 +294,15 @@ static int stor_vsc_channel_init(struct hv_device *device) if (ret != 0) { DPRINT_ERR(STORVSC, "unable to send QUERY_PROPERTIES_OPERATION"); - goto Cleanup; + goto cleanup; } - osd_waitevent_wait(request->wait_event); + wait_event_timeout(request->wait_event, request->wait_condition, + msecs_to_jiffies(1000)); + if (request->wait_condition == 0) { + ret = -ETIMEDOUT; + goto cleanup; + } /* TODO: Check returned version */ if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || @@ -297,7 +310,7 @@ static int stor_vsc_channel_init(struct hv_device *device) DPRINT_ERR(STORVSC, "QUERY_PROPERTIES_OPERATION failed " "(op %d status 0x%x)", vstor_packet->operation, vstor_packet->status); - goto Cleanup; + goto cleanup; } stor_device->path_id = vstor_packet->storage_channel_properties.path_id; @@ -314,6 +327,7 @@ static int stor_vsc_channel_init(struct hv_device *device) vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; + request->wait_condition = 0; ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, @@ -323,25 +337,27 @@ static int stor_vsc_channel_init(struct hv_device *device) if (ret != 0) { DPRINT_ERR(STORVSC, "unable to send END_INITIALIZATION_OPERATION"); - goto Cleanup; + goto cleanup; } - osd_waitevent_wait(request->wait_event); + wait_event_timeout(request->wait_event, request->wait_condition, + msecs_to_jiffies(1000)); + if (request->wait_condition == 0) { + ret = -ETIMEDOUT; + goto cleanup; + } if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || vstor_packet->status != 0) { DPRINT_ERR(STORVSC, "END_INITIALIZATION_OPERATION failed " "(op %d status 0x%x)", vstor_packet->operation, vstor_packet->status); - goto Cleanup; + goto cleanup; } DPRINT_INFO(STORVSC, "**** storage channel up and running!! ****"); -Cleanup: - kfree(request->wait_event); - request->wait_event = NULL; -nomem: +cleanup: put_stor_device(device); return ret; } @@ -476,8 +492,8 @@ static void stor_vsc_on_channel_callback(void *context) memcpy(&request->vstor_packet, packet, sizeof(struct vstor_packet)); - - osd_waitevent_set(request->wait_event); + request->wait_condition = 1; + wake_up(&request->wait_event); } else { stor_vsc_on_receive(device, (struct vstor_packet *)packet, @@ -539,7 +555,7 @@ static int stor_vsc_on_device_add(struct hv_device *device, stor_device = alloc_stor_device(device); if (!stor_device) { ret = -1; - goto Cleanup; + goto cleanup; } /* Save the channel properties to our storvsc channel */ @@ -569,7 +585,7 @@ static int stor_vsc_on_device_add(struct hv_device *device, stor_device->port_number, stor_device->path_id, stor_device->target_id); -Cleanup: +cleanup: return ret; } @@ -629,16 +645,13 @@ int stor_vsc_on_host_reset(struct hv_device *device) request = &stor_device->reset_request; vstor_packet = &request->vstor_packet; - request->wait_event = osd_waitevent_create(); - if (!request->wait_event) { - ret = -ENOMEM; - goto Cleanup; - } + init_waitqueue_head(&request->wait_event); vstor_packet->operation = VSTOR_OPERATION_RESET_BUS; vstor_packet->flags = REQUEST_COMPLETION_FLAG; vstor_packet->vm_srb.path_id = stor_device->path_id; + request->wait_condition = 0; ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)&stor_device->reset_request, @@ -647,13 +660,16 @@ int stor_vsc_on_host_reset(struct hv_device *device) if (ret != 0) { DPRINT_ERR(STORVSC, "Unable to send reset packet %p ret %d", vstor_packet, ret); - goto Cleanup; + goto cleanup; } - /* FIXME: Add a timeout */ - osd_waitevent_wait(request->wait_event); + wait_event_timeout(request->wait_event, request->wait_condition, + msecs_to_jiffies(1000)); + if (request->wait_condition == 0) { + ret = -ETIMEDOUT; + goto cleanup; + } - kfree(request->wait_event); DPRINT_INFO(STORVSC, "host adapter reset completed"); /* @@ -661,7 +677,7 @@ int stor_vsc_on_host_reset(struct hv_device *device) * should have been flushed out and return to us */ -Cleanup: +cleanup: put_stor_device(device); return ret; } diff --git a/drivers/staging/hv/vmbus_private.h b/drivers/staging/hv/vmbus_private.h index 004d8de1c7df..9f505c44c600 100644 --- a/drivers/staging/hv/vmbus_private.h +++ b/drivers/staging/hv/vmbus_private.h @@ -91,7 +91,8 @@ struct vmbus_msginfo { struct list_head msglist_entry; /* Synchronize the request/response if needed */ - struct osd_waitevent *wait_event; + int wait_condition; + wait_queue_head_t wait_event; /* The message itself */ unsigned char msg[0]; -- cgit v1.2.3 From e3fe0bb65b2686aa83dabdb1ecc22f5d80c536f8 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Fri, 11 Feb 2011 10:00:12 -0800 Subject: Staging: hv: Remove osd layer The OSD layer was a wrapper around native interfaces adding little value and was infact buggy - refer to the osd_wait.patch for details. This patch gets rid of the OSD abstraction. Signed-off-by: K. Y. Srinivasan Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Makefile | 2 +- drivers/staging/hv/blkvsc.c | 2 +- drivers/staging/hv/blkvsc_drv.c | 2 +- drivers/staging/hv/channel.c | 5 +- drivers/staging/hv/channel_mgmt.c | 2 +- drivers/staging/hv/connection.c | 2 +- drivers/staging/hv/hv.c | 2 +- drivers/staging/hv/hv_api.h | 5 + drivers/staging/hv/hv_kvp.c | 2 +- drivers/staging/hv/hv_util.c | 2 +- drivers/staging/hv/logging.h | 3 + drivers/staging/hv/netvsc.c | 2 +- drivers/staging/hv/netvsc_drv.c | 2 +- drivers/staging/hv/osd.c | 194 -------------------------------------- drivers/staging/hv/osd.h | 62 ------------ drivers/staging/hv/ring_buffer.c | 1 - drivers/staging/hv/rndis_filter.c | 2 +- drivers/staging/hv/storvsc.c | 2 +- drivers/staging/hv/storvsc_drv.c | 2 +- drivers/staging/hv/vmbus_drv.c | 2 +- 20 files changed, 26 insertions(+), 272 deletions(-) delete mode 100644 drivers/staging/hv/osd.c delete mode 100644 drivers/staging/hv/osd.h (limited to 'drivers') diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index 606ce7daa4ee..737e51796e63 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_HYPERV_BLOCK) += hv_blkvsc.o obj-$(CONFIG_HYPERV_NET) += hv_netvsc.o obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o -hv_vmbus-y := vmbus_drv.o osd.o \ +hv_vmbus-y := vmbus_drv.o \ hv.o connection.o channel.o \ channel_mgmt.o ring_buffer.o hv_storvsc-y := storvsc_drv.o storvsc.o diff --git a/drivers/staging/hv/blkvsc.c b/drivers/staging/hv/blkvsc.c index b0e07c1fc4c8..7c8729bc8329 100644 --- a/drivers/staging/hv/blkvsc.c +++ b/drivers/staging/hv/blkvsc.c @@ -22,7 +22,7 @@ */ #include #include -#include "osd.h" +#include "hv_api.h" #include "storvsc.c" static const char *g_blk_driver_name = "blkvsc"; diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 58bbcd60b3d7..36a0adbaa987 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -31,7 +31,7 @@ #include #include #include -#include "osd.h" +#include "hv_api.h" #include "logging.h" #include "version_info.h" #include "vmbus.h" diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index 5a0923ca565f..775a52a91222 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -24,10 +24,13 @@ #include #include #include -#include "osd.h" +#include "hv_api.h" #include "logging.h" #include "vmbus_private.h" +#define NUM_PAGES_SPANNED(addr, len) \ +((PAGE_ALIGN(addr + len) >> PAGE_SHIFT) - (addr >> PAGE_SHIFT)) + /* Internal routines */ static int create_gpadl_header( void *kbuffer, /* must be phys and virt contiguous */ diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index da1e56a9c4d6..325e0bc3603a 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -26,7 +26,7 @@ #include #include #include -#include "osd.h" +#include "hv_api.h" #include "logging.h" #include "vmbus_private.h" #include "utils.h" diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index 51dd362188b7..f7df47934cf9 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -26,7 +26,7 @@ #include #include #include -#include "osd.h" +#include "hv_api.h" #include "logging.h" #include "vmbus_private.h" diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c index 419b4d6aef63..31b90736bc04 100644 --- a/drivers/staging/hv/hv.c +++ b/drivers/staging/hv/hv.c @@ -23,7 +23,7 @@ #include #include #include -#include "osd.h" +#include "hv_api.h" #include "logging.h" #include "vmbus_private.h" diff --git a/drivers/staging/hv/hv_api.h b/drivers/staging/hv/hv_api.h index 70e863ad0464..7114fceab21e 100644 --- a/drivers/staging/hv/hv_api.h +++ b/drivers/staging/hv/hv_api.h @@ -23,6 +23,11 @@ #ifndef __HV_API_H #define __HV_API_H +struct hv_guid { + unsigned char data[16]; +}; + + /* Status codes for hypervisor operations. */ diff --git a/drivers/staging/hv/hv_kvp.c b/drivers/staging/hv/hv_kvp.c index bc1c20e8d611..faf692e4126e 100644 --- a/drivers/staging/hv/hv_kvp.c +++ b/drivers/staging/hv/hv_kvp.c @@ -28,7 +28,7 @@ #include #include "logging.h" -#include "osd.h" +#include "hv_api.h" #include "vmbus.h" #include "vmbus_packet_format.h" #include "vmbus_channel_interface.h" diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c index 43c7ec0e9adb..4792f2c402b2 100644 --- a/drivers/staging/hv/hv_util.c +++ b/drivers/staging/hv/hv_util.c @@ -28,7 +28,7 @@ #include #include "logging.h" -#include "osd.h" +#include "hv_api.h" #include "vmbus.h" #include "vmbus_packet_format.h" #include "vmbus_channel_interface.h" diff --git a/drivers/staging/hv/logging.h b/drivers/staging/hv/logging.h index 20d4d12023de..17999515ce08 100644 --- a/drivers/staging/hv/logging.h +++ b/drivers/staging/hv/logging.h @@ -25,6 +25,9 @@ #ifndef _LOGGING_H_ #define _LOGGING_H_ +#define LOWORD(dw) ((unsigned short)(dw)) +#define HIWORD(dw) ((unsigned short)(((unsigned int) (dw) >> 16) & 0xFFFF)) + /* #include */ /* #include */ diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index 7233564668e5..fa46a7e070bd 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -25,7 +25,7 @@ #include #include #include -#include "osd.h" +#include "hv_api.h" #include "logging.h" #include "netvsc.h" #include "rndis_filter.h" diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index a7f7819cc3b6..03f97404a2de 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -36,7 +36,7 @@ #include #include #include -#include "osd.h" +#include "hv_api.h" #include "logging.h" #include "version_info.h" #include "vmbus.h" diff --git a/drivers/staging/hv/osd.c b/drivers/staging/hv/osd.c deleted file mode 100644 index b5a3940331b3..000000000000 --- a/drivers/staging/hv/osd.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "osd.h" - -void *osd_virtual_alloc_exec(unsigned int size) -{ -#ifdef __x86_64__ - return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL_EXEC); -#else - return __vmalloc(size, GFP_KERNEL, - __pgprot(__PAGE_KERNEL & (~_PAGE_NX))); -#endif -} - -/** - * osd_page_alloc() - Allocate pages - * @count: Total number of Kernel pages you want to allocate - * - * Tries to allocate @count number of consecutive free kernel pages. - * And if successful, it will set the pages to 0 before returning. - * If successfull it will return pointer to the @count pages. - * Mainly used by Hyper-V drivers. - */ -void *osd_page_alloc(unsigned int count) -{ - void *p; - - p = (void *)__get_free_pages(GFP_KERNEL, get_order(count * PAGE_SIZE)); - if (p) - memset(p, 0, count * PAGE_SIZE); - return p; - - /* struct page* page = alloc_page(GFP_KERNEL|__GFP_ZERO); */ - /* void *p; */ - - /* BUGBUG: We need to use kmap in case we are in HIMEM region */ - /* p = page_address(page); */ - /* if (p) memset(p, 0, PAGE_SIZE); */ - /* return p; */ -} -EXPORT_SYMBOL_GPL(osd_page_alloc); - -/** - * osd_page_free() - Free pages - * @page: Pointer to the first page to be freed - * @count: Total number of Kernel pages you free - * - * Frees the pages allocated by osd_page_alloc() - * Mainly used by Hyper-V drivers. - */ -void osd_page_free(void *page, unsigned int count) -{ - free_pages((unsigned long)page, get_order(count * PAGE_SIZE)); - /*struct page* p = virt_to_page(page); - __free_page(p);*/ -} -EXPORT_SYMBOL_GPL(osd_page_free); - -/** - * osd_waitevent_create() - Create the event queue - * - * Allocates memory for a &struct osd_waitevent. And then calls - * init_waitqueue_head to set up the wait queue for the event. - * This structure is usually part of a another structure that contains - * the actual Hyper-V device driver structure. - * - * Returns pointer to &struct osd_waitevent - * Mainly used by Hyper-V drivers. - */ -struct osd_waitevent *osd_waitevent_create(void) -{ - struct osd_waitevent *wait = kmalloc(sizeof(struct osd_waitevent), - GFP_KERNEL); - if (!wait) - return NULL; - - wait->condition = 0; - init_waitqueue_head(&wait->event); - return wait; -} -EXPORT_SYMBOL_GPL(osd_waitevent_create); - - -/** - * osd_waitevent_set() - Wake up the process - * @wait_event: Structure to event to be woken up - * - * @wait_event is of type &struct osd_waitevent - * - * Wake up the sleeping process so it can do some work. - * And set condition indicator in &struct osd_waitevent to indicate - * the process is in a woken state. - * - * Only used by Network and Storage Hyper-V drivers. - */ -void osd_waitevent_set(struct osd_waitevent *wait_event) -{ - wait_event->condition = 1; - wake_up_interruptible(&wait_event->event); -} -EXPORT_SYMBOL_GPL(osd_waitevent_set); - -/** - * osd_waitevent_wait() - Wait for event till condition is true - * @wait_event: Structure to event to be put to sleep - * - * @wait_event is of type &struct osd_waitevent - * - * Set up the process to sleep until waitEvent->condition get true. - * And set condition indicator in &struct osd_waitevent to indicate - * the process is in a sleeping state. - * - * Returns the status of 'wait_event_interruptible()' system call - * - * Mainly used by Hyper-V drivers. - */ -int osd_waitevent_wait(struct osd_waitevent *wait_event) -{ - int ret = 0; - - ret = wait_event_interruptible(wait_event->event, - wait_event->condition); - wait_event->condition = 0; - return ret; -} -EXPORT_SYMBOL_GPL(osd_waitevent_wait); - -/** - * osd_waitevent_waitex() - Wait for event or timeout for process wakeup - * @wait_event: Structure to event to be put to sleep - * @timeout_in_ms: Total number of Milliseconds to wait before waking up - * - * @wait_event is of type &struct osd_waitevent - * Set up the process to sleep until @waitEvent->condition get true or - * @timeout_in_ms (Time out in Milliseconds) has been reached. - * And set condition indicator in &struct osd_waitevent to indicate - * the process is in a sleeping state. - * - * Returns the status of 'wait_event_interruptible_timeout()' system call - * - * Mainly used by Hyper-V drivers. - */ -int osd_waitevent_waitex(struct osd_waitevent *wait_event, u32 timeout_in_ms) -{ - int ret = 0; - - ret = wait_event_interruptible_timeout(wait_event->event, - wait_event->condition, - msecs_to_jiffies(timeout_in_ms)); - wait_event->condition = 0; - return ret; -} -EXPORT_SYMBOL_GPL(osd_waitevent_waitex); diff --git a/drivers/staging/hv/osd.h b/drivers/staging/hv/osd.h deleted file mode 100644 index f7871614b983..000000000000 --- a/drivers/staging/hv/osd.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ - - -#ifndef _OSD_H_ -#define _OSD_H_ - -#include -#include - -/* Defines */ -#define NUM_PAGES_SPANNED(addr, len) ((PAGE_ALIGN(addr + len) >> PAGE_SHIFT) - \ - (addr >> PAGE_SHIFT)) - -#define LOWORD(dw) ((unsigned short)(dw)) -#define HIWORD(dw) ((unsigned short)(((unsigned int) (dw) >> 16) & 0xFFFF)) - -struct hv_guid { - unsigned char data[16]; -}; - -struct osd_waitevent { - int condition; - wait_queue_head_t event; -}; - -/* Osd routines */ - -extern void *osd_virtual_alloc_exec(unsigned int size); - -extern void *osd_page_alloc(unsigned int count); -extern void osd_page_free(void *page, unsigned int count); - -extern struct osd_waitevent *osd_waitevent_create(void); -extern void osd_waitevent_set(struct osd_waitevent *wait_event); -extern int osd_waitevent_wait(struct osd_waitevent *wait_event); - -/* If >0, wait_event got signaled. If ==0, timeout. If < 0, error */ -extern int osd_waitevent_waitex(struct osd_waitevent *wait_event, - u32 timeout_in_ms); - -#endif /* _OSD_H_ */ diff --git a/drivers/staging/hv/ring_buffer.c b/drivers/staging/hv/ring_buffer.c index 4d53392f1e60..66688fb69741 100644 --- a/drivers/staging/hv/ring_buffer.c +++ b/drivers/staging/hv/ring_buffer.c @@ -23,7 +23,6 @@ #include #include -#include "osd.h" #include "logging.h" #include "ring_buffer.h" diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c index e3bf00491d7e..9dde936e37c6 100644 --- a/drivers/staging/hv/rndis_filter.c +++ b/drivers/staging/hv/rndis_filter.c @@ -26,8 +26,8 @@ #include #include -#include "osd.h" #include "logging.h" +#include "hv_api.h" #include "netvsc_api.h" #include "rndis_filter.h" diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 2560342a0b9c..e2ad72924184 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -25,7 +25,7 @@ #include #include #include -#include "osd.h" +#include "hv_api.h" #include "logging.h" #include "storvsc_api.h" #include "vmbus_packet_format.h" diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 956c9ebaa6a5..a8427ffd162b 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -31,7 +31,7 @@ #include #include #include -#include "osd.h" +#include "hv_api.h" #include "logging.h" #include "version_info.h" #include "vmbus.h" diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index dacaa54edeac..459c707afe57 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -29,7 +29,7 @@ #include #include #include "version_info.h" -#include "osd.h" +#include "hv_api.h" #include "logging.h" #include "vmbus.h" #include "channel.h" -- cgit v1.2.3 From d97ae00ea6a632bd97b99431db87d9b505b633a1 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Fri, 11 Feb 2011 14:48:45 -0800 Subject: Staging: hv: Cleanup vmalloc calls The subject says it all. There is no need to specify different page protection bits based on the architecture. Signed-off-by: K. Y. Srinivasan Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c index 31b90736bc04..2d492adb95bb 100644 --- a/drivers/staging/hv/hv.c +++ b/drivers/staging/hv/hv.c @@ -230,12 +230,7 @@ int hv_init(void) * Allocate the hypercall page memory * virtaddr = osd_page_alloc(1); */ -#ifdef __x86_64__ virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_EXEC); -#else - virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, - __pgprot(__PAGE_KERNEL & (~_PAGE_NX))); -#endif if (!virtaddr) { DPRINT_ERR(VMBUS, -- cgit v1.2.3 From 5d8ffd71090ddd166206bf9b47a84294d73db6a5 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Mon, 14 Feb 2011 14:51:41 -0800 Subject: staging: hv: Remove dead code from netvsc.c Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Reviewed-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/netvsc.c | 34 ---------------------------------- 1 file changed, 34 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index fa46a7e070bd..8c6d4ae54be2 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -134,7 +134,6 @@ static void put_net_device(struct hv_device *device) struct netvsc_device *net_device; net_device = device->ext; - /* ASSERT(netDevice); */ atomic_dec(&net_device->refcnt); } @@ -186,9 +185,6 @@ int netvsc_initialize(struct hv_driver *drv) sizeof(struct nvsp_message), sizeof(struct vmtransfer_page_packet_header)); - /* Make sure we are at least 2 pages since 1 page is used for control */ - /* ASSERT(driver->RingBufferSize >= (PAGE_SIZE << 1)); */ - drv->name = driver_name; memcpy(&drv->dev_type, &netvsc_device_type, sizeof(struct hv_guid)); @@ -220,9 +216,6 @@ static int netvsc_init_recv_buf(struct hv_device *device) "device being destroyed?"); return -1; } - /* ASSERT(netDevice->ReceiveBufferSize > 0); */ - /* page-size grandularity */ - /* ASSERT((netDevice->ReceiveBufferSize & (PAGE_SIZE - 1)) == 0); */ net_device->recv_buf = (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, @@ -234,9 +227,6 @@ static int netvsc_init_recv_buf(struct hv_device *device) ret = -1; goto cleanup; } - /* page-aligned buffer */ - /* ASSERT(((unsigned long)netDevice->ReceiveBuffer & (PAGE_SIZE - 1)) == */ - /* 0); */ DPRINT_INFO(NETVSC, "Establishing receive buffer's GPADL..."); @@ -299,8 +289,6 @@ static int netvsc_init_recv_buf(struct hv_device *device) } /* Parse the response */ - /* ASSERT(netDevice->ReceiveSectionCount == 0); */ - /* ASSERT(netDevice->ReceiveSections == NULL); */ net_device->recv_section_cnt = init_packet->msg. v1_msg.send_recv_buf_complete.num_sections; @@ -363,9 +351,6 @@ static int netvsc_init_send_buf(struct hv_device *device) goto cleanup; } - /* page-size grandularity */ - /* ASSERT((netDevice->SendBufferSize & (PAGE_SIZE - 1)) == 0); */ - net_device->send_buf = (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, get_order(net_device->send_buf_size)); @@ -375,8 +360,6 @@ static int netvsc_init_send_buf(struct hv_device *device) ret = -1; goto cleanup; } - /* page-aligned buffer */ - /* ASSERT(((unsigned long)netDevice->SendBuffer & (PAGE_SIZE - 1)) == 0); */ DPRINT_INFO(NETVSC, "Establishing send buffer's GPADL..."); @@ -639,8 +622,6 @@ static int netvsc_connect_vsp(struct hv_device *device) goto cleanup; } - /* Now, check the response */ - /* ASSERT(initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength <= MAX_MULTIPAGE_BUFFER_COUNT); */ DPRINT_INFO(NETVSC, "NvspMessageTypeInit status(%d) max mdl chain (%d)", init_packet->msg.init_msg.init_complete.status, init_packet->msg.init_msg. @@ -895,7 +876,6 @@ static void netvsc_send_completion(struct hv_device *device, /* Get the send context */ nvsc_packet = (struct hv_netvsc_packet *)(unsigned long) packet->trans_id; - /* ASSERT(nvscPacket); */ /* Notify the layer above us */ nvsc_packet->completion.send.send_completion( @@ -1072,8 +1052,6 @@ static void netvsc_receive(struct hv_device *device, /* This is how much we can satisfy */ xferpage_packet->count = count - 1; - /* ASSERT(xferpagePacket->Count > 0 && xferpagePacket->Count <= */ - /* vmxferpagePacket->RangeCount); */ if (xferpage_packet->count != vmxferpage_packet->range_cnt) { DPRINT_INFO(NETVSC, "Needed %d netvsc pkts to satisy this xfer " @@ -1101,10 +1079,6 @@ static void netvsc_receive(struct hv_device *device, vmxferpage_packet->ranges[i].byte_count; netvsc_packet->page_buf_cnt = 1; - /* ASSERT(vmxferpagePacket->Ranges[i].ByteOffset + */ - /* vmxferpagePacket->Ranges[i].ByteCount < */ - /* netDevice->ReceiveBufferSize); */ - netvsc_packet->page_buf[0].len = vmxferpage_packet->ranges[i].byte_count; @@ -1147,7 +1121,6 @@ static void netvsc_receive(struct hv_device *device, if (bytes_remain == 0) break; } - /* ASSERT(bytesRemain == 0); */ } DPRINT_DBG(NETVSC, "[%d] - (abs offset %u len %u) => " "(pfn %llx, offset %u, len %u)", i, @@ -1165,8 +1138,6 @@ static void netvsc_receive(struct hv_device *device, completion.recv.recv_completion_ctx); } - /* ASSERT(list_empty(&listHead)); */ - put_net_device(device); } @@ -1225,8 +1196,6 @@ static void netvsc_receive_completion(void *context) bool fsend_receive_comp = false; unsigned long flags; - /* ASSERT(packet->XferPagePacket); */ - /* * Even though it seems logical to do a GetOutboundNetDevice() here to * send out receive completion, we are using GetInboundNetDevice() @@ -1242,7 +1211,6 @@ static void netvsc_receive_completion(void *context) /* Overloading use of the lock. */ spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags); - /* ASSERT(packet->XferPagePacket->Count > 0); */ packet->xfer_page_pkt->count--; /* @@ -1280,8 +1248,6 @@ static void netvsc_channel_cb(void *context) unsigned char *buffer; int bufferlen = NETVSC_PACKET_SIZE; - /* ASSERT(device); */ - packet = kzalloc(NETVSC_PACKET_SIZE * sizeof(unsigned char), GFP_ATOMIC); if (!packet) -- cgit v1.2.3 From 8014552a167ff56f30f7f6a3b4f4dda427f3d2fd Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Mon, 14 Feb 2011 14:51:42 -0800 Subject: staging: hv: Remove dead code from rndis_filter.c Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Reviewed-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/rndis_filter.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c index 9dde936e37c6..e7189cd324ca 100644 --- a/drivers/staging/hv/rndis_filter.c +++ b/drivers/staging/hv/rndis_filter.c @@ -355,10 +355,6 @@ static void rndis_filter_receive_data(struct rndis_device *dev, struct rndis_packet *rndis_pkt; u32 data_offset; - /* empty ethernet frame ?? */ - /* ASSERT(Packet->PageBuffers[0].Length > */ - /* RNDIS_MESSAGE_SIZE(struct rndis_packet)); */ - rndis_pkt = &msg->msg.pkt; /* @@ -455,8 +451,6 @@ static int rndis_filter_receive(struct hv_device *dev, case REMOTE_NDIS_INITIALIZE_CMPLT: case REMOTE_NDIS_QUERY_CMPLT: case REMOTE_NDIS_SET_CMPLT: - /* case REMOTE_NDIS_RESET_CMPLT: */ - /* case REMOTE_NDIS_KEEPALIVE_CMPLT: */ /* completion msgs */ rndis_filter_receive_response(rndis_dev, &rndis_msg); break; @@ -563,9 +557,6 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 status; int ret; - /* ASSERT(RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32) <= */ - /* sizeof(struct rndis_message)); */ - request = get_rndis_request(dev, REMOTE_NDIS_SET_MSG, RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32)); @@ -634,8 +625,6 @@ int rndis_filter_init(struct netvsc_driver *drv) drv->base.dev_rm; rndis_filter.inner_drv.base.cleanup = drv->base.cleanup; - /* ASSERT(Driver->OnSend); */ - /* ASSERT(Driver->OnReceiveCallback); */ rndis_filter.inner_drv.send = drv->send; rndis_filter.inner_drv.recv_cb = drv->recv_cb; rndis_filter.inner_drv.link_status_change = @@ -646,7 +635,6 @@ int rndis_filter_init(struct netvsc_driver *drv) drv->base.dev_rm = rndis_filter_device_remove; drv->base.cleanup = rndis_filter_cleanup; drv->send = rndis_filter_send; - /* Driver->QueryLinkStatus = RndisFilterQueryDeviceLinkStatus; */ drv->recv_cb = rndis_filter_receive; return 0; @@ -793,8 +781,6 @@ static int rndis_filte_device_add(struct hv_device *dev, /* Initialize the rndis device */ netDevice = dev->ext; - /* ASSERT(netDevice); */ - /* ASSERT(netDevice->Device); */ netDevice->extension = rndisDevice; rndisDevice->net_dev = netDevice; @@ -882,7 +868,6 @@ static int rndis_filter_send(struct hv_device *dev, /* Add the rndis header */ filterPacket = (struct rndis_filter_packet *)pkt->extension; - /* ASSERT(filterPacket); */ memset(filterPacket, 0, sizeof(struct rndis_filter_packet)); -- cgit v1.2.3 From ebb61e5f9754e88843fc05ee2a6204ef3f6c2fc8 Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Fri, 18 Feb 2011 12:39:57 -0800 Subject: Staging: hv: Fixed FIXME comments by using list_for_each_entry Fixed FIXME requests in channel_mgmt.c by using list_for_each_entry. Signed-off-by: Hank Janssen Signed-off-by: K.Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel_mgmt.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 325e0bc3603a..0781c0ed7056 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -567,7 +567,6 @@ static void vmbus_onoffers_delivered( static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr) { struct vmbus_channel_open_result *result; - struct list_head *curr; struct vmbus_channel_msginfo *msginfo; struct vmbus_channel_message_header *requestheader; struct vmbus_channel_open_channel *openmsg; @@ -581,9 +580,8 @@ static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr) */ spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_for_each(curr, &vmbus_connection.chn_msg_list) { -/* FIXME: this should probably use list_entry() instead */ - msginfo = (struct vmbus_channel_msginfo *)curr; + list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list, + msglistentry) { requestheader = (struct vmbus_channel_message_header *)msginfo->msg; @@ -614,7 +612,6 @@ static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr) static void vmbus_ongpadl_created(struct vmbus_channel_message_header *hdr) { struct vmbus_channel_gpadl_created *gpadlcreated; - struct list_head *curr; struct vmbus_channel_msginfo *msginfo; struct vmbus_channel_message_header *requestheader; struct vmbus_channel_gpadl_header *gpadlheader; @@ -630,9 +627,8 @@ static void vmbus_ongpadl_created(struct vmbus_channel_message_header *hdr) */ spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_for_each(curr, &vmbus_connection.chn_msg_list) { -/* FIXME: this should probably use list_entry() instead */ - msginfo = (struct vmbus_channel_msginfo *)curr; + list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list, + msglistentry) { requestheader = (struct vmbus_channel_message_header *)msginfo->msg; @@ -666,7 +662,6 @@ static void vmbus_ongpadl_torndown( struct vmbus_channel_message_header *hdr) { struct vmbus_channel_gpadl_torndown *gpadl_torndown; - struct list_head *curr; struct vmbus_channel_msginfo *msginfo; struct vmbus_channel_message_header *requestheader; struct vmbus_channel_gpadl_teardown *gpadl_teardown; @@ -679,9 +674,8 @@ static void vmbus_ongpadl_torndown( */ spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_for_each(curr, &vmbus_connection.chn_msg_list) { -/* FIXME: this should probably use list_entry() instead */ - msginfo = (struct vmbus_channel_msginfo *)curr; + list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list, + msglistentry) { requestheader = (struct vmbus_channel_message_header *)msginfo->msg; @@ -712,7 +706,6 @@ static void vmbus_ongpadl_torndown( static void vmbus_onversion_response( struct vmbus_channel_message_header *hdr) { - struct list_head *curr; struct vmbus_channel_msginfo *msginfo; struct vmbus_channel_message_header *requestheader; struct vmbus_channel_initiate_contact *initiate; @@ -722,9 +715,8 @@ static void vmbus_onversion_response( version_response = (struct vmbus_channel_version_response *)hdr; spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_for_each(curr, &vmbus_connection.chn_msg_list) { -/* FIXME: this should probably use list_entry() instead */ - msginfo = (struct vmbus_channel_msginfo *)curr; + list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list, + msglistentry) { requestheader = (struct vmbus_channel_message_header *)msginfo->msg; -- cgit v1.2.3 From 1e1233234edeacabbcaab9d086474224ba5af015 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sat, 12 Feb 2011 04:38:22 +0100 Subject: Staging: bcm: Bcmchar: Fix style issues on bcm_char_open() Signed-off-by: Javier Martinez Canillas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 7dff283edb65..edcd0c02eb85 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -15,21 +15,22 @@ static int bcm_char_open(struct inode *inode, struct file * filp) { - PMINI_ADAPTER Adapter = NULL; - PPER_TARANG_DATA pTarang = NULL; + PMINI_ADAPTER Adapter = NULL; + PPER_TARANG_DATA pTarang = NULL; Adapter = GET_BCM_ADAPTER(gblpnetdev); - pTarang = (PPER_TARANG_DATA)kmalloc(sizeof(PER_TARANG_DATA), GFP_KERNEL); - if (!pTarang) - return -ENOMEM; + pTarang = (PPER_TARANG_DATA)kmalloc(sizeof(PER_TARANG_DATA), + GFP_KERNEL); + if (!pTarang) + return -ENOMEM; - memset (pTarang, 0, sizeof(PER_TARANG_DATA)); - pTarang->Adapter = Adapter; - pTarang->RxCntrlMsgBitMask = 0xFFFFFFFF & ~(1 << 0xB) ; + memset(pTarang, 0, sizeof(PER_TARANG_DATA)); + pTarang->Adapter = Adapter; + pTarang->RxCntrlMsgBitMask = 0xFFFFFFFF & ~(1 << 0xB); down(&Adapter->RxAppControlQueuelock); - pTarang->next = Adapter->pTarangs; - Adapter->pTarangs = pTarang; + pTarang->next = Adapter->pTarangs; + Adapter->pTarangs = pTarang; up(&Adapter->RxAppControlQueuelock); /* Store the Adapter structure */ @@ -41,6 +42,7 @@ static int bcm_char_open(struct inode *inode, struct file * filp) nonseekable_open(inode, filp); return 0; } + static int bcm_char_release(struct inode *inode, struct file *filp) { PPER_TARANG_DATA pTarang, tmp, ptmp; -- cgit v1.2.3 From a7d3976edc32e6041f9d68c79ba64a17d5ec5095 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sat, 12 Feb 2011 04:38:23 +0100 Subject: Staging: bcm: Bcmchar: Fix style issues on bcm_char_release() Signed-off-by: Javier Martinez Canillas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 68 ++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index edcd0c02eb85..2a3f64ccefec 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -45,61 +45,55 @@ static int bcm_char_open(struct inode *inode, struct file * filp) static int bcm_char_release(struct inode *inode, struct file *filp) { - PPER_TARANG_DATA pTarang, tmp, ptmp; - PMINI_ADAPTER Adapter=NULL; - struct sk_buff * pkt, * npkt; + PPER_TARANG_DATA pTarang, tmp, ptmp; + PMINI_ADAPTER Adapter = NULL; + struct sk_buff *pkt, *npkt; - pTarang = (PPER_TARANG_DATA)filp->private_data; + pTarang = (PPER_TARANG_DATA)filp->private_data; - if(pTarang == NULL) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "ptarang is null\n"); - return 0; + if (pTarang == NULL) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "ptarang is null\n"); + return 0; } Adapter = pTarang->Adapter; - down( &Adapter->RxAppControlQueuelock); + down(&Adapter->RxAppControlQueuelock); - tmp = Adapter->pTarangs; - for ( ptmp = NULL; tmp; ptmp = tmp, tmp = tmp->next ) - { - if ( tmp == pTarang ) + tmp = Adapter->pTarangs; + for (ptmp = NULL; tmp; ptmp = tmp, tmp = tmp->next) { + if (tmp == pTarang) break; } - if ( tmp ) - { - if ( !ptmp ) - Adapter->pTarangs = tmp->next; - else - ptmp->next = tmp->next; + if (tmp) { + if (!ptmp) + Adapter->pTarangs = tmp->next; + else + ptmp->next = tmp->next; + } else { + up(&Adapter->RxAppControlQueuelock); + return 0; } - else - { - up( &Adapter->RxAppControlQueuelock); - return 0; - } - - pkt = pTarang->RxAppControlHead; - while ( pkt ) - { - npkt = pkt->next; - kfree_skb(pkt); - pkt = npkt; + pkt = pTarang->RxAppControlHead; + while (pkt) { + npkt = pkt->next; + kfree_skb(pkt); + pkt = npkt; } - up( &Adapter->RxAppControlQueuelock); + up(&Adapter->RxAppControlQueuelock); - /*Stop Queuing the control response Packets*/ - atomic_dec(&Adapter->ApplicationRunning); + /*Stop Queuing the control response Packets*/ + atomic_dec(&Adapter->ApplicationRunning); - kfree(pTarang); + kfree(pTarang); /* remove this filp from the asynchronously notified filp's */ - filp->private_data = NULL; - return 0; + filp->private_data = NULL; + return 0; } static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size, loff_t *f_pos) -- cgit v1.2.3 From 7227ba06479f981f5cf9977a7eeb3a20d30dc501 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sat, 12 Feb 2011 04:38:24 +0100 Subject: Staging: bcm: Bcmchar: Fix style issues on bcm_char_read() Signed-off-by: Javier Martinez Canillas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 52 +++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 2a3f64ccefec..2064c2e901cc 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -96,59 +96,63 @@ static int bcm_char_release(struct inode *inode, struct file *filp) return 0; } -static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size, loff_t *f_pos) +static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size, + loff_t *f_pos) { PPER_TARANG_DATA pTarang = filp->private_data; PMINI_ADAPTER Adapter = pTarang->Adapter; - struct sk_buff* Packet = NULL; + struct sk_buff *Packet = NULL; ssize_t PktLen = 0; - int wait_ret_val=0; + int wait_ret_val = 0; + unsigned long ret = 0; wait_ret_val = wait_event_interruptible(Adapter->process_read_wait_queue, - (pTarang->RxAppControlHead || Adapter->device_removed)); - if((wait_ret_val == -ERESTARTSYS)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Exiting as i've been asked to exit!!!\n"); + (pTarang->RxAppControlHead || + Adapter->device_removed)); + if ((wait_ret_val == -ERESTARTSYS)) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + "Exiting as i've been asked to exit!!!\n"); return wait_ret_val; } - if(Adapter->device_removed) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device Removed... Killing the Apps...\n"); + if (Adapter->device_removed) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + "Device Removed... Killing the Apps...\n"); return -ENODEV; } - if(FALSE == Adapter->fw_download_done) + if (FALSE == Adapter->fw_download_done) return -EACCES; - down( &Adapter->RxAppControlQueuelock); + down(&Adapter->RxAppControlQueuelock); - if(pTarang->RxAppControlHead) - { + if (pTarang->RxAppControlHead) { Packet = pTarang->RxAppControlHead; - DEQUEUEPACKET(pTarang->RxAppControlHead,pTarang->RxAppControlTail); + DEQUEUEPACKET(pTarang->RxAppControlHead, + pTarang->RxAppControlTail); pTarang->AppCtrlQueueLen--; } - up(&Adapter->RxAppControlQueuelock); + up(&Adapter->RxAppControlQueuelock); - if(Packet) - { + if (Packet) { PktLen = Packet->len; - if(copy_to_user(buf, Packet->data, min_t(size_t, PktLen, size))) - { + ret = copy_to_user(buf, Packet->data, + min_t(size_t, PktLen, size)); + if (ret) { dev_kfree_skb(Packet); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nReturning from copy to user failure \n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "Returning from copy to user failure\n"); return -EFAULT; } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Read %zd Bytes From Adapter packet = %p by process %d!\n", PktLen, Packet, current->pid); dev_kfree_skb(Packet); } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<====\n"); - return PktLen; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<\n"); + return PktLen; } static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) -- cgit v1.2.3 From 78acd58746b513c062b3dafd5b563401bc9e9d47 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sat, 12 Feb 2011 04:38:25 +0100 Subject: Staging: bcm: Bcmchar: Fix some checkpatch errors Signed-off-by: Javier Martinez Canillas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 2064c2e901cc..3d9055aec97c 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -2100,7 +2100,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) } -static struct file_operations bcm_fops = { +static const struct file_operations bcm_fops = { .owner = THIS_MODULE, .open = bcm_char_open, .release = bcm_char_release, @@ -2114,32 +2114,32 @@ extern struct class *bcm_class; int register_control_device_interface(PMINI_ADAPTER Adapter) { - if(Adapter->major>0) + if (Adapter->major > 0) return Adapter->major; Adapter->major = register_chrdev(0, DEV_NAME, &bcm_fops); - if(Adapter->major < 0) { + if (Adapter->major < 0) { pr_err(DRV_NAME ": could not created character device\n"); return Adapter->major; } - Adapter->pstCreatedClassDevice = device_create (bcm_class, NULL, - MKDEV(Adapter->major, 0), Adapter, - DEV_NAME); + Adapter->pstCreatedClassDevice = device_create(bcm_class, NULL, + MKDEV(Adapter->major, 0), + Adapter, DEV_NAME); - if(IS_ERR(Adapter->pstCreatedClassDevice)) { + if (IS_ERR(Adapter->pstCreatedClassDevice)) { pr_err(DRV_NAME ": class device create failed\n"); unregister_chrdev(Adapter->major, DEV_NAME); return PTR_ERR(Adapter->pstCreatedClassDevice); } - + return 0; } void unregister_control_device_interface(PMINI_ADAPTER Adapter) { - if(Adapter->major > 0) { - device_destroy (bcm_class, MKDEV(Adapter->major, 0)); + if (Adapter->major > 0) { + device_destroy(bcm_class, MKDEV(Adapter->major, 0)); unregister_chrdev(Adapter->major, DEV_NAME); } } -- cgit v1.2.3 From ea801950cf54d5d3e219bd51e298193d56cd53e7 Mon Sep 17 00:00:00 2001 From: David Brown Date: Mon, 14 Feb 2011 16:15:25 -0800 Subject: staging: msm: Use explicit GPLv2 licenses Replace a BSD-style license in Code Aurora Forum authored files with an explicit GPLv2. Signed-off-by: David Brown Signed-off-by: Greg Kroah-Hartman --- drivers/staging/msm/mddi_toshiba.h | 30 +++++++----------------------- drivers/staging/msm/mddihost.h | 30 +++++++----------------------- drivers/staging/msm/mddihosti.h | 30 +++++++----------------------- drivers/staging/msm/mdp.h | 30 +++++++----------------------- drivers/staging/msm/mdp4.h | 30 +++++++----------------------- drivers/staging/msm/mdp_ppp_dq.h | 31 +++++++------------------------ drivers/staging/msm/msm_fb.h | 30 +++++++----------------------- drivers/staging/msm/msm_fb_def.h | 30 +++++++----------------------- drivers/staging/msm/msm_fb_panel.h | 30 +++++++----------------------- drivers/staging/msm/tvenc.h | 30 +++++++----------------------- 10 files changed, 70 insertions(+), 231 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/msm/mddi_toshiba.h b/drivers/staging/msm/mddi_toshiba.h index 2d22b9a2c413..cbeea0a26d6c 100644 --- a/drivers/staging/msm/mddi_toshiba.h +++ b/drivers/staging/msm/mddi_toshiba.h @@ -1,29 +1,13 @@ /* Copyright (c) 2009, Code Aurora Forum. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Code Aurora nor - * the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #ifndef MDDI_TOSHIBA_H diff --git a/drivers/staging/msm/mddihost.h b/drivers/staging/msm/mddihost.h index c46f24aea250..8f532d05f83d 100644 --- a/drivers/staging/msm/mddihost.h +++ b/drivers/staging/msm/mddihost.h @@ -1,29 +1,13 @@ /* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Code Aurora nor - * the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #ifndef MDDIHOST_H diff --git a/drivers/staging/msm/mddihosti.h b/drivers/staging/msm/mddihosti.h index 7b26a4253896..79eb39914ac1 100644 --- a/drivers/staging/msm/mddihosti.h +++ b/drivers/staging/msm/mddihosti.h @@ -1,29 +1,13 @@ /* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Code Aurora nor - * the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #ifndef MDDIHOSTI_H diff --git a/drivers/staging/msm/mdp.h b/drivers/staging/msm/mdp.h index 0a5d6ac386ac..44b114700dac 100644 --- a/drivers/staging/msm/mdp.h +++ b/drivers/staging/msm/mdp.h @@ -1,29 +1,13 @@ /* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Code Aurora nor - * the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #ifndef MDP_H diff --git a/drivers/staging/msm/mdp4.h b/drivers/staging/msm/mdp4.h index 26ec8f12cf64..96997d9c9088 100644 --- a/drivers/staging/msm/mdp4.h +++ b/drivers/staging/msm/mdp4.h @@ -1,29 +1,13 @@ /* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Code Aurora nor - * the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #ifndef MDP4_H diff --git a/drivers/staging/msm/mdp_ppp_dq.h b/drivers/staging/msm/mdp_ppp_dq.h index 03e4e9a5f234..759abc20e9ff 100644 --- a/drivers/staging/msm/mdp_ppp_dq.h +++ b/drivers/staging/msm/mdp_ppp_dq.h @@ -1,30 +1,13 @@ /* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of Code Aurora Forum, Inc. nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #ifndef MDP_PPP_DQ_H diff --git a/drivers/staging/msm/msm_fb.h b/drivers/staging/msm/msm_fb.h index f93913800475..4bca6d243f1c 100644 --- a/drivers/staging/msm/msm_fb.h +++ b/drivers/staging/msm/msm_fb.h @@ -1,29 +1,13 @@ /* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Code Aurora nor - * the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #ifndef MSM_FB_H diff --git a/drivers/staging/msm/msm_fb_def.h b/drivers/staging/msm/msm_fb_def.h index c5f9e9e670fb..bc7f2562cc03 100644 --- a/drivers/staging/msm/msm_fb_def.h +++ b/drivers/staging/msm/msm_fb_def.h @@ -1,29 +1,13 @@ /* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Code Aurora nor - * the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #ifndef MSM_FB_DEF_H diff --git a/drivers/staging/msm/msm_fb_panel.h b/drivers/staging/msm/msm_fb_panel.h index ab458310c3a2..6375976f09da 100644 --- a/drivers/staging/msm/msm_fb_panel.h +++ b/drivers/staging/msm/msm_fb_panel.h @@ -1,29 +1,13 @@ /* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Code Aurora nor - * the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #ifndef MSM_FB_PANEL_H diff --git a/drivers/staging/msm/tvenc.h b/drivers/staging/msm/tvenc.h index a682dbebcf7d..6bb375d7a5ad 100644 --- a/drivers/staging/msm/tvenc.h +++ b/drivers/staging/msm/tvenc.h @@ -1,29 +1,13 @@ /* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Code Aurora nor - * the names of its contributors may be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #ifndef TVENC_H -- cgit v1.2.3 From f2f1794835f1d8900d2b15d114c54e70c849809b Mon Sep 17 00:00:00 2001 From: Tony SIM Date: Tue, 15 Feb 2011 19:10:27 +0900 Subject: staging: iio: ak8975: add platform data. As some of the platform not support irq_to_gpio, we pass gpio port by platform data. Signed-off-by: Tony SIM Signed-off-by: Andrew Chew Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/magnetometer/ak8975.c | 8 +++++++- include/linux/input/ak8975.h | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 include/linux/input/ak8975.h (limited to 'drivers') diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c index 420f206cf517..80c0f4137076 100644 --- a/drivers/staging/iio/magnetometer/ak8975.c +++ b/drivers/staging/iio/magnetometer/ak8975.c @@ -29,6 +29,7 @@ #include #include +#include #include "../iio.h" #include "magnet.h" @@ -435,6 +436,7 @@ static int ak8975_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct ak8975_data *data; + struct ak8975_platform_data *pdata; int err; /* Allocate our device context. */ @@ -452,7 +454,11 @@ static int ak8975_probe(struct i2c_client *client, /* Grab and set up the supplied GPIO. */ data->eoc_irq = client->irq; - data->eoc_gpio = irq_to_gpio(client->irq); + pdata = client->dev.platform_data; + if (pdata) + data->eoc_gpio = pdata->gpio; + else + data->eoc_gpio = irq_to_gpio(client->irq); if (!data->eoc_gpio) { dev_err(&client->dev, "failed, no valid GPIO\n"); diff --git a/include/linux/input/ak8975.h b/include/linux/input/ak8975.h new file mode 100644 index 000000000000..25d41eb10c3e --- /dev/null +++ b/include/linux/input/ak8975.h @@ -0,0 +1,20 @@ +/* + * ak8975 platform support + * + * Copyright (C) 2010 Renesas Solutions Corp. + * + * Author: Tony SIM + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _AK8975_H +#define _AK8975_H + +struct ak8975_platform_data { + int gpio; +}; + +#endif -- cgit v1.2.3 From d5857d65b5f7fab78c69da4085f0ce85a0399b25 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 11 Feb 2011 13:09:09 +0000 Subject: staging:iio:buffering move the copy to user on rip down into implementations The current interface is not as adaptable as it should be. Moving this complexity into the implementations makes it easier to add new implementations. Signed-off-by: Jonathan Cameron Tested-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/industrialio-ring.c | 25 +++---------------------- drivers/staging/iio/ring_generic.h | 2 +- drivers/staging/iio/ring_sw.c | 27 +++++++++++++++++---------- drivers/staging/iio/ring_sw.h | 4 ++-- 4 files changed, 23 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c index 9a98fcdbe109..bd4373ae066b 100644 --- a/drivers/staging/iio/industrialio-ring.c +++ b/drivers/staging/iio/industrialio-ring.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -98,31 +97,13 @@ static ssize_t iio_ring_rip_outer(struct file *filp, char __user *buf, size_t count, loff_t *f_ps) { struct iio_ring_buffer *rb = filp->private_data; - int ret, dead_offset, copied; - u8 *data; + int ret, dead_offset; + /* rip lots must exist. */ if (!rb->access.rip_lots) return -EINVAL; - copied = rb->access.rip_lots(rb, count, &data, &dead_offset); + ret = rb->access.rip_lots(rb, count, buf, &dead_offset); - if (copied <= 0) { - ret = copied; - goto error_ret; - } - if (copy_to_user(buf, data + dead_offset, copied)) { - ret = -EFAULT; - goto error_free_data_cpy; - } - /* In clever ring buffer designs this may not need to be freed. - * When such a design exists I'll add this to ring access funcs. - */ - kfree(data); - - return copied; - -error_free_data_cpy: - kfree(data); -error_ret: return ret; } diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h index 8ecb1895cec2..f21ac09373cf 100644 --- a/drivers/staging/iio/ring_generic.h +++ b/drivers/staging/iio/ring_generic.h @@ -73,7 +73,7 @@ struct iio_ring_access_funcs { int (*read_last)(struct iio_ring_buffer *ring, u8 *data); int (*rip_lots)(struct iio_ring_buffer *ring, size_t count, - u8 **data, + char __user *buf, int *dead_offset); int (*mark_param_change)(struct iio_ring_buffer *ring); diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c index 52624ace0bc5..b71ce3900649 100644 --- a/drivers/staging/iio/ring_sw.c +++ b/drivers/staging/iio/ring_sw.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "ring_sw.h" #include "trigger.h" @@ -152,11 +153,12 @@ error_ret: } int iio_rip_sw_rb(struct iio_ring_buffer *r, - size_t count, u8 **data, int *dead_offset) + size_t count, char __user *buf, int *dead_offset) { struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r); u8 *initial_read_p, *initial_write_p, *current_read_p, *end_read_p; + u8 *data; int ret, max_copied; int bytes_to_rip; @@ -174,8 +176,8 @@ int iio_rip_sw_rb(struct iio_ring_buffer *r, /* Limit size to whole of ring buffer */ bytes_to_rip = min((size_t)(ring->buf.bytes_per_datum*ring->buf.length), count); - *data = kmalloc(bytes_to_rip, GFP_KERNEL); - if (*data == NULL) { + data = kmalloc(bytes_to_rip, GFP_KERNEL); + if (data == NULL) { ret = -ENOMEM; goto error_ret; } @@ -204,30 +206,30 @@ int iio_rip_sw_rb(struct iio_ring_buffer *r, if (initial_write_p >= initial_read_p + bytes_to_rip) { /* write_p is greater than necessary, all is easy */ max_copied = bytes_to_rip; - memcpy(*data, initial_read_p, max_copied); + memcpy(data, initial_read_p, max_copied); end_read_p = initial_read_p + max_copied; } else if (initial_write_p > initial_read_p) { /*not enough data to cpy */ max_copied = initial_write_p - initial_read_p; - memcpy(*data, initial_read_p, max_copied); + memcpy(data, initial_read_p, max_copied); end_read_p = initial_write_p; } else { /* going through 'end' of ring buffer */ max_copied = ring->data + ring->buf.length*ring->buf.bytes_per_datum - initial_read_p; - memcpy(*data, initial_read_p, max_copied); + memcpy(data, initial_read_p, max_copied); /* possible we are done if we align precisely with end */ if (max_copied == bytes_to_rip) end_read_p = ring->data; else if (initial_write_p > ring->data + bytes_to_rip - max_copied) { /* enough data to finish */ - memcpy(*data + max_copied, ring->data, + memcpy(data + max_copied, ring->data, bytes_to_rip - max_copied); max_copied = bytes_to_rip; end_read_p = ring->data + (bytes_to_rip - max_copied); } else { /* not enough data */ - memcpy(*data + max_copied, ring->data, + memcpy(data + max_copied, ring->data, initial_write_p - ring->data); max_copied += initial_write_p - ring->data; end_read_p = initial_write_p; @@ -264,11 +266,16 @@ int iio_rip_sw_rb(struct iio_ring_buffer *r, while (ring->read_p != end_read_p) ring->read_p = end_read_p; - return max_copied - *dead_offset; + ret = max_copied - *dead_offset; + if (copy_to_user(buf, data + *dead_offset, ret)) { + ret = -EFAULT; + goto error_free_data_cpy; + } error_free_data_cpy: - kfree(*data); + kfree(data); error_ret: + return ret; } EXPORT_SYMBOL(iio_rip_sw_rb); diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h index ad03d832c1b9..13341c1e35f2 100644 --- a/drivers/staging/iio/ring_sw.h +++ b/drivers/staging/iio/ring_sw.h @@ -96,13 +96,13 @@ int iio_store_to_sw_rb(struct iio_ring_buffer *r, u8 *data, s64 timestamp); * iio_rip_sw_rb() - attempt to read data from the ring buffer * @r: ring buffer instance * @count: number of datum's to try and read - * @data: where the data will be stored. + * @buf: userspace buffer into which data is copied * @dead_offset: how much of the stored data was possibly invalidated by * the end of the copy. **/ int iio_rip_sw_rb(struct iio_ring_buffer *r, size_t count, - u8 **data, + char __user *buf, int *dead_offset); /** -- cgit v1.2.3 From b174baf4b79a067b58a77b86893c55d2c018d6f4 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 11 Feb 2011 13:09:10 +0000 Subject: staging:iio:kfifo buffer implementation A very simple use of a kfifo as an alternative for the ring_sw Signed-off-by: Jonathan Cameron Tested-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Kconfig | 9 ++ drivers/staging/iio/Makefile | 1 + drivers/staging/iio/kfifo_buf.c | 196 ++++++++++++++++++++++++++++++++++++++++ drivers/staging/iio/kfifo_buf.h | 56 ++++++++++++ 4 files changed, 262 insertions(+) create mode 100644 drivers/staging/iio/kfifo_buf.c create mode 100644 drivers/staging/iio/kfifo_buf.h (limited to 'drivers') diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index e2ac07d86110..6775bf90e2f1 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -29,6 +29,15 @@ config IIO_SW_RING with the intention that some devices would be able to write in interrupt context. +config IIO_KFIFO_BUF + select IIO_TRIGGER + tristate "Industrial I/O buffering based on kfifo" + help + A simple fifo based on kfifo. Use this if you want a fifo + rather than a ring buffer. Note that this currently provides + no buffer events so it is up to userspace to work out how + often to read from the buffer. + endif # IIO_RINGBUFFER config IIO_TRIGGER diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile index f9b5fb2fe8f1..bb5c95c7d694 100644 --- a/drivers/staging/iio/Makefile +++ b/drivers/staging/iio/Makefile @@ -8,6 +8,7 @@ industrialio-$(CONFIG_IIO_RING_BUFFER) += industrialio-ring.o industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o obj-$(CONFIG_IIO_SW_RING) += ring_sw.o +obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o obj-y += accel/ obj-y += adc/ diff --git a/drivers/staging/iio/kfifo_buf.c b/drivers/staging/iio/kfifo_buf.c new file mode 100644 index 000000000000..a56c0cbba94b --- /dev/null +++ b/drivers/staging/iio/kfifo_buf.c @@ -0,0 +1,196 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "kfifo_buf.h" + +static inline int __iio_allocate_kfifo(struct iio_kfifo *buf, + int bytes_per_datum, int length) +{ + if ((length == 0) || (bytes_per_datum == 0)) + return -EINVAL; + + __iio_update_ring_buffer(&buf->ring, bytes_per_datum, length); + return kfifo_alloc(&buf->kf, bytes_per_datum*length, GFP_KERNEL); +} + +int iio_request_update_kfifo(struct iio_ring_buffer *r) +{ + int ret = 0; + struct iio_kfifo *buf = iio_to_kfifo(r); + + mutex_lock(&buf->use_lock); + if (!buf->update_needed) + goto error_ret; + if (buf->use_count) { + ret = -EAGAIN; + goto error_ret; + } + kfifo_free(&buf->kf); + ret = __iio_allocate_kfifo(buf, buf->ring.bytes_per_datum, + buf->ring.length); +error_ret: + mutex_unlock(&buf->use_lock); + return ret; +} +EXPORT_SYMBOL(iio_request_update_kfifo); + +void iio_mark_kfifo_in_use(struct iio_ring_buffer *r) +{ + struct iio_kfifo *buf = iio_to_kfifo(r); + mutex_lock(&buf->use_lock); + buf->use_count++; + mutex_unlock(&buf->use_lock); +} +EXPORT_SYMBOL(iio_mark_kfifo_in_use); + +void iio_unmark_kfifo_in_use(struct iio_ring_buffer *r) +{ + struct iio_kfifo *buf = iio_to_kfifo(r); + mutex_lock(&buf->use_lock); + buf->use_count--; + mutex_unlock(&buf->use_lock); +} +EXPORT_SYMBOL(iio_unmark_kfifo_in_use); + +int iio_get_length_kfifo(struct iio_ring_buffer *r) +{ + return r->length; +} +EXPORT_SYMBOL(iio_get_length_kfifo); + +static inline void __iio_init_kfifo(struct iio_kfifo *kf) +{ + mutex_init(&kf->use_lock); +} + +static IIO_RING_ENABLE_ATTR; +static IIO_RING_BYTES_PER_DATUM_ATTR; +static IIO_RING_LENGTH_ATTR; + +static struct attribute *iio_kfifo_attributes[] = { + &dev_attr_length.attr, + &dev_attr_bytes_per_datum.attr, + &dev_attr_enable.attr, + NULL, +}; + +static struct attribute_group iio_kfifo_attribute_group = { + .attrs = iio_kfifo_attributes, +}; + +static const struct attribute_group *iio_kfifo_attribute_groups[] = { + &iio_kfifo_attribute_group, + NULL +}; + +static void iio_kfifo_release(struct device *dev) +{ + struct iio_ring_buffer *r = to_iio_ring_buffer(dev); + struct iio_kfifo *kf = iio_to_kfifo(r); + kfifo_free(&kf->kf); + kfree(kf); +} + +static struct device_type iio_kfifo_type = { + .release = iio_kfifo_release, + .groups = iio_kfifo_attribute_groups, +}; + +struct iio_ring_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev) +{ + struct iio_kfifo *kf; + + kf = kzalloc(sizeof *kf, GFP_KERNEL); + if (!kf) + return NULL; + iio_ring_buffer_init(&kf->ring, indio_dev); + __iio_init_kfifo(kf); + kf->ring.dev.type = &iio_kfifo_type; + device_initialize(&kf->ring.dev); + kf->ring.dev.parent = &indio_dev->dev; + kf->ring.dev.bus = &iio_bus_type; + dev_set_drvdata(&kf->ring.dev, (void *)&(kf->ring)); + + return &kf->ring; +} +EXPORT_SYMBOL(iio_kfifo_allocate); + +int iio_get_bytes_per_datum_kfifo(struct iio_ring_buffer *r) +{ + return r->bytes_per_datum; +} +EXPORT_SYMBOL(iio_get_bytes_per_datum_kfifo); + +int iio_set_bytes_per_datum_kfifo(struct iio_ring_buffer *r, size_t bpd) +{ + if (r->bytes_per_datum != bpd) { + r->bytes_per_datum = bpd; + if (r->access.mark_param_change) + r->access.mark_param_change(r); + } + return 0; +} +EXPORT_SYMBOL(iio_set_bytes_per_datum_kfifo); + +int iio_mark_update_needed_kfifo(struct iio_ring_buffer *r) +{ + struct iio_kfifo *kf = iio_to_kfifo(r); + kf->update_needed = true; + return 0; +} +EXPORT_SYMBOL(iio_mark_update_needed_kfifo); + +int iio_set_length_kfifo(struct iio_ring_buffer *r, int length) +{ + if (r->length != length) { + r->length = length; + if (r->access.mark_param_change) + r->access.mark_param_change(r); + } + return 0; +} +EXPORT_SYMBOL(iio_set_length_kfifo); + +void iio_kfifo_free(struct iio_ring_buffer *r) +{ + if (r) + iio_put_ring_buffer(r); +} +EXPORT_SYMBOL(iio_kfifo_free); + +int iio_store_to_kfifo(struct iio_ring_buffer *r, u8 *data, s64 timestamp) +{ + int ret; + struct iio_kfifo *kf = iio_to_kfifo(r); + u8 *datal = kmalloc(r->bytes_per_datum, GFP_KERNEL); + memcpy(datal, data, r->bytes_per_datum - sizeof(timestamp)); + memcpy(datal + r->bytes_per_datum - sizeof(timestamp), + ×tamp, sizeof(timestamp)); + ret = kfifo_in(&kf->kf, data, r->bytes_per_datum); + if (ret != r->bytes_per_datum) { + kfree(datal); + return -EBUSY; + } + kfree(datal); + return 0; +} +EXPORT_SYMBOL(iio_store_to_kfifo); + +int iio_rip_kfifo(struct iio_ring_buffer *r, + size_t count, char __user *buf, int *deadoffset) +{ + int ret, copied; + struct iio_kfifo *kf = iio_to_kfifo(r); + + *deadoffset = 0; + ret = kfifo_to_user(&kf->kf, buf, r->bytes_per_datum*count, &copied); + + return copied; +} +EXPORT_SYMBOL(iio_rip_kfifo); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/iio/kfifo_buf.h b/drivers/staging/iio/kfifo_buf.h new file mode 100644 index 000000000000..8064383bf7c3 --- /dev/null +++ b/drivers/staging/iio/kfifo_buf.h @@ -0,0 +1,56 @@ + +#include +#include "iio.h" +#include "ring_generic.h" + +struct iio_kfifo { + struct iio_ring_buffer ring; + struct kfifo kf; + int use_count; + int update_needed; + struct mutex use_lock; +}; + +#define iio_to_kfifo(r) container_of(r, struct iio_kfifo, ring) + +int iio_create_kfifo(struct iio_ring_buffer **r); +int iio_init_kfifo(struct iio_ring_buffer *r, struct iio_dev *indio_dev); +void iio_exit_kfifo(struct iio_ring_buffer *r); +void iio_free_kfifo(struct iio_ring_buffer *r); +void iio_mark_kfifo_in_use(struct iio_ring_buffer *r); +void iio_unmark_kfifo_in_use(struct iio_ring_buffer *r); + +int iio_store_to_kfifo(struct iio_ring_buffer *r, u8 *data, s64 timestamp); +int iio_rip_kfifo(struct iio_ring_buffer *r, + size_t count, + char __user *buf, + int *dead_offset); + +int iio_request_update_kfifo(struct iio_ring_buffer *r); +int iio_mark_update_needed_kfifo(struct iio_ring_buffer *r); + +int iio_get_bytes_per_datum_kfifo(struct iio_ring_buffer *r); +int iio_set_bytes_per_datum_kfifo(struct iio_ring_buffer *r, size_t bpd); +int iio_get_length_kfifo(struct iio_ring_buffer *r); +int iio_set_length_kfifo(struct iio_ring_buffer *r, int length); + +static inline void iio_kfifo_register_funcs(struct iio_ring_access_funcs *ra) +{ + ra->mark_in_use = &iio_mark_kfifo_in_use; + ra->unmark_in_use = &iio_unmark_kfifo_in_use; + + ra->store_to = &iio_store_to_kfifo; + ra->rip_lots = &iio_rip_kfifo; + + ra->mark_param_change = &iio_mark_update_needed_kfifo; + ra->request_update = &iio_request_update_kfifo; + + ra->get_bytes_per_datum = &iio_get_bytes_per_datum_kfifo; + ra->set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo; + ra->get_length = &iio_get_length_kfifo; + ra->set_length = &iio_set_length_kfifo; +}; + +struct iio_ring_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev); +void iio_kfifo_free(struct iio_ring_buffer *r); + -- cgit v1.2.3 From b949793b2c319b9ea3c2594aab203664caf2923e Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 11 Feb 2011 13:09:11 +0000 Subject: staging:iio:lis3l02dq allow buffer implementation selection Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/Kconfig | 23 ++++++++++++++++++++++- drivers/staging/iio/accel/lis3l02dq.h | 10 ++++++++++ drivers/staging/iio/accel/lis3l02dq_ring.c | 9 +++++---- 3 files changed, 37 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig index a34f1d3e673c..81a33b60512b 100644 --- a/drivers/staging/iio/accel/Kconfig +++ b/drivers/staging/iio/accel/Kconfig @@ -66,12 +66,33 @@ config LIS3L02DQ tristate "ST Microelectronics LIS3L02DQ Accelerometer Driver" depends on SPI select IIO_TRIGGER if IIO_RING_BUFFER - select IIO_SW_RING if IIO_RING_BUFFER + depends on !IIO_RING_BUFFER || IIO_KFIFO_BUF || IIO_SW_RING help Say yes here to build SPI support for the ST microelectronics accelerometer. The driver supplies direct access via sysfs files and an event interface via a character device. +choice + prompt "Buffer type" + depends on LIS3L02DQ && IIO_RING_BUFFER + +config LIS3L02DQ_BUF_KFIFO + depends on IIO_KFIFO_BUF + bool "Simple FIFO" + help + Kfifo based FIFO. Does not provide any events so it is up + to userspace to ensure it reads often enough that data is not + lost. + +config LIS3L02DQ_BUF_RING_SW + depends on IIO_SW_RING + bool "IIO Software Ring" + help + Original IIO ring buffer implementation. Provides simple + buffer events, half full etc. + +endchoice + config SCA3000 depends on IIO_RING_BUFFER depends on SPI diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h index 6e730553fca8..579b3a26e5d7 100644 --- a/drivers/staging/iio/accel/lis3l02dq.h +++ b/drivers/staging/iio/accel/lis3l02dq.h @@ -196,6 +196,16 @@ ssize_t lis3l02dq_read_accel_from_ring(struct device *dev, int lis3l02dq_configure_ring(struct iio_dev *indio_dev); void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev); +#ifdef CONFIG_LIS3L02DQ_BUF_RING_SW +#define lis3l02dq_free_buf iio_sw_rb_free +#define lis3l02dq_alloc_buf iio_sw_rb_allocate +#define lis3l02dq_register_buf_funcs iio_ring_sw_register_funcs +#endif +#ifdef CONFIG_LIS3L02DQ_BUF_KFIFO +#define lis3l02dq_free_buf iio_kfifo_free +#define lis3l02dq_alloc_buf iio_kfifo_allocate +#define lis3l02dq_register_buf_funcs iio_kfifo_register_funcs +#endif #else /* CONFIG_IIO_RING_BUFFER */ static inline void lis3l02dq_remove_trigger(struct iio_dev *indio_dev) diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 1fd088a11076..2c461a31f129 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -13,6 +13,7 @@ #include "../iio.h" #include "../sysfs.h" #include "../ring_sw.h" +#include "../kfifo_buf.h" #include "accel.h" #include "../trigger.h" #include "lis3l02dq.h" @@ -484,7 +485,7 @@ void lis3l02dq_remove_trigger(struct iio_dev *indio_dev) void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev) { kfree(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->ring); + lis3l02dq_free_buf(indio_dev->ring); } int lis3l02dq_configure_ring(struct iio_dev *indio_dev) @@ -495,13 +496,13 @@ int lis3l02dq_configure_ring(struct iio_dev *indio_dev) INIT_WORK(&h->work_trigger_to_ring, lis3l02dq_trigger_bh_to_ring); h->get_ring_element = &lis3l02dq_get_ring_element; - ring = iio_sw_rb_allocate(indio_dev); + ring = lis3l02dq_alloc_buf(indio_dev); if (!ring) return -ENOMEM; indio_dev->ring = ring; /* Effectively select the ring buffer implementation */ - iio_ring_sw_register_funcs(&ring->access); + lis3l02dq_register_buf_funcs(&ring->access); ring->bpe = 2; ring->scan_el_attrs = &lis3l02dq_scan_el_group; ring->scan_timestamp = true; @@ -522,6 +523,6 @@ int lis3l02dq_configure_ring(struct iio_dev *indio_dev) return 0; error_iio_sw_rb_free: - iio_sw_rb_free(indio_dev->ring); + lis3l02dq_free_buf(indio_dev->ring); return ret; } -- cgit v1.2.3 From 30268a3da9325a2267cfc99efae7c192fa88199f Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 11 Feb 2011 13:09:12 +0000 Subject: staging:iio: update example to handle case with no ring events Signed-off-by: Jonathan Cameron Tested-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/generic_buffer.c | 45 ++++++++++++++-------- 1 file changed, 29 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c index df23aeb9d529..0befcb89ea3a 100644 --- a/drivers/staging/iio/Documentation/generic_buffer.c +++ b/drivers/staging/iio/Documentation/generic_buffer.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "iio_utils.h" const int buf_len = 128; @@ -134,10 +135,11 @@ int main(int argc, char **argv) int dev_num, trig_num; char *buffer_access, *buffer_event; int scan_size; + int noevents = 0; struct iio_channel_info *infoarray; - while ((c = getopt(argc, argv, "t:n:")) != -1) { + while ((c = getopt(argc, argv, "et:n:")) != -1) { switch (c) { case 'n': device_name = optarg; @@ -146,6 +148,9 @@ int main(int argc, char **argv) trigger_name = optarg; datardytrigger = 0; break; + case 'e': + noevents = 1; + break; case '?': return -1; } @@ -260,22 +265,30 @@ int main(int argc, char **argv) /* Wait for events 10 times */ for (j = 0; j < num_loops; j++) { - read_size = fread(&dat, 1, sizeof(struct iio_event_data), - fp_ev); - switch (dat.id) { - case IIO_EVENT_CODE_RING_100_FULL: - toread = buf_len; - break; - case IIO_EVENT_CODE_RING_75_FULL: - toread = buf_len*3/4; - break; - case IIO_EVENT_CODE_RING_50_FULL: - toread = buf_len/2; - break; - default: - printf("Unexpecteded event code\n"); - continue; + if (!noevents) { + read_size = fread(&dat, + 1, + sizeof(struct iio_event_data), + fp_ev); + switch (dat.id) { + case IIO_EVENT_CODE_RING_100_FULL: + toread = buf_len; + break; + case IIO_EVENT_CODE_RING_75_FULL: + toread = buf_len*3/4; + break; + case IIO_EVENT_CODE_RING_50_FULL: + toread = buf_len/2; + break; + default: + printf("Unexpecteded event code\n"); + continue; + } + } else { + usleep(1000); + toread = 64; } + read_size = read(fp, data, toread*scan_size); -- cgit v1.2.3 From 96df9799a4dd62aab7566165d887ea40b1c8aa00 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 11 Feb 2011 13:09:13 +0000 Subject: staging:iio: buffer example - add lots more runtime parameters Add ability to control delay for event free buffers Add ability to control length of buffer Add ability to control how many read cycles occur Signed-off-by: Jonathan Cameron Tested-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/generic_buffer.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c index 0befcb89ea3a..771b23627797 100644 --- a/drivers/staging/iio/Documentation/generic_buffer.c +++ b/drivers/staging/iio/Documentation/generic_buffer.c @@ -29,9 +29,6 @@ #include #include "iio_utils.h" -const int buf_len = 128; -const int num_loops = 2; - /** * size_from_channelarray() - calculate the storage size of a scan * @channels: the channel info array @@ -119,6 +116,11 @@ void process_scan(char *data, int main(int argc, char **argv) { + unsigned long num_loops = 2; + unsigned long timedelay = 1000000; + unsigned long buf_len = 128; + + int ret, c, i, j, toread; FILE *fp_ev; @@ -136,10 +138,11 @@ int main(int argc, char **argv) char *buffer_access, *buffer_event; int scan_size; int noevents = 0; + char *dummy; struct iio_channel_info *infoarray; - while ((c = getopt(argc, argv, "et:n:")) != -1) { + while ((c = getopt(argc, argv, "l:w:c:et:n:")) != -1) { switch (c) { case 'n': device_name = optarg; @@ -151,6 +154,15 @@ int main(int argc, char **argv) case 'e': noevents = 1; break; + case 'c': + num_loops = strtoul(optarg, &dummy, 10); + break; + case 'w': + timedelay = strtoul(optarg, &dummy, 10); + break; + case 'l': + buf_len = strtoul(optarg, &dummy, 10); + break; case '?': return -1; } @@ -285,7 +297,7 @@ int main(int argc, char **argv) continue; } } else { - usleep(1000); + usleep(timedelay); toread = 64; } -- cgit v1.2.3 From 72db6eb674d1a921f31d0fb7b50b6d76cb1c630a Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 11 Feb 2011 14:07:40 +0000 Subject: staging:iio:meter remove stubs from ade7753. General cleanup and use of standard functions to simplfy some spi reads as well. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/ade7753.c | 208 +++++++++--------------------------- drivers/staging/iio/meter/ade7753.h | 64 ----------- 2 files changed, 48 insertions(+), 224 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c index e72afbd2b841..8b86d82c3b32 100644 --- a/drivers/staging/iio/meter/ade7753.c +++ b/drivers/staging/iio/meter/ade7753.c @@ -1,5 +1,5 @@ /* - * ADE7753 Single-Phase Multifunction Metering IC with di/dt Sensor Interface Driver + * ADE7753 Single-Phase Multifunction Metering IC with di/dt Sensor Interface * * Copyright 2010 Analog Devices Inc. * @@ -23,9 +23,9 @@ #include "meter.h" #include "ade7753.h" -int ade7753_spi_write_reg_8(struct device *dev, - u8 reg_address, - u8 val) +static int ade7753_spi_write_reg_8(struct device *dev, + u8 reg_address, + u8 val) { int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); @@ -46,25 +46,14 @@ static int ade7753_spi_write_reg_16(struct device *dev, u16 value) { int ret; - struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ade7753_state *st = iio_dev_get_devdata(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 3, - } - }; mutex_lock(&st->buf_lock); st->tx[0] = ADE7753_WRITE_REG(reg_address); st->tx[1] = (value >> 8) & 0xFF; st->tx[2] = value & 0xFF; - - spi_message_init(&msg); - spi_message_add_tail(xfers, &msg); - ret = spi_sync(st->us, &msg); + ret = spi_write(st->us, st->tx, 3); mutex_unlock(&st->buf_lock); return ret; @@ -74,73 +63,40 @@ static int ade7753_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val) { - struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ade7753_state *st = iio_dev_get_devdata(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 2, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADE7753_READ_REG(reg_address); - st->tx[1] = 0; + ssize_t ret; - spi_message_init(&msg); - spi_message_add_tail(xfers, &msg); - ret = spi_sync(st->us, &msg); - if (ret) { + ret = spi_w8r8(st->us, ADE7753_READ_REG(reg_address)); + if (ret < 0) { dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X", reg_address); - goto error_ret; + return ret; } - *val = st->rx[1]; + *val = ret; -error_ret: - mutex_unlock(&st->buf_lock); - return ret; + return 0; } static int ade7753_spi_read_reg_16(struct device *dev, u8 reg_address, u16 *val) { - struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ade7753_state *st = iio_dev_get_devdata(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 3, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADE7753_READ_REG(reg_address); - st->tx[1] = 0; - st->tx[2] = 0; + ssize_t ret; - spi_message_init(&msg); - spi_message_add_tail(xfers, &msg); - ret = spi_sync(st->us, &msg); - if (ret) { + ret = spi_w8r16(st->us, ADE7753_READ_REG(reg_address)); + if (ret < 0) { dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", - reg_address); - goto error_ret; + reg_address); + return ret; } - *val = (st->rx[1] << 8) | st->rx[2]; -error_ret: - mutex_unlock(&st->buf_lock); - return ret; + *val = ret; + *val = be16_to_cpup(val); + + return 0; } static int ade7753_spi_read_reg_24(struct device *dev, @@ -154,27 +110,28 @@ static int ade7753_spi_read_reg_24(struct device *dev, struct spi_transfer xfers[] = { { .tx_buf = st->tx, - .rx_buf = st->rx, .bits_per_word = 8, - .len = 4, - }, + .len = 1, + }, { + .rx_buf = st->tx, + .bits_per_word = 8, + .len = 3, + } }; mutex_lock(&st->buf_lock); st->tx[0] = ADE7753_READ_REG(reg_address); - st->tx[1] = 0; - st->tx[2] = 0; - st->tx[3] = 0; spi_message_init(&msg); - spi_message_add_tail(xfers, &msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); ret = spi_sync(st->us, &msg); if (ret) { dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X", reg_address); goto error_ret; } - *val = (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3]; + *val = (st->rx[0] << 16) | (st->rx[1] << 8) | st->rx[2]; error_ret: mutex_unlock(&st->buf_lock); @@ -186,7 +143,7 @@ static ssize_t ade7753_read_8bit(struct device *dev, char *buf) { int ret; - u8 val = 0; + u8 val; struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); ret = ade7753_spi_read_reg_8(dev, this_attr->address, &val); @@ -201,7 +158,7 @@ static ssize_t ade7753_read_16bit(struct device *dev, char *buf) { int ret; - u16 val = 0; + u16 val; struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); ret = ade7753_spi_read_reg_16(dev, this_attr->address, &val); @@ -216,14 +173,14 @@ static ssize_t ade7753_read_24bit(struct device *dev, char *buf) { int ret; - u32 val = 0; + u32 val; struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); ret = ade7753_spi_read_reg_24(dev, this_attr->address, &val); if (ret) return ret; - return sprintf(buf, "%u\n", val & 0xFFFFFF); + return sprintf(buf, "%u\n", val); } static ssize_t ade7753_write_8bit(struct device *dev, @@ -264,17 +221,12 @@ error_ret: static int ade7753_reset(struct device *dev) { - int ret; u16 val; - ade7753_spi_read_reg_16(dev, - ADE7753_MODE, - &val); + + ade7753_spi_read_reg_16(dev, ADE7753_MODE, &val); val |= 1 << 6; /* Software Chip Reset */ - ret = ade7753_spi_write_reg_16(dev, - ADE7753_MODE, - val); - return ret; + return ade7753_spi_write_reg_16(dev, ADE7753_MODE, val); } static ssize_t ade7753_write_reset(struct device *dev, @@ -401,27 +353,20 @@ static int ade7753_set_irq(struct device *dev, bool enable) irqen &= ~(1 << 3); ret = ade7753_spi_write_reg_8(dev, ADE7753_IRQEN, irqen); - if (ret) - goto error_ret; error_ret: return ret; } /* Power down the device */ -int ade7753_stop_device(struct device *dev) +static int ade7753_stop_device(struct device *dev) { - int ret; u16 val; - ade7753_spi_read_reg_16(dev, - ADE7753_MODE, - &val); + + ade7753_spi_read_reg_16(dev, ADE7753_MODE, &val); val |= 1 << 4; /* AD converters can be turned off */ - ret = ade7753_spi_write_reg_16(dev, - ADE7753_MODE, - val); - return ret; + return ade7753_spi_write_reg_16(dev, ADE7753_MODE, val); } static int ade7753_initial_setup(struct ade7753_state *st) @@ -454,16 +399,14 @@ static ssize_t ade7753_read_frequency(struct device *dev, int ret, len = 0; u8 t; int sps; - ret = ade7753_spi_read_reg_8(dev, - ADE7753_MODE, - &t); + ret = ade7753_spi_read_reg_8(dev, ADE7753_MODE, &t); if (ret) return ret; t = (t >> 11) & 0x3; sps = 27900 / (1 + t); - len = sprintf(buf, "%d SPS\n", sps); + len = sprintf(buf, "%d\n", sps); return len; } @@ -493,24 +436,21 @@ static ssize_t ade7753_write_frequency(struct device *dev, else st->us->max_speed_hz = ADE7753_SPI_FAST; - ret = ade7753_spi_read_reg_16(dev, - ADE7753_MODE, - ®); + ret = ade7753_spi_read_reg_16(dev, ADE7753_MODE, ®); if (ret) goto out; reg &= ~(3 << 11); reg |= t << 11; - ret = ade7753_spi_write_reg_16(dev, - ADE7753_MODE, - reg); + ret = ade7753_spi_write_reg_16(dev, ADE7753_MODE, reg); out: mutex_unlock(&indio_dev->mlock); return ret ? ret : len; } + static IIO_DEV_ATTR_TEMP_RAW(ade7753_read_8bit); static IIO_CONST_ATTR(temp_offset, "-25 C"); static IIO_CONST_ATTR(temp_scale, "0.67 C"); @@ -525,14 +465,6 @@ static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("27900 14000 7000 3500"); static IIO_CONST_ATTR(name, "ade7753"); -static struct attribute *ade7753_event_attributes[] = { - NULL -}; - -static struct attribute_group ade7753_event_attribute_group = { - .attrs = ade7753_event_attributes, -}; - static struct attribute *ade7753_attributes[] = { &iio_dev_attr_temp_raw.dev_attr.attr, &iio_const_attr_temp_offset.dev_attr.attr, @@ -607,58 +539,22 @@ static int __devinit ade7753_probe(struct spi_device *spi) } st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->num_interrupt_lines = 1; - st->indio_dev->event_attrs = &ade7753_event_attribute_group; st->indio_dev->attrs = &ade7753_attribute_group; st->indio_dev->dev_data = (void *)(st); st->indio_dev->driver_module = THIS_MODULE; st->indio_dev->modes = INDIO_DIRECT_MODE; - ret = ade7753_configure_ring(st->indio_dev); - if (ret) - goto error_free_dev; - ret = iio_device_register(st->indio_dev); if (ret) - goto error_unreg_ring_funcs; + goto error_free_dev; regdone = 1; - ret = ade7753_initialize_ring(st->indio_dev->ring); - if (ret) { - printk(KERN_ERR "failed to initialize the ring\n"); - goto error_unreg_ring_funcs; - } - - if (spi->irq) { - ret = iio_register_interrupt_line(spi->irq, - st->indio_dev, - 0, - IRQF_TRIGGER_FALLING, - "ade7753"); - if (ret) - goto error_uninitialize_ring; - - ret = ade7753_probe_trigger(st->indio_dev); - if (ret) - goto error_unregister_line; - } - /* Get the device into a sane initial state */ ret = ade7753_initial_setup(st); if (ret) - goto error_remove_trigger; + goto error_free_dev; return 0; -error_remove_trigger: - if (st->indio_dev->modes & INDIO_RING_TRIGGERED) - ade7753_remove_trigger(st->indio_dev); -error_unregister_line: - if (st->indio_dev->modes & INDIO_RING_TRIGGERED) - iio_unregister_interrupt_line(st->indio_dev, 0); -error_uninitialize_ring: - ade7753_uninitialize_ring(st->indio_dev->ring); -error_unreg_ring_funcs: - ade7753_unconfigure_ring(st->indio_dev); error_free_dev: if (regdone) iio_device_unregister(st->indio_dev); @@ -685,14 +581,6 @@ static int ade7753_remove(struct spi_device *spi) if (ret) goto err_ret; - flush_scheduled_work(); - - ade7753_remove_trigger(indio_dev); - if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) - iio_unregister_interrupt_line(indio_dev, 0); - - ade7753_uninitialize_ring(indio_dev->ring); - ade7753_unconfigure_ring(indio_dev); iio_device_unregister(indio_dev); kfree(st->tx); kfree(st->rx); @@ -726,5 +614,5 @@ static __exit void ade7753_exit(void) module_exit(ade7753_exit); MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); -MODULE_DESCRIPTION("Analog Devices ADE7753/6 Single-Phase Multifunction Metering IC Driver"); +MODULE_DESCRIPTION("Analog Devices ADE7753/6 Single-Phase Multifunction Meter"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/meter/ade7753.h b/drivers/staging/iio/meter/ade7753.h index a3722b8c90fa..70dabae6efe9 100644 --- a/drivers/staging/iio/meter/ade7753.h +++ b/drivers/staging/iio/meter/ade7753.h @@ -60,81 +60,17 @@ /** * struct ade7753_state - device instance specific data * @us: actual spi_device - * @work_trigger_to_ring: bh for triggered event handling - * @inter: used to check if new interrupt has been triggered - * @last_timestamp: passing timestamp from th to bh of interrupt handler * @indio_dev: industrial I/O device structure - * @trig: data ready trigger registered with iio * @tx: transmit buffer * @rx: recieve buffer * @buf_lock: mutex to protect tx and rx **/ struct ade7753_state { struct spi_device *us; - struct work_struct work_trigger_to_ring; - s64 last_timestamp; struct iio_dev *indio_dev; - struct iio_trigger *trig; u8 *tx; u8 *rx; struct mutex buf_lock; }; -#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT) -/* At the moment triggers are only used for ring buffer - * filling. This may change! - */ - -enum ade7753_scan { - ADE7753_SCAN_ACTIVE_POWER, - ADE7753_SCAN_CH1, - ADE7753_SCAN_CH2, -}; - -void ade7753_remove_trigger(struct iio_dev *indio_dev); -int ade7753_probe_trigger(struct iio_dev *indio_dev); - -ssize_t ade7753_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - - -int ade7753_configure_ring(struct iio_dev *indio_dev); -void ade7753_unconfigure_ring(struct iio_dev *indio_dev); - -int ade7753_initialize_ring(struct iio_ring_buffer *ring); -void ade7753_uninitialize_ring(struct iio_ring_buffer *ring); -#else /* CONFIG_IIO_RING_BUFFER */ - -static inline void ade7753_remove_trigger(struct iio_dev *indio_dev) -{ -} -static inline int ade7753_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline ssize_t -ade7753_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static int ade7753_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} -static inline void ade7753_unconfigure_ring(struct iio_dev *indio_dev) -{ -} -static inline int ade7753_initialize_ring(struct iio_ring_buffer *ring) -{ - return 0; -} -static inline void ade7753_uninitialize_ring(struct iio_ring_buffer *ring) -{ -} -#endif /* CONFIG_IIO_RING_BUFFER */ #endif -- cgit v1.2.3 From 5a0326d9f8134b1b65c22fc09c53bad0d41fe36c Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 11 Feb 2011 14:07:41 +0000 Subject: staging:iio:meter remove stubs from ade7754. General cleanup and use of standard functions to simplfy some spi reads as well. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/ade7754.c | 165 ++++++------------------------------ drivers/staging/iio/meter/ade7754.h | 67 --------------- 2 files changed, 26 insertions(+), 206 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index 23dedfa7a270..4272818e7dc4 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c @@ -46,25 +46,14 @@ static int ade7754_spi_write_reg_16(struct device *dev, u16 value) { int ret; - struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ade7754_state *st = iio_dev_get_devdata(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 3, - } - }; mutex_lock(&st->buf_lock); st->tx[0] = ADE7754_WRITE_REG(reg_address); st->tx[1] = (value >> 8) & 0xFF; st->tx[2] = value & 0xFF; - - spi_message_init(&msg); - spi_message_add_tail(xfers, &msg); - ret = spi_sync(st->us, &msg); + ret = spi_write(st->us, st->tx, 3); mutex_unlock(&st->buf_lock); return ret; @@ -74,73 +63,40 @@ static int ade7754_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val) { - struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ade7754_state *st = iio_dev_get_devdata(indio_dev); int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 2, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADE7754_READ_REG(reg_address); - st->tx[1] = 0; - spi_message_init(&msg); - spi_message_add_tail(xfers, &msg); - ret = spi_sync(st->us, &msg); - if (ret) { + ret = spi_w8r8(st->us, ADE7754_READ_REG(reg_address)); + if (ret < 0) { dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X", reg_address); - goto error_ret; + return ret; } - *val = st->rx[1]; + *val = ret; -error_ret: - mutex_unlock(&st->buf_lock); - return ret; + return 0; } static int ade7754_spi_read_reg_16(struct device *dev, u8 reg_address, u16 *val) { - struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ade7754_state *st = iio_dev_get_devdata(indio_dev); int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 3, - }, - }; - mutex_lock(&st->buf_lock); - st->tx[0] = ADE7754_READ_REG(reg_address); - st->tx[1] = 0; - st->tx[2] = 0; - - spi_message_init(&msg); - spi_message_add_tail(xfers, &msg); - ret = spi_sync(st->us, &msg); - if (ret) { + ret = spi_w8r16(st->us, ADE7754_READ_REG(reg_address)); + if (ret < 0) { dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", - reg_address); - goto error_ret; + reg_address); + return ret; } - *val = (st->rx[1] << 8) | st->rx[2]; -error_ret: - mutex_unlock(&st->buf_lock); - return ret; + *val = ret; + *val = be16_to_cpup(val); + + return 0; } static int ade7754_spi_read_reg_24(struct device *dev, @@ -264,17 +220,11 @@ error_ret: static int ade7754_reset(struct device *dev) { - int ret; u8 val; - ade7754_spi_read_reg_8(dev, - ADE7754_OPMODE, - &val); - val |= 1 << 6; /* Software Chip Reset */ - ret = ade7754_spi_write_reg_8(dev, - ADE7754_OPMODE, - val); - return ret; + ade7754_spi_read_reg_8(dev, ADE7754_OPMODE, &val); + val |= 1 << 6; /* Software Chip Reset */ + return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val); } @@ -431,17 +381,11 @@ error_ret: /* Power down the device */ static int ade7754_stop_device(struct device *dev) { - int ret; u8 val; - ade7754_spi_read_reg_8(dev, - ADE7754_OPMODE, - &val); - val |= 7 << 3; /* ADE7754 powered down */ - ret = ade7754_spi_write_reg_8(dev, - ADE7754_OPMODE, - val); - return ret; + ade7754_spi_read_reg_8(dev, ADE7754_OPMODE, &val); + val |= 7 << 3; /* ADE7754 powered down */ + return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val); } static int ade7754_initial_setup(struct ade7754_state *st) @@ -471,7 +415,7 @@ static ssize_t ade7754_read_frequency(struct device *dev, struct device_attribute *attr, char *buf) { - int ret, len = 0; + int ret; u8 t; int sps; ret = ade7754_spi_read_reg_8(dev, @@ -483,8 +427,7 @@ static ssize_t ade7754_read_frequency(struct device *dev, t = (t >> 3) & 0x3; sps = 26000 / (1 + t); - len = sprintf(buf, "%d SPS\n", sps); - return len; + return sprintf(buf, "%d\n", sps); } static ssize_t ade7754_write_frequency(struct device *dev, @@ -513,18 +456,14 @@ static ssize_t ade7754_write_frequency(struct device *dev, else st->us->max_speed_hz = ADE7754_SPI_FAST; - ret = ade7754_spi_read_reg_8(dev, - ADE7754_WAVMODE, - ®); + ret = ade7754_spi_read_reg_8(dev, ADE7754_WAVMODE, ®); if (ret) goto out; reg &= ~(3 << 3); reg |= t << 3; - ret = ade7754_spi_write_reg_8(dev, - ADE7754_WAVMODE, - reg); + ret = ade7754_spi_write_reg_8(dev, ADE7754_WAVMODE, reg); out: mutex_unlock(&indio_dev->mlock); @@ -545,14 +484,6 @@ static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26000 13000 65000 33000"); static IIO_CONST_ATTR(name, "ade7754"); -static struct attribute *ade7754_event_attributes[] = { - NULL -}; - -static struct attribute_group ade7754_event_attribute_group = { - .attrs = ade7754_event_attributes, -}; - static struct attribute *ade7754_attributes[] = { &iio_dev_attr_temp_raw.dev_attr.attr, &iio_const_attr_temp_offset.dev_attr.attr, @@ -633,58 +564,22 @@ static int __devinit ade7754_probe(struct spi_device *spi) } st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->num_interrupt_lines = 1; - st->indio_dev->event_attrs = &ade7754_event_attribute_group; st->indio_dev->attrs = &ade7754_attribute_group; st->indio_dev->dev_data = (void *)(st); st->indio_dev->driver_module = THIS_MODULE; st->indio_dev->modes = INDIO_DIRECT_MODE; - ret = ade7754_configure_ring(st->indio_dev); - if (ret) - goto error_free_dev; - ret = iio_device_register(st->indio_dev); if (ret) - goto error_unreg_ring_funcs; + goto error_free_dev; regdone = 1; - ret = ade7754_initialize_ring(st->indio_dev->ring); - if (ret) { - printk(KERN_ERR "failed to initialize the ring\n"); - goto error_unreg_ring_funcs; - } - - if (spi->irq) { - ret = iio_register_interrupt_line(spi->irq, - st->indio_dev, - 0, - IRQF_TRIGGER_FALLING, - "ade7754"); - if (ret) - goto error_uninitialize_ring; - - ret = ade7754_probe_trigger(st->indio_dev); - if (ret) - goto error_unregister_line; - } - /* Get the device into a sane initial state */ ret = ade7754_initial_setup(st); if (ret) - goto error_remove_trigger; + goto error_free_dev; return 0; -error_remove_trigger: - if (st->indio_dev->modes & INDIO_RING_TRIGGERED) - ade7754_remove_trigger(st->indio_dev); -error_unregister_line: - if (st->indio_dev->modes & INDIO_RING_TRIGGERED) - iio_unregister_interrupt_line(st->indio_dev, 0); -error_uninitialize_ring: - ade7754_uninitialize_ring(st->indio_dev->ring); -error_unreg_ring_funcs: - ade7754_unconfigure_ring(st->indio_dev); error_free_dev: if (regdone) iio_device_unregister(st->indio_dev); @@ -711,14 +606,6 @@ static int ade7754_remove(struct spi_device *spi) if (ret) goto err_ret; - flush_scheduled_work(); - - ade7754_remove_trigger(indio_dev); - if (spi->irq) - iio_unregister_interrupt_line(indio_dev, 0); - - ade7754_uninitialize_ring(indio_dev->ring); - ade7754_unconfigure_ring(indio_dev); iio_device_unregister(indio_dev); kfree(st->tx); kfree(st->rx); diff --git a/drivers/staging/iio/meter/ade7754.h b/drivers/staging/iio/meter/ade7754.h index f6a3e4b926cf..8faa9b3b48b6 100644 --- a/drivers/staging/iio/meter/ade7754.h +++ b/drivers/staging/iio/meter/ade7754.h @@ -78,84 +78,17 @@ /** * struct ade7754_state - device instance specific data * @us: actual spi_device - * @work_trigger_to_ring: bh for triggered event handling - * @inter: used to check if new interrupt has been triggered - * @last_timestamp: passing timestamp from th to bh of interrupt handler * @indio_dev: industrial I/O device structure - * @trig: data ready trigger registered with iio * @tx: transmit buffer * @rx: recieve buffer * @buf_lock: mutex to protect tx and rx **/ struct ade7754_state { struct spi_device *us; - struct work_struct work_trigger_to_ring; - s64 last_timestamp; struct iio_dev *indio_dev; - struct iio_trigger *trig; u8 *tx; u8 *rx; struct mutex buf_lock; }; -#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT) -/* At the moment triggers are only used for ring buffer - * filling. This may change! - */ - -enum ade7754_scan { - ADE7754_SCAN_PHA_V, - ADE7754_SCAN_PHB_V, - ADE7754_SCAN_PHC_V, - ADE7754_SCAN_PHA_I, - ADE7754_SCAN_PHB_I, - ADE7754_SCAN_PHC_I, -}; - -void ade7754_remove_trigger(struct iio_dev *indio_dev); -int ade7754_probe_trigger(struct iio_dev *indio_dev); - -ssize_t ade7754_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - - -int ade7754_configure_ring(struct iio_dev *indio_dev); -void ade7754_unconfigure_ring(struct iio_dev *indio_dev); - -int ade7754_initialize_ring(struct iio_ring_buffer *ring); -void ade7754_uninitialize_ring(struct iio_ring_buffer *ring); -#else /* CONFIG_IIO_RING_BUFFER */ - -static inline void ade7754_remove_trigger(struct iio_dev *indio_dev) -{ -} -static inline int ade7754_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline ssize_t -ade7754_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static int ade7754_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} -static inline void ade7754_unconfigure_ring(struct iio_dev *indio_dev) -{ -} -static inline int ade7754_initialize_ring(struct iio_ring_buffer *ring) -{ - return 0; -} -static inline void ade7754_uninitialize_ring(struct iio_ring_buffer *ring) -{ -} -#endif /* CONFIG_IIO_RING_BUFFER */ #endif -- cgit v1.2.3 From 3859faca5e6a79bcef54bd2233efe970323e3631 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 11 Feb 2011 14:07:42 +0000 Subject: staging:iio:meter remove stubs from ade7759. General cleanup and use of standard functions to simplfy some spi reads as well. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/ade7759.c | 165 +++++++----------------------------- drivers/staging/iio/meter/ade7759.h | 65 -------------- 2 files changed, 30 insertions(+), 200 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index fafc3c1e5aaa..a9d3203b2e1c 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -23,7 +23,7 @@ #include "meter.h" #include "ade7759.h" -int ade7759_spi_write_reg_8(struct device *dev, +static int ade7759_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val) { @@ -46,25 +46,14 @@ static int ade7759_spi_write_reg_16(struct device *dev, u16 value) { int ret; - struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ade7759_state *st = iio_dev_get_devdata(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 3, - } - }; mutex_lock(&st->buf_lock); st->tx[0] = ADE7759_WRITE_REG(reg_address); st->tx[1] = (value >> 8) & 0xFF; st->tx[2] = value & 0xFF; - - spi_message_init(&msg); - spi_message_add_tail(xfers, &msg); - ret = spi_sync(st->us, &msg); + ret = spi_write(st->us, st->tx, 3); mutex_unlock(&st->buf_lock); return ret; @@ -74,73 +63,40 @@ static int ade7759_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val) { - struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ade7759_state *st = iio_dev_get_devdata(indio_dev); int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 2, - }, - }; - mutex_lock(&st->buf_lock); - st->tx[0] = ADE7759_READ_REG(reg_address); - st->tx[1] = 0; - - spi_message_init(&msg); - spi_message_add_tail(xfers, &msg); - ret = spi_sync(st->us, &msg); - if (ret) { + ret = spi_w8r8(st->us, ADE7759_READ_REG(reg_address)); + if (ret < 0) { dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X", reg_address); - goto error_ret; + return ret; } - *val = st->rx[1]; + *val = ret; -error_ret: - mutex_unlock(&st->buf_lock); - return ret; + return 0; } static int ade7759_spi_read_reg_16(struct device *dev, u8 reg_address, u16 *val) { - struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ade7759_state *st = iio_dev_get_devdata(indio_dev); int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 3, - }, - }; - mutex_lock(&st->buf_lock); - st->tx[0] = ADE7759_READ_REG(reg_address); - st->tx[1] = 0; - st->tx[2] = 0; - - spi_message_init(&msg); - spi_message_add_tail(xfers, &msg); - ret = spi_sync(st->us, &msg); - if (ret) { + ret = spi_w8r16(st->us, ADE7759_READ_REG(reg_address)); + if (ret < 0) { dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", - reg_address); - goto error_ret; + reg_address); + return ret; } - *val = (st->rx[1] << 8) | st->rx[2]; -error_ret: - mutex_unlock(&st->buf_lock); - return ret; + *val = ret; + *val = be16_to_cpup(val); + + return 0; } static int ade7759_spi_read_reg_40(struct device *dev, @@ -354,27 +310,22 @@ static int ade7759_set_irq(struct device *dev, bool enable) irqen &= ~(1 << 3); ret = ade7759_spi_write_reg_8(dev, ADE7759_IRQEN, irqen); - if (ret) - goto error_ret; error_ret: return ret; } /* Power down the device */ -int ade7759_stop_device(struct device *dev) +static int ade7759_stop_device(struct device *dev) { - int ret; u16 val; + ade7759_spi_read_reg_16(dev, ADE7759_MODE, &val); val |= 1 << 4; /* AD converters can be turned off */ - ret = ade7759_spi_write_reg_16(dev, - ADE7759_MODE, - val); - return ret; + return ade7759_spi_write_reg_16(dev, ADE7759_MODE, val); } static int ade7759_initial_setup(struct ade7759_state *st) @@ -404,7 +355,7 @@ static ssize_t ade7759_read_frequency(struct device *dev, struct device_attribute *attr, char *buf) { - int ret, len = 0; + int ret; u16 t; int sps; ret = ade7759_spi_read_reg_16(dev, @@ -416,8 +367,7 @@ static ssize_t ade7759_read_frequency(struct device *dev, t = (t >> 3) & 0x3; sps = 27900 / (1 + t); - len = sprintf(buf, "%d SPS\n", sps); - return len; + return sprintf(buf, "%d\n", sps); } static ssize_t ade7759_write_frequency(struct device *dev, @@ -446,18 +396,14 @@ static ssize_t ade7759_write_frequency(struct device *dev, else st->us->max_speed_hz = ADE7759_SPI_FAST; - ret = ade7759_spi_read_reg_16(dev, - ADE7759_MODE, - ®); + ret = ade7759_spi_read_reg_16(dev, ADE7759_MODE, ®); if (ret) goto out; reg &= ~(3 << 13); reg |= t << 13; - ret = ade7759_spi_write_reg_16(dev, - ADE7759_MODE, - reg); + ret = ade7759_spi_write_reg_16(dev, ADE7759_MODE, reg); out: mutex_unlock(&indio_dev->mlock); @@ -478,14 +424,6 @@ static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("27900 14000 7000 3500"); static IIO_CONST_ATTR(name, "ade7759"); -static struct attribute *ade7759_event_attributes[] = { - NULL -}; - -static struct attribute_group ade7759_event_attribute_group = { - .attrs = ade7759_event_attributes, -}; - static struct attribute *ade7759_attributes[] = { &iio_dev_attr_temp_raw.dev_attr.attr, &iio_const_attr_temp_offset.dev_attr.attr, @@ -517,7 +455,7 @@ static const struct attribute_group ade7759_attribute_group = { static int __devinit ade7759_probe(struct spi_device *spi) { - int ret, regdone = 0; + int ret; struct ade7759_state *st = kzalloc(sizeof *st, GFP_KERNEL); if (!st) { ret = -ENOMEM; @@ -548,62 +486,27 @@ static int __devinit ade7759_probe(struct spi_device *spi) st->indio_dev->dev.parent = &spi->dev; st->indio_dev->num_interrupt_lines = 1; - st->indio_dev->event_attrs = &ade7759_event_attribute_group; + st->indio_dev->attrs = &ade7759_attribute_group; st->indio_dev->dev_data = (void *)(st); st->indio_dev->driver_module = THIS_MODULE; st->indio_dev->modes = INDIO_DIRECT_MODE; - ret = ade7759_configure_ring(st->indio_dev); - if (ret) - goto error_free_dev; - ret = iio_device_register(st->indio_dev); if (ret) - goto error_unreg_ring_funcs; - regdone = 1; - - ret = ade7759_initialize_ring(st->indio_dev->ring); - if (ret) { - printk(KERN_ERR "failed to initialize the ring\n"); - goto error_unreg_ring_funcs; - } - - if (spi->irq) { - ret = iio_register_interrupt_line(spi->irq, - st->indio_dev, - 0, - IRQF_TRIGGER_FALLING, - "ade7759"); - if (ret) - goto error_uninitialize_ring; - - ret = ade7759_probe_trigger(st->indio_dev); - if (ret) - goto error_unregister_line; - } + goto error_free_dev; /* Get the device into a sane initial state */ ret = ade7759_initial_setup(st); if (ret) - goto error_remove_trigger; + goto error_unreg_dev; return 0; -error_remove_trigger: - if (st->indio_dev->modes & INDIO_RING_TRIGGERED) - ade7759_remove_trigger(st->indio_dev); -error_unregister_line: - if (st->indio_dev->modes & INDIO_RING_TRIGGERED) - iio_unregister_interrupt_line(st->indio_dev, 0); -error_uninitialize_ring: - ade7759_uninitialize_ring(st->indio_dev->ring); -error_unreg_ring_funcs: - ade7759_unconfigure_ring(st->indio_dev); + +error_unreg_dev: + iio_device_unregister(st->indio_dev); error_free_dev: - if (regdone) - iio_device_unregister(st->indio_dev); - else - iio_free_device(st->indio_dev); + iio_free_device(st->indio_dev); error_free_tx: kfree(st->tx); error_free_rx: @@ -625,14 +528,6 @@ static int ade7759_remove(struct spi_device *spi) if (ret) goto err_ret; - flush_scheduled_work(); - - ade7759_remove_trigger(indio_dev); - if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) - iio_unregister_interrupt_line(indio_dev, 0); - - ade7759_uninitialize_ring(indio_dev->ring); - ade7759_unconfigure_ring(indio_dev); iio_device_unregister(indio_dev); kfree(st->tx); kfree(st->rx); diff --git a/drivers/staging/iio/meter/ade7759.h b/drivers/staging/iio/meter/ade7759.h index 813dea2676a9..e9d1c43336fe 100644 --- a/drivers/staging/iio/meter/ade7759.h +++ b/drivers/staging/iio/meter/ade7759.h @@ -41,82 +41,17 @@ /** * struct ade7759_state - device instance specific data * @us: actual spi_device - * @work_trigger_to_ring: bh for triggered event handling - * @inter: used to check if new interrupt has been triggered - * @last_timestamp: passing timestamp from th to bh of interrupt handler * @indio_dev: industrial I/O device structure - * @trig: data ready trigger registered with iio * @tx: transmit buffer * @rx: recieve buffer * @buf_lock: mutex to protect tx and rx **/ struct ade7759_state { struct spi_device *us; - struct work_struct work_trigger_to_ring; - s64 last_timestamp; struct iio_dev *indio_dev; - struct iio_trigger *trig; u8 *tx; u8 *rx; struct mutex buf_lock; }; -#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT) -/* At the moment triggers are only used for ring buffer - * filling. This may change! - */ - -enum ade7759_scan { - ADE7759_SCAN_ACTIVE_POWER, - ADE7759_SCAN_CH1_CH2, - ADE7759_SCAN_CH1, - ADE7759_SCAN_CH2, -}; - -void ade7759_remove_trigger(struct iio_dev *indio_dev); -int ade7759_probe_trigger(struct iio_dev *indio_dev); - -ssize_t ade7759_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - - -int ade7759_configure_ring(struct iio_dev *indio_dev); -void ade7759_unconfigure_ring(struct iio_dev *indio_dev); - -int ade7759_initialize_ring(struct iio_ring_buffer *ring); -void ade7759_uninitialize_ring(struct iio_ring_buffer *ring); -#else /* CONFIG_IIO_RING_BUFFER */ - -static inline void ade7759_remove_trigger(struct iio_dev *indio_dev) -{ -} -static inline int ade7759_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline ssize_t -ade7759_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static int ade7759_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} -static inline void ade7759_unconfigure_ring(struct iio_dev *indio_dev) -{ -} -static inline int ade7759_initialize_ring(struct iio_ring_buffer *ring) -{ - return 0; -} -static inline void ade7759_uninitialize_ring(struct iio_ring_buffer *ring) -{ -} -#endif /* CONFIG_IIO_RING_BUFFER */ #endif -- cgit v1.2.3 From 3faa4d3f88d85cdf5de26bd6e52073071cc24b07 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 11 Feb 2011 14:07:43 +0000 Subject: staging:iio:meter remove stubs from ade7854. General cleanup and use of standard functions to simplfy some spi reads as well. Also added a device id table to the spi version. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/ade7854-spi.c | 120 +++++++++++++++++--------------- drivers/staging/iio/meter/ade7854.c | 78 +++------------------ drivers/staging/iio/meter/ade7854.h | 69 ------------------ 3 files changed, 76 insertions(+), 191 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/meter/ade7854-spi.c b/drivers/staging/iio/meter/ade7854-spi.c index fe58103ed4ca..84da8fbde022 100644 --- a/drivers/staging/iio/meter/ade7854-spi.c +++ b/drivers/staging/iio/meter/ade7854-spi.c @@ -22,12 +22,10 @@ static int ade7854_spi_write_reg_8(struct device *dev, struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ade7854_state *st = iio_dev_get_devdata(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 4, - } + struct spi_transfer xfer = { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 4, }; mutex_lock(&st->buf_lock); @@ -37,7 +35,7 @@ static int ade7854_spi_write_reg_8(struct device *dev, st->tx[3] = value & 0xFF; spi_message_init(&msg); - spi_message_add_tail(xfers, &msg); + spi_message_add_tail(&xfer, &msg); ret = spi_sync(st->spi, &msg); mutex_unlock(&st->buf_lock); @@ -52,12 +50,10 @@ static int ade7854_spi_write_reg_16(struct device *dev, struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ade7854_state *st = iio_dev_get_devdata(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 5, - } + struct spi_transfer xfer = { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 5, }; mutex_lock(&st->buf_lock); @@ -68,7 +64,7 @@ static int ade7854_spi_write_reg_16(struct device *dev, st->tx[4] = value & 0xFF; spi_message_init(&msg); - spi_message_add_tail(xfers, &msg); + spi_message_add_tail(&xfer, &msg); ret = spi_sync(st->spi, &msg); mutex_unlock(&st->buf_lock); @@ -83,12 +79,10 @@ static int ade7854_spi_write_reg_24(struct device *dev, struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ade7854_state *st = iio_dev_get_devdata(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 6, - } + struct spi_transfer xfer = { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 6, }; mutex_lock(&st->buf_lock); @@ -100,7 +94,7 @@ static int ade7854_spi_write_reg_24(struct device *dev, st->tx[5] = value & 0xFF; spi_message_init(&msg); - spi_message_add_tail(xfers, &msg); + spi_message_add_tail(&xfer, &msg); ret = spi_sync(st->spi, &msg); mutex_unlock(&st->buf_lock); @@ -115,12 +109,10 @@ static int ade7854_spi_write_reg_32(struct device *dev, struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ade7854_state *st = iio_dev_get_devdata(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 7, - } + struct spi_transfer xfer = { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 7, }; mutex_lock(&st->buf_lock); @@ -133,7 +125,7 @@ static int ade7854_spi_write_reg_32(struct device *dev, st->tx[6] = value & 0xFF; spi_message_init(&msg); - spi_message_add_tail(xfers, &msg); + spi_message_add_tail(&xfer, &msg); ret = spi_sync(st->spi, &msg); mutex_unlock(&st->buf_lock); @@ -152,8 +144,12 @@ static int ade7854_spi_read_reg_8(struct device *dev, { .tx_buf = st->tx, .bits_per_word = 8, - .len = 4, - }, + .len = 3, + }, { + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 1, + } }; mutex_lock(&st->buf_lock); @@ -161,17 +157,17 @@ static int ade7854_spi_read_reg_8(struct device *dev, st->tx[0] = ADE7854_READ_REG; st->tx[1] = (reg_address >> 8) & 0xFF; st->tx[2] = reg_address & 0xFF; - st->tx[3] = 0; spi_message_init(&msg); - spi_message_add_tail(xfers, &msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); ret = spi_sync(st->spi, &msg); if (ret) { dev_err(&st->spi->dev, "problem when reading 8 bit register 0x%02X", reg_address); goto error_ret; } - *val = st->rx[3]; + *val = st->rx[0]; error_ret: mutex_unlock(&st->buf_lock); @@ -190,26 +186,29 @@ static int ade7854_spi_read_reg_16(struct device *dev, { .tx_buf = st->tx, .bits_per_word = 8, - .len = 5, - }, + .len = 3, + }, { + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 2, + } }; mutex_lock(&st->buf_lock); st->tx[0] = ADE7854_READ_REG; st->tx[1] = (reg_address >> 8) & 0xFF; st->tx[2] = reg_address & 0xFF; - st->tx[3] = 0; - st->tx[4] = 0; spi_message_init(&msg); - spi_message_add_tail(xfers, &msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); ret = spi_sync(st->spi, &msg); if (ret) { dev_err(&st->spi->dev, "problem when reading 16 bit register 0x%02X", reg_address); goto error_ret; } - *val = (st->rx[3] << 8) | st->rx[4]; + *val = be16_to_cpup((const __be16 *)st->rx); error_ret: mutex_unlock(&st->buf_lock); @@ -228,8 +227,12 @@ static int ade7854_spi_read_reg_24(struct device *dev, { .tx_buf = st->tx, .bits_per_word = 8, - .len = 6, - }, + .len = 3, + }, { + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 3, + } }; mutex_lock(&st->buf_lock); @@ -237,19 +240,17 @@ static int ade7854_spi_read_reg_24(struct device *dev, st->tx[0] = ADE7854_READ_REG; st->tx[1] = (reg_address >> 8) & 0xFF; st->tx[2] = reg_address & 0xFF; - st->tx[3] = 0; - st->tx[4] = 0; - st->tx[5] = 0; spi_message_init(&msg); - spi_message_add_tail(xfers, &msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); ret = spi_sync(st->spi, &msg); if (ret) { dev_err(&st->spi->dev, "problem when reading 24 bit register 0x%02X", reg_address); goto error_ret; } - *val = (st->rx[3] << 16) | (st->rx[4] << 8) | st->rx[5]; + *val = (st->rx[0] << 16) | (st->rx[1] << 8) | st->rx[2]; error_ret: mutex_unlock(&st->buf_lock); @@ -268,8 +269,12 @@ static int ade7854_spi_read_reg_32(struct device *dev, { .tx_buf = st->tx, .bits_per_word = 8, - .len = 7, - }, + .len = 3, + }, { + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 4, + } }; mutex_lock(&st->buf_lock); @@ -277,20 +282,17 @@ static int ade7854_spi_read_reg_32(struct device *dev, st->tx[0] = ADE7854_READ_REG; st->tx[1] = (reg_address >> 8) & 0xFF; st->tx[2] = reg_address & 0xFF; - st->tx[3] = 0; - st->tx[4] = 0; - st->tx[5] = 0; - st->tx[6] = 0; spi_message_init(&msg); - spi_message_add_tail(xfers, &msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); ret = spi_sync(st->spi, &msg); if (ret) { dev_err(&st->spi->dev, "problem when reading 32 bit register 0x%02X", reg_address); goto error_ret; } - *val = (st->rx[3] << 24) | (st->rx[4] << 16) | (st->rx[5] << 8) | st->rx[6]; + *val = be32_to_cpup((const __be32 *)st->rx); error_ret: mutex_unlock(&st->buf_lock); @@ -333,6 +335,13 @@ static int ade7854_spi_remove(struct spi_device *spi) return 0; } +static const struct spi_device_id ade7854_id[] = { + { "ade7854", 0 }, + { "ade7858", 0 }, + { "ade7868", 0 }, + { "ade7878", 0 }, + { } +}; static struct spi_driver ade7854_driver = { .driver = { @@ -341,6 +350,7 @@ static struct spi_driver ade7854_driver = { }, .probe = ade7854_spi_probe, .remove = __devexit_p(ade7854_spi_remove), + .id_table = ade7854_id, }; static __init int ade7854_init(void) @@ -356,5 +366,5 @@ static __exit void ade7854_exit(void) module_exit(ade7854_exit); MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); -MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC SPI Driver"); +MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 SPI Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c index a13d5048cf42..866e585451f0 100644 --- a/drivers/staging/iio/meter/ade7854.c +++ b/drivers/staging/iio/meter/ade7854.c @@ -61,7 +61,7 @@ static ssize_t ade7854_read_24bit(struct device *dev, char *buf) { int ret; - u32 val = 0; + u32 val; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ade7854_state *st = iio_dev_get_devdata(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); @@ -70,7 +70,7 @@ static ssize_t ade7854_read_24bit(struct device *dev, if (ret) return ret; - return sprintf(buf, "%u\n", val & 0xFFFFFF); + return sprintf(buf, "%u\n", val); } static ssize_t ade7854_read_32bit(struct device *dev, @@ -178,15 +178,12 @@ static int ade7854_reset(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ade7854_state *st = iio_dev_get_devdata(indio_dev); - - int ret; u16 val; st->read_reg_16(dev, ADE7854_CONFIG, &val); val |= 1 << 7; /* Software Chip Reset */ - ret = st->write_reg_16(dev, ADE7854_CONFIG, val); - return ret; + return st->write_reg_16(dev, ADE7854_CONFIG, val); } @@ -477,14 +474,6 @@ static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("8000"); static IIO_CONST_ATTR(name, "ade7854"); -static struct attribute *ade7854_event_attributes[] = { - NULL -}; - -static struct attribute_group ade7854_event_attribute_group = { - .attrs = ade7854_event_attributes, -}; - static struct attribute *ade7854_attributes[] = { &iio_dev_attr_aigain.dev_attr.attr, &iio_dev_attr_bigain.dev_attr.attr, @@ -564,7 +553,7 @@ static const struct attribute_group ade7854_attribute_group = { int ade7854_probe(struct ade7854_state *st, struct device *dev) { - int ret, regdone = 0; + int ret; /* Allocate the comms buffers */ st->rx = kzalloc(sizeof(*st->rx)*ADE7854_MAX_RX, GFP_KERNEL); @@ -586,71 +575,34 @@ int ade7854_probe(struct ade7854_state *st, struct device *dev) } st->indio_dev->dev.parent = dev; - st->indio_dev->num_interrupt_lines = 1; - st->indio_dev->event_attrs = &ade7854_event_attribute_group; st->indio_dev->attrs = &ade7854_attribute_group; st->indio_dev->dev_data = (void *)(st); st->indio_dev->driver_module = THIS_MODULE; st->indio_dev->modes = INDIO_DIRECT_MODE; - ret = ade7854_configure_ring(st->indio_dev); - if (ret) - goto error_free_dev; - ret = iio_device_register(st->indio_dev); if (ret) - goto error_unreg_ring_funcs; - regdone = 1; - - ret = ade7854_initialize_ring(st->indio_dev->ring); - if (ret) { - printk(KERN_ERR "failed to initialize the ring\n"); - goto error_unreg_ring_funcs; - } + goto error_free_dev; - if (st->irq) { - ret = iio_register_interrupt_line(st->irq, - st->indio_dev, - 0, - IRQF_TRIGGER_FALLING, - "ade7854"); - if (ret) - goto error_uninitialize_ring; - - ret = ade7854_probe_trigger(st->indio_dev); - if (ret) - goto error_unregister_line; - } /* Get the device into a sane initial state */ ret = ade7854_initial_setup(st); if (ret) - goto error_remove_trigger; + goto error_unreg_dev; return 0; -error_remove_trigger: - if (st->indio_dev->modes & INDIO_RING_TRIGGERED) - ade7854_remove_trigger(st->indio_dev); -error_unregister_line: - if (st->indio_dev->modes & INDIO_RING_TRIGGERED) - iio_unregister_interrupt_line(st->indio_dev, 0); -error_uninitialize_ring: - ade7854_uninitialize_ring(st->indio_dev->ring); -error_unreg_ring_funcs: - ade7854_unconfigure_ring(st->indio_dev); +error_unreg_dev: + iio_device_unregister(st->indio_dev); error_free_dev: - if (regdone) - iio_device_unregister(st->indio_dev); - else - iio_free_device(st->indio_dev); + iio_free_device(st->indio_dev); error_free_tx: kfree(st->tx); error_free_rx: kfree(st->rx); error_free_st: kfree(st); - return ret; + return ret; } EXPORT_SYMBOL(ade7854_probe); @@ -658,14 +610,6 @@ int ade7854_remove(struct ade7854_state *st) { struct iio_dev *indio_dev = st->indio_dev; - flush_scheduled_work(); - - ade7854_remove_trigger(indio_dev); - if (st->irq) - iio_unregister_interrupt_line(indio_dev, 0); - - ade7854_uninitialize_ring(indio_dev->ring); - ade7854_unconfigure_ring(indio_dev); iio_device_unregister(indio_dev); kfree(st->tx); kfree(st->rx); @@ -676,5 +620,5 @@ int ade7854_remove(struct ade7854_state *st) EXPORT_SYMBOL(ade7854_remove); MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); -MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver"); +MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 Polyphase Energy Meter"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/meter/ade7854.h b/drivers/staging/iio/meter/ade7854.h index 47690e521ec1..4ad84a3bb462 100644 --- a/drivers/staging/iio/meter/ade7854.h +++ b/drivers/staging/iio/meter/ade7854.h @@ -147,11 +147,7 @@ /** * struct ade7854_state - device instance specific data * @spi: actual spi_device - * @work_trigger_to_ring: bh for triggered event handling - * @inter: used to check if new interrupt has been triggered - * @last_timestamp: passing timestamp from th to bh of interrupt handler * @indio_dev: industrial I/O device structure - * @trig: data ready trigger registered with iio * @tx: transmit buffer * @rx: recieve buffer * @buf_lock: mutex to protect tx and rx @@ -159,10 +155,7 @@ struct ade7854_state { struct spi_device *spi; struct i2c_client *i2c; - struct work_struct work_trigger_to_ring; - s64 last_timestamp; struct iio_dev *indio_dev; - struct iio_trigger *trig; u8 *tx; u8 *rx; int (*read_reg_8) (struct device *, u16, u8 *); @@ -180,66 +173,4 @@ struct ade7854_state { extern int ade7854_probe(struct ade7854_state *st, struct device *dev); extern int ade7854_remove(struct ade7854_state *st); -#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT) -/* At the moment triggers are only used for ring buffer - * filling. This may change! - */ - -enum ade7854_scan { - ADE7854_SCAN_PHA_V, - ADE7854_SCAN_PHB_V, - ADE7854_SCAN_PHC_V, - ADE7854_SCAN_PHA_I, - ADE7854_SCAN_PHB_I, - ADE7854_SCAN_PHC_I, -}; - -void ade7854_remove_trigger(struct iio_dev *indio_dev); -int ade7854_probe_trigger(struct iio_dev *indio_dev); - -ssize_t ade7854_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - - -int ade7854_configure_ring(struct iio_dev *indio_dev); -void ade7854_unconfigure_ring(struct iio_dev *indio_dev); - -int ade7854_initialize_ring(struct iio_ring_buffer *ring); -void ade7854_uninitialize_ring(struct iio_ring_buffer *ring); -#else /* CONFIG_IIO_RING_BUFFER */ - -static inline void ade7854_remove_trigger(struct iio_dev *indio_dev) -{ -} -static inline int ade7854_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline ssize_t -ade7854_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static inline int ade7854_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void ade7854_unconfigure_ring(struct iio_dev *indio_dev) -{ -} -static inline int ade7854_initialize_ring(struct iio_ring_buffer *ring) -{ - return 0; -} -static inline void ade7854_uninitialize_ring(struct iio_ring_buffer *ring) -{ -} -#endif /* CONFIG_IIO_RING_BUFFER */ - #endif -- cgit v1.2.3 From d14ae859bb8e1bf372217ecc55b2fe0cb359a545 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 11 Feb 2011 14:20:00 +0000 Subject: staging:iio:gyro:adis16060 cleanup and dead code removal Removed stubs related to buffering and triggering. Put them back when they are actually needed. Fixed line length issues. Made a number of functions static as no longer in header. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/gyro/adis16060.h | 70 ------------------------------- drivers/staging/iio/gyro/adis16060_core.c | 59 ++++++-------------------- 2 files changed, 13 insertions(+), 116 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/gyro/adis16060.h b/drivers/staging/iio/gyro/adis16060.h index 5c00e5385ee0..e85121bff57e 100644 --- a/drivers/staging/iio/gyro/adis16060.h +++ b/drivers/staging/iio/gyro/adis16060.h @@ -14,11 +14,7 @@ /** * struct adis16060_state - device instance specific data * @us_w: actual spi_device to write data - * @work_trigger_to_ring: bh for triggered event handling - * @inter: used to check if new interrupt has been triggered - * @last_timestamp: passing timestamp from th to bh of interrupt handler * @indio_dev: industrial I/O device structure - * @trig: data ready trigger registered with iio * @tx: transmit buffer * @rx: recieve buffer * @buf_lock: mutex to protect tx and rx @@ -26,76 +22,10 @@ struct adis16060_state { struct spi_device *us_w; struct spi_device *us_r; - struct work_struct work_trigger_to_ring; - s64 last_timestamp; struct iio_dev *indio_dev; - struct iio_trigger *trig; u8 *tx; u8 *rx; struct mutex buf_lock; }; -#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT) -/* At the moment triggers are only used for ring buffer - * filling. This may change! - */ - -enum adis16060_scan { - ADIS16060_SCAN_GYRO, - ADIS16060_SCAN_TEMP, - ADIS16060_SCAN_ADC_1, - ADIS16060_SCAN_ADC_2, -}; - -void adis16060_remove_trigger(struct iio_dev *indio_dev); -int adis16060_probe_trigger(struct iio_dev *indio_dev); - -ssize_t adis16060_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - - -int adis16060_configure_ring(struct iio_dev *indio_dev); -void adis16060_unconfigure_ring(struct iio_dev *indio_dev); - -int adis16060_initialize_ring(struct iio_ring_buffer *ring); -void adis16060_uninitialize_ring(struct iio_ring_buffer *ring); -#else /* CONFIG_IIO_RING_BUFFER */ - -static inline void adis16060_remove_trigger(struct iio_dev *indio_dev) -{ -} - -static inline int adis16060_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline ssize_t -adis16060_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static int adis16060_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void adis16060_unconfigure_ring(struct iio_dev *indio_dev) -{ -} - -static inline int adis16060_initialize_ring(struct iio_ring_buffer *ring) -{ - return 0; -} - -static inline void adis16060_uninitialize_ring(struct iio_ring_buffer *ring) -{ -} - -#endif /* CONFIG_IIO_RING_BUFFER */ #endif /* SPI_ADIS16060_H_ */ diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c index fc48aca04bd3..11f51f28d706 100644 --- a/drivers/staging/iio/gyro/adis16060_core.c +++ b/drivers/staging/iio/gyro/adis16060_core.c @@ -25,11 +25,9 @@ #include "adis16060.h" -#define DRIVER_NAME "adis16060" +static struct adis16060_state *adis16060_st; -struct adis16060_state *adis16060_st; - -int adis16060_spi_write(struct device *dev, +static int adis16060_spi_write(struct device *dev, u8 val) { int ret; @@ -47,7 +45,7 @@ int adis16060_spi_write(struct device *dev, return ret; } -int adis16060_spi_read(struct device *dev, +static int adis16060_spi_read(struct device *dev, u16 *val) { int ret; @@ -58,12 +56,15 @@ int adis16060_spi_read(struct device *dev, ret = spi_read(st->us_r, st->rx, 3); - /* The internal successive approximation ADC begins the conversion process - * on the falling edge of MSEL1 and starts to place data MSB first on the - * DOUT line at the 6th falling edge of SCLK + /* The internal successive approximation ADC begins the + * conversion process on the falling edge of MSEL1 and + * starts to place data MSB first on the DOUT line at + * the 6th falling edge of SCLK */ if (ret == 0) - *val = ((st->rx[0] & 0x3) << 12) | (st->rx[1] << 4) | ((st->rx[2] >> 4) & 0xF); + *val = ((st->rx[0] & 0x3) << 12) | + (st->rx[1] << 4) | + ((st->rx[2] >> 4) & 0xF); mutex_unlock(&st->buf_lock); return ret; @@ -74,7 +75,7 @@ static ssize_t adis16060_read(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - u16 val; + u16 val = 0; ssize_t ret; /* Take the iio_dev status lock */ @@ -174,45 +175,14 @@ static int __devinit adis16060_r_probe(struct spi_device *spi) st->indio_dev->driver_module = THIS_MODULE; st->indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis16060_configure_ring(st->indio_dev); - if (ret) - goto error_free_dev; - ret = iio_device_register(st->indio_dev); if (ret) - goto error_unreg_ring_funcs; + goto error_free_dev; regdone = 1; - ret = adis16060_initialize_ring(st->indio_dev->ring); - if (ret) { - printk(KERN_ERR "failed to initialize the ring\n"); - goto error_unreg_ring_funcs; - } - - if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) { - ret = iio_register_interrupt_line(spi->irq, - st->indio_dev, - 0, - IRQF_TRIGGER_RISING, - "adis16060"); - if (ret) - goto error_uninitialize_ring; - - ret = adis16060_probe_trigger(st->indio_dev); - if (ret) - goto error_unregister_line; - } - adis16060_st = st; return 0; -error_unregister_line: - if (st->indio_dev->modes & INDIO_RING_TRIGGERED) - iio_unregister_interrupt_line(st->indio_dev, 0); -error_uninitialize_ring: - adis16060_uninitialize_ring(st->indio_dev->ring); -error_unreg_ring_funcs: - adis16060_unconfigure_ring(st->indio_dev); error_free_dev: if (regdone) iio_device_unregister(st->indio_dev); @@ -236,12 +206,9 @@ static int adis16060_r_remove(struct spi_device *spi) flush_scheduled_work(); - adis16060_remove_trigger(indio_dev); if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) iio_unregister_interrupt_line(indio_dev, 0); - adis16060_uninitialize_ring(indio_dev->ring); - adis16060_unconfigure_ring(indio_dev); iio_device_unregister(indio_dev); kfree(st->tx); kfree(st->rx); @@ -315,5 +282,5 @@ static __exit void adis16060_exit(void) module_exit(adis16060_exit); MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); -MODULE_DESCRIPTION("Analog Devices ADIS16060 Yaw Rate Gyroscope with SPI driver"); +MODULE_DESCRIPTION("Analog Devices ADIS16060 Yaw Rate Gyroscope Driver"); MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 8d016b43c99a2fa8d415cc4fb042c7177098812c Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 11 Feb 2011 14:20:01 +0000 Subject: staging:iio:gyro:adis16080 unused stub removal and cleanup Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/gyro/adis16080.h | 84 ++++--------------------------- drivers/staging/iio/gyro/adis16080_core.c | 54 ++------------------ 2 files changed, 14 insertions(+), 124 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/gyro/adis16080.h b/drivers/staging/iio/gyro/adis16080.h index 3fcbe67f7c31..f4e38510ec46 100644 --- a/drivers/staging/iio/gyro/adis16080.h +++ b/drivers/staging/iio/gyro/adis16080.h @@ -1,14 +1,19 @@ #ifndef SPI_ADIS16080_H_ #define SPI_ADIS16080_H_ -#define ADIS16080_DIN_CODE 4 /* Output data format setting. 0: Twos complement. 1: Offset binary. */ +/* Output data format setting. 0: Twos complement. 1: Offset binary. */ +#define ADIS16080_DIN_CODE 4 #define ADIS16080_DIN_GYRO (0 << 10) /* Gyroscope output */ #define ADIS16080_DIN_TEMP (1 << 10) /* Temperature output */ #define ADIS16080_DIN_AIN1 (2 << 10) #define ADIS16080_DIN_AIN2 (3 << 10) -#define ADIS16080_DIN_WRITE (1 << 15) /* 1: Write contents on DIN to control register. - * 0: No changes to control register. - */ + +/* + * 1: Write contents on DIN to control register. + * 0: No changes to control register. + */ + +#define ADIS16080_DIN_WRITE (1 << 15) #define ADIS16080_MAX_TX 2 #define ADIS16080_MAX_RX 2 @@ -16,87 +21,16 @@ /** * struct adis16080_state - device instance specific data * @us: actual spi_device to write data - * @work_trigger_to_ring: bh for triggered event handling - * @inter: used to check if new interrupt has been triggered - * @last_timestamp: passing timestamp from th to bh of interrupt handler * @indio_dev: industrial I/O device structure - * @trig: data ready trigger registered with iio * @tx: transmit buffer * @rx: recieve buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16080_state { struct spi_device *us; - struct work_struct work_trigger_to_ring; - s64 last_timestamp; struct iio_dev *indio_dev; - struct iio_trigger *trig; u8 *tx; u8 *rx; struct mutex buf_lock; }; - -#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT) -/* At the moment triggers are only used for ring buffer - * filling. This may change! - */ - -enum adis16080_scan { - ADIS16080_SCAN_GYRO, - ADIS16080_SCAN_TEMP, - ADIS16080_SCAN_ADC_1, - ADIS16080_SCAN_ADC_2, -}; - -void adis16080_remove_trigger(struct iio_dev *indio_dev); -int adis16080_probe_trigger(struct iio_dev *indio_dev); - -ssize_t adis16080_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - - -int adis16080_configure_ring(struct iio_dev *indio_dev); -void adis16080_unconfigure_ring(struct iio_dev *indio_dev); - -int adis16080_initialize_ring(struct iio_ring_buffer *ring); -void adis16080_uninitialize_ring(struct iio_ring_buffer *ring); -#else /* CONFIG_IIO_RING_BUFFER */ - -static inline void adis16080_remove_trigger(struct iio_dev *indio_dev) -{ -} - -static inline int adis16080_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline ssize_t -adis16080_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static int adis16080_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void adis16080_unconfigure_ring(struct iio_dev *indio_dev) -{ -} - -static inline int adis16080_initialize_ring(struct iio_ring_buffer *ring) -{ - return 0; -} - -static inline void adis16080_uninitialize_ring(struct iio_ring_buffer *ring) -{ -} - -#endif /* CONFIG_IIO_RING_BUFFER */ #endif /* SPI_ADIS16080_H_ */ diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c index 0efb768db7d3..252080b238e8 100644 --- a/drivers/staging/iio/gyro/adis16080_core.c +++ b/drivers/staging/iio/gyro/adis16080_core.c @@ -25,11 +25,7 @@ #include "adis16080.h" -#define DRIVER_NAME "adis16080" - -struct adis16080_state *adis16080_st; - -int adis16080_spi_write(struct device *dev, +static int adis16080_spi_write(struct device *dev, u16 val) { int ret; @@ -46,7 +42,7 @@ int adis16080_spi_write(struct device *dev, return ret; } -int adis16080_spi_read(struct device *dev, +static int adis16080_spi_read(struct device *dev, u16 *val) { int ret; @@ -69,7 +65,7 @@ static ssize_t adis16080_read(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - u16 val; + u16 val = 0; ssize_t ret; /* Take the iio_dev status lock */ @@ -169,45 +165,13 @@ static int __devinit adis16080_probe(struct spi_device *spi) st->indio_dev->driver_module = THIS_MODULE; st->indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis16080_configure_ring(st->indio_dev); - if (ret) - goto error_free_dev; - ret = iio_device_register(st->indio_dev); if (ret) - goto error_unreg_ring_funcs; + goto error_free_dev; regdone = 1; - ret = adis16080_initialize_ring(st->indio_dev->ring); - if (ret) { - printk(KERN_ERR "failed to initialize the ring\n"); - goto error_unreg_ring_funcs; - } - - if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) { - ret = iio_register_interrupt_line(spi->irq, - st->indio_dev, - 0, - IRQF_TRIGGER_RISING, - "adis16080"); - if (ret) - goto error_uninitialize_ring; - - ret = adis16080_probe_trigger(st->indio_dev); - if (ret) - goto error_unregister_line; - } - - adis16080_st = st; return 0; -error_unregister_line: - if (st->indio_dev->modes & INDIO_RING_TRIGGERED) - iio_unregister_interrupt_line(st->indio_dev, 0); -error_uninitialize_ring: - adis16080_uninitialize_ring(st->indio_dev->ring); -error_unreg_ring_funcs: - adis16080_unconfigure_ring(st->indio_dev); error_free_dev: if (regdone) iio_device_unregister(st->indio_dev); @@ -229,14 +193,6 @@ static int adis16080_remove(struct spi_device *spi) struct adis16080_state *st = spi_get_drvdata(spi); struct iio_dev *indio_dev = st->indio_dev; - flush_scheduled_work(); - - adis16080_remove_trigger(indio_dev); - if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) - iio_unregister_interrupt_line(indio_dev, 0); - - adis16080_uninitialize_ring(indio_dev->ring); - adis16080_unconfigure_ring(indio_dev); iio_device_unregister(indio_dev); kfree(st->tx); kfree(st->rx); @@ -267,5 +223,5 @@ static __exit void adis16080_exit(void) module_exit(adis16080_exit); MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); -MODULE_DESCRIPTION("Analog Devices ADIS16080/100 Yaw Rate Gyroscope with SPI driver"); +MODULE_DESCRIPTION("Analog Devices ADIS16080/100 Yaw Rate Gyroscope Driver"); MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 7a9f437af97110ed7beaceb5932ad8d3aa6e519d Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 11 Feb 2011 14:20:02 +0000 Subject: staging:iio:gyro:adis16130 stub removal and cleanup Get rid of unused stubs for trigger and buffer support. Fix line length issues. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/gyro/adis16130.h | 72 ++----------------------------- drivers/staging/iio/gyro/adis16130_core.c | 61 +++----------------------- 2 files changed, 10 insertions(+), 123 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/gyro/adis16130.h b/drivers/staging/iio/gyro/adis16130.h index ab80ef6a8961..9efc4c773207 100644 --- a/drivers/staging/iio/gyro/adis16130.h +++ b/drivers/staging/iio/gyro/adis16130.h @@ -4,7 +4,9 @@ #define ADIS16130_CON 0x0 #define ADIS16130_CON_RD (1 << 6) #define ADIS16130_IOP 0x1 -#define ADIS16130_IOP_ALL_RDY (1 << 3) /* 1 = data-ready signal low when unread data on all channels; */ + +/* 1 = data-ready signal low when unread data on all channels; */ +#define ADIS16130_IOP_ALL_RDY (1 << 3) #define ADIS16130_IOP_SYNC (1 << 0) /* 1 = synchronization enabled */ #define ADIS16130_RATEDATA 0x8 /* Gyroscope output, rate of rotation */ #define ADIS16130_TEMPDATA 0xA /* Temperature output */ @@ -23,86 +25,18 @@ /** * struct adis16130_state - device instance specific data * @us: actual spi_device to write data - * @work_trigger_to_ring: bh for triggered event handling - * @inter: used to check if new interrupt has been triggered - * @last_timestamp: passing timestamp from th to bh of interrupt handler * @indio_dev: industrial I/O device structure - * @trig: data ready trigger registered with iio * @tx: transmit buffer * @rx: recieve buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16130_state { struct spi_device *us; - struct work_struct work_trigger_to_ring; - s64 last_timestamp; struct iio_dev *indio_dev; - struct iio_trigger *trig; u8 *tx; u8 *rx; u32 mode; /* 1: 24bits mode 0:16bits mode */ struct mutex buf_lock; }; -#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT) -/* At the moment triggers are only used for ring buffer - * filling. This may change! - */ - -enum adis16130_scan { - ADIS16130_SCAN_GYRO, - ADIS16130_SCAN_TEMP, -}; - -void adis16130_remove_trigger(struct iio_dev *indio_dev); -int adis16130_probe_trigger(struct iio_dev *indio_dev); - -ssize_t adis16130_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - - -int adis16130_configure_ring(struct iio_dev *indio_dev); -void adis16130_unconfigure_ring(struct iio_dev *indio_dev); - -int adis16130_initialize_ring(struct iio_ring_buffer *ring); -void adis16130_uninitialize_ring(struct iio_ring_buffer *ring); -#else /* CONFIG_IIO_RING_BUFFER */ - -static inline void adis16130_remove_trigger(struct iio_dev *indio_dev) -{ -} - -static inline int adis16130_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline ssize_t -adis16130_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static int adis16130_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void adis16130_unconfigure_ring(struct iio_dev *indio_dev) -{ -} - -static inline int adis16130_initialize_ring(struct iio_ring_buffer *ring) -{ - return 0; -} - -static inline void adis16130_uninitialize_ring(struct iio_ring_buffer *ring) -{ -} - -#endif /* CONFIG_IIO_RING_BUFFER */ #endif /* SPI_ADIS16130_H_ */ diff --git a/drivers/staging/iio/gyro/adis16130_core.c b/drivers/staging/iio/gyro/adis16130_core.c index 49ffc7b26e8a..04d81d4b2cf2 100644 --- a/drivers/staging/iio/gyro/adis16130_core.c +++ b/drivers/staging/iio/gyro/adis16130_core.c @@ -25,11 +25,7 @@ #include "adis16130.h" -#define DRIVER_NAME "adis16130" - -struct adis16130_state *adis16130_st; - -int adis16130_spi_write(struct device *dev, u8 reg_addr, +static int adis16130_spi_write(struct device *dev, u8 reg_addr, u8 val) { int ret; @@ -46,7 +42,7 @@ int adis16130_spi_write(struct device *dev, u8 reg_addr, return ret; } -int adis16130_spi_read(struct device *dev, u8 reg_addr, +static int adis16130_spi_read(struct device *dev, u8 reg_addr, u32 *val) { int ret; @@ -148,7 +144,8 @@ static IIO_DEV_ATTR_GYRO(adis16130_gyro_read, #define IIO_DEV_ATTR_BITS_MODE(_mode, _show, _store, _addr) \ IIO_DEVICE_ATTR(bits_mode, _mode, _show, _store, _addr) -static IIO_DEV_ATTR_BITS_MODE(S_IWUSR | S_IRUGO, adis16130_bitsmode_read, adis16130_bitsmode_write, +static IIO_DEV_ATTR_BITS_MODE(S_IWUSR | S_IRUGO, adis16130_bitsmode_read, + adis16130_bitsmode_write, ADIS16130_MODE); static struct attribute *adis16130_event_attributes[] = { @@ -173,7 +170,7 @@ static const struct attribute_group adis16130_attribute_group = { static int __devinit adis16130_probe(struct spi_device *spi) { - int ret, regdone = 0; + int ret; struct adis16130_state *st = kzalloc(sizeof *st, GFP_KERNEL); if (!st) { ret = -ENOMEM; @@ -211,50 +208,14 @@ static int __devinit adis16130_probe(struct spi_device *spi) st->indio_dev->modes = INDIO_DIRECT_MODE; st->mode = 1; - ret = adis16130_configure_ring(st->indio_dev); - if (ret) - goto error_free_dev; - ret = iio_device_register(st->indio_dev); if (ret) - goto error_unreg_ring_funcs; - regdone = 1; - - ret = adis16130_initialize_ring(st->indio_dev->ring); - if (ret) { - printk(KERN_ERR "failed to initialize the ring\n"); - goto error_unreg_ring_funcs; - } - - if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) { - ret = iio_register_interrupt_line(spi->irq, - st->indio_dev, - 0, - IRQF_TRIGGER_RISING, - "adis16130"); - if (ret) - goto error_uninitialize_ring; - - ret = adis16130_probe_trigger(st->indio_dev); - if (ret) - goto error_unregister_line; - } + goto error_free_dev; - adis16130_st = st; return 0; -error_unregister_line: - if (st->indio_dev->modes & INDIO_RING_TRIGGERED) - iio_unregister_interrupt_line(st->indio_dev, 0); -error_uninitialize_ring: - adis16130_uninitialize_ring(st->indio_dev->ring); -error_unreg_ring_funcs: - adis16130_unconfigure_ring(st->indio_dev); error_free_dev: - if (regdone) - iio_device_unregister(st->indio_dev); - else - iio_free_device(st->indio_dev); + iio_free_device(st->indio_dev); error_free_tx: kfree(st->tx); error_free_rx: @@ -271,14 +232,6 @@ static int adis16130_remove(struct spi_device *spi) struct adis16130_state *st = spi_get_drvdata(spi); struct iio_dev *indio_dev = st->indio_dev; - flush_scheduled_work(); - - adis16130_remove_trigger(indio_dev); - if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) - iio_unregister_interrupt_line(indio_dev, 0); - - adis16130_uninitialize_ring(indio_dev->ring); - adis16130_unconfigure_ring(indio_dev); iio_device_unregister(indio_dev); kfree(st->tx); kfree(st->rx); -- cgit v1.2.3 From 69648bed5383d5e9454aa9dc922dee4db2eef794 Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Thu, 10 Feb 2011 21:00:39 +0300 Subject: staging: zcache: fix memory leak obj is not freed if __get_free_page() failed. Signed-off-by: Vasiliy Kulikov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/zcache.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/zcache/zcache.c b/drivers/staging/zcache/zcache.c index 61be8498fb06..b8a2b30a1572 100644 --- a/drivers/staging/zcache/zcache.c +++ b/drivers/staging/zcache/zcache.c @@ -790,6 +790,7 @@ static int zcache_do_preload(struct tmem_pool *pool) page = (void *)__get_free_page(ZCACHE_GFP_MASK); if (unlikely(page == NULL)) { zcache_failed_get_free_pages++; + kmem_cache_free(zcache_obj_cache, obj); goto unlock_out; } preempt_disable(); -- cgit v1.2.3 From 6642a67c552e6d525913bb5fb4a00b2008213451 Mon Sep 17 00:00:00 2001 From: Jerome Marchand Date: Thu, 17 Feb 2011 17:11:49 +0100 Subject: Staging: zram: initialize device on first read Currently the device is initialized when first write is done to the device. Any read attempt before the first write would fail, including "hidden" read the user may not know about (as for example if he tries to write a partial block). This patch initializes the device on first request, whether read or write. Signed-off-by: Jerome Marchand Cc: Nitin Gupta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/zram_drv.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 5fdf9d2fc950..aab4ec482124 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -211,11 +211,6 @@ static void zram_read(struct zram *zram, struct bio *bio) u32 index; struct bio_vec *bvec; - if (unlikely(!zram->init_done)) { - bio_endio(bio, -ENXIO); - return; - } - zram_stat64_inc(zram, &zram->stats.num_reads); index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT; @@ -286,20 +281,15 @@ out: static void zram_write(struct zram *zram, struct bio *bio) { - int i, ret; + int i; u32 index; struct bio_vec *bvec; - if (unlikely(!zram->init_done)) { - ret = zram_init_device(zram); - if (ret) - goto out; - } - zram_stat64_inc(zram, &zram->stats.num_writes); index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT; bio_for_each_segment(bvec, bio, i) { + int ret; u32 offset; size_t clen; struct zobj_header *zheader; @@ -445,6 +435,11 @@ static int zram_make_request(struct request_queue *queue, struct bio *bio) return 0; } + if (unlikely(!zram->init_done) && zram_init_device(zram)) { + bio_io_error(bio); + return 0; + } + switch (bio_data_dir(bio)) { case READ: zram_read(zram, bio); -- cgit v1.2.3 From da101d563503d399d92412e833b6d5ae49c8ee5d Mon Sep 17 00:00:00 2001 From: Vipin Mehta Date: Fri, 18 Feb 2011 13:13:02 -0800 Subject: staging: ath6kl: Fixing a NULL pointer exception The driver was dereferencing a NULL pointer because of the device instance being registered via the set_wiphy_dev() function. The function ar6000_avail_ev() was passing the argument as NULL instead of using the one returned by the MMC stack through the probe callback. Signed-off-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 26dafc90451e..4f6ddf759493 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -1604,6 +1604,14 @@ ar6000_avail_ev(void *context, void *hif_handle) struct wireless_dev *wdev; #endif /* ATH6K_CONFIG_CFG80211 */ int init_status = 0; + HIF_DEVICE_OS_DEVICE_INFO osDevInfo; + + memset(&osDevInfo, 0, sizeof(osDevInfo)); + if (HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_OS_DEVICE, + &osDevInfo, sizeof(osDevInfo))) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: Failed to get OS device instance\n", __func__)); + return A_ERROR; + } AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_available\n")); @@ -1623,7 +1631,7 @@ ar6000_avail_ev(void *context, void *hif_handle) device_index = i; #ifdef ATH6K_CONFIG_CFG80211 - wdev = ar6k_cfg80211_init(NULL); + wdev = ar6k_cfg80211_init(osDevInfo.pOSDevice); if (IS_ERR(wdev)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ar6k_cfg80211_init failed\n", __func__)); return A_ERROR; @@ -1668,12 +1676,7 @@ ar6000_avail_ev(void *context, void *hif_handle) #ifdef SET_NETDEV_DEV if (ar_netif) { - HIF_DEVICE_OS_DEVICE_INFO osDevInfo; - A_MEMZERO(&osDevInfo, sizeof(osDevInfo)); - if (!HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_OS_DEVICE, - &osDevInfo, sizeof(osDevInfo))) { - SET_NETDEV_DEV(dev, osDevInfo.pOSDevice); - } + SET_NETDEV_DEV(dev, osDevInfo.pOSDevice); } #endif -- cgit v1.2.3 From e8763b5fe88a0ef8858cd614d961578d34b673a0 Mon Sep 17 00:00:00 2001 From: Vipin Mehta Date: Fri, 18 Feb 2011 13:13:03 -0800 Subject: staging: ath6kl: Fixing key settings for WPA/WPA2 A bug was observed during the reconnection phase in the WPA/WPA2-PSK scenario where the EAPOL frames were going encrypted during an auto reconnection attempt. The initial 4-way handshake would go fine but then the driver was getting a command to set default keys sometime later. Setting of an incorrect flag (TX_USAGE) in the hadrware was causing the EAPOL frames during the subsequent 4-way handshake attempts to go encrypted causing the AP to reject the station. Signed-off-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/cfg80211.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index 1a4e315bab69..b7742d435e2c 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -983,6 +983,7 @@ ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); struct ar_key *key = NULL; int status = 0; + u8 key_usage; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index)); @@ -1011,8 +1012,13 @@ ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, ar->arDefTxKeyIndex = key_index; key = &ar->keys[ar->arDefTxKeyIndex]; + key_usage = GROUP_USAGE; + if (WEP_CRYPT == ar->arPairwiseCrypto) { + key_usage |= TX_USAGE; + } + status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex, - ar->arPairwiseCrypto, GROUP_USAGE | TX_USAGE, + ar->arPairwiseCrypto, key_usage, key->key_len, key->seq, key->key, KEY_OP_INIT_VAL, NULL, SYNC_BOTH_WMIFLAG); if (status) { -- cgit v1.2.3 From 3f2fd78e68cdea8805c92b72008b9eb42f6580f6 Mon Sep 17 00:00:00 2001 From: Vipin Mehta Date: Fri, 18 Feb 2011 13:13:04 -0800 Subject: staging: ath6kl: Return correct scan complete status Return correct scan complete status to the cfg80211 module based on the value returned from the hardware. Signed-off-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index b7742d435e2c..bc5f6a7afc19 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -791,7 +791,7 @@ ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, int status) wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy); cfg80211_scan_done(ar->scan_request, - (status & A_ECANCELED) ? true : false); + ((status & A_ECANCELED) || (status & A_EBUSY)) ? true : false); if(ar->scan_request->n_ssids && ar->scan_request->ssids[0].ssid_len) { -- cgit v1.2.3 From 83195cc8a83df3546d72873ca2aed51f97b0c901 Mon Sep 17 00:00:00 2001 From: Vipin Mehta Date: Fri, 18 Feb 2011 13:13:05 -0800 Subject: staging: ath6kl: Fixing target crash due to mismatch connect/disconnect Firmware design requires a WMI_DISCONNECT_CMD for every WMI_CONNECT_CMD to clear the firmware previous profile state. There is one case in linux host driver where two WMI_CONNECT_CMD are given without a WMI_DISCONNECT_CMD. This causes firmware state to mismatch causing an ASSERT. Use the driver state variable arConnectPending to track whether a WMI_CONNECT_CMD is issued to firmware. Signed-off-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 50 +++++++++++----------- drivers/staging/ath6kl/os/linux/cfg80211.c | 7 +-- .../ath6kl/os/linux/include/ar6xapi_linux.h | 1 + drivers/staging/ath6kl/os/linux/wireless_ext.c | 11 +++-- 4 files changed, 36 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 4f6ddf759493..df9badbc052c 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -1943,15 +1943,12 @@ ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs) { if (!bypasswmi) { - if (ar->arConnected == true || ar->arConnectPending == true) - { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): Disconnect\n", __func__)); - if (!keepprofile) { - AR6000_SPIN_LOCK(&ar->arLock, 0); - ar6000_init_profile_info(ar); - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - } - wmi_disconnect_cmd(ar->arWmi); + bool disconnectIssued; + + disconnectIssued = (ar->arConnected) || (ar->arConnectPending); + ar6000_disconnect(ar); + if (!keepprofile) { + ar6000_init_profile_info(ar); } A_UNTIMEOUT(&ar->disconnect_timer); @@ -1973,14 +1970,12 @@ ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs) * Sometimes disconnect_event will be received when the debug logs * are collected. */ - if (ar->arConnected == true || ar->arConnectPending == true) { + if (disconnectIssued) { if(ar->arNetworkType & AP_NETWORK) { ar6000_disconnect_event(ar, DISCONNECT_CMD, bcast_mac, 0, NULL, 0); } else { ar6000_disconnect_event(ar, DISCONNECT_CMD, ar->arBssid, 0, NULL, 0); } - ar->arConnected = false; - ar->arConnectPending = false; } #ifdef USER_KEYS ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT; @@ -2163,7 +2158,7 @@ static void disconnect_timer_handler(unsigned long ptr) A_UNTIMEOUT(&ar->disconnect_timer); ar6000_init_profile_info(ar); - wmi_disconnect_cmd(ar->arWmi); + ar6000_disconnect(ar); } static void ar6000_detect_error(unsigned long ptr) @@ -2235,7 +2230,6 @@ void ar6000_init_profile_info(AR_SOFTC_T *ar) A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); A_MEMZERO(ar->arBssid, sizeof(ar->arBssid)); ar->arBssChannel = 0; - ar->arConnected = false; } static void @@ -2322,13 +2316,7 @@ ar6000_close(struct net_device *dev) netif_stop_queue(dev); #ifdef ATH6K_CONFIG_CFG80211 - AR6000_SPIN_LOCK(&ar->arLock, 0); - if (ar->arConnected == true || ar->arConnectPending == true) { - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - wmi_disconnect_cmd(ar->arWmi); - } else { - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - } + ar6000_disconnect(ar); if(ar->arWmiReady == true) { if (wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, @@ -4608,6 +4596,8 @@ ar6000_disconnect_event(AR_SOFTC_T *ar, u8 reason, u8 *bssid, A_MEMCPY(wrqu.addr.sa_data, bssid, ATH_MAC_LEN); wireless_send_event(ar->arNetDev, IWEVEXPIRED, &wrqu, NULL); } + + ar->arConnected = false; return; } @@ -4652,7 +4642,6 @@ ar6000_disconnect_event(AR_SOFTC_T *ar, u8 reason, u8 *bssid, */ if( reason == DISCONNECT_CMD) { - ar->arConnectPending = false; if ((!ar->arUserBssFilter) && (ar->arWmiReady)) { wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0); } @@ -6084,8 +6073,6 @@ ar6000_ap_mode_profile_commit(struct ar6_softc *ar) p.groupCryptoLen = ar->arGroupCryptoLen; p.ctrl_flags = ar->arConnectCtrlFlags; - ar->arConnected = false; - wmi_ap_profile_commit(ar->arWmi, &p); spin_lock_irqsave(&ar->arLock, flags); ar->arConnected = true; @@ -6166,6 +6153,21 @@ ar6000_connect_to_ap(struct ar6_softc *ar) return A_ERROR; } +int +ar6000_disconnect(struct ar6_softc *ar) +{ + if ((ar->arConnected == true) || (ar->arConnectPending == true)) { + wmi_disconnect_cmd(ar->arWmi); + /* + * Disconnect cmd is issued, clear connectPending. + * arConnected will be cleard in disconnect_event notification. + */ + ar->arConnectPending = false; + } + + return 0; +} + int ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie) { diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index bc5f6a7afc19..0f8f868c9a5a 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -318,7 +318,7 @@ ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, return 0; } else if(ar->arSsidLen == sme->ssid_len && !A_MEMCMP(ar->arSsid, sme->ssid, ar->arSsidLen)) { - wmi_disconnect_cmd(ar->arWmi); + ar6000_disconnect(ar); } A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); @@ -604,7 +604,7 @@ ar6k_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, } reconnect_flag = 0; - wmi_disconnect_cmd(ar->arWmi); + ar6000_disconnect(ar); A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); ar->arSsidLen = 0; @@ -1341,6 +1341,7 @@ ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, ar->arSsidLen, ar->arSsid, ar->arReqBssid, ar->arChannelHint, ar->arConnectCtrlFlags); + ar->arConnectPending = true; return 0; } @@ -1362,7 +1363,7 @@ ar6k_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) return -EIO; } - wmi_disconnect_cmd(ar->arWmi); + ar6000_disconnect(ar); A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); ar->arSsidLen = 0; diff --git a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h index a8d3f5498227..1acfb9cb7c73 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h @@ -171,6 +171,7 @@ void ap_wapi_rekey_event(struct ar6_softc *ar, u8 type, u8 *mac); #endif int ar6000_connect_to_ap(struct ar6_softc *ar); +int ar6000_disconnect(struct ar6_softc *ar); int ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool suspending); int ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state); int ar6000_set_bt_hw_state(struct ar6_softc *ar, u32 state); diff --git a/drivers/staging/ath6kl/os/linux/wireless_ext.c b/drivers/staging/ath6kl/os/linux/wireless_ext.c index 1f858ca87a01..baa86633b2a0 100644 --- a/drivers/staging/ath6kl/os/linux/wireless_ext.c +++ b/drivers/staging/ath6kl/os/linux/wireless_ext.c @@ -575,9 +575,10 @@ ar6000_ioctl_siwessid(struct net_device *dev, /* Update the arNetworkType */ ar->arNetworkType = ar->arNextMode; - if ((prevMode != AP_NETWORK) && - ((ar->arSsidLen) || ((ar->arSsidLen == 0) && ar->arConnected) || (!data->flags))) + ((ar->arSsidLen) || + ((ar->arSsidLen == 0) && (ar->arConnected || ar->arConnectPending)) || + (!data->flags))) { if ((!data->flags) || (A_MEMCMP(ar->arSsid, ssid, ar->arSsidLen) != 0) || @@ -594,7 +595,7 @@ ar6000_ioctl_siwessid(struct net_device *dev, if (ar->arWmiReady == true) { reconnect_flag = 0; status = wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, 0); - status = wmi_disconnect_cmd(ar->arWmi); + ar6000_disconnect(ar); A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); ar->arSsidLen = 0; if (ar->arSkipScan == false) { @@ -2414,7 +2415,7 @@ ar6000_ioctl_siwmlme(struct net_device *dev, ar6000_init_profile_info(ar); ar->arNetworkType = arNetworkType; reconnect_flag = 0; - wmi_disconnect_cmd(ar->arWmi); + ar6000_disconnect(ar); A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); ar->arSsidLen = 0; if (ar->arSkipScan == false) { @@ -2614,8 +2615,6 @@ ar6000_ioctl_siwcommit(struct net_device *dev, * update the host driver association state for the STA|IBSS mode. */ if (ar->arNetworkType != AP_NETWORK && ar->arNextMode == AP_NETWORK) { - ar->arConnectPending = false; - ar->arConnected = false; /* Stop getting pkts from upper stack */ netif_stop_queue(ar->arNetDev); A_MEMZERO(ar->arBssid, sizeof(ar->arBssid)); -- cgit v1.2.3 From caf3fb4194f321f7657d697f901744aa3b899682 Mon Sep 17 00:00:00 2001 From: Vipin Mehta Date: Fri, 18 Feb 2011 13:13:06 -0800 Subject: staging: ath6kl: Fixing driver initialization for manufacturing mode Fixing the driver initialization for manufacturing mode that involves downloading a firmware binary meant for RF tests on the factory floor. Signed-off-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index df9badbc052c..d907e93f9457 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -1806,7 +1806,9 @@ ar6000_avail_ev(void *context, void *hif_handle) break; } #ifdef HTC_RAW_INTERFACE - break; /* Don't call ar6000_init for ART */ + if (!eppingtest && bypasswmi) { + break; /* Don't call ar6000_init for ART */ + } #endif rtnl_lock(); status = (ar6000_init(dev)==0) ? 0 : A_ERROR; -- cgit v1.2.3 From 15eccc06e107f7d28e3e9985dc529a5dbbc4df63 Mon Sep 17 00:00:00 2001 From: Vipin Mehta Date: Fri, 18 Feb 2011 13:13:07 -0800 Subject: staging: ath6kl: Consolidating hardware configuration Move all the wmi configuration commands done after wmi_ready to a single function. Signed-off-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 184 +++++++++++++++++---------- 1 file changed, 115 insertions(+), 69 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index d907e93f9457..b69280da1130 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -2417,6 +2417,120 @@ u8 ar6000_endpoint_id2_ac(void * devt, HTC_ENDPOINT_ID ep ) return(arEndpoint2Ac(ar, ep )); } +/* + * This function applies WLAN specific configuration defined in wlan_config.h + */ +int ar6000_target_config_wlan_params(AR_SOFTC_T *ar) +{ + int status = 0; +#if defined(INIT_MODE_DRV_ENABLED) && defined(ENABLE_COEXISTENCE) + WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD sbcb_cmd; + WMI_SET_BTCOEX_FE_ANT_CMD sbfa_cmd; +#endif /* INIT_MODE_DRV_ENABLED && ENABLE_COEXISTENCE */ + +#ifdef CONFIG_HOST_TCMD_SUPPORT + if (ar->arTargetMode != AR6000_WLAN_MODE) { + return 0; + } +#endif /* CONFIG_HOST_TCMD_SUPPORT */ + + /* + * configure the device for rx dot11 header rules 0,0 are the default values + * therefore this command can be skipped if the inputs are 0,FALSE,FALSE.Required + * if checksum offload is needed. Set RxMetaVersion to 2 + */ + if ((wmi_set_rx_frame_format_cmd(ar->arWmi,ar->rxMetaVersion, processDot11Hdr, processDot11Hdr)) != 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the rx frame format.\n")); + status = A_ERROR; + } + +#if defined(INIT_MODE_DRV_ENABLED) && defined(ENABLE_COEXISTENCE) + /* Configure the type of BT collocated with WLAN */ + memset(&sbcb_cmd, 0, sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD)); +#ifdef CONFIG_AR600x_BT_QCOM + sbcb_cmd.btcoexCoLocatedBTdev = 1; +#elif defined(CONFIG_AR600x_BT_CSR) + sbcb_cmd.btcoexCoLocatedBTdev = 2; +#elif defined(CONFIG_AR600x_BT_AR3001) + sbcb_cmd.btcoexCoLocatedBTdev = 3; +#else +#error Unsupported Bluetooth Type +#endif /* Collocated Bluetooth Type */ + + if ((wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &sbcb_cmd)) != 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set collocated BT type\n")); + status = A_ERROR; + } + + /* Configure the type of BT collocated with WLAN */ + memset(&sbfa_cmd, 0, sizeof(WMI_SET_BTCOEX_FE_ANT_CMD)); +#ifdef CONFIG_AR600x_DUAL_ANTENNA + sbfa_cmd.btcoexFeAntType = 2; +#elif defined(CONFIG_AR600x_SINGLE_ANTENNA) + sbfa_cmd.btcoexFeAntType = 1; +#else +#error Unsupported Front-End Antenna Configuration +#endif /* AR600x Front-End Antenna Configuration */ + + if ((wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &sbfa_cmd)) != 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set fornt end antenna configuration\n")); + status = A_ERROR; + } +#endif /* INIT_MODE_DRV_ENABLED && ENABLE_COEXISTENCE */ + +#if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN + if ((wmi_pmparams_cmd(ar->arWmi, 0, 1, 0, 0, 1, IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set power save fail event policy\n")); + status = A_ERROR; + } +#endif + +#if WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP + if ((wmi_set_lpreamble_cmd(ar->arWmi, 0, WMI_DONOT_IGNORE_BARKER_IN_ERP)) != 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set barker preamble policy\n")); + status = A_ERROR; + } +#endif + + if ((wmi_set_keepalive_cmd(ar->arWmi, WLAN_CONFIG_KEEP_ALIVE_INTERVAL)) != 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set keep alive interval\n")); + status = A_ERROR; + } + +#if WLAN_CONFIG_DISABLE_11N + { + WMI_SET_HT_CAP_CMD htCap; + + memset(&htCap, 0, sizeof(WMI_SET_HT_CAP_CMD)); + htCap.band = 0; + if ((wmi_set_ht_cap_cmd(ar->arWmi, &htCap)) != 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set ht capabilities \n")); + status = A_ERROR; + } + + htCap.band = 1; + if ((wmi_set_ht_cap_cmd(ar->arWmi, &htCap)) != 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set ht capabilities \n")); + status = A_ERROR; + } + } +#endif /* WLAN_CONFIG_DISABLE_11N */ + +#ifdef ATH6K_CONFIG_OTA_MODE + if ((wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER)) != 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set power mode \n")); + status = A_ERROR; + } +#endif + + if ((wmi_disctimeout_cmd(ar->arWmi, WLAN_CONFIG_DISCONNECT_TIMEOUT)) != 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set disconnect timeout \n")); + status = A_ERROR; + } + + return status; +} + /* This function does one time initialization for the lifetime of the device */ int ar6000_init(struct net_device *dev) { @@ -2425,10 +2539,6 @@ int ar6000_init(struct net_device *dev) s32 timeleft; s16 i; int ret = 0; -#if defined(INIT_MODE_DRV_ENABLED) && defined(ENABLE_COEXISTENCE) - WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD sbcb_cmd; - WMI_SET_BTCOEX_FE_ANT_CMD sbfa_cmd; -#endif /* INIT_MODE_DRV_ENABLED && ENABLE_COEXISTENCE */ if((ar = ar6k_priv(dev)) == NULL) { @@ -2696,46 +2806,7 @@ int ar6000_init(struct net_device *dev) if ((ar6000_set_host_app_area(ar)) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the host app area\n")); } - - /* configure the device for rx dot11 header rules 0,0 are the default values - * therefore this command can be skipped if the inputs are 0,false,false.Required - if checksum offload is needed. Set RxMetaVersion to 2*/ - if ((wmi_set_rx_frame_format_cmd(ar->arWmi,ar->rxMetaVersion, processDot11Hdr, processDot11Hdr)) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the rx frame format.\n")); - } - -#if defined(INIT_MODE_DRV_ENABLED) && defined(ENABLE_COEXISTENCE) - /* Configure the type of BT collocated with WLAN */ - A_MEMZERO(&sbcb_cmd, sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD)); -#ifdef CONFIG_AR600x_BT_QCOM - sbcb_cmd.btcoexCoLocatedBTdev = 1; -#elif defined(CONFIG_AR600x_BT_CSR) - sbcb_cmd.btcoexCoLocatedBTdev = 2; -#elif defined(CONFIG_AR600x_BT_AR3001) - sbcb_cmd.btcoexCoLocatedBTdev = 3; -#else -#error Unsupported Bluetooth Type -#endif /* Collocated Bluetooth Type */ - - if ((wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &sbcb_cmd)) != 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set collocated BT type\n")); - } - - /* Configure the type of BT collocated with WLAN */ - A_MEMZERO(&sbfa_cmd, sizeof(WMI_SET_BTCOEX_FE_ANT_CMD)); -#ifdef CONFIG_AR600x_DUAL_ANTENNA - sbfa_cmd.btcoexFeAntType = 2; -#elif defined(CONFIG_AR600x_SINGLE_ANTENNA) - sbfa_cmd.btcoexFeAntType = 1; -#else -#error Unsupported Front-End Antenna Configuration -#endif /* AR600x Front-End Antenna Configuration */ - - if ((wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &sbfa_cmd)) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set fornt end antenna configuration\n")); - } -#endif /* INIT_MODE_DRV_ENABLED && ENABLE_COEXISTENCE */ + ar6000_target_config_wlan_params(ar); } ar->arNumDataEndPts = 1; @@ -4169,31 +4240,6 @@ ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, u32 sw_ver, u32 abi_ver) /* Indicate to the waiting thread that the ready event was received */ ar->arWmiReady = true; wake_up(&arEvent); - -#if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN - wmi_pmparams_cmd(ar->arWmi, 0, 1, 0, 0, 1, IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN); -#endif -#if WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP - wmi_set_lpreamble_cmd(ar->arWmi, 0, WMI_DONOT_IGNORE_BARKER_IN_ERP); -#endif - wmi_set_keepalive_cmd(ar->arWmi, WLAN_CONFIG_KEEP_ALIVE_INTERVAL); -#if WLAN_CONFIG_DISABLE_11N - { - WMI_SET_HT_CAP_CMD htCap; - - A_MEMZERO(&htCap, sizeof(WMI_SET_HT_CAP_CMD)); - htCap.band = 0; - wmi_set_ht_cap_cmd(ar->arWmi, &htCap); - - htCap.band = 1; - wmi_set_ht_cap_cmd(ar->arWmi, &htCap); - } -#endif /* WLAN_CONFIG_DISABLE_11N */ - -#ifdef ATH6K_CONFIG_OTA_MODE - wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER); -#endif - wmi_disctimeout_cmd(ar->arWmi, WLAN_CONFIG_DISCONNECT_TIMEOUT); } void -- cgit v1.2.3 From fb9b548717444c82eb2d196c91729421ee68d4be Mon Sep 17 00:00:00 2001 From: Vipin Mehta Date: Fri, 18 Feb 2011 13:13:08 -0800 Subject: staging: ath6kl: Adding support for txop bursting enable/disable Adding compile time support for enabling/disabling txop bursting. Signed-off-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 7 +++++++ drivers/staging/ath6kl/os/linux/include/wlan_config.h | 7 +++++++ 2 files changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index b69280da1130..f084a92c9209 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -2528,6 +2528,13 @@ int ar6000_target_config_wlan_params(AR_SOFTC_T *ar) status = A_ERROR; } +#if WLAN_CONFIG_DISABLE_TX_BURSTING + if ((wmi_set_wmm_txop(ar->arWmi, WMI_TXOP_DISABLED)) != 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set txop bursting \n")); + status = A_ERROR; + } +#endif + return status; } diff --git a/drivers/staging/ath6kl/os/linux/include/wlan_config.h b/drivers/staging/ath6kl/os/linux/include/wlan_config.h index f7d048722226..2de5cef26cce 100644 --- a/drivers/staging/ath6kl/os/linux/include/wlan_config.h +++ b/drivers/staging/ath6kl/os/linux/include/wlan_config.h @@ -102,6 +102,13 @@ */ #define WLAN_CONFIG_PM_WOW2 0 +/* + * This configuration item enables/disables transmit bursting + * 0 - Enable tx Bursting (default) + * 1 - Disable tx bursting + */ +#define WLAN_CONFIG_DISABLE_TX_BURSTING 0 + /* * Platform specific function to power ON/OFF AR6000 * and enable/disable SDIO card detection -- cgit v1.2.3 From 774c1fe2fe9f14c657deb63705ef044f7af9a6cb Mon Sep 17 00:00:00 2001 From: Vipin Mehta Date: Fri, 18 Feb 2011 13:13:09 -0800 Subject: staging: ath6kl: Fixing a memory leak Virtual Scatter Gather Lists not getting freed during the HTCStop(). The patch adds some clean up code in the code path. Signed-off-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 9 +++++++++ drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 2 ++ drivers/staging/ath6kl/htc2/htc.c | 2 ++ 3 files changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index 6083231cdbb0..ff0480b5254b 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -810,6 +810,15 @@ static int DevSetupVirtualScatterSupport(AR6K_DEVICE *pDev) return status; } +int DevCleanupMsgBundling(AR6K_DEVICE *pDev) +{ + if(NULL != pDev) + { + DevCleanupVirtualScatterSupport(pDev); + } + + return 0; +} int DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer) { diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index d3b6b309dc2a..19d8e706057d 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -297,6 +297,8 @@ static INLINE int DEV_PREPARE_SCATTER_OPERATION(HIF_SCATTER_REQ *pReq) { int DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer); + +int DevCleanupMsgBundling(AR6K_DEVICE *pDev); #define DEV_GET_MAX_MSG_PER_BUNDLE(pDev) (pDev)->HifScatterInfo.MaxScatterEntries #define DEV_GET_MAX_BUNDLE_LENGTH(pDev) (pDev)->HifScatterInfo.MaxTransferSizePerScatterReq diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index 684eca9bd022..e7adc45324af 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -486,6 +486,8 @@ void HTCStop(HTC_HANDLE HTCHandle) /* flush all recv buffers */ HTCFlushRecvBuffers(target); + DevCleanupMsgBundling(&target->Device); + ResetEndpointStates(target); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCStop \n")); -- cgit v1.2.3 From 1581595dd918481e2df9927e08c71c5635b9af1e Mon Sep 17 00:00:00 2001 From: Vipin Mehta Date: Fri, 18 Feb 2011 13:13:10 -0800 Subject: staging: ath6kl: Fixing a memory leak Fix for a memory leak discovered during suspend/resume testing. Signed-off-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index f084a92c9209..93592af1d052 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -2052,6 +2052,9 @@ ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs) } /* Done with cookies */ ar6000_cookie_cleanup(ar); + + /* cleanup any allocated AMSDU buffers */ + ar6000_cleanup_amsdu_rxbufs(ar); } /* * We need to differentiate between the surprise and planned removal of the -- cgit v1.2.3 From 711a1bccf23a54868d94af200061d35207c358e9 Mon Sep 17 00:00:00 2001 From: Vipin Mehta Date: Fri, 18 Feb 2011 13:13:11 -0800 Subject: staging: ath6kl: Add configuration for excessive TX retry threshold Adding host side interface to configure the excessive TX retry threshold. It is used by the target to determine disconnection triggers. Additionally, some definitions have been added to header file wmi.h to bridge the gap for the newly added command. Signed-off-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/include/common/wmi.h | 36 +++++++++++++++------- drivers/staging/ath6kl/include/wmi_api.h | 3 ++ .../staging/ath6kl/os/linux/include/athdrv_linux.h | 1 + .../ath6kl/os/linux/include/wmi_filter_linux.h | 7 +++++ drivers/staging/ath6kl/os/linux/ioctl.c | 28 +++++++++++++++++ drivers/staging/ath6kl/wmi/wmi.c | 21 +++++++++++++ 6 files changed, 85 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/include/common/wmi.h b/drivers/staging/ath6kl/include/common/wmi.h index f16ef28537b9..a8b143ad12cd 100644 --- a/drivers/staging/ath6kl/include/common/wmi.h +++ b/drivers/staging/ath6kl/include/common/wmi.h @@ -422,17 +422,24 @@ typedef enum { WMI_AP_SET_11BG_RATESET_CMDID, WMI_SET_PMK_CMDID, WMI_MCAST_FILTER_CMDID, - /* COEX CMDID AR6003*/ - WMI_SET_BTCOEX_FE_ANT_CMDID, - WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID, - WMI_SET_BTCOEX_SCO_CONFIG_CMDID, - WMI_SET_BTCOEX_A2DP_CONFIG_CMDID, - WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID, - WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID, - WMI_SET_BTCOEX_DEBUG_CMDID, - WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID, - WMI_GET_BTCOEX_STATS_CMDID, - WMI_GET_BTCOEX_CONFIG_CMDID, + /* COEX CMDID AR6003*/ + WMI_SET_BTCOEX_FE_ANT_CMDID, + WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID, + WMI_SET_BTCOEX_SCO_CONFIG_CMDID, + WMI_SET_BTCOEX_A2DP_CONFIG_CMDID, + WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID, + WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID, + WMI_SET_BTCOEX_DEBUG_CMDID, + WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID, + WMI_GET_BTCOEX_STATS_CMDID, + WMI_GET_BTCOEX_CONFIG_CMDID, + WMI_GET_PMK_CMDID, + WMI_SET_PASSPHRASE_CMDID, + WMI_ENABLE_WAC_CMDID, + WMI_WAC_SCAN_REPLY_CMDID, + WMI_WAC_CTRL_REQ_CMDID, + WMI_SET_DIV_PARAMS_CMDID, + WMI_SET_EXCESS_TX_RETRY_THRES_CMDID, } WMI_COMMAND_ID; /* @@ -549,6 +556,13 @@ typedef PREPACK struct { u8 pmk[WMI_PMK_LEN]; } POSTPACK WMI_SET_PMK_CMD; +/* + * WMI_SET_EXCESS_TX_RETRY_THRES_CMDID + */ +typedef PREPACK struct { + A_UINT32 threshold; +} POSTPACK WMI_SET_EXCESS_TX_RETRY_THRES_CMD; + /* * WMI_ADD_CIPHER_KEY_CMDID */ diff --git a/drivers/staging/ath6kl/include/wmi_api.h b/drivers/staging/ath6kl/include/wmi_api.h index e51440ad7b7d..7ba85051a79f 100644 --- a/drivers/staging/ath6kl/include/wmi_api.h +++ b/drivers/staging/ath6kl/include/wmi_api.h @@ -421,6 +421,9 @@ wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE pre int wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk); +int +wmi_set_excess_tx_retry_thres_cmd(struct wmi_t *wmip, WMI_SET_EXCESS_TX_RETRY_THRES_CMD *cmd); + u16 wmi_ieee2freq (int chan); u32 wmi_freq2ieee (u16 freq); diff --git a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h index 383571a1ab3f..5a6c27e9aa5a 100644 --- a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h @@ -997,6 +997,7 @@ typedef enum { #define AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM 154 +#define AR6000_XIOCTL_WMI_SET_EXCESS_TX_RETRY_THRES 161 /* used by AR6000_IOCTL_WMI_GETREV */ struct ar6000_version { diff --git a/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h b/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h index 0652c69f591d..d172625afa18 100644 --- a/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h @@ -288,6 +288,13 @@ u8 xioctl_filter[] = { (0xFF), /* AR6000_XIOCTL_ADD_AP_INTERFACE 152 */ (0xFF), /* AR6000_XIOCTL_REMOVE_AP_INTERFACE 153 */ (0xFF), /* AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM 154 */ +(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_WPA_OFFLOAD_STATE 155 */ +(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_PASSPHRASE 156 */ +(0xFF), +(0xFF), +(0xFF), +(0xFF), +(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_EXCESS_TX_RETRY_THRES 161 */ }; #endif /*_WMI_FILTER_LINUX_H_*/ diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index 5be8ea335ee7..fe275c7ed32d 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -1329,6 +1329,28 @@ ar6000_xioctl_get_btcoex_stats_cmd(struct net_device * dev, char *userdata, stru return(ret); } +static int +ar6000_xioctl_set_excess_tx_retry_thres_cmd(struct net_device * dev, char * userdata) +{ + AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + WMI_SET_EXCESS_TX_RETRY_THRES_CMD cmd; + int ret = 0; + + if (ar->arWmiReady == false) { + return -EIO; + } + + if (copy_from_user(&cmd, userdata, sizeof(cmd))) { + return -EFAULT; + } + + if (wmi_set_excess_tx_retry_thres_cmd(ar->arWmi, &cmd) != 0) + { + ret = -EINVAL; + } + return(ret); +} + #ifdef CONFIG_HOST_GPIO_SUPPORT struct ar6000_gpio_intr_wait_cmd_s gpio_intr_results; /* gpio_reg_results and gpio_data_available are protected by arSem */ @@ -4660,6 +4682,12 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) #endif break; + case AR6000_XIOCTL_WMI_SET_EXCESS_TX_RETRY_THRES: + { + ret = ar6000_xioctl_set_excess_tx_retry_thres_cmd(dev, userdata); + break; + } + default: ret = -EOPNOTSUPP; } diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index 242e855f3085..acbf6ed3caf8 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -6609,6 +6609,27 @@ wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk) return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMK_CMDID, NO_SYNC_WMIFLAG)); } +int +wmi_set_excess_tx_retry_thres_cmd(struct wmi_t *wmip, WMI_SET_EXCESS_TX_RETRY_THRES_CMD *cmd) +{ + void *osbuf; + WMI_SET_EXCESS_TX_RETRY_THRES_CMD *p; + + osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_EXCESS_TX_RETRY_THRES_CMD)); + if (osbuf == NULL) { + return A_NO_MEMORY; + } + + A_NETBUF_PUT(osbuf, sizeof(WMI_SET_EXCESS_TX_RETRY_THRES_CMD)); + + p = (WMI_SET_EXCESS_TX_RETRY_THRES_CMD *)(A_NETBUF_DATA(osbuf)); + memset(p, 0, sizeof(*p)); + + p->threshold = cmd->threshold; + + return (wmi_cmd_send(wmip, osbuf, WMI_SET_EXCESS_TX_RETRY_THRES_CMDID, NO_SYNC_WMIFLAG)); +} + int wmi_SGI_cmd(struct wmi_t *wmip, u32 sgiMask, u8 sgiPERThreshold) { -- cgit v1.2.3 From 0ad7fdde6cfba9b0cf716bbd9549b05f195b8ebb Mon Sep 17 00:00:00 2001 From: Vipin Mehta Date: Fri, 18 Feb 2011 13:13:12 -0800 Subject: staging: ath6kl: Fixing memory leak The patch fixes a mismatch in the allocation and free of scatter HIF bus requests in the suspend/resume path. Signed-off-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index 4d6feeae2882..850472404ff4 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -1092,6 +1092,7 @@ static int hifDeviceSuspend(struct device *dev) device->is_suspend = false; } } + CleanupHIFScatterResources(device); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceSuspend\n")); switch (status) { -- cgit v1.2.3 From 9ea979d3b9e12e0f7f76153275e24c1d6cb389ab Mon Sep 17 00:00:00 2001 From: Vipin Mehta Date: Fri, 18 Feb 2011 13:13:13 -0800 Subject: staging: ath6kl: Fixing the cached copy of the BSS filter set by user Fixing the cached copy of the BSS filter set by user. Signed-off-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index fe275c7ed32d..6d15d2df8613 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -2590,7 +2590,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) != 0) { ret = -EIO; } else { - ar->arUserBssFilter = param; + ar->arUserBssFilter = filt.bssFilter; } } break; -- cgit v1.2.3 From 98b6d2381a2812eba27a4cec3e8242262b0e5f01 Mon Sep 17 00:00:00 2001 From: Vipin Mehta Date: Fri, 18 Feb 2011 13:13:14 -0800 Subject: staging: ath6kl: Adding state in driver to track the sme state Adding state in driver to track the sme state. The connect/disconnect events from the driver were messing up the state maintained within the cfg80211 module. Signed-off-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 1 + drivers/staging/ath6kl/os/linux/cfg80211.c | 28 +++++++++++++++------- .../staging/ath6kl/os/linux/include/ar6000_drv.h | 7 ++++++ 3 files changed, 28 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 93592af1d052..5dc5cf0c5b16 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -1670,6 +1670,7 @@ ar6000_avail_ev(void *context, void *hif_handle) SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy)); wdev->netdev = dev; ar->arNetworkType = INFRA_NETWORK; + ar->smeState = SME_DISCONNECTED; #endif /* ATH6K_CONFIG_CFG80211 */ init_netdev(dev, ifname); diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index 0f8f868c9a5a..8644d19f13e3 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -248,6 +248,7 @@ ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, int status; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); + ar->smeState = SME_CONNECTING; if(ar->arWmiReady == false) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready yet\n", __func__)); @@ -562,6 +563,7 @@ ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, u16 channel, if (false == ar->arConnected) { /* inform connect result to cfg80211 */ + ar->smeState = SME_DISCONNECTED; cfg80211_connect_result(ar->arNetDev, bssid, assocReqIe, assocReqLen, assocRespIe, assocRespLen, @@ -644,18 +646,28 @@ ar6k_cfg80211_disconnect_event(AR_SOFTC_T *ar, u8 reason, } } - if(false == ar->arConnected) { + if(true == ar->arConnectPending) { if(NO_NETWORK_AVAIL == reason) { /* connect cmd failed */ - cfg80211_connect_result(ar->arNetDev, bssid, - NULL, 0, - NULL, 0, - WLAN_STATUS_UNSPECIFIED_FAILURE, - GFP_KERNEL); + wmi_disconnect_cmd(ar->arWmi); + } else if (reason == DISCONNECT_CMD) { + /* connection loss due to disconnect cmd or low rssi */ + ar->arConnectPending = false; + if (ar->smeState == SME_CONNECTING) { + cfg80211_connect_result(ar->arNetDev, bssid, + NULL, 0, + NULL, 0, + WLAN_STATUS_UNSPECIFIED_FAILURE, + GFP_KERNEL); + } else { + cfg80211_disconnected(ar->arNetDev, reason, NULL, 0, GFP_KERNEL); + } + ar->smeState = SME_DISCONNECTED; } } else { - /* connection loss due to disconnect cmd or low rssi */ - cfg80211_disconnected(ar->arNetDev, reason, NULL, 0, GFP_KERNEL); + if (reason != DISCONNECT_CMD) { + wmi_disconnect_cmd(ar->arWmi); + } } } diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 339925a84d6e..f3b7344d6675 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -393,6 +393,12 @@ struct ar_key { u8 seq_len; u32 cipher; }; + +enum { + SME_DISCONNECTED, + SME_CONNECTING, + SME_CONNECTED +}; #endif /* ATH6K_CONFIG_CFG80211 */ @@ -595,6 +601,7 @@ typedef struct ar6_softc { struct wireless_dev *wdev; struct cfg80211_scan_request *scan_request; struct ar_key keys[WMI_MAX_KEY_INDEX + 1]; + u32 smeState; #endif /* ATH6K_CONFIG_CFG80211 */ u16 arWlanPowerState; bool arWlanOff; -- cgit v1.2.3 From 28f7e85a4b454e4882a91ea13dd17cdf5013168d Mon Sep 17 00:00:00 2001 From: Vipin Mehta Date: Fri, 18 Feb 2011 13:13:15 -0800 Subject: staging: ath6kl: Fixing accidental overwriting of probed ssid list in the hardware Fixing the code to avoid overwriting of the first index in the probed ssid list maintained by the hardware. This index is used to store broadcast SSID. Signed-off-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/cfg80211.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index 8644d19f13e3..20b08c089dfc 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -765,12 +765,12 @@ ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, request->ssids[0].ssid_len) { u8 i; - if(request->n_ssids > MAX_PROBED_SSID_INDEX) { - request->n_ssids = MAX_PROBED_SSID_INDEX; + if(request->n_ssids > (MAX_PROBED_SSID_INDEX - 1)) { + request->n_ssids = MAX_PROBED_SSID_INDEX - 1; } for (i = 0; i < request->n_ssids; i++) { - wmi_probedSsid_cmd(ar->arWmi, i, SPECIFIC_SSID_FLAG, + wmi_probedSsid_cmd(ar->arWmi, i+1, SPECIFIC_SSID_FLAG, request->ssids[i].ssid_len, request->ssids[i].ssid); } @@ -810,7 +810,7 @@ ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, int status) u8 i; for (i = 0; i < ar->scan_request->n_ssids; i++) { - wmi_probedSsid_cmd(ar->arWmi, i, DISABLE_SSID_FLAG, + wmi_probedSsid_cmd(ar->arWmi, i+1, DISABLE_SSID_FLAG, 0, NULL); } } -- cgit v1.2.3 From d0e0086893de668db30f31b8ba407199a0f693d0 Mon Sep 17 00:00:00 2001 From: Vipin Mehta Date: Fri, 18 Feb 2011 13:13:16 -0800 Subject: staging: ath6kl: Fixing disappearing of scan list due to jiffies wrap over When jiffies wrap-over, all the BSS in the cache is removed. Wrap-over of jiffies is not handled in the correct way. This cause the scan list to go empty during this time for a small duration Signed-off-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/include/osapi_linux.h | 2 +- drivers/staging/ath6kl/wlan/src/wlan_node.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h index eb09d43f44e9..1957de07b714 100644 --- a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h @@ -121,7 +121,7 @@ typedef spinlock_t A_MUTEX_T; /* Get current time in ms adding a constant offset (in ms) */ #define A_GET_MS(offset) \ - (jiffies + ((offset) / 1000) * HZ) + (((jiffies / HZ) * 1000) + (offset)) /* * Timer Functions diff --git a/drivers/staging/ath6kl/wlan/src/wlan_node.c b/drivers/staging/ath6kl/wlan/src/wlan_node.c index 996b36d01ccb..d61cb6ea894e 100644 --- a/drivers/staging/ath6kl/wlan/src/wlan_node.c +++ b/drivers/staging/ath6kl/wlan/src/wlan_node.c @@ -122,7 +122,7 @@ wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni, timeoutValue = nt->nt_nodeAge; - ni->ni_tstamp = A_GET_MS (timeoutValue); + ni->ni_tstamp = A_GET_MS (0); ni->ni_actcnt = WLAN_NODE_INACT_CNT; IEEE80211_NODE_LOCK_BH(nt); @@ -360,7 +360,7 @@ wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt) if (A_MEMCMP(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0) { - if (bss->ni_tstamp <= now || --bss->ni_actcnt == 0) + if (((now - bss->ni_tstamp) > timeoutValue) || --bss->ni_actcnt == 0) { /* * free up all but the current bss - if set @@ -381,6 +381,7 @@ wlan_node_timeout (A_ATH_TIMER arg) bss_t *bss, *nextBss; u8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = false; u32 timeoutValue = 0; + u32 now = A_GET_MS(0); timeoutValue = nt->nt_nodeAge; @@ -393,7 +394,7 @@ wlan_node_timeout (A_ATH_TIMER arg) if (A_MEMCMP(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0) { - if (bss->ni_tstamp <= A_GET_MS(0)) + if ((now - bss->ni_tstamp) > timeoutValue) { /* * free up all but the current bss - if set -- cgit v1.2.3 From 5ff6a1fd5c3ad2cae9626016cefa1d474571d618 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 10 Feb 2011 11:15:59 +0100 Subject: staging/trivial: fix typos concerning "access" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h | 2 +- drivers/staging/brcm80211/include/siutils.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h index 1b3ac0894d67..4d058b503aa7 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h @@ -735,7 +735,7 @@ struct wlc_info { u32 apsd_trigger_timeout; /* timeout value for apsd_trigger_timer (in ms) * 0 == disable */ - ac_bitmap_t apsd_trigger_ac; /* Permissible Acess Category in which APSD Null + ac_bitmap_t apsd_trigger_ac; /* Permissible Access Category in which APSD Null * Trigger frames can be send */ u8 htphy_membership; /* HT PHY membership */ diff --git a/drivers/staging/brcm80211/include/siutils.h b/drivers/staging/brcm80211/include/siutils.h index e681d40655b9..2932bf582785 100644 --- a/drivers/staging/brcm80211/include/siutils.h +++ b/drivers/staging/brcm80211/include/siutils.h @@ -271,7 +271,7 @@ typedef struct si_info { /* * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts - * before after core switching to avoid invalid register accesss inside ISR. + * before after core switching to avoid invalid register access inside ISR. */ #define INTR_OFF(si, intr_val) \ if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ -- cgit v1.2.3 From aec563b4f05a24c1d88db5aaf2d5047b6ae01663 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 10 Feb 2011 11:16:00 +0100 Subject: staging/trivial: fix typos concerning "address" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/pcicfg.h | 6 +++--- drivers/staging/brcm80211/include/sbhnddma.h | 2 +- drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/pcicfg.h b/drivers/staging/brcm80211/include/pcicfg.h index 3a19e1d243cf..6bd171e1079e 100644 --- a/drivers/staging/brcm80211/include/pcicfg.h +++ b/drivers/staging/brcm80211/include/pcicfg.h @@ -465,8 +465,8 @@ typedef struct _pcie_enhanced_caphdr { #define bar0_window dev_dep[0x80 - 0x40] #define bar1_window dev_dep[0x84 - 0x40] #define sprom_control dev_dep[0x88 - 0x40] -#define PCI_BAR0_WIN 0x80 /* backplane addres space accessed by BAR0 */ -#define PCI_BAR1_WIN 0x84 /* backplane addres space accessed by BAR1 */ +#define PCI_BAR0_WIN 0x80 /* backplane address space accessed by BAR0 */ +#define PCI_BAR1_WIN 0x84 /* backplane address space accessed by BAR1 */ #define PCI_SPROM_CONTROL 0x88 /* sprom property control */ #define PCI_BAR1_CONTROL 0x8c /* BAR1 region burst control */ #define PCI_INT_STATUS 0x90 /* PCI and other cores interrupts */ @@ -475,7 +475,7 @@ typedef struct _pcie_enhanced_caphdr { #define PCI_BACKPLANE_ADDR 0xa0 /* address an arbitrary location on the system backplane */ #define PCI_BACKPLANE_DATA 0xa4 /* data at the location specified by above address */ #define PCI_CLK_CTL_ST 0xa8 /* pci config space clock control/status (>=rev14) */ -#define PCI_BAR0_WIN2 0xac /* backplane addres space accessed by second 4KB of BAR0 */ +#define PCI_BAR0_WIN2 0xac /* backplane address space accessed by second 4KB of BAR0 */ #define PCI_GPIO_IN 0xb0 /* pci config space gpio input (>=rev3) */ #define PCI_GPIO_OUT 0xb4 /* pci config space gpio output (>=rev3) */ #define PCI_GPIO_OUTEN 0xb8 /* pci config space gpio output enable (>=rev3) */ diff --git a/drivers/staging/brcm80211/include/sbhnddma.h b/drivers/staging/brcm80211/include/sbhnddma.h index 183922136d75..08cb7f6e0d85 100644 --- a/drivers/staging/brcm80211/include/sbhnddma.h +++ b/drivers/staging/brcm80211/include/sbhnddma.h @@ -190,7 +190,7 @@ typedef volatile struct { } dma64dd_t; /* - * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss. + * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical address. */ #define D64RINGALIGN_BITS 13 #define D64MAXRINGSZ (1 << D64RINGALIGN_BITS) diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c index 5bc6811513df..ff691d9b984e 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c @@ -1940,7 +1940,7 @@ int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) } info->stats.tx_packets++; - // Add 14 bytes for MAC adddress plus ethernet type + // Add 14 bytes for MAC address plus ethernet type info->stats.tx_bytes += (len + 14); return SUCCESS; } -- cgit v1.2.3 From dca488b87efcae6f2b21ebe61922289b6093db2c Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 10 Feb 2011 11:16:01 +0100 Subject: staging/trivial: fix typos concerning "adjust" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lirc/lirc_parallel.c | 2 +- drivers/staging/spectra/flash.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lirc/lirc_parallel.c b/drivers/staging/lirc/lirc_parallel.c index 3a9c09881b2b..2f668a8a0c41 100644 --- a/drivers/staging/lirc/lirc_parallel.c +++ b/drivers/staging/lirc/lirc_parallel.c @@ -295,7 +295,7 @@ static void irq_handler(void *blah) } while (lirc_get_signal()); if (signal != 0) { - /* ajust value to usecs */ + /* adjust value to usecs */ __u64 helper; helper = ((__u64) signal)*1000000; diff --git a/drivers/staging/spectra/flash.c b/drivers/staging/spectra/flash.c index fb39c8ecf596..f11197b43f7f 100644 --- a/drivers/staging/spectra/flash.c +++ b/drivers/staging/spectra/flash.c @@ -3911,7 +3911,7 @@ int GLOB_FTL_Page_Write(u8 *pData, u64 dwPageAddr) * Description: erases the specified block * increments the erase count * If erase count reaches its upper limit,call function to -* do the ajustment as per the relative erase count values +* do the adjustment as per the relative erase count values *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ int GLOB_FTL_Block_Erase(u64 blk_addr) { -- cgit v1.2.3 From 9e36261d45989e13a2822d047687096f944cc9af Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 10 Feb 2011 11:16:02 +0100 Subject: staging/trivial: fix typos concerning "consistent" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/staging/cxt1e1/hwprobe.c | 2 +- drivers/staging/cxt1e1/pmcc4.h | 2 +- drivers/staging/cxt1e1/pmcc4_drv.c | 2 +- drivers/staging/tidspbridge/include/dspbridge/drv.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/cxt1e1/hwprobe.c b/drivers/staging/cxt1e1/hwprobe.c index c517cc22f391..de8ac0bc24fb 100644 --- a/drivers/staging/cxt1e1/hwprobe.c +++ b/drivers/staging/cxt1e1/hwprobe.c @@ -317,7 +317,7 @@ c4hw_attach_all (void) pr_warning("No boards found\n"); return ENODEV; } - /* sanity check for consistant hardware found */ + /* sanity check for consistent hardware found */ for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) { if (hi->pci_slot != 0xff && (!hi->addr[0] || !hi->addr[1])) diff --git a/drivers/staging/cxt1e1/pmcc4.h b/drivers/staging/cxt1e1/pmcc4.h index ef6ac7fe7ddd..e046b87763a2 100644 --- a/drivers/staging/cxt1e1/pmcc4.h +++ b/drivers/staging/cxt1e1/pmcc4.h @@ -31,7 +31,7 @@ * $Log: pmcc4.h,v $ * Revision 1.4 2005/11/01 19:24:48 rickd * Remove de-implement function prototypes. Several to - * changes for consistant usage of same. + * changes for consistent usage of same. * * Revision 1.3 2005/09/28 00:10:08 rickd * Add GNU license info. Use config params from libsbew.h diff --git a/drivers/staging/cxt1e1/pmcc4_drv.c b/drivers/staging/cxt1e1/pmcc4_drv.c index 341e7a92f099..e1f07fabd22d 100644 --- a/drivers/staging/cxt1e1/pmcc4_drv.c +++ b/drivers/staging/cxt1e1/pmcc4_drv.c @@ -44,7 +44,7 @@ * Code cleanup. Default channel config to HDLC_FCS16. * * Revision 2.7 2005/10/18 18:16:30 rickd - * Further NCOMM code repairs - (1) interrupt matrix usage inconsistant + * Further NCOMM code repairs - (1) interrupt matrix usage inconsistent * for indexing into nciInterrupt[][], code missing double parameters. * (2) check input of ncomm interrupt registration cardID for correct * boundary values. diff --git a/drivers/staging/tidspbridge/include/dspbridge/drv.h b/drivers/staging/tidspbridge/include/dspbridge/drv.h index bb044097323d..25ef1a2c58eb 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/drv.h +++ b/drivers/staging/tidspbridge/include/dspbridge/drv.h @@ -395,7 +395,7 @@ void bridge_recover_schedule(void); /* * ======== mem_ext_phys_pool_init ======== * Purpose: - * Uses the physical memory chunk passed for internal consitent memory + * Uses the physical memory chunk passed for internal consistent memory * allocations. * physical address based on the page frame address. * Parameters: -- cgit v1.2.3 From f0c0dda0767e3fa713b8c4a29369a65e4ae5e5c4 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 10 Feb 2011 11:16:03 +0100 Subject: staging/trivial: fix typos concerning "failed" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index fef08b60f6f0..ffba7461700a 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -2444,7 +2444,7 @@ static int __init dhd_module_init(void) error = wifi_add_dev(); if (error) { DHD_ERROR(("%s: platform_driver_register failed\n", __func__)); - goto faild; + goto failed; } /* Waiting callback after platform_driver_register is done or @@ -2454,7 +2454,7 @@ static int __init dhd_module_init(void) __func__); /* remove device */ wifi_del_dev(); - goto faild; + goto failed; } #endif /* #if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */ @@ -2462,11 +2462,11 @@ static int __init dhd_module_init(void) if (error) { DHD_ERROR(("%s: sdio_register_driver failed\n", __func__)); - goto faild; + goto failed; } return error; -faild: +failed: /* turn off power and exit */ dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF); return -EINVAL; -- cgit v1.2.3 From 1bf8240c0779b00f1be8b236e55302d666b089c8 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 10 Feb 2011 11:16:04 +0100 Subject: staging/trivial: fix typos concerning "function" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/staging/intel_sst/intel_sst_stream_encoded.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/intel_sst/intel_sst_stream_encoded.c b/drivers/staging/intel_sst/intel_sst_stream_encoded.c index 85789ba65186..29753c7519a7 100644 --- a/drivers/staging/intel_sst/intel_sst_stream_encoded.c +++ b/drivers/staging/intel_sst/intel_sst_stream_encoded.c @@ -171,7 +171,7 @@ int sst_set_stream_param(int str_id, struct snd_sst_params *str_param) } /** -* sst_get_vol - This fuction allows to get the premix gain or gain of a stream +* sst_get_vol - This function allows to get the premix gain or gain of a stream * * @get_vol: this is an output param through which the volume * structure is passed back to user @@ -221,7 +221,7 @@ int sst_get_vol(struct snd_sst_vol *get_vol) } /** -* sst_set_vol - This fuction allows to set the premix gain or gain of a stream +* sst_set_vol - This function allows to set the premix gain or gain of a stream * * @set_vol: this holds the volume structure that needs to be set * @@ -263,7 +263,7 @@ int sst_set_vol(struct snd_sst_vol *set_vol) } /** -* sst_set_mute - This fuction sets premix mute or soft mute of a stream +* sst_set_mute - This function sets premix mute or soft mute of a stream * * @set_mute: this holds the mute structure that needs to be set * @@ -450,7 +450,7 @@ err: } /** - * sst_target_device_select - This fuction sets the target device configurations + * sst_target_device_select - This function sets the target device configurations * * @target: this parameter holds the configurations to be set * -- cgit v1.2.3 From f9560042621fe0ce8bef3242f710662fac438104 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 10 Feb 2011 11:16:05 +0100 Subject: staging/trivial: fix typos concerning "implementation" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quatech_usb2/quatech_usb2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c index ed58f482c963..391a6331b9af 100644 --- a/drivers/staging/quatech_usb2/quatech_usb2.c +++ b/drivers/staging/quatech_usb2/quatech_usb2.c @@ -1221,7 +1221,7 @@ static void qt2_throttle(struct tty_struct *tty) } /* Send command to box to stop receiving stuff. This will stop this * particular UART from filling the endpoint - in the multiport case the - * FPGA UART will handle any flow control implmented, but for the single + * FPGA UART will handle any flow control implemented, but for the single * port it's handed differently and we just quit submitting urbs */ if (serial->dev->descriptor.idProduct != QUATECH_SSU2_100) -- cgit v1.2.3 From d9fed669ac4cb2ae5b1fad961c57f7ae1a5aa0be Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 10 Feb 2011 11:16:06 +0100 Subject: staging/trivial: fix typos concerning "initiali[zs]e" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 4 ++-- drivers/staging/intel_sst/intelmid_v0_control.c | 2 +- drivers/staging/intel_sst/intelmid_v1_control.c | 4 ++-- drivers/staging/intel_sst/intelmid_v2_control.c | 4 ++-- drivers/staging/westbridge/astoria/api/src/cyasdma.c | 2 +- drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdma.h | 2 +- .../staging/westbridge/astoria/include/linux/westbridge/cyasmisc.h | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index cb1a8026262d..91a2de218e77 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -554,7 +554,7 @@ void wlc_init(struct wlc_info *wlc) * Initialize WME parameters; if they haven't been set by some other * mechanism (IOVar, etc) then read them from the hardware. */ - if (WLC_WME_RETRY_SHORT_GET(wlc, 0) == 0) { /* Unintialized; read from HW */ + if (WLC_WME_RETRY_SHORT_GET(wlc, 0) == 0) { /* Uninitialized; read from HW */ int ac; ASSERT(wlc->clk); @@ -1660,7 +1660,7 @@ void wlc_info_init(struct wlc_info *wlc, int unit) wlc->ibss_coalesce_allowed = true; wlc->pub->_coex = ON; - /* intialize mpc delay */ + /* initialize mpc delay */ wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; wlc->pr80838_war = true; diff --git a/drivers/staging/intel_sst/intelmid_v0_control.c b/drivers/staging/intel_sst/intelmid_v0_control.c index 7859225e3d60..7756f8feaf85 100644 --- a/drivers/staging/intel_sst/intelmid_v0_control.c +++ b/drivers/staging/intel_sst/intelmid_v0_control.c @@ -68,7 +68,7 @@ int rev_id = 0x20; /**** * fs_init_card - initialize the sound card * - * This initilizes the audio paths to know values in case of this sound card + * This initializes the audio paths to know values in case of this sound card */ static int fs_init_card(void) { diff --git a/drivers/staging/intel_sst/intelmid_v1_control.c b/drivers/staging/intel_sst/intelmid_v1_control.c index 478cfecdefd7..9cc15c1c18d4 100644 --- a/drivers/staging/intel_sst/intelmid_v1_control.c +++ b/drivers/staging/intel_sst/intelmid_v1_control.c @@ -72,9 +72,9 @@ enum _reg_v2 { }; /** - * mx_init_card - initilize the sound card + * mx_init_card - initialize the sound card * - * This initilizes the audio paths to know values in case of this sound card + * This initializes the audio paths to know values in case of this sound card */ static int mx_init_card(void) { diff --git a/drivers/staging/intel_sst/intelmid_v2_control.c b/drivers/staging/intel_sst/intelmid_v2_control.c index e2f6d6a3c850..26d815a67eb8 100644 --- a/drivers/staging/intel_sst/intelmid_v2_control.c +++ b/drivers/staging/intel_sst/intelmid_v2_control.c @@ -84,9 +84,9 @@ enum reg_v3 { }; /**** - * nc_init_card - initilize the sound card + * nc_init_card - initialize the sound card * - * This initilizes the audio paths to know values in case of this sound card + * This initializes the audio paths to know values in case of this sound card */ static int nc_init_card(void) { diff --git a/drivers/staging/westbridge/astoria/api/src/cyasdma.c b/drivers/staging/westbridge/astoria/api/src/cyasdma.c index de67e1310503..16b8ec124510 100644 --- a/drivers/staging/westbridge/astoria/api/src/cyasdma.c +++ b/drivers/staging/westbridge/astoria/api/src/cyasdma.c @@ -653,7 +653,7 @@ cy_as_dma_stop(cy_as_device *dev_p) /* * CyAsDmaStart() * - * This function intializes the DMA module to insure it is up and running. + * This function initializes the DMA module to insure it is up and running. */ cy_as_return_status_t cy_as_dma_start(cy_as_device *dev_p) diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdma.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdma.h index 6efb8b80ffb7..8dab5e900149 100644 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdma.h +++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdma.h @@ -35,7 +35,7 @@ at some future time. The DMA module must be started before it can be used. It is - started by calling CyAsDmaStart(). This function intializes + started by calling CyAsDmaStart(). This function initializes all of the endpoint data structures. In order to perform DMA on a particular endpoint, the endpoint diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc.h index b555c6c24524..2f0701850561 100644 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc.h +++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc.h @@ -550,7 +550,7 @@ cy_as_misc_destroy_device( West Bridge. Description - This function intializes the hardware to establish basic + This function initializes the hardware to establish basic communication with the West Bridge device. This is always the first function called to initialize communication with the West Bridge device. -- cgit v1.2.3 From 8c209fe9b0eb0bf0db09f55d83c101fc06bce152 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 10 Feb 2011 11:16:07 +0100 Subject: staging/trivial: fix typos concerning "management" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/pcicfg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/pcicfg.h b/drivers/staging/brcm80211/include/pcicfg.h index 6bd171e1079e..675554a1d341 100644 --- a/drivers/staging/brcm80211/include/pcicfg.h +++ b/drivers/staging/brcm80211/include/pcicfg.h @@ -388,7 +388,7 @@ typedef struct _pciconfig_cap_msi { u32 msgaddr; } pciconfig_cap_msi; -/* Data structure to define the Power managment facility +/* Data structure to define the Power management facility * Valid for PCI and PCIE configurations */ typedef struct _pciconfig_cap_pwrmgmt { -- cgit v1.2.3 From ecc73a99e4fe593e03b0d45f6121e952fc928eef Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 10 Feb 2011 11:16:08 +0100 Subject: staging/trivial: fix typos concerning "memory" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/staging/westbridge/astoria/device/cyasdevice.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/westbridge/astoria/device/cyasdevice.c b/drivers/staging/westbridge/astoria/device/cyasdevice.c index 5ca3d41a932d..7de35ccffd32 100644 --- a/drivers/staging/westbridge/astoria/device/cyasdevice.c +++ b/drivers/staging/westbridge/astoria/device/cyasdevice.c @@ -214,7 +214,7 @@ static int cyasdevice_initialize(void) cy_as_dev = cy_as_hal_alloc(sizeof(cyasdevice)); if (cy_as_dev == NULL) { cy_as_hal_print_message("<1>_cy_as_device: " - "memmory allocation failed\n"); + "memory allocation failed\n"); return -ENOMEM; } memset(cy_as_dev, 0, sizeof(cyasdevice)); -- cgit v1.2.3 From 3173a5ecd8c4a1409d5af036977f326de2bee05d Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 10 Feb 2011 11:16:09 +0100 Subject: staging/trivial: fix typos concerning "select" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/staging/intel_sst/intelmid.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/intel_sst/intelmid.h b/drivers/staging/intel_sst/intelmid.h index 0ce103185848..ca881b790cb2 100644 --- a/drivers/staging/intel_sst/intelmid.h +++ b/drivers/staging/intel_sst/intelmid.h @@ -94,8 +94,8 @@ struct mad_jack_msg_wq { * @irq: interrupt number detected * @pmic_status: Device status of sound card * @int_base: ptr to MMIO interrupt region - * @output_sel: device slected as o/p - * @input_sel: device slected as i/p + * @output_sel: device selected as o/p + * @input_sel: device selected as i/p * @master_mute: master mute status * @jack: jack status * @playback_cnt: active pb streams -- cgit v1.2.3 From 00781a74ee34222ee3cdc36d4f3d9c844dddbd27 Mon Sep 17 00:00:00 2001 From: Xose Vazquez Perez Date: Fri, 18 Feb 2011 14:27:09 +0100 Subject: wireless: rt2x00: rt2800pci.c: add two ids taken two RT35XX EDIMAX from DPO_RT3562_3592_3062_LinuxSTA_V2.4.1.1_20101217 Signed-off-by: Xose Vazquez Perez Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index aa97971a38af..7951cdaa9c01 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -1065,6 +1065,8 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { { PCI_DEVICE(0x1814, 0x3390), PCI_DEVICE_DATA(&rt2800pci_ops) }, #endif #ifdef CONFIG_RT2800PCI_RT35XX + { PCI_DEVICE(0x1432, 0x7711), PCI_DEVICE_DATA(&rt2800pci_ops) }, + { PCI_DEVICE(0x1432, 0x7722), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) }, -- cgit v1.2.3 From 28bec7b845e10b68e6ba1ade5de0fc566690fc61 Mon Sep 17 00:00:00 2001 From: Nikolay Ledovskikh Date: Fri, 18 Feb 2011 19:59:53 +0300 Subject: ath5k: Correct channel setting for AR2317 chip Correct channel setting function must be used for AR2317. When I tested ahb patch on bullet2 all seemed to work fine, but it couldn't connect another host (using ibss for example). During an analysis I observed that it's transmitting on another channel. I looked into madwifi code and understood that the problem is in channel setting function. So atheros RF2317 not fully handled in the current ath5k version and must be patched. Signed-off-by: Nikolay Ledovskikh Acked-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 78c26fdccad1..c44111fc98b7 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1253,6 +1253,7 @@ static int ath5k_hw_channel(struct ath5k_hw *ah, case AR5K_RF5111: ret = ath5k_hw_rf5111_channel(ah, channel); break; + case AR5K_RF2317: case AR5K_RF2425: ret = ath5k_hw_rf2425_channel(ah, channel); break; -- cgit v1.2.3 From 8c68bd401d423c81fd4bfc19c625180528e4a5e8 Mon Sep 17 00:00:00 2001 From: Michael Büsch Date: Tue, 15 Feb 2011 00:21:50 +0100 Subject: ssb: Make ssb_wait_bit multi-bit safe ssb_wait_bit was designed for only one-bit bitmasks. People start using it for multi-bit bitmasks. Make the "set" case is safe for this. The "unset" case is already safe. This does not change behavior of the current code. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/ssb/main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 3918d2cc5856..775c579817b4 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -1192,10 +1192,10 @@ void ssb_device_enable(struct ssb_device *dev, u32 core_specific_flags) } EXPORT_SYMBOL(ssb_device_enable); -/* Wait for a bit in a register to get set or unset. +/* Wait for bitmask in a register to get set or cleared. * timeout is in units of ten-microseconds */ -static int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask, - int timeout, int set) +static int ssb_wait_bits(struct ssb_device *dev, u16 reg, u32 bitmask, + int timeout, int set) { int i; u32 val; @@ -1203,7 +1203,7 @@ static int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask, for (i = 0; i < timeout; i++) { val = ssb_read32(dev, reg); if (set) { - if (val & bitmask) + if ((val & bitmask) == bitmask) return 0; } else { if (!(val & bitmask)) @@ -1227,8 +1227,8 @@ void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags) reject = ssb_tmslow_reject_bitmask(dev); ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK); - ssb_wait_bit(dev, SSB_TMSLOW, reject, 1000, 1); - ssb_wait_bit(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0); + ssb_wait_bits(dev, SSB_TMSLOW, reject, 1000, 1); + ssb_wait_bits(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0); ssb_write32(dev, SSB_TMSLOW, SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | reject | SSB_TMSLOW_RESET | -- cgit v1.2.3 From 12873372fe1f201813f1cc750a8af7d9193f445c Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Tue, 15 Feb 2011 09:19:28 -0500 Subject: ath5k: move external function definitions to a header file Johannes pointed out the mess of external function prototypes in the mac80211-ops.c file. Woe to anyone who changes these functions... Signed-off-by: Bob Copeland Cc: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 20 ++++++++++++++++++++ drivers/net/wireless/ath/ath5k/mac80211-ops.c | 17 ----------------- 2 files changed, 20 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index e43175a89d67..70abb61e9eff 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1158,6 +1158,26 @@ void ath5k_hw_deinit(struct ath5k_hw *ah); int ath5k_sysfs_register(struct ath5k_softc *sc); void ath5k_sysfs_unregister(struct ath5k_softc *sc); +/* base.c */ +struct ath5k_buf; +struct ath5k_txq; + +void set_beacon_filter(struct ieee80211_hw *hw, bool enable); +bool ath_any_vif_assoc(struct ath5k_softc *sc); +int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, + struct ath5k_txq *txq); +int ath5k_init_hw(struct ath5k_softc *sc); +int ath5k_stop_hw(struct ath5k_softc *sc); +void ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif); +void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, + struct ieee80211_vif *vif); +int ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan); +void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); +int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +void ath5k_beacon_config(struct ath5k_softc *sc); +void ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf); +void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf); + /*Chip id helper functions */ const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val); int ath5k_hw_read_srev(struct ath5k_hw *ah); diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 36a51995a7bc..a60a726a140c 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -48,23 +48,6 @@ extern int ath5k_modparam_nohwcrypt; -/* functions used from base.c */ -void set_beacon_filter(struct ieee80211_hw *hw, bool enable); -bool ath_any_vif_assoc(struct ath5k_softc *sc); -int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, - struct ath5k_txq *txq); -int ath5k_init_hw(struct ath5k_softc *sc); -int ath5k_stop_hw(struct ath5k_softc *sc); -void ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif); -void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, - struct ieee80211_vif *vif); -int ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan); -void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); -int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif); -void ath5k_beacon_config(struct ath5k_softc *sc); -void ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf); -void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf); - /********************\ * Mac80211 functions * \********************/ -- cgit v1.2.3 From fe0b7c616ebd7d25afbb4315d0e3220b112a7b2f Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 15 Feb 2011 09:37:06 -0600 Subject: p54: Fix compile warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If any of the p54-based drivers are built with CONFIG_P54_LEDS not defined, the following warning is generated: CC [M] drivers/net/wireless/p54/main.o drivers/net/wireless/p54/main.c: In function ‘p54_register_common’: drivers/net/wireless/p54/main.c:614:21: warning: unused variable ‘priv’ Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/p54/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index 0a78e666e2d1..338e8dcac1f3 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c @@ -611,7 +611,7 @@ EXPORT_SYMBOL_GPL(p54_init_common); int p54_register_common(struct ieee80211_hw *dev, struct device *pdev) { - struct p54_common *priv = dev->priv; + struct p54_common __maybe_unused *priv = dev->priv; int err; err = ieee80211_register_hw(dev); -- cgit v1.2.3 From 9bf8ab35f269d66e507de2b1ccc67a02d8284db5 Mon Sep 17 00:00:00 2001 From: Henry Ptasinski Date: Thu, 17 Feb 2011 21:29:01 -0800 Subject: wireless-next-2.6: brcm80211: fix compile issue Commit 59eb21a65047 "cfg80211: Extend channel to frequency mapping for 802.11j" changed the definition of the ieee80211_channel_to_frequency; so fix its usage in brcmfmac. Signed-off-by: Stanislav Fomichev Reviewed-by: Henry Ptasinski Signed-off-by: John W. Linville --- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 991463f4a7f4..9b7b71c294b8 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -2313,7 +2313,9 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt, u.beacon.variable) + wl_get_ielen(wl); - freq = ieee80211_channel_to_frequency(notif_bss_info->channel); + freq = ieee80211_channel_to_frequency(notif_bss_info->channel, + band->band); + channel = ieee80211_get_channel(wiphy, freq); WL_DBG("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n", -- cgit v1.2.3 From 98605c2ed4963c44aa72799e697ae4bc7085ffcd Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 16 Feb 2011 13:58:25 +0100 Subject: ssb: trivial: fix SPROM extract warning formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/ssb/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 5b33b3b06f7f..a467b20baac8 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -645,7 +645,7 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, break; default: ssb_printk(KERN_WARNING PFX "Unsupported SPROM" - " revision %d detected. Will extract" + " revision %d detected. Will extract" " v1\n", out->revision); out->revision = 1; sprom_extract_r123(out, in); -- cgit v1.2.3 From 0d4171e2153b70957fe67867420a1a24d5e4cd82 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Wed, 16 Feb 2011 19:43:06 +0100 Subject: p54: implement flush callback Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/main.c | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index 338e8dcac1f3..e14a05bbc485 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c @@ -524,6 +524,48 @@ static int p54_get_survey(struct ieee80211_hw *dev, int idx, return 0; } +static unsigned int p54_flush_count(struct p54_common *priv) +{ + unsigned int total = 0, i; + + BUILD_BUG_ON(P54_QUEUE_NUM > ARRAY_SIZE(priv->tx_stats)); + + /* + * Because the firmware has the sole control over any frames + * in the P54_QUEUE_BEACON or P54_QUEUE_SCAN queues, they + * don't really count as pending or active. + */ + for (i = P54_QUEUE_MGMT; i < P54_QUEUE_NUM; i++) + total += priv->tx_stats[i].len; + return total; +} + +static void p54_flush(struct ieee80211_hw *dev, bool drop) +{ + struct p54_common *priv = dev->priv; + unsigned int total, i; + + /* + * Currently, it wouldn't really matter if we wait for one second + * or 15 minutes. But once someone gets around and completes the + * TODOs [ancel stuck frames / reset device] in p54_work, it will + * suddenly make sense to wait that long. + */ + i = P54_STATISTICS_UPDATE * 2 / 20; + + /* + * In this case no locking is required because as we speak the + * queues have already been stopped and no new frames can sneak + * up from behind. + */ + while ((total = p54_flush_count(priv) && i--)) { + /* waste time */ + msleep(20); + } + + WARN(total, "tx flush timeout, unresponsive firmware"); +} + static const struct ieee80211_ops p54_ops = { .tx = p54_tx_80211, .start = p54_start, @@ -536,6 +578,7 @@ static const struct ieee80211_ops p54_ops = { .sta_remove = p54_sta_add_remove, .set_key = p54_set_key, .config = p54_config, + .flush = p54_flush, .bss_info_changed = p54_bss_info_changed, .configure_filter = p54_configure_filter, .conf_tx = p54_conf_tx, -- cgit v1.2.3 From b1a1bcf714c4d79f7872a34138d100941ebb0a0b Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 17 Feb 2011 01:50:50 +0100 Subject: ssb: when needed, reject IM input while disabling device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/ssb/main.c | 16 +++++++++++++++- include/linux/ssb/ssb_regs.h | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 775c579817b4..06c0b6d5250d 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -1220,7 +1220,7 @@ static int ssb_wait_bits(struct ssb_device *dev, u16 reg, u32 bitmask, void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags) { - u32 reject; + u32 reject, val; if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_RESET) return; @@ -1229,12 +1229,26 @@ void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags) ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK); ssb_wait_bits(dev, SSB_TMSLOW, reject, 1000, 1); ssb_wait_bits(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0); + + if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) { + val = ssb_read32(dev, SSB_IMSTATE); + val |= SSB_IMSTATE_REJECT; + ssb_write32(dev, SSB_IMSTATE, val); + ssb_wait_bits(dev, SSB_IMSTATE, SSB_IMSTATE_BUSY, 1000, 0); + } + ssb_write32(dev, SSB_TMSLOW, SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | reject | SSB_TMSLOW_RESET | core_specific_flags); ssb_flush_tmslow(dev); + if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) { + val = ssb_read32(dev, SSB_IMSTATE); + val &= ~SSB_IMSTATE_REJECT; + ssb_write32(dev, SSB_IMSTATE, val); + } + ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_RESET | core_specific_flags); diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h index 9b1125bea1fc..402955ae48ce 100644 --- a/include/linux/ssb/ssb_regs.h +++ b/include/linux/ssb/ssb_regs.h @@ -85,6 +85,8 @@ #define SSB_IMSTATE_AP_RSV 0x00000030 /* Reserved */ #define SSB_IMSTATE_IBE 0x00020000 /* In Band Error */ #define SSB_IMSTATE_TO 0x00040000 /* Timeout */ +#define SSB_IMSTATE_BUSY 0x01800000 /* Busy (Backplane rev >= 2.3 only) */ +#define SSB_IMSTATE_REJECT 0x02000000 /* Reject (Backplane rev >= 2.3 only) */ #define SSB_INTVEC 0x0F94 /* SB Interrupt Mask */ #define SSB_INTVEC_PCI 0x00000001 /* Enable interrupts for PCI */ #define SSB_INTVEC_ENET0 0x00000002 /* Enable interrupts for enet 0 */ -- cgit v1.2.3 From 011d18350f525dfdb1ccbd52019e8c04cadcc222 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 17 Feb 2011 01:50:51 +0100 Subject: ssb: reset device only if it was enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/ssb/main.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 06c0b6d5250d..e05ba6eefc7e 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -1226,27 +1226,31 @@ void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags) return; reject = ssb_tmslow_reject_bitmask(dev); - ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK); - ssb_wait_bits(dev, SSB_TMSLOW, reject, 1000, 1); - ssb_wait_bits(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0); - if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) { - val = ssb_read32(dev, SSB_IMSTATE); - val |= SSB_IMSTATE_REJECT; - ssb_write32(dev, SSB_IMSTATE, val); - ssb_wait_bits(dev, SSB_IMSTATE, SSB_IMSTATE_BUSY, 1000, 0); - } + if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_CLOCK) { + ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK); + ssb_wait_bits(dev, SSB_TMSLOW, reject, 1000, 1); + ssb_wait_bits(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0); + + if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) { + val = ssb_read32(dev, SSB_IMSTATE); + val |= SSB_IMSTATE_REJECT; + ssb_write32(dev, SSB_IMSTATE, val); + ssb_wait_bits(dev, SSB_IMSTATE, SSB_IMSTATE_BUSY, 1000, + 0); + } - ssb_write32(dev, SSB_TMSLOW, - SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | - reject | SSB_TMSLOW_RESET | - core_specific_flags); - ssb_flush_tmslow(dev); + ssb_write32(dev, SSB_TMSLOW, + SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | + reject | SSB_TMSLOW_RESET | + core_specific_flags); + ssb_flush_tmslow(dev); - if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) { - val = ssb_read32(dev, SSB_IMSTATE); - val &= ~SSB_IMSTATE_REJECT; - ssb_write32(dev, SSB_IMSTATE, val); + if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) { + val = ssb_read32(dev, SSB_IMSTATE); + val &= ~SSB_IMSTATE_REJECT; + ssb_write32(dev, SSB_IMSTATE, val); + } } ssb_write32(dev, SSB_TMSLOW, -- cgit v1.2.3 From 8354dd3ebc7f0b82f52990af3e5f4f4488020263 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Fri, 18 Feb 2011 16:09:51 +0530 Subject: ath9k_htc: Fix a compilation warning. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initialize caldata to avoid compilation warning. CC [M] drivers/net/wireless/ath/ath9k/htc_drv_main.o drivers/net/wireless/ath/ath9k/htc_drv_main.c: In function ‘ath9k_htc_config’: drivers/net/wireless/ath/ath9k/htc_drv_main.c:172: warning: ‘caldata’ may be used uninitialized in this function drivers/net/wireless/ath/ath9k/htc_drv_main.c:172: note: ‘caldata’ was declared here Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 953036a4ed53..50fde0e10595 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -169,7 +169,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, struct ieee80211_conf *conf = &common->hw->conf; bool fastcc; struct ieee80211_channel *channel = hw->conf.channel; - struct ath9k_hw_cal_data *caldata; + struct ath9k_hw_cal_data *caldata = NULL; enum htc_phymode mode; __be16 htc_mode; u8 cmd_rsp; -- cgit v1.2.3 From 1a63e2ce4e67f6df74f032ec302314141816e432 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Fri, 18 Feb 2011 16:49:47 +0530 Subject: ath9k_hw: Updates for AR9485 1.1 chipsets. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 112 ++- drivers/net/wireless/ath/ath9k/ar9485_initvals.h | 1141 ++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/reg.h | 4 + 3 files changed, 1246 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 06fb2c850535..6fa3c24af2da 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -28,7 +28,67 @@ */ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) { - if (AR_SREV_9485(ah)) { + if (AR_SREV_9485_11(ah)) { + /* mac */ + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], + ar9485_1_1_mac_core, + ARRAY_SIZE(ar9485_1_1_mac_core), 2); + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], + ar9485_1_1_mac_postamble, + ARRAY_SIZE(ar9485_1_1_mac_postamble), 5); + + /* bb */ + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_1, + ARRAY_SIZE(ar9485_1_1), 2); + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], + ar9485_1_1_baseband_core, + ARRAY_SIZE(ar9485_1_1_baseband_core), 2); + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], + ar9485_1_1_baseband_postamble, + ARRAY_SIZE(ar9485_1_1_baseband_postamble), 5); + + /* radio */ + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], + ar9485_1_1_radio_core, + ARRAY_SIZE(ar9485_1_1_radio_core), 2); + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], + ar9485_1_1_radio_postamble, + ARRAY_SIZE(ar9485_1_1_radio_postamble), 2); + + /* soc */ + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], + ar9485_1_1_soc_preamble, + ARRAY_SIZE(ar9485_1_1_soc_preamble), 2); + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0); + + /* rx/tx gain */ + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9485_common_rx_gain_1_1, + ARRAY_SIZE(ar9485_common_rx_gain_1_1), 2); + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9485_modes_lowest_ob_db_tx_gain_1_1, + ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), + 5); + + /* Load PCIE SERDES settings from INI */ + + /* Awake Setting */ + + INIT_INI_ARRAY(&ah->iniPcieSerdes, + ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1, + ARRAY_SIZE(ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1), + 2); + + /* Sleep Setting */ + + INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, + ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1, + ARRAY_SIZE(ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1), + 2); + } else if (AR_SREV_9485(ah)) { /* mac */ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], @@ -85,8 +145,8 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) /* Sleep Setting */ INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, - ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1, - ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1), + ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1, + ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1), 2); } else { /* mac */ @@ -163,7 +223,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) switch (ar9003_hw_get_tx_gain_idx(ah)) { case 0: default: - if (AR_SREV_9485(ah)) + if (AR_SREV_9485_11(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9485_modes_lowest_ob_db_tx_gain_1_1, + ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), + 5); + else if (AR_SREV_9485(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9485Modes_lowest_ob_db_tx_gain_1_0, ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0), @@ -175,10 +240,15 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) 5); break; case 1: - if (AR_SREV_9485(ah)) + if (AR_SREV_9485_11(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9485Modes_high_ob_db_tx_gain_1_1, + ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1), + 5); + else if (AR_SREV_9485(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9485Modes_high_ob_db_tx_gain_1_0, - ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0), + ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_0), 5); else INIT_INI_ARRAY(&ah->iniModesTxGain, @@ -187,10 +257,15 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) 5); break; case 2: - if (AR_SREV_9485(ah)) + if (AR_SREV_9485_11(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9485Modes_low_ob_db_tx_gain_1_1, + ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1), + 5); + else if (AR_SREV_9485(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9485Modes_low_ob_db_tx_gain_1_0, - ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0), + ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_0), 5); else INIT_INI_ARRAY(&ah->iniModesTxGain, @@ -199,7 +274,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) 5); break; case 3: - if (AR_SREV_9485(ah)) + if (AR_SREV_9485_11(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9485Modes_high_power_tx_gain_1_1, + ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1), + 5); + else if (AR_SREV_9485(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9485Modes_high_power_tx_gain_1_0, ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_0), @@ -218,7 +298,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) switch (ar9003_hw_get_rx_gain_idx(ah)) { case 0: default: - if (AR_SREV_9485(ah)) + if (AR_SREV_9485_11(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9485_common_rx_gain_1_1, + ARRAY_SIZE(ar9485_common_rx_gain_1_1), + 2); + else if (AR_SREV_9485(ah)) INIT_INI_ARRAY(&ah->iniModesRxGain, ar9485Common_rx_gain_1_0, ARRAY_SIZE(ar9485Common_rx_gain_1_0), @@ -230,7 +315,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) 2); break; case 1: - if (AR_SREV_9485(ah)) + if (AR_SREV_9485_11(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9485Common_wo_xlna_rx_gain_1_1, + ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), + 2); + else if (AR_SREV_9485(ah)) INIT_INI_ARRAY(&ah->iniModesRxGain, ar9485Common_wo_xlna_rx_gain_1_0, ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_0), diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index 70de3d89a7b5..eac4d8526fc1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h @@ -940,4 +940,1145 @@ static const u32 ar9485_1_0_mac_core[][2] = { {0x000083cc, 0x00000200}, {0x000083d0, 0x000301ff}, }; + +static const u32 ar9485_1_1_mac_core[][2] = { + /* Addr allmodes */ + {0x00000008, 0x00000000}, + {0x00000030, 0x00020085}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000000}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x000010f0, 0x00000100}, + {0x00001270, 0x00000000}, + {0x000012b0, 0x00000000}, + {0x000012f0, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00008000, 0x00000000}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000000}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00000000}, + {0x00008040, 0x00000000}, + {0x00008044, 0x00000000}, + {0x00008048, 0x00000000}, + {0x0000804c, 0xffffffff}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x00008070, 0x00000310}, + {0x00008074, 0x00000020}, + {0x00008078, 0x00000000}, + {0x0000809c, 0x0000000f}, + {0x000080a0, 0x00000000}, + {0x000080a4, 0x02ff0000}, + {0x000080a8, 0x0e070605}, + {0x000080ac, 0x0000000d}, + {0x000080b0, 0x00000000}, + {0x000080b4, 0x00000000}, + {0x000080b8, 0x00000000}, + {0x000080bc, 0x00000000}, + {0x000080c0, 0x2a800000}, + {0x000080c4, 0x06900168}, + {0x000080c8, 0x13881c22}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00252500}, + {0x000080d4, 0x00a00000}, + {0x000080d8, 0x00400000}, + {0x000080dc, 0x00000000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x3f3f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00000000}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000000}, + {0x00008114, 0x000007ff}, + {0x00008118, 0x000000aa}, + {0x0000811c, 0x00003210}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x0000ffff}, + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x18486200}, + {0x00008174, 0x33332210}, + {0x00008178, 0x00000000}, + {0x0000817c, 0x00020000}, + {0x000081c0, 0x00000000}, + {0x000081c4, 0x33332210}, + {0x000081d4, 0x00000000}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008244, 0x0010f400}, + {0x00008248, 0x00000800}, + {0x0000824c, 0x0001e800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x40000000}, + {0x00008260, 0x00080922}, + {0x00008264, 0x9ca00010}, + {0x00008268, 0xffffffff}, + {0x0000826c, 0x0000ffff}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000004}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x000000ff}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x0000829c, 0x00000000}, + {0x00008300, 0x00000140}, + {0x00008314, 0x00000000}, + {0x0000831c, 0x0000010d}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x00000007}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000700}, + {0x00008338, 0x00ff0000}, + {0x0000833c, 0x02400000}, + {0x00008340, 0x000107ff}, + {0x00008344, 0xa248105b}, + {0x00008348, 0x008f0000}, + {0x0000835c, 0x00000000}, + {0x00008360, 0xffffffff}, + {0x00008364, 0xffffffff}, + {0x00008368, 0x00000000}, + {0x00008370, 0x00000000}, + {0x00008374, 0x000000ff}, + {0x00008378, 0x00000000}, + {0x0000837c, 0x00000000}, + {0x00008380, 0xffffffff}, + {0x00008384, 0xffffffff}, + {0x00008390, 0xffffffff}, + {0x00008394, 0xffffffff}, + {0x00008398, 0x00000000}, + {0x0000839c, 0x00000000}, + {0x000083a0, 0x00000000}, + {0x000083a4, 0x0000fa14}, + {0x000083a8, 0x000f0c00}, + {0x000083ac, 0x33332210}, + {0x000083b0, 0x33332210}, + {0x000083b4, 0x33332210}, + {0x000083b8, 0x33332210}, + {0x000083bc, 0x00000000}, + {0x000083c0, 0x00000000}, + {0x000083c4, 0x00000000}, + {0x000083c8, 0x00000000}, + {0x000083cc, 0x00000200}, + {0x000083d0, 0x000301ff}, +}; + +static const u32 ar9485_1_1_baseband_core[][2] = { + /* Addr allmodes */ + {0x00009800, 0xafe68e30}, + {0x00009804, 0xfd14e000}, + {0x00009808, 0x9c0a8f6b}, + {0x0000980c, 0x04800000}, + {0x00009814, 0x9280c00a}, + {0x00009818, 0x00000000}, + {0x0000981c, 0x00020028}, + {0x00009834, 0x5f3ca3de}, + {0x00009838, 0x0108ecff}, + {0x0000983c, 0x14750600}, + {0x00009880, 0x201fff00}, + {0x00009884, 0x00001042}, + {0x000098a4, 0x00200400}, + {0x000098b0, 0x52440bbe}, + {0x000098d0, 0x004b6a8e}, + {0x000098d4, 0x00000820}, + {0x000098dc, 0x00000000}, + {0x000098f0, 0x00000000}, + {0x000098f4, 0x00000000}, + {0x00009c04, 0x00000000}, + {0x00009c08, 0x03200000}, + {0x00009c0c, 0x00000000}, + {0x00009c10, 0x00000000}, + {0x00009c14, 0x00046384}, + {0x00009c18, 0x05b6b440}, + {0x00009c1c, 0x00b6b440}, + {0x00009d00, 0xc080a333}, + {0x00009d04, 0x40206c10}, + {0x00009d08, 0x009c4060}, + {0x00009d0c, 0x1883800a}, + {0x00009d10, 0x01834061}, + {0x00009d14, 0x00c00400}, + {0x00009d18, 0x00000000}, + {0x00009d1c, 0x00000000}, + {0x00009e08, 0x0038233c}, + {0x00009e24, 0x9927b515}, + {0x00009e28, 0x12ef0200}, + {0x00009e30, 0x06336f77}, + {0x00009e34, 0x6af6532f}, + {0x00009e38, 0x0cc80c00}, + {0x00009e40, 0x0d261820}, + {0x00009e4c, 0x00001004}, + {0x00009e50, 0x00ff03f1}, + {0x00009fc0, 0x80be4788}, + {0x00009fc4, 0x0001efb5}, + {0x00009fcc, 0x40000014}, + {0x0000a20c, 0x00000000}, + {0x0000a210, 0x00000000}, + {0x0000a220, 0x00000000}, + {0x0000a224, 0x00000000}, + {0x0000a228, 0x10002310}, + {0x0000a23c, 0x00000000}, + {0x0000a244, 0x0c000000}, + {0x0000a2a0, 0x00000001}, + {0x0000a2c0, 0x00000001}, + {0x0000a2c8, 0x00000000}, + {0x0000a2cc, 0x18c43433}, + {0x0000a2d4, 0x00000000}, + {0x0000a2dc, 0x00000000}, + {0x0000a2e0, 0x00000000}, + {0x0000a2e4, 0x00000000}, + {0x0000a2e8, 0x00000000}, + {0x0000a2ec, 0x00000000}, + {0x0000a2f0, 0x00000000}, + {0x0000a2f4, 0x00000000}, + {0x0000a2f8, 0x00000000}, + {0x0000a344, 0x00000000}, + {0x0000a34c, 0x00000000}, + {0x0000a350, 0x0000a000}, + {0x0000a364, 0x00000000}, + {0x0000a370, 0x00000000}, + {0x0000a390, 0x00000001}, + {0x0000a394, 0x00000444}, + {0x0000a398, 0x001f0e0f}, + {0x0000a39c, 0x0075393f}, + {0x0000a3a0, 0xb79f6427}, + {0x0000a3a4, 0x000000ff}, + {0x0000a3a8, 0x3b3b3b3b}, + {0x0000a3ac, 0x2f2f2f2f}, + {0x0000a3c0, 0x20202020}, + {0x0000a3c4, 0x22222220}, + {0x0000a3c8, 0x20200020}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3d8, 0x20202020}, + {0x0000a3dc, 0x20202020}, + {0x0000a3e0, 0x20202020}, + {0x0000a3e4, 0x20202020}, + {0x0000a3e8, 0x20202020}, + {0x0000a3ec, 0x20202020}, + {0x0000a3f0, 0x00000000}, + {0x0000a3f4, 0x00000006}, + {0x0000a3f8, 0x0cdbd380}, + {0x0000a3fc, 0x000f0f01}, + {0x0000a400, 0x8fa91f01}, + {0x0000a404, 0x00000000}, + {0x0000a408, 0x0e79e5c6}, + {0x0000a40c, 0x00820820}, + {0x0000a414, 0x1ce739cf}, + {0x0000a418, 0x2d0019ce}, + {0x0000a41c, 0x1ce739ce}, + {0x0000a420, 0x000001ce}, + {0x0000a424, 0x1ce739ce}, + {0x0000a428, 0x000001ce}, + {0x0000a42c, 0x1ce739ce}, + {0x0000a430, 0x1ce739ce}, + {0x0000a434, 0x00000000}, + {0x0000a438, 0x00001801}, + {0x0000a43c, 0x00000000}, + {0x0000a440, 0x00000000}, + {0x0000a444, 0x00000000}, + {0x0000a448, 0x04000000}, + {0x0000a44c, 0x00000001}, + {0x0000a450, 0x00010000}, + {0x0000a5c4, 0xbfad9d74}, + {0x0000a5c8, 0x0048060a}, + {0x0000a5cc, 0x00000637}, + {0x0000a760, 0x03020100}, + {0x0000a764, 0x09080504}, + {0x0000a768, 0x0d0c0b0a}, + {0x0000a76c, 0x13121110}, + {0x0000a770, 0x31301514}, + {0x0000a774, 0x35343332}, + {0x0000a778, 0x00000036}, + {0x0000a780, 0x00000838}, + {0x0000a7c0, 0x00000000}, + {0x0000a7c4, 0xfffffffc}, + {0x0000a7c8, 0x00000000}, + {0x0000a7cc, 0x00000000}, + {0x0000a7d0, 0x00000000}, + {0x0000a7d4, 0x00000004}, + {0x0000a7dc, 0x00000000}, +}; + +static const u32 ar9485Common_1_1[][2] = { + /* Addr allmodes */ + {0x00007010, 0x00000022}, + {0x00007020, 0x00000000}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000004c2}, +}; + +static const u32 ar9485_1_1_baseband_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, + {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, + {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, + {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, + {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, + {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, + {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, + {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, + {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e}, + {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, + {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, + {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, + {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, + {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222}, + {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324}, + {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010}, + {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, + {0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0}, + {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, + {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b}, + {0x0000a234, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff}, + {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, + {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, + {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, + {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, + {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501}, + {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, + {0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0}, + {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, + {0x0000a2d0, 0x00071981, 0x00071981, 0x00071982, 0x00071982}, + {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, + {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000be04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, + {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; + +static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, + {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, + {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, + {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, + {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, + {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, + {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, + {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, +}; + +static const u32 ar9485_modes_lowest_ob_db_tx_gain_1_1[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, + {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, + {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, + {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, + {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, + {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, + {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, + {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, +}; + +static const u32 ar9485_1_1_radio_postamble[][2] = { + /* Addr allmodes */ + {0x0001609c, 0x0b283f31}, + {0x000160ac, 0x24611800}, + {0x000160b0, 0x03284f3e}, + {0x0001610c, 0x00170000}, + {0x00016140, 0x10804008}, +}; + +static const u32 ar9485_1_1_mac_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, + {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, +}; + +static const u32 ar9485_1_1_radio_core[][2] = { + /* Addr allmodes */ + {0x00016000, 0x36db6db6}, + {0x00016004, 0x6db6db40}, + {0x00016008, 0x73800000}, + {0x0001600c, 0x00000000}, + {0x00016040, 0x7f80fff8}, + {0x0001604c, 0x000f0278}, + {0x00016050, 0x4db6db8c}, + {0x00016054, 0x6db60000}, + {0x00016080, 0x00080000}, + {0x00016084, 0x0e48048c}, + {0x00016088, 0x14214514}, + {0x0001608c, 0x119f081e}, + {0x00016090, 0x24926490}, + {0x00016098, 0xd28b3330}, + {0x000160a0, 0xc2108ffe}, + {0x000160a4, 0x812fc370}, + {0x000160a8, 0x423c8000}, + {0x000160b4, 0x92480040}, + {0x000160c0, 0x006db6db}, + {0x000160c4, 0x0186db60}, + {0x000160c8, 0x6db6db6c}, + {0x000160cc, 0x6de6fbe0}, + {0x000160d0, 0xf7dfcf3c}, + {0x00016100, 0x04cb0001}, + {0x00016104, 0xfff80015}, + {0x00016108, 0x00080010}, + {0x00016144, 0x01884080}, + {0x00016148, 0x00008040}, + {0x00016240, 0x08400000}, + {0x00016244, 0x1bf90f00}, + {0x00016248, 0x00000000}, + {0x0001624c, 0x00000000}, + {0x00016280, 0x01000015}, + {0x00016284, 0x00d30000}, + {0x00016288, 0x00318000}, + {0x0001628c, 0x50000000}, + {0x00016290, 0x4b96210f}, + {0x00016380, 0x00000000}, + {0x00016384, 0x00000000}, + {0x00016388, 0x00800700}, + {0x0001638c, 0x00800700}, + {0x00016390, 0x00800700}, + {0x00016394, 0x00000000}, + {0x00016398, 0x00000000}, + {0x0001639c, 0x00000000}, + {0x000163a0, 0x00000001}, + {0x000163a4, 0x00000001}, + {0x000163a8, 0x00000000}, + {0x000163ac, 0x00000000}, + {0x000163b0, 0x00000000}, + {0x000163b4, 0x00000000}, + {0x000163b8, 0x00000000}, + {0x000163bc, 0x00000000}, + {0x000163c0, 0x000000a0}, + {0x000163c4, 0x000c0000}, + {0x000163c8, 0x14021402}, + {0x000163cc, 0x00001402}, + {0x000163d0, 0x00000000}, + {0x000163d4, 0x00000000}, + {0x00016c40, 0x13188278}, + {0x00016c44, 0x12000000}, +}; + +static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_enable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x10052e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000080c}, +}; + +static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, + {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, + {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, + {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, + {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, + {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, + {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, + {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, +}; + +static const u32 ar9485_1_1[][2] = { + /* Addr allmodes */ + {0x0000a580, 0x00000000}, + {0x0000a584, 0x00000000}, + {0x0000a588, 0x00000000}, + {0x0000a58c, 0x00000000}, + {0x0000a590, 0x00000000}, + {0x0000a594, 0x00000000}, + {0x0000a598, 0x00000000}, + {0x0000a59c, 0x00000000}, + {0x0000a5a0, 0x00000000}, + {0x0000a5a4, 0x00000000}, + {0x0000a5a8, 0x00000000}, + {0x0000a5ac, 0x00000000}, + {0x0000a5b0, 0x00000000}, + {0x0000a5b4, 0x00000000}, + {0x0000a5b8, 0x00000000}, + {0x0000a5bc, 0x00000000}, +}; + +static const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, + {0x0000a458, 0x80000000, 0x80000000, 0x80000000, 0x80000000}, + {0x0000a500, 0x00022200, 0x00022200, 0x00000006, 0x00000006}, + {0x0000a504, 0x05062002, 0x05062002, 0x03000201, 0x03000201}, + {0x0000a508, 0x0c002e00, 0x0c002e00, 0x06000203, 0x06000203}, + {0x0000a50c, 0x11062202, 0x11062202, 0x0a000401, 0x0a000401}, + {0x0000a510, 0x17022e00, 0x17022e00, 0x0e000403, 0x0e000403}, + {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x12000405, 0x12000405}, + {0x0000a518, 0x25020ec0, 0x25020ec0, 0x15000604, 0x15000604}, + {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x18000605, 0x18000605}, + {0x0000a520, 0x2f001f04, 0x2f001f04, 0x1c000a04, 0x1c000a04}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x21000a06, 0x21000a06}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x29000a24, 0x29000a24}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x2f000e21, 0x2f000e21}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x31000e20, 0x31000e20}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x33000e20, 0x33000e20}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000b500, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b504, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b508, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b50c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b510, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b514, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b518, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b51c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b520, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b524, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b528, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b52c, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a}, + {0x0000b530, 0x0000003a, 0x0000003a, 0x0000003a, 0x0000003a}, + {0x0000b534, 0x0000004a, 0x0000004a, 0x0000004a, 0x0000004a}, + {0x0000b538, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b53c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b540, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b544, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b548, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b54c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b550, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b554, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b558, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b55c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b560, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b564, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b568, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b56c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b570, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b574, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b578, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b57c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, + {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, +}; + +static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x10013e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000080c}, +}; + +static const u32 ar9485_1_1_soc_preamble[][2] = { + /* Addr allmodes */ + {0x00004014, 0xba280400}, + {0x000040a4, 0x00a0c9c9}, + {0x00007010, 0x00000022}, + {0x00007020, 0x00000000}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000004c2}, + {0x00007048, 0x00000002}, +}; + +static const u32 ar9485_1_1_baseband_core_txfir_coeff_japan_2484[][2] = { + /* Addr allmodes */ + {0x0000a398, 0x00000000}, + {0x0000a39c, 0x6f7f0301}, + {0x0000a3a0, 0xca9228ee}, +}; + +static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, + {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, + {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, + {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, + {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, + {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, + {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, + {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, +}; + +static const u32 ar9485_fast_clock_1_1_baseband_postamble[][3] = { + /* Addr 5G_HT2 5G_HT40 */ + {0x00009e00, 0x03721821, 0x03721821}, + {0x0000a230, 0x0000400b, 0x00004016}, + {0x0000a254, 0x00000898, 0x00001130}, +}; + +static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x10012e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000080c}, +}; + +static const u32 ar9485_common_rx_gain_1_1[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x01800082}, + {0x0000a014, 0x01820181}, + {0x0000a018, 0x01840183}, + {0x0000a01c, 0x01880185}, + {0x0000a020, 0x018a0189}, + {0x0000a024, 0x02850284}, + {0x0000a028, 0x02890288}, + {0x0000a02c, 0x03850384}, + {0x0000a030, 0x03890388}, + {0x0000a034, 0x038b038a}, + {0x0000a038, 0x038d038c}, + {0x0000a03c, 0x03910390}, + {0x0000a040, 0x03930392}, + {0x0000a044, 0x03950394}, + {0x0000a048, 0x00000396}, + {0x0000a04c, 0x00000000}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x28282828}, + {0x0000a084, 0x28282828}, + {0x0000a088, 0x28282828}, + {0x0000a08c, 0x28282828}, + {0x0000a090, 0x28282828}, + {0x0000a094, 0x21212128}, + {0x0000a098, 0x171c1c1c}, + {0x0000a09c, 0x02020212}, + {0x0000a0a0, 0x00000202}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x111f1100}, + {0x0000a0c8, 0x111d111e}, + {0x0000a0cc, 0x111b111c}, + {0x0000a0d0, 0x22032204}, + {0x0000a0d4, 0x22012202}, + {0x0000a0d8, 0x221f2200}, + {0x0000a0dc, 0x221d221e}, + {0x0000a0e0, 0x33013302}, + {0x0000a0e4, 0x331f3300}, + {0x0000a0e8, 0x4402331e}, + {0x0000a0ec, 0x44004401}, + {0x0000a0f0, 0x441e441f}, + {0x0000a0f4, 0x55015502}, + {0x0000a0f8, 0x551f5500}, + {0x0000a0fc, 0x6602551e}, + {0x0000a100, 0x66006601}, + {0x0000a104, 0x661e661f}, + {0x0000a108, 0x7703661d}, + {0x0000a10c, 0x77017702}, + {0x0000a110, 0x00007700}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x111f1100}, + {0x0000a148, 0x111d111e}, + {0x0000a14c, 0x111b111c}, + {0x0000a150, 0x22032204}, + {0x0000a154, 0x22012202}, + {0x0000a158, 0x221f2200}, + {0x0000a15c, 0x221d221e}, + {0x0000a160, 0x33013302}, + {0x0000a164, 0x331f3300}, + {0x0000a168, 0x4402331e}, + {0x0000a16c, 0x44004401}, + {0x0000a170, 0x441e441f}, + {0x0000a174, 0x55015502}, + {0x0000a178, 0x551f5500}, + {0x0000a17c, 0x6602551e}, + {0x0000a180, 0x66006601}, + {0x0000a184, 0x661e661f}, + {0x0000a188, 0x7703661d}, + {0x0000a18c, 0x77017702}, + {0x0000a190, 0x00007700}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000296}, +}; + +static const u32 ar9485_1_1_pcie_phy_clkreq_enable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x10053e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000080c}, +}; + +static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00060005}, + {0x0000a004, 0x00810080}, + {0x0000a008, 0x00830082}, + {0x0000a00c, 0x00850084}, + {0x0000a010, 0x01820181}, + {0x0000a014, 0x01840183}, + {0x0000a018, 0x01880185}, + {0x0000a01c, 0x018a0189}, + {0x0000a020, 0x02850284}, + {0x0000a024, 0x02890288}, + {0x0000a028, 0x028b028a}, + {0x0000a02c, 0x03850384}, + {0x0000a030, 0x03890388}, + {0x0000a034, 0x038b038a}, + {0x0000a038, 0x038d038c}, + {0x0000a03c, 0x03910390}, + {0x0000a040, 0x03930392}, + {0x0000a044, 0x03950394}, + {0x0000a048, 0x00000396}, + {0x0000a04c, 0x00000000}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x28282828}, + {0x0000a084, 0x28282828}, + {0x0000a088, 0x28282828}, + {0x0000a08c, 0x28282828}, + {0x0000a090, 0x28282828}, + {0x0000a094, 0x24242428}, + {0x0000a098, 0x171e1e1e}, + {0x0000a09c, 0x02020b0b}, + {0x0000a0a0, 0x02020202}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x22072208}, + {0x0000a0c4, 0x22052206}, + {0x0000a0c8, 0x22032204}, + {0x0000a0cc, 0x22012202}, + {0x0000a0d0, 0x221f2200}, + {0x0000a0d4, 0x221d221e}, + {0x0000a0d8, 0x33023303}, + {0x0000a0dc, 0x33003301}, + {0x0000a0e0, 0x331e331f}, + {0x0000a0e4, 0x4402331d}, + {0x0000a0e8, 0x44004401}, + {0x0000a0ec, 0x441e441f}, + {0x0000a0f0, 0x55025503}, + {0x0000a0f4, 0x55005501}, + {0x0000a0f8, 0x551e551f}, + {0x0000a0fc, 0x6602551d}, + {0x0000a100, 0x66006601}, + {0x0000a104, 0x661e661f}, + {0x0000a108, 0x7703661d}, + {0x0000a10c, 0x77017702}, + {0x0000a110, 0x00007700}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x111f1100}, + {0x0000a148, 0x111d111e}, + {0x0000a14c, 0x111b111c}, + {0x0000a150, 0x22032204}, + {0x0000a154, 0x22012202}, + {0x0000a158, 0x221f2200}, + {0x0000a15c, 0x221d221e}, + {0x0000a160, 0x33013302}, + {0x0000a164, 0x331f3300}, + {0x0000a168, 0x4402331e}, + {0x0000a16c, 0x44004401}, + {0x0000a170, 0x441e441f}, + {0x0000a174, 0x55015502}, + {0x0000a178, 0x551f5500}, + {0x0000a17c, 0x6602551e}, + {0x0000a180, 0x66006601}, + {0x0000a184, 0x661e661f}, + {0x0000a188, 0x7703661d}, + {0x0000a18c, 0x77017702}, + {0x0000a190, 0x00007700}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000296}, +}; + #endif diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index b262e98709de..64b226a78b2e 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -789,6 +789,7 @@ #define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */ #define AR_SREV_VERSION_9485 0x240 #define AR_SREV_REVISION_9485_10 0 +#define AR_SREV_REVISION_9485_11 1 #define AR_SREV_5416(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ @@ -866,6 +867,9 @@ #define AR_SREV_9485_10(_ah) \ (AR_SREV_9485(_ah) && \ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_10)) +#define AR_SREV_9485_11(_ah) \ + (AR_SREV_9485(_ah) && \ + ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11)) #define AR_SREV_9285E_20(_ah) \ (AR_SREV_9285_12_OR_LATER(_ah) && \ -- cgit v1.2.3 From f065a93e168299569078bc6f52128b57f602fff3 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 18 Feb 2011 03:18:26 -0500 Subject: hwmon: (lm85) extend to support EMC6D103 chips The interface is identical EMC6D102, so all that needs to be added are some definitions and their uses. Registers apparently missing in EMC6D103S/EMC6D103:A2 compared to EMC6D103:A0, EMC6D103:A1, and EMC6D102 (according to the data sheets), but used unconditionally in the driver: 62[5:7], 6D[0:7], and 6E[0:7]. For that reason, EMC6D103S chips don't get enabled for the time being. Signed-off-by: Jan Beulich (Guenter Roeck: Replaced EMC6D103_A2 with EMC6D103S per EMC6D103S datasheet) Signed-off-by: Guenter Roeck Cc: stable@kernel.org --- drivers/hwmon/Kconfig | 2 +- drivers/hwmon/lm85.c | 23 +++++++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 5eadb007e542..297bc9a7d6e6 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -575,7 +575,7 @@ config SENSORS_LM85 help If you say yes here you get support for National Semiconductor LM85 sensor chips and clones: ADM1027, ADT7463, ADT7468, EMC6D100, - EMC6D101 and EMC6D102. + EMC6D101, EMC6D102, and EMC6D103. This driver can also be built as a module. If so, the module will be called lm85. diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index 1e229847f37a..d2cc28660816 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c @@ -41,7 +41,7 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; enum chips { any_chip, lm85b, lm85c, adm1027, adt7463, adt7468, - emc6d100, emc6d102 + emc6d100, emc6d102, emc6d103 }; /* The LM85 registers */ @@ -90,6 +90,9 @@ enum chips { #define LM85_VERSTEP_EMC6D100_A0 0x60 #define LM85_VERSTEP_EMC6D100_A1 0x61 #define LM85_VERSTEP_EMC6D102 0x65 +#define LM85_VERSTEP_EMC6D103_A0 0x68 +#define LM85_VERSTEP_EMC6D103_A1 0x69 +#define LM85_VERSTEP_EMC6D103S 0x6A /* Also known as EMC6D103:A2 */ #define LM85_REG_CONFIG 0x40 @@ -348,6 +351,7 @@ static const struct i2c_device_id lm85_id[] = { { "emc6d100", emc6d100 }, { "emc6d101", emc6d100 }, { "emc6d102", emc6d102 }, + { "emc6d103", emc6d103 }, { } }; MODULE_DEVICE_TABLE(i2c, lm85_id); @@ -1250,6 +1254,20 @@ static int lm85_detect(struct i2c_client *client, struct i2c_board_info *info) case LM85_VERSTEP_EMC6D102: type_name = "emc6d102"; break; + case LM85_VERSTEP_EMC6D103_A0: + case LM85_VERSTEP_EMC6D103_A1: + type_name = "emc6d103"; + break; + /* + * Registers apparently missing in EMC6D103S/EMC6D103:A2 + * compared to EMC6D103:A0, EMC6D103:A1, and EMC6D102 + * (according to the data sheets), but used unconditionally + * in the driver: 62[5:7], 6D[0:7], and 6E[0:7]. + * So skip EMC6D103S for now. + case LM85_VERSTEP_EMC6D103S: + type_name = "emc6d103s"; + break; + */ } } else { dev_dbg(&adapter->dev, @@ -1283,6 +1301,7 @@ static int lm85_probe(struct i2c_client *client, case adt7468: case emc6d100: case emc6d102: + case emc6d103: data->freq_map = adm1027_freq_map; break; default: @@ -1468,7 +1487,7 @@ static struct lm85_data *lm85_update_device(struct device *dev) /* More alarm bits */ data->alarms |= lm85_read_value(client, EMC6D100_REG_ALARM3) << 16; - } else if (data->type == emc6d102) { + } else if (data->type == emc6d102 || data->type == emc6d103) { /* Have to read LSB bits after the MSB ones because the reading of the MSB bits has frozen the LSBs (backward from the ADM1027). -- cgit v1.2.3 From d5bb2923cfa0a29c5854f9618703ff60849b949e Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 13 Feb 2011 13:12:10 +0100 Subject: drivers/char/pcmcia/ipwireless/main.c: Convert release_resource to release_region/release_mem_region Request_region should be used with release_region, not release_resource. This patch contains a number of changes, related to calls to request_region, request_mem_region, and the associated error handling code. 1. For the call to request_region, the variable io_resource storing the result is dropped. The call to release_resource at the end of the function is changed to a call to release_region with the first two arguments of request_region as its arguments. The same call to release_region is also added to release_ipwireless. 2. The first call to request_mem_region is now tested and ret is set to -EBUSY if the the call has failed. This call was associated with the initialization of ipw->attr_memory. But the error handling code was testing ipw->common_memory. The definition of release_ipwireless also suggests that this call should be associated with ipw->common_memory, not ipw->attr_memory. 3. The second call to request_mem_region is now tested and ret is set to -EBUSY if the the call has failed. 4. The various gotos to the error handling code is adjusted so that there is no need for ifs. 5. Return the value stored in the ret variable rather than -1. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression x,E; @@ ( *x = request_region(...) | *x = request_mem_region(...) ) ... when != release_region(x) when != x = E * release_resource(x); // Signed-off-by: Julia Lawall Signed-off-by: Jiri Kosina Signed-off-by: Dominik Brodowski --- drivers/char/pcmcia/ipwireless/main.c | 52 +++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c index 94b8eb4d691d..444155a305ae 100644 --- a/drivers/char/pcmcia/ipwireless/main.c +++ b/drivers/char/pcmcia/ipwireless/main.c @@ -78,7 +78,6 @@ static void signalled_reboot_callback(void *callback_data) static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data) { struct ipw_dev *ipw = priv_data; - struct resource *io_resource; int ret; p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; @@ -92,9 +91,12 @@ static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data) if (ret) return ret; - io_resource = request_region(p_dev->resource[0]->start, - resource_size(p_dev->resource[0]), - IPWIRELESS_PCCARD_NAME); + if (!request_region(p_dev->resource[0]->start, + resource_size(p_dev->resource[0]), + IPWIRELESS_PCCARD_NAME)) { + ret = -EBUSY; + goto exit; + } p_dev->resource[2]->flags |= WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE; @@ -105,22 +107,25 @@ static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data) ret = pcmcia_map_mem_page(p_dev, p_dev->resource[2], p_dev->card_addr); if (ret != 0) - goto exit2; + goto exit1; ipw->is_v2_card = resource_size(p_dev->resource[2]) == 0x100; - ipw->attr_memory = ioremap(p_dev->resource[2]->start, + ipw->common_memory = ioremap(p_dev->resource[2]->start, resource_size(p_dev->resource[2])); - request_mem_region(p_dev->resource[2]->start, - resource_size(p_dev->resource[2]), - IPWIRELESS_PCCARD_NAME); + if (!request_mem_region(p_dev->resource[2]->start, + resource_size(p_dev->resource[2]), + IPWIRELESS_PCCARD_NAME)) { + ret = -EBUSY; + goto exit2; + } p_dev->resource[3]->flags |= WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE; p_dev->resource[3]->end = 0; /* this used to be 0x1000 */ ret = pcmcia_request_window(p_dev, p_dev->resource[3], 0); if (ret != 0) - goto exit2; + goto exit3; ret = pcmcia_map_mem_page(p_dev, p_dev->resource[3], 0); if (ret != 0) @@ -128,23 +133,28 @@ static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data) ipw->attr_memory = ioremap(p_dev->resource[3]->start, resource_size(p_dev->resource[3])); - request_mem_region(p_dev->resource[3]->start, - resource_size(p_dev->resource[3]), - IPWIRELESS_PCCARD_NAME); + if (!request_mem_region(p_dev->resource[3]->start, + resource_size(p_dev->resource[3]), + IPWIRELESS_PCCARD_NAME)) { + ret = -EBUSY; + goto exit4; + } return 0; +exit4: + iounmap(ipw->attr_memory); exit3: + release_mem_region(p_dev->resource[2]->start, + resource_size(p_dev->resource[2])); exit2: - if (ipw->common_memory) { - release_mem_region(p_dev->resource[2]->start, - resource_size(p_dev->resource[2])); - iounmap(ipw->common_memory); - } + iounmap(ipw->common_memory); exit1: - release_resource(io_resource); + release_region(p_dev->resource[0]->start, + resource_size(p_dev->resource[0])); +exit: pcmcia_disable_device(p_dev); - return -1; + return ret; } static int config_ipwireless(struct ipw_dev *ipw) @@ -219,6 +229,8 @@ exit: static void release_ipwireless(struct ipw_dev *ipw) { + release_region(ipw->link->resource[0]->start, + resource_size(ipw->link->resource[0])); if (ipw->common_memory) { release_mem_region(ipw->link->resource[2]->start, resource_size(ipw->link->resource[2])); -- cgit v1.2.3 From 5b703683b6cc3cb97bbe6b1b14898b273eb59279 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 4 Feb 2011 09:03:43 +0100 Subject: pcmcia vs. MECR on pxa25x/sa1111 After 2.6.34 changes, __pxa2xx_drv_pcmcia_probe() was replaced by sa1111_pcmcia_add(). That unfortunately means that configure_sockets() is not called, leading to MECR not being set properly, leading to strange crashes. Tested on pxa255+sa1111, I do not have lubbock board nearby. Perhaps cleaner solution exists? Signed-off-by: Pavel Machek Signed-off-by: Dominik Brodowski --- drivers/pcmcia/pxa2xx_base.c | 2 +- drivers/pcmcia/pxa2xx_base.h | 1 + drivers/pcmcia/pxa2xx_lubbock.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index 3755e7c8c715..2c540542b5af 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -215,7 +215,7 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt, } #endif -static void pxa2xx_configure_sockets(struct device *dev) +void pxa2xx_configure_sockets(struct device *dev) { struct pcmcia_low_level *ops = dev->platform_data; /* diff --git a/drivers/pcmcia/pxa2xx_base.h b/drivers/pcmcia/pxa2xx_base.h index bb62ea87b8f9..b609b45469ed 100644 --- a/drivers/pcmcia/pxa2xx_base.h +++ b/drivers/pcmcia/pxa2xx_base.h @@ -1,3 +1,4 @@ int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt); void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops); +void pxa2xx_configure_sockets(struct device *dev); diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c index b9f8c8fb42bd..25afe637c657 100644 --- a/drivers/pcmcia/pxa2xx_lubbock.c +++ b/drivers/pcmcia/pxa2xx_lubbock.c @@ -226,6 +226,7 @@ int pcmcia_lubbock_init(struct sa1111_dev *sadev) lubbock_set_misc_wr((1 << 15) | (1 << 14), 0); pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops); + pxa2xx_configure_sockets(&sadev->dev); ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops, pxa2xx_drv_pcmcia_add_one); } -- cgit v1.2.3 From 644e6e4a7fa6b11d59f24032997d90ea0d858d03 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 1 Feb 2011 15:46:05 +0000 Subject: cm4000_cs: Fix undefined ops warning Signed-off-by: Alan Cox Signed-off-by: Dominik Brodowski --- drivers/char/pcmcia/cm4000_cs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 777181a2e603..bcbbc71febb7 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -830,8 +830,7 @@ static void monitor_card(unsigned long p) test_bit(IS_ANY_T1, &dev->flags))) { DEBUGP(4, dev, "Perform AUTOPPS\n"); set_bit(IS_AUTOPPS_ACT, &dev->flags); - ptsreq.protocol = ptsreq.protocol = - (0x01 << dev->proto); + ptsreq.protocol = (0x01 << dev->proto); ptsreq.flags = 0x01; ptsreq.pts1 = 0x00; ptsreq.pts2 = 0x00; -- cgit v1.2.3 From 33619f0d3ff715a2a5499520967d526ad931d70d Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sat, 19 Feb 2011 12:35:15 +0100 Subject: pcmcia: re-enable Zoomed Video support Allow drivers to enable Zoomed Video support. Currently, this is only used by out-of-tree drivers (L64020 DVB driver in particular). CC: [for 2.6.37] Signed-off-by: Dominik Brodowski --- drivers/pcmcia/pcmcia_resource.c | 2 ++ include/pcmcia/ds.h | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 0bdda5b3ed55..42fbf1a75576 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -518,6 +518,8 @@ int pcmcia_enable_device(struct pcmcia_device *p_dev) flags |= CONF_ENABLE_IOCARD; if (flags & CONF_ENABLE_IOCARD) s->socket.flags |= SS_IOCARD; + if (flags & CONF_ENABLE_ZVCARD) + s->socket.flags |= SS_ZVCARD | SS_IOCARD; if (flags & CONF_ENABLE_SPKR) { s->socket.flags |= SS_SPKR_ENA; status = CCSR_AUDIO_ENA; diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h index 8479b66c067b..3fd5064dd43a 100644 --- a/include/pcmcia/ds.h +++ b/include/pcmcia/ds.h @@ -261,6 +261,7 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev); #define CONF_ENABLE_ESR 0x0008 #define CONF_ENABLE_IOCARD 0x0010 /* auto-enabled if IO resources or IRQ * (CONF_ENABLE_IRQ) in use */ +#define CONF_ENABLE_ZVCARD 0x0020 /* flags used by pcmcia_loop_config() autoconfiguration */ #define CONF_AUTO_CHECK_VCC 0x0100 /* check for matching Vcc? */ -- cgit v1.2.3 From 68e41c5d032668e2905404afbef75bc58be179d6 Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Sat, 12 Feb 2011 14:06:06 -0800 Subject: xhci: Avoid BUG() in interrupt context Change the BUGs in xhci_find_new_dequeue_state() to WARN_ONs, to avoid bringing down the box if one of them is hit This patch should be queued for stable kernels back to 2.6.31. Signed-off-by: Paul Zimmerman Signed-off-by: Sarah Sharp Cc: stable@kernel.org --- drivers/usb/host/xhci-ring.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 3e8211c1ce5a..2a87231d588d 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -474,8 +474,11 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, state->new_deq_seg = find_trb_seg(cur_td->start_seg, dev->eps[ep_index].stopped_trb, &state->new_cycle_state); - if (!state->new_deq_seg) - BUG(); + if (!state->new_deq_seg) { + WARN_ON(1); + return; + } + /* Dig out the cycle state saved by the xHC during the stop ep cmd */ xhci_dbg(xhci, "Finding endpoint context\n"); ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index); @@ -486,8 +489,10 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, state->new_deq_seg = find_trb_seg(state->new_deq_seg, state->new_deq_ptr, &state->new_cycle_state); - if (!state->new_deq_seg) - BUG(); + if (!state->new_deq_seg) { + WARN_ON(1); + return; + } trb = &state->new_deq_ptr->generic; if ((trb->field[3] & TRB_TYPE_BITMASK) == TRB_TYPE(TRB_LINK) && -- cgit v1.2.3 From a2490187011cc2263117626615a581927d19f1d3 Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Sat, 12 Feb 2011 14:06:44 -0800 Subject: xhci: Clarify some expressions in the TRB math This makes it easier to spot some problems, which will be fixed by the next patch in the series. Also change dev_dbg to dev_err in check_trb_math(), so any math errors will be visible even when running with debug disabled. Note: This patch changes the expressions containing "((1 << TRB_MAX_BUFF_SHIFT) - 1)" to use the equivalent "(TRB_MAX_BUFF_SIZE - 1)". No change in behavior is intended for those expressions. This patch should be queued for stable kernels back to 2.6.31. Signed-off-by: Paul Zimmerman Signed-off-by: Sarah Sharp Cc: stable@kernel.org --- drivers/usb/host/xhci-ring.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 2a87231d588d..1071411d6dfc 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2368,7 +2368,7 @@ static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb) /* Scatter gather list entries may cross 64KB boundaries */ running_total = TRB_MAX_BUFF_SIZE - - (sg_dma_address(sg) & ((1 << TRB_MAX_BUFF_SHIFT) - 1)); + (sg_dma_address(sg) & (TRB_MAX_BUFF_SIZE - 1)); if (running_total != 0) num_trbs++; @@ -2399,11 +2399,11 @@ static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb) static void check_trb_math(struct urb *urb, int num_trbs, int running_total) { if (num_trbs != 0) - dev_dbg(&urb->dev->dev, "%s - ep %#x - Miscalculated number of " + dev_err(&urb->dev->dev, "%s - ep %#x - Miscalculated number of " "TRBs, %d left\n", __func__, urb->ep->desc.bEndpointAddress, num_trbs); if (running_total != urb->transfer_buffer_length) - dev_dbg(&urb->dev->dev, "%s - ep %#x - Miscalculated tx length, " + dev_err(&urb->dev->dev, "%s - ep %#x - Miscalculated tx length, " "queued %#x (%d), asked for %#x (%d)\n", __func__, urb->ep->desc.bEndpointAddress, @@ -2538,8 +2538,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, sg = urb->sg; addr = (u64) sg_dma_address(sg); this_sg_len = sg_dma_len(sg); - trb_buff_len = TRB_MAX_BUFF_SIZE - - (addr & ((1 << TRB_MAX_BUFF_SHIFT) - 1)); + trb_buff_len = TRB_MAX_BUFF_SIZE - (addr & (TRB_MAX_BUFF_SIZE - 1)); trb_buff_len = min_t(int, trb_buff_len, this_sg_len); if (trb_buff_len > urb->transfer_buffer_length) trb_buff_len = urb->transfer_buffer_length; @@ -2577,7 +2576,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, (unsigned int) (addr + TRB_MAX_BUFF_SIZE) & ~(TRB_MAX_BUFF_SIZE - 1), (unsigned int) addr + trb_buff_len); if (TRB_MAX_BUFF_SIZE - - (addr & ((1 << TRB_MAX_BUFF_SHIFT) - 1)) < trb_buff_len) { + (addr & (TRB_MAX_BUFF_SIZE - 1)) < trb_buff_len) { xhci_warn(xhci, "WARN: sg dma xfer crosses 64KB boundaries!\n"); xhci_dbg(xhci, "Next boundary at %#x, end dma = %#x\n", (unsigned int) (addr + TRB_MAX_BUFF_SIZE) & ~(TRB_MAX_BUFF_SIZE - 1), @@ -2621,7 +2620,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, } trb_buff_len = TRB_MAX_BUFF_SIZE - - (addr & ((1 << TRB_MAX_BUFF_SHIFT) - 1)); + (addr & (TRB_MAX_BUFF_SIZE - 1)); trb_buff_len = min_t(int, trb_buff_len, this_sg_len); if (running_total + trb_buff_len > urb->transfer_buffer_length) trb_buff_len = @@ -2661,7 +2660,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, num_trbs = 0; /* How much data is (potentially) left before the 64KB boundary? */ running_total = TRB_MAX_BUFF_SIZE - - (urb->transfer_dma & ((1 << TRB_MAX_BUFF_SHIFT) - 1)); + (urb->transfer_dma & (TRB_MAX_BUFF_SIZE - 1)); /* If there's some data on this 64KB chunk, or we have to send a * zero-length transfer, we need at least one TRB @@ -2705,8 +2704,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, /* How much data is in the first TRB? */ addr = (u64) urb->transfer_dma; trb_buff_len = TRB_MAX_BUFF_SIZE - - (urb->transfer_dma & ((1 << TRB_MAX_BUFF_SHIFT) - 1)); - if (urb->transfer_buffer_length < trb_buff_len) + (urb->transfer_dma & (TRB_MAX_BUFF_SIZE - 1)); + if (trb_buff_len > urb->transfer_buffer_length) trb_buff_len = urb->transfer_buffer_length; first_trb = true; @@ -2884,8 +2883,7 @@ static int count_isoc_trbs_needed(struct xhci_hcd *xhci, addr = (u64) (urb->transfer_dma + urb->iso_frame_desc[i].offset); td_len = urb->iso_frame_desc[i].length; - running_total = TRB_MAX_BUFF_SIZE - - (addr & ((1 << TRB_MAX_BUFF_SHIFT) - 1)); + running_total = TRB_MAX_BUFF_SIZE - (addr & (TRB_MAX_BUFF_SIZE - 1)); if (running_total != 0) num_trbs++; -- cgit v1.2.3 From 5807795bd4dececdf553719cc02869e633395787 Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Sat, 12 Feb 2011 14:07:20 -0800 Subject: xhci: Fix errors in the running total calculations in the TRB math Calculations like running_total = TRB_MAX_BUFF_SIZE - (sg_dma_address(sg) & (TRB_MAX_BUFF_SIZE - 1)); if (running_total != 0) num_trbs++; are incorrect, because running_total can never be zero, so the if() expression will never be true. I think the intention was that running_total be in the range of 0 to TRB_MAX_BUFF_SIZE-1, not 1 to TRB_MAX_BUFF_SIZE. So adding a running_total &= TRB_MAX_BUFF_SIZE - 1; fixes the problem. This patch should be queued for stable kernels back to 2.6.31. Signed-off-by: Paul Zimmerman Signed-off-by: Sarah Sharp Cc: stable@kernel.org --- drivers/usb/host/xhci-ring.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 1071411d6dfc..dbbeec96ce1d 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2369,6 +2369,7 @@ static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb) /* Scatter gather list entries may cross 64KB boundaries */ running_total = TRB_MAX_BUFF_SIZE - (sg_dma_address(sg) & (TRB_MAX_BUFF_SIZE - 1)); + running_total &= TRB_MAX_BUFF_SIZE - 1; if (running_total != 0) num_trbs++; @@ -2661,6 +2662,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, /* How much data is (potentially) left before the 64KB boundary? */ running_total = TRB_MAX_BUFF_SIZE - (urb->transfer_dma & (TRB_MAX_BUFF_SIZE - 1)); + running_total &= TRB_MAX_BUFF_SIZE - 1; /* If there's some data on this 64KB chunk, or we have to send a * zero-length transfer, we need at least one TRB @@ -2884,6 +2886,7 @@ static int count_isoc_trbs_needed(struct xhci_hcd *xhci, td_len = urb->iso_frame_desc[i].length; running_total = TRB_MAX_BUFF_SIZE - (addr & (TRB_MAX_BUFF_SIZE - 1)); + running_total &= TRB_MAX_BUFF_SIZE - 1; if (running_total != 0) num_trbs++; -- cgit v1.2.3 From bcd2fde05341cef0052e49566ec88b406a521cf3 Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Sat, 12 Feb 2011 14:07:57 -0800 Subject: xhci: Fix an error in count_sg_trbs_needed() The expression while (running_total < sg_dma_len(sg)) does not take into account that the remaining data length can be less than sg_dma_len(sg). In that case, running_total can end up being greater than the total data length, so an extra TRB is counted. Changing the expression to while (running_total < sg_dma_len(sg) && running_total < temp) fixes that. This patch should be queued for stable kernels back to 2.6.31. Signed-off-by: Paul Zimmerman Signed-off-by: Sarah Sharp Cc: stable@kernel.org --- drivers/usb/host/xhci-ring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index dbbeec96ce1d..3289bf4832c9 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2374,7 +2374,7 @@ static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb) num_trbs++; /* How many more 64KB chunks to transfer, how many more TRBs? */ - while (running_total < sg_dma_len(sg)) { + while (running_total < sg_dma_len(sg) && running_total < temp) { num_trbs++; running_total += TRB_MAX_BUFF_SIZE; } -- cgit v1.2.3 From 07194ab7be63a972096309ab0ea747df455c6a20 Mon Sep 17 00:00:00 2001 From: Luben Tuikov Date: Fri, 11 Feb 2011 11:33:10 -0800 Subject: USB: Reset USB 3.0 devices on (re)discovery If the device isn't reset, the XHCI HCD sends SET ADDRESS to address 0 while the device is already in Addressed state, and the request is dropped on the floor as it is addressed to the default address. This sequence of events, which this patch fixes looks like this: usb_reset_and_verify_device() hub_port_init() hub_set_address() SET_ADDRESS to 0 with 1 usb_get_device_descriptor(udev, 8) usb_get_device_descriptor(udev, 18) descriptors_changed() --> goto re_enumerate: hub_port_logical_disconnect() kick_khubd() And then: hub_events() hub_port_connect_change() usb_disconnect() usb_disable_device() new device struct sets device state to Powered choose_address() hub_port_init() <-- no reset, but SET ADDRESS to 0 with 1, timeout! The solution is to always reset the device in hub_port_init() to put it in a known state. Note from Sarah Sharp: This patch should be queued for stable trees all the way back to 2.6.34, since that was the first kernel that supported configured device reset. The code this patch touches has been there since 2.6.32, but the bug would never be hit before 2.6.34 because the xHCI driver would completely reject an attempt to reset a configured device under xHCI. Signed-off-by: Luben Tuikov Signed-off-by: Sarah Sharp Cc: stable@kernel.org --- drivers/usb/core/hub.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index d041c6826e43..0f299b7aad60 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2681,17 +2681,13 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, mutex_lock(&usb_address0_mutex); - if (!udev->config && oldspeed == USB_SPEED_SUPER) { - /* Don't reset USB 3.0 devices during an initial setup */ - usb_set_device_state(udev, USB_STATE_DEFAULT); - } else { - /* Reset the device; full speed may morph to high speed */ - /* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */ - retval = hub_port_reset(hub, port1, udev, delay); - if (retval < 0) /* error or disconnect */ - goto fail; - /* success, speed is known */ - } + /* Reset the device; full speed may morph to high speed */ + /* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */ + retval = hub_port_reset(hub, port1, udev, delay); + if (retval < 0) /* error or disconnect */ + goto fail; + /* success, speed is known */ + retval = -ENODEV; if (oldspeed != USB_SPEED_UNKNOWN && oldspeed != udev->speed) { -- cgit v1.2.3 From 09ece30e06b19994e6f3d260e5c4be18dce22714 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 8 Feb 2011 16:29:33 -0800 Subject: USB: xhci: rework xhci_print_ir_set() to get ir set from xhci itself xhci->ir_set points to __iomem region, but xhci_print_ir_set accepts plain struct xhci_intr_reg * causing multiple sparse warning at call sites and inside the fucntion when we try to read that memory. Instead of adding __iomem qualifier to the argument let's rework the function so it itself gets needed register set from xhci and prints it. Signed-off-by: Dmitry Torokhov Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-dbg.c | 5 +++-- drivers/usb/host/xhci-mem.c | 2 +- drivers/usb/host/xhci.c | 6 +++--- drivers/usb/host/xhci.h | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c index fcbf4abbf381..582937e2132f 100644 --- a/drivers/usb/host/xhci-dbg.c +++ b/drivers/usb/host/xhci-dbg.c @@ -169,9 +169,10 @@ static void xhci_print_ports(struct xhci_hcd *xhci) } } -void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int set_num) +void xhci_print_ir_set(struct xhci_hcd *xhci, int set_num) { - void *addr; + struct xhci_intr_reg __iomem *ir_set = &xhci->run_regs->ir_set[set_num]; + void __iomem *addr; u32 temp; u64 temp_64; diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 1d0f45f0e7a6..c10ee8b6008e 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1961,7 +1961,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) /* Set the event ring dequeue address */ xhci_set_hc_event_deq(xhci); xhci_dbg(xhci, "Wrote ERST address to ir_set 0.\n"); - xhci_print_ir_set(xhci, xhci->ir_set, 0); + xhci_print_ir_set(xhci, 0); /* * XXX: Might need to set the Interrupter Moderation Register to diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 34cf4e165877..9784880df584 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -473,7 +473,7 @@ int xhci_run(struct usb_hcd *hcd) xhci->ir_set, (unsigned int) ER_IRQ_ENABLE(temp)); xhci_writel(xhci, ER_IRQ_ENABLE(temp), &xhci->ir_set->irq_pending); - xhci_print_ir_set(xhci, xhci->ir_set, 0); + xhci_print_ir_set(xhci, 0); if (NUM_TEST_NOOPS > 0) doorbell = xhci_setup_one_noop(xhci); @@ -528,7 +528,7 @@ void xhci_stop(struct usb_hcd *hcd) temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); xhci_writel(xhci, ER_IRQ_DISABLE(temp), &xhci->ir_set->irq_pending); - xhci_print_ir_set(xhci, xhci->ir_set, 0); + xhci_print_ir_set(xhci, 0); xhci_dbg(xhci, "cleaning up memory\n"); xhci_mem_cleanup(xhci); @@ -755,7 +755,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); xhci_writel(xhci, ER_IRQ_DISABLE(temp), &xhci->ir_set->irq_pending); - xhci_print_ir_set(xhci, xhci->ir_set, 0); + xhci_print_ir_set(xhci, 0); xhci_dbg(xhci, "cleaning up memory\n"); xhci_mem_cleanup(xhci); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 7f236fd22015..7f127df6dd55 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1348,7 +1348,7 @@ static inline int xhci_link_trb_quirk(struct xhci_hcd *xhci) } /* xHCI debugging */ -void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int set_num); +void xhci_print_ir_set(struct xhci_hcd *xhci, int set_num); void xhci_print_registers(struct xhci_hcd *xhci); void xhci_dbg_regs(struct xhci_hcd *xhci); void xhci_print_run_regs(struct xhci_hcd *xhci); -- cgit v1.2.3 From c50a00f8feba42c5bccff47e052e4cb0c95dcd2b Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 8 Feb 2011 16:29:34 -0800 Subject: USB: xhci: fix couple sparse annotations There is no point in casting to (void *) when setting up xhci->ir_set as it only makes us lose __iomem annotation and makes sparse unhappy. OTOH we do need to cast to (void *) when calculating xhci->dba from offset, but since it is IO memory we need to annotate it as such. Signed-off-by: Dmitry Torokhov Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-mem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index c10ee8b6008e..dbb8bcd3919e 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1900,11 +1900,11 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) val &= DBOFF_MASK; xhci_dbg(xhci, "// Doorbell array is located at offset 0x%x" " from cap regs base addr\n", val); - xhci->dba = (void *) xhci->cap_regs + val; + xhci->dba = (void __iomem *) xhci->cap_regs + val; xhci_dbg_regs(xhci); xhci_print_run_regs(xhci); /* Set ir_set to interrupt register set 0 */ - xhci->ir_set = (void *) xhci->run_regs->ir_set; + xhci->ir_set = &xhci->run_regs->ir_set[0]; /* * Event ring setup: Allocate a normal ring, but also setup -- cgit v1.2.3 From e58713724059da7d2982d6ad945192c8fca5b729 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 20 Feb 2011 10:03:12 -0800 Subject: Revert "tpm_tis: Use timeouts returned from TPM" This reverts commit 9b29050f8f75916f974a2d231ae5d3cd59792296. It has caused hibernate regressions, for example Juri Sladby's report: "I'm unable to hibernate 2.6.37.1 unless I rmmod tpm_tis: [10974.074587] Suspending console(s) (use no_console_suspend to debug) [10974.103073] tpm_tis 00:0c: Operation Timed out [10974.103089] legacy_suspend(): pnp_bus_suspend+0x0/0xa0 returns -62 [10974.103095] PM: Device 00:0c failed to freeze: error -62" and Rafael points out that some of the new conditionals in that commit seem to make no sense. This commit needs more work and testing, let's revert it for now. Reported-by: Norbert Preining Reported-and-requested-by: Jiri Slaby Cc: Stefan Berger Cc: Guillaume Chazarain Cc: Rajiv Andrade Acked-by: Rafael J. Wysocki Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 18 ++---------------- drivers/char/tpm/tpm.h | 2 -- drivers/char/tpm/tpm_tis.c | 4 +--- 3 files changed, 3 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index faf5a2c65926..36e0fa161c2b 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -577,11 +577,9 @@ duration: if (rc) return; - if (be32_to_cpu(tpm_cmd.header.out.return_code) != 0 || - be32_to_cpu(tpm_cmd.header.out.length) - != sizeof(tpm_cmd.header.out) + sizeof(u32) + 3 * sizeof(u32)) + if (be32_to_cpu(tpm_cmd.header.out.return_code) + != 3 * sizeof(u32)) return; - duration_cap = &tpm_cmd.params.getcap_out.cap.duration; chip->vendor.duration[TPM_SHORT] = usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_short)); @@ -941,18 +939,6 @@ ssize_t tpm_show_caps_1_2(struct device * dev, } EXPORT_SYMBOL_GPL(tpm_show_caps_1_2); -ssize_t tpm_show_timeouts(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct tpm_chip *chip = dev_get_drvdata(dev); - - return sprintf(buf, "%d %d %d\n", - jiffies_to_usecs(chip->vendor.duration[TPM_SHORT]), - jiffies_to_usecs(chip->vendor.duration[TPM_MEDIUM]), - jiffies_to_usecs(chip->vendor.duration[TPM_LONG])); -} -EXPORT_SYMBOL_GPL(tpm_show_timeouts); - ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index d84ff772c26f..72ddb031b69a 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -56,8 +56,6 @@ extern ssize_t tpm_show_owned(struct device *, struct device_attribute *attr, char *); extern ssize_t tpm_show_temp_deactivated(struct device *, struct device_attribute *attr, char *); -extern ssize_t tpm_show_timeouts(struct device *, - struct device_attribute *attr, char *); struct tpm_chip; diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 0d1d38e5f266..dd21df55689d 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -376,7 +376,6 @@ static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL); static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL); static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); -static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); static struct attribute *tis_attrs[] = { &dev_attr_pubek.attr, @@ -386,8 +385,7 @@ static struct attribute *tis_attrs[] = { &dev_attr_owned.attr, &dev_attr_temp_deactivated.attr, &dev_attr_caps.attr, - &dev_attr_cancel.attr, - &dev_attr_timeouts.attr, NULL, + &dev_attr_cancel.attr, NULL, }; static struct attribute_group tis_attr_grp = { -- cgit v1.2.3 From da9cf5050a2e3dbc3cf26a8d908482eb4485ed49 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 21 Feb 2011 18:25:57 +1100 Subject: md: avoid spinlock problem in blk_throtl_exit blk_throtl_exit assumes that ->queue_lock still exists, so make sure that it does. To do this, we stop redirecting ->queue_lock to conf->device_lock and leave it pointing where it is initialised - __queue_lock. As the blk_plug functions check the ->queue_lock is held, we now take that spin_lock explicitly around the plug functions. We don't need the locking, just the warning removal. This is needed for any kernel with the blk_throtl code, which is which is 2.6.37 and later. Cc: stable@kernel.org Signed-off-by: NeilBrown --- drivers/md/linear.c | 1 - drivers/md/multipath.c | 1 - drivers/md/raid0.c | 1 - drivers/md/raid1.c | 6 ++++-- drivers/md/raid10.c | 7 ++++--- drivers/md/raid5.c | 1 - 6 files changed, 8 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 8a2f767f26d8..0ed7f6bc2a7f 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -216,7 +216,6 @@ static int linear_run (mddev_t *mddev) if (md_check_no_bitmap(mddev)) return -EINVAL; - mddev->queue->queue_lock = &mddev->queue->__queue_lock; conf = linear_conf(mddev, mddev->raid_disks); if (!conf) diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 6d7ddf32ef2e..3a62d440e27b 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -435,7 +435,6 @@ static int multipath_run (mddev_t *mddev) * bookkeeping area. [whatever we allocate in multipath_run(), * should be freed in multipath_stop()] */ - mddev->queue->queue_lock = &mddev->queue->__queue_lock; conf = kzalloc(sizeof(multipath_conf_t), GFP_KERNEL); mddev->private = conf; diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 75671dfee551..c0ac457f1218 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -361,7 +361,6 @@ static int raid0_run(mddev_t *mddev) if (md_check_no_bitmap(mddev)) return -EINVAL; blk_queue_max_hw_sectors(mddev->queue, mddev->chunk_sectors); - mddev->queue->queue_lock = &mddev->queue->__queue_lock; /* if private is not null, we are here after takeover */ if (mddev->private == NULL) { diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index a23ffa397ba9..06cd712807d0 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -593,7 +593,10 @@ static int flush_pending_writes(conf_t *conf) if (conf->pending_bio_list.head) { struct bio *bio; bio = bio_list_get(&conf->pending_bio_list); + /* Only take the spinlock to quiet a warning */ + spin_lock(conf->mddev->queue->queue_lock); blk_remove_plug(conf->mddev->queue); + spin_unlock(conf->mddev->queue->queue_lock); spin_unlock_irq(&conf->device_lock); /* flush any pending bitmap writes to * disk before proceeding w/ I/O */ @@ -959,7 +962,7 @@ static int make_request(mddev_t *mddev, struct bio * bio) atomic_inc(&r1_bio->remaining); spin_lock_irqsave(&conf->device_lock, flags); bio_list_add(&conf->pending_bio_list, mbio); - blk_plug_device(mddev->queue); + blk_plug_device_unlocked(mddev->queue); spin_unlock_irqrestore(&conf->device_lock, flags); } r1_bio_write_done(r1_bio, bio->bi_vcnt, behind_pages, behind_pages != NULL); @@ -2021,7 +2024,6 @@ static int run(mddev_t *mddev) if (IS_ERR(conf)) return PTR_ERR(conf); - mddev->queue->queue_lock = &conf->device_lock; list_for_each_entry(rdev, &mddev->disks, same_set) { disk_stack_limits(mddev->gendisk, rdev->bdev, rdev->data_offset << 9); diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 3b607b28741b..747d061d8e05 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -662,7 +662,10 @@ static int flush_pending_writes(conf_t *conf) if (conf->pending_bio_list.head) { struct bio *bio; bio = bio_list_get(&conf->pending_bio_list); + /* Spinlock only taken to quiet a warning */ + spin_lock(conf->mddev->queue->queue_lock); blk_remove_plug(conf->mddev->queue); + spin_unlock(conf->mddev->queue->queue_lock); spin_unlock_irq(&conf->device_lock); /* flush any pending bitmap writes to disk * before proceeding w/ I/O */ @@ -971,7 +974,7 @@ static int make_request(mddev_t *mddev, struct bio * bio) atomic_inc(&r10_bio->remaining); spin_lock_irqsave(&conf->device_lock, flags); bio_list_add(&conf->pending_bio_list, mbio); - blk_plug_device(mddev->queue); + blk_plug_device_unlocked(mddev->queue); spin_unlock_irqrestore(&conf->device_lock, flags); } @@ -2304,8 +2307,6 @@ static int run(mddev_t *mddev) if (!conf) goto out; - mddev->queue->queue_lock = &conf->device_lock; - mddev->thread = conf->thread; conf->thread = NULL; diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 702812824195..78536fdbd87f 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -5204,7 +5204,6 @@ static int run(mddev_t *mddev) mddev->queue->backing_dev_info.congested_data = mddev; mddev->queue->backing_dev_info.congested_fn = raid5_congested; - mddev->queue->queue_lock = &conf->device_lock; mddev->queue->unplug_fn = raid5_unplug_queue; chunk_size = mddev->chunk_sectors << 9; -- cgit v1.2.3 From 0fd857ae09c455f0036bf548fb6ec26b3049f5de Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 18 Feb 2011 23:44:32 +0300 Subject: usb: musb: gadget: DBG() already prints function name In the gadget code, there are several DBG() macro invocations that explicitly print the calling function's name while DBG() macro itself does this anyway; most of these were added by commit f11d893de444965dfd3e55f726533ae1df5c6471 (usb: musb: support ISO high bandwidth for gadget mode). Remove the duplicated printing, somewhat clarifying the messages at the same time... Signed-off-by: Sergei Shtylyov Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 95fbaccb03e1..da8c93bfb6fb 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -978,7 +978,7 @@ static int musb_gadget_enable(struct usb_ep *ep, ok = musb->hb_iso_rx; if (!ok) { - DBG(4, "%s: not support ISO high bandwidth\n", __func__); + DBG(4, "no support for high bandwidth ISO\n"); goto fail; } musb_ep->hb_mult = (tmp >> 11) & 3; @@ -1002,7 +1002,7 @@ static int musb_gadget_enable(struct usb_ep *ep, goto fail; if (tmp > hw_ep->max_packet_sz_tx) { - DBG(4, "%s: packet size beyond hw fifo size\n", __func__); + DBG(4, "packet size beyond hardware FIFO size\n"); goto fail; } @@ -1042,7 +1042,7 @@ static int musb_gadget_enable(struct usb_ep *ep, goto fail; if (tmp > hw_ep->max_packet_sz_rx) { - DBG(4, "%s: packet size beyond hw fifo size\n", __func__); + DBG(4, "packet size beyond hardware FIFO size\n"); goto fail; } @@ -1815,7 +1815,7 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, /* driver must be initialized to support peripheral mode */ if (!musb) { - DBG(1, "%s, no dev??\n", __func__); + DBG(1, "no dev??\n"); retval = -ENODEV; goto err0; } -- cgit v1.2.3 From ce92136843cb6e14aba5fd7bc4e88dbe71e70c5a Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Mon, 21 Feb 2011 16:43:21 +1100 Subject: crypto: picoxcell - add support for the picoxcell crypto engines Picochip picoXcell devices have two crypto engines, one targeted at IPSEC offload and the other at WCDMA layer 2 ciphering. Signed-off-by: Jamie Iles Signed-off-by: Herbert Xu --- drivers/crypto/Kconfig | 17 + drivers/crypto/Makefile | 2 +- drivers/crypto/picoxcell_crypto.c | 1867 ++++++++++++++++++++++++++++++++ drivers/crypto/picoxcell_crypto_regs.h | 128 +++ 4 files changed, 2013 insertions(+), 1 deletion(-) create mode 100644 drivers/crypto/picoxcell_crypto.c create mode 100644 drivers/crypto/picoxcell_crypto_regs.h (limited to 'drivers') diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index eab2cf7a0269..e54185223c8c 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -252,4 +252,21 @@ config CRYPTO_DEV_OMAP_AES OMAP processors have AES module accelerator. Select this if you want to use the OMAP module for AES algorithms. +config CRYPTO_DEV_PICOXCELL + tristate "Support for picoXcell IPSEC and Layer2 crypto engines" + depends on ARCH_PICOXCELL + select CRYPTO_AES + select CRYPTO_AUTHENC + select CRYPTO_ALGAPI + select CRYPTO_DES + select CRYPTO_CBC + select CRYPTO_ECB + select CRYPTO_SEQIV + help + This option enables support for the hardware offload engines in the + Picochip picoXcell SoC devices. Select this for IPSEC ESP offload + and for 3gpp Layer 2 ciphering support. + + Saying m here will build a module named pipcoxcell_crypto. + endif # CRYPTO_HW diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index 256697330a41..5203e34248d7 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -10,4 +10,4 @@ obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/ obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o - +obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o diff --git a/drivers/crypto/picoxcell_crypto.c b/drivers/crypto/picoxcell_crypto.c new file mode 100644 index 000000000000..b092d0a65837 --- /dev/null +++ b/drivers/crypto/picoxcell_crypto.c @@ -0,0 +1,1867 @@ +/* + * Copyright (c) 2010-2011 Picochip Ltd., Jamie Iles + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "picoxcell_crypto_regs.h" + +/* + * The threshold for the number of entries in the CMD FIFO available before + * the CMD0_CNT interrupt is raised. Increasing this value will reduce the + * number of interrupts raised to the CPU. + */ +#define CMD0_IRQ_THRESHOLD 1 + +/* + * The timeout period (in jiffies) for a PDU. When the the number of PDUs in + * flight is greater than the STAT_IRQ_THRESHOLD or 0 the timer is disabled. + * When there are packets in flight but lower than the threshold, we enable + * the timer and at expiry, attempt to remove any processed packets from the + * queue and if there are still packets left, schedule the timer again. + */ +#define PACKET_TIMEOUT 1 + +/* The priority to register each algorithm with. */ +#define SPACC_CRYPTO_ALG_PRIORITY 10000 + +#define SPACC_CRYPTO_KASUMI_F8_KEY_LEN 16 +#define SPACC_CRYPTO_IPSEC_CIPHER_PG_SZ 64 +#define SPACC_CRYPTO_IPSEC_HASH_PG_SZ 64 +#define SPACC_CRYPTO_IPSEC_MAX_CTXS 32 +#define SPACC_CRYPTO_IPSEC_FIFO_SZ 32 +#define SPACC_CRYPTO_L2_CIPHER_PG_SZ 64 +#define SPACC_CRYPTO_L2_HASH_PG_SZ 64 +#define SPACC_CRYPTO_L2_MAX_CTXS 128 +#define SPACC_CRYPTO_L2_FIFO_SZ 128 + +#define MAX_DDT_LEN 16 + +/* DDT format. This must match the hardware DDT format exactly. */ +struct spacc_ddt { + dma_addr_t p; + u32 len; +}; + +/* + * Asynchronous crypto request structure. + * + * This structure defines a request that is either queued for processing or + * being processed. + */ +struct spacc_req { + struct list_head list; + struct spacc_engine *engine; + struct crypto_async_request *req; + int result; + bool is_encrypt; + unsigned ctx_id; + dma_addr_t src_addr, dst_addr; + struct spacc_ddt *src_ddt, *dst_ddt; + void (*complete)(struct spacc_req *req); + + /* AEAD specific bits. */ + u8 *giv; + size_t giv_len; + dma_addr_t giv_pa; +}; + +struct spacc_engine { + void __iomem *regs; + struct list_head pending; + int next_ctx; + spinlock_t hw_lock; + int in_flight; + struct list_head completed; + struct list_head in_progress; + struct tasklet_struct complete; + unsigned long fifo_sz; + void __iomem *cipher_ctx_base; + void __iomem *hash_key_base; + struct spacc_alg *algs; + unsigned num_algs; + struct list_head registered_algs; + size_t cipher_pg_sz; + size_t hash_pg_sz; + const char *name; + struct clk *clk; + struct device *dev; + unsigned max_ctxs; + struct timer_list packet_timeout; + unsigned stat_irq_thresh; + struct dma_pool *req_pool; +}; + +/* Algorithm type mask. */ +#define SPACC_CRYPTO_ALG_MASK 0x7 + +/* SPACC definition of a crypto algorithm. */ +struct spacc_alg { + unsigned long ctrl_default; + unsigned long type; + struct crypto_alg alg; + struct spacc_engine *engine; + struct list_head entry; + int key_offs; + int iv_offs; +}; + +/* Generic context structure for any algorithm type. */ +struct spacc_generic_ctx { + struct spacc_engine *engine; + int flags; + int key_offs; + int iv_offs; +}; + +/* Block cipher context. */ +struct spacc_ablk_ctx { + struct spacc_generic_ctx generic; + u8 key[AES_MAX_KEY_SIZE]; + u8 key_len; + /* + * The fallback cipher. If the operation can't be done in hardware, + * fallback to a software version. + */ + struct crypto_ablkcipher *sw_cipher; +}; + +/* AEAD cipher context. */ +struct spacc_aead_ctx { + struct spacc_generic_ctx generic; + u8 cipher_key[AES_MAX_KEY_SIZE]; + u8 hash_ctx[SPACC_CRYPTO_IPSEC_HASH_PG_SZ]; + u8 cipher_key_len; + u8 hash_key_len; + struct crypto_aead *sw_cipher; + size_t auth_size; + u8 salt[AES_BLOCK_SIZE]; +}; + +static inline struct spacc_alg *to_spacc_alg(struct crypto_alg *alg) +{ + return alg ? container_of(alg, struct spacc_alg, alg) : NULL; +} + +static inline int spacc_fifo_cmd_full(struct spacc_engine *engine) +{ + u32 fifo_stat = readl(engine->regs + SPA_FIFO_STAT_REG_OFFSET); + + return fifo_stat & SPA_FIFO_CMD_FULL; +} + +/* + * Given a cipher context, and a context number, get the base address of the + * context page. + * + * Returns the address of the context page where the key/context may + * be written. + */ +static inline void __iomem *spacc_ctx_page_addr(struct spacc_generic_ctx *ctx, + unsigned indx, + bool is_cipher_ctx) +{ + return is_cipher_ctx ? ctx->engine->cipher_ctx_base + + (indx * ctx->engine->cipher_pg_sz) : + ctx->engine->hash_key_base + (indx * ctx->engine->hash_pg_sz); +} + +/* The context pages can only be written with 32-bit accesses. */ +static inline void memcpy_toio32(u32 __iomem *dst, const void *src, + unsigned count) +{ + const u32 *src32 = (const u32 *) src; + + while (count--) + writel(*src32++, dst++); +} + +static void spacc_cipher_write_ctx(struct spacc_generic_ctx *ctx, + void __iomem *page_addr, const u8 *key, + size_t key_len, const u8 *iv, size_t iv_len) +{ + void __iomem *key_ptr = page_addr + ctx->key_offs; + void __iomem *iv_ptr = page_addr + ctx->iv_offs; + + memcpy_toio32(key_ptr, key, key_len / 4); + memcpy_toio32(iv_ptr, iv, iv_len / 4); +} + +/* + * Load a context into the engines context memory. + * + * Returns the index of the context page where the context was loaded. + */ +static unsigned spacc_load_ctx(struct spacc_generic_ctx *ctx, + const u8 *ciph_key, size_t ciph_len, + const u8 *iv, size_t ivlen, const u8 *hash_key, + size_t hash_len) +{ + unsigned indx = ctx->engine->next_ctx++; + void __iomem *ciph_page_addr, *hash_page_addr; + + ciph_page_addr = spacc_ctx_page_addr(ctx, indx, 1); + hash_page_addr = spacc_ctx_page_addr(ctx, indx, 0); + + ctx->engine->next_ctx &= ctx->engine->fifo_sz - 1; + spacc_cipher_write_ctx(ctx, ciph_page_addr, ciph_key, ciph_len, iv, + ivlen); + writel(ciph_len | (indx << SPA_KEY_SZ_CTX_INDEX_OFFSET) | + (1 << SPA_KEY_SZ_CIPHER_OFFSET), + ctx->engine->regs + SPA_KEY_SZ_REG_OFFSET); + + if (hash_key) { + memcpy_toio32(hash_page_addr, hash_key, hash_len / 4); + writel(hash_len | (indx << SPA_KEY_SZ_CTX_INDEX_OFFSET), + ctx->engine->regs + SPA_KEY_SZ_REG_OFFSET); + } + + return indx; +} + +/* Count the number of scatterlist entries in a scatterlist. */ +static int sg_count(struct scatterlist *sg_list, int nbytes) +{ + struct scatterlist *sg = sg_list; + int sg_nents = 0; + + while (nbytes > 0) { + ++sg_nents; + nbytes -= sg->length; + sg = sg_next(sg); + } + + return sg_nents; +} + +static inline void ddt_set(struct spacc_ddt *ddt, dma_addr_t phys, size_t len) +{ + ddt->p = phys; + ddt->len = len; +} + +/* + * Take a crypto request and scatterlists for the data and turn them into DDTs + * for passing to the crypto engines. This also DMA maps the data so that the + * crypto engines can DMA to/from them. + */ +static struct spacc_ddt *spacc_sg_to_ddt(struct spacc_engine *engine, + struct scatterlist *payload, + unsigned nbytes, + enum dma_data_direction dir, + dma_addr_t *ddt_phys) +{ + unsigned nents, mapped_ents; + struct scatterlist *cur; + struct spacc_ddt *ddt; + int i; + + nents = sg_count(payload, nbytes); + mapped_ents = dma_map_sg(engine->dev, payload, nents, dir); + + if (mapped_ents + 1 > MAX_DDT_LEN) + goto out; + + ddt = dma_pool_alloc(engine->req_pool, GFP_ATOMIC, ddt_phys); + if (!ddt) + goto out; + + for_each_sg(payload, cur, mapped_ents, i) + ddt_set(&ddt[i], sg_dma_address(cur), sg_dma_len(cur)); + ddt_set(&ddt[mapped_ents], 0, 0); + + return ddt; + +out: + dma_unmap_sg(engine->dev, payload, nents, dir); + return NULL; +} + +static int spacc_aead_make_ddts(struct spacc_req *req, u8 *giv) +{ + struct aead_request *areq = container_of(req->req, struct aead_request, + base); + struct spacc_engine *engine = req->engine; + struct spacc_ddt *src_ddt, *dst_ddt; + unsigned ivsize = crypto_aead_ivsize(crypto_aead_reqtfm(areq)); + unsigned nents = sg_count(areq->src, areq->cryptlen); + dma_addr_t iv_addr; + struct scatterlist *cur; + int i, dst_ents, src_ents, assoc_ents; + u8 *iv = giv ? giv : areq->iv; + + src_ddt = dma_pool_alloc(engine->req_pool, GFP_ATOMIC, &req->src_addr); + if (!src_ddt) + return -ENOMEM; + + dst_ddt = dma_pool_alloc(engine->req_pool, GFP_ATOMIC, &req->dst_addr); + if (!dst_ddt) { + dma_pool_free(engine->req_pool, src_ddt, req->src_addr); + return -ENOMEM; + } + + req->src_ddt = src_ddt; + req->dst_ddt = dst_ddt; + + assoc_ents = dma_map_sg(engine->dev, areq->assoc, + sg_count(areq->assoc, areq->assoclen), DMA_TO_DEVICE); + if (areq->src != areq->dst) { + src_ents = dma_map_sg(engine->dev, areq->src, nents, + DMA_TO_DEVICE); + dst_ents = dma_map_sg(engine->dev, areq->dst, nents, + DMA_FROM_DEVICE); + } else { + src_ents = dma_map_sg(engine->dev, areq->src, nents, + DMA_BIDIRECTIONAL); + dst_ents = 0; + } + + /* + * Map the IV/GIV. For the GIV it needs to be bidirectional as it is + * formed by the crypto block and sent as the ESP IV for IPSEC. + */ + iv_addr = dma_map_single(engine->dev, iv, ivsize, + giv ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE); + req->giv_pa = iv_addr; + + /* + * Map the associated data. For decryption we don't copy the + * associated data. + */ + for_each_sg(areq->assoc, cur, assoc_ents, i) { + ddt_set(src_ddt++, sg_dma_address(cur), sg_dma_len(cur)); + if (req->is_encrypt) + ddt_set(dst_ddt++, sg_dma_address(cur), + sg_dma_len(cur)); + } + ddt_set(src_ddt++, iv_addr, ivsize); + + if (giv || req->is_encrypt) + ddt_set(dst_ddt++, iv_addr, ivsize); + + /* + * Now map in the payload for the source and destination and terminate + * with the NULL pointers. + */ + for_each_sg(areq->src, cur, src_ents, i) { + ddt_set(src_ddt++, sg_dma_address(cur), sg_dma_len(cur)); + if (areq->src == areq->dst) + ddt_set(dst_ddt++, sg_dma_address(cur), + sg_dma_len(cur)); + } + + for_each_sg(areq->dst, cur, dst_ents, i) + ddt_set(dst_ddt++, sg_dma_address(cur), + sg_dma_len(cur)); + + ddt_set(src_ddt, 0, 0); + ddt_set(dst_ddt, 0, 0); + + return 0; +} + +static void spacc_aead_free_ddts(struct spacc_req *req) +{ + struct aead_request *areq = container_of(req->req, struct aead_request, + base); + struct spacc_alg *alg = to_spacc_alg(req->req->tfm->__crt_alg); + struct spacc_ablk_ctx *aead_ctx = crypto_tfm_ctx(req->req->tfm); + struct spacc_engine *engine = aead_ctx->generic.engine; + unsigned ivsize = alg->alg.cra_aead.ivsize; + unsigned nents = sg_count(areq->src, areq->cryptlen); + + if (areq->src != areq->dst) { + dma_unmap_sg(engine->dev, areq->src, nents, DMA_TO_DEVICE); + dma_unmap_sg(engine->dev, areq->dst, + sg_count(areq->dst, areq->cryptlen), + DMA_FROM_DEVICE); + } else + dma_unmap_sg(engine->dev, areq->src, nents, DMA_BIDIRECTIONAL); + + dma_unmap_sg(engine->dev, areq->assoc, + sg_count(areq->assoc, areq->assoclen), DMA_TO_DEVICE); + + dma_unmap_single(engine->dev, req->giv_pa, ivsize, DMA_BIDIRECTIONAL); + + dma_pool_free(engine->req_pool, req->src_ddt, req->src_addr); + dma_pool_free(engine->req_pool, req->dst_ddt, req->dst_addr); +} + +static void spacc_free_ddt(struct spacc_req *req, struct spacc_ddt *ddt, + dma_addr_t ddt_addr, struct scatterlist *payload, + unsigned nbytes, enum dma_data_direction dir) +{ + unsigned nents = sg_count(payload, nbytes); + + dma_unmap_sg(req->engine->dev, payload, nents, dir); + dma_pool_free(req->engine->req_pool, ddt, ddt_addr); +} + +/* + * Set key for a DES operation in an AEAD cipher. This also performs weak key + * checking if required. + */ +static int spacc_aead_des_setkey(struct crypto_aead *aead, const u8 *key, + unsigned int len) +{ + struct crypto_tfm *tfm = crypto_aead_tfm(aead); + struct spacc_aead_ctx *ctx = crypto_tfm_ctx(tfm); + u32 tmp[DES_EXPKEY_WORDS]; + + if (unlikely(!des_ekey(tmp, key)) && + (crypto_aead_get_flags(aead)) & CRYPTO_TFM_REQ_WEAK_KEY) { + tfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY; + return -EINVAL; + } + + memcpy(ctx->cipher_key, key, len); + ctx->cipher_key_len = len; + + return 0; +} + +/* Set the key for the AES block cipher component of the AEAD transform. */ +static int spacc_aead_aes_setkey(struct crypto_aead *aead, const u8 *key, + unsigned int len) +{ + struct crypto_tfm *tfm = crypto_aead_tfm(aead); + struct spacc_aead_ctx *ctx = crypto_tfm_ctx(tfm); + + /* + * IPSec engine only supports 128 and 256 bit AES keys. If we get a + * request for any other size (192 bits) then we need to do a software + * fallback. + */ + if (len != AES_KEYSIZE_128 && len != AES_KEYSIZE_256) { + /* + * Set the fallback transform to use the same request flags as + * the hardware transform. + */ + ctx->sw_cipher->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; + ctx->sw_cipher->base.crt_flags |= + tfm->crt_flags & CRYPTO_TFM_REQ_MASK; + return crypto_aead_setkey(ctx->sw_cipher, key, len); + } + + memcpy(ctx->cipher_key, key, len); + ctx->cipher_key_len = len; + + return 0; +} + +static int spacc_aead_setkey(struct crypto_aead *tfm, const u8 *key, + unsigned int keylen) +{ + struct spacc_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct spacc_alg *alg = to_spacc_alg(tfm->base.__crt_alg); + struct rtattr *rta = (void *)key; + struct crypto_authenc_key_param *param; + unsigned int authkeylen, enckeylen; + int err = -EINVAL; + + if (!RTA_OK(rta, keylen)) + goto badkey; + + if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM) + goto badkey; + + if (RTA_PAYLOAD(rta) < sizeof(*param)) + goto badkey; + + param = RTA_DATA(rta); + enckeylen = be32_to_cpu(param->enckeylen); + + key += RTA_ALIGN(rta->rta_len); + keylen -= RTA_ALIGN(rta->rta_len); + + if (keylen < enckeylen) + goto badkey; + + authkeylen = keylen - enckeylen; + + if (enckeylen > AES_MAX_KEY_SIZE) + goto badkey; + + if ((alg->ctrl_default & SPACC_CRYPTO_ALG_MASK) == + SPA_CTRL_CIPH_ALG_AES) + err = spacc_aead_aes_setkey(tfm, key + authkeylen, enckeylen); + else + err = spacc_aead_des_setkey(tfm, key + authkeylen, enckeylen); + + if (err) + goto badkey; + + memcpy(ctx->hash_ctx, key, authkeylen); + ctx->hash_key_len = authkeylen; + + return 0; + +badkey: + crypto_aead_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; +} + +static int spacc_aead_setauthsize(struct crypto_aead *tfm, + unsigned int authsize) +{ + struct spacc_aead_ctx *ctx = crypto_tfm_ctx(crypto_aead_tfm(tfm)); + + ctx->auth_size = authsize; + + return 0; +} + +/* + * Check if an AEAD request requires a fallback operation. Some requests can't + * be completed in hardware because the hardware may not support certain key + * sizes. In these cases we need to complete the request in software. + */ +static int spacc_aead_need_fallback(struct spacc_req *req) +{ + struct aead_request *aead_req; + struct crypto_tfm *tfm = req->req->tfm; + struct crypto_alg *alg = req->req->tfm->__crt_alg; + struct spacc_alg *spacc_alg = to_spacc_alg(alg); + struct spacc_aead_ctx *ctx = crypto_tfm_ctx(tfm); + + aead_req = container_of(req->req, struct aead_request, base); + /* + * If we have a non-supported key-length, then we need to do a + * software fallback. + */ + if ((spacc_alg->ctrl_default & SPACC_CRYPTO_ALG_MASK) == + SPA_CTRL_CIPH_ALG_AES && + ctx->cipher_key_len != AES_KEYSIZE_128 && + ctx->cipher_key_len != AES_KEYSIZE_256) + return 1; + + return 0; +} + +static int spacc_aead_do_fallback(struct aead_request *req, unsigned alg_type, + bool is_encrypt) +{ + struct crypto_tfm *old_tfm = crypto_aead_tfm(crypto_aead_reqtfm(req)); + struct spacc_aead_ctx *ctx = crypto_tfm_ctx(old_tfm); + int err; + + if (ctx->sw_cipher) { + /* + * Change the request to use the software fallback transform, + * and once the ciphering has completed, put the old transform + * back into the request. + */ + aead_request_set_tfm(req, ctx->sw_cipher); + err = is_encrypt ? crypto_aead_encrypt(req) : + crypto_aead_decrypt(req); + aead_request_set_tfm(req, __crypto_aead_cast(old_tfm)); + } else + err = -EINVAL; + + return err; +} + +static void spacc_aead_complete(struct spacc_req *req) +{ + spacc_aead_free_ddts(req); + req->req->complete(req->req, req->result); +} + +static int spacc_aead_submit(struct spacc_req *req) +{ + struct crypto_tfm *tfm = req->req->tfm; + struct spacc_aead_ctx *ctx = crypto_tfm_ctx(tfm); + struct crypto_alg *alg = req->req->tfm->__crt_alg; + struct spacc_alg *spacc_alg = to_spacc_alg(alg); + struct spacc_engine *engine = ctx->generic.engine; + u32 ctrl, proc_len, assoc_len; + struct aead_request *aead_req = + container_of(req->req, struct aead_request, base); + + req->result = -EINPROGRESS; + req->ctx_id = spacc_load_ctx(&ctx->generic, ctx->cipher_key, + ctx->cipher_key_len, aead_req->iv, alg->cra_aead.ivsize, + ctx->hash_ctx, ctx->hash_key_len); + + /* Set the source and destination DDT pointers. */ + writel(req->src_addr, engine->regs + SPA_SRC_PTR_REG_OFFSET); + writel(req->dst_addr, engine->regs + SPA_DST_PTR_REG_OFFSET); + writel(0, engine->regs + SPA_OFFSET_REG_OFFSET); + + assoc_len = aead_req->assoclen; + proc_len = aead_req->cryptlen + assoc_len; + + /* + * If we aren't generating an IV, then we need to include the IV in the + * associated data so that it is included in the hash. + */ + if (!req->giv) { + assoc_len += crypto_aead_ivsize(crypto_aead_reqtfm(aead_req)); + proc_len += crypto_aead_ivsize(crypto_aead_reqtfm(aead_req)); + } else + proc_len += req->giv_len; + + /* + * If we are decrypting, we need to take the length of the ICV out of + * the processing length. + */ + if (!req->is_encrypt) + proc_len -= ctx->auth_size; + + writel(proc_len, engine->regs + SPA_PROC_LEN_REG_OFFSET); + writel(assoc_len, engine->regs + SPA_AAD_LEN_REG_OFFSET); + writel(ctx->auth_size, engine->regs + SPA_ICV_LEN_REG_OFFSET); + writel(0, engine->regs + SPA_ICV_OFFSET_REG_OFFSET); + writel(0, engine->regs + SPA_AUX_INFO_REG_OFFSET); + + ctrl = spacc_alg->ctrl_default | (req->ctx_id << SPA_CTRL_CTX_IDX) | + (1 << SPA_CTRL_ICV_APPEND); + if (req->is_encrypt) + ctrl |= (1 << SPA_CTRL_ENCRYPT_IDX) | (1 << SPA_CTRL_AAD_COPY); + else + ctrl |= (1 << SPA_CTRL_KEY_EXP); + + mod_timer(&engine->packet_timeout, jiffies + PACKET_TIMEOUT); + + writel(ctrl, engine->regs + SPA_CTRL_REG_OFFSET); + + return -EINPROGRESS; +} + +/* + * Setup an AEAD request for processing. This will configure the engine, load + * the context and then start the packet processing. + * + * @giv Pointer to destination address for a generated IV. If the + * request does not need to generate an IV then this should be set to NULL. + */ +static int spacc_aead_setup(struct aead_request *req, u8 *giv, + unsigned alg_type, bool is_encrypt) +{ + struct crypto_alg *alg = req->base.tfm->__crt_alg; + struct spacc_engine *engine = to_spacc_alg(alg)->engine; + struct spacc_req *dev_req = aead_request_ctx(req); + int err = -EINPROGRESS; + unsigned long flags; + unsigned ivsize = crypto_aead_ivsize(crypto_aead_reqtfm(req)); + + dev_req->giv = giv; + dev_req->giv_len = ivsize; + dev_req->req = &req->base; + dev_req->is_encrypt = is_encrypt; + dev_req->result = -EBUSY; + dev_req->engine = engine; + dev_req->complete = spacc_aead_complete; + + if (unlikely(spacc_aead_need_fallback(dev_req))) + return spacc_aead_do_fallback(req, alg_type, is_encrypt); + + spacc_aead_make_ddts(dev_req, dev_req->giv); + + err = -EINPROGRESS; + spin_lock_irqsave(&engine->hw_lock, flags); + if (unlikely(spacc_fifo_cmd_full(engine))) { + if (!(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { + err = -EBUSY; + spin_unlock_irqrestore(&engine->hw_lock, flags); + goto out_free_ddts; + } + list_add_tail(&dev_req->list, &engine->pending); + } else { + ++engine->in_flight; + list_add_tail(&dev_req->list, &engine->in_progress); + spacc_aead_submit(dev_req); + } + spin_unlock_irqrestore(&engine->hw_lock, flags); + + goto out; + +out_free_ddts: + spacc_aead_free_ddts(dev_req); +out: + return err; +} + +static int spacc_aead_encrypt(struct aead_request *req) +{ + struct crypto_aead *aead = crypto_aead_reqtfm(req); + struct crypto_tfm *tfm = crypto_aead_tfm(aead); + struct spacc_alg *alg = to_spacc_alg(tfm->__crt_alg); + + return spacc_aead_setup(req, NULL, alg->type, 1); +} + +static int spacc_aead_givencrypt(struct aead_givcrypt_request *req) +{ + struct crypto_aead *tfm = aead_givcrypt_reqtfm(req); + struct spacc_aead_ctx *ctx = crypto_aead_ctx(tfm); + size_t ivsize = crypto_aead_ivsize(tfm); + struct spacc_alg *alg = to_spacc_alg(tfm->base.__crt_alg); + unsigned len; + __be64 seq; + + memcpy(req->areq.iv, ctx->salt, ivsize); + len = ivsize; + if (ivsize > sizeof(u64)) { + memset(req->giv, 0, ivsize - sizeof(u64)); + len = sizeof(u64); + } + seq = cpu_to_be64(req->seq); + memcpy(req->giv + ivsize - len, &seq, len); + + return spacc_aead_setup(&req->areq, req->giv, alg->type, 1); +} + +static int spacc_aead_decrypt(struct aead_request *req) +{ + struct crypto_aead *aead = crypto_aead_reqtfm(req); + struct crypto_tfm *tfm = crypto_aead_tfm(aead); + struct spacc_alg *alg = to_spacc_alg(tfm->__crt_alg); + + return spacc_aead_setup(req, NULL, alg->type, 0); +} + +/* + * Initialise a new AEAD context. This is responsible for allocating the + * fallback cipher and initialising the context. + */ +static int spacc_aead_cra_init(struct crypto_tfm *tfm) +{ + struct spacc_aead_ctx *ctx = crypto_tfm_ctx(tfm); + struct crypto_alg *alg = tfm->__crt_alg; + struct spacc_alg *spacc_alg = to_spacc_alg(alg); + struct spacc_engine *engine = spacc_alg->engine; + + ctx->generic.flags = spacc_alg->type; + ctx->generic.engine = engine; + ctx->sw_cipher = crypto_alloc_aead(alg->cra_name, 0, + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(ctx->sw_cipher)) { + dev_warn(engine->dev, "failed to allocate fallback for %s\n", + alg->cra_name); + ctx->sw_cipher = NULL; + } + ctx->generic.key_offs = spacc_alg->key_offs; + ctx->generic.iv_offs = spacc_alg->iv_offs; + + get_random_bytes(ctx->salt, sizeof(ctx->salt)); + + tfm->crt_aead.reqsize = sizeof(struct spacc_req); + + return 0; +} + +/* + * Destructor for an AEAD context. This is called when the transform is freed + * and must free the fallback cipher. + */ +static void spacc_aead_cra_exit(struct crypto_tfm *tfm) +{ + struct spacc_aead_ctx *ctx = crypto_tfm_ctx(tfm); + + if (ctx->sw_cipher) + crypto_free_aead(ctx->sw_cipher); + ctx->sw_cipher = NULL; +} + +/* + * Set the DES key for a block cipher transform. This also performs weak key + * checking if the transform has requested it. + */ +static int spacc_des_setkey(struct crypto_ablkcipher *cipher, const u8 *key, + unsigned int len) +{ + struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); + struct spacc_ablk_ctx *ctx = crypto_tfm_ctx(tfm); + u32 tmp[DES_EXPKEY_WORDS]; + + if (len > DES3_EDE_KEY_SIZE) { + crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + + if (unlikely(!des_ekey(tmp, key)) && + (crypto_ablkcipher_get_flags(cipher) & CRYPTO_TFM_REQ_WEAK_KEY)) { + tfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY; + return -EINVAL; + } + + memcpy(ctx->key, key, len); + ctx->key_len = len; + + return 0; +} + +/* + * Set the key for an AES block cipher. Some key lengths are not supported in + * hardware so this must also check whether a fallback is needed. + */ +static int spacc_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key, + unsigned int len) +{ + struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); + struct spacc_ablk_ctx *ctx = crypto_tfm_ctx(tfm); + int err = 0; + + if (len > AES_MAX_KEY_SIZE) { + crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + + /* + * IPSec engine only supports 128 and 256 bit AES keys. If we get a + * request for any other size (192 bits) then we need to do a software + * fallback. + */ + if ((len != AES_KEYSIZE_128 || len != AES_KEYSIZE_256) && + ctx->sw_cipher) { + /* + * Set the fallback transform to use the same request flags as + * the hardware transform. + */ + ctx->sw_cipher->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; + ctx->sw_cipher->base.crt_flags |= + cipher->base.crt_flags & CRYPTO_TFM_REQ_MASK; + + err = crypto_ablkcipher_setkey(ctx->sw_cipher, key, len); + if (err) + goto sw_setkey_failed; + } else if ((len != AES_KEYSIZE_128 || len != AES_KEYSIZE_256) && + !ctx->sw_cipher) + err = -EINVAL; + + memcpy(ctx->key, key, len); + ctx->key_len = len; + +sw_setkey_failed: + if (err && ctx->sw_cipher) { + tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; + tfm->crt_flags |= + ctx->sw_cipher->base.crt_flags & CRYPTO_TFM_RES_MASK; + } + + return err; +} + +static int spacc_kasumi_f8_setkey(struct crypto_ablkcipher *cipher, + const u8 *key, unsigned int len) +{ + struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); + struct spacc_ablk_ctx *ctx = crypto_tfm_ctx(tfm); + int err = 0; + + if (len > AES_MAX_KEY_SIZE) { + crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN); + err = -EINVAL; + goto out; + } + + memcpy(ctx->key, key, len); + ctx->key_len = len; + +out: + return err; +} + +static int spacc_ablk_need_fallback(struct spacc_req *req) +{ + struct spacc_ablk_ctx *ctx; + struct crypto_tfm *tfm = req->req->tfm; + struct crypto_alg *alg = req->req->tfm->__crt_alg; + struct spacc_alg *spacc_alg = to_spacc_alg(alg); + + ctx = crypto_tfm_ctx(tfm); + + return (spacc_alg->ctrl_default & SPACC_CRYPTO_ALG_MASK) == + SPA_CTRL_CIPH_ALG_AES && + ctx->key_len != AES_KEYSIZE_128 && + ctx->key_len != AES_KEYSIZE_256; +} + +static void spacc_ablk_complete(struct spacc_req *req) +{ + struct ablkcipher_request *ablk_req = + container_of(req->req, struct ablkcipher_request, base); + + if (ablk_req->src != ablk_req->dst) { + spacc_free_ddt(req, req->src_ddt, req->src_addr, ablk_req->src, + ablk_req->nbytes, DMA_TO_DEVICE); + spacc_free_ddt(req, req->dst_ddt, req->dst_addr, ablk_req->dst, + ablk_req->nbytes, DMA_FROM_DEVICE); + } else + spacc_free_ddt(req, req->dst_ddt, req->dst_addr, ablk_req->dst, + ablk_req->nbytes, DMA_BIDIRECTIONAL); + + req->req->complete(req->req, req->result); +} + +static int spacc_ablk_submit(struct spacc_req *req) +{ + struct crypto_tfm *tfm = req->req->tfm; + struct spacc_ablk_ctx *ctx = crypto_tfm_ctx(tfm); + struct ablkcipher_request *ablk_req = ablkcipher_request_cast(req->req); + struct crypto_alg *alg = req->req->tfm->__crt_alg; + struct spacc_alg *spacc_alg = to_spacc_alg(alg); + struct spacc_engine *engine = ctx->generic.engine; + u32 ctrl; + + req->ctx_id = spacc_load_ctx(&ctx->generic, ctx->key, + ctx->key_len, ablk_req->info, alg->cra_ablkcipher.ivsize, + NULL, 0); + + writel(req->src_addr, engine->regs + SPA_SRC_PTR_REG_OFFSET); + writel(req->dst_addr, engine->regs + SPA_DST_PTR_REG_OFFSET); + writel(0, engine->regs + SPA_OFFSET_REG_OFFSET); + + writel(ablk_req->nbytes, engine->regs + SPA_PROC_LEN_REG_OFFSET); + writel(0, engine->regs + SPA_ICV_OFFSET_REG_OFFSET); + writel(0, engine->regs + SPA_AUX_INFO_REG_OFFSET); + writel(0, engine->regs + SPA_AAD_LEN_REG_OFFSET); + + ctrl = spacc_alg->ctrl_default | (req->ctx_id << SPA_CTRL_CTX_IDX) | + (req->is_encrypt ? (1 << SPA_CTRL_ENCRYPT_IDX) : + (1 << SPA_CTRL_KEY_EXP)); + + mod_timer(&engine->packet_timeout, jiffies + PACKET_TIMEOUT); + + writel(ctrl, engine->regs + SPA_CTRL_REG_OFFSET); + + return -EINPROGRESS; +} + +static int spacc_ablk_do_fallback(struct ablkcipher_request *req, + unsigned alg_type, bool is_encrypt) +{ + struct crypto_tfm *old_tfm = + crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req)); + struct spacc_ablk_ctx *ctx = crypto_tfm_ctx(old_tfm); + int err; + + if (!ctx->sw_cipher) + return -EINVAL; + + /* + * Change the request to use the software fallback transform, and once + * the ciphering has completed, put the old transform back into the + * request. + */ + ablkcipher_request_set_tfm(req, ctx->sw_cipher); + err = is_encrypt ? crypto_ablkcipher_encrypt(req) : + crypto_ablkcipher_decrypt(req); + ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(old_tfm)); + + return err; +} + +static int spacc_ablk_setup(struct ablkcipher_request *req, unsigned alg_type, + bool is_encrypt) +{ + struct crypto_alg *alg = req->base.tfm->__crt_alg; + struct spacc_engine *engine = to_spacc_alg(alg)->engine; + struct spacc_req *dev_req = ablkcipher_request_ctx(req); + unsigned long flags; + int err = -ENOMEM; + + dev_req->req = &req->base; + dev_req->is_encrypt = is_encrypt; + dev_req->engine = engine; + dev_req->complete = spacc_ablk_complete; + dev_req->result = -EINPROGRESS; + + if (unlikely(spacc_ablk_need_fallback(dev_req))) + return spacc_ablk_do_fallback(req, alg_type, is_encrypt); + + /* + * Create the DDT's for the engine. If we share the same source and + * destination then we can optimize by reusing the DDT's. + */ + if (req->src != req->dst) { + dev_req->src_ddt = spacc_sg_to_ddt(engine, req->src, + req->nbytes, DMA_TO_DEVICE, &dev_req->src_addr); + if (!dev_req->src_ddt) + goto out; + + dev_req->dst_ddt = spacc_sg_to_ddt(engine, req->dst, + req->nbytes, DMA_FROM_DEVICE, &dev_req->dst_addr); + if (!dev_req->dst_ddt) + goto out_free_src; + } else { + dev_req->dst_ddt = spacc_sg_to_ddt(engine, req->dst, + req->nbytes, DMA_BIDIRECTIONAL, &dev_req->dst_addr); + if (!dev_req->dst_ddt) + goto out; + + dev_req->src_ddt = NULL; + dev_req->src_addr = dev_req->dst_addr; + } + + err = -EINPROGRESS; + spin_lock_irqsave(&engine->hw_lock, flags); + /* + * Check if the engine will accept the operation now. If it won't then + * we either stick it on the end of a pending list if we can backlog, + * or bailout with an error if not. + */ + if (unlikely(spacc_fifo_cmd_full(engine))) { + if (!(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { + err = -EBUSY; + spin_unlock_irqrestore(&engine->hw_lock, flags); + goto out_free_ddts; + } + list_add_tail(&dev_req->list, &engine->pending); + } else { + ++engine->in_flight; + list_add_tail(&dev_req->list, &engine->in_progress); + spacc_ablk_submit(dev_req); + } + spin_unlock_irqrestore(&engine->hw_lock, flags); + + goto out; + +out_free_ddts: + spacc_free_ddt(dev_req, dev_req->dst_ddt, dev_req->dst_addr, req->dst, + req->nbytes, req->src == req->dst ? + DMA_BIDIRECTIONAL : DMA_FROM_DEVICE); +out_free_src: + if (req->src != req->dst) + spacc_free_ddt(dev_req, dev_req->src_ddt, dev_req->src_addr, + req->src, req->nbytes, DMA_TO_DEVICE); +out: + return err; +} + +static int spacc_ablk_cra_init(struct crypto_tfm *tfm) +{ + struct spacc_ablk_ctx *ctx = crypto_tfm_ctx(tfm); + struct crypto_alg *alg = tfm->__crt_alg; + struct spacc_alg *spacc_alg = to_spacc_alg(alg); + struct spacc_engine *engine = spacc_alg->engine; + + ctx->generic.flags = spacc_alg->type; + ctx->generic.engine = engine; + if (alg->cra_flags & CRYPTO_ALG_NEED_FALLBACK) { + ctx->sw_cipher = crypto_alloc_ablkcipher(alg->cra_name, 0, + CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(ctx->sw_cipher)) { + dev_warn(engine->dev, "failed to allocate fallback for %s\n", + alg->cra_name); + ctx->sw_cipher = NULL; + } + } + ctx->generic.key_offs = spacc_alg->key_offs; + ctx->generic.iv_offs = spacc_alg->iv_offs; + + tfm->crt_ablkcipher.reqsize = sizeof(struct spacc_req); + + return 0; +} + +static void spacc_ablk_cra_exit(struct crypto_tfm *tfm) +{ + struct spacc_ablk_ctx *ctx = crypto_tfm_ctx(tfm); + + if (ctx->sw_cipher) + crypto_free_ablkcipher(ctx->sw_cipher); + ctx->sw_cipher = NULL; +} + +static int spacc_ablk_encrypt(struct ablkcipher_request *req) +{ + struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req); + struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); + struct spacc_alg *alg = to_spacc_alg(tfm->__crt_alg); + + return spacc_ablk_setup(req, alg->type, 1); +} + +static int spacc_ablk_decrypt(struct ablkcipher_request *req) +{ + struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(req); + struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); + struct spacc_alg *alg = to_spacc_alg(tfm->__crt_alg); + + return spacc_ablk_setup(req, alg->type, 0); +} + +static inline int spacc_fifo_stat_empty(struct spacc_engine *engine) +{ + return readl(engine->regs + SPA_FIFO_STAT_REG_OFFSET) & + SPA_FIFO_STAT_EMPTY; +} + +static void spacc_process_done(struct spacc_engine *engine) +{ + struct spacc_req *req; + unsigned long flags; + + spin_lock_irqsave(&engine->hw_lock, flags); + + while (!spacc_fifo_stat_empty(engine)) { + req = list_first_entry(&engine->in_progress, struct spacc_req, + list); + list_move_tail(&req->list, &engine->completed); + + /* POP the status register. */ + writel(~0, engine->regs + SPA_STAT_POP_REG_OFFSET); + req->result = (readl(engine->regs + SPA_STATUS_REG_OFFSET) & + SPA_STATUS_RES_CODE_MASK) >> SPA_STATUS_RES_CODE_OFFSET; + + /* + * Convert the SPAcc error status into the standard POSIX error + * codes. + */ + if (unlikely(req->result)) { + switch (req->result) { + case SPA_STATUS_ICV_FAIL: + req->result = -EBADMSG; + break; + + case SPA_STATUS_MEMORY_ERROR: + dev_warn(engine->dev, + "memory error triggered\n"); + req->result = -EFAULT; + break; + + case SPA_STATUS_BLOCK_ERROR: + dev_warn(engine->dev, + "block error triggered\n"); + req->result = -EIO; + break; + } + } + } + + tasklet_schedule(&engine->complete); + + spin_unlock_irqrestore(&engine->hw_lock, flags); +} + +static irqreturn_t spacc_spacc_irq(int irq, void *dev) +{ + struct spacc_engine *engine = (struct spacc_engine *)dev; + u32 spacc_irq_stat = readl(engine->regs + SPA_IRQ_STAT_REG_OFFSET); + + writel(spacc_irq_stat, engine->regs + SPA_IRQ_STAT_REG_OFFSET); + spacc_process_done(engine); + + return IRQ_HANDLED; +} + +static void spacc_packet_timeout(unsigned long data) +{ + struct spacc_engine *engine = (struct spacc_engine *)data; + + spacc_process_done(engine); +} + +static int spacc_req_submit(struct spacc_req *req) +{ + struct crypto_alg *alg = req->req->tfm->__crt_alg; + + if (CRYPTO_ALG_TYPE_AEAD == (CRYPTO_ALG_TYPE_MASK & alg->cra_flags)) + return spacc_aead_submit(req); + else + return spacc_ablk_submit(req); +} + +static void spacc_spacc_complete(unsigned long data) +{ + struct spacc_engine *engine = (struct spacc_engine *)data; + struct spacc_req *req, *tmp; + unsigned long flags; + int num_removed = 0; + LIST_HEAD(completed); + + spin_lock_irqsave(&engine->hw_lock, flags); + list_splice_init(&engine->completed, &completed); + spin_unlock_irqrestore(&engine->hw_lock, flags); + + list_for_each_entry_safe(req, tmp, &completed, list) { + ++num_removed; + req->complete(req); + } + + /* Try and fill the engine back up again. */ + spin_lock_irqsave(&engine->hw_lock, flags); + + engine->in_flight -= num_removed; + + list_for_each_entry_safe(req, tmp, &engine->pending, list) { + if (spacc_fifo_cmd_full(engine)) + break; + + list_move_tail(&req->list, &engine->in_progress); + ++engine->in_flight; + req->result = spacc_req_submit(req); + } + + if (engine->in_flight) + mod_timer(&engine->packet_timeout, jiffies + PACKET_TIMEOUT); + + spin_unlock_irqrestore(&engine->hw_lock, flags); +} + +#ifdef CONFIG_PM +static int spacc_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct spacc_engine *engine = platform_get_drvdata(pdev); + + /* + * We only support standby mode. All we have to do is gate the clock to + * the spacc. The hardware will preserve state until we turn it back + * on again. + */ + clk_disable(engine->clk); + + return 0; +} + +static int spacc_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct spacc_engine *engine = platform_get_drvdata(pdev); + + return clk_enable(engine->clk); +} + +static const struct dev_pm_ops spacc_pm_ops = { + .suspend = spacc_suspend, + .resume = spacc_resume, +}; +#endif /* CONFIG_PM */ + +static inline struct spacc_engine *spacc_dev_to_engine(struct device *dev) +{ + return dev ? platform_get_drvdata(to_platform_device(dev)) : NULL; +} + +static ssize_t spacc_stat_irq_thresh_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct spacc_engine *engine = spacc_dev_to_engine(dev); + + return snprintf(buf, PAGE_SIZE, "%u\n", engine->stat_irq_thresh); +} + +static ssize_t spacc_stat_irq_thresh_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct spacc_engine *engine = spacc_dev_to_engine(dev); + unsigned long thresh; + + if (strict_strtoul(buf, 0, &thresh)) + return -EINVAL; + + thresh = clamp(thresh, 1UL, engine->fifo_sz - 1); + + engine->stat_irq_thresh = thresh; + writel(engine->stat_irq_thresh << SPA_IRQ_CTRL_STAT_CNT_OFFSET, + engine->regs + SPA_IRQ_CTRL_REG_OFFSET); + + return len; +} +static DEVICE_ATTR(stat_irq_thresh, 0644, spacc_stat_irq_thresh_show, + spacc_stat_irq_thresh_store); + +static struct spacc_alg ipsec_engine_algs[] = { + { + .ctrl_default = SPA_CTRL_CIPH_ALG_AES | SPA_CTRL_CIPH_MODE_CBC, + .key_offs = 0, + .iv_offs = AES_MAX_KEY_SIZE, + .alg = { + .cra_name = "cbc(aes)", + .cra_driver_name = "cbc-aes-picoxcell", + .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct spacc_ablk_ctx), + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_ablkcipher = { + .setkey = spacc_aes_setkey, + .encrypt = spacc_ablk_encrypt, + .decrypt = spacc_ablk_decrypt, + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + }, + .cra_init = spacc_ablk_cra_init, + .cra_exit = spacc_ablk_cra_exit, + }, + }, + { + .key_offs = 0, + .iv_offs = AES_MAX_KEY_SIZE, + .ctrl_default = SPA_CTRL_CIPH_ALG_AES | SPA_CTRL_CIPH_MODE_ECB, + .alg = { + .cra_name = "ecb(aes)", + .cra_driver_name = "ecb-aes-picoxcell", + .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct spacc_ablk_ctx), + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_ablkcipher = { + .setkey = spacc_aes_setkey, + .encrypt = spacc_ablk_encrypt, + .decrypt = spacc_ablk_decrypt, + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + }, + .cra_init = spacc_ablk_cra_init, + .cra_exit = spacc_ablk_cra_exit, + }, + }, + { + .key_offs = DES_BLOCK_SIZE, + .iv_offs = 0, + .ctrl_default = SPA_CTRL_CIPH_ALG_DES | SPA_CTRL_CIPH_MODE_CBC, + .alg = { + .cra_name = "cbc(des)", + .cra_driver_name = "cbc-des-picoxcell", + .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = DES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct spacc_ablk_ctx), + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_ablkcipher = { + .setkey = spacc_des_setkey, + .encrypt = spacc_ablk_encrypt, + .decrypt = spacc_ablk_decrypt, + .min_keysize = DES_KEY_SIZE, + .max_keysize = DES_KEY_SIZE, + .ivsize = DES_BLOCK_SIZE, + }, + .cra_init = spacc_ablk_cra_init, + .cra_exit = spacc_ablk_cra_exit, + }, + }, + { + .key_offs = DES_BLOCK_SIZE, + .iv_offs = 0, + .ctrl_default = SPA_CTRL_CIPH_ALG_DES | SPA_CTRL_CIPH_MODE_ECB, + .alg = { + .cra_name = "ecb(des)", + .cra_driver_name = "ecb-des-picoxcell", + .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = DES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct spacc_ablk_ctx), + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_ablkcipher = { + .setkey = spacc_des_setkey, + .encrypt = spacc_ablk_encrypt, + .decrypt = spacc_ablk_decrypt, + .min_keysize = DES_KEY_SIZE, + .max_keysize = DES_KEY_SIZE, + }, + .cra_init = spacc_ablk_cra_init, + .cra_exit = spacc_ablk_cra_exit, + }, + }, + { + .key_offs = DES_BLOCK_SIZE, + .iv_offs = 0, + .ctrl_default = SPA_CTRL_CIPH_ALG_DES | SPA_CTRL_CIPH_MODE_CBC, + .alg = { + .cra_name = "cbc(des3_ede)", + .cra_driver_name = "cbc-des3-ede-picoxcell", + .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = DES3_EDE_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct spacc_ablk_ctx), + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_ablkcipher = { + .setkey = spacc_des_setkey, + .encrypt = spacc_ablk_encrypt, + .decrypt = spacc_ablk_decrypt, + .min_keysize = DES3_EDE_KEY_SIZE, + .max_keysize = DES3_EDE_KEY_SIZE, + .ivsize = DES3_EDE_BLOCK_SIZE, + }, + .cra_init = spacc_ablk_cra_init, + .cra_exit = spacc_ablk_cra_exit, + }, + }, + { + .key_offs = DES_BLOCK_SIZE, + .iv_offs = 0, + .ctrl_default = SPA_CTRL_CIPH_ALG_DES | SPA_CTRL_CIPH_MODE_ECB, + .alg = { + .cra_name = "ecb(des3_ede)", + .cra_driver_name = "ecb-des3-ede-picoxcell", + .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = DES3_EDE_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct spacc_ablk_ctx), + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_ablkcipher = { + .setkey = spacc_des_setkey, + .encrypt = spacc_ablk_encrypt, + .decrypt = spacc_ablk_decrypt, + .min_keysize = DES3_EDE_KEY_SIZE, + .max_keysize = DES3_EDE_KEY_SIZE, + }, + .cra_init = spacc_ablk_cra_init, + .cra_exit = spacc_ablk_cra_exit, + }, + }, + { + .ctrl_default = SPA_CTRL_CIPH_ALG_AES | SPA_CTRL_CIPH_MODE_CBC | + SPA_CTRL_HASH_ALG_SHA | SPA_CTRL_HASH_MODE_HMAC, + .key_offs = 0, + .iv_offs = AES_MAX_KEY_SIZE, + .alg = { + .cra_name = "authenc(hmac(sha1),cbc(aes))", + .cra_driver_name = "authenc-hmac-sha1-cbc-aes-picoxcell", + .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct spacc_aead_ctx), + .cra_type = &crypto_aead_type, + .cra_module = THIS_MODULE, + .cra_aead = { + .setkey = spacc_aead_setkey, + .setauthsize = spacc_aead_setauthsize, + .encrypt = spacc_aead_encrypt, + .decrypt = spacc_aead_decrypt, + .givencrypt = spacc_aead_givencrypt, + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = SHA1_DIGEST_SIZE, + }, + .cra_init = spacc_aead_cra_init, + .cra_exit = spacc_aead_cra_exit, + }, + }, + { + .ctrl_default = SPA_CTRL_CIPH_ALG_AES | SPA_CTRL_CIPH_MODE_CBC | + SPA_CTRL_HASH_ALG_SHA256 | + SPA_CTRL_HASH_MODE_HMAC, + .key_offs = 0, + .iv_offs = AES_MAX_KEY_SIZE, + .alg = { + .cra_name = "authenc(hmac(sha256),cbc(aes))", + .cra_driver_name = "authenc-hmac-sha256-cbc-aes-picoxcell", + .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct spacc_aead_ctx), + .cra_type = &crypto_aead_type, + .cra_module = THIS_MODULE, + .cra_aead = { + .setkey = spacc_aead_setkey, + .setauthsize = spacc_aead_setauthsize, + .encrypt = spacc_aead_encrypt, + .decrypt = spacc_aead_decrypt, + .givencrypt = spacc_aead_givencrypt, + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = SHA256_DIGEST_SIZE, + }, + .cra_init = spacc_aead_cra_init, + .cra_exit = spacc_aead_cra_exit, + }, + }, + { + .key_offs = 0, + .iv_offs = AES_MAX_KEY_SIZE, + .ctrl_default = SPA_CTRL_CIPH_ALG_AES | SPA_CTRL_CIPH_MODE_CBC | + SPA_CTRL_HASH_ALG_MD5 | SPA_CTRL_HASH_MODE_HMAC, + .alg = { + .cra_name = "authenc(hmac(md5),cbc(aes))", + .cra_driver_name = "authenc-hmac-md5-cbc-aes-picoxcell", + .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct spacc_aead_ctx), + .cra_type = &crypto_aead_type, + .cra_module = THIS_MODULE, + .cra_aead = { + .setkey = spacc_aead_setkey, + .setauthsize = spacc_aead_setauthsize, + .encrypt = spacc_aead_encrypt, + .decrypt = spacc_aead_decrypt, + .givencrypt = spacc_aead_givencrypt, + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = MD5_DIGEST_SIZE, + }, + .cra_init = spacc_aead_cra_init, + .cra_exit = spacc_aead_cra_exit, + }, + }, + { + .key_offs = DES_BLOCK_SIZE, + .iv_offs = 0, + .ctrl_default = SPA_CTRL_CIPH_ALG_DES | SPA_CTRL_CIPH_MODE_CBC | + SPA_CTRL_HASH_ALG_SHA | SPA_CTRL_HASH_MODE_HMAC, + .alg = { + .cra_name = "authenc(hmac(sha1),cbc(des3_ede))", + .cra_driver_name = "authenc-hmac-sha1-cbc-3des-picoxcell", + .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, + .cra_blocksize = DES3_EDE_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct spacc_aead_ctx), + .cra_type = &crypto_aead_type, + .cra_module = THIS_MODULE, + .cra_aead = { + .setkey = spacc_aead_setkey, + .setauthsize = spacc_aead_setauthsize, + .encrypt = spacc_aead_encrypt, + .decrypt = spacc_aead_decrypt, + .givencrypt = spacc_aead_givencrypt, + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = SHA1_DIGEST_SIZE, + }, + .cra_init = spacc_aead_cra_init, + .cra_exit = spacc_aead_cra_exit, + }, + }, + { + .key_offs = DES_BLOCK_SIZE, + .iv_offs = 0, + .ctrl_default = SPA_CTRL_CIPH_ALG_AES | SPA_CTRL_CIPH_MODE_CBC | + SPA_CTRL_HASH_ALG_SHA256 | + SPA_CTRL_HASH_MODE_HMAC, + .alg = { + .cra_name = "authenc(hmac(sha256),cbc(des3_ede))", + .cra_driver_name = "authenc-hmac-sha256-cbc-3des-picoxcell", + .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, + .cra_blocksize = DES3_EDE_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct spacc_aead_ctx), + .cra_type = &crypto_aead_type, + .cra_module = THIS_MODULE, + .cra_aead = { + .setkey = spacc_aead_setkey, + .setauthsize = spacc_aead_setauthsize, + .encrypt = spacc_aead_encrypt, + .decrypt = spacc_aead_decrypt, + .givencrypt = spacc_aead_givencrypt, + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = SHA256_DIGEST_SIZE, + }, + .cra_init = spacc_aead_cra_init, + .cra_exit = spacc_aead_cra_exit, + }, + }, + { + .key_offs = DES_BLOCK_SIZE, + .iv_offs = 0, + .ctrl_default = SPA_CTRL_CIPH_ALG_DES | SPA_CTRL_CIPH_MODE_CBC | + SPA_CTRL_HASH_ALG_MD5 | SPA_CTRL_HASH_MODE_HMAC, + .alg = { + .cra_name = "authenc(hmac(md5),cbc(des3_ede))", + .cra_driver_name = "authenc-hmac-md5-cbc-3des-picoxcell", + .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, + .cra_blocksize = DES3_EDE_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct spacc_aead_ctx), + .cra_type = &crypto_aead_type, + .cra_module = THIS_MODULE, + .cra_aead = { + .setkey = spacc_aead_setkey, + .setauthsize = spacc_aead_setauthsize, + .encrypt = spacc_aead_encrypt, + .decrypt = spacc_aead_decrypt, + .givencrypt = spacc_aead_givencrypt, + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = MD5_DIGEST_SIZE, + }, + .cra_init = spacc_aead_cra_init, + .cra_exit = spacc_aead_cra_exit, + }, + }, +}; + +static struct spacc_alg l2_engine_algs[] = { + { + .key_offs = 0, + .iv_offs = SPACC_CRYPTO_KASUMI_F8_KEY_LEN, + .ctrl_default = SPA_CTRL_CIPH_ALG_KASUMI | + SPA_CTRL_CIPH_MODE_F8, + .alg = { + .cra_name = "f8(kasumi)", + .cra_driver_name = "f8-kasumi-picoxcell", + .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, + .cra_flags = CRYPTO_ALG_TYPE_GIVCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = 8, + .cra_ctxsize = sizeof(struct spacc_ablk_ctx), + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_ablkcipher = { + .setkey = spacc_kasumi_f8_setkey, + .encrypt = spacc_ablk_encrypt, + .decrypt = spacc_ablk_decrypt, + .min_keysize = 16, + .max_keysize = 16, + .ivsize = 8, + }, + .cra_init = spacc_ablk_cra_init, + .cra_exit = spacc_ablk_cra_exit, + }, + }, +}; + +static int __devinit spacc_probe(struct platform_device *pdev, + unsigned max_ctxs, size_t cipher_pg_sz, + size_t hash_pg_sz, size_t fifo_sz, + struct spacc_alg *algs, size_t num_algs) +{ + int i, err, ret = -EINVAL; + struct resource *mem, *irq; + struct spacc_engine *engine = devm_kzalloc(&pdev->dev, sizeof(*engine), + GFP_KERNEL); + if (!engine) + return -ENOMEM; + + engine->max_ctxs = max_ctxs; + engine->cipher_pg_sz = cipher_pg_sz; + engine->hash_pg_sz = hash_pg_sz; + engine->fifo_sz = fifo_sz; + engine->algs = algs; + engine->num_algs = num_algs; + engine->name = dev_name(&pdev->dev); + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!mem || !irq) { + dev_err(&pdev->dev, "no memory/irq resource for engine\n"); + return -ENXIO; + } + + if (!devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem), + engine->name)) + return -ENOMEM; + + engine->regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); + if (!engine->regs) { + dev_err(&pdev->dev, "memory map failed\n"); + return -ENOMEM; + } + + if (devm_request_irq(&pdev->dev, irq->start, spacc_spacc_irq, 0, + engine->name, engine)) { + dev_err(engine->dev, "failed to request IRQ\n"); + return -EBUSY; + } + + engine->dev = &pdev->dev; + engine->cipher_ctx_base = engine->regs + SPA_CIPH_KEY_BASE_REG_OFFSET; + engine->hash_key_base = engine->regs + SPA_HASH_KEY_BASE_REG_OFFSET; + + engine->req_pool = dmam_pool_create(engine->name, engine->dev, + MAX_DDT_LEN * sizeof(struct spacc_ddt), 8, SZ_64K); + if (!engine->req_pool) + return -ENOMEM; + + spin_lock_init(&engine->hw_lock); + + engine->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(engine->clk)) { + dev_info(&pdev->dev, "clk unavailable\n"); + device_remove_file(&pdev->dev, &dev_attr_stat_irq_thresh); + return PTR_ERR(engine->clk); + } + + if (clk_enable(engine->clk)) { + dev_info(&pdev->dev, "unable to enable clk\n"); + clk_put(engine->clk); + return -EIO; + } + + err = device_create_file(&pdev->dev, &dev_attr_stat_irq_thresh); + if (err) { + clk_disable(engine->clk); + clk_put(engine->clk); + return err; + } + + + /* + * Use an IRQ threshold of 50% as a default. This seems to be a + * reasonable trade off of latency against throughput but can be + * changed at runtime. + */ + engine->stat_irq_thresh = (engine->fifo_sz / 2); + + /* + * Configure the interrupts. We only use the STAT_CNT interrupt as we + * only submit a new packet for processing when we complete another in + * the queue. This minimizes time spent in the interrupt handler. + */ + writel(engine->stat_irq_thresh << SPA_IRQ_CTRL_STAT_CNT_OFFSET, + engine->regs + SPA_IRQ_CTRL_REG_OFFSET); + writel(SPA_IRQ_EN_STAT_EN | SPA_IRQ_EN_GLBL_EN, + engine->regs + SPA_IRQ_EN_REG_OFFSET); + + setup_timer(&engine->packet_timeout, spacc_packet_timeout, + (unsigned long)engine); + + INIT_LIST_HEAD(&engine->pending); + INIT_LIST_HEAD(&engine->completed); + INIT_LIST_HEAD(&engine->in_progress); + engine->in_flight = 0; + tasklet_init(&engine->complete, spacc_spacc_complete, + (unsigned long)engine); + + platform_set_drvdata(pdev, engine); + + INIT_LIST_HEAD(&engine->registered_algs); + for (i = 0; i < engine->num_algs; ++i) { + engine->algs[i].engine = engine; + err = crypto_register_alg(&engine->algs[i].alg); + if (!err) { + list_add_tail(&engine->algs[i].entry, + &engine->registered_algs); + ret = 0; + } + if (err) + dev_err(engine->dev, "failed to register alg \"%s\"\n", + engine->algs[i].alg.cra_name); + else + dev_dbg(engine->dev, "registered alg \"%s\"\n", + engine->algs[i].alg.cra_name); + } + + return ret; +} + +static int __devexit spacc_remove(struct platform_device *pdev) +{ + struct spacc_alg *alg, *next; + struct spacc_engine *engine = platform_get_drvdata(pdev); + + del_timer_sync(&engine->packet_timeout); + device_remove_file(&pdev->dev, &dev_attr_stat_irq_thresh); + + list_for_each_entry_safe(alg, next, &engine->registered_algs, entry) { + list_del(&alg->entry); + crypto_unregister_alg(&alg->alg); + } + + clk_disable(engine->clk); + clk_put(engine->clk); + + return 0; +} + +static int __devinit ipsec_probe(struct platform_device *pdev) +{ + return spacc_probe(pdev, SPACC_CRYPTO_IPSEC_MAX_CTXS, + SPACC_CRYPTO_IPSEC_CIPHER_PG_SZ, + SPACC_CRYPTO_IPSEC_HASH_PG_SZ, + SPACC_CRYPTO_IPSEC_FIFO_SZ, ipsec_engine_algs, + ARRAY_SIZE(ipsec_engine_algs)); +} + +static struct platform_driver ipsec_driver = { + .probe = ipsec_probe, + .remove = __devexit_p(spacc_remove), + .driver = { + .name = "picoxcell-ipsec", +#ifdef CONFIG_PM + .pm = &spacc_pm_ops, +#endif /* CONFIG_PM */ + }, +}; + +static int __devinit l2_probe(struct platform_device *pdev) +{ + return spacc_probe(pdev, SPACC_CRYPTO_L2_MAX_CTXS, + SPACC_CRYPTO_L2_CIPHER_PG_SZ, + SPACC_CRYPTO_L2_HASH_PG_SZ, SPACC_CRYPTO_L2_FIFO_SZ, + l2_engine_algs, ARRAY_SIZE(l2_engine_algs)); +} + +static struct platform_driver l2_driver = { + .probe = l2_probe, + .remove = __devexit_p(spacc_remove), + .driver = { + .name = "picoxcell-l2", +#ifdef CONFIG_PM + .pm = &spacc_pm_ops, +#endif /* CONFIG_PM */ + }, +}; + +static int __init spacc_init(void) +{ + int ret = platform_driver_register(&ipsec_driver); + if (ret) { + pr_err("failed to register ipsec spacc driver"); + goto out; + } + + ret = platform_driver_register(&l2_driver); + if (ret) { + pr_err("failed to register l2 spacc driver"); + goto l2_failed; + } + + return 0; + +l2_failed: + platform_driver_unregister(&ipsec_driver); +out: + return ret; +} +module_init(spacc_init); + +static void __exit spacc_exit(void) +{ + platform_driver_unregister(&ipsec_driver); + platform_driver_unregister(&l2_driver); +} +module_exit(spacc_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jamie Iles"); diff --git a/drivers/crypto/picoxcell_crypto_regs.h b/drivers/crypto/picoxcell_crypto_regs.h new file mode 100644 index 000000000000..af93442564c9 --- /dev/null +++ b/drivers/crypto/picoxcell_crypto_regs.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2010 Picochip Ltd., Jamie Iles + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __PICOXCELL_CRYPTO_REGS_H__ +#define __PICOXCELL_CRYPTO_REGS_H__ + +#define SPA_STATUS_OK 0 +#define SPA_STATUS_ICV_FAIL 1 +#define SPA_STATUS_MEMORY_ERROR 2 +#define SPA_STATUS_BLOCK_ERROR 3 + +#define SPA_IRQ_CTRL_STAT_CNT_OFFSET 16 +#define SPA_IRQ_STAT_STAT_MASK (1 << 4) +#define SPA_FIFO_STAT_STAT_OFFSET 16 +#define SPA_FIFO_STAT_STAT_CNT_MASK (0x3F << SPA_FIFO_STAT_STAT_OFFSET) +#define SPA_STATUS_RES_CODE_OFFSET 24 +#define SPA_STATUS_RES_CODE_MASK (0x3 << SPA_STATUS_RES_CODE_OFFSET) +#define SPA_KEY_SZ_CTX_INDEX_OFFSET 8 +#define SPA_KEY_SZ_CIPHER_OFFSET 31 + +#define SPA_IRQ_EN_REG_OFFSET 0x00000000 +#define SPA_IRQ_STAT_REG_OFFSET 0x00000004 +#define SPA_IRQ_CTRL_REG_OFFSET 0x00000008 +#define SPA_FIFO_STAT_REG_OFFSET 0x0000000C +#define SPA_SDMA_BRST_SZ_REG_OFFSET 0x00000010 +#define SPA_SRC_PTR_REG_OFFSET 0x00000020 +#define SPA_DST_PTR_REG_OFFSET 0x00000024 +#define SPA_OFFSET_REG_OFFSET 0x00000028 +#define SPA_AAD_LEN_REG_OFFSET 0x0000002C +#define SPA_PROC_LEN_REG_OFFSET 0x00000030 +#define SPA_ICV_LEN_REG_OFFSET 0x00000034 +#define SPA_ICV_OFFSET_REG_OFFSET 0x00000038 +#define SPA_SW_CTRL_REG_OFFSET 0x0000003C +#define SPA_CTRL_REG_OFFSET 0x00000040 +#define SPA_AUX_INFO_REG_OFFSET 0x0000004C +#define SPA_STAT_POP_REG_OFFSET 0x00000050 +#define SPA_STATUS_REG_OFFSET 0x00000054 +#define SPA_KEY_SZ_REG_OFFSET 0x00000100 +#define SPA_CIPH_KEY_BASE_REG_OFFSET 0x00004000 +#define SPA_HASH_KEY_BASE_REG_OFFSET 0x00008000 +#define SPA_RC4_CTX_BASE_REG_OFFSET 0x00020000 + +#define SPA_IRQ_EN_REG_RESET 0x00000000 +#define SPA_IRQ_CTRL_REG_RESET 0x00000000 +#define SPA_FIFO_STAT_REG_RESET 0x00000000 +#define SPA_SDMA_BRST_SZ_REG_RESET 0x00000000 +#define SPA_SRC_PTR_REG_RESET 0x00000000 +#define SPA_DST_PTR_REG_RESET 0x00000000 +#define SPA_OFFSET_REG_RESET 0x00000000 +#define SPA_AAD_LEN_REG_RESET 0x00000000 +#define SPA_PROC_LEN_REG_RESET 0x00000000 +#define SPA_ICV_LEN_REG_RESET 0x00000000 +#define SPA_ICV_OFFSET_REG_RESET 0x00000000 +#define SPA_SW_CTRL_REG_RESET 0x00000000 +#define SPA_CTRL_REG_RESET 0x00000000 +#define SPA_AUX_INFO_REG_RESET 0x00000000 +#define SPA_STAT_POP_REG_RESET 0x00000000 +#define SPA_STATUS_REG_RESET 0x00000000 +#define SPA_KEY_SZ_REG_RESET 0x00000000 + +#define SPA_CTRL_HASH_ALG_IDX 4 +#define SPA_CTRL_CIPH_MODE_IDX 8 +#define SPA_CTRL_HASH_MODE_IDX 12 +#define SPA_CTRL_CTX_IDX 16 +#define SPA_CTRL_ENCRYPT_IDX 24 +#define SPA_CTRL_AAD_COPY 25 +#define SPA_CTRL_ICV_PT 26 +#define SPA_CTRL_ICV_ENC 27 +#define SPA_CTRL_ICV_APPEND 28 +#define SPA_CTRL_KEY_EXP 29 + +#define SPA_KEY_SZ_CXT_IDX 8 +#define SPA_KEY_SZ_CIPHER_IDX 31 + +#define SPA_IRQ_EN_CMD0_EN (1 << 0) +#define SPA_IRQ_EN_STAT_EN (1 << 4) +#define SPA_IRQ_EN_GLBL_EN (1 << 31) + +#define SPA_CTRL_CIPH_ALG_NULL 0x00 +#define SPA_CTRL_CIPH_ALG_DES 0x01 +#define SPA_CTRL_CIPH_ALG_AES 0x02 +#define SPA_CTRL_CIPH_ALG_RC4 0x03 +#define SPA_CTRL_CIPH_ALG_MULTI2 0x04 +#define SPA_CTRL_CIPH_ALG_KASUMI 0x05 + +#define SPA_CTRL_HASH_ALG_NULL (0x00 << SPA_CTRL_HASH_ALG_IDX) +#define SPA_CTRL_HASH_ALG_MD5 (0x01 << SPA_CTRL_HASH_ALG_IDX) +#define SPA_CTRL_HASH_ALG_SHA (0x02 << SPA_CTRL_HASH_ALG_IDX) +#define SPA_CTRL_HASH_ALG_SHA224 (0x03 << SPA_CTRL_HASH_ALG_IDX) +#define SPA_CTRL_HASH_ALG_SHA256 (0x04 << SPA_CTRL_HASH_ALG_IDX) +#define SPA_CTRL_HASH_ALG_SHA384 (0x05 << SPA_CTRL_HASH_ALG_IDX) +#define SPA_CTRL_HASH_ALG_SHA512 (0x06 << SPA_CTRL_HASH_ALG_IDX) +#define SPA_CTRL_HASH_ALG_AESMAC (0x07 << SPA_CTRL_HASH_ALG_IDX) +#define SPA_CTRL_HASH_ALG_AESCMAC (0x08 << SPA_CTRL_HASH_ALG_IDX) +#define SPA_CTRL_HASH_ALG_KASF9 (0x09 << SPA_CTRL_HASH_ALG_IDX) + +#define SPA_CTRL_CIPH_MODE_NULL (0x00 << SPA_CTRL_CIPH_MODE_IDX) +#define SPA_CTRL_CIPH_MODE_ECB (0x00 << SPA_CTRL_CIPH_MODE_IDX) +#define SPA_CTRL_CIPH_MODE_CBC (0x01 << SPA_CTRL_CIPH_MODE_IDX) +#define SPA_CTRL_CIPH_MODE_CTR (0x02 << SPA_CTRL_CIPH_MODE_IDX) +#define SPA_CTRL_CIPH_MODE_CCM (0x03 << SPA_CTRL_CIPH_MODE_IDX) +#define SPA_CTRL_CIPH_MODE_GCM (0x05 << SPA_CTRL_CIPH_MODE_IDX) +#define SPA_CTRL_CIPH_MODE_OFB (0x07 << SPA_CTRL_CIPH_MODE_IDX) +#define SPA_CTRL_CIPH_MODE_CFB (0x08 << SPA_CTRL_CIPH_MODE_IDX) +#define SPA_CTRL_CIPH_MODE_F8 (0x09 << SPA_CTRL_CIPH_MODE_IDX) + +#define SPA_CTRL_HASH_MODE_RAW (0x00 << SPA_CTRL_HASH_MODE_IDX) +#define SPA_CTRL_HASH_MODE_SSLMAC (0x01 << SPA_CTRL_HASH_MODE_IDX) +#define SPA_CTRL_HASH_MODE_HMAC (0x02 << SPA_CTRL_HASH_MODE_IDX) + +#define SPA_FIFO_STAT_EMPTY (1 << 31) +#define SPA_FIFO_CMD_FULL (1 << 7) + +#endif /* __PICOXCELL_CRYPTO_REGS_H__ */ -- cgit v1.2.3 From 442a4fffffa26fc3080350b4d50172f7589c3ac2 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Mon, 21 Feb 2011 21:43:10 +1100 Subject: random: update interface comments to reflect reality At present, the comment header in random.c makes no mention of add_disk_randomness, and instead, suggests that disk activity adds to the random pool by way of add_interrupt_randomness, which appears to not have been the case since sometime prior to the existence of git, and even prior to bitkeeper. Didn't look any further back. At least, as far as I can tell, there are no storage drivers setting IRQF_SAMPLE_RANDOM, which is a requirement for add_interrupt_randomness to trigger, so the only way for a disk to contribute entropy is by way of add_disk_randomness. Update comments accordingly, complete with special mention about solid state drives being a crappy source of entropy (see e2e1a148bc for reference). Signed-off-by: Jarod Wilson Acked-by: Matt Mackall Signed-off-by: Herbert Xu --- drivers/char/random.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/random.c b/drivers/char/random.c index 72a4fcb17745..5e29e8031bbc 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -128,6 +128,7 @@ * void add_input_randomness(unsigned int type, unsigned int code, * unsigned int value); * void add_interrupt_randomness(int irq); + * void add_disk_randomness(struct gendisk *disk); * * add_input_randomness() uses the input layer interrupt timing, as well as * the event type information from the hardware. @@ -136,9 +137,15 @@ * inputs to the entropy pool. Note that not all interrupts are good * sources of randomness! For example, the timer interrupts is not a * good choice, because the periodicity of the interrupts is too - * regular, and hence predictable to an attacker. Disk interrupts are - * a better measure, since the timing of the disk interrupts are more - * unpredictable. + * regular, and hence predictable to an attacker. Network Interface + * Controller interrupts are a better measure, since the timing of the + * NIC interrupts are more unpredictable. + * + * add_disk_randomness() uses what amounts to the seek time of block + * layer request events, on a per-disk_devt basis, as input to the + * entropy pool. Note that high-speed solid state drives with very low + * seek times do not make for good sources of entropy, as their seek + * times are usually fairly consistent. * * All of these routines try to estimate how many bits of randomness a * particular randomness source. They do this by keeping track of the -- cgit v1.2.3 From 9f072429592d70b0f88c4d66f83735cc693a9870 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 19 Feb 2011 17:07:40 +0100 Subject: ax88796: fix codingstyle and checkpatch warnings Signed-off-by: Marc Kleine-Budde --- drivers/net/ax88796.c | 262 ++++++++++++++++++++++++++------------------------ 1 file changed, 134 insertions(+), 128 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index 4bebff3faeab..6d1d5ca112eb 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -9,7 +9,7 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. -*/ + */ #include #include @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -30,33 +31,32 @@ #include #include -#include -static int phy_debug = 0; +static int phy_debug; /* Rename the lib8390.c functions to show that they are in this driver */ -#define __ei_open ax_ei_open -#define __ei_close ax_ei_close -#define __ei_poll ax_ei_poll +#define __ei_open ax_ei_open +#define __ei_close ax_ei_close +#define __ei_poll ax_ei_poll #define __ei_start_xmit ax_ei_start_xmit #define __ei_tx_timeout ax_ei_tx_timeout -#define __ei_get_stats ax_ei_get_stats +#define __ei_get_stats ax_ei_get_stats #define __ei_set_multicast_list ax_ei_set_multicast_list -#define __ei_interrupt ax_ei_interrupt +#define __ei_interrupt ax_ei_interrupt #define ____alloc_ei_netdev ax__alloc_ei_netdev -#define __NS8390_init ax_NS8390_init +#define __NS8390_init ax_NS8390_init /* force unsigned long back to 'void __iomem *' */ #define ax_convert_addr(_a) ((void __force __iomem *)(_a)) -#define ei_inb(_a) readb(ax_convert_addr(_a)) +#define ei_inb(_a) readb(ax_convert_addr(_a)) #define ei_outb(_v, _a) writeb(_v, ax_convert_addr(_a)) -#define ei_inb_p(_a) ei_inb(_a) +#define ei_inb_p(_a) ei_inb(_a) #define ei_outb_p(_v, _a) ei_outb(_v, _a) /* define EI_SHIFT() to take into account our register offsets */ -#define EI_SHIFT(x) (ei_local->reg_offset[(x)]) +#define EI_SHIFT(x) (ei_local->reg_offset[(x)]) /* Ensure we have our RCR base value */ #define AX88796_PLATFORM @@ -74,43 +74,43 @@ static unsigned char version[] = "ax88796.c: Copyright 2005,2007 Simtec Electron #define NE_DATAPORT EI_SHIFT(0x10) #define NE1SM_START_PG 0x20 /* First page of TX buffer */ -#define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */ +#define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */ #define NESM_START_PG 0x40 /* First page of TX buffer */ #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ /* device private data */ struct ax_device { - struct timer_list mii_timer; - spinlock_t mii_lock; - struct mii_if_info mii; - - u32 msg_enable; - void __iomem *map2; - struct platform_device *dev; - struct resource *mem; - struct resource *mem2; - struct ax_plat_data *plat; - - unsigned char running; - unsigned char resume_open; - unsigned int irqflags; - - u32 reg_offsets[0x20]; + struct timer_list mii_timer; + spinlock_t mii_lock; + struct mii_if_info mii; + + u32 msg_enable; + void __iomem *map2; + struct platform_device *dev; + struct resource *mem; + struct resource *mem2; + struct ax_plat_data *plat; + + unsigned char running; + unsigned char resume_open; + unsigned int irqflags; + + u32 reg_offsets[0x20]; }; static inline struct ax_device *to_ax_dev(struct net_device *dev) { struct ei_device *ei_local = netdev_priv(dev); - return (struct ax_device *)(ei_local+1); + return (struct ax_device *)(ei_local + 1); } -/* ax_initial_check +/* + * ax_initial_check * * do an initial probe for the card to check wether it exists * and is functional */ - static int ax_initial_check(struct net_device *dev) { struct ei_device *ei_local = netdev_priv(dev); @@ -122,10 +122,10 @@ static int ax_initial_check(struct net_device *dev) if (reg0 == 0xFF) return -ENODEV; - ei_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD); + ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP, ioaddr + E8390_CMD); regd = ei_inb(ioaddr + 0x0d); ei_outb(0xff, ioaddr + 0x0d); - ei_outb(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD); + ei_outb(E8390_NODMA + E8390_PAGE0, ioaddr + E8390_CMD); ei_inb(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */ if (ei_inb(ioaddr + EN0_COUNTER0) != 0) { ei_outb(reg0, ioaddr); @@ -136,13 +136,14 @@ static int ax_initial_check(struct net_device *dev) return 0; } -/* Hard reset the card. This used to pause for the same period that a - 8390 reset command required, but that shouldn't be necessary. */ - +/* + * Hard reset the card. This used to pause for the same period that a + * 8390 reset command required, but that shouldn't be necessary. + */ static void ax_reset_8390(struct net_device *dev) { struct ei_device *ei_local = netdev_priv(dev); - struct ax_device *ax = to_ax_dev(dev); + struct ax_device *ax = to_ax_dev(dev); unsigned long reset_start_time = jiffies; void __iomem *addr = (void __iomem *)dev->base_addr; @@ -156,7 +157,7 @@ static void ax_reset_8390(struct net_device *dev) /* This check _should_not_ be necessary, omit eventually. */ while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) { - if (jiffies - reset_start_time > 2*HZ/100) { + if (jiffies - reset_start_time > 2 * HZ / 100) { dev_warn(&ax->dev->dev, "%s: %s did not complete.\n", __func__, dev->name); break; @@ -171,7 +172,7 @@ static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { struct ei_device *ei_local = netdev_priv(dev); - struct ax_device *ax = to_ax_dev(dev); + struct ax_device *ax = to_ax_dev(dev); void __iomem *nic_base = ei_local->mem; /* This *shouldn't* happen. If it does, it's the last thing you'll see */ @@ -184,7 +185,7 @@ static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, } ei_status.dmaing |= 0x01; - ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); + ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD); ei_outb(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); ei_outb(0, nic_base + EN0_RCNTHI); ei_outb(0, nic_base + EN0_RSARLO); /* On page boundary */ @@ -192,9 +193,11 @@ static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); if (ei_status.word16) - readsw(nic_base + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1); + readsw(nic_base + NE_DATAPORT, hdr, + sizeof(struct e8390_pkt_hdr) >> 1); else - readsb(nic_base + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)); + readsb(nic_base + NE_DATAPORT, hdr, + sizeof(struct e8390_pkt_hdr)); ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ ei_status.dmaing &= ~0x01; @@ -203,16 +206,18 @@ static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, } -/* Block input and output, similar to the Crynwr packet driver. If you - are porting to a new ethercard, look at the packet driver source for hints. - The NEx000 doesn't share the on-board packet memory -- you have to put - the packet out through the "remote DMA" dataport using ei_outb. */ - +/* + * Block input and output, similar to the Crynwr packet driver. If + * you are porting to a new ethercard, look at the packet driver + * source for hints. The NEx000 doesn't share the on-board packet + * memory -- you have to put the packet out through the "remote DMA" + * dataport using ei_outb. + */ static void ax_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { struct ei_device *ei_local = netdev_priv(dev); - struct ax_device *ax = to_ax_dev(dev); + struct ax_device *ax = to_ax_dev(dev); void __iomem *nic_base = ei_local->mem; char *buf = skb->data; @@ -227,7 +232,7 @@ static void ax_block_input(struct net_device *dev, int count, ei_status.dmaing |= 0x01; - ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); + ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base + NE_CMD); ei_outb(count & 0xff, nic_base + EN0_RCNTLO); ei_outb(count >> 8, nic_base + EN0_RCNTHI); ei_outb(ring_offset & 0xff, nic_base + EN0_RSARLO); @@ -250,14 +255,15 @@ static void ax_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page) { struct ei_device *ei_local = netdev_priv(dev); - struct ax_device *ax = to_ax_dev(dev); + struct ax_device *ax = to_ax_dev(dev); void __iomem *nic_base = ei_local->mem; unsigned long dma_start; - /* Round the count up for word writes. Do we need to do this? - What effect will an odd byte count have on the 8390? - I should check someday. */ - + /* + * Round the count up for word writes. Do we need to do this? + * What effect will an odd byte count have on the 8390? I + * should check someday. + */ if (ei_status.word16 && (count & 0x01)) count++; @@ -278,25 +284,24 @@ static void ax_block_output(struct net_device *dev, int count, /* Now the normal output. */ ei_outb(count & 0xff, nic_base + EN0_RCNTLO); - ei_outb(count >> 8, nic_base + EN0_RCNTHI); + ei_outb(count >> 8, nic_base + EN0_RCNTHI); ei_outb(0x00, nic_base + EN0_RSARLO); ei_outb(start_page, nic_base + EN0_RSARHI); ei_outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD); - if (ei_status.word16) { - writesw(nic_base + NE_DATAPORT, buf, count>>1); - } else { + if (ei_status.word16) + writesw(nic_base + NE_DATAPORT, buf, count >> 1); + else writesb(nic_base + NE_DATAPORT, buf, count); - } dma_start = jiffies; while ((ei_inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) { - if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ + if (jiffies - dma_start > 2 * HZ / 100) { /* 20ms */ dev_warn(&ax->dev->dev, "%s: timeout waiting for Tx RDC.\n", dev->name); ax_reset_8390(dev); - ax_NS8390_init(dev,1); + ax_NS8390_init(dev, 1); break; } } @@ -308,20 +313,20 @@ static void ax_block_output(struct net_device *dev, int count, /* definitions for accessing MII/EEPROM interface */ #define AX_MEMR EI_SHIFT(0x14) -#define AX_MEMR_MDC (1<<0) -#define AX_MEMR_MDIR (1<<1) -#define AX_MEMR_MDI (1<<2) -#define AX_MEMR_MDO (1<<3) -#define AX_MEMR_EECS (1<<4) -#define AX_MEMR_EEI (1<<5) -#define AX_MEMR_EEO (1<<6) -#define AX_MEMR_EECLK (1<<7) - -/* ax_mii_ei_outbits +#define AX_MEMR_MDC BIT(0) +#define AX_MEMR_MDIR BIT(1) +#define AX_MEMR_MDI BIT(2) +#define AX_MEMR_MDO BIT(3) +#define AX_MEMR_EECS BIT(4) +#define AX_MEMR_EEI BIT(5) +#define AX_MEMR_EEO BIT(6) +#define AX_MEMR_EECLK BIT(7) + +/* + * ax_mii_ei_outbits * * write the specified set of bits to the phy -*/ - + */ static void ax_mii_ei_outbits(struct net_device *dev, unsigned int bits, int len) { @@ -356,11 +361,11 @@ ax_mii_ei_outbits(struct net_device *dev, unsigned int bits, int len) ei_outb(memr, (void __iomem *)dev->base_addr + AX_MEMR); } -/* ax_phy_ei_inbits +/* + * ax_phy_ei_inbits * * read a specified number of bits from the phy -*/ - + */ static unsigned int ax_phy_ei_inbits(struct net_device *dev, int no) { @@ -381,7 +386,7 @@ ax_phy_ei_inbits(struct net_device *dev, int no) udelay(1); if (ei_inb(memr_addr) & AX_MEMR_MDI) - result |= (1<page_lock, flags); + spin_lock_irqsave(&ei_local->page_lock, flags); ax_phy_issueaddr(dev, phy_addr, reg, 2); result = ax_phy_ei_inbits(dev, 17); - result &= ~(3<<16); + result &= ~(3 << 16); - spin_unlock_irqrestore(&ei_local->page_lock, flags); + spin_unlock_irqrestore(&ei_local->page_lock, flags); if (phy_debug) pr_debug("%s: %04x.%04x => read %04x\n", __func__, @@ -436,25 +441,25 @@ static void ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value) { struct ei_device *ei = netdev_priv(dev); - struct ax_device *ax = to_ax_dev(dev); + struct ax_device *ax = to_ax_dev(dev); unsigned long flags; dev_dbg(&ax->dev->dev, "%s: %p, %04x, %04x %04x\n", __func__, dev, phy_addr, reg, value); - spin_lock_irqsave(&ei->page_lock, flags); + spin_lock_irqsave(&ei->page_lock, flags); ax_phy_issueaddr(dev, phy_addr, reg, 1); ax_mii_ei_outbits(dev, 2, 2); /* send TA */ ax_mii_ei_outbits(dev, value, 16); - spin_unlock_irqrestore(&ei->page_lock, flags); + spin_unlock_irqrestore(&ei->page_lock, flags); } static void ax_mii_expiry(unsigned long data) { struct net_device *dev = (struct net_device *)data; - struct ax_device *ax = to_ax_dev(dev); + struct ax_device *ax = to_ax_dev(dev); unsigned long flags; spin_lock_irqsave(&ax->mii_lock, flags); @@ -469,7 +474,7 @@ static void ax_mii_expiry(unsigned long data) static int ax_open(struct net_device *dev) { - struct ax_device *ax = to_ax_dev(dev); + struct ax_device *ax = to_ax_dev(dev); struct ei_device *ei_local = netdev_priv(dev); int ret; @@ -495,8 +500,8 @@ static int ax_open(struct net_device *dev) init_timer(&ax->mii_timer); - ax->mii_timer.expires = jiffies+1; - ax->mii_timer.data = (unsigned long) dev; + ax->mii_timer.expires = jiffies + 1; + ax->mii_timer.data = (unsigned long) dev; ax->mii_timer.function = ax_mii_expiry; add_timer(&ax->mii_timer); @@ -513,7 +518,7 @@ static int ax_close(struct net_device *dev) /* turn the phy off */ - ei_outb(ax->plat->gpoc_val | (1<<6), + ei_outb(ax->plat->gpoc_val | (1 << 6), ei_local->mem + EI_SHIFT(0x17)); ax->running = 0; @@ -640,7 +645,7 @@ static const struct net_device_ops ax_netdev_ops = { .ndo_get_stats = ax_ei_get_stats, .ndo_set_multicast_list = ax_ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ax_ei_poll, @@ -654,22 +659,22 @@ static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local) void __iomem *ioaddr = ei_local->mem; struct ax_device *ax = to_ax_dev(dev); - /* Select page 0*/ - ei_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, ioaddr + E8390_CMD); + /* Select page 0 */ + ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_STOP, ioaddr + E8390_CMD); /* set to byte access */ ei_outb(ax->plat->dcr_val & ~1, ioaddr + EN0_DCFG); ei_outb(ax->plat->gpoc_val, ioaddr + EI_SHIFT(0x17)); } -/* ax_init_dev +/* + * ax_init_dev * * initialise the specified device, taking care to note the MAC * address it may already have (if configured), ensure * the device is ready to be used by lib8390.c and registerd with * the network layer. */ - static int ax_init_dev(struct net_device *dev, int first_init) { struct ei_device *ei_local = netdev_priv(dev); @@ -693,16 +698,16 @@ static int ax_init_dev(struct net_device *dev, int first_init) if (first_init && ax->plat->flags & AXFLG_HAS_EEPROM) { unsigned char SA_prom[32]; - for(i = 0; i < sizeof(SA_prom); i+=2) { + for (i = 0; i < sizeof(SA_prom); i += 2) { SA_prom[i] = ei_inb(ioaddr + NE_DATAPORT); - SA_prom[i+1] = ei_inb(ioaddr + NE_DATAPORT); + SA_prom[i + 1] = ei_inb(ioaddr + NE_DATAPORT); } if (ax->plat->wordlength == 2) for (i = 0; i < 16; i++) SA_prom[i] = SA_prom[i+i]; - memcpy(dev->dev_addr, SA_prom, 6); + memcpy(dev->dev_addr, SA_prom, 6); } #ifdef CONFIG_AX88796_93CX6 @@ -719,7 +724,7 @@ static int ax_init_dev(struct net_device *dev, int first_init) (__le16 __force *)mac_addr, sizeof(mac_addr) >> 1); - memcpy(dev->dev_addr, mac_addr, 6); + memcpy(dev->dev_addr, mac_addr, 6); } #endif if (ax->plat->wordlength == 2) { @@ -732,9 +737,10 @@ static int ax_init_dev(struct net_device *dev, int first_init) stop_page = NE1SM_STOP_PG; } - /* load the mac-address from the device if this is the - * first time we've initialised */ - + /* + * load the mac-address from the device if this is the first + * time we've initialised + */ if (first_init) { if (ax->plat->flags & AXFLG_MAC_FROMDEV) { ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP, @@ -759,7 +765,7 @@ static int ax_init_dev(struct net_device *dev, int first_init) ei_status.rx_start_page = start_page + TX_PAGES; #ifdef PACKETBUF_MEMSIZE - /* Allow the packet buffer size to be overridden by know-it-alls. */ + /* Allow the packet buffer size to be overridden by know-it-alls. */ ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE; #endif @@ -769,8 +775,8 @@ static int ax_init_dev(struct net_device *dev, int first_init) ei_status.get_8390_hdr = &ax_get_8390_hdr; ei_status.priv = 0; - dev->netdev_ops = &ax_netdev_ops; - dev->ethtool_ops = &ax_ethtool_ops; + dev->netdev_ops = &ax_netdev_ops; + dev->ethtool_ops = &ax_ethtool_ops; ax->msg_enable = NETIF_MSG_LINK; ax->mii.phy_id_mask = 0x1f; @@ -786,7 +792,7 @@ static int ax_init_dev(struct net_device *dev, int first_init) if (first_init) dev_info(&ax->dev->dev, "%dbit, irq %d, %lx, MAC: %pM\n", - ei_status.word16 ? 16:8, dev->irq, dev->base_addr, + ei_status.word16 ? 16 : 8, dev->irq, dev->base_addr, dev->dev_addr); ret = register_netdev(dev); @@ -805,7 +811,7 @@ static int ax_init_dev(struct net_device *dev, int first_init) static int ax_remove(struct platform_device *_dev) { struct net_device *dev = platform_get_drvdata(_dev); - struct ax_device *ax; + struct ax_device *ax; ax = to_ax_dev(dev); @@ -827,18 +833,18 @@ static int ax_remove(struct platform_device *_dev) return 0; } -/* ax_probe +/* + * ax_probe * * This is the entry point when the platform device system uses to - * notify us of a new device to attach to. Allocate memory, find - * the resources and information passed, and map the necessary registers. -*/ - + * notify us of a new device to attach to. Allocate memory, find the + * resources and information passed, and map the necessary registers. + */ static int ax_probe(struct platform_device *pdev) { struct net_device *dev; - struct ax_device *ax; - struct resource *res; + struct ax_device *ax; + struct resource *res; size_t size; int ret = 0; @@ -857,10 +863,9 @@ static int ax_probe(struct platform_device *pdev) ax->plat = pdev->dev.platform_data; platform_set_drvdata(pdev, dev); - ei_status.rxcr_base = ax->plat->rcr_val; + ei_status.rxcr_base = ax->plat->rcr_val; /* find the platform resources */ - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { dev_err(&pdev->dev, "no IRQ specified\n"); @@ -880,9 +885,10 @@ static int ax_probe(struct platform_device *pdev) size = (res->end - res->start) + 1; - /* setup the register offsets from either the platform data - * or by using the size of the resource provided */ - + /* + * setup the register offsets from either the platform data or + * by using the size of the resource provided + */ if (ax->plat->reg_offsets) ei_status.reg_offset = ax->plat->reg_offsets; else { @@ -894,7 +900,7 @@ static int ax_probe(struct platform_device *pdev) ax->mem = request_mem_region(res->start, size, pdev->name); if (ax->mem == NULL) { dev_err(&pdev->dev, "cannot reserve registers\n"); - ret = -ENXIO; + ret = -ENXIO; goto exit_mem; } @@ -906,7 +912,7 @@ static int ax_probe(struct platform_device *pdev) (unsigned long long)res->start, (unsigned long long)res->end); - ret = -ENXIO; + ret = -ENXIO; goto exit_req; } @@ -921,7 +927,7 @@ static int ax_probe(struct platform_device *pdev) ax->map2 = NULL; } else { - size = (res->end - res->start) + 1; + size = (res->end - res->start) + 1; ax->mem2 = request_mem_region(res->start, size, pdev->name); if (ax->mem2 == NULL) { @@ -974,7 +980,7 @@ static int ax_probe(struct platform_device *pdev) static int ax_suspend(struct platform_device *dev, pm_message_t state) { struct net_device *ndev = platform_get_drvdata(dev); - struct ax_device *ax = to_ax_dev(ndev); + struct ax_device *ax = to_ax_dev(ndev); ax->resume_open = ax->running; @@ -987,7 +993,7 @@ static int ax_suspend(struct platform_device *dev, pm_message_t state) static int ax_resume(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); - struct ax_device *ax = to_ax_dev(ndev); + struct ax_device *ax = to_ax_dev(ndev); ax_initial_setup(ndev, netdev_priv(ndev)); ax_NS8390_init(ndev, ax->resume_open); @@ -1001,7 +1007,7 @@ static int ax_resume(struct platform_device *pdev) #else #define ax_suspend NULL -#define ax_resume NULL +#define ax_resume NULL #endif static struct platform_driver axdrv = { -- cgit v1.2.3 From ea5a43db0f7123c5cb459d8f77454534bc62de4f Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 19 Feb 2011 22:08:33 +0100 Subject: ax88796: don't use magic ei_status to acces private data Signed-off-by: Marc Kleine-Budde --- drivers/net/ax88796.c | 81 ++++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index 6d1d5ca112eb..c49c3b108133 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -152,8 +152,8 @@ static void ax_reset_8390(struct net_device *dev) ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET); - ei_status.txing = 0; - ei_status.dmaing = 0; + ei_local->txing = 0; + ei_local->dmaing = 0; /* This check _should_not_ be necessary, omit eventually. */ while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) { @@ -176,15 +176,15 @@ static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, void __iomem *nic_base = ei_local->mem; /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) { + if (ei_local->dmaing) { dev_err(&ax->dev->dev, "%s: DMAing conflict in %s " "[DMAstat:%d][irqlock:%d].\n", dev->name, __func__, - ei_status.dmaing, ei_status.irqlock); + ei_local->dmaing, ei_local->irqlock); return; } - ei_status.dmaing |= 0x01; + ei_local->dmaing |= 0x01; ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD); ei_outb(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); ei_outb(0, nic_base + EN0_RCNTHI); @@ -192,7 +192,7 @@ static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, ei_outb(ring_page, nic_base + EN0_RSARHI); ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); - if (ei_status.word16) + if (ei_local->word16) readsw(nic_base + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr) >> 1); else @@ -200,7 +200,7 @@ static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, sizeof(struct e8390_pkt_hdr)); ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x01; + ei_local->dmaing &= ~0x01; le16_to_cpus(&hdr->count); } @@ -221,16 +221,16 @@ static void ax_block_input(struct net_device *dev, int count, void __iomem *nic_base = ei_local->mem; char *buf = skb->data; - if (ei_status.dmaing) { + if (ei_local->dmaing) { dev_err(&ax->dev->dev, "%s: DMAing conflict in %s " "[DMAstat:%d][irqlock:%d].\n", dev->name, __func__, - ei_status.dmaing, ei_status.irqlock); + ei_local->dmaing, ei_local->irqlock); return; } - ei_status.dmaing |= 0x01; + ei_local->dmaing |= 0x01; ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base + NE_CMD); ei_outb(count & 0xff, nic_base + EN0_RCNTLO); @@ -239,7 +239,7 @@ static void ax_block_input(struct net_device *dev, int count, ei_outb(ring_offset >> 8, nic_base + EN0_RSARHI); ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); - if (ei_status.word16) { + if (ei_local->word16) { readsw(nic_base + NE_DATAPORT, buf, count >> 1); if (count & 0x01) buf[count-1] = ei_inb(nic_base + NE_DATAPORT); @@ -248,7 +248,7 @@ static void ax_block_input(struct net_device *dev, int count, readsb(nic_base + NE_DATAPORT, buf, count); } - ei_status.dmaing &= ~1; + ei_local->dmaing &= ~1; } static void ax_block_output(struct net_device *dev, int count, @@ -264,19 +264,19 @@ static void ax_block_output(struct net_device *dev, int count, * What effect will an odd byte count have on the 8390? I * should check someday. */ - if (ei_status.word16 && (count & 0x01)) + if (ei_local->word16 && (count & 0x01)) count++; /* This *shouldn't* happen. If it does, it's the last thing you'll see */ - if (ei_status.dmaing) { + if (ei_local->dmaing) { dev_err(&ax->dev->dev, "%s: DMAing conflict in %s." "[DMAstat:%d][irqlock:%d]\n", dev->name, __func__, - ei_status.dmaing, ei_status.irqlock); + ei_local->dmaing, ei_local->irqlock); return; } - ei_status.dmaing |= 0x01; + ei_local->dmaing |= 0x01; /* We should already be in page 0, but to be safe... */ ei_outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); @@ -289,7 +289,7 @@ static void ax_block_output(struct net_device *dev, int count, ei_outb(start_page, nic_base + EN0_RSARHI); ei_outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD); - if (ei_status.word16) + if (ei_local->word16) writesw(nic_base + NE_DATAPORT, buf, count >> 1); else writesb(nic_base + NE_DATAPORT, buf, count); @@ -307,7 +307,7 @@ static void ax_block_output(struct net_device *dev, int count, } ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ - ei_status.dmaing &= ~0x01; + ei_local->dmaing &= ~0x01; } /* definitions for accessing MII/EEPROM interface */ @@ -758,22 +758,22 @@ static int ax_init_dev(struct net_device *dev, int first_init) ax_reset_8390(dev); - ei_status.name = "AX88796"; - ei_status.tx_start_page = start_page; - ei_status.stop_page = stop_page; - ei_status.word16 = (ax->plat->wordlength == 2); - ei_status.rx_start_page = start_page + TX_PAGES; + ei_local->name = "AX88796"; + ei_local->tx_start_page = start_page; + ei_local->stop_page = stop_page; + ei_local->word16 = (ax->plat->wordlength == 2); + ei_local->rx_start_page = start_page + TX_PAGES; #ifdef PACKETBUF_MEMSIZE /* Allow the packet buffer size to be overridden by know-it-alls. */ - ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE; + ei_local->stop_page = ei_local->tx_start_page + PACKETBUF_MEMSIZE; #endif - ei_status.reset_8390 = &ax_reset_8390; - ei_status.block_input = &ax_block_input; - ei_status.block_output = &ax_block_output; - ei_status.get_8390_hdr = &ax_get_8390_hdr; - ei_status.priv = 0; + ei_local->reset_8390 = &ax_reset_8390; + ei_local->block_input = &ax_block_input; + ei_local->block_output = &ax_block_output; + ei_local->get_8390_hdr = &ax_get_8390_hdr; + ei_local->priv = 0; dev->netdev_ops = &ax_netdev_ops; dev->ethtool_ops = &ax_ethtool_ops; @@ -792,7 +792,7 @@ static int ax_init_dev(struct net_device *dev, int first_init) if (first_init) dev_info(&ax->dev->dev, "%dbit, irq %d, %lx, MAC: %pM\n", - ei_status.word16 ? 16 : 8, dev->irq, dev->base_addr, + ei_local->word16 ? 16 : 8, dev->irq, dev->base_addr, dev->dev_addr); ret = register_netdev(dev); @@ -811,6 +811,7 @@ static int ax_init_dev(struct net_device *dev, int first_init) static int ax_remove(struct platform_device *_dev) { struct net_device *dev = platform_get_drvdata(_dev); + struct ei_device *ei_local = netdev_priv(dev); struct ax_device *ax; ax = to_ax_dev(dev); @@ -818,7 +819,7 @@ static int ax_remove(struct platform_device *_dev) unregister_netdev(dev); free_irq(dev->irq, dev); - iounmap(ei_status.mem); + iounmap(ei_local->mem); release_resource(ax->mem); kfree(ax->mem); @@ -843,6 +844,7 @@ static int ax_remove(struct platform_device *_dev) static int ax_probe(struct platform_device *pdev) { struct net_device *dev; + struct ei_device *ei_local; struct ax_device *ax; struct resource *res; size_t size; @@ -853,6 +855,7 @@ static int ax_probe(struct platform_device *pdev) return -ENOMEM; /* ok, let's setup our device */ + ei_local = netdev_priv(dev); ax = to_ax_dev(dev); memset(ax, 0, sizeof(struct ax_device)); @@ -863,7 +866,7 @@ static int ax_probe(struct platform_device *pdev) ax->plat = pdev->dev.platform_data; platform_set_drvdata(pdev, dev); - ei_status.rxcr_base = ax->plat->rcr_val; + ei_local->rxcr_base = ax->plat->rcr_val; /* find the platform resources */ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); @@ -890,9 +893,9 @@ static int ax_probe(struct platform_device *pdev) * by using the size of the resource provided */ if (ax->plat->reg_offsets) - ei_status.reg_offset = ax->plat->reg_offsets; + ei_local->reg_offset = ax->plat->reg_offsets; else { - ei_status.reg_offset = ax->reg_offsets; + ei_local->reg_offset = ax->reg_offsets; for (ret = 0; ret < 0x18; ret++) ax->reg_offsets[ret] = (size / 0x18) * ret; } @@ -904,10 +907,10 @@ static int ax_probe(struct platform_device *pdev) goto exit_mem; } - ei_status.mem = ioremap(res->start, size); - dev->base_addr = (unsigned long)ei_status.mem; + ei_local->mem = ioremap(res->start, size); + dev->base_addr = (unsigned long)ei_local->mem; - if (ei_status.mem == NULL) { + if (ei_local->mem == NULL) { dev_err(&pdev->dev, "Cannot ioremap area (%08llx,%08llx)\n", (unsigned long long)res->start, (unsigned long long)res->end); @@ -943,7 +946,7 @@ static int ax_probe(struct platform_device *pdev) goto exit_mem2; } - ei_status.reg_offset[0x1f] = ax->map2 - ei_status.mem; + ei_local->reg_offset[0x1f] = ax->map2 - ei_local->mem; } /* got resources, now initialise and register device */ @@ -962,7 +965,7 @@ static int ax_probe(struct platform_device *pdev) kfree(ax->mem2); exit_mem1: - iounmap(ei_status.mem); + iounmap(ei_local->mem); exit_req: release_resource(ax->mem); -- cgit v1.2.3 From 2f9709dbdf2777c88b7f1f9a8283119f17f7373e Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 19 Feb 2011 22:12:27 +0100 Subject: ax88796: remove memset of private data It's allocated via alloc_netdev, thus already zeroed. Signed-off-by: Marc Kleine-Budde --- drivers/net/ax88796.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index c49c3b108133..885f04ec1518 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -858,8 +858,6 @@ static int ax_probe(struct platform_device *pdev) ei_local = netdev_priv(dev); ax = to_ax_dev(dev); - memset(ax, 0, sizeof(struct ax_device)); - spin_lock_init(&ax->mii_lock); ax->dev = pdev; -- cgit v1.2.3 From 1cbece33ff657cfc9782963d502f3c3be07c0317 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sat, 19 Feb 2011 23:07:09 +0100 Subject: ax88796: remove first_init parameter from ax_init_dev() ax_init_dev() is always called with first_init=1. Signed-off-by: Marc Kleine-Budde --- drivers/net/ax88796.c | 44 +++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index 885f04ec1518..eac5b101beb7 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -675,7 +675,7 @@ static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local) * the device is ready to be used by lib8390.c and registerd with * the network layer. */ -static int ax_init_dev(struct net_device *dev, int first_init) +static int ax_init_dev(struct net_device *dev) { struct ei_device *ei_local = netdev_priv(dev); struct ax_device *ax = to_ax_dev(dev); @@ -695,7 +695,7 @@ static int ax_init_dev(struct net_device *dev, int first_init) /* read the mac from the card prom if we need it */ - if (first_init && ax->plat->flags & AXFLG_HAS_EEPROM) { + if (ax->plat->flags & AXFLG_HAS_EEPROM) { unsigned char SA_prom[32]; for (i = 0; i < sizeof(SA_prom); i += 2) { @@ -711,7 +711,7 @@ static int ax_init_dev(struct net_device *dev, int first_init) } #ifdef CONFIG_AX88796_93CX6 - if (first_init && ax->plat->flags & AXFLG_HAS_93CX6) { + if (ax->plat->flags & AXFLG_HAS_93CX6) { unsigned char mac_addr[6]; struct eeprom_93cx6 eeprom; @@ -737,25 +737,20 @@ static int ax_init_dev(struct net_device *dev, int first_init) stop_page = NE1SM_STOP_PG; } - /* - * load the mac-address from the device if this is the first - * time we've initialised - */ - if (first_init) { - if (ax->plat->flags & AXFLG_MAC_FROMDEV) { - ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP, - ei_local->mem + E8390_CMD); /* 0x61 */ - for (i = 0; i < ETHER_ADDR_LEN; i++) - dev->dev_addr[i] = - ei_inb(ioaddr + EN1_PHYS_SHIFT(i)); - } - - if ((ax->plat->flags & AXFLG_MAC_FROMPLATFORM) && - ax->plat->mac_addr) - memcpy(dev->dev_addr, ax->plat->mac_addr, - ETHER_ADDR_LEN); + /* load the mac-address from the device */ + if (ax->plat->flags & AXFLG_MAC_FROMDEV) { + ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP, + ei_local->mem + E8390_CMD); /* 0x61 */ + for (i = 0; i < ETHER_ADDR_LEN; i++) + dev->dev_addr[i] = + ei_inb(ioaddr + EN1_PHYS_SHIFT(i)); } + if ((ax->plat->flags & AXFLG_MAC_FROMPLATFORM) && + ax->plat->mac_addr) + memcpy(dev->dev_addr, ax->plat->mac_addr, + ETHER_ADDR_LEN); + ax_reset_8390(dev); ei_local->name = "AX88796"; @@ -790,10 +785,9 @@ static int ax_init_dev(struct net_device *dev, int first_init) ax_NS8390_init(dev, 0); - if (first_init) - dev_info(&ax->dev->dev, "%dbit, irq %d, %lx, MAC: %pM\n", - ei_local->word16 ? 16 : 8, dev->irq, dev->base_addr, - dev->dev_addr); + dev_info(&ax->dev->dev, "%dbit, irq %d, %lx, MAC: %pM\n", + ei_local->word16 ? 16 : 8, dev->irq, dev->base_addr, + dev->dev_addr); ret = register_netdev(dev); if (ret) @@ -949,7 +943,7 @@ static int ax_probe(struct platform_device *pdev) /* got resources, now initialise and register device */ - ret = ax_init_dev(dev, 1); + ret = ax_init_dev(dev); if (!ret) return 0; -- cgit v1.2.3 From 85ac6162c94638c7f27afa4bf63f165a6ca5e931 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sun, 20 Feb 2011 17:46:18 +0100 Subject: ax88796: use netdev_ instead of dev_ and pr_ Signed-off-by: Marc Kleine-Budde --- drivers/net/ax88796.c | 46 ++++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index eac5b101beb7..1370cac6d6c0 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -143,12 +143,11 @@ static int ax_initial_check(struct net_device *dev) static void ax_reset_8390(struct net_device *dev) { struct ei_device *ei_local = netdev_priv(dev); - struct ax_device *ax = to_ax_dev(dev); unsigned long reset_start_time = jiffies; void __iomem *addr = (void __iomem *)dev->base_addr; if (ei_debug > 1) - dev_dbg(&ax->dev->dev, "resetting the 8390 t=%ld\n", jiffies); + netdev_dbg(dev, "resetting the 8390 t=%ld\n", jiffies); ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET); @@ -158,8 +157,7 @@ static void ax_reset_8390(struct net_device *dev) /* This check _should_not_ be necessary, omit eventually. */ while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) { if (jiffies - reset_start_time > 2 * HZ / 100) { - dev_warn(&ax->dev->dev, "%s: %s did not complete.\n", - __func__, dev->name); + netdev_warn(dev, "%s: did not complete.\n", __func__); break; } } @@ -172,14 +170,13 @@ static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { struct ei_device *ei_local = netdev_priv(dev); - struct ax_device *ax = to_ax_dev(dev); void __iomem *nic_base = ei_local->mem; /* This *shouldn't* happen. If it does, it's the last thing you'll see */ if (ei_local->dmaing) { - dev_err(&ax->dev->dev, "%s: DMAing conflict in %s " + netdev_err(dev, "DMAing conflict in %s " "[DMAstat:%d][irqlock:%d].\n", - dev->name, __func__, + __func__, ei_local->dmaing, ei_local->irqlock); return; } @@ -217,15 +214,14 @@ static void ax_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { struct ei_device *ei_local = netdev_priv(dev); - struct ax_device *ax = to_ax_dev(dev); void __iomem *nic_base = ei_local->mem; char *buf = skb->data; if (ei_local->dmaing) { - dev_err(&ax->dev->dev, - "%s: DMAing conflict in %s " + netdev_err(dev, + "DMAing conflict in %s " "[DMAstat:%d][irqlock:%d].\n", - dev->name, __func__, + __func__, ei_local->dmaing, ei_local->irqlock); return; } @@ -255,7 +251,6 @@ static void ax_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page) { struct ei_device *ei_local = netdev_priv(dev); - struct ax_device *ax = to_ax_dev(dev); void __iomem *nic_base = ei_local->mem; unsigned long dma_start; @@ -269,9 +264,9 @@ static void ax_block_output(struct net_device *dev, int count, /* This *shouldn't* happen. If it does, it's the last thing you'll see */ if (ei_local->dmaing) { - dev_err(&ax->dev->dev, "%s: DMAing conflict in %s." + netdev_err(dev, "DMAing conflict in %s." "[DMAstat:%d][irqlock:%d]\n", - dev->name, __func__, + __func__, ei_local->dmaing, ei_local->irqlock); return; } @@ -298,8 +293,7 @@ static void ax_block_output(struct net_device *dev, int count, while ((ei_inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) { if (jiffies - dma_start > 2 * HZ / 100) { /* 20ms */ - dev_warn(&ax->dev->dev, - "%s: timeout waiting for Tx RDC.\n", dev->name); + netdev_warn(dev, "timeout waiting for Tx RDC.\n"); ax_reset_8390(dev); ax_NS8390_init(dev, 1); break; @@ -404,7 +398,7 @@ static void ax_phy_issueaddr(struct net_device *dev, int phy_addr, int reg, int opc) { if (phy_debug) - pr_debug("%s: dev %p, %04x, %04x, %d\n", + netdev_dbg(dev, "%s: dev %p, %04x, %04x, %d\n", __func__, dev, phy_addr, reg, opc); ax_mii_ei_outbits(dev, 0x3f, 6); /* pre-amble */ @@ -431,7 +425,7 @@ ax_phy_read(struct net_device *dev, int phy_addr, int reg) spin_unlock_irqrestore(&ei_local->page_lock, flags); if (phy_debug) - pr_debug("%s: %04x.%04x => read %04x\n", __func__, + netdev_dbg(dev, "%s: %04x.%04x => read %04x\n", __func__, phy_addr, reg, result); return result; @@ -441,10 +435,9 @@ static void ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value) { struct ei_device *ei = netdev_priv(dev); - struct ax_device *ax = to_ax_dev(dev); unsigned long flags; - dev_dbg(&ax->dev->dev, "%s: %p, %04x, %04x %04x\n", + netdev_dbg(dev, "%s: %p, %04x, %04x %04x\n", __func__, dev, phy_addr, reg, value); spin_lock_irqsave(&ei->page_lock, flags); @@ -478,7 +471,7 @@ static int ax_open(struct net_device *dev) struct ei_device *ei_local = netdev_priv(dev); int ret; - dev_dbg(&ax->dev->dev, "%s: open\n", dev->name); + netdev_dbg(dev, "open\n"); ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags, dev->name, dev); @@ -514,7 +507,7 @@ static int ax_close(struct net_device *dev) struct ax_device *ax = to_ax_dev(dev); struct ei_device *ei_local = netdev_priv(dev); - dev_dbg(&ax->dev->dev, "%s: close\n", dev->name); + netdev_dbg(dev, "close\n"); /* turn the phy off */ @@ -785,14 +778,14 @@ static int ax_init_dev(struct net_device *dev) ax_NS8390_init(dev, 0); - dev_info(&ax->dev->dev, "%dbit, irq %d, %lx, MAC: %pM\n", - ei_local->word16 ? 16 : 8, dev->irq, dev->base_addr, - dev->dev_addr); - ret = register_netdev(dev); if (ret) goto out_irq; + netdev_info(dev, "%dbit, irq %d, %lx, MAC: %pM\n", + ei_local->word16 ? 16 : 8, dev->irq, dev->base_addr, + dev->dev_addr); + return 0; out_irq: @@ -849,6 +842,7 @@ static int ax_probe(struct platform_device *pdev) return -ENOMEM; /* ok, let's setup our device */ + SET_NETDEV_DEV(dev, &pdev->dev); ei_local = netdev_priv(dev); ax = to_ax_dev(dev); -- cgit v1.2.3 From 0f442f5a3c25dd4df3fecb25819dc269c9222bdf Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sun, 20 Feb 2011 19:13:20 +0100 Subject: ax88796: remove platform_device member from struct ax_device Signed-off-by: Marc Kleine-Budde --- drivers/net/ax88796.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index 1370cac6d6c0..782d73e0b659 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -87,7 +87,6 @@ struct ax_device { u32 msg_enable; void __iomem *map2; - struct platform_device *dev; struct resource *mem; struct resource *mem2; struct ax_plat_data *plat; @@ -545,11 +544,11 @@ static int ax_ioctl(struct net_device *dev, struct ifreq *req, int cmd) static void ax_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - struct ax_device *ax = to_ax_dev(dev); + struct platform_device *pdev = to_platform_device(dev->dev.parent); strcpy(info->driver, DRV_NAME); strcpy(info->version, DRV_VERSION); - strcpy(info->bus_info, ax->dev->name); + strcpy(info->bus_info, pdev->name); } static int ax_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) @@ -848,7 +847,6 @@ static int ax_probe(struct platform_device *pdev) spin_lock_init(&ax->mii_lock); - ax->dev = pdev; ax->plat = pdev->dev.platform_data; platform_set_drvdata(pdev, dev); -- cgit v1.2.3 From a54dc58511644a22ae0d57d857e154cddf6d7926 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 21 Feb 2011 10:43:31 +0100 Subject: ax88796: make pointer to platform data const Signed-off-by: Marc Kleine-Budde --- drivers/net/ax88796.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index 782d73e0b659..fd289e52b2ec 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -89,7 +89,7 @@ struct ax_device { void __iomem *map2; struct resource *mem; struct resource *mem2; - struct ax_plat_data *plat; + const struct ax_plat_data *plat; unsigned char running; unsigned char resume_open; -- cgit v1.2.3 From c9218c3a8231c0a67662d85266698f2f037cac20 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 21 Feb 2011 11:24:39 +0100 Subject: ax88796: clean up probe and remove function This way we can remove the struct resource pointers from the private data. Signed-off-by: Marc Kleine-Budde --- drivers/net/ax88796.c | 75 +++++++++++++++++++++------------------------------ 1 file changed, 31 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index fd289e52b2ec..e62d0ba891e8 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -87,8 +87,6 @@ struct ax_device { u32 msg_enable; void __iomem *map2; - struct resource *mem; - struct resource *mem2; const struct ax_plat_data *plat; unsigned char running; @@ -794,25 +792,24 @@ static int ax_init_dev(struct net_device *dev) return ret; } -static int ax_remove(struct platform_device *_dev) +static int ax_remove(struct platform_device *pdev) { - struct net_device *dev = platform_get_drvdata(_dev); + struct net_device *dev = platform_get_drvdata(pdev); struct ei_device *ei_local = netdev_priv(dev); - struct ax_device *ax; - - ax = to_ax_dev(dev); + struct ax_device *ax = to_ax_dev(dev); + struct resource *mem; unregister_netdev(dev); free_irq(dev->irq, dev); iounmap(ei_local->mem); - release_resource(ax->mem); - kfree(ax->mem); + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(mem->start, resource_size(mem)); if (ax->map2) { iounmap(ax->map2); - release_resource(ax->mem2); - kfree(ax->mem2); + mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); + release_mem_region(mem->start, resource_size(mem)); } free_netdev(dev); @@ -832,8 +829,8 @@ static int ax_probe(struct platform_device *pdev) struct net_device *dev; struct ei_device *ei_local; struct ax_device *ax; - struct resource *res; - size_t size; + struct resource *irq, *mem, *mem2; + resource_size_t mem_size, mem2_size = 0; int ret = 0; dev = ax__alloc_ei_netdev(sizeof(struct ax_device)); @@ -853,24 +850,24 @@ static int ax_probe(struct platform_device *pdev) ei_local->rxcr_base = ax->plat->rcr_val; /* find the platform resources */ - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (res == NULL) { + irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!irq) { dev_err(&pdev->dev, "no IRQ specified\n"); ret = -ENXIO; goto exit_mem; } - dev->irq = res->start; - ax->irqflags = res->flags & IRQF_TRIGGER_MASK; + dev->irq = irq->start; + ax->irqflags = irq->flags & IRQF_TRIGGER_MASK; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) { + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) { dev_err(&pdev->dev, "no MEM specified\n"); ret = -ENXIO; goto exit_mem; } - size = (res->end - res->start) + 1; + mem_size = resource_size(mem); /* * setup the register offsets from either the platform data or @@ -881,50 +878,43 @@ static int ax_probe(struct platform_device *pdev) else { ei_local->reg_offset = ax->reg_offsets; for (ret = 0; ret < 0x18; ret++) - ax->reg_offsets[ret] = (size / 0x18) * ret; + ax->reg_offsets[ret] = (mem_size / 0x18) * ret; } - ax->mem = request_mem_region(res->start, size, pdev->name); - if (ax->mem == NULL) { + if (!request_mem_region(mem->start, mem_size, pdev->name)) { dev_err(&pdev->dev, "cannot reserve registers\n"); ret = -ENXIO; goto exit_mem; } - ei_local->mem = ioremap(res->start, size); + ei_local->mem = ioremap(mem->start, mem_size); dev->base_addr = (unsigned long)ei_local->mem; if (ei_local->mem == NULL) { - dev_err(&pdev->dev, "Cannot ioremap area (%08llx,%08llx)\n", - (unsigned long long)res->start, - (unsigned long long)res->end); + dev_err(&pdev->dev, "Cannot ioremap area %pR\n", mem); ret = -ENXIO; goto exit_req; } /* look for reset area */ - - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (res == NULL) { + mem2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!mem2) { if (!ax->plat->reg_offsets) { for (ret = 0; ret < 0x20; ret++) - ax->reg_offsets[ret] = (size / 0x20) * ret; + ax->reg_offsets[ret] = (mem_size / 0x20) * ret; } - - ax->map2 = NULL; } else { - size = (res->end - res->start) + 1; + mem2_size = resource_size(mem2); - ax->mem2 = request_mem_region(res->start, size, pdev->name); - if (ax->mem2 == NULL) { + if (!request_mem_region(mem2->start, mem2_size, pdev->name)) { dev_err(&pdev->dev, "cannot reserve registers\n"); ret = -ENXIO; goto exit_mem1; } - ax->map2 = ioremap(res->start, size); - if (ax->map2 == NULL) { + ax->map2 = ioremap(mem2->start, mem2_size); + if (!ax->map2) { dev_err(&pdev->dev, "cannot map reset register\n"); ret = -ENXIO; goto exit_mem2; @@ -934,26 +924,23 @@ static int ax_probe(struct platform_device *pdev) } /* got resources, now initialise and register device */ - ret = ax_init_dev(dev); if (!ret) return 0; - if (ax->map2 == NULL) + if (!ax->map2) goto exit_mem1; iounmap(ax->map2); exit_mem2: - release_resource(ax->mem2); - kfree(ax->mem2); + release_mem_region(mem2->start, mem2_size); exit_mem1: iounmap(ei_local->mem); exit_req: - release_resource(ax->mem); - kfree(ax->mem); + release_mem_region(mem->start, mem_size); exit_mem: free_netdev(dev); -- cgit v1.2.3 From f6d7f2c60d3a63d786feeb60628f930cd2d8e912 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 21 Feb 2011 12:41:55 +0100 Subject: ax88796: use generic mdio_bitbang driver ..instead of using hand-crafted and not proper working version. Signed-off-by: Marc Kleine-Budde --- drivers/net/Kconfig | 4 +- drivers/net/ax88796.c | 392 +++++++++++++++++++++++++------------------------- 2 files changed, 196 insertions(+), 200 deletions(-) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 65027a72ca93..f4b39274308a 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -238,8 +238,8 @@ source "drivers/net/arm/Kconfig" config AX88796 tristate "ASIX AX88796 NE2000 clone support" depends on ARM || MIPS || SUPERH - select CRC32 - select MII + select PHYLIB + select MDIO_BITBANG help AX88796 driver, using platform bus to provide chip detection and resources diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index e62d0ba891e8..e7cb8c8b9776 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -24,7 +24,8 @@ #include #include #include -#include +#include +#include #include #include @@ -32,8 +33,6 @@ #include -static int phy_debug; - /* Rename the lib8390.c functions to show that they are in this driver */ #define __ei_open ax_ei_open #define __ei_close ax_ei_close @@ -78,14 +77,20 @@ static unsigned char version[] = "ax88796.c: Copyright 2005,2007 Simtec Electron #define NESM_START_PG 0x40 /* First page of TX buffer */ #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ +#define AX_GPOC_PPDSET BIT(6) + /* device private data */ struct ax_device { - struct timer_list mii_timer; - spinlock_t mii_lock; - struct mii_if_info mii; + struct mii_bus *mii_bus; + struct mdiobb_ctrl bb_ctrl; + struct phy_device *phy_dev; + void __iomem *addr_memr; + u8 reg_memr; + int link; + int speed; + int duplex; - u32 msg_enable; void __iomem *map2; const struct ax_plat_data *plat; @@ -313,159 +318,84 @@ static void ax_block_output(struct net_device *dev, int count, #define AX_MEMR_EEO BIT(6) #define AX_MEMR_EECLK BIT(7) -/* - * ax_mii_ei_outbits - * - * write the specified set of bits to the phy - */ -static void -ax_mii_ei_outbits(struct net_device *dev, unsigned int bits, int len) +static void ax_handle_link_change(struct net_device *dev) { - struct ei_device *ei_local = netdev_priv(dev); - void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR; - unsigned int memr; - - /* clock low, data to output mode */ - memr = ei_inb(memr_addr); - memr &= ~(AX_MEMR_MDC | AX_MEMR_MDIR); - ei_outb(memr, memr_addr); - - for (len--; len >= 0; len--) { - if (bits & (1 << len)) - memr |= AX_MEMR_MDO; - else - memr &= ~AX_MEMR_MDO; + struct ax_device *ax = to_ax_dev(dev); + struct phy_device *phy_dev = ax->phy_dev; + int status_change = 0; - ei_outb(memr, memr_addr); + if (phy_dev->link && ((ax->speed != phy_dev->speed) || + (ax->duplex != phy_dev->duplex))) { - /* clock high */ - - ei_outb(memr | AX_MEMR_MDC, memr_addr); - udelay(1); - - /* clock low */ - ei_outb(memr, memr_addr); + ax->speed = phy_dev->speed; + ax->duplex = phy_dev->duplex; + status_change = 1; } - /* leaves the clock line low, mdir input */ - memr |= AX_MEMR_MDIR; - ei_outb(memr, (void __iomem *)dev->base_addr + AX_MEMR); -} - -/* - * ax_phy_ei_inbits - * - * read a specified number of bits from the phy - */ -static unsigned int -ax_phy_ei_inbits(struct net_device *dev, int no) -{ - struct ei_device *ei_local = netdev_priv(dev); - void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR; - unsigned int memr; - unsigned int result = 0; - - /* clock low, data to input mode */ - memr = ei_inb(memr_addr); - memr &= ~AX_MEMR_MDC; - memr |= AX_MEMR_MDIR; - ei_outb(memr, memr_addr); - - for (no--; no >= 0; no--) { - ei_outb(memr | AX_MEMR_MDC, memr_addr); - - udelay(1); - - if (ei_inb(memr_addr) & AX_MEMR_MDI) - result |= (1 << no); + if (phy_dev->link != ax->link) { + if (!phy_dev->link) { + ax->speed = 0; + ax->duplex = -1; + } + ax->link = phy_dev->link; - ei_outb(memr, memr_addr); + status_change = 1; } - return result; + if (status_change) + phy_print_status(phy_dev); } -/* - * ax_phy_issueaddr - * - * use the low level bit shifting routines to send the address - * and command to the specified phy - */ -static void -ax_phy_issueaddr(struct net_device *dev, int phy_addr, int reg, int opc) -{ - if (phy_debug) - netdev_dbg(dev, "%s: dev %p, %04x, %04x, %d\n", - __func__, dev, phy_addr, reg, opc); - - ax_mii_ei_outbits(dev, 0x3f, 6); /* pre-amble */ - ax_mii_ei_outbits(dev, 1, 2); /* frame-start */ - ax_mii_ei_outbits(dev, opc, 2); /* op code */ - ax_mii_ei_outbits(dev, phy_addr, 5); /* phy address */ - ax_mii_ei_outbits(dev, reg, 5); /* reg address */ -} - -static int -ax_phy_read(struct net_device *dev, int phy_addr, int reg) +static int ax_mii_probe(struct net_device *dev) { - struct ei_device *ei_local = netdev_priv(dev); - unsigned long flags; - unsigned int result; - - spin_lock_irqsave(&ei_local->page_lock, flags); - - ax_phy_issueaddr(dev, phy_addr, reg, 2); - - result = ax_phy_ei_inbits(dev, 17); - result &= ~(3 << 16); - - spin_unlock_irqrestore(&ei_local->page_lock, flags); - - if (phy_debug) - netdev_dbg(dev, "%s: %04x.%04x => read %04x\n", __func__, - phy_addr, reg, result); + struct ax_device *ax = to_ax_dev(dev); + struct phy_device *phy_dev = NULL; + int ret; - return result; -} + /* find the first phy */ + phy_dev = phy_find_first(ax->mii_bus); + if (!phy_dev) { + netdev_err(dev, "no PHY found\n"); + return -ENODEV; + } -static void -ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value) -{ - struct ei_device *ei = netdev_priv(dev); - unsigned long flags; + ret = phy_connect_direct(dev, phy_dev, ax_handle_link_change, 0, + PHY_INTERFACE_MODE_MII); + if (ret) { + netdev_err(dev, "Could not attach to PHY\n"); + return ret; + } - netdev_dbg(dev, "%s: %p, %04x, %04x %04x\n", - __func__, dev, phy_addr, reg, value); + /* mask with MAC supported features */ + phy_dev->supported &= PHY_BASIC_FEATURES; + phy_dev->advertising = phy_dev->supported; - spin_lock_irqsave(&ei->page_lock, flags); + ax->phy_dev = phy_dev; - ax_phy_issueaddr(dev, phy_addr, reg, 1); - ax_mii_ei_outbits(dev, 2, 2); /* send TA */ - ax_mii_ei_outbits(dev, value, 16); + netdev_info(dev, "PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", + phy_dev->drv->name, dev_name(&phy_dev->dev), phy_dev->irq); - spin_unlock_irqrestore(&ei->page_lock, flags); + return 0; } -static void ax_mii_expiry(unsigned long data) +static void ax_phy_switch(struct net_device *dev, int on) { - struct net_device *dev = (struct net_device *)data; + struct ei_device *ei_local = netdev_priv(dev); struct ax_device *ax = to_ax_dev(dev); - unsigned long flags; - spin_lock_irqsave(&ax->mii_lock, flags); - mii_check_media(&ax->mii, netif_msg_link(ax), 0); - spin_unlock_irqrestore(&ax->mii_lock, flags); + u8 reg_gpoc = ax->plat->gpoc_val; - if (ax->running) { - ax->mii_timer.expires = jiffies + HZ*2; - add_timer(&ax->mii_timer); - } + if (!!on) + reg_gpoc &= ~AX_GPOC_PPDSET; + else + reg_gpoc |= AX_GPOC_PPDSET; + + ei_outb(reg_gpoc, ei_local->mem + EI_SHIFT(0x17)); } static int ax_open(struct net_device *dev) { struct ax_device *ax = to_ax_dev(dev); - struct ei_device *ei_local = netdev_priv(dev); int ret; netdev_dbg(dev, "open\n"); @@ -473,50 +403,48 @@ static int ax_open(struct net_device *dev) ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags, dev->name, dev); if (ret) - return ret; - - ret = ax_ei_open(dev); - if (ret) { - free_irq(dev->irq, dev); - return ret; - } + goto failed_request_irq; /* turn the phy on (if turned off) */ + ax_phy_switch(dev, 1); - ei_outb(ax->plat->gpoc_val, ei_local->mem + EI_SHIFT(0x17)); - ax->running = 1; - - /* start the MII timer */ - - init_timer(&ax->mii_timer); + ret = ax_mii_probe(dev); + if (ret) + goto failed_mii_probe; + phy_start(ax->phy_dev); - ax->mii_timer.expires = jiffies + 1; - ax->mii_timer.data = (unsigned long) dev; - ax->mii_timer.function = ax_mii_expiry; + ret = ax_ei_open(dev); + if (ret) + goto failed_ax_ei_open; - add_timer(&ax->mii_timer); + ax->running = 1; return 0; + + failed_ax_ei_open: + phy_disconnect(ax->phy_dev); + failed_mii_probe: + ax_phy_switch(dev, 0); + free_irq(dev->irq, dev); + failed_request_irq: + return ret; } static int ax_close(struct net_device *dev) { struct ax_device *ax = to_ax_dev(dev); - struct ei_device *ei_local = netdev_priv(dev); netdev_dbg(dev, "close\n"); - /* turn the phy off */ - - ei_outb(ax->plat->gpoc_val | (1 << 6), - ei_local->mem + EI_SHIFT(0x17)); - ax->running = 0; wmb(); - del_timer_sync(&ax->mii_timer); ax_ei_close(dev); + /* turn the phy off */ + ax_phy_switch(dev, 0); + phy_disconnect(ax->phy_dev); + free_irq(dev->irq, dev); return 0; } @@ -524,17 +452,15 @@ static int ax_close(struct net_device *dev) static int ax_ioctl(struct net_device *dev, struct ifreq *req, int cmd) { struct ax_device *ax = to_ax_dev(dev); - unsigned long flags; - int rc; + struct phy_device *phy_dev = ax->phy_dev; if (!netif_running(dev)) return -EINVAL; - spin_lock_irqsave(&ax->mii_lock, flags); - rc = generic_mii_ioctl(&ax->mii, if_mii(req), cmd, NULL); - spin_unlock_irqrestore(&ax->mii_lock, flags); + if (!phy_dev) + return -ENODEV; - return rc; + return phy_mii_ioctl(phy_dev, req, cmd); } /* ethtool ops */ @@ -552,46 +478,30 @@ static void ax_get_drvinfo(struct net_device *dev, static int ax_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct ax_device *ax = to_ax_dev(dev); - unsigned long flags; + struct phy_device *phy_dev = ax->phy_dev; - spin_lock_irqsave(&ax->mii_lock, flags); - mii_ethtool_gset(&ax->mii, cmd); - spin_unlock_irqrestore(&ax->mii_lock, flags); + if (!phy_dev) + return -ENODEV; - return 0; + return phy_ethtool_gset(phy_dev, cmd); } static int ax_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct ax_device *ax = to_ax_dev(dev); - unsigned long flags; - int rc; - - spin_lock_irqsave(&ax->mii_lock, flags); - rc = mii_ethtool_sset(&ax->mii, cmd); - spin_unlock_irqrestore(&ax->mii_lock, flags); + struct phy_device *phy_dev = ax->phy_dev; - return rc; -} - -static int ax_nway_reset(struct net_device *dev) -{ - struct ax_device *ax = to_ax_dev(dev); - return mii_nway_restart(&ax->mii); -} + if (!phy_dev) + return -ENODEV; -static u32 ax_get_link(struct net_device *dev) -{ - struct ax_device *ax = to_ax_dev(dev); - return mii_link_ok(&ax->mii); + return phy_ethtool_sset(phy_dev, cmd); } static const struct ethtool_ops ax_ethtool_ops = { .get_drvinfo = ax_get_drvinfo, .get_settings = ax_get_settings, .set_settings = ax_set_settings, - .nway_reset = ax_nway_reset, - .get_link = ax_get_link, + .get_link = ethtool_op_get_link, }; #ifdef CONFIG_AX88796_93CX6 @@ -642,8 +552,102 @@ static const struct net_device_ops ax_netdev_ops = { #endif }; +static void ax_bb_mdc(struct mdiobb_ctrl *ctrl, int level) +{ + struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl); + + if (level) + ax->reg_memr |= AX_MEMR_MDC; + else + ax->reg_memr &= ~AX_MEMR_MDC; + + ei_outb(ax->reg_memr, ax->addr_memr); +} + +static void ax_bb_dir(struct mdiobb_ctrl *ctrl, int output) +{ + struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl); + + if (output) + ax->reg_memr &= ~AX_MEMR_MDIR; + else + ax->reg_memr |= AX_MEMR_MDIR; + + ei_outb(ax->reg_memr, ax->addr_memr); +} + +static void ax_bb_set_data(struct mdiobb_ctrl *ctrl, int value) +{ + struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl); + + if (value) + ax->reg_memr |= AX_MEMR_MDO; + else + ax->reg_memr &= ~AX_MEMR_MDO; + + ei_outb(ax->reg_memr, ax->addr_memr); +} + +static int ax_bb_get_data(struct mdiobb_ctrl *ctrl) +{ + struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl); + int reg_memr = ei_inb(ax->addr_memr); + + return reg_memr & AX_MEMR_MDI ? 1 : 0; +} + +static struct mdiobb_ops bb_ops = { + .owner = THIS_MODULE, + .set_mdc = ax_bb_mdc, + .set_mdio_dir = ax_bb_dir, + .set_mdio_data = ax_bb_set_data, + .get_mdio_data = ax_bb_get_data, +}; + /* setup code */ +static int ax_mii_init(struct net_device *dev) +{ + struct platform_device *pdev = to_platform_device(dev->dev.parent); + struct ei_device *ei_local = netdev_priv(dev); + struct ax_device *ax = to_ax_dev(dev); + int err, i; + + ax->bb_ctrl.ops = &bb_ops; + ax->addr_memr = ei_local->mem + AX_MEMR; + ax->mii_bus = alloc_mdio_bitbang(&ax->bb_ctrl); + if (!ax->mii_bus) { + err = -ENOMEM; + goto out; + } + + ax->mii_bus->name = "ax88796_mii_bus"; + ax->mii_bus->parent = dev->dev.parent; + snprintf(ax->mii_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id); + + ax->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); + if (!ax->mii_bus->irq) { + err = -ENOMEM; + goto out_free_mdio_bitbang; + } + + for (i = 0; i < PHY_MAX_ADDR; i++) + ax->mii_bus->irq[i] = PHY_POLL; + + err = mdiobus_register(ax->mii_bus); + if (err) + goto out_free_irq; + + return 0; + + out_free_irq: + kfree(ax->mii_bus->irq); + out_free_mdio_bitbang: + free_mdio_bitbang(ax->mii_bus); + out: + return err; +} + static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local) { void __iomem *ioaddr = ei_local->mem; @@ -763,15 +767,9 @@ static int ax_init_dev(struct net_device *dev) dev->netdev_ops = &ax_netdev_ops; dev->ethtool_ops = &ax_ethtool_ops; - ax->msg_enable = NETIF_MSG_LINK; - ax->mii.phy_id_mask = 0x1f; - ax->mii.reg_num_mask = 0x1f; - ax->mii.phy_id = 0x10; /* onboard phy */ - ax->mii.force_media = 0; - ax->mii.full_duplex = 0; - ax->mii.mdio_read = ax_phy_read; - ax->mii.mdio_write = ax_phy_write; - ax->mii.dev = dev; + ret = ax_mii_init(dev); + if (ret) + goto out_irq; ax_NS8390_init(dev, 0); @@ -842,8 +840,6 @@ static int ax_probe(struct platform_device *pdev) ei_local = netdev_priv(dev); ax = to_ax_dev(dev); - spin_lock_init(&ax->mii_lock); - ax->plat = pdev->dev.platform_data; platform_set_drvdata(pdev, dev); -- cgit v1.2.3 From 491bc292766330473eac4569be5d57f9aeb80112 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 9 Feb 2011 09:37:46 -0800 Subject: iwlwifi: Limit number of firmware reload If device has serious problem and cause firmware can not recover itself. Keep reloading firmware will not help, it can only fill up the syslog and lock up the system because busy reloading. Introduce the limit reload counter, if the reload reach the maximum within the pre-defined duration;stop the reload operation. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.c | 22 ++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 9 +++++++++ 2 files changed, 31 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 4ad89389a0a9..977ddfb8c24c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -948,6 +948,9 @@ EXPORT_SYMBOL(iwl_print_rx_config_cmd); */ void iwl_irq_handle_error(struct iwl_priv *priv) { + unsigned int reload_msec; + unsigned long reload_jiffies; + /* Set the FW error flag -- cleared on iwl_down */ set_bit(STATUS_FW_ERROR, &priv->status); @@ -991,6 +994,25 @@ void iwl_irq_handle_error(struct iwl_priv *priv) * commands by clearing the INIT status bit */ clear_bit(STATUS_READY, &priv->status); + /* + * If firmware keep reloading, then it indicate something + * serious wrong and firmware having problem to recover + * from it. Instead of keep trying which will fill the syslog + * and hang the system, let's just stop it + */ + reload_jiffies = jiffies; + reload_msec = jiffies_to_msecs((long) reload_jiffies - + (long) priv->reload_jiffies); + priv->reload_jiffies = reload_jiffies; + if (reload_msec <= IWL_MIN_RELOAD_DURATION) { + priv->reload_count++; + if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) { + IWL_ERR(priv, "BUG_ON, Stop restarting\n"); + return; + } + } else + priv->reload_count = 0; + if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { IWL_DEBUG(priv, IWL_DL_FW_ERRORS, "Restarting adapter due to uCode error.\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index ecfbef402781..065615ee040a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1110,6 +1110,11 @@ struct iwl_event_log { /* BT Antenna Coupling Threshold (dB) */ #define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) +/* Firmware reload counter and Timestamp */ +#define IWL_MIN_RELOAD_DURATION 1000 /* 1000 ms */ +#define IWL_MAX_CONTINUE_RELOAD_CNT 4 + + enum iwl_reset { IWL_RF_RESET = 0, IWL_FW_RESET, @@ -1262,6 +1267,10 @@ struct iwl_priv { /* force reset */ struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET]; + /* firmware reload counter and timestamp */ + unsigned long reload_jiffies; + int reload_count; + /* we allocate array of iwl_channel_info for NIC's valid channels. * Access via channel # using indirect index array */ struct iwl_channel_info *channel_info; /* channel info array */ -- cgit v1.2.3 From 46d0637a128f2f555c1f7be02cd65c45b92b2a60 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 7 Feb 2011 16:54:50 -0800 Subject: iwlwifi: Loading correct uCode again when fail to load During uCode loading, if the reply_alive come back with "failure", try to load the same uCode again. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index abd0461bd307..c04d99124ca8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -466,6 +466,15 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv, IWL_WARN(priv, "%s uCode did not respond OK.\n", (palive->ver_subtype == INITIALIZE_SUBTYPE) ? "init" : "runtime"); + /* + * If fail to load init uCode, + * let's try to load the init uCode again. + * We should not get into this situation, but if it + * does happen, we should not move on and loading "runtime" + * without proper calibrate the device. + */ + if (palive->ver_subtype == INITIALIZE_SUBTYPE) + priv->ucode_type = UCODE_NONE; queue_work(priv->workqueue, &priv->restart); } } -- cgit v1.2.3 From 73b78a22720087d2d384bdd49e9c25500ba73edd Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 11 Feb 2011 08:13:14 -0800 Subject: iwlwifi: enable 2-wire bt coex support for non-combo device For non-combo devices, 2-wire BT coex is needed to make sure BT coex still function with external BT devices Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c04d99124ca8..9965215697bb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2744,9 +2744,11 @@ static void iwl_alive_start(struct iwl_priv *priv) priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); } - if (priv->cfg->bt_params && - !priv->cfg->bt_params->advanced_bt_coexist) { - /* Configure Bluetooth device coexistence support */ + if (!priv->cfg->bt_params || (priv->cfg->bt_params && + !priv->cfg->bt_params->advanced_bt_coexist)) { + /* + * default is 2-wire BT coexexistence support + */ priv->cfg->ops->hcmd->send_bt_config(priv); } -- cgit v1.2.3 From aa833c4b1a928b8d3c4fcc2faaa0d6b81ea02b56 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 21 Feb 2011 10:57:10 -0800 Subject: iwlwifi: split the drivers for agn and legacy devices 3945/4965 Intel WiFi devices 3945 and 4965 now have their own driver in the folder drivers/net/wireless/iwlegacy Add support to build these drivers independently of the driver for AGN devices. Selecting the 3945 builds iwl3945.ko and iwl_legacy.ko, and selecting the 4965 builds iwl4965.ko and iwl_legacy.ko. iwl-legacy.ko contains code shared between both devices. The 3945 is an ABG/BG device, with no support for 802.11n. The 4965 is a 2x3 ABGN device. Signed-off-by: Meenakshi Venkataraman Acked-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/Kconfig | 1 + drivers/net/wireless/Makefile | 3 +- drivers/net/wireless/iwlwifi/Kconfig | 124 +- drivers/net/wireless/iwlwifi/Makefile | 39 +- drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c | 522 --- drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h | 60 - drivers/net/wireless/iwlwifi/iwl-3945-fh.h | 188 - drivers/net/wireless/iwlwifi/iwl-3945-hw.h | 294 -- drivers/net/wireless/iwlwifi/iwl-3945-led.c | 64 - drivers/net/wireless/iwlwifi/iwl-3945-led.h | 32 - drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 995 ------ drivers/net/wireless/iwlwifi/iwl-3945.c | 2819 --------------- drivers/net/wireless/iwlwifi/iwl-3945.h | 308 -- drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 792 ----- drivers/net/wireless/iwlwifi/iwl-4965.c | 2666 -------------- drivers/net/wireless/iwlwifi/iwl-agn.c | 18 - drivers/net/wireless/iwlwifi/iwl-core.c | 54 - drivers/net/wireless/iwlwifi/iwl-debugfs.c | 2 - drivers/net/wireless/iwlwifi/iwl-dev.h | 4 +- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 8 - drivers/net/wireless/iwlwifi/iwl-hcmd.c | 5 - drivers/net/wireless/iwlwifi/iwl-led.c | 2 - drivers/net/wireless/iwlwifi/iwl-legacy.c | 657 ---- drivers/net/wireless/iwlwifi/iwl-legacy.h | 79 - drivers/net/wireless/iwlwifi/iwl-power.c | 3 - drivers/net/wireless/iwlwifi/iwl-rx.c | 6 - drivers/net/wireless/iwlwifi/iwl-scan.c | 10 - drivers/net/wireless/iwlwifi/iwl-sta.c | 11 - drivers/net/wireless/iwlwifi/iwl-tx.c | 7 - drivers/net/wireless/iwlwifi/iwl3945-base.c | 4334 ----------------------- 30 files changed, 61 insertions(+), 14046 deletions(-) delete mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c delete mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h delete mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-fh.h delete mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-hw.h delete mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-led.c delete mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-led.h delete mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-rs.c delete mode 100644 drivers/net/wireless/iwlwifi/iwl-3945.c delete mode 100644 drivers/net/wireless/iwlwifi/iwl-3945.h delete mode 100644 drivers/net/wireless/iwlwifi/iwl-4965-hw.h delete mode 100644 drivers/net/wireless/iwlwifi/iwl-4965.c delete mode 100644 drivers/net/wireless/iwlwifi/iwl-legacy.c delete mode 100644 drivers/net/wireless/iwlwifi/iwl-legacy.h delete mode 100644 drivers/net/wireless/iwlwifi/iwl3945-base.c (limited to 'drivers') diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index b4338f389394..7aeb113cbb90 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -274,6 +274,7 @@ source "drivers/net/wireless/b43legacy/Kconfig" source "drivers/net/wireless/hostap/Kconfig" source "drivers/net/wireless/ipw2x00/Kconfig" source "drivers/net/wireless/iwlwifi/Kconfig" +source "drivers/net/wireless/iwlegacy/Kconfig" source "drivers/net/wireless/iwmc3200wifi/Kconfig" source "drivers/net/wireless/libertas/Kconfig" source "drivers/net/wireless/orinoco/Kconfig" diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 9760561a27a5..cd0c7e2aed43 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -41,7 +41,8 @@ obj-$(CONFIG_ADM8211) += adm8211.o obj-$(CONFIG_MWL8K) += mwl8k.o -obj-$(CONFIG_IWLWIFI) += iwlwifi/ +obj-$(CONFIG_IWLAGN) += iwlwifi/ +obj-$(CONFIG_IWLWIFI_LEGACY) += iwlegacy/ obj-$(CONFIG_RT2X00) += rt2x00/ obj-$(CONFIG_P54_COMMON) += p54/ diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index e1e3b1cf3cff..17d555f2215a 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -1,18 +1,52 @@ -config IWLWIFI - tristate "Intel Wireless Wifi" +config IWLAGN + tristate "Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlagn) " depends on PCI && MAC80211 select FW_LOADER select NEW_LEDS select LEDS_CLASS select LEDS_TRIGGERS select MAC80211_LEDS + ---help--- + Select to build the driver supporting the: + + Intel Wireless WiFi Link Next-Gen AGN + + This option enables support for use with the following hardware: + Intel Wireless WiFi Link 6250AGN Adapter + Intel 6000 Series Wi-Fi Adapters (6200AGN and 6300AGN) + Intel WiFi Link 1000BGN + Intel Wireless WiFi 5150AGN + Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN + Intel 6005 Series Wi-Fi Adapters + Intel 6030 Series Wi-Fi Adapters + Intel Wireless WiFi Link 6150BGN 2 Adapter + Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN) + Intel 2000 Series Wi-Fi Adapters + + + This driver uses the kernel's mac80211 subsystem. + + In order to use this driver, you will need a microcode (uCode) + image for it. You can obtain the microcode from: + + . + + The microcode is typically installed in /lib/firmware. You can + look in the hotplug script /etc/hotplug/firmware.agent to + determine which directory FIRMWARE_DIR is set to when the script + runs. + + If you want to compile the driver as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read . The + module will be called iwlagn. menu "Debugging Options" - depends on IWLWIFI + depends on IWLAGN config IWLWIFI_DEBUG - bool "Enable full debugging output in iwlagn and iwl3945 drivers" - depends on IWLWIFI + bool "Enable full debugging output in the iwlagn driver" + depends on IWLAGN ---help--- This option will enable debug tracing output for the iwlwifi drivers @@ -37,7 +71,7 @@ config IWLWIFI_DEBUG config IWLWIFI_DEBUGFS bool "iwlagn debugfs support" - depends on IWLWIFI && MAC80211_DEBUGFS + depends on IWLAGN && MAC80211_DEBUGFS ---help--- Enable creation of debugfs files for the iwlwifi drivers. This is a low-impact option that allows getting insight into the @@ -45,13 +79,13 @@ config IWLWIFI_DEBUGFS config IWLWIFI_DEBUG_EXPERIMENTAL_UCODE bool "Experimental uCode support" - depends on IWLWIFI && IWLWIFI_DEBUG + depends on IWLAGN && IWLWIFI_DEBUG ---help--- Enable use of experimental ucode for testing and debugging. config IWLWIFI_DEVICE_TRACING bool "iwlwifi device access tracing" - depends on IWLWIFI + depends on IWLAGN depends on EVENT_TRACING help Say Y here to trace all commands, including TX frames and IO @@ -68,57 +102,9 @@ config IWLWIFI_DEVICE_TRACING occur. endmenu -config IWLAGN - tristate "Intel Wireless WiFi Next Gen AGN (iwlagn)" - depends on IWLWIFI - ---help--- - Select to build the driver supporting the: - - Intel Wireless WiFi Link Next-Gen AGN - - This driver uses the kernel's mac80211 subsystem. - - In order to use this driver, you will need a microcode (uCode) - image for it. You can obtain the microcode from: - - . - - The microcode is typically installed in /lib/firmware. You can - look in the hotplug script /etc/hotplug/firmware.agent to - determine which directory FIRMWARE_DIR is set to when the script - runs. - - If you want to compile the driver as a module ( = code which can be - inserted in and removed from the running kernel whenever you want), - say M here and read . The - module will be called iwlagn. - - -config IWL4965 - bool "Intel Wireless WiFi 4965AGN" - depends on IWLAGN - ---help--- - This option enables support for Intel Wireless WiFi Link 4965AGN - -config IWL5000 - bool "Intel Wireless-N/Advanced-N/Ultimate-N WiFi Link" - depends on IWLAGN - ---help--- - This option enables support for use with the following hardware: - Intel Wireless WiFi Link 6250AGN Adapter - Intel 6000 Series Wi-Fi Adapters (6200AGN and 6300AGN) - Intel WiFi Link 1000BGN - Intel Wireless WiFi 5150AGN - Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN - Intel 6005 Series Wi-Fi Adapters - Intel 6030 Series Wi-Fi Adapters - Intel Wireless WiFi Link 6150BGN 2 Adapter - Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN) - Intel 2000 Series Wi-Fi Adapters - config IWL_P2P bool "iwlwifi experimental P2P support" - depends on IWL5000 + depends on IWLAGN help This option enables experimental P2P support for some devices based on microcode support. Since P2P support is still under @@ -132,27 +118,3 @@ config IWL_P2P Say Y only if you want to experiment with P2P. -config IWL3945 - tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)" - depends on IWLWIFI - ---help--- - Select to build the driver supporting the: - - Intel PRO/Wireless 3945ABG/BG Network Connection - - This driver uses the kernel's mac80211 subsystem. - - In order to use this driver, you will need a microcode (uCode) - image for it. You can obtain the microcode from: - - . - - The microcode is typically installed in /lib/firmware. You can - look in the hotplug script /etc/hotplug/firmware.agent to - determine which directory FIRMWARE_DIR is set to when the script - runs. - - If you want to compile the driver as a module ( = code which can be - inserted in and removed from the running kernel whenever you want), - say M here and read . The - module will be called iwl3945. diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 25be742c69c9..aab7d15bd5ed 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -1,36 +1,23 @@ -obj-$(CONFIG_IWLWIFI) += iwlcore.o -iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o -iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o -iwlcore-objs += iwl-scan.o iwl-led.o -iwlcore-$(CONFIG_IWL3945) += iwl-legacy.o -iwlcore-$(CONFIG_IWL4965) += iwl-legacy.o -iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o -iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o - -# If 3945 is selected only, iwl-legacy.o will be added -# to iwlcore-m above, but it needs to be built in. -iwlcore-objs += $(iwlcore-m) - -CFLAGS_iwl-devtrace.o := -I$(src) - # AGN obj-$(CONFIG_IWLAGN) += iwlagn.o iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o -iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o -iwlagn-$(CONFIG_IWL4965) += iwl-4965.o -iwlagn-$(CONFIG_IWL5000) += iwl-agn-rxon.o iwl-agn-hcmd.o iwl-agn-ict.o -iwlagn-$(CONFIG_IWL5000) += iwl-5000.o -iwlagn-$(CONFIG_IWL5000) += iwl-6000.o -iwlagn-$(CONFIG_IWL5000) += iwl-1000.o -iwlagn-$(CONFIG_IWL5000) += iwl-2000.o +iwlagn-objs += iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o +iwlagn-objs += iwl-rx.o iwl-tx.o iwl-sta.o +iwlagn-objs += iwl-scan.o iwl-led.o +iwlagn-objs += iwl-agn-rxon.o iwl-agn-hcmd.o iwl-agn-ict.o +iwlagn-objs += iwl-5000.o +iwlagn-objs += iwl-6000.o +iwlagn-objs += iwl-1000.o +iwlagn-objs += iwl-2000.o + +iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o +iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o +iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o -# 3945 -obj-$(CONFIG_IWL3945) += iwl3945.o -iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o -iwl3945-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-3945-debugfs.o +CFLAGS_iwl-devtrace.o := -I$(src) ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c deleted file mode 100644 index ef0835b01b6b..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c +++ /dev/null @@ -1,522 +0,0 @@ -/****************************************************************************** - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - *****************************************************************************/ - -#include "iwl-3945-debugfs.h" - - -static int iwl3945_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) -{ - int p = 0; - - p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", - le32_to_cpu(priv->_3945.statistics.flag)); - if (le32_to_cpu(priv->_3945.statistics.flag) & - UCODE_STATISTICS_CLEAR_MSK) - p += scnprintf(buf + p, bufsz - p, - "\tStatistics have been cleared\n"); - p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n", - (le32_to_cpu(priv->_3945.statistics.flag) & - UCODE_STATISTICS_FREQUENCY_MSK) - ? "2.4 GHz" : "5.2 GHz"); - p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n", - (le32_to_cpu(priv->_3945.statistics.flag) & - UCODE_STATISTICS_NARROW_BAND_MSK) - ? "enabled" : "disabled"); - return p; -} - -ssize_t iwl3945_ucode_rx_stats_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_priv *priv = file->private_data; - int pos = 0; - char *buf; - int bufsz = sizeof(struct iwl39_statistics_rx_phy) * 40 + - sizeof(struct iwl39_statistics_rx_non_phy) * 40 + 400; - ssize_t ret; - struct iwl39_statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm; - struct iwl39_statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck; - struct iwl39_statistics_rx_non_phy *general, *accum_general; - struct iwl39_statistics_rx_non_phy *delta_general, *max_general; - - if (!iwl_is_alive(priv)) - return -EAGAIN; - - buf = kzalloc(bufsz, GFP_KERNEL); - if (!buf) { - IWL_ERR(priv, "Can not allocate Buffer\n"); - return -ENOMEM; - } - - /* - * The statistic information display here is based on - * the last statistics notification from uCode - * might not reflect the current uCode activity - */ - ofdm = &priv->_3945.statistics.rx.ofdm; - cck = &priv->_3945.statistics.rx.cck; - general = &priv->_3945.statistics.rx.general; - accum_ofdm = &priv->_3945.accum_statistics.rx.ofdm; - accum_cck = &priv->_3945.accum_statistics.rx.cck; - accum_general = &priv->_3945.accum_statistics.rx.general; - delta_ofdm = &priv->_3945.delta_statistics.rx.ofdm; - delta_cck = &priv->_3945.delta_statistics.rx.cck; - delta_general = &priv->_3945.delta_statistics.rx.general; - max_ofdm = &priv->_3945.max_delta.rx.ofdm; - max_cck = &priv->_3945.max_delta.rx.cck; - max_general = &priv->_3945.max_delta.rx.general; - - pos += iwl3945_statistics_flag(priv, buf, bufsz); - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_Rx - OFDM:"); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "ina_cnt:", le32_to_cpu(ofdm->ina_cnt), - accum_ofdm->ina_cnt, - delta_ofdm->ina_cnt, max_ofdm->ina_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_cnt:", - le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt, - delta_ofdm->fina_cnt, max_ofdm->fina_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "plcp_err:", - le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err, - delta_ofdm->plcp_err, max_ofdm->plcp_err); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "crc32_err:", - le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err, - delta_ofdm->crc32_err, max_ofdm->crc32_err); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "overrun_err:", - le32_to_cpu(ofdm->overrun_err), - accum_ofdm->overrun_err, delta_ofdm->overrun_err, - max_ofdm->overrun_err); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "early_overrun_err:", - le32_to_cpu(ofdm->early_overrun_err), - accum_ofdm->early_overrun_err, - delta_ofdm->early_overrun_err, - max_ofdm->early_overrun_err); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "crc32_good:", le32_to_cpu(ofdm->crc32_good), - accum_ofdm->crc32_good, delta_ofdm->crc32_good, - max_ofdm->crc32_good); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "false_alarm_cnt:", - le32_to_cpu(ofdm->false_alarm_cnt), - accum_ofdm->false_alarm_cnt, - delta_ofdm->false_alarm_cnt, - max_ofdm->false_alarm_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_sync_err_cnt:", - le32_to_cpu(ofdm->fina_sync_err_cnt), - accum_ofdm->fina_sync_err_cnt, - delta_ofdm->fina_sync_err_cnt, - max_ofdm->fina_sync_err_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sfd_timeout:", - le32_to_cpu(ofdm->sfd_timeout), - accum_ofdm->sfd_timeout, - delta_ofdm->sfd_timeout, - max_ofdm->sfd_timeout); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_timeout:", - le32_to_cpu(ofdm->fina_timeout), - accum_ofdm->fina_timeout, - delta_ofdm->fina_timeout, - max_ofdm->fina_timeout); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "unresponded_rts:", - le32_to_cpu(ofdm->unresponded_rts), - accum_ofdm->unresponded_rts, - delta_ofdm->unresponded_rts, - max_ofdm->unresponded_rts); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "rxe_frame_lmt_ovrun:", - le32_to_cpu(ofdm->rxe_frame_limit_overrun), - accum_ofdm->rxe_frame_limit_overrun, - delta_ofdm->rxe_frame_limit_overrun, - max_ofdm->rxe_frame_limit_overrun); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sent_ack_cnt:", - le32_to_cpu(ofdm->sent_ack_cnt), - accum_ofdm->sent_ack_cnt, - delta_ofdm->sent_ack_cnt, - max_ofdm->sent_ack_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sent_cts_cnt:", - le32_to_cpu(ofdm->sent_cts_cnt), - accum_ofdm->sent_cts_cnt, - delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt); - - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_Rx - CCK:"); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "ina_cnt:", - le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt, - delta_cck->ina_cnt, max_cck->ina_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_cnt:", - le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt, - delta_cck->fina_cnt, max_cck->fina_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "plcp_err:", - le32_to_cpu(cck->plcp_err), accum_cck->plcp_err, - delta_cck->plcp_err, max_cck->plcp_err); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "crc32_err:", - le32_to_cpu(cck->crc32_err), accum_cck->crc32_err, - delta_cck->crc32_err, max_cck->crc32_err); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "overrun_err:", - le32_to_cpu(cck->overrun_err), - accum_cck->overrun_err, - delta_cck->overrun_err, max_cck->overrun_err); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "early_overrun_err:", - le32_to_cpu(cck->early_overrun_err), - accum_cck->early_overrun_err, - delta_cck->early_overrun_err, - max_cck->early_overrun_err); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "crc32_good:", - le32_to_cpu(cck->crc32_good), accum_cck->crc32_good, - delta_cck->crc32_good, - max_cck->crc32_good); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "false_alarm_cnt:", - le32_to_cpu(cck->false_alarm_cnt), - accum_cck->false_alarm_cnt, - delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_sync_err_cnt:", - le32_to_cpu(cck->fina_sync_err_cnt), - accum_cck->fina_sync_err_cnt, - delta_cck->fina_sync_err_cnt, - max_cck->fina_sync_err_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sfd_timeout:", - le32_to_cpu(cck->sfd_timeout), - accum_cck->sfd_timeout, - delta_cck->sfd_timeout, max_cck->sfd_timeout); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_timeout:", - le32_to_cpu(cck->fina_timeout), - accum_cck->fina_timeout, - delta_cck->fina_timeout, max_cck->fina_timeout); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "unresponded_rts:", - le32_to_cpu(cck->unresponded_rts), - accum_cck->unresponded_rts, - delta_cck->unresponded_rts, - max_cck->unresponded_rts); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "rxe_frame_lmt_ovrun:", - le32_to_cpu(cck->rxe_frame_limit_overrun), - accum_cck->rxe_frame_limit_overrun, - delta_cck->rxe_frame_limit_overrun, - max_cck->rxe_frame_limit_overrun); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sent_ack_cnt:", - le32_to_cpu(cck->sent_ack_cnt), - accum_cck->sent_ack_cnt, - delta_cck->sent_ack_cnt, - max_cck->sent_ack_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sent_cts_cnt:", - le32_to_cpu(cck->sent_cts_cnt), - accum_cck->sent_cts_cnt, - delta_cck->sent_cts_cnt, - max_cck->sent_cts_cnt); - - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_Rx - GENERAL:"); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "bogus_cts:", - le32_to_cpu(general->bogus_cts), - accum_general->bogus_cts, - delta_general->bogus_cts, max_general->bogus_cts); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "bogus_ack:", - le32_to_cpu(general->bogus_ack), - accum_general->bogus_ack, - delta_general->bogus_ack, max_general->bogus_ack); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "non_bssid_frames:", - le32_to_cpu(general->non_bssid_frames), - accum_general->non_bssid_frames, - delta_general->non_bssid_frames, - max_general->non_bssid_frames); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "filtered_frames:", - le32_to_cpu(general->filtered_frames), - accum_general->filtered_frames, - delta_general->filtered_frames, - max_general->filtered_frames); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "non_channel_beacons:", - le32_to_cpu(general->non_channel_beacons), - accum_general->non_channel_beacons, - delta_general->non_channel_beacons, - max_general->non_channel_beacons); - - ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); - kfree(buf); - return ret; -} - -ssize_t iwl3945_ucode_tx_stats_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_priv *priv = file->private_data; - int pos = 0; - char *buf; - int bufsz = (sizeof(struct iwl39_statistics_tx) * 48) + 250; - ssize_t ret; - struct iwl39_statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; - - if (!iwl_is_alive(priv)) - return -EAGAIN; - - buf = kzalloc(bufsz, GFP_KERNEL); - if (!buf) { - IWL_ERR(priv, "Can not allocate Buffer\n"); - return -ENOMEM; - } - - /* - * The statistic information display here is based on - * the last statistics notification from uCode - * might not reflect the current uCode activity - */ - tx = &priv->_3945.statistics.tx; - accum_tx = &priv->_3945.accum_statistics.tx; - delta_tx = &priv->_3945.delta_statistics.tx; - max_tx = &priv->_3945.max_delta.tx; - pos += iwl3945_statistics_flag(priv, buf, bufsz); - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_Tx:"); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "preamble:", - le32_to_cpu(tx->preamble_cnt), - accum_tx->preamble_cnt, - delta_tx->preamble_cnt, max_tx->preamble_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "rx_detected_cnt:", - le32_to_cpu(tx->rx_detected_cnt), - accum_tx->rx_detected_cnt, - delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "bt_prio_defer_cnt:", - le32_to_cpu(tx->bt_prio_defer_cnt), - accum_tx->bt_prio_defer_cnt, - delta_tx->bt_prio_defer_cnt, - max_tx->bt_prio_defer_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "bt_prio_kill_cnt:", - le32_to_cpu(tx->bt_prio_kill_cnt), - accum_tx->bt_prio_kill_cnt, - delta_tx->bt_prio_kill_cnt, - max_tx->bt_prio_kill_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "few_bytes_cnt:", - le32_to_cpu(tx->few_bytes_cnt), - accum_tx->few_bytes_cnt, - delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "cts_timeout:", - le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout, - delta_tx->cts_timeout, max_tx->cts_timeout); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "ack_timeout:", - le32_to_cpu(tx->ack_timeout), - accum_tx->ack_timeout, - delta_tx->ack_timeout, max_tx->ack_timeout); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "expected_ack_cnt:", - le32_to_cpu(tx->expected_ack_cnt), - accum_tx->expected_ack_cnt, - delta_tx->expected_ack_cnt, - max_tx->expected_ack_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "actual_ack_cnt:", - le32_to_cpu(tx->actual_ack_cnt), - accum_tx->actual_ack_cnt, - delta_tx->actual_ack_cnt, - max_tx->actual_ack_cnt); - - ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); - kfree(buf); - return ret; -} - -ssize_t iwl3945_ucode_general_stats_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_priv *priv = file->private_data; - int pos = 0; - char *buf; - int bufsz = sizeof(struct iwl39_statistics_general) * 10 + 300; - ssize_t ret; - struct iwl39_statistics_general *general, *accum_general; - struct iwl39_statistics_general *delta_general, *max_general; - struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; - struct iwl39_statistics_div *div, *accum_div, *delta_div, *max_div; - - if (!iwl_is_alive(priv)) - return -EAGAIN; - - buf = kzalloc(bufsz, GFP_KERNEL); - if (!buf) { - IWL_ERR(priv, "Can not allocate Buffer\n"); - return -ENOMEM; - } - - /* - * The statistic information display here is based on - * the last statistics notification from uCode - * might not reflect the current uCode activity - */ - general = &priv->_3945.statistics.general; - dbg = &priv->_3945.statistics.general.dbg; - div = &priv->_3945.statistics.general.div; - accum_general = &priv->_3945.accum_statistics.general; - delta_general = &priv->_3945.delta_statistics.general; - max_general = &priv->_3945.max_delta.general; - accum_dbg = &priv->_3945.accum_statistics.general.dbg; - delta_dbg = &priv->_3945.delta_statistics.general.dbg; - max_dbg = &priv->_3945.max_delta.general.dbg; - accum_div = &priv->_3945.accum_statistics.general.div; - delta_div = &priv->_3945.delta_statistics.general.div; - max_div = &priv->_3945.max_delta.general.div; - pos += iwl3945_statistics_flag(priv, buf, bufsz); - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_General:"); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "burst_check:", - le32_to_cpu(dbg->burst_check), - accum_dbg->burst_check, - delta_dbg->burst_check, max_dbg->burst_check); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "burst_count:", - le32_to_cpu(dbg->burst_count), - accum_dbg->burst_count, - delta_dbg->burst_count, max_dbg->burst_count); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sleep_time:", - le32_to_cpu(general->sleep_time), - accum_general->sleep_time, - delta_general->sleep_time, max_general->sleep_time); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "slots_out:", - le32_to_cpu(general->slots_out), - accum_general->slots_out, - delta_general->slots_out, max_general->slots_out); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "slots_idle:", - le32_to_cpu(general->slots_idle), - accum_general->slots_idle, - delta_general->slots_idle, max_general->slots_idle); - pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n", - le32_to_cpu(general->ttl_timestamp)); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "tx_on_a:", - le32_to_cpu(div->tx_on_a), accum_div->tx_on_a, - delta_div->tx_on_a, max_div->tx_on_a); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "tx_on_b:", - le32_to_cpu(div->tx_on_b), accum_div->tx_on_b, - delta_div->tx_on_b, max_div->tx_on_b); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "exec_time:", - le32_to_cpu(div->exec_time), accum_div->exec_time, - delta_div->exec_time, max_div->exec_time); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "probe_time:", - le32_to_cpu(div->probe_time), accum_div->probe_time, - delta_div->probe_time, max_div->probe_time); - ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); - kfree(buf); - return ret; -} diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h deleted file mode 100644 index 70809c53c215..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h +++ /dev/null @@ -1,60 +0,0 @@ -/****************************************************************************** - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - *****************************************************************************/ - -#include "iwl-dev.h" -#include "iwl-core.h" -#include "iwl-debug.h" - -#ifdef CONFIG_IWLWIFI_DEBUGFS -ssize_t iwl3945_ucode_rx_stats_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos); -ssize_t iwl3945_ucode_tx_stats_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos); -ssize_t iwl3945_ucode_general_stats_read(struct file *file, - char __user *user_buf, size_t count, - loff_t *ppos); -#else -static ssize_t iwl3945_ucode_rx_stats_read(struct file *file, - char __user *user_buf, size_t count, - loff_t *ppos) -{ - return 0; -} -static ssize_t iwl3945_ucode_tx_stats_read(struct file *file, - char __user *user_buf, size_t count, - loff_t *ppos) -{ - return 0; -} -static ssize_t iwl3945_ucode_general_stats_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - return 0; -} -#endif diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-fh.h b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h deleted file mode 100644 index 2c9ed2b502a3..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945-fh.h +++ /dev/null @@ -1,188 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ -#ifndef __iwl_3945_fh_h__ -#define __iwl_3945_fh_h__ - -/************************************/ -/* iwl3945 Flow Handler Definitions */ -/************************************/ - -/** - * This I/O area is directly read/writable by driver (e.g. Linux uses writel()) - * Addresses are offsets from device's PCI hardware base address. - */ -#define FH39_MEM_LOWER_BOUND (0x0800) -#define FH39_MEM_UPPER_BOUND (0x1000) - -#define FH39_CBCC_TABLE (FH39_MEM_LOWER_BOUND + 0x140) -#define FH39_TFDB_TABLE (FH39_MEM_LOWER_BOUND + 0x180) -#define FH39_RCSR_TABLE (FH39_MEM_LOWER_BOUND + 0x400) -#define FH39_RSSR_TABLE (FH39_MEM_LOWER_BOUND + 0x4c0) -#define FH39_TCSR_TABLE (FH39_MEM_LOWER_BOUND + 0x500) -#define FH39_TSSR_TABLE (FH39_MEM_LOWER_BOUND + 0x680) - -/* TFDB (Transmit Frame Buffer Descriptor) */ -#define FH39_TFDB(_ch, buf) (FH39_TFDB_TABLE + \ - ((_ch) * 2 + (buf)) * 0x28) -#define FH39_TFDB_CHNL_BUF_CTRL_REG(_ch) (FH39_TFDB_TABLE + 0x50 * (_ch)) - -/* CBCC channel is [0,2] */ -#define FH39_CBCC(_ch) (FH39_CBCC_TABLE + (_ch) * 0x8) -#define FH39_CBCC_CTRL(_ch) (FH39_CBCC(_ch) + 0x00) -#define FH39_CBCC_BASE(_ch) (FH39_CBCC(_ch) + 0x04) - -/* RCSR channel is [0,2] */ -#define FH39_RCSR(_ch) (FH39_RCSR_TABLE + (_ch) * 0x40) -#define FH39_RCSR_CONFIG(_ch) (FH39_RCSR(_ch) + 0x00) -#define FH39_RCSR_RBD_BASE(_ch) (FH39_RCSR(_ch) + 0x04) -#define FH39_RCSR_WPTR(_ch) (FH39_RCSR(_ch) + 0x20) -#define FH39_RCSR_RPTR_ADDR(_ch) (FH39_RCSR(_ch) + 0x24) - -#define FH39_RSCSR_CHNL0_WPTR (FH39_RCSR_WPTR(0)) - -/* RSSR */ -#define FH39_RSSR_CTRL (FH39_RSSR_TABLE + 0x000) -#define FH39_RSSR_STATUS (FH39_RSSR_TABLE + 0x004) - -/* TCSR */ -#define FH39_TCSR(_ch) (FH39_TCSR_TABLE + (_ch) * 0x20) -#define FH39_TCSR_CONFIG(_ch) (FH39_TCSR(_ch) + 0x00) -#define FH39_TCSR_CREDIT(_ch) (FH39_TCSR(_ch) + 0x04) -#define FH39_TCSR_BUFF_STTS(_ch) (FH39_TCSR(_ch) + 0x08) - -/* TSSR */ -#define FH39_TSSR_CBB_BASE (FH39_TSSR_TABLE + 0x000) -#define FH39_TSSR_MSG_CONFIG (FH39_TSSR_TABLE + 0x008) -#define FH39_TSSR_TX_STATUS (FH39_TSSR_TABLE + 0x010) - - -/* DBM */ - -#define FH39_SRVC_CHNL (6) - -#define FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE (20) -#define FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH (4) - -#define FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN (0x08000000) - -#define FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE (0x80000000) - -#define FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE (0x20000000) - -#define FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 (0x01000000) - -#define FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST (0x00001000) - -#define FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH (0x00000000) - -#define FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF (0x00000000) -#define FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER (0x00000001) - -#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000) -#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008) - -#define FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD (0x00200000) - -#define FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT (0x00000000) - -#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000) -#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000) - -#define FH39_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID (0x00004000) - -#define FH39_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR (0x00000001) - -#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON (0xFF000000) -#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON (0x00FF0000) - -#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B (0x00000400) - -#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON (0x00000100) -#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON (0x00000080) - -#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH (0x00000020) -#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH (0x00000005) - -#define FH39_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_ch) (BIT(_ch) << 24) -#define FH39_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_ch) (BIT(_ch) << 16) - -#define FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_ch) \ - (FH39_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_ch) | \ - FH39_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_ch)) - -#define FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000) - -struct iwl3945_tfd_tb { - __le32 addr; - __le32 len; -} __packed; - -struct iwl3945_tfd { - __le32 control_flags; - struct iwl3945_tfd_tb tbs[4]; - u8 __pad[28]; -} __packed; - - -#endif /* __iwl_3945_fh_h__ */ - diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h deleted file mode 100644 index 65b5834da28c..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h +++ /dev/null @@ -1,294 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ -/* - * Please use this file (iwl-3945-hw.h) only for hardware-related definitions. - * Please use iwl-commands.h for uCode API definitions. - * Please use iwl-3945.h for driver implementation definitions. - */ - -#ifndef __iwl_3945_hw__ -#define __iwl_3945_hw__ - -#include "iwl-eeprom.h" - -/* RSSI to dBm */ -#define IWL39_RSSI_OFFSET 95 - -#define IWL_DEFAULT_TX_POWER 0x0F - -/* - * EEPROM related constants, enums, and structures. - */ -#define EEPROM_SKU_CAP_OP_MODE_MRC (1 << 7) - -/* - * Mapping of a Tx power level, at factory calibration temperature, - * to a radio/DSP gain table index. - * One for each of 5 "sample" power levels in each band. - * v_det is measured at the factory, using the 3945's built-in power amplifier - * (PA) output voltage detector. This same detector is used during Tx of - * long packets in normal operation to provide feedback as to proper output - * level. - * Data copied from EEPROM. - * DO NOT ALTER THIS STRUCTURE!!! - */ -struct iwl3945_eeprom_txpower_sample { - u8 gain_index; /* index into power (gain) setup table ... */ - s8 power; /* ... for this pwr level for this chnl group */ - u16 v_det; /* PA output voltage */ -} __packed; - -/* - * Mappings of Tx power levels -> nominal radio/DSP gain table indexes. - * One for each channel group (a.k.a. "band") (1 for BG, 4 for A). - * Tx power setup code interpolates between the 5 "sample" power levels - * to determine the nominal setup for a requested power level. - * Data copied from EEPROM. - * DO NOT ALTER THIS STRUCTURE!!! - */ -struct iwl3945_eeprom_txpower_group { - struct iwl3945_eeprom_txpower_sample samples[5]; /* 5 power levels */ - s32 a, b, c, d, e; /* coefficients for voltage->power - * formula (signed) */ - s32 Fa, Fb, Fc, Fd, Fe; /* these modify coeffs based on - * frequency (signed) */ - s8 saturation_power; /* highest power possible by h/w in this - * band */ - u8 group_channel; /* "representative" channel # in this band */ - s16 temperature; /* h/w temperature at factory calib this band - * (signed) */ -} __packed; - -/* - * Temperature-based Tx-power compensation data, not band-specific. - * These coefficients are use to modify a/b/c/d/e coeffs based on - * difference between current temperature and factory calib temperature. - * Data copied from EEPROM. - */ -struct iwl3945_eeprom_temperature_corr { - u32 Ta; - u32 Tb; - u32 Tc; - u32 Td; - u32 Te; -} __packed; - -/* - * EEPROM map - */ -struct iwl3945_eeprom { - u8 reserved0[16]; - u16 device_id; /* abs.ofs: 16 */ - u8 reserved1[2]; - u16 pmc; /* abs.ofs: 20 */ - u8 reserved2[20]; - u8 mac_address[6]; /* abs.ofs: 42 */ - u8 reserved3[58]; - u16 board_revision; /* abs.ofs: 106 */ - u8 reserved4[11]; - u8 board_pba_number[9]; /* abs.ofs: 119 */ - u8 reserved5[8]; - u16 version; /* abs.ofs: 136 */ - u8 sku_cap; /* abs.ofs: 138 */ - u8 leds_mode; /* abs.ofs: 139 */ - u16 oem_mode; - u16 wowlan_mode; /* abs.ofs: 142 */ - u16 leds_time_interval; /* abs.ofs: 144 */ - u8 leds_off_time; /* abs.ofs: 146 */ - u8 leds_on_time; /* abs.ofs: 147 */ - u8 almgor_m_version; /* abs.ofs: 148 */ - u8 antenna_switch_type; /* abs.ofs: 149 */ - u8 reserved6[42]; - u8 sku_id[4]; /* abs.ofs: 192 */ - -/* - * Per-channel regulatory data. - * - * Each channel that *might* be supported by 3945 or 4965 has a fixed location - * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory - * txpower (MSB). - * - * Entries immediately below are for 20 MHz channel width. HT40 (40 MHz) - * channels (only for 4965, not supported by 3945) appear later in the EEPROM. - * - * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 - */ - u16 band_1_count; /* abs.ofs: 196 */ - struct iwl_eeprom_channel band_1_channels[14]; /* abs.ofs: 198 */ - -/* - * 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196, - * 5.0 GHz channels 7, 8, 11, 12, 16 - * (4915-5080MHz) (none of these is ever supported) - */ - u16 band_2_count; /* abs.ofs: 226 */ - struct iwl_eeprom_channel band_2_channels[13]; /* abs.ofs: 228 */ - -/* - * 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 - * (5170-5320MHz) - */ - u16 band_3_count; /* abs.ofs: 254 */ - struct iwl_eeprom_channel band_3_channels[12]; /* abs.ofs: 256 */ - -/* - * 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 - * (5500-5700MHz) - */ - u16 band_4_count; /* abs.ofs: 280 */ - struct iwl_eeprom_channel band_4_channels[11]; /* abs.ofs: 282 */ - -/* - * 5.7 GHz channels 145, 149, 153, 157, 161, 165 - * (5725-5825MHz) - */ - u16 band_5_count; /* abs.ofs: 304 */ - struct iwl_eeprom_channel band_5_channels[6]; /* abs.ofs: 306 */ - - u8 reserved9[194]; - -/* - * 3945 Txpower calibration data. - */ -#define IWL_NUM_TX_CALIB_GROUPS 5 - struct iwl3945_eeprom_txpower_group groups[IWL_NUM_TX_CALIB_GROUPS]; -/* abs.ofs: 512 */ - struct iwl3945_eeprom_temperature_corr corrections; /* abs.ofs: 832 */ - u8 reserved16[172]; /* fill out to full 1024 byte block */ -} __packed; - -#define IWL3945_EEPROM_IMG_SIZE 1024 - -/* End of EEPROM */ - -#define PCI_CFG_REV_ID_BIT_BASIC_SKU (0x40) /* bit 6 */ -#define PCI_CFG_REV_ID_BIT_RTP (0x80) /* bit 7 */ - -/* 4 DATA + 1 CMD. There are 2 HCCA queues that are not used. */ -#define IWL39_NUM_QUEUES 5 -#define IWL39_CMD_QUEUE_NUM 4 - -#define IWL_DEFAULT_TX_RETRY 15 - -/*********************************************/ - -#define RFD_SIZE 4 -#define NUM_TFD_CHUNKS 4 - -#define RX_QUEUE_SIZE 256 -#define RX_QUEUE_MASK 255 -#define RX_QUEUE_SIZE_LOG 8 - -#define U32_PAD(n) ((4-(n))&0x3) - -#define TFD_CTL_COUNT_SET(n) (n << 24) -#define TFD_CTL_COUNT_GET(ctl) ((ctl >> 24) & 7) -#define TFD_CTL_PAD_SET(n) (n << 28) -#define TFD_CTL_PAD_GET(ctl) (ctl >> 28) - -/* Sizes and addresses for instruction and data memory (SRAM) in - * 3945's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ -#define IWL39_RTC_INST_LOWER_BOUND (0x000000) -#define IWL39_RTC_INST_UPPER_BOUND (0x014000) - -#define IWL39_RTC_DATA_LOWER_BOUND (0x800000) -#define IWL39_RTC_DATA_UPPER_BOUND (0x808000) - -#define IWL39_RTC_INST_SIZE (IWL39_RTC_INST_UPPER_BOUND - \ - IWL39_RTC_INST_LOWER_BOUND) -#define IWL39_RTC_DATA_SIZE (IWL39_RTC_DATA_UPPER_BOUND - \ - IWL39_RTC_DATA_LOWER_BOUND) - -#define IWL39_MAX_INST_SIZE IWL39_RTC_INST_SIZE -#define IWL39_MAX_DATA_SIZE IWL39_RTC_DATA_SIZE - -/* Size of uCode instruction memory in bootstrap state machine */ -#define IWL39_MAX_BSM_SIZE IWL39_RTC_INST_SIZE - -static inline int iwl3945_hw_valid_rtc_data_addr(u32 addr) -{ - return (addr >= IWL39_RTC_DATA_LOWER_BOUND) && - (addr < IWL39_RTC_DATA_UPPER_BOUND); -} - -/* Base physical address of iwl3945_shared is provided to FH_TSSR_CBB_BASE - * and &iwl3945_shared.rx_read_ptr[0] is provided to FH_RCSR_RPTR_ADDR(0) */ -struct iwl3945_shared { - __le32 tx_base_ptr[8]; -} __packed; - -static inline u8 iwl3945_hw_get_rate(__le16 rate_n_flags) -{ - return le16_to_cpu(rate_n_flags) & 0xFF; -} - -static inline u16 iwl3945_hw_get_rate_n_flags(__le16 rate_n_flags) -{ - return le16_to_cpu(rate_n_flags); -} - -static inline __le16 iwl3945_hw_set_rate_n_flags(u8 rate, u16 flags) -{ - return cpu_to_le16((u16)rate|flags); -} -#endif diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c deleted file mode 100644 index dc7c3a4167a9..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c +++ /dev/null @@ -1,64 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "iwl-commands.h" -#include "iwl-3945.h" -#include "iwl-core.h" -#include "iwl-dev.h" -#include "iwl-3945-led.h" - - -/* Send led command */ -static int iwl3945_send_led_cmd(struct iwl_priv *priv, - struct iwl_led_cmd *led_cmd) -{ - struct iwl_host_cmd cmd = { - .id = REPLY_LEDS_CMD, - .len = sizeof(struct iwl_led_cmd), - .data = led_cmd, - .flags = CMD_ASYNC, - .callback = NULL, - }; - - return iwl_send_cmd(priv, &cmd); -} - -const struct iwl_led_ops iwl3945_led_ops = { - .cmd = iwl3945_send_led_cmd, -}; diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.h b/drivers/net/wireless/iwlwifi/iwl-3945-led.h deleted file mode 100644 index ce990adc51e7..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945-led.h +++ /dev/null @@ -1,32 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#ifndef __iwl_3945_led_h__ -#define __iwl_3945_led_h__ - -extern const struct iwl_led_ops iwl3945_led_ops; - -#endif /* __iwl_3945_led_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c deleted file mode 100644 index 1f3e7e34fbc7..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ /dev/null @@ -1,995 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "iwl-commands.h" -#include "iwl-3945.h" -#include "iwl-sta.h" - -#define RS_NAME "iwl-3945-rs" - -static s32 iwl3945_expected_tpt_g[IWL_RATE_COUNT_3945] = { - 7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202 -}; - -static s32 iwl3945_expected_tpt_g_prot[IWL_RATE_COUNT_3945] = { - 7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125 -}; - -static s32 iwl3945_expected_tpt_a[IWL_RATE_COUNT_3945] = { - 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186 -}; - -static s32 iwl3945_expected_tpt_b[IWL_RATE_COUNT_3945] = { - 7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -struct iwl3945_tpt_entry { - s8 min_rssi; - u8 index; -}; - -static struct iwl3945_tpt_entry iwl3945_tpt_table_a[] = { - {-60, IWL_RATE_54M_INDEX}, - {-64, IWL_RATE_48M_INDEX}, - {-72, IWL_RATE_36M_INDEX}, - {-80, IWL_RATE_24M_INDEX}, - {-84, IWL_RATE_18M_INDEX}, - {-85, IWL_RATE_12M_INDEX}, - {-87, IWL_RATE_9M_INDEX}, - {-89, IWL_RATE_6M_INDEX} -}; - -static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = { - {-60, IWL_RATE_54M_INDEX}, - {-64, IWL_RATE_48M_INDEX}, - {-68, IWL_RATE_36M_INDEX}, - {-80, IWL_RATE_24M_INDEX}, - {-84, IWL_RATE_18M_INDEX}, - {-85, IWL_RATE_12M_INDEX}, - {-86, IWL_RATE_11M_INDEX}, - {-88, IWL_RATE_5M_INDEX}, - {-90, IWL_RATE_2M_INDEX}, - {-92, IWL_RATE_1M_INDEX} -}; - -#define IWL_RATE_MAX_WINDOW 62 -#define IWL_RATE_FLUSH (3*HZ) -#define IWL_RATE_WIN_FLUSH (HZ/2) -#define IWL39_RATE_HIGH_TH 11520 -#define IWL_SUCCESS_UP_TH 8960 -#define IWL_SUCCESS_DOWN_TH 10880 -#define IWL_RATE_MIN_FAILURE_TH 6 -#define IWL_RATE_MIN_SUCCESS_TH 8 -#define IWL_RATE_DECREASE_TH 1920 -#define IWL_RATE_RETRY_TH 15 - -static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, enum ieee80211_band band) -{ - u32 index = 0; - u32 table_size = 0; - struct iwl3945_tpt_entry *tpt_table = NULL; - - if ((rssi < IWL_MIN_RSSI_VAL) || (rssi > IWL_MAX_RSSI_VAL)) - rssi = IWL_MIN_RSSI_VAL; - - switch (band) { - case IEEE80211_BAND_2GHZ: - tpt_table = iwl3945_tpt_table_g; - table_size = ARRAY_SIZE(iwl3945_tpt_table_g); - break; - - case IEEE80211_BAND_5GHZ: - tpt_table = iwl3945_tpt_table_a; - table_size = ARRAY_SIZE(iwl3945_tpt_table_a); - break; - - default: - BUG(); - break; - } - - while ((index < table_size) && (rssi < tpt_table[index].min_rssi)) - index++; - - index = min(index, (table_size - 1)); - - return tpt_table[index].index; -} - -static void iwl3945_clear_window(struct iwl3945_rate_scale_data *window) -{ - window->data = 0; - window->success_counter = 0; - window->success_ratio = -1; - window->counter = 0; - window->average_tpt = IWL_INVALID_VALUE; - window->stamp = 0; -} - -/** - * iwl3945_rate_scale_flush_windows - flush out the rate scale windows - * - * Returns the number of windows that have gathered data but were - * not flushed. If there were any that were not flushed, then - * reschedule the rate flushing routine. - */ -static int iwl3945_rate_scale_flush_windows(struct iwl3945_rs_sta *rs_sta) -{ - int unflushed = 0; - int i; - unsigned long flags; - struct iwl_priv *priv __maybe_unused = rs_sta->priv; - - /* - * For each rate, if we have collected data on that rate - * and it has been more than IWL_RATE_WIN_FLUSH - * since we flushed, clear out the gathered statistics - */ - for (i = 0; i < IWL_RATE_COUNT_3945; i++) { - if (!rs_sta->win[i].counter) - continue; - - spin_lock_irqsave(&rs_sta->lock, flags); - if (time_after(jiffies, rs_sta->win[i].stamp + - IWL_RATE_WIN_FLUSH)) { - IWL_DEBUG_RATE(priv, "flushing %d samples of rate " - "index %d\n", - rs_sta->win[i].counter, i); - iwl3945_clear_window(&rs_sta->win[i]); - } else - unflushed++; - spin_unlock_irqrestore(&rs_sta->lock, flags); - } - - return unflushed; -} - -#define IWL_RATE_FLUSH_MAX 5000 /* msec */ -#define IWL_RATE_FLUSH_MIN 50 /* msec */ -#define IWL_AVERAGE_PACKETS 1500 - -static void iwl3945_bg_rate_scale_flush(unsigned long data) -{ - struct iwl3945_rs_sta *rs_sta = (void *)data; - struct iwl_priv *priv __maybe_unused = rs_sta->priv; - int unflushed = 0; - unsigned long flags; - u32 packet_count, duration, pps; - - IWL_DEBUG_RATE(priv, "enter\n"); - - unflushed = iwl3945_rate_scale_flush_windows(rs_sta); - - spin_lock_irqsave(&rs_sta->lock, flags); - - /* Number of packets Rx'd since last time this timer ran */ - packet_count = (rs_sta->tx_packets - rs_sta->last_tx_packets) + 1; - - rs_sta->last_tx_packets = rs_sta->tx_packets + 1; - - if (unflushed) { - duration = - jiffies_to_msecs(jiffies - rs_sta->last_partial_flush); - - IWL_DEBUG_RATE(priv, "Tx'd %d packets in %dms\n", - packet_count, duration); - - /* Determine packets per second */ - if (duration) - pps = (packet_count * 1000) / duration; - else - pps = 0; - - if (pps) { - duration = (IWL_AVERAGE_PACKETS * 1000) / pps; - if (duration < IWL_RATE_FLUSH_MIN) - duration = IWL_RATE_FLUSH_MIN; - else if (duration > IWL_RATE_FLUSH_MAX) - duration = IWL_RATE_FLUSH_MAX; - } else - duration = IWL_RATE_FLUSH_MAX; - - rs_sta->flush_time = msecs_to_jiffies(duration); - - IWL_DEBUG_RATE(priv, "new flush period: %d msec ave %d\n", - duration, packet_count); - - mod_timer(&rs_sta->rate_scale_flush, jiffies + - rs_sta->flush_time); - - rs_sta->last_partial_flush = jiffies; - } else { - rs_sta->flush_time = IWL_RATE_FLUSH; - rs_sta->flush_pending = 0; - } - /* If there weren't any unflushed entries, we don't schedule the timer - * to run again */ - - rs_sta->last_flush = jiffies; - - spin_unlock_irqrestore(&rs_sta->lock, flags); - - IWL_DEBUG_RATE(priv, "leave\n"); -} - -/** - * iwl3945_collect_tx_data - Update the success/failure sliding window - * - * We keep a sliding window of the last 64 packets transmitted - * at this rate. window->data contains the bitmask of successful - * packets. - */ -static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta, - struct iwl3945_rate_scale_data *window, - int success, int retries, int index) -{ - unsigned long flags; - s32 fail_count; - struct iwl_priv *priv __maybe_unused = rs_sta->priv; - - if (!retries) { - IWL_DEBUG_RATE(priv, "leave: retries == 0 -- should be at least 1\n"); - return; - } - - spin_lock_irqsave(&rs_sta->lock, flags); - - /* - * Keep track of only the latest 62 tx frame attempts in this rate's - * history window; anything older isn't really relevant any more. - * If we have filled up the sliding window, drop the oldest attempt; - * if the oldest attempt (highest bit in bitmap) shows "success", - * subtract "1" from the success counter (this is the main reason - * we keep these bitmaps!). - * */ - while (retries > 0) { - if (window->counter >= IWL_RATE_MAX_WINDOW) { - - /* remove earliest */ - window->counter = IWL_RATE_MAX_WINDOW - 1; - - if (window->data & (1ULL << (IWL_RATE_MAX_WINDOW - 1))) { - window->data &= ~(1ULL << (IWL_RATE_MAX_WINDOW - 1)); - window->success_counter--; - } - } - - /* Increment frames-attempted counter */ - window->counter++; - - /* Shift bitmap by one frame (throw away oldest history), - * OR in "1", and increment "success" if this - * frame was successful. */ - window->data <<= 1; - if (success > 0) { - window->success_counter++; - window->data |= 0x1; - success--; - } - - retries--; - } - - /* Calculate current success ratio, avoid divide-by-0! */ - if (window->counter > 0) - window->success_ratio = 128 * (100 * window->success_counter) - / window->counter; - else - window->success_ratio = IWL_INVALID_VALUE; - - fail_count = window->counter - window->success_counter; - - /* Calculate average throughput, if we have enough history. */ - if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) || - (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH)) - window->average_tpt = ((window->success_ratio * - rs_sta->expected_tpt[index] + 64) / 128); - else - window->average_tpt = IWL_INVALID_VALUE; - - /* Tag this window as having been updated */ - window->stamp = jiffies; - - spin_unlock_irqrestore(&rs_sta->lock, flags); - -} - -/* - * Called after adding a new station to initialize rate scaling - */ -void iwl3945_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_id) -{ - struct ieee80211_hw *hw = priv->hw; - struct ieee80211_conf *conf = &priv->hw->conf; - struct iwl3945_sta_priv *psta; - struct iwl3945_rs_sta *rs_sta; - struct ieee80211_supported_band *sband; - int i; - - IWL_DEBUG_INFO(priv, "enter\n"); - if (sta_id == priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id) - goto out; - - psta = (struct iwl3945_sta_priv *) sta->drv_priv; - rs_sta = &psta->rs_sta; - sband = hw->wiphy->bands[conf->channel->band]; - - rs_sta->priv = priv; - - rs_sta->start_rate = IWL_RATE_INVALID; - - /* default to just 802.11b */ - rs_sta->expected_tpt = iwl3945_expected_tpt_b; - - rs_sta->last_partial_flush = jiffies; - rs_sta->last_flush = jiffies; - rs_sta->flush_time = IWL_RATE_FLUSH; - rs_sta->last_tx_packets = 0; - - rs_sta->rate_scale_flush.data = (unsigned long)rs_sta; - rs_sta->rate_scale_flush.function = iwl3945_bg_rate_scale_flush; - - for (i = 0; i < IWL_RATE_COUNT_3945; i++) - iwl3945_clear_window(&rs_sta->win[i]); - - /* TODO: what is a good starting rate for STA? About middle? Maybe not - * the lowest or the highest rate.. Could consider using RSSI from - * previous packets? Need to have IEEE 802.1X auth succeed immediately - * after assoc.. */ - - for (i = sband->n_bitrates - 1; i >= 0; i--) { - if (sta->supp_rates[sband->band] & (1 << i)) { - rs_sta->last_txrate_idx = i; - break; - } - } - - priv->_3945.sta_supp_rates = sta->supp_rates[sband->band]; - /* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */ - if (sband->band == IEEE80211_BAND_5GHZ) { - rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; - priv->_3945.sta_supp_rates = priv->_3945.sta_supp_rates << - IWL_FIRST_OFDM_RATE; - } - -out: - priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; - - IWL_DEBUG_INFO(priv, "leave\n"); -} - -static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) -{ - return hw->priv; -} - -/* rate scale requires free function to be implemented */ -static void rs_free(void *priv) -{ - return; -} - -static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp) -{ - struct iwl3945_rs_sta *rs_sta; - struct iwl3945_sta_priv *psta = (void *) sta->drv_priv; - struct iwl_priv *priv __maybe_unused = iwl_priv; - - IWL_DEBUG_RATE(priv, "enter\n"); - - rs_sta = &psta->rs_sta; - - spin_lock_init(&rs_sta->lock); - init_timer(&rs_sta->rate_scale_flush); - - IWL_DEBUG_RATE(priv, "leave\n"); - - return rs_sta; -} - -static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta, - void *priv_sta) -{ - struct iwl3945_rs_sta *rs_sta = priv_sta; - - /* - * Be careful not to use any members of iwl3945_rs_sta (like trying - * to use iwl_priv to print out debugging) since it may not be fully - * initialized at this point. - */ - del_timer_sync(&rs_sta->rate_scale_flush); -} - - -/** - * rs_tx_status - Update rate control values based on Tx results - * - * NOTE: Uses iwl_priv->retry_rate for the # of retries attempted by - * the hardware for each rate. - */ -static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband, - struct ieee80211_sta *sta, void *priv_sta, - struct sk_buff *skb) -{ - s8 retries = 0, current_count; - int scale_rate_index, first_index, last_index; - unsigned long flags; - struct iwl_priv *priv = (struct iwl_priv *)priv_rate; - struct iwl3945_rs_sta *rs_sta = priv_sta; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - - IWL_DEBUG_RATE(priv, "enter\n"); - - retries = info->status.rates[0].count; - /* Sanity Check for retries */ - if (retries > IWL_RATE_RETRY_TH) - retries = IWL_RATE_RETRY_TH; - - first_index = sband->bitrates[info->status.rates[0].idx].hw_value; - if ((first_index < 0) || (first_index >= IWL_RATE_COUNT_3945)) { - IWL_DEBUG_RATE(priv, "leave: Rate out of bounds: %d\n", first_index); - return; - } - - if (!priv_sta) { - IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n"); - return; - } - - /* Treat uninitialized rate scaling data same as non-existing. */ - if (!rs_sta->priv) { - IWL_DEBUG_RATE(priv, "leave: STA priv data uninitialized!\n"); - return; - } - - - rs_sta->tx_packets++; - - scale_rate_index = first_index; - last_index = first_index; - - /* - * Update the window for each rate. We determine which rates - * were Tx'd based on the total number of retries vs. the number - * of retries configured for each rate -- currently set to the - * priv value 'retry_rate' vs. rate specific - * - * On exit from this while loop last_index indicates the rate - * at which the frame was finally transmitted (or failed if no - * ACK) - */ - while (retries > 1) { - if ((retries - 1) < priv->retry_rate) { - current_count = (retries - 1); - last_index = scale_rate_index; - } else { - current_count = priv->retry_rate; - last_index = iwl3945_rs_next_rate(priv, - scale_rate_index); - } - - /* Update this rate accounting for as many retries - * as was used for it (per current_count) */ - iwl3945_collect_tx_data(rs_sta, - &rs_sta->win[scale_rate_index], - 0, current_count, scale_rate_index); - IWL_DEBUG_RATE(priv, "Update rate %d for %d retries.\n", - scale_rate_index, current_count); - - retries -= current_count; - - scale_rate_index = last_index; - } - - - /* Update the last index window with success/failure based on ACK */ - IWL_DEBUG_RATE(priv, "Update rate %d with %s.\n", - last_index, - (info->flags & IEEE80211_TX_STAT_ACK) ? - "success" : "failure"); - iwl3945_collect_tx_data(rs_sta, - &rs_sta->win[last_index], - info->flags & IEEE80211_TX_STAT_ACK, 1, last_index); - - /* We updated the rate scale window -- if its been more than - * flush_time since the last run, schedule the flush - * again */ - spin_lock_irqsave(&rs_sta->lock, flags); - - if (!rs_sta->flush_pending && - time_after(jiffies, rs_sta->last_flush + - rs_sta->flush_time)) { - - rs_sta->last_partial_flush = jiffies; - rs_sta->flush_pending = 1; - mod_timer(&rs_sta->rate_scale_flush, - jiffies + rs_sta->flush_time); - } - - spin_unlock_irqrestore(&rs_sta->lock, flags); - - IWL_DEBUG_RATE(priv, "leave\n"); -} - -static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, - u8 index, u16 rate_mask, enum ieee80211_band band) -{ - u8 high = IWL_RATE_INVALID; - u8 low = IWL_RATE_INVALID; - struct iwl_priv *priv __maybe_unused = rs_sta->priv; - - /* 802.11A walks to the next literal adjacent rate in - * the rate table */ - if (unlikely(band == IEEE80211_BAND_5GHZ)) { - int i; - u32 mask; - - /* Find the previous rate that is in the rate mask */ - i = index - 1; - for (mask = (1 << i); i >= 0; i--, mask >>= 1) { - if (rate_mask & mask) { - low = i; - break; - } - } - - /* Find the next rate that is in the rate mask */ - i = index + 1; - for (mask = (1 << i); i < IWL_RATE_COUNT_3945; - i++, mask <<= 1) { - if (rate_mask & mask) { - high = i; - break; - } - } - - return (high << 8) | low; - } - - low = index; - while (low != IWL_RATE_INVALID) { - if (rs_sta->tgg) - low = iwl3945_rates[low].prev_rs_tgg; - else - low = iwl3945_rates[low].prev_rs; - if (low == IWL_RATE_INVALID) - break; - if (rate_mask & (1 << low)) - break; - IWL_DEBUG_RATE(priv, "Skipping masked lower rate: %d\n", low); - } - - high = index; - while (high != IWL_RATE_INVALID) { - if (rs_sta->tgg) - high = iwl3945_rates[high].next_rs_tgg; - else - high = iwl3945_rates[high].next_rs; - if (high == IWL_RATE_INVALID) - break; - if (rate_mask & (1 << high)) - break; - IWL_DEBUG_RATE(priv, "Skipping masked higher rate: %d\n", high); - } - - return (high << 8) | low; -} - -/** - * rs_get_rate - find the rate for the requested packet - * - * Returns the ieee80211_rate structure allocated by the driver. - * - * The rate control algorithm has no internal mapping between hw_mode's - * rate ordering and the rate ordering used by the rate control algorithm. - * - * The rate control algorithm uses a single table of rates that goes across - * the entire A/B/G spectrum vs. being limited to just one particular - * hw_mode. - * - * As such, we can't convert the index obtained below into the hw_mode's - * rate table and must reference the driver allocated rate table - * - */ -static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, - void *priv_sta, struct ieee80211_tx_rate_control *txrc) -{ - struct ieee80211_supported_band *sband = txrc->sband; - struct sk_buff *skb = txrc->skb; - u8 low = IWL_RATE_INVALID; - u8 high = IWL_RATE_INVALID; - u16 high_low; - int index; - struct iwl3945_rs_sta *rs_sta = priv_sta; - struct iwl3945_rate_scale_data *window = NULL; - int current_tpt = IWL_INVALID_VALUE; - int low_tpt = IWL_INVALID_VALUE; - int high_tpt = IWL_INVALID_VALUE; - u32 fail_count; - s8 scale_action = 0; - unsigned long flags; - u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0; - s8 max_rate_idx = -1; - struct iwl_priv *priv __maybe_unused = (struct iwl_priv *)priv_r; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - - IWL_DEBUG_RATE(priv, "enter\n"); - - /* Treat uninitialized rate scaling data same as non-existing. */ - if (rs_sta && !rs_sta->priv) { - IWL_DEBUG_RATE(priv, "Rate scaling information not initialized yet.\n"); - priv_sta = NULL; - } - - if (rate_control_send_low(sta, priv_sta, txrc)) - return; - - rate_mask = sta->supp_rates[sband->band]; - - /* get user max rate if set */ - max_rate_idx = txrc->max_rate_idx; - if ((sband->band == IEEE80211_BAND_5GHZ) && (max_rate_idx != -1)) - max_rate_idx += IWL_FIRST_OFDM_RATE; - if ((max_rate_idx < 0) || (max_rate_idx >= IWL_RATE_COUNT)) - max_rate_idx = -1; - - index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT_3945 - 1); - - if (sband->band == IEEE80211_BAND_5GHZ) - rate_mask = rate_mask << IWL_FIRST_OFDM_RATE; - - spin_lock_irqsave(&rs_sta->lock, flags); - - /* for recent assoc, choose best rate regarding - * to rssi value - */ - if (rs_sta->start_rate != IWL_RATE_INVALID) { - if (rs_sta->start_rate < index && - (rate_mask & (1 << rs_sta->start_rate))) - index = rs_sta->start_rate; - rs_sta->start_rate = IWL_RATE_INVALID; - } - - /* force user max rate if set by user */ - if ((max_rate_idx != -1) && (max_rate_idx < index)) { - if (rate_mask & (1 << max_rate_idx)) - index = max_rate_idx; - } - - window = &(rs_sta->win[index]); - - fail_count = window->counter - window->success_counter; - - if (((fail_count < IWL_RATE_MIN_FAILURE_TH) && - (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) { - spin_unlock_irqrestore(&rs_sta->lock, flags); - - IWL_DEBUG_RATE(priv, "Invalid average_tpt on rate %d: " - "counter: %d, success_counter: %d, " - "expected_tpt is %sNULL\n", - index, - window->counter, - window->success_counter, - rs_sta->expected_tpt ? "not " : ""); - - /* Can't calculate this yet; not enough history */ - window->average_tpt = IWL_INVALID_VALUE; - goto out; - - } - - current_tpt = window->average_tpt; - - high_low = iwl3945_get_adjacent_rate(rs_sta, index, rate_mask, - sband->band); - low = high_low & 0xff; - high = (high_low >> 8) & 0xff; - - /* If user set max rate, dont allow higher than user constrain */ - if ((max_rate_idx != -1) && (max_rate_idx < high)) - high = IWL_RATE_INVALID; - - /* Collect Measured throughputs of adjacent rates */ - if (low != IWL_RATE_INVALID) - low_tpt = rs_sta->win[low].average_tpt; - - if (high != IWL_RATE_INVALID) - high_tpt = rs_sta->win[high].average_tpt; - - spin_unlock_irqrestore(&rs_sta->lock, flags); - - scale_action = 0; - - /* Low success ratio , need to drop the rate */ - if ((window->success_ratio < IWL_RATE_DECREASE_TH) || !current_tpt) { - IWL_DEBUG_RATE(priv, "decrease rate because of low success_ratio\n"); - scale_action = -1; - /* No throughput measured yet for adjacent rates, - * try increase */ - } else if ((low_tpt == IWL_INVALID_VALUE) && - (high_tpt == IWL_INVALID_VALUE)) { - - if (high != IWL_RATE_INVALID && window->success_ratio >= IWL_RATE_INCREASE_TH) - scale_action = 1; - else if (low != IWL_RATE_INVALID) - scale_action = 0; - - /* Both adjacent throughputs are measured, but neither one has - * better throughput; we're using the best rate, don't change - * it! */ - } else if ((low_tpt != IWL_INVALID_VALUE) && - (high_tpt != IWL_INVALID_VALUE) && - (low_tpt < current_tpt) && (high_tpt < current_tpt)) { - - IWL_DEBUG_RATE(priv, "No action -- low [%d] & high [%d] < " - "current_tpt [%d]\n", - low_tpt, high_tpt, current_tpt); - scale_action = 0; - - /* At least one of the rates has better throughput */ - } else { - if (high_tpt != IWL_INVALID_VALUE) { - - /* High rate has better throughput, Increase - * rate */ - if (high_tpt > current_tpt && - window->success_ratio >= IWL_RATE_INCREASE_TH) - scale_action = 1; - else { - IWL_DEBUG_RATE(priv, - "decrease rate because of high tpt\n"); - scale_action = 0; - } - } else if (low_tpt != IWL_INVALID_VALUE) { - if (low_tpt > current_tpt) { - IWL_DEBUG_RATE(priv, - "decrease rate because of low tpt\n"); - scale_action = -1; - } else if (window->success_ratio >= IWL_RATE_INCREASE_TH) { - /* Lower rate has better - * throughput,decrease rate */ - scale_action = 1; - } - } - } - - /* Sanity check; asked for decrease, but success rate or throughput - * has been good at old rate. Don't change it. */ - if ((scale_action == -1) && (low != IWL_RATE_INVALID) && - ((window->success_ratio > IWL_RATE_HIGH_TH) || - (current_tpt > (100 * rs_sta->expected_tpt[low])))) - scale_action = 0; - - switch (scale_action) { - case -1: - - /* Decrese rate */ - if (low != IWL_RATE_INVALID) - index = low; - break; - - case 1: - /* Increase rate */ - if (high != IWL_RATE_INVALID) - index = high; - - break; - - case 0: - default: - /* No change */ - break; - } - - IWL_DEBUG_RATE(priv, "Selected %d (action %d) - low %d high %d\n", - index, scale_action, low, high); - - out: - - rs_sta->last_txrate_idx = index; - if (sband->band == IEEE80211_BAND_5GHZ) - info->control.rates[0].idx = rs_sta->last_txrate_idx - - IWL_FIRST_OFDM_RATE; - else - info->control.rates[0].idx = rs_sta->last_txrate_idx; - - IWL_DEBUG_RATE(priv, "leave: %d\n", index); -} - -#ifdef CONFIG_MAC80211_DEBUGFS -static int iwl3945_open_file_generic(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t iwl3945_sta_dbgfs_stats_table_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - char *buff; - int desc = 0; - int j; - ssize_t ret; - struct iwl3945_rs_sta *lq_sta = file->private_data; - - buff = kmalloc(1024, GFP_KERNEL); - if (!buff) - return -ENOMEM; - - desc += sprintf(buff + desc, "tx packets=%d last rate index=%d\n" - "rate=0x%X flush time %d\n", - lq_sta->tx_packets, - lq_sta->last_txrate_idx, - lq_sta->start_rate, jiffies_to_msecs(lq_sta->flush_time)); - for (j = 0; j < IWL_RATE_COUNT_3945; j++) { - desc += sprintf(buff+desc, - "counter=%d success=%d %%=%d\n", - lq_sta->win[j].counter, - lq_sta->win[j].success_counter, - lq_sta->win[j].success_ratio); - } - ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); - kfree(buff); - return ret; -} - -static const struct file_operations rs_sta_dbgfs_stats_table_ops = { - .read = iwl3945_sta_dbgfs_stats_table_read, - .open = iwl3945_open_file_generic, - .llseek = default_llseek, -}; - -static void iwl3945_add_debugfs(void *priv, void *priv_sta, - struct dentry *dir) -{ - struct iwl3945_rs_sta *lq_sta = priv_sta; - - lq_sta->rs_sta_dbgfs_stats_table_file = - debugfs_create_file("rate_stats_table", 0600, dir, - lq_sta, &rs_sta_dbgfs_stats_table_ops); - -} - -static void iwl3945_remove_debugfs(void *priv, void *priv_sta) -{ - struct iwl3945_rs_sta *lq_sta = priv_sta; - debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); -} -#endif - -/* - * Initialization of rate scaling information is done by driver after - * the station is added. Since mac80211 calls this function before a - * station is added we ignore it. - */ -static void rs_rate_init_stub(void *priv_r, struct ieee80211_supported_band *sband, - struct ieee80211_sta *sta, void *priv_sta) -{ -} - -static struct rate_control_ops rs_ops = { - .module = NULL, - .name = RS_NAME, - .tx_status = rs_tx_status, - .get_rate = rs_get_rate, - .rate_init = rs_rate_init_stub, - .alloc = rs_alloc, - .free = rs_free, - .alloc_sta = rs_alloc_sta, - .free_sta = rs_free_sta, -#ifdef CONFIG_MAC80211_DEBUGFS - .add_sta_debugfs = iwl3945_add_debugfs, - .remove_sta_debugfs = iwl3945_remove_debugfs, -#endif - -}; -void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) -{ - struct iwl_priv *priv = hw->priv; - s32 rssi = 0; - unsigned long flags; - struct iwl3945_rs_sta *rs_sta; - struct ieee80211_sta *sta; - struct iwl3945_sta_priv *psta; - - IWL_DEBUG_RATE(priv, "enter\n"); - - rcu_read_lock(); - - sta = ieee80211_find_sta(priv->contexts[IWL_RXON_CTX_BSS].vif, - priv->stations[sta_id].sta.sta.addr); - if (!sta) { - IWL_DEBUG_RATE(priv, "Unable to find station to initialize rate scaling.\n"); - rcu_read_unlock(); - return; - } - - psta = (void *) sta->drv_priv; - rs_sta = &psta->rs_sta; - - spin_lock_irqsave(&rs_sta->lock, flags); - - rs_sta->tgg = 0; - switch (priv->band) { - case IEEE80211_BAND_2GHZ: - /* TODO: this always does G, not a regression */ - if (priv->contexts[IWL_RXON_CTX_BSS].active.flags & - RXON_FLG_TGG_PROTECT_MSK) { - rs_sta->tgg = 1; - rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot; - } else - rs_sta->expected_tpt = iwl3945_expected_tpt_g; - break; - - case IEEE80211_BAND_5GHZ: - rs_sta->expected_tpt = iwl3945_expected_tpt_a; - break; - case IEEE80211_NUM_BANDS: - BUG(); - break; - } - - spin_unlock_irqrestore(&rs_sta->lock, flags); - - rssi = priv->_3945.last_rx_rssi; - if (rssi == 0) - rssi = IWL_MIN_RSSI_VAL; - - IWL_DEBUG_RATE(priv, "Network RSSI: %d\n", rssi); - - rs_sta->start_rate = iwl3945_get_rate_index_by_rssi(rssi, priv->band); - - IWL_DEBUG_RATE(priv, "leave: rssi %d assign rate index: " - "%d (plcp 0x%x)\n", rssi, rs_sta->start_rate, - iwl3945_rates[rs_sta->start_rate].plcp); - rcu_read_unlock(); -} - -int iwl3945_rate_control_register(void) -{ - return ieee80211_rate_control_register(&rs_ops); -} - -void iwl3945_rate_control_unregister(void) -{ - ieee80211_rate_control_unregister(&rs_ops); -} - - diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c deleted file mode 100644 index 5b6932c2193a..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ /dev/null @@ -1,2819 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "iwl-fh.h" -#include "iwl-3945-fh.h" -#include "iwl-commands.h" -#include "iwl-sta.h" -#include "iwl-3945.h" -#include "iwl-eeprom.h" -#include "iwl-core.h" -#include "iwl-helpers.h" -#include "iwl-led.h" -#include "iwl-3945-led.h" -#include "iwl-3945-debugfs.h" -#include "iwl-legacy.h" - -#define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \ - [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ - IWL_RATE_##r##M_IEEE, \ - IWL_RATE_##ip##M_INDEX, \ - IWL_RATE_##in##M_INDEX, \ - IWL_RATE_##rp##M_INDEX, \ - IWL_RATE_##rn##M_INDEX, \ - IWL_RATE_##pp##M_INDEX, \ - IWL_RATE_##np##M_INDEX, \ - IWL_RATE_##r##M_INDEX_TABLE, \ - IWL_RATE_##ip##M_INDEX_TABLE } - -/* - * Parameter order: - * rate, prev rate, next rate, prev tgg rate, next tgg rate - * - * If there isn't a valid next or previous rate then INV is used which - * maps to IWL_RATE_INVALID - * - */ -const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945] = { - IWL_DECLARE_RATE_INFO(1, INV, 2, INV, 2, INV, 2), /* 1mbps */ - IWL_DECLARE_RATE_INFO(2, 1, 5, 1, 5, 1, 5), /* 2mbps */ - IWL_DECLARE_RATE_INFO(5, 2, 6, 2, 11, 2, 11), /*5.5mbps */ - IWL_DECLARE_RATE_INFO(11, 9, 12, 5, 12, 5, 18), /* 11mbps */ - IWL_DECLARE_RATE_INFO(6, 5, 9, 5, 11, 5, 11), /* 6mbps */ - IWL_DECLARE_RATE_INFO(9, 6, 11, 5, 11, 5, 11), /* 9mbps */ - IWL_DECLARE_RATE_INFO(12, 11, 18, 11, 18, 11, 18), /* 12mbps */ - IWL_DECLARE_RATE_INFO(18, 12, 24, 12, 24, 11, 24), /* 18mbps */ - IWL_DECLARE_RATE_INFO(24, 18, 36, 18, 36, 18, 36), /* 24mbps */ - IWL_DECLARE_RATE_INFO(36, 24, 48, 24, 48, 24, 48), /* 36mbps */ - IWL_DECLARE_RATE_INFO(48, 36, 54, 36, 54, 36, 54), /* 48mbps */ - IWL_DECLARE_RATE_INFO(54, 48, INV, 48, INV, 48, INV),/* 54mbps */ -}; - -static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index) -{ - u8 rate = iwl3945_rates[rate_index].prev_ieee; - - if (rate == IWL_RATE_INVALID) - rate = rate_index; - return rate; -} - -/* 1 = enable the iwl3945_disable_events() function */ -#define IWL_EVT_DISABLE (0) -#define IWL_EVT_DISABLE_SIZE (1532/32) - -/** - * iwl3945_disable_events - Disable selected events in uCode event log - * - * Disable an event by writing "1"s into "disable" - * bitmap in SRAM. Bit position corresponds to Event # (id/type). - * Default values of 0 enable uCode events to be logged. - * Use for only special debugging. This function is just a placeholder as-is, - * you'll need to provide the special bits! ... - * ... and set IWL_EVT_DISABLE to 1. */ -void iwl3945_disable_events(struct iwl_priv *priv) -{ - int i; - u32 base; /* SRAM address of event log header */ - u32 disable_ptr; /* SRAM address of event-disable bitmap array */ - u32 array_size; /* # of u32 entries in array */ - static const u32 evt_disable[IWL_EVT_DISABLE_SIZE] = { - 0x00000000, /* 31 - 0 Event id numbers */ - 0x00000000, /* 63 - 32 */ - 0x00000000, /* 95 - 64 */ - 0x00000000, /* 127 - 96 */ - 0x00000000, /* 159 - 128 */ - 0x00000000, /* 191 - 160 */ - 0x00000000, /* 223 - 192 */ - 0x00000000, /* 255 - 224 */ - 0x00000000, /* 287 - 256 */ - 0x00000000, /* 319 - 288 */ - 0x00000000, /* 351 - 320 */ - 0x00000000, /* 383 - 352 */ - 0x00000000, /* 415 - 384 */ - 0x00000000, /* 447 - 416 */ - 0x00000000, /* 479 - 448 */ - 0x00000000, /* 511 - 480 */ - 0x00000000, /* 543 - 512 */ - 0x00000000, /* 575 - 544 */ - 0x00000000, /* 607 - 576 */ - 0x00000000, /* 639 - 608 */ - 0x00000000, /* 671 - 640 */ - 0x00000000, /* 703 - 672 */ - 0x00000000, /* 735 - 704 */ - 0x00000000, /* 767 - 736 */ - 0x00000000, /* 799 - 768 */ - 0x00000000, /* 831 - 800 */ - 0x00000000, /* 863 - 832 */ - 0x00000000, /* 895 - 864 */ - 0x00000000, /* 927 - 896 */ - 0x00000000, /* 959 - 928 */ - 0x00000000, /* 991 - 960 */ - 0x00000000, /* 1023 - 992 */ - 0x00000000, /* 1055 - 1024 */ - 0x00000000, /* 1087 - 1056 */ - 0x00000000, /* 1119 - 1088 */ - 0x00000000, /* 1151 - 1120 */ - 0x00000000, /* 1183 - 1152 */ - 0x00000000, /* 1215 - 1184 */ - 0x00000000, /* 1247 - 1216 */ - 0x00000000, /* 1279 - 1248 */ - 0x00000000, /* 1311 - 1280 */ - 0x00000000, /* 1343 - 1312 */ - 0x00000000, /* 1375 - 1344 */ - 0x00000000, /* 1407 - 1376 */ - 0x00000000, /* 1439 - 1408 */ - 0x00000000, /* 1471 - 1440 */ - 0x00000000, /* 1503 - 1472 */ - }; - - base = le32_to_cpu(priv->card_alive.log_event_table_ptr); - if (!iwl3945_hw_valid_rtc_data_addr(base)) { - IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); - return; - } - - disable_ptr = iwl_read_targ_mem(priv, base + (4 * sizeof(u32))); - array_size = iwl_read_targ_mem(priv, base + (5 * sizeof(u32))); - - if (IWL_EVT_DISABLE && (array_size == IWL_EVT_DISABLE_SIZE)) { - IWL_DEBUG_INFO(priv, "Disabling selected uCode log events at 0x%x\n", - disable_ptr); - for (i = 0; i < IWL_EVT_DISABLE_SIZE; i++) - iwl_write_targ_mem(priv, - disable_ptr + (i * sizeof(u32)), - evt_disable[i]); - - } else { - IWL_DEBUG_INFO(priv, "Selected uCode log events may be disabled\n"); - IWL_DEBUG_INFO(priv, " by writing \"1\"s into disable bitmap\n"); - IWL_DEBUG_INFO(priv, " in SRAM at 0x%x, size %d u32s\n", - disable_ptr, array_size); - } - -} - -static int iwl3945_hwrate_to_plcp_idx(u8 plcp) -{ - int idx; - - for (idx = 0; idx < IWL_RATE_COUNT_3945; idx++) - if (iwl3945_rates[idx].plcp == plcp) - return idx; - return -1; -} - -#ifdef CONFIG_IWLWIFI_DEBUG -#define TX_STATUS_ENTRY(x) case TX_3945_STATUS_FAIL_ ## x: return #x - -static const char *iwl3945_get_tx_fail_reason(u32 status) -{ - switch (status & TX_STATUS_MSK) { - case TX_3945_STATUS_SUCCESS: - return "SUCCESS"; - TX_STATUS_ENTRY(SHORT_LIMIT); - TX_STATUS_ENTRY(LONG_LIMIT); - TX_STATUS_ENTRY(FIFO_UNDERRUN); - TX_STATUS_ENTRY(MGMNT_ABORT); - TX_STATUS_ENTRY(NEXT_FRAG); - TX_STATUS_ENTRY(LIFE_EXPIRE); - TX_STATUS_ENTRY(DEST_PS); - TX_STATUS_ENTRY(ABORTED); - TX_STATUS_ENTRY(BT_RETRY); - TX_STATUS_ENTRY(STA_INVALID); - TX_STATUS_ENTRY(FRAG_DROPPED); - TX_STATUS_ENTRY(TID_DISABLE); - TX_STATUS_ENTRY(FRAME_FLUSHED); - TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL); - TX_STATUS_ENTRY(TX_LOCKED); - TX_STATUS_ENTRY(NO_BEACON_ON_RADAR); - } - - return "UNKNOWN"; -} -#else -static inline const char *iwl3945_get_tx_fail_reason(u32 status) -{ - return ""; -} -#endif - -/* - * get ieee prev rate from rate scale table. - * for A and B mode we need to overright prev - * value - */ -int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate) -{ - int next_rate = iwl3945_get_prev_ieee_rate(rate); - - switch (priv->band) { - case IEEE80211_BAND_5GHZ: - if (rate == IWL_RATE_12M_INDEX) - next_rate = IWL_RATE_9M_INDEX; - else if (rate == IWL_RATE_6M_INDEX) - next_rate = IWL_RATE_6M_INDEX; - break; - case IEEE80211_BAND_2GHZ: - if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) && - iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { - if (rate == IWL_RATE_11M_INDEX) - next_rate = IWL_RATE_5M_INDEX; - } - break; - - default: - break; - } - - return next_rate; -} - - -/** - * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd - * - * When FW advances 'R' index, all entries between old and new 'R' index - * need to be reclaimed. As result, some free space forms. If there is - * enough free space (> low mark), wake the stack that feeds us. - */ -static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, - int txq_id, int index) -{ - struct iwl_tx_queue *txq = &priv->txq[txq_id]; - struct iwl_queue *q = &txq->q; - struct iwl_tx_info *tx_info; - - BUG_ON(txq_id == IWL39_CMD_QUEUE_NUM); - - for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index; - q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { - - tx_info = &txq->txb[txq->q.read_ptr]; - ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb); - tx_info->skb = NULL; - priv->cfg->ops->lib->txq_free_tfd(priv, txq); - } - - if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) && - (txq_id != IWL39_CMD_QUEUE_NUM) && - priv->mac80211_registered) - iwl_wake_queue(priv, txq); -} - -/** - * iwl3945_rx_reply_tx - Handle Tx response - */ -static void iwl3945_rx_reply_tx(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - u16 sequence = le16_to_cpu(pkt->hdr.sequence); - int txq_id = SEQ_TO_QUEUE(sequence); - int index = SEQ_TO_INDEX(sequence); - struct iwl_tx_queue *txq = &priv->txq[txq_id]; - struct ieee80211_tx_info *info; - struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; - u32 status = le32_to_cpu(tx_resp->status); - int rate_idx; - int fail; - - if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { - IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " - "is out of range [0-%d] %d %d\n", txq_id, - index, txq->q.n_bd, txq->q.write_ptr, - txq->q.read_ptr); - return; - } - - txq->time_stamp = jiffies; - info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); - ieee80211_tx_info_clear_status(info); - - /* Fill the MRR chain with some info about on-chip retransmissions */ - rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate); - if (info->band == IEEE80211_BAND_5GHZ) - rate_idx -= IWL_FIRST_OFDM_RATE; - - fail = tx_resp->failure_frame; - - info->status.rates[0].idx = rate_idx; - info->status.rates[0].count = fail + 1; /* add final attempt */ - - /* tx_status->rts_retry_count = tx_resp->failure_rts; */ - info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ? - IEEE80211_TX_STAT_ACK : 0; - - IWL_DEBUG_TX(priv, "Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n", - txq_id, iwl3945_get_tx_fail_reason(status), status, - tx_resp->rate, tx_resp->failure_frame); - - IWL_DEBUG_TX_REPLY(priv, "Tx queue reclaim %d\n", index); - iwl3945_tx_queue_reclaim(priv, txq_id, index); - - if (status & TX_ABORT_REQUIRED_MSK) - IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); -} - - - -/***************************************************************************** - * - * Intel PRO/Wireless 3945ABG/BG Network Connection - * - * RX handler implementations - * - *****************************************************************************/ -#ifdef CONFIG_IWLWIFI_DEBUGFS -/* - * based on the assumption of all statistics counter are in DWORD - * FIXME: This function is for debugging, do not deal with - * the case of counters roll-over. - */ -static void iwl3945_accumulative_statistics(struct iwl_priv *priv, - __le32 *stats) -{ - int i; - __le32 *prev_stats; - u32 *accum_stats; - u32 *delta, *max_delta; - - prev_stats = (__le32 *)&priv->_3945.statistics; - accum_stats = (u32 *)&priv->_3945.accum_statistics; - delta = (u32 *)&priv->_3945.delta_statistics; - max_delta = (u32 *)&priv->_3945.max_delta; - - for (i = sizeof(__le32); i < sizeof(struct iwl3945_notif_statistics); - i += sizeof(__le32), stats++, prev_stats++, delta++, - max_delta++, accum_stats++) { - if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { - *delta = (le32_to_cpu(*stats) - - le32_to_cpu(*prev_stats)); - *accum_stats += *delta; - if (*delta > *max_delta) - *max_delta = *delta; - } - } - - /* reset accumulative statistics for "no-counter" type statistics */ - priv->_3945.accum_statistics.general.temperature = - priv->_3945.statistics.general.temperature; - priv->_3945.accum_statistics.general.ttl_timestamp = - priv->_3945.statistics.general.ttl_timestamp; -} -#endif - -/** - * iwl3945_good_plcp_health - checks for plcp error. - * - * When the plcp error is exceeding the thresholds, reset the radio - * to improve the throughput. - */ -static bool iwl3945_good_plcp_health(struct iwl_priv *priv, - struct iwl_rx_packet *pkt) -{ - bool rc = true; - struct iwl3945_notif_statistics current_stat; - int combined_plcp_delta; - unsigned int plcp_msec; - unsigned long plcp_received_jiffies; - - if (priv->cfg->base_params->plcp_delta_threshold == - IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { - IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); - return rc; - } - memcpy(¤t_stat, pkt->u.raw, sizeof(struct - iwl3945_notif_statistics)); - /* - * check for plcp_err and trigger radio reset if it exceeds - * the plcp error threshold plcp_delta. - */ - plcp_received_jiffies = jiffies; - plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - - (long) priv->plcp_jiffies); - priv->plcp_jiffies = plcp_received_jiffies; - /* - * check to make sure plcp_msec is not 0 to prevent division - * by zero. - */ - if (plcp_msec) { - combined_plcp_delta = - (le32_to_cpu(current_stat.rx.ofdm.plcp_err) - - le32_to_cpu(priv->_3945.statistics.rx.ofdm.plcp_err)); - - if ((combined_plcp_delta > 0) && - ((combined_plcp_delta * 100) / plcp_msec) > - priv->cfg->base_params->plcp_delta_threshold) { - /* - * if plcp_err exceed the threshold, the following - * data is printed in csv format: - * Text: plcp_err exceeded %d, - * Received ofdm.plcp_err, - * Current ofdm.plcp_err, - * combined_plcp_delta, - * plcp_msec - */ - IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " - "%u, %d, %u mSecs\n", - priv->cfg->base_params->plcp_delta_threshold, - le32_to_cpu(current_stat.rx.ofdm.plcp_err), - combined_plcp_delta, plcp_msec); - /* - * Reset the RF radio due to the high plcp - * error rate - */ - rc = false; - } - } - return rc; -} - -void iwl3945_hw_rx_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - - IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", - (int)sizeof(struct iwl3945_notif_statistics), - le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); -#ifdef CONFIG_IWLWIFI_DEBUGFS - iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw); -#endif - iwl_recover_from_statistics(priv, pkt); - - memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics)); -} - -void iwl3945_reply_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - __le32 *flag = (__le32 *)&pkt->u.raw; - - if (le32_to_cpu(*flag) & UCODE_STATISTICS_CLEAR_MSK) { -#ifdef CONFIG_IWLWIFI_DEBUGFS - memset(&priv->_3945.accum_statistics, 0, - sizeof(struct iwl3945_notif_statistics)); - memset(&priv->_3945.delta_statistics, 0, - sizeof(struct iwl3945_notif_statistics)); - memset(&priv->_3945.max_delta, 0, - sizeof(struct iwl3945_notif_statistics)); -#endif - IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); - } - iwl3945_hw_rx_statistics(priv, rxb); -} - - -/****************************************************************************** - * - * Misc. internal state and helper functions - * - ******************************************************************************/ - -/* This is necessary only for a number of statistics, see the caller. */ -static int iwl3945_is_network_packet(struct iwl_priv *priv, - struct ieee80211_hdr *header) -{ - /* Filter incoming packets to determine if they are targeted toward - * this network, discarding packets coming from ourselves */ - switch (priv->iw_mode) { - case NL80211_IFTYPE_ADHOC: /* Header: Dest. | Source | BSSID */ - /* packets to our IBSS update information */ - return !compare_ether_addr(header->addr3, priv->bssid); - case NL80211_IFTYPE_STATION: /* Header: Dest. | AP{BSSID} | Source */ - /* packets to our IBSS update information */ - return !compare_ether_addr(header->addr2, priv->bssid); - default: - return 1; - } -} - -static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, - struct ieee80211_rx_status *stats) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); - struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); - struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); - u16 len = le16_to_cpu(rx_hdr->len); - struct sk_buff *skb; - __le16 fc = hdr->frame_control; - - /* We received data from the HW, so stop the watchdog */ - if (unlikely(len + IWL39_RX_FRAME_SIZE > - PAGE_SIZE << priv->hw_params.rx_page_order)) { - IWL_DEBUG_DROP(priv, "Corruption detected!\n"); - return; - } - - /* We only process data packets if the interface is open */ - if (unlikely(!priv->is_open)) { - IWL_DEBUG_DROP_LIMIT(priv, - "Dropping packet while interface is not open.\n"); - return; - } - - skb = dev_alloc_skb(128); - if (!skb) { - IWL_ERR(priv, "dev_alloc_skb failed\n"); - return; - } - - if (!iwl3945_mod_params.sw_crypto) - iwl_set_decrypted_flag(priv, - (struct ieee80211_hdr *)rxb_addr(rxb), - le32_to_cpu(rx_end->status), stats); - - skb_add_rx_frag(skb, 0, rxb->page, - (void *)rx_hdr->payload - (void *)pkt, len); - - iwl_update_stats(priv, false, fc, len); - memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); - - ieee80211_rx(priv->hw, skb); - priv->alloc_rxb_page--; - rxb->page = NULL; -} - -#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) - -static void iwl3945_rx_reply_rx(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct ieee80211_hdr *header; - struct ieee80211_rx_status rx_status; - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); - struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); - struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); - u16 rx_stats_sig_avg __maybe_unused = le16_to_cpu(rx_stats->sig_avg); - u16 rx_stats_noise_diff __maybe_unused = le16_to_cpu(rx_stats->noise_diff); - u8 network_packet; - - rx_status.flag = 0; - rx_status.mactime = le64_to_cpu(rx_end->timestamp); - rx_status.band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? - IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; - rx_status.freq = - ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel), - rx_status.band); - - rx_status.rate_idx = iwl3945_hwrate_to_plcp_idx(rx_hdr->rate); - if (rx_status.band == IEEE80211_BAND_5GHZ) - rx_status.rate_idx -= IWL_FIRST_OFDM_RATE; - - rx_status.antenna = (le16_to_cpu(rx_hdr->phy_flags) & - RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4; - - /* set the preamble flag if appropriate */ - if (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK) - rx_status.flag |= RX_FLAG_SHORTPRE; - - if ((unlikely(rx_stats->phy_count > 20))) { - IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n", - rx_stats->phy_count); - return; - } - - if (!(rx_end->status & RX_RES_STATUS_NO_CRC32_ERROR) - || !(rx_end->status & RX_RES_STATUS_NO_RXE_OVERFLOW)) { - IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n", rx_end->status); - return; - } - - - - /* Convert 3945's rssi indicator to dBm */ - rx_status.signal = rx_stats->rssi - IWL39_RSSI_OFFSET; - - IWL_DEBUG_STATS(priv, "Rssi %d sig_avg %d noise_diff %d\n", - rx_status.signal, rx_stats_sig_avg, - rx_stats_noise_diff); - - header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); - - network_packet = iwl3945_is_network_packet(priv, header); - - IWL_DEBUG_STATS_LIMIT(priv, "[%c] %d RSSI:%d Signal:%u, Rate:%u\n", - network_packet ? '*' : ' ', - le16_to_cpu(rx_hdr->channel), - rx_status.signal, rx_status.signal, - rx_status.rate_idx); - - iwl_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len), header); - - if (network_packet) { - priv->_3945.last_beacon_time = - le32_to_cpu(rx_end->beacon_timestamp); - priv->_3945.last_tsf = le64_to_cpu(rx_end->timestamp); - priv->_3945.last_rx_rssi = rx_status.signal; - } - - iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status); -} - -int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, - struct iwl_tx_queue *txq, - dma_addr_t addr, u16 len, u8 reset, u8 pad) -{ - int count; - struct iwl_queue *q; - struct iwl3945_tfd *tfd, *tfd_tmp; - - q = &txq->q; - tfd_tmp = (struct iwl3945_tfd *)txq->tfds; - tfd = &tfd_tmp[q->write_ptr]; - - if (reset) - memset(tfd, 0, sizeof(*tfd)); - - count = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags)); - - if ((count >= NUM_TFD_CHUNKS) || (count < 0)) { - IWL_ERR(priv, "Error can not send more than %d chunks\n", - NUM_TFD_CHUNKS); - return -EINVAL; - } - - tfd->tbs[count].addr = cpu_to_le32(addr); - tfd->tbs[count].len = cpu_to_le32(len); - - count++; - - tfd->control_flags = cpu_to_le32(TFD_CTL_COUNT_SET(count) | - TFD_CTL_PAD_SET(pad)); - - return 0; -} - -/** - * iwl3945_hw_txq_free_tfd - Free one TFD, those at index [txq->q.read_ptr] - * - * Does NOT advance any indexes - */ -void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) -{ - struct iwl3945_tfd *tfd_tmp = (struct iwl3945_tfd *)txq->tfds; - int index = txq->q.read_ptr; - struct iwl3945_tfd *tfd = &tfd_tmp[index]; - struct pci_dev *dev = priv->pci_dev; - int i; - int counter; - - /* sanity check */ - counter = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags)); - if (counter > NUM_TFD_CHUNKS) { - IWL_ERR(priv, "Too many chunks: %i\n", counter); - /* @todo issue fatal error, it is quite serious situation */ - return; - } - - /* Unmap tx_cmd */ - if (counter) - pci_unmap_single(dev, - dma_unmap_addr(&txq->meta[index], mapping), - dma_unmap_len(&txq->meta[index], len), - PCI_DMA_TODEVICE); - - /* unmap chunks if any */ - - for (i = 1; i < counter; i++) - pci_unmap_single(dev, le32_to_cpu(tfd->tbs[i].addr), - le32_to_cpu(tfd->tbs[i].len), PCI_DMA_TODEVICE); - - /* free SKB */ - if (txq->txb) { - struct sk_buff *skb; - - skb = txq->txb[txq->q.read_ptr].skb; - - /* can be called from irqs-disabled context */ - if (skb) { - dev_kfree_skb_any(skb); - txq->txb[txq->q.read_ptr].skb = NULL; - } - } -} - -/** - * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD: - * -*/ -void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, - struct iwl_device_cmd *cmd, - struct ieee80211_tx_info *info, - struct ieee80211_hdr *hdr, - int sta_id, int tx_id) -{ - u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value; - u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT_3945); - u16 rate_mask; - int rate; - u8 rts_retry_limit; - u8 data_retry_limit; - __le32 tx_flags; - __le16 fc = hdr->frame_control; - struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload; - - rate = iwl3945_rates[rate_index].plcp; - tx_flags = tx_cmd->tx_flags; - - /* We need to figure out how to get the sta->supp_rates while - * in this running context */ - rate_mask = IWL_RATES_MASK_3945; - - /* Set retry limit on DATA packets and Probe Responses*/ - if (ieee80211_is_probe_resp(fc)) - data_retry_limit = 3; - else - data_retry_limit = IWL_DEFAULT_TX_RETRY; - tx_cmd->data_retry_limit = data_retry_limit; - - if (tx_id >= IWL39_CMD_QUEUE_NUM) - rts_retry_limit = 3; - else - rts_retry_limit = 7; - - if (data_retry_limit < rts_retry_limit) - rts_retry_limit = data_retry_limit; - tx_cmd->rts_retry_limit = rts_retry_limit; - - tx_cmd->rate = rate; - tx_cmd->tx_flags = tx_flags; - - /* OFDM */ - tx_cmd->supp_rates[0] = - ((rate_mask & IWL_OFDM_RATES_MASK) >> IWL_FIRST_OFDM_RATE) & 0xFF; - - /* CCK */ - tx_cmd->supp_rates[1] = (rate_mask & 0xF); - - IWL_DEBUG_RATE(priv, "Tx sta id: %d, rate: %d (plcp), flags: 0x%4X " - "cck/ofdm mask: 0x%x/0x%x\n", sta_id, - tx_cmd->rate, le32_to_cpu(tx_cmd->tx_flags), - tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]); -} - -static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate) -{ - unsigned long flags_spin; - struct iwl_station_entry *station; - - if (sta_id == IWL_INVALID_STATION) - return IWL_INVALID_STATION; - - spin_lock_irqsave(&priv->sta_lock, flags_spin); - station = &priv->stations[sta_id]; - - station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK; - station->sta.rate_n_flags = cpu_to_le16(tx_rate); - station->sta.mode = STA_CONTROL_MODIFY_MSK; - iwl_send_add_sta(priv, &station->sta, CMD_ASYNC); - spin_unlock_irqrestore(&priv->sta_lock, flags_spin); - - IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n", - sta_id, tx_rate); - return sta_id; -} - -static void iwl3945_set_pwr_vmain(struct iwl_priv *priv) -{ -/* - * (for documentation purposes) - * to set power to V_AUX, do - - if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) { - iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, - APMG_PS_CTRL_VAL_PWR_SRC_VAUX, - ~APMG_PS_CTRL_MSK_PWR_SRC); - - iwl_poll_bit(priv, CSR_GPIO_IN, - CSR_GPIO_IN_VAL_VAUX_PWR_SRC, - CSR_GPIO_IN_BIT_AUX_POWER, 5000); - } - */ - - iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, - APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, - ~APMG_PS_CTRL_MSK_PWR_SRC); - - iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC, - CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */ -} - -static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) -{ - iwl_write_direct32(priv, FH39_RCSR_RBD_BASE(0), rxq->bd_dma); - iwl_write_direct32(priv, FH39_RCSR_RPTR_ADDR(0), rxq->rb_stts_dma); - iwl_write_direct32(priv, FH39_RCSR_WPTR(0), 0); - iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), - FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE | - FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE | - FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN | - FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 | - (RX_QUEUE_SIZE_LOG << FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE) | - FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST | - (1 << FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH) | - FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH); - - /* fake read to flush all prev I/O */ - iwl_read_direct32(priv, FH39_RSSR_CTRL); - - return 0; -} - -static int iwl3945_tx_reset(struct iwl_priv *priv) -{ - - /* bypass mode */ - iwl_write_prph(priv, ALM_SCD_MODE_REG, 0x2); - - /* RA 0 is active */ - iwl_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01); - - /* all 6 fifo are active */ - iwl_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f); - - iwl_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000); - iwl_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002); - iwl_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004); - iwl_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005); - - iwl_write_direct32(priv, FH39_TSSR_CBB_BASE, - priv->_3945.shared_phys); - - iwl_write_direct32(priv, FH39_TSSR_MSG_CONFIG, - FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON | - FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON | - FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B | - FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON | - FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON | - FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH | - FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH); - - - return 0; -} - -/** - * iwl3945_txq_ctx_reset - Reset TX queue context - * - * Destroys all DMA structures and initialize them again - */ -static int iwl3945_txq_ctx_reset(struct iwl_priv *priv) -{ - int rc; - int txq_id, slots_num; - - iwl3945_hw_txq_ctx_free(priv); - - /* allocate tx queue structure */ - rc = iwl_alloc_txq_mem(priv); - if (rc) - return rc; - - /* Tx CMD queue */ - rc = iwl3945_tx_reset(priv); - if (rc) - goto error; - - /* Tx queue(s) */ - for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { - slots_num = (txq_id == IWL39_CMD_QUEUE_NUM) ? - TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; - rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num, - txq_id); - if (rc) { - IWL_ERR(priv, "Tx %d queue init failed\n", txq_id); - goto error; - } - } - - return rc; - - error: - iwl3945_hw_txq_ctx_free(priv); - return rc; -} - - -/* - * Start up 3945's basic functionality after it has been reset - * (e.g. after platform boot, or shutdown via iwl_apm_stop()) - * NOTE: This does not load uCode nor start the embedded processor - */ -static int iwl3945_apm_init(struct iwl_priv *priv) -{ - int ret = iwl_apm_init(priv); - - /* Clear APMG (NIC's internal power management) interrupts */ - iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0); - iwl_write_prph(priv, APMG_RTC_INT_STT_REG, 0xFFFFFFFF); - - /* Reset radio chip */ - iwl_set_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); - udelay(5); - iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); - - return ret; -} - -static void iwl3945_nic_config(struct iwl_priv *priv) -{ - struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; - unsigned long flags; - u8 rev_id = 0; - - spin_lock_irqsave(&priv->lock, flags); - - /* Determine HW type */ - pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id); - - IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); - - if (rev_id & PCI_CFG_REV_ID_BIT_RTP) - IWL_DEBUG_INFO(priv, "RTP type\n"); - else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) { - IWL_DEBUG_INFO(priv, "3945 RADIO-MB type\n"); - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR39_HW_IF_CONFIG_REG_BIT_3945_MB); - } else { - IWL_DEBUG_INFO(priv, "3945 RADIO-MM type\n"); - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR39_HW_IF_CONFIG_REG_BIT_3945_MM); - } - - if (EEPROM_SKU_CAP_OP_MODE_MRC == eeprom->sku_cap) { - IWL_DEBUG_INFO(priv, "SKU OP mode is mrc\n"); - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC); - } else - IWL_DEBUG_INFO(priv, "SKU OP mode is basic\n"); - - if ((eeprom->board_revision & 0xF0) == 0xD0) { - IWL_DEBUG_INFO(priv, "3945ABG revision is 0x%X\n", - eeprom->board_revision); - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE); - } else { - IWL_DEBUG_INFO(priv, "3945ABG revision is 0x%X\n", - eeprom->board_revision); - iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE); - } - - if (eeprom->almgor_m_version <= 1) { - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A); - IWL_DEBUG_INFO(priv, "Card M type A version is 0x%X\n", - eeprom->almgor_m_version); - } else { - IWL_DEBUG_INFO(priv, "Card M type B version is 0x%X\n", - eeprom->almgor_m_version); - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B); - } - spin_unlock_irqrestore(&priv->lock, flags); - - if (eeprom->sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE) - IWL_DEBUG_RF_KILL(priv, "SW RF KILL supported in EEPROM.\n"); - - if (eeprom->sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE) - IWL_DEBUG_RF_KILL(priv, "HW RF KILL supported in EEPROM.\n"); -} - -int iwl3945_hw_nic_init(struct iwl_priv *priv) -{ - int rc; - unsigned long flags; - struct iwl_rx_queue *rxq = &priv->rxq; - - spin_lock_irqsave(&priv->lock, flags); - priv->cfg->ops->lib->apm_ops.init(priv); - spin_unlock_irqrestore(&priv->lock, flags); - - iwl3945_set_pwr_vmain(priv); - - priv->cfg->ops->lib->apm_ops.config(priv); - - /* Allocate the RX queue, or reset if it is already allocated */ - if (!rxq->bd) { - rc = iwl_rx_queue_alloc(priv); - if (rc) { - IWL_ERR(priv, "Unable to initialize Rx queue\n"); - return -ENOMEM; - } - } else - iwl3945_rx_queue_reset(priv, rxq); - - iwl3945_rx_replenish(priv); - - iwl3945_rx_init(priv, rxq); - - - /* Look at using this instead: - rxq->need_update = 1; - iwl_rx_queue_update_write_ptr(priv, rxq); - */ - - iwl_write_direct32(priv, FH39_RCSR_WPTR(0), rxq->write & ~7); - - rc = iwl3945_txq_ctx_reset(priv); - if (rc) - return rc; - - set_bit(STATUS_INIT, &priv->status); - - return 0; -} - -/** - * iwl3945_hw_txq_ctx_free - Free TXQ Context - * - * Destroy all TX DMA queues and structures - */ -void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv) -{ - int txq_id; - - /* Tx queues */ - if (priv->txq) - for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; - txq_id++) - if (txq_id == IWL39_CMD_QUEUE_NUM) - iwl_cmd_queue_free(priv); - else - iwl_tx_queue_free(priv, txq_id); - - /* free tx queue structure */ - iwl_free_txq_mem(priv); -} - -void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv) -{ - int txq_id; - - /* stop SCD */ - iwl_write_prph(priv, ALM_SCD_MODE_REG, 0); - iwl_write_prph(priv, ALM_SCD_TXFACT_REG, 0); - - /* reset TFD queues */ - for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { - iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), 0x0); - iwl_poll_direct_bit(priv, FH39_TSSR_TX_STATUS, - FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id), - 1000); - } - - iwl3945_hw_txq_ctx_free(priv); -} - -/** - * iwl3945_hw_reg_adjust_power_by_temp - * return index delta into power gain settings table -*/ -static int iwl3945_hw_reg_adjust_power_by_temp(int new_reading, int old_reading) -{ - return (new_reading - old_reading) * (-11) / 100; -} - -/** - * iwl3945_hw_reg_temp_out_of_range - Keep temperature in sane range - */ -static inline int iwl3945_hw_reg_temp_out_of_range(int temperature) -{ - return ((temperature < -260) || (temperature > 25)) ? 1 : 0; -} - -int iwl3945_hw_get_temperature(struct iwl_priv *priv) -{ - return iwl_read32(priv, CSR_UCODE_DRV_GP2); -} - -/** - * iwl3945_hw_reg_txpower_get_temperature - * get the current temperature by reading from NIC -*/ -static int iwl3945_hw_reg_txpower_get_temperature(struct iwl_priv *priv) -{ - struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; - int temperature; - - temperature = iwl3945_hw_get_temperature(priv); - - /* driver's okay range is -260 to +25. - * human readable okay range is 0 to +285 */ - IWL_DEBUG_INFO(priv, "Temperature: %d\n", temperature + IWL_TEMP_CONVERT); - - /* handle insane temp reading */ - if (iwl3945_hw_reg_temp_out_of_range(temperature)) { - IWL_ERR(priv, "Error bad temperature value %d\n", temperature); - - /* if really really hot(?), - * substitute the 3rd band/group's temp measured at factory */ - if (priv->last_temperature > 100) - temperature = eeprom->groups[2].temperature; - else /* else use most recent "sane" value from driver */ - temperature = priv->last_temperature; - } - - return temperature; /* raw, not "human readable" */ -} - -/* Adjust Txpower only if temperature variance is greater than threshold. - * - * Both are lower than older versions' 9 degrees */ -#define IWL_TEMPERATURE_LIMIT_TIMER 6 - -/** - * is_temp_calib_needed - determines if new calibration is needed - * - * records new temperature in tx_mgr->temperature. - * replaces tx_mgr->last_temperature *only* if calib needed - * (assumes caller will actually do the calibration!). */ -static int is_temp_calib_needed(struct iwl_priv *priv) -{ - int temp_diff; - - priv->temperature = iwl3945_hw_reg_txpower_get_temperature(priv); - temp_diff = priv->temperature - priv->last_temperature; - - /* get absolute value */ - if (temp_diff < 0) { - IWL_DEBUG_POWER(priv, "Getting cooler, delta %d,\n", temp_diff); - temp_diff = -temp_diff; - } else if (temp_diff == 0) - IWL_DEBUG_POWER(priv, "Same temp,\n"); - else - IWL_DEBUG_POWER(priv, "Getting warmer, delta %d,\n", temp_diff); - - /* if we don't need calibration, *don't* update last_temperature */ - if (temp_diff < IWL_TEMPERATURE_LIMIT_TIMER) { - IWL_DEBUG_POWER(priv, "Timed thermal calib not needed\n"); - return 0; - } - - IWL_DEBUG_POWER(priv, "Timed thermal calib needed\n"); - - /* assume that caller will actually do calib ... - * update the "last temperature" value */ - priv->last_temperature = priv->temperature; - return 1; -} - -#define IWL_MAX_GAIN_ENTRIES 78 -#define IWL_CCK_FROM_OFDM_POWER_DIFF -5 -#define IWL_CCK_FROM_OFDM_INDEX_DIFF (10) - -/* radio and DSP power table, each step is 1/2 dB. - * 1st number is for RF analog gain, 2nd number is for DSP pre-DAC gain. */ -static struct iwl3945_tx_power power_gain_table[2][IWL_MAX_GAIN_ENTRIES] = { - { - {251, 127}, /* 2.4 GHz, highest power */ - {251, 127}, - {251, 127}, - {251, 127}, - {251, 125}, - {251, 110}, - {251, 105}, - {251, 98}, - {187, 125}, - {187, 115}, - {187, 108}, - {187, 99}, - {243, 119}, - {243, 111}, - {243, 105}, - {243, 97}, - {243, 92}, - {211, 106}, - {211, 100}, - {179, 120}, - {179, 113}, - {179, 107}, - {147, 125}, - {147, 119}, - {147, 112}, - {147, 106}, - {147, 101}, - {147, 97}, - {147, 91}, - {115, 107}, - {235, 121}, - {235, 115}, - {235, 109}, - {203, 127}, - {203, 121}, - {203, 115}, - {203, 108}, - {203, 102}, - {203, 96}, - {203, 92}, - {171, 110}, - {171, 104}, - {171, 98}, - {139, 116}, - {227, 125}, - {227, 119}, - {227, 113}, - {227, 107}, - {227, 101}, - {227, 96}, - {195, 113}, - {195, 106}, - {195, 102}, - {195, 95}, - {163, 113}, - {163, 106}, - {163, 102}, - {163, 95}, - {131, 113}, - {131, 106}, - {131, 102}, - {131, 95}, - {99, 113}, - {99, 106}, - {99, 102}, - {99, 95}, - {67, 113}, - {67, 106}, - {67, 102}, - {67, 95}, - {35, 113}, - {35, 106}, - {35, 102}, - {35, 95}, - {3, 113}, - {3, 106}, - {3, 102}, - {3, 95} }, /* 2.4 GHz, lowest power */ - { - {251, 127}, /* 5.x GHz, highest power */ - {251, 120}, - {251, 114}, - {219, 119}, - {219, 101}, - {187, 113}, - {187, 102}, - {155, 114}, - {155, 103}, - {123, 117}, - {123, 107}, - {123, 99}, - {123, 92}, - {91, 108}, - {59, 125}, - {59, 118}, - {59, 109}, - {59, 102}, - {59, 96}, - {59, 90}, - {27, 104}, - {27, 98}, - {27, 92}, - {115, 118}, - {115, 111}, - {115, 104}, - {83, 126}, - {83, 121}, - {83, 113}, - {83, 105}, - {83, 99}, - {51, 118}, - {51, 111}, - {51, 104}, - {51, 98}, - {19, 116}, - {19, 109}, - {19, 102}, - {19, 98}, - {19, 93}, - {171, 113}, - {171, 107}, - {171, 99}, - {139, 120}, - {139, 113}, - {139, 107}, - {139, 99}, - {107, 120}, - {107, 113}, - {107, 107}, - {107, 99}, - {75, 120}, - {75, 113}, - {75, 107}, - {75, 99}, - {43, 120}, - {43, 113}, - {43, 107}, - {43, 99}, - {11, 120}, - {11, 113}, - {11, 107}, - {11, 99}, - {131, 107}, - {131, 99}, - {99, 120}, - {99, 113}, - {99, 107}, - {99, 99}, - {67, 120}, - {67, 113}, - {67, 107}, - {67, 99}, - {35, 120}, - {35, 113}, - {35, 107}, - {35, 99}, - {3, 120} } /* 5.x GHz, lowest power */ -}; - -static inline u8 iwl3945_hw_reg_fix_power_index(int index) -{ - if (index < 0) - return 0; - if (index >= IWL_MAX_GAIN_ENTRIES) - return IWL_MAX_GAIN_ENTRIES - 1; - return (u8) index; -} - -/* Kick off thermal recalibration check every 60 seconds */ -#define REG_RECALIB_PERIOD (60) - -/** - * iwl3945_hw_reg_set_scan_power - Set Tx power for scan probe requests - * - * Set (in our channel info database) the direct scan Tx power for 1 Mbit (CCK) - * or 6 Mbit (OFDM) rates. - */ -static void iwl3945_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index, - s32 rate_index, const s8 *clip_pwrs, - struct iwl_channel_info *ch_info, - int band_index) -{ - struct iwl3945_scan_power_info *scan_power_info; - s8 power; - u8 power_index; - - scan_power_info = &ch_info->scan_pwr_info[scan_tbl_index]; - - /* use this channel group's 6Mbit clipping/saturation pwr, - * but cap at regulatory scan power restriction (set during init - * based on eeprom channel data) for this channel. */ - power = min(ch_info->scan_power, clip_pwrs[IWL_RATE_6M_INDEX_TABLE]); - - /* further limit to user's max power preference. - * FIXME: Other spectrum management power limitations do not - * seem to apply?? */ - power = min(power, priv->tx_power_user_lmt); - scan_power_info->requested_power = power; - - /* find difference between new scan *power* and current "normal" - * Tx *power* for 6Mb. Use this difference (x2) to adjust the - * current "normal" temperature-compensated Tx power *index* for - * this rate (1Mb or 6Mb) to yield new temp-compensated scan power - * *index*. */ - power_index = ch_info->power_info[rate_index].power_table_index - - (power - ch_info->power_info - [IWL_RATE_6M_INDEX_TABLE].requested_power) * 2; - - /* store reference index that we use when adjusting *all* scan - * powers. So we can accommodate user (all channel) or spectrum - * management (single channel) power changes "between" temperature - * feedback compensation procedures. - * don't force fit this reference index into gain table; it may be a - * negative number. This will help avoid errors when we're at - * the lower bounds (highest gains, for warmest temperatures) - * of the table. */ - - /* don't exceed table bounds for "real" setting */ - power_index = iwl3945_hw_reg_fix_power_index(power_index); - - scan_power_info->power_table_index = power_index; - scan_power_info->tpc.tx_gain = - power_gain_table[band_index][power_index].tx_gain; - scan_power_info->tpc.dsp_atten = - power_gain_table[band_index][power_index].dsp_atten; -} - -/** - * iwl3945_send_tx_power - fill in Tx Power command with gain settings - * - * Configures power settings for all rates for the current channel, - * using values from channel info struct, and send to NIC - */ -static int iwl3945_send_tx_power(struct iwl_priv *priv) -{ - int rate_idx, i; - const struct iwl_channel_info *ch_info = NULL; - struct iwl3945_txpowertable_cmd txpower = { - .channel = priv->contexts[IWL_RXON_CTX_BSS].active.channel, - }; - u16 chan; - - if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status), - "TX Power requested while scanning!\n")) - return -EAGAIN; - - chan = le16_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.channel); - - txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1; - ch_info = iwl_get_channel_info(priv, priv->band, chan); - if (!ch_info) { - IWL_ERR(priv, - "Failed to get channel info for channel %d [%d]\n", - chan, priv->band); - return -EINVAL; - } - - if (!is_channel_valid(ch_info)) { - IWL_DEBUG_POWER(priv, "Not calling TX_PWR_TABLE_CMD on " - "non-Tx channel.\n"); - return 0; - } - - /* fill cmd with power settings for all rates for current channel */ - /* Fill OFDM rate */ - for (rate_idx = IWL_FIRST_OFDM_RATE, i = 0; - rate_idx <= IWL39_LAST_OFDM_RATE; rate_idx++, i++) { - - txpower.power[i].tpc = ch_info->power_info[i].tpc; - txpower.power[i].rate = iwl3945_rates[rate_idx].plcp; - - IWL_DEBUG_POWER(priv, "ch %d:%d rf %d dsp %3d rate code 0x%02x\n", - le16_to_cpu(txpower.channel), - txpower.band, - txpower.power[i].tpc.tx_gain, - txpower.power[i].tpc.dsp_atten, - txpower.power[i].rate); - } - /* Fill CCK rates */ - for (rate_idx = IWL_FIRST_CCK_RATE; - rate_idx <= IWL_LAST_CCK_RATE; rate_idx++, i++) { - txpower.power[i].tpc = ch_info->power_info[i].tpc; - txpower.power[i].rate = iwl3945_rates[rate_idx].plcp; - - IWL_DEBUG_POWER(priv, "ch %d:%d rf %d dsp %3d rate code 0x%02x\n", - le16_to_cpu(txpower.channel), - txpower.band, - txpower.power[i].tpc.tx_gain, - txpower.power[i].tpc.dsp_atten, - txpower.power[i].rate); - } - - return iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, - sizeof(struct iwl3945_txpowertable_cmd), - &txpower); - -} - -/** - * iwl3945_hw_reg_set_new_power - Configures power tables at new levels - * @ch_info: Channel to update. Uses power_info.requested_power. - * - * Replace requested_power and base_power_index ch_info fields for - * one channel. - * - * Called if user or spectrum management changes power preferences. - * Takes into account h/w and modulation limitations (clip power). - * - * This does *not* send anything to NIC, just sets up ch_info for one channel. - * - * NOTE: reg_compensate_for_temperature_dif() *must* be run after this to - * properly fill out the scan powers, and actual h/w gain settings, - * and send changes to NIC - */ -static int iwl3945_hw_reg_set_new_power(struct iwl_priv *priv, - struct iwl_channel_info *ch_info) -{ - struct iwl3945_channel_power_info *power_info; - int power_changed = 0; - int i; - const s8 *clip_pwrs; - int power; - - /* Get this chnlgrp's rate-to-max/clip-powers table */ - clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers; - - /* Get this channel's rate-to-current-power settings table */ - power_info = ch_info->power_info; - - /* update OFDM Txpower settings */ - for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; - i++, ++power_info) { - int delta_idx; - - /* limit new power to be no more than h/w capability */ - power = min(ch_info->curr_txpow, clip_pwrs[i]); - if (power == power_info->requested_power) - continue; - - /* find difference between old and new requested powers, - * update base (non-temp-compensated) power index */ - delta_idx = (power - power_info->requested_power) * 2; - power_info->base_power_index -= delta_idx; - - /* save new requested power value */ - power_info->requested_power = power; - - power_changed = 1; - } - - /* update CCK Txpower settings, based on OFDM 12M setting ... - * ... all CCK power settings for a given channel are the *same*. */ - if (power_changed) { - power = - ch_info->power_info[IWL_RATE_12M_INDEX_TABLE]. - requested_power + IWL_CCK_FROM_OFDM_POWER_DIFF; - - /* do all CCK rates' iwl3945_channel_power_info structures */ - for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++) { - power_info->requested_power = power; - power_info->base_power_index = - ch_info->power_info[IWL_RATE_12M_INDEX_TABLE]. - base_power_index + IWL_CCK_FROM_OFDM_INDEX_DIFF; - ++power_info; - } - } - - return 0; -} - -/** - * iwl3945_hw_reg_get_ch_txpower_limit - returns new power limit for channel - * - * NOTE: Returned power limit may be less (but not more) than requested, - * based strictly on regulatory (eeprom and spectrum mgt) limitations - * (no consideration for h/w clipping limitations). - */ -static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl_channel_info *ch_info) -{ - s8 max_power; - -#if 0 - /* if we're using TGd limits, use lower of TGd or EEPROM */ - if (ch_info->tgd_data.max_power != 0) - max_power = min(ch_info->tgd_data.max_power, - ch_info->eeprom.max_power_avg); - - /* else just use EEPROM limits */ - else -#endif - max_power = ch_info->eeprom.max_power_avg; - - return min(max_power, ch_info->max_power_avg); -} - -/** - * iwl3945_hw_reg_comp_txpower_temp - Compensate for temperature - * - * Compensate txpower settings of *all* channels for temperature. - * This only accounts for the difference between current temperature - * and the factory calibration temperatures, and bases the new settings - * on the channel's base_power_index. - * - * If RxOn is "associated", this sends the new Txpower to NIC! - */ -static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv) -{ - struct iwl_channel_info *ch_info = NULL; - struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; - int delta_index; - const s8 *clip_pwrs; /* array of h/w max power levels for each rate */ - u8 a_band; - u8 rate_index; - u8 scan_tbl_index; - u8 i; - int ref_temp; - int temperature = priv->temperature; - - if (priv->disable_tx_power_cal || - test_bit(STATUS_SCANNING, &priv->status)) { - /* do not perform tx power calibration */ - return 0; - } - /* set up new Tx power info for each and every channel, 2.4 and 5.x */ - for (i = 0; i < priv->channel_count; i++) { - ch_info = &priv->channel_info[i]; - a_band = is_channel_a_band(ch_info); - - /* Get this chnlgrp's factory calibration temperature */ - ref_temp = (s16)eeprom->groups[ch_info->group_index]. - temperature; - - /* get power index adjustment based on current and factory - * temps */ - delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature, - ref_temp); - - /* set tx power value for all rates, OFDM and CCK */ - for (rate_index = 0; rate_index < IWL_RATE_COUNT_3945; - rate_index++) { - int power_idx = - ch_info->power_info[rate_index].base_power_index; - - /* temperature compensate */ - power_idx += delta_index; - - /* stay within table range */ - power_idx = iwl3945_hw_reg_fix_power_index(power_idx); - ch_info->power_info[rate_index]. - power_table_index = (u8) power_idx; - ch_info->power_info[rate_index].tpc = - power_gain_table[a_band][power_idx]; - } - - /* Get this chnlgrp's rate-to-max/clip-powers table */ - clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers; - - /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */ - for (scan_tbl_index = 0; - scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) { - s32 actual_index = (scan_tbl_index == 0) ? - IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE; - iwl3945_hw_reg_set_scan_power(priv, scan_tbl_index, - actual_index, clip_pwrs, - ch_info, a_band); - } - } - - /* send Txpower command for current channel to ucode */ - return priv->cfg->ops->lib->send_tx_power(priv); -} - -int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power) -{ - struct iwl_channel_info *ch_info; - s8 max_power; - u8 a_band; - u8 i; - - if (priv->tx_power_user_lmt == power) { - IWL_DEBUG_POWER(priv, "Requested Tx power same as current " - "limit: %ddBm.\n", power); - return 0; - } - - IWL_DEBUG_POWER(priv, "Setting upper limit clamp to %ddBm.\n", power); - priv->tx_power_user_lmt = power; - - /* set up new Tx powers for each and every channel, 2.4 and 5.x */ - - for (i = 0; i < priv->channel_count; i++) { - ch_info = &priv->channel_info[i]; - a_band = is_channel_a_band(ch_info); - - /* find minimum power of all user and regulatory constraints - * (does not consider h/w clipping limitations) */ - max_power = iwl3945_hw_reg_get_ch_txpower_limit(ch_info); - max_power = min(power, max_power); - if (max_power != ch_info->curr_txpow) { - ch_info->curr_txpow = max_power; - - /* this considers the h/w clipping limitations */ - iwl3945_hw_reg_set_new_power(priv, ch_info); - } - } - - /* update txpower settings for all channels, - * send to NIC if associated. */ - is_temp_calib_needed(priv); - iwl3945_hw_reg_comp_txpower_temp(priv); - - return 0; -} - -static int iwl3945_send_rxon_assoc(struct iwl_priv *priv, - struct iwl_rxon_context *ctx) -{ - int rc = 0; - struct iwl_rx_packet *pkt; - struct iwl3945_rxon_assoc_cmd rxon_assoc; - struct iwl_host_cmd cmd = { - .id = REPLY_RXON_ASSOC, - .len = sizeof(rxon_assoc), - .flags = CMD_WANT_SKB, - .data = &rxon_assoc, - }; - const struct iwl_rxon_cmd *rxon1 = &ctx->staging; - const struct iwl_rxon_cmd *rxon2 = &ctx->active; - - if ((rxon1->flags == rxon2->flags) && - (rxon1->filter_flags == rxon2->filter_flags) && - (rxon1->cck_basic_rates == rxon2->cck_basic_rates) && - (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) { - IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n"); - return 0; - } - - rxon_assoc.flags = ctx->staging.flags; - rxon_assoc.filter_flags = ctx->staging.filter_flags; - rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; - rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; - rxon_assoc.reserved = 0; - - rc = iwl_send_cmd_sync(priv, &cmd); - if (rc) - return rc; - - pkt = (struct iwl_rx_packet *)cmd.reply_page; - if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { - IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n"); - rc = -EIO; - } - - iwl_free_pages(priv, cmd.reply_page); - - return rc; -} - -/** - * iwl3945_commit_rxon - commit staging_rxon to hardware - * - * The RXON command in staging_rxon is committed to the hardware and - * the active_rxon structure is updated with the new data. This - * function correctly transitions out of the RXON_ASSOC_MSK state if - * a HW tune is required based on the RXON structure changes. - */ -int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) -{ - /* cast away the const for active_rxon in this function */ - struct iwl3945_rxon_cmd *active_rxon = (void *)&ctx->active; - struct iwl3945_rxon_cmd *staging_rxon = (void *)&ctx->staging; - int rc = 0; - bool new_assoc = !!(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return -EINVAL; - - if (!iwl_is_alive(priv)) - return -1; - - /* always get timestamp with Rx frame */ - staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK; - - /* select antenna */ - staging_rxon->flags &= - ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK); - staging_rxon->flags |= iwl3945_get_antenna_flags(priv); - - rc = iwl_check_rxon_cmd(priv, ctx); - if (rc) { - IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); - return -EINVAL; - } - - /* If we don't need to send a full RXON, we can use - * iwl3945_rxon_assoc_cmd which is used to reconfigure filter - * and other flags for the current radio configuration. */ - if (!iwl_full_rxon_required(priv, &priv->contexts[IWL_RXON_CTX_BSS])) { - rc = iwl_send_rxon_assoc(priv, - &priv->contexts[IWL_RXON_CTX_BSS]); - if (rc) { - IWL_ERR(priv, "Error setting RXON_ASSOC " - "configuration (%d).\n", rc); - return rc; - } - - memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); - - return 0; - } - - /* If we are currently associated and the new config requires - * an RXON_ASSOC and the new config wants the associated mask enabled, - * we must clear the associated from the active configuration - * before we apply the new config */ - if (iwl_is_associated(priv, IWL_RXON_CTX_BSS) && new_assoc) { - IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); - active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - - /* - * reserved4 and 5 could have been filled by the iwlcore code. - * Let's clear them before pushing to the 3945. - */ - active_rxon->reserved4 = 0; - active_rxon->reserved5 = 0; - rc = iwl_send_cmd_pdu(priv, REPLY_RXON, - sizeof(struct iwl3945_rxon_cmd), - &priv->contexts[IWL_RXON_CTX_BSS].active); - - /* If the mask clearing failed then we set - * active_rxon back to what it was previously */ - if (rc) { - active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; - IWL_ERR(priv, "Error clearing ASSOC_MSK on current " - "configuration (%d).\n", rc); - return rc; - } - iwl_clear_ucode_stations(priv, - &priv->contexts[IWL_RXON_CTX_BSS]); - iwl_restore_stations(priv, &priv->contexts[IWL_RXON_CTX_BSS]); - } - - IWL_DEBUG_INFO(priv, "Sending RXON\n" - "* with%s RXON_FILTER_ASSOC_MSK\n" - "* channel = %d\n" - "* bssid = %pM\n", - (new_assoc ? "" : "out"), - le16_to_cpu(staging_rxon->channel), - staging_rxon->bssid_addr); - - /* - * reserved4 and 5 could have been filled by the iwlcore code. - * Let's clear them before pushing to the 3945. - */ - staging_rxon->reserved4 = 0; - staging_rxon->reserved5 = 0; - - iwl_set_rxon_hwcrypto(priv, ctx, !iwl3945_mod_params.sw_crypto); - - /* Apply the new configuration */ - rc = iwl_send_cmd_pdu(priv, REPLY_RXON, - sizeof(struct iwl3945_rxon_cmd), - staging_rxon); - if (rc) { - IWL_ERR(priv, "Error setting new configuration (%d).\n", rc); - return rc; - } - - memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); - - if (!new_assoc) { - iwl_clear_ucode_stations(priv, - &priv->contexts[IWL_RXON_CTX_BSS]); - iwl_restore_stations(priv, &priv->contexts[IWL_RXON_CTX_BSS]); - } - - /* If we issue a new RXON command which required a tune then we must - * send a new TXPOWER command or we won't be able to Tx any frames */ - rc = iwl_set_tx_power(priv, priv->tx_power_next, true); - if (rc) { - IWL_ERR(priv, "Error setting Tx power (%d).\n", rc); - return rc; - } - - /* Init the hardware's rate fallback order based on the band */ - rc = iwl3945_init_hw_rate_table(priv); - if (rc) { - IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc); - return -EIO; - } - - return 0; -} - -/** - * iwl3945_reg_txpower_periodic - called when time to check our temperature. - * - * -- reset periodic timer - * -- see if temp has changed enough to warrant re-calibration ... if so: - * -- correct coeffs for temp (can reset temp timer) - * -- save this temp as "last", - * -- send new set of gain settings to NIC - * NOTE: This should continue working, even when we're not associated, - * so we can keep our internal table of scan powers current. */ -void iwl3945_reg_txpower_periodic(struct iwl_priv *priv) -{ - /* This will kick in the "brute force" - * iwl3945_hw_reg_comp_txpower_temp() below */ - if (!is_temp_calib_needed(priv)) - goto reschedule; - - /* Set up a new set of temp-adjusted TxPowers, send to NIC. - * This is based *only* on current temperature, - * ignoring any previous power measurements */ - iwl3945_hw_reg_comp_txpower_temp(priv); - - reschedule: - queue_delayed_work(priv->workqueue, - &priv->_3945.thermal_periodic, REG_RECALIB_PERIOD * HZ); -} - -static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work) -{ - struct iwl_priv *priv = container_of(work, struct iwl_priv, - _3945.thermal_periodic.work); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - mutex_lock(&priv->mutex); - iwl3945_reg_txpower_periodic(priv); - mutex_unlock(&priv->mutex); -} - -/** - * iwl3945_hw_reg_get_ch_grp_index - find the channel-group index (0-4) - * for the channel. - * - * This function is used when initializing channel-info structs. - * - * NOTE: These channel groups do *NOT* match the bands above! - * These channel groups are based on factory-tested channels; - * on A-band, EEPROM's "group frequency" entries represent the top - * channel in each group 1-4. Group 5 All B/G channels are in group 0. - */ -static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl_priv *priv, - const struct iwl_channel_info *ch_info) -{ - struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; - struct iwl3945_eeprom_txpower_group *ch_grp = &eeprom->groups[0]; - u8 group; - u16 group_index = 0; /* based on factory calib frequencies */ - u8 grp_channel; - - /* Find the group index for the channel ... don't use index 1(?) */ - if (is_channel_a_band(ch_info)) { - for (group = 1; group < 5; group++) { - grp_channel = ch_grp[group].group_channel; - if (ch_info->channel <= grp_channel) { - group_index = group; - break; - } - } - /* group 4 has a few channels *above* its factory cal freq */ - if (group == 5) - group_index = 4; - } else - group_index = 0; /* 2.4 GHz, group 0 */ - - IWL_DEBUG_POWER(priv, "Chnl %d mapped to grp %d\n", ch_info->channel, - group_index); - return group_index; -} - -/** - * iwl3945_hw_reg_get_matched_power_index - Interpolate to get nominal index - * - * Interpolate to get nominal (i.e. at factory calibration temperature) index - * into radio/DSP gain settings table for requested power. - */ -static int iwl3945_hw_reg_get_matched_power_index(struct iwl_priv *priv, - s8 requested_power, - s32 setting_index, s32 *new_index) -{ - const struct iwl3945_eeprom_txpower_group *chnl_grp = NULL; - struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; - s32 index0, index1; - s32 power = 2 * requested_power; - s32 i; - const struct iwl3945_eeprom_txpower_sample *samples; - s32 gains0, gains1; - s32 res; - s32 denominator; - - chnl_grp = &eeprom->groups[setting_index]; - samples = chnl_grp->samples; - for (i = 0; i < 5; i++) { - if (power == samples[i].power) { - *new_index = samples[i].gain_index; - return 0; - } - } - - if (power > samples[1].power) { - index0 = 0; - index1 = 1; - } else if (power > samples[2].power) { - index0 = 1; - index1 = 2; - } else if (power > samples[3].power) { - index0 = 2; - index1 = 3; - } else { - index0 = 3; - index1 = 4; - } - - denominator = (s32) samples[index1].power - (s32) samples[index0].power; - if (denominator == 0) - return -EINVAL; - gains0 = (s32) samples[index0].gain_index * (1 << 19); - gains1 = (s32) samples[index1].gain_index * (1 << 19); - res = gains0 + (gains1 - gains0) * - ((s32) power - (s32) samples[index0].power) / denominator + - (1 << 18); - *new_index = res >> 19; - return 0; -} - -static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv) -{ - u32 i; - s32 rate_index; - struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; - const struct iwl3945_eeprom_txpower_group *group; - - IWL_DEBUG_POWER(priv, "Initializing factory calib info from EEPROM\n"); - - for (i = 0; i < IWL_NUM_TX_CALIB_GROUPS; i++) { - s8 *clip_pwrs; /* table of power levels for each rate */ - s8 satur_pwr; /* saturation power for each chnl group */ - group = &eeprom->groups[i]; - - /* sanity check on factory saturation power value */ - if (group->saturation_power < 40) { - IWL_WARN(priv, "Error: saturation power is %d, " - "less than minimum expected 40\n", - group->saturation_power); - return; - } - - /* - * Derive requested power levels for each rate, based on - * hardware capabilities (saturation power for band). - * Basic value is 3dB down from saturation, with further - * power reductions for highest 3 data rates. These - * backoffs provide headroom for high rate modulation - * power peaks, without too much distortion (clipping). - */ - /* we'll fill in this array with h/w max power levels */ - clip_pwrs = (s8 *) priv->_3945.clip_groups[i].clip_powers; - - /* divide factory saturation power by 2 to find -3dB level */ - satur_pwr = (s8) (group->saturation_power >> 1); - - /* fill in channel group's nominal powers for each rate */ - for (rate_index = 0; - rate_index < IWL_RATE_COUNT_3945; rate_index++, clip_pwrs++) { - switch (rate_index) { - case IWL_RATE_36M_INDEX_TABLE: - if (i == 0) /* B/G */ - *clip_pwrs = satur_pwr; - else /* A */ - *clip_pwrs = satur_pwr - 5; - break; - case IWL_RATE_48M_INDEX_TABLE: - if (i == 0) - *clip_pwrs = satur_pwr - 7; - else - *clip_pwrs = satur_pwr - 10; - break; - case IWL_RATE_54M_INDEX_TABLE: - if (i == 0) - *clip_pwrs = satur_pwr - 9; - else - *clip_pwrs = satur_pwr - 12; - break; - default: - *clip_pwrs = satur_pwr; - break; - } - } - } -} - -/** - * iwl3945_txpower_set_from_eeprom - Set channel power info based on EEPROM - * - * Second pass (during init) to set up priv->channel_info - * - * Set up Tx-power settings in our channel info database for each VALID - * (for this geo/SKU) channel, at all Tx data rates, based on eeprom values - * and current temperature. - * - * Since this is based on current temperature (at init time), these values may - * not be valid for very long, but it gives us a starting/default point, - * and allows us to active (i.e. using Tx) scan. - * - * This does *not* write values to NIC, just sets up our internal table. - */ -int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv) -{ - struct iwl_channel_info *ch_info = NULL; - struct iwl3945_channel_power_info *pwr_info; - struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; - int delta_index; - u8 rate_index; - u8 scan_tbl_index; - const s8 *clip_pwrs; /* array of power levels for each rate */ - u8 gain, dsp_atten; - s8 power; - u8 pwr_index, base_pwr_index, a_band; - u8 i; - int temperature; - - /* save temperature reference, - * so we can determine next time to calibrate */ - temperature = iwl3945_hw_reg_txpower_get_temperature(priv); - priv->last_temperature = temperature; - - iwl3945_hw_reg_init_channel_groups(priv); - - /* initialize Tx power info for each and every channel, 2.4 and 5.x */ - for (i = 0, ch_info = priv->channel_info; i < priv->channel_count; - i++, ch_info++) { - a_band = is_channel_a_band(ch_info); - if (!is_channel_valid(ch_info)) - continue; - - /* find this channel's channel group (*not* "band") index */ - ch_info->group_index = - iwl3945_hw_reg_get_ch_grp_index(priv, ch_info); - - /* Get this chnlgrp's rate->max/clip-powers table */ - clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers; - - /* calculate power index *adjustment* value according to - * diff between current temperature and factory temperature */ - delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature, - eeprom->groups[ch_info->group_index]. - temperature); - - IWL_DEBUG_POWER(priv, "Delta index for channel %d: %d [%d]\n", - ch_info->channel, delta_index, temperature + - IWL_TEMP_CONVERT); - - /* set tx power value for all OFDM rates */ - for (rate_index = 0; rate_index < IWL_OFDM_RATES; - rate_index++) { - s32 uninitialized_var(power_idx); - int rc; - - /* use channel group's clip-power table, - * but don't exceed channel's max power */ - s8 pwr = min(ch_info->max_power_avg, - clip_pwrs[rate_index]); - - pwr_info = &ch_info->power_info[rate_index]; - - /* get base (i.e. at factory-measured temperature) - * power table index for this rate's power */ - rc = iwl3945_hw_reg_get_matched_power_index(priv, pwr, - ch_info->group_index, - &power_idx); - if (rc) { - IWL_ERR(priv, "Invalid power index\n"); - return rc; - } - pwr_info->base_power_index = (u8) power_idx; - - /* temperature compensate */ - power_idx += delta_index; - - /* stay within range of gain table */ - power_idx = iwl3945_hw_reg_fix_power_index(power_idx); - - /* fill 1 OFDM rate's iwl3945_channel_power_info struct */ - pwr_info->requested_power = pwr; - pwr_info->power_table_index = (u8) power_idx; - pwr_info->tpc.tx_gain = - power_gain_table[a_band][power_idx].tx_gain; - pwr_info->tpc.dsp_atten = - power_gain_table[a_band][power_idx].dsp_atten; - } - - /* set tx power for CCK rates, based on OFDM 12 Mbit settings*/ - pwr_info = &ch_info->power_info[IWL_RATE_12M_INDEX_TABLE]; - power = pwr_info->requested_power + - IWL_CCK_FROM_OFDM_POWER_DIFF; - pwr_index = pwr_info->power_table_index + - IWL_CCK_FROM_OFDM_INDEX_DIFF; - base_pwr_index = pwr_info->base_power_index + - IWL_CCK_FROM_OFDM_INDEX_DIFF; - - /* stay within table range */ - pwr_index = iwl3945_hw_reg_fix_power_index(pwr_index); - gain = power_gain_table[a_band][pwr_index].tx_gain; - dsp_atten = power_gain_table[a_band][pwr_index].dsp_atten; - - /* fill each CCK rate's iwl3945_channel_power_info structure - * NOTE: All CCK-rate Txpwrs are the same for a given chnl! - * NOTE: CCK rates start at end of OFDM rates! */ - for (rate_index = 0; - rate_index < IWL_CCK_RATES; rate_index++) { - pwr_info = &ch_info->power_info[rate_index+IWL_OFDM_RATES]; - pwr_info->requested_power = power; - pwr_info->power_table_index = pwr_index; - pwr_info->base_power_index = base_pwr_index; - pwr_info->tpc.tx_gain = gain; - pwr_info->tpc.dsp_atten = dsp_atten; - } - - /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */ - for (scan_tbl_index = 0; - scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) { - s32 actual_index = (scan_tbl_index == 0) ? - IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE; - iwl3945_hw_reg_set_scan_power(priv, scan_tbl_index, - actual_index, clip_pwrs, ch_info, a_band); - } - } - - return 0; -} - -int iwl3945_hw_rxq_stop(struct iwl_priv *priv) -{ - int rc; - - iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), 0); - rc = iwl_poll_direct_bit(priv, FH39_RSSR_STATUS, - FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); - if (rc < 0) - IWL_ERR(priv, "Can't stop Rx DMA.\n"); - - return 0; -} - -int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq) -{ - int txq_id = txq->q.id; - - struct iwl3945_shared *shared_data = priv->_3945.shared_virt; - - shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr); - - iwl_write_direct32(priv, FH39_CBCC_CTRL(txq_id), 0); - iwl_write_direct32(priv, FH39_CBCC_BASE(txq_id), 0); - - iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), - FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT | - FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF | - FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD | - FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL | - FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE); - - /* fake read to flush all prev. writes */ - iwl_read32(priv, FH39_TSSR_CBB_BASE); - - return 0; -} - -/* - * HCMD utils - */ -static u16 iwl3945_get_hcmd_size(u8 cmd_id, u16 len) -{ - switch (cmd_id) { - case REPLY_RXON: - return sizeof(struct iwl3945_rxon_cmd); - case POWER_TABLE_CMD: - return sizeof(struct iwl3945_powertable_cmd); - default: - return len; - } -} - - -static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) -{ - struct iwl3945_addsta_cmd *addsta = (struct iwl3945_addsta_cmd *)data; - addsta->mode = cmd->mode; - memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify)); - memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo)); - addsta->station_flags = cmd->station_flags; - addsta->station_flags_msk = cmd->station_flags_msk; - addsta->tid_disable_tx = cpu_to_le16(0); - addsta->rate_n_flags = cmd->rate_n_flags; - addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid; - addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid; - addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn; - - return (u16)sizeof(struct iwl3945_addsta_cmd); -} - -static int iwl3945_add_bssid_station(struct iwl_priv *priv, - const u8 *addr, u8 *sta_id_r) -{ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - int ret; - u8 sta_id; - unsigned long flags; - - if (sta_id_r) - *sta_id_r = IWL_INVALID_STATION; - - ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id); - if (ret) { - IWL_ERR(priv, "Unable to add station %pM\n", addr); - return ret; - } - - if (sta_id_r) - *sta_id_r = sta_id; - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].used |= IWL_STA_LOCAL; - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return 0; -} -static int iwl3945_manage_ibss_station(struct iwl_priv *priv, - struct ieee80211_vif *vif, bool add) -{ - struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; - int ret; - - if (add) { - ret = iwl3945_add_bssid_station(priv, vif->bss_conf.bssid, - &vif_priv->ibss_bssid_sta_id); - if (ret) - return ret; - - iwl3945_sync_sta(priv, vif_priv->ibss_bssid_sta_id, - (priv->band == IEEE80211_BAND_5GHZ) ? - IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP); - iwl3945_rate_scale_init(priv->hw, vif_priv->ibss_bssid_sta_id); - - return 0; - } - - return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id, - vif->bss_conf.bssid); -} - -/** - * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table - */ -int iwl3945_init_hw_rate_table(struct iwl_priv *priv) -{ - int rc, i, index, prev_index; - struct iwl3945_rate_scaling_cmd rate_cmd = { - .reserved = {0, 0, 0}, - }; - struct iwl3945_rate_scaling_info *table = rate_cmd.table; - - for (i = 0; i < ARRAY_SIZE(iwl3945_rates); i++) { - index = iwl3945_rates[i].table_rs_index; - - table[index].rate_n_flags = - iwl3945_hw_set_rate_n_flags(iwl3945_rates[i].plcp, 0); - table[index].try_cnt = priv->retry_rate; - prev_index = iwl3945_get_prev_ieee_rate(i); - table[index].next_rate_index = - iwl3945_rates[prev_index].table_rs_index; - } - - switch (priv->band) { - case IEEE80211_BAND_5GHZ: - IWL_DEBUG_RATE(priv, "Select A mode rate scale\n"); - /* If one of the following CCK rates is used, - * have it fall back to the 6M OFDM rate */ - for (i = IWL_RATE_1M_INDEX_TABLE; - i <= IWL_RATE_11M_INDEX_TABLE; i++) - table[i].next_rate_index = - iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index; - - /* Don't fall back to CCK rates */ - table[IWL_RATE_12M_INDEX_TABLE].next_rate_index = - IWL_RATE_9M_INDEX_TABLE; - - /* Don't drop out of OFDM rates */ - table[IWL_RATE_6M_INDEX_TABLE].next_rate_index = - iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index; - break; - - case IEEE80211_BAND_2GHZ: - IWL_DEBUG_RATE(priv, "Select B/G mode rate scale\n"); - /* If an OFDM rate is used, have it fall back to the - * 1M CCK rates */ - - if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) && - iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { - - index = IWL_FIRST_CCK_RATE; - for (i = IWL_RATE_6M_INDEX_TABLE; - i <= IWL_RATE_54M_INDEX_TABLE; i++) - table[i].next_rate_index = - iwl3945_rates[index].table_rs_index; - - index = IWL_RATE_11M_INDEX_TABLE; - /* CCK shouldn't fall back to OFDM... */ - table[index].next_rate_index = IWL_RATE_5M_INDEX_TABLE; - } - break; - - default: - WARN_ON(1); - break; - } - - /* Update the rate scaling for control frame Tx */ - rate_cmd.table_id = 0; - rc = iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd), - &rate_cmd); - if (rc) - return rc; - - /* Update the rate scaling for data frame Tx */ - rate_cmd.table_id = 1; - return iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd), - &rate_cmd); -} - -/* Called when initializing driver */ -int iwl3945_hw_set_hw_params(struct iwl_priv *priv) -{ - memset((void *)&priv->hw_params, 0, - sizeof(struct iwl_hw_params)); - - priv->_3945.shared_virt = - dma_alloc_coherent(&priv->pci_dev->dev, - sizeof(struct iwl3945_shared), - &priv->_3945.shared_phys, GFP_KERNEL); - if (!priv->_3945.shared_virt) { - IWL_ERR(priv, "failed to allocate pci memory\n"); - return -ENOMEM; - } - - /* Assign number of Usable TX queues */ - priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; - - priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd); - priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_3K); - priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; - priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; - priv->hw_params.max_stations = IWL3945_STATION_COUNT; - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL3945_BROADCAST_ID; - - priv->sta_key_max_num = STA_KEY_MAX_NUM; - - priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR; - priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL; - priv->hw_params.beacon_time_tsf_bits = IWL3945_EXT_BEACON_TIME_POS; - - return 0; -} - -unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv, - struct iwl3945_frame *frame, u8 rate) -{ - struct iwl3945_tx_beacon_cmd *tx_beacon_cmd; - unsigned int frame_size; - - tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u; - memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); - - tx_beacon_cmd->tx.sta_id = - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; - tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; - - frame_size = iwl3945_fill_beacon_frame(priv, - tx_beacon_cmd->frame, - sizeof(frame->u) - sizeof(*tx_beacon_cmd)); - - BUG_ON(frame_size > MAX_MPDU_SIZE); - tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); - - tx_beacon_cmd->tx.rate = rate; - tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK | - TX_CMD_FLG_TSF_MSK); - - /* supp_rates[0] == OFDM start at IWL_FIRST_OFDM_RATE*/ - tx_beacon_cmd->tx.supp_rates[0] = - (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; - - tx_beacon_cmd->tx.supp_rates[1] = - (IWL_CCK_BASIC_RATES_MASK & 0xF); - - return sizeof(struct iwl3945_tx_beacon_cmd) + frame_size; -} - -void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv) -{ - priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx; - priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx; -} - -void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv) -{ - INIT_DELAYED_WORK(&priv->_3945.thermal_periodic, - iwl3945_bg_reg_txpower_periodic); -} - -void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv) -{ - cancel_delayed_work(&priv->_3945.thermal_periodic); -} - -/* check contents of special bootstrap uCode SRAM */ -static int iwl3945_verify_bsm(struct iwl_priv *priv) - { - __le32 *image = priv->ucode_boot.v_addr; - u32 len = priv->ucode_boot.len; - u32 reg; - u32 val; - - IWL_DEBUG_INFO(priv, "Begin verify bsm\n"); - - /* verify BSM SRAM contents */ - val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG); - for (reg = BSM_SRAM_LOWER_BOUND; - reg < BSM_SRAM_LOWER_BOUND + len; - reg += sizeof(u32), image++) { - val = iwl_read_prph(priv, reg); - if (val != le32_to_cpu(*image)) { - IWL_ERR(priv, "BSM uCode verification failed at " - "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", - BSM_SRAM_LOWER_BOUND, - reg - BSM_SRAM_LOWER_BOUND, len, - val, le32_to_cpu(*image)); - return -EIO; - } - } - - IWL_DEBUG_INFO(priv, "BSM bootstrap uCode image OK\n"); - - return 0; -} - - -/****************************************************************************** - * - * EEPROM related functions - * - ******************************************************************************/ - -/* - * Clear the OWNER_MSK, to establish driver (instead of uCode running on - * embedded controller) as EEPROM reader; each read is a series of pulses - * to/from the EEPROM chip, not a single event, so even reads could conflict - * if they weren't arbitrated by some ownership mechanism. Here, the driver - * simply claims ownership, which should be safe when this function is called - * (i.e. before loading uCode!). - */ -static int iwl3945_eeprom_acquire_semaphore(struct iwl_priv *priv) -{ - _iwl_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK); - return 0; -} - - -static void iwl3945_eeprom_release_semaphore(struct iwl_priv *priv) -{ - return; -} - - /** - * iwl3945_load_bsm - Load bootstrap instructions - * - * BSM operation: - * - * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program - * in special SRAM that does not power down during RFKILL. When powering back - * up after power-saving sleeps (or during initial uCode load), the BSM loads - * the bootstrap program into the on-board processor, and starts it. - * - * The bootstrap program loads (via DMA) instructions and data for a new - * program from host DRAM locations indicated by the host driver in the - * BSM_DRAM_* registers. Once the new program is loaded, it starts - * automatically. - * - * When initializing the NIC, the host driver points the BSM to the - * "initialize" uCode image. This uCode sets up some internal data, then - * notifies host via "initialize alive" that it is complete. - * - * The host then replaces the BSM_DRAM_* pointer values to point to the - * normal runtime uCode instructions and a backup uCode data cache buffer - * (filled initially with starting data values for the on-board processor), - * then triggers the "initialize" uCode to load and launch the runtime uCode, - * which begins normal operation. - * - * When doing a power-save shutdown, runtime uCode saves data SRAM into - * the backup data cache in DRAM before SRAM is powered down. - * - * When powering back up, the BSM loads the bootstrap program. This reloads - * the runtime uCode instructions and the backup data cache into SRAM, - * and re-launches the runtime uCode from where it left off. - */ -static int iwl3945_load_bsm(struct iwl_priv *priv) -{ - __le32 *image = priv->ucode_boot.v_addr; - u32 len = priv->ucode_boot.len; - dma_addr_t pinst; - dma_addr_t pdata; - u32 inst_len; - u32 data_len; - int rc; - int i; - u32 done; - u32 reg_offset; - - IWL_DEBUG_INFO(priv, "Begin load bsm\n"); - - /* make sure bootstrap program is no larger than BSM's SRAM size */ - if (len > IWL39_MAX_BSM_SIZE) - return -EINVAL; - - /* Tell bootstrap uCode where to find the "Initialize" uCode - * in host DRAM ... host DRAM physical address bits 31:0 for 3945. - * NOTE: iwl3945_initialize_alive_start() will replace these values, - * after the "initialize" uCode has run, to point to - * runtime/protocol instructions and backup data cache. */ - pinst = priv->ucode_init.p_addr; - pdata = priv->ucode_init_data.p_addr; - inst_len = priv->ucode_init.len; - data_len = priv->ucode_init_data.len; - - iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); - iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); - iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); - iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); - - /* Fill BSM memory with bootstrap instructions */ - for (reg_offset = BSM_SRAM_LOWER_BOUND; - reg_offset < BSM_SRAM_LOWER_BOUND + len; - reg_offset += sizeof(u32), image++) - _iwl_write_prph(priv, reg_offset, - le32_to_cpu(*image)); - - rc = iwl3945_verify_bsm(priv); - if (rc) - return rc; - - /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ - iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); - iwl_write_prph(priv, BSM_WR_MEM_DST_REG, - IWL39_RTC_INST_LOWER_BOUND); - iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); - - /* Load bootstrap code into instruction SRAM now, - * to prepare to load "initialize" uCode */ - iwl_write_prph(priv, BSM_WR_CTRL_REG, - BSM_WR_CTRL_REG_BIT_START); - - /* Wait for load of bootstrap uCode to finish */ - for (i = 0; i < 100; i++) { - done = iwl_read_prph(priv, BSM_WR_CTRL_REG); - if (!(done & BSM_WR_CTRL_REG_BIT_START)) - break; - udelay(10); - } - if (i < 100) - IWL_DEBUG_INFO(priv, "BSM write complete, poll %d iterations\n", i); - else { - IWL_ERR(priv, "BSM write did not complete!\n"); - return -EIO; - } - - /* Enable future boot loads whenever power management unit triggers it - * (e.g. when powering back up after power-save shutdown) */ - iwl_write_prph(priv, BSM_WR_CTRL_REG, - BSM_WR_CTRL_REG_BIT_START_EN); - - return 0; -} - -static struct iwl_hcmd_ops iwl3945_hcmd = { - .rxon_assoc = iwl3945_send_rxon_assoc, - .commit_rxon = iwl3945_commit_rxon, - .send_bt_config = iwl_send_bt_config, -}; - -static struct iwl_lib_ops iwl3945_lib = { - .txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd, - .txq_free_tfd = iwl3945_hw_txq_free_tfd, - .txq_init = iwl3945_hw_tx_queue_init, - .load_ucode = iwl3945_load_bsm, - .dump_nic_event_log = iwl3945_dump_nic_event_log, - .dump_nic_error_log = iwl3945_dump_nic_error_log, - .apm_ops = { - .init = iwl3945_apm_init, - .config = iwl3945_nic_config, - }, - .eeprom_ops = { - .regulatory_bands = { - EEPROM_REGULATORY_BAND_1_CHANNELS, - EEPROM_REGULATORY_BAND_2_CHANNELS, - EEPROM_REGULATORY_BAND_3_CHANNELS, - EEPROM_REGULATORY_BAND_4_CHANNELS, - EEPROM_REGULATORY_BAND_5_CHANNELS, - EEPROM_REGULATORY_BAND_NO_HT40, - EEPROM_REGULATORY_BAND_NO_HT40, - }, - .acquire_semaphore = iwl3945_eeprom_acquire_semaphore, - .release_semaphore = iwl3945_eeprom_release_semaphore, - .query_addr = iwlcore_eeprom_query_addr, - }, - .send_tx_power = iwl3945_send_tx_power, - .is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr, - .isr_ops = { - .isr = iwl_isr_legacy, - }, - - .debugfs_ops = { - .rx_stats_read = iwl3945_ucode_rx_stats_read, - .tx_stats_read = iwl3945_ucode_tx_stats_read, - .general_stats_read = iwl3945_ucode_general_stats_read, - }, -}; - -static const struct iwl_legacy_ops iwl3945_legacy_ops = { - .post_associate = iwl3945_post_associate, - .config_ap = iwl3945_config_ap, - .manage_ibss_station = iwl3945_manage_ibss_station, -}; - -static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { - .get_hcmd_size = iwl3945_get_hcmd_size, - .build_addsta_hcmd = iwl3945_build_addsta_hcmd, - .tx_cmd_protection = iwl_legacy_tx_cmd_protection, - .request_scan = iwl3945_request_scan, - .post_scan = iwl3945_post_scan, -}; - -static const struct iwl_ops iwl3945_ops = { - .lib = &iwl3945_lib, - .hcmd = &iwl3945_hcmd, - .utils = &iwl3945_hcmd_utils, - .led = &iwl3945_led_ops, - .legacy = &iwl3945_legacy_ops, - .ieee80211_ops = &iwl3945_hw_ops, -}; - -static struct iwl_base_params iwl3945_base_params = { - .eeprom_size = IWL3945_EEPROM_IMG_SIZE, - .num_of_queues = IWL39_NUM_QUEUES, - .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL, - .set_l0s = false, - .use_bsm = true, - .use_isr_legacy = true, - .led_compensation = 64, - .broken_powersave = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, - .wd_timeout = IWL_DEF_WD_TIMEOUT, - .max_event_log_size = 512, - .tx_power_by_driver = true, -}; - -static struct iwl_cfg iwl3945_bg_cfg = { - .name = "3945BG", - .fw_name_pre = IWL3945_FW_PRE, - .ucode_api_max = IWL3945_UCODE_API_MAX, - .ucode_api_min = IWL3945_UCODE_API_MIN, - .sku = IWL_SKU_G, - .eeprom_ver = EEPROM_3945_EEPROM_VERSION, - .ops = &iwl3945_ops, - .mod_params = &iwl3945_mod_params, - .base_params = &iwl3945_base_params, - .led_mode = IWL_LED_BLINK, -}; - -static struct iwl_cfg iwl3945_abg_cfg = { - .name = "3945ABG", - .fw_name_pre = IWL3945_FW_PRE, - .ucode_api_max = IWL3945_UCODE_API_MAX, - .ucode_api_min = IWL3945_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G, - .eeprom_ver = EEPROM_3945_EEPROM_VERSION, - .ops = &iwl3945_ops, - .mod_params = &iwl3945_mod_params, - .base_params = &iwl3945_base_params, - .led_mode = IWL_LED_BLINK, -}; - -DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { - {IWL_PCI_DEVICE(0x4222, 0x1005, iwl3945_bg_cfg)}, - {IWL_PCI_DEVICE(0x4222, 0x1034, iwl3945_bg_cfg)}, - {IWL_PCI_DEVICE(0x4222, 0x1044, iwl3945_bg_cfg)}, - {IWL_PCI_DEVICE(0x4227, 0x1014, iwl3945_bg_cfg)}, - {IWL_PCI_DEVICE(0x4222, PCI_ANY_ID, iwl3945_abg_cfg)}, - {IWL_PCI_DEVICE(0x4227, PCI_ANY_ID, iwl3945_abg_cfg)}, - {0} -}; - -MODULE_DEVICE_TABLE(pci, iwl3945_hw_card_ids); diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h deleted file mode 100644 index 3eef1eb74a78..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ /dev/null @@ -1,308 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ -/* - * Please use this file (iwl-3945.h) for driver implementation definitions. - * Please use iwl-3945-commands.h for uCode API definitions. - * Please use iwl-3945-hw.h for hardware-related definitions. - */ - -#ifndef __iwl_3945_h__ -#define __iwl_3945_h__ - -#include /* for struct pci_device_id */ -#include -#include - -/* Hardware specific file defines the PCI IDs table for that hardware module */ -extern const struct pci_device_id iwl3945_hw_card_ids[]; - -#include "iwl-csr.h" -#include "iwl-prph.h" -#include "iwl-fh.h" -#include "iwl-3945-hw.h" -#include "iwl-debug.h" -#include "iwl-power.h" -#include "iwl-dev.h" -#include "iwl-led.h" - -/* Highest firmware API version supported */ -#define IWL3945_UCODE_API_MAX 2 - -/* Lowest firmware API version supported */ -#define IWL3945_UCODE_API_MIN 1 - -#define IWL3945_FW_PRE "iwlwifi-3945-" -#define _IWL3945_MODULE_FIRMWARE(api) IWL3945_FW_PRE #api ".ucode" -#define IWL3945_MODULE_FIRMWARE(api) _IWL3945_MODULE_FIRMWARE(api) - -/* Default noise level to report when noise measurement is not available. - * This may be because we're: - * 1) Not associated (4965, no beacon statistics being sent to driver) - * 2) Scanning (noise measurement does not apply to associated channel) - * 3) Receiving CCK (3945 delivers noise info only for OFDM frames) - * Use default noise value of -127 ... this is below the range of measurable - * Rx dBm for either 3945 or 4965, so it can indicate "unmeasurable" to user. - * Also, -127 works better than 0 when averaging frames with/without - * noise info (e.g. averaging might be done in app); measured dBm values are - * always negative ... using a negative value as the default keeps all - * averages within an s8's (used in some apps) range of negative values. */ -#define IWL_NOISE_MEAS_NOT_AVAILABLE (-127) - -/* Module parameters accessible from iwl-*.c */ -extern struct iwl_mod_params iwl3945_mod_params; - -struct iwl3945_rate_scale_data { - u64 data; - s32 success_counter; - s32 success_ratio; - s32 counter; - s32 average_tpt; - unsigned long stamp; -}; - -struct iwl3945_rs_sta { - spinlock_t lock; - struct iwl_priv *priv; - s32 *expected_tpt; - unsigned long last_partial_flush; - unsigned long last_flush; - u32 flush_time; - u32 last_tx_packets; - u32 tx_packets; - u8 tgg; - u8 flush_pending; - u8 start_rate; - struct timer_list rate_scale_flush; - struct iwl3945_rate_scale_data win[IWL_RATE_COUNT_3945]; -#ifdef CONFIG_MAC80211_DEBUGFS - struct dentry *rs_sta_dbgfs_stats_table_file; -#endif - - /* used to be in sta_info */ - int last_txrate_idx; -}; - - -/* - * The common struct MUST be first because it is shared between - * 3945 and agn! - */ -struct iwl3945_sta_priv { - struct iwl_station_priv_common common; - struct iwl3945_rs_sta rs_sta; -}; - -enum iwl3945_antenna { - IWL_ANTENNA_DIVERSITY, - IWL_ANTENNA_MAIN, - IWL_ANTENNA_AUX -}; - -/* - * RTS threshold here is total size [2347] minus 4 FCS bytes - * Per spec: - * a value of 0 means RTS on all data/management packets - * a value > max MSDU size means no RTS - * else RTS for data/management frames where MPDU is larger - * than RTS value. - */ -#define DEFAULT_RTS_THRESHOLD 2347U -#define MIN_RTS_THRESHOLD 0U -#define MAX_RTS_THRESHOLD 2347U -#define MAX_MSDU_SIZE 2304U -#define MAX_MPDU_SIZE 2346U -#define DEFAULT_BEACON_INTERVAL 100U -#define DEFAULT_SHORT_RETRY_LIMIT 7U -#define DEFAULT_LONG_RETRY_LIMIT 4U - -#define IWL_TX_FIFO_AC0 0 -#define IWL_TX_FIFO_AC1 1 -#define IWL_TX_FIFO_AC2 2 -#define IWL_TX_FIFO_AC3 3 -#define IWL_TX_FIFO_HCCA_1 5 -#define IWL_TX_FIFO_HCCA_2 6 -#define IWL_TX_FIFO_NONE 7 - -#define IEEE80211_DATA_LEN 2304 -#define IEEE80211_4ADDR_LEN 30 -#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) -#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) - -struct iwl3945_frame { - union { - struct ieee80211_hdr frame; - struct iwl3945_tx_beacon_cmd beacon; - u8 raw[IEEE80211_FRAME_LEN]; - u8 cmd[360]; - } u; - struct list_head list; -}; - -#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) -#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) -#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) - -#define SUP_RATE_11A_MAX_NUM_CHANNELS 8 -#define SUP_RATE_11B_MAX_NUM_CHANNELS 4 -#define SUP_RATE_11G_MAX_NUM_CHANNELS 12 - -#define IWL_SUPPORTED_RATES_IE_LEN 8 - -#define SCAN_INTERVAL 100 - -#define MAX_TID_COUNT 9 - -#define IWL_INVALID_RATE 0xFF -#define IWL_INVALID_VALUE -1 - -#define STA_PS_STATUS_WAKE 0 -#define STA_PS_STATUS_SLEEP 1 - -struct iwl3945_ibss_seq { - u8 mac[ETH_ALEN]; - u16 seq_num; - u16 frag_num; - unsigned long packet_time; - struct list_head list; -}; - -#define IWL_RX_HDR(x) ((struct iwl3945_rx_frame_hdr *)(\ - x->u.rx_frame.stats.payload + \ - x->u.rx_frame.stats.phy_count)) -#define IWL_RX_END(x) ((struct iwl3945_rx_frame_end *)(\ - IWL_RX_HDR(x)->payload + \ - le16_to_cpu(IWL_RX_HDR(x)->len))) -#define IWL_RX_STATS(x) (&x->u.rx_frame.stats) -#define IWL_RX_DATA(x) (IWL_RX_HDR(x)->payload) - - -/****************************************************************************** - * - * Functions implemented in iwl-base.c which are forward declared here - * for use by iwl-*.c - * - *****************************************************************************/ -extern int iwl3945_calc_db_from_ratio(int sig_ratio); -extern void iwl3945_rx_replenish(void *data); -extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); -extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, - struct ieee80211_hdr *hdr,int left); -extern int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, - char **buf, bool display); -extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv); - -/****************************************************************************** - * - * Functions implemented in iwl-[34]*.c which are forward declared here - * for use by iwl-base.c - * - * NOTE: The implementation of these functions are hardware specific - * which is why they are in the hardware specific files (vs. iwl-base.c) - * - * Naming convention -- - * iwl3945_ <-- Its part of iwlwifi (should be changed to iwl3945_) - * iwl3945_hw_ <-- Hardware specific (implemented in iwl-XXXX.c by all HW) - * iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX) - * iwl3945_bg_ <-- Called from work queue context - * iwl3945_mac_ <-- mac80211 callback - * - ****************************************************************************/ -extern void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv); -extern void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv); -extern void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv); -extern int iwl3945_hw_rxq_stop(struct iwl_priv *priv); -extern int iwl3945_hw_set_hw_params(struct iwl_priv *priv); -extern int iwl3945_hw_nic_init(struct iwl_priv *priv); -extern int iwl3945_hw_nic_stop_master(struct iwl_priv *priv); -extern void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv); -extern void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv); -extern int iwl3945_hw_nic_reset(struct iwl_priv *priv); -extern int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, - struct iwl_tx_queue *txq, - dma_addr_t addr, u16 len, - u8 reset, u8 pad); -extern void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, - struct iwl_tx_queue *txq); -extern int iwl3945_hw_get_temperature(struct iwl_priv *priv); -extern int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, - struct iwl_tx_queue *txq); -extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv, - struct iwl3945_frame *frame, u8 rate); -void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, - struct iwl_device_cmd *cmd, - struct ieee80211_tx_info *info, - struct ieee80211_hdr *hdr, - int sta_id, int tx_id); -extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv); -extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power); -extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); -void iwl3945_reply_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); -extern void iwl3945_disable_events(struct iwl_priv *priv); -extern int iwl4965_get_temperature(const struct iwl_priv *priv); -extern void iwl3945_post_associate(struct iwl_priv *priv); -extern void iwl3945_config_ap(struct iwl_priv *priv); - -extern int iwl3945_commit_rxon(struct iwl_priv *priv, - struct iwl_rxon_context *ctx); - -/** - * iwl3945_hw_find_station - Find station id for a given BSSID - * @bssid: MAC address of station ID to find - * - * NOTE: This should not be hardware specific but the code has - * not yet been merged into a single common layer for managing the - * station tables. - */ -extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid); - -extern struct ieee80211_ops iwl3945_hw_ops; - -/* - * Forward declare iwl-3945.c functions for iwl-base.c - */ -extern __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv); -extern int iwl3945_init_hw_rate_table(struct iwl_priv *priv); -extern void iwl3945_reg_txpower_periodic(struct iwl_priv *priv); -extern int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv); - -extern const struct iwl_channel_info *iwl3945_get_channel_info( - const struct iwl_priv *priv, enum ieee80211_band band, u16 channel); - -extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate); - -/* scanning */ -int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); -void iwl3945_post_scan(struct iwl_priv *priv); - -/* rates */ -extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945]; - -/* Requires full declaration of iwl_priv before including */ -#include "iwl-io.h" - -#endif diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h deleted file mode 100644 index 9166794eda0d..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h +++ /dev/null @@ -1,792 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ -/* - * Please use this file (iwl-4965-hw.h) only for hardware-related definitions. - * Use iwl-commands.h for uCode API definitions. - * Use iwl-dev.h for driver implementation definitions. - */ - -#ifndef __iwl_4965_hw_h__ -#define __iwl_4965_hw_h__ - -#include "iwl-fh.h" - -/* EEPROM */ -#define IWL4965_EEPROM_IMG_SIZE 1024 - -/* - * uCode queue management definitions ... - * The first queue used for block-ack aggregation is #7 (4965 only). - * All block-ack aggregation queues should map to Tx DMA/FIFO channel 7. - */ -#define IWL49_FIRST_AMPDU_QUEUE 7 - -/* Sizes and addresses for instruction and data memory (SRAM) in - * 4965's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ -#define IWL49_RTC_INST_LOWER_BOUND (0x000000) -#define IWL49_RTC_INST_UPPER_BOUND (0x018000) - -#define IWL49_RTC_DATA_LOWER_BOUND (0x800000) -#define IWL49_RTC_DATA_UPPER_BOUND (0x80A000) - -#define IWL49_RTC_INST_SIZE (IWL49_RTC_INST_UPPER_BOUND - \ - IWL49_RTC_INST_LOWER_BOUND) -#define IWL49_RTC_DATA_SIZE (IWL49_RTC_DATA_UPPER_BOUND - \ - IWL49_RTC_DATA_LOWER_BOUND) - -#define IWL49_MAX_INST_SIZE IWL49_RTC_INST_SIZE -#define IWL49_MAX_DATA_SIZE IWL49_RTC_DATA_SIZE - -/* Size of uCode instruction memory in bootstrap state machine */ -#define IWL49_MAX_BSM_SIZE BSM_SRAM_SIZE - -static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr) -{ - return (addr >= IWL49_RTC_DATA_LOWER_BOUND) && - (addr < IWL49_RTC_DATA_UPPER_BOUND); -} - -/********************* START TEMPERATURE *************************************/ - -/** - * 4965 temperature calculation. - * - * The driver must calculate the device temperature before calculating - * a txpower setting (amplifier gain is temperature dependent). The - * calculation uses 4 measurements, 3 of which (R1, R2, R3) are calibration - * values used for the life of the driver, and one of which (R4) is the - * real-time temperature indicator. - * - * uCode provides all 4 values to the driver via the "initialize alive" - * notification (see struct iwl4965_init_alive_resp). After the runtime uCode - * image loads, uCode updates the R4 value via statistics notifications - * (see STATISTICS_NOTIFICATION), which occur after each received beacon - * when associated, or can be requested via REPLY_STATISTICS_CMD. - * - * NOTE: uCode provides the R4 value as a 23-bit signed value. Driver - * must sign-extend to 32 bits before applying formula below. - * - * Formula: - * - * degrees Kelvin = ((97 * 259 * (R4 - R2) / (R3 - R1)) / 100) + 8 - * - * NOTE: The basic formula is 259 * (R4-R2) / (R3-R1). The 97/100 is - * an additional correction, which should be centered around 0 degrees - * Celsius (273 degrees Kelvin). The 8 (3 percent of 273) compensates for - * centering the 97/100 correction around 0 degrees K. - * - * Add 273 to Kelvin value to find degrees Celsius, for comparing current - * temperature with factory-measured temperatures when calculating txpower - * settings. - */ -#define TEMPERATURE_CALIB_KELVIN_OFFSET 8 -#define TEMPERATURE_CALIB_A_VAL 259 - -/* Limit range of calculated temperature to be between these Kelvin values */ -#define IWL_TX_POWER_TEMPERATURE_MIN (263) -#define IWL_TX_POWER_TEMPERATURE_MAX (410) - -#define IWL_TX_POWER_TEMPERATURE_OUT_OF_RANGE(t) \ - (((t) < IWL_TX_POWER_TEMPERATURE_MIN) || \ - ((t) > IWL_TX_POWER_TEMPERATURE_MAX)) - -/********************* END TEMPERATURE ***************************************/ - -/********************* START TXPOWER *****************************************/ - -/** - * 4965 txpower calculations rely on information from three sources: - * - * 1) EEPROM - * 2) "initialize" alive notification - * 3) statistics notifications - * - * EEPROM data consists of: - * - * 1) Regulatory information (max txpower and channel usage flags) is provided - * separately for each channel that can possibly supported by 4965. - * 40 MHz wide (.11n HT40) channels are listed separately from 20 MHz - * (legacy) channels. - * - * See struct iwl4965_eeprom_channel for format, and struct iwl4965_eeprom - * for locations in EEPROM. - * - * 2) Factory txpower calibration information is provided separately for - * sub-bands of contiguous channels. 2.4GHz has just one sub-band, - * but 5 GHz has several sub-bands. - * - * In addition, per-band (2.4 and 5 Ghz) saturation txpowers are provided. - * - * See struct iwl4965_eeprom_calib_info (and the tree of structures - * contained within it) for format, and struct iwl4965_eeprom for - * locations in EEPROM. - * - * "Initialization alive" notification (see struct iwl4965_init_alive_resp) - * consists of: - * - * 1) Temperature calculation parameters. - * - * 2) Power supply voltage measurement. - * - * 3) Tx gain compensation to balance 2 transmitters for MIMO use. - * - * Statistics notifications deliver: - * - * 1) Current values for temperature param R4. - */ - -/** - * To calculate a txpower setting for a given desired target txpower, channel, - * modulation bit rate, and transmitter chain (4965 has 2 transmitters to - * support MIMO and transmit diversity), driver must do the following: - * - * 1) Compare desired txpower vs. (EEPROM) regulatory limit for this channel. - * Do not exceed regulatory limit; reduce target txpower if necessary. - * - * If setting up txpowers for MIMO rates (rate indexes 8-15, 24-31), - * 2 transmitters will be used simultaneously; driver must reduce the - * regulatory limit by 3 dB (half-power) for each transmitter, so the - * combined total output of the 2 transmitters is within regulatory limits. - * - * - * 2) Compare target txpower vs. (EEPROM) saturation txpower *reduced by - * backoff for this bit rate*. Do not exceed (saturation - backoff[rate]); - * reduce target txpower if necessary. - * - * Backoff values below are in 1/2 dB units (equivalent to steps in - * txpower gain tables): - * - * OFDM 6 - 36 MBit: 10 steps (5 dB) - * OFDM 48 MBit: 15 steps (7.5 dB) - * OFDM 54 MBit: 17 steps (8.5 dB) - * OFDM 60 MBit: 20 steps (10 dB) - * CCK all rates: 10 steps (5 dB) - * - * Backoff values apply to saturation txpower on a per-transmitter basis; - * when using MIMO (2 transmitters), each transmitter uses the same - * saturation level provided in EEPROM, and the same backoff values; - * no reduction (such as with regulatory txpower limits) is required. - * - * Saturation and Backoff values apply equally to 20 Mhz (legacy) channel - * widths and 40 Mhz (.11n HT40) channel widths; there is no separate - * factory measurement for ht40 channels. - * - * The result of this step is the final target txpower. The rest of - * the steps figure out the proper settings for the device to achieve - * that target txpower. - * - * - * 3) Determine (EEPROM) calibration sub band for the target channel, by - * comparing against first and last channels in each sub band - * (see struct iwl4965_eeprom_calib_subband_info). - * - * - * 4) Linearly interpolate (EEPROM) factory calibration measurement sets, - * referencing the 2 factory-measured (sample) channels within the sub band. - * - * Interpolation is based on difference between target channel's frequency - * and the sample channels' frequencies. Since channel numbers are based - * on frequency (5 MHz between each channel number), this is equivalent - * to interpolating based on channel number differences. - * - * Note that the sample channels may or may not be the channels at the - * edges of the sub band. The target channel may be "outside" of the - * span of the sampled channels. - * - * Driver may choose the pair (for 2 Tx chains) of measurements (see - * struct iwl4965_eeprom_calib_ch_info) for which the actual measured - * txpower comes closest to the desired txpower. Usually, though, - * the middle set of measurements is closest to the regulatory limits, - * and is therefore a good choice for all txpower calculations (this - * assumes that high accuracy is needed for maximizing legal txpower, - * while lower txpower configurations do not need as much accuracy). - * - * Driver should interpolate both members of the chosen measurement pair, - * i.e. for both Tx chains (radio transmitters), unless the driver knows - * that only one of the chains will be used (e.g. only one tx antenna - * connected, but this should be unusual). The rate scaling algorithm - * switches antennas to find best performance, so both Tx chains will - * be used (although only one at a time) even for non-MIMO transmissions. - * - * Driver should interpolate factory values for temperature, gain table - * index, and actual power. The power amplifier detector values are - * not used by the driver. - * - * Sanity check: If the target channel happens to be one of the sample - * channels, the results should agree with the sample channel's - * measurements! - * - * - * 5) Find difference between desired txpower and (interpolated) - * factory-measured txpower. Using (interpolated) factory gain table index - * (shown elsewhere) as a starting point, adjust this index lower to - * increase txpower, or higher to decrease txpower, until the target - * txpower is reached. Each step in the gain table is 1/2 dB. - * - * For example, if factory measured txpower is 16 dBm, and target txpower - * is 13 dBm, add 6 steps to the factory gain index to reduce txpower - * by 3 dB. - * - * - * 6) Find difference between current device temperature and (interpolated) - * factory-measured temperature for sub-band. Factory values are in - * degrees Celsius. To calculate current temperature, see comments for - * "4965 temperature calculation". - * - * If current temperature is higher than factory temperature, driver must - * increase gain (lower gain table index), and vice verse. - * - * Temperature affects gain differently for different channels: - * - * 2.4 GHz all channels: 3.5 degrees per half-dB step - * 5 GHz channels 34-43: 4.5 degrees per half-dB step - * 5 GHz channels >= 44: 4.0 degrees per half-dB step - * - * NOTE: Temperature can increase rapidly when transmitting, especially - * with heavy traffic at high txpowers. Driver should update - * temperature calculations often under these conditions to - * maintain strong txpower in the face of rising temperature. - * - * - * 7) Find difference between current power supply voltage indicator - * (from "initialize alive") and factory-measured power supply voltage - * indicator (EEPROM). - * - * If the current voltage is higher (indicator is lower) than factory - * voltage, gain should be reduced (gain table index increased) by: - * - * (eeprom - current) / 7 - * - * If the current voltage is lower (indicator is higher) than factory - * voltage, gain should be increased (gain table index decreased) by: - * - * 2 * (current - eeprom) / 7 - * - * If number of index steps in either direction turns out to be > 2, - * something is wrong ... just use 0. - * - * NOTE: Voltage compensation is independent of band/channel. - * - * NOTE: "Initialize" uCode measures current voltage, which is assumed - * to be constant after this initial measurement. Voltage - * compensation for txpower (number of steps in gain table) - * may be calculated once and used until the next uCode bootload. - * - * - * 8) If setting up txpowers for MIMO rates (rate indexes 8-15, 24-31), - * adjust txpower for each transmitter chain, so txpower is balanced - * between the two chains. There are 5 pairs of tx_atten[group][chain] - * values in "initialize alive", one pair for each of 5 channel ranges: - * - * Group 0: 5 GHz channel 34-43 - * Group 1: 5 GHz channel 44-70 - * Group 2: 5 GHz channel 71-124 - * Group 3: 5 GHz channel 125-200 - * Group 4: 2.4 GHz all channels - * - * Add the tx_atten[group][chain] value to the index for the target chain. - * The values are signed, but are in pairs of 0 and a non-negative number, - * so as to reduce gain (if necessary) of the "hotter" channel. This - * avoids any need to double-check for regulatory compliance after - * this step. - * - * - * 9) If setting up for a CCK rate, lower the gain by adding a CCK compensation - * value to the index: - * - * Hardware rev B: 9 steps (4.5 dB) - * Hardware rev C: 5 steps (2.5 dB) - * - * Hardware rev for 4965 can be determined by reading CSR_HW_REV_WA_REG, - * bits [3:2], 1 = B, 2 = C. - * - * NOTE: This compensation is in addition to any saturation backoff that - * might have been applied in an earlier step. - * - * - * 10) Select the gain table, based on band (2.4 vs 5 GHz). - * - * Limit the adjusted index to stay within the table! - * - * - * 11) Read gain table entries for DSP and radio gain, place into appropriate - * location(s) in command (struct iwl4965_txpowertable_cmd). - */ - -/** - * When MIMO is used (2 transmitters operating simultaneously), driver should - * limit each transmitter to deliver a max of 3 dB below the regulatory limit - * for the device. That is, use half power for each transmitter, so total - * txpower is within regulatory limits. - * - * The value "6" represents number of steps in gain table to reduce power 3 dB. - * Each step is 1/2 dB. - */ -#define IWL_TX_POWER_MIMO_REGULATORY_COMPENSATION (6) - -/** - * CCK gain compensation. - * - * When calculating txpowers for CCK, after making sure that the target power - * is within regulatory and saturation limits, driver must additionally - * back off gain by adding these values to the gain table index. - * - * Hardware rev for 4965 can be determined by reading CSR_HW_REV_WA_REG, - * bits [3:2], 1 = B, 2 = C. - */ -#define IWL_TX_POWER_CCK_COMPENSATION_B_STEP (9) -#define IWL_TX_POWER_CCK_COMPENSATION_C_STEP (5) - -/* - * 4965 power supply voltage compensation for txpower - */ -#define TX_POWER_IWL_VOLTAGE_CODES_PER_03V (7) - -/** - * Gain tables. - * - * The following tables contain pair of values for setting txpower, i.e. - * gain settings for the output of the device's digital signal processor (DSP), - * and for the analog gain structure of the transmitter. - * - * Each entry in the gain tables represents a step of 1/2 dB. Note that these - * are *relative* steps, not indications of absolute output power. Output - * power varies with temperature, voltage, and channel frequency, and also - * requires consideration of average power (to satisfy regulatory constraints), - * and peak power (to avoid distortion of the output signal). - * - * Each entry contains two values: - * 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained - * linear value that multiplies the output of the digital signal processor, - * before being sent to the analog radio. - * 2) Radio gain. This sets the analog gain of the radio Tx path. - * It is a coarser setting, and behaves in a logarithmic (dB) fashion. - * - * EEPROM contains factory calibration data for txpower. This maps actual - * measured txpower levels to gain settings in the "well known" tables - * below ("well-known" means here that both factory calibration *and* the - * driver work with the same table). - * - * There are separate tables for 2.4 GHz and 5 GHz bands. The 5 GHz table - * has an extension (into negative indexes), in case the driver needs to - * boost power setting for high device temperatures (higher than would be - * present during factory calibration). A 5 Ghz EEPROM index of "40" - * corresponds to the 49th entry in the table used by the driver. - */ -#define MIN_TX_GAIN_INDEX (0) /* highest gain, lowest idx, 2.4 */ -#define MIN_TX_GAIN_INDEX_52GHZ_EXT (-9) /* highest gain, lowest idx, 5 */ - -/** - * 2.4 GHz gain table - * - * Index Dsp gain Radio gain - * 0 110 0x3f (highest gain) - * 1 104 0x3f - * 2 98 0x3f - * 3 110 0x3e - * 4 104 0x3e - * 5 98 0x3e - * 6 110 0x3d - * 7 104 0x3d - * 8 98 0x3d - * 9 110 0x3c - * 10 104 0x3c - * 11 98 0x3c - * 12 110 0x3b - * 13 104 0x3b - * 14 98 0x3b - * 15 110 0x3a - * 16 104 0x3a - * 17 98 0x3a - * 18 110 0x39 - * 19 104 0x39 - * 20 98 0x39 - * 21 110 0x38 - * 22 104 0x38 - * 23 98 0x38 - * 24 110 0x37 - * 25 104 0x37 - * 26 98 0x37 - * 27 110 0x36 - * 28 104 0x36 - * 29 98 0x36 - * 30 110 0x35 - * 31 104 0x35 - * 32 98 0x35 - * 33 110 0x34 - * 34 104 0x34 - * 35 98 0x34 - * 36 110 0x33 - * 37 104 0x33 - * 38 98 0x33 - * 39 110 0x32 - * 40 104 0x32 - * 41 98 0x32 - * 42 110 0x31 - * 43 104 0x31 - * 44 98 0x31 - * 45 110 0x30 - * 46 104 0x30 - * 47 98 0x30 - * 48 110 0x6 - * 49 104 0x6 - * 50 98 0x6 - * 51 110 0x5 - * 52 104 0x5 - * 53 98 0x5 - * 54 110 0x4 - * 55 104 0x4 - * 56 98 0x4 - * 57 110 0x3 - * 58 104 0x3 - * 59 98 0x3 - * 60 110 0x2 - * 61 104 0x2 - * 62 98 0x2 - * 63 110 0x1 - * 64 104 0x1 - * 65 98 0x1 - * 66 110 0x0 - * 67 104 0x0 - * 68 98 0x0 - * 69 97 0 - * 70 96 0 - * 71 95 0 - * 72 94 0 - * 73 93 0 - * 74 92 0 - * 75 91 0 - * 76 90 0 - * 77 89 0 - * 78 88 0 - * 79 87 0 - * 80 86 0 - * 81 85 0 - * 82 84 0 - * 83 83 0 - * 84 82 0 - * 85 81 0 - * 86 80 0 - * 87 79 0 - * 88 78 0 - * 89 77 0 - * 90 76 0 - * 91 75 0 - * 92 74 0 - * 93 73 0 - * 94 72 0 - * 95 71 0 - * 96 70 0 - * 97 69 0 - * 98 68 0 - */ - -/** - * 5 GHz gain table - * - * Index Dsp gain Radio gain - * -9 123 0x3F (highest gain) - * -8 117 0x3F - * -7 110 0x3F - * -6 104 0x3F - * -5 98 0x3F - * -4 110 0x3E - * -3 104 0x3E - * -2 98 0x3E - * -1 110 0x3D - * 0 104 0x3D - * 1 98 0x3D - * 2 110 0x3C - * 3 104 0x3C - * 4 98 0x3C - * 5 110 0x3B - * 6 104 0x3B - * 7 98 0x3B - * 8 110 0x3A - * 9 104 0x3A - * 10 98 0x3A - * 11 110 0x39 - * 12 104 0x39 - * 13 98 0x39 - * 14 110 0x38 - * 15 104 0x38 - * 16 98 0x38 - * 17 110 0x37 - * 18 104 0x37 - * 19 98 0x37 - * 20 110 0x36 - * 21 104 0x36 - * 22 98 0x36 - * 23 110 0x35 - * 24 104 0x35 - * 25 98 0x35 - * 26 110 0x34 - * 27 104 0x34 - * 28 98 0x34 - * 29 110 0x33 - * 30 104 0x33 - * 31 98 0x33 - * 32 110 0x32 - * 33 104 0x32 - * 34 98 0x32 - * 35 110 0x31 - * 36 104 0x31 - * 37 98 0x31 - * 38 110 0x30 - * 39 104 0x30 - * 40 98 0x30 - * 41 110 0x25 - * 42 104 0x25 - * 43 98 0x25 - * 44 110 0x24 - * 45 104 0x24 - * 46 98 0x24 - * 47 110 0x23 - * 48 104 0x23 - * 49 98 0x23 - * 50 110 0x22 - * 51 104 0x18 - * 52 98 0x18 - * 53 110 0x17 - * 54 104 0x17 - * 55 98 0x17 - * 56 110 0x16 - * 57 104 0x16 - * 58 98 0x16 - * 59 110 0x15 - * 60 104 0x15 - * 61 98 0x15 - * 62 110 0x14 - * 63 104 0x14 - * 64 98 0x14 - * 65 110 0x13 - * 66 104 0x13 - * 67 98 0x13 - * 68 110 0x12 - * 69 104 0x08 - * 70 98 0x08 - * 71 110 0x07 - * 72 104 0x07 - * 73 98 0x07 - * 74 110 0x06 - * 75 104 0x06 - * 76 98 0x06 - * 77 110 0x05 - * 78 104 0x05 - * 79 98 0x05 - * 80 110 0x04 - * 81 104 0x04 - * 82 98 0x04 - * 83 110 0x03 - * 84 104 0x03 - * 85 98 0x03 - * 86 110 0x02 - * 87 104 0x02 - * 88 98 0x02 - * 89 110 0x01 - * 90 104 0x01 - * 91 98 0x01 - * 92 110 0x00 - * 93 104 0x00 - * 94 98 0x00 - * 95 93 0x00 - * 96 88 0x00 - * 97 83 0x00 - * 98 78 0x00 - */ - - -/** - * Sanity checks and default values for EEPROM regulatory levels. - * If EEPROM values fall outside MIN/MAX range, use default values. - * - * Regulatory limits refer to the maximum average txpower allowed by - * regulatory agencies in the geographies in which the device is meant - * to be operated. These limits are SKU-specific (i.e. geography-specific), - * and channel-specific; each channel has an individual regulatory limit - * listed in the EEPROM. - * - * Units are in half-dBm (i.e. "34" means 17 dBm). - */ -#define IWL_TX_POWER_DEFAULT_REGULATORY_24 (34) -#define IWL_TX_POWER_DEFAULT_REGULATORY_52 (34) -#define IWL_TX_POWER_REGULATORY_MIN (0) -#define IWL_TX_POWER_REGULATORY_MAX (34) - -/** - * Sanity checks and default values for EEPROM saturation levels. - * If EEPROM values fall outside MIN/MAX range, use default values. - * - * Saturation is the highest level that the output power amplifier can produce - * without significant clipping distortion. This is a "peak" power level. - * Different types of modulation (i.e. various "rates", and OFDM vs. CCK) - * require differing amounts of backoff, relative to their average power output, - * in order to avoid clipping distortion. - * - * Driver must make sure that it is violating neither the saturation limit, - * nor the regulatory limit, when calculating Tx power settings for various - * rates. - * - * Units are in half-dBm (i.e. "38" means 19 dBm). - */ -#define IWL_TX_POWER_DEFAULT_SATURATION_24 (38) -#define IWL_TX_POWER_DEFAULT_SATURATION_52 (38) -#define IWL_TX_POWER_SATURATION_MIN (20) -#define IWL_TX_POWER_SATURATION_MAX (50) - -/** - * Channel groups used for Tx Attenuation calibration (MIMO tx channel balance) - * and thermal Txpower calibration. - * - * When calculating txpower, driver must compensate for current device - * temperature; higher temperature requires higher gain. Driver must calculate - * current temperature (see "4965 temperature calculation"), then compare vs. - * factory calibration temperature in EEPROM; if current temperature is higher - * than factory temperature, driver must *increase* gain by proportions shown - * in table below. If current temperature is lower than factory, driver must - * *decrease* gain. - * - * Different frequency ranges require different compensation, as shown below. - */ -/* Group 0, 5.2 GHz ch 34-43: 4.5 degrees per 1/2 dB. */ -#define CALIB_IWL_TX_ATTEN_GR1_FCH 34 -#define CALIB_IWL_TX_ATTEN_GR1_LCH 43 - -/* Group 1, 5.3 GHz ch 44-70: 4.0 degrees per 1/2 dB. */ -#define CALIB_IWL_TX_ATTEN_GR2_FCH 44 -#define CALIB_IWL_TX_ATTEN_GR2_LCH 70 - -/* Group 2, 5.5 GHz ch 71-124: 4.0 degrees per 1/2 dB. */ -#define CALIB_IWL_TX_ATTEN_GR3_FCH 71 -#define CALIB_IWL_TX_ATTEN_GR3_LCH 124 - -/* Group 3, 5.7 GHz ch 125-200: 4.0 degrees per 1/2 dB. */ -#define CALIB_IWL_TX_ATTEN_GR4_FCH 125 -#define CALIB_IWL_TX_ATTEN_GR4_LCH 200 - -/* Group 4, 2.4 GHz all channels: 3.5 degrees per 1/2 dB. */ -#define CALIB_IWL_TX_ATTEN_GR5_FCH 1 -#define CALIB_IWL_TX_ATTEN_GR5_LCH 20 - -enum { - CALIB_CH_GROUP_1 = 0, - CALIB_CH_GROUP_2 = 1, - CALIB_CH_GROUP_3 = 2, - CALIB_CH_GROUP_4 = 3, - CALIB_CH_GROUP_5 = 4, - CALIB_CH_GROUP_MAX -}; - -/********************* END TXPOWER *****************************************/ - - -/** - * Tx/Rx Queues - * - * Most communication between driver and 4965 is via queues of data buffers. - * For example, all commands that the driver issues to device's embedded - * controller (uCode) are via the command queue (one of the Tx queues). All - * uCode command responses/replies/notifications, including Rx frames, are - * conveyed from uCode to driver via the Rx queue. - * - * Most support for these queues, including handshake support, resides in - * structures in host DRAM, shared between the driver and the device. When - * allocating this memory, the driver must make sure that data written by - * the host CPU updates DRAM immediately (and does not get "stuck" in CPU's - * cache memory), so DRAM and cache are consistent, and the device can - * immediately see changes made by the driver. - * - * 4965 supports up to 16 DRAM-based Tx queues, and services these queues via - * up to 7 DMA channels (FIFOs). Each Tx queue is supported by a circular array - * in DRAM containing 256 Transmit Frame Descriptors (TFDs). - */ -#define IWL49_NUM_FIFOS 7 -#define IWL49_CMD_FIFO_NUM 4 -#define IWL49_NUM_QUEUES 16 -#define IWL49_NUM_AMPDU_QUEUES 8 - - -/** - * struct iwl4965_schedq_bc_tbl - * - * Byte Count table - * - * Each Tx queue uses a byte-count table containing 320 entries: - * one 16-bit entry for each of 256 TFDs, plus an additional 64 entries that - * duplicate the first 64 entries (to avoid wrap-around within a Tx window; - * max Tx window is 64 TFDs). - * - * When driver sets up a new TFD, it must also enter the total byte count - * of the frame to be transmitted into the corresponding entry in the byte - * count table for the chosen Tx queue. If the TFD index is 0-63, the driver - * must duplicate the byte count entry in corresponding index 256-319. - * - * padding puts each byte count table on a 1024-byte boundary; - * 4965 assumes tables are separated by 1024 bytes. - */ -struct iwl4965_scd_bc_tbl { - __le16 tfd_offset[TFD_QUEUE_BC_SIZE]; - u8 pad[1024 - (TFD_QUEUE_BC_SIZE) * sizeof(__le16)]; -} __packed; - -#endif /* !__iwl_4965_hw_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c deleted file mode 100644 index 8998ed134d1a..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ /dev/null @@ -1,2666 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "iwl-eeprom.h" -#include "iwl-dev.h" -#include "iwl-core.h" -#include "iwl-io.h" -#include "iwl-helpers.h" -#include "iwl-agn-calib.h" -#include "iwl-sta.h" -#include "iwl-agn-led.h" -#include "iwl-agn.h" -#include "iwl-agn-debugfs.h" -#include "iwl-legacy.h" - -static int iwl4965_send_tx_power(struct iwl_priv *priv); -static int iwl4965_hw_get_temperature(struct iwl_priv *priv); - -/* Highest firmware API version supported */ -#define IWL4965_UCODE_API_MAX 2 - -/* Lowest firmware API version supported */ -#define IWL4965_UCODE_API_MIN 2 - -#define IWL4965_FW_PRE "iwlwifi-4965-" -#define _IWL4965_MODULE_FIRMWARE(api) IWL4965_FW_PRE #api ".ucode" -#define IWL4965_MODULE_FIRMWARE(api) _IWL4965_MODULE_FIRMWARE(api) - -/* check contents of special bootstrap uCode SRAM */ -static int iwl4965_verify_bsm(struct iwl_priv *priv) -{ - __le32 *image = priv->ucode_boot.v_addr; - u32 len = priv->ucode_boot.len; - u32 reg; - u32 val; - - IWL_DEBUG_INFO(priv, "Begin verify bsm\n"); - - /* verify BSM SRAM contents */ - val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG); - for (reg = BSM_SRAM_LOWER_BOUND; - reg < BSM_SRAM_LOWER_BOUND + len; - reg += sizeof(u32), image++) { - val = iwl_read_prph(priv, reg); - if (val != le32_to_cpu(*image)) { - IWL_ERR(priv, "BSM uCode verification failed at " - "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", - BSM_SRAM_LOWER_BOUND, - reg - BSM_SRAM_LOWER_BOUND, len, - val, le32_to_cpu(*image)); - return -EIO; - } - } - - IWL_DEBUG_INFO(priv, "BSM bootstrap uCode image OK\n"); - - return 0; -} - -/** - * iwl4965_load_bsm - Load bootstrap instructions - * - * BSM operation: - * - * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program - * in special SRAM that does not power down during RFKILL. When powering back - * up after power-saving sleeps (or during initial uCode load), the BSM loads - * the bootstrap program into the on-board processor, and starts it. - * - * The bootstrap program loads (via DMA) instructions and data for a new - * program from host DRAM locations indicated by the host driver in the - * BSM_DRAM_* registers. Once the new program is loaded, it starts - * automatically. - * - * When initializing the NIC, the host driver points the BSM to the - * "initialize" uCode image. This uCode sets up some internal data, then - * notifies host via "initialize alive" that it is complete. - * - * The host then replaces the BSM_DRAM_* pointer values to point to the - * normal runtime uCode instructions and a backup uCode data cache buffer - * (filled initially with starting data values for the on-board processor), - * then triggers the "initialize" uCode to load and launch the runtime uCode, - * which begins normal operation. - * - * When doing a power-save shutdown, runtime uCode saves data SRAM into - * the backup data cache in DRAM before SRAM is powered down. - * - * When powering back up, the BSM loads the bootstrap program. This reloads - * the runtime uCode instructions and the backup data cache into SRAM, - * and re-launches the runtime uCode from where it left off. - */ -static int iwl4965_load_bsm(struct iwl_priv *priv) -{ - __le32 *image = priv->ucode_boot.v_addr; - u32 len = priv->ucode_boot.len; - dma_addr_t pinst; - dma_addr_t pdata; - u32 inst_len; - u32 data_len; - int i; - u32 done; - u32 reg_offset; - int ret; - - IWL_DEBUG_INFO(priv, "Begin load bsm\n"); - - priv->ucode_type = UCODE_RT; - - /* make sure bootstrap program is no larger than BSM's SRAM size */ - if (len > IWL49_MAX_BSM_SIZE) - return -EINVAL; - - /* Tell bootstrap uCode where to find the "Initialize" uCode - * in host DRAM ... host DRAM physical address bits 35:4 for 4965. - * NOTE: iwl_init_alive_start() will replace these values, - * after the "initialize" uCode has run, to point to - * runtime/protocol instructions and backup data cache. - */ - pinst = priv->ucode_init.p_addr >> 4; - pdata = priv->ucode_init_data.p_addr >> 4; - inst_len = priv->ucode_init.len; - data_len = priv->ucode_init_data.len; - - iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); - iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); - iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); - iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); - - /* Fill BSM memory with bootstrap instructions */ - for (reg_offset = BSM_SRAM_LOWER_BOUND; - reg_offset < BSM_SRAM_LOWER_BOUND + len; - reg_offset += sizeof(u32), image++) - _iwl_write_prph(priv, reg_offset, le32_to_cpu(*image)); - - ret = iwl4965_verify_bsm(priv); - if (ret) - return ret; - - /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ - iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); - iwl_write_prph(priv, BSM_WR_MEM_DST_REG, IWL49_RTC_INST_LOWER_BOUND); - iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); - - /* Load bootstrap code into instruction SRAM now, - * to prepare to load "initialize" uCode */ - iwl_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START); - - /* Wait for load of bootstrap uCode to finish */ - for (i = 0; i < 100; i++) { - done = iwl_read_prph(priv, BSM_WR_CTRL_REG); - if (!(done & BSM_WR_CTRL_REG_BIT_START)) - break; - udelay(10); - } - if (i < 100) - IWL_DEBUG_INFO(priv, "BSM write complete, poll %d iterations\n", i); - else { - IWL_ERR(priv, "BSM write did not complete!\n"); - return -EIO; - } - - /* Enable future boot loads whenever power management unit triggers it - * (e.g. when powering back up after power-save shutdown) */ - iwl_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START_EN); - - - return 0; -} - -/** - * iwl4965_set_ucode_ptrs - Set uCode address location - * - * Tell initialization uCode where to find runtime uCode. - * - * BSM registers initially contain pointers to initialization uCode. - * We need to replace them to load runtime uCode inst and data, - * and to save runtime data when powering down. - */ -static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv) -{ - dma_addr_t pinst; - dma_addr_t pdata; - int ret = 0; - - /* bits 35:4 for 4965 */ - pinst = priv->ucode_code.p_addr >> 4; - pdata = priv->ucode_data_backup.p_addr >> 4; - - /* Tell bootstrap uCode where to find image to load */ - iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); - iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); - iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, - priv->ucode_data.len); - - /* Inst byte count must be last to set up, bit 31 signals uCode - * that all new ptr/size info is in place */ - iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, - priv->ucode_code.len | BSM_DRAM_INST_LOAD); - IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n"); - - return ret; -} - -/** - * iwl4965_init_alive_start - Called after REPLY_ALIVE notification received - * - * Called after REPLY_ALIVE notification received from "initialize" uCode. - * - * The 4965 "initialize" ALIVE reply contains calibration data for: - * Voltage, temperature, and MIMO tx gain correction, now stored in priv - * (3945 does not contain this data). - * - * Tell "initialize" uCode to go ahead and load the runtime uCode. -*/ -static void iwl4965_init_alive_start(struct iwl_priv *priv) -{ - /* Bootstrap uCode has loaded initialize uCode ... verify inst image. - * This is a paranoid check, because we would not have gotten the - * "initialize" alive if code weren't properly loaded. */ - if (iwl_verify_ucode(priv)) { - /* Runtime instruction load was bad; - * take it all the way back down so we can try again */ - IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n"); - goto restart; - } - - /* Calculate temperature */ - priv->temperature = iwl4965_hw_get_temperature(priv); - - /* Send pointers to protocol/runtime uCode image ... init code will - * load and launch runtime uCode, which will send us another "Alive" - * notification. */ - IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); - if (iwl4965_set_ucode_ptrs(priv)) { - /* Runtime instruction load won't happen; - * take it all the way back down so we can try again */ - IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n"); - goto restart; - } - return; - -restart: - queue_work(priv->workqueue, &priv->restart); -} - -static bool is_ht40_channel(__le32 rxon_flags) -{ - int chan_mod = le32_to_cpu(rxon_flags & RXON_FLG_CHANNEL_MODE_MSK) - >> RXON_FLG_CHANNEL_MODE_POS; - return ((chan_mod == CHANNEL_MODE_PURE_40) || - (chan_mod == CHANNEL_MODE_MIXED)); -} - -/* - * EEPROM handlers - */ -static u16 iwl4965_eeprom_calib_version(struct iwl_priv *priv) -{ - return iwl_eeprom_query16(priv, EEPROM_4965_CALIB_VERSION_OFFSET); -} - -/* - * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask - * must be called under priv->lock and mac access - */ -static void iwl4965_txq_set_sched(struct iwl_priv *priv, u32 mask) -{ - iwl_write_prph(priv, IWL49_SCD_TXFACT, mask); -} - -static void iwl4965_nic_config(struct iwl_priv *priv) -{ - unsigned long flags; - u16 radio_cfg; - - spin_lock_irqsave(&priv->lock, flags); - - radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); - - /* write radio config values to register */ - if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) == EEPROM_4965_RF_CFG_TYPE_MAX) - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | - EEPROM_RF_CFG_STEP_MSK(radio_cfg) | - EEPROM_RF_CFG_DASH_MSK(radio_cfg)); - - /* set CSR_HW_CONFIG_REG for uCode use */ - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | - CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); - - priv->calib_info = (struct iwl_eeprom_calib_info *) - iwl_eeprom_query_addr(priv, EEPROM_4965_CALIB_TXPOWER_OFFSET); - - spin_unlock_irqrestore(&priv->lock, flags); -} - -/* Reset differential Rx gains in NIC to prepare for chain noise calibration. - * Called after every association, but this runs only once! - * ... once chain noise is calibrated the first time, it's good forever. */ -static void iwl4965_chain_noise_reset(struct iwl_priv *priv) -{ - struct iwl_chain_noise_data *data = &(priv->chain_noise_data); - - if ((data->state == IWL_CHAIN_NOISE_ALIVE) && - iwl_is_any_associated(priv)) { - struct iwl_calib_diff_gain_cmd cmd; - - /* clear data for chain noise calibration algorithm */ - data->chain_noise_a = 0; - data->chain_noise_b = 0; - data->chain_noise_c = 0; - data->chain_signal_a = 0; - data->chain_signal_b = 0; - data->chain_signal_c = 0; - data->beacon_count = 0; - - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD; - cmd.diff_gain_a = 0; - cmd.diff_gain_b = 0; - cmd.diff_gain_c = 0; - if (iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, - sizeof(cmd), &cmd)) - IWL_ERR(priv, - "Could not send REPLY_PHY_CALIBRATION_CMD\n"); - data->state = IWL_CHAIN_NOISE_ACCUMULATE; - IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n"); - } -} - -static void iwl4965_gain_computation(struct iwl_priv *priv, - u32 *average_noise, - u16 min_average_noise_antenna_i, - u32 min_average_noise, - u8 default_chain) -{ - int i, ret; - struct iwl_chain_noise_data *data = &priv->chain_noise_data; - - data->delta_gain_code[min_average_noise_antenna_i] = 0; - - for (i = default_chain; i < NUM_RX_CHAINS; i++) { - s32 delta_g = 0; - - if (!(data->disconn_array[i]) && - (data->delta_gain_code[i] == - CHAIN_NOISE_DELTA_GAIN_INIT_VAL)) { - delta_g = average_noise[i] - min_average_noise; - data->delta_gain_code[i] = (u8)((delta_g * 10) / 15); - data->delta_gain_code[i] = - min(data->delta_gain_code[i], - (u8) CHAIN_NOISE_MAX_DELTA_GAIN_CODE); - - data->delta_gain_code[i] = - (data->delta_gain_code[i] | (1 << 2)); - } else { - data->delta_gain_code[i] = 0; - } - } - IWL_DEBUG_CALIB(priv, "delta_gain_codes: a %d b %d c %d\n", - data->delta_gain_code[0], - data->delta_gain_code[1], - data->delta_gain_code[2]); - - /* Differential gain gets sent to uCode only once */ - if (!data->radio_write) { - struct iwl_calib_diff_gain_cmd cmd; - data->radio_write = 1; - - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD; - cmd.diff_gain_a = data->delta_gain_code[0]; - cmd.diff_gain_b = data->delta_gain_code[1]; - cmd.diff_gain_c = data->delta_gain_code[2]; - ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, - sizeof(cmd), &cmd); - if (ret) - IWL_DEBUG_CALIB(priv, "fail sending cmd " - "REPLY_PHY_CALIBRATION_CMD\n"); - - /* TODO we might want recalculate - * rx_chain in rxon cmd */ - - /* Mark so we run this algo only once! */ - data->state = IWL_CHAIN_NOISE_CALIBRATED; - } -} - -static void iwl4965_bg_txpower_work(struct work_struct *work) -{ - struct iwl_priv *priv = container_of(work, struct iwl_priv, - txpower_work); - - /* If a scan happened to start before we got here - * then just return; the statistics notification will - * kick off another scheduled work to compensate for - * any temperature delta we missed here. */ - if (test_bit(STATUS_EXIT_PENDING, &priv->status) || - test_bit(STATUS_SCANNING, &priv->status)) - return; - - mutex_lock(&priv->mutex); - - /* Regardless of if we are associated, we must reconfigure the - * TX power since frames can be sent on non-radar channels while - * not associated */ - iwl4965_send_tx_power(priv); - - /* Update last_temperature to keep is_calib_needed from running - * when it isn't needed... */ - priv->last_temperature = priv->temperature; - - mutex_unlock(&priv->mutex); -} - -/* - * Acquire priv->lock before calling this function ! - */ -static void iwl4965_set_wr_ptrs(struct iwl_priv *priv, int txq_id, u32 index) -{ - iwl_write_direct32(priv, HBUS_TARG_WRPTR, - (index & 0xff) | (txq_id << 8)); - iwl_write_prph(priv, IWL49_SCD_QUEUE_RDPTR(txq_id), index); -} - -/** - * iwl4965_tx_queue_set_status - (optionally) start Tx/Cmd queue - * @tx_fifo_id: Tx DMA/FIFO channel (range 0-7) that the queue will feed - * @scd_retry: (1) Indicates queue will be used in aggregation mode - * - * NOTE: Acquire priv->lock before calling this function ! - */ -static void iwl4965_tx_queue_set_status(struct iwl_priv *priv, - struct iwl_tx_queue *txq, - int tx_fifo_id, int scd_retry) -{ - int txq_id = txq->q.id; - - /* Find out whether to activate Tx queue */ - int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0; - - /* Set up and activate */ - iwl_write_prph(priv, IWL49_SCD_QUEUE_STATUS_BITS(txq_id), - (active << IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE) | - (tx_fifo_id << IWL49_SCD_QUEUE_STTS_REG_POS_TXF) | - (scd_retry << IWL49_SCD_QUEUE_STTS_REG_POS_WSL) | - (scd_retry << IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACK) | - IWL49_SCD_QUEUE_STTS_REG_MSK); - - txq->sched_retry = scd_retry; - - IWL_DEBUG_INFO(priv, "%s %s Queue %d on AC %d\n", - active ? "Activate" : "Deactivate", - scd_retry ? "BA" : "AC", txq_id, tx_fifo_id); -} - -static const s8 default_queue_to_tx_fifo[] = { - IWL_TX_FIFO_VO, - IWL_TX_FIFO_VI, - IWL_TX_FIFO_BE, - IWL_TX_FIFO_BK, - IWL49_CMD_FIFO_NUM, - IWL_TX_FIFO_UNUSED, - IWL_TX_FIFO_UNUSED, -}; - -static int iwl4965_alive_notify(struct iwl_priv *priv) -{ - u32 a; - unsigned long flags; - int i, chan; - u32 reg_val; - - spin_lock_irqsave(&priv->lock, flags); - - /* Clear 4965's internal Tx Scheduler data base */ - priv->scd_base_addr = iwl_read_prph(priv, IWL49_SCD_SRAM_BASE_ADDR); - a = priv->scd_base_addr + IWL49_SCD_CONTEXT_DATA_OFFSET; - for (; a < priv->scd_base_addr + IWL49_SCD_TX_STTS_BITMAP_OFFSET; a += 4) - iwl_write_targ_mem(priv, a, 0); - for (; a < priv->scd_base_addr + IWL49_SCD_TRANSLATE_TBL_OFFSET; a += 4) - iwl_write_targ_mem(priv, a, 0); - for (; a < priv->scd_base_addr + - IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4) - iwl_write_targ_mem(priv, a, 0); - - /* Tel 4965 where to find Tx byte count tables */ - iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR, - priv->scd_bc_tbls.dma >> 10); - - /* Enable DMA channel */ - for (chan = 0; chan < FH49_TCSR_CHNL_NUM ; chan++) - iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(chan), - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); - - /* Update FH chicken bits */ - reg_val = iwl_read_direct32(priv, FH_TX_CHICKEN_BITS_REG); - iwl_write_direct32(priv, FH_TX_CHICKEN_BITS_REG, - reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); - - /* Disable chain mode for all queues */ - iwl_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0); - - /* Initialize each Tx queue (including the command queue) */ - for (i = 0; i < priv->hw_params.max_txq_num; i++) { - - /* TFD circular buffer read/write indexes */ - iwl_write_prph(priv, IWL49_SCD_QUEUE_RDPTR(i), 0); - iwl_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8)); - - /* Max Tx Window size for Scheduler-ACK mode */ - iwl_write_targ_mem(priv, priv->scd_base_addr + - IWL49_SCD_CONTEXT_QUEUE_OFFSET(i), - (SCD_WIN_SIZE << - IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) & - IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK); - - /* Frame limit */ - iwl_write_targ_mem(priv, priv->scd_base_addr + - IWL49_SCD_CONTEXT_QUEUE_OFFSET(i) + - sizeof(u32), - (SCD_FRAME_LIMIT << - IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & - IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK); - - } - iwl_write_prph(priv, IWL49_SCD_INTERRUPT_MASK, - (1 << priv->hw_params.max_txq_num) - 1); - - /* Activate all Tx DMA/FIFO channels */ - priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 6)); - - iwl4965_set_wr_ptrs(priv, IWL_DEFAULT_CMD_QUEUE_NUM, 0); - - /* make sure all queue are not stopped */ - memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); - for (i = 0; i < 4; i++) - atomic_set(&priv->queue_stop_count[i], 0); - - /* reset to 0 to enable all the queue first */ - priv->txq_ctx_active_msk = 0; - /* Map each Tx/cmd queue to its corresponding fifo */ - BUILD_BUG_ON(ARRAY_SIZE(default_queue_to_tx_fifo) != 7); - - for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) { - int ac = default_queue_to_tx_fifo[i]; - - iwl_txq_ctx_activate(priv, i); - - if (ac == IWL_TX_FIFO_UNUSED) - continue; - - iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0); - } - - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; -} - -static struct iwl_sensitivity_ranges iwl4965_sensitivity = { - .min_nrg_cck = 97, - .max_nrg_cck = 0, /* not used, set to 0 */ - - .auto_corr_min_ofdm = 85, - .auto_corr_min_ofdm_mrc = 170, - .auto_corr_min_ofdm_x1 = 105, - .auto_corr_min_ofdm_mrc_x1 = 220, - - .auto_corr_max_ofdm = 120, - .auto_corr_max_ofdm_mrc = 210, - .auto_corr_max_ofdm_x1 = 140, - .auto_corr_max_ofdm_mrc_x1 = 270, - - .auto_corr_min_cck = 125, - .auto_corr_max_cck = 200, - .auto_corr_min_cck_mrc = 200, - .auto_corr_max_cck_mrc = 400, - - .nrg_th_cck = 100, - .nrg_th_ofdm = 100, - - .barker_corr_th_min = 190, - .barker_corr_th_min_mrc = 390, - .nrg_th_cca = 62, -}; - -static void iwl4965_set_ct_threshold(struct iwl_priv *priv) -{ - /* want Kelvin */ - priv->hw_params.ct_kill_threshold = - CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY); -} - -/** - * iwl4965_hw_set_hw_params - * - * Called when initializing driver - */ -static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) -{ - if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && - priv->cfg->mod_params->num_of_queues <= IWL49_NUM_QUEUES) - priv->cfg->base_params->num_of_queues = - priv->cfg->mod_params->num_of_queues; - - priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; - priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM; - priv->hw_params.scd_bc_tbls_size = - priv->cfg->base_params->num_of_queues * - sizeof(struct iwl4965_scd_bc_tbl); - priv->hw_params.tfd_size = sizeof(struct iwl_tfd); - priv->hw_params.max_stations = IWL4965_STATION_COUNT; - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL4965_BROADCAST_ID; - priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE; - priv->hw_params.max_inst_size = IWL49_RTC_INST_SIZE; - priv->hw_params.max_bsm_size = BSM_SRAM_SIZE; - priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_5GHZ); - - priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; - - priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); - priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); - priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; - priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; - - iwl4965_set_ct_threshold(priv); - - priv->hw_params.sens = &iwl4965_sensitivity; - priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; - - return 0; -} - -static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res) -{ - s32 sign = 1; - - if (num < 0) { - sign = -sign; - num = -num; - } - if (denom < 0) { - sign = -sign; - denom = -denom; - } - *res = 1; - *res = ((num * 2 + denom) / (denom * 2)) * sign; - - return 1; -} - -/** - * iwl4965_get_voltage_compensation - Power supply voltage comp for txpower - * - * Determines power supply voltage compensation for txpower calculations. - * Returns number of 1/2-dB steps to subtract from gain table index, - * to compensate for difference between power supply voltage during - * factory measurements, vs. current power supply voltage. - * - * Voltage indication is higher for lower voltage. - * Lower voltage requires more gain (lower gain table index). - */ -static s32 iwl4965_get_voltage_compensation(s32 eeprom_voltage, - s32 current_voltage) -{ - s32 comp = 0; - - if ((TX_POWER_IWL_ILLEGAL_VOLTAGE == eeprom_voltage) || - (TX_POWER_IWL_ILLEGAL_VOLTAGE == current_voltage)) - return 0; - - iwl4965_math_div_round(current_voltage - eeprom_voltage, - TX_POWER_IWL_VOLTAGE_CODES_PER_03V, &comp); - - if (current_voltage > eeprom_voltage) - comp *= 2; - if ((comp < -2) || (comp > 2)) - comp = 0; - - return comp; -} - -static s32 iwl4965_get_tx_atten_grp(u16 channel) -{ - if (channel >= CALIB_IWL_TX_ATTEN_GR5_FCH && - channel <= CALIB_IWL_TX_ATTEN_GR5_LCH) - return CALIB_CH_GROUP_5; - - if (channel >= CALIB_IWL_TX_ATTEN_GR1_FCH && - channel <= CALIB_IWL_TX_ATTEN_GR1_LCH) - return CALIB_CH_GROUP_1; - - if (channel >= CALIB_IWL_TX_ATTEN_GR2_FCH && - channel <= CALIB_IWL_TX_ATTEN_GR2_LCH) - return CALIB_CH_GROUP_2; - - if (channel >= CALIB_IWL_TX_ATTEN_GR3_FCH && - channel <= CALIB_IWL_TX_ATTEN_GR3_LCH) - return CALIB_CH_GROUP_3; - - if (channel >= CALIB_IWL_TX_ATTEN_GR4_FCH && - channel <= CALIB_IWL_TX_ATTEN_GR4_LCH) - return CALIB_CH_GROUP_4; - - return -1; -} - -static u32 iwl4965_get_sub_band(const struct iwl_priv *priv, u32 channel) -{ - s32 b = -1; - - for (b = 0; b < EEPROM_TX_POWER_BANDS; b++) { - if (priv->calib_info->band_info[b].ch_from == 0) - continue; - - if ((channel >= priv->calib_info->band_info[b].ch_from) - && (channel <= priv->calib_info->band_info[b].ch_to)) - break; - } - - return b; -} - -static s32 iwl4965_interpolate_value(s32 x, s32 x1, s32 y1, s32 x2, s32 y2) -{ - s32 val; - - if (x2 == x1) - return y1; - else { - iwl4965_math_div_round((x2 - x) * (y1 - y2), (x2 - x1), &val); - return val + y2; - } -} - -/** - * iwl4965_interpolate_chan - Interpolate factory measurements for one channel - * - * Interpolates factory measurements from the two sample channels within a - * sub-band, to apply to channel of interest. Interpolation is proportional to - * differences in channel frequencies, which is proportional to differences - * in channel number. - */ -static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel, - struct iwl_eeprom_calib_ch_info *chan_info) -{ - s32 s = -1; - u32 c; - u32 m; - const struct iwl_eeprom_calib_measure *m1; - const struct iwl_eeprom_calib_measure *m2; - struct iwl_eeprom_calib_measure *omeas; - u32 ch_i1; - u32 ch_i2; - - s = iwl4965_get_sub_band(priv, channel); - if (s >= EEPROM_TX_POWER_BANDS) { - IWL_ERR(priv, "Tx Power can not find channel %d\n", channel); - return -1; - } - - ch_i1 = priv->calib_info->band_info[s].ch1.ch_num; - ch_i2 = priv->calib_info->band_info[s].ch2.ch_num; - chan_info->ch_num = (u8) channel; - - IWL_DEBUG_TXPOWER(priv, "channel %d subband %d factory cal ch %d & %d\n", - channel, s, ch_i1, ch_i2); - - for (c = 0; c < EEPROM_TX_POWER_TX_CHAINS; c++) { - for (m = 0; m < EEPROM_TX_POWER_MEASUREMENTS; m++) { - m1 = &(priv->calib_info->band_info[s].ch1. - measurements[c][m]); - m2 = &(priv->calib_info->band_info[s].ch2. - measurements[c][m]); - omeas = &(chan_info->measurements[c][m]); - - omeas->actual_pow = - (u8) iwl4965_interpolate_value(channel, ch_i1, - m1->actual_pow, - ch_i2, - m2->actual_pow); - omeas->gain_idx = - (u8) iwl4965_interpolate_value(channel, ch_i1, - m1->gain_idx, ch_i2, - m2->gain_idx); - omeas->temperature = - (u8) iwl4965_interpolate_value(channel, ch_i1, - m1->temperature, - ch_i2, - m2->temperature); - omeas->pa_det = - (s8) iwl4965_interpolate_value(channel, ch_i1, - m1->pa_det, ch_i2, - m2->pa_det); - - IWL_DEBUG_TXPOWER(priv, - "chain %d meas %d AP1=%d AP2=%d AP=%d\n", c, m, - m1->actual_pow, m2->actual_pow, omeas->actual_pow); - IWL_DEBUG_TXPOWER(priv, - "chain %d meas %d NI1=%d NI2=%d NI=%d\n", c, m, - m1->gain_idx, m2->gain_idx, omeas->gain_idx); - IWL_DEBUG_TXPOWER(priv, - "chain %d meas %d PA1=%d PA2=%d PA=%d\n", c, m, - m1->pa_det, m2->pa_det, omeas->pa_det); - IWL_DEBUG_TXPOWER(priv, - "chain %d meas %d T1=%d T2=%d T=%d\n", c, m, - m1->temperature, m2->temperature, - omeas->temperature); - } - } - - return 0; -} - -/* bit-rate-dependent table to prevent Tx distortion, in half-dB units, - * for OFDM 6, 12, 18, 24, 36, 48, 54, 60 MBit, and CCK all rates. */ -static s32 back_off_table[] = { - 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM SISO 20 MHz */ - 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM MIMO 20 MHz */ - 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM SISO 40 MHz */ - 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM MIMO 40 MHz */ - 10 /* CCK */ -}; - -/* Thermal compensation values for txpower for various frequency ranges ... - * ratios from 3:1 to 4.5:1 of degrees (Celsius) per half-dB gain adjust */ -static struct iwl4965_txpower_comp_entry { - s32 degrees_per_05db_a; - s32 degrees_per_05db_a_denom; -} tx_power_cmp_tble[CALIB_CH_GROUP_MAX] = { - {9, 2}, /* group 0 5.2, ch 34-43 */ - {4, 1}, /* group 1 5.2, ch 44-70 */ - {4, 1}, /* group 2 5.2, ch 71-124 */ - {4, 1}, /* group 3 5.2, ch 125-200 */ - {3, 1} /* group 4 2.4, ch all */ -}; - -static s32 get_min_power_index(s32 rate_power_index, u32 band) -{ - if (!band) { - if ((rate_power_index & 7) <= 4) - return MIN_TX_GAIN_INDEX_52GHZ_EXT; - } - return MIN_TX_GAIN_INDEX; -} - -struct gain_entry { - u8 dsp; - u8 radio; -}; - -static const struct gain_entry gain_table[2][108] = { - /* 5.2GHz power gain index table */ - { - {123, 0x3F}, /* highest txpower */ - {117, 0x3F}, - {110, 0x3F}, - {104, 0x3F}, - {98, 0x3F}, - {110, 0x3E}, - {104, 0x3E}, - {98, 0x3E}, - {110, 0x3D}, - {104, 0x3D}, - {98, 0x3D}, - {110, 0x3C}, - {104, 0x3C}, - {98, 0x3C}, - {110, 0x3B}, - {104, 0x3B}, - {98, 0x3B}, - {110, 0x3A}, - {104, 0x3A}, - {98, 0x3A}, - {110, 0x39}, - {104, 0x39}, - {98, 0x39}, - {110, 0x38}, - {104, 0x38}, - {98, 0x38}, - {110, 0x37}, - {104, 0x37}, - {98, 0x37}, - {110, 0x36}, - {104, 0x36}, - {98, 0x36}, - {110, 0x35}, - {104, 0x35}, - {98, 0x35}, - {110, 0x34}, - {104, 0x34}, - {98, 0x34}, - {110, 0x33}, - {104, 0x33}, - {98, 0x33}, - {110, 0x32}, - {104, 0x32}, - {98, 0x32}, - {110, 0x31}, - {104, 0x31}, - {98, 0x31}, - {110, 0x30}, - {104, 0x30}, - {98, 0x30}, - {110, 0x25}, - {104, 0x25}, - {98, 0x25}, - {110, 0x24}, - {104, 0x24}, - {98, 0x24}, - {110, 0x23}, - {104, 0x23}, - {98, 0x23}, - {110, 0x22}, - {104, 0x18}, - {98, 0x18}, - {110, 0x17}, - {104, 0x17}, - {98, 0x17}, - {110, 0x16}, - {104, 0x16}, - {98, 0x16}, - {110, 0x15}, - {104, 0x15}, - {98, 0x15}, - {110, 0x14}, - {104, 0x14}, - {98, 0x14}, - {110, 0x13}, - {104, 0x13}, - {98, 0x13}, - {110, 0x12}, - {104, 0x08}, - {98, 0x08}, - {110, 0x07}, - {104, 0x07}, - {98, 0x07}, - {110, 0x06}, - {104, 0x06}, - {98, 0x06}, - {110, 0x05}, - {104, 0x05}, - {98, 0x05}, - {110, 0x04}, - {104, 0x04}, - {98, 0x04}, - {110, 0x03}, - {104, 0x03}, - {98, 0x03}, - {110, 0x02}, - {104, 0x02}, - {98, 0x02}, - {110, 0x01}, - {104, 0x01}, - {98, 0x01}, - {110, 0x00}, - {104, 0x00}, - {98, 0x00}, - {93, 0x00}, - {88, 0x00}, - {83, 0x00}, - {78, 0x00}, - }, - /* 2.4GHz power gain index table */ - { - {110, 0x3f}, /* highest txpower */ - {104, 0x3f}, - {98, 0x3f}, - {110, 0x3e}, - {104, 0x3e}, - {98, 0x3e}, - {110, 0x3d}, - {104, 0x3d}, - {98, 0x3d}, - {110, 0x3c}, - {104, 0x3c}, - {98, 0x3c}, - {110, 0x3b}, - {104, 0x3b}, - {98, 0x3b}, - {110, 0x3a}, - {104, 0x3a}, - {98, 0x3a}, - {110, 0x39}, - {104, 0x39}, - {98, 0x39}, - {110, 0x38}, - {104, 0x38}, - {98, 0x38}, - {110, 0x37}, - {104, 0x37}, - {98, 0x37}, - {110, 0x36}, - {104, 0x36}, - {98, 0x36}, - {110, 0x35}, - {104, 0x35}, - {98, 0x35}, - {110, 0x34}, - {104, 0x34}, - {98, 0x34}, - {110, 0x33}, - {104, 0x33}, - {98, 0x33}, - {110, 0x32}, - {104, 0x32}, - {98, 0x32}, - {110, 0x31}, - {104, 0x31}, - {98, 0x31}, - {110, 0x30}, - {104, 0x30}, - {98, 0x30}, - {110, 0x6}, - {104, 0x6}, - {98, 0x6}, - {110, 0x5}, - {104, 0x5}, - {98, 0x5}, - {110, 0x4}, - {104, 0x4}, - {98, 0x4}, - {110, 0x3}, - {104, 0x3}, - {98, 0x3}, - {110, 0x2}, - {104, 0x2}, - {98, 0x2}, - {110, 0x1}, - {104, 0x1}, - {98, 0x1}, - {110, 0x0}, - {104, 0x0}, - {98, 0x0}, - {97, 0}, - {96, 0}, - {95, 0}, - {94, 0}, - {93, 0}, - {92, 0}, - {91, 0}, - {90, 0}, - {89, 0}, - {88, 0}, - {87, 0}, - {86, 0}, - {85, 0}, - {84, 0}, - {83, 0}, - {82, 0}, - {81, 0}, - {80, 0}, - {79, 0}, - {78, 0}, - {77, 0}, - {76, 0}, - {75, 0}, - {74, 0}, - {73, 0}, - {72, 0}, - {71, 0}, - {70, 0}, - {69, 0}, - {68, 0}, - {67, 0}, - {66, 0}, - {65, 0}, - {64, 0}, - {63, 0}, - {62, 0}, - {61, 0}, - {60, 0}, - {59, 0}, - } -}; - -static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, - u8 is_ht40, u8 ctrl_chan_high, - struct iwl4965_tx_power_db *tx_power_tbl) -{ - u8 saturation_power; - s32 target_power; - s32 user_target_power; - s32 power_limit; - s32 current_temp; - s32 reg_limit; - s32 current_regulatory; - s32 txatten_grp = CALIB_CH_GROUP_MAX; - int i; - int c; - const struct iwl_channel_info *ch_info = NULL; - struct iwl_eeprom_calib_ch_info ch_eeprom_info; - const struct iwl_eeprom_calib_measure *measurement; - s16 voltage; - s32 init_voltage; - s32 voltage_compensation; - s32 degrees_per_05db_num; - s32 degrees_per_05db_denom; - s32 factory_temp; - s32 temperature_comp[2]; - s32 factory_gain_index[2]; - s32 factory_actual_pwr[2]; - s32 power_index; - - /* tx_power_user_lmt is in dBm, convert to half-dBm (half-dB units - * are used for indexing into txpower table) */ - user_target_power = 2 * priv->tx_power_user_lmt; - - /* Get current (RXON) channel, band, width */ - IWL_DEBUG_TXPOWER(priv, "chan %d band %d is_ht40 %d\n", channel, band, - is_ht40); - - ch_info = iwl_get_channel_info(priv, priv->band, channel); - - if (!is_channel_valid(ch_info)) - return -EINVAL; - - /* get txatten group, used to select 1) thermal txpower adjustment - * and 2) mimo txpower balance between Tx chains. */ - txatten_grp = iwl4965_get_tx_atten_grp(channel); - if (txatten_grp < 0) { - IWL_ERR(priv, "Can't find txatten group for channel %d.\n", - channel); - return -EINVAL; - } - - IWL_DEBUG_TXPOWER(priv, "channel %d belongs to txatten group %d\n", - channel, txatten_grp); - - if (is_ht40) { - if (ctrl_chan_high) - channel -= 2; - else - channel += 2; - } - - /* hardware txpower limits ... - * saturation (clipping distortion) txpowers are in half-dBm */ - if (band) - saturation_power = priv->calib_info->saturation_power24; - else - saturation_power = priv->calib_info->saturation_power52; - - if (saturation_power < IWL_TX_POWER_SATURATION_MIN || - saturation_power > IWL_TX_POWER_SATURATION_MAX) { - if (band) - saturation_power = IWL_TX_POWER_DEFAULT_SATURATION_24; - else - saturation_power = IWL_TX_POWER_DEFAULT_SATURATION_52; - } - - /* regulatory txpower limits ... reg_limit values are in half-dBm, - * max_power_avg values are in dBm, convert * 2 */ - if (is_ht40) - reg_limit = ch_info->ht40_max_power_avg * 2; - else - reg_limit = ch_info->max_power_avg * 2; - - if ((reg_limit < IWL_TX_POWER_REGULATORY_MIN) || - (reg_limit > IWL_TX_POWER_REGULATORY_MAX)) { - if (band) - reg_limit = IWL_TX_POWER_DEFAULT_REGULATORY_24; - else - reg_limit = IWL_TX_POWER_DEFAULT_REGULATORY_52; - } - - /* Interpolate txpower calibration values for this channel, - * based on factory calibration tests on spaced channels. */ - iwl4965_interpolate_chan(priv, channel, &ch_eeprom_info); - - /* calculate tx gain adjustment based on power supply voltage */ - voltage = le16_to_cpu(priv->calib_info->voltage); - init_voltage = (s32)le32_to_cpu(priv->card_alive_init.voltage); - voltage_compensation = - iwl4965_get_voltage_compensation(voltage, init_voltage); - - IWL_DEBUG_TXPOWER(priv, "curr volt %d eeprom volt %d volt comp %d\n", - init_voltage, - voltage, voltage_compensation); - - /* get current temperature (Celsius) */ - current_temp = max(priv->temperature, IWL_TX_POWER_TEMPERATURE_MIN); - current_temp = min(priv->temperature, IWL_TX_POWER_TEMPERATURE_MAX); - current_temp = KELVIN_TO_CELSIUS(current_temp); - - /* select thermal txpower adjustment params, based on channel group - * (same frequency group used for mimo txatten adjustment) */ - degrees_per_05db_num = - tx_power_cmp_tble[txatten_grp].degrees_per_05db_a; - degrees_per_05db_denom = - tx_power_cmp_tble[txatten_grp].degrees_per_05db_a_denom; - - /* get per-chain txpower values from factory measurements */ - for (c = 0; c < 2; c++) { - measurement = &ch_eeprom_info.measurements[c][1]; - - /* txgain adjustment (in half-dB steps) based on difference - * between factory and current temperature */ - factory_temp = measurement->temperature; - iwl4965_math_div_round((current_temp - factory_temp) * - degrees_per_05db_denom, - degrees_per_05db_num, - &temperature_comp[c]); - - factory_gain_index[c] = measurement->gain_idx; - factory_actual_pwr[c] = measurement->actual_pow; - - IWL_DEBUG_TXPOWER(priv, "chain = %d\n", c); - IWL_DEBUG_TXPOWER(priv, "fctry tmp %d, " - "curr tmp %d, comp %d steps\n", - factory_temp, current_temp, - temperature_comp[c]); - - IWL_DEBUG_TXPOWER(priv, "fctry idx %d, fctry pwr %d\n", - factory_gain_index[c], - factory_actual_pwr[c]); - } - - /* for each of 33 bit-rates (including 1 for CCK) */ - for (i = 0; i < POWER_TABLE_NUM_ENTRIES; i++) { - u8 is_mimo_rate; - union iwl4965_tx_power_dual_stream tx_power; - - /* for mimo, reduce each chain's txpower by half - * (3dB, 6 steps), so total output power is regulatory - * compliant. */ - if (i & 0x8) { - current_regulatory = reg_limit - - IWL_TX_POWER_MIMO_REGULATORY_COMPENSATION; - is_mimo_rate = 1; - } else { - current_regulatory = reg_limit; - is_mimo_rate = 0; - } - - /* find txpower limit, either hardware or regulatory */ - power_limit = saturation_power - back_off_table[i]; - if (power_limit > current_regulatory) - power_limit = current_regulatory; - - /* reduce user's txpower request if necessary - * for this rate on this channel */ - target_power = user_target_power; - if (target_power > power_limit) - target_power = power_limit; - - IWL_DEBUG_TXPOWER(priv, "rate %d sat %d reg %d usr %d tgt %d\n", - i, saturation_power - back_off_table[i], - current_regulatory, user_target_power, - target_power); - - /* for each of 2 Tx chains (radio transmitters) */ - for (c = 0; c < 2; c++) { - s32 atten_value; - - if (is_mimo_rate) - atten_value = - (s32)le32_to_cpu(priv->card_alive_init. - tx_atten[txatten_grp][c]); - else - atten_value = 0; - - /* calculate index; higher index means lower txpower */ - power_index = (u8) (factory_gain_index[c] - - (target_power - - factory_actual_pwr[c]) - - temperature_comp[c] - - voltage_compensation + - atten_value); - -/* IWL_DEBUG_TXPOWER(priv, "calculated txpower index %d\n", - power_index); */ - - if (power_index < get_min_power_index(i, band)) - power_index = get_min_power_index(i, band); - - /* adjust 5 GHz index to support negative indexes */ - if (!band) - power_index += 9; - - /* CCK, rate 32, reduce txpower for CCK */ - if (i == POWER_TABLE_CCK_ENTRY) - power_index += - IWL_TX_POWER_CCK_COMPENSATION_C_STEP; - - /* stay within the table! */ - if (power_index > 107) { - IWL_WARN(priv, "txpower index %d > 107\n", - power_index); - power_index = 107; - } - if (power_index < 0) { - IWL_WARN(priv, "txpower index %d < 0\n", - power_index); - power_index = 0; - } - - /* fill txpower command for this rate/chain */ - tx_power.s.radio_tx_gain[c] = - gain_table[band][power_index].radio; - tx_power.s.dsp_predis_atten[c] = - gain_table[band][power_index].dsp; - - IWL_DEBUG_TXPOWER(priv, "chain %d mimo %d index %d " - "gain 0x%02x dsp %d\n", - c, atten_value, power_index, - tx_power.s.radio_tx_gain[c], - tx_power.s.dsp_predis_atten[c]); - } /* for each chain */ - - tx_power_tbl->power_tbl[i].dw = cpu_to_le32(tx_power.dw); - - } /* for each rate */ - - return 0; -} - -/** - * iwl4965_send_tx_power - Configure the TXPOWER level user limit - * - * Uses the active RXON for channel, band, and characteristics (ht40, high) - * The power limit is taken from priv->tx_power_user_lmt. - */ -static int iwl4965_send_tx_power(struct iwl_priv *priv) -{ - struct iwl4965_txpowertable_cmd cmd = { 0 }; - int ret; - u8 band = 0; - bool is_ht40 = false; - u8 ctrl_chan_high = 0; - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status), - "TX Power requested while scanning!\n")) - return -EAGAIN; - - band = priv->band == IEEE80211_BAND_2GHZ; - - is_ht40 = is_ht40_channel(ctx->active.flags); - - if (is_ht40 && (ctx->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) - ctrl_chan_high = 1; - - cmd.band = band; - cmd.channel = ctx->active.channel; - - ret = iwl4965_fill_txpower_tbl(priv, band, - le16_to_cpu(ctx->active.channel), - is_ht40, ctrl_chan_high, &cmd.tx_power); - if (ret) - goto out; - - ret = iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, sizeof(cmd), &cmd); - -out: - return ret; -} - -static int iwl4965_send_rxon_assoc(struct iwl_priv *priv, - struct iwl_rxon_context *ctx) -{ - int ret = 0; - struct iwl4965_rxon_assoc_cmd rxon_assoc; - const struct iwl_rxon_cmd *rxon1 = &ctx->staging; - const struct iwl_rxon_cmd *rxon2 = &ctx->active; - - if ((rxon1->flags == rxon2->flags) && - (rxon1->filter_flags == rxon2->filter_flags) && - (rxon1->cck_basic_rates == rxon2->cck_basic_rates) && - (rxon1->ofdm_ht_single_stream_basic_rates == - rxon2->ofdm_ht_single_stream_basic_rates) && - (rxon1->ofdm_ht_dual_stream_basic_rates == - rxon2->ofdm_ht_dual_stream_basic_rates) && - (rxon1->rx_chain == rxon2->rx_chain) && - (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) { - IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n"); - return 0; - } - - rxon_assoc.flags = ctx->staging.flags; - rxon_assoc.filter_flags = ctx->staging.filter_flags; - rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; - rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; - rxon_assoc.reserved = 0; - rxon_assoc.ofdm_ht_single_stream_basic_rates = - ctx->staging.ofdm_ht_single_stream_basic_rates; - rxon_assoc.ofdm_ht_dual_stream_basic_rates = - ctx->staging.ofdm_ht_dual_stream_basic_rates; - rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain; - - ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC, - sizeof(rxon_assoc), &rxon_assoc, NULL); - if (ret) - return ret; - - return ret; -} - -static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) -{ - /* cast away the const for active_rxon in this function */ - struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active; - int ret; - bool new_assoc = - !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); - - if (!iwl_is_alive(priv)) - return -EBUSY; - - if (!ctx->is_active) - return 0; - - /* always get timestamp with Rx frame */ - ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; - - ret = iwl_check_rxon_cmd(priv, ctx); - if (ret) { - IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); - return -EINVAL; - } - - /* - * receive commit_rxon request - * abort any previous channel switch if still in process - */ - if (priv->switch_rxon.switch_in_progress && - (priv->switch_rxon.channel != ctx->staging.channel)) { - IWL_DEBUG_11H(priv, "abort channel switch on %d\n", - le16_to_cpu(priv->switch_rxon.channel)); - iwl_chswitch_done(priv, false); - } - - /* If we don't need to send a full RXON, we can use - * iwl_rxon_assoc_cmd which is used to reconfigure filter - * and other flags for the current radio configuration. */ - if (!iwl_full_rxon_required(priv, ctx)) { - ret = iwl_send_rxon_assoc(priv, ctx); - if (ret) { - IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret); - return ret; - } - - memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); - iwl_print_rx_config_cmd(priv, ctx); - return 0; - } - - /* If we are currently associated and the new config requires - * an RXON_ASSOC and the new config wants the associated mask enabled, - * we must clear the associated from the active configuration - * before we apply the new config */ - if (iwl_is_associated_ctx(ctx) && new_assoc) { - IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); - active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - - ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, - sizeof(struct iwl_rxon_cmd), - active_rxon); - - /* If the mask clearing failed then we set - * active_rxon back to what it was previously */ - if (ret) { - active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; - IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret); - return ret; - } - iwl_clear_ucode_stations(priv, ctx); - iwl_restore_stations(priv, ctx); - ret = iwl_restore_default_wep_keys(priv, ctx); - if (ret) { - IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); - return ret; - } - } - - IWL_DEBUG_INFO(priv, "Sending RXON\n" - "* with%s RXON_FILTER_ASSOC_MSK\n" - "* channel = %d\n" - "* bssid = %pM\n", - (new_assoc ? "" : "out"), - le16_to_cpu(ctx->staging.channel), - ctx->staging.bssid_addr); - - iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto); - - /* Apply the new configuration - * RXON unassoc clears the station table in uCode so restoration of - * stations is needed after it (the RXON command) completes - */ - if (!new_assoc) { - ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, - sizeof(struct iwl_rxon_cmd), &ctx->staging); - if (ret) { - IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); - return ret; - } - IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n"); - memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); - iwl_clear_ucode_stations(priv, ctx); - iwl_restore_stations(priv, ctx); - ret = iwl_restore_default_wep_keys(priv, ctx); - if (ret) { - IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); - return ret; - } - } - if (new_assoc) { - priv->start_calib = 0; - /* Apply the new configuration - * RXON assoc doesn't clear the station table in uCode, - */ - ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, - sizeof(struct iwl_rxon_cmd), &ctx->staging); - if (ret) { - IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); - return ret; - } - memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); - } - iwl_print_rx_config_cmd(priv, ctx); - - iwl_init_sensitivity(priv); - - /* If we issue a new RXON command which required a tune then we must - * send a new TXPOWER command or we won't be able to Tx any frames */ - ret = iwl_set_tx_power(priv, priv->tx_power_next, true); - if (ret) { - IWL_ERR(priv, "Error sending TX power (%d)\n", ret); - return ret; - } - - return 0; -} - -static int iwl4965_hw_channel_switch(struct iwl_priv *priv, - struct ieee80211_channel_switch *ch_switch) -{ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - int rc; - u8 band = 0; - bool is_ht40 = false; - u8 ctrl_chan_high = 0; - struct iwl4965_channel_switch_cmd cmd; - const struct iwl_channel_info *ch_info; - u32 switch_time_in_usec, ucode_switch_time; - u16 ch; - u32 tsf_low; - u8 switch_count; - u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); - struct ieee80211_vif *vif = ctx->vif; - band = priv->band == IEEE80211_BAND_2GHZ; - - is_ht40 = is_ht40_channel(ctx->staging.flags); - - if (is_ht40 && - (ctx->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) - ctrl_chan_high = 1; - - cmd.band = band; - cmd.expect_beacon = 0; - ch = ch_switch->channel->hw_value; - cmd.channel = cpu_to_le16(ch); - cmd.rxon_flags = ctx->staging.flags; - cmd.rxon_filter_flags = ctx->staging.filter_flags; - switch_count = ch_switch->count; - tsf_low = ch_switch->timestamp & 0x0ffffffff; - /* - * calculate the ucode channel switch time - * adding TSF as one of the factor for when to switch - */ - if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) { - if (switch_count > ((priv->ucode_beacon_time - tsf_low) / - beacon_interval)) { - switch_count -= (priv->ucode_beacon_time - - tsf_low) / beacon_interval; - } else - switch_count = 0; - } - if (switch_count <= 1) - cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); - else { - switch_time_in_usec = - vif->bss_conf.beacon_int * switch_count * TIME_UNIT; - ucode_switch_time = iwl_usecs_to_beacons(priv, - switch_time_in_usec, - beacon_interval); - cmd.switch_time = iwl_add_beacon_time(priv, - priv->ucode_beacon_time, - ucode_switch_time, - beacon_interval); - } - IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", - cmd.switch_time); - ch_info = iwl_get_channel_info(priv, priv->band, ch); - if (ch_info) - cmd.expect_beacon = is_channel_radar(ch_info); - else { - IWL_ERR(priv, "invalid channel switch from %u to %u\n", - ctx->active.channel, ch); - return -EFAULT; - } - - rc = iwl4965_fill_txpower_tbl(priv, band, ch, is_ht40, - ctrl_chan_high, &cmd.tx_power); - if (rc) { - IWL_DEBUG_11H(priv, "error:%d fill txpower_tbl\n", rc); - return rc; - } - - priv->switch_rxon.channel = cmd.channel; - priv->switch_rxon.switch_in_progress = true; - - return iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); -} - -/** - * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array - */ -static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv, - struct iwl_tx_queue *txq, - u16 byte_cnt) -{ - struct iwl4965_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr; - int txq_id = txq->q.id; - int write_ptr = txq->q.write_ptr; - int len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; - __le16 bc_ent; - - WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX); - - bc_ent = cpu_to_le16(len & 0xFFF); - /* Set up byte count within first 256 entries */ - scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent; - - /* If within first 64 entries, duplicate at end */ - if (write_ptr < TFD_QUEUE_SIZE_BC_DUP) - scd_bc_tbl[txq_id]. - tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; -} - -/** - * iwl4965_hw_get_temperature - return the calibrated temperature (in Kelvin) - * @statistics: Provides the temperature reading from the uCode - * - * A return of <0 indicates bogus data in the statistics - */ -static int iwl4965_hw_get_temperature(struct iwl_priv *priv) -{ - s32 temperature; - s32 vt; - s32 R1, R2, R3; - u32 R4; - - if (test_bit(STATUS_TEMPERATURE, &priv->status) && - (priv->_agn.statistics.flag & - STATISTICS_REPLY_FLG_HT40_MODE_MSK)) { - IWL_DEBUG_TEMP(priv, "Running HT40 temperature calibration\n"); - R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]); - R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]); - R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[1]); - R4 = le32_to_cpu(priv->card_alive_init.therm_r4[1]); - } else { - IWL_DEBUG_TEMP(priv, "Running temperature calibration\n"); - R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[0]); - R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[0]); - R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[0]); - R4 = le32_to_cpu(priv->card_alive_init.therm_r4[0]); - } - - /* - * Temperature is only 23 bits, so sign extend out to 32. - * - * NOTE If we haven't received a statistics notification yet - * with an updated temperature, use R4 provided to us in the - * "initialize" ALIVE response. - */ - if (!test_bit(STATUS_TEMPERATURE, &priv->status)) - vt = sign_extend32(R4, 23); - else - vt = sign_extend32(le32_to_cpu(priv->_agn.statistics. - general.common.temperature), 23); - - IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt); - - if (R3 == R1) { - IWL_ERR(priv, "Calibration conflict R1 == R3\n"); - return -1; - } - - /* Calculate temperature in degrees Kelvin, adjust by 97%. - * Add offset to center the adjustment around 0 degrees Centigrade. */ - temperature = TEMPERATURE_CALIB_A_VAL * (vt - R2); - temperature /= (R3 - R1); - temperature = (temperature * 97) / 100 + TEMPERATURE_CALIB_KELVIN_OFFSET; - - IWL_DEBUG_TEMP(priv, "Calibrated temperature: %dK, %dC\n", - temperature, KELVIN_TO_CELSIUS(temperature)); - - return temperature; -} - -/* Adjust Txpower only if temperature variance is greater than threshold. */ -#define IWL_TEMPERATURE_THRESHOLD 3 - -/** - * iwl4965_is_temp_calib_needed - determines if new calibration is needed - * - * If the temperature changed has changed sufficiently, then a recalibration - * is needed. - * - * Assumes caller will replace priv->last_temperature once calibration - * executed. - */ -static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv) -{ - int temp_diff; - - if (!test_bit(STATUS_STATISTICS, &priv->status)) { - IWL_DEBUG_TEMP(priv, "Temperature not updated -- no statistics.\n"); - return 0; - } - - temp_diff = priv->temperature - priv->last_temperature; - - /* get absolute value */ - if (temp_diff < 0) { - IWL_DEBUG_POWER(priv, "Getting cooler, delta %d\n", temp_diff); - temp_diff = -temp_diff; - } else if (temp_diff == 0) - IWL_DEBUG_POWER(priv, "Temperature unchanged\n"); - else - IWL_DEBUG_POWER(priv, "Getting warmer, delta %d\n", temp_diff); - - if (temp_diff < IWL_TEMPERATURE_THRESHOLD) { - IWL_DEBUG_POWER(priv, " => thermal txpower calib not needed\n"); - return 0; - } - - IWL_DEBUG_POWER(priv, " => thermal txpower calib needed\n"); - - return 1; -} - -static void iwl4965_temperature_calib(struct iwl_priv *priv) -{ - s32 temp; - - temp = iwl4965_hw_get_temperature(priv); - if (temp < 0) - return; - - if (priv->temperature != temp) { - if (priv->temperature) - IWL_DEBUG_TEMP(priv, "Temperature changed " - "from %dC to %dC\n", - KELVIN_TO_CELSIUS(priv->temperature), - KELVIN_TO_CELSIUS(temp)); - else - IWL_DEBUG_TEMP(priv, "Temperature " - "initialized to %dC\n", - KELVIN_TO_CELSIUS(temp)); - } - - priv->temperature = temp; - iwl_tt_handler(priv); - set_bit(STATUS_TEMPERATURE, &priv->status); - - if (!priv->disable_tx_power_cal && - unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && - iwl4965_is_temp_calib_needed(priv)) - queue_work(priv->workqueue, &priv->txpower_work); -} - -/** - * iwl4965_tx_queue_stop_scheduler - Stop queue, but keep configuration - */ -static void iwl4965_tx_queue_stop_scheduler(struct iwl_priv *priv, - u16 txq_id) -{ - /* Simply stop the queue, but don't change any configuration; - * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ - iwl_write_prph(priv, - IWL49_SCD_QUEUE_STATUS_BITS(txq_id), - (0 << IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE)| - (1 << IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); -} - -/** - * txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE - * priv->lock must be held by the caller - */ -static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, - u16 ssn_idx, u8 tx_fifo) -{ - if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || - (IWL49_FIRST_AMPDU_QUEUE + - priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { - IWL_WARN(priv, - "queue number out of range: %d, must be %d to %d\n", - txq_id, IWL49_FIRST_AMPDU_QUEUE, - IWL49_FIRST_AMPDU_QUEUE + - priv->cfg->base_params->num_of_ampdu_queues - 1); - return -EINVAL; - } - - iwl4965_tx_queue_stop_scheduler(priv, txq_id); - - iwl_clear_bits_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, (1 << txq_id)); - - priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); - priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); - /* supposes that ssn_idx is valid (!= 0xFFF) */ - iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx); - - iwl_clear_bits_prph(priv, IWL49_SCD_INTERRUPT_MASK, (1 << txq_id)); - iwl_txq_ctx_deactivate(priv, txq_id); - iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0); - - return 0; -} - -/** - * iwl4965_tx_queue_set_q2ratid - Map unique receiver/tid combination to a queue - */ -static int iwl4965_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid, - u16 txq_id) -{ - u32 tbl_dw_addr; - u32 tbl_dw; - u16 scd_q2ratid; - - scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK; - - tbl_dw_addr = priv->scd_base_addr + - IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id); - - tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr); - - if (txq_id & 0x1) - tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); - else - tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); - - iwl_write_targ_mem(priv, tbl_dw_addr, tbl_dw); - - return 0; -} - - -/** - * iwl4965_tx_queue_agg_enable - Set up & enable aggregation for selected queue - * - * NOTE: txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE, - * i.e. it must be one of the higher queues used for aggregation - */ -static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, - int tx_fifo, int sta_id, int tid, u16 ssn_idx) -{ - unsigned long flags; - u16 ra_tid; - int ret; - - if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || - (IWL49_FIRST_AMPDU_QUEUE + - priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { - IWL_WARN(priv, - "queue number out of range: %d, must be %d to %d\n", - txq_id, IWL49_FIRST_AMPDU_QUEUE, - IWL49_FIRST_AMPDU_QUEUE + - priv->cfg->base_params->num_of_ampdu_queues - 1); - return -EINVAL; - } - - ra_tid = BUILD_RAxTID(sta_id, tid); - - /* Modify device's station table to Tx this TID */ - ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); - if (ret) - return ret; - - spin_lock_irqsave(&priv->lock, flags); - - /* Stop this Tx queue before configuring it */ - iwl4965_tx_queue_stop_scheduler(priv, txq_id); - - /* Map receiver-address / traffic-ID to this queue */ - iwl4965_tx_queue_set_q2ratid(priv, ra_tid, txq_id); - - /* Set this queue as a chain-building queue */ - iwl_set_bits_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, (1 << txq_id)); - - /* Place first TFD at index corresponding to start sequence number. - * Assumes that ssn_idx is valid (!= 0xFFF) */ - priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); - priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); - iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx); - - /* Set up Tx window size and frame limit for this queue */ - iwl_write_targ_mem(priv, - priv->scd_base_addr + IWL49_SCD_CONTEXT_QUEUE_OFFSET(txq_id), - (SCD_WIN_SIZE << IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) & - IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK); - - iwl_write_targ_mem(priv, priv->scd_base_addr + - IWL49_SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), - (SCD_FRAME_LIMIT << IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) - & IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK); - - iwl_set_bits_prph(priv, IWL49_SCD_INTERRUPT_MASK, (1 << txq_id)); - - /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ - iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1); - - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; -} - - -static u16 iwl4965_get_hcmd_size(u8 cmd_id, u16 len) -{ - switch (cmd_id) { - case REPLY_RXON: - return (u16) sizeof(struct iwl4965_rxon_cmd); - default: - return len; - } -} - -static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) -{ - struct iwl4965_addsta_cmd *addsta = (struct iwl4965_addsta_cmd *)data; - addsta->mode = cmd->mode; - memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify)); - memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo)); - addsta->station_flags = cmd->station_flags; - addsta->station_flags_msk = cmd->station_flags_msk; - addsta->tid_disable_tx = cmd->tid_disable_tx; - addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid; - addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid; - addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn; - addsta->sleep_tx_count = cmd->sleep_tx_count; - addsta->reserved1 = cpu_to_le16(0); - addsta->reserved2 = cpu_to_le16(0); - - return (u16)sizeof(struct iwl4965_addsta_cmd); -} - -static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp) -{ - return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN; -} - -/** - * iwl4965_tx_status_reply_tx - Handle Tx response for frames in aggregation queue - */ -static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, - struct iwl_ht_agg *agg, - struct iwl4965_tx_resp *tx_resp, - int txq_id, u16 start_idx) -{ - u16 status; - struct agg_tx_status *frame_status = tx_resp->u.agg_status; - struct ieee80211_tx_info *info = NULL; - struct ieee80211_hdr *hdr = NULL; - u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); - int i, sh, idx; - u16 seq; - if (agg->wait_for_ba) - IWL_DEBUG_TX_REPLY(priv, "got tx response w/o block-ack\n"); - - agg->frame_count = tx_resp->frame_count; - agg->start_idx = start_idx; - agg->rate_n_flags = rate_n_flags; - agg->bitmap = 0; - - /* num frames attempted by Tx command */ - if (agg->frame_count == 1) { - /* Only one frame was attempted; no block-ack will arrive */ - status = le16_to_cpu(frame_status[0].status); - idx = start_idx; - - /* FIXME: code repetition */ - IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n", - agg->frame_count, agg->start_idx, idx); - - info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb); - info->status.rates[0].count = tx_resp->failure_frame + 1; - info->flags &= ~IEEE80211_TX_CTL_AMPDU; - info->flags |= iwl_tx_status_to_mac80211(status); - iwlagn_hwrate_to_tx_control(priv, rate_n_flags, info); - /* FIXME: code repetition end */ - - IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n", - status & 0xff, tx_resp->failure_frame); - IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags); - - agg->wait_for_ba = 0; - } else { - /* Two or more frames were attempted; expect block-ack */ - u64 bitmap = 0; - int start = agg->start_idx; - - /* Construct bit-map of pending frames within Tx window */ - for (i = 0; i < agg->frame_count; i++) { - u16 sc; - status = le16_to_cpu(frame_status[i].status); - seq = le16_to_cpu(frame_status[i].sequence); - idx = SEQ_TO_INDEX(seq); - txq_id = SEQ_TO_QUEUE(seq); - - if (status & (AGG_TX_STATE_FEW_BYTES_MSK | - AGG_TX_STATE_ABORT_MSK)) - continue; - - IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n", - agg->frame_count, txq_id, idx); - - hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx); - if (!hdr) { - IWL_ERR(priv, - "BUG_ON idx doesn't point to valid skb" - " idx=%d, txq_id=%d\n", idx, txq_id); - return -1; - } - - sc = le16_to_cpu(hdr->seq_ctrl); - if (idx != (SEQ_TO_SN(sc) & 0xff)) { - IWL_ERR(priv, - "BUG_ON idx doesn't match seq control" - " idx=%d, seq_idx=%d, seq=%d\n", - idx, SEQ_TO_SN(sc), hdr->seq_ctrl); - return -1; - } - - IWL_DEBUG_TX_REPLY(priv, "AGG Frame i=%d idx %d seq=%d\n", - i, idx, SEQ_TO_SN(sc)); - - sh = idx - start; - if (sh > 64) { - sh = (start - idx) + 0xff; - bitmap = bitmap << sh; - sh = 0; - start = idx; - } else if (sh < -64) - sh = 0xff - (start - idx); - else if (sh < 0) { - sh = start - idx; - start = idx; - bitmap = bitmap << sh; - sh = 0; - } - bitmap |= 1ULL << sh; - IWL_DEBUG_TX_REPLY(priv, "start=%d bitmap=0x%llx\n", - start, (unsigned long long)bitmap); - } - - agg->bitmap = bitmap; - agg->start_idx = start; - IWL_DEBUG_TX_REPLY(priv, "Frames %d start_idx=%d bitmap=0x%llx\n", - agg->frame_count, agg->start_idx, - (unsigned long long)agg->bitmap); - - if (bitmap) - agg->wait_for_ba = 1; - } - return 0; -} - -static u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr) -{ - int i; - int start = 0; - int ret = IWL_INVALID_STATION; - unsigned long flags; - - if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) || - (priv->iw_mode == NL80211_IFTYPE_AP)) - start = IWL_STA_ID; - - if (is_broadcast_ether_addr(addr)) - return priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; - - spin_lock_irqsave(&priv->sta_lock, flags); - for (i = start; i < priv->hw_params.max_stations; i++) - if (priv->stations[i].used && - (!compare_ether_addr(priv->stations[i].sta.sta.addr, - addr))) { - ret = i; - goto out; - } - - IWL_DEBUG_ASSOC_LIMIT(priv, "can not find STA %pM total %d\n", - addr, priv->num_stations); - - out: - /* - * It may be possible that more commands interacting with stations - * arrive before we completed processing the adding of - * station - */ - if (ret != IWL_INVALID_STATION && - (!(priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) || - ((priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) && - (priv->stations[ret].used & IWL_STA_UCODE_INPROGRESS)))) { - IWL_ERR(priv, "Requested station info for sta %d before ready.\n", - ret); - ret = IWL_INVALID_STATION; - } - spin_unlock_irqrestore(&priv->sta_lock, flags); - return ret; -} - -static int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) -{ - if (priv->iw_mode == NL80211_IFTYPE_STATION) { - return IWL_AP_ID; - } else { - u8 *da = ieee80211_get_DA(hdr); - return iwl_find_station(priv, da); - } -} - -/** - * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response - */ -static void iwl4965_rx_reply_tx(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - u16 sequence = le16_to_cpu(pkt->hdr.sequence); - int txq_id = SEQ_TO_QUEUE(sequence); - int index = SEQ_TO_INDEX(sequence); - struct iwl_tx_queue *txq = &priv->txq[txq_id]; - struct ieee80211_hdr *hdr; - struct ieee80211_tx_info *info; - struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; - u32 status = le32_to_cpu(tx_resp->u.status); - int uninitialized_var(tid); - int sta_id; - int freed; - u8 *qc = NULL; - unsigned long flags; - - if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { - IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " - "is out of range [0-%d] %d %d\n", txq_id, - index, txq->q.n_bd, txq->q.write_ptr, - txq->q.read_ptr); - return; - } - - txq->time_stamp = jiffies; - info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); - memset(&info->status, 0, sizeof(info->status)); - - hdr = iwl_tx_queue_get_hdr(priv, txq_id, index); - if (ieee80211_is_data_qos(hdr->frame_control)) { - qc = ieee80211_get_qos_ctl(hdr); - tid = qc[0] & 0xf; - } - - sta_id = iwl_get_ra_sta_id(priv, hdr); - if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) { - IWL_ERR(priv, "Station not known\n"); - return; - } - - spin_lock_irqsave(&priv->sta_lock, flags); - if (txq->sched_retry) { - const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); - struct iwl_ht_agg *agg = NULL; - WARN_ON(!qc); - - agg = &priv->stations[sta_id].tid[tid].agg; - - iwl4965_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); - - /* check if BAR is needed */ - if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) - info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; - - if (txq->q.read_ptr != (scd_ssn & 0xff)) { - index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); - IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn " - "%d index %d\n", scd_ssn , index); - freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); - if (qc) - iwl_free_tfds_in_queue(priv, sta_id, - tid, freed); - - if (priv->mac80211_registered && - (iwl_queue_space(&txq->q) > txq->q.low_mark) && - (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) - iwl_wake_queue(priv, txq); - } - } else { - info->status.rates[0].count = tx_resp->failure_frame + 1; - info->flags |= iwl_tx_status_to_mac80211(status); - iwlagn_hwrate_to_tx_control(priv, - le32_to_cpu(tx_resp->rate_n_flags), - info); - - IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) " - "rate_n_flags 0x%x retries %d\n", - txq_id, - iwl_get_tx_fail_reason(status), status, - le32_to_cpu(tx_resp->rate_n_flags), - tx_resp->failure_frame); - - freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); - if (qc && likely(sta_id != IWL_INVALID_STATION)) - iwl_free_tfds_in_queue(priv, sta_id, tid, freed); - else if (sta_id == IWL_INVALID_STATION) - IWL_DEBUG_TX_REPLY(priv, "Station not known\n"); - - if (priv->mac80211_registered && - (iwl_queue_space(&txq->q) > txq->q.low_mark)) - iwl_wake_queue(priv, txq); - } - if (qc && likely(sta_id != IWL_INVALID_STATION)) - iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); - - iwl_check_abort_status(priv, tx_resp->frame_count, status); - - spin_unlock_irqrestore(&priv->sta_lock, flags); -} - -static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl4965_beacon_notif *beacon = (void *)pkt->u.raw; -#ifdef CONFIG_IWLWIFI_DEBUG - u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); - - IWL_DEBUG_RX(priv, "beacon status %#x, retries:%d ibssmgr:%d " - "tsf:0x%.8x%.8x rate:%d\n", - le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK, - beacon->beacon_notify_hdr.failure_frame, - le32_to_cpu(beacon->ibss_mgr_status), - le32_to_cpu(beacon->high_tsf), - le32_to_cpu(beacon->low_tsf), rate); -#endif - - priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); - - if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) - queue_work(priv->workqueue, &priv->beacon_update); -} - -static int iwl4965_calc_rssi(struct iwl_priv *priv, - struct iwl_rx_phy_res *rx_resp) -{ - /* data from PHY/DSP regarding signal strength, etc., - * contents are always there, not configurable by host. */ - struct iwl4965_rx_non_cfg_phy *ncphy = - (struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy_buf; - u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL49_AGC_DB_MASK) - >> IWL49_AGC_DB_POS; - - u32 valid_antennae = - (le16_to_cpu(rx_resp->phy_flags) & IWL49_RX_PHY_FLAGS_ANTENNAE_MASK) - >> IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET; - u8 max_rssi = 0; - u32 i; - - /* Find max rssi among 3 possible receivers. - * These values are measured by the digital signal processor (DSP). - * They should stay fairly constant even as the signal strength varies, - * if the radio's automatic gain control (AGC) is working right. - * AGC value (see below) will provide the "interesting" info. */ - for (i = 0; i < 3; i++) - if (valid_antennae & (1 << i)) - max_rssi = max(ncphy->rssi_info[i << 1], max_rssi); - - IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n", - ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4], - max_rssi, agc); - - /* dBm = max_rssi dB - agc dB - constant. - * Higher AGC (higher radio gain) means lower signal. */ - return max_rssi - agc - IWLAGN_RSSI_OFFSET; -} - - -/* Set up 4965-specific Rx frame reply handlers */ -static void iwl4965_rx_handler_setup(struct iwl_priv *priv) -{ - /* Legacy Rx frames */ - priv->rx_handlers[REPLY_RX] = iwlagn_rx_reply_rx; - /* Tx response */ - priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; - priv->rx_handlers[BEACON_NOTIFICATION] = iwl4965_rx_beacon_notif; - - /* set up notification wait support */ - spin_lock_init(&priv->_agn.notif_wait_lock); - INIT_LIST_HEAD(&priv->_agn.notif_waits); - init_waitqueue_head(&priv->_agn.notif_waitq); -} - -static void iwl4965_setup_deferred_work(struct iwl_priv *priv) -{ - INIT_WORK(&priv->txpower_work, iwl4965_bg_txpower_work); -} - -static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) -{ - cancel_work_sync(&priv->txpower_work); -} - -static struct iwl_hcmd_ops iwl4965_hcmd = { - .rxon_assoc = iwl4965_send_rxon_assoc, - .commit_rxon = iwl4965_commit_rxon, - .set_rxon_chain = iwlagn_set_rxon_chain, - .send_bt_config = iwl_send_bt_config, -}; - -static void iwl4965_post_scan(struct iwl_priv *priv) -{ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - /* - * Since setting the RXON may have been deferred while - * performing the scan, fire one off if needed - */ - if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) - iwlcore_commit_rxon(priv, ctx); -} - -static void iwl4965_post_associate(struct iwl_priv *priv) -{ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - struct ieee80211_vif *vif = ctx->vif; - struct ieee80211_conf *conf = NULL; - int ret = 0; - - if (!vif || !priv->is_open) - return; - - if (vif->type == NL80211_IFTYPE_AP) { - IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); - return; - } - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - iwl_scan_cancel_timeout(priv, 200); - - conf = ieee80211_get_hw_conf(priv->hw); - - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv, ctx); - - ret = iwl_send_rxon_timing(priv, ctx); - if (ret) - IWL_WARN(priv, "RXON timing - " - "Attempting to continue.\n"); - - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - - iwl_set_rxon_ht(priv, &priv->current_ht_config); - - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - - ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); - - IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", - vif->bss_conf.aid, vif->bss_conf.beacon_int); - - if (vif->bss_conf.use_short_preamble) - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; - else - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { - if (vif->bss_conf.use_short_slot) - ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; - else - ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; - } - - iwlcore_commit_rxon(priv, ctx); - - IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", - vif->bss_conf.aid, ctx->active.bssid_addr); - - switch (vif->type) { - case NL80211_IFTYPE_STATION: - break; - case NL80211_IFTYPE_ADHOC: - iwlagn_send_beacon_cmd(priv); - break; - default: - IWL_ERR(priv, "%s Should not be called in %d mode\n", - __func__, vif->type); - break; - } - - /* the chain noise calibration will enabled PM upon completion - * If chain noise has already been run, then we need to enable - * power management here */ - if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE) - iwl_power_update_mode(priv, false); - - /* Enable Rx differential gain and sensitivity calibrations */ - iwl_chain_noise_reset(priv); - priv->start_calib = 1; -} - -static void iwl4965_config_ap(struct iwl_priv *priv) -{ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - struct ieee80211_vif *vif = ctx->vif; - int ret = 0; - - lockdep_assert_held(&priv->mutex); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - /* The following should be done only at AP bring up */ - if (!iwl_is_associated_ctx(ctx)) { - - /* RXON - unassoc (to set timing command) */ - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv, ctx); - - /* RXON Timing */ - ret = iwl_send_rxon_timing(priv, ctx); - if (ret) - IWL_WARN(priv, "RXON timing failed - " - "Attempting to continue.\n"); - - /* AP has all antennas */ - priv->chain_noise_data.active_chains = - priv->hw_params.valid_rx_ant; - iwl_set_rxon_ht(priv, &priv->current_ht_config); - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - - ctx->staging.assoc_id = 0; - - if (vif->bss_conf.use_short_preamble) - ctx->staging.flags |= - RXON_FLG_SHORT_PREAMBLE_MSK; - else - ctx->staging.flags &= - ~RXON_FLG_SHORT_PREAMBLE_MSK; - - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { - if (vif->bss_conf.use_short_slot) - ctx->staging.flags |= - RXON_FLG_SHORT_SLOT_MSK; - else - ctx->staging.flags &= - ~RXON_FLG_SHORT_SLOT_MSK; - } - /* need to send beacon cmd before committing assoc RXON! */ - iwlagn_send_beacon_cmd(priv); - /* restore RXON assoc */ - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv, ctx); - } - iwlagn_send_beacon_cmd(priv); - - /* FIXME - we need to add code here to detect a totally new - * configuration, reset the AP, unassoc, rxon timing, assoc, - * clear sta table, add BCAST sta... */ -} - -static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { - .get_hcmd_size = iwl4965_get_hcmd_size, - .build_addsta_hcmd = iwl4965_build_addsta_hcmd, - .chain_noise_reset = iwl4965_chain_noise_reset, - .gain_computation = iwl4965_gain_computation, - .tx_cmd_protection = iwl_legacy_tx_cmd_protection, - .calc_rssi = iwl4965_calc_rssi, - .request_scan = iwlagn_request_scan, - .post_scan = iwl4965_post_scan, -}; - -static struct iwl_lib_ops iwl4965_lib = { - .set_hw_params = iwl4965_hw_set_hw_params, - .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, - .txq_set_sched = iwl4965_txq_set_sched, - .txq_agg_enable = iwl4965_txq_agg_enable, - .txq_agg_disable = iwl4965_txq_agg_disable, - .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, - .txq_free_tfd = iwl_hw_txq_free_tfd, - .txq_init = iwl_hw_tx_queue_init, - .rx_handler_setup = iwl4965_rx_handler_setup, - .setup_deferred_work = iwl4965_setup_deferred_work, - .cancel_deferred_work = iwl4965_cancel_deferred_work, - .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, - .alive_notify = iwl4965_alive_notify, - .init_alive_start = iwl4965_init_alive_start, - .load_ucode = iwl4965_load_bsm, - .dump_nic_event_log = iwl_dump_nic_event_log, - .dump_nic_error_log = iwl_dump_nic_error_log, - .dump_fh = iwl_dump_fh, - .set_channel_switch = iwl4965_hw_channel_switch, - .apm_ops = { - .init = iwl_apm_init, - .config = iwl4965_nic_config, - }, - .eeprom_ops = { - .regulatory_bands = { - EEPROM_REGULATORY_BAND_1_CHANNELS, - EEPROM_REGULATORY_BAND_2_CHANNELS, - EEPROM_REGULATORY_BAND_3_CHANNELS, - EEPROM_REGULATORY_BAND_4_CHANNELS, - EEPROM_REGULATORY_BAND_5_CHANNELS, - EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS, - EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS - }, - .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, - .release_semaphore = iwlcore_eeprom_release_semaphore, - .calib_version = iwl4965_eeprom_calib_version, - .query_addr = iwlcore_eeprom_query_addr, - }, - .send_tx_power = iwl4965_send_tx_power, - .update_chain_flags = iwl_update_chain_flags, - .isr_ops = { - .isr = iwl_isr_legacy, - }, - .temp_ops = { - .temperature = iwl4965_temperature_calib, - }, - .debugfs_ops = { - .rx_stats_read = iwl_ucode_rx_stats_read, - .tx_stats_read = iwl_ucode_tx_stats_read, - .general_stats_read = iwl_ucode_general_stats_read, - .bt_stats_read = iwl_ucode_bt_stats_read, - .reply_tx_error = iwl_reply_tx_error_read, - }, - .check_plcp_health = iwl_good_plcp_health, -}; - -static const struct iwl_legacy_ops iwl4965_legacy_ops = { - .post_associate = iwl4965_post_associate, - .config_ap = iwl4965_config_ap, - .manage_ibss_station = iwlagn_manage_ibss_station, - .update_bcast_stations = iwl_update_bcast_stations, -}; - -struct ieee80211_ops iwl4965_hw_ops = { - .tx = iwlagn_mac_tx, - .start = iwlagn_mac_start, - .stop = iwlagn_mac_stop, - .add_interface = iwl_mac_add_interface, - .remove_interface = iwl_mac_remove_interface, - .change_interface = iwl_mac_change_interface, - .config = iwl_legacy_mac_config, - .configure_filter = iwlagn_configure_filter, - .set_key = iwlagn_mac_set_key, - .update_tkip_key = iwlagn_mac_update_tkip_key, - .conf_tx = iwl_mac_conf_tx, - .reset_tsf = iwl_legacy_mac_reset_tsf, - .bss_info_changed = iwl_legacy_mac_bss_info_changed, - .ampdu_action = iwlagn_mac_ampdu_action, - .hw_scan = iwl_mac_hw_scan, - .sta_add = iwlagn_mac_sta_add, - .sta_remove = iwl_mac_sta_remove, - .channel_switch = iwlagn_mac_channel_switch, - .flush = iwlagn_mac_flush, - .tx_last_beacon = iwl_mac_tx_last_beacon, -}; - -static const struct iwl_ops iwl4965_ops = { - .lib = &iwl4965_lib, - .hcmd = &iwl4965_hcmd, - .utils = &iwl4965_hcmd_utils, - .led = &iwlagn_led_ops, - .legacy = &iwl4965_legacy_ops, - .ieee80211_ops = &iwl4965_hw_ops, -}; - -static struct iwl_base_params iwl4965_base_params = { - .eeprom_size = IWL4965_EEPROM_IMG_SIZE, - .num_of_queues = IWL49_NUM_QUEUES, - .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = true, - .use_isr_legacy = true, - .broken_powersave = true, - .led_compensation = 61, - .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .wd_timeout = IWL_DEF_WD_TIMEOUT, - .temperature_kelvin = true, - .max_event_log_size = 512, - .tx_power_by_driver = true, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, - .no_agg_framecnt_info = true, -}; - -struct iwl_cfg iwl4965_agn_cfg = { - .name = "Intel(R) Wireless WiFi Link 4965AGN", - .fw_name_pre = IWL4965_FW_PRE, - .ucode_api_max = IWL4965_UCODE_API_MAX, - .ucode_api_min = IWL4965_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_ABC, - .eeprom_ver = EEPROM_4965_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION, - .ops = &iwl4965_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl4965_base_params, - .led_mode = IWL_LED_BLINK, - /* - * Force use of chains B and C for scan RX on 5 GHz band - * because the device has off-channel reception on chain A. - */ - .scan_rx_antennas[IEEE80211_BAND_5GHZ] = ANT_BC, -}; - -/* Module firmware */ -MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE(IWL4965_UCODE_API_MAX)); - diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 9965215697bb..d08fa938501a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -86,7 +86,6 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_VERSION(DRV_VERSION); MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); MODULE_LICENSE("GPL"); -MODULE_ALIAS("iwl4965"); static int iwlagn_ant_coupling; static bool iwlagn_bt_ch_announce = 1; @@ -3810,7 +3809,6 @@ static void iwlagn_bg_roc_done(struct work_struct *work) mutex_unlock(&priv->mutex); } -#ifdef CONFIG_IWL5000 static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_channel *channel, enum nl80211_channel_type channel_type, @@ -3866,7 +3864,6 @@ static int iwl_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) return 0; } -#endif /***************************************************************************** * @@ -4036,7 +4033,6 @@ static void iwl_uninit_drv(struct iwl_priv *priv) kfree(priv->scan_cmd); } -#ifdef CONFIG_IWL5000 struct ieee80211_ops iwlagn_hw_ops = { .tx = iwlagn_mac_tx, .start = iwlagn_mac_start, @@ -4061,7 +4057,6 @@ struct ieee80211_ops iwlagn_hw_ops = { .remain_on_channel = iwl_mac_remain_on_channel, .cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel, }; -#endif static void iwl_hw_detect(struct iwl_priv *priv) { @@ -4129,12 +4124,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (cfg->mod_params->disable_hw_scan) { dev_printk(KERN_DEBUG, &(pdev->dev), "sw scan support is deprecated\n"); -#ifdef CONFIG_IWL5000 iwlagn_hw_ops.hw_scan = NULL; -#endif -#ifdef CONFIG_IWL4965 - iwl4965_hw_ops.hw_scan = NULL; -#endif } hw = iwl_alloc_all(cfg); @@ -4513,12 +4503,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) /* Hardware specific file defines the PCI IDs table for that hardware module */ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { -#ifdef CONFIG_IWL4965 - {IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)}, - {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)}, -#endif /* CONFIG_IWL4965 */ -#ifdef CONFIG_IWL5000 -/* 5100 Series WiFi */ {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */ {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */ {IWL_PCI_DEVICE(0x4232, 0x1204, iwl5100_agn_cfg)}, /* Mini Card */ @@ -4704,8 +4688,6 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x0893, 0x0266, iwl230_bg_cfg)}, {IWL_PCI_DEVICE(0x0892, 0x0466, iwl230_bg_cfg)}, -#endif /* CONFIG_IWL5000 */ - {0} }; MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 977ddfb8c24c..4bd342060254 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -43,11 +43,6 @@ #include "iwl-helpers.h" -MODULE_DESCRIPTION("iwl core"); -MODULE_VERSION(IWLWIFI_VERSION); -MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); -MODULE_LICENSE("GPL"); - /* * set bt_coex_active to true, uCode will do kill/defer * every time the priority line is asserted (BT is sending signals on the @@ -65,15 +60,12 @@ MODULE_LICENSE("GPL"); * default: bt_coex_active = true (BT_COEX_ENABLE) */ bool bt_coex_active = true; -EXPORT_SYMBOL_GPL(bt_coex_active); module_param(bt_coex_active, bool, S_IRUGO); MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist"); u32 iwl_debug_level; -EXPORT_SYMBOL(iwl_debug_level); const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -EXPORT_SYMBOL(iwl_bcast_addr); /* This function both allocates and initializes hw and priv. */ @@ -98,7 +90,6 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg) out: return hw; } -EXPORT_SYMBOL(iwl_alloc_all); #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ @@ -272,7 +263,6 @@ int iwlcore_init_geos(struct iwl_priv *priv) return 0; } -EXPORT_SYMBOL(iwlcore_init_geos); /* * iwlcore_free_geos - undo allocations in iwlcore_init_geos @@ -283,7 +273,6 @@ void iwlcore_free_geos(struct iwl_priv *priv) kfree(priv->ieee_rates); clear_bit(STATUS_GEO_CONFIGURED, &priv->status); } -EXPORT_SYMBOL(iwlcore_free_geos); static bool iwl_is_channel_extension(struct iwl_priv *priv, enum ieee80211_band band, @@ -328,7 +317,6 @@ bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, le16_to_cpu(ctx->staging.channel), ctx->ht.extension_chan_offset); } -EXPORT_SYMBOL(iwl_is_ht40_tx_allowed); static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val) { @@ -429,7 +417,6 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) return iwl_send_cmd_pdu(priv, ctx->rxon_timing_cmd, sizeof(ctx->timing), &ctx->timing); } -EXPORT_SYMBOL(iwl_send_rxon_timing); void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, int hw_decrypt) @@ -442,7 +429,6 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK; } -EXPORT_SYMBOL(iwl_set_rxon_hwcrypto); /* validate RXON structure is valid */ int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx) @@ -515,7 +501,6 @@ int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx) } return 0; } -EXPORT_SYMBOL(iwl_check_rxon_cmd); /** * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed @@ -579,7 +564,6 @@ int iwl_full_rxon_required(struct iwl_priv *priv, return 0; } -EXPORT_SYMBOL(iwl_full_rxon_required); u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, struct iwl_rxon_context *ctx) @@ -593,7 +577,6 @@ u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, else return IWL_RATE_6M_PLCP; } -EXPORT_SYMBOL(iwl_rate_get_lowest_plcp); static void _iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf, @@ -670,7 +653,6 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf) for_each_context(priv, ctx) _iwl_set_rxon_ht(priv, ht_conf, ctx); } -EXPORT_SYMBOL(iwl_set_rxon_ht); /* Return valid, unused, channel for a passive scan to reset the RF */ u8 iwl_get_single_channel_number(struct iwl_priv *priv, @@ -711,7 +693,6 @@ u8 iwl_get_single_channel_number(struct iwl_priv *priv, return channel; } -EXPORT_SYMBOL(iwl_get_single_channel_number); /** * iwl_set_rxon_channel - Set the band and channel values in staging RXON @@ -742,7 +723,6 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, return 0; } -EXPORT_SYMBOL(iwl_set_rxon_channel); void iwl_set_flags_for_band(struct iwl_priv *priv, struct iwl_rxon_context *ctx, @@ -766,7 +746,6 @@ void iwl_set_flags_for_band(struct iwl_priv *priv, ctx->staging.flags &= ~RXON_FLG_CCK_MSK; } } -EXPORT_SYMBOL(iwl_set_flags_for_band); /* * initialize rxon structure with default values from eeprom @@ -838,7 +817,6 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff; ctx->staging.ofdm_ht_triple_stream_basic_rates = 0xff; } -EXPORT_SYMBOL(iwl_connection_init_rx_config); void iwl_set_rate(struct iwl_priv *priv) { @@ -871,7 +849,6 @@ void iwl_set_rate(struct iwl_priv *priv) (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; } } -EXPORT_SYMBOL(iwl_set_rate); void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) { @@ -891,7 +868,6 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) mutex_unlock(&priv->mutex); } } -EXPORT_SYMBOL(iwl_chswitch_done); void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { @@ -919,7 +895,6 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) } } } -EXPORT_SYMBOL(iwl_rx_csa); #ifdef CONFIG_IWLWIFI_DEBUG void iwl_print_rx_config_cmd(struct iwl_priv *priv, @@ -941,7 +916,6 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv, IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr); IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id)); } -EXPORT_SYMBOL(iwl_print_rx_config_cmd); #endif /** * iwl_irq_handle_error - called for HW or SW error interrupt from card @@ -1021,7 +995,6 @@ void iwl_irq_handle_error(struct iwl_priv *priv) queue_work(priv->workqueue, &priv->restart); } } -EXPORT_SYMBOL(iwl_irq_handle_error); static int iwl_apm_stop_master(struct iwl_priv *priv) { @@ -1058,7 +1031,6 @@ void iwl_apm_stop(struct iwl_priv *priv) */ iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); } -EXPORT_SYMBOL(iwl_apm_stop); /* @@ -1173,7 +1145,6 @@ int iwl_apm_init(struct iwl_priv *priv) out: return ret; } -EXPORT_SYMBOL(iwl_apm_init); int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) @@ -1233,7 +1204,6 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) } return ret; } -EXPORT_SYMBOL(iwl_set_tx_power); void iwl_send_bt_config(struct iwl_priv *priv) { @@ -1257,7 +1227,6 @@ void iwl_send_bt_config(struct iwl_priv *priv) sizeof(struct iwl_bt_cmd), &bt_cmd)) IWL_ERR(priv, "failed to send BT Coex Config\n"); } -EXPORT_SYMBOL(iwl_send_bt_config); int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) { @@ -1275,7 +1244,6 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) sizeof(struct iwl_statistics_cmd), &statistics_cmd); } -EXPORT_SYMBOL(iwl_send_statistics_request); void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) @@ -1287,7 +1255,6 @@ void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, sleep->pm_sleep_mode, sleep->pm_wakeup_src); #endif } -EXPORT_SYMBOL(iwl_rx_pm_sleep_notif); void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) @@ -1299,7 +1266,6 @@ void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, get_cmd_string(pkt->hdr.cmd)); iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len); } -EXPORT_SYMBOL(iwl_rx_pm_debug_statistics_notif); void iwl_rx_reply_error(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) @@ -1314,7 +1280,6 @@ void iwl_rx_reply_error(struct iwl_priv *priv, le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num), le32_to_cpu(pkt->u.err_resp.error_info)); } -EXPORT_SYMBOL(iwl_rx_reply_error); void iwl_clear_isr_stats(struct iwl_priv *priv) { @@ -1366,7 +1331,6 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, IWL_DEBUG_MAC80211(priv, "leave\n"); return 0; } -EXPORT_SYMBOL(iwl_mac_conf_tx); int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw) { @@ -1374,7 +1338,6 @@ int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw) return priv->ibss_manager == IWL_IBSS_MANAGER; } -EXPORT_SYMBOL_GPL(iwl_mac_tx_last_beacon); static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { @@ -1484,7 +1447,6 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) IWL_DEBUG_MAC80211(priv, "leave\n"); return err; } -EXPORT_SYMBOL(iwl_mac_add_interface); static void iwl_teardown_interface(struct iwl_priv *priv, struct ieee80211_vif *vif, @@ -1537,7 +1499,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "leave\n"); } -EXPORT_SYMBOL(iwl_mac_remove_interface); int iwl_alloc_txq_mem(struct iwl_priv *priv) { @@ -1552,14 +1513,12 @@ int iwl_alloc_txq_mem(struct iwl_priv *priv) } return 0; } -EXPORT_SYMBOL(iwl_alloc_txq_mem); void iwl_free_txq_mem(struct iwl_priv *priv) { kfree(priv->txq); priv->txq = NULL; } -EXPORT_SYMBOL(iwl_free_txq_mem); #ifdef CONFIG_IWLWIFI_DEBUGFS @@ -1598,7 +1557,6 @@ int iwl_alloc_traffic_mem(struct iwl_priv *priv) iwl_reset_traffic_log(priv); return 0; } -EXPORT_SYMBOL(iwl_alloc_traffic_mem); void iwl_free_traffic_mem(struct iwl_priv *priv) { @@ -1608,7 +1566,6 @@ void iwl_free_traffic_mem(struct iwl_priv *priv) kfree(priv->rx_traffic); priv->rx_traffic = NULL; } -EXPORT_SYMBOL(iwl_free_traffic_mem); void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv, u16 length, struct ieee80211_hdr *header) @@ -1633,7 +1590,6 @@ void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv, (priv->tx_traffic_idx + 1) % IWL_TRAFFIC_ENTRIES; } } -EXPORT_SYMBOL(iwl_dbg_log_tx_data_frame); void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, u16 length, struct ieee80211_hdr *header) @@ -1658,7 +1614,6 @@ void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, (priv->rx_traffic_idx + 1) % IWL_TRAFFIC_ENTRIES; } } -EXPORT_SYMBOL(iwl_dbg_log_rx_data_frame); const char *get_mgmt_string(int cmd) { @@ -1795,7 +1750,6 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) stats->data_bytes += len; } } -EXPORT_SYMBOL(iwl_update_stats); #endif static void iwl_force_rf_reset(struct iwl_priv *priv) @@ -1934,7 +1888,6 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_unlock(&priv->mutex); return err; } -EXPORT_SYMBOL(iwl_mac_change_interface); /* * On every watchdog tick we check (latest) time stamp. If it does not @@ -2006,7 +1959,6 @@ void iwl_bg_watchdog(unsigned long data) mod_timer(&priv->watchdog, jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout))); } -EXPORT_SYMBOL(iwl_bg_watchdog); void iwl_setup_watchdog(struct iwl_priv *priv) { @@ -2018,7 +1970,6 @@ void iwl_setup_watchdog(struct iwl_priv *priv) else del_timer(&priv->watchdog); } -EXPORT_SYMBOL(iwl_setup_watchdog); /* * extended beacon time format @@ -2044,7 +1995,6 @@ u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval) return (quot << priv->hw_params.beacon_time_tsf_bits) + rem; } -EXPORT_SYMBOL(iwl_usecs_to_beacons); /* base is usually what we get from ucode with each received frame, * the same as HW timer counter counting down @@ -2072,7 +2022,6 @@ __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, return cpu_to_le32(res); } -EXPORT_SYMBOL(iwl_add_beacon_time); #ifdef CONFIG_PM @@ -2092,7 +2041,6 @@ int iwl_pci_suspend(struct device *device) return 0; } -EXPORT_SYMBOL(iwl_pci_suspend); int iwl_pci_resume(struct device *device) { @@ -2121,7 +2069,6 @@ int iwl_pci_resume(struct device *device) return 0; } -EXPORT_SYMBOL(iwl_pci_resume); const struct dev_pm_ops iwl_pm_ops = { .suspend = iwl_pci_suspend, @@ -2131,6 +2078,5 @@ const struct dev_pm_ops iwl_pm_ops = { .poweroff = iwl_pci_suspend, .restore = iwl_pci_resume, }; -EXPORT_SYMBOL(iwl_pm_ops); #endif /* CONFIG_PM */ diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index bc7a965c18f9..8842411f1cf3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1788,7 +1788,6 @@ err: iwl_dbgfs_unregister(priv); return -ENOMEM; } -EXPORT_SYMBOL(iwl_dbgfs_register); /** * Remove the debugfs files and directories @@ -1802,7 +1801,6 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) debugfs_remove_recursive(priv->debugfs_dir); priv->debugfs_dir = NULL; } -EXPORT_SYMBOL(iwl_dbgfs_unregister); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 065615ee040a..58165c769cf1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -43,14 +43,14 @@ #include "iwl-prph.h" #include "iwl-fh.h" #include "iwl-debug.h" -#include "iwl-4965-hw.h" -#include "iwl-3945-hw.h" #include "iwl-agn-hw.h" #include "iwl-led.h" #include "iwl-power.h" #include "iwl-agn-rs.h" #include "iwl-agn-tt.h" +#define U32_PAD(n) ((4-(n))&0x3) + struct iwl_tx_queue; /* CT-KILL constants */ diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 358cfd7e5af1..833194a2c639 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -222,7 +222,6 @@ const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) BUG_ON(offset >= priv->cfg->base_params->eeprom_size); return &priv->eeprom[offset]; } -EXPORT_SYMBOL(iwlcore_eeprom_query_addr); static int iwl_init_otp_access(struct iwl_priv *priv) { @@ -382,7 +381,6 @@ const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) { return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset); } -EXPORT_SYMBOL(iwl_eeprom_query_addr); u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset) { @@ -390,7 +388,6 @@ u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset) return 0; return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8); } -EXPORT_SYMBOL(iwl_eeprom_query16); /** * iwl_eeprom_init - read EEPROM contents @@ -509,14 +506,12 @@ err: alloc_err: return ret; } -EXPORT_SYMBOL(iwl_eeprom_init); void iwl_eeprom_free(struct iwl_priv *priv) { kfree(priv->eeprom); priv->eeprom = NULL; } -EXPORT_SYMBOL(iwl_eeprom_free); static void iwl_init_band_reference(const struct iwl_priv *priv, int eep_band, int *eeprom_ch_count, @@ -779,7 +774,6 @@ int iwl_init_channel_map(struct iwl_priv *priv) return 0; } -EXPORT_SYMBOL(iwl_init_channel_map); /* * iwl_free_channel_map - undo allocations in iwl_init_channel_map @@ -789,7 +783,6 @@ void iwl_free_channel_map(struct iwl_priv *priv) kfree(priv->channel_info); priv->channel_count = 0; } -EXPORT_SYMBOL(iwl_free_channel_map); /** * iwl_get_channel_info - Find driver's private channel info @@ -818,4 +811,3 @@ const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv, return NULL; } -EXPORT_SYMBOL(iwl_get_channel_info); diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index e4b953d7b7bf..02499f684683 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -114,7 +114,6 @@ const char *get_cmd_string(u8 cmd) } } -EXPORT_SYMBOL(get_cmd_string); #define HOST_COMPLETE_TIMEOUT (HZ / 2) @@ -253,7 +252,6 @@ out: mutex_unlock(&priv->sync_cmd_mutex); return ret; } -EXPORT_SYMBOL(iwl_send_cmd_sync); int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) { @@ -262,7 +260,6 @@ int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) return iwl_send_cmd_sync(priv, cmd); } -EXPORT_SYMBOL(iwl_send_cmd); int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data) { @@ -274,7 +271,6 @@ int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data) return iwl_send_cmd_sync(priv, &cmd); } -EXPORT_SYMBOL(iwl_send_cmd_pdu); int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, const void *data, @@ -293,4 +289,3 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, return iwl_send_cmd_async(priv, &cmd); } -EXPORT_SYMBOL(iwl_send_cmd_pdu_async); diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 074ad2275228..d7f2a0bb32c9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -175,7 +175,6 @@ void iwl_leds_init(struct iwl_priv *priv) priv->led_registered = true; } -EXPORT_SYMBOL(iwl_leds_init); void iwl_leds_exit(struct iwl_priv *priv) { @@ -185,4 +184,3 @@ void iwl_leds_exit(struct iwl_priv *priv) led_classdev_unregister(&priv->led); kfree(priv->led.name); } -EXPORT_SYMBOL(iwl_leds_exit); diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.c b/drivers/net/wireless/iwlwifi/iwl-legacy.c deleted file mode 100644 index e1ace3ce30b3..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-legacy.c +++ /dev/null @@ -1,657 +0,0 @@ -/****************************************************************************** - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - *****************************************************************************/ - -#include -#include - -#include "iwl-dev.h" -#include "iwl-core.h" -#include "iwl-helpers.h" -#include "iwl-legacy.h" - -static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) -{ - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - if (!ctx->is_active) - return; - - ctx->qos_data.def_qos_parm.qos_flags = 0; - - if (ctx->qos_data.qos_active) - ctx->qos_data.def_qos_parm.qos_flags |= - QOS_PARAM_FLG_UPDATE_EDCA_MSK; - - if (ctx->ht.enabled) - ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; - - IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", - ctx->qos_data.qos_active, - ctx->qos_data.def_qos_parm.qos_flags); - - iwl_send_cmd_pdu_async(priv, ctx->qos_cmd, - sizeof(struct iwl_qosparam_cmd), - &ctx->qos_data.def_qos_parm, NULL); -} - -/** - * iwl_legacy_mac_config - mac80211 config callback - */ -int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed) -{ - struct iwl_priv *priv = hw->priv; - const struct iwl_channel_info *ch_info; - struct ieee80211_conf *conf = &hw->conf; - struct ieee80211_channel *channel = conf->channel; - struct iwl_ht_config *ht_conf = &priv->current_ht_config; - struct iwl_rxon_context *ctx; - unsigned long flags = 0; - int ret = 0; - u16 ch; - int scan_active = 0; - bool ht_changed[NUM_IWL_RXON_CTX] = {}; - - if (WARN_ON(!priv->cfg->ops->legacy)) - return -EOPNOTSUPP; - - mutex_lock(&priv->mutex); - - IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", - channel->hw_value, changed); - - if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) { - scan_active = 1; - IWL_DEBUG_MAC80211(priv, "scan active\n"); - } - - if (changed & (IEEE80211_CONF_CHANGE_SMPS | - IEEE80211_CONF_CHANGE_CHANNEL)) { - /* mac80211 uses static for non-HT which is what we want */ - priv->current_ht_config.smps = conf->smps_mode; - - /* - * Recalculate chain counts. - * - * If monitor mode is enabled then mac80211 will - * set up the SM PS mode to OFF if an HT channel is - * configured. - */ - if (priv->cfg->ops->hcmd->set_rxon_chain) - for_each_context(priv, ctx) - priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - } - - /* during scanning mac80211 will delay channel setting until - * scan finish with changed = 0 - */ - if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) { - if (scan_active) - goto set_ch_out; - - ch = channel->hw_value; - ch_info = iwl_get_channel_info(priv, channel->band, ch); - if (!is_channel_valid(ch_info)) { - IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); - ret = -EINVAL; - goto set_ch_out; - } - - spin_lock_irqsave(&priv->lock, flags); - - for_each_context(priv, ctx) { - /* Configure HT40 channels */ - if (ctx->ht.enabled != conf_is_ht(conf)) { - ctx->ht.enabled = conf_is_ht(conf); - ht_changed[ctx->ctxid] = true; - } - if (ctx->ht.enabled) { - if (conf_is_ht40_minus(conf)) { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_BELOW; - ctx->ht.is_40mhz = true; - } else if (conf_is_ht40_plus(conf)) { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - ctx->ht.is_40mhz = true; - } else { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_NONE; - ctx->ht.is_40mhz = false; - } - } else - ctx->ht.is_40mhz = false; - - /* - * Default to no protection. Protection mode will - * later be set from BSS config in iwl_ht_conf - */ - ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE; - - /* if we are switching from ht to 2.4 clear flags - * from any ht related info since 2.4 does not - * support ht */ - if ((le16_to_cpu(ctx->staging.channel) != ch)) - ctx->staging.flags = 0; - - iwl_set_rxon_channel(priv, channel, ctx); - iwl_set_rxon_ht(priv, ht_conf); - - iwl_set_flags_for_band(priv, ctx, channel->band, - ctx->vif); - } - - spin_unlock_irqrestore(&priv->lock, flags); - - if (priv->cfg->ops->legacy->update_bcast_stations) - ret = priv->cfg->ops->legacy->update_bcast_stations(priv); - - set_ch_out: - /* The list of supported rates and rate mask can be different - * for each band; since the band may have changed, reset - * the rate mask to what mac80211 lists */ - iwl_set_rate(priv); - } - - if (changed & (IEEE80211_CONF_CHANGE_PS | - IEEE80211_CONF_CHANGE_IDLE)) { - ret = iwl_power_update_mode(priv, false); - if (ret) - IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n"); - } - - if (changed & IEEE80211_CONF_CHANGE_POWER) { - IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n", - priv->tx_power_user_lmt, conf->power_level); - - iwl_set_tx_power(priv, conf->power_level, false); - } - - if (!iwl_is_ready(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); - goto out; - } - - if (scan_active) - goto out; - - for_each_context(priv, ctx) { - if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging))) - iwlcore_commit_rxon(priv, ctx); - else - IWL_DEBUG_INFO(priv, - "Not re-sending same RXON configuration.\n"); - if (ht_changed[ctx->ctxid]) - iwl_update_qos(priv, ctx); - } - -out: - IWL_DEBUG_MAC80211(priv, "leave\n"); - mutex_unlock(&priv->mutex); - return ret; -} -EXPORT_SYMBOL(iwl_legacy_mac_config); - -void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw) -{ - struct iwl_priv *priv = hw->priv; - unsigned long flags; - /* IBSS can only be the IWL_RXON_CTX_BSS context */ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - if (WARN_ON(!priv->cfg->ops->legacy)) - return; - - mutex_lock(&priv->mutex); - IWL_DEBUG_MAC80211(priv, "enter\n"); - - spin_lock_irqsave(&priv->lock, flags); - memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config)); - spin_unlock_irqrestore(&priv->lock, flags); - - spin_lock_irqsave(&priv->lock, flags); - - /* new association get rid of ibss beacon skb */ - if (priv->beacon_skb) - dev_kfree_skb(priv->beacon_skb); - - priv->beacon_skb = NULL; - - priv->timestamp = 0; - - spin_unlock_irqrestore(&priv->lock, flags); - - iwl_scan_cancel_timeout(priv, 100); - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); - mutex_unlock(&priv->mutex); - return; - } - - /* we are restarting association process - * clear RXON_FILTER_ASSOC_MSK bit - */ - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv, ctx); - - iwl_set_rate(priv); - - mutex_unlock(&priv->mutex); - - IWL_DEBUG_MAC80211(priv, "leave\n"); -} -EXPORT_SYMBOL(iwl_legacy_mac_reset_tsf); - -static void iwl_ht_conf(struct iwl_priv *priv, - struct ieee80211_vif *vif) -{ - struct iwl_ht_config *ht_conf = &priv->current_ht_config; - struct ieee80211_sta *sta; - struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; - struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - - IWL_DEBUG_ASSOC(priv, "enter:\n"); - - if (!ctx->ht.enabled) - return; - - ctx->ht.protection = - bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; - ctx->ht.non_gf_sta_present = - !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); - - ht_conf->single_chain_sufficient = false; - - switch (vif->type) { - case NL80211_IFTYPE_STATION: - rcu_read_lock(); - sta = ieee80211_find_sta(vif, bss_conf->bssid); - if (sta) { - struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; - int maxstreams; - - maxstreams = (ht_cap->mcs.tx_params & - IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK) - >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; - maxstreams += 1; - - if ((ht_cap->mcs.rx_mask[1] == 0) && - (ht_cap->mcs.rx_mask[2] == 0)) - ht_conf->single_chain_sufficient = true; - if (maxstreams <= 1) - ht_conf->single_chain_sufficient = true; - } else { - /* - * If at all, this can only happen through a race - * when the AP disconnects us while we're still - * setting up the connection, in that case mac80211 - * will soon tell us about that. - */ - ht_conf->single_chain_sufficient = true; - } - rcu_read_unlock(); - break; - case NL80211_IFTYPE_ADHOC: - ht_conf->single_chain_sufficient = true; - break; - default: - break; - } - - IWL_DEBUG_ASSOC(priv, "leave\n"); -} - -static inline void iwl_set_no_assoc(struct iwl_priv *priv, - struct ieee80211_vif *vif) -{ - struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - - /* - * inform the ucode that there is no longer an - * association and that no more packets should be - * sent - */ - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - ctx->staging.assoc_id = 0; - iwlcore_commit_rxon(priv, ctx); -} - -static void iwlcore_beacon_update(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct iwl_priv *priv = hw->priv; - unsigned long flags; - __le64 timestamp; - struct sk_buff *skb = ieee80211_beacon_get(hw, vif); - - if (!skb) - return; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - lockdep_assert_held(&priv->mutex); - - if (!priv->beacon_ctx) { - IWL_ERR(priv, "update beacon but no beacon context!\n"); - dev_kfree_skb(skb); - return; - } - - spin_lock_irqsave(&priv->lock, flags); - - if (priv->beacon_skb) - dev_kfree_skb(priv->beacon_skb); - - priv->beacon_skb = skb; - - timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; - priv->timestamp = le64_to_cpu(timestamp); - - IWL_DEBUG_MAC80211(priv, "leave\n"); - spin_unlock_irqrestore(&priv->lock, flags); - - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); - return; - } - - priv->cfg->ops->legacy->post_associate(priv); -} - -void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changes) -{ - struct iwl_priv *priv = hw->priv; - struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - int ret; - - if (WARN_ON(!priv->cfg->ops->legacy)) - return; - - IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); - - if (!iwl_is_alive(priv)) - return; - - mutex_lock(&priv->mutex); - - if (changes & BSS_CHANGED_QOS) { - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - ctx->qos_data.qos_active = bss_conf->qos; - iwl_update_qos(priv, ctx); - spin_unlock_irqrestore(&priv->lock, flags); - } - - if (changes & BSS_CHANGED_BEACON_ENABLED) { - /* - * the add_interface code must make sure we only ever - * have a single interface that could be beaconing at - * any time. - */ - if (vif->bss_conf.enable_beacon) - priv->beacon_ctx = ctx; - else - priv->beacon_ctx = NULL; - } - - if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) { - dev_kfree_skb(priv->beacon_skb); - priv->beacon_skb = ieee80211_beacon_get(hw, vif); - } - - if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP) - iwl_send_rxon_timing(priv, ctx); - - if (changes & BSS_CHANGED_BSSID) { - IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid); - - /* - * If there is currently a HW scan going on in the - * background then we need to cancel it else the RXON - * below/in post_associate will fail. - */ - if (iwl_scan_cancel_timeout(priv, 100)) { - IWL_WARN(priv, "Aborted scan still in progress after 100ms\n"); - IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n"); - mutex_unlock(&priv->mutex); - return; - } - - /* mac80211 only sets assoc when in STATION mode */ - if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) { - memcpy(ctx->staging.bssid_addr, - bss_conf->bssid, ETH_ALEN); - - /* currently needed in a few places */ - memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); - } else { - ctx->staging.filter_flags &= - ~RXON_FILTER_ASSOC_MSK; - } - - } - - /* - * This needs to be after setting the BSSID in case - * mac80211 decides to do both changes at once because - * it will invoke post_associate. - */ - if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON) - iwlcore_beacon_update(hw, vif); - - if (changes & BSS_CHANGED_ERP_PREAMBLE) { - IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", - bss_conf->use_short_preamble); - if (bss_conf->use_short_preamble) - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; - else - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - } - - if (changes & BSS_CHANGED_ERP_CTS_PROT) { - IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot); - if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) - ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK; - else - ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK; - if (bss_conf->use_cts_prot) - ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; - else - ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN; - } - - if (changes & BSS_CHANGED_BASIC_RATES) { - /* XXX use this information - * - * To do that, remove code from iwl_set_rate() and put something - * like this here: - * - if (A-band) - ctx->staging.ofdm_basic_rates = - bss_conf->basic_rates; - else - ctx->staging.ofdm_basic_rates = - bss_conf->basic_rates >> 4; - ctx->staging.cck_basic_rates = - bss_conf->basic_rates & 0xF; - */ - } - - if (changes & BSS_CHANGED_HT) { - iwl_ht_conf(priv, vif); - - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - } - - if (changes & BSS_CHANGED_ASSOC) { - IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc); - if (bss_conf->assoc) { - priv->timestamp = bss_conf->timestamp; - - if (!iwl_is_rfkill(priv)) - priv->cfg->ops->legacy->post_associate(priv); - } else - iwl_set_no_assoc(priv, vif); - } - - if (changes && iwl_is_associated_ctx(ctx) && bss_conf->aid) { - IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n", - changes); - ret = iwl_send_rxon_assoc(priv, ctx); - if (!ret) { - /* Sync active_rxon with latest change. */ - memcpy((void *)&ctx->active, - &ctx->staging, - sizeof(struct iwl_rxon_cmd)); - } - } - - if (changes & BSS_CHANGED_BEACON_ENABLED) { - if (vif->bss_conf.enable_beacon) { - memcpy(ctx->staging.bssid_addr, - bss_conf->bssid, ETH_ALEN); - memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); - priv->cfg->ops->legacy->config_ap(priv); - } else - iwl_set_no_assoc(priv, vif); - } - - if (changes & BSS_CHANGED_IBSS) { - ret = priv->cfg->ops->legacy->manage_ibss_station(priv, vif, - bss_conf->ibss_joined); - if (ret) - IWL_ERR(priv, "failed to %s IBSS station %pM\n", - bss_conf->ibss_joined ? "add" : "remove", - bss_conf->bssid); - } - - mutex_unlock(&priv->mutex); - - IWL_DEBUG_MAC80211(priv, "leave\n"); -} -EXPORT_SYMBOL(iwl_legacy_mac_bss_info_changed); - -irqreturn_t iwl_isr_legacy(int irq, void *data) -{ - struct iwl_priv *priv = data; - u32 inta, inta_mask; - u32 inta_fh; - unsigned long flags; - if (!priv) - return IRQ_NONE; - - spin_lock_irqsave(&priv->lock, flags); - - /* Disable (but don't clear!) interrupts here to avoid - * back-to-back ISRs and sporadic interrupts from our NIC. - * If we have something to service, the tasklet will re-enable ints. - * If we *don't* have something, we'll re-enable before leaving here. */ - inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */ - iwl_write32(priv, CSR_INT_MASK, 0x00000000); - - /* Discover which interrupts are active/pending */ - inta = iwl_read32(priv, CSR_INT); - inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); - - /* Ignore interrupt if there's nothing in NIC to service. - * This may be due to IRQ shared with another device, - * or due to sporadic interrupts thrown from our NIC. */ - if (!inta && !inta_fh) { - IWL_DEBUG_ISR(priv, - "Ignore interrupt, inta == 0, inta_fh == 0\n"); - goto none; - } - - if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { - /* Hardware disappeared. It might have already raised - * an interrupt */ - IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta); - goto unplugged; - } - - IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", - inta, inta_mask, inta_fh); - - inta &= ~CSR_INT_BIT_SCD; - - /* iwl_irq_tasklet() will service interrupts and re-enable them */ - if (likely(inta || inta_fh)) - tasklet_schedule(&priv->irq_tasklet); - -unplugged: - spin_unlock_irqrestore(&priv->lock, flags); - return IRQ_HANDLED; - -none: - /* re-enable interrupts here since we don't have anything to service. */ - /* only Re-enable if disabled by irq */ - if (test_bit(STATUS_INT_ENABLED, &priv->status)) - iwl_enable_interrupts(priv); - spin_unlock_irqrestore(&priv->lock, flags); - return IRQ_NONE; -} -EXPORT_SYMBOL(iwl_isr_legacy); - -/* - * iwl_legacy_tx_cmd_protection: Set rts/cts. 3945 and 4965 only share this - * function. - */ -void iwl_legacy_tx_cmd_protection(struct iwl_priv *priv, - struct ieee80211_tx_info *info, - __le16 fc, __le32 *tx_flags) -{ - if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { - *tx_flags |= TX_CMD_FLG_RTS_MSK; - *tx_flags &= ~TX_CMD_FLG_CTS_MSK; - *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; - - if (!ieee80211_is_mgmt(fc)) - return; - - switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { - case cpu_to_le16(IEEE80211_STYPE_AUTH): - case cpu_to_le16(IEEE80211_STYPE_DEAUTH): - case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ): - case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ): - *tx_flags &= ~TX_CMD_FLG_RTS_MSK; - *tx_flags |= TX_CMD_FLG_CTS_MSK; - break; - } - } else if (info->control.rates[0].flags & - IEEE80211_TX_RC_USE_CTS_PROTECT) { - *tx_flags &= ~TX_CMD_FLG_RTS_MSK; - *tx_flags |= TX_CMD_FLG_CTS_MSK; - *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; - } -} -EXPORT_SYMBOL(iwl_legacy_tx_cmd_protection); diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.h b/drivers/net/wireless/iwlwifi/iwl-legacy.h deleted file mode 100644 index 9f7b2f935964..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-legacy.h +++ /dev/null @@ -1,79 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *****************************************************************************/ - -#ifndef __iwl_legacy_h__ -#define __iwl_legacy_h__ - -/* mac80211 handlers */ -int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed); -void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw); -void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changes); -void iwl_legacy_tx_cmd_protection(struct iwl_priv *priv, - struct ieee80211_tx_info *info, - __le16 fc, __le32 *tx_flags); - -irqreturn_t iwl_isr_legacy(int irq, void *data); - -#endif /* __iwl_legacy_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 1d1bf3234d8d..576795e2c75b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -425,7 +425,6 @@ int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, return ret; } -EXPORT_SYMBOL(iwl_power_set_mode); int iwl_power_update_mode(struct iwl_priv *priv, bool force) { @@ -434,7 +433,6 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) iwl_power_build_cmd(priv, &cmd); return iwl_power_set_mode(priv, &cmd, force); } -EXPORT_SYMBOL(iwl_power_update_mode); /* initialize to default */ void iwl_power_initialize(struct iwl_priv *priv) @@ -448,4 +446,3 @@ void iwl_power_initialize(struct iwl_priv *priv) memset(&priv->power_data.sleep_cmd, 0, sizeof(priv->power_data.sleep_cmd)); } -EXPORT_SYMBOL(iwl_power_initialize); diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index bc89393fb696..a21f6fe10fb7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -118,7 +118,6 @@ int iwl_rx_queue_space(const struct iwl_rx_queue *q) s = 0; return s; } -EXPORT_SYMBOL(iwl_rx_queue_space); /** * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue @@ -170,7 +169,6 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q exit_unlock: spin_unlock_irqrestore(&q->lock, flags); } -EXPORT_SYMBOL(iwl_rx_queue_update_write_ptr); int iwl_rx_queue_alloc(struct iwl_priv *priv) { @@ -211,7 +209,6 @@ err_rb: err_bd: return -ENOMEM; } -EXPORT_SYMBOL(iwl_rx_queue_alloc); void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, @@ -229,7 +226,6 @@ void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, memcpy(&priv->measure_report, report, sizeof(*report)); priv->measurement_status |= MEASUREMENT_READY; } -EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif); void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt) @@ -249,7 +245,6 @@ void iwl_recover_from_statistics(struct iwl_priv *priv, !priv->cfg->ops->lib->check_plcp_health(priv, pkt)) iwl_force_reset(priv, IWL_RF_RESET, false); } -EXPORT_SYMBOL(iwl_recover_from_statistics); /* * returns non-zero if packet should be dropped @@ -302,4 +297,3 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv, } return 0; } -EXPORT_SYMBOL(iwl_set_decrypted_flag); diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 08f1bea8b652..faa6d34cb658 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -155,7 +155,6 @@ int iwl_scan_cancel(struct iwl_priv *priv) queue_work(priv->workqueue, &priv->abort_scan); return 0; } -EXPORT_SYMBOL(iwl_scan_cancel); /** * iwl_scan_cancel_timeout - Cancel any currently executing HW scan @@ -180,7 +179,6 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) return test_bit(STATUS_SCAN_HW, &priv->status); } -EXPORT_SYMBOL(iwl_scan_cancel_timeout); /* Service response to REPLY_SCAN_CMD (0x80) */ static void iwl_rx_reply_scan(struct iwl_priv *priv, @@ -288,7 +286,6 @@ void iwl_setup_rx_scan_handlers(struct iwl_priv *priv) priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] = iwl_rx_scan_complete_notif; } -EXPORT_SYMBOL(iwl_setup_rx_scan_handlers); inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, enum ieee80211_band band, @@ -301,7 +298,6 @@ inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, return IWL_ACTIVE_DWELL_TIME_24 + IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1); } -EXPORT_SYMBOL(iwl_get_active_dwell_time); u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, enum ieee80211_band band, @@ -333,7 +329,6 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, return passive; } -EXPORT_SYMBOL(iwl_get_passive_dwell_time); void iwl_init_scan_params(struct iwl_priv *priv) { @@ -343,7 +338,6 @@ void iwl_init_scan_params(struct iwl_priv *priv) if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ]) priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = ant_idx; } -EXPORT_SYMBOL(iwl_init_scan_params); static int __must_check iwl_scan_initiate(struct iwl_priv *priv, struct ieee80211_vif *vif, @@ -439,7 +433,6 @@ out_unlock: return ret; } -EXPORT_SYMBOL(iwl_mac_hw_scan); /* * internal short scan, this function should only been called while associated. @@ -536,7 +529,6 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, return (u16)len; } -EXPORT_SYMBOL(iwl_fill_probe_req); static void iwl_bg_abort_scan(struct work_struct *work) { @@ -621,7 +613,6 @@ void iwl_setup_scan_deferred_work(struct iwl_priv *priv) INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan); INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check); } -EXPORT_SYMBOL(iwl_setup_scan_deferred_work); void iwl_cancel_scan_deferred_work(struct iwl_priv *priv) { @@ -635,4 +626,3 @@ void iwl_cancel_scan_deferred_work(struct iwl_priv *priv) mutex_unlock(&priv->mutex); } } -EXPORT_SYMBOL(iwl_cancel_scan_deferred_work); diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 49493d176515..bc90a12408a3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -169,7 +169,6 @@ int iwl_send_add_sta(struct iwl_priv *priv, return ret; } -EXPORT_SYMBOL(iwl_send_add_sta); static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, struct ieee80211_sta *sta, @@ -316,7 +315,6 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, return sta_id; } -EXPORT_SYMBOL_GPL(iwl_prep_station); #define STA_WAIT_TIMEOUT (HZ/2) @@ -379,7 +377,6 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, *sta_id_r = sta_id; return ret; } -EXPORT_SYMBOL(iwl_add_station_common); /** * iwl_sta_ucode_deactivate - deactivate ucode status for a station @@ -513,7 +510,6 @@ out_err: spin_unlock_irqrestore(&priv->sta_lock, flags); return -EINVAL; } -EXPORT_SYMBOL_GPL(iwl_remove_station); /** * iwl_clear_ucode_stations - clear ucode station table bits @@ -548,7 +544,6 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv, if (!cleared) IWL_DEBUG_INFO(priv, "No active stations found to be cleared\n"); } -EXPORT_SYMBOL(iwl_clear_ucode_stations); /** * iwl_restore_stations() - Restore driver known stations to device @@ -625,7 +620,6 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) else IWL_DEBUG_INFO(priv, "Restoring all known stations .... complete.\n"); } -EXPORT_SYMBOL(iwl_restore_stations); void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { @@ -668,7 +662,6 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) priv->stations[sta_id].sta.sta.addr, ret); iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true); } -EXPORT_SYMBOL(iwl_reprogram_ap_sta); int iwl_get_free_ucode_key_index(struct iwl_priv *priv) { @@ -680,7 +673,6 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv) return WEP_INVALID_OFFSET; } -EXPORT_SYMBOL(iwl_get_free_ucode_key_index); void iwl_dealloc_bcast_stations(struct iwl_priv *priv) { @@ -700,7 +692,6 @@ void iwl_dealloc_bcast_stations(struct iwl_priv *priv) } spin_unlock_irqrestore(&priv->sta_lock, flags); } -EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_stations); #ifdef CONFIG_IWLWIFI_DEBUG static void iwl_dump_lq_cmd(struct iwl_priv *priv, @@ -810,7 +801,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, } return ret; } -EXPORT_SYMBOL(iwl_send_lq_cmd); int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -832,4 +822,3 @@ int iwl_mac_sta_remove(struct ieee80211_hw *hw, mutex_unlock(&priv->mutex); return ret; } -EXPORT_SYMBOL(iwl_mac_sta_remove); diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 073b6ce6141c..7e607d39da1c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -84,7 +84,6 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) } txq->need_update = 0; } -EXPORT_SYMBOL(iwl_txq_update_write_ptr); /** * iwl_tx_queue_free - Deallocate DMA queue. @@ -131,7 +130,6 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) /* 0-fill queue descriptor structure */ memset(txq, 0, sizeof(*txq)); } -EXPORT_SYMBOL(iwl_tx_queue_free); /** * iwl_cmd_queue_free - Deallocate DMA queue. @@ -193,7 +191,6 @@ void iwl_cmd_queue_free(struct iwl_priv *priv) /* 0-fill queue descriptor structure */ memset(txq, 0, sizeof(*txq)); } -EXPORT_SYMBOL(iwl_cmd_queue_free); /*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** * DMA services @@ -233,7 +230,6 @@ int iwl_queue_space(const struct iwl_queue *q) s = 0; return s; } -EXPORT_SYMBOL(iwl_queue_space); /** @@ -384,7 +380,6 @@ out_free_arrays: return -ENOMEM; } -EXPORT_SYMBOL(iwl_tx_queue_init); void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, int slots_num, u32 txq_id) @@ -404,7 +399,6 @@ void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, /* Tell device where to find queue */ priv->cfg->ops->lib->txq_init(priv, txq); } -EXPORT_SYMBOL(iwl_tx_queue_reset); /*************** HOST COMMAND QUEUE FUNCTIONS *****/ @@ -641,4 +635,3 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) } meta->flags = 0; } -EXPORT_SYMBOL(iwl_tx_cmd_complete); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c deleted file mode 100644 index adcef735180a..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ /dev/null @@ -1,4334 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. - * - * Portions of this file are derived from the ipw3945 project, as well - * as portions of the ieee80211 subsystem header files. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#define DRV_NAME "iwl3945" - -#include "iwl-fh.h" -#include "iwl-3945-fh.h" -#include "iwl-commands.h" -#include "iwl-sta.h" -#include "iwl-3945.h" -#include "iwl-core.h" -#include "iwl-helpers.h" -#include "iwl-dev.h" -#include "iwl-spectrum.h" -#include "iwl-legacy.h" - -/* - * module name, copyright, version, etc. - */ - -#define DRV_DESCRIPTION \ -"Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux" - -#ifdef CONFIG_IWLWIFI_DEBUG -#define VD "d" -#else -#define VD -#endif - -/* - * add "s" to indicate spectrum measurement included. - * we add it here to be consistent with previous releases in which - * this was configurable. - */ -#define DRV_VERSION IWLWIFI_VERSION VD "s" -#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation" -#define DRV_AUTHOR "" - -MODULE_DESCRIPTION(DRV_DESCRIPTION); -MODULE_VERSION(DRV_VERSION); -MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); -MODULE_LICENSE("GPL"); - - /* module parameters */ -struct iwl_mod_params iwl3945_mod_params = { - .sw_crypto = 1, - .restart_fw = 1, - /* the rest are 0 by default */ -}; - -/** - * iwl3945_get_antenna_flags - Get antenna flags for RXON command - * @priv: eeprom and antenna fields are used to determine antenna flags - * - * priv->eeprom39 is used to determine if antenna AUX/MAIN are reversed - * iwl3945_mod_params.antenna specifies the antenna diversity mode: - * - * IWL_ANTENNA_DIVERSITY - NIC selects best antenna by itself - * IWL_ANTENNA_MAIN - Force MAIN antenna - * IWL_ANTENNA_AUX - Force AUX antenna - */ -__le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv) -{ - struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; - - switch (iwl3945_mod_params.antenna) { - case IWL_ANTENNA_DIVERSITY: - return 0; - - case IWL_ANTENNA_MAIN: - if (eeprom->antenna_switch_type) - return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK; - return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK; - - case IWL_ANTENNA_AUX: - if (eeprom->antenna_switch_type) - return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK; - return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK; - } - - /* bad antenna selector value */ - IWL_ERR(priv, "Bad antenna selector value (0x%x)\n", - iwl3945_mod_params.antenna); - - return 0; /* "diversity" is default if error */ -} - -static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - u8 sta_id) -{ - unsigned long flags; - __le16 key_flags = 0; - int ret; - - key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); - key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); - - if (sta_id == priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id) - key_flags |= STA_KEY_MULTICAST_MSK; - - keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - keyconf->hw_key_idx = keyconf->keyidx; - key_flags &= ~STA_KEY_FLG_INVALID; - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; - priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; - memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, - keyconf->keylen); - - memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, - keyconf->keylen); - - if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) - == STA_KEY_FLG_NO_ENC) - priv->stations[sta_id].sta.key.key_offset = - iwl_get_free_ucode_key_index(priv); - /* else, we are overriding an existing key => no need to allocated room - * in uCode. */ - - WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, - "no space for a new key"); - - priv->stations[sta_id].sta.key.key_flags = key_flags; - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - - IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n"); - - ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); - - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return ret; -} - -static int iwl3945_set_tkip_dynamic_key_info(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - u8 sta_id) -{ - return -EOPNOTSUPP; -} - -static int iwl3945_set_wep_dynamic_key_info(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - u8 sta_id) -{ - return -EOPNOTSUPP; -} - -static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) -{ - unsigned long flags; - struct iwl_addsta_cmd sta_cmd; - - spin_lock_irqsave(&priv->sta_lock, flags); - memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key)); - memset(&priv->stations[sta_id].sta.key, 0, - sizeof(struct iwl4965_keyinfo)); - priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->sta_lock, flags); - - IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n"); - return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); -} - -static int iwl3945_set_dynamic_key(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, u8 sta_id) -{ - int ret = 0; - - keyconf->hw_key_idx = HW_KEY_DYNAMIC; - - switch (keyconf->cipher) { - case WLAN_CIPHER_SUITE_CCMP: - ret = iwl3945_set_ccmp_dynamic_key_info(priv, keyconf, sta_id); - break; - case WLAN_CIPHER_SUITE_TKIP: - ret = iwl3945_set_tkip_dynamic_key_info(priv, keyconf, sta_id); - break; - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - ret = iwl3945_set_wep_dynamic_key_info(priv, keyconf, sta_id); - break; - default: - IWL_ERR(priv, "Unknown alg: %s alg=%x\n", __func__, - keyconf->cipher); - ret = -EINVAL; - } - - IWL_DEBUG_WEP(priv, "Set dynamic key: alg=%x len=%d idx=%d sta=%d ret=%d\n", - keyconf->cipher, keyconf->keylen, keyconf->keyidx, - sta_id, ret); - - return ret; -} - -static int iwl3945_remove_static_key(struct iwl_priv *priv) -{ - int ret = -EOPNOTSUPP; - - return ret; -} - -static int iwl3945_set_static_key(struct iwl_priv *priv, - struct ieee80211_key_conf *key) -{ - if (key->cipher == WLAN_CIPHER_SUITE_WEP40 || - key->cipher == WLAN_CIPHER_SUITE_WEP104) - return -EOPNOTSUPP; - - IWL_ERR(priv, "Static key invalid: cipher %x\n", key->cipher); - return -EINVAL; -} - -static void iwl3945_clear_free_frames(struct iwl_priv *priv) -{ - struct list_head *element; - - IWL_DEBUG_INFO(priv, "%d frames on pre-allocated heap on clear.\n", - priv->frames_count); - - while (!list_empty(&priv->free_frames)) { - element = priv->free_frames.next; - list_del(element); - kfree(list_entry(element, struct iwl3945_frame, list)); - priv->frames_count--; - } - - if (priv->frames_count) { - IWL_WARN(priv, "%d frames still in use. Did we lose one?\n", - priv->frames_count); - priv->frames_count = 0; - } -} - -static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl_priv *priv) -{ - struct iwl3945_frame *frame; - struct list_head *element; - if (list_empty(&priv->free_frames)) { - frame = kzalloc(sizeof(*frame), GFP_KERNEL); - if (!frame) { - IWL_ERR(priv, "Could not allocate frame!\n"); - return NULL; - } - - priv->frames_count++; - return frame; - } - - element = priv->free_frames.next; - list_del(element); - return list_entry(element, struct iwl3945_frame, list); -} - -static void iwl3945_free_frame(struct iwl_priv *priv, struct iwl3945_frame *frame) -{ - memset(frame, 0, sizeof(*frame)); - list_add(&frame->list, &priv->free_frames); -} - -unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, - struct ieee80211_hdr *hdr, - int left) -{ - - if (!iwl_is_associated(priv, IWL_RXON_CTX_BSS) || !priv->beacon_skb) - return 0; - - if (priv->beacon_skb->len > left) - return 0; - - memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len); - - return priv->beacon_skb->len; -} - -static int iwl3945_send_beacon_cmd(struct iwl_priv *priv) -{ - struct iwl3945_frame *frame; - unsigned int frame_size; - int rc; - u8 rate; - - frame = iwl3945_get_free_frame(priv); - - if (!frame) { - IWL_ERR(priv, "Could not obtain free frame buffer for beacon " - "command.\n"); - return -ENOMEM; - } - - rate = iwl_rate_get_lowest_plcp(priv, - &priv->contexts[IWL_RXON_CTX_BSS]); - - frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate); - - rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, - &frame->u.cmd[0]); - - iwl3945_free_frame(priv, frame); - - return rc; -} - -static void iwl3945_unset_hw_params(struct iwl_priv *priv) -{ - if (priv->_3945.shared_virt) - dma_free_coherent(&priv->pci_dev->dev, - sizeof(struct iwl3945_shared), - priv->_3945.shared_virt, - priv->_3945.shared_phys); -} - -static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, - struct ieee80211_tx_info *info, - struct iwl_device_cmd *cmd, - struct sk_buff *skb_frag, - int sta_id) -{ - struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload; - struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo; - - tx_cmd->sec_ctl = 0; - - switch (keyinfo->cipher) { - case WLAN_CIPHER_SUITE_CCMP: - tx_cmd->sec_ctl = TX_CMD_SEC_CCM; - memcpy(tx_cmd->key, keyinfo->key, keyinfo->keylen); - IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n"); - break; - - case WLAN_CIPHER_SUITE_TKIP: - break; - - case WLAN_CIPHER_SUITE_WEP104: - tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128; - /* fall through */ - case WLAN_CIPHER_SUITE_WEP40: - tx_cmd->sec_ctl |= TX_CMD_SEC_WEP | - (info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT; - - memcpy(&tx_cmd->key[3], keyinfo->key, keyinfo->keylen); - - IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption " - "with key %d\n", info->control.hw_key->hw_key_idx); - break; - - default: - IWL_ERR(priv, "Unknown encode cipher %x\n", keyinfo->cipher); - break; - } -} - -/* - * handle build REPLY_TX command notification. - */ -static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv, - struct iwl_device_cmd *cmd, - struct ieee80211_tx_info *info, - struct ieee80211_hdr *hdr, u8 std_id) -{ - struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload; - __le32 tx_flags = tx_cmd->tx_flags; - __le16 fc = hdr->frame_control; - - tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { - tx_flags |= TX_CMD_FLG_ACK_MSK; - if (ieee80211_is_mgmt(fc)) - tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; - if (ieee80211_is_probe_resp(fc) && - !(le16_to_cpu(hdr->seq_ctrl) & 0xf)) - tx_flags |= TX_CMD_FLG_TSF_MSK; - } else { - tx_flags &= (~TX_CMD_FLG_ACK_MSK); - tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; - } - - tx_cmd->sta_id = std_id; - if (ieee80211_has_morefrags(fc)) - tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; - - if (ieee80211_is_data_qos(fc)) { - u8 *qc = ieee80211_get_qos_ctl(hdr); - tx_cmd->tid_tspec = qc[0] & 0xf; - tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; - } else { - tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; - } - - priv->cfg->ops->utils->tx_cmd_protection(priv, info, fc, &tx_flags); - - tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); - if (ieee80211_is_mgmt(fc)) { - if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc)) - tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3); - else - tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2); - } else { - tx_cmd->timeout.pm_frame_timeout = 0; - } - - tx_cmd->driver_txop = 0; - tx_cmd->tx_flags = tx_flags; - tx_cmd->next_frame_len = 0; -} - -/* - * start REPLY_TX command process - */ -static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct iwl3945_tx_cmd *tx_cmd; - struct iwl_tx_queue *txq = NULL; - struct iwl_queue *q = NULL; - struct iwl_device_cmd *out_cmd; - struct iwl_cmd_meta *out_meta; - dma_addr_t phys_addr; - dma_addr_t txcmd_phys; - int txq_id = skb_get_queue_mapping(skb); - u16 len, idx, hdr_len; - u8 id; - u8 unicast; - u8 sta_id; - u8 tid = 0; - __le16 fc; - u8 wait_write_ptr = 0; - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - if (iwl_is_rfkill(priv)) { - IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n"); - goto drop_unlock; - } - - if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) { - IWL_ERR(priv, "ERROR: No TX rate available.\n"); - goto drop_unlock; - } - - unicast = !is_multicast_ether_addr(hdr->addr1); - id = 0; - - fc = hdr->frame_control; - -#ifdef CONFIG_IWLWIFI_DEBUG - if (ieee80211_is_auth(fc)) - IWL_DEBUG_TX(priv, "Sending AUTH frame\n"); - else if (ieee80211_is_assoc_req(fc)) - IWL_DEBUG_TX(priv, "Sending ASSOC frame\n"); - else if (ieee80211_is_reassoc_req(fc)) - IWL_DEBUG_TX(priv, "Sending REASSOC frame\n"); -#endif - - spin_unlock_irqrestore(&priv->lock, flags); - - hdr_len = ieee80211_hdrlen(fc); - - /* Find index into station table for destination station */ - sta_id = iwl_sta_id_or_broadcast( - priv, &priv->contexts[IWL_RXON_CTX_BSS], - info->control.sta); - if (sta_id == IWL_INVALID_STATION) { - IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", - hdr->addr1); - goto drop; - } - - IWL_DEBUG_RATE(priv, "station Id %d\n", sta_id); - - if (ieee80211_is_data_qos(fc)) { - u8 *qc = ieee80211_get_qos_ctl(hdr); - tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; - if (unlikely(tid >= MAX_TID_COUNT)) - goto drop; - } - - /* Descriptor for chosen Tx queue */ - txq = &priv->txq[txq_id]; - q = &txq->q; - - if ((iwl_queue_space(q) < q->high_mark)) - goto drop; - - spin_lock_irqsave(&priv->lock, flags); - - idx = get_cmd_index(q, q->write_ptr, 0); - - /* Set up driver data for this TFD */ - memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); - txq->txb[q->write_ptr].skb = skb; - txq->txb[q->write_ptr].ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - /* Init first empty entry in queue's array of Tx/cmd buffers */ - out_cmd = txq->cmd[idx]; - out_meta = &txq->meta[idx]; - tx_cmd = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload; - memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); - memset(tx_cmd, 0, sizeof(*tx_cmd)); - - /* - * Set up the Tx-command (not MAC!) header. - * Store the chosen Tx queue and TFD index within the sequence field; - * after Tx, uCode's Tx response will return this value so driver can - * locate the frame within the tx queue and do post-tx processing. - */ - out_cmd->hdr.cmd = REPLY_TX; - out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | - INDEX_TO_SEQ(q->write_ptr))); - - /* Copy MAC header from skb into command buffer */ - memcpy(tx_cmd->hdr, hdr, hdr_len); - - - if (info->control.hw_key) - iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, sta_id); - - /* TODO need this for burst mode later on */ - iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, sta_id); - - /* set is_hcca to 0; it probably will never be implemented */ - iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0); - - /* Total # bytes to be transmitted */ - len = (u16)skb->len; - tx_cmd->len = cpu_to_le16(len); - - iwl_dbg_log_tx_data_frame(priv, len, hdr); - iwl_update_stats(priv, true, fc, len); - tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; - tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; - - if (!ieee80211_has_morefrags(hdr->frame_control)) { - txq->need_update = 1; - } else { - wait_write_ptr = 1; - txq->need_update = 0; - } - - IWL_DEBUG_TX(priv, "sequence nr = 0X%x\n", - le16_to_cpu(out_cmd->hdr.sequence)); - IWL_DEBUG_TX(priv, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); - iwl_print_hex_dump(priv, IWL_DL_TX, tx_cmd, sizeof(*tx_cmd)); - iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, - ieee80211_hdrlen(fc)); - - /* - * Use the first empty entry in this queue's command buffer array - * to contain the Tx command and MAC header concatenated together - * (payload data will be in another buffer). - * Size of this varies, due to varying MAC header length. - * If end is not dword aligned, we'll have 2 extra bytes at the end - * of the MAC header (device reads on dword boundaries). - * We'll tell device about this padding later. - */ - len = sizeof(struct iwl3945_tx_cmd) + - sizeof(struct iwl_cmd_header) + hdr_len; - len = (len + 3) & ~3; - - /* Physical address of this Tx command's header (not MAC header!), - * within command buffer array. */ - txcmd_phys = pci_map_single(priv->pci_dev, &out_cmd->hdr, - len, PCI_DMA_TODEVICE); - /* we do not map meta data ... so we can safely access address to - * provide to unmap command*/ - dma_unmap_addr_set(out_meta, mapping, txcmd_phys); - dma_unmap_len_set(out_meta, len, len); - - /* Add buffer containing Tx command and MAC(!) header to TFD's - * first entry */ - priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, - txcmd_phys, len, 1, 0); - - - /* Set up TFD's 2nd entry to point directly to remainder of skb, - * if any (802.11 null frames have no payload). */ - len = skb->len - hdr_len; - if (len) { - phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, - len, PCI_DMA_TODEVICE); - priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, - phys_addr, len, - 0, U32_PAD(len)); - } - - - /* Tell device the write index *just past* this latest filled TFD */ - q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); - iwl_txq_update_write_ptr(priv, txq); - spin_unlock_irqrestore(&priv->lock, flags); - - if ((iwl_queue_space(q) < q->high_mark) - && priv->mac80211_registered) { - if (wait_write_ptr) { - spin_lock_irqsave(&priv->lock, flags); - txq->need_update = 1; - iwl_txq_update_write_ptr(priv, txq); - spin_unlock_irqrestore(&priv->lock, flags); - } - - iwl_stop_queue(priv, txq); - } - - return 0; - -drop_unlock: - spin_unlock_irqrestore(&priv->lock, flags); -drop: - return -1; -} - -static int iwl3945_get_measurement(struct iwl_priv *priv, - struct ieee80211_measurement_params *params, - u8 type) -{ - struct iwl_spectrum_cmd spectrum; - struct iwl_rx_packet *pkt; - struct iwl_host_cmd cmd = { - .id = REPLY_SPECTRUM_MEASUREMENT_CMD, - .data = (void *)&spectrum, - .flags = CMD_WANT_SKB, - }; - u32 add_time = le64_to_cpu(params->start_time); - int rc; - int spectrum_resp_status; - int duration = le16_to_cpu(params->duration); - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) - add_time = iwl_usecs_to_beacons(priv, - le64_to_cpu(params->start_time) - priv->_3945.last_tsf, - le16_to_cpu(ctx->timing.beacon_interval)); - - memset(&spectrum, 0, sizeof(spectrum)); - - spectrum.channel_count = cpu_to_le16(1); - spectrum.flags = - RXON_FLG_TSF2HOST_MSK | RXON_FLG_ANT_A_MSK | RXON_FLG_DIS_DIV_MSK; - spectrum.filter_flags = MEASUREMENT_FILTER_FLAG; - cmd.len = sizeof(spectrum); - spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len)); - - if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) - spectrum.start_time = - iwl_add_beacon_time(priv, - priv->_3945.last_beacon_time, add_time, - le16_to_cpu(ctx->timing.beacon_interval)); - else - spectrum.start_time = 0; - - spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT); - spectrum.channels[0].channel = params->channel; - spectrum.channels[0].type = type; - if (ctx->active.flags & RXON_FLG_BAND_24G_MSK) - spectrum.flags |= RXON_FLG_BAND_24G_MSK | - RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK; - - rc = iwl_send_cmd_sync(priv, &cmd); - if (rc) - return rc; - - pkt = (struct iwl_rx_packet *)cmd.reply_page; - if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { - IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n"); - rc = -EIO; - } - - spectrum_resp_status = le16_to_cpu(pkt->u.spectrum.status); - switch (spectrum_resp_status) { - case 0: /* Command will be handled */ - if (pkt->u.spectrum.id != 0xff) { - IWL_DEBUG_INFO(priv, "Replaced existing measurement: %d\n", - pkt->u.spectrum.id); - priv->measurement_status &= ~MEASUREMENT_READY; - } - priv->measurement_status |= MEASUREMENT_ACTIVE; - rc = 0; - break; - - case 1: /* Command will not be handled */ - rc = -EAGAIN; - break; - } - - iwl_free_pages(priv, cmd.reply_page); - - return rc; -} - -static void iwl3945_rx_reply_alive(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_alive_resp *palive; - struct delayed_work *pwork; - - palive = &pkt->u.alive_frame; - - IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision " - "0x%01X 0x%01X\n", - palive->is_valid, palive->ver_type, - palive->ver_subtype); - - if (palive->ver_subtype == INITIALIZE_SUBTYPE) { - IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); - memcpy(&priv->card_alive_init, &pkt->u.alive_frame, - sizeof(struct iwl_alive_resp)); - pwork = &priv->init_alive_start; - } else { - IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); - memcpy(&priv->card_alive, &pkt->u.alive_frame, - sizeof(struct iwl_alive_resp)); - pwork = &priv->alive_start; - iwl3945_disable_events(priv); - } - - /* We delay the ALIVE response by 5ms to - * give the HW RF Kill time to activate... */ - if (palive->is_valid == UCODE_VALID_OK) - queue_delayed_work(priv->workqueue, pwork, - msecs_to_jiffies(5)); - else - IWL_WARN(priv, "uCode did not respond OK.\n"); -} - -static void iwl3945_rx_reply_add_sta(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ -#ifdef CONFIG_IWLWIFI_DEBUG - struct iwl_rx_packet *pkt = rxb_addr(rxb); -#endif - - IWL_DEBUG_RX(priv, "Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status); -} - -static void iwl3945_bg_beacon_update(struct work_struct *work) -{ - struct iwl_priv *priv = - container_of(work, struct iwl_priv, beacon_update); - struct sk_buff *beacon; - - /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ - beacon = ieee80211_beacon_get(priv->hw, - priv->contexts[IWL_RXON_CTX_BSS].vif); - - if (!beacon) { - IWL_ERR(priv, "update beacon failed\n"); - return; - } - - mutex_lock(&priv->mutex); - /* new beacon skb is allocated every time; dispose previous.*/ - if (priv->beacon_skb) - dev_kfree_skb(priv->beacon_skb); - - priv->beacon_skb = beacon; - mutex_unlock(&priv->mutex); - - iwl3945_send_beacon_cmd(priv); -} - -static void iwl3945_rx_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status); -#ifdef CONFIG_IWLWIFI_DEBUG - u8 rate = beacon->beacon_notify_hdr.rate; - - IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d " - "tsf %d %d rate %d\n", - le32_to_cpu(beacon->beacon_notify_hdr.status) & TX_STATUS_MSK, - beacon->beacon_notify_hdr.failure_frame, - le32_to_cpu(beacon->ibss_mgr_status), - le32_to_cpu(beacon->high_tsf), - le32_to_cpu(beacon->low_tsf), rate); -#endif - - priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); - - if ((priv->iw_mode == NL80211_IFTYPE_AP) && - (!test_bit(STATUS_EXIT_PENDING, &priv->status))) - queue_work(priv->workqueue, &priv->beacon_update); -} - -/* Handle notification from uCode that card's power state is changing - * due to software, hardware, or critical temperature RFKILL */ -static void iwl3945_rx_card_state_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); - unsigned long status = priv->status; - - IWL_WARN(priv, "Card state received: HW:%s SW:%s\n", - (flags & HW_CARD_DISABLED) ? "Kill" : "On", - (flags & SW_CARD_DISABLED) ? "Kill" : "On"); - - iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, - CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); - - if (flags & HW_CARD_DISABLED) - set_bit(STATUS_RF_KILL_HW, &priv->status); - else - clear_bit(STATUS_RF_KILL_HW, &priv->status); - - - iwl_scan_cancel(priv); - - if ((test_bit(STATUS_RF_KILL_HW, &status) != - test_bit(STATUS_RF_KILL_HW, &priv->status))) - wiphy_rfkill_set_hw_state(priv->hw->wiphy, - test_bit(STATUS_RF_KILL_HW, &priv->status)); - else - wake_up_interruptible(&priv->wait_command_queue); -} - -/** - * iwl3945_setup_rx_handlers - Initialize Rx handler callbacks - * - * Setup the RX handlers for each of the reply types sent from the uCode - * to the host. - * - * This function chains into the hardware specific files for them to setup - * any hardware specific handlers as well. - */ -static void iwl3945_setup_rx_handlers(struct iwl_priv *priv) -{ - priv->rx_handlers[REPLY_ALIVE] = iwl3945_rx_reply_alive; - priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta; - priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; - priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; - priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] = - iwl_rx_spectrum_measure_notif; - priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; - priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = - iwl_rx_pm_debug_statistics_notif; - priv->rx_handlers[BEACON_NOTIFICATION] = iwl3945_rx_beacon_notif; - - /* - * The same handler is used for both the REPLY to a discrete - * statistics request from the host as well as for the periodic - * statistics notifications (after received beacons) from the uCode. - */ - priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_reply_statistics; - priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics; - - iwl_setup_rx_scan_handlers(priv); - priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif; - - /* Set up hardware specific Rx handlers */ - iwl3945_hw_rx_handler_setup(priv); -} - -/************************** RX-FUNCTIONS ****************************/ -/* - * Rx theory of operation - * - * The host allocates 32 DMA target addresses and passes the host address - * to the firmware at register IWL_RFDS_TABLE_LOWER + N * RFD_SIZE where N is - * 0 to 31 - * - * Rx Queue Indexes - * The host/firmware share two index registers for managing the Rx buffers. - * - * The READ index maps to the first position that the firmware may be writing - * to -- the driver can read up to (but not including) this position and get - * good data. - * The READ index is managed by the firmware once the card is enabled. - * - * The WRITE index maps to the last position the driver has read from -- the - * position preceding WRITE is the last slot the firmware can place a packet. - * - * The queue is empty (no good data) if WRITE = READ - 1, and is full if - * WRITE = READ. - * - * During initialization, the host sets up the READ queue position to the first - * INDEX position, and WRITE to the last (READ - 1 wrapped) - * - * When the firmware places a packet in a buffer, it will advance the READ index - * and fire the RX interrupt. The driver can then query the READ index and - * process as many packets as possible, moving the WRITE index forward as it - * resets the Rx queue buffers with new memory. - * - * The management in the driver is as follows: - * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When - * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled - * to replenish the iwl->rxq->rx_free. - * + In iwl3945_rx_replenish (scheduled) if 'processed' != 'read' then the - * iwl->rxq is replenished and the READ INDEX is updated (updating the - * 'processed' and 'read' driver indexes as well) - * + A received packet is processed and handed to the kernel network stack, - * detached from the iwl->rxq. The driver 'processed' index is updated. - * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free - * list. If there are no allocated buffers in iwl->rxq->rx_free, the READ - * INDEX is not incremented and iwl->status(RX_STALLED) is set. If there - * were enough free buffers and RX_STALLED is set it is cleared. - * - * - * Driver sequence: - * - * iwl3945_rx_replenish() Replenishes rx_free list from rx_used, and calls - * iwl3945_rx_queue_restock - * iwl3945_rx_queue_restock() Moves available buffers from rx_free into Rx - * queue, updates firmware pointers, and updates - * the WRITE index. If insufficient rx_free buffers - * are available, schedules iwl3945_rx_replenish - * - * -- enable interrupts -- - * ISR - iwl3945_rx() Detach iwl_rx_mem_buffers from pool up to the - * READ INDEX, detaching the SKB from the pool. - * Moves the packet buffer from queue to rx_used. - * Calls iwl3945_rx_queue_restock to refill any empty - * slots. - * ... - * - */ - -/** - * iwl3945_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr - */ -static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl_priv *priv, - dma_addr_t dma_addr) -{ - return cpu_to_le32((u32)dma_addr); -} - -/** - * iwl3945_rx_queue_restock - refill RX queue from pre-allocated pool - * - * If there are slots in the RX queue that need to be restocked, - * and we have free pre-allocated buffers, fill the ranks as much - * as we can, pulling from rx_free. - * - * This moves the 'write' index forward to catch up with 'processed', and - * also updates the memory address in the firmware to reference the new - * target buffer. - */ -static void iwl3945_rx_queue_restock(struct iwl_priv *priv) -{ - struct iwl_rx_queue *rxq = &priv->rxq; - struct list_head *element; - struct iwl_rx_mem_buffer *rxb; - unsigned long flags; - int write; - - spin_lock_irqsave(&rxq->lock, flags); - write = rxq->write & ~0x7; - while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) { - /* Get next free Rx buffer, remove from free list */ - element = rxq->rx_free.next; - rxb = list_entry(element, struct iwl_rx_mem_buffer, list); - list_del(element); - - /* Point to Rx buffer via next RBD in circular buffer */ - rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->page_dma); - rxq->queue[rxq->write] = rxb; - rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; - rxq->free_count--; - } - spin_unlock_irqrestore(&rxq->lock, flags); - /* If the pre-allocated buffer pool is dropping low, schedule to - * refill it */ - if (rxq->free_count <= RX_LOW_WATERMARK) - queue_work(priv->workqueue, &priv->rx_replenish); - - - /* If we've added more space for the firmware to place data, tell it. - * Increment device's write pointer in multiples of 8. */ - if ((rxq->write_actual != (rxq->write & ~0x7)) - || (abs(rxq->write - rxq->read) > 7)) { - spin_lock_irqsave(&rxq->lock, flags); - rxq->need_update = 1; - spin_unlock_irqrestore(&rxq->lock, flags); - iwl_rx_queue_update_write_ptr(priv, rxq); - } -} - -/** - * iwl3945_rx_replenish - Move all used packet from rx_used to rx_free - * - * When moving to rx_free an SKB is allocated for the slot. - * - * Also restock the Rx queue via iwl3945_rx_queue_restock. - * This is called as a scheduled work item (except for during initialization) - */ -static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority) -{ - struct iwl_rx_queue *rxq = &priv->rxq; - struct list_head *element; - struct iwl_rx_mem_buffer *rxb; - struct page *page; - unsigned long flags; - gfp_t gfp_mask = priority; - - while (1) { - spin_lock_irqsave(&rxq->lock, flags); - - if (list_empty(&rxq->rx_used)) { - spin_unlock_irqrestore(&rxq->lock, flags); - return; - } - spin_unlock_irqrestore(&rxq->lock, flags); - - if (rxq->free_count > RX_LOW_WATERMARK) - gfp_mask |= __GFP_NOWARN; - - if (priv->hw_params.rx_page_order > 0) - gfp_mask |= __GFP_COMP; - - /* Alloc a new receive buffer */ - page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order); - if (!page) { - if (net_ratelimit()) - IWL_DEBUG_INFO(priv, "Failed to allocate SKB buffer.\n"); - if ((rxq->free_count <= RX_LOW_WATERMARK) && - net_ratelimit()) - IWL_CRIT(priv, "Failed to allocate SKB buffer with %s. Only %u free buffers remaining.\n", - priority == GFP_ATOMIC ? "GFP_ATOMIC" : "GFP_KERNEL", - rxq->free_count); - /* We don't reschedule replenish work here -- we will - * call the restock method and if it still needs - * more buffers it will schedule replenish */ - break; - } - - spin_lock_irqsave(&rxq->lock, flags); - if (list_empty(&rxq->rx_used)) { - spin_unlock_irqrestore(&rxq->lock, flags); - __free_pages(page, priv->hw_params.rx_page_order); - return; - } - element = rxq->rx_used.next; - rxb = list_entry(element, struct iwl_rx_mem_buffer, list); - list_del(element); - spin_unlock_irqrestore(&rxq->lock, flags); - - rxb->page = page; - /* Get physical address of RB/SKB */ - rxb->page_dma = pci_map_page(priv->pci_dev, page, 0, - PAGE_SIZE << priv->hw_params.rx_page_order, - PCI_DMA_FROMDEVICE); - - spin_lock_irqsave(&rxq->lock, flags); - - list_add_tail(&rxb->list, &rxq->rx_free); - rxq->free_count++; - priv->alloc_rxb_page++; - - spin_unlock_irqrestore(&rxq->lock, flags); - } -} - -void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) -{ - unsigned long flags; - int i; - spin_lock_irqsave(&rxq->lock, flags); - INIT_LIST_HEAD(&rxq->rx_free); - INIT_LIST_HEAD(&rxq->rx_used); - /* Fill the rx_used queue with _all_ of the Rx buffers */ - for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { - /* In the reset function, these buffers may have been allocated - * to an SKB, so we need to unmap and free potential storage */ - if (rxq->pool[i].page != NULL) { - pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, - PAGE_SIZE << priv->hw_params.rx_page_order, - PCI_DMA_FROMDEVICE); - __iwl_free_pages(priv, rxq->pool[i].page); - rxq->pool[i].page = NULL; - } - list_add_tail(&rxq->pool[i].list, &rxq->rx_used); - } - - /* 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->write_actual = 0; - rxq->free_count = 0; - spin_unlock_irqrestore(&rxq->lock, flags); -} - -void iwl3945_rx_replenish(void *data) -{ - struct iwl_priv *priv = data; - unsigned long flags; - - iwl3945_rx_allocate(priv, GFP_KERNEL); - - spin_lock_irqsave(&priv->lock, flags); - iwl3945_rx_queue_restock(priv); - spin_unlock_irqrestore(&priv->lock, flags); -} - -static void iwl3945_rx_replenish_now(struct iwl_priv *priv) -{ - iwl3945_rx_allocate(priv, GFP_ATOMIC); - - iwl3945_rx_queue_restock(priv); -} - - -/* Assumes that the skb field of the buffers in 'pool' is kept accurate. - * If an SKB has been detached, the POOL needs to have its SKB set to NULL - * This free routine walks the list of POOL entries and if SKB is set to - * non NULL it is unmapped and freed - */ -static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) -{ - int i; - for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { - if (rxq->pool[i].page != NULL) { - pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, - PAGE_SIZE << priv->hw_params.rx_page_order, - PCI_DMA_FROMDEVICE); - __iwl_free_pages(priv, rxq->pool[i].page); - rxq->pool[i].page = NULL; - } - } - - dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, - rxq->bd_dma); - dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status), - rxq->rb_stts, rxq->rb_stts_dma); - rxq->bd = NULL; - rxq->rb_stts = NULL; -} - - -/* Convert linear signal-to-noise ratio into dB */ -static u8 ratio2dB[100] = { -/* 0 1 2 3 4 5 6 7 8 9 */ - 0, 0, 6, 10, 12, 14, 16, 17, 18, 19, /* 00 - 09 */ - 20, 21, 22, 22, 23, 23, 24, 25, 26, 26, /* 10 - 19 */ - 26, 26, 26, 27, 27, 28, 28, 28, 29, 29, /* 20 - 29 */ - 29, 30, 30, 30, 31, 31, 31, 31, 32, 32, /* 30 - 39 */ - 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, /* 40 - 49 */ - 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, /* 50 - 59 */ - 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, /* 60 - 69 */ - 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, /* 70 - 79 */ - 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, /* 80 - 89 */ - 39, 39, 39, 39, 39, 40, 40, 40, 40, 40 /* 90 - 99 */ -}; - -/* Calculates a relative dB value from a ratio of linear - * (i.e. not dB) signal levels. - * Conversion assumes that levels are voltages (20*log), not powers (10*log). */ -int iwl3945_calc_db_from_ratio(int sig_ratio) -{ - /* 1000:1 or higher just report as 60 dB */ - if (sig_ratio >= 1000) - return 60; - - /* 100:1 or higher, divide by 10 and use table, - * add 20 dB to make up for divide by 10 */ - if (sig_ratio >= 100) - return 20 + (int)ratio2dB[sig_ratio/10]; - - /* We shouldn't see this */ - if (sig_ratio < 1) - return 0; - - /* Use table for ratios 1:1 - 99:1 */ - return (int)ratio2dB[sig_ratio]; -} - -/** - * iwl3945_rx_handle - Main entry function for receiving responses from uCode - * - * Uses the priv->rx_handlers callback function array to invoke - * the appropriate handlers, including command responses, - * frame-received notifications, and other notifications. - */ -static void iwl3945_rx_handle(struct iwl_priv *priv) -{ - struct iwl_rx_mem_buffer *rxb; - struct iwl_rx_packet *pkt; - struct iwl_rx_queue *rxq = &priv->rxq; - u32 r, i; - int reclaim; - unsigned long flags; - u8 fill_rx = 0; - u32 count = 8; - int total_empty = 0; - - /* uCode's read index (stored in shared DRAM) indicates the last Rx - * buffer that the driver may process (last buffer filled by ucode). */ - r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF; - i = rxq->read; - - /* calculate total frames need to be restock after handling RX */ - total_empty = r - rxq->write_actual; - if (total_empty < 0) - total_empty += RX_QUEUE_SIZE; - - if (total_empty > (RX_QUEUE_SIZE / 2)) - fill_rx = 1; - /* Rx interrupt, but nothing sent from uCode */ - if (i == r) - IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i); - - while (i != r) { - int len; - - rxb = rxq->queue[i]; - - /* If an RXB doesn't have a Rx queue slot associated with it, - * then a bug has been introduced in the queue refilling - * routines -- catch it here */ - BUG_ON(rxb == NULL); - - rxq->queue[i] = NULL; - - pci_unmap_page(priv->pci_dev, rxb->page_dma, - PAGE_SIZE << priv->hw_params.rx_page_order, - PCI_DMA_FROMDEVICE); - pkt = rxb_addr(rxb); - - len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; - len += sizeof(u32); /* account for status word */ - trace_iwlwifi_dev_rx(priv, pkt, len); - - /* Reclaim a command buffer only if this packet is a response - * to a (driver-originated) command. - * If the packet (e.g. Rx frame) originated from uCode, - * there is no command buffer to reclaim. - * Ucode should set SEQ_RX_FRAME bit if ucode-originated, - * but apparently a few don't get set; catch them here. */ - reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) && - (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && - (pkt->hdr.cmd != REPLY_TX); - - /* Based on type of command response or notification, - * handle those that need handling via function in - * rx_handlers table. See iwl3945_setup_rx_handlers() */ - if (priv->rx_handlers[pkt->hdr.cmd]) { - IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, i, - get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); - priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; - priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); - } else { - /* No handling needed */ - IWL_DEBUG_RX(priv, - "r %d i %d No handler needed for %s, 0x%02x\n", - r, i, get_cmd_string(pkt->hdr.cmd), - pkt->hdr.cmd); - } - - /* - * XXX: After here, we should always check rxb->page - * against NULL before touching it or its virtual - * memory (pkt). Because some rx_handler might have - * already taken or freed the pages. - */ - - if (reclaim) { - /* Invoke any callbacks, transfer the buffer to caller, - * and fire off the (possibly) blocking iwl_send_cmd() - * as we reclaim the driver command queue */ - if (rxb->page) - iwl_tx_cmd_complete(priv, rxb); - else - IWL_WARN(priv, "Claim null rxb?\n"); - } - - /* Reuse the page if possible. For notification packets and - * SKBs that fail to Rx correctly, add them back into the - * rx_free list for reuse later. */ - spin_lock_irqsave(&rxq->lock, flags); - if (rxb->page != NULL) { - rxb->page_dma = pci_map_page(priv->pci_dev, rxb->page, - 0, PAGE_SIZE << priv->hw_params.rx_page_order, - PCI_DMA_FROMDEVICE); - list_add_tail(&rxb->list, &rxq->rx_free); - rxq->free_count++; - } else - list_add_tail(&rxb->list, &rxq->rx_used); - - spin_unlock_irqrestore(&rxq->lock, flags); - - i = (i + 1) & RX_QUEUE_MASK; - /* If there are a lot of unused frames, - * restock the Rx queue so ucode won't assert. */ - if (fill_rx) { - count++; - if (count >= 8) { - rxq->read = i; - iwl3945_rx_replenish_now(priv); - count = 0; - } - } - } - - /* Backtrack one entry */ - rxq->read = i; - if (fill_rx) - iwl3945_rx_replenish_now(priv); - else - iwl3945_rx_queue_restock(priv); -} - -/* call this function to flush any scheduled tasklet */ -static inline void iwl_synchronize_irq(struct iwl_priv *priv) -{ - /* wait to make sure we flush pending tasklet*/ - synchronize_irq(priv->pci_dev->irq); - tasklet_kill(&priv->irq_tasklet); -} - -static const char *desc_lookup(int i) -{ - switch (i) { - case 1: - return "FAIL"; - case 2: - return "BAD_PARAM"; - case 3: - return "BAD_CHECKSUM"; - case 4: - return "NMI_INTERRUPT"; - case 5: - return "SYSASSERT"; - case 6: - return "FATAL_ERROR"; - } - - return "UNKNOWN"; -} - -#define ERROR_START_OFFSET (1 * sizeof(u32)) -#define ERROR_ELEM_SIZE (7 * sizeof(u32)) - -void iwl3945_dump_nic_error_log(struct iwl_priv *priv) -{ - u32 i; - u32 desc, time, count, base, data1; - u32 blink1, blink2, ilink1, ilink2; - - base = le32_to_cpu(priv->card_alive.error_event_table_ptr); - - if (!iwl3945_hw_valid_rtc_data_addr(base)) { - IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base); - return; - } - - - count = iwl_read_targ_mem(priv, base); - - if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { - IWL_ERR(priv, "Start IWL Error Log Dump:\n"); - IWL_ERR(priv, "Status: 0x%08lX, count: %d\n", - priv->status, count); - } - - IWL_ERR(priv, "Desc Time asrtPC blink2 " - "ilink1 nmiPC Line\n"); - for (i = ERROR_START_OFFSET; - i < (count * ERROR_ELEM_SIZE) + ERROR_START_OFFSET; - i += ERROR_ELEM_SIZE) { - desc = iwl_read_targ_mem(priv, base + i); - time = - iwl_read_targ_mem(priv, base + i + 1 * sizeof(u32)); - blink1 = - iwl_read_targ_mem(priv, base + i + 2 * sizeof(u32)); - blink2 = - iwl_read_targ_mem(priv, base + i + 3 * sizeof(u32)); - ilink1 = - iwl_read_targ_mem(priv, base + i + 4 * sizeof(u32)); - ilink2 = - iwl_read_targ_mem(priv, base + i + 5 * sizeof(u32)); - data1 = - iwl_read_targ_mem(priv, base + i + 6 * sizeof(u32)); - - IWL_ERR(priv, - "%-13s (0x%X) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n", - desc_lookup(desc), desc, time, blink1, blink2, - ilink1, ilink2, data1); - trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, 0, - 0, blink1, blink2, ilink1, ilink2); - } -} - -#define EVENT_START_OFFSET (6 * sizeof(u32)) - -/** - * iwl3945_print_event_log - Dump error event log to syslog - * - */ -static int iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, - u32 num_events, u32 mode, - int pos, char **buf, size_t bufsz) -{ - u32 i; - u32 base; /* SRAM byte address of event log header */ - u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */ - u32 ptr; /* SRAM byte address of log data */ - u32 ev, time, data; /* event log data */ - unsigned long reg_flags; - - if (num_events == 0) - return pos; - - base = le32_to_cpu(priv->card_alive.log_event_table_ptr); - - if (mode == 0) - event_size = 2 * sizeof(u32); - else - event_size = 3 * sizeof(u32); - - ptr = base + EVENT_START_OFFSET + (start_idx * event_size); - - /* Make sure device is powered up for SRAM reads */ - spin_lock_irqsave(&priv->reg_lock, reg_flags); - iwl_grab_nic_access(priv); - - /* Set starting address; reads will auto-increment */ - _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); - rmb(); - - /* "time" is actually "data" for mode 0 (no timestamp). - * place event id # at far right for easier visual parsing. */ - for (i = 0; i < num_events; i++) { - ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); - time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); - if (mode == 0) { - /* data, ev */ - if (bufsz) { - pos += scnprintf(*buf + pos, bufsz - pos, - "0x%08x:%04u\n", - time, ev); - } else { - IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); - trace_iwlwifi_dev_ucode_event(priv, 0, - time, ev); - } - } else { - data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); - if (bufsz) { - pos += scnprintf(*buf + pos, bufsz - pos, - "%010u:0x%08x:%04u\n", - time, data, ev); - } else { - IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", - time, data, ev); - trace_iwlwifi_dev_ucode_event(priv, time, - data, ev); - } - } - } - - /* Allow device to power down */ - iwl_release_nic_access(priv); - spin_unlock_irqrestore(&priv->reg_lock, reg_flags); - return pos; -} - -/** - * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog - */ -static int iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, - u32 num_wraps, u32 next_entry, - u32 size, u32 mode, - int pos, char **buf, size_t bufsz) -{ - /* - * display the newest DEFAULT_LOG_ENTRIES entries - * i.e the entries just before the next ont that uCode would fill. - */ - if (num_wraps) { - if (next_entry < size) { - pos = iwl3945_print_event_log(priv, - capacity - (size - next_entry), - size - next_entry, mode, - pos, buf, bufsz); - pos = iwl3945_print_event_log(priv, 0, - next_entry, mode, - pos, buf, bufsz); - } else - pos = iwl3945_print_event_log(priv, next_entry - size, - size, mode, - pos, buf, bufsz); - } else { - if (next_entry < size) - pos = iwl3945_print_event_log(priv, 0, - next_entry, mode, - pos, buf, bufsz); - else - pos = iwl3945_print_event_log(priv, next_entry - size, - size, mode, - pos, buf, bufsz); - } - return pos; -} - -#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) - -int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, - char **buf, bool display) -{ - u32 base; /* SRAM byte address of event log header */ - u32 capacity; /* event log capacity in # entries */ - u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ - u32 num_wraps; /* # times uCode wrapped to top of log */ - u32 next_entry; /* index of next entry to be written by uCode */ - u32 size; /* # entries that we'll print */ - int pos = 0; - size_t bufsz = 0; - - base = le32_to_cpu(priv->card_alive.log_event_table_ptr); - if (!iwl3945_hw_valid_rtc_data_addr(base)) { - IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); - return -EINVAL; - } - - /* event log header */ - capacity = iwl_read_targ_mem(priv, base); - mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32))); - num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); - next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); - - if (capacity > priv->cfg->base_params->max_event_log_size) { - IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n", - capacity, priv->cfg->base_params->max_event_log_size); - capacity = priv->cfg->base_params->max_event_log_size; - } - - if (next_entry > priv->cfg->base_params->max_event_log_size) { - IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n", - next_entry, priv->cfg->base_params->max_event_log_size); - next_entry = priv->cfg->base_params->max_event_log_size; - } - - size = num_wraps ? capacity : next_entry; - - /* bail out if nothing in log */ - if (size == 0) { - IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); - return pos; - } - -#ifdef CONFIG_IWLWIFI_DEBUG - if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) - size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) - ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; -#else - size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) - ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; -#endif - - IWL_ERR(priv, "Start IWL Event Log Dump: display last %d count\n", - size); - -#ifdef CONFIG_IWLWIFI_DEBUG - if (display) { - if (full_log) - bufsz = capacity * 48; - else - bufsz = size * 48; - *buf = kmalloc(bufsz, GFP_KERNEL); - if (!*buf) - return -ENOMEM; - } - if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { - /* if uCode has wrapped back to top of log, - * start at the oldest entry, - * i.e the next one that uCode would fill. - */ - if (num_wraps) - pos = iwl3945_print_event_log(priv, next_entry, - capacity - next_entry, mode, - pos, buf, bufsz); - - /* (then/else) start at top of log */ - pos = iwl3945_print_event_log(priv, 0, next_entry, mode, - pos, buf, bufsz); - } else - pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps, - next_entry, size, mode, - pos, buf, bufsz); -#else - pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps, - next_entry, size, mode, - pos, buf, bufsz); -#endif - return pos; -} - -static void iwl3945_irq_tasklet(struct iwl_priv *priv) -{ - u32 inta, handled = 0; - u32 inta_fh; - unsigned long flags; -#ifdef CONFIG_IWLWIFI_DEBUG - u32 inta_mask; -#endif - - spin_lock_irqsave(&priv->lock, flags); - - /* Ack/clear/reset pending uCode interrupts. - * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, - * and will clear only when CSR_FH_INT_STATUS gets cleared. */ - inta = iwl_read32(priv, CSR_INT); - iwl_write32(priv, CSR_INT, inta); - - /* Ack/clear/reset pending flow-handler (DMA) interrupts. - * Any new interrupts that happen after this, either while we're - * in this tasklet, or later, will show up in next ISR/tasklet. */ - inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); - iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh); - -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(priv) & IWL_DL_ISR) { - /* just for debug */ - inta_mask = iwl_read32(priv, CSR_INT_MASK); - IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", - inta, inta_mask, inta_fh); - } -#endif - - spin_unlock_irqrestore(&priv->lock, flags); - - /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not - * atomic, make sure that inta covers all the interrupts that - * we've discovered, even if FH interrupt came in just after - * reading CSR_INT. */ - if (inta_fh & CSR39_FH_INT_RX_MASK) - inta |= CSR_INT_BIT_FH_RX; - if (inta_fh & CSR39_FH_INT_TX_MASK) - inta |= CSR_INT_BIT_FH_TX; - - /* Now service all interrupt bits discovered above. */ - if (inta & CSR_INT_BIT_HW_ERR) { - IWL_ERR(priv, "Hardware error detected. Restarting.\n"); - - /* Tell the device to stop sending interrupts */ - iwl_disable_interrupts(priv); - - priv->isr_stats.hw++; - iwl_irq_handle_error(priv); - - handled |= CSR_INT_BIT_HW_ERR; - - return; - } - -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) { - /* NIC fires this, but we don't use it, redundant with WAKEUP */ - if (inta & CSR_INT_BIT_SCD) { - IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " - "the frame/frames.\n"); - priv->isr_stats.sch++; - } - - /* Alive notification via Rx interrupt will do the real work */ - if (inta & CSR_INT_BIT_ALIVE) { - IWL_DEBUG_ISR(priv, "Alive interrupt\n"); - priv->isr_stats.alive++; - } - } -#endif - /* Safely ignore these bits for debug checks below */ - inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE); - - /* Error detected by uCode */ - if (inta & CSR_INT_BIT_SW_ERR) { - IWL_ERR(priv, "Microcode SW error detected. " - "Restarting 0x%X.\n", inta); - priv->isr_stats.sw++; - iwl_irq_handle_error(priv); - handled |= CSR_INT_BIT_SW_ERR; - } - - /* uCode wakes up after power-down sleep */ - if (inta & CSR_INT_BIT_WAKEUP) { - IWL_DEBUG_ISR(priv, "Wakeup interrupt\n"); - iwl_rx_queue_update_write_ptr(priv, &priv->rxq); - iwl_txq_update_write_ptr(priv, &priv->txq[0]); - iwl_txq_update_write_ptr(priv, &priv->txq[1]); - iwl_txq_update_write_ptr(priv, &priv->txq[2]); - iwl_txq_update_write_ptr(priv, &priv->txq[3]); - iwl_txq_update_write_ptr(priv, &priv->txq[4]); - iwl_txq_update_write_ptr(priv, &priv->txq[5]); - - priv->isr_stats.wakeup++; - handled |= CSR_INT_BIT_WAKEUP; - } - - /* All uCode command responses, including Tx command responses, - * Rx "responses" (frame-received notification), and other - * notifications from uCode come through here*/ - if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { - iwl3945_rx_handle(priv); - priv->isr_stats.rx++; - handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); - } - - if (inta & CSR_INT_BIT_FH_TX) { - IWL_DEBUG_ISR(priv, "Tx interrupt\n"); - priv->isr_stats.tx++; - - iwl_write32(priv, CSR_FH_INT_STATUS, (1 << 6)); - iwl_write_direct32(priv, FH39_TCSR_CREDIT - (FH39_SRVC_CHNL), 0x0); - handled |= CSR_INT_BIT_FH_TX; - } - - if (inta & ~handled) { - IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); - priv->isr_stats.unhandled++; - } - - if (inta & ~priv->inta_mask) { - IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", - inta & ~priv->inta_mask); - IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh); - } - - /* Re-enable all interrupts */ - /* only Re-enable if disabled by irq */ - if (test_bit(STATUS_INT_ENABLED, &priv->status)) - iwl_enable_interrupts(priv); - -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) { - inta = iwl_read32(priv, CSR_INT); - inta_mask = iwl_read32(priv, CSR_INT_MASK); - inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); - IWL_DEBUG_ISR(priv, "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, " - "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); - } -#endif -} - -static int iwl3945_get_single_channel_for_scan(struct iwl_priv *priv, - struct ieee80211_vif *vif, - enum ieee80211_band band, - struct iwl3945_scan_channel *scan_ch) -{ - const struct ieee80211_supported_band *sband; - u16 passive_dwell = 0; - u16 active_dwell = 0; - int added = 0; - u8 channel = 0; - - sband = iwl_get_hw_mode(priv, band); - if (!sband) { - IWL_ERR(priv, "invalid band\n"); - return added; - } - - active_dwell = iwl_get_active_dwell_time(priv, band, 0); - passive_dwell = iwl_get_passive_dwell_time(priv, band, vif); - - if (passive_dwell <= active_dwell) - passive_dwell = active_dwell + 1; - - - channel = iwl_get_single_channel_number(priv, band); - - if (channel) { - scan_ch->channel = channel; - scan_ch->type = 0; /* passive */ - scan_ch->active_dwell = cpu_to_le16(active_dwell); - scan_ch->passive_dwell = cpu_to_le16(passive_dwell); - /* Set txpower levels to defaults */ - scan_ch->tpc.dsp_atten = 110; - if (band == IEEE80211_BAND_5GHZ) - scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; - else - scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); - added++; - } else - IWL_ERR(priv, "no valid channel found\n"); - return added; -} - -static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, - enum ieee80211_band band, - u8 is_active, u8 n_probes, - struct iwl3945_scan_channel *scan_ch, - struct ieee80211_vif *vif) -{ - struct ieee80211_channel *chan; - const struct ieee80211_supported_band *sband; - const struct iwl_channel_info *ch_info; - u16 passive_dwell = 0; - u16 active_dwell = 0; - int added, i; - - sband = iwl_get_hw_mode(priv, band); - if (!sband) - return 0; - - active_dwell = iwl_get_active_dwell_time(priv, band, n_probes); - passive_dwell = iwl_get_passive_dwell_time(priv, band, vif); - - if (passive_dwell <= active_dwell) - passive_dwell = active_dwell + 1; - - for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) { - chan = priv->scan_request->channels[i]; - - if (chan->band != band) - continue; - - scan_ch->channel = chan->hw_value; - - ch_info = iwl_get_channel_info(priv, band, scan_ch->channel); - if (!is_channel_valid(ch_info)) { - IWL_DEBUG_SCAN(priv, "Channel %d is INVALID for this band.\n", - scan_ch->channel); - continue; - } - - scan_ch->active_dwell = cpu_to_le16(active_dwell); - scan_ch->passive_dwell = cpu_to_le16(passive_dwell); - /* If passive , set up for auto-switch - * and use long active_dwell time. - */ - if (!is_active || is_channel_passive(ch_info) || - (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) { - scan_ch->type = 0; /* passive */ - if (IWL_UCODE_API(priv->ucode_ver) == 1) - scan_ch->active_dwell = cpu_to_le16(passive_dwell - 1); - } else { - scan_ch->type = 1; /* active */ - } - - /* Set direct probe bits. These may be used both for active - * scan channels (probes gets sent right away), - * or for passive channels (probes get se sent only after - * hearing clear Rx packet).*/ - if (IWL_UCODE_API(priv->ucode_ver) >= 2) { - if (n_probes) - scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes); - } else { - /* uCode v1 does not allow setting direct probe bits on - * passive channel. */ - if ((scan_ch->type & 1) && n_probes) - scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes); - } - - /* Set txpower levels to defaults */ - scan_ch->tpc.dsp_atten = 110; - /* scan_pwr_info->tpc.dsp_atten; */ - - /*scan_pwr_info->tpc.tx_gain; */ - if (band == IEEE80211_BAND_5GHZ) - scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; - else { - scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); - /* NOTE: if we were doing 6Mb OFDM for scans we'd use - * power level: - * scan_ch->tpc.tx_gain = ((1 << 5) | (2 << 3)) | 3; - */ - } - - IWL_DEBUG_SCAN(priv, "Scanning %d [%s %d]\n", - scan_ch->channel, - (scan_ch->type & 1) ? "ACTIVE" : "PASSIVE", - (scan_ch->type & 1) ? - active_dwell : passive_dwell); - - scan_ch++; - added++; - } - - IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added); - return added; -} - -static void iwl3945_init_hw_rates(struct iwl_priv *priv, - struct ieee80211_rate *rates) -{ - int i; - - for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) { - rates[i].bitrate = iwl3945_rates[i].ieee * 5; - rates[i].hw_value = i; /* Rate scaling will work on indexes */ - rates[i].hw_value_short = i; - rates[i].flags = 0; - if ((i > IWL39_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) { - /* - * If CCK != 1M then set short preamble rate flag. - */ - rates[i].flags |= (iwl3945_rates[i].plcp == 10) ? - 0 : IEEE80211_RATE_SHORT_PREAMBLE; - } - } -} - -/****************************************************************************** - * - * uCode download functions - * - ******************************************************************************/ - -static void iwl3945_dealloc_ucode_pci(struct iwl_priv *priv) -{ - iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code); - iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data); - iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data_backup); - iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init); - iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init_data); - iwl_free_fw_desc(priv->pci_dev, &priv->ucode_boot); -} - -/** - * iwl3945_verify_inst_full - verify runtime uCode image in card vs. host, - * looking at all data. - */ -static int iwl3945_verify_inst_full(struct iwl_priv *priv, __le32 *image, u32 len) -{ - u32 val; - u32 save_len = len; - int rc = 0; - u32 errcnt; - - IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); - - iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, - IWL39_RTC_INST_LOWER_BOUND); - - errcnt = 0; - for (; len > 0; len -= sizeof(u32), image++) { - /* read data comes through single port, auto-incr addr */ - /* NOTE: Use the debugless read so we don't flood kernel log - * if IWL_DL_IO is set */ - val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); - if (val != le32_to_cpu(*image)) { - IWL_ERR(priv, "uCode INST section is invalid at " - "offset 0x%x, is 0x%x, s/b 0x%x\n", - save_len - len, val, le32_to_cpu(*image)); - rc = -EIO; - errcnt++; - if (errcnt >= 20) - break; - } - } - - - if (!errcnt) - IWL_DEBUG_INFO(priv, - "ucode image in INSTRUCTION memory is good\n"); - - return rc; -} - - -/** - * iwl3945_verify_inst_sparse - verify runtime uCode image in card vs. host, - * using sample data 100 bytes apart. If these sample points are good, - * it's a pretty good bet that everything between them is good, too. - */ -static int iwl3945_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) -{ - u32 val; - int rc = 0; - u32 errcnt = 0; - u32 i; - - IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); - - for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { - /* read data comes through single port, auto-incr addr */ - /* NOTE: Use the debugless read so we don't flood kernel log - * if IWL_DL_IO is set */ - iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, - i + IWL39_RTC_INST_LOWER_BOUND); - val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); - if (val != le32_to_cpu(*image)) { -#if 0 /* Enable this if you want to see details */ - IWL_ERR(priv, "uCode INST section is invalid at " - "offset 0x%x, is 0x%x, s/b 0x%x\n", - i, val, *image); -#endif - rc = -EIO; - errcnt++; - if (errcnt >= 3) - break; - } - } - - return rc; -} - - -/** - * iwl3945_verify_ucode - determine which instruction image is in SRAM, - * and verify its contents - */ -static int iwl3945_verify_ucode(struct iwl_priv *priv) -{ - __le32 *image; - u32 len; - int rc = 0; - - /* Try bootstrap */ - image = (__le32 *)priv->ucode_boot.v_addr; - len = priv->ucode_boot.len; - rc = iwl3945_verify_inst_sparse(priv, image, len); - if (rc == 0) { - IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n"); - return 0; - } - - /* Try initialize */ - image = (__le32 *)priv->ucode_init.v_addr; - len = priv->ucode_init.len; - rc = iwl3945_verify_inst_sparse(priv, image, len); - if (rc == 0) { - IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n"); - return 0; - } - - /* Try runtime/protocol */ - image = (__le32 *)priv->ucode_code.v_addr; - len = priv->ucode_code.len; - rc = iwl3945_verify_inst_sparse(priv, image, len); - if (rc == 0) { - IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n"); - return 0; - } - - IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n"); - - /* Since nothing seems to match, show first several data entries in - * instruction SRAM, so maybe visual inspection will give a clue. - * Selection of bootstrap image (vs. other images) is arbitrary. */ - image = (__le32 *)priv->ucode_boot.v_addr; - len = priv->ucode_boot.len; - rc = iwl3945_verify_inst_full(priv, image, len); - - return rc; -} - -static void iwl3945_nic_start(struct iwl_priv *priv) -{ - /* Remove all resets to allow NIC to operate */ - iwl_write32(priv, CSR_RESET, 0); -} - -#define IWL3945_UCODE_GET(item) \ -static u32 iwl3945_ucode_get_##item(const struct iwl_ucode_header *ucode)\ -{ \ - return le32_to_cpu(ucode->u.v1.item); \ -} - -static u32 iwl3945_ucode_get_header_size(u32 api_ver) -{ - return 24; -} - -static u8 *iwl3945_ucode_get_data(const struct iwl_ucode_header *ucode) -{ - return (u8 *) ucode->u.v1.data; -} - -IWL3945_UCODE_GET(inst_size); -IWL3945_UCODE_GET(data_size); -IWL3945_UCODE_GET(init_size); -IWL3945_UCODE_GET(init_data_size); -IWL3945_UCODE_GET(boot_size); - -/** - * iwl3945_read_ucode - Read uCode images from disk file. - * - * Copy into buffers for card to fetch via bus-mastering - */ -static int iwl3945_read_ucode(struct iwl_priv *priv) -{ - const struct iwl_ucode_header *ucode; - int ret = -EINVAL, index; - const struct firmware *ucode_raw; - /* firmware file name contains uCode/driver compatibility version */ - const char *name_pre = priv->cfg->fw_name_pre; - const unsigned int api_max = priv->cfg->ucode_api_max; - const unsigned int api_min = priv->cfg->ucode_api_min; - char buf[25]; - u8 *src; - size_t len; - u32 api_ver, inst_size, data_size, init_size, init_data_size, boot_size; - - /* Ask kernel firmware_class module to get the boot firmware off disk. - * request_firmware() is synchronous, file is in memory on return. */ - for (index = api_max; index >= api_min; index--) { - sprintf(buf, "%s%u%s", name_pre, index, ".ucode"); - ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev); - if (ret < 0) { - IWL_ERR(priv, "%s firmware file req failed: %d\n", - buf, ret); - if (ret == -ENOENT) - continue; - else - goto error; - } else { - if (index < api_max) - IWL_ERR(priv, "Loaded firmware %s, " - "which is deprecated. " - " Please use API v%u instead.\n", - buf, api_max); - IWL_DEBUG_INFO(priv, "Got firmware '%s' file " - "(%zd bytes) from disk\n", - buf, ucode_raw->size); - break; - } - } - - if (ret < 0) - goto error; - - /* Make sure that we got at least our header! */ - if (ucode_raw->size < iwl3945_ucode_get_header_size(1)) { - IWL_ERR(priv, "File size way too small!\n"); - ret = -EINVAL; - goto err_release; - } - - /* Data from ucode file: header followed by uCode images */ - ucode = (struct iwl_ucode_header *)ucode_raw->data; - - priv->ucode_ver = le32_to_cpu(ucode->ver); - api_ver = IWL_UCODE_API(priv->ucode_ver); - inst_size = iwl3945_ucode_get_inst_size(ucode); - data_size = iwl3945_ucode_get_data_size(ucode); - init_size = iwl3945_ucode_get_init_size(ucode); - init_data_size = iwl3945_ucode_get_init_data_size(ucode); - boot_size = iwl3945_ucode_get_boot_size(ucode); - src = iwl3945_ucode_get_data(ucode); - - /* api_ver should match the api version forming part of the - * firmware filename ... but we don't check for that and only rely - * on the API version read from firmware header from here on forward */ - - if (api_ver < api_min || api_ver > api_max) { - IWL_ERR(priv, "Driver unable to support your firmware API. " - "Driver supports v%u, firmware is v%u.\n", - api_max, api_ver); - priv->ucode_ver = 0; - ret = -EINVAL; - goto err_release; - } - if (api_ver != api_max) - IWL_ERR(priv, "Firmware has old API version. Expected %u, " - "got %u. New firmware can be obtained " - "from http://www.intellinuxwireless.org.\n", - api_max, api_ver); - - IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u\n", - IWL_UCODE_MAJOR(priv->ucode_ver), - IWL_UCODE_MINOR(priv->ucode_ver), - IWL_UCODE_API(priv->ucode_ver), - IWL_UCODE_SERIAL(priv->ucode_ver)); - - snprintf(priv->hw->wiphy->fw_version, - sizeof(priv->hw->wiphy->fw_version), - "%u.%u.%u.%u", - IWL_UCODE_MAJOR(priv->ucode_ver), - IWL_UCODE_MINOR(priv->ucode_ver), - IWL_UCODE_API(priv->ucode_ver), - IWL_UCODE_SERIAL(priv->ucode_ver)); - - IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n", - priv->ucode_ver); - IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n", - inst_size); - IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %u\n", - data_size); - IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %u\n", - init_size); - IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %u\n", - init_data_size); - IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n", - boot_size); - - - /* Verify size of file vs. image size info in file's header */ - if (ucode_raw->size != iwl3945_ucode_get_header_size(api_ver) + - inst_size + data_size + init_size + - init_data_size + boot_size) { - - IWL_DEBUG_INFO(priv, - "uCode file size %zd does not match expected size\n", - ucode_raw->size); - ret = -EINVAL; - goto err_release; - } - - /* Verify that uCode images will fit in card's SRAM */ - if (inst_size > IWL39_MAX_INST_SIZE) { - IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n", - inst_size); - ret = -EINVAL; - goto err_release; - } - - if (data_size > IWL39_MAX_DATA_SIZE) { - IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n", - data_size); - ret = -EINVAL; - goto err_release; - } - if (init_size > IWL39_MAX_INST_SIZE) { - IWL_DEBUG_INFO(priv, - "uCode init instr len %d too large to fit in\n", - init_size); - ret = -EINVAL; - goto err_release; - } - if (init_data_size > IWL39_MAX_DATA_SIZE) { - IWL_DEBUG_INFO(priv, - "uCode init data len %d too large to fit in\n", - init_data_size); - ret = -EINVAL; - goto err_release; - } - if (boot_size > IWL39_MAX_BSM_SIZE) { - IWL_DEBUG_INFO(priv, - "uCode boot instr len %d too large to fit in\n", - boot_size); - ret = -EINVAL; - goto err_release; - } - - /* Allocate ucode buffers for card's bus-master loading ... */ - - /* Runtime instructions and 2 copies of data: - * 1) unmodified from disk - * 2) backup cache for save/restore during power-downs */ - priv->ucode_code.len = inst_size; - iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_code); - - priv->ucode_data.len = data_size; - iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data); - - priv->ucode_data_backup.len = data_size; - iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup); - - if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr || - !priv->ucode_data_backup.v_addr) - goto err_pci_alloc; - - /* Initialization instructions and data */ - if (init_size && init_data_size) { - priv->ucode_init.len = init_size; - iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init); - - priv->ucode_init_data.len = init_data_size; - iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data); - - if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr) - goto err_pci_alloc; - } - - /* Bootstrap (instructions only, no data) */ - if (boot_size) { - priv->ucode_boot.len = boot_size; - iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot); - - if (!priv->ucode_boot.v_addr) - goto err_pci_alloc; - } - - /* Copy images into buffers for card's bus-master reads ... */ - - /* Runtime instructions (first block of data in file) */ - len = inst_size; - IWL_DEBUG_INFO(priv, - "Copying (but not loading) uCode instr len %zd\n", len); - memcpy(priv->ucode_code.v_addr, src, len); - src += len; - - IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n", - priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr); - - /* Runtime data (2nd block) - * NOTE: Copy into backup buffer will be done in iwl3945_up() */ - len = data_size; - IWL_DEBUG_INFO(priv, - "Copying (but not loading) uCode data len %zd\n", len); - memcpy(priv->ucode_data.v_addr, src, len); - memcpy(priv->ucode_data_backup.v_addr, src, len); - src += len; - - /* Initialization instructions (3rd block) */ - if (init_size) { - len = init_size; - IWL_DEBUG_INFO(priv, - "Copying (but not loading) init instr len %zd\n", len); - memcpy(priv->ucode_init.v_addr, src, len); - src += len; - } - - /* Initialization data (4th block) */ - if (init_data_size) { - len = init_data_size; - IWL_DEBUG_INFO(priv, - "Copying (but not loading) init data len %zd\n", len); - memcpy(priv->ucode_init_data.v_addr, src, len); - src += len; - } - - /* Bootstrap instructions (5th block) */ - len = boot_size; - IWL_DEBUG_INFO(priv, - "Copying (but not loading) boot instr len %zd\n", len); - memcpy(priv->ucode_boot.v_addr, src, len); - - /* We have our copies now, allow OS release its copies */ - release_firmware(ucode_raw); - return 0; - - err_pci_alloc: - IWL_ERR(priv, "failed to allocate pci memory\n"); - ret = -ENOMEM; - iwl3945_dealloc_ucode_pci(priv); - - err_release: - release_firmware(ucode_raw); - - error: - return ret; -} - - -/** - * iwl3945_set_ucode_ptrs - Set uCode address location - * - * Tell initialization uCode where to find runtime uCode. - * - * BSM registers initially contain pointers to initialization uCode. - * We need to replace them to load runtime uCode inst and data, - * and to save runtime data when powering down. - */ -static int iwl3945_set_ucode_ptrs(struct iwl_priv *priv) -{ - dma_addr_t pinst; - dma_addr_t pdata; - - /* bits 31:0 for 3945 */ - pinst = priv->ucode_code.p_addr; - pdata = priv->ucode_data_backup.p_addr; - - /* Tell bootstrap uCode where to find image to load */ - iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); - iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); - iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, - priv->ucode_data.len); - - /* Inst byte count must be last to set up, bit 31 signals uCode - * that all new ptr/size info is in place */ - iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, - priv->ucode_code.len | BSM_DRAM_INST_LOAD); - - IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n"); - - return 0; -} - -/** - * iwl3945_init_alive_start - Called after REPLY_ALIVE notification received - * - * Called after REPLY_ALIVE notification received from "initialize" uCode. - * - * Tell "initialize" uCode to go ahead and load the runtime uCode. - */ -static void iwl3945_init_alive_start(struct iwl_priv *priv) -{ - /* Check alive response for "valid" sign from uCode */ - if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { - /* We had an error bringing up the hardware, so take it - * all the way back down so we can try again */ - IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n"); - goto restart; - } - - /* Bootstrap uCode has loaded initialize uCode ... verify inst image. - * This is a paranoid check, because we would not have gotten the - * "initialize" alive if code weren't properly loaded. */ - if (iwl3945_verify_ucode(priv)) { - /* Runtime instruction load was bad; - * take it all the way back down so we can try again */ - IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n"); - goto restart; - } - - /* Send pointers to protocol/runtime uCode image ... init code will - * load and launch runtime uCode, which will send us another "Alive" - * notification. */ - IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); - if (iwl3945_set_ucode_ptrs(priv)) { - /* Runtime instruction load won't happen; - * take it all the way back down so we can try again */ - IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n"); - goto restart; - } - return; - - restart: - queue_work(priv->workqueue, &priv->restart); -} - -/** - * iwl3945_alive_start - called after REPLY_ALIVE notification received - * from protocol/runtime uCode (initialization uCode's - * Alive gets handled by iwl3945_init_alive_start()). - */ -static void iwl3945_alive_start(struct iwl_priv *priv) -{ - int thermal_spin = 0; - u32 rfkill; - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); - - if (priv->card_alive.is_valid != UCODE_VALID_OK) { - /* We had an error bringing up the hardware, so take it - * all the way back down so we can try again */ - IWL_DEBUG_INFO(priv, "Alive failed.\n"); - goto restart; - } - - /* Initialize uCode has loaded Runtime uCode ... verify inst image. - * This is a paranoid check, because we would not have gotten the - * "runtime" alive if code weren't properly loaded. */ - if (iwl3945_verify_ucode(priv)) { - /* Runtime instruction load was bad; - * take it all the way back down so we can try again */ - IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n"); - goto restart; - } - - rfkill = iwl_read_prph(priv, APMG_RFKILL_REG); - IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill); - - if (rfkill & 0x1) { - clear_bit(STATUS_RF_KILL_HW, &priv->status); - /* if RFKILL is not on, then wait for thermal - * sensor in adapter to kick in */ - while (iwl3945_hw_get_temperature(priv) == 0) { - thermal_spin++; - udelay(10); - } - - if (thermal_spin) - IWL_DEBUG_INFO(priv, "Thermal calibration took %dus\n", - thermal_spin * 10); - } else - set_bit(STATUS_RF_KILL_HW, &priv->status); - - /* After the ALIVE response, we can send commands to 3945 uCode */ - set_bit(STATUS_ALIVE, &priv->status); - - /* Enable watchdog to monitor the driver tx queues */ - iwl_setup_watchdog(priv); - - if (iwl_is_rfkill(priv)) - return; - - ieee80211_wake_queues(priv->hw); - - priv->active_rate = IWL_RATES_MASK_3945; - - iwl_power_update_mode(priv, true); - - if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { - struct iwl3945_rxon_cmd *active_rxon = - (struct iwl3945_rxon_cmd *)(&ctx->active); - - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - } else { - /* Initialize our rx_config data */ - iwl_connection_init_rx_config(priv, ctx); - } - - /* Configure Bluetooth device coexistence support */ - priv->cfg->ops->hcmd->send_bt_config(priv); - - set_bit(STATUS_READY, &priv->status); - - /* Configure the adapter for unassociated operation */ - iwl3945_commit_rxon(priv, ctx); - - iwl3945_reg_txpower_periodic(priv); - - IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); - wake_up_interruptible(&priv->wait_command_queue); - - return; - - restart: - queue_work(priv->workqueue, &priv->restart); -} - -static void iwl3945_cancel_deferred_work(struct iwl_priv *priv); - -static void __iwl3945_down(struct iwl_priv *priv) -{ - unsigned long flags; - int exit_pending; - - IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); - - iwl_scan_cancel_timeout(priv, 200); - - exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); - - /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set - * to prevent rearm timer */ - del_timer_sync(&priv->watchdog); - - /* Station information will now be cleared in device */ - iwl_clear_ucode_stations(priv, NULL); - iwl_dealloc_bcast_stations(priv); - iwl_clear_driver_stations(priv); - - /* Unblock any waiting calls */ - wake_up_interruptible_all(&priv->wait_command_queue); - - /* Wipe out the EXIT_PENDING status bit if we are not actually - * exiting the module */ - if (!exit_pending) - clear_bit(STATUS_EXIT_PENDING, &priv->status); - - /* stop and reset the on-board processor */ - iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); - - /* tell the device to stop sending interrupts */ - spin_lock_irqsave(&priv->lock, flags); - iwl_disable_interrupts(priv); - spin_unlock_irqrestore(&priv->lock, flags); - iwl_synchronize_irq(priv); - - if (priv->mac80211_registered) - ieee80211_stop_queues(priv->hw); - - /* If we have not previously called iwl3945_init() then - * clear all bits but the RF Kill bits and return */ - if (!iwl_is_init(priv)) { - priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << - STATUS_RF_KILL_HW | - test_bit(STATUS_GEO_CONFIGURED, &priv->status) << - STATUS_GEO_CONFIGURED | - test_bit(STATUS_EXIT_PENDING, &priv->status) << - STATUS_EXIT_PENDING; - goto exit; - } - - /* ...otherwise clear out all the status bits but the RF Kill - * bit and continue taking the NIC down. */ - priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << - STATUS_RF_KILL_HW | - test_bit(STATUS_GEO_CONFIGURED, &priv->status) << - STATUS_GEO_CONFIGURED | - test_bit(STATUS_FW_ERROR, &priv->status) << - STATUS_FW_ERROR | - test_bit(STATUS_EXIT_PENDING, &priv->status) << - STATUS_EXIT_PENDING; - - iwl3945_hw_txq_ctx_stop(priv); - iwl3945_hw_rxq_stop(priv); - - /* Power-down device's busmaster DMA clocks */ - iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); - udelay(5); - - /* Stop the device, and put it in low power state */ - iwl_apm_stop(priv); - - exit: - memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); - - if (priv->beacon_skb) - dev_kfree_skb(priv->beacon_skb); - priv->beacon_skb = NULL; - - /* clear out any free frames */ - iwl3945_clear_free_frames(priv); -} - -static void iwl3945_down(struct iwl_priv *priv) -{ - mutex_lock(&priv->mutex); - __iwl3945_down(priv); - mutex_unlock(&priv->mutex); - - iwl3945_cancel_deferred_work(priv); -} - -#define MAX_HW_RESTARTS 5 - -static int iwl3945_alloc_bcast_station(struct iwl_priv *priv) -{ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - unsigned long flags; - u8 sta_id; - - spin_lock_irqsave(&priv->sta_lock, flags); - sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL); - if (sta_id == IWL_INVALID_STATION) { - IWL_ERR(priv, "Unable to prepare broadcast station\n"); - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return -EINVAL; - } - - priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; - priv->stations[sta_id].used |= IWL_STA_BCAST; - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return 0; -} - -static int __iwl3945_up(struct iwl_priv *priv) -{ - int rc, i; - - rc = iwl3945_alloc_bcast_station(priv); - if (rc) - return rc; - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { - IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); - return -EIO; - } - - if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { - IWL_ERR(priv, "ucode not available for device bring up\n"); - return -EIO; - } - - /* If platform's RF_KILL switch is NOT set to KILL */ - if (iwl_read32(priv, CSR_GP_CNTRL) & - CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) - clear_bit(STATUS_RF_KILL_HW, &priv->status); - else { - set_bit(STATUS_RF_KILL_HW, &priv->status); - IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n"); - return -ENODEV; - } - - iwl_write32(priv, CSR_INT, 0xFFFFFFFF); - - rc = iwl3945_hw_nic_init(priv); - if (rc) { - IWL_ERR(priv, "Unable to int nic\n"); - return rc; - } - - /* make sure rfkill handshake bits are cleared */ - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, - CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); - - /* clear (again), then enable host interrupts */ - iwl_write32(priv, CSR_INT, 0xFFFFFFFF); - iwl_enable_interrupts(priv); - - /* really make sure rfkill handshake bits are cleared */ - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - - /* Copy original ucode data image from disk into backup cache. - * This will be used to initialize the on-board processor's - * data SRAM for a clean start when the runtime program first loads. */ - memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr, - priv->ucode_data.len); - - /* We return success when we resume from suspend and rf_kill is on. */ - if (test_bit(STATUS_RF_KILL_HW, &priv->status)) - return 0; - - for (i = 0; i < MAX_HW_RESTARTS; i++) { - - /* load bootstrap state machine, - * load bootstrap program into processor's memory, - * prepare to load the "initialize" uCode */ - rc = priv->cfg->ops->lib->load_ucode(priv); - - if (rc) { - IWL_ERR(priv, - "Unable to set up bootstrap uCode: %d\n", rc); - continue; - } - - /* start card; "initialize" will load runtime ucode */ - iwl3945_nic_start(priv); - - IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n"); - - return 0; - } - - set_bit(STATUS_EXIT_PENDING, &priv->status); - __iwl3945_down(priv); - clear_bit(STATUS_EXIT_PENDING, &priv->status); - - /* tried to restart and config the device for as long as our - * patience could withstand */ - IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i); - return -EIO; -} - - -/***************************************************************************** - * - * Workqueue callbacks - * - *****************************************************************************/ - -static void iwl3945_bg_init_alive_start(struct work_struct *data) -{ - struct iwl_priv *priv = - container_of(data, struct iwl_priv, init_alive_start.work); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - mutex_lock(&priv->mutex); - iwl3945_init_alive_start(priv); - mutex_unlock(&priv->mutex); -} - -static void iwl3945_bg_alive_start(struct work_struct *data) -{ - struct iwl_priv *priv = - container_of(data, struct iwl_priv, alive_start.work); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - mutex_lock(&priv->mutex); - iwl3945_alive_start(priv); - mutex_unlock(&priv->mutex); -} - -/* - * 3945 cannot interrupt driver when hardware rf kill switch toggles; - * driver must poll CSR_GP_CNTRL_REG register for change. This register - * *is* readable even when device has been SW_RESET into low power mode - * (e.g. during RF KILL). - */ -static void iwl3945_rfkill_poll(struct work_struct *data) -{ - struct iwl_priv *priv = - container_of(data, struct iwl_priv, _3945.rfkill_poll.work); - bool old_rfkill = test_bit(STATUS_RF_KILL_HW, &priv->status); - bool new_rfkill = !(iwl_read32(priv, CSR_GP_CNTRL) - & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); - - if (new_rfkill != old_rfkill) { - if (new_rfkill) - set_bit(STATUS_RF_KILL_HW, &priv->status); - else - clear_bit(STATUS_RF_KILL_HW, &priv->status); - - wiphy_rfkill_set_hw_state(priv->hw->wiphy, new_rfkill); - - IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n", - new_rfkill ? "disable radio" : "enable radio"); - } - - /* Keep this running, even if radio now enabled. This will be - * cancelled in mac_start() if system decides to start again */ - queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll, - round_jiffies_relative(2 * HZ)); - -} - -int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) -{ - struct iwl_host_cmd cmd = { - .id = REPLY_SCAN_CMD, - .len = sizeof(struct iwl3945_scan_cmd), - .flags = CMD_SIZE_HUGE, - }; - struct iwl3945_scan_cmd *scan; - u8 n_probes = 0; - enum ieee80211_band band; - bool is_active = false; - int ret; - - lockdep_assert_held(&priv->mutex); - - if (!priv->scan_cmd) { - priv->scan_cmd = kmalloc(sizeof(struct iwl3945_scan_cmd) + - IWL_MAX_SCAN_SIZE, GFP_KERNEL); - if (!priv->scan_cmd) { - IWL_DEBUG_SCAN(priv, "Fail to allocate scan memory\n"); - return -ENOMEM; - } - } - scan = priv->scan_cmd; - memset(scan, 0, sizeof(struct iwl3945_scan_cmd) + IWL_MAX_SCAN_SIZE); - - scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; - scan->quiet_time = IWL_ACTIVE_QUIET_TIME; - - if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { - u16 interval = 0; - u32 extra; - u32 suspend_time = 100; - u32 scan_suspend_time = 100; - - IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); - - if (priv->is_internal_short_scan) - interval = 0; - else - interval = vif->bss_conf.beacon_int; - - scan->suspend_time = 0; - scan->max_out_time = cpu_to_le32(200 * 1024); - if (!interval) - interval = suspend_time; - /* - * suspend time format: - * 0-19: beacon interval in usec (time before exec.) - * 20-23: 0 - * 24-31: number of beacons (suspend between channels) - */ - - extra = (suspend_time / interval) << 24; - scan_suspend_time = 0xFF0FFFFF & - (extra | ((suspend_time % interval) * 1024)); - - scan->suspend_time = cpu_to_le32(scan_suspend_time); - IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n", - scan_suspend_time, interval); - } - - if (priv->is_internal_short_scan) { - IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); - } else if (priv->scan_request->n_ssids) { - int i, p = 0; - IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); - for (i = 0; i < priv->scan_request->n_ssids; i++) { - /* always does wildcard anyway */ - if (!priv->scan_request->ssids[i].ssid_len) - continue; - scan->direct_scan[p].id = WLAN_EID_SSID; - scan->direct_scan[p].len = - priv->scan_request->ssids[i].ssid_len; - memcpy(scan->direct_scan[p].ssid, - priv->scan_request->ssids[i].ssid, - priv->scan_request->ssids[i].ssid_len); - n_probes++; - p++; - } - is_active = true; - } else - IWL_DEBUG_SCAN(priv, "Kicking off passive scan.\n"); - - /* We don't build a direct scan probe request; the uCode will do - * that based on the direct_mask added to each channel entry */ - scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; - scan->tx_cmd.sta_id = priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; - scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; - - /* flags + rate selection */ - - switch (priv->scan_band) { - case IEEE80211_BAND_2GHZ: - scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; - scan->tx_cmd.rate = IWL_RATE_1M_PLCP; - band = IEEE80211_BAND_2GHZ; - break; - case IEEE80211_BAND_5GHZ: - scan->tx_cmd.rate = IWL_RATE_6M_PLCP; - band = IEEE80211_BAND_5GHZ; - break; - default: - IWL_WARN(priv, "Invalid scan band\n"); - return -EIO; - } - - /* - * If active scaning is requested but a certain channel - * is marked passive, we can do active scanning if we - * detect transmissions. - */ - scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : - IWL_GOOD_CRC_TH_DISABLED; - - if (!priv->is_internal_short_scan) { - scan->tx_cmd.len = cpu_to_le16( - iwl_fill_probe_req(priv, - (struct ieee80211_mgmt *)scan->data, - vif->addr, - priv->scan_request->ie, - priv->scan_request->ie_len, - IWL_MAX_SCAN_SIZE - sizeof(*scan))); - } else { - /* use bcast addr, will not be transmitted but must be valid */ - scan->tx_cmd.len = cpu_to_le16( - iwl_fill_probe_req(priv, - (struct ieee80211_mgmt *)scan->data, - iwl_bcast_addr, NULL, 0, - IWL_MAX_SCAN_SIZE - sizeof(*scan))); - } - /* select Rx antennas */ - scan->flags |= iwl3945_get_antenna_flags(priv); - - if (priv->is_internal_short_scan) { - scan->channel_count = - iwl3945_get_single_channel_for_scan(priv, vif, band, - (void *)&scan->data[le16_to_cpu( - scan->tx_cmd.len)]); - } else { - scan->channel_count = - iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, - (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif); - } - - if (scan->channel_count == 0) { - IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); - return -EIO; - } - - cmd.len += le16_to_cpu(scan->tx_cmd.len) + - scan->channel_count * sizeof(struct iwl3945_scan_channel); - cmd.data = scan; - scan->len = cpu_to_le16(cmd.len); - - set_bit(STATUS_SCAN_HW, &priv->status); - ret = iwl_send_cmd_sync(priv, &cmd); - if (ret) - clear_bit(STATUS_SCAN_HW, &priv->status); - return ret; -} - -void iwl3945_post_scan(struct iwl_priv *priv) -{ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - /* - * Since setting the RXON may have been deferred while - * performing the scan, fire one off if needed - */ - if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) - iwl3945_commit_rxon(priv, ctx); -} - -static void iwl3945_bg_restart(struct work_struct *data) -{ - struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { - struct iwl_rxon_context *ctx; - mutex_lock(&priv->mutex); - for_each_context(priv, ctx) - ctx->vif = NULL; - priv->is_open = 0; - mutex_unlock(&priv->mutex); - iwl3945_down(priv); - ieee80211_restart_hw(priv->hw); - } else { - iwl3945_down(priv); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - mutex_lock(&priv->mutex); - __iwl3945_up(priv); - mutex_unlock(&priv->mutex); - } -} - -static void iwl3945_bg_rx_replenish(struct work_struct *data) -{ - struct iwl_priv *priv = - container_of(data, struct iwl_priv, rx_replenish); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - mutex_lock(&priv->mutex); - iwl3945_rx_replenish(priv); - mutex_unlock(&priv->mutex); -} - -void iwl3945_post_associate(struct iwl_priv *priv) -{ - int rc = 0; - struct ieee80211_conf *conf = NULL; - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - if (!ctx->vif || !priv->is_open) - return; - - if (ctx->vif->type == NL80211_IFTYPE_AP) { - IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); - return; - } - - IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", - ctx->vif->bss_conf.aid, ctx->active.bssid_addr); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - iwl_scan_cancel_timeout(priv, 200); - - conf = ieee80211_get_hw_conf(priv->hw); - - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl3945_commit_rxon(priv, ctx); - - rc = iwl_send_rxon_timing(priv, ctx); - if (rc) - IWL_WARN(priv, "REPLY_RXON_TIMING failed - " - "Attempting to continue.\n"); - - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - - ctx->staging.assoc_id = cpu_to_le16(ctx->vif->bss_conf.aid); - - IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", - ctx->vif->bss_conf.aid, ctx->vif->bss_conf.beacon_int); - - if (ctx->vif->bss_conf.use_short_preamble) - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; - else - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { - if (ctx->vif->bss_conf.use_short_slot) - ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; - else - ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; - } - - iwl3945_commit_rxon(priv, ctx); - - switch (ctx->vif->type) { - case NL80211_IFTYPE_STATION: - iwl3945_rate_scale_init(priv->hw, IWL_AP_ID); - break; - case NL80211_IFTYPE_ADHOC: - iwl3945_send_beacon_cmd(priv); - break; - default: - IWL_ERR(priv, "%s Should not be called in %d mode\n", - __func__, ctx->vif->type); - break; - } -} - -/***************************************************************************** - * - * mac80211 entry point functions - * - *****************************************************************************/ - -#define UCODE_READY_TIMEOUT (2 * HZ) - -static int iwl3945_mac_start(struct ieee80211_hw *hw) -{ - struct iwl_priv *priv = hw->priv; - int ret; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - /* we should be verifying the device is ready to be opened */ - mutex_lock(&priv->mutex); - - /* fetch ucode file from disk, alloc and copy to bus-master buffers ... - * ucode filename and max sizes are card-specific. */ - - if (!priv->ucode_code.len) { - ret = iwl3945_read_ucode(priv); - if (ret) { - IWL_ERR(priv, "Could not read microcode: %d\n", ret); - mutex_unlock(&priv->mutex); - goto out_release_irq; - } - } - - ret = __iwl3945_up(priv); - - mutex_unlock(&priv->mutex); - - if (ret) - goto out_release_irq; - - IWL_DEBUG_INFO(priv, "Start UP work.\n"); - - /* Wait for START_ALIVE from ucode. Otherwise callbacks from - * mac80211 will not be run successfully. */ - ret = wait_event_interruptible_timeout(priv->wait_command_queue, - test_bit(STATUS_READY, &priv->status), - UCODE_READY_TIMEOUT); - if (!ret) { - if (!test_bit(STATUS_READY, &priv->status)) { - IWL_ERR(priv, - "Wait for START_ALIVE timeout after %dms.\n", - jiffies_to_msecs(UCODE_READY_TIMEOUT)); - ret = -ETIMEDOUT; - goto out_release_irq; - } - } - - /* ucode is running and will send rfkill notifications, - * no need to poll the killswitch state anymore */ - cancel_delayed_work(&priv->_3945.rfkill_poll); - - priv->is_open = 1; - IWL_DEBUG_MAC80211(priv, "leave\n"); - return 0; - -out_release_irq: - priv->is_open = 0; - IWL_DEBUG_MAC80211(priv, "leave - failed\n"); - return ret; -} - -static void iwl3945_mac_stop(struct ieee80211_hw *hw) -{ - struct iwl_priv *priv = hw->priv; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - if (!priv->is_open) { - IWL_DEBUG_MAC80211(priv, "leave - skip\n"); - return; - } - - priv->is_open = 0; - - iwl3945_down(priv); - - flush_workqueue(priv->workqueue); - - /* start polling the killswitch state again */ - queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll, - round_jiffies_relative(2 * HZ)); - - IWL_DEBUG_MAC80211(priv, "leave\n"); -} - -static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct iwl_priv *priv = hw->priv; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, - ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); - - if (iwl3945_tx_skb(priv, skb)) - dev_kfree_skb_any(skb); - - IWL_DEBUG_MAC80211(priv, "leave\n"); - return NETDEV_TX_OK; -} - -void iwl3945_config_ap(struct iwl_priv *priv) -{ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - struct ieee80211_vif *vif = ctx->vif; - int rc = 0; - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - /* The following should be done only at AP bring up */ - if (!(iwl_is_associated(priv, IWL_RXON_CTX_BSS))) { - - /* RXON - unassoc (to set timing command) */ - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl3945_commit_rxon(priv, ctx); - - /* RXON Timing */ - rc = iwl_send_rxon_timing(priv, ctx); - if (rc) - IWL_WARN(priv, "REPLY_RXON_TIMING failed - " - "Attempting to continue.\n"); - - ctx->staging.assoc_id = 0; - - if (vif->bss_conf.use_short_preamble) - ctx->staging.flags |= - RXON_FLG_SHORT_PREAMBLE_MSK; - else - ctx->staging.flags &= - ~RXON_FLG_SHORT_PREAMBLE_MSK; - - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { - if (vif->bss_conf.use_short_slot) - ctx->staging.flags |= - RXON_FLG_SHORT_SLOT_MSK; - else - ctx->staging.flags &= - ~RXON_FLG_SHORT_SLOT_MSK; - } - /* restore RXON assoc */ - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - iwl3945_commit_rxon(priv, ctx); - } - iwl3945_send_beacon_cmd(priv); - - /* FIXME - we need to add code here to detect a totally new - * configuration, reset the AP, unassoc, rxon timing, assoc, - * clear sta table, add BCAST sta... */ -} - -static int iwl3945_mac_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 iwl_priv *priv = hw->priv; - int ret = 0; - u8 sta_id = IWL_INVALID_STATION; - u8 static_key; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - if (iwl3945_mod_params.sw_crypto) { - IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n"); - return -EOPNOTSUPP; - } - - /* - * To support IBSS RSN, don't program group keys in IBSS, the - * hardware will then not attempt to decrypt the frames. - */ - if (vif->type == NL80211_IFTYPE_ADHOC && - !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) - return -EOPNOTSUPP; - - static_key = !iwl_is_associated(priv, IWL_RXON_CTX_BSS); - - if (!static_key) { - sta_id = iwl_sta_id_or_broadcast( - priv, &priv->contexts[IWL_RXON_CTX_BSS], sta); - if (sta_id == IWL_INVALID_STATION) - return -EINVAL; - } - - mutex_lock(&priv->mutex); - iwl_scan_cancel_timeout(priv, 100); - - switch (cmd) { - case SET_KEY: - if (static_key) - ret = iwl3945_set_static_key(priv, key); - else - ret = iwl3945_set_dynamic_key(priv, key, sta_id); - IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n"); - break; - case DISABLE_KEY: - if (static_key) - ret = iwl3945_remove_static_key(priv); - else - ret = iwl3945_clear_sta_key_info(priv, sta_id); - IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n"); - break; - default: - ret = -EINVAL; - } - - mutex_unlock(&priv->mutex); - IWL_DEBUG_MAC80211(priv, "leave\n"); - - return ret; -} - -static int iwl3945_mac_sta_add(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - struct iwl_priv *priv = hw->priv; - struct iwl3945_sta_priv *sta_priv = (void *)sta->drv_priv; - int ret; - bool is_ap = vif->type == NL80211_IFTYPE_STATION; - u8 sta_id; - - IWL_DEBUG_INFO(priv, "received request to add station %pM\n", - sta->addr); - mutex_lock(&priv->mutex); - IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", - sta->addr); - sta_priv->common.sta_id = IWL_INVALID_STATION; - - - ret = iwl_add_station_common(priv, &priv->contexts[IWL_RXON_CTX_BSS], - sta->addr, is_ap, sta, &sta_id); - if (ret) { - IWL_ERR(priv, "Unable to add station %pM (%d)\n", - sta->addr, ret); - /* Should we return success if return code is EEXIST ? */ - mutex_unlock(&priv->mutex); - return ret; - } - - sta_priv->common.sta_id = sta_id; - - /* Initialize rate scaling */ - IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", - sta->addr); - iwl3945_rs_rate_init(priv, sta, sta_id); - mutex_unlock(&priv->mutex); - - return 0; -} - -static void iwl3945_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, - u64 multicast) -{ - struct iwl_priv *priv = hw->priv; - __le32 filter_or = 0, filter_nand = 0; - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - -#define CHK(test, flag) do { \ - if (*total_flags & (test)) \ - filter_or |= (flag); \ - else \ - filter_nand |= (flag); \ - } while (0) - - IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n", - changed_flags, *total_flags); - - CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); - CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK); - CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); - -#undef CHK - - mutex_lock(&priv->mutex); - - ctx->staging.filter_flags &= ~filter_nand; - ctx->staging.filter_flags |= filter_or; - - /* - * Not committing directly because hardware can perform a scan, - * but even if hw is ready, committing here breaks for some reason, - * we'll eventually commit the filter flags change anyway. - */ - - mutex_unlock(&priv->mutex); - - /* - * Receiving all multicast frames is always enabled by the - * default flags setup in iwl_connection_init_rx_config() - * since we currently do not support programming multicast - * filters into the device. - */ - *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | - FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; -} - - -/***************************************************************************** - * - * sysfs attributes - * - *****************************************************************************/ - -#ifdef CONFIG_IWLWIFI_DEBUG - -/* - * The following adds a new attribute to the sysfs representation - * of this device driver (i.e. a new file in /sys/bus/pci/drivers/iwl/) - * used for controlling the debug level. - * - * See the level definitions in iwl for details. - * - * The debug_level being managed using sysfs below is a per device debug - * level that is used instead of the global debug level if it (the per - * device debug level) is set. - */ -static ssize_t show_debug_level(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - return sprintf(buf, "0x%08X\n", iwl_get_debug_level(priv)); -} -static ssize_t store_debug_level(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - unsigned long val; - int ret; - - ret = strict_strtoul(buf, 0, &val); - if (ret) - IWL_INFO(priv, "%s is not in hex or decimal form.\n", buf); - else { - priv->debug_level = val; - if (iwl_alloc_traffic_mem(priv)) - IWL_ERR(priv, - "Not enough memory to generate traffic log\n"); - } - return strnlen(buf, count); -} - -static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, - show_debug_level, store_debug_level); - -#endif /* CONFIG_IWLWIFI_DEBUG */ - -static ssize_t show_temperature(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - - if (!iwl_is_alive(priv)) - return -EAGAIN; - - return sprintf(buf, "%d\n", iwl3945_hw_get_temperature(priv)); -} - -static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); - -static ssize_t show_tx_power(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - return sprintf(buf, "%d\n", priv->tx_power_user_lmt); -} - -static ssize_t store_tx_power(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - char *p = (char *)buf; - u32 val; - - val = simple_strtoul(p, &p, 10); - if (p == buf) - IWL_INFO(priv, ": %s is not in decimal form.\n", buf); - else - iwl3945_hw_reg_set_txpower(priv, val); - - return count; -} - -static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); - -static ssize_t show_flags(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - return sprintf(buf, "0x%04X\n", ctx->active.flags); -} - -static ssize_t store_flags(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - u32 flags = simple_strtoul(buf, NULL, 0); - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - mutex_lock(&priv->mutex); - if (le32_to_cpu(ctx->staging.flags) != flags) { - /* Cancel any currently running scans... */ - if (iwl_scan_cancel_timeout(priv, 100)) - IWL_WARN(priv, "Could not cancel scan.\n"); - else { - IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n", - flags); - ctx->staging.flags = cpu_to_le32(flags); - iwl3945_commit_rxon(priv, ctx); - } - } - mutex_unlock(&priv->mutex); - - return count; -} - -static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags); - -static ssize_t show_filter_flags(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - return sprintf(buf, "0x%04X\n", - le32_to_cpu(ctx->active.filter_flags)); -} - -static ssize_t store_filter_flags(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - u32 filter_flags = simple_strtoul(buf, NULL, 0); - - mutex_lock(&priv->mutex); - if (le32_to_cpu(ctx->staging.filter_flags) != filter_flags) { - /* Cancel any currently running scans... */ - if (iwl_scan_cancel_timeout(priv, 100)) - IWL_WARN(priv, "Could not cancel scan.\n"); - else { - IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = " - "0x%04X\n", filter_flags); - ctx->staging.filter_flags = - cpu_to_le32(filter_flags); - iwl3945_commit_rxon(priv, ctx); - } - } - mutex_unlock(&priv->mutex); - - return count; -} - -static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, - store_filter_flags); - -static ssize_t show_measurement(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - struct iwl_spectrum_notification measure_report; - u32 size = sizeof(measure_report), len = 0, ofs = 0; - u8 *data = (u8 *)&measure_report; - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - if (!(priv->measurement_status & MEASUREMENT_READY)) { - spin_unlock_irqrestore(&priv->lock, flags); - return 0; - } - memcpy(&measure_report, &priv->measure_report, size); - priv->measurement_status = 0; - spin_unlock_irqrestore(&priv->lock, flags); - - while (size && (PAGE_SIZE - len)) { - hex_dump_to_buffer(data + ofs, size, 16, 1, buf + len, - PAGE_SIZE - len, 1); - len = strlen(buf); - if (PAGE_SIZE - len) - buf[len++] = '\n'; - - ofs += 16; - size -= min(size, 16U); - } - - return len; -} - -static ssize_t store_measurement(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - struct ieee80211_measurement_params params = { - .channel = le16_to_cpu(ctx->active.channel), - .start_time = cpu_to_le64(priv->_3945.last_tsf), - .duration = cpu_to_le16(1), - }; - u8 type = IWL_MEASURE_BASIC; - u8 buffer[32]; - u8 channel; - - if (count) { - char *p = buffer; - strncpy(buffer, buf, min(sizeof(buffer), count)); - channel = simple_strtoul(p, NULL, 0); - if (channel) - params.channel = channel; - - p = buffer; - while (*p && *p != ' ') - p++; - if (*p) - type = simple_strtoul(p + 1, NULL, 0); - } - - IWL_DEBUG_INFO(priv, "Invoking measurement of type %d on " - "channel %d (for '%s')\n", type, params.channel, buf); - iwl3945_get_measurement(priv, ¶ms, type); - - return count; -} - -static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR, - show_measurement, store_measurement); - -static ssize_t store_retry_rate(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - - priv->retry_rate = simple_strtoul(buf, NULL, 0); - if (priv->retry_rate <= 0) - priv->retry_rate = 1; - - return count; -} - -static ssize_t show_retry_rate(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - return sprintf(buf, "%d", priv->retry_rate); -} - -static DEVICE_ATTR(retry_rate, S_IWUSR | S_IRUSR, show_retry_rate, - store_retry_rate); - - -static ssize_t show_channels(struct device *d, - struct device_attribute *attr, char *buf) -{ - /* all this shit doesn't belong into sysfs anyway */ - return 0; -} - -static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); - -static ssize_t show_antenna(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - - if (!iwl_is_alive(priv)) - return -EAGAIN; - - return sprintf(buf, "%d\n", iwl3945_mod_params.antenna); -} - -static ssize_t store_antenna(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv __maybe_unused = dev_get_drvdata(d); - int ant; - - if (count == 0) - return 0; - - if (sscanf(buf, "%1i", &ant) != 1) { - IWL_DEBUG_INFO(priv, "not in hex or decimal form.\n"); - return count; - } - - if ((ant >= 0) && (ant <= 2)) { - IWL_DEBUG_INFO(priv, "Setting antenna select to %d.\n", ant); - iwl3945_mod_params.antenna = (enum iwl3945_antenna)ant; - } else - IWL_DEBUG_INFO(priv, "Bad antenna select value %d.\n", ant); - - - return count; -} - -static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, show_antenna, store_antenna); - -static ssize_t show_status(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - if (!iwl_is_alive(priv)) - return -EAGAIN; - return sprintf(buf, "0x%08x\n", (int)priv->status); -} - -static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); - -static ssize_t dump_error_log(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - char *p = (char *)buf; - - if (p[0] == '1') - iwl3945_dump_nic_error_log(priv); - - return strnlen(buf, count); -} - -static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, dump_error_log); - -/***************************************************************************** - * - * driver setup and tear down - * - *****************************************************************************/ - -static void iwl3945_setup_deferred_work(struct iwl_priv *priv) -{ - priv->workqueue = create_singlethread_workqueue(DRV_NAME); - - init_waitqueue_head(&priv->wait_command_queue); - - INIT_WORK(&priv->restart, iwl3945_bg_restart); - INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); - INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); - INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); - INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); - INIT_DELAYED_WORK(&priv->_3945.rfkill_poll, iwl3945_rfkill_poll); - - iwl_setup_scan_deferred_work(priv); - - iwl3945_hw_setup_deferred_work(priv); - - init_timer(&priv->watchdog); - priv->watchdog.data = (unsigned long)priv; - priv->watchdog.function = iwl_bg_watchdog; - - tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) - iwl3945_irq_tasklet, (unsigned long)priv); -} - -static void iwl3945_cancel_deferred_work(struct iwl_priv *priv) -{ - iwl3945_hw_cancel_deferred_work(priv); - - cancel_delayed_work_sync(&priv->init_alive_start); - cancel_delayed_work(&priv->alive_start); - cancel_work_sync(&priv->beacon_update); - - iwl_cancel_scan_deferred_work(priv); -} - -static struct attribute *iwl3945_sysfs_entries[] = { - &dev_attr_antenna.attr, - &dev_attr_channels.attr, - &dev_attr_dump_errors.attr, - &dev_attr_flags.attr, - &dev_attr_filter_flags.attr, - &dev_attr_measurement.attr, - &dev_attr_retry_rate.attr, - &dev_attr_status.attr, - &dev_attr_temperature.attr, - &dev_attr_tx_power.attr, -#ifdef CONFIG_IWLWIFI_DEBUG - &dev_attr_debug_level.attr, -#endif - NULL -}; - -static struct attribute_group iwl3945_attribute_group = { - .name = NULL, /* put in device directory */ - .attrs = iwl3945_sysfs_entries, -}; - -struct ieee80211_ops iwl3945_hw_ops = { - .tx = iwl3945_mac_tx, - .start = iwl3945_mac_start, - .stop = iwl3945_mac_stop, - .add_interface = iwl_mac_add_interface, - .remove_interface = iwl_mac_remove_interface, - .change_interface = iwl_mac_change_interface, - .config = iwl_legacy_mac_config, - .configure_filter = iwl3945_configure_filter, - .set_key = iwl3945_mac_set_key, - .conf_tx = iwl_mac_conf_tx, - .reset_tsf = iwl_legacy_mac_reset_tsf, - .bss_info_changed = iwl_legacy_mac_bss_info_changed, - .hw_scan = iwl_mac_hw_scan, - .sta_add = iwl3945_mac_sta_add, - .sta_remove = iwl_mac_sta_remove, - .tx_last_beacon = iwl_mac_tx_last_beacon, -}; - -static int iwl3945_init_drv(struct iwl_priv *priv) -{ - int ret; - struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; - - priv->retry_rate = 1; - priv->beacon_skb = NULL; - - spin_lock_init(&priv->sta_lock); - spin_lock_init(&priv->hcmd_lock); - - INIT_LIST_HEAD(&priv->free_frames); - - mutex_init(&priv->mutex); - mutex_init(&priv->sync_cmd_mutex); - - priv->ieee_channels = NULL; - priv->ieee_rates = NULL; - priv->band = IEEE80211_BAND_2GHZ; - - priv->iw_mode = NL80211_IFTYPE_STATION; - priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; - - /* initialize force reset */ - priv->force_reset[IWL_RF_RESET].reset_duration = - IWL_DELAY_NEXT_FORCE_RF_RESET; - priv->force_reset[IWL_FW_RESET].reset_duration = - IWL_DELAY_NEXT_FORCE_FW_RELOAD; - - - priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER; - priv->tx_power_next = IWL_DEFAULT_TX_POWER; - - if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { - IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n", - eeprom->version); - ret = -EINVAL; - goto err; - } - ret = iwl_init_channel_map(priv); - if (ret) { - IWL_ERR(priv, "initializing regulatory failed: %d\n", ret); - goto err; - } - - /* Set up txpower settings in driver for all channels */ - if (iwl3945_txpower_set_from_eeprom(priv)) { - ret = -EIO; - goto err_free_channel_map; - } - - ret = iwlcore_init_geos(priv); - if (ret) { - IWL_ERR(priv, "initializing geos failed: %d\n", ret); - goto err_free_channel_map; - } - iwl3945_init_hw_rates(priv, priv->ieee_rates); - - return 0; - -err_free_channel_map: - iwl_free_channel_map(priv); -err: - return ret; -} - -#define IWL3945_MAX_PROBE_REQUEST 200 - -static int iwl3945_setup_mac(struct iwl_priv *priv) -{ - int ret; - struct ieee80211_hw *hw = priv->hw; - - hw->rate_control_algorithm = "iwl-3945-rs"; - hw->sta_data_size = sizeof(struct iwl3945_sta_priv); - hw->vif_data_size = sizeof(struct iwl_vif_priv); - - /* Tell mac80211 our characteristics */ - hw->flags = IEEE80211_HW_SIGNAL_DBM | - IEEE80211_HW_SPECTRUM_MGMT; - - if (!priv->cfg->base_params->broken_powersave) - hw->flags |= IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_SUPPORTS_DYNAMIC_PS; - - hw->wiphy->interface_modes = - priv->contexts[IWL_RXON_CTX_BSS].interface_modes; - - hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | - WIPHY_FLAG_DISABLE_BEACON_HINTS | - WIPHY_FLAG_IBSS_RSN; - - hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; - /* we create the 802.11 header and a zero-length SSID element */ - hw->wiphy->max_scan_ie_len = IWL3945_MAX_PROBE_REQUEST - 24 - 2; - - /* Default value; 4 EDCA QOS priorities */ - hw->queues = 4; - - if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) - priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = - &priv->bands[IEEE80211_BAND_2GHZ]; - - if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) - priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = - &priv->bands[IEEE80211_BAND_5GHZ]; - - iwl_leds_init(priv); - - ret = ieee80211_register_hw(priv->hw); - if (ret) { - IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); - return ret; - } - priv->mac80211_registered = 1; - - return 0; -} - -static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - int err = 0, i; - struct iwl_priv *priv; - struct ieee80211_hw *hw; - struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); - struct iwl3945_eeprom *eeprom; - unsigned long flags; - - /*********************** - * 1. Allocating HW data - * ********************/ - - /* mac80211 allocates memory for this device instance, including - * space for this driver's private structure */ - hw = iwl_alloc_all(cfg); - if (hw == NULL) { - pr_err("Can not allocate network device\n"); - err = -ENOMEM; - goto out; - } - priv = hw->priv; - SET_IEEE80211_DEV(hw, &pdev->dev); - - priv->cmd_queue = IWL39_CMD_QUEUE_NUM; - - /* 3945 has only one valid context */ - priv->valid_contexts = BIT(IWL_RXON_CTX_BSS); - - for (i = 0; i < NUM_IWL_RXON_CTX; i++) - priv->contexts[i].ctxid = i; - - priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON; - priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING; - priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; - priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; - priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; - priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; - priv->contexts[IWL_RXON_CTX_BSS].interface_modes = - BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC); - priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS; - priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS; - priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS; - - /* - * Disabling hardware scan means that mac80211 will perform scans - * "the hard way", rather than using device's scan. - */ - if (iwl3945_mod_params.disable_hw_scan) { - dev_printk(KERN_DEBUG, &(pdev->dev), - "sw scan support is deprecated\n"); - iwl3945_hw_ops.hw_scan = NULL; - } - - - IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); - priv->cfg = cfg; - priv->pci_dev = pdev; - priv->inta_mask = CSR_INI_SET_MASK; - - if (iwl_alloc_traffic_mem(priv)) - IWL_ERR(priv, "Not enough memory to generate traffic log\n"); - - /*************************** - * 2. Initializing PCI bus - * *************************/ - pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | - PCIE_LINK_STATE_CLKPM); - - if (pci_enable_device(pdev)) { - err = -ENODEV; - goto out_ieee80211_free_hw; - } - - pci_set_master(pdev); - - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (!err) - err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); - if (err) { - IWL_WARN(priv, "No suitable DMA available.\n"); - goto out_pci_disable_device; - } - - pci_set_drvdata(pdev, priv); - err = pci_request_regions(pdev, DRV_NAME); - if (err) - goto out_pci_disable_device; - - /*********************** - * 3. Read REV Register - * ********************/ - priv->hw_base = pci_iomap(pdev, 0, 0); - if (!priv->hw_base) { - err = -ENODEV; - goto out_pci_release_regions; - } - - IWL_DEBUG_INFO(priv, "pci_resource_len = 0x%08llx\n", - (unsigned long long) pci_resource_len(pdev, 0)); - IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base); - - /* We disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state */ - pci_write_config_byte(pdev, 0x41, 0x00); - - /* these spin locks will be used in apm_ops.init and EEPROM access - * we should init now - */ - spin_lock_init(&priv->reg_lock); - spin_lock_init(&priv->lock); - - /* - * stop and reset the on-board processor just in case it is in a - * strange state ... like being left stranded by a primary kernel - * and this is now the kdump kernel trying to start up - */ - iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); - - /*********************** - * 4. Read EEPROM - * ********************/ - - /* Read the EEPROM */ - err = iwl_eeprom_init(priv); - if (err) { - IWL_ERR(priv, "Unable to init EEPROM\n"); - goto out_iounmap; - } - /* MAC Address location in EEPROM same for 3945/4965 */ - eeprom = (struct iwl3945_eeprom *)priv->eeprom; - IWL_DEBUG_INFO(priv, "MAC address: %pM\n", eeprom->mac_address); - SET_IEEE80211_PERM_ADDR(priv->hw, eeprom->mac_address); - - /*********************** - * 5. Setup HW Constants - * ********************/ - /* Device-specific setup */ - if (iwl3945_hw_set_hw_params(priv)) { - IWL_ERR(priv, "failed to set hw settings\n"); - goto out_eeprom_free; - } - - /*********************** - * 6. Setup priv - * ********************/ - - err = iwl3945_init_drv(priv); - if (err) { - IWL_ERR(priv, "initializing driver failed\n"); - goto out_unset_hw_params; - } - - IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s\n", - priv->cfg->name); - - /*********************** - * 7. Setup Services - * ********************/ - - spin_lock_irqsave(&priv->lock, flags); - iwl_disable_interrupts(priv); - spin_unlock_irqrestore(&priv->lock, flags); - - pci_enable_msi(priv->pci_dev); - - err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr_ops.isr, - IRQF_SHARED, DRV_NAME, priv); - if (err) { - IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); - goto out_disable_msi; - } - - err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group); - if (err) { - IWL_ERR(priv, "failed to create sysfs device attributes\n"); - goto out_release_irq; - } - - iwl_set_rxon_channel(priv, - &priv->bands[IEEE80211_BAND_2GHZ].channels[5], - &priv->contexts[IWL_RXON_CTX_BSS]); - iwl3945_setup_deferred_work(priv); - iwl3945_setup_rx_handlers(priv); - iwl_power_initialize(priv); - - /********************************* - * 8. Setup and Register mac80211 - * *******************************/ - - iwl_enable_interrupts(priv); - - err = iwl3945_setup_mac(priv); - if (err) - goto out_remove_sysfs; - - err = iwl_dbgfs_register(priv, DRV_NAME); - if (err) - IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); - - /* Start monitoring the killswitch */ - queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll, - 2 * HZ); - - return 0; - - out_remove_sysfs: - destroy_workqueue(priv->workqueue); - priv->workqueue = NULL; - sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); - out_release_irq: - free_irq(priv->pci_dev->irq, priv); - out_disable_msi: - pci_disable_msi(priv->pci_dev); - iwlcore_free_geos(priv); - iwl_free_channel_map(priv); - out_unset_hw_params: - iwl3945_unset_hw_params(priv); - out_eeprom_free: - iwl_eeprom_free(priv); - out_iounmap: - pci_iounmap(pdev, priv->hw_base); - out_pci_release_regions: - pci_release_regions(pdev); - out_pci_disable_device: - pci_set_drvdata(pdev, NULL); - pci_disable_device(pdev); - out_ieee80211_free_hw: - iwl_free_traffic_mem(priv); - ieee80211_free_hw(priv->hw); - out: - return err; -} - -static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) -{ - struct iwl_priv *priv = pci_get_drvdata(pdev); - unsigned long flags; - - if (!priv) - return; - - IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); - - iwl_dbgfs_unregister(priv); - - set_bit(STATUS_EXIT_PENDING, &priv->status); - - iwl_leds_exit(priv); - - if (priv->mac80211_registered) { - ieee80211_unregister_hw(priv->hw); - priv->mac80211_registered = 0; - } else { - iwl3945_down(priv); - } - - /* - * Make sure device is reset to low power before unloading driver. - * This may be redundant with iwl_down(), but there are paths to - * run iwl_down() without calling apm_ops.stop(), and there are - * paths to avoid running iwl_down() at all before leaving driver. - * This (inexpensive) call *makes sure* device is reset. - */ - iwl_apm_stop(priv); - - /* make sure we flush any pending irq or - * tasklet for the driver - */ - spin_lock_irqsave(&priv->lock, flags); - iwl_disable_interrupts(priv); - spin_unlock_irqrestore(&priv->lock, flags); - - iwl_synchronize_irq(priv); - - sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); - - cancel_delayed_work_sync(&priv->_3945.rfkill_poll); - - iwl3945_dealloc_ucode_pci(priv); - - if (priv->rxq.bd) - iwl3945_rx_queue_free(priv, &priv->rxq); - iwl3945_hw_txq_ctx_free(priv); - - iwl3945_unset_hw_params(priv); - - /*netif_stop_queue(dev); */ - flush_workqueue(priv->workqueue); - - /* ieee80211_unregister_hw calls iwl3945_mac_stop, which flushes - * priv->workqueue... so we can't take down the workqueue - * until now... */ - destroy_workqueue(priv->workqueue); - priv->workqueue = NULL; - iwl_free_traffic_mem(priv); - - free_irq(pdev->irq, priv); - pci_disable_msi(pdev); - - pci_iounmap(pdev, priv->hw_base); - pci_release_regions(pdev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); - - iwl_free_channel_map(priv); - iwlcore_free_geos(priv); - kfree(priv->scan_cmd); - if (priv->beacon_skb) - dev_kfree_skb(priv->beacon_skb); - - ieee80211_free_hw(priv->hw); -} - - -/***************************************************************************** - * - * driver and module entry point - * - *****************************************************************************/ - -static struct pci_driver iwl3945_driver = { - .name = DRV_NAME, - .id_table = iwl3945_hw_card_ids, - .probe = iwl3945_pci_probe, - .remove = __devexit_p(iwl3945_pci_remove), - .driver.pm = IWL_PM_OPS, -}; - -static int __init iwl3945_init(void) -{ - - int ret; - pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); - pr_info(DRV_COPYRIGHT "\n"); - - ret = iwl3945_rate_control_register(); - if (ret) { - pr_err("Unable to register rate control algorithm: %d\n", ret); - return ret; - } - - ret = pci_register_driver(&iwl3945_driver); - if (ret) { - pr_err("Unable to initialize PCI module\n"); - goto error_register; - } - - return ret; - -error_register: - iwl3945_rate_control_unregister(); - return ret; -} - -static void __exit iwl3945_exit(void) -{ - pci_unregister_driver(&iwl3945_driver); - iwl3945_rate_control_unregister(); -} - -MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX)); - -module_param_named(antenna, iwl3945_mod_params.antenna, int, S_IRUGO); -MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); -module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, S_IRUGO); -MODULE_PARM_DESC(swcrypto, - "using software crypto (default 1 [software])\n"); -#ifdef CONFIG_IWLWIFI_DEBUG -module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "debug output mask"); -#endif -module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, - int, S_IRUGO); -MODULE_PARM_DESC(disable_hw_scan, - "disable hardware scanning (default 0) (deprecated)"); -module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, S_IRUGO); -MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error"); - -module_exit(iwl3945_exit); -module_init(iwl3945_init); -- cgit v1.2.3 From 4bc85c1324aaa4a8bb0171e332ff762b6230bdfe Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 21 Feb 2011 11:11:05 -0800 Subject: Revert "iwlwifi: split the drivers for agn and legacy devices 3945/4965" This reverts commit aa833c4b1a928b8d3c4fcc2faaa0d6b81ea02b56. --- drivers/net/wireless/Kconfig | 1 - drivers/net/wireless/Makefile | 3 +- drivers/net/wireless/iwlwifi/Kconfig | 124 +- drivers/net/wireless/iwlwifi/Makefile | 39 +- drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c | 522 +++ drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h | 60 + drivers/net/wireless/iwlwifi/iwl-3945-fh.h | 188 + drivers/net/wireless/iwlwifi/iwl-3945-hw.h | 294 ++ drivers/net/wireless/iwlwifi/iwl-3945-led.c | 64 + drivers/net/wireless/iwlwifi/iwl-3945-led.h | 32 + drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 995 ++++++ drivers/net/wireless/iwlwifi/iwl-3945.c | 2819 +++++++++++++++ drivers/net/wireless/iwlwifi/iwl-3945.h | 308 ++ drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 792 +++++ drivers/net/wireless/iwlwifi/iwl-4965.c | 2666 ++++++++++++++ drivers/net/wireless/iwlwifi/iwl-agn.c | 18 + drivers/net/wireless/iwlwifi/iwl-core.c | 54 + drivers/net/wireless/iwlwifi/iwl-debugfs.c | 2 + drivers/net/wireless/iwlwifi/iwl-dev.h | 4 +- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 8 + drivers/net/wireless/iwlwifi/iwl-hcmd.c | 5 + drivers/net/wireless/iwlwifi/iwl-led.c | 2 + drivers/net/wireless/iwlwifi/iwl-legacy.c | 657 ++++ drivers/net/wireless/iwlwifi/iwl-legacy.h | 79 + drivers/net/wireless/iwlwifi/iwl-power.c | 3 + drivers/net/wireless/iwlwifi/iwl-rx.c | 6 + drivers/net/wireless/iwlwifi/iwl-scan.c | 10 + drivers/net/wireless/iwlwifi/iwl-sta.c | 11 + drivers/net/wireless/iwlwifi/iwl-tx.c | 7 + drivers/net/wireless/iwlwifi/iwl3945-base.c | 4334 +++++++++++++++++++++++ 30 files changed, 14046 insertions(+), 61 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h create mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-fh.h create mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-hw.h create mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-led.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-led.h create mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-rs.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-3945.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-3945.h create mode 100644 drivers/net/wireless/iwlwifi/iwl-4965-hw.h create mode 100644 drivers/net/wireless/iwlwifi/iwl-4965.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-legacy.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-legacy.h create mode 100644 drivers/net/wireless/iwlwifi/iwl3945-base.c (limited to 'drivers') diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 7aeb113cbb90..b4338f389394 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -274,7 +274,6 @@ source "drivers/net/wireless/b43legacy/Kconfig" source "drivers/net/wireless/hostap/Kconfig" source "drivers/net/wireless/ipw2x00/Kconfig" source "drivers/net/wireless/iwlwifi/Kconfig" -source "drivers/net/wireless/iwlegacy/Kconfig" source "drivers/net/wireless/iwmc3200wifi/Kconfig" source "drivers/net/wireless/libertas/Kconfig" source "drivers/net/wireless/orinoco/Kconfig" diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index cd0c7e2aed43..9760561a27a5 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -41,8 +41,7 @@ obj-$(CONFIG_ADM8211) += adm8211.o obj-$(CONFIG_MWL8K) += mwl8k.o -obj-$(CONFIG_IWLAGN) += iwlwifi/ -obj-$(CONFIG_IWLWIFI_LEGACY) += iwlegacy/ +obj-$(CONFIG_IWLWIFI) += iwlwifi/ obj-$(CONFIG_RT2X00) += rt2x00/ obj-$(CONFIG_P54_COMMON) += p54/ diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 17d555f2215a..e1e3b1cf3cff 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -1,52 +1,18 @@ -config IWLAGN - tristate "Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlagn) " +config IWLWIFI + tristate "Intel Wireless Wifi" depends on PCI && MAC80211 select FW_LOADER select NEW_LEDS select LEDS_CLASS select LEDS_TRIGGERS select MAC80211_LEDS - ---help--- - Select to build the driver supporting the: - - Intel Wireless WiFi Link Next-Gen AGN - - This option enables support for use with the following hardware: - Intel Wireless WiFi Link 6250AGN Adapter - Intel 6000 Series Wi-Fi Adapters (6200AGN and 6300AGN) - Intel WiFi Link 1000BGN - Intel Wireless WiFi 5150AGN - Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN - Intel 6005 Series Wi-Fi Adapters - Intel 6030 Series Wi-Fi Adapters - Intel Wireless WiFi Link 6150BGN 2 Adapter - Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN) - Intel 2000 Series Wi-Fi Adapters - - - This driver uses the kernel's mac80211 subsystem. - - In order to use this driver, you will need a microcode (uCode) - image for it. You can obtain the microcode from: - - . - - The microcode is typically installed in /lib/firmware. You can - look in the hotplug script /etc/hotplug/firmware.agent to - determine which directory FIRMWARE_DIR is set to when the script - runs. - - If you want to compile the driver as a module ( = code which can be - inserted in and removed from the running kernel whenever you want), - say M here and read . The - module will be called iwlagn. menu "Debugging Options" - depends on IWLAGN + depends on IWLWIFI config IWLWIFI_DEBUG - bool "Enable full debugging output in the iwlagn driver" - depends on IWLAGN + bool "Enable full debugging output in iwlagn and iwl3945 drivers" + depends on IWLWIFI ---help--- This option will enable debug tracing output for the iwlwifi drivers @@ -71,7 +37,7 @@ config IWLWIFI_DEBUG config IWLWIFI_DEBUGFS bool "iwlagn debugfs support" - depends on IWLAGN && MAC80211_DEBUGFS + depends on IWLWIFI && MAC80211_DEBUGFS ---help--- Enable creation of debugfs files for the iwlwifi drivers. This is a low-impact option that allows getting insight into the @@ -79,13 +45,13 @@ config IWLWIFI_DEBUGFS config IWLWIFI_DEBUG_EXPERIMENTAL_UCODE bool "Experimental uCode support" - depends on IWLAGN && IWLWIFI_DEBUG + depends on IWLWIFI && IWLWIFI_DEBUG ---help--- Enable use of experimental ucode for testing and debugging. config IWLWIFI_DEVICE_TRACING bool "iwlwifi device access tracing" - depends on IWLAGN + depends on IWLWIFI depends on EVENT_TRACING help Say Y here to trace all commands, including TX frames and IO @@ -102,9 +68,57 @@ config IWLWIFI_DEVICE_TRACING occur. endmenu +config IWLAGN + tristate "Intel Wireless WiFi Next Gen AGN (iwlagn)" + depends on IWLWIFI + ---help--- + Select to build the driver supporting the: + + Intel Wireless WiFi Link Next-Gen AGN + + This driver uses the kernel's mac80211 subsystem. + + In order to use this driver, you will need a microcode (uCode) + image for it. You can obtain the microcode from: + + . + + The microcode is typically installed in /lib/firmware. You can + look in the hotplug script /etc/hotplug/firmware.agent to + determine which directory FIRMWARE_DIR is set to when the script + runs. + + If you want to compile the driver as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read . The + module will be called iwlagn. + + +config IWL4965 + bool "Intel Wireless WiFi 4965AGN" + depends on IWLAGN + ---help--- + This option enables support for Intel Wireless WiFi Link 4965AGN + +config IWL5000 + bool "Intel Wireless-N/Advanced-N/Ultimate-N WiFi Link" + depends on IWLAGN + ---help--- + This option enables support for use with the following hardware: + Intel Wireless WiFi Link 6250AGN Adapter + Intel 6000 Series Wi-Fi Adapters (6200AGN and 6300AGN) + Intel WiFi Link 1000BGN + Intel Wireless WiFi 5150AGN + Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN + Intel 6005 Series Wi-Fi Adapters + Intel 6030 Series Wi-Fi Adapters + Intel Wireless WiFi Link 6150BGN 2 Adapter + Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN) + Intel 2000 Series Wi-Fi Adapters + config IWL_P2P bool "iwlwifi experimental P2P support" - depends on IWLAGN + depends on IWL5000 help This option enables experimental P2P support for some devices based on microcode support. Since P2P support is still under @@ -118,3 +132,27 @@ config IWL_P2P Say Y only if you want to experiment with P2P. +config IWL3945 + tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)" + depends on IWLWIFI + ---help--- + Select to build the driver supporting the: + + Intel PRO/Wireless 3945ABG/BG Network Connection + + This driver uses the kernel's mac80211 subsystem. + + In order to use this driver, you will need a microcode (uCode) + image for it. You can obtain the microcode from: + + . + + The microcode is typically installed in /lib/firmware. You can + look in the hotplug script /etc/hotplug/firmware.agent to + determine which directory FIRMWARE_DIR is set to when the script + runs. + + If you want to compile the driver as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read . The + module will be called iwl3945. diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index aab7d15bd5ed..25be742c69c9 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -1,23 +1,36 @@ +obj-$(CONFIG_IWLWIFI) += iwlcore.o +iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o +iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o +iwlcore-objs += iwl-scan.o iwl-led.o +iwlcore-$(CONFIG_IWL3945) += iwl-legacy.o +iwlcore-$(CONFIG_IWL4965) += iwl-legacy.o +iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o +iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o + +# If 3945 is selected only, iwl-legacy.o will be added +# to iwlcore-m above, but it needs to be built in. +iwlcore-objs += $(iwlcore-m) + +CFLAGS_iwl-devtrace.o := -I$(src) + # AGN obj-$(CONFIG_IWLAGN) += iwlagn.o iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o - -iwlagn-objs += iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o -iwlagn-objs += iwl-rx.o iwl-tx.o iwl-sta.o -iwlagn-objs += iwl-scan.o iwl-led.o -iwlagn-objs += iwl-agn-rxon.o iwl-agn-hcmd.o iwl-agn-ict.o -iwlagn-objs += iwl-5000.o -iwlagn-objs += iwl-6000.o -iwlagn-objs += iwl-1000.o -iwlagn-objs += iwl-2000.o - iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o -iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o -iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o -CFLAGS_iwl-devtrace.o := -I$(src) +iwlagn-$(CONFIG_IWL4965) += iwl-4965.o +iwlagn-$(CONFIG_IWL5000) += iwl-agn-rxon.o iwl-agn-hcmd.o iwl-agn-ict.o +iwlagn-$(CONFIG_IWL5000) += iwl-5000.o +iwlagn-$(CONFIG_IWL5000) += iwl-6000.o +iwlagn-$(CONFIG_IWL5000) += iwl-1000.o +iwlagn-$(CONFIG_IWL5000) += iwl-2000.o + +# 3945 +obj-$(CONFIG_IWL3945) += iwl3945.o +iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o +iwl3945-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-3945-debugfs.o ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c new file mode 100644 index 000000000000..ef0835b01b6b --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c @@ -0,0 +1,522 @@ +/****************************************************************************** + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ + +#include "iwl-3945-debugfs.h" + + +static int iwl3945_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) +{ + int p = 0; + + p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", + le32_to_cpu(priv->_3945.statistics.flag)); + if (le32_to_cpu(priv->_3945.statistics.flag) & + UCODE_STATISTICS_CLEAR_MSK) + p += scnprintf(buf + p, bufsz - p, + "\tStatistics have been cleared\n"); + p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n", + (le32_to_cpu(priv->_3945.statistics.flag) & + UCODE_STATISTICS_FREQUENCY_MSK) + ? "2.4 GHz" : "5.2 GHz"); + p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n", + (le32_to_cpu(priv->_3945.statistics.flag) & + UCODE_STATISTICS_NARROW_BAND_MSK) + ? "enabled" : "disabled"); + return p; +} + +ssize_t iwl3945_ucode_rx_stats_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + int pos = 0; + char *buf; + int bufsz = sizeof(struct iwl39_statistics_rx_phy) * 40 + + sizeof(struct iwl39_statistics_rx_non_phy) * 40 + 400; + ssize_t ret; + struct iwl39_statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm; + struct iwl39_statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck; + struct iwl39_statistics_rx_non_phy *general, *accum_general; + struct iwl39_statistics_rx_non_phy *delta_general, *max_general; + + if (!iwl_is_alive(priv)) + return -EAGAIN; + + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate Buffer\n"); + return -ENOMEM; + } + + /* + * The statistic information display here is based on + * the last statistics notification from uCode + * might not reflect the current uCode activity + */ + ofdm = &priv->_3945.statistics.rx.ofdm; + cck = &priv->_3945.statistics.rx.cck; + general = &priv->_3945.statistics.rx.general; + accum_ofdm = &priv->_3945.accum_statistics.rx.ofdm; + accum_cck = &priv->_3945.accum_statistics.rx.cck; + accum_general = &priv->_3945.accum_statistics.rx.general; + delta_ofdm = &priv->_3945.delta_statistics.rx.ofdm; + delta_cck = &priv->_3945.delta_statistics.rx.cck; + delta_general = &priv->_3945.delta_statistics.rx.general; + max_ofdm = &priv->_3945.max_delta.rx.ofdm; + max_cck = &priv->_3945.max_delta.rx.cck; + max_general = &priv->_3945.max_delta.rx.general; + + pos += iwl3945_statistics_flag(priv, buf, bufsz); + pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" + "acumulative delta max\n", + "Statistics_Rx - OFDM:"); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "ina_cnt:", le32_to_cpu(ofdm->ina_cnt), + accum_ofdm->ina_cnt, + delta_ofdm->ina_cnt, max_ofdm->ina_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "fina_cnt:", + le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt, + delta_ofdm->fina_cnt, max_ofdm->fina_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", "plcp_err:", + le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err, + delta_ofdm->plcp_err, max_ofdm->plcp_err); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", "crc32_err:", + le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err, + delta_ofdm->crc32_err, max_ofdm->crc32_err); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", "overrun_err:", + le32_to_cpu(ofdm->overrun_err), + accum_ofdm->overrun_err, delta_ofdm->overrun_err, + max_ofdm->overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "early_overrun_err:", + le32_to_cpu(ofdm->early_overrun_err), + accum_ofdm->early_overrun_err, + delta_ofdm->early_overrun_err, + max_ofdm->early_overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "crc32_good:", le32_to_cpu(ofdm->crc32_good), + accum_ofdm->crc32_good, delta_ofdm->crc32_good, + max_ofdm->crc32_good); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", "false_alarm_cnt:", + le32_to_cpu(ofdm->false_alarm_cnt), + accum_ofdm->false_alarm_cnt, + delta_ofdm->false_alarm_cnt, + max_ofdm->false_alarm_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "fina_sync_err_cnt:", + le32_to_cpu(ofdm->fina_sync_err_cnt), + accum_ofdm->fina_sync_err_cnt, + delta_ofdm->fina_sync_err_cnt, + max_ofdm->fina_sync_err_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "sfd_timeout:", + le32_to_cpu(ofdm->sfd_timeout), + accum_ofdm->sfd_timeout, + delta_ofdm->sfd_timeout, + max_ofdm->sfd_timeout); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "fina_timeout:", + le32_to_cpu(ofdm->fina_timeout), + accum_ofdm->fina_timeout, + delta_ofdm->fina_timeout, + max_ofdm->fina_timeout); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "unresponded_rts:", + le32_to_cpu(ofdm->unresponded_rts), + accum_ofdm->unresponded_rts, + delta_ofdm->unresponded_rts, + max_ofdm->unresponded_rts); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "rxe_frame_lmt_ovrun:", + le32_to_cpu(ofdm->rxe_frame_limit_overrun), + accum_ofdm->rxe_frame_limit_overrun, + delta_ofdm->rxe_frame_limit_overrun, + max_ofdm->rxe_frame_limit_overrun); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "sent_ack_cnt:", + le32_to_cpu(ofdm->sent_ack_cnt), + accum_ofdm->sent_ack_cnt, + delta_ofdm->sent_ack_cnt, + max_ofdm->sent_ack_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "sent_cts_cnt:", + le32_to_cpu(ofdm->sent_cts_cnt), + accum_ofdm->sent_cts_cnt, + delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt); + + pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" + "acumulative delta max\n", + "Statistics_Rx - CCK:"); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "ina_cnt:", + le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt, + delta_cck->ina_cnt, max_cck->ina_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "fina_cnt:", + le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt, + delta_cck->fina_cnt, max_cck->fina_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "plcp_err:", + le32_to_cpu(cck->plcp_err), accum_cck->plcp_err, + delta_cck->plcp_err, max_cck->plcp_err); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "crc32_err:", + le32_to_cpu(cck->crc32_err), accum_cck->crc32_err, + delta_cck->crc32_err, max_cck->crc32_err); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "overrun_err:", + le32_to_cpu(cck->overrun_err), + accum_cck->overrun_err, + delta_cck->overrun_err, max_cck->overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "early_overrun_err:", + le32_to_cpu(cck->early_overrun_err), + accum_cck->early_overrun_err, + delta_cck->early_overrun_err, + max_cck->early_overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "crc32_good:", + le32_to_cpu(cck->crc32_good), accum_cck->crc32_good, + delta_cck->crc32_good, + max_cck->crc32_good); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "false_alarm_cnt:", + le32_to_cpu(cck->false_alarm_cnt), + accum_cck->false_alarm_cnt, + delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "fina_sync_err_cnt:", + le32_to_cpu(cck->fina_sync_err_cnt), + accum_cck->fina_sync_err_cnt, + delta_cck->fina_sync_err_cnt, + max_cck->fina_sync_err_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "sfd_timeout:", + le32_to_cpu(cck->sfd_timeout), + accum_cck->sfd_timeout, + delta_cck->sfd_timeout, max_cck->sfd_timeout); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "fina_timeout:", + le32_to_cpu(cck->fina_timeout), + accum_cck->fina_timeout, + delta_cck->fina_timeout, max_cck->fina_timeout); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "unresponded_rts:", + le32_to_cpu(cck->unresponded_rts), + accum_cck->unresponded_rts, + delta_cck->unresponded_rts, + max_cck->unresponded_rts); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "rxe_frame_lmt_ovrun:", + le32_to_cpu(cck->rxe_frame_limit_overrun), + accum_cck->rxe_frame_limit_overrun, + delta_cck->rxe_frame_limit_overrun, + max_cck->rxe_frame_limit_overrun); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "sent_ack_cnt:", + le32_to_cpu(cck->sent_ack_cnt), + accum_cck->sent_ack_cnt, + delta_cck->sent_ack_cnt, + max_cck->sent_ack_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "sent_cts_cnt:", + le32_to_cpu(cck->sent_cts_cnt), + accum_cck->sent_cts_cnt, + delta_cck->sent_cts_cnt, + max_cck->sent_cts_cnt); + + pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" + "acumulative delta max\n", + "Statistics_Rx - GENERAL:"); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "bogus_cts:", + le32_to_cpu(general->bogus_cts), + accum_general->bogus_cts, + delta_general->bogus_cts, max_general->bogus_cts); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "bogus_ack:", + le32_to_cpu(general->bogus_ack), + accum_general->bogus_ack, + delta_general->bogus_ack, max_general->bogus_ack); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "non_bssid_frames:", + le32_to_cpu(general->non_bssid_frames), + accum_general->non_bssid_frames, + delta_general->non_bssid_frames, + max_general->non_bssid_frames); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "filtered_frames:", + le32_to_cpu(general->filtered_frames), + accum_general->filtered_frames, + delta_general->filtered_frames, + max_general->filtered_frames); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "non_channel_beacons:", + le32_to_cpu(general->non_channel_beacons), + accum_general->non_channel_beacons, + delta_general->non_channel_beacons, + max_general->non_channel_beacons); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} + +ssize_t iwl3945_ucode_tx_stats_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + int pos = 0; + char *buf; + int bufsz = (sizeof(struct iwl39_statistics_tx) * 48) + 250; + ssize_t ret; + struct iwl39_statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; + + if (!iwl_is_alive(priv)) + return -EAGAIN; + + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate Buffer\n"); + return -ENOMEM; + } + + /* + * The statistic information display here is based on + * the last statistics notification from uCode + * might not reflect the current uCode activity + */ + tx = &priv->_3945.statistics.tx; + accum_tx = &priv->_3945.accum_statistics.tx; + delta_tx = &priv->_3945.delta_statistics.tx; + max_tx = &priv->_3945.max_delta.tx; + pos += iwl3945_statistics_flag(priv, buf, bufsz); + pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" + "acumulative delta max\n", + "Statistics_Tx:"); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "preamble:", + le32_to_cpu(tx->preamble_cnt), + accum_tx->preamble_cnt, + delta_tx->preamble_cnt, max_tx->preamble_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "rx_detected_cnt:", + le32_to_cpu(tx->rx_detected_cnt), + accum_tx->rx_detected_cnt, + delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "bt_prio_defer_cnt:", + le32_to_cpu(tx->bt_prio_defer_cnt), + accum_tx->bt_prio_defer_cnt, + delta_tx->bt_prio_defer_cnt, + max_tx->bt_prio_defer_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "bt_prio_kill_cnt:", + le32_to_cpu(tx->bt_prio_kill_cnt), + accum_tx->bt_prio_kill_cnt, + delta_tx->bt_prio_kill_cnt, + max_tx->bt_prio_kill_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "few_bytes_cnt:", + le32_to_cpu(tx->few_bytes_cnt), + accum_tx->few_bytes_cnt, + delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "cts_timeout:", + le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout, + delta_tx->cts_timeout, max_tx->cts_timeout); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "ack_timeout:", + le32_to_cpu(tx->ack_timeout), + accum_tx->ack_timeout, + delta_tx->ack_timeout, max_tx->ack_timeout); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "expected_ack_cnt:", + le32_to_cpu(tx->expected_ack_cnt), + accum_tx->expected_ack_cnt, + delta_tx->expected_ack_cnt, + max_tx->expected_ack_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "actual_ack_cnt:", + le32_to_cpu(tx->actual_ack_cnt), + accum_tx->actual_ack_cnt, + delta_tx->actual_ack_cnt, + max_tx->actual_ack_cnt); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} + +ssize_t iwl3945_ucode_general_stats_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + int pos = 0; + char *buf; + int bufsz = sizeof(struct iwl39_statistics_general) * 10 + 300; + ssize_t ret; + struct iwl39_statistics_general *general, *accum_general; + struct iwl39_statistics_general *delta_general, *max_general; + struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; + struct iwl39_statistics_div *div, *accum_div, *delta_div, *max_div; + + if (!iwl_is_alive(priv)) + return -EAGAIN; + + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate Buffer\n"); + return -ENOMEM; + } + + /* + * The statistic information display here is based on + * the last statistics notification from uCode + * might not reflect the current uCode activity + */ + general = &priv->_3945.statistics.general; + dbg = &priv->_3945.statistics.general.dbg; + div = &priv->_3945.statistics.general.div; + accum_general = &priv->_3945.accum_statistics.general; + delta_general = &priv->_3945.delta_statistics.general; + max_general = &priv->_3945.max_delta.general; + accum_dbg = &priv->_3945.accum_statistics.general.dbg; + delta_dbg = &priv->_3945.delta_statistics.general.dbg; + max_dbg = &priv->_3945.max_delta.general.dbg; + accum_div = &priv->_3945.accum_statistics.general.div; + delta_div = &priv->_3945.delta_statistics.general.div; + max_div = &priv->_3945.max_delta.general.div; + pos += iwl3945_statistics_flag(priv, buf, bufsz); + pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" + "acumulative delta max\n", + "Statistics_General:"); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "burst_check:", + le32_to_cpu(dbg->burst_check), + accum_dbg->burst_check, + delta_dbg->burst_check, max_dbg->burst_check); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "burst_count:", + le32_to_cpu(dbg->burst_count), + accum_dbg->burst_count, + delta_dbg->burst_count, max_dbg->burst_count); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "sleep_time:", + le32_to_cpu(general->sleep_time), + accum_general->sleep_time, + delta_general->sleep_time, max_general->sleep_time); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "slots_out:", + le32_to_cpu(general->slots_out), + accum_general->slots_out, + delta_general->slots_out, max_general->slots_out); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "slots_idle:", + le32_to_cpu(general->slots_idle), + accum_general->slots_idle, + delta_general->slots_idle, max_general->slots_idle); + pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n", + le32_to_cpu(general->ttl_timestamp)); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "tx_on_a:", + le32_to_cpu(div->tx_on_a), accum_div->tx_on_a, + delta_div->tx_on_a, max_div->tx_on_a); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "tx_on_b:", + le32_to_cpu(div->tx_on_b), accum_div->tx_on_b, + delta_div->tx_on_b, max_div->tx_on_b); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "exec_time:", + le32_to_cpu(div->exec_time), accum_div->exec_time, + delta_div->exec_time, max_div->exec_time); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "probe_time:", + le32_to_cpu(div->probe_time), accum_div->probe_time, + delta_div->probe_time, max_div->probe_time); + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h new file mode 100644 index 000000000000..70809c53c215 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h @@ -0,0 +1,60 @@ +/****************************************************************************** + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ + +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-debug.h" + +#ifdef CONFIG_IWLWIFI_DEBUGFS +ssize_t iwl3945_ucode_rx_stats_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos); +ssize_t iwl3945_ucode_tx_stats_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos); +ssize_t iwl3945_ucode_general_stats_read(struct file *file, + char __user *user_buf, size_t count, + loff_t *ppos); +#else +static ssize_t iwl3945_ucode_rx_stats_read(struct file *file, + char __user *user_buf, size_t count, + loff_t *ppos) +{ + return 0; +} +static ssize_t iwl3945_ucode_tx_stats_read(struct file *file, + char __user *user_buf, size_t count, + loff_t *ppos) +{ + return 0; +} +static ssize_t iwl3945_ucode_general_stats_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + return 0; +} +#endif diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-fh.h b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h new file mode 100644 index 000000000000..2c9ed2b502a3 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h @@ -0,0 +1,188 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#ifndef __iwl_3945_fh_h__ +#define __iwl_3945_fh_h__ + +/************************************/ +/* iwl3945 Flow Handler Definitions */ +/************************************/ + +/** + * This I/O area is directly read/writable by driver (e.g. Linux uses writel()) + * Addresses are offsets from device's PCI hardware base address. + */ +#define FH39_MEM_LOWER_BOUND (0x0800) +#define FH39_MEM_UPPER_BOUND (0x1000) + +#define FH39_CBCC_TABLE (FH39_MEM_LOWER_BOUND + 0x140) +#define FH39_TFDB_TABLE (FH39_MEM_LOWER_BOUND + 0x180) +#define FH39_RCSR_TABLE (FH39_MEM_LOWER_BOUND + 0x400) +#define FH39_RSSR_TABLE (FH39_MEM_LOWER_BOUND + 0x4c0) +#define FH39_TCSR_TABLE (FH39_MEM_LOWER_BOUND + 0x500) +#define FH39_TSSR_TABLE (FH39_MEM_LOWER_BOUND + 0x680) + +/* TFDB (Transmit Frame Buffer Descriptor) */ +#define FH39_TFDB(_ch, buf) (FH39_TFDB_TABLE + \ + ((_ch) * 2 + (buf)) * 0x28) +#define FH39_TFDB_CHNL_BUF_CTRL_REG(_ch) (FH39_TFDB_TABLE + 0x50 * (_ch)) + +/* CBCC channel is [0,2] */ +#define FH39_CBCC(_ch) (FH39_CBCC_TABLE + (_ch) * 0x8) +#define FH39_CBCC_CTRL(_ch) (FH39_CBCC(_ch) + 0x00) +#define FH39_CBCC_BASE(_ch) (FH39_CBCC(_ch) + 0x04) + +/* RCSR channel is [0,2] */ +#define FH39_RCSR(_ch) (FH39_RCSR_TABLE + (_ch) * 0x40) +#define FH39_RCSR_CONFIG(_ch) (FH39_RCSR(_ch) + 0x00) +#define FH39_RCSR_RBD_BASE(_ch) (FH39_RCSR(_ch) + 0x04) +#define FH39_RCSR_WPTR(_ch) (FH39_RCSR(_ch) + 0x20) +#define FH39_RCSR_RPTR_ADDR(_ch) (FH39_RCSR(_ch) + 0x24) + +#define FH39_RSCSR_CHNL0_WPTR (FH39_RCSR_WPTR(0)) + +/* RSSR */ +#define FH39_RSSR_CTRL (FH39_RSSR_TABLE + 0x000) +#define FH39_RSSR_STATUS (FH39_RSSR_TABLE + 0x004) + +/* TCSR */ +#define FH39_TCSR(_ch) (FH39_TCSR_TABLE + (_ch) * 0x20) +#define FH39_TCSR_CONFIG(_ch) (FH39_TCSR(_ch) + 0x00) +#define FH39_TCSR_CREDIT(_ch) (FH39_TCSR(_ch) + 0x04) +#define FH39_TCSR_BUFF_STTS(_ch) (FH39_TCSR(_ch) + 0x08) + +/* TSSR */ +#define FH39_TSSR_CBB_BASE (FH39_TSSR_TABLE + 0x000) +#define FH39_TSSR_MSG_CONFIG (FH39_TSSR_TABLE + 0x008) +#define FH39_TSSR_TX_STATUS (FH39_TSSR_TABLE + 0x010) + + +/* DBM */ + +#define FH39_SRVC_CHNL (6) + +#define FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE (20) +#define FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH (4) + +#define FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN (0x08000000) + +#define FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE (0x80000000) + +#define FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE (0x20000000) + +#define FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 (0x01000000) + +#define FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST (0x00001000) + +#define FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH (0x00000000) + +#define FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF (0x00000000) +#define FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER (0x00000001) + +#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000) +#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008) + +#define FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD (0x00200000) + +#define FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT (0x00000000) + +#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000) +#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000) + +#define FH39_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID (0x00004000) + +#define FH39_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR (0x00000001) + +#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON (0xFF000000) +#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON (0x00FF0000) + +#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B (0x00000400) + +#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON (0x00000100) +#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON (0x00000080) + +#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH (0x00000020) +#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH (0x00000005) + +#define FH39_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_ch) (BIT(_ch) << 24) +#define FH39_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_ch) (BIT(_ch) << 16) + +#define FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_ch) \ + (FH39_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_ch) | \ + FH39_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_ch)) + +#define FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000) + +struct iwl3945_tfd_tb { + __le32 addr; + __le32 len; +} __packed; + +struct iwl3945_tfd { + __le32 control_flags; + struct iwl3945_tfd_tb tbs[4]; + u8 __pad[28]; +} __packed; + + +#endif /* __iwl_3945_fh_h__ */ + diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h new file mode 100644 index 000000000000..65b5834da28c --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h @@ -0,0 +1,294 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Please use this file (iwl-3945-hw.h) only for hardware-related definitions. + * Please use iwl-commands.h for uCode API definitions. + * Please use iwl-3945.h for driver implementation definitions. + */ + +#ifndef __iwl_3945_hw__ +#define __iwl_3945_hw__ + +#include "iwl-eeprom.h" + +/* RSSI to dBm */ +#define IWL39_RSSI_OFFSET 95 + +#define IWL_DEFAULT_TX_POWER 0x0F + +/* + * EEPROM related constants, enums, and structures. + */ +#define EEPROM_SKU_CAP_OP_MODE_MRC (1 << 7) + +/* + * Mapping of a Tx power level, at factory calibration temperature, + * to a radio/DSP gain table index. + * One for each of 5 "sample" power levels in each band. + * v_det is measured at the factory, using the 3945's built-in power amplifier + * (PA) output voltage detector. This same detector is used during Tx of + * long packets in normal operation to provide feedback as to proper output + * level. + * Data copied from EEPROM. + * DO NOT ALTER THIS STRUCTURE!!! + */ +struct iwl3945_eeprom_txpower_sample { + u8 gain_index; /* index into power (gain) setup table ... */ + s8 power; /* ... for this pwr level for this chnl group */ + u16 v_det; /* PA output voltage */ +} __packed; + +/* + * Mappings of Tx power levels -> nominal radio/DSP gain table indexes. + * One for each channel group (a.k.a. "band") (1 for BG, 4 for A). + * Tx power setup code interpolates between the 5 "sample" power levels + * to determine the nominal setup for a requested power level. + * Data copied from EEPROM. + * DO NOT ALTER THIS STRUCTURE!!! + */ +struct iwl3945_eeprom_txpower_group { + struct iwl3945_eeprom_txpower_sample samples[5]; /* 5 power levels */ + s32 a, b, c, d, e; /* coefficients for voltage->power + * formula (signed) */ + s32 Fa, Fb, Fc, Fd, Fe; /* these modify coeffs based on + * frequency (signed) */ + s8 saturation_power; /* highest power possible by h/w in this + * band */ + u8 group_channel; /* "representative" channel # in this band */ + s16 temperature; /* h/w temperature at factory calib this band + * (signed) */ +} __packed; + +/* + * Temperature-based Tx-power compensation data, not band-specific. + * These coefficients are use to modify a/b/c/d/e coeffs based on + * difference between current temperature and factory calib temperature. + * Data copied from EEPROM. + */ +struct iwl3945_eeprom_temperature_corr { + u32 Ta; + u32 Tb; + u32 Tc; + u32 Td; + u32 Te; +} __packed; + +/* + * EEPROM map + */ +struct iwl3945_eeprom { + u8 reserved0[16]; + u16 device_id; /* abs.ofs: 16 */ + u8 reserved1[2]; + u16 pmc; /* abs.ofs: 20 */ + u8 reserved2[20]; + u8 mac_address[6]; /* abs.ofs: 42 */ + u8 reserved3[58]; + u16 board_revision; /* abs.ofs: 106 */ + u8 reserved4[11]; + u8 board_pba_number[9]; /* abs.ofs: 119 */ + u8 reserved5[8]; + u16 version; /* abs.ofs: 136 */ + u8 sku_cap; /* abs.ofs: 138 */ + u8 leds_mode; /* abs.ofs: 139 */ + u16 oem_mode; + u16 wowlan_mode; /* abs.ofs: 142 */ + u16 leds_time_interval; /* abs.ofs: 144 */ + u8 leds_off_time; /* abs.ofs: 146 */ + u8 leds_on_time; /* abs.ofs: 147 */ + u8 almgor_m_version; /* abs.ofs: 148 */ + u8 antenna_switch_type; /* abs.ofs: 149 */ + u8 reserved6[42]; + u8 sku_id[4]; /* abs.ofs: 192 */ + +/* + * Per-channel regulatory data. + * + * Each channel that *might* be supported by 3945 or 4965 has a fixed location + * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory + * txpower (MSB). + * + * Entries immediately below are for 20 MHz channel width. HT40 (40 MHz) + * channels (only for 4965, not supported by 3945) appear later in the EEPROM. + * + * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 + */ + u16 band_1_count; /* abs.ofs: 196 */ + struct iwl_eeprom_channel band_1_channels[14]; /* abs.ofs: 198 */ + +/* + * 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196, + * 5.0 GHz channels 7, 8, 11, 12, 16 + * (4915-5080MHz) (none of these is ever supported) + */ + u16 band_2_count; /* abs.ofs: 226 */ + struct iwl_eeprom_channel band_2_channels[13]; /* abs.ofs: 228 */ + +/* + * 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 + * (5170-5320MHz) + */ + u16 band_3_count; /* abs.ofs: 254 */ + struct iwl_eeprom_channel band_3_channels[12]; /* abs.ofs: 256 */ + +/* + * 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 + * (5500-5700MHz) + */ + u16 band_4_count; /* abs.ofs: 280 */ + struct iwl_eeprom_channel band_4_channels[11]; /* abs.ofs: 282 */ + +/* + * 5.7 GHz channels 145, 149, 153, 157, 161, 165 + * (5725-5825MHz) + */ + u16 band_5_count; /* abs.ofs: 304 */ + struct iwl_eeprom_channel band_5_channels[6]; /* abs.ofs: 306 */ + + u8 reserved9[194]; + +/* + * 3945 Txpower calibration data. + */ +#define IWL_NUM_TX_CALIB_GROUPS 5 + struct iwl3945_eeprom_txpower_group groups[IWL_NUM_TX_CALIB_GROUPS]; +/* abs.ofs: 512 */ + struct iwl3945_eeprom_temperature_corr corrections; /* abs.ofs: 832 */ + u8 reserved16[172]; /* fill out to full 1024 byte block */ +} __packed; + +#define IWL3945_EEPROM_IMG_SIZE 1024 + +/* End of EEPROM */ + +#define PCI_CFG_REV_ID_BIT_BASIC_SKU (0x40) /* bit 6 */ +#define PCI_CFG_REV_ID_BIT_RTP (0x80) /* bit 7 */ + +/* 4 DATA + 1 CMD. There are 2 HCCA queues that are not used. */ +#define IWL39_NUM_QUEUES 5 +#define IWL39_CMD_QUEUE_NUM 4 + +#define IWL_DEFAULT_TX_RETRY 15 + +/*********************************************/ + +#define RFD_SIZE 4 +#define NUM_TFD_CHUNKS 4 + +#define RX_QUEUE_SIZE 256 +#define RX_QUEUE_MASK 255 +#define RX_QUEUE_SIZE_LOG 8 + +#define U32_PAD(n) ((4-(n))&0x3) + +#define TFD_CTL_COUNT_SET(n) (n << 24) +#define TFD_CTL_COUNT_GET(ctl) ((ctl >> 24) & 7) +#define TFD_CTL_PAD_SET(n) (n << 28) +#define TFD_CTL_PAD_GET(ctl) (ctl >> 28) + +/* Sizes and addresses for instruction and data memory (SRAM) in + * 3945's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ +#define IWL39_RTC_INST_LOWER_BOUND (0x000000) +#define IWL39_RTC_INST_UPPER_BOUND (0x014000) + +#define IWL39_RTC_DATA_LOWER_BOUND (0x800000) +#define IWL39_RTC_DATA_UPPER_BOUND (0x808000) + +#define IWL39_RTC_INST_SIZE (IWL39_RTC_INST_UPPER_BOUND - \ + IWL39_RTC_INST_LOWER_BOUND) +#define IWL39_RTC_DATA_SIZE (IWL39_RTC_DATA_UPPER_BOUND - \ + IWL39_RTC_DATA_LOWER_BOUND) + +#define IWL39_MAX_INST_SIZE IWL39_RTC_INST_SIZE +#define IWL39_MAX_DATA_SIZE IWL39_RTC_DATA_SIZE + +/* Size of uCode instruction memory in bootstrap state machine */ +#define IWL39_MAX_BSM_SIZE IWL39_RTC_INST_SIZE + +static inline int iwl3945_hw_valid_rtc_data_addr(u32 addr) +{ + return (addr >= IWL39_RTC_DATA_LOWER_BOUND) && + (addr < IWL39_RTC_DATA_UPPER_BOUND); +} + +/* Base physical address of iwl3945_shared is provided to FH_TSSR_CBB_BASE + * and &iwl3945_shared.rx_read_ptr[0] is provided to FH_RCSR_RPTR_ADDR(0) */ +struct iwl3945_shared { + __le32 tx_base_ptr[8]; +} __packed; + +static inline u8 iwl3945_hw_get_rate(__le16 rate_n_flags) +{ + return le16_to_cpu(rate_n_flags) & 0xFF; +} + +static inline u16 iwl3945_hw_get_rate_n_flags(__le16 rate_n_flags) +{ + return le16_to_cpu(rate_n_flags); +} + +static inline __le16 iwl3945_hw_set_rate_n_flags(u8 rate, u16 flags) +{ + return cpu_to_le16((u16)rate|flags); +} +#endif diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c new file mode 100644 index 000000000000..dc7c3a4167a9 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c @@ -0,0 +1,64 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iwl-commands.h" +#include "iwl-3945.h" +#include "iwl-core.h" +#include "iwl-dev.h" +#include "iwl-3945-led.h" + + +/* Send led command */ +static int iwl3945_send_led_cmd(struct iwl_priv *priv, + struct iwl_led_cmd *led_cmd) +{ + struct iwl_host_cmd cmd = { + .id = REPLY_LEDS_CMD, + .len = sizeof(struct iwl_led_cmd), + .data = led_cmd, + .flags = CMD_ASYNC, + .callback = NULL, + }; + + return iwl_send_cmd(priv, &cmd); +} + +const struct iwl_led_ops iwl3945_led_ops = { + .cmd = iwl3945_send_led_cmd, +}; diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.h b/drivers/net/wireless/iwlwifi/iwl-3945-led.h new file mode 100644 index 000000000000..ce990adc51e7 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.h @@ -0,0 +1,32 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#ifndef __iwl_3945_led_h__ +#define __iwl_3945_led_h__ + +extern const struct iwl_led_ops iwl3945_led_ops; + +#endif /* __iwl_3945_led_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c new file mode 100644 index 000000000000..1f3e7e34fbc7 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c @@ -0,0 +1,995 @@ +/****************************************************************************** + * + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "iwl-commands.h" +#include "iwl-3945.h" +#include "iwl-sta.h" + +#define RS_NAME "iwl-3945-rs" + +static s32 iwl3945_expected_tpt_g[IWL_RATE_COUNT_3945] = { + 7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202 +}; + +static s32 iwl3945_expected_tpt_g_prot[IWL_RATE_COUNT_3945] = { + 7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125 +}; + +static s32 iwl3945_expected_tpt_a[IWL_RATE_COUNT_3945] = { + 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186 +}; + +static s32 iwl3945_expected_tpt_b[IWL_RATE_COUNT_3945] = { + 7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +struct iwl3945_tpt_entry { + s8 min_rssi; + u8 index; +}; + +static struct iwl3945_tpt_entry iwl3945_tpt_table_a[] = { + {-60, IWL_RATE_54M_INDEX}, + {-64, IWL_RATE_48M_INDEX}, + {-72, IWL_RATE_36M_INDEX}, + {-80, IWL_RATE_24M_INDEX}, + {-84, IWL_RATE_18M_INDEX}, + {-85, IWL_RATE_12M_INDEX}, + {-87, IWL_RATE_9M_INDEX}, + {-89, IWL_RATE_6M_INDEX} +}; + +static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = { + {-60, IWL_RATE_54M_INDEX}, + {-64, IWL_RATE_48M_INDEX}, + {-68, IWL_RATE_36M_INDEX}, + {-80, IWL_RATE_24M_INDEX}, + {-84, IWL_RATE_18M_INDEX}, + {-85, IWL_RATE_12M_INDEX}, + {-86, IWL_RATE_11M_INDEX}, + {-88, IWL_RATE_5M_INDEX}, + {-90, IWL_RATE_2M_INDEX}, + {-92, IWL_RATE_1M_INDEX} +}; + +#define IWL_RATE_MAX_WINDOW 62 +#define IWL_RATE_FLUSH (3*HZ) +#define IWL_RATE_WIN_FLUSH (HZ/2) +#define IWL39_RATE_HIGH_TH 11520 +#define IWL_SUCCESS_UP_TH 8960 +#define IWL_SUCCESS_DOWN_TH 10880 +#define IWL_RATE_MIN_FAILURE_TH 6 +#define IWL_RATE_MIN_SUCCESS_TH 8 +#define IWL_RATE_DECREASE_TH 1920 +#define IWL_RATE_RETRY_TH 15 + +static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, enum ieee80211_band band) +{ + u32 index = 0; + u32 table_size = 0; + struct iwl3945_tpt_entry *tpt_table = NULL; + + if ((rssi < IWL_MIN_RSSI_VAL) || (rssi > IWL_MAX_RSSI_VAL)) + rssi = IWL_MIN_RSSI_VAL; + + switch (band) { + case IEEE80211_BAND_2GHZ: + tpt_table = iwl3945_tpt_table_g; + table_size = ARRAY_SIZE(iwl3945_tpt_table_g); + break; + + case IEEE80211_BAND_5GHZ: + tpt_table = iwl3945_tpt_table_a; + table_size = ARRAY_SIZE(iwl3945_tpt_table_a); + break; + + default: + BUG(); + break; + } + + while ((index < table_size) && (rssi < tpt_table[index].min_rssi)) + index++; + + index = min(index, (table_size - 1)); + + return tpt_table[index].index; +} + +static void iwl3945_clear_window(struct iwl3945_rate_scale_data *window) +{ + window->data = 0; + window->success_counter = 0; + window->success_ratio = -1; + window->counter = 0; + window->average_tpt = IWL_INVALID_VALUE; + window->stamp = 0; +} + +/** + * iwl3945_rate_scale_flush_windows - flush out the rate scale windows + * + * Returns the number of windows that have gathered data but were + * not flushed. If there were any that were not flushed, then + * reschedule the rate flushing routine. + */ +static int iwl3945_rate_scale_flush_windows(struct iwl3945_rs_sta *rs_sta) +{ + int unflushed = 0; + int i; + unsigned long flags; + struct iwl_priv *priv __maybe_unused = rs_sta->priv; + + /* + * For each rate, if we have collected data on that rate + * and it has been more than IWL_RATE_WIN_FLUSH + * since we flushed, clear out the gathered statistics + */ + for (i = 0; i < IWL_RATE_COUNT_3945; i++) { + if (!rs_sta->win[i].counter) + continue; + + spin_lock_irqsave(&rs_sta->lock, flags); + if (time_after(jiffies, rs_sta->win[i].stamp + + IWL_RATE_WIN_FLUSH)) { + IWL_DEBUG_RATE(priv, "flushing %d samples of rate " + "index %d\n", + rs_sta->win[i].counter, i); + iwl3945_clear_window(&rs_sta->win[i]); + } else + unflushed++; + spin_unlock_irqrestore(&rs_sta->lock, flags); + } + + return unflushed; +} + +#define IWL_RATE_FLUSH_MAX 5000 /* msec */ +#define IWL_RATE_FLUSH_MIN 50 /* msec */ +#define IWL_AVERAGE_PACKETS 1500 + +static void iwl3945_bg_rate_scale_flush(unsigned long data) +{ + struct iwl3945_rs_sta *rs_sta = (void *)data; + struct iwl_priv *priv __maybe_unused = rs_sta->priv; + int unflushed = 0; + unsigned long flags; + u32 packet_count, duration, pps; + + IWL_DEBUG_RATE(priv, "enter\n"); + + unflushed = iwl3945_rate_scale_flush_windows(rs_sta); + + spin_lock_irqsave(&rs_sta->lock, flags); + + /* Number of packets Rx'd since last time this timer ran */ + packet_count = (rs_sta->tx_packets - rs_sta->last_tx_packets) + 1; + + rs_sta->last_tx_packets = rs_sta->tx_packets + 1; + + if (unflushed) { + duration = + jiffies_to_msecs(jiffies - rs_sta->last_partial_flush); + + IWL_DEBUG_RATE(priv, "Tx'd %d packets in %dms\n", + packet_count, duration); + + /* Determine packets per second */ + if (duration) + pps = (packet_count * 1000) / duration; + else + pps = 0; + + if (pps) { + duration = (IWL_AVERAGE_PACKETS * 1000) / pps; + if (duration < IWL_RATE_FLUSH_MIN) + duration = IWL_RATE_FLUSH_MIN; + else if (duration > IWL_RATE_FLUSH_MAX) + duration = IWL_RATE_FLUSH_MAX; + } else + duration = IWL_RATE_FLUSH_MAX; + + rs_sta->flush_time = msecs_to_jiffies(duration); + + IWL_DEBUG_RATE(priv, "new flush period: %d msec ave %d\n", + duration, packet_count); + + mod_timer(&rs_sta->rate_scale_flush, jiffies + + rs_sta->flush_time); + + rs_sta->last_partial_flush = jiffies; + } else { + rs_sta->flush_time = IWL_RATE_FLUSH; + rs_sta->flush_pending = 0; + } + /* If there weren't any unflushed entries, we don't schedule the timer + * to run again */ + + rs_sta->last_flush = jiffies; + + spin_unlock_irqrestore(&rs_sta->lock, flags); + + IWL_DEBUG_RATE(priv, "leave\n"); +} + +/** + * iwl3945_collect_tx_data - Update the success/failure sliding window + * + * We keep a sliding window of the last 64 packets transmitted + * at this rate. window->data contains the bitmask of successful + * packets. + */ +static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta, + struct iwl3945_rate_scale_data *window, + int success, int retries, int index) +{ + unsigned long flags; + s32 fail_count; + struct iwl_priv *priv __maybe_unused = rs_sta->priv; + + if (!retries) { + IWL_DEBUG_RATE(priv, "leave: retries == 0 -- should be at least 1\n"); + return; + } + + spin_lock_irqsave(&rs_sta->lock, flags); + + /* + * Keep track of only the latest 62 tx frame attempts in this rate's + * history window; anything older isn't really relevant any more. + * If we have filled up the sliding window, drop the oldest attempt; + * if the oldest attempt (highest bit in bitmap) shows "success", + * subtract "1" from the success counter (this is the main reason + * we keep these bitmaps!). + * */ + while (retries > 0) { + if (window->counter >= IWL_RATE_MAX_WINDOW) { + + /* remove earliest */ + window->counter = IWL_RATE_MAX_WINDOW - 1; + + if (window->data & (1ULL << (IWL_RATE_MAX_WINDOW - 1))) { + window->data &= ~(1ULL << (IWL_RATE_MAX_WINDOW - 1)); + window->success_counter--; + } + } + + /* Increment frames-attempted counter */ + window->counter++; + + /* Shift bitmap by one frame (throw away oldest history), + * OR in "1", and increment "success" if this + * frame was successful. */ + window->data <<= 1; + if (success > 0) { + window->success_counter++; + window->data |= 0x1; + success--; + } + + retries--; + } + + /* Calculate current success ratio, avoid divide-by-0! */ + if (window->counter > 0) + window->success_ratio = 128 * (100 * window->success_counter) + / window->counter; + else + window->success_ratio = IWL_INVALID_VALUE; + + fail_count = window->counter - window->success_counter; + + /* Calculate average throughput, if we have enough history. */ + if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) || + (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH)) + window->average_tpt = ((window->success_ratio * + rs_sta->expected_tpt[index] + 64) / 128); + else + window->average_tpt = IWL_INVALID_VALUE; + + /* Tag this window as having been updated */ + window->stamp = jiffies; + + spin_unlock_irqrestore(&rs_sta->lock, flags); + +} + +/* + * Called after adding a new station to initialize rate scaling + */ +void iwl3945_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_id) +{ + struct ieee80211_hw *hw = priv->hw; + struct ieee80211_conf *conf = &priv->hw->conf; + struct iwl3945_sta_priv *psta; + struct iwl3945_rs_sta *rs_sta; + struct ieee80211_supported_band *sband; + int i; + + IWL_DEBUG_INFO(priv, "enter\n"); + if (sta_id == priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id) + goto out; + + psta = (struct iwl3945_sta_priv *) sta->drv_priv; + rs_sta = &psta->rs_sta; + sband = hw->wiphy->bands[conf->channel->band]; + + rs_sta->priv = priv; + + rs_sta->start_rate = IWL_RATE_INVALID; + + /* default to just 802.11b */ + rs_sta->expected_tpt = iwl3945_expected_tpt_b; + + rs_sta->last_partial_flush = jiffies; + rs_sta->last_flush = jiffies; + rs_sta->flush_time = IWL_RATE_FLUSH; + rs_sta->last_tx_packets = 0; + + rs_sta->rate_scale_flush.data = (unsigned long)rs_sta; + rs_sta->rate_scale_flush.function = iwl3945_bg_rate_scale_flush; + + for (i = 0; i < IWL_RATE_COUNT_3945; i++) + iwl3945_clear_window(&rs_sta->win[i]); + + /* TODO: what is a good starting rate for STA? About middle? Maybe not + * the lowest or the highest rate.. Could consider using RSSI from + * previous packets? Need to have IEEE 802.1X auth succeed immediately + * after assoc.. */ + + for (i = sband->n_bitrates - 1; i >= 0; i--) { + if (sta->supp_rates[sband->band] & (1 << i)) { + rs_sta->last_txrate_idx = i; + break; + } + } + + priv->_3945.sta_supp_rates = sta->supp_rates[sband->band]; + /* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */ + if (sband->band == IEEE80211_BAND_5GHZ) { + rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; + priv->_3945.sta_supp_rates = priv->_3945.sta_supp_rates << + IWL_FIRST_OFDM_RATE; + } + +out: + priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; + + IWL_DEBUG_INFO(priv, "leave\n"); +} + +static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) +{ + return hw->priv; +} + +/* rate scale requires free function to be implemented */ +static void rs_free(void *priv) +{ + return; +} + +static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp) +{ + struct iwl3945_rs_sta *rs_sta; + struct iwl3945_sta_priv *psta = (void *) sta->drv_priv; + struct iwl_priv *priv __maybe_unused = iwl_priv; + + IWL_DEBUG_RATE(priv, "enter\n"); + + rs_sta = &psta->rs_sta; + + spin_lock_init(&rs_sta->lock); + init_timer(&rs_sta->rate_scale_flush); + + IWL_DEBUG_RATE(priv, "leave\n"); + + return rs_sta; +} + +static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta, + void *priv_sta) +{ + struct iwl3945_rs_sta *rs_sta = priv_sta; + + /* + * Be careful not to use any members of iwl3945_rs_sta (like trying + * to use iwl_priv to print out debugging) since it may not be fully + * initialized at this point. + */ + del_timer_sync(&rs_sta->rate_scale_flush); +} + + +/** + * rs_tx_status - Update rate control values based on Tx results + * + * NOTE: Uses iwl_priv->retry_rate for the # of retries attempted by + * the hardware for each rate. + */ +static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta, + struct sk_buff *skb) +{ + s8 retries = 0, current_count; + int scale_rate_index, first_index, last_index; + unsigned long flags; + struct iwl_priv *priv = (struct iwl_priv *)priv_rate; + struct iwl3945_rs_sta *rs_sta = priv_sta; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + + IWL_DEBUG_RATE(priv, "enter\n"); + + retries = info->status.rates[0].count; + /* Sanity Check for retries */ + if (retries > IWL_RATE_RETRY_TH) + retries = IWL_RATE_RETRY_TH; + + first_index = sband->bitrates[info->status.rates[0].idx].hw_value; + if ((first_index < 0) || (first_index >= IWL_RATE_COUNT_3945)) { + IWL_DEBUG_RATE(priv, "leave: Rate out of bounds: %d\n", first_index); + return; + } + + if (!priv_sta) { + IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n"); + return; + } + + /* Treat uninitialized rate scaling data same as non-existing. */ + if (!rs_sta->priv) { + IWL_DEBUG_RATE(priv, "leave: STA priv data uninitialized!\n"); + return; + } + + + rs_sta->tx_packets++; + + scale_rate_index = first_index; + last_index = first_index; + + /* + * Update the window for each rate. We determine which rates + * were Tx'd based on the total number of retries vs. the number + * of retries configured for each rate -- currently set to the + * priv value 'retry_rate' vs. rate specific + * + * On exit from this while loop last_index indicates the rate + * at which the frame was finally transmitted (or failed if no + * ACK) + */ + while (retries > 1) { + if ((retries - 1) < priv->retry_rate) { + current_count = (retries - 1); + last_index = scale_rate_index; + } else { + current_count = priv->retry_rate; + last_index = iwl3945_rs_next_rate(priv, + scale_rate_index); + } + + /* Update this rate accounting for as many retries + * as was used for it (per current_count) */ + iwl3945_collect_tx_data(rs_sta, + &rs_sta->win[scale_rate_index], + 0, current_count, scale_rate_index); + IWL_DEBUG_RATE(priv, "Update rate %d for %d retries.\n", + scale_rate_index, current_count); + + retries -= current_count; + + scale_rate_index = last_index; + } + + + /* Update the last index window with success/failure based on ACK */ + IWL_DEBUG_RATE(priv, "Update rate %d with %s.\n", + last_index, + (info->flags & IEEE80211_TX_STAT_ACK) ? + "success" : "failure"); + iwl3945_collect_tx_data(rs_sta, + &rs_sta->win[last_index], + info->flags & IEEE80211_TX_STAT_ACK, 1, last_index); + + /* We updated the rate scale window -- if its been more than + * flush_time since the last run, schedule the flush + * again */ + spin_lock_irqsave(&rs_sta->lock, flags); + + if (!rs_sta->flush_pending && + time_after(jiffies, rs_sta->last_flush + + rs_sta->flush_time)) { + + rs_sta->last_partial_flush = jiffies; + rs_sta->flush_pending = 1; + mod_timer(&rs_sta->rate_scale_flush, + jiffies + rs_sta->flush_time); + } + + spin_unlock_irqrestore(&rs_sta->lock, flags); + + IWL_DEBUG_RATE(priv, "leave\n"); +} + +static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, + u8 index, u16 rate_mask, enum ieee80211_band band) +{ + u8 high = IWL_RATE_INVALID; + u8 low = IWL_RATE_INVALID; + struct iwl_priv *priv __maybe_unused = rs_sta->priv; + + /* 802.11A walks to the next literal adjacent rate in + * the rate table */ + if (unlikely(band == IEEE80211_BAND_5GHZ)) { + int i; + u32 mask; + + /* Find the previous rate that is in the rate mask */ + i = index - 1; + for (mask = (1 << i); i >= 0; i--, mask >>= 1) { + if (rate_mask & mask) { + low = i; + break; + } + } + + /* Find the next rate that is in the rate mask */ + i = index + 1; + for (mask = (1 << i); i < IWL_RATE_COUNT_3945; + i++, mask <<= 1) { + if (rate_mask & mask) { + high = i; + break; + } + } + + return (high << 8) | low; + } + + low = index; + while (low != IWL_RATE_INVALID) { + if (rs_sta->tgg) + low = iwl3945_rates[low].prev_rs_tgg; + else + low = iwl3945_rates[low].prev_rs; + if (low == IWL_RATE_INVALID) + break; + if (rate_mask & (1 << low)) + break; + IWL_DEBUG_RATE(priv, "Skipping masked lower rate: %d\n", low); + } + + high = index; + while (high != IWL_RATE_INVALID) { + if (rs_sta->tgg) + high = iwl3945_rates[high].next_rs_tgg; + else + high = iwl3945_rates[high].next_rs; + if (high == IWL_RATE_INVALID) + break; + if (rate_mask & (1 << high)) + break; + IWL_DEBUG_RATE(priv, "Skipping masked higher rate: %d\n", high); + } + + return (high << 8) | low; +} + +/** + * rs_get_rate - find the rate for the requested packet + * + * Returns the ieee80211_rate structure allocated by the driver. + * + * The rate control algorithm has no internal mapping between hw_mode's + * rate ordering and the rate ordering used by the rate control algorithm. + * + * The rate control algorithm uses a single table of rates that goes across + * the entire A/B/G spectrum vs. being limited to just one particular + * hw_mode. + * + * As such, we can't convert the index obtained below into the hw_mode's + * rate table and must reference the driver allocated rate table + * + */ +static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, + void *priv_sta, struct ieee80211_tx_rate_control *txrc) +{ + struct ieee80211_supported_band *sband = txrc->sband; + struct sk_buff *skb = txrc->skb; + u8 low = IWL_RATE_INVALID; + u8 high = IWL_RATE_INVALID; + u16 high_low; + int index; + struct iwl3945_rs_sta *rs_sta = priv_sta; + struct iwl3945_rate_scale_data *window = NULL; + int current_tpt = IWL_INVALID_VALUE; + int low_tpt = IWL_INVALID_VALUE; + int high_tpt = IWL_INVALID_VALUE; + u32 fail_count; + s8 scale_action = 0; + unsigned long flags; + u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0; + s8 max_rate_idx = -1; + struct iwl_priv *priv __maybe_unused = (struct iwl_priv *)priv_r; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + + IWL_DEBUG_RATE(priv, "enter\n"); + + /* Treat uninitialized rate scaling data same as non-existing. */ + if (rs_sta && !rs_sta->priv) { + IWL_DEBUG_RATE(priv, "Rate scaling information not initialized yet.\n"); + priv_sta = NULL; + } + + if (rate_control_send_low(sta, priv_sta, txrc)) + return; + + rate_mask = sta->supp_rates[sband->band]; + + /* get user max rate if set */ + max_rate_idx = txrc->max_rate_idx; + if ((sband->band == IEEE80211_BAND_5GHZ) && (max_rate_idx != -1)) + max_rate_idx += IWL_FIRST_OFDM_RATE; + if ((max_rate_idx < 0) || (max_rate_idx >= IWL_RATE_COUNT)) + max_rate_idx = -1; + + index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT_3945 - 1); + + if (sband->band == IEEE80211_BAND_5GHZ) + rate_mask = rate_mask << IWL_FIRST_OFDM_RATE; + + spin_lock_irqsave(&rs_sta->lock, flags); + + /* for recent assoc, choose best rate regarding + * to rssi value + */ + if (rs_sta->start_rate != IWL_RATE_INVALID) { + if (rs_sta->start_rate < index && + (rate_mask & (1 << rs_sta->start_rate))) + index = rs_sta->start_rate; + rs_sta->start_rate = IWL_RATE_INVALID; + } + + /* force user max rate if set by user */ + if ((max_rate_idx != -1) && (max_rate_idx < index)) { + if (rate_mask & (1 << max_rate_idx)) + index = max_rate_idx; + } + + window = &(rs_sta->win[index]); + + fail_count = window->counter - window->success_counter; + + if (((fail_count < IWL_RATE_MIN_FAILURE_TH) && + (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) { + spin_unlock_irqrestore(&rs_sta->lock, flags); + + IWL_DEBUG_RATE(priv, "Invalid average_tpt on rate %d: " + "counter: %d, success_counter: %d, " + "expected_tpt is %sNULL\n", + index, + window->counter, + window->success_counter, + rs_sta->expected_tpt ? "not " : ""); + + /* Can't calculate this yet; not enough history */ + window->average_tpt = IWL_INVALID_VALUE; + goto out; + + } + + current_tpt = window->average_tpt; + + high_low = iwl3945_get_adjacent_rate(rs_sta, index, rate_mask, + sband->band); + low = high_low & 0xff; + high = (high_low >> 8) & 0xff; + + /* If user set max rate, dont allow higher than user constrain */ + if ((max_rate_idx != -1) && (max_rate_idx < high)) + high = IWL_RATE_INVALID; + + /* Collect Measured throughputs of adjacent rates */ + if (low != IWL_RATE_INVALID) + low_tpt = rs_sta->win[low].average_tpt; + + if (high != IWL_RATE_INVALID) + high_tpt = rs_sta->win[high].average_tpt; + + spin_unlock_irqrestore(&rs_sta->lock, flags); + + scale_action = 0; + + /* Low success ratio , need to drop the rate */ + if ((window->success_ratio < IWL_RATE_DECREASE_TH) || !current_tpt) { + IWL_DEBUG_RATE(priv, "decrease rate because of low success_ratio\n"); + scale_action = -1; + /* No throughput measured yet for adjacent rates, + * try increase */ + } else if ((low_tpt == IWL_INVALID_VALUE) && + (high_tpt == IWL_INVALID_VALUE)) { + + if (high != IWL_RATE_INVALID && window->success_ratio >= IWL_RATE_INCREASE_TH) + scale_action = 1; + else if (low != IWL_RATE_INVALID) + scale_action = 0; + + /* Both adjacent throughputs are measured, but neither one has + * better throughput; we're using the best rate, don't change + * it! */ + } else if ((low_tpt != IWL_INVALID_VALUE) && + (high_tpt != IWL_INVALID_VALUE) && + (low_tpt < current_tpt) && (high_tpt < current_tpt)) { + + IWL_DEBUG_RATE(priv, "No action -- low [%d] & high [%d] < " + "current_tpt [%d]\n", + low_tpt, high_tpt, current_tpt); + scale_action = 0; + + /* At least one of the rates has better throughput */ + } else { + if (high_tpt != IWL_INVALID_VALUE) { + + /* High rate has better throughput, Increase + * rate */ + if (high_tpt > current_tpt && + window->success_ratio >= IWL_RATE_INCREASE_TH) + scale_action = 1; + else { + IWL_DEBUG_RATE(priv, + "decrease rate because of high tpt\n"); + scale_action = 0; + } + } else if (low_tpt != IWL_INVALID_VALUE) { + if (low_tpt > current_tpt) { + IWL_DEBUG_RATE(priv, + "decrease rate because of low tpt\n"); + scale_action = -1; + } else if (window->success_ratio >= IWL_RATE_INCREASE_TH) { + /* Lower rate has better + * throughput,decrease rate */ + scale_action = 1; + } + } + } + + /* Sanity check; asked for decrease, but success rate or throughput + * has been good at old rate. Don't change it. */ + if ((scale_action == -1) && (low != IWL_RATE_INVALID) && + ((window->success_ratio > IWL_RATE_HIGH_TH) || + (current_tpt > (100 * rs_sta->expected_tpt[low])))) + scale_action = 0; + + switch (scale_action) { + case -1: + + /* Decrese rate */ + if (low != IWL_RATE_INVALID) + index = low; + break; + + case 1: + /* Increase rate */ + if (high != IWL_RATE_INVALID) + index = high; + + break; + + case 0: + default: + /* No change */ + break; + } + + IWL_DEBUG_RATE(priv, "Selected %d (action %d) - low %d high %d\n", + index, scale_action, low, high); + + out: + + rs_sta->last_txrate_idx = index; + if (sband->band == IEEE80211_BAND_5GHZ) + info->control.rates[0].idx = rs_sta->last_txrate_idx - + IWL_FIRST_OFDM_RATE; + else + info->control.rates[0].idx = rs_sta->last_txrate_idx; + + IWL_DEBUG_RATE(priv, "leave: %d\n", index); +} + +#ifdef CONFIG_MAC80211_DEBUGFS +static int iwl3945_open_file_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static ssize_t iwl3945_sta_dbgfs_stats_table_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + char *buff; + int desc = 0; + int j; + ssize_t ret; + struct iwl3945_rs_sta *lq_sta = file->private_data; + + buff = kmalloc(1024, GFP_KERNEL); + if (!buff) + return -ENOMEM; + + desc += sprintf(buff + desc, "tx packets=%d last rate index=%d\n" + "rate=0x%X flush time %d\n", + lq_sta->tx_packets, + lq_sta->last_txrate_idx, + lq_sta->start_rate, jiffies_to_msecs(lq_sta->flush_time)); + for (j = 0; j < IWL_RATE_COUNT_3945; j++) { + desc += sprintf(buff+desc, + "counter=%d success=%d %%=%d\n", + lq_sta->win[j].counter, + lq_sta->win[j].success_counter, + lq_sta->win[j].success_ratio); + } + ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); + kfree(buff); + return ret; +} + +static const struct file_operations rs_sta_dbgfs_stats_table_ops = { + .read = iwl3945_sta_dbgfs_stats_table_read, + .open = iwl3945_open_file_generic, + .llseek = default_llseek, +}; + +static void iwl3945_add_debugfs(void *priv, void *priv_sta, + struct dentry *dir) +{ + struct iwl3945_rs_sta *lq_sta = priv_sta; + + lq_sta->rs_sta_dbgfs_stats_table_file = + debugfs_create_file("rate_stats_table", 0600, dir, + lq_sta, &rs_sta_dbgfs_stats_table_ops); + +} + +static void iwl3945_remove_debugfs(void *priv, void *priv_sta) +{ + struct iwl3945_rs_sta *lq_sta = priv_sta; + debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); +} +#endif + +/* + * Initialization of rate scaling information is done by driver after + * the station is added. Since mac80211 calls this function before a + * station is added we ignore it. + */ +static void rs_rate_init_stub(void *priv_r, struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta) +{ +} + +static struct rate_control_ops rs_ops = { + .module = NULL, + .name = RS_NAME, + .tx_status = rs_tx_status, + .get_rate = rs_get_rate, + .rate_init = rs_rate_init_stub, + .alloc = rs_alloc, + .free = rs_free, + .alloc_sta = rs_alloc_sta, + .free_sta = rs_free_sta, +#ifdef CONFIG_MAC80211_DEBUGFS + .add_sta_debugfs = iwl3945_add_debugfs, + .remove_sta_debugfs = iwl3945_remove_debugfs, +#endif + +}; +void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) +{ + struct iwl_priv *priv = hw->priv; + s32 rssi = 0; + unsigned long flags; + struct iwl3945_rs_sta *rs_sta; + struct ieee80211_sta *sta; + struct iwl3945_sta_priv *psta; + + IWL_DEBUG_RATE(priv, "enter\n"); + + rcu_read_lock(); + + sta = ieee80211_find_sta(priv->contexts[IWL_RXON_CTX_BSS].vif, + priv->stations[sta_id].sta.sta.addr); + if (!sta) { + IWL_DEBUG_RATE(priv, "Unable to find station to initialize rate scaling.\n"); + rcu_read_unlock(); + return; + } + + psta = (void *) sta->drv_priv; + rs_sta = &psta->rs_sta; + + spin_lock_irqsave(&rs_sta->lock, flags); + + rs_sta->tgg = 0; + switch (priv->band) { + case IEEE80211_BAND_2GHZ: + /* TODO: this always does G, not a regression */ + if (priv->contexts[IWL_RXON_CTX_BSS].active.flags & + RXON_FLG_TGG_PROTECT_MSK) { + rs_sta->tgg = 1; + rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot; + } else + rs_sta->expected_tpt = iwl3945_expected_tpt_g; + break; + + case IEEE80211_BAND_5GHZ: + rs_sta->expected_tpt = iwl3945_expected_tpt_a; + break; + case IEEE80211_NUM_BANDS: + BUG(); + break; + } + + spin_unlock_irqrestore(&rs_sta->lock, flags); + + rssi = priv->_3945.last_rx_rssi; + if (rssi == 0) + rssi = IWL_MIN_RSSI_VAL; + + IWL_DEBUG_RATE(priv, "Network RSSI: %d\n", rssi); + + rs_sta->start_rate = iwl3945_get_rate_index_by_rssi(rssi, priv->band); + + IWL_DEBUG_RATE(priv, "leave: rssi %d assign rate index: " + "%d (plcp 0x%x)\n", rssi, rs_sta->start_rate, + iwl3945_rates[rs_sta->start_rate].plcp); + rcu_read_unlock(); +} + +int iwl3945_rate_control_register(void) +{ + return ieee80211_rate_control_register(&rs_ops); +} + +void iwl3945_rate_control_unregister(void) +{ + ieee80211_rate_control_unregister(&rs_ops); +} + + diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c new file mode 100644 index 000000000000..5b6932c2193a --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -0,0 +1,2819 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iwl-fh.h" +#include "iwl-3945-fh.h" +#include "iwl-commands.h" +#include "iwl-sta.h" +#include "iwl-3945.h" +#include "iwl-eeprom.h" +#include "iwl-core.h" +#include "iwl-helpers.h" +#include "iwl-led.h" +#include "iwl-3945-led.h" +#include "iwl-3945-debugfs.h" +#include "iwl-legacy.h" + +#define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \ + [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ + IWL_RATE_##r##M_IEEE, \ + IWL_RATE_##ip##M_INDEX, \ + IWL_RATE_##in##M_INDEX, \ + IWL_RATE_##rp##M_INDEX, \ + IWL_RATE_##rn##M_INDEX, \ + IWL_RATE_##pp##M_INDEX, \ + IWL_RATE_##np##M_INDEX, \ + IWL_RATE_##r##M_INDEX_TABLE, \ + IWL_RATE_##ip##M_INDEX_TABLE } + +/* + * Parameter order: + * rate, prev rate, next rate, prev tgg rate, next tgg rate + * + * If there isn't a valid next or previous rate then INV is used which + * maps to IWL_RATE_INVALID + * + */ +const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945] = { + IWL_DECLARE_RATE_INFO(1, INV, 2, INV, 2, INV, 2), /* 1mbps */ + IWL_DECLARE_RATE_INFO(2, 1, 5, 1, 5, 1, 5), /* 2mbps */ + IWL_DECLARE_RATE_INFO(5, 2, 6, 2, 11, 2, 11), /*5.5mbps */ + IWL_DECLARE_RATE_INFO(11, 9, 12, 5, 12, 5, 18), /* 11mbps */ + IWL_DECLARE_RATE_INFO(6, 5, 9, 5, 11, 5, 11), /* 6mbps */ + IWL_DECLARE_RATE_INFO(9, 6, 11, 5, 11, 5, 11), /* 9mbps */ + IWL_DECLARE_RATE_INFO(12, 11, 18, 11, 18, 11, 18), /* 12mbps */ + IWL_DECLARE_RATE_INFO(18, 12, 24, 12, 24, 11, 24), /* 18mbps */ + IWL_DECLARE_RATE_INFO(24, 18, 36, 18, 36, 18, 36), /* 24mbps */ + IWL_DECLARE_RATE_INFO(36, 24, 48, 24, 48, 24, 48), /* 36mbps */ + IWL_DECLARE_RATE_INFO(48, 36, 54, 36, 54, 36, 54), /* 48mbps */ + IWL_DECLARE_RATE_INFO(54, 48, INV, 48, INV, 48, INV),/* 54mbps */ +}; + +static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index) +{ + u8 rate = iwl3945_rates[rate_index].prev_ieee; + + if (rate == IWL_RATE_INVALID) + rate = rate_index; + return rate; +} + +/* 1 = enable the iwl3945_disable_events() function */ +#define IWL_EVT_DISABLE (0) +#define IWL_EVT_DISABLE_SIZE (1532/32) + +/** + * iwl3945_disable_events - Disable selected events in uCode event log + * + * Disable an event by writing "1"s into "disable" + * bitmap in SRAM. Bit position corresponds to Event # (id/type). + * Default values of 0 enable uCode events to be logged. + * Use for only special debugging. This function is just a placeholder as-is, + * you'll need to provide the special bits! ... + * ... and set IWL_EVT_DISABLE to 1. */ +void iwl3945_disable_events(struct iwl_priv *priv) +{ + int i; + u32 base; /* SRAM address of event log header */ + u32 disable_ptr; /* SRAM address of event-disable bitmap array */ + u32 array_size; /* # of u32 entries in array */ + static const u32 evt_disable[IWL_EVT_DISABLE_SIZE] = { + 0x00000000, /* 31 - 0 Event id numbers */ + 0x00000000, /* 63 - 32 */ + 0x00000000, /* 95 - 64 */ + 0x00000000, /* 127 - 96 */ + 0x00000000, /* 159 - 128 */ + 0x00000000, /* 191 - 160 */ + 0x00000000, /* 223 - 192 */ + 0x00000000, /* 255 - 224 */ + 0x00000000, /* 287 - 256 */ + 0x00000000, /* 319 - 288 */ + 0x00000000, /* 351 - 320 */ + 0x00000000, /* 383 - 352 */ + 0x00000000, /* 415 - 384 */ + 0x00000000, /* 447 - 416 */ + 0x00000000, /* 479 - 448 */ + 0x00000000, /* 511 - 480 */ + 0x00000000, /* 543 - 512 */ + 0x00000000, /* 575 - 544 */ + 0x00000000, /* 607 - 576 */ + 0x00000000, /* 639 - 608 */ + 0x00000000, /* 671 - 640 */ + 0x00000000, /* 703 - 672 */ + 0x00000000, /* 735 - 704 */ + 0x00000000, /* 767 - 736 */ + 0x00000000, /* 799 - 768 */ + 0x00000000, /* 831 - 800 */ + 0x00000000, /* 863 - 832 */ + 0x00000000, /* 895 - 864 */ + 0x00000000, /* 927 - 896 */ + 0x00000000, /* 959 - 928 */ + 0x00000000, /* 991 - 960 */ + 0x00000000, /* 1023 - 992 */ + 0x00000000, /* 1055 - 1024 */ + 0x00000000, /* 1087 - 1056 */ + 0x00000000, /* 1119 - 1088 */ + 0x00000000, /* 1151 - 1120 */ + 0x00000000, /* 1183 - 1152 */ + 0x00000000, /* 1215 - 1184 */ + 0x00000000, /* 1247 - 1216 */ + 0x00000000, /* 1279 - 1248 */ + 0x00000000, /* 1311 - 1280 */ + 0x00000000, /* 1343 - 1312 */ + 0x00000000, /* 1375 - 1344 */ + 0x00000000, /* 1407 - 1376 */ + 0x00000000, /* 1439 - 1408 */ + 0x00000000, /* 1471 - 1440 */ + 0x00000000, /* 1503 - 1472 */ + }; + + base = le32_to_cpu(priv->card_alive.log_event_table_ptr); + if (!iwl3945_hw_valid_rtc_data_addr(base)) { + IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); + return; + } + + disable_ptr = iwl_read_targ_mem(priv, base + (4 * sizeof(u32))); + array_size = iwl_read_targ_mem(priv, base + (5 * sizeof(u32))); + + if (IWL_EVT_DISABLE && (array_size == IWL_EVT_DISABLE_SIZE)) { + IWL_DEBUG_INFO(priv, "Disabling selected uCode log events at 0x%x\n", + disable_ptr); + for (i = 0; i < IWL_EVT_DISABLE_SIZE; i++) + iwl_write_targ_mem(priv, + disable_ptr + (i * sizeof(u32)), + evt_disable[i]); + + } else { + IWL_DEBUG_INFO(priv, "Selected uCode log events may be disabled\n"); + IWL_DEBUG_INFO(priv, " by writing \"1\"s into disable bitmap\n"); + IWL_DEBUG_INFO(priv, " in SRAM at 0x%x, size %d u32s\n", + disable_ptr, array_size); + } + +} + +static int iwl3945_hwrate_to_plcp_idx(u8 plcp) +{ + int idx; + + for (idx = 0; idx < IWL_RATE_COUNT_3945; idx++) + if (iwl3945_rates[idx].plcp == plcp) + return idx; + return -1; +} + +#ifdef CONFIG_IWLWIFI_DEBUG +#define TX_STATUS_ENTRY(x) case TX_3945_STATUS_FAIL_ ## x: return #x + +static const char *iwl3945_get_tx_fail_reason(u32 status) +{ + switch (status & TX_STATUS_MSK) { + case TX_3945_STATUS_SUCCESS: + return "SUCCESS"; + TX_STATUS_ENTRY(SHORT_LIMIT); + TX_STATUS_ENTRY(LONG_LIMIT); + TX_STATUS_ENTRY(FIFO_UNDERRUN); + TX_STATUS_ENTRY(MGMNT_ABORT); + TX_STATUS_ENTRY(NEXT_FRAG); + TX_STATUS_ENTRY(LIFE_EXPIRE); + TX_STATUS_ENTRY(DEST_PS); + TX_STATUS_ENTRY(ABORTED); + TX_STATUS_ENTRY(BT_RETRY); + TX_STATUS_ENTRY(STA_INVALID); + TX_STATUS_ENTRY(FRAG_DROPPED); + TX_STATUS_ENTRY(TID_DISABLE); + TX_STATUS_ENTRY(FRAME_FLUSHED); + TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL); + TX_STATUS_ENTRY(TX_LOCKED); + TX_STATUS_ENTRY(NO_BEACON_ON_RADAR); + } + + return "UNKNOWN"; +} +#else +static inline const char *iwl3945_get_tx_fail_reason(u32 status) +{ + return ""; +} +#endif + +/* + * get ieee prev rate from rate scale table. + * for A and B mode we need to overright prev + * value + */ +int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate) +{ + int next_rate = iwl3945_get_prev_ieee_rate(rate); + + switch (priv->band) { + case IEEE80211_BAND_5GHZ: + if (rate == IWL_RATE_12M_INDEX) + next_rate = IWL_RATE_9M_INDEX; + else if (rate == IWL_RATE_6M_INDEX) + next_rate = IWL_RATE_6M_INDEX; + break; + case IEEE80211_BAND_2GHZ: + if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) && + iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { + if (rate == IWL_RATE_11M_INDEX) + next_rate = IWL_RATE_5M_INDEX; + } + break; + + default: + break; + } + + return next_rate; +} + + +/** + * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd + * + * When FW advances 'R' index, all entries between old and new 'R' index + * need to be reclaimed. As result, some free space forms. If there is + * enough free space (> low mark), wake the stack that feeds us. + */ +static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, + int txq_id, int index) +{ + struct iwl_tx_queue *txq = &priv->txq[txq_id]; + struct iwl_queue *q = &txq->q; + struct iwl_tx_info *tx_info; + + BUG_ON(txq_id == IWL39_CMD_QUEUE_NUM); + + for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index; + q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { + + tx_info = &txq->txb[txq->q.read_ptr]; + ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb); + tx_info->skb = NULL; + priv->cfg->ops->lib->txq_free_tfd(priv, txq); + } + + if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) && + (txq_id != IWL39_CMD_QUEUE_NUM) && + priv->mac80211_registered) + iwl_wake_queue(priv, txq); +} + +/** + * iwl3945_rx_reply_tx - Handle Tx response + */ +static void iwl3945_rx_reply_tx(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + u16 sequence = le16_to_cpu(pkt->hdr.sequence); + int txq_id = SEQ_TO_QUEUE(sequence); + int index = SEQ_TO_INDEX(sequence); + struct iwl_tx_queue *txq = &priv->txq[txq_id]; + struct ieee80211_tx_info *info; + struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; + u32 status = le32_to_cpu(tx_resp->status); + int rate_idx; + int fail; + + if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { + IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " + "is out of range [0-%d] %d %d\n", txq_id, + index, txq->q.n_bd, txq->q.write_ptr, + txq->q.read_ptr); + return; + } + + txq->time_stamp = jiffies; + info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); + ieee80211_tx_info_clear_status(info); + + /* Fill the MRR chain with some info about on-chip retransmissions */ + rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate); + if (info->band == IEEE80211_BAND_5GHZ) + rate_idx -= IWL_FIRST_OFDM_RATE; + + fail = tx_resp->failure_frame; + + info->status.rates[0].idx = rate_idx; + info->status.rates[0].count = fail + 1; /* add final attempt */ + + /* tx_status->rts_retry_count = tx_resp->failure_rts; */ + info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ? + IEEE80211_TX_STAT_ACK : 0; + + IWL_DEBUG_TX(priv, "Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n", + txq_id, iwl3945_get_tx_fail_reason(status), status, + tx_resp->rate, tx_resp->failure_frame); + + IWL_DEBUG_TX_REPLY(priv, "Tx queue reclaim %d\n", index); + iwl3945_tx_queue_reclaim(priv, txq_id, index); + + if (status & TX_ABORT_REQUIRED_MSK) + IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); +} + + + +/***************************************************************************** + * + * Intel PRO/Wireless 3945ABG/BG Network Connection + * + * RX handler implementations + * + *****************************************************************************/ +#ifdef CONFIG_IWLWIFI_DEBUGFS +/* + * based on the assumption of all statistics counter are in DWORD + * FIXME: This function is for debugging, do not deal with + * the case of counters roll-over. + */ +static void iwl3945_accumulative_statistics(struct iwl_priv *priv, + __le32 *stats) +{ + int i; + __le32 *prev_stats; + u32 *accum_stats; + u32 *delta, *max_delta; + + prev_stats = (__le32 *)&priv->_3945.statistics; + accum_stats = (u32 *)&priv->_3945.accum_statistics; + delta = (u32 *)&priv->_3945.delta_statistics; + max_delta = (u32 *)&priv->_3945.max_delta; + + for (i = sizeof(__le32); i < sizeof(struct iwl3945_notif_statistics); + i += sizeof(__le32), stats++, prev_stats++, delta++, + max_delta++, accum_stats++) { + if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { + *delta = (le32_to_cpu(*stats) - + le32_to_cpu(*prev_stats)); + *accum_stats += *delta; + if (*delta > *max_delta) + *max_delta = *delta; + } + } + + /* reset accumulative statistics for "no-counter" type statistics */ + priv->_3945.accum_statistics.general.temperature = + priv->_3945.statistics.general.temperature; + priv->_3945.accum_statistics.general.ttl_timestamp = + priv->_3945.statistics.general.ttl_timestamp; +} +#endif + +/** + * iwl3945_good_plcp_health - checks for plcp error. + * + * When the plcp error is exceeding the thresholds, reset the radio + * to improve the throughput. + */ +static bool iwl3945_good_plcp_health(struct iwl_priv *priv, + struct iwl_rx_packet *pkt) +{ + bool rc = true; + struct iwl3945_notif_statistics current_stat; + int combined_plcp_delta; + unsigned int plcp_msec; + unsigned long plcp_received_jiffies; + + if (priv->cfg->base_params->plcp_delta_threshold == + IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { + IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); + return rc; + } + memcpy(¤t_stat, pkt->u.raw, sizeof(struct + iwl3945_notif_statistics)); + /* + * check for plcp_err and trigger radio reset if it exceeds + * the plcp error threshold plcp_delta. + */ + plcp_received_jiffies = jiffies; + plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - + (long) priv->plcp_jiffies); + priv->plcp_jiffies = plcp_received_jiffies; + /* + * check to make sure plcp_msec is not 0 to prevent division + * by zero. + */ + if (plcp_msec) { + combined_plcp_delta = + (le32_to_cpu(current_stat.rx.ofdm.plcp_err) - + le32_to_cpu(priv->_3945.statistics.rx.ofdm.plcp_err)); + + if ((combined_plcp_delta > 0) && + ((combined_plcp_delta * 100) / plcp_msec) > + priv->cfg->base_params->plcp_delta_threshold) { + /* + * if plcp_err exceed the threshold, the following + * data is printed in csv format: + * Text: plcp_err exceeded %d, + * Received ofdm.plcp_err, + * Current ofdm.plcp_err, + * combined_plcp_delta, + * plcp_msec + */ + IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " + "%u, %d, %u mSecs\n", + priv->cfg->base_params->plcp_delta_threshold, + le32_to_cpu(current_stat.rx.ofdm.plcp_err), + combined_plcp_delta, plcp_msec); + /* + * Reset the RF radio due to the high plcp + * error rate + */ + rc = false; + } + } + return rc; +} + +void iwl3945_hw_rx_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + + IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", + (int)sizeof(struct iwl3945_notif_statistics), + le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); +#ifdef CONFIG_IWLWIFI_DEBUGFS + iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw); +#endif + iwl_recover_from_statistics(priv, pkt); + + memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics)); +} + +void iwl3945_reply_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + __le32 *flag = (__le32 *)&pkt->u.raw; + + if (le32_to_cpu(*flag) & UCODE_STATISTICS_CLEAR_MSK) { +#ifdef CONFIG_IWLWIFI_DEBUGFS + memset(&priv->_3945.accum_statistics, 0, + sizeof(struct iwl3945_notif_statistics)); + memset(&priv->_3945.delta_statistics, 0, + sizeof(struct iwl3945_notif_statistics)); + memset(&priv->_3945.max_delta, 0, + sizeof(struct iwl3945_notif_statistics)); +#endif + IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); + } + iwl3945_hw_rx_statistics(priv, rxb); +} + + +/****************************************************************************** + * + * Misc. internal state and helper functions + * + ******************************************************************************/ + +/* This is necessary only for a number of statistics, see the caller. */ +static int iwl3945_is_network_packet(struct iwl_priv *priv, + struct ieee80211_hdr *header) +{ + /* Filter incoming packets to determine if they are targeted toward + * this network, discarding packets coming from ourselves */ + switch (priv->iw_mode) { + case NL80211_IFTYPE_ADHOC: /* Header: Dest. | Source | BSSID */ + /* packets to our IBSS update information */ + return !compare_ether_addr(header->addr3, priv->bssid); + case NL80211_IFTYPE_STATION: /* Header: Dest. | AP{BSSID} | Source */ + /* packets to our IBSS update information */ + return !compare_ether_addr(header->addr2, priv->bssid); + default: + return 1; + } +} + +static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct ieee80211_rx_status *stats) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); + struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); + struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); + u16 len = le16_to_cpu(rx_hdr->len); + struct sk_buff *skb; + __le16 fc = hdr->frame_control; + + /* We received data from the HW, so stop the watchdog */ + if (unlikely(len + IWL39_RX_FRAME_SIZE > + PAGE_SIZE << priv->hw_params.rx_page_order)) { + IWL_DEBUG_DROP(priv, "Corruption detected!\n"); + return; + } + + /* We only process data packets if the interface is open */ + if (unlikely(!priv->is_open)) { + IWL_DEBUG_DROP_LIMIT(priv, + "Dropping packet while interface is not open.\n"); + return; + } + + skb = dev_alloc_skb(128); + if (!skb) { + IWL_ERR(priv, "dev_alloc_skb failed\n"); + return; + } + + if (!iwl3945_mod_params.sw_crypto) + iwl_set_decrypted_flag(priv, + (struct ieee80211_hdr *)rxb_addr(rxb), + le32_to_cpu(rx_end->status), stats); + + skb_add_rx_frag(skb, 0, rxb->page, + (void *)rx_hdr->payload - (void *)pkt, len); + + iwl_update_stats(priv, false, fc, len); + memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); + + ieee80211_rx(priv->hw, skb); + priv->alloc_rxb_page--; + rxb->page = NULL; +} + +#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) + +static void iwl3945_rx_reply_rx(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct ieee80211_hdr *header; + struct ieee80211_rx_status rx_status; + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); + struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); + struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); + u16 rx_stats_sig_avg __maybe_unused = le16_to_cpu(rx_stats->sig_avg); + u16 rx_stats_noise_diff __maybe_unused = le16_to_cpu(rx_stats->noise_diff); + u8 network_packet; + + rx_status.flag = 0; + rx_status.mactime = le64_to_cpu(rx_end->timestamp); + rx_status.band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? + IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; + rx_status.freq = + ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel), + rx_status.band); + + rx_status.rate_idx = iwl3945_hwrate_to_plcp_idx(rx_hdr->rate); + if (rx_status.band == IEEE80211_BAND_5GHZ) + rx_status.rate_idx -= IWL_FIRST_OFDM_RATE; + + rx_status.antenna = (le16_to_cpu(rx_hdr->phy_flags) & + RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4; + + /* set the preamble flag if appropriate */ + if (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK) + rx_status.flag |= RX_FLAG_SHORTPRE; + + if ((unlikely(rx_stats->phy_count > 20))) { + IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n", + rx_stats->phy_count); + return; + } + + if (!(rx_end->status & RX_RES_STATUS_NO_CRC32_ERROR) + || !(rx_end->status & RX_RES_STATUS_NO_RXE_OVERFLOW)) { + IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n", rx_end->status); + return; + } + + + + /* Convert 3945's rssi indicator to dBm */ + rx_status.signal = rx_stats->rssi - IWL39_RSSI_OFFSET; + + IWL_DEBUG_STATS(priv, "Rssi %d sig_avg %d noise_diff %d\n", + rx_status.signal, rx_stats_sig_avg, + rx_stats_noise_diff); + + header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); + + network_packet = iwl3945_is_network_packet(priv, header); + + IWL_DEBUG_STATS_LIMIT(priv, "[%c] %d RSSI:%d Signal:%u, Rate:%u\n", + network_packet ? '*' : ' ', + le16_to_cpu(rx_hdr->channel), + rx_status.signal, rx_status.signal, + rx_status.rate_idx); + + iwl_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len), header); + + if (network_packet) { + priv->_3945.last_beacon_time = + le32_to_cpu(rx_end->beacon_timestamp); + priv->_3945.last_tsf = le64_to_cpu(rx_end->timestamp); + priv->_3945.last_rx_rssi = rx_status.signal; + } + + iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status); +} + +int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, + struct iwl_tx_queue *txq, + dma_addr_t addr, u16 len, u8 reset, u8 pad) +{ + int count; + struct iwl_queue *q; + struct iwl3945_tfd *tfd, *tfd_tmp; + + q = &txq->q; + tfd_tmp = (struct iwl3945_tfd *)txq->tfds; + tfd = &tfd_tmp[q->write_ptr]; + + if (reset) + memset(tfd, 0, sizeof(*tfd)); + + count = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags)); + + if ((count >= NUM_TFD_CHUNKS) || (count < 0)) { + IWL_ERR(priv, "Error can not send more than %d chunks\n", + NUM_TFD_CHUNKS); + return -EINVAL; + } + + tfd->tbs[count].addr = cpu_to_le32(addr); + tfd->tbs[count].len = cpu_to_le32(len); + + count++; + + tfd->control_flags = cpu_to_le32(TFD_CTL_COUNT_SET(count) | + TFD_CTL_PAD_SET(pad)); + + return 0; +} + +/** + * iwl3945_hw_txq_free_tfd - Free one TFD, those at index [txq->q.read_ptr] + * + * Does NOT advance any indexes + */ +void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) +{ + struct iwl3945_tfd *tfd_tmp = (struct iwl3945_tfd *)txq->tfds; + int index = txq->q.read_ptr; + struct iwl3945_tfd *tfd = &tfd_tmp[index]; + struct pci_dev *dev = priv->pci_dev; + int i; + int counter; + + /* sanity check */ + counter = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags)); + if (counter > NUM_TFD_CHUNKS) { + IWL_ERR(priv, "Too many chunks: %i\n", counter); + /* @todo issue fatal error, it is quite serious situation */ + return; + } + + /* Unmap tx_cmd */ + if (counter) + pci_unmap_single(dev, + dma_unmap_addr(&txq->meta[index], mapping), + dma_unmap_len(&txq->meta[index], len), + PCI_DMA_TODEVICE); + + /* unmap chunks if any */ + + for (i = 1; i < counter; i++) + pci_unmap_single(dev, le32_to_cpu(tfd->tbs[i].addr), + le32_to_cpu(tfd->tbs[i].len), PCI_DMA_TODEVICE); + + /* free SKB */ + if (txq->txb) { + struct sk_buff *skb; + + skb = txq->txb[txq->q.read_ptr].skb; + + /* can be called from irqs-disabled context */ + if (skb) { + dev_kfree_skb_any(skb); + txq->txb[txq->q.read_ptr].skb = NULL; + } + } +} + +/** + * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD: + * +*/ +void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, + struct iwl_device_cmd *cmd, + struct ieee80211_tx_info *info, + struct ieee80211_hdr *hdr, + int sta_id, int tx_id) +{ + u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value; + u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT_3945); + u16 rate_mask; + int rate; + u8 rts_retry_limit; + u8 data_retry_limit; + __le32 tx_flags; + __le16 fc = hdr->frame_control; + struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload; + + rate = iwl3945_rates[rate_index].plcp; + tx_flags = tx_cmd->tx_flags; + + /* We need to figure out how to get the sta->supp_rates while + * in this running context */ + rate_mask = IWL_RATES_MASK_3945; + + /* Set retry limit on DATA packets and Probe Responses*/ + if (ieee80211_is_probe_resp(fc)) + data_retry_limit = 3; + else + data_retry_limit = IWL_DEFAULT_TX_RETRY; + tx_cmd->data_retry_limit = data_retry_limit; + + if (tx_id >= IWL39_CMD_QUEUE_NUM) + rts_retry_limit = 3; + else + rts_retry_limit = 7; + + if (data_retry_limit < rts_retry_limit) + rts_retry_limit = data_retry_limit; + tx_cmd->rts_retry_limit = rts_retry_limit; + + tx_cmd->rate = rate; + tx_cmd->tx_flags = tx_flags; + + /* OFDM */ + tx_cmd->supp_rates[0] = + ((rate_mask & IWL_OFDM_RATES_MASK) >> IWL_FIRST_OFDM_RATE) & 0xFF; + + /* CCK */ + tx_cmd->supp_rates[1] = (rate_mask & 0xF); + + IWL_DEBUG_RATE(priv, "Tx sta id: %d, rate: %d (plcp), flags: 0x%4X " + "cck/ofdm mask: 0x%x/0x%x\n", sta_id, + tx_cmd->rate, le32_to_cpu(tx_cmd->tx_flags), + tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]); +} + +static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate) +{ + unsigned long flags_spin; + struct iwl_station_entry *station; + + if (sta_id == IWL_INVALID_STATION) + return IWL_INVALID_STATION; + + spin_lock_irqsave(&priv->sta_lock, flags_spin); + station = &priv->stations[sta_id]; + + station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK; + station->sta.rate_n_flags = cpu_to_le16(tx_rate); + station->sta.mode = STA_CONTROL_MODIFY_MSK; + iwl_send_add_sta(priv, &station->sta, CMD_ASYNC); + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + + IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n", + sta_id, tx_rate); + return sta_id; +} + +static void iwl3945_set_pwr_vmain(struct iwl_priv *priv) +{ +/* + * (for documentation purposes) + * to set power to V_AUX, do + + if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) { + iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, + APMG_PS_CTRL_VAL_PWR_SRC_VAUX, + ~APMG_PS_CTRL_MSK_PWR_SRC); + + iwl_poll_bit(priv, CSR_GPIO_IN, + CSR_GPIO_IN_VAL_VAUX_PWR_SRC, + CSR_GPIO_IN_BIT_AUX_POWER, 5000); + } + */ + + iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, + APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, + ~APMG_PS_CTRL_MSK_PWR_SRC); + + iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC, + CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */ +} + +static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) +{ + iwl_write_direct32(priv, FH39_RCSR_RBD_BASE(0), rxq->bd_dma); + iwl_write_direct32(priv, FH39_RCSR_RPTR_ADDR(0), rxq->rb_stts_dma); + iwl_write_direct32(priv, FH39_RCSR_WPTR(0), 0); + iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), + FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE | + FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE | + FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN | + FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 | + (RX_QUEUE_SIZE_LOG << FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE) | + FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST | + (1 << FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH) | + FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH); + + /* fake read to flush all prev I/O */ + iwl_read_direct32(priv, FH39_RSSR_CTRL); + + return 0; +} + +static int iwl3945_tx_reset(struct iwl_priv *priv) +{ + + /* bypass mode */ + iwl_write_prph(priv, ALM_SCD_MODE_REG, 0x2); + + /* RA 0 is active */ + iwl_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01); + + /* all 6 fifo are active */ + iwl_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f); + + iwl_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000); + iwl_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002); + iwl_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004); + iwl_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005); + + iwl_write_direct32(priv, FH39_TSSR_CBB_BASE, + priv->_3945.shared_phys); + + iwl_write_direct32(priv, FH39_TSSR_MSG_CONFIG, + FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON | + FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON | + FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B | + FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON | + FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON | + FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH | + FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH); + + + return 0; +} + +/** + * iwl3945_txq_ctx_reset - Reset TX queue context + * + * Destroys all DMA structures and initialize them again + */ +static int iwl3945_txq_ctx_reset(struct iwl_priv *priv) +{ + int rc; + int txq_id, slots_num; + + iwl3945_hw_txq_ctx_free(priv); + + /* allocate tx queue structure */ + rc = iwl_alloc_txq_mem(priv); + if (rc) + return rc; + + /* Tx CMD queue */ + rc = iwl3945_tx_reset(priv); + if (rc) + goto error; + + /* Tx queue(s) */ + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { + slots_num = (txq_id == IWL39_CMD_QUEUE_NUM) ? + TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; + rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num, + txq_id); + if (rc) { + IWL_ERR(priv, "Tx %d queue init failed\n", txq_id); + goto error; + } + } + + return rc; + + error: + iwl3945_hw_txq_ctx_free(priv); + return rc; +} + + +/* + * Start up 3945's basic functionality after it has been reset + * (e.g. after platform boot, or shutdown via iwl_apm_stop()) + * NOTE: This does not load uCode nor start the embedded processor + */ +static int iwl3945_apm_init(struct iwl_priv *priv) +{ + int ret = iwl_apm_init(priv); + + /* Clear APMG (NIC's internal power management) interrupts */ + iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0); + iwl_write_prph(priv, APMG_RTC_INT_STT_REG, 0xFFFFFFFF); + + /* Reset radio chip */ + iwl_set_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); + udelay(5); + iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); + + return ret; +} + +static void iwl3945_nic_config(struct iwl_priv *priv) +{ + struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; + unsigned long flags; + u8 rev_id = 0; + + spin_lock_irqsave(&priv->lock, flags); + + /* Determine HW type */ + pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id); + + IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); + + if (rev_id & PCI_CFG_REV_ID_BIT_RTP) + IWL_DEBUG_INFO(priv, "RTP type\n"); + else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) { + IWL_DEBUG_INFO(priv, "3945 RADIO-MB type\n"); + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR39_HW_IF_CONFIG_REG_BIT_3945_MB); + } else { + IWL_DEBUG_INFO(priv, "3945 RADIO-MM type\n"); + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR39_HW_IF_CONFIG_REG_BIT_3945_MM); + } + + if (EEPROM_SKU_CAP_OP_MODE_MRC == eeprom->sku_cap) { + IWL_DEBUG_INFO(priv, "SKU OP mode is mrc\n"); + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC); + } else + IWL_DEBUG_INFO(priv, "SKU OP mode is basic\n"); + + if ((eeprom->board_revision & 0xF0) == 0xD0) { + IWL_DEBUG_INFO(priv, "3945ABG revision is 0x%X\n", + eeprom->board_revision); + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE); + } else { + IWL_DEBUG_INFO(priv, "3945ABG revision is 0x%X\n", + eeprom->board_revision); + iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE); + } + + if (eeprom->almgor_m_version <= 1) { + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A); + IWL_DEBUG_INFO(priv, "Card M type A version is 0x%X\n", + eeprom->almgor_m_version); + } else { + IWL_DEBUG_INFO(priv, "Card M type B version is 0x%X\n", + eeprom->almgor_m_version); + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B); + } + spin_unlock_irqrestore(&priv->lock, flags); + + if (eeprom->sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE) + IWL_DEBUG_RF_KILL(priv, "SW RF KILL supported in EEPROM.\n"); + + if (eeprom->sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE) + IWL_DEBUG_RF_KILL(priv, "HW RF KILL supported in EEPROM.\n"); +} + +int iwl3945_hw_nic_init(struct iwl_priv *priv) +{ + int rc; + unsigned long flags; + struct iwl_rx_queue *rxq = &priv->rxq; + + spin_lock_irqsave(&priv->lock, flags); + priv->cfg->ops->lib->apm_ops.init(priv); + spin_unlock_irqrestore(&priv->lock, flags); + + iwl3945_set_pwr_vmain(priv); + + priv->cfg->ops->lib->apm_ops.config(priv); + + /* Allocate the RX queue, or reset if it is already allocated */ + if (!rxq->bd) { + rc = iwl_rx_queue_alloc(priv); + if (rc) { + IWL_ERR(priv, "Unable to initialize Rx queue\n"); + return -ENOMEM; + } + } else + iwl3945_rx_queue_reset(priv, rxq); + + iwl3945_rx_replenish(priv); + + iwl3945_rx_init(priv, rxq); + + + /* Look at using this instead: + rxq->need_update = 1; + iwl_rx_queue_update_write_ptr(priv, rxq); + */ + + iwl_write_direct32(priv, FH39_RCSR_WPTR(0), rxq->write & ~7); + + rc = iwl3945_txq_ctx_reset(priv); + if (rc) + return rc; + + set_bit(STATUS_INIT, &priv->status); + + return 0; +} + +/** + * iwl3945_hw_txq_ctx_free - Free TXQ Context + * + * Destroy all TX DMA queues and structures + */ +void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv) +{ + int txq_id; + + /* Tx queues */ + if (priv->txq) + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; + txq_id++) + if (txq_id == IWL39_CMD_QUEUE_NUM) + iwl_cmd_queue_free(priv); + else + iwl_tx_queue_free(priv, txq_id); + + /* free tx queue structure */ + iwl_free_txq_mem(priv); +} + +void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv) +{ + int txq_id; + + /* stop SCD */ + iwl_write_prph(priv, ALM_SCD_MODE_REG, 0); + iwl_write_prph(priv, ALM_SCD_TXFACT_REG, 0); + + /* reset TFD queues */ + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { + iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), 0x0); + iwl_poll_direct_bit(priv, FH39_TSSR_TX_STATUS, + FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id), + 1000); + } + + iwl3945_hw_txq_ctx_free(priv); +} + +/** + * iwl3945_hw_reg_adjust_power_by_temp + * return index delta into power gain settings table +*/ +static int iwl3945_hw_reg_adjust_power_by_temp(int new_reading, int old_reading) +{ + return (new_reading - old_reading) * (-11) / 100; +} + +/** + * iwl3945_hw_reg_temp_out_of_range - Keep temperature in sane range + */ +static inline int iwl3945_hw_reg_temp_out_of_range(int temperature) +{ + return ((temperature < -260) || (temperature > 25)) ? 1 : 0; +} + +int iwl3945_hw_get_temperature(struct iwl_priv *priv) +{ + return iwl_read32(priv, CSR_UCODE_DRV_GP2); +} + +/** + * iwl3945_hw_reg_txpower_get_temperature + * get the current temperature by reading from NIC +*/ +static int iwl3945_hw_reg_txpower_get_temperature(struct iwl_priv *priv) +{ + struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; + int temperature; + + temperature = iwl3945_hw_get_temperature(priv); + + /* driver's okay range is -260 to +25. + * human readable okay range is 0 to +285 */ + IWL_DEBUG_INFO(priv, "Temperature: %d\n", temperature + IWL_TEMP_CONVERT); + + /* handle insane temp reading */ + if (iwl3945_hw_reg_temp_out_of_range(temperature)) { + IWL_ERR(priv, "Error bad temperature value %d\n", temperature); + + /* if really really hot(?), + * substitute the 3rd band/group's temp measured at factory */ + if (priv->last_temperature > 100) + temperature = eeprom->groups[2].temperature; + else /* else use most recent "sane" value from driver */ + temperature = priv->last_temperature; + } + + return temperature; /* raw, not "human readable" */ +} + +/* Adjust Txpower only if temperature variance is greater than threshold. + * + * Both are lower than older versions' 9 degrees */ +#define IWL_TEMPERATURE_LIMIT_TIMER 6 + +/** + * is_temp_calib_needed - determines if new calibration is needed + * + * records new temperature in tx_mgr->temperature. + * replaces tx_mgr->last_temperature *only* if calib needed + * (assumes caller will actually do the calibration!). */ +static int is_temp_calib_needed(struct iwl_priv *priv) +{ + int temp_diff; + + priv->temperature = iwl3945_hw_reg_txpower_get_temperature(priv); + temp_diff = priv->temperature - priv->last_temperature; + + /* get absolute value */ + if (temp_diff < 0) { + IWL_DEBUG_POWER(priv, "Getting cooler, delta %d,\n", temp_diff); + temp_diff = -temp_diff; + } else if (temp_diff == 0) + IWL_DEBUG_POWER(priv, "Same temp,\n"); + else + IWL_DEBUG_POWER(priv, "Getting warmer, delta %d,\n", temp_diff); + + /* if we don't need calibration, *don't* update last_temperature */ + if (temp_diff < IWL_TEMPERATURE_LIMIT_TIMER) { + IWL_DEBUG_POWER(priv, "Timed thermal calib not needed\n"); + return 0; + } + + IWL_DEBUG_POWER(priv, "Timed thermal calib needed\n"); + + /* assume that caller will actually do calib ... + * update the "last temperature" value */ + priv->last_temperature = priv->temperature; + return 1; +} + +#define IWL_MAX_GAIN_ENTRIES 78 +#define IWL_CCK_FROM_OFDM_POWER_DIFF -5 +#define IWL_CCK_FROM_OFDM_INDEX_DIFF (10) + +/* radio and DSP power table, each step is 1/2 dB. + * 1st number is for RF analog gain, 2nd number is for DSP pre-DAC gain. */ +static struct iwl3945_tx_power power_gain_table[2][IWL_MAX_GAIN_ENTRIES] = { + { + {251, 127}, /* 2.4 GHz, highest power */ + {251, 127}, + {251, 127}, + {251, 127}, + {251, 125}, + {251, 110}, + {251, 105}, + {251, 98}, + {187, 125}, + {187, 115}, + {187, 108}, + {187, 99}, + {243, 119}, + {243, 111}, + {243, 105}, + {243, 97}, + {243, 92}, + {211, 106}, + {211, 100}, + {179, 120}, + {179, 113}, + {179, 107}, + {147, 125}, + {147, 119}, + {147, 112}, + {147, 106}, + {147, 101}, + {147, 97}, + {147, 91}, + {115, 107}, + {235, 121}, + {235, 115}, + {235, 109}, + {203, 127}, + {203, 121}, + {203, 115}, + {203, 108}, + {203, 102}, + {203, 96}, + {203, 92}, + {171, 110}, + {171, 104}, + {171, 98}, + {139, 116}, + {227, 125}, + {227, 119}, + {227, 113}, + {227, 107}, + {227, 101}, + {227, 96}, + {195, 113}, + {195, 106}, + {195, 102}, + {195, 95}, + {163, 113}, + {163, 106}, + {163, 102}, + {163, 95}, + {131, 113}, + {131, 106}, + {131, 102}, + {131, 95}, + {99, 113}, + {99, 106}, + {99, 102}, + {99, 95}, + {67, 113}, + {67, 106}, + {67, 102}, + {67, 95}, + {35, 113}, + {35, 106}, + {35, 102}, + {35, 95}, + {3, 113}, + {3, 106}, + {3, 102}, + {3, 95} }, /* 2.4 GHz, lowest power */ + { + {251, 127}, /* 5.x GHz, highest power */ + {251, 120}, + {251, 114}, + {219, 119}, + {219, 101}, + {187, 113}, + {187, 102}, + {155, 114}, + {155, 103}, + {123, 117}, + {123, 107}, + {123, 99}, + {123, 92}, + {91, 108}, + {59, 125}, + {59, 118}, + {59, 109}, + {59, 102}, + {59, 96}, + {59, 90}, + {27, 104}, + {27, 98}, + {27, 92}, + {115, 118}, + {115, 111}, + {115, 104}, + {83, 126}, + {83, 121}, + {83, 113}, + {83, 105}, + {83, 99}, + {51, 118}, + {51, 111}, + {51, 104}, + {51, 98}, + {19, 116}, + {19, 109}, + {19, 102}, + {19, 98}, + {19, 93}, + {171, 113}, + {171, 107}, + {171, 99}, + {139, 120}, + {139, 113}, + {139, 107}, + {139, 99}, + {107, 120}, + {107, 113}, + {107, 107}, + {107, 99}, + {75, 120}, + {75, 113}, + {75, 107}, + {75, 99}, + {43, 120}, + {43, 113}, + {43, 107}, + {43, 99}, + {11, 120}, + {11, 113}, + {11, 107}, + {11, 99}, + {131, 107}, + {131, 99}, + {99, 120}, + {99, 113}, + {99, 107}, + {99, 99}, + {67, 120}, + {67, 113}, + {67, 107}, + {67, 99}, + {35, 120}, + {35, 113}, + {35, 107}, + {35, 99}, + {3, 120} } /* 5.x GHz, lowest power */ +}; + +static inline u8 iwl3945_hw_reg_fix_power_index(int index) +{ + if (index < 0) + return 0; + if (index >= IWL_MAX_GAIN_ENTRIES) + return IWL_MAX_GAIN_ENTRIES - 1; + return (u8) index; +} + +/* Kick off thermal recalibration check every 60 seconds */ +#define REG_RECALIB_PERIOD (60) + +/** + * iwl3945_hw_reg_set_scan_power - Set Tx power for scan probe requests + * + * Set (in our channel info database) the direct scan Tx power for 1 Mbit (CCK) + * or 6 Mbit (OFDM) rates. + */ +static void iwl3945_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index, + s32 rate_index, const s8 *clip_pwrs, + struct iwl_channel_info *ch_info, + int band_index) +{ + struct iwl3945_scan_power_info *scan_power_info; + s8 power; + u8 power_index; + + scan_power_info = &ch_info->scan_pwr_info[scan_tbl_index]; + + /* use this channel group's 6Mbit clipping/saturation pwr, + * but cap at regulatory scan power restriction (set during init + * based on eeprom channel data) for this channel. */ + power = min(ch_info->scan_power, clip_pwrs[IWL_RATE_6M_INDEX_TABLE]); + + /* further limit to user's max power preference. + * FIXME: Other spectrum management power limitations do not + * seem to apply?? */ + power = min(power, priv->tx_power_user_lmt); + scan_power_info->requested_power = power; + + /* find difference between new scan *power* and current "normal" + * Tx *power* for 6Mb. Use this difference (x2) to adjust the + * current "normal" temperature-compensated Tx power *index* for + * this rate (1Mb or 6Mb) to yield new temp-compensated scan power + * *index*. */ + power_index = ch_info->power_info[rate_index].power_table_index + - (power - ch_info->power_info + [IWL_RATE_6M_INDEX_TABLE].requested_power) * 2; + + /* store reference index that we use when adjusting *all* scan + * powers. So we can accommodate user (all channel) or spectrum + * management (single channel) power changes "between" temperature + * feedback compensation procedures. + * don't force fit this reference index into gain table; it may be a + * negative number. This will help avoid errors when we're at + * the lower bounds (highest gains, for warmest temperatures) + * of the table. */ + + /* don't exceed table bounds for "real" setting */ + power_index = iwl3945_hw_reg_fix_power_index(power_index); + + scan_power_info->power_table_index = power_index; + scan_power_info->tpc.tx_gain = + power_gain_table[band_index][power_index].tx_gain; + scan_power_info->tpc.dsp_atten = + power_gain_table[band_index][power_index].dsp_atten; +} + +/** + * iwl3945_send_tx_power - fill in Tx Power command with gain settings + * + * Configures power settings for all rates for the current channel, + * using values from channel info struct, and send to NIC + */ +static int iwl3945_send_tx_power(struct iwl_priv *priv) +{ + int rate_idx, i; + const struct iwl_channel_info *ch_info = NULL; + struct iwl3945_txpowertable_cmd txpower = { + .channel = priv->contexts[IWL_RXON_CTX_BSS].active.channel, + }; + u16 chan; + + if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status), + "TX Power requested while scanning!\n")) + return -EAGAIN; + + chan = le16_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.channel); + + txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1; + ch_info = iwl_get_channel_info(priv, priv->band, chan); + if (!ch_info) { + IWL_ERR(priv, + "Failed to get channel info for channel %d [%d]\n", + chan, priv->band); + return -EINVAL; + } + + if (!is_channel_valid(ch_info)) { + IWL_DEBUG_POWER(priv, "Not calling TX_PWR_TABLE_CMD on " + "non-Tx channel.\n"); + return 0; + } + + /* fill cmd with power settings for all rates for current channel */ + /* Fill OFDM rate */ + for (rate_idx = IWL_FIRST_OFDM_RATE, i = 0; + rate_idx <= IWL39_LAST_OFDM_RATE; rate_idx++, i++) { + + txpower.power[i].tpc = ch_info->power_info[i].tpc; + txpower.power[i].rate = iwl3945_rates[rate_idx].plcp; + + IWL_DEBUG_POWER(priv, "ch %d:%d rf %d dsp %3d rate code 0x%02x\n", + le16_to_cpu(txpower.channel), + txpower.band, + txpower.power[i].tpc.tx_gain, + txpower.power[i].tpc.dsp_atten, + txpower.power[i].rate); + } + /* Fill CCK rates */ + for (rate_idx = IWL_FIRST_CCK_RATE; + rate_idx <= IWL_LAST_CCK_RATE; rate_idx++, i++) { + txpower.power[i].tpc = ch_info->power_info[i].tpc; + txpower.power[i].rate = iwl3945_rates[rate_idx].plcp; + + IWL_DEBUG_POWER(priv, "ch %d:%d rf %d dsp %3d rate code 0x%02x\n", + le16_to_cpu(txpower.channel), + txpower.band, + txpower.power[i].tpc.tx_gain, + txpower.power[i].tpc.dsp_atten, + txpower.power[i].rate); + } + + return iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, + sizeof(struct iwl3945_txpowertable_cmd), + &txpower); + +} + +/** + * iwl3945_hw_reg_set_new_power - Configures power tables at new levels + * @ch_info: Channel to update. Uses power_info.requested_power. + * + * Replace requested_power and base_power_index ch_info fields for + * one channel. + * + * Called if user or spectrum management changes power preferences. + * Takes into account h/w and modulation limitations (clip power). + * + * This does *not* send anything to NIC, just sets up ch_info for one channel. + * + * NOTE: reg_compensate_for_temperature_dif() *must* be run after this to + * properly fill out the scan powers, and actual h/w gain settings, + * and send changes to NIC + */ +static int iwl3945_hw_reg_set_new_power(struct iwl_priv *priv, + struct iwl_channel_info *ch_info) +{ + struct iwl3945_channel_power_info *power_info; + int power_changed = 0; + int i; + const s8 *clip_pwrs; + int power; + + /* Get this chnlgrp's rate-to-max/clip-powers table */ + clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers; + + /* Get this channel's rate-to-current-power settings table */ + power_info = ch_info->power_info; + + /* update OFDM Txpower settings */ + for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; + i++, ++power_info) { + int delta_idx; + + /* limit new power to be no more than h/w capability */ + power = min(ch_info->curr_txpow, clip_pwrs[i]); + if (power == power_info->requested_power) + continue; + + /* find difference between old and new requested powers, + * update base (non-temp-compensated) power index */ + delta_idx = (power - power_info->requested_power) * 2; + power_info->base_power_index -= delta_idx; + + /* save new requested power value */ + power_info->requested_power = power; + + power_changed = 1; + } + + /* update CCK Txpower settings, based on OFDM 12M setting ... + * ... all CCK power settings for a given channel are the *same*. */ + if (power_changed) { + power = + ch_info->power_info[IWL_RATE_12M_INDEX_TABLE]. + requested_power + IWL_CCK_FROM_OFDM_POWER_DIFF; + + /* do all CCK rates' iwl3945_channel_power_info structures */ + for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++) { + power_info->requested_power = power; + power_info->base_power_index = + ch_info->power_info[IWL_RATE_12M_INDEX_TABLE]. + base_power_index + IWL_CCK_FROM_OFDM_INDEX_DIFF; + ++power_info; + } + } + + return 0; +} + +/** + * iwl3945_hw_reg_get_ch_txpower_limit - returns new power limit for channel + * + * NOTE: Returned power limit may be less (but not more) than requested, + * based strictly on regulatory (eeprom and spectrum mgt) limitations + * (no consideration for h/w clipping limitations). + */ +static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl_channel_info *ch_info) +{ + s8 max_power; + +#if 0 + /* if we're using TGd limits, use lower of TGd or EEPROM */ + if (ch_info->tgd_data.max_power != 0) + max_power = min(ch_info->tgd_data.max_power, + ch_info->eeprom.max_power_avg); + + /* else just use EEPROM limits */ + else +#endif + max_power = ch_info->eeprom.max_power_avg; + + return min(max_power, ch_info->max_power_avg); +} + +/** + * iwl3945_hw_reg_comp_txpower_temp - Compensate for temperature + * + * Compensate txpower settings of *all* channels for temperature. + * This only accounts for the difference between current temperature + * and the factory calibration temperatures, and bases the new settings + * on the channel's base_power_index. + * + * If RxOn is "associated", this sends the new Txpower to NIC! + */ +static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv) +{ + struct iwl_channel_info *ch_info = NULL; + struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; + int delta_index; + const s8 *clip_pwrs; /* array of h/w max power levels for each rate */ + u8 a_band; + u8 rate_index; + u8 scan_tbl_index; + u8 i; + int ref_temp; + int temperature = priv->temperature; + + if (priv->disable_tx_power_cal || + test_bit(STATUS_SCANNING, &priv->status)) { + /* do not perform tx power calibration */ + return 0; + } + /* set up new Tx power info for each and every channel, 2.4 and 5.x */ + for (i = 0; i < priv->channel_count; i++) { + ch_info = &priv->channel_info[i]; + a_band = is_channel_a_band(ch_info); + + /* Get this chnlgrp's factory calibration temperature */ + ref_temp = (s16)eeprom->groups[ch_info->group_index]. + temperature; + + /* get power index adjustment based on current and factory + * temps */ + delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature, + ref_temp); + + /* set tx power value for all rates, OFDM and CCK */ + for (rate_index = 0; rate_index < IWL_RATE_COUNT_3945; + rate_index++) { + int power_idx = + ch_info->power_info[rate_index].base_power_index; + + /* temperature compensate */ + power_idx += delta_index; + + /* stay within table range */ + power_idx = iwl3945_hw_reg_fix_power_index(power_idx); + ch_info->power_info[rate_index]. + power_table_index = (u8) power_idx; + ch_info->power_info[rate_index].tpc = + power_gain_table[a_band][power_idx]; + } + + /* Get this chnlgrp's rate-to-max/clip-powers table */ + clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers; + + /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */ + for (scan_tbl_index = 0; + scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) { + s32 actual_index = (scan_tbl_index == 0) ? + IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE; + iwl3945_hw_reg_set_scan_power(priv, scan_tbl_index, + actual_index, clip_pwrs, + ch_info, a_band); + } + } + + /* send Txpower command for current channel to ucode */ + return priv->cfg->ops->lib->send_tx_power(priv); +} + +int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power) +{ + struct iwl_channel_info *ch_info; + s8 max_power; + u8 a_band; + u8 i; + + if (priv->tx_power_user_lmt == power) { + IWL_DEBUG_POWER(priv, "Requested Tx power same as current " + "limit: %ddBm.\n", power); + return 0; + } + + IWL_DEBUG_POWER(priv, "Setting upper limit clamp to %ddBm.\n", power); + priv->tx_power_user_lmt = power; + + /* set up new Tx powers for each and every channel, 2.4 and 5.x */ + + for (i = 0; i < priv->channel_count; i++) { + ch_info = &priv->channel_info[i]; + a_band = is_channel_a_band(ch_info); + + /* find minimum power of all user and regulatory constraints + * (does not consider h/w clipping limitations) */ + max_power = iwl3945_hw_reg_get_ch_txpower_limit(ch_info); + max_power = min(power, max_power); + if (max_power != ch_info->curr_txpow) { + ch_info->curr_txpow = max_power; + + /* this considers the h/w clipping limitations */ + iwl3945_hw_reg_set_new_power(priv, ch_info); + } + } + + /* update txpower settings for all channels, + * send to NIC if associated. */ + is_temp_calib_needed(priv); + iwl3945_hw_reg_comp_txpower_temp(priv); + + return 0; +} + +static int iwl3945_send_rxon_assoc(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + int rc = 0; + struct iwl_rx_packet *pkt; + struct iwl3945_rxon_assoc_cmd rxon_assoc; + struct iwl_host_cmd cmd = { + .id = REPLY_RXON_ASSOC, + .len = sizeof(rxon_assoc), + .flags = CMD_WANT_SKB, + .data = &rxon_assoc, + }; + const struct iwl_rxon_cmd *rxon1 = &ctx->staging; + const struct iwl_rxon_cmd *rxon2 = &ctx->active; + + if ((rxon1->flags == rxon2->flags) && + (rxon1->filter_flags == rxon2->filter_flags) && + (rxon1->cck_basic_rates == rxon2->cck_basic_rates) && + (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) { + IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n"); + return 0; + } + + rxon_assoc.flags = ctx->staging.flags; + rxon_assoc.filter_flags = ctx->staging.filter_flags; + rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; + rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; + rxon_assoc.reserved = 0; + + rc = iwl_send_cmd_sync(priv, &cmd); + if (rc) + return rc; + + pkt = (struct iwl_rx_packet *)cmd.reply_page; + if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { + IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n"); + rc = -EIO; + } + + iwl_free_pages(priv, cmd.reply_page); + + return rc; +} + +/** + * iwl3945_commit_rxon - commit staging_rxon to hardware + * + * The RXON command in staging_rxon is committed to the hardware and + * the active_rxon structure is updated with the new data. This + * function correctly transitions out of the RXON_ASSOC_MSK state if + * a HW tune is required based on the RXON structure changes. + */ +int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +{ + /* cast away the const for active_rxon in this function */ + struct iwl3945_rxon_cmd *active_rxon = (void *)&ctx->active; + struct iwl3945_rxon_cmd *staging_rxon = (void *)&ctx->staging; + int rc = 0; + bool new_assoc = !!(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return -EINVAL; + + if (!iwl_is_alive(priv)) + return -1; + + /* always get timestamp with Rx frame */ + staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK; + + /* select antenna */ + staging_rxon->flags &= + ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK); + staging_rxon->flags |= iwl3945_get_antenna_flags(priv); + + rc = iwl_check_rxon_cmd(priv, ctx); + if (rc) { + IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); + return -EINVAL; + } + + /* If we don't need to send a full RXON, we can use + * iwl3945_rxon_assoc_cmd which is used to reconfigure filter + * and other flags for the current radio configuration. */ + if (!iwl_full_rxon_required(priv, &priv->contexts[IWL_RXON_CTX_BSS])) { + rc = iwl_send_rxon_assoc(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); + if (rc) { + IWL_ERR(priv, "Error setting RXON_ASSOC " + "configuration (%d).\n", rc); + return rc; + } + + memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); + + return 0; + } + + /* If we are currently associated and the new config requires + * an RXON_ASSOC and the new config wants the associated mask enabled, + * we must clear the associated from the active configuration + * before we apply the new config */ + if (iwl_is_associated(priv, IWL_RXON_CTX_BSS) && new_assoc) { + IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); + active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; + + /* + * reserved4 and 5 could have been filled by the iwlcore code. + * Let's clear them before pushing to the 3945. + */ + active_rxon->reserved4 = 0; + active_rxon->reserved5 = 0; + rc = iwl_send_cmd_pdu(priv, REPLY_RXON, + sizeof(struct iwl3945_rxon_cmd), + &priv->contexts[IWL_RXON_CTX_BSS].active); + + /* If the mask clearing failed then we set + * active_rxon back to what it was previously */ + if (rc) { + active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; + IWL_ERR(priv, "Error clearing ASSOC_MSK on current " + "configuration (%d).\n", rc); + return rc; + } + iwl_clear_ucode_stations(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); + iwl_restore_stations(priv, &priv->contexts[IWL_RXON_CTX_BSS]); + } + + IWL_DEBUG_INFO(priv, "Sending RXON\n" + "* with%s RXON_FILTER_ASSOC_MSK\n" + "* channel = %d\n" + "* bssid = %pM\n", + (new_assoc ? "" : "out"), + le16_to_cpu(staging_rxon->channel), + staging_rxon->bssid_addr); + + /* + * reserved4 and 5 could have been filled by the iwlcore code. + * Let's clear them before pushing to the 3945. + */ + staging_rxon->reserved4 = 0; + staging_rxon->reserved5 = 0; + + iwl_set_rxon_hwcrypto(priv, ctx, !iwl3945_mod_params.sw_crypto); + + /* Apply the new configuration */ + rc = iwl_send_cmd_pdu(priv, REPLY_RXON, + sizeof(struct iwl3945_rxon_cmd), + staging_rxon); + if (rc) { + IWL_ERR(priv, "Error setting new configuration (%d).\n", rc); + return rc; + } + + memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); + + if (!new_assoc) { + iwl_clear_ucode_stations(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); + iwl_restore_stations(priv, &priv->contexts[IWL_RXON_CTX_BSS]); + } + + /* If we issue a new RXON command which required a tune then we must + * send a new TXPOWER command or we won't be able to Tx any frames */ + rc = iwl_set_tx_power(priv, priv->tx_power_next, true); + if (rc) { + IWL_ERR(priv, "Error setting Tx power (%d).\n", rc); + return rc; + } + + /* Init the hardware's rate fallback order based on the band */ + rc = iwl3945_init_hw_rate_table(priv); + if (rc) { + IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc); + return -EIO; + } + + return 0; +} + +/** + * iwl3945_reg_txpower_periodic - called when time to check our temperature. + * + * -- reset periodic timer + * -- see if temp has changed enough to warrant re-calibration ... if so: + * -- correct coeffs for temp (can reset temp timer) + * -- save this temp as "last", + * -- send new set of gain settings to NIC + * NOTE: This should continue working, even when we're not associated, + * so we can keep our internal table of scan powers current. */ +void iwl3945_reg_txpower_periodic(struct iwl_priv *priv) +{ + /* This will kick in the "brute force" + * iwl3945_hw_reg_comp_txpower_temp() below */ + if (!is_temp_calib_needed(priv)) + goto reschedule; + + /* Set up a new set of temp-adjusted TxPowers, send to NIC. + * This is based *only* on current temperature, + * ignoring any previous power measurements */ + iwl3945_hw_reg_comp_txpower_temp(priv); + + reschedule: + queue_delayed_work(priv->workqueue, + &priv->_3945.thermal_periodic, REG_RECALIB_PERIOD * HZ); +} + +static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work) +{ + struct iwl_priv *priv = container_of(work, struct iwl_priv, + _3945.thermal_periodic.work); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + iwl3945_reg_txpower_periodic(priv); + mutex_unlock(&priv->mutex); +} + +/** + * iwl3945_hw_reg_get_ch_grp_index - find the channel-group index (0-4) + * for the channel. + * + * This function is used when initializing channel-info structs. + * + * NOTE: These channel groups do *NOT* match the bands above! + * These channel groups are based on factory-tested channels; + * on A-band, EEPROM's "group frequency" entries represent the top + * channel in each group 1-4. Group 5 All B/G channels are in group 0. + */ +static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl_priv *priv, + const struct iwl_channel_info *ch_info) +{ + struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; + struct iwl3945_eeprom_txpower_group *ch_grp = &eeprom->groups[0]; + u8 group; + u16 group_index = 0; /* based on factory calib frequencies */ + u8 grp_channel; + + /* Find the group index for the channel ... don't use index 1(?) */ + if (is_channel_a_band(ch_info)) { + for (group = 1; group < 5; group++) { + grp_channel = ch_grp[group].group_channel; + if (ch_info->channel <= grp_channel) { + group_index = group; + break; + } + } + /* group 4 has a few channels *above* its factory cal freq */ + if (group == 5) + group_index = 4; + } else + group_index = 0; /* 2.4 GHz, group 0 */ + + IWL_DEBUG_POWER(priv, "Chnl %d mapped to grp %d\n", ch_info->channel, + group_index); + return group_index; +} + +/** + * iwl3945_hw_reg_get_matched_power_index - Interpolate to get nominal index + * + * Interpolate to get nominal (i.e. at factory calibration temperature) index + * into radio/DSP gain settings table for requested power. + */ +static int iwl3945_hw_reg_get_matched_power_index(struct iwl_priv *priv, + s8 requested_power, + s32 setting_index, s32 *new_index) +{ + const struct iwl3945_eeprom_txpower_group *chnl_grp = NULL; + struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; + s32 index0, index1; + s32 power = 2 * requested_power; + s32 i; + const struct iwl3945_eeprom_txpower_sample *samples; + s32 gains0, gains1; + s32 res; + s32 denominator; + + chnl_grp = &eeprom->groups[setting_index]; + samples = chnl_grp->samples; + for (i = 0; i < 5; i++) { + if (power == samples[i].power) { + *new_index = samples[i].gain_index; + return 0; + } + } + + if (power > samples[1].power) { + index0 = 0; + index1 = 1; + } else if (power > samples[2].power) { + index0 = 1; + index1 = 2; + } else if (power > samples[3].power) { + index0 = 2; + index1 = 3; + } else { + index0 = 3; + index1 = 4; + } + + denominator = (s32) samples[index1].power - (s32) samples[index0].power; + if (denominator == 0) + return -EINVAL; + gains0 = (s32) samples[index0].gain_index * (1 << 19); + gains1 = (s32) samples[index1].gain_index * (1 << 19); + res = gains0 + (gains1 - gains0) * + ((s32) power - (s32) samples[index0].power) / denominator + + (1 << 18); + *new_index = res >> 19; + return 0; +} + +static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv) +{ + u32 i; + s32 rate_index; + struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; + const struct iwl3945_eeprom_txpower_group *group; + + IWL_DEBUG_POWER(priv, "Initializing factory calib info from EEPROM\n"); + + for (i = 0; i < IWL_NUM_TX_CALIB_GROUPS; i++) { + s8 *clip_pwrs; /* table of power levels for each rate */ + s8 satur_pwr; /* saturation power for each chnl group */ + group = &eeprom->groups[i]; + + /* sanity check on factory saturation power value */ + if (group->saturation_power < 40) { + IWL_WARN(priv, "Error: saturation power is %d, " + "less than minimum expected 40\n", + group->saturation_power); + return; + } + + /* + * Derive requested power levels for each rate, based on + * hardware capabilities (saturation power for band). + * Basic value is 3dB down from saturation, with further + * power reductions for highest 3 data rates. These + * backoffs provide headroom for high rate modulation + * power peaks, without too much distortion (clipping). + */ + /* we'll fill in this array with h/w max power levels */ + clip_pwrs = (s8 *) priv->_3945.clip_groups[i].clip_powers; + + /* divide factory saturation power by 2 to find -3dB level */ + satur_pwr = (s8) (group->saturation_power >> 1); + + /* fill in channel group's nominal powers for each rate */ + for (rate_index = 0; + rate_index < IWL_RATE_COUNT_3945; rate_index++, clip_pwrs++) { + switch (rate_index) { + case IWL_RATE_36M_INDEX_TABLE: + if (i == 0) /* B/G */ + *clip_pwrs = satur_pwr; + else /* A */ + *clip_pwrs = satur_pwr - 5; + break; + case IWL_RATE_48M_INDEX_TABLE: + if (i == 0) + *clip_pwrs = satur_pwr - 7; + else + *clip_pwrs = satur_pwr - 10; + break; + case IWL_RATE_54M_INDEX_TABLE: + if (i == 0) + *clip_pwrs = satur_pwr - 9; + else + *clip_pwrs = satur_pwr - 12; + break; + default: + *clip_pwrs = satur_pwr; + break; + } + } + } +} + +/** + * iwl3945_txpower_set_from_eeprom - Set channel power info based on EEPROM + * + * Second pass (during init) to set up priv->channel_info + * + * Set up Tx-power settings in our channel info database for each VALID + * (for this geo/SKU) channel, at all Tx data rates, based on eeprom values + * and current temperature. + * + * Since this is based on current temperature (at init time), these values may + * not be valid for very long, but it gives us a starting/default point, + * and allows us to active (i.e. using Tx) scan. + * + * This does *not* write values to NIC, just sets up our internal table. + */ +int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv) +{ + struct iwl_channel_info *ch_info = NULL; + struct iwl3945_channel_power_info *pwr_info; + struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; + int delta_index; + u8 rate_index; + u8 scan_tbl_index; + const s8 *clip_pwrs; /* array of power levels for each rate */ + u8 gain, dsp_atten; + s8 power; + u8 pwr_index, base_pwr_index, a_band; + u8 i; + int temperature; + + /* save temperature reference, + * so we can determine next time to calibrate */ + temperature = iwl3945_hw_reg_txpower_get_temperature(priv); + priv->last_temperature = temperature; + + iwl3945_hw_reg_init_channel_groups(priv); + + /* initialize Tx power info for each and every channel, 2.4 and 5.x */ + for (i = 0, ch_info = priv->channel_info; i < priv->channel_count; + i++, ch_info++) { + a_band = is_channel_a_band(ch_info); + if (!is_channel_valid(ch_info)) + continue; + + /* find this channel's channel group (*not* "band") index */ + ch_info->group_index = + iwl3945_hw_reg_get_ch_grp_index(priv, ch_info); + + /* Get this chnlgrp's rate->max/clip-powers table */ + clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers; + + /* calculate power index *adjustment* value according to + * diff between current temperature and factory temperature */ + delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature, + eeprom->groups[ch_info->group_index]. + temperature); + + IWL_DEBUG_POWER(priv, "Delta index for channel %d: %d [%d]\n", + ch_info->channel, delta_index, temperature + + IWL_TEMP_CONVERT); + + /* set tx power value for all OFDM rates */ + for (rate_index = 0; rate_index < IWL_OFDM_RATES; + rate_index++) { + s32 uninitialized_var(power_idx); + int rc; + + /* use channel group's clip-power table, + * but don't exceed channel's max power */ + s8 pwr = min(ch_info->max_power_avg, + clip_pwrs[rate_index]); + + pwr_info = &ch_info->power_info[rate_index]; + + /* get base (i.e. at factory-measured temperature) + * power table index for this rate's power */ + rc = iwl3945_hw_reg_get_matched_power_index(priv, pwr, + ch_info->group_index, + &power_idx); + if (rc) { + IWL_ERR(priv, "Invalid power index\n"); + return rc; + } + pwr_info->base_power_index = (u8) power_idx; + + /* temperature compensate */ + power_idx += delta_index; + + /* stay within range of gain table */ + power_idx = iwl3945_hw_reg_fix_power_index(power_idx); + + /* fill 1 OFDM rate's iwl3945_channel_power_info struct */ + pwr_info->requested_power = pwr; + pwr_info->power_table_index = (u8) power_idx; + pwr_info->tpc.tx_gain = + power_gain_table[a_band][power_idx].tx_gain; + pwr_info->tpc.dsp_atten = + power_gain_table[a_band][power_idx].dsp_atten; + } + + /* set tx power for CCK rates, based on OFDM 12 Mbit settings*/ + pwr_info = &ch_info->power_info[IWL_RATE_12M_INDEX_TABLE]; + power = pwr_info->requested_power + + IWL_CCK_FROM_OFDM_POWER_DIFF; + pwr_index = pwr_info->power_table_index + + IWL_CCK_FROM_OFDM_INDEX_DIFF; + base_pwr_index = pwr_info->base_power_index + + IWL_CCK_FROM_OFDM_INDEX_DIFF; + + /* stay within table range */ + pwr_index = iwl3945_hw_reg_fix_power_index(pwr_index); + gain = power_gain_table[a_band][pwr_index].tx_gain; + dsp_atten = power_gain_table[a_band][pwr_index].dsp_atten; + + /* fill each CCK rate's iwl3945_channel_power_info structure + * NOTE: All CCK-rate Txpwrs are the same for a given chnl! + * NOTE: CCK rates start at end of OFDM rates! */ + for (rate_index = 0; + rate_index < IWL_CCK_RATES; rate_index++) { + pwr_info = &ch_info->power_info[rate_index+IWL_OFDM_RATES]; + pwr_info->requested_power = power; + pwr_info->power_table_index = pwr_index; + pwr_info->base_power_index = base_pwr_index; + pwr_info->tpc.tx_gain = gain; + pwr_info->tpc.dsp_atten = dsp_atten; + } + + /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */ + for (scan_tbl_index = 0; + scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) { + s32 actual_index = (scan_tbl_index == 0) ? + IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE; + iwl3945_hw_reg_set_scan_power(priv, scan_tbl_index, + actual_index, clip_pwrs, ch_info, a_band); + } + } + + return 0; +} + +int iwl3945_hw_rxq_stop(struct iwl_priv *priv) +{ + int rc; + + iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), 0); + rc = iwl_poll_direct_bit(priv, FH39_RSSR_STATUS, + FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); + if (rc < 0) + IWL_ERR(priv, "Can't stop Rx DMA.\n"); + + return 0; +} + +int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq) +{ + int txq_id = txq->q.id; + + struct iwl3945_shared *shared_data = priv->_3945.shared_virt; + + shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr); + + iwl_write_direct32(priv, FH39_CBCC_CTRL(txq_id), 0); + iwl_write_direct32(priv, FH39_CBCC_BASE(txq_id), 0); + + iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), + FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT | + FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF | + FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD | + FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL | + FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE); + + /* fake read to flush all prev. writes */ + iwl_read32(priv, FH39_TSSR_CBB_BASE); + + return 0; +} + +/* + * HCMD utils + */ +static u16 iwl3945_get_hcmd_size(u8 cmd_id, u16 len) +{ + switch (cmd_id) { + case REPLY_RXON: + return sizeof(struct iwl3945_rxon_cmd); + case POWER_TABLE_CMD: + return sizeof(struct iwl3945_powertable_cmd); + default: + return len; + } +} + + +static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) +{ + struct iwl3945_addsta_cmd *addsta = (struct iwl3945_addsta_cmd *)data; + addsta->mode = cmd->mode; + memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify)); + memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo)); + addsta->station_flags = cmd->station_flags; + addsta->station_flags_msk = cmd->station_flags_msk; + addsta->tid_disable_tx = cpu_to_le16(0); + addsta->rate_n_flags = cmd->rate_n_flags; + addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid; + addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid; + addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn; + + return (u16)sizeof(struct iwl3945_addsta_cmd); +} + +static int iwl3945_add_bssid_station(struct iwl_priv *priv, + const u8 *addr, u8 *sta_id_r) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + int ret; + u8 sta_id; + unsigned long flags; + + if (sta_id_r) + *sta_id_r = IWL_INVALID_STATION; + + ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id); + if (ret) { + IWL_ERR(priv, "Unable to add station %pM\n", addr); + return ret; + } + + if (sta_id_r) + *sta_id_r = sta_id; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].used |= IWL_STA_LOCAL; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return 0; +} +static int iwl3945_manage_ibss_station(struct iwl_priv *priv, + struct ieee80211_vif *vif, bool add) +{ + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; + int ret; + + if (add) { + ret = iwl3945_add_bssid_station(priv, vif->bss_conf.bssid, + &vif_priv->ibss_bssid_sta_id); + if (ret) + return ret; + + iwl3945_sync_sta(priv, vif_priv->ibss_bssid_sta_id, + (priv->band == IEEE80211_BAND_5GHZ) ? + IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP); + iwl3945_rate_scale_init(priv->hw, vif_priv->ibss_bssid_sta_id); + + return 0; + } + + return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id, + vif->bss_conf.bssid); +} + +/** + * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table + */ +int iwl3945_init_hw_rate_table(struct iwl_priv *priv) +{ + int rc, i, index, prev_index; + struct iwl3945_rate_scaling_cmd rate_cmd = { + .reserved = {0, 0, 0}, + }; + struct iwl3945_rate_scaling_info *table = rate_cmd.table; + + for (i = 0; i < ARRAY_SIZE(iwl3945_rates); i++) { + index = iwl3945_rates[i].table_rs_index; + + table[index].rate_n_flags = + iwl3945_hw_set_rate_n_flags(iwl3945_rates[i].plcp, 0); + table[index].try_cnt = priv->retry_rate; + prev_index = iwl3945_get_prev_ieee_rate(i); + table[index].next_rate_index = + iwl3945_rates[prev_index].table_rs_index; + } + + switch (priv->band) { + case IEEE80211_BAND_5GHZ: + IWL_DEBUG_RATE(priv, "Select A mode rate scale\n"); + /* If one of the following CCK rates is used, + * have it fall back to the 6M OFDM rate */ + for (i = IWL_RATE_1M_INDEX_TABLE; + i <= IWL_RATE_11M_INDEX_TABLE; i++) + table[i].next_rate_index = + iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index; + + /* Don't fall back to CCK rates */ + table[IWL_RATE_12M_INDEX_TABLE].next_rate_index = + IWL_RATE_9M_INDEX_TABLE; + + /* Don't drop out of OFDM rates */ + table[IWL_RATE_6M_INDEX_TABLE].next_rate_index = + iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index; + break; + + case IEEE80211_BAND_2GHZ: + IWL_DEBUG_RATE(priv, "Select B/G mode rate scale\n"); + /* If an OFDM rate is used, have it fall back to the + * 1M CCK rates */ + + if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) && + iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { + + index = IWL_FIRST_CCK_RATE; + for (i = IWL_RATE_6M_INDEX_TABLE; + i <= IWL_RATE_54M_INDEX_TABLE; i++) + table[i].next_rate_index = + iwl3945_rates[index].table_rs_index; + + index = IWL_RATE_11M_INDEX_TABLE; + /* CCK shouldn't fall back to OFDM... */ + table[index].next_rate_index = IWL_RATE_5M_INDEX_TABLE; + } + break; + + default: + WARN_ON(1); + break; + } + + /* Update the rate scaling for control frame Tx */ + rate_cmd.table_id = 0; + rc = iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd), + &rate_cmd); + if (rc) + return rc; + + /* Update the rate scaling for data frame Tx */ + rate_cmd.table_id = 1; + return iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd), + &rate_cmd); +} + +/* Called when initializing driver */ +int iwl3945_hw_set_hw_params(struct iwl_priv *priv) +{ + memset((void *)&priv->hw_params, 0, + sizeof(struct iwl_hw_params)); + + priv->_3945.shared_virt = + dma_alloc_coherent(&priv->pci_dev->dev, + sizeof(struct iwl3945_shared), + &priv->_3945.shared_phys, GFP_KERNEL); + if (!priv->_3945.shared_virt) { + IWL_ERR(priv, "failed to allocate pci memory\n"); + return -ENOMEM; + } + + /* Assign number of Usable TX queues */ + priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; + + priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd); + priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_3K); + priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; + priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; + priv->hw_params.max_stations = IWL3945_STATION_COUNT; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL3945_BROADCAST_ID; + + priv->sta_key_max_num = STA_KEY_MAX_NUM; + + priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR; + priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL; + priv->hw_params.beacon_time_tsf_bits = IWL3945_EXT_BEACON_TIME_POS; + + return 0; +} + +unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv, + struct iwl3945_frame *frame, u8 rate) +{ + struct iwl3945_tx_beacon_cmd *tx_beacon_cmd; + unsigned int frame_size; + + tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u; + memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); + + tx_beacon_cmd->tx.sta_id = + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; + tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; + + frame_size = iwl3945_fill_beacon_frame(priv, + tx_beacon_cmd->frame, + sizeof(frame->u) - sizeof(*tx_beacon_cmd)); + + BUG_ON(frame_size > MAX_MPDU_SIZE); + tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); + + tx_beacon_cmd->tx.rate = rate; + tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK | + TX_CMD_FLG_TSF_MSK); + + /* supp_rates[0] == OFDM start at IWL_FIRST_OFDM_RATE*/ + tx_beacon_cmd->tx.supp_rates[0] = + (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; + + tx_beacon_cmd->tx.supp_rates[1] = + (IWL_CCK_BASIC_RATES_MASK & 0xF); + + return sizeof(struct iwl3945_tx_beacon_cmd) + frame_size; +} + +void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv) +{ + priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx; + priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx; +} + +void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv) +{ + INIT_DELAYED_WORK(&priv->_3945.thermal_periodic, + iwl3945_bg_reg_txpower_periodic); +} + +void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv) +{ + cancel_delayed_work(&priv->_3945.thermal_periodic); +} + +/* check contents of special bootstrap uCode SRAM */ +static int iwl3945_verify_bsm(struct iwl_priv *priv) + { + __le32 *image = priv->ucode_boot.v_addr; + u32 len = priv->ucode_boot.len; + u32 reg; + u32 val; + + IWL_DEBUG_INFO(priv, "Begin verify bsm\n"); + + /* verify BSM SRAM contents */ + val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG); + for (reg = BSM_SRAM_LOWER_BOUND; + reg < BSM_SRAM_LOWER_BOUND + len; + reg += sizeof(u32), image++) { + val = iwl_read_prph(priv, reg); + if (val != le32_to_cpu(*image)) { + IWL_ERR(priv, "BSM uCode verification failed at " + "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", + BSM_SRAM_LOWER_BOUND, + reg - BSM_SRAM_LOWER_BOUND, len, + val, le32_to_cpu(*image)); + return -EIO; + } + } + + IWL_DEBUG_INFO(priv, "BSM bootstrap uCode image OK\n"); + + return 0; +} + + +/****************************************************************************** + * + * EEPROM related functions + * + ******************************************************************************/ + +/* + * Clear the OWNER_MSK, to establish driver (instead of uCode running on + * embedded controller) as EEPROM reader; each read is a series of pulses + * to/from the EEPROM chip, not a single event, so even reads could conflict + * if they weren't arbitrated by some ownership mechanism. Here, the driver + * simply claims ownership, which should be safe when this function is called + * (i.e. before loading uCode!). + */ +static int iwl3945_eeprom_acquire_semaphore(struct iwl_priv *priv) +{ + _iwl_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK); + return 0; +} + + +static void iwl3945_eeprom_release_semaphore(struct iwl_priv *priv) +{ + return; +} + + /** + * iwl3945_load_bsm - Load bootstrap instructions + * + * BSM operation: + * + * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program + * in special SRAM that does not power down during RFKILL. When powering back + * up after power-saving sleeps (or during initial uCode load), the BSM loads + * the bootstrap program into the on-board processor, and starts it. + * + * The bootstrap program loads (via DMA) instructions and data for a new + * program from host DRAM locations indicated by the host driver in the + * BSM_DRAM_* registers. Once the new program is loaded, it starts + * automatically. + * + * When initializing the NIC, the host driver points the BSM to the + * "initialize" uCode image. This uCode sets up some internal data, then + * notifies host via "initialize alive" that it is complete. + * + * The host then replaces the BSM_DRAM_* pointer values to point to the + * normal runtime uCode instructions and a backup uCode data cache buffer + * (filled initially with starting data values for the on-board processor), + * then triggers the "initialize" uCode to load and launch the runtime uCode, + * which begins normal operation. + * + * When doing a power-save shutdown, runtime uCode saves data SRAM into + * the backup data cache in DRAM before SRAM is powered down. + * + * When powering back up, the BSM loads the bootstrap program. This reloads + * the runtime uCode instructions and the backup data cache into SRAM, + * and re-launches the runtime uCode from where it left off. + */ +static int iwl3945_load_bsm(struct iwl_priv *priv) +{ + __le32 *image = priv->ucode_boot.v_addr; + u32 len = priv->ucode_boot.len; + dma_addr_t pinst; + dma_addr_t pdata; + u32 inst_len; + u32 data_len; + int rc; + int i; + u32 done; + u32 reg_offset; + + IWL_DEBUG_INFO(priv, "Begin load bsm\n"); + + /* make sure bootstrap program is no larger than BSM's SRAM size */ + if (len > IWL39_MAX_BSM_SIZE) + return -EINVAL; + + /* Tell bootstrap uCode where to find the "Initialize" uCode + * in host DRAM ... host DRAM physical address bits 31:0 for 3945. + * NOTE: iwl3945_initialize_alive_start() will replace these values, + * after the "initialize" uCode has run, to point to + * runtime/protocol instructions and backup data cache. */ + pinst = priv->ucode_init.p_addr; + pdata = priv->ucode_init_data.p_addr; + inst_len = priv->ucode_init.len; + data_len = priv->ucode_init_data.len; + + iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); + iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); + iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); + iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); + + /* Fill BSM memory with bootstrap instructions */ + for (reg_offset = BSM_SRAM_LOWER_BOUND; + reg_offset < BSM_SRAM_LOWER_BOUND + len; + reg_offset += sizeof(u32), image++) + _iwl_write_prph(priv, reg_offset, + le32_to_cpu(*image)); + + rc = iwl3945_verify_bsm(priv); + if (rc) + return rc; + + /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ + iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); + iwl_write_prph(priv, BSM_WR_MEM_DST_REG, + IWL39_RTC_INST_LOWER_BOUND); + iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); + + /* Load bootstrap code into instruction SRAM now, + * to prepare to load "initialize" uCode */ + iwl_write_prph(priv, BSM_WR_CTRL_REG, + BSM_WR_CTRL_REG_BIT_START); + + /* Wait for load of bootstrap uCode to finish */ + for (i = 0; i < 100; i++) { + done = iwl_read_prph(priv, BSM_WR_CTRL_REG); + if (!(done & BSM_WR_CTRL_REG_BIT_START)) + break; + udelay(10); + } + if (i < 100) + IWL_DEBUG_INFO(priv, "BSM write complete, poll %d iterations\n", i); + else { + IWL_ERR(priv, "BSM write did not complete!\n"); + return -EIO; + } + + /* Enable future boot loads whenever power management unit triggers it + * (e.g. when powering back up after power-save shutdown) */ + iwl_write_prph(priv, BSM_WR_CTRL_REG, + BSM_WR_CTRL_REG_BIT_START_EN); + + return 0; +} + +static struct iwl_hcmd_ops iwl3945_hcmd = { + .rxon_assoc = iwl3945_send_rxon_assoc, + .commit_rxon = iwl3945_commit_rxon, + .send_bt_config = iwl_send_bt_config, +}; + +static struct iwl_lib_ops iwl3945_lib = { + .txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd, + .txq_free_tfd = iwl3945_hw_txq_free_tfd, + .txq_init = iwl3945_hw_tx_queue_init, + .load_ucode = iwl3945_load_bsm, + .dump_nic_event_log = iwl3945_dump_nic_event_log, + .dump_nic_error_log = iwl3945_dump_nic_error_log, + .apm_ops = { + .init = iwl3945_apm_init, + .config = iwl3945_nic_config, + }, + .eeprom_ops = { + .regulatory_bands = { + EEPROM_REGULATORY_BAND_1_CHANNELS, + EEPROM_REGULATORY_BAND_2_CHANNELS, + EEPROM_REGULATORY_BAND_3_CHANNELS, + EEPROM_REGULATORY_BAND_4_CHANNELS, + EEPROM_REGULATORY_BAND_5_CHANNELS, + EEPROM_REGULATORY_BAND_NO_HT40, + EEPROM_REGULATORY_BAND_NO_HT40, + }, + .acquire_semaphore = iwl3945_eeprom_acquire_semaphore, + .release_semaphore = iwl3945_eeprom_release_semaphore, + .query_addr = iwlcore_eeprom_query_addr, + }, + .send_tx_power = iwl3945_send_tx_power, + .is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr, + .isr_ops = { + .isr = iwl_isr_legacy, + }, + + .debugfs_ops = { + .rx_stats_read = iwl3945_ucode_rx_stats_read, + .tx_stats_read = iwl3945_ucode_tx_stats_read, + .general_stats_read = iwl3945_ucode_general_stats_read, + }, +}; + +static const struct iwl_legacy_ops iwl3945_legacy_ops = { + .post_associate = iwl3945_post_associate, + .config_ap = iwl3945_config_ap, + .manage_ibss_station = iwl3945_manage_ibss_station, +}; + +static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { + .get_hcmd_size = iwl3945_get_hcmd_size, + .build_addsta_hcmd = iwl3945_build_addsta_hcmd, + .tx_cmd_protection = iwl_legacy_tx_cmd_protection, + .request_scan = iwl3945_request_scan, + .post_scan = iwl3945_post_scan, +}; + +static const struct iwl_ops iwl3945_ops = { + .lib = &iwl3945_lib, + .hcmd = &iwl3945_hcmd, + .utils = &iwl3945_hcmd_utils, + .led = &iwl3945_led_ops, + .legacy = &iwl3945_legacy_ops, + .ieee80211_ops = &iwl3945_hw_ops, +}; + +static struct iwl_base_params iwl3945_base_params = { + .eeprom_size = IWL3945_EEPROM_IMG_SIZE, + .num_of_queues = IWL39_NUM_QUEUES, + .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL, + .set_l0s = false, + .use_bsm = true, + .use_isr_legacy = true, + .led_compensation = 64, + .broken_powersave = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, + .wd_timeout = IWL_DEF_WD_TIMEOUT, + .max_event_log_size = 512, + .tx_power_by_driver = true, +}; + +static struct iwl_cfg iwl3945_bg_cfg = { + .name = "3945BG", + .fw_name_pre = IWL3945_FW_PRE, + .ucode_api_max = IWL3945_UCODE_API_MAX, + .ucode_api_min = IWL3945_UCODE_API_MIN, + .sku = IWL_SKU_G, + .eeprom_ver = EEPROM_3945_EEPROM_VERSION, + .ops = &iwl3945_ops, + .mod_params = &iwl3945_mod_params, + .base_params = &iwl3945_base_params, + .led_mode = IWL_LED_BLINK, +}; + +static struct iwl_cfg iwl3945_abg_cfg = { + .name = "3945ABG", + .fw_name_pre = IWL3945_FW_PRE, + .ucode_api_max = IWL3945_UCODE_API_MAX, + .ucode_api_min = IWL3945_UCODE_API_MIN, + .sku = IWL_SKU_A|IWL_SKU_G, + .eeprom_ver = EEPROM_3945_EEPROM_VERSION, + .ops = &iwl3945_ops, + .mod_params = &iwl3945_mod_params, + .base_params = &iwl3945_base_params, + .led_mode = IWL_LED_BLINK, +}; + +DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { + {IWL_PCI_DEVICE(0x4222, 0x1005, iwl3945_bg_cfg)}, + {IWL_PCI_DEVICE(0x4222, 0x1034, iwl3945_bg_cfg)}, + {IWL_PCI_DEVICE(0x4222, 0x1044, iwl3945_bg_cfg)}, + {IWL_PCI_DEVICE(0x4227, 0x1014, iwl3945_bg_cfg)}, + {IWL_PCI_DEVICE(0x4222, PCI_ANY_ID, iwl3945_abg_cfg)}, + {IWL_PCI_DEVICE(0x4227, PCI_ANY_ID, iwl3945_abg_cfg)}, + {0} +}; + +MODULE_DEVICE_TABLE(pci, iwl3945_hw_card_ids); diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h new file mode 100644 index 000000000000..3eef1eb74a78 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -0,0 +1,308 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ +/* + * Please use this file (iwl-3945.h) for driver implementation definitions. + * Please use iwl-3945-commands.h for uCode API definitions. + * Please use iwl-3945-hw.h for hardware-related definitions. + */ + +#ifndef __iwl_3945_h__ +#define __iwl_3945_h__ + +#include /* for struct pci_device_id */ +#include +#include + +/* Hardware specific file defines the PCI IDs table for that hardware module */ +extern const struct pci_device_id iwl3945_hw_card_ids[]; + +#include "iwl-csr.h" +#include "iwl-prph.h" +#include "iwl-fh.h" +#include "iwl-3945-hw.h" +#include "iwl-debug.h" +#include "iwl-power.h" +#include "iwl-dev.h" +#include "iwl-led.h" + +/* Highest firmware API version supported */ +#define IWL3945_UCODE_API_MAX 2 + +/* Lowest firmware API version supported */ +#define IWL3945_UCODE_API_MIN 1 + +#define IWL3945_FW_PRE "iwlwifi-3945-" +#define _IWL3945_MODULE_FIRMWARE(api) IWL3945_FW_PRE #api ".ucode" +#define IWL3945_MODULE_FIRMWARE(api) _IWL3945_MODULE_FIRMWARE(api) + +/* Default noise level to report when noise measurement is not available. + * This may be because we're: + * 1) Not associated (4965, no beacon statistics being sent to driver) + * 2) Scanning (noise measurement does not apply to associated channel) + * 3) Receiving CCK (3945 delivers noise info only for OFDM frames) + * Use default noise value of -127 ... this is below the range of measurable + * Rx dBm for either 3945 or 4965, so it can indicate "unmeasurable" to user. + * Also, -127 works better than 0 when averaging frames with/without + * noise info (e.g. averaging might be done in app); measured dBm values are + * always negative ... using a negative value as the default keeps all + * averages within an s8's (used in some apps) range of negative values. */ +#define IWL_NOISE_MEAS_NOT_AVAILABLE (-127) + +/* Module parameters accessible from iwl-*.c */ +extern struct iwl_mod_params iwl3945_mod_params; + +struct iwl3945_rate_scale_data { + u64 data; + s32 success_counter; + s32 success_ratio; + s32 counter; + s32 average_tpt; + unsigned long stamp; +}; + +struct iwl3945_rs_sta { + spinlock_t lock; + struct iwl_priv *priv; + s32 *expected_tpt; + unsigned long last_partial_flush; + unsigned long last_flush; + u32 flush_time; + u32 last_tx_packets; + u32 tx_packets; + u8 tgg; + u8 flush_pending; + u8 start_rate; + struct timer_list rate_scale_flush; + struct iwl3945_rate_scale_data win[IWL_RATE_COUNT_3945]; +#ifdef CONFIG_MAC80211_DEBUGFS + struct dentry *rs_sta_dbgfs_stats_table_file; +#endif + + /* used to be in sta_info */ + int last_txrate_idx; +}; + + +/* + * The common struct MUST be first because it is shared between + * 3945 and agn! + */ +struct iwl3945_sta_priv { + struct iwl_station_priv_common common; + struct iwl3945_rs_sta rs_sta; +}; + +enum iwl3945_antenna { + IWL_ANTENNA_DIVERSITY, + IWL_ANTENNA_MAIN, + IWL_ANTENNA_AUX +}; + +/* + * RTS threshold here is total size [2347] minus 4 FCS bytes + * Per spec: + * a value of 0 means RTS on all data/management packets + * a value > max MSDU size means no RTS + * else RTS for data/management frames where MPDU is larger + * than RTS value. + */ +#define DEFAULT_RTS_THRESHOLD 2347U +#define MIN_RTS_THRESHOLD 0U +#define MAX_RTS_THRESHOLD 2347U +#define MAX_MSDU_SIZE 2304U +#define MAX_MPDU_SIZE 2346U +#define DEFAULT_BEACON_INTERVAL 100U +#define DEFAULT_SHORT_RETRY_LIMIT 7U +#define DEFAULT_LONG_RETRY_LIMIT 4U + +#define IWL_TX_FIFO_AC0 0 +#define IWL_TX_FIFO_AC1 1 +#define IWL_TX_FIFO_AC2 2 +#define IWL_TX_FIFO_AC3 3 +#define IWL_TX_FIFO_HCCA_1 5 +#define IWL_TX_FIFO_HCCA_2 6 +#define IWL_TX_FIFO_NONE 7 + +#define IEEE80211_DATA_LEN 2304 +#define IEEE80211_4ADDR_LEN 30 +#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) +#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) + +struct iwl3945_frame { + union { + struct ieee80211_hdr frame; + struct iwl3945_tx_beacon_cmd beacon; + u8 raw[IEEE80211_FRAME_LEN]; + u8 cmd[360]; + } u; + struct list_head list; +}; + +#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) +#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) +#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) + +#define SUP_RATE_11A_MAX_NUM_CHANNELS 8 +#define SUP_RATE_11B_MAX_NUM_CHANNELS 4 +#define SUP_RATE_11G_MAX_NUM_CHANNELS 12 + +#define IWL_SUPPORTED_RATES_IE_LEN 8 + +#define SCAN_INTERVAL 100 + +#define MAX_TID_COUNT 9 + +#define IWL_INVALID_RATE 0xFF +#define IWL_INVALID_VALUE -1 + +#define STA_PS_STATUS_WAKE 0 +#define STA_PS_STATUS_SLEEP 1 + +struct iwl3945_ibss_seq { + u8 mac[ETH_ALEN]; + u16 seq_num; + u16 frag_num; + unsigned long packet_time; + struct list_head list; +}; + +#define IWL_RX_HDR(x) ((struct iwl3945_rx_frame_hdr *)(\ + x->u.rx_frame.stats.payload + \ + x->u.rx_frame.stats.phy_count)) +#define IWL_RX_END(x) ((struct iwl3945_rx_frame_end *)(\ + IWL_RX_HDR(x)->payload + \ + le16_to_cpu(IWL_RX_HDR(x)->len))) +#define IWL_RX_STATS(x) (&x->u.rx_frame.stats) +#define IWL_RX_DATA(x) (IWL_RX_HDR(x)->payload) + + +/****************************************************************************** + * + * Functions implemented in iwl-base.c which are forward declared here + * for use by iwl-*.c + * + *****************************************************************************/ +extern int iwl3945_calc_db_from_ratio(int sig_ratio); +extern void iwl3945_rx_replenish(void *data); +extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); +extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, + struct ieee80211_hdr *hdr,int left); +extern int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, + char **buf, bool display); +extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv); + +/****************************************************************************** + * + * Functions implemented in iwl-[34]*.c which are forward declared here + * for use by iwl-base.c + * + * NOTE: The implementation of these functions are hardware specific + * which is why they are in the hardware specific files (vs. iwl-base.c) + * + * Naming convention -- + * iwl3945_ <-- Its part of iwlwifi (should be changed to iwl3945_) + * iwl3945_hw_ <-- Hardware specific (implemented in iwl-XXXX.c by all HW) + * iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX) + * iwl3945_bg_ <-- Called from work queue context + * iwl3945_mac_ <-- mac80211 callback + * + ****************************************************************************/ +extern void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv); +extern void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv); +extern void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv); +extern int iwl3945_hw_rxq_stop(struct iwl_priv *priv); +extern int iwl3945_hw_set_hw_params(struct iwl_priv *priv); +extern int iwl3945_hw_nic_init(struct iwl_priv *priv); +extern int iwl3945_hw_nic_stop_master(struct iwl_priv *priv); +extern void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv); +extern void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv); +extern int iwl3945_hw_nic_reset(struct iwl_priv *priv); +extern int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, + struct iwl_tx_queue *txq, + dma_addr_t addr, u16 len, + u8 reset, u8 pad); +extern void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, + struct iwl_tx_queue *txq); +extern int iwl3945_hw_get_temperature(struct iwl_priv *priv); +extern int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, + struct iwl_tx_queue *txq); +extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv, + struct iwl3945_frame *frame, u8 rate); +void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, + struct iwl_device_cmd *cmd, + struct ieee80211_tx_info *info, + struct ieee80211_hdr *hdr, + int sta_id, int tx_id); +extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv); +extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power); +extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); +void iwl3945_reply_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); +extern void iwl3945_disable_events(struct iwl_priv *priv); +extern int iwl4965_get_temperature(const struct iwl_priv *priv); +extern void iwl3945_post_associate(struct iwl_priv *priv); +extern void iwl3945_config_ap(struct iwl_priv *priv); + +extern int iwl3945_commit_rxon(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); + +/** + * iwl3945_hw_find_station - Find station id for a given BSSID + * @bssid: MAC address of station ID to find + * + * NOTE: This should not be hardware specific but the code has + * not yet been merged into a single common layer for managing the + * station tables. + */ +extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid); + +extern struct ieee80211_ops iwl3945_hw_ops; + +/* + * Forward declare iwl-3945.c functions for iwl-base.c + */ +extern __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv); +extern int iwl3945_init_hw_rate_table(struct iwl_priv *priv); +extern void iwl3945_reg_txpower_periodic(struct iwl_priv *priv); +extern int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv); + +extern const struct iwl_channel_info *iwl3945_get_channel_info( + const struct iwl_priv *priv, enum ieee80211_band band, u16 channel); + +extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate); + +/* scanning */ +int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); +void iwl3945_post_scan(struct iwl_priv *priv); + +/* rates */ +extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945]; + +/* Requires full declaration of iwl_priv before including */ +#include "iwl-io.h" + +#endif diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h new file mode 100644 index 000000000000..9166794eda0d --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h @@ -0,0 +1,792 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Please use this file (iwl-4965-hw.h) only for hardware-related definitions. + * Use iwl-commands.h for uCode API definitions. + * Use iwl-dev.h for driver implementation definitions. + */ + +#ifndef __iwl_4965_hw_h__ +#define __iwl_4965_hw_h__ + +#include "iwl-fh.h" + +/* EEPROM */ +#define IWL4965_EEPROM_IMG_SIZE 1024 + +/* + * uCode queue management definitions ... + * The first queue used for block-ack aggregation is #7 (4965 only). + * All block-ack aggregation queues should map to Tx DMA/FIFO channel 7. + */ +#define IWL49_FIRST_AMPDU_QUEUE 7 + +/* Sizes and addresses for instruction and data memory (SRAM) in + * 4965's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ +#define IWL49_RTC_INST_LOWER_BOUND (0x000000) +#define IWL49_RTC_INST_UPPER_BOUND (0x018000) + +#define IWL49_RTC_DATA_LOWER_BOUND (0x800000) +#define IWL49_RTC_DATA_UPPER_BOUND (0x80A000) + +#define IWL49_RTC_INST_SIZE (IWL49_RTC_INST_UPPER_BOUND - \ + IWL49_RTC_INST_LOWER_BOUND) +#define IWL49_RTC_DATA_SIZE (IWL49_RTC_DATA_UPPER_BOUND - \ + IWL49_RTC_DATA_LOWER_BOUND) + +#define IWL49_MAX_INST_SIZE IWL49_RTC_INST_SIZE +#define IWL49_MAX_DATA_SIZE IWL49_RTC_DATA_SIZE + +/* Size of uCode instruction memory in bootstrap state machine */ +#define IWL49_MAX_BSM_SIZE BSM_SRAM_SIZE + +static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr) +{ + return (addr >= IWL49_RTC_DATA_LOWER_BOUND) && + (addr < IWL49_RTC_DATA_UPPER_BOUND); +} + +/********************* START TEMPERATURE *************************************/ + +/** + * 4965 temperature calculation. + * + * The driver must calculate the device temperature before calculating + * a txpower setting (amplifier gain is temperature dependent). The + * calculation uses 4 measurements, 3 of which (R1, R2, R3) are calibration + * values used for the life of the driver, and one of which (R4) is the + * real-time temperature indicator. + * + * uCode provides all 4 values to the driver via the "initialize alive" + * notification (see struct iwl4965_init_alive_resp). After the runtime uCode + * image loads, uCode updates the R4 value via statistics notifications + * (see STATISTICS_NOTIFICATION), which occur after each received beacon + * when associated, or can be requested via REPLY_STATISTICS_CMD. + * + * NOTE: uCode provides the R4 value as a 23-bit signed value. Driver + * must sign-extend to 32 bits before applying formula below. + * + * Formula: + * + * degrees Kelvin = ((97 * 259 * (R4 - R2) / (R3 - R1)) / 100) + 8 + * + * NOTE: The basic formula is 259 * (R4-R2) / (R3-R1). The 97/100 is + * an additional correction, which should be centered around 0 degrees + * Celsius (273 degrees Kelvin). The 8 (3 percent of 273) compensates for + * centering the 97/100 correction around 0 degrees K. + * + * Add 273 to Kelvin value to find degrees Celsius, for comparing current + * temperature with factory-measured temperatures when calculating txpower + * settings. + */ +#define TEMPERATURE_CALIB_KELVIN_OFFSET 8 +#define TEMPERATURE_CALIB_A_VAL 259 + +/* Limit range of calculated temperature to be between these Kelvin values */ +#define IWL_TX_POWER_TEMPERATURE_MIN (263) +#define IWL_TX_POWER_TEMPERATURE_MAX (410) + +#define IWL_TX_POWER_TEMPERATURE_OUT_OF_RANGE(t) \ + (((t) < IWL_TX_POWER_TEMPERATURE_MIN) || \ + ((t) > IWL_TX_POWER_TEMPERATURE_MAX)) + +/********************* END TEMPERATURE ***************************************/ + +/********************* START TXPOWER *****************************************/ + +/** + * 4965 txpower calculations rely on information from three sources: + * + * 1) EEPROM + * 2) "initialize" alive notification + * 3) statistics notifications + * + * EEPROM data consists of: + * + * 1) Regulatory information (max txpower and channel usage flags) is provided + * separately for each channel that can possibly supported by 4965. + * 40 MHz wide (.11n HT40) channels are listed separately from 20 MHz + * (legacy) channels. + * + * See struct iwl4965_eeprom_channel for format, and struct iwl4965_eeprom + * for locations in EEPROM. + * + * 2) Factory txpower calibration information is provided separately for + * sub-bands of contiguous channels. 2.4GHz has just one sub-band, + * but 5 GHz has several sub-bands. + * + * In addition, per-band (2.4 and 5 Ghz) saturation txpowers are provided. + * + * See struct iwl4965_eeprom_calib_info (and the tree of structures + * contained within it) for format, and struct iwl4965_eeprom for + * locations in EEPROM. + * + * "Initialization alive" notification (see struct iwl4965_init_alive_resp) + * consists of: + * + * 1) Temperature calculation parameters. + * + * 2) Power supply voltage measurement. + * + * 3) Tx gain compensation to balance 2 transmitters for MIMO use. + * + * Statistics notifications deliver: + * + * 1) Current values for temperature param R4. + */ + +/** + * To calculate a txpower setting for a given desired target txpower, channel, + * modulation bit rate, and transmitter chain (4965 has 2 transmitters to + * support MIMO and transmit diversity), driver must do the following: + * + * 1) Compare desired txpower vs. (EEPROM) regulatory limit for this channel. + * Do not exceed regulatory limit; reduce target txpower if necessary. + * + * If setting up txpowers for MIMO rates (rate indexes 8-15, 24-31), + * 2 transmitters will be used simultaneously; driver must reduce the + * regulatory limit by 3 dB (half-power) for each transmitter, so the + * combined total output of the 2 transmitters is within regulatory limits. + * + * + * 2) Compare target txpower vs. (EEPROM) saturation txpower *reduced by + * backoff for this bit rate*. Do not exceed (saturation - backoff[rate]); + * reduce target txpower if necessary. + * + * Backoff values below are in 1/2 dB units (equivalent to steps in + * txpower gain tables): + * + * OFDM 6 - 36 MBit: 10 steps (5 dB) + * OFDM 48 MBit: 15 steps (7.5 dB) + * OFDM 54 MBit: 17 steps (8.5 dB) + * OFDM 60 MBit: 20 steps (10 dB) + * CCK all rates: 10 steps (5 dB) + * + * Backoff values apply to saturation txpower on a per-transmitter basis; + * when using MIMO (2 transmitters), each transmitter uses the same + * saturation level provided in EEPROM, and the same backoff values; + * no reduction (such as with regulatory txpower limits) is required. + * + * Saturation and Backoff values apply equally to 20 Mhz (legacy) channel + * widths and 40 Mhz (.11n HT40) channel widths; there is no separate + * factory measurement for ht40 channels. + * + * The result of this step is the final target txpower. The rest of + * the steps figure out the proper settings for the device to achieve + * that target txpower. + * + * + * 3) Determine (EEPROM) calibration sub band for the target channel, by + * comparing against first and last channels in each sub band + * (see struct iwl4965_eeprom_calib_subband_info). + * + * + * 4) Linearly interpolate (EEPROM) factory calibration measurement sets, + * referencing the 2 factory-measured (sample) channels within the sub band. + * + * Interpolation is based on difference between target channel's frequency + * and the sample channels' frequencies. Since channel numbers are based + * on frequency (5 MHz between each channel number), this is equivalent + * to interpolating based on channel number differences. + * + * Note that the sample channels may or may not be the channels at the + * edges of the sub band. The target channel may be "outside" of the + * span of the sampled channels. + * + * Driver may choose the pair (for 2 Tx chains) of measurements (see + * struct iwl4965_eeprom_calib_ch_info) for which the actual measured + * txpower comes closest to the desired txpower. Usually, though, + * the middle set of measurements is closest to the regulatory limits, + * and is therefore a good choice for all txpower calculations (this + * assumes that high accuracy is needed for maximizing legal txpower, + * while lower txpower configurations do not need as much accuracy). + * + * Driver should interpolate both members of the chosen measurement pair, + * i.e. for both Tx chains (radio transmitters), unless the driver knows + * that only one of the chains will be used (e.g. only one tx antenna + * connected, but this should be unusual). The rate scaling algorithm + * switches antennas to find best performance, so both Tx chains will + * be used (although only one at a time) even for non-MIMO transmissions. + * + * Driver should interpolate factory values for temperature, gain table + * index, and actual power. The power amplifier detector values are + * not used by the driver. + * + * Sanity check: If the target channel happens to be one of the sample + * channels, the results should agree with the sample channel's + * measurements! + * + * + * 5) Find difference between desired txpower and (interpolated) + * factory-measured txpower. Using (interpolated) factory gain table index + * (shown elsewhere) as a starting point, adjust this index lower to + * increase txpower, or higher to decrease txpower, until the target + * txpower is reached. Each step in the gain table is 1/2 dB. + * + * For example, if factory measured txpower is 16 dBm, and target txpower + * is 13 dBm, add 6 steps to the factory gain index to reduce txpower + * by 3 dB. + * + * + * 6) Find difference between current device temperature and (interpolated) + * factory-measured temperature for sub-band. Factory values are in + * degrees Celsius. To calculate current temperature, see comments for + * "4965 temperature calculation". + * + * If current temperature is higher than factory temperature, driver must + * increase gain (lower gain table index), and vice verse. + * + * Temperature affects gain differently for different channels: + * + * 2.4 GHz all channels: 3.5 degrees per half-dB step + * 5 GHz channels 34-43: 4.5 degrees per half-dB step + * 5 GHz channels >= 44: 4.0 degrees per half-dB step + * + * NOTE: Temperature can increase rapidly when transmitting, especially + * with heavy traffic at high txpowers. Driver should update + * temperature calculations often under these conditions to + * maintain strong txpower in the face of rising temperature. + * + * + * 7) Find difference between current power supply voltage indicator + * (from "initialize alive") and factory-measured power supply voltage + * indicator (EEPROM). + * + * If the current voltage is higher (indicator is lower) than factory + * voltage, gain should be reduced (gain table index increased) by: + * + * (eeprom - current) / 7 + * + * If the current voltage is lower (indicator is higher) than factory + * voltage, gain should be increased (gain table index decreased) by: + * + * 2 * (current - eeprom) / 7 + * + * If number of index steps in either direction turns out to be > 2, + * something is wrong ... just use 0. + * + * NOTE: Voltage compensation is independent of band/channel. + * + * NOTE: "Initialize" uCode measures current voltage, which is assumed + * to be constant after this initial measurement. Voltage + * compensation for txpower (number of steps in gain table) + * may be calculated once and used until the next uCode bootload. + * + * + * 8) If setting up txpowers for MIMO rates (rate indexes 8-15, 24-31), + * adjust txpower for each transmitter chain, so txpower is balanced + * between the two chains. There are 5 pairs of tx_atten[group][chain] + * values in "initialize alive", one pair for each of 5 channel ranges: + * + * Group 0: 5 GHz channel 34-43 + * Group 1: 5 GHz channel 44-70 + * Group 2: 5 GHz channel 71-124 + * Group 3: 5 GHz channel 125-200 + * Group 4: 2.4 GHz all channels + * + * Add the tx_atten[group][chain] value to the index for the target chain. + * The values are signed, but are in pairs of 0 and a non-negative number, + * so as to reduce gain (if necessary) of the "hotter" channel. This + * avoids any need to double-check for regulatory compliance after + * this step. + * + * + * 9) If setting up for a CCK rate, lower the gain by adding a CCK compensation + * value to the index: + * + * Hardware rev B: 9 steps (4.5 dB) + * Hardware rev C: 5 steps (2.5 dB) + * + * Hardware rev for 4965 can be determined by reading CSR_HW_REV_WA_REG, + * bits [3:2], 1 = B, 2 = C. + * + * NOTE: This compensation is in addition to any saturation backoff that + * might have been applied in an earlier step. + * + * + * 10) Select the gain table, based on band (2.4 vs 5 GHz). + * + * Limit the adjusted index to stay within the table! + * + * + * 11) Read gain table entries for DSP and radio gain, place into appropriate + * location(s) in command (struct iwl4965_txpowertable_cmd). + */ + +/** + * When MIMO is used (2 transmitters operating simultaneously), driver should + * limit each transmitter to deliver a max of 3 dB below the regulatory limit + * for the device. That is, use half power for each transmitter, so total + * txpower is within regulatory limits. + * + * The value "6" represents number of steps in gain table to reduce power 3 dB. + * Each step is 1/2 dB. + */ +#define IWL_TX_POWER_MIMO_REGULATORY_COMPENSATION (6) + +/** + * CCK gain compensation. + * + * When calculating txpowers for CCK, after making sure that the target power + * is within regulatory and saturation limits, driver must additionally + * back off gain by adding these values to the gain table index. + * + * Hardware rev for 4965 can be determined by reading CSR_HW_REV_WA_REG, + * bits [3:2], 1 = B, 2 = C. + */ +#define IWL_TX_POWER_CCK_COMPENSATION_B_STEP (9) +#define IWL_TX_POWER_CCK_COMPENSATION_C_STEP (5) + +/* + * 4965 power supply voltage compensation for txpower + */ +#define TX_POWER_IWL_VOLTAGE_CODES_PER_03V (7) + +/** + * Gain tables. + * + * The following tables contain pair of values for setting txpower, i.e. + * gain settings for the output of the device's digital signal processor (DSP), + * and for the analog gain structure of the transmitter. + * + * Each entry in the gain tables represents a step of 1/2 dB. Note that these + * are *relative* steps, not indications of absolute output power. Output + * power varies with temperature, voltage, and channel frequency, and also + * requires consideration of average power (to satisfy regulatory constraints), + * and peak power (to avoid distortion of the output signal). + * + * Each entry contains two values: + * 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained + * linear value that multiplies the output of the digital signal processor, + * before being sent to the analog radio. + * 2) Radio gain. This sets the analog gain of the radio Tx path. + * It is a coarser setting, and behaves in a logarithmic (dB) fashion. + * + * EEPROM contains factory calibration data for txpower. This maps actual + * measured txpower levels to gain settings in the "well known" tables + * below ("well-known" means here that both factory calibration *and* the + * driver work with the same table). + * + * There are separate tables for 2.4 GHz and 5 GHz bands. The 5 GHz table + * has an extension (into negative indexes), in case the driver needs to + * boost power setting for high device temperatures (higher than would be + * present during factory calibration). A 5 Ghz EEPROM index of "40" + * corresponds to the 49th entry in the table used by the driver. + */ +#define MIN_TX_GAIN_INDEX (0) /* highest gain, lowest idx, 2.4 */ +#define MIN_TX_GAIN_INDEX_52GHZ_EXT (-9) /* highest gain, lowest idx, 5 */ + +/** + * 2.4 GHz gain table + * + * Index Dsp gain Radio gain + * 0 110 0x3f (highest gain) + * 1 104 0x3f + * 2 98 0x3f + * 3 110 0x3e + * 4 104 0x3e + * 5 98 0x3e + * 6 110 0x3d + * 7 104 0x3d + * 8 98 0x3d + * 9 110 0x3c + * 10 104 0x3c + * 11 98 0x3c + * 12 110 0x3b + * 13 104 0x3b + * 14 98 0x3b + * 15 110 0x3a + * 16 104 0x3a + * 17 98 0x3a + * 18 110 0x39 + * 19 104 0x39 + * 20 98 0x39 + * 21 110 0x38 + * 22 104 0x38 + * 23 98 0x38 + * 24 110 0x37 + * 25 104 0x37 + * 26 98 0x37 + * 27 110 0x36 + * 28 104 0x36 + * 29 98 0x36 + * 30 110 0x35 + * 31 104 0x35 + * 32 98 0x35 + * 33 110 0x34 + * 34 104 0x34 + * 35 98 0x34 + * 36 110 0x33 + * 37 104 0x33 + * 38 98 0x33 + * 39 110 0x32 + * 40 104 0x32 + * 41 98 0x32 + * 42 110 0x31 + * 43 104 0x31 + * 44 98 0x31 + * 45 110 0x30 + * 46 104 0x30 + * 47 98 0x30 + * 48 110 0x6 + * 49 104 0x6 + * 50 98 0x6 + * 51 110 0x5 + * 52 104 0x5 + * 53 98 0x5 + * 54 110 0x4 + * 55 104 0x4 + * 56 98 0x4 + * 57 110 0x3 + * 58 104 0x3 + * 59 98 0x3 + * 60 110 0x2 + * 61 104 0x2 + * 62 98 0x2 + * 63 110 0x1 + * 64 104 0x1 + * 65 98 0x1 + * 66 110 0x0 + * 67 104 0x0 + * 68 98 0x0 + * 69 97 0 + * 70 96 0 + * 71 95 0 + * 72 94 0 + * 73 93 0 + * 74 92 0 + * 75 91 0 + * 76 90 0 + * 77 89 0 + * 78 88 0 + * 79 87 0 + * 80 86 0 + * 81 85 0 + * 82 84 0 + * 83 83 0 + * 84 82 0 + * 85 81 0 + * 86 80 0 + * 87 79 0 + * 88 78 0 + * 89 77 0 + * 90 76 0 + * 91 75 0 + * 92 74 0 + * 93 73 0 + * 94 72 0 + * 95 71 0 + * 96 70 0 + * 97 69 0 + * 98 68 0 + */ + +/** + * 5 GHz gain table + * + * Index Dsp gain Radio gain + * -9 123 0x3F (highest gain) + * -8 117 0x3F + * -7 110 0x3F + * -6 104 0x3F + * -5 98 0x3F + * -4 110 0x3E + * -3 104 0x3E + * -2 98 0x3E + * -1 110 0x3D + * 0 104 0x3D + * 1 98 0x3D + * 2 110 0x3C + * 3 104 0x3C + * 4 98 0x3C + * 5 110 0x3B + * 6 104 0x3B + * 7 98 0x3B + * 8 110 0x3A + * 9 104 0x3A + * 10 98 0x3A + * 11 110 0x39 + * 12 104 0x39 + * 13 98 0x39 + * 14 110 0x38 + * 15 104 0x38 + * 16 98 0x38 + * 17 110 0x37 + * 18 104 0x37 + * 19 98 0x37 + * 20 110 0x36 + * 21 104 0x36 + * 22 98 0x36 + * 23 110 0x35 + * 24 104 0x35 + * 25 98 0x35 + * 26 110 0x34 + * 27 104 0x34 + * 28 98 0x34 + * 29 110 0x33 + * 30 104 0x33 + * 31 98 0x33 + * 32 110 0x32 + * 33 104 0x32 + * 34 98 0x32 + * 35 110 0x31 + * 36 104 0x31 + * 37 98 0x31 + * 38 110 0x30 + * 39 104 0x30 + * 40 98 0x30 + * 41 110 0x25 + * 42 104 0x25 + * 43 98 0x25 + * 44 110 0x24 + * 45 104 0x24 + * 46 98 0x24 + * 47 110 0x23 + * 48 104 0x23 + * 49 98 0x23 + * 50 110 0x22 + * 51 104 0x18 + * 52 98 0x18 + * 53 110 0x17 + * 54 104 0x17 + * 55 98 0x17 + * 56 110 0x16 + * 57 104 0x16 + * 58 98 0x16 + * 59 110 0x15 + * 60 104 0x15 + * 61 98 0x15 + * 62 110 0x14 + * 63 104 0x14 + * 64 98 0x14 + * 65 110 0x13 + * 66 104 0x13 + * 67 98 0x13 + * 68 110 0x12 + * 69 104 0x08 + * 70 98 0x08 + * 71 110 0x07 + * 72 104 0x07 + * 73 98 0x07 + * 74 110 0x06 + * 75 104 0x06 + * 76 98 0x06 + * 77 110 0x05 + * 78 104 0x05 + * 79 98 0x05 + * 80 110 0x04 + * 81 104 0x04 + * 82 98 0x04 + * 83 110 0x03 + * 84 104 0x03 + * 85 98 0x03 + * 86 110 0x02 + * 87 104 0x02 + * 88 98 0x02 + * 89 110 0x01 + * 90 104 0x01 + * 91 98 0x01 + * 92 110 0x00 + * 93 104 0x00 + * 94 98 0x00 + * 95 93 0x00 + * 96 88 0x00 + * 97 83 0x00 + * 98 78 0x00 + */ + + +/** + * Sanity checks and default values for EEPROM regulatory levels. + * If EEPROM values fall outside MIN/MAX range, use default values. + * + * Regulatory limits refer to the maximum average txpower allowed by + * regulatory agencies in the geographies in which the device is meant + * to be operated. These limits are SKU-specific (i.e. geography-specific), + * and channel-specific; each channel has an individual regulatory limit + * listed in the EEPROM. + * + * Units are in half-dBm (i.e. "34" means 17 dBm). + */ +#define IWL_TX_POWER_DEFAULT_REGULATORY_24 (34) +#define IWL_TX_POWER_DEFAULT_REGULATORY_52 (34) +#define IWL_TX_POWER_REGULATORY_MIN (0) +#define IWL_TX_POWER_REGULATORY_MAX (34) + +/** + * Sanity checks and default values for EEPROM saturation levels. + * If EEPROM values fall outside MIN/MAX range, use default values. + * + * Saturation is the highest level that the output power amplifier can produce + * without significant clipping distortion. This is a "peak" power level. + * Different types of modulation (i.e. various "rates", and OFDM vs. CCK) + * require differing amounts of backoff, relative to their average power output, + * in order to avoid clipping distortion. + * + * Driver must make sure that it is violating neither the saturation limit, + * nor the regulatory limit, when calculating Tx power settings for various + * rates. + * + * Units are in half-dBm (i.e. "38" means 19 dBm). + */ +#define IWL_TX_POWER_DEFAULT_SATURATION_24 (38) +#define IWL_TX_POWER_DEFAULT_SATURATION_52 (38) +#define IWL_TX_POWER_SATURATION_MIN (20) +#define IWL_TX_POWER_SATURATION_MAX (50) + +/** + * Channel groups used for Tx Attenuation calibration (MIMO tx channel balance) + * and thermal Txpower calibration. + * + * When calculating txpower, driver must compensate for current device + * temperature; higher temperature requires higher gain. Driver must calculate + * current temperature (see "4965 temperature calculation"), then compare vs. + * factory calibration temperature in EEPROM; if current temperature is higher + * than factory temperature, driver must *increase* gain by proportions shown + * in table below. If current temperature is lower than factory, driver must + * *decrease* gain. + * + * Different frequency ranges require different compensation, as shown below. + */ +/* Group 0, 5.2 GHz ch 34-43: 4.5 degrees per 1/2 dB. */ +#define CALIB_IWL_TX_ATTEN_GR1_FCH 34 +#define CALIB_IWL_TX_ATTEN_GR1_LCH 43 + +/* Group 1, 5.3 GHz ch 44-70: 4.0 degrees per 1/2 dB. */ +#define CALIB_IWL_TX_ATTEN_GR2_FCH 44 +#define CALIB_IWL_TX_ATTEN_GR2_LCH 70 + +/* Group 2, 5.5 GHz ch 71-124: 4.0 degrees per 1/2 dB. */ +#define CALIB_IWL_TX_ATTEN_GR3_FCH 71 +#define CALIB_IWL_TX_ATTEN_GR3_LCH 124 + +/* Group 3, 5.7 GHz ch 125-200: 4.0 degrees per 1/2 dB. */ +#define CALIB_IWL_TX_ATTEN_GR4_FCH 125 +#define CALIB_IWL_TX_ATTEN_GR4_LCH 200 + +/* Group 4, 2.4 GHz all channels: 3.5 degrees per 1/2 dB. */ +#define CALIB_IWL_TX_ATTEN_GR5_FCH 1 +#define CALIB_IWL_TX_ATTEN_GR5_LCH 20 + +enum { + CALIB_CH_GROUP_1 = 0, + CALIB_CH_GROUP_2 = 1, + CALIB_CH_GROUP_3 = 2, + CALIB_CH_GROUP_4 = 3, + CALIB_CH_GROUP_5 = 4, + CALIB_CH_GROUP_MAX +}; + +/********************* END TXPOWER *****************************************/ + + +/** + * Tx/Rx Queues + * + * Most communication between driver and 4965 is via queues of data buffers. + * For example, all commands that the driver issues to device's embedded + * controller (uCode) are via the command queue (one of the Tx queues). All + * uCode command responses/replies/notifications, including Rx frames, are + * conveyed from uCode to driver via the Rx queue. + * + * Most support for these queues, including handshake support, resides in + * structures in host DRAM, shared between the driver and the device. When + * allocating this memory, the driver must make sure that data written by + * the host CPU updates DRAM immediately (and does not get "stuck" in CPU's + * cache memory), so DRAM and cache are consistent, and the device can + * immediately see changes made by the driver. + * + * 4965 supports up to 16 DRAM-based Tx queues, and services these queues via + * up to 7 DMA channels (FIFOs). Each Tx queue is supported by a circular array + * in DRAM containing 256 Transmit Frame Descriptors (TFDs). + */ +#define IWL49_NUM_FIFOS 7 +#define IWL49_CMD_FIFO_NUM 4 +#define IWL49_NUM_QUEUES 16 +#define IWL49_NUM_AMPDU_QUEUES 8 + + +/** + * struct iwl4965_schedq_bc_tbl + * + * Byte Count table + * + * Each Tx queue uses a byte-count table containing 320 entries: + * one 16-bit entry for each of 256 TFDs, plus an additional 64 entries that + * duplicate the first 64 entries (to avoid wrap-around within a Tx window; + * max Tx window is 64 TFDs). + * + * When driver sets up a new TFD, it must also enter the total byte count + * of the frame to be transmitted into the corresponding entry in the byte + * count table for the chosen Tx queue. If the TFD index is 0-63, the driver + * must duplicate the byte count entry in corresponding index 256-319. + * + * padding puts each byte count table on a 1024-byte boundary; + * 4965 assumes tables are separated by 1024 bytes. + */ +struct iwl4965_scd_bc_tbl { + __le16 tfd_offset[TFD_QUEUE_BC_SIZE]; + u8 pad[1024 - (TFD_QUEUE_BC_SIZE) * sizeof(__le16)]; +} __packed; + +#endif /* !__iwl_4965_hw_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c new file mode 100644 index 000000000000..8998ed134d1a --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -0,0 +1,2666 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iwl-eeprom.h" +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-io.h" +#include "iwl-helpers.h" +#include "iwl-agn-calib.h" +#include "iwl-sta.h" +#include "iwl-agn-led.h" +#include "iwl-agn.h" +#include "iwl-agn-debugfs.h" +#include "iwl-legacy.h" + +static int iwl4965_send_tx_power(struct iwl_priv *priv); +static int iwl4965_hw_get_temperature(struct iwl_priv *priv); + +/* Highest firmware API version supported */ +#define IWL4965_UCODE_API_MAX 2 + +/* Lowest firmware API version supported */ +#define IWL4965_UCODE_API_MIN 2 + +#define IWL4965_FW_PRE "iwlwifi-4965-" +#define _IWL4965_MODULE_FIRMWARE(api) IWL4965_FW_PRE #api ".ucode" +#define IWL4965_MODULE_FIRMWARE(api) _IWL4965_MODULE_FIRMWARE(api) + +/* check contents of special bootstrap uCode SRAM */ +static int iwl4965_verify_bsm(struct iwl_priv *priv) +{ + __le32 *image = priv->ucode_boot.v_addr; + u32 len = priv->ucode_boot.len; + u32 reg; + u32 val; + + IWL_DEBUG_INFO(priv, "Begin verify bsm\n"); + + /* verify BSM SRAM contents */ + val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG); + for (reg = BSM_SRAM_LOWER_BOUND; + reg < BSM_SRAM_LOWER_BOUND + len; + reg += sizeof(u32), image++) { + val = iwl_read_prph(priv, reg); + if (val != le32_to_cpu(*image)) { + IWL_ERR(priv, "BSM uCode verification failed at " + "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", + BSM_SRAM_LOWER_BOUND, + reg - BSM_SRAM_LOWER_BOUND, len, + val, le32_to_cpu(*image)); + return -EIO; + } + } + + IWL_DEBUG_INFO(priv, "BSM bootstrap uCode image OK\n"); + + return 0; +} + +/** + * iwl4965_load_bsm - Load bootstrap instructions + * + * BSM operation: + * + * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program + * in special SRAM that does not power down during RFKILL. When powering back + * up after power-saving sleeps (or during initial uCode load), the BSM loads + * the bootstrap program into the on-board processor, and starts it. + * + * The bootstrap program loads (via DMA) instructions and data for a new + * program from host DRAM locations indicated by the host driver in the + * BSM_DRAM_* registers. Once the new program is loaded, it starts + * automatically. + * + * When initializing the NIC, the host driver points the BSM to the + * "initialize" uCode image. This uCode sets up some internal data, then + * notifies host via "initialize alive" that it is complete. + * + * The host then replaces the BSM_DRAM_* pointer values to point to the + * normal runtime uCode instructions and a backup uCode data cache buffer + * (filled initially with starting data values for the on-board processor), + * then triggers the "initialize" uCode to load and launch the runtime uCode, + * which begins normal operation. + * + * When doing a power-save shutdown, runtime uCode saves data SRAM into + * the backup data cache in DRAM before SRAM is powered down. + * + * When powering back up, the BSM loads the bootstrap program. This reloads + * the runtime uCode instructions and the backup data cache into SRAM, + * and re-launches the runtime uCode from where it left off. + */ +static int iwl4965_load_bsm(struct iwl_priv *priv) +{ + __le32 *image = priv->ucode_boot.v_addr; + u32 len = priv->ucode_boot.len; + dma_addr_t pinst; + dma_addr_t pdata; + u32 inst_len; + u32 data_len; + int i; + u32 done; + u32 reg_offset; + int ret; + + IWL_DEBUG_INFO(priv, "Begin load bsm\n"); + + priv->ucode_type = UCODE_RT; + + /* make sure bootstrap program is no larger than BSM's SRAM size */ + if (len > IWL49_MAX_BSM_SIZE) + return -EINVAL; + + /* Tell bootstrap uCode where to find the "Initialize" uCode + * in host DRAM ... host DRAM physical address bits 35:4 for 4965. + * NOTE: iwl_init_alive_start() will replace these values, + * after the "initialize" uCode has run, to point to + * runtime/protocol instructions and backup data cache. + */ + pinst = priv->ucode_init.p_addr >> 4; + pdata = priv->ucode_init_data.p_addr >> 4; + inst_len = priv->ucode_init.len; + data_len = priv->ucode_init_data.len; + + iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); + iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); + iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); + iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); + + /* Fill BSM memory with bootstrap instructions */ + for (reg_offset = BSM_SRAM_LOWER_BOUND; + reg_offset < BSM_SRAM_LOWER_BOUND + len; + reg_offset += sizeof(u32), image++) + _iwl_write_prph(priv, reg_offset, le32_to_cpu(*image)); + + ret = iwl4965_verify_bsm(priv); + if (ret) + return ret; + + /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ + iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); + iwl_write_prph(priv, BSM_WR_MEM_DST_REG, IWL49_RTC_INST_LOWER_BOUND); + iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); + + /* Load bootstrap code into instruction SRAM now, + * to prepare to load "initialize" uCode */ + iwl_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START); + + /* Wait for load of bootstrap uCode to finish */ + for (i = 0; i < 100; i++) { + done = iwl_read_prph(priv, BSM_WR_CTRL_REG); + if (!(done & BSM_WR_CTRL_REG_BIT_START)) + break; + udelay(10); + } + if (i < 100) + IWL_DEBUG_INFO(priv, "BSM write complete, poll %d iterations\n", i); + else { + IWL_ERR(priv, "BSM write did not complete!\n"); + return -EIO; + } + + /* Enable future boot loads whenever power management unit triggers it + * (e.g. when powering back up after power-save shutdown) */ + iwl_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START_EN); + + + return 0; +} + +/** + * iwl4965_set_ucode_ptrs - Set uCode address location + * + * Tell initialization uCode where to find runtime uCode. + * + * BSM registers initially contain pointers to initialization uCode. + * We need to replace them to load runtime uCode inst and data, + * and to save runtime data when powering down. + */ +static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv) +{ + dma_addr_t pinst; + dma_addr_t pdata; + int ret = 0; + + /* bits 35:4 for 4965 */ + pinst = priv->ucode_code.p_addr >> 4; + pdata = priv->ucode_data_backup.p_addr >> 4; + + /* Tell bootstrap uCode where to find image to load */ + iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); + iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); + iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, + priv->ucode_data.len); + + /* Inst byte count must be last to set up, bit 31 signals uCode + * that all new ptr/size info is in place */ + iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, + priv->ucode_code.len | BSM_DRAM_INST_LOAD); + IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n"); + + return ret; +} + +/** + * iwl4965_init_alive_start - Called after REPLY_ALIVE notification received + * + * Called after REPLY_ALIVE notification received from "initialize" uCode. + * + * The 4965 "initialize" ALIVE reply contains calibration data for: + * Voltage, temperature, and MIMO tx gain correction, now stored in priv + * (3945 does not contain this data). + * + * Tell "initialize" uCode to go ahead and load the runtime uCode. +*/ +static void iwl4965_init_alive_start(struct iwl_priv *priv) +{ + /* Bootstrap uCode has loaded initialize uCode ... verify inst image. + * This is a paranoid check, because we would not have gotten the + * "initialize" alive if code weren't properly loaded. */ + if (iwl_verify_ucode(priv)) { + /* Runtime instruction load was bad; + * take it all the way back down so we can try again */ + IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n"); + goto restart; + } + + /* Calculate temperature */ + priv->temperature = iwl4965_hw_get_temperature(priv); + + /* Send pointers to protocol/runtime uCode image ... init code will + * load and launch runtime uCode, which will send us another "Alive" + * notification. */ + IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); + if (iwl4965_set_ucode_ptrs(priv)) { + /* Runtime instruction load won't happen; + * take it all the way back down so we can try again */ + IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n"); + goto restart; + } + return; + +restart: + queue_work(priv->workqueue, &priv->restart); +} + +static bool is_ht40_channel(__le32 rxon_flags) +{ + int chan_mod = le32_to_cpu(rxon_flags & RXON_FLG_CHANNEL_MODE_MSK) + >> RXON_FLG_CHANNEL_MODE_POS; + return ((chan_mod == CHANNEL_MODE_PURE_40) || + (chan_mod == CHANNEL_MODE_MIXED)); +} + +/* + * EEPROM handlers + */ +static u16 iwl4965_eeprom_calib_version(struct iwl_priv *priv) +{ + return iwl_eeprom_query16(priv, EEPROM_4965_CALIB_VERSION_OFFSET); +} + +/* + * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask + * must be called under priv->lock and mac access + */ +static void iwl4965_txq_set_sched(struct iwl_priv *priv, u32 mask) +{ + iwl_write_prph(priv, IWL49_SCD_TXFACT, mask); +} + +static void iwl4965_nic_config(struct iwl_priv *priv) +{ + unsigned long flags; + u16 radio_cfg; + + spin_lock_irqsave(&priv->lock, flags); + + radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); + + /* write radio config values to register */ + if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) == EEPROM_4965_RF_CFG_TYPE_MAX) + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | + EEPROM_RF_CFG_STEP_MSK(radio_cfg) | + EEPROM_RF_CFG_DASH_MSK(radio_cfg)); + + /* set CSR_HW_CONFIG_REG for uCode use */ + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | + CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); + + priv->calib_info = (struct iwl_eeprom_calib_info *) + iwl_eeprom_query_addr(priv, EEPROM_4965_CALIB_TXPOWER_OFFSET); + + spin_unlock_irqrestore(&priv->lock, flags); +} + +/* Reset differential Rx gains in NIC to prepare for chain noise calibration. + * Called after every association, but this runs only once! + * ... once chain noise is calibrated the first time, it's good forever. */ +static void iwl4965_chain_noise_reset(struct iwl_priv *priv) +{ + struct iwl_chain_noise_data *data = &(priv->chain_noise_data); + + if ((data->state == IWL_CHAIN_NOISE_ALIVE) && + iwl_is_any_associated(priv)) { + struct iwl_calib_diff_gain_cmd cmd; + + /* clear data for chain noise calibration algorithm */ + data->chain_noise_a = 0; + data->chain_noise_b = 0; + data->chain_noise_c = 0; + data->chain_signal_a = 0; + data->chain_signal_b = 0; + data->chain_signal_c = 0; + data->beacon_count = 0; + + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD; + cmd.diff_gain_a = 0; + cmd.diff_gain_b = 0; + cmd.diff_gain_c = 0; + if (iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, + sizeof(cmd), &cmd)) + IWL_ERR(priv, + "Could not send REPLY_PHY_CALIBRATION_CMD\n"); + data->state = IWL_CHAIN_NOISE_ACCUMULATE; + IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n"); + } +} + +static void iwl4965_gain_computation(struct iwl_priv *priv, + u32 *average_noise, + u16 min_average_noise_antenna_i, + u32 min_average_noise, + u8 default_chain) +{ + int i, ret; + struct iwl_chain_noise_data *data = &priv->chain_noise_data; + + data->delta_gain_code[min_average_noise_antenna_i] = 0; + + for (i = default_chain; i < NUM_RX_CHAINS; i++) { + s32 delta_g = 0; + + if (!(data->disconn_array[i]) && + (data->delta_gain_code[i] == + CHAIN_NOISE_DELTA_GAIN_INIT_VAL)) { + delta_g = average_noise[i] - min_average_noise; + data->delta_gain_code[i] = (u8)((delta_g * 10) / 15); + data->delta_gain_code[i] = + min(data->delta_gain_code[i], + (u8) CHAIN_NOISE_MAX_DELTA_GAIN_CODE); + + data->delta_gain_code[i] = + (data->delta_gain_code[i] | (1 << 2)); + } else { + data->delta_gain_code[i] = 0; + } + } + IWL_DEBUG_CALIB(priv, "delta_gain_codes: a %d b %d c %d\n", + data->delta_gain_code[0], + data->delta_gain_code[1], + data->delta_gain_code[2]); + + /* Differential gain gets sent to uCode only once */ + if (!data->radio_write) { + struct iwl_calib_diff_gain_cmd cmd; + data->radio_write = 1; + + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD; + cmd.diff_gain_a = data->delta_gain_code[0]; + cmd.diff_gain_b = data->delta_gain_code[1]; + cmd.diff_gain_c = data->delta_gain_code[2]; + ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, + sizeof(cmd), &cmd); + if (ret) + IWL_DEBUG_CALIB(priv, "fail sending cmd " + "REPLY_PHY_CALIBRATION_CMD\n"); + + /* TODO we might want recalculate + * rx_chain in rxon cmd */ + + /* Mark so we run this algo only once! */ + data->state = IWL_CHAIN_NOISE_CALIBRATED; + } +} + +static void iwl4965_bg_txpower_work(struct work_struct *work) +{ + struct iwl_priv *priv = container_of(work, struct iwl_priv, + txpower_work); + + /* If a scan happened to start before we got here + * then just return; the statistics notification will + * kick off another scheduled work to compensate for + * any temperature delta we missed here. */ + if (test_bit(STATUS_EXIT_PENDING, &priv->status) || + test_bit(STATUS_SCANNING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + + /* Regardless of if we are associated, we must reconfigure the + * TX power since frames can be sent on non-radar channels while + * not associated */ + iwl4965_send_tx_power(priv); + + /* Update last_temperature to keep is_calib_needed from running + * when it isn't needed... */ + priv->last_temperature = priv->temperature; + + mutex_unlock(&priv->mutex); +} + +/* + * Acquire priv->lock before calling this function ! + */ +static void iwl4965_set_wr_ptrs(struct iwl_priv *priv, int txq_id, u32 index) +{ + iwl_write_direct32(priv, HBUS_TARG_WRPTR, + (index & 0xff) | (txq_id << 8)); + iwl_write_prph(priv, IWL49_SCD_QUEUE_RDPTR(txq_id), index); +} + +/** + * iwl4965_tx_queue_set_status - (optionally) start Tx/Cmd queue + * @tx_fifo_id: Tx DMA/FIFO channel (range 0-7) that the queue will feed + * @scd_retry: (1) Indicates queue will be used in aggregation mode + * + * NOTE: Acquire priv->lock before calling this function ! + */ +static void iwl4965_tx_queue_set_status(struct iwl_priv *priv, + struct iwl_tx_queue *txq, + int tx_fifo_id, int scd_retry) +{ + int txq_id = txq->q.id; + + /* Find out whether to activate Tx queue */ + int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0; + + /* Set up and activate */ + iwl_write_prph(priv, IWL49_SCD_QUEUE_STATUS_BITS(txq_id), + (active << IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE) | + (tx_fifo_id << IWL49_SCD_QUEUE_STTS_REG_POS_TXF) | + (scd_retry << IWL49_SCD_QUEUE_STTS_REG_POS_WSL) | + (scd_retry << IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACK) | + IWL49_SCD_QUEUE_STTS_REG_MSK); + + txq->sched_retry = scd_retry; + + IWL_DEBUG_INFO(priv, "%s %s Queue %d on AC %d\n", + active ? "Activate" : "Deactivate", + scd_retry ? "BA" : "AC", txq_id, tx_fifo_id); +} + +static const s8 default_queue_to_tx_fifo[] = { + IWL_TX_FIFO_VO, + IWL_TX_FIFO_VI, + IWL_TX_FIFO_BE, + IWL_TX_FIFO_BK, + IWL49_CMD_FIFO_NUM, + IWL_TX_FIFO_UNUSED, + IWL_TX_FIFO_UNUSED, +}; + +static int iwl4965_alive_notify(struct iwl_priv *priv) +{ + u32 a; + unsigned long flags; + int i, chan; + u32 reg_val; + + spin_lock_irqsave(&priv->lock, flags); + + /* Clear 4965's internal Tx Scheduler data base */ + priv->scd_base_addr = iwl_read_prph(priv, IWL49_SCD_SRAM_BASE_ADDR); + a = priv->scd_base_addr + IWL49_SCD_CONTEXT_DATA_OFFSET; + for (; a < priv->scd_base_addr + IWL49_SCD_TX_STTS_BITMAP_OFFSET; a += 4) + iwl_write_targ_mem(priv, a, 0); + for (; a < priv->scd_base_addr + IWL49_SCD_TRANSLATE_TBL_OFFSET; a += 4) + iwl_write_targ_mem(priv, a, 0); + for (; a < priv->scd_base_addr + + IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4) + iwl_write_targ_mem(priv, a, 0); + + /* Tel 4965 where to find Tx byte count tables */ + iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR, + priv->scd_bc_tbls.dma >> 10); + + /* Enable DMA channel */ + for (chan = 0; chan < FH49_TCSR_CHNL_NUM ; chan++) + iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(chan), + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); + + /* Update FH chicken bits */ + reg_val = iwl_read_direct32(priv, FH_TX_CHICKEN_BITS_REG); + iwl_write_direct32(priv, FH_TX_CHICKEN_BITS_REG, + reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); + + /* Disable chain mode for all queues */ + iwl_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0); + + /* Initialize each Tx queue (including the command queue) */ + for (i = 0; i < priv->hw_params.max_txq_num; i++) { + + /* TFD circular buffer read/write indexes */ + iwl_write_prph(priv, IWL49_SCD_QUEUE_RDPTR(i), 0); + iwl_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8)); + + /* Max Tx Window size for Scheduler-ACK mode */ + iwl_write_targ_mem(priv, priv->scd_base_addr + + IWL49_SCD_CONTEXT_QUEUE_OFFSET(i), + (SCD_WIN_SIZE << + IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) & + IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK); + + /* Frame limit */ + iwl_write_targ_mem(priv, priv->scd_base_addr + + IWL49_SCD_CONTEXT_QUEUE_OFFSET(i) + + sizeof(u32), + (SCD_FRAME_LIMIT << + IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & + IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK); + + } + iwl_write_prph(priv, IWL49_SCD_INTERRUPT_MASK, + (1 << priv->hw_params.max_txq_num) - 1); + + /* Activate all Tx DMA/FIFO channels */ + priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 6)); + + iwl4965_set_wr_ptrs(priv, IWL_DEFAULT_CMD_QUEUE_NUM, 0); + + /* make sure all queue are not stopped */ + memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); + for (i = 0; i < 4; i++) + atomic_set(&priv->queue_stop_count[i], 0); + + /* reset to 0 to enable all the queue first */ + priv->txq_ctx_active_msk = 0; + /* Map each Tx/cmd queue to its corresponding fifo */ + BUILD_BUG_ON(ARRAY_SIZE(default_queue_to_tx_fifo) != 7); + + for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) { + int ac = default_queue_to_tx_fifo[i]; + + iwl_txq_ctx_activate(priv, i); + + if (ac == IWL_TX_FIFO_UNUSED) + continue; + + iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0); + } + + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + +static struct iwl_sensitivity_ranges iwl4965_sensitivity = { + .min_nrg_cck = 97, + .max_nrg_cck = 0, /* not used, set to 0 */ + + .auto_corr_min_ofdm = 85, + .auto_corr_min_ofdm_mrc = 170, + .auto_corr_min_ofdm_x1 = 105, + .auto_corr_min_ofdm_mrc_x1 = 220, + + .auto_corr_max_ofdm = 120, + .auto_corr_max_ofdm_mrc = 210, + .auto_corr_max_ofdm_x1 = 140, + .auto_corr_max_ofdm_mrc_x1 = 270, + + .auto_corr_min_cck = 125, + .auto_corr_max_cck = 200, + .auto_corr_min_cck_mrc = 200, + .auto_corr_max_cck_mrc = 400, + + .nrg_th_cck = 100, + .nrg_th_ofdm = 100, + + .barker_corr_th_min = 190, + .barker_corr_th_min_mrc = 390, + .nrg_th_cca = 62, +}; + +static void iwl4965_set_ct_threshold(struct iwl_priv *priv) +{ + /* want Kelvin */ + priv->hw_params.ct_kill_threshold = + CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY); +} + +/** + * iwl4965_hw_set_hw_params + * + * Called when initializing driver + */ +static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) +{ + if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && + priv->cfg->mod_params->num_of_queues <= IWL49_NUM_QUEUES) + priv->cfg->base_params->num_of_queues = + priv->cfg->mod_params->num_of_queues; + + priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; + priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM; + priv->hw_params.scd_bc_tbls_size = + priv->cfg->base_params->num_of_queues * + sizeof(struct iwl4965_scd_bc_tbl); + priv->hw_params.tfd_size = sizeof(struct iwl_tfd); + priv->hw_params.max_stations = IWL4965_STATION_COUNT; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL4965_BROADCAST_ID; + priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE; + priv->hw_params.max_inst_size = IWL49_RTC_INST_SIZE; + priv->hw_params.max_bsm_size = BSM_SRAM_SIZE; + priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_5GHZ); + + priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; + + priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); + priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); + priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; + priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; + + iwl4965_set_ct_threshold(priv); + + priv->hw_params.sens = &iwl4965_sensitivity; + priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; + + return 0; +} + +static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res) +{ + s32 sign = 1; + + if (num < 0) { + sign = -sign; + num = -num; + } + if (denom < 0) { + sign = -sign; + denom = -denom; + } + *res = 1; + *res = ((num * 2 + denom) / (denom * 2)) * sign; + + return 1; +} + +/** + * iwl4965_get_voltage_compensation - Power supply voltage comp for txpower + * + * Determines power supply voltage compensation for txpower calculations. + * Returns number of 1/2-dB steps to subtract from gain table index, + * to compensate for difference between power supply voltage during + * factory measurements, vs. current power supply voltage. + * + * Voltage indication is higher for lower voltage. + * Lower voltage requires more gain (lower gain table index). + */ +static s32 iwl4965_get_voltage_compensation(s32 eeprom_voltage, + s32 current_voltage) +{ + s32 comp = 0; + + if ((TX_POWER_IWL_ILLEGAL_VOLTAGE == eeprom_voltage) || + (TX_POWER_IWL_ILLEGAL_VOLTAGE == current_voltage)) + return 0; + + iwl4965_math_div_round(current_voltage - eeprom_voltage, + TX_POWER_IWL_VOLTAGE_CODES_PER_03V, &comp); + + if (current_voltage > eeprom_voltage) + comp *= 2; + if ((comp < -2) || (comp > 2)) + comp = 0; + + return comp; +} + +static s32 iwl4965_get_tx_atten_grp(u16 channel) +{ + if (channel >= CALIB_IWL_TX_ATTEN_GR5_FCH && + channel <= CALIB_IWL_TX_ATTEN_GR5_LCH) + return CALIB_CH_GROUP_5; + + if (channel >= CALIB_IWL_TX_ATTEN_GR1_FCH && + channel <= CALIB_IWL_TX_ATTEN_GR1_LCH) + return CALIB_CH_GROUP_1; + + if (channel >= CALIB_IWL_TX_ATTEN_GR2_FCH && + channel <= CALIB_IWL_TX_ATTEN_GR2_LCH) + return CALIB_CH_GROUP_2; + + if (channel >= CALIB_IWL_TX_ATTEN_GR3_FCH && + channel <= CALIB_IWL_TX_ATTEN_GR3_LCH) + return CALIB_CH_GROUP_3; + + if (channel >= CALIB_IWL_TX_ATTEN_GR4_FCH && + channel <= CALIB_IWL_TX_ATTEN_GR4_LCH) + return CALIB_CH_GROUP_4; + + return -1; +} + +static u32 iwl4965_get_sub_band(const struct iwl_priv *priv, u32 channel) +{ + s32 b = -1; + + for (b = 0; b < EEPROM_TX_POWER_BANDS; b++) { + if (priv->calib_info->band_info[b].ch_from == 0) + continue; + + if ((channel >= priv->calib_info->band_info[b].ch_from) + && (channel <= priv->calib_info->band_info[b].ch_to)) + break; + } + + return b; +} + +static s32 iwl4965_interpolate_value(s32 x, s32 x1, s32 y1, s32 x2, s32 y2) +{ + s32 val; + + if (x2 == x1) + return y1; + else { + iwl4965_math_div_round((x2 - x) * (y1 - y2), (x2 - x1), &val); + return val + y2; + } +} + +/** + * iwl4965_interpolate_chan - Interpolate factory measurements for one channel + * + * Interpolates factory measurements from the two sample channels within a + * sub-band, to apply to channel of interest. Interpolation is proportional to + * differences in channel frequencies, which is proportional to differences + * in channel number. + */ +static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel, + struct iwl_eeprom_calib_ch_info *chan_info) +{ + s32 s = -1; + u32 c; + u32 m; + const struct iwl_eeprom_calib_measure *m1; + const struct iwl_eeprom_calib_measure *m2; + struct iwl_eeprom_calib_measure *omeas; + u32 ch_i1; + u32 ch_i2; + + s = iwl4965_get_sub_band(priv, channel); + if (s >= EEPROM_TX_POWER_BANDS) { + IWL_ERR(priv, "Tx Power can not find channel %d\n", channel); + return -1; + } + + ch_i1 = priv->calib_info->band_info[s].ch1.ch_num; + ch_i2 = priv->calib_info->band_info[s].ch2.ch_num; + chan_info->ch_num = (u8) channel; + + IWL_DEBUG_TXPOWER(priv, "channel %d subband %d factory cal ch %d & %d\n", + channel, s, ch_i1, ch_i2); + + for (c = 0; c < EEPROM_TX_POWER_TX_CHAINS; c++) { + for (m = 0; m < EEPROM_TX_POWER_MEASUREMENTS; m++) { + m1 = &(priv->calib_info->band_info[s].ch1. + measurements[c][m]); + m2 = &(priv->calib_info->band_info[s].ch2. + measurements[c][m]); + omeas = &(chan_info->measurements[c][m]); + + omeas->actual_pow = + (u8) iwl4965_interpolate_value(channel, ch_i1, + m1->actual_pow, + ch_i2, + m2->actual_pow); + omeas->gain_idx = + (u8) iwl4965_interpolate_value(channel, ch_i1, + m1->gain_idx, ch_i2, + m2->gain_idx); + omeas->temperature = + (u8) iwl4965_interpolate_value(channel, ch_i1, + m1->temperature, + ch_i2, + m2->temperature); + omeas->pa_det = + (s8) iwl4965_interpolate_value(channel, ch_i1, + m1->pa_det, ch_i2, + m2->pa_det); + + IWL_DEBUG_TXPOWER(priv, + "chain %d meas %d AP1=%d AP2=%d AP=%d\n", c, m, + m1->actual_pow, m2->actual_pow, omeas->actual_pow); + IWL_DEBUG_TXPOWER(priv, + "chain %d meas %d NI1=%d NI2=%d NI=%d\n", c, m, + m1->gain_idx, m2->gain_idx, omeas->gain_idx); + IWL_DEBUG_TXPOWER(priv, + "chain %d meas %d PA1=%d PA2=%d PA=%d\n", c, m, + m1->pa_det, m2->pa_det, omeas->pa_det); + IWL_DEBUG_TXPOWER(priv, + "chain %d meas %d T1=%d T2=%d T=%d\n", c, m, + m1->temperature, m2->temperature, + omeas->temperature); + } + } + + return 0; +} + +/* bit-rate-dependent table to prevent Tx distortion, in half-dB units, + * for OFDM 6, 12, 18, 24, 36, 48, 54, 60 MBit, and CCK all rates. */ +static s32 back_off_table[] = { + 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM SISO 20 MHz */ + 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM MIMO 20 MHz */ + 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM SISO 40 MHz */ + 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM MIMO 40 MHz */ + 10 /* CCK */ +}; + +/* Thermal compensation values for txpower for various frequency ranges ... + * ratios from 3:1 to 4.5:1 of degrees (Celsius) per half-dB gain adjust */ +static struct iwl4965_txpower_comp_entry { + s32 degrees_per_05db_a; + s32 degrees_per_05db_a_denom; +} tx_power_cmp_tble[CALIB_CH_GROUP_MAX] = { + {9, 2}, /* group 0 5.2, ch 34-43 */ + {4, 1}, /* group 1 5.2, ch 44-70 */ + {4, 1}, /* group 2 5.2, ch 71-124 */ + {4, 1}, /* group 3 5.2, ch 125-200 */ + {3, 1} /* group 4 2.4, ch all */ +}; + +static s32 get_min_power_index(s32 rate_power_index, u32 band) +{ + if (!band) { + if ((rate_power_index & 7) <= 4) + return MIN_TX_GAIN_INDEX_52GHZ_EXT; + } + return MIN_TX_GAIN_INDEX; +} + +struct gain_entry { + u8 dsp; + u8 radio; +}; + +static const struct gain_entry gain_table[2][108] = { + /* 5.2GHz power gain index table */ + { + {123, 0x3F}, /* highest txpower */ + {117, 0x3F}, + {110, 0x3F}, + {104, 0x3F}, + {98, 0x3F}, + {110, 0x3E}, + {104, 0x3E}, + {98, 0x3E}, + {110, 0x3D}, + {104, 0x3D}, + {98, 0x3D}, + {110, 0x3C}, + {104, 0x3C}, + {98, 0x3C}, + {110, 0x3B}, + {104, 0x3B}, + {98, 0x3B}, + {110, 0x3A}, + {104, 0x3A}, + {98, 0x3A}, + {110, 0x39}, + {104, 0x39}, + {98, 0x39}, + {110, 0x38}, + {104, 0x38}, + {98, 0x38}, + {110, 0x37}, + {104, 0x37}, + {98, 0x37}, + {110, 0x36}, + {104, 0x36}, + {98, 0x36}, + {110, 0x35}, + {104, 0x35}, + {98, 0x35}, + {110, 0x34}, + {104, 0x34}, + {98, 0x34}, + {110, 0x33}, + {104, 0x33}, + {98, 0x33}, + {110, 0x32}, + {104, 0x32}, + {98, 0x32}, + {110, 0x31}, + {104, 0x31}, + {98, 0x31}, + {110, 0x30}, + {104, 0x30}, + {98, 0x30}, + {110, 0x25}, + {104, 0x25}, + {98, 0x25}, + {110, 0x24}, + {104, 0x24}, + {98, 0x24}, + {110, 0x23}, + {104, 0x23}, + {98, 0x23}, + {110, 0x22}, + {104, 0x18}, + {98, 0x18}, + {110, 0x17}, + {104, 0x17}, + {98, 0x17}, + {110, 0x16}, + {104, 0x16}, + {98, 0x16}, + {110, 0x15}, + {104, 0x15}, + {98, 0x15}, + {110, 0x14}, + {104, 0x14}, + {98, 0x14}, + {110, 0x13}, + {104, 0x13}, + {98, 0x13}, + {110, 0x12}, + {104, 0x08}, + {98, 0x08}, + {110, 0x07}, + {104, 0x07}, + {98, 0x07}, + {110, 0x06}, + {104, 0x06}, + {98, 0x06}, + {110, 0x05}, + {104, 0x05}, + {98, 0x05}, + {110, 0x04}, + {104, 0x04}, + {98, 0x04}, + {110, 0x03}, + {104, 0x03}, + {98, 0x03}, + {110, 0x02}, + {104, 0x02}, + {98, 0x02}, + {110, 0x01}, + {104, 0x01}, + {98, 0x01}, + {110, 0x00}, + {104, 0x00}, + {98, 0x00}, + {93, 0x00}, + {88, 0x00}, + {83, 0x00}, + {78, 0x00}, + }, + /* 2.4GHz power gain index table */ + { + {110, 0x3f}, /* highest txpower */ + {104, 0x3f}, + {98, 0x3f}, + {110, 0x3e}, + {104, 0x3e}, + {98, 0x3e}, + {110, 0x3d}, + {104, 0x3d}, + {98, 0x3d}, + {110, 0x3c}, + {104, 0x3c}, + {98, 0x3c}, + {110, 0x3b}, + {104, 0x3b}, + {98, 0x3b}, + {110, 0x3a}, + {104, 0x3a}, + {98, 0x3a}, + {110, 0x39}, + {104, 0x39}, + {98, 0x39}, + {110, 0x38}, + {104, 0x38}, + {98, 0x38}, + {110, 0x37}, + {104, 0x37}, + {98, 0x37}, + {110, 0x36}, + {104, 0x36}, + {98, 0x36}, + {110, 0x35}, + {104, 0x35}, + {98, 0x35}, + {110, 0x34}, + {104, 0x34}, + {98, 0x34}, + {110, 0x33}, + {104, 0x33}, + {98, 0x33}, + {110, 0x32}, + {104, 0x32}, + {98, 0x32}, + {110, 0x31}, + {104, 0x31}, + {98, 0x31}, + {110, 0x30}, + {104, 0x30}, + {98, 0x30}, + {110, 0x6}, + {104, 0x6}, + {98, 0x6}, + {110, 0x5}, + {104, 0x5}, + {98, 0x5}, + {110, 0x4}, + {104, 0x4}, + {98, 0x4}, + {110, 0x3}, + {104, 0x3}, + {98, 0x3}, + {110, 0x2}, + {104, 0x2}, + {98, 0x2}, + {110, 0x1}, + {104, 0x1}, + {98, 0x1}, + {110, 0x0}, + {104, 0x0}, + {98, 0x0}, + {97, 0}, + {96, 0}, + {95, 0}, + {94, 0}, + {93, 0}, + {92, 0}, + {91, 0}, + {90, 0}, + {89, 0}, + {88, 0}, + {87, 0}, + {86, 0}, + {85, 0}, + {84, 0}, + {83, 0}, + {82, 0}, + {81, 0}, + {80, 0}, + {79, 0}, + {78, 0}, + {77, 0}, + {76, 0}, + {75, 0}, + {74, 0}, + {73, 0}, + {72, 0}, + {71, 0}, + {70, 0}, + {69, 0}, + {68, 0}, + {67, 0}, + {66, 0}, + {65, 0}, + {64, 0}, + {63, 0}, + {62, 0}, + {61, 0}, + {60, 0}, + {59, 0}, + } +}; + +static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, + u8 is_ht40, u8 ctrl_chan_high, + struct iwl4965_tx_power_db *tx_power_tbl) +{ + u8 saturation_power; + s32 target_power; + s32 user_target_power; + s32 power_limit; + s32 current_temp; + s32 reg_limit; + s32 current_regulatory; + s32 txatten_grp = CALIB_CH_GROUP_MAX; + int i; + int c; + const struct iwl_channel_info *ch_info = NULL; + struct iwl_eeprom_calib_ch_info ch_eeprom_info; + const struct iwl_eeprom_calib_measure *measurement; + s16 voltage; + s32 init_voltage; + s32 voltage_compensation; + s32 degrees_per_05db_num; + s32 degrees_per_05db_denom; + s32 factory_temp; + s32 temperature_comp[2]; + s32 factory_gain_index[2]; + s32 factory_actual_pwr[2]; + s32 power_index; + + /* tx_power_user_lmt is in dBm, convert to half-dBm (half-dB units + * are used for indexing into txpower table) */ + user_target_power = 2 * priv->tx_power_user_lmt; + + /* Get current (RXON) channel, band, width */ + IWL_DEBUG_TXPOWER(priv, "chan %d band %d is_ht40 %d\n", channel, band, + is_ht40); + + ch_info = iwl_get_channel_info(priv, priv->band, channel); + + if (!is_channel_valid(ch_info)) + return -EINVAL; + + /* get txatten group, used to select 1) thermal txpower adjustment + * and 2) mimo txpower balance between Tx chains. */ + txatten_grp = iwl4965_get_tx_atten_grp(channel); + if (txatten_grp < 0) { + IWL_ERR(priv, "Can't find txatten group for channel %d.\n", + channel); + return -EINVAL; + } + + IWL_DEBUG_TXPOWER(priv, "channel %d belongs to txatten group %d\n", + channel, txatten_grp); + + if (is_ht40) { + if (ctrl_chan_high) + channel -= 2; + else + channel += 2; + } + + /* hardware txpower limits ... + * saturation (clipping distortion) txpowers are in half-dBm */ + if (band) + saturation_power = priv->calib_info->saturation_power24; + else + saturation_power = priv->calib_info->saturation_power52; + + if (saturation_power < IWL_TX_POWER_SATURATION_MIN || + saturation_power > IWL_TX_POWER_SATURATION_MAX) { + if (band) + saturation_power = IWL_TX_POWER_DEFAULT_SATURATION_24; + else + saturation_power = IWL_TX_POWER_DEFAULT_SATURATION_52; + } + + /* regulatory txpower limits ... reg_limit values are in half-dBm, + * max_power_avg values are in dBm, convert * 2 */ + if (is_ht40) + reg_limit = ch_info->ht40_max_power_avg * 2; + else + reg_limit = ch_info->max_power_avg * 2; + + if ((reg_limit < IWL_TX_POWER_REGULATORY_MIN) || + (reg_limit > IWL_TX_POWER_REGULATORY_MAX)) { + if (band) + reg_limit = IWL_TX_POWER_DEFAULT_REGULATORY_24; + else + reg_limit = IWL_TX_POWER_DEFAULT_REGULATORY_52; + } + + /* Interpolate txpower calibration values for this channel, + * based on factory calibration tests on spaced channels. */ + iwl4965_interpolate_chan(priv, channel, &ch_eeprom_info); + + /* calculate tx gain adjustment based on power supply voltage */ + voltage = le16_to_cpu(priv->calib_info->voltage); + init_voltage = (s32)le32_to_cpu(priv->card_alive_init.voltage); + voltage_compensation = + iwl4965_get_voltage_compensation(voltage, init_voltage); + + IWL_DEBUG_TXPOWER(priv, "curr volt %d eeprom volt %d volt comp %d\n", + init_voltage, + voltage, voltage_compensation); + + /* get current temperature (Celsius) */ + current_temp = max(priv->temperature, IWL_TX_POWER_TEMPERATURE_MIN); + current_temp = min(priv->temperature, IWL_TX_POWER_TEMPERATURE_MAX); + current_temp = KELVIN_TO_CELSIUS(current_temp); + + /* select thermal txpower adjustment params, based on channel group + * (same frequency group used for mimo txatten adjustment) */ + degrees_per_05db_num = + tx_power_cmp_tble[txatten_grp].degrees_per_05db_a; + degrees_per_05db_denom = + tx_power_cmp_tble[txatten_grp].degrees_per_05db_a_denom; + + /* get per-chain txpower values from factory measurements */ + for (c = 0; c < 2; c++) { + measurement = &ch_eeprom_info.measurements[c][1]; + + /* txgain adjustment (in half-dB steps) based on difference + * between factory and current temperature */ + factory_temp = measurement->temperature; + iwl4965_math_div_round((current_temp - factory_temp) * + degrees_per_05db_denom, + degrees_per_05db_num, + &temperature_comp[c]); + + factory_gain_index[c] = measurement->gain_idx; + factory_actual_pwr[c] = measurement->actual_pow; + + IWL_DEBUG_TXPOWER(priv, "chain = %d\n", c); + IWL_DEBUG_TXPOWER(priv, "fctry tmp %d, " + "curr tmp %d, comp %d steps\n", + factory_temp, current_temp, + temperature_comp[c]); + + IWL_DEBUG_TXPOWER(priv, "fctry idx %d, fctry pwr %d\n", + factory_gain_index[c], + factory_actual_pwr[c]); + } + + /* for each of 33 bit-rates (including 1 for CCK) */ + for (i = 0; i < POWER_TABLE_NUM_ENTRIES; i++) { + u8 is_mimo_rate; + union iwl4965_tx_power_dual_stream tx_power; + + /* for mimo, reduce each chain's txpower by half + * (3dB, 6 steps), so total output power is regulatory + * compliant. */ + if (i & 0x8) { + current_regulatory = reg_limit - + IWL_TX_POWER_MIMO_REGULATORY_COMPENSATION; + is_mimo_rate = 1; + } else { + current_regulatory = reg_limit; + is_mimo_rate = 0; + } + + /* find txpower limit, either hardware or regulatory */ + power_limit = saturation_power - back_off_table[i]; + if (power_limit > current_regulatory) + power_limit = current_regulatory; + + /* reduce user's txpower request if necessary + * for this rate on this channel */ + target_power = user_target_power; + if (target_power > power_limit) + target_power = power_limit; + + IWL_DEBUG_TXPOWER(priv, "rate %d sat %d reg %d usr %d tgt %d\n", + i, saturation_power - back_off_table[i], + current_regulatory, user_target_power, + target_power); + + /* for each of 2 Tx chains (radio transmitters) */ + for (c = 0; c < 2; c++) { + s32 atten_value; + + if (is_mimo_rate) + atten_value = + (s32)le32_to_cpu(priv->card_alive_init. + tx_atten[txatten_grp][c]); + else + atten_value = 0; + + /* calculate index; higher index means lower txpower */ + power_index = (u8) (factory_gain_index[c] - + (target_power - + factory_actual_pwr[c]) - + temperature_comp[c] - + voltage_compensation + + atten_value); + +/* IWL_DEBUG_TXPOWER(priv, "calculated txpower index %d\n", + power_index); */ + + if (power_index < get_min_power_index(i, band)) + power_index = get_min_power_index(i, band); + + /* adjust 5 GHz index to support negative indexes */ + if (!band) + power_index += 9; + + /* CCK, rate 32, reduce txpower for CCK */ + if (i == POWER_TABLE_CCK_ENTRY) + power_index += + IWL_TX_POWER_CCK_COMPENSATION_C_STEP; + + /* stay within the table! */ + if (power_index > 107) { + IWL_WARN(priv, "txpower index %d > 107\n", + power_index); + power_index = 107; + } + if (power_index < 0) { + IWL_WARN(priv, "txpower index %d < 0\n", + power_index); + power_index = 0; + } + + /* fill txpower command for this rate/chain */ + tx_power.s.radio_tx_gain[c] = + gain_table[band][power_index].radio; + tx_power.s.dsp_predis_atten[c] = + gain_table[band][power_index].dsp; + + IWL_DEBUG_TXPOWER(priv, "chain %d mimo %d index %d " + "gain 0x%02x dsp %d\n", + c, atten_value, power_index, + tx_power.s.radio_tx_gain[c], + tx_power.s.dsp_predis_atten[c]); + } /* for each chain */ + + tx_power_tbl->power_tbl[i].dw = cpu_to_le32(tx_power.dw); + + } /* for each rate */ + + return 0; +} + +/** + * iwl4965_send_tx_power - Configure the TXPOWER level user limit + * + * Uses the active RXON for channel, band, and characteristics (ht40, high) + * The power limit is taken from priv->tx_power_user_lmt. + */ +static int iwl4965_send_tx_power(struct iwl_priv *priv) +{ + struct iwl4965_txpowertable_cmd cmd = { 0 }; + int ret; + u8 band = 0; + bool is_ht40 = false; + u8 ctrl_chan_high = 0; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status), + "TX Power requested while scanning!\n")) + return -EAGAIN; + + band = priv->band == IEEE80211_BAND_2GHZ; + + is_ht40 = is_ht40_channel(ctx->active.flags); + + if (is_ht40 && (ctx->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) + ctrl_chan_high = 1; + + cmd.band = band; + cmd.channel = ctx->active.channel; + + ret = iwl4965_fill_txpower_tbl(priv, band, + le16_to_cpu(ctx->active.channel), + is_ht40, ctrl_chan_high, &cmd.tx_power); + if (ret) + goto out; + + ret = iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, sizeof(cmd), &cmd); + +out: + return ret; +} + +static int iwl4965_send_rxon_assoc(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + int ret = 0; + struct iwl4965_rxon_assoc_cmd rxon_assoc; + const struct iwl_rxon_cmd *rxon1 = &ctx->staging; + const struct iwl_rxon_cmd *rxon2 = &ctx->active; + + if ((rxon1->flags == rxon2->flags) && + (rxon1->filter_flags == rxon2->filter_flags) && + (rxon1->cck_basic_rates == rxon2->cck_basic_rates) && + (rxon1->ofdm_ht_single_stream_basic_rates == + rxon2->ofdm_ht_single_stream_basic_rates) && + (rxon1->ofdm_ht_dual_stream_basic_rates == + rxon2->ofdm_ht_dual_stream_basic_rates) && + (rxon1->rx_chain == rxon2->rx_chain) && + (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) { + IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n"); + return 0; + } + + rxon_assoc.flags = ctx->staging.flags; + rxon_assoc.filter_flags = ctx->staging.filter_flags; + rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; + rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; + rxon_assoc.reserved = 0; + rxon_assoc.ofdm_ht_single_stream_basic_rates = + ctx->staging.ofdm_ht_single_stream_basic_rates; + rxon_assoc.ofdm_ht_dual_stream_basic_rates = + ctx->staging.ofdm_ht_dual_stream_basic_rates; + rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain; + + ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC, + sizeof(rxon_assoc), &rxon_assoc, NULL); + if (ret) + return ret; + + return ret; +} + +static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +{ + /* cast away the const for active_rxon in this function */ + struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active; + int ret; + bool new_assoc = + !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); + + if (!iwl_is_alive(priv)) + return -EBUSY; + + if (!ctx->is_active) + return 0; + + /* always get timestamp with Rx frame */ + ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; + + ret = iwl_check_rxon_cmd(priv, ctx); + if (ret) { + IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); + return -EINVAL; + } + + /* + * receive commit_rxon request + * abort any previous channel switch if still in process + */ + if (priv->switch_rxon.switch_in_progress && + (priv->switch_rxon.channel != ctx->staging.channel)) { + IWL_DEBUG_11H(priv, "abort channel switch on %d\n", + le16_to_cpu(priv->switch_rxon.channel)); + iwl_chswitch_done(priv, false); + } + + /* If we don't need to send a full RXON, we can use + * iwl_rxon_assoc_cmd which is used to reconfigure filter + * and other flags for the current radio configuration. */ + if (!iwl_full_rxon_required(priv, ctx)) { + ret = iwl_send_rxon_assoc(priv, ctx); + if (ret) { + IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret); + return ret; + } + + memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); + iwl_print_rx_config_cmd(priv, ctx); + return 0; + } + + /* If we are currently associated and the new config requires + * an RXON_ASSOC and the new config wants the associated mask enabled, + * we must clear the associated from the active configuration + * before we apply the new config */ + if (iwl_is_associated_ctx(ctx) && new_assoc) { + IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); + active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; + + ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, + sizeof(struct iwl_rxon_cmd), + active_rxon); + + /* If the mask clearing failed then we set + * active_rxon back to what it was previously */ + if (ret) { + active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; + IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret); + return ret; + } + iwl_clear_ucode_stations(priv, ctx); + iwl_restore_stations(priv, ctx); + ret = iwl_restore_default_wep_keys(priv, ctx); + if (ret) { + IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); + return ret; + } + } + + IWL_DEBUG_INFO(priv, "Sending RXON\n" + "* with%s RXON_FILTER_ASSOC_MSK\n" + "* channel = %d\n" + "* bssid = %pM\n", + (new_assoc ? "" : "out"), + le16_to_cpu(ctx->staging.channel), + ctx->staging.bssid_addr); + + iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto); + + /* Apply the new configuration + * RXON unassoc clears the station table in uCode so restoration of + * stations is needed after it (the RXON command) completes + */ + if (!new_assoc) { + ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, + sizeof(struct iwl_rxon_cmd), &ctx->staging); + if (ret) { + IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); + return ret; + } + IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n"); + memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); + iwl_clear_ucode_stations(priv, ctx); + iwl_restore_stations(priv, ctx); + ret = iwl_restore_default_wep_keys(priv, ctx); + if (ret) { + IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); + return ret; + } + } + if (new_assoc) { + priv->start_calib = 0; + /* Apply the new configuration + * RXON assoc doesn't clear the station table in uCode, + */ + ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, + sizeof(struct iwl_rxon_cmd), &ctx->staging); + if (ret) { + IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); + return ret; + } + memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); + } + iwl_print_rx_config_cmd(priv, ctx); + + iwl_init_sensitivity(priv); + + /* If we issue a new RXON command which required a tune then we must + * send a new TXPOWER command or we won't be able to Tx any frames */ + ret = iwl_set_tx_power(priv, priv->tx_power_next, true); + if (ret) { + IWL_ERR(priv, "Error sending TX power (%d)\n", ret); + return ret; + } + + return 0; +} + +static int iwl4965_hw_channel_switch(struct iwl_priv *priv, + struct ieee80211_channel_switch *ch_switch) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + int rc; + u8 band = 0; + bool is_ht40 = false; + u8 ctrl_chan_high = 0; + struct iwl4965_channel_switch_cmd cmd; + const struct iwl_channel_info *ch_info; + u32 switch_time_in_usec, ucode_switch_time; + u16 ch; + u32 tsf_low; + u8 switch_count; + u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); + struct ieee80211_vif *vif = ctx->vif; + band = priv->band == IEEE80211_BAND_2GHZ; + + is_ht40 = is_ht40_channel(ctx->staging.flags); + + if (is_ht40 && + (ctx->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) + ctrl_chan_high = 1; + + cmd.band = band; + cmd.expect_beacon = 0; + ch = ch_switch->channel->hw_value; + cmd.channel = cpu_to_le16(ch); + cmd.rxon_flags = ctx->staging.flags; + cmd.rxon_filter_flags = ctx->staging.filter_flags; + switch_count = ch_switch->count; + tsf_low = ch_switch->timestamp & 0x0ffffffff; + /* + * calculate the ucode channel switch time + * adding TSF as one of the factor for when to switch + */ + if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) { + if (switch_count > ((priv->ucode_beacon_time - tsf_low) / + beacon_interval)) { + switch_count -= (priv->ucode_beacon_time - + tsf_low) / beacon_interval; + } else + switch_count = 0; + } + if (switch_count <= 1) + cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); + else { + switch_time_in_usec = + vif->bss_conf.beacon_int * switch_count * TIME_UNIT; + ucode_switch_time = iwl_usecs_to_beacons(priv, + switch_time_in_usec, + beacon_interval); + cmd.switch_time = iwl_add_beacon_time(priv, + priv->ucode_beacon_time, + ucode_switch_time, + beacon_interval); + } + IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", + cmd.switch_time); + ch_info = iwl_get_channel_info(priv, priv->band, ch); + if (ch_info) + cmd.expect_beacon = is_channel_radar(ch_info); + else { + IWL_ERR(priv, "invalid channel switch from %u to %u\n", + ctx->active.channel, ch); + return -EFAULT; + } + + rc = iwl4965_fill_txpower_tbl(priv, band, ch, is_ht40, + ctrl_chan_high, &cmd.tx_power); + if (rc) { + IWL_DEBUG_11H(priv, "error:%d fill txpower_tbl\n", rc); + return rc; + } + + priv->switch_rxon.channel = cmd.channel; + priv->switch_rxon.switch_in_progress = true; + + return iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); +} + +/** + * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array + */ +static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv, + struct iwl_tx_queue *txq, + u16 byte_cnt) +{ + struct iwl4965_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr; + int txq_id = txq->q.id; + int write_ptr = txq->q.write_ptr; + int len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; + __le16 bc_ent; + + WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX); + + bc_ent = cpu_to_le16(len & 0xFFF); + /* Set up byte count within first 256 entries */ + scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent; + + /* If within first 64 entries, duplicate at end */ + if (write_ptr < TFD_QUEUE_SIZE_BC_DUP) + scd_bc_tbl[txq_id]. + tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; +} + +/** + * iwl4965_hw_get_temperature - return the calibrated temperature (in Kelvin) + * @statistics: Provides the temperature reading from the uCode + * + * A return of <0 indicates bogus data in the statistics + */ +static int iwl4965_hw_get_temperature(struct iwl_priv *priv) +{ + s32 temperature; + s32 vt; + s32 R1, R2, R3; + u32 R4; + + if (test_bit(STATUS_TEMPERATURE, &priv->status) && + (priv->_agn.statistics.flag & + STATISTICS_REPLY_FLG_HT40_MODE_MSK)) { + IWL_DEBUG_TEMP(priv, "Running HT40 temperature calibration\n"); + R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]); + R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]); + R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[1]); + R4 = le32_to_cpu(priv->card_alive_init.therm_r4[1]); + } else { + IWL_DEBUG_TEMP(priv, "Running temperature calibration\n"); + R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[0]); + R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[0]); + R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[0]); + R4 = le32_to_cpu(priv->card_alive_init.therm_r4[0]); + } + + /* + * Temperature is only 23 bits, so sign extend out to 32. + * + * NOTE If we haven't received a statistics notification yet + * with an updated temperature, use R4 provided to us in the + * "initialize" ALIVE response. + */ + if (!test_bit(STATUS_TEMPERATURE, &priv->status)) + vt = sign_extend32(R4, 23); + else + vt = sign_extend32(le32_to_cpu(priv->_agn.statistics. + general.common.temperature), 23); + + IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt); + + if (R3 == R1) { + IWL_ERR(priv, "Calibration conflict R1 == R3\n"); + return -1; + } + + /* Calculate temperature in degrees Kelvin, adjust by 97%. + * Add offset to center the adjustment around 0 degrees Centigrade. */ + temperature = TEMPERATURE_CALIB_A_VAL * (vt - R2); + temperature /= (R3 - R1); + temperature = (temperature * 97) / 100 + TEMPERATURE_CALIB_KELVIN_OFFSET; + + IWL_DEBUG_TEMP(priv, "Calibrated temperature: %dK, %dC\n", + temperature, KELVIN_TO_CELSIUS(temperature)); + + return temperature; +} + +/* Adjust Txpower only if temperature variance is greater than threshold. */ +#define IWL_TEMPERATURE_THRESHOLD 3 + +/** + * iwl4965_is_temp_calib_needed - determines if new calibration is needed + * + * If the temperature changed has changed sufficiently, then a recalibration + * is needed. + * + * Assumes caller will replace priv->last_temperature once calibration + * executed. + */ +static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv) +{ + int temp_diff; + + if (!test_bit(STATUS_STATISTICS, &priv->status)) { + IWL_DEBUG_TEMP(priv, "Temperature not updated -- no statistics.\n"); + return 0; + } + + temp_diff = priv->temperature - priv->last_temperature; + + /* get absolute value */ + if (temp_diff < 0) { + IWL_DEBUG_POWER(priv, "Getting cooler, delta %d\n", temp_diff); + temp_diff = -temp_diff; + } else if (temp_diff == 0) + IWL_DEBUG_POWER(priv, "Temperature unchanged\n"); + else + IWL_DEBUG_POWER(priv, "Getting warmer, delta %d\n", temp_diff); + + if (temp_diff < IWL_TEMPERATURE_THRESHOLD) { + IWL_DEBUG_POWER(priv, " => thermal txpower calib not needed\n"); + return 0; + } + + IWL_DEBUG_POWER(priv, " => thermal txpower calib needed\n"); + + return 1; +} + +static void iwl4965_temperature_calib(struct iwl_priv *priv) +{ + s32 temp; + + temp = iwl4965_hw_get_temperature(priv); + if (temp < 0) + return; + + if (priv->temperature != temp) { + if (priv->temperature) + IWL_DEBUG_TEMP(priv, "Temperature changed " + "from %dC to %dC\n", + KELVIN_TO_CELSIUS(priv->temperature), + KELVIN_TO_CELSIUS(temp)); + else + IWL_DEBUG_TEMP(priv, "Temperature " + "initialized to %dC\n", + KELVIN_TO_CELSIUS(temp)); + } + + priv->temperature = temp; + iwl_tt_handler(priv); + set_bit(STATUS_TEMPERATURE, &priv->status); + + if (!priv->disable_tx_power_cal && + unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && + iwl4965_is_temp_calib_needed(priv)) + queue_work(priv->workqueue, &priv->txpower_work); +} + +/** + * iwl4965_tx_queue_stop_scheduler - Stop queue, but keep configuration + */ +static void iwl4965_tx_queue_stop_scheduler(struct iwl_priv *priv, + u16 txq_id) +{ + /* Simply stop the queue, but don't change any configuration; + * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ + iwl_write_prph(priv, + IWL49_SCD_QUEUE_STATUS_BITS(txq_id), + (0 << IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE)| + (1 << IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); +} + +/** + * txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE + * priv->lock must be held by the caller + */ +static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, + u16 ssn_idx, u8 tx_fifo) +{ + if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || + (IWL49_FIRST_AMPDU_QUEUE + + priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { + IWL_WARN(priv, + "queue number out of range: %d, must be %d to %d\n", + txq_id, IWL49_FIRST_AMPDU_QUEUE, + IWL49_FIRST_AMPDU_QUEUE + + priv->cfg->base_params->num_of_ampdu_queues - 1); + return -EINVAL; + } + + iwl4965_tx_queue_stop_scheduler(priv, txq_id); + + iwl_clear_bits_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, (1 << txq_id)); + + priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); + priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); + /* supposes that ssn_idx is valid (!= 0xFFF) */ + iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx); + + iwl_clear_bits_prph(priv, IWL49_SCD_INTERRUPT_MASK, (1 << txq_id)); + iwl_txq_ctx_deactivate(priv, txq_id); + iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0); + + return 0; +} + +/** + * iwl4965_tx_queue_set_q2ratid - Map unique receiver/tid combination to a queue + */ +static int iwl4965_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid, + u16 txq_id) +{ + u32 tbl_dw_addr; + u32 tbl_dw; + u16 scd_q2ratid; + + scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK; + + tbl_dw_addr = priv->scd_base_addr + + IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id); + + tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr); + + if (txq_id & 0x1) + tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); + else + tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); + + iwl_write_targ_mem(priv, tbl_dw_addr, tbl_dw); + + return 0; +} + + +/** + * iwl4965_tx_queue_agg_enable - Set up & enable aggregation for selected queue + * + * NOTE: txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE, + * i.e. it must be one of the higher queues used for aggregation + */ +static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, + int tx_fifo, int sta_id, int tid, u16 ssn_idx) +{ + unsigned long flags; + u16 ra_tid; + int ret; + + if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || + (IWL49_FIRST_AMPDU_QUEUE + + priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { + IWL_WARN(priv, + "queue number out of range: %d, must be %d to %d\n", + txq_id, IWL49_FIRST_AMPDU_QUEUE, + IWL49_FIRST_AMPDU_QUEUE + + priv->cfg->base_params->num_of_ampdu_queues - 1); + return -EINVAL; + } + + ra_tid = BUILD_RAxTID(sta_id, tid); + + /* Modify device's station table to Tx this TID */ + ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); + if (ret) + return ret; + + spin_lock_irqsave(&priv->lock, flags); + + /* Stop this Tx queue before configuring it */ + iwl4965_tx_queue_stop_scheduler(priv, txq_id); + + /* Map receiver-address / traffic-ID to this queue */ + iwl4965_tx_queue_set_q2ratid(priv, ra_tid, txq_id); + + /* Set this queue as a chain-building queue */ + iwl_set_bits_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, (1 << txq_id)); + + /* Place first TFD at index corresponding to start sequence number. + * Assumes that ssn_idx is valid (!= 0xFFF) */ + priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); + priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); + iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx); + + /* Set up Tx window size and frame limit for this queue */ + iwl_write_targ_mem(priv, + priv->scd_base_addr + IWL49_SCD_CONTEXT_QUEUE_OFFSET(txq_id), + (SCD_WIN_SIZE << IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) & + IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK); + + iwl_write_targ_mem(priv, priv->scd_base_addr + + IWL49_SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), + (SCD_FRAME_LIMIT << IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) + & IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK); + + iwl_set_bits_prph(priv, IWL49_SCD_INTERRUPT_MASK, (1 << txq_id)); + + /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ + iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1); + + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + + +static u16 iwl4965_get_hcmd_size(u8 cmd_id, u16 len) +{ + switch (cmd_id) { + case REPLY_RXON: + return (u16) sizeof(struct iwl4965_rxon_cmd); + default: + return len; + } +} + +static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) +{ + struct iwl4965_addsta_cmd *addsta = (struct iwl4965_addsta_cmd *)data; + addsta->mode = cmd->mode; + memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify)); + memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo)); + addsta->station_flags = cmd->station_flags; + addsta->station_flags_msk = cmd->station_flags_msk; + addsta->tid_disable_tx = cmd->tid_disable_tx; + addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid; + addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid; + addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn; + addsta->sleep_tx_count = cmd->sleep_tx_count; + addsta->reserved1 = cpu_to_le16(0); + addsta->reserved2 = cpu_to_le16(0); + + return (u16)sizeof(struct iwl4965_addsta_cmd); +} + +static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp) +{ + return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN; +} + +/** + * iwl4965_tx_status_reply_tx - Handle Tx response for frames in aggregation queue + */ +static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, + struct iwl_ht_agg *agg, + struct iwl4965_tx_resp *tx_resp, + int txq_id, u16 start_idx) +{ + u16 status; + struct agg_tx_status *frame_status = tx_resp->u.agg_status; + struct ieee80211_tx_info *info = NULL; + struct ieee80211_hdr *hdr = NULL; + u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); + int i, sh, idx; + u16 seq; + if (agg->wait_for_ba) + IWL_DEBUG_TX_REPLY(priv, "got tx response w/o block-ack\n"); + + agg->frame_count = tx_resp->frame_count; + agg->start_idx = start_idx; + agg->rate_n_flags = rate_n_flags; + agg->bitmap = 0; + + /* num frames attempted by Tx command */ + if (agg->frame_count == 1) { + /* Only one frame was attempted; no block-ack will arrive */ + status = le16_to_cpu(frame_status[0].status); + idx = start_idx; + + /* FIXME: code repetition */ + IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n", + agg->frame_count, agg->start_idx, idx); + + info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb); + info->status.rates[0].count = tx_resp->failure_frame + 1; + info->flags &= ~IEEE80211_TX_CTL_AMPDU; + info->flags |= iwl_tx_status_to_mac80211(status); + iwlagn_hwrate_to_tx_control(priv, rate_n_flags, info); + /* FIXME: code repetition end */ + + IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n", + status & 0xff, tx_resp->failure_frame); + IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags); + + agg->wait_for_ba = 0; + } else { + /* Two or more frames were attempted; expect block-ack */ + u64 bitmap = 0; + int start = agg->start_idx; + + /* Construct bit-map of pending frames within Tx window */ + for (i = 0; i < agg->frame_count; i++) { + u16 sc; + status = le16_to_cpu(frame_status[i].status); + seq = le16_to_cpu(frame_status[i].sequence); + idx = SEQ_TO_INDEX(seq); + txq_id = SEQ_TO_QUEUE(seq); + + if (status & (AGG_TX_STATE_FEW_BYTES_MSK | + AGG_TX_STATE_ABORT_MSK)) + continue; + + IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n", + agg->frame_count, txq_id, idx); + + hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx); + if (!hdr) { + IWL_ERR(priv, + "BUG_ON idx doesn't point to valid skb" + " idx=%d, txq_id=%d\n", idx, txq_id); + return -1; + } + + sc = le16_to_cpu(hdr->seq_ctrl); + if (idx != (SEQ_TO_SN(sc) & 0xff)) { + IWL_ERR(priv, + "BUG_ON idx doesn't match seq control" + " idx=%d, seq_idx=%d, seq=%d\n", + idx, SEQ_TO_SN(sc), hdr->seq_ctrl); + return -1; + } + + IWL_DEBUG_TX_REPLY(priv, "AGG Frame i=%d idx %d seq=%d\n", + i, idx, SEQ_TO_SN(sc)); + + sh = idx - start; + if (sh > 64) { + sh = (start - idx) + 0xff; + bitmap = bitmap << sh; + sh = 0; + start = idx; + } else if (sh < -64) + sh = 0xff - (start - idx); + else if (sh < 0) { + sh = start - idx; + start = idx; + bitmap = bitmap << sh; + sh = 0; + } + bitmap |= 1ULL << sh; + IWL_DEBUG_TX_REPLY(priv, "start=%d bitmap=0x%llx\n", + start, (unsigned long long)bitmap); + } + + agg->bitmap = bitmap; + agg->start_idx = start; + IWL_DEBUG_TX_REPLY(priv, "Frames %d start_idx=%d bitmap=0x%llx\n", + agg->frame_count, agg->start_idx, + (unsigned long long)agg->bitmap); + + if (bitmap) + agg->wait_for_ba = 1; + } + return 0; +} + +static u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr) +{ + int i; + int start = 0; + int ret = IWL_INVALID_STATION; + unsigned long flags; + + if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) || + (priv->iw_mode == NL80211_IFTYPE_AP)) + start = IWL_STA_ID; + + if (is_broadcast_ether_addr(addr)) + return priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; + + spin_lock_irqsave(&priv->sta_lock, flags); + for (i = start; i < priv->hw_params.max_stations; i++) + if (priv->stations[i].used && + (!compare_ether_addr(priv->stations[i].sta.sta.addr, + addr))) { + ret = i; + goto out; + } + + IWL_DEBUG_ASSOC_LIMIT(priv, "can not find STA %pM total %d\n", + addr, priv->num_stations); + + out: + /* + * It may be possible that more commands interacting with stations + * arrive before we completed processing the adding of + * station + */ + if (ret != IWL_INVALID_STATION && + (!(priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) || + ((priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) && + (priv->stations[ret].used & IWL_STA_UCODE_INPROGRESS)))) { + IWL_ERR(priv, "Requested station info for sta %d before ready.\n", + ret); + ret = IWL_INVALID_STATION; + } + spin_unlock_irqrestore(&priv->sta_lock, flags); + return ret; +} + +static int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) +{ + if (priv->iw_mode == NL80211_IFTYPE_STATION) { + return IWL_AP_ID; + } else { + u8 *da = ieee80211_get_DA(hdr); + return iwl_find_station(priv, da); + } +} + +/** + * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response + */ +static void iwl4965_rx_reply_tx(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + u16 sequence = le16_to_cpu(pkt->hdr.sequence); + int txq_id = SEQ_TO_QUEUE(sequence); + int index = SEQ_TO_INDEX(sequence); + struct iwl_tx_queue *txq = &priv->txq[txq_id]; + struct ieee80211_hdr *hdr; + struct ieee80211_tx_info *info; + struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; + u32 status = le32_to_cpu(tx_resp->u.status); + int uninitialized_var(tid); + int sta_id; + int freed; + u8 *qc = NULL; + unsigned long flags; + + if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { + IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " + "is out of range [0-%d] %d %d\n", txq_id, + index, txq->q.n_bd, txq->q.write_ptr, + txq->q.read_ptr); + return; + } + + txq->time_stamp = jiffies; + info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); + memset(&info->status, 0, sizeof(info->status)); + + hdr = iwl_tx_queue_get_hdr(priv, txq_id, index); + if (ieee80211_is_data_qos(hdr->frame_control)) { + qc = ieee80211_get_qos_ctl(hdr); + tid = qc[0] & 0xf; + } + + sta_id = iwl_get_ra_sta_id(priv, hdr); + if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) { + IWL_ERR(priv, "Station not known\n"); + return; + } + + spin_lock_irqsave(&priv->sta_lock, flags); + if (txq->sched_retry) { + const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); + struct iwl_ht_agg *agg = NULL; + WARN_ON(!qc); + + agg = &priv->stations[sta_id].tid[tid].agg; + + iwl4965_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); + + /* check if BAR is needed */ + if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) + info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; + + if (txq->q.read_ptr != (scd_ssn & 0xff)) { + index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); + IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn " + "%d index %d\n", scd_ssn , index); + freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); + if (qc) + iwl_free_tfds_in_queue(priv, sta_id, + tid, freed); + + if (priv->mac80211_registered && + (iwl_queue_space(&txq->q) > txq->q.low_mark) && + (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) + iwl_wake_queue(priv, txq); + } + } else { + info->status.rates[0].count = tx_resp->failure_frame + 1; + info->flags |= iwl_tx_status_to_mac80211(status); + iwlagn_hwrate_to_tx_control(priv, + le32_to_cpu(tx_resp->rate_n_flags), + info); + + IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) " + "rate_n_flags 0x%x retries %d\n", + txq_id, + iwl_get_tx_fail_reason(status), status, + le32_to_cpu(tx_resp->rate_n_flags), + tx_resp->failure_frame); + + freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); + if (qc && likely(sta_id != IWL_INVALID_STATION)) + iwl_free_tfds_in_queue(priv, sta_id, tid, freed); + else if (sta_id == IWL_INVALID_STATION) + IWL_DEBUG_TX_REPLY(priv, "Station not known\n"); + + if (priv->mac80211_registered && + (iwl_queue_space(&txq->q) > txq->q.low_mark)) + iwl_wake_queue(priv, txq); + } + if (qc && likely(sta_id != IWL_INVALID_STATION)) + iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); + + iwl_check_abort_status(priv, tx_resp->frame_count, status); + + spin_unlock_irqrestore(&priv->sta_lock, flags); +} + +static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl4965_beacon_notif *beacon = (void *)pkt->u.raw; +#ifdef CONFIG_IWLWIFI_DEBUG + u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); + + IWL_DEBUG_RX(priv, "beacon status %#x, retries:%d ibssmgr:%d " + "tsf:0x%.8x%.8x rate:%d\n", + le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK, + beacon->beacon_notify_hdr.failure_frame, + le32_to_cpu(beacon->ibss_mgr_status), + le32_to_cpu(beacon->high_tsf), + le32_to_cpu(beacon->low_tsf), rate); +#endif + + priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); + + if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) + queue_work(priv->workqueue, &priv->beacon_update); +} + +static int iwl4965_calc_rssi(struct iwl_priv *priv, + struct iwl_rx_phy_res *rx_resp) +{ + /* data from PHY/DSP regarding signal strength, etc., + * contents are always there, not configurable by host. */ + struct iwl4965_rx_non_cfg_phy *ncphy = + (struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy_buf; + u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL49_AGC_DB_MASK) + >> IWL49_AGC_DB_POS; + + u32 valid_antennae = + (le16_to_cpu(rx_resp->phy_flags) & IWL49_RX_PHY_FLAGS_ANTENNAE_MASK) + >> IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET; + u8 max_rssi = 0; + u32 i; + + /* Find max rssi among 3 possible receivers. + * These values are measured by the digital signal processor (DSP). + * They should stay fairly constant even as the signal strength varies, + * if the radio's automatic gain control (AGC) is working right. + * AGC value (see below) will provide the "interesting" info. */ + for (i = 0; i < 3; i++) + if (valid_antennae & (1 << i)) + max_rssi = max(ncphy->rssi_info[i << 1], max_rssi); + + IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n", + ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4], + max_rssi, agc); + + /* dBm = max_rssi dB - agc dB - constant. + * Higher AGC (higher radio gain) means lower signal. */ + return max_rssi - agc - IWLAGN_RSSI_OFFSET; +} + + +/* Set up 4965-specific Rx frame reply handlers */ +static void iwl4965_rx_handler_setup(struct iwl_priv *priv) +{ + /* Legacy Rx frames */ + priv->rx_handlers[REPLY_RX] = iwlagn_rx_reply_rx; + /* Tx response */ + priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; + priv->rx_handlers[BEACON_NOTIFICATION] = iwl4965_rx_beacon_notif; + + /* set up notification wait support */ + spin_lock_init(&priv->_agn.notif_wait_lock); + INIT_LIST_HEAD(&priv->_agn.notif_waits); + init_waitqueue_head(&priv->_agn.notif_waitq); +} + +static void iwl4965_setup_deferred_work(struct iwl_priv *priv) +{ + INIT_WORK(&priv->txpower_work, iwl4965_bg_txpower_work); +} + +static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) +{ + cancel_work_sync(&priv->txpower_work); +} + +static struct iwl_hcmd_ops iwl4965_hcmd = { + .rxon_assoc = iwl4965_send_rxon_assoc, + .commit_rxon = iwl4965_commit_rxon, + .set_rxon_chain = iwlagn_set_rxon_chain, + .send_bt_config = iwl_send_bt_config, +}; + +static void iwl4965_post_scan(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + /* + * Since setting the RXON may have been deferred while + * performing the scan, fire one off if needed + */ + if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) + iwlcore_commit_rxon(priv, ctx); +} + +static void iwl4965_post_associate(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + struct ieee80211_vif *vif = ctx->vif; + struct ieee80211_conf *conf = NULL; + int ret = 0; + + if (!vif || !priv->is_open) + return; + + if (vif->type == NL80211_IFTYPE_AP) { + IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); + return; + } + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + iwl_scan_cancel_timeout(priv, 200); + + conf = ieee80211_get_hw_conf(priv->hw); + + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); + + ret = iwl_send_rxon_timing(priv, ctx); + if (ret) + IWL_WARN(priv, "RXON timing - " + "Attempting to continue.\n"); + + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + + iwl_set_rxon_ht(priv, &priv->current_ht_config); + + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + + ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); + + IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", + vif->bss_conf.aid, vif->bss_conf.beacon_int); + + if (vif->bss_conf.use_short_preamble) + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + else + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { + if (vif->bss_conf.use_short_slot) + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + else + ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + } + + iwlcore_commit_rxon(priv, ctx); + + IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", + vif->bss_conf.aid, ctx->active.bssid_addr); + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + break; + case NL80211_IFTYPE_ADHOC: + iwlagn_send_beacon_cmd(priv); + break; + default: + IWL_ERR(priv, "%s Should not be called in %d mode\n", + __func__, vif->type); + break; + } + + /* the chain noise calibration will enabled PM upon completion + * If chain noise has already been run, then we need to enable + * power management here */ + if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE) + iwl_power_update_mode(priv, false); + + /* Enable Rx differential gain and sensitivity calibrations */ + iwl_chain_noise_reset(priv); + priv->start_calib = 1; +} + +static void iwl4965_config_ap(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + struct ieee80211_vif *vif = ctx->vif; + int ret = 0; + + lockdep_assert_held(&priv->mutex); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + /* The following should be done only at AP bring up */ + if (!iwl_is_associated_ctx(ctx)) { + + /* RXON - unassoc (to set timing command) */ + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); + + /* RXON Timing */ + ret = iwl_send_rxon_timing(priv, ctx); + if (ret) + IWL_WARN(priv, "RXON timing failed - " + "Attempting to continue.\n"); + + /* AP has all antennas */ + priv->chain_noise_data.active_chains = + priv->hw_params.valid_rx_ant; + iwl_set_rxon_ht(priv, &priv->current_ht_config); + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + + ctx->staging.assoc_id = 0; + + if (vif->bss_conf.use_short_preamble) + ctx->staging.flags |= + RXON_FLG_SHORT_PREAMBLE_MSK; + else + ctx->staging.flags &= + ~RXON_FLG_SHORT_PREAMBLE_MSK; + + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { + if (vif->bss_conf.use_short_slot) + ctx->staging.flags |= + RXON_FLG_SHORT_SLOT_MSK; + else + ctx->staging.flags &= + ~RXON_FLG_SHORT_SLOT_MSK; + } + /* need to send beacon cmd before committing assoc RXON! */ + iwlagn_send_beacon_cmd(priv); + /* restore RXON assoc */ + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); + } + iwlagn_send_beacon_cmd(priv); + + /* FIXME - we need to add code here to detect a totally new + * configuration, reset the AP, unassoc, rxon timing, assoc, + * clear sta table, add BCAST sta... */ +} + +static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { + .get_hcmd_size = iwl4965_get_hcmd_size, + .build_addsta_hcmd = iwl4965_build_addsta_hcmd, + .chain_noise_reset = iwl4965_chain_noise_reset, + .gain_computation = iwl4965_gain_computation, + .tx_cmd_protection = iwl_legacy_tx_cmd_protection, + .calc_rssi = iwl4965_calc_rssi, + .request_scan = iwlagn_request_scan, + .post_scan = iwl4965_post_scan, +}; + +static struct iwl_lib_ops iwl4965_lib = { + .set_hw_params = iwl4965_hw_set_hw_params, + .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, + .txq_set_sched = iwl4965_txq_set_sched, + .txq_agg_enable = iwl4965_txq_agg_enable, + .txq_agg_disable = iwl4965_txq_agg_disable, + .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, + .txq_free_tfd = iwl_hw_txq_free_tfd, + .txq_init = iwl_hw_tx_queue_init, + .rx_handler_setup = iwl4965_rx_handler_setup, + .setup_deferred_work = iwl4965_setup_deferred_work, + .cancel_deferred_work = iwl4965_cancel_deferred_work, + .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, + .alive_notify = iwl4965_alive_notify, + .init_alive_start = iwl4965_init_alive_start, + .load_ucode = iwl4965_load_bsm, + .dump_nic_event_log = iwl_dump_nic_event_log, + .dump_nic_error_log = iwl_dump_nic_error_log, + .dump_fh = iwl_dump_fh, + .set_channel_switch = iwl4965_hw_channel_switch, + .apm_ops = { + .init = iwl_apm_init, + .config = iwl4965_nic_config, + }, + .eeprom_ops = { + .regulatory_bands = { + EEPROM_REGULATORY_BAND_1_CHANNELS, + EEPROM_REGULATORY_BAND_2_CHANNELS, + EEPROM_REGULATORY_BAND_3_CHANNELS, + EEPROM_REGULATORY_BAND_4_CHANNELS, + EEPROM_REGULATORY_BAND_5_CHANNELS, + EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS, + EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS + }, + .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, + .release_semaphore = iwlcore_eeprom_release_semaphore, + .calib_version = iwl4965_eeprom_calib_version, + .query_addr = iwlcore_eeprom_query_addr, + }, + .send_tx_power = iwl4965_send_tx_power, + .update_chain_flags = iwl_update_chain_flags, + .isr_ops = { + .isr = iwl_isr_legacy, + }, + .temp_ops = { + .temperature = iwl4965_temperature_calib, + }, + .debugfs_ops = { + .rx_stats_read = iwl_ucode_rx_stats_read, + .tx_stats_read = iwl_ucode_tx_stats_read, + .general_stats_read = iwl_ucode_general_stats_read, + .bt_stats_read = iwl_ucode_bt_stats_read, + .reply_tx_error = iwl_reply_tx_error_read, + }, + .check_plcp_health = iwl_good_plcp_health, +}; + +static const struct iwl_legacy_ops iwl4965_legacy_ops = { + .post_associate = iwl4965_post_associate, + .config_ap = iwl4965_config_ap, + .manage_ibss_station = iwlagn_manage_ibss_station, + .update_bcast_stations = iwl_update_bcast_stations, +}; + +struct ieee80211_ops iwl4965_hw_ops = { + .tx = iwlagn_mac_tx, + .start = iwlagn_mac_start, + .stop = iwlagn_mac_stop, + .add_interface = iwl_mac_add_interface, + .remove_interface = iwl_mac_remove_interface, + .change_interface = iwl_mac_change_interface, + .config = iwl_legacy_mac_config, + .configure_filter = iwlagn_configure_filter, + .set_key = iwlagn_mac_set_key, + .update_tkip_key = iwlagn_mac_update_tkip_key, + .conf_tx = iwl_mac_conf_tx, + .reset_tsf = iwl_legacy_mac_reset_tsf, + .bss_info_changed = iwl_legacy_mac_bss_info_changed, + .ampdu_action = iwlagn_mac_ampdu_action, + .hw_scan = iwl_mac_hw_scan, + .sta_add = iwlagn_mac_sta_add, + .sta_remove = iwl_mac_sta_remove, + .channel_switch = iwlagn_mac_channel_switch, + .flush = iwlagn_mac_flush, + .tx_last_beacon = iwl_mac_tx_last_beacon, +}; + +static const struct iwl_ops iwl4965_ops = { + .lib = &iwl4965_lib, + .hcmd = &iwl4965_hcmd, + .utils = &iwl4965_hcmd_utils, + .led = &iwlagn_led_ops, + .legacy = &iwl4965_legacy_ops, + .ieee80211_ops = &iwl4965_hw_ops, +}; + +static struct iwl_base_params iwl4965_base_params = { + .eeprom_size = IWL4965_EEPROM_IMG_SIZE, + .num_of_queues = IWL49_NUM_QUEUES, + .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES, + .pll_cfg_val = 0, + .set_l0s = true, + .use_bsm = true, + .use_isr_legacy = true, + .broken_powersave = true, + .led_compensation = 61, + .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .wd_timeout = IWL_DEF_WD_TIMEOUT, + .temperature_kelvin = true, + .max_event_log_size = 512, + .tx_power_by_driver = true, + .ucode_tracing = true, + .sensitivity_calib_by_driver = true, + .chain_noise_calib_by_driver = true, + .no_agg_framecnt_info = true, +}; + +struct iwl_cfg iwl4965_agn_cfg = { + .name = "Intel(R) Wireless WiFi Link 4965AGN", + .fw_name_pre = IWL4965_FW_PRE, + .ucode_api_max = IWL4965_UCODE_API_MAX, + .ucode_api_min = IWL4965_UCODE_API_MIN, + .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_ABC, + .eeprom_ver = EEPROM_4965_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION, + .ops = &iwl4965_ops, + .mod_params = &iwlagn_mod_params, + .base_params = &iwl4965_base_params, + .led_mode = IWL_LED_BLINK, + /* + * Force use of chains B and C for scan RX on 5 GHz band + * because the device has off-channel reception on chain A. + */ + .scan_rx_antennas[IEEE80211_BAND_5GHZ] = ANT_BC, +}; + +/* Module firmware */ +MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE(IWL4965_UCODE_API_MAX)); + diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d08fa938501a..9965215697bb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -86,6 +86,7 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_VERSION(DRV_VERSION); MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); MODULE_LICENSE("GPL"); +MODULE_ALIAS("iwl4965"); static int iwlagn_ant_coupling; static bool iwlagn_bt_ch_announce = 1; @@ -3809,6 +3810,7 @@ static void iwlagn_bg_roc_done(struct work_struct *work) mutex_unlock(&priv->mutex); } +#ifdef CONFIG_IWL5000 static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_channel *channel, enum nl80211_channel_type channel_type, @@ -3864,6 +3866,7 @@ static int iwl_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) return 0; } +#endif /***************************************************************************** * @@ -4033,6 +4036,7 @@ static void iwl_uninit_drv(struct iwl_priv *priv) kfree(priv->scan_cmd); } +#ifdef CONFIG_IWL5000 struct ieee80211_ops iwlagn_hw_ops = { .tx = iwlagn_mac_tx, .start = iwlagn_mac_start, @@ -4057,6 +4061,7 @@ struct ieee80211_ops iwlagn_hw_ops = { .remain_on_channel = iwl_mac_remain_on_channel, .cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel, }; +#endif static void iwl_hw_detect(struct iwl_priv *priv) { @@ -4124,7 +4129,12 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (cfg->mod_params->disable_hw_scan) { dev_printk(KERN_DEBUG, &(pdev->dev), "sw scan support is deprecated\n"); +#ifdef CONFIG_IWL5000 iwlagn_hw_ops.hw_scan = NULL; +#endif +#ifdef CONFIG_IWL4965 + iwl4965_hw_ops.hw_scan = NULL; +#endif } hw = iwl_alloc_all(cfg); @@ -4503,6 +4513,12 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) /* Hardware specific file defines the PCI IDs table for that hardware module */ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { +#ifdef CONFIG_IWL4965 + {IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)}, + {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)}, +#endif /* CONFIG_IWL4965 */ +#ifdef CONFIG_IWL5000 +/* 5100 Series WiFi */ {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */ {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */ {IWL_PCI_DEVICE(0x4232, 0x1204, iwl5100_agn_cfg)}, /* Mini Card */ @@ -4688,6 +4704,8 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x0893, 0x0266, iwl230_bg_cfg)}, {IWL_PCI_DEVICE(0x0892, 0x0466, iwl230_bg_cfg)}, +#endif /* CONFIG_IWL5000 */ + {0} }; MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 4bd342060254..977ddfb8c24c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -43,6 +43,11 @@ #include "iwl-helpers.h" +MODULE_DESCRIPTION("iwl core"); +MODULE_VERSION(IWLWIFI_VERSION); +MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); +MODULE_LICENSE("GPL"); + /* * set bt_coex_active to true, uCode will do kill/defer * every time the priority line is asserted (BT is sending signals on the @@ -60,12 +65,15 @@ * default: bt_coex_active = true (BT_COEX_ENABLE) */ bool bt_coex_active = true; +EXPORT_SYMBOL_GPL(bt_coex_active); module_param(bt_coex_active, bool, S_IRUGO); MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist"); u32 iwl_debug_level; +EXPORT_SYMBOL(iwl_debug_level); const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +EXPORT_SYMBOL(iwl_bcast_addr); /* This function both allocates and initializes hw and priv. */ @@ -90,6 +98,7 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg) out: return hw; } +EXPORT_SYMBOL(iwl_alloc_all); #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ @@ -263,6 +272,7 @@ int iwlcore_init_geos(struct iwl_priv *priv) return 0; } +EXPORT_SYMBOL(iwlcore_init_geos); /* * iwlcore_free_geos - undo allocations in iwlcore_init_geos @@ -273,6 +283,7 @@ void iwlcore_free_geos(struct iwl_priv *priv) kfree(priv->ieee_rates); clear_bit(STATUS_GEO_CONFIGURED, &priv->status); } +EXPORT_SYMBOL(iwlcore_free_geos); static bool iwl_is_channel_extension(struct iwl_priv *priv, enum ieee80211_band band, @@ -317,6 +328,7 @@ bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, le16_to_cpu(ctx->staging.channel), ctx->ht.extension_chan_offset); } +EXPORT_SYMBOL(iwl_is_ht40_tx_allowed); static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val) { @@ -417,6 +429,7 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) return iwl_send_cmd_pdu(priv, ctx->rxon_timing_cmd, sizeof(ctx->timing), &ctx->timing); } +EXPORT_SYMBOL(iwl_send_rxon_timing); void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, int hw_decrypt) @@ -429,6 +442,7 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK; } +EXPORT_SYMBOL(iwl_set_rxon_hwcrypto); /* validate RXON structure is valid */ int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx) @@ -501,6 +515,7 @@ int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx) } return 0; } +EXPORT_SYMBOL(iwl_check_rxon_cmd); /** * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed @@ -564,6 +579,7 @@ int iwl_full_rxon_required(struct iwl_priv *priv, return 0; } +EXPORT_SYMBOL(iwl_full_rxon_required); u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, struct iwl_rxon_context *ctx) @@ -577,6 +593,7 @@ u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, else return IWL_RATE_6M_PLCP; } +EXPORT_SYMBOL(iwl_rate_get_lowest_plcp); static void _iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf, @@ -653,6 +670,7 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf) for_each_context(priv, ctx) _iwl_set_rxon_ht(priv, ht_conf, ctx); } +EXPORT_SYMBOL(iwl_set_rxon_ht); /* Return valid, unused, channel for a passive scan to reset the RF */ u8 iwl_get_single_channel_number(struct iwl_priv *priv, @@ -693,6 +711,7 @@ u8 iwl_get_single_channel_number(struct iwl_priv *priv, return channel; } +EXPORT_SYMBOL(iwl_get_single_channel_number); /** * iwl_set_rxon_channel - Set the band and channel values in staging RXON @@ -723,6 +742,7 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, return 0; } +EXPORT_SYMBOL(iwl_set_rxon_channel); void iwl_set_flags_for_band(struct iwl_priv *priv, struct iwl_rxon_context *ctx, @@ -746,6 +766,7 @@ void iwl_set_flags_for_band(struct iwl_priv *priv, ctx->staging.flags &= ~RXON_FLG_CCK_MSK; } } +EXPORT_SYMBOL(iwl_set_flags_for_band); /* * initialize rxon structure with default values from eeprom @@ -817,6 +838,7 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff; ctx->staging.ofdm_ht_triple_stream_basic_rates = 0xff; } +EXPORT_SYMBOL(iwl_connection_init_rx_config); void iwl_set_rate(struct iwl_priv *priv) { @@ -849,6 +871,7 @@ void iwl_set_rate(struct iwl_priv *priv) (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; } } +EXPORT_SYMBOL(iwl_set_rate); void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) { @@ -868,6 +891,7 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) mutex_unlock(&priv->mutex); } } +EXPORT_SYMBOL(iwl_chswitch_done); void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { @@ -895,6 +919,7 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) } } } +EXPORT_SYMBOL(iwl_rx_csa); #ifdef CONFIG_IWLWIFI_DEBUG void iwl_print_rx_config_cmd(struct iwl_priv *priv, @@ -916,6 +941,7 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv, IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr); IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id)); } +EXPORT_SYMBOL(iwl_print_rx_config_cmd); #endif /** * iwl_irq_handle_error - called for HW or SW error interrupt from card @@ -995,6 +1021,7 @@ void iwl_irq_handle_error(struct iwl_priv *priv) queue_work(priv->workqueue, &priv->restart); } } +EXPORT_SYMBOL(iwl_irq_handle_error); static int iwl_apm_stop_master(struct iwl_priv *priv) { @@ -1031,6 +1058,7 @@ void iwl_apm_stop(struct iwl_priv *priv) */ iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); } +EXPORT_SYMBOL(iwl_apm_stop); /* @@ -1145,6 +1173,7 @@ int iwl_apm_init(struct iwl_priv *priv) out: return ret; } +EXPORT_SYMBOL(iwl_apm_init); int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) @@ -1204,6 +1233,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) } return ret; } +EXPORT_SYMBOL(iwl_set_tx_power); void iwl_send_bt_config(struct iwl_priv *priv) { @@ -1227,6 +1257,7 @@ void iwl_send_bt_config(struct iwl_priv *priv) sizeof(struct iwl_bt_cmd), &bt_cmd)) IWL_ERR(priv, "failed to send BT Coex Config\n"); } +EXPORT_SYMBOL(iwl_send_bt_config); int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) { @@ -1244,6 +1275,7 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) sizeof(struct iwl_statistics_cmd), &statistics_cmd); } +EXPORT_SYMBOL(iwl_send_statistics_request); void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) @@ -1255,6 +1287,7 @@ void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, sleep->pm_sleep_mode, sleep->pm_wakeup_src); #endif } +EXPORT_SYMBOL(iwl_rx_pm_sleep_notif); void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) @@ -1266,6 +1299,7 @@ void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, get_cmd_string(pkt->hdr.cmd)); iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len); } +EXPORT_SYMBOL(iwl_rx_pm_debug_statistics_notif); void iwl_rx_reply_error(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) @@ -1280,6 +1314,7 @@ void iwl_rx_reply_error(struct iwl_priv *priv, le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num), le32_to_cpu(pkt->u.err_resp.error_info)); } +EXPORT_SYMBOL(iwl_rx_reply_error); void iwl_clear_isr_stats(struct iwl_priv *priv) { @@ -1331,6 +1366,7 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, IWL_DEBUG_MAC80211(priv, "leave\n"); return 0; } +EXPORT_SYMBOL(iwl_mac_conf_tx); int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw) { @@ -1338,6 +1374,7 @@ int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw) return priv->ibss_manager == IWL_IBSS_MANAGER; } +EXPORT_SYMBOL_GPL(iwl_mac_tx_last_beacon); static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { @@ -1447,6 +1484,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) IWL_DEBUG_MAC80211(priv, "leave\n"); return err; } +EXPORT_SYMBOL(iwl_mac_add_interface); static void iwl_teardown_interface(struct iwl_priv *priv, struct ieee80211_vif *vif, @@ -1499,6 +1537,7 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "leave\n"); } +EXPORT_SYMBOL(iwl_mac_remove_interface); int iwl_alloc_txq_mem(struct iwl_priv *priv) { @@ -1513,12 +1552,14 @@ int iwl_alloc_txq_mem(struct iwl_priv *priv) } return 0; } +EXPORT_SYMBOL(iwl_alloc_txq_mem); void iwl_free_txq_mem(struct iwl_priv *priv) { kfree(priv->txq); priv->txq = NULL; } +EXPORT_SYMBOL(iwl_free_txq_mem); #ifdef CONFIG_IWLWIFI_DEBUGFS @@ -1557,6 +1598,7 @@ int iwl_alloc_traffic_mem(struct iwl_priv *priv) iwl_reset_traffic_log(priv); return 0; } +EXPORT_SYMBOL(iwl_alloc_traffic_mem); void iwl_free_traffic_mem(struct iwl_priv *priv) { @@ -1566,6 +1608,7 @@ void iwl_free_traffic_mem(struct iwl_priv *priv) kfree(priv->rx_traffic); priv->rx_traffic = NULL; } +EXPORT_SYMBOL(iwl_free_traffic_mem); void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv, u16 length, struct ieee80211_hdr *header) @@ -1590,6 +1633,7 @@ void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv, (priv->tx_traffic_idx + 1) % IWL_TRAFFIC_ENTRIES; } } +EXPORT_SYMBOL(iwl_dbg_log_tx_data_frame); void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, u16 length, struct ieee80211_hdr *header) @@ -1614,6 +1658,7 @@ void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, (priv->rx_traffic_idx + 1) % IWL_TRAFFIC_ENTRIES; } } +EXPORT_SYMBOL(iwl_dbg_log_rx_data_frame); const char *get_mgmt_string(int cmd) { @@ -1750,6 +1795,7 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) stats->data_bytes += len; } } +EXPORT_SYMBOL(iwl_update_stats); #endif static void iwl_force_rf_reset(struct iwl_priv *priv) @@ -1888,6 +1934,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_unlock(&priv->mutex); return err; } +EXPORT_SYMBOL(iwl_mac_change_interface); /* * On every watchdog tick we check (latest) time stamp. If it does not @@ -1959,6 +2006,7 @@ void iwl_bg_watchdog(unsigned long data) mod_timer(&priv->watchdog, jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout))); } +EXPORT_SYMBOL(iwl_bg_watchdog); void iwl_setup_watchdog(struct iwl_priv *priv) { @@ -1970,6 +2018,7 @@ void iwl_setup_watchdog(struct iwl_priv *priv) else del_timer(&priv->watchdog); } +EXPORT_SYMBOL(iwl_setup_watchdog); /* * extended beacon time format @@ -1995,6 +2044,7 @@ u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval) return (quot << priv->hw_params.beacon_time_tsf_bits) + rem; } +EXPORT_SYMBOL(iwl_usecs_to_beacons); /* base is usually what we get from ucode with each received frame, * the same as HW timer counter counting down @@ -2022,6 +2072,7 @@ __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, return cpu_to_le32(res); } +EXPORT_SYMBOL(iwl_add_beacon_time); #ifdef CONFIG_PM @@ -2041,6 +2092,7 @@ int iwl_pci_suspend(struct device *device) return 0; } +EXPORT_SYMBOL(iwl_pci_suspend); int iwl_pci_resume(struct device *device) { @@ -2069,6 +2121,7 @@ int iwl_pci_resume(struct device *device) return 0; } +EXPORT_SYMBOL(iwl_pci_resume); const struct dev_pm_ops iwl_pm_ops = { .suspend = iwl_pci_suspend, @@ -2078,5 +2131,6 @@ const struct dev_pm_ops iwl_pm_ops = { .poweroff = iwl_pci_suspend, .restore = iwl_pci_resume, }; +EXPORT_SYMBOL(iwl_pm_ops); #endif /* CONFIG_PM */ diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 8842411f1cf3..bc7a965c18f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1788,6 +1788,7 @@ err: iwl_dbgfs_unregister(priv); return -ENOMEM; } +EXPORT_SYMBOL(iwl_dbgfs_register); /** * Remove the debugfs files and directories @@ -1801,6 +1802,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) debugfs_remove_recursive(priv->debugfs_dir); priv->debugfs_dir = NULL; } +EXPORT_SYMBOL(iwl_dbgfs_unregister); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 58165c769cf1..065615ee040a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -43,14 +43,14 @@ #include "iwl-prph.h" #include "iwl-fh.h" #include "iwl-debug.h" +#include "iwl-4965-hw.h" +#include "iwl-3945-hw.h" #include "iwl-agn-hw.h" #include "iwl-led.h" #include "iwl-power.h" #include "iwl-agn-rs.h" #include "iwl-agn-tt.h" -#define U32_PAD(n) ((4-(n))&0x3) - struct iwl_tx_queue; /* CT-KILL constants */ diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 833194a2c639..358cfd7e5af1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -222,6 +222,7 @@ const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) BUG_ON(offset >= priv->cfg->base_params->eeprom_size); return &priv->eeprom[offset]; } +EXPORT_SYMBOL(iwlcore_eeprom_query_addr); static int iwl_init_otp_access(struct iwl_priv *priv) { @@ -381,6 +382,7 @@ const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) { return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset); } +EXPORT_SYMBOL(iwl_eeprom_query_addr); u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset) { @@ -388,6 +390,7 @@ u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset) return 0; return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8); } +EXPORT_SYMBOL(iwl_eeprom_query16); /** * iwl_eeprom_init - read EEPROM contents @@ -506,12 +509,14 @@ err: alloc_err: return ret; } +EXPORT_SYMBOL(iwl_eeprom_init); void iwl_eeprom_free(struct iwl_priv *priv) { kfree(priv->eeprom); priv->eeprom = NULL; } +EXPORT_SYMBOL(iwl_eeprom_free); static void iwl_init_band_reference(const struct iwl_priv *priv, int eep_band, int *eeprom_ch_count, @@ -774,6 +779,7 @@ int iwl_init_channel_map(struct iwl_priv *priv) return 0; } +EXPORT_SYMBOL(iwl_init_channel_map); /* * iwl_free_channel_map - undo allocations in iwl_init_channel_map @@ -783,6 +789,7 @@ void iwl_free_channel_map(struct iwl_priv *priv) kfree(priv->channel_info); priv->channel_count = 0; } +EXPORT_SYMBOL(iwl_free_channel_map); /** * iwl_get_channel_info - Find driver's private channel info @@ -811,3 +818,4 @@ const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv, return NULL; } +EXPORT_SYMBOL(iwl_get_channel_info); diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 02499f684683..e4b953d7b7bf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -114,6 +114,7 @@ const char *get_cmd_string(u8 cmd) } } +EXPORT_SYMBOL(get_cmd_string); #define HOST_COMPLETE_TIMEOUT (HZ / 2) @@ -252,6 +253,7 @@ out: mutex_unlock(&priv->sync_cmd_mutex); return ret; } +EXPORT_SYMBOL(iwl_send_cmd_sync); int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) { @@ -260,6 +262,7 @@ int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) return iwl_send_cmd_sync(priv, cmd); } +EXPORT_SYMBOL(iwl_send_cmd); int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data) { @@ -271,6 +274,7 @@ int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data) return iwl_send_cmd_sync(priv, &cmd); } +EXPORT_SYMBOL(iwl_send_cmd_pdu); int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, const void *data, @@ -289,3 +293,4 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, return iwl_send_cmd_async(priv, &cmd); } +EXPORT_SYMBOL(iwl_send_cmd_pdu_async); diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index d7f2a0bb32c9..074ad2275228 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -175,6 +175,7 @@ void iwl_leds_init(struct iwl_priv *priv) priv->led_registered = true; } +EXPORT_SYMBOL(iwl_leds_init); void iwl_leds_exit(struct iwl_priv *priv) { @@ -184,3 +185,4 @@ void iwl_leds_exit(struct iwl_priv *priv) led_classdev_unregister(&priv->led); kfree(priv->led.name); } +EXPORT_SYMBOL(iwl_leds_exit); diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.c b/drivers/net/wireless/iwlwifi/iwl-legacy.c new file mode 100644 index 000000000000..e1ace3ce30b3 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-legacy.c @@ -0,0 +1,657 @@ +/****************************************************************************** + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ + +#include +#include + +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-helpers.h" +#include "iwl-legacy.h" + +static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +{ + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (!ctx->is_active) + return; + + ctx->qos_data.def_qos_parm.qos_flags = 0; + + if (ctx->qos_data.qos_active) + ctx->qos_data.def_qos_parm.qos_flags |= + QOS_PARAM_FLG_UPDATE_EDCA_MSK; + + if (ctx->ht.enabled) + ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; + + IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", + ctx->qos_data.qos_active, + ctx->qos_data.def_qos_parm.qos_flags); + + iwl_send_cmd_pdu_async(priv, ctx->qos_cmd, + sizeof(struct iwl_qosparam_cmd), + &ctx->qos_data.def_qos_parm, NULL); +} + +/** + * iwl_legacy_mac_config - mac80211 config callback + */ +int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed) +{ + struct iwl_priv *priv = hw->priv; + const struct iwl_channel_info *ch_info; + struct ieee80211_conf *conf = &hw->conf; + struct ieee80211_channel *channel = conf->channel; + struct iwl_ht_config *ht_conf = &priv->current_ht_config; + struct iwl_rxon_context *ctx; + unsigned long flags = 0; + int ret = 0; + u16 ch; + int scan_active = 0; + bool ht_changed[NUM_IWL_RXON_CTX] = {}; + + if (WARN_ON(!priv->cfg->ops->legacy)) + return -EOPNOTSUPP; + + mutex_lock(&priv->mutex); + + IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", + channel->hw_value, changed); + + if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) { + scan_active = 1; + IWL_DEBUG_MAC80211(priv, "scan active\n"); + } + + if (changed & (IEEE80211_CONF_CHANGE_SMPS | + IEEE80211_CONF_CHANGE_CHANNEL)) { + /* mac80211 uses static for non-HT which is what we want */ + priv->current_ht_config.smps = conf->smps_mode; + + /* + * Recalculate chain counts. + * + * If monitor mode is enabled then mac80211 will + * set up the SM PS mode to OFF if an HT channel is + * configured. + */ + if (priv->cfg->ops->hcmd->set_rxon_chain) + for_each_context(priv, ctx) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + } + + /* during scanning mac80211 will delay channel setting until + * scan finish with changed = 0 + */ + if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) { + if (scan_active) + goto set_ch_out; + + ch = channel->hw_value; + ch_info = iwl_get_channel_info(priv, channel->band, ch); + if (!is_channel_valid(ch_info)) { + IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); + ret = -EINVAL; + goto set_ch_out; + } + + spin_lock_irqsave(&priv->lock, flags); + + for_each_context(priv, ctx) { + /* Configure HT40 channels */ + if (ctx->ht.enabled != conf_is_ht(conf)) { + ctx->ht.enabled = conf_is_ht(conf); + ht_changed[ctx->ctxid] = true; + } + if (ctx->ht.enabled) { + if (conf_is_ht40_minus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_BELOW; + ctx->ht.is_40mhz = true; + } else if (conf_is_ht40_plus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + ctx->ht.is_40mhz = true; + } else { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_NONE; + ctx->ht.is_40mhz = false; + } + } else + ctx->ht.is_40mhz = false; + + /* + * Default to no protection. Protection mode will + * later be set from BSS config in iwl_ht_conf + */ + ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE; + + /* if we are switching from ht to 2.4 clear flags + * from any ht related info since 2.4 does not + * support ht */ + if ((le16_to_cpu(ctx->staging.channel) != ch)) + ctx->staging.flags = 0; + + iwl_set_rxon_channel(priv, channel, ctx); + iwl_set_rxon_ht(priv, ht_conf); + + iwl_set_flags_for_band(priv, ctx, channel->band, + ctx->vif); + } + + spin_unlock_irqrestore(&priv->lock, flags); + + if (priv->cfg->ops->legacy->update_bcast_stations) + ret = priv->cfg->ops->legacy->update_bcast_stations(priv); + + set_ch_out: + /* The list of supported rates and rate mask can be different + * for each band; since the band may have changed, reset + * the rate mask to what mac80211 lists */ + iwl_set_rate(priv); + } + + if (changed & (IEEE80211_CONF_CHANGE_PS | + IEEE80211_CONF_CHANGE_IDLE)) { + ret = iwl_power_update_mode(priv, false); + if (ret) + IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n"); + } + + if (changed & IEEE80211_CONF_CHANGE_POWER) { + IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n", + priv->tx_power_user_lmt, conf->power_level); + + iwl_set_tx_power(priv, conf->power_level, false); + } + + if (!iwl_is_ready(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); + goto out; + } + + if (scan_active) + goto out; + + for_each_context(priv, ctx) { + if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging))) + iwlcore_commit_rxon(priv, ctx); + else + IWL_DEBUG_INFO(priv, + "Not re-sending same RXON configuration.\n"); + if (ht_changed[ctx->ctxid]) + iwl_update_qos(priv, ctx); + } + +out: + IWL_DEBUG_MAC80211(priv, "leave\n"); + mutex_unlock(&priv->mutex); + return ret; +} +EXPORT_SYMBOL(iwl_legacy_mac_config); + +void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw) +{ + struct iwl_priv *priv = hw->priv; + unsigned long flags; + /* IBSS can only be the IWL_RXON_CTX_BSS context */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + if (WARN_ON(!priv->cfg->ops->legacy)) + return; + + mutex_lock(&priv->mutex); + IWL_DEBUG_MAC80211(priv, "enter\n"); + + spin_lock_irqsave(&priv->lock, flags); + memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config)); + spin_unlock_irqrestore(&priv->lock, flags); + + spin_lock_irqsave(&priv->lock, flags); + + /* new association get rid of ibss beacon skb */ + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); + + priv->beacon_skb = NULL; + + priv->timestamp = 0; + + spin_unlock_irqrestore(&priv->lock, flags); + + iwl_scan_cancel_timeout(priv, 100); + if (!iwl_is_ready_rf(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); + mutex_unlock(&priv->mutex); + return; + } + + /* we are restarting association process + * clear RXON_FILTER_ASSOC_MSK bit + */ + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); + + iwl_set_rate(priv); + + mutex_unlock(&priv->mutex); + + IWL_DEBUG_MAC80211(priv, "leave\n"); +} +EXPORT_SYMBOL(iwl_legacy_mac_reset_tsf); + +static void iwl_ht_conf(struct iwl_priv *priv, + struct ieee80211_vif *vif) +{ + struct iwl_ht_config *ht_conf = &priv->current_ht_config; + struct ieee80211_sta *sta; + struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); + + IWL_DEBUG_ASSOC(priv, "enter:\n"); + + if (!ctx->ht.enabled) + return; + + ctx->ht.protection = + bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; + ctx->ht.non_gf_sta_present = + !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); + + ht_conf->single_chain_sufficient = false; + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + rcu_read_lock(); + sta = ieee80211_find_sta(vif, bss_conf->bssid); + if (sta) { + struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + int maxstreams; + + maxstreams = (ht_cap->mcs.tx_params & + IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK) + >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; + maxstreams += 1; + + if ((ht_cap->mcs.rx_mask[1] == 0) && + (ht_cap->mcs.rx_mask[2] == 0)) + ht_conf->single_chain_sufficient = true; + if (maxstreams <= 1) + ht_conf->single_chain_sufficient = true; + } else { + /* + * If at all, this can only happen through a race + * when the AP disconnects us while we're still + * setting up the connection, in that case mac80211 + * will soon tell us about that. + */ + ht_conf->single_chain_sufficient = true; + } + rcu_read_unlock(); + break; + case NL80211_IFTYPE_ADHOC: + ht_conf->single_chain_sufficient = true; + break; + default: + break; + } + + IWL_DEBUG_ASSOC(priv, "leave\n"); +} + +static inline void iwl_set_no_assoc(struct iwl_priv *priv, + struct ieee80211_vif *vif) +{ + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); + + /* + * inform the ucode that there is no longer an + * association and that no more packets should be + * sent + */ + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + ctx->staging.assoc_id = 0; + iwlcore_commit_rxon(priv, ctx); +} + +static void iwlcore_beacon_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct iwl_priv *priv = hw->priv; + unsigned long flags; + __le64 timestamp; + struct sk_buff *skb = ieee80211_beacon_get(hw, vif); + + if (!skb) + return; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + lockdep_assert_held(&priv->mutex); + + if (!priv->beacon_ctx) { + IWL_ERR(priv, "update beacon but no beacon context!\n"); + dev_kfree_skb(skb); + return; + } + + spin_lock_irqsave(&priv->lock, flags); + + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); + + priv->beacon_skb = skb; + + timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; + priv->timestamp = le64_to_cpu(timestamp); + + IWL_DEBUG_MAC80211(priv, "leave\n"); + spin_unlock_irqrestore(&priv->lock, flags); + + if (!iwl_is_ready_rf(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); + return; + } + + priv->cfg->ops->legacy->post_associate(priv); +} + +void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changes) +{ + struct iwl_priv *priv = hw->priv; + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); + int ret; + + if (WARN_ON(!priv->cfg->ops->legacy)) + return; + + IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); + + if (!iwl_is_alive(priv)) + return; + + mutex_lock(&priv->mutex); + + if (changes & BSS_CHANGED_QOS) { + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + ctx->qos_data.qos_active = bss_conf->qos; + iwl_update_qos(priv, ctx); + spin_unlock_irqrestore(&priv->lock, flags); + } + + if (changes & BSS_CHANGED_BEACON_ENABLED) { + /* + * the add_interface code must make sure we only ever + * have a single interface that could be beaconing at + * any time. + */ + if (vif->bss_conf.enable_beacon) + priv->beacon_ctx = ctx; + else + priv->beacon_ctx = NULL; + } + + if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) { + dev_kfree_skb(priv->beacon_skb); + priv->beacon_skb = ieee80211_beacon_get(hw, vif); + } + + if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP) + iwl_send_rxon_timing(priv, ctx); + + if (changes & BSS_CHANGED_BSSID) { + IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid); + + /* + * If there is currently a HW scan going on in the + * background then we need to cancel it else the RXON + * below/in post_associate will fail. + */ + if (iwl_scan_cancel_timeout(priv, 100)) { + IWL_WARN(priv, "Aborted scan still in progress after 100ms\n"); + IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n"); + mutex_unlock(&priv->mutex); + return; + } + + /* mac80211 only sets assoc when in STATION mode */ + if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) { + memcpy(ctx->staging.bssid_addr, + bss_conf->bssid, ETH_ALEN); + + /* currently needed in a few places */ + memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); + } else { + ctx->staging.filter_flags &= + ~RXON_FILTER_ASSOC_MSK; + } + + } + + /* + * This needs to be after setting the BSSID in case + * mac80211 decides to do both changes at once because + * it will invoke post_associate. + */ + if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON) + iwlcore_beacon_update(hw, vif); + + if (changes & BSS_CHANGED_ERP_PREAMBLE) { + IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", + bss_conf->use_short_preamble); + if (bss_conf->use_short_preamble) + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + else + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + } + + if (changes & BSS_CHANGED_ERP_CTS_PROT) { + IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot); + if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) + ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK; + else + ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK; + if (bss_conf->use_cts_prot) + ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; + else + ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN; + } + + if (changes & BSS_CHANGED_BASIC_RATES) { + /* XXX use this information + * + * To do that, remove code from iwl_set_rate() and put something + * like this here: + * + if (A-band) + ctx->staging.ofdm_basic_rates = + bss_conf->basic_rates; + else + ctx->staging.ofdm_basic_rates = + bss_conf->basic_rates >> 4; + ctx->staging.cck_basic_rates = + bss_conf->basic_rates & 0xF; + */ + } + + if (changes & BSS_CHANGED_HT) { + iwl_ht_conf(priv, vif); + + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + } + + if (changes & BSS_CHANGED_ASSOC) { + IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc); + if (bss_conf->assoc) { + priv->timestamp = bss_conf->timestamp; + + if (!iwl_is_rfkill(priv)) + priv->cfg->ops->legacy->post_associate(priv); + } else + iwl_set_no_assoc(priv, vif); + } + + if (changes && iwl_is_associated_ctx(ctx) && bss_conf->aid) { + IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n", + changes); + ret = iwl_send_rxon_assoc(priv, ctx); + if (!ret) { + /* Sync active_rxon with latest change. */ + memcpy((void *)&ctx->active, + &ctx->staging, + sizeof(struct iwl_rxon_cmd)); + } + } + + if (changes & BSS_CHANGED_BEACON_ENABLED) { + if (vif->bss_conf.enable_beacon) { + memcpy(ctx->staging.bssid_addr, + bss_conf->bssid, ETH_ALEN); + memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); + priv->cfg->ops->legacy->config_ap(priv); + } else + iwl_set_no_assoc(priv, vif); + } + + if (changes & BSS_CHANGED_IBSS) { + ret = priv->cfg->ops->legacy->manage_ibss_station(priv, vif, + bss_conf->ibss_joined); + if (ret) + IWL_ERR(priv, "failed to %s IBSS station %pM\n", + bss_conf->ibss_joined ? "add" : "remove", + bss_conf->bssid); + } + + mutex_unlock(&priv->mutex); + + IWL_DEBUG_MAC80211(priv, "leave\n"); +} +EXPORT_SYMBOL(iwl_legacy_mac_bss_info_changed); + +irqreturn_t iwl_isr_legacy(int irq, void *data) +{ + struct iwl_priv *priv = data; + u32 inta, inta_mask; + u32 inta_fh; + unsigned long flags; + if (!priv) + return IRQ_NONE; + + spin_lock_irqsave(&priv->lock, flags); + + /* Disable (but don't clear!) interrupts here to avoid + * back-to-back ISRs and sporadic interrupts from our NIC. + * If we have something to service, the tasklet will re-enable ints. + * If we *don't* have something, we'll re-enable before leaving here. */ + inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */ + iwl_write32(priv, CSR_INT_MASK, 0x00000000); + + /* Discover which interrupts are active/pending */ + inta = iwl_read32(priv, CSR_INT); + inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); + + /* Ignore interrupt if there's nothing in NIC to service. + * This may be due to IRQ shared with another device, + * or due to sporadic interrupts thrown from our NIC. */ + if (!inta && !inta_fh) { + IWL_DEBUG_ISR(priv, + "Ignore interrupt, inta == 0, inta_fh == 0\n"); + goto none; + } + + if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { + /* Hardware disappeared. It might have already raised + * an interrupt */ + IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta); + goto unplugged; + } + + IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", + inta, inta_mask, inta_fh); + + inta &= ~CSR_INT_BIT_SCD; + + /* iwl_irq_tasklet() will service interrupts and re-enable them */ + if (likely(inta || inta_fh)) + tasklet_schedule(&priv->irq_tasklet); + +unplugged: + spin_unlock_irqrestore(&priv->lock, flags); + return IRQ_HANDLED; + +none: + /* re-enable interrupts here since we don't have anything to service. */ + /* only Re-enable if disabled by irq */ + if (test_bit(STATUS_INT_ENABLED, &priv->status)) + iwl_enable_interrupts(priv); + spin_unlock_irqrestore(&priv->lock, flags); + return IRQ_NONE; +} +EXPORT_SYMBOL(iwl_isr_legacy); + +/* + * iwl_legacy_tx_cmd_protection: Set rts/cts. 3945 and 4965 only share this + * function. + */ +void iwl_legacy_tx_cmd_protection(struct iwl_priv *priv, + struct ieee80211_tx_info *info, + __le16 fc, __le32 *tx_flags) +{ + if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { + *tx_flags |= TX_CMD_FLG_RTS_MSK; + *tx_flags &= ~TX_CMD_FLG_CTS_MSK; + *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; + + if (!ieee80211_is_mgmt(fc)) + return; + + switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { + case cpu_to_le16(IEEE80211_STYPE_AUTH): + case cpu_to_le16(IEEE80211_STYPE_DEAUTH): + case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ): + case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ): + *tx_flags &= ~TX_CMD_FLG_RTS_MSK; + *tx_flags |= TX_CMD_FLG_CTS_MSK; + break; + } + } else if (info->control.rates[0].flags & + IEEE80211_TX_RC_USE_CTS_PROTECT) { + *tx_flags &= ~TX_CMD_FLG_RTS_MSK; + *tx_flags |= TX_CMD_FLG_CTS_MSK; + *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; + } +} +EXPORT_SYMBOL(iwl_legacy_tx_cmd_protection); diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.h b/drivers/net/wireless/iwlwifi/iwl-legacy.h new file mode 100644 index 000000000000..9f7b2f935964 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-legacy.h @@ -0,0 +1,79 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#ifndef __iwl_legacy_h__ +#define __iwl_legacy_h__ + +/* mac80211 handlers */ +int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed); +void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw); +void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changes); +void iwl_legacy_tx_cmd_protection(struct iwl_priv *priv, + struct ieee80211_tx_info *info, + __le16 fc, __le32 *tx_flags); + +irqreturn_t iwl_isr_legacy(int irq, void *data); + +#endif /* __iwl_legacy_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 576795e2c75b..1d1bf3234d8d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -425,6 +425,7 @@ int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, return ret; } +EXPORT_SYMBOL(iwl_power_set_mode); int iwl_power_update_mode(struct iwl_priv *priv, bool force) { @@ -433,6 +434,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) iwl_power_build_cmd(priv, &cmd); return iwl_power_set_mode(priv, &cmd, force); } +EXPORT_SYMBOL(iwl_power_update_mode); /* initialize to default */ void iwl_power_initialize(struct iwl_priv *priv) @@ -446,3 +448,4 @@ void iwl_power_initialize(struct iwl_priv *priv) memset(&priv->power_data.sleep_cmd, 0, sizeof(priv->power_data.sleep_cmd)); } +EXPORT_SYMBOL(iwl_power_initialize); diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index a21f6fe10fb7..bc89393fb696 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -118,6 +118,7 @@ int iwl_rx_queue_space(const struct iwl_rx_queue *q) s = 0; return s; } +EXPORT_SYMBOL(iwl_rx_queue_space); /** * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue @@ -169,6 +170,7 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q exit_unlock: spin_unlock_irqrestore(&q->lock, flags); } +EXPORT_SYMBOL(iwl_rx_queue_update_write_ptr); int iwl_rx_queue_alloc(struct iwl_priv *priv) { @@ -209,6 +211,7 @@ err_rb: err_bd: return -ENOMEM; } +EXPORT_SYMBOL(iwl_rx_queue_alloc); void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, @@ -226,6 +229,7 @@ void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, memcpy(&priv->measure_report, report, sizeof(*report)); priv->measurement_status |= MEASUREMENT_READY; } +EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif); void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt) @@ -245,6 +249,7 @@ void iwl_recover_from_statistics(struct iwl_priv *priv, !priv->cfg->ops->lib->check_plcp_health(priv, pkt)) iwl_force_reset(priv, IWL_RF_RESET, false); } +EXPORT_SYMBOL(iwl_recover_from_statistics); /* * returns non-zero if packet should be dropped @@ -297,3 +302,4 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv, } return 0; } +EXPORT_SYMBOL(iwl_set_decrypted_flag); diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index faa6d34cb658..08f1bea8b652 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -155,6 +155,7 @@ int iwl_scan_cancel(struct iwl_priv *priv) queue_work(priv->workqueue, &priv->abort_scan); return 0; } +EXPORT_SYMBOL(iwl_scan_cancel); /** * iwl_scan_cancel_timeout - Cancel any currently executing HW scan @@ -179,6 +180,7 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) return test_bit(STATUS_SCAN_HW, &priv->status); } +EXPORT_SYMBOL(iwl_scan_cancel_timeout); /* Service response to REPLY_SCAN_CMD (0x80) */ static void iwl_rx_reply_scan(struct iwl_priv *priv, @@ -286,6 +288,7 @@ void iwl_setup_rx_scan_handlers(struct iwl_priv *priv) priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] = iwl_rx_scan_complete_notif; } +EXPORT_SYMBOL(iwl_setup_rx_scan_handlers); inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, enum ieee80211_band band, @@ -298,6 +301,7 @@ inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, return IWL_ACTIVE_DWELL_TIME_24 + IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1); } +EXPORT_SYMBOL(iwl_get_active_dwell_time); u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, enum ieee80211_band band, @@ -329,6 +333,7 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, return passive; } +EXPORT_SYMBOL(iwl_get_passive_dwell_time); void iwl_init_scan_params(struct iwl_priv *priv) { @@ -338,6 +343,7 @@ void iwl_init_scan_params(struct iwl_priv *priv) if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ]) priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = ant_idx; } +EXPORT_SYMBOL(iwl_init_scan_params); static int __must_check iwl_scan_initiate(struct iwl_priv *priv, struct ieee80211_vif *vif, @@ -433,6 +439,7 @@ out_unlock: return ret; } +EXPORT_SYMBOL(iwl_mac_hw_scan); /* * internal short scan, this function should only been called while associated. @@ -529,6 +536,7 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, return (u16)len; } +EXPORT_SYMBOL(iwl_fill_probe_req); static void iwl_bg_abort_scan(struct work_struct *work) { @@ -613,6 +621,7 @@ void iwl_setup_scan_deferred_work(struct iwl_priv *priv) INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan); INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check); } +EXPORT_SYMBOL(iwl_setup_scan_deferred_work); void iwl_cancel_scan_deferred_work(struct iwl_priv *priv) { @@ -626,3 +635,4 @@ void iwl_cancel_scan_deferred_work(struct iwl_priv *priv) mutex_unlock(&priv->mutex); } } +EXPORT_SYMBOL(iwl_cancel_scan_deferred_work); diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index bc90a12408a3..49493d176515 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -169,6 +169,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, return ret; } +EXPORT_SYMBOL(iwl_send_add_sta); static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, struct ieee80211_sta *sta, @@ -315,6 +316,7 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, return sta_id; } +EXPORT_SYMBOL_GPL(iwl_prep_station); #define STA_WAIT_TIMEOUT (HZ/2) @@ -377,6 +379,7 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, *sta_id_r = sta_id; return ret; } +EXPORT_SYMBOL(iwl_add_station_common); /** * iwl_sta_ucode_deactivate - deactivate ucode status for a station @@ -510,6 +513,7 @@ out_err: spin_unlock_irqrestore(&priv->sta_lock, flags); return -EINVAL; } +EXPORT_SYMBOL_GPL(iwl_remove_station); /** * iwl_clear_ucode_stations - clear ucode station table bits @@ -544,6 +548,7 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv, if (!cleared) IWL_DEBUG_INFO(priv, "No active stations found to be cleared\n"); } +EXPORT_SYMBOL(iwl_clear_ucode_stations); /** * iwl_restore_stations() - Restore driver known stations to device @@ -620,6 +625,7 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) else IWL_DEBUG_INFO(priv, "Restoring all known stations .... complete.\n"); } +EXPORT_SYMBOL(iwl_restore_stations); void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { @@ -662,6 +668,7 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) priv->stations[sta_id].sta.sta.addr, ret); iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true); } +EXPORT_SYMBOL(iwl_reprogram_ap_sta); int iwl_get_free_ucode_key_index(struct iwl_priv *priv) { @@ -673,6 +680,7 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv) return WEP_INVALID_OFFSET; } +EXPORT_SYMBOL(iwl_get_free_ucode_key_index); void iwl_dealloc_bcast_stations(struct iwl_priv *priv) { @@ -692,6 +700,7 @@ void iwl_dealloc_bcast_stations(struct iwl_priv *priv) } spin_unlock_irqrestore(&priv->sta_lock, flags); } +EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_stations); #ifdef CONFIG_IWLWIFI_DEBUG static void iwl_dump_lq_cmd(struct iwl_priv *priv, @@ -801,6 +810,7 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, } return ret; } +EXPORT_SYMBOL(iwl_send_lq_cmd); int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -822,3 +832,4 @@ int iwl_mac_sta_remove(struct ieee80211_hw *hw, mutex_unlock(&priv->mutex); return ret; } +EXPORT_SYMBOL(iwl_mac_sta_remove); diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 7e607d39da1c..073b6ce6141c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -84,6 +84,7 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) } txq->need_update = 0; } +EXPORT_SYMBOL(iwl_txq_update_write_ptr); /** * iwl_tx_queue_free - Deallocate DMA queue. @@ -130,6 +131,7 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) /* 0-fill queue descriptor structure */ memset(txq, 0, sizeof(*txq)); } +EXPORT_SYMBOL(iwl_tx_queue_free); /** * iwl_cmd_queue_free - Deallocate DMA queue. @@ -191,6 +193,7 @@ void iwl_cmd_queue_free(struct iwl_priv *priv) /* 0-fill queue descriptor structure */ memset(txq, 0, sizeof(*txq)); } +EXPORT_SYMBOL(iwl_cmd_queue_free); /*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** * DMA services @@ -230,6 +233,7 @@ int iwl_queue_space(const struct iwl_queue *q) s = 0; return s; } +EXPORT_SYMBOL(iwl_queue_space); /** @@ -380,6 +384,7 @@ out_free_arrays: return -ENOMEM; } +EXPORT_SYMBOL(iwl_tx_queue_init); void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, int slots_num, u32 txq_id) @@ -399,6 +404,7 @@ void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, /* Tell device where to find queue */ priv->cfg->ops->lib->txq_init(priv, txq); } +EXPORT_SYMBOL(iwl_tx_queue_reset); /*************** HOST COMMAND QUEUE FUNCTIONS *****/ @@ -635,3 +641,4 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) } meta->flags = 0; } +EXPORT_SYMBOL(iwl_tx_cmd_complete); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c new file mode 100644 index 000000000000..adcef735180a --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -0,0 +1,4334 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define DRV_NAME "iwl3945" + +#include "iwl-fh.h" +#include "iwl-3945-fh.h" +#include "iwl-commands.h" +#include "iwl-sta.h" +#include "iwl-3945.h" +#include "iwl-core.h" +#include "iwl-helpers.h" +#include "iwl-dev.h" +#include "iwl-spectrum.h" +#include "iwl-legacy.h" + +/* + * module name, copyright, version, etc. + */ + +#define DRV_DESCRIPTION \ +"Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux" + +#ifdef CONFIG_IWLWIFI_DEBUG +#define VD "d" +#else +#define VD +#endif + +/* + * add "s" to indicate spectrum measurement included. + * we add it here to be consistent with previous releases in which + * this was configurable. + */ +#define DRV_VERSION IWLWIFI_VERSION VD "s" +#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation" +#define DRV_AUTHOR "" + +MODULE_DESCRIPTION(DRV_DESCRIPTION); +MODULE_VERSION(DRV_VERSION); +MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); +MODULE_LICENSE("GPL"); + + /* module parameters */ +struct iwl_mod_params iwl3945_mod_params = { + .sw_crypto = 1, + .restart_fw = 1, + /* the rest are 0 by default */ +}; + +/** + * iwl3945_get_antenna_flags - Get antenna flags for RXON command + * @priv: eeprom and antenna fields are used to determine antenna flags + * + * priv->eeprom39 is used to determine if antenna AUX/MAIN are reversed + * iwl3945_mod_params.antenna specifies the antenna diversity mode: + * + * IWL_ANTENNA_DIVERSITY - NIC selects best antenna by itself + * IWL_ANTENNA_MAIN - Force MAIN antenna + * IWL_ANTENNA_AUX - Force AUX antenna + */ +__le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv) +{ + struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; + + switch (iwl3945_mod_params.antenna) { + case IWL_ANTENNA_DIVERSITY: + return 0; + + case IWL_ANTENNA_MAIN: + if (eeprom->antenna_switch_type) + return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK; + return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK; + + case IWL_ANTENNA_AUX: + if (eeprom->antenna_switch_type) + return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK; + return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK; + } + + /* bad antenna selector value */ + IWL_ERR(priv, "Bad antenna selector value (0x%x)\n", + iwl3945_mod_params.antenna); + + return 0; /* "diversity" is default if error */ +} + +static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + unsigned long flags; + __le16 key_flags = 0; + int ret; + + key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); + key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); + + if (sta_id == priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id) + key_flags |= STA_KEY_MULTICAST_MSK; + + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + keyconf->hw_key_idx = keyconf->keyidx; + key_flags &= ~STA_KEY_FLG_INVALID; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; + priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; + memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, + keyconf->keylen); + + memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, + keyconf->keylen); + + if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) + == STA_KEY_FLG_NO_ENC) + priv->stations[sta_id].sta.key.key_offset = + iwl_get_free_ucode_key_index(priv); + /* else, we are overriding an existing key => no need to allocated room + * in uCode. */ + + WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, + "no space for a new key"); + + priv->stations[sta_id].sta.key.key_flags = key_flags; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + + IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n"); + + ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); + + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return ret; +} + +static int iwl3945_set_tkip_dynamic_key_info(struct iwl_priv *priv, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + return -EOPNOTSUPP; +} + +static int iwl3945_set_wep_dynamic_key_info(struct iwl_priv *priv, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + return -EOPNOTSUPP; +} + +static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) +{ + unsigned long flags; + struct iwl_addsta_cmd sta_cmd; + + spin_lock_irqsave(&priv->sta_lock, flags); + memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key)); + memset(&priv->stations[sta_id].sta.key, 0, + sizeof(struct iwl4965_keyinfo)); + priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n"); + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +static int iwl3945_set_dynamic_key(struct iwl_priv *priv, + struct ieee80211_key_conf *keyconf, u8 sta_id) +{ + int ret = 0; + + keyconf->hw_key_idx = HW_KEY_DYNAMIC; + + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_CCMP: + ret = iwl3945_set_ccmp_dynamic_key_info(priv, keyconf, sta_id); + break; + case WLAN_CIPHER_SUITE_TKIP: + ret = iwl3945_set_tkip_dynamic_key_info(priv, keyconf, sta_id); + break; + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + ret = iwl3945_set_wep_dynamic_key_info(priv, keyconf, sta_id); + break; + default: + IWL_ERR(priv, "Unknown alg: %s alg=%x\n", __func__, + keyconf->cipher); + ret = -EINVAL; + } + + IWL_DEBUG_WEP(priv, "Set dynamic key: alg=%x len=%d idx=%d sta=%d ret=%d\n", + keyconf->cipher, keyconf->keylen, keyconf->keyidx, + sta_id, ret); + + return ret; +} + +static int iwl3945_remove_static_key(struct iwl_priv *priv) +{ + int ret = -EOPNOTSUPP; + + return ret; +} + +static int iwl3945_set_static_key(struct iwl_priv *priv, + struct ieee80211_key_conf *key) +{ + if (key->cipher == WLAN_CIPHER_SUITE_WEP40 || + key->cipher == WLAN_CIPHER_SUITE_WEP104) + return -EOPNOTSUPP; + + IWL_ERR(priv, "Static key invalid: cipher %x\n", key->cipher); + return -EINVAL; +} + +static void iwl3945_clear_free_frames(struct iwl_priv *priv) +{ + struct list_head *element; + + IWL_DEBUG_INFO(priv, "%d frames on pre-allocated heap on clear.\n", + priv->frames_count); + + while (!list_empty(&priv->free_frames)) { + element = priv->free_frames.next; + list_del(element); + kfree(list_entry(element, struct iwl3945_frame, list)); + priv->frames_count--; + } + + if (priv->frames_count) { + IWL_WARN(priv, "%d frames still in use. Did we lose one?\n", + priv->frames_count); + priv->frames_count = 0; + } +} + +static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl_priv *priv) +{ + struct iwl3945_frame *frame; + struct list_head *element; + if (list_empty(&priv->free_frames)) { + frame = kzalloc(sizeof(*frame), GFP_KERNEL); + if (!frame) { + IWL_ERR(priv, "Could not allocate frame!\n"); + return NULL; + } + + priv->frames_count++; + return frame; + } + + element = priv->free_frames.next; + list_del(element); + return list_entry(element, struct iwl3945_frame, list); +} + +static void iwl3945_free_frame(struct iwl_priv *priv, struct iwl3945_frame *frame) +{ + memset(frame, 0, sizeof(*frame)); + list_add(&frame->list, &priv->free_frames); +} + +unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, + struct ieee80211_hdr *hdr, + int left) +{ + + if (!iwl_is_associated(priv, IWL_RXON_CTX_BSS) || !priv->beacon_skb) + return 0; + + if (priv->beacon_skb->len > left) + return 0; + + memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len); + + return priv->beacon_skb->len; +} + +static int iwl3945_send_beacon_cmd(struct iwl_priv *priv) +{ + struct iwl3945_frame *frame; + unsigned int frame_size; + int rc; + u8 rate; + + frame = iwl3945_get_free_frame(priv); + + if (!frame) { + IWL_ERR(priv, "Could not obtain free frame buffer for beacon " + "command.\n"); + return -ENOMEM; + } + + rate = iwl_rate_get_lowest_plcp(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); + + frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate); + + rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, + &frame->u.cmd[0]); + + iwl3945_free_frame(priv, frame); + + return rc; +} + +static void iwl3945_unset_hw_params(struct iwl_priv *priv) +{ + if (priv->_3945.shared_virt) + dma_free_coherent(&priv->pci_dev->dev, + sizeof(struct iwl3945_shared), + priv->_3945.shared_virt, + priv->_3945.shared_phys); +} + +static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, + struct ieee80211_tx_info *info, + struct iwl_device_cmd *cmd, + struct sk_buff *skb_frag, + int sta_id) +{ + struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload; + struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo; + + tx_cmd->sec_ctl = 0; + + switch (keyinfo->cipher) { + case WLAN_CIPHER_SUITE_CCMP: + tx_cmd->sec_ctl = TX_CMD_SEC_CCM; + memcpy(tx_cmd->key, keyinfo->key, keyinfo->keylen); + IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n"); + break; + + case WLAN_CIPHER_SUITE_TKIP: + break; + + case WLAN_CIPHER_SUITE_WEP104: + tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128; + /* fall through */ + case WLAN_CIPHER_SUITE_WEP40: + tx_cmd->sec_ctl |= TX_CMD_SEC_WEP | + (info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT; + + memcpy(&tx_cmd->key[3], keyinfo->key, keyinfo->keylen); + + IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption " + "with key %d\n", info->control.hw_key->hw_key_idx); + break; + + default: + IWL_ERR(priv, "Unknown encode cipher %x\n", keyinfo->cipher); + break; + } +} + +/* + * handle build REPLY_TX command notification. + */ +static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv, + struct iwl_device_cmd *cmd, + struct ieee80211_tx_info *info, + struct ieee80211_hdr *hdr, u8 std_id) +{ + struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload; + __le32 tx_flags = tx_cmd->tx_flags; + __le16 fc = hdr->frame_control; + + tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { + tx_flags |= TX_CMD_FLG_ACK_MSK; + if (ieee80211_is_mgmt(fc)) + tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; + if (ieee80211_is_probe_resp(fc) && + !(le16_to_cpu(hdr->seq_ctrl) & 0xf)) + tx_flags |= TX_CMD_FLG_TSF_MSK; + } else { + tx_flags &= (~TX_CMD_FLG_ACK_MSK); + tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; + } + + tx_cmd->sta_id = std_id; + if (ieee80211_has_morefrags(fc)) + tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; + + if (ieee80211_is_data_qos(fc)) { + u8 *qc = ieee80211_get_qos_ctl(hdr); + tx_cmd->tid_tspec = qc[0] & 0xf; + tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; + } else { + tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; + } + + priv->cfg->ops->utils->tx_cmd_protection(priv, info, fc, &tx_flags); + + tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); + if (ieee80211_is_mgmt(fc)) { + if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc)) + tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3); + else + tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2); + } else { + tx_cmd->timeout.pm_frame_timeout = 0; + } + + tx_cmd->driver_txop = 0; + tx_cmd->tx_flags = tx_flags; + tx_cmd->next_frame_len = 0; +} + +/* + * start REPLY_TX command process + */ +static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct iwl3945_tx_cmd *tx_cmd; + struct iwl_tx_queue *txq = NULL; + struct iwl_queue *q = NULL; + struct iwl_device_cmd *out_cmd; + struct iwl_cmd_meta *out_meta; + dma_addr_t phys_addr; + dma_addr_t txcmd_phys; + int txq_id = skb_get_queue_mapping(skb); + u16 len, idx, hdr_len; + u8 id; + u8 unicast; + u8 sta_id; + u8 tid = 0; + __le16 fc; + u8 wait_write_ptr = 0; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + if (iwl_is_rfkill(priv)) { + IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n"); + goto drop_unlock; + } + + if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) { + IWL_ERR(priv, "ERROR: No TX rate available.\n"); + goto drop_unlock; + } + + unicast = !is_multicast_ether_addr(hdr->addr1); + id = 0; + + fc = hdr->frame_control; + +#ifdef CONFIG_IWLWIFI_DEBUG + if (ieee80211_is_auth(fc)) + IWL_DEBUG_TX(priv, "Sending AUTH frame\n"); + else if (ieee80211_is_assoc_req(fc)) + IWL_DEBUG_TX(priv, "Sending ASSOC frame\n"); + else if (ieee80211_is_reassoc_req(fc)) + IWL_DEBUG_TX(priv, "Sending REASSOC frame\n"); +#endif + + spin_unlock_irqrestore(&priv->lock, flags); + + hdr_len = ieee80211_hdrlen(fc); + + /* Find index into station table for destination station */ + sta_id = iwl_sta_id_or_broadcast( + priv, &priv->contexts[IWL_RXON_CTX_BSS], + info->control.sta); + if (sta_id == IWL_INVALID_STATION) { + IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", + hdr->addr1); + goto drop; + } + + IWL_DEBUG_RATE(priv, "station Id %d\n", sta_id); + + if (ieee80211_is_data_qos(fc)) { + u8 *qc = ieee80211_get_qos_ctl(hdr); + tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; + if (unlikely(tid >= MAX_TID_COUNT)) + goto drop; + } + + /* Descriptor for chosen Tx queue */ + txq = &priv->txq[txq_id]; + q = &txq->q; + + if ((iwl_queue_space(q) < q->high_mark)) + goto drop; + + spin_lock_irqsave(&priv->lock, flags); + + idx = get_cmd_index(q, q->write_ptr, 0); + + /* Set up driver data for this TFD */ + memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); + txq->txb[q->write_ptr].skb = skb; + txq->txb[q->write_ptr].ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + /* Init first empty entry in queue's array of Tx/cmd buffers */ + out_cmd = txq->cmd[idx]; + out_meta = &txq->meta[idx]; + tx_cmd = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload; + memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); + memset(tx_cmd, 0, sizeof(*tx_cmd)); + + /* + * Set up the Tx-command (not MAC!) header. + * Store the chosen Tx queue and TFD index within the sequence field; + * after Tx, uCode's Tx response will return this value so driver can + * locate the frame within the tx queue and do post-tx processing. + */ + out_cmd->hdr.cmd = REPLY_TX; + out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | + INDEX_TO_SEQ(q->write_ptr))); + + /* Copy MAC header from skb into command buffer */ + memcpy(tx_cmd->hdr, hdr, hdr_len); + + + if (info->control.hw_key) + iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, sta_id); + + /* TODO need this for burst mode later on */ + iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, sta_id); + + /* set is_hcca to 0; it probably will never be implemented */ + iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0); + + /* Total # bytes to be transmitted */ + len = (u16)skb->len; + tx_cmd->len = cpu_to_le16(len); + + iwl_dbg_log_tx_data_frame(priv, len, hdr); + iwl_update_stats(priv, true, fc, len); + tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; + tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; + + if (!ieee80211_has_morefrags(hdr->frame_control)) { + txq->need_update = 1; + } else { + wait_write_ptr = 1; + txq->need_update = 0; + } + + IWL_DEBUG_TX(priv, "sequence nr = 0X%x\n", + le16_to_cpu(out_cmd->hdr.sequence)); + IWL_DEBUG_TX(priv, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); + iwl_print_hex_dump(priv, IWL_DL_TX, tx_cmd, sizeof(*tx_cmd)); + iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, + ieee80211_hdrlen(fc)); + + /* + * Use the first empty entry in this queue's command buffer array + * to contain the Tx command and MAC header concatenated together + * (payload data will be in another buffer). + * Size of this varies, due to varying MAC header length. + * If end is not dword aligned, we'll have 2 extra bytes at the end + * of the MAC header (device reads on dword boundaries). + * We'll tell device about this padding later. + */ + len = sizeof(struct iwl3945_tx_cmd) + + sizeof(struct iwl_cmd_header) + hdr_len; + len = (len + 3) & ~3; + + /* Physical address of this Tx command's header (not MAC header!), + * within command buffer array. */ + txcmd_phys = pci_map_single(priv->pci_dev, &out_cmd->hdr, + len, PCI_DMA_TODEVICE); + /* we do not map meta data ... so we can safely access address to + * provide to unmap command*/ + dma_unmap_addr_set(out_meta, mapping, txcmd_phys); + dma_unmap_len_set(out_meta, len, len); + + /* Add buffer containing Tx command and MAC(!) header to TFD's + * first entry */ + priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, + txcmd_phys, len, 1, 0); + + + /* Set up TFD's 2nd entry to point directly to remainder of skb, + * if any (802.11 null frames have no payload). */ + len = skb->len - hdr_len; + if (len) { + phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, + len, PCI_DMA_TODEVICE); + priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, + phys_addr, len, + 0, U32_PAD(len)); + } + + + /* Tell device the write index *just past* this latest filled TFD */ + q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); + iwl_txq_update_write_ptr(priv, txq); + spin_unlock_irqrestore(&priv->lock, flags); + + if ((iwl_queue_space(q) < q->high_mark) + && priv->mac80211_registered) { + if (wait_write_ptr) { + spin_lock_irqsave(&priv->lock, flags); + txq->need_update = 1; + iwl_txq_update_write_ptr(priv, txq); + spin_unlock_irqrestore(&priv->lock, flags); + } + + iwl_stop_queue(priv, txq); + } + + return 0; + +drop_unlock: + spin_unlock_irqrestore(&priv->lock, flags); +drop: + return -1; +} + +static int iwl3945_get_measurement(struct iwl_priv *priv, + struct ieee80211_measurement_params *params, + u8 type) +{ + struct iwl_spectrum_cmd spectrum; + struct iwl_rx_packet *pkt; + struct iwl_host_cmd cmd = { + .id = REPLY_SPECTRUM_MEASUREMENT_CMD, + .data = (void *)&spectrum, + .flags = CMD_WANT_SKB, + }; + u32 add_time = le64_to_cpu(params->start_time); + int rc; + int spectrum_resp_status; + int duration = le16_to_cpu(params->duration); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) + add_time = iwl_usecs_to_beacons(priv, + le64_to_cpu(params->start_time) - priv->_3945.last_tsf, + le16_to_cpu(ctx->timing.beacon_interval)); + + memset(&spectrum, 0, sizeof(spectrum)); + + spectrum.channel_count = cpu_to_le16(1); + spectrum.flags = + RXON_FLG_TSF2HOST_MSK | RXON_FLG_ANT_A_MSK | RXON_FLG_DIS_DIV_MSK; + spectrum.filter_flags = MEASUREMENT_FILTER_FLAG; + cmd.len = sizeof(spectrum); + spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len)); + + if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) + spectrum.start_time = + iwl_add_beacon_time(priv, + priv->_3945.last_beacon_time, add_time, + le16_to_cpu(ctx->timing.beacon_interval)); + else + spectrum.start_time = 0; + + spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT); + spectrum.channels[0].channel = params->channel; + spectrum.channels[0].type = type; + if (ctx->active.flags & RXON_FLG_BAND_24G_MSK) + spectrum.flags |= RXON_FLG_BAND_24G_MSK | + RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK; + + rc = iwl_send_cmd_sync(priv, &cmd); + if (rc) + return rc; + + pkt = (struct iwl_rx_packet *)cmd.reply_page; + if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { + IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n"); + rc = -EIO; + } + + spectrum_resp_status = le16_to_cpu(pkt->u.spectrum.status); + switch (spectrum_resp_status) { + case 0: /* Command will be handled */ + if (pkt->u.spectrum.id != 0xff) { + IWL_DEBUG_INFO(priv, "Replaced existing measurement: %d\n", + pkt->u.spectrum.id); + priv->measurement_status &= ~MEASUREMENT_READY; + } + priv->measurement_status |= MEASUREMENT_ACTIVE; + rc = 0; + break; + + case 1: /* Command will not be handled */ + rc = -EAGAIN; + break; + } + + iwl_free_pages(priv, cmd.reply_page); + + return rc; +} + +static void iwl3945_rx_reply_alive(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_alive_resp *palive; + struct delayed_work *pwork; + + palive = &pkt->u.alive_frame; + + IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision " + "0x%01X 0x%01X\n", + palive->is_valid, palive->ver_type, + palive->ver_subtype); + + if (palive->ver_subtype == INITIALIZE_SUBTYPE) { + IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); + memcpy(&priv->card_alive_init, &pkt->u.alive_frame, + sizeof(struct iwl_alive_resp)); + pwork = &priv->init_alive_start; + } else { + IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); + memcpy(&priv->card_alive, &pkt->u.alive_frame, + sizeof(struct iwl_alive_resp)); + pwork = &priv->alive_start; + iwl3945_disable_events(priv); + } + + /* We delay the ALIVE response by 5ms to + * give the HW RF Kill time to activate... */ + if (palive->is_valid == UCODE_VALID_OK) + queue_delayed_work(priv->workqueue, pwork, + msecs_to_jiffies(5)); + else + IWL_WARN(priv, "uCode did not respond OK.\n"); +} + +static void iwl3945_rx_reply_add_sta(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ +#ifdef CONFIG_IWLWIFI_DEBUG + struct iwl_rx_packet *pkt = rxb_addr(rxb); +#endif + + IWL_DEBUG_RX(priv, "Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status); +} + +static void iwl3945_bg_beacon_update(struct work_struct *work) +{ + struct iwl_priv *priv = + container_of(work, struct iwl_priv, beacon_update); + struct sk_buff *beacon; + + /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ + beacon = ieee80211_beacon_get(priv->hw, + priv->contexts[IWL_RXON_CTX_BSS].vif); + + if (!beacon) { + IWL_ERR(priv, "update beacon failed\n"); + return; + } + + mutex_lock(&priv->mutex); + /* new beacon skb is allocated every time; dispose previous.*/ + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); + + priv->beacon_skb = beacon; + mutex_unlock(&priv->mutex); + + iwl3945_send_beacon_cmd(priv); +} + +static void iwl3945_rx_beacon_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status); +#ifdef CONFIG_IWLWIFI_DEBUG + u8 rate = beacon->beacon_notify_hdr.rate; + + IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d " + "tsf %d %d rate %d\n", + le32_to_cpu(beacon->beacon_notify_hdr.status) & TX_STATUS_MSK, + beacon->beacon_notify_hdr.failure_frame, + le32_to_cpu(beacon->ibss_mgr_status), + le32_to_cpu(beacon->high_tsf), + le32_to_cpu(beacon->low_tsf), rate); +#endif + + priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); + + if ((priv->iw_mode == NL80211_IFTYPE_AP) && + (!test_bit(STATUS_EXIT_PENDING, &priv->status))) + queue_work(priv->workqueue, &priv->beacon_update); +} + +/* Handle notification from uCode that card's power state is changing + * due to software, hardware, or critical temperature RFKILL */ +static void iwl3945_rx_card_state_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); + unsigned long status = priv->status; + + IWL_WARN(priv, "Card state received: HW:%s SW:%s\n", + (flags & HW_CARD_DISABLED) ? "Kill" : "On", + (flags & SW_CARD_DISABLED) ? "Kill" : "On"); + + iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, + CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); + + if (flags & HW_CARD_DISABLED) + set_bit(STATUS_RF_KILL_HW, &priv->status); + else + clear_bit(STATUS_RF_KILL_HW, &priv->status); + + + iwl_scan_cancel(priv); + + if ((test_bit(STATUS_RF_KILL_HW, &status) != + test_bit(STATUS_RF_KILL_HW, &priv->status))) + wiphy_rfkill_set_hw_state(priv->hw->wiphy, + test_bit(STATUS_RF_KILL_HW, &priv->status)); + else + wake_up_interruptible(&priv->wait_command_queue); +} + +/** + * iwl3945_setup_rx_handlers - Initialize Rx handler callbacks + * + * Setup the RX handlers for each of the reply types sent from the uCode + * to the host. + * + * This function chains into the hardware specific files for them to setup + * any hardware specific handlers as well. + */ +static void iwl3945_setup_rx_handlers(struct iwl_priv *priv) +{ + priv->rx_handlers[REPLY_ALIVE] = iwl3945_rx_reply_alive; + priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta; + priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; + priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; + priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] = + iwl_rx_spectrum_measure_notif; + priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; + priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = + iwl_rx_pm_debug_statistics_notif; + priv->rx_handlers[BEACON_NOTIFICATION] = iwl3945_rx_beacon_notif; + + /* + * The same handler is used for both the REPLY to a discrete + * statistics request from the host as well as for the periodic + * statistics notifications (after received beacons) from the uCode. + */ + priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_reply_statistics; + priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics; + + iwl_setup_rx_scan_handlers(priv); + priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif; + + /* Set up hardware specific Rx handlers */ + iwl3945_hw_rx_handler_setup(priv); +} + +/************************** RX-FUNCTIONS ****************************/ +/* + * Rx theory of operation + * + * The host allocates 32 DMA target addresses and passes the host address + * to the firmware at register IWL_RFDS_TABLE_LOWER + N * RFD_SIZE where N is + * 0 to 31 + * + * Rx Queue Indexes + * The host/firmware share two index registers for managing the Rx buffers. + * + * The READ index maps to the first position that the firmware may be writing + * to -- the driver can read up to (but not including) this position and get + * good data. + * The READ index is managed by the firmware once the card is enabled. + * + * The WRITE index maps to the last position the driver has read from -- the + * position preceding WRITE is the last slot the firmware can place a packet. + * + * The queue is empty (no good data) if WRITE = READ - 1, and is full if + * WRITE = READ. + * + * During initialization, the host sets up the READ queue position to the first + * INDEX position, and WRITE to the last (READ - 1 wrapped) + * + * When the firmware places a packet in a buffer, it will advance the READ index + * and fire the RX interrupt. The driver can then query the READ index and + * process as many packets as possible, moving the WRITE index forward as it + * resets the Rx queue buffers with new memory. + * + * The management in the driver is as follows: + * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When + * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled + * to replenish the iwl->rxq->rx_free. + * + In iwl3945_rx_replenish (scheduled) if 'processed' != 'read' then the + * iwl->rxq is replenished and the READ INDEX is updated (updating the + * 'processed' and 'read' driver indexes as well) + * + A received packet is processed and handed to the kernel network stack, + * detached from the iwl->rxq. The driver 'processed' index is updated. + * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free + * list. If there are no allocated buffers in iwl->rxq->rx_free, the READ + * INDEX is not incremented and iwl->status(RX_STALLED) is set. If there + * were enough free buffers and RX_STALLED is set it is cleared. + * + * + * Driver sequence: + * + * iwl3945_rx_replenish() Replenishes rx_free list from rx_used, and calls + * iwl3945_rx_queue_restock + * iwl3945_rx_queue_restock() Moves available buffers from rx_free into Rx + * queue, updates firmware pointers, and updates + * the WRITE index. If insufficient rx_free buffers + * are available, schedules iwl3945_rx_replenish + * + * -- enable interrupts -- + * ISR - iwl3945_rx() Detach iwl_rx_mem_buffers from pool up to the + * READ INDEX, detaching the SKB from the pool. + * Moves the packet buffer from queue to rx_used. + * Calls iwl3945_rx_queue_restock to refill any empty + * slots. + * ... + * + */ + +/** + * iwl3945_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr + */ +static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl_priv *priv, + dma_addr_t dma_addr) +{ + return cpu_to_le32((u32)dma_addr); +} + +/** + * iwl3945_rx_queue_restock - refill RX queue from pre-allocated pool + * + * If there are slots in the RX queue that need to be restocked, + * and we have free pre-allocated buffers, fill the ranks as much + * as we can, pulling from rx_free. + * + * This moves the 'write' index forward to catch up with 'processed', and + * also updates the memory address in the firmware to reference the new + * target buffer. + */ +static void iwl3945_rx_queue_restock(struct iwl_priv *priv) +{ + struct iwl_rx_queue *rxq = &priv->rxq; + struct list_head *element; + struct iwl_rx_mem_buffer *rxb; + unsigned long flags; + int write; + + spin_lock_irqsave(&rxq->lock, flags); + write = rxq->write & ~0x7; + while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) { + /* Get next free Rx buffer, remove from free list */ + element = rxq->rx_free.next; + rxb = list_entry(element, struct iwl_rx_mem_buffer, list); + list_del(element); + + /* Point to Rx buffer via next RBD in circular buffer */ + rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->page_dma); + rxq->queue[rxq->write] = rxb; + rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; + rxq->free_count--; + } + spin_unlock_irqrestore(&rxq->lock, flags); + /* If the pre-allocated buffer pool is dropping low, schedule to + * refill it */ + if (rxq->free_count <= RX_LOW_WATERMARK) + queue_work(priv->workqueue, &priv->rx_replenish); + + + /* If we've added more space for the firmware to place data, tell it. + * Increment device's write pointer in multiples of 8. */ + if ((rxq->write_actual != (rxq->write & ~0x7)) + || (abs(rxq->write - rxq->read) > 7)) { + spin_lock_irqsave(&rxq->lock, flags); + rxq->need_update = 1; + spin_unlock_irqrestore(&rxq->lock, flags); + iwl_rx_queue_update_write_ptr(priv, rxq); + } +} + +/** + * iwl3945_rx_replenish - Move all used packet from rx_used to rx_free + * + * When moving to rx_free an SKB is allocated for the slot. + * + * Also restock the Rx queue via iwl3945_rx_queue_restock. + * This is called as a scheduled work item (except for during initialization) + */ +static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority) +{ + struct iwl_rx_queue *rxq = &priv->rxq; + struct list_head *element; + struct iwl_rx_mem_buffer *rxb; + struct page *page; + unsigned long flags; + gfp_t gfp_mask = priority; + + while (1) { + spin_lock_irqsave(&rxq->lock, flags); + + if (list_empty(&rxq->rx_used)) { + spin_unlock_irqrestore(&rxq->lock, flags); + return; + } + spin_unlock_irqrestore(&rxq->lock, flags); + + if (rxq->free_count > RX_LOW_WATERMARK) + gfp_mask |= __GFP_NOWARN; + + if (priv->hw_params.rx_page_order > 0) + gfp_mask |= __GFP_COMP; + + /* Alloc a new receive buffer */ + page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order); + if (!page) { + if (net_ratelimit()) + IWL_DEBUG_INFO(priv, "Failed to allocate SKB buffer.\n"); + if ((rxq->free_count <= RX_LOW_WATERMARK) && + net_ratelimit()) + IWL_CRIT(priv, "Failed to allocate SKB buffer with %s. Only %u free buffers remaining.\n", + priority == GFP_ATOMIC ? "GFP_ATOMIC" : "GFP_KERNEL", + rxq->free_count); + /* We don't reschedule replenish work here -- we will + * call the restock method and if it still needs + * more buffers it will schedule replenish */ + break; + } + + spin_lock_irqsave(&rxq->lock, flags); + if (list_empty(&rxq->rx_used)) { + spin_unlock_irqrestore(&rxq->lock, flags); + __free_pages(page, priv->hw_params.rx_page_order); + return; + } + element = rxq->rx_used.next; + rxb = list_entry(element, struct iwl_rx_mem_buffer, list); + list_del(element); + spin_unlock_irqrestore(&rxq->lock, flags); + + rxb->page = page; + /* Get physical address of RB/SKB */ + rxb->page_dma = pci_map_page(priv->pci_dev, page, 0, + PAGE_SIZE << priv->hw_params.rx_page_order, + PCI_DMA_FROMDEVICE); + + spin_lock_irqsave(&rxq->lock, flags); + + list_add_tail(&rxb->list, &rxq->rx_free); + rxq->free_count++; + priv->alloc_rxb_page++; + + spin_unlock_irqrestore(&rxq->lock, flags); + } +} + +void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) +{ + unsigned long flags; + int i; + spin_lock_irqsave(&rxq->lock, flags); + INIT_LIST_HEAD(&rxq->rx_free); + INIT_LIST_HEAD(&rxq->rx_used); + /* Fill the rx_used queue with _all_ of the Rx buffers */ + for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { + /* In the reset function, these buffers may have been allocated + * to an SKB, so we need to unmap and free potential storage */ + if (rxq->pool[i].page != NULL) { + pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, + PAGE_SIZE << priv->hw_params.rx_page_order, + PCI_DMA_FROMDEVICE); + __iwl_free_pages(priv, rxq->pool[i].page); + rxq->pool[i].page = NULL; + } + list_add_tail(&rxq->pool[i].list, &rxq->rx_used); + } + + /* 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->write_actual = 0; + rxq->free_count = 0; + spin_unlock_irqrestore(&rxq->lock, flags); +} + +void iwl3945_rx_replenish(void *data) +{ + struct iwl_priv *priv = data; + unsigned long flags; + + iwl3945_rx_allocate(priv, GFP_KERNEL); + + spin_lock_irqsave(&priv->lock, flags); + iwl3945_rx_queue_restock(priv); + spin_unlock_irqrestore(&priv->lock, flags); +} + +static void iwl3945_rx_replenish_now(struct iwl_priv *priv) +{ + iwl3945_rx_allocate(priv, GFP_ATOMIC); + + iwl3945_rx_queue_restock(priv); +} + + +/* Assumes that the skb field of the buffers in 'pool' is kept accurate. + * If an SKB has been detached, the POOL needs to have its SKB set to NULL + * This free routine walks the list of POOL entries and if SKB is set to + * non NULL it is unmapped and freed + */ +static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) +{ + int i; + for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { + if (rxq->pool[i].page != NULL) { + pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, + PAGE_SIZE << priv->hw_params.rx_page_order, + PCI_DMA_FROMDEVICE); + __iwl_free_pages(priv, rxq->pool[i].page); + rxq->pool[i].page = NULL; + } + } + + dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, + rxq->bd_dma); + dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status), + rxq->rb_stts, rxq->rb_stts_dma); + rxq->bd = NULL; + rxq->rb_stts = NULL; +} + + +/* Convert linear signal-to-noise ratio into dB */ +static u8 ratio2dB[100] = { +/* 0 1 2 3 4 5 6 7 8 9 */ + 0, 0, 6, 10, 12, 14, 16, 17, 18, 19, /* 00 - 09 */ + 20, 21, 22, 22, 23, 23, 24, 25, 26, 26, /* 10 - 19 */ + 26, 26, 26, 27, 27, 28, 28, 28, 29, 29, /* 20 - 29 */ + 29, 30, 30, 30, 31, 31, 31, 31, 32, 32, /* 30 - 39 */ + 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, /* 40 - 49 */ + 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, /* 50 - 59 */ + 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, /* 60 - 69 */ + 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, /* 70 - 79 */ + 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, /* 80 - 89 */ + 39, 39, 39, 39, 39, 40, 40, 40, 40, 40 /* 90 - 99 */ +}; + +/* Calculates a relative dB value from a ratio of linear + * (i.e. not dB) signal levels. + * Conversion assumes that levels are voltages (20*log), not powers (10*log). */ +int iwl3945_calc_db_from_ratio(int sig_ratio) +{ + /* 1000:1 or higher just report as 60 dB */ + if (sig_ratio >= 1000) + return 60; + + /* 100:1 or higher, divide by 10 and use table, + * add 20 dB to make up for divide by 10 */ + if (sig_ratio >= 100) + return 20 + (int)ratio2dB[sig_ratio/10]; + + /* We shouldn't see this */ + if (sig_ratio < 1) + return 0; + + /* Use table for ratios 1:1 - 99:1 */ + return (int)ratio2dB[sig_ratio]; +} + +/** + * iwl3945_rx_handle - Main entry function for receiving responses from uCode + * + * Uses the priv->rx_handlers callback function array to invoke + * the appropriate handlers, including command responses, + * frame-received notifications, and other notifications. + */ +static void iwl3945_rx_handle(struct iwl_priv *priv) +{ + struct iwl_rx_mem_buffer *rxb; + struct iwl_rx_packet *pkt; + struct iwl_rx_queue *rxq = &priv->rxq; + u32 r, i; + int reclaim; + unsigned long flags; + u8 fill_rx = 0; + u32 count = 8; + int total_empty = 0; + + /* uCode's read index (stored in shared DRAM) indicates the last Rx + * buffer that the driver may process (last buffer filled by ucode). */ + r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF; + i = rxq->read; + + /* calculate total frames need to be restock after handling RX */ + total_empty = r - rxq->write_actual; + if (total_empty < 0) + total_empty += RX_QUEUE_SIZE; + + if (total_empty > (RX_QUEUE_SIZE / 2)) + fill_rx = 1; + /* Rx interrupt, but nothing sent from uCode */ + if (i == r) + IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i); + + while (i != r) { + int len; + + rxb = rxq->queue[i]; + + /* If an RXB doesn't have a Rx queue slot associated with it, + * then a bug has been introduced in the queue refilling + * routines -- catch it here */ + BUG_ON(rxb == NULL); + + rxq->queue[i] = NULL; + + pci_unmap_page(priv->pci_dev, rxb->page_dma, + PAGE_SIZE << priv->hw_params.rx_page_order, + PCI_DMA_FROMDEVICE); + pkt = rxb_addr(rxb); + + len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; + len += sizeof(u32); /* account for status word */ + trace_iwlwifi_dev_rx(priv, pkt, len); + + /* Reclaim a command buffer only if this packet is a response + * to a (driver-originated) command. + * If the packet (e.g. Rx frame) originated from uCode, + * there is no command buffer to reclaim. + * Ucode should set SEQ_RX_FRAME bit if ucode-originated, + * but apparently a few don't get set; catch them here. */ + reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) && + (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && + (pkt->hdr.cmd != REPLY_TX); + + /* Based on type of command response or notification, + * handle those that need handling via function in + * rx_handlers table. See iwl3945_setup_rx_handlers() */ + if (priv->rx_handlers[pkt->hdr.cmd]) { + IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, i, + get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); + priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; + priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); + } else { + /* No handling needed */ + IWL_DEBUG_RX(priv, + "r %d i %d No handler needed for %s, 0x%02x\n", + r, i, get_cmd_string(pkt->hdr.cmd), + pkt->hdr.cmd); + } + + /* + * XXX: After here, we should always check rxb->page + * against NULL before touching it or its virtual + * memory (pkt). Because some rx_handler might have + * already taken or freed the pages. + */ + + if (reclaim) { + /* Invoke any callbacks, transfer the buffer to caller, + * and fire off the (possibly) blocking iwl_send_cmd() + * as we reclaim the driver command queue */ + if (rxb->page) + iwl_tx_cmd_complete(priv, rxb); + else + IWL_WARN(priv, "Claim null rxb?\n"); + } + + /* Reuse the page if possible. For notification packets and + * SKBs that fail to Rx correctly, add them back into the + * rx_free list for reuse later. */ + spin_lock_irqsave(&rxq->lock, flags); + if (rxb->page != NULL) { + rxb->page_dma = pci_map_page(priv->pci_dev, rxb->page, + 0, PAGE_SIZE << priv->hw_params.rx_page_order, + PCI_DMA_FROMDEVICE); + list_add_tail(&rxb->list, &rxq->rx_free); + rxq->free_count++; + } else + list_add_tail(&rxb->list, &rxq->rx_used); + + spin_unlock_irqrestore(&rxq->lock, flags); + + i = (i + 1) & RX_QUEUE_MASK; + /* If there are a lot of unused frames, + * restock the Rx queue so ucode won't assert. */ + if (fill_rx) { + count++; + if (count >= 8) { + rxq->read = i; + iwl3945_rx_replenish_now(priv); + count = 0; + } + } + } + + /* Backtrack one entry */ + rxq->read = i; + if (fill_rx) + iwl3945_rx_replenish_now(priv); + else + iwl3945_rx_queue_restock(priv); +} + +/* call this function to flush any scheduled tasklet */ +static inline void iwl_synchronize_irq(struct iwl_priv *priv) +{ + /* wait to make sure we flush pending tasklet*/ + synchronize_irq(priv->pci_dev->irq); + tasklet_kill(&priv->irq_tasklet); +} + +static const char *desc_lookup(int i) +{ + switch (i) { + case 1: + return "FAIL"; + case 2: + return "BAD_PARAM"; + case 3: + return "BAD_CHECKSUM"; + case 4: + return "NMI_INTERRUPT"; + case 5: + return "SYSASSERT"; + case 6: + return "FATAL_ERROR"; + } + + return "UNKNOWN"; +} + +#define ERROR_START_OFFSET (1 * sizeof(u32)) +#define ERROR_ELEM_SIZE (7 * sizeof(u32)) + +void iwl3945_dump_nic_error_log(struct iwl_priv *priv) +{ + u32 i; + u32 desc, time, count, base, data1; + u32 blink1, blink2, ilink1, ilink2; + + base = le32_to_cpu(priv->card_alive.error_event_table_ptr); + + if (!iwl3945_hw_valid_rtc_data_addr(base)) { + IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base); + return; + } + + + count = iwl_read_targ_mem(priv, base); + + if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { + IWL_ERR(priv, "Start IWL Error Log Dump:\n"); + IWL_ERR(priv, "Status: 0x%08lX, count: %d\n", + priv->status, count); + } + + IWL_ERR(priv, "Desc Time asrtPC blink2 " + "ilink1 nmiPC Line\n"); + for (i = ERROR_START_OFFSET; + i < (count * ERROR_ELEM_SIZE) + ERROR_START_OFFSET; + i += ERROR_ELEM_SIZE) { + desc = iwl_read_targ_mem(priv, base + i); + time = + iwl_read_targ_mem(priv, base + i + 1 * sizeof(u32)); + blink1 = + iwl_read_targ_mem(priv, base + i + 2 * sizeof(u32)); + blink2 = + iwl_read_targ_mem(priv, base + i + 3 * sizeof(u32)); + ilink1 = + iwl_read_targ_mem(priv, base + i + 4 * sizeof(u32)); + ilink2 = + iwl_read_targ_mem(priv, base + i + 5 * sizeof(u32)); + data1 = + iwl_read_targ_mem(priv, base + i + 6 * sizeof(u32)); + + IWL_ERR(priv, + "%-13s (0x%X) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n", + desc_lookup(desc), desc, time, blink1, blink2, + ilink1, ilink2, data1); + trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, 0, + 0, blink1, blink2, ilink1, ilink2); + } +} + +#define EVENT_START_OFFSET (6 * sizeof(u32)) + +/** + * iwl3945_print_event_log - Dump error event log to syslog + * + */ +static int iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, + u32 num_events, u32 mode, + int pos, char **buf, size_t bufsz) +{ + u32 i; + u32 base; /* SRAM byte address of event log header */ + u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */ + u32 ptr; /* SRAM byte address of log data */ + u32 ev, time, data; /* event log data */ + unsigned long reg_flags; + + if (num_events == 0) + return pos; + + base = le32_to_cpu(priv->card_alive.log_event_table_ptr); + + if (mode == 0) + event_size = 2 * sizeof(u32); + else + event_size = 3 * sizeof(u32); + + ptr = base + EVENT_START_OFFSET + (start_idx * event_size); + + /* Make sure device is powered up for SRAM reads */ + spin_lock_irqsave(&priv->reg_lock, reg_flags); + iwl_grab_nic_access(priv); + + /* Set starting address; reads will auto-increment */ + _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); + rmb(); + + /* "time" is actually "data" for mode 0 (no timestamp). + * place event id # at far right for easier visual parsing. */ + for (i = 0; i < num_events; i++) { + ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); + time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); + if (mode == 0) { + /* data, ev */ + if (bufsz) { + pos += scnprintf(*buf + pos, bufsz - pos, + "0x%08x:%04u\n", + time, ev); + } else { + IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); + trace_iwlwifi_dev_ucode_event(priv, 0, + time, ev); + } + } else { + data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); + if (bufsz) { + pos += scnprintf(*buf + pos, bufsz - pos, + "%010u:0x%08x:%04u\n", + time, data, ev); + } else { + IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", + time, data, ev); + trace_iwlwifi_dev_ucode_event(priv, time, + data, ev); + } + } + } + + /* Allow device to power down */ + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); + return pos; +} + +/** + * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog + */ +static int iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, + u32 num_wraps, u32 next_entry, + u32 size, u32 mode, + int pos, char **buf, size_t bufsz) +{ + /* + * display the newest DEFAULT_LOG_ENTRIES entries + * i.e the entries just before the next ont that uCode would fill. + */ + if (num_wraps) { + if (next_entry < size) { + pos = iwl3945_print_event_log(priv, + capacity - (size - next_entry), + size - next_entry, mode, + pos, buf, bufsz); + pos = iwl3945_print_event_log(priv, 0, + next_entry, mode, + pos, buf, bufsz); + } else + pos = iwl3945_print_event_log(priv, next_entry - size, + size, mode, + pos, buf, bufsz); + } else { + if (next_entry < size) + pos = iwl3945_print_event_log(priv, 0, + next_entry, mode, + pos, buf, bufsz); + else + pos = iwl3945_print_event_log(priv, next_entry - size, + size, mode, + pos, buf, bufsz); + } + return pos; +} + +#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) + +int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, + char **buf, bool display) +{ + u32 base; /* SRAM byte address of event log header */ + u32 capacity; /* event log capacity in # entries */ + u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ + u32 num_wraps; /* # times uCode wrapped to top of log */ + u32 next_entry; /* index of next entry to be written by uCode */ + u32 size; /* # entries that we'll print */ + int pos = 0; + size_t bufsz = 0; + + base = le32_to_cpu(priv->card_alive.log_event_table_ptr); + if (!iwl3945_hw_valid_rtc_data_addr(base)) { + IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); + return -EINVAL; + } + + /* event log header */ + capacity = iwl_read_targ_mem(priv, base); + mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32))); + num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); + next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); + + if (capacity > priv->cfg->base_params->max_event_log_size) { + IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n", + capacity, priv->cfg->base_params->max_event_log_size); + capacity = priv->cfg->base_params->max_event_log_size; + } + + if (next_entry > priv->cfg->base_params->max_event_log_size) { + IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n", + next_entry, priv->cfg->base_params->max_event_log_size); + next_entry = priv->cfg->base_params->max_event_log_size; + } + + size = num_wraps ? capacity : next_entry; + + /* bail out if nothing in log */ + if (size == 0) { + IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); + return pos; + } + +#ifdef CONFIG_IWLWIFI_DEBUG + if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) + size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) + ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; +#else + size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) + ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; +#endif + + IWL_ERR(priv, "Start IWL Event Log Dump: display last %d count\n", + size); + +#ifdef CONFIG_IWLWIFI_DEBUG + if (display) { + if (full_log) + bufsz = capacity * 48; + else + bufsz = size * 48; + *buf = kmalloc(bufsz, GFP_KERNEL); + if (!*buf) + return -ENOMEM; + } + if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { + /* if uCode has wrapped back to top of log, + * start at the oldest entry, + * i.e the next one that uCode would fill. + */ + if (num_wraps) + pos = iwl3945_print_event_log(priv, next_entry, + capacity - next_entry, mode, + pos, buf, bufsz); + + /* (then/else) start at top of log */ + pos = iwl3945_print_event_log(priv, 0, next_entry, mode, + pos, buf, bufsz); + } else + pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps, + next_entry, size, mode, + pos, buf, bufsz); +#else + pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps, + next_entry, size, mode, + pos, buf, bufsz); +#endif + return pos; +} + +static void iwl3945_irq_tasklet(struct iwl_priv *priv) +{ + u32 inta, handled = 0; + u32 inta_fh; + unsigned long flags; +#ifdef CONFIG_IWLWIFI_DEBUG + u32 inta_mask; +#endif + + spin_lock_irqsave(&priv->lock, flags); + + /* Ack/clear/reset pending uCode interrupts. + * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, + * and will clear only when CSR_FH_INT_STATUS gets cleared. */ + inta = iwl_read32(priv, CSR_INT); + iwl_write32(priv, CSR_INT, inta); + + /* Ack/clear/reset pending flow-handler (DMA) interrupts. + * Any new interrupts that happen after this, either while we're + * in this tasklet, or later, will show up in next ISR/tasklet. */ + inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); + iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh); + +#ifdef CONFIG_IWLWIFI_DEBUG + if (iwl_get_debug_level(priv) & IWL_DL_ISR) { + /* just for debug */ + inta_mask = iwl_read32(priv, CSR_INT_MASK); + IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", + inta, inta_mask, inta_fh); + } +#endif + + spin_unlock_irqrestore(&priv->lock, flags); + + /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not + * atomic, make sure that inta covers all the interrupts that + * we've discovered, even if FH interrupt came in just after + * reading CSR_INT. */ + if (inta_fh & CSR39_FH_INT_RX_MASK) + inta |= CSR_INT_BIT_FH_RX; + if (inta_fh & CSR39_FH_INT_TX_MASK) + inta |= CSR_INT_BIT_FH_TX; + + /* Now service all interrupt bits discovered above. */ + if (inta & CSR_INT_BIT_HW_ERR) { + IWL_ERR(priv, "Hardware error detected. Restarting.\n"); + + /* Tell the device to stop sending interrupts */ + iwl_disable_interrupts(priv); + + priv->isr_stats.hw++; + iwl_irq_handle_error(priv); + + handled |= CSR_INT_BIT_HW_ERR; + + return; + } + +#ifdef CONFIG_IWLWIFI_DEBUG + if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) { + /* NIC fires this, but we don't use it, redundant with WAKEUP */ + if (inta & CSR_INT_BIT_SCD) { + IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " + "the frame/frames.\n"); + priv->isr_stats.sch++; + } + + /* Alive notification via Rx interrupt will do the real work */ + if (inta & CSR_INT_BIT_ALIVE) { + IWL_DEBUG_ISR(priv, "Alive interrupt\n"); + priv->isr_stats.alive++; + } + } +#endif + /* Safely ignore these bits for debug checks below */ + inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE); + + /* Error detected by uCode */ + if (inta & CSR_INT_BIT_SW_ERR) { + IWL_ERR(priv, "Microcode SW error detected. " + "Restarting 0x%X.\n", inta); + priv->isr_stats.sw++; + iwl_irq_handle_error(priv); + handled |= CSR_INT_BIT_SW_ERR; + } + + /* uCode wakes up after power-down sleep */ + if (inta & CSR_INT_BIT_WAKEUP) { + IWL_DEBUG_ISR(priv, "Wakeup interrupt\n"); + iwl_rx_queue_update_write_ptr(priv, &priv->rxq); + iwl_txq_update_write_ptr(priv, &priv->txq[0]); + iwl_txq_update_write_ptr(priv, &priv->txq[1]); + iwl_txq_update_write_ptr(priv, &priv->txq[2]); + iwl_txq_update_write_ptr(priv, &priv->txq[3]); + iwl_txq_update_write_ptr(priv, &priv->txq[4]); + iwl_txq_update_write_ptr(priv, &priv->txq[5]); + + priv->isr_stats.wakeup++; + handled |= CSR_INT_BIT_WAKEUP; + } + + /* All uCode command responses, including Tx command responses, + * Rx "responses" (frame-received notification), and other + * notifications from uCode come through here*/ + if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { + iwl3945_rx_handle(priv); + priv->isr_stats.rx++; + handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); + } + + if (inta & CSR_INT_BIT_FH_TX) { + IWL_DEBUG_ISR(priv, "Tx interrupt\n"); + priv->isr_stats.tx++; + + iwl_write32(priv, CSR_FH_INT_STATUS, (1 << 6)); + iwl_write_direct32(priv, FH39_TCSR_CREDIT + (FH39_SRVC_CHNL), 0x0); + handled |= CSR_INT_BIT_FH_TX; + } + + if (inta & ~handled) { + IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); + priv->isr_stats.unhandled++; + } + + if (inta & ~priv->inta_mask) { + IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", + inta & ~priv->inta_mask); + IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh); + } + + /* Re-enable all interrupts */ + /* only Re-enable if disabled by irq */ + if (test_bit(STATUS_INT_ENABLED, &priv->status)) + iwl_enable_interrupts(priv); + +#ifdef CONFIG_IWLWIFI_DEBUG + if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) { + inta = iwl_read32(priv, CSR_INT); + inta_mask = iwl_read32(priv, CSR_INT_MASK); + inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); + IWL_DEBUG_ISR(priv, "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, " + "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); + } +#endif +} + +static int iwl3945_get_single_channel_for_scan(struct iwl_priv *priv, + struct ieee80211_vif *vif, + enum ieee80211_band band, + struct iwl3945_scan_channel *scan_ch) +{ + const struct ieee80211_supported_band *sband; + u16 passive_dwell = 0; + u16 active_dwell = 0; + int added = 0; + u8 channel = 0; + + sband = iwl_get_hw_mode(priv, band); + if (!sband) { + IWL_ERR(priv, "invalid band\n"); + return added; + } + + active_dwell = iwl_get_active_dwell_time(priv, band, 0); + passive_dwell = iwl_get_passive_dwell_time(priv, band, vif); + + if (passive_dwell <= active_dwell) + passive_dwell = active_dwell + 1; + + + channel = iwl_get_single_channel_number(priv, band); + + if (channel) { + scan_ch->channel = channel; + scan_ch->type = 0; /* passive */ + scan_ch->active_dwell = cpu_to_le16(active_dwell); + scan_ch->passive_dwell = cpu_to_le16(passive_dwell); + /* Set txpower levels to defaults */ + scan_ch->tpc.dsp_atten = 110; + if (band == IEEE80211_BAND_5GHZ) + scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; + else + scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); + added++; + } else + IWL_ERR(priv, "no valid channel found\n"); + return added; +} + +static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, + enum ieee80211_band band, + u8 is_active, u8 n_probes, + struct iwl3945_scan_channel *scan_ch, + struct ieee80211_vif *vif) +{ + struct ieee80211_channel *chan; + const struct ieee80211_supported_band *sband; + const struct iwl_channel_info *ch_info; + u16 passive_dwell = 0; + u16 active_dwell = 0; + int added, i; + + sband = iwl_get_hw_mode(priv, band); + if (!sband) + return 0; + + active_dwell = iwl_get_active_dwell_time(priv, band, n_probes); + passive_dwell = iwl_get_passive_dwell_time(priv, band, vif); + + if (passive_dwell <= active_dwell) + passive_dwell = active_dwell + 1; + + for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) { + chan = priv->scan_request->channels[i]; + + if (chan->band != band) + continue; + + scan_ch->channel = chan->hw_value; + + ch_info = iwl_get_channel_info(priv, band, scan_ch->channel); + if (!is_channel_valid(ch_info)) { + IWL_DEBUG_SCAN(priv, "Channel %d is INVALID for this band.\n", + scan_ch->channel); + continue; + } + + scan_ch->active_dwell = cpu_to_le16(active_dwell); + scan_ch->passive_dwell = cpu_to_le16(passive_dwell); + /* If passive , set up for auto-switch + * and use long active_dwell time. + */ + if (!is_active || is_channel_passive(ch_info) || + (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) { + scan_ch->type = 0; /* passive */ + if (IWL_UCODE_API(priv->ucode_ver) == 1) + scan_ch->active_dwell = cpu_to_le16(passive_dwell - 1); + } else { + scan_ch->type = 1; /* active */ + } + + /* Set direct probe bits. These may be used both for active + * scan channels (probes gets sent right away), + * or for passive channels (probes get se sent only after + * hearing clear Rx packet).*/ + if (IWL_UCODE_API(priv->ucode_ver) >= 2) { + if (n_probes) + scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes); + } else { + /* uCode v1 does not allow setting direct probe bits on + * passive channel. */ + if ((scan_ch->type & 1) && n_probes) + scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes); + } + + /* Set txpower levels to defaults */ + scan_ch->tpc.dsp_atten = 110; + /* scan_pwr_info->tpc.dsp_atten; */ + + /*scan_pwr_info->tpc.tx_gain; */ + if (band == IEEE80211_BAND_5GHZ) + scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; + else { + scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); + /* NOTE: if we were doing 6Mb OFDM for scans we'd use + * power level: + * scan_ch->tpc.tx_gain = ((1 << 5) | (2 << 3)) | 3; + */ + } + + IWL_DEBUG_SCAN(priv, "Scanning %d [%s %d]\n", + scan_ch->channel, + (scan_ch->type & 1) ? "ACTIVE" : "PASSIVE", + (scan_ch->type & 1) ? + active_dwell : passive_dwell); + + scan_ch++; + added++; + } + + IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added); + return added; +} + +static void iwl3945_init_hw_rates(struct iwl_priv *priv, + struct ieee80211_rate *rates) +{ + int i; + + for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) { + rates[i].bitrate = iwl3945_rates[i].ieee * 5; + rates[i].hw_value = i; /* Rate scaling will work on indexes */ + rates[i].hw_value_short = i; + rates[i].flags = 0; + if ((i > IWL39_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) { + /* + * If CCK != 1M then set short preamble rate flag. + */ + rates[i].flags |= (iwl3945_rates[i].plcp == 10) ? + 0 : IEEE80211_RATE_SHORT_PREAMBLE; + } + } +} + +/****************************************************************************** + * + * uCode download functions + * + ******************************************************************************/ + +static void iwl3945_dealloc_ucode_pci(struct iwl_priv *priv) +{ + iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code); + iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data); + iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data_backup); + iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init); + iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init_data); + iwl_free_fw_desc(priv->pci_dev, &priv->ucode_boot); +} + +/** + * iwl3945_verify_inst_full - verify runtime uCode image in card vs. host, + * looking at all data. + */ +static int iwl3945_verify_inst_full(struct iwl_priv *priv, __le32 *image, u32 len) +{ + u32 val; + u32 save_len = len; + int rc = 0; + u32 errcnt; + + IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); + + iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, + IWL39_RTC_INST_LOWER_BOUND); + + errcnt = 0; + for (; len > 0; len -= sizeof(u32), image++) { + /* read data comes through single port, auto-incr addr */ + /* NOTE: Use the debugless read so we don't flood kernel log + * if IWL_DL_IO is set */ + val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); + if (val != le32_to_cpu(*image)) { + IWL_ERR(priv, "uCode INST section is invalid at " + "offset 0x%x, is 0x%x, s/b 0x%x\n", + save_len - len, val, le32_to_cpu(*image)); + rc = -EIO; + errcnt++; + if (errcnt >= 20) + break; + } + } + + + if (!errcnt) + IWL_DEBUG_INFO(priv, + "ucode image in INSTRUCTION memory is good\n"); + + return rc; +} + + +/** + * iwl3945_verify_inst_sparse - verify runtime uCode image in card vs. host, + * using sample data 100 bytes apart. If these sample points are good, + * it's a pretty good bet that everything between them is good, too. + */ +static int iwl3945_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) +{ + u32 val; + int rc = 0; + u32 errcnt = 0; + u32 i; + + IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); + + for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { + /* read data comes through single port, auto-incr addr */ + /* NOTE: Use the debugless read so we don't flood kernel log + * if IWL_DL_IO is set */ + iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, + i + IWL39_RTC_INST_LOWER_BOUND); + val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); + if (val != le32_to_cpu(*image)) { +#if 0 /* Enable this if you want to see details */ + IWL_ERR(priv, "uCode INST section is invalid at " + "offset 0x%x, is 0x%x, s/b 0x%x\n", + i, val, *image); +#endif + rc = -EIO; + errcnt++; + if (errcnt >= 3) + break; + } + } + + return rc; +} + + +/** + * iwl3945_verify_ucode - determine which instruction image is in SRAM, + * and verify its contents + */ +static int iwl3945_verify_ucode(struct iwl_priv *priv) +{ + __le32 *image; + u32 len; + int rc = 0; + + /* Try bootstrap */ + image = (__le32 *)priv->ucode_boot.v_addr; + len = priv->ucode_boot.len; + rc = iwl3945_verify_inst_sparse(priv, image, len); + if (rc == 0) { + IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n"); + return 0; + } + + /* Try initialize */ + image = (__le32 *)priv->ucode_init.v_addr; + len = priv->ucode_init.len; + rc = iwl3945_verify_inst_sparse(priv, image, len); + if (rc == 0) { + IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n"); + return 0; + } + + /* Try runtime/protocol */ + image = (__le32 *)priv->ucode_code.v_addr; + len = priv->ucode_code.len; + rc = iwl3945_verify_inst_sparse(priv, image, len); + if (rc == 0) { + IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n"); + return 0; + } + + IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n"); + + /* Since nothing seems to match, show first several data entries in + * instruction SRAM, so maybe visual inspection will give a clue. + * Selection of bootstrap image (vs. other images) is arbitrary. */ + image = (__le32 *)priv->ucode_boot.v_addr; + len = priv->ucode_boot.len; + rc = iwl3945_verify_inst_full(priv, image, len); + + return rc; +} + +static void iwl3945_nic_start(struct iwl_priv *priv) +{ + /* Remove all resets to allow NIC to operate */ + iwl_write32(priv, CSR_RESET, 0); +} + +#define IWL3945_UCODE_GET(item) \ +static u32 iwl3945_ucode_get_##item(const struct iwl_ucode_header *ucode)\ +{ \ + return le32_to_cpu(ucode->u.v1.item); \ +} + +static u32 iwl3945_ucode_get_header_size(u32 api_ver) +{ + return 24; +} + +static u8 *iwl3945_ucode_get_data(const struct iwl_ucode_header *ucode) +{ + return (u8 *) ucode->u.v1.data; +} + +IWL3945_UCODE_GET(inst_size); +IWL3945_UCODE_GET(data_size); +IWL3945_UCODE_GET(init_size); +IWL3945_UCODE_GET(init_data_size); +IWL3945_UCODE_GET(boot_size); + +/** + * iwl3945_read_ucode - Read uCode images from disk file. + * + * Copy into buffers for card to fetch via bus-mastering + */ +static int iwl3945_read_ucode(struct iwl_priv *priv) +{ + const struct iwl_ucode_header *ucode; + int ret = -EINVAL, index; + const struct firmware *ucode_raw; + /* firmware file name contains uCode/driver compatibility version */ + const char *name_pre = priv->cfg->fw_name_pre; + const unsigned int api_max = priv->cfg->ucode_api_max; + const unsigned int api_min = priv->cfg->ucode_api_min; + char buf[25]; + u8 *src; + size_t len; + u32 api_ver, inst_size, data_size, init_size, init_data_size, boot_size; + + /* Ask kernel firmware_class module to get the boot firmware off disk. + * request_firmware() is synchronous, file is in memory on return. */ + for (index = api_max; index >= api_min; index--) { + sprintf(buf, "%s%u%s", name_pre, index, ".ucode"); + ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev); + if (ret < 0) { + IWL_ERR(priv, "%s firmware file req failed: %d\n", + buf, ret); + if (ret == -ENOENT) + continue; + else + goto error; + } else { + if (index < api_max) + IWL_ERR(priv, "Loaded firmware %s, " + "which is deprecated. " + " Please use API v%u instead.\n", + buf, api_max); + IWL_DEBUG_INFO(priv, "Got firmware '%s' file " + "(%zd bytes) from disk\n", + buf, ucode_raw->size); + break; + } + } + + if (ret < 0) + goto error; + + /* Make sure that we got at least our header! */ + if (ucode_raw->size < iwl3945_ucode_get_header_size(1)) { + IWL_ERR(priv, "File size way too small!\n"); + ret = -EINVAL; + goto err_release; + } + + /* Data from ucode file: header followed by uCode images */ + ucode = (struct iwl_ucode_header *)ucode_raw->data; + + priv->ucode_ver = le32_to_cpu(ucode->ver); + api_ver = IWL_UCODE_API(priv->ucode_ver); + inst_size = iwl3945_ucode_get_inst_size(ucode); + data_size = iwl3945_ucode_get_data_size(ucode); + init_size = iwl3945_ucode_get_init_size(ucode); + init_data_size = iwl3945_ucode_get_init_data_size(ucode); + boot_size = iwl3945_ucode_get_boot_size(ucode); + src = iwl3945_ucode_get_data(ucode); + + /* api_ver should match the api version forming part of the + * firmware filename ... but we don't check for that and only rely + * on the API version read from firmware header from here on forward */ + + if (api_ver < api_min || api_ver > api_max) { + IWL_ERR(priv, "Driver unable to support your firmware API. " + "Driver supports v%u, firmware is v%u.\n", + api_max, api_ver); + priv->ucode_ver = 0; + ret = -EINVAL; + goto err_release; + } + if (api_ver != api_max) + IWL_ERR(priv, "Firmware has old API version. Expected %u, " + "got %u. New firmware can be obtained " + "from http://www.intellinuxwireless.org.\n", + api_max, api_ver); + + IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u\n", + IWL_UCODE_MAJOR(priv->ucode_ver), + IWL_UCODE_MINOR(priv->ucode_ver), + IWL_UCODE_API(priv->ucode_ver), + IWL_UCODE_SERIAL(priv->ucode_ver)); + + snprintf(priv->hw->wiphy->fw_version, + sizeof(priv->hw->wiphy->fw_version), + "%u.%u.%u.%u", + IWL_UCODE_MAJOR(priv->ucode_ver), + IWL_UCODE_MINOR(priv->ucode_ver), + IWL_UCODE_API(priv->ucode_ver), + IWL_UCODE_SERIAL(priv->ucode_ver)); + + IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n", + priv->ucode_ver); + IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n", + inst_size); + IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %u\n", + data_size); + IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %u\n", + init_size); + IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %u\n", + init_data_size); + IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n", + boot_size); + + + /* Verify size of file vs. image size info in file's header */ + if (ucode_raw->size != iwl3945_ucode_get_header_size(api_ver) + + inst_size + data_size + init_size + + init_data_size + boot_size) { + + IWL_DEBUG_INFO(priv, + "uCode file size %zd does not match expected size\n", + ucode_raw->size); + ret = -EINVAL; + goto err_release; + } + + /* Verify that uCode images will fit in card's SRAM */ + if (inst_size > IWL39_MAX_INST_SIZE) { + IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n", + inst_size); + ret = -EINVAL; + goto err_release; + } + + if (data_size > IWL39_MAX_DATA_SIZE) { + IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n", + data_size); + ret = -EINVAL; + goto err_release; + } + if (init_size > IWL39_MAX_INST_SIZE) { + IWL_DEBUG_INFO(priv, + "uCode init instr len %d too large to fit in\n", + init_size); + ret = -EINVAL; + goto err_release; + } + if (init_data_size > IWL39_MAX_DATA_SIZE) { + IWL_DEBUG_INFO(priv, + "uCode init data len %d too large to fit in\n", + init_data_size); + ret = -EINVAL; + goto err_release; + } + if (boot_size > IWL39_MAX_BSM_SIZE) { + IWL_DEBUG_INFO(priv, + "uCode boot instr len %d too large to fit in\n", + boot_size); + ret = -EINVAL; + goto err_release; + } + + /* Allocate ucode buffers for card's bus-master loading ... */ + + /* Runtime instructions and 2 copies of data: + * 1) unmodified from disk + * 2) backup cache for save/restore during power-downs */ + priv->ucode_code.len = inst_size; + iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_code); + + priv->ucode_data.len = data_size; + iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data); + + priv->ucode_data_backup.len = data_size; + iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup); + + if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr || + !priv->ucode_data_backup.v_addr) + goto err_pci_alloc; + + /* Initialization instructions and data */ + if (init_size && init_data_size) { + priv->ucode_init.len = init_size; + iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init); + + priv->ucode_init_data.len = init_data_size; + iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data); + + if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr) + goto err_pci_alloc; + } + + /* Bootstrap (instructions only, no data) */ + if (boot_size) { + priv->ucode_boot.len = boot_size; + iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot); + + if (!priv->ucode_boot.v_addr) + goto err_pci_alloc; + } + + /* Copy images into buffers for card's bus-master reads ... */ + + /* Runtime instructions (first block of data in file) */ + len = inst_size; + IWL_DEBUG_INFO(priv, + "Copying (but not loading) uCode instr len %zd\n", len); + memcpy(priv->ucode_code.v_addr, src, len); + src += len; + + IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n", + priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr); + + /* Runtime data (2nd block) + * NOTE: Copy into backup buffer will be done in iwl3945_up() */ + len = data_size; + IWL_DEBUG_INFO(priv, + "Copying (but not loading) uCode data len %zd\n", len); + memcpy(priv->ucode_data.v_addr, src, len); + memcpy(priv->ucode_data_backup.v_addr, src, len); + src += len; + + /* Initialization instructions (3rd block) */ + if (init_size) { + len = init_size; + IWL_DEBUG_INFO(priv, + "Copying (but not loading) init instr len %zd\n", len); + memcpy(priv->ucode_init.v_addr, src, len); + src += len; + } + + /* Initialization data (4th block) */ + if (init_data_size) { + len = init_data_size; + IWL_DEBUG_INFO(priv, + "Copying (but not loading) init data len %zd\n", len); + memcpy(priv->ucode_init_data.v_addr, src, len); + src += len; + } + + /* Bootstrap instructions (5th block) */ + len = boot_size; + IWL_DEBUG_INFO(priv, + "Copying (but not loading) boot instr len %zd\n", len); + memcpy(priv->ucode_boot.v_addr, src, len); + + /* We have our copies now, allow OS release its copies */ + release_firmware(ucode_raw); + return 0; + + err_pci_alloc: + IWL_ERR(priv, "failed to allocate pci memory\n"); + ret = -ENOMEM; + iwl3945_dealloc_ucode_pci(priv); + + err_release: + release_firmware(ucode_raw); + + error: + return ret; +} + + +/** + * iwl3945_set_ucode_ptrs - Set uCode address location + * + * Tell initialization uCode where to find runtime uCode. + * + * BSM registers initially contain pointers to initialization uCode. + * We need to replace them to load runtime uCode inst and data, + * and to save runtime data when powering down. + */ +static int iwl3945_set_ucode_ptrs(struct iwl_priv *priv) +{ + dma_addr_t pinst; + dma_addr_t pdata; + + /* bits 31:0 for 3945 */ + pinst = priv->ucode_code.p_addr; + pdata = priv->ucode_data_backup.p_addr; + + /* Tell bootstrap uCode where to find image to load */ + iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); + iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); + iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, + priv->ucode_data.len); + + /* Inst byte count must be last to set up, bit 31 signals uCode + * that all new ptr/size info is in place */ + iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, + priv->ucode_code.len | BSM_DRAM_INST_LOAD); + + IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n"); + + return 0; +} + +/** + * iwl3945_init_alive_start - Called after REPLY_ALIVE notification received + * + * Called after REPLY_ALIVE notification received from "initialize" uCode. + * + * Tell "initialize" uCode to go ahead and load the runtime uCode. + */ +static void iwl3945_init_alive_start(struct iwl_priv *priv) +{ + /* Check alive response for "valid" sign from uCode */ + if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { + /* We had an error bringing up the hardware, so take it + * all the way back down so we can try again */ + IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n"); + goto restart; + } + + /* Bootstrap uCode has loaded initialize uCode ... verify inst image. + * This is a paranoid check, because we would not have gotten the + * "initialize" alive if code weren't properly loaded. */ + if (iwl3945_verify_ucode(priv)) { + /* Runtime instruction load was bad; + * take it all the way back down so we can try again */ + IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n"); + goto restart; + } + + /* Send pointers to protocol/runtime uCode image ... init code will + * load and launch runtime uCode, which will send us another "Alive" + * notification. */ + IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); + if (iwl3945_set_ucode_ptrs(priv)) { + /* Runtime instruction load won't happen; + * take it all the way back down so we can try again */ + IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n"); + goto restart; + } + return; + + restart: + queue_work(priv->workqueue, &priv->restart); +} + +/** + * iwl3945_alive_start - called after REPLY_ALIVE notification received + * from protocol/runtime uCode (initialization uCode's + * Alive gets handled by iwl3945_init_alive_start()). + */ +static void iwl3945_alive_start(struct iwl_priv *priv) +{ + int thermal_spin = 0; + u32 rfkill; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); + + if (priv->card_alive.is_valid != UCODE_VALID_OK) { + /* We had an error bringing up the hardware, so take it + * all the way back down so we can try again */ + IWL_DEBUG_INFO(priv, "Alive failed.\n"); + goto restart; + } + + /* Initialize uCode has loaded Runtime uCode ... verify inst image. + * This is a paranoid check, because we would not have gotten the + * "runtime" alive if code weren't properly loaded. */ + if (iwl3945_verify_ucode(priv)) { + /* Runtime instruction load was bad; + * take it all the way back down so we can try again */ + IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n"); + goto restart; + } + + rfkill = iwl_read_prph(priv, APMG_RFKILL_REG); + IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill); + + if (rfkill & 0x1) { + clear_bit(STATUS_RF_KILL_HW, &priv->status); + /* if RFKILL is not on, then wait for thermal + * sensor in adapter to kick in */ + while (iwl3945_hw_get_temperature(priv) == 0) { + thermal_spin++; + udelay(10); + } + + if (thermal_spin) + IWL_DEBUG_INFO(priv, "Thermal calibration took %dus\n", + thermal_spin * 10); + } else + set_bit(STATUS_RF_KILL_HW, &priv->status); + + /* After the ALIVE response, we can send commands to 3945 uCode */ + set_bit(STATUS_ALIVE, &priv->status); + + /* Enable watchdog to monitor the driver tx queues */ + iwl_setup_watchdog(priv); + + if (iwl_is_rfkill(priv)) + return; + + ieee80211_wake_queues(priv->hw); + + priv->active_rate = IWL_RATES_MASK_3945; + + iwl_power_update_mode(priv, true); + + if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { + struct iwl3945_rxon_cmd *active_rxon = + (struct iwl3945_rxon_cmd *)(&ctx->active); + + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; + } else { + /* Initialize our rx_config data */ + iwl_connection_init_rx_config(priv, ctx); + } + + /* Configure Bluetooth device coexistence support */ + priv->cfg->ops->hcmd->send_bt_config(priv); + + set_bit(STATUS_READY, &priv->status); + + /* Configure the adapter for unassociated operation */ + iwl3945_commit_rxon(priv, ctx); + + iwl3945_reg_txpower_periodic(priv); + + IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); + wake_up_interruptible(&priv->wait_command_queue); + + return; + + restart: + queue_work(priv->workqueue, &priv->restart); +} + +static void iwl3945_cancel_deferred_work(struct iwl_priv *priv); + +static void __iwl3945_down(struct iwl_priv *priv) +{ + unsigned long flags; + int exit_pending; + + IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); + + iwl_scan_cancel_timeout(priv, 200); + + exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); + + /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set + * to prevent rearm timer */ + del_timer_sync(&priv->watchdog); + + /* Station information will now be cleared in device */ + iwl_clear_ucode_stations(priv, NULL); + iwl_dealloc_bcast_stations(priv); + iwl_clear_driver_stations(priv); + + /* Unblock any waiting calls */ + wake_up_interruptible_all(&priv->wait_command_queue); + + /* Wipe out the EXIT_PENDING status bit if we are not actually + * exiting the module */ + if (!exit_pending) + clear_bit(STATUS_EXIT_PENDING, &priv->status); + + /* stop and reset the on-board processor */ + iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); + + /* tell the device to stop sending interrupts */ + spin_lock_irqsave(&priv->lock, flags); + iwl_disable_interrupts(priv); + spin_unlock_irqrestore(&priv->lock, flags); + iwl_synchronize_irq(priv); + + if (priv->mac80211_registered) + ieee80211_stop_queues(priv->hw); + + /* If we have not previously called iwl3945_init() then + * clear all bits but the RF Kill bits and return */ + if (!iwl_is_init(priv)) { + priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << + STATUS_RF_KILL_HW | + test_bit(STATUS_GEO_CONFIGURED, &priv->status) << + STATUS_GEO_CONFIGURED | + test_bit(STATUS_EXIT_PENDING, &priv->status) << + STATUS_EXIT_PENDING; + goto exit; + } + + /* ...otherwise clear out all the status bits but the RF Kill + * bit and continue taking the NIC down. */ + priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << + STATUS_RF_KILL_HW | + test_bit(STATUS_GEO_CONFIGURED, &priv->status) << + STATUS_GEO_CONFIGURED | + test_bit(STATUS_FW_ERROR, &priv->status) << + STATUS_FW_ERROR | + test_bit(STATUS_EXIT_PENDING, &priv->status) << + STATUS_EXIT_PENDING; + + iwl3945_hw_txq_ctx_stop(priv); + iwl3945_hw_rxq_stop(priv); + + /* Power-down device's busmaster DMA clocks */ + iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); + udelay(5); + + /* Stop the device, and put it in low power state */ + iwl_apm_stop(priv); + + exit: + memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); + + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); + priv->beacon_skb = NULL; + + /* clear out any free frames */ + iwl3945_clear_free_frames(priv); +} + +static void iwl3945_down(struct iwl_priv *priv) +{ + mutex_lock(&priv->mutex); + __iwl3945_down(priv); + mutex_unlock(&priv->mutex); + + iwl3945_cancel_deferred_work(priv); +} + +#define MAX_HW_RESTARTS 5 + +static int iwl3945_alloc_bcast_station(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + unsigned long flags; + u8 sta_id; + + spin_lock_irqsave(&priv->sta_lock, flags); + sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL); + if (sta_id == IWL_INVALID_STATION) { + IWL_ERR(priv, "Unable to prepare broadcast station\n"); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return -EINVAL; + } + + priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; + priv->stations[sta_id].used |= IWL_STA_BCAST; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return 0; +} + +static int __iwl3945_up(struct iwl_priv *priv) +{ + int rc, i; + + rc = iwl3945_alloc_bcast_station(priv); + if (rc) + return rc; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { + IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); + return -EIO; + } + + if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { + IWL_ERR(priv, "ucode not available for device bring up\n"); + return -EIO; + } + + /* If platform's RF_KILL switch is NOT set to KILL */ + if (iwl_read32(priv, CSR_GP_CNTRL) & + CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) + clear_bit(STATUS_RF_KILL_HW, &priv->status); + else { + set_bit(STATUS_RF_KILL_HW, &priv->status); + IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n"); + return -ENODEV; + } + + iwl_write32(priv, CSR_INT, 0xFFFFFFFF); + + rc = iwl3945_hw_nic_init(priv); + if (rc) { + IWL_ERR(priv, "Unable to int nic\n"); + return rc; + } + + /* make sure rfkill handshake bits are cleared */ + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, + CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); + + /* clear (again), then enable host interrupts */ + iwl_write32(priv, CSR_INT, 0xFFFFFFFF); + iwl_enable_interrupts(priv); + + /* really make sure rfkill handshake bits are cleared */ + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + + /* Copy original ucode data image from disk into backup cache. + * This will be used to initialize the on-board processor's + * data SRAM for a clean start when the runtime program first loads. */ + memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr, + priv->ucode_data.len); + + /* We return success when we resume from suspend and rf_kill is on. */ + if (test_bit(STATUS_RF_KILL_HW, &priv->status)) + return 0; + + for (i = 0; i < MAX_HW_RESTARTS; i++) { + + /* load bootstrap state machine, + * load bootstrap program into processor's memory, + * prepare to load the "initialize" uCode */ + rc = priv->cfg->ops->lib->load_ucode(priv); + + if (rc) { + IWL_ERR(priv, + "Unable to set up bootstrap uCode: %d\n", rc); + continue; + } + + /* start card; "initialize" will load runtime ucode */ + iwl3945_nic_start(priv); + + IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n"); + + return 0; + } + + set_bit(STATUS_EXIT_PENDING, &priv->status); + __iwl3945_down(priv); + clear_bit(STATUS_EXIT_PENDING, &priv->status); + + /* tried to restart and config the device for as long as our + * patience could withstand */ + IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i); + return -EIO; +} + + +/***************************************************************************** + * + * Workqueue callbacks + * + *****************************************************************************/ + +static void iwl3945_bg_init_alive_start(struct work_struct *data) +{ + struct iwl_priv *priv = + container_of(data, struct iwl_priv, init_alive_start.work); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + iwl3945_init_alive_start(priv); + mutex_unlock(&priv->mutex); +} + +static void iwl3945_bg_alive_start(struct work_struct *data) +{ + struct iwl_priv *priv = + container_of(data, struct iwl_priv, alive_start.work); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + iwl3945_alive_start(priv); + mutex_unlock(&priv->mutex); +} + +/* + * 3945 cannot interrupt driver when hardware rf kill switch toggles; + * driver must poll CSR_GP_CNTRL_REG register for change. This register + * *is* readable even when device has been SW_RESET into low power mode + * (e.g. during RF KILL). + */ +static void iwl3945_rfkill_poll(struct work_struct *data) +{ + struct iwl_priv *priv = + container_of(data, struct iwl_priv, _3945.rfkill_poll.work); + bool old_rfkill = test_bit(STATUS_RF_KILL_HW, &priv->status); + bool new_rfkill = !(iwl_read32(priv, CSR_GP_CNTRL) + & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); + + if (new_rfkill != old_rfkill) { + if (new_rfkill) + set_bit(STATUS_RF_KILL_HW, &priv->status); + else + clear_bit(STATUS_RF_KILL_HW, &priv->status); + + wiphy_rfkill_set_hw_state(priv->hw->wiphy, new_rfkill); + + IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n", + new_rfkill ? "disable radio" : "enable radio"); + } + + /* Keep this running, even if radio now enabled. This will be + * cancelled in mac_start() if system decides to start again */ + queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll, + round_jiffies_relative(2 * HZ)); + +} + +int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) +{ + struct iwl_host_cmd cmd = { + .id = REPLY_SCAN_CMD, + .len = sizeof(struct iwl3945_scan_cmd), + .flags = CMD_SIZE_HUGE, + }; + struct iwl3945_scan_cmd *scan; + u8 n_probes = 0; + enum ieee80211_band band; + bool is_active = false; + int ret; + + lockdep_assert_held(&priv->mutex); + + if (!priv->scan_cmd) { + priv->scan_cmd = kmalloc(sizeof(struct iwl3945_scan_cmd) + + IWL_MAX_SCAN_SIZE, GFP_KERNEL); + if (!priv->scan_cmd) { + IWL_DEBUG_SCAN(priv, "Fail to allocate scan memory\n"); + return -ENOMEM; + } + } + scan = priv->scan_cmd; + memset(scan, 0, sizeof(struct iwl3945_scan_cmd) + IWL_MAX_SCAN_SIZE); + + scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; + scan->quiet_time = IWL_ACTIVE_QUIET_TIME; + + if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { + u16 interval = 0; + u32 extra; + u32 suspend_time = 100; + u32 scan_suspend_time = 100; + + IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); + + if (priv->is_internal_short_scan) + interval = 0; + else + interval = vif->bss_conf.beacon_int; + + scan->suspend_time = 0; + scan->max_out_time = cpu_to_le32(200 * 1024); + if (!interval) + interval = suspend_time; + /* + * suspend time format: + * 0-19: beacon interval in usec (time before exec.) + * 20-23: 0 + * 24-31: number of beacons (suspend between channels) + */ + + extra = (suspend_time / interval) << 24; + scan_suspend_time = 0xFF0FFFFF & + (extra | ((suspend_time % interval) * 1024)); + + scan->suspend_time = cpu_to_le32(scan_suspend_time); + IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n", + scan_suspend_time, interval); + } + + if (priv->is_internal_short_scan) { + IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); + } else if (priv->scan_request->n_ssids) { + int i, p = 0; + IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); + for (i = 0; i < priv->scan_request->n_ssids; i++) { + /* always does wildcard anyway */ + if (!priv->scan_request->ssids[i].ssid_len) + continue; + scan->direct_scan[p].id = WLAN_EID_SSID; + scan->direct_scan[p].len = + priv->scan_request->ssids[i].ssid_len; + memcpy(scan->direct_scan[p].ssid, + priv->scan_request->ssids[i].ssid, + priv->scan_request->ssids[i].ssid_len); + n_probes++; + p++; + } + is_active = true; + } else + IWL_DEBUG_SCAN(priv, "Kicking off passive scan.\n"); + + /* We don't build a direct scan probe request; the uCode will do + * that based on the direct_mask added to each channel entry */ + scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; + scan->tx_cmd.sta_id = priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; + scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; + + /* flags + rate selection */ + + switch (priv->scan_band) { + case IEEE80211_BAND_2GHZ: + scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; + scan->tx_cmd.rate = IWL_RATE_1M_PLCP; + band = IEEE80211_BAND_2GHZ; + break; + case IEEE80211_BAND_5GHZ: + scan->tx_cmd.rate = IWL_RATE_6M_PLCP; + band = IEEE80211_BAND_5GHZ; + break; + default: + IWL_WARN(priv, "Invalid scan band\n"); + return -EIO; + } + + /* + * If active scaning is requested but a certain channel + * is marked passive, we can do active scanning if we + * detect transmissions. + */ + scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : + IWL_GOOD_CRC_TH_DISABLED; + + if (!priv->is_internal_short_scan) { + scan->tx_cmd.len = cpu_to_le16( + iwl_fill_probe_req(priv, + (struct ieee80211_mgmt *)scan->data, + vif->addr, + priv->scan_request->ie, + priv->scan_request->ie_len, + IWL_MAX_SCAN_SIZE - sizeof(*scan))); + } else { + /* use bcast addr, will not be transmitted but must be valid */ + scan->tx_cmd.len = cpu_to_le16( + iwl_fill_probe_req(priv, + (struct ieee80211_mgmt *)scan->data, + iwl_bcast_addr, NULL, 0, + IWL_MAX_SCAN_SIZE - sizeof(*scan))); + } + /* select Rx antennas */ + scan->flags |= iwl3945_get_antenna_flags(priv); + + if (priv->is_internal_short_scan) { + scan->channel_count = + iwl3945_get_single_channel_for_scan(priv, vif, band, + (void *)&scan->data[le16_to_cpu( + scan->tx_cmd.len)]); + } else { + scan->channel_count = + iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, + (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif); + } + + if (scan->channel_count == 0) { + IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); + return -EIO; + } + + cmd.len += le16_to_cpu(scan->tx_cmd.len) + + scan->channel_count * sizeof(struct iwl3945_scan_channel); + cmd.data = scan; + scan->len = cpu_to_le16(cmd.len); + + set_bit(STATUS_SCAN_HW, &priv->status); + ret = iwl_send_cmd_sync(priv, &cmd); + if (ret) + clear_bit(STATUS_SCAN_HW, &priv->status); + return ret; +} + +void iwl3945_post_scan(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + /* + * Since setting the RXON may have been deferred while + * performing the scan, fire one off if needed + */ + if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) + iwl3945_commit_rxon(priv, ctx); +} + +static void iwl3945_bg_restart(struct work_struct *data) +{ + struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { + struct iwl_rxon_context *ctx; + mutex_lock(&priv->mutex); + for_each_context(priv, ctx) + ctx->vif = NULL; + priv->is_open = 0; + mutex_unlock(&priv->mutex); + iwl3945_down(priv); + ieee80211_restart_hw(priv->hw); + } else { + iwl3945_down(priv); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + __iwl3945_up(priv); + mutex_unlock(&priv->mutex); + } +} + +static void iwl3945_bg_rx_replenish(struct work_struct *data) +{ + struct iwl_priv *priv = + container_of(data, struct iwl_priv, rx_replenish); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + iwl3945_rx_replenish(priv); + mutex_unlock(&priv->mutex); +} + +void iwl3945_post_associate(struct iwl_priv *priv) +{ + int rc = 0; + struct ieee80211_conf *conf = NULL; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + if (!ctx->vif || !priv->is_open) + return; + + if (ctx->vif->type == NL80211_IFTYPE_AP) { + IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); + return; + } + + IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", + ctx->vif->bss_conf.aid, ctx->active.bssid_addr); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + iwl_scan_cancel_timeout(priv, 200); + + conf = ieee80211_get_hw_conf(priv->hw); + + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwl3945_commit_rxon(priv, ctx); + + rc = iwl_send_rxon_timing(priv, ctx); + if (rc) + IWL_WARN(priv, "REPLY_RXON_TIMING failed - " + "Attempting to continue.\n"); + + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + + ctx->staging.assoc_id = cpu_to_le16(ctx->vif->bss_conf.aid); + + IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", + ctx->vif->bss_conf.aid, ctx->vif->bss_conf.beacon_int); + + if (ctx->vif->bss_conf.use_short_preamble) + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + else + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { + if (ctx->vif->bss_conf.use_short_slot) + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + else + ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + } + + iwl3945_commit_rxon(priv, ctx); + + switch (ctx->vif->type) { + case NL80211_IFTYPE_STATION: + iwl3945_rate_scale_init(priv->hw, IWL_AP_ID); + break; + case NL80211_IFTYPE_ADHOC: + iwl3945_send_beacon_cmd(priv); + break; + default: + IWL_ERR(priv, "%s Should not be called in %d mode\n", + __func__, ctx->vif->type); + break; + } +} + +/***************************************************************************** + * + * mac80211 entry point functions + * + *****************************************************************************/ + +#define UCODE_READY_TIMEOUT (2 * HZ) + +static int iwl3945_mac_start(struct ieee80211_hw *hw) +{ + struct iwl_priv *priv = hw->priv; + int ret; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + /* we should be verifying the device is ready to be opened */ + mutex_lock(&priv->mutex); + + /* fetch ucode file from disk, alloc and copy to bus-master buffers ... + * ucode filename and max sizes are card-specific. */ + + if (!priv->ucode_code.len) { + ret = iwl3945_read_ucode(priv); + if (ret) { + IWL_ERR(priv, "Could not read microcode: %d\n", ret); + mutex_unlock(&priv->mutex); + goto out_release_irq; + } + } + + ret = __iwl3945_up(priv); + + mutex_unlock(&priv->mutex); + + if (ret) + goto out_release_irq; + + IWL_DEBUG_INFO(priv, "Start UP work.\n"); + + /* Wait for START_ALIVE from ucode. Otherwise callbacks from + * mac80211 will not be run successfully. */ + ret = wait_event_interruptible_timeout(priv->wait_command_queue, + test_bit(STATUS_READY, &priv->status), + UCODE_READY_TIMEOUT); + if (!ret) { + if (!test_bit(STATUS_READY, &priv->status)) { + IWL_ERR(priv, + "Wait for START_ALIVE timeout after %dms.\n", + jiffies_to_msecs(UCODE_READY_TIMEOUT)); + ret = -ETIMEDOUT; + goto out_release_irq; + } + } + + /* ucode is running and will send rfkill notifications, + * no need to poll the killswitch state anymore */ + cancel_delayed_work(&priv->_3945.rfkill_poll); + + priv->is_open = 1; + IWL_DEBUG_MAC80211(priv, "leave\n"); + return 0; + +out_release_irq: + priv->is_open = 0; + IWL_DEBUG_MAC80211(priv, "leave - failed\n"); + return ret; +} + +static void iwl3945_mac_stop(struct ieee80211_hw *hw) +{ + struct iwl_priv *priv = hw->priv; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + if (!priv->is_open) { + IWL_DEBUG_MAC80211(priv, "leave - skip\n"); + return; + } + + priv->is_open = 0; + + iwl3945_down(priv); + + flush_workqueue(priv->workqueue); + + /* start polling the killswitch state again */ + queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll, + round_jiffies_relative(2 * HZ)); + + IWL_DEBUG_MAC80211(priv, "leave\n"); +} + +static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct iwl_priv *priv = hw->priv; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, + ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); + + if (iwl3945_tx_skb(priv, skb)) + dev_kfree_skb_any(skb); + + IWL_DEBUG_MAC80211(priv, "leave\n"); + return NETDEV_TX_OK; +} + +void iwl3945_config_ap(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + struct ieee80211_vif *vif = ctx->vif; + int rc = 0; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + /* The following should be done only at AP bring up */ + if (!(iwl_is_associated(priv, IWL_RXON_CTX_BSS))) { + + /* RXON - unassoc (to set timing command) */ + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwl3945_commit_rxon(priv, ctx); + + /* RXON Timing */ + rc = iwl_send_rxon_timing(priv, ctx); + if (rc) + IWL_WARN(priv, "REPLY_RXON_TIMING failed - " + "Attempting to continue.\n"); + + ctx->staging.assoc_id = 0; + + if (vif->bss_conf.use_short_preamble) + ctx->staging.flags |= + RXON_FLG_SHORT_PREAMBLE_MSK; + else + ctx->staging.flags &= + ~RXON_FLG_SHORT_PREAMBLE_MSK; + + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { + if (vif->bss_conf.use_short_slot) + ctx->staging.flags |= + RXON_FLG_SHORT_SLOT_MSK; + else + ctx->staging.flags &= + ~RXON_FLG_SHORT_SLOT_MSK; + } + /* restore RXON assoc */ + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + iwl3945_commit_rxon(priv, ctx); + } + iwl3945_send_beacon_cmd(priv); + + /* FIXME - we need to add code here to detect a totally new + * configuration, reset the AP, unassoc, rxon timing, assoc, + * clear sta table, add BCAST sta... */ +} + +static int iwl3945_mac_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 iwl_priv *priv = hw->priv; + int ret = 0; + u8 sta_id = IWL_INVALID_STATION; + u8 static_key; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + if (iwl3945_mod_params.sw_crypto) { + IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n"); + return -EOPNOTSUPP; + } + + /* + * To support IBSS RSN, don't program group keys in IBSS, the + * hardware will then not attempt to decrypt the frames. + */ + if (vif->type == NL80211_IFTYPE_ADHOC && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) + return -EOPNOTSUPP; + + static_key = !iwl_is_associated(priv, IWL_RXON_CTX_BSS); + + if (!static_key) { + sta_id = iwl_sta_id_or_broadcast( + priv, &priv->contexts[IWL_RXON_CTX_BSS], sta); + if (sta_id == IWL_INVALID_STATION) + return -EINVAL; + } + + mutex_lock(&priv->mutex); + iwl_scan_cancel_timeout(priv, 100); + + switch (cmd) { + case SET_KEY: + if (static_key) + ret = iwl3945_set_static_key(priv, key); + else + ret = iwl3945_set_dynamic_key(priv, key, sta_id); + IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n"); + break; + case DISABLE_KEY: + if (static_key) + ret = iwl3945_remove_static_key(priv); + else + ret = iwl3945_clear_sta_key_info(priv, sta_id); + IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n"); + break; + default: + ret = -EINVAL; + } + + mutex_unlock(&priv->mutex); + IWL_DEBUG_MAC80211(priv, "leave\n"); + + return ret; +} + +static int iwl3945_mac_sta_add(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct iwl_priv *priv = hw->priv; + struct iwl3945_sta_priv *sta_priv = (void *)sta->drv_priv; + int ret; + bool is_ap = vif->type == NL80211_IFTYPE_STATION; + u8 sta_id; + + IWL_DEBUG_INFO(priv, "received request to add station %pM\n", + sta->addr); + mutex_lock(&priv->mutex); + IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", + sta->addr); + sta_priv->common.sta_id = IWL_INVALID_STATION; + + + ret = iwl_add_station_common(priv, &priv->contexts[IWL_RXON_CTX_BSS], + sta->addr, is_ap, sta, &sta_id); + if (ret) { + IWL_ERR(priv, "Unable to add station %pM (%d)\n", + sta->addr, ret); + /* Should we return success if return code is EEXIST ? */ + mutex_unlock(&priv->mutex); + return ret; + } + + sta_priv->common.sta_id = sta_id; + + /* Initialize rate scaling */ + IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", + sta->addr); + iwl3945_rs_rate_init(priv, sta, sta_id); + mutex_unlock(&priv->mutex); + + return 0; +} + +static void iwl3945_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, + u64 multicast) +{ + struct iwl_priv *priv = hw->priv; + __le32 filter_or = 0, filter_nand = 0; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + +#define CHK(test, flag) do { \ + if (*total_flags & (test)) \ + filter_or |= (flag); \ + else \ + filter_nand |= (flag); \ + } while (0) + + IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n", + changed_flags, *total_flags); + + CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); + CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK); + CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); + +#undef CHK + + mutex_lock(&priv->mutex); + + ctx->staging.filter_flags &= ~filter_nand; + ctx->staging.filter_flags |= filter_or; + + /* + * Not committing directly because hardware can perform a scan, + * but even if hw is ready, committing here breaks for some reason, + * we'll eventually commit the filter flags change anyway. + */ + + mutex_unlock(&priv->mutex); + + /* + * Receiving all multicast frames is always enabled by the + * default flags setup in iwl_connection_init_rx_config() + * since we currently do not support programming multicast + * filters into the device. + */ + *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | + FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; +} + + +/***************************************************************************** + * + * sysfs attributes + * + *****************************************************************************/ + +#ifdef CONFIG_IWLWIFI_DEBUG + +/* + * The following adds a new attribute to the sysfs representation + * of this device driver (i.e. a new file in /sys/bus/pci/drivers/iwl/) + * used for controlling the debug level. + * + * See the level definitions in iwl for details. + * + * The debug_level being managed using sysfs below is a per device debug + * level that is used instead of the global debug level if it (the per + * device debug level) is set. + */ +static ssize_t show_debug_level(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + return sprintf(buf, "0x%08X\n", iwl_get_debug_level(priv)); +} +static ssize_t store_debug_level(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + unsigned long val; + int ret; + + ret = strict_strtoul(buf, 0, &val); + if (ret) + IWL_INFO(priv, "%s is not in hex or decimal form.\n", buf); + else { + priv->debug_level = val; + if (iwl_alloc_traffic_mem(priv)) + IWL_ERR(priv, + "Not enough memory to generate traffic log\n"); + } + return strnlen(buf, count); +} + +static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, + show_debug_level, store_debug_level); + +#endif /* CONFIG_IWLWIFI_DEBUG */ + +static ssize_t show_temperature(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + + if (!iwl_is_alive(priv)) + return -EAGAIN; + + return sprintf(buf, "%d\n", iwl3945_hw_get_temperature(priv)); +} + +static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); + +static ssize_t show_tx_power(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + return sprintf(buf, "%d\n", priv->tx_power_user_lmt); +} + +static ssize_t store_tx_power(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + char *p = (char *)buf; + u32 val; + + val = simple_strtoul(p, &p, 10); + if (p == buf) + IWL_INFO(priv, ": %s is not in decimal form.\n", buf); + else + iwl3945_hw_reg_set_txpower(priv, val); + + return count; +} + +static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); + +static ssize_t show_flags(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + return sprintf(buf, "0x%04X\n", ctx->active.flags); +} + +static ssize_t store_flags(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + u32 flags = simple_strtoul(buf, NULL, 0); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + mutex_lock(&priv->mutex); + if (le32_to_cpu(ctx->staging.flags) != flags) { + /* Cancel any currently running scans... */ + if (iwl_scan_cancel_timeout(priv, 100)) + IWL_WARN(priv, "Could not cancel scan.\n"); + else { + IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n", + flags); + ctx->staging.flags = cpu_to_le32(flags); + iwl3945_commit_rxon(priv, ctx); + } + } + mutex_unlock(&priv->mutex); + + return count; +} + +static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags); + +static ssize_t show_filter_flags(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + return sprintf(buf, "0x%04X\n", + le32_to_cpu(ctx->active.filter_flags)); +} + +static ssize_t store_filter_flags(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + u32 filter_flags = simple_strtoul(buf, NULL, 0); + + mutex_lock(&priv->mutex); + if (le32_to_cpu(ctx->staging.filter_flags) != filter_flags) { + /* Cancel any currently running scans... */ + if (iwl_scan_cancel_timeout(priv, 100)) + IWL_WARN(priv, "Could not cancel scan.\n"); + else { + IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = " + "0x%04X\n", filter_flags); + ctx->staging.filter_flags = + cpu_to_le32(filter_flags); + iwl3945_commit_rxon(priv, ctx); + } + } + mutex_unlock(&priv->mutex); + + return count; +} + +static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, + store_filter_flags); + +static ssize_t show_measurement(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl_spectrum_notification measure_report; + u32 size = sizeof(measure_report), len = 0, ofs = 0; + u8 *data = (u8 *)&measure_report; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + if (!(priv->measurement_status & MEASUREMENT_READY)) { + spin_unlock_irqrestore(&priv->lock, flags); + return 0; + } + memcpy(&measure_report, &priv->measure_report, size); + priv->measurement_status = 0; + spin_unlock_irqrestore(&priv->lock, flags); + + while (size && (PAGE_SIZE - len)) { + hex_dump_to_buffer(data + ofs, size, 16, 1, buf + len, + PAGE_SIZE - len, 1); + len = strlen(buf); + if (PAGE_SIZE - len) + buf[len++] = '\n'; + + ofs += 16; + size -= min(size, 16U); + } + + return len; +} + +static ssize_t store_measurement(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + struct ieee80211_measurement_params params = { + .channel = le16_to_cpu(ctx->active.channel), + .start_time = cpu_to_le64(priv->_3945.last_tsf), + .duration = cpu_to_le16(1), + }; + u8 type = IWL_MEASURE_BASIC; + u8 buffer[32]; + u8 channel; + + if (count) { + char *p = buffer; + strncpy(buffer, buf, min(sizeof(buffer), count)); + channel = simple_strtoul(p, NULL, 0); + if (channel) + params.channel = channel; + + p = buffer; + while (*p && *p != ' ') + p++; + if (*p) + type = simple_strtoul(p + 1, NULL, 0); + } + + IWL_DEBUG_INFO(priv, "Invoking measurement of type %d on " + "channel %d (for '%s')\n", type, params.channel, buf); + iwl3945_get_measurement(priv, ¶ms, type); + + return count; +} + +static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR, + show_measurement, store_measurement); + +static ssize_t store_retry_rate(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + + priv->retry_rate = simple_strtoul(buf, NULL, 0); + if (priv->retry_rate <= 0) + priv->retry_rate = 1; + + return count; +} + +static ssize_t show_retry_rate(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + return sprintf(buf, "%d", priv->retry_rate); +} + +static DEVICE_ATTR(retry_rate, S_IWUSR | S_IRUSR, show_retry_rate, + store_retry_rate); + + +static ssize_t show_channels(struct device *d, + struct device_attribute *attr, char *buf) +{ + /* all this shit doesn't belong into sysfs anyway */ + return 0; +} + +static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); + +static ssize_t show_antenna(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + + if (!iwl_is_alive(priv)) + return -EAGAIN; + + return sprintf(buf, "%d\n", iwl3945_mod_params.antenna); +} + +static ssize_t store_antenna(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv __maybe_unused = dev_get_drvdata(d); + int ant; + + if (count == 0) + return 0; + + if (sscanf(buf, "%1i", &ant) != 1) { + IWL_DEBUG_INFO(priv, "not in hex or decimal form.\n"); + return count; + } + + if ((ant >= 0) && (ant <= 2)) { + IWL_DEBUG_INFO(priv, "Setting antenna select to %d.\n", ant); + iwl3945_mod_params.antenna = (enum iwl3945_antenna)ant; + } else + IWL_DEBUG_INFO(priv, "Bad antenna select value %d.\n", ant); + + + return count; +} + +static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, show_antenna, store_antenna); + +static ssize_t show_status(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + if (!iwl_is_alive(priv)) + return -EAGAIN; + return sprintf(buf, "0x%08x\n", (int)priv->status); +} + +static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); + +static ssize_t dump_error_log(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + char *p = (char *)buf; + + if (p[0] == '1') + iwl3945_dump_nic_error_log(priv); + + return strnlen(buf, count); +} + +static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, dump_error_log); + +/***************************************************************************** + * + * driver setup and tear down + * + *****************************************************************************/ + +static void iwl3945_setup_deferred_work(struct iwl_priv *priv) +{ + priv->workqueue = create_singlethread_workqueue(DRV_NAME); + + init_waitqueue_head(&priv->wait_command_queue); + + INIT_WORK(&priv->restart, iwl3945_bg_restart); + INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); + INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); + INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); + INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); + INIT_DELAYED_WORK(&priv->_3945.rfkill_poll, iwl3945_rfkill_poll); + + iwl_setup_scan_deferred_work(priv); + + iwl3945_hw_setup_deferred_work(priv); + + init_timer(&priv->watchdog); + priv->watchdog.data = (unsigned long)priv; + priv->watchdog.function = iwl_bg_watchdog; + + tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) + iwl3945_irq_tasklet, (unsigned long)priv); +} + +static void iwl3945_cancel_deferred_work(struct iwl_priv *priv) +{ + iwl3945_hw_cancel_deferred_work(priv); + + cancel_delayed_work_sync(&priv->init_alive_start); + cancel_delayed_work(&priv->alive_start); + cancel_work_sync(&priv->beacon_update); + + iwl_cancel_scan_deferred_work(priv); +} + +static struct attribute *iwl3945_sysfs_entries[] = { + &dev_attr_antenna.attr, + &dev_attr_channels.attr, + &dev_attr_dump_errors.attr, + &dev_attr_flags.attr, + &dev_attr_filter_flags.attr, + &dev_attr_measurement.attr, + &dev_attr_retry_rate.attr, + &dev_attr_status.attr, + &dev_attr_temperature.attr, + &dev_attr_tx_power.attr, +#ifdef CONFIG_IWLWIFI_DEBUG + &dev_attr_debug_level.attr, +#endif + NULL +}; + +static struct attribute_group iwl3945_attribute_group = { + .name = NULL, /* put in device directory */ + .attrs = iwl3945_sysfs_entries, +}; + +struct ieee80211_ops iwl3945_hw_ops = { + .tx = iwl3945_mac_tx, + .start = iwl3945_mac_start, + .stop = iwl3945_mac_stop, + .add_interface = iwl_mac_add_interface, + .remove_interface = iwl_mac_remove_interface, + .change_interface = iwl_mac_change_interface, + .config = iwl_legacy_mac_config, + .configure_filter = iwl3945_configure_filter, + .set_key = iwl3945_mac_set_key, + .conf_tx = iwl_mac_conf_tx, + .reset_tsf = iwl_legacy_mac_reset_tsf, + .bss_info_changed = iwl_legacy_mac_bss_info_changed, + .hw_scan = iwl_mac_hw_scan, + .sta_add = iwl3945_mac_sta_add, + .sta_remove = iwl_mac_sta_remove, + .tx_last_beacon = iwl_mac_tx_last_beacon, +}; + +static int iwl3945_init_drv(struct iwl_priv *priv) +{ + int ret; + struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; + + priv->retry_rate = 1; + priv->beacon_skb = NULL; + + spin_lock_init(&priv->sta_lock); + spin_lock_init(&priv->hcmd_lock); + + INIT_LIST_HEAD(&priv->free_frames); + + mutex_init(&priv->mutex); + mutex_init(&priv->sync_cmd_mutex); + + priv->ieee_channels = NULL; + priv->ieee_rates = NULL; + priv->band = IEEE80211_BAND_2GHZ; + + priv->iw_mode = NL80211_IFTYPE_STATION; + priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; + + /* initialize force reset */ + priv->force_reset[IWL_RF_RESET].reset_duration = + IWL_DELAY_NEXT_FORCE_RF_RESET; + priv->force_reset[IWL_FW_RESET].reset_duration = + IWL_DELAY_NEXT_FORCE_FW_RELOAD; + + + priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER; + priv->tx_power_next = IWL_DEFAULT_TX_POWER; + + if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { + IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n", + eeprom->version); + ret = -EINVAL; + goto err; + } + ret = iwl_init_channel_map(priv); + if (ret) { + IWL_ERR(priv, "initializing regulatory failed: %d\n", ret); + goto err; + } + + /* Set up txpower settings in driver for all channels */ + if (iwl3945_txpower_set_from_eeprom(priv)) { + ret = -EIO; + goto err_free_channel_map; + } + + ret = iwlcore_init_geos(priv); + if (ret) { + IWL_ERR(priv, "initializing geos failed: %d\n", ret); + goto err_free_channel_map; + } + iwl3945_init_hw_rates(priv, priv->ieee_rates); + + return 0; + +err_free_channel_map: + iwl_free_channel_map(priv); +err: + return ret; +} + +#define IWL3945_MAX_PROBE_REQUEST 200 + +static int iwl3945_setup_mac(struct iwl_priv *priv) +{ + int ret; + struct ieee80211_hw *hw = priv->hw; + + hw->rate_control_algorithm = "iwl-3945-rs"; + hw->sta_data_size = sizeof(struct iwl3945_sta_priv); + hw->vif_data_size = sizeof(struct iwl_vif_priv); + + /* Tell mac80211 our characteristics */ + hw->flags = IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_SPECTRUM_MGMT; + + if (!priv->cfg->base_params->broken_powersave) + hw->flags |= IEEE80211_HW_SUPPORTS_PS | + IEEE80211_HW_SUPPORTS_DYNAMIC_PS; + + hw->wiphy->interface_modes = + priv->contexts[IWL_RXON_CTX_BSS].interface_modes; + + hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | + WIPHY_FLAG_DISABLE_BEACON_HINTS | + WIPHY_FLAG_IBSS_RSN; + + hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; + /* we create the 802.11 header and a zero-length SSID element */ + hw->wiphy->max_scan_ie_len = IWL3945_MAX_PROBE_REQUEST - 24 - 2; + + /* Default value; 4 EDCA QOS priorities */ + hw->queues = 4; + + if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) + priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = + &priv->bands[IEEE80211_BAND_2GHZ]; + + if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) + priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = + &priv->bands[IEEE80211_BAND_5GHZ]; + + iwl_leds_init(priv); + + ret = ieee80211_register_hw(priv->hw); + if (ret) { + IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); + return ret; + } + priv->mac80211_registered = 1; + + return 0; +} + +static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int err = 0, i; + struct iwl_priv *priv; + struct ieee80211_hw *hw; + struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); + struct iwl3945_eeprom *eeprom; + unsigned long flags; + + /*********************** + * 1. Allocating HW data + * ********************/ + + /* mac80211 allocates memory for this device instance, including + * space for this driver's private structure */ + hw = iwl_alloc_all(cfg); + if (hw == NULL) { + pr_err("Can not allocate network device\n"); + err = -ENOMEM; + goto out; + } + priv = hw->priv; + SET_IEEE80211_DEV(hw, &pdev->dev); + + priv->cmd_queue = IWL39_CMD_QUEUE_NUM; + + /* 3945 has only one valid context */ + priv->valid_contexts = BIT(IWL_RXON_CTX_BSS); + + for (i = 0; i < NUM_IWL_RXON_CTX; i++) + priv->contexts[i].ctxid = i; + + priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON; + priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING; + priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; + priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; + priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; + priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; + priv->contexts[IWL_RXON_CTX_BSS].interface_modes = + BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC); + priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS; + priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS; + priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS; + + /* + * Disabling hardware scan means that mac80211 will perform scans + * "the hard way", rather than using device's scan. + */ + if (iwl3945_mod_params.disable_hw_scan) { + dev_printk(KERN_DEBUG, &(pdev->dev), + "sw scan support is deprecated\n"); + iwl3945_hw_ops.hw_scan = NULL; + } + + + IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); + priv->cfg = cfg; + priv->pci_dev = pdev; + priv->inta_mask = CSR_INI_SET_MASK; + + if (iwl_alloc_traffic_mem(priv)) + IWL_ERR(priv, "Not enough memory to generate traffic log\n"); + + /*************************** + * 2. Initializing PCI bus + * *************************/ + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | + PCIE_LINK_STATE_CLKPM); + + if (pci_enable_device(pdev)) { + err = -ENODEV; + goto out_ieee80211_free_hw; + } + + pci_set_master(pdev); + + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (!err) + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); + if (err) { + IWL_WARN(priv, "No suitable DMA available.\n"); + goto out_pci_disable_device; + } + + pci_set_drvdata(pdev, priv); + err = pci_request_regions(pdev, DRV_NAME); + if (err) + goto out_pci_disable_device; + + /*********************** + * 3. Read REV Register + * ********************/ + priv->hw_base = pci_iomap(pdev, 0, 0); + if (!priv->hw_base) { + err = -ENODEV; + goto out_pci_release_regions; + } + + IWL_DEBUG_INFO(priv, "pci_resource_len = 0x%08llx\n", + (unsigned long long) pci_resource_len(pdev, 0)); + IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base); + + /* We disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state */ + pci_write_config_byte(pdev, 0x41, 0x00); + + /* these spin locks will be used in apm_ops.init and EEPROM access + * we should init now + */ + spin_lock_init(&priv->reg_lock); + spin_lock_init(&priv->lock); + + /* + * stop and reset the on-board processor just in case it is in a + * strange state ... like being left stranded by a primary kernel + * and this is now the kdump kernel trying to start up + */ + iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); + + /*********************** + * 4. Read EEPROM + * ********************/ + + /* Read the EEPROM */ + err = iwl_eeprom_init(priv); + if (err) { + IWL_ERR(priv, "Unable to init EEPROM\n"); + goto out_iounmap; + } + /* MAC Address location in EEPROM same for 3945/4965 */ + eeprom = (struct iwl3945_eeprom *)priv->eeprom; + IWL_DEBUG_INFO(priv, "MAC address: %pM\n", eeprom->mac_address); + SET_IEEE80211_PERM_ADDR(priv->hw, eeprom->mac_address); + + /*********************** + * 5. Setup HW Constants + * ********************/ + /* Device-specific setup */ + if (iwl3945_hw_set_hw_params(priv)) { + IWL_ERR(priv, "failed to set hw settings\n"); + goto out_eeprom_free; + } + + /*********************** + * 6. Setup priv + * ********************/ + + err = iwl3945_init_drv(priv); + if (err) { + IWL_ERR(priv, "initializing driver failed\n"); + goto out_unset_hw_params; + } + + IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s\n", + priv->cfg->name); + + /*********************** + * 7. Setup Services + * ********************/ + + spin_lock_irqsave(&priv->lock, flags); + iwl_disable_interrupts(priv); + spin_unlock_irqrestore(&priv->lock, flags); + + pci_enable_msi(priv->pci_dev); + + err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr_ops.isr, + IRQF_SHARED, DRV_NAME, priv); + if (err) { + IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); + goto out_disable_msi; + } + + err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group); + if (err) { + IWL_ERR(priv, "failed to create sysfs device attributes\n"); + goto out_release_irq; + } + + iwl_set_rxon_channel(priv, + &priv->bands[IEEE80211_BAND_2GHZ].channels[5], + &priv->contexts[IWL_RXON_CTX_BSS]); + iwl3945_setup_deferred_work(priv); + iwl3945_setup_rx_handlers(priv); + iwl_power_initialize(priv); + + /********************************* + * 8. Setup and Register mac80211 + * *******************************/ + + iwl_enable_interrupts(priv); + + err = iwl3945_setup_mac(priv); + if (err) + goto out_remove_sysfs; + + err = iwl_dbgfs_register(priv, DRV_NAME); + if (err) + IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); + + /* Start monitoring the killswitch */ + queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll, + 2 * HZ); + + return 0; + + out_remove_sysfs: + destroy_workqueue(priv->workqueue); + priv->workqueue = NULL; + sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); + out_release_irq: + free_irq(priv->pci_dev->irq, priv); + out_disable_msi: + pci_disable_msi(priv->pci_dev); + iwlcore_free_geos(priv); + iwl_free_channel_map(priv); + out_unset_hw_params: + iwl3945_unset_hw_params(priv); + out_eeprom_free: + iwl_eeprom_free(priv); + out_iounmap: + pci_iounmap(pdev, priv->hw_base); + out_pci_release_regions: + pci_release_regions(pdev); + out_pci_disable_device: + pci_set_drvdata(pdev, NULL); + pci_disable_device(pdev); + out_ieee80211_free_hw: + iwl_free_traffic_mem(priv); + ieee80211_free_hw(priv->hw); + out: + return err; +} + +static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) +{ + struct iwl_priv *priv = pci_get_drvdata(pdev); + unsigned long flags; + + if (!priv) + return; + + IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); + + iwl_dbgfs_unregister(priv); + + set_bit(STATUS_EXIT_PENDING, &priv->status); + + iwl_leds_exit(priv); + + if (priv->mac80211_registered) { + ieee80211_unregister_hw(priv->hw); + priv->mac80211_registered = 0; + } else { + iwl3945_down(priv); + } + + /* + * Make sure device is reset to low power before unloading driver. + * This may be redundant with iwl_down(), but there are paths to + * run iwl_down() without calling apm_ops.stop(), and there are + * paths to avoid running iwl_down() at all before leaving driver. + * This (inexpensive) call *makes sure* device is reset. + */ + iwl_apm_stop(priv); + + /* make sure we flush any pending irq or + * tasklet for the driver + */ + spin_lock_irqsave(&priv->lock, flags); + iwl_disable_interrupts(priv); + spin_unlock_irqrestore(&priv->lock, flags); + + iwl_synchronize_irq(priv); + + sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); + + cancel_delayed_work_sync(&priv->_3945.rfkill_poll); + + iwl3945_dealloc_ucode_pci(priv); + + if (priv->rxq.bd) + iwl3945_rx_queue_free(priv, &priv->rxq); + iwl3945_hw_txq_ctx_free(priv); + + iwl3945_unset_hw_params(priv); + + /*netif_stop_queue(dev); */ + flush_workqueue(priv->workqueue); + + /* ieee80211_unregister_hw calls iwl3945_mac_stop, which flushes + * priv->workqueue... so we can't take down the workqueue + * until now... */ + destroy_workqueue(priv->workqueue); + priv->workqueue = NULL; + iwl_free_traffic_mem(priv); + + free_irq(pdev->irq, priv); + pci_disable_msi(pdev); + + pci_iounmap(pdev, priv->hw_base); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + + iwl_free_channel_map(priv); + iwlcore_free_geos(priv); + kfree(priv->scan_cmd); + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); + + ieee80211_free_hw(priv->hw); +} + + +/***************************************************************************** + * + * driver and module entry point + * + *****************************************************************************/ + +static struct pci_driver iwl3945_driver = { + .name = DRV_NAME, + .id_table = iwl3945_hw_card_ids, + .probe = iwl3945_pci_probe, + .remove = __devexit_p(iwl3945_pci_remove), + .driver.pm = IWL_PM_OPS, +}; + +static int __init iwl3945_init(void) +{ + + int ret; + pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); + pr_info(DRV_COPYRIGHT "\n"); + + ret = iwl3945_rate_control_register(); + if (ret) { + pr_err("Unable to register rate control algorithm: %d\n", ret); + return ret; + } + + ret = pci_register_driver(&iwl3945_driver); + if (ret) { + pr_err("Unable to initialize PCI module\n"); + goto error_register; + } + + return ret; + +error_register: + iwl3945_rate_control_unregister(); + return ret; +} + +static void __exit iwl3945_exit(void) +{ + pci_unregister_driver(&iwl3945_driver); + iwl3945_rate_control_unregister(); +} + +MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX)); + +module_param_named(antenna, iwl3945_mod_params.antenna, int, S_IRUGO); +MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); +module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, S_IRUGO); +MODULE_PARM_DESC(swcrypto, + "using software crypto (default 1 [software])\n"); +#ifdef CONFIG_IWLWIFI_DEBUG +module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "debug output mask"); +#endif +module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, + int, S_IRUGO); +MODULE_PARM_DESC(disable_hw_scan, + "disable hardware scanning (default 0) (deprecated)"); +module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, S_IRUGO); +MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error"); + +module_exit(iwl3945_exit); +module_init(iwl3945_init); -- cgit v1.2.3 From be663ab67077fac8e23eb8e231a8c1c94cb32e54 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 21 Feb 2011 11:27:26 -0800 Subject: iwlwifi: split the drivers for agn and legacy devices 3945/4965 Intel WiFi devices 3945 and 4965 now have their own driver in the folder drivers/net/wireless/iwlegacy Add support to build these drivers independently of the driver for AGN devices. Selecting the 3945 builds iwl3945.ko and iwl_legacy.ko, and selecting the 4965 builds iwl4965.ko and iwl_legacy.ko. iwl-legacy.ko contains code shared between both devices. The 3945 is an ABG/BG device, with no support for 802.11n. The 4965 is a 2x3 ABGN device. Signed-off-by: Meenakshi Venkataraman Acked-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/Kconfig | 1 + drivers/net/wireless/Makefile | 3 +- drivers/net/wireless/iwlegacy/Kconfig | 116 + drivers/net/wireless/iwlegacy/Makefile | 25 + drivers/net/wireless/iwlegacy/iwl-3945-debugfs.c | 523 +++ drivers/net/wireless/iwlegacy/iwl-3945-debugfs.h | 60 + drivers/net/wireless/iwlegacy/iwl-3945-fh.h | 187 + drivers/net/wireless/iwlegacy/iwl-3945-hw.h | 293 ++ drivers/net/wireless/iwlegacy/iwl-3945-led.c | 64 + drivers/net/wireless/iwlegacy/iwl-3945-led.h | 32 + drivers/net/wireless/iwlegacy/iwl-3945-rs.c | 994 +++++ drivers/net/wireless/iwlegacy/iwl-3945.c | 2744 ++++++++++++++ drivers/net/wireless/iwlegacy/iwl-3945.h | 308 ++ drivers/net/wireless/iwlegacy/iwl-4965-calib.c | 967 +++++ drivers/net/wireless/iwlegacy/iwl-4965-calib.h | 75 + drivers/net/wireless/iwlegacy/iwl-4965-debugfs.c | 774 ++++ drivers/net/wireless/iwlegacy/iwl-4965-debugfs.h | 59 + drivers/net/wireless/iwlegacy/iwl-4965-eeprom.c | 154 + drivers/net/wireless/iwlegacy/iwl-4965-hw.h | 814 ++++ drivers/net/wireless/iwlegacy/iwl-4965-led.c | 74 + drivers/net/wireless/iwlegacy/iwl-4965-led.h | 33 + drivers/net/wireless/iwlegacy/iwl-4965-lib.c | 1260 +++++++ drivers/net/wireless/iwlegacy/iwl-4965-rs.c | 2870 ++++++++++++++ drivers/net/wireless/iwlegacy/iwl-4965-rx.c | 291 ++ drivers/net/wireless/iwlegacy/iwl-4965-sta.c | 720 ++++ drivers/net/wireless/iwlegacy/iwl-4965-tx.c | 1359 +++++++ drivers/net/wireless/iwlegacy/iwl-4965-ucode.c | 166 + drivers/net/wireless/iwlegacy/iwl-4965.c | 2188 +++++++++++ drivers/net/wireless/iwlegacy/iwl-4965.h | 282 ++ drivers/net/wireless/iwlegacy/iwl-commands.h | 3405 +++++++++++++++++ drivers/net/wireless/iwlegacy/iwl-core.c | 2668 +++++++++++++ drivers/net/wireless/iwlegacy/iwl-core.h | 646 ++++ drivers/net/wireless/iwlegacy/iwl-csr.h | 422 +++ drivers/net/wireless/iwlegacy/iwl-debug.h | 198 + drivers/net/wireless/iwlegacy/iwl-debugfs.c | 1467 ++++++++ drivers/net/wireless/iwlegacy/iwl-dev.h | 1426 +++++++ drivers/net/wireless/iwlegacy/iwl-devtrace.c | 45 + drivers/net/wireless/iwlegacy/iwl-devtrace.h | 270 ++ drivers/net/wireless/iwlegacy/iwl-eeprom.c | 561 +++ drivers/net/wireless/iwlegacy/iwl-eeprom.h | 344 ++ drivers/net/wireless/iwlegacy/iwl-fh.h | 513 +++ drivers/net/wireless/iwlegacy/iwl-hcmd.c | 271 ++ drivers/net/wireless/iwlegacy/iwl-helpers.h | 181 + drivers/net/wireless/iwlegacy/iwl-io.h | 545 +++ drivers/net/wireless/iwlegacy/iwl-led.c | 188 + drivers/net/wireless/iwlegacy/iwl-led.h | 56 + drivers/net/wireless/iwlegacy/iwl-legacy-rs.h | 456 +++ drivers/net/wireless/iwlegacy/iwl-power.c | 165 + drivers/net/wireless/iwlegacy/iwl-power.h | 55 + drivers/net/wireless/iwlegacy/iwl-prph.h | 523 +++ drivers/net/wireless/iwlegacy/iwl-rx.c | 302 ++ drivers/net/wireless/iwlegacy/iwl-scan.c | 625 ++++ drivers/net/wireless/iwlegacy/iwl-spectrum.h | 92 + drivers/net/wireless/iwlegacy/iwl-sta.c | 816 ++++ drivers/net/wireless/iwlegacy/iwl-sta.h | 148 + drivers/net/wireless/iwlegacy/iwl-tx.c | 637 ++++ drivers/net/wireless/iwlegacy/iwl3945-base.c | 4294 +++++++++++++++++++++ drivers/net/wireless/iwlegacy/iwl4965-base.c | 3633 ++++++++++++++++++ drivers/net/wireless/iwlwifi/Kconfig | 124 +- drivers/net/wireless/iwlwifi/Makefile | 39 +- drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c | 522 --- drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h | 60 - drivers/net/wireless/iwlwifi/iwl-3945-fh.h | 188 - drivers/net/wireless/iwlwifi/iwl-3945-hw.h | 294 -- drivers/net/wireless/iwlwifi/iwl-3945-led.c | 64 - drivers/net/wireless/iwlwifi/iwl-3945-led.h | 32 - drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 995 ----- drivers/net/wireless/iwlwifi/iwl-3945.c | 2819 -------------- drivers/net/wireless/iwlwifi/iwl-3945.h | 308 -- drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 792 ---- drivers/net/wireless/iwlwifi/iwl-4965.c | 2666 ------------- drivers/net/wireless/iwlwifi/iwl-agn.c | 18 - drivers/net/wireless/iwlwifi/iwl-core.c | 54 - drivers/net/wireless/iwlwifi/iwl-debugfs.c | 2 - drivers/net/wireless/iwlwifi/iwl-dev.h | 4 +- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 8 - drivers/net/wireless/iwlwifi/iwl-hcmd.c | 5 - drivers/net/wireless/iwlwifi/iwl-led.c | 2 - drivers/net/wireless/iwlwifi/iwl-legacy.c | 657 ---- drivers/net/wireless/iwlwifi/iwl-legacy.h | 79 - drivers/net/wireless/iwlwifi/iwl-power.c | 3 - drivers/net/wireless/iwlwifi/iwl-rx.c | 6 - drivers/net/wireless/iwlwifi/iwl-scan.c | 10 - drivers/net/wireless/iwlwifi/iwl-sta.c | 11 - drivers/net/wireless/iwlwifi/iwl-tx.c | 7 - drivers/net/wireless/iwlwifi/iwl3945-base.c | 4334 ---------------------- 86 files changed, 42445 insertions(+), 14046 deletions(-) create mode 100644 drivers/net/wireless/iwlegacy/Kconfig create mode 100644 drivers/net/wireless/iwlegacy/Makefile create mode 100644 drivers/net/wireless/iwlegacy/iwl-3945-debugfs.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-3945-debugfs.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-3945-fh.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-3945-hw.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-3945-led.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-3945-led.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-3945-rs.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-3945.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-3945.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-4965-calib.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-4965-calib.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-4965-debugfs.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-4965-debugfs.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-4965-eeprom.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-4965-hw.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-4965-led.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-4965-led.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-4965-lib.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-4965-rs.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-4965-rx.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-4965-sta.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-4965-tx.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-4965-ucode.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-4965.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-4965.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-commands.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-core.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-core.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-csr.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-debug.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-debugfs.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-dev.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-devtrace.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-devtrace.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-eeprom.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-eeprom.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-fh.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-hcmd.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-helpers.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-io.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-led.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-led.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-legacy-rs.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-power.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-power.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-prph.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-rx.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-scan.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-spectrum.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-sta.c create mode 100644 drivers/net/wireless/iwlegacy/iwl-sta.h create mode 100644 drivers/net/wireless/iwlegacy/iwl-tx.c create mode 100644 drivers/net/wireless/iwlegacy/iwl3945-base.c create mode 100644 drivers/net/wireless/iwlegacy/iwl4965-base.c delete mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c delete mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h delete mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-fh.h delete mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-hw.h delete mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-led.c delete mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-led.h delete mode 100644 drivers/net/wireless/iwlwifi/iwl-3945-rs.c delete mode 100644 drivers/net/wireless/iwlwifi/iwl-3945.c delete mode 100644 drivers/net/wireless/iwlwifi/iwl-3945.h delete mode 100644 drivers/net/wireless/iwlwifi/iwl-4965-hw.h delete mode 100644 drivers/net/wireless/iwlwifi/iwl-4965.c delete mode 100644 drivers/net/wireless/iwlwifi/iwl-legacy.c delete mode 100644 drivers/net/wireless/iwlwifi/iwl-legacy.h delete mode 100644 drivers/net/wireless/iwlwifi/iwl3945-base.c (limited to 'drivers') diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index b4338f389394..7aeb113cbb90 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -274,6 +274,7 @@ source "drivers/net/wireless/b43legacy/Kconfig" source "drivers/net/wireless/hostap/Kconfig" source "drivers/net/wireless/ipw2x00/Kconfig" source "drivers/net/wireless/iwlwifi/Kconfig" +source "drivers/net/wireless/iwlegacy/Kconfig" source "drivers/net/wireless/iwmc3200wifi/Kconfig" source "drivers/net/wireless/libertas/Kconfig" source "drivers/net/wireless/orinoco/Kconfig" diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 9760561a27a5..cd0c7e2aed43 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -41,7 +41,8 @@ obj-$(CONFIG_ADM8211) += adm8211.o obj-$(CONFIG_MWL8K) += mwl8k.o -obj-$(CONFIG_IWLWIFI) += iwlwifi/ +obj-$(CONFIG_IWLAGN) += iwlwifi/ +obj-$(CONFIG_IWLWIFI_LEGACY) += iwlegacy/ obj-$(CONFIG_RT2X00) += rt2x00/ obj-$(CONFIG_P54_COMMON) += p54/ diff --git a/drivers/net/wireless/iwlegacy/Kconfig b/drivers/net/wireless/iwlegacy/Kconfig new file mode 100644 index 000000000000..2a45dd44cc12 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/Kconfig @@ -0,0 +1,116 @@ +config IWLWIFI_LEGACY + tristate "Intel Wireless Wifi legacy devices" + depends on PCI && MAC80211 + select FW_LOADER + select NEW_LEDS + select LEDS_CLASS + select LEDS_TRIGGERS + select MAC80211_LEDS + +menu "Debugging Options" + depends on IWLWIFI_LEGACY + +config IWLWIFI_LEGACY_DEBUG + bool "Enable full debugging output in 4965 and 3945 drivers" + depends on IWLWIFI_LEGACY + ---help--- + This option will enable debug tracing output for the iwlwifilegacy + drivers. + + This will result in the kernel module being ~100k larger. You can + control which debug output is sent to the kernel log by setting the + value in + + /sys/class/net/wlan0/device/debug_level + + This entry will only exist if this option is enabled. + + To set a value, simply echo an 8-byte hex value to the same file: + + % echo 0x43fff > /sys/class/net/wlan0/device/debug_level + + You can find the list of debug mask values in: + drivers/net/wireless/iwlwifilegacy/iwl-debug.h + + If this is your first time using this driver, you should say Y here + as the debug information can assist others in helping you resolve + any problems you may encounter. + +config IWLWIFI_LEGACY_DEBUGFS + bool "4965 and 3945 debugfs support" + depends on IWLWIFI_LEGACY && MAC80211_DEBUGFS + ---help--- + Enable creation of debugfs files for the iwlwifilegacy drivers. This + is a low-impact option that allows getting insight into the + driver's state at runtime. + +config IWLWIFI_LEGACY_DEVICE_TRACING + bool "iwlwifilegacy legacy device access tracing" + depends on IWLWIFI_LEGACY + depends on EVENT_TRACING + help + Say Y here to trace all commands, including TX frames and IO + accesses, sent to the device. If you say yes, iwlwifilegacy will + register with the ftrace framework for event tracing and dump + all this information to the ringbuffer, you may need to + increase the ringbuffer size. See the ftrace documentation + for more information. + + When tracing is not enabled, this option still has some + (though rather small) overhead. + + If unsure, say Y so we can help you better when problems + occur. +endmenu + +config IWL4965 + tristate "Intel Wireless WiFi 4965AGN (iwl4965)" + depends on IWLWIFI_LEGACY + ---help--- + This option enables support for + + Select to build the driver supporting the: + + Intel Wireless WiFi Link 4965AGN + + This driver uses the kernel's mac80211 subsystem. + + In order to use this driver, you will need a microcode (uCode) + image for it. You can obtain the microcode from: + + . + + The microcode is typically installed in /lib/firmware. You can + look in the hotplug script /etc/hotplug/firmware.agent to + determine which directory FIRMWARE_DIR is set to when the script + runs. + + If you want to compile the driver as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read . The + module will be called iwl4965. + +config IWL3945 + tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)" + depends on IWLWIFI_LEGACY + ---help--- + Select to build the driver supporting the: + + Intel PRO/Wireless 3945ABG/BG Network Connection + + This driver uses the kernel's mac80211 subsystem. + + In order to use this driver, you will need a microcode (uCode) + image for it. You can obtain the microcode from: + + . + + The microcode is typically installed in /lib/firmware. You can + look in the hotplug script /etc/hotplug/firmware.agent to + determine which directory FIRMWARE_DIR is set to when the script + runs. + + If you want to compile the driver as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read . The + module will be called iwl3945. diff --git a/drivers/net/wireless/iwlegacy/Makefile b/drivers/net/wireless/iwlegacy/Makefile new file mode 100644 index 000000000000..d56aeb38c211 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/Makefile @@ -0,0 +1,25 @@ +obj-$(CONFIG_IWLWIFI_LEGACY) += iwl-legacy.o +iwl-legacy-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o +iwl-legacy-objs += iwl-rx.o iwl-tx.o iwl-sta.o +iwl-legacy-objs += iwl-scan.o iwl-led.o +iwl-legacy-$(CONFIG_IWLWIFI_LEGACY_DEBUGFS) += iwl-debugfs.o +iwl-legacy-$(CONFIG_IWLWIFI_LEGACY_DEVICE_TRACING) += iwl-devtrace.o + +iwl-legacy-objs += $(iwl-legacy-m) + +CFLAGS_iwl-devtrace.o := -I$(src) + +# 4965 +obj-$(CONFIG_IWL4965) += iwl4965.o +iwl4965-objs := iwl-4965.o iwl4965-base.o iwl-4965-rs.o iwl-4965-led.o +iwl4965-objs += iwl-4965-ucode.o iwl-4965-tx.o +iwl4965-objs += iwl-4965-lib.o iwl-4965-rx.o iwl-4965-calib.o +iwl4965-objs += iwl-4965-sta.o iwl-4965-eeprom.o +iwl4965-$(CONFIG_IWLWIFI_LEGACY_DEBUGFS) += iwl-4965-debugfs.o + +# 3945 +obj-$(CONFIG_IWL3945) += iwl3945.o +iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o +iwl3945-$(CONFIG_IWLWIFI_LEGACY_DEBUGFS) += iwl-3945-debugfs.o + +ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/iwlegacy/iwl-3945-debugfs.c b/drivers/net/wireless/iwlegacy/iwl-3945-debugfs.c new file mode 100644 index 000000000000..cfabb38793ab --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-3945-debugfs.c @@ -0,0 +1,523 @@ +/****************************************************************************** + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ + +#include "iwl-3945-debugfs.h" + + +static int iwl3945_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) +{ + int p = 0; + + p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", + le32_to_cpu(priv->_3945.statistics.flag)); + if (le32_to_cpu(priv->_3945.statistics.flag) & + UCODE_STATISTICS_CLEAR_MSK) + p += scnprintf(buf + p, bufsz - p, + "\tStatistics have been cleared\n"); + p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n", + (le32_to_cpu(priv->_3945.statistics.flag) & + UCODE_STATISTICS_FREQUENCY_MSK) + ? "2.4 GHz" : "5.2 GHz"); + p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n", + (le32_to_cpu(priv->_3945.statistics.flag) & + UCODE_STATISTICS_NARROW_BAND_MSK) + ? "enabled" : "disabled"); + return p; +} + +ssize_t iwl3945_ucode_rx_stats_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + int pos = 0; + char *buf; + int bufsz = sizeof(struct iwl39_statistics_rx_phy) * 40 + + sizeof(struct iwl39_statistics_rx_non_phy) * 40 + 400; + ssize_t ret; + struct iwl39_statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, + *max_ofdm; + struct iwl39_statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck; + struct iwl39_statistics_rx_non_phy *general, *accum_general; + struct iwl39_statistics_rx_non_phy *delta_general, *max_general; + + if (!iwl_legacy_is_alive(priv)) + return -EAGAIN; + + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate Buffer\n"); + return -ENOMEM; + } + + /* + * The statistic information display here is based on + * the last statistics notification from uCode + * might not reflect the current uCode activity + */ + ofdm = &priv->_3945.statistics.rx.ofdm; + cck = &priv->_3945.statistics.rx.cck; + general = &priv->_3945.statistics.rx.general; + accum_ofdm = &priv->_3945.accum_statistics.rx.ofdm; + accum_cck = &priv->_3945.accum_statistics.rx.cck; + accum_general = &priv->_3945.accum_statistics.rx.general; + delta_ofdm = &priv->_3945.delta_statistics.rx.ofdm; + delta_cck = &priv->_3945.delta_statistics.rx.cck; + delta_general = &priv->_3945.delta_statistics.rx.general; + max_ofdm = &priv->_3945.max_delta.rx.ofdm; + max_cck = &priv->_3945.max_delta.rx.cck; + max_general = &priv->_3945.max_delta.rx.general; + + pos += iwl3945_statistics_flag(priv, buf, bufsz); + pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" + "acumulative delta max\n", + "Statistics_Rx - OFDM:"); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "ina_cnt:", le32_to_cpu(ofdm->ina_cnt), + accum_ofdm->ina_cnt, + delta_ofdm->ina_cnt, max_ofdm->ina_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "fina_cnt:", + le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt, + delta_ofdm->fina_cnt, max_ofdm->fina_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", "plcp_err:", + le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err, + delta_ofdm->plcp_err, max_ofdm->plcp_err); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", "crc32_err:", + le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err, + delta_ofdm->crc32_err, max_ofdm->crc32_err); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", "overrun_err:", + le32_to_cpu(ofdm->overrun_err), + accum_ofdm->overrun_err, delta_ofdm->overrun_err, + max_ofdm->overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "early_overrun_err:", + le32_to_cpu(ofdm->early_overrun_err), + accum_ofdm->early_overrun_err, + delta_ofdm->early_overrun_err, + max_ofdm->early_overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "crc32_good:", le32_to_cpu(ofdm->crc32_good), + accum_ofdm->crc32_good, delta_ofdm->crc32_good, + max_ofdm->crc32_good); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", "false_alarm_cnt:", + le32_to_cpu(ofdm->false_alarm_cnt), + accum_ofdm->false_alarm_cnt, + delta_ofdm->false_alarm_cnt, + max_ofdm->false_alarm_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "fina_sync_err_cnt:", + le32_to_cpu(ofdm->fina_sync_err_cnt), + accum_ofdm->fina_sync_err_cnt, + delta_ofdm->fina_sync_err_cnt, + max_ofdm->fina_sync_err_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "sfd_timeout:", + le32_to_cpu(ofdm->sfd_timeout), + accum_ofdm->sfd_timeout, + delta_ofdm->sfd_timeout, + max_ofdm->sfd_timeout); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "fina_timeout:", + le32_to_cpu(ofdm->fina_timeout), + accum_ofdm->fina_timeout, + delta_ofdm->fina_timeout, + max_ofdm->fina_timeout); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "unresponded_rts:", + le32_to_cpu(ofdm->unresponded_rts), + accum_ofdm->unresponded_rts, + delta_ofdm->unresponded_rts, + max_ofdm->unresponded_rts); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "rxe_frame_lmt_ovrun:", + le32_to_cpu(ofdm->rxe_frame_limit_overrun), + accum_ofdm->rxe_frame_limit_overrun, + delta_ofdm->rxe_frame_limit_overrun, + max_ofdm->rxe_frame_limit_overrun); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "sent_ack_cnt:", + le32_to_cpu(ofdm->sent_ack_cnt), + accum_ofdm->sent_ack_cnt, + delta_ofdm->sent_ack_cnt, + max_ofdm->sent_ack_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "sent_cts_cnt:", + le32_to_cpu(ofdm->sent_cts_cnt), + accum_ofdm->sent_cts_cnt, + delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt); + + pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" + "acumulative delta max\n", + "Statistics_Rx - CCK:"); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "ina_cnt:", + le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt, + delta_cck->ina_cnt, max_cck->ina_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "fina_cnt:", + le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt, + delta_cck->fina_cnt, max_cck->fina_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "plcp_err:", + le32_to_cpu(cck->plcp_err), accum_cck->plcp_err, + delta_cck->plcp_err, max_cck->plcp_err); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "crc32_err:", + le32_to_cpu(cck->crc32_err), accum_cck->crc32_err, + delta_cck->crc32_err, max_cck->crc32_err); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "overrun_err:", + le32_to_cpu(cck->overrun_err), + accum_cck->overrun_err, + delta_cck->overrun_err, max_cck->overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "early_overrun_err:", + le32_to_cpu(cck->early_overrun_err), + accum_cck->early_overrun_err, + delta_cck->early_overrun_err, + max_cck->early_overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "crc32_good:", + le32_to_cpu(cck->crc32_good), accum_cck->crc32_good, + delta_cck->crc32_good, + max_cck->crc32_good); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "false_alarm_cnt:", + le32_to_cpu(cck->false_alarm_cnt), + accum_cck->false_alarm_cnt, + delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "fina_sync_err_cnt:", + le32_to_cpu(cck->fina_sync_err_cnt), + accum_cck->fina_sync_err_cnt, + delta_cck->fina_sync_err_cnt, + max_cck->fina_sync_err_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "sfd_timeout:", + le32_to_cpu(cck->sfd_timeout), + accum_cck->sfd_timeout, + delta_cck->sfd_timeout, max_cck->sfd_timeout); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "fina_timeout:", + le32_to_cpu(cck->fina_timeout), + accum_cck->fina_timeout, + delta_cck->fina_timeout, max_cck->fina_timeout); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "unresponded_rts:", + le32_to_cpu(cck->unresponded_rts), + accum_cck->unresponded_rts, + delta_cck->unresponded_rts, + max_cck->unresponded_rts); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "rxe_frame_lmt_ovrun:", + le32_to_cpu(cck->rxe_frame_limit_overrun), + accum_cck->rxe_frame_limit_overrun, + delta_cck->rxe_frame_limit_overrun, + max_cck->rxe_frame_limit_overrun); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "sent_ack_cnt:", + le32_to_cpu(cck->sent_ack_cnt), + accum_cck->sent_ack_cnt, + delta_cck->sent_ack_cnt, + max_cck->sent_ack_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "sent_cts_cnt:", + le32_to_cpu(cck->sent_cts_cnt), + accum_cck->sent_cts_cnt, + delta_cck->sent_cts_cnt, + max_cck->sent_cts_cnt); + + pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" + "acumulative delta max\n", + "Statistics_Rx - GENERAL:"); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "bogus_cts:", + le32_to_cpu(general->bogus_cts), + accum_general->bogus_cts, + delta_general->bogus_cts, max_general->bogus_cts); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "bogus_ack:", + le32_to_cpu(general->bogus_ack), + accum_general->bogus_ack, + delta_general->bogus_ack, max_general->bogus_ack); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "non_bssid_frames:", + le32_to_cpu(general->non_bssid_frames), + accum_general->non_bssid_frames, + delta_general->non_bssid_frames, + max_general->non_bssid_frames); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "filtered_frames:", + le32_to_cpu(general->filtered_frames), + accum_general->filtered_frames, + delta_general->filtered_frames, + max_general->filtered_frames); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "non_channel_beacons:", + le32_to_cpu(general->non_channel_beacons), + accum_general->non_channel_beacons, + delta_general->non_channel_beacons, + max_general->non_channel_beacons); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} + +ssize_t iwl3945_ucode_tx_stats_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + int pos = 0; + char *buf; + int bufsz = (sizeof(struct iwl39_statistics_tx) * 48) + 250; + ssize_t ret; + struct iwl39_statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; + + if (!iwl_legacy_is_alive(priv)) + return -EAGAIN; + + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate Buffer\n"); + return -ENOMEM; + } + + /* + * The statistic information display here is based on + * the last statistics notification from uCode + * might not reflect the current uCode activity + */ + tx = &priv->_3945.statistics.tx; + accum_tx = &priv->_3945.accum_statistics.tx; + delta_tx = &priv->_3945.delta_statistics.tx; + max_tx = &priv->_3945.max_delta.tx; + pos += iwl3945_statistics_flag(priv, buf, bufsz); + pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" + "acumulative delta max\n", + "Statistics_Tx:"); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "preamble:", + le32_to_cpu(tx->preamble_cnt), + accum_tx->preamble_cnt, + delta_tx->preamble_cnt, max_tx->preamble_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "rx_detected_cnt:", + le32_to_cpu(tx->rx_detected_cnt), + accum_tx->rx_detected_cnt, + delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "bt_prio_defer_cnt:", + le32_to_cpu(tx->bt_prio_defer_cnt), + accum_tx->bt_prio_defer_cnt, + delta_tx->bt_prio_defer_cnt, + max_tx->bt_prio_defer_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "bt_prio_kill_cnt:", + le32_to_cpu(tx->bt_prio_kill_cnt), + accum_tx->bt_prio_kill_cnt, + delta_tx->bt_prio_kill_cnt, + max_tx->bt_prio_kill_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "few_bytes_cnt:", + le32_to_cpu(tx->few_bytes_cnt), + accum_tx->few_bytes_cnt, + delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "cts_timeout:", + le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout, + delta_tx->cts_timeout, max_tx->cts_timeout); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "ack_timeout:", + le32_to_cpu(tx->ack_timeout), + accum_tx->ack_timeout, + delta_tx->ack_timeout, max_tx->ack_timeout); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "expected_ack_cnt:", + le32_to_cpu(tx->expected_ack_cnt), + accum_tx->expected_ack_cnt, + delta_tx->expected_ack_cnt, + max_tx->expected_ack_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "actual_ack_cnt:", + le32_to_cpu(tx->actual_ack_cnt), + accum_tx->actual_ack_cnt, + delta_tx->actual_ack_cnt, + max_tx->actual_ack_cnt); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} + +ssize_t iwl3945_ucode_general_stats_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + int pos = 0; + char *buf; + int bufsz = sizeof(struct iwl39_statistics_general) * 10 + 300; + ssize_t ret; + struct iwl39_statistics_general *general, *accum_general; + struct iwl39_statistics_general *delta_general, *max_general; + struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; + struct iwl39_statistics_div *div, *accum_div, *delta_div, *max_div; + + if (!iwl_legacy_is_alive(priv)) + return -EAGAIN; + + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate Buffer\n"); + return -ENOMEM; + } + + /* + * The statistic information display here is based on + * the last statistics notification from uCode + * might not reflect the current uCode activity + */ + general = &priv->_3945.statistics.general; + dbg = &priv->_3945.statistics.general.dbg; + div = &priv->_3945.statistics.general.div; + accum_general = &priv->_3945.accum_statistics.general; + delta_general = &priv->_3945.delta_statistics.general; + max_general = &priv->_3945.max_delta.general; + accum_dbg = &priv->_3945.accum_statistics.general.dbg; + delta_dbg = &priv->_3945.delta_statistics.general.dbg; + max_dbg = &priv->_3945.max_delta.general.dbg; + accum_div = &priv->_3945.accum_statistics.general.div; + delta_div = &priv->_3945.delta_statistics.general.div; + max_div = &priv->_3945.max_delta.general.div; + pos += iwl3945_statistics_flag(priv, buf, bufsz); + pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" + "acumulative delta max\n", + "Statistics_General:"); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "burst_check:", + le32_to_cpu(dbg->burst_check), + accum_dbg->burst_check, + delta_dbg->burst_check, max_dbg->burst_check); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "burst_count:", + le32_to_cpu(dbg->burst_count), + accum_dbg->burst_count, + delta_dbg->burst_count, max_dbg->burst_count); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "sleep_time:", + le32_to_cpu(general->sleep_time), + accum_general->sleep_time, + delta_general->sleep_time, max_general->sleep_time); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "slots_out:", + le32_to_cpu(general->slots_out), + accum_general->slots_out, + delta_general->slots_out, max_general->slots_out); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "slots_idle:", + le32_to_cpu(general->slots_idle), + accum_general->slots_idle, + delta_general->slots_idle, max_general->slots_idle); + pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n", + le32_to_cpu(general->ttl_timestamp)); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "tx_on_a:", + le32_to_cpu(div->tx_on_a), accum_div->tx_on_a, + delta_div->tx_on_a, max_div->tx_on_a); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "tx_on_b:", + le32_to_cpu(div->tx_on_b), accum_div->tx_on_b, + delta_div->tx_on_b, max_div->tx_on_b); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "exec_time:", + le32_to_cpu(div->exec_time), accum_div->exec_time, + delta_div->exec_time, max_div->exec_time); + pos += scnprintf(buf + pos, bufsz - pos, + " %-30s %10u %10u %10u %10u\n", + "probe_time:", + le32_to_cpu(div->probe_time), accum_div->probe_time, + delta_div->probe_time, max_div->probe_time); + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} diff --git a/drivers/net/wireless/iwlegacy/iwl-3945-debugfs.h b/drivers/net/wireless/iwlegacy/iwl-3945-debugfs.h new file mode 100644 index 000000000000..8fef4b32b447 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-3945-debugfs.h @@ -0,0 +1,60 @@ +/****************************************************************************** + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ + +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-debug.h" + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS +ssize_t iwl3945_ucode_rx_stats_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos); +ssize_t iwl3945_ucode_tx_stats_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos); +ssize_t iwl3945_ucode_general_stats_read(struct file *file, + char __user *user_buf, size_t count, + loff_t *ppos); +#else +static ssize_t iwl3945_ucode_rx_stats_read(struct file *file, + char __user *user_buf, size_t count, + loff_t *ppos) +{ + return 0; +} +static ssize_t iwl3945_ucode_tx_stats_read(struct file *file, + char __user *user_buf, size_t count, + loff_t *ppos) +{ + return 0; +} +static ssize_t iwl3945_ucode_general_stats_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + return 0; +} +#endif diff --git a/drivers/net/wireless/iwlegacy/iwl-3945-fh.h b/drivers/net/wireless/iwlegacy/iwl-3945-fh.h new file mode 100644 index 000000000000..836c9919f82e --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-3945-fh.h @@ -0,0 +1,187 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#ifndef __iwl_3945_fh_h__ +#define __iwl_3945_fh_h__ + +/************************************/ +/* iwl3945 Flow Handler Definitions */ +/************************************/ + +/** + * This I/O area is directly read/writable by driver (e.g. Linux uses writel()) + * Addresses are offsets from device's PCI hardware base address. + */ +#define FH39_MEM_LOWER_BOUND (0x0800) +#define FH39_MEM_UPPER_BOUND (0x1000) + +#define FH39_CBCC_TABLE (FH39_MEM_LOWER_BOUND + 0x140) +#define FH39_TFDB_TABLE (FH39_MEM_LOWER_BOUND + 0x180) +#define FH39_RCSR_TABLE (FH39_MEM_LOWER_BOUND + 0x400) +#define FH39_RSSR_TABLE (FH39_MEM_LOWER_BOUND + 0x4c0) +#define FH39_TCSR_TABLE (FH39_MEM_LOWER_BOUND + 0x500) +#define FH39_TSSR_TABLE (FH39_MEM_LOWER_BOUND + 0x680) + +/* TFDB (Transmit Frame Buffer Descriptor) */ +#define FH39_TFDB(_ch, buf) (FH39_TFDB_TABLE + \ + ((_ch) * 2 + (buf)) * 0x28) +#define FH39_TFDB_CHNL_BUF_CTRL_REG(_ch) (FH39_TFDB_TABLE + 0x50 * (_ch)) + +/* CBCC channel is [0,2] */ +#define FH39_CBCC(_ch) (FH39_CBCC_TABLE + (_ch) * 0x8) +#define FH39_CBCC_CTRL(_ch) (FH39_CBCC(_ch) + 0x00) +#define FH39_CBCC_BASE(_ch) (FH39_CBCC(_ch) + 0x04) + +/* RCSR channel is [0,2] */ +#define FH39_RCSR(_ch) (FH39_RCSR_TABLE + (_ch) * 0x40) +#define FH39_RCSR_CONFIG(_ch) (FH39_RCSR(_ch) + 0x00) +#define FH39_RCSR_RBD_BASE(_ch) (FH39_RCSR(_ch) + 0x04) +#define FH39_RCSR_WPTR(_ch) (FH39_RCSR(_ch) + 0x20) +#define FH39_RCSR_RPTR_ADDR(_ch) (FH39_RCSR(_ch) + 0x24) + +#define FH39_RSCSR_CHNL0_WPTR (FH39_RCSR_WPTR(0)) + +/* RSSR */ +#define FH39_RSSR_CTRL (FH39_RSSR_TABLE + 0x000) +#define FH39_RSSR_STATUS (FH39_RSSR_TABLE + 0x004) + +/* TCSR */ +#define FH39_TCSR(_ch) (FH39_TCSR_TABLE + (_ch) * 0x20) +#define FH39_TCSR_CONFIG(_ch) (FH39_TCSR(_ch) + 0x00) +#define FH39_TCSR_CREDIT(_ch) (FH39_TCSR(_ch) + 0x04) +#define FH39_TCSR_BUFF_STTS(_ch) (FH39_TCSR(_ch) + 0x08) + +/* TSSR */ +#define FH39_TSSR_CBB_BASE (FH39_TSSR_TABLE + 0x000) +#define FH39_TSSR_MSG_CONFIG (FH39_TSSR_TABLE + 0x008) +#define FH39_TSSR_TX_STATUS (FH39_TSSR_TABLE + 0x010) + + +/* DBM */ + +#define FH39_SRVC_CHNL (6) + +#define FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE (20) +#define FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH (4) + +#define FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN (0x08000000) + +#define FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE (0x80000000) + +#define FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE (0x20000000) + +#define FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 (0x01000000) + +#define FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST (0x00001000) + +#define FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH (0x00000000) + +#define FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF (0x00000000) +#define FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER (0x00000001) + +#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000) +#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008) + +#define FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD (0x00200000) + +#define FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT (0x00000000) + +#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000) +#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000) + +#define FH39_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID (0x00004000) + +#define FH39_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR (0x00000001) + +#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON (0xFF000000) +#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON (0x00FF0000) + +#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B (0x00000400) + +#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON (0x00000100) +#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON (0x00000080) + +#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH (0x00000020) +#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH (0x00000005) + +#define FH39_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_ch) (BIT(_ch) << 24) +#define FH39_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_ch) (BIT(_ch) << 16) + +#define FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_ch) \ + (FH39_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_ch) | \ + FH39_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_ch)) + +#define FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000) + +struct iwl3945_tfd_tb { + __le32 addr; + __le32 len; +} __packed; + +struct iwl3945_tfd { + __le32 control_flags; + struct iwl3945_tfd_tb tbs[4]; + u8 __pad[28]; +} __packed; + + +#endif /* __iwl_3945_fh_h__ */ diff --git a/drivers/net/wireless/iwlegacy/iwl-3945-hw.h b/drivers/net/wireless/iwlegacy/iwl-3945-hw.h new file mode 100644 index 000000000000..779d3cb86e2c --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-3945-hw.h @@ -0,0 +1,293 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Please use this file (iwl-3945-hw.h) only for hardware-related definitions. + * Please use iwl-commands.h for uCode API definitions. + * Please use iwl-3945.h for driver implementation definitions. + */ + +#ifndef __iwl_3945_hw__ +#define __iwl_3945_hw__ + +#include "iwl-eeprom.h" + +/* RSSI to dBm */ +#define IWL39_RSSI_OFFSET 95 + +#define IWL_DEFAULT_TX_POWER 0x0F + +/* + * EEPROM related constants, enums, and structures. + */ +#define EEPROM_SKU_CAP_OP_MODE_MRC (1 << 7) + +/* + * Mapping of a Tx power level, at factory calibration temperature, + * to a radio/DSP gain table index. + * One for each of 5 "sample" power levels in each band. + * v_det is measured at the factory, using the 3945's built-in power amplifier + * (PA) output voltage detector. This same detector is used during Tx of + * long packets in normal operation to provide feedback as to proper output + * level. + * Data copied from EEPROM. + * DO NOT ALTER THIS STRUCTURE!!! + */ +struct iwl3945_eeprom_txpower_sample { + u8 gain_index; /* index into power (gain) setup table ... */ + s8 power; /* ... for this pwr level for this chnl group */ + u16 v_det; /* PA output voltage */ +} __packed; + +/* + * Mappings of Tx power levels -> nominal radio/DSP gain table indexes. + * One for each channel group (a.k.a. "band") (1 for BG, 4 for A). + * Tx power setup code interpolates between the 5 "sample" power levels + * to determine the nominal setup for a requested power level. + * Data copied from EEPROM. + * DO NOT ALTER THIS STRUCTURE!!! + */ +struct iwl3945_eeprom_txpower_group { + struct iwl3945_eeprom_txpower_sample samples[5]; /* 5 power levels */ + s32 a, b, c, d, e; /* coefficients for voltage->power + * formula (signed) */ + s32 Fa, Fb, Fc, Fd, Fe; /* these modify coeffs based on + * frequency (signed) */ + s8 saturation_power; /* highest power possible by h/w in this + * band */ + u8 group_channel; /* "representative" channel # in this band */ + s16 temperature; /* h/w temperature at factory calib this band + * (signed) */ +} __packed; + +/* + * Temperature-based Tx-power compensation data, not band-specific. + * These coefficients are use to modify a/b/c/d/e coeffs based on + * difference between current temperature and factory calib temperature. + * Data copied from EEPROM. + */ +struct iwl3945_eeprom_temperature_corr { + u32 Ta; + u32 Tb; + u32 Tc; + u32 Td; + u32 Te; +} __packed; + +/* + * EEPROM map + */ +struct iwl3945_eeprom { + u8 reserved0[16]; + u16 device_id; /* abs.ofs: 16 */ + u8 reserved1[2]; + u16 pmc; /* abs.ofs: 20 */ + u8 reserved2[20]; + u8 mac_address[6]; /* abs.ofs: 42 */ + u8 reserved3[58]; + u16 board_revision; /* abs.ofs: 106 */ + u8 reserved4[11]; + u8 board_pba_number[9]; /* abs.ofs: 119 */ + u8 reserved5[8]; + u16 version; /* abs.ofs: 136 */ + u8 sku_cap; /* abs.ofs: 138 */ + u8 leds_mode; /* abs.ofs: 139 */ + u16 oem_mode; + u16 wowlan_mode; /* abs.ofs: 142 */ + u16 leds_time_interval; /* abs.ofs: 144 */ + u8 leds_off_time; /* abs.ofs: 146 */ + u8 leds_on_time; /* abs.ofs: 147 */ + u8 almgor_m_version; /* abs.ofs: 148 */ + u8 antenna_switch_type; /* abs.ofs: 149 */ + u8 reserved6[42]; + u8 sku_id[4]; /* abs.ofs: 192 */ + +/* + * Per-channel regulatory data. + * + * Each channel that *might* be supported by 3945 has a fixed location + * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory + * txpower (MSB). + * + * Entries immediately below are for 20 MHz channel width. + * + * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 + */ + u16 band_1_count; /* abs.ofs: 196 */ + struct iwl_eeprom_channel band_1_channels[14]; /* abs.ofs: 198 */ + +/* + * 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196, + * 5.0 GHz channels 7, 8, 11, 12, 16 + * (4915-5080MHz) (none of these is ever supported) + */ + u16 band_2_count; /* abs.ofs: 226 */ + struct iwl_eeprom_channel band_2_channels[13]; /* abs.ofs: 228 */ + +/* + * 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 + * (5170-5320MHz) + */ + u16 band_3_count; /* abs.ofs: 254 */ + struct iwl_eeprom_channel band_3_channels[12]; /* abs.ofs: 256 */ + +/* + * 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 + * (5500-5700MHz) + */ + u16 band_4_count; /* abs.ofs: 280 */ + struct iwl_eeprom_channel band_4_channels[11]; /* abs.ofs: 282 */ + +/* + * 5.7 GHz channels 145, 149, 153, 157, 161, 165 + * (5725-5825MHz) + */ + u16 band_5_count; /* abs.ofs: 304 */ + struct iwl_eeprom_channel band_5_channels[6]; /* abs.ofs: 306 */ + + u8 reserved9[194]; + +/* + * 3945 Txpower calibration data. + */ +#define IWL_NUM_TX_CALIB_GROUPS 5 + struct iwl3945_eeprom_txpower_group groups[IWL_NUM_TX_CALIB_GROUPS]; +/* abs.ofs: 512 */ + struct iwl3945_eeprom_temperature_corr corrections; /* abs.ofs: 832 */ + u8 reserved16[172]; /* fill out to full 1024 byte block */ +} __packed; + +#define IWL3945_EEPROM_IMG_SIZE 1024 + +/* End of EEPROM */ + +#define PCI_CFG_REV_ID_BIT_BASIC_SKU (0x40) /* bit 6 */ +#define PCI_CFG_REV_ID_BIT_RTP (0x80) /* bit 7 */ + +/* 4 DATA + 1 CMD. There are 2 HCCA queues that are not used. */ +#define IWL39_NUM_QUEUES 5 +#define IWL39_CMD_QUEUE_NUM 4 + +#define IWL_DEFAULT_TX_RETRY 15 + +/*********************************************/ + +#define RFD_SIZE 4 +#define NUM_TFD_CHUNKS 4 + +#define RX_QUEUE_SIZE 256 +#define RX_QUEUE_MASK 255 +#define RX_QUEUE_SIZE_LOG 8 + +#define U32_PAD(n) ((4-(n))&0x3) + +#define TFD_CTL_COUNT_SET(n) (n << 24) +#define TFD_CTL_COUNT_GET(ctl) ((ctl >> 24) & 7) +#define TFD_CTL_PAD_SET(n) (n << 28) +#define TFD_CTL_PAD_GET(ctl) (ctl >> 28) + +/* Sizes and addresses for instruction and data memory (SRAM) in + * 3945's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ +#define IWL39_RTC_INST_LOWER_BOUND (0x000000) +#define IWL39_RTC_INST_UPPER_BOUND (0x014000) + +#define IWL39_RTC_DATA_LOWER_BOUND (0x800000) +#define IWL39_RTC_DATA_UPPER_BOUND (0x808000) + +#define IWL39_RTC_INST_SIZE (IWL39_RTC_INST_UPPER_BOUND - \ + IWL39_RTC_INST_LOWER_BOUND) +#define IWL39_RTC_DATA_SIZE (IWL39_RTC_DATA_UPPER_BOUND - \ + IWL39_RTC_DATA_LOWER_BOUND) + +#define IWL39_MAX_INST_SIZE IWL39_RTC_INST_SIZE +#define IWL39_MAX_DATA_SIZE IWL39_RTC_DATA_SIZE + +/* Size of uCode instruction memory in bootstrap state machine */ +#define IWL39_MAX_BSM_SIZE IWL39_RTC_INST_SIZE + +static inline int iwl3945_hw_valid_rtc_data_addr(u32 addr) +{ + return (addr >= IWL39_RTC_DATA_LOWER_BOUND) && + (addr < IWL39_RTC_DATA_UPPER_BOUND); +} + +/* Base physical address of iwl3945_shared is provided to FH_TSSR_CBB_BASE + * and &iwl3945_shared.rx_read_ptr[0] is provided to FH_RCSR_RPTR_ADDR(0) */ +struct iwl3945_shared { + __le32 tx_base_ptr[8]; +} __packed; + +static inline u8 iwl3945_hw_get_rate(__le16 rate_n_flags) +{ + return le16_to_cpu(rate_n_flags) & 0xFF; +} + +static inline u16 iwl3945_hw_get_rate_n_flags(__le16 rate_n_flags) +{ + return le16_to_cpu(rate_n_flags); +} + +static inline __le16 iwl3945_hw_set_rate_n_flags(u8 rate, u16 flags) +{ + return cpu_to_le16((u16)rate|flags); +} +#endif diff --git a/drivers/net/wireless/iwlegacy/iwl-3945-led.c b/drivers/net/wireless/iwlegacy/iwl-3945-led.c new file mode 100644 index 000000000000..abd923558d48 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-3945-led.c @@ -0,0 +1,64 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iwl-commands.h" +#include "iwl-3945.h" +#include "iwl-core.h" +#include "iwl-dev.h" +#include "iwl-3945-led.h" + + +/* Send led command */ +static int iwl3945_send_led_cmd(struct iwl_priv *priv, + struct iwl_led_cmd *led_cmd) +{ + struct iwl_host_cmd cmd = { + .id = REPLY_LEDS_CMD, + .len = sizeof(struct iwl_led_cmd), + .data = led_cmd, + .flags = CMD_ASYNC, + .callback = NULL, + }; + + return iwl_legacy_send_cmd(priv, &cmd); +} + +const struct iwl_led_ops iwl3945_led_ops = { + .cmd = iwl3945_send_led_cmd, +}; diff --git a/drivers/net/wireless/iwlegacy/iwl-3945-led.h b/drivers/net/wireless/iwlegacy/iwl-3945-led.h new file mode 100644 index 000000000000..96716276eb0d --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-3945-led.h @@ -0,0 +1,32 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#ifndef __iwl_3945_led_h__ +#define __iwl_3945_led_h__ + +extern const struct iwl_led_ops iwl3945_led_ops; + +#endif /* __iwl_3945_led_h__ */ diff --git a/drivers/net/wireless/iwlegacy/iwl-3945-rs.c b/drivers/net/wireless/iwlegacy/iwl-3945-rs.c new file mode 100644 index 000000000000..4fabc5439858 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-3945-rs.c @@ -0,0 +1,994 @@ +/****************************************************************************** + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "iwl-commands.h" +#include "iwl-3945.h" +#include "iwl-sta.h" + +#define RS_NAME "iwl-3945-rs" + +static s32 iwl3945_expected_tpt_g[IWL_RATE_COUNT_3945] = { + 7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202 +}; + +static s32 iwl3945_expected_tpt_g_prot[IWL_RATE_COUNT_3945] = { + 7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125 +}; + +static s32 iwl3945_expected_tpt_a[IWL_RATE_COUNT_3945] = { + 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186 +}; + +static s32 iwl3945_expected_tpt_b[IWL_RATE_COUNT_3945] = { + 7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +struct iwl3945_tpt_entry { + s8 min_rssi; + u8 index; +}; + +static struct iwl3945_tpt_entry iwl3945_tpt_table_a[] = { + {-60, IWL_RATE_54M_INDEX}, + {-64, IWL_RATE_48M_INDEX}, + {-72, IWL_RATE_36M_INDEX}, + {-80, IWL_RATE_24M_INDEX}, + {-84, IWL_RATE_18M_INDEX}, + {-85, IWL_RATE_12M_INDEX}, + {-87, IWL_RATE_9M_INDEX}, + {-89, IWL_RATE_6M_INDEX} +}; + +static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = { + {-60, IWL_RATE_54M_INDEX}, + {-64, IWL_RATE_48M_INDEX}, + {-68, IWL_RATE_36M_INDEX}, + {-80, IWL_RATE_24M_INDEX}, + {-84, IWL_RATE_18M_INDEX}, + {-85, IWL_RATE_12M_INDEX}, + {-86, IWL_RATE_11M_INDEX}, + {-88, IWL_RATE_5M_INDEX}, + {-90, IWL_RATE_2M_INDEX}, + {-92, IWL_RATE_1M_INDEX} +}; + +#define IWL_RATE_MAX_WINDOW 62 +#define IWL_RATE_FLUSH (3*HZ) +#define IWL_RATE_WIN_FLUSH (HZ/2) +#define IWL39_RATE_HIGH_TH 11520 +#define IWL_SUCCESS_UP_TH 8960 +#define IWL_SUCCESS_DOWN_TH 10880 +#define IWL_RATE_MIN_FAILURE_TH 6 +#define IWL_RATE_MIN_SUCCESS_TH 8 +#define IWL_RATE_DECREASE_TH 1920 +#define IWL_RATE_RETRY_TH 15 + +static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, enum ieee80211_band band) +{ + u32 index = 0; + u32 table_size = 0; + struct iwl3945_tpt_entry *tpt_table = NULL; + + if ((rssi < IWL_MIN_RSSI_VAL) || (rssi > IWL_MAX_RSSI_VAL)) + rssi = IWL_MIN_RSSI_VAL; + + switch (band) { + case IEEE80211_BAND_2GHZ: + tpt_table = iwl3945_tpt_table_g; + table_size = ARRAY_SIZE(iwl3945_tpt_table_g); + break; + + case IEEE80211_BAND_5GHZ: + tpt_table = iwl3945_tpt_table_a; + table_size = ARRAY_SIZE(iwl3945_tpt_table_a); + break; + + default: + BUG(); + break; + } + + while ((index < table_size) && (rssi < tpt_table[index].min_rssi)) + index++; + + index = min(index, (table_size - 1)); + + return tpt_table[index].index; +} + +static void iwl3945_clear_window(struct iwl3945_rate_scale_data *window) +{ + window->data = 0; + window->success_counter = 0; + window->success_ratio = -1; + window->counter = 0; + window->average_tpt = IWL_INVALID_VALUE; + window->stamp = 0; +} + +/** + * iwl3945_rate_scale_flush_windows - flush out the rate scale windows + * + * Returns the number of windows that have gathered data but were + * not flushed. If there were any that were not flushed, then + * reschedule the rate flushing routine. + */ +static int iwl3945_rate_scale_flush_windows(struct iwl3945_rs_sta *rs_sta) +{ + int unflushed = 0; + int i; + unsigned long flags; + struct iwl_priv *priv __maybe_unused = rs_sta->priv; + + /* + * For each rate, if we have collected data on that rate + * and it has been more than IWL_RATE_WIN_FLUSH + * since we flushed, clear out the gathered statistics + */ + for (i = 0; i < IWL_RATE_COUNT_3945; i++) { + if (!rs_sta->win[i].counter) + continue; + + spin_lock_irqsave(&rs_sta->lock, flags); + if (time_after(jiffies, rs_sta->win[i].stamp + + IWL_RATE_WIN_FLUSH)) { + IWL_DEBUG_RATE(priv, "flushing %d samples of rate " + "index %d\n", + rs_sta->win[i].counter, i); + iwl3945_clear_window(&rs_sta->win[i]); + } else + unflushed++; + spin_unlock_irqrestore(&rs_sta->lock, flags); + } + + return unflushed; +} + +#define IWL_RATE_FLUSH_MAX 5000 /* msec */ +#define IWL_RATE_FLUSH_MIN 50 /* msec */ +#define IWL_AVERAGE_PACKETS 1500 + +static void iwl3945_bg_rate_scale_flush(unsigned long data) +{ + struct iwl3945_rs_sta *rs_sta = (void *)data; + struct iwl_priv *priv __maybe_unused = rs_sta->priv; + int unflushed = 0; + unsigned long flags; + u32 packet_count, duration, pps; + + IWL_DEBUG_RATE(priv, "enter\n"); + + unflushed = iwl3945_rate_scale_flush_windows(rs_sta); + + spin_lock_irqsave(&rs_sta->lock, flags); + + /* Number of packets Rx'd since last time this timer ran */ + packet_count = (rs_sta->tx_packets - rs_sta->last_tx_packets) + 1; + + rs_sta->last_tx_packets = rs_sta->tx_packets + 1; + + if (unflushed) { + duration = + jiffies_to_msecs(jiffies - rs_sta->last_partial_flush); + + IWL_DEBUG_RATE(priv, "Tx'd %d packets in %dms\n", + packet_count, duration); + + /* Determine packets per second */ + if (duration) + pps = (packet_count * 1000) / duration; + else + pps = 0; + + if (pps) { + duration = (IWL_AVERAGE_PACKETS * 1000) / pps; + if (duration < IWL_RATE_FLUSH_MIN) + duration = IWL_RATE_FLUSH_MIN; + else if (duration > IWL_RATE_FLUSH_MAX) + duration = IWL_RATE_FLUSH_MAX; + } else + duration = IWL_RATE_FLUSH_MAX; + + rs_sta->flush_time = msecs_to_jiffies(duration); + + IWL_DEBUG_RATE(priv, "new flush period: %d msec ave %d\n", + duration, packet_count); + + mod_timer(&rs_sta->rate_scale_flush, jiffies + + rs_sta->flush_time); + + rs_sta->last_partial_flush = jiffies; + } else { + rs_sta->flush_time = IWL_RATE_FLUSH; + rs_sta->flush_pending = 0; + } + /* If there weren't any unflushed entries, we don't schedule the timer + * to run again */ + + rs_sta->last_flush = jiffies; + + spin_unlock_irqrestore(&rs_sta->lock, flags); + + IWL_DEBUG_RATE(priv, "leave\n"); +} + +/** + * iwl3945_collect_tx_data - Update the success/failure sliding window + * + * We keep a sliding window of the last 64 packets transmitted + * at this rate. window->data contains the bitmask of successful + * packets. + */ +static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta, + struct iwl3945_rate_scale_data *window, + int success, int retries, int index) +{ + unsigned long flags; + s32 fail_count; + struct iwl_priv *priv __maybe_unused = rs_sta->priv; + + if (!retries) { + IWL_DEBUG_RATE(priv, "leave: retries == 0 -- should be at least 1\n"); + return; + } + + spin_lock_irqsave(&rs_sta->lock, flags); + + /* + * Keep track of only the latest 62 tx frame attempts in this rate's + * history window; anything older isn't really relevant any more. + * If we have filled up the sliding window, drop the oldest attempt; + * if the oldest attempt (highest bit in bitmap) shows "success", + * subtract "1" from the success counter (this is the main reason + * we keep these bitmaps!). + * */ + while (retries > 0) { + if (window->counter >= IWL_RATE_MAX_WINDOW) { + + /* remove earliest */ + window->counter = IWL_RATE_MAX_WINDOW - 1; + + if (window->data & (1ULL << (IWL_RATE_MAX_WINDOW - 1))) { + window->data &= ~(1ULL << (IWL_RATE_MAX_WINDOW - 1)); + window->success_counter--; + } + } + + /* Increment frames-attempted counter */ + window->counter++; + + /* Shift bitmap by one frame (throw away oldest history), + * OR in "1", and increment "success" if this + * frame was successful. */ + window->data <<= 1; + if (success > 0) { + window->success_counter++; + window->data |= 0x1; + success--; + } + + retries--; + } + + /* Calculate current success ratio, avoid divide-by-0! */ + if (window->counter > 0) + window->success_ratio = 128 * (100 * window->success_counter) + / window->counter; + else + window->success_ratio = IWL_INVALID_VALUE; + + fail_count = window->counter - window->success_counter; + + /* Calculate average throughput, if we have enough history. */ + if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) || + (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH)) + window->average_tpt = ((window->success_ratio * + rs_sta->expected_tpt[index] + 64) / 128); + else + window->average_tpt = IWL_INVALID_VALUE; + + /* Tag this window as having been updated */ + window->stamp = jiffies; + + spin_unlock_irqrestore(&rs_sta->lock, flags); + +} + +/* + * Called after adding a new station to initialize rate scaling + */ +void iwl3945_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_id) +{ + struct ieee80211_hw *hw = priv->hw; + struct ieee80211_conf *conf = &priv->hw->conf; + struct iwl3945_sta_priv *psta; + struct iwl3945_rs_sta *rs_sta; + struct ieee80211_supported_band *sband; + int i; + + IWL_DEBUG_INFO(priv, "enter\n"); + if (sta_id == priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id) + goto out; + + psta = (struct iwl3945_sta_priv *) sta->drv_priv; + rs_sta = &psta->rs_sta; + sband = hw->wiphy->bands[conf->channel->band]; + + rs_sta->priv = priv; + + rs_sta->start_rate = IWL_RATE_INVALID; + + /* default to just 802.11b */ + rs_sta->expected_tpt = iwl3945_expected_tpt_b; + + rs_sta->last_partial_flush = jiffies; + rs_sta->last_flush = jiffies; + rs_sta->flush_time = IWL_RATE_FLUSH; + rs_sta->last_tx_packets = 0; + + rs_sta->rate_scale_flush.data = (unsigned long)rs_sta; + rs_sta->rate_scale_flush.function = iwl3945_bg_rate_scale_flush; + + for (i = 0; i < IWL_RATE_COUNT_3945; i++) + iwl3945_clear_window(&rs_sta->win[i]); + + /* TODO: what is a good starting rate for STA? About middle? Maybe not + * the lowest or the highest rate.. Could consider using RSSI from + * previous packets? Need to have IEEE 802.1X auth succeed immediately + * after assoc.. */ + + for (i = sband->n_bitrates - 1; i >= 0; i--) { + if (sta->supp_rates[sband->band] & (1 << i)) { + rs_sta->last_txrate_idx = i; + break; + } + } + + priv->_3945.sta_supp_rates = sta->supp_rates[sband->band]; + /* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */ + if (sband->band == IEEE80211_BAND_5GHZ) { + rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; + priv->_3945.sta_supp_rates = priv->_3945.sta_supp_rates << + IWL_FIRST_OFDM_RATE; + } + +out: + priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; + + IWL_DEBUG_INFO(priv, "leave\n"); +} + +static void *iwl3945_rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) +{ + return hw->priv; +} + +/* rate scale requires free function to be implemented */ +static void iwl3945_rs_free(void *priv) +{ + return; +} + +static void *iwl3945_rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp) +{ + struct iwl3945_rs_sta *rs_sta; + struct iwl3945_sta_priv *psta = (void *) sta->drv_priv; + struct iwl_priv *priv __maybe_unused = iwl_priv; + + IWL_DEBUG_RATE(priv, "enter\n"); + + rs_sta = &psta->rs_sta; + + spin_lock_init(&rs_sta->lock); + init_timer(&rs_sta->rate_scale_flush); + + IWL_DEBUG_RATE(priv, "leave\n"); + + return rs_sta; +} + +static void iwl3945_rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta, + void *priv_sta) +{ + struct iwl3945_rs_sta *rs_sta = priv_sta; + + /* + * Be careful not to use any members of iwl3945_rs_sta (like trying + * to use iwl_priv to print out debugging) since it may not be fully + * initialized at this point. + */ + del_timer_sync(&rs_sta->rate_scale_flush); +} + + +/** + * iwl3945_rs_tx_status - Update rate control values based on Tx results + * + * NOTE: Uses iwl_priv->retry_rate for the # of retries attempted by + * the hardware for each rate. + */ +static void iwl3945_rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta, + struct sk_buff *skb) +{ + s8 retries = 0, current_count; + int scale_rate_index, first_index, last_index; + unsigned long flags; + struct iwl_priv *priv = (struct iwl_priv *)priv_rate; + struct iwl3945_rs_sta *rs_sta = priv_sta; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + + IWL_DEBUG_RATE(priv, "enter\n"); + + retries = info->status.rates[0].count; + /* Sanity Check for retries */ + if (retries > IWL_RATE_RETRY_TH) + retries = IWL_RATE_RETRY_TH; + + first_index = sband->bitrates[info->status.rates[0].idx].hw_value; + if ((first_index < 0) || (first_index >= IWL_RATE_COUNT_3945)) { + IWL_DEBUG_RATE(priv, "leave: Rate out of bounds: %d\n", first_index); + return; + } + + if (!priv_sta) { + IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n"); + return; + } + + /* Treat uninitialized rate scaling data same as non-existing. */ + if (!rs_sta->priv) { + IWL_DEBUG_RATE(priv, "leave: STA priv data uninitialized!\n"); + return; + } + + + rs_sta->tx_packets++; + + scale_rate_index = first_index; + last_index = first_index; + + /* + * Update the window for each rate. We determine which rates + * were Tx'd based on the total number of retries vs. the number + * of retries configured for each rate -- currently set to the + * priv value 'retry_rate' vs. rate specific + * + * On exit from this while loop last_index indicates the rate + * at which the frame was finally transmitted (or failed if no + * ACK) + */ + while (retries > 1) { + if ((retries - 1) < priv->retry_rate) { + current_count = (retries - 1); + last_index = scale_rate_index; + } else { + current_count = priv->retry_rate; + last_index = iwl3945_rs_next_rate(priv, + scale_rate_index); + } + + /* Update this rate accounting for as many retries + * as was used for it (per current_count) */ + iwl3945_collect_tx_data(rs_sta, + &rs_sta->win[scale_rate_index], + 0, current_count, scale_rate_index); + IWL_DEBUG_RATE(priv, "Update rate %d for %d retries.\n", + scale_rate_index, current_count); + + retries -= current_count; + + scale_rate_index = last_index; + } + + + /* Update the last index window with success/failure based on ACK */ + IWL_DEBUG_RATE(priv, "Update rate %d with %s.\n", + last_index, + (info->flags & IEEE80211_TX_STAT_ACK) ? + "success" : "failure"); + iwl3945_collect_tx_data(rs_sta, + &rs_sta->win[last_index], + info->flags & IEEE80211_TX_STAT_ACK, 1, last_index); + + /* We updated the rate scale window -- if its been more than + * flush_time since the last run, schedule the flush + * again */ + spin_lock_irqsave(&rs_sta->lock, flags); + + if (!rs_sta->flush_pending && + time_after(jiffies, rs_sta->last_flush + + rs_sta->flush_time)) { + + rs_sta->last_partial_flush = jiffies; + rs_sta->flush_pending = 1; + mod_timer(&rs_sta->rate_scale_flush, + jiffies + rs_sta->flush_time); + } + + spin_unlock_irqrestore(&rs_sta->lock, flags); + + IWL_DEBUG_RATE(priv, "leave\n"); +} + +static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, + u8 index, u16 rate_mask, enum ieee80211_band band) +{ + u8 high = IWL_RATE_INVALID; + u8 low = IWL_RATE_INVALID; + struct iwl_priv *priv __maybe_unused = rs_sta->priv; + + /* 802.11A walks to the next literal adjacent rate in + * the rate table */ + if (unlikely(band == IEEE80211_BAND_5GHZ)) { + int i; + u32 mask; + + /* Find the previous rate that is in the rate mask */ + i = index - 1; + for (mask = (1 << i); i >= 0; i--, mask >>= 1) { + if (rate_mask & mask) { + low = i; + break; + } + } + + /* Find the next rate that is in the rate mask */ + i = index + 1; + for (mask = (1 << i); i < IWL_RATE_COUNT_3945; + i++, mask <<= 1) { + if (rate_mask & mask) { + high = i; + break; + } + } + + return (high << 8) | low; + } + + low = index; + while (low != IWL_RATE_INVALID) { + if (rs_sta->tgg) + low = iwl3945_rates[low].prev_rs_tgg; + else + low = iwl3945_rates[low].prev_rs; + if (low == IWL_RATE_INVALID) + break; + if (rate_mask & (1 << low)) + break; + IWL_DEBUG_RATE(priv, "Skipping masked lower rate: %d\n", low); + } + + high = index; + while (high != IWL_RATE_INVALID) { + if (rs_sta->tgg) + high = iwl3945_rates[high].next_rs_tgg; + else + high = iwl3945_rates[high].next_rs; + if (high == IWL_RATE_INVALID) + break; + if (rate_mask & (1 << high)) + break; + IWL_DEBUG_RATE(priv, "Skipping masked higher rate: %d\n", high); + } + + return (high << 8) | low; +} + +/** + * iwl3945_rs_get_rate - find the rate for the requested packet + * + * Returns the ieee80211_rate structure allocated by the driver. + * + * The rate control algorithm has no internal mapping between hw_mode's + * rate ordering and the rate ordering used by the rate control algorithm. + * + * The rate control algorithm uses a single table of rates that goes across + * the entire A/B/G spectrum vs. being limited to just one particular + * hw_mode. + * + * As such, we can't convert the index obtained below into the hw_mode's + * rate table and must reference the driver allocated rate table + * + */ +static void iwl3945_rs_get_rate(void *priv_r, struct ieee80211_sta *sta, + void *priv_sta, struct ieee80211_tx_rate_control *txrc) +{ + struct ieee80211_supported_band *sband = txrc->sband; + struct sk_buff *skb = txrc->skb; + u8 low = IWL_RATE_INVALID; + u8 high = IWL_RATE_INVALID; + u16 high_low; + int index; + struct iwl3945_rs_sta *rs_sta = priv_sta; + struct iwl3945_rate_scale_data *window = NULL; + int current_tpt = IWL_INVALID_VALUE; + int low_tpt = IWL_INVALID_VALUE; + int high_tpt = IWL_INVALID_VALUE; + u32 fail_count; + s8 scale_action = 0; + unsigned long flags; + u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0; + s8 max_rate_idx = -1; + struct iwl_priv *priv __maybe_unused = (struct iwl_priv *)priv_r; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + + IWL_DEBUG_RATE(priv, "enter\n"); + + /* Treat uninitialized rate scaling data same as non-existing. */ + if (rs_sta && !rs_sta->priv) { + IWL_DEBUG_RATE(priv, "Rate scaling information not initialized yet.\n"); + priv_sta = NULL; + } + + if (rate_control_send_low(sta, priv_sta, txrc)) + return; + + rate_mask = sta->supp_rates[sband->band]; + + /* get user max rate if set */ + max_rate_idx = txrc->max_rate_idx; + if ((sband->band == IEEE80211_BAND_5GHZ) && (max_rate_idx != -1)) + max_rate_idx += IWL_FIRST_OFDM_RATE; + if ((max_rate_idx < 0) || (max_rate_idx >= IWL_RATE_COUNT)) + max_rate_idx = -1; + + index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT_3945 - 1); + + if (sband->band == IEEE80211_BAND_5GHZ) + rate_mask = rate_mask << IWL_FIRST_OFDM_RATE; + + spin_lock_irqsave(&rs_sta->lock, flags); + + /* for recent assoc, choose best rate regarding + * to rssi value + */ + if (rs_sta->start_rate != IWL_RATE_INVALID) { + if (rs_sta->start_rate < index && + (rate_mask & (1 << rs_sta->start_rate))) + index = rs_sta->start_rate; + rs_sta->start_rate = IWL_RATE_INVALID; + } + + /* force user max rate if set by user */ + if ((max_rate_idx != -1) && (max_rate_idx < index)) { + if (rate_mask & (1 << max_rate_idx)) + index = max_rate_idx; + } + + window = &(rs_sta->win[index]); + + fail_count = window->counter - window->success_counter; + + if (((fail_count < IWL_RATE_MIN_FAILURE_TH) && + (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) { + spin_unlock_irqrestore(&rs_sta->lock, flags); + + IWL_DEBUG_RATE(priv, "Invalid average_tpt on rate %d: " + "counter: %d, success_counter: %d, " + "expected_tpt is %sNULL\n", + index, + window->counter, + window->success_counter, + rs_sta->expected_tpt ? "not " : ""); + + /* Can't calculate this yet; not enough history */ + window->average_tpt = IWL_INVALID_VALUE; + goto out; + + } + + current_tpt = window->average_tpt; + + high_low = iwl3945_get_adjacent_rate(rs_sta, index, rate_mask, + sband->band); + low = high_low & 0xff; + high = (high_low >> 8) & 0xff; + + /* If user set max rate, dont allow higher than user constrain */ + if ((max_rate_idx != -1) && (max_rate_idx < high)) + high = IWL_RATE_INVALID; + + /* Collect Measured throughputs of adjacent rates */ + if (low != IWL_RATE_INVALID) + low_tpt = rs_sta->win[low].average_tpt; + + if (high != IWL_RATE_INVALID) + high_tpt = rs_sta->win[high].average_tpt; + + spin_unlock_irqrestore(&rs_sta->lock, flags); + + scale_action = 0; + + /* Low success ratio , need to drop the rate */ + if ((window->success_ratio < IWL_RATE_DECREASE_TH) || !current_tpt) { + IWL_DEBUG_RATE(priv, "decrease rate because of low success_ratio\n"); + scale_action = -1; + /* No throughput measured yet for adjacent rates, + * try increase */ + } else if ((low_tpt == IWL_INVALID_VALUE) && + (high_tpt == IWL_INVALID_VALUE)) { + + if (high != IWL_RATE_INVALID && window->success_ratio >= IWL_RATE_INCREASE_TH) + scale_action = 1; + else if (low != IWL_RATE_INVALID) + scale_action = 0; + + /* Both adjacent throughputs are measured, but neither one has + * better throughput; we're using the best rate, don't change + * it! */ + } else if ((low_tpt != IWL_INVALID_VALUE) && + (high_tpt != IWL_INVALID_VALUE) && + (low_tpt < current_tpt) && (high_tpt < current_tpt)) { + + IWL_DEBUG_RATE(priv, "No action -- low [%d] & high [%d] < " + "current_tpt [%d]\n", + low_tpt, high_tpt, current_tpt); + scale_action = 0; + + /* At least one of the rates has better throughput */ + } else { + if (high_tpt != IWL_INVALID_VALUE) { + + /* High rate has better throughput, Increase + * rate */ + if (high_tpt > current_tpt && + window->success_ratio >= IWL_RATE_INCREASE_TH) + scale_action = 1; + else { + IWL_DEBUG_RATE(priv, + "decrease rate because of high tpt\n"); + scale_action = 0; + } + } else if (low_tpt != IWL_INVALID_VALUE) { + if (low_tpt > current_tpt) { + IWL_DEBUG_RATE(priv, + "decrease rate because of low tpt\n"); + scale_action = -1; + } else if (window->success_ratio >= IWL_RATE_INCREASE_TH) { + /* Lower rate has better + * throughput,decrease rate */ + scale_action = 1; + } + } + } + + /* Sanity check; asked for decrease, but success rate or throughput + * has been good at old rate. Don't change it. */ + if ((scale_action == -1) && (low != IWL_RATE_INVALID) && + ((window->success_ratio > IWL_RATE_HIGH_TH) || + (current_tpt > (100 * rs_sta->expected_tpt[low])))) + scale_action = 0; + + switch (scale_action) { + case -1: + + /* Decrese rate */ + if (low != IWL_RATE_INVALID) + index = low; + break; + + case 1: + /* Increase rate */ + if (high != IWL_RATE_INVALID) + index = high; + + break; + + case 0: + default: + /* No change */ + break; + } + + IWL_DEBUG_RATE(priv, "Selected %d (action %d) - low %d high %d\n", + index, scale_action, low, high); + + out: + + rs_sta->last_txrate_idx = index; + if (sband->band == IEEE80211_BAND_5GHZ) + info->control.rates[0].idx = rs_sta->last_txrate_idx - + IWL_FIRST_OFDM_RATE; + else + info->control.rates[0].idx = rs_sta->last_txrate_idx; + + IWL_DEBUG_RATE(priv, "leave: %d\n", index); +} + +#ifdef CONFIG_MAC80211_DEBUGFS +static int iwl3945_open_file_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static ssize_t iwl3945_sta_dbgfs_stats_table_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + char *buff; + int desc = 0; + int j; + ssize_t ret; + struct iwl3945_rs_sta *lq_sta = file->private_data; + + buff = kmalloc(1024, GFP_KERNEL); + if (!buff) + return -ENOMEM; + + desc += sprintf(buff + desc, "tx packets=%d last rate index=%d\n" + "rate=0x%X flush time %d\n", + lq_sta->tx_packets, + lq_sta->last_txrate_idx, + lq_sta->start_rate, jiffies_to_msecs(lq_sta->flush_time)); + for (j = 0; j < IWL_RATE_COUNT_3945; j++) { + desc += sprintf(buff+desc, + "counter=%d success=%d %%=%d\n", + lq_sta->win[j].counter, + lq_sta->win[j].success_counter, + lq_sta->win[j].success_ratio); + } + ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); + kfree(buff); + return ret; +} + +static const struct file_operations rs_sta_dbgfs_stats_table_ops = { + .read = iwl3945_sta_dbgfs_stats_table_read, + .open = iwl3945_open_file_generic, + .llseek = default_llseek, +}; + +static void iwl3945_add_debugfs(void *priv, void *priv_sta, + struct dentry *dir) +{ + struct iwl3945_rs_sta *lq_sta = priv_sta; + + lq_sta->rs_sta_dbgfs_stats_table_file = + debugfs_create_file("rate_stats_table", 0600, dir, + lq_sta, &rs_sta_dbgfs_stats_table_ops); + +} + +static void iwl3945_remove_debugfs(void *priv, void *priv_sta) +{ + struct iwl3945_rs_sta *lq_sta = priv_sta; + debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); +} +#endif + +/* + * Initialization of rate scaling information is done by driver after + * the station is added. Since mac80211 calls this function before a + * station is added we ignore it. + */ +static void iwl3945_rs_rate_init_stub(void *priv_r, + struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta) +{ +} + +static struct rate_control_ops rs_ops = { + .module = NULL, + .name = RS_NAME, + .tx_status = iwl3945_rs_tx_status, + .get_rate = iwl3945_rs_get_rate, + .rate_init = iwl3945_rs_rate_init_stub, + .alloc = iwl3945_rs_alloc, + .free = iwl3945_rs_free, + .alloc_sta = iwl3945_rs_alloc_sta, + .free_sta = iwl3945_rs_free_sta, +#ifdef CONFIG_MAC80211_DEBUGFS + .add_sta_debugfs = iwl3945_add_debugfs, + .remove_sta_debugfs = iwl3945_remove_debugfs, +#endif + +}; +void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) +{ + struct iwl_priv *priv = hw->priv; + s32 rssi = 0; + unsigned long flags; + struct iwl3945_rs_sta *rs_sta; + struct ieee80211_sta *sta; + struct iwl3945_sta_priv *psta; + + IWL_DEBUG_RATE(priv, "enter\n"); + + rcu_read_lock(); + + sta = ieee80211_find_sta(priv->contexts[IWL_RXON_CTX_BSS].vif, + priv->stations[sta_id].sta.sta.addr); + if (!sta) { + IWL_DEBUG_RATE(priv, "Unable to find station to initialize rate scaling.\n"); + rcu_read_unlock(); + return; + } + + psta = (void *) sta->drv_priv; + rs_sta = &psta->rs_sta; + + spin_lock_irqsave(&rs_sta->lock, flags); + + rs_sta->tgg = 0; + switch (priv->band) { + case IEEE80211_BAND_2GHZ: + /* TODO: this always does G, not a regression */ + if (priv->contexts[IWL_RXON_CTX_BSS].active.flags & + RXON_FLG_TGG_PROTECT_MSK) { + rs_sta->tgg = 1; + rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot; + } else + rs_sta->expected_tpt = iwl3945_expected_tpt_g; + break; + + case IEEE80211_BAND_5GHZ: + rs_sta->expected_tpt = iwl3945_expected_tpt_a; + break; + case IEEE80211_NUM_BANDS: + BUG(); + break; + } + + spin_unlock_irqrestore(&rs_sta->lock, flags); + + rssi = priv->_3945.last_rx_rssi; + if (rssi == 0) + rssi = IWL_MIN_RSSI_VAL; + + IWL_DEBUG_RATE(priv, "Network RSSI: %d\n", rssi); + + rs_sta->start_rate = iwl3945_get_rate_index_by_rssi(rssi, priv->band); + + IWL_DEBUG_RATE(priv, "leave: rssi %d assign rate index: " + "%d (plcp 0x%x)\n", rssi, rs_sta->start_rate, + iwl3945_rates[rs_sta->start_rate].plcp); + rcu_read_unlock(); +} + +int iwl3945_rate_control_register(void) +{ + return ieee80211_rate_control_register(&rs_ops); +} + +void iwl3945_rate_control_unregister(void) +{ + ieee80211_rate_control_unregister(&rs_ops); +} diff --git a/drivers/net/wireless/iwlegacy/iwl-3945.c b/drivers/net/wireless/iwlegacy/iwl-3945.c new file mode 100644 index 000000000000..8359594839e2 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-3945.c @@ -0,0 +1,2744 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iwl-fh.h" +#include "iwl-3945-fh.h" +#include "iwl-commands.h" +#include "iwl-sta.h" +#include "iwl-3945.h" +#include "iwl-eeprom.h" +#include "iwl-core.h" +#include "iwl-helpers.h" +#include "iwl-led.h" +#include "iwl-3945-led.h" +#include "iwl-3945-debugfs.h" + +#define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \ + [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ + IWL_RATE_##r##M_IEEE, \ + IWL_RATE_##ip##M_INDEX, \ + IWL_RATE_##in##M_INDEX, \ + IWL_RATE_##rp##M_INDEX, \ + IWL_RATE_##rn##M_INDEX, \ + IWL_RATE_##pp##M_INDEX, \ + IWL_RATE_##np##M_INDEX, \ + IWL_RATE_##r##M_INDEX_TABLE, \ + IWL_RATE_##ip##M_INDEX_TABLE } + +/* + * Parameter order: + * rate, prev rate, next rate, prev tgg rate, next tgg rate + * + * If there isn't a valid next or previous rate then INV is used which + * maps to IWL_RATE_INVALID + * + */ +const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945] = { + IWL_DECLARE_RATE_INFO(1, INV, 2, INV, 2, INV, 2), /* 1mbps */ + IWL_DECLARE_RATE_INFO(2, 1, 5, 1, 5, 1, 5), /* 2mbps */ + IWL_DECLARE_RATE_INFO(5, 2, 6, 2, 11, 2, 11), /*5.5mbps */ + IWL_DECLARE_RATE_INFO(11, 9, 12, 5, 12, 5, 18), /* 11mbps */ + IWL_DECLARE_RATE_INFO(6, 5, 9, 5, 11, 5, 11), /* 6mbps */ + IWL_DECLARE_RATE_INFO(9, 6, 11, 5, 11, 5, 11), /* 9mbps */ + IWL_DECLARE_RATE_INFO(12, 11, 18, 11, 18, 11, 18), /* 12mbps */ + IWL_DECLARE_RATE_INFO(18, 12, 24, 12, 24, 11, 24), /* 18mbps */ + IWL_DECLARE_RATE_INFO(24, 18, 36, 18, 36, 18, 36), /* 24mbps */ + IWL_DECLARE_RATE_INFO(36, 24, 48, 24, 48, 24, 48), /* 36mbps */ + IWL_DECLARE_RATE_INFO(48, 36, 54, 36, 54, 36, 54), /* 48mbps */ + IWL_DECLARE_RATE_INFO(54, 48, INV, 48, INV, 48, INV),/* 54mbps */ +}; + +static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index) +{ + u8 rate = iwl3945_rates[rate_index].prev_ieee; + + if (rate == IWL_RATE_INVALID) + rate = rate_index; + return rate; +} + +/* 1 = enable the iwl3945_disable_events() function */ +#define IWL_EVT_DISABLE (0) +#define IWL_EVT_DISABLE_SIZE (1532/32) + +/** + * iwl3945_disable_events - Disable selected events in uCode event log + * + * Disable an event by writing "1"s into "disable" + * bitmap in SRAM. Bit position corresponds to Event # (id/type). + * Default values of 0 enable uCode events to be logged. + * Use for only special debugging. This function is just a placeholder as-is, + * you'll need to provide the special bits! ... + * ... and set IWL_EVT_DISABLE to 1. */ +void iwl3945_disable_events(struct iwl_priv *priv) +{ + int i; + u32 base; /* SRAM address of event log header */ + u32 disable_ptr; /* SRAM address of event-disable bitmap array */ + u32 array_size; /* # of u32 entries in array */ + static const u32 evt_disable[IWL_EVT_DISABLE_SIZE] = { + 0x00000000, /* 31 - 0 Event id numbers */ + 0x00000000, /* 63 - 32 */ + 0x00000000, /* 95 - 64 */ + 0x00000000, /* 127 - 96 */ + 0x00000000, /* 159 - 128 */ + 0x00000000, /* 191 - 160 */ + 0x00000000, /* 223 - 192 */ + 0x00000000, /* 255 - 224 */ + 0x00000000, /* 287 - 256 */ + 0x00000000, /* 319 - 288 */ + 0x00000000, /* 351 - 320 */ + 0x00000000, /* 383 - 352 */ + 0x00000000, /* 415 - 384 */ + 0x00000000, /* 447 - 416 */ + 0x00000000, /* 479 - 448 */ + 0x00000000, /* 511 - 480 */ + 0x00000000, /* 543 - 512 */ + 0x00000000, /* 575 - 544 */ + 0x00000000, /* 607 - 576 */ + 0x00000000, /* 639 - 608 */ + 0x00000000, /* 671 - 640 */ + 0x00000000, /* 703 - 672 */ + 0x00000000, /* 735 - 704 */ + 0x00000000, /* 767 - 736 */ + 0x00000000, /* 799 - 768 */ + 0x00000000, /* 831 - 800 */ + 0x00000000, /* 863 - 832 */ + 0x00000000, /* 895 - 864 */ + 0x00000000, /* 927 - 896 */ + 0x00000000, /* 959 - 928 */ + 0x00000000, /* 991 - 960 */ + 0x00000000, /* 1023 - 992 */ + 0x00000000, /* 1055 - 1024 */ + 0x00000000, /* 1087 - 1056 */ + 0x00000000, /* 1119 - 1088 */ + 0x00000000, /* 1151 - 1120 */ + 0x00000000, /* 1183 - 1152 */ + 0x00000000, /* 1215 - 1184 */ + 0x00000000, /* 1247 - 1216 */ + 0x00000000, /* 1279 - 1248 */ + 0x00000000, /* 1311 - 1280 */ + 0x00000000, /* 1343 - 1312 */ + 0x00000000, /* 1375 - 1344 */ + 0x00000000, /* 1407 - 1376 */ + 0x00000000, /* 1439 - 1408 */ + 0x00000000, /* 1471 - 1440 */ + 0x00000000, /* 1503 - 1472 */ + }; + + base = le32_to_cpu(priv->card_alive.log_event_table_ptr); + if (!iwl3945_hw_valid_rtc_data_addr(base)) { + IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); + return; + } + + disable_ptr = iwl_legacy_read_targ_mem(priv, base + (4 * sizeof(u32))); + array_size = iwl_legacy_read_targ_mem(priv, base + (5 * sizeof(u32))); + + if (IWL_EVT_DISABLE && (array_size == IWL_EVT_DISABLE_SIZE)) { + IWL_DEBUG_INFO(priv, "Disabling selected uCode log events at 0x%x\n", + disable_ptr); + for (i = 0; i < IWL_EVT_DISABLE_SIZE; i++) + iwl_legacy_write_targ_mem(priv, + disable_ptr + (i * sizeof(u32)), + evt_disable[i]); + + } else { + IWL_DEBUG_INFO(priv, "Selected uCode log events may be disabled\n"); + IWL_DEBUG_INFO(priv, " by writing \"1\"s into disable bitmap\n"); + IWL_DEBUG_INFO(priv, " in SRAM at 0x%x, size %d u32s\n", + disable_ptr, array_size); + } + +} + +static int iwl3945_hwrate_to_plcp_idx(u8 plcp) +{ + int idx; + + for (idx = 0; idx < IWL_RATE_COUNT_3945; idx++) + if (iwl3945_rates[idx].plcp == plcp) + return idx; + return -1; +} + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +#define TX_STATUS_ENTRY(x) case TX_3945_STATUS_FAIL_ ## x: return #x + +static const char *iwl3945_get_tx_fail_reason(u32 status) +{ + switch (status & TX_STATUS_MSK) { + case TX_3945_STATUS_SUCCESS: + return "SUCCESS"; + TX_STATUS_ENTRY(SHORT_LIMIT); + TX_STATUS_ENTRY(LONG_LIMIT); + TX_STATUS_ENTRY(FIFO_UNDERRUN); + TX_STATUS_ENTRY(MGMNT_ABORT); + TX_STATUS_ENTRY(NEXT_FRAG); + TX_STATUS_ENTRY(LIFE_EXPIRE); + TX_STATUS_ENTRY(DEST_PS); + TX_STATUS_ENTRY(ABORTED); + TX_STATUS_ENTRY(BT_RETRY); + TX_STATUS_ENTRY(STA_INVALID); + TX_STATUS_ENTRY(FRAG_DROPPED); + TX_STATUS_ENTRY(TID_DISABLE); + TX_STATUS_ENTRY(FRAME_FLUSHED); + TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL); + TX_STATUS_ENTRY(TX_LOCKED); + TX_STATUS_ENTRY(NO_BEACON_ON_RADAR); + } + + return "UNKNOWN"; +} +#else +static inline const char *iwl3945_get_tx_fail_reason(u32 status) +{ + return ""; +} +#endif + +/* + * get ieee prev rate from rate scale table. + * for A and B mode we need to overright prev + * value + */ +int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate) +{ + int next_rate = iwl3945_get_prev_ieee_rate(rate); + + switch (priv->band) { + case IEEE80211_BAND_5GHZ: + if (rate == IWL_RATE_12M_INDEX) + next_rate = IWL_RATE_9M_INDEX; + else if (rate == IWL_RATE_6M_INDEX) + next_rate = IWL_RATE_6M_INDEX; + break; + case IEEE80211_BAND_2GHZ: + if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) && + iwl_legacy_is_associated(priv, IWL_RXON_CTX_BSS)) { + if (rate == IWL_RATE_11M_INDEX) + next_rate = IWL_RATE_5M_INDEX; + } + break; + + default: + break; + } + + return next_rate; +} + + +/** + * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd + * + * When FW advances 'R' index, all entries between old and new 'R' index + * need to be reclaimed. As result, some free space forms. If there is + * enough free space (> low mark), wake the stack that feeds us. + */ +static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, + int txq_id, int index) +{ + struct iwl_tx_queue *txq = &priv->txq[txq_id]; + struct iwl_queue *q = &txq->q; + struct iwl_tx_info *tx_info; + + BUG_ON(txq_id == IWL39_CMD_QUEUE_NUM); + + for (index = iwl_legacy_queue_inc_wrap(index, q->n_bd); + q->read_ptr != index; + q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd)) { + + tx_info = &txq->txb[txq->q.read_ptr]; + ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb); + tx_info->skb = NULL; + priv->cfg->ops->lib->txq_free_tfd(priv, txq); + } + + if (iwl_legacy_queue_space(q) > q->low_mark && (txq_id >= 0) && + (txq_id != IWL39_CMD_QUEUE_NUM) && + priv->mac80211_registered) + iwl_legacy_wake_queue(priv, txq); +} + +/** + * iwl3945_rx_reply_tx - Handle Tx response + */ +static void iwl3945_rx_reply_tx(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + u16 sequence = le16_to_cpu(pkt->hdr.sequence); + int txq_id = SEQ_TO_QUEUE(sequence); + int index = SEQ_TO_INDEX(sequence); + struct iwl_tx_queue *txq = &priv->txq[txq_id]; + struct ieee80211_tx_info *info; + struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; + u32 status = le32_to_cpu(tx_resp->status); + int rate_idx; + int fail; + + if ((index >= txq->q.n_bd) || (iwl_legacy_queue_used(&txq->q, index) == 0)) { + IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " + "is out of range [0-%d] %d %d\n", txq_id, + index, txq->q.n_bd, txq->q.write_ptr, + txq->q.read_ptr); + return; + } + + txq->time_stamp = jiffies; + info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); + ieee80211_tx_info_clear_status(info); + + /* Fill the MRR chain with some info about on-chip retransmissions */ + rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate); + if (info->band == IEEE80211_BAND_5GHZ) + rate_idx -= IWL_FIRST_OFDM_RATE; + + fail = tx_resp->failure_frame; + + info->status.rates[0].idx = rate_idx; + info->status.rates[0].count = fail + 1; /* add final attempt */ + + /* tx_status->rts_retry_count = tx_resp->failure_rts; */ + info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ? + IEEE80211_TX_STAT_ACK : 0; + + IWL_DEBUG_TX(priv, "Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n", + txq_id, iwl3945_get_tx_fail_reason(status), status, + tx_resp->rate, tx_resp->failure_frame); + + IWL_DEBUG_TX_REPLY(priv, "Tx queue reclaim %d\n", index); + iwl3945_tx_queue_reclaim(priv, txq_id, index); + + if (status & TX_ABORT_REQUIRED_MSK) + IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); +} + + + +/***************************************************************************** + * + * Intel PRO/Wireless 3945ABG/BG Network Connection + * + * RX handler implementations + * + *****************************************************************************/ +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS +static void iwl3945_accumulative_statistics(struct iwl_priv *priv, + __le32 *stats) +{ + int i; + __le32 *prev_stats; + u32 *accum_stats; + u32 *delta, *max_delta; + + prev_stats = (__le32 *)&priv->_3945.statistics; + accum_stats = (u32 *)&priv->_3945.accum_statistics; + delta = (u32 *)&priv->_3945.delta_statistics; + max_delta = (u32 *)&priv->_3945.max_delta; + + for (i = sizeof(__le32); i < sizeof(struct iwl3945_notif_statistics); + i += sizeof(__le32), stats++, prev_stats++, delta++, + max_delta++, accum_stats++) { + if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { + *delta = (le32_to_cpu(*stats) - + le32_to_cpu(*prev_stats)); + *accum_stats += *delta; + if (*delta > *max_delta) + *max_delta = *delta; + } + } + + /* reset accumulative statistics for "no-counter" type statistics */ + priv->_3945.accum_statistics.general.temperature = + priv->_3945.statistics.general.temperature; + priv->_3945.accum_statistics.general.ttl_timestamp = + priv->_3945.statistics.general.ttl_timestamp; +} +#endif + +void iwl3945_hw_rx_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + + IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", + (int)sizeof(struct iwl3945_notif_statistics), + le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS + iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw); +#endif + iwl_legacy_recover_from_statistics(priv, pkt); + + memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics)); +} + +void iwl3945_reply_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + __le32 *flag = (__le32 *)&pkt->u.raw; + + if (le32_to_cpu(*flag) & UCODE_STATISTICS_CLEAR_MSK) { +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS + memset(&priv->_3945.accum_statistics, 0, + sizeof(struct iwl3945_notif_statistics)); + memset(&priv->_3945.delta_statistics, 0, + sizeof(struct iwl3945_notif_statistics)); + memset(&priv->_3945.max_delta, 0, + sizeof(struct iwl3945_notif_statistics)); +#endif + IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); + } + iwl3945_hw_rx_statistics(priv, rxb); +} + + +/****************************************************************************** + * + * Misc. internal state and helper functions + * + ******************************************************************************/ + +/* This is necessary only for a number of statistics, see the caller. */ +static int iwl3945_is_network_packet(struct iwl_priv *priv, + struct ieee80211_hdr *header) +{ + /* Filter incoming packets to determine if they are targeted toward + * this network, discarding packets coming from ourselves */ + switch (priv->iw_mode) { + case NL80211_IFTYPE_ADHOC: /* Header: Dest. | Source | BSSID */ + /* packets to our IBSS update information */ + return !compare_ether_addr(header->addr3, priv->bssid); + case NL80211_IFTYPE_STATION: /* Header: Dest. | AP{BSSID} | Source */ + /* packets to our IBSS update information */ + return !compare_ether_addr(header->addr2, priv->bssid); + default: + return 1; + } +} + +static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct ieee80211_rx_status *stats) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); + struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); + struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); + u16 len = le16_to_cpu(rx_hdr->len); + struct sk_buff *skb; + __le16 fc = hdr->frame_control; + + /* We received data from the HW, so stop the watchdog */ + if (unlikely(len + IWL39_RX_FRAME_SIZE > + PAGE_SIZE << priv->hw_params.rx_page_order)) { + IWL_DEBUG_DROP(priv, "Corruption detected!\n"); + return; + } + + /* We only process data packets if the interface is open */ + if (unlikely(!priv->is_open)) { + IWL_DEBUG_DROP_LIMIT(priv, + "Dropping packet while interface is not open.\n"); + return; + } + + skb = dev_alloc_skb(128); + if (!skb) { + IWL_ERR(priv, "dev_alloc_skb failed\n"); + return; + } + + if (!iwl3945_mod_params.sw_crypto) + iwl_legacy_set_decrypted_flag(priv, + (struct ieee80211_hdr *)rxb_addr(rxb), + le32_to_cpu(rx_end->status), stats); + + skb_add_rx_frag(skb, 0, rxb->page, + (void *)rx_hdr->payload - (void *)pkt, len); + + iwl_legacy_update_stats(priv, false, fc, len); + memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); + + ieee80211_rx(priv->hw, skb); + priv->alloc_rxb_page--; + rxb->page = NULL; +} + +#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) + +static void iwl3945_rx_reply_rx(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct ieee80211_hdr *header; + struct ieee80211_rx_status rx_status; + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); + struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); + struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); + u16 rx_stats_sig_avg __maybe_unused = le16_to_cpu(rx_stats->sig_avg); + u16 rx_stats_noise_diff __maybe_unused = le16_to_cpu(rx_stats->noise_diff); + u8 network_packet; + + rx_status.flag = 0; + rx_status.mactime = le64_to_cpu(rx_end->timestamp); + rx_status.band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? + IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; + rx_status.freq = + ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel), + rx_status.band); + + rx_status.rate_idx = iwl3945_hwrate_to_plcp_idx(rx_hdr->rate); + if (rx_status.band == IEEE80211_BAND_5GHZ) + rx_status.rate_idx -= IWL_FIRST_OFDM_RATE; + + rx_status.antenna = (le16_to_cpu(rx_hdr->phy_flags) & + RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4; + + /* set the preamble flag if appropriate */ + if (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK) + rx_status.flag |= RX_FLAG_SHORTPRE; + + if ((unlikely(rx_stats->phy_count > 20))) { + IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n", + rx_stats->phy_count); + return; + } + + if (!(rx_end->status & RX_RES_STATUS_NO_CRC32_ERROR) + || !(rx_end->status & RX_RES_STATUS_NO_RXE_OVERFLOW)) { + IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n", rx_end->status); + return; + } + + + + /* Convert 3945's rssi indicator to dBm */ + rx_status.signal = rx_stats->rssi - IWL39_RSSI_OFFSET; + + IWL_DEBUG_STATS(priv, "Rssi %d sig_avg %d noise_diff %d\n", + rx_status.signal, rx_stats_sig_avg, + rx_stats_noise_diff); + + header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); + + network_packet = iwl3945_is_network_packet(priv, header); + + IWL_DEBUG_STATS_LIMIT(priv, "[%c] %d RSSI:%d Signal:%u, Rate:%u\n", + network_packet ? '*' : ' ', + le16_to_cpu(rx_hdr->channel), + rx_status.signal, rx_status.signal, + rx_status.rate_idx); + + iwl_legacy_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len), + header); + + if (network_packet) { + priv->_3945.last_beacon_time = + le32_to_cpu(rx_end->beacon_timestamp); + priv->_3945.last_tsf = le64_to_cpu(rx_end->timestamp); + priv->_3945.last_rx_rssi = rx_status.signal; + } + + iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status); +} + +int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, + struct iwl_tx_queue *txq, + dma_addr_t addr, u16 len, u8 reset, u8 pad) +{ + int count; + struct iwl_queue *q; + struct iwl3945_tfd *tfd, *tfd_tmp; + + q = &txq->q; + tfd_tmp = (struct iwl3945_tfd *)txq->tfds; + tfd = &tfd_tmp[q->write_ptr]; + + if (reset) + memset(tfd, 0, sizeof(*tfd)); + + count = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags)); + + if ((count >= NUM_TFD_CHUNKS) || (count < 0)) { + IWL_ERR(priv, "Error can not send more than %d chunks\n", + NUM_TFD_CHUNKS); + return -EINVAL; + } + + tfd->tbs[count].addr = cpu_to_le32(addr); + tfd->tbs[count].len = cpu_to_le32(len); + + count++; + + tfd->control_flags = cpu_to_le32(TFD_CTL_COUNT_SET(count) | + TFD_CTL_PAD_SET(pad)); + + return 0; +} + +/** + * iwl3945_hw_txq_free_tfd - Free one TFD, those at index [txq->q.read_ptr] + * + * Does NOT advance any indexes + */ +void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) +{ + struct iwl3945_tfd *tfd_tmp = (struct iwl3945_tfd *)txq->tfds; + int index = txq->q.read_ptr; + struct iwl3945_tfd *tfd = &tfd_tmp[index]; + struct pci_dev *dev = priv->pci_dev; + int i; + int counter; + + /* sanity check */ + counter = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags)); + if (counter > NUM_TFD_CHUNKS) { + IWL_ERR(priv, "Too many chunks: %i\n", counter); + /* @todo issue fatal error, it is quite serious situation */ + return; + } + + /* Unmap tx_cmd */ + if (counter) + pci_unmap_single(dev, + dma_unmap_addr(&txq->meta[index], mapping), + dma_unmap_len(&txq->meta[index], len), + PCI_DMA_TODEVICE); + + /* unmap chunks if any */ + + for (i = 1; i < counter; i++) + pci_unmap_single(dev, le32_to_cpu(tfd->tbs[i].addr), + le32_to_cpu(tfd->tbs[i].len), PCI_DMA_TODEVICE); + + /* free SKB */ + if (txq->txb) { + struct sk_buff *skb; + + skb = txq->txb[txq->q.read_ptr].skb; + + /* can be called from irqs-disabled context */ + if (skb) { + dev_kfree_skb_any(skb); + txq->txb[txq->q.read_ptr].skb = NULL; + } + } +} + +/** + * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD: + * +*/ +void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, + struct iwl_device_cmd *cmd, + struct ieee80211_tx_info *info, + struct ieee80211_hdr *hdr, + int sta_id, int tx_id) +{ + u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value; + u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT_3945); + u16 rate_mask; + int rate; + u8 rts_retry_limit; + u8 data_retry_limit; + __le32 tx_flags; + __le16 fc = hdr->frame_control; + struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload; + + rate = iwl3945_rates[rate_index].plcp; + tx_flags = tx_cmd->tx_flags; + + /* We need to figure out how to get the sta->supp_rates while + * in this running context */ + rate_mask = IWL_RATES_MASK_3945; + + /* Set retry limit on DATA packets and Probe Responses*/ + if (ieee80211_is_probe_resp(fc)) + data_retry_limit = 3; + else + data_retry_limit = IWL_DEFAULT_TX_RETRY; + tx_cmd->data_retry_limit = data_retry_limit; + + if (tx_id >= IWL39_CMD_QUEUE_NUM) + rts_retry_limit = 3; + else + rts_retry_limit = 7; + + if (data_retry_limit < rts_retry_limit) + rts_retry_limit = data_retry_limit; + tx_cmd->rts_retry_limit = rts_retry_limit; + + tx_cmd->rate = rate; + tx_cmd->tx_flags = tx_flags; + + /* OFDM */ + tx_cmd->supp_rates[0] = + ((rate_mask & IWL_OFDM_RATES_MASK) >> IWL_FIRST_OFDM_RATE) & 0xFF; + + /* CCK */ + tx_cmd->supp_rates[1] = (rate_mask & 0xF); + + IWL_DEBUG_RATE(priv, "Tx sta id: %d, rate: %d (plcp), flags: 0x%4X " + "cck/ofdm mask: 0x%x/0x%x\n", sta_id, + tx_cmd->rate, le32_to_cpu(tx_cmd->tx_flags), + tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]); +} + +static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate) +{ + unsigned long flags_spin; + struct iwl_station_entry *station; + + if (sta_id == IWL_INVALID_STATION) + return IWL_INVALID_STATION; + + spin_lock_irqsave(&priv->sta_lock, flags_spin); + station = &priv->stations[sta_id]; + + station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK; + station->sta.rate_n_flags = cpu_to_le16(tx_rate); + station->sta.mode = STA_CONTROL_MODIFY_MSK; + iwl_legacy_send_add_sta(priv, &station->sta, CMD_ASYNC); + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + + IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n", + sta_id, tx_rate); + return sta_id; +} + +static void iwl3945_set_pwr_vmain(struct iwl_priv *priv) +{ +/* + * (for documentation purposes) + * to set power to V_AUX, do + + if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) { + iwl_legacy_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, + APMG_PS_CTRL_VAL_PWR_SRC_VAUX, + ~APMG_PS_CTRL_MSK_PWR_SRC); + + iwl_poll_bit(priv, CSR_GPIO_IN, + CSR_GPIO_IN_VAL_VAUX_PWR_SRC, + CSR_GPIO_IN_BIT_AUX_POWER, 5000); + } + */ + + iwl_legacy_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, + APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, + ~APMG_PS_CTRL_MSK_PWR_SRC); + + iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC, + CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */ +} + +static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) +{ + iwl_legacy_write_direct32(priv, FH39_RCSR_RBD_BASE(0), rxq->bd_dma); + iwl_legacy_write_direct32(priv, FH39_RCSR_RPTR_ADDR(0), + rxq->rb_stts_dma); + iwl_legacy_write_direct32(priv, FH39_RCSR_WPTR(0), 0); + iwl_legacy_write_direct32(priv, FH39_RCSR_CONFIG(0), + FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE | + FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE | + FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN | + FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 | + (RX_QUEUE_SIZE_LOG << FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE) | + FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST | + (1 << FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH) | + FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH); + + /* fake read to flush all prev I/O */ + iwl_legacy_read_direct32(priv, FH39_RSSR_CTRL); + + return 0; +} + +static int iwl3945_tx_reset(struct iwl_priv *priv) +{ + + /* bypass mode */ + iwl_legacy_write_prph(priv, ALM_SCD_MODE_REG, 0x2); + + /* RA 0 is active */ + iwl_legacy_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01); + + /* all 6 fifo are active */ + iwl_legacy_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f); + + iwl_legacy_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000); + iwl_legacy_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002); + iwl_legacy_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004); + iwl_legacy_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005); + + iwl_legacy_write_direct32(priv, FH39_TSSR_CBB_BASE, + priv->_3945.shared_phys); + + iwl_legacy_write_direct32(priv, FH39_TSSR_MSG_CONFIG, + FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON | + FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON | + FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B | + FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON | + FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON | + FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH | + FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH); + + + return 0; +} + +/** + * iwl3945_txq_ctx_reset - Reset TX queue context + * + * Destroys all DMA structures and initialize them again + */ +static int iwl3945_txq_ctx_reset(struct iwl_priv *priv) +{ + int rc; + int txq_id, slots_num; + + iwl3945_hw_txq_ctx_free(priv); + + /* allocate tx queue structure */ + rc = iwl_legacy_alloc_txq_mem(priv); + if (rc) + return rc; + + /* Tx CMD queue */ + rc = iwl3945_tx_reset(priv); + if (rc) + goto error; + + /* Tx queue(s) */ + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { + slots_num = (txq_id == IWL39_CMD_QUEUE_NUM) ? + TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; + rc = iwl_legacy_tx_queue_init(priv, &priv->txq[txq_id], + slots_num, txq_id); + if (rc) { + IWL_ERR(priv, "Tx %d queue init failed\n", txq_id); + goto error; + } + } + + return rc; + + error: + iwl3945_hw_txq_ctx_free(priv); + return rc; +} + + +/* + * Start up 3945's basic functionality after it has been reset + * (e.g. after platform boot, or shutdown via iwl_legacy_apm_stop()) + * NOTE: This does not load uCode nor start the embedded processor + */ +static int iwl3945_apm_init(struct iwl_priv *priv) +{ + int ret = iwl_legacy_apm_init(priv); + + /* Clear APMG (NIC's internal power management) interrupts */ + iwl_legacy_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0); + iwl_legacy_write_prph(priv, APMG_RTC_INT_STT_REG, 0xFFFFFFFF); + + /* Reset radio chip */ + iwl_legacy_set_bits_prph(priv, APMG_PS_CTRL_REG, + APMG_PS_CTRL_VAL_RESET_REQ); + udelay(5); + iwl_legacy_clear_bits_prph(priv, APMG_PS_CTRL_REG, + APMG_PS_CTRL_VAL_RESET_REQ); + + return ret; +} + +static void iwl3945_nic_config(struct iwl_priv *priv) +{ + struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; + unsigned long flags; + u8 rev_id = 0; + + spin_lock_irqsave(&priv->lock, flags); + + /* Determine HW type */ + pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id); + + IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); + + if (rev_id & PCI_CFG_REV_ID_BIT_RTP) + IWL_DEBUG_INFO(priv, "RTP type\n"); + else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) { + IWL_DEBUG_INFO(priv, "3945 RADIO-MB type\n"); + iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR39_HW_IF_CONFIG_REG_BIT_3945_MB); + } else { + IWL_DEBUG_INFO(priv, "3945 RADIO-MM type\n"); + iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR39_HW_IF_CONFIG_REG_BIT_3945_MM); + } + + if (EEPROM_SKU_CAP_OP_MODE_MRC == eeprom->sku_cap) { + IWL_DEBUG_INFO(priv, "SKU OP mode is mrc\n"); + iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC); + } else + IWL_DEBUG_INFO(priv, "SKU OP mode is basic\n"); + + if ((eeprom->board_revision & 0xF0) == 0xD0) { + IWL_DEBUG_INFO(priv, "3945ABG revision is 0x%X\n", + eeprom->board_revision); + iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE); + } else { + IWL_DEBUG_INFO(priv, "3945ABG revision is 0x%X\n", + eeprom->board_revision); + iwl_legacy_clear_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE); + } + + if (eeprom->almgor_m_version <= 1) { + iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A); + IWL_DEBUG_INFO(priv, "Card M type A version is 0x%X\n", + eeprom->almgor_m_version); + } else { + IWL_DEBUG_INFO(priv, "Card M type B version is 0x%X\n", + eeprom->almgor_m_version); + iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B); + } + spin_unlock_irqrestore(&priv->lock, flags); + + if (eeprom->sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE) + IWL_DEBUG_RF_KILL(priv, "SW RF KILL supported in EEPROM.\n"); + + if (eeprom->sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE) + IWL_DEBUG_RF_KILL(priv, "HW RF KILL supported in EEPROM.\n"); +} + +int iwl3945_hw_nic_init(struct iwl_priv *priv) +{ + int rc; + unsigned long flags; + struct iwl_rx_queue *rxq = &priv->rxq; + + spin_lock_irqsave(&priv->lock, flags); + priv->cfg->ops->lib->apm_ops.init(priv); + spin_unlock_irqrestore(&priv->lock, flags); + + iwl3945_set_pwr_vmain(priv); + + priv->cfg->ops->lib->apm_ops.config(priv); + + /* Allocate the RX queue, or reset if it is already allocated */ + if (!rxq->bd) { + rc = iwl_legacy_rx_queue_alloc(priv); + if (rc) { + IWL_ERR(priv, "Unable to initialize Rx queue\n"); + return -ENOMEM; + } + } else + iwl3945_rx_queue_reset(priv, rxq); + + iwl3945_rx_replenish(priv); + + iwl3945_rx_init(priv, rxq); + + + /* Look at using this instead: + rxq->need_update = 1; + iwl_legacy_rx_queue_update_write_ptr(priv, rxq); + */ + + iwl_legacy_write_direct32(priv, FH39_RCSR_WPTR(0), rxq->write & ~7); + + rc = iwl3945_txq_ctx_reset(priv); + if (rc) + return rc; + + set_bit(STATUS_INIT, &priv->status); + + return 0; +} + +/** + * iwl3945_hw_txq_ctx_free - Free TXQ Context + * + * Destroy all TX DMA queues and structures + */ +void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv) +{ + int txq_id; + + /* Tx queues */ + if (priv->txq) + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; + txq_id++) + if (txq_id == IWL39_CMD_QUEUE_NUM) + iwl_legacy_cmd_queue_free(priv); + else + iwl_legacy_tx_queue_free(priv, txq_id); + + /* free tx queue structure */ + iwl_legacy_txq_mem(priv); +} + +void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv) +{ + int txq_id; + + /* stop SCD */ + iwl_legacy_write_prph(priv, ALM_SCD_MODE_REG, 0); + iwl_legacy_write_prph(priv, ALM_SCD_TXFACT_REG, 0); + + /* reset TFD queues */ + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { + iwl_legacy_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), 0x0); + iwl_poll_direct_bit(priv, FH39_TSSR_TX_STATUS, + FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id), + 1000); + } + + iwl3945_hw_txq_ctx_free(priv); +} + +/** + * iwl3945_hw_reg_adjust_power_by_temp + * return index delta into power gain settings table +*/ +static int iwl3945_hw_reg_adjust_power_by_temp(int new_reading, int old_reading) +{ + return (new_reading - old_reading) * (-11) / 100; +} + +/** + * iwl3945_hw_reg_temp_out_of_range - Keep temperature in sane range + */ +static inline int iwl3945_hw_reg_temp_out_of_range(int temperature) +{ + return ((temperature < -260) || (temperature > 25)) ? 1 : 0; +} + +int iwl3945_hw_get_temperature(struct iwl_priv *priv) +{ + return iwl_read32(priv, CSR_UCODE_DRV_GP2); +} + +/** + * iwl3945_hw_reg_txpower_get_temperature + * get the current temperature by reading from NIC +*/ +static int iwl3945_hw_reg_txpower_get_temperature(struct iwl_priv *priv) +{ + struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; + int temperature; + + temperature = iwl3945_hw_get_temperature(priv); + + /* driver's okay range is -260 to +25. + * human readable okay range is 0 to +285 */ + IWL_DEBUG_INFO(priv, "Temperature: %d\n", temperature + IWL_TEMP_CONVERT); + + /* handle insane temp reading */ + if (iwl3945_hw_reg_temp_out_of_range(temperature)) { + IWL_ERR(priv, "Error bad temperature value %d\n", temperature); + + /* if really really hot(?), + * substitute the 3rd band/group's temp measured at factory */ + if (priv->last_temperature > 100) + temperature = eeprom->groups[2].temperature; + else /* else use most recent "sane" value from driver */ + temperature = priv->last_temperature; + } + + return temperature; /* raw, not "human readable" */ +} + +/* Adjust Txpower only if temperature variance is greater than threshold. + * + * Both are lower than older versions' 9 degrees */ +#define IWL_TEMPERATURE_LIMIT_TIMER 6 + +/** + * iwl3945_is_temp_calib_needed - determines if new calibration is needed + * + * records new temperature in tx_mgr->temperature. + * replaces tx_mgr->last_temperature *only* if calib needed + * (assumes caller will actually do the calibration!). */ +static int iwl3945_is_temp_calib_needed(struct iwl_priv *priv) +{ + int temp_diff; + + priv->temperature = iwl3945_hw_reg_txpower_get_temperature(priv); + temp_diff = priv->temperature - priv->last_temperature; + + /* get absolute value */ + if (temp_diff < 0) { + IWL_DEBUG_POWER(priv, "Getting cooler, delta %d,\n", temp_diff); + temp_diff = -temp_diff; + } else if (temp_diff == 0) + IWL_DEBUG_POWER(priv, "Same temp,\n"); + else + IWL_DEBUG_POWER(priv, "Getting warmer, delta %d,\n", temp_diff); + + /* if we don't need calibration, *don't* update last_temperature */ + if (temp_diff < IWL_TEMPERATURE_LIMIT_TIMER) { + IWL_DEBUG_POWER(priv, "Timed thermal calib not needed\n"); + return 0; + } + + IWL_DEBUG_POWER(priv, "Timed thermal calib needed\n"); + + /* assume that caller will actually do calib ... + * update the "last temperature" value */ + priv->last_temperature = priv->temperature; + return 1; +} + +#define IWL_MAX_GAIN_ENTRIES 78 +#define IWL_CCK_FROM_OFDM_POWER_DIFF -5 +#define IWL_CCK_FROM_OFDM_INDEX_DIFF (10) + +/* radio and DSP power table, each step is 1/2 dB. + * 1st number is for RF analog gain, 2nd number is for DSP pre-DAC gain. */ +static struct iwl3945_tx_power power_gain_table[2][IWL_MAX_GAIN_ENTRIES] = { + { + {251, 127}, /* 2.4 GHz, highest power */ + {251, 127}, + {251, 127}, + {251, 127}, + {251, 125}, + {251, 110}, + {251, 105}, + {251, 98}, + {187, 125}, + {187, 115}, + {187, 108}, + {187, 99}, + {243, 119}, + {243, 111}, + {243, 105}, + {243, 97}, + {243, 92}, + {211, 106}, + {211, 100}, + {179, 120}, + {179, 113}, + {179, 107}, + {147, 125}, + {147, 119}, + {147, 112}, + {147, 106}, + {147, 101}, + {147, 97}, + {147, 91}, + {115, 107}, + {235, 121}, + {235, 115}, + {235, 109}, + {203, 127}, + {203, 121}, + {203, 115}, + {203, 108}, + {203, 102}, + {203, 96}, + {203, 92}, + {171, 110}, + {171, 104}, + {171, 98}, + {139, 116}, + {227, 125}, + {227, 119}, + {227, 113}, + {227, 107}, + {227, 101}, + {227, 96}, + {195, 113}, + {195, 106}, + {195, 102}, + {195, 95}, + {163, 113}, + {163, 106}, + {163, 102}, + {163, 95}, + {131, 113}, + {131, 106}, + {131, 102}, + {131, 95}, + {99, 113}, + {99, 106}, + {99, 102}, + {99, 95}, + {67, 113}, + {67, 106}, + {67, 102}, + {67, 95}, + {35, 113}, + {35, 106}, + {35, 102}, + {35, 95}, + {3, 113}, + {3, 106}, + {3, 102}, + {3, 95} }, /* 2.4 GHz, lowest power */ + { + {251, 127}, /* 5.x GHz, highest power */ + {251, 120}, + {251, 114}, + {219, 119}, + {219, 101}, + {187, 113}, + {187, 102}, + {155, 114}, + {155, 103}, + {123, 117}, + {123, 107}, + {123, 99}, + {123, 92}, + {91, 108}, + {59, 125}, + {59, 118}, + {59, 109}, + {59, 102}, + {59, 96}, + {59, 90}, + {27, 104}, + {27, 98}, + {27, 92}, + {115, 118}, + {115, 111}, + {115, 104}, + {83, 126}, + {83, 121}, + {83, 113}, + {83, 105}, + {83, 99}, + {51, 118}, + {51, 111}, + {51, 104}, + {51, 98}, + {19, 116}, + {19, 109}, + {19, 102}, + {19, 98}, + {19, 93}, + {171, 113}, + {171, 107}, + {171, 99}, + {139, 120}, + {139, 113}, + {139, 107}, + {139, 99}, + {107, 120}, + {107, 113}, + {107, 107}, + {107, 99}, + {75, 120}, + {75, 113}, + {75, 107}, + {75, 99}, + {43, 120}, + {43, 113}, + {43, 107}, + {43, 99}, + {11, 120}, + {11, 113}, + {11, 107}, + {11, 99}, + {131, 107}, + {131, 99}, + {99, 120}, + {99, 113}, + {99, 107}, + {99, 99}, + {67, 120}, + {67, 113}, + {67, 107}, + {67, 99}, + {35, 120}, + {35, 113}, + {35, 107}, + {35, 99}, + {3, 120} } /* 5.x GHz, lowest power */ +}; + +static inline u8 iwl3945_hw_reg_fix_power_index(int index) +{ + if (index < 0) + return 0; + if (index >= IWL_MAX_GAIN_ENTRIES) + return IWL_MAX_GAIN_ENTRIES - 1; + return (u8) index; +} + +/* Kick off thermal recalibration check every 60 seconds */ +#define REG_RECALIB_PERIOD (60) + +/** + * iwl3945_hw_reg_set_scan_power - Set Tx power for scan probe requests + * + * Set (in our channel info database) the direct scan Tx power for 1 Mbit (CCK) + * or 6 Mbit (OFDM) rates. + */ +static void iwl3945_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index, + s32 rate_index, const s8 *clip_pwrs, + struct iwl_channel_info *ch_info, + int band_index) +{ + struct iwl3945_scan_power_info *scan_power_info; + s8 power; + u8 power_index; + + scan_power_info = &ch_info->scan_pwr_info[scan_tbl_index]; + + /* use this channel group's 6Mbit clipping/saturation pwr, + * but cap at regulatory scan power restriction (set during init + * based on eeprom channel data) for this channel. */ + power = min(ch_info->scan_power, clip_pwrs[IWL_RATE_6M_INDEX_TABLE]); + + power = min(power, priv->tx_power_user_lmt); + scan_power_info->requested_power = power; + + /* find difference between new scan *power* and current "normal" + * Tx *power* for 6Mb. Use this difference (x2) to adjust the + * current "normal" temperature-compensated Tx power *index* for + * this rate (1Mb or 6Mb) to yield new temp-compensated scan power + * *index*. */ + power_index = ch_info->power_info[rate_index].power_table_index + - (power - ch_info->power_info + [IWL_RATE_6M_INDEX_TABLE].requested_power) * 2; + + /* store reference index that we use when adjusting *all* scan + * powers. So we can accommodate user (all channel) or spectrum + * management (single channel) power changes "between" temperature + * feedback compensation procedures. + * don't force fit this reference index into gain table; it may be a + * negative number. This will help avoid errors when we're at + * the lower bounds (highest gains, for warmest temperatures) + * of the table. */ + + /* don't exceed table bounds for "real" setting */ + power_index = iwl3945_hw_reg_fix_power_index(power_index); + + scan_power_info->power_table_index = power_index; + scan_power_info->tpc.tx_gain = + power_gain_table[band_index][power_index].tx_gain; + scan_power_info->tpc.dsp_atten = + power_gain_table[band_index][power_index].dsp_atten; +} + +/** + * iwl3945_send_tx_power - fill in Tx Power command with gain settings + * + * Configures power settings for all rates for the current channel, + * using values from channel info struct, and send to NIC + */ +static int iwl3945_send_tx_power(struct iwl_priv *priv) +{ + int rate_idx, i; + const struct iwl_channel_info *ch_info = NULL; + struct iwl3945_txpowertable_cmd txpower = { + .channel = priv->contexts[IWL_RXON_CTX_BSS].active.channel, + }; + u16 chan; + + if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status), + "TX Power requested while scanning!\n")) + return -EAGAIN; + + chan = le16_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.channel); + + txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1; + ch_info = iwl_legacy_get_channel_info(priv, priv->band, chan); + if (!ch_info) { + IWL_ERR(priv, + "Failed to get channel info for channel %d [%d]\n", + chan, priv->band); + return -EINVAL; + } + + if (!iwl_legacy_is_channel_valid(ch_info)) { + IWL_DEBUG_POWER(priv, "Not calling TX_PWR_TABLE_CMD on " + "non-Tx channel.\n"); + return 0; + } + + /* fill cmd with power settings for all rates for current channel */ + /* Fill OFDM rate */ + for (rate_idx = IWL_FIRST_OFDM_RATE, i = 0; + rate_idx <= IWL39_LAST_OFDM_RATE; rate_idx++, i++) { + + txpower.power[i].tpc = ch_info->power_info[i].tpc; + txpower.power[i].rate = iwl3945_rates[rate_idx].plcp; + + IWL_DEBUG_POWER(priv, "ch %d:%d rf %d dsp %3d rate code 0x%02x\n", + le16_to_cpu(txpower.channel), + txpower.band, + txpower.power[i].tpc.tx_gain, + txpower.power[i].tpc.dsp_atten, + txpower.power[i].rate); + } + /* Fill CCK rates */ + for (rate_idx = IWL_FIRST_CCK_RATE; + rate_idx <= IWL_LAST_CCK_RATE; rate_idx++, i++) { + txpower.power[i].tpc = ch_info->power_info[i].tpc; + txpower.power[i].rate = iwl3945_rates[rate_idx].plcp; + + IWL_DEBUG_POWER(priv, "ch %d:%d rf %d dsp %3d rate code 0x%02x\n", + le16_to_cpu(txpower.channel), + txpower.band, + txpower.power[i].tpc.tx_gain, + txpower.power[i].tpc.dsp_atten, + txpower.power[i].rate); + } + + return iwl_legacy_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, + sizeof(struct iwl3945_txpowertable_cmd), + &txpower); + +} + +/** + * iwl3945_hw_reg_set_new_power - Configures power tables at new levels + * @ch_info: Channel to update. Uses power_info.requested_power. + * + * Replace requested_power and base_power_index ch_info fields for + * one channel. + * + * Called if user or spectrum management changes power preferences. + * Takes into account h/w and modulation limitations (clip power). + * + * This does *not* send anything to NIC, just sets up ch_info for one channel. + * + * NOTE: reg_compensate_for_temperature_dif() *must* be run after this to + * properly fill out the scan powers, and actual h/w gain settings, + * and send changes to NIC + */ +static int iwl3945_hw_reg_set_new_power(struct iwl_priv *priv, + struct iwl_channel_info *ch_info) +{ + struct iwl3945_channel_power_info *power_info; + int power_changed = 0; + int i; + const s8 *clip_pwrs; + int power; + + /* Get this chnlgrp's rate-to-max/clip-powers table */ + clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers; + + /* Get this channel's rate-to-current-power settings table */ + power_info = ch_info->power_info; + + /* update OFDM Txpower settings */ + for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; + i++, ++power_info) { + int delta_idx; + + /* limit new power to be no more than h/w capability */ + power = min(ch_info->curr_txpow, clip_pwrs[i]); + if (power == power_info->requested_power) + continue; + + /* find difference between old and new requested powers, + * update base (non-temp-compensated) power index */ + delta_idx = (power - power_info->requested_power) * 2; + power_info->base_power_index -= delta_idx; + + /* save new requested power value */ + power_info->requested_power = power; + + power_changed = 1; + } + + /* update CCK Txpower settings, based on OFDM 12M setting ... + * ... all CCK power settings for a given channel are the *same*. */ + if (power_changed) { + power = + ch_info->power_info[IWL_RATE_12M_INDEX_TABLE]. + requested_power + IWL_CCK_FROM_OFDM_POWER_DIFF; + + /* do all CCK rates' iwl3945_channel_power_info structures */ + for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++) { + power_info->requested_power = power; + power_info->base_power_index = + ch_info->power_info[IWL_RATE_12M_INDEX_TABLE]. + base_power_index + IWL_CCK_FROM_OFDM_INDEX_DIFF; + ++power_info; + } + } + + return 0; +} + +/** + * iwl3945_hw_reg_get_ch_txpower_limit - returns new power limit for channel + * + * NOTE: Returned power limit may be less (but not more) than requested, + * based strictly on regulatory (eeprom and spectrum mgt) limitations + * (no consideration for h/w clipping limitations). + */ +static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl_channel_info *ch_info) +{ + s8 max_power; + +#if 0 + /* if we're using TGd limits, use lower of TGd or EEPROM */ + if (ch_info->tgd_data.max_power != 0) + max_power = min(ch_info->tgd_data.max_power, + ch_info->eeprom.max_power_avg); + + /* else just use EEPROM limits */ + else +#endif + max_power = ch_info->eeprom.max_power_avg; + + return min(max_power, ch_info->max_power_avg); +} + +/** + * iwl3945_hw_reg_comp_txpower_temp - Compensate for temperature + * + * Compensate txpower settings of *all* channels for temperature. + * This only accounts for the difference between current temperature + * and the factory calibration temperatures, and bases the new settings + * on the channel's base_power_index. + * + * If RxOn is "associated", this sends the new Txpower to NIC! + */ +static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv) +{ + struct iwl_channel_info *ch_info = NULL; + struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; + int delta_index; + const s8 *clip_pwrs; /* array of h/w max power levels for each rate */ + u8 a_band; + u8 rate_index; + u8 scan_tbl_index; + u8 i; + int ref_temp; + int temperature = priv->temperature; + + if (priv->disable_tx_power_cal || + test_bit(STATUS_SCANNING, &priv->status)) { + /* do not perform tx power calibration */ + return 0; + } + /* set up new Tx power info for each and every channel, 2.4 and 5.x */ + for (i = 0; i < priv->channel_count; i++) { + ch_info = &priv->channel_info[i]; + a_band = iwl_legacy_is_channel_a_band(ch_info); + + /* Get this chnlgrp's factory calibration temperature */ + ref_temp = (s16)eeprom->groups[ch_info->group_index]. + temperature; + + /* get power index adjustment based on current and factory + * temps */ + delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature, + ref_temp); + + /* set tx power value for all rates, OFDM and CCK */ + for (rate_index = 0; rate_index < IWL_RATE_COUNT_3945; + rate_index++) { + int power_idx = + ch_info->power_info[rate_index].base_power_index; + + /* temperature compensate */ + power_idx += delta_index; + + /* stay within table range */ + power_idx = iwl3945_hw_reg_fix_power_index(power_idx); + ch_info->power_info[rate_index]. + power_table_index = (u8) power_idx; + ch_info->power_info[rate_index].tpc = + power_gain_table[a_band][power_idx]; + } + + /* Get this chnlgrp's rate-to-max/clip-powers table */ + clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers; + + /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */ + for (scan_tbl_index = 0; + scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) { + s32 actual_index = (scan_tbl_index == 0) ? + IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE; + iwl3945_hw_reg_set_scan_power(priv, scan_tbl_index, + actual_index, clip_pwrs, + ch_info, a_band); + } + } + + /* send Txpower command for current channel to ucode */ + return priv->cfg->ops->lib->send_tx_power(priv); +} + +int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power) +{ + struct iwl_channel_info *ch_info; + s8 max_power; + u8 a_band; + u8 i; + + if (priv->tx_power_user_lmt == power) { + IWL_DEBUG_POWER(priv, "Requested Tx power same as current " + "limit: %ddBm.\n", power); + return 0; + } + + IWL_DEBUG_POWER(priv, "Setting upper limit clamp to %ddBm.\n", power); + priv->tx_power_user_lmt = power; + + /* set up new Tx powers for each and every channel, 2.4 and 5.x */ + + for (i = 0; i < priv->channel_count; i++) { + ch_info = &priv->channel_info[i]; + a_band = iwl_legacy_is_channel_a_band(ch_info); + + /* find minimum power of all user and regulatory constraints + * (does not consider h/w clipping limitations) */ + max_power = iwl3945_hw_reg_get_ch_txpower_limit(ch_info); + max_power = min(power, max_power); + if (max_power != ch_info->curr_txpow) { + ch_info->curr_txpow = max_power; + + /* this considers the h/w clipping limitations */ + iwl3945_hw_reg_set_new_power(priv, ch_info); + } + } + + /* update txpower settings for all channels, + * send to NIC if associated. */ + iwl3945_is_temp_calib_needed(priv); + iwl3945_hw_reg_comp_txpower_temp(priv); + + return 0; +} + +static int iwl3945_send_rxon_assoc(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + int rc = 0; + struct iwl_rx_packet *pkt; + struct iwl3945_rxon_assoc_cmd rxon_assoc; + struct iwl_host_cmd cmd = { + .id = REPLY_RXON_ASSOC, + .len = sizeof(rxon_assoc), + .flags = CMD_WANT_SKB, + .data = &rxon_assoc, + }; + const struct iwl_legacy_rxon_cmd *rxon1 = &ctx->staging; + const struct iwl_legacy_rxon_cmd *rxon2 = &ctx->active; + + if ((rxon1->flags == rxon2->flags) && + (rxon1->filter_flags == rxon2->filter_flags) && + (rxon1->cck_basic_rates == rxon2->cck_basic_rates) && + (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) { + IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n"); + return 0; + } + + rxon_assoc.flags = ctx->staging.flags; + rxon_assoc.filter_flags = ctx->staging.filter_flags; + rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; + rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; + rxon_assoc.reserved = 0; + + rc = iwl_legacy_send_cmd_sync(priv, &cmd); + if (rc) + return rc; + + pkt = (struct iwl_rx_packet *)cmd.reply_page; + if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { + IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n"); + rc = -EIO; + } + + iwl_legacy_free_pages(priv, cmd.reply_page); + + return rc; +} + +/** + * iwl3945_commit_rxon - commit staging_rxon to hardware + * + * The RXON command in staging_rxon is committed to the hardware and + * the active_rxon structure is updated with the new data. This + * function correctly transitions out of the RXON_ASSOC_MSK state if + * a HW tune is required based on the RXON structure changes. + */ +int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +{ + /* cast away the const for active_rxon in this function */ + struct iwl3945_rxon_cmd *active_rxon = (void *)&ctx->active; + struct iwl3945_rxon_cmd *staging_rxon = (void *)&ctx->staging; + int rc = 0; + bool new_assoc = !!(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return -EINVAL; + + if (!iwl_legacy_is_alive(priv)) + return -1; + + /* always get timestamp with Rx frame */ + staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK; + + /* select antenna */ + staging_rxon->flags &= + ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK); + staging_rxon->flags |= iwl3945_get_antenna_flags(priv); + + rc = iwl_legacy_check_rxon_cmd(priv, ctx); + if (rc) { + IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); + return -EINVAL; + } + + /* If we don't need to send a full RXON, we can use + * iwl3945_rxon_assoc_cmd which is used to reconfigure filter + * and other flags for the current radio configuration. */ + if (!iwl_legacy_full_rxon_required(priv, + &priv->contexts[IWL_RXON_CTX_BSS])) { + rc = iwl_legacy_send_rxon_assoc(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); + if (rc) { + IWL_ERR(priv, "Error setting RXON_ASSOC " + "configuration (%d).\n", rc); + return rc; + } + + memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); + + return 0; + } + + /* If we are currently associated and the new config requires + * an RXON_ASSOC and the new config wants the associated mask enabled, + * we must clear the associated from the active configuration + * before we apply the new config */ + if (iwl_legacy_is_associated(priv, IWL_RXON_CTX_BSS) && new_assoc) { + IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); + active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; + + /* + * reserved4 and 5 could have been filled by the iwlcore code. + * Let's clear them before pushing to the 3945. + */ + active_rxon->reserved4 = 0; + active_rxon->reserved5 = 0; + rc = iwl_legacy_send_cmd_pdu(priv, REPLY_RXON, + sizeof(struct iwl3945_rxon_cmd), + &priv->contexts[IWL_RXON_CTX_BSS].active); + + /* If the mask clearing failed then we set + * active_rxon back to what it was previously */ + if (rc) { + active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; + IWL_ERR(priv, "Error clearing ASSOC_MSK on current " + "configuration (%d).\n", rc); + return rc; + } + iwl_legacy_clear_ucode_stations(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); + iwl_legacy_restore_stations(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); + } + + IWL_DEBUG_INFO(priv, "Sending RXON\n" + "* with%s RXON_FILTER_ASSOC_MSK\n" + "* channel = %d\n" + "* bssid = %pM\n", + (new_assoc ? "" : "out"), + le16_to_cpu(staging_rxon->channel), + staging_rxon->bssid_addr); + + /* + * reserved4 and 5 could have been filled by the iwlcore code. + * Let's clear them before pushing to the 3945. + */ + staging_rxon->reserved4 = 0; + staging_rxon->reserved5 = 0; + + iwl_legacy_set_rxon_hwcrypto(priv, ctx, !iwl3945_mod_params.sw_crypto); + + /* Apply the new configuration */ + rc = iwl_legacy_send_cmd_pdu(priv, REPLY_RXON, + sizeof(struct iwl3945_rxon_cmd), + staging_rxon); + if (rc) { + IWL_ERR(priv, "Error setting new configuration (%d).\n", rc); + return rc; + } + + memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); + + if (!new_assoc) { + iwl_legacy_clear_ucode_stations(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); + iwl_legacy_restore_stations(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); + } + + /* If we issue a new RXON command which required a tune then we must + * send a new TXPOWER command or we won't be able to Tx any frames */ + rc = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true); + if (rc) { + IWL_ERR(priv, "Error setting Tx power (%d).\n", rc); + return rc; + } + + /* Init the hardware's rate fallback order based on the band */ + rc = iwl3945_init_hw_rate_table(priv); + if (rc) { + IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc); + return -EIO; + } + + return 0; +} + +/** + * iwl3945_reg_txpower_periodic - called when time to check our temperature. + * + * -- reset periodic timer + * -- see if temp has changed enough to warrant re-calibration ... if so: + * -- correct coeffs for temp (can reset temp timer) + * -- save this temp as "last", + * -- send new set of gain settings to NIC + * NOTE: This should continue working, even when we're not associated, + * so we can keep our internal table of scan powers current. */ +void iwl3945_reg_txpower_periodic(struct iwl_priv *priv) +{ + /* This will kick in the "brute force" + * iwl3945_hw_reg_comp_txpower_temp() below */ + if (!iwl3945_is_temp_calib_needed(priv)) + goto reschedule; + + /* Set up a new set of temp-adjusted TxPowers, send to NIC. + * This is based *only* on current temperature, + * ignoring any previous power measurements */ + iwl3945_hw_reg_comp_txpower_temp(priv); + + reschedule: + queue_delayed_work(priv->workqueue, + &priv->_3945.thermal_periodic, REG_RECALIB_PERIOD * HZ); +} + +static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work) +{ + struct iwl_priv *priv = container_of(work, struct iwl_priv, + _3945.thermal_periodic.work); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + iwl3945_reg_txpower_periodic(priv); + mutex_unlock(&priv->mutex); +} + +/** + * iwl3945_hw_reg_get_ch_grp_index - find the channel-group index (0-4) + * for the channel. + * + * This function is used when initializing channel-info structs. + * + * NOTE: These channel groups do *NOT* match the bands above! + * These channel groups are based on factory-tested channels; + * on A-band, EEPROM's "group frequency" entries represent the top + * channel in each group 1-4. Group 5 All B/G channels are in group 0. + */ +static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl_priv *priv, + const struct iwl_channel_info *ch_info) +{ + struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; + struct iwl3945_eeprom_txpower_group *ch_grp = &eeprom->groups[0]; + u8 group; + u16 group_index = 0; /* based on factory calib frequencies */ + u8 grp_channel; + + /* Find the group index for the channel ... don't use index 1(?) */ + if (iwl_legacy_is_channel_a_band(ch_info)) { + for (group = 1; group < 5; group++) { + grp_channel = ch_grp[group].group_channel; + if (ch_info->channel <= grp_channel) { + group_index = group; + break; + } + } + /* group 4 has a few channels *above* its factory cal freq */ + if (group == 5) + group_index = 4; + } else + group_index = 0; /* 2.4 GHz, group 0 */ + + IWL_DEBUG_POWER(priv, "Chnl %d mapped to grp %d\n", ch_info->channel, + group_index); + return group_index; +} + +/** + * iwl3945_hw_reg_get_matched_power_index - Interpolate to get nominal index + * + * Interpolate to get nominal (i.e. at factory calibration temperature) index + * into radio/DSP gain settings table for requested power. + */ +static int iwl3945_hw_reg_get_matched_power_index(struct iwl_priv *priv, + s8 requested_power, + s32 setting_index, s32 *new_index) +{ + const struct iwl3945_eeprom_txpower_group *chnl_grp = NULL; + struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; + s32 index0, index1; + s32 power = 2 * requested_power; + s32 i; + const struct iwl3945_eeprom_txpower_sample *samples; + s32 gains0, gains1; + s32 res; + s32 denominator; + + chnl_grp = &eeprom->groups[setting_index]; + samples = chnl_grp->samples; + for (i = 0; i < 5; i++) { + if (power == samples[i].power) { + *new_index = samples[i].gain_index; + return 0; + } + } + + if (power > samples[1].power) { + index0 = 0; + index1 = 1; + } else if (power > samples[2].power) { + index0 = 1; + index1 = 2; + } else if (power > samples[3].power) { + index0 = 2; + index1 = 3; + } else { + index0 = 3; + index1 = 4; + } + + denominator = (s32) samples[index1].power - (s32) samples[index0].power; + if (denominator == 0) + return -EINVAL; + gains0 = (s32) samples[index0].gain_index * (1 << 19); + gains1 = (s32) samples[index1].gain_index * (1 << 19); + res = gains0 + (gains1 - gains0) * + ((s32) power - (s32) samples[index0].power) / denominator + + (1 << 18); + *new_index = res >> 19; + return 0; +} + +static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv) +{ + u32 i; + s32 rate_index; + struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; + const struct iwl3945_eeprom_txpower_group *group; + + IWL_DEBUG_POWER(priv, "Initializing factory calib info from EEPROM\n"); + + for (i = 0; i < IWL_NUM_TX_CALIB_GROUPS; i++) { + s8 *clip_pwrs; /* table of power levels for each rate */ + s8 satur_pwr; /* saturation power for each chnl group */ + group = &eeprom->groups[i]; + + /* sanity check on factory saturation power value */ + if (group->saturation_power < 40) { + IWL_WARN(priv, "Error: saturation power is %d, " + "less than minimum expected 40\n", + group->saturation_power); + return; + } + + /* + * Derive requested power levels for each rate, based on + * hardware capabilities (saturation power for band). + * Basic value is 3dB down from saturation, with further + * power reductions for highest 3 data rates. These + * backoffs provide headroom for high rate modulation + * power peaks, without too much distortion (clipping). + */ + /* we'll fill in this array with h/w max power levels */ + clip_pwrs = (s8 *) priv->_3945.clip_groups[i].clip_powers; + + /* divide factory saturation power by 2 to find -3dB level */ + satur_pwr = (s8) (group->saturation_power >> 1); + + /* fill in channel group's nominal powers for each rate */ + for (rate_index = 0; + rate_index < IWL_RATE_COUNT_3945; rate_index++, clip_pwrs++) { + switch (rate_index) { + case IWL_RATE_36M_INDEX_TABLE: + if (i == 0) /* B/G */ + *clip_pwrs = satur_pwr; + else /* A */ + *clip_pwrs = satur_pwr - 5; + break; + case IWL_RATE_48M_INDEX_TABLE: + if (i == 0) + *clip_pwrs = satur_pwr - 7; + else + *clip_pwrs = satur_pwr - 10; + break; + case IWL_RATE_54M_INDEX_TABLE: + if (i == 0) + *clip_pwrs = satur_pwr - 9; + else + *clip_pwrs = satur_pwr - 12; + break; + default: + *clip_pwrs = satur_pwr; + break; + } + } + } +} + +/** + * iwl3945_txpower_set_from_eeprom - Set channel power info based on EEPROM + * + * Second pass (during init) to set up priv->channel_info + * + * Set up Tx-power settings in our channel info database for each VALID + * (for this geo/SKU) channel, at all Tx data rates, based on eeprom values + * and current temperature. + * + * Since this is based on current temperature (at init time), these values may + * not be valid for very long, but it gives us a starting/default point, + * and allows us to active (i.e. using Tx) scan. + * + * This does *not* write values to NIC, just sets up our internal table. + */ +int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv) +{ + struct iwl_channel_info *ch_info = NULL; + struct iwl3945_channel_power_info *pwr_info; + struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; + int delta_index; + u8 rate_index; + u8 scan_tbl_index; + const s8 *clip_pwrs; /* array of power levels for each rate */ + u8 gain, dsp_atten; + s8 power; + u8 pwr_index, base_pwr_index, a_band; + u8 i; + int temperature; + + /* save temperature reference, + * so we can determine next time to calibrate */ + temperature = iwl3945_hw_reg_txpower_get_temperature(priv); + priv->last_temperature = temperature; + + iwl3945_hw_reg_init_channel_groups(priv); + + /* initialize Tx power info for each and every channel, 2.4 and 5.x */ + for (i = 0, ch_info = priv->channel_info; i < priv->channel_count; + i++, ch_info++) { + a_band = iwl_legacy_is_channel_a_band(ch_info); + if (!iwl_legacy_is_channel_valid(ch_info)) + continue; + + /* find this channel's channel group (*not* "band") index */ + ch_info->group_index = + iwl3945_hw_reg_get_ch_grp_index(priv, ch_info); + + /* Get this chnlgrp's rate->max/clip-powers table */ + clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers; + + /* calculate power index *adjustment* value according to + * diff between current temperature and factory temperature */ + delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature, + eeprom->groups[ch_info->group_index]. + temperature); + + IWL_DEBUG_POWER(priv, "Delta index for channel %d: %d [%d]\n", + ch_info->channel, delta_index, temperature + + IWL_TEMP_CONVERT); + + /* set tx power value for all OFDM rates */ + for (rate_index = 0; rate_index < IWL_OFDM_RATES; + rate_index++) { + s32 uninitialized_var(power_idx); + int rc; + + /* use channel group's clip-power table, + * but don't exceed channel's max power */ + s8 pwr = min(ch_info->max_power_avg, + clip_pwrs[rate_index]); + + pwr_info = &ch_info->power_info[rate_index]; + + /* get base (i.e. at factory-measured temperature) + * power table index for this rate's power */ + rc = iwl3945_hw_reg_get_matched_power_index(priv, pwr, + ch_info->group_index, + &power_idx); + if (rc) { + IWL_ERR(priv, "Invalid power index\n"); + return rc; + } + pwr_info->base_power_index = (u8) power_idx; + + /* temperature compensate */ + power_idx += delta_index; + + /* stay within range of gain table */ + power_idx = iwl3945_hw_reg_fix_power_index(power_idx); + + /* fill 1 OFDM rate's iwl3945_channel_power_info struct */ + pwr_info->requested_power = pwr; + pwr_info->power_table_index = (u8) power_idx; + pwr_info->tpc.tx_gain = + power_gain_table[a_band][power_idx].tx_gain; + pwr_info->tpc.dsp_atten = + power_gain_table[a_band][power_idx].dsp_atten; + } + + /* set tx power for CCK rates, based on OFDM 12 Mbit settings*/ + pwr_info = &ch_info->power_info[IWL_RATE_12M_INDEX_TABLE]; + power = pwr_info->requested_power + + IWL_CCK_FROM_OFDM_POWER_DIFF; + pwr_index = pwr_info->power_table_index + + IWL_CCK_FROM_OFDM_INDEX_DIFF; + base_pwr_index = pwr_info->base_power_index + + IWL_CCK_FROM_OFDM_INDEX_DIFF; + + /* stay within table range */ + pwr_index = iwl3945_hw_reg_fix_power_index(pwr_index); + gain = power_gain_table[a_band][pwr_index].tx_gain; + dsp_atten = power_gain_table[a_band][pwr_index].dsp_atten; + + /* fill each CCK rate's iwl3945_channel_power_info structure + * NOTE: All CCK-rate Txpwrs are the same for a given chnl! + * NOTE: CCK rates start at end of OFDM rates! */ + for (rate_index = 0; + rate_index < IWL_CCK_RATES; rate_index++) { + pwr_info = &ch_info->power_info[rate_index+IWL_OFDM_RATES]; + pwr_info->requested_power = power; + pwr_info->power_table_index = pwr_index; + pwr_info->base_power_index = base_pwr_index; + pwr_info->tpc.tx_gain = gain; + pwr_info->tpc.dsp_atten = dsp_atten; + } + + /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */ + for (scan_tbl_index = 0; + scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) { + s32 actual_index = (scan_tbl_index == 0) ? + IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE; + iwl3945_hw_reg_set_scan_power(priv, scan_tbl_index, + actual_index, clip_pwrs, ch_info, a_band); + } + } + + return 0; +} + +int iwl3945_hw_rxq_stop(struct iwl_priv *priv) +{ + int rc; + + iwl_legacy_write_direct32(priv, FH39_RCSR_CONFIG(0), 0); + rc = iwl_poll_direct_bit(priv, FH39_RSSR_STATUS, + FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); + if (rc < 0) + IWL_ERR(priv, "Can't stop Rx DMA.\n"); + + return 0; +} + +int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq) +{ + int txq_id = txq->q.id; + + struct iwl3945_shared *shared_data = priv->_3945.shared_virt; + + shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr); + + iwl_legacy_write_direct32(priv, FH39_CBCC_CTRL(txq_id), 0); + iwl_legacy_write_direct32(priv, FH39_CBCC_BASE(txq_id), 0); + + iwl_legacy_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), + FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT | + FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF | + FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD | + FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL | + FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE); + + /* fake read to flush all prev. writes */ + iwl_read32(priv, FH39_TSSR_CBB_BASE); + + return 0; +} + +/* + * HCMD utils + */ +static u16 iwl3945_get_hcmd_size(u8 cmd_id, u16 len) +{ + switch (cmd_id) { + case REPLY_RXON: + return sizeof(struct iwl3945_rxon_cmd); + case POWER_TABLE_CMD: + return sizeof(struct iwl3945_powertable_cmd); + default: + return len; + } +} + + +static u16 iwl3945_build_addsta_hcmd(const struct iwl_legacy_addsta_cmd *cmd, + u8 *data) +{ + struct iwl3945_addsta_cmd *addsta = (struct iwl3945_addsta_cmd *)data; + addsta->mode = cmd->mode; + memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify)); + memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo)); + addsta->station_flags = cmd->station_flags; + addsta->station_flags_msk = cmd->station_flags_msk; + addsta->tid_disable_tx = cpu_to_le16(0); + addsta->rate_n_flags = cmd->rate_n_flags; + addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid; + addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid; + addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn; + + return (u16)sizeof(struct iwl3945_addsta_cmd); +} + +static int iwl3945_add_bssid_station(struct iwl_priv *priv, + const u8 *addr, u8 *sta_id_r) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + int ret; + u8 sta_id; + unsigned long flags; + + if (sta_id_r) + *sta_id_r = IWL_INVALID_STATION; + + ret = iwl_legacy_add_station_common(priv, ctx, addr, 0, NULL, &sta_id); + if (ret) { + IWL_ERR(priv, "Unable to add station %pM\n", addr); + return ret; + } + + if (sta_id_r) + *sta_id_r = sta_id; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].used |= IWL_STA_LOCAL; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return 0; +} +static int iwl3945_manage_ibss_station(struct iwl_priv *priv, + struct ieee80211_vif *vif, bool add) +{ + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; + int ret; + + if (add) { + ret = iwl3945_add_bssid_station(priv, vif->bss_conf.bssid, + &vif_priv->ibss_bssid_sta_id); + if (ret) + return ret; + + iwl3945_sync_sta(priv, vif_priv->ibss_bssid_sta_id, + (priv->band == IEEE80211_BAND_5GHZ) ? + IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP); + iwl3945_rate_scale_init(priv->hw, vif_priv->ibss_bssid_sta_id); + + return 0; + } + + return iwl_legacy_remove_station(priv, vif_priv->ibss_bssid_sta_id, + vif->bss_conf.bssid); +} + +/** + * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table + */ +int iwl3945_init_hw_rate_table(struct iwl_priv *priv) +{ + int rc, i, index, prev_index; + struct iwl3945_rate_scaling_cmd rate_cmd = { + .reserved = {0, 0, 0}, + }; + struct iwl3945_rate_scaling_info *table = rate_cmd.table; + + for (i = 0; i < ARRAY_SIZE(iwl3945_rates); i++) { + index = iwl3945_rates[i].table_rs_index; + + table[index].rate_n_flags = + iwl3945_hw_set_rate_n_flags(iwl3945_rates[i].plcp, 0); + table[index].try_cnt = priv->retry_rate; + prev_index = iwl3945_get_prev_ieee_rate(i); + table[index].next_rate_index = + iwl3945_rates[prev_index].table_rs_index; + } + + switch (priv->band) { + case IEEE80211_BAND_5GHZ: + IWL_DEBUG_RATE(priv, "Select A mode rate scale\n"); + /* If one of the following CCK rates is used, + * have it fall back to the 6M OFDM rate */ + for (i = IWL_RATE_1M_INDEX_TABLE; + i <= IWL_RATE_11M_INDEX_TABLE; i++) + table[i].next_rate_index = + iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index; + + /* Don't fall back to CCK rates */ + table[IWL_RATE_12M_INDEX_TABLE].next_rate_index = + IWL_RATE_9M_INDEX_TABLE; + + /* Don't drop out of OFDM rates */ + table[IWL_RATE_6M_INDEX_TABLE].next_rate_index = + iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index; + break; + + case IEEE80211_BAND_2GHZ: + IWL_DEBUG_RATE(priv, "Select B/G mode rate scale\n"); + /* If an OFDM rate is used, have it fall back to the + * 1M CCK rates */ + + if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) && + iwl_legacy_is_associated(priv, IWL_RXON_CTX_BSS)) { + + index = IWL_FIRST_CCK_RATE; + for (i = IWL_RATE_6M_INDEX_TABLE; + i <= IWL_RATE_54M_INDEX_TABLE; i++) + table[i].next_rate_index = + iwl3945_rates[index].table_rs_index; + + index = IWL_RATE_11M_INDEX_TABLE; + /* CCK shouldn't fall back to OFDM... */ + table[index].next_rate_index = IWL_RATE_5M_INDEX_TABLE; + } + break; + + default: + WARN_ON(1); + break; + } + + /* Update the rate scaling for control frame Tx */ + rate_cmd.table_id = 0; + rc = iwl_legacy_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd), + &rate_cmd); + if (rc) + return rc; + + /* Update the rate scaling for data frame Tx */ + rate_cmd.table_id = 1; + return iwl_legacy_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd), + &rate_cmd); +} + +/* Called when initializing driver */ +int iwl3945_hw_set_hw_params(struct iwl_priv *priv) +{ + memset((void *)&priv->hw_params, 0, + sizeof(struct iwl_hw_params)); + + priv->_3945.shared_virt = + dma_alloc_coherent(&priv->pci_dev->dev, + sizeof(struct iwl3945_shared), + &priv->_3945.shared_phys, GFP_KERNEL); + if (!priv->_3945.shared_virt) { + IWL_ERR(priv, "failed to allocate pci memory\n"); + return -ENOMEM; + } + + /* Assign number of Usable TX queues */ + priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; + + priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd); + priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_3K); + priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; + priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; + priv->hw_params.max_stations = IWL3945_STATION_COUNT; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL3945_BROADCAST_ID; + + priv->sta_key_max_num = STA_KEY_MAX_NUM; + + priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR; + priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL; + priv->hw_params.beacon_time_tsf_bits = IWL3945_EXT_BEACON_TIME_POS; + + return 0; +} + +unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv, + struct iwl3945_frame *frame, u8 rate) +{ + struct iwl3945_tx_beacon_cmd *tx_beacon_cmd; + unsigned int frame_size; + + tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u; + memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); + + tx_beacon_cmd->tx.sta_id = + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; + tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; + + frame_size = iwl3945_fill_beacon_frame(priv, + tx_beacon_cmd->frame, + sizeof(frame->u) - sizeof(*tx_beacon_cmd)); + + BUG_ON(frame_size > MAX_MPDU_SIZE); + tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); + + tx_beacon_cmd->tx.rate = rate; + tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK | + TX_CMD_FLG_TSF_MSK); + + /* supp_rates[0] == OFDM start at IWL_FIRST_OFDM_RATE*/ + tx_beacon_cmd->tx.supp_rates[0] = + (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; + + tx_beacon_cmd->tx.supp_rates[1] = + (IWL_CCK_BASIC_RATES_MASK & 0xF); + + return sizeof(struct iwl3945_tx_beacon_cmd) + frame_size; +} + +void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv) +{ + priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx; + priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx; +} + +void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv) +{ + INIT_DELAYED_WORK(&priv->_3945.thermal_periodic, + iwl3945_bg_reg_txpower_periodic); +} + +void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv) +{ + cancel_delayed_work(&priv->_3945.thermal_periodic); +} + +/* check contents of special bootstrap uCode SRAM */ +static int iwl3945_verify_bsm(struct iwl_priv *priv) + { + __le32 *image = priv->ucode_boot.v_addr; + u32 len = priv->ucode_boot.len; + u32 reg; + u32 val; + + IWL_DEBUG_INFO(priv, "Begin verify bsm\n"); + + /* verify BSM SRAM contents */ + val = iwl_legacy_read_prph(priv, BSM_WR_DWCOUNT_REG); + for (reg = BSM_SRAM_LOWER_BOUND; + reg < BSM_SRAM_LOWER_BOUND + len; + reg += sizeof(u32), image++) { + val = iwl_legacy_read_prph(priv, reg); + if (val != le32_to_cpu(*image)) { + IWL_ERR(priv, "BSM uCode verification failed at " + "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", + BSM_SRAM_LOWER_BOUND, + reg - BSM_SRAM_LOWER_BOUND, len, + val, le32_to_cpu(*image)); + return -EIO; + } + } + + IWL_DEBUG_INFO(priv, "BSM bootstrap uCode image OK\n"); + + return 0; +} + + +/****************************************************************************** + * + * EEPROM related functions + * + ******************************************************************************/ + +/* + * Clear the OWNER_MSK, to establish driver (instead of uCode running on + * embedded controller) as EEPROM reader; each read is a series of pulses + * to/from the EEPROM chip, not a single event, so even reads could conflict + * if they weren't arbitrated by some ownership mechanism. Here, the driver + * simply claims ownership, which should be safe when this function is called + * (i.e. before loading uCode!). + */ +static int iwl3945_eeprom_acquire_semaphore(struct iwl_priv *priv) +{ + _iwl_legacy_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK); + return 0; +} + + +static void iwl3945_eeprom_release_semaphore(struct iwl_priv *priv) +{ + return; +} + + /** + * iwl3945_load_bsm - Load bootstrap instructions + * + * BSM operation: + * + * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program + * in special SRAM that does not power down during RFKILL. When powering back + * up after power-saving sleeps (or during initial uCode load), the BSM loads + * the bootstrap program into the on-board processor, and starts it. + * + * The bootstrap program loads (via DMA) instructions and data for a new + * program from host DRAM locations indicated by the host driver in the + * BSM_DRAM_* registers. Once the new program is loaded, it starts + * automatically. + * + * When initializing the NIC, the host driver points the BSM to the + * "initialize" uCode image. This uCode sets up some internal data, then + * notifies host via "initialize alive" that it is complete. + * + * The host then replaces the BSM_DRAM_* pointer values to point to the + * normal runtime uCode instructions and a backup uCode data cache buffer + * (filled initially with starting data values for the on-board processor), + * then triggers the "initialize" uCode to load and launch the runtime uCode, + * which begins normal operation. + * + * When doing a power-save shutdown, runtime uCode saves data SRAM into + * the backup data cache in DRAM before SRAM is powered down. + * + * When powering back up, the BSM loads the bootstrap program. This reloads + * the runtime uCode instructions and the backup data cache into SRAM, + * and re-launches the runtime uCode from where it left off. + */ +static int iwl3945_load_bsm(struct iwl_priv *priv) +{ + __le32 *image = priv->ucode_boot.v_addr; + u32 len = priv->ucode_boot.len; + dma_addr_t pinst; + dma_addr_t pdata; + u32 inst_len; + u32 data_len; + int rc; + int i; + u32 done; + u32 reg_offset; + + IWL_DEBUG_INFO(priv, "Begin load bsm\n"); + + /* make sure bootstrap program is no larger than BSM's SRAM size */ + if (len > IWL39_MAX_BSM_SIZE) + return -EINVAL; + + /* Tell bootstrap uCode where to find the "Initialize" uCode + * in host DRAM ... host DRAM physical address bits 31:0 for 3945. + * NOTE: iwl3945_initialize_alive_start() will replace these values, + * after the "initialize" uCode has run, to point to + * runtime/protocol instructions and backup data cache. */ + pinst = priv->ucode_init.p_addr; + pdata = priv->ucode_init_data.p_addr; + inst_len = priv->ucode_init.len; + data_len = priv->ucode_init_data.len; + + iwl_legacy_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); + iwl_legacy_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); + iwl_legacy_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); + iwl_legacy_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); + + /* Fill BSM memory with bootstrap instructions */ + for (reg_offset = BSM_SRAM_LOWER_BOUND; + reg_offset < BSM_SRAM_LOWER_BOUND + len; + reg_offset += sizeof(u32), image++) + _iwl_legacy_write_prph(priv, reg_offset, + le32_to_cpu(*image)); + + rc = iwl3945_verify_bsm(priv); + if (rc) + return rc; + + /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ + iwl_legacy_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); + iwl_legacy_write_prph(priv, BSM_WR_MEM_DST_REG, + IWL39_RTC_INST_LOWER_BOUND); + iwl_legacy_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); + + /* Load bootstrap code into instruction SRAM now, + * to prepare to load "initialize" uCode */ + iwl_legacy_write_prph(priv, BSM_WR_CTRL_REG, + BSM_WR_CTRL_REG_BIT_START); + + /* Wait for load of bootstrap uCode to finish */ + for (i = 0; i < 100; i++) { + done = iwl_legacy_read_prph(priv, BSM_WR_CTRL_REG); + if (!(done & BSM_WR_CTRL_REG_BIT_START)) + break; + udelay(10); + } + if (i < 100) + IWL_DEBUG_INFO(priv, "BSM write complete, poll %d iterations\n", i); + else { + IWL_ERR(priv, "BSM write did not complete!\n"); + return -EIO; + } + + /* Enable future boot loads whenever power management unit triggers it + * (e.g. when powering back up after power-save shutdown) */ + iwl_legacy_write_prph(priv, BSM_WR_CTRL_REG, + BSM_WR_CTRL_REG_BIT_START_EN); + + return 0; +} + +static struct iwl_hcmd_ops iwl3945_hcmd = { + .rxon_assoc = iwl3945_send_rxon_assoc, + .commit_rxon = iwl3945_commit_rxon, +}; + +static struct iwl_lib_ops iwl3945_lib = { + .txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd, + .txq_free_tfd = iwl3945_hw_txq_free_tfd, + .txq_init = iwl3945_hw_tx_queue_init, + .load_ucode = iwl3945_load_bsm, + .dump_nic_event_log = iwl3945_dump_nic_event_log, + .dump_nic_error_log = iwl3945_dump_nic_error_log, + .apm_ops = { + .init = iwl3945_apm_init, + .config = iwl3945_nic_config, + }, + .eeprom_ops = { + .regulatory_bands = { + EEPROM_REGULATORY_BAND_1_CHANNELS, + EEPROM_REGULATORY_BAND_2_CHANNELS, + EEPROM_REGULATORY_BAND_3_CHANNELS, + EEPROM_REGULATORY_BAND_4_CHANNELS, + EEPROM_REGULATORY_BAND_5_CHANNELS, + EEPROM_REGULATORY_BAND_NO_HT40, + EEPROM_REGULATORY_BAND_NO_HT40, + }, + .acquire_semaphore = iwl3945_eeprom_acquire_semaphore, + .release_semaphore = iwl3945_eeprom_release_semaphore, + }, + .send_tx_power = iwl3945_send_tx_power, + .is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr, + + .debugfs_ops = { + .rx_stats_read = iwl3945_ucode_rx_stats_read, + .tx_stats_read = iwl3945_ucode_tx_stats_read, + .general_stats_read = iwl3945_ucode_general_stats_read, + }, +}; + +static const struct iwl_legacy_ops iwl3945_legacy_ops = { + .post_associate = iwl3945_post_associate, + .config_ap = iwl3945_config_ap, + .manage_ibss_station = iwl3945_manage_ibss_station, +}; + +static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { + .get_hcmd_size = iwl3945_get_hcmd_size, + .build_addsta_hcmd = iwl3945_build_addsta_hcmd, + .request_scan = iwl3945_request_scan, + .post_scan = iwl3945_post_scan, +}; + +static const struct iwl_ops iwl3945_ops = { + .lib = &iwl3945_lib, + .hcmd = &iwl3945_hcmd, + .utils = &iwl3945_hcmd_utils, + .led = &iwl3945_led_ops, + .legacy = &iwl3945_legacy_ops, + .ieee80211_ops = &iwl3945_hw_ops, +}; + +static struct iwl_base_params iwl3945_base_params = { + .eeprom_size = IWL3945_EEPROM_IMG_SIZE, + .num_of_queues = IWL39_NUM_QUEUES, + .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL, + .set_l0s = false, + .use_bsm = true, + .led_compensation = 64, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, + .wd_timeout = IWL_DEF_WD_TIMEOUT, + .max_event_log_size = 512, +}; + +static struct iwl_cfg iwl3945_bg_cfg = { + .name = "3945BG", + .fw_name_pre = IWL3945_FW_PRE, + .ucode_api_max = IWL3945_UCODE_API_MAX, + .ucode_api_min = IWL3945_UCODE_API_MIN, + .sku = IWL_SKU_G, + .eeprom_ver = EEPROM_3945_EEPROM_VERSION, + .ops = &iwl3945_ops, + .mod_params = &iwl3945_mod_params, + .base_params = &iwl3945_base_params, + .led_mode = IWL_LED_BLINK, +}; + +static struct iwl_cfg iwl3945_abg_cfg = { + .name = "3945ABG", + .fw_name_pre = IWL3945_FW_PRE, + .ucode_api_max = IWL3945_UCODE_API_MAX, + .ucode_api_min = IWL3945_UCODE_API_MIN, + .sku = IWL_SKU_A|IWL_SKU_G, + .eeprom_ver = EEPROM_3945_EEPROM_VERSION, + .ops = &iwl3945_ops, + .mod_params = &iwl3945_mod_params, + .base_params = &iwl3945_base_params, + .led_mode = IWL_LED_BLINK, +}; + +DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { + {IWL_PCI_DEVICE(0x4222, 0x1005, iwl3945_bg_cfg)}, + {IWL_PCI_DEVICE(0x4222, 0x1034, iwl3945_bg_cfg)}, + {IWL_PCI_DEVICE(0x4222, 0x1044, iwl3945_bg_cfg)}, + {IWL_PCI_DEVICE(0x4227, 0x1014, iwl3945_bg_cfg)}, + {IWL_PCI_DEVICE(0x4222, PCI_ANY_ID, iwl3945_abg_cfg)}, + {IWL_PCI_DEVICE(0x4227, PCI_ANY_ID, iwl3945_abg_cfg)}, + {0} +}; + +MODULE_DEVICE_TABLE(pci, iwl3945_hw_card_ids); diff --git a/drivers/net/wireless/iwlegacy/iwl-3945.h b/drivers/net/wireless/iwlegacy/iwl-3945.h new file mode 100644 index 000000000000..b118b59b71de --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-3945.h @@ -0,0 +1,308 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ +/* + * Please use this file (iwl-3945.h) for driver implementation definitions. + * Please use iwl-3945-commands.h for uCode API definitions. + * Please use iwl-3945-hw.h for hardware-related definitions. + */ + +#ifndef __iwl_3945_h__ +#define __iwl_3945_h__ + +#include /* for struct pci_device_id */ +#include +#include + +/* Hardware specific file defines the PCI IDs table for that hardware module */ +extern const struct pci_device_id iwl3945_hw_card_ids[]; + +#include "iwl-csr.h" +#include "iwl-prph.h" +#include "iwl-fh.h" +#include "iwl-3945-hw.h" +#include "iwl-debug.h" +#include "iwl-power.h" +#include "iwl-dev.h" +#include "iwl-led.h" + +/* Highest firmware API version supported */ +#define IWL3945_UCODE_API_MAX 2 + +/* Lowest firmware API version supported */ +#define IWL3945_UCODE_API_MIN 1 + +#define IWL3945_FW_PRE "iwlwifi-3945-" +#define _IWL3945_MODULE_FIRMWARE(api) IWL3945_FW_PRE #api ".ucode" +#define IWL3945_MODULE_FIRMWARE(api) _IWL3945_MODULE_FIRMWARE(api) + +/* Default noise level to report when noise measurement is not available. + * This may be because we're: + * 1) Not associated (4965, no beacon statistics being sent to driver) + * 2) Scanning (noise measurement does not apply to associated channel) + * 3) Receiving CCK (3945 delivers noise info only for OFDM frames) + * Use default noise value of -127 ... this is below the range of measurable + * Rx dBm for either 3945 or 4965, so it can indicate "unmeasurable" to user. + * Also, -127 works better than 0 when averaging frames with/without + * noise info (e.g. averaging might be done in app); measured dBm values are + * always negative ... using a negative value as the default keeps all + * averages within an s8's (used in some apps) range of negative values. */ +#define IWL_NOISE_MEAS_NOT_AVAILABLE (-127) + +/* Module parameters accessible from iwl-*.c */ +extern struct iwl_mod_params iwl3945_mod_params; + +struct iwl3945_rate_scale_data { + u64 data; + s32 success_counter; + s32 success_ratio; + s32 counter; + s32 average_tpt; + unsigned long stamp; +}; + +struct iwl3945_rs_sta { + spinlock_t lock; + struct iwl_priv *priv; + s32 *expected_tpt; + unsigned long last_partial_flush; + unsigned long last_flush; + u32 flush_time; + u32 last_tx_packets; + u32 tx_packets; + u8 tgg; + u8 flush_pending; + u8 start_rate; + struct timer_list rate_scale_flush; + struct iwl3945_rate_scale_data win[IWL_RATE_COUNT_3945]; +#ifdef CONFIG_MAC80211_DEBUGFS + struct dentry *rs_sta_dbgfs_stats_table_file; +#endif + + /* used to be in sta_info */ + int last_txrate_idx; +}; + + +/* + * The common struct MUST be first because it is shared between + * 3945 and 4965! + */ +struct iwl3945_sta_priv { + struct iwl_station_priv_common common; + struct iwl3945_rs_sta rs_sta; +}; + +enum iwl3945_antenna { + IWL_ANTENNA_DIVERSITY, + IWL_ANTENNA_MAIN, + IWL_ANTENNA_AUX +}; + +/* + * RTS threshold here is total size [2347] minus 4 FCS bytes + * Per spec: + * a value of 0 means RTS on all data/management packets + * a value > max MSDU size means no RTS + * else RTS for data/management frames where MPDU is larger + * than RTS value. + */ +#define DEFAULT_RTS_THRESHOLD 2347U +#define MIN_RTS_THRESHOLD 0U +#define MAX_RTS_THRESHOLD 2347U +#define MAX_MSDU_SIZE 2304U +#define MAX_MPDU_SIZE 2346U +#define DEFAULT_BEACON_INTERVAL 100U +#define DEFAULT_SHORT_RETRY_LIMIT 7U +#define DEFAULT_LONG_RETRY_LIMIT 4U + +#define IWL_TX_FIFO_AC0 0 +#define IWL_TX_FIFO_AC1 1 +#define IWL_TX_FIFO_AC2 2 +#define IWL_TX_FIFO_AC3 3 +#define IWL_TX_FIFO_HCCA_1 5 +#define IWL_TX_FIFO_HCCA_2 6 +#define IWL_TX_FIFO_NONE 7 + +#define IEEE80211_DATA_LEN 2304 +#define IEEE80211_4ADDR_LEN 30 +#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) +#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) + +struct iwl3945_frame { + union { + struct ieee80211_hdr frame; + struct iwl3945_tx_beacon_cmd beacon; + u8 raw[IEEE80211_FRAME_LEN]; + u8 cmd[360]; + } u; + struct list_head list; +}; + +#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) +#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) +#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) + +#define SUP_RATE_11A_MAX_NUM_CHANNELS 8 +#define SUP_RATE_11B_MAX_NUM_CHANNELS 4 +#define SUP_RATE_11G_MAX_NUM_CHANNELS 12 + +#define IWL_SUPPORTED_RATES_IE_LEN 8 + +#define SCAN_INTERVAL 100 + +#define MAX_TID_COUNT 9 + +#define IWL_INVALID_RATE 0xFF +#define IWL_INVALID_VALUE -1 + +#define STA_PS_STATUS_WAKE 0 +#define STA_PS_STATUS_SLEEP 1 + +struct iwl3945_ibss_seq { + u8 mac[ETH_ALEN]; + u16 seq_num; + u16 frag_num; + unsigned long packet_time; + struct list_head list; +}; + +#define IWL_RX_HDR(x) ((struct iwl3945_rx_frame_hdr *)(\ + x->u.rx_frame.stats.payload + \ + x->u.rx_frame.stats.phy_count)) +#define IWL_RX_END(x) ((struct iwl3945_rx_frame_end *)(\ + IWL_RX_HDR(x)->payload + \ + le16_to_cpu(IWL_RX_HDR(x)->len))) +#define IWL_RX_STATS(x) (&x->u.rx_frame.stats) +#define IWL_RX_DATA(x) (IWL_RX_HDR(x)->payload) + + +/****************************************************************************** + * + * Functions implemented in iwl3945-base.c which are forward declared here + * for use by iwl-*.c + * + *****************************************************************************/ +extern int iwl3945_calc_db_from_ratio(int sig_ratio); +extern void iwl3945_rx_replenish(void *data); +extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); +extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, + struct ieee80211_hdr *hdr, int left); +extern int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, + char **buf, bool display); +extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv); + +/****************************************************************************** + * + * Functions implemented in iwl-[34]*.c which are forward declared here + * for use by iwl3945-base.c + * + * NOTE: The implementation of these functions are hardware specific + * which is why they are in the hardware specific files (vs. iwl-base.c) + * + * Naming convention -- + * iwl3945_ <-- Its part of iwlwifi (should be changed to iwl3945_) + * iwl3945_hw_ <-- Hardware specific (implemented in iwl-XXXX.c by all HW) + * iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX) + * iwl3945_bg_ <-- Called from work queue context + * iwl3945_mac_ <-- mac80211 callback + * + ****************************************************************************/ +extern void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv); +extern void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv); +extern void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv); +extern int iwl3945_hw_rxq_stop(struct iwl_priv *priv); +extern int iwl3945_hw_set_hw_params(struct iwl_priv *priv); +extern int iwl3945_hw_nic_init(struct iwl_priv *priv); +extern int iwl3945_hw_nic_stop_master(struct iwl_priv *priv); +extern void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv); +extern void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv); +extern int iwl3945_hw_nic_reset(struct iwl_priv *priv); +extern int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, + struct iwl_tx_queue *txq, + dma_addr_t addr, u16 len, + u8 reset, u8 pad); +extern void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, + struct iwl_tx_queue *txq); +extern int iwl3945_hw_get_temperature(struct iwl_priv *priv); +extern int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, + struct iwl_tx_queue *txq); +extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv, + struct iwl3945_frame *frame, u8 rate); +void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, + struct iwl_device_cmd *cmd, + struct ieee80211_tx_info *info, + struct ieee80211_hdr *hdr, + int sta_id, int tx_id); +extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv); +extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power); +extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); +void iwl3945_reply_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); +extern void iwl3945_disable_events(struct iwl_priv *priv); +extern int iwl4965_get_temperature(const struct iwl_priv *priv); +extern void iwl3945_post_associate(struct iwl_priv *priv); +extern void iwl3945_config_ap(struct iwl_priv *priv); + +extern int iwl3945_commit_rxon(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); + +/** + * iwl3945_hw_find_station - Find station id for a given BSSID + * @bssid: MAC address of station ID to find + * + * NOTE: This should not be hardware specific but the code has + * not yet been merged into a single common layer for managing the + * station tables. + */ +extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid); + +extern struct ieee80211_ops iwl3945_hw_ops; + +/* + * Forward declare iwl-3945.c functions for iwl3945-base.c + */ +extern __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv); +extern int iwl3945_init_hw_rate_table(struct iwl_priv *priv); +extern void iwl3945_reg_txpower_periodic(struct iwl_priv *priv); +extern int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv); + +extern const struct iwl_channel_info *iwl3945_get_channel_info( + const struct iwl_priv *priv, enum ieee80211_band band, u16 channel); + +extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate); + +/* scanning */ +int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); +void iwl3945_post_scan(struct iwl_priv *priv); + +/* rates */ +extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945]; + +/* Requires full declaration of iwl_priv before including */ +#include "iwl-io.h" + +#endif diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-calib.c b/drivers/net/wireless/iwlegacy/iwl-4965-calib.c new file mode 100644 index 000000000000..81d6a25eb04f --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-4965-calib.c @@ -0,0 +1,967 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include +#include + +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-4965-calib.h" + +/***************************************************************************** + * INIT calibrations framework + *****************************************************************************/ + +struct statistics_general_data { + u32 beacon_silence_rssi_a; + u32 beacon_silence_rssi_b; + u32 beacon_silence_rssi_c; + u32 beacon_energy_a; + u32 beacon_energy_b; + u32 beacon_energy_c; +}; + +void iwl4965_calib_free_results(struct iwl_priv *priv) +{ + int i; + + for (i = 0; i < IWL_CALIB_MAX; i++) { + kfree(priv->calib_results[i].buf); + priv->calib_results[i].buf = NULL; + priv->calib_results[i].buf_len = 0; + } +} + +/***************************************************************************** + * RUNTIME calibrations framework + *****************************************************************************/ + +/* "false alarms" are signals that our DSP tries to lock onto, + * but then determines that they are either noise, or transmissions + * from a distant wireless network (also "noise", really) that get + * "stepped on" by stronger transmissions within our own network. + * This algorithm attempts to set a sensitivity level that is high + * enough to receive all of our own network traffic, but not so + * high that our DSP gets too busy trying to lock onto non-network + * activity/noise. */ +static int iwl4965_sens_energy_cck(struct iwl_priv *priv, + u32 norm_fa, + u32 rx_enable_time, + struct statistics_general_data *rx_info) +{ + u32 max_nrg_cck = 0; + int i = 0; + u8 max_silence_rssi = 0; + u32 silence_ref = 0; + u8 silence_rssi_a = 0; + u8 silence_rssi_b = 0; + u8 silence_rssi_c = 0; + u32 val; + + /* "false_alarms" values below are cross-multiplications to assess the + * numbers of false alarms within the measured period of actual Rx + * (Rx is off when we're txing), vs the min/max expected false alarms + * (some should be expected if rx is sensitive enough) in a + * hypothetical listening period of 200 time units (TU), 204.8 msec: + * + * MIN_FA/fixed-time < false_alarms/actual-rx-time < MAX_FA/beacon-time + * + * */ + u32 false_alarms = norm_fa * 200 * 1024; + u32 max_false_alarms = MAX_FA_CCK * rx_enable_time; + u32 min_false_alarms = MIN_FA_CCK * rx_enable_time; + struct iwl_sensitivity_data *data = NULL; + const struct iwl_sensitivity_ranges *ranges = priv->hw_params.sens; + + data = &(priv->sensitivity_data); + + data->nrg_auto_corr_silence_diff = 0; + + /* Find max silence rssi among all 3 receivers. + * This is background noise, which may include transmissions from other + * networks, measured during silence before our network's beacon */ + silence_rssi_a = (u8)((rx_info->beacon_silence_rssi_a & + ALL_BAND_FILTER) >> 8); + silence_rssi_b = (u8)((rx_info->beacon_silence_rssi_b & + ALL_BAND_FILTER) >> 8); + silence_rssi_c = (u8)((rx_info->beacon_silence_rssi_c & + ALL_BAND_FILTER) >> 8); + + val = max(silence_rssi_b, silence_rssi_c); + max_silence_rssi = max(silence_rssi_a, (u8) val); + + /* Store silence rssi in 20-beacon history table */ + data->nrg_silence_rssi[data->nrg_silence_idx] = max_silence_rssi; + data->nrg_silence_idx++; + if (data->nrg_silence_idx >= NRG_NUM_PREV_STAT_L) + data->nrg_silence_idx = 0; + + /* Find max silence rssi across 20 beacon history */ + for (i = 0; i < NRG_NUM_PREV_STAT_L; i++) { + val = data->nrg_silence_rssi[i]; + silence_ref = max(silence_ref, val); + } + IWL_DEBUG_CALIB(priv, "silence a %u, b %u, c %u, 20-bcn max %u\n", + silence_rssi_a, silence_rssi_b, silence_rssi_c, + silence_ref); + + /* Find max rx energy (min value!) among all 3 receivers, + * measured during beacon frame. + * Save it in 10-beacon history table. */ + i = data->nrg_energy_idx; + val = min(rx_info->beacon_energy_b, rx_info->beacon_energy_c); + data->nrg_value[i] = min(rx_info->beacon_energy_a, val); + + data->nrg_energy_idx++; + if (data->nrg_energy_idx >= 10) + data->nrg_energy_idx = 0; + + /* Find min rx energy (max value) across 10 beacon history. + * This is the minimum signal level that we want to receive well. + * Add backoff (margin so we don't miss slightly lower energy frames). + * This establishes an upper bound (min value) for energy threshold. */ + max_nrg_cck = data->nrg_value[0]; + for (i = 1; i < 10; i++) + max_nrg_cck = (u32) max(max_nrg_cck, (data->nrg_value[i])); + max_nrg_cck += 6; + + IWL_DEBUG_CALIB(priv, "rx energy a %u, b %u, c %u, 10-bcn max/min %u\n", + rx_info->beacon_energy_a, rx_info->beacon_energy_b, + rx_info->beacon_energy_c, max_nrg_cck - 6); + + /* Count number of consecutive beacons with fewer-than-desired + * false alarms. */ + if (false_alarms < min_false_alarms) + data->num_in_cck_no_fa++; + else + data->num_in_cck_no_fa = 0; + IWL_DEBUG_CALIB(priv, "consecutive bcns with few false alarms = %u\n", + data->num_in_cck_no_fa); + + /* If we got too many false alarms this time, reduce sensitivity */ + if ((false_alarms > max_false_alarms) && + (data->auto_corr_cck > AUTO_CORR_MAX_TH_CCK)) { + IWL_DEBUG_CALIB(priv, "norm FA %u > max FA %u\n", + false_alarms, max_false_alarms); + IWL_DEBUG_CALIB(priv, "... reducing sensitivity\n"); + data->nrg_curr_state = IWL_FA_TOO_MANY; + /* Store for "fewer than desired" on later beacon */ + data->nrg_silence_ref = silence_ref; + + /* increase energy threshold (reduce nrg value) + * to decrease sensitivity */ + data->nrg_th_cck = data->nrg_th_cck - NRG_STEP_CCK; + /* Else if we got fewer than desired, increase sensitivity */ + } else if (false_alarms < min_false_alarms) { + data->nrg_curr_state = IWL_FA_TOO_FEW; + + /* Compare silence level with silence level for most recent + * healthy number or too many false alarms */ + data->nrg_auto_corr_silence_diff = (s32)data->nrg_silence_ref - + (s32)silence_ref; + + IWL_DEBUG_CALIB(priv, + "norm FA %u < min FA %u, silence diff %d\n", + false_alarms, min_false_alarms, + data->nrg_auto_corr_silence_diff); + + /* Increase value to increase sensitivity, but only if: + * 1a) previous beacon did *not* have *too many* false alarms + * 1b) AND there's a significant difference in Rx levels + * from a previous beacon with too many, or healthy # FAs + * OR 2) We've seen a lot of beacons (100) with too few + * false alarms */ + if ((data->nrg_prev_state != IWL_FA_TOO_MANY) && + ((data->nrg_auto_corr_silence_diff > NRG_DIFF) || + (data->num_in_cck_no_fa > MAX_NUMBER_CCK_NO_FA))) { + + IWL_DEBUG_CALIB(priv, "... increasing sensitivity\n"); + /* Increase nrg value to increase sensitivity */ + val = data->nrg_th_cck + NRG_STEP_CCK; + data->nrg_th_cck = min((u32)ranges->min_nrg_cck, val); + } else { + IWL_DEBUG_CALIB(priv, + "... but not changing sensitivity\n"); + } + + /* Else we got a healthy number of false alarms, keep status quo */ + } else { + IWL_DEBUG_CALIB(priv, " FA in safe zone\n"); + data->nrg_curr_state = IWL_FA_GOOD_RANGE; + + /* Store for use in "fewer than desired" with later beacon */ + data->nrg_silence_ref = silence_ref; + + /* If previous beacon had too many false alarms, + * give it some extra margin by reducing sensitivity again + * (but don't go below measured energy of desired Rx) */ + if (IWL_FA_TOO_MANY == data->nrg_prev_state) { + IWL_DEBUG_CALIB(priv, "... increasing margin\n"); + if (data->nrg_th_cck > (max_nrg_cck + NRG_MARGIN)) + data->nrg_th_cck -= NRG_MARGIN; + else + data->nrg_th_cck = max_nrg_cck; + } + } + + /* Make sure the energy threshold does not go above the measured + * energy of the desired Rx signals (reduced by backoff margin), + * or else we might start missing Rx frames. + * Lower value is higher energy, so we use max()! + */ + data->nrg_th_cck = max(max_nrg_cck, data->nrg_th_cck); + IWL_DEBUG_CALIB(priv, "new nrg_th_cck %u\n", data->nrg_th_cck); + + data->nrg_prev_state = data->nrg_curr_state; + + /* Auto-correlation CCK algorithm */ + if (false_alarms > min_false_alarms) { + + /* increase auto_corr values to decrease sensitivity + * so the DSP won't be disturbed by the noise + */ + if (data->auto_corr_cck < AUTO_CORR_MAX_TH_CCK) + data->auto_corr_cck = AUTO_CORR_MAX_TH_CCK + 1; + else { + val = data->auto_corr_cck + AUTO_CORR_STEP_CCK; + data->auto_corr_cck = + min((u32)ranges->auto_corr_max_cck, val); + } + val = data->auto_corr_cck_mrc + AUTO_CORR_STEP_CCK; + data->auto_corr_cck_mrc = + min((u32)ranges->auto_corr_max_cck_mrc, val); + } else if ((false_alarms < min_false_alarms) && + ((data->nrg_auto_corr_silence_diff > NRG_DIFF) || + (data->num_in_cck_no_fa > MAX_NUMBER_CCK_NO_FA))) { + + /* Decrease auto_corr values to increase sensitivity */ + val = data->auto_corr_cck - AUTO_CORR_STEP_CCK; + data->auto_corr_cck = + max((u32)ranges->auto_corr_min_cck, val); + val = data->auto_corr_cck_mrc - AUTO_CORR_STEP_CCK; + data->auto_corr_cck_mrc = + max((u32)ranges->auto_corr_min_cck_mrc, val); + } + + return 0; +} + + +static int iwl4965_sens_auto_corr_ofdm(struct iwl_priv *priv, + u32 norm_fa, + u32 rx_enable_time) +{ + u32 val; + u32 false_alarms = norm_fa * 200 * 1024; + u32 max_false_alarms = MAX_FA_OFDM * rx_enable_time; + u32 min_false_alarms = MIN_FA_OFDM * rx_enable_time; + struct iwl_sensitivity_data *data = NULL; + const struct iwl_sensitivity_ranges *ranges = priv->hw_params.sens; + + data = &(priv->sensitivity_data); + + /* If we got too many false alarms this time, reduce sensitivity */ + if (false_alarms > max_false_alarms) { + + IWL_DEBUG_CALIB(priv, "norm FA %u > max FA %u)\n", + false_alarms, max_false_alarms); + + val = data->auto_corr_ofdm + AUTO_CORR_STEP_OFDM; + data->auto_corr_ofdm = + min((u32)ranges->auto_corr_max_ofdm, val); + + val = data->auto_corr_ofdm_mrc + AUTO_CORR_STEP_OFDM; + data->auto_corr_ofdm_mrc = + min((u32)ranges->auto_corr_max_ofdm_mrc, val); + + val = data->auto_corr_ofdm_x1 + AUTO_CORR_STEP_OFDM; + data->auto_corr_ofdm_x1 = + min((u32)ranges->auto_corr_max_ofdm_x1, val); + + val = data->auto_corr_ofdm_mrc_x1 + AUTO_CORR_STEP_OFDM; + data->auto_corr_ofdm_mrc_x1 = + min((u32)ranges->auto_corr_max_ofdm_mrc_x1, val); + } + + /* Else if we got fewer than desired, increase sensitivity */ + else if (false_alarms < min_false_alarms) { + + IWL_DEBUG_CALIB(priv, "norm FA %u < min FA %u\n", + false_alarms, min_false_alarms); + + val = data->auto_corr_ofdm - AUTO_CORR_STEP_OFDM; + data->auto_corr_ofdm = + max((u32)ranges->auto_corr_min_ofdm, val); + + val = data->auto_corr_ofdm_mrc - AUTO_CORR_STEP_OFDM; + data->auto_corr_ofdm_mrc = + max((u32)ranges->auto_corr_min_ofdm_mrc, val); + + val = data->auto_corr_ofdm_x1 - AUTO_CORR_STEP_OFDM; + data->auto_corr_ofdm_x1 = + max((u32)ranges->auto_corr_min_ofdm_x1, val); + + val = data->auto_corr_ofdm_mrc_x1 - AUTO_CORR_STEP_OFDM; + data->auto_corr_ofdm_mrc_x1 = + max((u32)ranges->auto_corr_min_ofdm_mrc_x1, val); + } else { + IWL_DEBUG_CALIB(priv, "min FA %u < norm FA %u < max FA %u OK\n", + min_false_alarms, false_alarms, max_false_alarms); + } + return 0; +} + +static void iwl4965_prepare_legacy_sensitivity_tbl(struct iwl_priv *priv, + struct iwl_sensitivity_data *data, + __le16 *tbl) +{ + tbl[HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX] = + cpu_to_le16((u16)data->auto_corr_ofdm); + tbl[HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX] = + cpu_to_le16((u16)data->auto_corr_ofdm_mrc); + tbl[HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX] = + cpu_to_le16((u16)data->auto_corr_ofdm_x1); + tbl[HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX] = + cpu_to_le16((u16)data->auto_corr_ofdm_mrc_x1); + + tbl[HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX] = + cpu_to_le16((u16)data->auto_corr_cck); + tbl[HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX] = + cpu_to_le16((u16)data->auto_corr_cck_mrc); + + tbl[HD_MIN_ENERGY_CCK_DET_INDEX] = + cpu_to_le16((u16)data->nrg_th_cck); + tbl[HD_MIN_ENERGY_OFDM_DET_INDEX] = + cpu_to_le16((u16)data->nrg_th_ofdm); + + tbl[HD_BARKER_CORR_TH_ADD_MIN_INDEX] = + cpu_to_le16(data->barker_corr_th_min); + tbl[HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX] = + cpu_to_le16(data->barker_corr_th_min_mrc); + tbl[HD_OFDM_ENERGY_TH_IN_INDEX] = + cpu_to_le16(data->nrg_th_cca); + + IWL_DEBUG_CALIB(priv, "ofdm: ac %u mrc %u x1 %u mrc_x1 %u thresh %u\n", + data->auto_corr_ofdm, data->auto_corr_ofdm_mrc, + data->auto_corr_ofdm_x1, data->auto_corr_ofdm_mrc_x1, + data->nrg_th_ofdm); + + IWL_DEBUG_CALIB(priv, "cck: ac %u mrc %u thresh %u\n", + data->auto_corr_cck, data->auto_corr_cck_mrc, + data->nrg_th_cck); +} + +/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */ +static int iwl4965_sensitivity_write(struct iwl_priv *priv) +{ + struct iwl_sensitivity_cmd cmd; + struct iwl_sensitivity_data *data = NULL; + struct iwl_host_cmd cmd_out = { + .id = SENSITIVITY_CMD, + .len = sizeof(struct iwl_sensitivity_cmd), + .flags = CMD_ASYNC, + .data = &cmd, + }; + + data = &(priv->sensitivity_data); + + memset(&cmd, 0, sizeof(cmd)); + + iwl4965_prepare_legacy_sensitivity_tbl(priv, data, &cmd.table[0]); + + /* Update uCode's "work" table, and copy it to DSP */ + cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE; + + /* Don't send command to uCode if nothing has changed */ + if (!memcmp(&cmd.table[0], &(priv->sensitivity_tbl[0]), + sizeof(u16)*HD_TABLE_SIZE)) { + IWL_DEBUG_CALIB(priv, "No change in SENSITIVITY_CMD\n"); + return 0; + } + + /* Copy table for comparison next time */ + memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]), + sizeof(u16)*HD_TABLE_SIZE); + + return iwl_legacy_send_cmd(priv, &cmd_out); +} + +void iwl4965_init_sensitivity(struct iwl_priv *priv) +{ + int ret = 0; + int i; + struct iwl_sensitivity_data *data = NULL; + const struct iwl_sensitivity_ranges *ranges = priv->hw_params.sens; + + if (priv->disable_sens_cal) + return; + + IWL_DEBUG_CALIB(priv, "Start iwl4965_init_sensitivity\n"); + + /* Clear driver's sensitivity algo data */ + data = &(priv->sensitivity_data); + + if (ranges == NULL) + return; + + memset(data, 0, sizeof(struct iwl_sensitivity_data)); + + data->num_in_cck_no_fa = 0; + data->nrg_curr_state = IWL_FA_TOO_MANY; + data->nrg_prev_state = IWL_FA_TOO_MANY; + data->nrg_silence_ref = 0; + data->nrg_silence_idx = 0; + data->nrg_energy_idx = 0; + + for (i = 0; i < 10; i++) + data->nrg_value[i] = 0; + + for (i = 0; i < NRG_NUM_PREV_STAT_L; i++) + data->nrg_silence_rssi[i] = 0; + + data->auto_corr_ofdm = ranges->auto_corr_min_ofdm; + data->auto_corr_ofdm_mrc = ranges->auto_corr_min_ofdm_mrc; + data->auto_corr_ofdm_x1 = ranges->auto_corr_min_ofdm_x1; + data->auto_corr_ofdm_mrc_x1 = ranges->auto_corr_min_ofdm_mrc_x1; + data->auto_corr_cck = AUTO_CORR_CCK_MIN_VAL_DEF; + data->auto_corr_cck_mrc = ranges->auto_corr_min_cck_mrc; + data->nrg_th_cck = ranges->nrg_th_cck; + data->nrg_th_ofdm = ranges->nrg_th_ofdm; + data->barker_corr_th_min = ranges->barker_corr_th_min; + data->barker_corr_th_min_mrc = ranges->barker_corr_th_min_mrc; + data->nrg_th_cca = ranges->nrg_th_cca; + + data->last_bad_plcp_cnt_ofdm = 0; + data->last_fa_cnt_ofdm = 0; + data->last_bad_plcp_cnt_cck = 0; + data->last_fa_cnt_cck = 0; + + ret |= iwl4965_sensitivity_write(priv); + IWL_DEBUG_CALIB(priv, "<disable_sens_cal) + return; + + data = &(priv->sensitivity_data); + + if (!iwl_legacy_is_any_associated(priv)) { + IWL_DEBUG_CALIB(priv, "<< - not associated\n"); + return; + } + + spin_lock_irqsave(&priv->lock, flags); + + rx_info = &(((struct iwl_notif_statistics *)resp)->rx.general); + ofdm = &(((struct iwl_notif_statistics *)resp)->rx.ofdm); + cck = &(((struct iwl_notif_statistics *)resp)->rx.cck); + + if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { + IWL_DEBUG_CALIB(priv, "<< invalid data.\n"); + spin_unlock_irqrestore(&priv->lock, flags); + return; + } + + /* Extract Statistics: */ + rx_enable_time = le32_to_cpu(rx_info->channel_load); + fa_cck = le32_to_cpu(cck->false_alarm_cnt); + fa_ofdm = le32_to_cpu(ofdm->false_alarm_cnt); + bad_plcp_cck = le32_to_cpu(cck->plcp_err); + bad_plcp_ofdm = le32_to_cpu(ofdm->plcp_err); + + statis.beacon_silence_rssi_a = + le32_to_cpu(rx_info->beacon_silence_rssi_a); + statis.beacon_silence_rssi_b = + le32_to_cpu(rx_info->beacon_silence_rssi_b); + statis.beacon_silence_rssi_c = + le32_to_cpu(rx_info->beacon_silence_rssi_c); + statis.beacon_energy_a = + le32_to_cpu(rx_info->beacon_energy_a); + statis.beacon_energy_b = + le32_to_cpu(rx_info->beacon_energy_b); + statis.beacon_energy_c = + le32_to_cpu(rx_info->beacon_energy_c); + + spin_unlock_irqrestore(&priv->lock, flags); + + IWL_DEBUG_CALIB(priv, "rx_enable_time = %u usecs\n", rx_enable_time); + + if (!rx_enable_time) { + IWL_DEBUG_CALIB(priv, "<< RX Enable Time == 0!\n"); + return; + } + + /* These statistics increase monotonically, and do not reset + * at each beacon. Calculate difference from last value, or just + * use the new statistics value if it has reset or wrapped around. */ + if (data->last_bad_plcp_cnt_cck > bad_plcp_cck) + data->last_bad_plcp_cnt_cck = bad_plcp_cck; + else { + bad_plcp_cck -= data->last_bad_plcp_cnt_cck; + data->last_bad_plcp_cnt_cck += bad_plcp_cck; + } + + if (data->last_bad_plcp_cnt_ofdm > bad_plcp_ofdm) + data->last_bad_plcp_cnt_ofdm = bad_plcp_ofdm; + else { + bad_plcp_ofdm -= data->last_bad_plcp_cnt_ofdm; + data->last_bad_plcp_cnt_ofdm += bad_plcp_ofdm; + } + + if (data->last_fa_cnt_ofdm > fa_ofdm) + data->last_fa_cnt_ofdm = fa_ofdm; + else { + fa_ofdm -= data->last_fa_cnt_ofdm; + data->last_fa_cnt_ofdm += fa_ofdm; + } + + if (data->last_fa_cnt_cck > fa_cck) + data->last_fa_cnt_cck = fa_cck; + else { + fa_cck -= data->last_fa_cnt_cck; + data->last_fa_cnt_cck += fa_cck; + } + + /* Total aborted signal locks */ + norm_fa_ofdm = fa_ofdm + bad_plcp_ofdm; + norm_fa_cck = fa_cck + bad_plcp_cck; + + IWL_DEBUG_CALIB(priv, + "cck: fa %u badp %u ofdm: fa %u badp %u\n", fa_cck, + bad_plcp_cck, fa_ofdm, bad_plcp_ofdm); + + iwl4965_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time); + iwl4965_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis); + + iwl4965_sensitivity_write(priv); +} + +static inline u8 iwl4965_find_first_chain(u8 mask) +{ + if (mask & ANT_A) + return CHAIN_A; + if (mask & ANT_B) + return CHAIN_B; + return CHAIN_C; +} + +/** + * Run disconnected antenna algorithm to find out which antennas are + * disconnected. + */ +static void +iwl4965_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, + struct iwl_chain_noise_data *data) +{ + u32 active_chains = 0; + u32 max_average_sig; + u16 max_average_sig_antenna_i; + u8 num_tx_chains; + u8 first_chain; + u16 i = 0; + + average_sig[0] = data->chain_signal_a / + priv->cfg->base_params->chain_noise_num_beacons; + average_sig[1] = data->chain_signal_b / + priv->cfg->base_params->chain_noise_num_beacons; + average_sig[2] = data->chain_signal_c / + priv->cfg->base_params->chain_noise_num_beacons; + + if (average_sig[0] >= average_sig[1]) { + max_average_sig = average_sig[0]; + max_average_sig_antenna_i = 0; + active_chains = (1 << max_average_sig_antenna_i); + } else { + max_average_sig = average_sig[1]; + max_average_sig_antenna_i = 1; + active_chains = (1 << max_average_sig_antenna_i); + } + + if (average_sig[2] >= max_average_sig) { + max_average_sig = average_sig[2]; + max_average_sig_antenna_i = 2; + active_chains = (1 << max_average_sig_antenna_i); + } + + IWL_DEBUG_CALIB(priv, "average_sig: a %d b %d c %d\n", + average_sig[0], average_sig[1], average_sig[2]); + IWL_DEBUG_CALIB(priv, "max_average_sig = %d, antenna %d\n", + max_average_sig, max_average_sig_antenna_i); + + /* Compare signal strengths for all 3 receivers. */ + for (i = 0; i < NUM_RX_CHAINS; i++) { + if (i != max_average_sig_antenna_i) { + s32 rssi_delta = (max_average_sig - average_sig[i]); + + /* If signal is very weak, compared with + * strongest, mark it as disconnected. */ + if (rssi_delta > MAXIMUM_ALLOWED_PATHLOSS) + data->disconn_array[i] = 1; + else + active_chains |= (1 << i); + IWL_DEBUG_CALIB(priv, "i = %d rssiDelta = %d " + "disconn_array[i] = %d\n", + i, rssi_delta, data->disconn_array[i]); + } + } + + /* + * The above algorithm sometimes fails when the ucode + * reports 0 for all chains. It's not clear why that + * happens to start with, but it is then causing trouble + * because this can make us enable more chains than the + * hardware really has. + * + * To be safe, simply mask out any chains that we know + * are not on the device. + */ + active_chains &= priv->hw_params.valid_rx_ant; + + num_tx_chains = 0; + for (i = 0; i < NUM_RX_CHAINS; i++) { + /* loops on all the bits of + * priv->hw_setting.valid_tx_ant */ + u8 ant_msk = (1 << i); + if (!(priv->hw_params.valid_tx_ant & ant_msk)) + continue; + + num_tx_chains++; + if (data->disconn_array[i] == 0) + /* there is a Tx antenna connected */ + break; + if (num_tx_chains == priv->hw_params.tx_chains_num && + data->disconn_array[i]) { + /* + * If all chains are disconnected + * connect the first valid tx chain + */ + first_chain = + iwl4965_find_first_chain(priv->cfg->valid_tx_ant); + data->disconn_array[first_chain] = 0; + active_chains |= BIT(first_chain); + IWL_DEBUG_CALIB(priv, "All Tx chains are disconnected \ + W/A - declare %d as connected\n", + first_chain); + break; + } + } + + if (active_chains != priv->hw_params.valid_rx_ant && + active_chains != priv->chain_noise_data.active_chains) + IWL_DEBUG_CALIB(priv, + "Detected that not all antennas are connected! " + "Connected: %#x, valid: %#x.\n", + active_chains, priv->hw_params.valid_rx_ant); + + /* Save for use within RXON, TX, SCAN commands, etc. */ + data->active_chains = active_chains; + IWL_DEBUG_CALIB(priv, "active_chains (bitwise) = 0x%x\n", + active_chains); +} + +static void iwl4965_gain_computation(struct iwl_priv *priv, + u32 *average_noise, + u16 min_average_noise_antenna_i, + u32 min_average_noise, + u8 default_chain) +{ + int i, ret; + struct iwl_chain_noise_data *data = &priv->chain_noise_data; + + data->delta_gain_code[min_average_noise_antenna_i] = 0; + + for (i = default_chain; i < NUM_RX_CHAINS; i++) { + s32 delta_g = 0; + + if (!(data->disconn_array[i]) && + (data->delta_gain_code[i] == + CHAIN_NOISE_DELTA_GAIN_INIT_VAL)) { + delta_g = average_noise[i] - min_average_noise; + data->delta_gain_code[i] = (u8)((delta_g * 10) / 15); + data->delta_gain_code[i] = + min(data->delta_gain_code[i], + (u8) CHAIN_NOISE_MAX_DELTA_GAIN_CODE); + + data->delta_gain_code[i] = + (data->delta_gain_code[i] | (1 << 2)); + } else { + data->delta_gain_code[i] = 0; + } + } + IWL_DEBUG_CALIB(priv, "delta_gain_codes: a %d b %d c %d\n", + data->delta_gain_code[0], + data->delta_gain_code[1], + data->delta_gain_code[2]); + + /* Differential gain gets sent to uCode only once */ + if (!data->radio_write) { + struct iwl_calib_diff_gain_cmd cmd; + data->radio_write = 1; + + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD; + cmd.diff_gain_a = data->delta_gain_code[0]; + cmd.diff_gain_b = data->delta_gain_code[1]; + cmd.diff_gain_c = data->delta_gain_code[2]; + ret = iwl_legacy_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, + sizeof(cmd), &cmd); + if (ret) + IWL_DEBUG_CALIB(priv, "fail sending cmd " + "REPLY_PHY_CALIBRATION_CMD\n"); + + /* TODO we might want recalculate + * rx_chain in rxon cmd */ + + /* Mark so we run this algo only once! */ + data->state = IWL_CHAIN_NOISE_CALIBRATED; + } +} + + + +/* + * Accumulate 16 beacons of signal and noise statistics for each of + * 3 receivers/antennas/rx-chains, then figure out: + * 1) Which antennas are connected. + * 2) Differential rx gain settings to balance the 3 receivers. + */ +void iwl4965_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) +{ + struct iwl_chain_noise_data *data = NULL; + + u32 chain_noise_a; + u32 chain_noise_b; + u32 chain_noise_c; + u32 chain_sig_a; + u32 chain_sig_b; + u32 chain_sig_c; + u32 average_sig[NUM_RX_CHAINS] = {INITIALIZATION_VALUE}; + u32 average_noise[NUM_RX_CHAINS] = {INITIALIZATION_VALUE}; + u32 min_average_noise = MIN_AVERAGE_NOISE_MAX_VALUE; + u16 min_average_noise_antenna_i = INITIALIZATION_VALUE; + u16 i = 0; + u16 rxon_chnum = INITIALIZATION_VALUE; + u16 stat_chnum = INITIALIZATION_VALUE; + u8 rxon_band24; + u8 stat_band24; + unsigned long flags; + struct statistics_rx_non_phy *rx_info; + + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + if (priv->disable_chain_noise_cal) + return; + + data = &(priv->chain_noise_data); + + /* + * Accumulate just the first "chain_noise_num_beacons" after + * the first association, then we're done forever. + */ + if (data->state != IWL_CHAIN_NOISE_ACCUMULATE) { + if (data->state == IWL_CHAIN_NOISE_ALIVE) + IWL_DEBUG_CALIB(priv, "Wait for noise calib reset\n"); + return; + } + + spin_lock_irqsave(&priv->lock, flags); + + rx_info = &(((struct iwl_notif_statistics *)stat_resp)-> + rx.general); + + if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { + IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n"); + spin_unlock_irqrestore(&priv->lock, flags); + return; + } + + rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK); + rxon_chnum = le16_to_cpu(ctx->staging.channel); + + stat_band24 = !!(((struct iwl_notif_statistics *) + stat_resp)->flag & + STATISTICS_REPLY_FLG_BAND_24G_MSK); + stat_chnum = le32_to_cpu(((struct iwl_notif_statistics *) + stat_resp)->flag) >> 16; + + /* Make sure we accumulate data for just the associated channel + * (even if scanning). */ + if ((rxon_chnum != stat_chnum) || (rxon_band24 != stat_band24)) { + IWL_DEBUG_CALIB(priv, "Stats not from chan=%d, band24=%d\n", + rxon_chnum, rxon_band24); + spin_unlock_irqrestore(&priv->lock, flags); + return; + } + + /* + * Accumulate beacon statistics values across + * "chain_noise_num_beacons" + */ + chain_noise_a = le32_to_cpu(rx_info->beacon_silence_rssi_a) & + IN_BAND_FILTER; + chain_noise_b = le32_to_cpu(rx_info->beacon_silence_rssi_b) & + IN_BAND_FILTER; + chain_noise_c = le32_to_cpu(rx_info->beacon_silence_rssi_c) & + IN_BAND_FILTER; + + chain_sig_a = le32_to_cpu(rx_info->beacon_rssi_a) & IN_BAND_FILTER; + chain_sig_b = le32_to_cpu(rx_info->beacon_rssi_b) & IN_BAND_FILTER; + chain_sig_c = le32_to_cpu(rx_info->beacon_rssi_c) & IN_BAND_FILTER; + + spin_unlock_irqrestore(&priv->lock, flags); + + data->beacon_count++; + + data->chain_noise_a = (chain_noise_a + data->chain_noise_a); + data->chain_noise_b = (chain_noise_b + data->chain_noise_b); + data->chain_noise_c = (chain_noise_c + data->chain_noise_c); + + data->chain_signal_a = (chain_sig_a + data->chain_signal_a); + data->chain_signal_b = (chain_sig_b + data->chain_signal_b); + data->chain_signal_c = (chain_sig_c + data->chain_signal_c); + + IWL_DEBUG_CALIB(priv, "chan=%d, band24=%d, beacon=%d\n", + rxon_chnum, rxon_band24, data->beacon_count); + IWL_DEBUG_CALIB(priv, "chain_sig: a %d b %d c %d\n", + chain_sig_a, chain_sig_b, chain_sig_c); + IWL_DEBUG_CALIB(priv, "chain_noise: a %d b %d c %d\n", + chain_noise_a, chain_noise_b, chain_noise_c); + + /* If this is the "chain_noise_num_beacons", determine: + * 1) Disconnected antennas (using signal strengths) + * 2) Differential gain (using silence noise) to balance receivers */ + if (data->beacon_count != + priv->cfg->base_params->chain_noise_num_beacons) + return; + + /* Analyze signal for disconnected antenna */ + iwl4965_find_disconn_antenna(priv, average_sig, data); + + /* Analyze noise for rx balance */ + average_noise[0] = data->chain_noise_a / + priv->cfg->base_params->chain_noise_num_beacons; + average_noise[1] = data->chain_noise_b / + priv->cfg->base_params->chain_noise_num_beacons; + average_noise[2] = data->chain_noise_c / + priv->cfg->base_params->chain_noise_num_beacons; + + for (i = 0; i < NUM_RX_CHAINS; i++) { + if (!(data->disconn_array[i]) && + (average_noise[i] <= min_average_noise)) { + /* This means that chain i is active and has + * lower noise values so far: */ + min_average_noise = average_noise[i]; + min_average_noise_antenna_i = i; + } + } + + IWL_DEBUG_CALIB(priv, "average_noise: a %d b %d c %d\n", + average_noise[0], average_noise[1], + average_noise[2]); + + IWL_DEBUG_CALIB(priv, "min_average_noise = %d, antenna %d\n", + min_average_noise, min_average_noise_antenna_i); + + iwl4965_gain_computation(priv, average_noise, + min_average_noise_antenna_i, min_average_noise, + iwl4965_find_first_chain(priv->cfg->valid_rx_ant)); + + /* Some power changes may have been made during the calibration. + * Update and commit the RXON + */ + if (priv->cfg->ops->lib->update_chain_flags) + priv->cfg->ops->lib->update_chain_flags(priv); + + data->state = IWL_CHAIN_NOISE_DONE; + iwl_legacy_power_update_mode(priv, false); +} + +void iwl4965_reset_run_time_calib(struct iwl_priv *priv) +{ + int i; + memset(&(priv->sensitivity_data), 0, + sizeof(struct iwl_sensitivity_data)); + memset(&(priv->chain_noise_data), 0, + sizeof(struct iwl_chain_noise_data)); + for (i = 0; i < NUM_RX_CHAINS; i++) + priv->chain_noise_data.delta_gain_code[i] = + CHAIN_NOISE_DELTA_GAIN_INIT_VAL; + + /* Ask for statistics now, the uCode will send notification + * periodically after association */ + iwl_legacy_send_statistics_request(priv, CMD_ASYNC, true); +} diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-calib.h b/drivers/net/wireless/iwlegacy/iwl-4965-calib.h new file mode 100644 index 000000000000..f46c80e6e005 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-4965-calib.h @@ -0,0 +1,75 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ +#ifndef __iwl_4965_calib_h__ +#define __iwl_4965_calib_h__ + +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-commands.h" + +void iwl4965_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp); +void iwl4965_sensitivity_calibration(struct iwl_priv *priv, void *resp); +void iwl4965_init_sensitivity(struct iwl_priv *priv); +void iwl4965_reset_run_time_calib(struct iwl_priv *priv); +void iwl4965_calib_free_results(struct iwl_priv *priv); + +#endif /* __iwl_4965_calib_h__ */ diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-debugfs.c b/drivers/net/wireless/iwlegacy/iwl-4965-debugfs.c new file mode 100644 index 000000000000..1c93665766e4 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-4965-debugfs.c @@ -0,0 +1,774 @@ +/****************************************************************************** +* +* GPL LICENSE SUMMARY +* +* Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of version 2 of the GNU General Public License as +* published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, +* USA +* +* The full GNU General Public License is included in this distribution +* in the file called LICENSE.GPL. +* +* Contact Information: +* Intel Linux Wireless +* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 +*****************************************************************************/ +#include "iwl-4965.h" +#include "iwl-4965-debugfs.h" + +static const char *fmt_value = " %-30s %10u\n"; +static const char *fmt_table = " %-30s %10u %10u %10u %10u\n"; +static const char *fmt_header = + "%-32s current cumulative delta max\n"; + +static int iwl4965_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) +{ + int p = 0; + u32 flag; + + flag = le32_to_cpu(priv->_4965.statistics.flag); + + p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); + if (flag & UCODE_STATISTICS_CLEAR_MSK) + p += scnprintf(buf + p, bufsz - p, + "\tStatistics have been cleared\n"); + p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n", + (flag & UCODE_STATISTICS_FREQUENCY_MSK) + ? "2.4 GHz" : "5.2 GHz"); + p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n", + (flag & UCODE_STATISTICS_NARROW_BAND_MSK) + ? "enabled" : "disabled"); + + return p; +} + +ssize_t iwl4965_ucode_rx_stats_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + int pos = 0; + char *buf; + int bufsz = sizeof(struct statistics_rx_phy) * 40 + + sizeof(struct statistics_rx_non_phy) * 40 + + sizeof(struct statistics_rx_ht_phy) * 40 + 400; + ssize_t ret; + struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm; + struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck; + struct statistics_rx_non_phy *general, *accum_general; + struct statistics_rx_non_phy *delta_general, *max_general; + struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht; + + if (!iwl_legacy_is_alive(priv)) + return -EAGAIN; + + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate Buffer\n"); + return -ENOMEM; + } + + /* + * the statistic information display here is based on + * the last statistics notification from uCode + * might not reflect the current uCode activity + */ + ofdm = &priv->_4965.statistics.rx.ofdm; + cck = &priv->_4965.statistics.rx.cck; + general = &priv->_4965.statistics.rx.general; + ht = &priv->_4965.statistics.rx.ofdm_ht; + accum_ofdm = &priv->_4965.accum_statistics.rx.ofdm; + accum_cck = &priv->_4965.accum_statistics.rx.cck; + accum_general = &priv->_4965.accum_statistics.rx.general; + accum_ht = &priv->_4965.accum_statistics.rx.ofdm_ht; + delta_ofdm = &priv->_4965.delta_statistics.rx.ofdm; + delta_cck = &priv->_4965.delta_statistics.rx.cck; + delta_general = &priv->_4965.delta_statistics.rx.general; + delta_ht = &priv->_4965.delta_statistics.rx.ofdm_ht; + max_ofdm = &priv->_4965.max_delta.rx.ofdm; + max_cck = &priv->_4965.max_delta.rx.cck; + max_general = &priv->_4965.max_delta.rx.general; + max_ht = &priv->_4965.max_delta.rx.ofdm_ht; + + pos += iwl4965_statistics_flag(priv, buf, bufsz); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_header, "Statistics_Rx - OFDM:"); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "ina_cnt:", + le32_to_cpu(ofdm->ina_cnt), + accum_ofdm->ina_cnt, + delta_ofdm->ina_cnt, max_ofdm->ina_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "fina_cnt:", + le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt, + delta_ofdm->fina_cnt, max_ofdm->fina_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "plcp_err:", + le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err, + delta_ofdm->plcp_err, max_ofdm->plcp_err); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "crc32_err:", + le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err, + delta_ofdm->crc32_err, max_ofdm->crc32_err); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "overrun_err:", + le32_to_cpu(ofdm->overrun_err), + accum_ofdm->overrun_err, delta_ofdm->overrun_err, + max_ofdm->overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "early_overrun_err:", + le32_to_cpu(ofdm->early_overrun_err), + accum_ofdm->early_overrun_err, + delta_ofdm->early_overrun_err, + max_ofdm->early_overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "crc32_good:", + le32_to_cpu(ofdm->crc32_good), + accum_ofdm->crc32_good, delta_ofdm->crc32_good, + max_ofdm->crc32_good); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "false_alarm_cnt:", + le32_to_cpu(ofdm->false_alarm_cnt), + accum_ofdm->false_alarm_cnt, + delta_ofdm->false_alarm_cnt, + max_ofdm->false_alarm_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "fina_sync_err_cnt:", + le32_to_cpu(ofdm->fina_sync_err_cnt), + accum_ofdm->fina_sync_err_cnt, + delta_ofdm->fina_sync_err_cnt, + max_ofdm->fina_sync_err_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "sfd_timeout:", + le32_to_cpu(ofdm->sfd_timeout), + accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout, + max_ofdm->sfd_timeout); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "fina_timeout:", + le32_to_cpu(ofdm->fina_timeout), + accum_ofdm->fina_timeout, delta_ofdm->fina_timeout, + max_ofdm->fina_timeout); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "unresponded_rts:", + le32_to_cpu(ofdm->unresponded_rts), + accum_ofdm->unresponded_rts, + delta_ofdm->unresponded_rts, + max_ofdm->unresponded_rts); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "rxe_frame_lmt_ovrun:", + le32_to_cpu(ofdm->rxe_frame_limit_overrun), + accum_ofdm->rxe_frame_limit_overrun, + delta_ofdm->rxe_frame_limit_overrun, + max_ofdm->rxe_frame_limit_overrun); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "sent_ack_cnt:", + le32_to_cpu(ofdm->sent_ack_cnt), + accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt, + max_ofdm->sent_ack_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "sent_cts_cnt:", + le32_to_cpu(ofdm->sent_cts_cnt), + accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt, + max_ofdm->sent_cts_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "sent_ba_rsp_cnt:", + le32_to_cpu(ofdm->sent_ba_rsp_cnt), + accum_ofdm->sent_ba_rsp_cnt, + delta_ofdm->sent_ba_rsp_cnt, + max_ofdm->sent_ba_rsp_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "dsp_self_kill:", + le32_to_cpu(ofdm->dsp_self_kill), + accum_ofdm->dsp_self_kill, + delta_ofdm->dsp_self_kill, + max_ofdm->dsp_self_kill); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "mh_format_err:", + le32_to_cpu(ofdm->mh_format_err), + accum_ofdm->mh_format_err, + delta_ofdm->mh_format_err, + max_ofdm->mh_format_err); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "re_acq_main_rssi_sum:", + le32_to_cpu(ofdm->re_acq_main_rssi_sum), + accum_ofdm->re_acq_main_rssi_sum, + delta_ofdm->re_acq_main_rssi_sum, + max_ofdm->re_acq_main_rssi_sum); + + pos += scnprintf(buf + pos, bufsz - pos, + fmt_header, "Statistics_Rx - CCK:"); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "ina_cnt:", + le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt, + delta_cck->ina_cnt, max_cck->ina_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "fina_cnt:", + le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt, + delta_cck->fina_cnt, max_cck->fina_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "plcp_err:", + le32_to_cpu(cck->plcp_err), accum_cck->plcp_err, + delta_cck->plcp_err, max_cck->plcp_err); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "crc32_err:", + le32_to_cpu(cck->crc32_err), accum_cck->crc32_err, + delta_cck->crc32_err, max_cck->crc32_err); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "overrun_err:", + le32_to_cpu(cck->overrun_err), + accum_cck->overrun_err, delta_cck->overrun_err, + max_cck->overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "early_overrun_err:", + le32_to_cpu(cck->early_overrun_err), + accum_cck->early_overrun_err, + delta_cck->early_overrun_err, + max_cck->early_overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "crc32_good:", + le32_to_cpu(cck->crc32_good), accum_cck->crc32_good, + delta_cck->crc32_good, max_cck->crc32_good); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "false_alarm_cnt:", + le32_to_cpu(cck->false_alarm_cnt), + accum_cck->false_alarm_cnt, + delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "fina_sync_err_cnt:", + le32_to_cpu(cck->fina_sync_err_cnt), + accum_cck->fina_sync_err_cnt, + delta_cck->fina_sync_err_cnt, + max_cck->fina_sync_err_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "sfd_timeout:", + le32_to_cpu(cck->sfd_timeout), + accum_cck->sfd_timeout, delta_cck->sfd_timeout, + max_cck->sfd_timeout); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "fina_timeout:", + le32_to_cpu(cck->fina_timeout), + accum_cck->fina_timeout, delta_cck->fina_timeout, + max_cck->fina_timeout); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "unresponded_rts:", + le32_to_cpu(cck->unresponded_rts), + accum_cck->unresponded_rts, delta_cck->unresponded_rts, + max_cck->unresponded_rts); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "rxe_frame_lmt_ovrun:", + le32_to_cpu(cck->rxe_frame_limit_overrun), + accum_cck->rxe_frame_limit_overrun, + delta_cck->rxe_frame_limit_overrun, + max_cck->rxe_frame_limit_overrun); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "sent_ack_cnt:", + le32_to_cpu(cck->sent_ack_cnt), + accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt, + max_cck->sent_ack_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "sent_cts_cnt:", + le32_to_cpu(cck->sent_cts_cnt), + accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt, + max_cck->sent_cts_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "sent_ba_rsp_cnt:", + le32_to_cpu(cck->sent_ba_rsp_cnt), + accum_cck->sent_ba_rsp_cnt, + delta_cck->sent_ba_rsp_cnt, + max_cck->sent_ba_rsp_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "dsp_self_kill:", + le32_to_cpu(cck->dsp_self_kill), + accum_cck->dsp_self_kill, delta_cck->dsp_self_kill, + max_cck->dsp_self_kill); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "mh_format_err:", + le32_to_cpu(cck->mh_format_err), + accum_cck->mh_format_err, delta_cck->mh_format_err, + max_cck->mh_format_err); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "re_acq_main_rssi_sum:", + le32_to_cpu(cck->re_acq_main_rssi_sum), + accum_cck->re_acq_main_rssi_sum, + delta_cck->re_acq_main_rssi_sum, + max_cck->re_acq_main_rssi_sum); + + pos += scnprintf(buf + pos, bufsz - pos, + fmt_header, "Statistics_Rx - GENERAL:"); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "bogus_cts:", + le32_to_cpu(general->bogus_cts), + accum_general->bogus_cts, delta_general->bogus_cts, + max_general->bogus_cts); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "bogus_ack:", + le32_to_cpu(general->bogus_ack), + accum_general->bogus_ack, delta_general->bogus_ack, + max_general->bogus_ack); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "non_bssid_frames:", + le32_to_cpu(general->non_bssid_frames), + accum_general->non_bssid_frames, + delta_general->non_bssid_frames, + max_general->non_bssid_frames); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "filtered_frames:", + le32_to_cpu(general->filtered_frames), + accum_general->filtered_frames, + delta_general->filtered_frames, + max_general->filtered_frames); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "non_channel_beacons:", + le32_to_cpu(general->non_channel_beacons), + accum_general->non_channel_beacons, + delta_general->non_channel_beacons, + max_general->non_channel_beacons); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "channel_beacons:", + le32_to_cpu(general->channel_beacons), + accum_general->channel_beacons, + delta_general->channel_beacons, + max_general->channel_beacons); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "num_missed_bcon:", + le32_to_cpu(general->num_missed_bcon), + accum_general->num_missed_bcon, + delta_general->num_missed_bcon, + max_general->num_missed_bcon); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "adc_rx_saturation_time:", + le32_to_cpu(general->adc_rx_saturation_time), + accum_general->adc_rx_saturation_time, + delta_general->adc_rx_saturation_time, + max_general->adc_rx_saturation_time); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "ina_detect_search_tm:", + le32_to_cpu(general->ina_detection_search_time), + accum_general->ina_detection_search_time, + delta_general->ina_detection_search_time, + max_general->ina_detection_search_time); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "beacon_silence_rssi_a:", + le32_to_cpu(general->beacon_silence_rssi_a), + accum_general->beacon_silence_rssi_a, + delta_general->beacon_silence_rssi_a, + max_general->beacon_silence_rssi_a); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "beacon_silence_rssi_b:", + le32_to_cpu(general->beacon_silence_rssi_b), + accum_general->beacon_silence_rssi_b, + delta_general->beacon_silence_rssi_b, + max_general->beacon_silence_rssi_b); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "beacon_silence_rssi_c:", + le32_to_cpu(general->beacon_silence_rssi_c), + accum_general->beacon_silence_rssi_c, + delta_general->beacon_silence_rssi_c, + max_general->beacon_silence_rssi_c); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "interference_data_flag:", + le32_to_cpu(general->interference_data_flag), + accum_general->interference_data_flag, + delta_general->interference_data_flag, + max_general->interference_data_flag); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "channel_load:", + le32_to_cpu(general->channel_load), + accum_general->channel_load, + delta_general->channel_load, + max_general->channel_load); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "dsp_false_alarms:", + le32_to_cpu(general->dsp_false_alarms), + accum_general->dsp_false_alarms, + delta_general->dsp_false_alarms, + max_general->dsp_false_alarms); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "beacon_rssi_a:", + le32_to_cpu(general->beacon_rssi_a), + accum_general->beacon_rssi_a, + delta_general->beacon_rssi_a, + max_general->beacon_rssi_a); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "beacon_rssi_b:", + le32_to_cpu(general->beacon_rssi_b), + accum_general->beacon_rssi_b, + delta_general->beacon_rssi_b, + max_general->beacon_rssi_b); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "beacon_rssi_c:", + le32_to_cpu(general->beacon_rssi_c), + accum_general->beacon_rssi_c, + delta_general->beacon_rssi_c, + max_general->beacon_rssi_c); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "beacon_energy_a:", + le32_to_cpu(general->beacon_energy_a), + accum_general->beacon_energy_a, + delta_general->beacon_energy_a, + max_general->beacon_energy_a); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "beacon_energy_b:", + le32_to_cpu(general->beacon_energy_b), + accum_general->beacon_energy_b, + delta_general->beacon_energy_b, + max_general->beacon_energy_b); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "beacon_energy_c:", + le32_to_cpu(general->beacon_energy_c), + accum_general->beacon_energy_c, + delta_general->beacon_energy_c, + max_general->beacon_energy_c); + + pos += scnprintf(buf + pos, bufsz - pos, + fmt_header, "Statistics_Rx - OFDM_HT:"); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "plcp_err:", + le32_to_cpu(ht->plcp_err), accum_ht->plcp_err, + delta_ht->plcp_err, max_ht->plcp_err); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "overrun_err:", + le32_to_cpu(ht->overrun_err), accum_ht->overrun_err, + delta_ht->overrun_err, max_ht->overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "early_overrun_err:", + le32_to_cpu(ht->early_overrun_err), + accum_ht->early_overrun_err, + delta_ht->early_overrun_err, + max_ht->early_overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "crc32_good:", + le32_to_cpu(ht->crc32_good), accum_ht->crc32_good, + delta_ht->crc32_good, max_ht->crc32_good); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "crc32_err:", + le32_to_cpu(ht->crc32_err), accum_ht->crc32_err, + delta_ht->crc32_err, max_ht->crc32_err); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "mh_format_err:", + le32_to_cpu(ht->mh_format_err), + accum_ht->mh_format_err, + delta_ht->mh_format_err, max_ht->mh_format_err); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "agg_crc32_good:", + le32_to_cpu(ht->agg_crc32_good), + accum_ht->agg_crc32_good, + delta_ht->agg_crc32_good, max_ht->agg_crc32_good); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "agg_mpdu_cnt:", + le32_to_cpu(ht->agg_mpdu_cnt), + accum_ht->agg_mpdu_cnt, + delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "agg_cnt:", + le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt, + delta_ht->agg_cnt, max_ht->agg_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "unsupport_mcs:", + le32_to_cpu(ht->unsupport_mcs), + accum_ht->unsupport_mcs, + delta_ht->unsupport_mcs, max_ht->unsupport_mcs); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} + +ssize_t iwl4965_ucode_tx_stats_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + int pos = 0; + char *buf; + int bufsz = (sizeof(struct statistics_tx) * 48) + 250; + ssize_t ret; + struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; + + if (!iwl_legacy_is_alive(priv)) + return -EAGAIN; + + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate Buffer\n"); + return -ENOMEM; + } + + /* the statistic information display here is based on + * the last statistics notification from uCode + * might not reflect the current uCode activity + */ + tx = &priv->_4965.statistics.tx; + accum_tx = &priv->_4965.accum_statistics.tx; + delta_tx = &priv->_4965.delta_statistics.tx; + max_tx = &priv->_4965.max_delta.tx; + + pos += iwl4965_statistics_flag(priv, buf, bufsz); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_header, "Statistics_Tx:"); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "preamble:", + le32_to_cpu(tx->preamble_cnt), + accum_tx->preamble_cnt, + delta_tx->preamble_cnt, max_tx->preamble_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "rx_detected_cnt:", + le32_to_cpu(tx->rx_detected_cnt), + accum_tx->rx_detected_cnt, + delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "bt_prio_defer_cnt:", + le32_to_cpu(tx->bt_prio_defer_cnt), + accum_tx->bt_prio_defer_cnt, + delta_tx->bt_prio_defer_cnt, + max_tx->bt_prio_defer_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "bt_prio_kill_cnt:", + le32_to_cpu(tx->bt_prio_kill_cnt), + accum_tx->bt_prio_kill_cnt, + delta_tx->bt_prio_kill_cnt, + max_tx->bt_prio_kill_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "few_bytes_cnt:", + le32_to_cpu(tx->few_bytes_cnt), + accum_tx->few_bytes_cnt, + delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "cts_timeout:", + le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout, + delta_tx->cts_timeout, max_tx->cts_timeout); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "ack_timeout:", + le32_to_cpu(tx->ack_timeout), + accum_tx->ack_timeout, + delta_tx->ack_timeout, max_tx->ack_timeout); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "expected_ack_cnt:", + le32_to_cpu(tx->expected_ack_cnt), + accum_tx->expected_ack_cnt, + delta_tx->expected_ack_cnt, + max_tx->expected_ack_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "actual_ack_cnt:", + le32_to_cpu(tx->actual_ack_cnt), + accum_tx->actual_ack_cnt, + delta_tx->actual_ack_cnt, + max_tx->actual_ack_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "dump_msdu_cnt:", + le32_to_cpu(tx->dump_msdu_cnt), + accum_tx->dump_msdu_cnt, + delta_tx->dump_msdu_cnt, + max_tx->dump_msdu_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "abort_nxt_frame_mismatch:", + le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt), + accum_tx->burst_abort_next_frame_mismatch_cnt, + delta_tx->burst_abort_next_frame_mismatch_cnt, + max_tx->burst_abort_next_frame_mismatch_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "abort_missing_nxt_frame:", + le32_to_cpu(tx->burst_abort_missing_next_frame_cnt), + accum_tx->burst_abort_missing_next_frame_cnt, + delta_tx->burst_abort_missing_next_frame_cnt, + max_tx->burst_abort_missing_next_frame_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "cts_timeout_collision:", + le32_to_cpu(tx->cts_timeout_collision), + accum_tx->cts_timeout_collision, + delta_tx->cts_timeout_collision, + max_tx->cts_timeout_collision); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "ack_ba_timeout_collision:", + le32_to_cpu(tx->ack_or_ba_timeout_collision), + accum_tx->ack_or_ba_timeout_collision, + delta_tx->ack_or_ba_timeout_collision, + max_tx->ack_or_ba_timeout_collision); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "agg ba_timeout:", + le32_to_cpu(tx->agg.ba_timeout), + accum_tx->agg.ba_timeout, + delta_tx->agg.ba_timeout, + max_tx->agg.ba_timeout); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "agg ba_resched_frames:", + le32_to_cpu(tx->agg.ba_reschedule_frames), + accum_tx->agg.ba_reschedule_frames, + delta_tx->agg.ba_reschedule_frames, + max_tx->agg.ba_reschedule_frames); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "agg scd_query_agg_frame:", + le32_to_cpu(tx->agg.scd_query_agg_frame_cnt), + accum_tx->agg.scd_query_agg_frame_cnt, + delta_tx->agg.scd_query_agg_frame_cnt, + max_tx->agg.scd_query_agg_frame_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "agg scd_query_no_agg:", + le32_to_cpu(tx->agg.scd_query_no_agg), + accum_tx->agg.scd_query_no_agg, + delta_tx->agg.scd_query_no_agg, + max_tx->agg.scd_query_no_agg); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "agg scd_query_agg:", + le32_to_cpu(tx->agg.scd_query_agg), + accum_tx->agg.scd_query_agg, + delta_tx->agg.scd_query_agg, + max_tx->agg.scd_query_agg); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "agg scd_query_mismatch:", + le32_to_cpu(tx->agg.scd_query_mismatch), + accum_tx->agg.scd_query_mismatch, + delta_tx->agg.scd_query_mismatch, + max_tx->agg.scd_query_mismatch); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "agg frame_not_ready:", + le32_to_cpu(tx->agg.frame_not_ready), + accum_tx->agg.frame_not_ready, + delta_tx->agg.frame_not_ready, + max_tx->agg.frame_not_ready); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "agg underrun:", + le32_to_cpu(tx->agg.underrun), + accum_tx->agg.underrun, + delta_tx->agg.underrun, max_tx->agg.underrun); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "agg bt_prio_kill:", + le32_to_cpu(tx->agg.bt_prio_kill), + accum_tx->agg.bt_prio_kill, + delta_tx->agg.bt_prio_kill, + max_tx->agg.bt_prio_kill); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "agg rx_ba_rsp_cnt:", + le32_to_cpu(tx->agg.rx_ba_rsp_cnt), + accum_tx->agg.rx_ba_rsp_cnt, + delta_tx->agg.rx_ba_rsp_cnt, + max_tx->agg.rx_ba_rsp_cnt); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} + +ssize_t +iwl4965_ucode_general_stats_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + int pos = 0; + char *buf; + int bufsz = sizeof(struct statistics_general) * 10 + 300; + ssize_t ret; + struct statistics_general_common *general, *accum_general; + struct statistics_general_common *delta_general, *max_general; + struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; + struct statistics_div *div, *accum_div, *delta_div, *max_div; + + if (!iwl_legacy_is_alive(priv)) + return -EAGAIN; + + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate Buffer\n"); + return -ENOMEM; + } + + /* the statistic information display here is based on + * the last statistics notification from uCode + * might not reflect the current uCode activity + */ + general = &priv->_4965.statistics.general.common; + dbg = &priv->_4965.statistics.general.common.dbg; + div = &priv->_4965.statistics.general.common.div; + accum_general = &priv->_4965.accum_statistics.general.common; + accum_dbg = &priv->_4965.accum_statistics.general.common.dbg; + accum_div = &priv->_4965.accum_statistics.general.common.div; + delta_general = &priv->_4965.delta_statistics.general.common; + max_general = &priv->_4965.max_delta.general.common; + delta_dbg = &priv->_4965.delta_statistics.general.common.dbg; + max_dbg = &priv->_4965.max_delta.general.common.dbg; + delta_div = &priv->_4965.delta_statistics.general.common.div; + max_div = &priv->_4965.max_delta.general.common.div; + + pos += iwl4965_statistics_flag(priv, buf, bufsz); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_header, "Statistics_General:"); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_value, "temperature:", + le32_to_cpu(general->temperature)); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_value, "ttl_timestamp:", + le32_to_cpu(general->ttl_timestamp)); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "burst_check:", + le32_to_cpu(dbg->burst_check), + accum_dbg->burst_check, + delta_dbg->burst_check, max_dbg->burst_check); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "burst_count:", + le32_to_cpu(dbg->burst_count), + accum_dbg->burst_count, + delta_dbg->burst_count, max_dbg->burst_count); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "wait_for_silence_timeout_count:", + le32_to_cpu(dbg->wait_for_silence_timeout_cnt), + accum_dbg->wait_for_silence_timeout_cnt, + delta_dbg->wait_for_silence_timeout_cnt, + max_dbg->wait_for_silence_timeout_cnt); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "sleep_time:", + le32_to_cpu(general->sleep_time), + accum_general->sleep_time, + delta_general->sleep_time, max_general->sleep_time); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "slots_out:", + le32_to_cpu(general->slots_out), + accum_general->slots_out, + delta_general->slots_out, max_general->slots_out); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "slots_idle:", + le32_to_cpu(general->slots_idle), + accum_general->slots_idle, + delta_general->slots_idle, max_general->slots_idle); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "tx_on_a:", + le32_to_cpu(div->tx_on_a), accum_div->tx_on_a, + delta_div->tx_on_a, max_div->tx_on_a); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "tx_on_b:", + le32_to_cpu(div->tx_on_b), accum_div->tx_on_b, + delta_div->tx_on_b, max_div->tx_on_b); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "exec_time:", + le32_to_cpu(div->exec_time), accum_div->exec_time, + delta_div->exec_time, max_div->exec_time); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "probe_time:", + le32_to_cpu(div->probe_time), accum_div->probe_time, + delta_div->probe_time, max_div->probe_time); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "rx_enable_counter:", + le32_to_cpu(general->rx_enable_counter), + accum_general->rx_enable_counter, + delta_general->rx_enable_counter, + max_general->rx_enable_counter); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "num_of_sos_states:", + le32_to_cpu(general->num_of_sos_states), + accum_general->num_of_sos_states, + delta_general->num_of_sos_states, + max_general->num_of_sos_states); + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-debugfs.h b/drivers/net/wireless/iwlegacy/iwl-4965-debugfs.h new file mode 100644 index 000000000000..6c8e35361a9e --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-4965-debugfs.h @@ -0,0 +1,59 @@ +/****************************************************************************** + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ + +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-debug.h" + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS +ssize_t iwl4965_ucode_rx_stats_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos); +ssize_t iwl4965_ucode_tx_stats_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos); +ssize_t iwl4965_ucode_general_stats_read(struct file *file, + char __user *user_buf, size_t count, loff_t *ppos); +#else +static ssize_t +iwl4965_ucode_rx_stats_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + return 0; +} +static ssize_t +iwl4965_ucode_tx_stats_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + return 0; +} +static ssize_t +iwl4965_ucode_general_stats_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + return 0; +} +#endif diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-eeprom.c b/drivers/net/wireless/iwlegacy/iwl-4965-eeprom.c new file mode 100644 index 000000000000..cb9baab1ff7d --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-4965-eeprom.c @@ -0,0 +1,154 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + + +#include +#include +#include +#include + +#include + +#include "iwl-commands.h" +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-debug.h" +#include "iwl-4965.h" +#include "iwl-io.h" + +/****************************************************************************** + * + * EEPROM related functions + * +******************************************************************************/ + +/* + * The device's EEPROM semaphore prevents conflicts between driver and uCode + * when accessing the EEPROM; each access is a series of pulses to/from the + * EEPROM chip, not a single event, so even reads could conflict if they + * weren't arbitrated by the semaphore. + */ +int iwl4965_eeprom_acquire_semaphore(struct iwl_priv *priv) +{ + u16 count; + int ret; + + for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { + /* Request semaphore */ + iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); + + /* See if we got it */ + ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, + CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, + EEPROM_SEM_TIMEOUT); + if (ret >= 0) { + IWL_DEBUG_IO(priv, + "Acquired semaphore after %d tries.\n", + count+1); + return ret; + } + } + + return ret; +} + +void iwl4965_eeprom_release_semaphore(struct iwl_priv *priv) +{ + iwl_legacy_clear_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); + +} + +int iwl4965_eeprom_check_version(struct iwl_priv *priv) +{ + u16 eeprom_ver; + u16 calib_ver; + + eeprom_ver = iwl_legacy_eeprom_query16(priv, EEPROM_VERSION); + calib_ver = iwl_legacy_eeprom_query16(priv, + EEPROM_4965_CALIB_VERSION_OFFSET); + + if (eeprom_ver < priv->cfg->eeprom_ver || + calib_ver < priv->cfg->eeprom_calib_ver) + goto err; + + IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n", + eeprom_ver, calib_ver); + + return 0; +err: + IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x " + "CALIB=0x%x < 0x%x\n", + eeprom_ver, priv->cfg->eeprom_ver, + calib_ver, priv->cfg->eeprom_calib_ver); + return -EINVAL; + +} + +void iwl4965_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac) +{ + const u8 *addr = iwl_legacy_eeprom_query_addr(priv, + EEPROM_MAC_ADDRESS); + memcpy(mac, addr, ETH_ALEN); +} diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-hw.h b/drivers/net/wireless/iwlegacy/iwl-4965-hw.h new file mode 100644 index 000000000000..08b189c8472d --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-4965-hw.h @@ -0,0 +1,814 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Please use this file (iwl-4965-hw.h) only for hardware-related definitions. + * Use iwl-commands.h for uCode API definitions. + * Use iwl-dev.h for driver implementation definitions. + */ + +#ifndef __iwl_4965_hw_h__ +#define __iwl_4965_hw_h__ + +#include "iwl-fh.h" + +/* EEPROM */ +#define IWL4965_EEPROM_IMG_SIZE 1024 + +/* + * uCode queue management definitions ... + * The first queue used for block-ack aggregation is #7 (4965 only). + * All block-ack aggregation queues should map to Tx DMA/FIFO channel 7. + */ +#define IWL49_FIRST_AMPDU_QUEUE 7 + +/* Sizes and addresses for instruction and data memory (SRAM) in + * 4965's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ +#define IWL49_RTC_INST_LOWER_BOUND (0x000000) +#define IWL49_RTC_INST_UPPER_BOUND (0x018000) + +#define IWL49_RTC_DATA_LOWER_BOUND (0x800000) +#define IWL49_RTC_DATA_UPPER_BOUND (0x80A000) + +#define IWL49_RTC_INST_SIZE (IWL49_RTC_INST_UPPER_BOUND - \ + IWL49_RTC_INST_LOWER_BOUND) +#define IWL49_RTC_DATA_SIZE (IWL49_RTC_DATA_UPPER_BOUND - \ + IWL49_RTC_DATA_LOWER_BOUND) + +#define IWL49_MAX_INST_SIZE IWL49_RTC_INST_SIZE +#define IWL49_MAX_DATA_SIZE IWL49_RTC_DATA_SIZE + +/* Size of uCode instruction memory in bootstrap state machine */ +#define IWL49_MAX_BSM_SIZE BSM_SRAM_SIZE + +static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr) +{ + return (addr >= IWL49_RTC_DATA_LOWER_BOUND) && + (addr < IWL49_RTC_DATA_UPPER_BOUND); +} + +/********************* START TEMPERATURE *************************************/ + +/** + * 4965 temperature calculation. + * + * The driver must calculate the device temperature before calculating + * a txpower setting (amplifier gain is temperature dependent). The + * calculation uses 4 measurements, 3 of which (R1, R2, R3) are calibration + * values used for the life of the driver, and one of which (R4) is the + * real-time temperature indicator. + * + * uCode provides all 4 values to the driver via the "initialize alive" + * notification (see struct iwl4965_init_alive_resp). After the runtime uCode + * image loads, uCode updates the R4 value via statistics notifications + * (see STATISTICS_NOTIFICATION), which occur after each received beacon + * when associated, or can be requested via REPLY_STATISTICS_CMD. + * + * NOTE: uCode provides the R4 value as a 23-bit signed value. Driver + * must sign-extend to 32 bits before applying formula below. + * + * Formula: + * + * degrees Kelvin = ((97 * 259 * (R4 - R2) / (R3 - R1)) / 100) + 8 + * + * NOTE: The basic formula is 259 * (R4-R2) / (R3-R1). The 97/100 is + * an additional correction, which should be centered around 0 degrees + * Celsius (273 degrees Kelvin). The 8 (3 percent of 273) compensates for + * centering the 97/100 correction around 0 degrees K. + * + * Add 273 to Kelvin value to find degrees Celsius, for comparing current + * temperature with factory-measured temperatures when calculating txpower + * settings. + */ +#define TEMPERATURE_CALIB_KELVIN_OFFSET 8 +#define TEMPERATURE_CALIB_A_VAL 259 + +/* Limit range of calculated temperature to be between these Kelvin values */ +#define IWL_TX_POWER_TEMPERATURE_MIN (263) +#define IWL_TX_POWER_TEMPERATURE_MAX (410) + +#define IWL_TX_POWER_TEMPERATURE_OUT_OF_RANGE(t) \ + (((t) < IWL_TX_POWER_TEMPERATURE_MIN) || \ + ((t) > IWL_TX_POWER_TEMPERATURE_MAX)) + +/********************* END TEMPERATURE ***************************************/ + +/********************* START TXPOWER *****************************************/ + +/** + * 4965 txpower calculations rely on information from three sources: + * + * 1) EEPROM + * 2) "initialize" alive notification + * 3) statistics notifications + * + * EEPROM data consists of: + * + * 1) Regulatory information (max txpower and channel usage flags) is provided + * separately for each channel that can possibly supported by 4965. + * 40 MHz wide (.11n HT40) channels are listed separately from 20 MHz + * (legacy) channels. + * + * See struct iwl4965_eeprom_channel for format, and struct iwl4965_eeprom + * for locations in EEPROM. + * + * 2) Factory txpower calibration information is provided separately for + * sub-bands of contiguous channels. 2.4GHz has just one sub-band, + * but 5 GHz has several sub-bands. + * + * In addition, per-band (2.4 and 5 Ghz) saturation txpowers are provided. + * + * See struct iwl4965_eeprom_calib_info (and the tree of structures + * contained within it) for format, and struct iwl4965_eeprom for + * locations in EEPROM. + * + * "Initialization alive" notification (see struct iwl4965_init_alive_resp) + * consists of: + * + * 1) Temperature calculation parameters. + * + * 2) Power supply voltage measurement. + * + * 3) Tx gain compensation to balance 2 transmitters for MIMO use. + * + * Statistics notifications deliver: + * + * 1) Current values for temperature param R4. + */ + +/** + * To calculate a txpower setting for a given desired target txpower, channel, + * modulation bit rate, and transmitter chain (4965 has 2 transmitters to + * support MIMO and transmit diversity), driver must do the following: + * + * 1) Compare desired txpower vs. (EEPROM) regulatory limit for this channel. + * Do not exceed regulatory limit; reduce target txpower if necessary. + * + * If setting up txpowers for MIMO rates (rate indexes 8-15, 24-31), + * 2 transmitters will be used simultaneously; driver must reduce the + * regulatory limit by 3 dB (half-power) for each transmitter, so the + * combined total output of the 2 transmitters is within regulatory limits. + * + * + * 2) Compare target txpower vs. (EEPROM) saturation txpower *reduced by + * backoff for this bit rate*. Do not exceed (saturation - backoff[rate]); + * reduce target txpower if necessary. + * + * Backoff values below are in 1/2 dB units (equivalent to steps in + * txpower gain tables): + * + * OFDM 6 - 36 MBit: 10 steps (5 dB) + * OFDM 48 MBit: 15 steps (7.5 dB) + * OFDM 54 MBit: 17 steps (8.5 dB) + * OFDM 60 MBit: 20 steps (10 dB) + * CCK all rates: 10 steps (5 dB) + * + * Backoff values apply to saturation txpower on a per-transmitter basis; + * when using MIMO (2 transmitters), each transmitter uses the same + * saturation level provided in EEPROM, and the same backoff values; + * no reduction (such as with regulatory txpower limits) is required. + * + * Saturation and Backoff values apply equally to 20 Mhz (legacy) channel + * widths and 40 Mhz (.11n HT40) channel widths; there is no separate + * factory measurement for ht40 channels. + * + * The result of this step is the final target txpower. The rest of + * the steps figure out the proper settings for the device to achieve + * that target txpower. + * + * + * 3) Determine (EEPROM) calibration sub band for the target channel, by + * comparing against first and last channels in each sub band + * (see struct iwl4965_eeprom_calib_subband_info). + * + * + * 4) Linearly interpolate (EEPROM) factory calibration measurement sets, + * referencing the 2 factory-measured (sample) channels within the sub band. + * + * Interpolation is based on difference between target channel's frequency + * and the sample channels' frequencies. Since channel numbers are based + * on frequency (5 MHz between each channel number), this is equivalent + * to interpolating based on channel number differences. + * + * Note that the sample channels may or may not be the channels at the + * edges of the sub band. The target channel may be "outside" of the + * span of the sampled channels. + * + * Driver may choose the pair (for 2 Tx chains) of measurements (see + * struct iwl4965_eeprom_calib_ch_info) for which the actual measured + * txpower comes closest to the desired txpower. Usually, though, + * the middle set of measurements is closest to the regulatory limits, + * and is therefore a good choice for all txpower calculations (this + * assumes that high accuracy is needed for maximizing legal txpower, + * while lower txpower configurations do not need as much accuracy). + * + * Driver should interpolate both members of the chosen measurement pair, + * i.e. for both Tx chains (radio transmitters), unless the driver knows + * that only one of the chains will be used (e.g. only one tx antenna + * connected, but this should be unusual). The rate scaling algorithm + * switches antennas to find best performance, so both Tx chains will + * be used (although only one at a time) even for non-MIMO transmissions. + * + * Driver should interpolate factory values for temperature, gain table + * index, and actual power. The power amplifier detector values are + * not used by the driver. + * + * Sanity check: If the target channel happens to be one of the sample + * channels, the results should agree with the sample channel's + * measurements! + * + * + * 5) Find difference between desired txpower and (interpolated) + * factory-measured txpower. Using (interpolated) factory gain table index + * (shown elsewhere) as a starting point, adjust this index lower to + * increase txpower, or higher to decrease txpower, until the target + * txpower is reached. Each step in the gain table is 1/2 dB. + * + * For example, if factory measured txpower is 16 dBm, and target txpower + * is 13 dBm, add 6 steps to the factory gain index to reduce txpower + * by 3 dB. + * + * + * 6) Find difference between current device temperature and (interpolated) + * factory-measured temperature for sub-band. Factory values are in + * degrees Celsius. To calculate current temperature, see comments for + * "4965 temperature calculation". + * + * If current temperature is higher than factory temperature, driver must + * increase gain (lower gain table index), and vice verse. + * + * Temperature affects gain differently for different channels: + * + * 2.4 GHz all channels: 3.5 degrees per half-dB step + * 5 GHz channels 34-43: 4.5 degrees per half-dB step + * 5 GHz channels >= 44: 4.0 degrees per half-dB step + * + * NOTE: Temperature can increase rapidly when transmitting, especially + * with heavy traffic at high txpowers. Driver should update + * temperature calculations often under these conditions to + * maintain strong txpower in the face of rising temperature. + * + * + * 7) Find difference between current power supply voltage indicator + * (from "initialize alive") and factory-measured power supply voltage + * indicator (EEPROM). + * + * If the current voltage is higher (indicator is lower) than factory + * voltage, gain should be reduced (gain table index increased) by: + * + * (eeprom - current) / 7 + * + * If the current voltage is lower (indicator is higher) than factory + * voltage, gain should be increased (gain table index decreased) by: + * + * 2 * (current - eeprom) / 7 + * + * If number of index steps in either direction turns out to be > 2, + * something is wrong ... just use 0. + * + * NOTE: Voltage compensation is independent of band/channel. + * + * NOTE: "Initialize" uCode measures current voltage, which is assumed + * to be constant after this initial measurement. Voltage + * compensation for txpower (number of steps in gain table) + * may be calculated once and used until the next uCode bootload. + * + * + * 8) If setting up txpowers for MIMO rates (rate indexes 8-15, 24-31), + * adjust txpower for each transmitter chain, so txpower is balanced + * between the two chains. There are 5 pairs of tx_atten[group][chain] + * values in "initialize alive", one pair for each of 5 channel ranges: + * + * Group 0: 5 GHz channel 34-43 + * Group 1: 5 GHz channel 44-70 + * Group 2: 5 GHz channel 71-124 + * Group 3: 5 GHz channel 125-200 + * Group 4: 2.4 GHz all channels + * + * Add the tx_atten[group][chain] value to the index for the target chain. + * The values are signed, but are in pairs of 0 and a non-negative number, + * so as to reduce gain (if necessary) of the "hotter" channel. This + * avoids any need to double-check for regulatory compliance after + * this step. + * + * + * 9) If setting up for a CCK rate, lower the gain by adding a CCK compensation + * value to the index: + * + * Hardware rev B: 9 steps (4.5 dB) + * Hardware rev C: 5 steps (2.5 dB) + * + * Hardware rev for 4965 can be determined by reading CSR_HW_REV_WA_REG, + * bits [3:2], 1 = B, 2 = C. + * + * NOTE: This compensation is in addition to any saturation backoff that + * might have been applied in an earlier step. + * + * + * 10) Select the gain table, based on band (2.4 vs 5 GHz). + * + * Limit the adjusted index to stay within the table! + * + * + * 11) Read gain table entries for DSP and radio gain, place into appropriate + * location(s) in command (struct iwl4965_txpowertable_cmd). + */ + +/** + * When MIMO is used (2 transmitters operating simultaneously), driver should + * limit each transmitter to deliver a max of 3 dB below the regulatory limit + * for the device. That is, use half power for each transmitter, so total + * txpower is within regulatory limits. + * + * The value "6" represents number of steps in gain table to reduce power 3 dB. + * Each step is 1/2 dB. + */ +#define IWL_TX_POWER_MIMO_REGULATORY_COMPENSATION (6) + +/** + * CCK gain compensation. + * + * When calculating txpowers for CCK, after making sure that the target power + * is within regulatory and saturation limits, driver must additionally + * back off gain by adding these values to the gain table index. + * + * Hardware rev for 4965 can be determined by reading CSR_HW_REV_WA_REG, + * bits [3:2], 1 = B, 2 = C. + */ +#define IWL_TX_POWER_CCK_COMPENSATION_B_STEP (9) +#define IWL_TX_POWER_CCK_COMPENSATION_C_STEP (5) + +/* + * 4965 power supply voltage compensation for txpower + */ +#define TX_POWER_IWL_VOLTAGE_CODES_PER_03V (7) + +/** + * Gain tables. + * + * The following tables contain pair of values for setting txpower, i.e. + * gain settings for the output of the device's digital signal processor (DSP), + * and for the analog gain structure of the transmitter. + * + * Each entry in the gain tables represents a step of 1/2 dB. Note that these + * are *relative* steps, not indications of absolute output power. Output + * power varies with temperature, voltage, and channel frequency, and also + * requires consideration of average power (to satisfy regulatory constraints), + * and peak power (to avoid distortion of the output signal). + * + * Each entry contains two values: + * 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained + * linear value that multiplies the output of the digital signal processor, + * before being sent to the analog radio. + * 2) Radio gain. This sets the analog gain of the radio Tx path. + * It is a coarser setting, and behaves in a logarithmic (dB) fashion. + * + * EEPROM contains factory calibration data for txpower. This maps actual + * measured txpower levels to gain settings in the "well known" tables + * below ("well-known" means here that both factory calibration *and* the + * driver work with the same table). + * + * There are separate tables for 2.4 GHz and 5 GHz bands. The 5 GHz table + * has an extension (into negative indexes), in case the driver needs to + * boost power setting for high device temperatures (higher than would be + * present during factory calibration). A 5 Ghz EEPROM index of "40" + * corresponds to the 49th entry in the table used by the driver. + */ +#define MIN_TX_GAIN_INDEX (0) /* highest gain, lowest idx, 2.4 */ +#define MIN_TX_GAIN_INDEX_52GHZ_EXT (-9) /* highest gain, lowest idx, 5 */ + +/** + * 2.4 GHz gain table + * + * Index Dsp gain Radio gain + * 0 110 0x3f (highest gain) + * 1 104 0x3f + * 2 98 0x3f + * 3 110 0x3e + * 4 104 0x3e + * 5 98 0x3e + * 6 110 0x3d + * 7 104 0x3d + * 8 98 0x3d + * 9 110 0x3c + * 10 104 0x3c + * 11 98 0x3c + * 12 110 0x3b + * 13 104 0x3b + * 14 98 0x3b + * 15 110 0x3a + * 16 104 0x3a + * 17 98 0x3a + * 18 110 0x39 + * 19 104 0x39 + * 20 98 0x39 + * 21 110 0x38 + * 22 104 0x38 + * 23 98 0x38 + * 24 110 0x37 + * 25 104 0x37 + * 26 98 0x37 + * 27 110 0x36 + * 28 104 0x36 + * 29 98 0x36 + * 30 110 0x35 + * 31 104 0x35 + * 32 98 0x35 + * 33 110 0x34 + * 34 104 0x34 + * 35 98 0x34 + * 36 110 0x33 + * 37 104 0x33 + * 38 98 0x33 + * 39 110 0x32 + * 40 104 0x32 + * 41 98 0x32 + * 42 110 0x31 + * 43 104 0x31 + * 44 98 0x31 + * 45 110 0x30 + * 46 104 0x30 + * 47 98 0x30 + * 48 110 0x6 + * 49 104 0x6 + * 50 98 0x6 + * 51 110 0x5 + * 52 104 0x5 + * 53 98 0x5 + * 54 110 0x4 + * 55 104 0x4 + * 56 98 0x4 + * 57 110 0x3 + * 58 104 0x3 + * 59 98 0x3 + * 60 110 0x2 + * 61 104 0x2 + * 62 98 0x2 + * 63 110 0x1 + * 64 104 0x1 + * 65 98 0x1 + * 66 110 0x0 + * 67 104 0x0 + * 68 98 0x0 + * 69 97 0 + * 70 96 0 + * 71 95 0 + * 72 94 0 + * 73 93 0 + * 74 92 0 + * 75 91 0 + * 76 90 0 + * 77 89 0 + * 78 88 0 + * 79 87 0 + * 80 86 0 + * 81 85 0 + * 82 84 0 + * 83 83 0 + * 84 82 0 + * 85 81 0 + * 86 80 0 + * 87 79 0 + * 88 78 0 + * 89 77 0 + * 90 76 0 + * 91 75 0 + * 92 74 0 + * 93 73 0 + * 94 72 0 + * 95 71 0 + * 96 70 0 + * 97 69 0 + * 98 68 0 + */ + +/** + * 5 GHz gain table + * + * Index Dsp gain Radio gain + * -9 123 0x3F (highest gain) + * -8 117 0x3F + * -7 110 0x3F + * -6 104 0x3F + * -5 98 0x3F + * -4 110 0x3E + * -3 104 0x3E + * -2 98 0x3E + * -1 110 0x3D + * 0 104 0x3D + * 1 98 0x3D + * 2 110 0x3C + * 3 104 0x3C + * 4 98 0x3C + * 5 110 0x3B + * 6 104 0x3B + * 7 98 0x3B + * 8 110 0x3A + * 9 104 0x3A + * 10 98 0x3A + * 11 110 0x39 + * 12 104 0x39 + * 13 98 0x39 + * 14 110 0x38 + * 15 104 0x38 + * 16 98 0x38 + * 17 110 0x37 + * 18 104 0x37 + * 19 98 0x37 + * 20 110 0x36 + * 21 104 0x36 + * 22 98 0x36 + * 23 110 0x35 + * 24 104 0x35 + * 25 98 0x35 + * 26 110 0x34 + * 27 104 0x34 + * 28 98 0x34 + * 29 110 0x33 + * 30 104 0x33 + * 31 98 0x33 + * 32 110 0x32 + * 33 104 0x32 + * 34 98 0x32 + * 35 110 0x31 + * 36 104 0x31 + * 37 98 0x31 + * 38 110 0x30 + * 39 104 0x30 + * 40 98 0x30 + * 41 110 0x25 + * 42 104 0x25 + * 43 98 0x25 + * 44 110 0x24 + * 45 104 0x24 + * 46 98 0x24 + * 47 110 0x23 + * 48 104 0x23 + * 49 98 0x23 + * 50 110 0x22 + * 51 104 0x18 + * 52 98 0x18 + * 53 110 0x17 + * 54 104 0x17 + * 55 98 0x17 + * 56 110 0x16 + * 57 104 0x16 + * 58 98 0x16 + * 59 110 0x15 + * 60 104 0x15 + * 61 98 0x15 + * 62 110 0x14 + * 63 104 0x14 + * 64 98 0x14 + * 65 110 0x13 + * 66 104 0x13 + * 67 98 0x13 + * 68 110 0x12 + * 69 104 0x08 + * 70 98 0x08 + * 71 110 0x07 + * 72 104 0x07 + * 73 98 0x07 + * 74 110 0x06 + * 75 104 0x06 + * 76 98 0x06 + * 77 110 0x05 + * 78 104 0x05 + * 79 98 0x05 + * 80 110 0x04 + * 81 104 0x04 + * 82 98 0x04 + * 83 110 0x03 + * 84 104 0x03 + * 85 98 0x03 + * 86 110 0x02 + * 87 104 0x02 + * 88 98 0x02 + * 89 110 0x01 + * 90 104 0x01 + * 91 98 0x01 + * 92 110 0x00 + * 93 104 0x00 + * 94 98 0x00 + * 95 93 0x00 + * 96 88 0x00 + * 97 83 0x00 + * 98 78 0x00 + */ + + +/** + * Sanity checks and default values for EEPROM regulatory levels. + * If EEPROM values fall outside MIN/MAX range, use default values. + * + * Regulatory limits refer to the maximum average txpower allowed by + * regulatory agencies in the geographies in which the device is meant + * to be operated. These limits are SKU-specific (i.e. geography-specific), + * and channel-specific; each channel has an individual regulatory limit + * listed in the EEPROM. + * + * Units are in half-dBm (i.e. "34" means 17 dBm). + */ +#define IWL_TX_POWER_DEFAULT_REGULATORY_24 (34) +#define IWL_TX_POWER_DEFAULT_REGULATORY_52 (34) +#define IWL_TX_POWER_REGULATORY_MIN (0) +#define IWL_TX_POWER_REGULATORY_MAX (34) + +/** + * Sanity checks and default values for EEPROM saturation levels. + * If EEPROM values fall outside MIN/MAX range, use default values. + * + * Saturation is the highest level that the output power amplifier can produce + * without significant clipping distortion. This is a "peak" power level. + * Different types of modulation (i.e. various "rates", and OFDM vs. CCK) + * require differing amounts of backoff, relative to their average power output, + * in order to avoid clipping distortion. + * + * Driver must make sure that it is violating neither the saturation limit, + * nor the regulatory limit, when calculating Tx power settings for various + * rates. + * + * Units are in half-dBm (i.e. "38" means 19 dBm). + */ +#define IWL_TX_POWER_DEFAULT_SATURATION_24 (38) +#define IWL_TX_POWER_DEFAULT_SATURATION_52 (38) +#define IWL_TX_POWER_SATURATION_MIN (20) +#define IWL_TX_POWER_SATURATION_MAX (50) + +/** + * Channel groups used for Tx Attenuation calibration (MIMO tx channel balance) + * and thermal Txpower calibration. + * + * When calculating txpower, driver must compensate for current device + * temperature; higher temperature requires higher gain. Driver must calculate + * current temperature (see "4965 temperature calculation"), then compare vs. + * factory calibration temperature in EEPROM; if current temperature is higher + * than factory temperature, driver must *increase* gain by proportions shown + * in table below. If current temperature is lower than factory, driver must + * *decrease* gain. + * + * Different frequency ranges require different compensation, as shown below. + */ +/* Group 0, 5.2 GHz ch 34-43: 4.5 degrees per 1/2 dB. */ +#define CALIB_IWL_TX_ATTEN_GR1_FCH 34 +#define CALIB_IWL_TX_ATTEN_GR1_LCH 43 + +/* Group 1, 5.3 GHz ch 44-70: 4.0 degrees per 1/2 dB. */ +#define CALIB_IWL_TX_ATTEN_GR2_FCH 44 +#define CALIB_IWL_TX_ATTEN_GR2_LCH 70 + +/* Group 2, 5.5 GHz ch 71-124: 4.0 degrees per 1/2 dB. */ +#define CALIB_IWL_TX_ATTEN_GR3_FCH 71 +#define CALIB_IWL_TX_ATTEN_GR3_LCH 124 + +/* Group 3, 5.7 GHz ch 125-200: 4.0 degrees per 1/2 dB. */ +#define CALIB_IWL_TX_ATTEN_GR4_FCH 125 +#define CALIB_IWL_TX_ATTEN_GR4_LCH 200 + +/* Group 4, 2.4 GHz all channels: 3.5 degrees per 1/2 dB. */ +#define CALIB_IWL_TX_ATTEN_GR5_FCH 1 +#define CALIB_IWL_TX_ATTEN_GR5_LCH 20 + +enum { + CALIB_CH_GROUP_1 = 0, + CALIB_CH_GROUP_2 = 1, + CALIB_CH_GROUP_3 = 2, + CALIB_CH_GROUP_4 = 3, + CALIB_CH_GROUP_5 = 4, + CALIB_CH_GROUP_MAX +}; + +/********************* END TXPOWER *****************************************/ + + +/** + * Tx/Rx Queues + * + * Most communication between driver and 4965 is via queues of data buffers. + * For example, all commands that the driver issues to device's embedded + * controller (uCode) are via the command queue (one of the Tx queues). All + * uCode command responses/replies/notifications, including Rx frames, are + * conveyed from uCode to driver via the Rx queue. + * + * Most support for these queues, including handshake support, resides in + * structures in host DRAM, shared between the driver and the device. When + * allocating this memory, the driver must make sure that data written by + * the host CPU updates DRAM immediately (and does not get "stuck" in CPU's + * cache memory), so DRAM and cache are consistent, and the device can + * immediately see changes made by the driver. + * + * 4965 supports up to 16 DRAM-based Tx queues, and services these queues via + * up to 7 DMA channels (FIFOs). Each Tx queue is supported by a circular array + * in DRAM containing 256 Transmit Frame Descriptors (TFDs). + */ +#define IWL49_NUM_FIFOS 7 +#define IWL49_CMD_FIFO_NUM 4 +#define IWL49_NUM_QUEUES 16 +#define IWL49_NUM_AMPDU_QUEUES 8 + + +/** + * struct iwl4965_schedq_bc_tbl + * + * Byte Count table + * + * Each Tx queue uses a byte-count table containing 320 entries: + * one 16-bit entry for each of 256 TFDs, plus an additional 64 entries that + * duplicate the first 64 entries (to avoid wrap-around within a Tx window; + * max Tx window is 64 TFDs). + * + * When driver sets up a new TFD, it must also enter the total byte count + * of the frame to be transmitted into the corresponding entry in the byte + * count table for the chosen Tx queue. If the TFD index is 0-63, the driver + * must duplicate the byte count entry in corresponding index 256-319. + * + * padding puts each byte count table on a 1024-byte boundary; + * 4965 assumes tables are separated by 1024 bytes. + */ +struct iwl4965_scd_bc_tbl { + __le16 tfd_offset[TFD_QUEUE_BC_SIZE]; + u8 pad[1024 - (TFD_QUEUE_BC_SIZE) * sizeof(__le16)]; +} __packed; + + +#define IWL4965_RTC_INST_LOWER_BOUND (0x000000) + +/* RSSI to dBm */ +#define IWL4965_RSSI_OFFSET 44 + +/* PCI registers */ +#define PCI_CFG_RETRY_TIMEOUT 0x041 + +/* PCI register values */ +#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01 +#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02 + +#define IWL4965_DEFAULT_TX_RETRY 15 + +/* Limit range of txpower output target to be between these values */ +#define IWL4965_TX_POWER_TARGET_POWER_MIN (0) /* 0 dBm: 1 milliwatt */ + +/* EEPROM */ +#define IWL4965_FIRST_AMPDU_QUEUE 10 + + +#endif /* !__iwl_4965_hw_h__ */ diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-led.c b/drivers/net/wireless/iwlegacy/iwl-4965-led.c new file mode 100644 index 000000000000..26d324e30692 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-4965-led.c @@ -0,0 +1,74 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iwl-commands.h" +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-io.h" +#include "iwl-4965-led.h" + +/* Send led command */ +static int +iwl4965_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) +{ + struct iwl_host_cmd cmd = { + .id = REPLY_LEDS_CMD, + .len = sizeof(struct iwl_led_cmd), + .data = led_cmd, + .flags = CMD_ASYNC, + .callback = NULL, + }; + u32 reg; + + reg = iwl_read32(priv, CSR_LED_REG); + if (reg != (reg & CSR_LED_BSM_CTRL_MSK)) + iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK); + + return iwl_legacy_send_cmd(priv, &cmd); +} + +/* Set led register off */ +void iwl4965_led_enable(struct iwl_priv *priv) +{ + iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON); +} + +const struct iwl_led_ops iwl4965_led_ops = { + .cmd = iwl4965_send_led_cmd, +}; diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-led.h b/drivers/net/wireless/iwlegacy/iwl-4965-led.h new file mode 100644 index 000000000000..5ed3615fc338 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-4965-led.h @@ -0,0 +1,33 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#ifndef __iwl_4965_led_h__ +#define __iwl_4965_led_h__ + +extern const struct iwl_led_ops iwl4965_led_ops; +void iwl4965_led_enable(struct iwl_priv *priv); + +#endif /* __iwl_4965_led_h__ */ diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c new file mode 100644 index 000000000000..c1a24946715e --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c @@ -0,0 +1,1260 @@ +/****************************************************************************** + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ +#include +#include +#include +#include +#include + +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-io.h" +#include "iwl-helpers.h" +#include "iwl-4965-hw.h" +#include "iwl-4965.h" +#include "iwl-sta.h" + +void iwl4965_check_abort_status(struct iwl_priv *priv, + u8 frame_count, u32 status) +{ + if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) { + IWL_ERR(priv, "Tx flush command to flush out all frames\n"); + if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) + queue_work(priv->workqueue, &priv->tx_flush); + } +} + +/* + * EEPROM + */ +struct iwl_mod_params iwl4965_mod_params = { + .amsdu_size_8K = 1, + .restart_fw = 1, + /* the rest are 0 by default */ +}; + +void iwl4965_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) +{ + unsigned long flags; + int i; + spin_lock_irqsave(&rxq->lock, flags); + INIT_LIST_HEAD(&rxq->rx_free); + INIT_LIST_HEAD(&rxq->rx_used); + /* Fill the rx_used queue with _all_ of the Rx buffers */ + for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { + /* In the reset function, these buffers may have been allocated + * to an SKB, so we need to unmap and free potential storage */ + if (rxq->pool[i].page != NULL) { + pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, + PAGE_SIZE << priv->hw_params.rx_page_order, + PCI_DMA_FROMDEVICE); + __iwl_legacy_free_pages(priv, rxq->pool[i].page); + rxq->pool[i].page = NULL; + } + list_add_tail(&rxq->pool[i].list, &rxq->rx_used); + } + + for (i = 0; i < RX_QUEUE_SIZE; i++) + rxq->queue[i] = NULL; + + /* 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->write_actual = 0; + rxq->free_count = 0; + spin_unlock_irqrestore(&rxq->lock, flags); +} + +int iwl4965_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) +{ + u32 rb_size; + const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ + u32 rb_timeout = 0; + + if (priv->cfg->mod_params->amsdu_size_8K) + rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; + else + rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; + + /* Stop Rx DMA */ + iwl_legacy_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); + + /* Reset driver's Rx queue write index */ + iwl_legacy_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); + + /* Tell device where to find RBD circular buffer in DRAM */ + iwl_legacy_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG, + (u32)(rxq->bd_dma >> 8)); + + /* Tell device where in DRAM to update its Rx status */ + iwl_legacy_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, + rxq->rb_stts_dma >> 4); + + /* Enable Rx DMA + * Direct rx interrupts to hosts + * Rx buffer size 4 or 8k + * RB timeout 0x10 + * 256 RBDs + */ + iwl_legacy_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, + FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | + FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | + FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MSK | + rb_size| + (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| + (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); + + /* Set interrupt coalescing timer to default (2048 usecs) */ + iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); + + return 0; +} + +static void iwl4965_set_pwr_vmain(struct iwl_priv *priv) +{ +/* + * (for documentation purposes) + * to set power to V_AUX, do: + + if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) + iwl_legacy_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, + APMG_PS_CTRL_VAL_PWR_SRC_VAUX, + ~APMG_PS_CTRL_MSK_PWR_SRC); + */ + + iwl_legacy_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, + APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, + ~APMG_PS_CTRL_MSK_PWR_SRC); +} + +int iwl4965_hw_nic_init(struct iwl_priv *priv) +{ + unsigned long flags; + struct iwl_rx_queue *rxq = &priv->rxq; + int ret; + + /* nic_init */ + spin_lock_irqsave(&priv->lock, flags); + priv->cfg->ops->lib->apm_ops.init(priv); + + /* Set interrupt coalescing calibration timer to default (512 usecs) */ + iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF); + + spin_unlock_irqrestore(&priv->lock, flags); + + iwl4965_set_pwr_vmain(priv); + + priv->cfg->ops->lib->apm_ops.config(priv); + + /* Allocate the RX queue, or reset if it is already allocated */ + if (!rxq->bd) { + ret = iwl_legacy_rx_queue_alloc(priv); + if (ret) { + IWL_ERR(priv, "Unable to initialize Rx queue\n"); + return -ENOMEM; + } + } else + iwl4965_rx_queue_reset(priv, rxq); + + iwl4965_rx_replenish(priv); + + iwl4965_rx_init(priv, rxq); + + spin_lock_irqsave(&priv->lock, flags); + + rxq->need_update = 1; + iwl_legacy_rx_queue_update_write_ptr(priv, rxq); + + spin_unlock_irqrestore(&priv->lock, flags); + + /* Allocate or reset and init all Tx and Command queues */ + if (!priv->txq) { + ret = iwl4965_txq_ctx_alloc(priv); + if (ret) + return ret; + } else + iwl4965_txq_ctx_reset(priv); + + set_bit(STATUS_INIT, &priv->status); + + return 0; +} + +/** + * iwl4965_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr + */ +static inline __le32 iwl4965_dma_addr2rbd_ptr(struct iwl_priv *priv, + dma_addr_t dma_addr) +{ + return cpu_to_le32((u32)(dma_addr >> 8)); +} + +/** + * iwl4965_rx_queue_restock - refill RX queue from pre-allocated pool + * + * If there are slots in the RX queue that need to be restocked, + * and we have free pre-allocated buffers, fill the ranks as much + * as we can, pulling from rx_free. + * + * This moves the 'write' index forward to catch up with 'processed', and + * also updates the memory address in the firmware to reference the new + * target buffer. + */ +void iwl4965_rx_queue_restock(struct iwl_priv *priv) +{ + struct iwl_rx_queue *rxq = &priv->rxq; + struct list_head *element; + struct iwl_rx_mem_buffer *rxb; + unsigned long flags; + + spin_lock_irqsave(&rxq->lock, flags); + while ((iwl_legacy_rx_queue_space(rxq) > 0) && (rxq->free_count)) { + /* The overwritten rxb must be a used one */ + rxb = rxq->queue[rxq->write]; + BUG_ON(rxb && rxb->page); + + /* Get next free Rx buffer, remove from free list */ + element = rxq->rx_free.next; + rxb = list_entry(element, struct iwl_rx_mem_buffer, list); + list_del(element); + + /* Point to Rx buffer via next RBD in circular buffer */ + rxq->bd[rxq->write] = iwl4965_dma_addr2rbd_ptr(priv, + rxb->page_dma); + rxq->queue[rxq->write] = rxb; + rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; + rxq->free_count--; + } + spin_unlock_irqrestore(&rxq->lock, flags); + /* If the pre-allocated buffer pool is dropping low, schedule to + * refill it */ + if (rxq->free_count <= RX_LOW_WATERMARK) + queue_work(priv->workqueue, &priv->rx_replenish); + + + /* If we've added more space for the firmware to place data, tell it. + * Increment device's write pointer in multiples of 8. */ + if (rxq->write_actual != (rxq->write & ~0x7)) { + spin_lock_irqsave(&rxq->lock, flags); + rxq->need_update = 1; + spin_unlock_irqrestore(&rxq->lock, flags); + iwl_legacy_rx_queue_update_write_ptr(priv, rxq); + } +} + +/** + * iwl4965_rx_replenish - Move all used packet from rx_used to rx_free + * + * When moving to rx_free an SKB is allocated for the slot. + * + * Also restock the Rx queue via iwl_rx_queue_restock. + * This is called as a scheduled work item (except for during initialization) + */ +static void iwl4965_rx_allocate(struct iwl_priv *priv, gfp_t priority) +{ + struct iwl_rx_queue *rxq = &priv->rxq; + struct list_head *element; + struct iwl_rx_mem_buffer *rxb; + struct page *page; + unsigned long flags; + gfp_t gfp_mask = priority; + + while (1) { + spin_lock_irqsave(&rxq->lock, flags); + if (list_empty(&rxq->rx_used)) { + spin_unlock_irqrestore(&rxq->lock, flags); + return; + } + spin_unlock_irqrestore(&rxq->lock, flags); + + if (rxq->free_count > RX_LOW_WATERMARK) + gfp_mask |= __GFP_NOWARN; + + if (priv->hw_params.rx_page_order > 0) + gfp_mask |= __GFP_COMP; + + /* Alloc a new receive buffer */ + page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order); + if (!page) { + if (net_ratelimit()) + IWL_DEBUG_INFO(priv, "alloc_pages failed, " + "order: %d\n", + priv->hw_params.rx_page_order); + + if ((rxq->free_count <= RX_LOW_WATERMARK) && + net_ratelimit()) + IWL_CRIT(priv, + "Failed to alloc_pages with %s. " + "Only %u free buffers remaining.\n", + priority == GFP_ATOMIC ? + "GFP_ATOMIC" : "GFP_KERNEL", + rxq->free_count); + /* We don't reschedule replenish work here -- we will + * call the restock method and if it still needs + * more buffers it will schedule replenish */ + return; + } + + spin_lock_irqsave(&rxq->lock, flags); + + if (list_empty(&rxq->rx_used)) { + spin_unlock_irqrestore(&rxq->lock, flags); + __free_pages(page, priv->hw_params.rx_page_order); + return; + } + element = rxq->rx_used.next; + rxb = list_entry(element, struct iwl_rx_mem_buffer, list); + list_del(element); + + spin_unlock_irqrestore(&rxq->lock, flags); + + BUG_ON(rxb->page); + rxb->page = page; + /* Get physical address of the RB */ + rxb->page_dma = pci_map_page(priv->pci_dev, page, 0, + PAGE_SIZE << priv->hw_params.rx_page_order, + PCI_DMA_FROMDEVICE); + /* dma address must be no more than 36 bits */ + BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); + /* and also 256 byte aligned! */ + BUG_ON(rxb->page_dma & DMA_BIT_MASK(8)); + + spin_lock_irqsave(&rxq->lock, flags); + + list_add_tail(&rxb->list, &rxq->rx_free); + rxq->free_count++; + priv->alloc_rxb_page++; + + spin_unlock_irqrestore(&rxq->lock, flags); + } +} + +void iwl4965_rx_replenish(struct iwl_priv *priv) +{ + unsigned long flags; + + iwl4965_rx_allocate(priv, GFP_KERNEL); + + spin_lock_irqsave(&priv->lock, flags); + iwl4965_rx_queue_restock(priv); + spin_unlock_irqrestore(&priv->lock, flags); +} + +void iwl4965_rx_replenish_now(struct iwl_priv *priv) +{ + iwl4965_rx_allocate(priv, GFP_ATOMIC); + + iwl4965_rx_queue_restock(priv); +} + +/* Assumes that the skb field of the buffers in 'pool' is kept accurate. + * If an SKB has been detached, the POOL needs to have its SKB set to NULL + * This free routine walks the list of POOL entries and if SKB is set to + * non NULL it is unmapped and freed + */ +void iwl4965_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) +{ + int i; + for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { + if (rxq->pool[i].page != NULL) { + pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, + PAGE_SIZE << priv->hw_params.rx_page_order, + PCI_DMA_FROMDEVICE); + __iwl_legacy_free_pages(priv, rxq->pool[i].page); + rxq->pool[i].page = NULL; + } + } + + dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, + rxq->bd_dma); + dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status), + rxq->rb_stts, rxq->rb_stts_dma); + rxq->bd = NULL; + rxq->rb_stts = NULL; +} + +int iwl4965_rxq_stop(struct iwl_priv *priv) +{ + + /* stop Rx DMA */ + iwl_legacy_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); + iwl_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG, + FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); + + return 0; +} + +int iwl4965_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band) +{ + int idx = 0; + int band_offset = 0; + + /* HT rate format: mac80211 wants an MCS number, which is just LSB */ + if (rate_n_flags & RATE_MCS_HT_MSK) { + idx = (rate_n_flags & 0xff); + return idx; + /* Legacy rate format, search for match in table */ + } else { + if (band == IEEE80211_BAND_5GHZ) + band_offset = IWL_FIRST_OFDM_RATE; + for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++) + if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF)) + return idx - band_offset; + } + + return -1; +} + +static int iwl4965_calc_rssi(struct iwl_priv *priv, + struct iwl_rx_phy_res *rx_resp) +{ + /* data from PHY/DSP regarding signal strength, etc., + * contents are always there, not configurable by host. */ + struct iwl4965_rx_non_cfg_phy *ncphy = + (struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy_buf; + u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL49_AGC_DB_MASK) + >> IWL49_AGC_DB_POS; + + u32 valid_antennae = + (le16_to_cpu(rx_resp->phy_flags) & IWL49_RX_PHY_FLAGS_ANTENNAE_MASK) + >> IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET; + u8 max_rssi = 0; + u32 i; + + /* Find max rssi among 3 possible receivers. + * These values are measured by the digital signal processor (DSP). + * They should stay fairly constant even as the signal strength varies, + * if the radio's automatic gain control (AGC) is working right. + * AGC value (see below) will provide the "interesting" info. */ + for (i = 0; i < 3; i++) + if (valid_antennae & (1 << i)) + max_rssi = max(ncphy->rssi_info[i << 1], max_rssi); + + IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n", + ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4], + max_rssi, agc); + + /* dBm = max_rssi dB - agc dB - constant. + * Higher AGC (higher radio gain) means lower signal. */ + return max_rssi - agc - IWL4965_RSSI_OFFSET; +} + + +static u32 iwl4965_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) +{ + u32 decrypt_out = 0; + + if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) == + RX_RES_STATUS_STATION_FOUND) + decrypt_out |= (RX_RES_STATUS_STATION_FOUND | + RX_RES_STATUS_NO_STATION_INFO_MISMATCH); + + decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK); + + /* packet was not encrypted */ + if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) == + RX_RES_STATUS_SEC_TYPE_NONE) + return decrypt_out; + + /* packet was encrypted with unknown alg */ + if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) == + RX_RES_STATUS_SEC_TYPE_ERR) + return decrypt_out; + + /* decryption was not done in HW */ + if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) != + RX_MPDU_RES_STATUS_DEC_DONE_MSK) + return decrypt_out; + + switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) { + + case RX_RES_STATUS_SEC_TYPE_CCMP: + /* alg is CCM: check MIC only */ + if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK)) + /* Bad MIC */ + decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC; + else + decrypt_out |= RX_RES_STATUS_DECRYPT_OK; + + break; + + case RX_RES_STATUS_SEC_TYPE_TKIP: + if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) { + /* Bad TTAK */ + decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK; + break; + } + /* fall through if TTAK OK */ + default: + if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK)) + decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC; + else + decrypt_out |= RX_RES_STATUS_DECRYPT_OK; + break; + } + + IWL_DEBUG_RX(priv, "decrypt_in:0x%x decrypt_out = 0x%x\n", + decrypt_in, decrypt_out); + + return decrypt_out; +} + +static void iwl4965_pass_packet_to_mac80211(struct iwl_priv *priv, + struct ieee80211_hdr *hdr, + u16 len, + u32 ampdu_status, + struct iwl_rx_mem_buffer *rxb, + struct ieee80211_rx_status *stats) +{ + struct sk_buff *skb; + __le16 fc = hdr->frame_control; + + /* We only process data packets if the interface is open */ + if (unlikely(!priv->is_open)) { + IWL_DEBUG_DROP_LIMIT(priv, + "Dropping packet while interface is not open.\n"); + return; + } + + /* In case of HW accelerated crypto and bad decryption, drop */ + if (!priv->cfg->mod_params->sw_crypto && + iwl_legacy_set_decrypted_flag(priv, hdr, ampdu_status, stats)) + return; + + skb = dev_alloc_skb(128); + if (!skb) { + IWL_ERR(priv, "dev_alloc_skb failed\n"); + return; + } + + skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); + + iwl_legacy_update_stats(priv, false, fc, len); + memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); + + ieee80211_rx(priv->hw, skb); + priv->alloc_rxb_page--; + rxb->page = NULL; +} + +/* Called for REPLY_RX (legacy ABG frames), or + * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ +void iwl4965_rx_reply_rx(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct ieee80211_hdr *header; + struct ieee80211_rx_status rx_status; + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_rx_phy_res *phy_res; + __le32 rx_pkt_status; + struct iwl_rx_mpdu_res_start *amsdu; + u32 len; + u32 ampdu_status; + u32 rate_n_flags; + + /** + * REPLY_RX and REPLY_RX_MPDU_CMD are handled differently. + * REPLY_RX: physical layer info is in this buffer + * REPLY_RX_MPDU_CMD: physical layer info was sent in separate + * command and cached in priv->last_phy_res + * + * Here we set up local variables depending on which command is + * received. + */ + if (pkt->hdr.cmd == REPLY_RX) { + phy_res = (struct iwl_rx_phy_res *)pkt->u.raw; + header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res) + + phy_res->cfg_phy_cnt); + + len = le16_to_cpu(phy_res->byte_count); + rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) + + phy_res->cfg_phy_cnt + len); + ampdu_status = le32_to_cpu(rx_pkt_status); + } else { + if (!priv->_4965.last_phy_res_valid) { + IWL_ERR(priv, "MPDU frame without cached PHY data\n"); + return; + } + phy_res = &priv->_4965.last_phy_res; + amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw; + header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu)); + len = le16_to_cpu(amsdu->byte_count); + rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len); + ampdu_status = iwl4965_translate_rx_status(priv, + le32_to_cpu(rx_pkt_status)); + } + + if ((unlikely(phy_res->cfg_phy_cnt > 20))) { + IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n", + phy_res->cfg_phy_cnt); + return; + } + + if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) || + !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) { + IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n", + le32_to_cpu(rx_pkt_status)); + return; + } + + /* This will be used in several places later */ + rate_n_flags = le32_to_cpu(phy_res->rate_n_flags); + + /* rx_status carries information about the packet to mac80211 */ + rx_status.mactime = le64_to_cpu(phy_res->timestamp); + rx_status.freq = + ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel), + rx_status.band); + rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? + IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; + rx_status.rate_idx = + iwl4965_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band); + rx_status.flag = 0; + + /* TSF isn't reliable. In order to allow smooth user experience, + * this W/A doesn't propagate it to the mac80211 */ + /*rx_status.flag |= RX_FLAG_TSFT;*/ + + priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp); + + /* Find max signal strength (dBm) among 3 antenna/receiver chains */ + rx_status.signal = iwl4965_calc_rssi(priv, phy_res); + + iwl_legacy_dbg_log_rx_data_frame(priv, len, header); + IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n", + rx_status.signal, (unsigned long long)rx_status.mactime); + + /* + * "antenna number" + * + * It seems that the antenna field in the phy flags value + * is actually a bit field. This is undefined by radiotap, + * it wants an actual antenna number but I always get "7" + * for most legacy frames I receive indicating that the + * same frame was received on all three RX chains. + * + * I think this field should be removed in favor of a + * new 802.11n radiotap field "RX chains" that is defined + * as a bitmask. + */ + rx_status.antenna = + (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK) + >> RX_RES_PHY_FLAGS_ANTENNA_POS; + + /* set the preamble flag if appropriate */ + if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK) + rx_status.flag |= RX_FLAG_SHORTPRE; + + /* Set up the HT phy flags */ + if (rate_n_flags & RATE_MCS_HT_MSK) + rx_status.flag |= RX_FLAG_HT; + if (rate_n_flags & RATE_MCS_HT40_MSK) + rx_status.flag |= RX_FLAG_40MHZ; + if (rate_n_flags & RATE_MCS_SGI_MSK) + rx_status.flag |= RX_FLAG_SHORT_GI; + + iwl4965_pass_packet_to_mac80211(priv, header, len, ampdu_status, + rxb, &rx_status); +} + +/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). + * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ +void iwl4965_rx_reply_rx_phy(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + priv->_4965.last_phy_res_valid = true; + memcpy(&priv->_4965.last_phy_res, pkt->u.raw, + sizeof(struct iwl_rx_phy_res)); +} + +static int iwl4965_get_single_channel_for_scan(struct iwl_priv *priv, + struct ieee80211_vif *vif, + enum ieee80211_band band, + struct iwl_scan_channel *scan_ch) +{ + const struct ieee80211_supported_band *sband; + u16 passive_dwell = 0; + u16 active_dwell = 0; + int added = 0; + u16 channel = 0; + + sband = iwl_get_hw_mode(priv, band); + if (!sband) { + IWL_ERR(priv, "invalid band\n"); + return added; + } + + active_dwell = iwl_legacy_get_active_dwell_time(priv, band, 0); + passive_dwell = iwl_legacy_get_passive_dwell_time(priv, band, vif); + + if (passive_dwell <= active_dwell) + passive_dwell = active_dwell + 1; + + channel = iwl_legacy_get_single_channel_number(priv, band); + if (channel) { + scan_ch->channel = cpu_to_le16(channel); + scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; + scan_ch->active_dwell = cpu_to_le16(active_dwell); + scan_ch->passive_dwell = cpu_to_le16(passive_dwell); + /* Set txpower levels to defaults */ + scan_ch->dsp_atten = 110; + if (band == IEEE80211_BAND_5GHZ) + scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; + else + scan_ch->tx_gain = ((1 << 5) | (5 << 3)); + added++; + } else + IWL_ERR(priv, "no valid channel found\n"); + return added; +} + +static int iwl4965_get_channels_for_scan(struct iwl_priv *priv, + struct ieee80211_vif *vif, + enum ieee80211_band band, + u8 is_active, u8 n_probes, + struct iwl_scan_channel *scan_ch) +{ + struct ieee80211_channel *chan; + const struct ieee80211_supported_band *sband; + const struct iwl_channel_info *ch_info; + u16 passive_dwell = 0; + u16 active_dwell = 0; + int added, i; + u16 channel; + + sband = iwl_get_hw_mode(priv, band); + if (!sband) + return 0; + + active_dwell = iwl_legacy_get_active_dwell_time(priv, band, n_probes); + passive_dwell = iwl_legacy_get_passive_dwell_time(priv, band, vif); + + if (passive_dwell <= active_dwell) + passive_dwell = active_dwell + 1; + + for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) { + chan = priv->scan_request->channels[i]; + + if (chan->band != band) + continue; + + channel = chan->hw_value; + scan_ch->channel = cpu_to_le16(channel); + + ch_info = iwl_legacy_get_channel_info(priv, band, channel); + if (!iwl_legacy_is_channel_valid(ch_info)) { + IWL_DEBUG_SCAN(priv, + "Channel %d is INVALID for this band.\n", + channel); + continue; + } + + if (!is_active || iwl_legacy_is_channel_passive(ch_info) || + (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) + scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; + else + scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; + + if (n_probes) + scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes); + + scan_ch->active_dwell = cpu_to_le16(active_dwell); + scan_ch->passive_dwell = cpu_to_le16(passive_dwell); + + /* Set txpower levels to defaults */ + scan_ch->dsp_atten = 110; + + /* NOTE: if we were doing 6Mb OFDM for scans we'd use + * power level: + * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3; + */ + if (band == IEEE80211_BAND_5GHZ) + scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; + else + scan_ch->tx_gain = ((1 << 5) | (5 << 3)); + + IWL_DEBUG_SCAN(priv, "Scanning ch=%d prob=0x%X [%s %d]\n", + channel, le32_to_cpu(scan_ch->type), + (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ? + "ACTIVE" : "PASSIVE", + (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ? + active_dwell : passive_dwell); + + scan_ch++; + added++; + } + + IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added); + return added; +} + +int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) +{ + struct iwl_host_cmd cmd = { + .id = REPLY_SCAN_CMD, + .len = sizeof(struct iwl_scan_cmd), + .flags = CMD_SIZE_HUGE, + }; + struct iwl_scan_cmd *scan; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + u32 rate_flags = 0; + u16 cmd_len; + u16 rx_chain = 0; + enum ieee80211_band band; + u8 n_probes = 0; + u8 rx_ant = priv->hw_params.valid_rx_ant; + u8 rate; + bool is_active = false; + int chan_mod; + u8 active_chains; + u8 scan_tx_antennas = priv->hw_params.valid_tx_ant; + int ret; + + lockdep_assert_held(&priv->mutex); + + if (vif) + ctx = iwl_legacy_rxon_ctx_from_vif(vif); + + if (!priv->scan_cmd) { + priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) + + IWL_MAX_SCAN_SIZE, GFP_KERNEL); + if (!priv->scan_cmd) { + IWL_DEBUG_SCAN(priv, + "fail to allocate memory for scan\n"); + return -ENOMEM; + } + } + scan = priv->scan_cmd; + memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE); + + scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; + scan->quiet_time = IWL_ACTIVE_QUIET_TIME; + + if (iwl_legacy_is_any_associated(priv)) { + u16 interval = 0; + u32 extra; + u32 suspend_time = 100; + u32 scan_suspend_time = 100; + + IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); + if (priv->is_internal_short_scan) + interval = 0; + else + interval = vif->bss_conf.beacon_int; + + scan->suspend_time = 0; + scan->max_out_time = cpu_to_le32(200 * 1024); + if (!interval) + interval = suspend_time; + + extra = (suspend_time / interval) << 22; + scan_suspend_time = (extra | + ((suspend_time % interval) * 1024)); + scan->suspend_time = cpu_to_le32(scan_suspend_time); + IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n", + scan_suspend_time, interval); + } + + if (priv->is_internal_short_scan) { + IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); + } else if (priv->scan_request->n_ssids) { + int i, p = 0; + IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); + for (i = 0; i < priv->scan_request->n_ssids; i++) { + /* always does wildcard anyway */ + if (!priv->scan_request->ssids[i].ssid_len) + continue; + scan->direct_scan[p].id = WLAN_EID_SSID; + scan->direct_scan[p].len = + priv->scan_request->ssids[i].ssid_len; + memcpy(scan->direct_scan[p].ssid, + priv->scan_request->ssids[i].ssid, + priv->scan_request->ssids[i].ssid_len); + n_probes++; + p++; + } + is_active = true; + } else + IWL_DEBUG_SCAN(priv, "Start passive scan.\n"); + + scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; + scan->tx_cmd.sta_id = ctx->bcast_sta_id; + scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; + + switch (priv->scan_band) { + case IEEE80211_BAND_2GHZ: + scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; + chan_mod = le32_to_cpu( + priv->contexts[IWL_RXON_CTX_BSS].active.flags & + RXON_FLG_CHANNEL_MODE_MSK) + >> RXON_FLG_CHANNEL_MODE_POS; + if (chan_mod == CHANNEL_MODE_PURE_40) { + rate = IWL_RATE_6M_PLCP; + } else { + rate = IWL_RATE_1M_PLCP; + rate_flags = RATE_MCS_CCK_MSK; + } + break; + case IEEE80211_BAND_5GHZ: + rate = IWL_RATE_6M_PLCP; + break; + default: + IWL_WARN(priv, "Invalid scan band\n"); + return -EIO; + } + + /* + * If active scanning is requested but a certain channel is + * marked passive, we can do active scanning if we detect + * transmissions. + * + * There is an issue with some firmware versions that triggers + * a sysassert on a "good CRC threshold" of zero (== disabled), + * on a radar channel even though this means that we should NOT + * send probes. + * + * The "good CRC threshold" is the number of frames that we + * need to receive during our dwell time on a channel before + * sending out probes -- setting this to a huge value will + * mean we never reach it, but at the same time work around + * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER + * here instead of IWL_GOOD_CRC_TH_DISABLED. + */ + scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : + IWL_GOOD_CRC_TH_NEVER; + + band = priv->scan_band; + + if (priv->cfg->scan_rx_antennas[band]) + rx_ant = priv->cfg->scan_rx_antennas[band]; + + if (priv->cfg->scan_tx_antennas[band]) + scan_tx_antennas = priv->cfg->scan_tx_antennas[band]; + + priv->scan_tx_ant[band] = iwl4965_toggle_tx_ant(priv, + priv->scan_tx_ant[band], + scan_tx_antennas); + rate_flags |= iwl4965_ant_idx_to_flags(priv->scan_tx_ant[band]); + scan->tx_cmd.rate_n_flags = iwl4965_hw_set_rate_n_flags(rate, rate_flags); + + /* In power save mode use one chain, otherwise use all chains */ + if (test_bit(STATUS_POWER_PMI, &priv->status)) { + /* rx_ant has been set to all valid chains previously */ + active_chains = rx_ant & + ((u8)(priv->chain_noise_data.active_chains)); + if (!active_chains) + active_chains = rx_ant; + + IWL_DEBUG_SCAN(priv, "chain_noise_data.active_chains: %u\n", + priv->chain_noise_data.active_chains); + + rx_ant = iwl4965_first_antenna(active_chains); + } + + /* MIMO is not used here, but value is required */ + rx_chain |= priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS; + rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; + rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; + rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; + scan->rx_chain = cpu_to_le16(rx_chain); + if (!priv->is_internal_short_scan) { + cmd_len = iwl_legacy_fill_probe_req(priv, + (struct ieee80211_mgmt *)scan->data, + vif->addr, + priv->scan_request->ie, + priv->scan_request->ie_len, + IWL_MAX_SCAN_SIZE - sizeof(*scan)); + } else { + /* use bcast addr, will not be transmitted but must be valid */ + cmd_len = iwl_legacy_fill_probe_req(priv, + (struct ieee80211_mgmt *)scan->data, + iwl_bcast_addr, NULL, 0, + IWL_MAX_SCAN_SIZE - sizeof(*scan)); + + } + scan->tx_cmd.len = cpu_to_le16(cmd_len); + + scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | + RXON_FILTER_BCON_AWARE_MSK); + + if (priv->is_internal_short_scan) { + scan->channel_count = + iwl4965_get_single_channel_for_scan(priv, vif, band, + (void *)&scan->data[le16_to_cpu( + scan->tx_cmd.len)]); + } else { + scan->channel_count = + iwl4965_get_channels_for_scan(priv, vif, band, + is_active, n_probes, + (void *)&scan->data[le16_to_cpu( + scan->tx_cmd.len)]); + } + if (scan->channel_count == 0) { + IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); + return -EIO; + } + + cmd.len += le16_to_cpu(scan->tx_cmd.len) + + scan->channel_count * sizeof(struct iwl_scan_channel); + cmd.data = scan; + scan->len = cpu_to_le16(cmd.len); + + set_bit(STATUS_SCAN_HW, &priv->status); + + ret = iwl_legacy_send_cmd_sync(priv, &cmd); + if (ret) + clear_bit(STATUS_SCAN_HW, &priv->status); + + return ret; +} + +int iwl4965_manage_ibss_station(struct iwl_priv *priv, + struct ieee80211_vif *vif, bool add) +{ + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; + + if (add) + return iwl4965_add_bssid_station(priv, vif_priv->ctx, + vif->bss_conf.bssid, + &vif_priv->ibss_bssid_sta_id); + return iwl_legacy_remove_station(priv, vif_priv->ibss_bssid_sta_id, + vif->bss_conf.bssid); +} + +void iwl4965_free_tfds_in_queue(struct iwl_priv *priv, + int sta_id, int tid, int freed) +{ + lockdep_assert_held(&priv->sta_lock); + + if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed) + priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; + else { + IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n", + priv->stations[sta_id].tid[tid].tfds_in_queue, + freed); + priv->stations[sta_id].tid[tid].tfds_in_queue = 0; + } +} + +#define IWL_TX_QUEUE_MSK 0xfffff + +static bool iwl4965_is_single_rx_stream(struct iwl_priv *priv) +{ + return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC || + priv->current_ht_config.single_chain_sufficient; +} + +#define IWL_NUM_RX_CHAINS_MULTIPLE 3 +#define IWL_NUM_RX_CHAINS_SINGLE 2 +#define IWL_NUM_IDLE_CHAINS_DUAL 2 +#define IWL_NUM_IDLE_CHAINS_SINGLE 1 + +/* + * Determine how many receiver/antenna chains to use. + * + * More provides better reception via diversity. Fewer saves power + * at the expense of throughput, but only when not in powersave to + * start with. + * + * MIMO (dual stream) requires at least 2, but works better with 3. + * This does not determine *which* chains to use, just how many. + */ +static int iwl4965_get_active_rx_chain_count(struct iwl_priv *priv) +{ + /* # of Rx chains to use when expecting MIMO. */ + if (iwl4965_is_single_rx_stream(priv)) + return IWL_NUM_RX_CHAINS_SINGLE; + else + return IWL_NUM_RX_CHAINS_MULTIPLE; +} + +/* + * When we are in power saving mode, unless device support spatial + * multiplexing power save, use the active count for rx chain count. + */ +static int +iwl4965_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt) +{ + /* # Rx chains when idling, depending on SMPS mode */ + switch (priv->current_ht_config.smps) { + case IEEE80211_SMPS_STATIC: + case IEEE80211_SMPS_DYNAMIC: + return IWL_NUM_IDLE_CHAINS_SINGLE; + case IEEE80211_SMPS_OFF: + return active_cnt; + default: + WARN(1, "invalid SMPS mode %d", + priv->current_ht_config.smps); + return active_cnt; + } +} + +/* up to 4 chains */ +static u8 iwl4965_count_chain_bitmap(u32 chain_bitmap) +{ + u8 res; + res = (chain_bitmap & BIT(0)) >> 0; + res += (chain_bitmap & BIT(1)) >> 1; + res += (chain_bitmap & BIT(2)) >> 2; + res += (chain_bitmap & BIT(3)) >> 3; + return res; +} + +/** + * iwl4965_set_rxon_chain - Set up Rx chain usage in "staging" RXON image + * + * Selects how many and which Rx receivers/antennas/chains to use. + * This should not be used for scan command ... it puts data in wrong place. + */ +void iwl4965_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +{ + bool is_single = iwl4965_is_single_rx_stream(priv); + bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); + u8 idle_rx_cnt, active_rx_cnt, valid_rx_cnt; + u32 active_chains; + u16 rx_chain; + + /* Tell uCode which antennas are actually connected. + * Before first association, we assume all antennas are connected. + * Just after first association, iwl4965_chain_noise_calibration() + * checks which antennas actually *are* connected. */ + if (priv->chain_noise_data.active_chains) + active_chains = priv->chain_noise_data.active_chains; + else + active_chains = priv->hw_params.valid_rx_ant; + + rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS; + + /* How many receivers should we use? */ + active_rx_cnt = iwl4965_get_active_rx_chain_count(priv); + idle_rx_cnt = iwl4965_get_idle_rx_chain_count(priv, active_rx_cnt); + + + /* correct rx chain count according hw settings + * and chain noise calibration + */ + valid_rx_cnt = iwl4965_count_chain_bitmap(active_chains); + if (valid_rx_cnt < active_rx_cnt) + active_rx_cnt = valid_rx_cnt; + + if (valid_rx_cnt < idle_rx_cnt) + idle_rx_cnt = valid_rx_cnt; + + rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS; + rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; + + ctx->staging.rx_chain = cpu_to_le16(rx_chain); + + if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam) + ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK; + else + ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; + + IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n", + ctx->staging.rx_chain, + active_rx_cnt, idle_rx_cnt); + + WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 || + active_rx_cnt < idle_rx_cnt); +} + +u8 iwl4965_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid) +{ + int i; + u8 ind = ant; + + for (i = 0; i < RATE_ANT_NUM - 1; i++) { + ind = (ind + 1) < RATE_ANT_NUM ? ind + 1 : 0; + if (valid & BIT(ind)) + return ind; + } + return ant; +} + +static const char *iwl4965_get_fh_string(int cmd) +{ + switch (cmd) { + IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG); + IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG); + IWL_CMD(FH_RSCSR_CHNL0_WPTR); + IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG); + IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG); + IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG); + IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV); + IWL_CMD(FH_TSSR_TX_STATUS_REG); + IWL_CMD(FH_TSSR_TX_ERROR_REG); + default: + return "UNKNOWN"; + } +} + +int iwl4965_dump_fh(struct iwl_priv *priv, char **buf, bool display) +{ + int i; +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + int pos = 0; + size_t bufsz = 0; +#endif + static const u32 fh_tbl[] = { + FH_RSCSR_CHNL0_STTS_WPTR_REG, + FH_RSCSR_CHNL0_RBDCB_BASE_REG, + FH_RSCSR_CHNL0_WPTR, + FH_MEM_RCSR_CHNL0_CONFIG_REG, + FH_MEM_RSSR_SHARED_CTRL_REG, + FH_MEM_RSSR_RX_STATUS_REG, + FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV, + FH_TSSR_TX_STATUS_REG, + FH_TSSR_TX_ERROR_REG + }; +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + if (display) { + bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; + *buf = kmalloc(bufsz, GFP_KERNEL); + if (!*buf) + return -ENOMEM; + pos += scnprintf(*buf + pos, bufsz - pos, + "FH register values:\n"); + for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { + pos += scnprintf(*buf + pos, bufsz - pos, + " %34s: 0X%08x\n", + iwl4965_get_fh_string(fh_tbl[i]), + iwl_legacy_read_direct32(priv, fh_tbl[i])); + } + return pos; + } +#endif + IWL_ERR(priv, "FH register values:\n"); + for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { + IWL_ERR(priv, " %34s: 0X%08x\n", + iwl4965_get_fh_string(fh_tbl[i]), + iwl_legacy_read_direct32(priv, fh_tbl[i])); + } + return 0; +} diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c new file mode 100644 index 000000000000..69abd2816f8d --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c @@ -0,0 +1,2870 @@ +/****************************************************************************** + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "iwl-dev.h" +#include "iwl-sta.h" +#include "iwl-core.h" +#include "iwl-4965.h" + +#define IWL4965_RS_NAME "iwl-4965-rs" + +#define NUM_TRY_BEFORE_ANT_TOGGLE 1 +#define IWL_NUMBER_TRY 1 +#define IWL_HT_NUMBER_TRY 3 + +#define IWL_RATE_MAX_WINDOW 62 /* # tx in history window */ +#define IWL_RATE_MIN_FAILURE_TH 6 /* min failures to calc tpt */ +#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */ + +/* max allowed rate miss before sync LQ cmd */ +#define IWL_MISSED_RATE_MAX 15 +/* max time to accum history 2 seconds */ +#define IWL_RATE_SCALE_FLUSH_INTVL (3*HZ) + +static u8 rs_ht_to_legacy[] = { + IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX, + IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX, + IWL_RATE_6M_INDEX, + IWL_RATE_6M_INDEX, IWL_RATE_9M_INDEX, + IWL_RATE_12M_INDEX, IWL_RATE_18M_INDEX, + IWL_RATE_24M_INDEX, IWL_RATE_36M_INDEX, + IWL_RATE_48M_INDEX, IWL_RATE_54M_INDEX +}; + +static const u8 ant_toggle_lookup[] = { + /*ANT_NONE -> */ ANT_NONE, + /*ANT_A -> */ ANT_B, + /*ANT_B -> */ ANT_C, + /*ANT_AB -> */ ANT_BC, + /*ANT_C -> */ ANT_A, + /*ANT_AC -> */ ANT_AB, + /*ANT_BC -> */ ANT_AC, + /*ANT_ABC -> */ ANT_ABC, +}; + +#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \ + [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ + IWL_RATE_SISO_##s##M_PLCP, \ + IWL_RATE_MIMO2_##s##M_PLCP,\ + IWL_RATE_##r##M_IEEE, \ + IWL_RATE_##ip##M_INDEX, \ + IWL_RATE_##in##M_INDEX, \ + IWL_RATE_##rp##M_INDEX, \ + IWL_RATE_##rn##M_INDEX, \ + IWL_RATE_##pp##M_INDEX, \ + IWL_RATE_##np##M_INDEX } + +/* + * Parameter order: + * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate + * + * If there isn't a valid next or previous rate then INV is used which + * maps to IWL_RATE_INVALID + * + */ +const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = { + IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2), /* 1mbps */ + IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5), /* 2mbps */ + IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11), /*5.5mbps */ + IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18), /* 11mbps */ + IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11), /* 6mbps */ + IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11), /* 9mbps */ + IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18), /* 12mbps */ + IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24), /* 18mbps */ + IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36), /* 24mbps */ + IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48), /* 36mbps */ + IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */ + IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */ + IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */ +}; + +static int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags) +{ + int idx = 0; + + /* HT rate format */ + if (rate_n_flags & RATE_MCS_HT_MSK) { + idx = (rate_n_flags & 0xff); + + if (idx >= IWL_RATE_MIMO2_6M_PLCP) + idx = idx - IWL_RATE_MIMO2_6M_PLCP; + + idx += IWL_FIRST_OFDM_RATE; + /* skip 9M not supported in ht*/ + if (idx >= IWL_RATE_9M_INDEX) + idx += 1; + if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE)) + return idx; + + /* legacy rate format, search for match in table */ + } else { + for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++) + if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF)) + return idx; + } + + return -1; +} + +static void iwl4965_rs_rate_scale_perform(struct iwl_priv *priv, + struct sk_buff *skb, + struct ieee80211_sta *sta, + struct iwl_lq_sta *lq_sta); +static void iwl4965_rs_fill_link_cmd(struct iwl_priv *priv, + struct iwl_lq_sta *lq_sta, u32 rate_n_flags); +static void iwl4965_rs_stay_in_table(struct iwl_lq_sta *lq_sta, + bool force_search); + +#ifdef CONFIG_MAC80211_DEBUGFS +static void iwl4965_rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, + u32 *rate_n_flags, int index); +#else +static void iwl4965_rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, + u32 *rate_n_flags, int index) +{} +#endif + +/** + * The following tables contain the expected throughput metrics for all rates + * + * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits + * + * where invalid entries are zeros. + * + * CCK rates are only valid in legacy table and will only be used in G + * (2.4 GHz) band. + */ + +static s32 expected_tpt_legacy[IWL_RATE_COUNT] = { + 7, 13, 35, 58, 40, 57, 72, 98, 121, 154, 177, 186, 0 +}; + +static s32 expected_tpt_siso20MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 42, 0, 76, 102, 124, 158, 183, 193, 202}, /* Norm */ + {0, 0, 0, 0, 46, 0, 82, 110, 132, 167, 192, 202, 210}, /* SGI */ + {0, 0, 0, 0, 48, 0, 93, 135, 176, 251, 319, 351, 381}, /* AGG */ + {0, 0, 0, 0, 53, 0, 102, 149, 193, 275, 348, 381, 413}, /* AGG+SGI */ +}; + +static s32 expected_tpt_siso40MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 77, 0, 127, 160, 184, 220, 242, 250, 257}, /* Norm */ + {0, 0, 0, 0, 83, 0, 135, 169, 193, 229, 250, 257, 264}, /* SGI */ + {0, 0, 0, 0, 96, 0, 182, 259, 328, 451, 553, 598, 640}, /* AGG */ + {0, 0, 0, 0, 106, 0, 199, 282, 357, 487, 593, 640, 683}, /* AGG+SGI */ +}; + +static s32 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 74, 0, 123, 155, 179, 213, 235, 243, 250}, /* Norm */ + {0, 0, 0, 0, 81, 0, 131, 164, 187, 221, 242, 250, 256}, /* SGI */ + {0, 0, 0, 0, 92, 0, 175, 250, 317, 436, 534, 578, 619}, /* AGG */ + {0, 0, 0, 0, 102, 0, 192, 273, 344, 470, 573, 619, 660}, /* AGG+SGI*/ +}; + +static s32 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 123, 0, 182, 214, 235, 264, 279, 285, 289}, /* Norm */ + {0, 0, 0, 0, 131, 0, 191, 222, 242, 270, 284, 289, 293}, /* SGI */ + {0, 0, 0, 0, 180, 0, 327, 446, 545, 708, 828, 878, 922}, /* AGG */ + {0, 0, 0, 0, 197, 0, 355, 481, 584, 752, 872, 922, 966}, /* AGG+SGI */ +}; + +/* mbps, mcs */ +static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = { + { "1", "BPSK DSSS"}, + { "2", "QPSK DSSS"}, + {"5.5", "BPSK CCK"}, + { "11", "QPSK CCK"}, + { "6", "BPSK 1/2"}, + { "9", "BPSK 1/2"}, + { "12", "QPSK 1/2"}, + { "18", "QPSK 3/4"}, + { "24", "16QAM 1/2"}, + { "36", "16QAM 3/4"}, + { "48", "64QAM 2/3"}, + { "54", "64QAM 3/4"}, + { "60", "64QAM 5/6"}, +}; + +#define MCS_INDEX_PER_STREAM (8) + +static inline u8 iwl4965_rs_extract_rate(u32 rate_n_flags) +{ + return (u8)(rate_n_flags & 0xFF); +} + +static void +iwl4965_rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) +{ + window->data = 0; + window->success_counter = 0; + window->success_ratio = IWL_INVALID_VALUE; + window->counter = 0; + window->average_tpt = IWL_INVALID_VALUE; + window->stamp = 0; +} + +static inline u8 iwl4965_rs_is_valid_ant(u8 valid_antenna, u8 ant_type) +{ + return (ant_type & valid_antenna) == ant_type; +} + +/* + * removes the old data from the statistics. All data that is older than + * TID_MAX_TIME_DIFF, will be deleted. + */ +static void +iwl4965_rs_tl_rm_old_stats(struct iwl_traffic_load *tl, u32 curr_time) +{ + /* The oldest age we want to keep */ + u32 oldest_time = curr_time - TID_MAX_TIME_DIFF; + + while (tl->queue_count && + (tl->time_stamp < oldest_time)) { + tl->total -= tl->packet_count[tl->head]; + tl->packet_count[tl->head] = 0; + tl->time_stamp += TID_QUEUE_CELL_SPACING; + tl->queue_count--; + tl->head++; + if (tl->head >= TID_QUEUE_MAX_SIZE) + tl->head = 0; + } +} + +/* + * increment traffic load value for tid and also remove + * any old values if passed the certain time period + */ +static u8 iwl4965_rs_tl_add_packet(struct iwl_lq_sta *lq_data, + struct ieee80211_hdr *hdr) +{ + u32 curr_time = jiffies_to_msecs(jiffies); + u32 time_diff; + s32 index; + struct iwl_traffic_load *tl = NULL; + u8 tid; + + if (ieee80211_is_data_qos(hdr->frame_control)) { + u8 *qc = ieee80211_get_qos_ctl(hdr); + tid = qc[0] & 0xf; + } else + return MAX_TID_COUNT; + + if (unlikely(tid >= TID_MAX_LOAD_COUNT)) + return MAX_TID_COUNT; + + tl = &lq_data->load[tid]; + + curr_time -= curr_time % TID_ROUND_VALUE; + + /* Happens only for the first packet. Initialize the data */ + if (!(tl->queue_count)) { + tl->total = 1; + tl->time_stamp = curr_time; + tl->queue_count = 1; + tl->head = 0; + tl->packet_count[0] = 1; + return MAX_TID_COUNT; + } + + time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); + index = time_diff / TID_QUEUE_CELL_SPACING; + + /* The history is too long: remove data that is older than */ + /* TID_MAX_TIME_DIFF */ + if (index >= TID_QUEUE_MAX_SIZE) + iwl4965_rs_tl_rm_old_stats(tl, curr_time); + + index = (tl->head + index) % TID_QUEUE_MAX_SIZE; + tl->packet_count[index] = tl->packet_count[index] + 1; + tl->total = tl->total + 1; + + if ((index + 1) > tl->queue_count) + tl->queue_count = index + 1; + + return tid; +} + +/* + get the traffic load value for tid +*/ +static u32 iwl4965_rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid) +{ + u32 curr_time = jiffies_to_msecs(jiffies); + u32 time_diff; + s32 index; + struct iwl_traffic_load *tl = NULL; + + if (tid >= TID_MAX_LOAD_COUNT) + return 0; + + tl = &(lq_data->load[tid]); + + curr_time -= curr_time % TID_ROUND_VALUE; + + if (!(tl->queue_count)) + return 0; + + time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); + index = time_diff / TID_QUEUE_CELL_SPACING; + + /* The history is too long: remove data that is older than */ + /* TID_MAX_TIME_DIFF */ + if (index >= TID_QUEUE_MAX_SIZE) + iwl4965_rs_tl_rm_old_stats(tl, curr_time); + + return tl->total; +} + +static int iwl4965_rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, + struct iwl_lq_sta *lq_data, u8 tid, + struct ieee80211_sta *sta) +{ + int ret = -EAGAIN; + u32 load; + + load = iwl4965_rs_tl_get_load(lq_data, tid); + + if (load > IWL_AGG_LOAD_THRESHOLD) { + IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", + sta->addr, tid); + ret = ieee80211_start_tx_ba_session(sta, tid, 5000); + if (ret == -EAGAIN) { + /* + * driver and mac80211 is out of sync + * this might be cause by reloading firmware + * stop the tx ba session here + */ + IWL_ERR(priv, "Fail start Tx agg on tid: %d\n", + tid); + ieee80211_stop_tx_ba_session(sta, tid); + } + } else { + IWL_ERR(priv, "Aggregation not enabled for tid %d " + "because load = %u\n", tid, load); + } + return ret; +} + +static void iwl4965_rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid, + struct iwl_lq_sta *lq_data, + struct ieee80211_sta *sta) +{ + if (tid < TID_MAX_LOAD_COUNT) + iwl4965_rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); + else + IWL_ERR(priv, "tid exceeds max load count: %d/%d\n", + tid, TID_MAX_LOAD_COUNT); +} + +static inline int iwl4965_get_iwl4965_num_of_ant_from_rate(u32 rate_n_flags) +{ + return !!(rate_n_flags & RATE_MCS_ANT_A_MSK) + + !!(rate_n_flags & RATE_MCS_ANT_B_MSK) + + !!(rate_n_flags & RATE_MCS_ANT_C_MSK); +} + +/* + * Static function to get the expected throughput from an iwl_scale_tbl_info + * that wraps a NULL pointer check + */ +static s32 +iwl4965_get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index) +{ + if (tbl->expected_tpt) + return tbl->expected_tpt[rs_index]; + return 0; +} + +/** + * iwl4965_rs_collect_tx_data - Update the success/failure sliding window + * + * We keep a sliding window of the last 62 packets transmitted + * at this rate. window->data contains the bitmask of successful + * packets. + */ +static int iwl4965_rs_collect_tx_data(struct iwl_scale_tbl_info *tbl, + int scale_index, int attempts, int successes) +{ + struct iwl_rate_scale_data *window = NULL; + static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1)); + s32 fail_count, tpt; + + if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) + return -EINVAL; + + /* Select window for current tx bit rate */ + window = &(tbl->win[scale_index]); + + /* Get expected throughput */ + tpt = iwl4965_get_expected_tpt(tbl, scale_index); + + /* + * Keep track of only the latest 62 tx frame attempts in this rate's + * history window; anything older isn't really relevant any more. + * If we have filled up the sliding window, drop the oldest attempt; + * if the oldest attempt (highest bit in bitmap) shows "success", + * subtract "1" from the success counter (this is the main reason + * we keep these bitmaps!). + */ + while (attempts > 0) { + if (window->counter >= IWL_RATE_MAX_WINDOW) { + + /* remove earliest */ + window->counter = IWL_RATE_MAX_WINDOW - 1; + + if (window->data & mask) { + window->data &= ~mask; + window->success_counter--; + } + } + + /* Increment frames-attempted counter */ + window->counter++; + + /* Shift bitmap by one frame to throw away oldest history */ + window->data <<= 1; + + /* Mark the most recent #successes attempts as successful */ + if (successes > 0) { + window->success_counter++; + window->data |= 0x1; + successes--; + } + + attempts--; + } + + /* Calculate current success ratio, avoid divide-by-0! */ + if (window->counter > 0) + window->success_ratio = 128 * (100 * window->success_counter) + / window->counter; + else + window->success_ratio = IWL_INVALID_VALUE; + + fail_count = window->counter - window->success_counter; + + /* Calculate average throughput, if we have enough history. */ + if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) || + (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH)) + window->average_tpt = (window->success_ratio * tpt + 64) / 128; + else + window->average_tpt = IWL_INVALID_VALUE; + + /* Tag this window as having been updated */ + window->stamp = jiffies; + + return 0; +} + +/* + * Fill uCode API rate_n_flags field, based on "search" or "active" table. + */ +static u32 iwl4965_rate_n_flags_from_tbl(struct iwl_priv *priv, + struct iwl_scale_tbl_info *tbl, + int index, u8 use_green) +{ + u32 rate_n_flags = 0; + + if (is_legacy(tbl->lq_type)) { + rate_n_flags = iwl_rates[index].plcp; + if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE) + rate_n_flags |= RATE_MCS_CCK_MSK; + + } else if (is_Ht(tbl->lq_type)) { + if (index > IWL_LAST_OFDM_RATE) { + IWL_ERR(priv, "Invalid HT rate index %d\n", index); + index = IWL_LAST_OFDM_RATE; + } + rate_n_flags = RATE_MCS_HT_MSK; + + if (is_siso(tbl->lq_type)) + rate_n_flags |= iwl_rates[index].plcp_siso; + else + rate_n_flags |= iwl_rates[index].plcp_mimo2; + } else { + IWL_ERR(priv, "Invalid tbl->lq_type %d\n", tbl->lq_type); + } + + rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) & + RATE_MCS_ANT_ABC_MSK); + + if (is_Ht(tbl->lq_type)) { + if (tbl->is_ht40) { + if (tbl->is_dup) + rate_n_flags |= RATE_MCS_DUP_MSK; + else + rate_n_flags |= RATE_MCS_HT40_MSK; + } + if (tbl->is_SGI) + rate_n_flags |= RATE_MCS_SGI_MSK; + + if (use_green) { + rate_n_flags |= RATE_MCS_GF_MSK; + if (is_siso(tbl->lq_type) && tbl->is_SGI) { + rate_n_flags &= ~RATE_MCS_SGI_MSK; + IWL_ERR(priv, "GF was set with SGI:SISO\n"); + } + } + } + return rate_n_flags; +} + +/* + * Interpret uCode API's rate_n_flags format, + * fill "search" or "active" tx mode table. + */ +static int iwl4965_rs_get_tbl_info_from_mcs(const u32 rate_n_flags, + enum ieee80211_band band, + struct iwl_scale_tbl_info *tbl, + int *rate_idx) +{ + u32 ant_msk = (rate_n_flags & RATE_MCS_ANT_ABC_MSK); + u8 iwl4965_num_of_ant = iwl4965_get_iwl4965_num_of_ant_from_rate(rate_n_flags); + u8 mcs; + + memset(tbl, 0, sizeof(struct iwl_scale_tbl_info)); + *rate_idx = iwl4965_hwrate_to_plcp_idx(rate_n_flags); + + if (*rate_idx == IWL_RATE_INVALID) { + *rate_idx = -1; + return -EINVAL; + } + tbl->is_SGI = 0; /* default legacy setup */ + tbl->is_ht40 = 0; + tbl->is_dup = 0; + tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS); + tbl->lq_type = LQ_NONE; + tbl->max_search = IWL_MAX_SEARCH; + + /* legacy rate format */ + if (!(rate_n_flags & RATE_MCS_HT_MSK)) { + if (iwl4965_num_of_ant == 1) { + if (band == IEEE80211_BAND_5GHZ) + tbl->lq_type = LQ_A; + else + tbl->lq_type = LQ_G; + } + /* HT rate format */ + } else { + if (rate_n_flags & RATE_MCS_SGI_MSK) + tbl->is_SGI = 1; + + if ((rate_n_flags & RATE_MCS_HT40_MSK) || + (rate_n_flags & RATE_MCS_DUP_MSK)) + tbl->is_ht40 = 1; + + if (rate_n_flags & RATE_MCS_DUP_MSK) + tbl->is_dup = 1; + + mcs = iwl4965_rs_extract_rate(rate_n_flags); + + /* SISO */ + if (mcs <= IWL_RATE_SISO_60M_PLCP) { + if (iwl4965_num_of_ant == 1) + tbl->lq_type = LQ_SISO; /*else NONE*/ + /* MIMO2 */ + } else { + if (iwl4965_num_of_ant == 2) + tbl->lq_type = LQ_MIMO2; + } + } + return 0; +} + +/* switch to another antenna/antennas and return 1 */ +/* if no other valid antenna found, return 0 */ +static int iwl4965_rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, + struct iwl_scale_tbl_info *tbl) +{ + u8 new_ant_type; + + if (!tbl->ant_type || tbl->ant_type > ANT_ABC) + return 0; + + if (!iwl4965_rs_is_valid_ant(valid_ant, tbl->ant_type)) + return 0; + + new_ant_type = ant_toggle_lookup[tbl->ant_type]; + + while ((new_ant_type != tbl->ant_type) && + !iwl4965_rs_is_valid_ant(valid_ant, new_ant_type)) + new_ant_type = ant_toggle_lookup[new_ant_type]; + + if (new_ant_type == tbl->ant_type) + return 0; + + tbl->ant_type = new_ant_type; + *rate_n_flags &= ~RATE_MCS_ANT_ABC_MSK; + *rate_n_flags |= new_ant_type << RATE_MCS_ANT_POS; + return 1; +} + +/** + * Green-field mode is valid if the station supports it and + * there are no non-GF stations present in the BSS. + */ +static bool iwl4965_rs_use_green(struct ieee80211_sta *sta) +{ + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_rxon_context *ctx = sta_priv->common.ctx; + + return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && + !(ctx->ht.non_gf_sta_present); +} + +/** + * iwl4965_rs_get_supported_rates - get the available rates + * + * if management frame or broadcast frame only return + * basic available rates. + * + */ +static u16 iwl4965_rs_get_supported_rates(struct iwl_lq_sta *lq_sta, + struct ieee80211_hdr *hdr, + enum iwl_table_type rate_type) +{ + if (is_legacy(rate_type)) { + return lq_sta->active_legacy_rate; + } else { + if (is_siso(rate_type)) + return lq_sta->active_siso_rate; + else + return lq_sta->active_mimo2_rate; + } +} + +static u16 +iwl4965_rs_get_adjacent_rate(struct iwl_priv *priv, u8 index, u16 rate_mask, + int rate_type) +{ + u8 high = IWL_RATE_INVALID; + u8 low = IWL_RATE_INVALID; + + /* 802.11A or ht walks to the next literal adjacent rate in + * the rate table */ + if (is_a_band(rate_type) || !is_legacy(rate_type)) { + int i; + u32 mask; + + /* Find the previous rate that is in the rate mask */ + i = index - 1; + for (mask = (1 << i); i >= 0; i--, mask >>= 1) { + if (rate_mask & mask) { + low = i; + break; + } + } + + /* Find the next rate that is in the rate mask */ + i = index + 1; + for (mask = (1 << i); i < IWL_RATE_COUNT; i++, mask <<= 1) { + if (rate_mask & mask) { + high = i; + break; + } + } + + return (high << 8) | low; + } + + low = index; + while (low != IWL_RATE_INVALID) { + low = iwl_rates[low].prev_rs; + if (low == IWL_RATE_INVALID) + break; + if (rate_mask & (1 << low)) + break; + IWL_DEBUG_RATE(priv, "Skipping masked lower rate: %d\n", low); + } + + high = index; + while (high != IWL_RATE_INVALID) { + high = iwl_rates[high].next_rs; + if (high == IWL_RATE_INVALID) + break; + if (rate_mask & (1 << high)) + break; + IWL_DEBUG_RATE(priv, "Skipping masked higher rate: %d\n", high); + } + + return (high << 8) | low; +} + +static u32 iwl4965_rs_get_lower_rate(struct iwl_lq_sta *lq_sta, + struct iwl_scale_tbl_info *tbl, + u8 scale_index, u8 ht_possible) +{ + s32 low; + u16 rate_mask; + u16 high_low; + u8 switch_to_legacy = 0; + u8 is_green = lq_sta->is_green; + struct iwl_priv *priv = lq_sta->drv; + + /* check if we need to switch from HT to legacy rates. + * assumption is that mandatory rates (1Mbps or 6Mbps) + * are always supported (spec demand) */ + if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) { + switch_to_legacy = 1; + scale_index = rs_ht_to_legacy[scale_index]; + if (lq_sta->band == IEEE80211_BAND_5GHZ) + tbl->lq_type = LQ_A; + else + tbl->lq_type = LQ_G; + + if (iwl4965_num_of_ant(tbl->ant_type) > 1) + tbl->ant_type = + iwl4965_first_antenna(priv->hw_params.valid_tx_ant); + + tbl->is_ht40 = 0; + tbl->is_SGI = 0; + tbl->max_search = IWL_MAX_SEARCH; + } + + rate_mask = iwl4965_rs_get_supported_rates(lq_sta, NULL, tbl->lq_type); + + /* Mask with station rate restriction */ + if (is_legacy(tbl->lq_type)) { + /* supp_rates has no CCK bits in A mode */ + if (lq_sta->band == IEEE80211_BAND_5GHZ) + rate_mask = (u16)(rate_mask & + (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); + else + rate_mask = (u16)(rate_mask & lq_sta->supp_rates); + } + + /* If we switched from HT to legacy, check current rate */ + if (switch_to_legacy && (rate_mask & (1 << scale_index))) { + low = scale_index; + goto out; + } + + high_low = iwl4965_rs_get_adjacent_rate(lq_sta->drv, + scale_index, rate_mask, + tbl->lq_type); + low = high_low & 0xff; + + if (low == IWL_RATE_INVALID) + low = scale_index; + +out: + return iwl4965_rate_n_flags_from_tbl(lq_sta->drv, tbl, low, is_green); +} + +/* + * Simple function to compare two rate scale table types + */ +static bool iwl4965_table_type_matches(struct iwl_scale_tbl_info *a, + struct iwl_scale_tbl_info *b) +{ + return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) && + (a->is_SGI == b->is_SGI); +} + +/* + * mac80211 sends us Tx status + */ +static void +iwl4965_rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta, + struct sk_buff *skb) +{ + int legacy_success; + int retries; + int rs_index, mac_index, i; + struct iwl_lq_sta *lq_sta = priv_sta; + struct iwl_link_quality_cmd *table; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct iwl_priv *priv = (struct iwl_priv *)priv_r; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + enum mac80211_rate_control_flags mac_flags; + u32 tx_rate; + struct iwl_scale_tbl_info tbl_type; + struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_rxon_context *ctx = sta_priv->common.ctx; + + IWL_DEBUG_RATE_LIMIT(priv, + "get frame ack response, update rate scale window\n"); + + /* Treat uninitialized rate scaling data same as non-existing. */ + if (!lq_sta) { + IWL_DEBUG_RATE(priv, "Station rate scaling not created yet.\n"); + return; + } else if (!lq_sta->drv) { + IWL_DEBUG_RATE(priv, "Rate scaling not initialized yet.\n"); + return; + } + + if (!ieee80211_is_data(hdr->frame_control) || + info->flags & IEEE80211_TX_CTL_NO_ACK) + return; + + /* This packet was aggregated but doesn't carry status info */ + if ((info->flags & IEEE80211_TX_CTL_AMPDU) && + !(info->flags & IEEE80211_TX_STAT_AMPDU)) + return; + + /* + * Ignore this Tx frame response if its initial rate doesn't match + * that of latest Link Quality command. There may be stragglers + * from a previous Link Quality command, but we're no longer interested + * in those; they're either from the "active" mode while we're trying + * to check "search" mode, or a prior "search" mode after we've moved + * to a new "search" mode (which might become the new "active" mode). + */ + table = &lq_sta->lq; + tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags); + iwl4965_rs_get_tbl_info_from_mcs(tx_rate, + priv->band, &tbl_type, &rs_index); + if (priv->band == IEEE80211_BAND_5GHZ) + rs_index -= IWL_FIRST_OFDM_RATE; + mac_flags = info->status.rates[0].flags; + mac_index = info->status.rates[0].idx; + /* For HT packets, map MCS to PLCP */ + if (mac_flags & IEEE80211_TX_RC_MCS) { + mac_index &= RATE_MCS_CODE_MSK; /* Remove # of streams */ + if (mac_index >= (IWL_RATE_9M_INDEX - IWL_FIRST_OFDM_RATE)) + mac_index++; + /* + * mac80211 HT index is always zero-indexed; we need to move + * HT OFDM rates after CCK rates in 2.4 GHz band + */ + if (priv->band == IEEE80211_BAND_2GHZ) + mac_index += IWL_FIRST_OFDM_RATE; + } + /* Here we actually compare this rate to the latest LQ command */ + if ((mac_index < 0) || + (tbl_type.is_SGI != + !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) || + (tbl_type.is_ht40 != + !!(mac_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) || + (tbl_type.is_dup != + !!(mac_flags & IEEE80211_TX_RC_DUP_DATA)) || + (tbl_type.ant_type != info->antenna_sel_tx) || + (!!(tx_rate & RATE_MCS_HT_MSK) != + !!(mac_flags & IEEE80211_TX_RC_MCS)) || + (!!(tx_rate & RATE_MCS_GF_MSK) != + !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) || + (rs_index != mac_index)) { + IWL_DEBUG_RATE(priv, + "initial rate %d does not match %d (0x%x)\n", + mac_index, rs_index, tx_rate); + /* + * Since rates mis-match, the last LQ command may have failed. + * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with + * ... driver. + */ + lq_sta->missed_rate_counter++; + if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) { + lq_sta->missed_rate_counter = 0; + iwl_legacy_send_lq_cmd(priv, ctx, &lq_sta->lq, + CMD_ASYNC, false); + } + /* Regardless, ignore this status info for outdated rate */ + return; + } else + /* Rate did match, so reset the missed_rate_counter */ + lq_sta->missed_rate_counter = 0; + + /* Figure out if rate scale algorithm is in active or search table */ + if (iwl4965_table_type_matches(&tbl_type, + &(lq_sta->lq_info[lq_sta->active_tbl]))) { + curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); + other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); + } else if (iwl4965_table_type_matches(&tbl_type, + &lq_sta->lq_info[1 - lq_sta->active_tbl])) { + curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); + other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); + } else { + IWL_DEBUG_RATE(priv, + "Neither active nor search matches tx rate\n"); + tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); + IWL_DEBUG_RATE(priv, "active- lq:%x, ant:%x, SGI:%d\n", + tmp_tbl->lq_type, tmp_tbl->ant_type, tmp_tbl->is_SGI); + tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); + IWL_DEBUG_RATE(priv, "search- lq:%x, ant:%x, SGI:%d\n", + tmp_tbl->lq_type, tmp_tbl->ant_type, tmp_tbl->is_SGI); + IWL_DEBUG_RATE(priv, "actual- lq:%x, ant:%x, SGI:%d\n", + tbl_type.lq_type, tbl_type.ant_type, tbl_type.is_SGI); + /* + * no matching table found, let's by-pass the data collection + * and continue to perform rate scale to find the rate table + */ + iwl4965_rs_stay_in_table(lq_sta, true); + goto done; + } + + /* + * Updating the frame history depends on whether packets were + * aggregated. + * + * For aggregation, all packets were transmitted at the same rate, the + * first index into rate scale table. + */ + if (info->flags & IEEE80211_TX_STAT_AMPDU) { + tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags); + iwl4965_rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, + &rs_index); + iwl4965_rs_collect_tx_data(curr_tbl, rs_index, + info->status.ampdu_len, + info->status.ampdu_ack_len); + + /* Update success/fail counts if not searching for new mode */ + if (lq_sta->stay_in_tbl) { + lq_sta->total_success += info->status.ampdu_ack_len; + lq_sta->total_failed += (info->status.ampdu_len - + info->status.ampdu_ack_len); + } + } else { + /* + * For legacy, update frame history with for each Tx retry. + */ + retries = info->status.rates[0].count - 1; + /* HW doesn't send more than 15 retries */ + retries = min(retries, 15); + + /* The last transmission may have been successful */ + legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK); + /* Collect data for each rate used during failed TX attempts */ + for (i = 0; i <= retries; ++i) { + tx_rate = le32_to_cpu(table->rs_table[i].rate_n_flags); + iwl4965_rs_get_tbl_info_from_mcs(tx_rate, priv->band, + &tbl_type, &rs_index); + /* + * Only collect stats if retried rate is in the same RS + * table as active/search. + */ + if (iwl4965_table_type_matches(&tbl_type, curr_tbl)) + tmp_tbl = curr_tbl; + else if (iwl4965_table_type_matches(&tbl_type, + other_tbl)) + tmp_tbl = other_tbl; + else + continue; + iwl4965_rs_collect_tx_data(tmp_tbl, rs_index, 1, + i < retries ? 0 : legacy_success); + } + + /* Update success/fail counts if not searching for new mode */ + if (lq_sta->stay_in_tbl) { + lq_sta->total_success += legacy_success; + lq_sta->total_failed += retries + (1 - legacy_success); + } + } + /* The last TX rate is cached in lq_sta; it's set in if/else above */ + lq_sta->last_rate_n_flags = tx_rate; +done: + /* See if there's a better rate or modulation mode to try. */ + if (sta && sta->supp_rates[sband->band]) + iwl4965_rs_rate_scale_perform(priv, skb, sta, lq_sta); +} + +/* + * Begin a period of staying with a selected modulation mode. + * Set "stay_in_tbl" flag to prevent any mode switches. + * Set frame tx success limits according to legacy vs. high-throughput, + * and reset overall (spanning all rates) tx success history statistics. + * These control how long we stay using same modulation mode before + * searching for a new mode. + */ +static void iwl4965_rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy, + struct iwl_lq_sta *lq_sta) +{ + IWL_DEBUG_RATE(priv, "we are staying in the same table\n"); + lq_sta->stay_in_tbl = 1; /* only place this gets set */ + if (is_legacy) { + lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT; + lq_sta->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT; + lq_sta->max_success_limit = IWL_LEGACY_SUCCESS_LIMIT; + } else { + lq_sta->table_count_limit = IWL_NONE_LEGACY_TABLE_COUNT; + lq_sta->max_failure_limit = IWL_NONE_LEGACY_FAILURE_LIMIT; + lq_sta->max_success_limit = IWL_NONE_LEGACY_SUCCESS_LIMIT; + } + lq_sta->table_count = 0; + lq_sta->total_failed = 0; + lq_sta->total_success = 0; + lq_sta->flush_timer = jiffies; + lq_sta->action_counter = 0; +} + +/* + * Find correct throughput table for given mode of modulation + */ +static void iwl4965_rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta, + struct iwl_scale_tbl_info *tbl) +{ + /* Used to choose among HT tables */ + s32 (*ht_tbl_pointer)[IWL_RATE_COUNT]; + + /* Check for invalid LQ type */ + if (WARN_ON_ONCE(!is_legacy(tbl->lq_type) && !is_Ht(tbl->lq_type))) { + tbl->expected_tpt = expected_tpt_legacy; + return; + } + + /* Legacy rates have only one table */ + if (is_legacy(tbl->lq_type)) { + tbl->expected_tpt = expected_tpt_legacy; + return; + } + + /* Choose among many HT tables depending on number of streams + * (SISO/MIMO2), channel width (20/40), SGI, and aggregation + * status */ + if (is_siso(tbl->lq_type) && (!tbl->is_ht40 || lq_sta->is_dup)) + ht_tbl_pointer = expected_tpt_siso20MHz; + else if (is_siso(tbl->lq_type)) + ht_tbl_pointer = expected_tpt_siso40MHz; + else if (is_mimo2(tbl->lq_type) && (!tbl->is_ht40 || lq_sta->is_dup)) + ht_tbl_pointer = expected_tpt_mimo2_20MHz; + else /* if (is_mimo2(tbl->lq_type)) <-- must be true */ + ht_tbl_pointer = expected_tpt_mimo2_40MHz; + + if (!tbl->is_SGI && !lq_sta->is_agg) /* Normal */ + tbl->expected_tpt = ht_tbl_pointer[0]; + else if (tbl->is_SGI && !lq_sta->is_agg) /* SGI */ + tbl->expected_tpt = ht_tbl_pointer[1]; + else if (!tbl->is_SGI && lq_sta->is_agg) /* AGG */ + tbl->expected_tpt = ht_tbl_pointer[2]; + else /* AGG+SGI */ + tbl->expected_tpt = ht_tbl_pointer[3]; +} + +/* + * Find starting rate for new "search" high-throughput mode of modulation. + * Goal is to find lowest expected rate (under perfect conditions) that is + * above the current measured throughput of "active" mode, to give new mode + * a fair chance to prove itself without too many challenges. + * + * This gets called when transitioning to more aggressive modulation + * (i.e. legacy to SISO or MIMO, or SISO to MIMO), as well as less aggressive + * (i.e. MIMO to SISO). When moving to MIMO, bit rate will typically need + * to decrease to match "active" throughput. When moving from MIMO to SISO, + * bit rate will typically need to increase, but not if performance was bad. + */ +static s32 iwl4965_rs_get_best_rate(struct iwl_priv *priv, + struct iwl_lq_sta *lq_sta, + struct iwl_scale_tbl_info *tbl, /* "search" */ + u16 rate_mask, s8 index) +{ + /* "active" values */ + struct iwl_scale_tbl_info *active_tbl = + &(lq_sta->lq_info[lq_sta->active_tbl]); + s32 active_sr = active_tbl->win[index].success_ratio; + s32 active_tpt = active_tbl->expected_tpt[index]; + + /* expected "search" throughput */ + s32 *tpt_tbl = tbl->expected_tpt; + + s32 new_rate, high, low, start_hi; + u16 high_low; + s8 rate = index; + + new_rate = high = low = start_hi = IWL_RATE_INVALID; + + for (; ;) { + high_low = iwl4965_rs_get_adjacent_rate(priv, rate, rate_mask, + tbl->lq_type); + + low = high_low & 0xff; + high = (high_low >> 8) & 0xff; + + /* + * Lower the "search" bit rate, to give new "search" mode + * approximately the same throughput as "active" if: + * + * 1) "Active" mode has been working modestly well (but not + * great), and expected "search" throughput (under perfect + * conditions) at candidate rate is above the actual + * measured "active" throughput (but less than expected + * "active" throughput under perfect conditions). + * OR + * 2) "Active" mode has been working perfectly or very well + * and expected "search" throughput (under perfect + * conditions) at candidate rate is above expected + * "active" throughput (under perfect conditions). + */ + if ((((100 * tpt_tbl[rate]) > lq_sta->last_tpt) && + ((active_sr > IWL_RATE_DECREASE_TH) && + (active_sr <= IWL_RATE_HIGH_TH) && + (tpt_tbl[rate] <= active_tpt))) || + ((active_sr >= IWL_RATE_SCALE_SWITCH) && + (tpt_tbl[rate] > active_tpt))) { + + /* (2nd or later pass) + * If we've already tried to raise the rate, and are + * now trying to lower it, use the higher rate. */ + if (start_hi != IWL_RATE_INVALID) { + new_rate = start_hi; + break; + } + + new_rate = rate; + + /* Loop again with lower rate */ + if (low != IWL_RATE_INVALID) + rate = low; + + /* Lower rate not available, use the original */ + else + break; + + /* Else try to raise the "search" rate to match "active" */ + } else { + /* (2nd or later pass) + * If we've already tried to lower the rate, and are + * now trying to raise it, use the lower rate. */ + if (new_rate != IWL_RATE_INVALID) + break; + + /* Loop again with higher rate */ + else if (high != IWL_RATE_INVALID) { + start_hi = high; + rate = high; + + /* Higher rate not available, use the original */ + } else { + new_rate = rate; + break; + } + } + } + + return new_rate; +} + +/* + * Set up search table for MIMO2 + */ +static int iwl4965_rs_switch_to_mimo2(struct iwl_priv *priv, + struct iwl_lq_sta *lq_sta, + struct ieee80211_conf *conf, + struct ieee80211_sta *sta, + struct iwl_scale_tbl_info *tbl, int index) +{ + u16 rate_mask; + s32 rate; + s8 is_green = lq_sta->is_green; + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_rxon_context *ctx = sta_priv->common.ctx; + + if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) + return -1; + + if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2) + == WLAN_HT_CAP_SM_PS_STATIC) + return -1; + + /* Need both Tx chains/antennas to support MIMO */ + if (priv->hw_params.tx_chains_num < 2) + return -1; + + IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO2\n"); + + tbl->lq_type = LQ_MIMO2; + tbl->is_dup = lq_sta->is_dup; + tbl->action = 0; + tbl->max_search = IWL_MAX_SEARCH; + rate_mask = lq_sta->active_mimo2_rate; + + if (iwl_legacy_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap)) + tbl->is_ht40 = 1; + else + tbl->is_ht40 = 0; + + iwl4965_rs_set_expected_tpt_table(lq_sta, tbl); + + rate = iwl4965_rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index); + + IWL_DEBUG_RATE(priv, "LQ: MIMO2 best rate %d mask %X\n", + rate, rate_mask); + if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) { + IWL_DEBUG_RATE(priv, + "Can't switch with index %d rate mask %x\n", + rate, rate_mask); + return -1; + } + tbl->current_rate = iwl4965_rate_n_flags_from_tbl(priv, + tbl, rate, is_green); + + IWL_DEBUG_RATE(priv, "LQ: Switch to new mcs %X index is green %X\n", + tbl->current_rate, is_green); + return 0; +} + +/* + * Set up search table for SISO + */ +static int iwl4965_rs_switch_to_siso(struct iwl_priv *priv, + struct iwl_lq_sta *lq_sta, + struct ieee80211_conf *conf, + struct ieee80211_sta *sta, + struct iwl_scale_tbl_info *tbl, int index) +{ + u16 rate_mask; + u8 is_green = lq_sta->is_green; + s32 rate; + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_rxon_context *ctx = sta_priv->common.ctx; + + if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) + return -1; + + IWL_DEBUG_RATE(priv, "LQ: try to switch to SISO\n"); + + tbl->is_dup = lq_sta->is_dup; + tbl->lq_type = LQ_SISO; + tbl->action = 0; + tbl->max_search = IWL_MAX_SEARCH; + rate_mask = lq_sta->active_siso_rate; + + if (iwl_legacy_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap)) + tbl->is_ht40 = 1; + else + tbl->is_ht40 = 0; + + if (is_green) + tbl->is_SGI = 0; /*11n spec: no SGI in SISO+Greenfield*/ + + iwl4965_rs_set_expected_tpt_table(lq_sta, tbl); + rate = iwl4965_rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index); + + IWL_DEBUG_RATE(priv, "LQ: get best rate %d mask %X\n", rate, rate_mask); + if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) { + IWL_DEBUG_RATE(priv, + "can not switch with index %d rate mask %x\n", + rate, rate_mask); + return -1; + } + tbl->current_rate = iwl4965_rate_n_flags_from_tbl(priv, + tbl, rate, is_green); + IWL_DEBUG_RATE(priv, "LQ: Switch to new mcs %X index is green %X\n", + tbl->current_rate, is_green); + return 0; +} + +/* + * Try to switch to new modulation mode from legacy + */ +static int iwl4965_rs_move_legacy_other(struct iwl_priv *priv, + struct iwl_lq_sta *lq_sta, + struct ieee80211_conf *conf, + struct ieee80211_sta *sta, + int index) +{ + struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); + struct iwl_scale_tbl_info *search_tbl = + &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); + struct iwl_rate_scale_data *window = &(tbl->win[index]); + u32 sz = (sizeof(struct iwl_scale_tbl_info) - + (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); + u8 start_action; + u8 valid_tx_ant = priv->hw_params.valid_tx_ant; + u8 tx_chains_num = priv->hw_params.tx_chains_num; + int ret = 0; + u8 update_search_tbl_counter = 0; + + tbl->action = IWL_LEGACY_SWITCH_SISO; + + start_action = tbl->action; + for (; ;) { + lq_sta->action_counter++; + switch (tbl->action) { + case IWL_LEGACY_SWITCH_ANTENNA1: + case IWL_LEGACY_SWITCH_ANTENNA2: + IWL_DEBUG_RATE(priv, "LQ: Legacy toggle Antenna\n"); + + if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 && + tx_chains_num <= 1) || + (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 && + tx_chains_num <= 2)) + break; + + /* Don't change antenna if success has been great */ + if (window->success_ratio >= IWL_RS_GOOD_RATIO) + break; + + /* Set up search table to try other antenna */ + memcpy(search_tbl, tbl, sz); + + if (iwl4965_rs_toggle_antenna(valid_tx_ant, + &search_tbl->current_rate, search_tbl)) { + update_search_tbl_counter = 1; + iwl4965_rs_set_expected_tpt_table(lq_sta, + search_tbl); + goto out; + } + break; + case IWL_LEGACY_SWITCH_SISO: + IWL_DEBUG_RATE(priv, "LQ: Legacy switch to SISO\n"); + + /* Set up search table to try SISO */ + memcpy(search_tbl, tbl, sz); + search_tbl->is_SGI = 0; + ret = iwl4965_rs_switch_to_siso(priv, lq_sta, conf, sta, + search_tbl, index); + if (!ret) { + lq_sta->action_counter = 0; + goto out; + } + + break; + case IWL_LEGACY_SWITCH_MIMO2_AB: + case IWL_LEGACY_SWITCH_MIMO2_AC: + case IWL_LEGACY_SWITCH_MIMO2_BC: + IWL_DEBUG_RATE(priv, "LQ: Legacy switch to MIMO2\n"); + + /* Set up search table to try MIMO */ + memcpy(search_tbl, tbl, sz); + search_tbl->is_SGI = 0; + + if (tbl->action == IWL_LEGACY_SWITCH_MIMO2_AB) + search_tbl->ant_type = ANT_AB; + else if (tbl->action == IWL_LEGACY_SWITCH_MIMO2_AC) + search_tbl->ant_type = ANT_AC; + else + search_tbl->ant_type = ANT_BC; + + if (!iwl4965_rs_is_valid_ant(valid_tx_ant, + search_tbl->ant_type)) + break; + + ret = iwl4965_rs_switch_to_mimo2(priv, lq_sta, + conf, sta, + search_tbl, index); + if (!ret) { + lq_sta->action_counter = 0; + goto out; + } + break; + } + tbl->action++; + if (tbl->action > IWL_LEGACY_SWITCH_MIMO2_BC) + tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; + + if (tbl->action == start_action) + break; + + } + search_tbl->lq_type = LQ_NONE; + return 0; + +out: + lq_sta->search_better_tbl = 1; + tbl->action++; + if (tbl->action > IWL_LEGACY_SWITCH_MIMO2_BC) + tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; + if (update_search_tbl_counter) + search_tbl->action = tbl->action; + return 0; + +} + +/* + * Try to switch to new modulation mode from SISO + */ +static int iwl4965_rs_move_siso_to_other(struct iwl_priv *priv, + struct iwl_lq_sta *lq_sta, + struct ieee80211_conf *conf, + struct ieee80211_sta *sta, int index) +{ + u8 is_green = lq_sta->is_green; + struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); + struct iwl_scale_tbl_info *search_tbl = + &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); + struct iwl_rate_scale_data *window = &(tbl->win[index]); + struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + u32 sz = (sizeof(struct iwl_scale_tbl_info) - + (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); + u8 start_action; + u8 valid_tx_ant = priv->hw_params.valid_tx_ant; + u8 tx_chains_num = priv->hw_params.tx_chains_num; + u8 update_search_tbl_counter = 0; + int ret; + + start_action = tbl->action; + + for (;;) { + lq_sta->action_counter++; + switch (tbl->action) { + case IWL_SISO_SWITCH_ANTENNA1: + case IWL_SISO_SWITCH_ANTENNA2: + IWL_DEBUG_RATE(priv, "LQ: SISO toggle Antenna\n"); + if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 && + tx_chains_num <= 1) || + (tbl->action == IWL_SISO_SWITCH_ANTENNA2 && + tx_chains_num <= 2)) + break; + + if (window->success_ratio >= IWL_RS_GOOD_RATIO) + break; + + memcpy(search_tbl, tbl, sz); + if (iwl4965_rs_toggle_antenna(valid_tx_ant, + &search_tbl->current_rate, search_tbl)) { + update_search_tbl_counter = 1; + goto out; + } + break; + case IWL_SISO_SWITCH_MIMO2_AB: + case IWL_SISO_SWITCH_MIMO2_AC: + case IWL_SISO_SWITCH_MIMO2_BC: + IWL_DEBUG_RATE(priv, "LQ: SISO switch to MIMO2\n"); + memcpy(search_tbl, tbl, sz); + search_tbl->is_SGI = 0; + + if (tbl->action == IWL_SISO_SWITCH_MIMO2_AB) + search_tbl->ant_type = ANT_AB; + else if (tbl->action == IWL_SISO_SWITCH_MIMO2_AC) + search_tbl->ant_type = ANT_AC; + else + search_tbl->ant_type = ANT_BC; + + if (!iwl4965_rs_is_valid_ant(valid_tx_ant, + search_tbl->ant_type)) + break; + + ret = iwl4965_rs_switch_to_mimo2(priv, lq_sta, + conf, sta, + search_tbl, index); + if (!ret) + goto out; + break; + case IWL_SISO_SWITCH_GI: + if (!tbl->is_ht40 && !(ht_cap->cap & + IEEE80211_HT_CAP_SGI_20)) + break; + if (tbl->is_ht40 && !(ht_cap->cap & + IEEE80211_HT_CAP_SGI_40)) + break; + + IWL_DEBUG_RATE(priv, "LQ: SISO toggle SGI/NGI\n"); + + memcpy(search_tbl, tbl, sz); + if (is_green) { + if (!tbl->is_SGI) + break; + else + IWL_ERR(priv, + "SGI was set in GF+SISO\n"); + } + search_tbl->is_SGI = !tbl->is_SGI; + iwl4965_rs_set_expected_tpt_table(lq_sta, search_tbl); + if (tbl->is_SGI) { + s32 tpt = lq_sta->last_tpt / 100; + if (tpt >= search_tbl->expected_tpt[index]) + break; + } + search_tbl->current_rate = + iwl4965_rate_n_flags_from_tbl(priv, search_tbl, + index, is_green); + update_search_tbl_counter = 1; + goto out; + } + tbl->action++; + if (tbl->action > IWL_SISO_SWITCH_GI) + tbl->action = IWL_SISO_SWITCH_ANTENNA1; + + if (tbl->action == start_action) + break; + } + search_tbl->lq_type = LQ_NONE; + return 0; + + out: + lq_sta->search_better_tbl = 1; + tbl->action++; + if (tbl->action > IWL_SISO_SWITCH_GI) + tbl->action = IWL_SISO_SWITCH_ANTENNA1; + if (update_search_tbl_counter) + search_tbl->action = tbl->action; + + return 0; +} + +/* + * Try to switch to new modulation mode from MIMO2 + */ +static int iwl4965_rs_move_mimo2_to_other(struct iwl_priv *priv, + struct iwl_lq_sta *lq_sta, + struct ieee80211_conf *conf, + struct ieee80211_sta *sta, int index) +{ + s8 is_green = lq_sta->is_green; + struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); + struct iwl_scale_tbl_info *search_tbl = + &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); + struct iwl_rate_scale_data *window = &(tbl->win[index]); + struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + u32 sz = (sizeof(struct iwl_scale_tbl_info) - + (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); + u8 start_action; + u8 valid_tx_ant = priv->hw_params.valid_tx_ant; + u8 tx_chains_num = priv->hw_params.tx_chains_num; + u8 update_search_tbl_counter = 0; + int ret; + + start_action = tbl->action; + for (;;) { + lq_sta->action_counter++; + switch (tbl->action) { + case IWL_MIMO2_SWITCH_ANTENNA1: + case IWL_MIMO2_SWITCH_ANTENNA2: + IWL_DEBUG_RATE(priv, "LQ: MIMO2 toggle Antennas\n"); + + if (tx_chains_num <= 2) + break; + + if (window->success_ratio >= IWL_RS_GOOD_RATIO) + break; + + memcpy(search_tbl, tbl, sz); + if (iwl4965_rs_toggle_antenna(valid_tx_ant, + &search_tbl->current_rate, search_tbl)) { + update_search_tbl_counter = 1; + goto out; + } + break; + case IWL_MIMO2_SWITCH_SISO_A: + case IWL_MIMO2_SWITCH_SISO_B: + case IWL_MIMO2_SWITCH_SISO_C: + IWL_DEBUG_RATE(priv, "LQ: MIMO2 switch to SISO\n"); + + /* Set up new search table for SISO */ + memcpy(search_tbl, tbl, sz); + + if (tbl->action == IWL_MIMO2_SWITCH_SISO_A) + search_tbl->ant_type = ANT_A; + else if (tbl->action == IWL_MIMO2_SWITCH_SISO_B) + search_tbl->ant_type = ANT_B; + else + search_tbl->ant_type = ANT_C; + + if (!iwl4965_rs_is_valid_ant(valid_tx_ant, + search_tbl->ant_type)) + break; + + ret = iwl4965_rs_switch_to_siso(priv, lq_sta, + conf, sta, + search_tbl, index); + if (!ret) + goto out; + + break; + + case IWL_MIMO2_SWITCH_GI: + if (!tbl->is_ht40 && !(ht_cap->cap & + IEEE80211_HT_CAP_SGI_20)) + break; + if (tbl->is_ht40 && !(ht_cap->cap & + IEEE80211_HT_CAP_SGI_40)) + break; + + IWL_DEBUG_RATE(priv, "LQ: MIMO2 toggle SGI/NGI\n"); + + /* Set up new search table for MIMO2 */ + memcpy(search_tbl, tbl, sz); + search_tbl->is_SGI = !tbl->is_SGI; + iwl4965_rs_set_expected_tpt_table(lq_sta, search_tbl); + /* + * If active table already uses the fastest possible + * modulation (dual stream with short guard interval), + * and it's working well, there's no need to look + * for a better type of modulation! + */ + if (tbl->is_SGI) { + s32 tpt = lq_sta->last_tpt / 100; + if (tpt >= search_tbl->expected_tpt[index]) + break; + } + search_tbl->current_rate = + iwl4965_rate_n_flags_from_tbl(priv, search_tbl, + index, is_green); + update_search_tbl_counter = 1; + goto out; + + } + tbl->action++; + if (tbl->action > IWL_MIMO2_SWITCH_GI) + tbl->action = IWL_MIMO2_SWITCH_ANTENNA1; + + if (tbl->action == start_action) + break; + } + search_tbl->lq_type = LQ_NONE; + return 0; + out: + lq_sta->search_better_tbl = 1; + tbl->action++; + if (tbl->action > IWL_MIMO2_SWITCH_GI) + tbl->action = IWL_MIMO2_SWITCH_ANTENNA1; + if (update_search_tbl_counter) + search_tbl->action = tbl->action; + + return 0; + +} + +/* + * Check whether we should continue using same modulation mode, or + * begin search for a new mode, based on: + * 1) # tx successes or failures while using this mode + * 2) # times calling this function + * 3) elapsed time in this mode (not used, for now) + */ +static void +iwl4965_rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search) +{ + struct iwl_scale_tbl_info *tbl; + int i; + int active_tbl; + int flush_interval_passed = 0; + struct iwl_priv *priv; + + priv = lq_sta->drv; + active_tbl = lq_sta->active_tbl; + + tbl = &(lq_sta->lq_info[active_tbl]); + + /* If we've been disallowing search, see if we should now allow it */ + if (lq_sta->stay_in_tbl) { + + /* Elapsed time using current modulation mode */ + if (lq_sta->flush_timer) + flush_interval_passed = + time_after(jiffies, + (unsigned long)(lq_sta->flush_timer + + IWL_RATE_SCALE_FLUSH_INTVL)); + + /* + * Check if we should allow search for new modulation mode. + * If many frames have failed or succeeded, or we've used + * this same modulation for a long time, allow search, and + * reset history stats that keep track of whether we should + * allow a new search. Also (below) reset all bitmaps and + * stats in active history. + */ + if (force_search || + (lq_sta->total_failed > lq_sta->max_failure_limit) || + (lq_sta->total_success > lq_sta->max_success_limit) || + ((!lq_sta->search_better_tbl) && (lq_sta->flush_timer) + && (flush_interval_passed))) { + IWL_DEBUG_RATE(priv, "LQ: stay is expired %d %d %d\n:", + lq_sta->total_failed, + lq_sta->total_success, + flush_interval_passed); + + /* Allow search for new mode */ + lq_sta->stay_in_tbl = 0; /* only place reset */ + lq_sta->total_failed = 0; + lq_sta->total_success = 0; + lq_sta->flush_timer = 0; + + /* + * Else if we've used this modulation mode enough repetitions + * (regardless of elapsed time or success/failure), reset + * history bitmaps and rate-specific stats for all rates in + * active table. + */ + } else { + lq_sta->table_count++; + if (lq_sta->table_count >= + lq_sta->table_count_limit) { + lq_sta->table_count = 0; + + IWL_DEBUG_RATE(priv, + "LQ: stay in table clear win\n"); + for (i = 0; i < IWL_RATE_COUNT; i++) + iwl4965_rs_rate_scale_clear_window( + &(tbl->win[i])); + } + } + + /* If transitioning to allow "search", reset all history + * bitmaps and stats in active table (this will become the new + * "search" table). */ + if (!lq_sta->stay_in_tbl) { + for (i = 0; i < IWL_RATE_COUNT; i++) + iwl4965_rs_rate_scale_clear_window( + &(tbl->win[i])); + } + } +} + +/* + * setup rate table in uCode + * return rate_n_flags as used in the table + */ +static u32 iwl4965_rs_update_rate_tbl(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct iwl_lq_sta *lq_sta, + struct iwl_scale_tbl_info *tbl, + int index, u8 is_green) +{ + u32 rate; + + /* Update uCode's rate table. */ + rate = iwl4965_rate_n_flags_from_tbl(priv, tbl, index, is_green); + iwl4965_rs_fill_link_cmd(priv, lq_sta, rate); + iwl_legacy_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false); + + return rate; +} + +/* + * Do rate scaling and search for new modulation mode. + */ +static void iwl4965_rs_rate_scale_perform(struct iwl_priv *priv, + struct sk_buff *skb, + struct ieee80211_sta *sta, + struct iwl_lq_sta *lq_sta) +{ + struct ieee80211_hw *hw = priv->hw; + struct ieee80211_conf *conf = &hw->conf; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + int low = IWL_RATE_INVALID; + int high = IWL_RATE_INVALID; + int index; + int i; + struct iwl_rate_scale_data *window = NULL; + int current_tpt = IWL_INVALID_VALUE; + int low_tpt = IWL_INVALID_VALUE; + int high_tpt = IWL_INVALID_VALUE; + u32 fail_count; + s8 scale_action = 0; + u16 rate_mask; + u8 update_lq = 0; + struct iwl_scale_tbl_info *tbl, *tbl1; + u16 rate_scale_index_msk = 0; + u32 rate; + u8 is_green = 0; + u8 active_tbl = 0; + u8 done_search = 0; + u16 high_low; + s32 sr; + u8 tid = MAX_TID_COUNT; + struct iwl_tid_data *tid_data; + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_rxon_context *ctx = sta_priv->common.ctx; + + IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n"); + + /* Send management frames and NO_ACK data using lowest rate. */ + /* TODO: this could probably be improved.. */ + if (!ieee80211_is_data(hdr->frame_control) || + info->flags & IEEE80211_TX_CTL_NO_ACK) + return; + + if (!sta || !lq_sta) + return; + + lq_sta->supp_rates = sta->supp_rates[lq_sta->band]; + + tid = iwl4965_rs_tl_add_packet(lq_sta, hdr); + if ((tid != MAX_TID_COUNT) && (lq_sta->tx_agg_tid_en & (1 << tid))) { + tid_data = &priv->stations[lq_sta->lq.sta_id].tid[tid]; + if (tid_data->agg.state == IWL_AGG_OFF) + lq_sta->is_agg = 0; + else + lq_sta->is_agg = 1; + } else + lq_sta->is_agg = 0; + + /* + * Select rate-scale / modulation-mode table to work with in + * the rest of this function: "search" if searching for better + * modulation mode, or "active" if doing rate scaling within a mode. + */ + if (!lq_sta->search_better_tbl) + active_tbl = lq_sta->active_tbl; + else + active_tbl = 1 - lq_sta->active_tbl; + + tbl = &(lq_sta->lq_info[active_tbl]); + if (is_legacy(tbl->lq_type)) + lq_sta->is_green = 0; + else + lq_sta->is_green = iwl4965_rs_use_green(sta); + is_green = lq_sta->is_green; + + /* current tx rate */ + index = lq_sta->last_txrate_idx; + + IWL_DEBUG_RATE(priv, "Rate scale index %d for type %d\n", index, + tbl->lq_type); + + /* rates available for this association, and for modulation mode */ + rate_mask = iwl4965_rs_get_supported_rates(lq_sta, hdr, tbl->lq_type); + + IWL_DEBUG_RATE(priv, "mask 0x%04X\n", rate_mask); + + /* mask with station rate restriction */ + if (is_legacy(tbl->lq_type)) { + if (lq_sta->band == IEEE80211_BAND_5GHZ) + /* supp_rates has no CCK bits in A mode */ + rate_scale_index_msk = (u16) (rate_mask & + (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); + else + rate_scale_index_msk = (u16) (rate_mask & + lq_sta->supp_rates); + + } else + rate_scale_index_msk = rate_mask; + + if (!rate_scale_index_msk) + rate_scale_index_msk = rate_mask; + + if (!((1 << index) & rate_scale_index_msk)) { + IWL_ERR(priv, "Current Rate is not valid\n"); + if (lq_sta->search_better_tbl) { + /* revert to active table if search table is not valid*/ + tbl->lq_type = LQ_NONE; + lq_sta->search_better_tbl = 0; + tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); + /* get "active" rate info */ + index = iwl4965_hwrate_to_plcp_idx(tbl->current_rate); + rate = iwl4965_rs_update_rate_tbl(priv, ctx, lq_sta, + tbl, index, is_green); + } + return; + } + + /* Get expected throughput table and history window for current rate */ + if (!tbl->expected_tpt) { + IWL_ERR(priv, "tbl->expected_tpt is NULL\n"); + return; + } + + /* force user max rate if set by user */ + if ((lq_sta->max_rate_idx != -1) && + (lq_sta->max_rate_idx < index)) { + index = lq_sta->max_rate_idx; + update_lq = 1; + window = &(tbl->win[index]); + goto lq_update; + } + + window = &(tbl->win[index]); + + /* + * If there is not enough history to calculate actual average + * throughput, keep analyzing results of more tx frames, without + * changing rate or mode (bypass most of the rest of this function). + * Set up new rate table in uCode only if old rate is not supported + * in current association (use new rate found above). + */ + fail_count = window->counter - window->success_counter; + if ((fail_count < IWL_RATE_MIN_FAILURE_TH) && + (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) { + IWL_DEBUG_RATE(priv, "LQ: still below TH. succ=%d total=%d " + "for index %d\n", + window->success_counter, window->counter, index); + + /* Can't calculate this yet; not enough history */ + window->average_tpt = IWL_INVALID_VALUE; + + /* Should we stay with this modulation mode, + * or search for a new one? */ + iwl4965_rs_stay_in_table(lq_sta, false); + + goto out; + } + /* Else we have enough samples; calculate estimate of + * actual average throughput */ + if (window->average_tpt != ((window->success_ratio * + tbl->expected_tpt[index] + 64) / 128)) { + IWL_ERR(priv, + "expected_tpt should have been calculated by now\n"); + window->average_tpt = ((window->success_ratio * + tbl->expected_tpt[index] + 64) / 128); + } + + /* If we are searching for better modulation mode, check success. */ + if (lq_sta->search_better_tbl) { + /* If good success, continue using the "search" mode; + * no need to send new link quality command, since we're + * continuing to use the setup that we've been trying. */ + if (window->average_tpt > lq_sta->last_tpt) { + + IWL_DEBUG_RATE(priv, "LQ: SWITCHING TO NEW TABLE " + "suc=%d cur-tpt=%d old-tpt=%d\n", + window->success_ratio, + window->average_tpt, + lq_sta->last_tpt); + + if (!is_legacy(tbl->lq_type)) + lq_sta->enable_counter = 1; + + /* Swap tables; "search" becomes "active" */ + lq_sta->active_tbl = active_tbl; + current_tpt = window->average_tpt; + + /* Else poor success; go back to mode in "active" table */ + } else { + + IWL_DEBUG_RATE(priv, "LQ: GOING BACK TO THE OLD TABLE " + "suc=%d cur-tpt=%d old-tpt=%d\n", + window->success_ratio, + window->average_tpt, + lq_sta->last_tpt); + + /* Nullify "search" table */ + tbl->lq_type = LQ_NONE; + + /* Revert to "active" table */ + active_tbl = lq_sta->active_tbl; + tbl = &(lq_sta->lq_info[active_tbl]); + + /* Revert to "active" rate and throughput info */ + index = iwl4965_hwrate_to_plcp_idx(tbl->current_rate); + current_tpt = lq_sta->last_tpt; + + /* Need to set up a new rate table in uCode */ + update_lq = 1; + } + + /* Either way, we've made a decision; modulation mode + * search is done, allow rate adjustment next time. */ + lq_sta->search_better_tbl = 0; + done_search = 1; /* Don't switch modes below! */ + goto lq_update; + } + + /* (Else) not in search of better modulation mode, try for better + * starting rate, while staying in this mode. */ + high_low = iwl4965_rs_get_adjacent_rate(priv, index, + rate_scale_index_msk, + tbl->lq_type); + low = high_low & 0xff; + high = (high_low >> 8) & 0xff; + + /* If user set max rate, dont allow higher than user constrain */ + if ((lq_sta->max_rate_idx != -1) && + (lq_sta->max_rate_idx < high)) + high = IWL_RATE_INVALID; + + sr = window->success_ratio; + + /* Collect measured throughputs for current and adjacent rates */ + current_tpt = window->average_tpt; + if (low != IWL_RATE_INVALID) + low_tpt = tbl->win[low].average_tpt; + if (high != IWL_RATE_INVALID) + high_tpt = tbl->win[high].average_tpt; + + scale_action = 0; + + /* Too many failures, decrease rate */ + if ((sr <= IWL_RATE_DECREASE_TH) || (current_tpt == 0)) { + IWL_DEBUG_RATE(priv, + "decrease rate because of low success_ratio\n"); + scale_action = -1; + + /* No throughput measured yet for adjacent rates; try increase. */ + } else if ((low_tpt == IWL_INVALID_VALUE) && + (high_tpt == IWL_INVALID_VALUE)) { + + if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH) + scale_action = 1; + else if (low != IWL_RATE_INVALID) + scale_action = 0; + } + + /* Both adjacent throughputs are measured, but neither one has better + * throughput; we're using the best rate, don't change it! */ + else if ((low_tpt != IWL_INVALID_VALUE) && + (high_tpt != IWL_INVALID_VALUE) && + (low_tpt < current_tpt) && + (high_tpt < current_tpt)) + scale_action = 0; + + /* At least one adjacent rate's throughput is measured, + * and may have better performance. */ + else { + /* Higher adjacent rate's throughput is measured */ + if (high_tpt != IWL_INVALID_VALUE) { + /* Higher rate has better throughput */ + if (high_tpt > current_tpt && + sr >= IWL_RATE_INCREASE_TH) { + scale_action = 1; + } else { + scale_action = 0; + } + + /* Lower adjacent rate's throughput is measured */ + } else if (low_tpt != IWL_INVALID_VALUE) { + /* Lower rate has better throughput */ + if (low_tpt > current_tpt) { + IWL_DEBUG_RATE(priv, + "decrease rate because of low tpt\n"); + scale_action = -1; + } else if (sr >= IWL_RATE_INCREASE_TH) { + scale_action = 1; + } + } + } + + /* Sanity check; asked for decrease, but success rate or throughput + * has been good at old rate. Don't change it. */ + if ((scale_action == -1) && (low != IWL_RATE_INVALID) && + ((sr > IWL_RATE_HIGH_TH) || + (current_tpt > (100 * tbl->expected_tpt[low])))) + scale_action = 0; + + switch (scale_action) { + case -1: + /* Decrease starting rate, update uCode's rate table */ + if (low != IWL_RATE_INVALID) { + update_lq = 1; + index = low; + } + + break; + case 1: + /* Increase starting rate, update uCode's rate table */ + if (high != IWL_RATE_INVALID) { + update_lq = 1; + index = high; + } + + break; + case 0: + /* No change */ + default: + break; + } + + IWL_DEBUG_RATE(priv, "choose rate scale index %d action %d low %d " + "high %d type %d\n", + index, scale_action, low, high, tbl->lq_type); + +lq_update: + /* Replace uCode's rate table for the destination station. */ + if (update_lq) + rate = iwl4965_rs_update_rate_tbl(priv, ctx, lq_sta, + tbl, index, is_green); + + /* Should we stay with this modulation mode, + * or search for a new one? */ + iwl4965_rs_stay_in_table(lq_sta, false); + + /* + * Search for new modulation mode if we're: + * 1) Not changing rates right now + * 2) Not just finishing up a search + * 3) Allowing a new search + */ + if (!update_lq && !done_search && + !lq_sta->stay_in_tbl && window->counter) { + /* Save current throughput to compare with "search" throughput*/ + lq_sta->last_tpt = current_tpt; + + /* Select a new "search" modulation mode to try. + * If one is found, set up the new "search" table. */ + if (is_legacy(tbl->lq_type)) + iwl4965_rs_move_legacy_other(priv, lq_sta, + conf, sta, index); + else if (is_siso(tbl->lq_type)) + iwl4965_rs_move_siso_to_other(priv, lq_sta, + conf, sta, index); + else /* (is_mimo2(tbl->lq_type)) */ + iwl4965_rs_move_mimo2_to_other(priv, lq_sta, + conf, sta, index); + + /* If new "search" mode was selected, set up in uCode table */ + if (lq_sta->search_better_tbl) { + /* Access the "search" table, clear its history. */ + tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); + for (i = 0; i < IWL_RATE_COUNT; i++) + iwl4965_rs_rate_scale_clear_window( + &(tbl->win[i])); + + /* Use new "search" start rate */ + index = iwl4965_hwrate_to_plcp_idx(tbl->current_rate); + + IWL_DEBUG_RATE(priv, + "Switch current mcs: %X index: %d\n", + tbl->current_rate, index); + iwl4965_rs_fill_link_cmd(priv, lq_sta, + tbl->current_rate); + iwl_legacy_send_lq_cmd(priv, ctx, + &lq_sta->lq, CMD_ASYNC, false); + } else + done_search = 1; + } + + if (done_search && !lq_sta->stay_in_tbl) { + /* If the "active" (non-search) mode was legacy, + * and we've tried switching antennas, + * but we haven't been able to try HT modes (not available), + * stay with best antenna legacy modulation for a while + * before next round of mode comparisons. */ + tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); + if (is_legacy(tbl1->lq_type) && !conf_is_ht(conf) && + lq_sta->action_counter > tbl1->max_search) { + IWL_DEBUG_RATE(priv, "LQ: STAY in legacy table\n"); + iwl4965_rs_set_stay_in_table(priv, 1, lq_sta); + } + + /* If we're in an HT mode, and all 3 mode switch actions + * have been tried and compared, stay in this best modulation + * mode for a while before next round of mode comparisons. */ + if (lq_sta->enable_counter && + (lq_sta->action_counter >= tbl1->max_search)) { + if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && + (lq_sta->tx_agg_tid_en & (1 << tid)) && + (tid != MAX_TID_COUNT)) { + tid_data = + &priv->stations[lq_sta->lq.sta_id].tid[tid]; + if (tid_data->agg.state == IWL_AGG_OFF) { + IWL_DEBUG_RATE(priv, + "try to aggregate tid %d\n", + tid); + iwl4965_rs_tl_turn_on_agg(priv, tid, + lq_sta, sta); + } + } + iwl4965_rs_set_stay_in_table(priv, 0, lq_sta); + } + } + +out: + tbl->current_rate = iwl4965_rate_n_flags_from_tbl(priv, tbl, + index, is_green); + i = index; + lq_sta->last_txrate_idx = i; +} + +/** + * iwl4965_rs_initialize_lq - Initialize a station's hardware rate table + * + * The uCode's station table contains a table of fallback rates + * for automatic fallback during transmission. + * + * NOTE: This sets up a default set of values. These will be replaced later + * if the driver's iwl-4965-rs rate scaling algorithm is used, instead of + * rc80211_simple. + * + * NOTE: Run REPLY_ADD_STA command to set up station table entry, before + * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD, + * which requires station table entry to exist). + */ +static void iwl4965_rs_initialize_lq(struct iwl_priv *priv, + struct ieee80211_conf *conf, + struct ieee80211_sta *sta, + struct iwl_lq_sta *lq_sta) +{ + struct iwl_scale_tbl_info *tbl; + int rate_idx; + int i; + u32 rate; + u8 use_green = iwl4965_rs_use_green(sta); + u8 active_tbl = 0; + u8 valid_tx_ant; + struct iwl_station_priv *sta_priv; + struct iwl_rxon_context *ctx; + + if (!sta || !lq_sta) + return; + + sta_priv = (void *)sta->drv_priv; + ctx = sta_priv->common.ctx; + + i = lq_sta->last_txrate_idx; + + valid_tx_ant = priv->hw_params.valid_tx_ant; + + if (!lq_sta->search_better_tbl) + active_tbl = lq_sta->active_tbl; + else + active_tbl = 1 - lq_sta->active_tbl; + + tbl = &(lq_sta->lq_info[active_tbl]); + + if ((i < 0) || (i >= IWL_RATE_COUNT)) + i = 0; + + rate = iwl_rates[i].plcp; + tbl->ant_type = iwl4965_first_antenna(valid_tx_ant); + rate |= tbl->ant_type << RATE_MCS_ANT_POS; + + if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE) + rate |= RATE_MCS_CCK_MSK; + + iwl4965_rs_get_tbl_info_from_mcs(rate, priv->band, tbl, &rate_idx); + if (!iwl4965_rs_is_valid_ant(valid_tx_ant, tbl->ant_type)) + iwl4965_rs_toggle_antenna(valid_tx_ant, &rate, tbl); + + rate = iwl4965_rate_n_flags_from_tbl(priv, tbl, rate_idx, use_green); + tbl->current_rate = rate; + iwl4965_rs_set_expected_tpt_table(lq_sta, tbl); + iwl4965_rs_fill_link_cmd(NULL, lq_sta, rate); + priv->stations[lq_sta->lq.sta_id].lq = &lq_sta->lq; + iwl_legacy_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_SYNC, true); +} + +static void +iwl4965_rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, + struct ieee80211_tx_rate_control *txrc) +{ + + struct sk_buff *skb = txrc->skb; + struct ieee80211_supported_band *sband = txrc->sband; + struct iwl_priv *priv __maybe_unused = (struct iwl_priv *)priv_r; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct iwl_lq_sta *lq_sta = priv_sta; + int rate_idx; + + IWL_DEBUG_RATE_LIMIT(priv, "rate scale calculate new rate for skb\n"); + + /* Get max rate if user set max rate */ + if (lq_sta) { + lq_sta->max_rate_idx = txrc->max_rate_idx; + if ((sband->band == IEEE80211_BAND_5GHZ) && + (lq_sta->max_rate_idx != -1)) + lq_sta->max_rate_idx += IWL_FIRST_OFDM_RATE; + if ((lq_sta->max_rate_idx < 0) || + (lq_sta->max_rate_idx >= IWL_RATE_COUNT)) + lq_sta->max_rate_idx = -1; + } + + /* Treat uninitialized rate scaling data same as non-existing. */ + if (lq_sta && !lq_sta->drv) { + IWL_DEBUG_RATE(priv, "Rate scaling not initialized yet.\n"); + priv_sta = NULL; + } + + /* Send management frames and NO_ACK data using lowest rate. */ + if (rate_control_send_low(sta, priv_sta, txrc)) + return; + + rate_idx = lq_sta->last_txrate_idx; + + if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) { + rate_idx -= IWL_FIRST_OFDM_RATE; + /* 6M and 9M shared same MCS index */ + rate_idx = (rate_idx > 0) ? (rate_idx - 1) : 0; + if (iwl4965_rs_extract_rate(lq_sta->last_rate_n_flags) >= + IWL_RATE_MIMO2_6M_PLCP) + rate_idx = rate_idx + MCS_INDEX_PER_STREAM; + info->control.rates[0].flags = IEEE80211_TX_RC_MCS; + if (lq_sta->last_rate_n_flags & RATE_MCS_SGI_MSK) + info->control.rates[0].flags |= + IEEE80211_TX_RC_SHORT_GI; + if (lq_sta->last_rate_n_flags & RATE_MCS_DUP_MSK) + info->control.rates[0].flags |= + IEEE80211_TX_RC_DUP_DATA; + if (lq_sta->last_rate_n_flags & RATE_MCS_HT40_MSK) + info->control.rates[0].flags |= + IEEE80211_TX_RC_40_MHZ_WIDTH; + if (lq_sta->last_rate_n_flags & RATE_MCS_GF_MSK) + info->control.rates[0].flags |= + IEEE80211_TX_RC_GREEN_FIELD; + } else { + /* Check for invalid rates */ + if ((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT_LEGACY) || + ((sband->band == IEEE80211_BAND_5GHZ) && + (rate_idx < IWL_FIRST_OFDM_RATE))) + rate_idx = rate_lowest_index(sband, sta); + /* On valid 5 GHz rate, adjust index */ + else if (sband->band == IEEE80211_BAND_5GHZ) + rate_idx -= IWL_FIRST_OFDM_RATE; + info->control.rates[0].flags = 0; + } + info->control.rates[0].idx = rate_idx; + +} + +static void *iwl4965_rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta, + gfp_t gfp) +{ + struct iwl_lq_sta *lq_sta; + struct iwl_station_priv *sta_priv = + (struct iwl_station_priv *) sta->drv_priv; + struct iwl_priv *priv; + + priv = (struct iwl_priv *)priv_rate; + IWL_DEBUG_RATE(priv, "create station rate scale window\n"); + + lq_sta = &sta_priv->lq_sta; + + return lq_sta; +} + +/* + * Called after adding a new station to initialize rate scaling + */ +void +iwl4965_rs_rate_init(struct iwl_priv *priv, + struct ieee80211_sta *sta, + u8 sta_id) +{ + int i, j; + struct ieee80211_hw *hw = priv->hw; + struct ieee80211_conf *conf = &priv->hw->conf; + struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + struct iwl_station_priv *sta_priv; + struct iwl_lq_sta *lq_sta; + struct ieee80211_supported_band *sband; + + sta_priv = (struct iwl_station_priv *) sta->drv_priv; + lq_sta = &sta_priv->lq_sta; + sband = hw->wiphy->bands[conf->channel->band]; + + + lq_sta->lq.sta_id = sta_id; + + for (j = 0; j < LQ_SIZE; j++) + for (i = 0; i < IWL_RATE_COUNT; i++) + iwl4965_rs_rate_scale_clear_window( + &lq_sta->lq_info[j].win[i]); + + lq_sta->flush_timer = 0; + lq_sta->supp_rates = sta->supp_rates[sband->band]; + for (j = 0; j < LQ_SIZE; j++) + for (i = 0; i < IWL_RATE_COUNT; i++) + iwl4965_rs_rate_scale_clear_window( + &lq_sta->lq_info[j].win[i]); + + IWL_DEBUG_RATE(priv, "LQ:" + "*** rate scale station global init for station %d ***\n", + sta_id); + /* TODO: what is a good starting rate for STA? About middle? Maybe not + * the lowest or the highest rate.. Could consider using RSSI from + * previous packets? Need to have IEEE 802.1X auth succeed immediately + * after assoc.. */ + + lq_sta->is_dup = 0; + lq_sta->max_rate_idx = -1; + lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; + lq_sta->is_green = iwl4965_rs_use_green(sta); + lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); + lq_sta->band = priv->band; + /* + * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), + * supp_rates[] does not; shift to convert format, force 9 MBits off. + */ + lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1; + lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1; + lq_sta->active_siso_rate &= ~((u16)0x2); + lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; + + /* Same here */ + lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1; + lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1; + lq_sta->active_mimo2_rate &= ~((u16)0x2); + lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; + + /* These values will be overridden later */ + lq_sta->lq.general_params.single_stream_ant_msk = + iwl4965_first_antenna(priv->hw_params.valid_tx_ant); + lq_sta->lq.general_params.dual_stream_ant_msk = + priv->hw_params.valid_tx_ant & + ~iwl4965_first_antenna(priv->hw_params.valid_tx_ant); + if (!lq_sta->lq.general_params.dual_stream_ant_msk) { + lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB; + } else if (iwl4965_num_of_ant(priv->hw_params.valid_tx_ant) == 2) { + lq_sta->lq.general_params.dual_stream_ant_msk = + priv->hw_params.valid_tx_ant; + } + + /* as default allow aggregation for all tids */ + lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; + lq_sta->drv = priv; + + /* Set last_txrate_idx to lowest rate */ + lq_sta->last_txrate_idx = rate_lowest_index(sband, sta); + if (sband->band == IEEE80211_BAND_5GHZ) + lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; + lq_sta->is_agg = 0; + +#ifdef CONFIG_MAC80211_DEBUGFS + lq_sta->dbg_fixed_rate = 0; +#endif + + iwl4965_rs_initialize_lq(priv, conf, sta, lq_sta); +} + +static void iwl4965_rs_fill_link_cmd(struct iwl_priv *priv, + struct iwl_lq_sta *lq_sta, u32 new_rate) +{ + struct iwl_scale_tbl_info tbl_type; + int index = 0; + int rate_idx; + int repeat_rate = 0; + u8 ant_toggle_cnt = 0; + u8 use_ht_possible = 1; + u8 valid_tx_ant = 0; + struct iwl_link_quality_cmd *lq_cmd = &lq_sta->lq; + + /* Override starting rate (index 0) if needed for debug purposes */ + iwl4965_rs_dbgfs_set_mcs(lq_sta, &new_rate, index); + + /* Interpret new_rate (rate_n_flags) */ + iwl4965_rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, + &tbl_type, &rate_idx); + + /* How many times should we repeat the initial rate? */ + if (is_legacy(tbl_type.lq_type)) { + ant_toggle_cnt = 1; + repeat_rate = IWL_NUMBER_TRY; + } else { + repeat_rate = IWL_HT_NUMBER_TRY; + } + + lq_cmd->general_params.mimo_delimiter = + is_mimo(tbl_type.lq_type) ? 1 : 0; + + /* Fill 1st table entry (index 0) */ + lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate); + + if (iwl4965_num_of_ant(tbl_type.ant_type) == 1) { + lq_cmd->general_params.single_stream_ant_msk = + tbl_type.ant_type; + } else if (iwl4965_num_of_ant(tbl_type.ant_type) == 2) { + lq_cmd->general_params.dual_stream_ant_msk = + tbl_type.ant_type; + } /* otherwise we don't modify the existing value */ + + index++; + repeat_rate--; + if (priv) + valid_tx_ant = priv->hw_params.valid_tx_ant; + + /* Fill rest of rate table */ + while (index < LINK_QUAL_MAX_RETRY_NUM) { + /* Repeat initial/next rate. + * For legacy IWL_NUMBER_TRY == 1, this loop will not execute. + * For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */ + while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) { + if (is_legacy(tbl_type.lq_type)) { + if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE) + ant_toggle_cnt++; + else if (priv && + iwl4965_rs_toggle_antenna(valid_tx_ant, + &new_rate, &tbl_type)) + ant_toggle_cnt = 1; + } + + /* Override next rate if needed for debug purposes */ + iwl4965_rs_dbgfs_set_mcs(lq_sta, &new_rate, index); + + /* Fill next table entry */ + lq_cmd->rs_table[index].rate_n_flags = + cpu_to_le32(new_rate); + repeat_rate--; + index++; + } + + iwl4965_rs_get_tbl_info_from_mcs(new_rate, + lq_sta->band, &tbl_type, + &rate_idx); + + /* Indicate to uCode which entries might be MIMO. + * If initial rate was MIMO, this will finally end up + * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */ + if (is_mimo(tbl_type.lq_type)) + lq_cmd->general_params.mimo_delimiter = index; + + /* Get next rate */ + new_rate = iwl4965_rs_get_lower_rate(lq_sta, + &tbl_type, rate_idx, + use_ht_possible); + + /* How many times should we repeat the next rate? */ + if (is_legacy(tbl_type.lq_type)) { + if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE) + ant_toggle_cnt++; + else if (priv && + iwl4965_rs_toggle_antenna(valid_tx_ant, + &new_rate, &tbl_type)) + ant_toggle_cnt = 1; + + repeat_rate = IWL_NUMBER_TRY; + } else { + repeat_rate = IWL_HT_NUMBER_TRY; + } + + /* Don't allow HT rates after next pass. + * iwl4965_rs_get_lower_rate() will change type to LQ_A or LQ_G. */ + use_ht_possible = 0; + + /* Override next rate if needed for debug purposes */ + iwl4965_rs_dbgfs_set_mcs(lq_sta, &new_rate, index); + + /* Fill next table entry */ + lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate); + + index++; + repeat_rate--; + } + + lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; + lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; + + lq_cmd->agg_params.agg_time_limit = + cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); +} + +static void +*iwl4965_rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) +{ + return hw->priv; +} +/* rate scale requires free function to be implemented */ +static void iwl4965_rs_free(void *priv_rate) +{ + return; +} + +static void iwl4965_rs_free_sta(void *priv_r, struct ieee80211_sta *sta, + void *priv_sta) +{ + struct iwl_priv *priv __maybe_unused = priv_r; + + IWL_DEBUG_RATE(priv, "enter\n"); + IWL_DEBUG_RATE(priv, "leave\n"); +} + + +#ifdef CONFIG_MAC80211_DEBUGFS +static int iwl4965_open_file_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} +static void iwl4965_rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, + u32 *rate_n_flags, int index) +{ + struct iwl_priv *priv; + u8 valid_tx_ant; + u8 ant_sel_tx; + + priv = lq_sta->drv; + valid_tx_ant = priv->hw_params.valid_tx_ant; + if (lq_sta->dbg_fixed_rate) { + ant_sel_tx = + ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) + >> RATE_MCS_ANT_POS); + if ((valid_tx_ant & ant_sel_tx) == ant_sel_tx) { + *rate_n_flags = lq_sta->dbg_fixed_rate; + IWL_DEBUG_RATE(priv, "Fixed rate ON\n"); + } else { + lq_sta->dbg_fixed_rate = 0; + IWL_ERR(priv, + "Invalid antenna selection 0x%X, Valid is 0x%X\n", + ant_sel_tx, valid_tx_ant); + IWL_DEBUG_RATE(priv, "Fixed rate OFF\n"); + } + } else { + IWL_DEBUG_RATE(priv, "Fixed rate OFF\n"); + } +} + +static ssize_t iwl4965_rs_sta_dbgfs_scale_table_write(struct file *file, + const char __user *user_buf, size_t count, loff_t *ppos) +{ + struct iwl_lq_sta *lq_sta = file->private_data; + struct iwl_priv *priv; + char buf[64]; + int buf_size; + u32 parsed_rate; + struct iwl_station_priv *sta_priv = + container_of(lq_sta, struct iwl_station_priv, lq_sta); + struct iwl_rxon_context *ctx = sta_priv->common.ctx; + + priv = lq_sta->drv; + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + + if (sscanf(buf, "%x", &parsed_rate) == 1) + lq_sta->dbg_fixed_rate = parsed_rate; + else + lq_sta->dbg_fixed_rate = 0; + + lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */ + lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ + lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ + + IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n", + lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate); + + if (lq_sta->dbg_fixed_rate) { + iwl4965_rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate); + iwl_legacy_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC, + false); + } + + return count; +} + +static ssize_t iwl4965_rs_sta_dbgfs_scale_table_read(struct file *file, + char __user *user_buf, size_t count, loff_t *ppos) +{ + char *buff; + int desc = 0; + int i = 0; + int index = 0; + ssize_t ret; + + struct iwl_lq_sta *lq_sta = file->private_data; + struct iwl_priv *priv; + struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); + + priv = lq_sta->drv; + buff = kmalloc(1024, GFP_KERNEL); + if (!buff) + return -ENOMEM; + + desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id); + desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n", + lq_sta->total_failed, lq_sta->total_success, + lq_sta->active_legacy_rate); + desc += sprintf(buff+desc, "fixed rate 0x%X\n", + lq_sta->dbg_fixed_rate); + desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", + (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "", + (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "", + (priv->hw_params.valid_tx_ant & ANT_C) ? "ANT_C" : ""); + desc += sprintf(buff+desc, "lq type %s\n", + (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); + if (is_Ht(tbl->lq_type)) { + desc += sprintf(buff+desc, " %s", + (is_siso(tbl->lq_type)) ? "SISO" : "MIMO2"); + desc += sprintf(buff+desc, " %s", + (tbl->is_ht40) ? "40MHz" : "20MHz"); + desc += sprintf(buff+desc, " %s %s %s\n", + (tbl->is_SGI) ? "SGI" : "", + (lq_sta->is_green) ? "GF enabled" : "", + (lq_sta->is_agg) ? "AGG on" : ""); + } + desc += sprintf(buff+desc, "last tx rate=0x%X\n", + lq_sta->last_rate_n_flags); + desc += sprintf(buff+desc, "general:" + "flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n", + lq_sta->lq.general_params.flags, + lq_sta->lq.general_params.mimo_delimiter, + lq_sta->lq.general_params.single_stream_ant_msk, + lq_sta->lq.general_params.dual_stream_ant_msk); + + desc += sprintf(buff+desc, "agg:" + "time_limit=%d dist_start_th=%d frame_cnt_limit=%d\n", + le16_to_cpu(lq_sta->lq.agg_params.agg_time_limit), + lq_sta->lq.agg_params.agg_dis_start_th, + lq_sta->lq.agg_params.agg_frame_cnt_limit); + + desc += sprintf(buff+desc, + "Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n", + lq_sta->lq.general_params.start_rate_index[0], + lq_sta->lq.general_params.start_rate_index[1], + lq_sta->lq.general_params.start_rate_index[2], + lq_sta->lq.general_params.start_rate_index[3]); + + for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { + index = iwl4965_hwrate_to_plcp_idx( + le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags)); + if (is_legacy(tbl->lq_type)) { + desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps\n", + i, + le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags), + iwl_rate_mcs[index].mbps); + } else { + desc += sprintf(buff+desc, + " rate[%d] 0x%X %smbps (%s)\n", + i, + le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags), + iwl_rate_mcs[index].mbps, iwl_rate_mcs[index].mcs); + } + } + + ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); + kfree(buff); + return ret; +} + +static const struct file_operations rs_sta_dbgfs_scale_table_ops = { + .write = iwl4965_rs_sta_dbgfs_scale_table_write, + .read = iwl4965_rs_sta_dbgfs_scale_table_read, + .open = iwl4965_open_file_generic, + .llseek = default_llseek, +}; +static ssize_t iwl4965_rs_sta_dbgfs_stats_table_read(struct file *file, + char __user *user_buf, size_t count, loff_t *ppos) +{ + char *buff; + int desc = 0; + int i, j; + ssize_t ret; + + struct iwl_lq_sta *lq_sta = file->private_data; + + buff = kmalloc(1024, GFP_KERNEL); + if (!buff) + return -ENOMEM; + + for (i = 0; i < LQ_SIZE; i++) { + desc += sprintf(buff+desc, + "%s type=%d SGI=%d HT40=%d DUP=%d GF=%d\n" + "rate=0x%X\n", + lq_sta->active_tbl == i ? "*" : "x", + lq_sta->lq_info[i].lq_type, + lq_sta->lq_info[i].is_SGI, + lq_sta->lq_info[i].is_ht40, + lq_sta->lq_info[i].is_dup, + lq_sta->is_green, + lq_sta->lq_info[i].current_rate); + for (j = 0; j < IWL_RATE_COUNT; j++) { + desc += sprintf(buff+desc, + "counter=%d success=%d %%=%d\n", + lq_sta->lq_info[i].win[j].counter, + lq_sta->lq_info[i].win[j].success_counter, + lq_sta->lq_info[i].win[j].success_ratio); + } + } + ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); + kfree(buff); + return ret; +} + +static const struct file_operations rs_sta_dbgfs_stats_table_ops = { + .read = iwl4965_rs_sta_dbgfs_stats_table_read, + .open = iwl4965_open_file_generic, + .llseek = default_llseek, +}; + +static ssize_t iwl4965_rs_sta_dbgfs_rate_scale_data_read(struct file *file, + char __user *user_buf, size_t count, loff_t *ppos) +{ + char buff[120]; + int desc = 0; + ssize_t ret; + + struct iwl_lq_sta *lq_sta = file->private_data; + struct iwl_priv *priv; + struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl]; + + priv = lq_sta->drv; + + if (is_Ht(tbl->lq_type)) + desc += sprintf(buff+desc, + "Bit Rate= %d Mb/s\n", + tbl->expected_tpt[lq_sta->last_txrate_idx]); + else + desc += sprintf(buff+desc, + "Bit Rate= %d Mb/s\n", + iwl_rates[lq_sta->last_txrate_idx].ieee >> 1); + + ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); + return ret; +} + +static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = { + .read = iwl4965_rs_sta_dbgfs_rate_scale_data_read, + .open = iwl4965_open_file_generic, + .llseek = default_llseek, +}; + +static void iwl4965_rs_add_debugfs(void *priv, void *priv_sta, + struct dentry *dir) +{ + struct iwl_lq_sta *lq_sta = priv_sta; + lq_sta->rs_sta_dbgfs_scale_table_file = + debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir, + lq_sta, &rs_sta_dbgfs_scale_table_ops); + lq_sta->rs_sta_dbgfs_stats_table_file = + debugfs_create_file("rate_stats_table", S_IRUSR, dir, + lq_sta, &rs_sta_dbgfs_stats_table_ops); + lq_sta->rs_sta_dbgfs_rate_scale_data_file = + debugfs_create_file("rate_scale_data", S_IRUSR, dir, + lq_sta, &rs_sta_dbgfs_rate_scale_data_ops); + lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = + debugfs_create_u8("tx_agg_tid_enable", S_IRUSR | S_IWUSR, dir, + &lq_sta->tx_agg_tid_en); + +} + +static void iwl4965_rs_remove_debugfs(void *priv, void *priv_sta) +{ + struct iwl_lq_sta *lq_sta = priv_sta; + debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); + debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); + debugfs_remove(lq_sta->rs_sta_dbgfs_rate_scale_data_file); + debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file); +} +#endif + +/* + * Initialization of rate scaling information is done by driver after + * the station is added. Since mac80211 calls this function before a + * station is added we ignore it. + */ +static void +iwl4965_rs_rate_init_stub(void *priv_r, struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta) +{ +} +static struct rate_control_ops rs_4965_ops = { + .module = NULL, + .name = IWL4965_RS_NAME, + .tx_status = iwl4965_rs_tx_status, + .get_rate = iwl4965_rs_get_rate, + .rate_init = iwl4965_rs_rate_init_stub, + .alloc = iwl4965_rs_alloc, + .free = iwl4965_rs_free, + .alloc_sta = iwl4965_rs_alloc_sta, + .free_sta = iwl4965_rs_free_sta, +#ifdef CONFIG_MAC80211_DEBUGFS + .add_sta_debugfs = iwl4965_rs_add_debugfs, + .remove_sta_debugfs = iwl4965_rs_remove_debugfs, +#endif +}; + +int iwl4965_rate_control_register(void) +{ + pr_err("Registering 4965 rate control operations\n"); + return ieee80211_rate_control_register(&rs_4965_ops); +} + +void iwl4965_rate_control_unregister(void) +{ + ieee80211_rate_control_unregister(&rs_4965_ops); +} diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-rx.c b/drivers/net/wireless/iwlegacy/iwl-4965-rx.c new file mode 100644 index 000000000000..b9fa2f6411a7 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-4965-rx.c @@ -0,0 +1,291 @@ +/****************************************************************************** + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include +#include + +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-4965-calib.h" +#include "iwl-sta.h" +#include "iwl-io.h" +#include "iwl-helpers.h" +#include "iwl-4965-hw.h" +#include "iwl-4965.h" + +void iwl4965_rx_missed_beacon_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) + +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_missed_beacon_notif *missed_beacon; + + missed_beacon = &pkt->u.missed_beacon; + if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) > + priv->missed_beacon_threshold) { + IWL_DEBUG_CALIB(priv, + "missed bcn cnsq %d totl %d rcd %d expctd %d\n", + le32_to_cpu(missed_beacon->consecutive_missed_beacons), + le32_to_cpu(missed_beacon->total_missed_becons), + le32_to_cpu(missed_beacon->num_recvd_beacons), + le32_to_cpu(missed_beacon->num_expected_beacons)); + if (!test_bit(STATUS_SCANNING, &priv->status)) + iwl4965_init_sensitivity(priv); + } +} + +/* Calculate noise level, based on measurements during network silence just + * before arriving beacon. This measurement can be done only if we know + * exactly when to expect beacons, therefore only when we're associated. */ +static void iwl4965_rx_calc_noise(struct iwl_priv *priv) +{ + struct statistics_rx_non_phy *rx_info; + int num_active_rx = 0; + int total_silence = 0; + int bcn_silence_a, bcn_silence_b, bcn_silence_c; + int last_rx_noise; + + rx_info = &(priv->_4965.statistics.rx.general); + bcn_silence_a = + le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; + bcn_silence_b = + le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER; + bcn_silence_c = + le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER; + + if (bcn_silence_a) { + total_silence += bcn_silence_a; + num_active_rx++; + } + if (bcn_silence_b) { + total_silence += bcn_silence_b; + num_active_rx++; + } + if (bcn_silence_c) { + total_silence += bcn_silence_c; + num_active_rx++; + } + + /* Average among active antennas */ + if (num_active_rx) + last_rx_noise = (total_silence / num_active_rx) - 107; + else + last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; + + IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n", + bcn_silence_a, bcn_silence_b, bcn_silence_c, + last_rx_noise); +} + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS +/* + * based on the assumption of all statistics counter are in DWORD + * FIXME: This function is for debugging, do not deal with + * the case of counters roll-over. + */ +static void iwl4965_accumulative_statistics(struct iwl_priv *priv, + __le32 *stats) +{ + int i, size; + __le32 *prev_stats; + u32 *accum_stats; + u32 *delta, *max_delta; + struct statistics_general_common *general, *accum_general; + struct statistics_tx *tx, *accum_tx; + + prev_stats = (__le32 *)&priv->_4965.statistics; + accum_stats = (u32 *)&priv->_4965.accum_statistics; + size = sizeof(struct iwl_notif_statistics); + general = &priv->_4965.statistics.general.common; + accum_general = &priv->_4965.accum_statistics.general.common; + tx = &priv->_4965.statistics.tx; + accum_tx = &priv->_4965.accum_statistics.tx; + delta = (u32 *)&priv->_4965.delta_statistics; + max_delta = (u32 *)&priv->_4965.max_delta; + + for (i = sizeof(__le32); i < size; + i += sizeof(__le32), stats++, prev_stats++, delta++, + max_delta++, accum_stats++) { + if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { + *delta = (le32_to_cpu(*stats) - + le32_to_cpu(*prev_stats)); + *accum_stats += *delta; + if (*delta > *max_delta) + *max_delta = *delta; + } + } + + /* reset accumulative statistics for "no-counter" type statistics */ + accum_general->temperature = general->temperature; + accum_general->ttl_timestamp = general->ttl_timestamp; +} +#endif + +#define REG_RECALIB_PERIOD (60) + +/** + * iwl4965_good_plcp_health - checks for plcp error. + * + * When the plcp error is exceeding the thresholds, reset the radio + * to improve the throughput. + */ +bool iwl4965_good_plcp_health(struct iwl_priv *priv, + struct iwl_rx_packet *pkt) +{ + bool rc = true; + int combined_plcp_delta; + unsigned int plcp_msec; + unsigned long plcp_received_jiffies; + + if (priv->cfg->base_params->plcp_delta_threshold == + IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { + IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); + return rc; + } + + /* + * check for plcp_err and trigger radio reset if it exceeds + * the plcp error threshold plcp_delta. + */ + plcp_received_jiffies = jiffies; + plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - + (long) priv->plcp_jiffies); + priv->plcp_jiffies = plcp_received_jiffies; + /* + * check to make sure plcp_msec is not 0 to prevent division + * by zero. + */ + if (plcp_msec) { + struct statistics_rx_phy *ofdm; + struct statistics_rx_ht_phy *ofdm_ht; + + ofdm = &pkt->u.stats.rx.ofdm; + ofdm_ht = &pkt->u.stats.rx.ofdm_ht; + combined_plcp_delta = + (le32_to_cpu(ofdm->plcp_err) - + le32_to_cpu(priv->_4965.statistics. + rx.ofdm.plcp_err)) + + (le32_to_cpu(ofdm_ht->plcp_err) - + le32_to_cpu(priv->_4965.statistics. + rx.ofdm_ht.plcp_err)); + + if ((combined_plcp_delta > 0) && + ((combined_plcp_delta * 100) / plcp_msec) > + priv->cfg->base_params->plcp_delta_threshold) { + /* + * if plcp_err exceed the threshold, + * the following data is printed in csv format: + * Text: plcp_err exceeded %d, + * Received ofdm.plcp_err, + * Current ofdm.plcp_err, + * Received ofdm_ht.plcp_err, + * Current ofdm_ht.plcp_err, + * combined_plcp_delta, + * plcp_msec + */ + IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " + "%u, %u, %u, %u, %d, %u mSecs\n", + priv->cfg->base_params->plcp_delta_threshold, + le32_to_cpu(ofdm->plcp_err), + le32_to_cpu(ofdm->plcp_err), + le32_to_cpu(ofdm_ht->plcp_err), + le32_to_cpu(ofdm_ht->plcp_err), + combined_plcp_delta, plcp_msec); + + rc = false; + } + } + return rc; +} + +void iwl4965_rx_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + int change; + struct iwl_rx_packet *pkt = rxb_addr(rxb); + + IWL_DEBUG_RX(priv, + "Statistics notification received (%d vs %d).\n", + (int)sizeof(struct iwl_notif_statistics), + le32_to_cpu(pkt->len_n_flags) & + FH_RSCSR_FRAME_SIZE_MSK); + + change = ((priv->_4965.statistics.general.common.temperature != + pkt->u.stats.general.common.temperature) || + ((priv->_4965.statistics.flag & + STATISTICS_REPLY_FLG_HT40_MODE_MSK) != + (pkt->u.stats.flag & + STATISTICS_REPLY_FLG_HT40_MODE_MSK))); +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS + iwl4965_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); +#endif + + iwl_legacy_recover_from_statistics(priv, pkt); + + memcpy(&priv->_4965.statistics, &pkt->u.stats, + sizeof(priv->_4965.statistics)); + + set_bit(STATUS_STATISTICS, &priv->status); + + /* Reschedule the statistics timer to occur in + * REG_RECALIB_PERIOD seconds to ensure we get a + * thermal update even if the uCode doesn't give + * us one */ + mod_timer(&priv->statistics_periodic, jiffies + + msecs_to_jiffies(REG_RECALIB_PERIOD * 1000)); + + if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && + (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { + iwl4965_rx_calc_noise(priv); + queue_work(priv->workqueue, &priv->run_time_calib_work); + } + if (priv->cfg->ops->lib->temp_ops.temperature && change) + priv->cfg->ops->lib->temp_ops.temperature(priv); +} + +void iwl4965_reply_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + + if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS + memset(&priv->_4965.accum_statistics, 0, + sizeof(struct iwl_notif_statistics)); + memset(&priv->_4965.delta_statistics, 0, + sizeof(struct iwl_notif_statistics)); + memset(&priv->_4965.max_delta, 0, + sizeof(struct iwl_notif_statistics)); +#endif + IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); + } + iwl4965_rx_statistics(priv, rxb); +} diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-sta.c b/drivers/net/wireless/iwlegacy/iwl-4965-sta.c new file mode 100644 index 000000000000..057da2c3bf95 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-4965-sta.c @@ -0,0 +1,720 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include + +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-sta.h" +#include "iwl-4965.h" + +static struct iwl_link_quality_cmd * +iwl4965_sta_alloc_lq(struct iwl_priv *priv, u8 sta_id) +{ + int i, r; + struct iwl_link_quality_cmd *link_cmd; + u32 rate_flags = 0; + __le32 rate_n_flags; + + link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL); + if (!link_cmd) { + IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n"); + return NULL; + } + /* Set up the rate scaling to start at selected rate, fall back + * all the way down to 1M in IEEE order, and then spin on 1M */ + if (priv->band == IEEE80211_BAND_5GHZ) + r = IWL_RATE_6M_INDEX; + else + r = IWL_RATE_1M_INDEX; + + if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) + rate_flags |= RATE_MCS_CCK_MSK; + + rate_flags |= iwl4965_first_antenna(priv->hw_params.valid_tx_ant) << + RATE_MCS_ANT_POS; + rate_n_flags = iwl4965_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); + for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) + link_cmd->rs_table[i].rate_n_flags = rate_n_flags; + + link_cmd->general_params.single_stream_ant_msk = + iwl4965_first_antenna(priv->hw_params.valid_tx_ant); + + link_cmd->general_params.dual_stream_ant_msk = + priv->hw_params.valid_tx_ant & + ~iwl4965_first_antenna(priv->hw_params.valid_tx_ant); + if (!link_cmd->general_params.dual_stream_ant_msk) { + link_cmd->general_params.dual_stream_ant_msk = ANT_AB; + } else if (iwl4965_num_of_ant(priv->hw_params.valid_tx_ant) == 2) { + link_cmd->general_params.dual_stream_ant_msk = + priv->hw_params.valid_tx_ant; + } + + link_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; + link_cmd->agg_params.agg_time_limit = + cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); + + link_cmd->sta_id = sta_id; + + return link_cmd; +} + +/* + * iwl4965_add_bssid_station - Add the special IBSS BSSID station + * + * Function sleeps. + */ +int +iwl4965_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + const u8 *addr, u8 *sta_id_r) +{ + int ret; + u8 sta_id; + struct iwl_link_quality_cmd *link_cmd; + unsigned long flags; + + if (sta_id_r) + *sta_id_r = IWL_INVALID_STATION; + + ret = iwl_legacy_add_station_common(priv, ctx, addr, 0, NULL, &sta_id); + if (ret) { + IWL_ERR(priv, "Unable to add station %pM\n", addr); + return ret; + } + + if (sta_id_r) + *sta_id_r = sta_id; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].used |= IWL_STA_LOCAL; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + /* Set up default rate scaling table in device's station table */ + link_cmd = iwl4965_sta_alloc_lq(priv, sta_id); + if (!link_cmd) { + IWL_ERR(priv, + "Unable to initialize rate scaling for station %pM.\n", + addr); + return -ENOMEM; + } + + ret = iwl_legacy_send_lq_cmd(priv, ctx, link_cmd, CMD_SYNC, true); + if (ret) + IWL_ERR(priv, "Link quality command failed (%d)\n", ret); + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].lq = link_cmd; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return 0; +} + +static int iwl4965_static_wepkey_cmd(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + bool send_if_empty) +{ + int i, not_empty = 0; + u8 buff[sizeof(struct iwl_wep_cmd) + + sizeof(struct iwl_wep_key) * WEP_KEYS_MAX]; + struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff; + size_t cmd_size = sizeof(struct iwl_wep_cmd); + struct iwl_host_cmd cmd = { + .id = ctx->wep_key_cmd, + .data = wep_cmd, + .flags = CMD_SYNC, + }; + + might_sleep(); + + memset(wep_cmd, 0, cmd_size + + (sizeof(struct iwl_wep_key) * WEP_KEYS_MAX)); + + for (i = 0; i < WEP_KEYS_MAX ; i++) { + wep_cmd->key[i].key_index = i; + if (ctx->wep_keys[i].key_size) { + wep_cmd->key[i].key_offset = i; + not_empty = 1; + } else { + wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET; + } + + wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size; + memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key, + ctx->wep_keys[i].key_size); + } + + wep_cmd->global_key_type = WEP_KEY_WEP_TYPE; + wep_cmd->num_keys = WEP_KEYS_MAX; + + cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX; + + cmd.len = cmd_size; + + if (not_empty || send_if_empty) + return iwl_legacy_send_cmd(priv, &cmd); + else + return 0; +} + +int iwl4965_restore_default_wep_keys(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + lockdep_assert_held(&priv->mutex); + + return iwl4965_static_wepkey_cmd(priv, ctx, false); +} + +int iwl4965_remove_default_wep_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf) +{ + int ret; + + lockdep_assert_held(&priv->mutex); + + IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", + keyconf->keyidx); + + memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0])); + if (iwl_legacy_is_rfkill(priv)) { + IWL_DEBUG_WEP(priv, + "Not sending REPLY_WEPKEY command due to RFKILL.\n"); + /* but keys in device are clear anyway so return success */ + return 0; + } + ret = iwl4965_static_wepkey_cmd(priv, ctx, 1); + IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n", + keyconf->keyidx, ret); + + return ret; +} + +int iwl4965_set_default_wep_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf) +{ + int ret; + + lockdep_assert_held(&priv->mutex); + + if (keyconf->keylen != WEP_KEY_LEN_128 && + keyconf->keylen != WEP_KEY_LEN_64) { + IWL_DEBUG_WEP(priv, "Bad WEP key length %d\n", keyconf->keylen); + return -EINVAL; + } + + keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; + keyconf->hw_key_idx = HW_KEY_DEFAULT; + priv->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher; + + ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; + memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key, + keyconf->keylen); + + ret = iwl4965_static_wepkey_cmd(priv, ctx, false); + IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n", + keyconf->keylen, keyconf->keyidx, ret); + + return ret; +} + +static int iwl4965_set_wep_dynamic_key_info(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + unsigned long flags; + __le16 key_flags = 0; + struct iwl_legacy_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); + + keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; + + key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK); + key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); + key_flags &= ~STA_KEY_FLG_INVALID; + + if (keyconf->keylen == WEP_KEY_LEN_128) + key_flags |= STA_KEY_FLG_KEY_SIZE_MSK; + + if (sta_id == ctx->bcast_sta_id) + key_flags |= STA_KEY_MULTICAST_MSK; + + spin_lock_irqsave(&priv->sta_lock, flags); + + priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; + priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; + priv->stations[sta_id].keyinfo.keyidx = keyconf->keyidx; + + memcpy(priv->stations[sta_id].keyinfo.key, + keyconf->key, keyconf->keylen); + + memcpy(&priv->stations[sta_id].sta.key.key[3], + keyconf->key, keyconf->keylen); + + if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) + == STA_KEY_FLG_NO_ENC) + priv->stations[sta_id].sta.key.key_offset = + iwl_legacy_get_free_ucode_key_index(priv); + /* else, we are overriding an existing key => no need to allocated room + * in uCode. */ + + WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, + "no space for a new key"); + + priv->stations[sta_id].sta.key.key_flags = key_flags; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + + memcpy(&sta_cmd, &priv->stations[sta_id].sta, + sizeof(struct iwl_legacy_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return iwl_legacy_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +static int iwl4965_set_ccmp_dynamic_key_info(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + unsigned long flags; + __le16 key_flags = 0; + struct iwl_legacy_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); + + key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); + key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); + key_flags &= ~STA_KEY_FLG_INVALID; + + if (sta_id == ctx->bcast_sta_id) + key_flags |= STA_KEY_MULTICAST_MSK; + + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; + priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; + + memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, + keyconf->keylen); + + memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, + keyconf->keylen); + + if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) + == STA_KEY_FLG_NO_ENC) + priv->stations[sta_id].sta.key.key_offset = + iwl_legacy_get_free_ucode_key_index(priv); + /* else, we are overriding an existing key => no need to allocated room + * in uCode. */ + + WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, + "no space for a new key"); + + priv->stations[sta_id].sta.key.key_flags = key_flags; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + + memcpy(&sta_cmd, &priv->stations[sta_id].sta, + sizeof(struct iwl_legacy_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return iwl_legacy_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +static int iwl4965_set_tkip_dynamic_key_info(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + unsigned long flags; + int ret = 0; + __le16 key_flags = 0; + + key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK); + key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); + key_flags &= ~STA_KEY_FLG_INVALID; + + if (sta_id == ctx->bcast_sta_id) + key_flags |= STA_KEY_MULTICAST_MSK; + + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + + spin_lock_irqsave(&priv->sta_lock, flags); + + priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; + priv->stations[sta_id].keyinfo.keylen = 16; + + if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) + == STA_KEY_FLG_NO_ENC) + priv->stations[sta_id].sta.key.key_offset = + iwl_legacy_get_free_ucode_key_index(priv); + /* else, we are overriding an existing key => no need to allocated room + * in uCode. */ + + WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, + "no space for a new key"); + + priv->stations[sta_id].sta.key.key_flags = key_flags; + + + /* This copy is acutally not needed: we get the key with each TX */ + memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16); + + memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16); + + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return ret; +} + +void iwl4965_update_tkip_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + struct ieee80211_sta *sta, u32 iv32, u16 *phase1key) +{ + u8 sta_id; + unsigned long flags; + int i; + + if (iwl_legacy_scan_cancel(priv)) { + /* cancel scan failed, just live w/ bad key and rely + briefly on SW decryption */ + return; + } + + sta_id = iwl_legacy_sta_id_or_broadcast(priv, ctx, sta); + if (sta_id == IWL_INVALID_STATION) + return; + + spin_lock_irqsave(&priv->sta_lock, flags); + + priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32; + + for (i = 0; i < 5; i++) + priv->stations[sta_id].sta.key.tkip_rx_ttak[i] = + cpu_to_le16(phase1key[i]); + + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + + iwl_legacy_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); + + spin_unlock_irqrestore(&priv->sta_lock, flags); + +} + +int iwl4965_remove_dynamic_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + unsigned long flags; + u16 key_flags; + u8 keyidx; + struct iwl_legacy_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); + + ctx->key_mapping_keys--; + + spin_lock_irqsave(&priv->sta_lock, flags); + key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags); + keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3; + + IWL_DEBUG_WEP(priv, "Remove dynamic key: idx=%d sta=%d\n", + keyconf->keyidx, sta_id); + + if (keyconf->keyidx != keyidx) { + /* We need to remove a key with index different that the one + * in the uCode. This means that the key we need to remove has + * been replaced by another one with different index. + * Don't do anything and return ok + */ + spin_unlock_irqrestore(&priv->sta_lock, flags); + return 0; + } + + if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) { + IWL_WARN(priv, "Removing wrong key %d 0x%x\n", + keyconf->keyidx, key_flags); + spin_unlock_irqrestore(&priv->sta_lock, flags); + return 0; + } + + if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset, + &priv->ucode_key_table)) + IWL_ERR(priv, "index %d not used in uCode key table.\n", + priv->stations[sta_id].sta.key.key_offset); + memset(&priv->stations[sta_id].keyinfo, 0, + sizeof(struct iwl_hw_key)); + memset(&priv->stations[sta_id].sta.key, 0, + sizeof(struct iwl4965_keyinfo)); + priv->stations[sta_id].sta.key.key_flags = + STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID; + priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + + if (iwl_legacy_is_rfkill(priv)) { + IWL_DEBUG_WEP(priv, + "Not sending REPLY_ADD_STA command because RFKILL enabled.\n"); + spin_unlock_irqrestore(&priv->sta_lock, flags); + return 0; + } + memcpy(&sta_cmd, &priv->stations[sta_id].sta, + sizeof(struct iwl_legacy_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return iwl_legacy_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +int iwl4965_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, u8 sta_id) +{ + int ret; + + lockdep_assert_held(&priv->mutex); + + ctx->key_mapping_keys++; + keyconf->hw_key_idx = HW_KEY_DYNAMIC; + + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_CCMP: + ret = iwl4965_set_ccmp_dynamic_key_info(priv, ctx, + keyconf, sta_id); + break; + case WLAN_CIPHER_SUITE_TKIP: + ret = iwl4965_set_tkip_dynamic_key_info(priv, ctx, + keyconf, sta_id); + break; + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + ret = iwl4965_set_wep_dynamic_key_info(priv, ctx, + keyconf, sta_id); + break; + default: + IWL_ERR(priv, + "Unknown alg: %s cipher = %x\n", __func__, + keyconf->cipher); + ret = -EINVAL; + } + + IWL_DEBUG_WEP(priv, + "Set dynamic key: cipher=%x len=%d idx=%d sta=%d ret=%d\n", + keyconf->cipher, keyconf->keylen, keyconf->keyidx, + sta_id, ret); + + return ret; +} + +/** + * iwl4965_alloc_bcast_station - add broadcast station into driver's station table. + * + * This adds the broadcast station into the driver's station table + * and marks it driver active, so that it will be restored to the + * device at the next best time. + */ +int iwl4965_alloc_bcast_station(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + struct iwl_link_quality_cmd *link_cmd; + unsigned long flags; + u8 sta_id; + + spin_lock_irqsave(&priv->sta_lock, flags); + sta_id = iwl_legacy_prep_station(priv, ctx, iwl_bcast_addr, + false, NULL); + if (sta_id == IWL_INVALID_STATION) { + IWL_ERR(priv, "Unable to prepare broadcast station\n"); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return -EINVAL; + } + + priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; + priv->stations[sta_id].used |= IWL_STA_BCAST; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + link_cmd = iwl4965_sta_alloc_lq(priv, sta_id); + if (!link_cmd) { + IWL_ERR(priv, + "Unable to initialize rate scaling for bcast station.\n"); + return -ENOMEM; + } + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].lq = link_cmd; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return 0; +} + +/** + * iwl4965_update_bcast_station - update broadcast station's LQ command + * + * Only used by iwl4965. Placed here to have all bcast station management + * code together. + */ +static int iwl4965_update_bcast_station(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + unsigned long flags; + struct iwl_link_quality_cmd *link_cmd; + u8 sta_id = ctx->bcast_sta_id; + + link_cmd = iwl4965_sta_alloc_lq(priv, sta_id); + if (!link_cmd) { + IWL_ERR(priv, + "Unable to initialize rate scaling for bcast station.\n"); + return -ENOMEM; + } + + spin_lock_irqsave(&priv->sta_lock, flags); + if (priv->stations[sta_id].lq) + kfree(priv->stations[sta_id].lq); + else + IWL_DEBUG_INFO(priv, + "Bcast station rate scaling has not been initialized yet.\n"); + priv->stations[sta_id].lq = link_cmd; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return 0; +} + +int iwl4965_update_bcast_stations(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx; + int ret = 0; + + for_each_context(priv, ctx) { + ret = iwl4965_update_bcast_station(priv, ctx); + if (ret) + break; + } + + return ret; +} + +/** + * iwl4965_sta_tx_modify_enable_tid - Enable Tx for this TID in station table + */ +int iwl4965_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) +{ + unsigned long flags; + struct iwl_legacy_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); + + /* Remove "disable" flag, to enable Tx for this TID */ + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; + priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + memcpy(&sta_cmd, &priv->stations[sta_id].sta, + sizeof(struct iwl_legacy_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return iwl_legacy_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +int iwl4965_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, + int tid, u16 ssn) +{ + unsigned long flags; + int sta_id; + struct iwl_legacy_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); + + sta_id = iwl_legacy_sta_id(sta); + if (sta_id == IWL_INVALID_STATION) + return -ENXIO; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].sta.station_flags_msk = 0; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK; + priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid; + priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn); + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + memcpy(&sta_cmd, &priv->stations[sta_id].sta, + sizeof(struct iwl_legacy_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return iwl_legacy_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +int iwl4965_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, + int tid) +{ + unsigned long flags; + int sta_id; + struct iwl_legacy_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); + + sta_id = iwl_legacy_sta_id(sta); + if (sta_id == IWL_INVALID_STATION) { + IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid); + return -ENXIO; + } + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].sta.station_flags_msk = 0; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; + priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + memcpy(&sta_cmd, &priv->stations[sta_id].sta, + sizeof(struct iwl_legacy_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return iwl_legacy_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +void +iwl4965_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK; + priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; + priv->stations[sta_id].sta.sta.modify_mask = + STA_MODIFY_SLEEP_TX_COUNT_MSK; + priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt); + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + iwl_legacy_send_add_sta(priv, + &priv->stations[sta_id].sta, CMD_ASYNC); + spin_unlock_irqrestore(&priv->sta_lock, flags); + +} diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-tx.c b/drivers/net/wireless/iwlegacy/iwl-4965-tx.c new file mode 100644 index 000000000000..2e0f0dbf87ec --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-4965-tx.c @@ -0,0 +1,1359 @@ +/****************************************************************************** + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include +#include + +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-sta.h" +#include "iwl-io.h" +#include "iwl-helpers.h" +#include "iwl-4965-hw.h" +#include "iwl-4965.h" + +/* + * mac80211 queues, ACs, hardware queues, FIFOs. + * + * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues + * + * Mac80211 uses the following numbers, which we get as from it + * by way of skb_get_queue_mapping(skb): + * + * VO 0 + * VI 1 + * BE 2 + * BK 3 + * + * + * Regular (not A-MPDU) frames are put into hardware queues corresponding + * to the FIFOs, see comments in iwl-prph.h. Aggregated frames get their + * own queue per aggregation session (RA/TID combination), such queues are + * set up to map into FIFOs too, for which we need an AC->FIFO mapping. In + * order to map frames to the right queue, we also need an AC->hw queue + * mapping. This is implemented here. + * + * Due to the way hw queues are set up (by the hw specific modules like + * iwl-4965.c), the AC->hw queue mapping is the identity + * mapping. + */ + +static const u8 tid_to_ac[] = { + IEEE80211_AC_BE, + IEEE80211_AC_BK, + IEEE80211_AC_BK, + IEEE80211_AC_BE, + IEEE80211_AC_VI, + IEEE80211_AC_VI, + IEEE80211_AC_VO, + IEEE80211_AC_VO +}; + +static inline int iwl4965_get_ac_from_tid(u16 tid) +{ + if (likely(tid < ARRAY_SIZE(tid_to_ac))) + return tid_to_ac[tid]; + + /* no support for TIDs 8-15 yet */ + return -EINVAL; +} + +static inline int +iwl4965_get_fifo_from_tid(struct iwl_rxon_context *ctx, u16 tid) +{ + if (likely(tid < ARRAY_SIZE(tid_to_ac))) + return ctx->ac_to_fifo[tid_to_ac[tid]]; + + /* no support for TIDs 8-15 yet */ + return -EINVAL; +} + +/* + * handle build REPLY_TX command notification. + */ +static void iwl4965_tx_cmd_build_basic(struct iwl_priv *priv, + struct sk_buff *skb, + struct iwl_tx_cmd *tx_cmd, + struct ieee80211_tx_info *info, + struct ieee80211_hdr *hdr, + u8 std_id) +{ + __le16 fc = hdr->frame_control; + __le32 tx_flags = tx_cmd->tx_flags; + + tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { + tx_flags |= TX_CMD_FLG_ACK_MSK; + if (ieee80211_is_mgmt(fc)) + tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; + if (ieee80211_is_probe_resp(fc) && + !(le16_to_cpu(hdr->seq_ctrl) & 0xf)) + tx_flags |= TX_CMD_FLG_TSF_MSK; + } else { + tx_flags &= (~TX_CMD_FLG_ACK_MSK); + tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; + } + + if (ieee80211_is_back_req(fc)) + tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; + + tx_cmd->sta_id = std_id; + if (ieee80211_has_morefrags(fc)) + tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; + + if (ieee80211_is_data_qos(fc)) { + u8 *qc = ieee80211_get_qos_ctl(hdr); + tx_cmd->tid_tspec = qc[0] & 0xf; + tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; + } else { + tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; + } + + iwl_legacy_tx_cmd_protection(priv, info, fc, &tx_flags); + + tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); + if (ieee80211_is_mgmt(fc)) { + if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc)) + tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3); + else + tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2); + } else { + tx_cmd->timeout.pm_frame_timeout = 0; + } + + tx_cmd->driver_txop = 0; + tx_cmd->tx_flags = tx_flags; + tx_cmd->next_frame_len = 0; +} + +#define RTS_DFAULT_RETRY_LIMIT 60 + +static void iwl4965_tx_cmd_build_rate(struct iwl_priv *priv, + struct iwl_tx_cmd *tx_cmd, + struct ieee80211_tx_info *info, + __le16 fc) +{ + u32 rate_flags; + int rate_idx; + u8 rts_retry_limit; + u8 data_retry_limit; + u8 rate_plcp; + + /* Set retry limit on DATA packets and Probe Responses*/ + if (ieee80211_is_probe_resp(fc)) + data_retry_limit = 3; + else + data_retry_limit = IWL4965_DEFAULT_TX_RETRY; + tx_cmd->data_retry_limit = data_retry_limit; + + /* Set retry limit on RTS packets */ + rts_retry_limit = RTS_DFAULT_RETRY_LIMIT; + if (data_retry_limit < rts_retry_limit) + rts_retry_limit = data_retry_limit; + tx_cmd->rts_retry_limit = rts_retry_limit; + + /* DATA packets will use the uCode station table for rate/antenna + * selection */ + if (ieee80211_is_data(fc)) { + tx_cmd->initial_rate_index = 0; + tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; + return; + } + + /** + * If the current TX rate stored in mac80211 has the MCS bit set, it's + * not really a TX rate. Thus, we use the lowest supported rate for + * this band. Also use the lowest supported rate if the stored rate + * index is invalid. + */ + rate_idx = info->control.rates[0].idx; + if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS || + (rate_idx < 0) || (rate_idx > IWL_RATE_COUNT_LEGACY)) + rate_idx = rate_lowest_index(&priv->bands[info->band], + info->control.sta); + /* For 5 GHZ band, remap mac80211 rate indices into driver indices */ + if (info->band == IEEE80211_BAND_5GHZ) + rate_idx += IWL_FIRST_OFDM_RATE; + /* Get PLCP rate for tx_cmd->rate_n_flags */ + rate_plcp = iwl_rates[rate_idx].plcp; + /* Zero out flags for this packet */ + rate_flags = 0; + + /* Set CCK flag as needed */ + if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE)) + rate_flags |= RATE_MCS_CCK_MSK; + + /* Set up antennas */ + priv->mgmt_tx_ant = iwl4965_toggle_tx_ant(priv, priv->mgmt_tx_ant, + priv->hw_params.valid_tx_ant); + + rate_flags |= iwl4965_ant_idx_to_flags(priv->mgmt_tx_ant); + + /* Set the rate in the TX cmd */ + tx_cmd->rate_n_flags = iwl4965_hw_set_rate_n_flags(rate_plcp, rate_flags); +} + +static void iwl4965_tx_cmd_build_hwcrypto(struct iwl_priv *priv, + struct ieee80211_tx_info *info, + struct iwl_tx_cmd *tx_cmd, + struct sk_buff *skb_frag, + int sta_id) +{ + struct ieee80211_key_conf *keyconf = info->control.hw_key; + + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_CCMP: + tx_cmd->sec_ctl = TX_CMD_SEC_CCM; + memcpy(tx_cmd->key, keyconf->key, keyconf->keylen); + if (info->flags & IEEE80211_TX_CTL_AMPDU) + tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK; + IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n"); + break; + + case WLAN_CIPHER_SUITE_TKIP: + tx_cmd->sec_ctl = TX_CMD_SEC_TKIP; + ieee80211_get_tkip_key(keyconf, skb_frag, + IEEE80211_TKIP_P2_KEY, tx_cmd->key); + IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n"); + break; + + case WLAN_CIPHER_SUITE_WEP104: + tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128; + /* fall through */ + case WLAN_CIPHER_SUITE_WEP40: + tx_cmd->sec_ctl |= (TX_CMD_SEC_WEP | + (keyconf->keyidx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT); + + memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen); + + IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption " + "with key %d\n", keyconf->keyidx); + break; + + default: + IWL_ERR(priv, "Unknown encode cipher %x\n", keyconf->cipher); + break; + } +} + +/* + * start REPLY_TX command process + */ +int iwl4965_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_sta *sta = info->control.sta; + struct iwl_station_priv *sta_priv = NULL; + struct iwl_tx_queue *txq; + struct iwl_queue *q; + struct iwl_device_cmd *out_cmd; + struct iwl_cmd_meta *out_meta; + struct iwl_tx_cmd *tx_cmd; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + int txq_id; + dma_addr_t phys_addr; + dma_addr_t txcmd_phys; + dma_addr_t scratch_phys; + u16 len, firstlen, secondlen; + u16 seq_number = 0; + __le16 fc; + u8 hdr_len; + u8 sta_id; + u8 wait_write_ptr = 0; + u8 tid = 0; + u8 *qc = NULL; + unsigned long flags; + bool is_agg = false; + + if (info->control.vif) + ctx = iwl_legacy_rxon_ctx_from_vif(info->control.vif); + + spin_lock_irqsave(&priv->lock, flags); + if (iwl_legacy_is_rfkill(priv)) { + IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n"); + goto drop_unlock; + } + + fc = hdr->frame_control; + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + if (ieee80211_is_auth(fc)) + IWL_DEBUG_TX(priv, "Sending AUTH frame\n"); + else if (ieee80211_is_assoc_req(fc)) + IWL_DEBUG_TX(priv, "Sending ASSOC frame\n"); + else if (ieee80211_is_reassoc_req(fc)) + IWL_DEBUG_TX(priv, "Sending REASSOC frame\n"); +#endif + + hdr_len = ieee80211_hdrlen(fc); + + /* Find index into station table for destination station */ + sta_id = iwl_legacy_sta_id_or_broadcast(priv, ctx, info->control.sta); + if (sta_id == IWL_INVALID_STATION) { + IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", + hdr->addr1); + goto drop_unlock; + } + + IWL_DEBUG_TX(priv, "station Id %d\n", sta_id); + + if (sta) + sta_priv = (void *)sta->drv_priv; + + if (sta_priv && sta_priv->asleep && + (info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)) { + /* + * This sends an asynchronous command to the device, + * but we can rely on it being processed before the + * next frame is processed -- and the next frame to + * this station is the one that will consume this + * counter. + * For now set the counter to just 1 since we do not + * support uAPSD yet. + */ + iwl4965_sta_modify_sleep_tx_count(priv, sta_id, 1); + } + + /* + * Send this frame after DTIM -- there's a special queue + * reserved for this for contexts that support AP mode. + */ + if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { + txq_id = ctx->mcast_queue; + /* + * The microcode will clear the more data + * bit in the last frame it transmits. + */ + hdr->frame_control |= + cpu_to_le16(IEEE80211_FCTL_MOREDATA); + } else + txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)]; + + /* irqs already disabled/saved above when locking priv->lock */ + spin_lock(&priv->sta_lock); + + if (ieee80211_is_data_qos(fc)) { + qc = ieee80211_get_qos_ctl(hdr); + tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; + if (WARN_ON_ONCE(tid >= MAX_TID_COUNT)) { + spin_unlock(&priv->sta_lock); + goto drop_unlock; + } + seq_number = priv->stations[sta_id].tid[tid].seq_number; + seq_number &= IEEE80211_SCTL_SEQ; + hdr->seq_ctrl = hdr->seq_ctrl & + cpu_to_le16(IEEE80211_SCTL_FRAG); + hdr->seq_ctrl |= cpu_to_le16(seq_number); + seq_number += 0x10; + /* aggregation is on for this */ + if (info->flags & IEEE80211_TX_CTL_AMPDU && + priv->stations[sta_id].tid[tid].agg.state == IWL_AGG_ON) { + txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; + is_agg = true; + } + } + + txq = &priv->txq[txq_id]; + q = &txq->q; + + if (unlikely(iwl_legacy_queue_space(q) < q->high_mark)) { + spin_unlock(&priv->sta_lock); + goto drop_unlock; + } + + if (ieee80211_is_data_qos(fc)) { + priv->stations[sta_id].tid[tid].tfds_in_queue++; + if (!ieee80211_has_morefrags(fc)) + priv->stations[sta_id].tid[tid].seq_number = seq_number; + } + + spin_unlock(&priv->sta_lock); + + /* Set up driver data for this TFD */ + memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); + txq->txb[q->write_ptr].skb = skb; + txq->txb[q->write_ptr].ctx = ctx; + + /* Set up first empty entry in queue's array of Tx/cmd buffers */ + out_cmd = txq->cmd[q->write_ptr]; + out_meta = &txq->meta[q->write_ptr]; + tx_cmd = &out_cmd->cmd.tx; + memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); + memset(tx_cmd, 0, sizeof(struct iwl_tx_cmd)); + + /* + * Set up the Tx-command (not MAC!) header. + * Store the chosen Tx queue and TFD index within the sequence field; + * after Tx, uCode's Tx response will return this value so driver can + * locate the frame within the tx queue and do post-tx processing. + */ + out_cmd->hdr.cmd = REPLY_TX; + out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | + INDEX_TO_SEQ(q->write_ptr))); + + /* Copy MAC header from skb into command buffer */ + memcpy(tx_cmd->hdr, hdr, hdr_len); + + + /* Total # bytes to be transmitted */ + len = (u16)skb->len; + tx_cmd->len = cpu_to_le16(len); + + if (info->control.hw_key) + iwl4965_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id); + + /* TODO need this for burst mode later on */ + iwl4965_tx_cmd_build_basic(priv, skb, tx_cmd, info, hdr, sta_id); + iwl_legacy_dbg_log_tx_data_frame(priv, len, hdr); + + iwl4965_tx_cmd_build_rate(priv, tx_cmd, info, fc); + + iwl_legacy_update_stats(priv, true, fc, len); + /* + * Use the first empty entry in this queue's command buffer array + * to contain the Tx command and MAC header concatenated together + * (payload data will be in another buffer). + * Size of this varies, due to varying MAC header length. + * If end is not dword aligned, we'll have 2 extra bytes at the end + * of the MAC header (device reads on dword boundaries). + * We'll tell device about this padding later. + */ + len = sizeof(struct iwl_tx_cmd) + + sizeof(struct iwl_cmd_header) + hdr_len; + firstlen = (len + 3) & ~3; + + /* Tell NIC about any 2-byte padding after MAC header */ + if (firstlen != len) + tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK; + + /* Physical address of this Tx command's header (not MAC header!), + * within command buffer array. */ + txcmd_phys = pci_map_single(priv->pci_dev, + &out_cmd->hdr, firstlen, + PCI_DMA_BIDIRECTIONAL); + dma_unmap_addr_set(out_meta, mapping, txcmd_phys); + dma_unmap_len_set(out_meta, len, firstlen); + /* Add buffer containing Tx command and MAC(!) header to TFD's + * first entry */ + priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, + txcmd_phys, firstlen, 1, 0); + + if (!ieee80211_has_morefrags(hdr->frame_control)) { + txq->need_update = 1; + } else { + wait_write_ptr = 1; + txq->need_update = 0; + } + + /* Set up TFD's 2nd entry to point directly to remainder of skb, + * if any (802.11 null frames have no payload). */ + secondlen = skb->len - hdr_len; + if (secondlen > 0) { + phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, + secondlen, PCI_DMA_TODEVICE); + priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, + phys_addr, secondlen, + 0, 0); + } + + scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + + offsetof(struct iwl_tx_cmd, scratch); + + /* take back ownership of DMA buffer to enable update */ + pci_dma_sync_single_for_cpu(priv->pci_dev, txcmd_phys, + firstlen, PCI_DMA_BIDIRECTIONAL); + tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); + tx_cmd->dram_msb_ptr = iwl_legacy_get_dma_hi_addr(scratch_phys); + + IWL_DEBUG_TX(priv, "sequence nr = 0X%x\n", + le16_to_cpu(out_cmd->hdr.sequence)); + IWL_DEBUG_TX(priv, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); + iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd)); + iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len); + + /* Set up entry for this TFD in Tx byte-count array */ + if (info->flags & IEEE80211_TX_CTL_AMPDU) + priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, + le16_to_cpu(tx_cmd->len)); + + pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys, + firstlen, PCI_DMA_BIDIRECTIONAL); + + trace_iwlwifi_legacy_dev_tx(priv, + &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr], + sizeof(struct iwl_tfd), + &out_cmd->hdr, firstlen, + skb->data + hdr_len, secondlen); + + /* Tell device the write index *just past* this latest filled TFD */ + q->write_ptr = iwl_legacy_queue_inc_wrap(q->write_ptr, q->n_bd); + iwl_legacy_txq_update_write_ptr(priv, txq); + spin_unlock_irqrestore(&priv->lock, flags); + + /* + * At this point the frame is "transmitted" successfully + * and we will get a TX status notification eventually, + * regardless of the value of ret. "ret" only indicates + * whether or not we should update the write pointer. + */ + + /* + * Avoid atomic ops if it isn't an associated client. + * Also, if this is a packet for aggregation, don't + * increase the counter because the ucode will stop + * aggregation queues when their respective station + * goes to sleep. + */ + if (sta_priv && sta_priv->client && !is_agg) + atomic_inc(&sta_priv->pending_frames); + + if ((iwl_legacy_queue_space(q) < q->high_mark) && + priv->mac80211_registered) { + if (wait_write_ptr) { + spin_lock_irqsave(&priv->lock, flags); + txq->need_update = 1; + iwl_legacy_txq_update_write_ptr(priv, txq); + spin_unlock_irqrestore(&priv->lock, flags); + } else { + iwl_legacy_stop_queue(priv, txq); + } + } + + return 0; + +drop_unlock: + spin_unlock_irqrestore(&priv->lock, flags); + return -1; +} + +static inline int iwl4965_alloc_dma_ptr(struct iwl_priv *priv, + struct iwl_dma_ptr *ptr, size_t size) +{ + ptr->addr = dma_alloc_coherent(&priv->pci_dev->dev, size, &ptr->dma, + GFP_KERNEL); + if (!ptr->addr) + return -ENOMEM; + ptr->size = size; + return 0; +} + +static inline void iwl4965_free_dma_ptr(struct iwl_priv *priv, + struct iwl_dma_ptr *ptr) +{ + if (unlikely(!ptr->addr)) + return; + + dma_free_coherent(&priv->pci_dev->dev, ptr->size, ptr->addr, ptr->dma); + memset(ptr, 0, sizeof(*ptr)); +} + +/** + * iwl4965_hw_txq_ctx_free - Free TXQ Context + * + * Destroy all TX DMA queues and structures + */ +void iwl4965_hw_txq_ctx_free(struct iwl_priv *priv) +{ + int txq_id; + + /* Tx queues */ + if (priv->txq) { + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) + if (txq_id == priv->cmd_queue) + iwl_legacy_cmd_queue_free(priv); + else + iwl_legacy_tx_queue_free(priv, txq_id); + } + iwl4965_free_dma_ptr(priv, &priv->kw); + + iwl4965_free_dma_ptr(priv, &priv->scd_bc_tbls); + + /* free tx queue structure */ + iwl_legacy_txq_mem(priv); +} + +/** + * iwl4965_txq_ctx_alloc - allocate TX queue context + * Allocate all Tx DMA structures and initialize them + * + * @param priv + * @return error code + */ +int iwl4965_txq_ctx_alloc(struct iwl_priv *priv) +{ + int ret; + int txq_id, slots_num; + unsigned long flags; + + /* Free all tx/cmd queues and keep-warm buffer */ + iwl4965_hw_txq_ctx_free(priv); + + ret = iwl4965_alloc_dma_ptr(priv, &priv->scd_bc_tbls, + priv->hw_params.scd_bc_tbls_size); + if (ret) { + IWL_ERR(priv, "Scheduler BC Table allocation failed\n"); + goto error_bc_tbls; + } + /* Alloc keep-warm buffer */ + ret = iwl4965_alloc_dma_ptr(priv, &priv->kw, IWL_KW_SIZE); + if (ret) { + IWL_ERR(priv, "Keep Warm allocation failed\n"); + goto error_kw; + } + + /* allocate tx queue structure */ + ret = iwl_legacy_alloc_txq_mem(priv); + if (ret) + goto error; + + spin_lock_irqsave(&priv->lock, flags); + + /* Turn off all Tx DMA fifos */ + iwl4965_txq_set_sched(priv, 0); + + /* Tell NIC where to find the "keep warm" buffer */ + iwl_legacy_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); + + spin_unlock_irqrestore(&priv->lock, flags); + + /* Alloc and init all Tx queues, including the command queue (#4/#9) */ + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { + slots_num = (txq_id == priv->cmd_queue) ? + TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; + ret = iwl_legacy_tx_queue_init(priv, + &priv->txq[txq_id], slots_num, + txq_id); + if (ret) { + IWL_ERR(priv, "Tx %d queue init failed\n", txq_id); + goto error; + } + } + + return ret; + + error: + iwl4965_hw_txq_ctx_free(priv); + iwl4965_free_dma_ptr(priv, &priv->kw); + error_kw: + iwl4965_free_dma_ptr(priv, &priv->scd_bc_tbls); + error_bc_tbls: + return ret; +} + +void iwl4965_txq_ctx_reset(struct iwl_priv *priv) +{ + int txq_id, slots_num; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + + /* Turn off all Tx DMA fifos */ + iwl4965_txq_set_sched(priv, 0); + + /* Tell NIC where to find the "keep warm" buffer */ + iwl_legacy_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); + + spin_unlock_irqrestore(&priv->lock, flags); + + /* Alloc and init all Tx queues, including the command queue (#4) */ + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { + slots_num = txq_id == priv->cmd_queue ? + TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; + iwl_legacy_tx_queue_reset(priv, &priv->txq[txq_id], + slots_num, txq_id); + } +} + +/** + * iwl4965_txq_ctx_stop - Stop all Tx DMA channels + */ +void iwl4965_txq_ctx_stop(struct iwl_priv *priv) +{ + int ch; + unsigned long flags; + + /* Turn off all Tx DMA fifos */ + spin_lock_irqsave(&priv->lock, flags); + + iwl4965_txq_set_sched(priv, 0); + + /* Stop each Tx DMA channel, and wait for it to be idle */ + for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) { + iwl_legacy_write_direct32(priv, + FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); + if (iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG, + FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), + 1000)) + IWL_ERR(priv, "Failing on timeout while stopping" + " DMA channel %d [0x%08x]", ch, + iwl_legacy_read_direct32(priv, + FH_TSSR_TX_STATUS_REG)); + } + spin_unlock_irqrestore(&priv->lock, flags); +} + +/* + * Find first available (lowest unused) Tx Queue, mark it "active". + * Called only when finding queue for aggregation. + * Should never return anything < 7, because they should already + * be in use as EDCA AC (0-3), Command (4), reserved (5, 6) + */ +static int iwl4965_txq_ctx_activate_free(struct iwl_priv *priv) +{ + int txq_id; + + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) + if (!test_and_set_bit(txq_id, &priv->txq_ctx_active_msk)) + return txq_id; + return -1; +} + +/** + * iwl4965_tx_queue_stop_scheduler - Stop queue, but keep configuration + */ +static void iwl4965_tx_queue_stop_scheduler(struct iwl_priv *priv, + u16 txq_id) +{ + /* Simply stop the queue, but don't change any configuration; + * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ + iwl_legacy_write_prph(priv, + IWL49_SCD_QUEUE_STATUS_BITS(txq_id), + (0 << IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE)| + (1 << IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); +} + +/** + * iwl4965_tx_queue_set_q2ratid - Map unique receiver/tid combination to a queue + */ +static int iwl4965_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid, + u16 txq_id) +{ + u32 tbl_dw_addr; + u32 tbl_dw; + u16 scd_q2ratid; + + scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK; + + tbl_dw_addr = priv->scd_base_addr + + IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id); + + tbl_dw = iwl_legacy_read_targ_mem(priv, tbl_dw_addr); + + if (txq_id & 0x1) + tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); + else + tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); + + iwl_legacy_write_targ_mem(priv, tbl_dw_addr, tbl_dw); + + return 0; +} + +/** + * iwl4965_tx_queue_agg_enable - Set up & enable aggregation for selected queue + * + * NOTE: txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE, + * i.e. it must be one of the higher queues used for aggregation + */ +static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, + int tx_fifo, int sta_id, int tid, u16 ssn_idx) +{ + unsigned long flags; + u16 ra_tid; + int ret; + + if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || + (IWL49_FIRST_AMPDU_QUEUE + + priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { + IWL_WARN(priv, + "queue number out of range: %d, must be %d to %d\n", + txq_id, IWL49_FIRST_AMPDU_QUEUE, + IWL49_FIRST_AMPDU_QUEUE + + priv->cfg->base_params->num_of_ampdu_queues - 1); + return -EINVAL; + } + + ra_tid = BUILD_RAxTID(sta_id, tid); + + /* Modify device's station table to Tx this TID */ + ret = iwl4965_sta_tx_modify_enable_tid(priv, sta_id, tid); + if (ret) + return ret; + + spin_lock_irqsave(&priv->lock, flags); + + /* Stop this Tx queue before configuring it */ + iwl4965_tx_queue_stop_scheduler(priv, txq_id); + + /* Map receiver-address / traffic-ID to this queue */ + iwl4965_tx_queue_set_q2ratid(priv, ra_tid, txq_id); + + /* Set this queue as a chain-building queue */ + iwl_legacy_set_bits_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, (1 << txq_id)); + + /* Place first TFD at index corresponding to start sequence number. + * Assumes that ssn_idx is valid (!= 0xFFF) */ + priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); + priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); + iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx); + + /* Set up Tx window size and frame limit for this queue */ + iwl_legacy_write_targ_mem(priv, + priv->scd_base_addr + IWL49_SCD_CONTEXT_QUEUE_OFFSET(txq_id), + (SCD_WIN_SIZE << IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) & + IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK); + + iwl_legacy_write_targ_mem(priv, priv->scd_base_addr + + IWL49_SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), + (SCD_FRAME_LIMIT << IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) + & IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK); + + iwl_legacy_set_bits_prph(priv, IWL49_SCD_INTERRUPT_MASK, (1 << txq_id)); + + /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ + iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1); + + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + + +int iwl4965_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u16 tid, u16 *ssn) +{ + int sta_id; + int tx_fifo; + int txq_id; + int ret; + unsigned long flags; + struct iwl_tid_data *tid_data; + + tx_fifo = iwl4965_get_fifo_from_tid(iwl_legacy_rxon_ctx_from_vif(vif), tid); + if (unlikely(tx_fifo < 0)) + return tx_fifo; + + IWL_WARN(priv, "%s on ra = %pM tid = %d\n", + __func__, sta->addr, tid); + + sta_id = iwl_legacy_sta_id(sta); + if (sta_id == IWL_INVALID_STATION) { + IWL_ERR(priv, "Start AGG on invalid station\n"); + return -ENXIO; + } + if (unlikely(tid >= MAX_TID_COUNT)) + return -EINVAL; + + if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) { + IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n"); + return -ENXIO; + } + + txq_id = iwl4965_txq_ctx_activate_free(priv); + if (txq_id == -1) { + IWL_ERR(priv, "No free aggregation queue available\n"); + return -ENXIO; + } + + spin_lock_irqsave(&priv->sta_lock, flags); + tid_data = &priv->stations[sta_id].tid[tid]; + *ssn = SEQ_TO_SN(tid_data->seq_number); + tid_data->agg.txq_id = txq_id; + iwl_legacy_set_swq_id(&priv->txq[txq_id], + iwl4965_get_ac_from_tid(tid), txq_id); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + ret = iwl4965_txq_agg_enable(priv, txq_id, tx_fifo, + sta_id, tid, *ssn); + if (ret) + return ret; + + spin_lock_irqsave(&priv->sta_lock, flags); + tid_data = &priv->stations[sta_id].tid[tid]; + if (tid_data->tfds_in_queue == 0) { + IWL_DEBUG_HT(priv, "HW queue is empty\n"); + tid_data->agg.state = IWL_AGG_ON; + ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + } else { + IWL_DEBUG_HT(priv, + "HW queue is NOT empty: %d packets in HW queue\n", + tid_data->tfds_in_queue); + tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; + } + spin_unlock_irqrestore(&priv->sta_lock, flags); + return ret; +} + +/** + * txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE + * priv->lock must be held by the caller + */ +static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, + u16 ssn_idx, u8 tx_fifo) +{ + if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || + (IWL49_FIRST_AMPDU_QUEUE + + priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { + IWL_WARN(priv, + "queue number out of range: %d, must be %d to %d\n", + txq_id, IWL49_FIRST_AMPDU_QUEUE, + IWL49_FIRST_AMPDU_QUEUE + + priv->cfg->base_params->num_of_ampdu_queues - 1); + return -EINVAL; + } + + iwl4965_tx_queue_stop_scheduler(priv, txq_id); + + iwl_legacy_clear_bits_prph(priv, + IWL49_SCD_QUEUECHAIN_SEL, (1 << txq_id)); + + priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); + priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); + /* supposes that ssn_idx is valid (!= 0xFFF) */ + iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx); + + iwl_legacy_clear_bits_prph(priv, + IWL49_SCD_INTERRUPT_MASK, (1 << txq_id)); + iwl_txq_ctx_deactivate(priv, txq_id); + iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0); + + return 0; +} + +int iwl4965_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u16 tid) +{ + int tx_fifo_id, txq_id, sta_id, ssn; + struct iwl_tid_data *tid_data; + int write_ptr, read_ptr; + unsigned long flags; + + tx_fifo_id = iwl4965_get_fifo_from_tid(iwl_legacy_rxon_ctx_from_vif(vif), tid); + if (unlikely(tx_fifo_id < 0)) + return tx_fifo_id; + + sta_id = iwl_legacy_sta_id(sta); + + if (sta_id == IWL_INVALID_STATION) { + IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid); + return -ENXIO; + } + + spin_lock_irqsave(&priv->sta_lock, flags); + + tid_data = &priv->stations[sta_id].tid[tid]; + ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4; + txq_id = tid_data->agg.txq_id; + + switch (priv->stations[sta_id].tid[tid].agg.state) { + case IWL_EMPTYING_HW_QUEUE_ADDBA: + /* + * This can happen if the peer stops aggregation + * again before we've had a chance to drain the + * queue we selected previously, i.e. before the + * session was really started completely. + */ + IWL_DEBUG_HT(priv, "AGG stop before setup done\n"); + goto turn_off; + case IWL_AGG_ON: + break; + default: + IWL_WARN(priv, "Stopping AGG while state not ON or starting\n"); + } + + write_ptr = priv->txq[txq_id].q.write_ptr; + read_ptr = priv->txq[txq_id].q.read_ptr; + + /* The queue is not empty */ + if (write_ptr != read_ptr) { + IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n"); + priv->stations[sta_id].tid[tid].agg.state = + IWL_EMPTYING_HW_QUEUE_DELBA; + spin_unlock_irqrestore(&priv->sta_lock, flags); + return 0; + } + + IWL_DEBUG_HT(priv, "HW queue is empty\n"); + turn_off: + priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; + + /* do not restore/save irqs */ + spin_unlock(&priv->sta_lock); + spin_lock(&priv->lock); + + /* + * the only reason this call can fail is queue number out of range, + * which can happen if uCode is reloaded and all the station + * information are lost. if it is outside the range, there is no need + * to deactivate the uCode queue, just return "success" to allow + * mac80211 to clean up it own data. + */ + iwl4965_txq_agg_disable(priv, txq_id, ssn, tx_fifo_id); + spin_unlock_irqrestore(&priv->lock, flags); + + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + + return 0; +} + +int iwl4965_txq_check_empty(struct iwl_priv *priv, + int sta_id, u8 tid, int txq_id) +{ + struct iwl_queue *q = &priv->txq[txq_id].q; + u8 *addr = priv->stations[sta_id].sta.sta.addr; + struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; + struct iwl_rxon_context *ctx; + + ctx = &priv->contexts[priv->stations[sta_id].ctxid]; + + lockdep_assert_held(&priv->sta_lock); + + switch (priv->stations[sta_id].tid[tid].agg.state) { + case IWL_EMPTYING_HW_QUEUE_DELBA: + /* We are reclaiming the last packet of the */ + /* aggregated HW queue */ + if ((txq_id == tid_data->agg.txq_id) && + (q->read_ptr == q->write_ptr)) { + u16 ssn = SEQ_TO_SN(tid_data->seq_number); + int tx_fifo = iwl4965_get_fifo_from_tid(ctx, tid); + IWL_DEBUG_HT(priv, + "HW queue empty: continue DELBA flow\n"); + iwl4965_txq_agg_disable(priv, txq_id, ssn, tx_fifo); + tid_data->agg.state = IWL_AGG_OFF; + ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid); + } + break; + case IWL_EMPTYING_HW_QUEUE_ADDBA: + /* We are reclaiming the last packet of the queue */ + if (tid_data->tfds_in_queue == 0) { + IWL_DEBUG_HT(priv, + "HW queue empty: continue ADDBA flow\n"); + tid_data->agg.state = IWL_AGG_ON; + ieee80211_start_tx_ba_cb_irqsafe(ctx->vif, addr, tid); + } + break; + } + + return 0; +} + +static void iwl4965_non_agg_tx_status(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + const u8 *addr1) +{ + struct ieee80211_sta *sta; + struct iwl_station_priv *sta_priv; + + rcu_read_lock(); + sta = ieee80211_find_sta(ctx->vif, addr1); + if (sta) { + sta_priv = (void *)sta->drv_priv; + /* avoid atomic ops if this isn't a client */ + if (sta_priv->client && + atomic_dec_return(&sta_priv->pending_frames) == 0) + ieee80211_sta_block_awake(priv->hw, sta, false); + } + rcu_read_unlock(); +} + +static void +iwl4965_tx_status(struct iwl_priv *priv, struct iwl_tx_info *tx_info, + bool is_agg) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx_info->skb->data; + + if (!is_agg) + iwl4965_non_agg_tx_status(priv, tx_info->ctx, hdr->addr1); + + ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb); +} + +int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) +{ + struct iwl_tx_queue *txq = &priv->txq[txq_id]; + struct iwl_queue *q = &txq->q; + struct iwl_tx_info *tx_info; + int nfreed = 0; + struct ieee80211_hdr *hdr; + + if ((index >= q->n_bd) || (iwl_legacy_queue_used(q, index) == 0)) { + IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, " + "is out of range [0-%d] %d %d.\n", txq_id, + index, q->n_bd, q->write_ptr, q->read_ptr); + return 0; + } + + for (index = iwl_legacy_queue_inc_wrap(index, q->n_bd); + q->read_ptr != index; + q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd)) { + + tx_info = &txq->txb[txq->q.read_ptr]; + iwl4965_tx_status(priv, tx_info, + txq_id >= IWL4965_FIRST_AMPDU_QUEUE); + + hdr = (struct ieee80211_hdr *)tx_info->skb->data; + if (hdr && ieee80211_is_data_qos(hdr->frame_control)) + nfreed++; + tx_info->skb = NULL; + + priv->cfg->ops->lib->txq_free_tfd(priv, txq); + } + return nfreed; +} + +/** + * iwl4965_tx_status_reply_compressed_ba - Update tx status from block-ack + * + * Go through block-ack's bitmap of ACK'd frames, update driver's record of + * ACK vs. not. This gets sent to mac80211, then to rate scaling algo. + */ +static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv, + struct iwl_ht_agg *agg, + struct iwl_compressed_ba_resp *ba_resp) + +{ + int i, sh, ack; + u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl); + u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); + int successes = 0; + struct ieee80211_tx_info *info; + u64 bitmap, sent_bitmap; + + if (unlikely(!agg->wait_for_ba)) { + if (unlikely(ba_resp->bitmap)) + IWL_ERR(priv, "Received BA when not expected\n"); + return -EINVAL; + } + + /* Mark that the expected block-ack response arrived */ + agg->wait_for_ba = 0; + IWL_DEBUG_TX_REPLY(priv, "BA %d %d\n", agg->start_idx, + ba_resp->seq_ctl); + + /* Calculate shift to align block-ack bits with our Tx window bits */ + sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl >> 4); + if (sh < 0) /* tbw something is wrong with indices */ + sh += 0x100; + + if (agg->frame_count > (64 - sh)) { + IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size"); + return -1; + } + + /* don't use 64-bit values for now */ + bitmap = le64_to_cpu(ba_resp->bitmap) >> sh; + + /* check for success or failure according to the + * transmitted bitmap and block-ack bitmap */ + sent_bitmap = bitmap & agg->bitmap; + + /* For each frame attempted in aggregation, + * update driver's record of tx frame's status. */ + i = 0; + while (sent_bitmap) { + ack = sent_bitmap & 1ULL; + successes += ack; + IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n", + ack ? "ACK" : "NACK", i, + (agg->start_idx + i) & 0xff, + agg->start_idx + i); + sent_bitmap >>= 1; + ++i; + } + + IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", + (unsigned long long)bitmap); + + info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb); + memset(&info->status, 0, sizeof(info->status)); + info->flags |= IEEE80211_TX_STAT_ACK; + info->flags |= IEEE80211_TX_STAT_AMPDU; + info->status.ampdu_ack_len = successes; + info->status.ampdu_len = agg->frame_count; + iwl4965_hwrate_to_tx_control(priv, agg->rate_n_flags, info); + + return 0; +} + +/** + * translate ucode response to mac80211 tx status control values + */ +void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, + struct ieee80211_tx_info *info) +{ + struct ieee80211_tx_rate *r = &info->control.rates[0]; + + info->antenna_sel_tx = + ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS); + if (rate_n_flags & RATE_MCS_HT_MSK) + r->flags |= IEEE80211_TX_RC_MCS; + if (rate_n_flags & RATE_MCS_GF_MSK) + r->flags |= IEEE80211_TX_RC_GREEN_FIELD; + if (rate_n_flags & RATE_MCS_HT40_MSK) + r->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; + if (rate_n_flags & RATE_MCS_DUP_MSK) + r->flags |= IEEE80211_TX_RC_DUP_DATA; + if (rate_n_flags & RATE_MCS_SGI_MSK) + r->flags |= IEEE80211_TX_RC_SHORT_GI; + r->idx = iwl4965_hwrate_to_mac80211_idx(rate_n_flags, info->band); +} + +/** + * iwl4965_rx_reply_compressed_ba - Handler for REPLY_COMPRESSED_BA + * + * Handles block-acknowledge notification from device, which reports success + * of frames sent via aggregation. + */ +void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; + struct iwl_tx_queue *txq = NULL; + struct iwl_ht_agg *agg; + int index; + int sta_id; + int tid; + unsigned long flags; + + /* "flow" corresponds to Tx queue */ + u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); + + /* "ssn" is start of block-ack Tx window, corresponds to index + * (in Tx queue's circular buffer) of first TFD/frame in window */ + u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); + + if (scd_flow >= priv->hw_params.max_txq_num) { + IWL_ERR(priv, + "BUG_ON scd_flow is bigger than number of queues\n"); + return; + } + + txq = &priv->txq[scd_flow]; + sta_id = ba_resp->sta_id; + tid = ba_resp->tid; + agg = &priv->stations[sta_id].tid[tid].agg; + if (unlikely(agg->txq_id != scd_flow)) { + /* + * FIXME: this is a uCode bug which need to be addressed, + * log the information and return for now! + * since it is possible happen very often and in order + * not to fill the syslog, don't enable the logging by default + */ + IWL_DEBUG_TX_REPLY(priv, + "BA scd_flow %d does not match txq_id %d\n", + scd_flow, agg->txq_id); + return; + } + + /* Find index just before block-ack window */ + index = iwl_legacy_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); + + spin_lock_irqsave(&priv->sta_lock, flags); + + IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, " + "sta_id = %d\n", + agg->wait_for_ba, + (u8 *) &ba_resp->sta_addr_lo32, + ba_resp->sta_id); + IWL_DEBUG_TX_REPLY(priv, "TID = %d, SeqCtl = %d, bitmap = 0x%llx," + "scd_flow = " + "%d, scd_ssn = %d\n", + ba_resp->tid, + ba_resp->seq_ctl, + (unsigned long long)le64_to_cpu(ba_resp->bitmap), + ba_resp->scd_flow, + ba_resp->scd_ssn); + IWL_DEBUG_TX_REPLY(priv, "DAT start_idx = %d, bitmap = 0x%llx\n", + agg->start_idx, + (unsigned long long)agg->bitmap); + + /* Update driver's record of ACK vs. not for each frame in window */ + iwl4965_tx_status_reply_compressed_ba(priv, agg, ba_resp); + + /* Release all TFDs before the SSN, i.e. all TFDs in front of + * block-ack window (we assume that they've been successfully + * transmitted ... if not, it's too late anyway). */ + if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { + /* calculate mac80211 ampdu sw queue to wake */ + int freed = iwl4965_tx_queue_reclaim(priv, scd_flow, index); + iwl4965_free_tfds_in_queue(priv, sta_id, tid, freed); + + if ((iwl_legacy_queue_space(&txq->q) > txq->q.low_mark) && + priv->mac80211_registered && + (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) + iwl_legacy_wake_queue(priv, txq); + + iwl4965_txq_check_empty(priv, sta_id, tid, scd_flow); + } + + spin_unlock_irqrestore(&priv->sta_lock, flags); +} + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +const char *iwl4965_get_tx_fail_reason(u32 status) +{ +#define TX_STATUS_FAIL(x) case TX_STATUS_FAIL_ ## x: return #x +#define TX_STATUS_POSTPONE(x) case TX_STATUS_POSTPONE_ ## x: return #x + + switch (status & TX_STATUS_MSK) { + case TX_STATUS_SUCCESS: + return "SUCCESS"; + TX_STATUS_POSTPONE(DELAY); + TX_STATUS_POSTPONE(FEW_BYTES); + TX_STATUS_POSTPONE(QUIET_PERIOD); + TX_STATUS_POSTPONE(CALC_TTAK); + TX_STATUS_FAIL(INTERNAL_CROSSED_RETRY); + TX_STATUS_FAIL(SHORT_LIMIT); + TX_STATUS_FAIL(LONG_LIMIT); + TX_STATUS_FAIL(FIFO_UNDERRUN); + TX_STATUS_FAIL(DRAIN_FLOW); + TX_STATUS_FAIL(RFKILL_FLUSH); + TX_STATUS_FAIL(LIFE_EXPIRE); + TX_STATUS_FAIL(DEST_PS); + TX_STATUS_FAIL(HOST_ABORTED); + TX_STATUS_FAIL(BT_RETRY); + TX_STATUS_FAIL(STA_INVALID); + TX_STATUS_FAIL(FRAG_DROPPED); + TX_STATUS_FAIL(TID_DISABLE); + TX_STATUS_FAIL(FIFO_FLUSHED); + TX_STATUS_FAIL(INSUFFICIENT_CF_POLL); + TX_STATUS_FAIL(PASSIVE_NO_RX); + TX_STATUS_FAIL(NO_BEACON_ON_RADAR); + } + + return "UNKNOWN"; + +#undef TX_STATUS_FAIL +#undef TX_STATUS_POSTPONE +} +#endif /* CONFIG_IWLWIFI_LEGACY_DEBUG */ diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-ucode.c b/drivers/net/wireless/iwlegacy/iwl-4965-ucode.c new file mode 100644 index 000000000000..001d148feb94 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-4965-ucode.c @@ -0,0 +1,166 @@ +/****************************************************************************** + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include +#include + +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-io.h" +#include "iwl-helpers.h" +#include "iwl-4965-hw.h" +#include "iwl-4965.h" +#include "iwl-4965-calib.h" + +#define IWL_AC_UNSET -1 + +/** + * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host, + * using sample data 100 bytes apart. If these sample points are good, + * it's a pretty good bet that everything between them is good, too. + */ +static int +iwl4965_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) +{ + u32 val; + int ret = 0; + u32 errcnt = 0; + u32 i; + + IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); + + for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { + /* read data comes through single port, auto-incr addr */ + /* NOTE: Use the debugless read so we don't flood kernel log + * if IWL_DL_IO is set */ + iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_RADDR, + i + IWL4965_RTC_INST_LOWER_BOUND); + val = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); + if (val != le32_to_cpu(*image)) { + ret = -EIO; + errcnt++; + if (errcnt >= 3) + break; + } + } + + return ret; +} + +/** + * iwl4965_verify_inst_full - verify runtime uCode image in card vs. host, + * looking at all data. + */ +static int iwl4965_verify_inst_full(struct iwl_priv *priv, __le32 *image, + u32 len) +{ + u32 val; + u32 save_len = len; + int ret = 0; + u32 errcnt; + + IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); + + iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_RADDR, + IWL4965_RTC_INST_LOWER_BOUND); + + errcnt = 0; + for (; len > 0; len -= sizeof(u32), image++) { + /* read data comes through single port, auto-incr addr */ + /* NOTE: Use the debugless read so we don't flood kernel log + * if IWL_DL_IO is set */ + val = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); + if (val != le32_to_cpu(*image)) { + IWL_ERR(priv, "uCode INST section is invalid at " + "offset 0x%x, is 0x%x, s/b 0x%x\n", + save_len - len, val, le32_to_cpu(*image)); + ret = -EIO; + errcnt++; + if (errcnt >= 20) + break; + } + } + + if (!errcnt) + IWL_DEBUG_INFO(priv, + "ucode image in INSTRUCTION memory is good\n"); + + return ret; +} + +/** + * iwl4965_verify_ucode - determine which instruction image is in SRAM, + * and verify its contents + */ +int iwl4965_verify_ucode(struct iwl_priv *priv) +{ + __le32 *image; + u32 len; + int ret; + + /* Try bootstrap */ + image = (__le32 *)priv->ucode_boot.v_addr; + len = priv->ucode_boot.len; + ret = iwl4965_verify_inst_sparse(priv, image, len); + if (!ret) { + IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n"); + return 0; + } + + /* Try initialize */ + image = (__le32 *)priv->ucode_init.v_addr; + len = priv->ucode_init.len; + ret = iwl4965_verify_inst_sparse(priv, image, len); + if (!ret) { + IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n"); + return 0; + } + + /* Try runtime/protocol */ + image = (__le32 *)priv->ucode_code.v_addr; + len = priv->ucode_code.len; + ret = iwl4965_verify_inst_sparse(priv, image, len); + if (!ret) { + IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n"); + return 0; + } + + IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n"); + + /* Since nothing seems to match, show first several data entries in + * instruction SRAM, so maybe visual inspection will give a clue. + * Selection of bootstrap image (vs. other images) is arbitrary. */ + image = (__le32 *)priv->ucode_boot.v_addr; + len = priv->ucode_boot.len; + ret = iwl4965_verify_inst_full(priv, image, len); + + return ret; +} diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c new file mode 100644 index 000000000000..080444c89022 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-4965.c @@ -0,0 +1,2188 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iwl-eeprom.h" +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-io.h" +#include "iwl-helpers.h" +#include "iwl-4965-calib.h" +#include "iwl-sta.h" +#include "iwl-4965-led.h" +#include "iwl-4965.h" +#include "iwl-4965-debugfs.h" + +static int iwl4965_send_tx_power(struct iwl_priv *priv); +static int iwl4965_hw_get_temperature(struct iwl_priv *priv); + +/* Highest firmware API version supported */ +#define IWL4965_UCODE_API_MAX 2 + +/* Lowest firmware API version supported */ +#define IWL4965_UCODE_API_MIN 2 + +#define IWL4965_FW_PRE "iwlwifi-4965-" +#define _IWL4965_MODULE_FIRMWARE(api) IWL4965_FW_PRE #api ".ucode" +#define IWL4965_MODULE_FIRMWARE(api) _IWL4965_MODULE_FIRMWARE(api) + +/* check contents of special bootstrap uCode SRAM */ +static int iwl4965_verify_bsm(struct iwl_priv *priv) +{ + __le32 *image = priv->ucode_boot.v_addr; + u32 len = priv->ucode_boot.len; + u32 reg; + u32 val; + + IWL_DEBUG_INFO(priv, "Begin verify bsm\n"); + + /* verify BSM SRAM contents */ + val = iwl_legacy_read_prph(priv, BSM_WR_DWCOUNT_REG); + for (reg = BSM_SRAM_LOWER_BOUND; + reg < BSM_SRAM_LOWER_BOUND + len; + reg += sizeof(u32), image++) { + val = iwl_legacy_read_prph(priv, reg); + if (val != le32_to_cpu(*image)) { + IWL_ERR(priv, "BSM uCode verification failed at " + "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", + BSM_SRAM_LOWER_BOUND, + reg - BSM_SRAM_LOWER_BOUND, len, + val, le32_to_cpu(*image)); + return -EIO; + } + } + + IWL_DEBUG_INFO(priv, "BSM bootstrap uCode image OK\n"); + + return 0; +} + +/** + * iwl4965_load_bsm - Load bootstrap instructions + * + * BSM operation: + * + * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program + * in special SRAM that does not power down during RFKILL. When powering back + * up after power-saving sleeps (or during initial uCode load), the BSM loads + * the bootstrap program into the on-board processor, and starts it. + * + * The bootstrap program loads (via DMA) instructions and data for a new + * program from host DRAM locations indicated by the host driver in the + * BSM_DRAM_* registers. Once the new program is loaded, it starts + * automatically. + * + * When initializing the NIC, the host driver points the BSM to the + * "initialize" uCode image. This uCode sets up some internal data, then + * notifies host via "initialize alive" that it is complete. + * + * The host then replaces the BSM_DRAM_* pointer values to point to the + * normal runtime uCode instructions and a backup uCode data cache buffer + * (filled initially with starting data values for the on-board processor), + * then triggers the "initialize" uCode to load and launch the runtime uCode, + * which begins normal operation. + * + * When doing a power-save shutdown, runtime uCode saves data SRAM into + * the backup data cache in DRAM before SRAM is powered down. + * + * When powering back up, the BSM loads the bootstrap program. This reloads + * the runtime uCode instructions and the backup data cache into SRAM, + * and re-launches the runtime uCode from where it left off. + */ +static int iwl4965_load_bsm(struct iwl_priv *priv) +{ + __le32 *image = priv->ucode_boot.v_addr; + u32 len = priv->ucode_boot.len; + dma_addr_t pinst; + dma_addr_t pdata; + u32 inst_len; + u32 data_len; + int i; + u32 done; + u32 reg_offset; + int ret; + + IWL_DEBUG_INFO(priv, "Begin load bsm\n"); + + priv->ucode_type = UCODE_RT; + + /* make sure bootstrap program is no larger than BSM's SRAM size */ + if (len > IWL49_MAX_BSM_SIZE) + return -EINVAL; + + /* Tell bootstrap uCode where to find the "Initialize" uCode + * in host DRAM ... host DRAM physical address bits 35:4 for 4965. + * NOTE: iwl_init_alive_start() will replace these values, + * after the "initialize" uCode has run, to point to + * runtime/protocol instructions and backup data cache. + */ + pinst = priv->ucode_init.p_addr >> 4; + pdata = priv->ucode_init_data.p_addr >> 4; + inst_len = priv->ucode_init.len; + data_len = priv->ucode_init_data.len; + + iwl_legacy_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); + iwl_legacy_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); + iwl_legacy_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); + iwl_legacy_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); + + /* Fill BSM memory with bootstrap instructions */ + for (reg_offset = BSM_SRAM_LOWER_BOUND; + reg_offset < BSM_SRAM_LOWER_BOUND + len; + reg_offset += sizeof(u32), image++) + _iwl_legacy_write_prph(priv, reg_offset, le32_to_cpu(*image)); + + ret = iwl4965_verify_bsm(priv); + if (ret) + return ret; + + /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ + iwl_legacy_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); + iwl_legacy_write_prph(priv, + BSM_WR_MEM_DST_REG, IWL49_RTC_INST_LOWER_BOUND); + iwl_legacy_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); + + /* Load bootstrap code into instruction SRAM now, + * to prepare to load "initialize" uCode */ + iwl_legacy_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START); + + /* Wait for load of bootstrap uCode to finish */ + for (i = 0; i < 100; i++) { + done = iwl_legacy_read_prph(priv, BSM_WR_CTRL_REG); + if (!(done & BSM_WR_CTRL_REG_BIT_START)) + break; + udelay(10); + } + if (i < 100) + IWL_DEBUG_INFO(priv, "BSM write complete, poll %d iterations\n", i); + else { + IWL_ERR(priv, "BSM write did not complete!\n"); + return -EIO; + } + + /* Enable future boot loads whenever power management unit triggers it + * (e.g. when powering back up after power-save shutdown) */ + iwl_legacy_write_prph(priv, + BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START_EN); + + + return 0; +} + +/** + * iwl4965_set_ucode_ptrs - Set uCode address location + * + * Tell initialization uCode where to find runtime uCode. + * + * BSM registers initially contain pointers to initialization uCode. + * We need to replace them to load runtime uCode inst and data, + * and to save runtime data when powering down. + */ +static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv) +{ + dma_addr_t pinst; + dma_addr_t pdata; + int ret = 0; + + /* bits 35:4 for 4965 */ + pinst = priv->ucode_code.p_addr >> 4; + pdata = priv->ucode_data_backup.p_addr >> 4; + + /* Tell bootstrap uCode where to find image to load */ + iwl_legacy_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); + iwl_legacy_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); + iwl_legacy_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, + priv->ucode_data.len); + + /* Inst byte count must be last to set up, bit 31 signals uCode + * that all new ptr/size info is in place */ + iwl_legacy_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, + priv->ucode_code.len | BSM_DRAM_INST_LOAD); + IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n"); + + return ret; +} + +/** + * iwl4965_init_alive_start - Called after REPLY_ALIVE notification received + * + * Called after REPLY_ALIVE notification received from "initialize" uCode. + * + * The 4965 "initialize" ALIVE reply contains calibration data for: + * Voltage, temperature, and MIMO tx gain correction, now stored in priv + * (3945 does not contain this data). + * + * Tell "initialize" uCode to go ahead and load the runtime uCode. +*/ +static void iwl4965_init_alive_start(struct iwl_priv *priv) +{ + /* Bootstrap uCode has loaded initialize uCode ... verify inst image. + * This is a paranoid check, because we would not have gotten the + * "initialize" alive if code weren't properly loaded. */ + if (iwl4965_verify_ucode(priv)) { + /* Runtime instruction load was bad; + * take it all the way back down so we can try again */ + IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n"); + goto restart; + } + + /* Calculate temperature */ + priv->temperature = iwl4965_hw_get_temperature(priv); + + /* Send pointers to protocol/runtime uCode image ... init code will + * load and launch runtime uCode, which will send us another "Alive" + * notification. */ + IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); + if (iwl4965_set_ucode_ptrs(priv)) { + /* Runtime instruction load won't happen; + * take it all the way back down so we can try again */ + IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n"); + goto restart; + } + return; + +restart: + queue_work(priv->workqueue, &priv->restart); +} + +static bool iw4965_is_ht40_channel(__le32 rxon_flags) +{ + int chan_mod = le32_to_cpu(rxon_flags & RXON_FLG_CHANNEL_MODE_MSK) + >> RXON_FLG_CHANNEL_MODE_POS; + return ((chan_mod == CHANNEL_MODE_PURE_40) || + (chan_mod == CHANNEL_MODE_MIXED)); +} + +static void iwl4965_nic_config(struct iwl_priv *priv) +{ + unsigned long flags; + u16 radio_cfg; + + spin_lock_irqsave(&priv->lock, flags); + + radio_cfg = iwl_legacy_eeprom_query16(priv, EEPROM_RADIO_CONFIG); + + /* write radio config values to register */ + if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) == EEPROM_4965_RF_CFG_TYPE_MAX) + iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG, + EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | + EEPROM_RF_CFG_STEP_MSK(radio_cfg) | + EEPROM_RF_CFG_DASH_MSK(radio_cfg)); + + /* set CSR_HW_CONFIG_REG for uCode use */ + iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | + CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); + + priv->calib_info = (struct iwl_eeprom_calib_info *) + iwl_legacy_eeprom_query_addr(priv, + EEPROM_4965_CALIB_TXPOWER_OFFSET); + + spin_unlock_irqrestore(&priv->lock, flags); +} + +/* Reset differential Rx gains in NIC to prepare for chain noise calibration. + * Called after every association, but this runs only once! + * ... once chain noise is calibrated the first time, it's good forever. */ +static void iwl4965_chain_noise_reset(struct iwl_priv *priv) +{ + struct iwl_chain_noise_data *data = &(priv->chain_noise_data); + + if ((data->state == IWL_CHAIN_NOISE_ALIVE) && + iwl_legacy_is_any_associated(priv)) { + struct iwl_calib_diff_gain_cmd cmd; + + /* clear data for chain noise calibration algorithm */ + data->chain_noise_a = 0; + data->chain_noise_b = 0; + data->chain_noise_c = 0; + data->chain_signal_a = 0; + data->chain_signal_b = 0; + data->chain_signal_c = 0; + data->beacon_count = 0; + + memset(&cmd, 0, sizeof(cmd)); + cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD; + cmd.diff_gain_a = 0; + cmd.diff_gain_b = 0; + cmd.diff_gain_c = 0; + if (iwl_legacy_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, + sizeof(cmd), &cmd)) + IWL_ERR(priv, + "Could not send REPLY_PHY_CALIBRATION_CMD\n"); + data->state = IWL_CHAIN_NOISE_ACCUMULATE; + IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n"); + } +} + +static struct iwl_sensitivity_ranges iwl4965_sensitivity = { + .min_nrg_cck = 97, + .max_nrg_cck = 0, /* not used, set to 0 */ + + .auto_corr_min_ofdm = 85, + .auto_corr_min_ofdm_mrc = 170, + .auto_corr_min_ofdm_x1 = 105, + .auto_corr_min_ofdm_mrc_x1 = 220, + + .auto_corr_max_ofdm = 120, + .auto_corr_max_ofdm_mrc = 210, + .auto_corr_max_ofdm_x1 = 140, + .auto_corr_max_ofdm_mrc_x1 = 270, + + .auto_corr_min_cck = 125, + .auto_corr_max_cck = 200, + .auto_corr_min_cck_mrc = 200, + .auto_corr_max_cck_mrc = 400, + + .nrg_th_cck = 100, + .nrg_th_ofdm = 100, + + .barker_corr_th_min = 190, + .barker_corr_th_min_mrc = 390, + .nrg_th_cca = 62, +}; + +static void iwl4965_set_ct_threshold(struct iwl_priv *priv) +{ + /* want Kelvin */ + priv->hw_params.ct_kill_threshold = + CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY); +} + +/** + * iwl4965_hw_set_hw_params + * + * Called when initializing driver + */ +static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) +{ + if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && + priv->cfg->mod_params->num_of_queues <= IWL49_NUM_QUEUES) + priv->cfg->base_params->num_of_queues = + priv->cfg->mod_params->num_of_queues; + + priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; + priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM; + priv->hw_params.scd_bc_tbls_size = + priv->cfg->base_params->num_of_queues * + sizeof(struct iwl4965_scd_bc_tbl); + priv->hw_params.tfd_size = sizeof(struct iwl_tfd); + priv->hw_params.max_stations = IWL4965_STATION_COUNT; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL4965_BROADCAST_ID; + priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE; + priv->hw_params.max_inst_size = IWL49_RTC_INST_SIZE; + priv->hw_params.max_bsm_size = BSM_SRAM_SIZE; + priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_5GHZ); + + priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; + + priv->hw_params.tx_chains_num = iwl4965_num_of_ant(priv->cfg->valid_tx_ant); + priv->hw_params.rx_chains_num = iwl4965_num_of_ant(priv->cfg->valid_rx_ant); + priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; + priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; + + iwl4965_set_ct_threshold(priv); + + priv->hw_params.sens = &iwl4965_sensitivity; + priv->hw_params.beacon_time_tsf_bits = IWL4965_EXT_BEACON_TIME_POS; + + return 0; +} + +static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res) +{ + s32 sign = 1; + + if (num < 0) { + sign = -sign; + num = -num; + } + if (denom < 0) { + sign = -sign; + denom = -denom; + } + *res = 1; + *res = ((num * 2 + denom) / (denom * 2)) * sign; + + return 1; +} + +/** + * iwl4965_get_voltage_compensation - Power supply voltage comp for txpower + * + * Determines power supply voltage compensation for txpower calculations. + * Returns number of 1/2-dB steps to subtract from gain table index, + * to compensate for difference between power supply voltage during + * factory measurements, vs. current power supply voltage. + * + * Voltage indication is higher for lower voltage. + * Lower voltage requires more gain (lower gain table index). + */ +static s32 iwl4965_get_voltage_compensation(s32 eeprom_voltage, + s32 current_voltage) +{ + s32 comp = 0; + + if ((TX_POWER_IWL_ILLEGAL_VOLTAGE == eeprom_voltage) || + (TX_POWER_IWL_ILLEGAL_VOLTAGE == current_voltage)) + return 0; + + iwl4965_math_div_round(current_voltage - eeprom_voltage, + TX_POWER_IWL_VOLTAGE_CODES_PER_03V, &comp); + + if (current_voltage > eeprom_voltage) + comp *= 2; + if ((comp < -2) || (comp > 2)) + comp = 0; + + return comp; +} + +static s32 iwl4965_get_tx_atten_grp(u16 channel) +{ + if (channel >= CALIB_IWL_TX_ATTEN_GR5_FCH && + channel <= CALIB_IWL_TX_ATTEN_GR5_LCH) + return CALIB_CH_GROUP_5; + + if (channel >= CALIB_IWL_TX_ATTEN_GR1_FCH && + channel <= CALIB_IWL_TX_ATTEN_GR1_LCH) + return CALIB_CH_GROUP_1; + + if (channel >= CALIB_IWL_TX_ATTEN_GR2_FCH && + channel <= CALIB_IWL_TX_ATTEN_GR2_LCH) + return CALIB_CH_GROUP_2; + + if (channel >= CALIB_IWL_TX_ATTEN_GR3_FCH && + channel <= CALIB_IWL_TX_ATTEN_GR3_LCH) + return CALIB_CH_GROUP_3; + + if (channel >= CALIB_IWL_TX_ATTEN_GR4_FCH && + channel <= CALIB_IWL_TX_ATTEN_GR4_LCH) + return CALIB_CH_GROUP_4; + + return -1; +} + +static u32 iwl4965_get_sub_band(const struct iwl_priv *priv, u32 channel) +{ + s32 b = -1; + + for (b = 0; b < EEPROM_TX_POWER_BANDS; b++) { + if (priv->calib_info->band_info[b].ch_from == 0) + continue; + + if ((channel >= priv->calib_info->band_info[b].ch_from) + && (channel <= priv->calib_info->band_info[b].ch_to)) + break; + } + + return b; +} + +static s32 iwl4965_interpolate_value(s32 x, s32 x1, s32 y1, s32 x2, s32 y2) +{ + s32 val; + + if (x2 == x1) + return y1; + else { + iwl4965_math_div_round((x2 - x) * (y1 - y2), (x2 - x1), &val); + return val + y2; + } +} + +/** + * iwl4965_interpolate_chan - Interpolate factory measurements for one channel + * + * Interpolates factory measurements from the two sample channels within a + * sub-band, to apply to channel of interest. Interpolation is proportional to + * differences in channel frequencies, which is proportional to differences + * in channel number. + */ +static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel, + struct iwl_eeprom_calib_ch_info *chan_info) +{ + s32 s = -1; + u32 c; + u32 m; + const struct iwl_eeprom_calib_measure *m1; + const struct iwl_eeprom_calib_measure *m2; + struct iwl_eeprom_calib_measure *omeas; + u32 ch_i1; + u32 ch_i2; + + s = iwl4965_get_sub_band(priv, channel); + if (s >= EEPROM_TX_POWER_BANDS) { + IWL_ERR(priv, "Tx Power can not find channel %d\n", channel); + return -1; + } + + ch_i1 = priv->calib_info->band_info[s].ch1.ch_num; + ch_i2 = priv->calib_info->band_info[s].ch2.ch_num; + chan_info->ch_num = (u8) channel; + + IWL_DEBUG_TXPOWER(priv, "channel %d subband %d factory cal ch %d & %d\n", + channel, s, ch_i1, ch_i2); + + for (c = 0; c < EEPROM_TX_POWER_TX_CHAINS; c++) { + for (m = 0; m < EEPROM_TX_POWER_MEASUREMENTS; m++) { + m1 = &(priv->calib_info->band_info[s].ch1. + measurements[c][m]); + m2 = &(priv->calib_info->band_info[s].ch2. + measurements[c][m]); + omeas = &(chan_info->measurements[c][m]); + + omeas->actual_pow = + (u8) iwl4965_interpolate_value(channel, ch_i1, + m1->actual_pow, + ch_i2, + m2->actual_pow); + omeas->gain_idx = + (u8) iwl4965_interpolate_value(channel, ch_i1, + m1->gain_idx, ch_i2, + m2->gain_idx); + omeas->temperature = + (u8) iwl4965_interpolate_value(channel, ch_i1, + m1->temperature, + ch_i2, + m2->temperature); + omeas->pa_det = + (s8) iwl4965_interpolate_value(channel, ch_i1, + m1->pa_det, ch_i2, + m2->pa_det); + + IWL_DEBUG_TXPOWER(priv, + "chain %d meas %d AP1=%d AP2=%d AP=%d\n", c, m, + m1->actual_pow, m2->actual_pow, omeas->actual_pow); + IWL_DEBUG_TXPOWER(priv, + "chain %d meas %d NI1=%d NI2=%d NI=%d\n", c, m, + m1->gain_idx, m2->gain_idx, omeas->gain_idx); + IWL_DEBUG_TXPOWER(priv, + "chain %d meas %d PA1=%d PA2=%d PA=%d\n", c, m, + m1->pa_det, m2->pa_det, omeas->pa_det); + IWL_DEBUG_TXPOWER(priv, + "chain %d meas %d T1=%d T2=%d T=%d\n", c, m, + m1->temperature, m2->temperature, + omeas->temperature); + } + } + + return 0; +} + +/* bit-rate-dependent table to prevent Tx distortion, in half-dB units, + * for OFDM 6, 12, 18, 24, 36, 48, 54, 60 MBit, and CCK all rates. */ +static s32 back_off_table[] = { + 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM SISO 20 MHz */ + 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM MIMO 20 MHz */ + 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM SISO 40 MHz */ + 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM MIMO 40 MHz */ + 10 /* CCK */ +}; + +/* Thermal compensation values for txpower for various frequency ranges ... + * ratios from 3:1 to 4.5:1 of degrees (Celsius) per half-dB gain adjust */ +static struct iwl4965_txpower_comp_entry { + s32 degrees_per_05db_a; + s32 degrees_per_05db_a_denom; +} tx_power_cmp_tble[CALIB_CH_GROUP_MAX] = { + {9, 2}, /* group 0 5.2, ch 34-43 */ + {4, 1}, /* group 1 5.2, ch 44-70 */ + {4, 1}, /* group 2 5.2, ch 71-124 */ + {4, 1}, /* group 3 5.2, ch 125-200 */ + {3, 1} /* group 4 2.4, ch all */ +}; + +static s32 get_min_power_index(s32 rate_power_index, u32 band) +{ + if (!band) { + if ((rate_power_index & 7) <= 4) + return MIN_TX_GAIN_INDEX_52GHZ_EXT; + } + return MIN_TX_GAIN_INDEX; +} + +struct gain_entry { + u8 dsp; + u8 radio; +}; + +static const struct gain_entry gain_table[2][108] = { + /* 5.2GHz power gain index table */ + { + {123, 0x3F}, /* highest txpower */ + {117, 0x3F}, + {110, 0x3F}, + {104, 0x3F}, + {98, 0x3F}, + {110, 0x3E}, + {104, 0x3E}, + {98, 0x3E}, + {110, 0x3D}, + {104, 0x3D}, + {98, 0x3D}, + {110, 0x3C}, + {104, 0x3C}, + {98, 0x3C}, + {110, 0x3B}, + {104, 0x3B}, + {98, 0x3B}, + {110, 0x3A}, + {104, 0x3A}, + {98, 0x3A}, + {110, 0x39}, + {104, 0x39}, + {98, 0x39}, + {110, 0x38}, + {104, 0x38}, + {98, 0x38}, + {110, 0x37}, + {104, 0x37}, + {98, 0x37}, + {110, 0x36}, + {104, 0x36}, + {98, 0x36}, + {110, 0x35}, + {104, 0x35}, + {98, 0x35}, + {110, 0x34}, + {104, 0x34}, + {98, 0x34}, + {110, 0x33}, + {104, 0x33}, + {98, 0x33}, + {110, 0x32}, + {104, 0x32}, + {98, 0x32}, + {110, 0x31}, + {104, 0x31}, + {98, 0x31}, + {110, 0x30}, + {104, 0x30}, + {98, 0x30}, + {110, 0x25}, + {104, 0x25}, + {98, 0x25}, + {110, 0x24}, + {104, 0x24}, + {98, 0x24}, + {110, 0x23}, + {104, 0x23}, + {98, 0x23}, + {110, 0x22}, + {104, 0x18}, + {98, 0x18}, + {110, 0x17}, + {104, 0x17}, + {98, 0x17}, + {110, 0x16}, + {104, 0x16}, + {98, 0x16}, + {110, 0x15}, + {104, 0x15}, + {98, 0x15}, + {110, 0x14}, + {104, 0x14}, + {98, 0x14}, + {110, 0x13}, + {104, 0x13}, + {98, 0x13}, + {110, 0x12}, + {104, 0x08}, + {98, 0x08}, + {110, 0x07}, + {104, 0x07}, + {98, 0x07}, + {110, 0x06}, + {104, 0x06}, + {98, 0x06}, + {110, 0x05}, + {104, 0x05}, + {98, 0x05}, + {110, 0x04}, + {104, 0x04}, + {98, 0x04}, + {110, 0x03}, + {104, 0x03}, + {98, 0x03}, + {110, 0x02}, + {104, 0x02}, + {98, 0x02}, + {110, 0x01}, + {104, 0x01}, + {98, 0x01}, + {110, 0x00}, + {104, 0x00}, + {98, 0x00}, + {93, 0x00}, + {88, 0x00}, + {83, 0x00}, + {78, 0x00}, + }, + /* 2.4GHz power gain index table */ + { + {110, 0x3f}, /* highest txpower */ + {104, 0x3f}, + {98, 0x3f}, + {110, 0x3e}, + {104, 0x3e}, + {98, 0x3e}, + {110, 0x3d}, + {104, 0x3d}, + {98, 0x3d}, + {110, 0x3c}, + {104, 0x3c}, + {98, 0x3c}, + {110, 0x3b}, + {104, 0x3b}, + {98, 0x3b}, + {110, 0x3a}, + {104, 0x3a}, + {98, 0x3a}, + {110, 0x39}, + {104, 0x39}, + {98, 0x39}, + {110, 0x38}, + {104, 0x38}, + {98, 0x38}, + {110, 0x37}, + {104, 0x37}, + {98, 0x37}, + {110, 0x36}, + {104, 0x36}, + {98, 0x36}, + {110, 0x35}, + {104, 0x35}, + {98, 0x35}, + {110, 0x34}, + {104, 0x34}, + {98, 0x34}, + {110, 0x33}, + {104, 0x33}, + {98, 0x33}, + {110, 0x32}, + {104, 0x32}, + {98, 0x32}, + {110, 0x31}, + {104, 0x31}, + {98, 0x31}, + {110, 0x30}, + {104, 0x30}, + {98, 0x30}, + {110, 0x6}, + {104, 0x6}, + {98, 0x6}, + {110, 0x5}, + {104, 0x5}, + {98, 0x5}, + {110, 0x4}, + {104, 0x4}, + {98, 0x4}, + {110, 0x3}, + {104, 0x3}, + {98, 0x3}, + {110, 0x2}, + {104, 0x2}, + {98, 0x2}, + {110, 0x1}, + {104, 0x1}, + {98, 0x1}, + {110, 0x0}, + {104, 0x0}, + {98, 0x0}, + {97, 0}, + {96, 0}, + {95, 0}, + {94, 0}, + {93, 0}, + {92, 0}, + {91, 0}, + {90, 0}, + {89, 0}, + {88, 0}, + {87, 0}, + {86, 0}, + {85, 0}, + {84, 0}, + {83, 0}, + {82, 0}, + {81, 0}, + {80, 0}, + {79, 0}, + {78, 0}, + {77, 0}, + {76, 0}, + {75, 0}, + {74, 0}, + {73, 0}, + {72, 0}, + {71, 0}, + {70, 0}, + {69, 0}, + {68, 0}, + {67, 0}, + {66, 0}, + {65, 0}, + {64, 0}, + {63, 0}, + {62, 0}, + {61, 0}, + {60, 0}, + {59, 0}, + } +}; + +static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, + u8 is_ht40, u8 ctrl_chan_high, + struct iwl4965_tx_power_db *tx_power_tbl) +{ + u8 saturation_power; + s32 target_power; + s32 user_target_power; + s32 power_limit; + s32 current_temp; + s32 reg_limit; + s32 current_regulatory; + s32 txatten_grp = CALIB_CH_GROUP_MAX; + int i; + int c; + const struct iwl_channel_info *ch_info = NULL; + struct iwl_eeprom_calib_ch_info ch_eeprom_info; + const struct iwl_eeprom_calib_measure *measurement; + s16 voltage; + s32 init_voltage; + s32 voltage_compensation; + s32 degrees_per_05db_num; + s32 degrees_per_05db_denom; + s32 factory_temp; + s32 temperature_comp[2]; + s32 factory_gain_index[2]; + s32 factory_actual_pwr[2]; + s32 power_index; + + /* tx_power_user_lmt is in dBm, convert to half-dBm (half-dB units + * are used for indexing into txpower table) */ + user_target_power = 2 * priv->tx_power_user_lmt; + + /* Get current (RXON) channel, band, width */ + IWL_DEBUG_TXPOWER(priv, "chan %d band %d is_ht40 %d\n", channel, band, + is_ht40); + + ch_info = iwl_legacy_get_channel_info(priv, priv->band, channel); + + if (!iwl_legacy_is_channel_valid(ch_info)) + return -EINVAL; + + /* get txatten group, used to select 1) thermal txpower adjustment + * and 2) mimo txpower balance between Tx chains. */ + txatten_grp = iwl4965_get_tx_atten_grp(channel); + if (txatten_grp < 0) { + IWL_ERR(priv, "Can't find txatten group for channel %d.\n", + channel); + return -EINVAL; + } + + IWL_DEBUG_TXPOWER(priv, "channel %d belongs to txatten group %d\n", + channel, txatten_grp); + + if (is_ht40) { + if (ctrl_chan_high) + channel -= 2; + else + channel += 2; + } + + /* hardware txpower limits ... + * saturation (clipping distortion) txpowers are in half-dBm */ + if (band) + saturation_power = priv->calib_info->saturation_power24; + else + saturation_power = priv->calib_info->saturation_power52; + + if (saturation_power < IWL_TX_POWER_SATURATION_MIN || + saturation_power > IWL_TX_POWER_SATURATION_MAX) { + if (band) + saturation_power = IWL_TX_POWER_DEFAULT_SATURATION_24; + else + saturation_power = IWL_TX_POWER_DEFAULT_SATURATION_52; + } + + /* regulatory txpower limits ... reg_limit values are in half-dBm, + * max_power_avg values are in dBm, convert * 2 */ + if (is_ht40) + reg_limit = ch_info->ht40_max_power_avg * 2; + else + reg_limit = ch_info->max_power_avg * 2; + + if ((reg_limit < IWL_TX_POWER_REGULATORY_MIN) || + (reg_limit > IWL_TX_POWER_REGULATORY_MAX)) { + if (band) + reg_limit = IWL_TX_POWER_DEFAULT_REGULATORY_24; + else + reg_limit = IWL_TX_POWER_DEFAULT_REGULATORY_52; + } + + /* Interpolate txpower calibration values for this channel, + * based on factory calibration tests on spaced channels. */ + iwl4965_interpolate_chan(priv, channel, &ch_eeprom_info); + + /* calculate tx gain adjustment based on power supply voltage */ + voltage = le16_to_cpu(priv->calib_info->voltage); + init_voltage = (s32)le32_to_cpu(priv->card_alive_init.voltage); + voltage_compensation = + iwl4965_get_voltage_compensation(voltage, init_voltage); + + IWL_DEBUG_TXPOWER(priv, "curr volt %d eeprom volt %d volt comp %d\n", + init_voltage, + voltage, voltage_compensation); + + /* get current temperature (Celsius) */ + current_temp = max(priv->temperature, IWL_TX_POWER_TEMPERATURE_MIN); + current_temp = min(priv->temperature, IWL_TX_POWER_TEMPERATURE_MAX); + current_temp = KELVIN_TO_CELSIUS(current_temp); + + /* select thermal txpower adjustment params, based on channel group + * (same frequency group used for mimo txatten adjustment) */ + degrees_per_05db_num = + tx_power_cmp_tble[txatten_grp].degrees_per_05db_a; + degrees_per_05db_denom = + tx_power_cmp_tble[txatten_grp].degrees_per_05db_a_denom; + + /* get per-chain txpower values from factory measurements */ + for (c = 0; c < 2; c++) { + measurement = &ch_eeprom_info.measurements[c][1]; + + /* txgain adjustment (in half-dB steps) based on difference + * between factory and current temperature */ + factory_temp = measurement->temperature; + iwl4965_math_div_round((current_temp - factory_temp) * + degrees_per_05db_denom, + degrees_per_05db_num, + &temperature_comp[c]); + + factory_gain_index[c] = measurement->gain_idx; + factory_actual_pwr[c] = measurement->actual_pow; + + IWL_DEBUG_TXPOWER(priv, "chain = %d\n", c); + IWL_DEBUG_TXPOWER(priv, "fctry tmp %d, " + "curr tmp %d, comp %d steps\n", + factory_temp, current_temp, + temperature_comp[c]); + + IWL_DEBUG_TXPOWER(priv, "fctry idx %d, fctry pwr %d\n", + factory_gain_index[c], + factory_actual_pwr[c]); + } + + /* for each of 33 bit-rates (including 1 for CCK) */ + for (i = 0; i < POWER_TABLE_NUM_ENTRIES; i++) { + u8 is_mimo_rate; + union iwl4965_tx_power_dual_stream tx_power; + + /* for mimo, reduce each chain's txpower by half + * (3dB, 6 steps), so total output power is regulatory + * compliant. */ + if (i & 0x8) { + current_regulatory = reg_limit - + IWL_TX_POWER_MIMO_REGULATORY_COMPENSATION; + is_mimo_rate = 1; + } else { + current_regulatory = reg_limit; + is_mimo_rate = 0; + } + + /* find txpower limit, either hardware or regulatory */ + power_limit = saturation_power - back_off_table[i]; + if (power_limit > current_regulatory) + power_limit = current_regulatory; + + /* reduce user's txpower request if necessary + * for this rate on this channel */ + target_power = user_target_power; + if (target_power > power_limit) + target_power = power_limit; + + IWL_DEBUG_TXPOWER(priv, "rate %d sat %d reg %d usr %d tgt %d\n", + i, saturation_power - back_off_table[i], + current_regulatory, user_target_power, + target_power); + + /* for each of 2 Tx chains (radio transmitters) */ + for (c = 0; c < 2; c++) { + s32 atten_value; + + if (is_mimo_rate) + atten_value = + (s32)le32_to_cpu(priv->card_alive_init. + tx_atten[txatten_grp][c]); + else + atten_value = 0; + + /* calculate index; higher index means lower txpower */ + power_index = (u8) (factory_gain_index[c] - + (target_power - + factory_actual_pwr[c]) - + temperature_comp[c] - + voltage_compensation + + atten_value); + +/* IWL_DEBUG_TXPOWER(priv, "calculated txpower index %d\n", + power_index); */ + + if (power_index < get_min_power_index(i, band)) + power_index = get_min_power_index(i, band); + + /* adjust 5 GHz index to support negative indexes */ + if (!band) + power_index += 9; + + /* CCK, rate 32, reduce txpower for CCK */ + if (i == POWER_TABLE_CCK_ENTRY) + power_index += + IWL_TX_POWER_CCK_COMPENSATION_C_STEP; + + /* stay within the table! */ + if (power_index > 107) { + IWL_WARN(priv, "txpower index %d > 107\n", + power_index); + power_index = 107; + } + if (power_index < 0) { + IWL_WARN(priv, "txpower index %d < 0\n", + power_index); + power_index = 0; + } + + /* fill txpower command for this rate/chain */ + tx_power.s.radio_tx_gain[c] = + gain_table[band][power_index].radio; + tx_power.s.dsp_predis_atten[c] = + gain_table[band][power_index].dsp; + + IWL_DEBUG_TXPOWER(priv, "chain %d mimo %d index %d " + "gain 0x%02x dsp %d\n", + c, atten_value, power_index, + tx_power.s.radio_tx_gain[c], + tx_power.s.dsp_predis_atten[c]); + } /* for each chain */ + + tx_power_tbl->power_tbl[i].dw = cpu_to_le32(tx_power.dw); + + } /* for each rate */ + + return 0; +} + +/** + * iwl4965_send_tx_power - Configure the TXPOWER level user limit + * + * Uses the active RXON for channel, band, and characteristics (ht40, high) + * The power limit is taken from priv->tx_power_user_lmt. + */ +static int iwl4965_send_tx_power(struct iwl_priv *priv) +{ + struct iwl4965_txpowertable_cmd cmd = { 0 }; + int ret; + u8 band = 0; + bool is_ht40 = false; + u8 ctrl_chan_high = 0; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status), + "TX Power requested while scanning!\n")) + return -EAGAIN; + + band = priv->band == IEEE80211_BAND_2GHZ; + + is_ht40 = iw4965_is_ht40_channel(ctx->active.flags); + + if (is_ht40 && (ctx->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) + ctrl_chan_high = 1; + + cmd.band = band; + cmd.channel = ctx->active.channel; + + ret = iwl4965_fill_txpower_tbl(priv, band, + le16_to_cpu(ctx->active.channel), + is_ht40, ctrl_chan_high, &cmd.tx_power); + if (ret) + goto out; + + ret = iwl_legacy_send_cmd_pdu(priv, + REPLY_TX_PWR_TABLE_CMD, sizeof(cmd), &cmd); + +out: + return ret; +} + +static int iwl4965_send_rxon_assoc(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + int ret = 0; + struct iwl4965_rxon_assoc_cmd rxon_assoc; + const struct iwl_legacy_rxon_cmd *rxon1 = &ctx->staging; + const struct iwl_legacy_rxon_cmd *rxon2 = &ctx->active; + + if ((rxon1->flags == rxon2->flags) && + (rxon1->filter_flags == rxon2->filter_flags) && + (rxon1->cck_basic_rates == rxon2->cck_basic_rates) && + (rxon1->ofdm_ht_single_stream_basic_rates == + rxon2->ofdm_ht_single_stream_basic_rates) && + (rxon1->ofdm_ht_dual_stream_basic_rates == + rxon2->ofdm_ht_dual_stream_basic_rates) && + (rxon1->rx_chain == rxon2->rx_chain) && + (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) { + IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n"); + return 0; + } + + rxon_assoc.flags = ctx->staging.flags; + rxon_assoc.filter_flags = ctx->staging.filter_flags; + rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; + rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; + rxon_assoc.reserved = 0; + rxon_assoc.ofdm_ht_single_stream_basic_rates = + ctx->staging.ofdm_ht_single_stream_basic_rates; + rxon_assoc.ofdm_ht_dual_stream_basic_rates = + ctx->staging.ofdm_ht_dual_stream_basic_rates; + rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain; + + ret = iwl_legacy_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC, + sizeof(rxon_assoc), &rxon_assoc, NULL); + if (ret) + return ret; + + return ret; +} + +static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +{ + /* cast away the const for active_rxon in this function */ + struct iwl_legacy_rxon_cmd *active_rxon = (void *)&ctx->active; + int ret; + bool new_assoc = + !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); + + if (!iwl_legacy_is_alive(priv)) + return -EBUSY; + + if (!ctx->is_active) + return 0; + + /* always get timestamp with Rx frame */ + ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; + + ret = iwl_legacy_check_rxon_cmd(priv, ctx); + if (ret) { + IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); + return -EINVAL; + } + + /* + * receive commit_rxon request + * abort any previous channel switch if still in process + */ + if (priv->switch_rxon.switch_in_progress && + (priv->switch_rxon.channel != ctx->staging.channel)) { + IWL_DEBUG_11H(priv, "abort channel switch on %d\n", + le16_to_cpu(priv->switch_rxon.channel)); + iwl_legacy_chswitch_done(priv, false); + } + + /* If we don't need to send a full RXON, we can use + * iwl_rxon_assoc_cmd which is used to reconfigure filter + * and other flags for the current radio configuration. */ + if (!iwl_legacy_full_rxon_required(priv, ctx)) { + ret = iwl_legacy_send_rxon_assoc(priv, ctx); + if (ret) { + IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret); + return ret; + } + + memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); + iwl_legacy_print_rx_config_cmd(priv, ctx); + return 0; + } + + /* If we are currently associated and the new config requires + * an RXON_ASSOC and the new config wants the associated mask enabled, + * we must clear the associated from the active configuration + * before we apply the new config */ + if (iwl_legacy_is_associated_ctx(ctx) && new_assoc) { + IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); + active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; + + ret = iwl_legacy_send_cmd_pdu(priv, ctx->rxon_cmd, + sizeof(struct iwl_legacy_rxon_cmd), + active_rxon); + + /* If the mask clearing failed then we set + * active_rxon back to what it was previously */ + if (ret) { + active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; + IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret); + return ret; + } + iwl_legacy_clear_ucode_stations(priv, ctx); + iwl_legacy_restore_stations(priv, ctx); + ret = iwl4965_restore_default_wep_keys(priv, ctx); + if (ret) { + IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); + return ret; + } + } + + IWL_DEBUG_INFO(priv, "Sending RXON\n" + "* with%s RXON_FILTER_ASSOC_MSK\n" + "* channel = %d\n" + "* bssid = %pM\n", + (new_assoc ? "" : "out"), + le16_to_cpu(ctx->staging.channel), + ctx->staging.bssid_addr); + + iwl_legacy_set_rxon_hwcrypto(priv, ctx, + !priv->cfg->mod_params->sw_crypto); + + /* Apply the new configuration + * RXON unassoc clears the station table in uCode so restoration of + * stations is needed after it (the RXON command) completes + */ + if (!new_assoc) { + ret = iwl_legacy_send_cmd_pdu(priv, ctx->rxon_cmd, + sizeof(struct iwl_legacy_rxon_cmd), &ctx->staging); + if (ret) { + IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); + return ret; + } + IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n"); + memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); + iwl_legacy_clear_ucode_stations(priv, ctx); + iwl_legacy_restore_stations(priv, ctx); + ret = iwl4965_restore_default_wep_keys(priv, ctx); + if (ret) { + IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); + return ret; + } + } + if (new_assoc) { + priv->start_calib = 0; + /* Apply the new configuration + * RXON assoc doesn't clear the station table in uCode, + */ + ret = iwl_legacy_send_cmd_pdu(priv, ctx->rxon_cmd, + sizeof(struct iwl_legacy_rxon_cmd), &ctx->staging); + if (ret) { + IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); + return ret; + } + memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); + } + iwl_legacy_print_rx_config_cmd(priv, ctx); + + iwl4965_init_sensitivity(priv); + + /* If we issue a new RXON command which required a tune then we must + * send a new TXPOWER command or we won't be able to Tx any frames */ + ret = iwl_legacy_set_tx_power(priv, priv->tx_power_user_lmt, true); + if (ret) { + IWL_ERR(priv, "Error sending TX power (%d)\n", ret); + return ret; + } + + return 0; +} + +static int iwl4965_hw_channel_switch(struct iwl_priv *priv, + struct ieee80211_channel_switch *ch_switch) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + int rc; + u8 band = 0; + bool is_ht40 = false; + u8 ctrl_chan_high = 0; + struct iwl4965_channel_switch_cmd cmd; + const struct iwl_channel_info *ch_info; + u32 switch_time_in_usec, ucode_switch_time; + u16 ch; + u32 tsf_low; + u8 switch_count; + u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); + struct ieee80211_vif *vif = ctx->vif; + band = priv->band == IEEE80211_BAND_2GHZ; + + is_ht40 = iw4965_is_ht40_channel(ctx->staging.flags); + + if (is_ht40 && + (ctx->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) + ctrl_chan_high = 1; + + cmd.band = band; + cmd.expect_beacon = 0; + ch = ch_switch->channel->hw_value; + cmd.channel = cpu_to_le16(ch); + cmd.rxon_flags = ctx->staging.flags; + cmd.rxon_filter_flags = ctx->staging.filter_flags; + switch_count = ch_switch->count; + tsf_low = ch_switch->timestamp & 0x0ffffffff; + /* + * calculate the ucode channel switch time + * adding TSF as one of the factor for when to switch + */ + if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) { + if (switch_count > ((priv->ucode_beacon_time - tsf_low) / + beacon_interval)) { + switch_count -= (priv->ucode_beacon_time - + tsf_low) / beacon_interval; + } else + switch_count = 0; + } + if (switch_count <= 1) + cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); + else { + switch_time_in_usec = + vif->bss_conf.beacon_int * switch_count * TIME_UNIT; + ucode_switch_time = iwl_legacy_usecs_to_beacons(priv, + switch_time_in_usec, + beacon_interval); + cmd.switch_time = iwl_legacy_add_beacon_time(priv, + priv->ucode_beacon_time, + ucode_switch_time, + beacon_interval); + } + IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", + cmd.switch_time); + ch_info = iwl_legacy_get_channel_info(priv, priv->band, ch); + if (ch_info) + cmd.expect_beacon = iwl_legacy_is_channel_radar(ch_info); + else { + IWL_ERR(priv, "invalid channel switch from %u to %u\n", + ctx->active.channel, ch); + return -EFAULT; + } + + rc = iwl4965_fill_txpower_tbl(priv, band, ch, is_ht40, + ctrl_chan_high, &cmd.tx_power); + if (rc) { + IWL_DEBUG_11H(priv, "error:%d fill txpower_tbl\n", rc); + return rc; + } + + priv->switch_rxon.channel = cmd.channel; + priv->switch_rxon.switch_in_progress = true; + + return iwl_legacy_send_cmd_pdu(priv, + REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); +} + +/** + * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array + */ +static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv, + struct iwl_tx_queue *txq, + u16 byte_cnt) +{ + struct iwl4965_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr; + int txq_id = txq->q.id; + int write_ptr = txq->q.write_ptr; + int len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; + __le16 bc_ent; + + WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX); + + bc_ent = cpu_to_le16(len & 0xFFF); + /* Set up byte count within first 256 entries */ + scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent; + + /* If within first 64 entries, duplicate at end */ + if (write_ptr < TFD_QUEUE_SIZE_BC_DUP) + scd_bc_tbl[txq_id]. + tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; +} + +/** + * iwl4965_hw_get_temperature - return the calibrated temperature (in Kelvin) + * @statistics: Provides the temperature reading from the uCode + * + * A return of <0 indicates bogus data in the statistics + */ +static int iwl4965_hw_get_temperature(struct iwl_priv *priv) +{ + s32 temperature; + s32 vt; + s32 R1, R2, R3; + u32 R4; + + if (test_bit(STATUS_TEMPERATURE, &priv->status) && + (priv->_4965.statistics.flag & + STATISTICS_REPLY_FLG_HT40_MODE_MSK)) { + IWL_DEBUG_TEMP(priv, "Running HT40 temperature calibration\n"); + R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]); + R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]); + R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[1]); + R4 = le32_to_cpu(priv->card_alive_init.therm_r4[1]); + } else { + IWL_DEBUG_TEMP(priv, "Running temperature calibration\n"); + R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[0]); + R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[0]); + R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[0]); + R4 = le32_to_cpu(priv->card_alive_init.therm_r4[0]); + } + + /* + * Temperature is only 23 bits, so sign extend out to 32. + * + * NOTE If we haven't received a statistics notification yet + * with an updated temperature, use R4 provided to us in the + * "initialize" ALIVE response. + */ + if (!test_bit(STATUS_TEMPERATURE, &priv->status)) + vt = sign_extend32(R4, 23); + else + vt = sign_extend32(le32_to_cpu(priv->_4965.statistics. + general.common.temperature), 23); + + IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt); + + if (R3 == R1) { + IWL_ERR(priv, "Calibration conflict R1 == R3\n"); + return -1; + } + + /* Calculate temperature in degrees Kelvin, adjust by 97%. + * Add offset to center the adjustment around 0 degrees Centigrade. */ + temperature = TEMPERATURE_CALIB_A_VAL * (vt - R2); + temperature /= (R3 - R1); + temperature = (temperature * 97) / 100 + TEMPERATURE_CALIB_KELVIN_OFFSET; + + IWL_DEBUG_TEMP(priv, "Calibrated temperature: %dK, %dC\n", + temperature, KELVIN_TO_CELSIUS(temperature)); + + return temperature; +} + +/* Adjust Txpower only if temperature variance is greater than threshold. */ +#define IWL_TEMPERATURE_THRESHOLD 3 + +/** + * iwl4965_is_temp_calib_needed - determines if new calibration is needed + * + * If the temperature changed has changed sufficiently, then a recalibration + * is needed. + * + * Assumes caller will replace priv->last_temperature once calibration + * executed. + */ +static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv) +{ + int temp_diff; + + if (!test_bit(STATUS_STATISTICS, &priv->status)) { + IWL_DEBUG_TEMP(priv, "Temperature not updated -- no statistics.\n"); + return 0; + } + + temp_diff = priv->temperature - priv->last_temperature; + + /* get absolute value */ + if (temp_diff < 0) { + IWL_DEBUG_POWER(priv, "Getting cooler, delta %d\n", temp_diff); + temp_diff = -temp_diff; + } else if (temp_diff == 0) + IWL_DEBUG_POWER(priv, "Temperature unchanged\n"); + else + IWL_DEBUG_POWER(priv, "Getting warmer, delta %d\n", temp_diff); + + if (temp_diff < IWL_TEMPERATURE_THRESHOLD) { + IWL_DEBUG_POWER(priv, " => thermal txpower calib not needed\n"); + return 0; + } + + IWL_DEBUG_POWER(priv, " => thermal txpower calib needed\n"); + + return 1; +} + +static void iwl4965_temperature_calib(struct iwl_priv *priv) +{ + s32 temp; + + temp = iwl4965_hw_get_temperature(priv); + if (temp < 0) + return; + + if (priv->temperature != temp) { + if (priv->temperature) + IWL_DEBUG_TEMP(priv, "Temperature changed " + "from %dC to %dC\n", + KELVIN_TO_CELSIUS(priv->temperature), + KELVIN_TO_CELSIUS(temp)); + else + IWL_DEBUG_TEMP(priv, "Temperature " + "initialized to %dC\n", + KELVIN_TO_CELSIUS(temp)); + } + + priv->temperature = temp; + set_bit(STATUS_TEMPERATURE, &priv->status); + + if (!priv->disable_tx_power_cal && + unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && + iwl4965_is_temp_calib_needed(priv)) + queue_work(priv->workqueue, &priv->txpower_work); +} + +static u16 iwl4965_get_hcmd_size(u8 cmd_id, u16 len) +{ + switch (cmd_id) { + case REPLY_RXON: + return (u16) sizeof(struct iwl4965_rxon_cmd); + default: + return len; + } +} + +static u16 iwl4965_build_addsta_hcmd(const struct iwl_legacy_addsta_cmd *cmd, + u8 *data) +{ + struct iwl4965_addsta_cmd *addsta = (struct iwl4965_addsta_cmd *)data; + addsta->mode = cmd->mode; + memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify)); + memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo)); + addsta->station_flags = cmd->station_flags; + addsta->station_flags_msk = cmd->station_flags_msk; + addsta->tid_disable_tx = cmd->tid_disable_tx; + addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid; + addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid; + addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn; + addsta->sleep_tx_count = cmd->sleep_tx_count; + addsta->reserved1 = cpu_to_le16(0); + addsta->reserved2 = cpu_to_le16(0); + + return (u16)sizeof(struct iwl4965_addsta_cmd); +} + +static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp) +{ + return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN; +} + +/** + * iwl4965_tx_status_reply_tx - Handle Tx response for frames in aggregation queue + */ +static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, + struct iwl_ht_agg *agg, + struct iwl4965_tx_resp *tx_resp, + int txq_id, u16 start_idx) +{ + u16 status; + struct agg_tx_status *frame_status = tx_resp->u.agg_status; + struct ieee80211_tx_info *info = NULL; + struct ieee80211_hdr *hdr = NULL; + u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); + int i, sh, idx; + u16 seq; + if (agg->wait_for_ba) + IWL_DEBUG_TX_REPLY(priv, "got tx response w/o block-ack\n"); + + agg->frame_count = tx_resp->frame_count; + agg->start_idx = start_idx; + agg->rate_n_flags = rate_n_flags; + agg->bitmap = 0; + + /* num frames attempted by Tx command */ + if (agg->frame_count == 1) { + /* Only one frame was attempted; no block-ack will arrive */ + status = le16_to_cpu(frame_status[0].status); + idx = start_idx; + + IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n", + agg->frame_count, agg->start_idx, idx); + + info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb); + info->status.rates[0].count = tx_resp->failure_frame + 1; + info->flags &= ~IEEE80211_TX_CTL_AMPDU; + info->flags |= iwl4965_tx_status_to_mac80211(status); + iwl4965_hwrate_to_tx_control(priv, rate_n_flags, info); + + IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n", + status & 0xff, tx_resp->failure_frame); + IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags); + + agg->wait_for_ba = 0; + } else { + /* Two or more frames were attempted; expect block-ack */ + u64 bitmap = 0; + int start = agg->start_idx; + + /* Construct bit-map of pending frames within Tx window */ + for (i = 0; i < agg->frame_count; i++) { + u16 sc; + status = le16_to_cpu(frame_status[i].status); + seq = le16_to_cpu(frame_status[i].sequence); + idx = SEQ_TO_INDEX(seq); + txq_id = SEQ_TO_QUEUE(seq); + + if (status & (AGG_TX_STATE_FEW_BYTES_MSK | + AGG_TX_STATE_ABORT_MSK)) + continue; + + IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n", + agg->frame_count, txq_id, idx); + + hdr = iwl_legacy_tx_queue_get_hdr(priv, txq_id, idx); + if (!hdr) { + IWL_ERR(priv, + "BUG_ON idx doesn't point to valid skb" + " idx=%d, txq_id=%d\n", idx, txq_id); + return -1; + } + + sc = le16_to_cpu(hdr->seq_ctrl); + if (idx != (SEQ_TO_SN(sc) & 0xff)) { + IWL_ERR(priv, + "BUG_ON idx doesn't match seq control" + " idx=%d, seq_idx=%d, seq=%d\n", + idx, SEQ_TO_SN(sc), hdr->seq_ctrl); + return -1; + } + + IWL_DEBUG_TX_REPLY(priv, "AGG Frame i=%d idx %d seq=%d\n", + i, idx, SEQ_TO_SN(sc)); + + sh = idx - start; + if (sh > 64) { + sh = (start - idx) + 0xff; + bitmap = bitmap << sh; + sh = 0; + start = idx; + } else if (sh < -64) + sh = 0xff - (start - idx); + else if (sh < 0) { + sh = start - idx; + start = idx; + bitmap = bitmap << sh; + sh = 0; + } + bitmap |= 1ULL << sh; + IWL_DEBUG_TX_REPLY(priv, "start=%d bitmap=0x%llx\n", + start, (unsigned long long)bitmap); + } + + agg->bitmap = bitmap; + agg->start_idx = start; + IWL_DEBUG_TX_REPLY(priv, "Frames %d start_idx=%d bitmap=0x%llx\n", + agg->frame_count, agg->start_idx, + (unsigned long long)agg->bitmap); + + if (bitmap) + agg->wait_for_ba = 1; + } + return 0; +} + +static u8 iwl4965_find_station(struct iwl_priv *priv, const u8 *addr) +{ + int i; + int start = 0; + int ret = IWL_INVALID_STATION; + unsigned long flags; + + if ((priv->iw_mode == NL80211_IFTYPE_ADHOC)) + start = IWL_STA_ID; + + if (is_broadcast_ether_addr(addr)) + return priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; + + spin_lock_irqsave(&priv->sta_lock, flags); + for (i = start; i < priv->hw_params.max_stations; i++) + if (priv->stations[i].used && + (!compare_ether_addr(priv->stations[i].sta.sta.addr, + addr))) { + ret = i; + goto out; + } + + IWL_DEBUG_ASSOC_LIMIT(priv, "can not find STA %pM total %d\n", + addr, priv->num_stations); + + out: + /* + * It may be possible that more commands interacting with stations + * arrive before we completed processing the adding of + * station + */ + if (ret != IWL_INVALID_STATION && + (!(priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) || + ((priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) && + (priv->stations[ret].used & IWL_STA_UCODE_INPROGRESS)))) { + IWL_ERR(priv, "Requested station info for sta %d before ready.\n", + ret); + ret = IWL_INVALID_STATION; + } + spin_unlock_irqrestore(&priv->sta_lock, flags); + return ret; +} + +static int iwl4965_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) +{ + if (priv->iw_mode == NL80211_IFTYPE_STATION) { + return IWL_AP_ID; + } else { + u8 *da = ieee80211_get_DA(hdr); + return iwl4965_find_station(priv, da); + } +} + +/** + * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response + */ +static void iwl4965_rx_reply_tx(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + u16 sequence = le16_to_cpu(pkt->hdr.sequence); + int txq_id = SEQ_TO_QUEUE(sequence); + int index = SEQ_TO_INDEX(sequence); + struct iwl_tx_queue *txq = &priv->txq[txq_id]; + struct ieee80211_hdr *hdr; + struct ieee80211_tx_info *info; + struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; + u32 status = le32_to_cpu(tx_resp->u.status); + int uninitialized_var(tid); + int sta_id; + int freed; + u8 *qc = NULL; + unsigned long flags; + + if ((index >= txq->q.n_bd) || (iwl_legacy_queue_used(&txq->q, index) == 0)) { + IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " + "is out of range [0-%d] %d %d\n", txq_id, + index, txq->q.n_bd, txq->q.write_ptr, + txq->q.read_ptr); + return; + } + + txq->time_stamp = jiffies; + info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); + memset(&info->status, 0, sizeof(info->status)); + + hdr = iwl_legacy_tx_queue_get_hdr(priv, txq_id, index); + if (ieee80211_is_data_qos(hdr->frame_control)) { + qc = ieee80211_get_qos_ctl(hdr); + tid = qc[0] & 0xf; + } + + sta_id = iwl4965_get_ra_sta_id(priv, hdr); + if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) { + IWL_ERR(priv, "Station not known\n"); + return; + } + + spin_lock_irqsave(&priv->sta_lock, flags); + if (txq->sched_retry) { + const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); + struct iwl_ht_agg *agg = NULL; + WARN_ON(!qc); + + agg = &priv->stations[sta_id].tid[tid].agg; + + iwl4965_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); + + /* check if BAR is needed */ + if ((tx_resp->frame_count == 1) && !iwl4965_is_tx_success(status)) + info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; + + if (txq->q.read_ptr != (scd_ssn & 0xff)) { + index = iwl_legacy_queue_dec_wrap(scd_ssn & 0xff, + txq->q.n_bd); + IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn " + "%d index %d\n", scd_ssn , index); + freed = iwl4965_tx_queue_reclaim(priv, txq_id, index); + if (qc) + iwl4965_free_tfds_in_queue(priv, sta_id, + tid, freed); + + if (priv->mac80211_registered && + (iwl_legacy_queue_space(&txq->q) > txq->q.low_mark) + && (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) + iwl_legacy_wake_queue(priv, txq); + } + } else { + info->status.rates[0].count = tx_resp->failure_frame + 1; + info->flags |= iwl4965_tx_status_to_mac80211(status); + iwl4965_hwrate_to_tx_control(priv, + le32_to_cpu(tx_resp->rate_n_flags), + info); + + IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) " + "rate_n_flags 0x%x retries %d\n", + txq_id, + iwl4965_get_tx_fail_reason(status), status, + le32_to_cpu(tx_resp->rate_n_flags), + tx_resp->failure_frame); + + freed = iwl4965_tx_queue_reclaim(priv, txq_id, index); + if (qc && likely(sta_id != IWL_INVALID_STATION)) + iwl4965_free_tfds_in_queue(priv, sta_id, tid, freed); + else if (sta_id == IWL_INVALID_STATION) + IWL_DEBUG_TX_REPLY(priv, "Station not known\n"); + + if (priv->mac80211_registered && + (iwl_legacy_queue_space(&txq->q) > txq->q.low_mark)) + iwl_legacy_wake_queue(priv, txq); + } + if (qc && likely(sta_id != IWL_INVALID_STATION)) + iwl4965_txq_check_empty(priv, sta_id, tid, txq_id); + + iwl4965_check_abort_status(priv, tx_resp->frame_count, status); + + spin_unlock_irqrestore(&priv->sta_lock, flags); +} + +static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl4965_beacon_notif *beacon = (void *)pkt->u.raw; + u8 rate __maybe_unused = + iwl4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); + + IWL_DEBUG_RX(priv, "beacon status %#x, retries:%d ibssmgr:%d " + "tsf:0x%.8x%.8x rate:%d\n", + le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK, + beacon->beacon_notify_hdr.failure_frame, + le32_to_cpu(beacon->ibss_mgr_status), + le32_to_cpu(beacon->high_tsf), + le32_to_cpu(beacon->low_tsf), rate); + + priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); +} + +/* Set up 4965-specific Rx frame reply handlers */ +static void iwl4965_rx_handler_setup(struct iwl_priv *priv) +{ + /* Legacy Rx frames */ + priv->rx_handlers[REPLY_RX] = iwl4965_rx_reply_rx; + /* Tx response */ + priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; + priv->rx_handlers[BEACON_NOTIFICATION] = iwl4965_rx_beacon_notif; +} + +static struct iwl_hcmd_ops iwl4965_hcmd = { + .rxon_assoc = iwl4965_send_rxon_assoc, + .commit_rxon = iwl4965_commit_rxon, + .set_rxon_chain = iwl4965_set_rxon_chain, +}; + +static void iwl4965_post_scan(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + /* + * Since setting the RXON may have been deferred while + * performing the scan, fire one off if needed + */ + if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) + iwl_legacy_commit_rxon(priv, ctx); +} + +static void iwl4965_post_associate(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + struct ieee80211_vif *vif = ctx->vif; + struct ieee80211_conf *conf = NULL; + int ret = 0; + + if (!vif || !priv->is_open) + return; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + iwl_legacy_scan_cancel_timeout(priv, 200); + + conf = iwl_legacy_ieee80211_get_hw_conf(priv->hw); + + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwl_legacy_commit_rxon(priv, ctx); + + ret = iwl_legacy_send_rxon_timing(priv, ctx); + if (ret) + IWL_WARN(priv, "RXON timing - " + "Attempting to continue.\n"); + + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + + iwl_legacy_set_rxon_ht(priv, &priv->current_ht_config); + + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + + ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); + + IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", + vif->bss_conf.aid, vif->bss_conf.beacon_int); + + if (vif->bss_conf.use_short_preamble) + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + else + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { + if (vif->bss_conf.use_short_slot) + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + else + ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + } + + iwl_legacy_commit_rxon(priv, ctx); + + IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", + vif->bss_conf.aid, ctx->active.bssid_addr); + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + break; + case NL80211_IFTYPE_ADHOC: + iwl4965_send_beacon_cmd(priv); + break; + default: + IWL_ERR(priv, "%s Should not be called in %d mode\n", + __func__, vif->type); + break; + } + + /* the chain noise calibration will enabled PM upon completion + * If chain noise has already been run, then we need to enable + * power management here */ + if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE) + iwl_legacy_power_update_mode(priv, false); + + /* Enable Rx differential gain and sensitivity calibrations */ + iwl4965_chain_noise_reset(priv); + priv->start_calib = 1; +} + +static void iwl4965_config_ap(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + struct ieee80211_vif *vif = ctx->vif; + int ret = 0; + + lockdep_assert_held(&priv->mutex); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + /* The following should be done only at AP bring up */ + if (!iwl_legacy_is_associated_ctx(ctx)) { + + /* RXON - unassoc (to set timing command) */ + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwl_legacy_commit_rxon(priv, ctx); + + /* RXON Timing */ + ret = iwl_legacy_send_rxon_timing(priv, ctx); + if (ret) + IWL_WARN(priv, "RXON timing failed - " + "Attempting to continue.\n"); + + /* AP has all antennas */ + priv->chain_noise_data.active_chains = + priv->hw_params.valid_rx_ant; + iwl_legacy_set_rxon_ht(priv, &priv->current_ht_config); + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + + ctx->staging.assoc_id = 0; + + if (vif->bss_conf.use_short_preamble) + ctx->staging.flags |= + RXON_FLG_SHORT_PREAMBLE_MSK; + else + ctx->staging.flags &= + ~RXON_FLG_SHORT_PREAMBLE_MSK; + + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { + if (vif->bss_conf.use_short_slot) + ctx->staging.flags |= + RXON_FLG_SHORT_SLOT_MSK; + else + ctx->staging.flags &= + ~RXON_FLG_SHORT_SLOT_MSK; + } + /* need to send beacon cmd before committing assoc RXON! */ + iwl4965_send_beacon_cmd(priv); + /* restore RXON assoc */ + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + iwl_legacy_commit_rxon(priv, ctx); + } + iwl4965_send_beacon_cmd(priv); +} + +static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { + .get_hcmd_size = iwl4965_get_hcmd_size, + .build_addsta_hcmd = iwl4965_build_addsta_hcmd, + .request_scan = iwl4965_request_scan, + .post_scan = iwl4965_post_scan, +}; + +static struct iwl_lib_ops iwl4965_lib = { + .set_hw_params = iwl4965_hw_set_hw_params, + .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, + .txq_attach_buf_to_tfd = iwl4965_hw_txq_attach_buf_to_tfd, + .txq_free_tfd = iwl4965_hw_txq_free_tfd, + .txq_init = iwl4965_hw_tx_queue_init, + .rx_handler_setup = iwl4965_rx_handler_setup, + .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, + .init_alive_start = iwl4965_init_alive_start, + .load_ucode = iwl4965_load_bsm, + .dump_nic_event_log = iwl4965_dump_nic_event_log, + .dump_nic_error_log = iwl4965_dump_nic_error_log, + .dump_fh = iwl4965_dump_fh, + .set_channel_switch = iwl4965_hw_channel_switch, + .apm_ops = { + .init = iwl_legacy_apm_init, + .config = iwl4965_nic_config, + }, + .eeprom_ops = { + .regulatory_bands = { + EEPROM_REGULATORY_BAND_1_CHANNELS, + EEPROM_REGULATORY_BAND_2_CHANNELS, + EEPROM_REGULATORY_BAND_3_CHANNELS, + EEPROM_REGULATORY_BAND_4_CHANNELS, + EEPROM_REGULATORY_BAND_5_CHANNELS, + EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS, + EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS + }, + .acquire_semaphore = iwl4965_eeprom_acquire_semaphore, + .release_semaphore = iwl4965_eeprom_release_semaphore, + }, + .send_tx_power = iwl4965_send_tx_power, + .update_chain_flags = iwl4965_update_chain_flags, + .temp_ops = { + .temperature = iwl4965_temperature_calib, + }, + .debugfs_ops = { + .rx_stats_read = iwl4965_ucode_rx_stats_read, + .tx_stats_read = iwl4965_ucode_tx_stats_read, + .general_stats_read = iwl4965_ucode_general_stats_read, + }, + .check_plcp_health = iwl4965_good_plcp_health, +}; + +static const struct iwl_legacy_ops iwl4965_legacy_ops = { + .post_associate = iwl4965_post_associate, + .config_ap = iwl4965_config_ap, + .manage_ibss_station = iwl4965_manage_ibss_station, + .update_bcast_stations = iwl4965_update_bcast_stations, +}; + +struct ieee80211_ops iwl4965_hw_ops = { + .tx = iwl4965_mac_tx, + .start = iwl4965_mac_start, + .stop = iwl4965_mac_stop, + .add_interface = iwl_legacy_mac_add_interface, + .remove_interface = iwl_legacy_mac_remove_interface, + .change_interface = iwl_legacy_mac_change_interface, + .config = iwl_legacy_mac_config, + .configure_filter = iwl4965_configure_filter, + .set_key = iwl4965_mac_set_key, + .update_tkip_key = iwl4965_mac_update_tkip_key, + .conf_tx = iwl_legacy_mac_conf_tx, + .reset_tsf = iwl_legacy_mac_reset_tsf, + .bss_info_changed = iwl_legacy_mac_bss_info_changed, + .ampdu_action = iwl4965_mac_ampdu_action, + .hw_scan = iwl_legacy_mac_hw_scan, + .sta_add = iwl4965_mac_sta_add, + .sta_remove = iwl_legacy_mac_sta_remove, + .channel_switch = iwl4965_mac_channel_switch, + .tx_last_beacon = iwl_legacy_mac_tx_last_beacon, +}; + +static const struct iwl_ops iwl4965_ops = { + .lib = &iwl4965_lib, + .hcmd = &iwl4965_hcmd, + .utils = &iwl4965_hcmd_utils, + .led = &iwl4965_led_ops, + .legacy = &iwl4965_legacy_ops, + .ieee80211_ops = &iwl4965_hw_ops, +}; + +static struct iwl_base_params iwl4965_base_params = { + .eeprom_size = IWL4965_EEPROM_IMG_SIZE, + .num_of_queues = IWL49_NUM_QUEUES, + .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES, + .pll_cfg_val = 0, + .set_l0s = true, + .use_bsm = true, + .led_compensation = 61, + .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .wd_timeout = IWL_DEF_WD_TIMEOUT, + .temperature_kelvin = true, + .max_event_log_size = 512, + .ucode_tracing = true, + .sensitivity_calib_by_driver = true, + .chain_noise_calib_by_driver = true, +}; + +struct iwl_cfg iwl4965_cfg = { + .name = "Intel(R) Wireless WiFi Link 4965AGN", + .fw_name_pre = IWL4965_FW_PRE, + .ucode_api_max = IWL4965_UCODE_API_MAX, + .ucode_api_min = IWL4965_UCODE_API_MIN, + .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_ABC, + .eeprom_ver = EEPROM_4965_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION, + .ops = &iwl4965_ops, + .mod_params = &iwl4965_mod_params, + .base_params = &iwl4965_base_params, + .led_mode = IWL_LED_BLINK, + /* + * Force use of chains B and C for scan RX on 5 GHz band + * because the device has off-channel reception on chain A. + */ + .scan_rx_antennas[IEEE80211_BAND_5GHZ] = ANT_BC, +}; + +/* Module firmware */ +MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE(IWL4965_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.h b/drivers/net/wireless/iwlegacy/iwl-4965.h new file mode 100644 index 000000000000..79e206770f71 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-4965.h @@ -0,0 +1,282 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#ifndef __iwl_4965_h__ +#define __iwl_4965_h__ + +#include "iwl-dev.h" + +/* configuration for the _4965 devices */ +extern struct iwl_cfg iwl4965_cfg; + +extern struct iwl_mod_params iwl4965_mod_params; + +extern struct ieee80211_ops iwl4965_hw_ops; + +/* tx queue */ +void iwl4965_free_tfds_in_queue(struct iwl_priv *priv, + int sta_id, int tid, int freed); + +/* RXON */ +void iwl4965_set_rxon_chain(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); + +/* uCode */ +int iwl4965_verify_ucode(struct iwl_priv *priv); + +/* lib */ +void iwl4965_check_abort_status(struct iwl_priv *priv, + u8 frame_count, u32 status); + +void iwl4965_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); +int iwl4965_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq); +int iwl4965_hw_nic_init(struct iwl_priv *priv); +int iwl4965_dump_fh(struct iwl_priv *priv, char **buf, bool display); + +/* rx */ +void iwl4965_rx_queue_restock(struct iwl_priv *priv); +void iwl4965_rx_replenish(struct iwl_priv *priv); +void iwl4965_rx_replenish_now(struct iwl_priv *priv); +void iwl4965_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq); +int iwl4965_rxq_stop(struct iwl_priv *priv); +int iwl4965_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); +void iwl4965_rx_reply_rx(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); +void iwl4965_rx_reply_rx_phy(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); +void iwl4965_rx_handle(struct iwl_priv *priv); + +/* tx */ +void iwl4965_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); +int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, + struct iwl_tx_queue *txq, + dma_addr_t addr, u16 len, u8 reset, u8 pad); +int iwl4965_hw_tx_queue_init(struct iwl_priv *priv, + struct iwl_tx_queue *txq); +void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, + struct ieee80211_tx_info *info); +int iwl4965_tx_skb(struct iwl_priv *priv, struct sk_buff *skb); +int iwl4965_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u16 tid, u16 *ssn); +int iwl4965_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u16 tid); +int iwl4965_txq_check_empty(struct iwl_priv *priv, + int sta_id, u8 tid, int txq_id); +void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); +int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index); +void iwl4965_hw_txq_ctx_free(struct iwl_priv *priv); +int iwl4965_txq_ctx_alloc(struct iwl_priv *priv); +void iwl4965_txq_ctx_reset(struct iwl_priv *priv); +void iwl4965_txq_ctx_stop(struct iwl_priv *priv); +void iwl4965_txq_set_sched(struct iwl_priv *priv, u32 mask); + +/* + * Acquire priv->lock before calling this function ! + */ +void iwl4965_set_wr_ptrs(struct iwl_priv *priv, int txq_id, u32 index); +/** + * iwl4965_tx_queue_set_status - (optionally) start Tx/Cmd queue + * @tx_fifo_id: Tx DMA/FIFO channel (range 0-7) that the queue will feed + * @scd_retry: (1) Indicates queue will be used in aggregation mode + * + * NOTE: Acquire priv->lock before calling this function ! + */ +void iwl4965_tx_queue_set_status(struct iwl_priv *priv, + struct iwl_tx_queue *txq, + int tx_fifo_id, int scd_retry); + +static inline u32 iwl4965_tx_status_to_mac80211(u32 status) +{ + status &= TX_STATUS_MSK; + + switch (status) { + case TX_STATUS_SUCCESS: + case TX_STATUS_DIRECT_DONE: + return IEEE80211_TX_STAT_ACK; + case TX_STATUS_FAIL_DEST_PS: + return IEEE80211_TX_STAT_TX_FILTERED; + default: + return 0; + } +} + +static inline bool iwl4965_is_tx_success(u32 status) +{ + status &= TX_STATUS_MSK; + return (status == TX_STATUS_SUCCESS) || + (status == TX_STATUS_DIRECT_DONE); +} + +u8 iwl4965_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid); + +/* rx */ +void iwl4965_rx_missed_beacon_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); +bool iwl4965_good_plcp_health(struct iwl_priv *priv, + struct iwl_rx_packet *pkt); +void iwl4965_rx_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); +void iwl4965_reply_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); + +/* scan */ +int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); + +/* station mgmt */ +int iwl4965_manage_ibss_station(struct iwl_priv *priv, + struct ieee80211_vif *vif, bool add); + +/* hcmd */ +int iwl4965_send_beacon_cmd(struct iwl_priv *priv); + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +const char *iwl4965_get_tx_fail_reason(u32 status); +#else +static inline const char * +iwl4965_get_tx_fail_reason(u32 status) { return ""; } +#endif + +/* station management */ +int iwl4965_alloc_bcast_station(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); +int iwl4965_add_bssid_station(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + const u8 *addr, u8 *sta_id_r); +int iwl4965_remove_default_wep_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *key); +int iwl4965_set_default_wep_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *key); +int iwl4965_restore_default_wep_keys(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); +int iwl4965_set_dynamic_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *key, u8 sta_id); +int iwl4965_remove_dynamic_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *key, u8 sta_id); +void iwl4965_update_tkip_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + struct ieee80211_sta *sta, u32 iv32, u16 *phase1key); +int iwl4965_sta_tx_modify_enable_tid(struct iwl_priv *priv, + int sta_id, int tid); +int iwl4965_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, + int tid, u16 ssn); +int iwl4965_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, + int tid); +void iwl4965_sta_modify_sleep_tx_count(struct iwl_priv *priv, + int sta_id, int cnt); +int iwl4965_update_bcast_stations(struct iwl_priv *priv); + +/* rate */ +static inline u32 iwl4965_ant_idx_to_flags(u8 ant_idx) +{ + return BIT(ant_idx) << RATE_MCS_ANT_POS; +} + +static inline u8 iwl4965_hw_get_rate(__le32 rate_n_flags) +{ + return le32_to_cpu(rate_n_flags) & 0xFF; +} + +static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u32 flags) +{ + return cpu_to_le32(flags|(u32)rate); +} + +/* eeprom */ +void iwl4965_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac); +int iwl4965_eeprom_acquire_semaphore(struct iwl_priv *priv); +void iwl4965_eeprom_release_semaphore(struct iwl_priv *priv); +int iwl4965_eeprom_check_version(struct iwl_priv *priv); + +/* mac80211 handlers (for 4965) */ +int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb); +int iwl4965_mac_start(struct ieee80211_hw *hw); +void iwl4965_mac_stop(struct ieee80211_hw *hw); +void iwl4965_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, + u64 multicast); +int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key); +void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_key_conf *keyconf, + struct ieee80211_sta *sta, + u32 iv32, u16 *phase1key); +int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum ieee80211_ampdu_mlme_action action, + struct ieee80211_sta *sta, u16 tid, u16 *ssn, + u8 buf_size); +int iwl4965_mac_sta_add(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_channel_switch *ch_switch); + +#endif /* __iwl_4965_h__ */ diff --git a/drivers/net/wireless/iwlegacy/iwl-commands.h b/drivers/net/wireless/iwlegacy/iwl-commands.h new file mode 100644 index 000000000000..17a1d504348e --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-commands.h @@ -0,0 +1,3405 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +/* + * Please use this file (iwl-commands.h) only for uCode API definitions. + * Please use iwl-xxxx-hw.h for hardware-related definitions. + * Please use iwl-dev.h for driver implementation definitions. + */ + +#ifndef __iwl_legacy_commands_h__ +#define __iwl_legacy_commands_h__ + +struct iwl_priv; + +/* uCode version contains 4 values: Major/Minor/API/Serial */ +#define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24) +#define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16) +#define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8) +#define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF) + + +/* Tx rates */ +#define IWL_CCK_RATES 4 +#define IWL_OFDM_RATES 8 +#define IWL_MAX_RATES (IWL_CCK_RATES + IWL_OFDM_RATES) + +enum { + REPLY_ALIVE = 0x1, + REPLY_ERROR = 0x2, + + /* RXON and QOS commands */ + REPLY_RXON = 0x10, + REPLY_RXON_ASSOC = 0x11, + REPLY_QOS_PARAM = 0x13, + REPLY_RXON_TIMING = 0x14, + + /* Multi-Station support */ + REPLY_ADD_STA = 0x18, + REPLY_REMOVE_STA = 0x19, + + /* Security */ + REPLY_WEPKEY = 0x20, + + /* RX, TX, LEDs */ + REPLY_3945_RX = 0x1b, /* 3945 only */ + REPLY_TX = 0x1c, + REPLY_RATE_SCALE = 0x47, /* 3945 only */ + REPLY_LEDS_CMD = 0x48, + REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* for 4965 and up */ + + /* 802.11h related */ + REPLY_CHANNEL_SWITCH = 0x72, + CHANNEL_SWITCH_NOTIFICATION = 0x73, + REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74, + SPECTRUM_MEASURE_NOTIFICATION = 0x75, + + /* Power Management */ + POWER_TABLE_CMD = 0x77, + PM_SLEEP_NOTIFICATION = 0x7A, + PM_DEBUG_STATISTIC_NOTIFIC = 0x7B, + + /* Scan commands and notifications */ + REPLY_SCAN_CMD = 0x80, + REPLY_SCAN_ABORT_CMD = 0x81, + SCAN_START_NOTIFICATION = 0x82, + SCAN_RESULTS_NOTIFICATION = 0x83, + SCAN_COMPLETE_NOTIFICATION = 0x84, + + /* IBSS/AP commands */ + BEACON_NOTIFICATION = 0x90, + REPLY_TX_BEACON = 0x91, + + /* Miscellaneous commands */ + REPLY_TX_PWR_TABLE_CMD = 0x97, + + /* Bluetooth device coexistence config command */ + REPLY_BT_CONFIG = 0x9b, + + /* Statistics */ + REPLY_STATISTICS_CMD = 0x9c, + STATISTICS_NOTIFICATION = 0x9d, + + /* RF-KILL commands and notifications */ + CARD_STATE_NOTIFICATION = 0xa1, + + /* Missed beacons notification */ + MISSED_BEACONS_NOTIFICATION = 0xa2, + + REPLY_CT_KILL_CONFIG_CMD = 0xa4, + SENSITIVITY_CMD = 0xa8, + REPLY_PHY_CALIBRATION_CMD = 0xb0, + REPLY_RX_PHY_CMD = 0xc0, + REPLY_RX_MPDU_CMD = 0xc1, + REPLY_RX = 0xc3, + REPLY_COMPRESSED_BA = 0xc5, + + REPLY_MAX = 0xff +}; + +/****************************************************************************** + * (0) + * Commonly used structures and definitions: + * Command header, rate_n_flags, txpower + * + *****************************************************************************/ + +/* iwl_cmd_header flags value */ +#define IWL_CMD_FAILED_MSK 0x40 + +#define SEQ_TO_QUEUE(s) (((s) >> 8) & 0x1f) +#define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) +#define SEQ_TO_INDEX(s) ((s) & 0xff) +#define INDEX_TO_SEQ(i) ((i) & 0xff) +#define SEQ_HUGE_FRAME cpu_to_le16(0x4000) +#define SEQ_RX_FRAME cpu_to_le16(0x8000) + +/** + * struct iwl_cmd_header + * + * This header format appears in the beginning of each command sent from the + * driver, and each response/notification received from uCode. + */ +struct iwl_cmd_header { + u8 cmd; /* Command ID: REPLY_RXON, etc. */ + u8 flags; /* 0:5 reserved, 6 abort, 7 internal */ + /* + * The driver sets up the sequence number to values of its choosing. + * uCode does not use this value, but passes it back to the driver + * when sending the response to each driver-originated command, so + * the driver can match the response to the command. Since the values + * don't get used by uCode, the driver may set up an arbitrary format. + * + * There is one exception: uCode sets bit 15 when it originates + * the response/notification, i.e. when the response/notification + * is not a direct response to a command sent by the driver. For + * example, uCode issues REPLY_3945_RX when it sends a received frame + * to the driver; it is not a direct response to any driver command. + * + * The Linux driver uses the following format: + * + * 0:7 tfd index - position within TX queue + * 8:12 TX queue id + * 13 reserved + * 14 huge - driver sets this to indicate command is in the + * 'huge' storage at the end of the command buffers + * 15 unsolicited RX or uCode-originated notification + */ + __le16 sequence; + + /* command or response/notification data follows immediately */ + u8 data[0]; +} __packed; + + +/** + * struct iwl3945_tx_power + * + * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_SCAN_CMD, REPLY_CHANNEL_SWITCH + * + * Each entry contains two values: + * 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained + * linear value that multiplies the output of the digital signal processor, + * before being sent to the analog radio. + * 2) Radio gain. This sets the analog gain of the radio Tx path. + * It is a coarser setting, and behaves in a logarithmic (dB) fashion. + * + * Driver obtains values from struct iwl3945_tx_power power_gain_table[][]. + */ +struct iwl3945_tx_power { + u8 tx_gain; /* gain for analog radio */ + u8 dsp_atten; /* gain for DSP */ +} __packed; + +/** + * struct iwl3945_power_per_rate + * + * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH + */ +struct iwl3945_power_per_rate { + u8 rate; /* plcp */ + struct iwl3945_tx_power tpc; + u8 reserved; +} __packed; + +/** + * iwl4965 rate_n_flags bit fields + * + * rate_n_flags format is used in following iwl4965 commands: + * REPLY_RX (response only) + * REPLY_RX_MPDU (response only) + * REPLY_TX (both command and response) + * REPLY_TX_LINK_QUALITY_CMD + * + * High-throughput (HT) rate format for bits 7:0 (bit 8 must be "1"): + * 2-0: 0) 6 Mbps + * 1) 12 Mbps + * 2) 18 Mbps + * 3) 24 Mbps + * 4) 36 Mbps + * 5) 48 Mbps + * 6) 54 Mbps + * 7) 60 Mbps + * + * 4-3: 0) Single stream (SISO) + * 1) Dual stream (MIMO) + * 2) Triple stream (MIMO) + * + * 5: Value of 0x20 in bits 7:0 indicates 6 Mbps HT40 duplicate data + * + * Legacy OFDM rate format for bits 7:0 (bit 8 must be "0", bit 9 "0"): + * 3-0: 0xD) 6 Mbps + * 0xF) 9 Mbps + * 0x5) 12 Mbps + * 0x7) 18 Mbps + * 0x9) 24 Mbps + * 0xB) 36 Mbps + * 0x1) 48 Mbps + * 0x3) 54 Mbps + * + * Legacy CCK rate format for bits 7:0 (bit 8 must be "0", bit 9 "1"): + * 6-0: 10) 1 Mbps + * 20) 2 Mbps + * 55) 5.5 Mbps + * 110) 11 Mbps + */ +#define RATE_MCS_CODE_MSK 0x7 +#define RATE_MCS_SPATIAL_POS 3 +#define RATE_MCS_SPATIAL_MSK 0x18 +#define RATE_MCS_HT_DUP_POS 5 +#define RATE_MCS_HT_DUP_MSK 0x20 + +/* Bit 8: (1) HT format, (0) legacy format in bits 7:0 */ +#define RATE_MCS_FLAGS_POS 8 +#define RATE_MCS_HT_POS 8 +#define RATE_MCS_HT_MSK 0x100 + +/* Bit 9: (1) CCK, (0) OFDM. HT (bit 8) must be "0" for this bit to be valid */ +#define RATE_MCS_CCK_POS 9 +#define RATE_MCS_CCK_MSK 0x200 + +/* Bit 10: (1) Use Green Field preamble */ +#define RATE_MCS_GF_POS 10 +#define RATE_MCS_GF_MSK 0x400 + +/* Bit 11: (1) Use 40Mhz HT40 chnl width, (0) use 20 MHz legacy chnl width */ +#define RATE_MCS_HT40_POS 11 +#define RATE_MCS_HT40_MSK 0x800 + +/* Bit 12: (1) Duplicate data on both 20MHz chnls. HT40 (bit 11) must be set. */ +#define RATE_MCS_DUP_POS 12 +#define RATE_MCS_DUP_MSK 0x1000 + +/* Bit 13: (1) Short guard interval (0.4 usec), (0) normal GI (0.8 usec) */ +#define RATE_MCS_SGI_POS 13 +#define RATE_MCS_SGI_MSK 0x2000 + +/** + * rate_n_flags Tx antenna masks + * 4965 has 2 transmitters + * bit14:16 + */ +#define RATE_MCS_ANT_POS 14 +#define RATE_MCS_ANT_A_MSK 0x04000 +#define RATE_MCS_ANT_B_MSK 0x08000 +#define RATE_MCS_ANT_C_MSK 0x10000 +#define RATE_MCS_ANT_AB_MSK (RATE_MCS_ANT_A_MSK | RATE_MCS_ANT_B_MSK) +#define RATE_MCS_ANT_ABC_MSK (RATE_MCS_ANT_AB_MSK | RATE_MCS_ANT_C_MSK) +#define RATE_ANT_NUM 3 + +#define POWER_TABLE_NUM_ENTRIES 33 +#define POWER_TABLE_NUM_HT_OFDM_ENTRIES 32 +#define POWER_TABLE_CCK_ENTRY 32 + +#define IWL_PWR_NUM_HT_OFDM_ENTRIES 24 +#define IWL_PWR_CCK_ENTRIES 2 + +/** + * union iwl4965_tx_power_dual_stream + * + * Host format used for REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH + * Use __le32 version (struct tx_power_dual_stream) when building command. + * + * Driver provides radio gain and DSP attenuation settings to device in pairs, + * one value for each transmitter chain. The first value is for transmitter A, + * second for transmitter B. + * + * For SISO bit rates, both values in a pair should be identical. + * For MIMO rates, one value may be different from the other, + * in order to balance the Tx output between the two transmitters. + * + * See more details in doc for TXPOWER in iwl-4965-hw.h. + */ +union iwl4965_tx_power_dual_stream { + struct { + u8 radio_tx_gain[2]; + u8 dsp_predis_atten[2]; + } s; + u32 dw; +}; + +/** + * struct tx_power_dual_stream + * + * Table entries in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH + * + * Same format as iwl_tx_power_dual_stream, but __le32 + */ +struct tx_power_dual_stream { + __le32 dw; +} __packed; + +/** + * struct iwl4965_tx_power_db + * + * Entire table within REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH + */ +struct iwl4965_tx_power_db { + struct tx_power_dual_stream power_tbl[POWER_TABLE_NUM_ENTRIES]; +} __packed; + +/****************************************************************************** + * (0a) + * Alive and Error Commands & Responses: + * + *****************************************************************************/ + +#define UCODE_VALID_OK cpu_to_le32(0x1) +#define INITIALIZE_SUBTYPE (9) + +/* + * ("Initialize") REPLY_ALIVE = 0x1 (response only, not a command) + * + * uCode issues this "initialize alive" notification once the initialization + * uCode image has completed its work, and is ready to load the runtime image. + * This is the *first* "alive" notification that the driver will receive after + * rebooting uCode; the "initialize" alive is indicated by subtype field == 9. + * + * See comments documenting "BSM" (bootstrap state machine). + * + * For 4965, this notification contains important calibration data for + * calculating txpower settings: + * + * 1) Power supply voltage indication. The voltage sensor outputs higher + * values for lower voltage, and vice verse. + * + * 2) Temperature measurement parameters, for each of two channel widths + * (20 MHz and 40 MHz) supported by the radios. Temperature sensing + * is done via one of the receiver chains, and channel width influences + * the results. + * + * 3) Tx gain compensation to balance 4965's 2 Tx chains for MIMO operation, + * for each of 5 frequency ranges. + */ +struct iwl_init_alive_resp { + u8 ucode_minor; + u8 ucode_major; + __le16 reserved1; + u8 sw_rev[8]; + u8 ver_type; + u8 ver_subtype; /* "9" for initialize alive */ + __le16 reserved2; + __le32 log_event_table_ptr; + __le32 error_event_table_ptr; + __le32 timestamp; + __le32 is_valid; + + /* calibration values from "initialize" uCode */ + __le32 voltage; /* signed, higher value is lower voltage */ + __le32 therm_r1[2]; /* signed, 1st for normal, 2nd for HT40 */ + __le32 therm_r2[2]; /* signed */ + __le32 therm_r3[2]; /* signed */ + __le32 therm_r4[2]; /* signed */ + __le32 tx_atten[5][2]; /* signed MIMO gain comp, 5 freq groups, + * 2 Tx chains */ +} __packed; + + +/** + * REPLY_ALIVE = 0x1 (response only, not a command) + * + * uCode issues this "alive" notification once the runtime image is ready + * to receive commands from the driver. This is the *second* "alive" + * notification that the driver will receive after rebooting uCode; + * this "alive" is indicated by subtype field != 9. + * + * See comments documenting "BSM" (bootstrap state machine). + * + * This response includes two pointers to structures within the device's + * data SRAM (access via HBUS_TARG_MEM_* regs) that are useful for debugging: + * + * 1) log_event_table_ptr indicates base of the event log. This traces + * a 256-entry history of uCode execution within a circular buffer. + * Its header format is: + * + * __le32 log_size; log capacity (in number of entries) + * __le32 type; (1) timestamp with each entry, (0) no timestamp + * __le32 wraps; # times uCode has wrapped to top of circular buffer + * __le32 write_index; next circular buffer entry that uCode would fill + * + * The header is followed by the circular buffer of log entries. Entries + * with timestamps have the following format: + * + * __le32 event_id; range 0 - 1500 + * __le32 timestamp; low 32 bits of TSF (of network, if associated) + * __le32 data; event_id-specific data value + * + * Entries without timestamps contain only event_id and data. + * + * + * 2) error_event_table_ptr indicates base of the error log. This contains + * information about any uCode error that occurs. For 4965, the format + * of the error log is: + * + * __le32 valid; (nonzero) valid, (0) log is empty + * __le32 error_id; type of error + * __le32 pc; program counter + * __le32 blink1; branch link + * __le32 blink2; branch link + * __le32 ilink1; interrupt link + * __le32 ilink2; interrupt link + * __le32 data1; error-specific data + * __le32 data2; error-specific data + * __le32 line; source code line of error + * __le32 bcon_time; beacon timer + * __le32 tsf_low; network timestamp function timer + * __le32 tsf_hi; network timestamp function timer + * __le32 gp1; GP1 timer register + * __le32 gp2; GP2 timer register + * __le32 gp3; GP3 timer register + * __le32 ucode_ver; uCode version + * __le32 hw_ver; HW Silicon version + * __le32 brd_ver; HW board version + * __le32 log_pc; log program counter + * __le32 frame_ptr; frame pointer + * __le32 stack_ptr; stack pointer + * __le32 hcmd; last host command + * __le32 isr0; isr status register LMPM_NIC_ISR0: rxtx_flag + * __le32 isr1; isr status register LMPM_NIC_ISR1: host_flag + * __le32 isr2; isr status register LMPM_NIC_ISR2: enc_flag + * __le32 isr3; isr status register LMPM_NIC_ISR3: time_flag + * __le32 isr4; isr status register LMPM_NIC_ISR4: wico interrupt + * __le32 isr_pref; isr status register LMPM_NIC_PREF_STAT + * __le32 wait_event; wait event() caller address + * __le32 l2p_control; L2pControlField + * __le32 l2p_duration; L2pDurationField + * __le32 l2p_mhvalid; L2pMhValidBits + * __le32 l2p_addr_match; L2pAddrMatchStat + * __le32 lmpm_pmg_sel; indicate which clocks are turned on (LMPM_PMG_SEL) + * __le32 u_timestamp; indicate when the date and time of the compilation + * __le32 reserved; + * + * The Linux driver can print both logs to the system log when a uCode error + * occurs. + */ +struct iwl_alive_resp { + u8 ucode_minor; + u8 ucode_major; + __le16 reserved1; + u8 sw_rev[8]; + u8 ver_type; + u8 ver_subtype; /* not "9" for runtime alive */ + __le16 reserved2; + __le32 log_event_table_ptr; /* SRAM address for event log */ + __le32 error_event_table_ptr; /* SRAM address for error log */ + __le32 timestamp; + __le32 is_valid; +} __packed; + +/* + * REPLY_ERROR = 0x2 (response only, not a command) + */ +struct iwl_error_resp { + __le32 error_type; + u8 cmd_id; + u8 reserved1; + __le16 bad_cmd_seq_num; + __le32 error_info; + __le64 timestamp; +} __packed; + +/****************************************************************************** + * (1) + * RXON Commands & Responses: + * + *****************************************************************************/ + +/* + * Rx config defines & structure + */ +/* rx_config device types */ +enum { + RXON_DEV_TYPE_AP = 1, + RXON_DEV_TYPE_ESS = 3, + RXON_DEV_TYPE_IBSS = 4, + RXON_DEV_TYPE_SNIFFER = 6, +}; + + +#define RXON_RX_CHAIN_DRIVER_FORCE_MSK cpu_to_le16(0x1 << 0) +#define RXON_RX_CHAIN_DRIVER_FORCE_POS (0) +#define RXON_RX_CHAIN_VALID_MSK cpu_to_le16(0x7 << 1) +#define RXON_RX_CHAIN_VALID_POS (1) +#define RXON_RX_CHAIN_FORCE_SEL_MSK cpu_to_le16(0x7 << 4) +#define RXON_RX_CHAIN_FORCE_SEL_POS (4) +#define RXON_RX_CHAIN_FORCE_MIMO_SEL_MSK cpu_to_le16(0x7 << 7) +#define RXON_RX_CHAIN_FORCE_MIMO_SEL_POS (7) +#define RXON_RX_CHAIN_CNT_MSK cpu_to_le16(0x3 << 10) +#define RXON_RX_CHAIN_CNT_POS (10) +#define RXON_RX_CHAIN_MIMO_CNT_MSK cpu_to_le16(0x3 << 12) +#define RXON_RX_CHAIN_MIMO_CNT_POS (12) +#define RXON_RX_CHAIN_MIMO_FORCE_MSK cpu_to_le16(0x1 << 14) +#define RXON_RX_CHAIN_MIMO_FORCE_POS (14) + +/* rx_config flags */ +/* band & modulation selection */ +#define RXON_FLG_BAND_24G_MSK cpu_to_le32(1 << 0) +#define RXON_FLG_CCK_MSK cpu_to_le32(1 << 1) +/* auto detection enable */ +#define RXON_FLG_AUTO_DETECT_MSK cpu_to_le32(1 << 2) +/* TGg protection when tx */ +#define RXON_FLG_TGG_PROTECT_MSK cpu_to_le32(1 << 3) +/* cck short slot & preamble */ +#define RXON_FLG_SHORT_SLOT_MSK cpu_to_le32(1 << 4) +#define RXON_FLG_SHORT_PREAMBLE_MSK cpu_to_le32(1 << 5) +/* antenna selection */ +#define RXON_FLG_DIS_DIV_MSK cpu_to_le32(1 << 7) +#define RXON_FLG_ANT_SEL_MSK cpu_to_le32(0x0f00) +#define RXON_FLG_ANT_A_MSK cpu_to_le32(1 << 8) +#define RXON_FLG_ANT_B_MSK cpu_to_le32(1 << 9) +/* radar detection enable */ +#define RXON_FLG_RADAR_DETECT_MSK cpu_to_le32(1 << 12) +#define RXON_FLG_TGJ_NARROW_BAND_MSK cpu_to_le32(1 << 13) +/* rx response to host with 8-byte TSF +* (according to ON_AIR deassertion) */ +#define RXON_FLG_TSF2HOST_MSK cpu_to_le32(1 << 15) + + +/* HT flags */ +#define RXON_FLG_CTRL_CHANNEL_LOC_POS (22) +#define RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK cpu_to_le32(0x1 << 22) + +#define RXON_FLG_HT_OPERATING_MODE_POS (23) + +#define RXON_FLG_HT_PROT_MSK cpu_to_le32(0x1 << 23) +#define RXON_FLG_HT40_PROT_MSK cpu_to_le32(0x2 << 23) + +#define RXON_FLG_CHANNEL_MODE_POS (25) +#define RXON_FLG_CHANNEL_MODE_MSK cpu_to_le32(0x3 << 25) + +/* channel mode */ +enum { + CHANNEL_MODE_LEGACY = 0, + CHANNEL_MODE_PURE_40 = 1, + CHANNEL_MODE_MIXED = 2, + CHANNEL_MODE_RESERVED = 3, +}; +#define RXON_FLG_CHANNEL_MODE_LEGACY \ + cpu_to_le32(CHANNEL_MODE_LEGACY << RXON_FLG_CHANNEL_MODE_POS) +#define RXON_FLG_CHANNEL_MODE_PURE_40 \ + cpu_to_le32(CHANNEL_MODE_PURE_40 << RXON_FLG_CHANNEL_MODE_POS) +#define RXON_FLG_CHANNEL_MODE_MIXED \ + cpu_to_le32(CHANNEL_MODE_MIXED << RXON_FLG_CHANNEL_MODE_POS) + +/* CTS to self (if spec allows) flag */ +#define RXON_FLG_SELF_CTS_EN cpu_to_le32(0x1<<30) + +/* rx_config filter flags */ +/* accept all data frames */ +#define RXON_FILTER_PROMISC_MSK cpu_to_le32(1 << 0) +/* pass control & management to host */ +#define RXON_FILTER_CTL2HOST_MSK cpu_to_le32(1 << 1) +/* accept multi-cast */ +#define RXON_FILTER_ACCEPT_GRP_MSK cpu_to_le32(1 << 2) +/* don't decrypt uni-cast frames */ +#define RXON_FILTER_DIS_DECRYPT_MSK cpu_to_le32(1 << 3) +/* don't decrypt multi-cast frames */ +#define RXON_FILTER_DIS_GRP_DECRYPT_MSK cpu_to_le32(1 << 4) +/* STA is associated */ +#define RXON_FILTER_ASSOC_MSK cpu_to_le32(1 << 5) +/* transfer to host non bssid beacons in associated state */ +#define RXON_FILTER_BCON_AWARE_MSK cpu_to_le32(1 << 6) + +/** + * REPLY_RXON = 0x10 (command, has simple generic response) + * + * RXON tunes the radio tuner to a service channel, and sets up a number + * of parameters that are used primarily for Rx, but also for Tx operations. + * + * NOTE: When tuning to a new channel, driver must set the + * RXON_FILTER_ASSOC_MSK to 0. This will clear station-dependent + * info within the device, including the station tables, tx retry + * rate tables, and txpower tables. Driver must build a new station + * table and txpower table before transmitting anything on the RXON + * channel. + * + * NOTE: All RXONs wipe clean the internal txpower table. Driver must + * issue a new REPLY_TX_PWR_TABLE_CMD after each REPLY_RXON (0x10), + * regardless of whether RXON_FILTER_ASSOC_MSK is set. + */ + +struct iwl3945_rxon_cmd { + u8 node_addr[6]; + __le16 reserved1; + u8 bssid_addr[6]; + __le16 reserved2; + u8 wlap_bssid_addr[6]; + __le16 reserved3; + u8 dev_type; + u8 air_propagation; + __le16 reserved4; + u8 ofdm_basic_rates; + u8 cck_basic_rates; + __le16 assoc_id; + __le32 flags; + __le32 filter_flags; + __le16 channel; + __le16 reserved5; +} __packed; + +struct iwl4965_rxon_cmd { + u8 node_addr[6]; + __le16 reserved1; + u8 bssid_addr[6]; + __le16 reserved2; + u8 wlap_bssid_addr[6]; + __le16 reserved3; + u8 dev_type; + u8 air_propagation; + __le16 rx_chain; + u8 ofdm_basic_rates; + u8 cck_basic_rates; + __le16 assoc_id; + __le32 flags; + __le32 filter_flags; + __le16 channel; + u8 ofdm_ht_single_stream_basic_rates; + u8 ofdm_ht_dual_stream_basic_rates; +} __packed; + +/* Create a common rxon cmd which will be typecast into the 3945 or 4965 + * specific rxon cmd, depending on where it is called from. + */ +struct iwl_legacy_rxon_cmd { + u8 node_addr[6]; + __le16 reserved1; + u8 bssid_addr[6]; + __le16 reserved2; + u8 wlap_bssid_addr[6]; + __le16 reserved3; + u8 dev_type; + u8 air_propagation; + __le16 rx_chain; + u8 ofdm_basic_rates; + u8 cck_basic_rates; + __le16 assoc_id; + __le32 flags; + __le32 filter_flags; + __le16 channel; + u8 ofdm_ht_single_stream_basic_rates; + u8 ofdm_ht_dual_stream_basic_rates; + u8 reserved4; + u8 reserved5; +} __packed; + + +/* + * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response) + */ +struct iwl3945_rxon_assoc_cmd { + __le32 flags; + __le32 filter_flags; + u8 ofdm_basic_rates; + u8 cck_basic_rates; + __le16 reserved; +} __packed; + +struct iwl4965_rxon_assoc_cmd { + __le32 flags; + __le32 filter_flags; + u8 ofdm_basic_rates; + u8 cck_basic_rates; + u8 ofdm_ht_single_stream_basic_rates; + u8 ofdm_ht_dual_stream_basic_rates; + __le16 rx_chain_select_flags; + __le16 reserved; +} __packed; + +#define IWL_CONN_MAX_LISTEN_INTERVAL 10 +#define IWL_MAX_UCODE_BEACON_INTERVAL 4 /* 4096 */ +#define IWL39_MAX_UCODE_BEACON_INTERVAL 1 /* 1024 */ + +/* + * REPLY_RXON_TIMING = 0x14 (command, has simple generic response) + */ +struct iwl_rxon_time_cmd { + __le64 timestamp; + __le16 beacon_interval; + __le16 atim_window; + __le32 beacon_init_val; + __le16 listen_interval; + u8 dtim_period; + u8 delta_cp_bss_tbtts; +} __packed; + +/* + * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response) + */ +struct iwl3945_channel_switch_cmd { + u8 band; + u8 expect_beacon; + __le16 channel; + __le32 rxon_flags; + __le32 rxon_filter_flags; + __le32 switch_time; + struct iwl3945_power_per_rate power[IWL_MAX_RATES]; +} __packed; + +struct iwl4965_channel_switch_cmd { + u8 band; + u8 expect_beacon; + __le16 channel; + __le32 rxon_flags; + __le32 rxon_filter_flags; + __le32 switch_time; + struct iwl4965_tx_power_db tx_power; +} __packed; + +/* + * CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command) + */ +struct iwl_csa_notification { + __le16 band; + __le16 channel; + __le32 status; /* 0 - OK, 1 - fail */ +} __packed; + +/****************************************************************************** + * (2) + * Quality-of-Service (QOS) Commands & Responses: + * + *****************************************************************************/ + +/** + * struct iwl_ac_qos -- QOS timing params for REPLY_QOS_PARAM + * One for each of 4 EDCA access categories in struct iwl_qosparam_cmd + * + * @cw_min: Contention window, start value in numbers of slots. + * Should be a power-of-2, minus 1. Device's default is 0x0f. + * @cw_max: Contention window, max value in numbers of slots. + * Should be a power-of-2, minus 1. Device's default is 0x3f. + * @aifsn: Number of slots in Arbitration Interframe Space (before + * performing random backoff timing prior to Tx). Device default 1. + * @edca_txop: Length of Tx opportunity, in uSecs. Device default is 0. + * + * Device will automatically increase contention window by (2*CW) + 1 for each + * transmission retry. Device uses cw_max as a bit mask, ANDed with new CW + * value, to cap the CW value. + */ +struct iwl_ac_qos { + __le16 cw_min; + __le16 cw_max; + u8 aifsn; + u8 reserved1; + __le16 edca_txop; +} __packed; + +/* QoS flags defines */ +#define QOS_PARAM_FLG_UPDATE_EDCA_MSK cpu_to_le32(0x01) +#define QOS_PARAM_FLG_TGN_MSK cpu_to_le32(0x02) +#define QOS_PARAM_FLG_TXOP_TYPE_MSK cpu_to_le32(0x10) + +/* Number of Access Categories (AC) (EDCA), queues 0..3 */ +#define AC_NUM 4 + +/* + * REPLY_QOS_PARAM = 0x13 (command, has simple generic response) + * + * This command sets up timings for each of the 4 prioritized EDCA Tx FIFOs + * 0: Background, 1: Best Effort, 2: Video, 3: Voice. + */ +struct iwl_qosparam_cmd { + __le32 qos_flags; + struct iwl_ac_qos ac[AC_NUM]; +} __packed; + +/****************************************************************************** + * (3) + * Add/Modify Stations Commands & Responses: + * + *****************************************************************************/ +/* + * Multi station support + */ + +/* Special, dedicated locations within device's station table */ +#define IWL_AP_ID 0 +#define IWL_STA_ID 2 +#define IWL3945_BROADCAST_ID 24 +#define IWL3945_STATION_COUNT 25 +#define IWL4965_BROADCAST_ID 31 +#define IWL4965_STATION_COUNT 32 + +#define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/ +#define IWL_INVALID_STATION 255 + +#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2) +#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8) +#define STA_FLG_RTS_MIMO_PROT_MSK cpu_to_le32(1 << 17) +#define STA_FLG_AGG_MPDU_8US_MSK cpu_to_le32(1 << 18) +#define STA_FLG_MAX_AGG_SIZE_POS (19) +#define STA_FLG_MAX_AGG_SIZE_MSK cpu_to_le32(3 << 19) +#define STA_FLG_HT40_EN_MSK cpu_to_le32(1 << 21) +#define STA_FLG_MIMO_DIS_MSK cpu_to_le32(1 << 22) +#define STA_FLG_AGG_MPDU_DENSITY_POS (23) +#define STA_FLG_AGG_MPDU_DENSITY_MSK cpu_to_le32(7 << 23) + +/* Use in mode field. 1: modify existing entry, 0: add new station entry */ +#define STA_CONTROL_MODIFY_MSK 0x01 + +/* key flags __le16*/ +#define STA_KEY_FLG_ENCRYPT_MSK cpu_to_le16(0x0007) +#define STA_KEY_FLG_NO_ENC cpu_to_le16(0x0000) +#define STA_KEY_FLG_WEP cpu_to_le16(0x0001) +#define STA_KEY_FLG_CCMP cpu_to_le16(0x0002) +#define STA_KEY_FLG_TKIP cpu_to_le16(0x0003) + +#define STA_KEY_FLG_KEYID_POS 8 +#define STA_KEY_FLG_INVALID cpu_to_le16(0x0800) +/* wep key is either from global key (0) or from station info array (1) */ +#define STA_KEY_FLG_MAP_KEY_MSK cpu_to_le16(0x0008) + +/* wep key in STA: 5-bytes (0) or 13-bytes (1) */ +#define STA_KEY_FLG_KEY_SIZE_MSK cpu_to_le16(0x1000) +#define STA_KEY_MULTICAST_MSK cpu_to_le16(0x4000) +#define STA_KEY_MAX_NUM 8 + +/* Flags indicate whether to modify vs. don't change various station params */ +#define STA_MODIFY_KEY_MASK 0x01 +#define STA_MODIFY_TID_DISABLE_TX 0x02 +#define STA_MODIFY_TX_RATE_MSK 0x04 +#define STA_MODIFY_ADDBA_TID_MSK 0x08 +#define STA_MODIFY_DELBA_TID_MSK 0x10 +#define STA_MODIFY_SLEEP_TX_COUNT_MSK 0x20 + +/* Receiver address (actually, Rx station's index into station table), + * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */ +#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid)) + +struct iwl4965_keyinfo { + __le16 key_flags; + u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ + u8 reserved1; + __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */ + u8 key_offset; + u8 reserved2; + u8 key[16]; /* 16-byte unicast decryption key */ +} __packed; + +/** + * struct sta_id_modify + * @addr[ETH_ALEN]: station's MAC address + * @sta_id: index of station in uCode's station table + * @modify_mask: STA_MODIFY_*, 1: modify, 0: don't change + * + * Driver selects unused table index when adding new station, + * or the index to a pre-existing station entry when modifying that station. + * Some indexes have special purposes (IWL_AP_ID, index 0, is for AP). + * + * modify_mask flags select which parameters to modify vs. leave alone. + */ +struct sta_id_modify { + u8 addr[ETH_ALEN]; + __le16 reserved1; + u8 sta_id; + u8 modify_mask; + __le16 reserved2; +} __packed; + +/* + * REPLY_ADD_STA = 0x18 (command) + * + * The device contains an internal table of per-station information, + * with info on security keys, aggregation parameters, and Tx rates for + * initial Tx attempt and any retries (4965 devices uses + * REPLY_TX_LINK_QUALITY_CMD, + * 3945 uses REPLY_RATE_SCALE to set up rate tables). + * + * REPLY_ADD_STA sets up the table entry for one station, either creating + * a new entry, or modifying a pre-existing one. + * + * NOTE: RXON command (without "associated" bit set) wipes the station table + * clean. Moving into RF_KILL state does this also. Driver must set up + * new station table before transmitting anything on the RXON channel + * (except active scans or active measurements; those commands carry + * their own txpower/rate setup data). + * + * When getting started on a new channel, driver must set up the + * IWL_BROADCAST_ID entry (last entry in the table). For a client + * station in a BSS, once an AP is selected, driver sets up the AP STA + * in the IWL_AP_ID entry (1st entry in the table). BROADCAST and AP + * are all that are needed for a BSS client station. If the device is + * used as AP, or in an IBSS network, driver must set up station table + * entries for all STAs in network, starting with index IWL_STA_ID. + */ + +struct iwl3945_addsta_cmd { + u8 mode; /* 1: modify existing, 0: add new station */ + u8 reserved[3]; + struct sta_id_modify sta; + struct iwl4965_keyinfo key; + __le32 station_flags; /* STA_FLG_* */ + __le32 station_flags_msk; /* STA_FLG_* */ + + /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID) + * corresponding to bit (e.g. bit 5 controls TID 5). + * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */ + __le16 tid_disable_tx; + + __le16 rate_n_flags; + + /* TID for which to add block-ack support. + * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ + u8 add_immediate_ba_tid; + + /* TID for which to remove block-ack support. + * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */ + u8 remove_immediate_ba_tid; + + /* Starting Sequence Number for added block-ack support. + * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ + __le16 add_immediate_ba_ssn; +} __packed; + +struct iwl4965_addsta_cmd { + u8 mode; /* 1: modify existing, 0: add new station */ + u8 reserved[3]; + struct sta_id_modify sta; + struct iwl4965_keyinfo key; + __le32 station_flags; /* STA_FLG_* */ + __le32 station_flags_msk; /* STA_FLG_* */ + + /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID) + * corresponding to bit (e.g. bit 5 controls TID 5). + * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */ + __le16 tid_disable_tx; + + __le16 reserved1; + + /* TID for which to add block-ack support. + * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ + u8 add_immediate_ba_tid; + + /* TID for which to remove block-ack support. + * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */ + u8 remove_immediate_ba_tid; + + /* Starting Sequence Number for added block-ack support. + * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ + __le16 add_immediate_ba_ssn; + + /* + * Number of packets OK to transmit to station even though + * it is asleep -- used to synchronise PS-poll and u-APSD + * responses while ucode keeps track of STA sleep state. + */ + __le16 sleep_tx_count; + + __le16 reserved2; +} __packed; + +/* Wrapper struct for 3945 and 4965 addsta_cmd structures */ +struct iwl_legacy_addsta_cmd { + u8 mode; /* 1: modify existing, 0: add new station */ + u8 reserved[3]; + struct sta_id_modify sta; + struct iwl4965_keyinfo key; + __le32 station_flags; /* STA_FLG_* */ + __le32 station_flags_msk; /* STA_FLG_* */ + + /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID) + * corresponding to bit (e.g. bit 5 controls TID 5). + * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */ + __le16 tid_disable_tx; + + __le16 rate_n_flags; /* 3945 only */ + + /* TID for which to add block-ack support. + * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ + u8 add_immediate_ba_tid; + + /* TID for which to remove block-ack support. + * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */ + u8 remove_immediate_ba_tid; + + /* Starting Sequence Number for added block-ack support. + * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ + __le16 add_immediate_ba_ssn; + + /* + * Number of packets OK to transmit to station even though + * it is asleep -- used to synchronise PS-poll and u-APSD + * responses while ucode keeps track of STA sleep state. + */ + __le16 sleep_tx_count; + + __le16 reserved2; +} __packed; + + +#define ADD_STA_SUCCESS_MSK 0x1 +#define ADD_STA_NO_ROOM_IN_TABLE 0x2 +#define ADD_STA_NO_BLOCK_ACK_RESOURCE 0x4 +#define ADD_STA_MODIFY_NON_EXIST_STA 0x8 +/* + * REPLY_ADD_STA = 0x18 (response) + */ +struct iwl_add_sta_resp { + u8 status; /* ADD_STA_* */ +} __packed; + +#define REM_STA_SUCCESS_MSK 0x1 +/* + * REPLY_REM_STA = 0x19 (response) + */ +struct iwl_rem_sta_resp { + u8 status; +} __packed; + +/* + * REPLY_REM_STA = 0x19 (command) + */ +struct iwl_rem_sta_cmd { + u8 num_sta; /* number of removed stations */ + u8 reserved[3]; + u8 addr[ETH_ALEN]; /* MAC addr of the first station */ + u8 reserved2[2]; +} __packed; + +#define IWL_TX_FIFO_BK_MSK cpu_to_le32(BIT(0)) +#define IWL_TX_FIFO_BE_MSK cpu_to_le32(BIT(1)) +#define IWL_TX_FIFO_VI_MSK cpu_to_le32(BIT(2)) +#define IWL_TX_FIFO_VO_MSK cpu_to_le32(BIT(3)) +#define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00) + +#define IWL_DROP_SINGLE 0 +#define IWL_DROP_SELECTED 1 +#define IWL_DROP_ALL 2 + +/* + * REPLY_WEP_KEY = 0x20 + */ +struct iwl_wep_key { + u8 key_index; + u8 key_offset; + u8 reserved1[2]; + u8 key_size; + u8 reserved2[3]; + u8 key[16]; +} __packed; + +struct iwl_wep_cmd { + u8 num_keys; + u8 global_key_type; + u8 flags; + u8 reserved; + struct iwl_wep_key key[0]; +} __packed; + +#define WEP_KEY_WEP_TYPE 1 +#define WEP_KEYS_MAX 4 +#define WEP_INVALID_OFFSET 0xff +#define WEP_KEY_LEN_64 5 +#define WEP_KEY_LEN_128 13 + +/****************************************************************************** + * (4) + * Rx Responses: + * + *****************************************************************************/ + +#define RX_RES_STATUS_NO_CRC32_ERROR cpu_to_le32(1 << 0) +#define RX_RES_STATUS_NO_RXE_OVERFLOW cpu_to_le32(1 << 1) + +#define RX_RES_PHY_FLAGS_BAND_24_MSK cpu_to_le16(1 << 0) +#define RX_RES_PHY_FLAGS_MOD_CCK_MSK cpu_to_le16(1 << 1) +#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2) +#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3) +#define RX_RES_PHY_FLAGS_ANTENNA_MSK 0xf0 +#define RX_RES_PHY_FLAGS_ANTENNA_POS 4 + +#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8) +#define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8) +#define RX_RES_STATUS_SEC_TYPE_WEP (0x1 << 8) +#define RX_RES_STATUS_SEC_TYPE_CCMP (0x2 << 8) +#define RX_RES_STATUS_SEC_TYPE_TKIP (0x3 << 8) +#define RX_RES_STATUS_SEC_TYPE_ERR (0x7 << 8) + +#define RX_RES_STATUS_STATION_FOUND (1<<6) +#define RX_RES_STATUS_NO_STATION_INFO_MISMATCH (1<<7) + +#define RX_RES_STATUS_DECRYPT_TYPE_MSK (0x3 << 11) +#define RX_RES_STATUS_NOT_DECRYPT (0x0 << 11) +#define RX_RES_STATUS_DECRYPT_OK (0x3 << 11) +#define RX_RES_STATUS_BAD_ICV_MIC (0x1 << 11) +#define RX_RES_STATUS_BAD_KEY_TTAK (0x2 << 11) + +#define RX_MPDU_RES_STATUS_ICV_OK (0x20) +#define RX_MPDU_RES_STATUS_MIC_OK (0x40) +#define RX_MPDU_RES_STATUS_TTAK_OK (1 << 7) +#define RX_MPDU_RES_STATUS_DEC_DONE_MSK (0x800) + + +struct iwl3945_rx_frame_stats { + u8 phy_count; + u8 id; + u8 rssi; + u8 agc; + __le16 sig_avg; + __le16 noise_diff; + u8 payload[0]; +} __packed; + +struct iwl3945_rx_frame_hdr { + __le16 channel; + __le16 phy_flags; + u8 reserved1; + u8 rate; + __le16 len; + u8 payload[0]; +} __packed; + +struct iwl3945_rx_frame_end { + __le32 status; + __le64 timestamp; + __le32 beacon_timestamp; +} __packed; + +/* + * REPLY_3945_RX = 0x1b (response only, not a command) + * + * NOTE: DO NOT dereference from casts to this structure + * It is provided only for calculating minimum data set size. + * The actual offsets of the hdr and end are dynamic based on + * stats.phy_count + */ +struct iwl3945_rx_frame { + struct iwl3945_rx_frame_stats stats; + struct iwl3945_rx_frame_hdr hdr; + struct iwl3945_rx_frame_end end; +} __packed; + +#define IWL39_RX_FRAME_SIZE (4 + sizeof(struct iwl3945_rx_frame)) + +/* Fixed (non-configurable) rx data from phy */ + +#define IWL49_RX_RES_PHY_CNT 14 +#define IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET (4) +#define IWL49_RX_PHY_FLAGS_ANTENNAE_MASK (0x70) +#define IWL49_AGC_DB_MASK (0x3f80) /* MASK(7,13) */ +#define IWL49_AGC_DB_POS (7) +struct iwl4965_rx_non_cfg_phy { + __le16 ant_selection; /* ant A bit 4, ant B bit 5, ant C bit 6 */ + __le16 agc_info; /* agc code 0:6, agc dB 7:13, reserved 14:15 */ + u8 rssi_info[6]; /* we use even entries, 0/2/4 for A/B/C rssi */ + u8 pad[0]; +} __packed; + + +/* + * REPLY_RX = 0xc3 (response only, not a command) + * Used only for legacy (non 11n) frames. + */ +struct iwl_rx_phy_res { + u8 non_cfg_phy_cnt; /* non configurable DSP phy data byte count */ + u8 cfg_phy_cnt; /* configurable DSP phy data byte count */ + u8 stat_id; /* configurable DSP phy data set ID */ + u8 reserved1; + __le64 timestamp; /* TSF at on air rise */ + __le32 beacon_time_stamp; /* beacon at on-air rise */ + __le16 phy_flags; /* general phy flags: band, modulation, ... */ + __le16 channel; /* channel number */ + u8 non_cfg_phy_buf[32]; /* for various implementations of non_cfg_phy */ + __le32 rate_n_flags; /* RATE_MCS_* */ + __le16 byte_count; /* frame's byte-count */ + __le16 frame_time; /* frame's time on the air */ +} __packed; + +struct iwl_rx_mpdu_res_start { + __le16 byte_count; + __le16 reserved; +} __packed; + + +/****************************************************************************** + * (5) + * Tx Commands & Responses: + * + * Driver must place each REPLY_TX command into one of the prioritized Tx + * queues in host DRAM, shared between driver and device (see comments for + * SCD registers and Tx/Rx Queues). When the device's Tx scheduler and uCode + * are preparing to transmit, the device pulls the Tx command over the PCI + * bus via one of the device's Tx DMA channels, to fill an internal FIFO + * from which data will be transmitted. + * + * uCode handles all timing and protocol related to control frames + * (RTS/CTS/ACK), based on flags in the Tx command. uCode and Tx scheduler + * handle reception of block-acks; uCode updates the host driver via + * REPLY_COMPRESSED_BA. + * + * uCode handles retrying Tx when an ACK is expected but not received. + * This includes trying lower data rates than the one requested in the Tx + * command, as set up by the REPLY_RATE_SCALE (for 3945) or + * REPLY_TX_LINK_QUALITY_CMD (4965). + * + * Driver sets up transmit power for various rates via REPLY_TX_PWR_TABLE_CMD. + * This command must be executed after every RXON command, before Tx can occur. + *****************************************************************************/ + +/* REPLY_TX Tx flags field */ + +/* + * 1: Use Request-To-Send protocol before this frame. + * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. + */ +#define TX_CMD_FLG_RTS_MSK cpu_to_le32(1 << 1) + +/* + * 1: Transmit Clear-To-Send to self before this frame. + * Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames. + * Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. + */ +#define TX_CMD_FLG_CTS_MSK cpu_to_le32(1 << 2) + +/* 1: Expect ACK from receiving station + * 0: Don't expect ACK (MAC header's duration field s/b 0) + * Set this for unicast frames, but not broadcast/multicast. */ +#define TX_CMD_FLG_ACK_MSK cpu_to_le32(1 << 3) + +/* For 4965 devices: + * 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD). + * Tx command's initial_rate_index indicates first rate to try; + * uCode walks through table for additional Tx attempts. + * 0: Use Tx rate/MCS from Tx command's rate_n_flags field. + * This rate will be used for all Tx attempts; it will not be scaled. */ +#define TX_CMD_FLG_STA_RATE_MSK cpu_to_le32(1 << 4) + +/* 1: Expect immediate block-ack. + * Set when Txing a block-ack request frame. Also set TX_CMD_FLG_ACK_MSK. */ +#define TX_CMD_FLG_IMM_BA_RSP_MASK cpu_to_le32(1 << 6) + +/* + * 1: Frame requires full Tx-Op protection. + * Set this if either RTS or CTS Tx Flag gets set. + */ +#define TX_CMD_FLG_FULL_TXOP_PROT_MSK cpu_to_le32(1 << 7) + +/* Tx antenna selection field; used only for 3945, reserved (0) for 4965 devices. + * Set field to "0" to allow 3945 uCode to select antenna (normal usage). */ +#define TX_CMD_FLG_ANT_SEL_MSK cpu_to_le32(0xf00) +#define TX_CMD_FLG_ANT_A_MSK cpu_to_le32(1 << 8) +#define TX_CMD_FLG_ANT_B_MSK cpu_to_le32(1 << 9) + +/* 1: uCode overrides sequence control field in MAC header. + * 0: Driver provides sequence control field in MAC header. + * Set this for management frames, non-QOS data frames, non-unicast frames, + * and also in Tx command embedded in REPLY_SCAN_CMD for active scans. */ +#define TX_CMD_FLG_SEQ_CTL_MSK cpu_to_le32(1 << 13) + +/* 1: This frame is non-last MPDU; more fragments are coming. + * 0: Last fragment, or not using fragmentation. */ +#define TX_CMD_FLG_MORE_FRAG_MSK cpu_to_le32(1 << 14) + +/* 1: uCode calculates and inserts Timestamp Function (TSF) in outgoing frame. + * 0: No TSF required in outgoing frame. + * Set this for transmitting beacons and probe responses. */ +#define TX_CMD_FLG_TSF_MSK cpu_to_le32(1 << 16) + +/* 1: Driver inserted 2 bytes pad after the MAC header, for (required) dword + * alignment of frame's payload data field. + * 0: No pad + * Set this for MAC headers with 26 or 30 bytes, i.e. those with QOS or ADDR4 + * field (but not both). Driver must align frame data (i.e. data following + * MAC header) to DWORD boundary. */ +#define TX_CMD_FLG_MH_PAD_MSK cpu_to_le32(1 << 20) + +/* accelerate aggregation support + * 0 - no CCMP encryption; 1 - CCMP encryption */ +#define TX_CMD_FLG_AGG_CCMP_MSK cpu_to_le32(1 << 22) + +/* HCCA-AP - disable duration overwriting. */ +#define TX_CMD_FLG_DUR_MSK cpu_to_le32(1 << 25) + + +/* + * TX command security control + */ +#define TX_CMD_SEC_WEP 0x01 +#define TX_CMD_SEC_CCM 0x02 +#define TX_CMD_SEC_TKIP 0x03 +#define TX_CMD_SEC_MSK 0x03 +#define TX_CMD_SEC_SHIFT 6 +#define TX_CMD_SEC_KEY128 0x08 + +/* + * security overhead sizes + */ +#define WEP_IV_LEN 4 +#define WEP_ICV_LEN 4 +#define CCMP_MIC_LEN 8 +#define TKIP_ICV_LEN 4 + +/* + * REPLY_TX = 0x1c (command) + */ + +struct iwl3945_tx_cmd { + /* + * MPDU byte count: + * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size, + * + 8 byte IV for CCM or TKIP (not used for WEP) + * + Data payload + * + 8-byte MIC (not used for CCM/WEP) + * NOTE: Does not include Tx command bytes, post-MAC pad bytes, + * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i + * Range: 14-2342 bytes. + */ + __le16 len; + + /* + * MPDU or MSDU byte count for next frame. + * Used for fragmentation and bursting, but not 11n aggregation. + * Same as "len", but for next frame. Set to 0 if not applicable. + */ + __le16 next_frame_len; + + __le32 tx_flags; /* TX_CMD_FLG_* */ + + u8 rate; + + /* Index of recipient station in uCode's station table */ + u8 sta_id; + u8 tid_tspec; + u8 sec_ctl; + u8 key[16]; + union { + u8 byte[8]; + __le16 word[4]; + __le32 dw[2]; + } tkip_mic; + __le32 next_frame_info; + union { + __le32 life_time; + __le32 attempt; + } stop_time; + u8 supp_rates[2]; + u8 rts_retry_limit; /*byte 50 */ + u8 data_retry_limit; /*byte 51 */ + union { + __le16 pm_frame_timeout; + __le16 attempt_duration; + } timeout; + + /* + * Duration of EDCA burst Tx Opportunity, in 32-usec units. + * Set this if txop time is not specified by HCCA protocol (e.g. by AP). + */ + __le16 driver_txop; + + /* + * MAC header goes here, followed by 2 bytes padding if MAC header + * length is 26 or 30 bytes, followed by payload data + */ + u8 payload[0]; + struct ieee80211_hdr hdr[0]; +} __packed; + +/* + * REPLY_TX = 0x1c (response) + */ +struct iwl3945_tx_resp { + u8 failure_rts; + u8 failure_frame; + u8 bt_kill_count; + u8 rate; + __le32 wireless_media_time; + __le32 status; /* TX status */ +} __packed; + + +/* + * 4965 uCode updates these Tx attempt count values in host DRAM. + * Used for managing Tx retries when expecting block-acks. + * Driver should set these fields to 0. + */ +struct iwl_dram_scratch { + u8 try_cnt; /* Tx attempts */ + u8 bt_kill_cnt; /* Tx attempts blocked by Bluetooth device */ + __le16 reserved; +} __packed; + +struct iwl_tx_cmd { + /* + * MPDU byte count: + * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size, + * + 8 byte IV for CCM or TKIP (not used for WEP) + * + Data payload + * + 8-byte MIC (not used for CCM/WEP) + * NOTE: Does not include Tx command bytes, post-MAC pad bytes, + * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i + * Range: 14-2342 bytes. + */ + __le16 len; + + /* + * MPDU or MSDU byte count for next frame. + * Used for fragmentation and bursting, but not 11n aggregation. + * Same as "len", but for next frame. Set to 0 if not applicable. + */ + __le16 next_frame_len; + + __le32 tx_flags; /* TX_CMD_FLG_* */ + + /* uCode may modify this field of the Tx command (in host DRAM!). + * Driver must also set dram_lsb_ptr and dram_msb_ptr in this cmd. */ + struct iwl_dram_scratch scratch; + + /* Rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is cleared. */ + __le32 rate_n_flags; /* RATE_MCS_* */ + + /* Index of destination station in uCode's station table */ + u8 sta_id; + + /* Type of security encryption: CCM or TKIP */ + u8 sec_ctl; /* TX_CMD_SEC_* */ + + /* + * Index into rate table (see REPLY_TX_LINK_QUALITY_CMD) for initial + * Tx attempt, if TX_CMD_FLG_STA_RATE_MSK is set. Normally "0" for + * data frames, this field may be used to selectively reduce initial + * rate (via non-0 value) for special frames (e.g. management), while + * still supporting rate scaling for all frames. + */ + u8 initial_rate_index; + u8 reserved; + u8 key[16]; + __le16 next_frame_flags; + __le16 reserved2; + union { + __le32 life_time; + __le32 attempt; + } stop_time; + + /* Host DRAM physical address pointer to "scratch" in this command. + * Must be dword aligned. "0" in dram_lsb_ptr disables usage. */ + __le32 dram_lsb_ptr; + u8 dram_msb_ptr; + + u8 rts_retry_limit; /*byte 50 */ + u8 data_retry_limit; /*byte 51 */ + u8 tid_tspec; + union { + __le16 pm_frame_timeout; + __le16 attempt_duration; + } timeout; + + /* + * Duration of EDCA burst Tx Opportunity, in 32-usec units. + * Set this if txop time is not specified by HCCA protocol (e.g. by AP). + */ + __le16 driver_txop; + + /* + * MAC header goes here, followed by 2 bytes padding if MAC header + * length is 26 or 30 bytes, followed by payload data + */ + u8 payload[0]; + struct ieee80211_hdr hdr[0]; +} __packed; + +/* TX command response is sent after *3945* transmission attempts. + * + * NOTES: + * + * TX_STATUS_FAIL_NEXT_FRAG + * + * If the fragment flag in the MAC header for the frame being transmitted + * is set and there is insufficient time to transmit the next frame, the + * TX status will be returned with 'TX_STATUS_FAIL_NEXT_FRAG'. + * + * TX_STATUS_FIFO_UNDERRUN + * + * Indicates the host did not provide bytes to the FIFO fast enough while + * a TX was in progress. + * + * TX_STATUS_FAIL_MGMNT_ABORT + * + * This status is only possible if the ABORT ON MGMT RX parameter was + * set to true with the TX command. + * + * If the MSB of the status parameter is set then an abort sequence is + * required. This sequence consists of the host activating the TX Abort + * control line, and then waiting for the TX Abort command response. This + * indicates that a the device is no longer in a transmit state, and that the + * command FIFO has been cleared. The host must then deactivate the TX Abort + * control line. Receiving is still allowed in this case. + */ +enum { + TX_3945_STATUS_SUCCESS = 0x01, + TX_3945_STATUS_DIRECT_DONE = 0x02, + TX_3945_STATUS_FAIL_SHORT_LIMIT = 0x82, + TX_3945_STATUS_FAIL_LONG_LIMIT = 0x83, + TX_3945_STATUS_FAIL_FIFO_UNDERRUN = 0x84, + TX_3945_STATUS_FAIL_MGMNT_ABORT = 0x85, + TX_3945_STATUS_FAIL_NEXT_FRAG = 0x86, + TX_3945_STATUS_FAIL_LIFE_EXPIRE = 0x87, + TX_3945_STATUS_FAIL_DEST_PS = 0x88, + TX_3945_STATUS_FAIL_ABORTED = 0x89, + TX_3945_STATUS_FAIL_BT_RETRY = 0x8a, + TX_3945_STATUS_FAIL_STA_INVALID = 0x8b, + TX_3945_STATUS_FAIL_FRAG_DROPPED = 0x8c, + TX_3945_STATUS_FAIL_TID_DISABLE = 0x8d, + TX_3945_STATUS_FAIL_FRAME_FLUSHED = 0x8e, + TX_3945_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f, + TX_3945_STATUS_FAIL_TX_LOCKED = 0x90, + TX_3945_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91, +}; + +/* + * TX command response is sent after *4965* transmission attempts. + * + * both postpone and abort status are expected behavior from uCode. there is + * no special operation required from driver; except for RFKILL_FLUSH, + * which required tx flush host command to flush all the tx frames in queues + */ +enum { + TX_STATUS_SUCCESS = 0x01, + TX_STATUS_DIRECT_DONE = 0x02, + /* postpone TX */ + TX_STATUS_POSTPONE_DELAY = 0x40, + TX_STATUS_POSTPONE_FEW_BYTES = 0x41, + TX_STATUS_POSTPONE_QUIET_PERIOD = 0x43, + TX_STATUS_POSTPONE_CALC_TTAK = 0x44, + /* abort TX */ + TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY = 0x81, + TX_STATUS_FAIL_SHORT_LIMIT = 0x82, + TX_STATUS_FAIL_LONG_LIMIT = 0x83, + TX_STATUS_FAIL_FIFO_UNDERRUN = 0x84, + TX_STATUS_FAIL_DRAIN_FLOW = 0x85, + TX_STATUS_FAIL_RFKILL_FLUSH = 0x86, + TX_STATUS_FAIL_LIFE_EXPIRE = 0x87, + TX_STATUS_FAIL_DEST_PS = 0x88, + TX_STATUS_FAIL_HOST_ABORTED = 0x89, + TX_STATUS_FAIL_BT_RETRY = 0x8a, + TX_STATUS_FAIL_STA_INVALID = 0x8b, + TX_STATUS_FAIL_FRAG_DROPPED = 0x8c, + TX_STATUS_FAIL_TID_DISABLE = 0x8d, + TX_STATUS_FAIL_FIFO_FLUSHED = 0x8e, + TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f, + TX_STATUS_FAIL_PASSIVE_NO_RX = 0x90, + TX_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91, +}; + +#define TX_PACKET_MODE_REGULAR 0x0000 +#define TX_PACKET_MODE_BURST_SEQ 0x0100 +#define TX_PACKET_MODE_BURST_FIRST 0x0200 + +enum { + TX_POWER_PA_NOT_ACTIVE = 0x0, +}; + +enum { + TX_STATUS_MSK = 0x000000ff, /* bits 0:7 */ + TX_STATUS_DELAY_MSK = 0x00000040, + TX_STATUS_ABORT_MSK = 0x00000080, + TX_PACKET_MODE_MSK = 0x0000ff00, /* bits 8:15 */ + TX_FIFO_NUMBER_MSK = 0x00070000, /* bits 16:18 */ + TX_RESERVED = 0x00780000, /* bits 19:22 */ + TX_POWER_PA_DETECT_MSK = 0x7f800000, /* bits 23:30 */ + TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */ +}; + +/* ******************************* + * TX aggregation status + ******************************* */ + +enum { + AGG_TX_STATE_TRANSMITTED = 0x00, + AGG_TX_STATE_UNDERRUN_MSK = 0x01, + AGG_TX_STATE_FEW_BYTES_MSK = 0x04, + AGG_TX_STATE_ABORT_MSK = 0x08, + AGG_TX_STATE_LAST_SENT_TTL_MSK = 0x10, + AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK = 0x20, + AGG_TX_STATE_SCD_QUERY_MSK = 0x80, + AGG_TX_STATE_TEST_BAD_CRC32_MSK = 0x100, + AGG_TX_STATE_RESPONSE_MSK = 0x1ff, + AGG_TX_STATE_DUMP_TX_MSK = 0x200, + AGG_TX_STATE_DELAY_TX_MSK = 0x400 +}; + +#define AGG_TX_STATUS_MSK 0x00000fff /* bits 0:11 */ +#define AGG_TX_TRY_MSK 0x0000f000 /* bits 12:15 */ + +#define AGG_TX_STATE_LAST_SENT_MSK (AGG_TX_STATE_LAST_SENT_TTL_MSK | \ + AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK) + +/* # tx attempts for first frame in aggregation */ +#define AGG_TX_STATE_TRY_CNT_POS 12 +#define AGG_TX_STATE_TRY_CNT_MSK 0xf000 + +/* Command ID and sequence number of Tx command for this frame */ +#define AGG_TX_STATE_SEQ_NUM_POS 16 +#define AGG_TX_STATE_SEQ_NUM_MSK 0xffff0000 + +/* + * REPLY_TX = 0x1c (response) + * + * This response may be in one of two slightly different formats, indicated + * by the frame_count field: + * + * 1) No aggregation (frame_count == 1). This reports Tx results for + * a single frame. Multiple attempts, at various bit rates, may have + * been made for this frame. + * + * 2) Aggregation (frame_count > 1). This reports Tx results for + * 2 or more frames that used block-acknowledge. All frames were + * transmitted at same rate. Rate scaling may have been used if first + * frame in this new agg block failed in previous agg block(s). + * + * Note that, for aggregation, ACK (block-ack) status is not delivered here; + * block-ack has not been received by the time the 4965 device records + * this status. + * This status relates to reasons the tx might have been blocked or aborted + * within the sending station (this 4965 device), rather than whether it was + * received successfully by the destination station. + */ +struct agg_tx_status { + __le16 status; + __le16 sequence; +} __packed; + +struct iwl4965_tx_resp { + u8 frame_count; /* 1 no aggregation, >1 aggregation */ + u8 bt_kill_count; /* # blocked by bluetooth (unused for agg) */ + u8 failure_rts; /* # failures due to unsuccessful RTS */ + u8 failure_frame; /* # failures due to no ACK (unused for agg) */ + + /* For non-agg: Rate at which frame was successful. + * For agg: Rate at which all frames were transmitted. */ + __le32 rate_n_flags; /* RATE_MCS_* */ + + /* For non-agg: RTS + CTS + frame tx attempts time + ACK. + * For agg: RTS + CTS + aggregation tx time + block-ack time. */ + __le16 wireless_media_time; /* uSecs */ + + __le16 reserved; + __le32 pa_power1; /* RF power amplifier measurement (not used) */ + __le32 pa_power2; + + /* + * For non-agg: frame status TX_STATUS_* + * For agg: status of 1st frame, AGG_TX_STATE_*; other frame status + * fields follow this one, up to frame_count. + * Bit fields: + * 11- 0: AGG_TX_STATE_* status code + * 15-12: Retry count for 1st frame in aggregation (retries + * occur if tx failed for this frame when it was a + * member of a previous aggregation block). If rate + * scaling is used, retry count indicates the rate + * table entry used for all frames in the new agg. + * 31-16: Sequence # for this frame's Tx cmd (not SSN!) + */ + union { + __le32 status; + struct agg_tx_status agg_status[0]; /* for each agg frame */ + } u; +} __packed; + +/* + * REPLY_COMPRESSED_BA = 0xc5 (response only, not a command) + * + * Reports Block-Acknowledge from recipient station + */ +struct iwl_compressed_ba_resp { + __le32 sta_addr_lo32; + __le16 sta_addr_hi16; + __le16 reserved; + + /* Index of recipient (BA-sending) station in uCode's station table */ + u8 sta_id; + u8 tid; + __le16 seq_ctl; + __le64 bitmap; + __le16 scd_flow; + __le16 scd_ssn; +} __packed; + +/* + * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response) + * + * See details under "TXPOWER" in iwl-4965-hw.h. + */ + +struct iwl3945_txpowertable_cmd { + u8 band; /* 0: 5 GHz, 1: 2.4 GHz */ + u8 reserved; + __le16 channel; + struct iwl3945_power_per_rate power[IWL_MAX_RATES]; +} __packed; + +struct iwl4965_txpowertable_cmd { + u8 band; /* 0: 5 GHz, 1: 2.4 GHz */ + u8 reserved; + __le16 channel; + struct iwl4965_tx_power_db tx_power; +} __packed; + + +/** + * struct iwl3945_rate_scaling_cmd - Rate Scaling Command & Response + * + * REPLY_RATE_SCALE = 0x47 (command, has simple generic response) + * + * NOTE: The table of rates passed to the uCode via the + * RATE_SCALE command sets up the corresponding order of + * rates used for all related commands, including rate + * masks, etc. + * + * For example, if you set 9MB (PLCP 0x0f) as the first + * rate in the rate table, the bit mask for that rate + * when passed through ofdm_basic_rates on the REPLY_RXON + * command would be bit 0 (1 << 0) + */ +struct iwl3945_rate_scaling_info { + __le16 rate_n_flags; + u8 try_cnt; + u8 next_rate_index; +} __packed; + +struct iwl3945_rate_scaling_cmd { + u8 table_id; + u8 reserved[3]; + struct iwl3945_rate_scaling_info table[IWL_MAX_RATES]; +} __packed; + + +/*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */ +#define LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK (1 << 0) + +/* # of EDCA prioritized tx fifos */ +#define LINK_QUAL_AC_NUM AC_NUM + +/* # entries in rate scale table to support Tx retries */ +#define LINK_QUAL_MAX_RETRY_NUM 16 + +/* Tx antenna selection values */ +#define LINK_QUAL_ANT_A_MSK (1 << 0) +#define LINK_QUAL_ANT_B_MSK (1 << 1) +#define LINK_QUAL_ANT_MSK (LINK_QUAL_ANT_A_MSK|LINK_QUAL_ANT_B_MSK) + + +/** + * struct iwl_link_qual_general_params + * + * Used in REPLY_TX_LINK_QUALITY_CMD + */ +struct iwl_link_qual_general_params { + u8 flags; + + /* No entries at or above this (driver chosen) index contain MIMO */ + u8 mimo_delimiter; + + /* Best single antenna to use for single stream (legacy, SISO). */ + u8 single_stream_ant_msk; /* LINK_QUAL_ANT_* */ + + /* Best antennas to use for MIMO (unused for 4965, assumes both). */ + u8 dual_stream_ant_msk; /* LINK_QUAL_ANT_* */ + + /* + * If driver needs to use different initial rates for different + * EDCA QOS access categories (as implemented by tx fifos 0-3), + * this table will set that up, by indicating the indexes in the + * rs_table[LINK_QUAL_MAX_RETRY_NUM] rate table at which to start. + * Otherwise, driver should set all entries to 0. + * + * Entry usage: + * 0 = Background, 1 = Best Effort (normal), 2 = Video, 3 = Voice + * TX FIFOs above 3 use same value (typically 0) as TX FIFO 3. + */ + u8 start_rate_index[LINK_QUAL_AC_NUM]; +} __packed; + +#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */ +#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000) +#define LINK_QUAL_AGG_TIME_LIMIT_MIN (100) + +#define LINK_QUAL_AGG_DISABLE_START_DEF (3) +#define LINK_QUAL_AGG_DISABLE_START_MAX (255) +#define LINK_QUAL_AGG_DISABLE_START_MIN (0) + +#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (31) +#define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63) +#define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0) + +/** + * struct iwl_link_qual_agg_params + * + * Used in REPLY_TX_LINK_QUALITY_CMD + */ +struct iwl_link_qual_agg_params { + + /* + *Maximum number of uSec in aggregation. + * default set to 4000 (4 milliseconds) if not configured in .cfg + */ + __le16 agg_time_limit; + + /* + * Number of Tx retries allowed for a frame, before that frame will + * no longer be considered for the start of an aggregation sequence + * (scheduler will then try to tx it as single frame). + * Driver should set this to 3. + */ + u8 agg_dis_start_th; + + /* + * Maximum number of frames in aggregation. + * 0 = no limit (default). 1 = no aggregation. + * Other values = max # frames in aggregation. + */ + u8 agg_frame_cnt_limit; + + __le32 reserved; +} __packed; + +/* + * REPLY_TX_LINK_QUALITY_CMD = 0x4e (command, has simple generic response) + * + * For 4965 devices only; 3945 uses REPLY_RATE_SCALE. + * + * Each station in the 4965 device's internal station table has its own table + * of 16 + * Tx rates and modulation modes (e.g. legacy/SISO/MIMO) for retrying Tx when + * an ACK is not received. This command replaces the entire table for + * one station. + * + * NOTE: Station must already be in 4965 device's station table. + * Use REPLY_ADD_STA. + * + * The rate scaling procedures described below work well. Of course, other + * procedures are possible, and may work better for particular environments. + * + * + * FILLING THE RATE TABLE + * + * Given a particular initial rate and mode, as determined by the rate + * scaling algorithm described below, the Linux driver uses the following + * formula to fill the rs_table[LINK_QUAL_MAX_RETRY_NUM] rate table in the + * Link Quality command: + * + * + * 1) If using High-throughput (HT) (SISO or MIMO) initial rate: + * a) Use this same initial rate for first 3 entries. + * b) Find next lower available rate using same mode (SISO or MIMO), + * use for next 3 entries. If no lower rate available, switch to + * legacy mode (no HT40 channel, no MIMO, no short guard interval). + * c) If using MIMO, set command's mimo_delimiter to number of entries + * using MIMO (3 or 6). + * d) After trying 2 HT rates, switch to legacy mode (no HT40 channel, + * no MIMO, no short guard interval), at the next lower bit rate + * (e.g. if second HT bit rate was 54, try 48 legacy), and follow + * legacy procedure for remaining table entries. + * + * 2) If using legacy initial rate: + * a) Use the initial rate for only one entry. + * b) For each following entry, reduce the rate to next lower available + * rate, until reaching the lowest available rate. + * c) When reducing rate, also switch antenna selection. + * d) Once lowest available rate is reached, repeat this rate until + * rate table is filled (16 entries), switching antenna each entry. + * + * + * ACCUMULATING HISTORY + * + * The rate scaling algorithm for 4965 devices, as implemented in Linux driver, + * uses two sets of frame Tx success history: One for the current/active + * modulation mode, and one for a speculative/search mode that is being + * attempted. If the speculative mode turns out to be more effective (i.e. + * actual transfer rate is better), then the driver continues to use the + * speculative mode as the new current active mode. + * + * Each history set contains, separately for each possible rate, data for a + * sliding window of the 62 most recent tx attempts at that rate. The data + * includes a shifting bitmap of success(1)/failure(0), and sums of successful + * and attempted frames, from which the driver can additionally calculate a + * success ratio (success / attempted) and number of failures + * (attempted - success), and control the size of the window (attempted). + * The driver uses the bit map to remove successes from the success sum, as + * the oldest tx attempts fall out of the window. + * + * When the 4965 device makes multiple tx attempts for a given frame, each + * attempt might be at a different rate, and have different modulation + * characteristics (e.g. antenna, fat channel, short guard interval), as set + * up in the rate scaling table in the Link Quality command. The driver must + * determine which rate table entry was used for each tx attempt, to determine + * which rate-specific history to update, and record only those attempts that + * match the modulation characteristics of the history set. + * + * When using block-ack (aggregation), all frames are transmitted at the same + * rate, since there is no per-attempt acknowledgment from the destination + * station. The Tx response struct iwl_tx_resp indicates the Tx rate in + * rate_n_flags field. After receiving a block-ack, the driver can update + * history for the entire block all at once. + * + * + * FINDING BEST STARTING RATE: + * + * When working with a selected initial modulation mode (see below), the + * driver attempts to find a best initial rate. The initial rate is the + * first entry in the Link Quality command's rate table. + * + * 1) Calculate actual throughput (success ratio * expected throughput, see + * table below) for current initial rate. Do this only if enough frames + * have been attempted to make the value meaningful: at least 6 failed + * tx attempts, or at least 8 successes. If not enough, don't try rate + * scaling yet. + * + * 2) Find available rates adjacent to current initial rate. Available means: + * a) supported by hardware && + * b) supported by association && + * c) within any constraints selected by user + * + * 3) Gather measured throughputs for adjacent rates. These might not have + * enough history to calculate a throughput. That's okay, we might try + * using one of them anyway! + * + * 4) Try decreasing rate if, for current rate: + * a) success ratio is < 15% || + * b) lower adjacent rate has better measured throughput || + * c) higher adjacent rate has worse throughput, and lower is unmeasured + * + * As a sanity check, if decrease was determined above, leave rate + * unchanged if: + * a) lower rate unavailable + * b) success ratio at current rate > 85% (very good) + * c) current measured throughput is better than expected throughput + * of lower rate (under perfect 100% tx conditions, see table below) + * + * 5) Try increasing rate if, for current rate: + * a) success ratio is < 15% || + * b) both adjacent rates' throughputs are unmeasured (try it!) || + * b) higher adjacent rate has better measured throughput || + * c) lower adjacent rate has worse throughput, and higher is unmeasured + * + * As a sanity check, if increase was determined above, leave rate + * unchanged if: + * a) success ratio at current rate < 70%. This is not particularly + * good performance; higher rate is sure to have poorer success. + * + * 6) Re-evaluate the rate after each tx frame. If working with block- + * acknowledge, history and statistics may be calculated for the entire + * block (including prior history that fits within the history windows), + * before re-evaluation. + * + * FINDING BEST STARTING MODULATION MODE: + * + * After working with a modulation mode for a "while" (and doing rate scaling), + * the driver searches for a new initial mode in an attempt to improve + * throughput. The "while" is measured by numbers of attempted frames: + * + * For legacy mode, search for new mode after: + * 480 successful frames, or 160 failed frames + * For high-throughput modes (SISO or MIMO), search for new mode after: + * 4500 successful frames, or 400 failed frames + * + * Mode switch possibilities are (3 for each mode): + * + * For legacy: + * Change antenna, try SISO (if HT association), try MIMO (if HT association) + * For SISO: + * Change antenna, try MIMO, try shortened guard interval (SGI) + * For MIMO: + * Try SISO antenna A, SISO antenna B, try shortened guard interval (SGI) + * + * When trying a new mode, use the same bit rate as the old/current mode when + * trying antenna switches and shortened guard interval. When switching to + * SISO from MIMO or legacy, or to MIMO from SISO or legacy, use a rate + * for which the expected throughput (under perfect conditions) is about the + * same or slightly better than the actual measured throughput delivered by + * the old/current mode. + * + * Actual throughput can be estimated by multiplying the expected throughput + * by the success ratio (successful / attempted tx frames). Frame size is + * not considered in this calculation; it assumes that frame size will average + * out to be fairly consistent over several samples. The following are + * metric values for expected throughput assuming 100% success ratio. + * Only G band has support for CCK rates: + * + * RATE: 1 2 5 11 6 9 12 18 24 36 48 54 60 + * + * G: 7 13 35 58 40 57 72 98 121 154 177 186 186 + * A: 0 0 0 0 40 57 72 98 121 154 177 186 186 + * SISO 20MHz: 0 0 0 0 42 42 76 102 124 159 183 193 202 + * SGI SISO 20MHz: 0 0 0 0 46 46 82 110 132 168 192 202 211 + * MIMO 20MHz: 0 0 0 0 74 74 123 155 179 214 236 244 251 + * SGI MIMO 20MHz: 0 0 0 0 81 81 131 164 188 222 243 251 257 + * SISO 40MHz: 0 0 0 0 77 77 127 160 184 220 242 250 257 + * SGI SISO 40MHz: 0 0 0 0 83 83 135 169 193 229 250 257 264 + * MIMO 40MHz: 0 0 0 0 123 123 182 214 235 264 279 285 289 + * SGI MIMO 40MHz: 0 0 0 0 131 131 191 222 242 270 284 289 293 + * + * After the new mode has been tried for a short while (minimum of 6 failed + * frames or 8 successful frames), compare success ratio and actual throughput + * estimate of the new mode with the old. If either is better with the new + * mode, continue to use the new mode. + * + * Continue comparing modes until all 3 possibilities have been tried. + * If moving from legacy to HT, try all 3 possibilities from the new HT + * mode. After trying all 3, a best mode is found. Continue to use this mode + * for the longer "while" described above (e.g. 480 successful frames for + * legacy), and then repeat the search process. + * + */ +struct iwl_link_quality_cmd { + + /* Index of destination/recipient station in uCode's station table */ + u8 sta_id; + u8 reserved1; + __le16 control; /* not used */ + struct iwl_link_qual_general_params general_params; + struct iwl_link_qual_agg_params agg_params; + + /* + * Rate info; when using rate-scaling, Tx command's initial_rate_index + * specifies 1st Tx rate attempted, via index into this table. + * 4965 devices works its way through table when retrying Tx. + */ + struct { + __le32 rate_n_flags; /* RATE_MCS_*, IWL_RATE_* */ + } rs_table[LINK_QUAL_MAX_RETRY_NUM]; + __le32 reserved2; +} __packed; + +/* + * BT configuration enable flags: + * bit 0 - 1: BT channel announcement enabled + * 0: disable + * bit 1 - 1: priority of BT device enabled + * 0: disable + */ +#define BT_COEX_DISABLE (0x0) +#define BT_ENABLE_CHANNEL_ANNOUNCE BIT(0) +#define BT_ENABLE_PRIORITY BIT(1) + +#define BT_COEX_ENABLE (BT_ENABLE_CHANNEL_ANNOUNCE | BT_ENABLE_PRIORITY) + +#define BT_LEAD_TIME_DEF (0x1E) + +#define BT_MAX_KILL_DEF (0x5) + +/* + * REPLY_BT_CONFIG = 0x9b (command, has simple generic response) + * + * 3945 and 4965 devices support hardware handshake with Bluetooth device on + * same platform. Bluetooth device alerts wireless device when it will Tx; + * wireless device can delay or kill its own Tx to accommodate. + */ +struct iwl_bt_cmd { + u8 flags; + u8 lead_time; + u8 max_kill; + u8 reserved; + __le32 kill_ack_mask; + __le32 kill_cts_mask; +} __packed; + + +/****************************************************************************** + * (6) + * Spectrum Management (802.11h) Commands, Responses, Notifications: + * + *****************************************************************************/ + +/* + * Spectrum Management + */ +#define MEASUREMENT_FILTER_FLAG (RXON_FILTER_PROMISC_MSK | \ + RXON_FILTER_CTL2HOST_MSK | \ + RXON_FILTER_ACCEPT_GRP_MSK | \ + RXON_FILTER_DIS_DECRYPT_MSK | \ + RXON_FILTER_DIS_GRP_DECRYPT_MSK | \ + RXON_FILTER_ASSOC_MSK | \ + RXON_FILTER_BCON_AWARE_MSK) + +struct iwl_measure_channel { + __le32 duration; /* measurement duration in extended beacon + * format */ + u8 channel; /* channel to measure */ + u8 type; /* see enum iwl_measure_type */ + __le16 reserved; +} __packed; + +/* + * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (command) + */ +struct iwl_spectrum_cmd { + __le16 len; /* number of bytes starting from token */ + u8 token; /* token id */ + u8 id; /* measurement id -- 0 or 1 */ + u8 origin; /* 0 = TGh, 1 = other, 2 = TGk */ + u8 periodic; /* 1 = periodic */ + __le16 path_loss_timeout; + __le32 start_time; /* start time in extended beacon format */ + __le32 reserved2; + __le32 flags; /* rxon flags */ + __le32 filter_flags; /* rxon filter flags */ + __le16 channel_count; /* minimum 1, maximum 10 */ + __le16 reserved3; + struct iwl_measure_channel channels[10]; +} __packed; + +/* + * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (response) + */ +struct iwl_spectrum_resp { + u8 token; + u8 id; /* id of the prior command replaced, or 0xff */ + __le16 status; /* 0 - command will be handled + * 1 - cannot handle (conflicts with another + * measurement) */ +} __packed; + +enum iwl_measurement_state { + IWL_MEASUREMENT_START = 0, + IWL_MEASUREMENT_STOP = 1, +}; + +enum iwl_measurement_status { + IWL_MEASUREMENT_OK = 0, + IWL_MEASUREMENT_CONCURRENT = 1, + IWL_MEASUREMENT_CSA_CONFLICT = 2, + IWL_MEASUREMENT_TGH_CONFLICT = 3, + /* 4-5 reserved */ + IWL_MEASUREMENT_STOPPED = 6, + IWL_MEASUREMENT_TIMEOUT = 7, + IWL_MEASUREMENT_PERIODIC_FAILED = 8, +}; + +#define NUM_ELEMENTS_IN_HISTOGRAM 8 + +struct iwl_measurement_histogram { + __le32 ofdm[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 0.8usec counts */ + __le32 cck[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 1usec counts */ +} __packed; + +/* clear channel availability counters */ +struct iwl_measurement_cca_counters { + __le32 ofdm; + __le32 cck; +} __packed; + +enum iwl_measure_type { + IWL_MEASURE_BASIC = (1 << 0), + IWL_MEASURE_CHANNEL_LOAD = (1 << 1), + IWL_MEASURE_HISTOGRAM_RPI = (1 << 2), + IWL_MEASURE_HISTOGRAM_NOISE = (1 << 3), + IWL_MEASURE_FRAME = (1 << 4), + /* bits 5:6 are reserved */ + IWL_MEASURE_IDLE = (1 << 7), +}; + +/* + * SPECTRUM_MEASURE_NOTIFICATION = 0x75 (notification only, not a command) + */ +struct iwl_spectrum_notification { + u8 id; /* measurement id -- 0 or 1 */ + u8 token; + u8 channel_index; /* index in measurement channel list */ + u8 state; /* 0 - start, 1 - stop */ + __le32 start_time; /* lower 32-bits of TSF */ + u8 band; /* 0 - 5.2GHz, 1 - 2.4GHz */ + u8 channel; + u8 type; /* see enum iwl_measurement_type */ + u8 reserved1; + /* NOTE: cca_ofdm, cca_cck, basic_type, and histogram are only only + * valid if applicable for measurement type requested. */ + __le32 cca_ofdm; /* cca fraction time in 40Mhz clock periods */ + __le32 cca_cck; /* cca fraction time in 44Mhz clock periods */ + __le32 cca_time; /* channel load time in usecs */ + u8 basic_type; /* 0 - bss, 1 - ofdm preamble, 2 - + * unidentified */ + u8 reserved2[3]; + struct iwl_measurement_histogram histogram; + __le32 stop_time; /* lower 32-bits of TSF */ + __le32 status; /* see iwl_measurement_status */ +} __packed; + +/****************************************************************************** + * (7) + * Power Management Commands, Responses, Notifications: + * + *****************************************************************************/ + +/** + * struct iwl_powertable_cmd - Power Table Command + * @flags: See below: + * + * POWER_TABLE_CMD = 0x77 (command, has simple generic response) + * + * PM allow: + * bit 0 - '0' Driver not allow power management + * '1' Driver allow PM (use rest of parameters) + * + * uCode send sleep notifications: + * bit 1 - '0' Don't send sleep notification + * '1' send sleep notification (SEND_PM_NOTIFICATION) + * + * Sleep over DTIM + * bit 2 - '0' PM have to walk up every DTIM + * '1' PM could sleep over DTIM till listen Interval. + * + * PCI power managed + * bit 3 - '0' (PCI_CFG_LINK_CTRL & 0x1) + * '1' !(PCI_CFG_LINK_CTRL & 0x1) + * + * Fast PD + * bit 4 - '1' Put radio to sleep when receiving frame for others + * + * Force sleep Modes + * bit 31/30- '00' use both mac/xtal sleeps + * '01' force Mac sleep + * '10' force xtal sleep + * '11' Illegal set + * + * NOTE: if sleep_interval[SLEEP_INTRVL_TABLE_SIZE-1] > DTIM period then + * ucode assume sleep over DTIM is allowed and we don't need to wake up + * for every DTIM. + */ +#define IWL_POWER_VEC_SIZE 5 + +#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(BIT(0)) +#define IWL_POWER_POWER_SAVE_ENA_MSK cpu_to_le16(BIT(0)) +#define IWL_POWER_POWER_MANAGEMENT_ENA_MSK cpu_to_le16(BIT(1)) +#define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(BIT(2)) +#define IWL_POWER_PCI_PM_MSK cpu_to_le16(BIT(3)) +#define IWL_POWER_FAST_PD cpu_to_le16(BIT(4)) +#define IWL_POWER_BEACON_FILTERING cpu_to_le16(BIT(5)) +#define IWL_POWER_SHADOW_REG_ENA cpu_to_le16(BIT(6)) +#define IWL_POWER_CT_KILL_SET cpu_to_le16(BIT(7)) + +struct iwl3945_powertable_cmd { + __le16 flags; + u8 reserved[2]; + __le32 rx_data_timeout; + __le32 tx_data_timeout; + __le32 sleep_interval[IWL_POWER_VEC_SIZE]; +} __packed; + +struct iwl_powertable_cmd { + __le16 flags; + u8 keep_alive_seconds; /* 3945 reserved */ + u8 debug_flags; /* 3945 reserved */ + __le32 rx_data_timeout; + __le32 tx_data_timeout; + __le32 sleep_interval[IWL_POWER_VEC_SIZE]; + __le32 keep_alive_beacons; +} __packed; + +/* + * PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command) + * all devices identical. + */ +struct iwl_sleep_notification { + u8 pm_sleep_mode; + u8 pm_wakeup_src; + __le16 reserved; + __le32 sleep_time; + __le32 tsf_low; + __le32 bcon_timer; +} __packed; + +/* Sleep states. all devices identical. */ +enum { + IWL_PM_NO_SLEEP = 0, + IWL_PM_SLP_MAC = 1, + IWL_PM_SLP_FULL_MAC_UNASSOCIATE = 2, + IWL_PM_SLP_FULL_MAC_CARD_STATE = 3, + IWL_PM_SLP_PHY = 4, + IWL_PM_SLP_REPENT = 5, + IWL_PM_WAKEUP_BY_TIMER = 6, + IWL_PM_WAKEUP_BY_DRIVER = 7, + IWL_PM_WAKEUP_BY_RFKILL = 8, + /* 3 reserved */ + IWL_PM_NUM_OF_MODES = 12, +}; + +/* + * CARD_STATE_NOTIFICATION = 0xa1 (notification only, not a command) + */ +struct iwl_card_state_notif { + __le32 flags; +} __packed; + +#define HW_CARD_DISABLED 0x01 +#define SW_CARD_DISABLED 0x02 +#define CT_CARD_DISABLED 0x04 +#define RXON_CARD_DISABLED 0x10 + +struct iwl_ct_kill_config { + __le32 reserved; + __le32 critical_temperature_M; + __le32 critical_temperature_R; +} __packed; + +/****************************************************************************** + * (8) + * Scan Commands, Responses, Notifications: + * + *****************************************************************************/ + +#define SCAN_CHANNEL_TYPE_PASSIVE cpu_to_le32(0) +#define SCAN_CHANNEL_TYPE_ACTIVE cpu_to_le32(1) + +/** + * struct iwl_scan_channel - entry in REPLY_SCAN_CMD channel table + * + * One for each channel in the scan list. + * Each channel can independently select: + * 1) SSID for directed active scans + * 2) Txpower setting (for rate specified within Tx command) + * 3) How long to stay on-channel (behavior may be modified by quiet_time, + * quiet_plcp_th, good_CRC_th) + * + * To avoid uCode errors, make sure the following are true (see comments + * under struct iwl_scan_cmd about max_out_time and quiet_time): + * 1) If using passive_dwell (i.e. passive_dwell != 0): + * active_dwell <= passive_dwell (< max_out_time if max_out_time != 0) + * 2) quiet_time <= active_dwell + * 3) If restricting off-channel time (i.e. max_out_time !=0): + * passive_dwell < max_out_time + * active_dwell < max_out_time + */ +struct iwl3945_scan_channel { + /* + * type is defined as: + * 0:0 1 = active, 0 = passive + * 1:4 SSID direct bit map; if a bit is set, then corresponding + * SSID IE is transmitted in probe request. + * 5:7 reserved + */ + u8 type; + u8 channel; /* band is selected by iwl3945_scan_cmd "flags" field */ + struct iwl3945_tx_power tpc; + __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */ + __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */ +} __packed; + +/* set number of direct probes u8 type */ +#define IWL39_SCAN_PROBE_MASK(n) ((BIT(n) | (BIT(n) - BIT(1)))) + +struct iwl_scan_channel { + /* + * type is defined as: + * 0:0 1 = active, 0 = passive + * 1:20 SSID direct bit map; if a bit is set, then corresponding + * SSID IE is transmitted in probe request. + * 21:31 reserved + */ + __le32 type; + __le16 channel; /* band is selected by iwl_scan_cmd "flags" field */ + u8 tx_gain; /* gain for analog radio */ + u8 dsp_atten; /* gain for DSP */ + __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */ + __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */ +} __packed; + +/* set number of direct probes __le32 type */ +#define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1)))) + +/** + * struct iwl_ssid_ie - directed scan network information element + * + * Up to 20 of these may appear in REPLY_SCAN_CMD (Note: Only 4 are in + * 3945 SCAN api), selected by "type" bit field in struct iwl_scan_channel; + * each channel may select different ssids from among the 20 (4) entries. + * SSID IEs get transmitted in reverse order of entry. + */ +struct iwl_ssid_ie { + u8 id; + u8 len; + u8 ssid[32]; +} __packed; + +#define PROBE_OPTION_MAX_3945 4 +#define PROBE_OPTION_MAX 20 +#define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF) +#define IWL_GOOD_CRC_TH_DISABLED 0 +#define IWL_GOOD_CRC_TH_DEFAULT cpu_to_le16(1) +#define IWL_GOOD_CRC_TH_NEVER cpu_to_le16(0xffff) +#define IWL_MAX_SCAN_SIZE 1024 +#define IWL_MAX_CMD_SIZE 4096 + +/* + * REPLY_SCAN_CMD = 0x80 (command) + * + * The hardware scan command is very powerful; the driver can set it up to + * maintain (relatively) normal network traffic while doing a scan in the + * background. The max_out_time and suspend_time control the ratio of how + * long the device stays on an associated network channel ("service channel") + * vs. how long it's away from the service channel, i.e. tuned to other channels + * for scanning. + * + * max_out_time is the max time off-channel (in usec), and suspend_time + * is how long (in "extended beacon" format) that the scan is "suspended" + * after returning to the service channel. That is, suspend_time is the + * time that we stay on the service channel, doing normal work, between + * scan segments. The driver may set these parameters differently to support + * scanning when associated vs. not associated, and light vs. heavy traffic + * loads when associated. + * + * After receiving this command, the device's scan engine does the following; + * + * 1) Sends SCAN_START notification to driver + * 2) Checks to see if it has time to do scan for one channel + * 3) Sends NULL packet, with power-save (PS) bit set to 1, + * to tell AP that we're going off-channel + * 4) Tunes to first channel in scan list, does active or passive scan + * 5) Sends SCAN_RESULT notification to driver + * 6) Checks to see if it has time to do scan on *next* channel in list + * 7) Repeats 4-6 until it no longer has time to scan the next channel + * before max_out_time expires + * 8) Returns to service channel + * 9) Sends NULL packet with PS=0 to tell AP that we're back + * 10) Stays on service channel until suspend_time expires + * 11) Repeats entire process 2-10 until list is complete + * 12) Sends SCAN_COMPLETE notification + * + * For fast, efficient scans, the scan command also has support for staying on + * a channel for just a short time, if doing active scanning and getting no + * responses to the transmitted probe request. This time is controlled by + * quiet_time, and the number of received packets below which a channel is + * considered "quiet" is controlled by quiet_plcp_threshold. + * + * For active scanning on channels that have regulatory restrictions against + * blindly transmitting, the scan can listen before transmitting, to make sure + * that there is already legitimate activity on the channel. If enough + * packets are cleanly received on the channel (controlled by good_CRC_th, + * typical value 1), the scan engine starts transmitting probe requests. + * + * Driver must use separate scan commands for 2.4 vs. 5 GHz bands. + * + * To avoid uCode errors, see timing restrictions described under + * struct iwl_scan_channel. + */ + +struct iwl3945_scan_cmd { + __le16 len; + u8 reserved0; + u8 channel_count; /* # channels in channel list */ + __le16 quiet_time; /* dwell only this # millisecs on quiet channel + * (only for active scan) */ + __le16 quiet_plcp_th; /* quiet chnl is < this # pkts (typ. 1) */ + __le16 good_CRC_th; /* passive -> active promotion threshold */ + __le16 reserved1; + __le32 max_out_time; /* max usec to be away from associated (service) + * channel */ + __le32 suspend_time; /* pause scan this long (in "extended beacon + * format") when returning to service channel: + * 3945; 31:24 # beacons, 19:0 additional usec, + * 4965; 31:22 # beacons, 21:0 additional usec. + */ + __le32 flags; /* RXON_FLG_* */ + __le32 filter_flags; /* RXON_FILTER_* */ + + /* For active scans (set to all-0s for passive scans). + * Does not include payload. Must specify Tx rate; no rate scaling. */ + struct iwl3945_tx_cmd tx_cmd; + + /* For directed active scans (set to all-0s otherwise) */ + struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX_3945]; + + /* + * Probe request frame, followed by channel list. + * + * Size of probe request frame is specified by byte count in tx_cmd. + * Channel list follows immediately after probe request frame. + * Number of channels in list is specified by channel_count. + * Each channel in list is of type: + * + * struct iwl3945_scan_channel channels[0]; + * + * NOTE: Only one band of channels can be scanned per pass. You + * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait + * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION) + * before requesting another scan. + */ + u8 data[0]; +} __packed; + +struct iwl_scan_cmd { + __le16 len; + u8 reserved0; + u8 channel_count; /* # channels in channel list */ + __le16 quiet_time; /* dwell only this # millisecs on quiet channel + * (only for active scan) */ + __le16 quiet_plcp_th; /* quiet chnl is < this # pkts (typ. 1) */ + __le16 good_CRC_th; /* passive -> active promotion threshold */ + __le16 rx_chain; /* RXON_RX_CHAIN_* */ + __le32 max_out_time; /* max usec to be away from associated (service) + * channel */ + __le32 suspend_time; /* pause scan this long (in "extended beacon + * format") when returning to service chnl: + * 3945; 31:24 # beacons, 19:0 additional usec, + * 4965; 31:22 # beacons, 21:0 additional usec. + */ + __le32 flags; /* RXON_FLG_* */ + __le32 filter_flags; /* RXON_FILTER_* */ + + /* For active scans (set to all-0s for passive scans). + * Does not include payload. Must specify Tx rate; no rate scaling. */ + struct iwl_tx_cmd tx_cmd; + + /* For directed active scans (set to all-0s otherwise) */ + struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX]; + + /* + * Probe request frame, followed by channel list. + * + * Size of probe request frame is specified by byte count in tx_cmd. + * Channel list follows immediately after probe request frame. + * Number of channels in list is specified by channel_count. + * Each channel in list is of type: + * + * struct iwl_scan_channel channels[0]; + * + * NOTE: Only one band of channels can be scanned per pass. You + * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait + * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION) + * before requesting another scan. + */ + u8 data[0]; +} __packed; + +/* Can abort will notify by complete notification with abort status. */ +#define CAN_ABORT_STATUS cpu_to_le32(0x1) +/* complete notification statuses */ +#define ABORT_STATUS 0x2 + +/* + * REPLY_SCAN_CMD = 0x80 (response) + */ +struct iwl_scanreq_notification { + __le32 status; /* 1: okay, 2: cannot fulfill request */ +} __packed; + +/* + * SCAN_START_NOTIFICATION = 0x82 (notification only, not a command) + */ +struct iwl_scanstart_notification { + __le32 tsf_low; + __le32 tsf_high; + __le32 beacon_timer; + u8 channel; + u8 band; + u8 reserved[2]; + __le32 status; +} __packed; + +#define SCAN_OWNER_STATUS 0x1; +#define MEASURE_OWNER_STATUS 0x2; + +#define IWL_PROBE_STATUS_OK 0 +#define IWL_PROBE_STATUS_TX_FAILED BIT(0) +/* error statuses combined with TX_FAILED */ +#define IWL_PROBE_STATUS_FAIL_TTL BIT(1) +#define IWL_PROBE_STATUS_FAIL_BT BIT(2) + +#define NUMBER_OF_STATISTICS 1 /* first __le32 is good CRC */ +/* + * SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command) + */ +struct iwl_scanresults_notification { + u8 channel; + u8 band; + u8 probe_status; + u8 num_probe_not_sent; /* not enough time to send */ + __le32 tsf_low; + __le32 tsf_high; + __le32 statistics[NUMBER_OF_STATISTICS]; +} __packed; + +/* + * SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command) + */ +struct iwl_scancomplete_notification { + u8 scanned_channels; + u8 status; + u8 last_channel; + __le32 tsf_low; + __le32 tsf_high; +} __packed; + + +/****************************************************************************** + * (9) + * IBSS/AP Commands and Notifications: + * + *****************************************************************************/ + +enum iwl_ibss_manager { + IWL_NOT_IBSS_MANAGER = 0, + IWL_IBSS_MANAGER = 1, +}; + +/* + * BEACON_NOTIFICATION = 0x90 (notification only, not a command) + */ + +struct iwl3945_beacon_notif { + struct iwl3945_tx_resp beacon_notify_hdr; + __le32 low_tsf; + __le32 high_tsf; + __le32 ibss_mgr_status; +} __packed; + +struct iwl4965_beacon_notif { + struct iwl4965_tx_resp beacon_notify_hdr; + __le32 low_tsf; + __le32 high_tsf; + __le32 ibss_mgr_status; +} __packed; + +/* + * REPLY_TX_BEACON = 0x91 (command, has simple generic response) + */ + +struct iwl3945_tx_beacon_cmd { + struct iwl3945_tx_cmd tx; + __le16 tim_idx; + u8 tim_size; + u8 reserved1; + struct ieee80211_hdr frame[0]; /* beacon frame */ +} __packed; + +struct iwl_tx_beacon_cmd { + struct iwl_tx_cmd tx; + __le16 tim_idx; + u8 tim_size; + u8 reserved1; + struct ieee80211_hdr frame[0]; /* beacon frame */ +} __packed; + +/****************************************************************************** + * (10) + * Statistics Commands and Notifications: + * + *****************************************************************************/ + +#define IWL_TEMP_CONVERT 260 + +#define SUP_RATE_11A_MAX_NUM_CHANNELS 8 +#define SUP_RATE_11B_MAX_NUM_CHANNELS 4 +#define SUP_RATE_11G_MAX_NUM_CHANNELS 12 + +/* Used for passing to driver number of successes and failures per rate */ +struct rate_histogram { + union { + __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS]; + __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS]; + __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS]; + } success; + union { + __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS]; + __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS]; + __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS]; + } failed; +} __packed; + +/* statistics command response */ + +struct iwl39_statistics_rx_phy { + __le32 ina_cnt; + __le32 fina_cnt; + __le32 plcp_err; + __le32 crc32_err; + __le32 overrun_err; + __le32 early_overrun_err; + __le32 crc32_good; + __le32 false_alarm_cnt; + __le32 fina_sync_err_cnt; + __le32 sfd_timeout; + __le32 fina_timeout; + __le32 unresponded_rts; + __le32 rxe_frame_limit_overrun; + __le32 sent_ack_cnt; + __le32 sent_cts_cnt; +} __packed; + +struct iwl39_statistics_rx_non_phy { + __le32 bogus_cts; /* CTS received when not expecting CTS */ + __le32 bogus_ack; /* ACK received when not expecting ACK */ + __le32 non_bssid_frames; /* number of frames with BSSID that + * doesn't belong to the STA BSSID */ + __le32 filtered_frames; /* count frames that were dumped in the + * filtering process */ + __le32 non_channel_beacons; /* beacons with our bss id but not on + * our serving channel */ +} __packed; + +struct iwl39_statistics_rx { + struct iwl39_statistics_rx_phy ofdm; + struct iwl39_statistics_rx_phy cck; + struct iwl39_statistics_rx_non_phy general; +} __packed; + +struct iwl39_statistics_tx { + __le32 preamble_cnt; + __le32 rx_detected_cnt; + __le32 bt_prio_defer_cnt; + __le32 bt_prio_kill_cnt; + __le32 few_bytes_cnt; + __le32 cts_timeout; + __le32 ack_timeout; + __le32 expected_ack_cnt; + __le32 actual_ack_cnt; +} __packed; + +struct statistics_dbg { + __le32 burst_check; + __le32 burst_count; + __le32 wait_for_silence_timeout_cnt; + __le32 reserved[3]; +} __packed; + +struct iwl39_statistics_div { + __le32 tx_on_a; + __le32 tx_on_b; + __le32 exec_time; + __le32 probe_time; +} __packed; + +struct iwl39_statistics_general { + __le32 temperature; + struct statistics_dbg dbg; + __le32 sleep_time; + __le32 slots_out; + __le32 slots_idle; + __le32 ttl_timestamp; + struct iwl39_statistics_div div; +} __packed; + +struct statistics_rx_phy { + __le32 ina_cnt; + __le32 fina_cnt; + __le32 plcp_err; + __le32 crc32_err; + __le32 overrun_err; + __le32 early_overrun_err; + __le32 crc32_good; + __le32 false_alarm_cnt; + __le32 fina_sync_err_cnt; + __le32 sfd_timeout; + __le32 fina_timeout; + __le32 unresponded_rts; + __le32 rxe_frame_limit_overrun; + __le32 sent_ack_cnt; + __le32 sent_cts_cnt; + __le32 sent_ba_rsp_cnt; + __le32 dsp_self_kill; + __le32 mh_format_err; + __le32 re_acq_main_rssi_sum; + __le32 reserved3; +} __packed; + +struct statistics_rx_ht_phy { + __le32 plcp_err; + __le32 overrun_err; + __le32 early_overrun_err; + __le32 crc32_good; + __le32 crc32_err; + __le32 mh_format_err; + __le32 agg_crc32_good; + __le32 agg_mpdu_cnt; + __le32 agg_cnt; + __le32 unsupport_mcs; +} __packed; + +#define INTERFERENCE_DATA_AVAILABLE cpu_to_le32(1) + +struct statistics_rx_non_phy { + __le32 bogus_cts; /* CTS received when not expecting CTS */ + __le32 bogus_ack; /* ACK received when not expecting ACK */ + __le32 non_bssid_frames; /* number of frames with BSSID that + * doesn't belong to the STA BSSID */ + __le32 filtered_frames; /* count frames that were dumped in the + * filtering process */ + __le32 non_channel_beacons; /* beacons with our bss id but not on + * our serving channel */ + __le32 channel_beacons; /* beacons with our bss id and in our + * serving channel */ + __le32 num_missed_bcon; /* number of missed beacons */ + __le32 adc_rx_saturation_time; /* count in 0.8us units the time the + * ADC was in saturation */ + __le32 ina_detection_search_time;/* total time (in 0.8us) searched + * for INA */ + __le32 beacon_silence_rssi_a; /* RSSI silence after beacon frame */ + __le32 beacon_silence_rssi_b; /* RSSI silence after beacon frame */ + __le32 beacon_silence_rssi_c; /* RSSI silence after beacon frame */ + __le32 interference_data_flag; /* flag for interference data + * availability. 1 when data is + * available. */ + __le32 channel_load; /* counts RX Enable time in uSec */ + __le32 dsp_false_alarms; /* DSP false alarm (both OFDM + * and CCK) counter */ + __le32 beacon_rssi_a; + __le32 beacon_rssi_b; + __le32 beacon_rssi_c; + __le32 beacon_energy_a; + __le32 beacon_energy_b; + __le32 beacon_energy_c; +} __packed; + +struct statistics_rx { + struct statistics_rx_phy ofdm; + struct statistics_rx_phy cck; + struct statistics_rx_non_phy general; + struct statistics_rx_ht_phy ofdm_ht; +} __packed; + +/** + * struct statistics_tx_power - current tx power + * + * @ant_a: current tx power on chain a in 1/2 dB step + * @ant_b: current tx power on chain b in 1/2 dB step + * @ant_c: current tx power on chain c in 1/2 dB step + */ +struct statistics_tx_power { + u8 ant_a; + u8 ant_b; + u8 ant_c; + u8 reserved; +} __packed; + +struct statistics_tx_non_phy_agg { + __le32 ba_timeout; + __le32 ba_reschedule_frames; + __le32 scd_query_agg_frame_cnt; + __le32 scd_query_no_agg; + __le32 scd_query_agg; + __le32 scd_query_mismatch; + __le32 frame_not_ready; + __le32 underrun; + __le32 bt_prio_kill; + __le32 rx_ba_rsp_cnt; +} __packed; + +struct statistics_tx { + __le32 preamble_cnt; + __le32 rx_detected_cnt; + __le32 bt_prio_defer_cnt; + __le32 bt_prio_kill_cnt; + __le32 few_bytes_cnt; + __le32 cts_timeout; + __le32 ack_timeout; + __le32 expected_ack_cnt; + __le32 actual_ack_cnt; + __le32 dump_msdu_cnt; + __le32 burst_abort_next_frame_mismatch_cnt; + __le32 burst_abort_missing_next_frame_cnt; + __le32 cts_timeout_collision; + __le32 ack_or_ba_timeout_collision; + struct statistics_tx_non_phy_agg agg; + + __le32 reserved1; +} __packed; + + +struct statistics_div { + __le32 tx_on_a; + __le32 tx_on_b; + __le32 exec_time; + __le32 probe_time; + __le32 reserved1; + __le32 reserved2; +} __packed; + +struct statistics_general_common { + __le32 temperature; /* radio temperature */ + struct statistics_dbg dbg; + __le32 sleep_time; + __le32 slots_out; + __le32 slots_idle; + __le32 ttl_timestamp; + struct statistics_div div; + __le32 rx_enable_counter; + /* + * num_of_sos_states: + * count the number of times we have to re-tune + * in order to get out of bad PHY status + */ + __le32 num_of_sos_states; +} __packed; + +struct statistics_general { + struct statistics_general_common common; + __le32 reserved2; + __le32 reserved3; +} __packed; + +#define UCODE_STATISTICS_CLEAR_MSK (0x1 << 0) +#define UCODE_STATISTICS_FREQUENCY_MSK (0x1 << 1) +#define UCODE_STATISTICS_NARROW_BAND_MSK (0x1 << 2) + +/* + * REPLY_STATISTICS_CMD = 0x9c, + * all devices identical. + * + * This command triggers an immediate response containing uCode statistics. + * The response is in the same format as STATISTICS_NOTIFICATION 0x9d, below. + * + * If the CLEAR_STATS configuration flag is set, uCode will clear its + * internal copy of the statistics (counters) after issuing the response. + * This flag does not affect STATISTICS_NOTIFICATIONs after beacons (see below). + * + * If the DISABLE_NOTIF configuration flag is set, uCode will not issue + * STATISTICS_NOTIFICATIONs after received beacons (see below). This flag + * does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself. + */ +#define IWL_STATS_CONF_CLEAR_STATS cpu_to_le32(0x1) /* see above */ +#define IWL_STATS_CONF_DISABLE_NOTIF cpu_to_le32(0x2)/* see above */ +struct iwl_statistics_cmd { + __le32 configuration_flags; /* IWL_STATS_CONF_* */ +} __packed; + +/* + * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command) + * + * By default, uCode issues this notification after receiving a beacon + * while associated. To disable this behavior, set DISABLE_NOTIF flag in the + * REPLY_STATISTICS_CMD 0x9c, above. + * + * Statistics counters continue to increment beacon after beacon, but are + * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD + * 0x9c with CLEAR_STATS bit set (see above). + * + * uCode also issues this notification during scans. uCode clears statistics + * appropriately so that each notification contains statistics for only the + * one channel that has just been scanned. + */ +#define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2) +#define STATISTICS_REPLY_FLG_HT40_MODE_MSK cpu_to_le32(0x8) + +struct iwl3945_notif_statistics { + __le32 flag; + struct iwl39_statistics_rx rx; + struct iwl39_statistics_tx tx; + struct iwl39_statistics_general general; +} __packed; + +struct iwl_notif_statistics { + __le32 flag; + struct statistics_rx rx; + struct statistics_tx tx; + struct statistics_general general; +} __packed; + +/* + * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command) + * + * uCode send MISSED_BEACONS_NOTIFICATION to driver when detect beacon missed + * in regardless of how many missed beacons, which mean when driver receive the + * notification, inside the command, it can find all the beacons information + * which include number of total missed beacons, number of consecutive missed + * beacons, number of beacons received and number of beacons expected to + * receive. + * + * If uCode detected consecutive_missed_beacons > 5, it will reset the radio + * in order to bring the radio/PHY back to working state; which has no relation + * to when driver will perform sensitivity calibration. + * + * Driver should set it own missed_beacon_threshold to decide when to perform + * sensitivity calibration based on number of consecutive missed beacons in + * order to improve overall performance, especially in noisy environment. + * + */ + +#define IWL_MISSED_BEACON_THRESHOLD_MIN (1) +#define IWL_MISSED_BEACON_THRESHOLD_DEF (5) +#define IWL_MISSED_BEACON_THRESHOLD_MAX IWL_MISSED_BEACON_THRESHOLD_DEF + +struct iwl_missed_beacon_notif { + __le32 consecutive_missed_beacons; + __le32 total_missed_becons; + __le32 num_expected_beacons; + __le32 num_recvd_beacons; +} __packed; + + +/****************************************************************************** + * (11) + * Rx Calibration Commands: + * + * With the uCode used for open source drivers, most Tx calibration (except + * for Tx Power) and most Rx calibration is done by uCode during the + * "initialize" phase of uCode boot. Driver must calibrate only: + * + * 1) Tx power (depends on temperature), described elsewhere + * 2) Receiver gain balance (optimize MIMO, and detect disconnected antennas) + * 3) Receiver sensitivity (to optimize signal detection) + * + *****************************************************************************/ + +/** + * SENSITIVITY_CMD = 0xa8 (command, has simple generic response) + * + * This command sets up the Rx signal detector for a sensitivity level that + * is high enough to lock onto all signals within the associated network, + * but low enough to ignore signals that are below a certain threshold, so as + * not to have too many "false alarms". False alarms are signals that the + * Rx DSP tries to lock onto, but then discards after determining that they + * are noise. + * + * The optimum number of false alarms is between 5 and 50 per 200 TUs + * (200 * 1024 uSecs, i.e. 204.8 milliseconds) of actual Rx time (i.e. + * time listening, not transmitting). Driver must adjust sensitivity so that + * the ratio of actual false alarms to actual Rx time falls within this range. + * + * While associated, uCode delivers STATISTICS_NOTIFICATIONs after each + * received beacon. These provide information to the driver to analyze the + * sensitivity. Don't analyze statistics that come in from scanning, or any + * other non-associated-network source. Pertinent statistics include: + * + * From "general" statistics (struct statistics_rx_non_phy): + * + * (beacon_energy_[abc] & 0x0FF00) >> 8 (unsigned, higher value is lower level) + * Measure of energy of desired signal. Used for establishing a level + * below which the device does not detect signals. + * + * (beacon_silence_rssi_[abc] & 0x0FF00) >> 8 (unsigned, units in dB) + * Measure of background noise in silent period after beacon. + * + * channel_load + * uSecs of actual Rx time during beacon period (varies according to + * how much time was spent transmitting). + * + * From "cck" and "ofdm" statistics (struct statistics_rx_phy), separately: + * + * false_alarm_cnt + * Signal locks abandoned early (before phy-level header). + * + * plcp_err + * Signal locks abandoned late (during phy-level header). + * + * NOTE: Both false_alarm_cnt and plcp_err increment monotonically from + * beacon to beacon, i.e. each value is an accumulation of all errors + * before and including the latest beacon. Values will wrap around to 0 + * after counting up to 2^32 - 1. Driver must differentiate vs. + * previous beacon's values to determine # false alarms in the current + * beacon period. + * + * Total number of false alarms = false_alarms + plcp_errs + * + * For OFDM, adjust the following table entries in struct iwl_sensitivity_cmd + * (notice that the start points for OFDM are at or close to settings for + * maximum sensitivity): + * + * START / MIN / MAX + * HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX 90 / 85 / 120 + * HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX 170 / 170 / 210 + * HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX 105 / 105 / 140 + * HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX 220 / 220 / 270 + * + * If actual rate of OFDM false alarms (+ plcp_errors) is too high + * (greater than 50 for each 204.8 msecs listening), reduce sensitivity + * by *adding* 1 to all 4 of the table entries above, up to the max for + * each entry. Conversely, if false alarm rate is too low (less than 5 + * for each 204.8 msecs listening), *subtract* 1 from each entry to + * increase sensitivity. + * + * For CCK sensitivity, keep track of the following: + * + * 1). 20-beacon history of maximum background noise, indicated by + * (beacon_silence_rssi_[abc] & 0x0FF00), units in dB, across the + * 3 receivers. For any given beacon, the "silence reference" is + * the maximum of last 60 samples (20 beacons * 3 receivers). + * + * 2). 10-beacon history of strongest signal level, as indicated + * by (beacon_energy_[abc] & 0x0FF00) >> 8, across the 3 receivers, + * i.e. the strength of the signal through the best receiver at the + * moment. These measurements are "upside down", with lower values + * for stronger signals, so max energy will be *minimum* value. + * + * Then for any given beacon, the driver must determine the *weakest* + * of the strongest signals; this is the minimum level that needs to be + * successfully detected, when using the best receiver at the moment. + * "Max cck energy" is the maximum (higher value means lower energy!) + * of the last 10 minima. Once this is determined, driver must add + * a little margin by adding "6" to it. + * + * 3). Number of consecutive beacon periods with too few false alarms. + * Reset this to 0 at the first beacon period that falls within the + * "good" range (5 to 50 false alarms per 204.8 milliseconds rx). + * + * Then, adjust the following CCK table entries in struct iwl_sensitivity_cmd + * (notice that the start points for CCK are at maximum sensitivity): + * + * START / MIN / MAX + * HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX 125 / 125 / 200 + * HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX 200 / 200 / 400 + * HD_MIN_ENERGY_CCK_DET_INDEX 100 / 0 / 100 + * + * If actual rate of CCK false alarms (+ plcp_errors) is too high + * (greater than 50 for each 204.8 msecs listening), method for reducing + * sensitivity is: + * + * 1) *Add* 3 to value in HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX, + * up to max 400. + * + * 2) If current value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX is < 160, + * sensitivity has been reduced a significant amount; bring it up to + * a moderate 161. Otherwise, *add* 3, up to max 200. + * + * 3) a) If current value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX is > 160, + * sensitivity has been reduced only a moderate or small amount; + * *subtract* 2 from value in HD_MIN_ENERGY_CCK_DET_INDEX, + * down to min 0. Otherwise (if gain has been significantly reduced), + * don't change the HD_MIN_ENERGY_CCK_DET_INDEX value. + * + * b) Save a snapshot of the "silence reference". + * + * If actual rate of CCK false alarms (+ plcp_errors) is too low + * (less than 5 for each 204.8 msecs listening), method for increasing + * sensitivity is used only if: + * + * 1a) Previous beacon did not have too many false alarms + * 1b) AND difference between previous "silence reference" and current + * "silence reference" (prev - current) is 2 or more, + * OR 2) 100 or more consecutive beacon periods have had rate of + * less than 5 false alarms per 204.8 milliseconds rx time. + * + * Method for increasing sensitivity: + * + * 1) *Subtract* 3 from value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX, + * down to min 125. + * + * 2) *Subtract* 3 from value in HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX, + * down to min 200. + * + * 3) *Add* 2 to value in HD_MIN_ENERGY_CCK_DET_INDEX, up to max 100. + * + * If actual rate of CCK false alarms (+ plcp_errors) is within good range + * (between 5 and 50 for each 204.8 msecs listening): + * + * 1) Save a snapshot of the silence reference. + * + * 2) If previous beacon had too many CCK false alarms (+ plcp_errors), + * give some extra margin to energy threshold by *subtracting* 8 + * from value in HD_MIN_ENERGY_CCK_DET_INDEX. + * + * For all cases (too few, too many, good range), make sure that the CCK + * detection threshold (energy) is below the energy level for robust + * detection over the past 10 beacon periods, the "Max cck energy". + * Lower values mean higher energy; this means making sure that the value + * in HD_MIN_ENERGY_CCK_DET_INDEX is at or *above* "Max cck energy". + * + */ + +/* + * Table entries in SENSITIVITY_CMD (struct iwl_sensitivity_cmd) + */ +#define HD_TABLE_SIZE (11) /* number of entries */ +#define HD_MIN_ENERGY_CCK_DET_INDEX (0) /* table indexes */ +#define HD_MIN_ENERGY_OFDM_DET_INDEX (1) +#define HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX (2) +#define HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX (3) +#define HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX (4) +#define HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX (5) +#define HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX (6) +#define HD_BARKER_CORR_TH_ADD_MIN_INDEX (7) +#define HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX (8) +#define HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX (9) +#define HD_OFDM_ENERGY_TH_IN_INDEX (10) + +/* Control field in struct iwl_sensitivity_cmd */ +#define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE cpu_to_le16(0) +#define SENSITIVITY_CMD_CONTROL_WORK_TABLE cpu_to_le16(1) + +/** + * struct iwl_sensitivity_cmd + * @control: (1) updates working table, (0) updates default table + * @table: energy threshold values, use HD_* as index into table + * + * Always use "1" in "control" to update uCode's working table and DSP. + */ +struct iwl_sensitivity_cmd { + __le16 control; /* always use "1" */ + __le16 table[HD_TABLE_SIZE]; /* use HD_* as index */ +} __packed; + + +/** + * REPLY_PHY_CALIBRATION_CMD = 0xb0 (command, has simple generic response) + * + * This command sets the relative gains of 4965 device's 3 radio receiver chains. + * + * After the first association, driver should accumulate signal and noise + * statistics from the STATISTICS_NOTIFICATIONs that follow the first 20 + * beacons from the associated network (don't collect statistics that come + * in from scanning, or any other non-network source). + * + * DISCONNECTED ANTENNA: + * + * Driver should determine which antennas are actually connected, by comparing + * average beacon signal levels for the 3 Rx chains. Accumulate (add) the + * following values over 20 beacons, one accumulator for each of the chains + * a/b/c, from struct statistics_rx_non_phy: + * + * beacon_rssi_[abc] & 0x0FF (unsigned, units in dB) + * + * Find the strongest signal from among a/b/c. Compare the other two to the + * strongest. If any signal is more than 15 dB (times 20, unless you + * divide the accumulated values by 20) below the strongest, the driver + * considers that antenna to be disconnected, and should not try to use that + * antenna/chain for Rx or Tx. If both A and B seem to be disconnected, + * driver should declare the stronger one as connected, and attempt to use it + * (A and B are the only 2 Tx chains!). + * + * + * RX BALANCE: + * + * Driver should balance the 3 receivers (but just the ones that are connected + * to antennas, see above) for gain, by comparing the average signal levels + * detected during the silence after each beacon (background noise). + * Accumulate (add) the following values over 20 beacons, one accumulator for + * each of the chains a/b/c, from struct statistics_rx_non_phy: + * + * beacon_silence_rssi_[abc] & 0x0FF (unsigned, units in dB) + * + * Find the weakest background noise level from among a/b/c. This Rx chain + * will be the reference, with 0 gain adjustment. Attenuate other channels by + * finding noise difference: + * + * (accum_noise[i] - accum_noise[reference]) / 30 + * + * The "30" adjusts the dB in the 20 accumulated samples to units of 1.5 dB. + * For use in diff_gain_[abc] fields of struct iwl_calibration_cmd, the + * driver should limit the difference results to a range of 0-3 (0-4.5 dB), + * and set bit 2 to indicate "reduce gain". The value for the reference + * (weakest) chain should be "0". + * + * diff_gain_[abc] bit fields: + * 2: (1) reduce gain, (0) increase gain + * 1-0: amount of gain, units of 1.5 dB + */ + +/* Phy calibration command for series */ +/* The default calibrate table size if not specified by firmware */ +#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE 18 +enum { + IWL_PHY_CALIBRATE_DIFF_GAIN_CMD = 7, + IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 19, +}; + +#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE (253) + +struct iwl_calib_hdr { + u8 op_code; + u8 first_group; + u8 groups_num; + u8 data_valid; +} __packed; + +/* IWL_PHY_CALIBRATE_DIFF_GAIN_CMD (7) */ +struct iwl_calib_diff_gain_cmd { + struct iwl_calib_hdr hdr; + s8 diff_gain_a; /* see above */ + s8 diff_gain_b; + s8 diff_gain_c; + u8 reserved1; +} __packed; + +/****************************************************************************** + * (12) + * Miscellaneous Commands: + * + *****************************************************************************/ + +/* + * LEDs Command & Response + * REPLY_LEDS_CMD = 0x48 (command, has simple generic response) + * + * For each of 3 possible LEDs (Activity/Link/Tech, selected by "id" field), + * this command turns it on or off, or sets up a periodic blinking cycle. + */ +struct iwl_led_cmd { + __le32 interval; /* "interval" in uSec */ + u8 id; /* 1: Activity, 2: Link, 3: Tech */ + u8 off; /* # intervals off while blinking; + * "0", with >0 "on" value, turns LED on */ + u8 on; /* # intervals on while blinking; + * "0", regardless of "off", turns LED off */ + u8 reserved; +} __packed; + + +/****************************************************************************** + * (13) + * Union of all expected notifications/responses: + * + *****************************************************************************/ + +struct iwl_rx_packet { + /* + * The first 4 bytes of the RX frame header contain both the RX frame + * size and some flags. + * Bit fields: + * 31: flag flush RB request + * 30: flag ignore TC (terminal counter) request + * 29: flag fast IRQ request + * 28-14: Reserved + * 13-00: RX frame size + */ + __le32 len_n_flags; + struct iwl_cmd_header hdr; + union { + struct iwl3945_rx_frame rx_frame; + struct iwl3945_tx_resp tx_resp; + struct iwl3945_beacon_notif beacon_status; + + struct iwl_alive_resp alive_frame; + struct iwl_spectrum_notification spectrum_notif; + struct iwl_csa_notification csa_notif; + struct iwl_error_resp err_resp; + struct iwl_card_state_notif card_state_notif; + struct iwl_add_sta_resp add_sta; + struct iwl_rem_sta_resp rem_sta; + struct iwl_sleep_notification sleep_notif; + struct iwl_spectrum_resp spectrum; + struct iwl_notif_statistics stats; + struct iwl_compressed_ba_resp compressed_ba; + struct iwl_missed_beacon_notif missed_beacon; + __le32 status; + u8 raw[0]; + } u; +} __packed; + +#endif /* __iwl_legacy_commands_h__ */ diff --git a/drivers/net/wireless/iwlegacy/iwl-core.c b/drivers/net/wireless/iwlegacy/iwl-core.c new file mode 100644 index 000000000000..c95c3bcb724d --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-core.c @@ -0,0 +1,2668 @@ +/****************************************************************************** + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "iwl-eeprom.h" +#include "iwl-dev.h" +#include "iwl-debug.h" +#include "iwl-core.h" +#include "iwl-io.h" +#include "iwl-power.h" +#include "iwl-sta.h" +#include "iwl-helpers.h" + + +MODULE_DESCRIPTION("iwl-legacy: common functions for 3945 and 4965"); +MODULE_VERSION(IWLWIFI_VERSION); +MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); +MODULE_LICENSE("GPL"); + +/* + * set bt_coex_active to true, uCode will do kill/defer + * every time the priority line is asserted (BT is sending signals on the + * priority line in the PCIx). + * set bt_coex_active to false, uCode will ignore the BT activity and + * perform the normal operation + * + * User might experience transmit issue on some platform due to WiFi/BT + * co-exist problem. The possible behaviors are: + * Able to scan and finding all the available AP + * Not able to associate with any AP + * On those platforms, WiFi communication can be restored by set + * "bt_coex_active" module parameter to "false" + * + * default: bt_coex_active = true (BT_COEX_ENABLE) + */ +bool bt_coex_active = true; +EXPORT_SYMBOL_GPL(bt_coex_active); +module_param(bt_coex_active, bool, S_IRUGO); +MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist"); + +u32 iwl_debug_level; +EXPORT_SYMBOL(iwl_debug_level); + +const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +EXPORT_SYMBOL(iwl_bcast_addr); + + +/* This function both allocates and initializes hw and priv. */ +struct ieee80211_hw *iwl_legacy_alloc_all(struct iwl_cfg *cfg) +{ + struct iwl_priv *priv; + /* mac80211 allocates memory for this device instance, including + * space for this driver's private structure */ + struct ieee80211_hw *hw; + + hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), + cfg->ops->ieee80211_ops); + if (hw == NULL) { + pr_err("%s: Can not allocate network device\n", + cfg->name); + goto out; + } + + priv = hw->priv; + priv->hw = hw; + +out: + return hw; +} +EXPORT_SYMBOL(iwl_legacy_alloc_all); + +#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ +#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ +static void iwl_legacy_init_ht_hw_capab(const struct iwl_priv *priv, + struct ieee80211_sta_ht_cap *ht_info, + enum ieee80211_band band) +{ + u16 max_bit_rate = 0; + u8 rx_chains_num = priv->hw_params.rx_chains_num; + u8 tx_chains_num = priv->hw_params.tx_chains_num; + + ht_info->cap = 0; + memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); + + ht_info->ht_supported = true; + + ht_info->cap |= IEEE80211_HT_CAP_SGI_20; + max_bit_rate = MAX_BIT_RATE_20_MHZ; + if (priv->hw_params.ht40_channel & BIT(band)) { + ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; + ht_info->cap |= IEEE80211_HT_CAP_SGI_40; + ht_info->mcs.rx_mask[4] = 0x01; + max_bit_rate = MAX_BIT_RATE_40_MHZ; + } + + if (priv->cfg->mod_params->amsdu_size_8K) + ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; + + ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; + ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF; + + ht_info->mcs.rx_mask[0] = 0xFF; + if (rx_chains_num >= 2) + ht_info->mcs.rx_mask[1] = 0xFF; + if (rx_chains_num >= 3) + ht_info->mcs.rx_mask[2] = 0xFF; + + /* Highest supported Rx data rate */ + max_bit_rate *= rx_chains_num; + WARN_ON(max_bit_rate & ~IEEE80211_HT_MCS_RX_HIGHEST_MASK); + ht_info->mcs.rx_highest = cpu_to_le16(max_bit_rate); + + /* Tx MCS capabilities */ + ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; + if (tx_chains_num != rx_chains_num) { + ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; + ht_info->mcs.tx_params |= ((tx_chains_num - 1) << + IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); + } +} + +/** + * iwl_legacy_init_geos - Initialize mac80211's geo/channel info based from eeprom + */ +int iwl_legacy_init_geos(struct iwl_priv *priv) +{ + struct iwl_channel_info *ch; + struct ieee80211_supported_band *sband; + struct ieee80211_channel *channels; + struct ieee80211_channel *geo_ch; + struct ieee80211_rate *rates; + int i = 0; + + if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || + priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { + IWL_DEBUG_INFO(priv, "Geography modes already initialized.\n"); + set_bit(STATUS_GEO_CONFIGURED, &priv->status); + return 0; + } + + channels = kzalloc(sizeof(struct ieee80211_channel) * + priv->channel_count, GFP_KERNEL); + if (!channels) + return -ENOMEM; + + rates = kzalloc((sizeof(struct ieee80211_rate) * IWL_RATE_COUNT_LEGACY), + GFP_KERNEL); + if (!rates) { + kfree(channels); + return -ENOMEM; + } + + /* 5.2GHz channels start after the 2.4GHz channels */ + sband = &priv->bands[IEEE80211_BAND_5GHZ]; + sband->channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)]; + /* just OFDM */ + sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; + sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; + + if (priv->cfg->sku & IWL_SKU_N) + iwl_legacy_init_ht_hw_capab(priv, &sband->ht_cap, + IEEE80211_BAND_5GHZ); + + sband = &priv->bands[IEEE80211_BAND_2GHZ]; + sband->channels = channels; + /* OFDM & CCK */ + sband->bitrates = rates; + sband->n_bitrates = IWL_RATE_COUNT_LEGACY; + + if (priv->cfg->sku & IWL_SKU_N) + iwl_legacy_init_ht_hw_capab(priv, &sband->ht_cap, + IEEE80211_BAND_2GHZ); + + priv->ieee_channels = channels; + priv->ieee_rates = rates; + + for (i = 0; i < priv->channel_count; i++) { + ch = &priv->channel_info[i]; + + if (!iwl_legacy_is_channel_valid(ch)) + continue; + + if (iwl_legacy_is_channel_a_band(ch)) + sband = &priv->bands[IEEE80211_BAND_5GHZ]; + else + sband = &priv->bands[IEEE80211_BAND_2GHZ]; + + geo_ch = &sband->channels[sband->n_channels++]; + + geo_ch->center_freq = + ieee80211_channel_to_frequency(ch->channel, ch->band); + geo_ch->max_power = ch->max_power_avg; + geo_ch->max_antenna_gain = 0xff; + geo_ch->hw_value = ch->channel; + + if (iwl_legacy_is_channel_valid(ch)) { + if (!(ch->flags & EEPROM_CHANNEL_IBSS)) + geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; + + if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) + geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; + + if (ch->flags & EEPROM_CHANNEL_RADAR) + geo_ch->flags |= IEEE80211_CHAN_RADAR; + + geo_ch->flags |= ch->ht40_extension_channel; + + if (ch->max_power_avg > priv->tx_power_device_lmt) + priv->tx_power_device_lmt = ch->max_power_avg; + } else { + geo_ch->flags |= IEEE80211_CHAN_DISABLED; + } + + IWL_DEBUG_INFO(priv, "Channel %d Freq=%d[%sGHz] %s flag=0x%X\n", + ch->channel, geo_ch->center_freq, + iwl_legacy_is_channel_a_band(ch) ? "5.2" : "2.4", + geo_ch->flags & IEEE80211_CHAN_DISABLED ? + "restricted" : "valid", + geo_ch->flags); + } + + if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && + priv->cfg->sku & IWL_SKU_A) { + IWL_INFO(priv, "Incorrectly detected BG card as ABG. " + "Please send your PCI ID 0x%04X:0x%04X to maintainer.\n", + priv->pci_dev->device, + priv->pci_dev->subsystem_device); + priv->cfg->sku &= ~IWL_SKU_A; + } + + IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", + priv->bands[IEEE80211_BAND_2GHZ].n_channels, + priv->bands[IEEE80211_BAND_5GHZ].n_channels); + + set_bit(STATUS_GEO_CONFIGURED, &priv->status); + + return 0; +} +EXPORT_SYMBOL(iwl_legacy_init_geos); + +/* + * iwl_legacy_free_geos - undo allocations in iwl_legacy_init_geos + */ +void iwl_legacy_free_geos(struct iwl_priv *priv) +{ + kfree(priv->ieee_channels); + kfree(priv->ieee_rates); + clear_bit(STATUS_GEO_CONFIGURED, &priv->status); +} +EXPORT_SYMBOL(iwl_legacy_free_geos); + +static bool iwl_legacy_is_channel_extension(struct iwl_priv *priv, + enum ieee80211_band band, + u16 channel, u8 extension_chan_offset) +{ + const struct iwl_channel_info *ch_info; + + ch_info = iwl_legacy_get_channel_info(priv, band, channel); + if (!iwl_legacy_is_channel_valid(ch_info)) + return false; + + if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) + return !(ch_info->ht40_extension_channel & + IEEE80211_CHAN_NO_HT40PLUS); + else if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) + return !(ch_info->ht40_extension_channel & + IEEE80211_CHAN_NO_HT40MINUS); + + return false; +} + +bool iwl_legacy_is_ht40_tx_allowed(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_sta_ht_cap *ht_cap) +{ + if (!ctx->ht.enabled || !ctx->ht.is_40mhz) + return false; + + /* + * We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40 + * the bit will not set if it is pure 40MHz case + */ + if (ht_cap && !ht_cap->ht_supported) + return false; + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS + if (priv->disable_ht40) + return false; +#endif + + return iwl_legacy_is_channel_extension(priv, priv->band, + le16_to_cpu(ctx->staging.channel), + ctx->ht.extension_chan_offset); +} +EXPORT_SYMBOL(iwl_legacy_is_ht40_tx_allowed); + +static u16 iwl_legacy_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val) +{ + u16 new_val; + u16 beacon_factor; + + /* + * If mac80211 hasn't given us a beacon interval, program + * the default into the device. + */ + if (!beacon_val) + return DEFAULT_BEACON_INTERVAL; + + /* + * If the beacon interval we obtained from the peer + * is too large, we'll have to wake up more often + * (and in IBSS case, we'll beacon too much) + * + * For example, if max_beacon_val is 4096, and the + * requested beacon interval is 7000, we'll have to + * use 3500 to be able to wake up on the beacons. + * + * This could badly influence beacon detection stats. + */ + + beacon_factor = (beacon_val + max_beacon_val) / max_beacon_val; + new_val = beacon_val / beacon_factor; + + if (!new_val) + new_val = max_beacon_val; + + return new_val; +} + +int +iwl_legacy_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +{ + u64 tsf; + s32 interval_tm, rem; + struct ieee80211_conf *conf = NULL; + u16 beacon_int; + struct ieee80211_vif *vif = ctx->vif; + + conf = iwl_legacy_ieee80211_get_hw_conf(priv->hw); + + lockdep_assert_held(&priv->mutex); + + memset(&ctx->timing, 0, sizeof(struct iwl_rxon_time_cmd)); + + ctx->timing.timestamp = cpu_to_le64(priv->timestamp); + ctx->timing.listen_interval = cpu_to_le16(conf->listen_interval); + + beacon_int = vif ? vif->bss_conf.beacon_int : 0; + + /* + * TODO: For IBSS we need to get atim_window from mac80211, + * for now just always use 0 + */ + ctx->timing.atim_window = 0; + + beacon_int = iwl_legacy_adjust_beacon_interval(beacon_int, + priv->hw_params.max_beacon_itrvl * TIME_UNIT); + ctx->timing.beacon_interval = cpu_to_le16(beacon_int); + + tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */ + interval_tm = beacon_int * TIME_UNIT; + rem = do_div(tsf, interval_tm); + ctx->timing.beacon_init_val = cpu_to_le32(interval_tm - rem); + + ctx->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ?: 1) : 1; + + IWL_DEBUG_ASSOC(priv, + "beacon interval %d beacon timer %d beacon tim %d\n", + le16_to_cpu(ctx->timing.beacon_interval), + le32_to_cpu(ctx->timing.beacon_init_val), + le16_to_cpu(ctx->timing.atim_window)); + + return iwl_legacy_send_cmd_pdu(priv, ctx->rxon_timing_cmd, + sizeof(ctx->timing), &ctx->timing); +} +EXPORT_SYMBOL(iwl_legacy_send_rxon_timing); + +void +iwl_legacy_set_rxon_hwcrypto(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + int hw_decrypt) +{ + struct iwl_legacy_rxon_cmd *rxon = &ctx->staging; + + if (hw_decrypt) + rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK; + else + rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK; + +} +EXPORT_SYMBOL(iwl_legacy_set_rxon_hwcrypto); + +/* validate RXON structure is valid */ +int +iwl_legacy_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +{ + struct iwl_legacy_rxon_cmd *rxon = &ctx->staging; + bool error = false; + + if (rxon->flags & RXON_FLG_BAND_24G_MSK) { + if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) { + IWL_WARN(priv, "check 2.4G: wrong narrow\n"); + error = true; + } + if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) { + IWL_WARN(priv, "check 2.4G: wrong radar\n"); + error = true; + } + } else { + if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) { + IWL_WARN(priv, "check 5.2G: not short slot!\n"); + error = true; + } + if (rxon->flags & RXON_FLG_CCK_MSK) { + IWL_WARN(priv, "check 5.2G: CCK!\n"); + error = true; + } + } + if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) { + IWL_WARN(priv, "mac/bssid mcast!\n"); + error = true; + } + + /* make sure basic rates 6Mbps and 1Mbps are supported */ + if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 && + (rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) { + IWL_WARN(priv, "neither 1 nor 6 are basic\n"); + error = true; + } + + if (le16_to_cpu(rxon->assoc_id) > 2007) { + IWL_WARN(priv, "aid > 2007\n"); + error = true; + } + + if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) + == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) { + IWL_WARN(priv, "CCK and short slot\n"); + error = true; + } + + if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) + == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) { + IWL_WARN(priv, "CCK and auto detect"); + error = true; + } + + if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK | + RXON_FLG_TGG_PROTECT_MSK)) == + RXON_FLG_TGG_PROTECT_MSK) { + IWL_WARN(priv, "TGg but no auto-detect\n"); + error = true; + } + + if (error) + IWL_WARN(priv, "Tuning to channel %d\n", + le16_to_cpu(rxon->channel)); + + if (error) { + IWL_ERR(priv, "Invalid RXON\n"); + return -EINVAL; + } + return 0; +} +EXPORT_SYMBOL(iwl_legacy_check_rxon_cmd); + +/** + * iwl_legacy_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed + * @priv: staging_rxon is compared to active_rxon + * + * If the RXON structure is changing enough to require a new tune, + * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that + * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. + */ +int iwl_legacy_full_rxon_required(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + const struct iwl_legacy_rxon_cmd *staging = &ctx->staging; + const struct iwl_legacy_rxon_cmd *active = &ctx->active; + +#define CHK(cond) \ + if ((cond)) { \ + IWL_DEBUG_INFO(priv, "need full RXON - " #cond "\n"); \ + return 1; \ + } + +#define CHK_NEQ(c1, c2) \ + if ((c1) != (c2)) { \ + IWL_DEBUG_INFO(priv, "need full RXON - " \ + #c1 " != " #c2 " - %d != %d\n", \ + (c1), (c2)); \ + return 1; \ + } + + /* These items are only settable from the full RXON command */ + CHK(!iwl_legacy_is_associated_ctx(ctx)); + CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr)); + CHK(compare_ether_addr(staging->node_addr, active->node_addr)); + CHK(compare_ether_addr(staging->wlap_bssid_addr, + active->wlap_bssid_addr)); + CHK_NEQ(staging->dev_type, active->dev_type); + CHK_NEQ(staging->channel, active->channel); + CHK_NEQ(staging->air_propagation, active->air_propagation); + CHK_NEQ(staging->ofdm_ht_single_stream_basic_rates, + active->ofdm_ht_single_stream_basic_rates); + CHK_NEQ(staging->ofdm_ht_dual_stream_basic_rates, + active->ofdm_ht_dual_stream_basic_rates); + CHK_NEQ(staging->assoc_id, active->assoc_id); + + /* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can + * be updated with the RXON_ASSOC command -- however only some + * flag transitions are allowed using RXON_ASSOC */ + + /* Check if we are not switching bands */ + CHK_NEQ(staging->flags & RXON_FLG_BAND_24G_MSK, + active->flags & RXON_FLG_BAND_24G_MSK); + + /* Check if we are switching association toggle */ + CHK_NEQ(staging->filter_flags & RXON_FILTER_ASSOC_MSK, + active->filter_flags & RXON_FILTER_ASSOC_MSK); + +#undef CHK +#undef CHK_NEQ + + return 0; +} +EXPORT_SYMBOL(iwl_legacy_full_rxon_required); + +u8 iwl_legacy_get_lowest_plcp(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + /* + * Assign the lowest rate -- should really get this from + * the beacon skb from mac80211. + */ + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) + return IWL_RATE_1M_PLCP; + else + return IWL_RATE_6M_PLCP; +} +EXPORT_SYMBOL(iwl_legacy_get_lowest_plcp); + +static void _iwl_legacy_set_rxon_ht(struct iwl_priv *priv, + struct iwl_ht_config *ht_conf, + struct iwl_rxon_context *ctx) +{ + struct iwl_legacy_rxon_cmd *rxon = &ctx->staging; + + if (!ctx->ht.enabled) { + rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | + RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | + RXON_FLG_HT40_PROT_MSK | + RXON_FLG_HT_PROT_MSK); + return; + } + + rxon->flags |= cpu_to_le32(ctx->ht.protection << + RXON_FLG_HT_OPERATING_MODE_POS); + + /* Set up channel bandwidth: + * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */ + /* clear the HT channel mode before set the mode */ + rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | + RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); + if (iwl_legacy_is_ht40_tx_allowed(priv, ctx, NULL)) { + /* pure ht40 */ + if (ctx->ht.protection == + IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) { + rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40; + /* Note: control channel is opposite of extension channel */ + switch (ctx->ht.extension_chan_offset) { + case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: + rxon->flags &= + ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; + break; + case IEEE80211_HT_PARAM_CHA_SEC_BELOW: + rxon->flags |= + RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; + break; + } + } else { + /* Note: control channel is opposite of extension channel */ + switch (ctx->ht.extension_chan_offset) { + case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: + rxon->flags &= + ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); + rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED; + break; + case IEEE80211_HT_PARAM_CHA_SEC_BELOW: + rxon->flags |= + RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; + rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED; + break; + case IEEE80211_HT_PARAM_CHA_SEC_NONE: + default: + /* channel location only valid if in Mixed mode */ + IWL_ERR(priv, + "invalid extension channel offset\n"); + break; + } + } + } else { + rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY; + } + + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + + IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X " + "extension channel offset 0x%x\n", + le32_to_cpu(rxon->flags), ctx->ht.protection, + ctx->ht.extension_chan_offset); +} + +void iwl_legacy_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf) +{ + struct iwl_rxon_context *ctx; + + for_each_context(priv, ctx) + _iwl_legacy_set_rxon_ht(priv, ht_conf, ctx); +} +EXPORT_SYMBOL(iwl_legacy_set_rxon_ht); + +/* Return valid, unused, channel for a passive scan to reset the RF */ +u8 iwl_legacy_get_single_channel_number(struct iwl_priv *priv, + enum ieee80211_band band) +{ + const struct iwl_channel_info *ch_info; + int i; + u8 channel = 0; + u8 min, max; + struct iwl_rxon_context *ctx; + + if (band == IEEE80211_BAND_5GHZ) { + min = 14; + max = priv->channel_count; + } else { + min = 0; + max = 14; + } + + for (i = min; i < max; i++) { + bool busy = false; + + for_each_context(priv, ctx) { + busy = priv->channel_info[i].channel == + le16_to_cpu(ctx->staging.channel); + if (busy) + break; + } + + if (busy) + continue; + + channel = priv->channel_info[i].channel; + ch_info = iwl_legacy_get_channel_info(priv, band, channel); + if (iwl_legacy_is_channel_valid(ch_info)) + break; + } + + return channel; +} +EXPORT_SYMBOL(iwl_legacy_get_single_channel_number); + +/** + * iwl_legacy_set_rxon_channel - Set the band and channel values in staging RXON + * @ch: requested channel as a pointer to struct ieee80211_channel + + * NOTE: Does not commit to the hardware; it sets appropriate bit fields + * in the staging RXON flag structure based on the ch->band + */ +int +iwl_legacy_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, + struct iwl_rxon_context *ctx) +{ + enum ieee80211_band band = ch->band; + u16 channel = ch->hw_value; + + if ((le16_to_cpu(ctx->staging.channel) == channel) && + (priv->band == band)) + return 0; + + ctx->staging.channel = cpu_to_le16(channel); + if (band == IEEE80211_BAND_5GHZ) + ctx->staging.flags &= ~RXON_FLG_BAND_24G_MSK; + else + ctx->staging.flags |= RXON_FLG_BAND_24G_MSK; + + priv->band = band; + + IWL_DEBUG_INFO(priv, "Staging channel set to %d [%d]\n", channel, band); + + return 0; +} +EXPORT_SYMBOL(iwl_legacy_set_rxon_channel); + +void iwl_legacy_set_flags_for_band(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + enum ieee80211_band band, + struct ieee80211_vif *vif) +{ + if (band == IEEE80211_BAND_5GHZ) { + ctx->staging.flags &= + ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK + | RXON_FLG_CCK_MSK); + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + } else { + /* Copied from iwl_post_associate() */ + if (vif && vif->bss_conf.use_short_slot) + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + else + ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + + ctx->staging.flags |= RXON_FLG_BAND_24G_MSK; + ctx->staging.flags |= RXON_FLG_AUTO_DETECT_MSK; + ctx->staging.flags &= ~RXON_FLG_CCK_MSK; + } +} +EXPORT_SYMBOL(iwl_legacy_set_flags_for_band); + +/* + * initialize rxon structure with default values from eeprom + */ +void iwl_legacy_connection_init_rx_config(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + const struct iwl_channel_info *ch_info; + + memset(&ctx->staging, 0, sizeof(ctx->staging)); + + if (!ctx->vif) { + ctx->staging.dev_type = ctx->unused_devtype; + } else + switch (ctx->vif->type) { + + case NL80211_IFTYPE_STATION: + ctx->staging.dev_type = ctx->station_devtype; + ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; + break; + + case NL80211_IFTYPE_ADHOC: + ctx->staging.dev_type = ctx->ibss_devtype; + ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; + ctx->staging.filter_flags = RXON_FILTER_BCON_AWARE_MSK | + RXON_FILTER_ACCEPT_GRP_MSK; + break; + + default: + IWL_ERR(priv, "Unsupported interface type %d\n", + ctx->vif->type); + break; + } + +#if 0 + /* TODO: Figure out when short_preamble would be set and cache from + * that */ + if (!hw_to_local(priv->hw)->short_preamble) + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + else + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; +#endif + + ch_info = iwl_legacy_get_channel_info(priv, priv->band, + le16_to_cpu(ctx->active.channel)); + + if (!ch_info) + ch_info = &priv->channel_info[0]; + + ctx->staging.channel = cpu_to_le16(ch_info->channel); + priv->band = ch_info->band; + + iwl_legacy_set_flags_for_band(priv, ctx, priv->band, ctx->vif); + + ctx->staging.ofdm_basic_rates = + (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; + ctx->staging.cck_basic_rates = + (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; + + /* clear both MIX and PURE40 mode flag */ + ctx->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED | + RXON_FLG_CHANNEL_MODE_PURE_40); + if (ctx->vif) + memcpy(ctx->staging.node_addr, ctx->vif->addr, ETH_ALEN); + + ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff; + ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff; +} +EXPORT_SYMBOL(iwl_legacy_connection_init_rx_config); + +void iwl_legacy_set_rate(struct iwl_priv *priv) +{ + const struct ieee80211_supported_band *hw = NULL; + struct ieee80211_rate *rate; + struct iwl_rxon_context *ctx; + int i; + + hw = iwl_get_hw_mode(priv, priv->band); + if (!hw) { + IWL_ERR(priv, "Failed to set rate: unable to get hw mode\n"); + return; + } + + priv->active_rate = 0; + + for (i = 0; i < hw->n_bitrates; i++) { + rate = &(hw->bitrates[i]); + if (rate->hw_value < IWL_RATE_COUNT_LEGACY) + priv->active_rate |= (1 << rate->hw_value); + } + + IWL_DEBUG_RATE(priv, "Set active_rate = %0x\n", priv->active_rate); + + for_each_context(priv, ctx) { + ctx->staging.cck_basic_rates = + (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; + + ctx->staging.ofdm_basic_rates = + (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; + } +} +EXPORT_SYMBOL(iwl_legacy_set_rate); + +void iwl_legacy_chswitch_done(struct iwl_priv *priv, bool is_success) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (priv->switch_rxon.switch_in_progress) { + ieee80211_chswitch_done(ctx->vif, is_success); + mutex_lock(&priv->mutex); + priv->switch_rxon.switch_in_progress = false; + mutex_unlock(&priv->mutex); + } +} +EXPORT_SYMBOL(iwl_legacy_chswitch_done); + +void iwl_legacy_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_csa_notification *csa = &(pkt->u.csa_notif); + + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + struct iwl_legacy_rxon_cmd *rxon = (void *)&ctx->active; + + if (priv->switch_rxon.switch_in_progress) { + if (!le32_to_cpu(csa->status) && + (csa->channel == priv->switch_rxon.channel)) { + rxon->channel = csa->channel; + ctx->staging.channel = csa->channel; + IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", + le16_to_cpu(csa->channel)); + iwl_legacy_chswitch_done(priv, true); + } else { + IWL_ERR(priv, "CSA notif (fail) : channel %d\n", + le16_to_cpu(csa->channel)); + iwl_legacy_chswitch_done(priv, false); + } + } +} +EXPORT_SYMBOL(iwl_legacy_rx_csa); + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +void iwl_legacy_print_rx_config_cmd(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + struct iwl_legacy_rxon_cmd *rxon = &ctx->staging; + + IWL_DEBUG_RADIO(priv, "RX CONFIG:\n"); + iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); + IWL_DEBUG_RADIO(priv, "u16 channel: 0x%x\n", + le16_to_cpu(rxon->channel)); + IWL_DEBUG_RADIO(priv, "u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags)); + IWL_DEBUG_RADIO(priv, "u32 filter_flags: 0x%08x\n", + le32_to_cpu(rxon->filter_flags)); + IWL_DEBUG_RADIO(priv, "u8 dev_type: 0x%x\n", rxon->dev_type); + IWL_DEBUG_RADIO(priv, "u8 ofdm_basic_rates: 0x%02x\n", + rxon->ofdm_basic_rates); + IWL_DEBUG_RADIO(priv, "u8 cck_basic_rates: 0x%02x\n", + rxon->cck_basic_rates); + IWL_DEBUG_RADIO(priv, "u8[6] node_addr: %pM\n", rxon->node_addr); + IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr); + IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", + le16_to_cpu(rxon->assoc_id)); +} +EXPORT_SYMBOL(iwl_legacy_print_rx_config_cmd); +#endif +/** + * iwl_legacy_irq_handle_error - called for HW or SW error interrupt from card + */ +void iwl_legacy_irq_handle_error(struct iwl_priv *priv) +{ + /* Set the FW error flag -- cleared on iwl_down */ + set_bit(STATUS_FW_ERROR, &priv->status); + + /* Cancel currently queued command. */ + clear_bit(STATUS_HCMD_ACTIVE, &priv->status); + + IWL_ERR(priv, "Loaded firmware version: %s\n", + priv->hw->wiphy->fw_version); + + priv->cfg->ops->lib->dump_nic_error_log(priv); + if (priv->cfg->ops->lib->dump_fh) + priv->cfg->ops->lib->dump_fh(priv, NULL, false); + priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false); +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + if (iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) + iwl_legacy_print_rx_config_cmd(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); +#endif + + wake_up_interruptible(&priv->wait_command_queue); + + /* Keep the restart process from trying to send host + * commands by clearing the INIT status bit */ + clear_bit(STATUS_READY, &priv->status); + + if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { + IWL_DEBUG(priv, IWL_DL_FW_ERRORS, + "Restarting adapter due to uCode error.\n"); + + if (priv->cfg->mod_params->restart_fw) + queue_work(priv->workqueue, &priv->restart); + } +} +EXPORT_SYMBOL(iwl_legacy_irq_handle_error); + +static int iwl_legacy_apm_stop_master(struct iwl_priv *priv) +{ + int ret = 0; + + /* stop device's busmaster DMA activity */ + iwl_legacy_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); + + ret = iwl_poll_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED, + CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); + if (ret) + IWL_WARN(priv, "Master Disable Timed Out, 100 usec\n"); + + IWL_DEBUG_INFO(priv, "stop master\n"); + + return ret; +} + +void iwl_legacy_apm_stop(struct iwl_priv *priv) +{ + IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n"); + + /* Stop device's DMA activity */ + iwl_legacy_apm_stop_master(priv); + + /* Reset the entire device */ + iwl_legacy_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); + + udelay(10); + + /* + * Clear "initialization complete" bit to move adapter from + * D0A* (powered-up Active) --> D0U* (Uninitialized) state. + */ + iwl_legacy_clear_bit(priv, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_INIT_DONE); +} +EXPORT_SYMBOL(iwl_legacy_apm_stop); + + +/* + * Start up NIC's basic functionality after it has been reset + * (e.g. after platform boot, or shutdown via iwl_legacy_apm_stop()) + * NOTE: This does not load uCode nor start the embedded processor + */ +int iwl_legacy_apm_init(struct iwl_priv *priv) +{ + int ret = 0; + u16 lctl; + + IWL_DEBUG_INFO(priv, "Init card's basic functions\n"); + + /* + * Use "set_bit" below rather than "write", to preserve any hardware + * bits already set by default after reset. + */ + + /* Disable L0S exit timer (platform NMI Work/Around) */ + iwl_legacy_set_bit(priv, CSR_GIO_CHICKEN_BITS, + CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); + + /* + * Disable L0s without affecting L1; + * don't wait for ICH L0s (ICH bug W/A) + */ + iwl_legacy_set_bit(priv, CSR_GIO_CHICKEN_BITS, + CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); + + /* Set FH wait threshold to maximum (HW error during stress W/A) */ + iwl_legacy_set_bit(priv, CSR_DBG_HPET_MEM_REG, + CSR_DBG_HPET_MEM_REG_VAL); + + /* + * Enable HAP INTA (interrupt from management bus) to + * wake device's PCI Express link L1a -> L0s + * NOTE: This is no-op for 3945 (non-existant bit) + */ + iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); + + /* + * HW bug W/A for instability in PCIe bus L0->L0S->L1 transition. + * Check if BIOS (or OS) enabled L1-ASPM on this device. + * If so (likely), disable L0S, so device moves directly L0->L1; + * costs negligible amount of power savings. + * If not (unlikely), enable L0S, so there is at least some + * power savings, even without L1. + */ + if (priv->cfg->base_params->set_l0s) { + lctl = iwl_legacy_pcie_link_ctl(priv); + if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == + PCI_CFG_LINK_CTRL_VAL_L1_EN) { + /* L1-ASPM enabled; disable(!) L0S */ + iwl_legacy_set_bit(priv, CSR_GIO_REG, + CSR_GIO_REG_VAL_L0S_ENABLED); + IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n"); + } else { + /* L1-ASPM disabled; enable(!) L0S */ + iwl_legacy_clear_bit(priv, CSR_GIO_REG, + CSR_GIO_REG_VAL_L0S_ENABLED); + IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n"); + } + } + + /* Configure analog phase-lock-loop before activating to D0A */ + if (priv->cfg->base_params->pll_cfg_val) + iwl_legacy_set_bit(priv, CSR_ANA_PLL_CFG, + priv->cfg->base_params->pll_cfg_val); + + /* + * Set "initialization complete" bit to move adapter from + * D0U* --> D0A* (powered-up active) state. + */ + iwl_legacy_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); + + /* + * Wait for clock stabilization; once stabilized, access to + * device-internal resources is supported, e.g. iwl_legacy_write_prph() + * and accesses to uCode SRAM. + */ + ret = iwl_poll_bit(priv, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, + CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); + if (ret < 0) { + IWL_DEBUG_INFO(priv, "Failed to init the card\n"); + goto out; + } + + /* + * Enable DMA and BSM (if used) clocks, wait for them to stabilize. + * BSM (Boostrap State Machine) is only in 3945 and 4965. + * + * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits + * do not disable clocks. This preserves any hardware bits already + * set by default in "CLK_CTRL_REG" after reset. + */ + if (priv->cfg->base_params->use_bsm) + iwl_legacy_write_prph(priv, APMG_CLK_EN_REG, + APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT); + else + iwl_legacy_write_prph(priv, APMG_CLK_EN_REG, + APMG_CLK_VAL_DMA_CLK_RQT); + udelay(20); + + /* Disable L1-Active */ + iwl_legacy_set_bits_prph(priv, APMG_PCIDEV_STT_REG, + APMG_PCIDEV_STT_VAL_L1_ACT_DIS); + +out: + return ret; +} +EXPORT_SYMBOL(iwl_legacy_apm_init); + + +int iwl_legacy_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) +{ + int ret; + s8 prev_tx_power; + + lockdep_assert_held(&priv->mutex); + + if (priv->tx_power_user_lmt == tx_power && !force) + return 0; + + if (!priv->cfg->ops->lib->send_tx_power) + return -EOPNOTSUPP; + + if (tx_power < IWL4965_TX_POWER_TARGET_POWER_MIN) { + IWL_WARN(priv, + "Requested user TXPOWER %d below lower limit %d.\n", + tx_power, + IWL4965_TX_POWER_TARGET_POWER_MIN); + return -EINVAL; + } + + if (tx_power > priv->tx_power_device_lmt) { + IWL_WARN(priv, + "Requested user TXPOWER %d above upper limit %d.\n", + tx_power, priv->tx_power_device_lmt); + return -EINVAL; + } + + if (!iwl_legacy_is_ready_rf(priv)) + return -EIO; + + /* scan complete use tx_power_next, need to be updated */ + priv->tx_power_next = tx_power; + if (test_bit(STATUS_SCANNING, &priv->status) && !force) { + IWL_DEBUG_INFO(priv, "Deferring tx power set while scanning\n"); + return 0; + } + + prev_tx_power = priv->tx_power_user_lmt; + priv->tx_power_user_lmt = tx_power; + + ret = priv->cfg->ops->lib->send_tx_power(priv); + + /* if fail to set tx_power, restore the orig. tx power */ + if (ret) { + priv->tx_power_user_lmt = prev_tx_power; + priv->tx_power_next = prev_tx_power; + } + return ret; +} +EXPORT_SYMBOL(iwl_legacy_set_tx_power); + +void iwl_legacy_send_bt_config(struct iwl_priv *priv) +{ + struct iwl_bt_cmd bt_cmd = { + .lead_time = BT_LEAD_TIME_DEF, + .max_kill = BT_MAX_KILL_DEF, + .kill_ack_mask = 0, + .kill_cts_mask = 0, + }; + + if (!bt_coex_active) + bt_cmd.flags = BT_COEX_DISABLE; + else + bt_cmd.flags = BT_COEX_ENABLE; + + IWL_DEBUG_INFO(priv, "BT coex %s\n", + (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active"); + + if (iwl_legacy_send_cmd_pdu(priv, REPLY_BT_CONFIG, + sizeof(struct iwl_bt_cmd), &bt_cmd)) + IWL_ERR(priv, "failed to send BT Coex Config\n"); +} +EXPORT_SYMBOL(iwl_legacy_send_bt_config); + +int iwl_legacy_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) +{ + struct iwl_statistics_cmd statistics_cmd = { + .configuration_flags = + clear ? IWL_STATS_CONF_CLEAR_STATS : 0, + }; + + if (flags & CMD_ASYNC) + return iwl_legacy_send_cmd_pdu_async(priv, REPLY_STATISTICS_CMD, + sizeof(struct iwl_statistics_cmd), + &statistics_cmd, NULL); + else + return iwl_legacy_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, + sizeof(struct iwl_statistics_cmd), + &statistics_cmd); +} +EXPORT_SYMBOL(iwl_legacy_send_statistics_request); + +void iwl_legacy_rx_pm_sleep_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif); + IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", + sleep->pm_sleep_mode, sleep->pm_wakeup_src); +#endif +} +EXPORT_SYMBOL(iwl_legacy_rx_pm_sleep_notif); + +void iwl_legacy_rx_pm_debug_statistics_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; + IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " + "notification for %s:\n", len, + iwl_legacy_get_cmd_string(pkt->hdr.cmd)); + iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len); +} +EXPORT_SYMBOL(iwl_legacy_rx_pm_debug_statistics_notif); + +void iwl_legacy_rx_reply_error(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + + IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " + "seq 0x%04X ser 0x%08X\n", + le32_to_cpu(pkt->u.err_resp.error_type), + iwl_legacy_get_cmd_string(pkt->u.err_resp.cmd_id), + pkt->u.err_resp.cmd_id, + le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num), + le32_to_cpu(pkt->u.err_resp.error_info)); +} +EXPORT_SYMBOL(iwl_legacy_rx_reply_error); + +void iwl_legacy_clear_isr_stats(struct iwl_priv *priv) +{ + memset(&priv->isr_stats, 0, sizeof(priv->isr_stats)); +} + +int iwl_legacy_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, + const struct ieee80211_tx_queue_params *params) +{ + struct iwl_priv *priv = hw->priv; + struct iwl_rxon_context *ctx; + unsigned long flags; + int q; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + if (!iwl_legacy_is_ready_rf(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); + return -EIO; + } + + if (queue >= AC_NUM) { + IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue); + return 0; + } + + q = AC_NUM - 1 - queue; + + spin_lock_irqsave(&priv->lock, flags); + + for_each_context(priv, ctx) { + ctx->qos_data.def_qos_parm.ac[q].cw_min = + cpu_to_le16(params->cw_min); + ctx->qos_data.def_qos_parm.ac[q].cw_max = + cpu_to_le16(params->cw_max); + ctx->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; + ctx->qos_data.def_qos_parm.ac[q].edca_txop = + cpu_to_le16((params->txop * 32)); + + ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0; + } + + spin_unlock_irqrestore(&priv->lock, flags); + + IWL_DEBUG_MAC80211(priv, "leave\n"); + return 0; +} +EXPORT_SYMBOL(iwl_legacy_mac_conf_tx); + +int iwl_legacy_mac_tx_last_beacon(struct ieee80211_hw *hw) +{ + struct iwl_priv *priv = hw->priv; + + return priv->ibss_manager == IWL_IBSS_MANAGER; +} +EXPORT_SYMBOL_GPL(iwl_legacy_mac_tx_last_beacon); + +static int +iwl_legacy_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +{ + iwl_legacy_connection_init_rx_config(priv, ctx); + + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + + return iwl_legacy_commit_rxon(priv, ctx); +} + +static int iwl_legacy_setup_interface(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + struct ieee80211_vif *vif = ctx->vif; + int err; + + lockdep_assert_held(&priv->mutex); + + /* + * This variable will be correct only when there's just + * a single context, but all code using it is for hardware + * that supports only one context. + */ + priv->iw_mode = vif->type; + + ctx->is_active = true; + + err = iwl_legacy_set_mode(priv, ctx); + if (err) { + if (!ctx->always_active) + ctx->is_active = false; + return err; + } + + return 0; +} + +int +iwl_legacy_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct iwl_priv *priv = hw->priv; + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; + struct iwl_rxon_context *tmp, *ctx = NULL; + int err; + + IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", + vif->type, vif->addr); + + mutex_lock(&priv->mutex); + + if (!iwl_legacy_is_ready_rf(priv)) { + IWL_WARN(priv, "Try to add interface when device not ready\n"); + err = -EINVAL; + goto out; + } + + for_each_context(priv, tmp) { + u32 possible_modes = + tmp->interface_modes | tmp->exclusive_interface_modes; + + if (tmp->vif) { + /* check if this busy context is exclusive */ + if (tmp->exclusive_interface_modes & + BIT(tmp->vif->type)) { + err = -EINVAL; + goto out; + } + continue; + } + + if (!(possible_modes & BIT(vif->type))) + continue; + + /* have maybe usable context w/o interface */ + ctx = tmp; + break; + } + + if (!ctx) { + err = -EOPNOTSUPP; + goto out; + } + + vif_priv->ctx = ctx; + ctx->vif = vif; + + err = iwl_legacy_setup_interface(priv, ctx); + if (!err) + goto out; + + ctx->vif = NULL; + priv->iw_mode = NL80211_IFTYPE_STATION; + out: + mutex_unlock(&priv->mutex); + + IWL_DEBUG_MAC80211(priv, "leave\n"); + return err; +} +EXPORT_SYMBOL(iwl_legacy_mac_add_interface); + +static void iwl_legacy_teardown_interface(struct iwl_priv *priv, + struct ieee80211_vif *vif, + bool mode_change) +{ + struct iwl_rxon_context *ctx = iwl_legacy_rxon_ctx_from_vif(vif); + + lockdep_assert_held(&priv->mutex); + + if (priv->scan_vif == vif) { + iwl_legacy_scan_cancel_timeout(priv, 200); + iwl_legacy_force_scan_end(priv); + } + + if (!mode_change) { + iwl_legacy_set_mode(priv, ctx); + if (!ctx->always_active) + ctx->is_active = false; + } +} + +void iwl_legacy_mac_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct iwl_priv *priv = hw->priv; + struct iwl_rxon_context *ctx = iwl_legacy_rxon_ctx_from_vif(vif); + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + mutex_lock(&priv->mutex); + + WARN_ON(ctx->vif != vif); + ctx->vif = NULL; + + iwl_legacy_teardown_interface(priv, vif, false); + + memset(priv->bssid, 0, ETH_ALEN); + mutex_unlock(&priv->mutex); + + IWL_DEBUG_MAC80211(priv, "leave\n"); + +} +EXPORT_SYMBOL(iwl_legacy_mac_remove_interface); + +int iwl_legacy_alloc_txq_mem(struct iwl_priv *priv) +{ + if (!priv->txq) + priv->txq = kzalloc( + sizeof(struct iwl_tx_queue) * + priv->cfg->base_params->num_of_queues, + GFP_KERNEL); + if (!priv->txq) { + IWL_ERR(priv, "Not enough memory for txq\n"); + return -ENOMEM; + } + return 0; +} +EXPORT_SYMBOL(iwl_legacy_alloc_txq_mem); + +void iwl_legacy_txq_mem(struct iwl_priv *priv) +{ + kfree(priv->txq); + priv->txq = NULL; +} +EXPORT_SYMBOL(iwl_legacy_txq_mem); + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS + +#define IWL_TRAFFIC_DUMP_SIZE (IWL_TRAFFIC_ENTRY_SIZE * IWL_TRAFFIC_ENTRIES) + +void iwl_legacy_reset_traffic_log(struct iwl_priv *priv) +{ + priv->tx_traffic_idx = 0; + priv->rx_traffic_idx = 0; + if (priv->tx_traffic) + memset(priv->tx_traffic, 0, IWL_TRAFFIC_DUMP_SIZE); + if (priv->rx_traffic) + memset(priv->rx_traffic, 0, IWL_TRAFFIC_DUMP_SIZE); +} + +int iwl_legacy_alloc_traffic_mem(struct iwl_priv *priv) +{ + u32 traffic_size = IWL_TRAFFIC_DUMP_SIZE; + + if (iwl_debug_level & IWL_DL_TX) { + if (!priv->tx_traffic) { + priv->tx_traffic = + kzalloc(traffic_size, GFP_KERNEL); + if (!priv->tx_traffic) + return -ENOMEM; + } + } + if (iwl_debug_level & IWL_DL_RX) { + if (!priv->rx_traffic) { + priv->rx_traffic = + kzalloc(traffic_size, GFP_KERNEL); + if (!priv->rx_traffic) + return -ENOMEM; + } + } + iwl_legacy_reset_traffic_log(priv); + return 0; +} +EXPORT_SYMBOL(iwl_legacy_alloc_traffic_mem); + +void iwl_legacy_free_traffic_mem(struct iwl_priv *priv) +{ + kfree(priv->tx_traffic); + priv->tx_traffic = NULL; + + kfree(priv->rx_traffic); + priv->rx_traffic = NULL; +} +EXPORT_SYMBOL(iwl_legacy_free_traffic_mem); + +void iwl_legacy_dbg_log_tx_data_frame(struct iwl_priv *priv, + u16 length, struct ieee80211_hdr *header) +{ + __le16 fc; + u16 len; + + if (likely(!(iwl_debug_level & IWL_DL_TX))) + return; + + if (!priv->tx_traffic) + return; + + fc = header->frame_control; + if (ieee80211_is_data(fc)) { + len = (length > IWL_TRAFFIC_ENTRY_SIZE) + ? IWL_TRAFFIC_ENTRY_SIZE : length; + memcpy((priv->tx_traffic + + (priv->tx_traffic_idx * IWL_TRAFFIC_ENTRY_SIZE)), + header, len); + priv->tx_traffic_idx = + (priv->tx_traffic_idx + 1) % IWL_TRAFFIC_ENTRIES; + } +} +EXPORT_SYMBOL(iwl_legacy_dbg_log_tx_data_frame); + +void iwl_legacy_dbg_log_rx_data_frame(struct iwl_priv *priv, + u16 length, struct ieee80211_hdr *header) +{ + __le16 fc; + u16 len; + + if (likely(!(iwl_debug_level & IWL_DL_RX))) + return; + + if (!priv->rx_traffic) + return; + + fc = header->frame_control; + if (ieee80211_is_data(fc)) { + len = (length > IWL_TRAFFIC_ENTRY_SIZE) + ? IWL_TRAFFIC_ENTRY_SIZE : length; + memcpy((priv->rx_traffic + + (priv->rx_traffic_idx * IWL_TRAFFIC_ENTRY_SIZE)), + header, len); + priv->rx_traffic_idx = + (priv->rx_traffic_idx + 1) % IWL_TRAFFIC_ENTRIES; + } +} +EXPORT_SYMBOL(iwl_legacy_dbg_log_rx_data_frame); + +const char *iwl_legacy_get_mgmt_string(int cmd) +{ + switch (cmd) { + IWL_CMD(MANAGEMENT_ASSOC_REQ); + IWL_CMD(MANAGEMENT_ASSOC_RESP); + IWL_CMD(MANAGEMENT_REASSOC_REQ); + IWL_CMD(MANAGEMENT_REASSOC_RESP); + IWL_CMD(MANAGEMENT_PROBE_REQ); + IWL_CMD(MANAGEMENT_PROBE_RESP); + IWL_CMD(MANAGEMENT_BEACON); + IWL_CMD(MANAGEMENT_ATIM); + IWL_CMD(MANAGEMENT_DISASSOC); + IWL_CMD(MANAGEMENT_AUTH); + IWL_CMD(MANAGEMENT_DEAUTH); + IWL_CMD(MANAGEMENT_ACTION); + default: + return "UNKNOWN"; + + } +} + +const char *iwl_legacy_get_ctrl_string(int cmd) +{ + switch (cmd) { + IWL_CMD(CONTROL_BACK_REQ); + IWL_CMD(CONTROL_BACK); + IWL_CMD(CONTROL_PSPOLL); + IWL_CMD(CONTROL_RTS); + IWL_CMD(CONTROL_CTS); + IWL_CMD(CONTROL_ACK); + IWL_CMD(CONTROL_CFEND); + IWL_CMD(CONTROL_CFENDACK); + default: + return "UNKNOWN"; + + } +} + +void iwl_legacy_clear_traffic_stats(struct iwl_priv *priv) +{ + memset(&priv->tx_stats, 0, sizeof(struct traffic_stats)); + memset(&priv->rx_stats, 0, sizeof(struct traffic_stats)); +} + +/* + * if CONFIG_IWLWIFI_LEGACY_DEBUGFS defined, + * iwl_legacy_update_stats function will + * record all the MGMT, CTRL and DATA pkt for both TX and Rx pass + * Use debugFs to display the rx/rx_statistics + * if CONFIG_IWLWIFI_LEGACY_DEBUGFS not being defined, then no MGMT and CTRL + * information will be recorded, but DATA pkt still will be recorded + * for the reason of iwl_led.c need to control the led blinking based on + * number of tx and rx data. + * + */ +void +iwl_legacy_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) +{ + struct traffic_stats *stats; + + if (is_tx) + stats = &priv->tx_stats; + else + stats = &priv->rx_stats; + + if (ieee80211_is_mgmt(fc)) { + switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { + case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ): + stats->mgmt[MANAGEMENT_ASSOC_REQ]++; + break; + case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP): + stats->mgmt[MANAGEMENT_ASSOC_RESP]++; + break; + case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ): + stats->mgmt[MANAGEMENT_REASSOC_REQ]++; + break; + case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP): + stats->mgmt[MANAGEMENT_REASSOC_RESP]++; + break; + case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ): + stats->mgmt[MANAGEMENT_PROBE_REQ]++; + break; + case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP): + stats->mgmt[MANAGEMENT_PROBE_RESP]++; + break; + case cpu_to_le16(IEEE80211_STYPE_BEACON): + stats->mgmt[MANAGEMENT_BEACON]++; + break; + case cpu_to_le16(IEEE80211_STYPE_ATIM): + stats->mgmt[MANAGEMENT_ATIM]++; + break; + case cpu_to_le16(IEEE80211_STYPE_DISASSOC): + stats->mgmt[MANAGEMENT_DISASSOC]++; + break; + case cpu_to_le16(IEEE80211_STYPE_AUTH): + stats->mgmt[MANAGEMENT_AUTH]++; + break; + case cpu_to_le16(IEEE80211_STYPE_DEAUTH): + stats->mgmt[MANAGEMENT_DEAUTH]++; + break; + case cpu_to_le16(IEEE80211_STYPE_ACTION): + stats->mgmt[MANAGEMENT_ACTION]++; + break; + } + } else if (ieee80211_is_ctl(fc)) { + switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { + case cpu_to_le16(IEEE80211_STYPE_BACK_REQ): + stats->ctrl[CONTROL_BACK_REQ]++; + break; + case cpu_to_le16(IEEE80211_STYPE_BACK): + stats->ctrl[CONTROL_BACK]++; + break; + case cpu_to_le16(IEEE80211_STYPE_PSPOLL): + stats->ctrl[CONTROL_PSPOLL]++; + break; + case cpu_to_le16(IEEE80211_STYPE_RTS): + stats->ctrl[CONTROL_RTS]++; + break; + case cpu_to_le16(IEEE80211_STYPE_CTS): + stats->ctrl[CONTROL_CTS]++; + break; + case cpu_to_le16(IEEE80211_STYPE_ACK): + stats->ctrl[CONTROL_ACK]++; + break; + case cpu_to_le16(IEEE80211_STYPE_CFEND): + stats->ctrl[CONTROL_CFEND]++; + break; + case cpu_to_le16(IEEE80211_STYPE_CFENDACK): + stats->ctrl[CONTROL_CFENDACK]++; + break; + } + } else { + /* data */ + stats->data_cnt++; + stats->data_bytes += len; + } +} +EXPORT_SYMBOL(iwl_legacy_update_stats); +#endif + +static void _iwl_legacy_force_rf_reset(struct iwl_priv *priv) +{ + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (!iwl_legacy_is_any_associated(priv)) { + IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n"); + return; + } + /* + * There is no easy and better way to force reset the radio, + * the only known method is switching channel which will force to + * reset and tune the radio. + * Use internal short scan (single channel) operation to should + * achieve this objective. + * Driver should reset the radio when number of consecutive missed + * beacon, or any other uCode error condition detected. + */ + IWL_DEBUG_INFO(priv, "perform radio reset.\n"); + iwl_legacy_internal_short_hw_scan(priv); +} + + +int iwl_legacy_force_reset(struct iwl_priv *priv, int mode, bool external) +{ + struct iwl_force_reset *force_reset; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return -EINVAL; + + if (mode >= IWL_MAX_FORCE_RESET) { + IWL_DEBUG_INFO(priv, "invalid reset request.\n"); + return -EINVAL; + } + force_reset = &priv->force_reset[mode]; + force_reset->reset_request_count++; + if (!external) { + if (force_reset->last_force_reset_jiffies && + time_after(force_reset->last_force_reset_jiffies + + force_reset->reset_duration, jiffies)) { + IWL_DEBUG_INFO(priv, "force reset rejected\n"); + force_reset->reset_reject_count++; + return -EAGAIN; + } + } + force_reset->reset_success_count++; + force_reset->last_force_reset_jiffies = jiffies; + IWL_DEBUG_INFO(priv, "perform force reset (%d)\n", mode); + switch (mode) { + case IWL_RF_RESET: + _iwl_legacy_force_rf_reset(priv); + break; + case IWL_FW_RESET: + /* + * if the request is from external(ex: debugfs), + * then always perform the request in regardless the module + * parameter setting + * if the request is from internal (uCode error or driver + * detect failure), then fw_restart module parameter + * need to be check before performing firmware reload + */ + if (!external && !priv->cfg->mod_params->restart_fw) { + IWL_DEBUG_INFO(priv, "Cancel firmware reload based on " + "module parameter setting\n"); + break; + } + IWL_ERR(priv, "On demand firmware reload\n"); + /* Set the FW error flag -- cleared on iwl_down */ + set_bit(STATUS_FW_ERROR, &priv->status); + wake_up_interruptible(&priv->wait_command_queue); + /* + * Keep the restart process from trying to send host + * commands by clearing the INIT status bit + */ + clear_bit(STATUS_READY, &priv->status); + queue_work(priv->workqueue, &priv->restart); + break; + } + return 0; +} + +int +iwl_legacy_mac_change_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum nl80211_iftype newtype, bool newp2p) +{ + struct iwl_priv *priv = hw->priv; + struct iwl_rxon_context *ctx = iwl_legacy_rxon_ctx_from_vif(vif); + struct iwl_rxon_context *tmp; + u32 interface_modes; + int err; + + newtype = ieee80211_iftype_p2p(newtype, newp2p); + + mutex_lock(&priv->mutex); + + interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes; + + if (!(interface_modes & BIT(newtype))) { + err = -EBUSY; + goto out; + } + + if (ctx->exclusive_interface_modes & BIT(newtype)) { + for_each_context(priv, tmp) { + if (ctx == tmp) + continue; + + if (!tmp->vif) + continue; + + /* + * The current mode switch would be exclusive, but + * another context is active ... refuse the switch. + */ + err = -EBUSY; + goto out; + } + } + + /* success */ + iwl_legacy_teardown_interface(priv, vif, true); + vif->type = newtype; + err = iwl_legacy_setup_interface(priv, ctx); + WARN_ON(err); + /* + * We've switched internally, but submitting to the + * device may have failed for some reason. Mask this + * error, because otherwise mac80211 will not switch + * (and set the interface type back) and we'll be + * out of sync with it. + */ + err = 0; + + out: + mutex_unlock(&priv->mutex); + return err; +} +EXPORT_SYMBOL(iwl_legacy_mac_change_interface); + +/* + * On every watchdog tick we check (latest) time stamp. If it does not + * change during timeout period and queue is not empty we reset firmware. + */ +static int iwl_legacy_check_stuck_queue(struct iwl_priv *priv, int cnt) +{ + struct iwl_tx_queue *txq = &priv->txq[cnt]; + struct iwl_queue *q = &txq->q; + unsigned long timeout; + int ret; + + if (q->read_ptr == q->write_ptr) { + txq->time_stamp = jiffies; + return 0; + } + + timeout = txq->time_stamp + + msecs_to_jiffies(priv->cfg->base_params->wd_timeout); + + if (time_after(jiffies, timeout)) { + IWL_ERR(priv, "Queue %d stuck for %u ms.\n", + q->id, priv->cfg->base_params->wd_timeout); + ret = iwl_legacy_force_reset(priv, IWL_FW_RESET, false); + return (ret == -EAGAIN) ? 0 : 1; + } + + return 0; +} + +/* + * Making watchdog tick be a quarter of timeout assure we will + * discover the queue hung between timeout and 1.25*timeout + */ +#define IWL_WD_TICK(timeout) ((timeout) / 4) + +/* + * Watchdog timer callback, we check each tx queue for stuck, if if hung + * we reset the firmware. If everything is fine just rearm the timer. + */ +void iwl_legacy_bg_watchdog(unsigned long data) +{ + struct iwl_priv *priv = (struct iwl_priv *)data; + int cnt; + unsigned long timeout; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + timeout = priv->cfg->base_params->wd_timeout; + if (timeout == 0) + return; + + /* monitor and check for stuck cmd queue */ + if (iwl_legacy_check_stuck_queue(priv, priv->cmd_queue)) + return; + + /* monitor and check for other stuck queues */ + if (iwl_legacy_is_any_associated(priv)) { + for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { + /* skip as we already checked the command queue */ + if (cnt == priv->cmd_queue) + continue; + if (iwl_legacy_check_stuck_queue(priv, cnt)) + return; + } + } + + mod_timer(&priv->watchdog, jiffies + + msecs_to_jiffies(IWL_WD_TICK(timeout))); +} +EXPORT_SYMBOL(iwl_legacy_bg_watchdog); + +void iwl_legacy_setup_watchdog(struct iwl_priv *priv) +{ + unsigned int timeout = priv->cfg->base_params->wd_timeout; + + if (timeout) + mod_timer(&priv->watchdog, + jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout))); + else + del_timer(&priv->watchdog); +} +EXPORT_SYMBOL(iwl_legacy_setup_watchdog); + +/* + * extended beacon time format + * time in usec will be changed into a 32-bit value in extended:internal format + * the extended part is the beacon counts + * the internal part is the time in usec within one beacon interval + */ +u32 +iwl_legacy_usecs_to_beacons(struct iwl_priv *priv, + u32 usec, u32 beacon_interval) +{ + u32 quot; + u32 rem; + u32 interval = beacon_interval * TIME_UNIT; + + if (!interval || !usec) + return 0; + + quot = (usec / interval) & + (iwl_legacy_beacon_time_mask_high(priv, + priv->hw_params.beacon_time_tsf_bits) >> + priv->hw_params.beacon_time_tsf_bits); + rem = (usec % interval) & iwl_legacy_beacon_time_mask_low(priv, + priv->hw_params.beacon_time_tsf_bits); + + return (quot << priv->hw_params.beacon_time_tsf_bits) + rem; +} +EXPORT_SYMBOL(iwl_legacy_usecs_to_beacons); + +/* base is usually what we get from ucode with each received frame, + * the same as HW timer counter counting down + */ +__le32 iwl_legacy_add_beacon_time(struct iwl_priv *priv, u32 base, + u32 addon, u32 beacon_interval) +{ + u32 base_low = base & iwl_legacy_beacon_time_mask_low(priv, + priv->hw_params.beacon_time_tsf_bits); + u32 addon_low = addon & iwl_legacy_beacon_time_mask_low(priv, + priv->hw_params.beacon_time_tsf_bits); + u32 interval = beacon_interval * TIME_UNIT; + u32 res = (base & iwl_legacy_beacon_time_mask_high(priv, + priv->hw_params.beacon_time_tsf_bits)) + + (addon & iwl_legacy_beacon_time_mask_high(priv, + priv->hw_params.beacon_time_tsf_bits)); + + if (base_low > addon_low) + res += base_low - addon_low; + else if (base_low < addon_low) { + res += interval + base_low - addon_low; + res += (1 << priv->hw_params.beacon_time_tsf_bits); + } else + res += (1 << priv->hw_params.beacon_time_tsf_bits); + + return cpu_to_le32(res); +} +EXPORT_SYMBOL(iwl_legacy_add_beacon_time); + +#ifdef CONFIG_PM + +int iwl_legacy_pci_suspend(struct device *device) +{ + struct pci_dev *pdev = to_pci_dev(device); + struct iwl_priv *priv = pci_get_drvdata(pdev); + + /* + * This function is called when system goes into suspend state + * mac80211 will call iwl_mac_stop() from the mac80211 suspend function + * first but since iwl_mac_stop() has no knowledge of who the caller is, + * it will not call apm_ops.stop() to stop the DMA operation. + * Calling apm_ops.stop here to make sure we stop the DMA. + */ + iwl_legacy_apm_stop(priv); + + return 0; +} +EXPORT_SYMBOL(iwl_legacy_pci_suspend); + +int iwl_legacy_pci_resume(struct device *device) +{ + struct pci_dev *pdev = to_pci_dev(device); + struct iwl_priv *priv = pci_get_drvdata(pdev); + bool hw_rfkill = false; + + /* + * We disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state. + */ + pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); + + iwl_legacy_enable_interrupts(priv); + + if (!(iwl_read32(priv, CSR_GP_CNTRL) & + CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) + hw_rfkill = true; + + if (hw_rfkill) + set_bit(STATUS_RF_KILL_HW, &priv->status); + else + clear_bit(STATUS_RF_KILL_HW, &priv->status); + + wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rfkill); + + return 0; +} +EXPORT_SYMBOL(iwl_legacy_pci_resume); + +const struct dev_pm_ops iwl_legacy_pm_ops = { + .suspend = iwl_legacy_pci_suspend, + .resume = iwl_legacy_pci_resume, + .freeze = iwl_legacy_pci_suspend, + .thaw = iwl_legacy_pci_resume, + .poweroff = iwl_legacy_pci_suspend, + .restore = iwl_legacy_pci_resume, +}; +EXPORT_SYMBOL(iwl_legacy_pm_ops); + +#endif /* CONFIG_PM */ + +static void +iwl_legacy_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +{ + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (!ctx->is_active) + return; + + ctx->qos_data.def_qos_parm.qos_flags = 0; + + if (ctx->qos_data.qos_active) + ctx->qos_data.def_qos_parm.qos_flags |= + QOS_PARAM_FLG_UPDATE_EDCA_MSK; + + if (ctx->ht.enabled) + ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; + + IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", + ctx->qos_data.qos_active, + ctx->qos_data.def_qos_parm.qos_flags); + + iwl_legacy_send_cmd_pdu_async(priv, ctx->qos_cmd, + sizeof(struct iwl_qosparam_cmd), + &ctx->qos_data.def_qos_parm, NULL); +} + +/** + * iwl_legacy_mac_config - mac80211 config callback + */ +int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed) +{ + struct iwl_priv *priv = hw->priv; + const struct iwl_channel_info *ch_info; + struct ieee80211_conf *conf = &hw->conf; + struct ieee80211_channel *channel = conf->channel; + struct iwl_ht_config *ht_conf = &priv->current_ht_config; + struct iwl_rxon_context *ctx; + unsigned long flags = 0; + int ret = 0; + u16 ch; + int scan_active = 0; + bool ht_changed[NUM_IWL_RXON_CTX] = {}; + + if (WARN_ON(!priv->cfg->ops->legacy)) + return -EOPNOTSUPP; + + mutex_lock(&priv->mutex); + + IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", + channel->hw_value, changed); + + if (unlikely(!priv->cfg->mod_params->disable_hw_scan && + test_bit(STATUS_SCANNING, &priv->status))) { + scan_active = 1; + IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); + } + + if (changed & (IEEE80211_CONF_CHANGE_SMPS | + IEEE80211_CONF_CHANGE_CHANNEL)) { + /* mac80211 uses static for non-HT which is what we want */ + priv->current_ht_config.smps = conf->smps_mode; + + /* + * Recalculate chain counts. + * + * If monitor mode is enabled then mac80211 will + * set up the SM PS mode to OFF if an HT channel is + * configured. + */ + if (priv->cfg->ops->hcmd->set_rxon_chain) + for_each_context(priv, ctx) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + } + + /* during scanning mac80211 will delay channel setting until + * scan finish with changed = 0 + */ + if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) { + if (scan_active) + goto set_ch_out; + + ch = channel->hw_value; + ch_info = iwl_legacy_get_channel_info(priv, channel->band, ch); + if (!iwl_legacy_is_channel_valid(ch_info)) { + IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); + ret = -EINVAL; + goto set_ch_out; + } + + spin_lock_irqsave(&priv->lock, flags); + + for_each_context(priv, ctx) { + /* Configure HT40 channels */ + if (ctx->ht.enabled != conf_is_ht(conf)) { + ctx->ht.enabled = conf_is_ht(conf); + ht_changed[ctx->ctxid] = true; + } + if (ctx->ht.enabled) { + if (conf_is_ht40_minus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_BELOW; + ctx->ht.is_40mhz = true; + } else if (conf_is_ht40_plus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + ctx->ht.is_40mhz = true; + } else { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_NONE; + ctx->ht.is_40mhz = false; + } + } else + ctx->ht.is_40mhz = false; + + /* + * Default to no protection. Protection mode will + * later be set from BSS config in iwl_ht_conf + */ + ctx->ht.protection = + IEEE80211_HT_OP_MODE_PROTECTION_NONE; + + /* if we are switching from ht to 2.4 clear flags + * from any ht related info since 2.4 does not + * support ht */ + if ((le16_to_cpu(ctx->staging.channel) != ch)) + ctx->staging.flags = 0; + + iwl_legacy_set_rxon_channel(priv, channel, ctx); + iwl_legacy_set_rxon_ht(priv, ht_conf); + + iwl_legacy_set_flags_for_band(priv, ctx, channel->band, + ctx->vif); + } + + spin_unlock_irqrestore(&priv->lock, flags); + + if (priv->cfg->ops->legacy->update_bcast_stations) + ret = + priv->cfg->ops->legacy->update_bcast_stations(priv); + + set_ch_out: + /* The list of supported rates and rate mask can be different + * for each band; since the band may have changed, reset + * the rate mask to what mac80211 lists */ + iwl_legacy_set_rate(priv); + } + + if (changed & (IEEE80211_CONF_CHANGE_PS | + IEEE80211_CONF_CHANGE_IDLE)) { + ret = iwl_legacy_power_update_mode(priv, false); + if (ret) + IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n"); + } + + if (changed & IEEE80211_CONF_CHANGE_POWER) { + IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n", + priv->tx_power_user_lmt, conf->power_level); + + iwl_legacy_set_tx_power(priv, conf->power_level, false); + } + + if (!iwl_legacy_is_ready(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); + goto out; + } + + if (scan_active) + goto out; + + for_each_context(priv, ctx) { + if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging))) + iwl_legacy_commit_rxon(priv, ctx); + else + IWL_DEBUG_INFO(priv, + "Not re-sending same RXON configuration.\n"); + if (ht_changed[ctx->ctxid]) + iwl_legacy_update_qos(priv, ctx); + } + +out: + IWL_DEBUG_MAC80211(priv, "leave\n"); + mutex_unlock(&priv->mutex); + return ret; +} +EXPORT_SYMBOL(iwl_legacy_mac_config); + +void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw) +{ + struct iwl_priv *priv = hw->priv; + unsigned long flags; + /* IBSS can only be the IWL_RXON_CTX_BSS context */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + if (WARN_ON(!priv->cfg->ops->legacy)) + return; + + mutex_lock(&priv->mutex); + IWL_DEBUG_MAC80211(priv, "enter\n"); + + spin_lock_irqsave(&priv->lock, flags); + memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config)); + spin_unlock_irqrestore(&priv->lock, flags); + + spin_lock_irqsave(&priv->lock, flags); + + /* new association get rid of ibss beacon skb */ + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); + + priv->beacon_skb = NULL; + + priv->timestamp = 0; + + spin_unlock_irqrestore(&priv->lock, flags); + + iwl_legacy_scan_cancel_timeout(priv, 100); + if (!iwl_legacy_is_ready_rf(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); + mutex_unlock(&priv->mutex); + return; + } + + /* we are restarting association process + * clear RXON_FILTER_ASSOC_MSK bit + */ + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwl_legacy_commit_rxon(priv, ctx); + + iwl_legacy_set_rate(priv); + + mutex_unlock(&priv->mutex); + + IWL_DEBUG_MAC80211(priv, "leave\n"); +} +EXPORT_SYMBOL(iwl_legacy_mac_reset_tsf); + +static void iwl_legacy_ht_conf(struct iwl_priv *priv, + struct ieee80211_vif *vif) +{ + struct iwl_ht_config *ht_conf = &priv->current_ht_config; + struct ieee80211_sta *sta; + struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + struct iwl_rxon_context *ctx = iwl_legacy_rxon_ctx_from_vif(vif); + + IWL_DEBUG_ASSOC(priv, "enter:\n"); + + if (!ctx->ht.enabled) + return; + + ctx->ht.protection = + bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; + ctx->ht.non_gf_sta_present = + !!(bss_conf->ht_operation_mode & + IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); + + ht_conf->single_chain_sufficient = false; + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + rcu_read_lock(); + sta = ieee80211_find_sta(vif, bss_conf->bssid); + if (sta) { + struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; + int maxstreams; + + maxstreams = (ht_cap->mcs.tx_params & + IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK) + >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; + maxstreams += 1; + + if ((ht_cap->mcs.rx_mask[1] == 0) && + (ht_cap->mcs.rx_mask[2] == 0)) + ht_conf->single_chain_sufficient = true; + if (maxstreams <= 1) + ht_conf->single_chain_sufficient = true; + } else { + /* + * If at all, this can only happen through a race + * when the AP disconnects us while we're still + * setting up the connection, in that case mac80211 + * will soon tell us about that. + */ + ht_conf->single_chain_sufficient = true; + } + rcu_read_unlock(); + break; + case NL80211_IFTYPE_ADHOC: + ht_conf->single_chain_sufficient = true; + break; + default: + break; + } + + IWL_DEBUG_ASSOC(priv, "leave\n"); +} + +static inline void iwl_legacy_set_no_assoc(struct iwl_priv *priv, + struct ieee80211_vif *vif) +{ + struct iwl_rxon_context *ctx = iwl_legacy_rxon_ctx_from_vif(vif); + + /* + * inform the ucode that there is no longer an + * association and that no more packets should be + * sent + */ + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + ctx->staging.assoc_id = 0; + iwl_legacy_commit_rxon(priv, ctx); +} + +static void iwl_legacy_beacon_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct iwl_priv *priv = hw->priv; + unsigned long flags; + __le64 timestamp; + struct sk_buff *skb = ieee80211_beacon_get(hw, vif); + + if (!skb) + return; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + lockdep_assert_held(&priv->mutex); + + if (!priv->beacon_ctx) { + IWL_ERR(priv, "update beacon but no beacon context!\n"); + dev_kfree_skb(skb); + return; + } + + spin_lock_irqsave(&priv->lock, flags); + + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); + + priv->beacon_skb = skb; + + timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; + priv->timestamp = le64_to_cpu(timestamp); + + IWL_DEBUG_MAC80211(priv, "leave\n"); + spin_unlock_irqrestore(&priv->lock, flags); + + if (!iwl_legacy_is_ready_rf(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); + return; + } + + priv->cfg->ops->legacy->post_associate(priv); +} + +void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changes) +{ + struct iwl_priv *priv = hw->priv; + struct iwl_rxon_context *ctx = iwl_legacy_rxon_ctx_from_vif(vif); + int ret; + + if (WARN_ON(!priv->cfg->ops->legacy)) + return; + + IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); + + if (!iwl_legacy_is_alive(priv)) + return; + + mutex_lock(&priv->mutex); + + if (changes & BSS_CHANGED_QOS) { + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + ctx->qos_data.qos_active = bss_conf->qos; + iwl_legacy_update_qos(priv, ctx); + spin_unlock_irqrestore(&priv->lock, flags); + } + + if (changes & BSS_CHANGED_BEACON_ENABLED) { + /* + * the add_interface code must make sure we only ever + * have a single interface that could be beaconing at + * any time. + */ + if (vif->bss_conf.enable_beacon) + priv->beacon_ctx = ctx; + else + priv->beacon_ctx = NULL; + } + + if (changes & BSS_CHANGED_BSSID) { + IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid); + + /* + * If there is currently a HW scan going on in the + * background then we need to cancel it else the RXON + * below/in post_associate will fail. + */ + if (iwl_legacy_scan_cancel_timeout(priv, 100)) { + IWL_WARN(priv, + "Aborted scan still in progress after 100ms\n"); + IWL_DEBUG_MAC80211(priv, + "leaving - scan abort failed.\n"); + mutex_unlock(&priv->mutex); + return; + } + + /* mac80211 only sets assoc when in STATION mode */ + if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) { + memcpy(ctx->staging.bssid_addr, + bss_conf->bssid, ETH_ALEN); + + /* currently needed in a few places */ + memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); + } else { + ctx->staging.filter_flags &= + ~RXON_FILTER_ASSOC_MSK; + } + + } + + /* + * This needs to be after setting the BSSID in case + * mac80211 decides to do both changes at once because + * it will invoke post_associate. + */ + if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON) + iwl_legacy_beacon_update(hw, vif); + + if (changes & BSS_CHANGED_ERP_PREAMBLE) { + IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", + bss_conf->use_short_preamble); + if (bss_conf->use_short_preamble) + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + else + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + } + + if (changes & BSS_CHANGED_ERP_CTS_PROT) { + IWL_DEBUG_MAC80211(priv, + "ERP_CTS %d\n", bss_conf->use_cts_prot); + if (bss_conf->use_cts_prot && + (priv->band != IEEE80211_BAND_5GHZ)) + ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK; + else + ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK; + if (bss_conf->use_cts_prot) + ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; + else + ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN; + } + + if (changes & BSS_CHANGED_BASIC_RATES) { + /* XXX use this information + * + * To do that, remove code from iwl_legacy_set_rate() and put something + * like this here: + * + if (A-band) + ctx->staging.ofdm_basic_rates = + bss_conf->basic_rates; + else + ctx->staging.ofdm_basic_rates = + bss_conf->basic_rates >> 4; + ctx->staging.cck_basic_rates = + bss_conf->basic_rates & 0xF; + */ + } + + if (changes & BSS_CHANGED_HT) { + iwl_legacy_ht_conf(priv, vif); + + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + } + + if (changes & BSS_CHANGED_ASSOC) { + IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc); + if (bss_conf->assoc) { + priv->timestamp = bss_conf->timestamp; + + if (!iwl_legacy_is_rfkill(priv)) + priv->cfg->ops->legacy->post_associate(priv); + } else + iwl_legacy_set_no_assoc(priv, vif); + } + + if (changes && iwl_legacy_is_associated_ctx(ctx) && bss_conf->aid) { + IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n", + changes); + ret = iwl_legacy_send_rxon_assoc(priv, ctx); + if (!ret) { + /* Sync active_rxon with latest change. */ + memcpy((void *)&ctx->active, + &ctx->staging, + sizeof(struct iwl_legacy_rxon_cmd)); + } + } + + if (changes & BSS_CHANGED_BEACON_ENABLED) { + if (vif->bss_conf.enable_beacon) { + memcpy(ctx->staging.bssid_addr, + bss_conf->bssid, ETH_ALEN); + memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); + priv->cfg->ops->legacy->config_ap(priv); + } else + iwl_legacy_set_no_assoc(priv, vif); + } + + if (changes & BSS_CHANGED_IBSS) { + ret = priv->cfg->ops->legacy->manage_ibss_station(priv, vif, + bss_conf->ibss_joined); + if (ret) + IWL_ERR(priv, "failed to %s IBSS station %pM\n", + bss_conf->ibss_joined ? "add" : "remove", + bss_conf->bssid); + } + + mutex_unlock(&priv->mutex); + + IWL_DEBUG_MAC80211(priv, "leave\n"); +} +EXPORT_SYMBOL(iwl_legacy_mac_bss_info_changed); + +irqreturn_t iwl_legacy_isr(int irq, void *data) +{ + struct iwl_priv *priv = data; + u32 inta, inta_mask; + u32 inta_fh; + unsigned long flags; + if (!priv) + return IRQ_NONE; + + spin_lock_irqsave(&priv->lock, flags); + + /* Disable (but don't clear!) interrupts here to avoid + * back-to-back ISRs and sporadic interrupts from our NIC. + * If we have something to service, the tasklet will re-enable ints. + * If we *don't* have something, we'll re-enable before leaving here. */ + inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */ + iwl_write32(priv, CSR_INT_MASK, 0x00000000); + + /* Discover which interrupts are active/pending */ + inta = iwl_read32(priv, CSR_INT); + inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); + + /* Ignore interrupt if there's nothing in NIC to service. + * This may be due to IRQ shared with another device, + * or due to sporadic interrupts thrown from our NIC. */ + if (!inta && !inta_fh) { + IWL_DEBUG_ISR(priv, + "Ignore interrupt, inta == 0, inta_fh == 0\n"); + goto none; + } + + if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { + /* Hardware disappeared. It might have already raised + * an interrupt */ + IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta); + goto unplugged; + } + + IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", + inta, inta_mask, inta_fh); + + inta &= ~CSR_INT_BIT_SCD; + + /* iwl_irq_tasklet() will service interrupts and re-enable them */ + if (likely(inta || inta_fh)) + tasklet_schedule(&priv->irq_tasklet); + +unplugged: + spin_unlock_irqrestore(&priv->lock, flags); + return IRQ_HANDLED; + +none: + /* re-enable interrupts here since we don't have anything to service. */ + /* only Re-enable if diabled by irq */ + if (test_bit(STATUS_INT_ENABLED, &priv->status)) + iwl_legacy_enable_interrupts(priv); + spin_unlock_irqrestore(&priv->lock, flags); + return IRQ_NONE; +} +EXPORT_SYMBOL(iwl_legacy_isr); + +/* + * iwl_legacy_tx_cmd_protection: Set rts/cts. 3945 and 4965 only share this + * function. + */ +void iwl_legacy_tx_cmd_protection(struct iwl_priv *priv, + struct ieee80211_tx_info *info, + __le16 fc, __le32 *tx_flags) +{ + if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { + *tx_flags |= TX_CMD_FLG_RTS_MSK; + *tx_flags &= ~TX_CMD_FLG_CTS_MSK; + *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; + + if (!ieee80211_is_mgmt(fc)) + return; + + switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { + case cpu_to_le16(IEEE80211_STYPE_AUTH): + case cpu_to_le16(IEEE80211_STYPE_DEAUTH): + case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ): + case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ): + *tx_flags &= ~TX_CMD_FLG_RTS_MSK; + *tx_flags |= TX_CMD_FLG_CTS_MSK; + break; + } + } else if (info->control.rates[0].flags & + IEEE80211_TX_RC_USE_CTS_PROTECT) { + *tx_flags &= ~TX_CMD_FLG_RTS_MSK; + *tx_flags |= TX_CMD_FLG_CTS_MSK; + *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; + } +} +EXPORT_SYMBOL(iwl_legacy_tx_cmd_protection); diff --git a/drivers/net/wireless/iwlegacy/iwl-core.h b/drivers/net/wireless/iwlegacy/iwl-core.h new file mode 100644 index 000000000000..1159b0d255b8 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-core.h @@ -0,0 +1,646 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#ifndef __iwl_legacy_core_h__ +#define __iwl_legacy_core_h__ + +/************************ + * forward declarations * + ************************/ +struct iwl_host_cmd; +struct iwl_cmd; + + +#define IWLWIFI_VERSION "in-tree:" +#define DRV_COPYRIGHT "Copyright(c) 2003-2011 Intel Corporation" +#define DRV_AUTHOR "" + +#define IWL_PCI_DEVICE(dev, subdev, cfg) \ + .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ + .subvendor = PCI_ANY_ID, .subdevice = (subdev), \ + .driver_data = (kernel_ulong_t)&(cfg) + +#define TIME_UNIT 1024 + +#define IWL_SKU_G 0x1 +#define IWL_SKU_A 0x2 +#define IWL_SKU_N 0x8 + +#define IWL_CMD(x) case x: return #x + +struct iwl_hcmd_ops { + int (*rxon_assoc)(struct iwl_priv *priv, struct iwl_rxon_context *ctx); + int (*commit_rxon)(struct iwl_priv *priv, struct iwl_rxon_context *ctx); + void (*set_rxon_chain)(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); +}; + +struct iwl_hcmd_utils_ops { + u16 (*get_hcmd_size)(u8 cmd_id, u16 len); + u16 (*build_addsta_hcmd)(const struct iwl_legacy_addsta_cmd *cmd, + u8 *data); + int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif); + void (*post_scan)(struct iwl_priv *priv); +}; + +struct iwl_apm_ops { + int (*init)(struct iwl_priv *priv); + void (*config)(struct iwl_priv *priv); +}; + +struct iwl_debugfs_ops { + ssize_t (*rx_stats_read)(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos); + ssize_t (*tx_stats_read)(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos); + ssize_t (*general_stats_read)(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos); +}; + +struct iwl_temp_ops { + void (*temperature)(struct iwl_priv *priv); +}; + +struct iwl_lib_ops { + /* set hw dependent parameters */ + int (*set_hw_params)(struct iwl_priv *priv); + /* Handling TX */ + void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv, + struct iwl_tx_queue *txq, + u16 byte_cnt); + int (*txq_attach_buf_to_tfd)(struct iwl_priv *priv, + struct iwl_tx_queue *txq, + dma_addr_t addr, + u16 len, u8 reset, u8 pad); + void (*txq_free_tfd)(struct iwl_priv *priv, + struct iwl_tx_queue *txq); + int (*txq_init)(struct iwl_priv *priv, + struct iwl_tx_queue *txq); + /* setup Rx handler */ + void (*rx_handler_setup)(struct iwl_priv *priv); + /* alive notification after init uCode load */ + void (*init_alive_start)(struct iwl_priv *priv); + /* check validity of rtc data address */ + int (*is_valid_rtc_data_addr)(u32 addr); + /* 1st ucode load */ + int (*load_ucode)(struct iwl_priv *priv); + int (*dump_nic_event_log)(struct iwl_priv *priv, + bool full_log, char **buf, bool display); + void (*dump_nic_error_log)(struct iwl_priv *priv); + int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display); + int (*set_channel_switch)(struct iwl_priv *priv, + struct ieee80211_channel_switch *ch_switch); + /* power management */ + struct iwl_apm_ops apm_ops; + + /* power */ + int (*send_tx_power) (struct iwl_priv *priv); + void (*update_chain_flags)(struct iwl_priv *priv); + + /* eeprom operations (as defined in iwl-eeprom.h) */ + struct iwl_eeprom_ops eeprom_ops; + + /* temperature */ + struct iwl_temp_ops temp_ops; + /* check for plcp health */ + bool (*check_plcp_health)(struct iwl_priv *priv, + struct iwl_rx_packet *pkt); + + struct iwl_debugfs_ops debugfs_ops; + +}; + +struct iwl_led_ops { + int (*cmd)(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd); +}; + +struct iwl_legacy_ops { + void (*post_associate)(struct iwl_priv *priv); + void (*config_ap)(struct iwl_priv *priv); + /* station management */ + int (*update_bcast_stations)(struct iwl_priv *priv); + int (*manage_ibss_station)(struct iwl_priv *priv, + struct ieee80211_vif *vif, bool add); +}; + +struct iwl_ops { + const struct iwl_lib_ops *lib; + const struct iwl_hcmd_ops *hcmd; + const struct iwl_hcmd_utils_ops *utils; + const struct iwl_led_ops *led; + const struct iwl_nic_ops *nic; + const struct iwl_legacy_ops *legacy; + const struct ieee80211_ops *ieee80211_ops; +}; + +struct iwl_mod_params { + int sw_crypto; /* def: 0 = using hardware encryption */ + int disable_hw_scan; /* def: 0 = use h/w scan */ + int num_of_queues; /* def: HW dependent */ + int disable_11n; /* def: 0 = 11n capabilities enabled */ + int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */ + int antenna; /* def: 0 = both antennas (use diversity) */ + int restart_fw; /* def: 1 = restart firmware */ +}; + +/* + * @led_compensation: compensate on the led on/off time per HW according + * to the deviation to achieve the desired led frequency. + * The detail algorithm is described in iwl-led.c + * @chain_noise_num_beacons: number of beacons used to compute chain noise + * @plcp_delta_threshold: plcp error rate threshold used to trigger + * radio tuning when there is a high receiving plcp error rate + * @wd_timeout: TX queues watchdog timeout + * @temperature_kelvin: temperature report by uCode in kelvin + * @max_event_log_size: size of event log buffer size for ucode event logging + * @ucode_tracing: support ucode continuous tracing + * @sensitivity_calib_by_driver: driver has the capability to perform + * sensitivity calibration operation + * @chain_noise_calib_by_driver: driver has the capability to perform + * chain noise calibration operation + */ +struct iwl_base_params { + int eeprom_size; + int num_of_queues; /* def: HW dependent */ + int num_of_ampdu_queues;/* def: HW dependent */ + /* for iwl_legacy_apm_init() */ + u32 pll_cfg_val; + bool set_l0s; + bool use_bsm; + + u16 led_compensation; + int chain_noise_num_beacons; + u8 plcp_delta_threshold; + unsigned int wd_timeout; + bool temperature_kelvin; + u32 max_event_log_size; + const bool ucode_tracing; + const bool sensitivity_calib_by_driver; + const bool chain_noise_calib_by_driver; +}; + +/** + * struct iwl_cfg + * @fw_name_pre: Firmware filename prefix. The api version and extension + * (.ucode) will be added to filename before loading from disk. The + * filename is constructed as fw_name_pre.ucode. + * @ucode_api_max: Highest version of uCode API supported by driver. + * @ucode_api_min: Lowest version of uCode API supported by driver. + * @scan_antennas: available antenna for scan operation + * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off) + * + * We enable the driver to be backward compatible wrt API version. The + * driver specifies which APIs it supports (with @ucode_api_max being the + * highest and @ucode_api_min the lowest). Firmware will only be loaded if + * it has a supported API version. The firmware's API version will be + * stored in @iwl_priv, enabling the driver to make runtime changes based + * on firmware version used. + * + * For example, + * if (IWL_UCODE_API(priv->ucode_ver) >= 2) { + * Driver interacts with Firmware API version >= 2. + * } else { + * Driver interacts with Firmware API version 1. + * } + * + * The ideal usage of this infrastructure is to treat a new ucode API + * release as a new hardware revision. That is, through utilizing the + * iwl_hcmd_utils_ops etc. we accommodate different command structures + * and flows between hardware versions as well as their API + * versions. + * + */ +struct iwl_cfg { + /* params specific to an individual device within a device family */ + const char *name; + const char *fw_name_pre; + const unsigned int ucode_api_max; + const unsigned int ucode_api_min; + u8 valid_tx_ant; + u8 valid_rx_ant; + unsigned int sku; + u16 eeprom_ver; + u16 eeprom_calib_ver; + const struct iwl_ops *ops; + /* module based parameters which can be set from modprobe cmd */ + const struct iwl_mod_params *mod_params; + /* params not likely to change within a device family */ + struct iwl_base_params *base_params; + /* params likely to change within a device family */ + u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; + u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; + enum iwl_led_mode led_mode; +}; + +/*************************** + * L i b * + ***************************/ + +struct ieee80211_hw *iwl_legacy_alloc_all(struct iwl_cfg *cfg); +int iwl_legacy_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, + const struct ieee80211_tx_queue_params *params); +int iwl_legacy_mac_tx_last_beacon(struct ieee80211_hw *hw); +void iwl_legacy_set_rxon_hwcrypto(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + int hw_decrypt); +int iwl_legacy_check_rxon_cmd(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); +int iwl_legacy_full_rxon_required(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); +int iwl_legacy_set_rxon_channel(struct iwl_priv *priv, + struct ieee80211_channel *ch, + struct iwl_rxon_context *ctx); +void iwl_legacy_set_flags_for_band(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + enum ieee80211_band band, + struct ieee80211_vif *vif); +u8 iwl_legacy_get_single_channel_number(struct iwl_priv *priv, + enum ieee80211_band band); +void iwl_legacy_set_rxon_ht(struct iwl_priv *priv, + struct iwl_ht_config *ht_conf); +bool iwl_legacy_is_ht40_tx_allowed(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_sta_ht_cap *ht_cap); +void iwl_legacy_connection_init_rx_config(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); +void iwl_legacy_set_rate(struct iwl_priv *priv); +int iwl_legacy_set_decrypted_flag(struct iwl_priv *priv, + struct ieee80211_hdr *hdr, + u32 decrypt_res, + struct ieee80211_rx_status *stats); +void iwl_legacy_irq_handle_error(struct iwl_priv *priv); +int iwl_legacy_mac_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +void iwl_legacy_mac_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +int iwl_legacy_mac_change_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum nl80211_iftype newtype, bool newp2p); +int iwl_legacy_alloc_txq_mem(struct iwl_priv *priv); +void iwl_legacy_txq_mem(struct iwl_priv *priv); + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS +int iwl_legacy_alloc_traffic_mem(struct iwl_priv *priv); +void iwl_legacy_free_traffic_mem(struct iwl_priv *priv); +void iwl_legacy_reset_traffic_log(struct iwl_priv *priv); +void iwl_legacy_dbg_log_tx_data_frame(struct iwl_priv *priv, + u16 length, struct ieee80211_hdr *header); +void iwl_legacy_dbg_log_rx_data_frame(struct iwl_priv *priv, + u16 length, struct ieee80211_hdr *header); +const char *iwl_legacy_get_mgmt_string(int cmd); +const char *iwl_legacy_get_ctrl_string(int cmd); +void iwl_legacy_clear_traffic_stats(struct iwl_priv *priv); +void iwl_legacy_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, + u16 len); +#else +static inline int iwl_legacy_alloc_traffic_mem(struct iwl_priv *priv) +{ + return 0; +} +static inline void iwl_legacy_free_traffic_mem(struct iwl_priv *priv) +{ +} +static inline void iwl_legacy_reset_traffic_log(struct iwl_priv *priv) +{ +} +static inline void iwl_legacy_dbg_log_tx_data_frame(struct iwl_priv *priv, + u16 length, struct ieee80211_hdr *header) +{ +} +static inline void iwl_legacy_dbg_log_rx_data_frame(struct iwl_priv *priv, + u16 length, struct ieee80211_hdr *header) +{ +} +static inline void iwl_legacy_update_stats(struct iwl_priv *priv, bool is_tx, + __le16 fc, u16 len) +{ +} +#endif +/***************************************************** + * RX handlers. + * **************************************************/ +void iwl_legacy_rx_pm_sleep_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); +void iwl_legacy_rx_pm_debug_statistics_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); +void iwl_legacy_rx_reply_error(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); + +/***************************************************** +* RX +******************************************************/ +void iwl_legacy_cmd_queue_free(struct iwl_priv *priv); +int iwl_legacy_rx_queue_alloc(struct iwl_priv *priv); +void iwl_legacy_rx_queue_update_write_ptr(struct iwl_priv *priv, + struct iwl_rx_queue *q); +int iwl_legacy_rx_queue_space(const struct iwl_rx_queue *q); +void iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); +/* Handlers */ +void iwl_legacy_rx_spectrum_measure_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); +void iwl_legacy_recover_from_statistics(struct iwl_priv *priv, + struct iwl_rx_packet *pkt); +void iwl_legacy_chswitch_done(struct iwl_priv *priv, bool is_success); +void iwl_legacy_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); + +/* TX helpers */ + +/***************************************************** +* TX +******************************************************/ +void iwl_legacy_txq_update_write_ptr(struct iwl_priv *priv, + struct iwl_tx_queue *txq); +int iwl_legacy_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, + int slots_num, u32 txq_id); +void iwl_legacy_tx_queue_reset(struct iwl_priv *priv, + struct iwl_tx_queue *txq, + int slots_num, u32 txq_id); +void iwl_legacy_tx_queue_free(struct iwl_priv *priv, int txq_id); +void iwl_legacy_setup_watchdog(struct iwl_priv *priv); +/***************************************************** + * TX power + ****************************************************/ +int iwl_legacy_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); + +/******************************************************************************* + * Rate + ******************************************************************************/ + +u8 iwl_legacy_get_lowest_plcp(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); + +/******************************************************************************* + * Scanning + ******************************************************************************/ +void iwl_legacy_init_scan_params(struct iwl_priv *priv); +int iwl_legacy_scan_cancel(struct iwl_priv *priv); +int iwl_legacy_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); +void iwl_legacy_force_scan_end(struct iwl_priv *priv); +int iwl_legacy_mac_hw_scan(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct cfg80211_scan_request *req); +void iwl_legacy_internal_short_hw_scan(struct iwl_priv *priv); +int iwl_legacy_force_reset(struct iwl_priv *priv, int mode, bool external); +u16 iwl_legacy_fill_probe_req(struct iwl_priv *priv, + struct ieee80211_mgmt *frame, + const u8 *ta, const u8 *ie, int ie_len, int left); +void iwl_legacy_setup_rx_scan_handlers(struct iwl_priv *priv); +u16 iwl_legacy_get_active_dwell_time(struct iwl_priv *priv, + enum ieee80211_band band, + u8 n_probes); +u16 iwl_legacy_get_passive_dwell_time(struct iwl_priv *priv, + enum ieee80211_band band, + struct ieee80211_vif *vif); +void iwl_legacy_setup_scan_deferred_work(struct iwl_priv *priv); +void iwl_legacy_cancel_scan_deferred_work(struct iwl_priv *priv); + +/* For faster active scanning, scan will move to the next channel if fewer than + * PLCP_QUIET_THRESH packets are heard on this channel within + * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell + * time if it's a quiet channel (nothing responded to our probe, and there's + * no other traffic). + * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */ +#define IWL_ACTIVE_QUIET_TIME cpu_to_le16(10) /* msec */ +#define IWL_PLCP_QUIET_THRESH cpu_to_le16(1) /* packets */ + +#define IWL_SCAN_CHECK_WATCHDOG (HZ * 7) + +/***************************************************** + * S e n d i n g H o s t C o m m a n d s * + *****************************************************/ + +const char *iwl_legacy_get_cmd_string(u8 cmd); +int __must_check iwl_legacy_send_cmd_sync(struct iwl_priv *priv, + struct iwl_host_cmd *cmd); +int iwl_legacy_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); +int __must_check iwl_legacy_send_cmd_pdu(struct iwl_priv *priv, u8 id, + u16 len, const void *data); +int iwl_legacy_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, + const void *data, + void (*callback)(struct iwl_priv *priv, + struct iwl_device_cmd *cmd, + struct iwl_rx_packet *pkt)); + +int iwl_legacy_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); + + +/***************************************************** + * PCI * + *****************************************************/ + +static inline u16 iwl_legacy_pcie_link_ctl(struct iwl_priv *priv) +{ + int pos; + u16 pci_lnk_ctl; + pos = pci_find_capability(priv->pci_dev, PCI_CAP_ID_EXP); + pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); + return pci_lnk_ctl; +} + +void iwl_legacy_bg_watchdog(unsigned long data); +u32 iwl_legacy_usecs_to_beacons(struct iwl_priv *priv, + u32 usec, u32 beacon_interval); +__le32 iwl_legacy_add_beacon_time(struct iwl_priv *priv, u32 base, + u32 addon, u32 beacon_interval); + +#ifdef CONFIG_PM +int iwl_legacy_pci_suspend(struct device *device); +int iwl_legacy_pci_resume(struct device *device); +extern const struct dev_pm_ops iwl_legacy_pm_ops; + +#define IWL_LEGACY_PM_OPS (&iwl_legacy_pm_ops) + +#else /* !CONFIG_PM */ + +#define IWL_LEGACY_PM_OPS NULL + +#endif /* !CONFIG_PM */ + +/***************************************************** +* Error Handling Debugging +******************************************************/ +void iwl4965_dump_nic_error_log(struct iwl_priv *priv); +int iwl4965_dump_nic_event_log(struct iwl_priv *priv, + bool full_log, char **buf, bool display); +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +void iwl_legacy_print_rx_config_cmd(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); +#else +static inline void iwl_legacy_print_rx_config_cmd(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ +} +#endif + +void iwl_legacy_clear_isr_stats(struct iwl_priv *priv); + +/***************************************************** +* GEOS +******************************************************/ +int iwl_legacy_init_geos(struct iwl_priv *priv); +void iwl_legacy_free_geos(struct iwl_priv *priv); + +/*************** DRIVER STATUS FUNCTIONS *****/ + +#define STATUS_HCMD_ACTIVE 0 /* host command in progress */ +/* 1 is unused (used to be STATUS_HCMD_SYNC_ACTIVE) */ +#define STATUS_INT_ENABLED 2 +#define STATUS_RF_KILL_HW 3 +#define STATUS_CT_KILL 4 +#define STATUS_INIT 5 +#define STATUS_ALIVE 6 +#define STATUS_READY 7 +#define STATUS_TEMPERATURE 8 +#define STATUS_GEO_CONFIGURED 9 +#define STATUS_EXIT_PENDING 10 +#define STATUS_STATISTICS 12 +#define STATUS_SCANNING 13 +#define STATUS_SCAN_ABORTING 14 +#define STATUS_SCAN_HW 15 +#define STATUS_POWER_PMI 16 +#define STATUS_FW_ERROR 17 + + +static inline int iwl_legacy_is_ready(struct iwl_priv *priv) +{ + /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are + * set but EXIT_PENDING is not */ + return test_bit(STATUS_READY, &priv->status) && + test_bit(STATUS_GEO_CONFIGURED, &priv->status) && + !test_bit(STATUS_EXIT_PENDING, &priv->status); +} + +static inline int iwl_legacy_is_alive(struct iwl_priv *priv) +{ + return test_bit(STATUS_ALIVE, &priv->status); +} + +static inline int iwl_legacy_is_init(struct iwl_priv *priv) +{ + return test_bit(STATUS_INIT, &priv->status); +} + +static inline int iwl_legacy_is_rfkill_hw(struct iwl_priv *priv) +{ + return test_bit(STATUS_RF_KILL_HW, &priv->status); +} + +static inline int iwl_legacy_is_rfkill(struct iwl_priv *priv) +{ + return iwl_legacy_is_rfkill_hw(priv); +} + +static inline int iwl_legacy_is_ctkill(struct iwl_priv *priv) +{ + return test_bit(STATUS_CT_KILL, &priv->status); +} + +static inline int iwl_legacy_is_ready_rf(struct iwl_priv *priv) +{ + + if (iwl_legacy_is_rfkill(priv)) + return 0; + + return iwl_legacy_is_ready(priv); +} + +extern void iwl_legacy_send_bt_config(struct iwl_priv *priv); +extern int iwl_legacy_send_statistics_request(struct iwl_priv *priv, + u8 flags, bool clear); +void iwl_legacy_apm_stop(struct iwl_priv *priv); +int iwl_legacy_apm_init(struct iwl_priv *priv); + +int iwl_legacy_send_rxon_timing(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); +static inline int iwl_legacy_send_rxon_assoc(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + return priv->cfg->ops->hcmd->rxon_assoc(priv, ctx); +} +static inline int iwl_legacy_commit_rxon(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + return priv->cfg->ops->hcmd->commit_rxon(priv, ctx); +} +static inline const struct ieee80211_supported_band *iwl_get_hw_mode( + struct iwl_priv *priv, enum ieee80211_band band) +{ + return priv->hw->wiphy->bands[band]; +} + +extern bool bt_coex_active; + +/* mac80211 handlers */ +int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed); +void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw); +void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changes); +void iwl_legacy_tx_cmd_protection(struct iwl_priv *priv, + struct ieee80211_tx_info *info, + __le16 fc, __le32 *tx_flags); + +irqreturn_t iwl_legacy_isr(int irq, void *data); + +#endif /* __iwl_legacy_core_h__ */ diff --git a/drivers/net/wireless/iwlegacy/iwl-csr.h b/drivers/net/wireless/iwlegacy/iwl-csr.h new file mode 100644 index 000000000000..668a9616c269 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-csr.h @@ -0,0 +1,422 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#ifndef __iwl_legacy_csr_h__ +#define __iwl_legacy_csr_h__ +/* + * CSR (control and status registers) + * + * CSR registers are mapped directly into PCI bus space, and are accessible + * whenever platform supplies power to device, even when device is in + * low power states due to driver-invoked device resets + * (e.g. CSR_RESET_REG_FLAG_SW_RESET) or uCode-driven power-saving modes. + * + * Use iwl_write32() and iwl_read32() family to access these registers; + * these provide simple PCI bus access, without waking up the MAC. + * Do not use iwl_legacy_write_direct32() family for these registers; + * no need to "grab nic access" via CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ. + * The MAC (uCode processor, etc.) does not need to be powered up for accessing + * the CSR registers. + * + * NOTE: Device does need to be awake in order to read this memory + * via CSR_EEPROM register + */ +#define CSR_BASE (0x000) + +#define CSR_HW_IF_CONFIG_REG (CSR_BASE+0x000) /* hardware interface config */ +#define CSR_INT_COALESCING (CSR_BASE+0x004) /* accum ints, 32-usec units */ +#define CSR_INT (CSR_BASE+0x008) /* host interrupt status/ack */ +#define CSR_INT_MASK (CSR_BASE+0x00c) /* host interrupt enable */ +#define CSR_FH_INT_STATUS (CSR_BASE+0x010) /* busmaster int status/ack*/ +#define CSR_GPIO_IN (CSR_BASE+0x018) /* read external chip pins */ +#define CSR_RESET (CSR_BASE+0x020) /* busmaster enable, NMI, etc*/ +#define CSR_GP_CNTRL (CSR_BASE+0x024) + +/* 2nd byte of CSR_INT_COALESCING, not accessible via iwl_write32()! */ +#define CSR_INT_PERIODIC_REG (CSR_BASE+0x005) + +/* + * Hardware revision info + * Bit fields: + * 31-8: Reserved + * 7-4: Type of device: see CSR_HW_REV_TYPE_xxx definitions + * 3-2: Revision step: 0 = A, 1 = B, 2 = C, 3 = D + * 1-0: "Dash" (-) value, as in A-1, etc. + * + * NOTE: Revision step affects calculation of CCK txpower for 4965. + * NOTE: See also CSR_HW_REV_WA_REG (work-around for bug in 4965). + */ +#define CSR_HW_REV (CSR_BASE+0x028) + +/* + * EEPROM memory reads + * + * NOTE: Device must be awake, initialized via apm_ops.init(), + * in order to read. + */ +#define CSR_EEPROM_REG (CSR_BASE+0x02c) +#define CSR_EEPROM_GP (CSR_BASE+0x030) + +#define CSR_GIO_REG (CSR_BASE+0x03C) +#define CSR_GP_UCODE_REG (CSR_BASE+0x048) +#define CSR_GP_DRIVER_REG (CSR_BASE+0x050) + +/* + * UCODE-DRIVER GP (general purpose) mailbox registers. + * SET/CLR registers set/clear bit(s) if "1" is written. + */ +#define CSR_UCODE_DRV_GP1 (CSR_BASE+0x054) +#define CSR_UCODE_DRV_GP1_SET (CSR_BASE+0x058) +#define CSR_UCODE_DRV_GP1_CLR (CSR_BASE+0x05c) +#define CSR_UCODE_DRV_GP2 (CSR_BASE+0x060) + +#define CSR_LED_REG (CSR_BASE+0x094) +#define CSR_DRAM_INT_TBL_REG (CSR_BASE+0x0A0) + +/* GIO Chicken Bits (PCI Express bus link power management) */ +#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100) + +/* Analog phase-lock-loop configuration */ +#define CSR_ANA_PLL_CFG (CSR_BASE+0x20c) + +/* + * CSR Hardware Revision Workaround Register. Indicates hardware rev; + * "step" determines CCK backoff for txpower calculation. Used for 4965 only. + * See also CSR_HW_REV register. + * Bit fields: + * 3-2: 0 = A, 1 = B, 2 = C, 3 = D step + * 1-0: "Dash" (-) value, as in C-1, etc. + */ +#define CSR_HW_REV_WA_REG (CSR_BASE+0x22C) + +#define CSR_DBG_HPET_MEM_REG (CSR_BASE+0x240) +#define CSR_DBG_LINK_PWR_MGMT_REG (CSR_BASE+0x250) + +/* Bits for CSR_HW_IF_CONFIG_REG */ +#define CSR49_HW_IF_CONFIG_REG_BIT_4965_R (0x00000010) +#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x00000C00) +#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100) +#define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200) + +#define CSR39_HW_IF_CONFIG_REG_BIT_3945_MB (0x00000100) +#define CSR39_HW_IF_CONFIG_REG_BIT_3945_MM (0x00000200) +#define CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC (0x00000400) +#define CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE (0x00000800) +#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A (0x00000000) +#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B (0x00001000) + +#define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A (0x00080000) +#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000) +#define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY (0x00400000) /* PCI_OWN_SEM */ +#define CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE (0x02000000) /* ME_OWN */ +#define CSR_HW_IF_CONFIG_REG_PREPARE (0x08000000) /* WAKE_ME */ + +#define CSR_INT_PERIODIC_DIS (0x00) /* disable periodic int*/ +#define CSR_INT_PERIODIC_ENA (0xFF) /* 255*32 usec ~ 8 msec*/ + +/* interrupt flags in INTA, set by uCode or hardware (e.g. dma), + * acknowledged (reset) by host writing "1" to flagged bits. */ +#define CSR_INT_BIT_FH_RX (1 << 31) /* Rx DMA, cmd responses, FH_INT[17:16] */ +#define CSR_INT_BIT_HW_ERR (1 << 29) /* DMA hardware error FH_INT[31] */ +#define CSR_INT_BIT_RX_PERIODIC (1 << 28) /* Rx periodic */ +#define CSR_INT_BIT_FH_TX (1 << 27) /* Tx DMA FH_INT[1:0] */ +#define CSR_INT_BIT_SCD (1 << 26) /* TXQ pointer advanced */ +#define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */ +#define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */ +#define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */ +#define CSR_INT_BIT_SW_RX (1 << 3) /* Rx, command responses, 3945 */ +#define CSR_INT_BIT_WAKEUP (1 << 1) /* NIC controller waking up (pwr mgmt) */ +#define CSR_INT_BIT_ALIVE (1 << 0) /* uCode interrupts once it initializes */ + +#define CSR_INI_SET_MASK (CSR_INT_BIT_FH_RX | \ + CSR_INT_BIT_HW_ERR | \ + CSR_INT_BIT_FH_TX | \ + CSR_INT_BIT_SW_ERR | \ + CSR_INT_BIT_RF_KILL | \ + CSR_INT_BIT_SW_RX | \ + CSR_INT_BIT_WAKEUP | \ + CSR_INT_BIT_ALIVE) + +/* interrupt flags in FH (flow handler) (PCI busmaster DMA) */ +#define CSR_FH_INT_BIT_ERR (1 << 31) /* Error */ +#define CSR_FH_INT_BIT_HI_PRIOR (1 << 30) /* High priority Rx, bypass coalescing */ +#define CSR39_FH_INT_BIT_RX_CHNL2 (1 << 18) /* Rx channel 2 (3945 only) */ +#define CSR_FH_INT_BIT_RX_CHNL1 (1 << 17) /* Rx channel 1 */ +#define CSR_FH_INT_BIT_RX_CHNL0 (1 << 16) /* Rx channel 0 */ +#define CSR39_FH_INT_BIT_TX_CHNL6 (1 << 6) /* Tx channel 6 (3945 only) */ +#define CSR_FH_INT_BIT_TX_CHNL1 (1 << 1) /* Tx channel 1 */ +#define CSR_FH_INT_BIT_TX_CHNL0 (1 << 0) /* Tx channel 0 */ + +#define CSR39_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \ + CSR39_FH_INT_BIT_RX_CHNL2 | \ + CSR_FH_INT_BIT_RX_CHNL1 | \ + CSR_FH_INT_BIT_RX_CHNL0) + + +#define CSR39_FH_INT_TX_MASK (CSR39_FH_INT_BIT_TX_CHNL6 | \ + CSR_FH_INT_BIT_TX_CHNL1 | \ + CSR_FH_INT_BIT_TX_CHNL0) + +#define CSR49_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \ + CSR_FH_INT_BIT_RX_CHNL1 | \ + CSR_FH_INT_BIT_RX_CHNL0) + +#define CSR49_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL1 | \ + CSR_FH_INT_BIT_TX_CHNL0) + +/* GPIO */ +#define CSR_GPIO_IN_BIT_AUX_POWER (0x00000200) +#define CSR_GPIO_IN_VAL_VAUX_PWR_SRC (0x00000000) +#define CSR_GPIO_IN_VAL_VMAIN_PWR_SRC (0x00000200) + +/* RESET */ +#define CSR_RESET_REG_FLAG_NEVO_RESET (0x00000001) +#define CSR_RESET_REG_FLAG_FORCE_NMI (0x00000002) +#define CSR_RESET_REG_FLAG_SW_RESET (0x00000080) +#define CSR_RESET_REG_FLAG_MASTER_DISABLED (0x00000100) +#define CSR_RESET_REG_FLAG_STOP_MASTER (0x00000200) +#define CSR_RESET_LINK_PWR_MGMT_DISABLED (0x80000000) + +/* + * GP (general purpose) CONTROL REGISTER + * Bit fields: + * 27: HW_RF_KILL_SW + * Indicates state of (platform's) hardware RF-Kill switch + * 26-24: POWER_SAVE_TYPE + * Indicates current power-saving mode: + * 000 -- No power saving + * 001 -- MAC power-down + * 010 -- PHY (radio) power-down + * 011 -- Error + * 9-6: SYS_CONFIG + * Indicates current system configuration, reflecting pins on chip + * as forced high/low by device circuit board. + * 4: GOING_TO_SLEEP + * Indicates MAC is entering a power-saving sleep power-down. + * Not a good time to access device-internal resources. + * 3: MAC_ACCESS_REQ + * Host sets this to request and maintain MAC wakeup, to allow host + * access to device-internal resources. Host must wait for + * MAC_CLOCK_READY (and !GOING_TO_SLEEP) before accessing non-CSR + * device registers. + * 2: INIT_DONE + * Host sets this to put device into fully operational D0 power mode. + * Host resets this after SW_RESET to put device into low power mode. + * 0: MAC_CLOCK_READY + * Indicates MAC (ucode processor, etc.) is powered up and can run. + * Internal resources are accessible. + * NOTE: This does not indicate that the processor is actually running. + * NOTE: This does not indicate that 4965 or 3945 has completed + * init or post-power-down restore of internal SRAM memory. + * Use CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP as indication that + * SRAM is restored and uCode is in normal operation mode. + * Later devices (5xxx/6xxx/1xxx) use non-volatile SRAM, and + * do not need to save/restore it. + * NOTE: After device reset, this bit remains "0" until host sets + * INIT_DONE + */ +#define CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY (0x00000001) +#define CSR_GP_CNTRL_REG_FLAG_INIT_DONE (0x00000004) +#define CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ (0x00000008) +#define CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP (0x00000010) + +#define CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN (0x00000001) + +#define CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE (0x07000000) +#define CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE (0x04000000) +#define CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW (0x08000000) + + +/* EEPROM REG */ +#define CSR_EEPROM_REG_READ_VALID_MSK (0x00000001) +#define CSR_EEPROM_REG_BIT_CMD (0x00000002) +#define CSR_EEPROM_REG_MSK_ADDR (0x0000FFFC) +#define CSR_EEPROM_REG_MSK_DATA (0xFFFF0000) + +/* EEPROM GP */ +#define CSR_EEPROM_GP_VALID_MSK (0x00000007) /* signature */ +#define CSR_EEPROM_GP_IF_OWNER_MSK (0x00000180) +#define CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K (0x00000002) +#define CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K (0x00000004) + +/* GP REG */ +#define CSR_GP_REG_POWER_SAVE_STATUS_MSK (0x03000000) /* bit 24/25 */ +#define CSR_GP_REG_NO_POWER_SAVE (0x00000000) +#define CSR_GP_REG_MAC_POWER_SAVE (0x01000000) +#define CSR_GP_REG_PHY_POWER_SAVE (0x02000000) +#define CSR_GP_REG_POWER_SAVE_ERROR (0x03000000) + + +/* CSR GIO */ +#define CSR_GIO_REG_VAL_L0S_ENABLED (0x00000002) + +/* + * UCODE-DRIVER GP (general purpose) mailbox register 1 + * Host driver and uCode write and/or read this register to communicate with + * each other. + * Bit fields: + * 4: UCODE_DISABLE + * Host sets this to request permanent halt of uCode, same as + * sending CARD_STATE command with "halt" bit set. + * 3: CT_KILL_EXIT + * Host sets this to request exit from CT_KILL state, i.e. host thinks + * device temperature is low enough to continue normal operation. + * 2: CMD_BLOCKED + * Host sets this during RF KILL power-down sequence (HW, SW, CT KILL) + * to release uCode to clear all Tx and command queues, enter + * unassociated mode, and power down. + * NOTE: Some devices also use HBUS_TARG_MBX_C register for this bit. + * 1: SW_BIT_RFKILL + * Host sets this when issuing CARD_STATE command to request + * device sleep. + * 0: MAC_SLEEP + * uCode sets this when preparing a power-saving power-down. + * uCode resets this when power-up is complete and SRAM is sane. + * NOTE: 3945/4965 saves internal SRAM data to host when powering down, + * and must restore this data after powering back up. + * MAC_SLEEP is the best indication that restore is complete. + * Later devices (5xxx/6xxx/1xxx) use non-volatile SRAM, and + * do not need to save/restore it. + */ +#define CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP (0x00000001) +#define CSR_UCODE_SW_BIT_RFKILL (0x00000002) +#define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED (0x00000004) +#define CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT (0x00000008) + +/* GIO Chicken Bits (PCI Express bus link power management) */ +#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000) +#define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER (0x20000000) + +/* LED */ +#define CSR_LED_BSM_CTRL_MSK (0xFFFFFFDF) +#define CSR_LED_REG_TRUN_ON (0x78) +#define CSR_LED_REG_TRUN_OFF (0x38) + +/* ANA_PLL */ +#define CSR39_ANA_PLL_CFG_VAL (0x01000000) + +/* HPET MEM debug */ +#define CSR_DBG_HPET_MEM_REG_VAL (0xFFFF0000) + +/* DRAM INT TABLE */ +#define CSR_DRAM_INT_TBL_ENABLE (1 << 31) +#define CSR_DRAM_INIT_TBL_WRAP_CHECK (1 << 27) + +/* + * HBUS (Host-side Bus) + * + * HBUS registers are mapped directly into PCI bus space, but are used + * to indirectly access device's internal memory or registers that + * may be powered-down. + * + * Use iwl_legacy_write_direct32()/iwl_legacy_read_direct32() family + * for these registers; + * host must "grab nic access" via CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ + * to make sure the MAC (uCode processor, etc.) is powered up for accessing + * internal resources. + * + * Do not use iwl_write32()/iwl_read32() family to access these registers; + * these provide only simple PCI bus access, without waking up the MAC. + */ +#define HBUS_BASE (0x400) + +/* + * Registers for accessing device's internal SRAM memory (e.g. SCD SRAM + * structures, error log, event log, verifying uCode load). + * First write to address register, then read from or write to data register + * to complete the job. Once the address register is set up, accesses to + * data registers auto-increment the address by one dword. + * Bit usage for address registers (read or write): + * 0-31: memory address within device + */ +#define HBUS_TARG_MEM_RADDR (HBUS_BASE+0x00c) +#define HBUS_TARG_MEM_WADDR (HBUS_BASE+0x010) +#define HBUS_TARG_MEM_WDAT (HBUS_BASE+0x018) +#define HBUS_TARG_MEM_RDAT (HBUS_BASE+0x01c) + +/* Mailbox C, used as workaround alternative to CSR_UCODE_DRV_GP1 mailbox */ +#define HBUS_TARG_MBX_C (HBUS_BASE+0x030) +#define HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED (0x00000004) + +/* + * Registers for accessing device's internal peripheral registers + * (e.g. SCD, BSM, etc.). First write to address register, + * then read from or write to data register to complete the job. + * Bit usage for address registers (read or write): + * 0-15: register address (offset) within device + * 24-25: (# bytes - 1) to read or write (e.g. 3 for dword) + */ +#define HBUS_TARG_PRPH_WADDR (HBUS_BASE+0x044) +#define HBUS_TARG_PRPH_RADDR (HBUS_BASE+0x048) +#define HBUS_TARG_PRPH_WDAT (HBUS_BASE+0x04c) +#define HBUS_TARG_PRPH_RDAT (HBUS_BASE+0x050) + +/* + * Per-Tx-queue write pointer (index, really!) + * Indicates index to next TFD that driver will fill (1 past latest filled). + * Bit usage: + * 0-7: queue write index + * 11-8: queue selector + */ +#define HBUS_TARG_WRPTR (HBUS_BASE+0x060) + +#endif /* !__iwl_legacy_csr_h__ */ diff --git a/drivers/net/wireless/iwlegacy/iwl-debug.h b/drivers/net/wireless/iwlegacy/iwl-debug.h new file mode 100644 index 000000000000..665789f3e75d --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-debug.h @@ -0,0 +1,198 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#ifndef __iwl_legacy_debug_h__ +#define __iwl_legacy_debug_h__ + +struct iwl_priv; +extern u32 iwl_debug_level; + +#define IWL_ERR(p, f, a...) dev_err(&((p)->pci_dev->dev), f, ## a) +#define IWL_WARN(p, f, a...) dev_warn(&((p)->pci_dev->dev), f, ## a) +#define IWL_INFO(p, f, a...) dev_info(&((p)->pci_dev->dev), f, ## a) +#define IWL_CRIT(p, f, a...) dev_crit(&((p)->pci_dev->dev), f, ## a) + +#define iwl_print_hex_error(priv, p, len) \ +do { \ + print_hex_dump(KERN_ERR, "iwl data: ", \ + DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ +} while (0) + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +#define IWL_DEBUG(__priv, level, fmt, args...) \ +do { \ + if (iwl_legacy_get_debug_level(__priv) & (level)) \ + dev_printk(KERN_ERR, &(__priv->hw->wiphy->dev), \ + "%c %s " fmt, in_interrupt() ? 'I' : 'U', \ + __func__ , ## args); \ +} while (0) + +#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...) \ +do { \ + if ((iwl_legacy_get_debug_level(__priv) & (level)) && net_ratelimit()) \ + dev_printk(KERN_ERR, &(__priv->hw->wiphy->dev), \ + "%c %s " fmt, in_interrupt() ? 'I' : 'U', \ + __func__ , ## args); \ +} while (0) + +#define iwl_print_hex_dump(priv, level, p, len) \ +do { \ + if (iwl_legacy_get_debug_level(priv) & level) \ + print_hex_dump(KERN_DEBUG, "iwl data: ", \ + DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ +} while (0) + +#else +#define IWL_DEBUG(__priv, level, fmt, args...) +#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...) +static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level, + const void *p, u32 len) +{} +#endif /* CONFIG_IWLWIFI_LEGACY_DEBUG */ + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS +int iwl_legacy_dbgfs_register(struct iwl_priv *priv, const char *name); +void iwl_legacy_dbgfs_unregister(struct iwl_priv *priv); +#else +static inline int +iwl_legacy_dbgfs_register(struct iwl_priv *priv, const char *name) +{ + return 0; +} +static inline void iwl_legacy_dbgfs_unregister(struct iwl_priv *priv) +{ +} +#endif /* CONFIG_IWLWIFI_LEGACY_DEBUGFS */ + +/* + * To use the debug system: + * + * If you are defining a new debug classification, simply add it to the #define + * list here in the form of + * + * #define IWL_DL_xxxx VALUE + * + * where xxxx should be the name of the classification (for example, WEP). + * + * You then need to either add a IWL_xxxx_DEBUG() macro definition for your + * classification, or use IWL_DEBUG(IWL_DL_xxxx, ...) whenever you want + * to send output to that classification. + * + * The active debug levels can be accessed via files + * + * /sys/module/iwl4965/parameters/debug{50} + * /sys/module/iwl3945/parameters/debug + * /sys/class/net/wlan0/device/debug_level + * + * when CONFIG_IWLWIFI_LEGACY_DEBUG=y. + */ + +/* 0x0000000F - 0x00000001 */ +#define IWL_DL_INFO (1 << 0) +#define IWL_DL_MAC80211 (1 << 1) +#define IWL_DL_HCMD (1 << 2) +#define IWL_DL_STATE (1 << 3) +/* 0x000000F0 - 0x00000010 */ +#define IWL_DL_MACDUMP (1 << 4) +#define IWL_DL_HCMD_DUMP (1 << 5) +#define IWL_DL_EEPROM (1 << 6) +#define IWL_DL_RADIO (1 << 7) +/* 0x00000F00 - 0x00000100 */ +#define IWL_DL_POWER (1 << 8) +#define IWL_DL_TEMP (1 << 9) +#define IWL_DL_NOTIF (1 << 10) +#define IWL_DL_SCAN (1 << 11) +/* 0x0000F000 - 0x00001000 */ +#define IWL_DL_ASSOC (1 << 12) +#define IWL_DL_DROP (1 << 13) +#define IWL_DL_TXPOWER (1 << 14) +#define IWL_DL_AP (1 << 15) +/* 0x000F0000 - 0x00010000 */ +#define IWL_DL_FW (1 << 16) +#define IWL_DL_RF_KILL (1 << 17) +#define IWL_DL_FW_ERRORS (1 << 18) +#define IWL_DL_LED (1 << 19) +/* 0x00F00000 - 0x00100000 */ +#define IWL_DL_RATE (1 << 20) +#define IWL_DL_CALIB (1 << 21) +#define IWL_DL_WEP (1 << 22) +#define IWL_DL_TX (1 << 23) +/* 0x0F000000 - 0x01000000 */ +#define IWL_DL_RX (1 << 24) +#define IWL_DL_ISR (1 << 25) +#define IWL_DL_HT (1 << 26) +#define IWL_DL_IO (1 << 27) +/* 0xF0000000 - 0x10000000 */ +#define IWL_DL_11H (1 << 28) +#define IWL_DL_STATS (1 << 29) +#define IWL_DL_TX_REPLY (1 << 30) +#define IWL_DL_QOS (1 << 31) + +#define IWL_DEBUG_INFO(p, f, a...) IWL_DEBUG(p, IWL_DL_INFO, f, ## a) +#define IWL_DEBUG_MAC80211(p, f, a...) IWL_DEBUG(p, IWL_DL_MAC80211, f, ## a) +#define IWL_DEBUG_MACDUMP(p, f, a...) IWL_DEBUG(p, IWL_DL_MACDUMP, f, ## a) +#define IWL_DEBUG_TEMP(p, f, a...) IWL_DEBUG(p, IWL_DL_TEMP, f, ## a) +#define IWL_DEBUG_SCAN(p, f, a...) IWL_DEBUG(p, IWL_DL_SCAN, f, ## a) +#define IWL_DEBUG_RX(p, f, a...) IWL_DEBUG(p, IWL_DL_RX, f, ## a) +#define IWL_DEBUG_TX(p, f, a...) IWL_DEBUG(p, IWL_DL_TX, f, ## a) +#define IWL_DEBUG_ISR(p, f, a...) IWL_DEBUG(p, IWL_DL_ISR, f, ## a) +#define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a) +#define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a) +#define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a) +#define IWL_DEBUG_HC_DUMP(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD_DUMP, f, ## a) +#define IWL_DEBUG_EEPROM(p, f, a...) IWL_DEBUG(p, IWL_DL_EEPROM, f, ## a) +#define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a) +#define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a) +#define IWL_DEBUG_RF_KILL(p, f, a...) IWL_DEBUG(p, IWL_DL_RF_KILL, f, ## a) +#define IWL_DEBUG_DROP(p, f, a...) IWL_DEBUG(p, IWL_DL_DROP, f, ## a) +#define IWL_DEBUG_DROP_LIMIT(p, f, a...) \ + IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a) +#define IWL_DEBUG_AP(p, f, a...) IWL_DEBUG(p, IWL_DL_AP, f, ## a) +#define IWL_DEBUG_TXPOWER(p, f, a...) IWL_DEBUG(p, IWL_DL_TXPOWER, f, ## a) +#define IWL_DEBUG_IO(p, f, a...) IWL_DEBUG(p, IWL_DL_IO, f, ## a) +#define IWL_DEBUG_RATE(p, f, a...) IWL_DEBUG(p, IWL_DL_RATE, f, ## a) +#define IWL_DEBUG_RATE_LIMIT(p, f, a...) \ + IWL_DEBUG_LIMIT(p, IWL_DL_RATE, f, ## a) +#define IWL_DEBUG_NOTIF(p, f, a...) IWL_DEBUG(p, IWL_DL_NOTIF, f, ## a) +#define IWL_DEBUG_ASSOC(p, f, a...) \ + IWL_DEBUG(p, IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) +#define IWL_DEBUG_ASSOC_LIMIT(p, f, a...) \ + IWL_DEBUG_LIMIT(p, IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) +#define IWL_DEBUG_HT(p, f, a...) IWL_DEBUG(p, IWL_DL_HT, f, ## a) +#define IWL_DEBUG_STATS(p, f, a...) IWL_DEBUG(p, IWL_DL_STATS, f, ## a) +#define IWL_DEBUG_STATS_LIMIT(p, f, a...) \ + IWL_DEBUG_LIMIT(p, IWL_DL_STATS, f, ## a) +#define IWL_DEBUG_TX_REPLY(p, f, a...) IWL_DEBUG(p, IWL_DL_TX_REPLY, f, ## a) +#define IWL_DEBUG_TX_REPLY_LIMIT(p, f, a...) \ + IWL_DEBUG_LIMIT(p, IWL_DL_TX_REPLY, f, ## a) +#define IWL_DEBUG_QOS(p, f, a...) IWL_DEBUG(p, IWL_DL_QOS, f, ## a) +#define IWL_DEBUG_RADIO(p, f, a...) IWL_DEBUG(p, IWL_DL_RADIO, f, ## a) +#define IWL_DEBUG_POWER(p, f, a...) IWL_DEBUG(p, IWL_DL_POWER, f, ## a) +#define IWL_DEBUG_11H(p, f, a...) IWL_DEBUG(p, IWL_DL_11H, f, ## a) + +#endif diff --git a/drivers/net/wireless/iwlegacy/iwl-debugfs.c b/drivers/net/wireless/iwlegacy/iwl-debugfs.c new file mode 100644 index 000000000000..6ea9c4fbcd3a --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-debugfs.c @@ -0,0 +1,1467 @@ +/****************************************************************************** + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ +#include +#include + + +#include "iwl-dev.h" +#include "iwl-debug.h" +#include "iwl-core.h" +#include "iwl-io.h" + +/* create and remove of files */ +#define DEBUGFS_ADD_FILE(name, parent, mode) do { \ + if (!debugfs_create_file(#name, mode, parent, priv, \ + &iwl_legacy_dbgfs_##name##_ops)) \ + goto err; \ +} while (0) + +#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ + struct dentry *__tmp; \ + __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \ + parent, ptr); \ + if (IS_ERR(__tmp) || !__tmp) \ + goto err; \ +} while (0) + +#define DEBUGFS_ADD_X32(name, parent, ptr) do { \ + struct dentry *__tmp; \ + __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \ + parent, ptr); \ + if (IS_ERR(__tmp) || !__tmp) \ + goto err; \ +} while (0) + +/* file operation */ +#define DEBUGFS_READ_FUNC(name) \ +static ssize_t iwl_legacy_dbgfs_##name##_read(struct file *file, \ + char __user *user_buf, \ + size_t count, loff_t *ppos); + +#define DEBUGFS_WRITE_FUNC(name) \ +static ssize_t iwl_legacy_dbgfs_##name##_write(struct file *file, \ + const char __user *user_buf, \ + size_t count, loff_t *ppos); + + +static int +iwl_legacy_dbgfs_open_file_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +#define DEBUGFS_READ_FILE_OPS(name) \ + DEBUGFS_READ_FUNC(name); \ +static const struct file_operations iwl_legacy_dbgfs_##name##_ops = { \ + .read = iwl_legacy_dbgfs_##name##_read, \ + .open = iwl_legacy_dbgfs_open_file_generic, \ + .llseek = generic_file_llseek, \ +}; + +#define DEBUGFS_WRITE_FILE_OPS(name) \ + DEBUGFS_WRITE_FUNC(name); \ +static const struct file_operations iwl_legacy_dbgfs_##name##_ops = { \ + .write = iwl_legacy_dbgfs_##name##_write, \ + .open = iwl_legacy_dbgfs_open_file_generic, \ + .llseek = generic_file_llseek, \ +}; + +#define DEBUGFS_READ_WRITE_FILE_OPS(name) \ + DEBUGFS_READ_FUNC(name); \ + DEBUGFS_WRITE_FUNC(name); \ +static const struct file_operations iwl_legacy_dbgfs_##name##_ops = { \ + .write = iwl_legacy_dbgfs_##name##_write, \ + .read = iwl_legacy_dbgfs_##name##_read, \ + .open = iwl_legacy_dbgfs_open_file_generic, \ + .llseek = generic_file_llseek, \ +}; + +static ssize_t iwl_legacy_dbgfs_tx_statistics_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + char *buf; + int pos = 0; + + int cnt; + ssize_t ret; + const size_t bufsz = 100 + + sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX); + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) + return -ENOMEM; + pos += scnprintf(buf + pos, bufsz - pos, "Management:\n"); + for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) { + pos += scnprintf(buf + pos, bufsz - pos, + "\t%25s\t\t: %u\n", + iwl_legacy_get_mgmt_string(cnt), + priv->tx_stats.mgmt[cnt]); + } + pos += scnprintf(buf + pos, bufsz - pos, "Control\n"); + for (cnt = 0; cnt < CONTROL_MAX; cnt++) { + pos += scnprintf(buf + pos, bufsz - pos, + "\t%25s\t\t: %u\n", + iwl_legacy_get_ctrl_string(cnt), + priv->tx_stats.ctrl[cnt]); + } + pos += scnprintf(buf + pos, bufsz - pos, "Data:\n"); + pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n", + priv->tx_stats.data_cnt); + pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n", + priv->tx_stats.data_bytes); + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} + +static ssize_t +iwl_legacy_dbgfs_clear_traffic_statistics_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + u32 clear_flag; + char buf[8]; + int buf_size; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%x", &clear_flag) != 1) + return -EFAULT; + iwl_legacy_clear_traffic_stats(priv); + + return count; +} + +static ssize_t iwl_legacy_dbgfs_rx_statistics_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + char *buf; + int pos = 0; + int cnt; + ssize_t ret; + const size_t bufsz = 100 + + sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX); + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + pos += scnprintf(buf + pos, bufsz - pos, "Management:\n"); + for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) { + pos += scnprintf(buf + pos, bufsz - pos, + "\t%25s\t\t: %u\n", + iwl_legacy_get_mgmt_string(cnt), + priv->rx_stats.mgmt[cnt]); + } + pos += scnprintf(buf + pos, bufsz - pos, "Control:\n"); + for (cnt = 0; cnt < CONTROL_MAX; cnt++) { + pos += scnprintf(buf + pos, bufsz - pos, + "\t%25s\t\t: %u\n", + iwl_legacy_get_ctrl_string(cnt), + priv->rx_stats.ctrl[cnt]); + } + pos += scnprintf(buf + pos, bufsz - pos, "Data:\n"); + pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n", + priv->rx_stats.data_cnt); + pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n", + priv->rx_stats.data_bytes); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} + +#define BYTE1_MASK 0x000000ff; +#define BYTE2_MASK 0x0000ffff; +#define BYTE3_MASK 0x00ffffff; +static ssize_t iwl_legacy_dbgfs_sram_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + u32 val; + char *buf; + ssize_t ret; + int i; + int pos = 0; + struct iwl_priv *priv = file->private_data; + size_t bufsz; + + /* default is to dump the entire data segment */ + if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { + priv->dbgfs_sram_offset = 0x800000; + if (priv->ucode_type == UCODE_INIT) + priv->dbgfs_sram_len = priv->ucode_init_data.len; + else + priv->dbgfs_sram_len = priv->ucode_data.len; + } + bufsz = 30 + priv->dbgfs_sram_len * sizeof(char) * 10; + buf = kmalloc(bufsz, GFP_KERNEL); + if (!buf) + return -ENOMEM; + pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", + priv->dbgfs_sram_len); + pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", + priv->dbgfs_sram_offset); + for (i = priv->dbgfs_sram_len; i > 0; i -= 4) { + val = iwl_legacy_read_targ_mem(priv, priv->dbgfs_sram_offset + \ + priv->dbgfs_sram_len - i); + if (i < 4) { + switch (i) { + case 1: + val &= BYTE1_MASK; + break; + case 2: + val &= BYTE2_MASK; + break; + case 3: + val &= BYTE3_MASK; + break; + } + } + if (!(i % 16)) + pos += scnprintf(buf + pos, bufsz - pos, "\n"); + pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val); + } + pos += scnprintf(buf + pos, bufsz - pos, "\n"); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} + +static ssize_t iwl_legacy_dbgfs_sram_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + char buf[64]; + int buf_size; + u32 offset, len; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + + if (sscanf(buf, "%x,%x", &offset, &len) == 2) { + priv->dbgfs_sram_offset = offset; + priv->dbgfs_sram_len = len; + } else { + priv->dbgfs_sram_offset = 0; + priv->dbgfs_sram_len = 0; + } + + return count; +} + +static ssize_t +iwl_legacy_dbgfs_stations_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + struct iwl_station_entry *station; + int max_sta = priv->hw_params.max_stations; + char *buf; + int i, j, pos = 0; + ssize_t ret; + /* Add 30 for initial string */ + const size_t bufsz = 30 + sizeof(char) * 500 * (priv->num_stations); + + buf = kmalloc(bufsz, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n", + priv->num_stations); + + for (i = 0; i < max_sta; i++) { + station = &priv->stations[i]; + if (!station->used) + continue; + pos += scnprintf(buf + pos, bufsz - pos, + "station %d - addr: %pM, flags: %#x\n", + i, station->sta.sta.addr, + station->sta.station_flags_msk); + pos += scnprintf(buf + pos, bufsz - pos, + "TID\tseq_num\ttxq_id\tframes\ttfds\t"); + pos += scnprintf(buf + pos, bufsz - pos, + "start_idx\tbitmap\t\t\trate_n_flags\n"); + + for (j = 0; j < MAX_TID_COUNT; j++) { + pos += scnprintf(buf + pos, bufsz - pos, + "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x", + j, station->tid[j].seq_number, + station->tid[j].agg.txq_id, + station->tid[j].agg.frame_count, + station->tid[j].tfds_in_queue, + station->tid[j].agg.start_idx, + station->tid[j].agg.bitmap, + station->tid[j].agg.rate_n_flags); + + if (station->tid[j].agg.wait_for_ba) + pos += scnprintf(buf + pos, bufsz - pos, + " - waitforba"); + pos += scnprintf(buf + pos, bufsz - pos, "\n"); + } + + pos += scnprintf(buf + pos, bufsz - pos, "\n"); + } + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} + +static ssize_t iwl_legacy_dbgfs_nvm_read(struct file *file, + char __user *user_buf, + size_t count, + loff_t *ppos) +{ + ssize_t ret; + struct iwl_priv *priv = file->private_data; + int pos = 0, ofs = 0, buf_size = 0; + const u8 *ptr; + char *buf; + u16 eeprom_ver; + size_t eeprom_len = priv->cfg->base_params->eeprom_size; + buf_size = 4 * eeprom_len + 256; + + if (eeprom_len % 16) { + IWL_ERR(priv, "NVM size is not multiple of 16.\n"); + return -ENODATA; + } + + ptr = priv->eeprom; + if (!ptr) { + IWL_ERR(priv, "Invalid EEPROM memory\n"); + return -ENOMEM; + } + + /* 4 characters for byte 0xYY */ + buf = kzalloc(buf_size, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate Buffer\n"); + return -ENOMEM; + } + eeprom_ver = iwl_legacy_eeprom_query16(priv, EEPROM_VERSION); + pos += scnprintf(buf + pos, buf_size - pos, "EEPROM " + "version: 0x%x\n", eeprom_ver); + for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { + pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); + hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos, + buf_size - pos, 0); + pos += strlen(buf + pos); + if (buf_size - pos > 0) + buf[pos++] = '\n'; + } + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} + +static ssize_t iwl_legacy_dbgfs_log_event_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + char *buf; + int pos = 0; + ssize_t ret = -ENOMEM; + + ret = pos = priv->cfg->ops->lib->dump_nic_event_log( + priv, true, &buf, true); + if (buf) { + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + } + return ret; +} + +static ssize_t iwl_legacy_dbgfs_log_event_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + u32 event_log_flag; + char buf[8]; + int buf_size; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%d", &event_log_flag) != 1) + return -EFAULT; + if (event_log_flag == 1) + priv->cfg->ops->lib->dump_nic_event_log(priv, true, + NULL, false); + + return count; +} + + + +static ssize_t +iwl_legacy_dbgfs_channels_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + struct ieee80211_channel *channels = NULL; + const struct ieee80211_supported_band *supp_band = NULL; + int pos = 0, i, bufsz = PAGE_SIZE; + char *buf; + ssize_t ret; + + if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status)) + return -EAGAIN; + + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate Buffer\n"); + return -ENOMEM; + } + + supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ); + if (supp_band) { + channels = supp_band->channels; + + pos += scnprintf(buf + pos, bufsz - pos, + "Displaying %d channels in 2.4GHz band 802.11bg):\n", + supp_band->n_channels); + + for (i = 0; i < supp_band->n_channels; i++) + pos += scnprintf(buf + pos, bufsz - pos, + "%d: %ddBm: BSS%s%s, %s.\n", + channels[i].hw_value, + channels[i].max_power, + channels[i].flags & IEEE80211_CHAN_RADAR ? + " (IEEE 802.11h required)" : "", + ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) + || (channels[i].flags & + IEEE80211_CHAN_RADAR)) ? "" : + ", IBSS", + channels[i].flags & + IEEE80211_CHAN_PASSIVE_SCAN ? + "passive only" : "active/passive"); + } + supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ); + if (supp_band) { + channels = supp_band->channels; + + pos += scnprintf(buf + pos, bufsz - pos, + "Displaying %d channels in 5.2GHz band (802.11a)\n", + supp_band->n_channels); + + for (i = 0; i < supp_band->n_channels; i++) + pos += scnprintf(buf + pos, bufsz - pos, + "%d: %ddBm: BSS%s%s, %s.\n", + channels[i].hw_value, + channels[i].max_power, + channels[i].flags & IEEE80211_CHAN_RADAR ? + " (IEEE 802.11h required)" : "", + ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) + || (channels[i].flags & + IEEE80211_CHAN_RADAR)) ? "" : + ", IBSS", + channels[i].flags & + IEEE80211_CHAN_PASSIVE_SCAN ? + "passive only" : "active/passive"); + } + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} + +static ssize_t iwl_legacy_dbgfs_status_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + char buf[512]; + int pos = 0; + const size_t bufsz = sizeof(buf); + + pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n", + test_bit(STATUS_HCMD_ACTIVE, &priv->status)); + pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n", + test_bit(STATUS_INT_ENABLED, &priv->status)); + pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", + test_bit(STATUS_RF_KILL_HW, &priv->status)); + pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n", + test_bit(STATUS_CT_KILL, &priv->status)); + pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n", + test_bit(STATUS_INIT, &priv->status)); + pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", + test_bit(STATUS_ALIVE, &priv->status)); + pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", + test_bit(STATUS_READY, &priv->status)); + pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n", + test_bit(STATUS_TEMPERATURE, &priv->status)); + pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n", + test_bit(STATUS_GEO_CONFIGURED, &priv->status)); + pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", + test_bit(STATUS_EXIT_PENDING, &priv->status)); + pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", + test_bit(STATUS_STATISTICS, &priv->status)); + pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n", + test_bit(STATUS_SCANNING, &priv->status)); + pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n", + test_bit(STATUS_SCAN_ABORTING, &priv->status)); + pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n", + test_bit(STATUS_SCAN_HW, &priv->status)); + pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n", + test_bit(STATUS_POWER_PMI, &priv->status)); + pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", + test_bit(STATUS_FW_ERROR, &priv->status)); + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + +static ssize_t iwl_legacy_dbgfs_interrupt_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + int pos = 0; + int cnt = 0; + char *buf; + int bufsz = 24 * 64; /* 24 items * 64 char per item */ + ssize_t ret; + + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate Buffer\n"); + return -ENOMEM; + } + + pos += scnprintf(buf + pos, bufsz - pos, + "Interrupt Statistics Report:\n"); + + pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n", + priv->isr_stats.hw); + pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n", + priv->isr_stats.sw); + if (priv->isr_stats.sw || priv->isr_stats.hw) { + pos += scnprintf(buf + pos, bufsz - pos, + "\tLast Restarting Code: 0x%X\n", + priv->isr_stats.err_code); + } +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n", + priv->isr_stats.sch); + pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n", + priv->isr_stats.alive); +#endif + pos += scnprintf(buf + pos, bufsz - pos, + "HW RF KILL switch toggled:\t %u\n", + priv->isr_stats.rfkill); + + pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n", + priv->isr_stats.ctkill); + + pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n", + priv->isr_stats.wakeup); + + pos += scnprintf(buf + pos, bufsz - pos, + "Rx command responses:\t\t %u\n", + priv->isr_stats.rx); + for (cnt = 0; cnt < REPLY_MAX; cnt++) { + if (priv->isr_stats.rx_handlers[cnt] > 0) + pos += scnprintf(buf + pos, bufsz - pos, + "\tRx handler[%36s]:\t\t %u\n", + iwl_legacy_get_cmd_string(cnt), + priv->isr_stats.rx_handlers[cnt]); + } + + pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n", + priv->isr_stats.tx); + + pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n", + priv->isr_stats.unhandled); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} + +static ssize_t iwl_legacy_dbgfs_interrupt_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + char buf[8]; + int buf_size; + u32 reset_flag; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%x", &reset_flag) != 1) + return -EFAULT; + if (reset_flag == 0) + iwl_legacy_clear_isr_stats(priv); + + return count; +} + +static ssize_t +iwl_legacy_dbgfs_qos_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + struct iwl_rxon_context *ctx; + int pos = 0, i; + char buf[256 * NUM_IWL_RXON_CTX]; + const size_t bufsz = sizeof(buf); + + for_each_context(priv, ctx) { + pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n", + ctx->ctxid); + for (i = 0; i < AC_NUM; i++) { + pos += scnprintf(buf + pos, bufsz - pos, + "\tcw_min\tcw_max\taifsn\ttxop\n"); + pos += scnprintf(buf + pos, bufsz - pos, + "AC[%d]\t%u\t%u\t%u\t%u\n", i, + ctx->qos_data.def_qos_parm.ac[i].cw_min, + ctx->qos_data.def_qos_parm.ac[i].cw_max, + ctx->qos_data.def_qos_parm.ac[i].aifsn, + ctx->qos_data.def_qos_parm.ac[i].edca_txop); + } + pos += scnprintf(buf + pos, bufsz - pos, "\n"); + } + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + +static ssize_t iwl_legacy_dbgfs_disable_ht40_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + char buf[8]; + int buf_size; + int ht40; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%d", &ht40) != 1) + return -EFAULT; + if (!iwl_legacy_is_any_associated(priv)) + priv->disable_ht40 = ht40 ? true : false; + else { + IWL_ERR(priv, "Sta associated with AP - " + "Change to 40MHz channel support is not allowed\n"); + return -EINVAL; + } + + return count; +} + +static ssize_t iwl_legacy_dbgfs_disable_ht40_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + char buf[100]; + int pos = 0; + const size_t bufsz = sizeof(buf); + + pos += scnprintf(buf + pos, bufsz - pos, + "11n 40MHz Mode: %s\n", + priv->disable_ht40 ? "Disabled" : "Enabled"); + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + +DEBUGFS_READ_WRITE_FILE_OPS(sram); +DEBUGFS_READ_WRITE_FILE_OPS(log_event); +DEBUGFS_READ_FILE_OPS(nvm); +DEBUGFS_READ_FILE_OPS(stations); +DEBUGFS_READ_FILE_OPS(channels); +DEBUGFS_READ_FILE_OPS(status); +DEBUGFS_READ_WRITE_FILE_OPS(interrupt); +DEBUGFS_READ_FILE_OPS(qos); +DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); + +static ssize_t iwl_legacy_dbgfs_traffic_log_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + int pos = 0, ofs = 0; + int cnt = 0, entry; + struct iwl_tx_queue *txq; + struct iwl_queue *q; + struct iwl_rx_queue *rxq = &priv->rxq; + char *buf; + int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + + (priv->cfg->base_params->num_of_queues * 32 * 8) + 400; + const u8 *ptr; + ssize_t ret; + + if (!priv->txq) { + IWL_ERR(priv, "txq not ready\n"); + return -EAGAIN; + } + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate buffer\n"); + return -ENOMEM; + } + pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n"); + for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { + txq = &priv->txq[cnt]; + q = &txq->q; + pos += scnprintf(buf + pos, bufsz - pos, + "q[%d]: read_ptr: %u, write_ptr: %u\n", + cnt, q->read_ptr, q->write_ptr); + } + if (priv->tx_traffic && (iwl_debug_level & IWL_DL_TX)) { + ptr = priv->tx_traffic; + pos += scnprintf(buf + pos, bufsz - pos, + "Tx Traffic idx: %u\n", priv->tx_traffic_idx); + for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) { + for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16; + entry++, ofs += 16) { + pos += scnprintf(buf + pos, bufsz - pos, + "0x%.4x ", ofs); + hex_dump_to_buffer(ptr + ofs, 16, 16, 2, + buf + pos, bufsz - pos, 0); + pos += strlen(buf + pos); + if (bufsz - pos > 0) + buf[pos++] = '\n'; + } + } + } + + pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n"); + pos += scnprintf(buf + pos, bufsz - pos, + "read: %u, write: %u\n", + rxq->read, rxq->write); + + if (priv->rx_traffic && (iwl_debug_level & IWL_DL_RX)) { + ptr = priv->rx_traffic; + pos += scnprintf(buf + pos, bufsz - pos, + "Rx Traffic idx: %u\n", priv->rx_traffic_idx); + for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) { + for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16; + entry++, ofs += 16) { + pos += scnprintf(buf + pos, bufsz - pos, + "0x%.4x ", ofs); + hex_dump_to_buffer(ptr + ofs, 16, 16, 2, + buf + pos, bufsz - pos, 0); + pos += strlen(buf + pos); + if (bufsz - pos > 0) + buf[pos++] = '\n'; + } + } + } + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} + +static ssize_t iwl_legacy_dbgfs_traffic_log_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + char buf[8]; + int buf_size; + int traffic_log; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%d", &traffic_log) != 1) + return -EFAULT; + if (traffic_log == 0) + iwl_legacy_reset_traffic_log(priv); + + return count; +} + +static ssize_t iwl_legacy_dbgfs_tx_queue_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + struct iwl_tx_queue *txq; + struct iwl_queue *q; + char *buf; + int pos = 0; + int cnt; + int ret; + const size_t bufsz = sizeof(char) * 64 * + priv->cfg->base_params->num_of_queues; + + if (!priv->txq) { + IWL_ERR(priv, "txq not ready\n"); + return -EAGAIN; + } + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { + txq = &priv->txq[cnt]; + q = &txq->q; + pos += scnprintf(buf + pos, bufsz - pos, + "hwq %.2d: read=%u write=%u stop=%d" + " swq_id=%#.2x (ac %d/hwq %d)\n", + cnt, q->read_ptr, q->write_ptr, + !!test_bit(cnt, priv->queue_stopped), + txq->swq_id, txq->swq_id & 3, + (txq->swq_id >> 2) & 0x1f); + if (cnt >= 4) + continue; + /* for the ACs, display the stop count too */ + pos += scnprintf(buf + pos, bufsz - pos, + " stop-count: %d\n", + atomic_read(&priv->queue_stop_count[cnt])); + } + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} + +static ssize_t iwl_legacy_dbgfs_rx_queue_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + struct iwl_rx_queue *rxq = &priv->rxq; + char buf[256]; + int pos = 0; + const size_t bufsz = sizeof(buf); + + pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n", + rxq->read); + pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n", + rxq->write); + pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n", + rxq->free_count); + if (rxq->rb_stts) { + pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n", + le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF); + } else { + pos += scnprintf(buf + pos, bufsz - pos, + "closed_rb_num: Not Allocated\n"); + } + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + +static ssize_t iwl_legacy_dbgfs_ucode_rx_stats_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file, + user_buf, count, ppos); +} + +static ssize_t iwl_legacy_dbgfs_ucode_tx_stats_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + return priv->cfg->ops->lib->debugfs_ops.tx_stats_read(file, + user_buf, count, ppos); +} + +static ssize_t iwl_legacy_dbgfs_ucode_general_stats_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + return priv->cfg->ops->lib->debugfs_ops.general_stats_read(file, + user_buf, count, ppos); +} + +static ssize_t iwl_legacy_dbgfs_sensitivity_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + int pos = 0; + int cnt = 0; + char *buf; + int bufsz = sizeof(struct iwl_sensitivity_data) * 4 + 100; + ssize_t ret; + struct iwl_sensitivity_data *data; + + data = &priv->sensitivity_data; + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate Buffer\n"); + return -ENOMEM; + } + + pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n", + data->auto_corr_ofdm); + pos += scnprintf(buf + pos, bufsz - pos, + "auto_corr_ofdm_mrc:\t\t %u\n", + data->auto_corr_ofdm_mrc); + pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n", + data->auto_corr_ofdm_x1); + pos += scnprintf(buf + pos, bufsz - pos, + "auto_corr_ofdm_mrc_x1:\t\t %u\n", + data->auto_corr_ofdm_mrc_x1); + pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n", + data->auto_corr_cck); + pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n", + data->auto_corr_cck_mrc); + pos += scnprintf(buf + pos, bufsz - pos, + "last_bad_plcp_cnt_ofdm:\t\t %u\n", + data->last_bad_plcp_cnt_ofdm); + pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n", + data->last_fa_cnt_ofdm); + pos += scnprintf(buf + pos, bufsz - pos, + "last_bad_plcp_cnt_cck:\t\t %u\n", + data->last_bad_plcp_cnt_cck); + pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n", + data->last_fa_cnt_cck); + pos += scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n", + data->nrg_curr_state); + pos += scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n", + data->nrg_prev_state); + pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t"); + for (cnt = 0; cnt < 10; cnt++) { + pos += scnprintf(buf + pos, bufsz - pos, " %u", + data->nrg_value[cnt]); + } + pos += scnprintf(buf + pos, bufsz - pos, "\n"); + pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t"); + for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) { + pos += scnprintf(buf + pos, bufsz - pos, " %u", + data->nrg_silence_rssi[cnt]); + } + pos += scnprintf(buf + pos, bufsz - pos, "\n"); + pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n", + data->nrg_silence_ref); + pos += scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n", + data->nrg_energy_idx); + pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n", + data->nrg_silence_idx); + pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n", + data->nrg_th_cck); + pos += scnprintf(buf + pos, bufsz - pos, + "nrg_auto_corr_silence_diff:\t %u\n", + data->nrg_auto_corr_silence_diff); + pos += scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n", + data->num_in_cck_no_fa); + pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n", + data->nrg_th_ofdm); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} + + +static ssize_t iwl_legacy_dbgfs_chain_noise_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + int pos = 0; + int cnt = 0; + char *buf; + int bufsz = sizeof(struct iwl_chain_noise_data) * 4 + 100; + ssize_t ret; + struct iwl_chain_noise_data *data; + + data = &priv->chain_noise_data; + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate Buffer\n"); + return -ENOMEM; + } + + pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n", + data->active_chains); + pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n", + data->chain_noise_a); + pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n", + data->chain_noise_b); + pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n", + data->chain_noise_c); + pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n", + data->chain_signal_a); + pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n", + data->chain_signal_b); + pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n", + data->chain_signal_c); + pos += scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n", + data->beacon_count); + + pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t"); + for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) { + pos += scnprintf(buf + pos, bufsz - pos, " %u", + data->disconn_array[cnt]); + } + pos += scnprintf(buf + pos, bufsz - pos, "\n"); + pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t"); + for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) { + pos += scnprintf(buf + pos, bufsz - pos, " %u", + data->delta_gain_code[cnt]); + } + pos += scnprintf(buf + pos, bufsz - pos, "\n"); + pos += scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n", + data->radio_write); + pos += scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n", + data->state); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} + +static ssize_t iwl_legacy_dbgfs_power_save_status_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + char buf[60]; + int pos = 0; + const size_t bufsz = sizeof(buf); + u32 pwrsave_status; + + pwrsave_status = iwl_read32(priv, CSR_GP_CNTRL) & + CSR_GP_REG_POWER_SAVE_STATUS_MSK; + + pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: "); + pos += scnprintf(buf + pos, bufsz - pos, "%s\n", + (pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" : + (pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" : + (pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" : + "error"); + + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + +static ssize_t iwl_legacy_dbgfs_clear_ucode_statistics_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + char buf[8]; + int buf_size; + int clear; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%d", &clear) != 1) + return -EFAULT; + + /* make request to uCode to retrieve statistics information */ + mutex_lock(&priv->mutex); + iwl_legacy_send_statistics_request(priv, CMD_SYNC, true); + mutex_unlock(&priv->mutex); + + return count; +} + +static ssize_t iwl_legacy_dbgfs_ucode_tracing_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + int pos = 0; + char buf[128]; + const size_t bufsz = sizeof(buf); + + pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n", + priv->event_log.ucode_trace ? "On" : "Off"); + pos += scnprintf(buf + pos, bufsz - pos, "non_wraps_count:\t\t %u\n", + priv->event_log.non_wraps_count); + pos += scnprintf(buf + pos, bufsz - pos, "wraps_once_count:\t\t %u\n", + priv->event_log.wraps_once_count); + pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n", + priv->event_log.wraps_more_count); + + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + +static ssize_t iwl_legacy_dbgfs_ucode_tracing_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + char buf[8]; + int buf_size; + int trace; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%d", &trace) != 1) + return -EFAULT; + + if (trace) { + priv->event_log.ucode_trace = true; + /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */ + mod_timer(&priv->ucode_trace, + jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD)); + } else { + priv->event_log.ucode_trace = false; + del_timer_sync(&priv->ucode_trace); + } + + return count; +} + +static ssize_t iwl_legacy_dbgfs_rxon_flags_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + int len = 0; + char buf[20]; + + len = sprintf(buf, "0x%04X\n", + le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.flags)); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static ssize_t iwl_legacy_dbgfs_rxon_filter_flags_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + int len = 0; + char buf[20]; + + len = sprintf(buf, "0x%04X\n", + le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags)); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static ssize_t iwl_legacy_dbgfs_fh_reg_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + char *buf; + int pos = 0; + ssize_t ret = -EFAULT; + + if (priv->cfg->ops->lib->dump_fh) { + ret = pos = priv->cfg->ops->lib->dump_fh(priv, &buf, true); + if (buf) { + ret = simple_read_from_buffer(user_buf, + count, ppos, buf, pos); + kfree(buf); + } + } + + return ret; +} + +static ssize_t iwl_legacy_dbgfs_missed_beacon_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + int pos = 0; + char buf[12]; + const size_t bufsz = sizeof(buf); + + pos += scnprintf(buf + pos, bufsz - pos, "%d\n", + priv->missed_beacon_threshold); + + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + +static ssize_t iwl_legacy_dbgfs_missed_beacon_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + char buf[8]; + int buf_size; + int missed; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%d", &missed) != 1) + return -EINVAL; + + if (missed < IWL_MISSED_BEACON_THRESHOLD_MIN || + missed > IWL_MISSED_BEACON_THRESHOLD_MAX) + priv->missed_beacon_threshold = + IWL_MISSED_BEACON_THRESHOLD_DEF; + else + priv->missed_beacon_threshold = missed; + + return count; +} + +static ssize_t iwl_legacy_dbgfs_plcp_delta_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + int pos = 0; + char buf[12]; + const size_t bufsz = sizeof(buf); + + pos += scnprintf(buf + pos, bufsz - pos, "%u\n", + priv->cfg->base_params->plcp_delta_threshold); + + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + +static ssize_t iwl_legacy_dbgfs_plcp_delta_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + char buf[8]; + int buf_size; + int plcp; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%d", &plcp) != 1) + return -EINVAL; + if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || + (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) + priv->cfg->base_params->plcp_delta_threshold = + IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; + else + priv->cfg->base_params->plcp_delta_threshold = plcp; + return count; +} + +static ssize_t iwl_legacy_dbgfs_force_reset_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + int i, pos = 0; + char buf[300]; + const size_t bufsz = sizeof(buf); + struct iwl_force_reset *force_reset; + + for (i = 0; i < IWL_MAX_FORCE_RESET; i++) { + force_reset = &priv->force_reset[i]; + pos += scnprintf(buf + pos, bufsz - pos, + "Force reset method %d\n", i); + pos += scnprintf(buf + pos, bufsz - pos, + "\tnumber of reset request: %d\n", + force_reset->reset_request_count); + pos += scnprintf(buf + pos, bufsz - pos, + "\tnumber of reset request success: %d\n", + force_reset->reset_success_count); + pos += scnprintf(buf + pos, bufsz - pos, + "\tnumber of reset request reject: %d\n", + force_reset->reset_reject_count); + pos += scnprintf(buf + pos, bufsz - pos, + "\treset duration: %lu\n", + force_reset->reset_duration); + } + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + +static ssize_t iwl_legacy_dbgfs_force_reset_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + char buf[8]; + int buf_size; + int reset, ret; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%d", &reset) != 1) + return -EINVAL; + switch (reset) { + case IWL_RF_RESET: + case IWL_FW_RESET: + ret = iwl_legacy_force_reset(priv, reset, true); + break; + default: + return -EINVAL; + } + return ret ? ret : count; +} + +static ssize_t iwl_legacy_dbgfs_wd_timeout_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + char buf[8]; + int buf_size; + int timeout; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%d", &timeout) != 1) + return -EINVAL; + if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT) + timeout = IWL_DEF_WD_TIMEOUT; + + priv->cfg->base_params->wd_timeout = timeout; + iwl_legacy_setup_watchdog(priv); + return count; +} + +DEBUGFS_READ_FILE_OPS(rx_statistics); +DEBUGFS_READ_FILE_OPS(tx_statistics); +DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); +DEBUGFS_READ_FILE_OPS(rx_queue); +DEBUGFS_READ_FILE_OPS(tx_queue); +DEBUGFS_READ_FILE_OPS(ucode_rx_stats); +DEBUGFS_READ_FILE_OPS(ucode_tx_stats); +DEBUGFS_READ_FILE_OPS(ucode_general_stats); +DEBUGFS_READ_FILE_OPS(sensitivity); +DEBUGFS_READ_FILE_OPS(chain_noise); +DEBUGFS_READ_FILE_OPS(power_save_status); +DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics); +DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); +DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); +DEBUGFS_READ_FILE_OPS(fh_reg); +DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); +DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); +DEBUGFS_READ_WRITE_FILE_OPS(force_reset); +DEBUGFS_READ_FILE_OPS(rxon_flags); +DEBUGFS_READ_FILE_OPS(rxon_filter_flags); +DEBUGFS_WRITE_FILE_OPS(wd_timeout); + +/* + * Create the debugfs files and directories + * + */ +int iwl_legacy_dbgfs_register(struct iwl_priv *priv, const char *name) +{ + struct dentry *phyd = priv->hw->wiphy->debugfsdir; + struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug; + + dir_drv = debugfs_create_dir(name, phyd); + if (!dir_drv) + return -ENOMEM; + + priv->debugfs_dir = dir_drv; + + dir_data = debugfs_create_dir("data", dir_drv); + if (!dir_data) + goto err; + dir_rf = debugfs_create_dir("rf", dir_drv); + if (!dir_rf) + goto err; + dir_debug = debugfs_create_dir("debug", dir_drv); + if (!dir_debug) + goto err; + + DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR); + DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR); + DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR); + DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); + DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); + DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR); + DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR); + DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); + DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); + + if (priv->cfg->base_params->sensitivity_calib_by_driver) + DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); + if (priv->cfg->base_params->chain_noise_calib_by_driver) + DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); + if (priv->cfg->base_params->ucode_tracing) + DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); + DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); + DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR); + if (priv->cfg->base_params->sensitivity_calib_by_driver) + DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, + &priv->disable_sens_cal); + if (priv->cfg->base_params->chain_noise_calib_by_driver) + DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, + &priv->disable_chain_noise_cal); + DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, + &priv->disable_tx_power_cal); + return 0; + +err: + IWL_ERR(priv, "Can't create the debugfs directory\n"); + iwl_legacy_dbgfs_unregister(priv); + return -ENOMEM; +} +EXPORT_SYMBOL(iwl_legacy_dbgfs_register); + +/** + * Remove the debugfs files and directories + * + */ +void iwl_legacy_dbgfs_unregister(struct iwl_priv *priv) +{ + if (!priv->debugfs_dir) + return; + + debugfs_remove_recursive(priv->debugfs_dir); + priv->debugfs_dir = NULL; +} +EXPORT_SYMBOL(iwl_legacy_dbgfs_unregister); diff --git a/drivers/net/wireless/iwlegacy/iwl-dev.h b/drivers/net/wireless/iwlegacy/iwl-dev.h new file mode 100644 index 000000000000..25718cf9919a --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-dev.h @@ -0,0 +1,1426 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ +/* + * Please use this file (iwl-dev.h) for driver implementation definitions. + * Please use iwl-commands.h for uCode API definitions. + * Please use iwl-4965-hw.h for hardware-related definitions. + */ + +#ifndef __iwl_legacy_dev_h__ +#define __iwl_legacy_dev_h__ + +#include /* for struct pci_device_id */ +#include +#include +#include +#include + +#include "iwl-eeprom.h" +#include "iwl-csr.h" +#include "iwl-prph.h" +#include "iwl-fh.h" +#include "iwl-debug.h" +#include "iwl-4965-hw.h" +#include "iwl-3945-hw.h" +#include "iwl-led.h" +#include "iwl-power.h" +#include "iwl-legacy-rs.h" + +struct iwl_tx_queue; + +/* CT-KILL constants */ +#define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ + +/* Default noise level to report when noise measurement is not available. + * This may be because we're: + * 1) Not associated (4965, no beacon statistics being sent to driver) + * 2) Scanning (noise measurement does not apply to associated channel) + * 3) Receiving CCK (3945 delivers noise info only for OFDM frames) + * Use default noise value of -127 ... this is below the range of measurable + * Rx dBm for either 3945 or 4965, so it can indicate "unmeasurable" to user. + * Also, -127 works better than 0 when averaging frames with/without + * noise info (e.g. averaging might be done in app); measured dBm values are + * always negative ... using a negative value as the default keeps all + * averages within an s8's (used in some apps) range of negative values. */ +#define IWL_NOISE_MEAS_NOT_AVAILABLE (-127) + +/* + * RTS threshold here is total size [2347] minus 4 FCS bytes + * Per spec: + * a value of 0 means RTS on all data/management packets + * a value > max MSDU size means no RTS + * else RTS for data/management frames where MPDU is larger + * than RTS value. + */ +#define DEFAULT_RTS_THRESHOLD 2347U +#define MIN_RTS_THRESHOLD 0U +#define MAX_RTS_THRESHOLD 2347U +#define MAX_MSDU_SIZE 2304U +#define MAX_MPDU_SIZE 2346U +#define DEFAULT_BEACON_INTERVAL 100U +#define DEFAULT_SHORT_RETRY_LIMIT 7U +#define DEFAULT_LONG_RETRY_LIMIT 4U + +struct iwl_rx_mem_buffer { + dma_addr_t page_dma; + struct page *page; + struct list_head list; +}; + +#define rxb_addr(r) page_address(r->page) + +/* defined below */ +struct iwl_device_cmd; + +struct iwl_cmd_meta { + /* only for SYNC commands, iff the reply skb is wanted */ + struct iwl_host_cmd *source; + /* + * only for ASYNC commands + * (which is somewhat stupid -- look at iwl-sta.c for instance + * which duplicates a bunch of code because the callback isn't + * invoked for SYNC commands, if it were and its result passed + * through it would be simpler...) + */ + void (*callback)(struct iwl_priv *priv, + struct iwl_device_cmd *cmd, + struct iwl_rx_packet *pkt); + + /* The CMD_SIZE_HUGE flag bit indicates that the command + * structure is stored at the end of the shared queue memory. */ + u32 flags; + + DEFINE_DMA_UNMAP_ADDR(mapping); + DEFINE_DMA_UNMAP_LEN(len); +}; + +/* + * Generic queue structure + * + * Contains common data for Rx and Tx queues + */ +struct iwl_queue { + int n_bd; /* number of BDs in this queue */ + int write_ptr; /* 1-st empty entry (index) host_w*/ + int read_ptr; /* last used entry (index) host_r*/ + /* use for monitoring and recovering the stuck queue */ + dma_addr_t dma_addr; /* physical addr for BD's */ + int n_window; /* safe queue window */ + u32 id; + int low_mark; /* low watermark, resume queue if free + * space more than this */ + int high_mark; /* high watermark, stop queue if free + * space less than this */ +} __packed; + +/* One for each TFD */ +struct iwl_tx_info { + struct sk_buff *skb; + struct iwl_rxon_context *ctx; +}; + +/** + * struct iwl_tx_queue - Tx Queue for DMA + * @q: generic Rx/Tx queue descriptor + * @bd: base of circular buffer of TFDs + * @cmd: array of command/TX buffer pointers + * @meta: array of meta data for each command/tx buffer + * @dma_addr_cmd: physical address of cmd/tx buffer array + * @txb: array of per-TFD driver data + * @time_stamp: time (in jiffies) of last read_ptr change + * @need_update: indicates need to update read/write index + * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled + * + * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame + * descriptors) and required locking structures. + */ +#define TFD_TX_CMD_SLOTS 256 +#define TFD_CMD_SLOTS 32 + +struct iwl_tx_queue { + struct iwl_queue q; + void *tfds; + struct iwl_device_cmd **cmd; + struct iwl_cmd_meta *meta; + struct iwl_tx_info *txb; + unsigned long time_stamp; + u8 need_update; + u8 sched_retry; + u8 active; + u8 swq_id; +}; + +#define IWL_NUM_SCAN_RATES (2) + +struct iwl4965_channel_tgd_info { + u8 type; + s8 max_power; +}; + +struct iwl4965_channel_tgh_info { + s64 last_radar_time; +}; + +#define IWL4965_MAX_RATE (33) + +struct iwl3945_clip_group { + /* maximum power level to prevent clipping for each rate, derived by + * us from this band's saturation power in EEPROM */ + const s8 clip_powers[IWL_MAX_RATES]; +}; + +/* current Tx power values to use, one for each rate for each channel. + * requested power is limited by: + * -- regulatory EEPROM limits for this channel + * -- hardware capabilities (clip-powers) + * -- spectrum management + * -- user preference (e.g. iwconfig) + * when requested power is set, base power index must also be set. */ +struct iwl3945_channel_power_info { + struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */ + s8 power_table_index; /* actual (compenst'd) index into gain table */ + s8 base_power_index; /* gain index for power at factory temp. */ + s8 requested_power; /* power (dBm) requested for this chnl/rate */ +}; + +/* current scan Tx power values to use, one for each scan rate for each + * channel. */ +struct iwl3945_scan_power_info { + struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */ + s8 power_table_index; /* actual (compenst'd) index into gain table */ + s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */ +}; + +/* + * One for each channel, holds all channel setup data + * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant + * with one another! + */ +struct iwl_channel_info { + struct iwl4965_channel_tgd_info tgd; + struct iwl4965_channel_tgh_info tgh; + struct iwl_eeprom_channel eeprom; /* EEPROM regulatory limit */ + struct iwl_eeprom_channel ht40_eeprom; /* EEPROM regulatory limit for + * HT40 channel */ + + u8 channel; /* channel number */ + u8 flags; /* flags copied from EEPROM */ + s8 max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ + s8 curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) limit */ + s8 min_power; /* always 0 */ + s8 scan_power; /* (dBm) regul. eeprom, direct scans, any rate */ + + u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */ + u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ + enum ieee80211_band band; + + /* HT40 channel info */ + s8 ht40_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ + u8 ht40_flags; /* flags copied from EEPROM */ + u8 ht40_extension_channel; /* HT_IE_EXT_CHANNEL_* */ + + /* Radio/DSP gain settings for each "normal" data Tx rate. + * These include, in addition to RF and DSP gain, a few fields for + * remembering/modifying gain settings (indexes). */ + struct iwl3945_channel_power_info power_info[IWL4965_MAX_RATE]; + + /* Radio/DSP gain settings for each scan rate, for directed scans. */ + struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES]; +}; + +#define IWL_TX_FIFO_BK 0 /* shared */ +#define IWL_TX_FIFO_BE 1 +#define IWL_TX_FIFO_VI 2 /* shared */ +#define IWL_TX_FIFO_VO 3 +#define IWL_TX_FIFO_UNUSED -1 + +/* Minimum number of queues. MAX_NUM is defined in hw specific files. + * Set the minimum to accommodate the 4 standard TX queues, 1 command + * queue, 2 (unused) HCCA queues, and 4 HT queues (one for each AC) */ +#define IWL_MIN_NUM_QUEUES 10 + +#define IWL_DEFAULT_CMD_QUEUE_NUM 4 + +#define IEEE80211_DATA_LEN 2304 +#define IEEE80211_4ADDR_LEN 30 +#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) +#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) + +struct iwl_frame { + union { + struct ieee80211_hdr frame; + struct iwl_tx_beacon_cmd beacon; + u8 raw[IEEE80211_FRAME_LEN]; + u8 cmd[360]; + } u; + struct list_head list; +}; + +#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) +#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) +#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) + +enum { + CMD_SYNC = 0, + CMD_SIZE_NORMAL = 0, + CMD_NO_SKB = 0, + CMD_SIZE_HUGE = (1 << 0), + CMD_ASYNC = (1 << 1), + CMD_WANT_SKB = (1 << 2), +}; + +#define DEF_CMD_PAYLOAD_SIZE 320 + +/** + * struct iwl_device_cmd + * + * For allocation of the command and tx queues, this establishes the overall + * size of the largest command we send to uCode, except for a scan command + * (which is relatively huge; space is allocated separately). + */ +struct iwl_device_cmd { + struct iwl_cmd_header hdr; /* uCode API */ + union { + u32 flags; + u8 val8; + u16 val16; + u32 val32; + struct iwl_tx_cmd tx; + u8 payload[DEF_CMD_PAYLOAD_SIZE]; + } __packed cmd; +} __packed; + +#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) + + +struct iwl_host_cmd { + const void *data; + unsigned long reply_page; + void (*callback)(struct iwl_priv *priv, + struct iwl_device_cmd *cmd, + struct iwl_rx_packet *pkt); + u32 flags; + u16 len; + u8 id; +}; + +#define SUP_RATE_11A_MAX_NUM_CHANNELS 8 +#define SUP_RATE_11B_MAX_NUM_CHANNELS 4 +#define SUP_RATE_11G_MAX_NUM_CHANNELS 12 + +/** + * struct iwl_rx_queue - Rx queue + * @bd: driver's pointer to buffer of receive buffer descriptors (rbd) + * @bd_dma: bus address of buffer of receive buffer descriptors (rbd) + * @read: Shared index to newest available Rx buffer + * @write: Shared index to oldest written Rx packet + * @free_count: Number of pre-allocated buffers in rx_free + * @rx_free: list of free SKBs for use + * @rx_used: List of Rx buffers with no SKB + * @need_update: flag to indicate we need to update read/write index + * @rb_stts: driver's pointer to receive buffer status + * @rb_stts_dma: bus address of receive buffer status + * + * NOTE: rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers + */ +struct iwl_rx_queue { + __le32 *bd; + dma_addr_t bd_dma; + struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; + struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE]; + u32 read; + u32 write; + u32 free_count; + u32 write_actual; + struct list_head rx_free; + struct list_head rx_used; + int need_update; + struct iwl_rb_status *rb_stts; + dma_addr_t rb_stts_dma; + spinlock_t lock; +}; + +#define IWL_SUPPORTED_RATES_IE_LEN 8 + +#define MAX_TID_COUNT 9 + +#define IWL_INVALID_RATE 0xFF +#define IWL_INVALID_VALUE -1 + +/** + * struct iwl_ht_agg -- aggregation status while waiting for block-ack + * @txq_id: Tx queue used for Tx attempt + * @frame_count: # frames attempted by Tx command + * @wait_for_ba: Expect block-ack before next Tx reply + * @start_idx: Index of 1st Transmit Frame Descriptor (TFD) in Tx window + * @bitmap0: Low order bitmap, one bit for each frame pending ACK in Tx window + * @bitmap1: High order, one bit for each frame pending ACK in Tx window + * @rate_n_flags: Rate at which Tx was attempted + * + * If REPLY_TX indicates that aggregation was attempted, driver must wait + * for block ack (REPLY_COMPRESSED_BA). This struct stores tx reply info + * until block ack arrives. + */ +struct iwl_ht_agg { + u16 txq_id; + u16 frame_count; + u16 wait_for_ba; + u16 start_idx; + u64 bitmap; + u32 rate_n_flags; +#define IWL_AGG_OFF 0 +#define IWL_AGG_ON 1 +#define IWL_EMPTYING_HW_QUEUE_ADDBA 2 +#define IWL_EMPTYING_HW_QUEUE_DELBA 3 + u8 state; +}; + + +struct iwl_tid_data { + u16 seq_number; /* 4965 only */ + u16 tfds_in_queue; + struct iwl_ht_agg agg; +}; + +struct iwl_hw_key { + u32 cipher; + int keylen; + u8 keyidx; + u8 key[32]; +}; + +union iwl_ht_rate_supp { + u16 rates; + struct { + u8 siso_rate; + u8 mimo_rate; + }; +}; + +#define CFG_HT_RX_AMPDU_FACTOR_8K (0x0) +#define CFG_HT_RX_AMPDU_FACTOR_16K (0x1) +#define CFG_HT_RX_AMPDU_FACTOR_32K (0x2) +#define CFG_HT_RX_AMPDU_FACTOR_64K (0x3) +#define CFG_HT_RX_AMPDU_FACTOR_DEF CFG_HT_RX_AMPDU_FACTOR_64K +#define CFG_HT_RX_AMPDU_FACTOR_MAX CFG_HT_RX_AMPDU_FACTOR_64K +#define CFG_HT_RX_AMPDU_FACTOR_MIN CFG_HT_RX_AMPDU_FACTOR_8K + +/* + * Maximal MPDU density for TX aggregation + * 4 - 2us density + * 5 - 4us density + * 6 - 8us density + * 7 - 16us density + */ +#define CFG_HT_MPDU_DENSITY_2USEC (0x4) +#define CFG_HT_MPDU_DENSITY_4USEC (0x5) +#define CFG_HT_MPDU_DENSITY_8USEC (0x6) +#define CFG_HT_MPDU_DENSITY_16USEC (0x7) +#define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_4USEC +#define CFG_HT_MPDU_DENSITY_MAX CFG_HT_MPDU_DENSITY_16USEC +#define CFG_HT_MPDU_DENSITY_MIN (0x1) + +struct iwl_ht_config { + bool single_chain_sufficient; + enum ieee80211_smps_mode smps; /* current smps mode */ +}; + +/* QoS structures */ +struct iwl_qos_info { + int qos_active; + struct iwl_qosparam_cmd def_qos_parm; +}; + +/* + * Structure should be accessed with sta_lock held. When station addition + * is in progress (IWL_STA_UCODE_INPROGRESS) it is possible to access only + * the commands (iwl_legacy_addsta_cmd and iwl_link_quality_cmd) without + * sta_lock held. + */ +struct iwl_station_entry { + struct iwl_legacy_addsta_cmd sta; + struct iwl_tid_data tid[MAX_TID_COUNT]; + u8 used, ctxid; + struct iwl_hw_key keyinfo; + struct iwl_link_quality_cmd *lq; +}; + +struct iwl_station_priv_common { + struct iwl_rxon_context *ctx; + u8 sta_id; +}; + +/* + * iwl_station_priv: Driver's private station information + * + * When mac80211 creates a station it reserves some space (hw->sta_data_size) + * in the structure for use by driver. This structure is places in that + * space. + * + * The common struct MUST be first because it is shared between + * 3945 and 4965! + */ +struct iwl_station_priv { + struct iwl_station_priv_common common; + struct iwl_lq_sta lq_sta; + atomic_t pending_frames; + bool client; + bool asleep; +}; + +/** + * struct iwl_vif_priv - driver's private per-interface information + * + * When mac80211 allocates a virtual interface, it can allocate + * space for us to put data into. + */ +struct iwl_vif_priv { + struct iwl_rxon_context *ctx; + u8 ibss_bssid_sta_id; +}; + +/* one for each uCode image (inst/data, boot/init/runtime) */ +struct fw_desc { + void *v_addr; /* access by driver */ + dma_addr_t p_addr; /* access by card's busmaster DMA */ + u32 len; /* bytes */ +}; + +/* uCode file layout */ +struct iwl_ucode_header { + __le32 ver; /* major/minor/API/serial */ + struct { + __le32 inst_size; /* bytes of runtime code */ + __le32 data_size; /* bytes of runtime data */ + __le32 init_size; /* bytes of init code */ + __le32 init_data_size; /* bytes of init data */ + __le32 boot_size; /* bytes of bootstrap code */ + u8 data[0]; /* in same order as sizes */ + } v1; +}; + +struct iwl4965_ibss_seq { + u8 mac[ETH_ALEN]; + u16 seq_num; + u16 frag_num; + unsigned long packet_time; + struct list_head list; +}; + +struct iwl_sensitivity_ranges { + u16 min_nrg_cck; + u16 max_nrg_cck; + + u16 nrg_th_cck; + u16 nrg_th_ofdm; + + u16 auto_corr_min_ofdm; + u16 auto_corr_min_ofdm_mrc; + u16 auto_corr_min_ofdm_x1; + u16 auto_corr_min_ofdm_mrc_x1; + + u16 auto_corr_max_ofdm; + u16 auto_corr_max_ofdm_mrc; + u16 auto_corr_max_ofdm_x1; + u16 auto_corr_max_ofdm_mrc_x1; + + u16 auto_corr_max_cck; + u16 auto_corr_max_cck_mrc; + u16 auto_corr_min_cck; + u16 auto_corr_min_cck_mrc; + + u16 barker_corr_th_min; + u16 barker_corr_th_min_mrc; + u16 nrg_th_cca; +}; + + +#define KELVIN_TO_CELSIUS(x) ((x)-273) +#define CELSIUS_TO_KELVIN(x) ((x)+273) + + +/** + * struct iwl_hw_params + * @max_txq_num: Max # Tx queues supported + * @dma_chnl_num: Number of Tx DMA/FIFO channels + * @scd_bc_tbls_size: size of scheduler byte count tables + * @tfd_size: TFD size + * @tx/rx_chains_num: Number of TX/RX chains + * @valid_tx/rx_ant: usable antennas + * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) + * @max_rxq_log: Log-base-2 of max_rxq_size + * @rx_page_order: Rx buffer page order + * @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR + * @max_stations: + * @ht40_channel: is 40MHz width possible in band 2.4 + * BIT(IEEE80211_BAND_5GHZ) BIT(IEEE80211_BAND_5GHZ) + * @sw_crypto: 0 for hw, 1 for sw + * @max_xxx_size: for ucode uses + * @ct_kill_threshold: temperature threshold + * @beacon_time_tsf_bits: number of valid tsf bits for beacon time + * @struct iwl_sensitivity_ranges: range of sensitivity values + */ +struct iwl_hw_params { + u8 max_txq_num; + u8 dma_chnl_num; + u16 scd_bc_tbls_size; + u32 tfd_size; + u8 tx_chains_num; + u8 rx_chains_num; + u8 valid_tx_ant; + u8 valid_rx_ant; + u16 max_rxq_size; + u16 max_rxq_log; + u32 rx_page_order; + u32 rx_wrt_ptr_reg; + u8 max_stations; + u8 ht40_channel; + u8 max_beacon_itrvl; /* in 1024 ms */ + u32 max_inst_size; + u32 max_data_size; + u32 max_bsm_size; + u32 ct_kill_threshold; /* value in hw-dependent units */ + u16 beacon_time_tsf_bits; + const struct iwl_sensitivity_ranges *sens; +}; + + +/****************************************************************************** + * + * Functions implemented in core module which are forward declared here + * for use by iwl-[4-5].c + * + * NOTE: The implementation of these functions are not hardware specific + * which is why they are in the core module files. + * + * Naming convention -- + * iwl_ <-- Is part of iwlwifi + * iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX) + * iwl4965_bg_ <-- Called from work queue context + * iwl4965_mac_ <-- mac80211 callback + * + ****************************************************************************/ +extern void iwl4965_update_chain_flags(struct iwl_priv *priv); +extern const u8 iwl_bcast_addr[ETH_ALEN]; +extern int iwl_legacy_queue_space(const struct iwl_queue *q); +static inline int iwl_legacy_queue_used(const struct iwl_queue *q, int i) +{ + return q->write_ptr >= q->read_ptr ? + (i >= q->read_ptr && i < q->write_ptr) : + !(i < q->read_ptr && i >= q->write_ptr); +} + + +static inline u8 iwl_legacy_get_cmd_index(struct iwl_queue *q, u32 index, + int is_huge) +{ + /* + * This is for init calibration result and scan command which + * required buffer > TFD_MAX_PAYLOAD_SIZE, + * the big buffer at end of command array + */ + if (is_huge) + return q->n_window; /* must be power of 2 */ + + /* Otherwise, use normal size buffers */ + return index & (q->n_window - 1); +} + + +struct iwl_dma_ptr { + dma_addr_t dma; + void *addr; + size_t size; +}; + +#define IWL_OPERATION_MODE_AUTO 0 +#define IWL_OPERATION_MODE_HT_ONLY 1 +#define IWL_OPERATION_MODE_MIXED 2 +#define IWL_OPERATION_MODE_20MHZ 3 + +#define IWL_TX_CRC_SIZE 4 +#define IWL_TX_DELIMITER_SIZE 4 + +#define TX_POWER_IWL_ILLEGAL_VOLTAGE -10000 + +/* Sensitivity and chain noise calibration */ +#define INITIALIZATION_VALUE 0xFFFF +#define IWL4965_CAL_NUM_BEACONS 20 +#define IWL_CAL_NUM_BEACONS 16 +#define MAXIMUM_ALLOWED_PATHLOSS 15 + +#define CHAIN_NOISE_MAX_DELTA_GAIN_CODE 3 + +#define MAX_FA_OFDM 50 +#define MIN_FA_OFDM 5 +#define MAX_FA_CCK 50 +#define MIN_FA_CCK 5 + +#define AUTO_CORR_STEP_OFDM 1 + +#define AUTO_CORR_STEP_CCK 3 +#define AUTO_CORR_MAX_TH_CCK 160 + +#define NRG_DIFF 2 +#define NRG_STEP_CCK 2 +#define NRG_MARGIN 8 +#define MAX_NUMBER_CCK_NO_FA 100 + +#define AUTO_CORR_CCK_MIN_VAL_DEF (125) + +#define CHAIN_A 0 +#define CHAIN_B 1 +#define CHAIN_C 2 +#define CHAIN_NOISE_DELTA_GAIN_INIT_VAL 4 +#define ALL_BAND_FILTER 0xFF00 +#define IN_BAND_FILTER 0xFF +#define MIN_AVERAGE_NOISE_MAX_VALUE 0xFFFFFFFF + +#define NRG_NUM_PREV_STAT_L 20 +#define NUM_RX_CHAINS 3 + +enum iwl4965_false_alarm_state { + IWL_FA_TOO_MANY = 0, + IWL_FA_TOO_FEW = 1, + IWL_FA_GOOD_RANGE = 2, +}; + +enum iwl4965_chain_noise_state { + IWL_CHAIN_NOISE_ALIVE = 0, /* must be 0 */ + IWL_CHAIN_NOISE_ACCUMULATE, + IWL_CHAIN_NOISE_CALIBRATED, + IWL_CHAIN_NOISE_DONE, +}; + +enum iwl4965_calib_enabled_state { + IWL_CALIB_DISABLED = 0, /* must be 0 */ + IWL_CALIB_ENABLED = 1, +}; + +/* + * enum iwl_calib + * defines the order in which results of initial calibrations + * should be sent to the runtime uCode + */ +enum iwl_calib { + IWL_CALIB_MAX, +}; + +/* Opaque calibration results */ +struct iwl_calib_result { + void *buf; + size_t buf_len; +}; + +enum ucode_type { + UCODE_NONE = 0, + UCODE_INIT, + UCODE_RT +}; + +/* Sensitivity calib data */ +struct iwl_sensitivity_data { + u32 auto_corr_ofdm; + u32 auto_corr_ofdm_mrc; + u32 auto_corr_ofdm_x1; + u32 auto_corr_ofdm_mrc_x1; + u32 auto_corr_cck; + u32 auto_corr_cck_mrc; + + u32 last_bad_plcp_cnt_ofdm; + u32 last_fa_cnt_ofdm; + u32 last_bad_plcp_cnt_cck; + u32 last_fa_cnt_cck; + + u32 nrg_curr_state; + u32 nrg_prev_state; + u32 nrg_value[10]; + u8 nrg_silence_rssi[NRG_NUM_PREV_STAT_L]; + u32 nrg_silence_ref; + u32 nrg_energy_idx; + u32 nrg_silence_idx; + u32 nrg_th_cck; + s32 nrg_auto_corr_silence_diff; + u32 num_in_cck_no_fa; + u32 nrg_th_ofdm; + + u16 barker_corr_th_min; + u16 barker_corr_th_min_mrc; + u16 nrg_th_cca; +}; + +/* Chain noise (differential Rx gain) calib data */ +struct iwl_chain_noise_data { + u32 active_chains; + u32 chain_noise_a; + u32 chain_noise_b; + u32 chain_noise_c; + u32 chain_signal_a; + u32 chain_signal_b; + u32 chain_signal_c; + u16 beacon_count; + u8 disconn_array[NUM_RX_CHAINS]; + u8 delta_gain_code[NUM_RX_CHAINS]; + u8 radio_write; + u8 state; +}; + +#define EEPROM_SEM_TIMEOUT 10 /* milliseconds */ +#define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ + +#define IWL_TRAFFIC_ENTRIES (256) +#define IWL_TRAFFIC_ENTRY_SIZE (64) + +enum { + MEASUREMENT_READY = (1 << 0), + MEASUREMENT_ACTIVE = (1 << 1), +}; + +/* interrupt statistics */ +struct isr_statistics { + u32 hw; + u32 sw; + u32 err_code; + u32 sch; + u32 alive; + u32 rfkill; + u32 ctkill; + u32 wakeup; + u32 rx; + u32 rx_handlers[REPLY_MAX]; + u32 tx; + u32 unhandled; +}; + +/* management statistics */ +enum iwl_mgmt_stats { + MANAGEMENT_ASSOC_REQ = 0, + MANAGEMENT_ASSOC_RESP, + MANAGEMENT_REASSOC_REQ, + MANAGEMENT_REASSOC_RESP, + MANAGEMENT_PROBE_REQ, + MANAGEMENT_PROBE_RESP, + MANAGEMENT_BEACON, + MANAGEMENT_ATIM, + MANAGEMENT_DISASSOC, + MANAGEMENT_AUTH, + MANAGEMENT_DEAUTH, + MANAGEMENT_ACTION, + MANAGEMENT_MAX, +}; +/* control statistics */ +enum iwl_ctrl_stats { + CONTROL_BACK_REQ = 0, + CONTROL_BACK, + CONTROL_PSPOLL, + CONTROL_RTS, + CONTROL_CTS, + CONTROL_ACK, + CONTROL_CFEND, + CONTROL_CFENDACK, + CONTROL_MAX, +}; + +struct traffic_stats { +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS + u32 mgmt[MANAGEMENT_MAX]; + u32 ctrl[CONTROL_MAX]; + u32 data_cnt; + u64 data_bytes; +#endif +}; + +/* + * iwl_switch_rxon: "channel switch" structure + * + * @ switch_in_progress: channel switch in progress + * @ channel: new channel + */ +struct iwl_switch_rxon { + bool switch_in_progress; + __le16 channel; +}; + +/* + * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds + * to perform continuous uCode event logging operation if enabled + */ +#define UCODE_TRACE_PERIOD (100) + +/* + * iwl_event_log: current uCode event log position + * + * @ucode_trace: enable/disable ucode continuous trace timer + * @num_wraps: how many times the event buffer wraps + * @next_entry: the entry just before the next one that uCode would fill + * @non_wraps_count: counter for no wrap detected when dump ucode events + * @wraps_once_count: counter for wrap once detected when dump ucode events + * @wraps_more_count: counter for wrap more than once detected + * when dump ucode events + */ +struct iwl_event_log { + bool ucode_trace; + u32 num_wraps; + u32 next_entry; + int non_wraps_count; + int wraps_once_count; + int wraps_more_count; +}; + +/* + * host interrupt timeout value + * used with setting interrupt coalescing timer + * the CSR_INT_COALESCING is an 8 bit register in 32-usec unit + * + * default interrupt coalescing timer is 64 x 32 = 2048 usecs + * default interrupt coalescing calibration timer is 16 x 32 = 512 usecs + */ +#define IWL_HOST_INT_TIMEOUT_MAX (0xFF) +#define IWL_HOST_INT_TIMEOUT_DEF (0x40) +#define IWL_HOST_INT_TIMEOUT_MIN (0x0) +#define IWL_HOST_INT_CALIB_TIMEOUT_MAX (0xFF) +#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10) +#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0) + +/* + * This is the threshold value of plcp error rate per 100mSecs. It is + * used to set and check for the validity of plcp_delta. + */ +#define IWL_MAX_PLCP_ERR_THRESHOLD_MIN (1) +#define IWL_MAX_PLCP_ERR_THRESHOLD_DEF (50) +#define IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF (100) +#define IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF (200) +#define IWL_MAX_PLCP_ERR_THRESHOLD_MAX (255) +#define IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE (0) + +#define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3) +#define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5) + +/* TX queue watchdog timeouts in mSecs */ +#define IWL_DEF_WD_TIMEOUT (2000) +#define IWL_LONG_WD_TIMEOUT (10000) +#define IWL_MAX_WD_TIMEOUT (120000) + +enum iwl_reset { + IWL_RF_RESET = 0, + IWL_FW_RESET, + IWL_MAX_FORCE_RESET, +}; + +struct iwl_force_reset { + int reset_request_count; + int reset_success_count; + int reset_reject_count; + unsigned long reset_duration; + unsigned long last_force_reset_jiffies; +}; + +/* extend beacon time format bit shifting */ +/* + * for _3945 devices + * bits 31:24 - extended + * bits 23:0 - interval + */ +#define IWL3945_EXT_BEACON_TIME_POS 24 +/* + * for _4965 devices + * bits 31:22 - extended + * bits 21:0 - interval + */ +#define IWL4965_EXT_BEACON_TIME_POS 22 + +enum iwl_rxon_context_id { + IWL_RXON_CTX_BSS, + + NUM_IWL_RXON_CTX +}; + +struct iwl_rxon_context { + struct ieee80211_vif *vif; + + const u8 *ac_to_fifo; + const u8 *ac_to_queue; + u8 mcast_queue; + + /* + * We could use the vif to indicate active, but we + * also need it to be active during disabling when + * we already removed the vif for type setting. + */ + bool always_active, is_active; + + bool ht_need_multiple_chains; + + enum iwl_rxon_context_id ctxid; + + u32 interface_modes, exclusive_interface_modes; + u8 unused_devtype, ap_devtype, ibss_devtype, station_devtype; + + /* + * We declare this const so it can only be + * changed via explicit cast within the + * routines that actually update the physical + * hardware. + */ + const struct iwl_legacy_rxon_cmd active; + struct iwl_legacy_rxon_cmd staging; + + struct iwl_rxon_time_cmd timing; + + struct iwl_qos_info qos_data; + + u8 bcast_sta_id, ap_sta_id; + + u8 rxon_cmd, rxon_assoc_cmd, rxon_timing_cmd; + u8 qos_cmd; + u8 wep_key_cmd; + + struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; + u8 key_mapping_keys; + + __le32 station_flags; + + struct { + bool non_gf_sta_present; + u8 protection; + bool enabled, is_40mhz; + u8 extension_chan_offset; + } ht; +}; + +struct iwl_priv { + + /* ieee device used by generic ieee processing code */ + struct ieee80211_hw *hw; + struct ieee80211_channel *ieee_channels; + struct ieee80211_rate *ieee_rates; + struct iwl_cfg *cfg; + + /* temporary frame storage list */ + struct list_head free_frames; + int frames_count; + + enum ieee80211_band band; + int alloc_rxb_page; + + void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); + + struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; + + /* spectrum measurement report caching */ + struct iwl_spectrum_notification measure_report; + u8 measurement_status; + + /* ucode beacon time */ + u32 ucode_beacon_time; + int missed_beacon_threshold; + + /* track IBSS manager (last beacon) status */ + u32 ibss_manager; + + /* storing the jiffies when the plcp error rate is received */ + unsigned long plcp_jiffies; + + /* force reset */ + struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET]; + + /* we allocate array of iwl_channel_info for NIC's valid channels. + * Access via channel # using indirect index array */ + struct iwl_channel_info *channel_info; /* channel info array */ + u8 channel_count; /* # of channels */ + + /* thermal calibration */ + s32 temperature; /* degrees Kelvin */ + s32 last_temperature; + + /* init calibration results */ + struct iwl_calib_result calib_results[IWL_CALIB_MAX]; + + /* Scan related variables */ + unsigned long scan_start; + unsigned long scan_start_tsf; + void *scan_cmd; + enum ieee80211_band scan_band; + struct cfg80211_scan_request *scan_request; + struct ieee80211_vif *scan_vif; + bool is_internal_short_scan; + u8 scan_tx_ant[IEEE80211_NUM_BANDS]; + u8 mgmt_tx_ant; + + /* spinlock */ + spinlock_t lock; /* protect general shared data */ + spinlock_t hcmd_lock; /* protect hcmd */ + spinlock_t reg_lock; /* protect hw register access */ + struct mutex mutex; + struct mutex sync_cmd_mutex; /* enable serialization of sync commands */ + + /* basic pci-network driver stuff */ + struct pci_dev *pci_dev; + + /* pci hardware address support */ + void __iomem *hw_base; + u32 hw_rev; + u32 hw_wa_rev; + u8 rev_id; + + /* microcode/device supports multiple contexts */ + u8 valid_contexts; + + /* command queue number */ + u8 cmd_queue; + + /* max number of station keys */ + u8 sta_key_max_num; + + /* EEPROM MAC addresses */ + struct mac_address addresses[1]; + + /* uCode images, save to reload in case of failure */ + int fw_index; /* firmware we're trying to load */ + u32 ucode_ver; /* version of ucode, copy of + iwl_ucode.ver */ + struct fw_desc ucode_code; /* runtime inst */ + struct fw_desc ucode_data; /* runtime data original */ + struct fw_desc ucode_data_backup; /* runtime data save/restore */ + struct fw_desc ucode_init; /* initialization inst */ + struct fw_desc ucode_init_data; /* initialization data */ + struct fw_desc ucode_boot; /* bootstrap inst */ + enum ucode_type ucode_type; + u8 ucode_write_complete; /* the image write is complete */ + char firmware_name[25]; + + struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX]; + + struct iwl_switch_rxon switch_rxon; + + /* 1st responses from initialize and runtime uCode images. + * _4965's initialize alive response contains some calibration data. */ + struct iwl_init_alive_resp card_alive_init; + struct iwl_alive_resp card_alive; + + u16 active_rate; + + u8 start_calib; + struct iwl_sensitivity_data sensitivity_data; + struct iwl_chain_noise_data chain_noise_data; + __le16 sensitivity_tbl[HD_TABLE_SIZE]; + + struct iwl_ht_config current_ht_config; + + /* Rate scaling data */ + u8 retry_rate; + + wait_queue_head_t wait_command_queue; + + int activity_timer_active; + + /* Rx and Tx DMA processing queues */ + struct iwl_rx_queue rxq; + struct iwl_tx_queue *txq; + unsigned long txq_ctx_active_msk; + struct iwl_dma_ptr kw; /* keep warm address */ + struct iwl_dma_ptr scd_bc_tbls; + + u32 scd_base_addr; /* scheduler sram base address */ + + unsigned long status; + + /* counts mgmt, ctl, and data packets */ + struct traffic_stats tx_stats; + struct traffic_stats rx_stats; + + /* counts interrupts */ + struct isr_statistics isr_stats; + + struct iwl_power_mgr power_data; + + /* context information */ + u8 bssid[ETH_ALEN]; /* used only on 3945 but filled by core */ + + /* station table variables */ + + /* Note: if lock and sta_lock are needed, lock must be acquired first */ + spinlock_t sta_lock; + int num_stations; + struct iwl_station_entry stations[IWL_STATION_COUNT]; + unsigned long ucode_key_table; + + /* queue refcounts */ +#define IWL_MAX_HW_QUEUES 32 + unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; + /* for each AC */ + atomic_t queue_stop_count[4]; + + /* Indication if ieee80211_ops->open has been called */ + u8 is_open; + + u8 mac80211_registered; + + /* eeprom -- this is in the card's little endian byte order */ + u8 *eeprom; + struct iwl_eeprom_calib_info *calib_info; + + enum nl80211_iftype iw_mode; + + /* Last Rx'd beacon timestamp */ + u64 timestamp; + + union { +#if defined(CONFIG_IWL3945) || defined(CONFIG_IWL3945_MODULE) + struct { + void *shared_virt; + dma_addr_t shared_phys; + + struct delayed_work thermal_periodic; + struct delayed_work rfkill_poll; + + struct iwl3945_notif_statistics statistics; +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS + struct iwl3945_notif_statistics accum_statistics; + struct iwl3945_notif_statistics delta_statistics; + struct iwl3945_notif_statistics max_delta; +#endif + + u32 sta_supp_rates; + int last_rx_rssi; /* From Rx packet statistics */ + + /* Rx'd packet timing information */ + u32 last_beacon_time; + u64 last_tsf; + + /* + * each calibration channel group in the + * EEPROM has a derived clip setting for + * each rate. + */ + const struct iwl3945_clip_group clip_groups[5]; + + } _3945; +#endif +#if defined(CONFIG_IWL4965) || defined(CONFIG_IWL4965_MODULE) + struct { + /* + * reporting the number of tids has AGG on. 0 means + * no AGGREGATION + */ + u8 agg_tids_count; + + struct iwl_rx_phy_res last_phy_res; + bool last_phy_res_valid; + + struct completion firmware_loading_complete; + + /* + * chain noise reset and gain commands are the + * two extra calibration commands follows the standard + * phy calibration commands + */ + u8 phy_calib_chain_noise_reset_cmd; + u8 phy_calib_chain_noise_gain_cmd; + + struct iwl_notif_statistics statistics; +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS + struct iwl_notif_statistics accum_statistics; + struct iwl_notif_statistics delta_statistics; + struct iwl_notif_statistics max_delta; +#endif + + } _4965; +#endif + }; + + struct iwl_hw_params hw_params; + + u32 inta_mask; + + struct workqueue_struct *workqueue; + + struct work_struct restart; + struct work_struct scan_completed; + struct work_struct rx_replenish; + struct work_struct abort_scan; + + struct iwl_rxon_context *beacon_ctx; + struct sk_buff *beacon_skb; + + struct work_struct start_internal_scan; + struct work_struct tx_flush; + + struct tasklet_struct irq_tasklet; + + struct delayed_work init_alive_start; + struct delayed_work alive_start; + struct delayed_work scan_check; + + /* TX Power */ + s8 tx_power_user_lmt; + s8 tx_power_device_lmt; + s8 tx_power_next; + + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + /* debugging info */ + u32 debug_level; /* per device debugging will override global + iwl_debug_level if set */ +#endif /* CONFIG_IWLWIFI_LEGACY_DEBUG */ +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS + /* debugfs */ + u16 tx_traffic_idx; + u16 rx_traffic_idx; + u8 *tx_traffic; + u8 *rx_traffic; + struct dentry *debugfs_dir; + u32 dbgfs_sram_offset, dbgfs_sram_len; + bool disable_ht40; +#endif /* CONFIG_IWLWIFI_LEGACY_DEBUGFS */ + + struct work_struct txpower_work; + u32 disable_sens_cal; + u32 disable_chain_noise_cal; + u32 disable_tx_power_cal; + struct work_struct run_time_calib_work; + struct timer_list statistics_periodic; + struct timer_list ucode_trace; + struct timer_list watchdog; + bool hw_ready; + + struct iwl_event_log event_log; + + struct led_classdev led; + unsigned long blink_on, blink_off; + bool led_registered; +}; /*iwl_priv */ + +static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id) +{ + set_bit(txq_id, &priv->txq_ctx_active_msk); +} + +static inline void iwl_txq_ctx_deactivate(struct iwl_priv *priv, int txq_id) +{ + clear_bit(txq_id, &priv->txq_ctx_active_msk); +} + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +/* + * iwl_legacy_get_debug_level: Return active debug level for device + * + * Using sysfs it is possible to set per device debug level. This debug + * level will be used if set, otherwise the global debug level which can be + * set via module parameter is used. + */ +static inline u32 iwl_legacy_get_debug_level(struct iwl_priv *priv) +{ + if (priv->debug_level) + return priv->debug_level; + else + return iwl_debug_level; +} +#else +static inline u32 iwl_legacy_get_debug_level(struct iwl_priv *priv) +{ + return iwl_debug_level; +} +#endif + + +static inline struct ieee80211_hdr * +iwl_legacy_tx_queue_get_hdr(struct iwl_priv *priv, + int txq_id, int idx) +{ + if (priv->txq[txq_id].txb[idx].skb) + return (struct ieee80211_hdr *)priv->txq[txq_id]. + txb[idx].skb->data; + return NULL; +} + +static inline struct iwl_rxon_context * +iwl_legacy_rxon_ctx_from_vif(struct ieee80211_vif *vif) +{ + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; + + return vif_priv->ctx; +} + +#define for_each_context(priv, ctx) \ + for (ctx = &priv->contexts[IWL_RXON_CTX_BSS]; \ + ctx < &priv->contexts[NUM_IWL_RXON_CTX]; ctx++) \ + if (priv->valid_contexts & BIT(ctx->ctxid)) + +static inline int iwl_legacy_is_associated(struct iwl_priv *priv, + enum iwl_rxon_context_id ctxid) +{ + return (priv->contexts[ctxid].active.filter_flags & + RXON_FILTER_ASSOC_MSK) ? 1 : 0; +} + +static inline int iwl_legacy_is_any_associated(struct iwl_priv *priv) +{ + return iwl_legacy_is_associated(priv, IWL_RXON_CTX_BSS); +} + +static inline int iwl_legacy_is_associated_ctx(struct iwl_rxon_context *ctx) +{ + return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; +} + +static inline int iwl_legacy_is_channel_valid(const struct iwl_channel_info *ch_info) +{ + if (ch_info == NULL) + return 0; + return (ch_info->flags & EEPROM_CHANNEL_VALID) ? 1 : 0; +} + +static inline int iwl_legacy_is_channel_radar(const struct iwl_channel_info *ch_info) +{ + return (ch_info->flags & EEPROM_CHANNEL_RADAR) ? 1 : 0; +} + +static inline u8 iwl_legacy_is_channel_a_band(const struct iwl_channel_info *ch_info) +{ + return ch_info->band == IEEE80211_BAND_5GHZ; +} + +static inline int +iwl_legacy_is_channel_passive(const struct iwl_channel_info *ch) +{ + return (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) ? 1 : 0; +} + +static inline void +__iwl_legacy_free_pages(struct iwl_priv *priv, struct page *page) +{ + __free_pages(page, priv->hw_params.rx_page_order); + priv->alloc_rxb_page--; +} + +static inline void iwl_legacy_free_pages(struct iwl_priv *priv, unsigned long page) +{ + free_pages(page, priv->hw_params.rx_page_order); + priv->alloc_rxb_page--; +} +#endif /* __iwl_legacy_dev_h__ */ diff --git a/drivers/net/wireless/iwlegacy/iwl-devtrace.c b/drivers/net/wireless/iwlegacy/iwl-devtrace.c new file mode 100644 index 000000000000..080b852b33bd --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-devtrace.c @@ -0,0 +1,45 @@ +/****************************************************************************** + * + * Copyright(c) 2009 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include + +/* sparse doesn't like tracepoint macros */ +#ifndef __CHECKER__ +#include "iwl-dev.h" + +#define CREATE_TRACE_POINTS +#include "iwl-devtrace.h" + +EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_iowrite8); +EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ioread32); +EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_iowrite32); +EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_rx); +EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_tx); +EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_event); +EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_error); +EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_cont_event); +EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_wrap_event); +#endif diff --git a/drivers/net/wireless/iwlegacy/iwl-devtrace.h b/drivers/net/wireless/iwlegacy/iwl-devtrace.h new file mode 100644 index 000000000000..9612aa0f6ec4 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-devtrace.h @@ -0,0 +1,270 @@ +/****************************************************************************** + * + * Copyright(c) 2009 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#if !defined(__IWLWIFI_LEGACY_DEVICE_TRACE) || defined(TRACE_HEADER_MULTI_READ) +#define __IWLWIFI_LEGACY_DEVICE_TRACE + +#include + +#if !defined(CONFIG_IWLWIFI_LEGACY_DEVICE_TRACING) || defined(__CHECKER__) +#undef TRACE_EVENT +#define TRACE_EVENT(name, proto, ...) \ +static inline void trace_ ## name(proto) {} +#endif + + +#define PRIV_ENTRY __field(struct iwl_priv *, priv) +#define PRIV_ASSIGN (__entry->priv = priv) + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM iwlwifi_legacy_io + +TRACE_EVENT(iwlwifi_legacy_dev_ioread32, + TP_PROTO(struct iwl_priv *priv, u32 offs, u32 val), + TP_ARGS(priv, offs, val), + TP_STRUCT__entry( + PRIV_ENTRY + __field(u32, offs) + __field(u32, val) + ), + TP_fast_assign( + PRIV_ASSIGN; + __entry->offs = offs; + __entry->val = val; + ), + TP_printk("[%p] read io[%#x] = %#x", __entry->priv, + __entry->offs, __entry->val) +); + +TRACE_EVENT(iwlwifi_legacy_dev_iowrite8, + TP_PROTO(struct iwl_priv *priv, u32 offs, u8 val), + TP_ARGS(priv, offs, val), + TP_STRUCT__entry( + PRIV_ENTRY + __field(u32, offs) + __field(u8, val) + ), + TP_fast_assign( + PRIV_ASSIGN; + __entry->offs = offs; + __entry->val = val; + ), + TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, + __entry->offs, __entry->val) +); + +TRACE_EVENT(iwlwifi_legacy_dev_iowrite32, + TP_PROTO(struct iwl_priv *priv, u32 offs, u32 val), + TP_ARGS(priv, offs, val), + TP_STRUCT__entry( + PRIV_ENTRY + __field(u32, offs) + __field(u32, val) + ), + TP_fast_assign( + PRIV_ASSIGN; + __entry->offs = offs; + __entry->val = val; + ), + TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, + __entry->offs, __entry->val) +); + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM iwlwifi_legacy_ucode + +TRACE_EVENT(iwlwifi_legacy_dev_ucode_cont_event, + TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev), + TP_ARGS(priv, time, data, ev), + TP_STRUCT__entry( + PRIV_ENTRY + + __field(u32, time) + __field(u32, data) + __field(u32, ev) + ), + TP_fast_assign( + PRIV_ASSIGN; + __entry->time = time; + __entry->data = data; + __entry->ev = ev; + ), + TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u", + __entry->priv, __entry->time, __entry->data, __entry->ev) +); + +TRACE_EVENT(iwlwifi_legacy_dev_ucode_wrap_event, + TP_PROTO(struct iwl_priv *priv, u32 wraps, u32 n_entry, u32 p_entry), + TP_ARGS(priv, wraps, n_entry, p_entry), + TP_STRUCT__entry( + PRIV_ENTRY + + __field(u32, wraps) + __field(u32, n_entry) + __field(u32, p_entry) + ), + TP_fast_assign( + PRIV_ASSIGN; + __entry->wraps = wraps; + __entry->n_entry = n_entry; + __entry->p_entry = p_entry; + ), + TP_printk("[%p] wraps=#%02d n=0x%X p=0x%X", + __entry->priv, __entry->wraps, __entry->n_entry, + __entry->p_entry) +); + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM iwlwifi + +TRACE_EVENT(iwlwifi_legacy_dev_hcmd, + TP_PROTO(struct iwl_priv *priv, void *hcmd, size_t len, u32 flags), + TP_ARGS(priv, hcmd, len, flags), + TP_STRUCT__entry( + PRIV_ENTRY + __dynamic_array(u8, hcmd, len) + __field(u32, flags) + ), + TP_fast_assign( + PRIV_ASSIGN; + memcpy(__get_dynamic_array(hcmd), hcmd, len); + __entry->flags = flags; + ), + TP_printk("[%p] hcmd %#.2x (%ssync)", + __entry->priv, ((u8 *)__get_dynamic_array(hcmd))[0], + __entry->flags & CMD_ASYNC ? "a" : "") +); + +TRACE_EVENT(iwlwifi_legacy_dev_rx, + TP_PROTO(struct iwl_priv *priv, void *rxbuf, size_t len), + TP_ARGS(priv, rxbuf, len), + TP_STRUCT__entry( + PRIV_ENTRY + __dynamic_array(u8, rxbuf, len) + ), + TP_fast_assign( + PRIV_ASSIGN; + memcpy(__get_dynamic_array(rxbuf), rxbuf, len); + ), + TP_printk("[%p] RX cmd %#.2x", + __entry->priv, ((u8 *)__get_dynamic_array(rxbuf))[4]) +); + +TRACE_EVENT(iwlwifi_legacy_dev_tx, + TP_PROTO(struct iwl_priv *priv, void *tfd, size_t tfdlen, + void *buf0, size_t buf0_len, + void *buf1, size_t buf1_len), + TP_ARGS(priv, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), + TP_STRUCT__entry( + PRIV_ENTRY + + __field(size_t, framelen) + __dynamic_array(u8, tfd, tfdlen) + + /* + * Do not insert between or below these items, + * we want to keep the frame together (except + * for the possible padding). + */ + __dynamic_array(u8, buf0, buf0_len) + __dynamic_array(u8, buf1, buf1_len) + ), + TP_fast_assign( + PRIV_ASSIGN; + __entry->framelen = buf0_len + buf1_len; + memcpy(__get_dynamic_array(tfd), tfd, tfdlen); + memcpy(__get_dynamic_array(buf0), buf0, buf0_len); + memcpy(__get_dynamic_array(buf1), buf1, buf1_len); + ), + TP_printk("[%p] TX %.2x (%zu bytes)", + __entry->priv, + ((u8 *)__get_dynamic_array(buf0))[0], + __entry->framelen) +); + +TRACE_EVENT(iwlwifi_legacy_dev_ucode_error, + TP_PROTO(struct iwl_priv *priv, u32 desc, u32 time, + u32 data1, u32 data2, u32 line, u32 blink1, + u32 blink2, u32 ilink1, u32 ilink2), + TP_ARGS(priv, desc, time, data1, data2, line, + blink1, blink2, ilink1, ilink2), + TP_STRUCT__entry( + PRIV_ENTRY + __field(u32, desc) + __field(u32, time) + __field(u32, data1) + __field(u32, data2) + __field(u32, line) + __field(u32, blink1) + __field(u32, blink2) + __field(u32, ilink1) + __field(u32, ilink2) + ), + TP_fast_assign( + PRIV_ASSIGN; + __entry->desc = desc; + __entry->time = time; + __entry->data1 = data1; + __entry->data2 = data2; + __entry->line = line; + __entry->blink1 = blink1; + __entry->blink2 = blink2; + __entry->ilink1 = ilink1; + __entry->ilink2 = ilink2; + ), + TP_printk("[%p] #%02d %010u data 0x%08X 0x%08X line %u, " + "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X", + __entry->priv, __entry->desc, __entry->time, __entry->data1, + __entry->data2, __entry->line, __entry->blink1, + __entry->blink2, __entry->ilink1, __entry->ilink2) +); + +TRACE_EVENT(iwlwifi_legacy_dev_ucode_event, + TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev), + TP_ARGS(priv, time, data, ev), + TP_STRUCT__entry( + PRIV_ENTRY + + __field(u32, time) + __field(u32, data) + __field(u32, ev) + ), + TP_fast_assign( + PRIV_ASSIGN; + __entry->time = time; + __entry->data = data; + __entry->ev = ev; + ), + TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u", + __entry->priv, __entry->time, __entry->data, __entry->ev) +); +#endif /* __IWLWIFI_DEVICE_TRACE */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE iwl-devtrace +#include diff --git a/drivers/net/wireless/iwlegacy/iwl-eeprom.c b/drivers/net/wireless/iwlegacy/iwl-eeprom.c new file mode 100644 index 000000000000..39e577323942 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-eeprom.c @@ -0,0 +1,561 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + + +#include +#include +#include +#include + +#include + +#include "iwl-commands.h" +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-debug.h" +#include "iwl-eeprom.h" +#include "iwl-io.h" + +/************************** EEPROM BANDS **************************** + * + * The iwl_eeprom_band definitions below provide the mapping from the + * EEPROM contents to the specific channel number supported for each + * band. + * + * For example, iwl_priv->eeprom.band_3_channels[4] from the band_3 + * definition below maps to physical channel 42 in the 5.2GHz spectrum. + * The specific geography and calibration information for that channel + * is contained in the eeprom map itself. + * + * During init, we copy the eeprom information and channel map + * information into priv->channel_info_24/52 and priv->channel_map_24/52 + * + * channel_map_24/52 provides the index in the channel_info array for a + * given channel. We have to have two separate maps as there is channel + * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and + * band_2 + * + * A value of 0xff stored in the channel_map indicates that the channel + * is not supported by the hardware at all. + * + * A value of 0xfe in the channel_map indicates that the channel is not + * valid for Tx with the current hardware. This means that + * while the system can tune and receive on a given channel, it may not + * be able to associate or transmit any frames on that + * channel. There is no corresponding channel information for that + * entry. + * + *********************************************************************/ + +/* 2.4 GHz */ +const u8 iwl_eeprom_band_1[14] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 +}; + +/* 5.2 GHz bands */ +static const u8 iwl_eeprom_band_2[] = { /* 4915-5080MHz */ + 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 +}; + +static const u8 iwl_eeprom_band_3[] = { /* 5170-5320MHz */ + 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 +}; + +static const u8 iwl_eeprom_band_4[] = { /* 5500-5700MHz */ + 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 +}; + +static const u8 iwl_eeprom_band_5[] = { /* 5725-5825MHz */ + 145, 149, 153, 157, 161, 165 +}; + +static const u8 iwl_eeprom_band_6[] = { /* 2.4 ht40 channel */ + 1, 2, 3, 4, 5, 6, 7 +}; + +static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */ + 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 +}; + +/****************************************************************************** + * + * EEPROM related functions + * +******************************************************************************/ + +static int iwl_legacy_eeprom_verify_signature(struct iwl_priv *priv) +{ + u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; + int ret = 0; + + IWL_DEBUG_EEPROM(priv, "EEPROM signature=0x%08x\n", gp); + switch (gp) { + case CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K: + case CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K: + break; + default: + IWL_ERR(priv, "bad EEPROM signature," + "EEPROM_GP=0x%08x\n", gp); + ret = -ENOENT; + break; + } + return ret; +} + +const u8 +*iwl_legacy_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) +{ + BUG_ON(offset >= priv->cfg->base_params->eeprom_size); + return &priv->eeprom[offset]; +} +EXPORT_SYMBOL(iwl_legacy_eeprom_query_addr); + +u16 iwl_legacy_eeprom_query16(const struct iwl_priv *priv, size_t offset) +{ + if (!priv->eeprom) + return 0; + return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8); +} +EXPORT_SYMBOL(iwl_legacy_eeprom_query16); + +/** + * iwl_legacy_eeprom_init - read EEPROM contents + * + * Load the EEPROM contents from adapter into priv->eeprom + * + * NOTE: This routine uses the non-debug IO access functions. + */ +int iwl_legacy_eeprom_init(struct iwl_priv *priv) +{ + __le16 *e; + u32 gp = iwl_read32(priv, CSR_EEPROM_GP); + int sz; + int ret; + u16 addr; + + /* allocate eeprom */ + sz = priv->cfg->base_params->eeprom_size; + IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz); + priv->eeprom = kzalloc(sz, GFP_KERNEL); + if (!priv->eeprom) { + ret = -ENOMEM; + goto alloc_err; + } + e = (__le16 *)priv->eeprom; + + priv->cfg->ops->lib->apm_ops.init(priv); + + ret = iwl_legacy_eeprom_verify_signature(priv); + if (ret < 0) { + IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); + ret = -ENOENT; + goto err; + } + + /* Make sure driver (instead of uCode) is allowed to read EEPROM */ + ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv); + if (ret < 0) { + IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); + ret = -ENOENT; + goto err; + } + + /* eeprom is an array of 16bit values */ + for (addr = 0; addr < sz; addr += sizeof(u16)) { + u32 r; + + _iwl_legacy_write32(priv, CSR_EEPROM_REG, + CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); + + ret = iwl_poll_bit(priv, CSR_EEPROM_REG, + CSR_EEPROM_REG_READ_VALID_MSK, + CSR_EEPROM_REG_READ_VALID_MSK, + IWL_EEPROM_ACCESS_TIMEOUT); + if (ret < 0) { + IWL_ERR(priv, "Time out reading EEPROM[%d]\n", + addr); + goto done; + } + r = _iwl_legacy_read_direct32(priv, CSR_EEPROM_REG); + e[addr / 2] = cpu_to_le16(r >> 16); + } + + IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n", + "EEPROM", + iwl_legacy_eeprom_query16(priv, EEPROM_VERSION)); + + ret = 0; +done: + priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv); + +err: + if (ret) + iwl_legacy_eeprom_free(priv); + /* Reset chip to save power until we load uCode during "up". */ + iwl_legacy_apm_stop(priv); +alloc_err: + return ret; +} +EXPORT_SYMBOL(iwl_legacy_eeprom_init); + +void iwl_legacy_eeprom_free(struct iwl_priv *priv) +{ + kfree(priv->eeprom); + priv->eeprom = NULL; +} +EXPORT_SYMBOL(iwl_legacy_eeprom_free); + +static void iwl_legacy_init_band_reference(const struct iwl_priv *priv, + int eep_band, int *eeprom_ch_count, + const struct iwl_eeprom_channel **eeprom_ch_info, + const u8 **eeprom_ch_index) +{ + u32 offset = priv->cfg->ops->lib-> + eeprom_ops.regulatory_bands[eep_band - 1]; + switch (eep_band) { + case 1: /* 2.4GHz band */ + *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1); + *eeprom_ch_info = (struct iwl_eeprom_channel *) + iwl_legacy_eeprom_query_addr(priv, offset); + *eeprom_ch_index = iwl_eeprom_band_1; + break; + case 2: /* 4.9GHz band */ + *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2); + *eeprom_ch_info = (struct iwl_eeprom_channel *) + iwl_legacy_eeprom_query_addr(priv, offset); + *eeprom_ch_index = iwl_eeprom_band_2; + break; + case 3: /* 5.2GHz band */ + *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3); + *eeprom_ch_info = (struct iwl_eeprom_channel *) + iwl_legacy_eeprom_query_addr(priv, offset); + *eeprom_ch_index = iwl_eeprom_band_3; + break; + case 4: /* 5.5GHz band */ + *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4); + *eeprom_ch_info = (struct iwl_eeprom_channel *) + iwl_legacy_eeprom_query_addr(priv, offset); + *eeprom_ch_index = iwl_eeprom_band_4; + break; + case 5: /* 5.7GHz band */ + *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5); + *eeprom_ch_info = (struct iwl_eeprom_channel *) + iwl_legacy_eeprom_query_addr(priv, offset); + *eeprom_ch_index = iwl_eeprom_band_5; + break; + case 6: /* 2.4GHz ht40 channels */ + *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6); + *eeprom_ch_info = (struct iwl_eeprom_channel *) + iwl_legacy_eeprom_query_addr(priv, offset); + *eeprom_ch_index = iwl_eeprom_band_6; + break; + case 7: /* 5 GHz ht40 channels */ + *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7); + *eeprom_ch_info = (struct iwl_eeprom_channel *) + iwl_legacy_eeprom_query_addr(priv, offset); + *eeprom_ch_index = iwl_eeprom_band_7; + break; + default: + BUG(); + return; + } +} + +#define CHECK_AND_PRINT(x) ((eeprom_ch->flags & EEPROM_CHANNEL_##x) \ + ? # x " " : "") +/** + * iwl_legacy_mod_ht40_chan_info - Copy ht40 channel info into driver's priv. + * + * Does not set up a command, or touch hardware. + */ +static int iwl_legacy_mod_ht40_chan_info(struct iwl_priv *priv, + enum ieee80211_band band, u16 channel, + const struct iwl_eeprom_channel *eeprom_ch, + u8 clear_ht40_extension_channel) +{ + struct iwl_channel_info *ch_info; + + ch_info = (struct iwl_channel_info *) + iwl_legacy_get_channel_info(priv, band, channel); + + if (!iwl_legacy_is_channel_valid(ch_info)) + return -1; + + IWL_DEBUG_EEPROM(priv, "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):" + " Ad-Hoc %ssupported\n", + ch_info->channel, + iwl_legacy_is_channel_a_band(ch_info) ? + "5.2" : "2.4", + CHECK_AND_PRINT(IBSS), + CHECK_AND_PRINT(ACTIVE), + CHECK_AND_PRINT(RADAR), + CHECK_AND_PRINT(WIDE), + CHECK_AND_PRINT(DFS), + eeprom_ch->flags, + eeprom_ch->max_power_avg, + ((eeprom_ch->flags & EEPROM_CHANNEL_IBSS) + && !(eeprom_ch->flags & EEPROM_CHANNEL_RADAR)) ? + "" : "not "); + + ch_info->ht40_eeprom = *eeprom_ch; + ch_info->ht40_max_power_avg = eeprom_ch->max_power_avg; + ch_info->ht40_flags = eeprom_ch->flags; + if (eeprom_ch->flags & EEPROM_CHANNEL_VALID) + ch_info->ht40_extension_channel &= + ~clear_ht40_extension_channel; + + return 0; +} + +#define CHECK_AND_PRINT_I(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \ + ? # x " " : "") + +/** + * iwl_legacy_init_channel_map - Set up driver's info for all possible channels + */ +int iwl_legacy_init_channel_map(struct iwl_priv *priv) +{ + int eeprom_ch_count = 0; + const u8 *eeprom_ch_index = NULL; + const struct iwl_eeprom_channel *eeprom_ch_info = NULL; + int band, ch; + struct iwl_channel_info *ch_info; + + if (priv->channel_count) { + IWL_DEBUG_EEPROM(priv, "Channel map already initialized.\n"); + return 0; + } + + IWL_DEBUG_EEPROM(priv, "Initializing regulatory info from EEPROM\n"); + + priv->channel_count = + ARRAY_SIZE(iwl_eeprom_band_1) + + ARRAY_SIZE(iwl_eeprom_band_2) + + ARRAY_SIZE(iwl_eeprom_band_3) + + ARRAY_SIZE(iwl_eeprom_band_4) + + ARRAY_SIZE(iwl_eeprom_band_5); + + IWL_DEBUG_EEPROM(priv, "Parsing data for %d channels.\n", + priv->channel_count); + + priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) * + priv->channel_count, GFP_KERNEL); + if (!priv->channel_info) { + IWL_ERR(priv, "Could not allocate channel_info\n"); + priv->channel_count = 0; + return -ENOMEM; + } + + ch_info = priv->channel_info; + + /* Loop through the 5 EEPROM bands adding them in order to the + * channel map we maintain (that contains additional information than + * what just in the EEPROM) */ + for (band = 1; band <= 5; band++) { + + iwl_legacy_init_band_reference(priv, band, &eeprom_ch_count, + &eeprom_ch_info, &eeprom_ch_index); + + /* Loop through each band adding each of the channels */ + for (ch = 0; ch < eeprom_ch_count; ch++) { + ch_info->channel = eeprom_ch_index[ch]; + ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ : + IEEE80211_BAND_5GHZ; + + /* permanently store EEPROM's channel regulatory flags + * and max power in channel info database. */ + ch_info->eeprom = eeprom_ch_info[ch]; + + /* Copy the run-time flags so they are there even on + * invalid channels */ + ch_info->flags = eeprom_ch_info[ch].flags; + /* First write that ht40 is not enabled, and then enable + * one by one */ + ch_info->ht40_extension_channel = + IEEE80211_CHAN_NO_HT40; + + if (!(iwl_legacy_is_channel_valid(ch_info))) { + IWL_DEBUG_EEPROM(priv, + "Ch. %d Flags %x [%sGHz] - " + "No traffic\n", + ch_info->channel, + ch_info->flags, + iwl_legacy_is_channel_a_band(ch_info) ? + "5.2" : "2.4"); + ch_info++; + continue; + } + + /* Initialize regulatory-based run-time data */ + ch_info->max_power_avg = ch_info->curr_txpow = + eeprom_ch_info[ch].max_power_avg; + ch_info->scan_power = eeprom_ch_info[ch].max_power_avg; + ch_info->min_power = 0; + + IWL_DEBUG_EEPROM(priv, "Ch. %d [%sGHz] " + "%s%s%s%s%s%s(0x%02x %ddBm):" + " Ad-Hoc %ssupported\n", + ch_info->channel, + iwl_legacy_is_channel_a_band(ch_info) ? + "5.2" : "2.4", + CHECK_AND_PRINT_I(VALID), + CHECK_AND_PRINT_I(IBSS), + CHECK_AND_PRINT_I(ACTIVE), + CHECK_AND_PRINT_I(RADAR), + CHECK_AND_PRINT_I(WIDE), + CHECK_AND_PRINT_I(DFS), + eeprom_ch_info[ch].flags, + eeprom_ch_info[ch].max_power_avg, + ((eeprom_ch_info[ch]. + flags & EEPROM_CHANNEL_IBSS) + && !(eeprom_ch_info[ch]. + flags & EEPROM_CHANNEL_RADAR)) + ? "" : "not "); + + /* Set the tx_power_user_lmt to the highest power + * supported by any channel */ + if (eeprom_ch_info[ch].max_power_avg > + priv->tx_power_user_lmt) + priv->tx_power_user_lmt = + eeprom_ch_info[ch].max_power_avg; + + ch_info++; + } + } + + /* Check if we do have HT40 channels */ + if (priv->cfg->ops->lib->eeprom_ops.regulatory_bands[5] == + EEPROM_REGULATORY_BAND_NO_HT40 && + priv->cfg->ops->lib->eeprom_ops.regulatory_bands[6] == + EEPROM_REGULATORY_BAND_NO_HT40) + return 0; + + /* Two additional EEPROM bands for 2.4 and 5 GHz HT40 channels */ + for (band = 6; band <= 7; band++) { + enum ieee80211_band ieeeband; + + iwl_legacy_init_band_reference(priv, band, &eeprom_ch_count, + &eeprom_ch_info, &eeprom_ch_index); + + /* EEPROM band 6 is 2.4, band 7 is 5 GHz */ + ieeeband = + (band == 6) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; + + /* Loop through each band adding each of the channels */ + for (ch = 0; ch < eeprom_ch_count; ch++) { + /* Set up driver's info for lower half */ + iwl_legacy_mod_ht40_chan_info(priv, ieeeband, + eeprom_ch_index[ch], + &eeprom_ch_info[ch], + IEEE80211_CHAN_NO_HT40PLUS); + + /* Set up driver's info for upper half */ + iwl_legacy_mod_ht40_chan_info(priv, ieeeband, + eeprom_ch_index[ch] + 4, + &eeprom_ch_info[ch], + IEEE80211_CHAN_NO_HT40MINUS); + } + } + + return 0; +} +EXPORT_SYMBOL(iwl_legacy_init_channel_map); + +/* + * iwl_legacy_free_channel_map - undo allocations in iwl_legacy_init_channel_map + */ +void iwl_legacy_free_channel_map(struct iwl_priv *priv) +{ + kfree(priv->channel_info); + priv->channel_count = 0; +} +EXPORT_SYMBOL(iwl_legacy_free_channel_map); + +/** + * iwl_legacy_get_channel_info - Find driver's private channel info + * + * Based on band and channel number. + */ +const struct +iwl_channel_info *iwl_legacy_get_channel_info(const struct iwl_priv *priv, + enum ieee80211_band band, u16 channel) +{ + int i; + + switch (band) { + case IEEE80211_BAND_5GHZ: + for (i = 14; i < priv->channel_count; i++) { + if (priv->channel_info[i].channel == channel) + return &priv->channel_info[i]; + } + break; + case IEEE80211_BAND_2GHZ: + if (channel >= 1 && channel <= 14) + return &priv->channel_info[channel - 1]; + break; + default: + BUG(); + } + + return NULL; +} +EXPORT_SYMBOL(iwl_legacy_get_channel_info); diff --git a/drivers/net/wireless/iwlegacy/iwl-eeprom.h b/drivers/net/wireless/iwlegacy/iwl-eeprom.h new file mode 100644 index 000000000000..0744f8da63b4 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-eeprom.h @@ -0,0 +1,344 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#ifndef __iwl_legacy_eeprom_h__ +#define __iwl_legacy_eeprom_h__ + +#include + +struct iwl_priv; + +/* + * EEPROM access time values: + * + * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG. + * Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1). + * When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec. + * Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG. + */ +#define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */ + +#define IWL_EEPROM_SEM_TIMEOUT 10 /* microseconds */ +#define IWL_EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ + + +/* + * Regulatory channel usage flags in EEPROM struct iwl4965_eeprom_channel.flags. + * + * IBSS and/or AP operation is allowed *only* on those channels with + * (VALID && IBSS && ACTIVE && !RADAR). This restriction is in place because + * RADAR detection is not supported by the 4965 driver, but is a + * requirement for establishing a new network for legal operation on channels + * requiring RADAR detection or restricting ACTIVE scanning. + * + * NOTE: "WIDE" flag does not indicate anything about "HT40" 40 MHz channels. + * It only indicates that 20 MHz channel use is supported; HT40 channel + * usage is indicated by a separate set of regulatory flags for each + * HT40 channel pair. + * + * NOTE: Using a channel inappropriately will result in a uCode error! + */ +#define IWL_NUM_TX_CALIB_GROUPS 5 +enum { + EEPROM_CHANNEL_VALID = (1 << 0), /* usable for this SKU/geo */ + EEPROM_CHANNEL_IBSS = (1 << 1), /* usable as an IBSS channel */ + /* Bit 2 Reserved */ + EEPROM_CHANNEL_ACTIVE = (1 << 3), /* active scanning allowed */ + EEPROM_CHANNEL_RADAR = (1 << 4), /* radar detection required */ + EEPROM_CHANNEL_WIDE = (1 << 5), /* 20 MHz channel okay */ + /* Bit 6 Reserved (was Narrow Channel) */ + EEPROM_CHANNEL_DFS = (1 << 7), /* dynamic freq selection candidate */ +}; + +/* SKU Capabilities */ +/* 3945 only */ +#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0) +#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1) + +/* *regulatory* channel data format in eeprom, one for each channel. + * There are separate entries for HT40 (40 MHz) vs. normal (20 MHz) channels. */ +struct iwl_eeprom_channel { + u8 flags; /* EEPROM_CHANNEL_* flags copied from EEPROM */ + s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */ +} __packed; + +/* 3945 Specific */ +#define EEPROM_3945_EEPROM_VERSION (0x2f) + +/* 4965 has two radio transmitters (and 3 radio receivers) */ +#define EEPROM_TX_POWER_TX_CHAINS (2) + +/* 4965 has room for up to 8 sets of txpower calibration data */ +#define EEPROM_TX_POWER_BANDS (8) + +/* 4965 factory calibration measures txpower gain settings for + * each of 3 target output levels */ +#define EEPROM_TX_POWER_MEASUREMENTS (3) + +/* 4965 Specific */ +/* 4965 driver does not work with txpower calibration version < 5 */ +#define EEPROM_4965_TX_POWER_VERSION (5) +#define EEPROM_4965_EEPROM_VERSION (0x2f) +#define EEPROM_4965_CALIB_VERSION_OFFSET (2*0xB6) /* 2 bytes */ +#define EEPROM_4965_CALIB_TXPOWER_OFFSET (2*0xE8) /* 48 bytes */ +#define EEPROM_4965_BOARD_REVISION (2*0x4F) /* 2 bytes */ +#define EEPROM_4965_BOARD_PBA (2*0x56+1) /* 9 bytes */ + +/* 2.4 GHz */ +extern const u8 iwl_eeprom_band_1[14]; + +/* + * factory calibration data for one txpower level, on one channel, + * measured on one of the 2 tx chains (radio transmitter and associated + * antenna). EEPROM contains: + * + * 1) Temperature (degrees Celsius) of device when measurement was made. + * + * 2) Gain table index used to achieve the target measurement power. + * This refers to the "well-known" gain tables (see iwl-4965-hw.h). + * + * 3) Actual measured output power, in half-dBm ("34" = 17 dBm). + * + * 4) RF power amplifier detector level measurement (not used). + */ +struct iwl_eeprom_calib_measure { + u8 temperature; /* Device temperature (Celsius) */ + u8 gain_idx; /* Index into gain table */ + u8 actual_pow; /* Measured RF output power, half-dBm */ + s8 pa_det; /* Power amp detector level (not used) */ +} __packed; + + +/* + * measurement set for one channel. EEPROM contains: + * + * 1) Channel number measured + * + * 2) Measurements for each of 3 power levels for each of 2 radio transmitters + * (a.k.a. "tx chains") (6 measurements altogether) + */ +struct iwl_eeprom_calib_ch_info { + u8 ch_num; + struct iwl_eeprom_calib_measure + measurements[EEPROM_TX_POWER_TX_CHAINS] + [EEPROM_TX_POWER_MEASUREMENTS]; +} __packed; + +/* + * txpower subband info. + * + * For each frequency subband, EEPROM contains the following: + * + * 1) First and last channels within range of the subband. "0" values + * indicate that this sample set is not being used. + * + * 2) Sample measurement sets for 2 channels close to the range endpoints. + */ +struct iwl_eeprom_calib_subband_info { + u8 ch_from; /* channel number of lowest channel in subband */ + u8 ch_to; /* channel number of highest channel in subband */ + struct iwl_eeprom_calib_ch_info ch1; + struct iwl_eeprom_calib_ch_info ch2; +} __packed; + + +/* + * txpower calibration info. EEPROM contains: + * + * 1) Factory-measured saturation power levels (maximum levels at which + * tx power amplifier can output a signal without too much distortion). + * There is one level for 2.4 GHz band and one for 5 GHz band. These + * values apply to all channels within each of the bands. + * + * 2) Factory-measured power supply voltage level. This is assumed to be + * constant (i.e. same value applies to all channels/bands) while the + * factory measurements are being made. + * + * 3) Up to 8 sets of factory-measured txpower calibration values. + * These are for different frequency ranges, since txpower gain + * characteristics of the analog radio circuitry vary with frequency. + * + * Not all sets need to be filled with data; + * struct iwl_eeprom_calib_subband_info contains range of channels + * (0 if unused) for each set of data. + */ +struct iwl_eeprom_calib_info { + u8 saturation_power24; /* half-dBm (e.g. "34" = 17 dBm) */ + u8 saturation_power52; /* half-dBm */ + __le16 voltage; /* signed */ + struct iwl_eeprom_calib_subband_info + band_info[EEPROM_TX_POWER_BANDS]; +} __packed; + + +/* General */ +#define EEPROM_DEVICE_ID (2*0x08) /* 2 bytes */ +#define EEPROM_MAC_ADDRESS (2*0x15) /* 6 bytes */ +#define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */ +#define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */ +#define EEPROM_VERSION (2*0x44) /* 2 bytes */ +#define EEPROM_SKU_CAP (2*0x45) /* 2 bytes */ +#define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */ +#define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */ +#define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */ +#define EEPROM_NUM_MAC_ADDRESS (2*0x4C) /* 2 bytes */ + +/* The following masks are to be applied on EEPROM_RADIO_CONFIG */ +#define EEPROM_RF_CFG_TYPE_MSK(x) (x & 0x3) /* bits 0-1 */ +#define EEPROM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */ +#define EEPROM_RF_CFG_DASH_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */ +#define EEPROM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */ +#define EEPROM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */ +#define EEPROM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */ + +#define EEPROM_3945_RF_CFG_TYPE_MAX 0x0 +#define EEPROM_4965_RF_CFG_TYPE_MAX 0x1 + +/* + * Per-channel regulatory data. + * + * Each channel that *might* be supported by iwl has a fixed location + * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory + * txpower (MSB). + * + * Entries immediately below are for 20 MHz channel width. HT40 (40 MHz) + * channels (only for 4965, not supported by 3945) appear later in the EEPROM. + * + * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 + */ +#define EEPROM_REGULATORY_SKU_ID (2*0x60) /* 4 bytes */ +#define EEPROM_REGULATORY_BAND_1 (2*0x62) /* 2 bytes */ +#define EEPROM_REGULATORY_BAND_1_CHANNELS (2*0x63) /* 28 bytes */ + +/* + * 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196, + * 5.0 GHz channels 7, 8, 11, 12, 16 + * (4915-5080MHz) (none of these is ever supported) + */ +#define EEPROM_REGULATORY_BAND_2 (2*0x71) /* 2 bytes */ +#define EEPROM_REGULATORY_BAND_2_CHANNELS (2*0x72) /* 26 bytes */ + +/* + * 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 + * (5170-5320MHz) + */ +#define EEPROM_REGULATORY_BAND_3 (2*0x7F) /* 2 bytes */ +#define EEPROM_REGULATORY_BAND_3_CHANNELS (2*0x80) /* 24 bytes */ + +/* + * 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 + * (5500-5700MHz) + */ +#define EEPROM_REGULATORY_BAND_4 (2*0x8C) /* 2 bytes */ +#define EEPROM_REGULATORY_BAND_4_CHANNELS (2*0x8D) /* 22 bytes */ + +/* + * 5.7 GHz channels 145, 149, 153, 157, 161, 165 + * (5725-5825MHz) + */ +#define EEPROM_REGULATORY_BAND_5 (2*0x98) /* 2 bytes */ +#define EEPROM_REGULATORY_BAND_5_CHANNELS (2*0x99) /* 12 bytes */ + +/* + * 2.4 GHz HT40 channels 1 (5), 2 (6), 3 (7), 4 (8), 5 (9), 6 (10), 7 (11) + * + * The channel listed is the center of the lower 20 MHz half of the channel. + * The overall center frequency is actually 2 channels (10 MHz) above that, + * and the upper half of each HT40 channel is centered 4 channels (20 MHz) away + * from the lower half; e.g. the upper half of HT40 channel 1 is channel 5, + * and the overall HT40 channel width centers on channel 3. + * + * NOTE: The RXON command uses 20 MHz channel numbers to specify the + * control channel to which to tune. RXON also specifies whether the + * control channel is the upper or lower half of a HT40 channel. + * + * NOTE: 4965 does not support HT40 channels on 2.4 GHz. + */ +#define EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS (2*0xA0) /* 14 bytes */ + +/* + * 5.2 GHz HT40 channels 36 (40), 44 (48), 52 (56), 60 (64), + * 100 (104), 108 (112), 116 (120), 124 (128), 132 (136), 149 (153), 157 (161) + */ +#define EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS (2*0xA8) /* 22 bytes */ + +#define EEPROM_REGULATORY_BAND_NO_HT40 (0) + +struct iwl_eeprom_ops { + const u32 regulatory_bands[7]; + int (*acquire_semaphore) (struct iwl_priv *priv); + void (*release_semaphore) (struct iwl_priv *priv); +}; + + +int iwl_legacy_eeprom_init(struct iwl_priv *priv); +void iwl_legacy_eeprom_free(struct iwl_priv *priv); +const u8 *iwl_legacy_eeprom_query_addr(const struct iwl_priv *priv, + size_t offset); +u16 iwl_legacy_eeprom_query16(const struct iwl_priv *priv, size_t offset); +int iwl_legacy_init_channel_map(struct iwl_priv *priv); +void iwl_legacy_free_channel_map(struct iwl_priv *priv); +const struct iwl_channel_info *iwl_legacy_get_channel_info( + const struct iwl_priv *priv, + enum ieee80211_band band, u16 channel); + +#endif /* __iwl_legacy_eeprom_h__ */ diff --git a/drivers/net/wireless/iwlegacy/iwl-fh.h b/drivers/net/wireless/iwlegacy/iwl-fh.h new file mode 100644 index 000000000000..4e20c7e5c883 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-fh.h @@ -0,0 +1,513 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ +#ifndef __iwl_legacy_fh_h__ +#define __iwl_legacy_fh_h__ + +/****************************/ +/* Flow Handler Definitions */ +/****************************/ + +/** + * This I/O area is directly read/writable by driver (e.g. Linux uses writel()) + * Addresses are offsets from device's PCI hardware base address. + */ +#define FH_MEM_LOWER_BOUND (0x1000) +#define FH_MEM_UPPER_BOUND (0x2000) + +/** + * Keep-Warm (KW) buffer base address. + * + * Driver must allocate a 4KByte buffer that is used by 4965 for keeping the + * host DRAM powered on (via dummy accesses to DRAM) to maintain low-latency + * DRAM access when 4965 is Txing or Rxing. The dummy accesses prevent host + * from going into a power-savings mode that would cause higher DRAM latency, + * and possible data over/under-runs, before all Tx/Rx is complete. + * + * Driver loads FH_KW_MEM_ADDR_REG with the physical address (bits 35:4) + * of the buffer, which must be 4K aligned. Once this is set up, the 4965 + * automatically invokes keep-warm accesses when normal accesses might not + * be sufficient to maintain fast DRAM response. + * + * Bit fields: + * 31-0: Keep-warm buffer physical base address [35:4], must be 4K aligned + */ +#define FH_KW_MEM_ADDR_REG (FH_MEM_LOWER_BOUND + 0x97C) + + +/** + * TFD Circular Buffers Base (CBBC) addresses + * + * 4965 has 16 base pointer registers, one for each of 16 host-DRAM-resident + * circular buffers (CBs/queues) containing Transmit Frame Descriptors (TFDs) + * (see struct iwl_tfd_frame). These 16 pointer registers are offset by 0x04 + * bytes from one another. Each TFD circular buffer in DRAM must be 256-byte + * aligned (address bits 0-7 must be 0). + * + * Bit fields in each pointer register: + * 27-0: TFD CB physical base address [35:8], must be 256-byte aligned + */ +#define FH_MEM_CBBC_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0x9D0) +#define FH_MEM_CBBC_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xA10) + +/* Find TFD CB base pointer for given queue (range 0-15). */ +#define FH_MEM_CBBC_QUEUE(x) (FH_MEM_CBBC_LOWER_BOUND + (x) * 0x4) + + +/** + * Rx SRAM Control and Status Registers (RSCSR) + * + * These registers provide handshake between driver and 4965 for the Rx queue + * (this queue handles *all* command responses, notifications, Rx data, etc. + * sent from 4965 uCode to host driver). Unlike Tx, there is only one Rx + * queue, and only one Rx DMA/FIFO channel. Also unlike Tx, which can + * concatenate up to 20 DRAM buffers to form a Tx frame, each Receive Buffer + * Descriptor (RBD) points to only one Rx Buffer (RB); there is a 1:1 + * mapping between RBDs and RBs. + * + * Driver must allocate host DRAM memory for the following, and set the + * physical address of each into 4965 registers: + * + * 1) Receive Buffer Descriptor (RBD) circular buffer (CB), typically with 256 + * entries (although any power of 2, up to 4096, is selectable by driver). + * Each entry (1 dword) points to a receive buffer (RB) of consistent size + * (typically 4K, although 8K or 16K are also selectable by driver). + * Driver sets up RB size and number of RBDs in the CB via Rx config + * register FH_MEM_RCSR_CHNL0_CONFIG_REG. + * + * Bit fields within one RBD: + * 27-0: Receive Buffer physical address bits [35:8], 256-byte aligned + * + * Driver sets physical address [35:8] of base of RBD circular buffer + * into FH_RSCSR_CHNL0_RBDCB_BASE_REG [27:0]. + * + * 2) Rx status buffer, 8 bytes, in which 4965 indicates which Rx Buffers + * (RBs) have been filled, via a "write pointer", actually the index of + * the RB's corresponding RBD within the circular buffer. Driver sets + * physical address [35:4] into FH_RSCSR_CHNL0_STTS_WPTR_REG [31:0]. + * + * Bit fields in lower dword of Rx status buffer (upper dword not used + * by driver; see struct iwl4965_shared, val0): + * 31-12: Not used by driver + * 11- 0: Index of last filled Rx buffer descriptor + * (4965 writes, driver reads this value) + * + * As the driver prepares Receive Buffers (RBs) for 4965 to fill, driver must + * enter pointers to these RBs into contiguous RBD circular buffer entries, + * and update the 4965's "write" index register, + * FH_RSCSR_CHNL0_RBDCB_WPTR_REG. + * + * This "write" index corresponds to the *next* RBD that the driver will make + * available, i.e. one RBD past the tail of the ready-to-fill RBDs within + * the circular buffer. This value should initially be 0 (before preparing any + * RBs), should be 8 after preparing the first 8 RBs (for example), and must + * wrap back to 0 at the end of the circular buffer (but don't wrap before + * "read" index has advanced past 1! See below). + * NOTE: 4965 EXPECTS THE WRITE INDEX TO BE INCREMENTED IN MULTIPLES OF 8. + * + * As the 4965 fills RBs (referenced from contiguous RBDs within the circular + * buffer), it updates the Rx status buffer in host DRAM, 2) described above, + * to tell the driver the index of the latest filled RBD. The driver must + * read this "read" index from DRAM after receiving an Rx interrupt from 4965. + * + * The driver must also internally keep track of a third index, which is the + * next RBD to process. When receiving an Rx interrupt, driver should process + * all filled but unprocessed RBs up to, but not including, the RB + * corresponding to the "read" index. For example, if "read" index becomes "1", + * driver may process the RB pointed to by RBD 0. Depending on volume of + * traffic, there may be many RBs to process. + * + * If read index == write index, 4965 thinks there is no room to put new data. + * Due to this, the maximum number of filled RBs is 255, instead of 256. To + * be safe, make sure that there is a gap of at least 2 RBDs between "write" + * and "read" indexes; that is, make sure that there are no more than 254 + * buffers waiting to be filled. + */ +#define FH_MEM_RSCSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xBC0) +#define FH_MEM_RSCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xC00) +#define FH_MEM_RSCSR_CHNL0 (FH_MEM_RSCSR_LOWER_BOUND) + +/** + * Physical base address of 8-byte Rx Status buffer. + * Bit fields: + * 31-0: Rx status buffer physical base address [35:4], must 16-byte aligned. + */ +#define FH_RSCSR_CHNL0_STTS_WPTR_REG (FH_MEM_RSCSR_CHNL0) + +/** + * Physical base address of Rx Buffer Descriptor Circular Buffer. + * Bit fields: + * 27-0: RBD CD physical base address [35:8], must be 256-byte aligned. + */ +#define FH_RSCSR_CHNL0_RBDCB_BASE_REG (FH_MEM_RSCSR_CHNL0 + 0x004) + +/** + * Rx write pointer (index, really!). + * Bit fields: + * 11-0: Index of driver's most recent prepared-to-be-filled RBD, + 1. + * NOTE: For 256-entry circular buffer, use only bits [7:0]. + */ +#define FH_RSCSR_CHNL0_RBDCB_WPTR_REG (FH_MEM_RSCSR_CHNL0 + 0x008) +#define FH_RSCSR_CHNL0_WPTR (FH_RSCSR_CHNL0_RBDCB_WPTR_REG) + + +/** + * Rx Config/Status Registers (RCSR) + * Rx Config Reg for channel 0 (only channel used) + * + * Driver must initialize FH_MEM_RCSR_CHNL0_CONFIG_REG as follows for + * normal operation (see bit fields). + * + * Clearing FH_MEM_RCSR_CHNL0_CONFIG_REG to 0 turns off Rx DMA. + * Driver should poll FH_MEM_RSSR_RX_STATUS_REG for + * FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (bit 24) before continuing. + * + * Bit fields: + * 31-30: Rx DMA channel enable: '00' off/pause, '01' pause at end of frame, + * '10' operate normally + * 29-24: reserved + * 23-20: # RBDs in circular buffer = 2^value; use "8" for 256 RBDs (normal), + * min "5" for 32 RBDs, max "12" for 4096 RBDs. + * 19-18: reserved + * 17-16: size of each receive buffer; '00' 4K (normal), '01' 8K, + * '10' 12K, '11' 16K. + * 15-14: reserved + * 13-12: IRQ destination; '00' none, '01' host driver (normal operation) + * 11- 4: timeout for closing Rx buffer and interrupting host (units 32 usec) + * typical value 0x10 (about 1/2 msec) + * 3- 0: reserved + */ +#define FH_MEM_RCSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xC00) +#define FH_MEM_RCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xCC0) +#define FH_MEM_RCSR_CHNL0 (FH_MEM_RCSR_LOWER_BOUND) + +#define FH_MEM_RCSR_CHNL0_CONFIG_REG (FH_MEM_RCSR_CHNL0) + +#define FH_RCSR_CHNL0_RX_CONFIG_RB_TIMEOUT_MSK (0x00000FF0) /* bits 4-11 */ +#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_MSK (0x00001000) /* bits 12 */ +#define FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MSK (0x00008000) /* bit 15 */ +#define FH_RCSR_CHNL0_RX_CONFIG_RB_SIZE_MSK (0x00030000) /* bits 16-17 */ +#define FH_RCSR_CHNL0_RX_CONFIG_RBDBC_SIZE_MSK (0x00F00000) /* bits 20-23 */ +#define FH_RCSR_CHNL0_RX_CONFIG_DMA_CHNL_EN_MSK (0xC0000000) /* bits 30-31*/ + +#define FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS (20) +#define FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS (4) +#define RX_RB_TIMEOUT (0x10) + +#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_VAL (0x00000000) +#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_EOF_VAL (0x40000000) +#define FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL (0x80000000) + +#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K (0x00000000) +#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K (0x00010000) +#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_12K (0x00020000) +#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_16K (0x00030000) + +#define FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY (0x00000004) +#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL (0x00000000) +#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL (0x00001000) + +#define FH_RSCSR_FRAME_SIZE_MSK (0x00003FFF) /* bits 0-13 */ + +/** + * Rx Shared Status Registers (RSSR) + * + * After stopping Rx DMA channel (writing 0 to + * FH_MEM_RCSR_CHNL0_CONFIG_REG), driver must poll + * FH_MEM_RSSR_RX_STATUS_REG until Rx channel is idle. + * + * Bit fields: + * 24: 1 = Channel 0 is idle + * + * FH_MEM_RSSR_SHARED_CTRL_REG and FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV + * contain default values that should not be altered by the driver. + */ +#define FH_MEM_RSSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xC40) +#define FH_MEM_RSSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xD00) + +#define FH_MEM_RSSR_SHARED_CTRL_REG (FH_MEM_RSSR_LOWER_BOUND) +#define FH_MEM_RSSR_RX_STATUS_REG (FH_MEM_RSSR_LOWER_BOUND + 0x004) +#define FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV\ + (FH_MEM_RSSR_LOWER_BOUND + 0x008) + +#define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000) + +#define FH_MEM_TFDIB_REG1_ADDR_BITSHIFT 28 + +/* TFDB Area - TFDs buffer table */ +#define FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK (0xFFFFFFFF) +#define FH_TFDIB_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0x900) +#define FH_TFDIB_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0x958) +#define FH_TFDIB_CTRL0_REG(_chnl) (FH_TFDIB_LOWER_BOUND + 0x8 * (_chnl)) +#define FH_TFDIB_CTRL1_REG(_chnl) (FH_TFDIB_LOWER_BOUND + 0x8 * (_chnl) + 0x4) + +/** + * Transmit DMA Channel Control/Status Registers (TCSR) + * + * 4965 has one configuration register for each of 8 Tx DMA/FIFO channels + * supported in hardware (don't confuse these with the 16 Tx queues in DRAM, + * which feed the DMA/FIFO channels); config regs are separated by 0x20 bytes. + * + * To use a Tx DMA channel, driver must initialize its + * FH_TCSR_CHNL_TX_CONFIG_REG(chnl) with: + * + * FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | + * FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL + * + * All other bits should be 0. + * + * Bit fields: + * 31-30: Tx DMA channel enable: '00' off/pause, '01' pause at end of frame, + * '10' operate normally + * 29- 4: Reserved, set to "0" + * 3: Enable internal DMA requests (1, normal operation), disable (0) + * 2- 0: Reserved, set to "0" + */ +#define FH_TCSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xD00) +#define FH_TCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xE60) + +/* Find Control/Status reg for given Tx DMA/FIFO channel */ +#define FH49_TCSR_CHNL_NUM (7) +#define FH50_TCSR_CHNL_NUM (8) + +/* TCSR: tx_config register values */ +#define FH_TCSR_CHNL_TX_CONFIG_REG(_chnl) \ + (FH_TCSR_LOWER_BOUND + 0x20 * (_chnl)) +#define FH_TCSR_CHNL_TX_CREDIT_REG(_chnl) \ + (FH_TCSR_LOWER_BOUND + 0x20 * (_chnl) + 0x4) +#define FH_TCSR_CHNL_TX_BUF_STS_REG(_chnl) \ + (FH_TCSR_LOWER_BOUND + 0x20 * (_chnl) + 0x8) + +#define FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF (0x00000000) +#define FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRV (0x00000001) + +#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE (0x00000000) +#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE (0x00000008) + +#define FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_NOINT (0x00000000) +#define FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD (0x00100000) +#define FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD (0x00200000) + +#define FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT (0x00000000) +#define FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_ENDTFD (0x00400000) +#define FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_IFTFD (0x00800000) + +#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000) +#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE_EOF (0x40000000) +#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000) + +#define FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_EMPTY (0x00000000) +#define FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_WAIT (0x00002000) +#define FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID (0x00000003) + +#define FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM (20) +#define FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX (12) + +/** + * Tx Shared Status Registers (TSSR) + * + * After stopping Tx DMA channel (writing 0 to + * FH_TCSR_CHNL_TX_CONFIG_REG(chnl)), driver must poll + * FH_TSSR_TX_STATUS_REG until selected Tx channel is idle + * (channel's buffers empty | no pending requests). + * + * Bit fields: + * 31-24: 1 = Channel buffers empty (channel 7:0) + * 23-16: 1 = No pending requests (channel 7:0) + */ +#define FH_TSSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xEA0) +#define FH_TSSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xEC0) + +#define FH_TSSR_TX_STATUS_REG (FH_TSSR_LOWER_BOUND + 0x010) + +/** + * Bit fields for TSSR(Tx Shared Status & Control) error status register: + * 31: Indicates an address error when accessed to internal memory + * uCode/driver must write "1" in order to clear this flag + * 30: Indicates that Host did not send the expected number of dwords to FH + * uCode/driver must write "1" in order to clear this flag + * 16-9:Each status bit is for one channel. Indicates that an (Error) ActDMA + * command was received from the scheduler while the TRB was already full + * with previous command + * uCode/driver must write "1" in order to clear this flag + * 7-0: Each status bit indicates a channel's TxCredit error. When an error + * bit is set, it indicates that the FH has received a full indication + * from the RTC TxFIFO and the current value of the TxCredit counter was + * not equal to zero. This mean that the credit mechanism was not + * synchronized to the TxFIFO status + * uCode/driver must write "1" in order to clear this flag + */ +#define FH_TSSR_TX_ERROR_REG (FH_TSSR_LOWER_BOUND + 0x018) + +#define FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_chnl) ((1 << (_chnl)) << 16) + +/* Tx service channels */ +#define FH_SRVC_CHNL (9) +#define FH_SRVC_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0x9C8) +#define FH_SRVC_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0x9D0) +#define FH_SRVC_CHNL_SRAM_ADDR_REG(_chnl) \ + (FH_SRVC_LOWER_BOUND + ((_chnl) - 9) * 0x4) + +#define FH_TX_CHICKEN_BITS_REG (FH_MEM_LOWER_BOUND + 0xE98) +/* Instruct FH to increment the retry count of a packet when + * it is brought from the memory to TX-FIFO + */ +#define FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN (0x00000002) + +#define RX_QUEUE_SIZE 256 +#define RX_QUEUE_MASK 255 +#define RX_QUEUE_SIZE_LOG 8 + +/* + * RX related structures and functions + */ +#define RX_FREE_BUFFERS 64 +#define RX_LOW_WATERMARK 8 + +/* Size of one Rx buffer in host DRAM */ +#define IWL_RX_BUF_SIZE_3K (3 * 1000) /* 3945 only */ +#define IWL_RX_BUF_SIZE_4K (4 * 1024) +#define IWL_RX_BUF_SIZE_8K (8 * 1024) + +/** + * struct iwl_rb_status - reseve buffer status + * host memory mapped FH registers + * @closed_rb_num [0:11] - Indicates the index of the RB which was closed + * @closed_fr_num [0:11] - Indicates the index of the RX Frame which was closed + * @finished_rb_num [0:11] - Indicates the index of the current RB + * in which the last frame was written to + * @finished_fr_num [0:11] - Indicates the index of the RX Frame + * which was transfered + */ +struct iwl_rb_status { + __le16 closed_rb_num; + __le16 closed_fr_num; + __le16 finished_rb_num; + __le16 finished_fr_nam; + __le32 __unused; /* 3945 only */ +} __packed; + + +#define TFD_QUEUE_SIZE_MAX (256) +#define TFD_QUEUE_SIZE_BC_DUP (64) +#define TFD_QUEUE_BC_SIZE (TFD_QUEUE_SIZE_MAX + TFD_QUEUE_SIZE_BC_DUP) +#define IWL_TX_DMA_MASK DMA_BIT_MASK(36) +#define IWL_NUM_OF_TBS 20 + +static inline u8 iwl_legacy_get_dma_hi_addr(dma_addr_t addr) +{ + return (sizeof(addr) > sizeof(u32) ? (addr >> 16) >> 16 : 0) & 0xF; +} +/** + * struct iwl_tfd_tb transmit buffer descriptor within transmit frame descriptor + * + * This structure contains dma address and length of transmission address + * + * @lo: low [31:0] portion of the dma address of TX buffer + * every even is unaligned on 16 bit boundary + * @hi_n_len 0-3 [35:32] portion of dma + * 4-15 length of the tx buffer + */ +struct iwl_tfd_tb { + __le32 lo; + __le16 hi_n_len; +} __packed; + +/** + * struct iwl_tfd + * + * Transmit Frame Descriptor (TFD) + * + * @ __reserved1[3] reserved + * @ num_tbs 0-4 number of active tbs + * 5 reserved + * 6-7 padding (not used) + * @ tbs[20] transmit frame buffer descriptors + * @ __pad padding + * + * Each Tx queue uses a circular buffer of 256 TFDs stored in host DRAM. + * Both driver and device share these circular buffers, each of which must be + * contiguous 256 TFDs x 128 bytes-per-TFD = 32 KBytes + * + * Driver must indicate the physical address of the base of each + * circular buffer via the FH_MEM_CBBC_QUEUE registers. + * + * Each TFD contains pointer/size information for up to 20 data buffers + * in host DRAM. These buffers collectively contain the (one) frame described + * by the TFD. Each buffer must be a single contiguous block of memory within + * itself, but buffers may be scattered in host DRAM. Each buffer has max size + * of (4K - 4). The concatenates all of a TFD's buffers into a single + * Tx frame, up to 8 KBytes in size. + * + * A maximum of 255 (not 256!) TFDs may be on a queue waiting for Tx. + */ +struct iwl_tfd { + u8 __reserved1[3]; + u8 num_tbs; + struct iwl_tfd_tb tbs[IWL_NUM_OF_TBS]; + __le32 __pad; +} __packed; + +/* Keep Warm Size */ +#define IWL_KW_SIZE 0x1000 /* 4k */ + +#endif /* !__iwl_legacy_fh_h__ */ diff --git a/drivers/net/wireless/iwlegacy/iwl-hcmd.c b/drivers/net/wireless/iwlegacy/iwl-hcmd.c new file mode 100644 index 000000000000..9d721cbda5bb --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-hcmd.c @@ -0,0 +1,271 @@ +/****************************************************************************** + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ + +#include +#include +#include +#include + +#include "iwl-dev.h" +#include "iwl-debug.h" +#include "iwl-eeprom.h" +#include "iwl-core.h" + + +const char *iwl_legacy_get_cmd_string(u8 cmd) +{ + switch (cmd) { + IWL_CMD(REPLY_ALIVE); + IWL_CMD(REPLY_ERROR); + IWL_CMD(REPLY_RXON); + IWL_CMD(REPLY_RXON_ASSOC); + IWL_CMD(REPLY_QOS_PARAM); + IWL_CMD(REPLY_RXON_TIMING); + IWL_CMD(REPLY_ADD_STA); + IWL_CMD(REPLY_REMOVE_STA); + IWL_CMD(REPLY_WEPKEY); + IWL_CMD(REPLY_3945_RX); + IWL_CMD(REPLY_TX); + IWL_CMD(REPLY_RATE_SCALE); + IWL_CMD(REPLY_LEDS_CMD); + IWL_CMD(REPLY_TX_LINK_QUALITY_CMD); + IWL_CMD(REPLY_CHANNEL_SWITCH); + IWL_CMD(CHANNEL_SWITCH_NOTIFICATION); + IWL_CMD(REPLY_SPECTRUM_MEASUREMENT_CMD); + IWL_CMD(SPECTRUM_MEASURE_NOTIFICATION); + IWL_CMD(POWER_TABLE_CMD); + IWL_CMD(PM_SLEEP_NOTIFICATION); + IWL_CMD(PM_DEBUG_STATISTIC_NOTIFIC); + IWL_CMD(REPLY_SCAN_CMD); + IWL_CMD(REPLY_SCAN_ABORT_CMD); + IWL_CMD(SCAN_START_NOTIFICATION); + IWL_CMD(SCAN_RESULTS_NOTIFICATION); + IWL_CMD(SCAN_COMPLETE_NOTIFICATION); + IWL_CMD(BEACON_NOTIFICATION); + IWL_CMD(REPLY_TX_BEACON); + IWL_CMD(REPLY_TX_PWR_TABLE_CMD); + IWL_CMD(REPLY_BT_CONFIG); + IWL_CMD(REPLY_STATISTICS_CMD); + IWL_CMD(STATISTICS_NOTIFICATION); + IWL_CMD(CARD_STATE_NOTIFICATION); + IWL_CMD(MISSED_BEACONS_NOTIFICATION); + IWL_CMD(REPLY_CT_KILL_CONFIG_CMD); + IWL_CMD(SENSITIVITY_CMD); + IWL_CMD(REPLY_PHY_CALIBRATION_CMD); + IWL_CMD(REPLY_RX_PHY_CMD); + IWL_CMD(REPLY_RX_MPDU_CMD); + IWL_CMD(REPLY_RX); + IWL_CMD(REPLY_COMPRESSED_BA); + default: + return "UNKNOWN"; + + } +} +EXPORT_SYMBOL(iwl_legacy_get_cmd_string); + +#define HOST_COMPLETE_TIMEOUT (HZ / 2) + +static void iwl_legacy_generic_cmd_callback(struct iwl_priv *priv, + struct iwl_device_cmd *cmd, + struct iwl_rx_packet *pkt) +{ + if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { + IWL_ERR(priv, "Bad return from %s (0x%08X)\n", + iwl_legacy_get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); + return; + } + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + switch (cmd->hdr.cmd) { + case REPLY_TX_LINK_QUALITY_CMD: + case SENSITIVITY_CMD: + IWL_DEBUG_HC_DUMP(priv, "back from %s (0x%08X)\n", + iwl_legacy_get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); + break; + default: + IWL_DEBUG_HC(priv, "back from %s (0x%08X)\n", + iwl_legacy_get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); + } +#endif +} + +static int +iwl_legacy_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd) +{ + int ret; + + BUG_ON(!(cmd->flags & CMD_ASYNC)); + + /* An asynchronous command can not expect an SKB to be set. */ + BUG_ON(cmd->flags & CMD_WANT_SKB); + + /* Assign a generic callback if one is not provided */ + if (!cmd->callback) + cmd->callback = iwl_legacy_generic_cmd_callback; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return -EBUSY; + + ret = iwl_legacy_enqueue_hcmd(priv, cmd); + if (ret < 0) { + IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n", + iwl_legacy_get_cmd_string(cmd->id), ret); + return ret; + } + return 0; +} + +int iwl_legacy_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) +{ + int cmd_idx; + int ret; + + BUG_ON(cmd->flags & CMD_ASYNC); + + /* A synchronous command can not have a callback set. */ + BUG_ON(cmd->callback); + + IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", + iwl_legacy_get_cmd_string(cmd->id)); + mutex_lock(&priv->sync_cmd_mutex); + + set_bit(STATUS_HCMD_ACTIVE, &priv->status); + IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n", + iwl_legacy_get_cmd_string(cmd->id)); + + cmd_idx = iwl_legacy_enqueue_hcmd(priv, cmd); + if (cmd_idx < 0) { + ret = cmd_idx; + IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n", + iwl_legacy_get_cmd_string(cmd->id), ret); + goto out; + } + + ret = wait_event_interruptible_timeout(priv->wait_command_queue, + !test_bit(STATUS_HCMD_ACTIVE, &priv->status), + HOST_COMPLETE_TIMEOUT); + if (!ret) { + if (test_bit(STATUS_HCMD_ACTIVE, &priv->status)) { + IWL_ERR(priv, + "Error sending %s: time out after %dms.\n", + iwl_legacy_get_cmd_string(cmd->id), + jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); + + clear_bit(STATUS_HCMD_ACTIVE, &priv->status); + IWL_DEBUG_INFO(priv, + "Clearing HCMD_ACTIVE for command %s\n", + iwl_legacy_get_cmd_string(cmd->id)); + ret = -ETIMEDOUT; + goto cancel; + } + } + + if (test_bit(STATUS_RF_KILL_HW, &priv->status)) { + IWL_ERR(priv, "Command %s aborted: RF KILL Switch\n", + iwl_legacy_get_cmd_string(cmd->id)); + ret = -ECANCELED; + goto fail; + } + if (test_bit(STATUS_FW_ERROR, &priv->status)) { + IWL_ERR(priv, "Command %s failed: FW Error\n", + iwl_legacy_get_cmd_string(cmd->id)); + ret = -EIO; + goto fail; + } + if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) { + IWL_ERR(priv, "Error: Response NULL in '%s'\n", + iwl_legacy_get_cmd_string(cmd->id)); + ret = -EIO; + goto cancel; + } + + ret = 0; + goto out; + +cancel: + if (cmd->flags & CMD_WANT_SKB) { + /* + * Cancel the CMD_WANT_SKB flag for the cmd in the + * TX cmd queue. Otherwise in case the cmd comes + * in later, it will possibly set an invalid + * address (cmd->meta.source). + */ + priv->txq[priv->cmd_queue].meta[cmd_idx].flags &= + ~CMD_WANT_SKB; + } +fail: + if (cmd->reply_page) { + iwl_legacy_free_pages(priv, cmd->reply_page); + cmd->reply_page = 0; + } +out: + mutex_unlock(&priv->sync_cmd_mutex); + return ret; +} +EXPORT_SYMBOL(iwl_legacy_send_cmd_sync); + +int iwl_legacy_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) +{ + if (cmd->flags & CMD_ASYNC) + return iwl_legacy_send_cmd_async(priv, cmd); + + return iwl_legacy_send_cmd_sync(priv, cmd); +} +EXPORT_SYMBOL(iwl_legacy_send_cmd); + +int +iwl_legacy_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data) +{ + struct iwl_host_cmd cmd = { + .id = id, + .len = len, + .data = data, + }; + + return iwl_legacy_send_cmd_sync(priv, &cmd); +} +EXPORT_SYMBOL(iwl_legacy_send_cmd_pdu); + +int iwl_legacy_send_cmd_pdu_async(struct iwl_priv *priv, + u8 id, u16 len, const void *data, + void (*callback)(struct iwl_priv *priv, + struct iwl_device_cmd *cmd, + struct iwl_rx_packet *pkt)) +{ + struct iwl_host_cmd cmd = { + .id = id, + .len = len, + .data = data, + }; + + cmd.flags |= CMD_ASYNC; + cmd.callback = callback; + + return iwl_legacy_send_cmd_async(priv, &cmd); +} +EXPORT_SYMBOL(iwl_legacy_send_cmd_pdu_async); diff --git a/drivers/net/wireless/iwlegacy/iwl-helpers.h b/drivers/net/wireless/iwlegacy/iwl-helpers.h new file mode 100644 index 000000000000..02132e755831 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-helpers.h @@ -0,0 +1,181 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#ifndef __iwl_legacy_helpers_h__ +#define __iwl_legacy_helpers_h__ + +#include +#include + +#include "iwl-io.h" + +#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) + + +static inline struct ieee80211_conf *iwl_legacy_ieee80211_get_hw_conf( + struct ieee80211_hw *hw) +{ + return &hw->conf; +} + +/** + * iwl_legacy_queue_inc_wrap - increment queue index, wrap back to beginning + * @index -- current index + * @n_bd -- total number of entries in queue (must be power of 2) + */ +static inline int iwl_legacy_queue_inc_wrap(int index, int n_bd) +{ + return ++index & (n_bd - 1); +} + +/** + * iwl_legacy_queue_dec_wrap - decrement queue index, wrap back to end + * @index -- current index + * @n_bd -- total number of entries in queue (must be power of 2) + */ +static inline int iwl_legacy_queue_dec_wrap(int index, int n_bd) +{ + return --index & (n_bd - 1); +} + +/* TODO: Move fw_desc functions to iwl-pci.ko */ +static inline void iwl_legacy_free_fw_desc(struct pci_dev *pci_dev, + struct fw_desc *desc) +{ + if (desc->v_addr) + dma_free_coherent(&pci_dev->dev, desc->len, + desc->v_addr, desc->p_addr); + desc->v_addr = NULL; + desc->len = 0; +} + +static inline int iwl_legacy_alloc_fw_desc(struct pci_dev *pci_dev, + struct fw_desc *desc) +{ + if (!desc->len) { + desc->v_addr = NULL; + return -EINVAL; + } + + desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len, + &desc->p_addr, GFP_KERNEL); + return (desc->v_addr != NULL) ? 0 : -ENOMEM; +} + +/* + * we have 8 bits used like this: + * + * 7 6 5 4 3 2 1 0 + * | | | | | | | | + * | | | | | | +-+-------- AC queue (0-3) + * | | | | | | + * | +-+-+-+-+------------ HW queue ID + * | + * +---------------------- unused + */ +static inline void +iwl_legacy_set_swq_id(struct iwl_tx_queue *txq, u8 ac, u8 hwq) +{ + BUG_ON(ac > 3); /* only have 2 bits */ + BUG_ON(hwq > 31); /* only use 5 bits */ + + txq->swq_id = (hwq << 2) | ac; +} + +static inline void iwl_legacy_wake_queue(struct iwl_priv *priv, + struct iwl_tx_queue *txq) +{ + u8 queue = txq->swq_id; + u8 ac = queue & 3; + u8 hwq = (queue >> 2) & 0x1f; + + if (test_and_clear_bit(hwq, priv->queue_stopped)) + if (atomic_dec_return(&priv->queue_stop_count[ac]) <= 0) + ieee80211_wake_queue(priv->hw, ac); +} + +static inline void iwl_legacy_stop_queue(struct iwl_priv *priv, + struct iwl_tx_queue *txq) +{ + u8 queue = txq->swq_id; + u8 ac = queue & 3; + u8 hwq = (queue >> 2) & 0x1f; + + if (!test_and_set_bit(hwq, priv->queue_stopped)) + if (atomic_inc_return(&priv->queue_stop_count[ac]) > 0) + ieee80211_stop_queue(priv->hw, ac); +} + +#define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue +#define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue + +static inline void iwl_legacy_disable_interrupts(struct iwl_priv *priv) +{ + clear_bit(STATUS_INT_ENABLED, &priv->status); + + /* disable interrupts from uCode/NIC to host */ + iwl_write32(priv, CSR_INT_MASK, 0x00000000); + + /* acknowledge/clear/reset any interrupts still pending + * from uCode or flow handler (Rx/Tx DMA) */ + iwl_write32(priv, CSR_INT, 0xffffffff); + iwl_write32(priv, CSR_FH_INT_STATUS, 0xffffffff); + IWL_DEBUG_ISR(priv, "Disabled interrupts\n"); +} + +static inline void iwl_legacy_enable_interrupts(struct iwl_priv *priv) +{ + IWL_DEBUG_ISR(priv, "Enabling interrupts\n"); + set_bit(STATUS_INT_ENABLED, &priv->status); + iwl_write32(priv, CSR_INT_MASK, priv->inta_mask); +} + +/** + * iwl_legacy_beacon_time_mask_low - mask of lower 32 bit of beacon time + * @priv -- pointer to iwl_priv data structure + * @tsf_bits -- number of bits need to shift for masking) + */ +static inline u32 iwl_legacy_beacon_time_mask_low(struct iwl_priv *priv, + u16 tsf_bits) +{ + return (1 << tsf_bits) - 1; +} + +/** + * iwl_legacy_beacon_time_mask_high - mask of higher 32 bit of beacon time + * @priv -- pointer to iwl_priv data structure + * @tsf_bits -- number of bits need to shift for masking) + */ +static inline u32 iwl_legacy_beacon_time_mask_high(struct iwl_priv *priv, + u16 tsf_bits) +{ + return ((1 << (32 - tsf_bits)) - 1) << tsf_bits; +} + +#endif /* __iwl_legacy_helpers_h__ */ diff --git a/drivers/net/wireless/iwlegacy/iwl-io.h b/drivers/net/wireless/iwlegacy/iwl-io.h new file mode 100644 index 000000000000..5cc5d342914f --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-io.h @@ -0,0 +1,545 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#ifndef __iwl_legacy_io_h__ +#define __iwl_legacy_io_h__ + +#include + +#include "iwl-dev.h" +#include "iwl-debug.h" +#include "iwl-devtrace.h" + +/* + * IO, register, and NIC memory access functions + * + * NOTE on naming convention and macro usage for these + * + * A single _ prefix before a an access function means that no state + * check or debug information is printed when that function is called. + * + * A double __ prefix before an access function means that state is checked + * and the current line number and caller function name are printed in addition + * to any other debug output. + * + * The non-prefixed name is the #define that maps the caller into a + * #define that provides the caller's name and __LINE__ to the double + * prefix version. + * + * If you wish to call the function without any debug or state checking, + * you should use the single _ prefix version (as is used by dependent IO + * routines, for example _iwl_legacy_read_direct32 calls the non-check version of + * _iwl_legacy_read32.) + * + * These declarations are *extremely* useful in quickly isolating code deltas + * which result in misconfiguration of the hardware I/O. In combination with + * git-bisect and the IO debug level you can quickly determine the specific + * commit which breaks the IO sequence to the hardware. + * + */ + +static inline void _iwl_legacy_write8(struct iwl_priv *priv, u32 ofs, u8 val) +{ + trace_iwlwifi_legacy_dev_iowrite8(priv, ofs, val); + iowrite8(val, priv->hw_base + ofs); +} + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +static inline void +__iwl_legacy_write8(const char *f, u32 l, struct iwl_priv *priv, + u32 ofs, u8 val) +{ + IWL_DEBUG_IO(priv, "write8(0x%08X, 0x%02X) - %s %d\n", ofs, val, f, l); + _iwl_legacy_write8(priv, ofs, val); +} +#define iwl_write8(priv, ofs, val) \ + __iwl_legacy_write8(__FILE__, __LINE__, priv, ofs, val) +#else +#define iwl_write8(priv, ofs, val) _iwl_legacy_write8(priv, ofs, val) +#endif + + +static inline void _iwl_legacy_write32(struct iwl_priv *priv, u32 ofs, u32 val) +{ + trace_iwlwifi_legacy_dev_iowrite32(priv, ofs, val); + iowrite32(val, priv->hw_base + ofs); +} + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +static inline void +__iwl_legacy_write32(const char *f, u32 l, struct iwl_priv *priv, + u32 ofs, u32 val) +{ + IWL_DEBUG_IO(priv, "write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l); + _iwl_legacy_write32(priv, ofs, val); +} +#define iwl_write32(priv, ofs, val) \ + __iwl_legacy_write32(__FILE__, __LINE__, priv, ofs, val) +#else +#define iwl_write32(priv, ofs, val) _iwl_legacy_write32(priv, ofs, val) +#endif + +static inline u32 _iwl_legacy_read32(struct iwl_priv *priv, u32 ofs) +{ + u32 val = ioread32(priv->hw_base + ofs); + trace_iwlwifi_legacy_dev_ioread32(priv, ofs, val); + return val; +} + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +static inline u32 +__iwl_legacy_read32(char *f, u32 l, struct iwl_priv *priv, u32 ofs) +{ + IWL_DEBUG_IO(priv, "read_direct32(0x%08X) - %s %d\n", ofs, f, l); + return _iwl_legacy_read32(priv, ofs); +} +#define iwl_read32(priv, ofs) __iwl_legacy_read32(__FILE__, __LINE__, priv, ofs) +#else +#define iwl_read32(p, o) _iwl_legacy_read32(p, o) +#endif + +#define IWL_POLL_INTERVAL 10 /* microseconds */ +static inline int +_iwl_legacy_poll_bit(struct iwl_priv *priv, u32 addr, + u32 bits, u32 mask, int timeout) +{ + int t = 0; + + do { + if ((_iwl_legacy_read32(priv, addr) & mask) == (bits & mask)) + return t; + udelay(IWL_POLL_INTERVAL); + t += IWL_POLL_INTERVAL; + } while (t < timeout); + + return -ETIMEDOUT; +} +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +static inline int __iwl_legacy_poll_bit(const char *f, u32 l, + struct iwl_priv *priv, u32 addr, + u32 bits, u32 mask, int timeout) +{ + int ret = _iwl_legacy_poll_bit(priv, addr, bits, mask, timeout); + IWL_DEBUG_IO(priv, "poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n", + addr, bits, mask, + unlikely(ret == -ETIMEDOUT) ? "timeout" : "", f, l); + return ret; +} +#define iwl_poll_bit(priv, addr, bits, mask, timeout) \ + __iwl_legacy_poll_bit(__FILE__, __LINE__, priv, addr, \ + bits, mask, timeout) +#else +#define iwl_poll_bit(p, a, b, m, t) _iwl_legacy_poll_bit(p, a, b, m, t) +#endif + +static inline void _iwl_legacy_set_bit(struct iwl_priv *priv, u32 reg, u32 mask) +{ + _iwl_legacy_write32(priv, reg, _iwl_legacy_read32(priv, reg) | mask); +} +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +static inline void __iwl_legacy_set_bit(const char *f, u32 l, + struct iwl_priv *priv, u32 reg, u32 mask) +{ + u32 val = _iwl_legacy_read32(priv, reg) | mask; + IWL_DEBUG_IO(priv, "set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, + mask, val); + _iwl_legacy_write32(priv, reg, val); +} +static inline void iwl_legacy_set_bit(struct iwl_priv *p, u32 r, u32 m) +{ + unsigned long reg_flags; + + spin_lock_irqsave(&p->reg_lock, reg_flags); + __iwl_legacy_set_bit(__FILE__, __LINE__, p, r, m); + spin_unlock_irqrestore(&p->reg_lock, reg_flags); +} +#else +static inline void iwl_legacy_set_bit(struct iwl_priv *p, u32 r, u32 m) +{ + unsigned long reg_flags; + + spin_lock_irqsave(&p->reg_lock, reg_flags); + _iwl_legacy_set_bit(p, r, m); + spin_unlock_irqrestore(&p->reg_lock, reg_flags); +} +#endif + +static inline void +_iwl_legacy_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask) +{ + _iwl_legacy_write32(priv, reg, _iwl_legacy_read32(priv, reg) & ~mask); +} +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +static inline void +__iwl_legacy_clear_bit(const char *f, u32 l, + struct iwl_priv *priv, u32 reg, u32 mask) +{ + u32 val = _iwl_legacy_read32(priv, reg) & ~mask; + IWL_DEBUG_IO(priv, "clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val); + _iwl_legacy_write32(priv, reg, val); +} +static inline void iwl_legacy_clear_bit(struct iwl_priv *p, u32 r, u32 m) +{ + unsigned long reg_flags; + + spin_lock_irqsave(&p->reg_lock, reg_flags); + __iwl_legacy_clear_bit(__FILE__, __LINE__, p, r, m); + spin_unlock_irqrestore(&p->reg_lock, reg_flags); +} +#else +static inline void iwl_legacy_clear_bit(struct iwl_priv *p, u32 r, u32 m) +{ + unsigned long reg_flags; + + spin_lock_irqsave(&p->reg_lock, reg_flags); + _iwl_legacy_clear_bit(p, r, m); + spin_unlock_irqrestore(&p->reg_lock, reg_flags); +} +#endif + +static inline int _iwl_legacy_grab_nic_access(struct iwl_priv *priv) +{ + int ret; + u32 val; + + /* this bit wakes up the NIC */ + _iwl_legacy_set_bit(priv, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + + /* + * These bits say the device is running, and should keep running for + * at least a short while (at least as long as MAC_ACCESS_REQ stays 1), + * but they do not indicate that embedded SRAM is restored yet; + * 3945 and 4965 have volatile SRAM, and must save/restore contents + * to/from host DRAM when sleeping/waking for power-saving. + * Each direction takes approximately 1/4 millisecond; with this + * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a + * series of register accesses are expected (e.g. reading Event Log), + * to keep device from sleeping. + * + * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that + * SRAM is okay/restored. We don't check that here because this call + * is just for hardware register access; but GP1 MAC_SLEEP check is a + * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log). + * + */ + ret = _iwl_legacy_poll_bit(priv, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, + (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | + CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); + if (ret < 0) { + val = _iwl_legacy_read32(priv, CSR_GP_CNTRL); + IWL_ERR(priv, + "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val); + _iwl_legacy_write32(priv, CSR_RESET, + CSR_RESET_REG_FLAG_FORCE_NMI); + return -EIO; + } + + return 0; +} + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +static inline int __iwl_legacy_grab_nic_access(const char *f, u32 l, + struct iwl_priv *priv) +{ + IWL_DEBUG_IO(priv, "grabbing nic access - %s %d\n", f, l); + return _iwl_legacy_grab_nic_access(priv); +} +#define iwl_grab_nic_access(priv) \ + __iwl_legacy_grab_nic_access(__FILE__, __LINE__, priv) +#else +#define iwl_grab_nic_access(priv) \ + _iwl_legacy_grab_nic_access(priv) +#endif + +static inline void _iwl_legacy_release_nic_access(struct iwl_priv *priv) +{ + _iwl_legacy_clear_bit(priv, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); +} +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +static inline void __iwl_legacy_release_nic_access(const char *f, u32 l, + struct iwl_priv *priv) +{ + + IWL_DEBUG_IO(priv, "releasing nic access - %s %d\n", f, l); + _iwl_legacy_release_nic_access(priv); +} +#define iwl_release_nic_access(priv) \ + __iwl_legacy_release_nic_access(__FILE__, __LINE__, priv) +#else +#define iwl_release_nic_access(priv) \ + _iwl_legacy_release_nic_access(priv) +#endif + +static inline u32 _iwl_legacy_read_direct32(struct iwl_priv *priv, u32 reg) +{ + return _iwl_legacy_read32(priv, reg); +} +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +static inline u32 __iwl_legacy_read_direct32(const char *f, u32 l, + struct iwl_priv *priv, u32 reg) +{ + u32 value = _iwl_legacy_read_direct32(priv, reg); + IWL_DEBUG_IO(priv, + "read_direct32(0x%4X) = 0x%08x - %s %d\n", reg, value, + f, l); + return value; +} +static inline u32 iwl_legacy_read_direct32(struct iwl_priv *priv, u32 reg) +{ + u32 value; + unsigned long reg_flags; + + spin_lock_irqsave(&priv->reg_lock, reg_flags); + iwl_grab_nic_access(priv); + value = __iwl_legacy_read_direct32(__FILE__, __LINE__, priv, reg); + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); + return value; +} + +#else +static inline u32 iwl_legacy_read_direct32(struct iwl_priv *priv, u32 reg) +{ + u32 value; + unsigned long reg_flags; + + spin_lock_irqsave(&priv->reg_lock, reg_flags); + iwl_grab_nic_access(priv); + value = _iwl_legacy_read_direct32(priv, reg); + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); + return value; + +} +#endif + +static inline void _iwl_legacy_write_direct32(struct iwl_priv *priv, + u32 reg, u32 value) +{ + _iwl_legacy_write32(priv, reg, value); +} +static inline void +iwl_legacy_write_direct32(struct iwl_priv *priv, u32 reg, u32 value) +{ + unsigned long reg_flags; + + spin_lock_irqsave(&priv->reg_lock, reg_flags); + if (!iwl_grab_nic_access(priv)) { + _iwl_legacy_write_direct32(priv, reg, value); + iwl_release_nic_access(priv); + } + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); +} + +static inline void iwl_legacy_write_reg_buf(struct iwl_priv *priv, + u32 reg, u32 len, u32 *values) +{ + u32 count = sizeof(u32); + + if ((priv != NULL) && (values != NULL)) { + for (; 0 < len; len -= count, reg += count, values++) + iwl_legacy_write_direct32(priv, reg, *values); + } +} + +static inline int _iwl_legacy_poll_direct_bit(struct iwl_priv *priv, u32 addr, + u32 mask, int timeout) +{ + int t = 0; + + do { + if ((iwl_legacy_read_direct32(priv, addr) & mask) == mask) + return t; + udelay(IWL_POLL_INTERVAL); + t += IWL_POLL_INTERVAL; + } while (t < timeout); + + return -ETIMEDOUT; +} + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +static inline int __iwl_legacy_poll_direct_bit(const char *f, u32 l, + struct iwl_priv *priv, + u32 addr, u32 mask, int timeout) +{ + int ret = _iwl_legacy_poll_direct_bit(priv, addr, mask, timeout); + + if (unlikely(ret == -ETIMEDOUT)) + IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) - " + "timedout - %s %d\n", addr, mask, f, l); + else + IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) = 0x%08X " + "- %s %d\n", addr, mask, ret, f, l); + return ret; +} +#define iwl_poll_direct_bit(priv, addr, mask, timeout) \ +__iwl_legacy_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout) +#else +#define iwl_poll_direct_bit _iwl_legacy_poll_direct_bit +#endif + +static inline u32 _iwl_legacy_read_prph(struct iwl_priv *priv, u32 reg) +{ + _iwl_legacy_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); + rmb(); + return _iwl_legacy_read_direct32(priv, HBUS_TARG_PRPH_RDAT); +} +static inline u32 iwl_legacy_read_prph(struct iwl_priv *priv, u32 reg) +{ + unsigned long reg_flags; + u32 val; + + spin_lock_irqsave(&priv->reg_lock, reg_flags); + iwl_grab_nic_access(priv); + val = _iwl_legacy_read_prph(priv, reg); + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); + return val; +} + +static inline void _iwl_legacy_write_prph(struct iwl_priv *priv, + u32 addr, u32 val) +{ + _iwl_legacy_write_direct32(priv, HBUS_TARG_PRPH_WADDR, + ((addr & 0x0000FFFF) | (3 << 24))); + wmb(); + _iwl_legacy_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val); +} + +static inline void +iwl_legacy_write_prph(struct iwl_priv *priv, u32 addr, u32 val) +{ + unsigned long reg_flags; + + spin_lock_irqsave(&priv->reg_lock, reg_flags); + if (!iwl_grab_nic_access(priv)) { + _iwl_legacy_write_prph(priv, addr, val); + iwl_release_nic_access(priv); + } + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); +} + +#define _iwl_legacy_set_bits_prph(priv, reg, mask) \ +_iwl_legacy_write_prph(priv, reg, (_iwl_legacy_read_prph(priv, reg) | mask)) + +static inline void +iwl_legacy_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask) +{ + unsigned long reg_flags; + + spin_lock_irqsave(&priv->reg_lock, reg_flags); + iwl_grab_nic_access(priv); + _iwl_legacy_set_bits_prph(priv, reg, mask); + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); +} + +#define _iwl_legacy_set_bits_mask_prph(priv, reg, bits, mask) \ +_iwl_legacy_write_prph(priv, reg, \ + ((_iwl_legacy_read_prph(priv, reg) & mask) | bits)) + +static inline void iwl_legacy_set_bits_mask_prph(struct iwl_priv *priv, u32 reg, + u32 bits, u32 mask) +{ + unsigned long reg_flags; + + spin_lock_irqsave(&priv->reg_lock, reg_flags); + iwl_grab_nic_access(priv); + _iwl_legacy_set_bits_mask_prph(priv, reg, bits, mask); + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); +} + +static inline void iwl_legacy_clear_bits_prph(struct iwl_priv + *priv, u32 reg, u32 mask) +{ + unsigned long reg_flags; + u32 val; + + spin_lock_irqsave(&priv->reg_lock, reg_flags); + iwl_grab_nic_access(priv); + val = _iwl_legacy_read_prph(priv, reg); + _iwl_legacy_write_prph(priv, reg, (val & ~mask)); + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); +} + +static inline u32 iwl_legacy_read_targ_mem(struct iwl_priv *priv, u32 addr) +{ + unsigned long reg_flags; + u32 value; + + spin_lock_irqsave(&priv->reg_lock, reg_flags); + iwl_grab_nic_access(priv); + + _iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr); + rmb(); + value = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); + + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); + return value; +} + +static inline void +iwl_legacy_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val) +{ + unsigned long reg_flags; + + spin_lock_irqsave(&priv->reg_lock, reg_flags); + if (!iwl_grab_nic_access(priv)) { + _iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr); + wmb(); + _iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_WDAT, val); + iwl_release_nic_access(priv); + } + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); +} + +static inline void +iwl_legacy_write_targ_mem_buf(struct iwl_priv *priv, u32 addr, + u32 len, u32 *values) +{ + unsigned long reg_flags; + + spin_lock_irqsave(&priv->reg_lock, reg_flags); + if (!iwl_grab_nic_access(priv)) { + _iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr); + wmb(); + for (; 0 < len; len -= sizeof(u32), values++) + _iwl_legacy_write_direct32(priv, + HBUS_TARG_MEM_WDAT, *values); + + iwl_release_nic_access(priv); + } + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); +} +#endif diff --git a/drivers/net/wireless/iwlegacy/iwl-led.c b/drivers/net/wireless/iwlegacy/iwl-led.c new file mode 100644 index 000000000000..15eb8b707157 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-led.c @@ -0,0 +1,188 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-io.h" + +/* default: IWL_LED_BLINK(0) using blinking index table */ +static int led_mode; +module_param(led_mode, int, S_IRUGO); +MODULE_PARM_DESC(led_mode, "0=system default, " + "1=On(RF On)/Off(RF Off), 2=blinking"); + +static const struct ieee80211_tpt_blink iwl_blink[] = { + { .throughput = 0 * 1024 - 1, .blink_time = 334 }, + { .throughput = 1 * 1024 - 1, .blink_time = 260 }, + { .throughput = 5 * 1024 - 1, .blink_time = 220 }, + { .throughput = 10 * 1024 - 1, .blink_time = 190 }, + { .throughput = 20 * 1024 - 1, .blink_time = 170 }, + { .throughput = 50 * 1024 - 1, .blink_time = 150 }, + { .throughput = 70 * 1024 - 1, .blink_time = 130 }, + { .throughput = 100 * 1024 - 1, .blink_time = 110 }, + { .throughput = 200 * 1024 - 1, .blink_time = 80 }, + { .throughput = 300 * 1024 - 1, .blink_time = 50 }, +}; + +/* + * Adjust led blink rate to compensate on a MAC Clock difference on every HW + * Led blink rate analysis showed an average deviation of 0% on 3945, + * 5% on 4965 HW. + * Need to compensate on the led on/off time per HW according to the deviation + * to achieve the desired led frequency + * The calculation is: (100-averageDeviation)/100 * blinkTime + * For code efficiency the calculation will be: + * compensation = (100 - averageDeviation) * 64 / 100 + * NewBlinkTime = (compensation * BlinkTime) / 64 + */ +static inline u8 iwl_legacy_blink_compensation(struct iwl_priv *priv, + u8 time, u16 compensation) +{ + if (!compensation) { + IWL_ERR(priv, "undefined blink compensation: " + "use pre-defined blinking time\n"); + return time; + } + + return (u8)((time * compensation) >> 6); +} + +/* Set led pattern command */ +static int iwl_legacy_led_cmd(struct iwl_priv *priv, + unsigned long on, + unsigned long off) +{ + struct iwl_led_cmd led_cmd = { + .id = IWL_LED_LINK, + .interval = IWL_DEF_LED_INTRVL + }; + int ret; + + if (!test_bit(STATUS_READY, &priv->status)) + return -EBUSY; + + if (priv->blink_on == on && priv->blink_off == off) + return 0; + + IWL_DEBUG_LED(priv, "Led blink time compensation=%u\n", + priv->cfg->base_params->led_compensation); + led_cmd.on = iwl_legacy_blink_compensation(priv, on, + priv->cfg->base_params->led_compensation); + led_cmd.off = iwl_legacy_blink_compensation(priv, off, + priv->cfg->base_params->led_compensation); + + ret = priv->cfg->ops->led->cmd(priv, &led_cmd); + if (!ret) { + priv->blink_on = on; + priv->blink_off = off; + } + return ret; +} + +static void iwl_legacy_led_brightness_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct iwl_priv *priv = container_of(led_cdev, struct iwl_priv, led); + unsigned long on = 0; + + if (brightness > 0) + on = IWL_LED_SOLID; + + iwl_legacy_led_cmd(priv, on, 0); +} + +static int iwl_legacy_led_blink_set(struct led_classdev *led_cdev, + unsigned long *delay_on, + unsigned long *delay_off) +{ + struct iwl_priv *priv = container_of(led_cdev, struct iwl_priv, led); + + return iwl_legacy_led_cmd(priv, *delay_on, *delay_off); +} + +void iwl_legacy_leds_init(struct iwl_priv *priv) +{ + int mode = led_mode; + int ret; + + if (mode == IWL_LED_DEFAULT) + mode = priv->cfg->led_mode; + + priv->led.name = kasprintf(GFP_KERNEL, "%s-led", + wiphy_name(priv->hw->wiphy)); + priv->led.brightness_set = iwl_legacy_led_brightness_set; + priv->led.blink_set = iwl_legacy_led_blink_set; + priv->led.max_brightness = 1; + + switch (mode) { + case IWL_LED_DEFAULT: + WARN_ON(1); + break; + case IWL_LED_BLINK: + priv->led.default_trigger = + ieee80211_create_tpt_led_trigger(priv->hw, + IEEE80211_TPT_LEDTRIG_FL_CONNECTED, + iwl_blink, ARRAY_SIZE(iwl_blink)); + break; + case IWL_LED_RF_STATE: + priv->led.default_trigger = + ieee80211_get_radio_led_name(priv->hw); + break; + } + + ret = led_classdev_register(&priv->pci_dev->dev, &priv->led); + if (ret) { + kfree(priv->led.name); + return; + } + + priv->led_registered = true; +} +EXPORT_SYMBOL(iwl_legacy_leds_init); + +void iwl_legacy_leds_exit(struct iwl_priv *priv) +{ + if (!priv->led_registered) + return; + + led_classdev_unregister(&priv->led); + kfree(priv->led.name); +} +EXPORT_SYMBOL(iwl_legacy_leds_exit); diff --git a/drivers/net/wireless/iwlegacy/iwl-led.h b/drivers/net/wireless/iwlegacy/iwl-led.h new file mode 100644 index 000000000000..f0791f70f79d --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-led.h @@ -0,0 +1,56 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#ifndef __iwl_legacy_leds_h__ +#define __iwl_legacy_leds_h__ + + +struct iwl_priv; + +#define IWL_LED_SOLID 11 +#define IWL_DEF_LED_INTRVL cpu_to_le32(1000) + +#define IWL_LED_ACTIVITY (0<<1) +#define IWL_LED_LINK (1<<1) + +/* + * LED mode + * IWL_LED_DEFAULT: use device default + * IWL_LED_RF_STATE: turn LED on/off based on RF state + * LED ON = RF ON + * LED OFF = RF OFF + * IWL_LED_BLINK: adjust led blink rate based on blink table + */ +enum iwl_led_mode { + IWL_LED_DEFAULT, + IWL_LED_RF_STATE, + IWL_LED_BLINK, +}; + +void iwl_legacy_leds_init(struct iwl_priv *priv); +void iwl_legacy_leds_exit(struct iwl_priv *priv); + +#endif /* __iwl_legacy_leds_h__ */ diff --git a/drivers/net/wireless/iwlegacy/iwl-legacy-rs.h b/drivers/net/wireless/iwlegacy/iwl-legacy-rs.h new file mode 100644 index 000000000000..f66a1b2c0397 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-legacy-rs.h @@ -0,0 +1,456 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#ifndef __iwl_legacy_rs_h__ +#define __iwl_legacy_rs_h__ + +struct iwl_rate_info { + u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ + u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */ + u8 plcp_mimo2; /* uCode API: IWL_RATE_MIMO2_6M_PLCP, etc. */ + u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */ + u8 prev_ieee; /* previous rate in IEEE speeds */ + u8 next_ieee; /* next rate in IEEE speeds */ + u8 prev_rs; /* previous rate used in rs algo */ + u8 next_rs; /* next rate used in rs algo */ + u8 prev_rs_tgg; /* previous rate used in TGG rs algo */ + u8 next_rs_tgg; /* next rate used in TGG rs algo */ +}; + +struct iwl3945_rate_info { + u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ + u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */ + u8 prev_ieee; /* previous rate in IEEE speeds */ + u8 next_ieee; /* next rate in IEEE speeds */ + u8 prev_rs; /* previous rate used in rs algo */ + u8 next_rs; /* next rate used in rs algo */ + u8 prev_rs_tgg; /* previous rate used in TGG rs algo */ + u8 next_rs_tgg; /* next rate used in TGG rs algo */ + u8 table_rs_index; /* index in rate scale table cmd */ + u8 prev_table_rs; /* prev in rate table cmd */ +}; + + +/* + * These serve as indexes into + * struct iwl_rate_info iwl_rates[IWL_RATE_COUNT]; + */ +enum { + IWL_RATE_1M_INDEX = 0, + IWL_RATE_2M_INDEX, + IWL_RATE_5M_INDEX, + IWL_RATE_11M_INDEX, + IWL_RATE_6M_INDEX, + IWL_RATE_9M_INDEX, + IWL_RATE_12M_INDEX, + IWL_RATE_18M_INDEX, + IWL_RATE_24M_INDEX, + IWL_RATE_36M_INDEX, + IWL_RATE_48M_INDEX, + IWL_RATE_54M_INDEX, + IWL_RATE_60M_INDEX, + IWL_RATE_COUNT, + IWL_RATE_COUNT_LEGACY = IWL_RATE_COUNT - 1, /* Excluding 60M */ + IWL_RATE_COUNT_3945 = IWL_RATE_COUNT - 1, + IWL_RATE_INVM_INDEX = IWL_RATE_COUNT, + IWL_RATE_INVALID = IWL_RATE_COUNT, +}; + +enum { + IWL_RATE_6M_INDEX_TABLE = 0, + IWL_RATE_9M_INDEX_TABLE, + IWL_RATE_12M_INDEX_TABLE, + IWL_RATE_18M_INDEX_TABLE, + IWL_RATE_24M_INDEX_TABLE, + IWL_RATE_36M_INDEX_TABLE, + IWL_RATE_48M_INDEX_TABLE, + IWL_RATE_54M_INDEX_TABLE, + IWL_RATE_1M_INDEX_TABLE, + IWL_RATE_2M_INDEX_TABLE, + IWL_RATE_5M_INDEX_TABLE, + IWL_RATE_11M_INDEX_TABLE, + IWL_RATE_INVM_INDEX_TABLE = IWL_RATE_INVM_INDEX - 1, +}; + +enum { + IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX, + IWL39_LAST_OFDM_RATE = IWL_RATE_54M_INDEX, + IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX, + IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX, + IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX, +}; + +/* #define vs. enum to keep from defaulting to 'large integer' */ +#define IWL_RATE_6M_MASK (1 << IWL_RATE_6M_INDEX) +#define IWL_RATE_9M_MASK (1 << IWL_RATE_9M_INDEX) +#define IWL_RATE_12M_MASK (1 << IWL_RATE_12M_INDEX) +#define IWL_RATE_18M_MASK (1 << IWL_RATE_18M_INDEX) +#define IWL_RATE_24M_MASK (1 << IWL_RATE_24M_INDEX) +#define IWL_RATE_36M_MASK (1 << IWL_RATE_36M_INDEX) +#define IWL_RATE_48M_MASK (1 << IWL_RATE_48M_INDEX) +#define IWL_RATE_54M_MASK (1 << IWL_RATE_54M_INDEX) +#define IWL_RATE_60M_MASK (1 << IWL_RATE_60M_INDEX) +#define IWL_RATE_1M_MASK (1 << IWL_RATE_1M_INDEX) +#define IWL_RATE_2M_MASK (1 << IWL_RATE_2M_INDEX) +#define IWL_RATE_5M_MASK (1 << IWL_RATE_5M_INDEX) +#define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX) + +/* uCode API values for legacy bit rates, both OFDM and CCK */ +enum { + IWL_RATE_6M_PLCP = 13, + IWL_RATE_9M_PLCP = 15, + IWL_RATE_12M_PLCP = 5, + IWL_RATE_18M_PLCP = 7, + IWL_RATE_24M_PLCP = 9, + IWL_RATE_36M_PLCP = 11, + IWL_RATE_48M_PLCP = 1, + IWL_RATE_54M_PLCP = 3, + IWL_RATE_60M_PLCP = 3,/*FIXME:RS:should be removed*/ + IWL_RATE_1M_PLCP = 10, + IWL_RATE_2M_PLCP = 20, + IWL_RATE_5M_PLCP = 55, + IWL_RATE_11M_PLCP = 110, + /*FIXME:RS:add IWL_RATE_LEGACY_INVM_PLCP = 0,*/ +}; + +/* uCode API values for OFDM high-throughput (HT) bit rates */ +enum { + IWL_RATE_SISO_6M_PLCP = 0, + IWL_RATE_SISO_12M_PLCP = 1, + IWL_RATE_SISO_18M_PLCP = 2, + IWL_RATE_SISO_24M_PLCP = 3, + IWL_RATE_SISO_36M_PLCP = 4, + IWL_RATE_SISO_48M_PLCP = 5, + IWL_RATE_SISO_54M_PLCP = 6, + IWL_RATE_SISO_60M_PLCP = 7, + IWL_RATE_MIMO2_6M_PLCP = 0x8, + IWL_RATE_MIMO2_12M_PLCP = 0x9, + IWL_RATE_MIMO2_18M_PLCP = 0xa, + IWL_RATE_MIMO2_24M_PLCP = 0xb, + IWL_RATE_MIMO2_36M_PLCP = 0xc, + IWL_RATE_MIMO2_48M_PLCP = 0xd, + IWL_RATE_MIMO2_54M_PLCP = 0xe, + IWL_RATE_MIMO2_60M_PLCP = 0xf, + IWL_RATE_SISO_INVM_PLCP, + IWL_RATE_MIMO2_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP, +}; + +/* MAC header values for bit rates */ +enum { + IWL_RATE_6M_IEEE = 12, + IWL_RATE_9M_IEEE = 18, + IWL_RATE_12M_IEEE = 24, + IWL_RATE_18M_IEEE = 36, + IWL_RATE_24M_IEEE = 48, + IWL_RATE_36M_IEEE = 72, + IWL_RATE_48M_IEEE = 96, + IWL_RATE_54M_IEEE = 108, + IWL_RATE_60M_IEEE = 120, + IWL_RATE_1M_IEEE = 2, + IWL_RATE_2M_IEEE = 4, + IWL_RATE_5M_IEEE = 11, + IWL_RATE_11M_IEEE = 22, +}; + +#define IWL_CCK_BASIC_RATES_MASK \ + (IWL_RATE_1M_MASK | \ + IWL_RATE_2M_MASK) + +#define IWL_CCK_RATES_MASK \ + (IWL_CCK_BASIC_RATES_MASK | \ + IWL_RATE_5M_MASK | \ + IWL_RATE_11M_MASK) + +#define IWL_OFDM_BASIC_RATES_MASK \ + (IWL_RATE_6M_MASK | \ + IWL_RATE_12M_MASK | \ + IWL_RATE_24M_MASK) + +#define IWL_OFDM_RATES_MASK \ + (IWL_OFDM_BASIC_RATES_MASK | \ + IWL_RATE_9M_MASK | \ + IWL_RATE_18M_MASK | \ + IWL_RATE_36M_MASK | \ + IWL_RATE_48M_MASK | \ + IWL_RATE_54M_MASK) + +#define IWL_BASIC_RATES_MASK \ + (IWL_OFDM_BASIC_RATES_MASK | \ + IWL_CCK_BASIC_RATES_MASK) + +#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1) +#define IWL_RATES_MASK_3945 ((1 << IWL_RATE_COUNT_3945) - 1) + +#define IWL_INVALID_VALUE -1 + +#define IWL_MIN_RSSI_VAL -100 +#define IWL_MAX_RSSI_VAL 0 + +/* These values specify how many Tx frame attempts before + * searching for a new modulation mode */ +#define IWL_LEGACY_FAILURE_LIMIT 160 +#define IWL_LEGACY_SUCCESS_LIMIT 480 +#define IWL_LEGACY_TABLE_COUNT 160 + +#define IWL_NONE_LEGACY_FAILURE_LIMIT 400 +#define IWL_NONE_LEGACY_SUCCESS_LIMIT 4500 +#define IWL_NONE_LEGACY_TABLE_COUNT 1500 + +/* Success ratio (ACKed / attempted tx frames) values (perfect is 128 * 100) */ +#define IWL_RS_GOOD_RATIO 12800 /* 100% */ +#define IWL_RATE_SCALE_SWITCH 10880 /* 85% */ +#define IWL_RATE_HIGH_TH 10880 /* 85% */ +#define IWL_RATE_INCREASE_TH 6400 /* 50% */ +#define IWL_RATE_DECREASE_TH 1920 /* 15% */ + +/* possible actions when in legacy mode */ +#define IWL_LEGACY_SWITCH_ANTENNA1 0 +#define IWL_LEGACY_SWITCH_ANTENNA2 1 +#define IWL_LEGACY_SWITCH_SISO 2 +#define IWL_LEGACY_SWITCH_MIMO2_AB 3 +#define IWL_LEGACY_SWITCH_MIMO2_AC 4 +#define IWL_LEGACY_SWITCH_MIMO2_BC 5 + +/* possible actions when in siso mode */ +#define IWL_SISO_SWITCH_ANTENNA1 0 +#define IWL_SISO_SWITCH_ANTENNA2 1 +#define IWL_SISO_SWITCH_MIMO2_AB 2 +#define IWL_SISO_SWITCH_MIMO2_AC 3 +#define IWL_SISO_SWITCH_MIMO2_BC 4 +#define IWL_SISO_SWITCH_GI 5 + +/* possible actions when in mimo mode */ +#define IWL_MIMO2_SWITCH_ANTENNA1 0 +#define IWL_MIMO2_SWITCH_ANTENNA2 1 +#define IWL_MIMO2_SWITCH_SISO_A 2 +#define IWL_MIMO2_SWITCH_SISO_B 3 +#define IWL_MIMO2_SWITCH_SISO_C 4 +#define IWL_MIMO2_SWITCH_GI 5 + +#define IWL_MAX_SEARCH IWL_MIMO2_SWITCH_GI + +#define IWL_ACTION_LIMIT 3 /* # possible actions */ + +#define LQ_SIZE 2 /* 2 mode tables: "Active" and "Search" */ + +/* load per tid defines for A-MPDU activation */ +#define IWL_AGG_TPT_THREHOLD 0 +#define IWL_AGG_LOAD_THRESHOLD 10 +#define IWL_AGG_ALL_TID 0xff +#define TID_QUEUE_CELL_SPACING 50 /*mS */ +#define TID_QUEUE_MAX_SIZE 20 +#define TID_ROUND_VALUE 5 /* mS */ +#define TID_MAX_LOAD_COUNT 8 + +#define TID_MAX_TIME_DIFF ((TID_QUEUE_MAX_SIZE - 1) * TID_QUEUE_CELL_SPACING) +#define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y)) + +extern const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT]; + +enum iwl_table_type { + LQ_NONE, + LQ_G, /* legacy types */ + LQ_A, + LQ_SISO, /* high-throughput types */ + LQ_MIMO2, + LQ_MAX, +}; + +#define is_legacy(tbl) (((tbl) == LQ_G) || ((tbl) == LQ_A)) +#define is_siso(tbl) ((tbl) == LQ_SISO) +#define is_mimo2(tbl) ((tbl) == LQ_MIMO2) +#define is_mimo(tbl) (is_mimo2(tbl)) +#define is_Ht(tbl) (is_siso(tbl) || is_mimo(tbl)) +#define is_a_band(tbl) ((tbl) == LQ_A) +#define is_g_and(tbl) ((tbl) == LQ_G) + +#define ANT_NONE 0x0 +#define ANT_A BIT(0) +#define ANT_B BIT(1) +#define ANT_AB (ANT_A | ANT_B) +#define ANT_C BIT(2) +#define ANT_AC (ANT_A | ANT_C) +#define ANT_BC (ANT_B | ANT_C) +#define ANT_ABC (ANT_AB | ANT_C) + +#define IWL_MAX_MCS_DISPLAY_SIZE 12 + +struct iwl_rate_mcs_info { + char mbps[IWL_MAX_MCS_DISPLAY_SIZE]; + char mcs[IWL_MAX_MCS_DISPLAY_SIZE]; +}; + +/** + * struct iwl_rate_scale_data -- tx success history for one rate + */ +struct iwl_rate_scale_data { + u64 data; /* bitmap of successful frames */ + s32 success_counter; /* number of frames successful */ + s32 success_ratio; /* per-cent * 128 */ + s32 counter; /* number of frames attempted */ + s32 average_tpt; /* success ratio * expected throughput */ + unsigned long stamp; +}; + +/** + * struct iwl_scale_tbl_info -- tx params and success history for all rates + * + * There are two of these in struct iwl_lq_sta, + * one for "active", and one for "search". + */ +struct iwl_scale_tbl_info { + enum iwl_table_type lq_type; + u8 ant_type; + u8 is_SGI; /* 1 = short guard interval */ + u8 is_ht40; /* 1 = 40 MHz channel width */ + u8 is_dup; /* 1 = duplicated data streams */ + u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */ + u8 max_search; /* maximun number of tables we can search */ + s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ + u32 current_rate; /* rate_n_flags, uCode API format */ + struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ +}; + +struct iwl_traffic_load { + unsigned long time_stamp; /* age of the oldest statistics */ + u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time + * slice */ + u32 total; /* total num of packets during the + * last TID_MAX_TIME_DIFF */ + u8 queue_count; /* number of queues that has + * been used since the last cleanup */ + u8 head; /* start of the circular buffer */ +}; + +/** + * struct iwl_lq_sta -- driver's rate scaling private structure + * + * Pointer to this gets passed back and forth between driver and mac80211. + */ +struct iwl_lq_sta { + u8 active_tbl; /* index of active table, range 0-1 */ + u8 enable_counter; /* indicates HT mode */ + u8 stay_in_tbl; /* 1: disallow, 0: allow search for new mode */ + u8 search_better_tbl; /* 1: currently trying alternate mode */ + s32 last_tpt; + + /* The following determine when to search for a new mode */ + u32 table_count_limit; + u32 max_failure_limit; /* # failed frames before new search */ + u32 max_success_limit; /* # successful frames before new search */ + u32 table_count; + u32 total_failed; /* total failed frames, any/all rates */ + u32 total_success; /* total successful frames, any/all rates */ + u64 flush_timer; /* time staying in mode before new search */ + + u8 action_counter; /* # mode-switch actions tried */ + u8 is_green; + u8 is_dup; + enum ieee80211_band band; + + /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ + u32 supp_rates; + u16 active_legacy_rate; + u16 active_siso_rate; + u16 active_mimo2_rate; + s8 max_rate_idx; /* Max rate set by user */ + u8 missed_rate_counter; + + struct iwl_link_quality_cmd lq; + struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ + struct iwl_traffic_load load[TID_MAX_LOAD_COUNT]; + u8 tx_agg_tid_en; +#ifdef CONFIG_MAC80211_DEBUGFS + struct dentry *rs_sta_dbgfs_scale_table_file; + struct dentry *rs_sta_dbgfs_stats_table_file; + struct dentry *rs_sta_dbgfs_rate_scale_data_file; + struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; + u32 dbg_fixed_rate; +#endif + struct iwl_priv *drv; + + /* used to be in sta_info */ + int last_txrate_idx; + /* last tx rate_n_flags */ + u32 last_rate_n_flags; + /* packets destined for this STA are aggregated */ + u8 is_agg; +}; + +static inline u8 iwl4965_num_of_ant(u8 mask) +{ + return !!((mask) & ANT_A) + + !!((mask) & ANT_B) + + !!((mask) & ANT_C); +} + +static inline u8 iwl4965_first_antenna(u8 mask) +{ + if (mask & ANT_A) + return ANT_A; + if (mask & ANT_B) + return ANT_B; + return ANT_C; +} + + +/** + * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info + * + * The specific throughput table used is based on the type of network + * the associated with, including A, B, G, and G w/ TGG protection + */ +extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id); + +/* Initialize station's rate scaling information after adding station */ +extern void iwl4965_rs_rate_init(struct iwl_priv *priv, + struct ieee80211_sta *sta, u8 sta_id); +extern void iwl3945_rs_rate_init(struct iwl_priv *priv, + struct ieee80211_sta *sta, u8 sta_id); + +/** + * iwl_rate_control_register - Register the rate control algorithm callbacks + * + * Since the rate control algorithm is hardware specific, there is no need + * or reason to place it as a stand alone module. The driver can call + * iwl_rate_control_register in order to register the rate control callbacks + * with the mac80211 subsystem. This should be performed prior to calling + * ieee80211_register_hw + * + */ +extern int iwl4965_rate_control_register(void); +extern int iwl3945_rate_control_register(void); + +/** + * iwl_rate_control_unregister - Unregister the rate control callbacks + * + * This should be called after calling ieee80211_unregister_hw, but before + * the driver is unloaded. + */ +extern void iwl4965_rate_control_unregister(void); +extern void iwl3945_rate_control_unregister(void); + +#endif /* __iwl_legacy_rs__ */ diff --git a/drivers/net/wireless/iwlegacy/iwl-power.c b/drivers/net/wireless/iwlegacy/iwl-power.c new file mode 100644 index 000000000000..903ef0d6d6cb --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-power.c @@ -0,0 +1,165 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ + + +#include +#include +#include +#include + +#include + +#include "iwl-eeprom.h" +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-io.h" +#include "iwl-commands.h" +#include "iwl-debug.h" +#include "iwl-power.h" + +/* + * Setting power level allows the card to go to sleep when not busy. + * + * We calculate a sleep command based on the required latency, which + * we get from mac80211. In order to handle thermal throttling, we can + * also use pre-defined power levels. + */ + +/* + * This defines the old power levels. They are still used by default + * (level 1) and for thermal throttle (levels 3 through 5) + */ + +struct iwl_power_vec_entry { + struct iwl_powertable_cmd cmd; + u8 no_dtim; /* number of skip dtim */ +}; + +static void iwl_legacy_power_sleep_cam_cmd(struct iwl_priv *priv, + struct iwl_powertable_cmd *cmd) +{ + memset(cmd, 0, sizeof(*cmd)); + + if (priv->power_data.pci_pm) + cmd->flags |= IWL_POWER_PCI_PM_MSK; + + IWL_DEBUG_POWER(priv, "Sleep command for CAM\n"); +} + +static int +iwl_legacy_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd) +{ + IWL_DEBUG_POWER(priv, "Sending power/sleep command\n"); + IWL_DEBUG_POWER(priv, "Flags value = 0x%08X\n", cmd->flags); + IWL_DEBUG_POWER(priv, "Tx timeout = %u\n", + le32_to_cpu(cmd->tx_data_timeout)); + IWL_DEBUG_POWER(priv, "Rx timeout = %u\n", + le32_to_cpu(cmd->rx_data_timeout)); + IWL_DEBUG_POWER(priv, + "Sleep interval vector = { %d , %d , %d , %d , %d }\n", + le32_to_cpu(cmd->sleep_interval[0]), + le32_to_cpu(cmd->sleep_interval[1]), + le32_to_cpu(cmd->sleep_interval[2]), + le32_to_cpu(cmd->sleep_interval[3]), + le32_to_cpu(cmd->sleep_interval[4])); + + return iwl_legacy_send_cmd_pdu(priv, POWER_TABLE_CMD, + sizeof(struct iwl_powertable_cmd), cmd); +} + +int +iwl_legacy_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, + bool force) +{ + int ret; + bool update_chains; + + lockdep_assert_held(&priv->mutex); + + /* Don't update the RX chain when chain noise calibration is running */ + update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE || + priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE; + + if (!memcmp(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd)) && !force) + return 0; + + if (!iwl_legacy_is_ready_rf(priv)) + return -EIO; + + /* scan complete use sleep_power_next, need to be updated */ + memcpy(&priv->power_data.sleep_cmd_next, cmd, sizeof(*cmd)); + if (test_bit(STATUS_SCANNING, &priv->status) && !force) { + IWL_DEBUG_INFO(priv, "Defer power set mode while scanning\n"); + return 0; + } + + if (cmd->flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK) + set_bit(STATUS_POWER_PMI, &priv->status); + + ret = iwl_legacy_set_power(priv, cmd); + if (!ret) { + if (!(cmd->flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK)) + clear_bit(STATUS_POWER_PMI, &priv->status); + + if (priv->cfg->ops->lib->update_chain_flags && update_chains) + priv->cfg->ops->lib->update_chain_flags(priv); + else if (priv->cfg->ops->lib->update_chain_flags) + IWL_DEBUG_POWER(priv, + "Cannot update the power, chain noise " + "calibration running: %d\n", + priv->chain_noise_data.state); + + memcpy(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd)); + } else + IWL_ERR(priv, "set power fail, ret = %d", ret); + + return ret; +} + +int iwl_legacy_power_update_mode(struct iwl_priv *priv, bool force) +{ + struct iwl_powertable_cmd cmd; + + iwl_legacy_power_sleep_cam_cmd(priv, &cmd); + return iwl_legacy_power_set_mode(priv, &cmd, force); +} +EXPORT_SYMBOL(iwl_legacy_power_update_mode); + +/* initialize to default */ +void iwl_legacy_power_initialize(struct iwl_priv *priv) +{ + u16 lctl = iwl_legacy_pcie_link_ctl(priv); + + priv->power_data.pci_pm = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); + + priv->power_data.debug_sleep_level_override = -1; + + memset(&priv->power_data.sleep_cmd, 0, + sizeof(priv->power_data.sleep_cmd)); +} +EXPORT_SYMBOL(iwl_legacy_power_initialize); diff --git a/drivers/net/wireless/iwlegacy/iwl-power.h b/drivers/net/wireless/iwlegacy/iwl-power.h new file mode 100644 index 000000000000..d30b36acdc4a --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-power.h @@ -0,0 +1,55 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ +#ifndef __iwl_legacy_power_setting_h__ +#define __iwl_legacy_power_setting_h__ + +#include "iwl-commands.h" + +enum iwl_power_level { + IWL_POWER_INDEX_1, + IWL_POWER_INDEX_2, + IWL_POWER_INDEX_3, + IWL_POWER_INDEX_4, + IWL_POWER_INDEX_5, + IWL_POWER_NUM +}; + +struct iwl_power_mgr { + struct iwl_powertable_cmd sleep_cmd; + struct iwl_powertable_cmd sleep_cmd_next; + int debug_sleep_level_override; + bool pci_pm; +}; + +int +iwl_legacy_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, + bool force); +int iwl_legacy_power_update_mode(struct iwl_priv *priv, bool force); +void iwl_legacy_power_initialize(struct iwl_priv *priv); + +#endif /* __iwl_legacy_power_setting_h__ */ diff --git a/drivers/net/wireless/iwlegacy/iwl-prph.h b/drivers/net/wireless/iwlegacy/iwl-prph.h new file mode 100644 index 000000000000..30a493003ab0 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-prph.h @@ -0,0 +1,523 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#ifndef __iwl_legacy_prph_h__ +#define __iwl_legacy_prph_h__ + +/* + * Registers in this file are internal, not PCI bus memory mapped. + * Driver accesses these via HBUS_TARG_PRPH_* registers. + */ +#define PRPH_BASE (0x00000) +#define PRPH_END (0xFFFFF) + +/* APMG (power management) constants */ +#define APMG_BASE (PRPH_BASE + 0x3000) +#define APMG_CLK_CTRL_REG (APMG_BASE + 0x0000) +#define APMG_CLK_EN_REG (APMG_BASE + 0x0004) +#define APMG_CLK_DIS_REG (APMG_BASE + 0x0008) +#define APMG_PS_CTRL_REG (APMG_BASE + 0x000c) +#define APMG_PCIDEV_STT_REG (APMG_BASE + 0x0010) +#define APMG_RFKILL_REG (APMG_BASE + 0x0014) +#define APMG_RTC_INT_STT_REG (APMG_BASE + 0x001c) +#define APMG_RTC_INT_MSK_REG (APMG_BASE + 0x0020) +#define APMG_DIGITAL_SVR_REG (APMG_BASE + 0x0058) +#define APMG_ANALOG_SVR_REG (APMG_BASE + 0x006C) + +#define APMS_CLK_VAL_MRB_FUNC_MODE (0x00000001) +#define APMG_CLK_VAL_DMA_CLK_RQT (0x00000200) +#define APMG_CLK_VAL_BSM_CLK_RQT (0x00000800) + +#define APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS (0x00400000) +#define APMG_PS_CTRL_VAL_RESET_REQ (0x04000000) +#define APMG_PS_CTRL_MSK_PWR_SRC (0x03000000) +#define APMG_PS_CTRL_VAL_PWR_SRC_VMAIN (0x00000000) +#define APMG_PS_CTRL_VAL_PWR_SRC_MAX (0x01000000) /* 3945 only */ +#define APMG_PS_CTRL_VAL_PWR_SRC_VAUX (0x02000000) +#define APMG_SVR_VOLTAGE_CONFIG_BIT_MSK (0x000001E0) /* bit 8:5 */ +#define APMG_SVR_DIGITAL_VOLTAGE_1_32 (0x00000060) + +#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800) + +/** + * BSM (Bootstrap State Machine) + * + * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program + * in special SRAM that does not power down when the embedded control + * processor is sleeping (e.g. for periodic power-saving shutdowns of radio). + * + * When powering back up after sleeps (or during initial uCode load), the BSM + * internally loads the short bootstrap program from the special SRAM into the + * embedded processor's instruction SRAM, and starts the processor so it runs + * the bootstrap program. + * + * This bootstrap program loads (via PCI busmaster DMA) instructions and data + * images for a uCode program from host DRAM locations. The host driver + * indicates DRAM locations and sizes for instruction and data images via the + * four BSM_DRAM_* registers. Once the bootstrap program loads the new program, + * the new program starts automatically. + * + * The uCode used for open-source drivers includes two programs: + * + * 1) Initialization -- performs hardware calibration and sets up some + * internal data, then notifies host via "initialize alive" notification + * (struct iwl_init_alive_resp) that it has completed all of its work. + * After signal from host, it then loads and starts the runtime program. + * The initialization program must be used when initially setting up the + * NIC after loading the driver. + * + * 2) Runtime/Protocol -- performs all normal runtime operations. This + * notifies host via "alive" notification (struct iwl_alive_resp) that it + * is ready to be used. + * + * When initializing the NIC, the host driver does the following procedure: + * + * 1) Load bootstrap program (instructions only, no data image for bootstrap) + * into bootstrap memory. Use dword writes starting at BSM_SRAM_LOWER_BOUND + * + * 2) Point (via BSM_DRAM_*) to the "initialize" uCode data and instruction + * images in host DRAM. + * + * 3) Set up BSM to copy from BSM SRAM into uCode instruction SRAM when asked: + * BSM_WR_MEM_SRC_REG = 0 + * BSM_WR_MEM_DST_REG = RTC_INST_LOWER_BOUND + * BSM_WR_MEM_DWCOUNT_REG = # dwords in bootstrap instruction image + * + * 4) Load bootstrap into instruction SRAM: + * BSM_WR_CTRL_REG = BSM_WR_CTRL_REG_BIT_START + * + * 5) Wait for load completion: + * Poll BSM_WR_CTRL_REG for BSM_WR_CTRL_REG_BIT_START = 0 + * + * 6) Enable future boot loads whenever NIC's power management triggers it: + * BSM_WR_CTRL_REG = BSM_WR_CTRL_REG_BIT_START_EN + * + * 7) Start the NIC by removing all reset bits: + * CSR_RESET = 0 + * + * The bootstrap uCode (already in instruction SRAM) loads initialization + * uCode. Initialization uCode performs data initialization, sends + * "initialize alive" notification to host, and waits for a signal from + * host to load runtime code. + * + * 4) Point (via BSM_DRAM_*) to the "runtime" uCode data and instruction + * images in host DRAM. The last register loaded must be the instruction + * byte count register ("1" in MSbit tells initialization uCode to load + * the runtime uCode): + * BSM_DRAM_INST_BYTECOUNT_REG = byte count | BSM_DRAM_INST_LOAD + * + * 5) Wait for "alive" notification, then issue normal runtime commands. + * + * Data caching during power-downs: + * + * Just before the embedded controller powers down (e.g for automatic + * power-saving modes, or for RFKILL), uCode stores (via PCI busmaster DMA) + * a current snapshot of the embedded processor's data SRAM into host DRAM. + * This caches the data while the embedded processor's memory is powered down. + * Location and size are controlled by BSM_DRAM_DATA_* registers. + * + * NOTE: Instruction SRAM does not need to be saved, since that doesn't + * change during operation; the original image (from uCode distribution + * file) can be used for reload. + * + * When powering back up, the BSM loads the bootstrap program. Bootstrap looks + * at the BSM_DRAM_* registers, which now point to the runtime instruction + * image and the cached (modified) runtime data (*not* the initialization + * uCode). Bootstrap reloads these runtime images into SRAM, and restarts the + * uCode from where it left off before the power-down. + * + * NOTE: Initialization uCode does *not* run as part of the save/restore + * procedure. + * + * This save/restore method is mostly for autonomous power management during + * normal operation (result of POWER_TABLE_CMD). Platform suspend/resume and + * RFKILL should use complete restarts (with total re-initialization) of uCode, + * allowing total shutdown (including BSM memory). + * + * Note that, during normal operation, the host DRAM that held the initial + * startup data for the runtime code is now being used as a backup data cache + * for modified data! If you need to completely re-initialize the NIC, make + * sure that you use the runtime data image from the uCode distribution file, + * not the modified/saved runtime data. You may want to store a separate + * "clean" runtime data image in DRAM to avoid disk reads of distribution file. + */ + +/* BSM bit fields */ +#define BSM_WR_CTRL_REG_BIT_START (0x80000000) /* start boot load now */ +#define BSM_WR_CTRL_REG_BIT_START_EN (0x40000000) /* enable boot after pwrup*/ +#define BSM_DRAM_INST_LOAD (0x80000000) /* start program load now */ + +/* BSM addresses */ +#define BSM_BASE (PRPH_BASE + 0x3400) +#define BSM_END (PRPH_BASE + 0x3800) + +#define BSM_WR_CTRL_REG (BSM_BASE + 0x000) /* ctl and status */ +#define BSM_WR_MEM_SRC_REG (BSM_BASE + 0x004) /* source in BSM mem */ +#define BSM_WR_MEM_DST_REG (BSM_BASE + 0x008) /* dest in SRAM mem */ +#define BSM_WR_DWCOUNT_REG (BSM_BASE + 0x00C) /* bytes */ +#define BSM_WR_STATUS_REG (BSM_BASE + 0x010) /* bit 0: 1 == done */ + +/* + * Pointers and size regs for bootstrap load and data SRAM save/restore. + * NOTE: 3945 pointers use bits 31:0 of DRAM address. + * 4965 pointers use bits 35:4 of DRAM address. + */ +#define BSM_DRAM_INST_PTR_REG (BSM_BASE + 0x090) +#define BSM_DRAM_INST_BYTECOUNT_REG (BSM_BASE + 0x094) +#define BSM_DRAM_DATA_PTR_REG (BSM_BASE + 0x098) +#define BSM_DRAM_DATA_BYTECOUNT_REG (BSM_BASE + 0x09C) + +/* + * BSM special memory, stays powered on during power-save sleeps. + * Read/write, address range from LOWER_BOUND to (LOWER_BOUND + SIZE -1) + */ +#define BSM_SRAM_LOWER_BOUND (PRPH_BASE + 0x3800) +#define BSM_SRAM_SIZE (1024) /* bytes */ + + +/* 3945 Tx scheduler registers */ +#define ALM_SCD_BASE (PRPH_BASE + 0x2E00) +#define ALM_SCD_MODE_REG (ALM_SCD_BASE + 0x000) +#define ALM_SCD_ARASTAT_REG (ALM_SCD_BASE + 0x004) +#define ALM_SCD_TXFACT_REG (ALM_SCD_BASE + 0x010) +#define ALM_SCD_TXF4MF_REG (ALM_SCD_BASE + 0x014) +#define ALM_SCD_TXF5MF_REG (ALM_SCD_BASE + 0x020) +#define ALM_SCD_SBYP_MODE_1_REG (ALM_SCD_BASE + 0x02C) +#define ALM_SCD_SBYP_MODE_2_REG (ALM_SCD_BASE + 0x030) + +/** + * Tx Scheduler + * + * The Tx Scheduler selects the next frame to be transmitted, choosing TFDs + * (Transmit Frame Descriptors) from up to 16 circular Tx queues resident in + * host DRAM. It steers each frame's Tx command (which contains the frame + * data) into one of up to 7 prioritized Tx DMA FIFO channels within the + * device. A queue maps to only one (selectable by driver) Tx DMA channel, + * but one DMA channel may take input from several queues. + * + * Tx DMA FIFOs have dedicated purposes. For 4965, they are used as follows + * (cf. default_queue_to_tx_fifo in iwl-4965.c): + * + * 0 -- EDCA BK (background) frames, lowest priority + * 1 -- EDCA BE (best effort) frames, normal priority + * 2 -- EDCA VI (video) frames, higher priority + * 3 -- EDCA VO (voice) and management frames, highest priority + * 4 -- Commands (e.g. RXON, etc.) + * 5 -- unused (HCCA) + * 6 -- unused (HCCA) + * 7 -- not used by driver (device-internal only) + * + * + * Driver should normally map queues 0-6 to Tx DMA/FIFO channels 0-6. + * In addition, driver can map the remaining queues to Tx DMA/FIFO + * channels 0-3 to support 11n aggregation via EDCA DMA channels. + * + * The driver sets up each queue to work in one of two modes: + * + * 1) Scheduler-Ack, in which the scheduler automatically supports a + * block-ack (BA) window of up to 64 TFDs. In this mode, each queue + * contains TFDs for a unique combination of Recipient Address (RA) + * and Traffic Identifier (TID), that is, traffic of a given + * Quality-Of-Service (QOS) priority, destined for a single station. + * + * In scheduler-ack mode, the scheduler keeps track of the Tx status of + * each frame within the BA window, including whether it's been transmitted, + * and whether it's been acknowledged by the receiving station. The device + * automatically processes block-acks received from the receiving STA, + * and reschedules un-acked frames to be retransmitted (successful + * Tx completion may end up being out-of-order). + * + * The driver must maintain the queue's Byte Count table in host DRAM + * (struct iwl4965_sched_queue_byte_cnt_tbl) for this mode. + * This mode does not support fragmentation. + * + * 2) FIFO (a.k.a. non-Scheduler-ACK), in which each TFD is processed in order. + * The device may automatically retry Tx, but will retry only one frame + * at a time, until receiving ACK from receiving station, or reaching + * retry limit and giving up. + * + * The command queue (#4/#9) must use this mode! + * This mode does not require use of the Byte Count table in host DRAM. + * + * Driver controls scheduler operation via 3 means: + * 1) Scheduler registers + * 2) Shared scheduler data base in internal 4956 SRAM + * 3) Shared data in host DRAM + * + * Initialization: + * + * When loading, driver should allocate memory for: + * 1) 16 TFD circular buffers, each with space for (typically) 256 TFDs. + * 2) 16 Byte Count circular buffers in 16 KBytes contiguous memory + * (1024 bytes for each queue). + * + * After receiving "Alive" response from uCode, driver must initialize + * the scheduler (especially for queue #4/#9, the command queue, otherwise + * the driver can't issue commands!): + */ + +/** + * Max Tx window size is the max number of contiguous TFDs that the scheduler + * can keep track of at one time when creating block-ack chains of frames. + * Note that "64" matches the number of ack bits in a block-ack packet. + * Driver should use SCD_WIN_SIZE and SCD_FRAME_LIMIT values to initialize + * IWL49_SCD_CONTEXT_QUEUE_OFFSET(x) values. + */ +#define SCD_WIN_SIZE 64 +#define SCD_FRAME_LIMIT 64 + +/* SCD registers are internal, must be accessed via HBUS_TARG_PRPH regs */ +#define IWL49_SCD_START_OFFSET 0xa02c00 + +/* + * 4965 tells driver SRAM address for internal scheduler structs via this reg. + * Value is valid only after "Alive" response from uCode. + */ +#define IWL49_SCD_SRAM_BASE_ADDR (IWL49_SCD_START_OFFSET + 0x0) + +/* + * Driver may need to update queue-empty bits after changing queue's + * write and read pointers (indexes) during (re-)initialization (i.e. when + * scheduler is not tracking what's happening). + * Bit fields: + * 31-16: Write mask -- 1: update empty bit, 0: don't change empty bit + * 15-00: Empty state, one for each queue -- 1: empty, 0: non-empty + * NOTE: This register is not used by Linux driver. + */ +#define IWL49_SCD_EMPTY_BITS (IWL49_SCD_START_OFFSET + 0x4) + +/* + * Physical base address of array of byte count (BC) circular buffers (CBs). + * Each Tx queue has a BC CB in host DRAM to support Scheduler-ACK mode. + * This register points to BC CB for queue 0, must be on 1024-byte boundary. + * Others are spaced by 1024 bytes. + * Each BC CB is 2 bytes * (256 + 64) = 740 bytes, followed by 384 bytes pad. + * (Index into a queue's BC CB) = (index into queue's TFD CB) = (SSN & 0xff). + * Bit fields: + * 25-00: Byte Count CB physical address [35:10], must be 1024-byte aligned. + */ +#define IWL49_SCD_DRAM_BASE_ADDR (IWL49_SCD_START_OFFSET + 0x10) + +/* + * Enables any/all Tx DMA/FIFO channels. + * Scheduler generates requests for only the active channels. + * Set this to 0xff to enable all 8 channels (normal usage). + * Bit fields: + * 7- 0: Enable (1), disable (0), one bit for each channel 0-7 + */ +#define IWL49_SCD_TXFACT (IWL49_SCD_START_OFFSET + 0x1c) +/* + * Queue (x) Write Pointers (indexes, really!), one for each Tx queue. + * Initialized and updated by driver as new TFDs are added to queue. + * NOTE: If using Block Ack, index must correspond to frame's + * Start Sequence Number; index = (SSN & 0xff) + * NOTE: Alternative to HBUS_TARG_WRPTR, which is what Linux driver uses? + */ +#define IWL49_SCD_QUEUE_WRPTR(x) (IWL49_SCD_START_OFFSET + 0x24 + (x) * 4) + +/* + * Queue (x) Read Pointers (indexes, really!), one for each Tx queue. + * For FIFO mode, index indicates next frame to transmit. + * For Scheduler-ACK mode, index indicates first frame in Tx window. + * Initialized by driver, updated by scheduler. + */ +#define IWL49_SCD_QUEUE_RDPTR(x) (IWL49_SCD_START_OFFSET + 0x64 + (x) * 4) + +/* + * Select which queues work in chain mode (1) vs. not (0). + * Use chain mode to build chains of aggregated frames. + * Bit fields: + * 31-16: Reserved + * 15-00: Mode, one bit for each queue -- 1: Chain mode, 0: one-at-a-time + * NOTE: If driver sets up queue for chain mode, it should be also set up + * Scheduler-ACK mode as well, via SCD_QUEUE_STATUS_BITS(x). + */ +#define IWL49_SCD_QUEUECHAIN_SEL (IWL49_SCD_START_OFFSET + 0xd0) + +/* + * Select which queues interrupt driver when scheduler increments + * a queue's read pointer (index). + * Bit fields: + * 31-16: Reserved + * 15-00: Interrupt enable, one bit for each queue -- 1: enabled, 0: disabled + * NOTE: This functionality is apparently a no-op; driver relies on interrupts + * from Rx queue to read Tx command responses and update Tx queues. + */ +#define IWL49_SCD_INTERRUPT_MASK (IWL49_SCD_START_OFFSET + 0xe4) + +/* + * Queue search status registers. One for each queue. + * Sets up queue mode and assigns queue to Tx DMA channel. + * Bit fields: + * 19-10: Write mask/enable bits for bits 0-9 + * 9: Driver should init to "0" + * 8: Scheduler-ACK mode (1), non-Scheduler-ACK (i.e. FIFO) mode (0). + * Driver should init to "1" for aggregation mode, or "0" otherwise. + * 7-6: Driver should init to "0" + * 5: Window Size Left; indicates whether scheduler can request + * another TFD, based on window size, etc. Driver should init + * this bit to "1" for aggregation mode, or "0" for non-agg. + * 4-1: Tx FIFO to use (range 0-7). + * 0: Queue is active (1), not active (0). + * Other bits should be written as "0" + * + * NOTE: If enabling Scheduler-ACK mode, chain mode should also be enabled + * via SCD_QUEUECHAIN_SEL. + */ +#define IWL49_SCD_QUEUE_STATUS_BITS(x)\ + (IWL49_SCD_START_OFFSET + 0x104 + (x) * 4) + +/* Bit field positions */ +#define IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE (0) +#define IWL49_SCD_QUEUE_STTS_REG_POS_TXF (1) +#define IWL49_SCD_QUEUE_STTS_REG_POS_WSL (5) +#define IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACK (8) + +/* Write masks */ +#define IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (10) +#define IWL49_SCD_QUEUE_STTS_REG_MSK (0x0007FC00) + +/** + * 4965 internal SRAM structures for scheduler, shared with driver ... + * + * Driver should clear and initialize the following areas after receiving + * "Alive" response from 4965 uCode, i.e. after initial + * uCode load, or after a uCode load done for error recovery: + * + * SCD_CONTEXT_DATA_OFFSET (size 128 bytes) + * SCD_TX_STTS_BITMAP_OFFSET (size 256 bytes) + * SCD_TRANSLATE_TBL_OFFSET (size 32 bytes) + * + * Driver accesses SRAM via HBUS_TARG_MEM_* registers. + * Driver reads base address of this scheduler area from SCD_SRAM_BASE_ADDR. + * All OFFSET values must be added to this base address. + */ + +/* + * Queue context. One 8-byte entry for each of 16 queues. + * + * Driver should clear this entire area (size 0x80) to 0 after receiving + * "Alive" notification from uCode. Additionally, driver should init + * each queue's entry as follows: + * + * LS Dword bit fields: + * 0-06: Max Tx window size for Scheduler-ACK. Driver should init to 64. + * + * MS Dword bit fields: + * 16-22: Frame limit. Driver should init to 10 (0xa). + * + * Driver should init all other bits to 0. + * + * Init must be done after driver receives "Alive" response from 4965 uCode, + * and when setting up queue for aggregation. + */ +#define IWL49_SCD_CONTEXT_DATA_OFFSET 0x380 +#define IWL49_SCD_CONTEXT_QUEUE_OFFSET(x) \ + (IWL49_SCD_CONTEXT_DATA_OFFSET + ((x) * 8)) + +#define IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS (0) +#define IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK (0x0000007F) +#define IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16) +#define IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000) + +/* + * Tx Status Bitmap + * + * Driver should clear this entire area (size 0x100) to 0 after receiving + * "Alive" notification from uCode. Area is used only by device itself; + * no other support (besides clearing) is required from driver. + */ +#define IWL49_SCD_TX_STTS_BITMAP_OFFSET 0x400 + +/* + * RAxTID to queue translation mapping. + * + * When queue is in Scheduler-ACK mode, frames placed in a that queue must be + * for only one combination of receiver address (RA) and traffic ID (TID), i.e. + * one QOS priority level destined for one station (for this wireless link, + * not final destination). The SCD_TRANSLATE_TABLE area provides 16 16-bit + * mappings, one for each of the 16 queues. If queue is not in Scheduler-ACK + * mode, the device ignores the mapping value. + * + * Bit fields, for each 16-bit map: + * 15-9: Reserved, set to 0 + * 8-4: Index into device's station table for recipient station + * 3-0: Traffic ID (tid), range 0-15 + * + * Driver should clear this entire area (size 32 bytes) to 0 after receiving + * "Alive" notification from uCode. To update a 16-bit map value, driver + * must read a dword-aligned value from device SRAM, replace the 16-bit map + * value of interest, and write the dword value back into device SRAM. + */ +#define IWL49_SCD_TRANSLATE_TBL_OFFSET 0x500 + +/* Find translation table dword to read/write for given queue */ +#define IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \ + ((IWL49_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffffffc) + +#define IWL_SCD_TXFIFO_POS_TID (0) +#define IWL_SCD_TXFIFO_POS_RA (4) +#define IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK (0x01FF) + +/*********************** END TX SCHEDULER *************************************/ + +#endif /* __iwl_legacy_prph_h__ */ diff --git a/drivers/net/wireless/iwlegacy/iwl-rx.c b/drivers/net/wireless/iwlegacy/iwl-rx.c new file mode 100644 index 000000000000..654cf233a384 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-rx.c @@ -0,0 +1,302 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include +#include +#include "iwl-eeprom.h" +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-sta.h" +#include "iwl-io.h" +#include "iwl-helpers.h" +/************************** RX-FUNCTIONS ****************************/ +/* + * Rx theory of operation + * + * Driver allocates a circular buffer of Receive Buffer Descriptors (RBDs), + * each of which point to Receive Buffers to be filled by the NIC. These get + * used not only for Rx frames, but for any command response or notification + * from the NIC. The driver and NIC manage the Rx buffers by means + * of indexes into the circular buffer. + * + * Rx Queue Indexes + * The host/firmware share two index registers for managing the Rx buffers. + * + * The READ index maps to the first position that the firmware may be writing + * to -- the driver can read up to (but not including) this position and get + * good data. + * The READ index is managed by the firmware once the card is enabled. + * + * The WRITE index maps to the last position the driver has read from -- the + * position preceding WRITE is the last slot the firmware can place a packet. + * + * The queue is empty (no good data) if WRITE = READ - 1, and is full if + * WRITE = READ. + * + * During initialization, the host sets up the READ queue position to the first + * INDEX position, and WRITE to the last (READ - 1 wrapped) + * + * When the firmware places a packet in a buffer, it will advance the READ index + * and fire the RX interrupt. The driver can then query the READ index and + * process as many packets as possible, moving the WRITE index forward as it + * resets the Rx queue buffers with new memory. + * + * The management in the driver is as follows: + * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When + * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled + * to replenish the iwl->rxq->rx_free. + * + In iwl_rx_replenish (scheduled) if 'processed' != 'read' then the + * iwl->rxq is replenished and the READ INDEX is updated (updating the + * 'processed' and 'read' driver indexes as well) + * + A received packet is processed and handed to the kernel network stack, + * detached from the iwl->rxq. The driver 'processed' index is updated. + * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free + * list. If there are no allocated buffers in iwl->rxq->rx_free, the READ + * INDEX is not incremented and iwl->status(RX_STALLED) is set. If there + * were enough free buffers and RX_STALLED is set it is cleared. + * + * + * Driver sequence: + * + * iwl_legacy_rx_queue_alloc() Allocates rx_free + * iwl_rx_replenish() Replenishes rx_free list from rx_used, and calls + * iwl_rx_queue_restock + * iwl_rx_queue_restock() Moves available buffers from rx_free into Rx + * queue, updates firmware pointers, and updates + * the WRITE index. If insufficient rx_free buffers + * are available, schedules iwl_rx_replenish + * + * -- enable interrupts -- + * ISR - iwl_rx() Detach iwl_rx_mem_buffers from pool up to the + * READ INDEX, detaching the SKB from the pool. + * Moves the packet buffer from queue to rx_used. + * Calls iwl_rx_queue_restock to refill any empty + * slots. + * ... + * + */ + +/** + * iwl_legacy_rx_queue_space - Return number of free slots available in queue. + */ +int iwl_legacy_rx_queue_space(const struct iwl_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; +} +EXPORT_SYMBOL(iwl_legacy_rx_queue_space); + +/** + * iwl_legacy_rx_queue_update_write_ptr - Update the write pointer for the RX queue + */ +void +iwl_legacy_rx_queue_update_write_ptr(struct iwl_priv *priv, + struct iwl_rx_queue *q) +{ + unsigned long flags; + u32 rx_wrt_ptr_reg = priv->hw_params.rx_wrt_ptr_reg; + u32 reg; + + spin_lock_irqsave(&q->lock, flags); + + if (q->need_update == 0) + goto exit_unlock; + + /* If power-saving is in use, make sure device is awake */ + if (test_bit(STATUS_POWER_PMI, &priv->status)) { + reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); + + if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { + IWL_DEBUG_INFO(priv, + "Rx queue requesting wakeup," + " GP1 = 0x%x\n", reg); + iwl_legacy_set_bit(priv, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + goto exit_unlock; + } + + q->write_actual = (q->write & ~0x7); + iwl_legacy_write_direct32(priv, rx_wrt_ptr_reg, + q->write_actual); + + /* Else device is assumed to be awake */ + } else { + /* Device expects a multiple of 8 */ + q->write_actual = (q->write & ~0x7); + iwl_legacy_write_direct32(priv, rx_wrt_ptr_reg, + q->write_actual); + } + + q->need_update = 0; + + exit_unlock: + spin_unlock_irqrestore(&q->lock, flags); +} +EXPORT_SYMBOL(iwl_legacy_rx_queue_update_write_ptr); + +int iwl_legacy_rx_queue_alloc(struct iwl_priv *priv) +{ + struct iwl_rx_queue *rxq = &priv->rxq; + struct device *dev = &priv->pci_dev->dev; + int i; + + spin_lock_init(&rxq->lock); + INIT_LIST_HEAD(&rxq->rx_free); + INIT_LIST_HEAD(&rxq->rx_used); + + /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ + rxq->bd = dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->bd_dma, + GFP_KERNEL); + if (!rxq->bd) + goto err_bd; + + rxq->rb_stts = dma_alloc_coherent(dev, sizeof(struct iwl_rb_status), + &rxq->rb_stts_dma, GFP_KERNEL); + if (!rxq->rb_stts) + goto err_rb; + + /* Fill the rx_used queue with _all_ of the Rx buffers */ + for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) + list_add_tail(&rxq->pool[i].list, &rxq->rx_used); + + /* 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->write_actual = 0; + rxq->free_count = 0; + rxq->need_update = 0; + return 0; + +err_rb: + dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, + rxq->bd_dma); +err_bd: + return -ENOMEM; +} +EXPORT_SYMBOL(iwl_legacy_rx_queue_alloc); + + +void iwl_legacy_rx_spectrum_measure_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif); + + if (!report->state) { + IWL_DEBUG_11H(priv, + "Spectrum Measure Notification: Start\n"); + return; + } + + memcpy(&priv->measure_report, report, sizeof(*report)); + priv->measurement_status |= MEASUREMENT_READY; +} +EXPORT_SYMBOL(iwl_legacy_rx_spectrum_measure_notif); + +void iwl_legacy_recover_from_statistics(struct iwl_priv *priv, + struct iwl_rx_packet *pkt) +{ + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + if (iwl_legacy_is_any_associated(priv)) { + if (priv->cfg->ops->lib->check_plcp_health) { + if (!priv->cfg->ops->lib->check_plcp_health( + priv, pkt)) { + /* + * high plcp error detected + * reset Radio + */ + iwl_legacy_force_reset(priv, + IWL_RF_RESET, false); + } + } + } +} +EXPORT_SYMBOL(iwl_legacy_recover_from_statistics); + +/* + * returns non-zero if packet should be dropped + */ +int iwl_legacy_set_decrypted_flag(struct iwl_priv *priv, + struct ieee80211_hdr *hdr, + u32 decrypt_res, + struct ieee80211_rx_status *stats) +{ + u16 fc = le16_to_cpu(hdr->frame_control); + + /* + * All contexts have the same setting here due to it being + * a module parameter, so OK to check any context. + */ + if (priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags & + RXON_FILTER_DIS_DECRYPT_MSK) + return 0; + + if (!(fc & IEEE80211_FCTL_PROTECTED)) + return 0; + + IWL_DEBUG_RX(priv, "decrypt_res:0x%x\n", decrypt_res); + switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) { + case RX_RES_STATUS_SEC_TYPE_TKIP: + /* The uCode has got a bad phase 1 Key, pushes the packet. + * Decryption will be done in SW. */ + if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == + RX_RES_STATUS_BAD_KEY_TTAK) + break; + + case RX_RES_STATUS_SEC_TYPE_WEP: + if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == + RX_RES_STATUS_BAD_ICV_MIC) { + /* bad ICV, the packet is destroyed since the + * decryption is inplace, drop it */ + IWL_DEBUG_RX(priv, "Packet destroyed\n"); + return -1; + } + case RX_RES_STATUS_SEC_TYPE_CCMP: + if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == + RX_RES_STATUS_DECRYPT_OK) { + IWL_DEBUG_RX(priv, "hw decrypt successfully!!!\n"); + stats->flag |= RX_FLAG_DECRYPTED; + } + break; + + default: + break; + } + return 0; +} +EXPORT_SYMBOL(iwl_legacy_set_decrypted_flag); diff --git a/drivers/net/wireless/iwlegacy/iwl-scan.c b/drivers/net/wireless/iwlegacy/iwl-scan.c new file mode 100644 index 000000000000..842f0b46b6df --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-scan.c @@ -0,0 +1,625 @@ +/****************************************************************************** + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ +#include +#include +#include +#include + +#include "iwl-eeprom.h" +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-sta.h" +#include "iwl-io.h" +#include "iwl-helpers.h" + +/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after + * sending probe req. This should be set long enough to hear probe responses + * from more than one AP. */ +#define IWL_ACTIVE_DWELL_TIME_24 (30) /* all times in msec */ +#define IWL_ACTIVE_DWELL_TIME_52 (20) + +#define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3) +#define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2) + +/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel. + * Must be set longer than active dwell time. + * For the most reliable scan, set > AP beacon interval (typically 100msec). */ +#define IWL_PASSIVE_DWELL_TIME_24 (20) /* all times in msec */ +#define IWL_PASSIVE_DWELL_TIME_52 (10) +#define IWL_PASSIVE_DWELL_BASE (100) +#define IWL_CHANNEL_TUNE_TIME 5 + +static int iwl_legacy_send_scan_abort(struct iwl_priv *priv) +{ + int ret; + struct iwl_rx_packet *pkt; + struct iwl_host_cmd cmd = { + .id = REPLY_SCAN_ABORT_CMD, + .flags = CMD_WANT_SKB, + }; + + /* Exit instantly with error when device is not ready + * to receive scan abort command or it does not perform + * hardware scan currently */ + if (!test_bit(STATUS_READY, &priv->status) || + !test_bit(STATUS_GEO_CONFIGURED, &priv->status) || + !test_bit(STATUS_SCAN_HW, &priv->status) || + test_bit(STATUS_FW_ERROR, &priv->status) || + test_bit(STATUS_EXIT_PENDING, &priv->status)) + return -EIO; + + ret = iwl_legacy_send_cmd_sync(priv, &cmd); + if (ret) + return ret; + + pkt = (struct iwl_rx_packet *)cmd.reply_page; + if (pkt->u.status != CAN_ABORT_STATUS) { + /* The scan abort will return 1 for success or + * 2 for "failure". A failure condition can be + * due to simply not being in an active scan which + * can occur if we send the scan abort before we + * the microcode has notified us that a scan is + * completed. */ + IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", pkt->u.status); + ret = -EIO; + } + + iwl_legacy_free_pages(priv, cmd.reply_page); + return ret; +} + +static void iwl_legacy_complete_scan(struct iwl_priv *priv, bool aborted) +{ + /* check if scan was requested from mac80211 */ + if (priv->scan_request) { + IWL_DEBUG_SCAN(priv, "Complete scan in mac80211\n"); + ieee80211_scan_completed(priv->hw, aborted); + } + + priv->is_internal_short_scan = false; + priv->scan_vif = NULL; + priv->scan_request = NULL; +} + +void iwl_legacy_force_scan_end(struct iwl_priv *priv) +{ + lockdep_assert_held(&priv->mutex); + + if (!test_bit(STATUS_SCANNING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Forcing scan end while not scanning\n"); + return; + } + + IWL_DEBUG_SCAN(priv, "Forcing scan end\n"); + clear_bit(STATUS_SCANNING, &priv->status); + clear_bit(STATUS_SCAN_HW, &priv->status); + clear_bit(STATUS_SCAN_ABORTING, &priv->status); + iwl_legacy_complete_scan(priv, true); +} + +static void iwl_legacy_do_scan_abort(struct iwl_priv *priv) +{ + int ret; + + lockdep_assert_held(&priv->mutex); + + if (!test_bit(STATUS_SCANNING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Not performing scan to abort\n"); + return; + } + + if (test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Scan abort in progress\n"); + return; + } + + ret = iwl_legacy_send_scan_abort(priv); + if (ret) { + IWL_DEBUG_SCAN(priv, "Send scan abort failed %d\n", ret); + iwl_legacy_force_scan_end(priv); + } else + IWL_DEBUG_SCAN(priv, "Sucessfully send scan abort\n"); +} + +/** + * iwl_scan_cancel - Cancel any currently executing HW scan + */ +int iwl_legacy_scan_cancel(struct iwl_priv *priv) +{ + IWL_DEBUG_SCAN(priv, "Queuing abort scan\n"); + queue_work(priv->workqueue, &priv->abort_scan); + return 0; +} +EXPORT_SYMBOL(iwl_legacy_scan_cancel); + +/** + * iwl_legacy_scan_cancel_timeout - Cancel any currently executing HW scan + * @ms: amount of time to wait (in milliseconds) for scan to abort + * + */ +int iwl_legacy_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(ms); + + lockdep_assert_held(&priv->mutex); + + IWL_DEBUG_SCAN(priv, "Scan cancel timeout\n"); + + iwl_legacy_do_scan_abort(priv); + + while (time_before_eq(jiffies, timeout)) { + if (!test_bit(STATUS_SCAN_HW, &priv->status)) + break; + msleep(20); + } + + return test_bit(STATUS_SCAN_HW, &priv->status); +} +EXPORT_SYMBOL(iwl_legacy_scan_cancel_timeout); + +/* Service response to REPLY_SCAN_CMD (0x80) */ +static void iwl_legacy_rx_reply_scan(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_scanreq_notification *notif = + (struct iwl_scanreq_notification *)pkt->u.raw; + + IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status); +#endif +} + +/* Service SCAN_START_NOTIFICATION (0x82) */ +static void iwl_legacy_rx_scan_start_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_scanstart_notification *notif = + (struct iwl_scanstart_notification *)pkt->u.raw; + priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); + IWL_DEBUG_SCAN(priv, "Scan start: " + "%d [802.11%s] " + "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n", + notif->channel, + notif->band ? "bg" : "a", + le32_to_cpu(notif->tsf_high), + le32_to_cpu(notif->tsf_low), + notif->status, notif->beacon_timer); +} + +/* Service SCAN_RESULTS_NOTIFICATION (0x83) */ +static void iwl_legacy_rx_scan_results_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_scanresults_notification *notif = + (struct iwl_scanresults_notification *)pkt->u.raw; + + IWL_DEBUG_SCAN(priv, "Scan ch.res: " + "%d [802.11%s] " + "(TSF: 0x%08X:%08X) - %d " + "elapsed=%lu usec\n", + notif->channel, + notif->band ? "bg" : "a", + le32_to_cpu(notif->tsf_high), + le32_to_cpu(notif->tsf_low), + le32_to_cpu(notif->statistics[0]), + le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf); +#endif +} + +/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ +static void iwl_legacy_rx_scan_complete_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; +#endif + + IWL_DEBUG_SCAN(priv, + "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", + scan_notif->scanned_channels, + scan_notif->tsf_low, + scan_notif->tsf_high, scan_notif->status); + + /* The HW is no longer scanning */ + clear_bit(STATUS_SCAN_HW, &priv->status); + + IWL_DEBUG_SCAN(priv, "Scan on %sGHz took %dms\n", + (priv->scan_band == IEEE80211_BAND_2GHZ) ? "2.4" : "5.2", + jiffies_to_msecs(jiffies - priv->scan_start)); + + queue_work(priv->workqueue, &priv->scan_completed); +} + +void iwl_legacy_setup_rx_scan_handlers(struct iwl_priv *priv) +{ + /* scan handlers */ + priv->rx_handlers[REPLY_SCAN_CMD] = iwl_legacy_rx_reply_scan; + priv->rx_handlers[SCAN_START_NOTIFICATION] = + iwl_legacy_rx_scan_start_notif; + priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] = + iwl_legacy_rx_scan_results_notif; + priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] = + iwl_legacy_rx_scan_complete_notif; +} +EXPORT_SYMBOL(iwl_legacy_setup_rx_scan_handlers); + +inline u16 iwl_legacy_get_active_dwell_time(struct iwl_priv *priv, + enum ieee80211_band band, + u8 n_probes) +{ + if (band == IEEE80211_BAND_5GHZ) + return IWL_ACTIVE_DWELL_TIME_52 + + IWL_ACTIVE_DWELL_FACTOR_52GHZ * (n_probes + 1); + else + return IWL_ACTIVE_DWELL_TIME_24 + + IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1); +} +EXPORT_SYMBOL(iwl_legacy_get_active_dwell_time); + +u16 iwl_legacy_get_passive_dwell_time(struct iwl_priv *priv, + enum ieee80211_band band, + struct ieee80211_vif *vif) +{ + struct iwl_rxon_context *ctx; + u16 passive = (band == IEEE80211_BAND_2GHZ) ? + IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : + IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; + + if (iwl_legacy_is_any_associated(priv)) { + /* + * If we're associated, we clamp the maximum passive + * dwell time to be 98% of the smallest beacon interval + * (minus 2 * channel tune time) + */ + for_each_context(priv, ctx) { + u16 value; + + if (!iwl_legacy_is_associated_ctx(ctx)) + continue; + value = ctx->vif ? ctx->vif->bss_conf.beacon_int : 0; + if ((value > IWL_PASSIVE_DWELL_BASE) || !value) + value = IWL_PASSIVE_DWELL_BASE; + value = (value * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; + passive = min(value, passive); + } + } + + return passive; +} +EXPORT_SYMBOL(iwl_legacy_get_passive_dwell_time); + +void iwl_legacy_init_scan_params(struct iwl_priv *priv) +{ + u8 ant_idx = fls(priv->hw_params.valid_tx_ant) - 1; + if (!priv->scan_tx_ant[IEEE80211_BAND_5GHZ]) + priv->scan_tx_ant[IEEE80211_BAND_5GHZ] = ant_idx; + if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ]) + priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = ant_idx; +} +EXPORT_SYMBOL(iwl_legacy_init_scan_params); + +static int __must_check iwl_legacy_scan_initiate(struct iwl_priv *priv, + struct ieee80211_vif *vif, + bool internal, + enum ieee80211_band band) +{ + int ret; + + lockdep_assert_held(&priv->mutex); + + if (WARN_ON(!priv->cfg->ops->utils->request_scan)) + return -EOPNOTSUPP; + + cancel_delayed_work(&priv->scan_check); + + if (!iwl_legacy_is_ready_rf(priv)) { + IWL_WARN(priv, "Request scan called when driver not ready.\n"); + return -EIO; + } + + if (test_bit(STATUS_SCAN_HW, &priv->status)) { + IWL_DEBUG_SCAN(priv, + "Multiple concurrent scan requests in parallel.\n"); + return -EBUSY; + } + + if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Scan request while abort pending.\n"); + return -EBUSY; + } + + IWL_DEBUG_SCAN(priv, "Starting %sscan...\n", + internal ? "internal short " : ""); + + set_bit(STATUS_SCANNING, &priv->status); + priv->is_internal_short_scan = internal; + priv->scan_start = jiffies; + priv->scan_band = band; + + ret = priv->cfg->ops->utils->request_scan(priv, vif); + if (ret) { + clear_bit(STATUS_SCANNING, &priv->status); + priv->is_internal_short_scan = false; + return ret; + } + + queue_delayed_work(priv->workqueue, &priv->scan_check, + IWL_SCAN_CHECK_WATCHDOG); + + return 0; +} + +int iwl_legacy_mac_hw_scan(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct cfg80211_scan_request *req) +{ + struct iwl_priv *priv = hw->priv; + int ret; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + if (req->n_channels == 0) + return -EINVAL; + + mutex_lock(&priv->mutex); + + if (test_bit(STATUS_SCANNING, &priv->status) && + !priv->is_internal_short_scan) { + IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); + ret = -EAGAIN; + goto out_unlock; + } + + /* mac80211 will only ask for one band at a time */ + priv->scan_request = req; + priv->scan_vif = vif; + + /* + * If an internal scan is in progress, just set + * up the scan_request as per above. + */ + if (priv->is_internal_short_scan) { + IWL_DEBUG_SCAN(priv, "SCAN request during internal scan\n"); + ret = 0; + } else + ret = iwl_legacy_scan_initiate(priv, vif, false, + req->channels[0]->band); + + IWL_DEBUG_MAC80211(priv, "leave\n"); + +out_unlock: + mutex_unlock(&priv->mutex); + + return ret; +} +EXPORT_SYMBOL(iwl_legacy_mac_hw_scan); + +/* + * internal short scan, this function should only been called while associated. + * It will reset and tune the radio to prevent possible RF related problem + */ +void iwl_legacy_internal_short_hw_scan(struct iwl_priv *priv) +{ + queue_work(priv->workqueue, &priv->start_internal_scan); +} + +static void iwl_legacy_bg_start_internal_scan(struct work_struct *work) +{ + struct iwl_priv *priv = + container_of(work, struct iwl_priv, start_internal_scan); + + IWL_DEBUG_SCAN(priv, "Start internal scan\n"); + + mutex_lock(&priv->mutex); + + if (priv->is_internal_short_scan == true) { + IWL_DEBUG_SCAN(priv, "Internal scan already in progress\n"); + goto unlock; + } + + if (test_bit(STATUS_SCANNING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); + goto unlock; + } + + if (iwl_legacy_scan_initiate(priv, NULL, true, priv->band)) + IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n"); + unlock: + mutex_unlock(&priv->mutex); +} + +static void iwl_legacy_bg_scan_check(struct work_struct *data) +{ + struct iwl_priv *priv = + container_of(data, struct iwl_priv, scan_check.work); + + IWL_DEBUG_SCAN(priv, "Scan check work\n"); + + /* Since we are here firmware does not finish scan and + * most likely is in bad shape, so we don't bother to + * send abort command, just force scan complete to mac80211 */ + mutex_lock(&priv->mutex); + iwl_legacy_force_scan_end(priv); + mutex_unlock(&priv->mutex); +} + +/** + * iwl_legacy_fill_probe_req - fill in all required fields and IE for probe request + */ + +u16 +iwl_legacy_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, + const u8 *ta, const u8 *ies, int ie_len, int left) +{ + int len = 0; + u8 *pos = NULL; + + /* Make sure there is enough space for the probe request, + * two mandatory IEs and the data */ + left -= 24; + if (left < 0) + return 0; + + frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); + memcpy(frame->da, iwl_bcast_addr, ETH_ALEN); + memcpy(frame->sa, ta, ETH_ALEN); + memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN); + frame->seq_ctrl = 0; + + len += 24; + + /* ...next IE... */ + pos = &frame->u.probe_req.variable[0]; + + /* fill in our indirect SSID IE */ + left -= 2; + if (left < 0) + return 0; + *pos++ = WLAN_EID_SSID; + *pos++ = 0; + + len += 2; + + if (WARN_ON(left < ie_len)) + return len; + + if (ies && ie_len) { + memcpy(pos, ies, ie_len); + len += ie_len; + } + + return (u16)len; +} +EXPORT_SYMBOL(iwl_legacy_fill_probe_req); + +static void iwl_legacy_bg_abort_scan(struct work_struct *work) +{ + struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan); + + IWL_DEBUG_SCAN(priv, "Abort scan work\n"); + + /* We keep scan_check work queued in case when firmware will not + * report back scan completed notification */ + mutex_lock(&priv->mutex); + iwl_legacy_scan_cancel_timeout(priv, 200); + mutex_unlock(&priv->mutex); +} + +static void iwl_legacy_bg_scan_completed(struct work_struct *work) +{ + struct iwl_priv *priv = + container_of(work, struct iwl_priv, scan_completed); + bool aborted; + + IWL_DEBUG_SCAN(priv, "Completed %sscan.\n", + priv->is_internal_short_scan ? "internal short " : ""); + + cancel_delayed_work(&priv->scan_check); + + mutex_lock(&priv->mutex); + + aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status); + if (aborted) + IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n"); + + if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Scan already completed.\n"); + goto out_settings; + } + + if (priv->is_internal_short_scan && !aborted) { + int err; + + /* Check if mac80211 requested scan during our internal scan */ + if (priv->scan_request == NULL) + goto out_complete; + + /* If so request a new scan */ + err = iwl_legacy_scan_initiate(priv, priv->scan_vif, false, + priv->scan_request->channels[0]->band); + if (err) { + IWL_DEBUG_SCAN(priv, + "failed to initiate pending scan: %d\n", err); + aborted = true; + goto out_complete; + } + + goto out; + } + +out_complete: + iwl_legacy_complete_scan(priv, aborted); + +out_settings: + /* Can we still talk to firmware ? */ + if (!iwl_legacy_is_ready_rf(priv)) + goto out; + + /* + * We do not commit power settings while scan is pending, + * do it now if the settings changed. + */ + iwl_legacy_power_set_mode(priv, &priv->power_data.sleep_cmd_next, + false); + iwl_legacy_set_tx_power(priv, priv->tx_power_next, false); + + priv->cfg->ops->utils->post_scan(priv); + +out: + mutex_unlock(&priv->mutex); +} + +void iwl_legacy_setup_scan_deferred_work(struct iwl_priv *priv) +{ + INIT_WORK(&priv->scan_completed, iwl_legacy_bg_scan_completed); + INIT_WORK(&priv->abort_scan, iwl_legacy_bg_abort_scan); + INIT_WORK(&priv->start_internal_scan, + iwl_legacy_bg_start_internal_scan); + INIT_DELAYED_WORK(&priv->scan_check, iwl_legacy_bg_scan_check); +} +EXPORT_SYMBOL(iwl_legacy_setup_scan_deferred_work); + +void iwl_legacy_cancel_scan_deferred_work(struct iwl_priv *priv) +{ + cancel_work_sync(&priv->start_internal_scan); + cancel_work_sync(&priv->abort_scan); + cancel_work_sync(&priv->scan_completed); + + if (cancel_delayed_work_sync(&priv->scan_check)) { + mutex_lock(&priv->mutex); + iwl_legacy_force_scan_end(priv); + mutex_unlock(&priv->mutex); + } +} +EXPORT_SYMBOL(iwl_legacy_cancel_scan_deferred_work); diff --git a/drivers/net/wireless/iwlegacy/iwl-spectrum.h b/drivers/net/wireless/iwlegacy/iwl-spectrum.h new file mode 100644 index 000000000000..9f70a4723103 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-spectrum.h @@ -0,0 +1,92 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#ifndef __iwl_legacy_spectrum_h__ +#define __iwl_legacy_spectrum_h__ +enum { /* ieee80211_basic_report.map */ + IEEE80211_BASIC_MAP_BSS = (1 << 0), + IEEE80211_BASIC_MAP_OFDM = (1 << 1), + IEEE80211_BASIC_MAP_UNIDENTIFIED = (1 << 2), + IEEE80211_BASIC_MAP_RADAR = (1 << 3), + IEEE80211_BASIC_MAP_UNMEASURED = (1 << 4), + /* Bits 5-7 are reserved */ + +}; +struct ieee80211_basic_report { + u8 channel; + __le64 start_time; + __le16 duration; + u8 map; +} __packed; + +enum { /* ieee80211_measurement_request.mode */ + /* Bit 0 is reserved */ + IEEE80211_MEASUREMENT_ENABLE = (1 << 1), + IEEE80211_MEASUREMENT_REQUEST = (1 << 2), + IEEE80211_MEASUREMENT_REPORT = (1 << 3), + /* Bits 4-7 are reserved */ +}; + +enum { + IEEE80211_REPORT_BASIC = 0, /* required */ + IEEE80211_REPORT_CCA = 1, /* optional */ + IEEE80211_REPORT_RPI = 2, /* optional */ + /* 3-255 reserved */ +}; + +struct ieee80211_measurement_params { + u8 channel; + __le64 start_time; + __le16 duration; +} __packed; + +struct ieee80211_info_element { + u8 id; + u8 len; + u8 data[0]; +} __packed; + +struct ieee80211_measurement_request { + struct ieee80211_info_element ie; + u8 token; + u8 mode; + u8 type; + struct ieee80211_measurement_params params[0]; +} __packed; + +struct ieee80211_measurement_report { + struct ieee80211_info_element ie; + u8 token; + u8 mode; + u8 type; + union { + struct ieee80211_basic_report basic[0]; + } u; +} __packed; + +#endif diff --git a/drivers/net/wireless/iwlegacy/iwl-sta.c b/drivers/net/wireless/iwlegacy/iwl-sta.c new file mode 100644 index 000000000000..47c9da3834ea --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-sta.c @@ -0,0 +1,816 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include +#include + +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-sta.h" + +/* priv->sta_lock must be held */ +static void iwl_legacy_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) +{ + + if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) + IWL_ERR(priv, + "ACTIVATE a non DRIVER active station id %u addr %pM\n", + sta_id, priv->stations[sta_id].sta.sta.addr); + + if (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) { + IWL_DEBUG_ASSOC(priv, + "STA id %u addr %pM already present" + " in uCode (according to driver)\n", + sta_id, priv->stations[sta_id].sta.sta.addr); + } else { + priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE; + IWL_DEBUG_ASSOC(priv, "Added STA id %u addr %pM to uCode\n", + sta_id, priv->stations[sta_id].sta.sta.addr); + } +} + +static int iwl_legacy_process_add_sta_resp(struct iwl_priv *priv, + struct iwl_legacy_addsta_cmd *addsta, + struct iwl_rx_packet *pkt, + bool sync) +{ + u8 sta_id = addsta->sta.sta_id; + unsigned long flags; + int ret = -EIO; + + if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { + IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", + pkt->hdr.flags); + return ret; + } + + IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n", + sta_id); + + spin_lock_irqsave(&priv->sta_lock, flags); + + switch (pkt->u.add_sta.status) { + case ADD_STA_SUCCESS_MSK: + IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n"); + iwl_legacy_sta_ucode_activate(priv, sta_id); + ret = 0; + break; + case ADD_STA_NO_ROOM_IN_TABLE: + IWL_ERR(priv, "Adding station %d failed, no room in table.\n", + sta_id); + break; + case ADD_STA_NO_BLOCK_ACK_RESOURCE: + IWL_ERR(priv, + "Adding station %d failed, no block ack resource.\n", + sta_id); + break; + case ADD_STA_MODIFY_NON_EXIST_STA: + IWL_ERR(priv, "Attempting to modify non-existing station %d\n", + sta_id); + break; + default: + IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n", + pkt->u.add_sta.status); + break; + } + + IWL_DEBUG_INFO(priv, "%s station id %u addr %pM\n", + priv->stations[sta_id].sta.mode == + STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", + sta_id, priv->stations[sta_id].sta.sta.addr); + + /* + * XXX: The MAC address in the command buffer is often changed from + * the original sent to the device. That is, the MAC address + * written to the command buffer often is not the same MAC adress + * read from the command buffer when the command returns. This + * issue has not yet been resolved and this debugging is left to + * observe the problem. + */ + IWL_DEBUG_INFO(priv, "%s station according to cmd buffer %pM\n", + priv->stations[sta_id].sta.mode == + STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", + addsta->sta.addr); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return ret; +} + +static void iwl_legacy_add_sta_callback(struct iwl_priv *priv, + struct iwl_device_cmd *cmd, + struct iwl_rx_packet *pkt) +{ + struct iwl_legacy_addsta_cmd *addsta = + (struct iwl_legacy_addsta_cmd *)cmd->cmd.payload; + + iwl_legacy_process_add_sta_resp(priv, addsta, pkt, false); + +} + +int iwl_legacy_send_add_sta(struct iwl_priv *priv, + struct iwl_legacy_addsta_cmd *sta, u8 flags) +{ + struct iwl_rx_packet *pkt = NULL; + int ret = 0; + u8 data[sizeof(*sta)]; + struct iwl_host_cmd cmd = { + .id = REPLY_ADD_STA, + .flags = flags, + .data = data, + }; + u8 sta_id __maybe_unused = sta->sta.sta_id; + + IWL_DEBUG_INFO(priv, "Adding sta %u (%pM) %ssynchronously\n", + sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : ""); + + if (flags & CMD_ASYNC) + cmd.callback = iwl_legacy_add_sta_callback; + else { + cmd.flags |= CMD_WANT_SKB; + might_sleep(); + } + + cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data); + ret = iwl_legacy_send_cmd(priv, &cmd); + + if (ret || (flags & CMD_ASYNC)) + return ret; + + if (ret == 0) { + pkt = (struct iwl_rx_packet *)cmd.reply_page; + ret = iwl_legacy_process_add_sta_resp(priv, sta, pkt, true); + } + iwl_legacy_free_pages(priv, cmd.reply_page); + + return ret; +} +EXPORT_SYMBOL(iwl_legacy_send_add_sta); + +static void iwl_legacy_set_ht_add_station(struct iwl_priv *priv, u8 index, + struct ieee80211_sta *sta, + struct iwl_rxon_context *ctx) +{ + struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap; + __le32 sta_flags; + u8 mimo_ps_mode; + + if (!sta || !sta_ht_inf->ht_supported) + goto done; + + mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2; + IWL_DEBUG_ASSOC(priv, "spatial multiplexing power save mode: %s\n", + (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ? + "static" : + (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ? + "dynamic" : "disabled"); + + sta_flags = priv->stations[index].sta.station_flags; + + sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK); + + switch (mimo_ps_mode) { + case WLAN_HT_CAP_SM_PS_STATIC: + sta_flags |= STA_FLG_MIMO_DIS_MSK; + break; + case WLAN_HT_CAP_SM_PS_DYNAMIC: + sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK; + break; + case WLAN_HT_CAP_SM_PS_DISABLED: + break; + default: + IWL_WARN(priv, "Invalid MIMO PS mode %d\n", mimo_ps_mode); + break; + } + + sta_flags |= cpu_to_le32( + (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS); + + sta_flags |= cpu_to_le32( + (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); + + if (iwl_legacy_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap)) + sta_flags |= STA_FLG_HT40_EN_MSK; + else + sta_flags &= ~STA_FLG_HT40_EN_MSK; + + priv->stations[index].sta.station_flags = sta_flags; + done: + return; +} + +/** + * iwl_legacy_prep_station - Prepare station information for addition + * + * should be called with sta_lock held + */ +u8 iwl_legacy_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + const u8 *addr, bool is_ap, struct ieee80211_sta *sta) +{ + struct iwl_station_entry *station; + int i; + u8 sta_id = IWL_INVALID_STATION; + u16 rate; + + if (is_ap) + sta_id = ctx->ap_sta_id; + else if (is_broadcast_ether_addr(addr)) + sta_id = ctx->bcast_sta_id; + else + for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) { + if (!compare_ether_addr(priv->stations[i].sta.sta.addr, + addr)) { + sta_id = i; + break; + } + + if (!priv->stations[i].used && + sta_id == IWL_INVALID_STATION) + sta_id = i; + } + + /* + * These two conditions have the same outcome, but keep them + * separate + */ + if (unlikely(sta_id == IWL_INVALID_STATION)) + return sta_id; + + /* + * uCode is not able to deal with multiple requests to add a + * station. Keep track if one is in progress so that we do not send + * another. + */ + if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) { + IWL_DEBUG_INFO(priv, + "STA %d already in process of being added.\n", + sta_id); + return sta_id; + } + + if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) && + (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) && + !compare_ether_addr(priv->stations[sta_id].sta.sta.addr, addr)) { + IWL_DEBUG_ASSOC(priv, + "STA %d (%pM) already added, not adding again.\n", + sta_id, addr); + return sta_id; + } + + station = &priv->stations[sta_id]; + station->used = IWL_STA_DRIVER_ACTIVE; + IWL_DEBUG_ASSOC(priv, "Add STA to driver ID %d: %pM\n", + sta_id, addr); + priv->num_stations++; + + /* Set up the REPLY_ADD_STA command to send to device */ + memset(&station->sta, 0, sizeof(struct iwl_legacy_addsta_cmd)); + memcpy(station->sta.sta.addr, addr, ETH_ALEN); + station->sta.mode = 0; + station->sta.sta.sta_id = sta_id; + station->sta.station_flags = ctx->station_flags; + station->ctxid = ctx->ctxid; + + if (sta) { + struct iwl_station_priv_common *sta_priv; + + sta_priv = (void *)sta->drv_priv; + sta_priv->ctx = ctx; + } + + /* + * OK to call unconditionally, since local stations (IBSS BSSID + * STA and broadcast STA) pass in a NULL sta, and mac80211 + * doesn't allow HT IBSS. + */ + iwl_legacy_set_ht_add_station(priv, sta_id, sta, ctx); + + /* 3945 only */ + rate = (priv->band == IEEE80211_BAND_5GHZ) ? + IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP; + /* Turn on both antennas for the station... */ + station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK); + + return sta_id; + +} +EXPORT_SYMBOL_GPL(iwl_legacy_prep_station); + +#define STA_WAIT_TIMEOUT (HZ/2) + +/** + * iwl_legacy_add_station_common - + */ +int +iwl_legacy_add_station_common(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + const u8 *addr, bool is_ap, + struct ieee80211_sta *sta, u8 *sta_id_r) +{ + unsigned long flags_spin; + int ret = 0; + u8 sta_id; + struct iwl_legacy_addsta_cmd sta_cmd; + + *sta_id_r = 0; + spin_lock_irqsave(&priv->sta_lock, flags_spin); + sta_id = iwl_legacy_prep_station(priv, ctx, addr, is_ap, sta); + if (sta_id == IWL_INVALID_STATION) { + IWL_ERR(priv, "Unable to prepare station %pM for addition\n", + addr); + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + return -EINVAL; + } + + /* + * uCode is not able to deal with multiple requests to add a + * station. Keep track if one is in progress so that we do not send + * another. + */ + if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) { + IWL_DEBUG_INFO(priv, + "STA %d already in process of being added.\n", + sta_id); + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + return -EEXIST; + } + + if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) && + (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) { + IWL_DEBUG_ASSOC(priv, + "STA %d (%pM) already added, not adding again.\n", + sta_id, addr); + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + return -EEXIST; + } + + priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS; + memcpy(&sta_cmd, &priv->stations[sta_id].sta, + sizeof(struct iwl_legacy_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + + /* Add station to device's station table */ + ret = iwl_legacy_send_add_sta(priv, &sta_cmd, CMD_SYNC); + if (ret) { + spin_lock_irqsave(&priv->sta_lock, flags_spin); + IWL_ERR(priv, "Adding station %pM failed.\n", + priv->stations[sta_id].sta.sta.addr); + priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; + priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + } + *sta_id_r = sta_id; + return ret; +} +EXPORT_SYMBOL(iwl_legacy_add_station_common); + +/** + * iwl_legacy_sta_ucode_deactivate - deactivate ucode status for a station + * + * priv->sta_lock must be held + */ +static void iwl_legacy_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id) +{ + /* Ucode must be active and driver must be non active */ + if ((priv->stations[sta_id].used & + (IWL_STA_UCODE_ACTIVE | IWL_STA_DRIVER_ACTIVE)) != + IWL_STA_UCODE_ACTIVE) + IWL_ERR(priv, "removed non active STA %u\n", sta_id); + + priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE; + + memset(&priv->stations[sta_id], 0, sizeof(struct iwl_station_entry)); + IWL_DEBUG_ASSOC(priv, "Removed STA %u\n", sta_id); +} + +static int iwl_legacy_send_remove_station(struct iwl_priv *priv, + const u8 *addr, int sta_id, + bool temporary) +{ + struct iwl_rx_packet *pkt; + int ret; + + unsigned long flags_spin; + struct iwl_rem_sta_cmd rm_sta_cmd; + + struct iwl_host_cmd cmd = { + .id = REPLY_REMOVE_STA, + .len = sizeof(struct iwl_rem_sta_cmd), + .flags = CMD_SYNC, + .data = &rm_sta_cmd, + }; + + memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd)); + rm_sta_cmd.num_sta = 1; + memcpy(&rm_sta_cmd.addr, addr, ETH_ALEN); + + cmd.flags |= CMD_WANT_SKB; + + ret = iwl_legacy_send_cmd(priv, &cmd); + + if (ret) + return ret; + + pkt = (struct iwl_rx_packet *)cmd.reply_page; + if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { + IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", + pkt->hdr.flags); + ret = -EIO; + } + + if (!ret) { + switch (pkt->u.rem_sta.status) { + case REM_STA_SUCCESS_MSK: + if (!temporary) { + spin_lock_irqsave(&priv->sta_lock, flags_spin); + iwl_legacy_sta_ucode_deactivate(priv, sta_id); + spin_unlock_irqrestore(&priv->sta_lock, + flags_spin); + } + IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); + break; + default: + ret = -EIO; + IWL_ERR(priv, "REPLY_REMOVE_STA failed\n"); + break; + } + } + iwl_legacy_free_pages(priv, cmd.reply_page); + + return ret; +} + +/** + * iwl_legacy_remove_station - Remove driver's knowledge of station. + */ +int iwl_legacy_remove_station(struct iwl_priv *priv, const u8 sta_id, + const u8 *addr) +{ + unsigned long flags; + + if (!iwl_legacy_is_ready(priv)) { + IWL_DEBUG_INFO(priv, + "Unable to remove station %pM, device not ready.\n", + addr); + /* + * It is typical for stations to be removed when we are + * going down. Return success since device will be down + * soon anyway + */ + return 0; + } + + IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n", + sta_id, addr); + + if (WARN_ON(sta_id == IWL_INVALID_STATION)) + return -EINVAL; + + spin_lock_irqsave(&priv->sta_lock, flags); + + if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { + IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n", + addr); + goto out_err; + } + + if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) { + IWL_DEBUG_INFO(priv, "Removing %pM but non UCODE active\n", + addr); + goto out_err; + } + + if (priv->stations[sta_id].used & IWL_STA_LOCAL) { + kfree(priv->stations[sta_id].lq); + priv->stations[sta_id].lq = NULL; + } + + priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; + + priv->num_stations--; + + BUG_ON(priv->num_stations < 0); + + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return iwl_legacy_send_remove_station(priv, addr, sta_id, false); +out_err: + spin_unlock_irqrestore(&priv->sta_lock, flags); + return -EINVAL; +} +EXPORT_SYMBOL_GPL(iwl_legacy_remove_station); + +/** + * iwl_legacy_clear_ucode_stations - clear ucode station table bits + * + * This function clears all the bits in the driver indicating + * which stations are active in the ucode. Call when something + * other than explicit station management would cause this in + * the ucode, e.g. unassociated RXON. + */ +void iwl_legacy_clear_ucode_stations(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + int i; + unsigned long flags_spin; + bool cleared = false; + + IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver\n"); + + spin_lock_irqsave(&priv->sta_lock, flags_spin); + for (i = 0; i < priv->hw_params.max_stations; i++) { + if (ctx && ctx->ctxid != priv->stations[i].ctxid) + continue; + + if (priv->stations[i].used & IWL_STA_UCODE_ACTIVE) { + IWL_DEBUG_INFO(priv, + "Clearing ucode active for station %d\n", i); + priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE; + cleared = true; + } + } + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + + if (!cleared) + IWL_DEBUG_INFO(priv, + "No active stations found to be cleared\n"); +} +EXPORT_SYMBOL(iwl_legacy_clear_ucode_stations); + +/** + * iwl_legacy_restore_stations() - Restore driver known stations to device + * + * All stations considered active by driver, but not present in ucode, is + * restored. + * + * Function sleeps. + */ +void +iwl_legacy_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +{ + struct iwl_legacy_addsta_cmd sta_cmd; + struct iwl_link_quality_cmd lq; + unsigned long flags_spin; + int i; + bool found = false; + int ret; + bool send_lq; + + if (!iwl_legacy_is_ready(priv)) { + IWL_DEBUG_INFO(priv, + "Not ready yet, not restoring any stations.\n"); + return; + } + + IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n"); + spin_lock_irqsave(&priv->sta_lock, flags_spin); + for (i = 0; i < priv->hw_params.max_stations; i++) { + if (ctx->ctxid != priv->stations[i].ctxid) + continue; + if ((priv->stations[i].used & IWL_STA_DRIVER_ACTIVE) && + !(priv->stations[i].used & IWL_STA_UCODE_ACTIVE)) { + IWL_DEBUG_ASSOC(priv, "Restoring sta %pM\n", + priv->stations[i].sta.sta.addr); + priv->stations[i].sta.mode = 0; + priv->stations[i].used |= IWL_STA_UCODE_INPROGRESS; + found = true; + } + } + + for (i = 0; i < priv->hw_params.max_stations; i++) { + if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) { + memcpy(&sta_cmd, &priv->stations[i].sta, + sizeof(struct iwl_legacy_addsta_cmd)); + send_lq = false; + if (priv->stations[i].lq) { + memcpy(&lq, priv->stations[i].lq, + sizeof(struct iwl_link_quality_cmd)); + send_lq = true; + } + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + ret = iwl_legacy_send_add_sta(priv, &sta_cmd, CMD_SYNC); + if (ret) { + spin_lock_irqsave(&priv->sta_lock, flags_spin); + IWL_ERR(priv, "Adding station %pM failed.\n", + priv->stations[i].sta.sta.addr); + priv->stations[i].used &= + ~IWL_STA_DRIVER_ACTIVE; + priv->stations[i].used &= + ~IWL_STA_UCODE_INPROGRESS; + spin_unlock_irqrestore(&priv->sta_lock, + flags_spin); + } + /* + * Rate scaling has already been initialized, send + * current LQ command + */ + if (send_lq) + iwl_legacy_send_lq_cmd(priv, ctx, &lq, + CMD_SYNC, true); + spin_lock_irqsave(&priv->sta_lock, flags_spin); + priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; + } + } + + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + if (!found) + IWL_DEBUG_INFO(priv, "Restoring all known stations" + " .... no stations to be restored.\n"); + else + IWL_DEBUG_INFO(priv, "Restoring all known stations" + " .... complete.\n"); +} +EXPORT_SYMBOL(iwl_legacy_restore_stations); + +int iwl_legacy_get_free_ucode_key_index(struct iwl_priv *priv) +{ + int i; + + for (i = 0; i < priv->sta_key_max_num; i++) + if (!test_and_set_bit(i, &priv->ucode_key_table)) + return i; + + return WEP_INVALID_OFFSET; +} +EXPORT_SYMBOL(iwl_legacy_get_free_ucode_key_index); + +void iwl_legacy_dealloc_bcast_stations(struct iwl_priv *priv) +{ + unsigned long flags; + int i; + + spin_lock_irqsave(&priv->sta_lock, flags); + for (i = 0; i < priv->hw_params.max_stations; i++) { + if (!(priv->stations[i].used & IWL_STA_BCAST)) + continue; + + priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE; + priv->num_stations--; + BUG_ON(priv->num_stations < 0); + kfree(priv->stations[i].lq); + priv->stations[i].lq = NULL; + } + spin_unlock_irqrestore(&priv->sta_lock, flags); +} +EXPORT_SYMBOL_GPL(iwl_legacy_dealloc_bcast_stations); + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +static void iwl_legacy_dump_lq_cmd(struct iwl_priv *priv, + struct iwl_link_quality_cmd *lq) +{ + int i; + IWL_DEBUG_RATE(priv, "lq station id 0x%x\n", lq->sta_id); + IWL_DEBUG_RATE(priv, "lq ant 0x%X 0x%X\n", + lq->general_params.single_stream_ant_msk, + lq->general_params.dual_stream_ant_msk); + + for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) + IWL_DEBUG_RATE(priv, "lq index %d 0x%X\n", + i, lq->rs_table[i].rate_n_flags); +} +#else +static inline void iwl_legacy_dump_lq_cmd(struct iwl_priv *priv, + struct iwl_link_quality_cmd *lq) +{ +} +#endif + +/** + * iwl_legacy_is_lq_table_valid() - Test one aspect of LQ cmd for validity + * + * It sometimes happens when a HT rate has been in use and we + * loose connectivity with AP then mac80211 will first tell us that the + * current channel is not HT anymore before removing the station. In such a + * scenario the RXON flags will be updated to indicate we are not + * communicating HT anymore, but the LQ command may still contain HT rates. + * Test for this to prevent driver from sending LQ command between the time + * RXON flags are updated and when LQ command is updated. + */ +static bool iwl_legacy_is_lq_table_valid(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct iwl_link_quality_cmd *lq) +{ + int i; + + if (ctx->ht.enabled) + return true; + + IWL_DEBUG_INFO(priv, "Channel %u is not an HT channel\n", + ctx->active.channel); + for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { + if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & + RATE_MCS_HT_MSK) { + IWL_DEBUG_INFO(priv, + "index %d of LQ expects HT channel\n", + i); + return false; + } + } + return true; +} + +/** + * iwl_legacy_send_lq_cmd() - Send link quality command + * @init: This command is sent as part of station initialization right + * after station has been added. + * + * The link quality command is sent as the last step of station creation. + * This is the special case in which init is set and we call a callback in + * this case to clear the state indicating that station creation is in + * progress. + */ +int iwl_legacy_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + struct iwl_link_quality_cmd *lq, u8 flags, bool init) +{ + int ret = 0; + unsigned long flags_spin; + + struct iwl_host_cmd cmd = { + .id = REPLY_TX_LINK_QUALITY_CMD, + .len = sizeof(struct iwl_link_quality_cmd), + .flags = flags, + .data = lq, + }; + + if (WARN_ON(lq->sta_id == IWL_INVALID_STATION)) + return -EINVAL; + + + spin_lock_irqsave(&priv->sta_lock, flags_spin); + if (!(priv->stations[lq->sta_id].used & IWL_STA_DRIVER_ACTIVE)) { + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + return -EINVAL; + } + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + + iwl_legacy_dump_lq_cmd(priv, lq); + BUG_ON(init && (cmd.flags & CMD_ASYNC)); + + if (iwl_legacy_is_lq_table_valid(priv, ctx, lq)) + ret = iwl_legacy_send_cmd(priv, &cmd); + else + ret = -EINVAL; + + if (cmd.flags & CMD_ASYNC) + return ret; + + if (init) { + IWL_DEBUG_INFO(priv, "init LQ command complete," + " clearing sta addition status for sta %d\n", + lq->sta_id); + spin_lock_irqsave(&priv->sta_lock, flags_spin); + priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + } + return ret; +} +EXPORT_SYMBOL(iwl_legacy_send_lq_cmd); + +int iwl_legacy_mac_sta_remove(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct iwl_priv *priv = hw->priv; + struct iwl_station_priv_common *sta_common = (void *)sta->drv_priv; + int ret; + + IWL_DEBUG_INFO(priv, "received request to remove station %pM\n", + sta->addr); + mutex_lock(&priv->mutex); + IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", + sta->addr); + ret = iwl_legacy_remove_station(priv, sta_common->sta_id, sta->addr); + if (ret) + IWL_ERR(priv, "Error removing station %pM\n", + sta->addr); + mutex_unlock(&priv->mutex); + return ret; +} +EXPORT_SYMBOL(iwl_legacy_mac_sta_remove); diff --git a/drivers/net/wireless/iwlegacy/iwl-sta.h b/drivers/net/wireless/iwlegacy/iwl-sta.h new file mode 100644 index 000000000000..67bd75fe01a1 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-sta.h @@ -0,0 +1,148 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ +#ifndef __iwl_legacy_sta_h__ +#define __iwl_legacy_sta_h__ + +#include "iwl-dev.h" + +#define HW_KEY_DYNAMIC 0 +#define HW_KEY_DEFAULT 1 + +#define IWL_STA_DRIVER_ACTIVE BIT(0) /* driver entry is active */ +#define IWL_STA_UCODE_ACTIVE BIT(1) /* ucode entry is active */ +#define IWL_STA_UCODE_INPROGRESS BIT(2) /* ucode entry is in process of + being activated */ +#define IWL_STA_LOCAL BIT(3) /* station state not directed by mac80211; + (this is for the IBSS BSSID stations) */ +#define IWL_STA_BCAST BIT(4) /* this station is the special bcast station */ + + +void iwl_legacy_restore_stations(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); +void iwl_legacy_clear_ucode_stations(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); +void iwl_legacy_dealloc_bcast_stations(struct iwl_priv *priv); +int iwl_legacy_get_free_ucode_key_index(struct iwl_priv *priv); +int iwl_legacy_send_add_sta(struct iwl_priv *priv, + struct iwl_legacy_addsta_cmd *sta, u8 flags); +int iwl_legacy_add_station_common(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + const u8 *addr, bool is_ap, + struct ieee80211_sta *sta, u8 *sta_id_r); +int iwl_legacy_remove_station(struct iwl_priv *priv, + const u8 sta_id, + const u8 *addr); +int iwl_legacy_mac_sta_remove(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta); + +u8 iwl_legacy_prep_station(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + const u8 *addr, bool is_ap, + struct ieee80211_sta *sta); + +int iwl_legacy_send_lq_cmd(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct iwl_link_quality_cmd *lq, + u8 flags, bool init); + +/** + * iwl_legacy_clear_driver_stations - clear knowledge of all stations from driver + * @priv: iwl priv struct + * + * This is called during iwl_down() to make sure that in the case + * we're coming there from a hardware restart mac80211 will be + * able to reconfigure stations -- if we're getting there in the + * normal down flow then the stations will already be cleared. + */ +static inline void iwl_legacy_clear_driver_stations(struct iwl_priv *priv) +{ + unsigned long flags; + struct iwl_rxon_context *ctx; + + spin_lock_irqsave(&priv->sta_lock, flags); + memset(priv->stations, 0, sizeof(priv->stations)); + priv->num_stations = 0; + + priv->ucode_key_table = 0; + + for_each_context(priv, ctx) { + /* + * Remove all key information that is not stored as part + * of station information since mac80211 may not have had + * a chance to remove all the keys. When device is + * reconfigured by mac80211 after an error all keys will + * be reconfigured. + */ + memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys)); + ctx->key_mapping_keys = 0; + } + + spin_unlock_irqrestore(&priv->sta_lock, flags); +} + +static inline int iwl_legacy_sta_id(struct ieee80211_sta *sta) +{ + if (WARN_ON(!sta)) + return IWL_INVALID_STATION; + + return ((struct iwl_station_priv_common *)sta->drv_priv)->sta_id; +} + +/** + * iwl_legacy_sta_id_or_broadcast - return sta_id or broadcast sta + * @priv: iwl priv + * @context: the current context + * @sta: mac80211 station + * + * In certain circumstances mac80211 passes a station pointer + * that may be %NULL, for example during TX or key setup. In + * that case, we need to use the broadcast station, so this + * inline wraps that pattern. + */ +static inline int iwl_legacy_sta_id_or_broadcast(struct iwl_priv *priv, + struct iwl_rxon_context *context, + struct ieee80211_sta *sta) +{ + int sta_id; + + if (!sta) + return context->bcast_sta_id; + + sta_id = iwl_legacy_sta_id(sta); + + /* + * mac80211 should not be passing a partially + * initialised station! + */ + WARN_ON(sta_id == IWL_INVALID_STATION); + + return sta_id; +} +#endif /* __iwl_legacy_sta_h__ */ diff --git a/drivers/net/wireless/iwlegacy/iwl-tx.c b/drivers/net/wireless/iwlegacy/iwl-tx.c new file mode 100644 index 000000000000..7db8340d1c07 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl-tx.c @@ -0,0 +1,637 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include +#include +#include "iwl-eeprom.h" +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-sta.h" +#include "iwl-io.h" +#include "iwl-helpers.h" + +/** + * iwl_legacy_txq_update_write_ptr - Send new write index to hardware + */ +void +iwl_legacy_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) +{ + u32 reg = 0; + int txq_id = txq->q.id; + + if (txq->need_update == 0) + return; + + /* if we're trying to save power */ + if (test_bit(STATUS_POWER_PMI, &priv->status)) { + /* wake up nic if it's powered down ... + * uCode will wake up, and interrupt us again, so next + * time we'll skip this part. */ + reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); + + if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { + IWL_DEBUG_INFO(priv, + "Tx queue %d requesting wakeup," + " GP1 = 0x%x\n", txq_id, reg); + iwl_legacy_set_bit(priv, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + return; + } + + iwl_legacy_write_direct32(priv, HBUS_TARG_WRPTR, + txq->q.write_ptr | (txq_id << 8)); + + /* + * else not in power-save mode, + * uCode will never sleep when we're + * trying to tx (during RFKILL, we're not trying to tx). + */ + } else + iwl_write32(priv, HBUS_TARG_WRPTR, + txq->q.write_ptr | (txq_id << 8)); + txq->need_update = 0; +} +EXPORT_SYMBOL(iwl_legacy_txq_update_write_ptr); + +/** + * iwl_legacy_tx_queue_free - Deallocate DMA queue. + * @txq: Transmit queue to deallocate. + * + * Empty queue by removing and destroying all BD's. + * Free all buffers. + * 0-fill, but do not free "txq" descriptor structure. + */ +void iwl_legacy_tx_queue_free(struct iwl_priv *priv, int txq_id) +{ + struct iwl_tx_queue *txq = &priv->txq[txq_id]; + struct iwl_queue *q = &txq->q; + struct device *dev = &priv->pci_dev->dev; + int i; + + if (q->n_bd == 0) + return; + + /* first, empty all BD's */ + for (; q->write_ptr != q->read_ptr; + q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd)) + priv->cfg->ops->lib->txq_free_tfd(priv, txq); + + /* De-alloc array of command/tx buffers */ + for (i = 0; i < TFD_TX_CMD_SLOTS; i++) + kfree(txq->cmd[i]); + + /* De-alloc circular buffer of TFDs */ + if (txq->q.n_bd) + dma_free_coherent(dev, priv->hw_params.tfd_size * + txq->q.n_bd, txq->tfds, txq->q.dma_addr); + + /* De-alloc array of per-TFD driver data */ + kfree(txq->txb); + txq->txb = NULL; + + /* deallocate arrays */ + kfree(txq->cmd); + kfree(txq->meta); + txq->cmd = NULL; + txq->meta = NULL; + + /* 0-fill queue descriptor structure */ + memset(txq, 0, sizeof(*txq)); +} +EXPORT_SYMBOL(iwl_legacy_tx_queue_free); + +/** + * iwl_legacy_cmd_queue_free - Deallocate DMA queue. + * @txq: Transmit queue to deallocate. + * + * Empty queue by removing and destroying all BD's. + * Free all buffers. + * 0-fill, but do not free "txq" descriptor structure. + */ +void iwl_legacy_cmd_queue_free(struct iwl_priv *priv) +{ + struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; + struct iwl_queue *q = &txq->q; + struct device *dev = &priv->pci_dev->dev; + int i; + bool huge = false; + + if (q->n_bd == 0) + return; + + for (; q->read_ptr != q->write_ptr; + q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd)) { + /* we have no way to tell if it is a huge cmd ATM */ + i = iwl_legacy_get_cmd_index(q, q->read_ptr, 0); + + if (txq->meta[i].flags & CMD_SIZE_HUGE) { + huge = true; + continue; + } + + pci_unmap_single(priv->pci_dev, + dma_unmap_addr(&txq->meta[i], mapping), + dma_unmap_len(&txq->meta[i], len), + PCI_DMA_BIDIRECTIONAL); + } + if (huge) { + i = q->n_window; + pci_unmap_single(priv->pci_dev, + dma_unmap_addr(&txq->meta[i], mapping), + dma_unmap_len(&txq->meta[i], len), + PCI_DMA_BIDIRECTIONAL); + } + + /* De-alloc array of command/tx buffers */ + for (i = 0; i <= TFD_CMD_SLOTS; i++) + kfree(txq->cmd[i]); + + /* De-alloc circular buffer of TFDs */ + if (txq->q.n_bd) + dma_free_coherent(dev, priv->hw_params.tfd_size * txq->q.n_bd, + txq->tfds, txq->q.dma_addr); + + /* deallocate arrays */ + kfree(txq->cmd); + kfree(txq->meta); + txq->cmd = NULL; + txq->meta = NULL; + + /* 0-fill queue descriptor structure */ + memset(txq, 0, sizeof(*txq)); +} +EXPORT_SYMBOL(iwl_legacy_cmd_queue_free); + +/*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** + * DMA services + * + * Theory of operation + * + * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer + * of buffer descriptors, each of which points to one or more data buffers for + * the device to read from or fill. Driver and device exchange status of each + * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty + * entries in each circular buffer, to protect against confusing empty and full + * queue states. + * + * The device reads or writes the data in the queues via the device's several + * DMA/FIFO channels. Each queue is mapped to a single DMA channel. + * + * For Tx queue, there are low mark and high mark limits. If, after queuing + * the packet for Tx, free space become < low mark, Tx queue stopped. When + * reclaiming packets (on 'tx done IRQ), if free space become > high mark, + * Tx queue resumed. + * + * See more detailed info in iwl-4965-hw.h. + ***************************************************/ + +int iwl_legacy_queue_space(const struct iwl_queue *q) +{ + int s = q->read_ptr - q->write_ptr; + + if (q->read_ptr > q->write_ptr) + s -= q->n_bd; + + if (s <= 0) + s += q->n_window; + /* keep some reserve to not confuse empty and full situations */ + s -= 2; + if (s < 0) + s = 0; + return s; +} +EXPORT_SYMBOL(iwl_legacy_queue_space); + + +/** + * iwl_legacy_queue_init - Initialize queue's high/low-water and read/write indexes + */ +static int iwl_legacy_queue_init(struct iwl_priv *priv, struct iwl_queue *q, + int count, int slots_num, u32 id) +{ + q->n_bd = count; + q->n_window = slots_num; + q->id = id; + + /* count must be power-of-two size, otherwise iwl_legacy_queue_inc_wrap + * and iwl_legacy_queue_dec_wrap are broken. */ + BUG_ON(!is_power_of_2(count)); + + /* slots_num must be power-of-two size, otherwise + * iwl_legacy_get_cmd_index is broken. */ + BUG_ON(!is_power_of_2(slots_num)); + + q->low_mark = q->n_window / 4; + if (q->low_mark < 4) + q->low_mark = 4; + + q->high_mark = q->n_window / 8; + if (q->high_mark < 2) + q->high_mark = 2; + + q->write_ptr = q->read_ptr = 0; + + return 0; +} + +/** + * iwl_legacy_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue + */ +static int iwl_legacy_tx_queue_alloc(struct iwl_priv *priv, + struct iwl_tx_queue *txq, u32 id) +{ + struct device *dev = &priv->pci_dev->dev; + size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX; + + /* Driver private data, only for Tx (not command) queues, + * not shared with device. */ + if (id != priv->cmd_queue) { + txq->txb = kzalloc(sizeof(txq->txb[0]) * + TFD_QUEUE_SIZE_MAX, GFP_KERNEL); + if (!txq->txb) { + IWL_ERR(priv, "kmalloc for auxiliary BD " + "structures failed\n"); + goto error; + } + } else { + txq->txb = NULL; + } + + /* Circular buffer of transmit frame descriptors (TFDs), + * shared with device */ + txq->tfds = dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr, + GFP_KERNEL); + if (!txq->tfds) { + IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", tfd_sz); + goto error; + } + txq->q.id = id; + + return 0; + + error: + kfree(txq->txb); + txq->txb = NULL; + + return -ENOMEM; +} + +/** + * iwl_legacy_tx_queue_init - Allocate and initialize one tx/cmd queue + */ +int iwl_legacy_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, + int slots_num, u32 txq_id) +{ + int i, len; + int ret; + int actual_slots = slots_num; + + /* + * Alloc buffer array for commands (Tx or other types of commands). + * For the command queue (#4/#9), allocate command space + one big + * command for scan, since scan command is very huge; the system will + * not have two scans at the same time, so only one is needed. + * For normal Tx queues (all other queues), no super-size command + * space is needed. + */ + if (txq_id == priv->cmd_queue) + actual_slots++; + + txq->meta = kzalloc(sizeof(struct iwl_cmd_meta) * actual_slots, + GFP_KERNEL); + txq->cmd = kzalloc(sizeof(struct iwl_device_cmd *) * actual_slots, + GFP_KERNEL); + + if (!txq->meta || !txq->cmd) + goto out_free_arrays; + + len = sizeof(struct iwl_device_cmd); + for (i = 0; i < actual_slots; i++) { + /* only happens for cmd queue */ + if (i == slots_num) + len = IWL_MAX_CMD_SIZE; + + txq->cmd[i] = kmalloc(len, GFP_KERNEL); + if (!txq->cmd[i]) + goto err; + } + + /* Alloc driver data array and TFD circular buffer */ + ret = iwl_legacy_tx_queue_alloc(priv, txq, txq_id); + if (ret) + goto err; + + txq->need_update = 0; + + /* + * For the default queues 0-3, set up the swq_id + * already -- all others need to get one later + * (if they need one at all). + */ + if (txq_id < 4) + iwl_legacy_set_swq_id(txq, txq_id, txq_id); + + /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise + * iwl_legacy_queue_inc_wrap and iwl_legacy_queue_dec_wrap are broken. */ + BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); + + /* Initialize queue's high/low-water marks, and head/tail indexes */ + iwl_legacy_queue_init(priv, &txq->q, + TFD_QUEUE_SIZE_MAX, slots_num, txq_id); + + /* Tell device where to find queue */ + priv->cfg->ops->lib->txq_init(priv, txq); + + return 0; +err: + for (i = 0; i < actual_slots; i++) + kfree(txq->cmd[i]); +out_free_arrays: + kfree(txq->meta); + kfree(txq->cmd); + + return -ENOMEM; +} +EXPORT_SYMBOL(iwl_legacy_tx_queue_init); + +void iwl_legacy_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, + int slots_num, u32 txq_id) +{ + int actual_slots = slots_num; + + if (txq_id == priv->cmd_queue) + actual_slots++; + + memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots); + + txq->need_update = 0; + + /* Initialize queue's high/low-water marks, and head/tail indexes */ + iwl_legacy_queue_init(priv, &txq->q, + TFD_QUEUE_SIZE_MAX, slots_num, txq_id); + + /* Tell device where to find queue */ + priv->cfg->ops->lib->txq_init(priv, txq); +} +EXPORT_SYMBOL(iwl_legacy_tx_queue_reset); + +/*************** HOST COMMAND QUEUE FUNCTIONS *****/ + +/** + * iwl_legacy_enqueue_hcmd - enqueue a uCode command + * @priv: device private data point + * @cmd: a point to the ucode command structure + * + * The function returns < 0 values to indicate the operation is + * failed. On success, it turns the index (> 0) of command in the + * command queue. + */ +int iwl_legacy_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) +{ + struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; + struct iwl_queue *q = &txq->q; + struct iwl_device_cmd *out_cmd; + struct iwl_cmd_meta *out_meta; + dma_addr_t phys_addr; + unsigned long flags; + int len; + u32 idx; + u16 fix_size; + + cmd->len = priv->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len); + fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr)); + + /* If any of the command structures end up being larger than + * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then + * we will need to increase the size of the TFD entries + * Also, check to see if command buffer should not exceed the size + * of device_cmd and max_cmd_size. */ + BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && + !(cmd->flags & CMD_SIZE_HUGE)); + BUG_ON(fix_size > IWL_MAX_CMD_SIZE); + + if (iwl_legacy_is_rfkill(priv) || iwl_legacy_is_ctkill(priv)) { + IWL_WARN(priv, "Not sending command - %s KILL\n", + iwl_legacy_is_rfkill(priv) ? "RF" : "CT"); + return -EIO; + } + + if (iwl_legacy_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { + IWL_ERR(priv, "No space in command queue\n"); + IWL_ERR(priv, "Restarting adapter due to queue full\n"); + queue_work(priv->workqueue, &priv->restart); + return -ENOSPC; + } + + spin_lock_irqsave(&priv->hcmd_lock, flags); + + /* If this is a huge cmd, mark the huge flag also on the meta.flags + * of the _original_ cmd. This is used for DMA mapping clean up. + */ + if (cmd->flags & CMD_SIZE_HUGE) { + idx = iwl_legacy_get_cmd_index(q, q->write_ptr, 0); + txq->meta[idx].flags = CMD_SIZE_HUGE; + } + + idx = iwl_legacy_get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); + out_cmd = txq->cmd[idx]; + out_meta = &txq->meta[idx]; + + memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */ + out_meta->flags = cmd->flags; + if (cmd->flags & CMD_WANT_SKB) + out_meta->source = cmd; + if (cmd->flags & CMD_ASYNC) + out_meta->callback = cmd->callback; + + out_cmd->hdr.cmd = cmd->id; + memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len); + + /* At this point, the out_cmd now has all of the incoming cmd + * information */ + + out_cmd->hdr.flags = 0; + out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(priv->cmd_queue) | + INDEX_TO_SEQ(q->write_ptr)); + if (cmd->flags & CMD_SIZE_HUGE) + out_cmd->hdr.sequence |= SEQ_HUGE_FRAME; + len = sizeof(struct iwl_device_cmd); + if (idx == TFD_CMD_SLOTS) + len = IWL_MAX_CMD_SIZE; + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + switch (out_cmd->hdr.cmd) { + case REPLY_TX_LINK_QUALITY_CMD: + case SENSITIVITY_CMD: + IWL_DEBUG_HC_DUMP(priv, + "Sending command %s (#%x), seq: 0x%04X, " + "%d bytes at %d[%d]:%d\n", + iwl_legacy_get_cmd_string(out_cmd->hdr.cmd), + out_cmd->hdr.cmd, + le16_to_cpu(out_cmd->hdr.sequence), fix_size, + q->write_ptr, idx, priv->cmd_queue); + break; + default: + IWL_DEBUG_HC(priv, "Sending command %s (#%x), seq: 0x%04X, " + "%d bytes at %d[%d]:%d\n", + iwl_legacy_get_cmd_string(out_cmd->hdr.cmd), + out_cmd->hdr.cmd, + le16_to_cpu(out_cmd->hdr.sequence), fix_size, + q->write_ptr, idx, priv->cmd_queue); + } +#endif + txq->need_update = 1; + + if (priv->cfg->ops->lib->txq_update_byte_cnt_tbl) + /* Set up entry in queue's byte count circular buffer */ + priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0); + + phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr, + fix_size, PCI_DMA_BIDIRECTIONAL); + dma_unmap_addr_set(out_meta, mapping, phys_addr); + dma_unmap_len_set(out_meta, len, fix_size); + + trace_iwlwifi_legacy_dev_hcmd(priv, &out_cmd->hdr, + fix_size, cmd->flags); + + priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, + phys_addr, fix_size, 1, + U32_PAD(cmd->len)); + + /* Increment and update queue's write index */ + q->write_ptr = iwl_legacy_queue_inc_wrap(q->write_ptr, q->n_bd); + iwl_legacy_txq_update_write_ptr(priv, txq); + + spin_unlock_irqrestore(&priv->hcmd_lock, flags); + return idx; +} + +/** + * iwl_legacy_hcmd_queue_reclaim - Reclaim TX command queue entries already Tx'd + * + * When FW advances 'R' index, all entries between old and new 'R' index + * need to be reclaimed. As result, some free space forms. If there is + * enough free space (> low mark), wake the stack that feeds us. + */ +static void iwl_legacy_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, + int idx, int cmd_idx) +{ + struct iwl_tx_queue *txq = &priv->txq[txq_id]; + struct iwl_queue *q = &txq->q; + int nfreed = 0; + + if ((idx >= q->n_bd) || (iwl_legacy_queue_used(q, idx) == 0)) { + IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, " + "is out of range [0-%d] %d %d.\n", txq_id, + idx, q->n_bd, q->write_ptr, q->read_ptr); + return; + } + + for (idx = iwl_legacy_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; + q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd)) { + + if (nfreed++ > 0) { + IWL_ERR(priv, "HCMD skipped: index (%d) %d %d\n", idx, + q->write_ptr, q->read_ptr); + queue_work(priv->workqueue, &priv->restart); + } + + } +} + +/** + * iwl_legacy_tx_cmd_complete - Pull unused buffers off the queue and reclaim them + * @rxb: Rx buffer to reclaim + * + * If an Rx buffer has an async callback associated with it the callback + * will be executed. The attached skb (if present) will only be freed + * if the callback returns 1 + */ +void +iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + u16 sequence = le16_to_cpu(pkt->hdr.sequence); + int txq_id = SEQ_TO_QUEUE(sequence); + int index = SEQ_TO_INDEX(sequence); + int cmd_index; + bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME); + struct iwl_device_cmd *cmd; + struct iwl_cmd_meta *meta; + struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; + + /* If a Tx command is being handled and it isn't in the actual + * command queue then there a command routing bug has been introduced + * in the queue management code. */ + if (WARN(txq_id != priv->cmd_queue, + "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n", + txq_id, priv->cmd_queue, sequence, + priv->txq[priv->cmd_queue].q.read_ptr, + priv->txq[priv->cmd_queue].q.write_ptr)) { + iwl_print_hex_error(priv, pkt, 32); + return; + } + + /* If this is a huge cmd, clear the huge flag on the meta.flags + * of the _original_ cmd. So that iwl_legacy_cmd_queue_free won't unmap + * the DMA buffer for the scan (huge) command. + */ + if (huge) { + cmd_index = iwl_legacy_get_cmd_index(&txq->q, index, 0); + txq->meta[cmd_index].flags = 0; + } + cmd_index = iwl_legacy_get_cmd_index(&txq->q, index, huge); + cmd = txq->cmd[cmd_index]; + meta = &txq->meta[cmd_index]; + + pci_unmap_single(priv->pci_dev, + dma_unmap_addr(meta, mapping), + dma_unmap_len(meta, len), + PCI_DMA_BIDIRECTIONAL); + + /* Input error checking is done when commands are added to queue. */ + if (meta->flags & CMD_WANT_SKB) { + meta->source->reply_page = (unsigned long)rxb_addr(rxb); + rxb->page = NULL; + } else if (meta->callback) + meta->callback(priv, cmd, pkt); + + iwl_legacy_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); + + if (!(meta->flags & CMD_ASYNC)) { + clear_bit(STATUS_HCMD_ACTIVE, &priv->status); + IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s\n", + iwl_legacy_get_cmd_string(cmd->hdr.cmd)); + wake_up_interruptible(&priv->wait_command_queue); + } + meta->flags = 0; +} +EXPORT_SYMBOL(iwl_legacy_tx_cmd_complete); diff --git a/drivers/net/wireless/iwlegacy/iwl3945-base.c b/drivers/net/wireless/iwlegacy/iwl3945-base.c new file mode 100644 index 000000000000..ef94d161b783 --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl3945-base.c @@ -0,0 +1,4294 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define DRV_NAME "iwl3945" + +#include "iwl-fh.h" +#include "iwl-3945-fh.h" +#include "iwl-commands.h" +#include "iwl-sta.h" +#include "iwl-3945.h" +#include "iwl-core.h" +#include "iwl-helpers.h" +#include "iwl-dev.h" +#include "iwl-spectrum.h" + +/* + * module name, copyright, version, etc. + */ + +#define DRV_DESCRIPTION \ +"Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux" + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +#define VD "d" +#else +#define VD +#endif + +/* + * add "s" to indicate spectrum measurement included. + * we add it here to be consistent with previous releases in which + * this was configurable. + */ +#define DRV_VERSION IWLWIFI_VERSION VD "s" +#define DRV_COPYRIGHT "Copyright(c) 2003-2011 Intel Corporation" +#define DRV_AUTHOR "" + +MODULE_DESCRIPTION(DRV_DESCRIPTION); +MODULE_VERSION(DRV_VERSION); +MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); +MODULE_LICENSE("GPL"); + + /* module parameters */ +struct iwl_mod_params iwl3945_mod_params = { + .sw_crypto = 1, + .restart_fw = 1, + /* the rest are 0 by default */ +}; + +/** + * iwl3945_get_antenna_flags - Get antenna flags for RXON command + * @priv: eeprom and antenna fields are used to determine antenna flags + * + * priv->eeprom39 is used to determine if antenna AUX/MAIN are reversed + * iwl3945_mod_params.antenna specifies the antenna diversity mode: + * + * IWL_ANTENNA_DIVERSITY - NIC selects best antenna by itself + * IWL_ANTENNA_MAIN - Force MAIN antenna + * IWL_ANTENNA_AUX - Force AUX antenna + */ +__le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv) +{ + struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; + + switch (iwl3945_mod_params.antenna) { + case IWL_ANTENNA_DIVERSITY: + return 0; + + case IWL_ANTENNA_MAIN: + if (eeprom->antenna_switch_type) + return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK; + return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK; + + case IWL_ANTENNA_AUX: + if (eeprom->antenna_switch_type) + return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK; + return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK; + } + + /* bad antenna selector value */ + IWL_ERR(priv, "Bad antenna selector value (0x%x)\n", + iwl3945_mod_params.antenna); + + return 0; /* "diversity" is default if error */ +} + +static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + unsigned long flags; + __le16 key_flags = 0; + int ret; + + key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); + key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); + + if (sta_id == priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id) + key_flags |= STA_KEY_MULTICAST_MSK; + + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + keyconf->hw_key_idx = keyconf->keyidx; + key_flags &= ~STA_KEY_FLG_INVALID; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; + priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; + memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, + keyconf->keylen); + + memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, + keyconf->keylen); + + if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) + == STA_KEY_FLG_NO_ENC) + priv->stations[sta_id].sta.key.key_offset = + iwl_legacy_get_free_ucode_key_index(priv); + /* else, we are overriding an existing key => no need to allocated room + * in uCode. */ + + WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, + "no space for a new key"); + + priv->stations[sta_id].sta.key.key_flags = key_flags; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + + IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n"); + + ret = iwl_legacy_send_add_sta(priv, + &priv->stations[sta_id].sta, CMD_ASYNC); + + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return ret; +} + +static int iwl3945_set_tkip_dynamic_key_info(struct iwl_priv *priv, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + return -EOPNOTSUPP; +} + +static int iwl3945_set_wep_dynamic_key_info(struct iwl_priv *priv, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + return -EOPNOTSUPP; +} + +static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) +{ + unsigned long flags; + struct iwl_legacy_addsta_cmd sta_cmd; + + spin_lock_irqsave(&priv->sta_lock, flags); + memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key)); + memset(&priv->stations[sta_id].sta.key, 0, + sizeof(struct iwl4965_keyinfo)); + priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_legacy_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n"); + return iwl_legacy_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +static int iwl3945_set_dynamic_key(struct iwl_priv *priv, + struct ieee80211_key_conf *keyconf, u8 sta_id) +{ + int ret = 0; + + keyconf->hw_key_idx = HW_KEY_DYNAMIC; + + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_CCMP: + ret = iwl3945_set_ccmp_dynamic_key_info(priv, keyconf, sta_id); + break; + case WLAN_CIPHER_SUITE_TKIP: + ret = iwl3945_set_tkip_dynamic_key_info(priv, keyconf, sta_id); + break; + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + ret = iwl3945_set_wep_dynamic_key_info(priv, keyconf, sta_id); + break; + default: + IWL_ERR(priv, "Unknown alg: %s alg=%x\n", __func__, + keyconf->cipher); + ret = -EINVAL; + } + + IWL_DEBUG_WEP(priv, "Set dynamic key: alg=%x len=%d idx=%d sta=%d ret=%d\n", + keyconf->cipher, keyconf->keylen, keyconf->keyidx, + sta_id, ret); + + return ret; +} + +static int iwl3945_remove_static_key(struct iwl_priv *priv) +{ + int ret = -EOPNOTSUPP; + + return ret; +} + +static int iwl3945_set_static_key(struct iwl_priv *priv, + struct ieee80211_key_conf *key) +{ + if (key->cipher == WLAN_CIPHER_SUITE_WEP40 || + key->cipher == WLAN_CIPHER_SUITE_WEP104) + return -EOPNOTSUPP; + + IWL_ERR(priv, "Static key invalid: cipher %x\n", key->cipher); + return -EINVAL; +} + +static void iwl3945_clear_free_frames(struct iwl_priv *priv) +{ + struct list_head *element; + + IWL_DEBUG_INFO(priv, "%d frames on pre-allocated heap on clear.\n", + priv->frames_count); + + while (!list_empty(&priv->free_frames)) { + element = priv->free_frames.next; + list_del(element); + kfree(list_entry(element, struct iwl3945_frame, list)); + priv->frames_count--; + } + + if (priv->frames_count) { + IWL_WARN(priv, "%d frames still in use. Did we lose one?\n", + priv->frames_count); + priv->frames_count = 0; + } +} + +static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl_priv *priv) +{ + struct iwl3945_frame *frame; + struct list_head *element; + if (list_empty(&priv->free_frames)) { + frame = kzalloc(sizeof(*frame), GFP_KERNEL); + if (!frame) { + IWL_ERR(priv, "Could not allocate frame!\n"); + return NULL; + } + + priv->frames_count++; + return frame; + } + + element = priv->free_frames.next; + list_del(element); + return list_entry(element, struct iwl3945_frame, list); +} + +static void iwl3945_free_frame(struct iwl_priv *priv, struct iwl3945_frame *frame) +{ + memset(frame, 0, sizeof(*frame)); + list_add(&frame->list, &priv->free_frames); +} + +unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, + struct ieee80211_hdr *hdr, + int left) +{ + + if (!iwl_legacy_is_associated(priv, IWL_RXON_CTX_BSS) || !priv->beacon_skb) + return 0; + + if (priv->beacon_skb->len > left) + return 0; + + memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len); + + return priv->beacon_skb->len; +} + +static int iwl3945_send_beacon_cmd(struct iwl_priv *priv) +{ + struct iwl3945_frame *frame; + unsigned int frame_size; + int rc; + u8 rate; + + frame = iwl3945_get_free_frame(priv); + + if (!frame) { + IWL_ERR(priv, "Could not obtain free frame buffer for beacon " + "command.\n"); + return -ENOMEM; + } + + rate = iwl_legacy_get_lowest_plcp(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); + + frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate); + + rc = iwl_legacy_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, + &frame->u.cmd[0]); + + iwl3945_free_frame(priv, frame); + + return rc; +} + +static void iwl3945_unset_hw_params(struct iwl_priv *priv) +{ + if (priv->_3945.shared_virt) + dma_free_coherent(&priv->pci_dev->dev, + sizeof(struct iwl3945_shared), + priv->_3945.shared_virt, + priv->_3945.shared_phys); +} + +static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, + struct ieee80211_tx_info *info, + struct iwl_device_cmd *cmd, + struct sk_buff *skb_frag, + int sta_id) +{ + struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload; + struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo; + + tx_cmd->sec_ctl = 0; + + switch (keyinfo->cipher) { + case WLAN_CIPHER_SUITE_CCMP: + tx_cmd->sec_ctl = TX_CMD_SEC_CCM; + memcpy(tx_cmd->key, keyinfo->key, keyinfo->keylen); + IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n"); + break; + + case WLAN_CIPHER_SUITE_TKIP: + break; + + case WLAN_CIPHER_SUITE_WEP104: + tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128; + /* fall through */ + case WLAN_CIPHER_SUITE_WEP40: + tx_cmd->sec_ctl |= TX_CMD_SEC_WEP | + (info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT; + + memcpy(&tx_cmd->key[3], keyinfo->key, keyinfo->keylen); + + IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption " + "with key %d\n", info->control.hw_key->hw_key_idx); + break; + + default: + IWL_ERR(priv, "Unknown encode cipher %x\n", keyinfo->cipher); + break; + } +} + +/* + * handle build REPLY_TX command notification. + */ +static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv, + struct iwl_device_cmd *cmd, + struct ieee80211_tx_info *info, + struct ieee80211_hdr *hdr, u8 std_id) +{ + struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload; + __le32 tx_flags = tx_cmd->tx_flags; + __le16 fc = hdr->frame_control; + + tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; + if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { + tx_flags |= TX_CMD_FLG_ACK_MSK; + if (ieee80211_is_mgmt(fc)) + tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; + if (ieee80211_is_probe_resp(fc) && + !(le16_to_cpu(hdr->seq_ctrl) & 0xf)) + tx_flags |= TX_CMD_FLG_TSF_MSK; + } else { + tx_flags &= (~TX_CMD_FLG_ACK_MSK); + tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; + } + + tx_cmd->sta_id = std_id; + if (ieee80211_has_morefrags(fc)) + tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; + + if (ieee80211_is_data_qos(fc)) { + u8 *qc = ieee80211_get_qos_ctl(hdr); + tx_cmd->tid_tspec = qc[0] & 0xf; + tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; + } else { + tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; + } + + iwl_legacy_tx_cmd_protection(priv, info, fc, &tx_flags); + + tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); + if (ieee80211_is_mgmt(fc)) { + if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc)) + tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3); + else + tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2); + } else { + tx_cmd->timeout.pm_frame_timeout = 0; + } + + tx_cmd->driver_txop = 0; + tx_cmd->tx_flags = tx_flags; + tx_cmd->next_frame_len = 0; +} + +/* + * start REPLY_TX command process + */ +static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct iwl3945_tx_cmd *tx_cmd; + struct iwl_tx_queue *txq = NULL; + struct iwl_queue *q = NULL; + struct iwl_device_cmd *out_cmd; + struct iwl_cmd_meta *out_meta; + dma_addr_t phys_addr; + dma_addr_t txcmd_phys; + int txq_id = skb_get_queue_mapping(skb); + u16 len, idx, hdr_len; + u8 id; + u8 unicast; + u8 sta_id; + u8 tid = 0; + __le16 fc; + u8 wait_write_ptr = 0; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + if (iwl_legacy_is_rfkill(priv)) { + IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n"); + goto drop_unlock; + } + + if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) { + IWL_ERR(priv, "ERROR: No TX rate available.\n"); + goto drop_unlock; + } + + unicast = !is_multicast_ether_addr(hdr->addr1); + id = 0; + + fc = hdr->frame_control; + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + if (ieee80211_is_auth(fc)) + IWL_DEBUG_TX(priv, "Sending AUTH frame\n"); + else if (ieee80211_is_assoc_req(fc)) + IWL_DEBUG_TX(priv, "Sending ASSOC frame\n"); + else if (ieee80211_is_reassoc_req(fc)) + IWL_DEBUG_TX(priv, "Sending REASSOC frame\n"); +#endif + + spin_unlock_irqrestore(&priv->lock, flags); + + hdr_len = ieee80211_hdrlen(fc); + + /* Find index into station table for destination station */ + sta_id = iwl_legacy_sta_id_or_broadcast( + priv, &priv->contexts[IWL_RXON_CTX_BSS], + info->control.sta); + if (sta_id == IWL_INVALID_STATION) { + IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", + hdr->addr1); + goto drop; + } + + IWL_DEBUG_RATE(priv, "station Id %d\n", sta_id); + + if (ieee80211_is_data_qos(fc)) { + u8 *qc = ieee80211_get_qos_ctl(hdr); + tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; + if (unlikely(tid >= MAX_TID_COUNT)) + goto drop; + } + + /* Descriptor for chosen Tx queue */ + txq = &priv->txq[txq_id]; + q = &txq->q; + + if ((iwl_legacy_queue_space(q) < q->high_mark)) + goto drop; + + spin_lock_irqsave(&priv->lock, flags); + + idx = iwl_legacy_get_cmd_index(q, q->write_ptr, 0); + + /* Set up driver data for this TFD */ + memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); + txq->txb[q->write_ptr].skb = skb; + txq->txb[q->write_ptr].ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + /* Init first empty entry in queue's array of Tx/cmd buffers */ + out_cmd = txq->cmd[idx]; + out_meta = &txq->meta[idx]; + tx_cmd = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload; + memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); + memset(tx_cmd, 0, sizeof(*tx_cmd)); + + /* + * Set up the Tx-command (not MAC!) header. + * Store the chosen Tx queue and TFD index within the sequence field; + * after Tx, uCode's Tx response will return this value so driver can + * locate the frame within the tx queue and do post-tx processing. + */ + out_cmd->hdr.cmd = REPLY_TX; + out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | + INDEX_TO_SEQ(q->write_ptr))); + + /* Copy MAC header from skb into command buffer */ + memcpy(tx_cmd->hdr, hdr, hdr_len); + + + if (info->control.hw_key) + iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, sta_id); + + /* TODO need this for burst mode later on */ + iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, sta_id); + + /* set is_hcca to 0; it probably will never be implemented */ + iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0); + + /* Total # bytes to be transmitted */ + len = (u16)skb->len; + tx_cmd->len = cpu_to_le16(len); + + iwl_legacy_dbg_log_tx_data_frame(priv, len, hdr); + iwl_legacy_update_stats(priv, true, fc, len); + tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; + tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; + + if (!ieee80211_has_morefrags(hdr->frame_control)) { + txq->need_update = 1; + } else { + wait_write_ptr = 1; + txq->need_update = 0; + } + + IWL_DEBUG_TX(priv, "sequence nr = 0X%x\n", + le16_to_cpu(out_cmd->hdr.sequence)); + IWL_DEBUG_TX(priv, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); + iwl_print_hex_dump(priv, IWL_DL_TX, tx_cmd, sizeof(*tx_cmd)); + iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, + ieee80211_hdrlen(fc)); + + /* + * Use the first empty entry in this queue's command buffer array + * to contain the Tx command and MAC header concatenated together + * (payload data will be in another buffer). + * Size of this varies, due to varying MAC header length. + * If end is not dword aligned, we'll have 2 extra bytes at the end + * of the MAC header (device reads on dword boundaries). + * We'll tell device about this padding later. + */ + len = sizeof(struct iwl3945_tx_cmd) + + sizeof(struct iwl_cmd_header) + hdr_len; + len = (len + 3) & ~3; + + /* Physical address of this Tx command's header (not MAC header!), + * within command buffer array. */ + txcmd_phys = pci_map_single(priv->pci_dev, &out_cmd->hdr, + len, PCI_DMA_TODEVICE); + /* we do not map meta data ... so we can safely access address to + * provide to unmap command*/ + dma_unmap_addr_set(out_meta, mapping, txcmd_phys); + dma_unmap_len_set(out_meta, len, len); + + /* Add buffer containing Tx command and MAC(!) header to TFD's + * first entry */ + priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, + txcmd_phys, len, 1, 0); + + + /* Set up TFD's 2nd entry to point directly to remainder of skb, + * if any (802.11 null frames have no payload). */ + len = skb->len - hdr_len; + if (len) { + phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, + len, PCI_DMA_TODEVICE); + priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, + phys_addr, len, + 0, U32_PAD(len)); + } + + + /* Tell device the write index *just past* this latest filled TFD */ + q->write_ptr = iwl_legacy_queue_inc_wrap(q->write_ptr, q->n_bd); + iwl_legacy_txq_update_write_ptr(priv, txq); + spin_unlock_irqrestore(&priv->lock, flags); + + if ((iwl_legacy_queue_space(q) < q->high_mark) + && priv->mac80211_registered) { + if (wait_write_ptr) { + spin_lock_irqsave(&priv->lock, flags); + txq->need_update = 1; + iwl_legacy_txq_update_write_ptr(priv, txq); + spin_unlock_irqrestore(&priv->lock, flags); + } + + iwl_legacy_stop_queue(priv, txq); + } + + return 0; + +drop_unlock: + spin_unlock_irqrestore(&priv->lock, flags); +drop: + return -1; +} + +static int iwl3945_get_measurement(struct iwl_priv *priv, + struct ieee80211_measurement_params *params, + u8 type) +{ + struct iwl_spectrum_cmd spectrum; + struct iwl_rx_packet *pkt; + struct iwl_host_cmd cmd = { + .id = REPLY_SPECTRUM_MEASUREMENT_CMD, + .data = (void *)&spectrum, + .flags = CMD_WANT_SKB, + }; + u32 add_time = le64_to_cpu(params->start_time); + int rc; + int spectrum_resp_status; + int duration = le16_to_cpu(params->duration); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + if (iwl_legacy_is_associated(priv, IWL_RXON_CTX_BSS)) + add_time = iwl_legacy_usecs_to_beacons(priv, + le64_to_cpu(params->start_time) - priv->_3945.last_tsf, + le16_to_cpu(ctx->timing.beacon_interval)); + + memset(&spectrum, 0, sizeof(spectrum)); + + spectrum.channel_count = cpu_to_le16(1); + spectrum.flags = + RXON_FLG_TSF2HOST_MSK | RXON_FLG_ANT_A_MSK | RXON_FLG_DIS_DIV_MSK; + spectrum.filter_flags = MEASUREMENT_FILTER_FLAG; + cmd.len = sizeof(spectrum); + spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len)); + + if (iwl_legacy_is_associated(priv, IWL_RXON_CTX_BSS)) + spectrum.start_time = + iwl_legacy_add_beacon_time(priv, + priv->_3945.last_beacon_time, add_time, + le16_to_cpu(ctx->timing.beacon_interval)); + else + spectrum.start_time = 0; + + spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT); + spectrum.channels[0].channel = params->channel; + spectrum.channels[0].type = type; + if (ctx->active.flags & RXON_FLG_BAND_24G_MSK) + spectrum.flags |= RXON_FLG_BAND_24G_MSK | + RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK; + + rc = iwl_legacy_send_cmd_sync(priv, &cmd); + if (rc) + return rc; + + pkt = (struct iwl_rx_packet *)cmd.reply_page; + if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { + IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n"); + rc = -EIO; + } + + spectrum_resp_status = le16_to_cpu(pkt->u.spectrum.status); + switch (spectrum_resp_status) { + case 0: /* Command will be handled */ + if (pkt->u.spectrum.id != 0xff) { + IWL_DEBUG_INFO(priv, "Replaced existing measurement: %d\n", + pkt->u.spectrum.id); + priv->measurement_status &= ~MEASUREMENT_READY; + } + priv->measurement_status |= MEASUREMENT_ACTIVE; + rc = 0; + break; + + case 1: /* Command will not be handled */ + rc = -EAGAIN; + break; + } + + iwl_legacy_free_pages(priv, cmd.reply_page); + + return rc; +} + +static void iwl3945_rx_reply_alive(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_alive_resp *palive; + struct delayed_work *pwork; + + palive = &pkt->u.alive_frame; + + IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision " + "0x%01X 0x%01X\n", + palive->is_valid, palive->ver_type, + palive->ver_subtype); + + if (palive->ver_subtype == INITIALIZE_SUBTYPE) { + IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); + memcpy(&priv->card_alive_init, &pkt->u.alive_frame, + sizeof(struct iwl_alive_resp)); + pwork = &priv->init_alive_start; + } else { + IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); + memcpy(&priv->card_alive, &pkt->u.alive_frame, + sizeof(struct iwl_alive_resp)); + pwork = &priv->alive_start; + iwl3945_disable_events(priv); + } + + /* We delay the ALIVE response by 5ms to + * give the HW RF Kill time to activate... */ + if (palive->is_valid == UCODE_VALID_OK) + queue_delayed_work(priv->workqueue, pwork, + msecs_to_jiffies(5)); + else + IWL_WARN(priv, "uCode did not respond OK.\n"); +} + +static void iwl3945_rx_reply_add_sta(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + struct iwl_rx_packet *pkt = rxb_addr(rxb); +#endif + + IWL_DEBUG_RX(priv, "Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status); +} + +static void iwl3945_rx_beacon_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status); +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + u8 rate = beacon->beacon_notify_hdr.rate; + + IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d " + "tsf %d %d rate %d\n", + le32_to_cpu(beacon->beacon_notify_hdr.status) & TX_STATUS_MSK, + beacon->beacon_notify_hdr.failure_frame, + le32_to_cpu(beacon->ibss_mgr_status), + le32_to_cpu(beacon->high_tsf), + le32_to_cpu(beacon->low_tsf), rate); +#endif + + priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); + +} + +/* Handle notification from uCode that card's power state is changing + * due to software, hardware, or critical temperature RFKILL */ +static void iwl3945_rx_card_state_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); + unsigned long status = priv->status; + + IWL_WARN(priv, "Card state received: HW:%s SW:%s\n", + (flags & HW_CARD_DISABLED) ? "Kill" : "On", + (flags & SW_CARD_DISABLED) ? "Kill" : "On"); + + iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, + CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); + + if (flags & HW_CARD_DISABLED) + set_bit(STATUS_RF_KILL_HW, &priv->status); + else + clear_bit(STATUS_RF_KILL_HW, &priv->status); + + + iwl_legacy_scan_cancel(priv); + + if ((test_bit(STATUS_RF_KILL_HW, &status) != + test_bit(STATUS_RF_KILL_HW, &priv->status))) + wiphy_rfkill_set_hw_state(priv->hw->wiphy, + test_bit(STATUS_RF_KILL_HW, &priv->status)); + else + wake_up_interruptible(&priv->wait_command_queue); +} + +/** + * iwl3945_setup_rx_handlers - Initialize Rx handler callbacks + * + * Setup the RX handlers for each of the reply types sent from the uCode + * to the host. + * + * This function chains into the hardware specific files for them to setup + * any hardware specific handlers as well. + */ +static void iwl3945_setup_rx_handlers(struct iwl_priv *priv) +{ + priv->rx_handlers[REPLY_ALIVE] = iwl3945_rx_reply_alive; + priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta; + priv->rx_handlers[REPLY_ERROR] = iwl_legacy_rx_reply_error; + priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_legacy_rx_csa; + priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] = + iwl_legacy_rx_spectrum_measure_notif; + priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_legacy_rx_pm_sleep_notif; + priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = + iwl_legacy_rx_pm_debug_statistics_notif; + priv->rx_handlers[BEACON_NOTIFICATION] = iwl3945_rx_beacon_notif; + + /* + * The same handler is used for both the REPLY to a discrete + * statistics request from the host as well as for the periodic + * statistics notifications (after received beacons) from the uCode. + */ + priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_reply_statistics; + priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics; + + iwl_legacy_setup_rx_scan_handlers(priv); + priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif; + + /* Set up hardware specific Rx handlers */ + iwl3945_hw_rx_handler_setup(priv); +} + +/************************** RX-FUNCTIONS ****************************/ +/* + * Rx theory of operation + * + * The host allocates 32 DMA target addresses and passes the host address + * to the firmware at register IWL_RFDS_TABLE_LOWER + N * RFD_SIZE where N is + * 0 to 31 + * + * Rx Queue Indexes + * The host/firmware share two index registers for managing the Rx buffers. + * + * The READ index maps to the first position that the firmware may be writing + * to -- the driver can read up to (but not including) this position and get + * good data. + * The READ index is managed by the firmware once the card is enabled. + * + * The WRITE index maps to the last position the driver has read from -- the + * position preceding WRITE is the last slot the firmware can place a packet. + * + * The queue is empty (no good data) if WRITE = READ - 1, and is full if + * WRITE = READ. + * + * During initialization, the host sets up the READ queue position to the first + * INDEX position, and WRITE to the last (READ - 1 wrapped) + * + * When the firmware places a packet in a buffer, it will advance the READ index + * and fire the RX interrupt. The driver can then query the READ index and + * process as many packets as possible, moving the WRITE index forward as it + * resets the Rx queue buffers with new memory. + * + * The management in the driver is as follows: + * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When + * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled + * to replenish the iwl->rxq->rx_free. + * + In iwl3945_rx_replenish (scheduled) if 'processed' != 'read' then the + * iwl->rxq is replenished and the READ INDEX is updated (updating the + * 'processed' and 'read' driver indexes as well) + * + A received packet is processed and handed to the kernel network stack, + * detached from the iwl->rxq. The driver 'processed' index is updated. + * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free + * list. If there are no allocated buffers in iwl->rxq->rx_free, the READ + * INDEX is not incremented and iwl->status(RX_STALLED) is set. If there + * were enough free buffers and RX_STALLED is set it is cleared. + * + * + * Driver sequence: + * + * iwl3945_rx_replenish() Replenishes rx_free list from rx_used, and calls + * iwl3945_rx_queue_restock + * iwl3945_rx_queue_restock() Moves available buffers from rx_free into Rx + * queue, updates firmware pointers, and updates + * the WRITE index. If insufficient rx_free buffers + * are available, schedules iwl3945_rx_replenish + * + * -- enable interrupts -- + * ISR - iwl3945_rx() Detach iwl_rx_mem_buffers from pool up to the + * READ INDEX, detaching the SKB from the pool. + * Moves the packet buffer from queue to rx_used. + * Calls iwl3945_rx_queue_restock to refill any empty + * slots. + * ... + * + */ + +/** + * iwl3945_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr + */ +static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl_priv *priv, + dma_addr_t dma_addr) +{ + return cpu_to_le32((u32)dma_addr); +} + +/** + * iwl3945_rx_queue_restock - refill RX queue from pre-allocated pool + * + * If there are slots in the RX queue that need to be restocked, + * and we have free pre-allocated buffers, fill the ranks as much + * as we can, pulling from rx_free. + * + * This moves the 'write' index forward to catch up with 'processed', and + * also updates the memory address in the firmware to reference the new + * target buffer. + */ +static void iwl3945_rx_queue_restock(struct iwl_priv *priv) +{ + struct iwl_rx_queue *rxq = &priv->rxq; + struct list_head *element; + struct iwl_rx_mem_buffer *rxb; + unsigned long flags; + int write; + + spin_lock_irqsave(&rxq->lock, flags); + write = rxq->write & ~0x7; + while ((iwl_legacy_rx_queue_space(rxq) > 0) && (rxq->free_count)) { + /* Get next free Rx buffer, remove from free list */ + element = rxq->rx_free.next; + rxb = list_entry(element, struct iwl_rx_mem_buffer, list); + list_del(element); + + /* Point to Rx buffer via next RBD in circular buffer */ + rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->page_dma); + rxq->queue[rxq->write] = rxb; + rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; + rxq->free_count--; + } + spin_unlock_irqrestore(&rxq->lock, flags); + /* If the pre-allocated buffer pool is dropping low, schedule to + * refill it */ + if (rxq->free_count <= RX_LOW_WATERMARK) + queue_work(priv->workqueue, &priv->rx_replenish); + + + /* If we've added more space for the firmware to place data, tell it. + * Increment device's write pointer in multiples of 8. */ + if ((rxq->write_actual != (rxq->write & ~0x7)) + || (abs(rxq->write - rxq->read) > 7)) { + spin_lock_irqsave(&rxq->lock, flags); + rxq->need_update = 1; + spin_unlock_irqrestore(&rxq->lock, flags); + iwl_legacy_rx_queue_update_write_ptr(priv, rxq); + } +} + +/** + * iwl3945_rx_replenish - Move all used packet from rx_used to rx_free + * + * When moving to rx_free an SKB is allocated for the slot. + * + * Also restock the Rx queue via iwl3945_rx_queue_restock. + * This is called as a scheduled work item (except for during initialization) + */ +static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority) +{ + struct iwl_rx_queue *rxq = &priv->rxq; + struct list_head *element; + struct iwl_rx_mem_buffer *rxb; + struct page *page; + unsigned long flags; + gfp_t gfp_mask = priority; + + while (1) { + spin_lock_irqsave(&rxq->lock, flags); + + if (list_empty(&rxq->rx_used)) { + spin_unlock_irqrestore(&rxq->lock, flags); + return; + } + spin_unlock_irqrestore(&rxq->lock, flags); + + if (rxq->free_count > RX_LOW_WATERMARK) + gfp_mask |= __GFP_NOWARN; + + if (priv->hw_params.rx_page_order > 0) + gfp_mask |= __GFP_COMP; + + /* Alloc a new receive buffer */ + page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order); + if (!page) { + if (net_ratelimit()) + IWL_DEBUG_INFO(priv, "Failed to allocate SKB buffer.\n"); + if ((rxq->free_count <= RX_LOW_WATERMARK) && + net_ratelimit()) + IWL_CRIT(priv, "Failed to allocate SKB buffer with %s. Only %u free buffers remaining.\n", + priority == GFP_ATOMIC ? "GFP_ATOMIC" : "GFP_KERNEL", + rxq->free_count); + /* We don't reschedule replenish work here -- we will + * call the restock method and if it still needs + * more buffers it will schedule replenish */ + break; + } + + spin_lock_irqsave(&rxq->lock, flags); + if (list_empty(&rxq->rx_used)) { + spin_unlock_irqrestore(&rxq->lock, flags); + __free_pages(page, priv->hw_params.rx_page_order); + return; + } + element = rxq->rx_used.next; + rxb = list_entry(element, struct iwl_rx_mem_buffer, list); + list_del(element); + spin_unlock_irqrestore(&rxq->lock, flags); + + rxb->page = page; + /* Get physical address of RB/SKB */ + rxb->page_dma = pci_map_page(priv->pci_dev, page, 0, + PAGE_SIZE << priv->hw_params.rx_page_order, + PCI_DMA_FROMDEVICE); + + spin_lock_irqsave(&rxq->lock, flags); + + list_add_tail(&rxb->list, &rxq->rx_free); + rxq->free_count++; + priv->alloc_rxb_page++; + + spin_unlock_irqrestore(&rxq->lock, flags); + } +} + +void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) +{ + unsigned long flags; + int i; + spin_lock_irqsave(&rxq->lock, flags); + INIT_LIST_HEAD(&rxq->rx_free); + INIT_LIST_HEAD(&rxq->rx_used); + /* Fill the rx_used queue with _all_ of the Rx buffers */ + for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { + /* In the reset function, these buffers may have been allocated + * to an SKB, so we need to unmap and free potential storage */ + if (rxq->pool[i].page != NULL) { + pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, + PAGE_SIZE << priv->hw_params.rx_page_order, + PCI_DMA_FROMDEVICE); + __iwl_legacy_free_pages(priv, rxq->pool[i].page); + rxq->pool[i].page = NULL; + } + list_add_tail(&rxq->pool[i].list, &rxq->rx_used); + } + + /* 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->write_actual = 0; + rxq->free_count = 0; + spin_unlock_irqrestore(&rxq->lock, flags); +} + +void iwl3945_rx_replenish(void *data) +{ + struct iwl_priv *priv = data; + unsigned long flags; + + iwl3945_rx_allocate(priv, GFP_KERNEL); + + spin_lock_irqsave(&priv->lock, flags); + iwl3945_rx_queue_restock(priv); + spin_unlock_irqrestore(&priv->lock, flags); +} + +static void iwl3945_rx_replenish_now(struct iwl_priv *priv) +{ + iwl3945_rx_allocate(priv, GFP_ATOMIC); + + iwl3945_rx_queue_restock(priv); +} + + +/* Assumes that the skb field of the buffers in 'pool' is kept accurate. + * If an SKB has been detached, the POOL needs to have its SKB set to NULL + * This free routine walks the list of POOL entries and if SKB is set to + * non NULL it is unmapped and freed + */ +static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) +{ + int i; + for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { + if (rxq->pool[i].page != NULL) { + pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, + PAGE_SIZE << priv->hw_params.rx_page_order, + PCI_DMA_FROMDEVICE); + __iwl_legacy_free_pages(priv, rxq->pool[i].page); + rxq->pool[i].page = NULL; + } + } + + dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, + rxq->bd_dma); + dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status), + rxq->rb_stts, rxq->rb_stts_dma); + rxq->bd = NULL; + rxq->rb_stts = NULL; +} + + +/* Convert linear signal-to-noise ratio into dB */ +static u8 ratio2dB[100] = { +/* 0 1 2 3 4 5 6 7 8 9 */ + 0, 0, 6, 10, 12, 14, 16, 17, 18, 19, /* 00 - 09 */ + 20, 21, 22, 22, 23, 23, 24, 25, 26, 26, /* 10 - 19 */ + 26, 26, 26, 27, 27, 28, 28, 28, 29, 29, /* 20 - 29 */ + 29, 30, 30, 30, 31, 31, 31, 31, 32, 32, /* 30 - 39 */ + 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, /* 40 - 49 */ + 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, /* 50 - 59 */ + 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, /* 60 - 69 */ + 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, /* 70 - 79 */ + 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, /* 80 - 89 */ + 39, 39, 39, 39, 39, 40, 40, 40, 40, 40 /* 90 - 99 */ +}; + +/* Calculates a relative dB value from a ratio of linear + * (i.e. not dB) signal levels. + * Conversion assumes that levels are voltages (20*log), not powers (10*log). */ +int iwl3945_calc_db_from_ratio(int sig_ratio) +{ + /* 1000:1 or higher just report as 60 dB */ + if (sig_ratio >= 1000) + return 60; + + /* 100:1 or higher, divide by 10 and use table, + * add 20 dB to make up for divide by 10 */ + if (sig_ratio >= 100) + return 20 + (int)ratio2dB[sig_ratio/10]; + + /* We shouldn't see this */ + if (sig_ratio < 1) + return 0; + + /* Use table for ratios 1:1 - 99:1 */ + return (int)ratio2dB[sig_ratio]; +} + +/** + * iwl3945_rx_handle - Main entry function for receiving responses from uCode + * + * Uses the priv->rx_handlers callback function array to invoke + * the appropriate handlers, including command responses, + * frame-received notifications, and other notifications. + */ +static void iwl3945_rx_handle(struct iwl_priv *priv) +{ + struct iwl_rx_mem_buffer *rxb; + struct iwl_rx_packet *pkt; + struct iwl_rx_queue *rxq = &priv->rxq; + u32 r, i; + int reclaim; + unsigned long flags; + u8 fill_rx = 0; + u32 count = 8; + int total_empty = 0; + + /* uCode's read index (stored in shared DRAM) indicates the last Rx + * buffer that the driver may process (last buffer filled by ucode). */ + r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF; + i = rxq->read; + + /* calculate total frames need to be restock after handling RX */ + total_empty = r - rxq->write_actual; + if (total_empty < 0) + total_empty += RX_QUEUE_SIZE; + + if (total_empty > (RX_QUEUE_SIZE / 2)) + fill_rx = 1; + /* Rx interrupt, but nothing sent from uCode */ + if (i == r) + IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i); + + while (i != r) { + int len; + + rxb = rxq->queue[i]; + + /* If an RXB doesn't have a Rx queue slot associated with it, + * then a bug has been introduced in the queue refilling + * routines -- catch it here */ + BUG_ON(rxb == NULL); + + rxq->queue[i] = NULL; + + pci_unmap_page(priv->pci_dev, rxb->page_dma, + PAGE_SIZE << priv->hw_params.rx_page_order, + PCI_DMA_FROMDEVICE); + pkt = rxb_addr(rxb); + + len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; + len += sizeof(u32); /* account for status word */ + trace_iwlwifi_legacy_dev_rx(priv, pkt, len); + + /* Reclaim a command buffer only if this packet is a response + * to a (driver-originated) command. + * If the packet (e.g. Rx frame) originated from uCode, + * there is no command buffer to reclaim. + * Ucode should set SEQ_RX_FRAME bit if ucode-originated, + * but apparently a few don't get set; catch them here. */ + reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) && + (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && + (pkt->hdr.cmd != REPLY_TX); + + /* Based on type of command response or notification, + * handle those that need handling via function in + * rx_handlers table. See iwl3945_setup_rx_handlers() */ + if (priv->rx_handlers[pkt->hdr.cmd]) { + IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, i, + iwl_legacy_get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); + priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; + priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); + } else { + /* No handling needed */ + IWL_DEBUG_RX(priv, + "r %d i %d No handler needed for %s, 0x%02x\n", + r, i, iwl_legacy_get_cmd_string(pkt->hdr.cmd), + pkt->hdr.cmd); + } + + /* + * XXX: After here, we should always check rxb->page + * against NULL before touching it or its virtual + * memory (pkt). Because some rx_handler might have + * already taken or freed the pages. + */ + + if (reclaim) { + /* Invoke any callbacks, transfer the buffer to caller, + * and fire off the (possibly) blocking iwl_legacy_send_cmd() + * as we reclaim the driver command queue */ + if (rxb->page) + iwl_legacy_tx_cmd_complete(priv, rxb); + else + IWL_WARN(priv, "Claim null rxb?\n"); + } + + /* Reuse the page if possible. For notification packets and + * SKBs that fail to Rx correctly, add them back into the + * rx_free list for reuse later. */ + spin_lock_irqsave(&rxq->lock, flags); + if (rxb->page != NULL) { + rxb->page_dma = pci_map_page(priv->pci_dev, rxb->page, + 0, PAGE_SIZE << priv->hw_params.rx_page_order, + PCI_DMA_FROMDEVICE); + list_add_tail(&rxb->list, &rxq->rx_free); + rxq->free_count++; + } else + list_add_tail(&rxb->list, &rxq->rx_used); + + spin_unlock_irqrestore(&rxq->lock, flags); + + i = (i + 1) & RX_QUEUE_MASK; + /* If there are a lot of unused frames, + * restock the Rx queue so ucode won't assert. */ + if (fill_rx) { + count++; + if (count >= 8) { + rxq->read = i; + iwl3945_rx_replenish_now(priv); + count = 0; + } + } + } + + /* Backtrack one entry */ + rxq->read = i; + if (fill_rx) + iwl3945_rx_replenish_now(priv); + else + iwl3945_rx_queue_restock(priv); +} + +/* call this function to flush any scheduled tasklet */ +static inline void iwl3945_synchronize_irq(struct iwl_priv *priv) +{ + /* wait to make sure we flush pending tasklet*/ + synchronize_irq(priv->pci_dev->irq); + tasklet_kill(&priv->irq_tasklet); +} + +static const char *iwl3945_desc_lookup(int i) +{ + switch (i) { + case 1: + return "FAIL"; + case 2: + return "BAD_PARAM"; + case 3: + return "BAD_CHECKSUM"; + case 4: + return "NMI_INTERRUPT"; + case 5: + return "SYSASSERT"; + case 6: + return "FATAL_ERROR"; + } + + return "UNKNOWN"; +} + +#define ERROR_START_OFFSET (1 * sizeof(u32)) +#define ERROR_ELEM_SIZE (7 * sizeof(u32)) + +void iwl3945_dump_nic_error_log(struct iwl_priv *priv) +{ + u32 i; + u32 desc, time, count, base, data1; + u32 blink1, blink2, ilink1, ilink2; + + base = le32_to_cpu(priv->card_alive.error_event_table_ptr); + + if (!iwl3945_hw_valid_rtc_data_addr(base)) { + IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base); + return; + } + + + count = iwl_legacy_read_targ_mem(priv, base); + + if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { + IWL_ERR(priv, "Start IWL Error Log Dump:\n"); + IWL_ERR(priv, "Status: 0x%08lX, count: %d\n", + priv->status, count); + } + + IWL_ERR(priv, "Desc Time asrtPC blink2 " + "ilink1 nmiPC Line\n"); + for (i = ERROR_START_OFFSET; + i < (count * ERROR_ELEM_SIZE) + ERROR_START_OFFSET; + i += ERROR_ELEM_SIZE) { + desc = iwl_legacy_read_targ_mem(priv, base + i); + time = + iwl_legacy_read_targ_mem(priv, base + i + 1 * sizeof(u32)); + blink1 = + iwl_legacy_read_targ_mem(priv, base + i + 2 * sizeof(u32)); + blink2 = + iwl_legacy_read_targ_mem(priv, base + i + 3 * sizeof(u32)); + ilink1 = + iwl_legacy_read_targ_mem(priv, base + i + 4 * sizeof(u32)); + ilink2 = + iwl_legacy_read_targ_mem(priv, base + i + 5 * sizeof(u32)); + data1 = + iwl_legacy_read_targ_mem(priv, base + i + 6 * sizeof(u32)); + + IWL_ERR(priv, + "%-13s (0x%X) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n", + iwl3945_desc_lookup(desc), desc, time, blink1, blink2, + ilink1, ilink2, data1); + trace_iwlwifi_legacy_dev_ucode_error(priv, desc, time, data1, 0, + 0, blink1, blink2, ilink1, ilink2); + } +} + +#define EVENT_START_OFFSET (6 * sizeof(u32)) + +/** + * iwl3945_print_event_log - Dump error event log to syslog + * + */ +static int iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, + u32 num_events, u32 mode, + int pos, char **buf, size_t bufsz) +{ + u32 i; + u32 base; /* SRAM byte address of event log header */ + u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */ + u32 ptr; /* SRAM byte address of log data */ + u32 ev, time, data; /* event log data */ + unsigned long reg_flags; + + if (num_events == 0) + return pos; + + base = le32_to_cpu(priv->card_alive.log_event_table_ptr); + + if (mode == 0) + event_size = 2 * sizeof(u32); + else + event_size = 3 * sizeof(u32); + + ptr = base + EVENT_START_OFFSET + (start_idx * event_size); + + /* Make sure device is powered up for SRAM reads */ + spin_lock_irqsave(&priv->reg_lock, reg_flags); + iwl_grab_nic_access(priv); + + /* Set starting address; reads will auto-increment */ + _iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); + rmb(); + + /* "time" is actually "data" for mode 0 (no timestamp). + * place event id # at far right for easier visual parsing. */ + for (i = 0; i < num_events; i++) { + ev = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); + time = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); + if (mode == 0) { + /* data, ev */ + if (bufsz) { + pos += scnprintf(*buf + pos, bufsz - pos, + "0x%08x:%04u\n", + time, ev); + } else { + IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); + trace_iwlwifi_legacy_dev_ucode_event(priv, 0, + time, ev); + } + } else { + data = _iwl_legacy_read_direct32(priv, + HBUS_TARG_MEM_RDAT); + if (bufsz) { + pos += scnprintf(*buf + pos, bufsz - pos, + "%010u:0x%08x:%04u\n", + time, data, ev); + } else { + IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", + time, data, ev); + trace_iwlwifi_legacy_dev_ucode_event(priv, time, + data, ev); + } + } + } + + /* Allow device to power down */ + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); + return pos; +} + +/** + * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog + */ +static int iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, + u32 num_wraps, u32 next_entry, + u32 size, u32 mode, + int pos, char **buf, size_t bufsz) +{ + /* + * display the newest DEFAULT_LOG_ENTRIES entries + * i.e the entries just before the next ont that uCode would fill. + */ + if (num_wraps) { + if (next_entry < size) { + pos = iwl3945_print_event_log(priv, + capacity - (size - next_entry), + size - next_entry, mode, + pos, buf, bufsz); + pos = iwl3945_print_event_log(priv, 0, + next_entry, mode, + pos, buf, bufsz); + } else + pos = iwl3945_print_event_log(priv, next_entry - size, + size, mode, + pos, buf, bufsz); + } else { + if (next_entry < size) + pos = iwl3945_print_event_log(priv, 0, + next_entry, mode, + pos, buf, bufsz); + else + pos = iwl3945_print_event_log(priv, next_entry - size, + size, mode, + pos, buf, bufsz); + } + return pos; +} + +#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) + +int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, + char **buf, bool display) +{ + u32 base; /* SRAM byte address of event log header */ + u32 capacity; /* event log capacity in # entries */ + u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ + u32 num_wraps; /* # times uCode wrapped to top of log */ + u32 next_entry; /* index of next entry to be written by uCode */ + u32 size; /* # entries that we'll print */ + int pos = 0; + size_t bufsz = 0; + + base = le32_to_cpu(priv->card_alive.log_event_table_ptr); + if (!iwl3945_hw_valid_rtc_data_addr(base)) { + IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); + return -EINVAL; + } + + /* event log header */ + capacity = iwl_legacy_read_targ_mem(priv, base); + mode = iwl_legacy_read_targ_mem(priv, base + (1 * sizeof(u32))); + num_wraps = iwl_legacy_read_targ_mem(priv, base + (2 * sizeof(u32))); + next_entry = iwl_legacy_read_targ_mem(priv, base + (3 * sizeof(u32))); + + if (capacity > priv->cfg->base_params->max_event_log_size) { + IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n", + capacity, priv->cfg->base_params->max_event_log_size); + capacity = priv->cfg->base_params->max_event_log_size; + } + + if (next_entry > priv->cfg->base_params->max_event_log_size) { + IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n", + next_entry, priv->cfg->base_params->max_event_log_size); + next_entry = priv->cfg->base_params->max_event_log_size; + } + + size = num_wraps ? capacity : next_entry; + + /* bail out if nothing in log */ + if (size == 0) { + IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); + return pos; + } + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + if (!(iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) + size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) + ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; +#else + size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) + ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; +#endif + + IWL_ERR(priv, "Start IWL Event Log Dump: display last %d count\n", + size); + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + if (display) { + if (full_log) + bufsz = capacity * 48; + else + bufsz = size * 48; + *buf = kmalloc(bufsz, GFP_KERNEL); + if (!*buf) + return -ENOMEM; + } + if ((iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { + /* if uCode has wrapped back to top of log, + * start at the oldest entry, + * i.e the next one that uCode would fill. + */ + if (num_wraps) + pos = iwl3945_print_event_log(priv, next_entry, + capacity - next_entry, mode, + pos, buf, bufsz); + + /* (then/else) start at top of log */ + pos = iwl3945_print_event_log(priv, 0, next_entry, mode, + pos, buf, bufsz); + } else + pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps, + next_entry, size, mode, + pos, buf, bufsz); +#else + pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps, + next_entry, size, mode, + pos, buf, bufsz); +#endif + return pos; +} + +static void iwl3945_irq_tasklet(struct iwl_priv *priv) +{ + u32 inta, handled = 0; + u32 inta_fh; + unsigned long flags; +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + u32 inta_mask; +#endif + + spin_lock_irqsave(&priv->lock, flags); + + /* Ack/clear/reset pending uCode interrupts. + * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, + * and will clear only when CSR_FH_INT_STATUS gets cleared. */ + inta = iwl_read32(priv, CSR_INT); + iwl_write32(priv, CSR_INT, inta); + + /* Ack/clear/reset pending flow-handler (DMA) interrupts. + * Any new interrupts that happen after this, either while we're + * in this tasklet, or later, will show up in next ISR/tasklet. */ + inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); + iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh); + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + if (iwl_legacy_get_debug_level(priv) & IWL_DL_ISR) { + /* just for debug */ + inta_mask = iwl_read32(priv, CSR_INT_MASK); + IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", + inta, inta_mask, inta_fh); + } +#endif + + spin_unlock_irqrestore(&priv->lock, flags); + + /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not + * atomic, make sure that inta covers all the interrupts that + * we've discovered, even if FH interrupt came in just after + * reading CSR_INT. */ + if (inta_fh & CSR39_FH_INT_RX_MASK) + inta |= CSR_INT_BIT_FH_RX; + if (inta_fh & CSR39_FH_INT_TX_MASK) + inta |= CSR_INT_BIT_FH_TX; + + /* Now service all interrupt bits discovered above. */ + if (inta & CSR_INT_BIT_HW_ERR) { + IWL_ERR(priv, "Hardware error detected. Restarting.\n"); + + /* Tell the device to stop sending interrupts */ + iwl_legacy_disable_interrupts(priv); + + priv->isr_stats.hw++; + iwl_legacy_irq_handle_error(priv); + + handled |= CSR_INT_BIT_HW_ERR; + + return; + } + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + if (iwl_legacy_get_debug_level(priv) & (IWL_DL_ISR)) { + /* NIC fires this, but we don't use it, redundant with WAKEUP */ + if (inta & CSR_INT_BIT_SCD) { + IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " + "the frame/frames.\n"); + priv->isr_stats.sch++; + } + + /* Alive notification via Rx interrupt will do the real work */ + if (inta & CSR_INT_BIT_ALIVE) { + IWL_DEBUG_ISR(priv, "Alive interrupt\n"); + priv->isr_stats.alive++; + } + } +#endif + /* Safely ignore these bits for debug checks below */ + inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE); + + /* Error detected by uCode */ + if (inta & CSR_INT_BIT_SW_ERR) { + IWL_ERR(priv, "Microcode SW error detected. " + "Restarting 0x%X.\n", inta); + priv->isr_stats.sw++; + iwl_legacy_irq_handle_error(priv); + handled |= CSR_INT_BIT_SW_ERR; + } + + /* uCode wakes up after power-down sleep */ + if (inta & CSR_INT_BIT_WAKEUP) { + IWL_DEBUG_ISR(priv, "Wakeup interrupt\n"); + iwl_legacy_rx_queue_update_write_ptr(priv, &priv->rxq); + iwl_legacy_txq_update_write_ptr(priv, &priv->txq[0]); + iwl_legacy_txq_update_write_ptr(priv, &priv->txq[1]); + iwl_legacy_txq_update_write_ptr(priv, &priv->txq[2]); + iwl_legacy_txq_update_write_ptr(priv, &priv->txq[3]); + iwl_legacy_txq_update_write_ptr(priv, &priv->txq[4]); + iwl_legacy_txq_update_write_ptr(priv, &priv->txq[5]); + + priv->isr_stats.wakeup++; + handled |= CSR_INT_BIT_WAKEUP; + } + + /* All uCode command responses, including Tx command responses, + * Rx "responses" (frame-received notification), and other + * notifications from uCode come through here*/ + if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { + iwl3945_rx_handle(priv); + priv->isr_stats.rx++; + handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); + } + + if (inta & CSR_INT_BIT_FH_TX) { + IWL_DEBUG_ISR(priv, "Tx interrupt\n"); + priv->isr_stats.tx++; + + iwl_write32(priv, CSR_FH_INT_STATUS, (1 << 6)); + iwl_legacy_write_direct32(priv, FH39_TCSR_CREDIT + (FH39_SRVC_CHNL), 0x0); + handled |= CSR_INT_BIT_FH_TX; + } + + if (inta & ~handled) { + IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); + priv->isr_stats.unhandled++; + } + + if (inta & ~priv->inta_mask) { + IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", + inta & ~priv->inta_mask); + IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh); + } + + /* Re-enable all interrupts */ + /* only Re-enable if disabled by irq */ + if (test_bit(STATUS_INT_ENABLED, &priv->status)) + iwl_legacy_enable_interrupts(priv); + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + if (iwl_legacy_get_debug_level(priv) & (IWL_DL_ISR)) { + inta = iwl_read32(priv, CSR_INT); + inta_mask = iwl_read32(priv, CSR_INT_MASK); + inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); + IWL_DEBUG_ISR(priv, "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, " + "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); + } +#endif +} + +static int iwl3945_get_single_channel_for_scan(struct iwl_priv *priv, + struct ieee80211_vif *vif, + enum ieee80211_band band, + struct iwl3945_scan_channel *scan_ch) +{ + const struct ieee80211_supported_band *sband; + u16 passive_dwell = 0; + u16 active_dwell = 0; + int added = 0; + u8 channel = 0; + + sband = iwl_get_hw_mode(priv, band); + if (!sband) { + IWL_ERR(priv, "invalid band\n"); + return added; + } + + active_dwell = iwl_legacy_get_active_dwell_time(priv, band, 0); + passive_dwell = iwl_legacy_get_passive_dwell_time(priv, band, vif); + + if (passive_dwell <= active_dwell) + passive_dwell = active_dwell + 1; + + + channel = iwl_legacy_get_single_channel_number(priv, band); + + if (channel) { + scan_ch->channel = channel; + scan_ch->type = 0; /* passive */ + scan_ch->active_dwell = cpu_to_le16(active_dwell); + scan_ch->passive_dwell = cpu_to_le16(passive_dwell); + /* Set txpower levels to defaults */ + scan_ch->tpc.dsp_atten = 110; + if (band == IEEE80211_BAND_5GHZ) + scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; + else + scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); + added++; + } else + IWL_ERR(priv, "no valid channel found\n"); + return added; +} + +static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, + enum ieee80211_band band, + u8 is_active, u8 n_probes, + struct iwl3945_scan_channel *scan_ch, + struct ieee80211_vif *vif) +{ + struct ieee80211_channel *chan; + const struct ieee80211_supported_band *sband; + const struct iwl_channel_info *ch_info; + u16 passive_dwell = 0; + u16 active_dwell = 0; + int added, i; + + sband = iwl_get_hw_mode(priv, band); + if (!sband) + return 0; + + active_dwell = iwl_legacy_get_active_dwell_time(priv, band, n_probes); + passive_dwell = iwl_legacy_get_passive_dwell_time(priv, band, vif); + + if (passive_dwell <= active_dwell) + passive_dwell = active_dwell + 1; + + for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) { + chan = priv->scan_request->channels[i]; + + if (chan->band != band) + continue; + + scan_ch->channel = chan->hw_value; + + ch_info = iwl_legacy_get_channel_info(priv, band, + scan_ch->channel); + if (!iwl_legacy_is_channel_valid(ch_info)) { + IWL_DEBUG_SCAN(priv, + "Channel %d is INVALID for this band.\n", + scan_ch->channel); + continue; + } + + scan_ch->active_dwell = cpu_to_le16(active_dwell); + scan_ch->passive_dwell = cpu_to_le16(passive_dwell); + /* If passive , set up for auto-switch + * and use long active_dwell time. + */ + if (!is_active || iwl_legacy_is_channel_passive(ch_info) || + (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) { + scan_ch->type = 0; /* passive */ + if (IWL_UCODE_API(priv->ucode_ver) == 1) + scan_ch->active_dwell = cpu_to_le16(passive_dwell - 1); + } else { + scan_ch->type = 1; /* active */ + } + + /* Set direct probe bits. These may be used both for active + * scan channels (probes gets sent right away), + * or for passive channels (probes get se sent only after + * hearing clear Rx packet).*/ + if (IWL_UCODE_API(priv->ucode_ver) >= 2) { + if (n_probes) + scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes); + } else { + /* uCode v1 does not allow setting direct probe bits on + * passive channel. */ + if ((scan_ch->type & 1) && n_probes) + scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes); + } + + /* Set txpower levels to defaults */ + scan_ch->tpc.dsp_atten = 110; + /* scan_pwr_info->tpc.dsp_atten; */ + + /*scan_pwr_info->tpc.tx_gain; */ + if (band == IEEE80211_BAND_5GHZ) + scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; + else { + scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); + /* NOTE: if we were doing 6Mb OFDM for scans we'd use + * power level: + * scan_ch->tpc.tx_gain = ((1 << 5) | (2 << 3)) | 3; + */ + } + + IWL_DEBUG_SCAN(priv, "Scanning %d [%s %d]\n", + scan_ch->channel, + (scan_ch->type & 1) ? "ACTIVE" : "PASSIVE", + (scan_ch->type & 1) ? + active_dwell : passive_dwell); + + scan_ch++; + added++; + } + + IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added); + return added; +} + +static void iwl3945_init_hw_rates(struct iwl_priv *priv, + struct ieee80211_rate *rates) +{ + int i; + + for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) { + rates[i].bitrate = iwl3945_rates[i].ieee * 5; + rates[i].hw_value = i; /* Rate scaling will work on indexes */ + rates[i].hw_value_short = i; + rates[i].flags = 0; + if ((i > IWL39_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) { + /* + * If CCK != 1M then set short preamble rate flag. + */ + rates[i].flags |= (iwl3945_rates[i].plcp == 10) ? + 0 : IEEE80211_RATE_SHORT_PREAMBLE; + } + } +} + +/****************************************************************************** + * + * uCode download functions + * + ******************************************************************************/ + +static void iwl3945_dealloc_ucode_pci(struct iwl_priv *priv) +{ + iwl_legacy_free_fw_desc(priv->pci_dev, &priv->ucode_code); + iwl_legacy_free_fw_desc(priv->pci_dev, &priv->ucode_data); + iwl_legacy_free_fw_desc(priv->pci_dev, &priv->ucode_data_backup); + iwl_legacy_free_fw_desc(priv->pci_dev, &priv->ucode_init); + iwl_legacy_free_fw_desc(priv->pci_dev, &priv->ucode_init_data); + iwl_legacy_free_fw_desc(priv->pci_dev, &priv->ucode_boot); +} + +/** + * iwl3945_verify_inst_full - verify runtime uCode image in card vs. host, + * looking at all data. + */ +static int iwl3945_verify_inst_full(struct iwl_priv *priv, __le32 *image, u32 len) +{ + u32 val; + u32 save_len = len; + int rc = 0; + u32 errcnt; + + IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); + + iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_RADDR, + IWL39_RTC_INST_LOWER_BOUND); + + errcnt = 0; + for (; len > 0; len -= sizeof(u32), image++) { + /* read data comes through single port, auto-incr addr */ + /* NOTE: Use the debugless read so we don't flood kernel log + * if IWL_DL_IO is set */ + val = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); + if (val != le32_to_cpu(*image)) { + IWL_ERR(priv, "uCode INST section is invalid at " + "offset 0x%x, is 0x%x, s/b 0x%x\n", + save_len - len, val, le32_to_cpu(*image)); + rc = -EIO; + errcnt++; + if (errcnt >= 20) + break; + } + } + + + if (!errcnt) + IWL_DEBUG_INFO(priv, + "ucode image in INSTRUCTION memory is good\n"); + + return rc; +} + + +/** + * iwl3945_verify_inst_sparse - verify runtime uCode image in card vs. host, + * using sample data 100 bytes apart. If these sample points are good, + * it's a pretty good bet that everything between them is good, too. + */ +static int iwl3945_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) +{ + u32 val; + int rc = 0; + u32 errcnt = 0; + u32 i; + + IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); + + for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { + /* read data comes through single port, auto-incr addr */ + /* NOTE: Use the debugless read so we don't flood kernel log + * if IWL_DL_IO is set */ + iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_RADDR, + i + IWL39_RTC_INST_LOWER_BOUND); + val = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); + if (val != le32_to_cpu(*image)) { +#if 0 /* Enable this if you want to see details */ + IWL_ERR(priv, "uCode INST section is invalid at " + "offset 0x%x, is 0x%x, s/b 0x%x\n", + i, val, *image); +#endif + rc = -EIO; + errcnt++; + if (errcnt >= 3) + break; + } + } + + return rc; +} + + +/** + * iwl3945_verify_ucode - determine which instruction image is in SRAM, + * and verify its contents + */ +static int iwl3945_verify_ucode(struct iwl_priv *priv) +{ + __le32 *image; + u32 len; + int rc = 0; + + /* Try bootstrap */ + image = (__le32 *)priv->ucode_boot.v_addr; + len = priv->ucode_boot.len; + rc = iwl3945_verify_inst_sparse(priv, image, len); + if (rc == 0) { + IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n"); + return 0; + } + + /* Try initialize */ + image = (__le32 *)priv->ucode_init.v_addr; + len = priv->ucode_init.len; + rc = iwl3945_verify_inst_sparse(priv, image, len); + if (rc == 0) { + IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n"); + return 0; + } + + /* Try runtime/protocol */ + image = (__le32 *)priv->ucode_code.v_addr; + len = priv->ucode_code.len; + rc = iwl3945_verify_inst_sparse(priv, image, len); + if (rc == 0) { + IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n"); + return 0; + } + + IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n"); + + /* Since nothing seems to match, show first several data entries in + * instruction SRAM, so maybe visual inspection will give a clue. + * Selection of bootstrap image (vs. other images) is arbitrary. */ + image = (__le32 *)priv->ucode_boot.v_addr; + len = priv->ucode_boot.len; + rc = iwl3945_verify_inst_full(priv, image, len); + + return rc; +} + +static void iwl3945_nic_start(struct iwl_priv *priv) +{ + /* Remove all resets to allow NIC to operate */ + iwl_write32(priv, CSR_RESET, 0); +} + +#define IWL3945_UCODE_GET(item) \ +static u32 iwl3945_ucode_get_##item(const struct iwl_ucode_header *ucode)\ +{ \ + return le32_to_cpu(ucode->v1.item); \ +} + +static u32 iwl3945_ucode_get_header_size(u32 api_ver) +{ + return 24; +} + +static u8 *iwl3945_ucode_get_data(const struct iwl_ucode_header *ucode) +{ + return (u8 *) ucode->v1.data; +} + +IWL3945_UCODE_GET(inst_size); +IWL3945_UCODE_GET(data_size); +IWL3945_UCODE_GET(init_size); +IWL3945_UCODE_GET(init_data_size); +IWL3945_UCODE_GET(boot_size); + +/** + * iwl3945_read_ucode - Read uCode images from disk file. + * + * Copy into buffers for card to fetch via bus-mastering + */ +static int iwl3945_read_ucode(struct iwl_priv *priv) +{ + const struct iwl_ucode_header *ucode; + int ret = -EINVAL, index; + const struct firmware *ucode_raw; + /* firmware file name contains uCode/driver compatibility version */ + const char *name_pre = priv->cfg->fw_name_pre; + const unsigned int api_max = priv->cfg->ucode_api_max; + const unsigned int api_min = priv->cfg->ucode_api_min; + char buf[25]; + u8 *src; + size_t len; + u32 api_ver, inst_size, data_size, init_size, init_data_size, boot_size; + + /* Ask kernel firmware_class module to get the boot firmware off disk. + * request_firmware() is synchronous, file is in memory on return. */ + for (index = api_max; index >= api_min; index--) { + sprintf(buf, "%s%u%s", name_pre, index, ".ucode"); + ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev); + if (ret < 0) { + IWL_ERR(priv, "%s firmware file req failed: %d\n", + buf, ret); + if (ret == -ENOENT) + continue; + else + goto error; + } else { + if (index < api_max) + IWL_ERR(priv, "Loaded firmware %s, " + "which is deprecated. " + " Please use API v%u instead.\n", + buf, api_max); + IWL_DEBUG_INFO(priv, "Got firmware '%s' file " + "(%zd bytes) from disk\n", + buf, ucode_raw->size); + break; + } + } + + if (ret < 0) + goto error; + + /* Make sure that we got at least our header! */ + if (ucode_raw->size < iwl3945_ucode_get_header_size(1)) { + IWL_ERR(priv, "File size way too small!\n"); + ret = -EINVAL; + goto err_release; + } + + /* Data from ucode file: header followed by uCode images */ + ucode = (struct iwl_ucode_header *)ucode_raw->data; + + priv->ucode_ver = le32_to_cpu(ucode->ver); + api_ver = IWL_UCODE_API(priv->ucode_ver); + inst_size = iwl3945_ucode_get_inst_size(ucode); + data_size = iwl3945_ucode_get_data_size(ucode); + init_size = iwl3945_ucode_get_init_size(ucode); + init_data_size = iwl3945_ucode_get_init_data_size(ucode); + boot_size = iwl3945_ucode_get_boot_size(ucode); + src = iwl3945_ucode_get_data(ucode); + + /* api_ver should match the api version forming part of the + * firmware filename ... but we don't check for that and only rely + * on the API version read from firmware header from here on forward */ + + if (api_ver < api_min || api_ver > api_max) { + IWL_ERR(priv, "Driver unable to support your firmware API. " + "Driver supports v%u, firmware is v%u.\n", + api_max, api_ver); + priv->ucode_ver = 0; + ret = -EINVAL; + goto err_release; + } + if (api_ver != api_max) + IWL_ERR(priv, "Firmware has old API version. Expected %u, " + "got %u. New firmware can be obtained " + "from http://www.intellinuxwireless.org.\n", + api_max, api_ver); + + IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u\n", + IWL_UCODE_MAJOR(priv->ucode_ver), + IWL_UCODE_MINOR(priv->ucode_ver), + IWL_UCODE_API(priv->ucode_ver), + IWL_UCODE_SERIAL(priv->ucode_ver)); + + snprintf(priv->hw->wiphy->fw_version, + sizeof(priv->hw->wiphy->fw_version), + "%u.%u.%u.%u", + IWL_UCODE_MAJOR(priv->ucode_ver), + IWL_UCODE_MINOR(priv->ucode_ver), + IWL_UCODE_API(priv->ucode_ver), + IWL_UCODE_SERIAL(priv->ucode_ver)); + + IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n", + priv->ucode_ver); + IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n", + inst_size); + IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %u\n", + data_size); + IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %u\n", + init_size); + IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %u\n", + init_data_size); + IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n", + boot_size); + + + /* Verify size of file vs. image size info in file's header */ + if (ucode_raw->size != iwl3945_ucode_get_header_size(api_ver) + + inst_size + data_size + init_size + + init_data_size + boot_size) { + + IWL_DEBUG_INFO(priv, + "uCode file size %zd does not match expected size\n", + ucode_raw->size); + ret = -EINVAL; + goto err_release; + } + + /* Verify that uCode images will fit in card's SRAM */ + if (inst_size > IWL39_MAX_INST_SIZE) { + IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n", + inst_size); + ret = -EINVAL; + goto err_release; + } + + if (data_size > IWL39_MAX_DATA_SIZE) { + IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n", + data_size); + ret = -EINVAL; + goto err_release; + } + if (init_size > IWL39_MAX_INST_SIZE) { + IWL_DEBUG_INFO(priv, + "uCode init instr len %d too large to fit in\n", + init_size); + ret = -EINVAL; + goto err_release; + } + if (init_data_size > IWL39_MAX_DATA_SIZE) { + IWL_DEBUG_INFO(priv, + "uCode init data len %d too large to fit in\n", + init_data_size); + ret = -EINVAL; + goto err_release; + } + if (boot_size > IWL39_MAX_BSM_SIZE) { + IWL_DEBUG_INFO(priv, + "uCode boot instr len %d too large to fit in\n", + boot_size); + ret = -EINVAL; + goto err_release; + } + + /* Allocate ucode buffers for card's bus-master loading ... */ + + /* Runtime instructions and 2 copies of data: + * 1) unmodified from disk + * 2) backup cache for save/restore during power-downs */ + priv->ucode_code.len = inst_size; + iwl_legacy_alloc_fw_desc(priv->pci_dev, &priv->ucode_code); + + priv->ucode_data.len = data_size; + iwl_legacy_alloc_fw_desc(priv->pci_dev, &priv->ucode_data); + + priv->ucode_data_backup.len = data_size; + iwl_legacy_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup); + + if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr || + !priv->ucode_data_backup.v_addr) + goto err_pci_alloc; + + /* Initialization instructions and data */ + if (init_size && init_data_size) { + priv->ucode_init.len = init_size; + iwl_legacy_alloc_fw_desc(priv->pci_dev, &priv->ucode_init); + + priv->ucode_init_data.len = init_data_size; + iwl_legacy_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data); + + if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr) + goto err_pci_alloc; + } + + /* Bootstrap (instructions only, no data) */ + if (boot_size) { + priv->ucode_boot.len = boot_size; + iwl_legacy_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot); + + if (!priv->ucode_boot.v_addr) + goto err_pci_alloc; + } + + /* Copy images into buffers for card's bus-master reads ... */ + + /* Runtime instructions (first block of data in file) */ + len = inst_size; + IWL_DEBUG_INFO(priv, + "Copying (but not loading) uCode instr len %zd\n", len); + memcpy(priv->ucode_code.v_addr, src, len); + src += len; + + IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n", + priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr); + + /* Runtime data (2nd block) + * NOTE: Copy into backup buffer will be done in iwl3945_up() */ + len = data_size; + IWL_DEBUG_INFO(priv, + "Copying (but not loading) uCode data len %zd\n", len); + memcpy(priv->ucode_data.v_addr, src, len); + memcpy(priv->ucode_data_backup.v_addr, src, len); + src += len; + + /* Initialization instructions (3rd block) */ + if (init_size) { + len = init_size; + IWL_DEBUG_INFO(priv, + "Copying (but not loading) init instr len %zd\n", len); + memcpy(priv->ucode_init.v_addr, src, len); + src += len; + } + + /* Initialization data (4th block) */ + if (init_data_size) { + len = init_data_size; + IWL_DEBUG_INFO(priv, + "Copying (but not loading) init data len %zd\n", len); + memcpy(priv->ucode_init_data.v_addr, src, len); + src += len; + } + + /* Bootstrap instructions (5th block) */ + len = boot_size; + IWL_DEBUG_INFO(priv, + "Copying (but not loading) boot instr len %zd\n", len); + memcpy(priv->ucode_boot.v_addr, src, len); + + /* We have our copies now, allow OS release its copies */ + release_firmware(ucode_raw); + return 0; + + err_pci_alloc: + IWL_ERR(priv, "failed to allocate pci memory\n"); + ret = -ENOMEM; + iwl3945_dealloc_ucode_pci(priv); + + err_release: + release_firmware(ucode_raw); + + error: + return ret; +} + + +/** + * iwl3945_set_ucode_ptrs - Set uCode address location + * + * Tell initialization uCode where to find runtime uCode. + * + * BSM registers initially contain pointers to initialization uCode. + * We need to replace them to load runtime uCode inst and data, + * and to save runtime data when powering down. + */ +static int iwl3945_set_ucode_ptrs(struct iwl_priv *priv) +{ + dma_addr_t pinst; + dma_addr_t pdata; + + /* bits 31:0 for 3945 */ + pinst = priv->ucode_code.p_addr; + pdata = priv->ucode_data_backup.p_addr; + + /* Tell bootstrap uCode where to find image to load */ + iwl_legacy_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); + iwl_legacy_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); + iwl_legacy_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, + priv->ucode_data.len); + + /* Inst byte count must be last to set up, bit 31 signals uCode + * that all new ptr/size info is in place */ + iwl_legacy_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, + priv->ucode_code.len | BSM_DRAM_INST_LOAD); + + IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n"); + + return 0; +} + +/** + * iwl3945_init_alive_start - Called after REPLY_ALIVE notification received + * + * Called after REPLY_ALIVE notification received from "initialize" uCode. + * + * Tell "initialize" uCode to go ahead and load the runtime uCode. + */ +static void iwl3945_init_alive_start(struct iwl_priv *priv) +{ + /* Check alive response for "valid" sign from uCode */ + if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { + /* We had an error bringing up the hardware, so take it + * all the way back down so we can try again */ + IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n"); + goto restart; + } + + /* Bootstrap uCode has loaded initialize uCode ... verify inst image. + * This is a paranoid check, because we would not have gotten the + * "initialize" alive if code weren't properly loaded. */ + if (iwl3945_verify_ucode(priv)) { + /* Runtime instruction load was bad; + * take it all the way back down so we can try again */ + IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n"); + goto restart; + } + + /* Send pointers to protocol/runtime uCode image ... init code will + * load and launch runtime uCode, which will send us another "Alive" + * notification. */ + IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); + if (iwl3945_set_ucode_ptrs(priv)) { + /* Runtime instruction load won't happen; + * take it all the way back down so we can try again */ + IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n"); + goto restart; + } + return; + + restart: + queue_work(priv->workqueue, &priv->restart); +} + +/** + * iwl3945_alive_start - called after REPLY_ALIVE notification received + * from protocol/runtime uCode (initialization uCode's + * Alive gets handled by iwl3945_init_alive_start()). + */ +static void iwl3945_alive_start(struct iwl_priv *priv) +{ + int thermal_spin = 0; + u32 rfkill; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); + + if (priv->card_alive.is_valid != UCODE_VALID_OK) { + /* We had an error bringing up the hardware, so take it + * all the way back down so we can try again */ + IWL_DEBUG_INFO(priv, "Alive failed.\n"); + goto restart; + } + + /* Initialize uCode has loaded Runtime uCode ... verify inst image. + * This is a paranoid check, because we would not have gotten the + * "runtime" alive if code weren't properly loaded. */ + if (iwl3945_verify_ucode(priv)) { + /* Runtime instruction load was bad; + * take it all the way back down so we can try again */ + IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n"); + goto restart; + } + + rfkill = iwl_legacy_read_prph(priv, APMG_RFKILL_REG); + IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill); + + if (rfkill & 0x1) { + clear_bit(STATUS_RF_KILL_HW, &priv->status); + /* if RFKILL is not on, then wait for thermal + * sensor in adapter to kick in */ + while (iwl3945_hw_get_temperature(priv) == 0) { + thermal_spin++; + udelay(10); + } + + if (thermal_spin) + IWL_DEBUG_INFO(priv, "Thermal calibration took %dus\n", + thermal_spin * 10); + } else + set_bit(STATUS_RF_KILL_HW, &priv->status); + + /* After the ALIVE response, we can send commands to 3945 uCode */ + set_bit(STATUS_ALIVE, &priv->status); + + /* Enable watchdog to monitor the driver tx queues */ + iwl_legacy_setup_watchdog(priv); + + if (iwl_legacy_is_rfkill(priv)) + return; + + ieee80211_wake_queues(priv->hw); + + priv->active_rate = IWL_RATES_MASK_3945; + + iwl_legacy_power_update_mode(priv, true); + + if (iwl_legacy_is_associated(priv, IWL_RXON_CTX_BSS)) { + struct iwl3945_rxon_cmd *active_rxon = + (struct iwl3945_rxon_cmd *)(&ctx->active); + + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; + } else { + /* Initialize our rx_config data */ + iwl_legacy_connection_init_rx_config(priv, ctx); + } + + /* Configure Bluetooth device coexistence support */ + iwl_legacy_send_bt_config(priv); + + set_bit(STATUS_READY, &priv->status); + + /* Configure the adapter for unassociated operation */ + iwl3945_commit_rxon(priv, ctx); + + iwl3945_reg_txpower_periodic(priv); + + IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); + wake_up_interruptible(&priv->wait_command_queue); + + return; + + restart: + queue_work(priv->workqueue, &priv->restart); +} + +static void iwl3945_cancel_deferred_work(struct iwl_priv *priv); + +static void __iwl3945_down(struct iwl_priv *priv) +{ + unsigned long flags; + int exit_pending; + + IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); + + iwl_legacy_scan_cancel_timeout(priv, 200); + + exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); + + /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set + * to prevent rearm timer */ + del_timer_sync(&priv->watchdog); + + /* Station information will now be cleared in device */ + iwl_legacy_clear_ucode_stations(priv, NULL); + iwl_legacy_dealloc_bcast_stations(priv); + iwl_legacy_clear_driver_stations(priv); + + /* Unblock any waiting calls */ + wake_up_interruptible_all(&priv->wait_command_queue); + + /* Wipe out the EXIT_PENDING status bit if we are not actually + * exiting the module */ + if (!exit_pending) + clear_bit(STATUS_EXIT_PENDING, &priv->status); + + /* stop and reset the on-board processor */ + iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); + + /* tell the device to stop sending interrupts */ + spin_lock_irqsave(&priv->lock, flags); + iwl_legacy_disable_interrupts(priv); + spin_unlock_irqrestore(&priv->lock, flags); + iwl3945_synchronize_irq(priv); + + if (priv->mac80211_registered) + ieee80211_stop_queues(priv->hw); + + /* If we have not previously called iwl3945_init() then + * clear all bits but the RF Kill bits and return */ + if (!iwl_legacy_is_init(priv)) { + priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << + STATUS_RF_KILL_HW | + test_bit(STATUS_GEO_CONFIGURED, &priv->status) << + STATUS_GEO_CONFIGURED | + test_bit(STATUS_EXIT_PENDING, &priv->status) << + STATUS_EXIT_PENDING; + goto exit; + } + + /* ...otherwise clear out all the status bits but the RF Kill + * bit and continue taking the NIC down. */ + priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << + STATUS_RF_KILL_HW | + test_bit(STATUS_GEO_CONFIGURED, &priv->status) << + STATUS_GEO_CONFIGURED | + test_bit(STATUS_FW_ERROR, &priv->status) << + STATUS_FW_ERROR | + test_bit(STATUS_EXIT_PENDING, &priv->status) << + STATUS_EXIT_PENDING; + + iwl3945_hw_txq_ctx_stop(priv); + iwl3945_hw_rxq_stop(priv); + + /* Power-down device's busmaster DMA clocks */ + iwl_legacy_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); + udelay(5); + + /* Stop the device, and put it in low power state */ + iwl_legacy_apm_stop(priv); + + exit: + memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); + + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); + priv->beacon_skb = NULL; + + /* clear out any free frames */ + iwl3945_clear_free_frames(priv); +} + +static void iwl3945_down(struct iwl_priv *priv) +{ + mutex_lock(&priv->mutex); + __iwl3945_down(priv); + mutex_unlock(&priv->mutex); + + iwl3945_cancel_deferred_work(priv); +} + +#define MAX_HW_RESTARTS 5 + +static int iwl3945_alloc_bcast_station(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + unsigned long flags; + u8 sta_id; + + spin_lock_irqsave(&priv->sta_lock, flags); + sta_id = iwl_legacy_prep_station(priv, ctx, + iwl_bcast_addr, false, NULL); + if (sta_id == IWL_INVALID_STATION) { + IWL_ERR(priv, "Unable to prepare broadcast station\n"); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return -EINVAL; + } + + priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; + priv->stations[sta_id].used |= IWL_STA_BCAST; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return 0; +} + +static int __iwl3945_up(struct iwl_priv *priv) +{ + int rc, i; + + rc = iwl3945_alloc_bcast_station(priv); + if (rc) + return rc; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { + IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); + return -EIO; + } + + if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { + IWL_ERR(priv, "ucode not available for device bring up\n"); + return -EIO; + } + + /* If platform's RF_KILL switch is NOT set to KILL */ + if (iwl_read32(priv, CSR_GP_CNTRL) & + CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) + clear_bit(STATUS_RF_KILL_HW, &priv->status); + else { + set_bit(STATUS_RF_KILL_HW, &priv->status); + IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n"); + return -ENODEV; + } + + iwl_write32(priv, CSR_INT, 0xFFFFFFFF); + + rc = iwl3945_hw_nic_init(priv); + if (rc) { + IWL_ERR(priv, "Unable to int nic\n"); + return rc; + } + + /* make sure rfkill handshake bits are cleared */ + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, + CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); + + /* clear (again), then enable host interrupts */ + iwl_write32(priv, CSR_INT, 0xFFFFFFFF); + iwl_legacy_enable_interrupts(priv); + + /* really make sure rfkill handshake bits are cleared */ + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + + /* Copy original ucode data image from disk into backup cache. + * This will be used to initialize the on-board processor's + * data SRAM for a clean start when the runtime program first loads. */ + memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr, + priv->ucode_data.len); + + /* We return success when we resume from suspend and rf_kill is on. */ + if (test_bit(STATUS_RF_KILL_HW, &priv->status)) + return 0; + + for (i = 0; i < MAX_HW_RESTARTS; i++) { + + /* load bootstrap state machine, + * load bootstrap program into processor's memory, + * prepare to load the "initialize" uCode */ + rc = priv->cfg->ops->lib->load_ucode(priv); + + if (rc) { + IWL_ERR(priv, + "Unable to set up bootstrap uCode: %d\n", rc); + continue; + } + + /* start card; "initialize" will load runtime ucode */ + iwl3945_nic_start(priv); + + IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n"); + + return 0; + } + + set_bit(STATUS_EXIT_PENDING, &priv->status); + __iwl3945_down(priv); + clear_bit(STATUS_EXIT_PENDING, &priv->status); + + /* tried to restart and config the device for as long as our + * patience could withstand */ + IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i); + return -EIO; +} + + +/***************************************************************************** + * + * Workqueue callbacks + * + *****************************************************************************/ + +static void iwl3945_bg_init_alive_start(struct work_struct *data) +{ + struct iwl_priv *priv = + container_of(data, struct iwl_priv, init_alive_start.work); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + iwl3945_init_alive_start(priv); + mutex_unlock(&priv->mutex); +} + +static void iwl3945_bg_alive_start(struct work_struct *data) +{ + struct iwl_priv *priv = + container_of(data, struct iwl_priv, alive_start.work); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + iwl3945_alive_start(priv); + mutex_unlock(&priv->mutex); +} + +/* + * 3945 cannot interrupt driver when hardware rf kill switch toggles; + * driver must poll CSR_GP_CNTRL_REG register for change. This register + * *is* readable even when device has been SW_RESET into low power mode + * (e.g. during RF KILL). + */ +static void iwl3945_rfkill_poll(struct work_struct *data) +{ + struct iwl_priv *priv = + container_of(data, struct iwl_priv, _3945.rfkill_poll.work); + bool old_rfkill = test_bit(STATUS_RF_KILL_HW, &priv->status); + bool new_rfkill = !(iwl_read32(priv, CSR_GP_CNTRL) + & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); + + if (new_rfkill != old_rfkill) { + if (new_rfkill) + set_bit(STATUS_RF_KILL_HW, &priv->status); + else + clear_bit(STATUS_RF_KILL_HW, &priv->status); + + wiphy_rfkill_set_hw_state(priv->hw->wiphy, new_rfkill); + + IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n", + new_rfkill ? "disable radio" : "enable radio"); + } + + /* Keep this running, even if radio now enabled. This will be + * cancelled in mac_start() if system decides to start again */ + queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll, + round_jiffies_relative(2 * HZ)); + +} + +int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) +{ + struct iwl_host_cmd cmd = { + .id = REPLY_SCAN_CMD, + .len = sizeof(struct iwl3945_scan_cmd), + .flags = CMD_SIZE_HUGE, + }; + struct iwl3945_scan_cmd *scan; + u8 n_probes = 0; + enum ieee80211_band band; + bool is_active = false; + int ret; + + lockdep_assert_held(&priv->mutex); + + if (!priv->scan_cmd) { + priv->scan_cmd = kmalloc(sizeof(struct iwl3945_scan_cmd) + + IWL_MAX_SCAN_SIZE, GFP_KERNEL); + if (!priv->scan_cmd) { + IWL_DEBUG_SCAN(priv, "Fail to allocate scan memory\n"); + return -ENOMEM; + } + } + scan = priv->scan_cmd; + memset(scan, 0, sizeof(struct iwl3945_scan_cmd) + IWL_MAX_SCAN_SIZE); + + scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; + scan->quiet_time = IWL_ACTIVE_QUIET_TIME; + + if (iwl_legacy_is_associated(priv, IWL_RXON_CTX_BSS)) { + u16 interval = 0; + u32 extra; + u32 suspend_time = 100; + u32 scan_suspend_time = 100; + + IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); + + if (priv->is_internal_short_scan) + interval = 0; + else + interval = vif->bss_conf.beacon_int; + + scan->suspend_time = 0; + scan->max_out_time = cpu_to_le32(200 * 1024); + if (!interval) + interval = suspend_time; + /* + * suspend time format: + * 0-19: beacon interval in usec (time before exec.) + * 20-23: 0 + * 24-31: number of beacons (suspend between channels) + */ + + extra = (suspend_time / interval) << 24; + scan_suspend_time = 0xFF0FFFFF & + (extra | ((suspend_time % interval) * 1024)); + + scan->suspend_time = cpu_to_le32(scan_suspend_time); + IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n", + scan_suspend_time, interval); + } + + if (priv->is_internal_short_scan) { + IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); + } else if (priv->scan_request->n_ssids) { + int i, p = 0; + IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); + for (i = 0; i < priv->scan_request->n_ssids; i++) { + /* always does wildcard anyway */ + if (!priv->scan_request->ssids[i].ssid_len) + continue; + scan->direct_scan[p].id = WLAN_EID_SSID; + scan->direct_scan[p].len = + priv->scan_request->ssids[i].ssid_len; + memcpy(scan->direct_scan[p].ssid, + priv->scan_request->ssids[i].ssid, + priv->scan_request->ssids[i].ssid_len); + n_probes++; + p++; + } + is_active = true; + } else + IWL_DEBUG_SCAN(priv, "Kicking off passive scan.\n"); + + /* We don't build a direct scan probe request; the uCode will do + * that based on the direct_mask added to each channel entry */ + scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; + scan->tx_cmd.sta_id = priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; + scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; + + /* flags + rate selection */ + + switch (priv->scan_band) { + case IEEE80211_BAND_2GHZ: + scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; + scan->tx_cmd.rate = IWL_RATE_1M_PLCP; + band = IEEE80211_BAND_2GHZ; + break; + case IEEE80211_BAND_5GHZ: + scan->tx_cmd.rate = IWL_RATE_6M_PLCP; + band = IEEE80211_BAND_5GHZ; + break; + default: + IWL_WARN(priv, "Invalid scan band\n"); + return -EIO; + } + + /* + * If active scaning is requested but a certain channel + * is marked passive, we can do active scanning if we + * detect transmissions. + */ + scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : + IWL_GOOD_CRC_TH_DISABLED; + + if (!priv->is_internal_short_scan) { + scan->tx_cmd.len = cpu_to_le16( + iwl_legacy_fill_probe_req(priv, + (struct ieee80211_mgmt *)scan->data, + vif->addr, + priv->scan_request->ie, + priv->scan_request->ie_len, + IWL_MAX_SCAN_SIZE - sizeof(*scan))); + } else { + /* use bcast addr, will not be transmitted but must be valid */ + scan->tx_cmd.len = cpu_to_le16( + iwl_legacy_fill_probe_req(priv, + (struct ieee80211_mgmt *)scan->data, + iwl_bcast_addr, NULL, 0, + IWL_MAX_SCAN_SIZE - sizeof(*scan))); + } + /* select Rx antennas */ + scan->flags |= iwl3945_get_antenna_flags(priv); + + if (priv->is_internal_short_scan) { + scan->channel_count = + iwl3945_get_single_channel_for_scan(priv, vif, band, + (void *)&scan->data[le16_to_cpu( + scan->tx_cmd.len)]); + } else { + scan->channel_count = + iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, + (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif); + } + + if (scan->channel_count == 0) { + IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); + return -EIO; + } + + cmd.len += le16_to_cpu(scan->tx_cmd.len) + + scan->channel_count * sizeof(struct iwl3945_scan_channel); + cmd.data = scan; + scan->len = cpu_to_le16(cmd.len); + + set_bit(STATUS_SCAN_HW, &priv->status); + ret = iwl_legacy_send_cmd_sync(priv, &cmd); + if (ret) + clear_bit(STATUS_SCAN_HW, &priv->status); + return ret; +} + +void iwl3945_post_scan(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + /* + * Since setting the RXON may have been deferred while + * performing the scan, fire one off if needed + */ + if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) + iwl3945_commit_rxon(priv, ctx); +} + +static void iwl3945_bg_restart(struct work_struct *data) +{ + struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { + struct iwl_rxon_context *ctx; + mutex_lock(&priv->mutex); + for_each_context(priv, ctx) + ctx->vif = NULL; + priv->is_open = 0; + mutex_unlock(&priv->mutex); + iwl3945_down(priv); + ieee80211_restart_hw(priv->hw); + } else { + iwl3945_down(priv); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + __iwl3945_up(priv); + mutex_unlock(&priv->mutex); + } +} + +static void iwl3945_bg_rx_replenish(struct work_struct *data) +{ + struct iwl_priv *priv = + container_of(data, struct iwl_priv, rx_replenish); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + iwl3945_rx_replenish(priv); + mutex_unlock(&priv->mutex); +} + +void iwl3945_post_associate(struct iwl_priv *priv) +{ + int rc = 0; + struct ieee80211_conf *conf = NULL; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + if (!ctx->vif || !priv->is_open) + return; + + IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", + ctx->vif->bss_conf.aid, ctx->active.bssid_addr); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + iwl_legacy_scan_cancel_timeout(priv, 200); + + conf = iwl_legacy_ieee80211_get_hw_conf(priv->hw); + + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwl3945_commit_rxon(priv, ctx); + + rc = iwl_legacy_send_rxon_timing(priv, ctx); + if (rc) + IWL_WARN(priv, "REPLY_RXON_TIMING failed - " + "Attempting to continue.\n"); + + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + + ctx->staging.assoc_id = cpu_to_le16(ctx->vif->bss_conf.aid); + + IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", + ctx->vif->bss_conf.aid, ctx->vif->bss_conf.beacon_int); + + if (ctx->vif->bss_conf.use_short_preamble) + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + else + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { + if (ctx->vif->bss_conf.use_short_slot) + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + else + ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + } + + iwl3945_commit_rxon(priv, ctx); + + switch (ctx->vif->type) { + case NL80211_IFTYPE_STATION: + iwl3945_rate_scale_init(priv->hw, IWL_AP_ID); + break; + case NL80211_IFTYPE_ADHOC: + iwl3945_send_beacon_cmd(priv); + break; + default: + IWL_ERR(priv, "%s Should not be called in %d mode\n", + __func__, ctx->vif->type); + break; + } +} + +/***************************************************************************** + * + * mac80211 entry point functions + * + *****************************************************************************/ + +#define UCODE_READY_TIMEOUT (2 * HZ) + +static int iwl3945_mac_start(struct ieee80211_hw *hw) +{ + struct iwl_priv *priv = hw->priv; + int ret; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + /* we should be verifying the device is ready to be opened */ + mutex_lock(&priv->mutex); + + /* fetch ucode file from disk, alloc and copy to bus-master buffers ... + * ucode filename and max sizes are card-specific. */ + + if (!priv->ucode_code.len) { + ret = iwl3945_read_ucode(priv); + if (ret) { + IWL_ERR(priv, "Could not read microcode: %d\n", ret); + mutex_unlock(&priv->mutex); + goto out_release_irq; + } + } + + ret = __iwl3945_up(priv); + + mutex_unlock(&priv->mutex); + + if (ret) + goto out_release_irq; + + IWL_DEBUG_INFO(priv, "Start UP work.\n"); + + /* Wait for START_ALIVE from ucode. Otherwise callbacks from + * mac80211 will not be run successfully. */ + ret = wait_event_interruptible_timeout(priv->wait_command_queue, + test_bit(STATUS_READY, &priv->status), + UCODE_READY_TIMEOUT); + if (!ret) { + if (!test_bit(STATUS_READY, &priv->status)) { + IWL_ERR(priv, + "Wait for START_ALIVE timeout after %dms.\n", + jiffies_to_msecs(UCODE_READY_TIMEOUT)); + ret = -ETIMEDOUT; + goto out_release_irq; + } + } + + /* ucode is running and will send rfkill notifications, + * no need to poll the killswitch state anymore */ + cancel_delayed_work(&priv->_3945.rfkill_poll); + + priv->is_open = 1; + IWL_DEBUG_MAC80211(priv, "leave\n"); + return 0; + +out_release_irq: + priv->is_open = 0; + IWL_DEBUG_MAC80211(priv, "leave - failed\n"); + return ret; +} + +static void iwl3945_mac_stop(struct ieee80211_hw *hw) +{ + struct iwl_priv *priv = hw->priv; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + if (!priv->is_open) { + IWL_DEBUG_MAC80211(priv, "leave - skip\n"); + return; + } + + priv->is_open = 0; + + iwl3945_down(priv); + + flush_workqueue(priv->workqueue); + + /* start polling the killswitch state again */ + queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll, + round_jiffies_relative(2 * HZ)); + + IWL_DEBUG_MAC80211(priv, "leave\n"); +} + +static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct iwl_priv *priv = hw->priv; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, + ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); + + if (iwl3945_tx_skb(priv, skb)) + dev_kfree_skb_any(skb); + + IWL_DEBUG_MAC80211(priv, "leave\n"); + return NETDEV_TX_OK; +} + +void iwl3945_config_ap(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + struct ieee80211_vif *vif = ctx->vif; + int rc = 0; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + /* The following should be done only at AP bring up */ + if (!(iwl_legacy_is_associated(priv, IWL_RXON_CTX_BSS))) { + + /* RXON - unassoc (to set timing command) */ + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwl3945_commit_rxon(priv, ctx); + + /* RXON Timing */ + rc = iwl_legacy_send_rxon_timing(priv, ctx); + if (rc) + IWL_WARN(priv, "REPLY_RXON_TIMING failed - " + "Attempting to continue.\n"); + + ctx->staging.assoc_id = 0; + + if (vif->bss_conf.use_short_preamble) + ctx->staging.flags |= + RXON_FLG_SHORT_PREAMBLE_MSK; + else + ctx->staging.flags &= + ~RXON_FLG_SHORT_PREAMBLE_MSK; + + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { + if (vif->bss_conf.use_short_slot) + ctx->staging.flags |= + RXON_FLG_SHORT_SLOT_MSK; + else + ctx->staging.flags &= + ~RXON_FLG_SHORT_SLOT_MSK; + } + /* restore RXON assoc */ + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + iwl3945_commit_rxon(priv, ctx); + } + iwl3945_send_beacon_cmd(priv); +} + +static int iwl3945_mac_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 iwl_priv *priv = hw->priv; + int ret = 0; + u8 sta_id = IWL_INVALID_STATION; + u8 static_key; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + if (iwl3945_mod_params.sw_crypto) { + IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n"); + return -EOPNOTSUPP; + } + + /* + * To support IBSS RSN, don't program group keys in IBSS, the + * hardware will then not attempt to decrypt the frames. + */ + if (vif->type == NL80211_IFTYPE_ADHOC && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) + return -EOPNOTSUPP; + + static_key = !iwl_legacy_is_associated(priv, IWL_RXON_CTX_BSS); + + if (!static_key) { + sta_id = iwl_legacy_sta_id_or_broadcast( + priv, &priv->contexts[IWL_RXON_CTX_BSS], sta); + if (sta_id == IWL_INVALID_STATION) + return -EINVAL; + } + + mutex_lock(&priv->mutex); + iwl_legacy_scan_cancel_timeout(priv, 100); + + switch (cmd) { + case SET_KEY: + if (static_key) + ret = iwl3945_set_static_key(priv, key); + else + ret = iwl3945_set_dynamic_key(priv, key, sta_id); + IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n"); + break; + case DISABLE_KEY: + if (static_key) + ret = iwl3945_remove_static_key(priv); + else + ret = iwl3945_clear_sta_key_info(priv, sta_id); + IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n"); + break; + default: + ret = -EINVAL; + } + + mutex_unlock(&priv->mutex); + IWL_DEBUG_MAC80211(priv, "leave\n"); + + return ret; +} + +static int iwl3945_mac_sta_add(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct iwl_priv *priv = hw->priv; + struct iwl3945_sta_priv *sta_priv = (void *)sta->drv_priv; + int ret; + bool is_ap = vif->type == NL80211_IFTYPE_STATION; + u8 sta_id; + + IWL_DEBUG_INFO(priv, "received request to add station %pM\n", + sta->addr); + mutex_lock(&priv->mutex); + IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", + sta->addr); + sta_priv->common.sta_id = IWL_INVALID_STATION; + + + ret = iwl_legacy_add_station_common(priv, + &priv->contexts[IWL_RXON_CTX_BSS], + sta->addr, is_ap, sta, &sta_id); + if (ret) { + IWL_ERR(priv, "Unable to add station %pM (%d)\n", + sta->addr, ret); + /* Should we return success if return code is EEXIST ? */ + mutex_unlock(&priv->mutex); + return ret; + } + + sta_priv->common.sta_id = sta_id; + + /* Initialize rate scaling */ + IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", + sta->addr); + iwl3945_rs_rate_init(priv, sta, sta_id); + mutex_unlock(&priv->mutex); + + return 0; +} + +static void iwl3945_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, + u64 multicast) +{ + struct iwl_priv *priv = hw->priv; + __le32 filter_or = 0, filter_nand = 0; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + +#define CHK(test, flag) do { \ + if (*total_flags & (test)) \ + filter_or |= (flag); \ + else \ + filter_nand |= (flag); \ + } while (0) + + IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n", + changed_flags, *total_flags); + + CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); + CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK); + CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); + +#undef CHK + + mutex_lock(&priv->mutex); + + ctx->staging.filter_flags &= ~filter_nand; + ctx->staging.filter_flags |= filter_or; + + /* + * Not committing directly because hardware can perform a scan, + * but even if hw is ready, committing here breaks for some reason, + * we'll eventually commit the filter flags change anyway. + */ + + mutex_unlock(&priv->mutex); + + /* + * Receiving all multicast frames is always enabled by the + * default flags setup in iwl_legacy_connection_init_rx_config() + * since we currently do not support programming multicast + * filters into the device. + */ + *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | + FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; +} + + +/***************************************************************************** + * + * sysfs attributes + * + *****************************************************************************/ + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + +/* + * The following adds a new attribute to the sysfs representation + * of this device driver (i.e. a new file in /sys/bus/pci/drivers/iwl/) + * used for controlling the debug level. + * + * See the level definitions in iwl for details. + * + * The debug_level being managed using sysfs below is a per device debug + * level that is used instead of the global debug level if it (the per + * device debug level) is set. + */ +static ssize_t iwl3945_show_debug_level(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + return sprintf(buf, "0x%08X\n", iwl_legacy_get_debug_level(priv)); +} +static ssize_t iwl3945_store_debug_level(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + unsigned long val; + int ret; + + ret = strict_strtoul(buf, 0, &val); + if (ret) + IWL_INFO(priv, "%s is not in hex or decimal form.\n", buf); + else { + priv->debug_level = val; + if (iwl_legacy_alloc_traffic_mem(priv)) + IWL_ERR(priv, + "Not enough memory to generate traffic log\n"); + } + return strnlen(buf, count); +} + +static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, + iwl3945_show_debug_level, iwl3945_store_debug_level); + +#endif /* CONFIG_IWLWIFI_LEGACY_DEBUG */ + +static ssize_t iwl3945_show_temperature(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + + if (!iwl_legacy_is_alive(priv)) + return -EAGAIN; + + return sprintf(buf, "%d\n", iwl3945_hw_get_temperature(priv)); +} + +static DEVICE_ATTR(temperature, S_IRUGO, iwl3945_show_temperature, NULL); + +static ssize_t iwl3945_show_tx_power(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + return sprintf(buf, "%d\n", priv->tx_power_user_lmt); +} + +static ssize_t iwl3945_store_tx_power(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + char *p = (char *)buf; + u32 val; + + val = simple_strtoul(p, &p, 10); + if (p == buf) + IWL_INFO(priv, ": %s is not in decimal form.\n", buf); + else + iwl3945_hw_reg_set_txpower(priv, val); + + return count; +} + +static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, iwl3945_show_tx_power, iwl3945_store_tx_power); + +static ssize_t iwl3945_show_flags(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + return sprintf(buf, "0x%04X\n", ctx->active.flags); +} + +static ssize_t iwl3945_store_flags(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + u32 flags = simple_strtoul(buf, NULL, 0); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + mutex_lock(&priv->mutex); + if (le32_to_cpu(ctx->staging.flags) != flags) { + /* Cancel any currently running scans... */ + if (iwl_legacy_scan_cancel_timeout(priv, 100)) + IWL_WARN(priv, "Could not cancel scan.\n"); + else { + IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n", + flags); + ctx->staging.flags = cpu_to_le32(flags); + iwl3945_commit_rxon(priv, ctx); + } + } + mutex_unlock(&priv->mutex); + + return count; +} + +static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, iwl3945_show_flags, iwl3945_store_flags); + +static ssize_t iwl3945_show_filter_flags(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + return sprintf(buf, "0x%04X\n", + le32_to_cpu(ctx->active.filter_flags)); +} + +static ssize_t iwl3945_store_filter_flags(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + u32 filter_flags = simple_strtoul(buf, NULL, 0); + + mutex_lock(&priv->mutex); + if (le32_to_cpu(ctx->staging.filter_flags) != filter_flags) { + /* Cancel any currently running scans... */ + if (iwl_legacy_scan_cancel_timeout(priv, 100)) + IWL_WARN(priv, "Could not cancel scan.\n"); + else { + IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = " + "0x%04X\n", filter_flags); + ctx->staging.filter_flags = + cpu_to_le32(filter_flags); + iwl3945_commit_rxon(priv, ctx); + } + } + mutex_unlock(&priv->mutex); + + return count; +} + +static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, iwl3945_show_filter_flags, + iwl3945_store_filter_flags); + +static ssize_t iwl3945_show_measurement(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl_spectrum_notification measure_report; + u32 size = sizeof(measure_report), len = 0, ofs = 0; + u8 *data = (u8 *)&measure_report; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + if (!(priv->measurement_status & MEASUREMENT_READY)) { + spin_unlock_irqrestore(&priv->lock, flags); + return 0; + } + memcpy(&measure_report, &priv->measure_report, size); + priv->measurement_status = 0; + spin_unlock_irqrestore(&priv->lock, flags); + + while (size && (PAGE_SIZE - len)) { + hex_dump_to_buffer(data + ofs, size, 16, 1, buf + len, + PAGE_SIZE - len, 1); + len = strlen(buf); + if (PAGE_SIZE - len) + buf[len++] = '\n'; + + ofs += 16; + size -= min(size, 16U); + } + + return len; +} + +static ssize_t iwl3945_store_measurement(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + struct ieee80211_measurement_params params = { + .channel = le16_to_cpu(ctx->active.channel), + .start_time = cpu_to_le64(priv->_3945.last_tsf), + .duration = cpu_to_le16(1), + }; + u8 type = IWL_MEASURE_BASIC; + u8 buffer[32]; + u8 channel; + + if (count) { + char *p = buffer; + strncpy(buffer, buf, min(sizeof(buffer), count)); + channel = simple_strtoul(p, NULL, 0); + if (channel) + params.channel = channel; + + p = buffer; + while (*p && *p != ' ') + p++; + if (*p) + type = simple_strtoul(p + 1, NULL, 0); + } + + IWL_DEBUG_INFO(priv, "Invoking measurement of type %d on " + "channel %d (for '%s')\n", type, params.channel, buf); + iwl3945_get_measurement(priv, ¶ms, type); + + return count; +} + +static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR, + iwl3945_show_measurement, iwl3945_store_measurement); + +static ssize_t iwl3945_store_retry_rate(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + + priv->retry_rate = simple_strtoul(buf, NULL, 0); + if (priv->retry_rate <= 0) + priv->retry_rate = 1; + + return count; +} + +static ssize_t iwl3945_show_retry_rate(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + return sprintf(buf, "%d", priv->retry_rate); +} + +static DEVICE_ATTR(retry_rate, S_IWUSR | S_IRUSR, iwl3945_show_retry_rate, + iwl3945_store_retry_rate); + + +static ssize_t iwl3945_show_channels(struct device *d, + struct device_attribute *attr, char *buf) +{ + /* all this shit doesn't belong into sysfs anyway */ + return 0; +} + +static DEVICE_ATTR(channels, S_IRUSR, iwl3945_show_channels, NULL); + +static ssize_t iwl3945_show_antenna(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + + if (!iwl_legacy_is_alive(priv)) + return -EAGAIN; + + return sprintf(buf, "%d\n", iwl3945_mod_params.antenna); +} + +static ssize_t iwl3945_store_antenna(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv __maybe_unused = dev_get_drvdata(d); + int ant; + + if (count == 0) + return 0; + + if (sscanf(buf, "%1i", &ant) != 1) { + IWL_DEBUG_INFO(priv, "not in hex or decimal form.\n"); + return count; + } + + if ((ant >= 0) && (ant <= 2)) { + IWL_DEBUG_INFO(priv, "Setting antenna select to %d.\n", ant); + iwl3945_mod_params.antenna = (enum iwl3945_antenna)ant; + } else + IWL_DEBUG_INFO(priv, "Bad antenna select value %d.\n", ant); + + + return count; +} + +static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, iwl3945_show_antenna, iwl3945_store_antenna); + +static ssize_t iwl3945_show_status(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + if (!iwl_legacy_is_alive(priv)) + return -EAGAIN; + return sprintf(buf, "0x%08x\n", (int)priv->status); +} + +static DEVICE_ATTR(status, S_IRUGO, iwl3945_show_status, NULL); + +static ssize_t iwl3945_dump_error_log(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + char *p = (char *)buf; + + if (p[0] == '1') + iwl3945_dump_nic_error_log(priv); + + return strnlen(buf, count); +} + +static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, iwl3945_dump_error_log); + +/***************************************************************************** + * + * driver setup and tear down + * + *****************************************************************************/ + +static void iwl3945_setup_deferred_work(struct iwl_priv *priv) +{ + priv->workqueue = create_singlethread_workqueue(DRV_NAME); + + init_waitqueue_head(&priv->wait_command_queue); + + INIT_WORK(&priv->restart, iwl3945_bg_restart); + INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); + INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); + INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); + INIT_DELAYED_WORK(&priv->_3945.rfkill_poll, iwl3945_rfkill_poll); + + iwl_legacy_setup_scan_deferred_work(priv); + + iwl3945_hw_setup_deferred_work(priv); + + init_timer(&priv->watchdog); + priv->watchdog.data = (unsigned long)priv; + priv->watchdog.function = iwl_legacy_bg_watchdog; + + tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) + iwl3945_irq_tasklet, (unsigned long)priv); +} + +static void iwl3945_cancel_deferred_work(struct iwl_priv *priv) +{ + iwl3945_hw_cancel_deferred_work(priv); + + cancel_delayed_work_sync(&priv->init_alive_start); + cancel_delayed_work(&priv->alive_start); + + iwl_legacy_cancel_scan_deferred_work(priv); +} + +static struct attribute *iwl3945_sysfs_entries[] = { + &dev_attr_antenna.attr, + &dev_attr_channels.attr, + &dev_attr_dump_errors.attr, + &dev_attr_flags.attr, + &dev_attr_filter_flags.attr, + &dev_attr_measurement.attr, + &dev_attr_retry_rate.attr, + &dev_attr_status.attr, + &dev_attr_temperature.attr, + &dev_attr_tx_power.attr, +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + &dev_attr_debug_level.attr, +#endif + NULL +}; + +static struct attribute_group iwl3945_attribute_group = { + .name = NULL, /* put in device directory */ + .attrs = iwl3945_sysfs_entries, +}; + +struct ieee80211_ops iwl3945_hw_ops = { + .tx = iwl3945_mac_tx, + .start = iwl3945_mac_start, + .stop = iwl3945_mac_stop, + .add_interface = iwl_legacy_mac_add_interface, + .remove_interface = iwl_legacy_mac_remove_interface, + .change_interface = iwl_legacy_mac_change_interface, + .config = iwl_legacy_mac_config, + .configure_filter = iwl3945_configure_filter, + .set_key = iwl3945_mac_set_key, + .conf_tx = iwl_legacy_mac_conf_tx, + .reset_tsf = iwl_legacy_mac_reset_tsf, + .bss_info_changed = iwl_legacy_mac_bss_info_changed, + .hw_scan = iwl_legacy_mac_hw_scan, + .sta_add = iwl3945_mac_sta_add, + .sta_remove = iwl_legacy_mac_sta_remove, + .tx_last_beacon = iwl_legacy_mac_tx_last_beacon, +}; + +static int iwl3945_init_drv(struct iwl_priv *priv) +{ + int ret; + struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; + + priv->retry_rate = 1; + priv->beacon_skb = NULL; + + spin_lock_init(&priv->sta_lock); + spin_lock_init(&priv->hcmd_lock); + + INIT_LIST_HEAD(&priv->free_frames); + + mutex_init(&priv->mutex); + mutex_init(&priv->sync_cmd_mutex); + + priv->ieee_channels = NULL; + priv->ieee_rates = NULL; + priv->band = IEEE80211_BAND_2GHZ; + + priv->iw_mode = NL80211_IFTYPE_STATION; + priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; + + /* initialize force reset */ + priv->force_reset[IWL_RF_RESET].reset_duration = + IWL_DELAY_NEXT_FORCE_RF_RESET; + priv->force_reset[IWL_FW_RESET].reset_duration = + IWL_DELAY_NEXT_FORCE_FW_RELOAD; + + + priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER; + priv->tx_power_next = IWL_DEFAULT_TX_POWER; + + if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { + IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n", + eeprom->version); + ret = -EINVAL; + goto err; + } + ret = iwl_legacy_init_channel_map(priv); + if (ret) { + IWL_ERR(priv, "initializing regulatory failed: %d\n", ret); + goto err; + } + + /* Set up txpower settings in driver for all channels */ + if (iwl3945_txpower_set_from_eeprom(priv)) { + ret = -EIO; + goto err_free_channel_map; + } + + ret = iwl_legacy_init_geos(priv); + if (ret) { + IWL_ERR(priv, "initializing geos failed: %d\n", ret); + goto err_free_channel_map; + } + iwl3945_init_hw_rates(priv, priv->ieee_rates); + + return 0; + +err_free_channel_map: + iwl_legacy_free_channel_map(priv); +err: + return ret; +} + +#define IWL3945_MAX_PROBE_REQUEST 200 + +static int iwl3945_setup_mac(struct iwl_priv *priv) +{ + int ret; + struct ieee80211_hw *hw = priv->hw; + + hw->rate_control_algorithm = "iwl-3945-rs"; + hw->sta_data_size = sizeof(struct iwl3945_sta_priv); + hw->vif_data_size = sizeof(struct iwl_vif_priv); + + /* Tell mac80211 our characteristics */ + hw->flags = IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_SPECTRUM_MGMT; + + hw->wiphy->interface_modes = + priv->contexts[IWL_RXON_CTX_BSS].interface_modes; + + hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | + WIPHY_FLAG_DISABLE_BEACON_HINTS | + WIPHY_FLAG_IBSS_RSN; + + hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; + /* we create the 802.11 header and a zero-length SSID element */ + hw->wiphy->max_scan_ie_len = IWL3945_MAX_PROBE_REQUEST - 24 - 2; + + /* Default value; 4 EDCA QOS priorities */ + hw->queues = 4; + + if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) + priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = + &priv->bands[IEEE80211_BAND_2GHZ]; + + if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) + priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = + &priv->bands[IEEE80211_BAND_5GHZ]; + + iwl_legacy_leds_init(priv); + + ret = ieee80211_register_hw(priv->hw); + if (ret) { + IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); + return ret; + } + priv->mac80211_registered = 1; + + return 0; +} + +static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int err = 0, i; + struct iwl_priv *priv; + struct ieee80211_hw *hw; + struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); + struct iwl3945_eeprom *eeprom; + unsigned long flags; + + /*********************** + * 1. Allocating HW data + * ********************/ + + /* mac80211 allocates memory for this device instance, including + * space for this driver's private structure */ + hw = iwl_legacy_alloc_all(cfg); + if (hw == NULL) { + pr_err("Can not allocate network device\n"); + err = -ENOMEM; + goto out; + } + priv = hw->priv; + SET_IEEE80211_DEV(hw, &pdev->dev); + + priv->cmd_queue = IWL39_CMD_QUEUE_NUM; + + /* 3945 has only one valid context */ + priv->valid_contexts = BIT(IWL_RXON_CTX_BSS); + + for (i = 0; i < NUM_IWL_RXON_CTX; i++) + priv->contexts[i].ctxid = i; + + priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON; + priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING; + priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; + priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; + priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; + priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; + priv->contexts[IWL_RXON_CTX_BSS].interface_modes = + BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC); + priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS; + priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS; + priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS; + + /* + * Disabling hardware scan means that mac80211 will perform scans + * "the hard way", rather than using device's scan. + */ + if (iwl3945_mod_params.disable_hw_scan) { + dev_printk(KERN_DEBUG, &(pdev->dev), + "sw scan support is deprecated\n"); + iwl3945_hw_ops.hw_scan = NULL; + } + + IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); + priv->cfg = cfg; + priv->pci_dev = pdev; + priv->inta_mask = CSR_INI_SET_MASK; + + if (iwl_legacy_alloc_traffic_mem(priv)) + IWL_ERR(priv, "Not enough memory to generate traffic log\n"); + + /*************************** + * 2. Initializing PCI bus + * *************************/ + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | + PCIE_LINK_STATE_CLKPM); + + if (pci_enable_device(pdev)) { + err = -ENODEV; + goto out_ieee80211_free_hw; + } + + pci_set_master(pdev); + + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (!err) + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); + if (err) { + IWL_WARN(priv, "No suitable DMA available.\n"); + goto out_pci_disable_device; + } + + pci_set_drvdata(pdev, priv); + err = pci_request_regions(pdev, DRV_NAME); + if (err) + goto out_pci_disable_device; + + /*********************** + * 3. Read REV Register + * ********************/ + priv->hw_base = pci_iomap(pdev, 0, 0); + if (!priv->hw_base) { + err = -ENODEV; + goto out_pci_release_regions; + } + + IWL_DEBUG_INFO(priv, "pci_resource_len = 0x%08llx\n", + (unsigned long long) pci_resource_len(pdev, 0)); + IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base); + + /* We disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state */ + pci_write_config_byte(pdev, 0x41, 0x00); + + /* these spin locks will be used in apm_ops.init and EEPROM access + * we should init now + */ + spin_lock_init(&priv->reg_lock); + spin_lock_init(&priv->lock); + + /* + * stop and reset the on-board processor just in case it is in a + * strange state ... like being left stranded by a primary kernel + * and this is now the kdump kernel trying to start up + */ + iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); + + /*********************** + * 4. Read EEPROM + * ********************/ + + /* Read the EEPROM */ + err = iwl_legacy_eeprom_init(priv); + if (err) { + IWL_ERR(priv, "Unable to init EEPROM\n"); + goto out_iounmap; + } + /* MAC Address location in EEPROM same for 3945/4965 */ + eeprom = (struct iwl3945_eeprom *)priv->eeprom; + IWL_DEBUG_INFO(priv, "MAC address: %pM\n", eeprom->mac_address); + SET_IEEE80211_PERM_ADDR(priv->hw, eeprom->mac_address); + + /*********************** + * 5. Setup HW Constants + * ********************/ + /* Device-specific setup */ + if (iwl3945_hw_set_hw_params(priv)) { + IWL_ERR(priv, "failed to set hw settings\n"); + goto out_eeprom_free; + } + + /*********************** + * 6. Setup priv + * ********************/ + + err = iwl3945_init_drv(priv); + if (err) { + IWL_ERR(priv, "initializing driver failed\n"); + goto out_unset_hw_params; + } + + IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s\n", + priv->cfg->name); + + /*********************** + * 7. Setup Services + * ********************/ + + spin_lock_irqsave(&priv->lock, flags); + iwl_legacy_disable_interrupts(priv); + spin_unlock_irqrestore(&priv->lock, flags); + + pci_enable_msi(priv->pci_dev); + + err = request_irq(priv->pci_dev->irq, iwl_legacy_isr, + IRQF_SHARED, DRV_NAME, priv); + if (err) { + IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); + goto out_disable_msi; + } + + err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group); + if (err) { + IWL_ERR(priv, "failed to create sysfs device attributes\n"); + goto out_release_irq; + } + + iwl_legacy_set_rxon_channel(priv, + &priv->bands[IEEE80211_BAND_2GHZ].channels[5], + &priv->contexts[IWL_RXON_CTX_BSS]); + iwl3945_setup_deferred_work(priv); + iwl3945_setup_rx_handlers(priv); + iwl_legacy_power_initialize(priv); + + /********************************* + * 8. Setup and Register mac80211 + * *******************************/ + + iwl_legacy_enable_interrupts(priv); + + err = iwl3945_setup_mac(priv); + if (err) + goto out_remove_sysfs; + + err = iwl_legacy_dbgfs_register(priv, DRV_NAME); + if (err) + IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); + + /* Start monitoring the killswitch */ + queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll, + 2 * HZ); + + return 0; + + out_remove_sysfs: + destroy_workqueue(priv->workqueue); + priv->workqueue = NULL; + sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); + out_release_irq: + free_irq(priv->pci_dev->irq, priv); + out_disable_msi: + pci_disable_msi(priv->pci_dev); + iwl_legacy_free_geos(priv); + iwl_legacy_free_channel_map(priv); + out_unset_hw_params: + iwl3945_unset_hw_params(priv); + out_eeprom_free: + iwl_legacy_eeprom_free(priv); + out_iounmap: + pci_iounmap(pdev, priv->hw_base); + out_pci_release_regions: + pci_release_regions(pdev); + out_pci_disable_device: + pci_set_drvdata(pdev, NULL); + pci_disable_device(pdev); + out_ieee80211_free_hw: + iwl_legacy_free_traffic_mem(priv); + ieee80211_free_hw(priv->hw); + out: + return err; +} + +static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) +{ + struct iwl_priv *priv = pci_get_drvdata(pdev); + unsigned long flags; + + if (!priv) + return; + + IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); + + iwl_legacy_dbgfs_unregister(priv); + + set_bit(STATUS_EXIT_PENDING, &priv->status); + + iwl_legacy_leds_exit(priv); + + if (priv->mac80211_registered) { + ieee80211_unregister_hw(priv->hw); + priv->mac80211_registered = 0; + } else { + iwl3945_down(priv); + } + + /* + * Make sure device is reset to low power before unloading driver. + * This may be redundant with iwl_down(), but there are paths to + * run iwl_down() without calling apm_ops.stop(), and there are + * paths to avoid running iwl_down() at all before leaving driver. + * This (inexpensive) call *makes sure* device is reset. + */ + iwl_legacy_apm_stop(priv); + + /* make sure we flush any pending irq or + * tasklet for the driver + */ + spin_lock_irqsave(&priv->lock, flags); + iwl_legacy_disable_interrupts(priv); + spin_unlock_irqrestore(&priv->lock, flags); + + iwl3945_synchronize_irq(priv); + + sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); + + cancel_delayed_work_sync(&priv->_3945.rfkill_poll); + + iwl3945_dealloc_ucode_pci(priv); + + if (priv->rxq.bd) + iwl3945_rx_queue_free(priv, &priv->rxq); + iwl3945_hw_txq_ctx_free(priv); + + iwl3945_unset_hw_params(priv); + + /*netif_stop_queue(dev); */ + flush_workqueue(priv->workqueue); + + /* ieee80211_unregister_hw calls iwl3945_mac_stop, which flushes + * priv->workqueue... so we can't take down the workqueue + * until now... */ + destroy_workqueue(priv->workqueue); + priv->workqueue = NULL; + iwl_legacy_free_traffic_mem(priv); + + free_irq(pdev->irq, priv); + pci_disable_msi(pdev); + + pci_iounmap(pdev, priv->hw_base); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + + iwl_legacy_free_channel_map(priv); + iwl_legacy_free_geos(priv); + kfree(priv->scan_cmd); + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); + + ieee80211_free_hw(priv->hw); +} + + +/***************************************************************************** + * + * driver and module entry point + * + *****************************************************************************/ + +static struct pci_driver iwl3945_driver = { + .name = DRV_NAME, + .id_table = iwl3945_hw_card_ids, + .probe = iwl3945_pci_probe, + .remove = __devexit_p(iwl3945_pci_remove), + .driver.pm = IWL_LEGACY_PM_OPS, +}; + +static int __init iwl3945_init(void) +{ + + int ret; + pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); + pr_info(DRV_COPYRIGHT "\n"); + + ret = iwl3945_rate_control_register(); + if (ret) { + pr_err("Unable to register rate control algorithm: %d\n", ret); + return ret; + } + + ret = pci_register_driver(&iwl3945_driver); + if (ret) { + pr_err("Unable to initialize PCI module\n"); + goto error_register; + } + + return ret; + +error_register: + iwl3945_rate_control_unregister(); + return ret; +} + +static void __exit iwl3945_exit(void) +{ + pci_unregister_driver(&iwl3945_driver); + iwl3945_rate_control_unregister(); +} + +MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX)); + +module_param_named(antenna, iwl3945_mod_params.antenna, int, S_IRUGO); +MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); +module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, S_IRUGO); +MODULE_PARM_DESC(swcrypto, + "using software crypto (default 1 [software])"); +module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, + int, S_IRUGO); +MODULE_PARM_DESC(disable_hw_scan, + "disable hardware scanning (default 0) (deprecated)"); +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "debug output mask"); +#endif +module_param_named(fw_restart, iwl3945_mod_params.restart_fw, int, S_IRUGO); +MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); + +module_exit(iwl3945_exit); +module_init(iwl3945_init); diff --git a/drivers/net/wireless/iwlegacy/iwl4965-base.c b/drivers/net/wireless/iwlegacy/iwl4965-base.c new file mode 100644 index 000000000000..c0e07685059a --- /dev/null +++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c @@ -0,0 +1,3633 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define DRV_NAME "iwl4965" + +#include "iwl-eeprom.h" +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-io.h" +#include "iwl-helpers.h" +#include "iwl-sta.h" +#include "iwl-4965-calib.h" +#include "iwl-4965.h" +#include "iwl-4965-led.h" + + +/****************************************************************************** + * + * module boiler plate + * + ******************************************************************************/ + +/* + * module name, copyright, version, etc. + */ +#define DRV_DESCRIPTION "Intel(R) Wireless WiFi 4965 driver for Linux" + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +#define VD "d" +#else +#define VD +#endif + +#define DRV_VERSION IWLWIFI_VERSION VD + + +MODULE_DESCRIPTION(DRV_DESCRIPTION); +MODULE_VERSION(DRV_VERSION); +MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("iwl4965"); + +void iwl4965_update_chain_flags(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx; + + if (priv->cfg->ops->hcmd->set_rxon_chain) { + for_each_context(priv, ctx) { + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + if (ctx->active.rx_chain != ctx->staging.rx_chain) + iwl_legacy_commit_rxon(priv, ctx); + } + } +} + +static void iwl4965_clear_free_frames(struct iwl_priv *priv) +{ + struct list_head *element; + + IWL_DEBUG_INFO(priv, "%d frames on pre-allocated heap on clear.\n", + priv->frames_count); + + while (!list_empty(&priv->free_frames)) { + element = priv->free_frames.next; + list_del(element); + kfree(list_entry(element, struct iwl_frame, list)); + priv->frames_count--; + } + + if (priv->frames_count) { + IWL_WARN(priv, "%d frames still in use. Did we lose one?\n", + priv->frames_count); + priv->frames_count = 0; + } +} + +static struct iwl_frame *iwl4965_get_free_frame(struct iwl_priv *priv) +{ + struct iwl_frame *frame; + struct list_head *element; + if (list_empty(&priv->free_frames)) { + frame = kzalloc(sizeof(*frame), GFP_KERNEL); + if (!frame) { + IWL_ERR(priv, "Could not allocate frame!\n"); + return NULL; + } + + priv->frames_count++; + return frame; + } + + element = priv->free_frames.next; + list_del(element); + return list_entry(element, struct iwl_frame, list); +} + +static void iwl4965_free_frame(struct iwl_priv *priv, struct iwl_frame *frame) +{ + memset(frame, 0, sizeof(*frame)); + list_add(&frame->list, &priv->free_frames); +} + +static u32 iwl4965_fill_beacon_frame(struct iwl_priv *priv, + struct ieee80211_hdr *hdr, + int left) +{ + lockdep_assert_held(&priv->mutex); + + if (!priv->beacon_skb) + return 0; + + if (priv->beacon_skb->len > left) + return 0; + + memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len); + + return priv->beacon_skb->len; +} + +/* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */ +static void iwl4965_set_beacon_tim(struct iwl_priv *priv, + struct iwl_tx_beacon_cmd *tx_beacon_cmd, + u8 *beacon, u32 frame_size) +{ + u16 tim_idx; + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon; + + /* + * The index is relative to frame start but we start looking at the + * variable-length part of the beacon. + */ + tim_idx = mgmt->u.beacon.variable - beacon; + + /* Parse variable-length elements of beacon to find WLAN_EID_TIM */ + while ((tim_idx < (frame_size - 2)) && + (beacon[tim_idx] != WLAN_EID_TIM)) + tim_idx += beacon[tim_idx+1] + 2; + + /* If TIM field was found, set variables */ + if ((tim_idx < (frame_size - 1)) && (beacon[tim_idx] == WLAN_EID_TIM)) { + tx_beacon_cmd->tim_idx = cpu_to_le16(tim_idx); + tx_beacon_cmd->tim_size = beacon[tim_idx+1]; + } else + IWL_WARN(priv, "Unable to find TIM Element in beacon\n"); +} + +static unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, + struct iwl_frame *frame) +{ + struct iwl_tx_beacon_cmd *tx_beacon_cmd; + u32 frame_size; + u32 rate_flags; + u32 rate; + /* + * We have to set up the TX command, the TX Beacon command, and the + * beacon contents. + */ + + lockdep_assert_held(&priv->mutex); + + if (!priv->beacon_ctx) { + IWL_ERR(priv, "trying to build beacon w/o beacon context!\n"); + return 0; + } + + /* Initialize memory */ + tx_beacon_cmd = &frame->u.beacon; + memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); + + /* Set up TX beacon contents */ + frame_size = iwl4965_fill_beacon_frame(priv, tx_beacon_cmd->frame, + sizeof(frame->u) - sizeof(*tx_beacon_cmd)); + if (WARN_ON_ONCE(frame_size > MAX_MPDU_SIZE)) + return 0; + if (!frame_size) + return 0; + + /* Set up TX command fields */ + tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); + tx_beacon_cmd->tx.sta_id = priv->beacon_ctx->bcast_sta_id; + tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; + tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK | + TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK; + + /* Set up TX beacon command fields */ + iwl4965_set_beacon_tim(priv, tx_beacon_cmd, (u8 *)tx_beacon_cmd->frame, + frame_size); + + /* Set up packet rate and flags */ + rate = iwl_legacy_get_lowest_plcp(priv, priv->beacon_ctx); + priv->mgmt_tx_ant = iwl4965_toggle_tx_ant(priv, priv->mgmt_tx_ant, + priv->hw_params.valid_tx_ant); + rate_flags = iwl4965_ant_idx_to_flags(priv->mgmt_tx_ant); + if ((rate >= IWL_FIRST_CCK_RATE) && (rate <= IWL_LAST_CCK_RATE)) + rate_flags |= RATE_MCS_CCK_MSK; + tx_beacon_cmd->tx.rate_n_flags = iwl4965_hw_set_rate_n_flags(rate, + rate_flags); + + return sizeof(*tx_beacon_cmd) + frame_size; +} + +int iwl4965_send_beacon_cmd(struct iwl_priv *priv) +{ + struct iwl_frame *frame; + unsigned int frame_size; + int rc; + + frame = iwl4965_get_free_frame(priv); + if (!frame) { + IWL_ERR(priv, "Could not obtain free frame buffer for beacon " + "command.\n"); + return -ENOMEM; + } + + frame_size = iwl4965_hw_get_beacon_cmd(priv, frame); + if (!frame_size) { + IWL_ERR(priv, "Error configuring the beacon command\n"); + iwl4965_free_frame(priv, frame); + return -EINVAL; + } + + rc = iwl_legacy_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, + &frame->u.cmd[0]); + + iwl4965_free_frame(priv, frame); + + return rc; +} + +static inline dma_addr_t iwl4965_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) +{ + struct iwl_tfd_tb *tb = &tfd->tbs[idx]; + + dma_addr_t addr = get_unaligned_le32(&tb->lo); + if (sizeof(dma_addr_t) > sizeof(u32)) + addr |= + ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16; + + return addr; +} + +static inline u16 iwl4965_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx) +{ + struct iwl_tfd_tb *tb = &tfd->tbs[idx]; + + return le16_to_cpu(tb->hi_n_len) >> 4; +} + +static inline void iwl4965_tfd_set_tb(struct iwl_tfd *tfd, u8 idx, + dma_addr_t addr, u16 len) +{ + struct iwl_tfd_tb *tb = &tfd->tbs[idx]; + u16 hi_n_len = len << 4; + + put_unaligned_le32(addr, &tb->lo); + if (sizeof(dma_addr_t) > sizeof(u32)) + hi_n_len |= ((addr >> 16) >> 16) & 0xF; + + tb->hi_n_len = cpu_to_le16(hi_n_len); + + tfd->num_tbs = idx + 1; +} + +static inline u8 iwl4965_tfd_get_num_tbs(struct iwl_tfd *tfd) +{ + return tfd->num_tbs & 0x1f; +} + +/** + * iwl4965_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] + * @priv - driver private data + * @txq - tx queue + * + * Does NOT advance any TFD circular buffer read/write indexes + * Does NOT free the TFD itself (which is within circular buffer) + */ +void iwl4965_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) +{ + struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)txq->tfds; + struct iwl_tfd *tfd; + struct pci_dev *dev = priv->pci_dev; + int index = txq->q.read_ptr; + int i; + int num_tbs; + + tfd = &tfd_tmp[index]; + + /* Sanity check on number of chunks */ + num_tbs = iwl4965_tfd_get_num_tbs(tfd); + + if (num_tbs >= IWL_NUM_OF_TBS) { + IWL_ERR(priv, "Too many chunks: %i\n", num_tbs); + /* @todo issue fatal error, it is quite serious situation */ + return; + } + + /* Unmap tx_cmd */ + if (num_tbs) + pci_unmap_single(dev, + dma_unmap_addr(&txq->meta[index], mapping), + dma_unmap_len(&txq->meta[index], len), + PCI_DMA_BIDIRECTIONAL); + + /* Unmap chunks, if any. */ + for (i = 1; i < num_tbs; i++) + pci_unmap_single(dev, iwl4965_tfd_tb_get_addr(tfd, i), + iwl4965_tfd_tb_get_len(tfd, i), + PCI_DMA_TODEVICE); + + /* free SKB */ + if (txq->txb) { + struct sk_buff *skb; + + skb = txq->txb[txq->q.read_ptr].skb; + + /* can be called from irqs-disabled context */ + if (skb) { + dev_kfree_skb_any(skb); + txq->txb[txq->q.read_ptr].skb = NULL; + } + } +} + +int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, + struct iwl_tx_queue *txq, + dma_addr_t addr, u16 len, + u8 reset, u8 pad) +{ + struct iwl_queue *q; + struct iwl_tfd *tfd, *tfd_tmp; + u32 num_tbs; + + q = &txq->q; + tfd_tmp = (struct iwl_tfd *)txq->tfds; + tfd = &tfd_tmp[q->write_ptr]; + + if (reset) + memset(tfd, 0, sizeof(*tfd)); + + num_tbs = iwl4965_tfd_get_num_tbs(tfd); + + /* Each TFD can point to a maximum 20 Tx buffers */ + if (num_tbs >= IWL_NUM_OF_TBS) { + IWL_ERR(priv, "Error can not send more than %d chunks\n", + IWL_NUM_OF_TBS); + return -EINVAL; + } + + BUG_ON(addr & ~DMA_BIT_MASK(36)); + if (unlikely(addr & ~IWL_TX_DMA_MASK)) + IWL_ERR(priv, "Unaligned address = %llx\n", + (unsigned long long)addr); + + iwl4965_tfd_set_tb(tfd, num_tbs, addr, len); + + return 0; +} + +/* + * Tell nic where to find circular buffer of Tx Frame Descriptors for + * given Tx queue, and enable the DMA channel used for that queue. + * + * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA + * channels supported in hardware. + */ +int iwl4965_hw_tx_queue_init(struct iwl_priv *priv, + struct iwl_tx_queue *txq) +{ + int txq_id = txq->q.id; + + /* Circular buffer (TFD queue in DRAM) physical base address */ + iwl_legacy_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id), + txq->q.dma_addr >> 8); + + return 0; +} + +/****************************************************************************** + * + * Generic RX handler implementations + * + ******************************************************************************/ +static void iwl4965_rx_reply_alive(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_alive_resp *palive; + struct delayed_work *pwork; + + palive = &pkt->u.alive_frame; + + IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision " + "0x%01X 0x%01X\n", + palive->is_valid, palive->ver_type, + palive->ver_subtype); + + if (palive->ver_subtype == INITIALIZE_SUBTYPE) { + IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); + memcpy(&priv->card_alive_init, + &pkt->u.alive_frame, + sizeof(struct iwl_init_alive_resp)); + pwork = &priv->init_alive_start; + } else { + IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); + memcpy(&priv->card_alive, &pkt->u.alive_frame, + sizeof(struct iwl_alive_resp)); + pwork = &priv->alive_start; + } + + /* We delay the ALIVE response by 5ms to + * give the HW RF Kill time to activate... */ + if (palive->is_valid == UCODE_VALID_OK) + queue_delayed_work(priv->workqueue, pwork, + msecs_to_jiffies(5)); + else + IWL_WARN(priv, "uCode did not respond OK.\n"); +} + +/** + * iwl4965_bg_statistics_periodic - Timer callback to queue statistics + * + * This callback is provided in order to send a statistics request. + * + * This timer function is continually reset to execute within + * REG_RECALIB_PERIOD seconds since the last STATISTICS_NOTIFICATION + * was received. We need to ensure we receive the statistics in order + * to update the temperature used for calibrating the TXPOWER. + */ +static void iwl4965_bg_statistics_periodic(unsigned long data) +{ + struct iwl_priv *priv = (struct iwl_priv *)data; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + /* dont send host command if rf-kill is on */ + if (!iwl_legacy_is_ready_rf(priv)) + return; + + iwl_legacy_send_statistics_request(priv, CMD_ASYNC, false); +} + + +static void iwl4965_print_cont_event_trace(struct iwl_priv *priv, u32 base, + u32 start_idx, u32 num_events, + u32 mode) +{ + u32 i; + u32 ptr; /* SRAM byte address of log data */ + u32 ev, time, data; /* event log data */ + unsigned long reg_flags; + + if (mode == 0) + ptr = base + (4 * sizeof(u32)) + (start_idx * 2 * sizeof(u32)); + else + ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32)); + + /* Make sure device is powered up for SRAM reads */ + spin_lock_irqsave(&priv->reg_lock, reg_flags); + if (iwl_grab_nic_access(priv)) { + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); + return; + } + + /* Set starting address; reads will auto-increment */ + _iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); + rmb(); + + /* + * "time" is actually "data" for mode 0 (no timestamp). + * place event id # at far right for easier visual parsing. + */ + for (i = 0; i < num_events; i++) { + ev = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); + time = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); + if (mode == 0) { + trace_iwlwifi_legacy_dev_ucode_cont_event(priv, + 0, time, ev); + } else { + data = _iwl_legacy_read_direct32(priv, + HBUS_TARG_MEM_RDAT); + trace_iwlwifi_legacy_dev_ucode_cont_event(priv, + time, data, ev); + } + } + /* Allow device to power down */ + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); +} + +static void iwl4965_continuous_event_trace(struct iwl_priv *priv) +{ + u32 capacity; /* event log capacity in # entries */ + u32 base; /* SRAM byte address of event log header */ + u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ + u32 num_wraps; /* # times uCode wrapped to top of log */ + u32 next_entry; /* index of next entry to be written by uCode */ + + if (priv->ucode_type == UCODE_INIT) + base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr); + else + base = le32_to_cpu(priv->card_alive.log_event_table_ptr); + if (priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { + capacity = iwl_legacy_read_targ_mem(priv, base); + num_wraps = iwl_legacy_read_targ_mem(priv, + base + (2 * sizeof(u32))); + mode = iwl_legacy_read_targ_mem(priv, base + (1 * sizeof(u32))); + next_entry = iwl_legacy_read_targ_mem(priv, + base + (3 * sizeof(u32))); + } else + return; + + if (num_wraps == priv->event_log.num_wraps) { + iwl4965_print_cont_event_trace(priv, + base, priv->event_log.next_entry, + next_entry - priv->event_log.next_entry, + mode); + priv->event_log.non_wraps_count++; + } else { + if ((num_wraps - priv->event_log.num_wraps) > 1) + priv->event_log.wraps_more_count++; + else + priv->event_log.wraps_once_count++; + trace_iwlwifi_legacy_dev_ucode_wrap_event(priv, + num_wraps - priv->event_log.num_wraps, + next_entry, priv->event_log.next_entry); + if (next_entry < priv->event_log.next_entry) { + iwl4965_print_cont_event_trace(priv, base, + priv->event_log.next_entry, + capacity - priv->event_log.next_entry, + mode); + + iwl4965_print_cont_event_trace(priv, base, 0, + next_entry, mode); + } else { + iwl4965_print_cont_event_trace(priv, base, + next_entry, capacity - next_entry, + mode); + + iwl4965_print_cont_event_trace(priv, base, 0, + next_entry, mode); + } + } + priv->event_log.num_wraps = num_wraps; + priv->event_log.next_entry = next_entry; +} + +/** + * iwl4965_bg_ucode_trace - Timer callback to log ucode event + * + * The timer is continually set to execute every + * UCODE_TRACE_PERIOD milliseconds after the last timer expired + * this function is to perform continuous uCode event logging operation + * if enabled + */ +static void iwl4965_bg_ucode_trace(unsigned long data) +{ + struct iwl_priv *priv = (struct iwl_priv *)data; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (priv->event_log.ucode_trace) { + iwl4965_continuous_event_trace(priv); + /* Reschedule the timer to occur in UCODE_TRACE_PERIOD */ + mod_timer(&priv->ucode_trace, + jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD)); + } +} + +static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl4965_beacon_notif *beacon = + (struct iwl4965_beacon_notif *)pkt->u.raw; +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + u8 rate = iwl4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); + + IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d " + "tsf %d %d rate %d\n", + le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK, + beacon->beacon_notify_hdr.failure_frame, + le32_to_cpu(beacon->ibss_mgr_status), + le32_to_cpu(beacon->high_tsf), + le32_to_cpu(beacon->low_tsf), rate); +#endif + + priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); +} + +static void iwl4965_perform_ct_kill_task(struct iwl_priv *priv) +{ + unsigned long flags; + + IWL_DEBUG_POWER(priv, "Stop all queues\n"); + + if (priv->mac80211_registered) + ieee80211_stop_queues(priv->hw); + + iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, + CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); + iwl_read32(priv, CSR_UCODE_DRV_GP1); + + spin_lock_irqsave(&priv->reg_lock, flags); + if (!iwl_grab_nic_access(priv)) + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, flags); +} + +/* Handle notification from uCode that card's power state is changing + * due to software, hardware, or critical temperature RFKILL */ +static void iwl4965_rx_card_state_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); + unsigned long status = priv->status; + + IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n", + (flags & HW_CARD_DISABLED) ? "Kill" : "On", + (flags & SW_CARD_DISABLED) ? "Kill" : "On", + (flags & CT_CARD_DISABLED) ? + "Reached" : "Not reached"); + + if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | + CT_CARD_DISABLED)) { + + iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, + CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); + + iwl_legacy_write_direct32(priv, HBUS_TARG_MBX_C, + HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); + + if (!(flags & RXON_CARD_DISABLED)) { + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, + CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); + iwl_legacy_write_direct32(priv, HBUS_TARG_MBX_C, + HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); + } + } + + if (flags & CT_CARD_DISABLED) + iwl4965_perform_ct_kill_task(priv); + + if (flags & HW_CARD_DISABLED) + set_bit(STATUS_RF_KILL_HW, &priv->status); + else + clear_bit(STATUS_RF_KILL_HW, &priv->status); + + if (!(flags & RXON_CARD_DISABLED)) + iwl_legacy_scan_cancel(priv); + + if ((test_bit(STATUS_RF_KILL_HW, &status) != + test_bit(STATUS_RF_KILL_HW, &priv->status))) + wiphy_rfkill_set_hw_state(priv->hw->wiphy, + test_bit(STATUS_RF_KILL_HW, &priv->status)); + else + wake_up_interruptible(&priv->wait_command_queue); +} + +/** + * iwl4965_setup_rx_handlers - Initialize Rx handler callbacks + * + * Setup the RX handlers for each of the reply types sent from the uCode + * to the host. + * + * This function chains into the hardware specific files for them to setup + * any hardware specific handlers as well. + */ +static void iwl4965_setup_rx_handlers(struct iwl_priv *priv) +{ + priv->rx_handlers[REPLY_ALIVE] = iwl4965_rx_reply_alive; + priv->rx_handlers[REPLY_ERROR] = iwl_legacy_rx_reply_error; + priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_legacy_rx_csa; + priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] = + iwl_legacy_rx_spectrum_measure_notif; + priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_legacy_rx_pm_sleep_notif; + priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = + iwl_legacy_rx_pm_debug_statistics_notif; + priv->rx_handlers[BEACON_NOTIFICATION] = iwl4965_rx_beacon_notif; + + /* + * The same handler is used for both the REPLY to a discrete + * statistics request from the host as well as for the periodic + * statistics notifications (after received beacons) from the uCode. + */ + priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl4965_reply_statistics; + priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl4965_rx_statistics; + + iwl_legacy_setup_rx_scan_handlers(priv); + + /* status change handler */ + priv->rx_handlers[CARD_STATE_NOTIFICATION] = + iwl4965_rx_card_state_notif; + + priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] = + iwl4965_rx_missed_beacon_notif; + /* Rx handlers */ + priv->rx_handlers[REPLY_RX_PHY_CMD] = iwl4965_rx_reply_rx_phy; + priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwl4965_rx_reply_rx; + /* block ack */ + priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl4965_rx_reply_compressed_ba; + /* Set up hardware specific Rx handlers */ + priv->cfg->ops->lib->rx_handler_setup(priv); +} + +/** + * iwl4965_rx_handle - Main entry function for receiving responses from uCode + * + * Uses the priv->rx_handlers callback function array to invoke + * the appropriate handlers, including command responses, + * frame-received notifications, and other notifications. + */ +void iwl4965_rx_handle(struct iwl_priv *priv) +{ + struct iwl_rx_mem_buffer *rxb; + struct iwl_rx_packet *pkt; + struct iwl_rx_queue *rxq = &priv->rxq; + u32 r, i; + int reclaim; + unsigned long flags; + u8 fill_rx = 0; + u32 count = 8; + int total_empty; + + /* uCode's read index (stored in shared DRAM) indicates the last Rx + * buffer that the driver may process (last buffer filled by ucode). */ + r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF; + i = rxq->read; + + /* Rx interrupt, but nothing sent from uCode */ + if (i == r) + IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i); + + /* calculate total frames need to be restock after handling RX */ + total_empty = r - rxq->write_actual; + if (total_empty < 0) + total_empty += RX_QUEUE_SIZE; + + if (total_empty > (RX_QUEUE_SIZE / 2)) + fill_rx = 1; + + while (i != r) { + int len; + + rxb = rxq->queue[i]; + + /* If an RXB doesn't have a Rx queue slot associated with it, + * then a bug has been introduced in the queue refilling + * routines -- catch it here */ + BUG_ON(rxb == NULL); + + rxq->queue[i] = NULL; + + pci_unmap_page(priv->pci_dev, rxb->page_dma, + PAGE_SIZE << priv->hw_params.rx_page_order, + PCI_DMA_FROMDEVICE); + pkt = rxb_addr(rxb); + + len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; + len += sizeof(u32); /* account for status word */ + trace_iwlwifi_legacy_dev_rx(priv, pkt, len); + + /* Reclaim a command buffer only if this packet is a response + * to a (driver-originated) command. + * If the packet (e.g. Rx frame) originated from uCode, + * there is no command buffer to reclaim. + * Ucode should set SEQ_RX_FRAME bit if ucode-originated, + * but apparently a few don't get set; catch them here. */ + reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) && + (pkt->hdr.cmd != REPLY_RX_PHY_CMD) && + (pkt->hdr.cmd != REPLY_RX) && + (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) && + (pkt->hdr.cmd != REPLY_COMPRESSED_BA) && + (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && + (pkt->hdr.cmd != REPLY_TX); + + /* Based on type of command response or notification, + * handle those that need handling via function in + * rx_handlers table. See iwl4965_setup_rx_handlers() */ + if (priv->rx_handlers[pkt->hdr.cmd]) { + IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, + i, iwl_legacy_get_cmd_string(pkt->hdr.cmd), + pkt->hdr.cmd); + priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; + priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); + } else { + /* No handling needed */ + IWL_DEBUG_RX(priv, + "r %d i %d No handler needed for %s, 0x%02x\n", + r, i, iwl_legacy_get_cmd_string(pkt->hdr.cmd), + pkt->hdr.cmd); + } + + /* + * XXX: After here, we should always check rxb->page + * against NULL before touching it or its virtual + * memory (pkt). Because some rx_handler might have + * already taken or freed the pages. + */ + + if (reclaim) { + /* Invoke any callbacks, transfer the buffer to caller, + * and fire off the (possibly) blocking iwl_legacy_send_cmd() + * as we reclaim the driver command queue */ + if (rxb->page) + iwl_legacy_tx_cmd_complete(priv, rxb); + else + IWL_WARN(priv, "Claim null rxb?\n"); + } + + /* Reuse the page if possible. For notification packets and + * SKBs that fail to Rx correctly, add them back into the + * rx_free list for reuse later. */ + spin_lock_irqsave(&rxq->lock, flags); + if (rxb->page != NULL) { + rxb->page_dma = pci_map_page(priv->pci_dev, rxb->page, + 0, PAGE_SIZE << priv->hw_params.rx_page_order, + PCI_DMA_FROMDEVICE); + list_add_tail(&rxb->list, &rxq->rx_free); + rxq->free_count++; + } else + list_add_tail(&rxb->list, &rxq->rx_used); + + spin_unlock_irqrestore(&rxq->lock, flags); + + i = (i + 1) & RX_QUEUE_MASK; + /* If there are a lot of unused frames, + * restock the Rx queue so ucode wont assert. */ + if (fill_rx) { + count++; + if (count >= 8) { + rxq->read = i; + iwl4965_rx_replenish_now(priv); + count = 0; + } + } + } + + /* Backtrack one entry */ + rxq->read = i; + if (fill_rx) + iwl4965_rx_replenish_now(priv); + else + iwl4965_rx_queue_restock(priv); +} + +/* call this function to flush any scheduled tasklet */ +static inline void iwl4965_synchronize_irq(struct iwl_priv *priv) +{ + /* wait to make sure we flush pending tasklet*/ + synchronize_irq(priv->pci_dev->irq); + tasklet_kill(&priv->irq_tasklet); +} + +static void iwl4965_irq_tasklet(struct iwl_priv *priv) +{ + u32 inta, handled = 0; + u32 inta_fh; + unsigned long flags; + u32 i; +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + u32 inta_mask; +#endif + + spin_lock_irqsave(&priv->lock, flags); + + /* Ack/clear/reset pending uCode interrupts. + * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, + * and will clear only when CSR_FH_INT_STATUS gets cleared. */ + inta = iwl_read32(priv, CSR_INT); + iwl_write32(priv, CSR_INT, inta); + + /* Ack/clear/reset pending flow-handler (DMA) interrupts. + * Any new interrupts that happen after this, either while we're + * in this tasklet, or later, will show up in next ISR/tasklet. */ + inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); + iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh); + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + if (iwl_legacy_get_debug_level(priv) & IWL_DL_ISR) { + /* just for debug */ + inta_mask = iwl_read32(priv, CSR_INT_MASK); + IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", + inta, inta_mask, inta_fh); + } +#endif + + spin_unlock_irqrestore(&priv->lock, flags); + + /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not + * atomic, make sure that inta covers all the interrupts that + * we've discovered, even if FH interrupt came in just after + * reading CSR_INT. */ + if (inta_fh & CSR49_FH_INT_RX_MASK) + inta |= CSR_INT_BIT_FH_RX; + if (inta_fh & CSR49_FH_INT_TX_MASK) + inta |= CSR_INT_BIT_FH_TX; + + /* Now service all interrupt bits discovered above. */ + if (inta & CSR_INT_BIT_HW_ERR) { + IWL_ERR(priv, "Hardware error detected. Restarting.\n"); + + /* Tell the device to stop sending interrupts */ + iwl_legacy_disable_interrupts(priv); + + priv->isr_stats.hw++; + iwl_legacy_irq_handle_error(priv); + + handled |= CSR_INT_BIT_HW_ERR; + + return; + } + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + if (iwl_legacy_get_debug_level(priv) & (IWL_DL_ISR)) { + /* NIC fires this, but we don't use it, redundant with WAKEUP */ + if (inta & CSR_INT_BIT_SCD) { + IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " + "the frame/frames.\n"); + priv->isr_stats.sch++; + } + + /* Alive notification via Rx interrupt will do the real work */ + if (inta & CSR_INT_BIT_ALIVE) { + IWL_DEBUG_ISR(priv, "Alive interrupt\n"); + priv->isr_stats.alive++; + } + } +#endif + /* Safely ignore these bits for debug checks below */ + inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE); + + /* HW RF KILL switch toggled */ + if (inta & CSR_INT_BIT_RF_KILL) { + int hw_rf_kill = 0; + if (!(iwl_read32(priv, CSR_GP_CNTRL) & + CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) + hw_rf_kill = 1; + + IWL_WARN(priv, "RF_KILL bit toggled to %s.\n", + hw_rf_kill ? "disable radio" : "enable radio"); + + priv->isr_stats.rfkill++; + + /* driver only loads ucode once setting the interface up. + * the driver allows loading the ucode even if the radio + * is killed. Hence update the killswitch state here. The + * rfkill handler will care about restarting if needed. + */ + if (!test_bit(STATUS_ALIVE, &priv->status)) { + if (hw_rf_kill) + set_bit(STATUS_RF_KILL_HW, &priv->status); + else + clear_bit(STATUS_RF_KILL_HW, &priv->status); + wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill); + } + + handled |= CSR_INT_BIT_RF_KILL; + } + + /* Chip got too hot and stopped itself */ + if (inta & CSR_INT_BIT_CT_KILL) { + IWL_ERR(priv, "Microcode CT kill error detected.\n"); + priv->isr_stats.ctkill++; + handled |= CSR_INT_BIT_CT_KILL; + } + + /* Error detected by uCode */ + if (inta & CSR_INT_BIT_SW_ERR) { + IWL_ERR(priv, "Microcode SW error detected. " + " Restarting 0x%X.\n", inta); + priv->isr_stats.sw++; + iwl_legacy_irq_handle_error(priv); + handled |= CSR_INT_BIT_SW_ERR; + } + + /* + * uCode wakes up after power-down sleep. + * Tell device about any new tx or host commands enqueued, + * and about any Rx buffers made available while asleep. + */ + if (inta & CSR_INT_BIT_WAKEUP) { + IWL_DEBUG_ISR(priv, "Wakeup interrupt\n"); + iwl_legacy_rx_queue_update_write_ptr(priv, &priv->rxq); + for (i = 0; i < priv->hw_params.max_txq_num; i++) + iwl_legacy_txq_update_write_ptr(priv, &priv->txq[i]); + priv->isr_stats.wakeup++; + handled |= CSR_INT_BIT_WAKEUP; + } + + /* All uCode command responses, including Tx command responses, + * Rx "responses" (frame-received notification), and other + * notifications from uCode come through here*/ + if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { + iwl4965_rx_handle(priv); + priv->isr_stats.rx++; + handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); + } + + /* This "Tx" DMA channel is used only for loading uCode */ + if (inta & CSR_INT_BIT_FH_TX) { + IWL_DEBUG_ISR(priv, "uCode load interrupt\n"); + priv->isr_stats.tx++; + handled |= CSR_INT_BIT_FH_TX; + /* Wake up uCode load routine, now that load is complete */ + priv->ucode_write_complete = 1; + wake_up_interruptible(&priv->wait_command_queue); + } + + if (inta & ~handled) { + IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); + priv->isr_stats.unhandled++; + } + + if (inta & ~(priv->inta_mask)) { + IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", + inta & ~priv->inta_mask); + IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh); + } + + /* Re-enable all interrupts */ + /* only Re-enable if diabled by irq */ + if (test_bit(STATUS_INT_ENABLED, &priv->status)) + iwl_legacy_enable_interrupts(priv); + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + if (iwl_legacy_get_debug_level(priv) & (IWL_DL_ISR)) { + inta = iwl_read32(priv, CSR_INT); + inta_mask = iwl_read32(priv, CSR_INT_MASK); + inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); + IWL_DEBUG_ISR(priv, + "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, " + "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); + } +#endif +} + +/***************************************************************************** + * + * sysfs attributes + * + *****************************************************************************/ + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + +/* + * The following adds a new attribute to the sysfs representation + * of this device driver (i.e. a new file in /sys/class/net/wlan0/device/) + * used for controlling the debug level. + * + * See the level definitions in iwl for details. + * + * The debug_level being managed using sysfs below is a per device debug + * level that is used instead of the global debug level if it (the per + * device debug level) is set. + */ +static ssize_t iwl4965_show_debug_level(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + return sprintf(buf, "0x%08X\n", iwl_legacy_get_debug_level(priv)); +} +static ssize_t iwl4965_store_debug_level(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + unsigned long val; + int ret; + + ret = strict_strtoul(buf, 0, &val); + if (ret) + IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf); + else { + priv->debug_level = val; + if (iwl_legacy_alloc_traffic_mem(priv)) + IWL_ERR(priv, + "Not enough memory to generate traffic log\n"); + } + return strnlen(buf, count); +} + +static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, + iwl4965_show_debug_level, iwl4965_store_debug_level); + + +#endif /* CONFIG_IWLWIFI_LEGACY_DEBUG */ + + +static ssize_t iwl4965_show_temperature(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + + if (!iwl_legacy_is_alive(priv)) + return -EAGAIN; + + return sprintf(buf, "%d\n", priv->temperature); +} + +static DEVICE_ATTR(temperature, S_IRUGO, iwl4965_show_temperature, NULL); + +static ssize_t iwl4965_show_tx_power(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + + if (!iwl_legacy_is_ready_rf(priv)) + return sprintf(buf, "off\n"); + else + return sprintf(buf, "%d\n", priv->tx_power_user_lmt); +} + +static ssize_t iwl4965_store_tx_power(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iwl_priv *priv = dev_get_drvdata(d); + unsigned long val; + int ret; + + ret = strict_strtoul(buf, 10, &val); + if (ret) + IWL_INFO(priv, "%s is not in decimal form.\n", buf); + else { + ret = iwl_legacy_set_tx_power(priv, val, false); + if (ret) + IWL_ERR(priv, "failed setting tx power (0x%d).\n", + ret); + else + ret = count; + } + return ret; +} + +static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, + iwl4965_show_tx_power, iwl4965_store_tx_power); + +static struct attribute *iwl_sysfs_entries[] = { + &dev_attr_temperature.attr, + &dev_attr_tx_power.attr, +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + &dev_attr_debug_level.attr, +#endif + NULL +}; + +static struct attribute_group iwl_attribute_group = { + .name = NULL, /* put in device directory */ + .attrs = iwl_sysfs_entries, +}; + +/****************************************************************************** + * + * uCode download functions + * + ******************************************************************************/ + +static void iwl4965_dealloc_ucode_pci(struct iwl_priv *priv) +{ + iwl_legacy_free_fw_desc(priv->pci_dev, &priv->ucode_code); + iwl_legacy_free_fw_desc(priv->pci_dev, &priv->ucode_data); + iwl_legacy_free_fw_desc(priv->pci_dev, &priv->ucode_data_backup); + iwl_legacy_free_fw_desc(priv->pci_dev, &priv->ucode_init); + iwl_legacy_free_fw_desc(priv->pci_dev, &priv->ucode_init_data); + iwl_legacy_free_fw_desc(priv->pci_dev, &priv->ucode_boot); +} + +static void iwl4965_nic_start(struct iwl_priv *priv) +{ + /* Remove all resets to allow NIC to operate */ + iwl_write32(priv, CSR_RESET, 0); +} + +static void iwl4965_ucode_callback(const struct firmware *ucode_raw, + void *context); +static int iwl4965_mac_setup_register(struct iwl_priv *priv, + u32 max_probe_length); + +static int __must_check iwl4965_request_firmware(struct iwl_priv *priv, bool first) +{ + const char *name_pre = priv->cfg->fw_name_pre; + char tag[8]; + + if (first) { + priv->fw_index = priv->cfg->ucode_api_max; + sprintf(tag, "%d", priv->fw_index); + } else { + priv->fw_index--; + sprintf(tag, "%d", priv->fw_index); + } + + if (priv->fw_index < priv->cfg->ucode_api_min) { + IWL_ERR(priv, "no suitable firmware found!\n"); + return -ENOENT; + } + + sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); + + IWL_DEBUG_INFO(priv, "attempting to load firmware '%s'\n", + priv->firmware_name); + + return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, + &priv->pci_dev->dev, GFP_KERNEL, priv, + iwl4965_ucode_callback); +} + +struct iwl4965_firmware_pieces { + const void *inst, *data, *init, *init_data, *boot; + size_t inst_size, data_size, init_size, init_data_size, boot_size; +}; + +static int iwl4965_load_firmware(struct iwl_priv *priv, + const struct firmware *ucode_raw, + struct iwl4965_firmware_pieces *pieces) +{ + struct iwl_ucode_header *ucode = (void *)ucode_raw->data; + u32 api_ver, hdr_size; + const u8 *src; + + priv->ucode_ver = le32_to_cpu(ucode->ver); + api_ver = IWL_UCODE_API(priv->ucode_ver); + + switch (api_ver) { + default: + case 0: + case 1: + case 2: + hdr_size = 24; + if (ucode_raw->size < hdr_size) { + IWL_ERR(priv, "File size too small!\n"); + return -EINVAL; + } + pieces->inst_size = le32_to_cpu(ucode->v1.inst_size); + pieces->data_size = le32_to_cpu(ucode->v1.data_size); + pieces->init_size = le32_to_cpu(ucode->v1.init_size); + pieces->init_data_size = + le32_to_cpu(ucode->v1.init_data_size); + pieces->boot_size = le32_to_cpu(ucode->v1.boot_size); + src = ucode->v1.data; + break; + } + + /* Verify size of file vs. image size info in file's header */ + if (ucode_raw->size != hdr_size + pieces->inst_size + + pieces->data_size + pieces->init_size + + pieces->init_data_size + pieces->boot_size) { + + IWL_ERR(priv, + "uCode file size %d does not match expected size\n", + (int)ucode_raw->size); + return -EINVAL; + } + + pieces->inst = src; + src += pieces->inst_size; + pieces->data = src; + src += pieces->data_size; + pieces->init = src; + src += pieces->init_size; + pieces->init_data = src; + src += pieces->init_data_size; + pieces->boot = src; + src += pieces->boot_size; + + return 0; +} + +/** + * iwl4965_ucode_callback - callback when firmware was loaded + * + * If loaded successfully, copies the firmware into buffers + * for the card to fetch (via DMA). + */ +static void +iwl4965_ucode_callback(const struct firmware *ucode_raw, void *context) +{ + struct iwl_priv *priv = context; + struct iwl_ucode_header *ucode; + int err; + struct iwl4965_firmware_pieces pieces; + const unsigned int api_max = priv->cfg->ucode_api_max; + const unsigned int api_min = priv->cfg->ucode_api_min; + u32 api_ver; + + u32 max_probe_length = 200; + u32 standard_phy_calibration_size = + IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE; + + memset(&pieces, 0, sizeof(pieces)); + + if (!ucode_raw) { + if (priv->fw_index <= priv->cfg->ucode_api_max) + IWL_ERR(priv, + "request for firmware file '%s' failed.\n", + priv->firmware_name); + goto try_again; + } + + IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n", + priv->firmware_name, ucode_raw->size); + + /* Make sure that we got at least the API version number */ + if (ucode_raw->size < 4) { + IWL_ERR(priv, "File size way too small!\n"); + goto try_again; + } + + /* Data from ucode file: header followed by uCode images */ + ucode = (struct iwl_ucode_header *)ucode_raw->data; + + err = iwl4965_load_firmware(priv, ucode_raw, &pieces); + + if (err) + goto try_again; + + api_ver = IWL_UCODE_API(priv->ucode_ver); + + /* + * api_ver should match the api version forming part of the + * firmware filename ... but we don't check for that and only rely + * on the API version read from firmware header from here on forward + */ + if (api_ver < api_min || api_ver > api_max) { + IWL_ERR(priv, + "Driver unable to support your firmware API. " + "Driver supports v%u, firmware is v%u.\n", + api_max, api_ver); + goto try_again; + } + + if (api_ver != api_max) + IWL_ERR(priv, + "Firmware has old API version. Expected v%u, " + "got v%u. New firmware can be obtained " + "from http://www.intellinuxwireless.org.\n", + api_max, api_ver); + + IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u\n", + IWL_UCODE_MAJOR(priv->ucode_ver), + IWL_UCODE_MINOR(priv->ucode_ver), + IWL_UCODE_API(priv->ucode_ver), + IWL_UCODE_SERIAL(priv->ucode_ver)); + + snprintf(priv->hw->wiphy->fw_version, + sizeof(priv->hw->wiphy->fw_version), + "%u.%u.%u.%u", + IWL_UCODE_MAJOR(priv->ucode_ver), + IWL_UCODE_MINOR(priv->ucode_ver), + IWL_UCODE_API(priv->ucode_ver), + IWL_UCODE_SERIAL(priv->ucode_ver)); + + /* + * For any of the failures below (before allocating pci memory) + * we will try to load a version with a smaller API -- maybe the + * user just got a corrupted version of the latest API. + */ + + IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n", + priv->ucode_ver); + IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %Zd\n", + pieces.inst_size); + IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %Zd\n", + pieces.data_size); + IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %Zd\n", + pieces.init_size); + IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n", + pieces.init_data_size); + IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %Zd\n", + pieces.boot_size); + + /* Verify that uCode images will fit in card's SRAM */ + if (pieces.inst_size > priv->hw_params.max_inst_size) { + IWL_ERR(priv, "uCode instr len %Zd too large to fit in\n", + pieces.inst_size); + goto try_again; + } + + if (pieces.data_size > priv->hw_params.max_data_size) { + IWL_ERR(priv, "uCode data len %Zd too large to fit in\n", + pieces.data_size); + goto try_again; + } + + if (pieces.init_size > priv->hw_params.max_inst_size) { + IWL_ERR(priv, "uCode init instr len %Zd too large to fit in\n", + pieces.init_size); + goto try_again; + } + + if (pieces.init_data_size > priv->hw_params.max_data_size) { + IWL_ERR(priv, "uCode init data len %Zd too large to fit in\n", + pieces.init_data_size); + goto try_again; + } + + if (pieces.boot_size > priv->hw_params.max_bsm_size) { + IWL_ERR(priv, "uCode boot instr len %Zd too large to fit in\n", + pieces.boot_size); + goto try_again; + } + + /* Allocate ucode buffers for card's bus-master loading ... */ + + /* Runtime instructions and 2 copies of data: + * 1) unmodified from disk + * 2) backup cache for save/restore during power-downs */ + priv->ucode_code.len = pieces.inst_size; + iwl_legacy_alloc_fw_desc(priv->pci_dev, &priv->ucode_code); + + priv->ucode_data.len = pieces.data_size; + iwl_legacy_alloc_fw_desc(priv->pci_dev, &priv->ucode_data); + + priv->ucode_data_backup.len = pieces.data_size; + iwl_legacy_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup); + + if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr || + !priv->ucode_data_backup.v_addr) + goto err_pci_alloc; + + /* Initialization instructions and data */ + if (pieces.init_size && pieces.init_data_size) { + priv->ucode_init.len = pieces.init_size; + iwl_legacy_alloc_fw_desc(priv->pci_dev, &priv->ucode_init); + + priv->ucode_init_data.len = pieces.init_data_size; + iwl_legacy_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data); + + if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr) + goto err_pci_alloc; + } + + /* Bootstrap (instructions only, no data) */ + if (pieces.boot_size) { + priv->ucode_boot.len = pieces.boot_size; + iwl_legacy_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot); + + if (!priv->ucode_boot.v_addr) + goto err_pci_alloc; + } + + /* Now that we can no longer fail, copy information */ + + priv->sta_key_max_num = STA_KEY_MAX_NUM; + + /* Copy images into buffers for card's bus-master reads ... */ + + /* Runtime instructions (first block of data in file) */ + IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n", + pieces.inst_size); + memcpy(priv->ucode_code.v_addr, pieces.inst, pieces.inst_size); + + IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n", + priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr); + + /* + * Runtime data + * NOTE: Copy into backup buffer will be done in iwl_up() + */ + IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", + pieces.data_size); + memcpy(priv->ucode_data.v_addr, pieces.data, pieces.data_size); + memcpy(priv->ucode_data_backup.v_addr, pieces.data, pieces.data_size); + + /* Initialization instructions */ + if (pieces.init_size) { + IWL_DEBUG_INFO(priv, + "Copying (but not loading) init instr len %Zd\n", + pieces.init_size); + memcpy(priv->ucode_init.v_addr, pieces.init, pieces.init_size); + } + + /* Initialization data */ + if (pieces.init_data_size) { + IWL_DEBUG_INFO(priv, + "Copying (but not loading) init data len %Zd\n", + pieces.init_data_size); + memcpy(priv->ucode_init_data.v_addr, pieces.init_data, + pieces.init_data_size); + } + + /* Bootstrap instructions */ + IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", + pieces.boot_size); + memcpy(priv->ucode_boot.v_addr, pieces.boot, pieces.boot_size); + + /* + * figure out the offset of chain noise reset and gain commands + * base on the size of standard phy calibration commands table size + */ + priv->_4965.phy_calib_chain_noise_reset_cmd = + standard_phy_calibration_size; + priv->_4965.phy_calib_chain_noise_gain_cmd = + standard_phy_calibration_size + 1; + + /************************************************** + * This is still part of probe() in a sense... + * + * 9. Setup and register with mac80211 and debugfs + **************************************************/ + err = iwl4965_mac_setup_register(priv, max_probe_length); + if (err) + goto out_unbind; + + err = iwl_legacy_dbgfs_register(priv, DRV_NAME); + if (err) + IWL_ERR(priv, + "failed to create debugfs files. Ignoring error: %d\n", err); + + err = sysfs_create_group(&priv->pci_dev->dev.kobj, + &iwl_attribute_group); + if (err) { + IWL_ERR(priv, "failed to create sysfs device attributes\n"); + goto out_unbind; + } + + /* We have our copies now, allow OS release its copies */ + release_firmware(ucode_raw); + complete(&priv->_4965.firmware_loading_complete); + return; + + try_again: + /* try next, if any */ + if (iwl4965_request_firmware(priv, false)) + goto out_unbind; + release_firmware(ucode_raw); + return; + + err_pci_alloc: + IWL_ERR(priv, "failed to allocate pci memory\n"); + iwl4965_dealloc_ucode_pci(priv); + out_unbind: + complete(&priv->_4965.firmware_loading_complete); + device_release_driver(&priv->pci_dev->dev); + release_firmware(ucode_raw); +} + +static const char * const desc_lookup_text[] = { + "OK", + "FAIL", + "BAD_PARAM", + "BAD_CHECKSUM", + "NMI_INTERRUPT_WDG", + "SYSASSERT", + "FATAL_ERROR", + "BAD_COMMAND", + "HW_ERROR_TUNE_LOCK", + "HW_ERROR_TEMPERATURE", + "ILLEGAL_CHAN_FREQ", + "VCC_NOT_STABLE", + "FH_ERROR", + "NMI_INTERRUPT_HOST", + "NMI_INTERRUPT_ACTION_PT", + "NMI_INTERRUPT_UNKNOWN", + "UCODE_VERSION_MISMATCH", + "HW_ERROR_ABS_LOCK", + "HW_ERROR_CAL_LOCK_FAIL", + "NMI_INTERRUPT_INST_ACTION_PT", + "NMI_INTERRUPT_DATA_ACTION_PT", + "NMI_TRM_HW_ER", + "NMI_INTERRUPT_TRM", + "NMI_INTERRUPT_BREAK_POINT" + "DEBUG_0", + "DEBUG_1", + "DEBUG_2", + "DEBUG_3", +}; + +static struct { char *name; u8 num; } advanced_lookup[] = { + { "NMI_INTERRUPT_WDG", 0x34 }, + { "SYSASSERT", 0x35 }, + { "UCODE_VERSION_MISMATCH", 0x37 }, + { "BAD_COMMAND", 0x38 }, + { "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C }, + { "FATAL_ERROR", 0x3D }, + { "NMI_TRM_HW_ERR", 0x46 }, + { "NMI_INTERRUPT_TRM", 0x4C }, + { "NMI_INTERRUPT_BREAK_POINT", 0x54 }, + { "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C }, + { "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 }, + { "NMI_INTERRUPT_HOST", 0x66 }, + { "NMI_INTERRUPT_ACTION_PT", 0x7C }, + { "NMI_INTERRUPT_UNKNOWN", 0x84 }, + { "NMI_INTERRUPT_INST_ACTION_PT", 0x86 }, + { "ADVANCED_SYSASSERT", 0 }, +}; + +static const char *iwl4965_desc_lookup(u32 num) +{ + int i; + int max = ARRAY_SIZE(desc_lookup_text); + + if (num < max) + return desc_lookup_text[num]; + + max = ARRAY_SIZE(advanced_lookup) - 1; + for (i = 0; i < max; i++) { + if (advanced_lookup[i].num == num) + break; + } + return advanced_lookup[i].name; +} + +#define ERROR_START_OFFSET (1 * sizeof(u32)) +#define ERROR_ELEM_SIZE (7 * sizeof(u32)) + +void iwl4965_dump_nic_error_log(struct iwl_priv *priv) +{ + u32 data2, line; + u32 desc, time, count, base, data1; + u32 blink1, blink2, ilink1, ilink2; + u32 pc, hcmd; + + if (priv->ucode_type == UCODE_INIT) { + base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr); + } else { + base = le32_to_cpu(priv->card_alive.error_event_table_ptr); + } + + if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { + IWL_ERR(priv, + "Not valid error log pointer 0x%08X for %s uCode\n", + base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); + return; + } + + count = iwl_legacy_read_targ_mem(priv, base); + + if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { + IWL_ERR(priv, "Start IWL Error Log Dump:\n"); + IWL_ERR(priv, "Status: 0x%08lX, count: %d\n", + priv->status, count); + } + + desc = iwl_legacy_read_targ_mem(priv, base + 1 * sizeof(u32)); + priv->isr_stats.err_code = desc; + pc = iwl_legacy_read_targ_mem(priv, base + 2 * sizeof(u32)); + blink1 = iwl_legacy_read_targ_mem(priv, base + 3 * sizeof(u32)); + blink2 = iwl_legacy_read_targ_mem(priv, base + 4 * sizeof(u32)); + ilink1 = iwl_legacy_read_targ_mem(priv, base + 5 * sizeof(u32)); + ilink2 = iwl_legacy_read_targ_mem(priv, base + 6 * sizeof(u32)); + data1 = iwl_legacy_read_targ_mem(priv, base + 7 * sizeof(u32)); + data2 = iwl_legacy_read_targ_mem(priv, base + 8 * sizeof(u32)); + line = iwl_legacy_read_targ_mem(priv, base + 9 * sizeof(u32)); + time = iwl_legacy_read_targ_mem(priv, base + 11 * sizeof(u32)); + hcmd = iwl_legacy_read_targ_mem(priv, base + 22 * sizeof(u32)); + + trace_iwlwifi_legacy_dev_ucode_error(priv, desc, + time, data1, data2, line, + blink1, blink2, ilink1, ilink2); + + IWL_ERR(priv, "Desc Time " + "data1 data2 line\n"); + IWL_ERR(priv, "%-28s (0x%04X) %010u 0x%08X 0x%08X %u\n", + iwl4965_desc_lookup(desc), desc, time, data1, data2, line); + IWL_ERR(priv, "pc blink1 blink2 ilink1 ilink2 hcmd\n"); + IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X 0x%05X 0x%05X\n", + pc, blink1, blink2, ilink1, ilink2, hcmd); +} + +#define EVENT_START_OFFSET (4 * sizeof(u32)) + +/** + * iwl4965_print_event_log - Dump error event log to syslog + * + */ +static int iwl4965_print_event_log(struct iwl_priv *priv, u32 start_idx, + u32 num_events, u32 mode, + int pos, char **buf, size_t bufsz) +{ + u32 i; + u32 base; /* SRAM byte address of event log header */ + u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */ + u32 ptr; /* SRAM byte address of log data */ + u32 ev, time, data; /* event log data */ + unsigned long reg_flags; + + if (num_events == 0) + return pos; + + if (priv->ucode_type == UCODE_INIT) { + base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); + } else { + base = le32_to_cpu(priv->card_alive.log_event_table_ptr); + } + + if (mode == 0) + event_size = 2 * sizeof(u32); + else + event_size = 3 * sizeof(u32); + + ptr = base + EVENT_START_OFFSET + (start_idx * event_size); + + /* Make sure device is powered up for SRAM reads */ + spin_lock_irqsave(&priv->reg_lock, reg_flags); + iwl_grab_nic_access(priv); + + /* Set starting address; reads will auto-increment */ + _iwl_legacy_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); + rmb(); + + /* "time" is actually "data" for mode 0 (no timestamp). + * place event id # at far right for easier visual parsing. */ + for (i = 0; i < num_events; i++) { + ev = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); + time = _iwl_legacy_read_direct32(priv, HBUS_TARG_MEM_RDAT); + if (mode == 0) { + /* data, ev */ + if (bufsz) { + pos += scnprintf(*buf + pos, bufsz - pos, + "EVT_LOG:0x%08x:%04u\n", + time, ev); + } else { + trace_iwlwifi_legacy_dev_ucode_event(priv, 0, + time, ev); + IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", + time, ev); + } + } else { + data = _iwl_legacy_read_direct32(priv, + HBUS_TARG_MEM_RDAT); + if (bufsz) { + pos += scnprintf(*buf + pos, bufsz - pos, + "EVT_LOGT:%010u:0x%08x:%04u\n", + time, data, ev); + } else { + IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n", + time, data, ev); + trace_iwlwifi_legacy_dev_ucode_event(priv, time, + data, ev); + } + } + } + + /* Allow device to power down */ + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, reg_flags); + return pos; +} + +/** + * iwl4965_print_last_event_logs - Dump the newest # of event log to syslog + */ +static int iwl4965_print_last_event_logs(struct iwl_priv *priv, u32 capacity, + u32 num_wraps, u32 next_entry, + u32 size, u32 mode, + int pos, char **buf, size_t bufsz) +{ + /* + * display the newest DEFAULT_LOG_ENTRIES entries + * i.e the entries just before the next ont that uCode would fill. + */ + if (num_wraps) { + if (next_entry < size) { + pos = iwl4965_print_event_log(priv, + capacity - (size - next_entry), + size - next_entry, mode, + pos, buf, bufsz); + pos = iwl4965_print_event_log(priv, 0, + next_entry, mode, + pos, buf, bufsz); + } else + pos = iwl4965_print_event_log(priv, next_entry - size, + size, mode, pos, buf, bufsz); + } else { + if (next_entry < size) { + pos = iwl4965_print_event_log(priv, 0, next_entry, + mode, pos, buf, bufsz); + } else { + pos = iwl4965_print_event_log(priv, next_entry - size, + size, mode, pos, buf, bufsz); + } + } + return pos; +} + +#define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20) + +int iwl4965_dump_nic_event_log(struct iwl_priv *priv, bool full_log, + char **buf, bool display) +{ + u32 base; /* SRAM byte address of event log header */ + u32 capacity; /* event log capacity in # entries */ + u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ + u32 num_wraps; /* # times uCode wrapped to top of log */ + u32 next_entry; /* index of next entry to be written by uCode */ + u32 size; /* # entries that we'll print */ + int pos = 0; + size_t bufsz = 0; + + if (priv->ucode_type == UCODE_INIT) { + base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); + } else { + base = le32_to_cpu(priv->card_alive.log_event_table_ptr); + } + + if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { + IWL_ERR(priv, + "Invalid event log pointer 0x%08X for %s uCode\n", + base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); + return -EINVAL; + } + + /* event log header */ + capacity = iwl_legacy_read_targ_mem(priv, base); + mode = iwl_legacy_read_targ_mem(priv, base + (1 * sizeof(u32))); + num_wraps = iwl_legacy_read_targ_mem(priv, base + (2 * sizeof(u32))); + next_entry = iwl_legacy_read_targ_mem(priv, base + (3 * sizeof(u32))); + + size = num_wraps ? capacity : next_entry; + + /* bail out if nothing in log */ + if (size == 0) { + IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); + return pos; + } + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + if (!(iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) + size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) + ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; +#else + size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) + ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; +#endif + IWL_ERR(priv, "Start IWL Event Log Dump: display last %u entries\n", + size); + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG + if (display) { + if (full_log) + bufsz = capacity * 48; + else + bufsz = size * 48; + *buf = kmalloc(bufsz, GFP_KERNEL); + if (!*buf) + return -ENOMEM; + } + if ((iwl_legacy_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { + /* + * if uCode has wrapped back to top of log, + * start at the oldest entry, + * i.e the next one that uCode would fill. + */ + if (num_wraps) + pos = iwl4965_print_event_log(priv, next_entry, + capacity - next_entry, mode, + pos, buf, bufsz); + /* (then/else) start at top of log */ + pos = iwl4965_print_event_log(priv, 0, + next_entry, mode, pos, buf, bufsz); + } else + pos = iwl4965_print_last_event_logs(priv, capacity, num_wraps, + next_entry, size, mode, + pos, buf, bufsz); +#else + pos = iwl4965_print_last_event_logs(priv, capacity, num_wraps, + next_entry, size, mode, + pos, buf, bufsz); +#endif + return pos; +} + +static void iwl4965_rf_kill_ct_config(struct iwl_priv *priv) +{ + struct iwl_ct_kill_config cmd; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&priv->lock, flags); + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, + CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); + spin_unlock_irqrestore(&priv->lock, flags); + + cmd.critical_temperature_R = + cpu_to_le32(priv->hw_params.ct_kill_threshold); + + ret = iwl_legacy_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, + sizeof(cmd), &cmd); + if (ret) + IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n"); + else + IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD " + "succeeded, " + "critical temperature is %d\n", + priv->hw_params.ct_kill_threshold); +} + +static const s8 default_queue_to_tx_fifo[] = { + IWL_TX_FIFO_VO, + IWL_TX_FIFO_VI, + IWL_TX_FIFO_BE, + IWL_TX_FIFO_BK, + IWL49_CMD_FIFO_NUM, + IWL_TX_FIFO_UNUSED, + IWL_TX_FIFO_UNUSED, +}; + +static int iwl4965_alive_notify(struct iwl_priv *priv) +{ + u32 a; + unsigned long flags; + int i, chan; + u32 reg_val; + + spin_lock_irqsave(&priv->lock, flags); + + /* Clear 4965's internal Tx Scheduler data base */ + priv->scd_base_addr = iwl_legacy_read_prph(priv, + IWL49_SCD_SRAM_BASE_ADDR); + a = priv->scd_base_addr + IWL49_SCD_CONTEXT_DATA_OFFSET; + for (; a < priv->scd_base_addr + IWL49_SCD_TX_STTS_BITMAP_OFFSET; a += 4) + iwl_legacy_write_targ_mem(priv, a, 0); + for (; a < priv->scd_base_addr + IWL49_SCD_TRANSLATE_TBL_OFFSET; a += 4) + iwl_legacy_write_targ_mem(priv, a, 0); + for (; a < priv->scd_base_addr + + IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4) + iwl_legacy_write_targ_mem(priv, a, 0); + + /* Tel 4965 where to find Tx byte count tables */ + iwl_legacy_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR, + priv->scd_bc_tbls.dma >> 10); + + /* Enable DMA channel */ + for (chan = 0; chan < FH49_TCSR_CHNL_NUM ; chan++) + iwl_legacy_write_direct32(priv, + FH_TCSR_CHNL_TX_CONFIG_REG(chan), + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); + + /* Update FH chicken bits */ + reg_val = iwl_legacy_read_direct32(priv, FH_TX_CHICKEN_BITS_REG); + iwl_legacy_write_direct32(priv, FH_TX_CHICKEN_BITS_REG, + reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); + + /* Disable chain mode for all queues */ + iwl_legacy_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0); + + /* Initialize each Tx queue (including the command queue) */ + for (i = 0; i < priv->hw_params.max_txq_num; i++) { + + /* TFD circular buffer read/write indexes */ + iwl_legacy_write_prph(priv, IWL49_SCD_QUEUE_RDPTR(i), 0); + iwl_legacy_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8)); + + /* Max Tx Window size for Scheduler-ACK mode */ + iwl_legacy_write_targ_mem(priv, priv->scd_base_addr + + IWL49_SCD_CONTEXT_QUEUE_OFFSET(i), + (SCD_WIN_SIZE << + IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) & + IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK); + + /* Frame limit */ + iwl_legacy_write_targ_mem(priv, priv->scd_base_addr + + IWL49_SCD_CONTEXT_QUEUE_OFFSET(i) + + sizeof(u32), + (SCD_FRAME_LIMIT << + IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & + IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK); + + } + iwl_legacy_write_prph(priv, IWL49_SCD_INTERRUPT_MASK, + (1 << priv->hw_params.max_txq_num) - 1); + + /* Activate all Tx DMA/FIFO channels */ + iwl4965_txq_set_sched(priv, IWL_MASK(0, 6)); + + iwl4965_set_wr_ptrs(priv, IWL_DEFAULT_CMD_QUEUE_NUM, 0); + + /* make sure all queue are not stopped */ + memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); + for (i = 0; i < 4; i++) + atomic_set(&priv->queue_stop_count[i], 0); + + /* reset to 0 to enable all the queue first */ + priv->txq_ctx_active_msk = 0; + /* Map each Tx/cmd queue to its corresponding fifo */ + BUILD_BUG_ON(ARRAY_SIZE(default_queue_to_tx_fifo) != 7); + + for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) { + int ac = default_queue_to_tx_fifo[i]; + + iwl_txq_ctx_activate(priv, i); + + if (ac == IWL_TX_FIFO_UNUSED) + continue; + + iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0); + } + + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + +/** + * iwl4965_alive_start - called after REPLY_ALIVE notification received + * from protocol/runtime uCode (initialization uCode's + * Alive gets handled by iwl_init_alive_start()). + */ +static void iwl4965_alive_start(struct iwl_priv *priv) +{ + int ret = 0; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); + + if (priv->card_alive.is_valid != UCODE_VALID_OK) { + /* We had an error bringing up the hardware, so take it + * all the way back down so we can try again */ + IWL_DEBUG_INFO(priv, "Alive failed.\n"); + goto restart; + } + + /* Initialize uCode has loaded Runtime uCode ... verify inst image. + * This is a paranoid check, because we would not have gotten the + * "runtime" alive if code weren't properly loaded. */ + if (iwl4965_verify_ucode(priv)) { + /* Runtime instruction load was bad; + * take it all the way back down so we can try again */ + IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n"); + goto restart; + } + + ret = iwl4965_alive_notify(priv); + if (ret) { + IWL_WARN(priv, + "Could not complete ALIVE transition [ntf]: %d\n", ret); + goto restart; + } + + + /* After the ALIVE response, we can send host commands to the uCode */ + set_bit(STATUS_ALIVE, &priv->status); + + /* Enable watchdog to monitor the driver tx queues */ + iwl_legacy_setup_watchdog(priv); + + if (iwl_legacy_is_rfkill(priv)) + return; + + ieee80211_wake_queues(priv->hw); + + priv->active_rate = IWL_RATES_MASK; + + if (iwl_legacy_is_associated_ctx(ctx)) { + struct iwl_legacy_rxon_cmd *active_rxon = + (struct iwl_legacy_rxon_cmd *)&ctx->active; + /* apply any changes in staging */ + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; + } else { + struct iwl_rxon_context *tmp; + /* Initialize our rx_config data */ + for_each_context(priv, tmp) + iwl_legacy_connection_init_rx_config(priv, tmp); + + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + } + + /* Configure bluetooth coexistence if enabled */ + iwl_legacy_send_bt_config(priv); + + iwl4965_reset_run_time_calib(priv); + + set_bit(STATUS_READY, &priv->status); + + /* Configure the adapter for unassociated operation */ + iwl_legacy_commit_rxon(priv, ctx); + + /* At this point, the NIC is initialized and operational */ + iwl4965_rf_kill_ct_config(priv); + + IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); + wake_up_interruptible(&priv->wait_command_queue); + + iwl_legacy_power_update_mode(priv, true); + IWL_DEBUG_INFO(priv, "Updated power mode\n"); + + return; + + restart: + queue_work(priv->workqueue, &priv->restart); +} + +static void iwl4965_cancel_deferred_work(struct iwl_priv *priv); + +static void __iwl4965_down(struct iwl_priv *priv) +{ + unsigned long flags; + int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status); + + IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); + + iwl_legacy_scan_cancel_timeout(priv, 200); + + exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); + + /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set + * to prevent rearm timer */ + del_timer_sync(&priv->watchdog); + + iwl_legacy_clear_ucode_stations(priv, NULL); + iwl_legacy_dealloc_bcast_stations(priv); + iwl_legacy_clear_driver_stations(priv); + + /* Unblock any waiting calls */ + wake_up_interruptible_all(&priv->wait_command_queue); + + /* Wipe out the EXIT_PENDING status bit if we are not actually + * exiting the module */ + if (!exit_pending) + clear_bit(STATUS_EXIT_PENDING, &priv->status); + + /* stop and reset the on-board processor */ + iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); + + /* tell the device to stop sending interrupts */ + spin_lock_irqsave(&priv->lock, flags); + iwl_legacy_disable_interrupts(priv); + spin_unlock_irqrestore(&priv->lock, flags); + iwl4965_synchronize_irq(priv); + + if (priv->mac80211_registered) + ieee80211_stop_queues(priv->hw); + + /* If we have not previously called iwl_init() then + * clear all bits but the RF Kill bit and return */ + if (!iwl_legacy_is_init(priv)) { + priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << + STATUS_RF_KILL_HW | + test_bit(STATUS_GEO_CONFIGURED, &priv->status) << + STATUS_GEO_CONFIGURED | + test_bit(STATUS_EXIT_PENDING, &priv->status) << + STATUS_EXIT_PENDING; + goto exit; + } + + /* ...otherwise clear out all the status bits but the RF Kill + * bit and continue taking the NIC down. */ + priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << + STATUS_RF_KILL_HW | + test_bit(STATUS_GEO_CONFIGURED, &priv->status) << + STATUS_GEO_CONFIGURED | + test_bit(STATUS_FW_ERROR, &priv->status) << + STATUS_FW_ERROR | + test_bit(STATUS_EXIT_PENDING, &priv->status) << + STATUS_EXIT_PENDING; + + iwl4965_txq_ctx_stop(priv); + iwl4965_rxq_stop(priv); + + /* Power-down device's busmaster DMA clocks */ + iwl_legacy_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); + udelay(5); + + /* Make sure (redundant) we've released our request to stay awake */ + iwl_legacy_clear_bit(priv, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + + /* Stop the device, and put it in low power state */ + iwl_legacy_apm_stop(priv); + + exit: + memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); + + dev_kfree_skb(priv->beacon_skb); + priv->beacon_skb = NULL; + + /* clear out any free frames */ + iwl4965_clear_free_frames(priv); +} + +static void iwl4965_down(struct iwl_priv *priv) +{ + mutex_lock(&priv->mutex); + __iwl4965_down(priv); + mutex_unlock(&priv->mutex); + + iwl4965_cancel_deferred_work(priv); +} + +#define HW_READY_TIMEOUT (50) + +static int iwl4965_set_hw_ready(struct iwl_priv *priv) +{ + int ret = 0; + + iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_NIC_READY); + + /* See if we got it */ + ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, + CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, + HW_READY_TIMEOUT); + if (ret != -ETIMEDOUT) + priv->hw_ready = true; + else + priv->hw_ready = false; + + IWL_DEBUG_INFO(priv, "hardware %s\n", + (priv->hw_ready == 1) ? "ready" : "not ready"); + return ret; +} + +static int iwl4965_prepare_card_hw(struct iwl_priv *priv) +{ + int ret = 0; + + IWL_DEBUG_INFO(priv, "iwl4965_prepare_card_hw enter\n"); + + ret = iwl4965_set_hw_ready(priv); + if (priv->hw_ready) + return ret; + + /* If HW is not ready, prepare the conditions to check again */ + iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_PREPARE); + + ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG, + ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, + CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000); + + /* HW should be ready by now, check again. */ + if (ret != -ETIMEDOUT) + iwl4965_set_hw_ready(priv); + + return ret; +} + +#define MAX_HW_RESTARTS 5 + +static int __iwl4965_up(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx; + int i; + int ret; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { + IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); + return -EIO; + } + + if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { + IWL_ERR(priv, "ucode not available for device bringup\n"); + return -EIO; + } + + for_each_context(priv, ctx) { + ret = iwl4965_alloc_bcast_station(priv, ctx); + if (ret) { + iwl_legacy_dealloc_bcast_stations(priv); + return ret; + } + } + + iwl4965_prepare_card_hw(priv); + + if (!priv->hw_ready) { + IWL_WARN(priv, "Exit HW not ready\n"); + return -EIO; + } + + /* If platform's RF_KILL switch is NOT set to KILL */ + if (iwl_read32(priv, + CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) + clear_bit(STATUS_RF_KILL_HW, &priv->status); + else + set_bit(STATUS_RF_KILL_HW, &priv->status); + + if (iwl_legacy_is_rfkill(priv)) { + wiphy_rfkill_set_hw_state(priv->hw->wiphy, true); + + iwl_legacy_enable_interrupts(priv); + IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n"); + return 0; + } + + iwl_write32(priv, CSR_INT, 0xFFFFFFFF); + + /* must be initialised before iwl_hw_nic_init */ + priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; + + ret = iwl4965_hw_nic_init(priv); + if (ret) { + IWL_ERR(priv, "Unable to init nic\n"); + return ret; + } + + /* make sure rfkill handshake bits are cleared */ + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, + CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); + + /* clear (again), then enable host interrupts */ + iwl_write32(priv, CSR_INT, 0xFFFFFFFF); + iwl_legacy_enable_interrupts(priv); + + /* really make sure rfkill handshake bits are cleared */ + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + + /* Copy original ucode data image from disk into backup cache. + * This will be used to initialize the on-board processor's + * data SRAM for a clean start when the runtime program first loads. */ + memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr, + priv->ucode_data.len); + + for (i = 0; i < MAX_HW_RESTARTS; i++) { + + /* load bootstrap state machine, + * load bootstrap program into processor's memory, + * prepare to load the "initialize" uCode */ + ret = priv->cfg->ops->lib->load_ucode(priv); + + if (ret) { + IWL_ERR(priv, "Unable to set up bootstrap uCode: %d\n", + ret); + continue; + } + + /* start card; "initialize" will load runtime ucode */ + iwl4965_nic_start(priv); + + IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n"); + + return 0; + } + + set_bit(STATUS_EXIT_PENDING, &priv->status); + __iwl4965_down(priv); + clear_bit(STATUS_EXIT_PENDING, &priv->status); + + /* tried to restart and config the device for as long as our + * patience could withstand */ + IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i); + return -EIO; +} + + +/***************************************************************************** + * + * Workqueue callbacks + * + *****************************************************************************/ + +static void iwl4965_bg_init_alive_start(struct work_struct *data) +{ + struct iwl_priv *priv = + container_of(data, struct iwl_priv, init_alive_start.work); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + priv->cfg->ops->lib->init_alive_start(priv); + mutex_unlock(&priv->mutex); +} + +static void iwl4965_bg_alive_start(struct work_struct *data) +{ + struct iwl_priv *priv = + container_of(data, struct iwl_priv, alive_start.work); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + iwl4965_alive_start(priv); + mutex_unlock(&priv->mutex); +} + +static void iwl4965_bg_run_time_calib_work(struct work_struct *work) +{ + struct iwl_priv *priv = container_of(work, struct iwl_priv, + run_time_calib_work); + + mutex_lock(&priv->mutex); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status) || + test_bit(STATUS_SCANNING, &priv->status)) { + mutex_unlock(&priv->mutex); + return; + } + + if (priv->start_calib) { + iwl4965_chain_noise_calibration(priv, + (void *)&priv->_4965.statistics); + iwl4965_sensitivity_calibration(priv, + (void *)&priv->_4965.statistics); + } + + mutex_unlock(&priv->mutex); +} + +static void iwl4965_bg_restart(struct work_struct *data) +{ + struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { + struct iwl_rxon_context *ctx; + + mutex_lock(&priv->mutex); + for_each_context(priv, ctx) + ctx->vif = NULL; + priv->is_open = 0; + + __iwl4965_down(priv); + + mutex_unlock(&priv->mutex); + iwl4965_cancel_deferred_work(priv); + ieee80211_restart_hw(priv->hw); + } else { + iwl4965_down(priv); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + __iwl4965_up(priv); + mutex_unlock(&priv->mutex); + } +} + +static void iwl4965_bg_rx_replenish(struct work_struct *data) +{ + struct iwl_priv *priv = + container_of(data, struct iwl_priv, rx_replenish); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + iwl4965_rx_replenish(priv); + mutex_unlock(&priv->mutex); +} + +/***************************************************************************** + * + * mac80211 entry point functions + * + *****************************************************************************/ + +#define UCODE_READY_TIMEOUT (4 * HZ) + +/* + * Not a mac80211 entry point function, but it fits in with all the + * other mac80211 functions grouped here. + */ +static int iwl4965_mac_setup_register(struct iwl_priv *priv, + u32 max_probe_length) +{ + int ret; + struct ieee80211_hw *hw = priv->hw; + struct iwl_rxon_context *ctx; + + hw->rate_control_algorithm = "iwl-4965-rs"; + + /* Tell mac80211 our characteristics */ + hw->flags = IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_AMPDU_AGGREGATION | + IEEE80211_HW_NEED_DTIM_PERIOD | + IEEE80211_HW_SPECTRUM_MGMT | + IEEE80211_HW_REPORTS_TX_ACK_STATUS; + + if (priv->cfg->sku & IWL_SKU_N) + hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | + IEEE80211_HW_SUPPORTS_STATIC_SMPS; + + hw->sta_data_size = sizeof(struct iwl_station_priv); + hw->vif_data_size = sizeof(struct iwl_vif_priv); + + for_each_context(priv, ctx) { + hw->wiphy->interface_modes |= ctx->interface_modes; + hw->wiphy->interface_modes |= ctx->exclusive_interface_modes; + } + + hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | + WIPHY_FLAG_DISABLE_BEACON_HINTS; + + /* + * For now, disable PS by default because it affects + * RX performance significantly. + */ + hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + + hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; + /* we create the 802.11 header and a zero-length SSID element */ + hw->wiphy->max_scan_ie_len = max_probe_length - 24 - 2; + + /* Default value; 4 EDCA QOS priorities */ + hw->queues = 4; + + hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; + + if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) + priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = + &priv->bands[IEEE80211_BAND_2GHZ]; + if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) + priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = + &priv->bands[IEEE80211_BAND_5GHZ]; + + iwl_legacy_leds_init(priv); + + ret = ieee80211_register_hw(priv->hw); + if (ret) { + IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); + return ret; + } + priv->mac80211_registered = 1; + + return 0; +} + + +int iwl4965_mac_start(struct ieee80211_hw *hw) +{ + struct iwl_priv *priv = hw->priv; + int ret; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + /* we should be verifying the device is ready to be opened */ + mutex_lock(&priv->mutex); + ret = __iwl4965_up(priv); + mutex_unlock(&priv->mutex); + + if (ret) + return ret; + + if (iwl_legacy_is_rfkill(priv)) + goto out; + + IWL_DEBUG_INFO(priv, "Start UP work done.\n"); + + /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from + * mac80211 will not be run successfully. */ + ret = wait_event_interruptible_timeout(priv->wait_command_queue, + test_bit(STATUS_READY, &priv->status), + UCODE_READY_TIMEOUT); + if (!ret) { + if (!test_bit(STATUS_READY, &priv->status)) { + IWL_ERR(priv, "START_ALIVE timeout after %dms.\n", + jiffies_to_msecs(UCODE_READY_TIMEOUT)); + return -ETIMEDOUT; + } + } + + iwl4965_led_enable(priv); + +out: + priv->is_open = 1; + IWL_DEBUG_MAC80211(priv, "leave\n"); + return 0; +} + +void iwl4965_mac_stop(struct ieee80211_hw *hw) +{ + struct iwl_priv *priv = hw->priv; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + if (!priv->is_open) + return; + + priv->is_open = 0; + + iwl4965_down(priv); + + flush_workqueue(priv->workqueue); + + /* enable interrupts again in order to receive rfkill changes */ + iwl_write32(priv, CSR_INT, 0xFFFFFFFF); + iwl_legacy_enable_interrupts(priv); + + IWL_DEBUG_MAC80211(priv, "leave\n"); +} + +int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct iwl_priv *priv = hw->priv; + + IWL_DEBUG_MACDUMP(priv, "enter\n"); + + IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, + ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); + + if (iwl4965_tx_skb(priv, skb)) + dev_kfree_skb_any(skb); + + IWL_DEBUG_MACDUMP(priv, "leave\n"); + return NETDEV_TX_OK; +} + +void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_key_conf *keyconf, + struct ieee80211_sta *sta, + u32 iv32, u16 *phase1key) +{ + struct iwl_priv *priv = hw->priv; + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + iwl4965_update_tkip_key(priv, vif_priv->ctx, keyconf, sta, + iv32, phase1key); + + IWL_DEBUG_MAC80211(priv, "leave\n"); +} + +int iwl4965_mac_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 iwl_priv *priv = hw->priv; + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; + struct iwl_rxon_context *ctx = vif_priv->ctx; + int ret; + u8 sta_id; + bool is_default_wep_key = false; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + if (priv->cfg->mod_params->sw_crypto) { + IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n"); + return -EOPNOTSUPP; + } + + sta_id = iwl_legacy_sta_id_or_broadcast(priv, vif_priv->ctx, sta); + if (sta_id == IWL_INVALID_STATION) + return -EINVAL; + + mutex_lock(&priv->mutex); + iwl_legacy_scan_cancel_timeout(priv, 100); + + /* + * If we are getting WEP group key and we didn't receive any key mapping + * so far, we are in legacy wep mode (group key only), otherwise we are + * in 1X mode. + * In legacy wep mode, we use another host command to the uCode. + */ + if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || + key->cipher == WLAN_CIPHER_SUITE_WEP104) && + !sta) { + if (cmd == SET_KEY) + is_default_wep_key = !ctx->key_mapping_keys; + else + is_default_wep_key = + (key->hw_key_idx == HW_KEY_DEFAULT); + } + + switch (cmd) { + case SET_KEY: + if (is_default_wep_key) + ret = iwl4965_set_default_wep_key(priv, + vif_priv->ctx, key); + else + ret = iwl4965_set_dynamic_key(priv, vif_priv->ctx, + key, sta_id); + + IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n"); + break; + case DISABLE_KEY: + if (is_default_wep_key) + ret = iwl4965_remove_default_wep_key(priv, ctx, key); + else + ret = iwl4965_remove_dynamic_key(priv, ctx, + key, sta_id); + + IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n"); + break; + default: + ret = -EINVAL; + } + + mutex_unlock(&priv->mutex); + IWL_DEBUG_MAC80211(priv, "leave\n"); + + return ret; +} + +int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum ieee80211_ampdu_mlme_action action, + struct ieee80211_sta *sta, u16 tid, u16 *ssn, + u8 buf_size) +{ + struct iwl_priv *priv = hw->priv; + int ret = -EINVAL; + + IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", + sta->addr, tid); + + if (!(priv->cfg->sku & IWL_SKU_N)) + return -EACCES; + + mutex_lock(&priv->mutex); + + switch (action) { + case IEEE80211_AMPDU_RX_START: + IWL_DEBUG_HT(priv, "start Rx\n"); + ret = iwl4965_sta_rx_agg_start(priv, sta, tid, *ssn); + break; + case IEEE80211_AMPDU_RX_STOP: + IWL_DEBUG_HT(priv, "stop Rx\n"); + ret = iwl4965_sta_rx_agg_stop(priv, sta, tid); + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + ret = 0; + break; + case IEEE80211_AMPDU_TX_START: + IWL_DEBUG_HT(priv, "start Tx\n"); + ret = iwl4965_tx_agg_start(priv, vif, sta, tid, ssn); + if (ret == 0) { + priv->_4965.agg_tids_count++; + IWL_DEBUG_HT(priv, "priv->_4965.agg_tids_count = %u\n", + priv->_4965.agg_tids_count); + } + break; + case IEEE80211_AMPDU_TX_STOP: + IWL_DEBUG_HT(priv, "stop Tx\n"); + ret = iwl4965_tx_agg_stop(priv, vif, sta, tid); + if ((ret == 0) && (priv->_4965.agg_tids_count > 0)) { + priv->_4965.agg_tids_count--; + IWL_DEBUG_HT(priv, "priv->_4965.agg_tids_count = %u\n", + priv->_4965.agg_tids_count); + } + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + ret = 0; + break; + case IEEE80211_AMPDU_TX_OPERATIONAL: + ret = 0; + break; + } + mutex_unlock(&priv->mutex); + + return ret; +} + +int iwl4965_mac_sta_add(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct iwl_priv *priv = hw->priv; + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; + bool is_ap = vif->type == NL80211_IFTYPE_STATION; + int ret; + u8 sta_id; + + IWL_DEBUG_INFO(priv, "received request to add station %pM\n", + sta->addr); + mutex_lock(&priv->mutex); + IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", + sta->addr); + sta_priv->common.sta_id = IWL_INVALID_STATION; + + atomic_set(&sta_priv->pending_frames, 0); + + ret = iwl_legacy_add_station_common(priv, vif_priv->ctx, sta->addr, + is_ap, sta, &sta_id); + if (ret) { + IWL_ERR(priv, "Unable to add station %pM (%d)\n", + sta->addr, ret); + /* Should we return success if return code is EEXIST ? */ + mutex_unlock(&priv->mutex); + return ret; + } + + sta_priv->common.sta_id = sta_id; + + /* Initialize rate scaling */ + IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", + sta->addr); + iwl4965_rs_rate_init(priv, sta, sta_id); + mutex_unlock(&priv->mutex); + + return 0; +} + +void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, + struct ieee80211_channel_switch *ch_switch) +{ + struct iwl_priv *priv = hw->priv; + const struct iwl_channel_info *ch_info; + struct ieee80211_conf *conf = &hw->conf; + struct ieee80211_channel *channel = ch_switch->channel; + struct iwl_ht_config *ht_conf = &priv->current_ht_config; + + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + u16 ch; + unsigned long flags = 0; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + if (iwl_legacy_is_rfkill(priv)) + goto out_exit; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status) || + test_bit(STATUS_SCANNING, &priv->status)) + goto out_exit; + + if (!iwl_legacy_is_associated_ctx(ctx)) + goto out_exit; + + /* channel switch in progress */ + if (priv->switch_rxon.switch_in_progress == true) + goto out_exit; + + mutex_lock(&priv->mutex); + if (priv->cfg->ops->lib->set_channel_switch) { + + ch = channel->hw_value; + if (le16_to_cpu(ctx->active.channel) != ch) { + ch_info = iwl_legacy_get_channel_info(priv, + channel->band, + ch); + if (!iwl_legacy_is_channel_valid(ch_info)) { + IWL_DEBUG_MAC80211(priv, "invalid channel\n"); + goto out; + } + spin_lock_irqsave(&priv->lock, flags); + + priv->current_ht_config.smps = conf->smps_mode; + + /* Configure HT40 channels */ + ctx->ht.enabled = conf_is_ht(conf); + if (ctx->ht.enabled) { + if (conf_is_ht40_minus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_BELOW; + ctx->ht.is_40mhz = true; + } else if (conf_is_ht40_plus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + ctx->ht.is_40mhz = true; + } else { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_NONE; + ctx->ht.is_40mhz = false; + } + } else + ctx->ht.is_40mhz = false; + + if ((le16_to_cpu(ctx->staging.channel) != ch)) + ctx->staging.flags = 0; + + iwl_legacy_set_rxon_channel(priv, channel, ctx); + iwl_legacy_set_rxon_ht(priv, ht_conf); + iwl_legacy_set_flags_for_band(priv, ctx, channel->band, + ctx->vif); + spin_unlock_irqrestore(&priv->lock, flags); + + iwl_legacy_set_rate(priv); + /* + * at this point, staging_rxon has the + * configuration for channel switch + */ + if (priv->cfg->ops->lib->set_channel_switch(priv, + ch_switch)) + priv->switch_rxon.switch_in_progress = false; + } + } +out: + mutex_unlock(&priv->mutex); +out_exit: + if (!priv->switch_rxon.switch_in_progress) + ieee80211_chswitch_done(ctx->vif, false); + IWL_DEBUG_MAC80211(priv, "leave\n"); +} + +void iwl4965_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *total_flags, + u64 multicast) +{ + struct iwl_priv *priv = hw->priv; + __le32 filter_or = 0, filter_nand = 0; + struct iwl_rxon_context *ctx; + +#define CHK(test, flag) do { \ + if (*total_flags & (test)) \ + filter_or |= (flag); \ + else \ + filter_nand |= (flag); \ + } while (0) + + IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n", + changed_flags, *total_flags); + + CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); + /* Setting _just_ RXON_FILTER_CTL2HOST_MSK causes FH errors */ + CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_PROMISC_MSK); + CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); + +#undef CHK + + mutex_lock(&priv->mutex); + + for_each_context(priv, ctx) { + ctx->staging.filter_flags &= ~filter_nand; + ctx->staging.filter_flags |= filter_or; + + /* + * Not committing directly because hardware can perform a scan, + * but we'll eventually commit the filter flags change anyway. + */ + } + + mutex_unlock(&priv->mutex); + + /* + * Receiving all multicast frames is always enabled by the + * default flags setup in iwl_legacy_connection_init_rx_config() + * since we currently do not support programming multicast + * filters into the device. + */ + *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | + FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; +} + +/***************************************************************************** + * + * driver setup and teardown + * + *****************************************************************************/ + +static void iwl4965_bg_txpower_work(struct work_struct *work) +{ + struct iwl_priv *priv = container_of(work, struct iwl_priv, + txpower_work); + + /* If a scan happened to start before we got here + * then just return; the statistics notification will + * kick off another scheduled work to compensate for + * any temperature delta we missed here. */ + if (test_bit(STATUS_EXIT_PENDING, &priv->status) || + test_bit(STATUS_SCANNING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + + /* Regardless of if we are associated, we must reconfigure the + * TX power since frames can be sent on non-radar channels while + * not associated */ + priv->cfg->ops->lib->send_tx_power(priv); + + /* Update last_temperature to keep is_calib_needed from running + * when it isn't needed... */ + priv->last_temperature = priv->temperature; + + mutex_unlock(&priv->mutex); +} + +static void iwl4965_setup_deferred_work(struct iwl_priv *priv) +{ + priv->workqueue = create_singlethread_workqueue(DRV_NAME); + + init_waitqueue_head(&priv->wait_command_queue); + + INIT_WORK(&priv->restart, iwl4965_bg_restart); + INIT_WORK(&priv->rx_replenish, iwl4965_bg_rx_replenish); + INIT_WORK(&priv->run_time_calib_work, iwl4965_bg_run_time_calib_work); + INIT_DELAYED_WORK(&priv->init_alive_start, iwl4965_bg_init_alive_start); + INIT_DELAYED_WORK(&priv->alive_start, iwl4965_bg_alive_start); + + iwl_legacy_setup_scan_deferred_work(priv); + + INIT_WORK(&priv->txpower_work, iwl4965_bg_txpower_work); + + init_timer(&priv->statistics_periodic); + priv->statistics_periodic.data = (unsigned long)priv; + priv->statistics_periodic.function = iwl4965_bg_statistics_periodic; + + init_timer(&priv->ucode_trace); + priv->ucode_trace.data = (unsigned long)priv; + priv->ucode_trace.function = iwl4965_bg_ucode_trace; + + init_timer(&priv->watchdog); + priv->watchdog.data = (unsigned long)priv; + priv->watchdog.function = iwl_legacy_bg_watchdog; + + tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) + iwl4965_irq_tasklet, (unsigned long)priv); +} + +static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) +{ + cancel_work_sync(&priv->txpower_work); + cancel_delayed_work_sync(&priv->init_alive_start); + cancel_delayed_work(&priv->alive_start); + cancel_work_sync(&priv->run_time_calib_work); + + iwl_legacy_cancel_scan_deferred_work(priv); + + del_timer_sync(&priv->statistics_periodic); + del_timer_sync(&priv->ucode_trace); +} + +static void iwl4965_init_hw_rates(struct iwl_priv *priv, + struct ieee80211_rate *rates) +{ + int i; + + for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) { + rates[i].bitrate = iwl_rates[i].ieee * 5; + rates[i].hw_value = i; /* Rate scaling will work on indexes */ + rates[i].hw_value_short = i; + rates[i].flags = 0; + if ((i >= IWL_FIRST_CCK_RATE) && (i <= IWL_LAST_CCK_RATE)) { + /* + * If CCK != 1M then set short preamble rate flag. + */ + rates[i].flags |= + (iwl_rates[i].plcp == IWL_RATE_1M_PLCP) ? + 0 : IEEE80211_RATE_SHORT_PREAMBLE; + } + } +} +/* + * Acquire priv->lock before calling this function ! + */ +void iwl4965_set_wr_ptrs(struct iwl_priv *priv, int txq_id, u32 index) +{ + iwl_legacy_write_direct32(priv, HBUS_TARG_WRPTR, + (index & 0xff) | (txq_id << 8)); + iwl_legacy_write_prph(priv, IWL49_SCD_QUEUE_RDPTR(txq_id), index); +} + +void iwl4965_tx_queue_set_status(struct iwl_priv *priv, + struct iwl_tx_queue *txq, + int tx_fifo_id, int scd_retry) +{ + int txq_id = txq->q.id; + + /* Find out whether to activate Tx queue */ + int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0; + + /* Set up and activate */ + iwl_legacy_write_prph(priv, IWL49_SCD_QUEUE_STATUS_BITS(txq_id), + (active << IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE) | + (tx_fifo_id << IWL49_SCD_QUEUE_STTS_REG_POS_TXF) | + (scd_retry << IWL49_SCD_QUEUE_STTS_REG_POS_WSL) | + (scd_retry << IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACK) | + IWL49_SCD_QUEUE_STTS_REG_MSK); + + txq->sched_retry = scd_retry; + + IWL_DEBUG_INFO(priv, "%s %s Queue %d on AC %d\n", + active ? "Activate" : "Deactivate", + scd_retry ? "BA" : "AC", txq_id, tx_fifo_id); +} + + +static int iwl4965_init_drv(struct iwl_priv *priv) +{ + int ret; + + spin_lock_init(&priv->sta_lock); + spin_lock_init(&priv->hcmd_lock); + + INIT_LIST_HEAD(&priv->free_frames); + + mutex_init(&priv->mutex); + mutex_init(&priv->sync_cmd_mutex); + + priv->ieee_channels = NULL; + priv->ieee_rates = NULL; + priv->band = IEEE80211_BAND_2GHZ; + + priv->iw_mode = NL80211_IFTYPE_STATION; + priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; + priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; + priv->_4965.agg_tids_count = 0; + + /* initialize force reset */ + priv->force_reset[IWL_RF_RESET].reset_duration = + IWL_DELAY_NEXT_FORCE_RF_RESET; + priv->force_reset[IWL_FW_RESET].reset_duration = + IWL_DELAY_NEXT_FORCE_FW_RELOAD; + + /* Choose which receivers/antennas to use */ + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); + + iwl_legacy_init_scan_params(priv); + + /* Set the tx_power_user_lmt to the lowest power level + * this value will get overwritten by channel max power avg + * from eeprom */ + priv->tx_power_user_lmt = IWL4965_TX_POWER_TARGET_POWER_MIN; + priv->tx_power_next = IWL4965_TX_POWER_TARGET_POWER_MIN; + + ret = iwl_legacy_init_channel_map(priv); + if (ret) { + IWL_ERR(priv, "initializing regulatory failed: %d\n", ret); + goto err; + } + + ret = iwl_legacy_init_geos(priv); + if (ret) { + IWL_ERR(priv, "initializing geos failed: %d\n", ret); + goto err_free_channel_map; + } + iwl4965_init_hw_rates(priv, priv->ieee_rates); + + return 0; + +err_free_channel_map: + iwl_legacy_free_channel_map(priv); +err: + return ret; +} + +static void iwl4965_uninit_drv(struct iwl_priv *priv) +{ + iwl4965_calib_free_results(priv); + iwl_legacy_free_geos(priv); + iwl_legacy_free_channel_map(priv); + kfree(priv->scan_cmd); +} + +static void iwl4965_hw_detect(struct iwl_priv *priv) +{ + priv->hw_rev = _iwl_legacy_read32(priv, CSR_HW_REV); + priv->hw_wa_rev = _iwl_legacy_read32(priv, CSR_HW_REV_WA_REG); + pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &priv->rev_id); + IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id); +} + +static int iwl4965_set_hw_params(struct iwl_priv *priv) +{ + priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; + priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; + if (priv->cfg->mod_params->amsdu_size_8K) + priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_8K); + else + priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_4K); + + priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL; + + if (priv->cfg->mod_params->disable_11n) + priv->cfg->sku &= ~IWL_SKU_N; + + /* Device-specific setup */ + return priv->cfg->ops->lib->set_hw_params(priv); +} + +static const u8 iwl4965_bss_ac_to_fifo[] = { + IWL_TX_FIFO_VO, + IWL_TX_FIFO_VI, + IWL_TX_FIFO_BE, + IWL_TX_FIFO_BK, +}; + +static const u8 iwl4965_bss_ac_to_queue[] = { + 0, 1, 2, 3, +}; + +static int +iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int err = 0, i; + struct iwl_priv *priv; + struct ieee80211_hw *hw; + struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); + unsigned long flags; + u16 pci_cmd; + + /************************ + * 1. Allocating HW data + ************************/ + + hw = iwl_legacy_alloc_all(cfg); + if (!hw) { + err = -ENOMEM; + goto out; + } + priv = hw->priv; + /* At this point both hw and priv are allocated. */ + + /* + * The default context is always valid, + * more may be discovered when firmware + * is loaded. + */ + priv->valid_contexts = BIT(IWL_RXON_CTX_BSS); + + for (i = 0; i < NUM_IWL_RXON_CTX; i++) + priv->contexts[i].ctxid = i; + + priv->contexts[IWL_RXON_CTX_BSS].always_active = true; + priv->contexts[IWL_RXON_CTX_BSS].is_active = true; + priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON; + priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING; + priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; + priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; + priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; + priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; + priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwl4965_bss_ac_to_fifo; + priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwl4965_bss_ac_to_queue; + priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes = + BIT(NL80211_IFTYPE_ADHOC); + priv->contexts[IWL_RXON_CTX_BSS].interface_modes = + BIT(NL80211_IFTYPE_STATION); + priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP; + priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS; + priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS; + priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS; + + BUILD_BUG_ON(NUM_IWL_RXON_CTX != 1); + + SET_IEEE80211_DEV(hw, &pdev->dev); + + IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); + priv->cfg = cfg; + priv->pci_dev = pdev; + priv->inta_mask = CSR_INI_SET_MASK; + + if (iwl_legacy_alloc_traffic_mem(priv)) + IWL_ERR(priv, "Not enough memory to generate traffic log\n"); + + /************************** + * 2. Initializing PCI bus + **************************/ + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | + PCIE_LINK_STATE_CLKPM); + + if (pci_enable_device(pdev)) { + err = -ENODEV; + goto out_ieee80211_free_hw; + } + + pci_set_master(pdev); + + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); + if (!err) + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36)); + if (err) { + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (!err) + err = pci_set_consistent_dma_mask(pdev, + DMA_BIT_MASK(32)); + /* both attempts failed: */ + if (err) { + IWL_WARN(priv, "No suitable DMA available.\n"); + goto out_pci_disable_device; + } + } + + err = pci_request_regions(pdev, DRV_NAME); + if (err) + goto out_pci_disable_device; + + pci_set_drvdata(pdev, priv); + + + /*********************** + * 3. Read REV register + ***********************/ + priv->hw_base = pci_iomap(pdev, 0, 0); + if (!priv->hw_base) { + err = -ENODEV; + goto out_pci_release_regions; + } + + IWL_DEBUG_INFO(priv, "pci_resource_len = 0x%08llx\n", + (unsigned long long) pci_resource_len(pdev, 0)); + IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base); + + /* these spin locks will be used in apm_ops.init and EEPROM access + * we should init now + */ + spin_lock_init(&priv->reg_lock); + spin_lock_init(&priv->lock); + + /* + * stop and reset the on-board processor just in case it is in a + * strange state ... like being left stranded by a primary kernel + * and this is now the kdump kernel trying to start up + */ + iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); + + iwl4965_hw_detect(priv); + IWL_INFO(priv, "Detected %s, REV=0x%X\n", + priv->cfg->name, priv->hw_rev); + + /* We disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state */ + pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); + + iwl4965_prepare_card_hw(priv); + if (!priv->hw_ready) { + IWL_WARN(priv, "Failed, HW not ready\n"); + goto out_iounmap; + } + + /***************** + * 4. Read EEPROM + *****************/ + /* Read the EEPROM */ + err = iwl_legacy_eeprom_init(priv); + if (err) { + IWL_ERR(priv, "Unable to init EEPROM\n"); + goto out_iounmap; + } + err = iwl4965_eeprom_check_version(priv); + if (err) + goto out_free_eeprom; + + if (err) + goto out_free_eeprom; + + /* extract MAC Address */ + iwl4965_eeprom_get_mac(priv, priv->addresses[0].addr); + IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr); + priv->hw->wiphy->addresses = priv->addresses; + priv->hw->wiphy->n_addresses = 1; + + /************************ + * 5. Setup HW constants + ************************/ + if (iwl4965_set_hw_params(priv)) { + IWL_ERR(priv, "failed to set hw parameters\n"); + goto out_free_eeprom; + } + + /******************* + * 6. Setup priv + *******************/ + + err = iwl4965_init_drv(priv); + if (err) + goto out_free_eeprom; + /* At this point both hw and priv are initialized. */ + + /******************** + * 7. Setup services + ********************/ + spin_lock_irqsave(&priv->lock, flags); + iwl_legacy_disable_interrupts(priv); + spin_unlock_irqrestore(&priv->lock, flags); + + pci_enable_msi(priv->pci_dev); + + err = request_irq(priv->pci_dev->irq, iwl_legacy_isr, + IRQF_SHARED, DRV_NAME, priv); + if (err) { + IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); + goto out_disable_msi; + } + + iwl4965_setup_deferred_work(priv); + iwl4965_setup_rx_handlers(priv); + + /********************************************* + * 8. Enable interrupts and read RFKILL state + *********************************************/ + + /* enable interrupts if needed: hw bug w/a */ + pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); + if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { + pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; + pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd); + } + + iwl_legacy_enable_interrupts(priv); + + /* If platform's RF_KILL switch is NOT set to KILL */ + if (iwl_read32(priv, CSR_GP_CNTRL) & + CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) + clear_bit(STATUS_RF_KILL_HW, &priv->status); + else + set_bit(STATUS_RF_KILL_HW, &priv->status); + + wiphy_rfkill_set_hw_state(priv->hw->wiphy, + test_bit(STATUS_RF_KILL_HW, &priv->status)); + + iwl_legacy_power_initialize(priv); + + init_completion(&priv->_4965.firmware_loading_complete); + + err = iwl4965_request_firmware(priv, true); + if (err) + goto out_destroy_workqueue; + + return 0; + + out_destroy_workqueue: + destroy_workqueue(priv->workqueue); + priv->workqueue = NULL; + free_irq(priv->pci_dev->irq, priv); + out_disable_msi: + pci_disable_msi(priv->pci_dev); + iwl4965_uninit_drv(priv); + out_free_eeprom: + iwl_legacy_eeprom_free(priv); + out_iounmap: + pci_iounmap(pdev, priv->hw_base); + out_pci_release_regions: + pci_set_drvdata(pdev, NULL); + pci_release_regions(pdev); + out_pci_disable_device: + pci_disable_device(pdev); + out_ieee80211_free_hw: + iwl_legacy_free_traffic_mem(priv); + ieee80211_free_hw(priv->hw); + out: + return err; +} + +static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) +{ + struct iwl_priv *priv = pci_get_drvdata(pdev); + unsigned long flags; + + if (!priv) + return; + + wait_for_completion(&priv->_4965.firmware_loading_complete); + + IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); + + iwl_legacy_dbgfs_unregister(priv); + sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group); + + /* ieee80211_unregister_hw call wil cause iwl_mac_stop to + * to be called and iwl4965_down since we are removing the device + * we need to set STATUS_EXIT_PENDING bit. + */ + set_bit(STATUS_EXIT_PENDING, &priv->status); + + iwl_legacy_leds_exit(priv); + + if (priv->mac80211_registered) { + ieee80211_unregister_hw(priv->hw); + priv->mac80211_registered = 0; + } else { + iwl4965_down(priv); + } + + /* + * Make sure device is reset to low power before unloading driver. + * This may be redundant with iwl4965_down(), but there are paths to + * run iwl4965_down() without calling apm_ops.stop(), and there are + * paths to avoid running iwl4965_down() at all before leaving driver. + * This (inexpensive) call *makes sure* device is reset. + */ + iwl_legacy_apm_stop(priv); + + /* make sure we flush any pending irq or + * tasklet for the driver + */ + spin_lock_irqsave(&priv->lock, flags); + iwl_legacy_disable_interrupts(priv); + spin_unlock_irqrestore(&priv->lock, flags); + + iwl4965_synchronize_irq(priv); + + iwl4965_dealloc_ucode_pci(priv); + + if (priv->rxq.bd) + iwl4965_rx_queue_free(priv, &priv->rxq); + iwl4965_hw_txq_ctx_free(priv); + + iwl_legacy_eeprom_free(priv); + + + /*netif_stop_queue(dev); */ + flush_workqueue(priv->workqueue); + + /* ieee80211_unregister_hw calls iwl_mac_stop, which flushes + * priv->workqueue... so we can't take down the workqueue + * until now... */ + destroy_workqueue(priv->workqueue); + priv->workqueue = NULL; + iwl_legacy_free_traffic_mem(priv); + + free_irq(priv->pci_dev->irq, priv); + pci_disable_msi(priv->pci_dev); + pci_iounmap(pdev, priv->hw_base); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + + iwl4965_uninit_drv(priv); + + dev_kfree_skb(priv->beacon_skb); + + ieee80211_free_hw(priv->hw); +} + +/* + * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask + * must be called under priv->lock and mac access + */ +void iwl4965_txq_set_sched(struct iwl_priv *priv, u32 mask) +{ + iwl_legacy_write_prph(priv, IWL49_SCD_TXFACT, mask); +} + +/***************************************************************************** + * + * driver and module entry point + * + *****************************************************************************/ + +/* Hardware specific file defines the PCI IDs table for that hardware module */ +static DEFINE_PCI_DEVICE_TABLE(iwl4965_hw_card_ids) = { +#if defined(CONFIG_IWL4965_MODULE) || defined(CONFIG_IWL4965) + {IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_cfg)}, + {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_cfg)}, +#endif /* CONFIG_IWL4965 */ + + {0} +}; +MODULE_DEVICE_TABLE(pci, iwl4965_hw_card_ids); + +static struct pci_driver iwl4965_driver = { + .name = DRV_NAME, + .id_table = iwl4965_hw_card_ids, + .probe = iwl4965_pci_probe, + .remove = __devexit_p(iwl4965_pci_remove), + .driver.pm = IWL_LEGACY_PM_OPS, +}; + +static int __init iwl4965_init(void) +{ + + int ret; + pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); + pr_info(DRV_COPYRIGHT "\n"); + + ret = iwl4965_rate_control_register(); + if (ret) { + pr_err("Unable to register rate control algorithm: %d\n", ret); + return ret; + } + + ret = pci_register_driver(&iwl4965_driver); + if (ret) { + pr_err("Unable to initialize PCI module\n"); + goto error_register; + } + + return ret; + +error_register: + iwl4965_rate_control_unregister(); + return ret; +} + +static void __exit iwl4965_exit(void) +{ + pci_unregister_driver(&iwl4965_driver); + iwl4965_rate_control_unregister(); +} + +module_exit(iwl4965_exit); +module_init(iwl4965_init); + +#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG +module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "debug output mask"); +#endif + +module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, S_IRUGO); +MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); +module_param_named(queues_num, iwl4965_mod_params.num_of_queues, int, S_IRUGO); +MODULE_PARM_DESC(queues_num, "number of hw queues."); +module_param_named(11n_disable, iwl4965_mod_params.disable_11n, int, S_IRUGO); +MODULE_PARM_DESC(11n_disable, "disable 11n functionality"); +module_param_named(amsdu_size_8K, iwl4965_mod_params.amsdu_size_8K, + int, S_IRUGO); +MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); +module_param_named(fw_restart, iwl4965_mod_params.restart_fw, int, S_IRUGO); +MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index e1e3b1cf3cff..17d555f2215a 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -1,18 +1,52 @@ -config IWLWIFI - tristate "Intel Wireless Wifi" +config IWLAGN + tristate "Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlagn) " depends on PCI && MAC80211 select FW_LOADER select NEW_LEDS select LEDS_CLASS select LEDS_TRIGGERS select MAC80211_LEDS + ---help--- + Select to build the driver supporting the: + + Intel Wireless WiFi Link Next-Gen AGN + + This option enables support for use with the following hardware: + Intel Wireless WiFi Link 6250AGN Adapter + Intel 6000 Series Wi-Fi Adapters (6200AGN and 6300AGN) + Intel WiFi Link 1000BGN + Intel Wireless WiFi 5150AGN + Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN + Intel 6005 Series Wi-Fi Adapters + Intel 6030 Series Wi-Fi Adapters + Intel Wireless WiFi Link 6150BGN 2 Adapter + Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN) + Intel 2000 Series Wi-Fi Adapters + + + This driver uses the kernel's mac80211 subsystem. + + In order to use this driver, you will need a microcode (uCode) + image for it. You can obtain the microcode from: + + . + + The microcode is typically installed in /lib/firmware. You can + look in the hotplug script /etc/hotplug/firmware.agent to + determine which directory FIRMWARE_DIR is set to when the script + runs. + + If you want to compile the driver as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read . The + module will be called iwlagn. menu "Debugging Options" - depends on IWLWIFI + depends on IWLAGN config IWLWIFI_DEBUG - bool "Enable full debugging output in iwlagn and iwl3945 drivers" - depends on IWLWIFI + bool "Enable full debugging output in the iwlagn driver" + depends on IWLAGN ---help--- This option will enable debug tracing output for the iwlwifi drivers @@ -37,7 +71,7 @@ config IWLWIFI_DEBUG config IWLWIFI_DEBUGFS bool "iwlagn debugfs support" - depends on IWLWIFI && MAC80211_DEBUGFS + depends on IWLAGN && MAC80211_DEBUGFS ---help--- Enable creation of debugfs files for the iwlwifi drivers. This is a low-impact option that allows getting insight into the @@ -45,13 +79,13 @@ config IWLWIFI_DEBUGFS config IWLWIFI_DEBUG_EXPERIMENTAL_UCODE bool "Experimental uCode support" - depends on IWLWIFI && IWLWIFI_DEBUG + depends on IWLAGN && IWLWIFI_DEBUG ---help--- Enable use of experimental ucode for testing and debugging. config IWLWIFI_DEVICE_TRACING bool "iwlwifi device access tracing" - depends on IWLWIFI + depends on IWLAGN depends on EVENT_TRACING help Say Y here to trace all commands, including TX frames and IO @@ -68,57 +102,9 @@ config IWLWIFI_DEVICE_TRACING occur. endmenu -config IWLAGN - tristate "Intel Wireless WiFi Next Gen AGN (iwlagn)" - depends on IWLWIFI - ---help--- - Select to build the driver supporting the: - - Intel Wireless WiFi Link Next-Gen AGN - - This driver uses the kernel's mac80211 subsystem. - - In order to use this driver, you will need a microcode (uCode) - image for it. You can obtain the microcode from: - - . - - The microcode is typically installed in /lib/firmware. You can - look in the hotplug script /etc/hotplug/firmware.agent to - determine which directory FIRMWARE_DIR is set to when the script - runs. - - If you want to compile the driver as a module ( = code which can be - inserted in and removed from the running kernel whenever you want), - say M here and read . The - module will be called iwlagn. - - -config IWL4965 - bool "Intel Wireless WiFi 4965AGN" - depends on IWLAGN - ---help--- - This option enables support for Intel Wireless WiFi Link 4965AGN - -config IWL5000 - bool "Intel Wireless-N/Advanced-N/Ultimate-N WiFi Link" - depends on IWLAGN - ---help--- - This option enables support for use with the following hardware: - Intel Wireless WiFi Link 6250AGN Adapter - Intel 6000 Series Wi-Fi Adapters (6200AGN and 6300AGN) - Intel WiFi Link 1000BGN - Intel Wireless WiFi 5150AGN - Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN - Intel 6005 Series Wi-Fi Adapters - Intel 6030 Series Wi-Fi Adapters - Intel Wireless WiFi Link 6150BGN 2 Adapter - Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN) - Intel 2000 Series Wi-Fi Adapters - config IWL_P2P bool "iwlwifi experimental P2P support" - depends on IWL5000 + depends on IWLAGN help This option enables experimental P2P support for some devices based on microcode support. Since P2P support is still under @@ -132,27 +118,3 @@ config IWL_P2P Say Y only if you want to experiment with P2P. -config IWL3945 - tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)" - depends on IWLWIFI - ---help--- - Select to build the driver supporting the: - - Intel PRO/Wireless 3945ABG/BG Network Connection - - This driver uses the kernel's mac80211 subsystem. - - In order to use this driver, you will need a microcode (uCode) - image for it. You can obtain the microcode from: - - . - - The microcode is typically installed in /lib/firmware. You can - look in the hotplug script /etc/hotplug/firmware.agent to - determine which directory FIRMWARE_DIR is set to when the script - runs. - - If you want to compile the driver as a module ( = code which can be - inserted in and removed from the running kernel whenever you want), - say M here and read . The - module will be called iwl3945. diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 25be742c69c9..aab7d15bd5ed 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -1,36 +1,23 @@ -obj-$(CONFIG_IWLWIFI) += iwlcore.o -iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o -iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o -iwlcore-objs += iwl-scan.o iwl-led.o -iwlcore-$(CONFIG_IWL3945) += iwl-legacy.o -iwlcore-$(CONFIG_IWL4965) += iwl-legacy.o -iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o -iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o - -# If 3945 is selected only, iwl-legacy.o will be added -# to iwlcore-m above, but it needs to be built in. -iwlcore-objs += $(iwlcore-m) - -CFLAGS_iwl-devtrace.o := -I$(src) - # AGN obj-$(CONFIG_IWLAGN) += iwlagn.o iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o -iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o -iwlagn-$(CONFIG_IWL4965) += iwl-4965.o -iwlagn-$(CONFIG_IWL5000) += iwl-agn-rxon.o iwl-agn-hcmd.o iwl-agn-ict.o -iwlagn-$(CONFIG_IWL5000) += iwl-5000.o -iwlagn-$(CONFIG_IWL5000) += iwl-6000.o -iwlagn-$(CONFIG_IWL5000) += iwl-1000.o -iwlagn-$(CONFIG_IWL5000) += iwl-2000.o +iwlagn-objs += iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o +iwlagn-objs += iwl-rx.o iwl-tx.o iwl-sta.o +iwlagn-objs += iwl-scan.o iwl-led.o +iwlagn-objs += iwl-agn-rxon.o iwl-agn-hcmd.o iwl-agn-ict.o +iwlagn-objs += iwl-5000.o +iwlagn-objs += iwl-6000.o +iwlagn-objs += iwl-1000.o +iwlagn-objs += iwl-2000.o + +iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o +iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o +iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o -# 3945 -obj-$(CONFIG_IWL3945) += iwl3945.o -iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o -iwl3945-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-3945-debugfs.o +CFLAGS_iwl-devtrace.o := -I$(src) ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c deleted file mode 100644 index ef0835b01b6b..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c +++ /dev/null @@ -1,522 +0,0 @@ -/****************************************************************************** - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - *****************************************************************************/ - -#include "iwl-3945-debugfs.h" - - -static int iwl3945_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) -{ - int p = 0; - - p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", - le32_to_cpu(priv->_3945.statistics.flag)); - if (le32_to_cpu(priv->_3945.statistics.flag) & - UCODE_STATISTICS_CLEAR_MSK) - p += scnprintf(buf + p, bufsz - p, - "\tStatistics have been cleared\n"); - p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n", - (le32_to_cpu(priv->_3945.statistics.flag) & - UCODE_STATISTICS_FREQUENCY_MSK) - ? "2.4 GHz" : "5.2 GHz"); - p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n", - (le32_to_cpu(priv->_3945.statistics.flag) & - UCODE_STATISTICS_NARROW_BAND_MSK) - ? "enabled" : "disabled"); - return p; -} - -ssize_t iwl3945_ucode_rx_stats_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_priv *priv = file->private_data; - int pos = 0; - char *buf; - int bufsz = sizeof(struct iwl39_statistics_rx_phy) * 40 + - sizeof(struct iwl39_statistics_rx_non_phy) * 40 + 400; - ssize_t ret; - struct iwl39_statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm; - struct iwl39_statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck; - struct iwl39_statistics_rx_non_phy *general, *accum_general; - struct iwl39_statistics_rx_non_phy *delta_general, *max_general; - - if (!iwl_is_alive(priv)) - return -EAGAIN; - - buf = kzalloc(bufsz, GFP_KERNEL); - if (!buf) { - IWL_ERR(priv, "Can not allocate Buffer\n"); - return -ENOMEM; - } - - /* - * The statistic information display here is based on - * the last statistics notification from uCode - * might not reflect the current uCode activity - */ - ofdm = &priv->_3945.statistics.rx.ofdm; - cck = &priv->_3945.statistics.rx.cck; - general = &priv->_3945.statistics.rx.general; - accum_ofdm = &priv->_3945.accum_statistics.rx.ofdm; - accum_cck = &priv->_3945.accum_statistics.rx.cck; - accum_general = &priv->_3945.accum_statistics.rx.general; - delta_ofdm = &priv->_3945.delta_statistics.rx.ofdm; - delta_cck = &priv->_3945.delta_statistics.rx.cck; - delta_general = &priv->_3945.delta_statistics.rx.general; - max_ofdm = &priv->_3945.max_delta.rx.ofdm; - max_cck = &priv->_3945.max_delta.rx.cck; - max_general = &priv->_3945.max_delta.rx.general; - - pos += iwl3945_statistics_flag(priv, buf, bufsz); - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_Rx - OFDM:"); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "ina_cnt:", le32_to_cpu(ofdm->ina_cnt), - accum_ofdm->ina_cnt, - delta_ofdm->ina_cnt, max_ofdm->ina_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_cnt:", - le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt, - delta_ofdm->fina_cnt, max_ofdm->fina_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "plcp_err:", - le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err, - delta_ofdm->plcp_err, max_ofdm->plcp_err); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "crc32_err:", - le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err, - delta_ofdm->crc32_err, max_ofdm->crc32_err); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "overrun_err:", - le32_to_cpu(ofdm->overrun_err), - accum_ofdm->overrun_err, delta_ofdm->overrun_err, - max_ofdm->overrun_err); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "early_overrun_err:", - le32_to_cpu(ofdm->early_overrun_err), - accum_ofdm->early_overrun_err, - delta_ofdm->early_overrun_err, - max_ofdm->early_overrun_err); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "crc32_good:", le32_to_cpu(ofdm->crc32_good), - accum_ofdm->crc32_good, delta_ofdm->crc32_good, - max_ofdm->crc32_good); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "false_alarm_cnt:", - le32_to_cpu(ofdm->false_alarm_cnt), - accum_ofdm->false_alarm_cnt, - delta_ofdm->false_alarm_cnt, - max_ofdm->false_alarm_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_sync_err_cnt:", - le32_to_cpu(ofdm->fina_sync_err_cnt), - accum_ofdm->fina_sync_err_cnt, - delta_ofdm->fina_sync_err_cnt, - max_ofdm->fina_sync_err_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sfd_timeout:", - le32_to_cpu(ofdm->sfd_timeout), - accum_ofdm->sfd_timeout, - delta_ofdm->sfd_timeout, - max_ofdm->sfd_timeout); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_timeout:", - le32_to_cpu(ofdm->fina_timeout), - accum_ofdm->fina_timeout, - delta_ofdm->fina_timeout, - max_ofdm->fina_timeout); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "unresponded_rts:", - le32_to_cpu(ofdm->unresponded_rts), - accum_ofdm->unresponded_rts, - delta_ofdm->unresponded_rts, - max_ofdm->unresponded_rts); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "rxe_frame_lmt_ovrun:", - le32_to_cpu(ofdm->rxe_frame_limit_overrun), - accum_ofdm->rxe_frame_limit_overrun, - delta_ofdm->rxe_frame_limit_overrun, - max_ofdm->rxe_frame_limit_overrun); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sent_ack_cnt:", - le32_to_cpu(ofdm->sent_ack_cnt), - accum_ofdm->sent_ack_cnt, - delta_ofdm->sent_ack_cnt, - max_ofdm->sent_ack_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sent_cts_cnt:", - le32_to_cpu(ofdm->sent_cts_cnt), - accum_ofdm->sent_cts_cnt, - delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt); - - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_Rx - CCK:"); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "ina_cnt:", - le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt, - delta_cck->ina_cnt, max_cck->ina_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_cnt:", - le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt, - delta_cck->fina_cnt, max_cck->fina_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "plcp_err:", - le32_to_cpu(cck->plcp_err), accum_cck->plcp_err, - delta_cck->plcp_err, max_cck->plcp_err); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "crc32_err:", - le32_to_cpu(cck->crc32_err), accum_cck->crc32_err, - delta_cck->crc32_err, max_cck->crc32_err); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "overrun_err:", - le32_to_cpu(cck->overrun_err), - accum_cck->overrun_err, - delta_cck->overrun_err, max_cck->overrun_err); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "early_overrun_err:", - le32_to_cpu(cck->early_overrun_err), - accum_cck->early_overrun_err, - delta_cck->early_overrun_err, - max_cck->early_overrun_err); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "crc32_good:", - le32_to_cpu(cck->crc32_good), accum_cck->crc32_good, - delta_cck->crc32_good, - max_cck->crc32_good); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "false_alarm_cnt:", - le32_to_cpu(cck->false_alarm_cnt), - accum_cck->false_alarm_cnt, - delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_sync_err_cnt:", - le32_to_cpu(cck->fina_sync_err_cnt), - accum_cck->fina_sync_err_cnt, - delta_cck->fina_sync_err_cnt, - max_cck->fina_sync_err_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sfd_timeout:", - le32_to_cpu(cck->sfd_timeout), - accum_cck->sfd_timeout, - delta_cck->sfd_timeout, max_cck->sfd_timeout); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_timeout:", - le32_to_cpu(cck->fina_timeout), - accum_cck->fina_timeout, - delta_cck->fina_timeout, max_cck->fina_timeout); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "unresponded_rts:", - le32_to_cpu(cck->unresponded_rts), - accum_cck->unresponded_rts, - delta_cck->unresponded_rts, - max_cck->unresponded_rts); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "rxe_frame_lmt_ovrun:", - le32_to_cpu(cck->rxe_frame_limit_overrun), - accum_cck->rxe_frame_limit_overrun, - delta_cck->rxe_frame_limit_overrun, - max_cck->rxe_frame_limit_overrun); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sent_ack_cnt:", - le32_to_cpu(cck->sent_ack_cnt), - accum_cck->sent_ack_cnt, - delta_cck->sent_ack_cnt, - max_cck->sent_ack_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sent_cts_cnt:", - le32_to_cpu(cck->sent_cts_cnt), - accum_cck->sent_cts_cnt, - delta_cck->sent_cts_cnt, - max_cck->sent_cts_cnt); - - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_Rx - GENERAL:"); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "bogus_cts:", - le32_to_cpu(general->bogus_cts), - accum_general->bogus_cts, - delta_general->bogus_cts, max_general->bogus_cts); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "bogus_ack:", - le32_to_cpu(general->bogus_ack), - accum_general->bogus_ack, - delta_general->bogus_ack, max_general->bogus_ack); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "non_bssid_frames:", - le32_to_cpu(general->non_bssid_frames), - accum_general->non_bssid_frames, - delta_general->non_bssid_frames, - max_general->non_bssid_frames); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "filtered_frames:", - le32_to_cpu(general->filtered_frames), - accum_general->filtered_frames, - delta_general->filtered_frames, - max_general->filtered_frames); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "non_channel_beacons:", - le32_to_cpu(general->non_channel_beacons), - accum_general->non_channel_beacons, - delta_general->non_channel_beacons, - max_general->non_channel_beacons); - - ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); - kfree(buf); - return ret; -} - -ssize_t iwl3945_ucode_tx_stats_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_priv *priv = file->private_data; - int pos = 0; - char *buf; - int bufsz = (sizeof(struct iwl39_statistics_tx) * 48) + 250; - ssize_t ret; - struct iwl39_statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; - - if (!iwl_is_alive(priv)) - return -EAGAIN; - - buf = kzalloc(bufsz, GFP_KERNEL); - if (!buf) { - IWL_ERR(priv, "Can not allocate Buffer\n"); - return -ENOMEM; - } - - /* - * The statistic information display here is based on - * the last statistics notification from uCode - * might not reflect the current uCode activity - */ - tx = &priv->_3945.statistics.tx; - accum_tx = &priv->_3945.accum_statistics.tx; - delta_tx = &priv->_3945.delta_statistics.tx; - max_tx = &priv->_3945.max_delta.tx; - pos += iwl3945_statistics_flag(priv, buf, bufsz); - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_Tx:"); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "preamble:", - le32_to_cpu(tx->preamble_cnt), - accum_tx->preamble_cnt, - delta_tx->preamble_cnt, max_tx->preamble_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "rx_detected_cnt:", - le32_to_cpu(tx->rx_detected_cnt), - accum_tx->rx_detected_cnt, - delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "bt_prio_defer_cnt:", - le32_to_cpu(tx->bt_prio_defer_cnt), - accum_tx->bt_prio_defer_cnt, - delta_tx->bt_prio_defer_cnt, - max_tx->bt_prio_defer_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "bt_prio_kill_cnt:", - le32_to_cpu(tx->bt_prio_kill_cnt), - accum_tx->bt_prio_kill_cnt, - delta_tx->bt_prio_kill_cnt, - max_tx->bt_prio_kill_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "few_bytes_cnt:", - le32_to_cpu(tx->few_bytes_cnt), - accum_tx->few_bytes_cnt, - delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "cts_timeout:", - le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout, - delta_tx->cts_timeout, max_tx->cts_timeout); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "ack_timeout:", - le32_to_cpu(tx->ack_timeout), - accum_tx->ack_timeout, - delta_tx->ack_timeout, max_tx->ack_timeout); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "expected_ack_cnt:", - le32_to_cpu(tx->expected_ack_cnt), - accum_tx->expected_ack_cnt, - delta_tx->expected_ack_cnt, - max_tx->expected_ack_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "actual_ack_cnt:", - le32_to_cpu(tx->actual_ack_cnt), - accum_tx->actual_ack_cnt, - delta_tx->actual_ack_cnt, - max_tx->actual_ack_cnt); - - ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); - kfree(buf); - return ret; -} - -ssize_t iwl3945_ucode_general_stats_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_priv *priv = file->private_data; - int pos = 0; - char *buf; - int bufsz = sizeof(struct iwl39_statistics_general) * 10 + 300; - ssize_t ret; - struct iwl39_statistics_general *general, *accum_general; - struct iwl39_statistics_general *delta_general, *max_general; - struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; - struct iwl39_statistics_div *div, *accum_div, *delta_div, *max_div; - - if (!iwl_is_alive(priv)) - return -EAGAIN; - - buf = kzalloc(bufsz, GFP_KERNEL); - if (!buf) { - IWL_ERR(priv, "Can not allocate Buffer\n"); - return -ENOMEM; - } - - /* - * The statistic information display here is based on - * the last statistics notification from uCode - * might not reflect the current uCode activity - */ - general = &priv->_3945.statistics.general; - dbg = &priv->_3945.statistics.general.dbg; - div = &priv->_3945.statistics.general.div; - accum_general = &priv->_3945.accum_statistics.general; - delta_general = &priv->_3945.delta_statistics.general; - max_general = &priv->_3945.max_delta.general; - accum_dbg = &priv->_3945.accum_statistics.general.dbg; - delta_dbg = &priv->_3945.delta_statistics.general.dbg; - max_dbg = &priv->_3945.max_delta.general.dbg; - accum_div = &priv->_3945.accum_statistics.general.div; - delta_div = &priv->_3945.delta_statistics.general.div; - max_div = &priv->_3945.max_delta.general.div; - pos += iwl3945_statistics_flag(priv, buf, bufsz); - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_General:"); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "burst_check:", - le32_to_cpu(dbg->burst_check), - accum_dbg->burst_check, - delta_dbg->burst_check, max_dbg->burst_check); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "burst_count:", - le32_to_cpu(dbg->burst_count), - accum_dbg->burst_count, - delta_dbg->burst_count, max_dbg->burst_count); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sleep_time:", - le32_to_cpu(general->sleep_time), - accum_general->sleep_time, - delta_general->sleep_time, max_general->sleep_time); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "slots_out:", - le32_to_cpu(general->slots_out), - accum_general->slots_out, - delta_general->slots_out, max_general->slots_out); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "slots_idle:", - le32_to_cpu(general->slots_idle), - accum_general->slots_idle, - delta_general->slots_idle, max_general->slots_idle); - pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n", - le32_to_cpu(general->ttl_timestamp)); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "tx_on_a:", - le32_to_cpu(div->tx_on_a), accum_div->tx_on_a, - delta_div->tx_on_a, max_div->tx_on_a); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "tx_on_b:", - le32_to_cpu(div->tx_on_b), accum_div->tx_on_b, - delta_div->tx_on_b, max_div->tx_on_b); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "exec_time:", - le32_to_cpu(div->exec_time), accum_div->exec_time, - delta_div->exec_time, max_div->exec_time); - pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "probe_time:", - le32_to_cpu(div->probe_time), accum_div->probe_time, - delta_div->probe_time, max_div->probe_time); - ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); - kfree(buf); - return ret; -} diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h deleted file mode 100644 index 70809c53c215..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.h +++ /dev/null @@ -1,60 +0,0 @@ -/****************************************************************************** - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - *****************************************************************************/ - -#include "iwl-dev.h" -#include "iwl-core.h" -#include "iwl-debug.h" - -#ifdef CONFIG_IWLWIFI_DEBUGFS -ssize_t iwl3945_ucode_rx_stats_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos); -ssize_t iwl3945_ucode_tx_stats_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos); -ssize_t iwl3945_ucode_general_stats_read(struct file *file, - char __user *user_buf, size_t count, - loff_t *ppos); -#else -static ssize_t iwl3945_ucode_rx_stats_read(struct file *file, - char __user *user_buf, size_t count, - loff_t *ppos) -{ - return 0; -} -static ssize_t iwl3945_ucode_tx_stats_read(struct file *file, - char __user *user_buf, size_t count, - loff_t *ppos) -{ - return 0; -} -static ssize_t iwl3945_ucode_general_stats_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - return 0; -} -#endif diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-fh.h b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h deleted file mode 100644 index 2c9ed2b502a3..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945-fh.h +++ /dev/null @@ -1,188 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ -#ifndef __iwl_3945_fh_h__ -#define __iwl_3945_fh_h__ - -/************************************/ -/* iwl3945 Flow Handler Definitions */ -/************************************/ - -/** - * This I/O area is directly read/writable by driver (e.g. Linux uses writel()) - * Addresses are offsets from device's PCI hardware base address. - */ -#define FH39_MEM_LOWER_BOUND (0x0800) -#define FH39_MEM_UPPER_BOUND (0x1000) - -#define FH39_CBCC_TABLE (FH39_MEM_LOWER_BOUND + 0x140) -#define FH39_TFDB_TABLE (FH39_MEM_LOWER_BOUND + 0x180) -#define FH39_RCSR_TABLE (FH39_MEM_LOWER_BOUND + 0x400) -#define FH39_RSSR_TABLE (FH39_MEM_LOWER_BOUND + 0x4c0) -#define FH39_TCSR_TABLE (FH39_MEM_LOWER_BOUND + 0x500) -#define FH39_TSSR_TABLE (FH39_MEM_LOWER_BOUND + 0x680) - -/* TFDB (Transmit Frame Buffer Descriptor) */ -#define FH39_TFDB(_ch, buf) (FH39_TFDB_TABLE + \ - ((_ch) * 2 + (buf)) * 0x28) -#define FH39_TFDB_CHNL_BUF_CTRL_REG(_ch) (FH39_TFDB_TABLE + 0x50 * (_ch)) - -/* CBCC channel is [0,2] */ -#define FH39_CBCC(_ch) (FH39_CBCC_TABLE + (_ch) * 0x8) -#define FH39_CBCC_CTRL(_ch) (FH39_CBCC(_ch) + 0x00) -#define FH39_CBCC_BASE(_ch) (FH39_CBCC(_ch) + 0x04) - -/* RCSR channel is [0,2] */ -#define FH39_RCSR(_ch) (FH39_RCSR_TABLE + (_ch) * 0x40) -#define FH39_RCSR_CONFIG(_ch) (FH39_RCSR(_ch) + 0x00) -#define FH39_RCSR_RBD_BASE(_ch) (FH39_RCSR(_ch) + 0x04) -#define FH39_RCSR_WPTR(_ch) (FH39_RCSR(_ch) + 0x20) -#define FH39_RCSR_RPTR_ADDR(_ch) (FH39_RCSR(_ch) + 0x24) - -#define FH39_RSCSR_CHNL0_WPTR (FH39_RCSR_WPTR(0)) - -/* RSSR */ -#define FH39_RSSR_CTRL (FH39_RSSR_TABLE + 0x000) -#define FH39_RSSR_STATUS (FH39_RSSR_TABLE + 0x004) - -/* TCSR */ -#define FH39_TCSR(_ch) (FH39_TCSR_TABLE + (_ch) * 0x20) -#define FH39_TCSR_CONFIG(_ch) (FH39_TCSR(_ch) + 0x00) -#define FH39_TCSR_CREDIT(_ch) (FH39_TCSR(_ch) + 0x04) -#define FH39_TCSR_BUFF_STTS(_ch) (FH39_TCSR(_ch) + 0x08) - -/* TSSR */ -#define FH39_TSSR_CBB_BASE (FH39_TSSR_TABLE + 0x000) -#define FH39_TSSR_MSG_CONFIG (FH39_TSSR_TABLE + 0x008) -#define FH39_TSSR_TX_STATUS (FH39_TSSR_TABLE + 0x010) - - -/* DBM */ - -#define FH39_SRVC_CHNL (6) - -#define FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE (20) -#define FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH (4) - -#define FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN (0x08000000) - -#define FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE (0x80000000) - -#define FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE (0x20000000) - -#define FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 (0x01000000) - -#define FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST (0x00001000) - -#define FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH (0x00000000) - -#define FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF (0x00000000) -#define FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER (0x00000001) - -#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000) -#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008) - -#define FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD (0x00200000) - -#define FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT (0x00000000) - -#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000) -#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000) - -#define FH39_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID (0x00004000) - -#define FH39_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR (0x00000001) - -#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON (0xFF000000) -#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON (0x00FF0000) - -#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B (0x00000400) - -#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON (0x00000100) -#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON (0x00000080) - -#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH (0x00000020) -#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH (0x00000005) - -#define FH39_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_ch) (BIT(_ch) << 24) -#define FH39_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_ch) (BIT(_ch) << 16) - -#define FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_ch) \ - (FH39_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_ch) | \ - FH39_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_ch)) - -#define FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000) - -struct iwl3945_tfd_tb { - __le32 addr; - __le32 len; -} __packed; - -struct iwl3945_tfd { - __le32 control_flags; - struct iwl3945_tfd_tb tbs[4]; - u8 __pad[28]; -} __packed; - - -#endif /* __iwl_3945_fh_h__ */ - diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h deleted file mode 100644 index 65b5834da28c..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h +++ /dev/null @@ -1,294 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ -/* - * Please use this file (iwl-3945-hw.h) only for hardware-related definitions. - * Please use iwl-commands.h for uCode API definitions. - * Please use iwl-3945.h for driver implementation definitions. - */ - -#ifndef __iwl_3945_hw__ -#define __iwl_3945_hw__ - -#include "iwl-eeprom.h" - -/* RSSI to dBm */ -#define IWL39_RSSI_OFFSET 95 - -#define IWL_DEFAULT_TX_POWER 0x0F - -/* - * EEPROM related constants, enums, and structures. - */ -#define EEPROM_SKU_CAP_OP_MODE_MRC (1 << 7) - -/* - * Mapping of a Tx power level, at factory calibration temperature, - * to a radio/DSP gain table index. - * One for each of 5 "sample" power levels in each band. - * v_det is measured at the factory, using the 3945's built-in power amplifier - * (PA) output voltage detector. This same detector is used during Tx of - * long packets in normal operation to provide feedback as to proper output - * level. - * Data copied from EEPROM. - * DO NOT ALTER THIS STRUCTURE!!! - */ -struct iwl3945_eeprom_txpower_sample { - u8 gain_index; /* index into power (gain) setup table ... */ - s8 power; /* ... for this pwr level for this chnl group */ - u16 v_det; /* PA output voltage */ -} __packed; - -/* - * Mappings of Tx power levels -> nominal radio/DSP gain table indexes. - * One for each channel group (a.k.a. "band") (1 for BG, 4 for A). - * Tx power setup code interpolates between the 5 "sample" power levels - * to determine the nominal setup for a requested power level. - * Data copied from EEPROM. - * DO NOT ALTER THIS STRUCTURE!!! - */ -struct iwl3945_eeprom_txpower_group { - struct iwl3945_eeprom_txpower_sample samples[5]; /* 5 power levels */ - s32 a, b, c, d, e; /* coefficients for voltage->power - * formula (signed) */ - s32 Fa, Fb, Fc, Fd, Fe; /* these modify coeffs based on - * frequency (signed) */ - s8 saturation_power; /* highest power possible by h/w in this - * band */ - u8 group_channel; /* "representative" channel # in this band */ - s16 temperature; /* h/w temperature at factory calib this band - * (signed) */ -} __packed; - -/* - * Temperature-based Tx-power compensation data, not band-specific. - * These coefficients are use to modify a/b/c/d/e coeffs based on - * difference between current temperature and factory calib temperature. - * Data copied from EEPROM. - */ -struct iwl3945_eeprom_temperature_corr { - u32 Ta; - u32 Tb; - u32 Tc; - u32 Td; - u32 Te; -} __packed; - -/* - * EEPROM map - */ -struct iwl3945_eeprom { - u8 reserved0[16]; - u16 device_id; /* abs.ofs: 16 */ - u8 reserved1[2]; - u16 pmc; /* abs.ofs: 20 */ - u8 reserved2[20]; - u8 mac_address[6]; /* abs.ofs: 42 */ - u8 reserved3[58]; - u16 board_revision; /* abs.ofs: 106 */ - u8 reserved4[11]; - u8 board_pba_number[9]; /* abs.ofs: 119 */ - u8 reserved5[8]; - u16 version; /* abs.ofs: 136 */ - u8 sku_cap; /* abs.ofs: 138 */ - u8 leds_mode; /* abs.ofs: 139 */ - u16 oem_mode; - u16 wowlan_mode; /* abs.ofs: 142 */ - u16 leds_time_interval; /* abs.ofs: 144 */ - u8 leds_off_time; /* abs.ofs: 146 */ - u8 leds_on_time; /* abs.ofs: 147 */ - u8 almgor_m_version; /* abs.ofs: 148 */ - u8 antenna_switch_type; /* abs.ofs: 149 */ - u8 reserved6[42]; - u8 sku_id[4]; /* abs.ofs: 192 */ - -/* - * Per-channel regulatory data. - * - * Each channel that *might* be supported by 3945 or 4965 has a fixed location - * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory - * txpower (MSB). - * - * Entries immediately below are for 20 MHz channel width. HT40 (40 MHz) - * channels (only for 4965, not supported by 3945) appear later in the EEPROM. - * - * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 - */ - u16 band_1_count; /* abs.ofs: 196 */ - struct iwl_eeprom_channel band_1_channels[14]; /* abs.ofs: 198 */ - -/* - * 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196, - * 5.0 GHz channels 7, 8, 11, 12, 16 - * (4915-5080MHz) (none of these is ever supported) - */ - u16 band_2_count; /* abs.ofs: 226 */ - struct iwl_eeprom_channel band_2_channels[13]; /* abs.ofs: 228 */ - -/* - * 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 - * (5170-5320MHz) - */ - u16 band_3_count; /* abs.ofs: 254 */ - struct iwl_eeprom_channel band_3_channels[12]; /* abs.ofs: 256 */ - -/* - * 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 - * (5500-5700MHz) - */ - u16 band_4_count; /* abs.ofs: 280 */ - struct iwl_eeprom_channel band_4_channels[11]; /* abs.ofs: 282 */ - -/* - * 5.7 GHz channels 145, 149, 153, 157, 161, 165 - * (5725-5825MHz) - */ - u16 band_5_count; /* abs.ofs: 304 */ - struct iwl_eeprom_channel band_5_channels[6]; /* abs.ofs: 306 */ - - u8 reserved9[194]; - -/* - * 3945 Txpower calibration data. - */ -#define IWL_NUM_TX_CALIB_GROUPS 5 - struct iwl3945_eeprom_txpower_group groups[IWL_NUM_TX_CALIB_GROUPS]; -/* abs.ofs: 512 */ - struct iwl3945_eeprom_temperature_corr corrections; /* abs.ofs: 832 */ - u8 reserved16[172]; /* fill out to full 1024 byte block */ -} __packed; - -#define IWL3945_EEPROM_IMG_SIZE 1024 - -/* End of EEPROM */ - -#define PCI_CFG_REV_ID_BIT_BASIC_SKU (0x40) /* bit 6 */ -#define PCI_CFG_REV_ID_BIT_RTP (0x80) /* bit 7 */ - -/* 4 DATA + 1 CMD. There are 2 HCCA queues that are not used. */ -#define IWL39_NUM_QUEUES 5 -#define IWL39_CMD_QUEUE_NUM 4 - -#define IWL_DEFAULT_TX_RETRY 15 - -/*********************************************/ - -#define RFD_SIZE 4 -#define NUM_TFD_CHUNKS 4 - -#define RX_QUEUE_SIZE 256 -#define RX_QUEUE_MASK 255 -#define RX_QUEUE_SIZE_LOG 8 - -#define U32_PAD(n) ((4-(n))&0x3) - -#define TFD_CTL_COUNT_SET(n) (n << 24) -#define TFD_CTL_COUNT_GET(ctl) ((ctl >> 24) & 7) -#define TFD_CTL_PAD_SET(n) (n << 28) -#define TFD_CTL_PAD_GET(ctl) (ctl >> 28) - -/* Sizes and addresses for instruction and data memory (SRAM) in - * 3945's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ -#define IWL39_RTC_INST_LOWER_BOUND (0x000000) -#define IWL39_RTC_INST_UPPER_BOUND (0x014000) - -#define IWL39_RTC_DATA_LOWER_BOUND (0x800000) -#define IWL39_RTC_DATA_UPPER_BOUND (0x808000) - -#define IWL39_RTC_INST_SIZE (IWL39_RTC_INST_UPPER_BOUND - \ - IWL39_RTC_INST_LOWER_BOUND) -#define IWL39_RTC_DATA_SIZE (IWL39_RTC_DATA_UPPER_BOUND - \ - IWL39_RTC_DATA_LOWER_BOUND) - -#define IWL39_MAX_INST_SIZE IWL39_RTC_INST_SIZE -#define IWL39_MAX_DATA_SIZE IWL39_RTC_DATA_SIZE - -/* Size of uCode instruction memory in bootstrap state machine */ -#define IWL39_MAX_BSM_SIZE IWL39_RTC_INST_SIZE - -static inline int iwl3945_hw_valid_rtc_data_addr(u32 addr) -{ - return (addr >= IWL39_RTC_DATA_LOWER_BOUND) && - (addr < IWL39_RTC_DATA_UPPER_BOUND); -} - -/* Base physical address of iwl3945_shared is provided to FH_TSSR_CBB_BASE - * and &iwl3945_shared.rx_read_ptr[0] is provided to FH_RCSR_RPTR_ADDR(0) */ -struct iwl3945_shared { - __le32 tx_base_ptr[8]; -} __packed; - -static inline u8 iwl3945_hw_get_rate(__le16 rate_n_flags) -{ - return le16_to_cpu(rate_n_flags) & 0xFF; -} - -static inline u16 iwl3945_hw_get_rate_n_flags(__le16 rate_n_flags) -{ - return le16_to_cpu(rate_n_flags); -} - -static inline __le16 iwl3945_hw_set_rate_n_flags(u8 rate, u16 flags) -{ - return cpu_to_le16((u16)rate|flags); -} -#endif diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c deleted file mode 100644 index dc7c3a4167a9..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c +++ /dev/null @@ -1,64 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "iwl-commands.h" -#include "iwl-3945.h" -#include "iwl-core.h" -#include "iwl-dev.h" -#include "iwl-3945-led.h" - - -/* Send led command */ -static int iwl3945_send_led_cmd(struct iwl_priv *priv, - struct iwl_led_cmd *led_cmd) -{ - struct iwl_host_cmd cmd = { - .id = REPLY_LEDS_CMD, - .len = sizeof(struct iwl_led_cmd), - .data = led_cmd, - .flags = CMD_ASYNC, - .callback = NULL, - }; - - return iwl_send_cmd(priv, &cmd); -} - -const struct iwl_led_ops iwl3945_led_ops = { - .cmd = iwl3945_send_led_cmd, -}; diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.h b/drivers/net/wireless/iwlwifi/iwl-3945-led.h deleted file mode 100644 index ce990adc51e7..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945-led.h +++ /dev/null @@ -1,32 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#ifndef __iwl_3945_led_h__ -#define __iwl_3945_led_h__ - -extern const struct iwl_led_ops iwl3945_led_ops; - -#endif /* __iwl_3945_led_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c deleted file mode 100644 index 1f3e7e34fbc7..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ /dev/null @@ -1,995 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "iwl-commands.h" -#include "iwl-3945.h" -#include "iwl-sta.h" - -#define RS_NAME "iwl-3945-rs" - -static s32 iwl3945_expected_tpt_g[IWL_RATE_COUNT_3945] = { - 7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202 -}; - -static s32 iwl3945_expected_tpt_g_prot[IWL_RATE_COUNT_3945] = { - 7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125 -}; - -static s32 iwl3945_expected_tpt_a[IWL_RATE_COUNT_3945] = { - 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186 -}; - -static s32 iwl3945_expected_tpt_b[IWL_RATE_COUNT_3945] = { - 7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -struct iwl3945_tpt_entry { - s8 min_rssi; - u8 index; -}; - -static struct iwl3945_tpt_entry iwl3945_tpt_table_a[] = { - {-60, IWL_RATE_54M_INDEX}, - {-64, IWL_RATE_48M_INDEX}, - {-72, IWL_RATE_36M_INDEX}, - {-80, IWL_RATE_24M_INDEX}, - {-84, IWL_RATE_18M_INDEX}, - {-85, IWL_RATE_12M_INDEX}, - {-87, IWL_RATE_9M_INDEX}, - {-89, IWL_RATE_6M_INDEX} -}; - -static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = { - {-60, IWL_RATE_54M_INDEX}, - {-64, IWL_RATE_48M_INDEX}, - {-68, IWL_RATE_36M_INDEX}, - {-80, IWL_RATE_24M_INDEX}, - {-84, IWL_RATE_18M_INDEX}, - {-85, IWL_RATE_12M_INDEX}, - {-86, IWL_RATE_11M_INDEX}, - {-88, IWL_RATE_5M_INDEX}, - {-90, IWL_RATE_2M_INDEX}, - {-92, IWL_RATE_1M_INDEX} -}; - -#define IWL_RATE_MAX_WINDOW 62 -#define IWL_RATE_FLUSH (3*HZ) -#define IWL_RATE_WIN_FLUSH (HZ/2) -#define IWL39_RATE_HIGH_TH 11520 -#define IWL_SUCCESS_UP_TH 8960 -#define IWL_SUCCESS_DOWN_TH 10880 -#define IWL_RATE_MIN_FAILURE_TH 6 -#define IWL_RATE_MIN_SUCCESS_TH 8 -#define IWL_RATE_DECREASE_TH 1920 -#define IWL_RATE_RETRY_TH 15 - -static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, enum ieee80211_band band) -{ - u32 index = 0; - u32 table_size = 0; - struct iwl3945_tpt_entry *tpt_table = NULL; - - if ((rssi < IWL_MIN_RSSI_VAL) || (rssi > IWL_MAX_RSSI_VAL)) - rssi = IWL_MIN_RSSI_VAL; - - switch (band) { - case IEEE80211_BAND_2GHZ: - tpt_table = iwl3945_tpt_table_g; - table_size = ARRAY_SIZE(iwl3945_tpt_table_g); - break; - - case IEEE80211_BAND_5GHZ: - tpt_table = iwl3945_tpt_table_a; - table_size = ARRAY_SIZE(iwl3945_tpt_table_a); - break; - - default: - BUG(); - break; - } - - while ((index < table_size) && (rssi < tpt_table[index].min_rssi)) - index++; - - index = min(index, (table_size - 1)); - - return tpt_table[index].index; -} - -static void iwl3945_clear_window(struct iwl3945_rate_scale_data *window) -{ - window->data = 0; - window->success_counter = 0; - window->success_ratio = -1; - window->counter = 0; - window->average_tpt = IWL_INVALID_VALUE; - window->stamp = 0; -} - -/** - * iwl3945_rate_scale_flush_windows - flush out the rate scale windows - * - * Returns the number of windows that have gathered data but were - * not flushed. If there were any that were not flushed, then - * reschedule the rate flushing routine. - */ -static int iwl3945_rate_scale_flush_windows(struct iwl3945_rs_sta *rs_sta) -{ - int unflushed = 0; - int i; - unsigned long flags; - struct iwl_priv *priv __maybe_unused = rs_sta->priv; - - /* - * For each rate, if we have collected data on that rate - * and it has been more than IWL_RATE_WIN_FLUSH - * since we flushed, clear out the gathered statistics - */ - for (i = 0; i < IWL_RATE_COUNT_3945; i++) { - if (!rs_sta->win[i].counter) - continue; - - spin_lock_irqsave(&rs_sta->lock, flags); - if (time_after(jiffies, rs_sta->win[i].stamp + - IWL_RATE_WIN_FLUSH)) { - IWL_DEBUG_RATE(priv, "flushing %d samples of rate " - "index %d\n", - rs_sta->win[i].counter, i); - iwl3945_clear_window(&rs_sta->win[i]); - } else - unflushed++; - spin_unlock_irqrestore(&rs_sta->lock, flags); - } - - return unflushed; -} - -#define IWL_RATE_FLUSH_MAX 5000 /* msec */ -#define IWL_RATE_FLUSH_MIN 50 /* msec */ -#define IWL_AVERAGE_PACKETS 1500 - -static void iwl3945_bg_rate_scale_flush(unsigned long data) -{ - struct iwl3945_rs_sta *rs_sta = (void *)data; - struct iwl_priv *priv __maybe_unused = rs_sta->priv; - int unflushed = 0; - unsigned long flags; - u32 packet_count, duration, pps; - - IWL_DEBUG_RATE(priv, "enter\n"); - - unflushed = iwl3945_rate_scale_flush_windows(rs_sta); - - spin_lock_irqsave(&rs_sta->lock, flags); - - /* Number of packets Rx'd since last time this timer ran */ - packet_count = (rs_sta->tx_packets - rs_sta->last_tx_packets) + 1; - - rs_sta->last_tx_packets = rs_sta->tx_packets + 1; - - if (unflushed) { - duration = - jiffies_to_msecs(jiffies - rs_sta->last_partial_flush); - - IWL_DEBUG_RATE(priv, "Tx'd %d packets in %dms\n", - packet_count, duration); - - /* Determine packets per second */ - if (duration) - pps = (packet_count * 1000) / duration; - else - pps = 0; - - if (pps) { - duration = (IWL_AVERAGE_PACKETS * 1000) / pps; - if (duration < IWL_RATE_FLUSH_MIN) - duration = IWL_RATE_FLUSH_MIN; - else if (duration > IWL_RATE_FLUSH_MAX) - duration = IWL_RATE_FLUSH_MAX; - } else - duration = IWL_RATE_FLUSH_MAX; - - rs_sta->flush_time = msecs_to_jiffies(duration); - - IWL_DEBUG_RATE(priv, "new flush period: %d msec ave %d\n", - duration, packet_count); - - mod_timer(&rs_sta->rate_scale_flush, jiffies + - rs_sta->flush_time); - - rs_sta->last_partial_flush = jiffies; - } else { - rs_sta->flush_time = IWL_RATE_FLUSH; - rs_sta->flush_pending = 0; - } - /* If there weren't any unflushed entries, we don't schedule the timer - * to run again */ - - rs_sta->last_flush = jiffies; - - spin_unlock_irqrestore(&rs_sta->lock, flags); - - IWL_DEBUG_RATE(priv, "leave\n"); -} - -/** - * iwl3945_collect_tx_data - Update the success/failure sliding window - * - * We keep a sliding window of the last 64 packets transmitted - * at this rate. window->data contains the bitmask of successful - * packets. - */ -static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta, - struct iwl3945_rate_scale_data *window, - int success, int retries, int index) -{ - unsigned long flags; - s32 fail_count; - struct iwl_priv *priv __maybe_unused = rs_sta->priv; - - if (!retries) { - IWL_DEBUG_RATE(priv, "leave: retries == 0 -- should be at least 1\n"); - return; - } - - spin_lock_irqsave(&rs_sta->lock, flags); - - /* - * Keep track of only the latest 62 tx frame attempts in this rate's - * history window; anything older isn't really relevant any more. - * If we have filled up the sliding window, drop the oldest attempt; - * if the oldest attempt (highest bit in bitmap) shows "success", - * subtract "1" from the success counter (this is the main reason - * we keep these bitmaps!). - * */ - while (retries > 0) { - if (window->counter >= IWL_RATE_MAX_WINDOW) { - - /* remove earliest */ - window->counter = IWL_RATE_MAX_WINDOW - 1; - - if (window->data & (1ULL << (IWL_RATE_MAX_WINDOW - 1))) { - window->data &= ~(1ULL << (IWL_RATE_MAX_WINDOW - 1)); - window->success_counter--; - } - } - - /* Increment frames-attempted counter */ - window->counter++; - - /* Shift bitmap by one frame (throw away oldest history), - * OR in "1", and increment "success" if this - * frame was successful. */ - window->data <<= 1; - if (success > 0) { - window->success_counter++; - window->data |= 0x1; - success--; - } - - retries--; - } - - /* Calculate current success ratio, avoid divide-by-0! */ - if (window->counter > 0) - window->success_ratio = 128 * (100 * window->success_counter) - / window->counter; - else - window->success_ratio = IWL_INVALID_VALUE; - - fail_count = window->counter - window->success_counter; - - /* Calculate average throughput, if we have enough history. */ - if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) || - (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH)) - window->average_tpt = ((window->success_ratio * - rs_sta->expected_tpt[index] + 64) / 128); - else - window->average_tpt = IWL_INVALID_VALUE; - - /* Tag this window as having been updated */ - window->stamp = jiffies; - - spin_unlock_irqrestore(&rs_sta->lock, flags); - -} - -/* - * Called after adding a new station to initialize rate scaling - */ -void iwl3945_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_id) -{ - struct ieee80211_hw *hw = priv->hw; - struct ieee80211_conf *conf = &priv->hw->conf; - struct iwl3945_sta_priv *psta; - struct iwl3945_rs_sta *rs_sta; - struct ieee80211_supported_band *sband; - int i; - - IWL_DEBUG_INFO(priv, "enter\n"); - if (sta_id == priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id) - goto out; - - psta = (struct iwl3945_sta_priv *) sta->drv_priv; - rs_sta = &psta->rs_sta; - sband = hw->wiphy->bands[conf->channel->band]; - - rs_sta->priv = priv; - - rs_sta->start_rate = IWL_RATE_INVALID; - - /* default to just 802.11b */ - rs_sta->expected_tpt = iwl3945_expected_tpt_b; - - rs_sta->last_partial_flush = jiffies; - rs_sta->last_flush = jiffies; - rs_sta->flush_time = IWL_RATE_FLUSH; - rs_sta->last_tx_packets = 0; - - rs_sta->rate_scale_flush.data = (unsigned long)rs_sta; - rs_sta->rate_scale_flush.function = iwl3945_bg_rate_scale_flush; - - for (i = 0; i < IWL_RATE_COUNT_3945; i++) - iwl3945_clear_window(&rs_sta->win[i]); - - /* TODO: what is a good starting rate for STA? About middle? Maybe not - * the lowest or the highest rate.. Could consider using RSSI from - * previous packets? Need to have IEEE 802.1X auth succeed immediately - * after assoc.. */ - - for (i = sband->n_bitrates - 1; i >= 0; i--) { - if (sta->supp_rates[sband->band] & (1 << i)) { - rs_sta->last_txrate_idx = i; - break; - } - } - - priv->_3945.sta_supp_rates = sta->supp_rates[sband->band]; - /* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */ - if (sband->band == IEEE80211_BAND_5GHZ) { - rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; - priv->_3945.sta_supp_rates = priv->_3945.sta_supp_rates << - IWL_FIRST_OFDM_RATE; - } - -out: - priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; - - IWL_DEBUG_INFO(priv, "leave\n"); -} - -static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) -{ - return hw->priv; -} - -/* rate scale requires free function to be implemented */ -static void rs_free(void *priv) -{ - return; -} - -static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp) -{ - struct iwl3945_rs_sta *rs_sta; - struct iwl3945_sta_priv *psta = (void *) sta->drv_priv; - struct iwl_priv *priv __maybe_unused = iwl_priv; - - IWL_DEBUG_RATE(priv, "enter\n"); - - rs_sta = &psta->rs_sta; - - spin_lock_init(&rs_sta->lock); - init_timer(&rs_sta->rate_scale_flush); - - IWL_DEBUG_RATE(priv, "leave\n"); - - return rs_sta; -} - -static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta, - void *priv_sta) -{ - struct iwl3945_rs_sta *rs_sta = priv_sta; - - /* - * Be careful not to use any members of iwl3945_rs_sta (like trying - * to use iwl_priv to print out debugging) since it may not be fully - * initialized at this point. - */ - del_timer_sync(&rs_sta->rate_scale_flush); -} - - -/** - * rs_tx_status - Update rate control values based on Tx results - * - * NOTE: Uses iwl_priv->retry_rate for the # of retries attempted by - * the hardware for each rate. - */ -static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband, - struct ieee80211_sta *sta, void *priv_sta, - struct sk_buff *skb) -{ - s8 retries = 0, current_count; - int scale_rate_index, first_index, last_index; - unsigned long flags; - struct iwl_priv *priv = (struct iwl_priv *)priv_rate; - struct iwl3945_rs_sta *rs_sta = priv_sta; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - - IWL_DEBUG_RATE(priv, "enter\n"); - - retries = info->status.rates[0].count; - /* Sanity Check for retries */ - if (retries > IWL_RATE_RETRY_TH) - retries = IWL_RATE_RETRY_TH; - - first_index = sband->bitrates[info->status.rates[0].idx].hw_value; - if ((first_index < 0) || (first_index >= IWL_RATE_COUNT_3945)) { - IWL_DEBUG_RATE(priv, "leave: Rate out of bounds: %d\n", first_index); - return; - } - - if (!priv_sta) { - IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n"); - return; - } - - /* Treat uninitialized rate scaling data same as non-existing. */ - if (!rs_sta->priv) { - IWL_DEBUG_RATE(priv, "leave: STA priv data uninitialized!\n"); - return; - } - - - rs_sta->tx_packets++; - - scale_rate_index = first_index; - last_index = first_index; - - /* - * Update the window for each rate. We determine which rates - * were Tx'd based on the total number of retries vs. the number - * of retries configured for each rate -- currently set to the - * priv value 'retry_rate' vs. rate specific - * - * On exit from this while loop last_index indicates the rate - * at which the frame was finally transmitted (or failed if no - * ACK) - */ - while (retries > 1) { - if ((retries - 1) < priv->retry_rate) { - current_count = (retries - 1); - last_index = scale_rate_index; - } else { - current_count = priv->retry_rate; - last_index = iwl3945_rs_next_rate(priv, - scale_rate_index); - } - - /* Update this rate accounting for as many retries - * as was used for it (per current_count) */ - iwl3945_collect_tx_data(rs_sta, - &rs_sta->win[scale_rate_index], - 0, current_count, scale_rate_index); - IWL_DEBUG_RATE(priv, "Update rate %d for %d retries.\n", - scale_rate_index, current_count); - - retries -= current_count; - - scale_rate_index = last_index; - } - - - /* Update the last index window with success/failure based on ACK */ - IWL_DEBUG_RATE(priv, "Update rate %d with %s.\n", - last_index, - (info->flags & IEEE80211_TX_STAT_ACK) ? - "success" : "failure"); - iwl3945_collect_tx_data(rs_sta, - &rs_sta->win[last_index], - info->flags & IEEE80211_TX_STAT_ACK, 1, last_index); - - /* We updated the rate scale window -- if its been more than - * flush_time since the last run, schedule the flush - * again */ - spin_lock_irqsave(&rs_sta->lock, flags); - - if (!rs_sta->flush_pending && - time_after(jiffies, rs_sta->last_flush + - rs_sta->flush_time)) { - - rs_sta->last_partial_flush = jiffies; - rs_sta->flush_pending = 1; - mod_timer(&rs_sta->rate_scale_flush, - jiffies + rs_sta->flush_time); - } - - spin_unlock_irqrestore(&rs_sta->lock, flags); - - IWL_DEBUG_RATE(priv, "leave\n"); -} - -static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, - u8 index, u16 rate_mask, enum ieee80211_band band) -{ - u8 high = IWL_RATE_INVALID; - u8 low = IWL_RATE_INVALID; - struct iwl_priv *priv __maybe_unused = rs_sta->priv; - - /* 802.11A walks to the next literal adjacent rate in - * the rate table */ - if (unlikely(band == IEEE80211_BAND_5GHZ)) { - int i; - u32 mask; - - /* Find the previous rate that is in the rate mask */ - i = index - 1; - for (mask = (1 << i); i >= 0; i--, mask >>= 1) { - if (rate_mask & mask) { - low = i; - break; - } - } - - /* Find the next rate that is in the rate mask */ - i = index + 1; - for (mask = (1 << i); i < IWL_RATE_COUNT_3945; - i++, mask <<= 1) { - if (rate_mask & mask) { - high = i; - break; - } - } - - return (high << 8) | low; - } - - low = index; - while (low != IWL_RATE_INVALID) { - if (rs_sta->tgg) - low = iwl3945_rates[low].prev_rs_tgg; - else - low = iwl3945_rates[low].prev_rs; - if (low == IWL_RATE_INVALID) - break; - if (rate_mask & (1 << low)) - break; - IWL_DEBUG_RATE(priv, "Skipping masked lower rate: %d\n", low); - } - - high = index; - while (high != IWL_RATE_INVALID) { - if (rs_sta->tgg) - high = iwl3945_rates[high].next_rs_tgg; - else - high = iwl3945_rates[high].next_rs; - if (high == IWL_RATE_INVALID) - break; - if (rate_mask & (1 << high)) - break; - IWL_DEBUG_RATE(priv, "Skipping masked higher rate: %d\n", high); - } - - return (high << 8) | low; -} - -/** - * rs_get_rate - find the rate for the requested packet - * - * Returns the ieee80211_rate structure allocated by the driver. - * - * The rate control algorithm has no internal mapping between hw_mode's - * rate ordering and the rate ordering used by the rate control algorithm. - * - * The rate control algorithm uses a single table of rates that goes across - * the entire A/B/G spectrum vs. being limited to just one particular - * hw_mode. - * - * As such, we can't convert the index obtained below into the hw_mode's - * rate table and must reference the driver allocated rate table - * - */ -static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, - void *priv_sta, struct ieee80211_tx_rate_control *txrc) -{ - struct ieee80211_supported_band *sband = txrc->sband; - struct sk_buff *skb = txrc->skb; - u8 low = IWL_RATE_INVALID; - u8 high = IWL_RATE_INVALID; - u16 high_low; - int index; - struct iwl3945_rs_sta *rs_sta = priv_sta; - struct iwl3945_rate_scale_data *window = NULL; - int current_tpt = IWL_INVALID_VALUE; - int low_tpt = IWL_INVALID_VALUE; - int high_tpt = IWL_INVALID_VALUE; - u32 fail_count; - s8 scale_action = 0; - unsigned long flags; - u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0; - s8 max_rate_idx = -1; - struct iwl_priv *priv __maybe_unused = (struct iwl_priv *)priv_r; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - - IWL_DEBUG_RATE(priv, "enter\n"); - - /* Treat uninitialized rate scaling data same as non-existing. */ - if (rs_sta && !rs_sta->priv) { - IWL_DEBUG_RATE(priv, "Rate scaling information not initialized yet.\n"); - priv_sta = NULL; - } - - if (rate_control_send_low(sta, priv_sta, txrc)) - return; - - rate_mask = sta->supp_rates[sband->band]; - - /* get user max rate if set */ - max_rate_idx = txrc->max_rate_idx; - if ((sband->band == IEEE80211_BAND_5GHZ) && (max_rate_idx != -1)) - max_rate_idx += IWL_FIRST_OFDM_RATE; - if ((max_rate_idx < 0) || (max_rate_idx >= IWL_RATE_COUNT)) - max_rate_idx = -1; - - index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT_3945 - 1); - - if (sband->band == IEEE80211_BAND_5GHZ) - rate_mask = rate_mask << IWL_FIRST_OFDM_RATE; - - spin_lock_irqsave(&rs_sta->lock, flags); - - /* for recent assoc, choose best rate regarding - * to rssi value - */ - if (rs_sta->start_rate != IWL_RATE_INVALID) { - if (rs_sta->start_rate < index && - (rate_mask & (1 << rs_sta->start_rate))) - index = rs_sta->start_rate; - rs_sta->start_rate = IWL_RATE_INVALID; - } - - /* force user max rate if set by user */ - if ((max_rate_idx != -1) && (max_rate_idx < index)) { - if (rate_mask & (1 << max_rate_idx)) - index = max_rate_idx; - } - - window = &(rs_sta->win[index]); - - fail_count = window->counter - window->success_counter; - - if (((fail_count < IWL_RATE_MIN_FAILURE_TH) && - (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) { - spin_unlock_irqrestore(&rs_sta->lock, flags); - - IWL_DEBUG_RATE(priv, "Invalid average_tpt on rate %d: " - "counter: %d, success_counter: %d, " - "expected_tpt is %sNULL\n", - index, - window->counter, - window->success_counter, - rs_sta->expected_tpt ? "not " : ""); - - /* Can't calculate this yet; not enough history */ - window->average_tpt = IWL_INVALID_VALUE; - goto out; - - } - - current_tpt = window->average_tpt; - - high_low = iwl3945_get_adjacent_rate(rs_sta, index, rate_mask, - sband->band); - low = high_low & 0xff; - high = (high_low >> 8) & 0xff; - - /* If user set max rate, dont allow higher than user constrain */ - if ((max_rate_idx != -1) && (max_rate_idx < high)) - high = IWL_RATE_INVALID; - - /* Collect Measured throughputs of adjacent rates */ - if (low != IWL_RATE_INVALID) - low_tpt = rs_sta->win[low].average_tpt; - - if (high != IWL_RATE_INVALID) - high_tpt = rs_sta->win[high].average_tpt; - - spin_unlock_irqrestore(&rs_sta->lock, flags); - - scale_action = 0; - - /* Low success ratio , need to drop the rate */ - if ((window->success_ratio < IWL_RATE_DECREASE_TH) || !current_tpt) { - IWL_DEBUG_RATE(priv, "decrease rate because of low success_ratio\n"); - scale_action = -1; - /* No throughput measured yet for adjacent rates, - * try increase */ - } else if ((low_tpt == IWL_INVALID_VALUE) && - (high_tpt == IWL_INVALID_VALUE)) { - - if (high != IWL_RATE_INVALID && window->success_ratio >= IWL_RATE_INCREASE_TH) - scale_action = 1; - else if (low != IWL_RATE_INVALID) - scale_action = 0; - - /* Both adjacent throughputs are measured, but neither one has - * better throughput; we're using the best rate, don't change - * it! */ - } else if ((low_tpt != IWL_INVALID_VALUE) && - (high_tpt != IWL_INVALID_VALUE) && - (low_tpt < current_tpt) && (high_tpt < current_tpt)) { - - IWL_DEBUG_RATE(priv, "No action -- low [%d] & high [%d] < " - "current_tpt [%d]\n", - low_tpt, high_tpt, current_tpt); - scale_action = 0; - - /* At least one of the rates has better throughput */ - } else { - if (high_tpt != IWL_INVALID_VALUE) { - - /* High rate has better throughput, Increase - * rate */ - if (high_tpt > current_tpt && - window->success_ratio >= IWL_RATE_INCREASE_TH) - scale_action = 1; - else { - IWL_DEBUG_RATE(priv, - "decrease rate because of high tpt\n"); - scale_action = 0; - } - } else if (low_tpt != IWL_INVALID_VALUE) { - if (low_tpt > current_tpt) { - IWL_DEBUG_RATE(priv, - "decrease rate because of low tpt\n"); - scale_action = -1; - } else if (window->success_ratio >= IWL_RATE_INCREASE_TH) { - /* Lower rate has better - * throughput,decrease rate */ - scale_action = 1; - } - } - } - - /* Sanity check; asked for decrease, but success rate or throughput - * has been good at old rate. Don't change it. */ - if ((scale_action == -1) && (low != IWL_RATE_INVALID) && - ((window->success_ratio > IWL_RATE_HIGH_TH) || - (current_tpt > (100 * rs_sta->expected_tpt[low])))) - scale_action = 0; - - switch (scale_action) { - case -1: - - /* Decrese rate */ - if (low != IWL_RATE_INVALID) - index = low; - break; - - case 1: - /* Increase rate */ - if (high != IWL_RATE_INVALID) - index = high; - - break; - - case 0: - default: - /* No change */ - break; - } - - IWL_DEBUG_RATE(priv, "Selected %d (action %d) - low %d high %d\n", - index, scale_action, low, high); - - out: - - rs_sta->last_txrate_idx = index; - if (sband->band == IEEE80211_BAND_5GHZ) - info->control.rates[0].idx = rs_sta->last_txrate_idx - - IWL_FIRST_OFDM_RATE; - else - info->control.rates[0].idx = rs_sta->last_txrate_idx; - - IWL_DEBUG_RATE(priv, "leave: %d\n", index); -} - -#ifdef CONFIG_MAC80211_DEBUGFS -static int iwl3945_open_file_generic(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t iwl3945_sta_dbgfs_stats_table_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - char *buff; - int desc = 0; - int j; - ssize_t ret; - struct iwl3945_rs_sta *lq_sta = file->private_data; - - buff = kmalloc(1024, GFP_KERNEL); - if (!buff) - return -ENOMEM; - - desc += sprintf(buff + desc, "tx packets=%d last rate index=%d\n" - "rate=0x%X flush time %d\n", - lq_sta->tx_packets, - lq_sta->last_txrate_idx, - lq_sta->start_rate, jiffies_to_msecs(lq_sta->flush_time)); - for (j = 0; j < IWL_RATE_COUNT_3945; j++) { - desc += sprintf(buff+desc, - "counter=%d success=%d %%=%d\n", - lq_sta->win[j].counter, - lq_sta->win[j].success_counter, - lq_sta->win[j].success_ratio); - } - ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); - kfree(buff); - return ret; -} - -static const struct file_operations rs_sta_dbgfs_stats_table_ops = { - .read = iwl3945_sta_dbgfs_stats_table_read, - .open = iwl3945_open_file_generic, - .llseek = default_llseek, -}; - -static void iwl3945_add_debugfs(void *priv, void *priv_sta, - struct dentry *dir) -{ - struct iwl3945_rs_sta *lq_sta = priv_sta; - - lq_sta->rs_sta_dbgfs_stats_table_file = - debugfs_create_file("rate_stats_table", 0600, dir, - lq_sta, &rs_sta_dbgfs_stats_table_ops); - -} - -static void iwl3945_remove_debugfs(void *priv, void *priv_sta) -{ - struct iwl3945_rs_sta *lq_sta = priv_sta; - debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); -} -#endif - -/* - * Initialization of rate scaling information is done by driver after - * the station is added. Since mac80211 calls this function before a - * station is added we ignore it. - */ -static void rs_rate_init_stub(void *priv_r, struct ieee80211_supported_band *sband, - struct ieee80211_sta *sta, void *priv_sta) -{ -} - -static struct rate_control_ops rs_ops = { - .module = NULL, - .name = RS_NAME, - .tx_status = rs_tx_status, - .get_rate = rs_get_rate, - .rate_init = rs_rate_init_stub, - .alloc = rs_alloc, - .free = rs_free, - .alloc_sta = rs_alloc_sta, - .free_sta = rs_free_sta, -#ifdef CONFIG_MAC80211_DEBUGFS - .add_sta_debugfs = iwl3945_add_debugfs, - .remove_sta_debugfs = iwl3945_remove_debugfs, -#endif - -}; -void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) -{ - struct iwl_priv *priv = hw->priv; - s32 rssi = 0; - unsigned long flags; - struct iwl3945_rs_sta *rs_sta; - struct ieee80211_sta *sta; - struct iwl3945_sta_priv *psta; - - IWL_DEBUG_RATE(priv, "enter\n"); - - rcu_read_lock(); - - sta = ieee80211_find_sta(priv->contexts[IWL_RXON_CTX_BSS].vif, - priv->stations[sta_id].sta.sta.addr); - if (!sta) { - IWL_DEBUG_RATE(priv, "Unable to find station to initialize rate scaling.\n"); - rcu_read_unlock(); - return; - } - - psta = (void *) sta->drv_priv; - rs_sta = &psta->rs_sta; - - spin_lock_irqsave(&rs_sta->lock, flags); - - rs_sta->tgg = 0; - switch (priv->band) { - case IEEE80211_BAND_2GHZ: - /* TODO: this always does G, not a regression */ - if (priv->contexts[IWL_RXON_CTX_BSS].active.flags & - RXON_FLG_TGG_PROTECT_MSK) { - rs_sta->tgg = 1; - rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot; - } else - rs_sta->expected_tpt = iwl3945_expected_tpt_g; - break; - - case IEEE80211_BAND_5GHZ: - rs_sta->expected_tpt = iwl3945_expected_tpt_a; - break; - case IEEE80211_NUM_BANDS: - BUG(); - break; - } - - spin_unlock_irqrestore(&rs_sta->lock, flags); - - rssi = priv->_3945.last_rx_rssi; - if (rssi == 0) - rssi = IWL_MIN_RSSI_VAL; - - IWL_DEBUG_RATE(priv, "Network RSSI: %d\n", rssi); - - rs_sta->start_rate = iwl3945_get_rate_index_by_rssi(rssi, priv->band); - - IWL_DEBUG_RATE(priv, "leave: rssi %d assign rate index: " - "%d (plcp 0x%x)\n", rssi, rs_sta->start_rate, - iwl3945_rates[rs_sta->start_rate].plcp); - rcu_read_unlock(); -} - -int iwl3945_rate_control_register(void) -{ - return ieee80211_rate_control_register(&rs_ops); -} - -void iwl3945_rate_control_unregister(void) -{ - ieee80211_rate_control_unregister(&rs_ops); -} - - diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c deleted file mode 100644 index 5b6932c2193a..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ /dev/null @@ -1,2819 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "iwl-fh.h" -#include "iwl-3945-fh.h" -#include "iwl-commands.h" -#include "iwl-sta.h" -#include "iwl-3945.h" -#include "iwl-eeprom.h" -#include "iwl-core.h" -#include "iwl-helpers.h" -#include "iwl-led.h" -#include "iwl-3945-led.h" -#include "iwl-3945-debugfs.h" -#include "iwl-legacy.h" - -#define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \ - [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ - IWL_RATE_##r##M_IEEE, \ - IWL_RATE_##ip##M_INDEX, \ - IWL_RATE_##in##M_INDEX, \ - IWL_RATE_##rp##M_INDEX, \ - IWL_RATE_##rn##M_INDEX, \ - IWL_RATE_##pp##M_INDEX, \ - IWL_RATE_##np##M_INDEX, \ - IWL_RATE_##r##M_INDEX_TABLE, \ - IWL_RATE_##ip##M_INDEX_TABLE } - -/* - * Parameter order: - * rate, prev rate, next rate, prev tgg rate, next tgg rate - * - * If there isn't a valid next or previous rate then INV is used which - * maps to IWL_RATE_INVALID - * - */ -const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945] = { - IWL_DECLARE_RATE_INFO(1, INV, 2, INV, 2, INV, 2), /* 1mbps */ - IWL_DECLARE_RATE_INFO(2, 1, 5, 1, 5, 1, 5), /* 2mbps */ - IWL_DECLARE_RATE_INFO(5, 2, 6, 2, 11, 2, 11), /*5.5mbps */ - IWL_DECLARE_RATE_INFO(11, 9, 12, 5, 12, 5, 18), /* 11mbps */ - IWL_DECLARE_RATE_INFO(6, 5, 9, 5, 11, 5, 11), /* 6mbps */ - IWL_DECLARE_RATE_INFO(9, 6, 11, 5, 11, 5, 11), /* 9mbps */ - IWL_DECLARE_RATE_INFO(12, 11, 18, 11, 18, 11, 18), /* 12mbps */ - IWL_DECLARE_RATE_INFO(18, 12, 24, 12, 24, 11, 24), /* 18mbps */ - IWL_DECLARE_RATE_INFO(24, 18, 36, 18, 36, 18, 36), /* 24mbps */ - IWL_DECLARE_RATE_INFO(36, 24, 48, 24, 48, 24, 48), /* 36mbps */ - IWL_DECLARE_RATE_INFO(48, 36, 54, 36, 54, 36, 54), /* 48mbps */ - IWL_DECLARE_RATE_INFO(54, 48, INV, 48, INV, 48, INV),/* 54mbps */ -}; - -static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index) -{ - u8 rate = iwl3945_rates[rate_index].prev_ieee; - - if (rate == IWL_RATE_INVALID) - rate = rate_index; - return rate; -} - -/* 1 = enable the iwl3945_disable_events() function */ -#define IWL_EVT_DISABLE (0) -#define IWL_EVT_DISABLE_SIZE (1532/32) - -/** - * iwl3945_disable_events - Disable selected events in uCode event log - * - * Disable an event by writing "1"s into "disable" - * bitmap in SRAM. Bit position corresponds to Event # (id/type). - * Default values of 0 enable uCode events to be logged. - * Use for only special debugging. This function is just a placeholder as-is, - * you'll need to provide the special bits! ... - * ... and set IWL_EVT_DISABLE to 1. */ -void iwl3945_disable_events(struct iwl_priv *priv) -{ - int i; - u32 base; /* SRAM address of event log header */ - u32 disable_ptr; /* SRAM address of event-disable bitmap array */ - u32 array_size; /* # of u32 entries in array */ - static const u32 evt_disable[IWL_EVT_DISABLE_SIZE] = { - 0x00000000, /* 31 - 0 Event id numbers */ - 0x00000000, /* 63 - 32 */ - 0x00000000, /* 95 - 64 */ - 0x00000000, /* 127 - 96 */ - 0x00000000, /* 159 - 128 */ - 0x00000000, /* 191 - 160 */ - 0x00000000, /* 223 - 192 */ - 0x00000000, /* 255 - 224 */ - 0x00000000, /* 287 - 256 */ - 0x00000000, /* 319 - 288 */ - 0x00000000, /* 351 - 320 */ - 0x00000000, /* 383 - 352 */ - 0x00000000, /* 415 - 384 */ - 0x00000000, /* 447 - 416 */ - 0x00000000, /* 479 - 448 */ - 0x00000000, /* 511 - 480 */ - 0x00000000, /* 543 - 512 */ - 0x00000000, /* 575 - 544 */ - 0x00000000, /* 607 - 576 */ - 0x00000000, /* 639 - 608 */ - 0x00000000, /* 671 - 640 */ - 0x00000000, /* 703 - 672 */ - 0x00000000, /* 735 - 704 */ - 0x00000000, /* 767 - 736 */ - 0x00000000, /* 799 - 768 */ - 0x00000000, /* 831 - 800 */ - 0x00000000, /* 863 - 832 */ - 0x00000000, /* 895 - 864 */ - 0x00000000, /* 927 - 896 */ - 0x00000000, /* 959 - 928 */ - 0x00000000, /* 991 - 960 */ - 0x00000000, /* 1023 - 992 */ - 0x00000000, /* 1055 - 1024 */ - 0x00000000, /* 1087 - 1056 */ - 0x00000000, /* 1119 - 1088 */ - 0x00000000, /* 1151 - 1120 */ - 0x00000000, /* 1183 - 1152 */ - 0x00000000, /* 1215 - 1184 */ - 0x00000000, /* 1247 - 1216 */ - 0x00000000, /* 1279 - 1248 */ - 0x00000000, /* 1311 - 1280 */ - 0x00000000, /* 1343 - 1312 */ - 0x00000000, /* 1375 - 1344 */ - 0x00000000, /* 1407 - 1376 */ - 0x00000000, /* 1439 - 1408 */ - 0x00000000, /* 1471 - 1440 */ - 0x00000000, /* 1503 - 1472 */ - }; - - base = le32_to_cpu(priv->card_alive.log_event_table_ptr); - if (!iwl3945_hw_valid_rtc_data_addr(base)) { - IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); - return; - } - - disable_ptr = iwl_read_targ_mem(priv, base + (4 * sizeof(u32))); - array_size = iwl_read_targ_mem(priv, base + (5 * sizeof(u32))); - - if (IWL_EVT_DISABLE && (array_size == IWL_EVT_DISABLE_SIZE)) { - IWL_DEBUG_INFO(priv, "Disabling selected uCode log events at 0x%x\n", - disable_ptr); - for (i = 0; i < IWL_EVT_DISABLE_SIZE; i++) - iwl_write_targ_mem(priv, - disable_ptr + (i * sizeof(u32)), - evt_disable[i]); - - } else { - IWL_DEBUG_INFO(priv, "Selected uCode log events may be disabled\n"); - IWL_DEBUG_INFO(priv, " by writing \"1\"s into disable bitmap\n"); - IWL_DEBUG_INFO(priv, " in SRAM at 0x%x, size %d u32s\n", - disable_ptr, array_size); - } - -} - -static int iwl3945_hwrate_to_plcp_idx(u8 plcp) -{ - int idx; - - for (idx = 0; idx < IWL_RATE_COUNT_3945; idx++) - if (iwl3945_rates[idx].plcp == plcp) - return idx; - return -1; -} - -#ifdef CONFIG_IWLWIFI_DEBUG -#define TX_STATUS_ENTRY(x) case TX_3945_STATUS_FAIL_ ## x: return #x - -static const char *iwl3945_get_tx_fail_reason(u32 status) -{ - switch (status & TX_STATUS_MSK) { - case TX_3945_STATUS_SUCCESS: - return "SUCCESS"; - TX_STATUS_ENTRY(SHORT_LIMIT); - TX_STATUS_ENTRY(LONG_LIMIT); - TX_STATUS_ENTRY(FIFO_UNDERRUN); - TX_STATUS_ENTRY(MGMNT_ABORT); - TX_STATUS_ENTRY(NEXT_FRAG); - TX_STATUS_ENTRY(LIFE_EXPIRE); - TX_STATUS_ENTRY(DEST_PS); - TX_STATUS_ENTRY(ABORTED); - TX_STATUS_ENTRY(BT_RETRY); - TX_STATUS_ENTRY(STA_INVALID); - TX_STATUS_ENTRY(FRAG_DROPPED); - TX_STATUS_ENTRY(TID_DISABLE); - TX_STATUS_ENTRY(FRAME_FLUSHED); - TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL); - TX_STATUS_ENTRY(TX_LOCKED); - TX_STATUS_ENTRY(NO_BEACON_ON_RADAR); - } - - return "UNKNOWN"; -} -#else -static inline const char *iwl3945_get_tx_fail_reason(u32 status) -{ - return ""; -} -#endif - -/* - * get ieee prev rate from rate scale table. - * for A and B mode we need to overright prev - * value - */ -int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate) -{ - int next_rate = iwl3945_get_prev_ieee_rate(rate); - - switch (priv->band) { - case IEEE80211_BAND_5GHZ: - if (rate == IWL_RATE_12M_INDEX) - next_rate = IWL_RATE_9M_INDEX; - else if (rate == IWL_RATE_6M_INDEX) - next_rate = IWL_RATE_6M_INDEX; - break; - case IEEE80211_BAND_2GHZ: - if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) && - iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { - if (rate == IWL_RATE_11M_INDEX) - next_rate = IWL_RATE_5M_INDEX; - } - break; - - default: - break; - } - - return next_rate; -} - - -/** - * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd - * - * When FW advances 'R' index, all entries between old and new 'R' index - * need to be reclaimed. As result, some free space forms. If there is - * enough free space (> low mark), wake the stack that feeds us. - */ -static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, - int txq_id, int index) -{ - struct iwl_tx_queue *txq = &priv->txq[txq_id]; - struct iwl_queue *q = &txq->q; - struct iwl_tx_info *tx_info; - - BUG_ON(txq_id == IWL39_CMD_QUEUE_NUM); - - for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index; - q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { - - tx_info = &txq->txb[txq->q.read_ptr]; - ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb); - tx_info->skb = NULL; - priv->cfg->ops->lib->txq_free_tfd(priv, txq); - } - - if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) && - (txq_id != IWL39_CMD_QUEUE_NUM) && - priv->mac80211_registered) - iwl_wake_queue(priv, txq); -} - -/** - * iwl3945_rx_reply_tx - Handle Tx response - */ -static void iwl3945_rx_reply_tx(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - u16 sequence = le16_to_cpu(pkt->hdr.sequence); - int txq_id = SEQ_TO_QUEUE(sequence); - int index = SEQ_TO_INDEX(sequence); - struct iwl_tx_queue *txq = &priv->txq[txq_id]; - struct ieee80211_tx_info *info; - struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; - u32 status = le32_to_cpu(tx_resp->status); - int rate_idx; - int fail; - - if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { - IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " - "is out of range [0-%d] %d %d\n", txq_id, - index, txq->q.n_bd, txq->q.write_ptr, - txq->q.read_ptr); - return; - } - - txq->time_stamp = jiffies; - info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); - ieee80211_tx_info_clear_status(info); - - /* Fill the MRR chain with some info about on-chip retransmissions */ - rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate); - if (info->band == IEEE80211_BAND_5GHZ) - rate_idx -= IWL_FIRST_OFDM_RATE; - - fail = tx_resp->failure_frame; - - info->status.rates[0].idx = rate_idx; - info->status.rates[0].count = fail + 1; /* add final attempt */ - - /* tx_status->rts_retry_count = tx_resp->failure_rts; */ - info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ? - IEEE80211_TX_STAT_ACK : 0; - - IWL_DEBUG_TX(priv, "Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n", - txq_id, iwl3945_get_tx_fail_reason(status), status, - tx_resp->rate, tx_resp->failure_frame); - - IWL_DEBUG_TX_REPLY(priv, "Tx queue reclaim %d\n", index); - iwl3945_tx_queue_reclaim(priv, txq_id, index); - - if (status & TX_ABORT_REQUIRED_MSK) - IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); -} - - - -/***************************************************************************** - * - * Intel PRO/Wireless 3945ABG/BG Network Connection - * - * RX handler implementations - * - *****************************************************************************/ -#ifdef CONFIG_IWLWIFI_DEBUGFS -/* - * based on the assumption of all statistics counter are in DWORD - * FIXME: This function is for debugging, do not deal with - * the case of counters roll-over. - */ -static void iwl3945_accumulative_statistics(struct iwl_priv *priv, - __le32 *stats) -{ - int i; - __le32 *prev_stats; - u32 *accum_stats; - u32 *delta, *max_delta; - - prev_stats = (__le32 *)&priv->_3945.statistics; - accum_stats = (u32 *)&priv->_3945.accum_statistics; - delta = (u32 *)&priv->_3945.delta_statistics; - max_delta = (u32 *)&priv->_3945.max_delta; - - for (i = sizeof(__le32); i < sizeof(struct iwl3945_notif_statistics); - i += sizeof(__le32), stats++, prev_stats++, delta++, - max_delta++, accum_stats++) { - if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { - *delta = (le32_to_cpu(*stats) - - le32_to_cpu(*prev_stats)); - *accum_stats += *delta; - if (*delta > *max_delta) - *max_delta = *delta; - } - } - - /* reset accumulative statistics for "no-counter" type statistics */ - priv->_3945.accum_statistics.general.temperature = - priv->_3945.statistics.general.temperature; - priv->_3945.accum_statistics.general.ttl_timestamp = - priv->_3945.statistics.general.ttl_timestamp; -} -#endif - -/** - * iwl3945_good_plcp_health - checks for plcp error. - * - * When the plcp error is exceeding the thresholds, reset the radio - * to improve the throughput. - */ -static bool iwl3945_good_plcp_health(struct iwl_priv *priv, - struct iwl_rx_packet *pkt) -{ - bool rc = true; - struct iwl3945_notif_statistics current_stat; - int combined_plcp_delta; - unsigned int plcp_msec; - unsigned long plcp_received_jiffies; - - if (priv->cfg->base_params->plcp_delta_threshold == - IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { - IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); - return rc; - } - memcpy(¤t_stat, pkt->u.raw, sizeof(struct - iwl3945_notif_statistics)); - /* - * check for plcp_err and trigger radio reset if it exceeds - * the plcp error threshold plcp_delta. - */ - plcp_received_jiffies = jiffies; - plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - - (long) priv->plcp_jiffies); - priv->plcp_jiffies = plcp_received_jiffies; - /* - * check to make sure plcp_msec is not 0 to prevent division - * by zero. - */ - if (plcp_msec) { - combined_plcp_delta = - (le32_to_cpu(current_stat.rx.ofdm.plcp_err) - - le32_to_cpu(priv->_3945.statistics.rx.ofdm.plcp_err)); - - if ((combined_plcp_delta > 0) && - ((combined_plcp_delta * 100) / plcp_msec) > - priv->cfg->base_params->plcp_delta_threshold) { - /* - * if plcp_err exceed the threshold, the following - * data is printed in csv format: - * Text: plcp_err exceeded %d, - * Received ofdm.plcp_err, - * Current ofdm.plcp_err, - * combined_plcp_delta, - * plcp_msec - */ - IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " - "%u, %d, %u mSecs\n", - priv->cfg->base_params->plcp_delta_threshold, - le32_to_cpu(current_stat.rx.ofdm.plcp_err), - combined_plcp_delta, plcp_msec); - /* - * Reset the RF radio due to the high plcp - * error rate - */ - rc = false; - } - } - return rc; -} - -void iwl3945_hw_rx_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - - IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", - (int)sizeof(struct iwl3945_notif_statistics), - le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); -#ifdef CONFIG_IWLWIFI_DEBUGFS - iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw); -#endif - iwl_recover_from_statistics(priv, pkt); - - memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics)); -} - -void iwl3945_reply_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - __le32 *flag = (__le32 *)&pkt->u.raw; - - if (le32_to_cpu(*flag) & UCODE_STATISTICS_CLEAR_MSK) { -#ifdef CONFIG_IWLWIFI_DEBUGFS - memset(&priv->_3945.accum_statistics, 0, - sizeof(struct iwl3945_notif_statistics)); - memset(&priv->_3945.delta_statistics, 0, - sizeof(struct iwl3945_notif_statistics)); - memset(&priv->_3945.max_delta, 0, - sizeof(struct iwl3945_notif_statistics)); -#endif - IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); - } - iwl3945_hw_rx_statistics(priv, rxb); -} - - -/****************************************************************************** - * - * Misc. internal state and helper functions - * - ******************************************************************************/ - -/* This is necessary only for a number of statistics, see the caller. */ -static int iwl3945_is_network_packet(struct iwl_priv *priv, - struct ieee80211_hdr *header) -{ - /* Filter incoming packets to determine if they are targeted toward - * this network, discarding packets coming from ourselves */ - switch (priv->iw_mode) { - case NL80211_IFTYPE_ADHOC: /* Header: Dest. | Source | BSSID */ - /* packets to our IBSS update information */ - return !compare_ether_addr(header->addr3, priv->bssid); - case NL80211_IFTYPE_STATION: /* Header: Dest. | AP{BSSID} | Source */ - /* packets to our IBSS update information */ - return !compare_ether_addr(header->addr2, priv->bssid); - default: - return 1; - } -} - -static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, - struct ieee80211_rx_status *stats) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); - struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); - struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); - u16 len = le16_to_cpu(rx_hdr->len); - struct sk_buff *skb; - __le16 fc = hdr->frame_control; - - /* We received data from the HW, so stop the watchdog */ - if (unlikely(len + IWL39_RX_FRAME_SIZE > - PAGE_SIZE << priv->hw_params.rx_page_order)) { - IWL_DEBUG_DROP(priv, "Corruption detected!\n"); - return; - } - - /* We only process data packets if the interface is open */ - if (unlikely(!priv->is_open)) { - IWL_DEBUG_DROP_LIMIT(priv, - "Dropping packet while interface is not open.\n"); - return; - } - - skb = dev_alloc_skb(128); - if (!skb) { - IWL_ERR(priv, "dev_alloc_skb failed\n"); - return; - } - - if (!iwl3945_mod_params.sw_crypto) - iwl_set_decrypted_flag(priv, - (struct ieee80211_hdr *)rxb_addr(rxb), - le32_to_cpu(rx_end->status), stats); - - skb_add_rx_frag(skb, 0, rxb->page, - (void *)rx_hdr->payload - (void *)pkt, len); - - iwl_update_stats(priv, false, fc, len); - memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); - - ieee80211_rx(priv->hw, skb); - priv->alloc_rxb_page--; - rxb->page = NULL; -} - -#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) - -static void iwl3945_rx_reply_rx(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct ieee80211_hdr *header; - struct ieee80211_rx_status rx_status; - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); - struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); - struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); - u16 rx_stats_sig_avg __maybe_unused = le16_to_cpu(rx_stats->sig_avg); - u16 rx_stats_noise_diff __maybe_unused = le16_to_cpu(rx_stats->noise_diff); - u8 network_packet; - - rx_status.flag = 0; - rx_status.mactime = le64_to_cpu(rx_end->timestamp); - rx_status.band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? - IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; - rx_status.freq = - ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel), - rx_status.band); - - rx_status.rate_idx = iwl3945_hwrate_to_plcp_idx(rx_hdr->rate); - if (rx_status.band == IEEE80211_BAND_5GHZ) - rx_status.rate_idx -= IWL_FIRST_OFDM_RATE; - - rx_status.antenna = (le16_to_cpu(rx_hdr->phy_flags) & - RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4; - - /* set the preamble flag if appropriate */ - if (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK) - rx_status.flag |= RX_FLAG_SHORTPRE; - - if ((unlikely(rx_stats->phy_count > 20))) { - IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n", - rx_stats->phy_count); - return; - } - - if (!(rx_end->status & RX_RES_STATUS_NO_CRC32_ERROR) - || !(rx_end->status & RX_RES_STATUS_NO_RXE_OVERFLOW)) { - IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n", rx_end->status); - return; - } - - - - /* Convert 3945's rssi indicator to dBm */ - rx_status.signal = rx_stats->rssi - IWL39_RSSI_OFFSET; - - IWL_DEBUG_STATS(priv, "Rssi %d sig_avg %d noise_diff %d\n", - rx_status.signal, rx_stats_sig_avg, - rx_stats_noise_diff); - - header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); - - network_packet = iwl3945_is_network_packet(priv, header); - - IWL_DEBUG_STATS_LIMIT(priv, "[%c] %d RSSI:%d Signal:%u, Rate:%u\n", - network_packet ? '*' : ' ', - le16_to_cpu(rx_hdr->channel), - rx_status.signal, rx_status.signal, - rx_status.rate_idx); - - iwl_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len), header); - - if (network_packet) { - priv->_3945.last_beacon_time = - le32_to_cpu(rx_end->beacon_timestamp); - priv->_3945.last_tsf = le64_to_cpu(rx_end->timestamp); - priv->_3945.last_rx_rssi = rx_status.signal; - } - - iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status); -} - -int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, - struct iwl_tx_queue *txq, - dma_addr_t addr, u16 len, u8 reset, u8 pad) -{ - int count; - struct iwl_queue *q; - struct iwl3945_tfd *tfd, *tfd_tmp; - - q = &txq->q; - tfd_tmp = (struct iwl3945_tfd *)txq->tfds; - tfd = &tfd_tmp[q->write_ptr]; - - if (reset) - memset(tfd, 0, sizeof(*tfd)); - - count = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags)); - - if ((count >= NUM_TFD_CHUNKS) || (count < 0)) { - IWL_ERR(priv, "Error can not send more than %d chunks\n", - NUM_TFD_CHUNKS); - return -EINVAL; - } - - tfd->tbs[count].addr = cpu_to_le32(addr); - tfd->tbs[count].len = cpu_to_le32(len); - - count++; - - tfd->control_flags = cpu_to_le32(TFD_CTL_COUNT_SET(count) | - TFD_CTL_PAD_SET(pad)); - - return 0; -} - -/** - * iwl3945_hw_txq_free_tfd - Free one TFD, those at index [txq->q.read_ptr] - * - * Does NOT advance any indexes - */ -void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) -{ - struct iwl3945_tfd *tfd_tmp = (struct iwl3945_tfd *)txq->tfds; - int index = txq->q.read_ptr; - struct iwl3945_tfd *tfd = &tfd_tmp[index]; - struct pci_dev *dev = priv->pci_dev; - int i; - int counter; - - /* sanity check */ - counter = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags)); - if (counter > NUM_TFD_CHUNKS) { - IWL_ERR(priv, "Too many chunks: %i\n", counter); - /* @todo issue fatal error, it is quite serious situation */ - return; - } - - /* Unmap tx_cmd */ - if (counter) - pci_unmap_single(dev, - dma_unmap_addr(&txq->meta[index], mapping), - dma_unmap_len(&txq->meta[index], len), - PCI_DMA_TODEVICE); - - /* unmap chunks if any */ - - for (i = 1; i < counter; i++) - pci_unmap_single(dev, le32_to_cpu(tfd->tbs[i].addr), - le32_to_cpu(tfd->tbs[i].len), PCI_DMA_TODEVICE); - - /* free SKB */ - if (txq->txb) { - struct sk_buff *skb; - - skb = txq->txb[txq->q.read_ptr].skb; - - /* can be called from irqs-disabled context */ - if (skb) { - dev_kfree_skb_any(skb); - txq->txb[txq->q.read_ptr].skb = NULL; - } - } -} - -/** - * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD: - * -*/ -void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, - struct iwl_device_cmd *cmd, - struct ieee80211_tx_info *info, - struct ieee80211_hdr *hdr, - int sta_id, int tx_id) -{ - u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value; - u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT_3945); - u16 rate_mask; - int rate; - u8 rts_retry_limit; - u8 data_retry_limit; - __le32 tx_flags; - __le16 fc = hdr->frame_control; - struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload; - - rate = iwl3945_rates[rate_index].plcp; - tx_flags = tx_cmd->tx_flags; - - /* We need to figure out how to get the sta->supp_rates while - * in this running context */ - rate_mask = IWL_RATES_MASK_3945; - - /* Set retry limit on DATA packets and Probe Responses*/ - if (ieee80211_is_probe_resp(fc)) - data_retry_limit = 3; - else - data_retry_limit = IWL_DEFAULT_TX_RETRY; - tx_cmd->data_retry_limit = data_retry_limit; - - if (tx_id >= IWL39_CMD_QUEUE_NUM) - rts_retry_limit = 3; - else - rts_retry_limit = 7; - - if (data_retry_limit < rts_retry_limit) - rts_retry_limit = data_retry_limit; - tx_cmd->rts_retry_limit = rts_retry_limit; - - tx_cmd->rate = rate; - tx_cmd->tx_flags = tx_flags; - - /* OFDM */ - tx_cmd->supp_rates[0] = - ((rate_mask & IWL_OFDM_RATES_MASK) >> IWL_FIRST_OFDM_RATE) & 0xFF; - - /* CCK */ - tx_cmd->supp_rates[1] = (rate_mask & 0xF); - - IWL_DEBUG_RATE(priv, "Tx sta id: %d, rate: %d (plcp), flags: 0x%4X " - "cck/ofdm mask: 0x%x/0x%x\n", sta_id, - tx_cmd->rate, le32_to_cpu(tx_cmd->tx_flags), - tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]); -} - -static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate) -{ - unsigned long flags_spin; - struct iwl_station_entry *station; - - if (sta_id == IWL_INVALID_STATION) - return IWL_INVALID_STATION; - - spin_lock_irqsave(&priv->sta_lock, flags_spin); - station = &priv->stations[sta_id]; - - station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK; - station->sta.rate_n_flags = cpu_to_le16(tx_rate); - station->sta.mode = STA_CONTROL_MODIFY_MSK; - iwl_send_add_sta(priv, &station->sta, CMD_ASYNC); - spin_unlock_irqrestore(&priv->sta_lock, flags_spin); - - IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n", - sta_id, tx_rate); - return sta_id; -} - -static void iwl3945_set_pwr_vmain(struct iwl_priv *priv) -{ -/* - * (for documentation purposes) - * to set power to V_AUX, do - - if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) { - iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, - APMG_PS_CTRL_VAL_PWR_SRC_VAUX, - ~APMG_PS_CTRL_MSK_PWR_SRC); - - iwl_poll_bit(priv, CSR_GPIO_IN, - CSR_GPIO_IN_VAL_VAUX_PWR_SRC, - CSR_GPIO_IN_BIT_AUX_POWER, 5000); - } - */ - - iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, - APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, - ~APMG_PS_CTRL_MSK_PWR_SRC); - - iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC, - CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */ -} - -static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) -{ - iwl_write_direct32(priv, FH39_RCSR_RBD_BASE(0), rxq->bd_dma); - iwl_write_direct32(priv, FH39_RCSR_RPTR_ADDR(0), rxq->rb_stts_dma); - iwl_write_direct32(priv, FH39_RCSR_WPTR(0), 0); - iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), - FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE | - FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE | - FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN | - FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 | - (RX_QUEUE_SIZE_LOG << FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE) | - FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST | - (1 << FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH) | - FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH); - - /* fake read to flush all prev I/O */ - iwl_read_direct32(priv, FH39_RSSR_CTRL); - - return 0; -} - -static int iwl3945_tx_reset(struct iwl_priv *priv) -{ - - /* bypass mode */ - iwl_write_prph(priv, ALM_SCD_MODE_REG, 0x2); - - /* RA 0 is active */ - iwl_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01); - - /* all 6 fifo are active */ - iwl_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f); - - iwl_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000); - iwl_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002); - iwl_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004); - iwl_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005); - - iwl_write_direct32(priv, FH39_TSSR_CBB_BASE, - priv->_3945.shared_phys); - - iwl_write_direct32(priv, FH39_TSSR_MSG_CONFIG, - FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON | - FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON | - FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B | - FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON | - FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON | - FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH | - FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH); - - - return 0; -} - -/** - * iwl3945_txq_ctx_reset - Reset TX queue context - * - * Destroys all DMA structures and initialize them again - */ -static int iwl3945_txq_ctx_reset(struct iwl_priv *priv) -{ - int rc; - int txq_id, slots_num; - - iwl3945_hw_txq_ctx_free(priv); - - /* allocate tx queue structure */ - rc = iwl_alloc_txq_mem(priv); - if (rc) - return rc; - - /* Tx CMD queue */ - rc = iwl3945_tx_reset(priv); - if (rc) - goto error; - - /* Tx queue(s) */ - for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { - slots_num = (txq_id == IWL39_CMD_QUEUE_NUM) ? - TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; - rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num, - txq_id); - if (rc) { - IWL_ERR(priv, "Tx %d queue init failed\n", txq_id); - goto error; - } - } - - return rc; - - error: - iwl3945_hw_txq_ctx_free(priv); - return rc; -} - - -/* - * Start up 3945's basic functionality after it has been reset - * (e.g. after platform boot, or shutdown via iwl_apm_stop()) - * NOTE: This does not load uCode nor start the embedded processor - */ -static int iwl3945_apm_init(struct iwl_priv *priv) -{ - int ret = iwl_apm_init(priv); - - /* Clear APMG (NIC's internal power management) interrupts */ - iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0); - iwl_write_prph(priv, APMG_RTC_INT_STT_REG, 0xFFFFFFFF); - - /* Reset radio chip */ - iwl_set_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); - udelay(5); - iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); - - return ret; -} - -static void iwl3945_nic_config(struct iwl_priv *priv) -{ - struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; - unsigned long flags; - u8 rev_id = 0; - - spin_lock_irqsave(&priv->lock, flags); - - /* Determine HW type */ - pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id); - - IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); - - if (rev_id & PCI_CFG_REV_ID_BIT_RTP) - IWL_DEBUG_INFO(priv, "RTP type\n"); - else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) { - IWL_DEBUG_INFO(priv, "3945 RADIO-MB type\n"); - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR39_HW_IF_CONFIG_REG_BIT_3945_MB); - } else { - IWL_DEBUG_INFO(priv, "3945 RADIO-MM type\n"); - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR39_HW_IF_CONFIG_REG_BIT_3945_MM); - } - - if (EEPROM_SKU_CAP_OP_MODE_MRC == eeprom->sku_cap) { - IWL_DEBUG_INFO(priv, "SKU OP mode is mrc\n"); - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC); - } else - IWL_DEBUG_INFO(priv, "SKU OP mode is basic\n"); - - if ((eeprom->board_revision & 0xF0) == 0xD0) { - IWL_DEBUG_INFO(priv, "3945ABG revision is 0x%X\n", - eeprom->board_revision); - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE); - } else { - IWL_DEBUG_INFO(priv, "3945ABG revision is 0x%X\n", - eeprom->board_revision); - iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE); - } - - if (eeprom->almgor_m_version <= 1) { - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A); - IWL_DEBUG_INFO(priv, "Card M type A version is 0x%X\n", - eeprom->almgor_m_version); - } else { - IWL_DEBUG_INFO(priv, "Card M type B version is 0x%X\n", - eeprom->almgor_m_version); - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B); - } - spin_unlock_irqrestore(&priv->lock, flags); - - if (eeprom->sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE) - IWL_DEBUG_RF_KILL(priv, "SW RF KILL supported in EEPROM.\n"); - - if (eeprom->sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE) - IWL_DEBUG_RF_KILL(priv, "HW RF KILL supported in EEPROM.\n"); -} - -int iwl3945_hw_nic_init(struct iwl_priv *priv) -{ - int rc; - unsigned long flags; - struct iwl_rx_queue *rxq = &priv->rxq; - - spin_lock_irqsave(&priv->lock, flags); - priv->cfg->ops->lib->apm_ops.init(priv); - spin_unlock_irqrestore(&priv->lock, flags); - - iwl3945_set_pwr_vmain(priv); - - priv->cfg->ops->lib->apm_ops.config(priv); - - /* Allocate the RX queue, or reset if it is already allocated */ - if (!rxq->bd) { - rc = iwl_rx_queue_alloc(priv); - if (rc) { - IWL_ERR(priv, "Unable to initialize Rx queue\n"); - return -ENOMEM; - } - } else - iwl3945_rx_queue_reset(priv, rxq); - - iwl3945_rx_replenish(priv); - - iwl3945_rx_init(priv, rxq); - - - /* Look at using this instead: - rxq->need_update = 1; - iwl_rx_queue_update_write_ptr(priv, rxq); - */ - - iwl_write_direct32(priv, FH39_RCSR_WPTR(0), rxq->write & ~7); - - rc = iwl3945_txq_ctx_reset(priv); - if (rc) - return rc; - - set_bit(STATUS_INIT, &priv->status); - - return 0; -} - -/** - * iwl3945_hw_txq_ctx_free - Free TXQ Context - * - * Destroy all TX DMA queues and structures - */ -void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv) -{ - int txq_id; - - /* Tx queues */ - if (priv->txq) - for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; - txq_id++) - if (txq_id == IWL39_CMD_QUEUE_NUM) - iwl_cmd_queue_free(priv); - else - iwl_tx_queue_free(priv, txq_id); - - /* free tx queue structure */ - iwl_free_txq_mem(priv); -} - -void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv) -{ - int txq_id; - - /* stop SCD */ - iwl_write_prph(priv, ALM_SCD_MODE_REG, 0); - iwl_write_prph(priv, ALM_SCD_TXFACT_REG, 0); - - /* reset TFD queues */ - for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { - iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), 0x0); - iwl_poll_direct_bit(priv, FH39_TSSR_TX_STATUS, - FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id), - 1000); - } - - iwl3945_hw_txq_ctx_free(priv); -} - -/** - * iwl3945_hw_reg_adjust_power_by_temp - * return index delta into power gain settings table -*/ -static int iwl3945_hw_reg_adjust_power_by_temp(int new_reading, int old_reading) -{ - return (new_reading - old_reading) * (-11) / 100; -} - -/** - * iwl3945_hw_reg_temp_out_of_range - Keep temperature in sane range - */ -static inline int iwl3945_hw_reg_temp_out_of_range(int temperature) -{ - return ((temperature < -260) || (temperature > 25)) ? 1 : 0; -} - -int iwl3945_hw_get_temperature(struct iwl_priv *priv) -{ - return iwl_read32(priv, CSR_UCODE_DRV_GP2); -} - -/** - * iwl3945_hw_reg_txpower_get_temperature - * get the current temperature by reading from NIC -*/ -static int iwl3945_hw_reg_txpower_get_temperature(struct iwl_priv *priv) -{ - struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; - int temperature; - - temperature = iwl3945_hw_get_temperature(priv); - - /* driver's okay range is -260 to +25. - * human readable okay range is 0 to +285 */ - IWL_DEBUG_INFO(priv, "Temperature: %d\n", temperature + IWL_TEMP_CONVERT); - - /* handle insane temp reading */ - if (iwl3945_hw_reg_temp_out_of_range(temperature)) { - IWL_ERR(priv, "Error bad temperature value %d\n", temperature); - - /* if really really hot(?), - * substitute the 3rd band/group's temp measured at factory */ - if (priv->last_temperature > 100) - temperature = eeprom->groups[2].temperature; - else /* else use most recent "sane" value from driver */ - temperature = priv->last_temperature; - } - - return temperature; /* raw, not "human readable" */ -} - -/* Adjust Txpower only if temperature variance is greater than threshold. - * - * Both are lower than older versions' 9 degrees */ -#define IWL_TEMPERATURE_LIMIT_TIMER 6 - -/** - * is_temp_calib_needed - determines if new calibration is needed - * - * records new temperature in tx_mgr->temperature. - * replaces tx_mgr->last_temperature *only* if calib needed - * (assumes caller will actually do the calibration!). */ -static int is_temp_calib_needed(struct iwl_priv *priv) -{ - int temp_diff; - - priv->temperature = iwl3945_hw_reg_txpower_get_temperature(priv); - temp_diff = priv->temperature - priv->last_temperature; - - /* get absolute value */ - if (temp_diff < 0) { - IWL_DEBUG_POWER(priv, "Getting cooler, delta %d,\n", temp_diff); - temp_diff = -temp_diff; - } else if (temp_diff == 0) - IWL_DEBUG_POWER(priv, "Same temp,\n"); - else - IWL_DEBUG_POWER(priv, "Getting warmer, delta %d,\n", temp_diff); - - /* if we don't need calibration, *don't* update last_temperature */ - if (temp_diff < IWL_TEMPERATURE_LIMIT_TIMER) { - IWL_DEBUG_POWER(priv, "Timed thermal calib not needed\n"); - return 0; - } - - IWL_DEBUG_POWER(priv, "Timed thermal calib needed\n"); - - /* assume that caller will actually do calib ... - * update the "last temperature" value */ - priv->last_temperature = priv->temperature; - return 1; -} - -#define IWL_MAX_GAIN_ENTRIES 78 -#define IWL_CCK_FROM_OFDM_POWER_DIFF -5 -#define IWL_CCK_FROM_OFDM_INDEX_DIFF (10) - -/* radio and DSP power table, each step is 1/2 dB. - * 1st number is for RF analog gain, 2nd number is for DSP pre-DAC gain. */ -static struct iwl3945_tx_power power_gain_table[2][IWL_MAX_GAIN_ENTRIES] = { - { - {251, 127}, /* 2.4 GHz, highest power */ - {251, 127}, - {251, 127}, - {251, 127}, - {251, 125}, - {251, 110}, - {251, 105}, - {251, 98}, - {187, 125}, - {187, 115}, - {187, 108}, - {187, 99}, - {243, 119}, - {243, 111}, - {243, 105}, - {243, 97}, - {243, 92}, - {211, 106}, - {211, 100}, - {179, 120}, - {179, 113}, - {179, 107}, - {147, 125}, - {147, 119}, - {147, 112}, - {147, 106}, - {147, 101}, - {147, 97}, - {147, 91}, - {115, 107}, - {235, 121}, - {235, 115}, - {235, 109}, - {203, 127}, - {203, 121}, - {203, 115}, - {203, 108}, - {203, 102}, - {203, 96}, - {203, 92}, - {171, 110}, - {171, 104}, - {171, 98}, - {139, 116}, - {227, 125}, - {227, 119}, - {227, 113}, - {227, 107}, - {227, 101}, - {227, 96}, - {195, 113}, - {195, 106}, - {195, 102}, - {195, 95}, - {163, 113}, - {163, 106}, - {163, 102}, - {163, 95}, - {131, 113}, - {131, 106}, - {131, 102}, - {131, 95}, - {99, 113}, - {99, 106}, - {99, 102}, - {99, 95}, - {67, 113}, - {67, 106}, - {67, 102}, - {67, 95}, - {35, 113}, - {35, 106}, - {35, 102}, - {35, 95}, - {3, 113}, - {3, 106}, - {3, 102}, - {3, 95} }, /* 2.4 GHz, lowest power */ - { - {251, 127}, /* 5.x GHz, highest power */ - {251, 120}, - {251, 114}, - {219, 119}, - {219, 101}, - {187, 113}, - {187, 102}, - {155, 114}, - {155, 103}, - {123, 117}, - {123, 107}, - {123, 99}, - {123, 92}, - {91, 108}, - {59, 125}, - {59, 118}, - {59, 109}, - {59, 102}, - {59, 96}, - {59, 90}, - {27, 104}, - {27, 98}, - {27, 92}, - {115, 118}, - {115, 111}, - {115, 104}, - {83, 126}, - {83, 121}, - {83, 113}, - {83, 105}, - {83, 99}, - {51, 118}, - {51, 111}, - {51, 104}, - {51, 98}, - {19, 116}, - {19, 109}, - {19, 102}, - {19, 98}, - {19, 93}, - {171, 113}, - {171, 107}, - {171, 99}, - {139, 120}, - {139, 113}, - {139, 107}, - {139, 99}, - {107, 120}, - {107, 113}, - {107, 107}, - {107, 99}, - {75, 120}, - {75, 113}, - {75, 107}, - {75, 99}, - {43, 120}, - {43, 113}, - {43, 107}, - {43, 99}, - {11, 120}, - {11, 113}, - {11, 107}, - {11, 99}, - {131, 107}, - {131, 99}, - {99, 120}, - {99, 113}, - {99, 107}, - {99, 99}, - {67, 120}, - {67, 113}, - {67, 107}, - {67, 99}, - {35, 120}, - {35, 113}, - {35, 107}, - {35, 99}, - {3, 120} } /* 5.x GHz, lowest power */ -}; - -static inline u8 iwl3945_hw_reg_fix_power_index(int index) -{ - if (index < 0) - return 0; - if (index >= IWL_MAX_GAIN_ENTRIES) - return IWL_MAX_GAIN_ENTRIES - 1; - return (u8) index; -} - -/* Kick off thermal recalibration check every 60 seconds */ -#define REG_RECALIB_PERIOD (60) - -/** - * iwl3945_hw_reg_set_scan_power - Set Tx power for scan probe requests - * - * Set (in our channel info database) the direct scan Tx power for 1 Mbit (CCK) - * or 6 Mbit (OFDM) rates. - */ -static void iwl3945_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index, - s32 rate_index, const s8 *clip_pwrs, - struct iwl_channel_info *ch_info, - int band_index) -{ - struct iwl3945_scan_power_info *scan_power_info; - s8 power; - u8 power_index; - - scan_power_info = &ch_info->scan_pwr_info[scan_tbl_index]; - - /* use this channel group's 6Mbit clipping/saturation pwr, - * but cap at regulatory scan power restriction (set during init - * based on eeprom channel data) for this channel. */ - power = min(ch_info->scan_power, clip_pwrs[IWL_RATE_6M_INDEX_TABLE]); - - /* further limit to user's max power preference. - * FIXME: Other spectrum management power limitations do not - * seem to apply?? */ - power = min(power, priv->tx_power_user_lmt); - scan_power_info->requested_power = power; - - /* find difference between new scan *power* and current "normal" - * Tx *power* for 6Mb. Use this difference (x2) to adjust the - * current "normal" temperature-compensated Tx power *index* for - * this rate (1Mb or 6Mb) to yield new temp-compensated scan power - * *index*. */ - power_index = ch_info->power_info[rate_index].power_table_index - - (power - ch_info->power_info - [IWL_RATE_6M_INDEX_TABLE].requested_power) * 2; - - /* store reference index that we use when adjusting *all* scan - * powers. So we can accommodate user (all channel) or spectrum - * management (single channel) power changes "between" temperature - * feedback compensation procedures. - * don't force fit this reference index into gain table; it may be a - * negative number. This will help avoid errors when we're at - * the lower bounds (highest gains, for warmest temperatures) - * of the table. */ - - /* don't exceed table bounds for "real" setting */ - power_index = iwl3945_hw_reg_fix_power_index(power_index); - - scan_power_info->power_table_index = power_index; - scan_power_info->tpc.tx_gain = - power_gain_table[band_index][power_index].tx_gain; - scan_power_info->tpc.dsp_atten = - power_gain_table[band_index][power_index].dsp_atten; -} - -/** - * iwl3945_send_tx_power - fill in Tx Power command with gain settings - * - * Configures power settings for all rates for the current channel, - * using values from channel info struct, and send to NIC - */ -static int iwl3945_send_tx_power(struct iwl_priv *priv) -{ - int rate_idx, i; - const struct iwl_channel_info *ch_info = NULL; - struct iwl3945_txpowertable_cmd txpower = { - .channel = priv->contexts[IWL_RXON_CTX_BSS].active.channel, - }; - u16 chan; - - if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status), - "TX Power requested while scanning!\n")) - return -EAGAIN; - - chan = le16_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.channel); - - txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1; - ch_info = iwl_get_channel_info(priv, priv->band, chan); - if (!ch_info) { - IWL_ERR(priv, - "Failed to get channel info for channel %d [%d]\n", - chan, priv->band); - return -EINVAL; - } - - if (!is_channel_valid(ch_info)) { - IWL_DEBUG_POWER(priv, "Not calling TX_PWR_TABLE_CMD on " - "non-Tx channel.\n"); - return 0; - } - - /* fill cmd with power settings for all rates for current channel */ - /* Fill OFDM rate */ - for (rate_idx = IWL_FIRST_OFDM_RATE, i = 0; - rate_idx <= IWL39_LAST_OFDM_RATE; rate_idx++, i++) { - - txpower.power[i].tpc = ch_info->power_info[i].tpc; - txpower.power[i].rate = iwl3945_rates[rate_idx].plcp; - - IWL_DEBUG_POWER(priv, "ch %d:%d rf %d dsp %3d rate code 0x%02x\n", - le16_to_cpu(txpower.channel), - txpower.band, - txpower.power[i].tpc.tx_gain, - txpower.power[i].tpc.dsp_atten, - txpower.power[i].rate); - } - /* Fill CCK rates */ - for (rate_idx = IWL_FIRST_CCK_RATE; - rate_idx <= IWL_LAST_CCK_RATE; rate_idx++, i++) { - txpower.power[i].tpc = ch_info->power_info[i].tpc; - txpower.power[i].rate = iwl3945_rates[rate_idx].plcp; - - IWL_DEBUG_POWER(priv, "ch %d:%d rf %d dsp %3d rate code 0x%02x\n", - le16_to_cpu(txpower.channel), - txpower.band, - txpower.power[i].tpc.tx_gain, - txpower.power[i].tpc.dsp_atten, - txpower.power[i].rate); - } - - return iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, - sizeof(struct iwl3945_txpowertable_cmd), - &txpower); - -} - -/** - * iwl3945_hw_reg_set_new_power - Configures power tables at new levels - * @ch_info: Channel to update. Uses power_info.requested_power. - * - * Replace requested_power and base_power_index ch_info fields for - * one channel. - * - * Called if user or spectrum management changes power preferences. - * Takes into account h/w and modulation limitations (clip power). - * - * This does *not* send anything to NIC, just sets up ch_info for one channel. - * - * NOTE: reg_compensate_for_temperature_dif() *must* be run after this to - * properly fill out the scan powers, and actual h/w gain settings, - * and send changes to NIC - */ -static int iwl3945_hw_reg_set_new_power(struct iwl_priv *priv, - struct iwl_channel_info *ch_info) -{ - struct iwl3945_channel_power_info *power_info; - int power_changed = 0; - int i; - const s8 *clip_pwrs; - int power; - - /* Get this chnlgrp's rate-to-max/clip-powers table */ - clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers; - - /* Get this channel's rate-to-current-power settings table */ - power_info = ch_info->power_info; - - /* update OFDM Txpower settings */ - for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; - i++, ++power_info) { - int delta_idx; - - /* limit new power to be no more than h/w capability */ - power = min(ch_info->curr_txpow, clip_pwrs[i]); - if (power == power_info->requested_power) - continue; - - /* find difference between old and new requested powers, - * update base (non-temp-compensated) power index */ - delta_idx = (power - power_info->requested_power) * 2; - power_info->base_power_index -= delta_idx; - - /* save new requested power value */ - power_info->requested_power = power; - - power_changed = 1; - } - - /* update CCK Txpower settings, based on OFDM 12M setting ... - * ... all CCK power settings for a given channel are the *same*. */ - if (power_changed) { - power = - ch_info->power_info[IWL_RATE_12M_INDEX_TABLE]. - requested_power + IWL_CCK_FROM_OFDM_POWER_DIFF; - - /* do all CCK rates' iwl3945_channel_power_info structures */ - for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++) { - power_info->requested_power = power; - power_info->base_power_index = - ch_info->power_info[IWL_RATE_12M_INDEX_TABLE]. - base_power_index + IWL_CCK_FROM_OFDM_INDEX_DIFF; - ++power_info; - } - } - - return 0; -} - -/** - * iwl3945_hw_reg_get_ch_txpower_limit - returns new power limit for channel - * - * NOTE: Returned power limit may be less (but not more) than requested, - * based strictly on regulatory (eeprom and spectrum mgt) limitations - * (no consideration for h/w clipping limitations). - */ -static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl_channel_info *ch_info) -{ - s8 max_power; - -#if 0 - /* if we're using TGd limits, use lower of TGd or EEPROM */ - if (ch_info->tgd_data.max_power != 0) - max_power = min(ch_info->tgd_data.max_power, - ch_info->eeprom.max_power_avg); - - /* else just use EEPROM limits */ - else -#endif - max_power = ch_info->eeprom.max_power_avg; - - return min(max_power, ch_info->max_power_avg); -} - -/** - * iwl3945_hw_reg_comp_txpower_temp - Compensate for temperature - * - * Compensate txpower settings of *all* channels for temperature. - * This only accounts for the difference between current temperature - * and the factory calibration temperatures, and bases the new settings - * on the channel's base_power_index. - * - * If RxOn is "associated", this sends the new Txpower to NIC! - */ -static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv) -{ - struct iwl_channel_info *ch_info = NULL; - struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; - int delta_index; - const s8 *clip_pwrs; /* array of h/w max power levels for each rate */ - u8 a_band; - u8 rate_index; - u8 scan_tbl_index; - u8 i; - int ref_temp; - int temperature = priv->temperature; - - if (priv->disable_tx_power_cal || - test_bit(STATUS_SCANNING, &priv->status)) { - /* do not perform tx power calibration */ - return 0; - } - /* set up new Tx power info for each and every channel, 2.4 and 5.x */ - for (i = 0; i < priv->channel_count; i++) { - ch_info = &priv->channel_info[i]; - a_band = is_channel_a_band(ch_info); - - /* Get this chnlgrp's factory calibration temperature */ - ref_temp = (s16)eeprom->groups[ch_info->group_index]. - temperature; - - /* get power index adjustment based on current and factory - * temps */ - delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature, - ref_temp); - - /* set tx power value for all rates, OFDM and CCK */ - for (rate_index = 0; rate_index < IWL_RATE_COUNT_3945; - rate_index++) { - int power_idx = - ch_info->power_info[rate_index].base_power_index; - - /* temperature compensate */ - power_idx += delta_index; - - /* stay within table range */ - power_idx = iwl3945_hw_reg_fix_power_index(power_idx); - ch_info->power_info[rate_index]. - power_table_index = (u8) power_idx; - ch_info->power_info[rate_index].tpc = - power_gain_table[a_band][power_idx]; - } - - /* Get this chnlgrp's rate-to-max/clip-powers table */ - clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers; - - /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */ - for (scan_tbl_index = 0; - scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) { - s32 actual_index = (scan_tbl_index == 0) ? - IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE; - iwl3945_hw_reg_set_scan_power(priv, scan_tbl_index, - actual_index, clip_pwrs, - ch_info, a_band); - } - } - - /* send Txpower command for current channel to ucode */ - return priv->cfg->ops->lib->send_tx_power(priv); -} - -int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power) -{ - struct iwl_channel_info *ch_info; - s8 max_power; - u8 a_band; - u8 i; - - if (priv->tx_power_user_lmt == power) { - IWL_DEBUG_POWER(priv, "Requested Tx power same as current " - "limit: %ddBm.\n", power); - return 0; - } - - IWL_DEBUG_POWER(priv, "Setting upper limit clamp to %ddBm.\n", power); - priv->tx_power_user_lmt = power; - - /* set up new Tx powers for each and every channel, 2.4 and 5.x */ - - for (i = 0; i < priv->channel_count; i++) { - ch_info = &priv->channel_info[i]; - a_band = is_channel_a_band(ch_info); - - /* find minimum power of all user and regulatory constraints - * (does not consider h/w clipping limitations) */ - max_power = iwl3945_hw_reg_get_ch_txpower_limit(ch_info); - max_power = min(power, max_power); - if (max_power != ch_info->curr_txpow) { - ch_info->curr_txpow = max_power; - - /* this considers the h/w clipping limitations */ - iwl3945_hw_reg_set_new_power(priv, ch_info); - } - } - - /* update txpower settings for all channels, - * send to NIC if associated. */ - is_temp_calib_needed(priv); - iwl3945_hw_reg_comp_txpower_temp(priv); - - return 0; -} - -static int iwl3945_send_rxon_assoc(struct iwl_priv *priv, - struct iwl_rxon_context *ctx) -{ - int rc = 0; - struct iwl_rx_packet *pkt; - struct iwl3945_rxon_assoc_cmd rxon_assoc; - struct iwl_host_cmd cmd = { - .id = REPLY_RXON_ASSOC, - .len = sizeof(rxon_assoc), - .flags = CMD_WANT_SKB, - .data = &rxon_assoc, - }; - const struct iwl_rxon_cmd *rxon1 = &ctx->staging; - const struct iwl_rxon_cmd *rxon2 = &ctx->active; - - if ((rxon1->flags == rxon2->flags) && - (rxon1->filter_flags == rxon2->filter_flags) && - (rxon1->cck_basic_rates == rxon2->cck_basic_rates) && - (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) { - IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n"); - return 0; - } - - rxon_assoc.flags = ctx->staging.flags; - rxon_assoc.filter_flags = ctx->staging.filter_flags; - rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; - rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; - rxon_assoc.reserved = 0; - - rc = iwl_send_cmd_sync(priv, &cmd); - if (rc) - return rc; - - pkt = (struct iwl_rx_packet *)cmd.reply_page; - if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { - IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n"); - rc = -EIO; - } - - iwl_free_pages(priv, cmd.reply_page); - - return rc; -} - -/** - * iwl3945_commit_rxon - commit staging_rxon to hardware - * - * The RXON command in staging_rxon is committed to the hardware and - * the active_rxon structure is updated with the new data. This - * function correctly transitions out of the RXON_ASSOC_MSK state if - * a HW tune is required based on the RXON structure changes. - */ -int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) -{ - /* cast away the const for active_rxon in this function */ - struct iwl3945_rxon_cmd *active_rxon = (void *)&ctx->active; - struct iwl3945_rxon_cmd *staging_rxon = (void *)&ctx->staging; - int rc = 0; - bool new_assoc = !!(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return -EINVAL; - - if (!iwl_is_alive(priv)) - return -1; - - /* always get timestamp with Rx frame */ - staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK; - - /* select antenna */ - staging_rxon->flags &= - ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK); - staging_rxon->flags |= iwl3945_get_antenna_flags(priv); - - rc = iwl_check_rxon_cmd(priv, ctx); - if (rc) { - IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); - return -EINVAL; - } - - /* If we don't need to send a full RXON, we can use - * iwl3945_rxon_assoc_cmd which is used to reconfigure filter - * and other flags for the current radio configuration. */ - if (!iwl_full_rxon_required(priv, &priv->contexts[IWL_RXON_CTX_BSS])) { - rc = iwl_send_rxon_assoc(priv, - &priv->contexts[IWL_RXON_CTX_BSS]); - if (rc) { - IWL_ERR(priv, "Error setting RXON_ASSOC " - "configuration (%d).\n", rc); - return rc; - } - - memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); - - return 0; - } - - /* If we are currently associated and the new config requires - * an RXON_ASSOC and the new config wants the associated mask enabled, - * we must clear the associated from the active configuration - * before we apply the new config */ - if (iwl_is_associated(priv, IWL_RXON_CTX_BSS) && new_assoc) { - IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); - active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - - /* - * reserved4 and 5 could have been filled by the iwlcore code. - * Let's clear them before pushing to the 3945. - */ - active_rxon->reserved4 = 0; - active_rxon->reserved5 = 0; - rc = iwl_send_cmd_pdu(priv, REPLY_RXON, - sizeof(struct iwl3945_rxon_cmd), - &priv->contexts[IWL_RXON_CTX_BSS].active); - - /* If the mask clearing failed then we set - * active_rxon back to what it was previously */ - if (rc) { - active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; - IWL_ERR(priv, "Error clearing ASSOC_MSK on current " - "configuration (%d).\n", rc); - return rc; - } - iwl_clear_ucode_stations(priv, - &priv->contexts[IWL_RXON_CTX_BSS]); - iwl_restore_stations(priv, &priv->contexts[IWL_RXON_CTX_BSS]); - } - - IWL_DEBUG_INFO(priv, "Sending RXON\n" - "* with%s RXON_FILTER_ASSOC_MSK\n" - "* channel = %d\n" - "* bssid = %pM\n", - (new_assoc ? "" : "out"), - le16_to_cpu(staging_rxon->channel), - staging_rxon->bssid_addr); - - /* - * reserved4 and 5 could have been filled by the iwlcore code. - * Let's clear them before pushing to the 3945. - */ - staging_rxon->reserved4 = 0; - staging_rxon->reserved5 = 0; - - iwl_set_rxon_hwcrypto(priv, ctx, !iwl3945_mod_params.sw_crypto); - - /* Apply the new configuration */ - rc = iwl_send_cmd_pdu(priv, REPLY_RXON, - sizeof(struct iwl3945_rxon_cmd), - staging_rxon); - if (rc) { - IWL_ERR(priv, "Error setting new configuration (%d).\n", rc); - return rc; - } - - memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); - - if (!new_assoc) { - iwl_clear_ucode_stations(priv, - &priv->contexts[IWL_RXON_CTX_BSS]); - iwl_restore_stations(priv, &priv->contexts[IWL_RXON_CTX_BSS]); - } - - /* If we issue a new RXON command which required a tune then we must - * send a new TXPOWER command or we won't be able to Tx any frames */ - rc = iwl_set_tx_power(priv, priv->tx_power_next, true); - if (rc) { - IWL_ERR(priv, "Error setting Tx power (%d).\n", rc); - return rc; - } - - /* Init the hardware's rate fallback order based on the band */ - rc = iwl3945_init_hw_rate_table(priv); - if (rc) { - IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc); - return -EIO; - } - - return 0; -} - -/** - * iwl3945_reg_txpower_periodic - called when time to check our temperature. - * - * -- reset periodic timer - * -- see if temp has changed enough to warrant re-calibration ... if so: - * -- correct coeffs for temp (can reset temp timer) - * -- save this temp as "last", - * -- send new set of gain settings to NIC - * NOTE: This should continue working, even when we're not associated, - * so we can keep our internal table of scan powers current. */ -void iwl3945_reg_txpower_periodic(struct iwl_priv *priv) -{ - /* This will kick in the "brute force" - * iwl3945_hw_reg_comp_txpower_temp() below */ - if (!is_temp_calib_needed(priv)) - goto reschedule; - - /* Set up a new set of temp-adjusted TxPowers, send to NIC. - * This is based *only* on current temperature, - * ignoring any previous power measurements */ - iwl3945_hw_reg_comp_txpower_temp(priv); - - reschedule: - queue_delayed_work(priv->workqueue, - &priv->_3945.thermal_periodic, REG_RECALIB_PERIOD * HZ); -} - -static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work) -{ - struct iwl_priv *priv = container_of(work, struct iwl_priv, - _3945.thermal_periodic.work); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - mutex_lock(&priv->mutex); - iwl3945_reg_txpower_periodic(priv); - mutex_unlock(&priv->mutex); -} - -/** - * iwl3945_hw_reg_get_ch_grp_index - find the channel-group index (0-4) - * for the channel. - * - * This function is used when initializing channel-info structs. - * - * NOTE: These channel groups do *NOT* match the bands above! - * These channel groups are based on factory-tested channels; - * on A-band, EEPROM's "group frequency" entries represent the top - * channel in each group 1-4. Group 5 All B/G channels are in group 0. - */ -static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl_priv *priv, - const struct iwl_channel_info *ch_info) -{ - struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; - struct iwl3945_eeprom_txpower_group *ch_grp = &eeprom->groups[0]; - u8 group; - u16 group_index = 0; /* based on factory calib frequencies */ - u8 grp_channel; - - /* Find the group index for the channel ... don't use index 1(?) */ - if (is_channel_a_band(ch_info)) { - for (group = 1; group < 5; group++) { - grp_channel = ch_grp[group].group_channel; - if (ch_info->channel <= grp_channel) { - group_index = group; - break; - } - } - /* group 4 has a few channels *above* its factory cal freq */ - if (group == 5) - group_index = 4; - } else - group_index = 0; /* 2.4 GHz, group 0 */ - - IWL_DEBUG_POWER(priv, "Chnl %d mapped to grp %d\n", ch_info->channel, - group_index); - return group_index; -} - -/** - * iwl3945_hw_reg_get_matched_power_index - Interpolate to get nominal index - * - * Interpolate to get nominal (i.e. at factory calibration temperature) index - * into radio/DSP gain settings table for requested power. - */ -static int iwl3945_hw_reg_get_matched_power_index(struct iwl_priv *priv, - s8 requested_power, - s32 setting_index, s32 *new_index) -{ - const struct iwl3945_eeprom_txpower_group *chnl_grp = NULL; - struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; - s32 index0, index1; - s32 power = 2 * requested_power; - s32 i; - const struct iwl3945_eeprom_txpower_sample *samples; - s32 gains0, gains1; - s32 res; - s32 denominator; - - chnl_grp = &eeprom->groups[setting_index]; - samples = chnl_grp->samples; - for (i = 0; i < 5; i++) { - if (power == samples[i].power) { - *new_index = samples[i].gain_index; - return 0; - } - } - - if (power > samples[1].power) { - index0 = 0; - index1 = 1; - } else if (power > samples[2].power) { - index0 = 1; - index1 = 2; - } else if (power > samples[3].power) { - index0 = 2; - index1 = 3; - } else { - index0 = 3; - index1 = 4; - } - - denominator = (s32) samples[index1].power - (s32) samples[index0].power; - if (denominator == 0) - return -EINVAL; - gains0 = (s32) samples[index0].gain_index * (1 << 19); - gains1 = (s32) samples[index1].gain_index * (1 << 19); - res = gains0 + (gains1 - gains0) * - ((s32) power - (s32) samples[index0].power) / denominator + - (1 << 18); - *new_index = res >> 19; - return 0; -} - -static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv) -{ - u32 i; - s32 rate_index; - struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; - const struct iwl3945_eeprom_txpower_group *group; - - IWL_DEBUG_POWER(priv, "Initializing factory calib info from EEPROM\n"); - - for (i = 0; i < IWL_NUM_TX_CALIB_GROUPS; i++) { - s8 *clip_pwrs; /* table of power levels for each rate */ - s8 satur_pwr; /* saturation power for each chnl group */ - group = &eeprom->groups[i]; - - /* sanity check on factory saturation power value */ - if (group->saturation_power < 40) { - IWL_WARN(priv, "Error: saturation power is %d, " - "less than minimum expected 40\n", - group->saturation_power); - return; - } - - /* - * Derive requested power levels for each rate, based on - * hardware capabilities (saturation power for band). - * Basic value is 3dB down from saturation, with further - * power reductions for highest 3 data rates. These - * backoffs provide headroom for high rate modulation - * power peaks, without too much distortion (clipping). - */ - /* we'll fill in this array with h/w max power levels */ - clip_pwrs = (s8 *) priv->_3945.clip_groups[i].clip_powers; - - /* divide factory saturation power by 2 to find -3dB level */ - satur_pwr = (s8) (group->saturation_power >> 1); - - /* fill in channel group's nominal powers for each rate */ - for (rate_index = 0; - rate_index < IWL_RATE_COUNT_3945; rate_index++, clip_pwrs++) { - switch (rate_index) { - case IWL_RATE_36M_INDEX_TABLE: - if (i == 0) /* B/G */ - *clip_pwrs = satur_pwr; - else /* A */ - *clip_pwrs = satur_pwr - 5; - break; - case IWL_RATE_48M_INDEX_TABLE: - if (i == 0) - *clip_pwrs = satur_pwr - 7; - else - *clip_pwrs = satur_pwr - 10; - break; - case IWL_RATE_54M_INDEX_TABLE: - if (i == 0) - *clip_pwrs = satur_pwr - 9; - else - *clip_pwrs = satur_pwr - 12; - break; - default: - *clip_pwrs = satur_pwr; - break; - } - } - } -} - -/** - * iwl3945_txpower_set_from_eeprom - Set channel power info based on EEPROM - * - * Second pass (during init) to set up priv->channel_info - * - * Set up Tx-power settings in our channel info database for each VALID - * (for this geo/SKU) channel, at all Tx data rates, based on eeprom values - * and current temperature. - * - * Since this is based on current temperature (at init time), these values may - * not be valid for very long, but it gives us a starting/default point, - * and allows us to active (i.e. using Tx) scan. - * - * This does *not* write values to NIC, just sets up our internal table. - */ -int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv) -{ - struct iwl_channel_info *ch_info = NULL; - struct iwl3945_channel_power_info *pwr_info; - struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; - int delta_index; - u8 rate_index; - u8 scan_tbl_index; - const s8 *clip_pwrs; /* array of power levels for each rate */ - u8 gain, dsp_atten; - s8 power; - u8 pwr_index, base_pwr_index, a_band; - u8 i; - int temperature; - - /* save temperature reference, - * so we can determine next time to calibrate */ - temperature = iwl3945_hw_reg_txpower_get_temperature(priv); - priv->last_temperature = temperature; - - iwl3945_hw_reg_init_channel_groups(priv); - - /* initialize Tx power info for each and every channel, 2.4 and 5.x */ - for (i = 0, ch_info = priv->channel_info; i < priv->channel_count; - i++, ch_info++) { - a_band = is_channel_a_band(ch_info); - if (!is_channel_valid(ch_info)) - continue; - - /* find this channel's channel group (*not* "band") index */ - ch_info->group_index = - iwl3945_hw_reg_get_ch_grp_index(priv, ch_info); - - /* Get this chnlgrp's rate->max/clip-powers table */ - clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers; - - /* calculate power index *adjustment* value according to - * diff between current temperature and factory temperature */ - delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature, - eeprom->groups[ch_info->group_index]. - temperature); - - IWL_DEBUG_POWER(priv, "Delta index for channel %d: %d [%d]\n", - ch_info->channel, delta_index, temperature + - IWL_TEMP_CONVERT); - - /* set tx power value for all OFDM rates */ - for (rate_index = 0; rate_index < IWL_OFDM_RATES; - rate_index++) { - s32 uninitialized_var(power_idx); - int rc; - - /* use channel group's clip-power table, - * but don't exceed channel's max power */ - s8 pwr = min(ch_info->max_power_avg, - clip_pwrs[rate_index]); - - pwr_info = &ch_info->power_info[rate_index]; - - /* get base (i.e. at factory-measured temperature) - * power table index for this rate's power */ - rc = iwl3945_hw_reg_get_matched_power_index(priv, pwr, - ch_info->group_index, - &power_idx); - if (rc) { - IWL_ERR(priv, "Invalid power index\n"); - return rc; - } - pwr_info->base_power_index = (u8) power_idx; - - /* temperature compensate */ - power_idx += delta_index; - - /* stay within range of gain table */ - power_idx = iwl3945_hw_reg_fix_power_index(power_idx); - - /* fill 1 OFDM rate's iwl3945_channel_power_info struct */ - pwr_info->requested_power = pwr; - pwr_info->power_table_index = (u8) power_idx; - pwr_info->tpc.tx_gain = - power_gain_table[a_band][power_idx].tx_gain; - pwr_info->tpc.dsp_atten = - power_gain_table[a_band][power_idx].dsp_atten; - } - - /* set tx power for CCK rates, based on OFDM 12 Mbit settings*/ - pwr_info = &ch_info->power_info[IWL_RATE_12M_INDEX_TABLE]; - power = pwr_info->requested_power + - IWL_CCK_FROM_OFDM_POWER_DIFF; - pwr_index = pwr_info->power_table_index + - IWL_CCK_FROM_OFDM_INDEX_DIFF; - base_pwr_index = pwr_info->base_power_index + - IWL_CCK_FROM_OFDM_INDEX_DIFF; - - /* stay within table range */ - pwr_index = iwl3945_hw_reg_fix_power_index(pwr_index); - gain = power_gain_table[a_band][pwr_index].tx_gain; - dsp_atten = power_gain_table[a_band][pwr_index].dsp_atten; - - /* fill each CCK rate's iwl3945_channel_power_info structure - * NOTE: All CCK-rate Txpwrs are the same for a given chnl! - * NOTE: CCK rates start at end of OFDM rates! */ - for (rate_index = 0; - rate_index < IWL_CCK_RATES; rate_index++) { - pwr_info = &ch_info->power_info[rate_index+IWL_OFDM_RATES]; - pwr_info->requested_power = power; - pwr_info->power_table_index = pwr_index; - pwr_info->base_power_index = base_pwr_index; - pwr_info->tpc.tx_gain = gain; - pwr_info->tpc.dsp_atten = dsp_atten; - } - - /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */ - for (scan_tbl_index = 0; - scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) { - s32 actual_index = (scan_tbl_index == 0) ? - IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE; - iwl3945_hw_reg_set_scan_power(priv, scan_tbl_index, - actual_index, clip_pwrs, ch_info, a_band); - } - } - - return 0; -} - -int iwl3945_hw_rxq_stop(struct iwl_priv *priv) -{ - int rc; - - iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), 0); - rc = iwl_poll_direct_bit(priv, FH39_RSSR_STATUS, - FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); - if (rc < 0) - IWL_ERR(priv, "Can't stop Rx DMA.\n"); - - return 0; -} - -int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq) -{ - int txq_id = txq->q.id; - - struct iwl3945_shared *shared_data = priv->_3945.shared_virt; - - shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr); - - iwl_write_direct32(priv, FH39_CBCC_CTRL(txq_id), 0); - iwl_write_direct32(priv, FH39_CBCC_BASE(txq_id), 0); - - iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), - FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT | - FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF | - FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD | - FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL | - FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE); - - /* fake read to flush all prev. writes */ - iwl_read32(priv, FH39_TSSR_CBB_BASE); - - return 0; -} - -/* - * HCMD utils - */ -static u16 iwl3945_get_hcmd_size(u8 cmd_id, u16 len) -{ - switch (cmd_id) { - case REPLY_RXON: - return sizeof(struct iwl3945_rxon_cmd); - case POWER_TABLE_CMD: - return sizeof(struct iwl3945_powertable_cmd); - default: - return len; - } -} - - -static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) -{ - struct iwl3945_addsta_cmd *addsta = (struct iwl3945_addsta_cmd *)data; - addsta->mode = cmd->mode; - memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify)); - memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo)); - addsta->station_flags = cmd->station_flags; - addsta->station_flags_msk = cmd->station_flags_msk; - addsta->tid_disable_tx = cpu_to_le16(0); - addsta->rate_n_flags = cmd->rate_n_flags; - addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid; - addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid; - addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn; - - return (u16)sizeof(struct iwl3945_addsta_cmd); -} - -static int iwl3945_add_bssid_station(struct iwl_priv *priv, - const u8 *addr, u8 *sta_id_r) -{ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - int ret; - u8 sta_id; - unsigned long flags; - - if (sta_id_r) - *sta_id_r = IWL_INVALID_STATION; - - ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id); - if (ret) { - IWL_ERR(priv, "Unable to add station %pM\n", addr); - return ret; - } - - if (sta_id_r) - *sta_id_r = sta_id; - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].used |= IWL_STA_LOCAL; - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return 0; -} -static int iwl3945_manage_ibss_station(struct iwl_priv *priv, - struct ieee80211_vif *vif, bool add) -{ - struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; - int ret; - - if (add) { - ret = iwl3945_add_bssid_station(priv, vif->bss_conf.bssid, - &vif_priv->ibss_bssid_sta_id); - if (ret) - return ret; - - iwl3945_sync_sta(priv, vif_priv->ibss_bssid_sta_id, - (priv->band == IEEE80211_BAND_5GHZ) ? - IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP); - iwl3945_rate_scale_init(priv->hw, vif_priv->ibss_bssid_sta_id); - - return 0; - } - - return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id, - vif->bss_conf.bssid); -} - -/** - * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table - */ -int iwl3945_init_hw_rate_table(struct iwl_priv *priv) -{ - int rc, i, index, prev_index; - struct iwl3945_rate_scaling_cmd rate_cmd = { - .reserved = {0, 0, 0}, - }; - struct iwl3945_rate_scaling_info *table = rate_cmd.table; - - for (i = 0; i < ARRAY_SIZE(iwl3945_rates); i++) { - index = iwl3945_rates[i].table_rs_index; - - table[index].rate_n_flags = - iwl3945_hw_set_rate_n_flags(iwl3945_rates[i].plcp, 0); - table[index].try_cnt = priv->retry_rate; - prev_index = iwl3945_get_prev_ieee_rate(i); - table[index].next_rate_index = - iwl3945_rates[prev_index].table_rs_index; - } - - switch (priv->band) { - case IEEE80211_BAND_5GHZ: - IWL_DEBUG_RATE(priv, "Select A mode rate scale\n"); - /* If one of the following CCK rates is used, - * have it fall back to the 6M OFDM rate */ - for (i = IWL_RATE_1M_INDEX_TABLE; - i <= IWL_RATE_11M_INDEX_TABLE; i++) - table[i].next_rate_index = - iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index; - - /* Don't fall back to CCK rates */ - table[IWL_RATE_12M_INDEX_TABLE].next_rate_index = - IWL_RATE_9M_INDEX_TABLE; - - /* Don't drop out of OFDM rates */ - table[IWL_RATE_6M_INDEX_TABLE].next_rate_index = - iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index; - break; - - case IEEE80211_BAND_2GHZ: - IWL_DEBUG_RATE(priv, "Select B/G mode rate scale\n"); - /* If an OFDM rate is used, have it fall back to the - * 1M CCK rates */ - - if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) && - iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { - - index = IWL_FIRST_CCK_RATE; - for (i = IWL_RATE_6M_INDEX_TABLE; - i <= IWL_RATE_54M_INDEX_TABLE; i++) - table[i].next_rate_index = - iwl3945_rates[index].table_rs_index; - - index = IWL_RATE_11M_INDEX_TABLE; - /* CCK shouldn't fall back to OFDM... */ - table[index].next_rate_index = IWL_RATE_5M_INDEX_TABLE; - } - break; - - default: - WARN_ON(1); - break; - } - - /* Update the rate scaling for control frame Tx */ - rate_cmd.table_id = 0; - rc = iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd), - &rate_cmd); - if (rc) - return rc; - - /* Update the rate scaling for data frame Tx */ - rate_cmd.table_id = 1; - return iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd), - &rate_cmd); -} - -/* Called when initializing driver */ -int iwl3945_hw_set_hw_params(struct iwl_priv *priv) -{ - memset((void *)&priv->hw_params, 0, - sizeof(struct iwl_hw_params)); - - priv->_3945.shared_virt = - dma_alloc_coherent(&priv->pci_dev->dev, - sizeof(struct iwl3945_shared), - &priv->_3945.shared_phys, GFP_KERNEL); - if (!priv->_3945.shared_virt) { - IWL_ERR(priv, "failed to allocate pci memory\n"); - return -ENOMEM; - } - - /* Assign number of Usable TX queues */ - priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; - - priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd); - priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_3K); - priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; - priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; - priv->hw_params.max_stations = IWL3945_STATION_COUNT; - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL3945_BROADCAST_ID; - - priv->sta_key_max_num = STA_KEY_MAX_NUM; - - priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR; - priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL; - priv->hw_params.beacon_time_tsf_bits = IWL3945_EXT_BEACON_TIME_POS; - - return 0; -} - -unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv, - struct iwl3945_frame *frame, u8 rate) -{ - struct iwl3945_tx_beacon_cmd *tx_beacon_cmd; - unsigned int frame_size; - - tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u; - memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); - - tx_beacon_cmd->tx.sta_id = - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; - tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; - - frame_size = iwl3945_fill_beacon_frame(priv, - tx_beacon_cmd->frame, - sizeof(frame->u) - sizeof(*tx_beacon_cmd)); - - BUG_ON(frame_size > MAX_MPDU_SIZE); - tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); - - tx_beacon_cmd->tx.rate = rate; - tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK | - TX_CMD_FLG_TSF_MSK); - - /* supp_rates[0] == OFDM start at IWL_FIRST_OFDM_RATE*/ - tx_beacon_cmd->tx.supp_rates[0] = - (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; - - tx_beacon_cmd->tx.supp_rates[1] = - (IWL_CCK_BASIC_RATES_MASK & 0xF); - - return sizeof(struct iwl3945_tx_beacon_cmd) + frame_size; -} - -void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv) -{ - priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx; - priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx; -} - -void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv) -{ - INIT_DELAYED_WORK(&priv->_3945.thermal_periodic, - iwl3945_bg_reg_txpower_periodic); -} - -void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv) -{ - cancel_delayed_work(&priv->_3945.thermal_periodic); -} - -/* check contents of special bootstrap uCode SRAM */ -static int iwl3945_verify_bsm(struct iwl_priv *priv) - { - __le32 *image = priv->ucode_boot.v_addr; - u32 len = priv->ucode_boot.len; - u32 reg; - u32 val; - - IWL_DEBUG_INFO(priv, "Begin verify bsm\n"); - - /* verify BSM SRAM contents */ - val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG); - for (reg = BSM_SRAM_LOWER_BOUND; - reg < BSM_SRAM_LOWER_BOUND + len; - reg += sizeof(u32), image++) { - val = iwl_read_prph(priv, reg); - if (val != le32_to_cpu(*image)) { - IWL_ERR(priv, "BSM uCode verification failed at " - "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", - BSM_SRAM_LOWER_BOUND, - reg - BSM_SRAM_LOWER_BOUND, len, - val, le32_to_cpu(*image)); - return -EIO; - } - } - - IWL_DEBUG_INFO(priv, "BSM bootstrap uCode image OK\n"); - - return 0; -} - - -/****************************************************************************** - * - * EEPROM related functions - * - ******************************************************************************/ - -/* - * Clear the OWNER_MSK, to establish driver (instead of uCode running on - * embedded controller) as EEPROM reader; each read is a series of pulses - * to/from the EEPROM chip, not a single event, so even reads could conflict - * if they weren't arbitrated by some ownership mechanism. Here, the driver - * simply claims ownership, which should be safe when this function is called - * (i.e. before loading uCode!). - */ -static int iwl3945_eeprom_acquire_semaphore(struct iwl_priv *priv) -{ - _iwl_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK); - return 0; -} - - -static void iwl3945_eeprom_release_semaphore(struct iwl_priv *priv) -{ - return; -} - - /** - * iwl3945_load_bsm - Load bootstrap instructions - * - * BSM operation: - * - * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program - * in special SRAM that does not power down during RFKILL. When powering back - * up after power-saving sleeps (or during initial uCode load), the BSM loads - * the bootstrap program into the on-board processor, and starts it. - * - * The bootstrap program loads (via DMA) instructions and data for a new - * program from host DRAM locations indicated by the host driver in the - * BSM_DRAM_* registers. Once the new program is loaded, it starts - * automatically. - * - * When initializing the NIC, the host driver points the BSM to the - * "initialize" uCode image. This uCode sets up some internal data, then - * notifies host via "initialize alive" that it is complete. - * - * The host then replaces the BSM_DRAM_* pointer values to point to the - * normal runtime uCode instructions and a backup uCode data cache buffer - * (filled initially with starting data values for the on-board processor), - * then triggers the "initialize" uCode to load and launch the runtime uCode, - * which begins normal operation. - * - * When doing a power-save shutdown, runtime uCode saves data SRAM into - * the backup data cache in DRAM before SRAM is powered down. - * - * When powering back up, the BSM loads the bootstrap program. This reloads - * the runtime uCode instructions and the backup data cache into SRAM, - * and re-launches the runtime uCode from where it left off. - */ -static int iwl3945_load_bsm(struct iwl_priv *priv) -{ - __le32 *image = priv->ucode_boot.v_addr; - u32 len = priv->ucode_boot.len; - dma_addr_t pinst; - dma_addr_t pdata; - u32 inst_len; - u32 data_len; - int rc; - int i; - u32 done; - u32 reg_offset; - - IWL_DEBUG_INFO(priv, "Begin load bsm\n"); - - /* make sure bootstrap program is no larger than BSM's SRAM size */ - if (len > IWL39_MAX_BSM_SIZE) - return -EINVAL; - - /* Tell bootstrap uCode where to find the "Initialize" uCode - * in host DRAM ... host DRAM physical address bits 31:0 for 3945. - * NOTE: iwl3945_initialize_alive_start() will replace these values, - * after the "initialize" uCode has run, to point to - * runtime/protocol instructions and backup data cache. */ - pinst = priv->ucode_init.p_addr; - pdata = priv->ucode_init_data.p_addr; - inst_len = priv->ucode_init.len; - data_len = priv->ucode_init_data.len; - - iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); - iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); - iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); - iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); - - /* Fill BSM memory with bootstrap instructions */ - for (reg_offset = BSM_SRAM_LOWER_BOUND; - reg_offset < BSM_SRAM_LOWER_BOUND + len; - reg_offset += sizeof(u32), image++) - _iwl_write_prph(priv, reg_offset, - le32_to_cpu(*image)); - - rc = iwl3945_verify_bsm(priv); - if (rc) - return rc; - - /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ - iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); - iwl_write_prph(priv, BSM_WR_MEM_DST_REG, - IWL39_RTC_INST_LOWER_BOUND); - iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); - - /* Load bootstrap code into instruction SRAM now, - * to prepare to load "initialize" uCode */ - iwl_write_prph(priv, BSM_WR_CTRL_REG, - BSM_WR_CTRL_REG_BIT_START); - - /* Wait for load of bootstrap uCode to finish */ - for (i = 0; i < 100; i++) { - done = iwl_read_prph(priv, BSM_WR_CTRL_REG); - if (!(done & BSM_WR_CTRL_REG_BIT_START)) - break; - udelay(10); - } - if (i < 100) - IWL_DEBUG_INFO(priv, "BSM write complete, poll %d iterations\n", i); - else { - IWL_ERR(priv, "BSM write did not complete!\n"); - return -EIO; - } - - /* Enable future boot loads whenever power management unit triggers it - * (e.g. when powering back up after power-save shutdown) */ - iwl_write_prph(priv, BSM_WR_CTRL_REG, - BSM_WR_CTRL_REG_BIT_START_EN); - - return 0; -} - -static struct iwl_hcmd_ops iwl3945_hcmd = { - .rxon_assoc = iwl3945_send_rxon_assoc, - .commit_rxon = iwl3945_commit_rxon, - .send_bt_config = iwl_send_bt_config, -}; - -static struct iwl_lib_ops iwl3945_lib = { - .txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd, - .txq_free_tfd = iwl3945_hw_txq_free_tfd, - .txq_init = iwl3945_hw_tx_queue_init, - .load_ucode = iwl3945_load_bsm, - .dump_nic_event_log = iwl3945_dump_nic_event_log, - .dump_nic_error_log = iwl3945_dump_nic_error_log, - .apm_ops = { - .init = iwl3945_apm_init, - .config = iwl3945_nic_config, - }, - .eeprom_ops = { - .regulatory_bands = { - EEPROM_REGULATORY_BAND_1_CHANNELS, - EEPROM_REGULATORY_BAND_2_CHANNELS, - EEPROM_REGULATORY_BAND_3_CHANNELS, - EEPROM_REGULATORY_BAND_4_CHANNELS, - EEPROM_REGULATORY_BAND_5_CHANNELS, - EEPROM_REGULATORY_BAND_NO_HT40, - EEPROM_REGULATORY_BAND_NO_HT40, - }, - .acquire_semaphore = iwl3945_eeprom_acquire_semaphore, - .release_semaphore = iwl3945_eeprom_release_semaphore, - .query_addr = iwlcore_eeprom_query_addr, - }, - .send_tx_power = iwl3945_send_tx_power, - .is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr, - .isr_ops = { - .isr = iwl_isr_legacy, - }, - - .debugfs_ops = { - .rx_stats_read = iwl3945_ucode_rx_stats_read, - .tx_stats_read = iwl3945_ucode_tx_stats_read, - .general_stats_read = iwl3945_ucode_general_stats_read, - }, -}; - -static const struct iwl_legacy_ops iwl3945_legacy_ops = { - .post_associate = iwl3945_post_associate, - .config_ap = iwl3945_config_ap, - .manage_ibss_station = iwl3945_manage_ibss_station, -}; - -static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { - .get_hcmd_size = iwl3945_get_hcmd_size, - .build_addsta_hcmd = iwl3945_build_addsta_hcmd, - .tx_cmd_protection = iwl_legacy_tx_cmd_protection, - .request_scan = iwl3945_request_scan, - .post_scan = iwl3945_post_scan, -}; - -static const struct iwl_ops iwl3945_ops = { - .lib = &iwl3945_lib, - .hcmd = &iwl3945_hcmd, - .utils = &iwl3945_hcmd_utils, - .led = &iwl3945_led_ops, - .legacy = &iwl3945_legacy_ops, - .ieee80211_ops = &iwl3945_hw_ops, -}; - -static struct iwl_base_params iwl3945_base_params = { - .eeprom_size = IWL3945_EEPROM_IMG_SIZE, - .num_of_queues = IWL39_NUM_QUEUES, - .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL, - .set_l0s = false, - .use_bsm = true, - .use_isr_legacy = true, - .led_compensation = 64, - .broken_powersave = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, - .wd_timeout = IWL_DEF_WD_TIMEOUT, - .max_event_log_size = 512, - .tx_power_by_driver = true, -}; - -static struct iwl_cfg iwl3945_bg_cfg = { - .name = "3945BG", - .fw_name_pre = IWL3945_FW_PRE, - .ucode_api_max = IWL3945_UCODE_API_MAX, - .ucode_api_min = IWL3945_UCODE_API_MIN, - .sku = IWL_SKU_G, - .eeprom_ver = EEPROM_3945_EEPROM_VERSION, - .ops = &iwl3945_ops, - .mod_params = &iwl3945_mod_params, - .base_params = &iwl3945_base_params, - .led_mode = IWL_LED_BLINK, -}; - -static struct iwl_cfg iwl3945_abg_cfg = { - .name = "3945ABG", - .fw_name_pre = IWL3945_FW_PRE, - .ucode_api_max = IWL3945_UCODE_API_MAX, - .ucode_api_min = IWL3945_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G, - .eeprom_ver = EEPROM_3945_EEPROM_VERSION, - .ops = &iwl3945_ops, - .mod_params = &iwl3945_mod_params, - .base_params = &iwl3945_base_params, - .led_mode = IWL_LED_BLINK, -}; - -DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { - {IWL_PCI_DEVICE(0x4222, 0x1005, iwl3945_bg_cfg)}, - {IWL_PCI_DEVICE(0x4222, 0x1034, iwl3945_bg_cfg)}, - {IWL_PCI_DEVICE(0x4222, 0x1044, iwl3945_bg_cfg)}, - {IWL_PCI_DEVICE(0x4227, 0x1014, iwl3945_bg_cfg)}, - {IWL_PCI_DEVICE(0x4222, PCI_ANY_ID, iwl3945_abg_cfg)}, - {IWL_PCI_DEVICE(0x4227, PCI_ANY_ID, iwl3945_abg_cfg)}, - {0} -}; - -MODULE_DEVICE_TABLE(pci, iwl3945_hw_card_ids); diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h deleted file mode 100644 index 3eef1eb74a78..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ /dev/null @@ -1,308 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ -/* - * Please use this file (iwl-3945.h) for driver implementation definitions. - * Please use iwl-3945-commands.h for uCode API definitions. - * Please use iwl-3945-hw.h for hardware-related definitions. - */ - -#ifndef __iwl_3945_h__ -#define __iwl_3945_h__ - -#include /* for struct pci_device_id */ -#include -#include - -/* Hardware specific file defines the PCI IDs table for that hardware module */ -extern const struct pci_device_id iwl3945_hw_card_ids[]; - -#include "iwl-csr.h" -#include "iwl-prph.h" -#include "iwl-fh.h" -#include "iwl-3945-hw.h" -#include "iwl-debug.h" -#include "iwl-power.h" -#include "iwl-dev.h" -#include "iwl-led.h" - -/* Highest firmware API version supported */ -#define IWL3945_UCODE_API_MAX 2 - -/* Lowest firmware API version supported */ -#define IWL3945_UCODE_API_MIN 1 - -#define IWL3945_FW_PRE "iwlwifi-3945-" -#define _IWL3945_MODULE_FIRMWARE(api) IWL3945_FW_PRE #api ".ucode" -#define IWL3945_MODULE_FIRMWARE(api) _IWL3945_MODULE_FIRMWARE(api) - -/* Default noise level to report when noise measurement is not available. - * This may be because we're: - * 1) Not associated (4965, no beacon statistics being sent to driver) - * 2) Scanning (noise measurement does not apply to associated channel) - * 3) Receiving CCK (3945 delivers noise info only for OFDM frames) - * Use default noise value of -127 ... this is below the range of measurable - * Rx dBm for either 3945 or 4965, so it can indicate "unmeasurable" to user. - * Also, -127 works better than 0 when averaging frames with/without - * noise info (e.g. averaging might be done in app); measured dBm values are - * always negative ... using a negative value as the default keeps all - * averages within an s8's (used in some apps) range of negative values. */ -#define IWL_NOISE_MEAS_NOT_AVAILABLE (-127) - -/* Module parameters accessible from iwl-*.c */ -extern struct iwl_mod_params iwl3945_mod_params; - -struct iwl3945_rate_scale_data { - u64 data; - s32 success_counter; - s32 success_ratio; - s32 counter; - s32 average_tpt; - unsigned long stamp; -}; - -struct iwl3945_rs_sta { - spinlock_t lock; - struct iwl_priv *priv; - s32 *expected_tpt; - unsigned long last_partial_flush; - unsigned long last_flush; - u32 flush_time; - u32 last_tx_packets; - u32 tx_packets; - u8 tgg; - u8 flush_pending; - u8 start_rate; - struct timer_list rate_scale_flush; - struct iwl3945_rate_scale_data win[IWL_RATE_COUNT_3945]; -#ifdef CONFIG_MAC80211_DEBUGFS - struct dentry *rs_sta_dbgfs_stats_table_file; -#endif - - /* used to be in sta_info */ - int last_txrate_idx; -}; - - -/* - * The common struct MUST be first because it is shared between - * 3945 and agn! - */ -struct iwl3945_sta_priv { - struct iwl_station_priv_common common; - struct iwl3945_rs_sta rs_sta; -}; - -enum iwl3945_antenna { - IWL_ANTENNA_DIVERSITY, - IWL_ANTENNA_MAIN, - IWL_ANTENNA_AUX -}; - -/* - * RTS threshold here is total size [2347] minus 4 FCS bytes - * Per spec: - * a value of 0 means RTS on all data/management packets - * a value > max MSDU size means no RTS - * else RTS for data/management frames where MPDU is larger - * than RTS value. - */ -#define DEFAULT_RTS_THRESHOLD 2347U -#define MIN_RTS_THRESHOLD 0U -#define MAX_RTS_THRESHOLD 2347U -#define MAX_MSDU_SIZE 2304U -#define MAX_MPDU_SIZE 2346U -#define DEFAULT_BEACON_INTERVAL 100U -#define DEFAULT_SHORT_RETRY_LIMIT 7U -#define DEFAULT_LONG_RETRY_LIMIT 4U - -#define IWL_TX_FIFO_AC0 0 -#define IWL_TX_FIFO_AC1 1 -#define IWL_TX_FIFO_AC2 2 -#define IWL_TX_FIFO_AC3 3 -#define IWL_TX_FIFO_HCCA_1 5 -#define IWL_TX_FIFO_HCCA_2 6 -#define IWL_TX_FIFO_NONE 7 - -#define IEEE80211_DATA_LEN 2304 -#define IEEE80211_4ADDR_LEN 30 -#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) -#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) - -struct iwl3945_frame { - union { - struct ieee80211_hdr frame; - struct iwl3945_tx_beacon_cmd beacon; - u8 raw[IEEE80211_FRAME_LEN]; - u8 cmd[360]; - } u; - struct list_head list; -}; - -#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) -#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) -#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) - -#define SUP_RATE_11A_MAX_NUM_CHANNELS 8 -#define SUP_RATE_11B_MAX_NUM_CHANNELS 4 -#define SUP_RATE_11G_MAX_NUM_CHANNELS 12 - -#define IWL_SUPPORTED_RATES_IE_LEN 8 - -#define SCAN_INTERVAL 100 - -#define MAX_TID_COUNT 9 - -#define IWL_INVALID_RATE 0xFF -#define IWL_INVALID_VALUE -1 - -#define STA_PS_STATUS_WAKE 0 -#define STA_PS_STATUS_SLEEP 1 - -struct iwl3945_ibss_seq { - u8 mac[ETH_ALEN]; - u16 seq_num; - u16 frag_num; - unsigned long packet_time; - struct list_head list; -}; - -#define IWL_RX_HDR(x) ((struct iwl3945_rx_frame_hdr *)(\ - x->u.rx_frame.stats.payload + \ - x->u.rx_frame.stats.phy_count)) -#define IWL_RX_END(x) ((struct iwl3945_rx_frame_end *)(\ - IWL_RX_HDR(x)->payload + \ - le16_to_cpu(IWL_RX_HDR(x)->len))) -#define IWL_RX_STATS(x) (&x->u.rx_frame.stats) -#define IWL_RX_DATA(x) (IWL_RX_HDR(x)->payload) - - -/****************************************************************************** - * - * Functions implemented in iwl-base.c which are forward declared here - * for use by iwl-*.c - * - *****************************************************************************/ -extern int iwl3945_calc_db_from_ratio(int sig_ratio); -extern void iwl3945_rx_replenish(void *data); -extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); -extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, - struct ieee80211_hdr *hdr,int left); -extern int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, - char **buf, bool display); -extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv); - -/****************************************************************************** - * - * Functions implemented in iwl-[34]*.c which are forward declared here - * for use by iwl-base.c - * - * NOTE: The implementation of these functions are hardware specific - * which is why they are in the hardware specific files (vs. iwl-base.c) - * - * Naming convention -- - * iwl3945_ <-- Its part of iwlwifi (should be changed to iwl3945_) - * iwl3945_hw_ <-- Hardware specific (implemented in iwl-XXXX.c by all HW) - * iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX) - * iwl3945_bg_ <-- Called from work queue context - * iwl3945_mac_ <-- mac80211 callback - * - ****************************************************************************/ -extern void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv); -extern void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv); -extern void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv); -extern int iwl3945_hw_rxq_stop(struct iwl_priv *priv); -extern int iwl3945_hw_set_hw_params(struct iwl_priv *priv); -extern int iwl3945_hw_nic_init(struct iwl_priv *priv); -extern int iwl3945_hw_nic_stop_master(struct iwl_priv *priv); -extern void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv); -extern void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv); -extern int iwl3945_hw_nic_reset(struct iwl_priv *priv); -extern int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, - struct iwl_tx_queue *txq, - dma_addr_t addr, u16 len, - u8 reset, u8 pad); -extern void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, - struct iwl_tx_queue *txq); -extern int iwl3945_hw_get_temperature(struct iwl_priv *priv); -extern int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, - struct iwl_tx_queue *txq); -extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv, - struct iwl3945_frame *frame, u8 rate); -void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, - struct iwl_device_cmd *cmd, - struct ieee80211_tx_info *info, - struct ieee80211_hdr *hdr, - int sta_id, int tx_id); -extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv); -extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power); -extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); -void iwl3945_reply_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); -extern void iwl3945_disable_events(struct iwl_priv *priv); -extern int iwl4965_get_temperature(const struct iwl_priv *priv); -extern void iwl3945_post_associate(struct iwl_priv *priv); -extern void iwl3945_config_ap(struct iwl_priv *priv); - -extern int iwl3945_commit_rxon(struct iwl_priv *priv, - struct iwl_rxon_context *ctx); - -/** - * iwl3945_hw_find_station - Find station id for a given BSSID - * @bssid: MAC address of station ID to find - * - * NOTE: This should not be hardware specific but the code has - * not yet been merged into a single common layer for managing the - * station tables. - */ -extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid); - -extern struct ieee80211_ops iwl3945_hw_ops; - -/* - * Forward declare iwl-3945.c functions for iwl-base.c - */ -extern __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv); -extern int iwl3945_init_hw_rate_table(struct iwl_priv *priv); -extern void iwl3945_reg_txpower_periodic(struct iwl_priv *priv); -extern int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv); - -extern const struct iwl_channel_info *iwl3945_get_channel_info( - const struct iwl_priv *priv, enum ieee80211_band band, u16 channel); - -extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate); - -/* scanning */ -int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); -void iwl3945_post_scan(struct iwl_priv *priv); - -/* rates */ -extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945]; - -/* Requires full declaration of iwl_priv before including */ -#include "iwl-io.h" - -#endif diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h deleted file mode 100644 index 9166794eda0d..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h +++ /dev/null @@ -1,792 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ -/* - * Please use this file (iwl-4965-hw.h) only for hardware-related definitions. - * Use iwl-commands.h for uCode API definitions. - * Use iwl-dev.h for driver implementation definitions. - */ - -#ifndef __iwl_4965_hw_h__ -#define __iwl_4965_hw_h__ - -#include "iwl-fh.h" - -/* EEPROM */ -#define IWL4965_EEPROM_IMG_SIZE 1024 - -/* - * uCode queue management definitions ... - * The first queue used for block-ack aggregation is #7 (4965 only). - * All block-ack aggregation queues should map to Tx DMA/FIFO channel 7. - */ -#define IWL49_FIRST_AMPDU_QUEUE 7 - -/* Sizes and addresses for instruction and data memory (SRAM) in - * 4965's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ -#define IWL49_RTC_INST_LOWER_BOUND (0x000000) -#define IWL49_RTC_INST_UPPER_BOUND (0x018000) - -#define IWL49_RTC_DATA_LOWER_BOUND (0x800000) -#define IWL49_RTC_DATA_UPPER_BOUND (0x80A000) - -#define IWL49_RTC_INST_SIZE (IWL49_RTC_INST_UPPER_BOUND - \ - IWL49_RTC_INST_LOWER_BOUND) -#define IWL49_RTC_DATA_SIZE (IWL49_RTC_DATA_UPPER_BOUND - \ - IWL49_RTC_DATA_LOWER_BOUND) - -#define IWL49_MAX_INST_SIZE IWL49_RTC_INST_SIZE -#define IWL49_MAX_DATA_SIZE IWL49_RTC_DATA_SIZE - -/* Size of uCode instruction memory in bootstrap state machine */ -#define IWL49_MAX_BSM_SIZE BSM_SRAM_SIZE - -static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr) -{ - return (addr >= IWL49_RTC_DATA_LOWER_BOUND) && - (addr < IWL49_RTC_DATA_UPPER_BOUND); -} - -/********************* START TEMPERATURE *************************************/ - -/** - * 4965 temperature calculation. - * - * The driver must calculate the device temperature before calculating - * a txpower setting (amplifier gain is temperature dependent). The - * calculation uses 4 measurements, 3 of which (R1, R2, R3) are calibration - * values used for the life of the driver, and one of which (R4) is the - * real-time temperature indicator. - * - * uCode provides all 4 values to the driver via the "initialize alive" - * notification (see struct iwl4965_init_alive_resp). After the runtime uCode - * image loads, uCode updates the R4 value via statistics notifications - * (see STATISTICS_NOTIFICATION), which occur after each received beacon - * when associated, or can be requested via REPLY_STATISTICS_CMD. - * - * NOTE: uCode provides the R4 value as a 23-bit signed value. Driver - * must sign-extend to 32 bits before applying formula below. - * - * Formula: - * - * degrees Kelvin = ((97 * 259 * (R4 - R2) / (R3 - R1)) / 100) + 8 - * - * NOTE: The basic formula is 259 * (R4-R2) / (R3-R1). The 97/100 is - * an additional correction, which should be centered around 0 degrees - * Celsius (273 degrees Kelvin). The 8 (3 percent of 273) compensates for - * centering the 97/100 correction around 0 degrees K. - * - * Add 273 to Kelvin value to find degrees Celsius, for comparing current - * temperature with factory-measured temperatures when calculating txpower - * settings. - */ -#define TEMPERATURE_CALIB_KELVIN_OFFSET 8 -#define TEMPERATURE_CALIB_A_VAL 259 - -/* Limit range of calculated temperature to be between these Kelvin values */ -#define IWL_TX_POWER_TEMPERATURE_MIN (263) -#define IWL_TX_POWER_TEMPERATURE_MAX (410) - -#define IWL_TX_POWER_TEMPERATURE_OUT_OF_RANGE(t) \ - (((t) < IWL_TX_POWER_TEMPERATURE_MIN) || \ - ((t) > IWL_TX_POWER_TEMPERATURE_MAX)) - -/********************* END TEMPERATURE ***************************************/ - -/********************* START TXPOWER *****************************************/ - -/** - * 4965 txpower calculations rely on information from three sources: - * - * 1) EEPROM - * 2) "initialize" alive notification - * 3) statistics notifications - * - * EEPROM data consists of: - * - * 1) Regulatory information (max txpower and channel usage flags) is provided - * separately for each channel that can possibly supported by 4965. - * 40 MHz wide (.11n HT40) channels are listed separately from 20 MHz - * (legacy) channels. - * - * See struct iwl4965_eeprom_channel for format, and struct iwl4965_eeprom - * for locations in EEPROM. - * - * 2) Factory txpower calibration information is provided separately for - * sub-bands of contiguous channels. 2.4GHz has just one sub-band, - * but 5 GHz has several sub-bands. - * - * In addition, per-band (2.4 and 5 Ghz) saturation txpowers are provided. - * - * See struct iwl4965_eeprom_calib_info (and the tree of structures - * contained within it) for format, and struct iwl4965_eeprom for - * locations in EEPROM. - * - * "Initialization alive" notification (see struct iwl4965_init_alive_resp) - * consists of: - * - * 1) Temperature calculation parameters. - * - * 2) Power supply voltage measurement. - * - * 3) Tx gain compensation to balance 2 transmitters for MIMO use. - * - * Statistics notifications deliver: - * - * 1) Current values for temperature param R4. - */ - -/** - * To calculate a txpower setting for a given desired target txpower, channel, - * modulation bit rate, and transmitter chain (4965 has 2 transmitters to - * support MIMO and transmit diversity), driver must do the following: - * - * 1) Compare desired txpower vs. (EEPROM) regulatory limit for this channel. - * Do not exceed regulatory limit; reduce target txpower if necessary. - * - * If setting up txpowers for MIMO rates (rate indexes 8-15, 24-31), - * 2 transmitters will be used simultaneously; driver must reduce the - * regulatory limit by 3 dB (half-power) for each transmitter, so the - * combined total output of the 2 transmitters is within regulatory limits. - * - * - * 2) Compare target txpower vs. (EEPROM) saturation txpower *reduced by - * backoff for this bit rate*. Do not exceed (saturation - backoff[rate]); - * reduce target txpower if necessary. - * - * Backoff values below are in 1/2 dB units (equivalent to steps in - * txpower gain tables): - * - * OFDM 6 - 36 MBit: 10 steps (5 dB) - * OFDM 48 MBit: 15 steps (7.5 dB) - * OFDM 54 MBit: 17 steps (8.5 dB) - * OFDM 60 MBit: 20 steps (10 dB) - * CCK all rates: 10 steps (5 dB) - * - * Backoff values apply to saturation txpower on a per-transmitter basis; - * when using MIMO (2 transmitters), each transmitter uses the same - * saturation level provided in EEPROM, and the same backoff values; - * no reduction (such as with regulatory txpower limits) is required. - * - * Saturation and Backoff values apply equally to 20 Mhz (legacy) channel - * widths and 40 Mhz (.11n HT40) channel widths; there is no separate - * factory measurement for ht40 channels. - * - * The result of this step is the final target txpower. The rest of - * the steps figure out the proper settings for the device to achieve - * that target txpower. - * - * - * 3) Determine (EEPROM) calibration sub band for the target channel, by - * comparing against first and last channels in each sub band - * (see struct iwl4965_eeprom_calib_subband_info). - * - * - * 4) Linearly interpolate (EEPROM) factory calibration measurement sets, - * referencing the 2 factory-measured (sample) channels within the sub band. - * - * Interpolation is based on difference between target channel's frequency - * and the sample channels' frequencies. Since channel numbers are based - * on frequency (5 MHz between each channel number), this is equivalent - * to interpolating based on channel number differences. - * - * Note that the sample channels may or may not be the channels at the - * edges of the sub band. The target channel may be "outside" of the - * span of the sampled channels. - * - * Driver may choose the pair (for 2 Tx chains) of measurements (see - * struct iwl4965_eeprom_calib_ch_info) for which the actual measured - * txpower comes closest to the desired txpower. Usually, though, - * the middle set of measurements is closest to the regulatory limits, - * and is therefore a good choice for all txpower calculations (this - * assumes that high accuracy is needed for maximizing legal txpower, - * while lower txpower configurations do not need as much accuracy). - * - * Driver should interpolate both members of the chosen measurement pair, - * i.e. for both Tx chains (radio transmitters), unless the driver knows - * that only one of the chains will be used (e.g. only one tx antenna - * connected, but this should be unusual). The rate scaling algorithm - * switches antennas to find best performance, so both Tx chains will - * be used (although only one at a time) even for non-MIMO transmissions. - * - * Driver should interpolate factory values for temperature, gain table - * index, and actual power. The power amplifier detector values are - * not used by the driver. - * - * Sanity check: If the target channel happens to be one of the sample - * channels, the results should agree with the sample channel's - * measurements! - * - * - * 5) Find difference between desired txpower and (interpolated) - * factory-measured txpower. Using (interpolated) factory gain table index - * (shown elsewhere) as a starting point, adjust this index lower to - * increase txpower, or higher to decrease txpower, until the target - * txpower is reached. Each step in the gain table is 1/2 dB. - * - * For example, if factory measured txpower is 16 dBm, and target txpower - * is 13 dBm, add 6 steps to the factory gain index to reduce txpower - * by 3 dB. - * - * - * 6) Find difference between current device temperature and (interpolated) - * factory-measured temperature for sub-band. Factory values are in - * degrees Celsius. To calculate current temperature, see comments for - * "4965 temperature calculation". - * - * If current temperature is higher than factory temperature, driver must - * increase gain (lower gain table index), and vice verse. - * - * Temperature affects gain differently for different channels: - * - * 2.4 GHz all channels: 3.5 degrees per half-dB step - * 5 GHz channels 34-43: 4.5 degrees per half-dB step - * 5 GHz channels >= 44: 4.0 degrees per half-dB step - * - * NOTE: Temperature can increase rapidly when transmitting, especially - * with heavy traffic at high txpowers. Driver should update - * temperature calculations often under these conditions to - * maintain strong txpower in the face of rising temperature. - * - * - * 7) Find difference between current power supply voltage indicator - * (from "initialize alive") and factory-measured power supply voltage - * indicator (EEPROM). - * - * If the current voltage is higher (indicator is lower) than factory - * voltage, gain should be reduced (gain table index increased) by: - * - * (eeprom - current) / 7 - * - * If the current voltage is lower (indicator is higher) than factory - * voltage, gain should be increased (gain table index decreased) by: - * - * 2 * (current - eeprom) / 7 - * - * If number of index steps in either direction turns out to be > 2, - * something is wrong ... just use 0. - * - * NOTE: Voltage compensation is independent of band/channel. - * - * NOTE: "Initialize" uCode measures current voltage, which is assumed - * to be constant after this initial measurement. Voltage - * compensation for txpower (number of steps in gain table) - * may be calculated once and used until the next uCode bootload. - * - * - * 8) If setting up txpowers for MIMO rates (rate indexes 8-15, 24-31), - * adjust txpower for each transmitter chain, so txpower is balanced - * between the two chains. There are 5 pairs of tx_atten[group][chain] - * values in "initialize alive", one pair for each of 5 channel ranges: - * - * Group 0: 5 GHz channel 34-43 - * Group 1: 5 GHz channel 44-70 - * Group 2: 5 GHz channel 71-124 - * Group 3: 5 GHz channel 125-200 - * Group 4: 2.4 GHz all channels - * - * Add the tx_atten[group][chain] value to the index for the target chain. - * The values are signed, but are in pairs of 0 and a non-negative number, - * so as to reduce gain (if necessary) of the "hotter" channel. This - * avoids any need to double-check for regulatory compliance after - * this step. - * - * - * 9) If setting up for a CCK rate, lower the gain by adding a CCK compensation - * value to the index: - * - * Hardware rev B: 9 steps (4.5 dB) - * Hardware rev C: 5 steps (2.5 dB) - * - * Hardware rev for 4965 can be determined by reading CSR_HW_REV_WA_REG, - * bits [3:2], 1 = B, 2 = C. - * - * NOTE: This compensation is in addition to any saturation backoff that - * might have been applied in an earlier step. - * - * - * 10) Select the gain table, based on band (2.4 vs 5 GHz). - * - * Limit the adjusted index to stay within the table! - * - * - * 11) Read gain table entries for DSP and radio gain, place into appropriate - * location(s) in command (struct iwl4965_txpowertable_cmd). - */ - -/** - * When MIMO is used (2 transmitters operating simultaneously), driver should - * limit each transmitter to deliver a max of 3 dB below the regulatory limit - * for the device. That is, use half power for each transmitter, so total - * txpower is within regulatory limits. - * - * The value "6" represents number of steps in gain table to reduce power 3 dB. - * Each step is 1/2 dB. - */ -#define IWL_TX_POWER_MIMO_REGULATORY_COMPENSATION (6) - -/** - * CCK gain compensation. - * - * When calculating txpowers for CCK, after making sure that the target power - * is within regulatory and saturation limits, driver must additionally - * back off gain by adding these values to the gain table index. - * - * Hardware rev for 4965 can be determined by reading CSR_HW_REV_WA_REG, - * bits [3:2], 1 = B, 2 = C. - */ -#define IWL_TX_POWER_CCK_COMPENSATION_B_STEP (9) -#define IWL_TX_POWER_CCK_COMPENSATION_C_STEP (5) - -/* - * 4965 power supply voltage compensation for txpower - */ -#define TX_POWER_IWL_VOLTAGE_CODES_PER_03V (7) - -/** - * Gain tables. - * - * The following tables contain pair of values for setting txpower, i.e. - * gain settings for the output of the device's digital signal processor (DSP), - * and for the analog gain structure of the transmitter. - * - * Each entry in the gain tables represents a step of 1/2 dB. Note that these - * are *relative* steps, not indications of absolute output power. Output - * power varies with temperature, voltage, and channel frequency, and also - * requires consideration of average power (to satisfy regulatory constraints), - * and peak power (to avoid distortion of the output signal). - * - * Each entry contains two values: - * 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained - * linear value that multiplies the output of the digital signal processor, - * before being sent to the analog radio. - * 2) Radio gain. This sets the analog gain of the radio Tx path. - * It is a coarser setting, and behaves in a logarithmic (dB) fashion. - * - * EEPROM contains factory calibration data for txpower. This maps actual - * measured txpower levels to gain settings in the "well known" tables - * below ("well-known" means here that both factory calibration *and* the - * driver work with the same table). - * - * There are separate tables for 2.4 GHz and 5 GHz bands. The 5 GHz table - * has an extension (into negative indexes), in case the driver needs to - * boost power setting for high device temperatures (higher than would be - * present during factory calibration). A 5 Ghz EEPROM index of "40" - * corresponds to the 49th entry in the table used by the driver. - */ -#define MIN_TX_GAIN_INDEX (0) /* highest gain, lowest idx, 2.4 */ -#define MIN_TX_GAIN_INDEX_52GHZ_EXT (-9) /* highest gain, lowest idx, 5 */ - -/** - * 2.4 GHz gain table - * - * Index Dsp gain Radio gain - * 0 110 0x3f (highest gain) - * 1 104 0x3f - * 2 98 0x3f - * 3 110 0x3e - * 4 104 0x3e - * 5 98 0x3e - * 6 110 0x3d - * 7 104 0x3d - * 8 98 0x3d - * 9 110 0x3c - * 10 104 0x3c - * 11 98 0x3c - * 12 110 0x3b - * 13 104 0x3b - * 14 98 0x3b - * 15 110 0x3a - * 16 104 0x3a - * 17 98 0x3a - * 18 110 0x39 - * 19 104 0x39 - * 20 98 0x39 - * 21 110 0x38 - * 22 104 0x38 - * 23 98 0x38 - * 24 110 0x37 - * 25 104 0x37 - * 26 98 0x37 - * 27 110 0x36 - * 28 104 0x36 - * 29 98 0x36 - * 30 110 0x35 - * 31 104 0x35 - * 32 98 0x35 - * 33 110 0x34 - * 34 104 0x34 - * 35 98 0x34 - * 36 110 0x33 - * 37 104 0x33 - * 38 98 0x33 - * 39 110 0x32 - * 40 104 0x32 - * 41 98 0x32 - * 42 110 0x31 - * 43 104 0x31 - * 44 98 0x31 - * 45 110 0x30 - * 46 104 0x30 - * 47 98 0x30 - * 48 110 0x6 - * 49 104 0x6 - * 50 98 0x6 - * 51 110 0x5 - * 52 104 0x5 - * 53 98 0x5 - * 54 110 0x4 - * 55 104 0x4 - * 56 98 0x4 - * 57 110 0x3 - * 58 104 0x3 - * 59 98 0x3 - * 60 110 0x2 - * 61 104 0x2 - * 62 98 0x2 - * 63 110 0x1 - * 64 104 0x1 - * 65 98 0x1 - * 66 110 0x0 - * 67 104 0x0 - * 68 98 0x0 - * 69 97 0 - * 70 96 0 - * 71 95 0 - * 72 94 0 - * 73 93 0 - * 74 92 0 - * 75 91 0 - * 76 90 0 - * 77 89 0 - * 78 88 0 - * 79 87 0 - * 80 86 0 - * 81 85 0 - * 82 84 0 - * 83 83 0 - * 84 82 0 - * 85 81 0 - * 86 80 0 - * 87 79 0 - * 88 78 0 - * 89 77 0 - * 90 76 0 - * 91 75 0 - * 92 74 0 - * 93 73 0 - * 94 72 0 - * 95 71 0 - * 96 70 0 - * 97 69 0 - * 98 68 0 - */ - -/** - * 5 GHz gain table - * - * Index Dsp gain Radio gain - * -9 123 0x3F (highest gain) - * -8 117 0x3F - * -7 110 0x3F - * -6 104 0x3F - * -5 98 0x3F - * -4 110 0x3E - * -3 104 0x3E - * -2 98 0x3E - * -1 110 0x3D - * 0 104 0x3D - * 1 98 0x3D - * 2 110 0x3C - * 3 104 0x3C - * 4 98 0x3C - * 5 110 0x3B - * 6 104 0x3B - * 7 98 0x3B - * 8 110 0x3A - * 9 104 0x3A - * 10 98 0x3A - * 11 110 0x39 - * 12 104 0x39 - * 13 98 0x39 - * 14 110 0x38 - * 15 104 0x38 - * 16 98 0x38 - * 17 110 0x37 - * 18 104 0x37 - * 19 98 0x37 - * 20 110 0x36 - * 21 104 0x36 - * 22 98 0x36 - * 23 110 0x35 - * 24 104 0x35 - * 25 98 0x35 - * 26 110 0x34 - * 27 104 0x34 - * 28 98 0x34 - * 29 110 0x33 - * 30 104 0x33 - * 31 98 0x33 - * 32 110 0x32 - * 33 104 0x32 - * 34 98 0x32 - * 35 110 0x31 - * 36 104 0x31 - * 37 98 0x31 - * 38 110 0x30 - * 39 104 0x30 - * 40 98 0x30 - * 41 110 0x25 - * 42 104 0x25 - * 43 98 0x25 - * 44 110 0x24 - * 45 104 0x24 - * 46 98 0x24 - * 47 110 0x23 - * 48 104 0x23 - * 49 98 0x23 - * 50 110 0x22 - * 51 104 0x18 - * 52 98 0x18 - * 53 110 0x17 - * 54 104 0x17 - * 55 98 0x17 - * 56 110 0x16 - * 57 104 0x16 - * 58 98 0x16 - * 59 110 0x15 - * 60 104 0x15 - * 61 98 0x15 - * 62 110 0x14 - * 63 104 0x14 - * 64 98 0x14 - * 65 110 0x13 - * 66 104 0x13 - * 67 98 0x13 - * 68 110 0x12 - * 69 104 0x08 - * 70 98 0x08 - * 71 110 0x07 - * 72 104 0x07 - * 73 98 0x07 - * 74 110 0x06 - * 75 104 0x06 - * 76 98 0x06 - * 77 110 0x05 - * 78 104 0x05 - * 79 98 0x05 - * 80 110 0x04 - * 81 104 0x04 - * 82 98 0x04 - * 83 110 0x03 - * 84 104 0x03 - * 85 98 0x03 - * 86 110 0x02 - * 87 104 0x02 - * 88 98 0x02 - * 89 110 0x01 - * 90 104 0x01 - * 91 98 0x01 - * 92 110 0x00 - * 93 104 0x00 - * 94 98 0x00 - * 95 93 0x00 - * 96 88 0x00 - * 97 83 0x00 - * 98 78 0x00 - */ - - -/** - * Sanity checks and default values for EEPROM regulatory levels. - * If EEPROM values fall outside MIN/MAX range, use default values. - * - * Regulatory limits refer to the maximum average txpower allowed by - * regulatory agencies in the geographies in which the device is meant - * to be operated. These limits are SKU-specific (i.e. geography-specific), - * and channel-specific; each channel has an individual regulatory limit - * listed in the EEPROM. - * - * Units are in half-dBm (i.e. "34" means 17 dBm). - */ -#define IWL_TX_POWER_DEFAULT_REGULATORY_24 (34) -#define IWL_TX_POWER_DEFAULT_REGULATORY_52 (34) -#define IWL_TX_POWER_REGULATORY_MIN (0) -#define IWL_TX_POWER_REGULATORY_MAX (34) - -/** - * Sanity checks and default values for EEPROM saturation levels. - * If EEPROM values fall outside MIN/MAX range, use default values. - * - * Saturation is the highest level that the output power amplifier can produce - * without significant clipping distortion. This is a "peak" power level. - * Different types of modulation (i.e. various "rates", and OFDM vs. CCK) - * require differing amounts of backoff, relative to their average power output, - * in order to avoid clipping distortion. - * - * Driver must make sure that it is violating neither the saturation limit, - * nor the regulatory limit, when calculating Tx power settings for various - * rates. - * - * Units are in half-dBm (i.e. "38" means 19 dBm). - */ -#define IWL_TX_POWER_DEFAULT_SATURATION_24 (38) -#define IWL_TX_POWER_DEFAULT_SATURATION_52 (38) -#define IWL_TX_POWER_SATURATION_MIN (20) -#define IWL_TX_POWER_SATURATION_MAX (50) - -/** - * Channel groups used for Tx Attenuation calibration (MIMO tx channel balance) - * and thermal Txpower calibration. - * - * When calculating txpower, driver must compensate for current device - * temperature; higher temperature requires higher gain. Driver must calculate - * current temperature (see "4965 temperature calculation"), then compare vs. - * factory calibration temperature in EEPROM; if current temperature is higher - * than factory temperature, driver must *increase* gain by proportions shown - * in table below. If current temperature is lower than factory, driver must - * *decrease* gain. - * - * Different frequency ranges require different compensation, as shown below. - */ -/* Group 0, 5.2 GHz ch 34-43: 4.5 degrees per 1/2 dB. */ -#define CALIB_IWL_TX_ATTEN_GR1_FCH 34 -#define CALIB_IWL_TX_ATTEN_GR1_LCH 43 - -/* Group 1, 5.3 GHz ch 44-70: 4.0 degrees per 1/2 dB. */ -#define CALIB_IWL_TX_ATTEN_GR2_FCH 44 -#define CALIB_IWL_TX_ATTEN_GR2_LCH 70 - -/* Group 2, 5.5 GHz ch 71-124: 4.0 degrees per 1/2 dB. */ -#define CALIB_IWL_TX_ATTEN_GR3_FCH 71 -#define CALIB_IWL_TX_ATTEN_GR3_LCH 124 - -/* Group 3, 5.7 GHz ch 125-200: 4.0 degrees per 1/2 dB. */ -#define CALIB_IWL_TX_ATTEN_GR4_FCH 125 -#define CALIB_IWL_TX_ATTEN_GR4_LCH 200 - -/* Group 4, 2.4 GHz all channels: 3.5 degrees per 1/2 dB. */ -#define CALIB_IWL_TX_ATTEN_GR5_FCH 1 -#define CALIB_IWL_TX_ATTEN_GR5_LCH 20 - -enum { - CALIB_CH_GROUP_1 = 0, - CALIB_CH_GROUP_2 = 1, - CALIB_CH_GROUP_3 = 2, - CALIB_CH_GROUP_4 = 3, - CALIB_CH_GROUP_5 = 4, - CALIB_CH_GROUP_MAX -}; - -/********************* END TXPOWER *****************************************/ - - -/** - * Tx/Rx Queues - * - * Most communication between driver and 4965 is via queues of data buffers. - * For example, all commands that the driver issues to device's embedded - * controller (uCode) are via the command queue (one of the Tx queues). All - * uCode command responses/replies/notifications, including Rx frames, are - * conveyed from uCode to driver via the Rx queue. - * - * Most support for these queues, including handshake support, resides in - * structures in host DRAM, shared between the driver and the device. When - * allocating this memory, the driver must make sure that data written by - * the host CPU updates DRAM immediately (and does not get "stuck" in CPU's - * cache memory), so DRAM and cache are consistent, and the device can - * immediately see changes made by the driver. - * - * 4965 supports up to 16 DRAM-based Tx queues, and services these queues via - * up to 7 DMA channels (FIFOs). Each Tx queue is supported by a circular array - * in DRAM containing 256 Transmit Frame Descriptors (TFDs). - */ -#define IWL49_NUM_FIFOS 7 -#define IWL49_CMD_FIFO_NUM 4 -#define IWL49_NUM_QUEUES 16 -#define IWL49_NUM_AMPDU_QUEUES 8 - - -/** - * struct iwl4965_schedq_bc_tbl - * - * Byte Count table - * - * Each Tx queue uses a byte-count table containing 320 entries: - * one 16-bit entry for each of 256 TFDs, plus an additional 64 entries that - * duplicate the first 64 entries (to avoid wrap-around within a Tx window; - * max Tx window is 64 TFDs). - * - * When driver sets up a new TFD, it must also enter the total byte count - * of the frame to be transmitted into the corresponding entry in the byte - * count table for the chosen Tx queue. If the TFD index is 0-63, the driver - * must duplicate the byte count entry in corresponding index 256-319. - * - * padding puts each byte count table on a 1024-byte boundary; - * 4965 assumes tables are separated by 1024 bytes. - */ -struct iwl4965_scd_bc_tbl { - __le16 tfd_offset[TFD_QUEUE_BC_SIZE]; - u8 pad[1024 - (TFD_QUEUE_BC_SIZE) * sizeof(__le16)]; -} __packed; - -#endif /* !__iwl_4965_hw_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c deleted file mode 100644 index 8998ed134d1a..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ /dev/null @@ -1,2666 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "iwl-eeprom.h" -#include "iwl-dev.h" -#include "iwl-core.h" -#include "iwl-io.h" -#include "iwl-helpers.h" -#include "iwl-agn-calib.h" -#include "iwl-sta.h" -#include "iwl-agn-led.h" -#include "iwl-agn.h" -#include "iwl-agn-debugfs.h" -#include "iwl-legacy.h" - -static int iwl4965_send_tx_power(struct iwl_priv *priv); -static int iwl4965_hw_get_temperature(struct iwl_priv *priv); - -/* Highest firmware API version supported */ -#define IWL4965_UCODE_API_MAX 2 - -/* Lowest firmware API version supported */ -#define IWL4965_UCODE_API_MIN 2 - -#define IWL4965_FW_PRE "iwlwifi-4965-" -#define _IWL4965_MODULE_FIRMWARE(api) IWL4965_FW_PRE #api ".ucode" -#define IWL4965_MODULE_FIRMWARE(api) _IWL4965_MODULE_FIRMWARE(api) - -/* check contents of special bootstrap uCode SRAM */ -static int iwl4965_verify_bsm(struct iwl_priv *priv) -{ - __le32 *image = priv->ucode_boot.v_addr; - u32 len = priv->ucode_boot.len; - u32 reg; - u32 val; - - IWL_DEBUG_INFO(priv, "Begin verify bsm\n"); - - /* verify BSM SRAM contents */ - val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG); - for (reg = BSM_SRAM_LOWER_BOUND; - reg < BSM_SRAM_LOWER_BOUND + len; - reg += sizeof(u32), image++) { - val = iwl_read_prph(priv, reg); - if (val != le32_to_cpu(*image)) { - IWL_ERR(priv, "BSM uCode verification failed at " - "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", - BSM_SRAM_LOWER_BOUND, - reg - BSM_SRAM_LOWER_BOUND, len, - val, le32_to_cpu(*image)); - return -EIO; - } - } - - IWL_DEBUG_INFO(priv, "BSM bootstrap uCode image OK\n"); - - return 0; -} - -/** - * iwl4965_load_bsm - Load bootstrap instructions - * - * BSM operation: - * - * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program - * in special SRAM that does not power down during RFKILL. When powering back - * up after power-saving sleeps (or during initial uCode load), the BSM loads - * the bootstrap program into the on-board processor, and starts it. - * - * The bootstrap program loads (via DMA) instructions and data for a new - * program from host DRAM locations indicated by the host driver in the - * BSM_DRAM_* registers. Once the new program is loaded, it starts - * automatically. - * - * When initializing the NIC, the host driver points the BSM to the - * "initialize" uCode image. This uCode sets up some internal data, then - * notifies host via "initialize alive" that it is complete. - * - * The host then replaces the BSM_DRAM_* pointer values to point to the - * normal runtime uCode instructions and a backup uCode data cache buffer - * (filled initially with starting data values for the on-board processor), - * then triggers the "initialize" uCode to load and launch the runtime uCode, - * which begins normal operation. - * - * When doing a power-save shutdown, runtime uCode saves data SRAM into - * the backup data cache in DRAM before SRAM is powered down. - * - * When powering back up, the BSM loads the bootstrap program. This reloads - * the runtime uCode instructions and the backup data cache into SRAM, - * and re-launches the runtime uCode from where it left off. - */ -static int iwl4965_load_bsm(struct iwl_priv *priv) -{ - __le32 *image = priv->ucode_boot.v_addr; - u32 len = priv->ucode_boot.len; - dma_addr_t pinst; - dma_addr_t pdata; - u32 inst_len; - u32 data_len; - int i; - u32 done; - u32 reg_offset; - int ret; - - IWL_DEBUG_INFO(priv, "Begin load bsm\n"); - - priv->ucode_type = UCODE_RT; - - /* make sure bootstrap program is no larger than BSM's SRAM size */ - if (len > IWL49_MAX_BSM_SIZE) - return -EINVAL; - - /* Tell bootstrap uCode where to find the "Initialize" uCode - * in host DRAM ... host DRAM physical address bits 35:4 for 4965. - * NOTE: iwl_init_alive_start() will replace these values, - * after the "initialize" uCode has run, to point to - * runtime/protocol instructions and backup data cache. - */ - pinst = priv->ucode_init.p_addr >> 4; - pdata = priv->ucode_init_data.p_addr >> 4; - inst_len = priv->ucode_init.len; - data_len = priv->ucode_init_data.len; - - iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); - iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); - iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); - iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); - - /* Fill BSM memory with bootstrap instructions */ - for (reg_offset = BSM_SRAM_LOWER_BOUND; - reg_offset < BSM_SRAM_LOWER_BOUND + len; - reg_offset += sizeof(u32), image++) - _iwl_write_prph(priv, reg_offset, le32_to_cpu(*image)); - - ret = iwl4965_verify_bsm(priv); - if (ret) - return ret; - - /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ - iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); - iwl_write_prph(priv, BSM_WR_MEM_DST_REG, IWL49_RTC_INST_LOWER_BOUND); - iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); - - /* Load bootstrap code into instruction SRAM now, - * to prepare to load "initialize" uCode */ - iwl_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START); - - /* Wait for load of bootstrap uCode to finish */ - for (i = 0; i < 100; i++) { - done = iwl_read_prph(priv, BSM_WR_CTRL_REG); - if (!(done & BSM_WR_CTRL_REG_BIT_START)) - break; - udelay(10); - } - if (i < 100) - IWL_DEBUG_INFO(priv, "BSM write complete, poll %d iterations\n", i); - else { - IWL_ERR(priv, "BSM write did not complete!\n"); - return -EIO; - } - - /* Enable future boot loads whenever power management unit triggers it - * (e.g. when powering back up after power-save shutdown) */ - iwl_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START_EN); - - - return 0; -} - -/** - * iwl4965_set_ucode_ptrs - Set uCode address location - * - * Tell initialization uCode where to find runtime uCode. - * - * BSM registers initially contain pointers to initialization uCode. - * We need to replace them to load runtime uCode inst and data, - * and to save runtime data when powering down. - */ -static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv) -{ - dma_addr_t pinst; - dma_addr_t pdata; - int ret = 0; - - /* bits 35:4 for 4965 */ - pinst = priv->ucode_code.p_addr >> 4; - pdata = priv->ucode_data_backup.p_addr >> 4; - - /* Tell bootstrap uCode where to find image to load */ - iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); - iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); - iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, - priv->ucode_data.len); - - /* Inst byte count must be last to set up, bit 31 signals uCode - * that all new ptr/size info is in place */ - iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, - priv->ucode_code.len | BSM_DRAM_INST_LOAD); - IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n"); - - return ret; -} - -/** - * iwl4965_init_alive_start - Called after REPLY_ALIVE notification received - * - * Called after REPLY_ALIVE notification received from "initialize" uCode. - * - * The 4965 "initialize" ALIVE reply contains calibration data for: - * Voltage, temperature, and MIMO tx gain correction, now stored in priv - * (3945 does not contain this data). - * - * Tell "initialize" uCode to go ahead and load the runtime uCode. -*/ -static void iwl4965_init_alive_start(struct iwl_priv *priv) -{ - /* Bootstrap uCode has loaded initialize uCode ... verify inst image. - * This is a paranoid check, because we would not have gotten the - * "initialize" alive if code weren't properly loaded. */ - if (iwl_verify_ucode(priv)) { - /* Runtime instruction load was bad; - * take it all the way back down so we can try again */ - IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n"); - goto restart; - } - - /* Calculate temperature */ - priv->temperature = iwl4965_hw_get_temperature(priv); - - /* Send pointers to protocol/runtime uCode image ... init code will - * load and launch runtime uCode, which will send us another "Alive" - * notification. */ - IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); - if (iwl4965_set_ucode_ptrs(priv)) { - /* Runtime instruction load won't happen; - * take it all the way back down so we can try again */ - IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n"); - goto restart; - } - return; - -restart: - queue_work(priv->workqueue, &priv->restart); -} - -static bool is_ht40_channel(__le32 rxon_flags) -{ - int chan_mod = le32_to_cpu(rxon_flags & RXON_FLG_CHANNEL_MODE_MSK) - >> RXON_FLG_CHANNEL_MODE_POS; - return ((chan_mod == CHANNEL_MODE_PURE_40) || - (chan_mod == CHANNEL_MODE_MIXED)); -} - -/* - * EEPROM handlers - */ -static u16 iwl4965_eeprom_calib_version(struct iwl_priv *priv) -{ - return iwl_eeprom_query16(priv, EEPROM_4965_CALIB_VERSION_OFFSET); -} - -/* - * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask - * must be called under priv->lock and mac access - */ -static void iwl4965_txq_set_sched(struct iwl_priv *priv, u32 mask) -{ - iwl_write_prph(priv, IWL49_SCD_TXFACT, mask); -} - -static void iwl4965_nic_config(struct iwl_priv *priv) -{ - unsigned long flags; - u16 radio_cfg; - - spin_lock_irqsave(&priv->lock, flags); - - radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); - - /* write radio config values to register */ - if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) == EEPROM_4965_RF_CFG_TYPE_MAX) - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | - EEPROM_RF_CFG_STEP_MSK(radio_cfg) | - EEPROM_RF_CFG_DASH_MSK(radio_cfg)); - - /* set CSR_HW_CONFIG_REG for uCode use */ - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | - CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); - - priv->calib_info = (struct iwl_eeprom_calib_info *) - iwl_eeprom_query_addr(priv, EEPROM_4965_CALIB_TXPOWER_OFFSET); - - spin_unlock_irqrestore(&priv->lock, flags); -} - -/* Reset differential Rx gains in NIC to prepare for chain noise calibration. - * Called after every association, but this runs only once! - * ... once chain noise is calibrated the first time, it's good forever. */ -static void iwl4965_chain_noise_reset(struct iwl_priv *priv) -{ - struct iwl_chain_noise_data *data = &(priv->chain_noise_data); - - if ((data->state == IWL_CHAIN_NOISE_ALIVE) && - iwl_is_any_associated(priv)) { - struct iwl_calib_diff_gain_cmd cmd; - - /* clear data for chain noise calibration algorithm */ - data->chain_noise_a = 0; - data->chain_noise_b = 0; - data->chain_noise_c = 0; - data->chain_signal_a = 0; - data->chain_signal_b = 0; - data->chain_signal_c = 0; - data->beacon_count = 0; - - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD; - cmd.diff_gain_a = 0; - cmd.diff_gain_b = 0; - cmd.diff_gain_c = 0; - if (iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, - sizeof(cmd), &cmd)) - IWL_ERR(priv, - "Could not send REPLY_PHY_CALIBRATION_CMD\n"); - data->state = IWL_CHAIN_NOISE_ACCUMULATE; - IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n"); - } -} - -static void iwl4965_gain_computation(struct iwl_priv *priv, - u32 *average_noise, - u16 min_average_noise_antenna_i, - u32 min_average_noise, - u8 default_chain) -{ - int i, ret; - struct iwl_chain_noise_data *data = &priv->chain_noise_data; - - data->delta_gain_code[min_average_noise_antenna_i] = 0; - - for (i = default_chain; i < NUM_RX_CHAINS; i++) { - s32 delta_g = 0; - - if (!(data->disconn_array[i]) && - (data->delta_gain_code[i] == - CHAIN_NOISE_DELTA_GAIN_INIT_VAL)) { - delta_g = average_noise[i] - min_average_noise; - data->delta_gain_code[i] = (u8)((delta_g * 10) / 15); - data->delta_gain_code[i] = - min(data->delta_gain_code[i], - (u8) CHAIN_NOISE_MAX_DELTA_GAIN_CODE); - - data->delta_gain_code[i] = - (data->delta_gain_code[i] | (1 << 2)); - } else { - data->delta_gain_code[i] = 0; - } - } - IWL_DEBUG_CALIB(priv, "delta_gain_codes: a %d b %d c %d\n", - data->delta_gain_code[0], - data->delta_gain_code[1], - data->delta_gain_code[2]); - - /* Differential gain gets sent to uCode only once */ - if (!data->radio_write) { - struct iwl_calib_diff_gain_cmd cmd; - data->radio_write = 1; - - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD; - cmd.diff_gain_a = data->delta_gain_code[0]; - cmd.diff_gain_b = data->delta_gain_code[1]; - cmd.diff_gain_c = data->delta_gain_code[2]; - ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, - sizeof(cmd), &cmd); - if (ret) - IWL_DEBUG_CALIB(priv, "fail sending cmd " - "REPLY_PHY_CALIBRATION_CMD\n"); - - /* TODO we might want recalculate - * rx_chain in rxon cmd */ - - /* Mark so we run this algo only once! */ - data->state = IWL_CHAIN_NOISE_CALIBRATED; - } -} - -static void iwl4965_bg_txpower_work(struct work_struct *work) -{ - struct iwl_priv *priv = container_of(work, struct iwl_priv, - txpower_work); - - /* If a scan happened to start before we got here - * then just return; the statistics notification will - * kick off another scheduled work to compensate for - * any temperature delta we missed here. */ - if (test_bit(STATUS_EXIT_PENDING, &priv->status) || - test_bit(STATUS_SCANNING, &priv->status)) - return; - - mutex_lock(&priv->mutex); - - /* Regardless of if we are associated, we must reconfigure the - * TX power since frames can be sent on non-radar channels while - * not associated */ - iwl4965_send_tx_power(priv); - - /* Update last_temperature to keep is_calib_needed from running - * when it isn't needed... */ - priv->last_temperature = priv->temperature; - - mutex_unlock(&priv->mutex); -} - -/* - * Acquire priv->lock before calling this function ! - */ -static void iwl4965_set_wr_ptrs(struct iwl_priv *priv, int txq_id, u32 index) -{ - iwl_write_direct32(priv, HBUS_TARG_WRPTR, - (index & 0xff) | (txq_id << 8)); - iwl_write_prph(priv, IWL49_SCD_QUEUE_RDPTR(txq_id), index); -} - -/** - * iwl4965_tx_queue_set_status - (optionally) start Tx/Cmd queue - * @tx_fifo_id: Tx DMA/FIFO channel (range 0-7) that the queue will feed - * @scd_retry: (1) Indicates queue will be used in aggregation mode - * - * NOTE: Acquire priv->lock before calling this function ! - */ -static void iwl4965_tx_queue_set_status(struct iwl_priv *priv, - struct iwl_tx_queue *txq, - int tx_fifo_id, int scd_retry) -{ - int txq_id = txq->q.id; - - /* Find out whether to activate Tx queue */ - int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0; - - /* Set up and activate */ - iwl_write_prph(priv, IWL49_SCD_QUEUE_STATUS_BITS(txq_id), - (active << IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE) | - (tx_fifo_id << IWL49_SCD_QUEUE_STTS_REG_POS_TXF) | - (scd_retry << IWL49_SCD_QUEUE_STTS_REG_POS_WSL) | - (scd_retry << IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACK) | - IWL49_SCD_QUEUE_STTS_REG_MSK); - - txq->sched_retry = scd_retry; - - IWL_DEBUG_INFO(priv, "%s %s Queue %d on AC %d\n", - active ? "Activate" : "Deactivate", - scd_retry ? "BA" : "AC", txq_id, tx_fifo_id); -} - -static const s8 default_queue_to_tx_fifo[] = { - IWL_TX_FIFO_VO, - IWL_TX_FIFO_VI, - IWL_TX_FIFO_BE, - IWL_TX_FIFO_BK, - IWL49_CMD_FIFO_NUM, - IWL_TX_FIFO_UNUSED, - IWL_TX_FIFO_UNUSED, -}; - -static int iwl4965_alive_notify(struct iwl_priv *priv) -{ - u32 a; - unsigned long flags; - int i, chan; - u32 reg_val; - - spin_lock_irqsave(&priv->lock, flags); - - /* Clear 4965's internal Tx Scheduler data base */ - priv->scd_base_addr = iwl_read_prph(priv, IWL49_SCD_SRAM_BASE_ADDR); - a = priv->scd_base_addr + IWL49_SCD_CONTEXT_DATA_OFFSET; - for (; a < priv->scd_base_addr + IWL49_SCD_TX_STTS_BITMAP_OFFSET; a += 4) - iwl_write_targ_mem(priv, a, 0); - for (; a < priv->scd_base_addr + IWL49_SCD_TRANSLATE_TBL_OFFSET; a += 4) - iwl_write_targ_mem(priv, a, 0); - for (; a < priv->scd_base_addr + - IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4) - iwl_write_targ_mem(priv, a, 0); - - /* Tel 4965 where to find Tx byte count tables */ - iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR, - priv->scd_bc_tbls.dma >> 10); - - /* Enable DMA channel */ - for (chan = 0; chan < FH49_TCSR_CHNL_NUM ; chan++) - iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(chan), - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); - - /* Update FH chicken bits */ - reg_val = iwl_read_direct32(priv, FH_TX_CHICKEN_BITS_REG); - iwl_write_direct32(priv, FH_TX_CHICKEN_BITS_REG, - reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); - - /* Disable chain mode for all queues */ - iwl_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0); - - /* Initialize each Tx queue (including the command queue) */ - for (i = 0; i < priv->hw_params.max_txq_num; i++) { - - /* TFD circular buffer read/write indexes */ - iwl_write_prph(priv, IWL49_SCD_QUEUE_RDPTR(i), 0); - iwl_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8)); - - /* Max Tx Window size for Scheduler-ACK mode */ - iwl_write_targ_mem(priv, priv->scd_base_addr + - IWL49_SCD_CONTEXT_QUEUE_OFFSET(i), - (SCD_WIN_SIZE << - IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) & - IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK); - - /* Frame limit */ - iwl_write_targ_mem(priv, priv->scd_base_addr + - IWL49_SCD_CONTEXT_QUEUE_OFFSET(i) + - sizeof(u32), - (SCD_FRAME_LIMIT << - IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & - IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK); - - } - iwl_write_prph(priv, IWL49_SCD_INTERRUPT_MASK, - (1 << priv->hw_params.max_txq_num) - 1); - - /* Activate all Tx DMA/FIFO channels */ - priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 6)); - - iwl4965_set_wr_ptrs(priv, IWL_DEFAULT_CMD_QUEUE_NUM, 0); - - /* make sure all queue are not stopped */ - memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); - for (i = 0; i < 4; i++) - atomic_set(&priv->queue_stop_count[i], 0); - - /* reset to 0 to enable all the queue first */ - priv->txq_ctx_active_msk = 0; - /* Map each Tx/cmd queue to its corresponding fifo */ - BUILD_BUG_ON(ARRAY_SIZE(default_queue_to_tx_fifo) != 7); - - for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) { - int ac = default_queue_to_tx_fifo[i]; - - iwl_txq_ctx_activate(priv, i); - - if (ac == IWL_TX_FIFO_UNUSED) - continue; - - iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0); - } - - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; -} - -static struct iwl_sensitivity_ranges iwl4965_sensitivity = { - .min_nrg_cck = 97, - .max_nrg_cck = 0, /* not used, set to 0 */ - - .auto_corr_min_ofdm = 85, - .auto_corr_min_ofdm_mrc = 170, - .auto_corr_min_ofdm_x1 = 105, - .auto_corr_min_ofdm_mrc_x1 = 220, - - .auto_corr_max_ofdm = 120, - .auto_corr_max_ofdm_mrc = 210, - .auto_corr_max_ofdm_x1 = 140, - .auto_corr_max_ofdm_mrc_x1 = 270, - - .auto_corr_min_cck = 125, - .auto_corr_max_cck = 200, - .auto_corr_min_cck_mrc = 200, - .auto_corr_max_cck_mrc = 400, - - .nrg_th_cck = 100, - .nrg_th_ofdm = 100, - - .barker_corr_th_min = 190, - .barker_corr_th_min_mrc = 390, - .nrg_th_cca = 62, -}; - -static void iwl4965_set_ct_threshold(struct iwl_priv *priv) -{ - /* want Kelvin */ - priv->hw_params.ct_kill_threshold = - CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY); -} - -/** - * iwl4965_hw_set_hw_params - * - * Called when initializing driver - */ -static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) -{ - if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && - priv->cfg->mod_params->num_of_queues <= IWL49_NUM_QUEUES) - priv->cfg->base_params->num_of_queues = - priv->cfg->mod_params->num_of_queues; - - priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; - priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM; - priv->hw_params.scd_bc_tbls_size = - priv->cfg->base_params->num_of_queues * - sizeof(struct iwl4965_scd_bc_tbl); - priv->hw_params.tfd_size = sizeof(struct iwl_tfd); - priv->hw_params.max_stations = IWL4965_STATION_COUNT; - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL4965_BROADCAST_ID; - priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE; - priv->hw_params.max_inst_size = IWL49_RTC_INST_SIZE; - priv->hw_params.max_bsm_size = BSM_SRAM_SIZE; - priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_5GHZ); - - priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; - - priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); - priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); - priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; - priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; - - iwl4965_set_ct_threshold(priv); - - priv->hw_params.sens = &iwl4965_sensitivity; - priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; - - return 0; -} - -static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res) -{ - s32 sign = 1; - - if (num < 0) { - sign = -sign; - num = -num; - } - if (denom < 0) { - sign = -sign; - denom = -denom; - } - *res = 1; - *res = ((num * 2 + denom) / (denom * 2)) * sign; - - return 1; -} - -/** - * iwl4965_get_voltage_compensation - Power supply voltage comp for txpower - * - * Determines power supply voltage compensation for txpower calculations. - * Returns number of 1/2-dB steps to subtract from gain table index, - * to compensate for difference between power supply voltage during - * factory measurements, vs. current power supply voltage. - * - * Voltage indication is higher for lower voltage. - * Lower voltage requires more gain (lower gain table index). - */ -static s32 iwl4965_get_voltage_compensation(s32 eeprom_voltage, - s32 current_voltage) -{ - s32 comp = 0; - - if ((TX_POWER_IWL_ILLEGAL_VOLTAGE == eeprom_voltage) || - (TX_POWER_IWL_ILLEGAL_VOLTAGE == current_voltage)) - return 0; - - iwl4965_math_div_round(current_voltage - eeprom_voltage, - TX_POWER_IWL_VOLTAGE_CODES_PER_03V, &comp); - - if (current_voltage > eeprom_voltage) - comp *= 2; - if ((comp < -2) || (comp > 2)) - comp = 0; - - return comp; -} - -static s32 iwl4965_get_tx_atten_grp(u16 channel) -{ - if (channel >= CALIB_IWL_TX_ATTEN_GR5_FCH && - channel <= CALIB_IWL_TX_ATTEN_GR5_LCH) - return CALIB_CH_GROUP_5; - - if (channel >= CALIB_IWL_TX_ATTEN_GR1_FCH && - channel <= CALIB_IWL_TX_ATTEN_GR1_LCH) - return CALIB_CH_GROUP_1; - - if (channel >= CALIB_IWL_TX_ATTEN_GR2_FCH && - channel <= CALIB_IWL_TX_ATTEN_GR2_LCH) - return CALIB_CH_GROUP_2; - - if (channel >= CALIB_IWL_TX_ATTEN_GR3_FCH && - channel <= CALIB_IWL_TX_ATTEN_GR3_LCH) - return CALIB_CH_GROUP_3; - - if (channel >= CALIB_IWL_TX_ATTEN_GR4_FCH && - channel <= CALIB_IWL_TX_ATTEN_GR4_LCH) - return CALIB_CH_GROUP_4; - - return -1; -} - -static u32 iwl4965_get_sub_band(const struct iwl_priv *priv, u32 channel) -{ - s32 b = -1; - - for (b = 0; b < EEPROM_TX_POWER_BANDS; b++) { - if (priv->calib_info->band_info[b].ch_from == 0) - continue; - - if ((channel >= priv->calib_info->band_info[b].ch_from) - && (channel <= priv->calib_info->band_info[b].ch_to)) - break; - } - - return b; -} - -static s32 iwl4965_interpolate_value(s32 x, s32 x1, s32 y1, s32 x2, s32 y2) -{ - s32 val; - - if (x2 == x1) - return y1; - else { - iwl4965_math_div_round((x2 - x) * (y1 - y2), (x2 - x1), &val); - return val + y2; - } -} - -/** - * iwl4965_interpolate_chan - Interpolate factory measurements for one channel - * - * Interpolates factory measurements from the two sample channels within a - * sub-band, to apply to channel of interest. Interpolation is proportional to - * differences in channel frequencies, which is proportional to differences - * in channel number. - */ -static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel, - struct iwl_eeprom_calib_ch_info *chan_info) -{ - s32 s = -1; - u32 c; - u32 m; - const struct iwl_eeprom_calib_measure *m1; - const struct iwl_eeprom_calib_measure *m2; - struct iwl_eeprom_calib_measure *omeas; - u32 ch_i1; - u32 ch_i2; - - s = iwl4965_get_sub_band(priv, channel); - if (s >= EEPROM_TX_POWER_BANDS) { - IWL_ERR(priv, "Tx Power can not find channel %d\n", channel); - return -1; - } - - ch_i1 = priv->calib_info->band_info[s].ch1.ch_num; - ch_i2 = priv->calib_info->band_info[s].ch2.ch_num; - chan_info->ch_num = (u8) channel; - - IWL_DEBUG_TXPOWER(priv, "channel %d subband %d factory cal ch %d & %d\n", - channel, s, ch_i1, ch_i2); - - for (c = 0; c < EEPROM_TX_POWER_TX_CHAINS; c++) { - for (m = 0; m < EEPROM_TX_POWER_MEASUREMENTS; m++) { - m1 = &(priv->calib_info->band_info[s].ch1. - measurements[c][m]); - m2 = &(priv->calib_info->band_info[s].ch2. - measurements[c][m]); - omeas = &(chan_info->measurements[c][m]); - - omeas->actual_pow = - (u8) iwl4965_interpolate_value(channel, ch_i1, - m1->actual_pow, - ch_i2, - m2->actual_pow); - omeas->gain_idx = - (u8) iwl4965_interpolate_value(channel, ch_i1, - m1->gain_idx, ch_i2, - m2->gain_idx); - omeas->temperature = - (u8) iwl4965_interpolate_value(channel, ch_i1, - m1->temperature, - ch_i2, - m2->temperature); - omeas->pa_det = - (s8) iwl4965_interpolate_value(channel, ch_i1, - m1->pa_det, ch_i2, - m2->pa_det); - - IWL_DEBUG_TXPOWER(priv, - "chain %d meas %d AP1=%d AP2=%d AP=%d\n", c, m, - m1->actual_pow, m2->actual_pow, omeas->actual_pow); - IWL_DEBUG_TXPOWER(priv, - "chain %d meas %d NI1=%d NI2=%d NI=%d\n", c, m, - m1->gain_idx, m2->gain_idx, omeas->gain_idx); - IWL_DEBUG_TXPOWER(priv, - "chain %d meas %d PA1=%d PA2=%d PA=%d\n", c, m, - m1->pa_det, m2->pa_det, omeas->pa_det); - IWL_DEBUG_TXPOWER(priv, - "chain %d meas %d T1=%d T2=%d T=%d\n", c, m, - m1->temperature, m2->temperature, - omeas->temperature); - } - } - - return 0; -} - -/* bit-rate-dependent table to prevent Tx distortion, in half-dB units, - * for OFDM 6, 12, 18, 24, 36, 48, 54, 60 MBit, and CCK all rates. */ -static s32 back_off_table[] = { - 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM SISO 20 MHz */ - 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM MIMO 20 MHz */ - 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM SISO 40 MHz */ - 10, 10, 10, 10, 10, 15, 17, 20, /* OFDM MIMO 40 MHz */ - 10 /* CCK */ -}; - -/* Thermal compensation values for txpower for various frequency ranges ... - * ratios from 3:1 to 4.5:1 of degrees (Celsius) per half-dB gain adjust */ -static struct iwl4965_txpower_comp_entry { - s32 degrees_per_05db_a; - s32 degrees_per_05db_a_denom; -} tx_power_cmp_tble[CALIB_CH_GROUP_MAX] = { - {9, 2}, /* group 0 5.2, ch 34-43 */ - {4, 1}, /* group 1 5.2, ch 44-70 */ - {4, 1}, /* group 2 5.2, ch 71-124 */ - {4, 1}, /* group 3 5.2, ch 125-200 */ - {3, 1} /* group 4 2.4, ch all */ -}; - -static s32 get_min_power_index(s32 rate_power_index, u32 band) -{ - if (!band) { - if ((rate_power_index & 7) <= 4) - return MIN_TX_GAIN_INDEX_52GHZ_EXT; - } - return MIN_TX_GAIN_INDEX; -} - -struct gain_entry { - u8 dsp; - u8 radio; -}; - -static const struct gain_entry gain_table[2][108] = { - /* 5.2GHz power gain index table */ - { - {123, 0x3F}, /* highest txpower */ - {117, 0x3F}, - {110, 0x3F}, - {104, 0x3F}, - {98, 0x3F}, - {110, 0x3E}, - {104, 0x3E}, - {98, 0x3E}, - {110, 0x3D}, - {104, 0x3D}, - {98, 0x3D}, - {110, 0x3C}, - {104, 0x3C}, - {98, 0x3C}, - {110, 0x3B}, - {104, 0x3B}, - {98, 0x3B}, - {110, 0x3A}, - {104, 0x3A}, - {98, 0x3A}, - {110, 0x39}, - {104, 0x39}, - {98, 0x39}, - {110, 0x38}, - {104, 0x38}, - {98, 0x38}, - {110, 0x37}, - {104, 0x37}, - {98, 0x37}, - {110, 0x36}, - {104, 0x36}, - {98, 0x36}, - {110, 0x35}, - {104, 0x35}, - {98, 0x35}, - {110, 0x34}, - {104, 0x34}, - {98, 0x34}, - {110, 0x33}, - {104, 0x33}, - {98, 0x33}, - {110, 0x32}, - {104, 0x32}, - {98, 0x32}, - {110, 0x31}, - {104, 0x31}, - {98, 0x31}, - {110, 0x30}, - {104, 0x30}, - {98, 0x30}, - {110, 0x25}, - {104, 0x25}, - {98, 0x25}, - {110, 0x24}, - {104, 0x24}, - {98, 0x24}, - {110, 0x23}, - {104, 0x23}, - {98, 0x23}, - {110, 0x22}, - {104, 0x18}, - {98, 0x18}, - {110, 0x17}, - {104, 0x17}, - {98, 0x17}, - {110, 0x16}, - {104, 0x16}, - {98, 0x16}, - {110, 0x15}, - {104, 0x15}, - {98, 0x15}, - {110, 0x14}, - {104, 0x14}, - {98, 0x14}, - {110, 0x13}, - {104, 0x13}, - {98, 0x13}, - {110, 0x12}, - {104, 0x08}, - {98, 0x08}, - {110, 0x07}, - {104, 0x07}, - {98, 0x07}, - {110, 0x06}, - {104, 0x06}, - {98, 0x06}, - {110, 0x05}, - {104, 0x05}, - {98, 0x05}, - {110, 0x04}, - {104, 0x04}, - {98, 0x04}, - {110, 0x03}, - {104, 0x03}, - {98, 0x03}, - {110, 0x02}, - {104, 0x02}, - {98, 0x02}, - {110, 0x01}, - {104, 0x01}, - {98, 0x01}, - {110, 0x00}, - {104, 0x00}, - {98, 0x00}, - {93, 0x00}, - {88, 0x00}, - {83, 0x00}, - {78, 0x00}, - }, - /* 2.4GHz power gain index table */ - { - {110, 0x3f}, /* highest txpower */ - {104, 0x3f}, - {98, 0x3f}, - {110, 0x3e}, - {104, 0x3e}, - {98, 0x3e}, - {110, 0x3d}, - {104, 0x3d}, - {98, 0x3d}, - {110, 0x3c}, - {104, 0x3c}, - {98, 0x3c}, - {110, 0x3b}, - {104, 0x3b}, - {98, 0x3b}, - {110, 0x3a}, - {104, 0x3a}, - {98, 0x3a}, - {110, 0x39}, - {104, 0x39}, - {98, 0x39}, - {110, 0x38}, - {104, 0x38}, - {98, 0x38}, - {110, 0x37}, - {104, 0x37}, - {98, 0x37}, - {110, 0x36}, - {104, 0x36}, - {98, 0x36}, - {110, 0x35}, - {104, 0x35}, - {98, 0x35}, - {110, 0x34}, - {104, 0x34}, - {98, 0x34}, - {110, 0x33}, - {104, 0x33}, - {98, 0x33}, - {110, 0x32}, - {104, 0x32}, - {98, 0x32}, - {110, 0x31}, - {104, 0x31}, - {98, 0x31}, - {110, 0x30}, - {104, 0x30}, - {98, 0x30}, - {110, 0x6}, - {104, 0x6}, - {98, 0x6}, - {110, 0x5}, - {104, 0x5}, - {98, 0x5}, - {110, 0x4}, - {104, 0x4}, - {98, 0x4}, - {110, 0x3}, - {104, 0x3}, - {98, 0x3}, - {110, 0x2}, - {104, 0x2}, - {98, 0x2}, - {110, 0x1}, - {104, 0x1}, - {98, 0x1}, - {110, 0x0}, - {104, 0x0}, - {98, 0x0}, - {97, 0}, - {96, 0}, - {95, 0}, - {94, 0}, - {93, 0}, - {92, 0}, - {91, 0}, - {90, 0}, - {89, 0}, - {88, 0}, - {87, 0}, - {86, 0}, - {85, 0}, - {84, 0}, - {83, 0}, - {82, 0}, - {81, 0}, - {80, 0}, - {79, 0}, - {78, 0}, - {77, 0}, - {76, 0}, - {75, 0}, - {74, 0}, - {73, 0}, - {72, 0}, - {71, 0}, - {70, 0}, - {69, 0}, - {68, 0}, - {67, 0}, - {66, 0}, - {65, 0}, - {64, 0}, - {63, 0}, - {62, 0}, - {61, 0}, - {60, 0}, - {59, 0}, - } -}; - -static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, - u8 is_ht40, u8 ctrl_chan_high, - struct iwl4965_tx_power_db *tx_power_tbl) -{ - u8 saturation_power; - s32 target_power; - s32 user_target_power; - s32 power_limit; - s32 current_temp; - s32 reg_limit; - s32 current_regulatory; - s32 txatten_grp = CALIB_CH_GROUP_MAX; - int i; - int c; - const struct iwl_channel_info *ch_info = NULL; - struct iwl_eeprom_calib_ch_info ch_eeprom_info; - const struct iwl_eeprom_calib_measure *measurement; - s16 voltage; - s32 init_voltage; - s32 voltage_compensation; - s32 degrees_per_05db_num; - s32 degrees_per_05db_denom; - s32 factory_temp; - s32 temperature_comp[2]; - s32 factory_gain_index[2]; - s32 factory_actual_pwr[2]; - s32 power_index; - - /* tx_power_user_lmt is in dBm, convert to half-dBm (half-dB units - * are used for indexing into txpower table) */ - user_target_power = 2 * priv->tx_power_user_lmt; - - /* Get current (RXON) channel, band, width */ - IWL_DEBUG_TXPOWER(priv, "chan %d band %d is_ht40 %d\n", channel, band, - is_ht40); - - ch_info = iwl_get_channel_info(priv, priv->band, channel); - - if (!is_channel_valid(ch_info)) - return -EINVAL; - - /* get txatten group, used to select 1) thermal txpower adjustment - * and 2) mimo txpower balance between Tx chains. */ - txatten_grp = iwl4965_get_tx_atten_grp(channel); - if (txatten_grp < 0) { - IWL_ERR(priv, "Can't find txatten group for channel %d.\n", - channel); - return -EINVAL; - } - - IWL_DEBUG_TXPOWER(priv, "channel %d belongs to txatten group %d\n", - channel, txatten_grp); - - if (is_ht40) { - if (ctrl_chan_high) - channel -= 2; - else - channel += 2; - } - - /* hardware txpower limits ... - * saturation (clipping distortion) txpowers are in half-dBm */ - if (band) - saturation_power = priv->calib_info->saturation_power24; - else - saturation_power = priv->calib_info->saturation_power52; - - if (saturation_power < IWL_TX_POWER_SATURATION_MIN || - saturation_power > IWL_TX_POWER_SATURATION_MAX) { - if (band) - saturation_power = IWL_TX_POWER_DEFAULT_SATURATION_24; - else - saturation_power = IWL_TX_POWER_DEFAULT_SATURATION_52; - } - - /* regulatory txpower limits ... reg_limit values are in half-dBm, - * max_power_avg values are in dBm, convert * 2 */ - if (is_ht40) - reg_limit = ch_info->ht40_max_power_avg * 2; - else - reg_limit = ch_info->max_power_avg * 2; - - if ((reg_limit < IWL_TX_POWER_REGULATORY_MIN) || - (reg_limit > IWL_TX_POWER_REGULATORY_MAX)) { - if (band) - reg_limit = IWL_TX_POWER_DEFAULT_REGULATORY_24; - else - reg_limit = IWL_TX_POWER_DEFAULT_REGULATORY_52; - } - - /* Interpolate txpower calibration values for this channel, - * based on factory calibration tests on spaced channels. */ - iwl4965_interpolate_chan(priv, channel, &ch_eeprom_info); - - /* calculate tx gain adjustment based on power supply voltage */ - voltage = le16_to_cpu(priv->calib_info->voltage); - init_voltage = (s32)le32_to_cpu(priv->card_alive_init.voltage); - voltage_compensation = - iwl4965_get_voltage_compensation(voltage, init_voltage); - - IWL_DEBUG_TXPOWER(priv, "curr volt %d eeprom volt %d volt comp %d\n", - init_voltage, - voltage, voltage_compensation); - - /* get current temperature (Celsius) */ - current_temp = max(priv->temperature, IWL_TX_POWER_TEMPERATURE_MIN); - current_temp = min(priv->temperature, IWL_TX_POWER_TEMPERATURE_MAX); - current_temp = KELVIN_TO_CELSIUS(current_temp); - - /* select thermal txpower adjustment params, based on channel group - * (same frequency group used for mimo txatten adjustment) */ - degrees_per_05db_num = - tx_power_cmp_tble[txatten_grp].degrees_per_05db_a; - degrees_per_05db_denom = - tx_power_cmp_tble[txatten_grp].degrees_per_05db_a_denom; - - /* get per-chain txpower values from factory measurements */ - for (c = 0; c < 2; c++) { - measurement = &ch_eeprom_info.measurements[c][1]; - - /* txgain adjustment (in half-dB steps) based on difference - * between factory and current temperature */ - factory_temp = measurement->temperature; - iwl4965_math_div_round((current_temp - factory_temp) * - degrees_per_05db_denom, - degrees_per_05db_num, - &temperature_comp[c]); - - factory_gain_index[c] = measurement->gain_idx; - factory_actual_pwr[c] = measurement->actual_pow; - - IWL_DEBUG_TXPOWER(priv, "chain = %d\n", c); - IWL_DEBUG_TXPOWER(priv, "fctry tmp %d, " - "curr tmp %d, comp %d steps\n", - factory_temp, current_temp, - temperature_comp[c]); - - IWL_DEBUG_TXPOWER(priv, "fctry idx %d, fctry pwr %d\n", - factory_gain_index[c], - factory_actual_pwr[c]); - } - - /* for each of 33 bit-rates (including 1 for CCK) */ - for (i = 0; i < POWER_TABLE_NUM_ENTRIES; i++) { - u8 is_mimo_rate; - union iwl4965_tx_power_dual_stream tx_power; - - /* for mimo, reduce each chain's txpower by half - * (3dB, 6 steps), so total output power is regulatory - * compliant. */ - if (i & 0x8) { - current_regulatory = reg_limit - - IWL_TX_POWER_MIMO_REGULATORY_COMPENSATION; - is_mimo_rate = 1; - } else { - current_regulatory = reg_limit; - is_mimo_rate = 0; - } - - /* find txpower limit, either hardware or regulatory */ - power_limit = saturation_power - back_off_table[i]; - if (power_limit > current_regulatory) - power_limit = current_regulatory; - - /* reduce user's txpower request if necessary - * for this rate on this channel */ - target_power = user_target_power; - if (target_power > power_limit) - target_power = power_limit; - - IWL_DEBUG_TXPOWER(priv, "rate %d sat %d reg %d usr %d tgt %d\n", - i, saturation_power - back_off_table[i], - current_regulatory, user_target_power, - target_power); - - /* for each of 2 Tx chains (radio transmitters) */ - for (c = 0; c < 2; c++) { - s32 atten_value; - - if (is_mimo_rate) - atten_value = - (s32)le32_to_cpu(priv->card_alive_init. - tx_atten[txatten_grp][c]); - else - atten_value = 0; - - /* calculate index; higher index means lower txpower */ - power_index = (u8) (factory_gain_index[c] - - (target_power - - factory_actual_pwr[c]) - - temperature_comp[c] - - voltage_compensation + - atten_value); - -/* IWL_DEBUG_TXPOWER(priv, "calculated txpower index %d\n", - power_index); */ - - if (power_index < get_min_power_index(i, band)) - power_index = get_min_power_index(i, band); - - /* adjust 5 GHz index to support negative indexes */ - if (!band) - power_index += 9; - - /* CCK, rate 32, reduce txpower for CCK */ - if (i == POWER_TABLE_CCK_ENTRY) - power_index += - IWL_TX_POWER_CCK_COMPENSATION_C_STEP; - - /* stay within the table! */ - if (power_index > 107) { - IWL_WARN(priv, "txpower index %d > 107\n", - power_index); - power_index = 107; - } - if (power_index < 0) { - IWL_WARN(priv, "txpower index %d < 0\n", - power_index); - power_index = 0; - } - - /* fill txpower command for this rate/chain */ - tx_power.s.radio_tx_gain[c] = - gain_table[band][power_index].radio; - tx_power.s.dsp_predis_atten[c] = - gain_table[band][power_index].dsp; - - IWL_DEBUG_TXPOWER(priv, "chain %d mimo %d index %d " - "gain 0x%02x dsp %d\n", - c, atten_value, power_index, - tx_power.s.radio_tx_gain[c], - tx_power.s.dsp_predis_atten[c]); - } /* for each chain */ - - tx_power_tbl->power_tbl[i].dw = cpu_to_le32(tx_power.dw); - - } /* for each rate */ - - return 0; -} - -/** - * iwl4965_send_tx_power - Configure the TXPOWER level user limit - * - * Uses the active RXON for channel, band, and characteristics (ht40, high) - * The power limit is taken from priv->tx_power_user_lmt. - */ -static int iwl4965_send_tx_power(struct iwl_priv *priv) -{ - struct iwl4965_txpowertable_cmd cmd = { 0 }; - int ret; - u8 band = 0; - bool is_ht40 = false; - u8 ctrl_chan_high = 0; - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status), - "TX Power requested while scanning!\n")) - return -EAGAIN; - - band = priv->band == IEEE80211_BAND_2GHZ; - - is_ht40 = is_ht40_channel(ctx->active.flags); - - if (is_ht40 && (ctx->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) - ctrl_chan_high = 1; - - cmd.band = band; - cmd.channel = ctx->active.channel; - - ret = iwl4965_fill_txpower_tbl(priv, band, - le16_to_cpu(ctx->active.channel), - is_ht40, ctrl_chan_high, &cmd.tx_power); - if (ret) - goto out; - - ret = iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, sizeof(cmd), &cmd); - -out: - return ret; -} - -static int iwl4965_send_rxon_assoc(struct iwl_priv *priv, - struct iwl_rxon_context *ctx) -{ - int ret = 0; - struct iwl4965_rxon_assoc_cmd rxon_assoc; - const struct iwl_rxon_cmd *rxon1 = &ctx->staging; - const struct iwl_rxon_cmd *rxon2 = &ctx->active; - - if ((rxon1->flags == rxon2->flags) && - (rxon1->filter_flags == rxon2->filter_flags) && - (rxon1->cck_basic_rates == rxon2->cck_basic_rates) && - (rxon1->ofdm_ht_single_stream_basic_rates == - rxon2->ofdm_ht_single_stream_basic_rates) && - (rxon1->ofdm_ht_dual_stream_basic_rates == - rxon2->ofdm_ht_dual_stream_basic_rates) && - (rxon1->rx_chain == rxon2->rx_chain) && - (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) { - IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n"); - return 0; - } - - rxon_assoc.flags = ctx->staging.flags; - rxon_assoc.filter_flags = ctx->staging.filter_flags; - rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; - rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; - rxon_assoc.reserved = 0; - rxon_assoc.ofdm_ht_single_stream_basic_rates = - ctx->staging.ofdm_ht_single_stream_basic_rates; - rxon_assoc.ofdm_ht_dual_stream_basic_rates = - ctx->staging.ofdm_ht_dual_stream_basic_rates; - rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain; - - ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC, - sizeof(rxon_assoc), &rxon_assoc, NULL); - if (ret) - return ret; - - return ret; -} - -static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) -{ - /* cast away the const for active_rxon in this function */ - struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active; - int ret; - bool new_assoc = - !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); - - if (!iwl_is_alive(priv)) - return -EBUSY; - - if (!ctx->is_active) - return 0; - - /* always get timestamp with Rx frame */ - ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; - - ret = iwl_check_rxon_cmd(priv, ctx); - if (ret) { - IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); - return -EINVAL; - } - - /* - * receive commit_rxon request - * abort any previous channel switch if still in process - */ - if (priv->switch_rxon.switch_in_progress && - (priv->switch_rxon.channel != ctx->staging.channel)) { - IWL_DEBUG_11H(priv, "abort channel switch on %d\n", - le16_to_cpu(priv->switch_rxon.channel)); - iwl_chswitch_done(priv, false); - } - - /* If we don't need to send a full RXON, we can use - * iwl_rxon_assoc_cmd which is used to reconfigure filter - * and other flags for the current radio configuration. */ - if (!iwl_full_rxon_required(priv, ctx)) { - ret = iwl_send_rxon_assoc(priv, ctx); - if (ret) { - IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret); - return ret; - } - - memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); - iwl_print_rx_config_cmd(priv, ctx); - return 0; - } - - /* If we are currently associated and the new config requires - * an RXON_ASSOC and the new config wants the associated mask enabled, - * we must clear the associated from the active configuration - * before we apply the new config */ - if (iwl_is_associated_ctx(ctx) && new_assoc) { - IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); - active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - - ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, - sizeof(struct iwl_rxon_cmd), - active_rxon); - - /* If the mask clearing failed then we set - * active_rxon back to what it was previously */ - if (ret) { - active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; - IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret); - return ret; - } - iwl_clear_ucode_stations(priv, ctx); - iwl_restore_stations(priv, ctx); - ret = iwl_restore_default_wep_keys(priv, ctx); - if (ret) { - IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); - return ret; - } - } - - IWL_DEBUG_INFO(priv, "Sending RXON\n" - "* with%s RXON_FILTER_ASSOC_MSK\n" - "* channel = %d\n" - "* bssid = %pM\n", - (new_assoc ? "" : "out"), - le16_to_cpu(ctx->staging.channel), - ctx->staging.bssid_addr); - - iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto); - - /* Apply the new configuration - * RXON unassoc clears the station table in uCode so restoration of - * stations is needed after it (the RXON command) completes - */ - if (!new_assoc) { - ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, - sizeof(struct iwl_rxon_cmd), &ctx->staging); - if (ret) { - IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); - return ret; - } - IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n"); - memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); - iwl_clear_ucode_stations(priv, ctx); - iwl_restore_stations(priv, ctx); - ret = iwl_restore_default_wep_keys(priv, ctx); - if (ret) { - IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); - return ret; - } - } - if (new_assoc) { - priv->start_calib = 0; - /* Apply the new configuration - * RXON assoc doesn't clear the station table in uCode, - */ - ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, - sizeof(struct iwl_rxon_cmd), &ctx->staging); - if (ret) { - IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); - return ret; - } - memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); - } - iwl_print_rx_config_cmd(priv, ctx); - - iwl_init_sensitivity(priv); - - /* If we issue a new RXON command which required a tune then we must - * send a new TXPOWER command or we won't be able to Tx any frames */ - ret = iwl_set_tx_power(priv, priv->tx_power_next, true); - if (ret) { - IWL_ERR(priv, "Error sending TX power (%d)\n", ret); - return ret; - } - - return 0; -} - -static int iwl4965_hw_channel_switch(struct iwl_priv *priv, - struct ieee80211_channel_switch *ch_switch) -{ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - int rc; - u8 band = 0; - bool is_ht40 = false; - u8 ctrl_chan_high = 0; - struct iwl4965_channel_switch_cmd cmd; - const struct iwl_channel_info *ch_info; - u32 switch_time_in_usec, ucode_switch_time; - u16 ch; - u32 tsf_low; - u8 switch_count; - u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); - struct ieee80211_vif *vif = ctx->vif; - band = priv->band == IEEE80211_BAND_2GHZ; - - is_ht40 = is_ht40_channel(ctx->staging.flags); - - if (is_ht40 && - (ctx->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) - ctrl_chan_high = 1; - - cmd.band = band; - cmd.expect_beacon = 0; - ch = ch_switch->channel->hw_value; - cmd.channel = cpu_to_le16(ch); - cmd.rxon_flags = ctx->staging.flags; - cmd.rxon_filter_flags = ctx->staging.filter_flags; - switch_count = ch_switch->count; - tsf_low = ch_switch->timestamp & 0x0ffffffff; - /* - * calculate the ucode channel switch time - * adding TSF as one of the factor for when to switch - */ - if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) { - if (switch_count > ((priv->ucode_beacon_time - tsf_low) / - beacon_interval)) { - switch_count -= (priv->ucode_beacon_time - - tsf_low) / beacon_interval; - } else - switch_count = 0; - } - if (switch_count <= 1) - cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); - else { - switch_time_in_usec = - vif->bss_conf.beacon_int * switch_count * TIME_UNIT; - ucode_switch_time = iwl_usecs_to_beacons(priv, - switch_time_in_usec, - beacon_interval); - cmd.switch_time = iwl_add_beacon_time(priv, - priv->ucode_beacon_time, - ucode_switch_time, - beacon_interval); - } - IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", - cmd.switch_time); - ch_info = iwl_get_channel_info(priv, priv->band, ch); - if (ch_info) - cmd.expect_beacon = is_channel_radar(ch_info); - else { - IWL_ERR(priv, "invalid channel switch from %u to %u\n", - ctx->active.channel, ch); - return -EFAULT; - } - - rc = iwl4965_fill_txpower_tbl(priv, band, ch, is_ht40, - ctrl_chan_high, &cmd.tx_power); - if (rc) { - IWL_DEBUG_11H(priv, "error:%d fill txpower_tbl\n", rc); - return rc; - } - - priv->switch_rxon.channel = cmd.channel; - priv->switch_rxon.switch_in_progress = true; - - return iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); -} - -/** - * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array - */ -static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv, - struct iwl_tx_queue *txq, - u16 byte_cnt) -{ - struct iwl4965_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr; - int txq_id = txq->q.id; - int write_ptr = txq->q.write_ptr; - int len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; - __le16 bc_ent; - - WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX); - - bc_ent = cpu_to_le16(len & 0xFFF); - /* Set up byte count within first 256 entries */ - scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent; - - /* If within first 64 entries, duplicate at end */ - if (write_ptr < TFD_QUEUE_SIZE_BC_DUP) - scd_bc_tbl[txq_id]. - tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; -} - -/** - * iwl4965_hw_get_temperature - return the calibrated temperature (in Kelvin) - * @statistics: Provides the temperature reading from the uCode - * - * A return of <0 indicates bogus data in the statistics - */ -static int iwl4965_hw_get_temperature(struct iwl_priv *priv) -{ - s32 temperature; - s32 vt; - s32 R1, R2, R3; - u32 R4; - - if (test_bit(STATUS_TEMPERATURE, &priv->status) && - (priv->_agn.statistics.flag & - STATISTICS_REPLY_FLG_HT40_MODE_MSK)) { - IWL_DEBUG_TEMP(priv, "Running HT40 temperature calibration\n"); - R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]); - R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]); - R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[1]); - R4 = le32_to_cpu(priv->card_alive_init.therm_r4[1]); - } else { - IWL_DEBUG_TEMP(priv, "Running temperature calibration\n"); - R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[0]); - R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[0]); - R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[0]); - R4 = le32_to_cpu(priv->card_alive_init.therm_r4[0]); - } - - /* - * Temperature is only 23 bits, so sign extend out to 32. - * - * NOTE If we haven't received a statistics notification yet - * with an updated temperature, use R4 provided to us in the - * "initialize" ALIVE response. - */ - if (!test_bit(STATUS_TEMPERATURE, &priv->status)) - vt = sign_extend32(R4, 23); - else - vt = sign_extend32(le32_to_cpu(priv->_agn.statistics. - general.common.temperature), 23); - - IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt); - - if (R3 == R1) { - IWL_ERR(priv, "Calibration conflict R1 == R3\n"); - return -1; - } - - /* Calculate temperature in degrees Kelvin, adjust by 97%. - * Add offset to center the adjustment around 0 degrees Centigrade. */ - temperature = TEMPERATURE_CALIB_A_VAL * (vt - R2); - temperature /= (R3 - R1); - temperature = (temperature * 97) / 100 + TEMPERATURE_CALIB_KELVIN_OFFSET; - - IWL_DEBUG_TEMP(priv, "Calibrated temperature: %dK, %dC\n", - temperature, KELVIN_TO_CELSIUS(temperature)); - - return temperature; -} - -/* Adjust Txpower only if temperature variance is greater than threshold. */ -#define IWL_TEMPERATURE_THRESHOLD 3 - -/** - * iwl4965_is_temp_calib_needed - determines if new calibration is needed - * - * If the temperature changed has changed sufficiently, then a recalibration - * is needed. - * - * Assumes caller will replace priv->last_temperature once calibration - * executed. - */ -static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv) -{ - int temp_diff; - - if (!test_bit(STATUS_STATISTICS, &priv->status)) { - IWL_DEBUG_TEMP(priv, "Temperature not updated -- no statistics.\n"); - return 0; - } - - temp_diff = priv->temperature - priv->last_temperature; - - /* get absolute value */ - if (temp_diff < 0) { - IWL_DEBUG_POWER(priv, "Getting cooler, delta %d\n", temp_diff); - temp_diff = -temp_diff; - } else if (temp_diff == 0) - IWL_DEBUG_POWER(priv, "Temperature unchanged\n"); - else - IWL_DEBUG_POWER(priv, "Getting warmer, delta %d\n", temp_diff); - - if (temp_diff < IWL_TEMPERATURE_THRESHOLD) { - IWL_DEBUG_POWER(priv, " => thermal txpower calib not needed\n"); - return 0; - } - - IWL_DEBUG_POWER(priv, " => thermal txpower calib needed\n"); - - return 1; -} - -static void iwl4965_temperature_calib(struct iwl_priv *priv) -{ - s32 temp; - - temp = iwl4965_hw_get_temperature(priv); - if (temp < 0) - return; - - if (priv->temperature != temp) { - if (priv->temperature) - IWL_DEBUG_TEMP(priv, "Temperature changed " - "from %dC to %dC\n", - KELVIN_TO_CELSIUS(priv->temperature), - KELVIN_TO_CELSIUS(temp)); - else - IWL_DEBUG_TEMP(priv, "Temperature " - "initialized to %dC\n", - KELVIN_TO_CELSIUS(temp)); - } - - priv->temperature = temp; - iwl_tt_handler(priv); - set_bit(STATUS_TEMPERATURE, &priv->status); - - if (!priv->disable_tx_power_cal && - unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && - iwl4965_is_temp_calib_needed(priv)) - queue_work(priv->workqueue, &priv->txpower_work); -} - -/** - * iwl4965_tx_queue_stop_scheduler - Stop queue, but keep configuration - */ -static void iwl4965_tx_queue_stop_scheduler(struct iwl_priv *priv, - u16 txq_id) -{ - /* Simply stop the queue, but don't change any configuration; - * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ - iwl_write_prph(priv, - IWL49_SCD_QUEUE_STATUS_BITS(txq_id), - (0 << IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE)| - (1 << IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); -} - -/** - * txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE - * priv->lock must be held by the caller - */ -static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, - u16 ssn_idx, u8 tx_fifo) -{ - if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || - (IWL49_FIRST_AMPDU_QUEUE + - priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { - IWL_WARN(priv, - "queue number out of range: %d, must be %d to %d\n", - txq_id, IWL49_FIRST_AMPDU_QUEUE, - IWL49_FIRST_AMPDU_QUEUE + - priv->cfg->base_params->num_of_ampdu_queues - 1); - return -EINVAL; - } - - iwl4965_tx_queue_stop_scheduler(priv, txq_id); - - iwl_clear_bits_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, (1 << txq_id)); - - priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); - priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); - /* supposes that ssn_idx is valid (!= 0xFFF) */ - iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx); - - iwl_clear_bits_prph(priv, IWL49_SCD_INTERRUPT_MASK, (1 << txq_id)); - iwl_txq_ctx_deactivate(priv, txq_id); - iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0); - - return 0; -} - -/** - * iwl4965_tx_queue_set_q2ratid - Map unique receiver/tid combination to a queue - */ -static int iwl4965_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid, - u16 txq_id) -{ - u32 tbl_dw_addr; - u32 tbl_dw; - u16 scd_q2ratid; - - scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK; - - tbl_dw_addr = priv->scd_base_addr + - IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id); - - tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr); - - if (txq_id & 0x1) - tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); - else - tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); - - iwl_write_targ_mem(priv, tbl_dw_addr, tbl_dw); - - return 0; -} - - -/** - * iwl4965_tx_queue_agg_enable - Set up & enable aggregation for selected queue - * - * NOTE: txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE, - * i.e. it must be one of the higher queues used for aggregation - */ -static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, - int tx_fifo, int sta_id, int tid, u16 ssn_idx) -{ - unsigned long flags; - u16 ra_tid; - int ret; - - if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || - (IWL49_FIRST_AMPDU_QUEUE + - priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { - IWL_WARN(priv, - "queue number out of range: %d, must be %d to %d\n", - txq_id, IWL49_FIRST_AMPDU_QUEUE, - IWL49_FIRST_AMPDU_QUEUE + - priv->cfg->base_params->num_of_ampdu_queues - 1); - return -EINVAL; - } - - ra_tid = BUILD_RAxTID(sta_id, tid); - - /* Modify device's station table to Tx this TID */ - ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); - if (ret) - return ret; - - spin_lock_irqsave(&priv->lock, flags); - - /* Stop this Tx queue before configuring it */ - iwl4965_tx_queue_stop_scheduler(priv, txq_id); - - /* Map receiver-address / traffic-ID to this queue */ - iwl4965_tx_queue_set_q2ratid(priv, ra_tid, txq_id); - - /* Set this queue as a chain-building queue */ - iwl_set_bits_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, (1 << txq_id)); - - /* Place first TFD at index corresponding to start sequence number. - * Assumes that ssn_idx is valid (!= 0xFFF) */ - priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); - priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); - iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx); - - /* Set up Tx window size and frame limit for this queue */ - iwl_write_targ_mem(priv, - priv->scd_base_addr + IWL49_SCD_CONTEXT_QUEUE_OFFSET(txq_id), - (SCD_WIN_SIZE << IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) & - IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK); - - iwl_write_targ_mem(priv, priv->scd_base_addr + - IWL49_SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), - (SCD_FRAME_LIMIT << IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) - & IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK); - - iwl_set_bits_prph(priv, IWL49_SCD_INTERRUPT_MASK, (1 << txq_id)); - - /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ - iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1); - - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; -} - - -static u16 iwl4965_get_hcmd_size(u8 cmd_id, u16 len) -{ - switch (cmd_id) { - case REPLY_RXON: - return (u16) sizeof(struct iwl4965_rxon_cmd); - default: - return len; - } -} - -static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) -{ - struct iwl4965_addsta_cmd *addsta = (struct iwl4965_addsta_cmd *)data; - addsta->mode = cmd->mode; - memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify)); - memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo)); - addsta->station_flags = cmd->station_flags; - addsta->station_flags_msk = cmd->station_flags_msk; - addsta->tid_disable_tx = cmd->tid_disable_tx; - addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid; - addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid; - addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn; - addsta->sleep_tx_count = cmd->sleep_tx_count; - addsta->reserved1 = cpu_to_le16(0); - addsta->reserved2 = cpu_to_le16(0); - - return (u16)sizeof(struct iwl4965_addsta_cmd); -} - -static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp) -{ - return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN; -} - -/** - * iwl4965_tx_status_reply_tx - Handle Tx response for frames in aggregation queue - */ -static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, - struct iwl_ht_agg *agg, - struct iwl4965_tx_resp *tx_resp, - int txq_id, u16 start_idx) -{ - u16 status; - struct agg_tx_status *frame_status = tx_resp->u.agg_status; - struct ieee80211_tx_info *info = NULL; - struct ieee80211_hdr *hdr = NULL; - u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); - int i, sh, idx; - u16 seq; - if (agg->wait_for_ba) - IWL_DEBUG_TX_REPLY(priv, "got tx response w/o block-ack\n"); - - agg->frame_count = tx_resp->frame_count; - agg->start_idx = start_idx; - agg->rate_n_flags = rate_n_flags; - agg->bitmap = 0; - - /* num frames attempted by Tx command */ - if (agg->frame_count == 1) { - /* Only one frame was attempted; no block-ack will arrive */ - status = le16_to_cpu(frame_status[0].status); - idx = start_idx; - - /* FIXME: code repetition */ - IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n", - agg->frame_count, agg->start_idx, idx); - - info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb); - info->status.rates[0].count = tx_resp->failure_frame + 1; - info->flags &= ~IEEE80211_TX_CTL_AMPDU; - info->flags |= iwl_tx_status_to_mac80211(status); - iwlagn_hwrate_to_tx_control(priv, rate_n_flags, info); - /* FIXME: code repetition end */ - - IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n", - status & 0xff, tx_resp->failure_frame); - IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags); - - agg->wait_for_ba = 0; - } else { - /* Two or more frames were attempted; expect block-ack */ - u64 bitmap = 0; - int start = agg->start_idx; - - /* Construct bit-map of pending frames within Tx window */ - for (i = 0; i < agg->frame_count; i++) { - u16 sc; - status = le16_to_cpu(frame_status[i].status); - seq = le16_to_cpu(frame_status[i].sequence); - idx = SEQ_TO_INDEX(seq); - txq_id = SEQ_TO_QUEUE(seq); - - if (status & (AGG_TX_STATE_FEW_BYTES_MSK | - AGG_TX_STATE_ABORT_MSK)) - continue; - - IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n", - agg->frame_count, txq_id, idx); - - hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx); - if (!hdr) { - IWL_ERR(priv, - "BUG_ON idx doesn't point to valid skb" - " idx=%d, txq_id=%d\n", idx, txq_id); - return -1; - } - - sc = le16_to_cpu(hdr->seq_ctrl); - if (idx != (SEQ_TO_SN(sc) & 0xff)) { - IWL_ERR(priv, - "BUG_ON idx doesn't match seq control" - " idx=%d, seq_idx=%d, seq=%d\n", - idx, SEQ_TO_SN(sc), hdr->seq_ctrl); - return -1; - } - - IWL_DEBUG_TX_REPLY(priv, "AGG Frame i=%d idx %d seq=%d\n", - i, idx, SEQ_TO_SN(sc)); - - sh = idx - start; - if (sh > 64) { - sh = (start - idx) + 0xff; - bitmap = bitmap << sh; - sh = 0; - start = idx; - } else if (sh < -64) - sh = 0xff - (start - idx); - else if (sh < 0) { - sh = start - idx; - start = idx; - bitmap = bitmap << sh; - sh = 0; - } - bitmap |= 1ULL << sh; - IWL_DEBUG_TX_REPLY(priv, "start=%d bitmap=0x%llx\n", - start, (unsigned long long)bitmap); - } - - agg->bitmap = bitmap; - agg->start_idx = start; - IWL_DEBUG_TX_REPLY(priv, "Frames %d start_idx=%d bitmap=0x%llx\n", - agg->frame_count, agg->start_idx, - (unsigned long long)agg->bitmap); - - if (bitmap) - agg->wait_for_ba = 1; - } - return 0; -} - -static u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr) -{ - int i; - int start = 0; - int ret = IWL_INVALID_STATION; - unsigned long flags; - - if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) || - (priv->iw_mode == NL80211_IFTYPE_AP)) - start = IWL_STA_ID; - - if (is_broadcast_ether_addr(addr)) - return priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; - - spin_lock_irqsave(&priv->sta_lock, flags); - for (i = start; i < priv->hw_params.max_stations; i++) - if (priv->stations[i].used && - (!compare_ether_addr(priv->stations[i].sta.sta.addr, - addr))) { - ret = i; - goto out; - } - - IWL_DEBUG_ASSOC_LIMIT(priv, "can not find STA %pM total %d\n", - addr, priv->num_stations); - - out: - /* - * It may be possible that more commands interacting with stations - * arrive before we completed processing the adding of - * station - */ - if (ret != IWL_INVALID_STATION && - (!(priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) || - ((priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) && - (priv->stations[ret].used & IWL_STA_UCODE_INPROGRESS)))) { - IWL_ERR(priv, "Requested station info for sta %d before ready.\n", - ret); - ret = IWL_INVALID_STATION; - } - spin_unlock_irqrestore(&priv->sta_lock, flags); - return ret; -} - -static int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) -{ - if (priv->iw_mode == NL80211_IFTYPE_STATION) { - return IWL_AP_ID; - } else { - u8 *da = ieee80211_get_DA(hdr); - return iwl_find_station(priv, da); - } -} - -/** - * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response - */ -static void iwl4965_rx_reply_tx(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - u16 sequence = le16_to_cpu(pkt->hdr.sequence); - int txq_id = SEQ_TO_QUEUE(sequence); - int index = SEQ_TO_INDEX(sequence); - struct iwl_tx_queue *txq = &priv->txq[txq_id]; - struct ieee80211_hdr *hdr; - struct ieee80211_tx_info *info; - struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; - u32 status = le32_to_cpu(tx_resp->u.status); - int uninitialized_var(tid); - int sta_id; - int freed; - u8 *qc = NULL; - unsigned long flags; - - if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { - IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " - "is out of range [0-%d] %d %d\n", txq_id, - index, txq->q.n_bd, txq->q.write_ptr, - txq->q.read_ptr); - return; - } - - txq->time_stamp = jiffies; - info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); - memset(&info->status, 0, sizeof(info->status)); - - hdr = iwl_tx_queue_get_hdr(priv, txq_id, index); - if (ieee80211_is_data_qos(hdr->frame_control)) { - qc = ieee80211_get_qos_ctl(hdr); - tid = qc[0] & 0xf; - } - - sta_id = iwl_get_ra_sta_id(priv, hdr); - if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) { - IWL_ERR(priv, "Station not known\n"); - return; - } - - spin_lock_irqsave(&priv->sta_lock, flags); - if (txq->sched_retry) { - const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); - struct iwl_ht_agg *agg = NULL; - WARN_ON(!qc); - - agg = &priv->stations[sta_id].tid[tid].agg; - - iwl4965_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); - - /* check if BAR is needed */ - if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) - info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; - - if (txq->q.read_ptr != (scd_ssn & 0xff)) { - index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); - IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn " - "%d index %d\n", scd_ssn , index); - freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); - if (qc) - iwl_free_tfds_in_queue(priv, sta_id, - tid, freed); - - if (priv->mac80211_registered && - (iwl_queue_space(&txq->q) > txq->q.low_mark) && - (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) - iwl_wake_queue(priv, txq); - } - } else { - info->status.rates[0].count = tx_resp->failure_frame + 1; - info->flags |= iwl_tx_status_to_mac80211(status); - iwlagn_hwrate_to_tx_control(priv, - le32_to_cpu(tx_resp->rate_n_flags), - info); - - IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) " - "rate_n_flags 0x%x retries %d\n", - txq_id, - iwl_get_tx_fail_reason(status), status, - le32_to_cpu(tx_resp->rate_n_flags), - tx_resp->failure_frame); - - freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); - if (qc && likely(sta_id != IWL_INVALID_STATION)) - iwl_free_tfds_in_queue(priv, sta_id, tid, freed); - else if (sta_id == IWL_INVALID_STATION) - IWL_DEBUG_TX_REPLY(priv, "Station not known\n"); - - if (priv->mac80211_registered && - (iwl_queue_space(&txq->q) > txq->q.low_mark)) - iwl_wake_queue(priv, txq); - } - if (qc && likely(sta_id != IWL_INVALID_STATION)) - iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); - - iwl_check_abort_status(priv, tx_resp->frame_count, status); - - spin_unlock_irqrestore(&priv->sta_lock, flags); -} - -static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl4965_beacon_notif *beacon = (void *)pkt->u.raw; -#ifdef CONFIG_IWLWIFI_DEBUG - u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); - - IWL_DEBUG_RX(priv, "beacon status %#x, retries:%d ibssmgr:%d " - "tsf:0x%.8x%.8x rate:%d\n", - le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK, - beacon->beacon_notify_hdr.failure_frame, - le32_to_cpu(beacon->ibss_mgr_status), - le32_to_cpu(beacon->high_tsf), - le32_to_cpu(beacon->low_tsf), rate); -#endif - - priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); - - if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) - queue_work(priv->workqueue, &priv->beacon_update); -} - -static int iwl4965_calc_rssi(struct iwl_priv *priv, - struct iwl_rx_phy_res *rx_resp) -{ - /* data from PHY/DSP regarding signal strength, etc., - * contents are always there, not configurable by host. */ - struct iwl4965_rx_non_cfg_phy *ncphy = - (struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy_buf; - u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL49_AGC_DB_MASK) - >> IWL49_AGC_DB_POS; - - u32 valid_antennae = - (le16_to_cpu(rx_resp->phy_flags) & IWL49_RX_PHY_FLAGS_ANTENNAE_MASK) - >> IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET; - u8 max_rssi = 0; - u32 i; - - /* Find max rssi among 3 possible receivers. - * These values are measured by the digital signal processor (DSP). - * They should stay fairly constant even as the signal strength varies, - * if the radio's automatic gain control (AGC) is working right. - * AGC value (see below) will provide the "interesting" info. */ - for (i = 0; i < 3; i++) - if (valid_antennae & (1 << i)) - max_rssi = max(ncphy->rssi_info[i << 1], max_rssi); - - IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n", - ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4], - max_rssi, agc); - - /* dBm = max_rssi dB - agc dB - constant. - * Higher AGC (higher radio gain) means lower signal. */ - return max_rssi - agc - IWLAGN_RSSI_OFFSET; -} - - -/* Set up 4965-specific Rx frame reply handlers */ -static void iwl4965_rx_handler_setup(struct iwl_priv *priv) -{ - /* Legacy Rx frames */ - priv->rx_handlers[REPLY_RX] = iwlagn_rx_reply_rx; - /* Tx response */ - priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; - priv->rx_handlers[BEACON_NOTIFICATION] = iwl4965_rx_beacon_notif; - - /* set up notification wait support */ - spin_lock_init(&priv->_agn.notif_wait_lock); - INIT_LIST_HEAD(&priv->_agn.notif_waits); - init_waitqueue_head(&priv->_agn.notif_waitq); -} - -static void iwl4965_setup_deferred_work(struct iwl_priv *priv) -{ - INIT_WORK(&priv->txpower_work, iwl4965_bg_txpower_work); -} - -static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) -{ - cancel_work_sync(&priv->txpower_work); -} - -static struct iwl_hcmd_ops iwl4965_hcmd = { - .rxon_assoc = iwl4965_send_rxon_assoc, - .commit_rxon = iwl4965_commit_rxon, - .set_rxon_chain = iwlagn_set_rxon_chain, - .send_bt_config = iwl_send_bt_config, -}; - -static void iwl4965_post_scan(struct iwl_priv *priv) -{ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - /* - * Since setting the RXON may have been deferred while - * performing the scan, fire one off if needed - */ - if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) - iwlcore_commit_rxon(priv, ctx); -} - -static void iwl4965_post_associate(struct iwl_priv *priv) -{ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - struct ieee80211_vif *vif = ctx->vif; - struct ieee80211_conf *conf = NULL; - int ret = 0; - - if (!vif || !priv->is_open) - return; - - if (vif->type == NL80211_IFTYPE_AP) { - IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); - return; - } - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - iwl_scan_cancel_timeout(priv, 200); - - conf = ieee80211_get_hw_conf(priv->hw); - - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv, ctx); - - ret = iwl_send_rxon_timing(priv, ctx); - if (ret) - IWL_WARN(priv, "RXON timing - " - "Attempting to continue.\n"); - - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - - iwl_set_rxon_ht(priv, &priv->current_ht_config); - - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - - ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); - - IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", - vif->bss_conf.aid, vif->bss_conf.beacon_int); - - if (vif->bss_conf.use_short_preamble) - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; - else - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { - if (vif->bss_conf.use_short_slot) - ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; - else - ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; - } - - iwlcore_commit_rxon(priv, ctx); - - IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", - vif->bss_conf.aid, ctx->active.bssid_addr); - - switch (vif->type) { - case NL80211_IFTYPE_STATION: - break; - case NL80211_IFTYPE_ADHOC: - iwlagn_send_beacon_cmd(priv); - break; - default: - IWL_ERR(priv, "%s Should not be called in %d mode\n", - __func__, vif->type); - break; - } - - /* the chain noise calibration will enabled PM upon completion - * If chain noise has already been run, then we need to enable - * power management here */ - if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE) - iwl_power_update_mode(priv, false); - - /* Enable Rx differential gain and sensitivity calibrations */ - iwl_chain_noise_reset(priv); - priv->start_calib = 1; -} - -static void iwl4965_config_ap(struct iwl_priv *priv) -{ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - struct ieee80211_vif *vif = ctx->vif; - int ret = 0; - - lockdep_assert_held(&priv->mutex); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - /* The following should be done only at AP bring up */ - if (!iwl_is_associated_ctx(ctx)) { - - /* RXON - unassoc (to set timing command) */ - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv, ctx); - - /* RXON Timing */ - ret = iwl_send_rxon_timing(priv, ctx); - if (ret) - IWL_WARN(priv, "RXON timing failed - " - "Attempting to continue.\n"); - - /* AP has all antennas */ - priv->chain_noise_data.active_chains = - priv->hw_params.valid_rx_ant; - iwl_set_rxon_ht(priv, &priv->current_ht_config); - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - - ctx->staging.assoc_id = 0; - - if (vif->bss_conf.use_short_preamble) - ctx->staging.flags |= - RXON_FLG_SHORT_PREAMBLE_MSK; - else - ctx->staging.flags &= - ~RXON_FLG_SHORT_PREAMBLE_MSK; - - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { - if (vif->bss_conf.use_short_slot) - ctx->staging.flags |= - RXON_FLG_SHORT_SLOT_MSK; - else - ctx->staging.flags &= - ~RXON_FLG_SHORT_SLOT_MSK; - } - /* need to send beacon cmd before committing assoc RXON! */ - iwlagn_send_beacon_cmd(priv); - /* restore RXON assoc */ - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv, ctx); - } - iwlagn_send_beacon_cmd(priv); - - /* FIXME - we need to add code here to detect a totally new - * configuration, reset the AP, unassoc, rxon timing, assoc, - * clear sta table, add BCAST sta... */ -} - -static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { - .get_hcmd_size = iwl4965_get_hcmd_size, - .build_addsta_hcmd = iwl4965_build_addsta_hcmd, - .chain_noise_reset = iwl4965_chain_noise_reset, - .gain_computation = iwl4965_gain_computation, - .tx_cmd_protection = iwl_legacy_tx_cmd_protection, - .calc_rssi = iwl4965_calc_rssi, - .request_scan = iwlagn_request_scan, - .post_scan = iwl4965_post_scan, -}; - -static struct iwl_lib_ops iwl4965_lib = { - .set_hw_params = iwl4965_hw_set_hw_params, - .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, - .txq_set_sched = iwl4965_txq_set_sched, - .txq_agg_enable = iwl4965_txq_agg_enable, - .txq_agg_disable = iwl4965_txq_agg_disable, - .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, - .txq_free_tfd = iwl_hw_txq_free_tfd, - .txq_init = iwl_hw_tx_queue_init, - .rx_handler_setup = iwl4965_rx_handler_setup, - .setup_deferred_work = iwl4965_setup_deferred_work, - .cancel_deferred_work = iwl4965_cancel_deferred_work, - .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, - .alive_notify = iwl4965_alive_notify, - .init_alive_start = iwl4965_init_alive_start, - .load_ucode = iwl4965_load_bsm, - .dump_nic_event_log = iwl_dump_nic_event_log, - .dump_nic_error_log = iwl_dump_nic_error_log, - .dump_fh = iwl_dump_fh, - .set_channel_switch = iwl4965_hw_channel_switch, - .apm_ops = { - .init = iwl_apm_init, - .config = iwl4965_nic_config, - }, - .eeprom_ops = { - .regulatory_bands = { - EEPROM_REGULATORY_BAND_1_CHANNELS, - EEPROM_REGULATORY_BAND_2_CHANNELS, - EEPROM_REGULATORY_BAND_3_CHANNELS, - EEPROM_REGULATORY_BAND_4_CHANNELS, - EEPROM_REGULATORY_BAND_5_CHANNELS, - EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS, - EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS - }, - .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, - .release_semaphore = iwlcore_eeprom_release_semaphore, - .calib_version = iwl4965_eeprom_calib_version, - .query_addr = iwlcore_eeprom_query_addr, - }, - .send_tx_power = iwl4965_send_tx_power, - .update_chain_flags = iwl_update_chain_flags, - .isr_ops = { - .isr = iwl_isr_legacy, - }, - .temp_ops = { - .temperature = iwl4965_temperature_calib, - }, - .debugfs_ops = { - .rx_stats_read = iwl_ucode_rx_stats_read, - .tx_stats_read = iwl_ucode_tx_stats_read, - .general_stats_read = iwl_ucode_general_stats_read, - .bt_stats_read = iwl_ucode_bt_stats_read, - .reply_tx_error = iwl_reply_tx_error_read, - }, - .check_plcp_health = iwl_good_plcp_health, -}; - -static const struct iwl_legacy_ops iwl4965_legacy_ops = { - .post_associate = iwl4965_post_associate, - .config_ap = iwl4965_config_ap, - .manage_ibss_station = iwlagn_manage_ibss_station, - .update_bcast_stations = iwl_update_bcast_stations, -}; - -struct ieee80211_ops iwl4965_hw_ops = { - .tx = iwlagn_mac_tx, - .start = iwlagn_mac_start, - .stop = iwlagn_mac_stop, - .add_interface = iwl_mac_add_interface, - .remove_interface = iwl_mac_remove_interface, - .change_interface = iwl_mac_change_interface, - .config = iwl_legacy_mac_config, - .configure_filter = iwlagn_configure_filter, - .set_key = iwlagn_mac_set_key, - .update_tkip_key = iwlagn_mac_update_tkip_key, - .conf_tx = iwl_mac_conf_tx, - .reset_tsf = iwl_legacy_mac_reset_tsf, - .bss_info_changed = iwl_legacy_mac_bss_info_changed, - .ampdu_action = iwlagn_mac_ampdu_action, - .hw_scan = iwl_mac_hw_scan, - .sta_add = iwlagn_mac_sta_add, - .sta_remove = iwl_mac_sta_remove, - .channel_switch = iwlagn_mac_channel_switch, - .flush = iwlagn_mac_flush, - .tx_last_beacon = iwl_mac_tx_last_beacon, -}; - -static const struct iwl_ops iwl4965_ops = { - .lib = &iwl4965_lib, - .hcmd = &iwl4965_hcmd, - .utils = &iwl4965_hcmd_utils, - .led = &iwlagn_led_ops, - .legacy = &iwl4965_legacy_ops, - .ieee80211_ops = &iwl4965_hw_ops, -}; - -static struct iwl_base_params iwl4965_base_params = { - .eeprom_size = IWL4965_EEPROM_IMG_SIZE, - .num_of_queues = IWL49_NUM_QUEUES, - .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = true, - .use_isr_legacy = true, - .broken_powersave = true, - .led_compensation = 61, - .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .wd_timeout = IWL_DEF_WD_TIMEOUT, - .temperature_kelvin = true, - .max_event_log_size = 512, - .tx_power_by_driver = true, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, - .no_agg_framecnt_info = true, -}; - -struct iwl_cfg iwl4965_agn_cfg = { - .name = "Intel(R) Wireless WiFi Link 4965AGN", - .fw_name_pre = IWL4965_FW_PRE, - .ucode_api_max = IWL4965_UCODE_API_MAX, - .ucode_api_min = IWL4965_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_ABC, - .eeprom_ver = EEPROM_4965_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION, - .ops = &iwl4965_ops, - .mod_params = &iwlagn_mod_params, - .base_params = &iwl4965_base_params, - .led_mode = IWL_LED_BLINK, - /* - * Force use of chains B and C for scan RX on 5 GHz band - * because the device has off-channel reception on chain A. - */ - .scan_rx_antennas[IEEE80211_BAND_5GHZ] = ANT_BC, -}; - -/* Module firmware */ -MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE(IWL4965_UCODE_API_MAX)); - diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 9965215697bb..d08fa938501a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -86,7 +86,6 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_VERSION(DRV_VERSION); MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); MODULE_LICENSE("GPL"); -MODULE_ALIAS("iwl4965"); static int iwlagn_ant_coupling; static bool iwlagn_bt_ch_announce = 1; @@ -3810,7 +3809,6 @@ static void iwlagn_bg_roc_done(struct work_struct *work) mutex_unlock(&priv->mutex); } -#ifdef CONFIG_IWL5000 static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_channel *channel, enum nl80211_channel_type channel_type, @@ -3866,7 +3864,6 @@ static int iwl_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) return 0; } -#endif /***************************************************************************** * @@ -4036,7 +4033,6 @@ static void iwl_uninit_drv(struct iwl_priv *priv) kfree(priv->scan_cmd); } -#ifdef CONFIG_IWL5000 struct ieee80211_ops iwlagn_hw_ops = { .tx = iwlagn_mac_tx, .start = iwlagn_mac_start, @@ -4061,7 +4057,6 @@ struct ieee80211_ops iwlagn_hw_ops = { .remain_on_channel = iwl_mac_remain_on_channel, .cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel, }; -#endif static void iwl_hw_detect(struct iwl_priv *priv) { @@ -4129,12 +4124,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (cfg->mod_params->disable_hw_scan) { dev_printk(KERN_DEBUG, &(pdev->dev), "sw scan support is deprecated\n"); -#ifdef CONFIG_IWL5000 iwlagn_hw_ops.hw_scan = NULL; -#endif -#ifdef CONFIG_IWL4965 - iwl4965_hw_ops.hw_scan = NULL; -#endif } hw = iwl_alloc_all(cfg); @@ -4513,12 +4503,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) /* Hardware specific file defines the PCI IDs table for that hardware module */ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { -#ifdef CONFIG_IWL4965 - {IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)}, - {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)}, -#endif /* CONFIG_IWL4965 */ -#ifdef CONFIG_IWL5000 -/* 5100 Series WiFi */ {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */ {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */ {IWL_PCI_DEVICE(0x4232, 0x1204, iwl5100_agn_cfg)}, /* Mini Card */ @@ -4704,8 +4688,6 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x0893, 0x0266, iwl230_bg_cfg)}, {IWL_PCI_DEVICE(0x0892, 0x0466, iwl230_bg_cfg)}, -#endif /* CONFIG_IWL5000 */ - {0} }; MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 977ddfb8c24c..4bd342060254 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -43,11 +43,6 @@ #include "iwl-helpers.h" -MODULE_DESCRIPTION("iwl core"); -MODULE_VERSION(IWLWIFI_VERSION); -MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); -MODULE_LICENSE("GPL"); - /* * set bt_coex_active to true, uCode will do kill/defer * every time the priority line is asserted (BT is sending signals on the @@ -65,15 +60,12 @@ MODULE_LICENSE("GPL"); * default: bt_coex_active = true (BT_COEX_ENABLE) */ bool bt_coex_active = true; -EXPORT_SYMBOL_GPL(bt_coex_active); module_param(bt_coex_active, bool, S_IRUGO); MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist"); u32 iwl_debug_level; -EXPORT_SYMBOL(iwl_debug_level); const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -EXPORT_SYMBOL(iwl_bcast_addr); /* This function both allocates and initializes hw and priv. */ @@ -98,7 +90,6 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg) out: return hw; } -EXPORT_SYMBOL(iwl_alloc_all); #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ @@ -272,7 +263,6 @@ int iwlcore_init_geos(struct iwl_priv *priv) return 0; } -EXPORT_SYMBOL(iwlcore_init_geos); /* * iwlcore_free_geos - undo allocations in iwlcore_init_geos @@ -283,7 +273,6 @@ void iwlcore_free_geos(struct iwl_priv *priv) kfree(priv->ieee_rates); clear_bit(STATUS_GEO_CONFIGURED, &priv->status); } -EXPORT_SYMBOL(iwlcore_free_geos); static bool iwl_is_channel_extension(struct iwl_priv *priv, enum ieee80211_band band, @@ -328,7 +317,6 @@ bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, le16_to_cpu(ctx->staging.channel), ctx->ht.extension_chan_offset); } -EXPORT_SYMBOL(iwl_is_ht40_tx_allowed); static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val) { @@ -429,7 +417,6 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) return iwl_send_cmd_pdu(priv, ctx->rxon_timing_cmd, sizeof(ctx->timing), &ctx->timing); } -EXPORT_SYMBOL(iwl_send_rxon_timing); void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, int hw_decrypt) @@ -442,7 +429,6 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK; } -EXPORT_SYMBOL(iwl_set_rxon_hwcrypto); /* validate RXON structure is valid */ int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx) @@ -515,7 +501,6 @@ int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx) } return 0; } -EXPORT_SYMBOL(iwl_check_rxon_cmd); /** * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed @@ -579,7 +564,6 @@ int iwl_full_rxon_required(struct iwl_priv *priv, return 0; } -EXPORT_SYMBOL(iwl_full_rxon_required); u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, struct iwl_rxon_context *ctx) @@ -593,7 +577,6 @@ u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, else return IWL_RATE_6M_PLCP; } -EXPORT_SYMBOL(iwl_rate_get_lowest_plcp); static void _iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf, @@ -670,7 +653,6 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf) for_each_context(priv, ctx) _iwl_set_rxon_ht(priv, ht_conf, ctx); } -EXPORT_SYMBOL(iwl_set_rxon_ht); /* Return valid, unused, channel for a passive scan to reset the RF */ u8 iwl_get_single_channel_number(struct iwl_priv *priv, @@ -711,7 +693,6 @@ u8 iwl_get_single_channel_number(struct iwl_priv *priv, return channel; } -EXPORT_SYMBOL(iwl_get_single_channel_number); /** * iwl_set_rxon_channel - Set the band and channel values in staging RXON @@ -742,7 +723,6 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, return 0; } -EXPORT_SYMBOL(iwl_set_rxon_channel); void iwl_set_flags_for_band(struct iwl_priv *priv, struct iwl_rxon_context *ctx, @@ -766,7 +746,6 @@ void iwl_set_flags_for_band(struct iwl_priv *priv, ctx->staging.flags &= ~RXON_FLG_CCK_MSK; } } -EXPORT_SYMBOL(iwl_set_flags_for_band); /* * initialize rxon structure with default values from eeprom @@ -838,7 +817,6 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff; ctx->staging.ofdm_ht_triple_stream_basic_rates = 0xff; } -EXPORT_SYMBOL(iwl_connection_init_rx_config); void iwl_set_rate(struct iwl_priv *priv) { @@ -871,7 +849,6 @@ void iwl_set_rate(struct iwl_priv *priv) (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; } } -EXPORT_SYMBOL(iwl_set_rate); void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) { @@ -891,7 +868,6 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) mutex_unlock(&priv->mutex); } } -EXPORT_SYMBOL(iwl_chswitch_done); void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { @@ -919,7 +895,6 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) } } } -EXPORT_SYMBOL(iwl_rx_csa); #ifdef CONFIG_IWLWIFI_DEBUG void iwl_print_rx_config_cmd(struct iwl_priv *priv, @@ -941,7 +916,6 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv, IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr); IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id)); } -EXPORT_SYMBOL(iwl_print_rx_config_cmd); #endif /** * iwl_irq_handle_error - called for HW or SW error interrupt from card @@ -1021,7 +995,6 @@ void iwl_irq_handle_error(struct iwl_priv *priv) queue_work(priv->workqueue, &priv->restart); } } -EXPORT_SYMBOL(iwl_irq_handle_error); static int iwl_apm_stop_master(struct iwl_priv *priv) { @@ -1058,7 +1031,6 @@ void iwl_apm_stop(struct iwl_priv *priv) */ iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); } -EXPORT_SYMBOL(iwl_apm_stop); /* @@ -1173,7 +1145,6 @@ int iwl_apm_init(struct iwl_priv *priv) out: return ret; } -EXPORT_SYMBOL(iwl_apm_init); int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) @@ -1233,7 +1204,6 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) } return ret; } -EXPORT_SYMBOL(iwl_set_tx_power); void iwl_send_bt_config(struct iwl_priv *priv) { @@ -1257,7 +1227,6 @@ void iwl_send_bt_config(struct iwl_priv *priv) sizeof(struct iwl_bt_cmd), &bt_cmd)) IWL_ERR(priv, "failed to send BT Coex Config\n"); } -EXPORT_SYMBOL(iwl_send_bt_config); int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) { @@ -1275,7 +1244,6 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) sizeof(struct iwl_statistics_cmd), &statistics_cmd); } -EXPORT_SYMBOL(iwl_send_statistics_request); void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) @@ -1287,7 +1255,6 @@ void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, sleep->pm_sleep_mode, sleep->pm_wakeup_src); #endif } -EXPORT_SYMBOL(iwl_rx_pm_sleep_notif); void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) @@ -1299,7 +1266,6 @@ void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, get_cmd_string(pkt->hdr.cmd)); iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len); } -EXPORT_SYMBOL(iwl_rx_pm_debug_statistics_notif); void iwl_rx_reply_error(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) @@ -1314,7 +1280,6 @@ void iwl_rx_reply_error(struct iwl_priv *priv, le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num), le32_to_cpu(pkt->u.err_resp.error_info)); } -EXPORT_SYMBOL(iwl_rx_reply_error); void iwl_clear_isr_stats(struct iwl_priv *priv) { @@ -1366,7 +1331,6 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, IWL_DEBUG_MAC80211(priv, "leave\n"); return 0; } -EXPORT_SYMBOL(iwl_mac_conf_tx); int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw) { @@ -1374,7 +1338,6 @@ int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw) return priv->ibss_manager == IWL_IBSS_MANAGER; } -EXPORT_SYMBOL_GPL(iwl_mac_tx_last_beacon); static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { @@ -1484,7 +1447,6 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) IWL_DEBUG_MAC80211(priv, "leave\n"); return err; } -EXPORT_SYMBOL(iwl_mac_add_interface); static void iwl_teardown_interface(struct iwl_priv *priv, struct ieee80211_vif *vif, @@ -1537,7 +1499,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "leave\n"); } -EXPORT_SYMBOL(iwl_mac_remove_interface); int iwl_alloc_txq_mem(struct iwl_priv *priv) { @@ -1552,14 +1513,12 @@ int iwl_alloc_txq_mem(struct iwl_priv *priv) } return 0; } -EXPORT_SYMBOL(iwl_alloc_txq_mem); void iwl_free_txq_mem(struct iwl_priv *priv) { kfree(priv->txq); priv->txq = NULL; } -EXPORT_SYMBOL(iwl_free_txq_mem); #ifdef CONFIG_IWLWIFI_DEBUGFS @@ -1598,7 +1557,6 @@ int iwl_alloc_traffic_mem(struct iwl_priv *priv) iwl_reset_traffic_log(priv); return 0; } -EXPORT_SYMBOL(iwl_alloc_traffic_mem); void iwl_free_traffic_mem(struct iwl_priv *priv) { @@ -1608,7 +1566,6 @@ void iwl_free_traffic_mem(struct iwl_priv *priv) kfree(priv->rx_traffic); priv->rx_traffic = NULL; } -EXPORT_SYMBOL(iwl_free_traffic_mem); void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv, u16 length, struct ieee80211_hdr *header) @@ -1633,7 +1590,6 @@ void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv, (priv->tx_traffic_idx + 1) % IWL_TRAFFIC_ENTRIES; } } -EXPORT_SYMBOL(iwl_dbg_log_tx_data_frame); void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, u16 length, struct ieee80211_hdr *header) @@ -1658,7 +1614,6 @@ void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, (priv->rx_traffic_idx + 1) % IWL_TRAFFIC_ENTRIES; } } -EXPORT_SYMBOL(iwl_dbg_log_rx_data_frame); const char *get_mgmt_string(int cmd) { @@ -1795,7 +1750,6 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) stats->data_bytes += len; } } -EXPORT_SYMBOL(iwl_update_stats); #endif static void iwl_force_rf_reset(struct iwl_priv *priv) @@ -1934,7 +1888,6 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_unlock(&priv->mutex); return err; } -EXPORT_SYMBOL(iwl_mac_change_interface); /* * On every watchdog tick we check (latest) time stamp. If it does not @@ -2006,7 +1959,6 @@ void iwl_bg_watchdog(unsigned long data) mod_timer(&priv->watchdog, jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout))); } -EXPORT_SYMBOL(iwl_bg_watchdog); void iwl_setup_watchdog(struct iwl_priv *priv) { @@ -2018,7 +1970,6 @@ void iwl_setup_watchdog(struct iwl_priv *priv) else del_timer(&priv->watchdog); } -EXPORT_SYMBOL(iwl_setup_watchdog); /* * extended beacon time format @@ -2044,7 +1995,6 @@ u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval) return (quot << priv->hw_params.beacon_time_tsf_bits) + rem; } -EXPORT_SYMBOL(iwl_usecs_to_beacons); /* base is usually what we get from ucode with each received frame, * the same as HW timer counter counting down @@ -2072,7 +2022,6 @@ __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, return cpu_to_le32(res); } -EXPORT_SYMBOL(iwl_add_beacon_time); #ifdef CONFIG_PM @@ -2092,7 +2041,6 @@ int iwl_pci_suspend(struct device *device) return 0; } -EXPORT_SYMBOL(iwl_pci_suspend); int iwl_pci_resume(struct device *device) { @@ -2121,7 +2069,6 @@ int iwl_pci_resume(struct device *device) return 0; } -EXPORT_SYMBOL(iwl_pci_resume); const struct dev_pm_ops iwl_pm_ops = { .suspend = iwl_pci_suspend, @@ -2131,6 +2078,5 @@ const struct dev_pm_ops iwl_pm_ops = { .poweroff = iwl_pci_suspend, .restore = iwl_pci_resume, }; -EXPORT_SYMBOL(iwl_pm_ops); #endif /* CONFIG_PM */ diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index bc7a965c18f9..8842411f1cf3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1788,7 +1788,6 @@ err: iwl_dbgfs_unregister(priv); return -ENOMEM; } -EXPORT_SYMBOL(iwl_dbgfs_register); /** * Remove the debugfs files and directories @@ -1802,7 +1801,6 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) debugfs_remove_recursive(priv->debugfs_dir); priv->debugfs_dir = NULL; } -EXPORT_SYMBOL(iwl_dbgfs_unregister); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 065615ee040a..58165c769cf1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -43,14 +43,14 @@ #include "iwl-prph.h" #include "iwl-fh.h" #include "iwl-debug.h" -#include "iwl-4965-hw.h" -#include "iwl-3945-hw.h" #include "iwl-agn-hw.h" #include "iwl-led.h" #include "iwl-power.h" #include "iwl-agn-rs.h" #include "iwl-agn-tt.h" +#define U32_PAD(n) ((4-(n))&0x3) + struct iwl_tx_queue; /* CT-KILL constants */ diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 358cfd7e5af1..833194a2c639 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -222,7 +222,6 @@ const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) BUG_ON(offset >= priv->cfg->base_params->eeprom_size); return &priv->eeprom[offset]; } -EXPORT_SYMBOL(iwlcore_eeprom_query_addr); static int iwl_init_otp_access(struct iwl_priv *priv) { @@ -382,7 +381,6 @@ const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) { return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset); } -EXPORT_SYMBOL(iwl_eeprom_query_addr); u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset) { @@ -390,7 +388,6 @@ u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset) return 0; return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8); } -EXPORT_SYMBOL(iwl_eeprom_query16); /** * iwl_eeprom_init - read EEPROM contents @@ -509,14 +506,12 @@ err: alloc_err: return ret; } -EXPORT_SYMBOL(iwl_eeprom_init); void iwl_eeprom_free(struct iwl_priv *priv) { kfree(priv->eeprom); priv->eeprom = NULL; } -EXPORT_SYMBOL(iwl_eeprom_free); static void iwl_init_band_reference(const struct iwl_priv *priv, int eep_band, int *eeprom_ch_count, @@ -779,7 +774,6 @@ int iwl_init_channel_map(struct iwl_priv *priv) return 0; } -EXPORT_SYMBOL(iwl_init_channel_map); /* * iwl_free_channel_map - undo allocations in iwl_init_channel_map @@ -789,7 +783,6 @@ void iwl_free_channel_map(struct iwl_priv *priv) kfree(priv->channel_info); priv->channel_count = 0; } -EXPORT_SYMBOL(iwl_free_channel_map); /** * iwl_get_channel_info - Find driver's private channel info @@ -818,4 +811,3 @@ const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv, return NULL; } -EXPORT_SYMBOL(iwl_get_channel_info); diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index e4b953d7b7bf..02499f684683 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -114,7 +114,6 @@ const char *get_cmd_string(u8 cmd) } } -EXPORT_SYMBOL(get_cmd_string); #define HOST_COMPLETE_TIMEOUT (HZ / 2) @@ -253,7 +252,6 @@ out: mutex_unlock(&priv->sync_cmd_mutex); return ret; } -EXPORT_SYMBOL(iwl_send_cmd_sync); int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) { @@ -262,7 +260,6 @@ int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) return iwl_send_cmd_sync(priv, cmd); } -EXPORT_SYMBOL(iwl_send_cmd); int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data) { @@ -274,7 +271,6 @@ int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data) return iwl_send_cmd_sync(priv, &cmd); } -EXPORT_SYMBOL(iwl_send_cmd_pdu); int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, const void *data, @@ -293,4 +289,3 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, return iwl_send_cmd_async(priv, &cmd); } -EXPORT_SYMBOL(iwl_send_cmd_pdu_async); diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 074ad2275228..d7f2a0bb32c9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -175,7 +175,6 @@ void iwl_leds_init(struct iwl_priv *priv) priv->led_registered = true; } -EXPORT_SYMBOL(iwl_leds_init); void iwl_leds_exit(struct iwl_priv *priv) { @@ -185,4 +184,3 @@ void iwl_leds_exit(struct iwl_priv *priv) led_classdev_unregister(&priv->led); kfree(priv->led.name); } -EXPORT_SYMBOL(iwl_leds_exit); diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.c b/drivers/net/wireless/iwlwifi/iwl-legacy.c deleted file mode 100644 index e1ace3ce30b3..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-legacy.c +++ /dev/null @@ -1,657 +0,0 @@ -/****************************************************************************** - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - *****************************************************************************/ - -#include -#include - -#include "iwl-dev.h" -#include "iwl-core.h" -#include "iwl-helpers.h" -#include "iwl-legacy.h" - -static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) -{ - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - if (!ctx->is_active) - return; - - ctx->qos_data.def_qos_parm.qos_flags = 0; - - if (ctx->qos_data.qos_active) - ctx->qos_data.def_qos_parm.qos_flags |= - QOS_PARAM_FLG_UPDATE_EDCA_MSK; - - if (ctx->ht.enabled) - ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; - - IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", - ctx->qos_data.qos_active, - ctx->qos_data.def_qos_parm.qos_flags); - - iwl_send_cmd_pdu_async(priv, ctx->qos_cmd, - sizeof(struct iwl_qosparam_cmd), - &ctx->qos_data.def_qos_parm, NULL); -} - -/** - * iwl_legacy_mac_config - mac80211 config callback - */ -int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed) -{ - struct iwl_priv *priv = hw->priv; - const struct iwl_channel_info *ch_info; - struct ieee80211_conf *conf = &hw->conf; - struct ieee80211_channel *channel = conf->channel; - struct iwl_ht_config *ht_conf = &priv->current_ht_config; - struct iwl_rxon_context *ctx; - unsigned long flags = 0; - int ret = 0; - u16 ch; - int scan_active = 0; - bool ht_changed[NUM_IWL_RXON_CTX] = {}; - - if (WARN_ON(!priv->cfg->ops->legacy)) - return -EOPNOTSUPP; - - mutex_lock(&priv->mutex); - - IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", - channel->hw_value, changed); - - if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) { - scan_active = 1; - IWL_DEBUG_MAC80211(priv, "scan active\n"); - } - - if (changed & (IEEE80211_CONF_CHANGE_SMPS | - IEEE80211_CONF_CHANGE_CHANNEL)) { - /* mac80211 uses static for non-HT which is what we want */ - priv->current_ht_config.smps = conf->smps_mode; - - /* - * Recalculate chain counts. - * - * If monitor mode is enabled then mac80211 will - * set up the SM PS mode to OFF if an HT channel is - * configured. - */ - if (priv->cfg->ops->hcmd->set_rxon_chain) - for_each_context(priv, ctx) - priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - } - - /* during scanning mac80211 will delay channel setting until - * scan finish with changed = 0 - */ - if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) { - if (scan_active) - goto set_ch_out; - - ch = channel->hw_value; - ch_info = iwl_get_channel_info(priv, channel->band, ch); - if (!is_channel_valid(ch_info)) { - IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); - ret = -EINVAL; - goto set_ch_out; - } - - spin_lock_irqsave(&priv->lock, flags); - - for_each_context(priv, ctx) { - /* Configure HT40 channels */ - if (ctx->ht.enabled != conf_is_ht(conf)) { - ctx->ht.enabled = conf_is_ht(conf); - ht_changed[ctx->ctxid] = true; - } - if (ctx->ht.enabled) { - if (conf_is_ht40_minus(conf)) { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_BELOW; - ctx->ht.is_40mhz = true; - } else if (conf_is_ht40_plus(conf)) { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - ctx->ht.is_40mhz = true; - } else { - ctx->ht.extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_NONE; - ctx->ht.is_40mhz = false; - } - } else - ctx->ht.is_40mhz = false; - - /* - * Default to no protection. Protection mode will - * later be set from BSS config in iwl_ht_conf - */ - ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE; - - /* if we are switching from ht to 2.4 clear flags - * from any ht related info since 2.4 does not - * support ht */ - if ((le16_to_cpu(ctx->staging.channel) != ch)) - ctx->staging.flags = 0; - - iwl_set_rxon_channel(priv, channel, ctx); - iwl_set_rxon_ht(priv, ht_conf); - - iwl_set_flags_for_band(priv, ctx, channel->band, - ctx->vif); - } - - spin_unlock_irqrestore(&priv->lock, flags); - - if (priv->cfg->ops->legacy->update_bcast_stations) - ret = priv->cfg->ops->legacy->update_bcast_stations(priv); - - set_ch_out: - /* The list of supported rates and rate mask can be different - * for each band; since the band may have changed, reset - * the rate mask to what mac80211 lists */ - iwl_set_rate(priv); - } - - if (changed & (IEEE80211_CONF_CHANGE_PS | - IEEE80211_CONF_CHANGE_IDLE)) { - ret = iwl_power_update_mode(priv, false); - if (ret) - IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n"); - } - - if (changed & IEEE80211_CONF_CHANGE_POWER) { - IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n", - priv->tx_power_user_lmt, conf->power_level); - - iwl_set_tx_power(priv, conf->power_level, false); - } - - if (!iwl_is_ready(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); - goto out; - } - - if (scan_active) - goto out; - - for_each_context(priv, ctx) { - if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging))) - iwlcore_commit_rxon(priv, ctx); - else - IWL_DEBUG_INFO(priv, - "Not re-sending same RXON configuration.\n"); - if (ht_changed[ctx->ctxid]) - iwl_update_qos(priv, ctx); - } - -out: - IWL_DEBUG_MAC80211(priv, "leave\n"); - mutex_unlock(&priv->mutex); - return ret; -} -EXPORT_SYMBOL(iwl_legacy_mac_config); - -void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw) -{ - struct iwl_priv *priv = hw->priv; - unsigned long flags; - /* IBSS can only be the IWL_RXON_CTX_BSS context */ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - if (WARN_ON(!priv->cfg->ops->legacy)) - return; - - mutex_lock(&priv->mutex); - IWL_DEBUG_MAC80211(priv, "enter\n"); - - spin_lock_irqsave(&priv->lock, flags); - memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config)); - spin_unlock_irqrestore(&priv->lock, flags); - - spin_lock_irqsave(&priv->lock, flags); - - /* new association get rid of ibss beacon skb */ - if (priv->beacon_skb) - dev_kfree_skb(priv->beacon_skb); - - priv->beacon_skb = NULL; - - priv->timestamp = 0; - - spin_unlock_irqrestore(&priv->lock, flags); - - iwl_scan_cancel_timeout(priv, 100); - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); - mutex_unlock(&priv->mutex); - return; - } - - /* we are restarting association process - * clear RXON_FILTER_ASSOC_MSK bit - */ - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv, ctx); - - iwl_set_rate(priv); - - mutex_unlock(&priv->mutex); - - IWL_DEBUG_MAC80211(priv, "leave\n"); -} -EXPORT_SYMBOL(iwl_legacy_mac_reset_tsf); - -static void iwl_ht_conf(struct iwl_priv *priv, - struct ieee80211_vif *vif) -{ - struct iwl_ht_config *ht_conf = &priv->current_ht_config; - struct ieee80211_sta *sta; - struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; - struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - - IWL_DEBUG_ASSOC(priv, "enter:\n"); - - if (!ctx->ht.enabled) - return; - - ctx->ht.protection = - bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; - ctx->ht.non_gf_sta_present = - !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); - - ht_conf->single_chain_sufficient = false; - - switch (vif->type) { - case NL80211_IFTYPE_STATION: - rcu_read_lock(); - sta = ieee80211_find_sta(vif, bss_conf->bssid); - if (sta) { - struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; - int maxstreams; - - maxstreams = (ht_cap->mcs.tx_params & - IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK) - >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; - maxstreams += 1; - - if ((ht_cap->mcs.rx_mask[1] == 0) && - (ht_cap->mcs.rx_mask[2] == 0)) - ht_conf->single_chain_sufficient = true; - if (maxstreams <= 1) - ht_conf->single_chain_sufficient = true; - } else { - /* - * If at all, this can only happen through a race - * when the AP disconnects us while we're still - * setting up the connection, in that case mac80211 - * will soon tell us about that. - */ - ht_conf->single_chain_sufficient = true; - } - rcu_read_unlock(); - break; - case NL80211_IFTYPE_ADHOC: - ht_conf->single_chain_sufficient = true; - break; - default: - break; - } - - IWL_DEBUG_ASSOC(priv, "leave\n"); -} - -static inline void iwl_set_no_assoc(struct iwl_priv *priv, - struct ieee80211_vif *vif) -{ - struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - - /* - * inform the ucode that there is no longer an - * association and that no more packets should be - * sent - */ - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - ctx->staging.assoc_id = 0; - iwlcore_commit_rxon(priv, ctx); -} - -static void iwlcore_beacon_update(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct iwl_priv *priv = hw->priv; - unsigned long flags; - __le64 timestamp; - struct sk_buff *skb = ieee80211_beacon_get(hw, vif); - - if (!skb) - return; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - lockdep_assert_held(&priv->mutex); - - if (!priv->beacon_ctx) { - IWL_ERR(priv, "update beacon but no beacon context!\n"); - dev_kfree_skb(skb); - return; - } - - spin_lock_irqsave(&priv->lock, flags); - - if (priv->beacon_skb) - dev_kfree_skb(priv->beacon_skb); - - priv->beacon_skb = skb; - - timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; - priv->timestamp = le64_to_cpu(timestamp); - - IWL_DEBUG_MAC80211(priv, "leave\n"); - spin_unlock_irqrestore(&priv->lock, flags); - - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); - return; - } - - priv->cfg->ops->legacy->post_associate(priv); -} - -void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changes) -{ - struct iwl_priv *priv = hw->priv; - struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - int ret; - - if (WARN_ON(!priv->cfg->ops->legacy)) - return; - - IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); - - if (!iwl_is_alive(priv)) - return; - - mutex_lock(&priv->mutex); - - if (changes & BSS_CHANGED_QOS) { - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - ctx->qos_data.qos_active = bss_conf->qos; - iwl_update_qos(priv, ctx); - spin_unlock_irqrestore(&priv->lock, flags); - } - - if (changes & BSS_CHANGED_BEACON_ENABLED) { - /* - * the add_interface code must make sure we only ever - * have a single interface that could be beaconing at - * any time. - */ - if (vif->bss_conf.enable_beacon) - priv->beacon_ctx = ctx; - else - priv->beacon_ctx = NULL; - } - - if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) { - dev_kfree_skb(priv->beacon_skb); - priv->beacon_skb = ieee80211_beacon_get(hw, vif); - } - - if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP) - iwl_send_rxon_timing(priv, ctx); - - if (changes & BSS_CHANGED_BSSID) { - IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid); - - /* - * If there is currently a HW scan going on in the - * background then we need to cancel it else the RXON - * below/in post_associate will fail. - */ - if (iwl_scan_cancel_timeout(priv, 100)) { - IWL_WARN(priv, "Aborted scan still in progress after 100ms\n"); - IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n"); - mutex_unlock(&priv->mutex); - return; - } - - /* mac80211 only sets assoc when in STATION mode */ - if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) { - memcpy(ctx->staging.bssid_addr, - bss_conf->bssid, ETH_ALEN); - - /* currently needed in a few places */ - memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); - } else { - ctx->staging.filter_flags &= - ~RXON_FILTER_ASSOC_MSK; - } - - } - - /* - * This needs to be after setting the BSSID in case - * mac80211 decides to do both changes at once because - * it will invoke post_associate. - */ - if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON) - iwlcore_beacon_update(hw, vif); - - if (changes & BSS_CHANGED_ERP_PREAMBLE) { - IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", - bss_conf->use_short_preamble); - if (bss_conf->use_short_preamble) - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; - else - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - } - - if (changes & BSS_CHANGED_ERP_CTS_PROT) { - IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot); - if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) - ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK; - else - ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK; - if (bss_conf->use_cts_prot) - ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; - else - ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN; - } - - if (changes & BSS_CHANGED_BASIC_RATES) { - /* XXX use this information - * - * To do that, remove code from iwl_set_rate() and put something - * like this here: - * - if (A-band) - ctx->staging.ofdm_basic_rates = - bss_conf->basic_rates; - else - ctx->staging.ofdm_basic_rates = - bss_conf->basic_rates >> 4; - ctx->staging.cck_basic_rates = - bss_conf->basic_rates & 0xF; - */ - } - - if (changes & BSS_CHANGED_HT) { - iwl_ht_conf(priv, vif); - - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - } - - if (changes & BSS_CHANGED_ASSOC) { - IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc); - if (bss_conf->assoc) { - priv->timestamp = bss_conf->timestamp; - - if (!iwl_is_rfkill(priv)) - priv->cfg->ops->legacy->post_associate(priv); - } else - iwl_set_no_assoc(priv, vif); - } - - if (changes && iwl_is_associated_ctx(ctx) && bss_conf->aid) { - IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n", - changes); - ret = iwl_send_rxon_assoc(priv, ctx); - if (!ret) { - /* Sync active_rxon with latest change. */ - memcpy((void *)&ctx->active, - &ctx->staging, - sizeof(struct iwl_rxon_cmd)); - } - } - - if (changes & BSS_CHANGED_BEACON_ENABLED) { - if (vif->bss_conf.enable_beacon) { - memcpy(ctx->staging.bssid_addr, - bss_conf->bssid, ETH_ALEN); - memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); - priv->cfg->ops->legacy->config_ap(priv); - } else - iwl_set_no_assoc(priv, vif); - } - - if (changes & BSS_CHANGED_IBSS) { - ret = priv->cfg->ops->legacy->manage_ibss_station(priv, vif, - bss_conf->ibss_joined); - if (ret) - IWL_ERR(priv, "failed to %s IBSS station %pM\n", - bss_conf->ibss_joined ? "add" : "remove", - bss_conf->bssid); - } - - mutex_unlock(&priv->mutex); - - IWL_DEBUG_MAC80211(priv, "leave\n"); -} -EXPORT_SYMBOL(iwl_legacy_mac_bss_info_changed); - -irqreturn_t iwl_isr_legacy(int irq, void *data) -{ - struct iwl_priv *priv = data; - u32 inta, inta_mask; - u32 inta_fh; - unsigned long flags; - if (!priv) - return IRQ_NONE; - - spin_lock_irqsave(&priv->lock, flags); - - /* Disable (but don't clear!) interrupts here to avoid - * back-to-back ISRs and sporadic interrupts from our NIC. - * If we have something to service, the tasklet will re-enable ints. - * If we *don't* have something, we'll re-enable before leaving here. */ - inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */ - iwl_write32(priv, CSR_INT_MASK, 0x00000000); - - /* Discover which interrupts are active/pending */ - inta = iwl_read32(priv, CSR_INT); - inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); - - /* Ignore interrupt if there's nothing in NIC to service. - * This may be due to IRQ shared with another device, - * or due to sporadic interrupts thrown from our NIC. */ - if (!inta && !inta_fh) { - IWL_DEBUG_ISR(priv, - "Ignore interrupt, inta == 0, inta_fh == 0\n"); - goto none; - } - - if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { - /* Hardware disappeared. It might have already raised - * an interrupt */ - IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta); - goto unplugged; - } - - IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", - inta, inta_mask, inta_fh); - - inta &= ~CSR_INT_BIT_SCD; - - /* iwl_irq_tasklet() will service interrupts and re-enable them */ - if (likely(inta || inta_fh)) - tasklet_schedule(&priv->irq_tasklet); - -unplugged: - spin_unlock_irqrestore(&priv->lock, flags); - return IRQ_HANDLED; - -none: - /* re-enable interrupts here since we don't have anything to service. */ - /* only Re-enable if disabled by irq */ - if (test_bit(STATUS_INT_ENABLED, &priv->status)) - iwl_enable_interrupts(priv); - spin_unlock_irqrestore(&priv->lock, flags); - return IRQ_NONE; -} -EXPORT_SYMBOL(iwl_isr_legacy); - -/* - * iwl_legacy_tx_cmd_protection: Set rts/cts. 3945 and 4965 only share this - * function. - */ -void iwl_legacy_tx_cmd_protection(struct iwl_priv *priv, - struct ieee80211_tx_info *info, - __le16 fc, __le32 *tx_flags) -{ - if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { - *tx_flags |= TX_CMD_FLG_RTS_MSK; - *tx_flags &= ~TX_CMD_FLG_CTS_MSK; - *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; - - if (!ieee80211_is_mgmt(fc)) - return; - - switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { - case cpu_to_le16(IEEE80211_STYPE_AUTH): - case cpu_to_le16(IEEE80211_STYPE_DEAUTH): - case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ): - case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ): - *tx_flags &= ~TX_CMD_FLG_RTS_MSK; - *tx_flags |= TX_CMD_FLG_CTS_MSK; - break; - } - } else if (info->control.rates[0].flags & - IEEE80211_TX_RC_USE_CTS_PROTECT) { - *tx_flags &= ~TX_CMD_FLG_RTS_MSK; - *tx_flags |= TX_CMD_FLG_CTS_MSK; - *tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; - } -} -EXPORT_SYMBOL(iwl_legacy_tx_cmd_protection); diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.h b/drivers/net/wireless/iwlwifi/iwl-legacy.h deleted file mode 100644 index 9f7b2f935964..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-legacy.h +++ /dev/null @@ -1,79 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *****************************************************************************/ - -#ifndef __iwl_legacy_h__ -#define __iwl_legacy_h__ - -/* mac80211 handlers */ -int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed); -void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw); -void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changes); -void iwl_legacy_tx_cmd_protection(struct iwl_priv *priv, - struct ieee80211_tx_info *info, - __le16 fc, __le32 *tx_flags); - -irqreturn_t iwl_isr_legacy(int irq, void *data); - -#endif /* __iwl_legacy_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 1d1bf3234d8d..576795e2c75b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -425,7 +425,6 @@ int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, return ret; } -EXPORT_SYMBOL(iwl_power_set_mode); int iwl_power_update_mode(struct iwl_priv *priv, bool force) { @@ -434,7 +433,6 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) iwl_power_build_cmd(priv, &cmd); return iwl_power_set_mode(priv, &cmd, force); } -EXPORT_SYMBOL(iwl_power_update_mode); /* initialize to default */ void iwl_power_initialize(struct iwl_priv *priv) @@ -448,4 +446,3 @@ void iwl_power_initialize(struct iwl_priv *priv) memset(&priv->power_data.sleep_cmd, 0, sizeof(priv->power_data.sleep_cmd)); } -EXPORT_SYMBOL(iwl_power_initialize); diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index bc89393fb696..a21f6fe10fb7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -118,7 +118,6 @@ int iwl_rx_queue_space(const struct iwl_rx_queue *q) s = 0; return s; } -EXPORT_SYMBOL(iwl_rx_queue_space); /** * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue @@ -170,7 +169,6 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q exit_unlock: spin_unlock_irqrestore(&q->lock, flags); } -EXPORT_SYMBOL(iwl_rx_queue_update_write_ptr); int iwl_rx_queue_alloc(struct iwl_priv *priv) { @@ -211,7 +209,6 @@ err_rb: err_bd: return -ENOMEM; } -EXPORT_SYMBOL(iwl_rx_queue_alloc); void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, @@ -229,7 +226,6 @@ void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, memcpy(&priv->measure_report, report, sizeof(*report)); priv->measurement_status |= MEASUREMENT_READY; } -EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif); void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt) @@ -249,7 +245,6 @@ void iwl_recover_from_statistics(struct iwl_priv *priv, !priv->cfg->ops->lib->check_plcp_health(priv, pkt)) iwl_force_reset(priv, IWL_RF_RESET, false); } -EXPORT_SYMBOL(iwl_recover_from_statistics); /* * returns non-zero if packet should be dropped @@ -302,4 +297,3 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv, } return 0; } -EXPORT_SYMBOL(iwl_set_decrypted_flag); diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 08f1bea8b652..faa6d34cb658 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -155,7 +155,6 @@ int iwl_scan_cancel(struct iwl_priv *priv) queue_work(priv->workqueue, &priv->abort_scan); return 0; } -EXPORT_SYMBOL(iwl_scan_cancel); /** * iwl_scan_cancel_timeout - Cancel any currently executing HW scan @@ -180,7 +179,6 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) return test_bit(STATUS_SCAN_HW, &priv->status); } -EXPORT_SYMBOL(iwl_scan_cancel_timeout); /* Service response to REPLY_SCAN_CMD (0x80) */ static void iwl_rx_reply_scan(struct iwl_priv *priv, @@ -288,7 +286,6 @@ void iwl_setup_rx_scan_handlers(struct iwl_priv *priv) priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] = iwl_rx_scan_complete_notif; } -EXPORT_SYMBOL(iwl_setup_rx_scan_handlers); inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, enum ieee80211_band band, @@ -301,7 +298,6 @@ inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, return IWL_ACTIVE_DWELL_TIME_24 + IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1); } -EXPORT_SYMBOL(iwl_get_active_dwell_time); u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, enum ieee80211_band band, @@ -333,7 +329,6 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, return passive; } -EXPORT_SYMBOL(iwl_get_passive_dwell_time); void iwl_init_scan_params(struct iwl_priv *priv) { @@ -343,7 +338,6 @@ void iwl_init_scan_params(struct iwl_priv *priv) if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ]) priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = ant_idx; } -EXPORT_SYMBOL(iwl_init_scan_params); static int __must_check iwl_scan_initiate(struct iwl_priv *priv, struct ieee80211_vif *vif, @@ -439,7 +433,6 @@ out_unlock: return ret; } -EXPORT_SYMBOL(iwl_mac_hw_scan); /* * internal short scan, this function should only been called while associated. @@ -536,7 +529,6 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, return (u16)len; } -EXPORT_SYMBOL(iwl_fill_probe_req); static void iwl_bg_abort_scan(struct work_struct *work) { @@ -621,7 +613,6 @@ void iwl_setup_scan_deferred_work(struct iwl_priv *priv) INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan); INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check); } -EXPORT_SYMBOL(iwl_setup_scan_deferred_work); void iwl_cancel_scan_deferred_work(struct iwl_priv *priv) { @@ -635,4 +626,3 @@ void iwl_cancel_scan_deferred_work(struct iwl_priv *priv) mutex_unlock(&priv->mutex); } } -EXPORT_SYMBOL(iwl_cancel_scan_deferred_work); diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 49493d176515..bc90a12408a3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -169,7 +169,6 @@ int iwl_send_add_sta(struct iwl_priv *priv, return ret; } -EXPORT_SYMBOL(iwl_send_add_sta); static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, struct ieee80211_sta *sta, @@ -316,7 +315,6 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, return sta_id; } -EXPORT_SYMBOL_GPL(iwl_prep_station); #define STA_WAIT_TIMEOUT (HZ/2) @@ -379,7 +377,6 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, *sta_id_r = sta_id; return ret; } -EXPORT_SYMBOL(iwl_add_station_common); /** * iwl_sta_ucode_deactivate - deactivate ucode status for a station @@ -513,7 +510,6 @@ out_err: spin_unlock_irqrestore(&priv->sta_lock, flags); return -EINVAL; } -EXPORT_SYMBOL_GPL(iwl_remove_station); /** * iwl_clear_ucode_stations - clear ucode station table bits @@ -548,7 +544,6 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv, if (!cleared) IWL_DEBUG_INFO(priv, "No active stations found to be cleared\n"); } -EXPORT_SYMBOL(iwl_clear_ucode_stations); /** * iwl_restore_stations() - Restore driver known stations to device @@ -625,7 +620,6 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) else IWL_DEBUG_INFO(priv, "Restoring all known stations .... complete.\n"); } -EXPORT_SYMBOL(iwl_restore_stations); void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { @@ -668,7 +662,6 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) priv->stations[sta_id].sta.sta.addr, ret); iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true); } -EXPORT_SYMBOL(iwl_reprogram_ap_sta); int iwl_get_free_ucode_key_index(struct iwl_priv *priv) { @@ -680,7 +673,6 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv) return WEP_INVALID_OFFSET; } -EXPORT_SYMBOL(iwl_get_free_ucode_key_index); void iwl_dealloc_bcast_stations(struct iwl_priv *priv) { @@ -700,7 +692,6 @@ void iwl_dealloc_bcast_stations(struct iwl_priv *priv) } spin_unlock_irqrestore(&priv->sta_lock, flags); } -EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_stations); #ifdef CONFIG_IWLWIFI_DEBUG static void iwl_dump_lq_cmd(struct iwl_priv *priv, @@ -810,7 +801,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, } return ret; } -EXPORT_SYMBOL(iwl_send_lq_cmd); int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -832,4 +822,3 @@ int iwl_mac_sta_remove(struct ieee80211_hw *hw, mutex_unlock(&priv->mutex); return ret; } -EXPORT_SYMBOL(iwl_mac_sta_remove); diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 073b6ce6141c..7e607d39da1c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -84,7 +84,6 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) } txq->need_update = 0; } -EXPORT_SYMBOL(iwl_txq_update_write_ptr); /** * iwl_tx_queue_free - Deallocate DMA queue. @@ -131,7 +130,6 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) /* 0-fill queue descriptor structure */ memset(txq, 0, sizeof(*txq)); } -EXPORT_SYMBOL(iwl_tx_queue_free); /** * iwl_cmd_queue_free - Deallocate DMA queue. @@ -193,7 +191,6 @@ void iwl_cmd_queue_free(struct iwl_priv *priv) /* 0-fill queue descriptor structure */ memset(txq, 0, sizeof(*txq)); } -EXPORT_SYMBOL(iwl_cmd_queue_free); /*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** * DMA services @@ -233,7 +230,6 @@ int iwl_queue_space(const struct iwl_queue *q) s = 0; return s; } -EXPORT_SYMBOL(iwl_queue_space); /** @@ -384,7 +380,6 @@ out_free_arrays: return -ENOMEM; } -EXPORT_SYMBOL(iwl_tx_queue_init); void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, int slots_num, u32 txq_id) @@ -404,7 +399,6 @@ void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, /* Tell device where to find queue */ priv->cfg->ops->lib->txq_init(priv, txq); } -EXPORT_SYMBOL(iwl_tx_queue_reset); /*************** HOST COMMAND QUEUE FUNCTIONS *****/ @@ -641,4 +635,3 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) } meta->flags = 0; } -EXPORT_SYMBOL(iwl_tx_cmd_complete); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c deleted file mode 100644 index adcef735180a..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ /dev/null @@ -1,4334 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. - * - * Portions of this file are derived from the ipw3945 project, as well - * as portions of the ieee80211 subsystem header files. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#define DRV_NAME "iwl3945" - -#include "iwl-fh.h" -#include "iwl-3945-fh.h" -#include "iwl-commands.h" -#include "iwl-sta.h" -#include "iwl-3945.h" -#include "iwl-core.h" -#include "iwl-helpers.h" -#include "iwl-dev.h" -#include "iwl-spectrum.h" -#include "iwl-legacy.h" - -/* - * module name, copyright, version, etc. - */ - -#define DRV_DESCRIPTION \ -"Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux" - -#ifdef CONFIG_IWLWIFI_DEBUG -#define VD "d" -#else -#define VD -#endif - -/* - * add "s" to indicate spectrum measurement included. - * we add it here to be consistent with previous releases in which - * this was configurable. - */ -#define DRV_VERSION IWLWIFI_VERSION VD "s" -#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation" -#define DRV_AUTHOR "" - -MODULE_DESCRIPTION(DRV_DESCRIPTION); -MODULE_VERSION(DRV_VERSION); -MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); -MODULE_LICENSE("GPL"); - - /* module parameters */ -struct iwl_mod_params iwl3945_mod_params = { - .sw_crypto = 1, - .restart_fw = 1, - /* the rest are 0 by default */ -}; - -/** - * iwl3945_get_antenna_flags - Get antenna flags for RXON command - * @priv: eeprom and antenna fields are used to determine antenna flags - * - * priv->eeprom39 is used to determine if antenna AUX/MAIN are reversed - * iwl3945_mod_params.antenna specifies the antenna diversity mode: - * - * IWL_ANTENNA_DIVERSITY - NIC selects best antenna by itself - * IWL_ANTENNA_MAIN - Force MAIN antenna - * IWL_ANTENNA_AUX - Force AUX antenna - */ -__le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv) -{ - struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; - - switch (iwl3945_mod_params.antenna) { - case IWL_ANTENNA_DIVERSITY: - return 0; - - case IWL_ANTENNA_MAIN: - if (eeprom->antenna_switch_type) - return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK; - return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK; - - case IWL_ANTENNA_AUX: - if (eeprom->antenna_switch_type) - return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK; - return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK; - } - - /* bad antenna selector value */ - IWL_ERR(priv, "Bad antenna selector value (0x%x)\n", - iwl3945_mod_params.antenna); - - return 0; /* "diversity" is default if error */ -} - -static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - u8 sta_id) -{ - unsigned long flags; - __le16 key_flags = 0; - int ret; - - key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); - key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); - - if (sta_id == priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id) - key_flags |= STA_KEY_MULTICAST_MSK; - - keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - keyconf->hw_key_idx = keyconf->keyidx; - key_flags &= ~STA_KEY_FLG_INVALID; - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; - priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; - memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, - keyconf->keylen); - - memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, - keyconf->keylen); - - if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) - == STA_KEY_FLG_NO_ENC) - priv->stations[sta_id].sta.key.key_offset = - iwl_get_free_ucode_key_index(priv); - /* else, we are overriding an existing key => no need to allocated room - * in uCode. */ - - WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, - "no space for a new key"); - - priv->stations[sta_id].sta.key.key_flags = key_flags; - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - - IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n"); - - ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); - - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return ret; -} - -static int iwl3945_set_tkip_dynamic_key_info(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - u8 sta_id) -{ - return -EOPNOTSUPP; -} - -static int iwl3945_set_wep_dynamic_key_info(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - u8 sta_id) -{ - return -EOPNOTSUPP; -} - -static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) -{ - unsigned long flags; - struct iwl_addsta_cmd sta_cmd; - - spin_lock_irqsave(&priv->sta_lock, flags); - memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key)); - memset(&priv->stations[sta_id].sta.key, 0, - sizeof(struct iwl4965_keyinfo)); - priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->sta_lock, flags); - - IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n"); - return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); -} - -static int iwl3945_set_dynamic_key(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, u8 sta_id) -{ - int ret = 0; - - keyconf->hw_key_idx = HW_KEY_DYNAMIC; - - switch (keyconf->cipher) { - case WLAN_CIPHER_SUITE_CCMP: - ret = iwl3945_set_ccmp_dynamic_key_info(priv, keyconf, sta_id); - break; - case WLAN_CIPHER_SUITE_TKIP: - ret = iwl3945_set_tkip_dynamic_key_info(priv, keyconf, sta_id); - break; - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - ret = iwl3945_set_wep_dynamic_key_info(priv, keyconf, sta_id); - break; - default: - IWL_ERR(priv, "Unknown alg: %s alg=%x\n", __func__, - keyconf->cipher); - ret = -EINVAL; - } - - IWL_DEBUG_WEP(priv, "Set dynamic key: alg=%x len=%d idx=%d sta=%d ret=%d\n", - keyconf->cipher, keyconf->keylen, keyconf->keyidx, - sta_id, ret); - - return ret; -} - -static int iwl3945_remove_static_key(struct iwl_priv *priv) -{ - int ret = -EOPNOTSUPP; - - return ret; -} - -static int iwl3945_set_static_key(struct iwl_priv *priv, - struct ieee80211_key_conf *key) -{ - if (key->cipher == WLAN_CIPHER_SUITE_WEP40 || - key->cipher == WLAN_CIPHER_SUITE_WEP104) - return -EOPNOTSUPP; - - IWL_ERR(priv, "Static key invalid: cipher %x\n", key->cipher); - return -EINVAL; -} - -static void iwl3945_clear_free_frames(struct iwl_priv *priv) -{ - struct list_head *element; - - IWL_DEBUG_INFO(priv, "%d frames on pre-allocated heap on clear.\n", - priv->frames_count); - - while (!list_empty(&priv->free_frames)) { - element = priv->free_frames.next; - list_del(element); - kfree(list_entry(element, struct iwl3945_frame, list)); - priv->frames_count--; - } - - if (priv->frames_count) { - IWL_WARN(priv, "%d frames still in use. Did we lose one?\n", - priv->frames_count); - priv->frames_count = 0; - } -} - -static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl_priv *priv) -{ - struct iwl3945_frame *frame; - struct list_head *element; - if (list_empty(&priv->free_frames)) { - frame = kzalloc(sizeof(*frame), GFP_KERNEL); - if (!frame) { - IWL_ERR(priv, "Could not allocate frame!\n"); - return NULL; - } - - priv->frames_count++; - return frame; - } - - element = priv->free_frames.next; - list_del(element); - return list_entry(element, struct iwl3945_frame, list); -} - -static void iwl3945_free_frame(struct iwl_priv *priv, struct iwl3945_frame *frame) -{ - memset(frame, 0, sizeof(*frame)); - list_add(&frame->list, &priv->free_frames); -} - -unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, - struct ieee80211_hdr *hdr, - int left) -{ - - if (!iwl_is_associated(priv, IWL_RXON_CTX_BSS) || !priv->beacon_skb) - return 0; - - if (priv->beacon_skb->len > left) - return 0; - - memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len); - - return priv->beacon_skb->len; -} - -static int iwl3945_send_beacon_cmd(struct iwl_priv *priv) -{ - struct iwl3945_frame *frame; - unsigned int frame_size; - int rc; - u8 rate; - - frame = iwl3945_get_free_frame(priv); - - if (!frame) { - IWL_ERR(priv, "Could not obtain free frame buffer for beacon " - "command.\n"); - return -ENOMEM; - } - - rate = iwl_rate_get_lowest_plcp(priv, - &priv->contexts[IWL_RXON_CTX_BSS]); - - frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate); - - rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, - &frame->u.cmd[0]); - - iwl3945_free_frame(priv, frame); - - return rc; -} - -static void iwl3945_unset_hw_params(struct iwl_priv *priv) -{ - if (priv->_3945.shared_virt) - dma_free_coherent(&priv->pci_dev->dev, - sizeof(struct iwl3945_shared), - priv->_3945.shared_virt, - priv->_3945.shared_phys); -} - -static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, - struct ieee80211_tx_info *info, - struct iwl_device_cmd *cmd, - struct sk_buff *skb_frag, - int sta_id) -{ - struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload; - struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo; - - tx_cmd->sec_ctl = 0; - - switch (keyinfo->cipher) { - case WLAN_CIPHER_SUITE_CCMP: - tx_cmd->sec_ctl = TX_CMD_SEC_CCM; - memcpy(tx_cmd->key, keyinfo->key, keyinfo->keylen); - IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n"); - break; - - case WLAN_CIPHER_SUITE_TKIP: - break; - - case WLAN_CIPHER_SUITE_WEP104: - tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128; - /* fall through */ - case WLAN_CIPHER_SUITE_WEP40: - tx_cmd->sec_ctl |= TX_CMD_SEC_WEP | - (info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT; - - memcpy(&tx_cmd->key[3], keyinfo->key, keyinfo->keylen); - - IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption " - "with key %d\n", info->control.hw_key->hw_key_idx); - break; - - default: - IWL_ERR(priv, "Unknown encode cipher %x\n", keyinfo->cipher); - break; - } -} - -/* - * handle build REPLY_TX command notification. - */ -static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv, - struct iwl_device_cmd *cmd, - struct ieee80211_tx_info *info, - struct ieee80211_hdr *hdr, u8 std_id) -{ - struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload; - __le32 tx_flags = tx_cmd->tx_flags; - __le16 fc = hdr->frame_control; - - tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { - tx_flags |= TX_CMD_FLG_ACK_MSK; - if (ieee80211_is_mgmt(fc)) - tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; - if (ieee80211_is_probe_resp(fc) && - !(le16_to_cpu(hdr->seq_ctrl) & 0xf)) - tx_flags |= TX_CMD_FLG_TSF_MSK; - } else { - tx_flags &= (~TX_CMD_FLG_ACK_MSK); - tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; - } - - tx_cmd->sta_id = std_id; - if (ieee80211_has_morefrags(fc)) - tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; - - if (ieee80211_is_data_qos(fc)) { - u8 *qc = ieee80211_get_qos_ctl(hdr); - tx_cmd->tid_tspec = qc[0] & 0xf; - tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; - } else { - tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; - } - - priv->cfg->ops->utils->tx_cmd_protection(priv, info, fc, &tx_flags); - - tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); - if (ieee80211_is_mgmt(fc)) { - if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc)) - tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3); - else - tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2); - } else { - tx_cmd->timeout.pm_frame_timeout = 0; - } - - tx_cmd->driver_txop = 0; - tx_cmd->tx_flags = tx_flags; - tx_cmd->next_frame_len = 0; -} - -/* - * start REPLY_TX command process - */ -static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct iwl3945_tx_cmd *tx_cmd; - struct iwl_tx_queue *txq = NULL; - struct iwl_queue *q = NULL; - struct iwl_device_cmd *out_cmd; - struct iwl_cmd_meta *out_meta; - dma_addr_t phys_addr; - dma_addr_t txcmd_phys; - int txq_id = skb_get_queue_mapping(skb); - u16 len, idx, hdr_len; - u8 id; - u8 unicast; - u8 sta_id; - u8 tid = 0; - __le16 fc; - u8 wait_write_ptr = 0; - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - if (iwl_is_rfkill(priv)) { - IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n"); - goto drop_unlock; - } - - if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) { - IWL_ERR(priv, "ERROR: No TX rate available.\n"); - goto drop_unlock; - } - - unicast = !is_multicast_ether_addr(hdr->addr1); - id = 0; - - fc = hdr->frame_control; - -#ifdef CONFIG_IWLWIFI_DEBUG - if (ieee80211_is_auth(fc)) - IWL_DEBUG_TX(priv, "Sending AUTH frame\n"); - else if (ieee80211_is_assoc_req(fc)) - IWL_DEBUG_TX(priv, "Sending ASSOC frame\n"); - else if (ieee80211_is_reassoc_req(fc)) - IWL_DEBUG_TX(priv, "Sending REASSOC frame\n"); -#endif - - spin_unlock_irqrestore(&priv->lock, flags); - - hdr_len = ieee80211_hdrlen(fc); - - /* Find index into station table for destination station */ - sta_id = iwl_sta_id_or_broadcast( - priv, &priv->contexts[IWL_RXON_CTX_BSS], - info->control.sta); - if (sta_id == IWL_INVALID_STATION) { - IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", - hdr->addr1); - goto drop; - } - - IWL_DEBUG_RATE(priv, "station Id %d\n", sta_id); - - if (ieee80211_is_data_qos(fc)) { - u8 *qc = ieee80211_get_qos_ctl(hdr); - tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; - if (unlikely(tid >= MAX_TID_COUNT)) - goto drop; - } - - /* Descriptor for chosen Tx queue */ - txq = &priv->txq[txq_id]; - q = &txq->q; - - if ((iwl_queue_space(q) < q->high_mark)) - goto drop; - - spin_lock_irqsave(&priv->lock, flags); - - idx = get_cmd_index(q, q->write_ptr, 0); - - /* Set up driver data for this TFD */ - memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); - txq->txb[q->write_ptr].skb = skb; - txq->txb[q->write_ptr].ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - /* Init first empty entry in queue's array of Tx/cmd buffers */ - out_cmd = txq->cmd[idx]; - out_meta = &txq->meta[idx]; - tx_cmd = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload; - memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); - memset(tx_cmd, 0, sizeof(*tx_cmd)); - - /* - * Set up the Tx-command (not MAC!) header. - * Store the chosen Tx queue and TFD index within the sequence field; - * after Tx, uCode's Tx response will return this value so driver can - * locate the frame within the tx queue and do post-tx processing. - */ - out_cmd->hdr.cmd = REPLY_TX; - out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | - INDEX_TO_SEQ(q->write_ptr))); - - /* Copy MAC header from skb into command buffer */ - memcpy(tx_cmd->hdr, hdr, hdr_len); - - - if (info->control.hw_key) - iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, sta_id); - - /* TODO need this for burst mode later on */ - iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, sta_id); - - /* set is_hcca to 0; it probably will never be implemented */ - iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0); - - /* Total # bytes to be transmitted */ - len = (u16)skb->len; - tx_cmd->len = cpu_to_le16(len); - - iwl_dbg_log_tx_data_frame(priv, len, hdr); - iwl_update_stats(priv, true, fc, len); - tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; - tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; - - if (!ieee80211_has_morefrags(hdr->frame_control)) { - txq->need_update = 1; - } else { - wait_write_ptr = 1; - txq->need_update = 0; - } - - IWL_DEBUG_TX(priv, "sequence nr = 0X%x\n", - le16_to_cpu(out_cmd->hdr.sequence)); - IWL_DEBUG_TX(priv, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); - iwl_print_hex_dump(priv, IWL_DL_TX, tx_cmd, sizeof(*tx_cmd)); - iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, - ieee80211_hdrlen(fc)); - - /* - * Use the first empty entry in this queue's command buffer array - * to contain the Tx command and MAC header concatenated together - * (payload data will be in another buffer). - * Size of this varies, due to varying MAC header length. - * If end is not dword aligned, we'll have 2 extra bytes at the end - * of the MAC header (device reads on dword boundaries). - * We'll tell device about this padding later. - */ - len = sizeof(struct iwl3945_tx_cmd) + - sizeof(struct iwl_cmd_header) + hdr_len; - len = (len + 3) & ~3; - - /* Physical address of this Tx command's header (not MAC header!), - * within command buffer array. */ - txcmd_phys = pci_map_single(priv->pci_dev, &out_cmd->hdr, - len, PCI_DMA_TODEVICE); - /* we do not map meta data ... so we can safely access address to - * provide to unmap command*/ - dma_unmap_addr_set(out_meta, mapping, txcmd_phys); - dma_unmap_len_set(out_meta, len, len); - - /* Add buffer containing Tx command and MAC(!) header to TFD's - * first entry */ - priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, - txcmd_phys, len, 1, 0); - - - /* Set up TFD's 2nd entry to point directly to remainder of skb, - * if any (802.11 null frames have no payload). */ - len = skb->len - hdr_len; - if (len) { - phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, - len, PCI_DMA_TODEVICE); - priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, - phys_addr, len, - 0, U32_PAD(len)); - } - - - /* Tell device the write index *just past* this latest filled TFD */ - q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); - iwl_txq_update_write_ptr(priv, txq); - spin_unlock_irqrestore(&priv->lock, flags); - - if ((iwl_queue_space(q) < q->high_mark) - && priv->mac80211_registered) { - if (wait_write_ptr) { - spin_lock_irqsave(&priv->lock, flags); - txq->need_update = 1; - iwl_txq_update_write_ptr(priv, txq); - spin_unlock_irqrestore(&priv->lock, flags); - } - - iwl_stop_queue(priv, txq); - } - - return 0; - -drop_unlock: - spin_unlock_irqrestore(&priv->lock, flags); -drop: - return -1; -} - -static int iwl3945_get_measurement(struct iwl_priv *priv, - struct ieee80211_measurement_params *params, - u8 type) -{ - struct iwl_spectrum_cmd spectrum; - struct iwl_rx_packet *pkt; - struct iwl_host_cmd cmd = { - .id = REPLY_SPECTRUM_MEASUREMENT_CMD, - .data = (void *)&spectrum, - .flags = CMD_WANT_SKB, - }; - u32 add_time = le64_to_cpu(params->start_time); - int rc; - int spectrum_resp_status; - int duration = le16_to_cpu(params->duration); - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) - add_time = iwl_usecs_to_beacons(priv, - le64_to_cpu(params->start_time) - priv->_3945.last_tsf, - le16_to_cpu(ctx->timing.beacon_interval)); - - memset(&spectrum, 0, sizeof(spectrum)); - - spectrum.channel_count = cpu_to_le16(1); - spectrum.flags = - RXON_FLG_TSF2HOST_MSK | RXON_FLG_ANT_A_MSK | RXON_FLG_DIS_DIV_MSK; - spectrum.filter_flags = MEASUREMENT_FILTER_FLAG; - cmd.len = sizeof(spectrum); - spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len)); - - if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) - spectrum.start_time = - iwl_add_beacon_time(priv, - priv->_3945.last_beacon_time, add_time, - le16_to_cpu(ctx->timing.beacon_interval)); - else - spectrum.start_time = 0; - - spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT); - spectrum.channels[0].channel = params->channel; - spectrum.channels[0].type = type; - if (ctx->active.flags & RXON_FLG_BAND_24G_MSK) - spectrum.flags |= RXON_FLG_BAND_24G_MSK | - RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK; - - rc = iwl_send_cmd_sync(priv, &cmd); - if (rc) - return rc; - - pkt = (struct iwl_rx_packet *)cmd.reply_page; - if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { - IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n"); - rc = -EIO; - } - - spectrum_resp_status = le16_to_cpu(pkt->u.spectrum.status); - switch (spectrum_resp_status) { - case 0: /* Command will be handled */ - if (pkt->u.spectrum.id != 0xff) { - IWL_DEBUG_INFO(priv, "Replaced existing measurement: %d\n", - pkt->u.spectrum.id); - priv->measurement_status &= ~MEASUREMENT_READY; - } - priv->measurement_status |= MEASUREMENT_ACTIVE; - rc = 0; - break; - - case 1: /* Command will not be handled */ - rc = -EAGAIN; - break; - } - - iwl_free_pages(priv, cmd.reply_page); - - return rc; -} - -static void iwl3945_rx_reply_alive(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_alive_resp *palive; - struct delayed_work *pwork; - - palive = &pkt->u.alive_frame; - - IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision " - "0x%01X 0x%01X\n", - palive->is_valid, palive->ver_type, - palive->ver_subtype); - - if (palive->ver_subtype == INITIALIZE_SUBTYPE) { - IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); - memcpy(&priv->card_alive_init, &pkt->u.alive_frame, - sizeof(struct iwl_alive_resp)); - pwork = &priv->init_alive_start; - } else { - IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); - memcpy(&priv->card_alive, &pkt->u.alive_frame, - sizeof(struct iwl_alive_resp)); - pwork = &priv->alive_start; - iwl3945_disable_events(priv); - } - - /* We delay the ALIVE response by 5ms to - * give the HW RF Kill time to activate... */ - if (palive->is_valid == UCODE_VALID_OK) - queue_delayed_work(priv->workqueue, pwork, - msecs_to_jiffies(5)); - else - IWL_WARN(priv, "uCode did not respond OK.\n"); -} - -static void iwl3945_rx_reply_add_sta(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ -#ifdef CONFIG_IWLWIFI_DEBUG - struct iwl_rx_packet *pkt = rxb_addr(rxb); -#endif - - IWL_DEBUG_RX(priv, "Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status); -} - -static void iwl3945_bg_beacon_update(struct work_struct *work) -{ - struct iwl_priv *priv = - container_of(work, struct iwl_priv, beacon_update); - struct sk_buff *beacon; - - /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ - beacon = ieee80211_beacon_get(priv->hw, - priv->contexts[IWL_RXON_CTX_BSS].vif); - - if (!beacon) { - IWL_ERR(priv, "update beacon failed\n"); - return; - } - - mutex_lock(&priv->mutex); - /* new beacon skb is allocated every time; dispose previous.*/ - if (priv->beacon_skb) - dev_kfree_skb(priv->beacon_skb); - - priv->beacon_skb = beacon; - mutex_unlock(&priv->mutex); - - iwl3945_send_beacon_cmd(priv); -} - -static void iwl3945_rx_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status); -#ifdef CONFIG_IWLWIFI_DEBUG - u8 rate = beacon->beacon_notify_hdr.rate; - - IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d " - "tsf %d %d rate %d\n", - le32_to_cpu(beacon->beacon_notify_hdr.status) & TX_STATUS_MSK, - beacon->beacon_notify_hdr.failure_frame, - le32_to_cpu(beacon->ibss_mgr_status), - le32_to_cpu(beacon->high_tsf), - le32_to_cpu(beacon->low_tsf), rate); -#endif - - priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); - - if ((priv->iw_mode == NL80211_IFTYPE_AP) && - (!test_bit(STATUS_EXIT_PENDING, &priv->status))) - queue_work(priv->workqueue, &priv->beacon_update); -} - -/* Handle notification from uCode that card's power state is changing - * due to software, hardware, or critical temperature RFKILL */ -static void iwl3945_rx_card_state_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); - unsigned long status = priv->status; - - IWL_WARN(priv, "Card state received: HW:%s SW:%s\n", - (flags & HW_CARD_DISABLED) ? "Kill" : "On", - (flags & SW_CARD_DISABLED) ? "Kill" : "On"); - - iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, - CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); - - if (flags & HW_CARD_DISABLED) - set_bit(STATUS_RF_KILL_HW, &priv->status); - else - clear_bit(STATUS_RF_KILL_HW, &priv->status); - - - iwl_scan_cancel(priv); - - if ((test_bit(STATUS_RF_KILL_HW, &status) != - test_bit(STATUS_RF_KILL_HW, &priv->status))) - wiphy_rfkill_set_hw_state(priv->hw->wiphy, - test_bit(STATUS_RF_KILL_HW, &priv->status)); - else - wake_up_interruptible(&priv->wait_command_queue); -} - -/** - * iwl3945_setup_rx_handlers - Initialize Rx handler callbacks - * - * Setup the RX handlers for each of the reply types sent from the uCode - * to the host. - * - * This function chains into the hardware specific files for them to setup - * any hardware specific handlers as well. - */ -static void iwl3945_setup_rx_handlers(struct iwl_priv *priv) -{ - priv->rx_handlers[REPLY_ALIVE] = iwl3945_rx_reply_alive; - priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta; - priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; - priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; - priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] = - iwl_rx_spectrum_measure_notif; - priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; - priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = - iwl_rx_pm_debug_statistics_notif; - priv->rx_handlers[BEACON_NOTIFICATION] = iwl3945_rx_beacon_notif; - - /* - * The same handler is used for both the REPLY to a discrete - * statistics request from the host as well as for the periodic - * statistics notifications (after received beacons) from the uCode. - */ - priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_reply_statistics; - priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics; - - iwl_setup_rx_scan_handlers(priv); - priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif; - - /* Set up hardware specific Rx handlers */ - iwl3945_hw_rx_handler_setup(priv); -} - -/************************** RX-FUNCTIONS ****************************/ -/* - * Rx theory of operation - * - * The host allocates 32 DMA target addresses and passes the host address - * to the firmware at register IWL_RFDS_TABLE_LOWER + N * RFD_SIZE where N is - * 0 to 31 - * - * Rx Queue Indexes - * The host/firmware share two index registers for managing the Rx buffers. - * - * The READ index maps to the first position that the firmware may be writing - * to -- the driver can read up to (but not including) this position and get - * good data. - * The READ index is managed by the firmware once the card is enabled. - * - * The WRITE index maps to the last position the driver has read from -- the - * position preceding WRITE is the last slot the firmware can place a packet. - * - * The queue is empty (no good data) if WRITE = READ - 1, and is full if - * WRITE = READ. - * - * During initialization, the host sets up the READ queue position to the first - * INDEX position, and WRITE to the last (READ - 1 wrapped) - * - * When the firmware places a packet in a buffer, it will advance the READ index - * and fire the RX interrupt. The driver can then query the READ index and - * process as many packets as possible, moving the WRITE index forward as it - * resets the Rx queue buffers with new memory. - * - * The management in the driver is as follows: - * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When - * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled - * to replenish the iwl->rxq->rx_free. - * + In iwl3945_rx_replenish (scheduled) if 'processed' != 'read' then the - * iwl->rxq is replenished and the READ INDEX is updated (updating the - * 'processed' and 'read' driver indexes as well) - * + A received packet is processed and handed to the kernel network stack, - * detached from the iwl->rxq. The driver 'processed' index is updated. - * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free - * list. If there are no allocated buffers in iwl->rxq->rx_free, the READ - * INDEX is not incremented and iwl->status(RX_STALLED) is set. If there - * were enough free buffers and RX_STALLED is set it is cleared. - * - * - * Driver sequence: - * - * iwl3945_rx_replenish() Replenishes rx_free list from rx_used, and calls - * iwl3945_rx_queue_restock - * iwl3945_rx_queue_restock() Moves available buffers from rx_free into Rx - * queue, updates firmware pointers, and updates - * the WRITE index. If insufficient rx_free buffers - * are available, schedules iwl3945_rx_replenish - * - * -- enable interrupts -- - * ISR - iwl3945_rx() Detach iwl_rx_mem_buffers from pool up to the - * READ INDEX, detaching the SKB from the pool. - * Moves the packet buffer from queue to rx_used. - * Calls iwl3945_rx_queue_restock to refill any empty - * slots. - * ... - * - */ - -/** - * iwl3945_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr - */ -static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl_priv *priv, - dma_addr_t dma_addr) -{ - return cpu_to_le32((u32)dma_addr); -} - -/** - * iwl3945_rx_queue_restock - refill RX queue from pre-allocated pool - * - * If there are slots in the RX queue that need to be restocked, - * and we have free pre-allocated buffers, fill the ranks as much - * as we can, pulling from rx_free. - * - * This moves the 'write' index forward to catch up with 'processed', and - * also updates the memory address in the firmware to reference the new - * target buffer. - */ -static void iwl3945_rx_queue_restock(struct iwl_priv *priv) -{ - struct iwl_rx_queue *rxq = &priv->rxq; - struct list_head *element; - struct iwl_rx_mem_buffer *rxb; - unsigned long flags; - int write; - - spin_lock_irqsave(&rxq->lock, flags); - write = rxq->write & ~0x7; - while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) { - /* Get next free Rx buffer, remove from free list */ - element = rxq->rx_free.next; - rxb = list_entry(element, struct iwl_rx_mem_buffer, list); - list_del(element); - - /* Point to Rx buffer via next RBD in circular buffer */ - rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->page_dma); - rxq->queue[rxq->write] = rxb; - rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; - rxq->free_count--; - } - spin_unlock_irqrestore(&rxq->lock, flags); - /* If the pre-allocated buffer pool is dropping low, schedule to - * refill it */ - if (rxq->free_count <= RX_LOW_WATERMARK) - queue_work(priv->workqueue, &priv->rx_replenish); - - - /* If we've added more space for the firmware to place data, tell it. - * Increment device's write pointer in multiples of 8. */ - if ((rxq->write_actual != (rxq->write & ~0x7)) - || (abs(rxq->write - rxq->read) > 7)) { - spin_lock_irqsave(&rxq->lock, flags); - rxq->need_update = 1; - spin_unlock_irqrestore(&rxq->lock, flags); - iwl_rx_queue_update_write_ptr(priv, rxq); - } -} - -/** - * iwl3945_rx_replenish - Move all used packet from rx_used to rx_free - * - * When moving to rx_free an SKB is allocated for the slot. - * - * Also restock the Rx queue via iwl3945_rx_queue_restock. - * This is called as a scheduled work item (except for during initialization) - */ -static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority) -{ - struct iwl_rx_queue *rxq = &priv->rxq; - struct list_head *element; - struct iwl_rx_mem_buffer *rxb; - struct page *page; - unsigned long flags; - gfp_t gfp_mask = priority; - - while (1) { - spin_lock_irqsave(&rxq->lock, flags); - - if (list_empty(&rxq->rx_used)) { - spin_unlock_irqrestore(&rxq->lock, flags); - return; - } - spin_unlock_irqrestore(&rxq->lock, flags); - - if (rxq->free_count > RX_LOW_WATERMARK) - gfp_mask |= __GFP_NOWARN; - - if (priv->hw_params.rx_page_order > 0) - gfp_mask |= __GFP_COMP; - - /* Alloc a new receive buffer */ - page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order); - if (!page) { - if (net_ratelimit()) - IWL_DEBUG_INFO(priv, "Failed to allocate SKB buffer.\n"); - if ((rxq->free_count <= RX_LOW_WATERMARK) && - net_ratelimit()) - IWL_CRIT(priv, "Failed to allocate SKB buffer with %s. Only %u free buffers remaining.\n", - priority == GFP_ATOMIC ? "GFP_ATOMIC" : "GFP_KERNEL", - rxq->free_count); - /* We don't reschedule replenish work here -- we will - * call the restock method and if it still needs - * more buffers it will schedule replenish */ - break; - } - - spin_lock_irqsave(&rxq->lock, flags); - if (list_empty(&rxq->rx_used)) { - spin_unlock_irqrestore(&rxq->lock, flags); - __free_pages(page, priv->hw_params.rx_page_order); - return; - } - element = rxq->rx_used.next; - rxb = list_entry(element, struct iwl_rx_mem_buffer, list); - list_del(element); - spin_unlock_irqrestore(&rxq->lock, flags); - - rxb->page = page; - /* Get physical address of RB/SKB */ - rxb->page_dma = pci_map_page(priv->pci_dev, page, 0, - PAGE_SIZE << priv->hw_params.rx_page_order, - PCI_DMA_FROMDEVICE); - - spin_lock_irqsave(&rxq->lock, flags); - - list_add_tail(&rxb->list, &rxq->rx_free); - rxq->free_count++; - priv->alloc_rxb_page++; - - spin_unlock_irqrestore(&rxq->lock, flags); - } -} - -void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) -{ - unsigned long flags; - int i; - spin_lock_irqsave(&rxq->lock, flags); - INIT_LIST_HEAD(&rxq->rx_free); - INIT_LIST_HEAD(&rxq->rx_used); - /* Fill the rx_used queue with _all_ of the Rx buffers */ - for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { - /* In the reset function, these buffers may have been allocated - * to an SKB, so we need to unmap and free potential storage */ - if (rxq->pool[i].page != NULL) { - pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, - PAGE_SIZE << priv->hw_params.rx_page_order, - PCI_DMA_FROMDEVICE); - __iwl_free_pages(priv, rxq->pool[i].page); - rxq->pool[i].page = NULL; - } - list_add_tail(&rxq->pool[i].list, &rxq->rx_used); - } - - /* 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->write_actual = 0; - rxq->free_count = 0; - spin_unlock_irqrestore(&rxq->lock, flags); -} - -void iwl3945_rx_replenish(void *data) -{ - struct iwl_priv *priv = data; - unsigned long flags; - - iwl3945_rx_allocate(priv, GFP_KERNEL); - - spin_lock_irqsave(&priv->lock, flags); - iwl3945_rx_queue_restock(priv); - spin_unlock_irqrestore(&priv->lock, flags); -} - -static void iwl3945_rx_replenish_now(struct iwl_priv *priv) -{ - iwl3945_rx_allocate(priv, GFP_ATOMIC); - - iwl3945_rx_queue_restock(priv); -} - - -/* Assumes that the skb field of the buffers in 'pool' is kept accurate. - * If an SKB has been detached, the POOL needs to have its SKB set to NULL - * This free routine walks the list of POOL entries and if SKB is set to - * non NULL it is unmapped and freed - */ -static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) -{ - int i; - for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { - if (rxq->pool[i].page != NULL) { - pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma, - PAGE_SIZE << priv->hw_params.rx_page_order, - PCI_DMA_FROMDEVICE); - __iwl_free_pages(priv, rxq->pool[i].page); - rxq->pool[i].page = NULL; - } - } - - dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd, - rxq->bd_dma); - dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status), - rxq->rb_stts, rxq->rb_stts_dma); - rxq->bd = NULL; - rxq->rb_stts = NULL; -} - - -/* Convert linear signal-to-noise ratio into dB */ -static u8 ratio2dB[100] = { -/* 0 1 2 3 4 5 6 7 8 9 */ - 0, 0, 6, 10, 12, 14, 16, 17, 18, 19, /* 00 - 09 */ - 20, 21, 22, 22, 23, 23, 24, 25, 26, 26, /* 10 - 19 */ - 26, 26, 26, 27, 27, 28, 28, 28, 29, 29, /* 20 - 29 */ - 29, 30, 30, 30, 31, 31, 31, 31, 32, 32, /* 30 - 39 */ - 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, /* 40 - 49 */ - 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, /* 50 - 59 */ - 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, /* 60 - 69 */ - 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, /* 70 - 79 */ - 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, /* 80 - 89 */ - 39, 39, 39, 39, 39, 40, 40, 40, 40, 40 /* 90 - 99 */ -}; - -/* Calculates a relative dB value from a ratio of linear - * (i.e. not dB) signal levels. - * Conversion assumes that levels are voltages (20*log), not powers (10*log). */ -int iwl3945_calc_db_from_ratio(int sig_ratio) -{ - /* 1000:1 or higher just report as 60 dB */ - if (sig_ratio >= 1000) - return 60; - - /* 100:1 or higher, divide by 10 and use table, - * add 20 dB to make up for divide by 10 */ - if (sig_ratio >= 100) - return 20 + (int)ratio2dB[sig_ratio/10]; - - /* We shouldn't see this */ - if (sig_ratio < 1) - return 0; - - /* Use table for ratios 1:1 - 99:1 */ - return (int)ratio2dB[sig_ratio]; -} - -/** - * iwl3945_rx_handle - Main entry function for receiving responses from uCode - * - * Uses the priv->rx_handlers callback function array to invoke - * the appropriate handlers, including command responses, - * frame-received notifications, and other notifications. - */ -static void iwl3945_rx_handle(struct iwl_priv *priv) -{ - struct iwl_rx_mem_buffer *rxb; - struct iwl_rx_packet *pkt; - struct iwl_rx_queue *rxq = &priv->rxq; - u32 r, i; - int reclaim; - unsigned long flags; - u8 fill_rx = 0; - u32 count = 8; - int total_empty = 0; - - /* uCode's read index (stored in shared DRAM) indicates the last Rx - * buffer that the driver may process (last buffer filled by ucode). */ - r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF; - i = rxq->read; - - /* calculate total frames need to be restock after handling RX */ - total_empty = r - rxq->write_actual; - if (total_empty < 0) - total_empty += RX_QUEUE_SIZE; - - if (total_empty > (RX_QUEUE_SIZE / 2)) - fill_rx = 1; - /* Rx interrupt, but nothing sent from uCode */ - if (i == r) - IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i); - - while (i != r) { - int len; - - rxb = rxq->queue[i]; - - /* If an RXB doesn't have a Rx queue slot associated with it, - * then a bug has been introduced in the queue refilling - * routines -- catch it here */ - BUG_ON(rxb == NULL); - - rxq->queue[i] = NULL; - - pci_unmap_page(priv->pci_dev, rxb->page_dma, - PAGE_SIZE << priv->hw_params.rx_page_order, - PCI_DMA_FROMDEVICE); - pkt = rxb_addr(rxb); - - len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; - len += sizeof(u32); /* account for status word */ - trace_iwlwifi_dev_rx(priv, pkt, len); - - /* Reclaim a command buffer only if this packet is a response - * to a (driver-originated) command. - * If the packet (e.g. Rx frame) originated from uCode, - * there is no command buffer to reclaim. - * Ucode should set SEQ_RX_FRAME bit if ucode-originated, - * but apparently a few don't get set; catch them here. */ - reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) && - (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && - (pkt->hdr.cmd != REPLY_TX); - - /* Based on type of command response or notification, - * handle those that need handling via function in - * rx_handlers table. See iwl3945_setup_rx_handlers() */ - if (priv->rx_handlers[pkt->hdr.cmd]) { - IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, i, - get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); - priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; - priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); - } else { - /* No handling needed */ - IWL_DEBUG_RX(priv, - "r %d i %d No handler needed for %s, 0x%02x\n", - r, i, get_cmd_string(pkt->hdr.cmd), - pkt->hdr.cmd); - } - - /* - * XXX: After here, we should always check rxb->page - * against NULL before touching it or its virtual - * memory (pkt). Because some rx_handler might have - * already taken or freed the pages. - */ - - if (reclaim) { - /* Invoke any callbacks, transfer the buffer to caller, - * and fire off the (possibly) blocking iwl_send_cmd() - * as we reclaim the driver command queue */ - if (rxb->page) - iwl_tx_cmd_complete(priv, rxb); - else - IWL_WARN(priv, "Claim null rxb?\n"); - } - - /* Reuse the page if possible. For notification packets and - * SKBs that fail to Rx correctly, add them back into the - * rx_free list for reuse later. */ - spin_lock_irqsave(&rxq->lock, flags); - if (rxb->page != NULL) { - rxb->page_dma = pci_map_page(priv->pci_dev, rxb->page, - 0, PAGE_SIZE << priv->hw_params.rx_page_order, - PCI_DMA_FROMDEVICE); - list_add_tail(&rxb->list, &rxq->rx_free); - rxq->free_count++; - } else - list_add_tail(&rxb->list, &rxq->rx_used); - - spin_unlock_irqrestore(&rxq->lock, flags); - - i = (i + 1) & RX_QUEUE_MASK; - /* If there are a lot of unused frames, - * restock the Rx queue so ucode won't assert. */ - if (fill_rx) { - count++; - if (count >= 8) { - rxq->read = i; - iwl3945_rx_replenish_now(priv); - count = 0; - } - } - } - - /* Backtrack one entry */ - rxq->read = i; - if (fill_rx) - iwl3945_rx_replenish_now(priv); - else - iwl3945_rx_queue_restock(priv); -} - -/* call this function to flush any scheduled tasklet */ -static inline void iwl_synchronize_irq(struct iwl_priv *priv) -{ - /* wait to make sure we flush pending tasklet*/ - synchronize_irq(priv->pci_dev->irq); - tasklet_kill(&priv->irq_tasklet); -} - -static const char *desc_lookup(int i) -{ - switch (i) { - case 1: - return "FAIL"; - case 2: - return "BAD_PARAM"; - case 3: - return "BAD_CHECKSUM"; - case 4: - return "NMI_INTERRUPT"; - case 5: - return "SYSASSERT"; - case 6: - return "FATAL_ERROR"; - } - - return "UNKNOWN"; -} - -#define ERROR_START_OFFSET (1 * sizeof(u32)) -#define ERROR_ELEM_SIZE (7 * sizeof(u32)) - -void iwl3945_dump_nic_error_log(struct iwl_priv *priv) -{ - u32 i; - u32 desc, time, count, base, data1; - u32 blink1, blink2, ilink1, ilink2; - - base = le32_to_cpu(priv->card_alive.error_event_table_ptr); - - if (!iwl3945_hw_valid_rtc_data_addr(base)) { - IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base); - return; - } - - - count = iwl_read_targ_mem(priv, base); - - if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { - IWL_ERR(priv, "Start IWL Error Log Dump:\n"); - IWL_ERR(priv, "Status: 0x%08lX, count: %d\n", - priv->status, count); - } - - IWL_ERR(priv, "Desc Time asrtPC blink2 " - "ilink1 nmiPC Line\n"); - for (i = ERROR_START_OFFSET; - i < (count * ERROR_ELEM_SIZE) + ERROR_START_OFFSET; - i += ERROR_ELEM_SIZE) { - desc = iwl_read_targ_mem(priv, base + i); - time = - iwl_read_targ_mem(priv, base + i + 1 * sizeof(u32)); - blink1 = - iwl_read_targ_mem(priv, base + i + 2 * sizeof(u32)); - blink2 = - iwl_read_targ_mem(priv, base + i + 3 * sizeof(u32)); - ilink1 = - iwl_read_targ_mem(priv, base + i + 4 * sizeof(u32)); - ilink2 = - iwl_read_targ_mem(priv, base + i + 5 * sizeof(u32)); - data1 = - iwl_read_targ_mem(priv, base + i + 6 * sizeof(u32)); - - IWL_ERR(priv, - "%-13s (0x%X) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n", - desc_lookup(desc), desc, time, blink1, blink2, - ilink1, ilink2, data1); - trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, 0, - 0, blink1, blink2, ilink1, ilink2); - } -} - -#define EVENT_START_OFFSET (6 * sizeof(u32)) - -/** - * iwl3945_print_event_log - Dump error event log to syslog - * - */ -static int iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, - u32 num_events, u32 mode, - int pos, char **buf, size_t bufsz) -{ - u32 i; - u32 base; /* SRAM byte address of event log header */ - u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */ - u32 ptr; /* SRAM byte address of log data */ - u32 ev, time, data; /* event log data */ - unsigned long reg_flags; - - if (num_events == 0) - return pos; - - base = le32_to_cpu(priv->card_alive.log_event_table_ptr); - - if (mode == 0) - event_size = 2 * sizeof(u32); - else - event_size = 3 * sizeof(u32); - - ptr = base + EVENT_START_OFFSET + (start_idx * event_size); - - /* Make sure device is powered up for SRAM reads */ - spin_lock_irqsave(&priv->reg_lock, reg_flags); - iwl_grab_nic_access(priv); - - /* Set starting address; reads will auto-increment */ - _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr); - rmb(); - - /* "time" is actually "data" for mode 0 (no timestamp). - * place event id # at far right for easier visual parsing. */ - for (i = 0; i < num_events; i++) { - ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); - time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); - if (mode == 0) { - /* data, ev */ - if (bufsz) { - pos += scnprintf(*buf + pos, bufsz - pos, - "0x%08x:%04u\n", - time, ev); - } else { - IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); - trace_iwlwifi_dev_ucode_event(priv, 0, - time, ev); - } - } else { - data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); - if (bufsz) { - pos += scnprintf(*buf + pos, bufsz - pos, - "%010u:0x%08x:%04u\n", - time, data, ev); - } else { - IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", - time, data, ev); - trace_iwlwifi_dev_ucode_event(priv, time, - data, ev); - } - } - } - - /* Allow device to power down */ - iwl_release_nic_access(priv); - spin_unlock_irqrestore(&priv->reg_lock, reg_flags); - return pos; -} - -/** - * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog - */ -static int iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, - u32 num_wraps, u32 next_entry, - u32 size, u32 mode, - int pos, char **buf, size_t bufsz) -{ - /* - * display the newest DEFAULT_LOG_ENTRIES entries - * i.e the entries just before the next ont that uCode would fill. - */ - if (num_wraps) { - if (next_entry < size) { - pos = iwl3945_print_event_log(priv, - capacity - (size - next_entry), - size - next_entry, mode, - pos, buf, bufsz); - pos = iwl3945_print_event_log(priv, 0, - next_entry, mode, - pos, buf, bufsz); - } else - pos = iwl3945_print_event_log(priv, next_entry - size, - size, mode, - pos, buf, bufsz); - } else { - if (next_entry < size) - pos = iwl3945_print_event_log(priv, 0, - next_entry, mode, - pos, buf, bufsz); - else - pos = iwl3945_print_event_log(priv, next_entry - size, - size, mode, - pos, buf, bufsz); - } - return pos; -} - -#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) - -int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, - char **buf, bool display) -{ - u32 base; /* SRAM byte address of event log header */ - u32 capacity; /* event log capacity in # entries */ - u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ - u32 num_wraps; /* # times uCode wrapped to top of log */ - u32 next_entry; /* index of next entry to be written by uCode */ - u32 size; /* # entries that we'll print */ - int pos = 0; - size_t bufsz = 0; - - base = le32_to_cpu(priv->card_alive.log_event_table_ptr); - if (!iwl3945_hw_valid_rtc_data_addr(base)) { - IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); - return -EINVAL; - } - - /* event log header */ - capacity = iwl_read_targ_mem(priv, base); - mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32))); - num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); - next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); - - if (capacity > priv->cfg->base_params->max_event_log_size) { - IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n", - capacity, priv->cfg->base_params->max_event_log_size); - capacity = priv->cfg->base_params->max_event_log_size; - } - - if (next_entry > priv->cfg->base_params->max_event_log_size) { - IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n", - next_entry, priv->cfg->base_params->max_event_log_size); - next_entry = priv->cfg->base_params->max_event_log_size; - } - - size = num_wraps ? capacity : next_entry; - - /* bail out if nothing in log */ - if (size == 0) { - IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); - return pos; - } - -#ifdef CONFIG_IWLWIFI_DEBUG - if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) - size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) - ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; -#else - size = (size > DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES) - ? DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES : size; -#endif - - IWL_ERR(priv, "Start IWL Event Log Dump: display last %d count\n", - size); - -#ifdef CONFIG_IWLWIFI_DEBUG - if (display) { - if (full_log) - bufsz = capacity * 48; - else - bufsz = size * 48; - *buf = kmalloc(bufsz, GFP_KERNEL); - if (!*buf) - return -ENOMEM; - } - if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { - /* if uCode has wrapped back to top of log, - * start at the oldest entry, - * i.e the next one that uCode would fill. - */ - if (num_wraps) - pos = iwl3945_print_event_log(priv, next_entry, - capacity - next_entry, mode, - pos, buf, bufsz); - - /* (then/else) start at top of log */ - pos = iwl3945_print_event_log(priv, 0, next_entry, mode, - pos, buf, bufsz); - } else - pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps, - next_entry, size, mode, - pos, buf, bufsz); -#else - pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps, - next_entry, size, mode, - pos, buf, bufsz); -#endif - return pos; -} - -static void iwl3945_irq_tasklet(struct iwl_priv *priv) -{ - u32 inta, handled = 0; - u32 inta_fh; - unsigned long flags; -#ifdef CONFIG_IWLWIFI_DEBUG - u32 inta_mask; -#endif - - spin_lock_irqsave(&priv->lock, flags); - - /* Ack/clear/reset pending uCode interrupts. - * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, - * and will clear only when CSR_FH_INT_STATUS gets cleared. */ - inta = iwl_read32(priv, CSR_INT); - iwl_write32(priv, CSR_INT, inta); - - /* Ack/clear/reset pending flow-handler (DMA) interrupts. - * Any new interrupts that happen after this, either while we're - * in this tasklet, or later, will show up in next ISR/tasklet. */ - inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); - iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh); - -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(priv) & IWL_DL_ISR) { - /* just for debug */ - inta_mask = iwl_read32(priv, CSR_INT_MASK); - IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", - inta, inta_mask, inta_fh); - } -#endif - - spin_unlock_irqrestore(&priv->lock, flags); - - /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not - * atomic, make sure that inta covers all the interrupts that - * we've discovered, even if FH interrupt came in just after - * reading CSR_INT. */ - if (inta_fh & CSR39_FH_INT_RX_MASK) - inta |= CSR_INT_BIT_FH_RX; - if (inta_fh & CSR39_FH_INT_TX_MASK) - inta |= CSR_INT_BIT_FH_TX; - - /* Now service all interrupt bits discovered above. */ - if (inta & CSR_INT_BIT_HW_ERR) { - IWL_ERR(priv, "Hardware error detected. Restarting.\n"); - - /* Tell the device to stop sending interrupts */ - iwl_disable_interrupts(priv); - - priv->isr_stats.hw++; - iwl_irq_handle_error(priv); - - handled |= CSR_INT_BIT_HW_ERR; - - return; - } - -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) { - /* NIC fires this, but we don't use it, redundant with WAKEUP */ - if (inta & CSR_INT_BIT_SCD) { - IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " - "the frame/frames.\n"); - priv->isr_stats.sch++; - } - - /* Alive notification via Rx interrupt will do the real work */ - if (inta & CSR_INT_BIT_ALIVE) { - IWL_DEBUG_ISR(priv, "Alive interrupt\n"); - priv->isr_stats.alive++; - } - } -#endif - /* Safely ignore these bits for debug checks below */ - inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE); - - /* Error detected by uCode */ - if (inta & CSR_INT_BIT_SW_ERR) { - IWL_ERR(priv, "Microcode SW error detected. " - "Restarting 0x%X.\n", inta); - priv->isr_stats.sw++; - iwl_irq_handle_error(priv); - handled |= CSR_INT_BIT_SW_ERR; - } - - /* uCode wakes up after power-down sleep */ - if (inta & CSR_INT_BIT_WAKEUP) { - IWL_DEBUG_ISR(priv, "Wakeup interrupt\n"); - iwl_rx_queue_update_write_ptr(priv, &priv->rxq); - iwl_txq_update_write_ptr(priv, &priv->txq[0]); - iwl_txq_update_write_ptr(priv, &priv->txq[1]); - iwl_txq_update_write_ptr(priv, &priv->txq[2]); - iwl_txq_update_write_ptr(priv, &priv->txq[3]); - iwl_txq_update_write_ptr(priv, &priv->txq[4]); - iwl_txq_update_write_ptr(priv, &priv->txq[5]); - - priv->isr_stats.wakeup++; - handled |= CSR_INT_BIT_WAKEUP; - } - - /* All uCode command responses, including Tx command responses, - * Rx "responses" (frame-received notification), and other - * notifications from uCode come through here*/ - if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { - iwl3945_rx_handle(priv); - priv->isr_stats.rx++; - handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); - } - - if (inta & CSR_INT_BIT_FH_TX) { - IWL_DEBUG_ISR(priv, "Tx interrupt\n"); - priv->isr_stats.tx++; - - iwl_write32(priv, CSR_FH_INT_STATUS, (1 << 6)); - iwl_write_direct32(priv, FH39_TCSR_CREDIT - (FH39_SRVC_CHNL), 0x0); - handled |= CSR_INT_BIT_FH_TX; - } - - if (inta & ~handled) { - IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); - priv->isr_stats.unhandled++; - } - - if (inta & ~priv->inta_mask) { - IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", - inta & ~priv->inta_mask); - IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh); - } - - /* Re-enable all interrupts */ - /* only Re-enable if disabled by irq */ - if (test_bit(STATUS_INT_ENABLED, &priv->status)) - iwl_enable_interrupts(priv); - -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) { - inta = iwl_read32(priv, CSR_INT); - inta_mask = iwl_read32(priv, CSR_INT_MASK); - inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); - IWL_DEBUG_ISR(priv, "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, " - "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); - } -#endif -} - -static int iwl3945_get_single_channel_for_scan(struct iwl_priv *priv, - struct ieee80211_vif *vif, - enum ieee80211_band band, - struct iwl3945_scan_channel *scan_ch) -{ - const struct ieee80211_supported_band *sband; - u16 passive_dwell = 0; - u16 active_dwell = 0; - int added = 0; - u8 channel = 0; - - sband = iwl_get_hw_mode(priv, band); - if (!sband) { - IWL_ERR(priv, "invalid band\n"); - return added; - } - - active_dwell = iwl_get_active_dwell_time(priv, band, 0); - passive_dwell = iwl_get_passive_dwell_time(priv, band, vif); - - if (passive_dwell <= active_dwell) - passive_dwell = active_dwell + 1; - - - channel = iwl_get_single_channel_number(priv, band); - - if (channel) { - scan_ch->channel = channel; - scan_ch->type = 0; /* passive */ - scan_ch->active_dwell = cpu_to_le16(active_dwell); - scan_ch->passive_dwell = cpu_to_le16(passive_dwell); - /* Set txpower levels to defaults */ - scan_ch->tpc.dsp_atten = 110; - if (band == IEEE80211_BAND_5GHZ) - scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; - else - scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); - added++; - } else - IWL_ERR(priv, "no valid channel found\n"); - return added; -} - -static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, - enum ieee80211_band band, - u8 is_active, u8 n_probes, - struct iwl3945_scan_channel *scan_ch, - struct ieee80211_vif *vif) -{ - struct ieee80211_channel *chan; - const struct ieee80211_supported_band *sband; - const struct iwl_channel_info *ch_info; - u16 passive_dwell = 0; - u16 active_dwell = 0; - int added, i; - - sband = iwl_get_hw_mode(priv, band); - if (!sband) - return 0; - - active_dwell = iwl_get_active_dwell_time(priv, band, n_probes); - passive_dwell = iwl_get_passive_dwell_time(priv, band, vif); - - if (passive_dwell <= active_dwell) - passive_dwell = active_dwell + 1; - - for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) { - chan = priv->scan_request->channels[i]; - - if (chan->band != band) - continue; - - scan_ch->channel = chan->hw_value; - - ch_info = iwl_get_channel_info(priv, band, scan_ch->channel); - if (!is_channel_valid(ch_info)) { - IWL_DEBUG_SCAN(priv, "Channel %d is INVALID for this band.\n", - scan_ch->channel); - continue; - } - - scan_ch->active_dwell = cpu_to_le16(active_dwell); - scan_ch->passive_dwell = cpu_to_le16(passive_dwell); - /* If passive , set up for auto-switch - * and use long active_dwell time. - */ - if (!is_active || is_channel_passive(ch_info) || - (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) { - scan_ch->type = 0; /* passive */ - if (IWL_UCODE_API(priv->ucode_ver) == 1) - scan_ch->active_dwell = cpu_to_le16(passive_dwell - 1); - } else { - scan_ch->type = 1; /* active */ - } - - /* Set direct probe bits. These may be used both for active - * scan channels (probes gets sent right away), - * or for passive channels (probes get se sent only after - * hearing clear Rx packet).*/ - if (IWL_UCODE_API(priv->ucode_ver) >= 2) { - if (n_probes) - scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes); - } else { - /* uCode v1 does not allow setting direct probe bits on - * passive channel. */ - if ((scan_ch->type & 1) && n_probes) - scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes); - } - - /* Set txpower levels to defaults */ - scan_ch->tpc.dsp_atten = 110; - /* scan_pwr_info->tpc.dsp_atten; */ - - /*scan_pwr_info->tpc.tx_gain; */ - if (band == IEEE80211_BAND_5GHZ) - scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; - else { - scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); - /* NOTE: if we were doing 6Mb OFDM for scans we'd use - * power level: - * scan_ch->tpc.tx_gain = ((1 << 5) | (2 << 3)) | 3; - */ - } - - IWL_DEBUG_SCAN(priv, "Scanning %d [%s %d]\n", - scan_ch->channel, - (scan_ch->type & 1) ? "ACTIVE" : "PASSIVE", - (scan_ch->type & 1) ? - active_dwell : passive_dwell); - - scan_ch++; - added++; - } - - IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added); - return added; -} - -static void iwl3945_init_hw_rates(struct iwl_priv *priv, - struct ieee80211_rate *rates) -{ - int i; - - for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) { - rates[i].bitrate = iwl3945_rates[i].ieee * 5; - rates[i].hw_value = i; /* Rate scaling will work on indexes */ - rates[i].hw_value_short = i; - rates[i].flags = 0; - if ((i > IWL39_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) { - /* - * If CCK != 1M then set short preamble rate flag. - */ - rates[i].flags |= (iwl3945_rates[i].plcp == 10) ? - 0 : IEEE80211_RATE_SHORT_PREAMBLE; - } - } -} - -/****************************************************************************** - * - * uCode download functions - * - ******************************************************************************/ - -static void iwl3945_dealloc_ucode_pci(struct iwl_priv *priv) -{ - iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code); - iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data); - iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data_backup); - iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init); - iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init_data); - iwl_free_fw_desc(priv->pci_dev, &priv->ucode_boot); -} - -/** - * iwl3945_verify_inst_full - verify runtime uCode image in card vs. host, - * looking at all data. - */ -static int iwl3945_verify_inst_full(struct iwl_priv *priv, __le32 *image, u32 len) -{ - u32 val; - u32 save_len = len; - int rc = 0; - u32 errcnt; - - IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); - - iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, - IWL39_RTC_INST_LOWER_BOUND); - - errcnt = 0; - for (; len > 0; len -= sizeof(u32), image++) { - /* read data comes through single port, auto-incr addr */ - /* NOTE: Use the debugless read so we don't flood kernel log - * if IWL_DL_IO is set */ - val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); - if (val != le32_to_cpu(*image)) { - IWL_ERR(priv, "uCode INST section is invalid at " - "offset 0x%x, is 0x%x, s/b 0x%x\n", - save_len - len, val, le32_to_cpu(*image)); - rc = -EIO; - errcnt++; - if (errcnt >= 20) - break; - } - } - - - if (!errcnt) - IWL_DEBUG_INFO(priv, - "ucode image in INSTRUCTION memory is good\n"); - - return rc; -} - - -/** - * iwl3945_verify_inst_sparse - verify runtime uCode image in card vs. host, - * using sample data 100 bytes apart. If these sample points are good, - * it's a pretty good bet that everything between them is good, too. - */ -static int iwl3945_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) -{ - u32 val; - int rc = 0; - u32 errcnt = 0; - u32 i; - - IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len); - - for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { - /* read data comes through single port, auto-incr addr */ - /* NOTE: Use the debugless read so we don't flood kernel log - * if IWL_DL_IO is set */ - iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, - i + IWL39_RTC_INST_LOWER_BOUND); - val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); - if (val != le32_to_cpu(*image)) { -#if 0 /* Enable this if you want to see details */ - IWL_ERR(priv, "uCode INST section is invalid at " - "offset 0x%x, is 0x%x, s/b 0x%x\n", - i, val, *image); -#endif - rc = -EIO; - errcnt++; - if (errcnt >= 3) - break; - } - } - - return rc; -} - - -/** - * iwl3945_verify_ucode - determine which instruction image is in SRAM, - * and verify its contents - */ -static int iwl3945_verify_ucode(struct iwl_priv *priv) -{ - __le32 *image; - u32 len; - int rc = 0; - - /* Try bootstrap */ - image = (__le32 *)priv->ucode_boot.v_addr; - len = priv->ucode_boot.len; - rc = iwl3945_verify_inst_sparse(priv, image, len); - if (rc == 0) { - IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n"); - return 0; - } - - /* Try initialize */ - image = (__le32 *)priv->ucode_init.v_addr; - len = priv->ucode_init.len; - rc = iwl3945_verify_inst_sparse(priv, image, len); - if (rc == 0) { - IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n"); - return 0; - } - - /* Try runtime/protocol */ - image = (__le32 *)priv->ucode_code.v_addr; - len = priv->ucode_code.len; - rc = iwl3945_verify_inst_sparse(priv, image, len); - if (rc == 0) { - IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n"); - return 0; - } - - IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n"); - - /* Since nothing seems to match, show first several data entries in - * instruction SRAM, so maybe visual inspection will give a clue. - * Selection of bootstrap image (vs. other images) is arbitrary. */ - image = (__le32 *)priv->ucode_boot.v_addr; - len = priv->ucode_boot.len; - rc = iwl3945_verify_inst_full(priv, image, len); - - return rc; -} - -static void iwl3945_nic_start(struct iwl_priv *priv) -{ - /* Remove all resets to allow NIC to operate */ - iwl_write32(priv, CSR_RESET, 0); -} - -#define IWL3945_UCODE_GET(item) \ -static u32 iwl3945_ucode_get_##item(const struct iwl_ucode_header *ucode)\ -{ \ - return le32_to_cpu(ucode->u.v1.item); \ -} - -static u32 iwl3945_ucode_get_header_size(u32 api_ver) -{ - return 24; -} - -static u8 *iwl3945_ucode_get_data(const struct iwl_ucode_header *ucode) -{ - return (u8 *) ucode->u.v1.data; -} - -IWL3945_UCODE_GET(inst_size); -IWL3945_UCODE_GET(data_size); -IWL3945_UCODE_GET(init_size); -IWL3945_UCODE_GET(init_data_size); -IWL3945_UCODE_GET(boot_size); - -/** - * iwl3945_read_ucode - Read uCode images from disk file. - * - * Copy into buffers for card to fetch via bus-mastering - */ -static int iwl3945_read_ucode(struct iwl_priv *priv) -{ - const struct iwl_ucode_header *ucode; - int ret = -EINVAL, index; - const struct firmware *ucode_raw; - /* firmware file name contains uCode/driver compatibility version */ - const char *name_pre = priv->cfg->fw_name_pre; - const unsigned int api_max = priv->cfg->ucode_api_max; - const unsigned int api_min = priv->cfg->ucode_api_min; - char buf[25]; - u8 *src; - size_t len; - u32 api_ver, inst_size, data_size, init_size, init_data_size, boot_size; - - /* Ask kernel firmware_class module to get the boot firmware off disk. - * request_firmware() is synchronous, file is in memory on return. */ - for (index = api_max; index >= api_min; index--) { - sprintf(buf, "%s%u%s", name_pre, index, ".ucode"); - ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev); - if (ret < 0) { - IWL_ERR(priv, "%s firmware file req failed: %d\n", - buf, ret); - if (ret == -ENOENT) - continue; - else - goto error; - } else { - if (index < api_max) - IWL_ERR(priv, "Loaded firmware %s, " - "which is deprecated. " - " Please use API v%u instead.\n", - buf, api_max); - IWL_DEBUG_INFO(priv, "Got firmware '%s' file " - "(%zd bytes) from disk\n", - buf, ucode_raw->size); - break; - } - } - - if (ret < 0) - goto error; - - /* Make sure that we got at least our header! */ - if (ucode_raw->size < iwl3945_ucode_get_header_size(1)) { - IWL_ERR(priv, "File size way too small!\n"); - ret = -EINVAL; - goto err_release; - } - - /* Data from ucode file: header followed by uCode images */ - ucode = (struct iwl_ucode_header *)ucode_raw->data; - - priv->ucode_ver = le32_to_cpu(ucode->ver); - api_ver = IWL_UCODE_API(priv->ucode_ver); - inst_size = iwl3945_ucode_get_inst_size(ucode); - data_size = iwl3945_ucode_get_data_size(ucode); - init_size = iwl3945_ucode_get_init_size(ucode); - init_data_size = iwl3945_ucode_get_init_data_size(ucode); - boot_size = iwl3945_ucode_get_boot_size(ucode); - src = iwl3945_ucode_get_data(ucode); - - /* api_ver should match the api version forming part of the - * firmware filename ... but we don't check for that and only rely - * on the API version read from firmware header from here on forward */ - - if (api_ver < api_min || api_ver > api_max) { - IWL_ERR(priv, "Driver unable to support your firmware API. " - "Driver supports v%u, firmware is v%u.\n", - api_max, api_ver); - priv->ucode_ver = 0; - ret = -EINVAL; - goto err_release; - } - if (api_ver != api_max) - IWL_ERR(priv, "Firmware has old API version. Expected %u, " - "got %u. New firmware can be obtained " - "from http://www.intellinuxwireless.org.\n", - api_max, api_ver); - - IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u\n", - IWL_UCODE_MAJOR(priv->ucode_ver), - IWL_UCODE_MINOR(priv->ucode_ver), - IWL_UCODE_API(priv->ucode_ver), - IWL_UCODE_SERIAL(priv->ucode_ver)); - - snprintf(priv->hw->wiphy->fw_version, - sizeof(priv->hw->wiphy->fw_version), - "%u.%u.%u.%u", - IWL_UCODE_MAJOR(priv->ucode_ver), - IWL_UCODE_MINOR(priv->ucode_ver), - IWL_UCODE_API(priv->ucode_ver), - IWL_UCODE_SERIAL(priv->ucode_ver)); - - IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n", - priv->ucode_ver); - IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n", - inst_size); - IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %u\n", - data_size); - IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %u\n", - init_size); - IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %u\n", - init_data_size); - IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n", - boot_size); - - - /* Verify size of file vs. image size info in file's header */ - if (ucode_raw->size != iwl3945_ucode_get_header_size(api_ver) + - inst_size + data_size + init_size + - init_data_size + boot_size) { - - IWL_DEBUG_INFO(priv, - "uCode file size %zd does not match expected size\n", - ucode_raw->size); - ret = -EINVAL; - goto err_release; - } - - /* Verify that uCode images will fit in card's SRAM */ - if (inst_size > IWL39_MAX_INST_SIZE) { - IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n", - inst_size); - ret = -EINVAL; - goto err_release; - } - - if (data_size > IWL39_MAX_DATA_SIZE) { - IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n", - data_size); - ret = -EINVAL; - goto err_release; - } - if (init_size > IWL39_MAX_INST_SIZE) { - IWL_DEBUG_INFO(priv, - "uCode init instr len %d too large to fit in\n", - init_size); - ret = -EINVAL; - goto err_release; - } - if (init_data_size > IWL39_MAX_DATA_SIZE) { - IWL_DEBUG_INFO(priv, - "uCode init data len %d too large to fit in\n", - init_data_size); - ret = -EINVAL; - goto err_release; - } - if (boot_size > IWL39_MAX_BSM_SIZE) { - IWL_DEBUG_INFO(priv, - "uCode boot instr len %d too large to fit in\n", - boot_size); - ret = -EINVAL; - goto err_release; - } - - /* Allocate ucode buffers for card's bus-master loading ... */ - - /* Runtime instructions and 2 copies of data: - * 1) unmodified from disk - * 2) backup cache for save/restore during power-downs */ - priv->ucode_code.len = inst_size; - iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_code); - - priv->ucode_data.len = data_size; - iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data); - - priv->ucode_data_backup.len = data_size; - iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup); - - if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr || - !priv->ucode_data_backup.v_addr) - goto err_pci_alloc; - - /* Initialization instructions and data */ - if (init_size && init_data_size) { - priv->ucode_init.len = init_size; - iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init); - - priv->ucode_init_data.len = init_data_size; - iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data); - - if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr) - goto err_pci_alloc; - } - - /* Bootstrap (instructions only, no data) */ - if (boot_size) { - priv->ucode_boot.len = boot_size; - iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot); - - if (!priv->ucode_boot.v_addr) - goto err_pci_alloc; - } - - /* Copy images into buffers for card's bus-master reads ... */ - - /* Runtime instructions (first block of data in file) */ - len = inst_size; - IWL_DEBUG_INFO(priv, - "Copying (but not loading) uCode instr len %zd\n", len); - memcpy(priv->ucode_code.v_addr, src, len); - src += len; - - IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n", - priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr); - - /* Runtime data (2nd block) - * NOTE: Copy into backup buffer will be done in iwl3945_up() */ - len = data_size; - IWL_DEBUG_INFO(priv, - "Copying (but not loading) uCode data len %zd\n", len); - memcpy(priv->ucode_data.v_addr, src, len); - memcpy(priv->ucode_data_backup.v_addr, src, len); - src += len; - - /* Initialization instructions (3rd block) */ - if (init_size) { - len = init_size; - IWL_DEBUG_INFO(priv, - "Copying (but not loading) init instr len %zd\n", len); - memcpy(priv->ucode_init.v_addr, src, len); - src += len; - } - - /* Initialization data (4th block) */ - if (init_data_size) { - len = init_data_size; - IWL_DEBUG_INFO(priv, - "Copying (but not loading) init data len %zd\n", len); - memcpy(priv->ucode_init_data.v_addr, src, len); - src += len; - } - - /* Bootstrap instructions (5th block) */ - len = boot_size; - IWL_DEBUG_INFO(priv, - "Copying (but not loading) boot instr len %zd\n", len); - memcpy(priv->ucode_boot.v_addr, src, len); - - /* We have our copies now, allow OS release its copies */ - release_firmware(ucode_raw); - return 0; - - err_pci_alloc: - IWL_ERR(priv, "failed to allocate pci memory\n"); - ret = -ENOMEM; - iwl3945_dealloc_ucode_pci(priv); - - err_release: - release_firmware(ucode_raw); - - error: - return ret; -} - - -/** - * iwl3945_set_ucode_ptrs - Set uCode address location - * - * Tell initialization uCode where to find runtime uCode. - * - * BSM registers initially contain pointers to initialization uCode. - * We need to replace them to load runtime uCode inst and data, - * and to save runtime data when powering down. - */ -static int iwl3945_set_ucode_ptrs(struct iwl_priv *priv) -{ - dma_addr_t pinst; - dma_addr_t pdata; - - /* bits 31:0 for 3945 */ - pinst = priv->ucode_code.p_addr; - pdata = priv->ucode_data_backup.p_addr; - - /* Tell bootstrap uCode where to find image to load */ - iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); - iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); - iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, - priv->ucode_data.len); - - /* Inst byte count must be last to set up, bit 31 signals uCode - * that all new ptr/size info is in place */ - iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, - priv->ucode_code.len | BSM_DRAM_INST_LOAD); - - IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n"); - - return 0; -} - -/** - * iwl3945_init_alive_start - Called after REPLY_ALIVE notification received - * - * Called after REPLY_ALIVE notification received from "initialize" uCode. - * - * Tell "initialize" uCode to go ahead and load the runtime uCode. - */ -static void iwl3945_init_alive_start(struct iwl_priv *priv) -{ - /* Check alive response for "valid" sign from uCode */ - if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { - /* We had an error bringing up the hardware, so take it - * all the way back down so we can try again */ - IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n"); - goto restart; - } - - /* Bootstrap uCode has loaded initialize uCode ... verify inst image. - * This is a paranoid check, because we would not have gotten the - * "initialize" alive if code weren't properly loaded. */ - if (iwl3945_verify_ucode(priv)) { - /* Runtime instruction load was bad; - * take it all the way back down so we can try again */ - IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n"); - goto restart; - } - - /* Send pointers to protocol/runtime uCode image ... init code will - * load and launch runtime uCode, which will send us another "Alive" - * notification. */ - IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); - if (iwl3945_set_ucode_ptrs(priv)) { - /* Runtime instruction load won't happen; - * take it all the way back down so we can try again */ - IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n"); - goto restart; - } - return; - - restart: - queue_work(priv->workqueue, &priv->restart); -} - -/** - * iwl3945_alive_start - called after REPLY_ALIVE notification received - * from protocol/runtime uCode (initialization uCode's - * Alive gets handled by iwl3945_init_alive_start()). - */ -static void iwl3945_alive_start(struct iwl_priv *priv) -{ - int thermal_spin = 0; - u32 rfkill; - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); - - if (priv->card_alive.is_valid != UCODE_VALID_OK) { - /* We had an error bringing up the hardware, so take it - * all the way back down so we can try again */ - IWL_DEBUG_INFO(priv, "Alive failed.\n"); - goto restart; - } - - /* Initialize uCode has loaded Runtime uCode ... verify inst image. - * This is a paranoid check, because we would not have gotten the - * "runtime" alive if code weren't properly loaded. */ - if (iwl3945_verify_ucode(priv)) { - /* Runtime instruction load was bad; - * take it all the way back down so we can try again */ - IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n"); - goto restart; - } - - rfkill = iwl_read_prph(priv, APMG_RFKILL_REG); - IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill); - - if (rfkill & 0x1) { - clear_bit(STATUS_RF_KILL_HW, &priv->status); - /* if RFKILL is not on, then wait for thermal - * sensor in adapter to kick in */ - while (iwl3945_hw_get_temperature(priv) == 0) { - thermal_spin++; - udelay(10); - } - - if (thermal_spin) - IWL_DEBUG_INFO(priv, "Thermal calibration took %dus\n", - thermal_spin * 10); - } else - set_bit(STATUS_RF_KILL_HW, &priv->status); - - /* After the ALIVE response, we can send commands to 3945 uCode */ - set_bit(STATUS_ALIVE, &priv->status); - - /* Enable watchdog to monitor the driver tx queues */ - iwl_setup_watchdog(priv); - - if (iwl_is_rfkill(priv)) - return; - - ieee80211_wake_queues(priv->hw); - - priv->active_rate = IWL_RATES_MASK_3945; - - iwl_power_update_mode(priv, true); - - if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { - struct iwl3945_rxon_cmd *active_rxon = - (struct iwl3945_rxon_cmd *)(&ctx->active); - - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - } else { - /* Initialize our rx_config data */ - iwl_connection_init_rx_config(priv, ctx); - } - - /* Configure Bluetooth device coexistence support */ - priv->cfg->ops->hcmd->send_bt_config(priv); - - set_bit(STATUS_READY, &priv->status); - - /* Configure the adapter for unassociated operation */ - iwl3945_commit_rxon(priv, ctx); - - iwl3945_reg_txpower_periodic(priv); - - IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); - wake_up_interruptible(&priv->wait_command_queue); - - return; - - restart: - queue_work(priv->workqueue, &priv->restart); -} - -static void iwl3945_cancel_deferred_work(struct iwl_priv *priv); - -static void __iwl3945_down(struct iwl_priv *priv) -{ - unsigned long flags; - int exit_pending; - - IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); - - iwl_scan_cancel_timeout(priv, 200); - - exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); - - /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set - * to prevent rearm timer */ - del_timer_sync(&priv->watchdog); - - /* Station information will now be cleared in device */ - iwl_clear_ucode_stations(priv, NULL); - iwl_dealloc_bcast_stations(priv); - iwl_clear_driver_stations(priv); - - /* Unblock any waiting calls */ - wake_up_interruptible_all(&priv->wait_command_queue); - - /* Wipe out the EXIT_PENDING status bit if we are not actually - * exiting the module */ - if (!exit_pending) - clear_bit(STATUS_EXIT_PENDING, &priv->status); - - /* stop and reset the on-board processor */ - iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); - - /* tell the device to stop sending interrupts */ - spin_lock_irqsave(&priv->lock, flags); - iwl_disable_interrupts(priv); - spin_unlock_irqrestore(&priv->lock, flags); - iwl_synchronize_irq(priv); - - if (priv->mac80211_registered) - ieee80211_stop_queues(priv->hw); - - /* If we have not previously called iwl3945_init() then - * clear all bits but the RF Kill bits and return */ - if (!iwl_is_init(priv)) { - priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << - STATUS_RF_KILL_HW | - test_bit(STATUS_GEO_CONFIGURED, &priv->status) << - STATUS_GEO_CONFIGURED | - test_bit(STATUS_EXIT_PENDING, &priv->status) << - STATUS_EXIT_PENDING; - goto exit; - } - - /* ...otherwise clear out all the status bits but the RF Kill - * bit and continue taking the NIC down. */ - priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << - STATUS_RF_KILL_HW | - test_bit(STATUS_GEO_CONFIGURED, &priv->status) << - STATUS_GEO_CONFIGURED | - test_bit(STATUS_FW_ERROR, &priv->status) << - STATUS_FW_ERROR | - test_bit(STATUS_EXIT_PENDING, &priv->status) << - STATUS_EXIT_PENDING; - - iwl3945_hw_txq_ctx_stop(priv); - iwl3945_hw_rxq_stop(priv); - - /* Power-down device's busmaster DMA clocks */ - iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); - udelay(5); - - /* Stop the device, and put it in low power state */ - iwl_apm_stop(priv); - - exit: - memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); - - if (priv->beacon_skb) - dev_kfree_skb(priv->beacon_skb); - priv->beacon_skb = NULL; - - /* clear out any free frames */ - iwl3945_clear_free_frames(priv); -} - -static void iwl3945_down(struct iwl_priv *priv) -{ - mutex_lock(&priv->mutex); - __iwl3945_down(priv); - mutex_unlock(&priv->mutex); - - iwl3945_cancel_deferred_work(priv); -} - -#define MAX_HW_RESTARTS 5 - -static int iwl3945_alloc_bcast_station(struct iwl_priv *priv) -{ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - unsigned long flags; - u8 sta_id; - - spin_lock_irqsave(&priv->sta_lock, flags); - sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL); - if (sta_id == IWL_INVALID_STATION) { - IWL_ERR(priv, "Unable to prepare broadcast station\n"); - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return -EINVAL; - } - - priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; - priv->stations[sta_id].used |= IWL_STA_BCAST; - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return 0; -} - -static int __iwl3945_up(struct iwl_priv *priv) -{ - int rc, i; - - rc = iwl3945_alloc_bcast_station(priv); - if (rc) - return rc; - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { - IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); - return -EIO; - } - - if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { - IWL_ERR(priv, "ucode not available for device bring up\n"); - return -EIO; - } - - /* If platform's RF_KILL switch is NOT set to KILL */ - if (iwl_read32(priv, CSR_GP_CNTRL) & - CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) - clear_bit(STATUS_RF_KILL_HW, &priv->status); - else { - set_bit(STATUS_RF_KILL_HW, &priv->status); - IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n"); - return -ENODEV; - } - - iwl_write32(priv, CSR_INT, 0xFFFFFFFF); - - rc = iwl3945_hw_nic_init(priv); - if (rc) { - IWL_ERR(priv, "Unable to int nic\n"); - return rc; - } - - /* make sure rfkill handshake bits are cleared */ - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, - CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); - - /* clear (again), then enable host interrupts */ - iwl_write32(priv, CSR_INT, 0xFFFFFFFF); - iwl_enable_interrupts(priv); - - /* really make sure rfkill handshake bits are cleared */ - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - - /* Copy original ucode data image from disk into backup cache. - * This will be used to initialize the on-board processor's - * data SRAM for a clean start when the runtime program first loads. */ - memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr, - priv->ucode_data.len); - - /* We return success when we resume from suspend and rf_kill is on. */ - if (test_bit(STATUS_RF_KILL_HW, &priv->status)) - return 0; - - for (i = 0; i < MAX_HW_RESTARTS; i++) { - - /* load bootstrap state machine, - * load bootstrap program into processor's memory, - * prepare to load the "initialize" uCode */ - rc = priv->cfg->ops->lib->load_ucode(priv); - - if (rc) { - IWL_ERR(priv, - "Unable to set up bootstrap uCode: %d\n", rc); - continue; - } - - /* start card; "initialize" will load runtime ucode */ - iwl3945_nic_start(priv); - - IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n"); - - return 0; - } - - set_bit(STATUS_EXIT_PENDING, &priv->status); - __iwl3945_down(priv); - clear_bit(STATUS_EXIT_PENDING, &priv->status); - - /* tried to restart and config the device for as long as our - * patience could withstand */ - IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i); - return -EIO; -} - - -/***************************************************************************** - * - * Workqueue callbacks - * - *****************************************************************************/ - -static void iwl3945_bg_init_alive_start(struct work_struct *data) -{ - struct iwl_priv *priv = - container_of(data, struct iwl_priv, init_alive_start.work); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - mutex_lock(&priv->mutex); - iwl3945_init_alive_start(priv); - mutex_unlock(&priv->mutex); -} - -static void iwl3945_bg_alive_start(struct work_struct *data) -{ - struct iwl_priv *priv = - container_of(data, struct iwl_priv, alive_start.work); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - mutex_lock(&priv->mutex); - iwl3945_alive_start(priv); - mutex_unlock(&priv->mutex); -} - -/* - * 3945 cannot interrupt driver when hardware rf kill switch toggles; - * driver must poll CSR_GP_CNTRL_REG register for change. This register - * *is* readable even when device has been SW_RESET into low power mode - * (e.g. during RF KILL). - */ -static void iwl3945_rfkill_poll(struct work_struct *data) -{ - struct iwl_priv *priv = - container_of(data, struct iwl_priv, _3945.rfkill_poll.work); - bool old_rfkill = test_bit(STATUS_RF_KILL_HW, &priv->status); - bool new_rfkill = !(iwl_read32(priv, CSR_GP_CNTRL) - & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); - - if (new_rfkill != old_rfkill) { - if (new_rfkill) - set_bit(STATUS_RF_KILL_HW, &priv->status); - else - clear_bit(STATUS_RF_KILL_HW, &priv->status); - - wiphy_rfkill_set_hw_state(priv->hw->wiphy, new_rfkill); - - IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n", - new_rfkill ? "disable radio" : "enable radio"); - } - - /* Keep this running, even if radio now enabled. This will be - * cancelled in mac_start() if system decides to start again */ - queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll, - round_jiffies_relative(2 * HZ)); - -} - -int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) -{ - struct iwl_host_cmd cmd = { - .id = REPLY_SCAN_CMD, - .len = sizeof(struct iwl3945_scan_cmd), - .flags = CMD_SIZE_HUGE, - }; - struct iwl3945_scan_cmd *scan; - u8 n_probes = 0; - enum ieee80211_band band; - bool is_active = false; - int ret; - - lockdep_assert_held(&priv->mutex); - - if (!priv->scan_cmd) { - priv->scan_cmd = kmalloc(sizeof(struct iwl3945_scan_cmd) + - IWL_MAX_SCAN_SIZE, GFP_KERNEL); - if (!priv->scan_cmd) { - IWL_DEBUG_SCAN(priv, "Fail to allocate scan memory\n"); - return -ENOMEM; - } - } - scan = priv->scan_cmd; - memset(scan, 0, sizeof(struct iwl3945_scan_cmd) + IWL_MAX_SCAN_SIZE); - - scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; - scan->quiet_time = IWL_ACTIVE_QUIET_TIME; - - if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { - u16 interval = 0; - u32 extra; - u32 suspend_time = 100; - u32 scan_suspend_time = 100; - - IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); - - if (priv->is_internal_short_scan) - interval = 0; - else - interval = vif->bss_conf.beacon_int; - - scan->suspend_time = 0; - scan->max_out_time = cpu_to_le32(200 * 1024); - if (!interval) - interval = suspend_time; - /* - * suspend time format: - * 0-19: beacon interval in usec (time before exec.) - * 20-23: 0 - * 24-31: number of beacons (suspend between channels) - */ - - extra = (suspend_time / interval) << 24; - scan_suspend_time = 0xFF0FFFFF & - (extra | ((suspend_time % interval) * 1024)); - - scan->suspend_time = cpu_to_le32(scan_suspend_time); - IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n", - scan_suspend_time, interval); - } - - if (priv->is_internal_short_scan) { - IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); - } else if (priv->scan_request->n_ssids) { - int i, p = 0; - IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); - for (i = 0; i < priv->scan_request->n_ssids; i++) { - /* always does wildcard anyway */ - if (!priv->scan_request->ssids[i].ssid_len) - continue; - scan->direct_scan[p].id = WLAN_EID_SSID; - scan->direct_scan[p].len = - priv->scan_request->ssids[i].ssid_len; - memcpy(scan->direct_scan[p].ssid, - priv->scan_request->ssids[i].ssid, - priv->scan_request->ssids[i].ssid_len); - n_probes++; - p++; - } - is_active = true; - } else - IWL_DEBUG_SCAN(priv, "Kicking off passive scan.\n"); - - /* We don't build a direct scan probe request; the uCode will do - * that based on the direct_mask added to each channel entry */ - scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; - scan->tx_cmd.sta_id = priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; - scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; - - /* flags + rate selection */ - - switch (priv->scan_band) { - case IEEE80211_BAND_2GHZ: - scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; - scan->tx_cmd.rate = IWL_RATE_1M_PLCP; - band = IEEE80211_BAND_2GHZ; - break; - case IEEE80211_BAND_5GHZ: - scan->tx_cmd.rate = IWL_RATE_6M_PLCP; - band = IEEE80211_BAND_5GHZ; - break; - default: - IWL_WARN(priv, "Invalid scan band\n"); - return -EIO; - } - - /* - * If active scaning is requested but a certain channel - * is marked passive, we can do active scanning if we - * detect transmissions. - */ - scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : - IWL_GOOD_CRC_TH_DISABLED; - - if (!priv->is_internal_short_scan) { - scan->tx_cmd.len = cpu_to_le16( - iwl_fill_probe_req(priv, - (struct ieee80211_mgmt *)scan->data, - vif->addr, - priv->scan_request->ie, - priv->scan_request->ie_len, - IWL_MAX_SCAN_SIZE - sizeof(*scan))); - } else { - /* use bcast addr, will not be transmitted but must be valid */ - scan->tx_cmd.len = cpu_to_le16( - iwl_fill_probe_req(priv, - (struct ieee80211_mgmt *)scan->data, - iwl_bcast_addr, NULL, 0, - IWL_MAX_SCAN_SIZE - sizeof(*scan))); - } - /* select Rx antennas */ - scan->flags |= iwl3945_get_antenna_flags(priv); - - if (priv->is_internal_short_scan) { - scan->channel_count = - iwl3945_get_single_channel_for_scan(priv, vif, band, - (void *)&scan->data[le16_to_cpu( - scan->tx_cmd.len)]); - } else { - scan->channel_count = - iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, - (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif); - } - - if (scan->channel_count == 0) { - IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); - return -EIO; - } - - cmd.len += le16_to_cpu(scan->tx_cmd.len) + - scan->channel_count * sizeof(struct iwl3945_scan_channel); - cmd.data = scan; - scan->len = cpu_to_le16(cmd.len); - - set_bit(STATUS_SCAN_HW, &priv->status); - ret = iwl_send_cmd_sync(priv, &cmd); - if (ret) - clear_bit(STATUS_SCAN_HW, &priv->status); - return ret; -} - -void iwl3945_post_scan(struct iwl_priv *priv) -{ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - /* - * Since setting the RXON may have been deferred while - * performing the scan, fire one off if needed - */ - if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) - iwl3945_commit_rxon(priv, ctx); -} - -static void iwl3945_bg_restart(struct work_struct *data) -{ - struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { - struct iwl_rxon_context *ctx; - mutex_lock(&priv->mutex); - for_each_context(priv, ctx) - ctx->vif = NULL; - priv->is_open = 0; - mutex_unlock(&priv->mutex); - iwl3945_down(priv); - ieee80211_restart_hw(priv->hw); - } else { - iwl3945_down(priv); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - mutex_lock(&priv->mutex); - __iwl3945_up(priv); - mutex_unlock(&priv->mutex); - } -} - -static void iwl3945_bg_rx_replenish(struct work_struct *data) -{ - struct iwl_priv *priv = - container_of(data, struct iwl_priv, rx_replenish); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - mutex_lock(&priv->mutex); - iwl3945_rx_replenish(priv); - mutex_unlock(&priv->mutex); -} - -void iwl3945_post_associate(struct iwl_priv *priv) -{ - int rc = 0; - struct ieee80211_conf *conf = NULL; - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - if (!ctx->vif || !priv->is_open) - return; - - if (ctx->vif->type == NL80211_IFTYPE_AP) { - IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); - return; - } - - IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", - ctx->vif->bss_conf.aid, ctx->active.bssid_addr); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - iwl_scan_cancel_timeout(priv, 200); - - conf = ieee80211_get_hw_conf(priv->hw); - - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl3945_commit_rxon(priv, ctx); - - rc = iwl_send_rxon_timing(priv, ctx); - if (rc) - IWL_WARN(priv, "REPLY_RXON_TIMING failed - " - "Attempting to continue.\n"); - - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - - ctx->staging.assoc_id = cpu_to_le16(ctx->vif->bss_conf.aid); - - IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", - ctx->vif->bss_conf.aid, ctx->vif->bss_conf.beacon_int); - - if (ctx->vif->bss_conf.use_short_preamble) - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; - else - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { - if (ctx->vif->bss_conf.use_short_slot) - ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; - else - ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; - } - - iwl3945_commit_rxon(priv, ctx); - - switch (ctx->vif->type) { - case NL80211_IFTYPE_STATION: - iwl3945_rate_scale_init(priv->hw, IWL_AP_ID); - break; - case NL80211_IFTYPE_ADHOC: - iwl3945_send_beacon_cmd(priv); - break; - default: - IWL_ERR(priv, "%s Should not be called in %d mode\n", - __func__, ctx->vif->type); - break; - } -} - -/***************************************************************************** - * - * mac80211 entry point functions - * - *****************************************************************************/ - -#define UCODE_READY_TIMEOUT (2 * HZ) - -static int iwl3945_mac_start(struct ieee80211_hw *hw) -{ - struct iwl_priv *priv = hw->priv; - int ret; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - /* we should be verifying the device is ready to be opened */ - mutex_lock(&priv->mutex); - - /* fetch ucode file from disk, alloc and copy to bus-master buffers ... - * ucode filename and max sizes are card-specific. */ - - if (!priv->ucode_code.len) { - ret = iwl3945_read_ucode(priv); - if (ret) { - IWL_ERR(priv, "Could not read microcode: %d\n", ret); - mutex_unlock(&priv->mutex); - goto out_release_irq; - } - } - - ret = __iwl3945_up(priv); - - mutex_unlock(&priv->mutex); - - if (ret) - goto out_release_irq; - - IWL_DEBUG_INFO(priv, "Start UP work.\n"); - - /* Wait for START_ALIVE from ucode. Otherwise callbacks from - * mac80211 will not be run successfully. */ - ret = wait_event_interruptible_timeout(priv->wait_command_queue, - test_bit(STATUS_READY, &priv->status), - UCODE_READY_TIMEOUT); - if (!ret) { - if (!test_bit(STATUS_READY, &priv->status)) { - IWL_ERR(priv, - "Wait for START_ALIVE timeout after %dms.\n", - jiffies_to_msecs(UCODE_READY_TIMEOUT)); - ret = -ETIMEDOUT; - goto out_release_irq; - } - } - - /* ucode is running and will send rfkill notifications, - * no need to poll the killswitch state anymore */ - cancel_delayed_work(&priv->_3945.rfkill_poll); - - priv->is_open = 1; - IWL_DEBUG_MAC80211(priv, "leave\n"); - return 0; - -out_release_irq: - priv->is_open = 0; - IWL_DEBUG_MAC80211(priv, "leave - failed\n"); - return ret; -} - -static void iwl3945_mac_stop(struct ieee80211_hw *hw) -{ - struct iwl_priv *priv = hw->priv; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - if (!priv->is_open) { - IWL_DEBUG_MAC80211(priv, "leave - skip\n"); - return; - } - - priv->is_open = 0; - - iwl3945_down(priv); - - flush_workqueue(priv->workqueue); - - /* start polling the killswitch state again */ - queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll, - round_jiffies_relative(2 * HZ)); - - IWL_DEBUG_MAC80211(priv, "leave\n"); -} - -static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct iwl_priv *priv = hw->priv; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, - ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); - - if (iwl3945_tx_skb(priv, skb)) - dev_kfree_skb_any(skb); - - IWL_DEBUG_MAC80211(priv, "leave\n"); - return NETDEV_TX_OK; -} - -void iwl3945_config_ap(struct iwl_priv *priv) -{ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - struct ieee80211_vif *vif = ctx->vif; - int rc = 0; - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - /* The following should be done only at AP bring up */ - if (!(iwl_is_associated(priv, IWL_RXON_CTX_BSS))) { - - /* RXON - unassoc (to set timing command) */ - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl3945_commit_rxon(priv, ctx); - - /* RXON Timing */ - rc = iwl_send_rxon_timing(priv, ctx); - if (rc) - IWL_WARN(priv, "REPLY_RXON_TIMING failed - " - "Attempting to continue.\n"); - - ctx->staging.assoc_id = 0; - - if (vif->bss_conf.use_short_preamble) - ctx->staging.flags |= - RXON_FLG_SHORT_PREAMBLE_MSK; - else - ctx->staging.flags &= - ~RXON_FLG_SHORT_PREAMBLE_MSK; - - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { - if (vif->bss_conf.use_short_slot) - ctx->staging.flags |= - RXON_FLG_SHORT_SLOT_MSK; - else - ctx->staging.flags &= - ~RXON_FLG_SHORT_SLOT_MSK; - } - /* restore RXON assoc */ - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - iwl3945_commit_rxon(priv, ctx); - } - iwl3945_send_beacon_cmd(priv); - - /* FIXME - we need to add code here to detect a totally new - * configuration, reset the AP, unassoc, rxon timing, assoc, - * clear sta table, add BCAST sta... */ -} - -static int iwl3945_mac_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 iwl_priv *priv = hw->priv; - int ret = 0; - u8 sta_id = IWL_INVALID_STATION; - u8 static_key; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - if (iwl3945_mod_params.sw_crypto) { - IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n"); - return -EOPNOTSUPP; - } - - /* - * To support IBSS RSN, don't program group keys in IBSS, the - * hardware will then not attempt to decrypt the frames. - */ - if (vif->type == NL80211_IFTYPE_ADHOC && - !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) - return -EOPNOTSUPP; - - static_key = !iwl_is_associated(priv, IWL_RXON_CTX_BSS); - - if (!static_key) { - sta_id = iwl_sta_id_or_broadcast( - priv, &priv->contexts[IWL_RXON_CTX_BSS], sta); - if (sta_id == IWL_INVALID_STATION) - return -EINVAL; - } - - mutex_lock(&priv->mutex); - iwl_scan_cancel_timeout(priv, 100); - - switch (cmd) { - case SET_KEY: - if (static_key) - ret = iwl3945_set_static_key(priv, key); - else - ret = iwl3945_set_dynamic_key(priv, key, sta_id); - IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n"); - break; - case DISABLE_KEY: - if (static_key) - ret = iwl3945_remove_static_key(priv); - else - ret = iwl3945_clear_sta_key_info(priv, sta_id); - IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n"); - break; - default: - ret = -EINVAL; - } - - mutex_unlock(&priv->mutex); - IWL_DEBUG_MAC80211(priv, "leave\n"); - - return ret; -} - -static int iwl3945_mac_sta_add(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - struct iwl_priv *priv = hw->priv; - struct iwl3945_sta_priv *sta_priv = (void *)sta->drv_priv; - int ret; - bool is_ap = vif->type == NL80211_IFTYPE_STATION; - u8 sta_id; - - IWL_DEBUG_INFO(priv, "received request to add station %pM\n", - sta->addr); - mutex_lock(&priv->mutex); - IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", - sta->addr); - sta_priv->common.sta_id = IWL_INVALID_STATION; - - - ret = iwl_add_station_common(priv, &priv->contexts[IWL_RXON_CTX_BSS], - sta->addr, is_ap, sta, &sta_id); - if (ret) { - IWL_ERR(priv, "Unable to add station %pM (%d)\n", - sta->addr, ret); - /* Should we return success if return code is EEXIST ? */ - mutex_unlock(&priv->mutex); - return ret; - } - - sta_priv->common.sta_id = sta_id; - - /* Initialize rate scaling */ - IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", - sta->addr); - iwl3945_rs_rate_init(priv, sta, sta_id); - mutex_unlock(&priv->mutex); - - return 0; -} - -static void iwl3945_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, - u64 multicast) -{ - struct iwl_priv *priv = hw->priv; - __le32 filter_or = 0, filter_nand = 0; - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - -#define CHK(test, flag) do { \ - if (*total_flags & (test)) \ - filter_or |= (flag); \ - else \ - filter_nand |= (flag); \ - } while (0) - - IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n", - changed_flags, *total_flags); - - CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); - CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK); - CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); - -#undef CHK - - mutex_lock(&priv->mutex); - - ctx->staging.filter_flags &= ~filter_nand; - ctx->staging.filter_flags |= filter_or; - - /* - * Not committing directly because hardware can perform a scan, - * but even if hw is ready, committing here breaks for some reason, - * we'll eventually commit the filter flags change anyway. - */ - - mutex_unlock(&priv->mutex); - - /* - * Receiving all multicast frames is always enabled by the - * default flags setup in iwl_connection_init_rx_config() - * since we currently do not support programming multicast - * filters into the device. - */ - *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | - FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; -} - - -/***************************************************************************** - * - * sysfs attributes - * - *****************************************************************************/ - -#ifdef CONFIG_IWLWIFI_DEBUG - -/* - * The following adds a new attribute to the sysfs representation - * of this device driver (i.e. a new file in /sys/bus/pci/drivers/iwl/) - * used for controlling the debug level. - * - * See the level definitions in iwl for details. - * - * The debug_level being managed using sysfs below is a per device debug - * level that is used instead of the global debug level if it (the per - * device debug level) is set. - */ -static ssize_t show_debug_level(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - return sprintf(buf, "0x%08X\n", iwl_get_debug_level(priv)); -} -static ssize_t store_debug_level(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - unsigned long val; - int ret; - - ret = strict_strtoul(buf, 0, &val); - if (ret) - IWL_INFO(priv, "%s is not in hex or decimal form.\n", buf); - else { - priv->debug_level = val; - if (iwl_alloc_traffic_mem(priv)) - IWL_ERR(priv, - "Not enough memory to generate traffic log\n"); - } - return strnlen(buf, count); -} - -static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, - show_debug_level, store_debug_level); - -#endif /* CONFIG_IWLWIFI_DEBUG */ - -static ssize_t show_temperature(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - - if (!iwl_is_alive(priv)) - return -EAGAIN; - - return sprintf(buf, "%d\n", iwl3945_hw_get_temperature(priv)); -} - -static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); - -static ssize_t show_tx_power(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - return sprintf(buf, "%d\n", priv->tx_power_user_lmt); -} - -static ssize_t store_tx_power(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - char *p = (char *)buf; - u32 val; - - val = simple_strtoul(p, &p, 10); - if (p == buf) - IWL_INFO(priv, ": %s is not in decimal form.\n", buf); - else - iwl3945_hw_reg_set_txpower(priv, val); - - return count; -} - -static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); - -static ssize_t show_flags(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - return sprintf(buf, "0x%04X\n", ctx->active.flags); -} - -static ssize_t store_flags(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - u32 flags = simple_strtoul(buf, NULL, 0); - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - mutex_lock(&priv->mutex); - if (le32_to_cpu(ctx->staging.flags) != flags) { - /* Cancel any currently running scans... */ - if (iwl_scan_cancel_timeout(priv, 100)) - IWL_WARN(priv, "Could not cancel scan.\n"); - else { - IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n", - flags); - ctx->staging.flags = cpu_to_le32(flags); - iwl3945_commit_rxon(priv, ctx); - } - } - mutex_unlock(&priv->mutex); - - return count; -} - -static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags); - -static ssize_t show_filter_flags(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - - return sprintf(buf, "0x%04X\n", - le32_to_cpu(ctx->active.filter_flags)); -} - -static ssize_t store_filter_flags(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - u32 filter_flags = simple_strtoul(buf, NULL, 0); - - mutex_lock(&priv->mutex); - if (le32_to_cpu(ctx->staging.filter_flags) != filter_flags) { - /* Cancel any currently running scans... */ - if (iwl_scan_cancel_timeout(priv, 100)) - IWL_WARN(priv, "Could not cancel scan.\n"); - else { - IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = " - "0x%04X\n", filter_flags); - ctx->staging.filter_flags = - cpu_to_le32(filter_flags); - iwl3945_commit_rxon(priv, ctx); - } - } - mutex_unlock(&priv->mutex); - - return count; -} - -static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, - store_filter_flags); - -static ssize_t show_measurement(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - struct iwl_spectrum_notification measure_report; - u32 size = sizeof(measure_report), len = 0, ofs = 0; - u8 *data = (u8 *)&measure_report; - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - if (!(priv->measurement_status & MEASUREMENT_READY)) { - spin_unlock_irqrestore(&priv->lock, flags); - return 0; - } - memcpy(&measure_report, &priv->measure_report, size); - priv->measurement_status = 0; - spin_unlock_irqrestore(&priv->lock, flags); - - while (size && (PAGE_SIZE - len)) { - hex_dump_to_buffer(data + ofs, size, 16, 1, buf + len, - PAGE_SIZE - len, 1); - len = strlen(buf); - if (PAGE_SIZE - len) - buf[len++] = '\n'; - - ofs += 16; - size -= min(size, 16U); - } - - return len; -} - -static ssize_t store_measurement(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - struct ieee80211_measurement_params params = { - .channel = le16_to_cpu(ctx->active.channel), - .start_time = cpu_to_le64(priv->_3945.last_tsf), - .duration = cpu_to_le16(1), - }; - u8 type = IWL_MEASURE_BASIC; - u8 buffer[32]; - u8 channel; - - if (count) { - char *p = buffer; - strncpy(buffer, buf, min(sizeof(buffer), count)); - channel = simple_strtoul(p, NULL, 0); - if (channel) - params.channel = channel; - - p = buffer; - while (*p && *p != ' ') - p++; - if (*p) - type = simple_strtoul(p + 1, NULL, 0); - } - - IWL_DEBUG_INFO(priv, "Invoking measurement of type %d on " - "channel %d (for '%s')\n", type, params.channel, buf); - iwl3945_get_measurement(priv, ¶ms, type); - - return count; -} - -static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR, - show_measurement, store_measurement); - -static ssize_t store_retry_rate(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - - priv->retry_rate = simple_strtoul(buf, NULL, 0); - if (priv->retry_rate <= 0) - priv->retry_rate = 1; - - return count; -} - -static ssize_t show_retry_rate(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - return sprintf(buf, "%d", priv->retry_rate); -} - -static DEVICE_ATTR(retry_rate, S_IWUSR | S_IRUSR, show_retry_rate, - store_retry_rate); - - -static ssize_t show_channels(struct device *d, - struct device_attribute *attr, char *buf) -{ - /* all this shit doesn't belong into sysfs anyway */ - return 0; -} - -static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); - -static ssize_t show_antenna(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - - if (!iwl_is_alive(priv)) - return -EAGAIN; - - return sprintf(buf, "%d\n", iwl3945_mod_params.antenna); -} - -static ssize_t store_antenna(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv __maybe_unused = dev_get_drvdata(d); - int ant; - - if (count == 0) - return 0; - - if (sscanf(buf, "%1i", &ant) != 1) { - IWL_DEBUG_INFO(priv, "not in hex or decimal form.\n"); - return count; - } - - if ((ant >= 0) && (ant <= 2)) { - IWL_DEBUG_INFO(priv, "Setting antenna select to %d.\n", ant); - iwl3945_mod_params.antenna = (enum iwl3945_antenna)ant; - } else - IWL_DEBUG_INFO(priv, "Bad antenna select value %d.\n", ant); - - - return count; -} - -static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, show_antenna, store_antenna); - -static ssize_t show_status(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - if (!iwl_is_alive(priv)) - return -EAGAIN; - return sprintf(buf, "0x%08x\n", (int)priv->status); -} - -static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); - -static ssize_t dump_error_log(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - char *p = (char *)buf; - - if (p[0] == '1') - iwl3945_dump_nic_error_log(priv); - - return strnlen(buf, count); -} - -static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, dump_error_log); - -/***************************************************************************** - * - * driver setup and tear down - * - *****************************************************************************/ - -static void iwl3945_setup_deferred_work(struct iwl_priv *priv) -{ - priv->workqueue = create_singlethread_workqueue(DRV_NAME); - - init_waitqueue_head(&priv->wait_command_queue); - - INIT_WORK(&priv->restart, iwl3945_bg_restart); - INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); - INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); - INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); - INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); - INIT_DELAYED_WORK(&priv->_3945.rfkill_poll, iwl3945_rfkill_poll); - - iwl_setup_scan_deferred_work(priv); - - iwl3945_hw_setup_deferred_work(priv); - - init_timer(&priv->watchdog); - priv->watchdog.data = (unsigned long)priv; - priv->watchdog.function = iwl_bg_watchdog; - - tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) - iwl3945_irq_tasklet, (unsigned long)priv); -} - -static void iwl3945_cancel_deferred_work(struct iwl_priv *priv) -{ - iwl3945_hw_cancel_deferred_work(priv); - - cancel_delayed_work_sync(&priv->init_alive_start); - cancel_delayed_work(&priv->alive_start); - cancel_work_sync(&priv->beacon_update); - - iwl_cancel_scan_deferred_work(priv); -} - -static struct attribute *iwl3945_sysfs_entries[] = { - &dev_attr_antenna.attr, - &dev_attr_channels.attr, - &dev_attr_dump_errors.attr, - &dev_attr_flags.attr, - &dev_attr_filter_flags.attr, - &dev_attr_measurement.attr, - &dev_attr_retry_rate.attr, - &dev_attr_status.attr, - &dev_attr_temperature.attr, - &dev_attr_tx_power.attr, -#ifdef CONFIG_IWLWIFI_DEBUG - &dev_attr_debug_level.attr, -#endif - NULL -}; - -static struct attribute_group iwl3945_attribute_group = { - .name = NULL, /* put in device directory */ - .attrs = iwl3945_sysfs_entries, -}; - -struct ieee80211_ops iwl3945_hw_ops = { - .tx = iwl3945_mac_tx, - .start = iwl3945_mac_start, - .stop = iwl3945_mac_stop, - .add_interface = iwl_mac_add_interface, - .remove_interface = iwl_mac_remove_interface, - .change_interface = iwl_mac_change_interface, - .config = iwl_legacy_mac_config, - .configure_filter = iwl3945_configure_filter, - .set_key = iwl3945_mac_set_key, - .conf_tx = iwl_mac_conf_tx, - .reset_tsf = iwl_legacy_mac_reset_tsf, - .bss_info_changed = iwl_legacy_mac_bss_info_changed, - .hw_scan = iwl_mac_hw_scan, - .sta_add = iwl3945_mac_sta_add, - .sta_remove = iwl_mac_sta_remove, - .tx_last_beacon = iwl_mac_tx_last_beacon, -}; - -static int iwl3945_init_drv(struct iwl_priv *priv) -{ - int ret; - struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; - - priv->retry_rate = 1; - priv->beacon_skb = NULL; - - spin_lock_init(&priv->sta_lock); - spin_lock_init(&priv->hcmd_lock); - - INIT_LIST_HEAD(&priv->free_frames); - - mutex_init(&priv->mutex); - mutex_init(&priv->sync_cmd_mutex); - - priv->ieee_channels = NULL; - priv->ieee_rates = NULL; - priv->band = IEEE80211_BAND_2GHZ; - - priv->iw_mode = NL80211_IFTYPE_STATION; - priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; - - /* initialize force reset */ - priv->force_reset[IWL_RF_RESET].reset_duration = - IWL_DELAY_NEXT_FORCE_RF_RESET; - priv->force_reset[IWL_FW_RESET].reset_duration = - IWL_DELAY_NEXT_FORCE_FW_RELOAD; - - - priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER; - priv->tx_power_next = IWL_DEFAULT_TX_POWER; - - if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { - IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n", - eeprom->version); - ret = -EINVAL; - goto err; - } - ret = iwl_init_channel_map(priv); - if (ret) { - IWL_ERR(priv, "initializing regulatory failed: %d\n", ret); - goto err; - } - - /* Set up txpower settings in driver for all channels */ - if (iwl3945_txpower_set_from_eeprom(priv)) { - ret = -EIO; - goto err_free_channel_map; - } - - ret = iwlcore_init_geos(priv); - if (ret) { - IWL_ERR(priv, "initializing geos failed: %d\n", ret); - goto err_free_channel_map; - } - iwl3945_init_hw_rates(priv, priv->ieee_rates); - - return 0; - -err_free_channel_map: - iwl_free_channel_map(priv); -err: - return ret; -} - -#define IWL3945_MAX_PROBE_REQUEST 200 - -static int iwl3945_setup_mac(struct iwl_priv *priv) -{ - int ret; - struct ieee80211_hw *hw = priv->hw; - - hw->rate_control_algorithm = "iwl-3945-rs"; - hw->sta_data_size = sizeof(struct iwl3945_sta_priv); - hw->vif_data_size = sizeof(struct iwl_vif_priv); - - /* Tell mac80211 our characteristics */ - hw->flags = IEEE80211_HW_SIGNAL_DBM | - IEEE80211_HW_SPECTRUM_MGMT; - - if (!priv->cfg->base_params->broken_powersave) - hw->flags |= IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_SUPPORTS_DYNAMIC_PS; - - hw->wiphy->interface_modes = - priv->contexts[IWL_RXON_CTX_BSS].interface_modes; - - hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | - WIPHY_FLAG_DISABLE_BEACON_HINTS | - WIPHY_FLAG_IBSS_RSN; - - hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; - /* we create the 802.11 header and a zero-length SSID element */ - hw->wiphy->max_scan_ie_len = IWL3945_MAX_PROBE_REQUEST - 24 - 2; - - /* Default value; 4 EDCA QOS priorities */ - hw->queues = 4; - - if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) - priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = - &priv->bands[IEEE80211_BAND_2GHZ]; - - if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) - priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = - &priv->bands[IEEE80211_BAND_5GHZ]; - - iwl_leds_init(priv); - - ret = ieee80211_register_hw(priv->hw); - if (ret) { - IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); - return ret; - } - priv->mac80211_registered = 1; - - return 0; -} - -static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - int err = 0, i; - struct iwl_priv *priv; - struct ieee80211_hw *hw; - struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); - struct iwl3945_eeprom *eeprom; - unsigned long flags; - - /*********************** - * 1. Allocating HW data - * ********************/ - - /* mac80211 allocates memory for this device instance, including - * space for this driver's private structure */ - hw = iwl_alloc_all(cfg); - if (hw == NULL) { - pr_err("Can not allocate network device\n"); - err = -ENOMEM; - goto out; - } - priv = hw->priv; - SET_IEEE80211_DEV(hw, &pdev->dev); - - priv->cmd_queue = IWL39_CMD_QUEUE_NUM; - - /* 3945 has only one valid context */ - priv->valid_contexts = BIT(IWL_RXON_CTX_BSS); - - for (i = 0; i < NUM_IWL_RXON_CTX; i++) - priv->contexts[i].ctxid = i; - - priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON; - priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING; - priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; - priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; - priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; - priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; - priv->contexts[IWL_RXON_CTX_BSS].interface_modes = - BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC); - priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS; - priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS; - priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS; - - /* - * Disabling hardware scan means that mac80211 will perform scans - * "the hard way", rather than using device's scan. - */ - if (iwl3945_mod_params.disable_hw_scan) { - dev_printk(KERN_DEBUG, &(pdev->dev), - "sw scan support is deprecated\n"); - iwl3945_hw_ops.hw_scan = NULL; - } - - - IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); - priv->cfg = cfg; - priv->pci_dev = pdev; - priv->inta_mask = CSR_INI_SET_MASK; - - if (iwl_alloc_traffic_mem(priv)) - IWL_ERR(priv, "Not enough memory to generate traffic log\n"); - - /*************************** - * 2. Initializing PCI bus - * *************************/ - pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | - PCIE_LINK_STATE_CLKPM); - - if (pci_enable_device(pdev)) { - err = -ENODEV; - goto out_ieee80211_free_hw; - } - - pci_set_master(pdev); - - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (!err) - err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); - if (err) { - IWL_WARN(priv, "No suitable DMA available.\n"); - goto out_pci_disable_device; - } - - pci_set_drvdata(pdev, priv); - err = pci_request_regions(pdev, DRV_NAME); - if (err) - goto out_pci_disable_device; - - /*********************** - * 3. Read REV Register - * ********************/ - priv->hw_base = pci_iomap(pdev, 0, 0); - if (!priv->hw_base) { - err = -ENODEV; - goto out_pci_release_regions; - } - - IWL_DEBUG_INFO(priv, "pci_resource_len = 0x%08llx\n", - (unsigned long long) pci_resource_len(pdev, 0)); - IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base); - - /* We disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state */ - pci_write_config_byte(pdev, 0x41, 0x00); - - /* these spin locks will be used in apm_ops.init and EEPROM access - * we should init now - */ - spin_lock_init(&priv->reg_lock); - spin_lock_init(&priv->lock); - - /* - * stop and reset the on-board processor just in case it is in a - * strange state ... like being left stranded by a primary kernel - * and this is now the kdump kernel trying to start up - */ - iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); - - /*********************** - * 4. Read EEPROM - * ********************/ - - /* Read the EEPROM */ - err = iwl_eeprom_init(priv); - if (err) { - IWL_ERR(priv, "Unable to init EEPROM\n"); - goto out_iounmap; - } - /* MAC Address location in EEPROM same for 3945/4965 */ - eeprom = (struct iwl3945_eeprom *)priv->eeprom; - IWL_DEBUG_INFO(priv, "MAC address: %pM\n", eeprom->mac_address); - SET_IEEE80211_PERM_ADDR(priv->hw, eeprom->mac_address); - - /*********************** - * 5. Setup HW Constants - * ********************/ - /* Device-specific setup */ - if (iwl3945_hw_set_hw_params(priv)) { - IWL_ERR(priv, "failed to set hw settings\n"); - goto out_eeprom_free; - } - - /*********************** - * 6. Setup priv - * ********************/ - - err = iwl3945_init_drv(priv); - if (err) { - IWL_ERR(priv, "initializing driver failed\n"); - goto out_unset_hw_params; - } - - IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s\n", - priv->cfg->name); - - /*********************** - * 7. Setup Services - * ********************/ - - spin_lock_irqsave(&priv->lock, flags); - iwl_disable_interrupts(priv); - spin_unlock_irqrestore(&priv->lock, flags); - - pci_enable_msi(priv->pci_dev); - - err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr_ops.isr, - IRQF_SHARED, DRV_NAME, priv); - if (err) { - IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); - goto out_disable_msi; - } - - err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group); - if (err) { - IWL_ERR(priv, "failed to create sysfs device attributes\n"); - goto out_release_irq; - } - - iwl_set_rxon_channel(priv, - &priv->bands[IEEE80211_BAND_2GHZ].channels[5], - &priv->contexts[IWL_RXON_CTX_BSS]); - iwl3945_setup_deferred_work(priv); - iwl3945_setup_rx_handlers(priv); - iwl_power_initialize(priv); - - /********************************* - * 8. Setup and Register mac80211 - * *******************************/ - - iwl_enable_interrupts(priv); - - err = iwl3945_setup_mac(priv); - if (err) - goto out_remove_sysfs; - - err = iwl_dbgfs_register(priv, DRV_NAME); - if (err) - IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); - - /* Start monitoring the killswitch */ - queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll, - 2 * HZ); - - return 0; - - out_remove_sysfs: - destroy_workqueue(priv->workqueue); - priv->workqueue = NULL; - sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); - out_release_irq: - free_irq(priv->pci_dev->irq, priv); - out_disable_msi: - pci_disable_msi(priv->pci_dev); - iwlcore_free_geos(priv); - iwl_free_channel_map(priv); - out_unset_hw_params: - iwl3945_unset_hw_params(priv); - out_eeprom_free: - iwl_eeprom_free(priv); - out_iounmap: - pci_iounmap(pdev, priv->hw_base); - out_pci_release_regions: - pci_release_regions(pdev); - out_pci_disable_device: - pci_set_drvdata(pdev, NULL); - pci_disable_device(pdev); - out_ieee80211_free_hw: - iwl_free_traffic_mem(priv); - ieee80211_free_hw(priv->hw); - out: - return err; -} - -static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) -{ - struct iwl_priv *priv = pci_get_drvdata(pdev); - unsigned long flags; - - if (!priv) - return; - - IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); - - iwl_dbgfs_unregister(priv); - - set_bit(STATUS_EXIT_PENDING, &priv->status); - - iwl_leds_exit(priv); - - if (priv->mac80211_registered) { - ieee80211_unregister_hw(priv->hw); - priv->mac80211_registered = 0; - } else { - iwl3945_down(priv); - } - - /* - * Make sure device is reset to low power before unloading driver. - * This may be redundant with iwl_down(), but there are paths to - * run iwl_down() without calling apm_ops.stop(), and there are - * paths to avoid running iwl_down() at all before leaving driver. - * This (inexpensive) call *makes sure* device is reset. - */ - iwl_apm_stop(priv); - - /* make sure we flush any pending irq or - * tasklet for the driver - */ - spin_lock_irqsave(&priv->lock, flags); - iwl_disable_interrupts(priv); - spin_unlock_irqrestore(&priv->lock, flags); - - iwl_synchronize_irq(priv); - - sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); - - cancel_delayed_work_sync(&priv->_3945.rfkill_poll); - - iwl3945_dealloc_ucode_pci(priv); - - if (priv->rxq.bd) - iwl3945_rx_queue_free(priv, &priv->rxq); - iwl3945_hw_txq_ctx_free(priv); - - iwl3945_unset_hw_params(priv); - - /*netif_stop_queue(dev); */ - flush_workqueue(priv->workqueue); - - /* ieee80211_unregister_hw calls iwl3945_mac_stop, which flushes - * priv->workqueue... so we can't take down the workqueue - * until now... */ - destroy_workqueue(priv->workqueue); - priv->workqueue = NULL; - iwl_free_traffic_mem(priv); - - free_irq(pdev->irq, priv); - pci_disable_msi(pdev); - - pci_iounmap(pdev, priv->hw_base); - pci_release_regions(pdev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); - - iwl_free_channel_map(priv); - iwlcore_free_geos(priv); - kfree(priv->scan_cmd); - if (priv->beacon_skb) - dev_kfree_skb(priv->beacon_skb); - - ieee80211_free_hw(priv->hw); -} - - -/***************************************************************************** - * - * driver and module entry point - * - *****************************************************************************/ - -static struct pci_driver iwl3945_driver = { - .name = DRV_NAME, - .id_table = iwl3945_hw_card_ids, - .probe = iwl3945_pci_probe, - .remove = __devexit_p(iwl3945_pci_remove), - .driver.pm = IWL_PM_OPS, -}; - -static int __init iwl3945_init(void) -{ - - int ret; - pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); - pr_info(DRV_COPYRIGHT "\n"); - - ret = iwl3945_rate_control_register(); - if (ret) { - pr_err("Unable to register rate control algorithm: %d\n", ret); - return ret; - } - - ret = pci_register_driver(&iwl3945_driver); - if (ret) { - pr_err("Unable to initialize PCI module\n"); - goto error_register; - } - - return ret; - -error_register: - iwl3945_rate_control_unregister(); - return ret; -} - -static void __exit iwl3945_exit(void) -{ - pci_unregister_driver(&iwl3945_driver); - iwl3945_rate_control_unregister(); -} - -MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX)); - -module_param_named(antenna, iwl3945_mod_params.antenna, int, S_IRUGO); -MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); -module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, S_IRUGO); -MODULE_PARM_DESC(swcrypto, - "using software crypto (default 1 [software])\n"); -#ifdef CONFIG_IWLWIFI_DEBUG -module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "debug output mask"); -#endif -module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, - int, S_IRUGO); -MODULE_PARM_DESC(disable_hw_scan, - "disable hardware scanning (default 0) (deprecated)"); -module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, S_IRUGO); -MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error"); - -module_exit(iwl3945_exit); -module_init(iwl3945_init); -- cgit v1.2.3 From 573cfde7aaeaadb0fd356ff2a14bdf9238967661 Mon Sep 17 00:00:00 2001 From: Nick Kossifidis Date: Fri, 4 Feb 2011 01:41:02 +0200 Subject: ath5k: Fix fast channel switching Fast channel change fixes: a) Always set OFDM timings b) Don't re-activate PHY c) Enable only NF calibration, not AGC https://bugzilla.kernel.org/show_bug.cgi?id=27382 Signed-off-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 142 +++++++++++++++++++++-------------- 1 file changed, 87 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index c44111fc98b7..62ce2f4e8605 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -282,6 +282,34 @@ int ath5k_hw_phy_disable(struct ath5k_hw *ah) return 0; } +/* + * Wait for synth to settle + */ +static void ath5k_hw_wait_for_synth(struct ath5k_hw *ah, + struct ieee80211_channel *channel) +{ + /* + * On 5211+ read activation -> rx delay + * and use it (100ns steps). + */ + if (ah->ah_version != AR5K_AR5210) { + u32 delay; + delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & + AR5K_PHY_RX_DELAY_M; + delay = (channel->hw_value & CHANNEL_CCK) ? + ((delay << 2) / 22) : (delay / 10); + if (ah->ah_bwmode == AR5K_BWMODE_10MHZ) + delay = delay << 1; + if (ah->ah_bwmode == AR5K_BWMODE_5MHZ) + delay = delay << 2; + /* XXX: /2 on turbo ? Let's be safe + * for now */ + udelay(100 + delay); + } else { + mdelay(1); + } +} + /**********************\ * RF Gain optimization * @@ -3238,6 +3266,13 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, /* Failed */ if (i >= 100) return -EIO; + + /* Set channel and wait for synth */ + ret = ath5k_hw_channel(ah, channel); + if (ret) + return ret; + + ath5k_hw_wait_for_synth(ah, channel); } /* @@ -3252,13 +3287,53 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, if (ret) return ret; + /* Write OFDM timings on 5212*/ + if (ah->ah_version == AR5K_AR5212 && + channel->hw_value & CHANNEL_OFDM) { + + ret = ath5k_hw_write_ofdm_timings(ah, channel); + if (ret) + return ret; + + /* Spur info is available only from EEPROM versions + * greater than 5.3, but the EEPROM routines will use + * static values for older versions */ + if (ah->ah_mac_srev >= AR5K_SREV_AR5424) + ath5k_hw_set_spur_mitigation_filter(ah, + channel); + } + + /* If we used fast channel switching + * we are done, release RF bus and + * fire up NF calibration. + * + * Note: Only NF calibration due to + * channel change, not AGC calibration + * since AGC is still running ! + */ + if (fast) { + /* + * Release RF Bus grant + */ + AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ, + AR5K_PHY_RFBUS_REQ_REQUEST); + + /* + * Start NF calibration + */ + AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, + AR5K_PHY_AGCCTL_NF); + + return ret; + } + /* * For 5210 we do all initialization using * initvals, so we don't have to modify * any settings (5210 also only supports * a/aturbo modes) */ - if ((ah->ah_version != AR5K_AR5210) && !fast) { + if (ah->ah_version != AR5K_AR5210) { /* * Write initial RF gain settings @@ -3277,22 +3352,6 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, if (ret) return ret; - /* Write OFDM timings on 5212*/ - if (ah->ah_version == AR5K_AR5212 && - channel->hw_value & CHANNEL_OFDM) { - - ret = ath5k_hw_write_ofdm_timings(ah, channel); - if (ret) - return ret; - - /* Spur info is available only from EEPROM versions - * greater than 5.3, but the EEPROM routines will use - * static values for older versions */ - if (ah->ah_mac_srev >= AR5K_SREV_AR5424) - ath5k_hw_set_spur_mitigation_filter(ah, - channel); - } - /*Enable/disable 802.11b mode on 5111 (enable 2111 frequency converter + CCK)*/ if (ah->ah_radio == AR5K_RF5111) { @@ -3323,47 +3382,20 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, */ ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); + ath5k_hw_wait_for_synth(ah, channel); + /* - * On 5211+ read activation -> rx delay - * and use it. + * Perform ADC test to see if baseband is ready + * Set tx hold and check adc test register */ - if (ah->ah_version != AR5K_AR5210) { - u32 delay; - delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & - AR5K_PHY_RX_DELAY_M; - delay = (channel->hw_value & CHANNEL_CCK) ? - ((delay << 2) / 22) : (delay / 10); - if (ah->ah_bwmode == AR5K_BWMODE_10MHZ) - delay = delay << 1; - if (ah->ah_bwmode == AR5K_BWMODE_5MHZ) - delay = delay << 2; - /* XXX: /2 on turbo ? Let's be safe - * for now */ - udelay(100 + delay); - } else { - mdelay(1); - } - - if (fast) - /* - * Release RF Bus grant - */ - AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ, - AR5K_PHY_RFBUS_REQ_REQUEST); - else { - /* - * Perform ADC test to see if baseband is ready - * Set tx hold and check adc test register - */ - phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); - ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); - for (i = 0; i <= 20; i++) { - if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) - break; - udelay(200); - } - ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1); + phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); + ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); + for (i = 0; i <= 20; i++) { + if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) + break; + udelay(200); } + ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1); /* * Start automatic gain control calibration -- cgit v1.2.3 From 41504cce240f791f1e16561db95728c5537fbad9 Mon Sep 17 00:00:00 2001 From: "Fry, Donald H" Date: Wed, 16 Feb 2011 11:49:34 -0800 Subject: iwlagn: Support new 5000 microcode. New iwlwifi-5000 microcode requires driver support for API version 5. Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 79ab0a6b1386..537fb8c84e3a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -51,7 +51,7 @@ #include "iwl-agn-debugfs.h" /* Highest firmware API version supported */ -#define IWL5000_UCODE_API_MAX 2 +#define IWL5000_UCODE_API_MAX 5 #define IWL5150_UCODE_API_MAX 2 /* Lowest firmware API version supported */ -- cgit v1.2.3 From a866a2cc1c558089dd4c627eeb300142b1354474 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Sun, 30 Jan 2011 13:22:41 +0100 Subject: rt2x00: Fix WPA TKIP Michael MIC failures. As reported and found by Johannes Stezenbach: rt2800{pci,usb} do not report the Michael MIC in RXed frames, but do check the Michael MIC in hardware. Therefore we have to report to mac80211 that the received frame does not include the Michael MIC. https://bugzilla.kernel.org/show_bug.cgi?id=16608 Signed-off-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 6 ++++++ drivers/net/wireless/rt2x00/rt2800usb.c | 6 ++++++ 2 files changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 7951cdaa9c01..3b3f1e45ab3e 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -652,6 +652,12 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry, */ rxdesc->flags |= RX_FLAG_IV_STRIPPED; + /* + * The hardware has already checked the Michael Mic and has + * stripped it from the frame. Signal this to mac80211. + */ + rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; + if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) rxdesc->flags |= RX_FLAG_DECRYPTED; else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index b97a4a54ff4c..197a36c05fda 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -486,6 +486,12 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, */ rxdesc->flags |= RX_FLAG_IV_STRIPPED; + /* + * The hardware has already checked the Michael Mic and has + * stripped it from the frame. Signal this to mac80211. + */ + rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; + if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) rxdesc->flags |= RX_FLAG_DECRYPTED; else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) -- cgit v1.2.3 From 0bf719dfdecc5552155cbec78e49fa06e531e35c Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 11 Feb 2011 01:48:42 +0100 Subject: p54pci: update receive dma buffers before and after processing Documentation/DMA-API-HOWTO.txt states: "DMA transfers need to be synced properly in order for the cpu and device to see the most uptodate and correct copy of the DMA buffer." Cc: Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54pci.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index 1eacba4daa5b..0494d7b102d4 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c @@ -199,6 +199,7 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index, while (i != idx) { u16 len; struct sk_buff *skb; + dma_addr_t dma_addr; desc = &ring[i]; len = le16_to_cpu(desc->len); skb = rx_buf[i]; @@ -216,17 +217,20 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index, len = priv->common.rx_mtu; } + dma_addr = le32_to_cpu(desc->host_addr); + pci_dma_sync_single_for_cpu(priv->pdev, dma_addr, + priv->common.rx_mtu + 32, PCI_DMA_FROMDEVICE); skb_put(skb, len); if (p54_rx(dev, skb)) { - pci_unmap_single(priv->pdev, - le32_to_cpu(desc->host_addr), - priv->common.rx_mtu + 32, - PCI_DMA_FROMDEVICE); + pci_unmap_single(priv->pdev, dma_addr, + priv->common.rx_mtu + 32, PCI_DMA_FROMDEVICE); rx_buf[i] = NULL; - desc->host_addr = 0; + desc->host_addr = cpu_to_le32(0); } else { skb_trim(skb, 0); + pci_dma_sync_single_for_device(priv->pdev, dma_addr, + priv->common.rx_mtu + 32, PCI_DMA_FROMDEVICE); desc->len = cpu_to_le16(priv->common.rx_mtu + 32); } -- cgit v1.2.3 From f456228365bf3615bc6837c363653f31df66abff Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Wed, 9 Feb 2011 22:13:11 +0100 Subject: ar9170usb: mark the old driver as obsolete AR9170USB will be replaced by carl9170 in the foreseeable future [2.6.40]. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- Documentation/feature-removal-schedule.txt | 11 +++++++++++ MAINTAINERS | 2 +- drivers/net/wireless/ath/ar9170/Kconfig | 4 +++- 3 files changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 8c594c45b6a1..ab274856c6a2 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -35,6 +35,17 @@ Who: Luis R. Rodriguez --------------------------- +What: AR9170USB +When: 2.6.40 + +Why: This driver is deprecated and the firmware is no longer + maintained. The replacement driver "carl9170" has been + around for a while, so the devices are still supported. + +Who: Christian Lamparter + +--------------------------- + What: IRQF_SAMPLE_RANDOM Check: IRQF_SAMPLE_RANDOM When: July 2009 diff --git a/MAINTAINERS b/MAINTAINERS index 2b35b6c84e2c..95482e9e5ba5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1199,7 +1199,7 @@ ATHEROS AR9170 WIRELESS DRIVER M: Christian Lamparter L: linux-wireless@vger.kernel.org W: http://wireless.kernel.org/en/users/Drivers/ar9170 -S: Maintained +S: Obsolete F: drivers/net/wireless/ath/ar9170/ CARL9170 LINUX COMMUNITY WIRELESS DRIVER diff --git a/drivers/net/wireless/ath/ar9170/Kconfig b/drivers/net/wireless/ath/ar9170/Kconfig index d7a4799d20fb..7b9672b0d090 100644 --- a/drivers/net/wireless/ath/ar9170/Kconfig +++ b/drivers/net/wireless/ath/ar9170/Kconfig @@ -1,8 +1,10 @@ config AR9170_USB - tristate "Atheros AR9170 802.11n USB support" + tristate "Atheros AR9170 802.11n USB support (OBSOLETE)" depends on USB && MAC80211 select FW_LOADER help + This driver is going to get replaced by carl9170. + This is a driver for the Atheros "otus" 802.11n USB devices. These devices require additional firmware (2 files). -- cgit v1.2.3 From d985255e00e8a6a0d87b1dc674113bc76bed04a0 Mon Sep 17 00:00:00 2001 From: Wojciech Dubowik Date: Fri, 18 Feb 2011 13:06:42 +0100 Subject: ath5k: Enable AR2315 chipset recognition Enable recognition of AR2315 chipsets in ath5k driver. Reported-by: Simon Morgenthaler Signed-off-by: Wojciech Dubowik Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/attach.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index c71fdbb4c439..bc8240560488 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -220,7 +220,8 @@ int ath5k_hw_init(struct ath5k_softc *sc) ah->ah_radio = AR5K_RF5112; ah->ah_single_chip = false; ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B; - } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) { + } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4) || + ah->ah_mac_version == (AR5K_SREV_AR2315_R6 >> 4)) { ah->ah_radio = AR5K_RF2316; ah->ah_single_chip = true; ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316; -- cgit v1.2.3 From 0aec516ce4cfd44f48b3ae0c54bc2f1eab007173 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 18 Feb 2011 17:25:36 -0800 Subject: wl12xx: fix sdio_test kconfig/build errors The wl12xx sdio_test code uses wl12xx_get_platform_data, which is only present when WL12*_SDIO is enabled, so make WL12XX_SDIO_TEST depend on WL12XX_SDIO so that the needed interface will be present. sdio_test.c:(.devinit.text+0x13178): undefined reference to `wl12xx_get_platform_data' Signed-off-by: Randy Dunlap Cc: Luciano Coelho Cc: Roger Quadros Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig index 0e65bce457d6..692ebff38fc8 100644 --- a/drivers/net/wireless/wl12xx/Kconfig +++ b/drivers/net/wireless/wl12xx/Kconfig @@ -54,7 +54,7 @@ config WL12XX_SDIO config WL12XX_SDIO_TEST tristate "TI wl12xx SDIO testing support" - depends on WL12XX && MMC + depends on WL12XX && MMC && WL12XX_SDIO default n ---help--- This module adds support for the SDIO bus testing with the -- cgit v1.2.3 From 69081624c7b2138b137738e307cb67e2dafd6e9b Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Sat, 19 Feb 2011 01:13:42 -0800 Subject: ath9k: Implement op_flush() When op_flush() is called with no drop (drop=false), the driver tries to tx as many frames as possible in about 100ms on every hw queue. During this time period frames from sw queue are also scheduled on to respective hw queue. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/main.c | 71 ++++++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/xmit.c | 27 +++++++------ 3 files changed, 88 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index a224c56448de..f9f0389b92ab 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -189,6 +189,7 @@ struct ath_txq { u32 axq_ampdu_depth; bool stopped; bool axq_tx_inprogress; + bool txq_flush_inprogress; struct list_head axq_acq; struct list_head txq_fifo[ATH_TXFIFO_DEPTH]; struct list_head txq_fifo_pending; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 1d2c7c3cc5ca..a71550049d84 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -15,6 +15,7 @@ */ #include +#include #include "ath9k.h" #include "btcoex.h" @@ -53,6 +54,21 @@ static u8 parse_mpdudensity(u8 mpdudensity) } } +static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq) +{ + bool pending = false; + + spin_lock_bh(&txq->axq_lock); + + if (txq->axq_depth || !list_empty(&txq->axq_acq)) + pending = true; + else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) + pending = !list_empty(&txq->txq_fifo_pending); + + spin_unlock_bh(&txq->axq_lock); + return pending; +} + bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode) { unsigned long flags; @@ -2111,6 +2127,60 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) mutex_unlock(&sc->mutex); } +static void ath9k_flush(struct ieee80211_hw *hw, bool drop) +{ +#define ATH_FLUSH_TIMEOUT 60 /* ms */ + struct ath_softc *sc = hw->priv; + struct ath_txq *txq; + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + int i, j, npend = 0; + + mutex_lock(&sc->mutex); + + cancel_delayed_work_sync(&sc->tx_complete_work); + + for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { + if (!ATH_TXQ_SETUP(sc, i)) + continue; + txq = &sc->tx.txq[i]; + + if (!drop) { + for (j = 0; j < ATH_FLUSH_TIMEOUT; j++) { + if (!ath9k_has_pending_frames(sc, txq)) + break; + usleep_range(1000, 2000); + } + } + + if (drop || ath9k_has_pending_frames(sc, txq)) { + ath_dbg(common, ATH_DBG_QUEUE, "Drop frames from hw queue:%d\n", + txq->axq_qnum); + spin_lock_bh(&txq->axq_lock); + txq->txq_flush_inprogress = true; + spin_unlock_bh(&txq->axq_lock); + + ath9k_ps_wakeup(sc); + ath9k_hw_stoptxdma(ah, txq->axq_qnum); + npend = ath9k_hw_numtxpending(ah, txq->axq_qnum); + ath9k_ps_restore(sc); + if (npend) + break; + + ath_draintxq(sc, txq, false); + txq->txq_flush_inprogress = false; + } + } + + if (npend) { + ath_reset(sc, false); + txq->txq_flush_inprogress = false; + } + + ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); + mutex_unlock(&sc->mutex); +} + struct ieee80211_ops ath9k_ops = { .tx = ath9k_tx, .start = ath9k_start, @@ -2132,4 +2202,5 @@ struct ieee80211_ops ath9k_ops = { .get_survey = ath9k_get_survey, .rfkill_poll = ath9k_rfkill_poll_state, .set_coverage_class = ath9k_set_coverage_class, + .flush = ath9k_flush, }; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index bc614acb96de..e16136d61799 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -2014,7 +2014,8 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) spin_lock_bh(&txq->axq_lock); if (list_empty(&txq->axq_q)) { txq->axq_link = NULL; - if (sc->sc_flags & SC_OP_TXAGGR) + if (sc->sc_flags & SC_OP_TXAGGR && + !txq->txq_flush_inprogress) ath_txq_schedule(sc, txq); spin_unlock_bh(&txq->axq_lock); break; @@ -2071,6 +2072,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) if (bf_is_ampdu_not_probing(bf)) txq->axq_ampdu_depth--; + spin_unlock_bh(&txq->axq_lock); if (bf_held) @@ -2094,7 +2096,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) spin_lock_bh(&txq->axq_lock); - if (sc->sc_flags & SC_OP_TXAGGR) + if (sc->sc_flags & SC_OP_TXAGGR && !txq->txq_flush_inprogress) ath_txq_schedule(sc, txq); spin_unlock_bh(&txq->axq_lock); } @@ -2265,15 +2267,18 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) spin_lock_bh(&txq->axq_lock); - if (!list_empty(&txq->txq_fifo_pending)) { - INIT_LIST_HEAD(&bf_head); - bf = list_first_entry(&txq->txq_fifo_pending, - struct ath_buf, list); - list_cut_position(&bf_head, &txq->txq_fifo_pending, - &bf->bf_lastbf->list); - ath_tx_txqaddbuf(sc, txq, &bf_head); - } else if (sc->sc_flags & SC_OP_TXAGGR) - ath_txq_schedule(sc, txq); + if (!txq->txq_flush_inprogress) { + if (!list_empty(&txq->txq_fifo_pending)) { + INIT_LIST_HEAD(&bf_head); + bf = list_first_entry(&txq->txq_fifo_pending, + struct ath_buf, list); + list_cut_position(&bf_head, + &txq->txq_fifo_pending, + &bf->bf_lastbf->list); + ath_tx_txqaddbuf(sc, txq, &bf_head); + } else if (sc->sc_flags & SC_OP_TXAGGR) + ath_txq_schedule(sc, txq); + } spin_unlock_bh(&txq->axq_lock); } } -- cgit v1.2.3 From a9dd591919788b38c9177a41dcb40a7a0620cdd0 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 19 Feb 2011 16:28:47 -0600 Subject: rtlwifi: Make changes in rtlwifi/rtl8192ce/reg.h to support rtl8192cu This change modifies rtlwifi/rtl8192ce/reg.h to support rtl8192cu. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ce/reg.h | 71 ++++++++++++++++++++++++++-- drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 2 +- 2 files changed, 69 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h index 875d51465225..9ffbadc281f2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h @@ -63,7 +63,15 @@ #define REG_LEDCFG3 0x004F #define REG_FSIMR 0x0050 #define REG_FSISR 0x0054 - +#define REG_HSIMR 0x0058 +#define REG_HSISR 0x005c + +/* RTL8723 WIFI/BT/GPS Multi-Function GPIO Pin Control. */ +#define REG_GPIO_PIN_CTRL_2 0x0060 +/* RTL8723 WIFI/BT/GPS Multi-Function GPIO Select. */ +#define REG_GPIO_IO_SEL_2 0x0062 +/* RTL8723 WIFI/BT/GPS Multi-Function control source. */ +#define REG_MULTI_FUNC_CTRL 0x0068 #define REG_MCUFWDL 0x0080 #define REG_HMEBOX_EXT_0 0x0088 @@ -79,6 +87,7 @@ #define REG_PCIE_MIO_INTD 0x00E8 #define REG_HPON_FSM 0x00EC #define REG_SYS_CFG 0x00F0 +#define REG_GPIO_OUTSTS 0x00F4 /* For RTL8723 only.*/ #define REG_CR 0x0100 #define REG_PBP 0x0104 @@ -209,6 +218,8 @@ #define REG_RDG_PIFS 0x0513 #define REG_SIFS_CTX 0x0514 #define REG_SIFS_TRX 0x0516 +#define REG_SIFS_CCK 0x0514 +#define REG_SIFS_OFDM 0x0516 #define REG_AGGR_BREAK_TIME 0x051A #define REG_SLOT 0x051B #define REG_TX_PTCL_CTRL 0x0520 @@ -261,6 +272,10 @@ #define REG_MAC_SPEC_SIFS 0x063A #define REG_RESP_SIFS_CCK 0x063C #define REG_RESP_SIFS_OFDM 0x063E +/* [15:8]SIFS_R2T_OFDM, [7:0]SIFS_R2T_CCK */ +#define REG_R2T_SIFS 0x063C +/* [15:8]SIFS_T2T_OFDM, [7:0]SIFS_T2T_CCK */ +#define REG_T2T_SIFS 0x063E #define REG_ACKTO 0x0640 #define REG_CTS2TO 0x0641 #define REG_EIFS 0x0642 @@ -641,9 +656,10 @@ #define STOPBE BIT(1) #define STOPBK BIT(0) -#define RCR_APPFCS BIT(31) +#define RCR_APP_FCS BIT(31) #define RCR_APP_MIC BIT(30) #define RCR_APP_ICV BIT(29) +#define RCR_APP_PHYSTS BIT(28) #define RCR_APP_PHYST_RXFF BIT(28) #define RCR_APP_BA_SSN BIT(27) #define RCR_ENMBID BIT(24) @@ -759,6 +775,7 @@ #define BOOT_FROM_EEPROM BIT(4) #define EEPROM_EN BIT(5) +#define EEPROMSEL BOOT_FROM_EEPROM #define AFE_BGEN BIT(0) #define AFE_MBEN BIT(1) @@ -876,6 +893,8 @@ #define BD_MAC2 BIT(9) #define BD_MAC1 BIT(10) #define IC_MACPHY_MODE BIT(11) +#define BT_FUNC BIT(16) +#define VENDOR_ID BIT(19) #define PAD_HWPD_IDN BIT(22) #define TRP_VAUX_EN BIT(23) #define TRP_BT_EN BIT(24) @@ -883,6 +902,28 @@ #define BD_HCI_SEL BIT(26) #define TYPE_ID BIT(27) +/* REG_GPIO_OUTSTS (For RTL8723 only) */ +#define EFS_HCI_SEL (BIT(0)|BIT(1)) +#define PAD_HCI_SEL (BIT(2)|BIT(3)) +#define HCI_SEL (BIT(4)|BIT(5)) +#define PKG_SEL_HCI BIT(6) +#define FEN_GPS BIT(7) +#define FEN_BT BIT(8) +#define FEN_WL BIT(9) +#define FEN_PCI BIT(10) +#define FEN_USB BIT(11) +#define BTRF_HWPDN_N BIT(12) +#define WLRF_HWPDN_N BIT(13) +#define PDN_BT_N BIT(14) +#define PDN_GPS_N BIT(15) +#define BT_CTL_HWPDN BIT(16) +#define GPS_CTL_HWPDN BIT(17) +#define PPHY_SUSB BIT(20) +#define UPHY_SUSB BIT(21) +#define PCI_SUSEN BIT(22) +#define USB_SUSEN BIT(23) +#define RF_RL_ID (BIT(31) | BIT(30) | BIT(29) | BIT(28)) + #define CHIP_VER_RTL_MASK 0xF000 #define CHIP_VER_RTL_SHIFT 12 @@ -1184,6 +1225,30 @@ #define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) +/* REG_MULTI_FUNC_CTRL(For RTL8723 Only) */ +/* Enable GPIO[9] as WiFi HW PDn source */ +#define WL_HWPDN_EN BIT(0) +/* WiFi HW PDn polarity control */ +#define WL_HWPDN_SL BIT(1) +/* WiFi function enable */ +#define WL_FUNC_EN BIT(2) +/* Enable GPIO[9] as WiFi RF HW PDn source */ +#define WL_HWROF_EN BIT(3) +/* Enable GPIO[11] as BT HW PDn source */ +#define BT_HWPDN_EN BIT(16) +/* BT HW PDn polarity control */ +#define BT_HWPDN_SL BIT(17) +/* BT function enable */ +#define BT_FUNC_EN BIT(18) +/* Enable GPIO[11] as BT/GPS RF HW PDn source */ +#define BT_HWROF_EN BIT(19) +/* Enable GPIO[10] as GPS HW PDn source */ +#define GPS_HWPDN_EN BIT(20) +/* GPS HW PDn polarity control */ +#define GPS_HWPDN_SL BIT(21) +/* GPS function enable */ +#define GPS_FUNC_EN BIT(22) + #define RPMAC_RESET 0x100 #define RPMAC_TXSTART 0x104 #define RPMAC_TXLEGACYSIG 0x108 @@ -1496,7 +1561,7 @@ #define BTXHTSTBC 0x30 #define BTXHTADVANCECODING 0x40 #define BTXHTSHORTGI 0x80 -#define BTXHTNUMBERHT_LT F 0x300 +#define BTXHTNUMBERHT_LTF 0x300 #define BTXHTCRC8 0x3fc00 #define BCOUNTERRESET 0x10000 #define BNUMOFOFDMTX 0xffff diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index a8b3d0605abd..40ae618a0262 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -52,7 +52,7 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->dm.thermalvalue = 0; rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13); - rtlpci->receive_config = (RCR_APPFCS | + rtlpci->receive_config = (RCR_APP_FCS | RCR_AMF | RCR_ADF | RCR_APP_MIC | -- cgit v1.2.3 From 0e80b9d1c51883e01603e2ff0caae608eda09fa5 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 19 Feb 2011 16:28:52 -0600 Subject: rtlwifi: Make changes in rtlwifi/rtl8192ce/def.h to support rtl8192cu This change modifies rtlwifi/rtl8192ce/def.h to handle rtl8192cu. In addition, a couple of routines needed for both drivers are converted to be inline. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ce/def.h | 144 +++++++++++++++++++++++++++ drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 13 --- 2 files changed, 144 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h index 83cd64895292..2f577c8828fc 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h @@ -121,11 +121,37 @@ #define CHIP_92C 0x01 #define CHIP_88C 0x00 +/* Add vendor information into chip version definition. + * Add UMC B-Cut and RTL8723 chip info definition. + * + * BIT 7 Reserved + * BIT 6 UMC BCut + * BIT 5 Manufacturer(TSMC/UMC) + * BIT 4 TEST/NORMAL + * BIT 3 8723 Version + * BIT 2 8723? + * BIT 1 1T2R? + * BIT 0 88C/92C +*/ + enum version_8192c { VERSION_A_CHIP_92C = 0x01, VERSION_A_CHIP_88C = 0x00, VERSION_B_CHIP_92C = 0x11, VERSION_B_CHIP_88C = 0x10, + VERSION_TEST_CHIP_88C = 0x00, + VERSION_TEST_CHIP_92C = 0x01, + VERSION_NORMAL_TSMC_CHIP_88C = 0x10, + VERSION_NORMAL_TSMC_CHIP_92C = 0x11, + VERSION_NORMAL_TSMC_CHIP_92C_1T2R = 0x13, + VERSION_NORMAL_UMC_CHIP_88C_A_CUT = 0x30, + VERSION_NORMAL_UMC_CHIP_92C_A_CUT = 0x31, + VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT = 0x33, + VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT = 0x34, + VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT = 0x3c, + VERSION_NORMAL_UMC_CHIP_88C_B_CUT = 0x70, + VERSION_NORMAL_UMC_CHIP_92C_B_CUT = 0x71, + VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT = 0x73, VERSION_UNKNOWN = 0x88, }; @@ -254,4 +280,122 @@ struct h2c_cmd_8192c { u8 *p_cmdbuffer; }; +static inline u8 _rtl92c_get_chnl_group(u8 chnl) +{ + u8 group = 0; + + if (chnl < 3) + group = 0; + else if (chnl < 9) + group = 1; + else + group = 2; + + return group; +} + +/* NOTE: reference to rtl8192c_rates struct */ +static inline int _rtl92c_rate_mapping(struct ieee80211_hw *hw, bool isHT, + u8 desc_rate, bool first_ampdu) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int rate_idx = 0; + + if (first_ampdu) { + if (false == isHT) { + switch (desc_rate) { + case DESC92C_RATE1M: + rate_idx = 0; + break; + case DESC92C_RATE2M: + rate_idx = 1; + break; + case DESC92C_RATE5_5M: + rate_idx = 2; + break; + case DESC92C_RATE11M: + rate_idx = 3; + break; + case DESC92C_RATE6M: + rate_idx = 4; + break; + case DESC92C_RATE9M: + rate_idx = 5; + break; + case DESC92C_RATE12M: + rate_idx = 6; + break; + case DESC92C_RATE18M: + rate_idx = 7; + break; + case DESC92C_RATE24M: + rate_idx = 8; + break; + case DESC92C_RATE36M: + rate_idx = 9; + break; + case DESC92C_RATE48M: + rate_idx = 10; + break; + case DESC92C_RATE54M: + rate_idx = 11; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, + ("Rate %d is not support, set to " + "1M rate.\n", desc_rate)); + rate_idx = 0; + break; + } + } else { + rate_idx = 11; + } + return rate_idx; + } + switch (desc_rate) { + case DESC92C_RATE1M: + rate_idx = 0; + break; + case DESC92C_RATE2M: + rate_idx = 1; + break; + case DESC92C_RATE5_5M: + rate_idx = 2; + break; + case DESC92C_RATE11M: + rate_idx = 3; + break; + case DESC92C_RATE6M: + rate_idx = 4; + break; + case DESC92C_RATE9M: + rate_idx = 5; + break; + case DESC92C_RATE12M: + rate_idx = 6; + break; + case DESC92C_RATE18M: + rate_idx = 7; + break; + case DESC92C_RATE24M: + rate_idx = 8; + break; + case DESC92C_RATE36M: + rate_idx = 9; + break; + case DESC92C_RATE48M: + rate_idx = 10; + break; + case DESC92C_RATE54M: + rate_idx = 11; + break; + /* TODO: How to mapping MCS rate? */ + /* NOTE: referenc to __ieee80211_rx */ + default: + rate_idx = 11; + break; + } + return rate_idx; +} + #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 1c41a0c93506..0e280995aace 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -1335,19 +1335,6 @@ void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw, rtl92ce_enable_interrupt(hw); } -static u8 _rtl92c_get_chnl_group(u8 chnl) -{ - u8 group; - - if (chnl < 3) - group = 0; - else if (chnl < 9) - group = 1; - else - group = 2; - return group; -} - static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, bool autoload_fail, u8 *hwinfo) -- cgit v1.2.3 From 7ea4724036ed17ec811cb8082af7760f04484ef7 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 19 Feb 2011 16:28:57 -0600 Subject: rtlwifi: Modify some rtl8192ce routines for merging rtl8192cu Modify some rtl8192ce routines for merging with rtl8192cu. In addition, remove some usage of Hungarian notation. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.c | 60 +++++------ drivers/net/wireless/rtlwifi/core.c | 8 +- drivers/net/wireless/rtlwifi/pci.c | 36 +++---- drivers/net/wireless/rtlwifi/ps.c | 58 +++++------ drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 82 +++++++-------- drivers/net/wireless/rtlwifi/rtl8192ce/dm.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/fw.c | 10 +- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 101 +++++++++--------- drivers/net/wireless/rtlwifi/rtl8192ce/led.c | 6 +- drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | 24 ++--- drivers/net/wireless/rtlwifi/rtl8192ce/phy.h | 3 +- drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 4 +- drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 116 ++++++++++----------- drivers/net/wireless/rtlwifi/usb.c | 12 +-- drivers/net/wireless/rtlwifi/wifi.h | 120 +++++++++++----------- 15 files changed, 321 insertions(+), 321 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index cf0b73e51fc2..1d6cc1f3c6bf 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -399,21 +399,21 @@ static void _rtl_query_protection_mode(struct ieee80211_hw *hw, u8 rate_flag = info->control.rates[0].flags; /* Common Settings */ - tcb_desc->b_rts_stbc = false; - tcb_desc->b_cts_enable = false; + tcb_desc->rts_stbc = false; + tcb_desc->cts_enable = false; tcb_desc->rts_sc = 0; - tcb_desc->b_rts_bw = false; - tcb_desc->b_rts_use_shortpreamble = false; - tcb_desc->b_rts_use_shortgi = false; + tcb_desc->rts_bw = false; + tcb_desc->rts_use_shortpreamble = false; + tcb_desc->rts_use_shortgi = false; if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) { /* Use CTS-to-SELF in protection mode. */ - tcb_desc->b_rts_enable = true; - tcb_desc->b_cts_enable = true; + tcb_desc->rts_enable = true; + tcb_desc->cts_enable = true; tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M]; } else if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) { /* Use RTS-CTS in protection mode. */ - tcb_desc->b_rts_enable = true; + tcb_desc->rts_enable = true; tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M]; } @@ -429,7 +429,7 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, if (mac->opmode == NL80211_IFTYPE_STATION) tcb_desc->ratr_index = 0; else if (mac->opmode == NL80211_IFTYPE_ADHOC) { - if (tcb_desc->b_multicast || tcb_desc->b_broadcast) { + if (tcb_desc->multicast || tcb_desc->broadcast) { tcb_desc->hw_rate = rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M]; tcb_desc->use_driver_rate = 1; @@ -439,7 +439,7 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, } } - if (rtlpriv->dm.b_useramask) { + if (rtlpriv->dm.useramask) { /* TODO we will differentiate adhoc and station futrue */ tcb_desc->mac_id = 0; @@ -461,19 +461,19 @@ static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - tcb_desc->b_packet_bw = false; + tcb_desc->packet_bw = false; if (!mac->bw_40 || !mac->ht_enable) return; - if (tcb_desc->b_multicast || tcb_desc->b_broadcast) + if (tcb_desc->multicast || tcb_desc->broadcast) return; /*use legency rate, shall use 20MHz */ if (tcb_desc->hw_rate <= rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M]) return; - tcb_desc->b_packet_bw = true; + tcb_desc->packet_bw = true; } static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw) @@ -545,9 +545,9 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw, } if (is_multicast_ether_addr(ieee80211_get_DA(hdr))) - tcb_desc->b_multicast = 1; + tcb_desc->multicast = 1; else if (is_broadcast_ether_addr(ieee80211_get_DA(hdr))) - tcb_desc->b_broadcast = 1; + tcb_desc->broadcast = 1; _rtl_txrate_selectmode(hw, tcb_desc); _rtl_query_bandwidth_mode(hw, tcb_desc); @@ -777,10 +777,10 @@ void rtl_watchdog_wq_callback(void *data) struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - bool b_busytraffic = false; - bool b_higher_busytraffic = false; - bool b_higher_busyrxtraffic = false; - bool b_higher_busytxtraffic = false; + bool busytraffic = false; + bool higher_busytraffic = false; + bool higher_busyrxtraffic = false; + bool higher_busytxtraffic = false; u8 idx = 0; u32 rx_cnt_inp4eriod = 0; @@ -788,7 +788,7 @@ void rtl_watchdog_wq_callback(void *data) u32 aver_rx_cnt_inperiod = 0; u32 aver_tx_cnt_inperiod = 0; - bool benter_ps = false; + bool enter_ps = false; if (is_hal_stop(rtlhal)) return; @@ -832,29 +832,29 @@ void rtl_watchdog_wq_callback(void *data) /* (2) check traffic busy */ if (aver_rx_cnt_inperiod > 100 || aver_tx_cnt_inperiod > 100) - b_busytraffic = true; + busytraffic = true; /* Higher Tx/Rx data. */ if (aver_rx_cnt_inperiod > 4000 || aver_tx_cnt_inperiod > 4000) { - b_higher_busytraffic = true; + higher_busytraffic = true; /* Extremely high Rx data. */ if (aver_rx_cnt_inperiod > 5000) - b_higher_busyrxtraffic = true; + higher_busyrxtraffic = true; else - b_higher_busytxtraffic = false; + higher_busytxtraffic = false; } if (((rtlpriv->link_info.num_rx_inperiod + rtlpriv->link_info.num_tx_inperiod) > 8) || (rtlpriv->link_info.num_rx_inperiod > 2)) - benter_ps = false; + enter_ps = false; else - benter_ps = true; + enter_ps = true; /* LeisurePS only work in infra mode. */ - if (benter_ps) + if (enter_ps) rtl_lps_enter(hw); else rtl_lps_leave(hw); @@ -863,9 +863,9 @@ void rtl_watchdog_wq_callback(void *data) rtlpriv->link_info.num_rx_inperiod = 0; rtlpriv->link_info.num_tx_inperiod = 0; - rtlpriv->link_info.b_busytraffic = b_busytraffic; - rtlpriv->link_info.b_higher_busytraffic = b_higher_busytraffic; - rtlpriv->link_info.b_higher_busyrxtraffic = b_higher_busyrxtraffic; + rtlpriv->link_info.busytraffic = busytraffic; + rtlpriv->link_info.higher_busytraffic = higher_busytraffic; + rtlpriv->link_info.higher_busyrxtraffic = higher_busyrxtraffic; } diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 25d2d667ffba..2d1e3e833568 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -666,7 +666,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, (u8 *) (&basic_rates)); - if (rtlpriv->dm.b_useramask) + if (rtlpriv->dm.useramask) rtlpriv->cfg->ops->update_rate_mask(hw, 0); else rtlpriv->cfg->ops->update_rate_table(hw); @@ -681,7 +681,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, */ if (changed & BSS_CHANGED_ASSOC) { if (bss_conf->assoc) { - if (ppsc->b_fwctrl_lps) { + if (ppsc->fwctrl_lps) { u8 mstatus = RT_MEDIA_CONNECT; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_JOINBSSRPT, @@ -689,7 +689,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, ppsc->report_linked = true; } } else { - if (ppsc->b_fwctrl_lps) { + if (ppsc->fwctrl_lps) { u8 mstatus = RT_MEDIA_DISCONNECT; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_JOINBSSRPT, @@ -818,7 +818,7 @@ static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw) /* fix fwlps issue */ rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); - if (rtlpriv->dm.b_useramask) + if (rtlpriv->dm.useramask) rtlpriv->cfg->ops->update_rate_mask(hw, 0); else rtlpriv->cfg->ops->update_rate_table(hw); diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index a508ea51a1f8..2da164380771 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -50,7 +50,7 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw) u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; ppsc->reg_rfps_level = 0; - ppsc->b_support_aspm = 0; + ppsc->support_aspm = 0; /*Update PCI ASPM setting */ ppsc->const_amdpci_aspm = rtlpci->const_amdpci_aspm; @@ -115,29 +115,29 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw) switch (rtlpci->const_support_pciaspm) { case 0:{ /*Not support ASPM. */ - bool b_support_aspm = false; - ppsc->b_support_aspm = b_support_aspm; + bool support_aspm = false; + ppsc->support_aspm = support_aspm; break; } case 1:{ /*Support ASPM. */ - bool b_support_aspm = true; - bool b_support_backdoor = true; - ppsc->b_support_aspm = b_support_aspm; + bool support_aspm = true; + bool support_backdoor = true; + ppsc->support_aspm = support_aspm; /*if(priv->oem_id == RT_CID_TOSHIBA && !priv->ndis_adapter.amd_l1_patch) - b_support_backdoor = false; */ + support_backdoor = false; */ - ppsc->b_support_backdoor = b_support_backdoor; + ppsc->support_backdoor = support_backdoor; break; } case 2: /*ASPM value set by chipset. */ if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) { - bool b_support_aspm = true; - ppsc->b_support_aspm = b_support_aspm; + bool support_aspm = true; + ppsc->support_aspm = support_aspm; } break; default: @@ -585,7 +585,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) hdr = (struct ieee80211_hdr *)(skb->data); fc = le16_to_cpu(hdr->frame_control); - if (!stats.b_crc) { + if (!stats.crc) { memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); @@ -890,17 +890,17 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw, rtlhal->hw = hw; rtlpci->pdev = pdev; - ppsc->b_inactiveps = false; - ppsc->b_leisure_ps = true; - ppsc->b_fwctrl_lps = true; - ppsc->b_reg_fwctrl_lps = 3; + ppsc->inactiveps = false; + ppsc->leisure_ps = true; + ppsc->fwctrl_lps = true; + ppsc->reg_fwctrl_lps = 3; ppsc->reg_max_lps_awakeintvl = 5; - if (ppsc->b_reg_fwctrl_lps == 1) + if (ppsc->reg_fwctrl_lps == 1) ppsc->fwctrl_psmode = FW_PS_MIN_MODE; - else if (ppsc->b_reg_fwctrl_lps == 2) + else if (ppsc->reg_fwctrl_lps == 2) ppsc->fwctrl_psmode = FW_PS_MAX_MODE; - else if (ppsc->b_reg_fwctrl_lps == 3) + else if (ppsc->reg_fwctrl_lps == 3) ppsc->fwctrl_psmode = FW_PS_DTIM_MODE; /*Tx/Rx related var */ diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index d2326c13449e..6b7e217b6b89 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -86,7 +86,7 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); enum rf_pwrstate rtstate; - bool b_actionallowed = false; + bool actionallowed = false; u16 rfwait_cnt = 0; unsigned long flag; @@ -139,13 +139,13 @@ no_protect: ppsc->rfoff_reason &= (~changesource); if ((changesource == RF_CHANGE_BY_HW) && - (ppsc->b_hwradiooff == true)) { - ppsc->b_hwradiooff = false; + (ppsc->hwradiooff == true)) { + ppsc->hwradiooff = false; } if (!ppsc->rfoff_reason) { ppsc->rfoff_reason = 0; - b_actionallowed = true; + actionallowed = true; } break; @@ -153,17 +153,17 @@ no_protect: case ERFOFF: if ((changesource == RF_CHANGE_BY_HW) - && (ppsc->b_hwradiooff == false)) { - ppsc->b_hwradiooff = true; + && (ppsc->hwradiooff == false)) { + ppsc->hwradiooff = true; } ppsc->rfoff_reason |= changesource; - b_actionallowed = true; + actionallowed = true; break; case ERFSLEEP: ppsc->rfoff_reason |= changesource; - b_actionallowed = true; + actionallowed = true; break; default: @@ -172,7 +172,7 @@ no_protect: break; } - if (b_actionallowed) + if (actionallowed) rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset); if (!protect_or_not) { @@ -181,7 +181,7 @@ no_protect: spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); } - return b_actionallowed; + return actionallowed; } EXPORT_SYMBOL(rtl_ps_set_rf_state); @@ -191,7 +191,7 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw) struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - ppsc->b_swrf_processing = true; + ppsc->swrf_processing = true; if (ppsc->inactive_pwrstate == ERFON && rtlhal->interface == INTF_PCI) { if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && @@ -213,7 +213,7 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw) } } - ppsc->b_swrf_processing = false; + ppsc->swrf_processing = false; } void rtl_ips_nic_off_wq_callback(void *data) @@ -239,13 +239,13 @@ void rtl_ips_nic_off_wq_callback(void *data) if (rtlpriv->sec.being_setkey) return; - if (ppsc->b_inactiveps) { + if (ppsc->inactiveps) { rtstate = ppsc->rfpwr_state; /* *Do not enter IPS in the following conditions: *(1) RF is already OFF or Sleep - *(2) b_swrf_processing (indicates the IPS is still under going) + *(2) swrf_processing (indicates the IPS is still under going) *(3) Connectted (only disconnected can trigger IPS) *(4) IBSS (send Beacon) *(5) AP mode (send Beacon) @@ -253,14 +253,14 @@ void rtl_ips_nic_off_wq_callback(void *data) */ if (rtstate == ERFON && - !ppsc->b_swrf_processing && + !ppsc->swrf_processing && (mac->link_state == MAC80211_NOLINK) && !mac->act_scanning) { RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("IPSEnter(): Turn off RF.\n")); ppsc->inactive_pwrstate = ERFOFF; - ppsc->b_in_powersavemode = true; + ppsc->in_powersavemode = true; /*rtl_pci_reset_trx_ring(hw); */ _rtl_ps_inactive_ps(hw); @@ -290,15 +290,15 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw) spin_lock_irqsave(&rtlpriv->locks.ips_lock, flags); - if (ppsc->b_inactiveps) { + if (ppsc->inactiveps) { rtstate = ppsc->rfpwr_state; if (rtstate != ERFON && - !ppsc->b_swrf_processing && + !ppsc->swrf_processing && ppsc->rfoff_reason <= RF_CHANGE_BY_IPS) { ppsc->inactive_pwrstate = ERFON; - ppsc->b_in_powersavemode = false; + ppsc->in_powersavemode = false; _rtl_ps_inactive_ps(hw); } @@ -370,9 +370,9 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) * mode and set RPWM to turn RF on. */ - if ((ppsc->b_fwctrl_lps) && (ppsc->b_leisure_ps) && + if ((ppsc->fwctrl_lps) && (ppsc->leisure_ps) && ppsc->report_linked) { - bool b_fw_current_inps; + bool fw_current_inps; if (ppsc->dot11_psmode == EACTIVE) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, ("FW LPS leave ps_mode:%x\n", @@ -385,11 +385,11 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, (u8 *) (&fw_pwrmode)); - b_fw_current_inps = false; + fw_current_inps = false; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, - (u8 *) (&b_fw_current_inps)); + (u8 *) (&fw_current_inps)); } else { if (rtl_get_fwlps_doze(hw)) { @@ -398,10 +398,10 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) ppsc->fwctrl_psmode)); rpwm_val = 0x02; /* RF off */ - b_fw_current_inps = true; + fw_current_inps = true; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, - (u8 *) (&b_fw_current_inps)); + (u8 *) (&fw_current_inps)); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, (u8 *) (&ppsc->fwctrl_psmode)); @@ -425,13 +425,13 @@ void rtl_lps_enter(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); unsigned long flag; - if (!(ppsc->b_fwctrl_lps && ppsc->b_leisure_ps)) + if (!(ppsc->fwctrl_lps && ppsc->leisure_ps)) return; if (rtlpriv->sec.being_setkey) return; - if (rtlpriv->link_info.b_busytraffic) + if (rtlpriv->link_info.busytraffic) return; /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */ @@ -446,7 +446,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw) spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); - if (ppsc->b_leisure_ps) { + if (ppsc->leisure_ps) { /* Idle for a while if we connect to AP a while ago. */ if (mac->cnt_after_linked >= 2) { if (ppsc->dot11_psmode == EACTIVE) { @@ -470,7 +470,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw) spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); - if (ppsc->b_fwctrl_lps && ppsc->b_leisure_ps) { + if (ppsc->fwctrl_lps && ppsc->leisure_ps) { if (ppsc->dot11_psmode != EACTIVE) { /*FIX ME */ diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index b08b7802f04f..b4f1e4e6b733 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -306,13 +306,13 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; - bool b_multi_sta = false; + bool multi_sta = false; if (mac->opmode == NL80211_IFTYPE_ADHOC) - b_multi_sta = true; + multi_sta = true; - if ((b_multi_sta == false) || (dm_digtable.cursta_connectctate != - DIG_STA_DISCONNECT)) { + if ((multi_sta == false) || (dm_digtable.cursta_connectctate != + DIG_STA_DISCONNECT)) { binitialized = false; dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; return; @@ -479,7 +479,7 @@ static void rtl92c_dm_dig(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - if (rtlpriv->dm.b_dm_initialgain_enable == false) + if (rtlpriv->dm.dm_initialgain_enable == false) return; if (dm_digtable.dig_enable_flag == false) return; @@ -492,7 +492,7 @@ static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - rtlpriv->dm.bdynamic_txpower_enable = false; + rtlpriv->dm.dynamic_txpower_enable = false; rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; @@ -550,9 +550,9 @@ static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw) void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - rtlpriv->dm.bcurrent_turbo_edca = false; - rtlpriv->dm.bis_any_nonbepkts = false; - rtlpriv->dm.bis_cur_rdlstate = false; + rtlpriv->dm.current_turbo_edca = false; + rtlpriv->dm.is_any_nonbepkts = false; + rtlpriv->dm.is_cur_rdlstate = false; } static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) @@ -570,7 +570,7 @@ static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) goto dm_checkedcaturbo_exit; if (mac->link_state != MAC80211_LINKED) { - rtlpriv->dm.bcurrent_turbo_edca = false; + rtlpriv->dm.current_turbo_edca = false; return; } @@ -582,40 +582,40 @@ static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) edca_be_dl |= 0x005e0000; } - if ((!rtlpriv->dm.bis_any_nonbepkts) && - (!rtlpriv->dm.b_disable_framebursting)) { + if ((!rtlpriv->dm.is_any_nonbepkts) && + (!rtlpriv->dm.disable_framebursting)) { cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; if (cur_rxok_cnt > 4 * cur_txok_cnt) { - if (!rtlpriv->dm.bis_cur_rdlstate || - !rtlpriv->dm.bcurrent_turbo_edca) { + if (!rtlpriv->dm.is_cur_rdlstate || + !rtlpriv->dm.current_turbo_edca) { rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, edca_be_dl); - rtlpriv->dm.bis_cur_rdlstate = true; + rtlpriv->dm.is_cur_rdlstate = true; } } else { - if (rtlpriv->dm.bis_cur_rdlstate || - !rtlpriv->dm.bcurrent_turbo_edca) { + if (rtlpriv->dm.is_cur_rdlstate || + !rtlpriv->dm.current_turbo_edca) { rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, edca_be_ul); - rtlpriv->dm.bis_cur_rdlstate = false; + rtlpriv->dm.is_cur_rdlstate = false; } } - rtlpriv->dm.bcurrent_turbo_edca = true; + rtlpriv->dm.current_turbo_edca = true; } else { - if (rtlpriv->dm.bcurrent_turbo_edca) { + if (rtlpriv->dm.current_turbo_edca) { u8 tmp = AC0_BE; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, (u8 *) (&tmp)); - rtlpriv->dm.bcurrent_turbo_edca = false; + rtlpriv->dm.current_turbo_edca = false; } } dm_checkedcaturbo_exit: - rtlpriv->dm.bis_any_nonbepkts = false; + rtlpriv->dm.is_any_nonbepkts = false; last_txok_cnt = rtlpriv->stats.txbytesunicast; last_rxok_cnt = rtlpriv->stats.rxbytesunicast; } @@ -636,7 +636,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw u8 txpwr_level[2] = {0, 0}; u8 ofdm_min_index = 6, rf; - rtlpriv->dm.btxpower_trackingInit = true; + rtlpriv->dm.txpower_trackingInit = true; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n")); @@ -696,7 +696,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK; for (i = 0; i < CCK_TABLE_LENGTH; i++) { - if (rtlpriv->dm.b_cck_inch14) { + if (rtlpriv->dm.cck_inch14) { if (memcmp((void *)&temp_cck, (void *)&cckswing_table_ch14[i][2], 4) == 0) { @@ -708,7 +708,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw "cck_index=0x%x, ch 14 %d\n", RCCK0_TXFILTER2, temp_cck, cck_index_old, - rtlpriv->dm.b_cck_inch14)); + rtlpriv->dm.cck_inch14)); break; } } else { @@ -724,7 +724,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw "cck_index=0x%x, ch14 %d\n", RCCK0_TXFILTER2, temp_cck, cck_index_old, - rtlpriv->dm.b_cck_inch14)); + rtlpriv->dm.cck_inch14)); break; } } @@ -937,7 +937,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw BIT(31) | BIT(29), 0x00); } - if (!rtlpriv->dm.b_cck_inch14) { + if (!rtlpriv->dm.cck_inch14) { rtl_write_byte(rtlpriv, 0xa22, cckswing_table_ch1ch13[cck_index] [0]); @@ -1057,12 +1057,12 @@ static void rtl92c_dm_initialize_txpower_tracking_thermalmeter( { struct rtl_priv *rtlpriv = rtl_priv(hw); - rtlpriv->dm.btxpower_tracking = true; - rtlpriv->dm.btxpower_trackingInit = false; + rtlpriv->dm.txpower_tracking = true; + rtlpriv->dm.txpower_trackingInit = false; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("pMgntInfo->btxpower_tracking = %d\n", - rtlpriv->dm.btxpower_tracking)); + ("pMgntInfo->txpower_tracking = %d\n", + rtlpriv->dm.txpower_tracking)); } static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) @@ -1081,7 +1081,7 @@ static void rtl92c_dm_check_txpower_tracking_thermal_meter( struct rtl_priv *rtlpriv = rtl_priv(hw); static u8 tm_trigger; - if (!rtlpriv->dm.btxpower_tracking) + if (!rtlpriv->dm.txpower_tracking) return; if (!tm_trigger) { @@ -1113,9 +1113,9 @@ void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) p_ra->pre_ratr_state = DM_RATR_STA_INIT; if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) - rtlpriv->dm.b_useramask = true; + rtlpriv->dm.useramask = true; else - rtlpriv->dm.b_useramask = false; + rtlpriv->dm.useramask = false; } @@ -1133,7 +1133,7 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) return; } - if (!rtlpriv->dm.b_useramask) { + if (!rtlpriv->dm.useramask) { RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, ("<---- driver does not control rate adaptive mask\n")); return; @@ -1365,16 +1365,16 @@ void rtl92c_dm_watchdog(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - bool b_fw_current_inpsmode = false; - bool b_fw_ps_awake = true; + bool fw_current_inpsmode = false; + bool fw_ps_awake = true; rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, - (u8 *) (&b_fw_current_inpsmode)); + (u8 *) (&fw_current_inpsmode)); rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, - (u8 *) (&b_fw_ps_awake)); + (u8 *) (&fw_ps_awake)); - if ((ppsc->rfpwr_state == ERFON) && ((!b_fw_current_inpsmode) && - b_fw_ps_awake) + if ((ppsc->rfpwr_state == ERFON) && ((!fw_current_inpsmode) && + fw_ps_awake) && (!ppsc->rfchange_inprogress)) { rtl92c_dm_pwdb_monitor(hw); rtl92c_dm_dig(hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c index ddf0a41a7a81..888df5e2d2fc 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c @@ -44,7 +44,7 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); long undecorated_smoothed_pwdb; - if (!rtlpriv->dm.bdynamic_txpower_enable) + if (!rtlpriv->dm.dynamic_txpower_enable) return; if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c index b0776a34b817..11c8bdb4af59 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c @@ -316,12 +316,12 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, while (true) { spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); - if (rtlhal->b_h2c_setinprogress) { + if (rtlhal->h2c_setinprogress) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("H2C set in progress! Wait to set.." "element_id(%d).\n", element_id)); - while (rtlhal->b_h2c_setinprogress) { + while (rtlhal->h2c_setinprogress) { spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); h2c_waitcounter++; @@ -337,7 +337,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, } spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); } else { - rtlhal->b_h2c_setinprogress = true; + rtlhal->h2c_setinprogress = true; spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); break; } @@ -493,7 +493,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, } spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); - rtlhal->b_h2c_setinprogress = false; + rtlhal->h2c_setinprogress = false; spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n")); @@ -505,7 +505,7 @@ void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u32 tmp_cmdbuf[2]; - if (rtlhal->bfw_ready == false) { + if (rtlhal->fw_ready == false) { RT_ASSERT(false, ("return H2C cmd because of Fw " "download fail!!!\n")); return; diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 0e280995aace..7a1bfa92375f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -124,7 +124,7 @@ void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; } case HW_VAR_FW_PSMODE_STATUS: - *((bool *) (val)) = ppsc->b_fw_current_inpsmode; + *((bool *) (val)) = ppsc->fw_current_inpsmode; break; case HW_VAR_CORRECT_TSF:{ u64 tsf; @@ -173,15 +173,15 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; } case HW_VAR_BASIC_RATE:{ - u16 b_rate_cfg = ((u16 *) val)[0]; + u16 rate_cfg = ((u16 *) val)[0]; u8 rate_index = 0; - b_rate_cfg = b_rate_cfg & 0x15f; - b_rate_cfg |= 0x01; - rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff); + rate_cfg &= 0x15f; + rate_cfg |= 0x01; + rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff); rtl_write_byte(rtlpriv, REG_RRSR + 1, - (b_rate_cfg >> 8)&0xff); - while (b_rate_cfg > 0x1) { - b_rate_cfg = (b_rate_cfg >> 1); + (rate_cfg >> 8)&0xff); + while (rate_cfg > 0x1) { + rate_cfg = (rate_cfg >> 1); rate_index++; } rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, @@ -469,12 +469,12 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; } case HW_VAR_FW_PSMODE_STATUS: - ppsc->b_fw_current_inpsmode = *((bool *) val); + ppsc->fw_current_inpsmode = *((bool *) val); break; case HW_VAR_H2C_FW_JOINBSSRPT:{ u8 mstatus = (*(u8 *) val); u8 tmp_regcr, tmp_reg422; - bool b_recover = false; + bool recover = false; if (mstatus == RT_MEDIA_CONNECT) { rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, @@ -491,7 +491,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); if (tmp_reg422 & BIT(6)) - b_recover = true; + recover = true; rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422 & (~BIT(6))); @@ -500,7 +500,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0); _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4)); - if (b_recover) { + if (recover) { rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422); @@ -868,7 +868,7 @@ static void _rtl92ce_enable_aspm_back_door(struct ieee80211_hw *hw) rtl_write_word(rtlpriv, 0x350, 0x870c); rtl_write_byte(rtlpriv, 0x352, 0x1); - if (ppsc->b_support_backdoor) + if (ppsc->support_backdoor) rtl_write_byte(rtlpriv, 0x349, 0x1b); else rtl_write_byte(rtlpriv, 0x349, 0x03); @@ -940,10 +940,10 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) ("Failed to download FW. Init HW " "without FW now..\n")); err = 1; - rtlhal->bfw_ready = false; + rtlhal->fw_ready = false; return err; } else { - rtlhal->bfw_ready = true; + rtlhal->fw_ready = true; } rtlhal->last_hmeboxnum = 0; @@ -1237,7 +1237,7 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0); - if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->bfw_ready) + if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready) rtl92c_firmware_selfreset(hw); rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51); rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); @@ -1555,7 +1555,7 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, rtlefuse->eeprom_thermalmeter = (tempval & 0x1f); if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail) - rtlefuse->b_apk_thermalmeterignore = true; + rtlefuse->apk_thermalmeterignore = true; rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; RTPRINT(rtlpriv, FINIT, INIT_TxPower, @@ -1612,7 +1612,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; - rtlefuse->b_txpwr_fromeprom = true; + rtlefuse->txpwr_fromeprom = true; rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, @@ -1655,7 +1655,7 @@ static void _rtl92ce_hal_customized_behavior(struct ieee80211_hw *hw) switch (rtlhal->oem_id) { case RT_CID_819x_HP: - pcipriv->ledctl.bled_opendrain = true; + pcipriv->ledctl.led_opendrain = true; break; case RT_CID_819x_Lenovo: case RT_CID_DEFAULT: @@ -1680,10 +1680,10 @@ void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw) rtlhal->version = _rtl92ce_read_chip_version(hw); if (get_rf_type(rtlphy) == RF_1T1R) - rtlpriv->dm.brfpath_rxenable[0] = true; + rtlpriv->dm.rfpath_rxenable[0] = true; else - rtlpriv->dm.brfpath_rxenable[0] = - rtlpriv->dm.brfpath_rxenable[1] = true; + rtlpriv->dm.rfpath_rxenable[0] = + rtlpriv->dm.rfpath_rxenable[1] = true; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n", rtlhal->version)); tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); @@ -1714,13 +1714,13 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw) u32 ratr_value = (u32) mac->basic_rates; u8 *p_mcsrate = mac->mcs; u8 ratr_index = 0; - u8 b_nmode = mac->ht_enable; + u8 nmode = mac->ht_enable; u8 mimo_ps = 1; u16 shortgi_rate; u32 tmp_ratr_value; - u8 b_curtxbw_40mhz = mac->bw_40; - u8 b_curshortgi_40mhz = mac->sgi_40; - u8 b_curshortgi_20mhz = mac->sgi_20; + u8 curtxbw_40mhz = mac->bw_40; + u8 curshortgi_40mhz = mac->sgi_40; + u8 curshortgi_20mhz = mac->sgi_20; enum wireless_mode wirelessmode = mac->mode; ratr_value |= EF2BYTE((*(u16 *) (p_mcsrate))) << 12; @@ -1737,7 +1737,7 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw) break; case WIRELESS_MODE_N_24G: case WIRELESS_MODE_N_5G: - b_nmode = 1; + nmode = 1; if (mimo_ps == 0) { ratr_value &= 0x0007F005; } else { @@ -1763,9 +1763,8 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw) ratr_value &= 0x0FFFFFFF; - if (b_nmode && ((b_curtxbw_40mhz && - b_curshortgi_40mhz) || (!b_curtxbw_40mhz && - b_curshortgi_20mhz))) { + if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) || (!curtxbw_40mhz && + curshortgi_20mhz))) { ratr_value |= 0x10000000; tmp_ratr_value = (ratr_value >> 12); @@ -1793,11 +1792,11 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) u32 ratr_bitmap = (u32) mac->basic_rates; u8 *p_mcsrate = mac->mcs; u8 ratr_index; - u8 b_curtxbw_40mhz = mac->bw_40; - u8 b_curshortgi_40mhz = mac->sgi_40; - u8 b_curshortgi_20mhz = mac->sgi_20; + u8 curtxbw_40mhz = mac->bw_40; + u8 curshortgi_40mhz = mac->sgi_40; + u8 curshortgi_20mhz = mac->sgi_20; enum wireless_mode wirelessmode = mac->mode; - bool b_shortgi = false; + bool shortgi = false; u8 rate_mask[5]; u8 macid = 0; u8 mimops = 1; @@ -1839,7 +1838,7 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) } else { if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_1T1R) { - if (b_curtxbw_40mhz) { + if (curtxbw_40mhz) { if (rssi_level == 1) ratr_bitmap &= 0x000f0000; else if (rssi_level == 2) @@ -1855,7 +1854,7 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) ratr_bitmap &= 0x000ff005; } } else { - if (b_curtxbw_40mhz) { + if (curtxbw_40mhz) { if (rssi_level == 1) ratr_bitmap &= 0x0f0f0000; else if (rssi_level == 2) @@ -1873,13 +1872,13 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) } } - if ((b_curtxbw_40mhz && b_curshortgi_40mhz) || - (!b_curtxbw_40mhz && b_curshortgi_20mhz)) { + if ((curtxbw_40mhz && curshortgi_40mhz) || + (!curtxbw_40mhz && curshortgi_20mhz)) { if (macid == 0) - b_shortgi = true; + shortgi = true; else if (macid == 1) - b_shortgi = false; + shortgi = false; } break; default: @@ -1895,7 +1894,7 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) ("ratr_bitmap :%x\n", ratr_bitmap)); *(u32 *)&rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) | (ratr_index << 28)); - rate_mask[4] = macid | (b_shortgi ? 0x20 : 0x00) | 0x80; + rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, " "ratr_val:%x, %x:%x:%x:%x:%x\n", ratr_index, ratr_bitmap, @@ -1927,13 +1926,13 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate; u8 u1tmp; - bool b_actuallyset = false; + bool actuallyset = false; unsigned long flag; if ((rtlpci->up_first_time == 1) || (rtlpci->being_init_adapter)) return false; - if (ppsc->b_swrf_processing) + if (ppsc->swrf_processing) return false; spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); @@ -1959,24 +1958,24 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; - if ((ppsc->b_hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) { + if ((ppsc->hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, ("GPIOChangeRF - HW Radio ON, RF ON\n")); e_rfpowerstate_toset = ERFON; - ppsc->b_hwradiooff = false; - b_actuallyset = true; - } else if ((ppsc->b_hwradiooff == false) + ppsc->hwradiooff = false; + actuallyset = true; + } else if ((ppsc->hwradiooff == false) && (e_rfpowerstate_toset == ERFOFF)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, ("GPIOChangeRF - HW Radio OFF, RF OFF\n")); e_rfpowerstate_toset = ERFOFF; - ppsc->b_hwradiooff = true; - b_actuallyset = true; + ppsc->hwradiooff = true; + actuallyset = true; } - if (b_actuallyset) { + if (actuallyset) { if (e_rfpowerstate_toset == ERFON) { if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) { @@ -2015,7 +2014,7 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) } *valid = 1; - return !ppsc->b_hwradiooff; + return !ppsc->hwradiooff; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c index 78a0569208ea..7b1da8d7508f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c @@ -57,7 +57,7 @@ void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) ("switch case not process\n")); break; } - pled->b_ledon = true; + pled->ledon = true; } void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) @@ -76,7 +76,7 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; case LED_PIN_LED0: ledcfg &= 0xf0; - if (pcipriv->ledctl.bled_opendrain == true) + if (pcipriv->ledctl.led_opendrain == true) rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(1) | BIT(5) | BIT(6))); else @@ -92,7 +92,7 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) ("switch case not process\n")); break; } - pled->b_ledon = false; + pled->ledon = false; } void rtl92ce_init_sw_leds(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 05f7a45b30e1..4b256d0bebcc 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -330,7 +330,7 @@ bool rtl92c_phy_bb_config(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); u16 regval; u32 regvaldw; - u8 b_reg_hwparafile = 1; + u8 reg_hwparafile = 1; _rtl92c_phy_init_bb_rf_register_definition(hw); regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); @@ -345,7 +345,7 @@ bool rtl92c_phy_bb_config(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0); rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23)); - if (b_reg_hwparafile == 1) + if (reg_hwparafile == 1) rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); return rtstatus; } @@ -388,7 +388,7 @@ static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n")); return false; } - rtlphy->bcck_high_power = (bool) (rtl_get_bbreg(hw, + rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, 0x200)); return true; @@ -954,7 +954,7 @@ void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); u8 cckpowerlevel[2], ofdmpowerlevel[2]; - if (rtlefuse->b_txpwr_fromeprom == false) + if (rtlefuse->txpwr_fromeprom == false) return; _rtl92c_get_txpower_index(hw, channel, &cckpowerlevel[0], &ofdmpowerlevel[0]); @@ -1437,7 +1437,7 @@ static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw) } static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, - bool b_iqk_ok, long result[][8], + bool iqk_ok, long result[][8], u8 final_candidate, bool btxonly) { u32 oldval_0, x, tx0_a, reg; @@ -1445,7 +1445,7 @@ static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, if (final_candidate == 0xFF) return; - else if (b_iqk_ok) { + else if (iqk_ok) { oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD) >> 22) & 0x3FF; x = result[final_candidate][0]; @@ -1477,7 +1477,7 @@ static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, } static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, - bool b_iqk_ok, long result[][8], + bool iqk_ok, long result[][8], u8 final_candidate, bool btxonly) { u32 oldval_1, x, tx1_a, reg; @@ -1485,7 +1485,7 @@ static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, if (final_candidate == 0xFF) return; - else if (b_iqk_ok) { + else if (iqk_ok) { oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, MASKDWORD) >> 22) & 0x3FF; x = result[final_candidate][4]; @@ -1698,11 +1698,11 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, } _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t); if (t == 0) { - rtlphy->b_rfpi_enable = (u8) rtl_get_bbreg(hw, + rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, BIT(8)); } - if (!rtlphy->b_rfpi_enable) + if (!rtlphy->rfpi_enable) _rtl92c_phy_pi_mode_switch(hw, true); if (t == 0) { rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); @@ -1783,7 +1783,7 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, if (is2t) rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); if (t != 0) { - if (!rtlphy->b_rfpi_enable) + if (!rtlphy->rfpi_enable) _rtl92c_phy_pi_mode_switch(hw, false); _rtl92c_phy_reload_adda_registers(hw, adda_reg, rtlphy->adda_backup, 16); @@ -2370,7 +2370,7 @@ void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - if (rtlphy->b_apk_done) + if (rtlphy->apk_done) return; if (IS_92C_SERIAL(rtlhal->version)) _rtl92c_phy_ap_calibrate(hw, delta, true); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h index ca4daee6e9a8..4bdeb998ba82 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h @@ -80,7 +80,7 @@ #define RTL92C_MAX_PATH_NUM 2 #define CHANNEL_MAX_NUMBER 14 #define CHANNEL_GROUP_MAX 3 - +#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255 enum swchnlcmd_id { CMDID_END, CMDID_SET_TXPOWEROWER_LEVEL, @@ -233,5 +233,6 @@ void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw); void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); void rtl92c_phy_set_io(struct ieee80211_hw *hw); +void rtl92c_bb_block_on(struct ieee80211_hw *hw); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index 40ae618a0262..b4df0b332832 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -46,9 +46,9 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - rtlpriv->dm.b_dm_initialgain_enable = 1; + rtlpriv->dm.dm_initialgain_enable = 1; rtlpriv->dm.dm_flag = 0; - rtlpriv->dm.b_disable_framebursting = 0;; + rtlpriv->dm.disable_framebursting = 0; rtlpriv->dm.thermalvalue = 0; rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 003bf108193f..58d7d36924e8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -245,9 +245,9 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, struct rtl_stats *pstats, struct rx_desc_92c *pdesc, struct rx_fwinfo_92c *p_drvinfo, - bool bpacket_match_bssid, - bool bpacket_toself, - bool b_packet_beacon) + bool packet_match_bssid, + bool packet_toself, + bool packet_beacon) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct phy_sts_cck_8192s_t *cck_buf; @@ -258,11 +258,11 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, bool is_cck_rate; is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); - pstats->b_packet_matchbssid = bpacket_match_bssid; - pstats->b_packet_toself = bpacket_toself; - pstats->b_is_cck = is_cck_rate; - pstats->b_packet_beacon = b_packet_beacon; - pstats->b_is_cck = is_cck_rate; + pstats->packet_matchbssid = packet_match_bssid; + pstats->packet_toself = packet_toself; + pstats->is_cck = is_cck_rate; + pstats->packet_beacon = packet_beacon; + pstats->is_cck = is_cck_rate; pstats->rx_mimo_signalquality[0] = -1; pstats->rx_mimo_signalquality[1] = -1; @@ -315,7 +315,7 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, pstats->rx_pwdb_all = pwdb_all; pstats->recvsignalpower = rx_pwr_all; - if (bpacket_match_bssid) { + if (packet_match_bssid) { u8 sq; if (pstats->rx_pwdb_all > 40) sq = 100; @@ -334,10 +334,10 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, pstats->rx_mimo_signalquality[1] = -1; } } else { - rtlpriv->dm.brfpath_rxenable[0] = - rtlpriv->dm.brfpath_rxenable[1] = true; + rtlpriv->dm.rfpath_rxenable[0] = + rtlpriv->dm.rfpath_rxenable[1] = true; for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) { - if (rtlpriv->dm.brfpath_rxenable[i]) + if (rtlpriv->dm.rfpath_rxenable[i]) rf_rx_num++; rx_pwr[i] = @@ -347,7 +347,7 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, rtlpriv->stats.rx_snr_db[i] = (long)(p_drvinfo->rxsnr[i] / 2); - if (bpacket_match_bssid) + if (packet_match_bssid) pstats->rx_mimo_signalstrength[i] = (u8) rssi; } @@ -366,7 +366,7 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, for (i = 0; i < max_spatial_stream; i++) { evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]); - if (bpacket_match_bssid) { + if (packet_match_bssid) { if (i == 0) pstats->signalquality = (u8) (evm & 0xff); @@ -393,7 +393,7 @@ static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw, u8 rfpath; u32 last_rssi, tmpval; - if (pstats->b_packet_toself || pstats->b_packet_beacon) { + if (pstats->packet_toself || pstats->packet_beacon) { rtlpriv->stats.rssi_calculate_cnt++; if (rtlpriv->stats.ui_rssi.total_num++ >= @@ -421,7 +421,7 @@ static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw, pstats->rssi = rtlpriv->stats.signal_strength; } - if (!pstats->b_is_cck && pstats->b_packet_toself) { + if (!pstats->is_cck && pstats->packet_toself) { for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; rfpath++) { @@ -493,7 +493,7 @@ static void _rtl92ce_process_pwdb(struct ieee80211_hw *hw, rtlpriv->dm.undecorated_smoothed_pwdb; } - if (pstats->b_packet_toself || pstats->b_packet_beacon) { + if (pstats->packet_toself || pstats->packet_beacon) { if (undecorated_smoothed_pwdb < 0) undecorated_smoothed_pwdb = pstats->rx_pwdb_all; @@ -525,7 +525,7 @@ static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw, u32 last_evm, n_spatialstream, tmpval; if (pstats->signalquality != 0) { - if (pstats->b_packet_toself || pstats->b_packet_beacon) { + if (pstats->packet_toself || pstats->packet_beacon) { if (rtlpriv->stats.ui_link_quality.total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX) { @@ -595,8 +595,8 @@ static void _rtl92ce_process_phyinfo(struct ieee80211_hw *hw, struct rtl_stats *pcurrent_stats) { - if (!pcurrent_stats->b_packet_matchbssid && - !pcurrent_stats->b_packet_beacon) + if (!pcurrent_stats->packet_matchbssid && + !pcurrent_stats->packet_beacon) return; _rtl92ce_process_ui_rssi(hw, pcurrent_stats); @@ -618,7 +618,7 @@ static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw, u8 *praddr; u8 *psaddr; u16 fc, type; - bool b_packet_matchbssid, b_packet_toself, b_packet_beacon; + bool packet_matchbssid, packet_toself, packet_beacon; tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; @@ -628,23 +628,23 @@ static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw, praddr = hdr->addr1; psaddr = hdr->addr2; - b_packet_matchbssid = + packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && (!compare_ether_addr(mac->bssid, (fc & IEEE80211_FCTL_TODS) ? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : hdr->addr3)) && - (!pstats->b_hwerror) && (!pstats->b_crc) && (!pstats->b_icv)); + (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv)); - b_packet_toself = b_packet_matchbssid && + packet_toself = packet_matchbssid && (!compare_ether_addr(praddr, rtlefuse->dev_addr)); if (ieee80211_is_beacon(fc)) - b_packet_beacon = true; + packet_beacon = true; _rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, - b_packet_matchbssid, b_packet_toself, - b_packet_beacon); + packet_matchbssid, packet_toself, + packet_beacon); _rtl92ce_process_phyinfo(hw, tmp_buf, pstats); } @@ -662,14 +662,14 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) * RX_DRV_INFO_SIZE_UNIT; stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03); - stats->b_icv = (u16) GET_RX_DESC_ICV(pdesc); - stats->b_crc = (u16) GET_RX_DESC_CRC32(pdesc); - stats->b_hwerror = (stats->b_crc | stats->b_icv); + stats->icv = (u16) GET_RX_DESC_ICV(pdesc); + stats->crc = (u16) GET_RX_DESC_CRC32(pdesc); + stats->hwerror = (stats->crc | stats->icv); stats->decrypted = !GET_RX_DESC_SWDEC(pdesc); stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc); - stats->b_shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc); - stats->b_isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1); - stats->b_isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1) + stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc); + stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1); + stats->isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1) && (GET_RX_DESC_FAGGR(pdesc) == 1)); stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); @@ -727,7 +727,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - bool b_defaultadapter = true; + bool defaultadapter = true; struct ieee80211_sta *sta = ieee80211_find_sta(mac->vif, mac->bssid); @@ -743,11 +743,11 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, _rtl92ce_map_hwqueue_to_fwqueue(le16_to_cpu(hdr->frame_control), queue_index); - bool b_firstseg = ((hdr->seq_ctrl & - cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); + bool firstseg = ((hdr->seq_ctrl & + cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); - bool b_lastseg = ((hdr->frame_control & - cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); + bool lastseg = ((hdr->frame_control & + cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len, @@ -759,7 +759,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c)); - if (b_firstseg) { + if (firstseg) { SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); SET_TX_DESC_TX_RATE(pdesc, tcb_desc.hw_rate); @@ -774,25 +774,25 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, } SET_TX_DESC_SEQ(pdesc, seq_number); - SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.b_rts_enable && + SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.rts_enable && !tcb_desc. - b_cts_enable) ? 1 : 0)); + cts_enable) ? 1 : 0)); SET_TX_DESC_HW_RTS_ENABLE(pdesc, - ((tcb_desc.b_rts_enable - || tcb_desc.b_cts_enable) ? 1 : 0)); - SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.b_cts_enable) ? 1 : 0)); - SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.b_rts_stbc) ? 1 : 0)); + ((tcb_desc.rts_enable + || tcb_desc.cts_enable) ? 1 : 0)); + SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.cts_enable) ? 1 : 0)); + SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.rts_stbc) ? 1 : 0)); SET_TX_DESC_RTS_RATE(pdesc, tcb_desc.rts_rate); SET_TX_DESC_RTS_BW(pdesc, 0); SET_TX_DESC_RTS_SC(pdesc, tcb_desc.rts_sc); SET_TX_DESC_RTS_SHORT(pdesc, ((tcb_desc.rts_rate <= DESC92C_RATE54M) ? - (tcb_desc.b_rts_use_shortpreamble ? 1 : 0) - : (tcb_desc.b_rts_use_shortgi ? 1 : 0))); + (tcb_desc.rts_use_shortpreamble ? 1 : 0) + : (tcb_desc.rts_use_shortgi ? 1 : 0))); if (mac->bw_40) { - if (tcb_desc.b_packet_bw) { + if (tcb_desc.packet_bw) { SET_TX_DESC_DATA_BW(pdesc, 1); SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3); } else { @@ -854,14 +854,14 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, } } - SET_TX_DESC_FIRST_SEG(pdesc, (b_firstseg ? 1 : 0)); - SET_TX_DESC_LAST_SEG(pdesc, (b_lastseg ? 1 : 0)); + SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0)); + SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0)); SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len); SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); - if (rtlpriv->dm.b_useramask) { + if (rtlpriv->dm.useramask) { SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index); SET_TX_DESC_MACID(pdesc, tcb_desc.mac_id); } else { @@ -869,16 +869,16 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, SET_TX_DESC_MACID(pdesc, tcb_desc.ratr_index); } - if ((!ieee80211_is_data_qos(fc)) && ppsc->b_leisure_ps && - ppsc->b_fwctrl_lps) { + if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps && + ppsc->fwctrl_lps) { SET_TX_DESC_HWSEQ_EN(pdesc, 1); SET_TX_DESC_PKT_ID(pdesc, 8); - if (!b_defaultadapter) + if (!defaultadapter) SET_TX_DESC_QOS(pdesc, 1); } - SET_TX_DESC_MORE_FRAG(pdesc, (b_lastseg ? 0 : 1)); + SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1)); if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { @@ -889,8 +889,8 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, } void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, - u8 *pdesc, bool b_firstseg, - bool b_lastseg, struct sk_buff *skb) + u8 *pdesc, bool firstseg, + bool lastseg, struct sk_buff *skb) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); @@ -905,7 +905,7 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE); - if (b_firstseg) + if (firstseg) SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M); diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index fbf24a0f9054..91340c547dbb 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -366,10 +366,10 @@ static int _rtl_usb_init_sw(struct ieee80211_hw *hw) struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); rtlhal->hw = hw; - ppsc->b_inactiveps = false; - ppsc->b_leisure_ps = false; - ppsc->b_fwctrl_lps = false; - ppsc->b_reg_fwctrl_lps = 3; + ppsc->inactiveps = false; + ppsc->leisure_ps = false; + ppsc->fwctrl_lps = false; + ppsc->reg_fwctrl_lps = 3; ppsc->reg_max_lps_awakeintvl = 5; ppsc->fwctrl_psmode = FW_PS_DTIM_MODE; @@ -450,7 +450,7 @@ static void _rtl_usb_rx_process_agg(struct ieee80211_hw *hw, skb_pull(skb, (stats.rx_drvinfo_size + stats.rx_bufshift)); hdr = (struct ieee80211_hdr *)(skb->data); fc = le16_to_cpu(hdr->frame_control); - if (!stats.b_crc) { + if (!stats.crc) { memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); if (is_broadcast_ether_addr(hdr->addr1)) { @@ -493,7 +493,7 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw, skb_pull(skb, (stats.rx_drvinfo_size + stats.rx_bufshift)); hdr = (struct ieee80211_hdr *)(skb->data); fc = le16_to_cpu(hdr->frame_control); - if (!stats.b_crc) { + if (!stats.crc) { memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); if (is_broadcast_ether_addr(hdr->addr1)) { diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index ae55efad7a19..35e13eef9583 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -578,11 +578,11 @@ struct rtl_probe_rsp { struct rtl_led { void *hw; enum rtl_led_pin ledpin; - bool b_ledon; + bool ledon; }; struct rtl_led_ctl { - bool bled_opendrain; + bool led_opendrain; struct rtl_led sw_led0; struct rtl_led sw_led1; }; @@ -727,10 +727,10 @@ struct rtl_phy { u32 iqk_mac_backup[IQK_MAC_REG_NUM]; u32 iqk_bb_backup[10]; - bool b_rfpi_enable; + bool rfpi_enable; u8 pwrgroup_cnt; - u8 bcck_high_power; + u8 cck_high_power; /* 3 groups of pwr diff by rates*/ u32 mcs_txpwrlevel_origoffset[4][16]; u8 default_initialgain[4]; @@ -740,7 +740,7 @@ struct rtl_phy { u8 cur_ofdm24g_txpwridx; u32 rfreg_chnlval[2]; - bool b_apk_done; + bool apk_done; /*fsync*/ u8 framesync; @@ -867,9 +867,9 @@ struct rtl_hal { /*firmware */ u8 *pfirmware; - bool b_h2c_setinprogress; + bool h2c_setinprogress; u8 last_hmeboxnum; - bool bfw_ready; + bool fw_ready; /*Reserve page start offset except beacon in TxQ. */ u8 fw_rsvdpage_startoffset; }; @@ -900,17 +900,17 @@ struct rtl_dm { long entry_min_undecoratedsmoothed_pwdb; long undecorated_smoothed_pwdb; /*out dm */ long entry_max_undecoratedsmoothed_pwdb; - bool b_dm_initialgain_enable; - bool bdynamic_txpower_enable; - bool bcurrent_turbo_edca; - bool bis_any_nonbepkts; /*out dm */ - bool bis_cur_rdlstate; - bool btxpower_trackingInit; - bool b_disable_framebursting; - bool b_cck_inch14; - bool btxpower_tracking; - bool b_useramask; - bool brfpath_rxenable[4]; + bool dm_initialgain_enable; + bool dynamic_txpower_enable; + bool current_turbo_edca; + bool is_any_nonbepkts; /*out dm */ + bool is_cur_rdlstate; + bool txpower_trackingInit; + bool disable_framebursting; + bool cck_inch14; + bool txpower_tracking; + bool useramask; + bool rfpath_rxenable[4]; u8 thermalvalue_iqk; u8 thermalvalue_lck; @@ -928,7 +928,7 @@ struct rtl_dm { #define EFUSE_MAX_LOGICAL_SIZE 128 struct rtl_efuse { - bool bautoLoad_ok; + bool autoLoad_ok; bool bootfromefuse; u16 max_physical_size; u8 contents[EFUSE_MAX_LOGICAL_SIZE]; @@ -950,7 +950,7 @@ struct rtl_efuse { u8 dev_addr[6]; - bool b_txpwr_fromeprom; + bool txpwr_fromeprom; u8 eeprom_tssi[2]; u8 eeprom_pwrlimit_ht20[3]; u8 eeprom_pwrlimit_ht40[3]; @@ -974,15 +974,15 @@ struct rtl_efuse { u8 thermalmeter[2]; u8 legacy_ht_txpowerdiff; /*Legacy to HT rate power diff */ - bool b_apk_thermalmeterignore; + bool apk_thermalmeterignore; }; struct rtl_ps_ctl { bool set_rfpowerstate_inprogress; - bool b_in_powersavemode; + bool in_powersavemode; bool rfchange_inprogress; - bool b_swrf_processing; - bool b_hwradiooff; + bool swrf_processing; + bool hwradiooff; u32 last_sleep_jiffies; u32 last_awake_jiffies; @@ -993,23 +993,23 @@ struct rtl_ps_ctl { * If it supports ASPM, Offset[560h] = 0x40, * otherwise Offset[560h] = 0x00. * */ - bool b_support_aspm; - bool b_support_backdoor; + bool support_aspm; + bool support_backdoor; /*for LPS */ enum rt_psmode dot11_psmode; /*Power save mode configured. */ - bool b_leisure_ps; - bool b_fwctrl_lps; + bool leisure_ps; + bool fwctrl_lps; u8 fwctrl_psmode; /*For Fw control LPS mode */ - u8 b_reg_fwctrl_lps; + u8 reg_fwctrl_lps; /*Record Fw PS mode status. */ - bool b_fw_current_inpsmode; + bool fw_current_inpsmode; u8 reg_max_lps_awakeintvl; bool report_linked; /*for IPS */ - bool b_inactiveps; + bool inactiveps; u32 rfoff_reason; @@ -1047,10 +1047,10 @@ struct rtl_stats { s32 recvsignalpower; s8 rxpower; /*in dBm Translate from PWdB */ u8 signalstrength; /*in 0-100 index. */ - u16 b_hwerror:1; - u16 b_crc:1; - u16 b_icv:1; - u16 b_shortpreamble:1; + u16 hwerror:1; + u16 crc:1; + u16 icv:1; + u16 shortpreamble:1; u16 antenna:1; u16 decrypted:1; u16 wakeup:1; @@ -1059,15 +1059,15 @@ struct rtl_stats { u8 rx_drvinfo_size; u8 rx_bufshift; - bool b_isampdu; + bool isampdu; bool rx_is40Mhzpacket; u32 rx_pwdb_all; u8 rx_mimo_signalstrength[4]; /*in 0~100 index */ s8 rx_mimo_signalquality[2]; - bool b_packet_matchbssid; - bool b_is_cck; - bool b_packet_toself; - bool b_packet_beacon; /*for rssi */ + bool packet_matchbssid; + bool is_cck; + bool packet_toself; + bool packet_beacon; /*for rssi */ char cck_adc_pwdb[4]; /*for rx path selection */ }; @@ -1078,23 +1078,23 @@ struct rt_link_detect { u32 num_tx_inperiod; u32 num_rx_inperiod; - bool b_busytraffic; - bool b_higher_busytraffic; - bool b_higher_busyrxtraffic; + bool busytraffic; + bool higher_busytraffic; + bool higher_busyrxtraffic; }; struct rtl_tcb_desc { - u8 b_packet_bw:1; - u8 b_multicast:1; - u8 b_broadcast:1; - - u8 b_rts_stbc:1; - u8 b_rts_enable:1; - u8 b_cts_enable:1; - u8 b_rts_use_shortpreamble:1; - u8 b_rts_use_shortgi:1; + u8 packet_bw:1; + u8 multicast:1; + u8 broadcast:1; + + u8 rts_stbc:1; + u8 rts_enable:1; + u8 cts_enable:1; + u8 rts_use_shortpreamble:1; + u8 rts_use_shortgi:1; u8 rts_sc:1; - u8 b_rts_bw:1; + u8 rts_bw:1; u8 rts_rate; u8 use_shortgi:1; @@ -1137,23 +1137,23 @@ struct rtl_hal_ops { struct ieee80211_tx_info *info, struct sk_buff *skb, unsigned int queue_index); void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc, - bool b_firstseg, bool b_lastseg, + bool firstseg, bool lastseg, struct sk_buff *skb); bool (*cmd_send_packet)(struct ieee80211_hw *hw, struct sk_buff *skb); - bool(*query_rx_desc) (struct ieee80211_hw *hw, + bool (*query_rx_desc) (struct ieee80211_hw *hw, struct rtl_stats *stats, struct ieee80211_rx_status *rx_status, u8 *pdesc, struct sk_buff *skb); void (*set_channel_access) (struct ieee80211_hw *hw); - bool(*radio_onoff_checking) (struct ieee80211_hw *hw, u8 *valid); + bool (*radio_onoff_checking) (struct ieee80211_hw *hw, u8 *valid); void (*dm_watchdog) (struct ieee80211_hw *hw); void (*scan_operation_backup) (struct ieee80211_hw *hw, u8 operation); - bool(*set_rf_power_state) (struct ieee80211_hw *hw, + bool (*set_rf_power_state) (struct ieee80211_hw *hw, enum rf_pwrstate rfpwr_state); void (*led_control) (struct ieee80211_hw *hw, enum led_ctl_mode ledaction); void (*set_desc) (u8 *pdesc, bool istx, u8 desc_name, u8 *val); - u32(*get_desc) (u8 *pdesc, bool istx, u8 desc_name); + u32 (*get_desc) (u8 *pdesc, bool istx, u8 desc_name); void (*tx_polling) (struct ieee80211_hw *hw, unsigned int hw_queue); void (*enable_hw_sec) (struct ieee80211_hw *hw); void (*set_key) (struct ieee80211_hw *hw, u32 key_index, @@ -1161,10 +1161,10 @@ struct rtl_hal_ops { bool is_wepkey, bool clear_all); void (*init_sw_leds) (struct ieee80211_hw *hw); void (*deinit_sw_leds) (struct ieee80211_hw *hw); - u32(*get_bbreg) (struct ieee80211_hw *hw, u32 regaddr, u32 bitmask); + u32 (*get_bbreg) (struct ieee80211_hw *hw, u32 regaddr, u32 bitmask); void (*set_bbreg) (struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, u32 data); - u32(*get_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath, + u32 (*get_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath, u32 regaddr, u32 bitmask); void (*set_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath, u32 regaddr, u32 bitmask, u32 data); -- cgit v1.2.3 From 18d30067d3b0c7e1362b7a866a9873e03a6d7d62 Mon Sep 17 00:00:00 2001 From: George Date: Sat, 19 Feb 2011 16:29:02 -0600 Subject: rtlwifi: Add headers for rtl8187cu Signed-off-by: Larry Finger Signed-off-by: George Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/def.h | 62 ++++ drivers/net/wireless/rtlwifi/rtl8192cu/dm.h | 32 ++ drivers/net/wireless/rtlwifi/rtl8192cu/fw.h | 30 ++ drivers/net/wireless/rtlwifi/rtl8192cu/hw.h | 107 ++++++ drivers/net/wireless/rtlwifi/rtl8192cu/led.h | 37 +++ drivers/net/wireless/rtlwifi/rtl8192cu/mac.h | 180 +++++++++++ drivers/net/wireless/rtlwifi/rtl8192cu/phy.h | 34 ++ drivers/net/wireless/rtlwifi/rtl8192cu/reg.h | 30 ++ drivers/net/wireless/rtlwifi/rtl8192cu/rf.h | 30 ++ drivers/net/wireless/rtlwifi/rtl8192cu/sw.h | 35 ++ drivers/net/wireless/rtlwifi/rtl8192cu/table.h | 71 ++++ drivers/net/wireless/rtlwifi/rtl8192cu/trx.h | 430 +++++++++++++++++++++++++ drivers/net/wireless/rtlwifi/wifi.h | 138 +++++++- 13 files changed, 1212 insertions(+), 4 deletions(-) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/def.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/dm.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/fw.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/hw.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/led.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/mac.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/phy.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/reg.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/rf.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/sw.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/table.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/trx.h (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/def.h b/drivers/net/wireless/rtlwifi/rtl8192cu/def.h new file mode 100644 index 000000000000..c54940ea72fe --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/def.h @@ -0,0 +1,62 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../rtl8192ce/def.h" + +/*------------------------------------------------------------------------- + * Chip specific + *-------------------------------------------------------------------------*/ +#define CHIP_8723 BIT(2) /* RTL8723 With BT feature */ +#define CHIP_8723_DRV_REV BIT(3) /* RTL8723 Driver Revised */ +#define NORMAL_CHIP BIT(4) +#define CHIP_VENDOR_UMC BIT(5) +#define CHIP_VENDOR_UMC_B_CUT BIT(6) + +#define IS_NORMAL_CHIP(version) \ + (((version) & NORMAL_CHIP) ? true : false) + +#define IS_8723_SERIES(version) \ + (((version) & CHIP_8723) ? true : false) + +#define IS_92C_1T2R(version) \ + (((version) & CHIP_92C) && ((version) & CHIP_92C_1T2R)) + +#define IS_VENDOR_UMC(version) \ + (((version) & CHIP_VENDOR_UMC) ? true : false) + +#define IS_VENDOR_UMC_A_CUT(version) \ + (((version) & CHIP_VENDOR_UMC) ? (((version) & (BIT(6) | BIT(7))) ? \ + false : true) : false) + +#define IS_VENDOR_8723_A_CUT(version) \ + (((version) & CHIP_VENDOR_UMC) ? (((version) & (BIT(6))) ? \ + false : true) : false) + +#define CHIP_BONDING_92C_1T2R 0x1 +#define CHIP_BONDING_IDENTIFIER(_value) (((_value) >> 22) & 0x3) diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h new file mode 100644 index 000000000000..5e7fbfc2851b --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h @@ -0,0 +1,32 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../rtl8192ce/dm.h" + +void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/fw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/fw.h new file mode 100644 index 000000000000..a3bbac811d08 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/fw.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../rtl8192ce/fw.h" diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h new file mode 100644 index 000000000000..3c0ea5ea6db5 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h @@ -0,0 +1,107 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92CU_HW_H__ +#define __RTL92CU_HW_H__ + +#define LLT_POLLING_LLT_THRESHOLD 20 +#define LLT_POLLING_READY_TIMEOUT_COUNT 100 +#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255 + +#define RX_PAGE_SIZE_REG_VALUE PBP_128 +/* Note: We will divide number of page equally for each queue + * other than public queue! */ +#define TX_TOTAL_PAGE_NUMBER 0xF8 +#define TX_PAGE_BOUNDARY (TX_TOTAL_PAGE_NUMBER + 1) + + +#define CHIP_B_PAGE_NUM_PUBQ 0xE7 + +/* For Test Chip Setting + * (HPQ + LPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER */ +#define CHIP_A_PAGE_NUM_PUBQ 0x7E + + +/* For Chip A Setting */ +#define WMM_CHIP_A_TX_TOTAL_PAGE_NUMBER 0xF5 +#define WMM_CHIP_A_TX_PAGE_BOUNDARY \ + (WMM_CHIP_A_TX_TOTAL_PAGE_NUMBER + 1) /* F6 */ + +#define WMM_CHIP_A_PAGE_NUM_PUBQ 0xA3 +#define WMM_CHIP_A_PAGE_NUM_HPQ 0x29 +#define WMM_CHIP_A_PAGE_NUM_LPQ 0x29 + + + +/* Note: For Chip B Setting ,modify later */ +#define WMM_CHIP_B_TX_TOTAL_PAGE_NUMBER 0xF5 +#define WMM_CHIP_B_TX_PAGE_BOUNDARY \ + (WMM_CHIP_B_TX_TOTAL_PAGE_NUMBER + 1) /* F6 */ + +#define WMM_CHIP_B_PAGE_NUM_PUBQ 0xB0 +#define WMM_CHIP_B_PAGE_NUM_HPQ 0x29 +#define WMM_CHIP_B_PAGE_NUM_LPQ 0x1C +#define WMM_CHIP_B_PAGE_NUM_NPQ 0x1C + +#define BOARD_TYPE_NORMAL_MASK 0xE0 +#define BOARD_TYPE_TEST_MASK 0x0F + +/* should be renamed and moved to another file */ +enum _BOARD_TYPE_8192CUSB { + BOARD_USB_DONGLE = 0, /* USB dongle */ + BOARD_USB_High_PA = 1, /* USB dongle - high power PA */ + BOARD_MINICARD = 2, /* Minicard */ + BOARD_USB_SOLO = 3, /* USB solo-Slim module */ + BOARD_USB_COMBO = 4, /* USB Combo-Slim module */ +}; + +#define IS_HIGHT_PA(boardtype) \ + ((boardtype == BOARD_USB_High_PA) ? true : false) + +#define RTL92C_DRIVER_INFO_SIZE 4 +void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw); +void rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw); +int rtl92cu_hw_init(struct ieee80211_hw *hw); +void rtl92cu_card_disable(struct ieee80211_hw *hw); +int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); +void rtl92cu_set_beacon_related_registers(struct ieee80211_hw *hw); +void rtl92cu_set_beacon_interval(struct ieee80211_hw *hw); +void rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr); +void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw); +void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level); + +void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw); +bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid); +void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); +u8 _rtl92c_get_chnl_group(u8 chnl); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/led.h b/drivers/net/wireless/rtlwifi/rtl8192cu/led.h new file mode 100644 index 000000000000..decaee4d1eb1 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/led.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + *****************************************************************************/ + +#ifndef __RTL92CU_LED_H__ +#define __RTL92CU_LED_H__ + +void rtl92cu_init_sw_leds(struct ieee80211_hw *hw); +void rtl92cu_deinit_sw_leds(struct ieee80211_hw *hw); +void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); +void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); +void rtl92cu_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h new file mode 100644 index 000000000000..298fdb724aa5 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h @@ -0,0 +1,180 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92C_MAC_H__ +#define __RTL92C_MAC_H__ + +#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255 +#define DRIVER_EARLY_INT_TIME 0x05 +#define BCN_DMA_ATIME_INT_TIME 0x02 + +void rtl92c_read_chip_version(struct ieee80211_hw *hw); +bool rtl92c_llt_write(struct ieee80211_hw *hw, u32 address, u32 data); +bool rtl92c_init_llt_table(struct ieee80211_hw *hw, u32 boundary); +void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all); +void rtl92c_enable_interrupt(struct ieee80211_hw *hw); +void rtl92c_disable_interrupt(struct ieee80211_hw *hw); +void rtl92c_set_qos(struct ieee80211_hw *hw, int aci); + + +/*--------------------------------------------------------------- + * Hardware init functions + *---------------------------------------------------------------*/ +void rtl92c_set_mac_addr(struct ieee80211_hw *hw, const u8 *addr); +void rtl92c_init_interrupt(struct ieee80211_hw *hw); +void rtl92c_init_driver_info_size(struct ieee80211_hw *hw, u8 size); + +int rtl92c_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); +void rtl92c_init_network_type(struct ieee80211_hw *hw); +void rtl92c_init_adaptive_ctrl(struct ieee80211_hw *hw); +void rtl92c_init_rate_fallback(struct ieee80211_hw *hw); + +void rtl92c_init_edca_param(struct ieee80211_hw *hw, + u16 queue, + u16 txop, + u8 ecwmax, + u8 ecwmin, + u8 aifs); + +void rtl92c_init_edca(struct ieee80211_hw *hw); +void rtl92c_init_ampdu_aggregation(struct ieee80211_hw *hw); +void rtl92c_init_beacon_max_error(struct ieee80211_hw *hw, bool infra_mode); +void rtl92c_init_rdg_setting(struct ieee80211_hw *hw); +void rtl92c_init_retry_function(struct ieee80211_hw *hw); + +void rtl92c_init_beacon_parameters(struct ieee80211_hw *hw, + enum version_8192c version); + +void rtl92c_disable_fast_edca(struct ieee80211_hw *hw); +void rtl92c_set_min_space(struct ieee80211_hw *hw, bool is2T); + +/* For filter */ +u16 rtl92c_get_mgt_filter(struct ieee80211_hw *hw); +void rtl92c_set_mgt_filter(struct ieee80211_hw *hw, u16 filter); +u16 rtl92c_get_ctrl_filter(struct ieee80211_hw *hw); +void rtl92c_set_ctrl_filter(struct ieee80211_hw *hw, u16 filter); +u16 rtl92c_get_data_filter(struct ieee80211_hw *hw); +void rtl92c_set_data_filter(struct ieee80211_hw *hw, u16 filter); + + +u32 rtl92c_get_txdma_status(struct ieee80211_hw *hw); + +#define RX_HAL_IS_CCK_RATE(_pdesc)\ + (GET_RX_DESC_RX_MCS(_pdesc) == DESC92C_RATE1M ||\ + GET_RX_DESC_RX_MCS(_pdesc) == DESC92C_RATE2M ||\ + GET_RX_DESC_RX_MCS(_pdesc) == DESC92C_RATE5_5M ||\ + GET_RX_DESC_RX_MCS(_pdesc) == DESC92C_RATE11M) + +struct rx_fwinfo_92c { + u8 gain_trsw[4]; + u8 pwdb_all; + u8 cfosho[4]; + u8 cfotail[4]; + char rxevm[2]; + char rxsnr[4]; + u8 pdsnr[2]; + u8 csi_current[2]; + u8 csi_target[2]; + u8 sigevm; + u8 max_ex_pwr; + u8 ex_intf_flag:1; + u8 sgi_en:1; + u8 rxsc:2; + u8 reserve:4; +} __packed; + +struct rx_desc_92c { + u32 length:14; + u32 crc32:1; + u32 icverror:1; + u32 drv_infosize:4; + u32 security:3; + u32 qos:1; + u32 shift:2; + u32 phystatus:1; + u32 swdec:1; + u32 lastseg:1; + u32 firstseg:1; + u32 eor:1; + u32 own:1; + u32 macid:5; /* word 1 */ + u32 tid:4; + u32 hwrsvd:5; + u32 paggr:1; + u32 faggr:1; + u32 a1_fit:4; + u32 a2_fit:4; + u32 pam:1; + u32 pwr:1; + u32 moredata:1; + u32 morefrag:1; + u32 type:2; + u32 mc:1; + u32 bc:1; + u32 seq:12; /* word 2 */ + u32 frag:4; + u32 nextpktlen:14; + u32 nextind:1; + u32 rsvd:1; + u32 rxmcs:6; /* word 3 */ + u32 rxht:1; + u32 amsdu:1; + u32 splcp:1; + u32 bandwidth:1; + u32 htc:1; + u32 tcpchk_rpt:1; + u32 ipcchk_rpt:1; + u32 tcpchk_valid:1; + u32 hwpcerr:1; + u32 hwpcind:1; + u32 iv0:16; + u32 iv1; /* word 4 */ + u32 tsfl; /* word 5 */ + u32 bufferaddress; /* word 6 */ + u32 bufferaddress64; /* word 7 */ +} __packed; + +enum rtl_desc_qsel rtl92c_map_hwqueue_to_fwqueue(u16 fc, + unsigned int + skb_queue); +void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct rtl_stats *pstats, + struct rx_desc_92c *pdesc, + struct rx_fwinfo_92c *p_drvinfo); + +/*--------------------------------------------------------------- + * Card disable functions + *---------------------------------------------------------------*/ + + + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h new file mode 100644 index 000000000000..c456c15afbf1 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h @@ -0,0 +1,34 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../rtl8192ce/phy.h" + +void rtl92c_bb_block_on(struct ieee80211_hw *hw); +bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath); +void rtl92c_phy_set_io(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h b/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h new file mode 100644 index 000000000000..7f1be614c998 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../rtl8192ce/reg.h" diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h new file mode 100644 index 000000000000..c4ed125ef4dc --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../rtl8192ce/rf.h" diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h new file mode 100644 index 000000000000..3b2c66339554 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h @@ -0,0 +1,35 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92CU_SW_H__ +#define __RTL92CU_SW_H__ + +#define EFUSE_MAX_SECTION 16 + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/table.h b/drivers/net/wireless/rtlwifi/rtl8192cu/table.h new file mode 100644 index 000000000000..c3d5cd826cfa --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/table.h @@ -0,0 +1,71 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92CU_TABLE__H_ +#define __RTL92CU_TABLE__H_ + +#include + +#define RTL8192CUPHY_REG_2TARRAY_LENGTH 374 +extern u32 RTL8192CUPHY_REG_2TARRAY[RTL8192CUPHY_REG_2TARRAY_LENGTH]; +#define RTL8192CUPHY_REG_1TARRAY_LENGTH 374 +extern u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH]; + +#define RTL8192CUPHY_REG_ARRAY_PGLENGTH 336 +extern u32 RTL8192CUPHY_REG_ARRAY_PG[RTL8192CUPHY_REG_ARRAY_PGLENGTH]; + +#define RTL8192CURADIOA_2TARRAYLENGTH 282 +extern u32 RTL8192CURADIOA_2TARRAY[RTL8192CURADIOA_2TARRAYLENGTH]; +#define RTL8192CURADIOB_2TARRAYLENGTH 78 +extern u32 RTL8192CU_RADIOB_2TARRAY[RTL8192CURADIOB_2TARRAYLENGTH]; +#define RTL8192CURADIOA_1TARRAYLENGTH 282 +extern u32 RTL8192CU_RADIOA_1TARRAY[RTL8192CURADIOA_1TARRAYLENGTH]; +#define RTL8192CURADIOB_1TARRAYLENGTH 1 +extern u32 RTL8192CU_RADIOB_1TARRAY[RTL8192CURADIOB_1TARRAYLENGTH]; + +#define RTL8192CUMAC_2T_ARRAYLENGTH 172 +extern u32 RTL8192CUMAC_2T_ARRAY[RTL8192CUMAC_2T_ARRAYLENGTH]; + +#define RTL8192CUAGCTAB_2TARRAYLENGTH 320 +extern u32 RTL8192CUAGCTAB_2TARRAY[RTL8192CUAGCTAB_2TARRAYLENGTH]; +#define RTL8192CUAGCTAB_1TARRAYLENGTH 320 +extern u32 RTL8192CUAGCTAB_1TARRAY[RTL8192CUAGCTAB_1TARRAYLENGTH]; + +#define RTL8192CUPHY_REG_1T_HPArrayLength 378 +extern u32 RTL8192CUPHY_REG_1T_HPArray[RTL8192CUPHY_REG_1T_HPArrayLength]; + +#define RTL8192CUPHY_REG_Array_PG_HPLength 336 +extern u32 RTL8192CUPHY_REG_Array_PG_HP[RTL8192CUPHY_REG_Array_PG_HPLength]; + +#define RTL8192CURadioA_1T_HPArrayLength 282 +extern u32 RTL8192CURadioA_1T_HPArray[RTL8192CURadioA_1T_HPArrayLength]; +#define RTL8192CUAGCTAB_1T_HPArrayLength 320 +extern u32 Rtl8192CUAGCTAB_1T_HPArray[RTL8192CUAGCTAB_1T_HPArrayLength]; + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h new file mode 100644 index 000000000000..b396d46edbb7 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h @@ -0,0 +1,430 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92CU_TRX_H__ +#define __RTL92CU_TRX_H__ + +#define RTL92C_USB_BULK_IN_NUM 1 +#define RTL92C_NUM_RX_URBS 8 +#define RTL92C_NUM_TX_URBS 32 + +#define RTL92C_SIZE_MAX_RX_BUFFER 15360 /* 8192 */ +#define RX_DRV_INFO_SIZE_UNIT 8 + +enum usb_rx_agg_mode { + USB_RX_AGG_DISABLE, + USB_RX_AGG_DMA, + USB_RX_AGG_USB, + USB_RX_AGG_DMA_USB +}; + +#define TX_SELE_HQ BIT(0) /* High Queue */ +#define TX_SELE_LQ BIT(1) /* Low Queue */ +#define TX_SELE_NQ BIT(2) /* Normal Queue */ + +#define RTL_USB_TX_AGG_NUM_DESC 5 + +#define RTL_USB_RX_AGG_PAGE_NUM 4 +#define RTL_USB_RX_AGG_PAGE_TIMEOUT 3 + +#define RTL_USB_RX_AGG_BLOCK_NUM 5 +#define RTL_USB_RX_AGG_BLOCK_TIMEOUT 3 + +/*======================== rx status =========================================*/ + +struct rx_drv_info_92c { + /* + * Driver info contain PHY status and other variabel size info + * PHY Status content as below + */ + + /* DWORD 0 */ + u8 gain_trsw[4]; + + /* DWORD 1 */ + u8 pwdb_all; + u8 cfosho[4]; + + /* DWORD 2 */ + u8 cfotail[4]; + + /* DWORD 3 */ + s8 rxevm[2]; + s8 rxsnr[4]; + + /* DWORD 4 */ + u8 pdsnr[2]; + + /* DWORD 5 */ + u8 csi_current[2]; + u8 csi_target[2]; + + /* DWORD 6 */ + u8 sigevm; + u8 max_ex_pwr; + u8 ex_intf_flag:1; + u8 sgi_en:1; + u8 rxsc:2; + u8 reserve:4; +} __packed; + +/* Define a macro that takes a le32 word, converts it to host ordering, + * right shifts by a specified count, creates a mask of the specified + * bit count, and extracts that number of bits. + */ + +#define SHIFT_AND_MASK_LE(__pdesc, __shift, __bits) \ + ((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) & \ + BIT_LEN_MASK_32(__bits)) + +/* Define a macro that clears a bit field in an le32 word and + * sets the specified value into that bit field. The resulting + * value remains in le32 ordering; however, it is properly converted + * to host ordering for the clear and set operations before conversion + * back to le32. + */ + +#define SET_BITS_OFFSET_LE(__pdesc, __shift, __len, __val) \ + (*(__le32 *)(__pdesc) = \ + (cpu_to_le32((le32_to_cpu(*((__le32 *)(__pdesc))) & \ + (~(BIT_OFFSET_LEN_MASK_32((__shift), __len)))) | \ + (((u32)(__val) & BIT_LEN_MASK_32(__len)) << (__shift))))); + +/* macros to read various fields in RX descriptor */ + +/* DWORD 0 */ +#define GET_RX_DESC_PKT_LEN(__rxdesc) \ + SHIFT_AND_MASK_LE((__rxdesc), 0, 14) +#define GET_RX_DESC_CRC32(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc, 14, 1) +#define GET_RX_DESC_ICV(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc, 15, 1) +#define GET_RX_DESC_DRVINFO_SIZE(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc, 16, 4) +#define GET_RX_DESC_SECURITY(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc, 20, 3) +#define GET_RX_DESC_QOS(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc, 23, 1) +#define GET_RX_DESC_SHIFT(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc, 24, 2) +#define GET_RX_DESC_PHY_STATUS(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc, 26, 1) +#define GET_RX_DESC_SWDEC(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc, 27, 1) +#define GET_RX_DESC_LAST_SEG(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc, 28, 1) +#define GET_RX_DESC_FIRST_SEG(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc, 29, 1) +#define GET_RX_DESC_EOR(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc, 30, 1) +#define GET_RX_DESC_OWN(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc, 31, 1) + +/* DWORD 1 */ +#define GET_RX_DESC_MACID(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+4, 0, 5) +#define GET_RX_DESC_TID(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+4, 5, 4) +#define GET_RX_DESC_PAGGR(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+4, 14, 1) +#define GET_RX_DESC_FAGGR(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+4, 15, 1) +#define GET_RX_DESC_A1_FIT(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+4, 16, 4) +#define GET_RX_DESC_A2_FIT(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+4, 20, 4) +#define GET_RX_DESC_PAM(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+4, 24, 1) +#define GET_RX_DESC_PWR(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+4, 25, 1) +#define GET_RX_DESC_MORE_DATA(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+4, 26, 1) +#define GET_RX_DESC_MORE_FRAG(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+4, 27, 1) +#define GET_RX_DESC_TYPE(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+4, 28, 2) +#define GET_RX_DESC_MC(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+4, 30, 1) +#define GET_RX_DESC_BC(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+4, 31, 1) + +/* DWORD 2 */ +#define GET_RX_DESC_SEQ(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+8, 0, 12) +#define GET_RX_DESC_FRAG(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+8, 12, 4) +#define GET_RX_DESC_USB_AGG_PKTNUM(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+8, 16, 8) +#define GET_RX_DESC_NEXT_IND(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+8, 30, 1) + +/* DWORD 3 */ +#define GET_RX_DESC_RX_MCS(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+12, 0, 6) +#define GET_RX_DESC_RX_HT(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+12, 6, 1) +#define GET_RX_DESC_AMSDU(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+12, 7, 1) +#define GET_RX_DESC_SPLCP(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+12, 8, 1) +#define GET_RX_DESC_BW(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+12, 9, 1) +#define GET_RX_DESC_HTC(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+12, 10, 1) +#define GET_RX_DESC_TCP_CHK_RPT(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+12, 11, 1) +#define GET_RX_DESC_IP_CHK_RPT(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+12, 12, 1) +#define GET_RX_DESC_TCP_CHK_VALID(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+12, 13, 1) +#define GET_RX_DESC_HWPC_ERR(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+12, 14, 1) +#define GET_RX_DESC_HWPC_IND(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+12, 15, 1) +#define GET_RX_DESC_IV0(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+12, 16, 16) + +/* DWORD 4 */ +#define GET_RX_DESC_IV1(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+16, 0, 32) + +/* DWORD 5 */ +#define GET_RX_DESC_TSFL(__rxdesc) \ + SHIFT_AND_MASK_LE(__rxdesc+20, 0, 32) + +/*======================= tx desc ============================================*/ + +/* macros to set various fields in TX descriptor */ + +/* Dword 0 */ +#define SET_TX_DESC_PKT_SIZE(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc, 0, 16, __value) +#define SET_TX_DESC_OFFSET(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc, 16, 8, __value) +#define SET_TX_DESC_BMC(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc, 24, 1, __value) +#define SET_TX_DESC_HTC(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc, 25, 1, __value) +#define SET_TX_DESC_LAST_SEG(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc, 26, 1, __value) +#define SET_TX_DESC_FIRST_SEG(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc, 27, 1, __value) +#define SET_TX_DESC_LINIP(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc, 28, 1, __value) +#define SET_TX_DESC_NO_ACM(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc, 29, 1, __value) +#define SET_TX_DESC_GF(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc, 30, 1, __value) +#define SET_TX_DESC_OWN(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc, 31, 1, __value) + + +/* Dword 1 */ +#define SET_TX_DESC_MACID(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+4, 0, 5, __value) +#define SET_TX_DESC_AGG_ENABLE(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+4, 5, 1, __value) +#define SET_TX_DESC_AGG_BREAK(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+4, 6, 1, __value) +#define SET_TX_DESC_RDG_ENABLE(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+4, 7, 1, __value) +#define SET_TX_DESC_QUEUE_SEL(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+4, 8, 5, __value) +#define SET_TX_DESC_RDG_NAV_EXT(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+4, 13, 1, __value) +#define SET_TX_DESC_LSIG_TXOP_EN(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+4, 14, 1, __value) +#define SET_TX_DESC_PIFS(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+4, 15, 1, __value) +#define SET_TX_DESC_RATE_ID(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+4, 16, 4, __value) +#define SET_TX_DESC_RA_BRSR_ID(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+4, 16, 4, __value) +#define SET_TX_DESC_NAV_USE_HDR(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+4, 20, 1, __value) +#define SET_TX_DESC_EN_DESC_ID(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+4, 21, 1, __value) +#define SET_TX_DESC_SEC_TYPE(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+4, 22, 2, __value) +#define SET_TX_DESC_PKT_OFFSET(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+4, 26, 5, __value) + +/* Dword 2 */ +#define SET_TX_DESC_RTS_RC(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+8, 0, 6, __value) +#define SET_TX_DESC_DATA_RC(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+8, 6, 6, __value) +#define SET_TX_DESC_BAR_RTY_TH(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+8, 14, 2, __value) +#define SET_TX_DESC_MORE_FRAG(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+8, 17, 1, __value) +#define SET_TX_DESC_RAW(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+8, 18, 1, __value) +#define SET_TX_DESC_CCX(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+8, 19, 1, __value) +#define SET_TX_DESC_AMPDU_DENSITY(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+8, 20, 3, __value) +#define SET_TX_DESC_ANTSEL_A(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+8, 24, 1, __value) +#define SET_TX_DESC_ANTSEL_B(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+8, 25, 1, __value) +#define SET_TX_DESC_TX_ANT_CCK(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+8, 26, 2, __value) +#define SET_TX_DESC_TX_ANTL(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+8, 28, 2, __value) +#define SET_TX_DESC_TX_ANT_HT(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+8, 30, 2, __value) + +/* Dword 3 */ +#define SET_TX_DESC_NEXT_HEAP_PAGE(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+12, 0, 8, __value) +#define SET_TX_DESC_TAIL_PAGE(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+12, 8, 8, __value) +#define SET_TX_DESC_SEQ(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+12, 16, 12, __value) +#define SET_TX_DESC_PKT_ID(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+12, 28, 4, __value) + +/* Dword 4 */ +#define SET_TX_DESC_RTS_RATE(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 0, 5, __value) +#define SET_TX_DESC_AP_DCFE(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 5, 1, __value) +#define SET_TX_DESC_QOS(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 6, 1, __value) +#define SET_TX_DESC_HWSEQ_EN(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 7, 1, __value) +#define SET_TX_DESC_USE_RATE(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 8, 1, __value) +#define SET_TX_DESC_DISABLE_RTS_FB(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 9, 1, __value) +#define SET_TX_DESC_DISABLE_FB(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 10, 1, __value) +#define SET_TX_DESC_CTS2SELF(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 11, 1, __value) +#define SET_TX_DESC_RTS_ENABLE(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 12, 1, __value) +#define SET_TX_DESC_HW_RTS_ENABLE(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 13, 1, __value) +#define SET_TX_DESC_WAIT_DCTS(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 18, 1, __value) +#define SET_TX_DESC_CTS2AP_EN(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 19, 1, __value) +#define SET_TX_DESC_DATA_SC(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 20, 2, __value) +#define SET_TX_DESC_DATA_STBC(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 22, 2, __value) +#define SET_TX_DESC_DATA_SHORT(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 24, 1, __value) +#define SET_TX_DESC_DATA_BW(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 25, 1, __value) +#define SET_TX_DESC_RTS_SHORT(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 26, 1, __value) +#define SET_TX_DESC_RTS_BW(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 27, 1, __value) +#define SET_TX_DESC_RTS_SC(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 28, 2, __value) +#define SET_TX_DESC_RTS_STBC(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+16, 30, 2, __value) + +/* Dword 5 */ +#define SET_TX_DESC_TX_RATE(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+20, 0, 6, __val) +#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+20, 6, 1, __val) +#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \ + SET_BITS_OFFSET_LE(__pdesc+20, 7, 1, __val) +#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+20, 8, 5, __value) +#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+20, 13, 4, __value) +#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+20, 17, 1, __value) +#define SET_TX_DESC_DATA_RETRY_LIMIT(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+20, 18, 6, __value) +#define SET_TX_DESC_USB_TXAGG_NUM(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+20, 24, 8, __value) + +/* Dword 6 */ +#define SET_TX_DESC_TXAGC_A(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+24, 0, 5, __value) +#define SET_TX_DESC_TXAGC_B(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+24, 5, 5, __value) +#define SET_TX_DESC_USB_MAX_LEN(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+24, 10, 1, __value) +#define SET_TX_DESC_MAX_AGG_NUM(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+24, 11, 5, __value) +#define SET_TX_DESC_MCSG1_MAX_LEN(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+24, 16, 4, __value) +#define SET_TX_DESC_MCSG2_MAX_LEN(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+24, 20, 4, __value) +#define SET_TX_DESC_MCSG3_MAX_LEN(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+24, 24, 4, __value) +#define SET_TX_DESC_MCSG7_MAX_LEN(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+24, 28, 4, __value) + +/* Dword 7 */ +#define SET_TX_DESC_TX_DESC_CHECKSUM(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+28, 0, 16, __value) +#define SET_TX_DESC_MCSG4_MAX_LEN(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+28, 16, 4, __value) +#define SET_TX_DESC_MCSG5_MAX_LEN(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+28, 20, 4, __value) +#define SET_TX_DESC_MCSG6_MAX_LEN(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+28, 24, 4, __value) +#define SET_TX_DESC_MCSG15_MAX_LEN(__txdesc, __value) \ + SET_BITS_OFFSET_LE(__txdesc+28, 28, 4, __value) + + +int rtl8192cu_endpoint_mapping(struct ieee80211_hw *hw); +u16 rtl8192cu_mq_to_hwq(__le16 fc, u16 mac80211_queue_index); +bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, + u8 *p_desc, struct sk_buff *skb); +void rtl8192cu_rx_hdl(struct ieee80211_hw *hw, struct sk_buff * skb); +void rtl8192c_rx_segregate_hdl(struct ieee80211_hw *, struct sk_buff *, + struct sk_buff_head *); +void rtl8192c_tx_cleanup(struct ieee80211_hw *hw, struct sk_buff *skb); +int rtl8192c_tx_post_hdl(struct ieee80211_hw *hw, struct urb *urb, + struct sk_buff *skb); +struct sk_buff *rtl8192c_tx_aggregate_hdl(struct ieee80211_hw *, + struct sk_buff_head *); +void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc_tx, + struct ieee80211_tx_info *info, struct sk_buff *skb, + unsigned int queue_index); +void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc, + u32 buffer_len, bool bIsPsPoll); +void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw, + u8 *pdesc, bool b_firstseg, + bool b_lastseg, struct sk_buff *skb); +bool rtl92cu_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb); + +#endif diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 35e13eef9583..328fb40ad901 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -114,6 +114,7 @@ enum hardware_type { HARDWARE_TYPE_RTL8192CU, HARDWARE_TYPE_RTL8192DE, HARDWARE_TYPE_RTL8192DU, + HARDWARE_TYPE_RTL8723U, /*keep it last*/ HARDWARE_TYPE_NUM @@ -121,6 +122,10 @@ enum hardware_type { #define IS_HARDWARE_TYPE_8192CE(rtlhal) \ (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) +#define IS_HARDWARE_TYPE_8192CU(rtlhal) \ + (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) +#define IS_HARDWARE_TYPE_8723U(rtlhal) \ + (rtlhal->hw_type == HARDWARE_TYPE_RTL8723U) enum scan_operation_backup_opt { SCAN_OPT_BACKUP = 0, @@ -363,6 +368,8 @@ enum rtl_var_map { EFUSE_LOADER_CLK_EN, EFUSE_ANA8M, EFUSE_HWSET_MAX_SIZE, + EFUSE_MAX_SECTION_MAP, + EFUSE_REAL_CONTENT_SIZE, /*CAM map */ RWCAM, @@ -509,6 +516,17 @@ enum wireless_mode { WIRELESS_MODE_N_5G = 0x20 }; +#define IS_WIRELESS_MODE_A(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_A) +#define IS_WIRELESS_MODE_B(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_B) +#define IS_WIRELESS_MODE_G(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_G) +#define IS_WIRELESS_MODE_N_24G(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_N_24G) +#define IS_WIRELESS_MODE_N_5G(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_N_5G) + enum ratr_table_mode { RATR_INX_WIRELESS_NGB = 0, RATR_INX_WIRELESS_NG = 1, @@ -694,6 +712,25 @@ struct rtl_rfkill { bool rfkill_state; /*0 is off, 1 is on */ }; +struct phy_parameters { + u16 length; + u32 *pdata; +}; + +enum hw_param_tab_index { + PHY_REG_2T, + PHY_REG_1T, + PHY_REG_PG, + RADIOA_2T, + RADIOB_2T, + RADIOA_1T, + RADIOB_1T, + MAC_REG, + AGCTAB_2T, + AGCTAB_1T, + MAX_TAB +}; + struct rtl_phy { struct bb_reg_def phyreg_def[4]; /*Radio A/B/C/D */ struct init_gain initgain_backup; @@ -747,6 +784,7 @@ struct rtl_phy { u32 framesync_c34; u8 num_total_rfpath; + struct phy_parameters hwparam_tables[MAX_TAB]; }; #define MAX_TID_COUNT 9 @@ -862,11 +900,13 @@ struct rtl_hal { enum intf_type interface; u16 hw_type; /*92c or 92d or 92s and so on */ u8 oem_id; - u8 version; /*version of chip */ + u32 version; /*version of chip */ u8 state; /*stop 0, start 1 */ /*firmware */ u8 *pfirmware; + u16 fw_version; + u16 fw_subversion; bool h2c_setinprogress; u8 last_hmeboxnum; bool fw_ready; @@ -925,10 +965,10 @@ struct rtl_dm { char cck_index; }; -#define EFUSE_MAX_LOGICAL_SIZE 128 +#define EFUSE_MAX_LOGICAL_SIZE 256 struct rtl_efuse { - bool autoLoad_ok; + bool autoload_ok; bool bootfromefuse; u16 max_physical_size; u8 contents[EFUSE_MAX_LOGICAL_SIZE]; @@ -947,6 +987,8 @@ struct rtl_efuse { u8 eeprom_oemid; u16 eeprom_channelplan; u8 eeprom_version; + u8 board_type; + u8 external_pa; u8 dev_addr[6]; @@ -1020,6 +1062,7 @@ struct rtl_ps_ctl { /*just for PCIE ASPM */ u8 const_amdpci_aspm; + bool pwrdown_mode; enum rf_pwrstate inactive_pwrstate; enum rf_pwrstate rfpwr_state; /*cur power state */ }; @@ -1120,9 +1163,11 @@ struct rtl_hal_ops { void (*disable_interrupt) (struct ieee80211_hw *hw); int (*set_network_type) (struct ieee80211_hw *hw, enum nl80211_iftype type); + void (*set_chk_bssid)(struct ieee80211_hw *hw, + bool check_bssid); void (*set_bw_mode) (struct ieee80211_hw *hw, enum nl80211_channel_type ch_type); - u8(*switch_channel) (struct ieee80211_hw *hw); + u8 (*switch_channel) (struct ieee80211_hw *hw); void (*set_qos) (struct ieee80211_hw *hw, int aci); void (*set_bcn_reg) (struct ieee80211_hw *hw); void (*set_bcn_intv) (struct ieee80211_hw *hw); @@ -1136,6 +1181,8 @@ struct rtl_hal_ops { struct ieee80211_hdr *hdr, u8 *pdesc_tx, struct ieee80211_tx_info *info, struct sk_buff *skb, unsigned int queue_index); + void (*fill_fake_txdesc) (struct ieee80211_hw *hw, u8 * pDesc, + u32 buffer_len, bool bIsPsPoll); void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc, bool firstseg, bool lastseg, struct sk_buff *skb); @@ -1311,6 +1358,89 @@ struct rtl_priv { #define rtl_efuse(rtlpriv) (&((rtlpriv)->efuse)) #define rtl_psc(rtlpriv) (&((rtlpriv)->psc)) +/*************************************** + Bluetooth Co-existance Related +****************************************/ + +enum bt_ant_num { + ANT_X2 = 0, + ANT_X1 = 1, +}; + +enum bt_co_type { + BT_2WIRE = 0, + BT_ISSC_3WIRE = 1, + BT_ACCEL = 2, + BT_CSR_BC4 = 3, + BT_CSR_BC8 = 4, + BT_RTL8756 = 5, +}; + +enum bt_cur_state { + BT_OFF = 0, + BT_ON = 1, +}; + +enum bt_service_type { + BT_SCO = 0, + BT_A2DP = 1, + BT_HID = 2, + BT_HID_IDLE = 3, + BT_SCAN = 4, + BT_IDLE = 5, + BT_OTHER_ACTION = 6, + BT_BUSY = 7, + BT_OTHERBUSY = 8, + BT_PAN = 9, +}; + +enum bt_radio_shared { + BT_RADIO_SHARED = 0, + BT_RADIO_INDIVIDUAL = 1, +}; + +struct bt_coexist_info { + + /* EEPROM BT info. */ + u8 eeprom_bt_coexist; + u8 eeprom_bt_type; + u8 eeprom_bt_ant_num; + u8 eeprom_bt_ant_isolation; + u8 eeprom_bt_radio_shared; + + u8 bt_coexistence; + u8 bt_ant_num; + u8 bt_coexist_type; + u8 bt_state; + u8 bt_cur_state; /* 0:on, 1:off */ + u8 bt_ant_isolation; /* 0:good, 1:bad */ + u8 bt_pape_ctrl; /* 0:SW, 1:SW/HW dynamic */ + u8 bt_service; + u8 bt_radio_shared_type; + u8 bt_rfreg_origin_1e; + u8 bt_rfreg_origin_1f; + u8 bt_rssi_state; + u32 ratio_tx; + u32 ratio_pri; + u32 bt_edca_ul; + u32 bt_edca_dl; + + bool b_init_set; + bool b_bt_busy_traffic; + bool b_bt_traffic_mode_set; + bool b_bt_non_traffic_mode_set; + + bool b_fw_coexist_all_off; + bool b_sw_coexist_all_off; + u32 current_state; + u32 previous_state; + u8 bt_pre_rssi_state; + + u8 b_reg_bt_iso; + u8 b_reg_bt_sco; + +}; + /**************************************** mem access macro define start Call endian free function when -- cgit v1.2.3 From e97b775d9bce1d7b51df5bf470ba9c529d93dc66 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 19 Feb 2011 16:29:07 -0600 Subject: rtlwifi: Modify wifi.h for rtl8192cu Further merge of parameters needed for rtl8192cu. In addition, some changes needed for rtl8192se and rtl8192de are included and additional Hungarian notation is removed. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ce/phy.h | 4 - drivers/net/wireless/rtlwifi/wifi.h | 285 ++++++++++++++++++++++----- 2 files changed, 239 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h index 4bdeb998ba82..3fc60e434cef 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h @@ -57,8 +57,6 @@ #define IQK_MAC_REG_NUM 4 #define RF90_PATH_MAX 2 -#define CHANNEL_MAX_NUMBER 14 -#define CHANNEL_GROUP_MAX 3 #define CT_OFFSET_MAC_ADDR 0X16 @@ -78,8 +76,6 @@ #define CT_OFFSET_CUSTOMER_ID 0x7F #define RTL92C_MAX_PATH_NUM 2 -#define CHANNEL_MAX_NUMBER 14 -#define CHANNEL_GROUP_MAX 3 #define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255 enum swchnlcmd_id { CMDID_END, diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 328fb40ad901..c0f8140e8874 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -83,6 +83,19 @@ #define MAC80211_3ADDR_LEN 24 #define MAC80211_4ADDR_LEN 30 +#define CHANNEL_MAX_NUMBER (14 + 24 + 21) /* 14 is the max channel no */ +#define CHANNEL_GROUP_MAX (3 + 9) /* ch1~3, 4~9, 10~14 = three groups */ +#define MAX_PG_GROUP 13 +#define CHANNEL_GROUP_MAX_2G 3 +#define CHANNEL_GROUP_IDX_5GL 3 +#define CHANNEL_GROUP_IDX_5GM 6 +#define CHANNEL_GROUP_IDX_5GH 9 +#define CHANNEL_GROUP_MAX_5G 9 +#define CHANNEL_MAX_NUMBER_2G 14 +#define AVG_THERMAL_NUM 8 + +/* for early mode */ +#define EM_HDR_LEN 8 enum intf_type { INTF_PCI = 0, INTF_USB = 1, @@ -114,18 +127,37 @@ enum hardware_type { HARDWARE_TYPE_RTL8192CU, HARDWARE_TYPE_RTL8192DE, HARDWARE_TYPE_RTL8192DU, + HARDWARE_TYPE_RTL8723E, HARDWARE_TYPE_RTL8723U, - /*keep it last*/ + /* keep it last */ HARDWARE_TYPE_NUM }; +#define IS_HARDWARE_TYPE_8192SU(rtlhal) \ + (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SU) +#define IS_HARDWARE_TYPE_8192SE(rtlhal) \ + (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) #define IS_HARDWARE_TYPE_8192CE(rtlhal) \ (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) #define IS_HARDWARE_TYPE_8192CU(rtlhal) \ (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) +#define IS_HARDWARE_TYPE_8192DE(rtlhal) \ + (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) +#define IS_HARDWARE_TYPE_8192DU(rtlhal) \ + (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DU) +#define IS_HARDWARE_TYPE_8723E(rtlhal) \ + (rtlhal->hw_type == HARDWARE_TYPE_RTL8723E) #define IS_HARDWARE_TYPE_8723U(rtlhal) \ (rtlhal->hw_type == HARDWARE_TYPE_RTL8723U) +#define IS_HARDWARE_TYPE_8192S(rtlhal) \ +(IS_HARDWARE_TYPE_8192SE(rtlhal) || IS_HARDWARE_TYPE_8192SU(rtlhal)) +#define IS_HARDWARE_TYPE_8192C(rtlhal) \ +(IS_HARDWARE_TYPE_8192CE(rtlhal) || IS_HARDWARE_TYPE_8192CU(rtlhal)) +#define IS_HARDWARE_TYPE_8192D(rtlhal) \ +(IS_HARDWARE_TYPE_8192DE(rtlhal) || IS_HARDWARE_TYPE_8192DU(rtlhal)) +#define IS_HARDWARE_TYPE_8723(rtlhal) \ +(IS_HARDWARE_TYPE_8723E(rtlhal) || IS_HARDWARE_TYPE_8723U(rtlhal)) enum scan_operation_backup_opt { SCAN_OPT_BACKUP = 0, @@ -324,6 +356,7 @@ enum rf_type { RF_1T1R = 0, RF_1T2R = 1, RF_2T2R = 2, + RF_2T2R_GREEN = 3, }; enum ht_channel_width { @@ -408,6 +441,7 @@ enum rtl_var_map { RTL_IMR_ATIMEND, /*For 92C,ATIM Window End Interrupt */ RTL_IMR_BDOK, /*Beacon Queue DMA OK Interrup */ RTL_IMR_HIGHDOK, /*High Queue DMA OK Interrupt */ + RTL_IMR_COMDOK, /*Command Queue DMA OK Interrupt*/ RTL_IMR_TBDOK, /*Transmit Beacon OK interrup */ RTL_IMR_MGNTDOK, /*Management Queue DMA OK Interrupt */ RTL_IMR_TBDER, /*For 92C,Transmit Beacon Error Interrupt */ @@ -416,7 +450,8 @@ enum rtl_var_map { RTL_IMR_VIDOK, /*AC_VI DMA OK Interrupt */ RTL_IMR_VODOK, /*AC_VO DMA Interrupt */ RTL_IMR_ROK, /*Receive DMA OK Interrupt */ - RTL_IBSS_INT_MASKS, /*(RTL_IMR_BcnInt|RTL_IMR_TBDOK|RTL_IMR_TBDER)*/ + RTL_IBSS_INT_MASKS, /*(RTL_IMR_BcnInt | RTL_IMR_TBDOK | + * RTL_IMR_TBDER) */ /*CCK Rates, TxHT = 0 */ RTL_RC_CCK_RATE1M, @@ -492,6 +527,19 @@ enum acm_method { eAcmWay2_SW = 2, }; +enum macphy_mode { + SINGLEMAC_SINGLEPHY = 0, + DUALMAC_DUALPHY, + DUALMAC_SINGLEPHY, +}; + +enum band_type { + BAND_ON_2_4G = 0, + BAND_ON_5G, + BAND_ON_BOTH, + BANDMAX +}; + /*aci/aifsn Field. Ref: WMM spec 2.2.2: WME Parameter Element, p.12.*/ union aci_aifsn { @@ -625,6 +673,8 @@ struct false_alarm_statistics { u32 cnt_rate_illegal; u32 cnt_crc8_fail; u32 cnt_mcs_fail; + u32 cnt_fast_fsync_fail; + u32 cnt_sb_search_fail; u32 cnt_ofdm_fail; u32 cnt_cck_fail; u32 cnt_all; @@ -712,6 +762,13 @@ struct rtl_rfkill { bool rfkill_state; /*0 is off, 1 is on */ }; +#define IQK_MATRIX_REG_NUM 8 +#define IQK_MATRIX_SETTINGS_NUM (1 + 24 + 21) +struct iqk_matrix_regs { + bool b_iqk_done; + long value[1][IQK_MATRIX_REG_NUM]; +}; + struct phy_parameters { u16 length; u32 *pdata; @@ -746,8 +803,9 @@ struct rtl_phy { u8 current_channel; u8 h2c_box_num; u8 set_io_inprogress; + u8 lck_inprogress; - /*record for power tracking*/ + /* record for power tracking */ s32 reg_e94; s32 reg_e9c; s32 reg_ea4; @@ -764,27 +822,32 @@ struct rtl_phy { u32 iqk_mac_backup[IQK_MAC_REG_NUM]; u32 iqk_bb_backup[10]; + /* Dual mac */ + bool need_iqk; + struct iqk_matrix_regs iqk_matrix_regsetting[IQK_MATRIX_SETTINGS_NUM]; + bool rfpi_enable; u8 pwrgroup_cnt; u8 cck_high_power; - /* 3 groups of pwr diff by rates*/ - u32 mcs_txpwrlevel_origoffset[4][16]; + /* MAX_PG_GROUP groups of pwr diff by rates */ + u32 mcs_txpwrlevel_origoffset[MAX_PG_GROUP][16]; u8 default_initialgain[4]; - /*the current Tx power level*/ + /* the current Tx power level */ u8 cur_cck_txpwridx; u8 cur_ofdm24g_txpwridx; u32 rfreg_chnlval[2]; bool apk_done; + u32 reg_rf3c[2]; /* pathA / pathB */ - /*fsync*/ u8 framesync; u32 framesync_c34; u8 num_total_rfpath; struct phy_parameters hwparam_tables[MAX_TAB]; + u16 rf_pathmap; }; #define MAX_TID_COUNT 9 @@ -825,12 +888,11 @@ struct rtl_io { int (*writeN_async) (struct rtl_priv *rtlpriv, u32 addr, u16 len, u8 *pdata); - u8(*read8_sync) (struct rtl_priv *rtlpriv, u32 addr); - u16(*read16_sync) (struct rtl_priv *rtlpriv, u32 addr); - u32(*read32_sync) (struct rtl_priv *rtlpriv, u32 addr); + u8(*read8_sync) (struct rtl_priv *rtlpriv, u32 addr); + u16(*read16_sync) (struct rtl_priv *rtlpriv, u32 addr); + u32(*read32_sync) (struct rtl_priv *rtlpriv, u32 addr); int (*readN_sync) (struct rtl_priv *rtlpriv, u32 addr, u16 len, u8 *pdata); - }; struct rtl_mac { @@ -862,16 +924,24 @@ struct rtl_mac { bool act_scanning; u8 cnt_after_linked; - /*RDG*/ bool rdg_en; + /* early mode */ + /* skb wait queue */ + struct sk_buff_head skb_waitq[MAX_TID_COUNT]; + u8 earlymode_threshold; + + /*RDG*/ + bool rdg_en; - /*AP*/ u8 bssid[6]; - u8 mcs[16]; /*16 bytes mcs for HT rates.*/ - u32 basic_rates; /*b/g rates*/ + /*AP*/ + u8 bssid[6]; + u32 vendor; + u8 mcs[16]; /* 16 bytes mcs for HT rates. */ + u32 basic_rates; /* b/g rates */ u8 ht_enable; u8 sgi_40; u8 sgi_20; u8 bw_40; - u8 mode; /*wireless mode*/ + u8 mode; /* wireless mode */ u8 slot_time; u8 short_preamble; u8 use_cts_protect; @@ -882,9 +952,11 @@ struct rtl_mac { u8 retry_long; u16 assoc_id; - /*IBSS*/ int beacon_interval; + /*IBSS*/ + int beacon_interval; - /*AMPDU*/ u8 min_space_cfg; /*For Min spacing configurations */ + /*AMPDU*/ + u8 min_space_cfg; /*For Min spacing configurations */ u8 max_mss_density; u8 current_ampdu_factor; u8 current_ampdu_density; @@ -899,11 +971,13 @@ struct rtl_hal { enum intf_type interface; u16 hw_type; /*92c or 92d or 92s and so on */ + u8 ic_class; u8 oem_id; u32 version; /*version of chip */ u8 state; /*stop 0, start 1 */ /*firmware */ + u32 fwsize; u8 *pfirmware; u16 fw_version; u16 fw_subversion; @@ -912,6 +986,39 @@ struct rtl_hal { bool fw_ready; /*Reserve page start offset except beacon in TxQ. */ u8 fw_rsvdpage_startoffset; + u8 h2c_txcmd_seq; + + /* FW Cmd IO related */ + u16 fwcmd_iomap; + u32 fwcmd_ioparam; + bool set_fwcmd_inprogress; + u8 current_fwcmd_io; + + /**/ + bool driver_going2unload; + + /*AMPDU init min space*/ + u8 minspace_cfg; /*For Min spacing configurations */ + + /* Dual mac */ + enum macphy_mode macphymode; + enum band_type current_bandtype; /* 0:2.4G, 1:5G */ + enum band_type current_bandtypebackup; + enum band_type bandset; + /* dual MAC 0--Mac0 1--Mac1 */ + u32 interfaceindex; + /* just for DualMac S3S4 */ + u8 macphyctl_reg; + bool earlymode_enable; + /* Dual mac*/ + bool during_mac0init_radiob; + bool during_mac1init_radioa; + bool reloadtxpowerindex; + /* True if IMR or IQK have done + for 2.4G in scan progress */ + bool load_imrandiqk_setting_for2g; + + bool disable_amsdu_8k; }; struct rtl_security { @@ -936,7 +1043,7 @@ struct rtl_security { }; struct rtl_dm { - /*PHY status for DM (dynamic management) */ + /*PHY status for Dynamic Management */ long entry_min_undecoratedsmoothed_pwdb; long undecorated_smoothed_pwdb; /*out dm */ long entry_max_undecoratedsmoothed_pwdb; @@ -951,33 +1058,46 @@ struct rtl_dm { bool txpower_tracking; bool useramask; bool rfpath_rxenable[4]; + bool inform_fw_driverctrldm; + bool current_mrc_switch; + u8 txpowercount; + u8 thermalvalue_rxgain; u8 thermalvalue_iqk; u8 thermalvalue_lck; u8 thermalvalue; u8 last_dtp_lvl; + u8 thermalvalue_avg[AVG_THERMAL_NUM]; + u8 thermalvalue_avg_index; + bool done_txpower; u8 dynamic_txhighpower_lvl; /*Tx high power level */ - u8 dm_flag; /*Indicate if each dynamic mechanism's status. */ + u8 dm_flag; /*Indicate each dynamic mechanism's status. */ u8 dm_type; u8 txpower_track_control; - + bool interrupt_migration; + bool disable_tx_int; char ofdm_index[2]; char cck_index; + u8 power_index_backup[6]; }; -#define EFUSE_MAX_LOGICAL_SIZE 256 +#define EFUSE_MAX_LOGICAL_SIZE 256 struct rtl_efuse { - bool autoload_ok; + bool autoLoad_ok; bool bootfromefuse; u16 max_physical_size; - u8 contents[EFUSE_MAX_LOGICAL_SIZE]; u8 efuse_map[2][EFUSE_MAX_LOGICAL_SIZE]; u16 efuse_usedbytes; u8 efuse_usedpercentage; +#ifdef EFUSE_REPG_WORKAROUND + bool efuse_re_pg_sec1flag; + u8 efuse_re_pg_data[8]; +#endif u8 autoload_failflag; + u8 autoload_status; short epromtype; u16 eeprom_vid; @@ -993,43 +1113,61 @@ struct rtl_efuse { u8 dev_addr[6]; bool txpwr_fromeprom; + u8 eeprom_crystalcap; u8 eeprom_tssi[2]; - u8 eeprom_pwrlimit_ht20[3]; - u8 eeprom_pwrlimit_ht40[3]; - u8 eeprom_chnlarea_txpwr_cck[2][3]; - u8 eeprom_chnlarea_txpwr_ht40_1s[2][3]; - u8 eeprom_chnlarea_txpwr_ht40_2sdiif[2][3]; - u8 txpwrlevel_cck[2][14]; - u8 txpwrlevel_ht40_1s[2][14]; /*For HT 40MHZ pwr */ - u8 txpwrlevel_ht40_2s[2][14]; /*For HT 40MHZ pwr */ + u8 eeprom_tssi_5g[3][2]; /* for 5GL/5GM/5GH band. */ + u8 eeprom_pwrlimit_ht20[CHANNEL_GROUP_MAX]; + u8 eeprom_pwrlimit_ht40[CHANNEL_GROUP_MAX]; + u8 eeprom_chnlarea_txpwr_cck[2][CHANNEL_GROUP_MAX_2G]; + u8 eeprom_chnlarea_txpwr_ht40_1s[2][CHANNEL_GROUP_MAX]; + u8 eeprom_chnlarea_txpwr_ht40_2sdiif[2][CHANNEL_GROUP_MAX]; + u8 txpwrlevel_cck[2][CHANNEL_MAX_NUMBER_2G]; + u8 txpwrlevel_ht40_1s[2][CHANNEL_MAX_NUMBER]; /*For HT 40MHZ pwr */ + u8 txpwrlevel_ht40_2s[2][CHANNEL_MAX_NUMBER]; /*For HT 40MHZ pwr */ + + u8 internal_pa_5g[2]; /* pathA / pathB */ + u8 eeprom_c9; + u8 eeprom_cc; /*For power group */ - u8 pwrgroup_ht20[2][14]; - u8 pwrgroup_ht40[2][14]; - - char txpwr_ht20diff[2][14]; /*HT 20<->40 Pwr diff */ - u8 txpwr_legacyhtdiff[2][14]; /*For HT<->legacy pwr diff */ + u8 eeprom_pwrgroup[2][3]; + u8 pwrgroup_ht20[2][CHANNEL_MAX_NUMBER]; + u8 pwrgroup_ht40[2][CHANNEL_MAX_NUMBER]; + + char txpwr_ht20diff[2][CHANNEL_MAX_NUMBER]; /*HT 20<->40 Pwr diff */ + /*For HT<->legacy pwr diff*/ + u8 txpwr_legacyhtdiff[2][CHANNEL_MAX_NUMBER]; + u8 txpwr_safetyflag; /* Band edge enable flag */ + u16 eeprom_txpowerdiff; + u8 legacy_httxpowerdiff; /* Legacy to HT rate power diff */ + u8 antenna_txpwdiff[3]; u8 eeprom_regulatory; u8 eeprom_thermalmeter; - /*ThermalMeter, index 0 for RFIC0, and 1 for RFIC1 */ - u8 thermalmeter[2]; + u8 thermalmeter[2]; /*ThermalMeter, index 0 for RFIC0, 1 for RFIC1 */ + u16 tssi_13dbm; + u8 crystalcap; /* CrystalCap. */ + u8 delta_iqk; + u8 delta_lck; u8 legacy_ht_txpowerdiff; /*Legacy to HT rate power diff */ bool apk_thermalmeterignore; + + bool b1x1_recvcombine; + bool b1ss_support; + + /*channel plan */ + u8 channel_plan; }; struct rtl_ps_ctl { + bool pwrdomain_protect; bool set_rfpowerstate_inprogress; bool in_powersavemode; bool rfchange_inprogress; bool swrf_processing; bool hwradiooff; - u32 last_sleep_jiffies; - u32 last_awake_jiffies; - u32 last_delaylps_stamp_jiffies; - /* * just for PCIE ASPM * If it supports ASPM, Offset[560h] = 0x40, @@ -1040,6 +1178,7 @@ struct rtl_ps_ctl { /*for LPS */ enum rt_psmode dot11_psmode; /*Power save mode configured. */ + bool swctrl_lps; bool leisure_ps; bool fwctrl_lps; u8 fwctrl_psmode; @@ -1063,8 +1202,25 @@ struct rtl_ps_ctl { u8 const_amdpci_aspm; bool pwrdown_mode; + enum rf_pwrstate inactive_pwrstate; enum rf_pwrstate rfpwr_state; /*cur power state */ + + /* for SW LPS*/ + bool sw_ps_enabled; + bool state; + bool state_inap; + bool multi_buffered; + u16 nullfunc_seq; + unsigned int dtim_counter; + unsigned int sleep_ms; + unsigned long last_sleep_jiffies; + unsigned long last_awake_jiffies; + unsigned long last_delaylps_stamp_jiffies; + unsigned long last_dtim; + unsigned long last_beacon; + unsigned long last_action; + unsigned long last_slept; }; struct rtl_stats { @@ -1103,6 +1259,7 @@ struct rtl_stats { u8 rx_drvinfo_size; u8 rx_bufshift; bool isampdu; + bool isfirst_ampdu; bool rx_is40Mhzpacket; u32 rx_pwdb_all; u8 rx_mimo_signalstrength[4]; /*in 0~100 index */ @@ -1148,6 +1305,15 @@ struct rtl_tcb_desc { u8 ratr_index; u8 mac_id; u8 hw_rate; + + u8 last_inipkt:1; + u8 cmd_or_init:1; + u8 queue_index; + + /* early mode */ + u8 empkt_num; + /* The max value by HW */ + u32 empkt_len[5]; }; struct rtl_hal_ops { @@ -1159,6 +1325,8 @@ struct rtl_hal_ops { u32 *p_inta, u32 *p_intb); int (*hw_init) (struct ieee80211_hw *hw); void (*hw_disable) (struct ieee80211_hw *hw); + void (*hw_suspend) (struct ieee80211_hw *hw); + void (*hw_resume) (struct ieee80211_hw *hw); void (*enable_interrupt) (struct ieee80211_hw *hw); void (*disable_interrupt) (struct ieee80211_hw *hw); int (*set_network_type) (struct ieee80211_hw *hw, @@ -1167,7 +1335,7 @@ struct rtl_hal_ops { bool check_bssid); void (*set_bw_mode) (struct ieee80211_hw *hw, enum nl80211_channel_type ch_type); - u8 (*switch_channel) (struct ieee80211_hw *hw); + u8(*switch_channel) (struct ieee80211_hw *hw); void (*set_qos) (struct ieee80211_hw *hw, int aci); void (*set_bcn_reg) (struct ieee80211_hw *hw); void (*set_bcn_intv) (struct ieee80211_hw *hw); @@ -1219,6 +1387,7 @@ struct rtl_hal_ops { struct rtl_intf_ops { /*com */ + void (*read_efuse_byte)(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf); int (*adapter_start) (struct ieee80211_hw *hw); void (*adapter_stop) (struct ieee80211_hw *hw); @@ -1262,6 +1431,7 @@ struct rtl_hal_usbint_cfg { }; struct rtl_hal_cfg { + u8 bar_id; char *name; char *fw_name; struct rtl_hal_ops *ops; @@ -1285,7 +1455,11 @@ struct rtl_locks { spinlock_t rf_ps_lock; spinlock_t rf_lock; spinlock_t lps_lock; + spinlock_t waitq_lock; spinlock_t tx_urb_lock; + + /*Dual mac*/ + spinlock_t cck_and_rw_pagea_lock; }; struct rtl_works { @@ -1302,12 +1476,20 @@ struct rtl_works { struct workqueue_struct *rtl_wq; struct delayed_work watchdog_wq; struct delayed_work ips_nic_off_wq; + + /* For SW LPS */ + struct delayed_work ps_work; + struct delayed_work ps_rfon_wq; }; struct rtl_debug { u32 dbgp_type[DBGP_TYPE_MAX]; u32 global_debuglevel; u64 global_debugcomponents; + + /* add for proc debug */ + struct proc_dir_entry *proc_dir; + char proc_name[20]; }; struct rtl_priv { @@ -1358,6 +1540,7 @@ struct rtl_priv { #define rtl_efuse(rtlpriv) (&((rtlpriv)->efuse)) #define rtl_psc(rtlpriv) (&((rtlpriv)->psc)) + /*************************************** Bluetooth Co-existance Related ****************************************/ @@ -1441,6 +1624,7 @@ struct bt_coexist_info { }; + /**************************************** mem access macro define start Call endian free function when @@ -1563,10 +1747,15 @@ Set subfield of little-endian 4-byte value to specified value. */ ((((u8)__val) & BIT_LEN_MASK_8(__bitlen)) << (__bitoffset)) \ ); +#define N_BYTE_ALIGMENT(__value, __aligment) ((__aligment == 1) ? \ + (__value) : (((__value + __aligment - 1) / __aligment) * __aligment)) + /**************************************** mem access macro define end ****************************************/ +#define byte(x, n) ((x >> (8 * n)) & 0xff) + #define packet_get_type(_packet) (EF1BYTE((_packet).octet[0]) & 0xFC) #define RTL_WATCH_DOG_TIME 2000 #define MSECS(t) msecs_to_jiffies(t) @@ -1587,6 +1776,8 @@ Set subfield of little-endian 4-byte value to specified value. */ #define RT_RF_OFF_LEVL_FW_32K BIT(5) /*FW in 32k */ /*Always enable ASPM and Clock Req in initialization.*/ #define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT(6) +/* no matter RFOFF or SLEEP we set PS_ASPM_LEVL*/ +#define RT_PS_LEVEL_ASPM BIT(7) /*When LPS is on, disable 2R if no packet is received or transmittd.*/ #define RT_RF_LPS_DISALBE_2R BIT(30) #define RT_RF_LPS_LEVEL_ASPM BIT(31) /*LPS with ASPM */ @@ -1601,8 +1792,10 @@ Set subfield of little-endian 4-byte value to specified value. */ container_of(container_of(x, struct delayed_work, work), y, z) #define FILL_OCTET_STRING(_os, _octet, _len) \ - (_os).octet = (u8 *)(_octet); \ - (_os).length = (_len); + do { \ + (_os). octet = (u8 *)(_octet); \ + (_os). length = (_len); \ + } while (0); #define CP_MACADDR(des, src) \ memcpy((des), (src), ETH_ALEN) -- cgit v1.2.3 From 4295cd254af3181873c7ad15969421d3cb852cf9 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 19 Feb 2011 16:29:12 -0600 Subject: rtlwifi: Move common parts of rtl8192ce/phy.c Move common routines from rtlwifi/rtl8192ce/phy.c and .../rtl8192cu/phy.c into rtlwifi/rtl8192c/phy_common.c. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | 2049 ++++++++++++++++++++ drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | 2035 +------------------ 2 files changed, 2058 insertions(+), 2026 deletions(-) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c new file mode 100644 index 000000000000..3728abc4df59 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c @@ -0,0 +1,2049 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/* Define macro to shorten lines */ +#define MCS_TXPWR mcs_txpwrlevel_origoffset + +static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset); +static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data); +static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset); +static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data); +static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); +static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); +static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); +static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype); +static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype); +static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); +static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, + u32 cmdtableidx, u32 cmdtablesz, + enum swchnlcmd_id cmdid, u32 para1, + u32 para2, u32 msdelay); +static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, u8 *step, + u32 *delay); +static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + long power_indbm); +static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, + enum radio_path rfpath); +static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx); +static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t); + +u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 returnvalue, originalvalue, bitshift; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " + "bitmask(%#x)\n", regaddr, + bitmask)); + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x " + "Addr[0x%x]=0x%x\n", bitmask, + regaddr, originalvalue)); + + return returnvalue; + +} + +void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 originalvalue, bitshift; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," + " data(%#x)\n", regaddr, bitmask, + data)); + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | (data << bitshift)); + } + + rtl_write_dword(rtlpriv, regaddr, data); + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," + " data(%#x)\n", regaddr, bitmask, + data)); + +} + +static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset) +{ + RT_ASSERT(false, ("deprecated!\n")); + return 0; +} + +static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data) +{ + RT_ASSERT(false, ("deprecated!\n")); +} + +static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + u32 newoffset; + u32 tmplong, tmplong2; + u8 rfpi_enable = 0; + u32 retvalue; + + offset &= 0x3f; + newoffset = offset; + if (RT_CANNOT_IO(hw)) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("return all one\n")); + return 0xFFFFFFFF; + } + tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); + if (rfpath == RF90_PATH_A) + tmplong2 = tmplong; + else + tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); + tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | + (newoffset << 23) | BLSSIREADEDGE; + rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, + tmplong & (~BLSSIREADEDGE)); + mdelay(1); + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); + mdelay(1); + rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, + tmplong | BLSSIREADEDGE); + mdelay(1); + if (rfpath == RF90_PATH_A) + rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, + BIT(8)); + else if (rfpath == RF90_PATH_B) + rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, + BIT(8)); + if (rfpi_enable) + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, + BLSSIREADBACKDATA); + else + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, + BLSSIREADBACKDATA); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rflssi_readback, + retvalue)); + return retvalue; +} + +static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data) +{ + u32 data_and_addr; + u32 newoffset; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; + + if (RT_CANNOT_IO(hw)) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("stop\n")); + return; + } + offset &= 0x3f; + newoffset = offset; + data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; + rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, + data_and_addr)); +} + +static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) +{ + u32 i; + + for (i = 0; i <= 31; i++) { + if (((bitmask >> i) & 0x1) == 1) + break; + } + return i; +} + +static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) +{ + rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); + rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022); + rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45); + rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23); + rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1); + rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2); + rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2); +} +bool rtl92c_phy_rf_config(struct ieee80211_hw *hw) +{ + return rtl92c_phy_rf6052_config(hw); +} + +static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + bool rtstatus; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n")); + rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, + BASEBAND_CONFIG_PHY_REG); + if (rtstatus != true) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!")); + return false; + } + if (rtlphy->rf_type == RF_1T2R) { + _rtl92c_phy_bb_config_1t(hw); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n")); + } + if (rtlefuse->autoload_failflag == false) { + rtlphy->pwrgroup_cnt = 0; + rtstatus = _rtl92c_phy_config_bb_with_pgheaderfile(hw, + BASEBAND_CONFIG_PHY_REG); + } + if (rtstatus != true) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!")); + return false; + } + rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, + BASEBAND_CONFIG_AGC_TAB); + if (rtstatus != true) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n")); + return false; + } + rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER2, + 0x200)); + return true; +} + + +void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw) +{ +} + +static void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, + u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (regaddr == RTXAGC_A_RATE18_06) { + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0] = data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0])); + } + if (regaddr == RTXAGC_A_RATE54_24) { + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1] = data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1])); + } + if (regaddr == RTXAGC_A_CCK1_MCS32) { + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6] = data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6])); + } + if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7] = data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7])); + } + if (regaddr == RTXAGC_A_MCS03_MCS00) { + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2] = data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2])); + } + if (regaddr == RTXAGC_A_MCS07_MCS04) { + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3] = data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3])); + } + if (regaddr == RTXAGC_A_MCS11_MCS08) { + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4] = data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4])); + } + if (regaddr == RTXAGC_A_MCS15_MCS12) { + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5] = data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5])); + } + if (regaddr == RTXAGC_B_RATE18_06) { + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8] = data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8])); + } + if (regaddr == RTXAGC_B_RATE54_24) { + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9])); + } + + if (regaddr == RTXAGC_B_CCK1_55_MCS32) { + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14])); + } + + if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15])); + } + + if (regaddr == RTXAGC_B_MCS03_MCS00) { + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10])); + } + + if (regaddr == RTXAGC_B_MCS07_MCS04) { + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11])); + } + + if (regaddr == RTXAGC_B_MCS11_MCS08) { + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12])); + } + + if (regaddr == RTXAGC_B_MCS15_MCS12) { + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13])); + + rtlphy->pwrgroup_cnt++; + } +} + +static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, + enum radio_path rfpath) +{ + return true; +} + +void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + rtlphy->default_initialgain[0] = + (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[1] = + (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[2] = + (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); + rtlphy->default_initialgain[3] = + (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Default initial gain (c50=0x%x, " + "c58=0x%x, c60=0x%x, c68=0x%x\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3])); + + rtlphy->framesync = (u8) rtl_get_bbreg(hw, + ROFDM0_RXDETECTOR3, MASKBYTE0); + rtlphy->framesync_c34 = rtl_get_bbreg(hw, + ROFDM0_RXDETECTOR2, MASKDWORD); + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync)); +} + +static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; + rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = + RFPGA0_XA_LSSIPARAMETER; + rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = + RFPGA0_XB_LSSIPARAMETER; + + rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER; + rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER; + + rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; + rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; + + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; + + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; + + rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; + + rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; + rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; + + rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; + rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; + + rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = + ROFDM0_XARXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = + ROFDM0_XBRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = + ROFDM0_XCRXIQIMBANLANCE; + rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = + ROFDM0_XDRXIQIMBALANCE; + + rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; + rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; + rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; + rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; + + rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = + ROFDM0_XATXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = + ROFDM0_XBTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = + ROFDM0_XCTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = + ROFDM0_XDTXIQIMBALANCE; + + rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; + rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; + rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; + rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; + + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = + RFPGA0_XA_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = + RFPGA0_XB_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = + RFPGA0_XC_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = + RFPGA0_XD_LSSIREADBACK; + + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = + TRANSCEIVEA_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = + TRANSCEIVEB_HSPI_READBACK; + +} + +void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 txpwr_level; + long txpwr_dbm; + + txpwr_level = rtlphy->cur_cck_txpwridx; + txpwr_dbm = _rtl92c_phy_txpwr_idx_to_dbm(hw, + WIRELESS_MODE_B, txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx + + rtlefuse->legacy_ht_txpowerdiff; + if (_rtl92c_phy_txpwr_idx_to_dbm(hw, + WIRELESS_MODE_G, + txpwr_level) > txpwr_dbm) + txpwr_dbm = + _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, + txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx; + if (_rtl92c_phy_txpwr_idx_to_dbm(hw, + WIRELESS_MODE_N_24G, + txpwr_level) > txpwr_dbm) + txpwr_dbm = + _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, + txpwr_level); + *powerlevel = txpwr_dbm; +} + +static void _rtl92c_get_txpower_index(struct ieee80211_hw *hw, u8 channel, + u8 *cckpowerlevel, u8 *ofdmpowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 index = (channel - 1); + + cckpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; + cckpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; + if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) { + ofdmpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; + ofdmpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; + } else if (get_rf_type(rtlphy) == RF_2T2R) { + ofdmpowerlevel[RF90_PATH_A] = + rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index]; + ofdmpowerlevel[RF90_PATH_B] = + rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index]; + } +} + +static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw, + u8 channel, u8 *cckpowerlevel, + u8 *ofdmpowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; + rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; +} + +void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 cckpowerlevel[2], ofdmpowerlevel[2]; + + if (rtlefuse->txpwr_fromeprom == false) + return; + _rtl92c_get_txpower_index(hw, channel, + &cckpowerlevel[0], &ofdmpowerlevel[0]); + _rtl92c_ccxpower_index_check(hw, + channel, &cckpowerlevel[0], + &ofdmpowerlevel[0]); + rtl92c_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); + rtl92c_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel); +} + +bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 idx; + u8 rf_path; + + u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, + WIRELESS_MODE_B, + power_indbm); + u8 ofdmtxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, + WIRELESS_MODE_N_24G, + power_indbm); + if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0) + ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff; + else + ofdmtxpwridx = 0; + RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE, + ("%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", + power_indbm, ccktxpwridx, ofdmtxpwridx)); + for (idx = 0; idx < 14; idx++) { + for (rf_path = 0; rf_path < 2; rf_path++) { + rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; + rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] = + ofdmtxpwridx; + rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] = + ofdmtxpwridx; + } + } + rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); + return true; +} + +void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval) +{ +} + +static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + long power_indbm) +{ + u8 txpwridx; + long offset; + + switch (wirelessmode) { + case WIRELESS_MODE_B: + offset = -7; + break; + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + offset = -8; + break; + default: + offset = -8; + break; + } + + if ((power_indbm - offset) > 0) + txpwridx = (u8) ((power_indbm - offset) * 2); + else + txpwridx = 0; + + if (txpwridx > MAX_TXPWR_IDX_NMODE_92S) + txpwridx = MAX_TXPWR_IDX_NMODE_92S; + + return txpwridx; +} + +static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx) +{ + long offset; + long pwrout_dbm; + + switch (wirelessmode) { + case WIRELESS_MODE_B: + offset = -7; + break; + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + offset = -8; + break; + default: + offset = -8; + break; + } + pwrout_dbm = txpwridx / 2 + offset; + return pwrout_dbm; +} + +void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + enum io_type iotype; + + if (!is_hal_stop(rtlhal)) { + switch (operation) { + case SCAN_OPT_BACKUP: + iotype = IO_CMD_PAUSE_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + + break; + case SCAN_OPT_RESTORE: + iotype = IO_CMD_RESUME_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Unknown Scan Backup operation.\n")); + break; + } + } +} + +void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_bw = rtlphy->current_chan_bw; + + if (rtlphy->set_bwmode_inprogress) + return; + rtlphy->set_bwmode_inprogress = true; + if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) + rtl92c_phy_set_bw_mode_callback(hw); + else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("FALSE driver sleep or unload\n")); + rtlphy->set_bwmode_inprogress = false; + rtlphy->current_chan_bw = tmp_bw; + } +} + +void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 delay; + + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, + ("switch to channel%d\n", rtlphy->current_channel)); + if (is_hal_stop(rtlhal)) + return; + do { + if (!rtlphy->sw_chnl_inprogress) + break; + if (!_rtl92c_phy_sw_chnl_step_by_step + (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, + &rtlphy->sw_chnl_step, &delay)) { + if (delay > 0) + mdelay(delay); + else + continue; + } else + rtlphy->sw_chnl_inprogress = false; + break; + } while (true); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); +} + +u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (rtlphy->sw_chnl_inprogress) + return 0; + if (rtlphy->set_bwmode_inprogress) + return 0; + RT_ASSERT((rtlphy->current_channel <= 14), + ("WIRELESS_MODE_G but channel>14")); + rtlphy->sw_chnl_inprogress = true; + rtlphy->sw_chnl_stage = 0; + rtlphy->sw_chnl_step = 0; + if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { + rtl92c_phy_sw_chnl_callback(hw); + RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, + ("sw_chnl_inprogress false schdule workitem\n")); + rtlphy->sw_chnl_inprogress = false; + } else { + RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, + ("sw_chnl_inprogress false driver sleep or" + " unload\n")); + rtlphy->sw_chnl_inprogress = false; + } + return 1; +} + +static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, u8 *step, + u32 *delay) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; + u32 precommoncmdcnt; + struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; + u32 postcommoncmdcnt; + struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; + u32 rfdependcmdcnt; + struct swchnlcmd *currentcmd = NULL; + u8 rfpath; + u8 num_total_rfpath = rtlphy->num_total_rfpath; + + precommoncmdcnt = 0; + _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, + CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); + _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, + MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); + + postcommoncmdcnt = 0; + + _rtl92c_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, + MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); + + rfdependcmdcnt = 0; + + RT_ASSERT((channel >= 1 && channel <= 14), + ("illegal channel for Zebra: %d\n", channel)); + + _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, + RF_CHNLBW, channel, 10); + + _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, + MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, + 0); + + do { + switch (*stage) { + case 0: + currentcmd = &precommoncmd[*step]; + break; + case 1: + currentcmd = &rfdependcmd[*step]; + break; + case 2: + currentcmd = &postcommoncmd[*step]; + break; + } + + if (currentcmd->cmdid == CMDID_END) { + if ((*stage) == 2) { + return true; + } else { + (*stage)++; + (*step) = 0; + continue; + } + } + + switch (currentcmd->cmdid) { + case CMDID_SET_TXPOWEROWER_LEVEL: + rtl92c_phy_set_txpower_level(hw, channel); + break; + case CMDID_WRITEPORT_ULONG: + rtl_write_dword(rtlpriv, currentcmd->para1, + currentcmd->para2); + break; + case CMDID_WRITEPORT_USHORT: + rtl_write_word(rtlpriv, currentcmd->para1, + (u16) currentcmd->para2); + break; + case CMDID_WRITEPORT_UCHAR: + rtl_write_byte(rtlpriv, currentcmd->para1, + (u8) currentcmd->para2); + break; + case CMDID_RF_WRITEREG: + for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { + rtlphy->rfreg_chnlval[rfpath] = + ((rtlphy->rfreg_chnlval[rfpath] & + 0xfffffc00) | currentcmd->para2); + + rtl_set_rfreg(hw, (enum radio_path)rfpath, + currentcmd->para1, + RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[rfpath]); + } + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + + break; + } while (true); + + (*delay) = currentcmd->msdelay; + (*step)++; + return false; +} + +static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, + u32 cmdtableidx, u32 cmdtablesz, + enum swchnlcmd_id cmdid, + u32 para1, u32 para2, u32 msdelay) +{ + struct swchnlcmd *pcmd; + + if (cmdtable == NULL) { + RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); + return false; + } + + if (cmdtableidx >= cmdtablesz) + return false; + + pcmd = cmdtable + cmdtableidx; + pcmd->cmdid = cmdid; + pcmd->para1 = para1; + pcmd->para2 = para2; + pcmd->msdelay = msdelay; + return true; +} + +bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath) +{ + return true; +} + +static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) +{ + u32 reg_eac, reg_e94, reg_e9c, reg_ea4; + u8 result = 0x00; + + rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f); + rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f); + rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102); + rtl_set_bbreg(hw, 0xe3c, MASKDWORD, + config_pathb ? 0x28160202 : 0x28160502); + + if (config_pathb) { + rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22); + rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22); + rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102); + rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202); + } + + rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1); + rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); + reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); + reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); + reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && + (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; + + if (!(reg_eac & BIT(27)) && + (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && + (((reg_eac & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + return result; +} + +static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw) +{ + u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; + u8 result = 0x00; + + rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); + rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); + mdelay(IQK_DELAY_TIME); + reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); + reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); + reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); + reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); + reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); + if (!(reg_eac & BIT(31)) && + (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && + (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; + + if (!(reg_eac & BIT(30)) && + (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && + (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + return result; +} + +static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, + bool iqk_ok, long result[][8], + u8 final_candidate, bool btxonly) +{ + u32 oldval_0, x, tx0_a, reg; + long y, tx0_c; + + if (final_candidate == 0xFF) + return; + else if (iqk_ok) { + oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, + MASKDWORD) >> 22) & 0x3FF; + x = result[final_candidate][0]; + if ((x & 0x00000200) != 0) + x = x | 0xFFFFFC00; + tx0_a = (x * oldval_0) >> 8; + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), + ((x * oldval_0 >> 7) & 0x1)); + y = result[final_candidate][1]; + if ((y & 0x00000200) != 0) + y = y | 0xFFFFFC00; + tx0_c = (y * oldval_0) >> 8; + rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, + ((tx0_c & 0x3C0) >> 6)); + rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, + (tx0_c & 0x3F)); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), + ((y * oldval_0 >> 7) & 0x1)); + if (btxonly) + return; + reg = result[final_candidate][2]; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][3] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][3] >> 6) & 0xF; + rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); + } +} + +static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, + bool iqk_ok, long result[][8], + u8 final_candidate, bool btxonly) +{ + u32 oldval_1, x, tx1_a, reg; + long y, tx1_c; + + if (final_candidate == 0xFF) + return; + else if (iqk_ok) { + oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, + MASKDWORD) >> 22) & 0x3FF; + x = result[final_candidate][4]; + if ((x & 0x00000200) != 0) + x = x | 0xFFFFFC00; + tx1_a = (x * oldval_1) >> 8; + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27), + ((x * oldval_1 >> 7) & 0x1)); + y = result[final_candidate][5]; + if ((y & 0x00000200) != 0) + y = y | 0xFFFFFC00; + tx1_c = (y * oldval_1) >> 8; + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, + ((tx1_c & 0x3C0) >> 6)); + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, + (tx1_c & 0x3F)); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25), + ((y * oldval_1 >> 7) & 0x1)); + if (btxonly) + return; + reg = result[final_candidate][6]; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][7] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][7] >> 6) & 0xF; + rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg); + } +} + +static void _rtl92c_phy_save_adda_registers(struct ieee80211_hw *hw, + u32 *addareg, u32 *addabackup, + u32 registernum) +{ + u32 i; + + for (i = 0; i < registernum; i++) + addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); +} + +static void _rtl92c_phy_save_mac_registers(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); + macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); +} + +static void _rtl92c_phy_reload_adda_registers(struct ieee80211_hw *hw, + u32 *addareg, u32 *addabackup, + u32 regiesternum) +{ + u32 i; + + for (i = 0; i < regiesternum; i++) + rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); +} + +static void _rtl92c_phy_reload_mac_registers(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) + rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); + rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); +} + +static void _rtl92c_phy_path_adda_on(struct ieee80211_hw *hw, + u32 *addareg, bool is_patha_on, bool is2t) +{ + u32 pathOn; + u32 i; + + pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4; + if (false == is2t) { + pathOn = 0x0bdb25a0; + rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0); + } else { + rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn); + } + + for (i = 1; i < IQK_ADDA_REG_NUM; i++) + rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn); +} + +static void _rtl92c_phy_mac_setting_calibration(struct ieee80211_hw *hw, + u32 *macreg, u32 *macbackup) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + + rtl_write_byte(rtlpriv, macreg[0], 0x3F); + + for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) + rtl_write_byte(rtlpriv, macreg[i], + (u8) (macbackup[i] & (~BIT(3)))); + rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5)))); +} + +static void _rtl92c_phy_path_a_standby(struct ieee80211_hw *hw) +{ + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); + rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); +} + +static void _rtl92c_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode) +{ + u32 mode; + + mode = pi_mode ? 0x01000100 : 0x01000000; + rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); + rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); +} + +static bool _rtl92c_phy_simularity_compare(struct ieee80211_hw *hw, + long result[][8], u8 c1, u8 c2) +{ + u32 i, j, diff, simularity_bitmap, bound; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + u8 final_candidate[2] = { 0xFF, 0xFF }; + bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version); + + if (is2t) + bound = 8; + else + bound = 4; + + simularity_bitmap = 0; + + for (i = 0; i < bound; i++) { + diff = (result[c1][i] > result[c2][i]) ? + (result[c1][i] - result[c2][i]) : + (result[c2][i] - result[c1][i]); + + if (diff > MAX_TOLERANCE) { + if ((i == 2 || i == 6) && !simularity_bitmap) { + if (result[c1][i] + result[c1][i + 1] == 0) + final_candidate[(i / 4)] = c2; + else if (result[c2][i] + result[c2][i + 1] == 0) + final_candidate[(i / 4)] = c1; + else + simularity_bitmap = simularity_bitmap | + (1 << i); + } else + simularity_bitmap = + simularity_bitmap | (1 << i); + } + } + + if (simularity_bitmap == 0) { + for (i = 0; i < (bound / 4); i++) { + if (final_candidate[i] != 0xFF) { + for (j = i * 4; j < (i + 1) * 4 - 2; j++) + result[3][j] = + result[final_candidate[i]][j]; + bresult = false; + } + } + return bresult; + } else if (!(simularity_bitmap & 0x0F)) { + for (i = 0; i < 4; i++) + result[3][i] = result[c1][i]; + return false; + } else if (!(simularity_bitmap & 0xF0) && is2t) { + for (i = 4; i < 8; i++) + result[3][i] = result[c1][i]; + return false; + } else { + return false; + } + +} + +static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, + long result[][8], u8 t, bool is2t) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 i; + u8 patha_ok, pathb_ok; + u32 adda_reg[IQK_ADDA_REG_NUM] = { + 0x85c, 0xe6c, 0xe70, 0xe74, + 0xe78, 0xe7c, 0xe80, 0xe84, + 0xe88, 0xe8c, 0xed0, 0xed4, + 0xed8, 0xedc, 0xee0, 0xeec + }; + + u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { + 0x522, 0x550, 0x551, 0x040 + }; + + const u32 retrycount = 2; + + u32 bbvalue; + + if (t == 0) { + bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD); + + _rtl92c_phy_save_adda_registers(hw, adda_reg, + rtlphy->adda_backup, 16); + _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + } + _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t); + if (t == 0) { + rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER1, + BIT(8)); + } + if (!rtlphy->rfpi_enable) + _rtl92c_phy_pi_mode_switch(hw, true); + if (t == 0) { + rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); + rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); + rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD); + } + rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); + rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); + rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); + if (is2t) { + rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); + rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); + } + _rtl92c_phy_mac_setting_calibration(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000); + if (is2t) + rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); + rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800); + for (i = 0; i < retrycount; i++) { + patha_ok = _rtl92c_phy_path_a_iqk(hw, is2t); + if (patha_ok == 0x03) { + result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & + 0x3FF0000) >> 16; + break; + } else if (i == (retrycount - 1) && patha_ok == 0x01) + result[t][0] = (rtl_get_bbreg(hw, 0xe94, + MASKDWORD) & 0x3FF0000) >> + 16; + result[t][1] = + (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; + + } + + if (is2t) { + _rtl92c_phy_path_a_standby(hw); + _rtl92c_phy_path_adda_on(hw, adda_reg, false, is2t); + for (i = 0; i < retrycount; i++) { + pathb_ok = _rtl92c_phy_path_b_iqk(hw); + if (pathb_ok == 0x03) { + result[t][4] = (rtl_get_bbreg(hw, + 0xeb4, + MASKDWORD) & + 0x3FF0000) >> 16; + result[t][5] = + (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][6] = + (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][7] = + (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & + 0x3FF0000) >> 16; + break; + } else if (i == (retrycount - 1) && pathb_ok == 0x01) { + result[t][4] = (rtl_get_bbreg(hw, + 0xeb4, + MASKDWORD) & + 0x3FF0000) >> 16; + } + result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & + 0x3FF0000) >> 16; + } + } + rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); + rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874); + rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08); + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); + rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); + if (is2t) + rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); + if (t != 0) { + if (!rtlphy->rfpi_enable) + _rtl92c_phy_pi_mode_switch(hw, false); + _rtl92c_phy_reload_adda_registers(hw, adda_reg, + rtlphy->adda_backup, 16); + _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); + } +} + +static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, + char delta, bool is2t) +{ + /* This routine is deliberately dummied out for later fixes */ +#if 0 + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + + u32 reg_d[PATH_NUM]; + u32 tmpreg, index, offset, path, i, pathbound = PATH_NUM, apkbound; + + u32 bb_backup[APK_BB_REG_NUM]; + u32 bb_reg[APK_BB_REG_NUM] = { + 0x904, 0xc04, 0x800, 0xc08, 0x874 + }; + u32 bb_ap_mode[APK_BB_REG_NUM] = { + 0x00000020, 0x00a05430, 0x02040000, + 0x000800e4, 0x00204000 + }; + u32 bb_normal_ap_mode[APK_BB_REG_NUM] = { + 0x00000020, 0x00a05430, 0x02040000, + 0x000800e4, 0x22204000 + }; + + u32 afe_backup[APK_AFE_REG_NUM]; + u32 afe_reg[APK_AFE_REG_NUM] = { + 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, + 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, + 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, + 0xeec + }; + + u32 mac_backup[IQK_MAC_REG_NUM]; + u32 mac_reg[IQK_MAC_REG_NUM] = { + 0x522, 0x550, 0x551, 0x040 + }; + + u32 apk_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { + {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c}, + {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e} + }; + + u32 apk_normal_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { + {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c}, + {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c} + }; + + u32 apk_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { + {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d}, + {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050} + }; + + u32 apk_normal_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { + {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}, + {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a} + }; + + u32 afe_on_off[PATH_NUM] = { + 0x04db25a4, 0x0b1b25a4 + }; + + u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c }; + + u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 }; + + u32 apk_value[PATH_NUM] = { 0x92fc0000, 0x12fc0000 }; + + u32 apk_normal_value[PATH_NUM] = { 0x92680000, 0x12680000 }; + + const char apk_delta_mapping[APK_BB_REG_NUM][13] = { + {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6}, + {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0} + }; + + const u32 apk_normal_setting_value_1[13] = { + 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28, + 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3, + 0x12680000, 0x00880000, 0x00880000 + }; + + const u32 apk_normal_setting_value_2[16] = { + 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3, + 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025, + 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008, + 0x00050006 + }; + + const u32 apk_result[PATH_NUM][APK_BB_REG_NUM]; + + long bb_offset, delta_v, delta_offset; + + if (!is2t) + pathbound = 1; + + for (index = 0; index < PATH_NUM; index++) { + apk_offset[index] = apk_normal_offset[index]; + apk_value[index] = apk_normal_value[index]; + afe_on_off[index] = 0x6fdb25a4; + } + + for (index = 0; index < APK_BB_REG_NUM; index++) { + for (path = 0; path < pathbound; path++) { + apk_rf_init_value[path][index] = + apk_normal_rf_init_value[path][index]; + apk_rf_value_0[path][index] = + apk_normal_rf_value_0[path][index]; + } + bb_ap_mode[index] = bb_normal_ap_mode[index]; + + apkbound = 6; + } + + for (index = 0; index < APK_BB_REG_NUM; index++) { + if (index == 0) + continue; + bb_backup[index] = rtl_get_bbreg(hw, bb_reg[index], MASKDWORD); + } + + _rtl92c_phy_save_mac_registers(hw, mac_reg, mac_backup); + + _rtl92c_phy_save_adda_registers(hw, afe_reg, afe_backup, 16); + + for (path = 0; path < pathbound; path++) { + if (path == RF90_PATH_A) { + offset = 0xb00; + for (index = 0; index < 11; index++) { + rtl_set_bbreg(hw, offset, MASKDWORD, + apk_normal_setting_value_1 + [index]); + + offset += 0x04; + } + + rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); + + offset = 0xb68; + for (; index < 13; index++) { + rtl_set_bbreg(hw, offset, MASKDWORD, + apk_normal_setting_value_1 + [index]); + + offset += 0x04; + } + + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); + + offset = 0xb00; + for (index = 0; index < 16; index++) { + rtl_set_bbreg(hw, offset, MASKDWORD, + apk_normal_setting_value_2 + [index]); + + offset += 0x04; + } + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); + } else if (path == RF90_PATH_B) { + offset = 0xb70; + for (index = 0; index < 10; index++) { + rtl_set_bbreg(hw, offset, MASKDWORD, + apk_normal_setting_value_1 + [index]); + + offset += 0x04; + } + rtl_set_bbreg(hw, 0xb28, MASKDWORD, 0x12680000); + rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); + + offset = 0xb68; + index = 11; + for (; index < 13; index++) { + rtl_set_bbreg(hw, offset, MASKDWORD, + apk_normal_setting_value_1 + [index]); + + offset += 0x04; + } + + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); + + offset = 0xb60; + for (index = 0; index < 16; index++) { + rtl_set_bbreg(hw, offset, MASKDWORD, + apk_normal_setting_value_2 + [index]); + + offset += 0x04; + } + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); + } + + reg_d[path] = rtl_get_rfreg(hw, (enum radio_path)path, + 0xd, MASKDWORD); + + for (index = 0; index < APK_AFE_REG_NUM; index++) + rtl_set_bbreg(hw, afe_reg[index], MASKDWORD, + afe_on_off[path]); + + if (path == RF90_PATH_A) { + for (index = 0; index < APK_BB_REG_NUM; index++) { + if (index == 0) + continue; + rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, + bb_ap_mode[index]); + } + } + + _rtl92c_phy_mac_setting_calibration(hw, mac_reg, mac_backup); + + if (path == 0) { + rtl_set_rfreg(hw, RF90_PATH_B, 0x0, MASKDWORD, 0x10000); + } else { + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASKDWORD, + 0x10000); + rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, + 0x1000f); + rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, + 0x20103); + } + + delta_offset = ((delta + 14) / 2); + if (delta_offset < 0) + delta_offset = 0; + else if (delta_offset > 12) + delta_offset = 12; + + for (index = 0; index < APK_BB_REG_NUM; index++) { + if (index != 1) + continue; + + tmpreg = apk_rf_init_value[path][index]; + + if (!rtlefuse->apk_thermalmeterignore) { + bb_offset = (tmpreg & 0xF0000) >> 16; + + if (!(tmpreg & BIT(15))) + bb_offset = -bb_offset; + + delta_v = + apk_delta_mapping[index][delta_offset]; + + bb_offset += delta_v; + + if (bb_offset < 0) { + tmpreg = tmpreg & (~BIT(15)); + bb_offset = -bb_offset; + } else { + tmpreg = tmpreg | BIT(15); + } + + tmpreg = + (tmpreg & 0xFFF0FFFF) | (bb_offset << 16); + } + + rtl_set_rfreg(hw, (enum radio_path)path, 0xc, + MASKDWORD, 0x8992e); + rtl_set_rfreg(hw, (enum radio_path)path, 0x0, + MASKDWORD, apk_rf_value_0[path][index]); + rtl_set_rfreg(hw, (enum radio_path)path, 0xd, + MASKDWORD, tmpreg); + + i = 0; + do { + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80000000); + rtl_set_bbreg(hw, apk_offset[path], + MASKDWORD, apk_value[0]); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("PHY_APCalibrate() offset 0x%x " + "value 0x%x\n", + apk_offset[path], + rtl_get_bbreg(hw, apk_offset[path], + MASKDWORD))); + + mdelay(3); + + rtl_set_bbreg(hw, apk_offset[path], + MASKDWORD, apk_value[1]); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("PHY_APCalibrate() offset 0x%x " + "value 0x%x\n", + apk_offset[path], + rtl_get_bbreg(hw, apk_offset[path], + MASKDWORD))); + + mdelay(20); + + rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); + + if (path == RF90_PATH_A) + tmpreg = rtl_get_bbreg(hw, 0xbd8, + 0x03E00000); + else + tmpreg = rtl_get_bbreg(hw, 0xbd8, + 0xF8000000); + + RTPRINT(rtlpriv, FINIT, INIT_IQK, + ("PHY_APCalibrate() offset " + "0xbd8[25:21] %x\n", tmpreg)); + + i++; + + } while (tmpreg > apkbound && i < 4); + + apk_result[path][index] = tmpreg; + } + } + + _rtl92c_phy_reload_mac_registers(hw, mac_reg, mac_backup); + + for (index = 0; index < APK_BB_REG_NUM; index++) { + if (index == 0) + continue; + rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, bb_backup[index]); + } + + _rtl92c_phy_reload_adda_registers(hw, afe_reg, afe_backup, 16); + + for (path = 0; path < pathbound; path++) { + rtl_set_rfreg(hw, (enum radio_path)path, 0xd, + MASKDWORD, reg_d[path]); + + if (path == RF90_PATH_B) { + rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, + 0x1000f); + rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, + 0x20101); + } + + if (apk_result[path][1] > 6) + apk_result[path][1] = 6; + } + + for (path = 0; path < pathbound; path++) { + rtl_set_rfreg(hw, (enum radio_path)path, 0x3, MASKDWORD, + ((apk_result[path][1] << 15) | + (apk_result[path][1] << 10) | + (apk_result[path][1] << 5) | + apk_result[path][1])); + + if (path == RF90_PATH_A) + rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, + ((apk_result[path][1] << 15) | + (apk_result[path][1] << 10) | + (0x00 << 5) | 0x05)); + else + rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, + ((apk_result[path][1] << 15) | + (apk_result[path][1] << 10) | + (0x02 << 5) | 0x05)); + + rtl_set_rfreg(hw, (enum radio_path)path, 0xe, MASKDWORD, + ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) | + 0x08)); + + } + + rtlphy->apk_done = true; +#endif +} + +static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, + bool bmain, bool is2t) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (is_hal_stop(rtlhal)) { + rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01); + rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); + } + if (is2t) { + if (bmain) + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(5) | BIT(6), 0x1); + else + rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, + BIT(5) | BIT(6), 0x2); + } else { + if (bmain) + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2); + else + rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1); + + } +} + +#undef IQK_ADDA_REG_NUM +#undef IQK_DELAY_TIME + +void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + long result[4][8]; + u8 i, final_candidate; + bool patha_ok, pathb_ok; + long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, + reg_ecc, reg_tmp = 0; + bool is12simular, is13simular, is23simular; + bool start_conttx = false, singletone = false; + u32 iqk_bb_reg[10] = { + ROFDM0_XARXIQIMBALANCE, + ROFDM0_XBRXIQIMBALANCE, + ROFDM0_ECCATHRESHOLD, + ROFDM0_AGCRSSITABLE, + ROFDM0_XATXIQIMBALANCE, + ROFDM0_XBTXIQIMBALANCE, + ROFDM0_XCTXIQIMBALANCE, + ROFDM0_XCTXAFE, + ROFDM0_XDTXAFE, + ROFDM0_RXIQEXTANTA + }; + + if (recovery) { + _rtl92c_phy_reload_adda_registers(hw, + iqk_bb_reg, + rtlphy->iqk_bb_backup, 10); + return; + } + if (start_conttx || singletone) + return; + for (i = 0; i < 8; i++) { + result[0][i] = 0; + result[1][i] = 0; + result[2][i] = 0; + result[3][i] = 0; + } + final_candidate = 0xff; + patha_ok = false; + pathb_ok = false; + is12simular = false; + is23simular = false; + is13simular = false; + for (i = 0; i < 3; i++) { + if (IS_92C_SERIAL(rtlhal->version)) + _rtl92c_phy_iq_calibrate(hw, result, i, true); + else + _rtl92c_phy_iq_calibrate(hw, result, i, false); + if (i == 1) { + is12simular = _rtl92c_phy_simularity_compare(hw, + result, 0, + 1); + if (is12simular) { + final_candidate = 0; + break; + } + } + if (i == 2) { + is13simular = _rtl92c_phy_simularity_compare(hw, + result, 0, + 2); + if (is13simular) { + final_candidate = 0; + break; + } + is23simular = _rtl92c_phy_simularity_compare(hw, + result, 1, + 2); + if (is23simular) + final_candidate = 1; + else { + for (i = 0; i < 8; i++) + reg_tmp += result[3][i]; + + if (reg_tmp != 0) + final_candidate = 3; + else + final_candidate = 0xFF; + } + } + } + for (i = 0; i < 4; i++) { + reg_e94 = result[i][0]; + reg_e9c = result[i][1]; + reg_ea4 = result[i][2]; + reg_eac = result[i][3]; + reg_eb4 = result[i][4]; + reg_ebc = result[i][5]; + reg_ec4 = result[i][6]; + reg_ecc = result[i][7]; + } + if (final_candidate != 0xff) { + rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; + rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; + reg_ea4 = result[final_candidate][2]; + reg_eac = result[final_candidate][3]; + rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; + rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; + reg_ec4 = result[final_candidate][6]; + reg_ecc = result[final_candidate][7]; + patha_ok = pathb_ok = true; + } else { + rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; + rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; + } + if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ + _rtl92c_phy_path_a_fill_iqk_matrix(hw, patha_ok, result, + final_candidate, + (reg_ea4 == 0)); + if (IS_92C_SERIAL(rtlhal->version)) { + if (reg_eb4 != 0) /*&&(reg_ec4 != 0) */ + _rtl92c_phy_path_b_fill_iqk_matrix(hw, pathb_ok, + result, + final_candidate, + (reg_ec4 == 0)); + } + _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, 10); +} + +void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool start_conttx = false, singletone = false; + + if (start_conttx || singletone) + return; + if (IS_92C_SERIAL(rtlhal->version)) + _rtl92c_phy_lc_calibrate(hw, true); + else + _rtl92c_phy_lc_calibrate(hw, false); +} + +void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (rtlphy->apk_done) + return; + if (IS_92C_SERIAL(rtlhal->version)) + _rtl92c_phy_ap_calibrate(hw, delta, true); + else + _rtl92c_phy_ap_calibrate(hw, delta, false); +} + +void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (IS_92C_SERIAL(rtlhal->version)) + _rtl92c_phy_set_rfpath_switch(hw, bmain, true); + else + _rtl92c_phy_set_rfpath_switch(hw, bmain, false); +} + +bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + bool postprocessing = false; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("-->IO Cmd(%#x), set_io_inprogress(%d)\n", + iotype, rtlphy->set_io_inprogress)); + do { + switch (iotype) { + case IO_CMD_RESUME_DM_BY_SCAN: + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("[IO CMD] Resume DM after scan.\n")); + postprocessing = true; + break; + case IO_CMD_PAUSE_DM_BY_SCAN: + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("[IO CMD] Pause DM before scan.\n")); + postprocessing = true; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + } while (false); + if (postprocessing && !rtlphy->set_io_inprogress) { + rtlphy->set_io_inprogress = true; + rtlphy->current_io_type = iotype; + } else { + return false; + } + rtl92c_phy_set_io(hw); + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype)); + return true; +} + +void rtl92c_phy_set_io(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress)); + switch (rtlphy->current_io_type) { + case IO_CMD_RESUME_DM_BY_SCAN: + dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1; + rtl92c_dm_write_dig(hw); + rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); + break; + case IO_CMD_PAUSE_DM_BY_SCAN: + rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue; + dm_digtable.cur_igvalue = 0x17; + rtl92c_dm_write_dig(hw); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + rtlphy->set_io_inprogress = false; + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + ("<---(%#x)\n", rtlphy->current_io_type)); +} + +void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); +} + +static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw) +{ + u32 u4b_tmp; + u8 delay = 5; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); + while (u4b_tmp != 0 && delay > 0) { + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); + u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); + delay--; + } + if (delay == 0) { + rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, + ("Switch RF timeout !!!.\n")); + return; + } + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 4b256d0bebcc..191106033b3c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -37,85 +37,7 @@ #include "dm.h" #include "table.h" -/* Define macro to shorten lines */ -#define MCS_TXPWR mcs_txpwrlevel_origoffset - -static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset); -static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, - u32 data); -static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset); -static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, - u32 data); -static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); -static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); -static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); -static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, - u8 configtype); -static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, - u8 configtype); -static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); -static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, - u32 cmdtableidx, u32 cmdtablesz, - enum swchnlcmd_id cmdid, u32 para1, - u32 para2, u32 msdelay); -static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, - u8 channel, u8 *stage, u8 *step, - u32 *delay); -static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, - long power_indbm); -static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, - enum radio_path rfpath); -static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, - u8 txpwridx); -u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 returnvalue, originalvalue, bitshift; - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "bitmask(%#x)\n", regaddr, - bitmask)); - originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); - returnvalue = (originalvalue & bitmask) >> bitshift; - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x " - "Addr[0x%x]=0x%x\n", bitmask, - regaddr, originalvalue)); - - return returnvalue; - -} - -void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask, u32 data) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 originalvalue, bitshift; - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, - data)); - - if (bitmask != MASKDWORD) { - originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); - data = ((originalvalue & (~bitmask)) | (data << bitshift)); - } - - rtl_write_dword(rtlpriv, regaddr, data); - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, - data)); - -} +#include "../rtl8192c/phy_common.c" u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, u32 regaddr, u32 bitmask) @@ -200,118 +122,6 @@ void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, bitmask, data, rfpath)); } -static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset) -{ - RT_ASSERT(false, ("deprecated!\n")); - return 0; -} - -static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, - u32 data) -{ - RT_ASSERT(false, ("deprecated!\n")); -} - -static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; - u32 newoffset; - u32 tmplong, tmplong2; - u8 rfpi_enable = 0; - u32 retvalue; - - offset &= 0x3f; - newoffset = offset; - if (RT_CANNOT_IO(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("return all one\n")); - return 0xFFFFFFFF; - } - tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); - if (rfpath == RF90_PATH_A) - tmplong2 = tmplong; - else - tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); - tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | - (newoffset << 23) | BLSSIREADEDGE; - rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, - tmplong & (~BLSSIREADEDGE)); - mdelay(1); - rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); - mdelay(1); - rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, - tmplong | BLSSIREADEDGE); - mdelay(1); - if (rfpath == RF90_PATH_A) - rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, - BIT(8)); - else if (rfpath == RF90_PATH_B) - rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, - BIT(8)); - if (rfpi_enable) - retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, - BLSSIREADBACKDATA); - else - retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, - BLSSIREADBACKDATA); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rflssi_readback, - retvalue)); - return retvalue; -} - -static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, - u32 data) -{ - u32 data_and_addr; - u32 newoffset; - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; - - if (RT_CANNOT_IO(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("stop\n")); - return; - } - offset &= 0x3f; - newoffset = offset; - data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; - rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf3wire_offset, - data_and_addr)); -} - -static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) -{ - u32 i; - - for (i = 0; i <= 31; i++) { - if (((bitmask >> i) & 0x1) == 1) - break; - } - return i; -} - -static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) -{ - rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); - rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022); - rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45); - rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23); - rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1); - rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2); - rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2); - rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2); - rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2); - rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2); -} - bool rtl92c_phy_mac_config(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -350,50 +160,6 @@ bool rtl92c_phy_bb_config(struct ieee80211_hw *hw) return rtstatus; } -bool rtl92c_phy_rf_config(struct ieee80211_hw *hw) -{ - return rtl92c_phy_rf6052_config(hw); -} - -static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - bool rtstatus; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n")); - rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, - BASEBAND_CONFIG_PHY_REG); - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!")); - return false; - } - if (rtlphy->rf_type == RF_1T2R) { - _rtl92c_phy_bb_config_1t(hw); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n")); - } - if (rtlefuse->autoload_failflag == false) { - rtlphy->pwrgroup_cnt = 0; - rtstatus = _rtl92c_phy_config_bb_with_pgheaderfile(hw, - BASEBAND_CONFIG_PHY_REG); - } - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!")); - return false; - } - rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, - BASEBAND_CONFIG_AGC_TAB); - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n")); - return false; - } - rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, - RFPGA0_XA_HSSIPARAMETER2, - 0x200)); - return true; -} - static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -411,10 +177,6 @@ static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) return true; } -void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw) -{ -} - static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, u8 configtype) { @@ -475,142 +237,6 @@ static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, return true; } -static void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask, - u32 data) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - if (regaddr == RTXAGC_A_RATE18_06) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0])); - } - if (regaddr == RTXAGC_A_RATE54_24) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1])); - } - if (regaddr == RTXAGC_A_CCK1_MCS32) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6])); - } - if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7])); - } - if (regaddr == RTXAGC_A_MCS03_MCS00) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2])); - } - if (regaddr == RTXAGC_A_MCS07_MCS04) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3])); - } - if (regaddr == RTXAGC_A_MCS11_MCS08) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4])); - } - if (regaddr == RTXAGC_A_MCS15_MCS12) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5])); - } - if (regaddr == RTXAGC_B_RATE18_06) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8])); - } - if (regaddr == RTXAGC_B_RATE54_24) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9])); - } - - if (regaddr == RTXAGC_B_CCK1_55_MCS32) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14])); - } - - if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15])); - } - - if (regaddr == RTXAGC_B_MCS03_MCS00) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10])); - } - - if (regaddr == RTXAGC_B_MCS07_MCS04) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11])); - } - - if (regaddr == RTXAGC_B_MCS11_MCS08) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12])); - } - - if (regaddr == RTXAGC_B_MCS15_MCS12) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13])); - - rtlphy->pwrgroup_cnt++; - } -} - static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, u8 configtype) { @@ -650,12 +276,6 @@ static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, return true; } -static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, - enum radio_path rfpath) -{ - return true; -} - bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, enum radio_path rfpath) { @@ -747,345 +367,6 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, return true; } -void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - rtlphy->default_initialgain[0] = - (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); - rtlphy->default_initialgain[1] = - (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); - rtlphy->default_initialgain[2] = - (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); - rtlphy->default_initialgain[3] = - (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Default initial gain (c50=0x%x, " - "c58=0x%x, c60=0x%x, c68=0x%x\n", - rtlphy->default_initialgain[0], - rtlphy->default_initialgain[1], - rtlphy->default_initialgain[2], - rtlphy->default_initialgain[3])); - - rtlphy->framesync = (u8) rtl_get_bbreg(hw, - ROFDM0_RXDETECTOR3, MASKBYTE0); - rtlphy->framesync_c34 = rtl_get_bbreg(hw, - ROFDM0_RXDETECTOR2, MASKDWORD); - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Default framesync (0x%x) = 0x%x\n", - ROFDM0_RXDETECTOR3, rtlphy->framesync)); -} - -static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; - rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; - rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; - rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; - - rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; - rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; - rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; - rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; - - rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; - rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; - - rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; - rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; - - rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = - RFPGA0_XA_LSSIPARAMETER; - rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = - RFPGA0_XB_LSSIPARAMETER; - - rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER; - rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER; - rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER; - rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER; - - rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; - rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; - rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; - rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; - - rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; - rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; - - rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; - rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; - - rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = - RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = - RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = - RFPGA0_XCD_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = - RFPGA0_XCD_SWITCHCONTROL; - - rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; - rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; - rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; - rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; - - rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; - rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; - rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; - rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; - - rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = - ROFDM0_XARXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = - ROFDM0_XBRXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = - ROFDM0_XCRXIQIMBANLANCE; - rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = - ROFDM0_XDRXIQIMBALANCE; - - rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; - rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; - rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; - rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; - - rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = - ROFDM0_XATXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = - ROFDM0_XBTXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = - ROFDM0_XCTXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = - ROFDM0_XDTXIQIMBALANCE; - - rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; - rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; - rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; - rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; - - rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = - RFPGA0_XA_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = - RFPGA0_XB_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = - RFPGA0_XC_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = - RFPGA0_XD_LSSIREADBACK; - - rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = - TRANSCEIVEA_HSPI_READBACK; - rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = - TRANSCEIVEB_HSPI_READBACK; - -} - -void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 txpwr_level; - long txpwr_dbm; - - txpwr_level = rtlphy->cur_cck_txpwridx; - txpwr_dbm = _rtl92c_phy_txpwr_idx_to_dbm(hw, - WIRELESS_MODE_B, txpwr_level); - txpwr_level = rtlphy->cur_ofdm24g_txpwridx + - rtlefuse->legacy_ht_txpowerdiff; - if (_rtl92c_phy_txpwr_idx_to_dbm(hw, - WIRELESS_MODE_G, - txpwr_level) > txpwr_dbm) - txpwr_dbm = - _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, - txpwr_level); - txpwr_level = rtlphy->cur_ofdm24g_txpwridx; - if (_rtl92c_phy_txpwr_idx_to_dbm(hw, - WIRELESS_MODE_N_24G, - txpwr_level) > txpwr_dbm) - txpwr_dbm = - _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, - txpwr_level); - *powerlevel = txpwr_dbm; -} - -static void _rtl92c_get_txpower_index(struct ieee80211_hw *hw, u8 channel, - u8 *cckpowerlevel, u8 *ofdmpowerlevel) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 index = (channel - 1); - - cckpowerlevel[RF90_PATH_A] = - rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; - cckpowerlevel[RF90_PATH_B] = - rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; - if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) { - ofdmpowerlevel[RF90_PATH_A] = - rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; - ofdmpowerlevel[RF90_PATH_B] = - rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; - } else if (get_rf_type(rtlphy) == RF_2T2R) { - ofdmpowerlevel[RF90_PATH_A] = - rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index]; - ofdmpowerlevel[RF90_PATH_B] = - rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index]; - } -} - -static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw, - u8 channel, u8 *cckpowerlevel, - u8 *ofdmpowerlevel) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; - rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; -} - -void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) -{ - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 cckpowerlevel[2], ofdmpowerlevel[2]; - - if (rtlefuse->txpwr_fromeprom == false) - return; - _rtl92c_get_txpower_index(hw, channel, - &cckpowerlevel[0], &ofdmpowerlevel[0]); - _rtl92c_ccxpower_index_check(hw, - channel, &cckpowerlevel[0], - &ofdmpowerlevel[0]); - rtl92c_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); - rtl92c_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel); -} - -bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 idx; - u8 rf_path; - - u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, - WIRELESS_MODE_B, - power_indbm); - u8 ofdmtxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, - WIRELESS_MODE_N_24G, - power_indbm); - if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0) - ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff; - else - ofdmtxpwridx = 0; - RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE, - ("%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", - power_indbm, ccktxpwridx, ofdmtxpwridx)); - for (idx = 0; idx < 14; idx++) { - for (rf_path = 0; rf_path < 2; rf_path++) { - rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; - rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] = - ofdmtxpwridx; - rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] = - ofdmtxpwridx; - } - } - rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); - return true; -} - -void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval) -{ -} - -static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, - long power_indbm) -{ - u8 txpwridx; - long offset; - - switch (wirelessmode) { - case WIRELESS_MODE_B: - offset = -7; - break; - case WIRELESS_MODE_G: - case WIRELESS_MODE_N_24G: - offset = -8; - break; - default: - offset = -8; - break; - } - - if ((power_indbm - offset) > 0) - txpwridx = (u8) ((power_indbm - offset) * 2); - else - txpwridx = 0; - - if (txpwridx > MAX_TXPWR_IDX_NMODE_92S) - txpwridx = MAX_TXPWR_IDX_NMODE_92S; - - return txpwridx; -} - -static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, - u8 txpwridx) -{ - long offset; - long pwrout_dbm; - - switch (wirelessmode) { - case WIRELESS_MODE_B: - offset = -7; - break; - case WIRELESS_MODE_G: - case WIRELESS_MODE_N_24G: - offset = -8; - break; - default: - offset = -8; - break; - } - pwrout_dbm = txpwridx / 2 + offset; - return pwrout_dbm; -} - -void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - enum io_type iotype; - - if (!is_hal_stop(rtlhal)) { - switch (operation) { - case SCAN_OPT_BACKUP: - iotype = IO_CMD_PAUSE_DM_BY_SCAN; - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_IO_CMD, - (u8 *)&iotype); - - break; - case SCAN_OPT_RESTORE: - iotype = IO_CMD_RESUME_DM_BY_SCAN; - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_IO_CMD, - (u8 *)&iotype); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Unknown Scan Backup operation.\n")); - break; - } - } -} - void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -1154,656 +435,18 @@ void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); } -void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, - enum nl80211_channel_type ch_type) +static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) { + u8 tmpreg; + u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 tmp_bw = rtlphy->current_chan_bw; - if (rtlphy->set_bwmode_inprogress) - return; - rtlphy->set_bwmode_inprogress = true; - if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) - rtl92c_phy_set_bw_mode_callback(hw); - else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("FALSE driver sleep or unload\n")); - rtlphy->set_bwmode_inprogress = false; - rtlphy->current_chan_bw = tmp_bw; - } -} + tmpreg = rtl_read_byte(rtlpriv, 0xd03); -void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u32 delay; - - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("switch to channel%d\n", rtlphy->current_channel)); - if (is_hal_stop(rtlhal)) - return; - do { - if (!rtlphy->sw_chnl_inprogress) - break; - if (!_rtl92c_phy_sw_chnl_step_by_step - (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, - &rtlphy->sw_chnl_step, &delay)) { - if (delay > 0) - mdelay(delay); - else - continue; - } else - rtlphy->sw_chnl_inprogress = false; - break; - } while (true); - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); -} - -u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (rtlphy->sw_chnl_inprogress) - return 0; - if (rtlphy->set_bwmode_inprogress) - return 0; - RT_ASSERT((rtlphy->current_channel <= 14), - ("WIRELESS_MODE_G but channel>14")); - rtlphy->sw_chnl_inprogress = true; - rtlphy->sw_chnl_stage = 0; - rtlphy->sw_chnl_step = 0; - if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { - rtl92c_phy_sw_chnl_callback(hw); - RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - ("sw_chnl_inprogress false schdule workitem\n")); - rtlphy->sw_chnl_inprogress = false; - } else { - RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - ("sw_chnl_inprogress false driver sleep or" - " unload\n")); - rtlphy->sw_chnl_inprogress = false; - } - return 1; -} - -static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, - u8 channel, u8 *stage, u8 *step, - u32 *delay) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; - u32 precommoncmdcnt; - struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; - u32 postcommoncmdcnt; - struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; - u32 rfdependcmdcnt; - struct swchnlcmd *currentcmd = NULL; - u8 rfpath; - u8 num_total_rfpath = rtlphy->num_total_rfpath; - - precommoncmdcnt = 0; - _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, - MAX_PRECMD_CNT, - CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); - _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, - MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); - - postcommoncmdcnt = 0; - - _rtl92c_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, - MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); - - rfdependcmdcnt = 0; - - RT_ASSERT((channel >= 1 && channel <= 14), - ("illegal channel for Zebra: %d\n", channel)); - - _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, - MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, - RF_CHNLBW, channel, 10); - - _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, - MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, - 0); - - do { - switch (*stage) { - case 0: - currentcmd = &precommoncmd[*step]; - break; - case 1: - currentcmd = &rfdependcmd[*step]; - break; - case 2: - currentcmd = &postcommoncmd[*step]; - break; - } - - if (currentcmd->cmdid == CMDID_END) { - if ((*stage) == 2) { - return true; - } else { - (*stage)++; - (*step) = 0; - continue; - } - } - - switch (currentcmd->cmdid) { - case CMDID_SET_TXPOWEROWER_LEVEL: - rtl92c_phy_set_txpower_level(hw, channel); - break; - case CMDID_WRITEPORT_ULONG: - rtl_write_dword(rtlpriv, currentcmd->para1, - currentcmd->para2); - break; - case CMDID_WRITEPORT_USHORT: - rtl_write_word(rtlpriv, currentcmd->para1, - (u16) currentcmd->para2); - break; - case CMDID_WRITEPORT_UCHAR: - rtl_write_byte(rtlpriv, currentcmd->para1, - (u8) currentcmd->para2); - break; - case CMDID_RF_WRITEREG: - for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { - rtlphy->rfreg_chnlval[rfpath] = - ((rtlphy->rfreg_chnlval[rfpath] & - 0xfffffc00) | currentcmd->para2); - - rtl_set_rfreg(hw, (enum radio_path)rfpath, - currentcmd->para1, - RFREG_OFFSET_MASK, - rtlphy->rfreg_chnlval[rfpath]); - } - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); - break; - } - - break; - } while (true); - - (*delay) = currentcmd->msdelay; - (*step)++; - return false; -} - -static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, - u32 cmdtableidx, u32 cmdtablesz, - enum swchnlcmd_id cmdid, - u32 para1, u32 para2, u32 msdelay) -{ - struct swchnlcmd *pcmd; - - if (cmdtable == NULL) { - RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); - return false; - } - - if (cmdtableidx >= cmdtablesz) - return false; - - pcmd = cmdtable + cmdtableidx; - pcmd->cmdid = cmdid; - pcmd->para1 = para1; - pcmd->para2 = para2; - pcmd->msdelay = msdelay; - return true; -} - -bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath) -{ - return true; -} - -static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) -{ - u32 reg_eac, reg_e94, reg_e9c, reg_ea4; - u8 result = 0x00; - - rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f); - rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f); - rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102); - rtl_set_bbreg(hw, 0xe3c, MASKDWORD, - config_pathb ? 0x28160202 : 0x28160502); - - if (config_pathb) { - rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22); - rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22); - rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102); - rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202); - } - - rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1); - rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); - rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); - - mdelay(IQK_DELAY_TIME); - - reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); - reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); - reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); - reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); - - if (!(reg_eac & BIT(28)) && - (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && - (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) - result |= 0x01; - else - return result; - - if (!(reg_eac & BIT(27)) && - (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && - (((reg_eac & 0x03FF0000) >> 16) != 0x36)) - result |= 0x02; - return result; -} - -static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw) -{ - u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; - u8 result = 0x00; - - rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); - rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); - mdelay(IQK_DELAY_TIME); - reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); - reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); - reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); - reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); - reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); - if (!(reg_eac & BIT(31)) && - (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && - (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) - result |= 0x01; - else - return result; - - if (!(reg_eac & BIT(30)) && - (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && - (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) - result |= 0x02; - return result; -} - -static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, - bool iqk_ok, long result[][8], - u8 final_candidate, bool btxonly) -{ - u32 oldval_0, x, tx0_a, reg; - long y, tx0_c; - - if (final_candidate == 0xFF) - return; - else if (iqk_ok) { - oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, - MASKDWORD) >> 22) & 0x3FF; - x = result[final_candidate][0]; - if ((x & 0x00000200) != 0) - x = x | 0xFFFFFC00; - tx0_a = (x * oldval_0) >> 8; - rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), - ((x * oldval_0 >> 7) & 0x1)); - y = result[final_candidate][1]; - if ((y & 0x00000200) != 0) - y = y | 0xFFFFFC00; - tx0_c = (y * oldval_0) >> 8; - rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, - ((tx0_c & 0x3C0) >> 6)); - rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, - (tx0_c & 0x3F)); - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), - ((y * oldval_0 >> 7) & 0x1)); - if (btxonly) - return; - reg = result[final_candidate][2]; - rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); - reg = result[final_candidate][3] & 0x3F; - rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); - reg = (result[final_candidate][3] >> 6) & 0xF; - rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); - } -} - -static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, - bool iqk_ok, long result[][8], - u8 final_candidate, bool btxonly) -{ - u32 oldval_1, x, tx1_a, reg; - long y, tx1_c; - - if (final_candidate == 0xFF) - return; - else if (iqk_ok) { - oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, - MASKDWORD) >> 22) & 0x3FF; - x = result[final_candidate][4]; - if ((x & 0x00000200) != 0) - x = x | 0xFFFFFC00; - tx1_a = (x * oldval_1) >> 8; - rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a); - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27), - ((x * oldval_1 >> 7) & 0x1)); - y = result[final_candidate][5]; - if ((y & 0x00000200) != 0) - y = y | 0xFFFFFC00; - tx1_c = (y * oldval_1) >> 8; - rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, - ((tx1_c & 0x3C0) >> 6)); - rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, - (tx1_c & 0x3F)); - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25), - ((y * oldval_1 >> 7) & 0x1)); - if (btxonly) - return; - reg = result[final_candidate][6]; - rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); - reg = result[final_candidate][7] & 0x3F; - rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); - reg = (result[final_candidate][7] >> 6) & 0xF; - rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg); - } -} - -static void _rtl92c_phy_save_adda_registers(struct ieee80211_hw *hw, - u32 *addareg, u32 *addabackup, - u32 registernum) -{ - u32 i; - - for (i = 0; i < registernum; i++) - addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); -} - -static void _rtl92c_phy_save_mac_registers(struct ieee80211_hw *hw, - u32 *macreg, u32 *macbackup) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 i; - - for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) - macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); - macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); -} - -static void _rtl92c_phy_reload_adda_registers(struct ieee80211_hw *hw, - u32 *addareg, u32 *addabackup, - u32 regiesternum) -{ - u32 i; - - for (i = 0; i < regiesternum; i++) - rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); -} - -static void _rtl92c_phy_reload_mac_registers(struct ieee80211_hw *hw, - u32 *macreg, u32 *macbackup) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 i; - - for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) - rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); - rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); -} - -static void _rtl92c_phy_path_adda_on(struct ieee80211_hw *hw, - u32 *addareg, bool is_patha_on, bool is2t) -{ - u32 pathOn; - u32 i; - - pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4; - if (false == is2t) { - pathOn = 0x0bdb25a0; - rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0); - } else { - rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn); - } - - for (i = 1; i < IQK_ADDA_REG_NUM; i++) - rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn); -} - -static void _rtl92c_phy_mac_setting_calibration(struct ieee80211_hw *hw, - u32 *macreg, u32 *macbackup) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 i; - - rtl_write_byte(rtlpriv, macreg[0], 0x3F); - - for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) - rtl_write_byte(rtlpriv, macreg[i], - (u8) (macbackup[i] & (~BIT(3)))); - rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5)))); -} - -static void _rtl92c_phy_path_a_standby(struct ieee80211_hw *hw) -{ - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); - rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); -} - -static void _rtl92c_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode) -{ - u32 mode; - - mode = pi_mode ? 0x01000100 : 0x01000000; - rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); - rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); -} - -static bool _rtl92c_phy_simularity_compare(struct ieee80211_hw *hw, - long result[][8], u8 c1, u8 c2) -{ - u32 i, j, diff, simularity_bitmap, bound; - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - u8 final_candidate[2] = { 0xFF, 0xFF }; - bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version); - - if (is2t) - bound = 8; - else - bound = 4; - - simularity_bitmap = 0; - - for (i = 0; i < bound; i++) { - diff = (result[c1][i] > result[c2][i]) ? - (result[c1][i] - result[c2][i]) : - (result[c2][i] - result[c1][i]); - - if (diff > MAX_TOLERANCE) { - if ((i == 2 || i == 6) && !simularity_bitmap) { - if (result[c1][i] + result[c1][i + 1] == 0) - final_candidate[(i / 4)] = c2; - else if (result[c2][i] + result[c2][i + 1] == 0) - final_candidate[(i / 4)] = c1; - else - simularity_bitmap = simularity_bitmap | - (1 << i); - } else - simularity_bitmap = - simularity_bitmap | (1 << i); - } - } - - if (simularity_bitmap == 0) { - for (i = 0; i < (bound / 4); i++) { - if (final_candidate[i] != 0xFF) { - for (j = i * 4; j < (i + 1) * 4 - 2; j++) - result[3][j] = - result[final_candidate[i]][j]; - bresult = false; - } - } - return bresult; - } else if (!(simularity_bitmap & 0x0F)) { - for (i = 0; i < 4; i++) - result[3][i] = result[c1][i]; - return false; - } else if (!(simularity_bitmap & 0xF0) && is2t) { - for (i = 4; i < 8; i++) - result[3][i] = result[c1][i]; - return false; - } else { - return false; - } - -} - -static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, - long result[][8], u8 t, bool is2t) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u32 i; - u8 patha_ok, pathb_ok; - u32 adda_reg[IQK_ADDA_REG_NUM] = { - 0x85c, 0xe6c, 0xe70, 0xe74, - 0xe78, 0xe7c, 0xe80, 0xe84, - 0xe88, 0xe8c, 0xed0, 0xed4, - 0xed8, 0xedc, 0xee0, 0xeec - }; - - u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { - 0x522, 0x550, 0x551, 0x040 - }; - - const u32 retrycount = 2; - - u32 bbvalue; - - if (t == 0) { - bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD); - - _rtl92c_phy_save_adda_registers(hw, adda_reg, - rtlphy->adda_backup, 16); - _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg, - rtlphy->iqk_mac_backup); - } - _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t); - if (t == 0) { - rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw, - RFPGA0_XA_HSSIPARAMETER1, - BIT(8)); - } - if (!rtlphy->rfpi_enable) - _rtl92c_phy_pi_mode_switch(hw, true); - if (t == 0) { - rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); - rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); - rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD); - } - rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); - rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); - rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); - if (is2t) { - rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); - rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); - } - _rtl92c_phy_mac_setting_calibration(hw, iqk_mac_reg, - rtlphy->iqk_mac_backup); - rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000); - if (is2t) - rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000); - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); - rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); - rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800); - for (i = 0; i < retrycount; i++) { - patha_ok = _rtl92c_phy_path_a_iqk(hw, is2t); - if (patha_ok == 0x03) { - result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & - 0x3FF0000) >> 16; - break; - } else if (i == (retrycount - 1) && patha_ok == 0x01) - result[t][0] = (rtl_get_bbreg(hw, 0xe94, - MASKDWORD) & 0x3FF0000) >> - 16; - result[t][1] = - (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; - - } - - if (is2t) { - _rtl92c_phy_path_a_standby(hw); - _rtl92c_phy_path_adda_on(hw, adda_reg, false, is2t); - for (i = 0; i < retrycount; i++) { - pathb_ok = _rtl92c_phy_path_b_iqk(hw); - if (pathb_ok == 0x03) { - result[t][4] = (rtl_get_bbreg(hw, - 0xeb4, - MASKDWORD) & - 0x3FF0000) >> 16; - result[t][5] = - (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][6] = - (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][7] = - (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & - 0x3FF0000) >> 16; - break; - } else if (i == (retrycount - 1) && pathb_ok == 0x01) { - result[t][4] = (rtl_get_bbreg(hw, - 0xeb4, - MASKDWORD) & - 0x3FF0000) >> 16; - } - result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & - 0x3FF0000) >> 16; - } - } - rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); - rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874); - rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08); - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); - rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); - if (is2t) - rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); - if (t != 0) { - if (!rtlphy->rfpi_enable) - _rtl92c_phy_pi_mode_switch(hw, false); - _rtl92c_phy_reload_adda_registers(hw, adda_reg, - rtlphy->adda_backup, 16); - _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg, - rtlphy->iqk_mac_backup); - } -} - -static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) -{ - u8 tmpreg; - u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; - struct rtl_priv *rtlpriv = rtl_priv(hw); - - tmpreg = rtl_read_byte(rtlpriv, 0xd03); - - if ((tmpreg & 0x70) != 0) - rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); - else - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + if ((tmpreg & 0x70) != 0) + rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); + else + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); if ((tmpreg & 0x70) != 0) { rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); @@ -1837,666 +480,6 @@ static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) } } -static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, - char delta, bool is2t) -{ - /* This routine is deliberately dummied out for later fixes */ -#if 0 - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - - u32 reg_d[PATH_NUM]; - u32 tmpreg, index, offset, path, i, pathbound = PATH_NUM, apkbound; - - u32 bb_backup[APK_BB_REG_NUM]; - u32 bb_reg[APK_BB_REG_NUM] = { - 0x904, 0xc04, 0x800, 0xc08, 0x874 - }; - u32 bb_ap_mode[APK_BB_REG_NUM] = { - 0x00000020, 0x00a05430, 0x02040000, - 0x000800e4, 0x00204000 - }; - u32 bb_normal_ap_mode[APK_BB_REG_NUM] = { - 0x00000020, 0x00a05430, 0x02040000, - 0x000800e4, 0x22204000 - }; - - u32 afe_backup[APK_AFE_REG_NUM]; - u32 afe_reg[APK_AFE_REG_NUM] = { - 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, - 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, - 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, - 0xeec - }; - - u32 mac_backup[IQK_MAC_REG_NUM]; - u32 mac_reg[IQK_MAC_REG_NUM] = { - 0x522, 0x550, 0x551, 0x040 - }; - - u32 apk_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { - {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c}, - {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e} - }; - - u32 apk_normal_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { - {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c}, - {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c} - }; - - u32 apk_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { - {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d}, - {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050} - }; - - u32 apk_normal_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { - {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}, - {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a} - }; - - u32 afe_on_off[PATH_NUM] = { - 0x04db25a4, 0x0b1b25a4 - }; - - u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c }; - - u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 }; - - u32 apk_value[PATH_NUM] = { 0x92fc0000, 0x12fc0000 }; - - u32 apk_normal_value[PATH_NUM] = { 0x92680000, 0x12680000 }; - - const char apk_delta_mapping[APK_BB_REG_NUM][13] = { - {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, - {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, - {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, - {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6}, - {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0} - }; - - const u32 apk_normal_setting_value_1[13] = { - 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28, - 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3, - 0x12680000, 0x00880000, 0x00880000 - }; - - const u32 apk_normal_setting_value_2[16] = { - 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3, - 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025, - 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008, - 0x00050006 - }; - - const u32 apk_result[PATH_NUM][APK_BB_REG_NUM]; - - long bb_offset, delta_v, delta_offset; - - if (!is2t) - pathbound = 1; - - for (index = 0; index < PATH_NUM; index++) { - apk_offset[index] = apk_normal_offset[index]; - apk_value[index] = apk_normal_value[index]; - afe_on_off[index] = 0x6fdb25a4; - } - - for (index = 0; index < APK_BB_REG_NUM; index++) { - for (path = 0; path < pathbound; path++) { - apk_rf_init_value[path][index] = - apk_normal_rf_init_value[path][index]; - apk_rf_value_0[path][index] = - apk_normal_rf_value_0[path][index]; - } - bb_ap_mode[index] = bb_normal_ap_mode[index]; - - apkbound = 6; - } - - for (index = 0; index < APK_BB_REG_NUM; index++) { - if (index == 0) - continue; - bb_backup[index] = rtl_get_bbreg(hw, bb_reg[index], MASKDWORD); - } - - _rtl92c_phy_save_mac_registers(hw, mac_reg, mac_backup); - - _rtl92c_phy_save_adda_registers(hw, afe_reg, afe_backup, 16); - - for (path = 0; path < pathbound; path++) { - if (path == RF90_PATH_A) { - offset = 0xb00; - for (index = 0; index < 11; index++) { - rtl_set_bbreg(hw, offset, MASKDWORD, - apk_normal_setting_value_1 - [index]); - - offset += 0x04; - } - - rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); - - offset = 0xb68; - for (; index < 13; index++) { - rtl_set_bbreg(hw, offset, MASKDWORD, - apk_normal_setting_value_1 - [index]); - - offset += 0x04; - } - - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); - - offset = 0xb00; - for (index = 0; index < 16; index++) { - rtl_set_bbreg(hw, offset, MASKDWORD, - apk_normal_setting_value_2 - [index]); - - offset += 0x04; - } - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); - } else if (path == RF90_PATH_B) { - offset = 0xb70; - for (index = 0; index < 10; index++) { - rtl_set_bbreg(hw, offset, MASKDWORD, - apk_normal_setting_value_1 - [index]); - - offset += 0x04; - } - rtl_set_bbreg(hw, 0xb28, MASKDWORD, 0x12680000); - rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); - - offset = 0xb68; - index = 11; - for (; index < 13; index++) { - rtl_set_bbreg(hw, offset, MASKDWORD, - apk_normal_setting_value_1 - [index]); - - offset += 0x04; - } - - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); - - offset = 0xb60; - for (index = 0; index < 16; index++) { - rtl_set_bbreg(hw, offset, MASKDWORD, - apk_normal_setting_value_2 - [index]); - - offset += 0x04; - } - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); - } - - reg_d[path] = rtl_get_rfreg(hw, (enum radio_path)path, - 0xd, MASKDWORD); - - for (index = 0; index < APK_AFE_REG_NUM; index++) - rtl_set_bbreg(hw, afe_reg[index], MASKDWORD, - afe_on_off[path]); - - if (path == RF90_PATH_A) { - for (index = 0; index < APK_BB_REG_NUM; index++) { - if (index == 0) - continue; - rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, - bb_ap_mode[index]); - } - } - - _rtl92c_phy_mac_setting_calibration(hw, mac_reg, mac_backup); - - if (path == 0) { - rtl_set_rfreg(hw, RF90_PATH_B, 0x0, MASKDWORD, 0x10000); - } else { - rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASKDWORD, - 0x10000); - rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, - 0x1000f); - rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, - 0x20103); - } - - delta_offset = ((delta + 14) / 2); - if (delta_offset < 0) - delta_offset = 0; - else if (delta_offset > 12) - delta_offset = 12; - - for (index = 0; index < APK_BB_REG_NUM; index++) { - if (index != 1) - continue; - - tmpreg = apk_rf_init_value[path][index]; - - if (!rtlefuse->b_apk_thermalmeterignore) { - bb_offset = (tmpreg & 0xF0000) >> 16; - - if (!(tmpreg & BIT(15))) - bb_offset = -bb_offset; - - delta_v = - apk_delta_mapping[index][delta_offset]; - - bb_offset += delta_v; - - if (bb_offset < 0) { - tmpreg = tmpreg & (~BIT(15)); - bb_offset = -bb_offset; - } else { - tmpreg = tmpreg | BIT(15); - } - - tmpreg = - (tmpreg & 0xFFF0FFFF) | (bb_offset << 16); - } - - rtl_set_rfreg(hw, (enum radio_path)path, 0xc, - MASKDWORD, 0x8992e); - rtl_set_rfreg(hw, (enum radio_path)path, 0x0, - MASKDWORD, apk_rf_value_0[path][index]); - rtl_set_rfreg(hw, (enum radio_path)path, 0xd, - MASKDWORD, tmpreg); - - i = 0; - do { - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80000000); - rtl_set_bbreg(hw, apk_offset[path], - MASKDWORD, apk_value[0]); - RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("PHY_APCalibrate() offset 0x%x " - "value 0x%x\n", - apk_offset[path], - rtl_get_bbreg(hw, apk_offset[path], - MASKDWORD))); - - mdelay(3); - - rtl_set_bbreg(hw, apk_offset[path], - MASKDWORD, apk_value[1]); - RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("PHY_APCalibrate() offset 0x%x " - "value 0x%x\n", - apk_offset[path], - rtl_get_bbreg(hw, apk_offset[path], - MASKDWORD))); - - mdelay(20); - - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); - - if (path == RF90_PATH_A) - tmpreg = rtl_get_bbreg(hw, 0xbd8, - 0x03E00000); - else - tmpreg = rtl_get_bbreg(hw, 0xbd8, - 0xF8000000); - - RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("PHY_APCalibrate() offset " - "0xbd8[25:21] %x\n", tmpreg)); - - i++; - - } while (tmpreg > apkbound && i < 4); - - apk_result[path][index] = tmpreg; - } - } - - _rtl92c_phy_reload_mac_registers(hw, mac_reg, mac_backup); - - for (index = 0; index < APK_BB_REG_NUM; index++) { - if (index == 0) - continue; - rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, bb_backup[index]); - } - - _rtl92c_phy_reload_adda_registers(hw, afe_reg, afe_backup, 16); - - for (path = 0; path < pathbound; path++) { - rtl_set_rfreg(hw, (enum radio_path)path, 0xd, - MASKDWORD, reg_d[path]); - - if (path == RF90_PATH_B) { - rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, - 0x1000f); - rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, - 0x20101); - } - - if (apk_result[path][1] > 6) - apk_result[path][1] = 6; - } - - for (path = 0; path < pathbound; path++) { - rtl_set_rfreg(hw, (enum radio_path)path, 0x3, MASKDWORD, - ((apk_result[path][1] << 15) | - (apk_result[path][1] << 10) | - (apk_result[path][1] << 5) | - apk_result[path][1])); - - if (path == RF90_PATH_A) - rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, - ((apk_result[path][1] << 15) | - (apk_result[path][1] << 10) | - (0x00 << 5) | 0x05)); - else - rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, - ((apk_result[path][1] << 15) | - (apk_result[path][1] << 10) | - (0x02 << 5) | 0x05)); - - rtl_set_rfreg(hw, (enum radio_path)path, 0xe, MASKDWORD, - ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) | - 0x08)); - - } - - rtlphy->b_apk_done = true; -#endif -} - -static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, - bool bmain, bool is2t) -{ - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (is_hal_stop(rtlhal)) { - rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01); - rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); - } - if (is2t) { - if (bmain) - rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, - BIT(5) | BIT(6), 0x1); - else - rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, - BIT(5) | BIT(6), 0x2); - } else { - if (bmain) - rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2); - else - rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1); - - } -} - -#undef IQK_ADDA_REG_NUM -#undef IQK_DELAY_TIME - -void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - long result[4][8]; - u8 i, final_candidate; - bool b_patha_ok, b_pathb_ok; - long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, - reg_ecc, reg_tmp = 0; - bool is12simular, is13simular, is23simular; - bool b_start_conttx = false, b_singletone = false; - u32 iqk_bb_reg[10] = { - ROFDM0_XARXIQIMBALANCE, - ROFDM0_XBRXIQIMBALANCE, - ROFDM0_ECCATHRESHOLD, - ROFDM0_AGCRSSITABLE, - ROFDM0_XATXIQIMBALANCE, - ROFDM0_XBTXIQIMBALANCE, - ROFDM0_XCTXIQIMBALANCE, - ROFDM0_XCTXAFE, - ROFDM0_XDTXAFE, - ROFDM0_RXIQEXTANTA - }; - - if (b_recovery) { - _rtl92c_phy_reload_adda_registers(hw, - iqk_bb_reg, - rtlphy->iqk_bb_backup, 10); - return; - } - if (b_start_conttx || b_singletone) - return; - for (i = 0; i < 8; i++) { - result[0][i] = 0; - result[1][i] = 0; - result[2][i] = 0; - result[3][i] = 0; - } - final_candidate = 0xff; - b_patha_ok = false; - b_pathb_ok = false; - is12simular = false; - is23simular = false; - is13simular = false; - for (i = 0; i < 3; i++) { - if (IS_92C_SERIAL(rtlhal->version)) - _rtl92c_phy_iq_calibrate(hw, result, i, true); - else - _rtl92c_phy_iq_calibrate(hw, result, i, false); - if (i == 1) { - is12simular = _rtl92c_phy_simularity_compare(hw, - result, 0, - 1); - if (is12simular) { - final_candidate = 0; - break; - } - } - if (i == 2) { - is13simular = _rtl92c_phy_simularity_compare(hw, - result, 0, - 2); - if (is13simular) { - final_candidate = 0; - break; - } - is23simular = _rtl92c_phy_simularity_compare(hw, - result, 1, - 2); - if (is23simular) - final_candidate = 1; - else { - for (i = 0; i < 8; i++) - reg_tmp += result[3][i]; - - if (reg_tmp != 0) - final_candidate = 3; - else - final_candidate = 0xFF; - } - } - } - for (i = 0; i < 4; i++) { - reg_e94 = result[i][0]; - reg_e9c = result[i][1]; - reg_ea4 = result[i][2]; - reg_eac = result[i][3]; - reg_eb4 = result[i][4]; - reg_ebc = result[i][5]; - reg_ec4 = result[i][6]; - reg_ecc = result[i][7]; - } - if (final_candidate != 0xff) { - rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; - rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; - reg_ea4 = result[final_candidate][2]; - reg_eac = result[final_candidate][3]; - rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; - rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; - reg_ec4 = result[final_candidate][6]; - reg_ecc = result[final_candidate][7]; - b_patha_ok = b_pathb_ok = true; - } else { - rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; - rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; - } - if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ - _rtl92c_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result, - final_candidate, - (reg_ea4 == 0)); - if (IS_92C_SERIAL(rtlhal->version)) { - if (reg_eb4 != 0) /*&&(reg_ec4 != 0) */ - _rtl92c_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, - result, - final_candidate, - (reg_ec4 == 0)); - } - _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg, - rtlphy->iqk_bb_backup, 10); -} - -void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw) -{ - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - bool b_start_conttx = false, b_singletone = false; - - if (b_start_conttx || b_singletone) - return; - if (IS_92C_SERIAL(rtlhal->version)) - _rtl92c_phy_lc_calibrate(hw, true); - else - _rtl92c_phy_lc_calibrate(hw, false); -} - -void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (rtlphy->apk_done) - return; - if (IS_92C_SERIAL(rtlhal->version)) - _rtl92c_phy_ap_calibrate(hw, delta, true); - else - _rtl92c_phy_ap_calibrate(hw, delta, false); -} - -void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) -{ - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (IS_92C_SERIAL(rtlhal->version)) - _rtl92c_phy_set_rfpath_switch(hw, bmain, true); - else - _rtl92c_phy_set_rfpath_switch(hw, bmain, false); -} - -bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - bool b_postprocessing = false; - - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("-->IO Cmd(%#x), set_io_inprogress(%d)\n", - iotype, rtlphy->set_io_inprogress)); - do { - switch (iotype) { - case IO_CMD_RESUME_DM_BY_SCAN: - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("[IO CMD] Resume DM after scan.\n")); - b_postprocessing = true; - break; - case IO_CMD_PAUSE_DM_BY_SCAN: - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("[IO CMD] Pause DM before scan.\n")); - b_postprocessing = true; - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); - break; - } - } while (false); - if (b_postprocessing && !rtlphy->set_io_inprogress) { - rtlphy->set_io_inprogress = true; - rtlphy->current_io_type = iotype; - } else { - return false; - } - rtl92c_phy_set_io(hw); - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype)); - return true; -} - -void rtl92c_phy_set_io(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("--->Cmd(%#x), set_io_inprogress(%d)\n", - rtlphy->current_io_type, rtlphy->set_io_inprogress)); - switch (rtlphy->current_io_type) { - case IO_CMD_RESUME_DM_BY_SCAN: - dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1; - rtl92c_dm_write_dig(hw); - rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); - break; - case IO_CMD_PAUSE_DM_BY_SCAN: - rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue; - dm_digtable.cur_igvalue = 0x17; - rtl92c_dm_write_dig(hw); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); - break; - } - rtlphy->set_io_inprogress = false; - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("<---(%#x)\n", rtlphy->current_io_type)); -} - -void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); -} - -static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw) -{ - u32 u4b_tmp; - u8 delay = 5; - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); - rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); - u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); - while (u4b_tmp != 0 && delay > 0) { - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); - rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); - u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); - delay--; - } - if (delay == 0) { - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); - RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Switch RF timeout !!!.\n")); - return; - } - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); - rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); -} - static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, enum rf_pwrstate rfpwr_state) { -- cgit v1.2.3 From 442888c706e90634c4cc3441751b43115a7d8506 Mon Sep 17 00:00:00 2001 From: George Date: Sat, 19 Feb 2011 16:29:17 -0600 Subject: rtlwifi: rtl8192cu: Add routines dm, fw, led and sw Add the rtlwifi/rtl8192cu routines for dm.c, fw.c, led.c and sw.c. Where possible, these routines use the corresponding code in rtl8192ce. Signed-off-by: George Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/dm.c | 116 ++++++++++ drivers/net/wireless/rtlwifi/rtl8192cu/fw.c | 30 +++ drivers/net/wireless/rtlwifi/rtl8192cu/led.c | 142 ++++++++++++ drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 327 +++++++++++++++++++++++++++ 4 files changed, 615 insertions(+) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/dm.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/fw.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/led.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/sw.c (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c new file mode 100644 index 000000000000..a4649a2f7e6f --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c @@ -0,0 +1,116 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../base.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "dm.h" +#include "fw.h" + +#include "../rtl8192c/dm_common.c" + +void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long undecorated_smoothed_pwdb; + + if (!rtlpriv->dm.dynamic_txpower_enable) + return; + + if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + + if ((mac->link_state < MAC80211_LINKED) && + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, + ("Not connected to any\n")); + + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + + rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; + return; + } + + if (mac->link_state >= MAC80211_LINKED) { + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("AP Client PWDB = 0x%lx\n", + undecorated_smoothed_pwdb)); + } else { + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("STA Default Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb)); + } + } else { + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; + + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("AP Ext Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb)); + } + + if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); + } else if ((undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && + (undecorated_smoothed_pwdb >= + TX_POWER_NEAR_FIELD_THRESH_LVL1)) { + + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); + } else if (undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { + rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("TXHIGHPWRLEVEL_NORMAL\n")); + } + + if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel)); + rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); + } + + rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/fw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/fw.c new file mode 100644 index 000000000000..8e350eea3422 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/fw.c @@ -0,0 +1,30 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../rtl8192ce/fw.c" diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c new file mode 100644 index 000000000000..332c74348a69 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c @@ -0,0 +1,142 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../usb.h" +#include "reg.h" +#include "led.h" + +static void _rtl92cu_init_led(struct ieee80211_hw *hw, + struct rtl_led *pled, enum rtl_led_pin ledpin) +{ + pled->hw = hw; + pled->ledpin = ledpin; + pled->ledon = false; +} + +static void _rtl92cu_deInit_led(struct rtl_led *pled) +{ +} + +void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) +{ + u8 ledcfg; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, + ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + switch (pled->ledpin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + rtl_write_byte(rtlpriv, + REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6)); + break; + case LED_PIN_LED1: + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5)); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + pled->ledon = true; +} + +void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw); + u8 ledcfg; + + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, + ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); + switch (pled->ledpin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + ledcfg &= 0xf0; + if (usbpriv->ledctl.led_opendrain == true) + rtl_write_byte(rtlpriv, REG_LEDCFG2, + (ledcfg | BIT(1) | BIT(5) | BIT(6))); + else + rtl_write_byte(rtlpriv, REG_LEDCFG2, + (ledcfg | BIT(3) | BIT(5) | BIT(6))); + break; + case LED_PIN_LED1: + ledcfg &= 0x0f; + rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3))); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + pled->ledon = false; +} + +void rtl92cu_init_sw_leds(struct ieee80211_hw *hw) +{ + struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw); + _rtl92cu_init_led(hw, &(usbpriv->ledctl.sw_led0), LED_PIN_LED0); + _rtl92cu_init_led(hw, &(usbpriv->ledctl.sw_led1), LED_PIN_LED1); +} + +void rtl92cu_deinit_sw_leds(struct ieee80211_hw *hw) +{ + struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw); + _rtl92cu_deInit_led(&(usbpriv->ledctl.sw_led0)); + _rtl92cu_deInit_led(&(usbpriv->ledctl.sw_led1)); +} + +static void _rtl92cu_sw_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ +} + +void rtl92cu_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && + (ledaction == LED_CTL_TX || + ledaction == LED_CTL_RX || + ledaction == LED_CTL_SITE_SURVEY || + ledaction == LED_CTL_LINK || + ledaction == LED_CTL_NO_LINK || + ledaction == LED_CTL_START_TO_LINK || + ledaction == LED_CTL_POWER_ON)) { + return; + } + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", + ledaction)); + _rtl92cu_sw_led_control(hw, ledaction); +} diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c new file mode 100644 index 000000000000..4e937e0da8e2 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -0,0 +1,327 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../core.h" +#include "../usb.h" +#include "../efuse.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "mac.h" +#include "dm.h" +#include "sw.h" +#include "trx.h" +#include "led.h" +#include "hw.h" + + +MODULE_AUTHOR("Georgia "); +MODULE_AUTHOR("Ziv Huang "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n USB wireless"); +MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin"); + +static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->dm.dm_initialgain_enable = 1; + rtlpriv->dm.dm_flag = 0; + rtlpriv->dm.disable_framebursting = 0; + rtlpriv->dm.thermalvalue = 0; + rtlpriv->rtlhal.pfirmware = vmalloc(0x4000); + if (!rtlpriv->rtlhal.pfirmware) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Can't alloc buffer for fw.\n")); + return 1; + } + return 0; +} + +static void rtl92cu_deinit_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->rtlhal.pfirmware) { + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + } +} + +static struct rtl_hal_ops rtl8192cu_hal_ops = { + .init_sw_vars = rtl92cu_init_sw_vars, + .deinit_sw_vars = rtl92cu_deinit_sw_vars, + .read_chip_version = rtl92c_read_chip_version, + .read_eeprom_info = rtl92cu_read_eeprom_info, + .enable_interrupt = rtl92c_enable_interrupt, + .disable_interrupt = rtl92c_disable_interrupt, + .hw_init = rtl92cu_hw_init, + .hw_disable = rtl92cu_card_disable, + .set_network_type = rtl92cu_set_network_type, + .set_chk_bssid = rtl92cu_set_check_bssid, + .set_qos = rtl92c_set_qos, + .set_bcn_reg = rtl92cu_set_beacon_related_registers, + .set_bcn_intv = rtl92cu_set_beacon_interval, + .update_interrupt_mask = rtl92cu_update_interrupt_mask, + .get_hw_reg = rtl92cu_get_hw_reg, + .set_hw_reg = rtl92cu_set_hw_reg, + .update_rate_table = rtl92cu_update_hal_rate_table, + .update_rate_mask = rtl92cu_update_hal_rate_mask, + .fill_tx_desc = rtl92cu_tx_fill_desc, + .fill_fake_txdesc = rtl92cu_fill_fake_txdesc, + .fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc, + .cmd_send_packet = rtl92cu_cmd_send_packet, + .query_rx_desc = rtl92cu_rx_query_desc, + .set_channel_access = rtl92cu_update_channel_access_setting, + .radio_onoff_checking = rtl92cu_gpio_radio_on_off_checking, + .set_bw_mode = rtl92c_phy_set_bw_mode, + .switch_channel = rtl92c_phy_sw_chnl, + .dm_watchdog = rtl92c_dm_watchdog, + .scan_operation_backup = rtl92c_phy_scan_operation_backup, + .set_rf_power_state = rtl92c_phy_set_rf_power_state, + .led_control = rtl92cu_led_control, + .enable_hw_sec = rtl92cu_enable_hw_security_config, + .set_key = rtl92c_set_key, + .init_sw_leds = rtl92cu_init_sw_leds, + .deinit_sw_leds = rtl92cu_deinit_sw_leds, + .get_bbreg = rtl92c_phy_query_bb_reg, + .set_bbreg = rtl92c_phy_set_bb_reg, + .get_rfreg = rtl92c_phy_query_rf_reg, + .set_rfreg = rtl92c_phy_set_rf_reg, +}; + +static struct rtl_mod_params rtl92cu_mod_params = { + .sw_crypto = 0, +}; + +static struct rtl_hal_usbint_cfg rtl92cu_interface_cfg = { + /* rx */ + .in_ep_num = RTL92C_USB_BULK_IN_NUM, + .rx_urb_num = RTL92C_NUM_RX_URBS, + .rx_max_size = RTL92C_SIZE_MAX_RX_BUFFER, + .usb_rx_hdl = rtl8192cu_rx_hdl, + .usb_rx_segregate_hdl = NULL, /* rtl8192c_rx_segregate_hdl; */ + /* tx */ + .usb_tx_cleanup = rtl8192c_tx_cleanup, + .usb_tx_post_hdl = rtl8192c_tx_post_hdl, + .usb_tx_aggregate_hdl = rtl8192c_tx_aggregate_hdl, + /* endpoint mapping */ + .usb_endpoint_mapping = rtl8192cu_endpoint_mapping, + .usb_mq_to_hwq = rtl8192cu_mq_to_hwq, +}; + +static struct rtl_hal_cfg rtl92cu_hal_cfg = { + .name = "rtl92c_usb", + .fw_name = "rtlwifi/rtl8192cufw.bin", + .ops = &rtl8192cu_hal_ops, + .mod_params = &rtl92cu_mod_params, + .usb_interface_cfg = &rtl92cu_interface_cfg, + + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, + .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, + .maps[SYS_CLK] = REG_SYS_CLKR, + .maps[MAC_RCR_AM] = AM, + .maps[MAC_RCR_AB] = AB, + .maps[MAC_RCR_ACRC32] = ACRC32, + .maps[MAC_RCR_ACF] = ACF, + .maps[MAC_RCR_AAP] = AAP, + + .maps[EFUSE_TEST] = REG_EFUSE_TEST, + .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_CLK] = 0, + .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, + .maps[EFUSE_PWC_EV12V] = PWC_EV12V, + .maps[EFUSE_FEN_ELDR] = FEN_ELDR, + .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, + .maps[EFUSE_ANA8M] = EFUSE_ANA8M, + .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, + .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, + .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, + + .maps[RWCAM] = REG_CAMCMD, + .maps[WCAMI] = REG_CAMWRITE, + .maps[RCAMO] = REG_CAMREAD, + .maps[CAMDBG] = REG_CAMDBG, + .maps[SECR] = REG_SECCFG, + .maps[SEC_CAM_NONE] = CAM_NONE, + .maps[SEC_CAM_WEP40] = CAM_WEP40, + .maps[SEC_CAM_TKIP] = CAM_TKIP, + .maps[SEC_CAM_AES] = CAM_AES, + .maps[SEC_CAM_WEP104] = CAM_WEP104, + + .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, + .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, + .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, + .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, + .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, + .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, + .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, + .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, + .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, + .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, + .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, + .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, + .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, + .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, + .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2, + .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1, + + .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, + .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, + .maps[RTL_IMR_BcnInt] = IMR_BCNINT, + .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, + .maps[RTL_IMR_RDU] = IMR_RDU, + .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, + .maps[RTL_IMR_BDOK] = IMR_BDOK, + .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK, + .maps[RTL_IMR_TBDER] = IMR_TBDER, + .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK, + .maps[RTL_IMR_TBDOK] = IMR_TBDOK, + .maps[RTL_IMR_BKDOK] = IMR_BKDOK, + .maps[RTL_IMR_BEDOK] = IMR_BEDOK, + .maps[RTL_IMR_VIDOK] = IMR_VIDOK, + .maps[RTL_IMR_VODOK] = IMR_VODOK, + .maps[RTL_IMR_ROK] = IMR_ROK, + .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER), + + .maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M, + .maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M, + .maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M, + .maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M, + .maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M, + .maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M, + .maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M, + .maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M, + .maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M, + .maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M, + .maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M, + .maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M, + .maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7, + .maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15, +}; + +#define USB_VENDER_ID_REALTEK 0x0bda + +/* 2010-10-19 DID_USB_V3.4 */ +static struct usb_device_id rtl8192c_usb_ids[] = { + + /*=== Realtek demoboard ===*/ + /* Default ID */ + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8191, rtl92cu_hal_cfg)}, + + /****** 8188CU ********/ + /* 8188CE-VAU USB minCard */ + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8170, rtl92cu_hal_cfg)}, + /* 8188cu 1*1 dongle */ + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8176, rtl92cu_hal_cfg)}, + /* 8188cu 1*1 dongle, (b/g mode only) */ + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8177, rtl92cu_hal_cfg)}, + /* 8188cu Slim Solo */ + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817a, rtl92cu_hal_cfg)}, + /* 8188cu Slim Combo */ + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817b, rtl92cu_hal_cfg)}, + /* 8188RU High-power USB Dongle */ + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817d, rtl92cu_hal_cfg)}, + /* 8188CE-VAU USB minCard (b/g mode only) */ + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817e, rtl92cu_hal_cfg)}, + /* 8188 Combo for BC4 */ + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8754, rtl92cu_hal_cfg)}, + + /****** 8192CU ********/ + /* 8191cu 1*2 */ + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8177, rtl92cu_hal_cfg)}, + /* 8192cu 2*2 */ + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817b, rtl92cu_hal_cfg)}, + /* 8192CE-VAU USB minCard */ + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817c, rtl92cu_hal_cfg)}, + + /*=== Customer ID ===*/ + /****** 8188CU ********/ + {RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/ + {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ + {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ + {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ + {RTL_USB_DEVICE(0x0Df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ + {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ + /* HP - Lite-On ,8188CUS Slim Combo */ + {RTL_USB_DEVICE(0x103c, 0x1629, rtl92cu_hal_cfg)}, + {RTL_USB_DEVICE(0x2001, 0x3308, rtl92cu_hal_cfg)}, /*D-Link - Alpha*/ + {RTL_USB_DEVICE(0x2019, 0xab2a, rtl92cu_hal_cfg)}, /*Planex - Abocom*/ + {RTL_USB_DEVICE(0x2019, 0xed17, rtl92cu_hal_cfg)}, /*PCI - Edimax*/ + {RTL_USB_DEVICE(0x20f4, 0x648b, rtl92cu_hal_cfg)}, /*TRENDnet - Cameo*/ + {RTL_USB_DEVICE(0x7392, 0x7811, rtl92cu_hal_cfg)}, /*Edimax - Edimax*/ + {RTL_USB_DEVICE(0x3358, 0x13d3, rtl92cu_hal_cfg)}, /*Azwave 8188CE-VAU*/ + /* Russian customer -Azwave (8188CE-VAU b/g mode only) */ + {RTL_USB_DEVICE(0x3359, 0x13d3, rtl92cu_hal_cfg)}, + + /****** 8192CU ********/ + {RTL_USB_DEVICE(0x0586, 0x341f, rtl92cu_hal_cfg)}, /*Zyxel -Abocom*/ + {RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/ + {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/ + {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Abocom -Abocom*/ + {RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/ + {RTL_USB_DEVICE(0x2001, 0x3309, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ + {RTL_USB_DEVICE(0x2001, 0x330a, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ + {RTL_USB_DEVICE(0x2019, 0xab2b, rtl92cu_hal_cfg)}, /*Planex -Abocom*/ + {RTL_USB_DEVICE(0x7392, 0x7822, rtl92cu_hal_cfg)}, /*Edimax -Edimax*/ + {} +}; + +MODULE_DEVICE_TABLE(usb, rtl8192c_usb_ids); + +static struct usb_driver rtl8192cu_driver = { + .name = "rtl8192cu", + .probe = rtl_usb_probe, + .disconnect = rtl_usb_disconnect, + .id_table = rtl8192c_usb_ids, + +#ifdef CONFIG_PM + /* .suspend = rtl_usb_suspend, */ + /* .resume = rtl_usb_resume, */ + /* .reset_resume = rtl8192c_resume, */ +#endif /* CONFIG_PM */ +#ifdef CONFIG_AUTOSUSPEND + .supports_autosuspend = 1, +#endif +}; + +static int __init rtl8192cu_init(void) +{ + return usb_register(&rtl8192cu_driver); +} + +static void __exit rtl8192cu_exit(void) +{ + usb_deregister(&rtl8192cu_driver); +} + +module_init(rtl8192cu_init); +module_exit(rtl8192cu_exit); -- cgit v1.2.3 From dc0313f46664192c3cbd60e94abb28ab6f00979d Mon Sep 17 00:00:00 2001 From: George Date: Sat, 19 Feb 2011 16:29:22 -0600 Subject: rtlwifi: rtl8192cu: Add routine hw Add the routine rtlwifi/rtl8192cu/hw.c. This one is distinct from the routine of the same name in rtl8192ce. Signed-off-by: George Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 2505 +++++++++++++++++++++++++++ 1 file changed, 2505 insertions(+) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/hw.c (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c new file mode 100644 index 000000000000..df8fe3b51c9b --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -0,0 +1,2505 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../efuse.h" +#include "../base.h" +#include "../cam.h" +#include "../ps.h" +#include "../usb.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "mac.h" +#include "dm.h" +#include "fw.h" +#include "hw.h" +#include "trx.h" +#include "led.h" +#include "table.h" + +static void _rtl92cu_phy_param_tab_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); + + rtlphy->hwparam_tables[MAC_REG].length = RTL8192CUMAC_2T_ARRAYLENGTH; + rtlphy->hwparam_tables[MAC_REG].pdata = RTL8192CUMAC_2T_ARRAY; + if (IS_HIGHT_PA(rtlefuse->board_type)) { + rtlphy->hwparam_tables[PHY_REG_PG].length = + RTL8192CUPHY_REG_Array_PG_HPLength; + rtlphy->hwparam_tables[PHY_REG_PG].pdata = + RTL8192CUPHY_REG_Array_PG_HP; + } else { + rtlphy->hwparam_tables[PHY_REG_PG].length = + RTL8192CUPHY_REG_ARRAY_PGLENGTH; + rtlphy->hwparam_tables[PHY_REG_PG].pdata = + RTL8192CUPHY_REG_ARRAY_PG; + } + /* 2T */ + rtlphy->hwparam_tables[PHY_REG_2T].length = + RTL8192CUPHY_REG_2TARRAY_LENGTH; + rtlphy->hwparam_tables[PHY_REG_2T].pdata = + RTL8192CUPHY_REG_2TARRAY; + rtlphy->hwparam_tables[RADIOA_2T].length = + RTL8192CURADIOA_2TARRAYLENGTH; + rtlphy->hwparam_tables[RADIOA_2T].pdata = + RTL8192CURADIOA_2TARRAY; + rtlphy->hwparam_tables[RADIOB_2T].length = + RTL8192CURADIOB_2TARRAYLENGTH; + rtlphy->hwparam_tables[RADIOB_2T].pdata = + RTL8192CU_RADIOB_2TARRAY; + rtlphy->hwparam_tables[AGCTAB_2T].length = + RTL8192CUAGCTAB_2TARRAYLENGTH; + rtlphy->hwparam_tables[AGCTAB_2T].pdata = + RTL8192CUAGCTAB_2TARRAY; + /* 1T */ + if (IS_HIGHT_PA(rtlefuse->board_type)) { + rtlphy->hwparam_tables[PHY_REG_1T].length = + RTL8192CUPHY_REG_1T_HPArrayLength; + rtlphy->hwparam_tables[PHY_REG_1T].pdata = + RTL8192CUPHY_REG_1T_HPArray; + rtlphy->hwparam_tables[RADIOA_1T].length = + RTL8192CURadioA_1T_HPArrayLength; + rtlphy->hwparam_tables[RADIOA_1T].pdata = + RTL8192CURadioA_1T_HPArray; + rtlphy->hwparam_tables[RADIOB_1T].length = + RTL8192CURADIOB_1TARRAYLENGTH; + rtlphy->hwparam_tables[RADIOB_1T].pdata = + RTL8192CU_RADIOB_1TARRAY; + rtlphy->hwparam_tables[AGCTAB_1T].length = + RTL8192CUAGCTAB_1T_HPArrayLength; + rtlphy->hwparam_tables[AGCTAB_1T].pdata = + Rtl8192CUAGCTAB_1T_HPArray; + } else { + rtlphy->hwparam_tables[PHY_REG_1T].length = + RTL8192CUPHY_REG_1TARRAY_LENGTH; + rtlphy->hwparam_tables[PHY_REG_1T].pdata = + RTL8192CUPHY_REG_1TARRAY; + rtlphy->hwparam_tables[RADIOA_1T].length = + RTL8192CURADIOA_1TARRAYLENGTH; + rtlphy->hwparam_tables[RADIOA_1T].pdata = + RTL8192CU_RADIOA_1TARRAY; + rtlphy->hwparam_tables[RADIOB_1T].length = + RTL8192CURADIOB_1TARRAYLENGTH; + rtlphy->hwparam_tables[RADIOB_1T].pdata = + RTL8192CU_RADIOB_1TARRAY; + rtlphy->hwparam_tables[AGCTAB_1T].length = + RTL8192CUAGCTAB_1TARRAYLENGTH; + rtlphy->hwparam_tables[AGCTAB_1T].pdata = + RTL8192CUAGCTAB_1TARRAY; + } +} + +static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, + u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 rf_path, index, tempval; + u16 i; + + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 3; i++) { + if (!autoload_fail) { + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i] = + hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i]; + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = + hwinfo[EEPROM_TXPOWERHT40_1S + rf_path * 3 + + i]; + } else { + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i] = + EEPROM_DEFAULT_TXPOWERLEVEL; + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = + EEPROM_DEFAULT_TXPOWERLEVEL; + } + } + } + for (i = 0; i < 3; i++) { + if (!autoload_fail) + tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; + else + tempval = EEPROM_DEFAULT_HT40_2SDIFF; + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_A][i] = + (tempval & 0xf); + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_B][i] = + ((tempval & 0xf0) >> 4); + } + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, + i, rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i])); + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i])); + for (rf_path = 0; rf_path < 2; rf_path++) + for (i = 0; i < 3; i++) + RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] + [i])); + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 14; i++) { + index = _rtl92c_get_chnl_group((u8) i); + rtlefuse->txpwrlevel_cck[rf_path][i] = + rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][index]; + rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][index]; + if ((rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] - + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][index]) + > 0) { + rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path] + [index] - rtlefuse-> + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] + [index]; + } else { + rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0; + } + } + for (i = 0; i < 14; i++) { + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = " + "[0x%x / 0x%x / 0x%x]\n", rf_path, i, + rtlefuse->txpwrlevel_cck[rf_path][i], + rtlefuse->txpwrlevel_ht40_1s[rf_path][i], + rtlefuse->txpwrlevel_ht40_2s[rf_path][i])); + } + } + for (i = 0; i < 3; i++) { + if (!autoload_fail) { + rtlefuse->eeprom_pwrlimit_ht40[i] = + hwinfo[EEPROM_TXPWR_GROUP + i]; + rtlefuse->eeprom_pwrlimit_ht20[i] = + hwinfo[EEPROM_TXPWR_GROUP + 3 + i]; + } else { + rtlefuse->eeprom_pwrlimit_ht40[i] = 0; + rtlefuse->eeprom_pwrlimit_ht20[i] = 0; + } + } + for (rf_path = 0; rf_path < 2; rf_path++) { + for (i = 0; i < 14; i++) { + index = _rtl92c_get_chnl_group((u8) i); + if (rf_path == RF90_PATH_A) { + rtlefuse->pwrgroup_ht20[rf_path][i] = + (rtlefuse->eeprom_pwrlimit_ht20[index] + & 0xf); + rtlefuse->pwrgroup_ht40[rf_path][i] = + (rtlefuse->eeprom_pwrlimit_ht40[index] + & 0xf); + } else if (rf_path == RF90_PATH_B) { + rtlefuse->pwrgroup_ht20[rf_path][i] = + ((rtlefuse->eeprom_pwrlimit_ht20[index] + & 0xf0) >> 4); + rtlefuse->pwrgroup_ht40[rf_path][i] = + ((rtlefuse->eeprom_pwrlimit_ht40[index] + & 0xf0) >> 4); + } + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF-%d pwrgroup_ht20[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht20[rf_path][i])); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF-%d pwrgroup_ht40[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht40[rf_path][i])); + } + } + for (i = 0; i < 14; i++) { + index = _rtl92c_get_chnl_group((u8) i); + if (!autoload_fail) + tempval = hwinfo[EEPROM_TXPOWERHT20DIFF + index]; + else + tempval = EEPROM_DEFAULT_HT20_DIFF; + rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); + rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = + ((tempval >> 4) & 0xF); + if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] & BIT(3)) + rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] |= 0xF0; + if (rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] & BIT(3)) + rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] |= 0xF0; + index = _rtl92c_get_chnl_group((u8) i); + if (!autoload_fail) + tempval = hwinfo[EEPROM_TXPOWER_OFDMDIFF + index]; + else + tempval = EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF); + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = + ((tempval >> 4) & 0xF); + } + rtlefuse->legacy_ht_txpowerdiff = + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7]; + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, + rtlefuse->txpwr_ht20diff[RF90_PATH_A][i])); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i])); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, + rtlefuse->txpwr_ht20diff[RF90_PATH_B][i])); + for (i = 0; i < 14; i++) + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, + rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i])); + if (!autoload_fail) + rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); + else + rtlefuse->eeprom_regulatory = 0; + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory)); + if (!autoload_fail) { + rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; + rtlefuse->eeprom_tssi[RF90_PATH_B] = hwinfo[EEPROM_TSSI_B]; + } else { + rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI; + rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI; + } + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("TSSI_A = 0x%x, TSSI_B = 0x%x\n", + rtlefuse->eeprom_tssi[RF90_PATH_A], + rtlefuse->eeprom_tssi[RF90_PATH_B])); + if (!autoload_fail) + tempval = hwinfo[EEPROM_THERMAL_METER]; + else + tempval = EEPROM_DEFAULT_THERMALMETER; + rtlefuse->eeprom_thermalmeter = (tempval & 0x1f); + if (rtlefuse->eeprom_thermalmeter < 0x06 || + rtlefuse->eeprom_thermalmeter > 0x1c) + rtlefuse->eeprom_thermalmeter = 0x12; + if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail) + rtlefuse->apk_thermalmeterignore = true; + rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + ("thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter)); +} + +static void _rtl92cu_read_board_type(struct ieee80211_hw *hw, u8 *contents) +{ + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 boardType; + + if (IS_NORMAL_CHIP(rtlhal->version)) { + boardType = ((contents[EEPROM_RF_OPT1]) & + BOARD_TYPE_NORMAL_MASK) >> 5; /*bit[7:5]*/ + } else { + boardType = contents[EEPROM_RF_OPT4]; + boardType &= BOARD_TYPE_TEST_MASK; + } + rtlefuse->board_type = boardType; + if (IS_HIGHT_PA(rtlefuse->board_type)) + rtlefuse->external_pa = 1; + printk(KERN_INFO "rtl8192cu: Board Type %x\n", rtlefuse->board_type); + +#ifdef CONFIG_ANTENNA_DIVERSITY + /* Antenna Diversity setting. */ + if (registry_par->antdiv_cfg == 2) /* 2: From Efuse */ + rtl_efuse->antenna_cfg = (contents[EEPROM_RF_OPT1]&0x18)>>3; + else + rtl_efuse->antenna_cfg = registry_par->antdiv_cfg; /* 0:OFF, */ + + printk(KERN_INFO "rtl8192cu: Antenna Config %x\n", + rtl_efuse->antenna_cfg); +#endif +} + +#ifdef CONFIG_BT_COEXIST +static void _update_bt_param(_adapter *padapter) +{ + struct btcoexist_priv *pbtpriv = &(padapter->halpriv.bt_coexist); + struct registry_priv *registry_par = &padapter->registrypriv; + if (2 != registry_par->bt_iso) { + /* 0:Low, 1:High, 2:From Efuse */ + pbtpriv->BT_Ant_isolation = registry_par->bt_iso; + } + if (registry_par->bt_sco == 1) { + /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter, 4.Busy, + * 5.OtherBusy */ + pbtpriv->BT_Service = BT_OtherAction; + } else if (registry_par->bt_sco == 2) { + pbtpriv->BT_Service = BT_SCO; + } else if (registry_par->bt_sco == 4) { + pbtpriv->BT_Service = BT_Busy; + } else if (registry_par->bt_sco == 5) { + pbtpriv->BT_Service = BT_OtherBusy; + } else { + pbtpriv->BT_Service = BT_Idle; + } + pbtpriv->BT_Ampdu = registry_par->bt_ampdu; + pbtpriv->bCOBT = _TRUE; + pbtpriv->BtEdcaUL = 0; + pbtpriv->BtEdcaDL = 0; + pbtpriv->BtRssiState = 0xff; + pbtpriv->bInitSet = _FALSE; + pbtpriv->bBTBusyTraffic = _FALSE; + pbtpriv->bBTTrafficModeSet = _FALSE; + pbtpriv->bBTNonTrafficModeSet = _FALSE; + pbtpriv->CurrentState = 0; + pbtpriv->PreviousState = 0; + printk(KERN_INFO "rtl8192cu: BT Coexistance = %s\n", + (pbtpriv->BT_Coexist == _TRUE) ? "enable" : "disable"); + if (pbtpriv->BT_Coexist) { + if (pbtpriv->BT_Ant_Num == Ant_x2) + printk(KERN_INFO "rtl8192cu: BlueTooth BT_" + "Ant_Num = Antx2\n"); + else if (pbtpriv->BT_Ant_Num == Ant_x1) + printk(KERN_INFO "rtl8192cu: BlueTooth BT_" + "Ant_Num = Antx1\n"); + switch (pbtpriv->BT_CoexistType) { + case BT_2Wire: + printk(KERN_INFO "rtl8192cu: BlueTooth BT_" + "CoexistType = BT_2Wire\n"); + break; + case BT_ISSC_3Wire: + printk(KERN_INFO "rtl8192cu: BlueTooth BT_" + "CoexistType = BT_ISSC_3Wire\n"); + break; + case BT_Accel: + printk(KERN_INFO "rtl8192cu: BlueTooth BT_" + "CoexistType = BT_Accel\n"); + break; + case BT_CSR_BC4: + printk(KERN_INFO "rtl8192cu: BlueTooth BT_" + "CoexistType = BT_CSR_BC4\n"); + break; + case BT_CSR_BC8: + printk(KERN_INFO "rtl8192cu: BlueTooth BT_" + "CoexistType = BT_CSR_BC8\n"); + break; + case BT_RTL8756: + printk(KERN_INFO "rtl8192cu: BlueTooth BT_" + "CoexistType = BT_RTL8756\n"); + break; + default: + printk(KERN_INFO "rtl8192cu: BlueTooth BT_" + "CoexistType = Unknown\n"); + break; + } + printk(KERN_INFO "rtl8192cu: BlueTooth BT_Ant_isolation = %d\n", + pbtpriv->BT_Ant_isolation); + switch (pbtpriv->BT_Service) { + case BT_OtherAction: + printk(KERN_INFO "rtl8192cu: BlueTooth BT_Service = " + "BT_OtherAction\n"); + break; + case BT_SCO: + printk(KERN_INFO "rtl8192cu: BlueTooth BT_Service = " + "BT_SCO\n"); + break; + case BT_Busy: + printk(KERN_INFO "rtl8192cu: BlueTooth BT_Service = " + "BT_Busy\n"); + break; + case BT_OtherBusy: + printk(KERN_INFO "rtl8192cu: BlueTooth BT_Service = " + "BT_OtherBusy\n"); + break; + default: + printk(KERN_INFO "rtl8192cu: BlueTooth BT_Service = " + "BT_Idle\n"); + break; + } + printk(KERN_INFO "rtl8192cu: BT_RadioSharedType = 0x%x\n", + pbtpriv->BT_RadioSharedType); + } +} + +#define GET_BT_COEXIST(priv) (&priv->bt_coexist) + +static void _rtl92cu_read_bluetooth_coexistInfo(struct ieee80211_hw *hw, + u8 *contents, + bool bautoloadfailed); +{ + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); + bool isNormal = IS_NORMAL_CHIP(pHalData->VersionID); + struct btcoexist_priv *pbtpriv = &pHalData->bt_coexist; + u8 rf_opt4; + + _rtw_memset(pbtpriv, 0, sizeof(struct btcoexist_priv)); + if (AutoloadFail) { + pbtpriv->BT_Coexist = _FALSE; + pbtpriv->BT_CoexistType = BT_2Wire; + pbtpriv->BT_Ant_Num = Ant_x2; + pbtpriv->BT_Ant_isolation = 0; + pbtpriv->BT_RadioSharedType = BT_Radio_Shared; + return; + } + if (isNormal) { + if (pHalData->BoardType == BOARD_USB_COMBO) + pbtpriv->BT_Coexist = _TRUE; + else + pbtpriv->BT_Coexist = ((PROMContent[EEPROM_RF_OPT3] & + 0x20) >> 5); /* bit[5] */ + rf_opt4 = PROMContent[EEPROM_RF_OPT4]; + pbtpriv->BT_CoexistType = ((rf_opt4&0xe)>>1); /* bit [3:1] */ + pbtpriv->BT_Ant_Num = (rf_opt4&0x1); /* bit [0] */ + pbtpriv->BT_Ant_isolation = ((rf_opt4&0x10)>>4); /* bit [4] */ + pbtpriv->BT_RadioSharedType = ((rf_opt4&0x20)>>5); /* bit [5] */ + } else { + pbtpriv->BT_Coexist = (PROMContent[EEPROM_RF_OPT4] >> 4) ? + _TRUE : _FALSE; + } + _update_bt_param(Adapter); +} +#endif + +static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u16 i, usvalue; + u8 hwinfo[HWSET_MAX_SIZE] = {0}; + u16 eeprom_id; + + if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) { + rtl_efuse_shadow_map_update(hw); + memcpy((void *)hwinfo, + (void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], + HWSET_MAX_SIZE); + } else if (rtlefuse->epromtype == EEPROM_93C46) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("RTL819X Not boot from eeprom, check it !!")); + } + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, ("MAP\n"), + hwinfo, HWSET_MAX_SIZE); + eeprom_id = *((u16 *)&hwinfo[0]); + if (eeprom_id != RTL8190_EEPROM_ID) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); + rtlefuse->autoload_failflag = true; + } else { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + rtlefuse->autoload_failflag = false; + } + if (rtlefuse->autoload_failflag == true) + return; + for (i = 0; i < 6; i += 2) { + usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; + *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue; + } + printk(KERN_INFO "rtl8192cu: MAC address: %pM\n", rtlefuse->dev_addr); + _rtl92cu_read_txpower_info_from_hwpg(hw, + rtlefuse->autoload_failflag, hwinfo); + rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID]; + rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID]; + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + (" VID = 0x%02x PID = 0x%02x\n", + rtlefuse->eeprom_vid, rtlefuse->eeprom_did)); + rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; + rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; + rtlefuse->txpwr_fromeprom = true; + rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid)); + if (rtlhal->oem_id == RT_CID_DEFAULT) { + switch (rtlefuse->eeprom_oemid) { + case EEPROM_CID_DEFAULT: + if (rtlefuse->eeprom_did == 0x8176) { + if ((rtlefuse->eeprom_svid == 0x103C && + rtlefuse->eeprom_smid == 0x1629)) + rtlhal->oem_id = RT_CID_819x_HP; + else + rtlhal->oem_id = RT_CID_DEFAULT; + } else { + rtlhal->oem_id = RT_CID_DEFAULT; + } + break; + case EEPROM_CID_TOSHIBA: + rtlhal->oem_id = RT_CID_TOSHIBA; + break; + case EEPROM_CID_QMI: + rtlhal->oem_id = RT_CID_819x_QMI; + break; + case EEPROM_CID_WHQL: + default: + rtlhal->oem_id = RT_CID_DEFAULT; + break; + } + } + _rtl92cu_read_board_type(hw, hwinfo); +#ifdef CONFIG_BT_COEXIST + _rtl92cu_read_bluetooth_coexistInfo(hw, hwinfo, + rtlefuse->autoload_failflag); +#endif +} + +static void _rtl92cu_hal_customized_behavior(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + switch (rtlhal->oem_id) { + case RT_CID_819x_HP: + usb_priv->ledctl.led_opendrain = true; + break; + case RT_CID_819x_Lenovo: + case RT_CID_DEFAULT: + case RT_CID_TOSHIBA: + case RT_CID_CCX: + case RT_CID_819x_Acer: + case RT_CID_WHQL: + default: + break; + } + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("RT Customized ID: 0x%02X\n", rtlhal->oem_id)); +} + +void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw) +{ + + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_u1b; + + if (!IS_NORMAL_CHIP(rtlhal->version)) + return; + tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); + rtlefuse->epromtype = (tmp_u1b & EEPROMSEL) ? + EEPROM_93C46 : EEPROM_BOOT_EFUSE; + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from %s\n", + (tmp_u1b & EEPROMSEL) ? "EERROM" : "EFUSE")); + rtlefuse->autoload_failflag = (tmp_u1b & EEPROM_EN) ? false : true; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload %s\n", + (tmp_u1b & EEPROM_EN) ? "OK!!" : "ERR!!")); + _rtl92cu_read_adapter_info(hw); + _rtl92cu_hal_customized_behavior(hw); + return; +} + +static int _rtl92cu_init_power_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int status = 0; + u16 value16; + u8 value8; + /* polling autoload done. */ + u32 pollingCount = 0; + + do { + if (rtl_read_byte(rtlpriv, REG_APS_FSMCO) & PFM_ALDN) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("Autoload Done!\n")); + break; + } + if (pollingCount++ > 100) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, + ("Failed to polling REG_APS_FSMCO[PFM_ALDN]" + " done!\n")); + return -ENODEV; + } + } while (true); + /* 0. RSV_CTRL 0x1C[7:0] = 0 unlock ISO/CLK/Power control register */ + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0); + /* Power on when re-enter from IPS/Radio off/card disable */ + /* enable SPS into PWM mode */ + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); + udelay(100); + value8 = rtl_read_byte(rtlpriv, REG_LDOV12D_CTRL); + if (0 == (value8 & LDV12_EN)) { + value8 |= LDV12_EN; + rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, value8); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + (" power-on :REG_LDOV12D_CTRL Reg0x21:0x%02x.\n", + value8)); + udelay(100); + value8 = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL); + value8 &= ~ISO_MD2PP; + rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, value8); + } + /* auto enable WLAN */ + pollingCount = 0; + value16 = rtl_read_word(rtlpriv, REG_APS_FSMCO); + value16 |= APFM_ONMAC; + rtl_write_word(rtlpriv, REG_APS_FSMCO, value16); + do { + if (!(rtl_read_word(rtlpriv, REG_APS_FSMCO) & APFM_ONMAC)) { + printk(KERN_INFO "rtl8192cu: MAC auto ON okay!\n"); + break; + } + if (pollingCount++ > 100) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, + ("Failed to polling REG_APS_FSMCO[APFM_ONMAC]" + " done!\n")); + return -ENODEV; + } + } while (true); + /* Enable Radio ,GPIO ,and LED function */ + rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x0812); + /* release RF digital isolation */ + value16 = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL); + value16 &= ~ISO_DIOR; + rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, value16); + /* Reconsider when to do this operation after asking HWSD. */ + pollingCount = 0; + rtl_write_byte(rtlpriv, REG_APSD_CTRL, (rtl_read_byte(rtlpriv, + REG_APSD_CTRL) & ~BIT(6))); + do { + pollingCount++; + } while ((pollingCount < 200) && + (rtl_read_byte(rtlpriv, REG_APSD_CTRL) & BIT(7))); + /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */ + value16 = rtl_read_word(rtlpriv, REG_CR); + value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN | + PROTOCOL_EN | SCHEDULE_EN | MACTXEN | MACRXEN | ENSEC); + rtl_write_word(rtlpriv, REG_CR, value16); + return status; +} + +static void _rtl92cu_init_queue_reserved_page(struct ieee80211_hw *hw, + bool wmm_enable, + u8 out_ep_num, + u8 queue_sel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool isChipN = IS_NORMAL_CHIP(rtlhal->version); + u32 outEPNum = (u32)out_ep_num; + u32 numHQ = 0; + u32 numLQ = 0; + u32 numNQ = 0; + u32 numPubQ; + u32 value32; + u8 value8; + u32 txQPageNum, txQPageUnit, txQRemainPage; + + if (!wmm_enable) { + numPubQ = (isChipN) ? CHIP_B_PAGE_NUM_PUBQ : + CHIP_A_PAGE_NUM_PUBQ; + txQPageNum = TX_TOTAL_PAGE_NUMBER - numPubQ; + + txQPageUnit = txQPageNum/outEPNum; + txQRemainPage = txQPageNum % outEPNum; + if (queue_sel & TX_SELE_HQ) + numHQ = txQPageUnit; + if (queue_sel & TX_SELE_LQ) + numLQ = txQPageUnit; + /* HIGH priority queue always present in the configuration of + * 2 out-ep. Remainder pages have assigned to High queue */ + if ((outEPNum > 1) && (txQRemainPage)) + numHQ += txQRemainPage; + /* NOTE: This step done before writting REG_RQPN. */ + if (isChipN) { + if (queue_sel & TX_SELE_NQ) + numNQ = txQPageUnit; + value8 = (u8)_NPQ(numNQ); + rtl_write_byte(rtlpriv, REG_RQPN_NPQ, value8); + } + } else { + /* for WMM ,number of out-ep must more than or equal to 2! */ + numPubQ = isChipN ? WMM_CHIP_B_PAGE_NUM_PUBQ : + WMM_CHIP_A_PAGE_NUM_PUBQ; + if (queue_sel & TX_SELE_HQ) { + numHQ = isChipN ? WMM_CHIP_B_PAGE_NUM_HPQ : + WMM_CHIP_A_PAGE_NUM_HPQ; + } + if (queue_sel & TX_SELE_LQ) { + numLQ = isChipN ? WMM_CHIP_B_PAGE_NUM_LPQ : + WMM_CHIP_A_PAGE_NUM_LPQ; + } + /* NOTE: This step done before writting REG_RQPN. */ + if (isChipN) { + if (queue_sel & TX_SELE_NQ) + numNQ = WMM_CHIP_B_PAGE_NUM_NPQ; + value8 = (u8)_NPQ(numNQ); + rtl_write_byte(rtlpriv, REG_RQPN_NPQ, value8); + } + } + /* TX DMA */ + value32 = _HPQ(numHQ) | _LPQ(numLQ) | _PUBQ(numPubQ) | LD_RQPN; + rtl_write_dword(rtlpriv, REG_RQPN, value32); +} + +static void _rtl92c_init_trx_buffer(struct ieee80211_hw *hw, bool wmm_enable) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 txpktbuf_bndy; + u8 value8; + + if (!wmm_enable) + txpktbuf_bndy = TX_PAGE_BOUNDARY; + else /* for WMM */ + txpktbuf_bndy = (IS_NORMAL_CHIP(rtlhal->version)) + ? WMM_CHIP_B_TX_PAGE_BOUNDARY + : WMM_CHIP_A_TX_PAGE_BOUNDARY; + rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_TRXFF_BNDY, txpktbuf_bndy); + rtl_write_byte(rtlpriv, REG_TDECTRL+1, txpktbuf_bndy); + rtl_write_word(rtlpriv, (REG_TRXFF_BNDY + 2), 0x27FF); + value8 = _PSRX(RX_PAGE_SIZE_REG_VALUE) | _PSTX(PBP_128); + rtl_write_byte(rtlpriv, REG_PBP, value8); +} + +static void _rtl92c_init_chipN_reg_priority(struct ieee80211_hw *hw, u16 beQ, + u16 bkQ, u16 viQ, u16 voQ, + u16 mgtQ, u16 hiQ) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 value16 = (rtl_read_word(rtlpriv, REG_TRXDMA_CTRL) & 0x7); + + value16 |= _TXDMA_BEQ_MAP(beQ) | _TXDMA_BKQ_MAP(bkQ) | + _TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) | + _TXDMA_MGQ_MAP(mgtQ) | _TXDMA_HIQ_MAP(hiQ); + rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, value16); +} + +static void _rtl92cu_init_chipN_one_out_ep_priority(struct ieee80211_hw *hw, + bool wmm_enable, + u8 queue_sel) +{ + u16 uninitialized_var(value); + + switch (queue_sel) { + case TX_SELE_HQ: + value = QUEUE_HIGH; + break; + case TX_SELE_LQ: + value = QUEUE_LOW; + break; + case TX_SELE_NQ: + value = QUEUE_NORMAL; + break; + default: + WARN_ON(1); /* Shall not reach here! */ + break; + } + _rtl92c_init_chipN_reg_priority(hw, value, value, value, value, + value, value); + printk(KERN_INFO "rtl8192cu: Tx queue select: 0x%02x\n", queue_sel); +} + +static void _rtl92cu_init_chipN_two_out_ep_priority(struct ieee80211_hw *hw, + bool wmm_enable, + u8 queue_sel) +{ + u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ; + u16 uninitialized_var(valueHi); + u16 uninitialized_var(valueLow); + + switch (queue_sel) { + case (TX_SELE_HQ | TX_SELE_LQ): + valueHi = QUEUE_HIGH; + valueLow = QUEUE_LOW; + break; + case (TX_SELE_NQ | TX_SELE_LQ): + valueHi = QUEUE_NORMAL; + valueLow = QUEUE_LOW; + break; + case (TX_SELE_HQ | TX_SELE_NQ): + valueHi = QUEUE_HIGH; + valueLow = QUEUE_NORMAL; + break; + default: + WARN_ON(1); + break; + } + if (!wmm_enable) { + beQ = valueLow; + bkQ = valueLow; + viQ = valueHi; + voQ = valueHi; + mgtQ = valueHi; + hiQ = valueHi; + } else {/* for WMM ,CONFIG_OUT_EP_WIFI_MODE */ + beQ = valueHi; + bkQ = valueLow; + viQ = valueLow; + voQ = valueHi; + mgtQ = valueHi; + hiQ = valueHi; + } + _rtl92c_init_chipN_reg_priority(hw, beQ, bkQ, viQ, voQ, mgtQ, hiQ); + printk(KERN_INFO "rtl8192cu: Tx queue select: 0x%02x\n", queue_sel); +} + +static void _rtl92cu_init_chipN_three_out_ep_priority(struct ieee80211_hw *hw, + bool wmm_enable, + u8 queue_sel) +{ + u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (!wmm_enable) { /* typical setting */ + beQ = QUEUE_LOW; + bkQ = QUEUE_LOW; + viQ = QUEUE_NORMAL; + voQ = QUEUE_HIGH; + mgtQ = QUEUE_HIGH; + hiQ = QUEUE_HIGH; + } else { /* for WMM */ + beQ = QUEUE_LOW; + bkQ = QUEUE_NORMAL; + viQ = QUEUE_NORMAL; + voQ = QUEUE_HIGH; + mgtQ = QUEUE_HIGH; + hiQ = QUEUE_HIGH; + } + _rtl92c_init_chipN_reg_priority(hw, beQ, bkQ, viQ, voQ, mgtQ, hiQ); + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, + ("Tx queue select :0x%02x..\n", queue_sel)); +} + +static void _rtl92cu_init_chipN_queue_priority(struct ieee80211_hw *hw, + bool wmm_enable, + u8 out_ep_num, + u8 queue_sel) +{ + switch (out_ep_num) { + case 1: + _rtl92cu_init_chipN_one_out_ep_priority(hw, wmm_enable, + queue_sel); + break; + case 2: + _rtl92cu_init_chipN_two_out_ep_priority(hw, wmm_enable, + queue_sel); + break; + case 3: + _rtl92cu_init_chipN_three_out_ep_priority(hw, wmm_enable, + queue_sel); + break; + default: + WARN_ON(1); /* Shall not reach here! */ + break; + } +} + +static void _rtl92cu_init_chipT_queue_priority(struct ieee80211_hw *hw, + bool wmm_enable, + u8 out_ep_num, + u8 queue_sel) +{ + u8 hq_sele; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + switch (out_ep_num) { + case 2: /* (TX_SELE_HQ|TX_SELE_LQ) */ + if (!wmm_enable) /* typical setting */ + hq_sele = HQSEL_VOQ | HQSEL_VIQ | HQSEL_MGTQ | + HQSEL_HIQ; + else /* for WMM */ + hq_sele = HQSEL_VOQ | HQSEL_BEQ | HQSEL_MGTQ | + HQSEL_HIQ; + break; + case 1: + if (TX_SELE_LQ == queue_sel) { + /* map all endpoint to Low queue */ + hq_sele = 0; + } else if (TX_SELE_HQ == queue_sel) { + /* map all endpoint to High queue */ + hq_sele = HQSEL_VOQ | HQSEL_VIQ | HQSEL_BEQ | + HQSEL_BKQ | HQSEL_MGTQ | HQSEL_HIQ; + } + break; + default: + WARN_ON(1); /* Shall not reach here! */ + break; + } + rtl_write_byte(rtlpriv, (REG_TRXDMA_CTRL+1), hq_sele); + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, + ("Tx queue select :0x%02x..\n", hq_sele)); +} + +static void _rtl92cu_init_queue_priority(struct ieee80211_hw *hw, + bool wmm_enable, + u8 out_ep_num, + u8 queue_sel) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + if (IS_NORMAL_CHIP(rtlhal->version)) + _rtl92cu_init_chipN_queue_priority(hw, wmm_enable, out_ep_num, + queue_sel); + else + _rtl92cu_init_chipT_queue_priority(hw, wmm_enable, out_ep_num, + queue_sel); +} + +static void _rtl92cu_init_usb_aggregation(struct ieee80211_hw *hw) +{ +} + +static void _rtl92cu_init_wmac_setting(struct ieee80211_hw *hw) +{ + u16 value16; + + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + mac->rx_conf = (RCR_APM | RCR_AM | RCR_ADF | RCR_AB | RCR_APP_FCS | + RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL | + RCR_APP_MIC | RCR_APP_PHYSTS | RCR_ACRC32); + rtl_write_dword(rtlpriv, REG_RCR, mac->rx_conf); + /* Accept all multicast address */ + rtl_write_dword(rtlpriv, REG_MAR, 0xFFFFFFFF); + rtl_write_dword(rtlpriv, REG_MAR + 4, 0xFFFFFFFF); + /* Accept all management frames */ + value16 = 0xFFFF; + rtl92c_set_mgt_filter(hw, value16); + /* Reject all control frame - default value is 0 */ + rtl92c_set_ctrl_filter(hw, 0x0); + /* Accept all data frames */ + value16 = 0xFFFF; + rtl92c_set_data_filter(hw, value16); +} + +static int _rtl92cu_init_mac(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); + int err = 0; + u32 boundary = 0; + u8 wmm_enable = false; /* TODO */ + u8 out_ep_nums = rtlusb->out_ep_nums; + u8 queue_sel = rtlusb->out_queue_sel; + err = _rtl92cu_init_power_on(hw); + + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Failed to init power on!\n")); + return err; + } + if (!wmm_enable) { + boundary = TX_PAGE_BOUNDARY; + } else { /* for WMM */ + boundary = (IS_NORMAL_CHIP(rtlhal->version)) + ? WMM_CHIP_B_TX_PAGE_BOUNDARY + : WMM_CHIP_A_TX_PAGE_BOUNDARY; + } + if (false == rtl92c_init_llt_table(hw, boundary)) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Failed to init LLT Table!\n")); + return -EINVAL; + } + _rtl92cu_init_queue_reserved_page(hw, wmm_enable, out_ep_nums, + queue_sel); + _rtl92c_init_trx_buffer(hw, wmm_enable); + _rtl92cu_init_queue_priority(hw, wmm_enable, out_ep_nums, + queue_sel); + /* Get Rx PHY status in order to report RSSI and others. */ + rtl92c_init_driver_info_size(hw, RTL92C_DRIVER_INFO_SIZE); + rtl92c_init_interrupt(hw); + rtl92c_init_network_type(hw); + _rtl92cu_init_wmac_setting(hw); + rtl92c_init_adaptive_ctrl(hw); + rtl92c_init_edca(hw); + rtl92c_init_rate_fallback(hw); + rtl92c_init_retry_function(hw); + _rtl92cu_init_usb_aggregation(hw); + rtlpriv->cfg->ops->set_bw_mode(hw, NL80211_CHAN_HT20); + rtl92c_set_min_space(hw, IS_92C_SERIAL(rtlhal->version)); + rtl92c_init_beacon_parameters(hw, rtlhal->version); + rtl92c_init_ampdu_aggregation(hw); + rtl92c_init_beacon_max_error(hw, true); + return err; +} + +void rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 sec_reg_value = 0x0; + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm)); + if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("not open sw encryption\n")); + return; + } + sec_reg_value = SCR_TxEncEnable | SCR_RxDecEnable; + if (rtlpriv->sec.use_defaultkey) { + sec_reg_value |= SCR_TxUseDK; + sec_reg_value |= SCR_RxUseDK; + } + if (IS_NORMAL_CHIP(rtlhal->version)) + sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); + rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("The SECR-value %x\n", sec_reg_value)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); +} + +static void _rtl92cu_hw_configure(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + /* To Fix MAC loopback mode fail. */ + rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f); + rtl_write_byte(rtlpriv, 0x15, 0xe9); + /* HW SEQ CTRL */ + /* set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. */ + rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF); + /* fixed USB interface interference issue */ + rtl_write_byte(rtlpriv, 0xfe40, 0xe0); + rtl_write_byte(rtlpriv, 0xfe41, 0x8d); + rtl_write_byte(rtlpriv, 0xfe42, 0x80); + rtlusb->reg_bcn_ctrl_val = 0x18; + rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlusb->reg_bcn_ctrl_val); +} + +static void _InitPABias(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 pa_setting; + + /* FIXED PA current issue */ + pa_setting = efuse_read_1byte(hw, 0x1FA); + if (!(pa_setting & BIT(0))) { + rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0x0F406); + rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0x4F406); + rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0x8F406); + rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0xCF406); + } + if (!(pa_setting & BIT(1)) && IS_NORMAL_CHIP(rtlhal->version) && + IS_92C_SERIAL(rtlhal->version)) { + rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0x0F406); + rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0x4F406); + rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0x8F406); + rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0xCF406); + } + if (!(pa_setting & BIT(4))) { + pa_setting = rtl_read_byte(rtlpriv, 0x16); + pa_setting &= 0x0F; + rtl_write_byte(rtlpriv, 0x16, pa_setting | 0x90); + } +} + +static void _InitAntenna_Selection(struct ieee80211_hw *hw) +{ +#ifdef CONFIG_ANTENNA_DIVERSITY + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (pHalData->AntDivCfg == 0) + return; + + if (rtlphy->rf_type == RF_1T1R) { + rtl_write_dword(rtlpriv, REG_LEDCFG0, + rtl_read_dword(rtlpriv, + REG_LEDCFG0)|BIT(23)); + rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); + if (rtl_get_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300) == + Antenna_A) + pHalData->CurAntenna = Antenna_A; + else + pHalData->CurAntenna = Antenna_B; + } +#endif +} + +static void _dump_registers(struct ieee80211_hw *hw) +{ +} + +static void _update_mac_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + mac->rx_conf = rtl_read_dword(rtlpriv, REG_RCR); + mac->rx_mgt_filter = rtl_read_word(rtlpriv, REG_RXFLTMAP0); + mac->rx_ctrl_filter = rtl_read_word(rtlpriv, REG_RXFLTMAP1); + mac->rx_data_filter = rtl_read_word(rtlpriv, REG_RXFLTMAP2); +} + +int rtl92cu_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + int err = 0; + static bool iqk_initialized; + + rtlhal->hw_type = HARDWARE_TYPE_RTL8192CU; + err = _rtl92cu_init_mac(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("init mac failed!\n")); + return err; + } + err = rtl92c_download_fw(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("Failed to download FW. Init HW without FW now..\n")); + err = 1; + rtlhal->fw_ready = false; + return err; + } else { + rtlhal->fw_ready = true; + } + rtlhal->last_hmeboxnum = 0; /* h2c */ + _rtl92cu_phy_param_tab_init(hw); + rtl92c_phy_mac_config(hw); + rtl92c_phy_bb_config(hw); + rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; + rtl92c_phy_rf_config(hw); + if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && + !IS_92C_SERIAL(rtlhal->version)) { + rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, 0x30255); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G2, MASKDWORD, 0x50a00); + } + rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, + RF_CHNLBW, RFREG_OFFSET_MASK); + rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, + RF_CHNLBW, RFREG_OFFSET_MASK); + rtl92c_bb_block_on(hw); + rtl_cam_reset_all_entry(hw); + rtl92cu_enable_hw_security_config(hw); + ppsc->rfpwr_state = ERFON; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); + if (ppsc->rfpwr_state == ERFON) { + rtl92c_phy_set_rfpath_switch(hw, 1); + if (iqk_initialized) { + rtl92c_phy_iq_calibrate(hw, false); + } else { + rtl92c_phy_iq_calibrate(hw, false); + iqk_initialized = true; + } + rtl92c_dm_check_txpower_tracking(hw); + rtl92c_phy_lc_calibrate(hw); + } + _rtl92cu_hw_configure(hw); + _InitPABias(hw); + _InitAntenna_Selection(hw); + _update_mac_setting(hw); + rtl92c_dm_init(hw); + _dump_registers(hw); + return err; +} + +static void _DisableRFAFEAndResetBB(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); +/************************************** +a. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue +b. RF path 0 offset 0x00 = 0x00 disable RF +c. APSD_CTRL 0x600[7:0] = 0x40 +d. SYS_FUNC_EN 0x02[7:0] = 0x16 reset BB state machine +e. SYS_FUNC_EN 0x02[7:0] = 0x14 reset BB state machine +***************************************/ + u8 eRFPath = 0, value8 = 0; + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + rtl_set_rfreg(hw, (enum radio_path)eRFPath, 0x0, MASKBYTE0, 0x0); + + value8 |= APSDOFF; + rtl_write_byte(rtlpriv, REG_APSD_CTRL, value8); /*0x40*/ + value8 = 0; + value8 |= (FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, value8);/*0x16*/ + value8 &= (~FEN_BB_GLB_RSTn); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, value8); /*0x14*/ +} + +static void _ResetDigitalProcedure1(struct ieee80211_hw *hw, bool bWithoutHWSM) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (rtlhal->fw_version <= 0x20) { + /***************************** + f. MCUFWDL 0x80[7:0]=0 reset MCU ready status + g. SYS_FUNC_EN 0x02[10]= 0 reset MCU reg, (8051 reset) + h. SYS_FUNC_EN 0x02[15-12]= 5 reset MAC reg, DCORE + i. SYS_FUNC_EN 0x02[10]= 1 enable MCU reg, (8051 enable) + ******************************/ + u16 valu16 = 0; + + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); + valu16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (valu16 & + (~FEN_CPUEN))); /* reset MCU ,8051 */ + valu16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN)&0x0FFF; + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (valu16 | + (FEN_HWPDN|FEN_ELDR))); /* reset MAC */ + valu16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (valu16 | + FEN_CPUEN)); /* enable MCU ,8051 */ + } else { + u8 retry_cnts = 0; + + /* IF fw in RAM code, do reset */ + if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(1)) { + /* reset MCU ready status */ + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); + if (rtlhal->fw_ready) { + /* 8051 reset by self */ + rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20); + while ((retry_cnts++ < 100) && + (FEN_CPUEN & rtl_read_word(rtlpriv, + REG_SYS_FUNC_EN))) { + udelay(50); + } + if (retry_cnts >= 100) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("#####=> 8051 reset failed!.." + ".......................\n");); + /* if 8051 reset fail, reset MAC. */ + rtl_write_byte(rtlpriv, + REG_SYS_FUNC_EN + 1, + 0x50); + udelay(100); + } + } + } + /* Reset MAC and Enable 8051 */ + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x54); + rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); + } + if (bWithoutHWSM) { + /***************************** + Without HW auto state machine + g.SYS_CLKR 0x08[15:0] = 0x30A3 disable MAC clock + h.AFE_PLL_CTRL 0x28[7:0] = 0x80 disable AFE PLL + i.AFE_XTAL_CTRL 0x24[15:0] = 0x880F gated AFE DIG_CLOCK + j.SYS_ISu_CTRL 0x00[7:0] = 0xF9 isolated digital to PON + ******************************/ + rtl_write_word(rtlpriv, REG_SYS_CLKR, 0x70A3); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80); + rtl_write_word(rtlpriv, REG_AFE_XTAL_CTRL, 0x880F); + rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, 0xF9); + } +} + +static void _ResetDigitalProcedure2(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); +/***************************** +k. SYS_FUNC_EN 0x03[7:0] = 0x44 disable ELDR runction +l. SYS_CLKR 0x08[15:0] = 0x3083 disable ELDR clock +m. SYS_ISO_CTRL 0x01[7:0] = 0x83 isolated ELDR to PON +******************************/ + rtl_write_word(rtlpriv, REG_SYS_CLKR, 0x70A3); + rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL+1, 0x82); +} + +static void _DisableGPIO(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); +/*************************************** +j. GPIO_PIN_CTRL 0x44[31:0]=0x000 +k. Value = GPIO_PIN_CTRL[7:0] +l. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); write ext PIN level +m. GPIO_MUXCFG 0x42 [15:0] = 0x0780 +n. LEDCFG 0x4C[15:0] = 0x8080 +***************************************/ + u8 value8; + u16 value16; + u32 value32; + + /* 1. Disable GPIO[7:0] */ + rtl_write_word(rtlpriv, REG_GPIO_PIN_CTRL+2, 0x0000); + value32 = rtl_read_dword(rtlpriv, REG_GPIO_PIN_CTRL) & 0xFFFF00FF; + value8 = (u8) (value32&0x000000FF); + value32 |= ((value8<<8) | 0x00FF0000); + rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, value32); + /* 2. Disable GPIO[10:8] */ + rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG+3, 0x00); + value16 = rtl_read_word(rtlpriv, REG_GPIO_MUXCFG+2) & 0xFF0F; + value8 = (u8) (value16&0x000F); + value16 |= ((value8<<4) | 0x0780); + rtl_write_word(rtlpriv, REG_GPIO_PIN_CTRL+2, value16); + /* 3. Disable LED0 & 1 */ + rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080); +} + +static void _DisableAnalog(struct ieee80211_hw *hw, bool bWithoutHWSM) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 value16 = 0; + u8 value8 = 0; + + if (bWithoutHWSM) { + /***************************** + n. LDOA15_CTRL 0x20[7:0] = 0x04 disable A15 power + o. LDOV12D_CTRL 0x21[7:0] = 0x54 disable digital core power + r. When driver call disable, the ASIC will turn off remaining + clock automatically + ******************************/ + rtl_write_byte(rtlpriv, REG_LDOA15_CTRL, 0x04); + value8 = rtl_read_byte(rtlpriv, REG_LDOV12D_CTRL); + value8 &= (~LDV12_EN); + rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, value8); + } + +/***************************** +h. SPS0_CTRL 0x11[7:0] = 0x23 enter PFM mode +i. APS_FSMCO 0x04[15:0] = 0x4802 set USB suspend +******************************/ + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); + value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN); + rtl_write_word(rtlpriv, REG_APS_FSMCO, (u16)value16); + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0E); +} + +static void _CardDisableHWSM(struct ieee80211_hw *hw) +{ + /* ==== RF Off Sequence ==== */ + _DisableRFAFEAndResetBB(hw); + /* ==== Reset digital sequence ====== */ + _ResetDigitalProcedure1(hw, false); + /* ==== Pull GPIO PIN to balance level and LED control ====== */ + _DisableGPIO(hw); + /* ==== Disable analog sequence === */ + _DisableAnalog(hw, false); +} + +static void _CardDisableWithoutHWSM(struct ieee80211_hw *hw) +{ + /*==== RF Off Sequence ==== */ + _DisableRFAFEAndResetBB(hw); + /* ==== Reset digital sequence ====== */ + _ResetDigitalProcedure1(hw, true); + /* ==== Pull GPIO PIN to balance level and LED control ====== */ + _DisableGPIO(hw); + /* ==== Reset digital sequence ====== */ + _ResetDigitalProcedure2(hw); + /* ==== Disable analog sequence === */ + _DisableAnalog(hw, true); +} + +static void _rtl92cu_set_bcn_ctrl_reg(struct ieee80211_hw *hw, + u8 set_bits, u8 clear_bits) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + rtlusb->reg_bcn_ctrl_val |= set_bits; + rtlusb->reg_bcn_ctrl_val &= ~clear_bits; + rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlusb->reg_bcn_ctrl_val); +} + +static void _rtl92cu_stop_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u8 tmp1byte = 0; + if (IS_NORMAL_CHIP(rtlhal->version)) { + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, + tmp1byte & (~BIT(6))); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); + } else { + rtl_write_byte(rtlpriv, REG_TXPAUSE, + rtl_read_byte(rtlpriv, REG_TXPAUSE) | BIT(6)); + } +} + +static void _rtl92cu_resume_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + u8 tmp1byte = 0; + + if (IS_NORMAL_CHIP(rtlhal->version)) { + tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, + tmp1byte | BIT(6)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); + tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); + tmp1byte |= BIT(0); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); + } else { + rtl_write_byte(rtlpriv, REG_TXPAUSE, + rtl_read_byte(rtlpriv, REG_TXPAUSE) & (~BIT(6))); + } +} + +static void _rtl92cu_enable_bcn_sub_func(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + if (IS_NORMAL_CHIP(rtlhal->version)) + _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(1)); + else + _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4)); +} + +static void _rtl92cu_disable_bcn_sub_func(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + if (IS_NORMAL_CHIP(rtlhal->version)) + _rtl92cu_set_bcn_ctrl_reg(hw, BIT(1), 0); + else + _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); +} + +static int _rtl92cu_set_media_status(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bt_msr = rtl_read_byte(rtlpriv, MSR); + enum led_ctl_mode ledaction = LED_CTL_NO_LINK; + + bt_msr &= 0xfc; + rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xFF); + if (type == NL80211_IFTYPE_UNSPECIFIED || type == + NL80211_IFTYPE_STATION) { + _rtl92cu_stop_tx_beacon(hw); + _rtl92cu_enable_bcn_sub_func(hw); + } else if (type == NL80211_IFTYPE_ADHOC || type == NL80211_IFTYPE_AP) { + _rtl92cu_resume_tx_beacon(hw); + _rtl92cu_disable_bcn_sub_func(hw); + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("Set HW_VAR_MEDIA_" + "STATUS:No such media status(%x).\n", type)); + } + switch (type) { + case NL80211_IFTYPE_UNSPECIFIED: + bt_msr |= MSR_NOLINK; + ledaction = LED_CTL_LINK; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Set Network type to NO LINK!\n")); + break; + case NL80211_IFTYPE_ADHOC: + bt_msr |= MSR_ADHOC; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Set Network type to Ad Hoc!\n")); + break; + case NL80211_IFTYPE_STATION: + bt_msr |= MSR_INFRA; + ledaction = LED_CTL_LINK; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Set Network type to STA!\n")); + break; + case NL80211_IFTYPE_AP: + bt_msr |= MSR_AP; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Set Network type to AP!\n")); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Network type %d not support!\n", type)); + goto error_out; + } + rtl_write_byte(rtlpriv, (MSR), bt_msr); + rtlpriv->cfg->ops->led_control(hw, ledaction); + if ((bt_msr & 0xfc) == MSR_AP) + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); + else + rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); + return 0; +error_out: + return 1; +} + +void rtl92cu_card_disable(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + enum nl80211_iftype opmode; + + mac->link_state = MAC80211_NOLINK; + opmode = NL80211_IFTYPE_UNSPECIFIED; + _rtl92cu_set_media_status(hw, opmode); + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + if (rtlusb->disableHWSM) + _CardDisableHWSM(hw); + else + _CardDisableWithoutHWSM(hw); +} + +void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) +{ + /* dummy routine needed for callback from rtl_op_configure_filter() */ +} + +/*========================================================================== */ + +static void _rtl92cu_set_check_bssid(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u8 filterout_non_associated_bssid = false; + + switch (type) { + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_STATION: + filterout_non_associated_bssid = true; + break; + case NL80211_IFTYPE_UNSPECIFIED: + case NL80211_IFTYPE_AP: + default: + break; + } + if (filterout_non_associated_bssid == true) { + if (IS_NORMAL_CHIP(rtlhal->version)) { + switch (rtlphy->current_io_type) { + case IO_CMD_RESUME_DM_BY_SCAN: + reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_RCR, (u8 *)(®_rcr)); + /* enable update TSF */ + _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4)); + break; + case IO_CMD_PAUSE_DM_BY_SCAN: + reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_RCR, (u8 *)(®_rcr)); + /* disable update TSF */ + _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); + break; + } + } else { + reg_rcr |= (RCR_CBSSID); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *)(®_rcr)); + _rtl92cu_set_bcn_ctrl_reg(hw, 0, (BIT(4)|BIT(5))); + } + } else if (filterout_non_associated_bssid == false) { + if (IS_NORMAL_CHIP(rtlhal->version)) { + reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *)(®_rcr)); + _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); + } else { + reg_rcr &= (~RCR_CBSSID); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *)(®_rcr)); + _rtl92cu_set_bcn_ctrl_reg(hw, (BIT(4)|BIT(5)), 0); + } + } +} + +int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) +{ + if (_rtl92cu_set_media_status(hw, type)) + return -EOPNOTSUPP; + _rtl92cu_set_check_bssid(hw, type); + return 0; +} + +static void _InitBeaconParameters(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + rtl_write_word(rtlpriv, REG_BCN_CTRL, 0x1010); + + /* TODO: Remove these magic number */ + rtl_write_word(rtlpriv, REG_TBTT_PROHIBIT, 0x6404); + rtl_write_byte(rtlpriv, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME); + rtl_write_byte(rtlpriv, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME); + /* Change beacon AIFS to the largest number + * beacause test chip does not contension before sending beacon. */ + if (IS_NORMAL_CHIP(rtlhal->version)) + rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660F); + else + rtl_write_word(rtlpriv, REG_BCNTCFG, 0x66FF); +} + +static void _beacon_function_enable(struct ieee80211_hw *hw, bool Enable, + bool Linked) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + _rtl92cu_set_bcn_ctrl_reg(hw, (BIT(4) | BIT(3) | BIT(1)), 0x00); + rtl_write_byte(rtlpriv, REG_RD_CTRL+1, 0x6F); +} + +void rtl92cu_set_beacon_related_registers(struct ieee80211_hw *hw) +{ + + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval, atim_window; + u32 value32; + + bcn_interval = mac->beacon_interval; + atim_window = 2; /*FIX MERGE */ + rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); + _InitBeaconParameters(hw); + rtl_write_byte(rtlpriv, REG_SLOT, 0x09); + /* + * Force beacon frame transmission even after receiving beacon frame + * from other ad hoc STA + * + * + * Reset TSF Timer to zero, added by Roger. 2008.06.24 + */ + value32 = rtl_read_dword(rtlpriv, REG_TCR); + value32 &= ~TSFRST; + rtl_write_dword(rtlpriv, REG_TCR, value32); + value32 |= TSFRST; + rtl_write_dword(rtlpriv, REG_TCR, value32); + RT_TRACE(rtlpriv, COMP_INIT|COMP_BEACON, DBG_LOUD, + ("SetBeaconRelatedRegisters8192CUsb(): Set TCR(%x)\n", + value32)); + /* TODO: Modify later (Find the right parameters) + * NOTE: Fix test chip's bug (about contention windows's randomness) */ + if ((mac->opmode == NL80211_IFTYPE_ADHOC) || + (mac->opmode == NL80211_IFTYPE_AP)) { + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x50); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x50); + } + _beacon_function_enable(hw, true, true); +} + +void rtl92cu_set_beacon_interval(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval = mac->beacon_interval; + + RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, + ("beacon_interval:%d\n", bcn_interval)); + rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); +} + +void rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr) +{ +} + +void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + switch (variable) { + case HW_VAR_RCR: + *((u32 *)(val)) = mac->rx_conf; + break; + case HW_VAR_RF_STATE: + *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; + break; + case HW_VAR_FWLPS_RF_ON:{ + enum rf_pwrstate rfState; + u32 val_rcr; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, + (u8 *)(&rfState)); + if (rfState == ERFOFF) { + *((bool *) (val)) = true; + } else { + val_rcr = rtl_read_dword(rtlpriv, REG_RCR); + val_rcr &= 0x00070000; + if (val_rcr) + *((bool *) (val)) = false; + else + *((bool *) (val)) = true; + } + break; + } + case HW_VAR_FW_PSMODE_STATUS: + *((bool *) (val)) = ppsc->fw_current_inpsmode; + break; + case HW_VAR_CORRECT_TSF:{ + u64 tsf; + u32 *ptsf_low = (u32 *)&tsf; + u32 *ptsf_high = ((u32 *)&tsf) + 1; + + *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); + *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); + *((u64 *)(val)) = tsf; + break; + } + case HW_VAR_MGT_FILTER: + *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP0); + break; + case HW_VAR_CTRL_FILTER: + *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP1); + break; + case HW_VAR_DATA_FILTER: + *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP2); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } +} + +void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + enum wireless_mode wirelessmode = mac->mode; + u8 idx = 0; + + switch (variable) { + case HW_VAR_ETHER_ADDR:{ + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_MACID + idx), + val[idx]); + } + break; + } + case HW_VAR_BASIC_RATE:{ + u16 rate_cfg = ((u16 *) val)[0]; + u8 rate_index = 0; + + rate_cfg &= 0x15f; + /* TODO */ + /* if (mac->current_network.vender == HT_IOT_PEER_CISCO + * && ((rate_cfg & 0x150) == 0)) { + * rate_cfg |= 0x010; + * } */ + rate_cfg |= 0x01; + rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff); + rtl_write_byte(rtlpriv, REG_RRSR + 1, + (rate_cfg >> 8) & 0xff); + while (rate_cfg > 0x1) { + rate_cfg >>= 1; + rate_index++; + } + rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, + rate_index); + break; + } + case HW_VAR_BSSID:{ + for (idx = 0; idx < ETH_ALEN; idx++) { + rtl_write_byte(rtlpriv, (REG_BSSID + idx), + val[idx]); + } + break; + } + case HW_VAR_SIFS:{ + rtl_write_byte(rtlpriv, REG_SIFS_CCK + 1, val[0]); + rtl_write_byte(rtlpriv, REG_SIFS_OFDM + 1, val[1]); + rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); + rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); + rtl_write_byte(rtlpriv, REG_R2T_SIFS+1, val[0]); + rtl_write_byte(rtlpriv, REG_T2T_SIFS+1, val[0]); + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("HW_VAR_SIFS\n")); + break; + } + case HW_VAR_SLOT_TIME:{ + u8 e_aci; + u8 QOS_MODE = 1; + + rtl_write_byte(rtlpriv, REG_SLOT, val[0]); + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("HW_VAR_SLOT_TIME %x\n", val[0])); + if (QOS_MODE) { + for (e_aci = 0; e_aci < AC_MAX; e_aci++) + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AC_PARAM, + (u8 *)(&e_aci)); + } else { + u8 sifstime = 0; + u8 u1bAIFS; + + if (IS_WIRELESS_MODE_A(wirelessmode) || + IS_WIRELESS_MODE_N_24G(wirelessmode) || + IS_WIRELESS_MODE_N_5G(wirelessmode)) + sifstime = 16; + else + sifstime = 10; + u1bAIFS = sifstime + (2 * val[0]); + rtl_write_byte(rtlpriv, REG_EDCA_VO_PARAM, + u1bAIFS); + rtl_write_byte(rtlpriv, REG_EDCA_VI_PARAM, + u1bAIFS); + rtl_write_byte(rtlpriv, REG_EDCA_BE_PARAM, + u1bAIFS); + rtl_write_byte(rtlpriv, REG_EDCA_BK_PARAM, + u1bAIFS); + } + break; + } + case HW_VAR_ACK_PREAMBLE:{ + u8 reg_tmp; + u8 short_preamble = (bool) (*(u8 *) val); + reg_tmp = 0; + if (short_preamble) + reg_tmp |= 0x80; + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp); + break; + } + case HW_VAR_AMPDU_MIN_SPACE:{ + u8 min_spacing_to_set; + u8 sec_min_space; + + min_spacing_to_set = *((u8 *) val); + if (min_spacing_to_set <= 7) { + switch (rtlpriv->sec.pairwise_enc_algorithm) { + case NO_ENCRYPTION: + case AESCCMP_ENCRYPTION: + sec_min_space = 0; + break; + case WEP40_ENCRYPTION: + case WEP104_ENCRYPTION: + case TKIP_ENCRYPTION: + sec_min_space = 6; + break; + default: + sec_min_space = 7; + break; + } + if (min_spacing_to_set < sec_min_space) + min_spacing_to_set = sec_min_space; + mac->min_space_cfg = ((mac->min_space_cfg & + 0xf8) | + min_spacing_to_set); + *val = min_spacing_to_set; + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg)); + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + } + break; + } + case HW_VAR_SHORTGI_DENSITY:{ + u8 density_to_set; + + density_to_set = *((u8 *) val); + density_to_set &= 0x1f; + mac->min_space_cfg &= 0x07; + mac->min_space_cfg |= (density_to_set << 3); + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg)); + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, + mac->min_space_cfg); + break; + } + case HW_VAR_AMPDU_FACTOR:{ + u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9}; + u8 factor_toset; + u8 *p_regtoset = NULL; + u8 index = 0; + + p_regtoset = regtoset_normal; + factor_toset = *((u8 *) val); + if (factor_toset <= 3) { + factor_toset = (1 << (factor_toset + 2)); + if (factor_toset > 0xf) + factor_toset = 0xf; + for (index = 0; index < 4; index++) { + if ((p_regtoset[index] & 0xf0) > + (factor_toset << 4)) + p_regtoset[index] = + (p_regtoset[index] & 0x0f) + | (factor_toset << 4); + if ((p_regtoset[index] & 0x0f) > + factor_toset) + p_regtoset[index] = + (p_regtoset[index] & 0xf0) + | (factor_toset); + rtl_write_byte(rtlpriv, + (REG_AGGLEN_LMT + index), + p_regtoset[index]); + } + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset)); + } + break; + } + case HW_VAR_AC_PARAM:{ + u8 e_aci = *((u8 *) val); + u32 u4b_ac_param; + u16 cw_min = le16_to_cpu(mac->ac[e_aci].cw_min); + u16 cw_max = le16_to_cpu(mac->ac[e_aci].cw_max); + u16 tx_op = le16_to_cpu(mac->ac[e_aci].tx_op); + + u4b_ac_param = (u32) mac->ac[e_aci].aifs; + u4b_ac_param |= (u32) ((cw_min & 0xF) << + AC_PARAM_ECW_MIN_OFFSET); + u4b_ac_param |= (u32) ((cw_max & 0xF) << + AC_PARAM_ECW_MAX_OFFSET); + u4b_ac_param |= (u32) tx_op << AC_PARAM_TXOP_OFFSET; + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, + ("queue:%x, ac_param:%x\n", e_aci, + u4b_ac_param)); + switch (e_aci) { + case AC1_BK: + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, + u4b_ac_param); + break; + case AC0_BE: + rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, + u4b_ac_param); + break; + case AC2_VI: + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, + u4b_ac_param); + break; + case AC3_VO: + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, + u4b_ac_param); + break; + default: + RT_ASSERT(false, ("SetHwReg8185(): invalid" + " aci: %d !\n", e_aci)); + break; + } + if (rtlusb->acm_method != eAcmWay2_SW) + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_ACM_CTRL, (u8 *)(&e_aci)); + break; + } + case HW_VAR_ACM_CTRL:{ + u8 e_aci = *((u8 *) val); + union aci_aifsn *p_aci_aifsn = (union aci_aifsn *) + (&(mac->ac[0].aifs)); + u8 acm = p_aci_aifsn->f.acm; + u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); + + acm_ctrl = + acm_ctrl | ((rtlusb->acm_method == 2) ? 0x0 : 0x1); + if (acm) { + switch (e_aci) { + case AC0_BE: + acm_ctrl |= AcmHw_BeqEn; + break; + case AC2_VI: + acm_ctrl |= AcmHw_ViqEn; + break; + case AC3_VO: + acm_ctrl |= AcmHw_VoqEn; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("HW_VAR_ACM_CTRL acm set " + "failed: eACI is %d\n", acm)); + break; + } + } else { + switch (e_aci) { + case AC0_BE: + acm_ctrl &= (~AcmHw_BeqEn); + break; + case AC2_VI: + acm_ctrl &= (~AcmHw_ViqEn); + break; + case AC3_VO: + acm_ctrl &= (~AcmHw_BeqEn); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + } + RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, + ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] " + "Write 0x%X\n", acm_ctrl)); + rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); + break; + } + case HW_VAR_RCR:{ + rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]); + mac->rx_conf = ((u32 *) (val))[0]; + RT_TRACE(rtlpriv, COMP_RECV, DBG_DMESG, + ("### Set RCR(0x%08x) ###\n", mac->rx_conf)); + break; + } + case HW_VAR_RETRY_LIMIT:{ + u8 retry_limit = ((u8 *) (val))[0]; + + rtl_write_word(rtlpriv, REG_RL, + retry_limit << RETRY_LIMIT_SHORT_SHIFT | + retry_limit << RETRY_LIMIT_LONG_SHIFT); + RT_TRACE(rtlpriv, COMP_MLME, DBG_DMESG, ("Set HW_VAR_R" + "ETRY_LIMIT(0x%08x)\n", retry_limit)); + break; + } + case HW_VAR_DUAL_TSF_RST: + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); + break; + case HW_VAR_EFUSE_BYTES: + rtlefuse->efuse_usedbytes = *((u16 *) val); + break; + case HW_VAR_EFUSE_USAGE: + rtlefuse->efuse_usedpercentage = *((u8 *) val); + break; + case HW_VAR_IO_CMD: + rtl92c_phy_set_io_cmd(hw, (*(enum io_type *)val)); + break; + case HW_VAR_WPA_CONFIG: + rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val)); + break; + case HW_VAR_SET_RPWM:{ + u8 rpwm_val = rtl_read_byte(rtlpriv, REG_USB_HRPWM); + + if (rpwm_val & BIT(7)) + rtl_write_byte(rtlpriv, REG_USB_HRPWM, + (*(u8 *)val)); + else + rtl_write_byte(rtlpriv, REG_USB_HRPWM, + ((*(u8 *)val) | BIT(7))); + break; + } + case HW_VAR_H2C_FW_PWRMODE:{ + u8 psmode = (*(u8 *) val); + + if ((psmode != FW_PS_ACTIVE_MODE) && + (!IS_92C_SERIAL(rtlhal->version))) + rtl92c_dm_rf_saving(hw, true); + rtl92c_set_fw_pwrmode_cmd(hw, (*(u8 *) val)); + break; + } + case HW_VAR_FW_PSMODE_STATUS: + ppsc->fw_current_inpsmode = *((bool *) val); + break; + case HW_VAR_H2C_FW_JOINBSSRPT:{ + u8 mstatus = (*(u8 *) val); + u8 tmp_reg422; + bool recover = false; + + if (mstatus == RT_MEDIA_CONNECT) { + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_AID, NULL); + rtl_write_byte(rtlpriv, REG_CR + 1, 0x03); + _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(3)); + _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); + tmp_reg422 = rtl_read_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2); + if (tmp_reg422 & BIT(6)) + recover = true; + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, + tmp_reg422 & (~BIT(6))); + rtl92c_set_fw_rsvdpagepkt(hw, 0); + _rtl92cu_set_bcn_ctrl_reg(hw, BIT(3), 0); + _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4)); + if (recover) + rtl_write_byte(rtlpriv, + REG_FWHW_TXQ_CTRL + 2, + tmp_reg422 | BIT(6)); + rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); + } + rtl92c_set_fw_joinbss_report_cmd(hw, (*(u8 *) val)); + break; + } + case HW_VAR_AID:{ + u16 u2btmp; + + u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); + u2btmp &= 0xC000; + rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, + (u2btmp | mac->assoc_id)); + break; + } + case HW_VAR_CORRECT_TSF:{ + u8 btype_ibss = ((u8 *) (val))[0]; + + if (btype_ibss == true) + _rtl92cu_stop_tx_beacon(hw); + _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(3)); + rtl_write_dword(rtlpriv, REG_TSFTR, (u32)(mac->tsf & + 0xffffffff)); + rtl_write_dword(rtlpriv, REG_TSFTR + 4, + (u32)((mac->tsf >> 32) & 0xffffffff)); + _rtl92cu_set_bcn_ctrl_reg(hw, BIT(3), 0); + if (btype_ibss == true) + _rtl92cu_resume_tx_beacon(hw); + break; + } + case HW_VAR_MGT_FILTER: + rtl_write_word(rtlpriv, REG_RXFLTMAP0, *(u16 *)val); + break; + case HW_VAR_CTRL_FILTER: + rtl_write_word(rtlpriv, REG_RXFLTMAP1, *(u16 *)val); + break; + case HW_VAR_DATA_FILTER: + rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *)val); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " + "not process\n")); + break; + } +} + +void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u32 ratr_value = (u32) mac->basic_rates; + u8 *mcsrate = mac->mcs; + u8 ratr_index = 0; + u8 nmode = mac->ht_enable; + u8 mimo_ps = 1; + u16 shortgi_rate = 0; + u32 tmp_ratr_value = 0; + u8 curtxbw_40mhz = mac->bw_40; + u8 curshortgi_40mhz = mac->sgi_40; + u8 curshortgi_20mhz = mac->sgi_20; + enum wireless_mode wirelessmode = mac->mode; + + ratr_value |= ((*(u16 *) (mcsrate))) << 12; + switch (wirelessmode) { + case WIRELESS_MODE_B: + if (ratr_value & 0x0000000c) + ratr_value &= 0x0000000d; + else + ratr_value &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_value &= 0x00000FF5; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + nmode = 1; + if (mimo_ps == 0) { + ratr_value &= 0x0007F005; + } else { + u32 ratr_mask; + + if (get_rf_type(rtlphy) == RF_1T2R || + get_rf_type(rtlphy) == RF_1T1R) + ratr_mask = 0x000ff005; + else + ratr_mask = 0x0f0ff005; + if (curtxbw_40mhz) + ratr_mask |= 0x00000010; + ratr_value &= ratr_mask; + } + break; + default: + if (rtlphy->rf_type == RF_1T2R) + ratr_value &= 0x000ff0ff; + else + ratr_value &= 0x0f0ff0ff; + break; + } + ratr_value &= 0x0FFFFFFF; + if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) || + (!curtxbw_40mhz && curshortgi_20mhz))) { + ratr_value |= 0x10000000; + tmp_ratr_value = (ratr_value >> 12); + for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { + if ((1 << shortgi_rate) & tmp_ratr_value) + break; + } + shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | + (shortgi_rate << 4) | (shortgi_rate); + } + rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("%x\n", rtl_read_dword(rtlpriv, + REG_ARFR0))); +} + +void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u32 ratr_bitmap = (u32) mac->basic_rates; + u8 *p_mcsrate = mac->mcs; + u8 ratr_index = 0; + u8 curtxbw_40mhz = mac->bw_40; + u8 curshortgi_40mhz = mac->sgi_40; + u8 curshortgi_20mhz = mac->sgi_20; + enum wireless_mode wirelessmode = mac->mode; + bool shortgi = false; + u8 rate_mask[5]; + u8 macid = 0; + u8 mimops = 1; + + ratr_bitmap |= (p_mcsrate[1] << 20) | (p_mcsrate[0] << 12); + switch (wirelessmode) { + case WIRELESS_MODE_B: + ratr_index = RATR_INX_WIRELESS_B; + if (ratr_bitmap & 0x0000000c) + ratr_bitmap &= 0x0000000d; + else + ratr_bitmap &= 0x0000000f; + break; + case WIRELESS_MODE_G: + ratr_index = RATR_INX_WIRELESS_GB; + if (rssi_level == 1) + ratr_bitmap &= 0x00000f00; + else if (rssi_level == 2) + ratr_bitmap &= 0x00000ff0; + else + ratr_bitmap &= 0x00000ff5; + break; + case WIRELESS_MODE_A: + ratr_index = RATR_INX_WIRELESS_A; + ratr_bitmap &= 0x00000ff0; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + ratr_index = RATR_INX_WIRELESS_NGB; + if (mimops == 0) { + if (rssi_level == 1) + ratr_bitmap &= 0x00070000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0007f000; + else + ratr_bitmap &= 0x0007f005; + } else { + if (rtlphy->rf_type == RF_1T2R || + rtlphy->rf_type == RF_1T1R) { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x000f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x000ff000; + else + ratr_bitmap &= 0x000ff005; + } + } else { + if (curtxbw_40mhz) { + if (rssi_level == 1) + ratr_bitmap &= 0x0f0f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f0ff000; + else + ratr_bitmap &= 0x0f0ff015; + } else { + if (rssi_level == 1) + ratr_bitmap &= 0x0f0f0000; + else if (rssi_level == 2) + ratr_bitmap &= 0x0f0ff000; + else + ratr_bitmap &= 0x0f0ff005; + } + } + } + if ((curtxbw_40mhz && curshortgi_40mhz) || + (!curtxbw_40mhz && curshortgi_20mhz)) { + if (macid == 0) + shortgi = true; + else if (macid == 1) + shortgi = false; + } + break; + default: + ratr_index = RATR_INX_WIRELESS_NGB; + if (rtlphy->rf_type == RF_1T2R) + ratr_bitmap &= 0x000ff0ff; + else + ratr_bitmap &= 0x0f0ff0ff; + break; + } + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("ratr_bitmap :%x\n", + ratr_bitmap)); + *(u32 *)&rate_mask = ((ratr_bitmap & 0x0fffffff) | + ratr_index << 28); + rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, " + "ratr_val:%x, %x:%x:%x:%x:%x\n", + ratr_index, ratr_bitmap, + rate_mask[0], rate_mask[1], + rate_mask[2], rate_mask[3], + rate_mask[4])); + rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); +} + +void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 sifs_timer; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, + (u8 *)&mac->slot_time); + if (!mac->ht_enable) + sifs_timer = 0x0a0a; + else + sifs_timer = 0x0e0e; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); +} + +bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate; + u8 u1tmp = 0; + bool actuallyset = false; + unsigned long flag = 0; + /* to do - usb autosuspend */ + u8 usb_autosuspend = 0; + + if (ppsc->swrf_processing) + return false; + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + if (ppsc->rfchange_inprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + return false; + } else { + ppsc->rfchange_inprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } + cur_rfstate = ppsc->rfpwr_state; + if (usb_autosuspend) { + /* to do................... */ + } else { + if (ppsc->pwrdown_mode) { + u1tmp = rtl_read_byte(rtlpriv, REG_HSISR); + e_rfpowerstate_toset = (u1tmp & BIT(7)) ? + ERFOFF : ERFON; + RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, + ("pwrdown, 0x5c(BIT7)=%02x\n", u1tmp)); + } else { + rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, + rtl_read_byte(rtlpriv, + REG_MAC_PINMUX_CFG) & ~(BIT(3))); + u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); + e_rfpowerstate_toset = (u1tmp & BIT(3)) ? + ERFON : ERFOFF; + RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, + ("GPIO_IN=%02x\n", u1tmp)); + } + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("N-SS RF =%x\n", + e_rfpowerstate_toset)); + } + if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("GPIOChangeRF - HW " + "Radio ON, RF ON\n")); + ppsc->hwradiooff = false; + actuallyset = true; + } else if ((!ppsc->hwradiooff) && (e_rfpowerstate_toset == + ERFOFF)) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("GPIOChangeRF - HW" + " Radio OFF\n")); + ppsc->hwradiooff = true; + actuallyset = true; + } else { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD , + ("pHalData->bHwRadioOff and eRfPowerStateToSet do not" + " match: pHalData->bHwRadioOff %x, eRfPowerStateToSet " + "%x\n", ppsc->hwradiooff, e_rfpowerstate_toset)); + } + if (actuallyset) { + ppsc->hwradiooff = 1; + if (e_rfpowerstate_toset == ERFON) { + if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); + else if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_PCI_D3) + && RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3)) + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3); + } + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + /* For power down module, we need to enable register block + * contrl reg at 0x1c. Then enable power down control bit + * of register 0x04 BIT4 and BIT15 as 1. + */ + if (ppsc->pwrdown_mode && e_rfpowerstate_toset == ERFOFF) { + /* Enable register area 0x0-0xc. */ + rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0); + if (IS_HARDWARE_TYPE_8723U(rtlhal)) { + /* + * We should configure HW PDn source for WiFi + * ONLY, and then our HW will be set in + * power-down mode if PDn source from all + * functions are configured. + */ + u1tmp = rtl_read_byte(rtlpriv, + REG_MULTI_FUNC_CTRL); + rtl_write_byte(rtlpriv, REG_MULTI_FUNC_CTRL, + (u1tmp|WL_HWPDN_EN)); + } else { + rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x8812); + } + } + if (e_rfpowerstate_toset == ERFOFF) { + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); + else if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_PCI_D3) + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3); + } + } else if (e_rfpowerstate_toset == ERFOFF || cur_rfstate == ERFOFF) { + /* Enter D3 or ASPM after GPIO had been done. */ + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); + else if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_PCI_D3) + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3); + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } else { + spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); + ppsc->rfchange_inprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); + } + *valid = 1; + return !ppsc->hwradiooff; +} -- cgit v1.2.3 From 666e8457fae432ec292e0abc344f8684046fa605 Mon Sep 17 00:00:00 2001 From: George Date: Sat, 19 Feb 2011 16:29:27 -0600 Subject: rtlwifi: rtl8192cu: Add routine mac Add the routine rtlwifi/rtl8192cu/hw.c. Signed-off-by: George Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 1144 ++++++++++++++++++++++++++ 1 file changed, 1144 insertions(+) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/mac.c (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c new file mode 100644 index 000000000000..f8514cba17b6 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -0,0 +1,1144 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * +****************************************************************************/ +#include + +#include "../wifi.h" +#include "../pci.h" +#include "../usb.h" +#include "../ps.h" +#include "../cam.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" +#include "mac.h" +#include "trx.h" + +/* macro to shorten lines */ + +#define LINK_Q ui_link_quality +#define RX_EVM rx_evm_percentage +#define RX_SIGQ rx_mimo_signalquality + + +void rtl92c_read_chip_version(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + enum version_8192c chip_version = VERSION_UNKNOWN; + u32 value32; + + value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); + if (value32 & TRP_VAUX_EN) { + chip_version = (value32 & TYPE_ID) ? VERSION_TEST_CHIP_92C : + VERSION_TEST_CHIP_88C; + } else { + /* Normal mass production chip. */ + chip_version = NORMAL_CHIP; + chip_version |= ((value32 & TYPE_ID) ? CHIP_92C : 0); + chip_version |= ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0); + /* RTL8723 with BT function. */ + chip_version |= ((value32 & BT_FUNC) ? CHIP_8723 : 0); + if (IS_VENDOR_UMC(chip_version)) + chip_version |= ((value32 & CHIP_VER_RTL_MASK) ? + CHIP_VENDOR_UMC_B_CUT : 0); + if (IS_92C_SERIAL(chip_version)) { + value32 = rtl_read_dword(rtlpriv, REG_HPON_FSM); + chip_version |= ((CHIP_BONDING_IDENTIFIER(value32) == + CHIP_BONDING_92C_1T2R) ? CHIP_92C_1T2R : 0); + } else if (IS_8723_SERIES(chip_version)) { + value32 = rtl_read_dword(rtlpriv, REG_GPIO_OUTSTS); + chip_version |= ((value32 & RF_RL_ID) ? + CHIP_8723_DRV_REV : 0); + } + } + rtlhal->version = (enum version_8192c)chip_version; + switch (rtlhal->version) { + case VERSION_NORMAL_TSMC_CHIP_92C_1T2R: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_B_CHIP_92C.\n")); + break; + case VERSION_NORMAL_TSMC_CHIP_92C: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_92C.\n")); + break; + case VERSION_NORMAL_TSMC_CHIP_88C: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_88C.\n")); + break; + case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_NORMAL_UMC_CHIP_i" + "92C_1T2R_A_CUT.\n")); + break; + case VERSION_NORMAL_UMC_CHIP_92C_A_CUT: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_NORMAL_UMC_CHIP_" + "92C_A_CUT.\n")); + break; + case VERSION_NORMAL_UMC_CHIP_88C_A_CUT: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" + "_88C_A_CUT.\n")); + break; + case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" + "_92C_1T2R_B_CUT.\n")); + break; + case VERSION_NORMAL_UMC_CHIP_92C_B_CUT: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" + "_92C_B_CUT.\n")); + break; + case VERSION_NORMAL_UMC_CHIP_88C_B_CUT: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" + "_88C_B_CUT.\n")); + break; + case VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_NORMA_UMC_CHIP" + "_8723_1T1R_A_CUT.\n")); + break; + case VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_NORMA_UMC_CHIP" + "_8723_1T1R_B_CUT.\n")); + break; + case VERSION_TEST_CHIP_92C: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_TEST_CHIP_92C.\n")); + break; + case VERSION_TEST_CHIP_88C: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: VERSION_TEST_CHIP_88C.\n")); + break; + default: + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Chip Version ID: ???????????????.\n")); + break; + } + if (IS_92C_SERIAL(rtlhal->version)) + rtlphy->rf_type = + (IS_92C_1T2R(rtlhal->version)) ? RF_1T2R : RF_2T2R; + else + rtlphy->rf_type = RF_1T1R; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ? + "RF_2T2R" : "RF_1T1R")); + if (get_rf_type(rtlphy) == RF_1T1R) + rtlpriv->dm.rfpath_rxenable[0] = true; + else + rtlpriv->dm.rfpath_rxenable[0] = + rtlpriv->dm.rfpath_rxenable[1] = true; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n", + rtlhal->version)); +} + +/** + * writeLLT - LLT table write access + * @io: io callback + * @address: LLT logical address. + * @data: LLT data content + * + * Realtek hardware access function. + * + */ +bool rtl92c_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool status = true; + long count = 0; + u32 value = _LLT_INIT_ADDR(address) | + _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS); + + rtl_write_dword(rtlpriv, REG_LLT_INIT, value); + do { + value = rtl_read_dword(rtlpriv, REG_LLT_INIT); + if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) + break; + if (count > POLLING_LLT_THRESHOLD) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Failed to polling write LLT done at" + " address %d! _LLT_OP_VALUE(%x)\n", + address, _LLT_OP_VALUE(value))); + status = false; + break; + } + } while (++count); + return status; +} +/** + * rtl92c_init_LLT_table - Init LLT table + * @io: io callback + * @boundary: + * + * Realtek hardware access function. + * + */ +bool rtl92c_init_llt_table(struct ieee80211_hw *hw, u32 boundary) +{ + bool rst = true; + u32 i; + + for (i = 0; i < (boundary - 1); i++) { + rst = rtl92c_llt_write(hw, i , i + 1); + if (true != rst) { + printk(KERN_ERR "===> %s #1 fail\n", __func__); + return rst; + } + } + /* end of list */ + rst = rtl92c_llt_write(hw, (boundary - 1), 0xFF); + if (true != rst) { + printk(KERN_ERR "===> %s #2 fail\n", __func__); + return rst; + } + /* Make the other pages as ring buffer + * This ring buffer is used as beacon buffer if we config this MAC + * as two MAC transfer. + * Otherwise used as local loopback buffer. + */ + for (i = boundary; i < LLT_LAST_ENTRY_OF_TX_PKT_BUFFER; i++) { + rst = rtl92c_llt_write(hw, i, (i + 1)); + if (true != rst) { + printk(KERN_ERR "===> %s #3 fail\n", __func__); + return rst; + } + } + /* Let last entry point to the start entry of ring buffer */ + rst = rtl92c_llt_write(hw, LLT_LAST_ENTRY_OF_TX_PKT_BUFFER, boundary); + if (true != rst) { + printk(KERN_ERR "===> %s #4 fail\n", __func__); + return rst; + } + return rst; +} +void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, + u8 *p_macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 *macaddr = p_macaddr; + u32 entry_id = 0; + bool is_pairwise = false; + static u8 cam_const_addr[4][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} + }; + static u8 cam_const_broad[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + if (clear_all) { + u8 idx = 0; + u8 cam_offset = 0; + u8 clear_number = 5; + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n")); + for (idx = 0; idx < clear_number; idx++) { + rtl_cam_mark_invalid(hw, cam_offset + idx); + rtl_cam_empty_entry(hw, cam_offset + idx); + if (idx < 5) { + memset(rtlpriv->sec.key_buf[idx], 0, + MAX_KEY_LEN); + rtlpriv->sec.key_len[idx] = 0; + } + } + } else { + switch (enc_algo) { + case WEP40_ENCRYPTION: + enc_algo = CAM_WEP40; + break; + case WEP104_ENCRYPTION: + enc_algo = CAM_WEP104; + break; + case TKIP_ENCRYPTION: + enc_algo = CAM_TKIP; + break; + case AESCCMP_ENCRYPTION: + enc_algo = CAM_AES; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("iillegal switch case\n")); + enc_algo = CAM_TKIP; + break; + } + if (is_wepkey || rtlpriv->sec.use_defaultkey) { + macaddr = cam_const_addr[key_index]; + entry_id = key_index; + } else { + if (is_group) { + macaddr = cam_const_broad; + entry_id = key_index; + } else { + key_index = PAIRWISE_KEYIDX; + entry_id = CAM_PAIRWISE_KEY_POSITION; + is_pairwise = true; + } + } + if (rtlpriv->sec.key_len[key_index] == 0) { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("delete one entry\n")); + rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); + } else { + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("The insert KEY length is %d\n", + rtlpriv->sec.key_len[PAIRWISE_KEYIDX])); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("The insert KEY is %x %x\n", + rtlpriv->sec.key_buf[0][0], + rtlpriv->sec.key_buf[0][1])); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("add one entry\n")); + if (is_pairwise) { + RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, + "Pairwiase Key content :", + rtlpriv->sec.pairwise_key, + rtlpriv->sec. + key_len[PAIRWISE_KEYIDX]); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("set Pairwiase key\n")); + + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec. + key_buf[key_index]); + } else { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + ("set group key\n")); + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + rtl_cam_add_one_entry(hw, + rtlefuse->dev_addr, + PAIRWISE_KEYIDX, + CAM_PAIRWISE_KEY_POSITION, + enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf + [entry_id]); + } + rtl_cam_add_one_entry(hw, macaddr, key_index, + entry_id, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[entry_id]); + } + } + } +} + +u32 rtl92c_get_txdma_status(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + return rtl_read_dword(rtlpriv, REG_TXDMA_STATUS); +} + +void rtl92c_enable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + if (IS_HARDWARE_TYPE_8192CE(rtlhal)) { + rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & + 0xFFFFFFFF); + rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & + 0xFFFFFFFF); + rtlpci->irq_enabled = true; + } else { + rtl_write_dword(rtlpriv, REG_HIMR, rtlusb->irq_mask[0] & + 0xFFFFFFFF); + rtl_write_dword(rtlpriv, REG_HIMRE, rtlusb->irq_mask[1] & + 0xFFFFFFFF); + rtlusb->irq_enabled = true; + } +} + +void rtl92c_init_interrupt(struct ieee80211_hw *hw) +{ + rtl92c_enable_interrupt(hw); +} + +void rtl92c_disable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED); + rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED); + if (IS_HARDWARE_TYPE_8192CE(rtlhal)) + rtlpci->irq_enabled = false; + else if (IS_HARDWARE_TYPE_8192CU(rtlhal)) + rtlusb->irq_enabled = false; +} + +void rtl92c_set_qos(struct ieee80211_hw *hw, int aci) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u32 u4b_ac_param; + + rtl92c_dm_init_edca_turbo(hw); + u4b_ac_param = (u32) mac->ac[aci].aifs; + u4b_ac_param |= + ((u32) le16_to_cpu(mac->ac[aci].cw_min) & 0xF) << + AC_PARAM_ECW_MIN_OFFSET; + u4b_ac_param |= + ((u32) le16_to_cpu(mac->ac[aci].cw_max) & 0xF) << + AC_PARAM_ECW_MAX_OFFSET; + u4b_ac_param |= (u32) le16_to_cpu(mac->ac[aci].tx_op) << + AC_PARAM_TXOP_OFFSET; + RT_TRACE(rtlpriv, COMP_QOS, DBG_LOUD, + ("queue:%x, ac_param:%x\n", aci, u4b_ac_param)); + switch (aci) { + case AC1_BK: + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param); + break; + case AC0_BE: + rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param); + break; + case AC2_VI: + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, u4b_ac_param); + break; + case AC3_VO: + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, u4b_ac_param); + break; + default: + RT_ASSERT(false, ("invalid aci: %d !\n", aci)); + break; + } +} + +/*------------------------------------------------------------------------- + * HW MAC Address + *-------------------------------------------------------------------------*/ +void rtl92c_set_mac_addr(struct ieee80211_hw *hw, const u8 *addr) +{ + u32 i; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + for (i = 0 ; i < ETH_ALEN ; i++) + rtl_write_byte(rtlpriv, (REG_MACID + i), *(addr+i)); + + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("MAC Address: %02X-%02X-%02X-" + "%02X-%02X-%02X\n", + rtl_read_byte(rtlpriv, REG_MACID), + rtl_read_byte(rtlpriv, REG_MACID+1), + rtl_read_byte(rtlpriv, REG_MACID+2), + rtl_read_byte(rtlpriv, REG_MACID+3), + rtl_read_byte(rtlpriv, REG_MACID+4), + rtl_read_byte(rtlpriv, REG_MACID+5))); +} + +void rtl92c_init_driver_info_size(struct ieee80211_hw *hw, u8 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, size); +} + +int rtl92c_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) +{ + u8 value; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + switch (type) { + case NL80211_IFTYPE_UNSPECIFIED: + value = NT_NO_LINK; + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("Set Network type to NO LINK!\n")); + break; + case NL80211_IFTYPE_ADHOC: + value = NT_LINK_AD_HOC; + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("Set Network type to Ad Hoc!\n")); + break; + case NL80211_IFTYPE_STATION: + value = NT_LINK_AP; + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("Set Network type to STA!\n")); + break; + case NL80211_IFTYPE_AP: + value = NT_AS_AP; + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("Set Network type to AP!\n")); + break; + default: + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("Network type %d not support!\n", type)); + return -EOPNOTSUPP; + } + rtl_write_byte(rtlpriv, (REG_CR + 2), value); + return 0; +} + +void rtl92c_init_network_type(struct ieee80211_hw *hw) +{ + rtl92c_set_network_type(hw, NL80211_IFTYPE_UNSPECIFIED); +} + +void rtl92c_init_adaptive_ctrl(struct ieee80211_hw *hw) +{ + u16 value16; + u32 value32; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* Response Rate Set */ + value32 = rtl_read_dword(rtlpriv, REG_RRSR); + value32 &= ~RATE_BITMAP_ALL; + value32 |= RATE_RRSR_CCK_ONLY_1M; + rtl_write_dword(rtlpriv, REG_RRSR, value32); + /* SIFS (used in NAV) */ + value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10); + rtl_write_word(rtlpriv, REG_SPEC_SIFS, value16); + /* Retry Limit */ + value16 = _LRL(0x30) | _SRL(0x30); + rtl_write_dword(rtlpriv, REG_RL, value16); +} + +void rtl92c_init_rate_fallback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* Set Data Auto Rate Fallback Retry Count register. */ + rtl_write_dword(rtlpriv, REG_DARFRC, 0x00000000); + rtl_write_dword(rtlpriv, REG_DARFRC+4, 0x10080404); + rtl_write_dword(rtlpriv, REG_RARFRC, 0x04030201); + rtl_write_dword(rtlpriv, REG_RARFRC+4, 0x08070605); +} + +static void rtl92c_set_cck_sifs(struct ieee80211_hw *hw, u8 trx_sifs, + u8 ctx_sifs) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_SIFS_CCK, trx_sifs); + rtl_write_byte(rtlpriv, (REG_SIFS_CCK + 1), ctx_sifs); +} + +static void rtl92c_set_ofdm_sifs(struct ieee80211_hw *hw, u8 trx_sifs, + u8 ctx_sifs) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_SIFS_OFDM, trx_sifs); + rtl_write_byte(rtlpriv, (REG_SIFS_OFDM + 1), ctx_sifs); +} + +void rtl92c_init_edca_param(struct ieee80211_hw *hw, + u16 queue, u16 txop, u8 cw_min, u8 cw_max, u8 aifs) +{ + /* sequence: VO, VI, BE, BK ==> the same as 92C hardware design. + * referenc : enum nl80211_txq_q or ieee80211_set_wmm_default function. + */ + u32 value; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + value = (u32)aifs; + value |= ((u32)cw_min & 0xF) << 8; + value |= ((u32)cw_max & 0xF) << 12; + value |= (u32)txop << 16; + /* 92C hardware register sequence is the same as queue number. */ + rtl_write_dword(rtlpriv, (REG_EDCA_VO_PARAM + (queue * 4)), value); +} + +void rtl92c_init_edca(struct ieee80211_hw *hw) +{ + u16 value16; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* disable EDCCA count down, to reduce collison and retry */ + value16 = rtl_read_word(rtlpriv, REG_RD_CTRL); + value16 |= DIS_EDCA_CNT_DWN; + rtl_write_word(rtlpriv, REG_RD_CTRL, value16); + /* Update SIFS timing. ?????????? + * pHalData->SifsTime = 0x0e0e0a0a; */ + rtl92c_set_cck_sifs(hw, 0xa, 0xa); + rtl92c_set_ofdm_sifs(hw, 0xe, 0xe); + /* Set CCK/OFDM SIFS to be 10us. */ + rtl_write_word(rtlpriv, REG_SIFS_CCK, 0x0a0a); + rtl_write_word(rtlpriv, REG_SIFS_OFDM, 0x1010); + rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0204); + rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x014004); + /* TXOP */ + rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, 0x005EA42B); + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0x0000A44F); + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x005EA324); + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x002FA226); + /* PIFS */ + rtl_write_byte(rtlpriv, REG_PIFS, 0x1C); + /* AGGR BREAK TIME Register */ + rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); + rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040); + rtl_write_byte(rtlpriv, REG_BCNDMATIM, 0x02); + rtl_write_byte(rtlpriv, REG_ATIMWND, 0x02); +} + +void rtl92c_init_ampdu_aggregation(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x99997631); + rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); + /* init AMPDU aggregation number, tuning for Tx's TP, */ + rtl_write_word(rtlpriv, 0x4CA, 0x0708); +} + +void rtl92c_init_beacon_max_error(struct ieee80211_hw *hw, bool infra_mode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xFF); +} + +void rtl92c_init_rdg_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_RD_CTRL, 0xFF); + rtl_write_word(rtlpriv, REG_RD_NAV_NXT, 0x200); + rtl_write_byte(rtlpriv, REG_RD_RESP_PKT_TH, 0x05); +} + +void rtl92c_init_retry_function(struct ieee80211_hw *hw) +{ + u8 value8; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + value8 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL); + value8 |= EN_AMPDU_RTY_NEW; + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL, value8); + /* Set ACK timeout */ + rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); +} + +void rtl92c_init_beacon_parameters(struct ieee80211_hw *hw, + enum version_8192c version) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + rtl_write_word(rtlpriv, REG_TBTT_PROHIBIT, 0x6404);/* ms */ + rtl_write_byte(rtlpriv, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME);/*ms*/ + rtl_write_byte(rtlpriv, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME); + if (IS_NORMAL_CHIP(rtlhal->version)) + rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660F); + else + rtl_write_word(rtlpriv, REG_BCNTCFG, 0x66FF); +} + +void rtl92c_disable_fast_edca(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_word(rtlpriv, REG_FAST_EDCA_CTRL, 0); +} + +void rtl92c_set_min_space(struct ieee80211_hw *hw, bool is2T) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value = is2T ? MAX_MSS_DENSITY_2T : MAX_MSS_DENSITY_1T; + + rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, value); +} + +u16 rtl92c_get_mgt_filter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + return rtl_read_word(rtlpriv, REG_RXFLTMAP0); +} + +void rtl92c_set_mgt_filter(struct ieee80211_hw *hw, u16 filter) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_word(rtlpriv, REG_RXFLTMAP0, filter); +} + +u16 rtl92c_get_ctrl_filter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + return rtl_read_word(rtlpriv, REG_RXFLTMAP1); +} + +void rtl92c_set_ctrl_filter(struct ieee80211_hw *hw, u16 filter) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_word(rtlpriv, REG_RXFLTMAP1, filter); +} + +u16 rtl92c_get_data_filter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + return rtl_read_word(rtlpriv, REG_RXFLTMAP2); +} + +void rtl92c_set_data_filter(struct ieee80211_hw *hw, u16 filter) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_word(rtlpriv, REG_RXFLTMAP2, filter); +} +/*==============================================================*/ + +static u8 _rtl92c_query_rxpwrpercentage(char antpower) +{ + if ((antpower <= -100) || (antpower >= 20)) + return 0; + else if (antpower >= 0) + return 100; + else + return 100 + antpower; +} + +static u8 _rtl92c_evm_db_to_percentage(char value) +{ + char ret_val; + + ret_val = value; + if (ret_val >= 0) + ret_val = 0; + if (ret_val <= -33) + ret_val = -33; + ret_val = 0 - ret_val; + ret_val *= 3; + if (ret_val == 99) + ret_val = 100; + return ret_val; +} + +static long _rtl92c_translate_todbm(struct ieee80211_hw *hw, + u8 signal_strength_index) +{ + long signal_power; + + signal_power = (long)((signal_strength_index + 1) >> 1); + signal_power -= 95; + return signal_power; +} + +static long _rtl92c_signal_scale_mapping(struct ieee80211_hw *hw, + long currsig) +{ + long retsig; + + if (currsig >= 61 && currsig <= 100) + retsig = 90 + ((currsig - 60) / 4); + else if (currsig >= 41 && currsig <= 60) + retsig = 78 + ((currsig - 40) / 2); + else if (currsig >= 31 && currsig <= 40) + retsig = 66 + (currsig - 30); + else if (currsig >= 21 && currsig <= 30) + retsig = 54 + (currsig - 20); + else if (currsig >= 5 && currsig <= 20) + retsig = 42 + (((currsig - 5) * 2) / 3); + else if (currsig == 4) + retsig = 36; + else if (currsig == 3) + retsig = 27; + else if (currsig == 2) + retsig = 18; + else if (currsig == 1) + retsig = 9; + else + retsig = currsig; + return retsig; +} + +static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw, + struct rtl_stats *pstats, + struct rx_desc_92c *pdesc, + struct rx_fwinfo_92c *p_drvinfo, + bool packet_match_bssid, + bool packet_toself, + bool packet_beacon) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct phy_sts_cck_8192s_t *cck_buf; + s8 rx_pwr_all = 0, rx_pwr[4]; + u8 rf_rx_num = 0, evm, pwdb_all; + u8 i, max_spatial_stream; + u32 rssi, total_rssi = 0; + bool in_powersavemode = false; + bool is_cck_rate; + + is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); + pstats->packet_matchbssid = packet_match_bssid; + pstats->packet_toself = packet_toself; + pstats->is_cck = is_cck_rate; + pstats->packet_beacon = packet_beacon; + pstats->is_cck = is_cck_rate; + pstats->RX_SIGQ[0] = -1; + pstats->RX_SIGQ[1] = -1; + if (is_cck_rate) { + u8 report, cck_highpwr; + cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; + if (!in_powersavemode) + cck_highpwr = rtlphy->cck_high_power; + else + cck_highpwr = false; + if (!cck_highpwr) { + u8 cck_agc_rpt = cck_buf->cck_agc_rpt; + report = cck_buf->cck_agc_rpt & 0xc0; + report = report >> 6; + switch (report) { + case 0x3: + rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); + break; + case 0x2: + rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); + break; + case 0x1: + rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); + break; + case 0x0: + rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); + break; + } + } else { + u8 cck_agc_rpt = cck_buf->cck_agc_rpt; + report = p_drvinfo->cfosho[0] & 0x60; + report = report >> 5; + switch (report) { + case 0x3: + rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x2: + rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x1: + rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1); + break; + case 0x0: + rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1); + break; + } + } + pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all); + pstats->rx_pwdb_all = pwdb_all; + pstats->recvsignalpower = rx_pwr_all; + if (packet_match_bssid) { + u8 sq; + if (pstats->rx_pwdb_all > 40) + sq = 100; + else { + sq = cck_buf->sq_rpt; + if (sq > 64) + sq = 0; + else if (sq < 20) + sq = 100; + else + sq = ((64 - sq) * 100) / 44; + } + pstats->signalquality = sq; + pstats->RX_SIGQ[0] = sq; + pstats->RX_SIGQ[1] = -1; + } + } else { + rtlpriv->dm.rfpath_rxenable[0] = + rtlpriv->dm.rfpath_rxenable[1] = true; + for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) { + if (rtlpriv->dm.rfpath_rxenable[i]) + rf_rx_num++; + rx_pwr[i] = + ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110; + rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]); + total_rssi += rssi; + rtlpriv->stats.rx_snr_db[i] = + (long)(p_drvinfo->rxsnr[i] / 2); + + if (packet_match_bssid) + pstats->rx_mimo_signalstrength[i] = (u8) rssi; + } + rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; + pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all); + pstats->rx_pwdb_all = pwdb_all; + pstats->rxpower = rx_pwr_all; + pstats->recvsignalpower = rx_pwr_all; + if (GET_RX_DESC_RX_MCS(pdesc) && + GET_RX_DESC_RX_MCS(pdesc) >= DESC92C_RATEMCS8 && + GET_RX_DESC_RX_MCS(pdesc) <= DESC92C_RATEMCS15) + max_spatial_stream = 2; + else + max_spatial_stream = 1; + for (i = 0; i < max_spatial_stream; i++) { + evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]); + if (packet_match_bssid) { + if (i == 0) + pstats->signalquality = + (u8) (evm & 0xff); + pstats->RX_SIGQ[i] = + (u8) (evm & 0xff); + } + } + } + if (is_cck_rate) + pstats->signalstrength = + (u8) (_rtl92c_signal_scale_mapping(hw, pwdb_all)); + else if (rf_rx_num != 0) + pstats->signalstrength = + (u8) (_rtl92c_signal_scale_mapping + (hw, total_rssi /= rf_rx_num)); +} + +static void _rtl92c_process_ui_rssi(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u8 rfpath; + u32 last_rssi, tmpval; + + if (pstats->packet_toself || pstats->packet_beacon) { + rtlpriv->stats.rssi_calculate_cnt++; + if (rtlpriv->stats.ui_rssi.total_num++ >= + PHY_RSSI_SLID_WIN_MAX) { + rtlpriv->stats.ui_rssi.total_num = + PHY_RSSI_SLID_WIN_MAX; + last_rssi = + rtlpriv->stats.ui_rssi.elements[rtlpriv-> + stats.ui_rssi.index]; + rtlpriv->stats.ui_rssi.total_val -= last_rssi; + } + rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength; + rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi. + index++] = pstats->signalstrength; + if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX) + rtlpriv->stats.ui_rssi.index = 0; + tmpval = rtlpriv->stats.ui_rssi.total_val / + rtlpriv->stats.ui_rssi.total_num; + rtlpriv->stats.signal_strength = + _rtl92c_translate_todbm(hw, (u8) tmpval); + pstats->rssi = rtlpriv->stats.signal_strength; + } + if (!pstats->is_cck && pstats->packet_toself) { + for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; + rfpath++) { + if (!rtl8192_phy_check_is_legal_rfpath(hw, rfpath)) + continue; + if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + pstats->rx_mimo_signalstrength[rfpath]; + } + if (pstats->rx_mimo_signalstrength[rfpath] > + rtlpriv->stats.rx_rssi_percentage[rfpath]) { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + ((rtlpriv->stats. + rx_rssi_percentage[rfpath] * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_mimo_signalstrength[rfpath])) / + (RX_SMOOTH_FACTOR); + + rtlpriv->stats.rx_rssi_percentage[rfpath] = + rtlpriv->stats.rx_rssi_percentage[rfpath] + + 1; + } else { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + ((rtlpriv->stats. + rx_rssi_percentage[rfpath] * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_mimo_signalstrength[rfpath])) / + (RX_SMOOTH_FACTOR); + } + } + } +} + +static void _rtl92c_update_rxsignalstatistics(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int weighting = 0; + + if (rtlpriv->stats.recv_signal_power == 0) + rtlpriv->stats.recv_signal_power = pstats->recvsignalpower; + if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power) + weighting = 5; + else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power) + weighting = (-5); + rtlpriv->stats.recv_signal_power = + (rtlpriv->stats.recv_signal_power * 5 + + pstats->recvsignalpower + weighting) / 6; +} + +static void _rtl92c_process_pwdb(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long undecorated_smoothed_pwdb = 0; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + return; + } else { + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; + } + if (pstats->packet_toself || pstats->packet_beacon) { + if (undecorated_smoothed_pwdb < 0) + undecorated_smoothed_pwdb = pstats->rx_pwdb_all; + if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) { + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); + undecorated_smoothed_pwdb = undecorated_smoothed_pwdb + + 1; + } else { + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); + } + rtlpriv->dm.undecorated_smoothed_pwdb = + undecorated_smoothed_pwdb; + _rtl92c_update_rxsignalstatistics(hw, pstats); + } +} + +static void _rtl92c_process_LINK_Q(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 last_evm = 0, n_stream, tmpval; + + if (pstats->signalquality != 0) { + if (pstats->packet_toself || pstats->packet_beacon) { + if (rtlpriv->stats.LINK_Q.total_num++ >= + PHY_LINKQUALITY_SLID_WIN_MAX) { + rtlpriv->stats.LINK_Q.total_num = + PHY_LINKQUALITY_SLID_WIN_MAX; + last_evm = + rtlpriv->stats.LINK_Q.elements + [rtlpriv->stats.LINK_Q.index]; + rtlpriv->stats.LINK_Q.total_val -= + last_evm; + } + rtlpriv->stats.LINK_Q.total_val += + pstats->signalquality; + rtlpriv->stats.LINK_Q.elements + [rtlpriv->stats.LINK_Q.index++] = + pstats->signalquality; + if (rtlpriv->stats.LINK_Q.index >= + PHY_LINKQUALITY_SLID_WIN_MAX) + rtlpriv->stats.LINK_Q.index = 0; + tmpval = rtlpriv->stats.LINK_Q.total_val / + rtlpriv->stats.LINK_Q.total_num; + rtlpriv->stats.signal_quality = tmpval; + rtlpriv->stats.last_sigstrength_inpercent = tmpval; + for (n_stream = 0; n_stream < 2; + n_stream++) { + if (pstats->RX_SIGQ[n_stream] != -1) { + if (!rtlpriv->stats.RX_EVM[n_stream]) { + rtlpriv->stats.RX_EVM[n_stream] + = pstats->RX_SIGQ[n_stream]; + } + rtlpriv->stats.RX_EVM[n_stream] = + ((rtlpriv->stats.RX_EVM + [n_stream] * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->RX_SIGQ + [n_stream] * 1)) / + (RX_SMOOTH_FACTOR); + } + } + } + } else { + ; + } +} + +static void _rtl92c_process_phyinfo(struct ieee80211_hw *hw, + u8 *buffer, + struct rtl_stats *pcurrent_stats) +{ + if (!pcurrent_stats->packet_matchbssid && + !pcurrent_stats->packet_beacon) + return; + _rtl92c_process_ui_rssi(hw, pcurrent_stats); + _rtl92c_process_pwdb(hw, pcurrent_stats); + _rtl92c_process_LINK_Q(hw, pcurrent_stats); +} + +void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct rtl_stats *pstats, + struct rx_desc_92c *pdesc, + struct rx_fwinfo_92c *p_drvinfo) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct ieee80211_hdr *hdr; + u8 *tmp_buf; + u8 *praddr; + u8 *psaddr; + __le16 fc; + u16 type, cpu_fc; + bool packet_matchbssid, packet_toself, packet_beacon; + + tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; + hdr = (struct ieee80211_hdr *)tmp_buf; + fc = hdr->frame_control; + cpu_fc = le16_to_cpu(fc); + type = WLAN_FC_GET_TYPE(fc); + praddr = hdr->addr1; + psaddr = hdr->addr2; + packet_matchbssid = + ((IEEE80211_FTYPE_CTL != type) && + (!compare_ether_addr(mac->bssid, + (cpu_fc & IEEE80211_FCTL_TODS) ? + hdr->addr1 : (cpu_fc & IEEE80211_FCTL_FROMDS) ? + hdr->addr2 : hdr->addr3)) && + (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv)); + + packet_toself = packet_matchbssid && + (!compare_ether_addr(praddr, rtlefuse->dev_addr)); + if (ieee80211_is_beacon(fc)) + packet_beacon = true; + _rtl92c_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, + packet_matchbssid, packet_toself, + packet_beacon); + _rtl92c_process_phyinfo(hw, tmp_buf, pstats); +} -- cgit v1.2.3 From f0a39ae738d660cb69e486abd20c0dec1cdcb898 Mon Sep 17 00:00:00 2001 From: George Date: Sat, 19 Feb 2011 16:29:32 -0600 Subject: rtlwifi: rtl8192cu: Add routine phy Add the routine rtlwifi/rtl8192cu/phy.c. Most of the code is included from rtlwifi/rtl8192c/phy_common.c. Signed-off-by: George Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/phy.c | 611 +++++++++++++++++++++++++++ 1 file changed, 611 insertions(+) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/phy.c (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c new file mode 100644 index 000000000000..dc65ef2bbeac --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c @@ -0,0 +1,611 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "../ps.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" +#include "table.h" + +#include "../rtl8192c/phy_common.c" + +u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 original_value, readback_value, bitshift; + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " + "rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask)); + if (rtlphy->rf_mode != RF_OP_BY_FW) { + original_value = _rtl92c_phy_rf_serial_read(hw, + rfpath, regaddr); + } else { + original_value = _rtl92c_phy_fw_rf_serial_read(hw, + rfpath, regaddr); + } + bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + readback_value = (original_value & bitmask) >> bitshift; + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + ("regaddr(%#x), rfpath(%#x), " + "bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value)); + return readback_value; +} + +void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 original_value, bitshift; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath)); + if (rtlphy->rf_mode != RF_OP_BY_FW) { + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl92c_phy_rf_serial_read(hw, + rfpath, + regaddr); + bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); + } + _rtl92c_phy_rf_serial_write(hw, rfpath, regaddr, data); + } else { + if (bitmask != RFREG_OFFSET_MASK) { + original_value = _rtl92c_phy_fw_rf_serial_read(hw, + rfpath, + regaddr); + bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + data = + ((original_value & (~bitmask)) | + (data << bitshift)); + } + _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data); + } + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " + "bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath)); +} + +bool rtl92c_phy_mac_config(struct ieee80211_hw *hw) +{ + bool rtstatus; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool is92c = IS_92C_SERIAL(rtlhal->version); + + rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw); + if (is92c && IS_HARDWARE_TYPE_8192CE(rtlhal)) + rtl_write_byte(rtlpriv, 0x14, 0x71); + return rtstatus; +} + +bool rtl92c_phy_bb_config(struct ieee80211_hw *hw) +{ + bool rtstatus = true; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u16 regval; + u8 b_reg_hwparafile = 1; + + _rtl92c_phy_init_bb_rf_register_definition(hw); + regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); + rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, regval | BIT(13) | + BIT(0) | BIT(1)); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83); + rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb); + rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); + if (IS_HARDWARE_TYPE_8192CE(rtlhal)) { + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_PPLL | FEN_PCIEA | + FEN_DIO_PCIE | FEN_BB_GLB_RSTn | FEN_BBRSTB); + } else if (IS_HARDWARE_TYPE_8192CU(rtlhal)) { + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD | + FEN_BB_GLB_RSTn | FEN_BBRSTB); + rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f); + } + rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); + if (b_reg_hwparafile == 1) + rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); + return rtstatus; +} + +static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 i; + u32 arraylength; + u32 *ptrarray; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n")); + arraylength = rtlphy->hwparam_tables[MAC_REG].length ; + ptrarray = rtlphy->hwparam_tables[MAC_REG].pdata; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Img:RTL8192CEMAC_2T_ARRAY\n")); + for (i = 0; i < arraylength; i = i + 2) + rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); + return true; +} + +static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype) +{ + int i; + u32 *phy_regarray_table; + u32 *agctab_array_table; + u16 phy_reg_arraylen, agctab_arraylen; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (IS_92C_SERIAL(rtlhal->version)) { + agctab_arraylen = rtlphy->hwparam_tables[AGCTAB_2T].length; + agctab_array_table = rtlphy->hwparam_tables[AGCTAB_2T].pdata; + phy_reg_arraylen = rtlphy->hwparam_tables[PHY_REG_2T].length; + phy_regarray_table = rtlphy->hwparam_tables[PHY_REG_2T].pdata; + } else { + agctab_arraylen = rtlphy->hwparam_tables[AGCTAB_1T].length; + agctab_array_table = rtlphy->hwparam_tables[AGCTAB_1T].pdata; + phy_reg_arraylen = rtlphy->hwparam_tables[PHY_REG_1T].length; + phy_regarray_table = rtlphy->hwparam_tables[PHY_REG_1T].pdata; + } + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_reg_arraylen; i = i + 2) { + if (phy_regarray_table[i] == 0xfe) + mdelay(50); + else if (phy_regarray_table[i] == 0xfd) + mdelay(5); + else if (phy_regarray_table[i] == 0xfc) + mdelay(1); + else if (phy_regarray_table[i] == 0xfb) + udelay(50); + else if (phy_regarray_table[i] == 0xfa) + udelay(5); + else if (phy_regarray_table[i] == 0xf9) + udelay(1); + rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD, + phy_regarray_table[i + 1]); + udelay(1); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("The phy_regarray_table[0] is %x" + " Rtl819XPHY_REGArray[1] is %x\n", + phy_regarray_table[i], + phy_regarray_table[i + 1])); + } + rtl92c_phy_config_bb_external_pa(hw); + } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { + for (i = 0; i < agctab_arraylen; i = i + 2) { + rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD, + agctab_array_table[i + 1]); + udelay(1); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("The agctab_array_table[0] is " + "%x Rtl819XPHY_REGArray[1] is %x\n", + agctab_array_table[i], + agctab_array_table[i + 1])); + } + } + return true; +} + +static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + int i; + u32 *phy_regarray_table_pg; + u16 phy_regarray_pg_len; + + rtlphy->pwrgroup_cnt = 0; + phy_regarray_pg_len = rtlphy->hwparam_tables[PHY_REG_PG].length; + phy_regarray_table_pg = rtlphy->hwparam_tables[PHY_REG_PG].pdata; + if (configtype == BASEBAND_CONFIG_PHY_REG) { + for (i = 0; i < phy_regarray_pg_len; i = i + 3) { + if (phy_regarray_table_pg[i] == 0xfe) + mdelay(50); + else if (phy_regarray_table_pg[i] == 0xfd) + mdelay(5); + else if (phy_regarray_table_pg[i] == 0xfc) + mdelay(1); + else if (phy_regarray_table_pg[i] == 0xfb) + udelay(50); + else if (phy_regarray_table_pg[i] == 0xfa) + udelay(5); + else if (phy_regarray_table_pg[i] == 0xf9) + udelay(1); + _rtl92c_store_pwrIndex_diffrate_offset(hw, + phy_regarray_table_pg[i], + phy_regarray_table_pg[i + 1], + phy_regarray_table_pg[i + 2]); + } + } else { + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, + ("configtype != BaseBand_Config_PHY_REG\n")); + } + return true; +} + +bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath) +{ + int i; + u32 *radioa_array_table; + u32 *radiob_array_table; + u16 radioa_arraylen, radiob_arraylen; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + if (IS_92C_SERIAL(rtlhal->version)) { + radioa_arraylen = rtlphy->hwparam_tables[RADIOA_2T].length; + radioa_array_table = rtlphy->hwparam_tables[RADIOA_2T].pdata; + radiob_arraylen = rtlphy->hwparam_tables[RADIOB_2T].length; + radiob_array_table = rtlphy->hwparam_tables[RADIOB_2T].pdata; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Radio_A:RTL8192CERADIOA_2TARRAY\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Radio_B:RTL8192CE_RADIOB_2TARRAY\n")); + } else { + radioa_arraylen = rtlphy->hwparam_tables[RADIOA_1T].length; + radioa_array_table = rtlphy->hwparam_tables[RADIOA_1T].pdata; + radiob_arraylen = rtlphy->hwparam_tables[RADIOB_1T].length; + radiob_array_table = rtlphy->hwparam_tables[RADIOB_1T].pdata; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Radio_A:RTL8192CE_RADIOA_1TARRAY\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n")); + } + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath)); + switch (rfpath) { + case RF90_PATH_A: + for (i = 0; i < radioa_arraylen; i = i + 2) { + if (radioa_array_table[i] == 0xfe) + mdelay(50); + else if (radioa_array_table[i] == 0xfd) + mdelay(5); + else if (radioa_array_table[i] == 0xfc) + mdelay(1); + else if (radioa_array_table[i] == 0xfb) + udelay(50); + else if (radioa_array_table[i] == 0xfa) + udelay(5); + else if (radioa_array_table[i] == 0xf9) + udelay(1); + else { + rtl_set_rfreg(hw, rfpath, radioa_array_table[i], + RFREG_OFFSET_MASK, + radioa_array_table[i + 1]); + udelay(1); + } + } + _rtl92c_phy_config_rf_external_pa(hw, rfpath); + break; + case RF90_PATH_B: + for (i = 0; i < radiob_arraylen; i = i + 2) { + if (radiob_array_table[i] == 0xfe) { + mdelay(50); + } else if (radiob_array_table[i] == 0xfd) + mdelay(5); + else if (radiob_array_table[i] == 0xfc) + mdelay(1); + else if (radiob_array_table[i] == 0xfb) + udelay(50); + else if (radiob_array_table[i] == 0xfa) + udelay(5); + else if (radiob_array_table[i] == 0xf9) + udelay(1); + else { + rtl_set_rfreg(hw, rfpath, radiob_array_table[i], + RFREG_OFFSET_MASK, + radiob_array_table[i + 1]); + udelay(1); + } + } + break; + case RF90_PATH_C: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + case RF90_PATH_D: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + return true; +} + +void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 reg_bw_opmode; + u8 reg_prsr_rsc; + + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, + ("Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz")) + if (is_hal_stop(rtlhal)) { + rtlphy->set_bwmode_inprogress = false; + return; + } + reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); + reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + reg_bw_opmode |= BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + break; + case HT_CHANNEL_WIDTH_20_40: + reg_bw_opmode &= ~BW_OPMODE_20MHZ; + rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); + reg_prsr_rsc = + (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); + rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + break; + } + switch (rtlphy->current_chan_bw) { + case HT_CHANNEL_WIDTH_20: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); + break; + case HT_CHANNEL_WIDTH_20_40: + rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, + (mac->cur_40_prime_sc >> 1)); + rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); + rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0); + rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), + (mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + break; + } + rtl92c_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); + rtlphy->set_bwmode_inprogress = false; + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); +} + +void rtl92c_bb_block_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + mutex_lock(&rtlpriv->io.bb_mutex); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); + rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); + mutex_unlock(&rtlpriv->io.bb_mutex); +} + +static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) +{ + u8 tmpreg; + u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + tmpreg = rtl_read_byte(rtlpriv, 0xd03); + + if ((tmpreg & 0x70) != 0) + rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); + else + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); + + if ((tmpreg & 0x70) != 0) { + rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); + if (is2t) + rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, + MASK12BITS); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, + (rf_a_mode & 0x8FFFF) | 0x10000); + if (is2t) + rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, + (rf_b_mode & 0x8FFFF) | 0x10000); + } + lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); + rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000); + mdelay(100); + if ((tmpreg & 0x70) != 0) { + rtl_write_byte(rtlpriv, 0xd03, tmpreg); + rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); + if (is2t) + rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, + rf_b_mode); + } else { + rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); + } +} + +static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool bresult = true; + u8 i, queue_id; + struct rtl8192_tx_ring *ring = NULL; + + ppsc->set_rfpowerstate_inprogress = true; + switch (rfpwr_state) { + case ERFON: + if ((ppsc->rfpwr_state == ERFOFF) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { + bool rtstatus; + u32 InitializeCount = 0; + + do { + InitializeCount++; + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("IPS Set eRf nic enable\n")); + rtstatus = rtl_ps_enable_nic(hw); + } while ((rtstatus != true) + && (InitializeCount < 10)); + RT_CLEAR_PS_LEVEL(ppsc, + RT_RF_OFF_LEVL_HALT_NIC); + } else { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("Set ERFON sleeped:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc-> + last_sleep_jiffies))); + ppsc->last_awake_jiffies = jiffies; + rtl92ce_phy_set_rf_on(hw); + } + if (mac->link_state == MAC80211_LINKED) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_LINK); + } else { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } + break; + case ERFOFF: + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (skb_queue_len(&ring->queue) == 0 || + queue_id == BEACON_QUEUE) { + queue_id++; + continue; + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("eRf Off/Sleep: %d times " + "TcbBusyQueue[%d] " + "=%d before doze!\n", (i + 1), + queue_id, + skb_queue_len(&ring->queue))); + udelay(10); + i++; + } + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("\nERFOFF: %d times " + "TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue))); + break; + } + } + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("IPS Set eRf nic disable\n")); + rtl_ps_disable_nic(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } else { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_POWER_OFF); + } + } + break; + case ERFSLEEP: + if (ppsc->rfpwr_state == ERFOFF) + break; + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (skb_queue_len(&ring->queue) == 0) { + queue_id++; + continue; + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("eRf Off/Sleep: %d times " + "TcbBusyQueue[%d] =%d before " + "doze!\n", (i + 1), queue_id, + skb_queue_len(&ring->queue))); + udelay(10); + i++; + } + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("\n ERFSLEEP: %d times " + "TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue))); + break; + } + } + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + ("Set ERFSLEEP awaked:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies))); + ppsc->last_sleep_jiffies = jiffies; + _rtl92ce_phy_set_rf_sleep(hw); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + bresult = false; + break; + } + if (bresult) + ppsc->rfpwr_state = rfpwr_state; + ppsc->set_rfpowerstate_inprogress = false; + return bresult; +} + +bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool bresult = false; + + if (rfpwr_state == ppsc->rfpwr_state) + return bresult; + bresult = _rtl92ce_phy_set_rf_power_state(hw, rfpwr_state); + return bresult; +} -- cgit v1.2.3 From 3ac23f8106051aa8a922d9ad8415232bb5c1af70 Mon Sep 17 00:00:00 2001 From: George Date: Sat, 19 Feb 2011 16:29:37 -0600 Subject: rtlwifi: rtl8192cu: Add routine rf Add rtlwifi/rtl8192cu/rf.c. This routine is distinct from the one in rtl8192ce with the same name. Signed-off-by: George Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/rf.c | 493 ++++++++++++++++++++++++++++ 1 file changed, 493 insertions(+) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/rf.c (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c new file mode 100644 index 000000000000..9149adcc8fa5 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c @@ -0,0 +1,493 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" + +static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw); + +void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + + switch (bandwidth) { + case HT_CHANNEL_WIDTH_20: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff) | 0x0400); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + case HT_CHANNEL_WIDTH_20_40: + rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & + 0xfffff3ff)); + rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, + rtlphy->rfreg_chnlval[0]); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("unknown bandwidth: %#X\n", bandwidth)); + break; + } +} + +void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 tx_agc[2] = { 0, 0 }, tmpval = 0; + bool turbo_scanoff = false; + u8 idx1, idx2; + u8 *ptr; + + if (rtlhal->interface == INTF_PCI) { + if (rtlefuse->eeprom_regulatory != 0) + turbo_scanoff = true; + } else { + if ((rtlefuse->eeprom_regulatory != 0) || + (rtlefuse->external_pa)) + turbo_scanoff = true; + } + if (mac->act_scanning == true) { + tx_agc[RF90_PATH_A] = 0x3f3f3f3f; + tx_agc[RF90_PATH_B] = 0x3f3f3f3f; + if (turbo_scanoff) { + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + if (rtlhal->interface == INTF_USB) { + if (tx_agc[idx1] > 0x20 && + rtlefuse->external_pa) + tx_agc[idx1] = 0x20; + } + } + } + } else { + if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_LEVEL1) { + tx_agc[RF90_PATH_A] = 0x10101010; + tx_agc[RF90_PATH_B] = 0x10101010; + } else if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_LEVEL1) { + tx_agc[RF90_PATH_A] = 0x00000000; + tx_agc[RF90_PATH_B] = 0x00000000; + } else{ + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + tx_agc[idx1] = ppowerlevel[idx1] | + (ppowerlevel[idx1] << 8) | + (ppowerlevel[idx1] << 16) | + (ppowerlevel[idx1] << 24); + } + if (rtlefuse->eeprom_regulatory == 0) { + tmpval = (rtlphy->mcs_txpwrlevel_origoffset + [0][6]) + + (rtlphy->mcs_txpwrlevel_origoffset + [0][7] << 8); + tx_agc[RF90_PATH_A] += tmpval; + tmpval = (rtlphy->mcs_txpwrlevel_origoffset + [0][14]) + + (rtlphy->mcs_txpwrlevel_origoffset + [0][15] << 24); + tx_agc[RF90_PATH_B] += tmpval; + } + } + } + for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { + ptr = (u8 *) (&(tx_agc[idx1])); + for (idx2 = 0; idx2 < 4; idx2++) { + if (*ptr > RF6052_MAX_TX_PWR) + *ptr = RF6052_MAX_TX_PWR; + ptr++; + } + } + tmpval = tx_agc[RF90_PATH_A] & 0xff; + rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); + + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_A_CCK1_MCS32)); + + tmpval = tx_agc[RF90_PATH_A] >> 8; + if (mac->mode == WIRELESS_MODE_B) + tmpval = tmpval & 0xff00ffff; + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK11_A_CCK2_11)); + tmpval = tx_agc[RF90_PATH_B] >> 24; + rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK11_A_CCK2_11)); + tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; + rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, + RTXAGC_B_CCK1_55_MCS32)); +} + +static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel, + u32 *ofdmbase, u32 *mcsbase) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 powerBase0, powerBase1; + u8 legacy_pwrdiff = 0, ht20_pwrdiff = 0; + u8 i, powerlevel[2]; + + for (i = 0; i < 2; i++) { + powerlevel[i] = ppowerlevel[i]; + legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1]; + powerBase0 = powerlevel[i] + legacy_pwrdiff; + powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) | + (powerBase0 << 8) | powerBase0; + *(ofdmbase + i) = powerBase0; + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + (" [OFDM power base index rf(%c) = 0x%x]\n", + ((i == 0) ? 'A' : 'B'), *(ofdmbase + i))); + } + for (i = 0; i < 2; i++) { + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { + ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1]; + powerlevel[i] += ht20_pwrdiff; + } + powerBase1 = powerlevel[i]; + powerBase1 = (powerBase1 << 24) | + (powerBase1 << 16) | (powerBase1 << 8) | powerBase1; + *(mcsbase + i) = powerBase1; + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + (" [MCS power base index rf(%c) = 0x%x]\n", + ((i == 0) ? 'A' : 'B'), *(mcsbase + i))); + } +} + +static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, + u8 channel, u8 index, + u32 *powerBase0, + u32 *powerBase1, + u32 *p_outwriteval) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 i, chnlgroup = 0, pwr_diff_limit[4]; + u32 writeVal, customer_limit, rf; + + for (rf = 0; rf < 2; rf++) { + switch (rtlefuse->eeprom_regulatory) { + case 0: + chnlgroup = 0; + writeVal = rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index + (rf ? 8 : 0)] + + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("RTK better performance,writeVal(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeVal)); + break; + case 1: + if (rtlphy->pwrgroup_cnt == 1) + chnlgroup = 0; + if (rtlphy->pwrgroup_cnt >= 3) { + if (channel <= 3) + chnlgroup = 0; + else if (channel >= 4 && channel <= 9) + chnlgroup = 1; + else if (channel > 9) + chnlgroup = 2; + if (rtlphy->current_chan_bw == + HT_CHANNEL_WIDTH_20) + chnlgroup++; + else + chnlgroup += 4; + } + writeVal = rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index + + (rf ? 8 : 0)] + + ((index < 2) ? powerBase0[rf] : + powerBase1[rf]); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Realtek regulatory, 20MHz, " + "writeVal(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeVal)); + break; + case 2: + writeVal = ((index < 2) ? powerBase0[rf] : + powerBase1[rf]); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Better regulatory,writeVal(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeVal)); + break; + case 3: + chnlgroup = 0; + if (rtlphy->current_chan_bw == + HT_CHANNEL_WIDTH_20_40) { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("customer's limit, 40MHzrf(%c) = " + "0x%x\n", ((rf == 0) ? 'A' : 'B'), + rtlefuse->pwrgroup_ht40[rf] + [channel - 1])); + } else { + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("customer's limit, 20MHz rf(%c) = " + "0x%x\n", ((rf == 0) ? 'A' : 'B'), + rtlefuse->pwrgroup_ht20[rf] + [channel - 1])); + } + for (i = 0; i < 4; i++) { + pwr_diff_limit[i] = + (u8) ((rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index + (rf ? 8 : 0)] + & (0x7f << (i * 8))) >> (i * 8)); + if (rtlphy->current_chan_bw == + HT_CHANNEL_WIDTH_20_40) { + if (pwr_diff_limit[i] > + rtlefuse->pwrgroup_ht40[rf] + [channel - 1]) + pwr_diff_limit[i] = rtlefuse-> + pwrgroup_ht40[rf] + [channel - 1]; + } else { + if (pwr_diff_limit[i] > + rtlefuse->pwrgroup_ht20[rf] + [channel - 1]) + pwr_diff_limit[i] = + rtlefuse->pwrgroup_ht20[rf] + [channel - 1]; + } + } + customer_limit = (pwr_diff_limit[3] << 24) | + (pwr_diff_limit[2] << 16) | + (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Customer's limit rf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), customer_limit)); + writeVal = customer_limit + ((index < 2) ? + powerBase0[rf] : powerBase1[rf]); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Customer, writeVal rf(%c)= 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeVal)); + break; + default: + chnlgroup = 0; + writeVal = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] + [index + (rf ? 8 : 0)] + ((index < 2) ? + powerBase0[rf] : powerBase1[rf]); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("RTK better " + "performance, writeValrf(%c) = 0x%x\n", + ((rf == 0) ? 'A' : 'B'), writeVal)); + break; + } + if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_LEVEL1) + writeVal = 0x14141414; + else if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_LEVEL2) + writeVal = 0x00000000; + if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1) + writeVal = writeVal - 0x06060606; + else if (rtlpriv->dm.dynamic_txhighpower_lvl == + TXHIGHPWRLEVEL_BT2) + writeVal = writeVal; + *(p_outwriteval + rf) = writeVal; + } +} + +static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw, + u8 index, u32 *pValue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u16 regoffset_a[6] = { + RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24, + RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04, + RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12 + }; + u16 regoffset_b[6] = { + RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24, + RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04, + RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12 + }; + u8 i, rf, pwr_val[4]; + u32 writeVal; + u16 regoffset; + + for (rf = 0; rf < 2; rf++) { + writeVal = pValue[rf]; + for (i = 0; i < 4; i++) { + pwr_val[i] = (u8)((writeVal & (0x7f << (i * 8))) >> + (i * 8)); + if (pwr_val[i] > RF6052_MAX_TX_PWR) + pwr_val[i] = RF6052_MAX_TX_PWR; + } + writeVal = (pwr_val[3] << 24) | (pwr_val[2] << 16) | + (pwr_val[1] << 8) | pwr_val[0]; + if (rf == 0) + regoffset = regoffset_a[index]; + else + regoffset = regoffset_b[index]; + rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + ("Set 0x%x = %08x\n", regoffset, writeVal)); + if (((get_rf_type(rtlphy) == RF_2T2R) && + (regoffset == RTXAGC_A_MCS15_MCS12 || + regoffset == RTXAGC_B_MCS15_MCS12)) || + ((get_rf_type(rtlphy) != RF_2T2R) && + (regoffset == RTXAGC_A_MCS07_MCS04 || + regoffset == RTXAGC_B_MCS07_MCS04))) { + writeVal = pwr_val[3]; + if (regoffset == RTXAGC_A_MCS15_MCS12 || + regoffset == RTXAGC_A_MCS07_MCS04) + regoffset = 0xc90; + if (regoffset == RTXAGC_B_MCS15_MCS12 || + regoffset == RTXAGC_B_MCS07_MCS04) + regoffset = 0xc98; + for (i = 0; i < 3; i++) { + writeVal = (writeVal > 6) ? (writeVal - 6) : 0; + rtl_write_byte(rtlpriv, (u32)(regoffset + i), + (u8)writeVal); + } + } + } +} + +void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel) +{ + u32 writeVal[2], powerBase0[2], powerBase1[2]; + u8 index = 0; + + rtl92c_phy_get_power_base(hw, ppowerlevel, + channel, &powerBase0[0], &powerBase1[0]); + for (index = 0; index < 6; index++) { + _rtl92c_get_txpower_writeval_by_regulatory(hw, + channel, index, + &powerBase0[0], + &powerBase1[0], + &writeVal[0]); + _rtl92c_write_ofdm_power_reg(hw, index, &writeVal[0]); + } +} + +bool rtl92c_phy_rf6052_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + bool rtstatus = true; + u8 b_reg_hwparafile = 1; + + if (rtlphy->rf_type == RF_1T1R) + rtlphy->num_total_rfpath = 1; + else + rtlphy->num_total_rfpath = 2; + if (b_reg_hwparafile == 1) + rtstatus = _rtl92c_phy_rf6052_config_parafile(hw); + return rtstatus; +} + +static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u32 u4_regvalue = 0; + u8 rfpath; + bool rtstatus = true; + struct bb_reg_def *pphyreg; + + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + pphyreg = &rtlphy->phyreg_def[rfpath]; + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV); + break; + case RF90_PATH_B: + case RF90_PATH_D: + u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16); + break; + } + rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); + udelay(1); + rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); + udelay(1); + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, + B3WIREADDREAALENGTH, 0x0); + udelay(1); + rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); + udelay(1); + switch (rfpath) { + case RF90_PATH_A: + rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, + (enum radio_path) rfpath); + break; + case RF90_PATH_B: + rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, + (enum radio_path) rfpath); + break; + case RF90_PATH_C: + break; + case RF90_PATH_D: + break; + } + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + rtl_set_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV, u4_regvalue); + break; + case RF90_PATH_B: + case RF90_PATH_D: + rtl_set_bbreg(hw, pphyreg->rfintfs, + BRFSI_RFENV << 16, u4_regvalue); + break; + } + if (rtstatus != true) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + ("Radio[%d] Fail!!", rfpath)); + goto phy_rf_cfg_fail; + } + } + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n")); + return rtstatus; +phy_rf_cfg_fail: + return rtstatus; +} -- cgit v1.2.3 From 59187c5b12526a5f53d1a8b91922ce992bc98eef Mon Sep 17 00:00:00 2001 From: George Date: Sat, 19 Feb 2011 16:29:42 -0600 Subject: rtlwifi: rtl8192cu: Add routine table Add rtlwifi/rtl8192cu/table.c. These tables are different than the ones used in rtl8192ce. Signed-off-by: George Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/table.c | 1888 ++++++++++++++++++++++++ 1 file changed, 1888 insertions(+) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/table.c (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/table.c b/drivers/net/wireless/rtlwifi/rtl8192cu/table.c new file mode 100644 index 000000000000..d57ef5e88a9e --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/table.c @@ -0,0 +1,1888 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "table.h" + +u32 RTL8192CUPHY_REG_2TARRAY[RTL8192CUPHY_REG_2TARRAY_LENGTH] = { + 0x024, 0x0011800f, + 0x028, 0x00ffdb83, + 0x800, 0x80040002, + 0x804, 0x00000003, + 0x808, 0x0000fc00, + 0x80c, 0x0000000a, + 0x810, 0x10005388, + 0x814, 0x020c3d10, + 0x818, 0x02200385, + 0x81c, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390004, + 0x828, 0x01000100, + 0x82c, 0x00390004, + 0x830, 0x27272727, + 0x834, 0x27272727, + 0x838, 0x27272727, + 0x83c, 0x27272727, + 0x840, 0x00010000, + 0x844, 0x00010000, + 0x848, 0x27272727, + 0x84c, 0x27272727, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569a569a, + 0x85c, 0x0c1b25a4, + 0x860, 0x66e60230, + 0x864, 0x061f0130, + 0x868, 0x27272727, + 0x86c, 0x2b2b2b27, + 0x870, 0x07000700, + 0x874, 0x22184000, + 0x878, 0x08080808, + 0x87c, 0x00000000, + 0x880, 0xc0083070, + 0x884, 0x000004d5, + 0x888, 0x00000000, + 0x88c, 0xcc0000c0, + 0x890, 0x00000800, + 0x894, 0xfffffffe, + 0x898, 0x40302010, + 0x89c, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90c, 0x81121313, + 0xa00, 0x00d047c8, + 0xa04, 0x80ff000c, + 0xa08, 0x8c838300, + 0xa0c, 0x2e68120f, + 0xa10, 0x9500bb78, + 0xa14, 0x11144028, + 0xa18, 0x00881117, + 0xa1c, 0x89140f00, + 0xa20, 0x1a1b0000, + 0xa24, 0x090e1317, + 0xa28, 0x00000204, + 0xa2c, 0x00d30000, + 0xa70, 0x101fbf00, + 0xa74, 0x00000007, + 0xc00, 0x48071d40, + 0xc04, 0x03a05633, + 0xc08, 0x000000e4, + 0xc0c, 0x6c6c6c6c, + 0xc10, 0x08800000, + 0xc14, 0x40000100, + 0xc18, 0x08800000, + 0xc1c, 0x40000100, + 0xc20, 0x00000000, + 0xc24, 0x00000000, + 0xc28, 0x00000000, + 0xc2c, 0x00000000, + 0xc30, 0x69e9ac44, + 0xc34, 0x469652cf, + 0xc38, 0x49795994, + 0xc3c, 0x0a97971c, + 0xc40, 0x1f7c403f, + 0xc44, 0x000100b7, + 0xc48, 0xec020107, + 0xc4c, 0x007f037f, + 0xc50, 0x6954341e, + 0xc54, 0x43bc0094, + 0xc58, 0x6954341e, + 0xc5c, 0x433c0094, + 0xc60, 0x00000000, + 0xc64, 0x5116848b, + 0xc68, 0x47c00bff, + 0xc6c, 0x00000036, + 0xc70, 0x2c7f000d, + 0xc74, 0x0186115b, + 0xc78, 0x0000001f, + 0xc7c, 0x00b99612, + 0xc80, 0x40000100, + 0xc84, 0x20f60000, + 0xc88, 0x40000100, + 0xc8c, 0x20200000, + 0xc90, 0x00121820, + 0xc94, 0x00000000, + 0xc98, 0x00121820, + 0xc9c, 0x00007f7f, + 0xca0, 0x00000000, + 0xca4, 0x00000080, + 0xca8, 0x00000000, + 0xcac, 0x00000000, + 0xcb0, 0x00000000, + 0xcb4, 0x00000000, + 0xcb8, 0x00000000, + 0xcbc, 0x28000000, + 0xcc0, 0x00000000, + 0xcc4, 0x00000000, + 0xcc8, 0x00000000, + 0xccc, 0x00000000, + 0xcd0, 0x00000000, + 0xcd4, 0x00000000, + 0xcd8, 0x64b22427, + 0xcdc, 0x00766932, + 0xce0, 0x00222222, + 0xce4, 0x00000000, + 0xce8, 0x37644302, + 0xcec, 0x2f97d40c, + 0xd00, 0x00080740, + 0xd04, 0x00020403, + 0xd08, 0x0000907f, + 0xd0c, 0x20010201, + 0xd10, 0xa0633333, + 0xd14, 0x3333bc43, + 0xd18, 0x7a8f5b6b, + 0xd2c, 0xcc979975, + 0xd30, 0x00000000, + 0xd34, 0x80608000, + 0xd38, 0x00000000, + 0xd3c, 0x00027293, + 0xd40, 0x00000000, + 0xd44, 0x00000000, + 0xd48, 0x00000000, + 0xd4c, 0x00000000, + 0xd50, 0x6437140a, + 0xd54, 0x00000000, + 0xd58, 0x00000000, + 0xd5c, 0x30032064, + 0xd60, 0x4653de68, + 0xd64, 0x04518a3c, + 0xd68, 0x00002101, + 0xd6c, 0x2a201c16, + 0xd70, 0x1812362e, + 0xd74, 0x322c2220, + 0xd78, 0x000e3c24, + 0xe00, 0x2a2a2a2a, + 0xe04, 0x2a2a2a2a, + 0xe08, 0x03902a2a, + 0xe10, 0x2a2a2a2a, + 0xe14, 0x2a2a2a2a, + 0xe18, 0x2a2a2a2a, + 0xe1c, 0x2a2a2a2a, + 0xe28, 0x00000000, + 0xe30, 0x1000dc1f, + 0xe34, 0x10008c1f, + 0xe38, 0x02140102, + 0xe3c, 0x681604c2, + 0xe40, 0x01007c00, + 0xe44, 0x01004800, + 0xe48, 0xfb000000, + 0xe4c, 0x000028d1, + 0xe50, 0x1000dc1f, + 0xe54, 0x10008c1f, + 0xe58, 0x02140102, + 0xe5c, 0x28160d05, + 0xe60, 0x00000010, + 0xe68, 0x001b25a4, + 0xe6c, 0x63db25a4, + 0xe70, 0x63db25a4, + 0xe74, 0x0c1b25a4, + 0xe78, 0x0c1b25a4, + 0xe7c, 0x0c1b25a4, + 0xe80, 0x0c1b25a4, + 0xe84, 0x63db25a4, + 0xe88, 0x0c1b25a4, + 0xe8c, 0x63db25a4, + 0xed0, 0x63db25a4, + 0xed4, 0x63db25a4, + 0xed8, 0x63db25a4, + 0xedc, 0x001b25a4, + 0xee0, 0x001b25a4, + 0xeec, 0x6fdb25a4, + 0xf14, 0x00000003, + 0xf4c, 0x00000000, + 0xf00, 0x00000300, +}; + +u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH] = { + 0x024, 0x0011800f, + 0x028, 0x00ffdb83, + 0x800, 0x80040000, + 0x804, 0x00000001, + 0x808, 0x0000fc00, + 0x80c, 0x0000000a, + 0x810, 0x10005388, + 0x814, 0x020c3d10, + 0x818, 0x02200385, + 0x81c, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390004, + 0x828, 0x00000000, + 0x82c, 0x00000000, + 0x830, 0x00000000, + 0x834, 0x00000000, + 0x838, 0x00000000, + 0x83c, 0x00000000, + 0x840, 0x00010000, + 0x844, 0x00000000, + 0x848, 0x00000000, + 0x84c, 0x00000000, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569a569a, + 0x85c, 0x001b25a4, + 0x860, 0x66e60230, + 0x864, 0x061f0130, + 0x868, 0x00000000, + 0x86c, 0x32323200, + 0x870, 0x07000700, + 0x874, 0x22004000, + 0x878, 0x00000808, + 0x87c, 0x00000000, + 0x880, 0xc0083070, + 0x884, 0x000004d5, + 0x888, 0x00000000, + 0x88c, 0xccc000c0, + 0x890, 0x00000800, + 0x894, 0xfffffffe, + 0x898, 0x40302010, + 0x89c, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90c, 0x81121111, + 0xa00, 0x00d047c8, + 0xa04, 0x80ff000c, + 0xa08, 0x8c838300, + 0xa0c, 0x2e68120f, + 0xa10, 0x9500bb78, + 0xa14, 0x11144028, + 0xa18, 0x00881117, + 0xa1c, 0x89140f00, + 0xa20, 0x1a1b0000, + 0xa24, 0x090e1317, + 0xa28, 0x00000204, + 0xa2c, 0x00d30000, + 0xa70, 0x101fbf00, + 0xa74, 0x00000007, + 0xc00, 0x48071d40, + 0xc04, 0x03a05611, + 0xc08, 0x000000e4, + 0xc0c, 0x6c6c6c6c, + 0xc10, 0x08800000, + 0xc14, 0x40000100, + 0xc18, 0x08800000, + 0xc1c, 0x40000100, + 0xc20, 0x00000000, + 0xc24, 0x00000000, + 0xc28, 0x00000000, + 0xc2c, 0x00000000, + 0xc30, 0x69e9ac44, + 0xc34, 0x469652cf, + 0xc38, 0x49795994, + 0xc3c, 0x0a97971c, + 0xc40, 0x1f7c403f, + 0xc44, 0x000100b7, + 0xc48, 0xec020107, + 0xc4c, 0x007f037f, + 0xc50, 0x6954341e, + 0xc54, 0x43bc0094, + 0xc58, 0x6954341e, + 0xc5c, 0x433c0094, + 0xc60, 0x00000000, + 0xc64, 0x5116848b, + 0xc68, 0x47c00bff, + 0xc6c, 0x00000036, + 0xc70, 0x2c7f000d, + 0xc74, 0x018610db, + 0xc78, 0x0000001f, + 0xc7c, 0x00b91612, + 0xc80, 0x40000100, + 0xc84, 0x20f60000, + 0xc88, 0x40000100, + 0xc8c, 0x20200000, + 0xc90, 0x00121820, + 0xc94, 0x00000000, + 0xc98, 0x00121820, + 0xc9c, 0x00007f7f, + 0xca0, 0x00000000, + 0xca4, 0x00000080, + 0xca8, 0x00000000, + 0xcac, 0x00000000, + 0xcb0, 0x00000000, + 0xcb4, 0x00000000, + 0xcb8, 0x00000000, + 0xcbc, 0x28000000, + 0xcc0, 0x00000000, + 0xcc4, 0x00000000, + 0xcc8, 0x00000000, + 0xccc, 0x00000000, + 0xcd0, 0x00000000, + 0xcd4, 0x00000000, + 0xcd8, 0x64b22427, + 0xcdc, 0x00766932, + 0xce0, 0x00222222, + 0xce4, 0x00000000, + 0xce8, 0x37644302, + 0xcec, 0x2f97d40c, + 0xd00, 0x00080740, + 0xd04, 0x00020401, + 0xd08, 0x0000907f, + 0xd0c, 0x20010201, + 0xd10, 0xa0633333, + 0xd14, 0x3333bc43, + 0xd18, 0x7a8f5b6b, + 0xd2c, 0xcc979975, + 0xd30, 0x00000000, + 0xd34, 0x80608000, + 0xd38, 0x00000000, + 0xd3c, 0x00027293, + 0xd40, 0x00000000, + 0xd44, 0x00000000, + 0xd48, 0x00000000, + 0xd4c, 0x00000000, + 0xd50, 0x6437140a, + 0xd54, 0x00000000, + 0xd58, 0x00000000, + 0xd5c, 0x30032064, + 0xd60, 0x4653de68, + 0xd64, 0x04518a3c, + 0xd68, 0x00002101, + 0xd6c, 0x2a201c16, + 0xd70, 0x1812362e, + 0xd74, 0x322c2220, + 0xd78, 0x000e3c24, + 0xe00, 0x2a2a2a2a, + 0xe04, 0x2a2a2a2a, + 0xe08, 0x03902a2a, + 0xe10, 0x2a2a2a2a, + 0xe14, 0x2a2a2a2a, + 0xe18, 0x2a2a2a2a, + 0xe1c, 0x2a2a2a2a, + 0xe28, 0x00000000, + 0xe30, 0x1000dc1f, + 0xe34, 0x10008c1f, + 0xe38, 0x02140102, + 0xe3c, 0x681604c2, + 0xe40, 0x01007c00, + 0xe44, 0x01004800, + 0xe48, 0xfb000000, + 0xe4c, 0x000028d1, + 0xe50, 0x1000dc1f, + 0xe54, 0x10008c1f, + 0xe58, 0x02140102, + 0xe5c, 0x28160d05, + 0xe60, 0x00000008, + 0xe68, 0x001b25a4, + 0xe6c, 0x631b25a0, + 0xe70, 0x631b25a0, + 0xe74, 0x081b25a0, + 0xe78, 0x081b25a0, + 0xe7c, 0x081b25a0, + 0xe80, 0x081b25a0, + 0xe84, 0x631b25a0, + 0xe88, 0x081b25a0, + 0xe8c, 0x631b25a0, + 0xed0, 0x631b25a0, + 0xed4, 0x631b25a0, + 0xed8, 0x631b25a0, + 0xedc, 0x001b25a0, + 0xee0, 0x001b25a0, + 0xeec, 0x6b1b25a0, + 0xf14, 0x00000003, + 0xf4c, 0x00000000, + 0xf00, 0x00000300, +}; + +u32 RTL8192CUPHY_REG_ARRAY_PG[RTL8192CUPHY_REG_ARRAY_PGLENGTH] = { + 0xe00, 0xffffffff, 0x07090c0c, + 0xe04, 0xffffffff, 0x01020405, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x0b0c0c0e, + 0xe14, 0xffffffff, 0x01030506, + 0xe18, 0xffffffff, 0x0b0c0d0e, + 0xe1c, 0xffffffff, 0x01030509, + 0x830, 0xffffffff, 0x07090c0c, + 0x834, 0xffffffff, 0x01020405, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x0b0c0d0e, + 0x848, 0xffffffff, 0x01030509, + 0x84c, 0xffffffff, 0x0b0c0d0e, + 0x868, 0xffffffff, 0x01030509, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x06060606, + 0xe14, 0xffffffff, 0x00020406, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x06060606, + 0x848, 0xffffffff, 0x00020406, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x04040404, + 0xe04, 0xffffffff, 0x00020204, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x04040404, + 0x834, 0xffffffff, 0x00020204, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, +}; + +u32 RTL8192CURADIOA_2TARRAY[RTL8192CURADIOA_2TARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00031284, + 0x002, 0x00098000, + 0x003, 0x00018c63, + 0x004, 0x000210e7, + 0x009, 0x0002044f, + 0x00a, 0x0001adb1, + 0x00b, 0x00054867, + 0x00c, 0x0008992e, + 0x00d, 0x0000e52c, + 0x00e, 0x00039ce7, + 0x00f, 0x00000451, + 0x019, 0x00000000, + 0x01a, 0x00010255, + 0x01b, 0x00060a00, + 0x01c, 0x000fc378, + 0x01d, 0x000a1250, + 0x01e, 0x0004445f, + 0x01f, 0x00080001, + 0x020, 0x0000b614, + 0x021, 0x0006c000, + 0x022, 0x00000000, + 0x023, 0x00001558, + 0x024, 0x00000060, + 0x025, 0x00000483, + 0x026, 0x0004f000, + 0x027, 0x000ec7d9, + 0x028, 0x000577c0, + 0x029, 0x00004783, + 0x02a, 0x00000001, + 0x02b, 0x00021334, + 0x02a, 0x00000000, + 0x02b, 0x00000054, + 0x02a, 0x00000001, + 0x02b, 0x00000808, + 0x02b, 0x00053333, + 0x02c, 0x0000000c, + 0x02a, 0x00000002, + 0x02b, 0x00000808, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000003, + 0x02b, 0x00000808, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000004, + 0x02b, 0x00000808, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000005, + 0x02b, 0x00000808, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x00000006, + 0x02b, 0x00000709, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000007, + 0x02b, 0x00000709, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000008, + 0x02b, 0x0000060a, + 0x02b, 0x0004b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000009, + 0x02b, 0x0000060a, + 0x02b, 0x00053333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000a, + 0x02b, 0x0000060a, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000b, + 0x02b, 0x0000060a, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000c, + 0x02b, 0x0000060a, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000d, + 0x02b, 0x0000060a, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000e, + 0x02b, 0x0000050b, + 0x02b, 0x00066666, + 0x02c, 0x0000001a, + 0x02a, 0x000e0000, + 0x010, 0x0004000f, + 0x011, 0x000e31fc, + 0x010, 0x0006000f, + 0x011, 0x000ff9f8, + 0x010, 0x0002000f, + 0x011, 0x000203f9, + 0x010, 0x0003000f, + 0x011, 0x000ff500, + 0x010, 0x00000000, + 0x011, 0x00000000, + 0x010, 0x0008000f, + 0x011, 0x0003f100, + 0x010, 0x0009000f, + 0x011, 0x00023100, + 0x012, 0x00032000, + 0x012, 0x00071000, + 0x012, 0x000b0000, + 0x012, 0x000fc000, + 0x013, 0x000287af, + 0x013, 0x000244b7, + 0x013, 0x000204ab, + 0x013, 0x0001c49f, + 0x013, 0x00018493, + 0x013, 0x00014297, + 0x013, 0x00010295, + 0x013, 0x0000c298, + 0x013, 0x0000819c, + 0x013, 0x000040a8, + 0x013, 0x0000001c, + 0x014, 0x0001944c, + 0x014, 0x00059444, + 0x014, 0x0009944c, + 0x014, 0x000d9444, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x015, 0x000cf424, + 0x016, 0x000e0330, + 0x016, 0x000a0330, + 0x016, 0x00060330, + 0x016, 0x00020330, + 0x000, 0x00010159, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00044457, + 0x01f, 0x00080000, + 0x000, 0x00030159, +}; + +u32 RTL8192CU_RADIOB_2TARRAY[RTL8192CURADIOB_2TARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00031284, + 0x002, 0x00098000, + 0x003, 0x00018c63, + 0x004, 0x000210e7, + 0x009, 0x0002044f, + 0x00a, 0x0001adb1, + 0x00b, 0x00054867, + 0x00c, 0x0008992e, + 0x00d, 0x0000e52c, + 0x00e, 0x00039ce7, + 0x00f, 0x00000451, + 0x012, 0x00032000, + 0x012, 0x00071000, + 0x012, 0x000b0000, + 0x012, 0x000fc000, + 0x013, 0x000287af, + 0x013, 0x000244b7, + 0x013, 0x000204ab, + 0x013, 0x0001c49f, + 0x013, 0x00018493, + 0x013, 0x00014297, + 0x013, 0x00010295, + 0x013, 0x0000c298, + 0x013, 0x0000819c, + 0x013, 0x000040a8, + 0x013, 0x0000001c, + 0x014, 0x0001944c, + 0x014, 0x00059444, + 0x014, 0x0009944c, + 0x014, 0x000d9444, + 0x015, 0x0000f424, + 0x015, 0x0004f424, + 0x015, 0x0008f424, + 0x015, 0x000cf424, + 0x016, 0x000e0330, + 0x016, 0x000a0330, + 0x016, 0x00060330, + 0x016, 0x00020330, +}; + +u32 RTL8192CU_RADIOA_1TARRAY[RTL8192CURADIOA_1TARRAYLENGTH] = { + 0x000, 0x00030159, + 0x001, 0x00031284, + 0x002, 0x00098000, + 0x003, 0x00018c63, + 0x004, 0x000210e7, + 0x009, 0x0002044f, + 0x00a, 0x0001adb1, + 0x00b, 0x00054867, + 0x00c, 0x0008992e, + 0x00d, 0x0000e52c, + 0x00e, 0x00039ce7, + 0x00f, 0x00000451, + 0x019, 0x00000000, + 0x01a, 0x00010255, + 0x01b, 0x00060a00, + 0x01c, 0x000fc378, + 0x01d, 0x000a1250, + 0x01e, 0x0004445f, + 0x01f, 0x00080001, + 0x020, 0x0000b614, + 0x021, 0x0006c000, + 0x022, 0x00000000, + 0x023, 0x00001558, + 0x024, 0x00000060, + 0x025, 0x00000483, + 0x026, 0x0004f000, + 0x027, 0x000ec7d9, + 0x028, 0x000577c0, + 0x029, 0x00004783, + 0x02a, 0x00000001, + 0x02b, 0x00021334, + 0x02a, 0x00000000, + 0x02b, 0x00000054, + 0x02a, 0x00000001, + 0x02b, 0x00000808, + 0x02b, 0x00053333, + 0x02c, 0x0000000c, + 0x02a, 0x00000002, + 0x02b, 0x00000808, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000003, + 0x02b, 0x00000808, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000004, + 0x02b, 0x00000808, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000005, + 0x02b, 0x00000808, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x00000006, + 0x02b, 0x00000709, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000007, + 0x02b, 0x00000709, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000008, + 0x02b, 0x0000060a, + 0x02b, 0x0004b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000009, + 0x02b, 0x0000060a, + 0x02b, 0x00053333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000a, + 0x02b, 0x0000060a, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000b, + 0x02b, 0x0000060a, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000c, + 0x02b, 0x0000060a, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000d, + 0x02b, 0x0000060a, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000e, + 0x02b, 0x0000050b, + 0x02b, 0x00066666, + 0x02c, 0x0000001a, + 0x02a, 0x000e0000, + 0x010, 0x0004000f, + 0x011, 0x000e31fc, + 0x010, 0x0006000f, + 0x011, 0x000ff9f8, + 0x010, 0x0002000f, + 0x011, 0x000203f9, + 0x010, 0x0003000f, + 0x011, 0x000ff500, + 0x010, 0x00000000, + 0x011, 0x00000000, + 0x010, 0x0008000f, + 0x011, 0x0003f100, + 0x010, 0x0009000f, + 0x011, 0x00023100, + 0x012, 0x00032000, + 0x012, 0x00071000, + 0x012, 0x000b0000, + 0x012, 0x000fc000, + 0x013, 0x000287b3, + 0x013, 0x000244b7, + 0x013, 0x000204ab, + 0x013, 0x0001c49f, + 0x013, 0x00018493, + 0x013, 0x0001429b, + 0x013, 0x00010299, + 0x013, 0x0000c29c, + 0x013, 0x000081a0, + 0x013, 0x000040ac, + 0x013, 0x00000020, + 0x014, 0x0001944c, + 0x014, 0x00059444, + 0x014, 0x0009944c, + 0x014, 0x000d9444, + 0x015, 0x0000f405, + 0x015, 0x0004f405, + 0x015, 0x0008f405, + 0x015, 0x000cf405, + 0x016, 0x000e0330, + 0x016, 0x000a0330, + 0x016, 0x00060330, + 0x016, 0x00020330, + 0x000, 0x00010159, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00044457, + 0x01f, 0x00080000, + 0x000, 0x00030159, +}; + +u32 RTL8192CU_RADIOB_1TARRAY[RTL8192CURADIOB_1TARRAYLENGTH] = { + 0x0, +}; + +u32 RTL8192CUMAC_2T_ARRAY[RTL8192CUMAC_2T_ARRAYLENGTH] = { + 0x420, 0x00000080, + 0x423, 0x00000000, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000004, + 0x435, 0x00000005, + 0x436, 0x00000006, + 0x437, 0x00000007, + 0x438, 0x00000000, + 0x439, 0x00000000, + 0x43a, 0x00000000, + 0x43b, 0x00000001, + 0x43c, 0x00000004, + 0x43d, 0x00000005, + 0x43e, 0x00000006, + 0x43f, 0x00000007, + 0x440, 0x0000005d, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000015, + 0x445, 0x000000f0, + 0x446, 0x0000000f, + 0x447, 0x00000000, + 0x458, 0x00000041, + 0x459, 0x000000a8, + 0x45a, 0x00000072, + 0x45b, 0x000000b9, + 0x460, 0x00000066, + 0x461, 0x00000066, + 0x462, 0x00000008, + 0x463, 0x00000003, + 0x4c8, 0x000000ff, + 0x4c9, 0x00000008, + 0x4cc, 0x000000ff, + 0x4cd, 0x000000ff, + 0x4ce, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000a2, + 0x502, 0x0000002f, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000a3, + 0x506, 0x0000005e, + 0x507, 0x00000000, + 0x508, 0x0000002b, + 0x509, 0x000000a4, + 0x50a, 0x0000005e, + 0x50b, 0x00000000, + 0x50c, 0x0000004f, + 0x50d, 0x000000a4, + 0x50e, 0x00000000, + 0x50f, 0x00000000, + 0x512, 0x0000001c, + 0x514, 0x0000000a, + 0x515, 0x00000010, + 0x516, 0x0000000a, + 0x517, 0x00000010, + 0x51a, 0x00000016, + 0x524, 0x0000000f, + 0x525, 0x0000004f, + 0x546, 0x00000040, + 0x547, 0x00000000, + 0x550, 0x00000010, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55a, 0x00000002, + 0x55d, 0x000000ff, + 0x605, 0x00000030, + 0x608, 0x0000000e, + 0x609, 0x0000002a, + 0x652, 0x00000020, + 0x63c, 0x0000000a, + 0x63d, 0x0000000e, + 0x63e, 0x0000000a, + 0x63f, 0x0000000e, + 0x66e, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70a, 0x00000065, + 0x70b, 0x00000087, +}; + +u32 RTL8192CUAGCTAB_2TARRAY[RTL8192CUAGCTAB_2TARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7b020001, + 0xc78, 0x7b030001, + 0xc78, 0x7b040001, + 0xc78, 0x7b050001, + 0xc78, 0x7a060001, + 0xc78, 0x79070001, + 0xc78, 0x78080001, + 0xc78, 0x77090001, + 0xc78, 0x760a0001, + 0xc78, 0x750b0001, + 0xc78, 0x740c0001, + 0xc78, 0x730d0001, + 0xc78, 0x720e0001, + 0xc78, 0x710f0001, + 0xc78, 0x70100001, + 0xc78, 0x6f110001, + 0xc78, 0x6e120001, + 0xc78, 0x6d130001, + 0xc78, 0x6c140001, + 0xc78, 0x6b150001, + 0xc78, 0x6a160001, + 0xc78, 0x69170001, + 0xc78, 0x68180001, + 0xc78, 0x67190001, + 0xc78, 0x661a0001, + 0xc78, 0x651b0001, + 0xc78, 0x641c0001, + 0xc78, 0x631d0001, + 0xc78, 0x621e0001, + 0xc78, 0x611f0001, + 0xc78, 0x60200001, + 0xc78, 0x49210001, + 0xc78, 0x48220001, + 0xc78, 0x47230001, + 0xc78, 0x46240001, + 0xc78, 0x45250001, + 0xc78, 0x44260001, + 0xc78, 0x43270001, + 0xc78, 0x42280001, + 0xc78, 0x41290001, + 0xc78, 0x402a0001, + 0xc78, 0x262b0001, + 0xc78, 0x252c0001, + 0xc78, 0x242d0001, + 0xc78, 0x232e0001, + 0xc78, 0x222f0001, + 0xc78, 0x21300001, + 0xc78, 0x20310001, + 0xc78, 0x06320001, + 0xc78, 0x05330001, + 0xc78, 0x04340001, + 0xc78, 0x03350001, + 0xc78, 0x02360001, + 0xc78, 0x01370001, + 0xc78, 0x00380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x7b400001, + 0xc78, 0x7b410001, + 0xc78, 0x7b420001, + 0xc78, 0x7b430001, + 0xc78, 0x7b440001, + 0xc78, 0x7b450001, + 0xc78, 0x7a460001, + 0xc78, 0x79470001, + 0xc78, 0x78480001, + 0xc78, 0x77490001, + 0xc78, 0x764a0001, + 0xc78, 0x754b0001, + 0xc78, 0x744c0001, + 0xc78, 0x734d0001, + 0xc78, 0x724e0001, + 0xc78, 0x714f0001, + 0xc78, 0x70500001, + 0xc78, 0x6f510001, + 0xc78, 0x6e520001, + 0xc78, 0x6d530001, + 0xc78, 0x6c540001, + 0xc78, 0x6b550001, + 0xc78, 0x6a560001, + 0xc78, 0x69570001, + 0xc78, 0x68580001, + 0xc78, 0x67590001, + 0xc78, 0x665a0001, + 0xc78, 0x655b0001, + 0xc78, 0x645c0001, + 0xc78, 0x635d0001, + 0xc78, 0x625e0001, + 0xc78, 0x615f0001, + 0xc78, 0x60600001, + 0xc78, 0x49610001, + 0xc78, 0x48620001, + 0xc78, 0x47630001, + 0xc78, 0x46640001, + 0xc78, 0x45650001, + 0xc78, 0x44660001, + 0xc78, 0x43670001, + 0xc78, 0x42680001, + 0xc78, 0x41690001, + 0xc78, 0x406a0001, + 0xc78, 0x266b0001, + 0xc78, 0x256c0001, + 0xc78, 0x246d0001, + 0xc78, 0x236e0001, + 0xc78, 0x226f0001, + 0xc78, 0x21700001, + 0xc78, 0x20710001, + 0xc78, 0x06720001, + 0xc78, 0x05730001, + 0xc78, 0x04740001, + 0xc78, 0x03750001, + 0xc78, 0x02760001, + 0xc78, 0x01770001, + 0xc78, 0x00780001, + 0xc78, 0x00790001, + 0xc78, 0x007a0001, + 0xc78, 0x007b0001, + 0xc78, 0x007c0001, + 0xc78, 0x007d0001, + 0xc78, 0x007e0001, + 0xc78, 0x007f0001, + 0xc78, 0x3800001e, + 0xc78, 0x3801001e, + 0xc78, 0x3802001e, + 0xc78, 0x3803001e, + 0xc78, 0x3804001e, + 0xc78, 0x3805001e, + 0xc78, 0x3806001e, + 0xc78, 0x3807001e, + 0xc78, 0x3808001e, + 0xc78, 0x3c09001e, + 0xc78, 0x3e0a001e, + 0xc78, 0x400b001e, + 0xc78, 0x440c001e, + 0xc78, 0x480d001e, + 0xc78, 0x4c0e001e, + 0xc78, 0x500f001e, + 0xc78, 0x5210001e, + 0xc78, 0x5611001e, + 0xc78, 0x5a12001e, + 0xc78, 0x5e13001e, + 0xc78, 0x6014001e, + 0xc78, 0x6015001e, + 0xc78, 0x6016001e, + 0xc78, 0x6217001e, + 0xc78, 0x6218001e, + 0xc78, 0x6219001e, + 0xc78, 0x621a001e, + 0xc78, 0x621b001e, + 0xc78, 0x621c001e, + 0xc78, 0x621d001e, + 0xc78, 0x621e001e, + 0xc78, 0x621f001e, +}; + +u32 RTL8192CUAGCTAB_1TARRAY[RTL8192CUAGCTAB_1TARRAYLENGTH] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7b020001, + 0xc78, 0x7b030001, + 0xc78, 0x7b040001, + 0xc78, 0x7b050001, + 0xc78, 0x7a060001, + 0xc78, 0x79070001, + 0xc78, 0x78080001, + 0xc78, 0x77090001, + 0xc78, 0x760a0001, + 0xc78, 0x750b0001, + 0xc78, 0x740c0001, + 0xc78, 0x730d0001, + 0xc78, 0x720e0001, + 0xc78, 0x710f0001, + 0xc78, 0x70100001, + 0xc78, 0x6f110001, + 0xc78, 0x6e120001, + 0xc78, 0x6d130001, + 0xc78, 0x6c140001, + 0xc78, 0x6b150001, + 0xc78, 0x6a160001, + 0xc78, 0x69170001, + 0xc78, 0x68180001, + 0xc78, 0x67190001, + 0xc78, 0x661a0001, + 0xc78, 0x651b0001, + 0xc78, 0x641c0001, + 0xc78, 0x631d0001, + 0xc78, 0x621e0001, + 0xc78, 0x611f0001, + 0xc78, 0x60200001, + 0xc78, 0x49210001, + 0xc78, 0x48220001, + 0xc78, 0x47230001, + 0xc78, 0x46240001, + 0xc78, 0x45250001, + 0xc78, 0x44260001, + 0xc78, 0x43270001, + 0xc78, 0x42280001, + 0xc78, 0x41290001, + 0xc78, 0x402a0001, + 0xc78, 0x262b0001, + 0xc78, 0x252c0001, + 0xc78, 0x242d0001, + 0xc78, 0x232e0001, + 0xc78, 0x222f0001, + 0xc78, 0x21300001, + 0xc78, 0x20310001, + 0xc78, 0x06320001, + 0xc78, 0x05330001, + 0xc78, 0x04340001, + 0xc78, 0x03350001, + 0xc78, 0x02360001, + 0xc78, 0x01370001, + 0xc78, 0x00380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x7b400001, + 0xc78, 0x7b410001, + 0xc78, 0x7b420001, + 0xc78, 0x7b430001, + 0xc78, 0x7b440001, + 0xc78, 0x7b450001, + 0xc78, 0x7a460001, + 0xc78, 0x79470001, + 0xc78, 0x78480001, + 0xc78, 0x77490001, + 0xc78, 0x764a0001, + 0xc78, 0x754b0001, + 0xc78, 0x744c0001, + 0xc78, 0x734d0001, + 0xc78, 0x724e0001, + 0xc78, 0x714f0001, + 0xc78, 0x70500001, + 0xc78, 0x6f510001, + 0xc78, 0x6e520001, + 0xc78, 0x6d530001, + 0xc78, 0x6c540001, + 0xc78, 0x6b550001, + 0xc78, 0x6a560001, + 0xc78, 0x69570001, + 0xc78, 0x68580001, + 0xc78, 0x67590001, + 0xc78, 0x665a0001, + 0xc78, 0x655b0001, + 0xc78, 0x645c0001, + 0xc78, 0x635d0001, + 0xc78, 0x625e0001, + 0xc78, 0x615f0001, + 0xc78, 0x60600001, + 0xc78, 0x49610001, + 0xc78, 0x48620001, + 0xc78, 0x47630001, + 0xc78, 0x46640001, + 0xc78, 0x45650001, + 0xc78, 0x44660001, + 0xc78, 0x43670001, + 0xc78, 0x42680001, + 0xc78, 0x41690001, + 0xc78, 0x406a0001, + 0xc78, 0x266b0001, + 0xc78, 0x256c0001, + 0xc78, 0x246d0001, + 0xc78, 0x236e0001, + 0xc78, 0x226f0001, + 0xc78, 0x21700001, + 0xc78, 0x20710001, + 0xc78, 0x06720001, + 0xc78, 0x05730001, + 0xc78, 0x04740001, + 0xc78, 0x03750001, + 0xc78, 0x02760001, + 0xc78, 0x01770001, + 0xc78, 0x00780001, + 0xc78, 0x00790001, + 0xc78, 0x007a0001, + 0xc78, 0x007b0001, + 0xc78, 0x007c0001, + 0xc78, 0x007d0001, + 0xc78, 0x007e0001, + 0xc78, 0x007f0001, + 0xc78, 0x3800001e, + 0xc78, 0x3801001e, + 0xc78, 0x3802001e, + 0xc78, 0x3803001e, + 0xc78, 0x3804001e, + 0xc78, 0x3805001e, + 0xc78, 0x3806001e, + 0xc78, 0x3807001e, + 0xc78, 0x3808001e, + 0xc78, 0x3c09001e, + 0xc78, 0x3e0a001e, + 0xc78, 0x400b001e, + 0xc78, 0x440c001e, + 0xc78, 0x480d001e, + 0xc78, 0x4c0e001e, + 0xc78, 0x500f001e, + 0xc78, 0x5210001e, + 0xc78, 0x5611001e, + 0xc78, 0x5a12001e, + 0xc78, 0x5e13001e, + 0xc78, 0x6014001e, + 0xc78, 0x6015001e, + 0xc78, 0x6016001e, + 0xc78, 0x6217001e, + 0xc78, 0x6218001e, + 0xc78, 0x6219001e, + 0xc78, 0x621a001e, + 0xc78, 0x621b001e, + 0xc78, 0x621c001e, + 0xc78, 0x621d001e, + 0xc78, 0x621e001e, + 0xc78, 0x621f001e, +}; + +u32 RTL8192CUPHY_REG_1T_HPArray[RTL8192CUPHY_REG_1T_HPArrayLength] = { + 0x024, 0x0011800f, + 0x028, 0x00ffdb83, + 0x040, 0x000c0004, + 0x800, 0x80040000, + 0x804, 0x00000001, + 0x808, 0x0000fc00, + 0x80c, 0x0000000a, + 0x810, 0x10005388, + 0x814, 0x020c3d10, + 0x818, 0x02200385, + 0x81c, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390204, + 0x828, 0x00000000, + 0x82c, 0x00000000, + 0x830, 0x00000000, + 0x834, 0x00000000, + 0x838, 0x00000000, + 0x83c, 0x00000000, + 0x840, 0x00010000, + 0x844, 0x00000000, + 0x848, 0x00000000, + 0x84c, 0x00000000, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569a569a, + 0x85c, 0x001b25a4, + 0x860, 0x66e60230, + 0x864, 0x061f0130, + 0x868, 0x00000000, + 0x86c, 0x20202000, + 0x870, 0x03000300, + 0x874, 0x22004000, + 0x878, 0x00000808, + 0x87c, 0x00ffc3f1, + 0x880, 0xc0083070, + 0x884, 0x000004d5, + 0x888, 0x00000000, + 0x88c, 0xccc000c0, + 0x890, 0x00000800, + 0x894, 0xfffffffe, + 0x898, 0x40302010, + 0x89c, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90c, 0x81121111, + 0xa00, 0x00d047c8, + 0xa04, 0x80ff000c, + 0xa08, 0x8c838300, + 0xa0c, 0x2e68120f, + 0xa10, 0x9500bb78, + 0xa14, 0x11144028, + 0xa18, 0x00881117, + 0xa1c, 0x89140f00, + 0xa20, 0x15160000, + 0xa24, 0x070b0f12, + 0xa28, 0x00000104, + 0xa2c, 0x00d30000, + 0xa70, 0x101fbf00, + 0xa74, 0x00000007, + 0xc00, 0x48071d40, + 0xc04, 0x03a05611, + 0xc08, 0x000000e4, + 0xc0c, 0x6c6c6c6c, + 0xc10, 0x08800000, + 0xc14, 0x40000100, + 0xc18, 0x08800000, + 0xc1c, 0x40000100, + 0xc20, 0x00000000, + 0xc24, 0x00000000, + 0xc28, 0x00000000, + 0xc2c, 0x00000000, + 0xc30, 0x69e9ac44, + 0xc34, 0x469652cf, + 0xc38, 0x49795994, + 0xc3c, 0x0a97971c, + 0xc40, 0x1f7c403f, + 0xc44, 0x000100b7, + 0xc48, 0xec020107, + 0xc4c, 0x007f037f, + 0xc50, 0x6954342e, + 0xc54, 0x43bc0094, + 0xc58, 0x6954342f, + 0xc5c, 0x433c0094, + 0xc60, 0x00000000, + 0xc64, 0x5116848b, + 0xc68, 0x47c00bff, + 0xc6c, 0x00000036, + 0xc70, 0x2c46000d, + 0xc74, 0x018610db, + 0xc78, 0x0000001f, + 0xc7c, 0x00b91612, + 0xc80, 0x24000090, + 0xc84, 0x20f60000, + 0xc88, 0x24000090, + 0xc8c, 0x20200000, + 0xc90, 0x00121820, + 0xc94, 0x00000000, + 0xc98, 0x00121820, + 0xc9c, 0x00007f7f, + 0xca0, 0x00000000, + 0xca4, 0x00000080, + 0xca8, 0x00000000, + 0xcac, 0x00000000, + 0xcb0, 0x00000000, + 0xcb4, 0x00000000, + 0xcb8, 0x00000000, + 0xcbc, 0x28000000, + 0xcc0, 0x00000000, + 0xcc4, 0x00000000, + 0xcc8, 0x00000000, + 0xccc, 0x00000000, + 0xcd0, 0x00000000, + 0xcd4, 0x00000000, + 0xcd8, 0x64b22427, + 0xcdc, 0x00766932, + 0xce0, 0x00222222, + 0xce4, 0x00000000, + 0xce8, 0x37644302, + 0xcec, 0x2f97d40c, + 0xd00, 0x00080740, + 0xd04, 0x00020401, + 0xd08, 0x0000907f, + 0xd0c, 0x20010201, + 0xd10, 0xa0633333, + 0xd14, 0x3333bc43, + 0xd18, 0x7a8f5b6b, + 0xd2c, 0xcc979975, + 0xd30, 0x00000000, + 0xd34, 0x80608000, + 0xd38, 0x00000000, + 0xd3c, 0x00027293, + 0xd40, 0x00000000, + 0xd44, 0x00000000, + 0xd48, 0x00000000, + 0xd4c, 0x00000000, + 0xd50, 0x6437140a, + 0xd54, 0x00000000, + 0xd58, 0x00000000, + 0xd5c, 0x30032064, + 0xd60, 0x4653de68, + 0xd64, 0x04518a3c, + 0xd68, 0x00002101, + 0xd6c, 0x2a201c16, + 0xd70, 0x1812362e, + 0xd74, 0x322c2220, + 0xd78, 0x000e3c24, + 0xe00, 0x24242424, + 0xe04, 0x24242424, + 0xe08, 0x03902024, + 0xe10, 0x24242424, + 0xe14, 0x24242424, + 0xe18, 0x24242424, + 0xe1c, 0x24242424, + 0xe28, 0x00000000, + 0xe30, 0x1000dc1f, + 0xe34, 0x10008c1f, + 0xe38, 0x02140102, + 0xe3c, 0x681604c2, + 0xe40, 0x01007c00, + 0xe44, 0x01004800, + 0xe48, 0xfb000000, + 0xe4c, 0x000028d1, + 0xe50, 0x1000dc1f, + 0xe54, 0x10008c1f, + 0xe58, 0x02140102, + 0xe5c, 0x28160d05, + 0xe60, 0x00000008, + 0xe68, 0x001b25a4, + 0xe6c, 0x631b25a0, + 0xe70, 0x631b25a0, + 0xe74, 0x081b25a0, + 0xe78, 0x081b25a0, + 0xe7c, 0x081b25a0, + 0xe80, 0x081b25a0, + 0xe84, 0x631b25a0, + 0xe88, 0x081b25a0, + 0xe8c, 0x631b25a0, + 0xed0, 0x631b25a0, + 0xed4, 0x631b25a0, + 0xed8, 0x631b25a0, + 0xedc, 0x001b25a0, + 0xee0, 0x001b25a0, + 0xeec, 0x6b1b25a0, + 0xee8, 0x31555448, + 0xf14, 0x00000003, + 0xf4c, 0x00000000, + 0xf00, 0x00000300, +}; + +u32 RTL8192CUPHY_REG_Array_PG_HP[RTL8192CUPHY_REG_Array_PG_HPLength] = { + 0xe00, 0xffffffff, 0x06080808, + 0xe04, 0xffffffff, 0x00040406, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x04060608, + 0xe14, 0xffffffff, 0x00020204, + 0xe18, 0xffffffff, 0x04060608, + 0xe1c, 0xffffffff, 0x00020204, + 0x830, 0xffffffff, 0x06080808, + 0x834, 0xffffffff, 0x00040406, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x04060608, + 0x848, 0xffffffff, 0x00020204, + 0x84c, 0xffffffff, 0x04060608, + 0x868, 0xffffffff, 0x00020204, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, + 0xe00, 0xffffffff, 0x00000000, + 0xe04, 0xffffffff, 0x00000000, + 0xe08, 0x0000ff00, 0x00000000, + 0x86c, 0xffffff00, 0x00000000, + 0xe10, 0xffffffff, 0x00000000, + 0xe14, 0xffffffff, 0x00000000, + 0xe18, 0xffffffff, 0x00000000, + 0xe1c, 0xffffffff, 0x00000000, + 0x830, 0xffffffff, 0x00000000, + 0x834, 0xffffffff, 0x00000000, + 0x838, 0xffffff00, 0x00000000, + 0x86c, 0x000000ff, 0x00000000, + 0x83c, 0xffffffff, 0x00000000, + 0x848, 0xffffffff, 0x00000000, + 0x84c, 0xffffffff, 0x00000000, + 0x868, 0xffffffff, 0x00000000, +}; + +u32 RTL8192CURadioA_1T_HPArray[RTL8192CURadioA_1T_HPArrayLength] = { + 0x000, 0x00030159, + 0x001, 0x00031284, + 0x002, 0x00098000, + 0x003, 0x00018c63, + 0x004, 0x000210e7, + 0x009, 0x0002044f, + 0x00a, 0x0001adb0, + 0x00b, 0x00054867, + 0x00c, 0x0008992e, + 0x00d, 0x0000e529, + 0x00e, 0x00039ce7, + 0x00f, 0x00000451, + 0x019, 0x00000000, + 0x01a, 0x00000255, + 0x01b, 0x00060a00, + 0x01c, 0x000fc378, + 0x01d, 0x000a1250, + 0x01e, 0x0004445f, + 0x01f, 0x00080001, + 0x020, 0x0000b614, + 0x021, 0x0006c000, + 0x022, 0x0000083c, + 0x023, 0x00001558, + 0x024, 0x00000060, + 0x025, 0x00000483, + 0x026, 0x0004f000, + 0x027, 0x000ec7d9, + 0x028, 0x000977c0, + 0x029, 0x00004783, + 0x02a, 0x00000001, + 0x02b, 0x00021334, + 0x02a, 0x00000000, + 0x02b, 0x00000054, + 0x02a, 0x00000001, + 0x02b, 0x00000808, + 0x02b, 0x00053333, + 0x02c, 0x0000000c, + 0x02a, 0x00000002, + 0x02b, 0x00000808, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000003, + 0x02b, 0x00000808, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000004, + 0x02b, 0x00000808, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000005, + 0x02b, 0x00000808, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x00000006, + 0x02b, 0x00000709, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000007, + 0x02b, 0x00000709, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x00000008, + 0x02b, 0x0000060a, + 0x02b, 0x0004b333, + 0x02c, 0x0000000d, + 0x02a, 0x00000009, + 0x02b, 0x0000060a, + 0x02b, 0x00053333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000a, + 0x02b, 0x0000060a, + 0x02b, 0x0005b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000b, + 0x02b, 0x0000060a, + 0x02b, 0x00063333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000c, + 0x02b, 0x0000060a, + 0x02b, 0x0006b333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000d, + 0x02b, 0x0000060a, + 0x02b, 0x00073333, + 0x02c, 0x0000000d, + 0x02a, 0x0000000e, + 0x02b, 0x0000050b, + 0x02b, 0x00066666, + 0x02c, 0x0000001a, + 0x02a, 0x000e0000, + 0x010, 0x0004000f, + 0x011, 0x000e31fc, + 0x010, 0x0006000f, + 0x011, 0x000ff9f8, + 0x010, 0x0002000f, + 0x011, 0x000203f9, + 0x010, 0x0003000f, + 0x011, 0x000ff500, + 0x010, 0x00000000, + 0x011, 0x00000000, + 0x010, 0x0008000f, + 0x011, 0x0003f100, + 0x010, 0x0009000f, + 0x011, 0x00023100, + 0x012, 0x000d8000, + 0x012, 0x00090000, + 0x012, 0x00051000, + 0x012, 0x00012000, + 0x013, 0x00028fb4, + 0x013, 0x00024fa8, + 0x013, 0x000207a4, + 0x013, 0x0001c798, + 0x013, 0x000183a4, + 0x013, 0x00014398, + 0x013, 0x000101a4, + 0x013, 0x0000c198, + 0x013, 0x000080a4, + 0x013, 0x00004098, + 0x013, 0x00000000, + 0x014, 0x0001944c, + 0x014, 0x00059444, + 0x014, 0x0009944c, + 0x014, 0x000d9444, + 0x015, 0x0000f405, + 0x015, 0x0004f405, + 0x015, 0x0008f405, + 0x015, 0x000cf405, + 0x016, 0x000e0330, + 0x016, 0x000a0330, + 0x016, 0x00060330, + 0x016, 0x00020330, + 0x000, 0x00010159, + 0x018, 0x0000f401, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01f, 0x00080003, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x01e, 0x00044457, + 0x01f, 0x00080000, + 0x000, 0x00030159, +}; + +u32 Rtl8192CUAGCTAB_1T_HPArray[RTL8192CUAGCTAB_1T_HPArrayLength] = { + 0xc78, 0x7b000001, + 0xc78, 0x7b010001, + 0xc78, 0x7b020001, + 0xc78, 0x7b030001, + 0xc78, 0x7b040001, + 0xc78, 0x7b050001, + 0xc78, 0x7b060001, + 0xc78, 0x7b070001, + 0xc78, 0x7b080001, + 0xc78, 0x7a090001, + 0xc78, 0x790a0001, + 0xc78, 0x780b0001, + 0xc78, 0x770c0001, + 0xc78, 0x760d0001, + 0xc78, 0x750e0001, + 0xc78, 0x740f0001, + 0xc78, 0x73100001, + 0xc78, 0x72110001, + 0xc78, 0x71120001, + 0xc78, 0x70130001, + 0xc78, 0x6f140001, + 0xc78, 0x6e150001, + 0xc78, 0x6d160001, + 0xc78, 0x6c170001, + 0xc78, 0x6b180001, + 0xc78, 0x6a190001, + 0xc78, 0x691a0001, + 0xc78, 0x681b0001, + 0xc78, 0x671c0001, + 0xc78, 0x661d0001, + 0xc78, 0x651e0001, + 0xc78, 0x641f0001, + 0xc78, 0x63200001, + 0xc78, 0x62210001, + 0xc78, 0x61220001, + 0xc78, 0x60230001, + 0xc78, 0x46240001, + 0xc78, 0x45250001, + 0xc78, 0x44260001, + 0xc78, 0x43270001, + 0xc78, 0x42280001, + 0xc78, 0x41290001, + 0xc78, 0x402a0001, + 0xc78, 0x262b0001, + 0xc78, 0x252c0001, + 0xc78, 0x242d0001, + 0xc78, 0x232e0001, + 0xc78, 0x222f0001, + 0xc78, 0x21300001, + 0xc78, 0x20310001, + 0xc78, 0x06320001, + 0xc78, 0x05330001, + 0xc78, 0x04340001, + 0xc78, 0x03350001, + 0xc78, 0x02360001, + 0xc78, 0x01370001, + 0xc78, 0x00380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x7b400001, + 0xc78, 0x7b410001, + 0xc78, 0x7b420001, + 0xc78, 0x7b430001, + 0xc78, 0x7b440001, + 0xc78, 0x7b450001, + 0xc78, 0x7b460001, + 0xc78, 0x7b470001, + 0xc78, 0x7b480001, + 0xc78, 0x7a490001, + 0xc78, 0x794a0001, + 0xc78, 0x784b0001, + 0xc78, 0x774c0001, + 0xc78, 0x764d0001, + 0xc78, 0x754e0001, + 0xc78, 0x744f0001, + 0xc78, 0x73500001, + 0xc78, 0x72510001, + 0xc78, 0x71520001, + 0xc78, 0x70530001, + 0xc78, 0x6f540001, + 0xc78, 0x6e550001, + 0xc78, 0x6d560001, + 0xc78, 0x6c570001, + 0xc78, 0x6b580001, + 0xc78, 0x6a590001, + 0xc78, 0x695a0001, + 0xc78, 0x685b0001, + 0xc78, 0x675c0001, + 0xc78, 0x665d0001, + 0xc78, 0x655e0001, + 0xc78, 0x645f0001, + 0xc78, 0x63600001, + 0xc78, 0x62610001, + 0xc78, 0x61620001, + 0xc78, 0x60630001, + 0xc78, 0x46640001, + 0xc78, 0x45650001, + 0xc78, 0x44660001, + 0xc78, 0x43670001, + 0xc78, 0x42680001, + 0xc78, 0x41690001, + 0xc78, 0x406a0001, + 0xc78, 0x266b0001, + 0xc78, 0x256c0001, + 0xc78, 0x246d0001, + 0xc78, 0x236e0001, + 0xc78, 0x226f0001, + 0xc78, 0x21700001, + 0xc78, 0x20710001, + 0xc78, 0x06720001, + 0xc78, 0x05730001, + 0xc78, 0x04740001, + 0xc78, 0x03750001, + 0xc78, 0x02760001, + 0xc78, 0x01770001, + 0xc78, 0x00780001, + 0xc78, 0x00790001, + 0xc78, 0x007a0001, + 0xc78, 0x007b0001, + 0xc78, 0x007c0001, + 0xc78, 0x007d0001, + 0xc78, 0x007e0001, + 0xc78, 0x007f0001, + 0xc78, 0x3800001e, + 0xc78, 0x3801001e, + 0xc78, 0x3802001e, + 0xc78, 0x3803001e, + 0xc78, 0x3804001e, + 0xc78, 0x3805001e, + 0xc78, 0x3806001e, + 0xc78, 0x3807001e, + 0xc78, 0x3808001e, + 0xc78, 0x3c09001e, + 0xc78, 0x3e0a001e, + 0xc78, 0x400b001e, + 0xc78, 0x440c001e, + 0xc78, 0x480d001e, + 0xc78, 0x4c0e001e, + 0xc78, 0x500f001e, + 0xc78, 0x5210001e, + 0xc78, 0x5611001e, + 0xc78, 0x5a12001e, + 0xc78, 0x5e13001e, + 0xc78, 0x6014001e, + 0xc78, 0x6015001e, + 0xc78, 0x6016001e, + 0xc78, 0x6217001e, + 0xc78, 0x6218001e, + 0xc78, 0x6219001e, + 0xc78, 0x621a001e, + 0xc78, 0x621b001e, + 0xc78, 0x621c001e, + 0xc78, 0x621d001e, + 0xc78, 0x621e001e, + 0xc78, 0x621f001e, +}; -- cgit v1.2.3 From 29d00a3e46bb6b0743e79f4abc249d8c318e0a56 Mon Sep 17 00:00:00 2001 From: George Date: Sat, 19 Feb 2011 16:29:47 -0600 Subject: rtlwifi: rtl8192cu: Add routine trx Add routine rtlwifi/rtl8192cu/trx.c. This routine differs from the rtl8192ce file of the same name. Signed-off-by: George Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 684 +++++++++++++++++++++++++++ 1 file changed, 684 insertions(+) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/trx.c (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c new file mode 100644 index 000000000000..9855c3e0a4b2 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -0,0 +1,684 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../usb.h" +#include "../ps.h" +#include "../base.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "rf.h" +#include "dm.h" +#include "mac.h" +#include "trx.h" + +static int _ConfigVerTOutEP(struct ieee80211_hw *hw) +{ + u8 ep_cfg, txqsele; + u8 ep_nums = 0; + + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); + + rtlusb->out_queue_sel = 0; + ep_cfg = rtl_read_byte(rtlpriv, REG_TEST_SIE_OPTIONAL); + ep_cfg = (ep_cfg & USB_TEST_EP_MASK) >> USB_TEST_EP_SHIFT; + switch (ep_cfg) { + case 0: /* 2 bulk OUT, 1 bulk IN */ + case 3: + rtlusb->out_queue_sel = TX_SELE_HQ | TX_SELE_LQ; + ep_nums = 2; + break; + case 1: /* 1 bulk IN/OUT => map all endpoint to Low queue */ + case 2: /* 1 bulk IN, 1 bulk OUT => map all endpoint to High queue */ + txqsele = rtl_read_byte(rtlpriv, REG_TEST_USB_TXQS); + if (txqsele & 0x0F) /* /map all endpoint to High queue */ + rtlusb->out_queue_sel = TX_SELE_HQ; + else if (txqsele&0xF0) /* map all endpoint to Low queue */ + rtlusb->out_queue_sel = TX_SELE_LQ; + ep_nums = 1; + break; + default: + break; + } + return (rtlusb->out_ep_nums == ep_nums) ? 0 : -EINVAL; +} + +static int _ConfigVerNOutEP(struct ieee80211_hw *hw) +{ + u8 ep_cfg; + u8 ep_nums = 0; + + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); + + rtlusb->out_queue_sel = 0; + /* Normal and High queue */ + ep_cfg = rtl_read_byte(rtlpriv, (REG_NORMAL_SIE_EP + 1)); + if (ep_cfg & USB_NORMAL_SIE_EP_MASK) { + rtlusb->out_queue_sel |= TX_SELE_HQ; + ep_nums++; + } + if ((ep_cfg >> USB_NORMAL_SIE_EP_SHIFT) & USB_NORMAL_SIE_EP_MASK) { + rtlusb->out_queue_sel |= TX_SELE_NQ; + ep_nums++; + } + /* Low queue */ + ep_cfg = rtl_read_byte(rtlpriv, (REG_NORMAL_SIE_EP + 2)); + if (ep_cfg & USB_NORMAL_SIE_EP_MASK) { + rtlusb->out_queue_sel |= TX_SELE_LQ; + ep_nums++; + } + return (rtlusb->out_ep_nums == ep_nums) ? 0 : -EINVAL; +} + +static void _TwoOutEpMapping(struct ieee80211_hw *hw, bool bIsChipB, + bool bwificfg, struct rtl_ep_map *ep_map) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (bwificfg) { /* for WMM */ + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("USB Chip-B & WMM Setting.....\n")); + ep_map->ep_mapping[RTL_TXQ_BE] = 2; + ep_map->ep_mapping[RTL_TXQ_BK] = 3; + ep_map->ep_mapping[RTL_TXQ_VI] = 3; + ep_map->ep_mapping[RTL_TXQ_VO] = 2; + ep_map->ep_mapping[RTL_TXQ_MGT] = 2; + ep_map->ep_mapping[RTL_TXQ_BCN] = 2; + ep_map->ep_mapping[RTL_TXQ_HI] = 2; + } else { /* typical setting */ + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("USB typical Setting.....\n")); + ep_map->ep_mapping[RTL_TXQ_BE] = 3; + ep_map->ep_mapping[RTL_TXQ_BK] = 3; + ep_map->ep_mapping[RTL_TXQ_VI] = 2; + ep_map->ep_mapping[RTL_TXQ_VO] = 2; + ep_map->ep_mapping[RTL_TXQ_MGT] = 2; + ep_map->ep_mapping[RTL_TXQ_BCN] = 2; + ep_map->ep_mapping[RTL_TXQ_HI] = 2; + } +} + +static void _ThreeOutEpMapping(struct ieee80211_hw *hw, bool bwificfg, + struct rtl_ep_map *ep_map) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + if (bwificfg) { /* for WMM */ + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("USB 3EP Setting for WMM.....\n")); + ep_map->ep_mapping[RTL_TXQ_BE] = 5; + ep_map->ep_mapping[RTL_TXQ_BK] = 3; + ep_map->ep_mapping[RTL_TXQ_VI] = 3; + ep_map->ep_mapping[RTL_TXQ_VO] = 2; + ep_map->ep_mapping[RTL_TXQ_MGT] = 2; + ep_map->ep_mapping[RTL_TXQ_BCN] = 2; + ep_map->ep_mapping[RTL_TXQ_HI] = 2; + } else { /* typical setting */ + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("USB 3EP Setting for typical.....\n")); + ep_map->ep_mapping[RTL_TXQ_BE] = 5; + ep_map->ep_mapping[RTL_TXQ_BK] = 5; + ep_map->ep_mapping[RTL_TXQ_VI] = 3; + ep_map->ep_mapping[RTL_TXQ_VO] = 2; + ep_map->ep_mapping[RTL_TXQ_MGT] = 2; + ep_map->ep_mapping[RTL_TXQ_BCN] = 2; + ep_map->ep_mapping[RTL_TXQ_HI] = 2; + } +} + +static void _OneOutEpMapping(struct ieee80211_hw *hw, struct rtl_ep_map *ep_map) +{ + ep_map->ep_mapping[RTL_TXQ_BE] = 2; + ep_map->ep_mapping[RTL_TXQ_BK] = 2; + ep_map->ep_mapping[RTL_TXQ_VI] = 2; + ep_map->ep_mapping[RTL_TXQ_VO] = 2; + ep_map->ep_mapping[RTL_TXQ_MGT] = 2; + ep_map->ep_mapping[RTL_TXQ_BCN] = 2; + ep_map->ep_mapping[RTL_TXQ_HI] = 2; +} +static int _out_ep_mapping(struct ieee80211_hw *hw) +{ + int err = 0; + bool bIsChipN, bwificfg = false; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); + struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); + struct rtl_ep_map *ep_map = &(rtlusb->ep_map); + + bIsChipN = IS_NORMAL_CHIP(rtlhal->version); + switch (rtlusb->out_ep_nums) { + case 2: + _TwoOutEpMapping(hw, bIsChipN, bwificfg, ep_map); + break; + case 3: + /* Test chip doesn't support three out EPs. */ + if (!bIsChipN) { + err = -EINVAL; + goto err_out; + } + _ThreeOutEpMapping(hw, bIsChipN, ep_map); + break; + case 1: + _OneOutEpMapping(hw, ep_map); + break; + default: + err = -EINVAL; + break; + } +err_out: + return err; + +} +/* endpoint mapping */ +int rtl8192cu_endpoint_mapping(struct ieee80211_hw *hw) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + int error = 0; + if (likely(IS_NORMAL_CHIP(rtlhal->version))) + error = _ConfigVerNOutEP(hw); + else + error = _ConfigVerTOutEP(hw); + if (error) + goto err_out; + error = _out_ep_mapping(hw); + if (error) + goto err_out; +err_out: + return error; +} + +u16 rtl8192cu_mq_to_hwq(__le16 fc, u16 mac80211_queue_index) +{ + u16 hw_queue_index; + + if (unlikely(ieee80211_is_beacon(fc))) { + hw_queue_index = RTL_TXQ_BCN; + goto out; + } + if (ieee80211_is_mgmt(fc)) { + hw_queue_index = RTL_TXQ_MGT; + goto out; + } + switch (mac80211_queue_index) { + case 0: + hw_queue_index = RTL_TXQ_VO; + break; + case 1: + hw_queue_index = RTL_TXQ_VI; + break; + case 2: + hw_queue_index = RTL_TXQ_BE; + break; + case 3: + hw_queue_index = RTL_TXQ_BK; + break; + default: + hw_queue_index = RTL_TXQ_BE; + RT_ASSERT(false, ("QSLT_BE queue, skb_queue:%d\n", + mac80211_queue_index)); + break; + } +out: + return hw_queue_index; +} + +static enum rtl_desc_qsel _rtl8192cu_mq_to_descq(struct ieee80211_hw *hw, + __le16 fc, u16 mac80211_queue_index) +{ + enum rtl_desc_qsel qsel; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (unlikely(ieee80211_is_beacon(fc))) { + qsel = QSLT_BEACON; + goto out; + } + if (ieee80211_is_mgmt(fc)) { + qsel = QSLT_MGNT; + goto out; + } + switch (mac80211_queue_index) { + case 0: /* VO */ + qsel = QSLT_VO; + RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, + ("VO queue, set qsel = 0x%x\n", QSLT_VO)); + break; + case 1: /* VI */ + qsel = QSLT_VI; + RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, + ("VI queue, set qsel = 0x%x\n", QSLT_VI)); + break; + case 3: /* BK */ + qsel = QSLT_BK; + RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, + ("BK queue, set qsel = 0x%x\n", QSLT_BK)); + break; + case 2: /* BE */ + default: + qsel = QSLT_BE; + RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, + ("BE queue, set qsel = 0x%x\n", QSLT_BE)); + break; + } +out: + return qsel; +} + +/* =============================================================== */ + +/*---------------------------------------------------------------------- + * + * Rx handler + * + *---------------------------------------------------------------------- */ +bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw, + struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, + u8 *p_desc, struct sk_buff *skb) +{ + struct rx_fwinfo_92c *p_drvinfo; + struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc; + u32 phystatus = GET_RX_DESC_PHY_STATUS(pdesc); + + stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc); + stats->rx_drvinfo_size = (u8)GET_RX_DESC_DRVINFO_SIZE(pdesc) * + RX_DRV_INFO_SIZE_UNIT; + stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03); + stats->icv = (u16) GET_RX_DESC_ICV(pdesc); + stats->crc = (u16) GET_RX_DESC_CRC32(pdesc); + stats->hwerror = (stats->crc | stats->icv); + stats->decrypted = !GET_RX_DESC_SWDEC(pdesc); + stats->rate = (u8) GET_RX_DESC_RX_MCS(pdesc); + stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc); + stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1); + stats->isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1) + && (GET_RX_DESC_FAGGR(pdesc) == 1)); + stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); + stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); + rx_status->freq = hw->conf.channel->center_freq; + rx_status->band = hw->conf.channel->band; + if (GET_RX_DESC_CRC32(pdesc)) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + if (!GET_RX_DESC_SWDEC(pdesc)) + rx_status->flag |= RX_FLAG_DECRYPTED; + if (GET_RX_DESC_BW(pdesc)) + rx_status->flag |= RX_FLAG_40MHZ; + if (GET_RX_DESC_RX_HT(pdesc)) + rx_status->flag |= RX_FLAG_HT; + rx_status->flag |= RX_FLAG_TSFT; + if (stats->decrypted) + rx_status->flag |= RX_FLAG_DECRYPTED; + rx_status->rate_idx = _rtl92c_rate_mapping(hw, + (bool)GET_RX_DESC_RX_HT(pdesc), + (u8)GET_RX_DESC_RX_MCS(pdesc), + (bool)GET_RX_DESC_PAGGR(pdesc)); + rx_status->mactime = GET_RX_DESC_TSFL(pdesc); + if (phystatus == true) { + p_drvinfo = (struct rx_fwinfo_92c *)(pdesc + RTL_RX_DESC_SIZE); + rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc, + p_drvinfo); + } + /*rx_status->qual = stats->signal; */ + rx_status->signal = stats->rssi + 10; + /*rx_status->noise = -stats->noise; */ + return true; +} + +#define RTL_RX_DRV_INFO_UNIT 8 + +static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct ieee80211_rx_status *rx_status = + (struct ieee80211_rx_status *)IEEE80211_SKB_RXCB(skb); + u32 skb_len, pkt_len, drvinfo_len; + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 *rxdesc; + struct rtl_stats stats = { + .signal = 0, + .noise = -98, + .rate = 0, + }; + struct rx_fwinfo_92c *p_drvinfo; + bool bv; + __le16 fc; + struct ieee80211_hdr *hdr; + + memset(rx_status, 0, sizeof(rx_status)); + rxdesc = skb->data; + skb_len = skb->len; + drvinfo_len = (GET_RX_DESC_DRVINFO_SIZE(rxdesc) * RTL_RX_DRV_INFO_UNIT); + pkt_len = GET_RX_DESC_PKT_LEN(rxdesc); + /* TODO: Error recovery. drop this skb or something. */ + WARN_ON(skb_len < (pkt_len + RTL_RX_DESC_SIZE + drvinfo_len)); + stats.length = (u16) GET_RX_DESC_PKT_LEN(rxdesc); + stats.rx_drvinfo_size = (u8)GET_RX_DESC_DRVINFO_SIZE(rxdesc) * + RX_DRV_INFO_SIZE_UNIT; + stats.rx_bufshift = (u8) (GET_RX_DESC_SHIFT(rxdesc) & 0x03); + stats.icv = (u16) GET_RX_DESC_ICV(rxdesc); + stats.crc = (u16) GET_RX_DESC_CRC32(rxdesc); + stats.hwerror = (stats.crc | stats.icv); + stats.decrypted = !GET_RX_DESC_SWDEC(rxdesc); + stats.rate = (u8) GET_RX_DESC_RX_MCS(rxdesc); + stats.shortpreamble = (u16) GET_RX_DESC_SPLCP(rxdesc); + stats.isampdu = (bool) ((GET_RX_DESC_PAGGR(rxdesc) == 1) + && (GET_RX_DESC_FAGGR(rxdesc) == 1)); + stats.timestamp_low = GET_RX_DESC_TSFL(rxdesc); + stats.rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(rxdesc); + /* TODO: is center_freq changed when doing scan? */ + /* TODO: Shall we add protection or just skip those two step? */ + rx_status->freq = hw->conf.channel->center_freq; + rx_status->band = hw->conf.channel->band; + if (GET_RX_DESC_CRC32(rxdesc)) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + if (!GET_RX_DESC_SWDEC(rxdesc)) + rx_status->flag |= RX_FLAG_DECRYPTED; + if (GET_RX_DESC_BW(rxdesc)) + rx_status->flag |= RX_FLAG_40MHZ; + if (GET_RX_DESC_RX_HT(rxdesc)) + rx_status->flag |= RX_FLAG_HT; + /* Data rate */ + rx_status->rate_idx = _rtl92c_rate_mapping(hw, + (bool)GET_RX_DESC_RX_HT(rxdesc), + (u8)GET_RX_DESC_RX_MCS(rxdesc), + (bool)GET_RX_DESC_PAGGR(rxdesc) + ); + /* There is a phy status after this rx descriptor. */ + if (GET_RX_DESC_PHY_STATUS(rxdesc)) { + p_drvinfo = (struct rx_fwinfo_92c *)(rxdesc + RTL_RX_DESC_SIZE); + rtl92c_translate_rx_signal_stuff(hw, skb, &stats, + (struct rx_desc_92c *)rxdesc, p_drvinfo); + } + skb_pull(skb, (drvinfo_len + RTL_RX_DESC_SIZE)); + hdr = (struct ieee80211_hdr *)(skb->data); + fc = hdr->frame_control; + bv = ieee80211_is_probe_resp(fc); + if (bv) + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("Got probe response frame.\n")); + if (ieee80211_is_beacon(fc)) + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("Got beacon frame.\n")); + if (ieee80211_is_data(fc)) + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Got data frame.\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("Fram: fc = 0x%X addr1 = 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:" + "0x%02X\n", fc, (u32)hdr->addr1[0], (u32)hdr->addr1[1], + (u32)hdr->addr1[2], (u32)hdr->addr1[3], (u32)hdr->addr1[4], + (u32)hdr->addr1[5])); + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); + ieee80211_rx_irqsafe(hw, skb); +} + +void rtl8192cu_rx_hdl(struct ieee80211_hw *hw, struct sk_buff * skb) +{ + _rtl_rx_process(hw, skb); +} + +void rtl8192c_rx_segregate_hdl( + struct ieee80211_hw *hw, + struct sk_buff *skb, + struct sk_buff_head *skb_list) +{ +} + +/*---------------------------------------------------------------------- + * + * Tx handler + * + *---------------------------------------------------------------------- */ +void rtl8192c_tx_cleanup(struct ieee80211_hw *hw, struct sk_buff *skb) +{ +} + +int rtl8192c_tx_post_hdl(struct ieee80211_hw *hw, struct urb *urb, + struct sk_buff *skb) +{ + return 0; +} + +struct sk_buff *rtl8192c_tx_aggregate_hdl(struct ieee80211_hw *hw, + struct sk_buff_head *list) +{ + return skb_dequeue(list); +} + +/*======================================== trx ===============================*/ + +static void _rtl_fill_usb_tx_desc(u8 *txdesc) +{ + SET_TX_DESC_OWN(txdesc, 1); + SET_TX_DESC_LAST_SEG(txdesc, 1); + SET_TX_DESC_FIRST_SEG(txdesc, 1); +} +/** + * For HW recovery information + */ +static void _rtl_tx_desc_checksum(u8 *txdesc) +{ + u16 *ptr = (u16 *)txdesc; + u16 checksum = 0; + u32 index; + + /* Clear first */ + SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, 0); + for (index = 0; index < 16; index++) + checksum = checksum ^ (*(ptr + index)); + SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, checksum); +} + +void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc_tx, + struct ieee80211_tx_info *info, struct sk_buff *skb, + unsigned int queue_index) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool defaultadapter = true; + struct ieee80211_sta *sta = ieee80211_find_sta(mac->vif, mac->bssid); + struct rtl_tcb_desc tcb_desc; + u8 *qc = ieee80211_get_qos_ctl(hdr); + u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; + u16 seq_number; + __le16 fc = hdr->frame_control; + u8 rate_flag = info->control.rates[0].flags; + u16 pktlen = skb->len; + enum rtl_desc_qsel fw_qsel = _rtl8192cu_mq_to_descq(hw, fc, + skb_get_queue_mapping(skb)); + u8 *txdesc; + + seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + rtl_get_tcb_desc(hw, info, skb, &tcb_desc); + txdesc = (u8 *)skb_push(skb, RTL_TX_HEADER_SIZE); + memset(txdesc, 0, RTL_TX_HEADER_SIZE); + SET_TX_DESC_PKT_SIZE(txdesc, pktlen); + SET_TX_DESC_LINIP(txdesc, 0); + SET_TX_DESC_PKT_OFFSET(txdesc, RTL_DUMMY_OFFSET); + SET_TX_DESC_OFFSET(txdesc, RTL_TX_HEADER_SIZE); + SET_TX_DESC_TX_RATE(txdesc, tcb_desc.hw_rate); + if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble) + SET_TX_DESC_DATA_SHORTGI(txdesc, 1); + if (mac->tids[tid].agg.agg_state == RTL_AGG_ON && + info->flags & IEEE80211_TX_CTL_AMPDU) { + SET_TX_DESC_AGG_ENABLE(txdesc, 1); + SET_TX_DESC_MAX_AGG_NUM(txdesc, 0x14); + } else { + SET_TX_DESC_AGG_BREAK(txdesc, 1); + } + SET_TX_DESC_SEQ(txdesc, seq_number); + SET_TX_DESC_RTS_ENABLE(txdesc, ((tcb_desc.rts_enable && + !tcb_desc.cts_enable) ? 1 : 0)); + SET_TX_DESC_HW_RTS_ENABLE(txdesc, ((tcb_desc.rts_enable || + tcb_desc.cts_enable) ? 1 : 0)); + SET_TX_DESC_CTS2SELF(txdesc, ((tcb_desc.cts_enable) ? 1 : 0)); + SET_TX_DESC_RTS_STBC(txdesc, ((tcb_desc.rts_stbc) ? 1 : 0)); + SET_TX_DESC_RTS_RATE(txdesc, tcb_desc.rts_rate); + SET_TX_DESC_RTS_BW(txdesc, 0); + SET_TX_DESC_RTS_SC(txdesc, tcb_desc.rts_sc); + SET_TX_DESC_RTS_SHORT(txdesc, + ((tcb_desc.rts_rate <= DESC92C_RATE54M) ? + (tcb_desc.rts_use_shortpreamble ? 1 : 0) + : (tcb_desc.rts_use_shortgi ? 1 : 0))); + if (mac->bw_40) { + if (tcb_desc.packet_bw) { + SET_TX_DESC_DATA_BW(txdesc, 1); + SET_TX_DESC_DATA_SC(txdesc, 3); + } else { + SET_TX_DESC_DATA_BW(txdesc, 0); + if (rate_flag & IEEE80211_TX_RC_DUP_DATA) + SET_TX_DESC_DATA_SC(txdesc, + mac->cur_40_prime_sc); + } + } else { + SET_TX_DESC_DATA_BW(txdesc, 0); + SET_TX_DESC_DATA_SC(txdesc, 0); + } + if (sta) { + u8 ampdu_density = sta->ht_cap.ampdu_density; + SET_TX_DESC_AMPDU_DENSITY(txdesc, ampdu_density); + } + if (info->control.hw_key) { + struct ieee80211_key_conf *keyconf = info->control.hw_key; + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + SET_TX_DESC_SEC_TYPE(txdesc, 0x1); + break; + case WLAN_CIPHER_SUITE_CCMP: + SET_TX_DESC_SEC_TYPE(txdesc, 0x3); + break; + default: + SET_TX_DESC_SEC_TYPE(txdesc, 0x0); + break; + } + } + SET_TX_DESC_PKT_ID(txdesc, 0); + SET_TX_DESC_QUEUE_SEL(txdesc, fw_qsel); + SET_TX_DESC_DATA_RATE_FB_LIMIT(txdesc, 0x1F); + SET_TX_DESC_RTS_RATE_FB_LIMIT(txdesc, 0xF); + SET_TX_DESC_DISABLE_FB(txdesc, 0); + SET_TX_DESC_USE_RATE(txdesc, tcb_desc.use_driver_rate ? 1 : 0); + if (ieee80211_is_data_qos(fc)) { + if (mac->rdg_en) { + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, + ("Enable RDG function.\n")); + SET_TX_DESC_RDG_ENABLE(txdesc, 1); + SET_TX_DESC_HTC(txdesc, 1); + } + } + if (rtlpriv->dm.useramask) { + SET_TX_DESC_RATE_ID(txdesc, tcb_desc.ratr_index); + SET_TX_DESC_MACID(txdesc, tcb_desc.mac_id); + } else { + SET_TX_DESC_RATE_ID(txdesc, 0xC + tcb_desc.ratr_index); + SET_TX_DESC_MACID(txdesc, tcb_desc.ratr_index); + } + if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps && + ppsc->fwctrl_lps) { + SET_TX_DESC_HWSEQ_EN(txdesc, 1); + SET_TX_DESC_PKT_ID(txdesc, 8); + if (!defaultadapter) + SET_TX_DESC_QOS(txdesc, 1); + } + if (ieee80211_has_morefrags(fc)) + SET_TX_DESC_MORE_FRAG(txdesc, 1); + if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || + is_broadcast_ether_addr(ieee80211_get_DA(hdr))) + SET_TX_DESC_BMC(txdesc, 1); + _rtl_fill_usb_tx_desc(txdesc); + _rtl_tx_desc_checksum(txdesc); + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, (" %s ==>\n", __func__)); +} + +void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc, + u32 buffer_len, bool bIsPsPoll) +{ + /* Clear all status */ + memset(pDesc, 0, RTL_TX_HEADER_SIZE); + SET_TX_DESC_FIRST_SEG(pDesc, 1); /* bFirstSeg; */ + SET_TX_DESC_LAST_SEG(pDesc, 1); /* bLastSeg; */ + SET_TX_DESC_OFFSET(pDesc, RTL_TX_HEADER_SIZE); /* Offset = 32 */ + SET_TX_DESC_PKT_SIZE(pDesc, buffer_len); /* Buffer size + command hdr */ + SET_TX_DESC_QUEUE_SEL(pDesc, QSLT_MGNT); /* Fixed queue of Mgnt queue */ + /* Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error + * vlaue by Hw. */ + if (bIsPsPoll) { + SET_TX_DESC_NAV_USE_HDR(pDesc, 1); + } else { + SET_TX_DESC_HWSEQ_EN(pDesc, 1); /* Hw set sequence number */ + SET_TX_DESC_PKT_ID(pDesc, 0x100); /* set bit3 to 1. */ + } + SET_TX_DESC_USE_RATE(pDesc, 1); /* use data rate which is set by Sw */ + SET_TX_DESC_OWN(pDesc, 1); + SET_TX_DESC_TX_RATE(pDesc, DESC92C_RATE1M); + _rtl_tx_desc_checksum(pDesc); +} + +void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw, + u8 *pdesc, bool firstseg, + bool lastseg, struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 fw_queue = QSLT_BEACON; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); + __le16 fc = hdr->frame_control; + + memset((void *)pdesc, 0, RTL_TX_HEADER_SIZE); + if (firstseg) + SET_TX_DESC_OFFSET(pdesc, RTL_TX_HEADER_SIZE); + SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M); + SET_TX_DESC_SEQ(pdesc, 0); + SET_TX_DESC_LINIP(pdesc, 0); + SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue); + SET_TX_DESC_FIRST_SEG(pdesc, 1); + SET_TX_DESC_LAST_SEG(pdesc, 1); + SET_TX_DESC_RATE_ID(pdesc, 7); + SET_TX_DESC_MACID(pdesc, 0); + SET_TX_DESC_OWN(pdesc, 1); + SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len)); + SET_TX_DESC_FIRST_SEG(pdesc, 1); + SET_TX_DESC_LAST_SEG(pdesc, 1); + SET_TX_DESC_OFFSET(pdesc, 0x20); + SET_TX_DESC_USE_RATE(pdesc, 1); + if (!ieee80211_is_data_qos(fc)) { + SET_TX_DESC_HWSEQ_EN(pdesc, 1); + SET_TX_DESC_PKT_ID(pdesc, 8); + } + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content\n", + pdesc, RTL_TX_DESC_SIZE); +} + +bool rtl92cu_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + return true; +} -- cgit v1.2.3 From 663dcc73675bd70ee11195ce832b1d1691f967d0 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 19 Feb 2011 16:29:52 -0600 Subject: rtlwifi: Modify build system for rtl8192cu Modify Kconfig and Makefile to build rtl8192cu. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/Kconfig | 17 ++++++++++++++--- drivers/net/wireless/rtlwifi/Makefile | 3 +++ drivers/net/wireless/rtlwifi/rtl8192ce/Makefile | 2 ++ drivers/net/wireless/rtlwifi/rtl8192ce/reg.h | 1 + drivers/net/wireless/rtlwifi/rtl8192cu/Makefile | 15 +++++++++++++++ 5 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/Makefile (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig index 7f6573f7f470..86f8d4d64037 100644 --- a/drivers/net/wireless/rtlwifi/Kconfig +++ b/drivers/net/wireless/rtlwifi/Kconfig @@ -1,6 +1,6 @@ config RTL8192CE - tristate "Realtek RTL8192CE/RTL8188SE Wireless Network Adapter" - depends on MAC80211 && EXPERIMENTAL + tristate "Realtek RTL8192CE/RTL8188CE Wireless Network Adapter" + depends on MAC80211 && PCI && EXPERIMENTAL select FW_LOADER select RTLWIFI ---help--- @@ -9,7 +9,18 @@ config RTL8192CE If you choose to build it as a module, it will be called rtl8192ce +config RTL8192CU + tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter" + depends on MAC80211 && USB && EXPERIMENTAL + select FW_LOADER + select RTLWIFI + ---help--- + This is the driver for Realtek RTL8192CU/RTL8188CU 802.11n USB + wireless network adapters. + + If you choose to build it as a module, it will be called rtl8192cu + config RTLWIFI tristate - depends on RTL8192CE + depends on RTL8192CE || RTL8192CU default m diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile index efbff2f478bf..c3e83a1da33b 100644 --- a/drivers/net/wireless/rtlwifi/Makefile +++ b/drivers/net/wireless/rtlwifi/Makefile @@ -12,3 +12,6 @@ rtlwifi-objs := \ usb.o obj-$(CONFIG_RTL8192CE) += rtl8192ce/ +obj-$(CONFIG_RTL8192CU) += rtl8192cu/ + +ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile b/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile index 0f0be7c763b8..5c5fdde637cb 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile @@ -10,3 +10,5 @@ rtl8192ce-objs := \ trx.o obj-$(CONFIG_RTL8192CE) += rtl8192ce.o + +ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h index 9ffbadc281f2..3df22bd9480d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h @@ -1077,6 +1077,7 @@ #define _RARF_RC8(x) (((x) & 0x1F) << 24) #define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_TXOP_OFFSET 16 #define AC_PARAM_ECW_MAX_OFFSET 12 #define AC_PARAM_ECW_MIN_OFFSET 8 #define AC_PARAM_AIFS_OFFSET 0 diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/Makefile b/drivers/net/wireless/rtlwifi/rtl8192cu/Makefile new file mode 100644 index 000000000000..91c65122ca80 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/Makefile @@ -0,0 +1,15 @@ +rtl8192cu-objs := \ + dm.o \ + fw.o \ + hw.o \ + led.o \ + mac.o \ + phy.o \ + rf.o \ + sw.o \ + table.o \ + trx.o + +obj-$(CONFIG_RTL8192CU) += rtl8192cu.o + +ccflags-y += -D__CHECK_ENDIAN__ -- cgit v1.2.3 From 17c9ac62812b58aacefc7336215aecbb522f6547 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 19 Feb 2011 16:29:57 -0600 Subject: rtlwifi: rtl8192ce: Fix endian warnings Drivers rtlwifi, and rtl8192ce generate a large number of sparse warnings. This patch fixes most of them. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.c | 16 +- drivers/net/wireless/rtlwifi/core.c | 6 +- drivers/net/wireless/rtlwifi/pci.c | 29 +- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 39 +-- drivers/net/wireless/rtlwifi/rtl8192ce/reg.h | 1 - drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 21 +- drivers/net/wireless/rtlwifi/rtl8192ce/trx.h | 462 ++++++++++++++------------- drivers/net/wireless/rtlwifi/usb.c | 16 +- drivers/net/wireless/rtlwifi/usb.h | 2 +- drivers/net/wireless/rtlwifi/wifi.h | 12 +- 10 files changed, 313 insertions(+), 291 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 1d6cc1f3c6bf..3f40dc2b129c 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -144,7 +144,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, ht_cap->mcs.rx_mask[1] = 0xFF; ht_cap->mcs.rx_mask[4] = 0x01; - ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15; + ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15); } else if (get_rf_type(rtlphy) == RF_1T1R) { RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T1R\n")); @@ -153,7 +153,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, ht_cap->mcs.rx_mask[1] = 0x00; ht_cap->mcs.rx_mask[4] = 0x01; - ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7; + ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS7); } } @@ -498,7 +498,7 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw, struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); struct ieee80211_rate *txrate; - u16 fc = le16_to_cpu(hdr->frame_control); + __le16 fc = hdr->frame_control; memset(tcb_desc, 0, sizeof(struct rtl_tcb_desc)); @@ -570,7 +570,7 @@ bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb) struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rtl_priv *rtlpriv = rtl_priv(hw); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); - u16 fc = le16_to_cpu(hdr->frame_control); + __le16 fc = hdr->frame_control; if (ieee80211_is_auth(fc)) { RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); @@ -587,7 +587,7 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); struct rtl_priv *rtlpriv = rtl_priv(hw); - u16 fc = le16_to_cpu(hdr->frame_control); + __le16 fc = hdr->frame_control; u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN)); u8 category; @@ -632,7 +632,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) struct rtl_priv *rtlpriv = rtl_priv(hw); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - u16 fc = le16_to_cpu(hdr->frame_control); + __le16 fc = hdr->frame_control; u16 ether_type; u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb); const struct iphdr *ip; @@ -646,7 +646,6 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len + SNAP_SIZE + PROTOC_TYPE_SIZE); ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE); - ether_type = ntohs(ether_type); if (ETH_P_IP == ether_type) { if (IPPROTO_UDP == ip->protocol) { @@ -690,7 +689,8 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) } return true; - } else if (0x86DD == ether_type) { + } else if (ETH_P_IPV6 == ether_type) { + /* IPv6 */ return true; } diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 2d1e3e833568..b0996bf8a214 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -434,9 +434,9 @@ static int rtl_op_conf_tx(struct ieee80211_hw *hw, u16 queue, aci = _rtl_get_hal_qnum(queue); mac->ac[aci].aifs = param->aifs; - mac->ac[aci].cw_min = param->cw_min; - mac->ac[aci].cw_max = param->cw_max; - mac->ac[aci].tx_op = param->txop; + mac->ac[aci].cw_min = cpu_to_le16(param->cw_min); + mac->ac[aci].cw_max = cpu_to_le16(param->cw_max); + mac->ac[aci].tx_op = cpu_to_le16(param->txop); memcpy(&mac->edca_param[aci], param, sizeof(*param)); rtlpriv->cfg->ops->set_qos(hw, aci); return 0; diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 2da164380771..1f18bf7df741 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -476,9 +476,9 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) skb = __skb_dequeue(&ring->queue); pci_unmap_single(rtlpci->pdev, - le32_to_cpu(rtlpriv->cfg->ops-> + rtlpriv->cfg->ops-> get_desc((u8 *) entry, true, - HW_DESC_TXBUFF_ADDR)), + HW_DESC_TXBUFF_ADDR), skb->len, PCI_DMA_TODEVICE); RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE, @@ -557,7 +557,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) return; } else { struct ieee80211_hdr *hdr; - u16 fc; + __le16 fc; struct sk_buff *new_skb = NULL; rtlpriv->cfg->ops->query_rx_desc(hw, &stats, @@ -583,7 +583,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) */ hdr = (struct ieee80211_hdr *)(skb->data); - fc = le16_to_cpu(hdr->frame_control); + fc = hdr->frame_control; if (!stats.crc) { memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, @@ -666,7 +666,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) } done: - bufferaddress = cpu_to_le32(*((dma_addr_t *) skb->cb)); + bufferaddress = (u32)(*((dma_addr_t *) skb->cb)); tmp_one = 1; rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false, HW_DESC_RXBUFF_ADDR, @@ -955,9 +955,8 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, ("queue:%d, ring_addr:%p\n", prio, ring)); for (i = 0; i < entries; i++) { - nextdescaddress = cpu_to_le32((u32) dma + - ((i + 1) % entries) * - sizeof(*ring)); + nextdescaddress = (u32) dma + ((i + 1) % entries) * + sizeof(*ring); rtlpriv->cfg->ops->set_desc((u8 *)&(ring[i]), true, HW_DESC_TX_NEXTDESC_ADDR, @@ -1021,7 +1020,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw) rtlpci->rxbuffersize, PCI_DMA_FROMDEVICE); - bufferaddress = cpu_to_le32(*((dma_addr_t *)skb->cb)); + bufferaddress = (u32)(*((dma_addr_t *)skb->cb)); rtlpriv->cfg->ops->set_desc((u8 *)entry, false, HW_DESC_RXBUFF_ADDR, (u8 *)&bufferaddress); @@ -1052,9 +1051,9 @@ static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw, struct sk_buff *skb = __skb_dequeue(&ring->queue); pci_unmap_single(rtlpci->pdev, - le32_to_cpu(rtlpriv->cfg-> + rtlpriv->cfg-> ops->get_desc((u8 *) entry, true, - HW_DESC_TXBUFF_ADDR)), + HW_DESC_TXBUFF_ADDR), skb->len, PCI_DMA_TODEVICE); kfree_skb(skb); ring->idx = (ring->idx + 1) % ring->entries; @@ -1186,11 +1185,11 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) __skb_dequeue(&ring->queue); pci_unmap_single(rtlpci->pdev, - le32_to_cpu(rtlpriv->cfg->ops-> + rtlpriv->cfg->ops-> get_desc((u8 *) entry, true, - HW_DESC_TXBUFF_ADDR)), + HW_DESC_TXBUFF_ADDR), skb->len, PCI_DMA_TODEVICE); kfree_skb(skb); ring->idx = (ring->idx + 1) % ring->entries; @@ -1204,7 +1203,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) return 0; } -static unsigned int _rtl_mac_to_hwqueue(u16 fc, +static unsigned int _rtl_mac_to_hwqueue(__le16 fc, unsigned int mac80211_queue_index) { unsigned int hw_queue_index; @@ -1254,7 +1253,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb) unsigned int queue_index, hw_queue; unsigned long flags; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); - u16 fc = le16_to_cpu(hdr->frame_control); + __le16 fc = hdr->frame_control; u8 *pda_addr = hdr->addr1; struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); /*ssn */ diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 7a1bfa92375f..0b910921e606 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -318,15 +318,17 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } case HW_VAR_AC_PARAM:{ u8 e_aci = *((u8 *) val); - u32 u4b_ac_param = 0; + u32 u4b_ac_param; + u16 cw_min = le16_to_cpu(mac->ac[e_aci].cw_min); + u16 cw_max = le16_to_cpu(mac->ac[e_aci].cw_max); + u16 tx_op = le16_to_cpu(mac->ac[e_aci].tx_op); - u4b_ac_param |= (u32) mac->ac[e_aci].aifs; - u4b_ac_param |= ((u32) mac->ac[e_aci].cw_min + u4b_ac_param = (u32) mac->ac[e_aci].aifs; + u4b_ac_param |= ((u32)cw_min & 0xF) << AC_PARAM_ECW_MIN_OFFSET; - u4b_ac_param |= ((u32) mac->ac[e_aci].cw_max & + u4b_ac_param |= ((u32)cw_max & 0xF) << AC_PARAM_ECW_MAX_OFFSET; - u4b_ac_param |= (u32) mac->ac[e_aci].tx_op - << AC_PARAM_TXOP_LIMIT_OFFSET; + u4b_ac_param |= (u32)tx_op << AC_PARAM_TXOP_OFFSET; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, ("queue:%x, ac_param:%x\n", e_aci, @@ -1170,21 +1172,20 @@ void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - u32 u4b_ac_param; + u16 cw_min = le16_to_cpu(mac->ac[aci].cw_min); + u16 cw_max = le16_to_cpu(mac->ac[aci].cw_max); + u16 tx_op = le16_to_cpu(mac->ac[aci].tx_op); rtl92c_dm_init_edca_turbo(hw); - u4b_ac_param = (u32) mac->ac[aci].aifs; - u4b_ac_param |= - ((u32) mac->ac[aci].cw_min & 0xF) << AC_PARAM_ECW_MIN_OFFSET; - u4b_ac_param |= - ((u32) mac->ac[aci].cw_max & 0xF) << AC_PARAM_ECW_MAX_OFFSET; - u4b_ac_param |= (u32) mac->ac[aci].tx_op << AC_PARAM_TXOP_LIMIT_OFFSET; + u4b_ac_param |= (u32) ((cw_min & 0xF) << AC_PARAM_ECW_MIN_OFFSET); + u4b_ac_param |= (u32) ((cw_max & 0xF) << AC_PARAM_ECW_MAX_OFFSET); + u4b_ac_param |= (u32) (tx_op << AC_PARAM_TXOP_OFFSET); RT_TRACE(rtlpriv, COMP_QOS, DBG_DMESG, ("queue:%x, ac_param:%x aifs:%x cwmin:%x cwmax:%x txop:%x\n", - aci, u4b_ac_param, mac->ac[aci].aifs, mac->ac[aci].cw_min, - mac->ac[aci].cw_max, mac->ac[aci].tx_op)); + aci, u4b_ac_param, mac->ac[aci].aifs, cw_min, + cw_max, tx_op)); switch (aci) { case AC1_BK: rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param); @@ -1712,7 +1713,7 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw) struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); u32 ratr_value = (u32) mac->basic_rates; - u8 *p_mcsrate = mac->mcs; + u8 *mcsrate = mac->mcs; u8 ratr_index = 0; u8 nmode = mac->ht_enable; u8 mimo_ps = 1; @@ -1723,7 +1724,7 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw) u8 curshortgi_20mhz = mac->sgi_20; enum wireless_mode wirelessmode = mac->mode; - ratr_value |= EF2BYTE((*(u16 *) (p_mcsrate))) << 12; + ratr_value |= ((*(u16 *) (mcsrate))) << 12; switch (wirelessmode) { case WIRELESS_MODE_B: @@ -1892,8 +1893,8 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) } RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("ratr_bitmap :%x\n", ratr_bitmap)); - *(u32 *)&rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) | - (ratr_index << 28)); + *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | + (ratr_index << 28); rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, " "ratr_val:%x, %x:%x:%x:%x:%x\n", diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h index 3df22bd9480d..b0868a613841 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h @@ -1076,7 +1076,6 @@ #define _RARF_RC7(x) (((x) & 0x1F) << 16) #define _RARF_RC8(x) (((x) & 0x1F) << 24) -#define AC_PARAM_TXOP_LIMIT_OFFSET 16 #define AC_PARAM_TXOP_OFFSET 16 #define AC_PARAM_ECW_MAX_OFFSET 12 #define AC_PARAM_ECW_MIN_OFFSET 8 diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 58d7d36924e8..01b95427fee0 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -36,7 +36,7 @@ #include "trx.h" #include "led.h" -static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(u16 fc, +static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(__le16 fc, unsigned int skb_queue) { @@ -617,13 +617,15 @@ static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw, u8 *tmp_buf; u8 *praddr; u8 *psaddr; - u16 fc, type; + __le16 fc; + u16 type, c_fc; bool packet_matchbssid, packet_toself, packet_beacon; tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; hdr = (struct ieee80211_hdr *)tmp_buf; - fc = le16_to_cpu(hdr->frame_control); + fc = hdr->frame_control; + c_fc = le16_to_cpu(fc); type = WLAN_FC_GET_TYPE(fc); praddr = hdr->addr1; psaddr = hdr->addr2; @@ -631,8 +633,8 @@ static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw, packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && (!compare_ether_addr(mac->bssid, - (fc & IEEE80211_FCTL_TODS) ? - hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ? + (c_fc & IEEE80211_FCTL_TODS) ? + hdr->addr1 : (c_fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : hdr->addr3)) && (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv)); @@ -728,20 +730,17 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); bool defaultadapter = true; - struct ieee80211_sta *sta = ieee80211_find_sta(mac->vif, mac->bssid); - u8 *pdesc = (u8 *) pdesc_tx; struct rtl_tcb_desc tcb_desc; u8 *qc = ieee80211_get_qos_ctl(hdr); u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; u16 seq_number; - u16 fc = le16_to_cpu(hdr->frame_control); + __le16 fc = hdr->frame_control; u8 rate_flag = info->control.rates[0].flags; enum rtl_desc_qsel fw_qsel = - _rtl92ce_map_hwqueue_to_fwqueue(le16_to_cpu(hdr->frame_control), - queue_index); + _rtl92ce_map_hwqueue_to_fwqueue(fc, queue_index); bool firstseg = ((hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); @@ -901,7 +900,7 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, PCI_DMA_TODEVICE); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); - u16 fc = le16_to_cpu(hdr->frame_control); + __le16 fc = hdr->frame_control; CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h index a5fcdfb69cda..803adcc80c96 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h @@ -40,470 +40,494 @@ #define USB_HWDESC_HEADER_LEN 32 #define CRCLENGTH 4 +/* Define a macro that takes a le32 word, converts it to host ordering, + * right shifts by a specified count, creates a mask of the specified + * bit count, and extracts that number of bits. + */ + +#define SHIFT_AND_MASK_LE(__pdesc, __shift, __mask) \ + ((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) & \ + BIT_LEN_MASK_32(__mask)) + +/* Define a macro that clears a bit field in an le32 word and + * sets the specified value into that bit field. The resulting + * value remains in le32 ordering; however, it is properly converted + * to host ordering for the clear and set operations before conversion + * back to le32. + */ + +#define SET_BITS_OFFSET_LE(__pdesc, __shift, __len, __val) \ + (*(__le32 *)(__pdesc) = \ + (cpu_to_le32((le32_to_cpu(*((__le32 *)(__pdesc))) & \ + (~(BIT_OFFSET_LEN_MASK_32((__shift), __len)))) | \ + (((u32)(__val) & BIT_LEN_MASK_32(__len)) << (__shift))))); + +/* macros to read/write various fields in RX or TX descriptors */ + #define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val) + SET_BITS_OFFSET_LE(__pdesc, 0, 16, __val) #define SET_TX_DESC_OFFSET(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val) + SET_BITS_OFFSET_LE(__pdesc, 16, 8, __val) #define SET_TX_DESC_BMC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val) + SET_BITS_OFFSET_LE(__pdesc, 24, 1, __val) #define SET_TX_DESC_HTC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val) + SET_BITS_OFFSET_LE(__pdesc, 25, 1, __val) #define SET_TX_DESC_LAST_SEG(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val) + SET_BITS_OFFSET_LE(__pdesc, 26, 1, __val) #define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val) + SET_BITS_OFFSET_LE(__pdesc, 27, 1, __val) #define SET_TX_DESC_LINIP(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val) + SET_BITS_OFFSET_LE(__pdesc, 28, 1, __val) #define SET_TX_DESC_NO_ACM(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val) + SET_BITS_OFFSET_LE(__pdesc, 29, 1, __val) #define SET_TX_DESC_GF(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val) + SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val) #define SET_TX_DESC_OWN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) + SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val) #define GET_TX_DESC_PKT_SIZE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 0, 16) + SHIFT_AND_MASK_LE(__pdesc, 0, 16) #define GET_TX_DESC_OFFSET(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 16, 8) + SHIFT_AND_MASK_LE(__pdesc, 16, 8) #define GET_TX_DESC_BMC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 24, 1) + SHIFT_AND_MASK_LE(__pdesc, 24, 1) #define GET_TX_DESC_HTC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 25, 1) + SHIFT_AND_MASK_LE(__pdesc, 25, 1) #define GET_TX_DESC_LAST_SEG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 26, 1) + SHIFT_AND_MASK_LE(__pdesc, 26, 1) #define GET_TX_DESC_FIRST_SEG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 27, 1) + SHIFT_AND_MASK_LE(__pdesc, 27, 1) #define GET_TX_DESC_LINIP(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 28, 1) + SHIFT_AND_MASK_LE(__pdesc, 28, 1) #define GET_TX_DESC_NO_ACM(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 29, 1) + SHIFT_AND_MASK_LE(__pdesc, 29, 1) #define GET_TX_DESC_GF(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 30, 1) + SHIFT_AND_MASK_LE(__pdesc, 30, 1) #define GET_TX_DESC_OWN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 31, 1) + SHIFT_AND_MASK_LE(__pdesc, 31, 1) #define SET_TX_DESC_MACID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 5, __val) + SET_BITS_OFFSET_LE(__pdesc+4, 0, 5, __val) #define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 5, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+4, 5, 1, __val) #define SET_TX_DESC_BK(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 6, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+4, 6, 1, __val) #define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 7, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+4, 7, 1, __val) #define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val) + SET_BITS_OFFSET_LE(__pdesc+4, 8, 5, __val) #define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+4, 13, 1, __val) #define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+4, 14, 1, __val) #define SET_TX_DESC_PIFS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+4, 15, 1, __val) #define SET_TX_DESC_RATE_ID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 4, __val) + SET_BITS_OFFSET_LE(__pdesc+4, 16, 4, __val) #define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 20, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+4, 20, 1, __val) #define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+4, 21, 1, __val) #define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val) + SET_BITS_OFFSET_LE(__pdesc+4, 22, 2, __val) #define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 8, __val) + SET_BITS_OFFSET_LE(__pdesc+4, 24, 8, __val) #define GET_TX_DESC_MACID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 0, 5) + SHIFT_AND_MASK_LE(__pdesc+4, 0, 5) #define GET_TX_DESC_AGG_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 5, 1) + SHIFT_AND_MASK_LE(__pdesc+4, 5, 1) #define GET_TX_DESC_AGG_BREAK(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 6, 1) + SHIFT_AND_MASK_LE(__pdesc+4, 6, 1) #define GET_TX_DESC_RDG_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 7, 1) + SHIFT_AND_MASK_LE(__pdesc+4, 7, 1) #define GET_TX_DESC_QUEUE_SEL(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 8, 5) + SHIFT_AND_MASK_LE(__pdesc+4, 8, 5) #define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 13, 1) + SHIFT_AND_MASK_LE(__pdesc+4, 13, 1) #define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 14, 1) + SHIFT_AND_MASK_LE(__pdesc+4, 14, 1) #define GET_TX_DESC_PIFS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 15, 1) + SHIFT_AND_MASK_LE(__pdesc+4, 15, 1) #define GET_TX_DESC_RATE_ID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 16, 4) + SHIFT_AND_MASK_LE(__pdesc+4, 16, 4) #define GET_TX_DESC_NAV_USE_HDR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 20, 1) + SHIFT_AND_MASK_LE(__pdesc+4, 20, 1) #define GET_TX_DESC_EN_DESC_ID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 21, 1) + SHIFT_AND_MASK_LE(__pdesc+4, 21, 1) #define GET_TX_DESC_SEC_TYPE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 22, 2) + SHIFT_AND_MASK_LE(__pdesc+4, 22, 2) #define GET_TX_DESC_PKT_OFFSET(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 24, 8) + SHIFT_AND_MASK_LE(__pdesc+4, 24, 8) #define SET_TX_DESC_RTS_RC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 6, __val) + SET_BITS_OFFSET_LE(__pdesc+8, 0, 6, __val) #define SET_TX_DESC_DATA_RC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 6, 6, __val) + SET_BITS_OFFSET_LE(__pdesc+8, 6, 6, __val) #define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val) + SET_BITS_OFFSET_LE(__pdesc+8, 14, 2, __val) #define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+8, 17, 1, __val) #define SET_TX_DESC_RAW(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+8, 18, 1, __val) #define SET_TX_DESC_CCX(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+8, 19, 1, __val) #define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val) + SET_BITS_OFFSET_LE(__pdesc+8, 20, 3, __val) #define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+8, 24, 1, __val) #define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 25, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+8, 25, 1, __val) #define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 26, 2, __val) + SET_BITS_OFFSET_LE(__pdesc+8, 26, 2, __val) #define SET_TX_DESC_TX_ANTL(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 28, 2, __val) + SET_BITS_OFFSET_LE(__pdesc+8, 28, 2, __val) #define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 30, 2, __val) + SET_BITS_OFFSET_LE(__pdesc+8, 30, 2, __val) #define GET_TX_DESC_RTS_RC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 0, 6) + SHIFT_AND_MASK_LE(__pdesc+8, 0, 6) #define GET_TX_DESC_DATA_RC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 6, 6) + SHIFT_AND_MASK_LE(__pdesc+8, 6, 6) #define GET_TX_DESC_BAR_RTY_TH(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 14, 2) + SHIFT_AND_MASK_LE(__pdesc+8, 14, 2) #define GET_TX_DESC_MORE_FRAG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 17, 1) + SHIFT_AND_MASK_LE(__pdesc+8, 17, 1) #define GET_TX_DESC_RAW(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 18, 1) + SHIFT_AND_MASK_LE(__pdesc+8, 18, 1) #define GET_TX_DESC_CCX(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 19, 1) + SHIFT_AND_MASK_LE(__pdesc+8, 19, 1) #define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 20, 3) + SHIFT_AND_MASK_LE(__pdesc+8, 20, 3) #define GET_TX_DESC_ANTSEL_A(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 24, 1) + SHIFT_AND_MASK_LE(__pdesc+8, 24, 1) #define GET_TX_DESC_ANTSEL_B(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 25, 1) + SHIFT_AND_MASK_LE(__pdesc+8, 25, 1) #define GET_TX_DESC_TX_ANT_CCK(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 26, 2) + SHIFT_AND_MASK_LE(__pdesc+8, 26, 2) #define GET_TX_DESC_TX_ANTL(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 28, 2) + SHIFT_AND_MASK_LE(__pdesc+8, 28, 2) #define GET_TX_DESC_TX_ANT_HT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 30, 2) + SHIFT_AND_MASK_LE(__pdesc+8, 30, 2) #define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 8, __val) + SET_BITS_OFFSET_LE(__pdesc+12, 0, 8, __val) #define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 8, __val) + SET_BITS_OFFSET_LE(__pdesc+12, 8, 8, __val) #define SET_TX_DESC_SEQ(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 12, __val) + SET_BITS_OFFSET_LE(__pdesc+12, 16, 12, __val) #define SET_TX_DESC_PKT_ID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 28, 4, __val) + SET_BITS_OFFSET_LE(__pdesc+12, 28, 4, __val) #define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 0, 8) + SHIFT_AND_MASK_LE(__pdesc+12, 0, 8) #define GET_TX_DESC_TAIL_PAGE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 8, 8) + SHIFT_AND_MASK_LE(__pdesc+12, 8, 8) #define GET_TX_DESC_SEQ(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 16, 12) + SHIFT_AND_MASK_LE(__pdesc+12, 16, 12) #define GET_TX_DESC_PKT_ID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 28, 4) + SHIFT_AND_MASK_LE(__pdesc+12, 28, 4) #define SET_TX_DESC_RTS_RATE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 5, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 0, 5, __val) #define SET_TX_DESC_AP_DCFE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 5, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 5, 1, __val) #define SET_TX_DESC_QOS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 6, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 6, 1, __val) #define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 7, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 7, 1, __val) #define SET_TX_DESC_USE_RATE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 8, 1, __val) #define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 9, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 9, 1, __val) #define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 10, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 10, 1, __val) #define SET_TX_DESC_CTS2SELF(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 11, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 11, 1, __val) #define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 12, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 12, 1, __val) #define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 13, 1, __val) #define SET_TX_DESC_PORT_ID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 14, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 14, 1, __val) #define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 18, 1, __val) #define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 19, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 19, 1, __val) #define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 20, 2, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 20, 2, __val) #define SET_TX_DESC_TX_STBC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 22, 2, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 22, 2, __val) #define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 24, 1, __val) #define SET_TX_DESC_DATA_BW(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 25, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 25, 1, __val) #define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 26, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 26, 1, __val) #define SET_TX_DESC_RTS_BW(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 27, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 27, 1, __val) #define SET_TX_DESC_RTS_SC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 28, 2, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 28, 2, __val) #define SET_TX_DESC_RTS_STBC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 30, 2, __val) + SET_BITS_OFFSET_LE(__pdesc+16, 30, 2, __val) #define GET_TX_DESC_RTS_RATE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 0, 5) + SHIFT_AND_MASK_LE(__pdesc+16, 0, 5) #define GET_TX_DESC_AP_DCFE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 5, 1) + SHIFT_AND_MASK_LE(__pdesc+16, 5, 1) #define GET_TX_DESC_QOS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 6, 1) + SHIFT_AND_MASK_LE(__pdesc+16, 6, 1) #define GET_TX_DESC_HWSEQ_EN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 7, 1) + SHIFT_AND_MASK_LE(__pdesc+16, 7, 1) #define GET_TX_DESC_USE_RATE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 8, 1) + SHIFT_AND_MASK_LE(__pdesc+16, 8, 1) #define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 9, 1) + SHIFT_AND_MASK_LE(__pdesc+16, 9, 1) #define GET_TX_DESC_DISABLE_FB(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 10, 1) + SHIFT_AND_MASK_LE(__pdesc+16, 10, 1) #define GET_TX_DESC_CTS2SELF(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 11, 1) + SHIFT_AND_MASK_LE(__pdesc+16, 11, 1) #define GET_TX_DESC_RTS_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 12, 1) + SHIFT_AND_MASK_LE(__pdesc+16, 12, 1) #define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 13, 1) + SHIFT_AND_MASK_LE(__pdesc+16, 13, 1) #define GET_TX_DESC_PORT_ID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 14, 1) + SHIFT_AND_MASK_LE(__pdesc+16, 14, 1) #define GET_TX_DESC_WAIT_DCTS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 18, 1) + SHIFT_AND_MASK_LE(__pdesc+16, 18, 1) #define GET_TX_DESC_CTS2AP_EN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 19, 1) + SHIFT_AND_MASK_LE(__pdesc+16, 19, 1) #define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 20, 2) + SHIFT_AND_MASK_LE(__pdesc+16, 20, 2) #define GET_TX_DESC_TX_STBC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 22, 2) + SHIFT_AND_MASK_LE(__pdesc+16, 22, 2) #define GET_TX_DESC_DATA_SHORT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 24, 1) + SHIFT_AND_MASK_LE(__pdesc+16, 24, 1) #define GET_TX_DESC_DATA_BW(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 25, 1) + SHIFT_AND_MASK_LE(__pdesc+16, 25, 1) #define GET_TX_DESC_RTS_SHORT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 26, 1) + SHIFT_AND_MASK_LE(__pdesc+16, 26, 1) #define GET_TX_DESC_RTS_BW(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 27, 1) + SHIFT_AND_MASK_LE(__pdesc+16, 27, 1) #define GET_TX_DESC_RTS_SC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 28, 2) + SHIFT_AND_MASK_LE(__pdesc+16, 28, 2) #define GET_TX_DESC_RTS_STBC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 30, 2) + SHIFT_AND_MASK_LE(__pdesc+16, 30, 2) #define SET_TX_DESC_TX_RATE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 6, __val) + SET_BITS_OFFSET_LE(__pdesc+20, 0, 6, __val) #define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 6, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+20, 6, 1, __val) #define SET_TX_DESC_CCX_TAG(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+20, 7, 1, __val) #define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 5, __val) + SET_BITS_OFFSET_LE(__pdesc+20, 8, 5, __val) #define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val) + SET_BITS_OFFSET_LE(__pdesc+20, 13, 4, __val) #define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 17, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+20, 17, 1, __val) #define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 18, 6, __val) + SET_BITS_OFFSET_LE(__pdesc+20, 18, 6, __val) #define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 24, 8, __val) + SET_BITS_OFFSET_LE(__pdesc+20, 24, 8, __val) #define GET_TX_DESC_TX_RATE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 0, 6) + SHIFT_AND_MASK_LE(__pdesc+20, 0, 6) #define GET_TX_DESC_DATA_SHORTGI(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 6, 1) + SHIFT_AND_MASK_LE(__pdesc+20, 6, 1) #define GET_TX_DESC_CCX_TAG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 7, 1) + SHIFT_AND_MASK_LE(__pdesc+20, 7, 1) #define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 8, 5) + SHIFT_AND_MASK_LE(__pdesc+20, 8, 5) #define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 13, 4) + SHIFT_AND_MASK_LE(__pdesc+20, 13, 4) #define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 17, 1) + SHIFT_AND_MASK_LE(__pdesc+20, 17, 1) #define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 18, 6) + SHIFT_AND_MASK_LE(__pdesc+20, 18, 6) #define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 24, 8) + SHIFT_AND_MASK_LE(__pdesc+20, 24, 8) #define SET_TX_DESC_TXAGC_A(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 5, __val) + SET_BITS_OFFSET_LE(__pdesc+24, 0, 5, __val) #define SET_TX_DESC_TXAGC_B(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 5, 5, __val) + SET_BITS_OFFSET_LE(__pdesc+24, 5, 5, __val) #define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 10, 1, __val) + SET_BITS_OFFSET_LE(__pdesc+24, 10, 1, __val) #define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 11, 5, __val) + SET_BITS_OFFSET_LE(__pdesc+24, 11, 5, __val) #define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 16, 4, __val) + SET_BITS_OFFSET_LE(__pdesc+24, 16, 4, __val) #define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 20, 4, __val) + SET_BITS_OFFSET_LE(__pdesc+24, 20, 4, __val) #define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 24, 4, __val) + SET_BITS_OFFSET_LE(__pdesc+24, 24, 4, __val) #define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 28, 4, __val) + SET_BITS_OFFSET_LE(__pdesc+24, 28, 4, __val) #define GET_TX_DESC_TXAGC_A(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 0, 5) + SHIFT_AND_MASK_LE(__pdesc+24, 0, 5) #define GET_TX_DESC_TXAGC_B(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 5, 5) + SHIFT_AND_MASK_LE(__pdesc+24, 5, 5) #define GET_TX_DESC_USE_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 10, 1) + SHIFT_AND_MASK_LE(__pdesc+24, 10, 1) #define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 11, 5) + SHIFT_AND_MASK_LE(__pdesc+24, 11, 5) #define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 16, 4) + SHIFT_AND_MASK_LE(__pdesc+24, 16, 4) #define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 20, 4) + SHIFT_AND_MASK_LE(__pdesc+24, 20, 4) #define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 24, 4) + SHIFT_AND_MASK_LE(__pdesc+24, 24, 4) #define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 28, 4) + SHIFT_AND_MASK_LE(__pdesc+24, 28, 4) #define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val) + SET_BITS_OFFSET_LE(__pdesc+28, 0, 16, __val) #define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 16, 4, __val) + SET_BITS_OFFSET_LE(__pdesc+28, 16, 4, __val) #define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 20, 4, __val) + SET_BITS_OFFSET_LE(__pdesc+28, 20, 4, __val) #define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 24, 4, __val) + SET_BITS_OFFSET_LE(__pdesc+28, 24, 4, __val) #define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 28, 4, __val) + SET_BITS_OFFSET_LE(__pdesc+28, 28, 4, __val) #define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 0, 16) + SHIFT_AND_MASK_LE(__pdesc+28, 0, 16) #define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 16, 4) + SHIFT_AND_MASK_LE(__pdesc+28, 16, 4) #define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 20, 4) + SHIFT_AND_MASK_LE(__pdesc+28, 20, 4) #define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 24, 4) + SHIFT_AND_MASK_LE(__pdesc+28, 24, 4) #define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 28, 4) + SHIFT_AND_MASK_LE(__pdesc+28, 28, 4) #define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+32, 0, 32, __val) + SET_BITS_OFFSET_LE(__pdesc+32, 0, 32, __val) #define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+36, 0, 32, __val) + SET_BITS_OFFSET_LE(__pdesc+36, 0, 32, __val) #define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+32, 0, 32) + SHIFT_AND_MASK_LE(__pdesc+32, 0, 32) #define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+36, 0, 32) + SHIFT_AND_MASK_LE(__pdesc+36, 0, 32) #define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val) + SET_BITS_OFFSET_LE(__pdesc+40, 0, 32, __val) #define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+44, 0, 32, __val) + SET_BITS_OFFSET_LE(__pdesc+44, 0, 32, __val) #define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+40, 0, 32) + SHIFT_AND_MASK_LE(__pdesc+40, 0, 32) #define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+44, 0, 32) + SHIFT_AND_MASK_LE(__pdesc+44, 0, 32) #define GET_RX_DESC_PKT_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 0, 14) + SHIFT_AND_MASK_LE(__pdesc, 0, 14) #define GET_RX_DESC_CRC32(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 14, 1) + SHIFT_AND_MASK_LE(__pdesc, 14, 1) #define GET_RX_DESC_ICV(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 15, 1) + SHIFT_AND_MASK_LE(__pdesc, 15, 1) #define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 16, 4) + SHIFT_AND_MASK_LE(__pdesc, 16, 4) #define GET_RX_DESC_SECURITY(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 20, 3) + SHIFT_AND_MASK_LE(__pdesc, 20, 3) #define GET_RX_DESC_QOS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 23, 1) + SHIFT_AND_MASK_LE(__pdesc, 23, 1) #define GET_RX_DESC_SHIFT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 24, 2) + SHIFT_AND_MASK_LE(__pdesc, 24, 2) #define GET_RX_DESC_PHYST(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 26, 1) + SHIFT_AND_MASK_LE(__pdesc, 26, 1) #define GET_RX_DESC_SWDEC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 27, 1) + SHIFT_AND_MASK_LE(__pdesc, 27, 1) #define GET_RX_DESC_LS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 28, 1) + SHIFT_AND_MASK_LE(__pdesc, 28, 1) #define GET_RX_DESC_FS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 29, 1) + SHIFT_AND_MASK_LE(__pdesc, 29, 1) #define GET_RX_DESC_EOR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 30, 1) + SHIFT_AND_MASK_LE(__pdesc, 30, 1) #define GET_RX_DESC_OWN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 31, 1) + SHIFT_AND_MASK_LE(__pdesc, 31, 1) #define SET_RX_DESC_PKT_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val) + SET_BITS_OFFSET_LE(__pdesc, 0, 14, __val) #define SET_RX_DESC_EOR(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val) + SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val) #define SET_RX_DESC_OWN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) + SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val) #define GET_RX_DESC_MACID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 0, 5) + SHIFT_AND_MASK_LE(__pdesc+4, 0, 5) #define GET_RX_DESC_TID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 5, 4) + SHIFT_AND_MASK_LE(__pdesc+4, 5, 4) #define GET_RX_DESC_HWRSVD(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 9, 5) + SHIFT_AND_MASK_LE(__pdesc+4, 9, 5) #define GET_RX_DESC_PAGGR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 14, 1) + SHIFT_AND_MASK_LE(__pdesc+4, 14, 1) #define GET_RX_DESC_FAGGR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 15, 1) + SHIFT_AND_MASK_LE(__pdesc+4, 15, 1) #define GET_RX_DESC_A1_FIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 16, 4) + SHIFT_AND_MASK_LE(__pdesc+4, 16, 4) #define GET_RX_DESC_A2_FIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 20, 4) + SHIFT_AND_MASK_LE(__pdesc+4, 20, 4) #define GET_RX_DESC_PAM(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 24, 1) + SHIFT_AND_MASK_LE(__pdesc+4, 24, 1) #define GET_RX_DESC_PWR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 25, 1) + SHIFT_AND_MASK_LE(__pdesc+4, 25, 1) #define GET_RX_DESC_MD(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 26, 1) + SHIFT_AND_MASK_LE(__pdesc+4, 26, 1) #define GET_RX_DESC_MF(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 27, 1) + SHIFT_AND_MASK_LE(__pdesc+4, 27, 1) #define GET_RX_DESC_TYPE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 28, 2) + SHIFT_AND_MASK_LE(__pdesc+4, 28, 2) #define GET_RX_DESC_MC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 30, 1) + SHIFT_AND_MASK_LE(__pdesc+4, 30, 1) #define GET_RX_DESC_BC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 31, 1) + SHIFT_AND_MASK_LE(__pdesc+4, 31, 1) #define GET_RX_DESC_SEQ(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 0, 12) + SHIFT_AND_MASK_LE(__pdesc+8, 0, 12) #define GET_RX_DESC_FRAG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 12, 4) + SHIFT_AND_MASK_LE(__pdesc+8, 12, 4) #define GET_RX_DESC_NEXT_PKT_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 16, 14) + SHIFT_AND_MASK_LE(__pdesc+8, 16, 14) #define GET_RX_DESC_NEXT_IND(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 30, 1) + SHIFT_AND_MASK_LE(__pdesc+8, 30, 1) #define GET_RX_DESC_RSVD(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 31, 1) + SHIFT_AND_MASK_LE(__pdesc+8, 31, 1) #define GET_RX_DESC_RXMCS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 0, 6) + SHIFT_AND_MASK_LE(__pdesc+12, 0, 6) #define GET_RX_DESC_RXHT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 6, 1) + SHIFT_AND_MASK_LE(__pdesc+12, 6, 1) #define GET_RX_DESC_SPLCP(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 8, 1) + SHIFT_AND_MASK_LE(__pdesc+12, 8, 1) #define GET_RX_DESC_BW(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 9, 1) + SHIFT_AND_MASK_LE(__pdesc+12, 9, 1) #define GET_RX_DESC_HTC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 10, 1) + SHIFT_AND_MASK_LE(__pdesc+12, 10, 1) #define GET_RX_DESC_HWPC_ERR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 14, 1) + SHIFT_AND_MASK_LE(__pdesc+12, 14, 1) #define GET_RX_DESC_HWPC_IND(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 15, 1) + SHIFT_AND_MASK_LE(__pdesc+12, 15, 1) #define GET_RX_DESC_IV0(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 16, 16) + SHIFT_AND_MASK_LE(__pdesc+12, 16, 16) #define GET_RX_DESC_IV1(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 0, 32) + SHIFT_AND_MASK_LE(__pdesc+16, 0, 32) #define GET_RX_DESC_TSFL(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 0, 32) + SHIFT_AND_MASK_LE(__pdesc+20, 0, 32) #define GET_RX_DESC_BUFF_ADDR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 0, 32) + SHIFT_AND_MASK_LE(__pdesc+24, 0, 32) #define GET_RX_DESC_BUFF_ADDR64(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 0, 32) + SHIFT_AND_MASK_LE(__pdesc+28, 0, 32) #define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val) + SET_BITS_OFFSET_LE(__pdesc+24, 0, 32, __val) #define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val) + SET_BITS_OFFSET_LE(__pdesc+28, 0, 32, __val) #define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \ do { \ diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index 91340c547dbb..a4b2613d6a8c 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -126,7 +126,7 @@ static u32 _usb_read_sync(struct usb_device *udev, u32 addr, u16 len) wvalue = (u16)addr; _usbctrl_vendorreq_sync_read(udev, request, wvalue, index, data, len); - ret = le32_to_cpu(*data); + ret = *data; kfree(data); return ret; } @@ -163,7 +163,7 @@ static void _usb_write_async(struct usb_device *udev, u32 addr, u32 val, request = REALTEK_USB_VENQT_CMD_REQ; index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */ wvalue = (u16)(addr&0x0000ffff); - data = cpu_to_le32(val); + data = val; _usbctrl_vendorreq_async_write(udev, request, wvalue, index, &data, len); } @@ -437,7 +437,7 @@ static void _rtl_usb_rx_process_agg(struct ieee80211_hw *hw, u8 *rxdesc = skb->data; struct ieee80211_hdr *hdr; bool unicast = false; - u16 fc; + __le16 fc; struct ieee80211_rx_status rx_status = {0}; struct rtl_stats stats = { .signal = 0, @@ -449,7 +449,7 @@ static void _rtl_usb_rx_process_agg(struct ieee80211_hw *hw, rtlpriv->cfg->ops->query_rx_desc(hw, &stats, &rx_status, rxdesc, skb); skb_pull(skb, (stats.rx_drvinfo_size + stats.rx_bufshift)); hdr = (struct ieee80211_hdr *)(skb->data); - fc = le16_to_cpu(hdr->frame_control); + fc = hdr->frame_control; if (!stats.crc) { memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); @@ -480,7 +480,7 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw, u8 *rxdesc = skb->data; struct ieee80211_hdr *hdr; bool unicast = false; - u16 fc; + __le16 fc; struct ieee80211_rx_status rx_status = {0}; struct rtl_stats stats = { .signal = 0, @@ -492,7 +492,7 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw, rtlpriv->cfg->ops->query_rx_desc(hw, &stats, &rx_status, rxdesc, skb); skb_pull(skb, (stats.rx_drvinfo_size + stats.rx_bufshift)); hdr = (struct ieee80211_hdr *)(skb->data); - fc = le16_to_cpu(hdr->frame_control); + fc = hdr->frame_control; if (!stats.crc) { memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); @@ -853,7 +853,7 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct rtl_tx_desc *pdesc = NULL; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); - u16 fc = le16_to_cpu(hdr->frame_control); + __le16 fc = hdr->frame_control; u8 *pda_addr = hdr->addr1; /* ssn */ u8 *qc = NULL; @@ -892,7 +892,7 @@ static int rtl_usb_tx(struct ieee80211_hw *hw, struct sk_buff *skb) struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); - u16 fc = le16_to_cpu(hdr->frame_control); + __le16 fc = hdr->frame_control; u16 hw_queue; if (unlikely(is_hal_stop(rtlhal))) diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h index c83311655104..abadfe918d30 100644 --- a/drivers/net/wireless/rtlwifi/usb.h +++ b/drivers/net/wireless/rtlwifi/usb.h @@ -114,7 +114,7 @@ struct rtl_usb { u32 irq_mask[2]; bool irq_enabled; - u16 (*usb_mq_to_hwq)(u16 fc, u16 mac80211_queue_index); + u16 (*usb_mq_to_hwq)(__le16 fc, u16 mac80211_queue_index); /* Tx */ u8 out_ep_nums ; diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index c0f8140e8874..053943967a1c 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -1427,7 +1427,7 @@ struct rtl_hal_usbint_cfg { /* endpoint mapping */ int (*usb_endpoint_mapping)(struct ieee80211_hw *hw); - u16 (*usb_mq_to_hwq)(u16 fc, u16 mac80211_queue_index); + u16 (*usb_mq_to_hwq)(__le16 fc, u16 mac80211_queue_index); }; struct rtl_hal_cfg { @@ -1646,7 +1646,7 @@ struct bt_coexist_info { #define READEF2BYTE(_ptr) \ EF2BYTE(*((u16 *)(_ptr))) #define READEF4BYTE(_ptr) \ - EF4BYTE(*((u32 *)(_ptr))) + EF4BYTE(*((__le32 *)(_ptr))) /* Write data to memory */ #define WRITEEF1BYTE(_ptr, _val) \ @@ -1759,10 +1759,10 @@ Set subfield of little-endian 4-byte value to specified value. */ #define packet_get_type(_packet) (EF1BYTE((_packet).octet[0]) & 0xFC) #define RTL_WATCH_DOG_TIME 2000 #define MSECS(t) msecs_to_jiffies(t) -#define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS) -#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE) -#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE) -#define WLAN_FC_MORE_DATA(fc) ((fc) & IEEE80211_FCTL_MOREDATA) +#define WLAN_FC_GET_VERS(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_VERS) +#define WLAN_FC_GET_TYPE(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) +#define WLAN_FC_GET_STYPE(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) +#define WLAN_FC_MORE_DATA(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_MOREDATA) #define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) #define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) -- cgit v1.2.3 From 9e0bc671873c96104b8f793b03661f443e1c4b5a Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 19 Feb 2011 16:30:02 -0600 Subject: rtlwifi: Remove obsolete/unused macros The original code has many macros that are no longer needed. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.h | 38 +++------------ drivers/net/wireless/rtlwifi/wifi.h | 97 ++++++++++--------------------------- 2 files changed, 33 insertions(+), 102 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h index c95982b030da..043045342bc7 100644 --- a/drivers/net/wireless/rtlwifi/base.h +++ b/drivers/net/wireless/rtlwifi/base.h @@ -53,46 +53,22 @@ #define FRAME_OFFSET_SEQUENCE 22 #define FRAME_OFFSET_ADDRESS4 24 -#define SET_80211_HDR_FRAME_CONTROL(_hdr, _val) \ - WRITEEF2BYTE(_hdr, _val) -#define SET_80211_HDR_TYPE_AND_SUBTYPE(_hdr, _val) \ - WRITEEF1BYTE(_hdr, _val) -#define SET_80211_HDR_PWR_MGNT(_hdr, _val) \ - SET_BITS_TO_LE_2BYTE(_hdr, 12, 1, _val) -#define SET_80211_HDR_TO_DS(_hdr, _val) \ - SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val) #define SET_80211_PS_POLL_AID(_hdr, _val) \ - WRITEEF2BYTE(((u8 *)(_hdr)) + 2, _val) + (*(u16 *)((u8 *)(_hdr) + 2) = le16_to_cpu(_val)) #define SET_80211_PS_POLL_BSSID(_hdr, _val) \ - CP_MACADDR(((u8 *)(_hdr)) + 4, (u8 *)(_val)) + memcpy(((u8 *)(_hdr)) + 4, (u8 *)(_val), ETH_ALEN) #define SET_80211_PS_POLL_TA(_hdr, _val) \ - CP_MACADDR(((u8 *)(_hdr)) + 10, (u8 *)(_val)) + memcpy(((u8 *)(_hdr)) + 10, (u8 *)(_val), ETH_ALEN) #define SET_80211_HDR_DURATION(_hdr, _val) \ - WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_DURATION, _val) + (*(u16 *)((u8 *)(_hdr) + FRAME_OFFSET_DURATION) = le16_to_cpu(_val)) #define SET_80211_HDR_ADDRESS1(_hdr, _val) \ - CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8*)(_val)) + memcpy((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8*)(_val), ETH_ALEN) #define SET_80211_HDR_ADDRESS2(_hdr, _val) \ - CP_MACADDR((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS2, (u8 *)(_val)) + memcpy((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS2, (u8 *)(_val), ETH_ALEN) #define SET_80211_HDR_ADDRESS3(_hdr, _val) \ - CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val)) -#define SET_80211_HDR_FRAGMENT_SEQUENCE(_hdr, _val) \ - WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_SEQUENCE, _val) - -#define SET_BEACON_PROBE_RSP_TIME_STAMP_LOW(__phdr, __val) \ - WRITEEF4BYTE(((u8 *)(__phdr)) + 24, __val) -#define SET_BEACON_PROBE_RSP_TIME_STAMP_HIGH(__phdr, __val) \ - WRITEEF4BYTE(((u8 *)(__phdr)) + 28, __val) -#define SET_BEACON_PROBE_RSP_BEACON_INTERVAL(__phdr, __val) \ - WRITEEF2BYTE(((u8 *)(__phdr)) + 32, __val) -#define GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) \ - READEF2BYTE(((u8 *)(__phdr)) + 34) -#define SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \ - WRITEEF2BYTE(((u8 *)(__phdr)) + 34, __val) -#define MASK_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \ - SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, \ - (GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) & (~(__val)))) + memcpy((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val), ETH_ALEN) int rtl_init_core(struct ieee80211_hw *hw); void rtl_deinit_core(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 053943967a1c..4b90b35f211e 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -1632,7 +1632,7 @@ struct bt_coexist_info { 2. Before write integer to IO. 3. After read integer from IO. ****************************************/ -/* Convert little data endian to host */ +/* Convert little data endian to host ordering */ #define EF1BYTE(_val) \ ((u8)(_val)) #define EF2BYTE(_val) \ @@ -1640,27 +1640,21 @@ struct bt_coexist_info { #define EF4BYTE(_val) \ (le32_to_cpu(_val)) -/* Read data from memory */ -#define READEF1BYTE(_ptr) \ - EF1BYTE(*((u8 *)(_ptr))) +/* Read le16 data from memory and convert to host ordering */ #define READEF2BYTE(_ptr) \ EF2BYTE(*((u16 *)(_ptr))) -#define READEF4BYTE(_ptr) \ - EF4BYTE(*((__le32 *)(_ptr))) -/* Write data to memory */ -#define WRITEEF1BYTE(_ptr, _val) \ - (*((u8 *)(_ptr))) = EF1BYTE(_val) +/* Write le16 data to memory in host ordering */ #define WRITEEF2BYTE(_ptr, _val) \ (*((u16 *)(_ptr))) = EF2BYTE(_val) -#define WRITEEF4BYTE(_ptr, _val) \ - (*((u32 *)(_ptr))) = EF4BYTE(_val) - -/*Example: -BIT_LEN_MASK_32(0) => 0x00000000 -BIT_LEN_MASK_32(1) => 0x00000001 -BIT_LEN_MASK_32(2) => 0x00000003 -BIT_LEN_MASK_32(32) => 0xFFFFFFFF*/ + +/* Create a bit mask + * Examples: + * BIT_LEN_MASK_32(0) => 0x00000000 + * BIT_LEN_MASK_32(1) => 0x00000001 + * BIT_LEN_MASK_32(2) => 0x00000003 + * BIT_LEN_MASK_32(32) => 0xFFFFFFFF + */ #define BIT_LEN_MASK_32(__bitlen) \ (0xFFFFFFFF >> (32 - (__bitlen))) #define BIT_LEN_MASK_16(__bitlen) \ @@ -1668,9 +1662,11 @@ BIT_LEN_MASK_32(32) => 0xFFFFFFFF*/ #define BIT_LEN_MASK_8(__bitlen) \ (0xFF >> (8 - (__bitlen))) -/*Example: -BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003 -BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000*/ +/* Create an offset bit mask + * Examples: + * BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003 + * BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000 + */ #define BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen) \ (BIT_LEN_MASK_32(__bitlen) << (__bitoffset)) #define BIT_OFFSET_LEN_MASK_16(__bitoffset, __bitlen) \ @@ -1679,8 +1675,9 @@ BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000*/ (BIT_LEN_MASK_8(__bitlen) << (__bitoffset)) /*Description: -Return 4-byte value in host byte ordering from -4-byte pointer in little-endian system.*/ + * Return 4-byte value in host byte ordering from + * 4-byte pointer in little-endian system. + */ #define LE_P4BYTE_TO_HOST_4BYTE(__pstart) \ (EF4BYTE(*((u32 *)(__pstart)))) #define LE_P2BYTE_TO_HOST_2BYTE(__pstart) \ @@ -1688,28 +1685,10 @@ Return 4-byte value in host byte ordering from #define LE_P1BYTE_TO_HOST_1BYTE(__pstart) \ (EF1BYTE(*((u8 *)(__pstart)))) -/*Description: -Translate subfield (continuous bits in little-endian) of 4-byte -value to host byte ordering.*/ -#define LE_BITS_TO_4BYTE(__pstart, __bitoffset, __bitlen) \ - ( \ - (LE_P4BYTE_TO_HOST_4BYTE(__pstart) >> (__bitoffset)) & \ - BIT_LEN_MASK_32(__bitlen) \ - ) -#define LE_BITS_TO_2BYTE(__pstart, __bitoffset, __bitlen) \ - ( \ - (LE_P2BYTE_TO_HOST_2BYTE(__pstart) >> (__bitoffset)) & \ - BIT_LEN_MASK_16(__bitlen) \ - ) -#define LE_BITS_TO_1BYTE(__pstart, __bitoffset, __bitlen) \ - ( \ - (LE_P1BYTE_TO_HOST_1BYTE(__pstart) >> (__bitoffset)) & \ - BIT_LEN_MASK_8(__bitlen) \ - ) - -/*Description: -Mask subfield (continuous bits in little-endian) of 4-byte value -and return the result in 4-byte value in host byte ordering.*/ +/* Description: + * Mask subfield (continuous bits in little-endian) of 4-byte value + * and return the result in 4-byte value in host byte ordering. + */ #define LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) \ ( \ LE_P4BYTE_TO_HOST_4BYTE(__pstart) & \ @@ -1726,20 +1705,9 @@ and return the result in 4-byte value in host byte ordering.*/ (~BIT_OFFSET_LEN_MASK_8(__bitoffset, __bitlen)) \ ) -/*Description: -Set subfield of little-endian 4-byte value to specified value. */ -#define SET_BITS_TO_LE_4BYTE(__pstart, __bitoffset, __bitlen, __val) \ - *((u32 *)(__pstart)) = EF4BYTE \ - ( \ - LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) | \ - ((((u32)__val) & BIT_LEN_MASK_32(__bitlen)) << (__bitoffset)) \ - ); -#define SET_BITS_TO_LE_2BYTE(__pstart, __bitoffset, __bitlen, __val) \ - *((u16 *)(__pstart)) = EF2BYTE \ - ( \ - LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) | \ - ((((u16)__val) & BIT_LEN_MASK_16(__bitlen)) << (__bitoffset)) \ - ); +/* Description: + * Set subfield of little-endian 4-byte value to specified value. + */ #define SET_BITS_TO_LE_1BYTE(__pstart, __bitoffset, __bitlen, __val) \ *((u8 *)(__pstart)) = EF1BYTE \ ( \ @@ -1747,16 +1715,12 @@ Set subfield of little-endian 4-byte value to specified value. */ ((((u8)__val) & BIT_LEN_MASK_8(__bitlen)) << (__bitoffset)) \ ); -#define N_BYTE_ALIGMENT(__value, __aligment) ((__aligment == 1) ? \ - (__value) : (((__value + __aligment - 1) / __aligment) * __aligment)) - /**************************************** mem access macro define end ****************************************/ #define byte(x, n) ((x >> (8 * n)) & 0xff) -#define packet_get_type(_packet) (EF1BYTE((_packet).octet[0]) & 0xFC) #define RTL_WATCH_DOG_TIME 2000 #define MSECS(t) msecs_to_jiffies(t) #define WLAN_FC_GET_VERS(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_VERS) @@ -1791,15 +1755,6 @@ Set subfield of little-endian 4-byte value to specified value. */ #define container_of_dwork_rtl(x, y, z) \ container_of(container_of(x, struct delayed_work, work), y, z) -#define FILL_OCTET_STRING(_os, _octet, _len) \ - do { \ - (_os). octet = (u8 *)(_octet); \ - (_os). length = (_len); \ - } while (0); - -#define CP_MACADDR(des, src) \ - memcpy((des), (src), ETH_ALEN) - static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr) { return rtlpriv->io.read8_sync(rtlpriv, addr); -- cgit v1.2.3 From d96aa640967ab10641a0a389a4a1569efa54ac72 Mon Sep 17 00:00:00 2001 From: RA-Jay Hung Date: Sun, 20 Feb 2011 13:54:52 +0100 Subject: rt2x00: Add antenna setting for RT3070/RT3090/RT3390 with RX antenna diversity support For RT3070/RT3090/RT3390 with RX antenna diversity support, we must select default antenna using gpio control way even if we do not turn on antenna diversity feature. Seperate the meaning of TX/RX chain and antenna. Some chips use 2x2 TX/RX chain but may have 3 RX antennas or 1x1 TX/RX chain but may have 2 RX antennas to do antenna diversity. Signed-off-by: RA-Jay Hung Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 3 ++ drivers/net/wireless/rt2x00/rt2800lib.c | 74 +++++++++++++++++++++++++++++---- drivers/net/wireless/rt2x00/rt2x00.h | 2 + 3 files changed, 70 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index ec8159ce0ee8..ef8f605d1081 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -270,6 +270,7 @@ /* * GPIO_CTRL_CFG: + * GPIOD: GPIO direction, 0: Output, 1: Input */ #define GPIO_CTRL_CFG 0x0228 #define GPIO_CTRL_CFG_BIT0 FIELD32(0x00000001) @@ -281,6 +282,7 @@ #define GPIO_CTRL_CFG_BIT6 FIELD32(0x00000040) #define GPIO_CTRL_CFG_BIT7 FIELD32(0x00000080) #define GPIO_CTRL_CFG_BIT8 FIELD32(0x00000100) +#define GPIO_CTRL_CFG_GPIOD FIELD32(0x00000800) /* * MCU_CMD_CFG @@ -2068,6 +2070,7 @@ struct mac_iveiv_entry { #define MCU_LED_LED_POLARITY 0x54 #define MCU_RADAR 0x60 #define MCU_BOOT_SIGNAL 0x72 +#define MCU_ANT_SELECT 0X73 #define MCU_BBP_SIGNAL 0x80 #define MCU_POWER_SAVE 0x83 diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 7a68a67c506a..c62b4a593eb8 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1376,10 +1376,32 @@ void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp, } EXPORT_SYMBOL_GPL(rt2800_config_erp); +static void rt2800_set_ant_diversity(struct rt2x00_dev *rt2x00dev, + enum antenna ant) +{ + u32 reg; + u8 eesk_pin = (ant == ANTENNA_A) ? 1 : 0; + u8 gpio_bit3 = (ant == ANTENNA_A) ? 0 : 1; + + if (rt2x00_is_pci(rt2x00dev)) { + rt2800_register_read(rt2x00dev, E2PROM_CSR, ®); + rt2x00_set_field32(®, E2PROM_CSR_DATA_CLOCK, eesk_pin); + rt2800_register_write(rt2x00dev, E2PROM_CSR, reg); + } else if (rt2x00_is_usb(rt2x00dev)) + rt2800_mcu_request(rt2x00dev, MCU_ANT_SELECT, 0xff, + eesk_pin, 0); + + rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); + rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD, 0); + rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, gpio_bit3); + rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); +} + void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) { u8 r1; u8 r3; + u16 eeprom; rt2800_bbp_read(rt2x00dev, 1, &r1); rt2800_bbp_read(rt2x00dev, 3, &r3); @@ -1387,7 +1409,7 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) /* * Configure the TX antenna. */ - switch ((int)ant->tx) { + switch (ant->tx_chain_num) { case 1: rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0); break; @@ -1402,8 +1424,18 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) /* * Configure the RX antenna. */ - switch ((int)ant->rx) { + switch (ant->rx_chain_num) { case 1: + if (rt2x00_rt(rt2x00dev, RT3070) || + rt2x00_rt(rt2x00dev, RT3090) || + rt2x00_rt(rt2x00dev, RT3390)) { + rt2x00_eeprom_read(rt2x00dev, + EEPROM_NIC_CONF1, &eeprom); + if (rt2x00_get_field16(eeprom, + EEPROM_NIC_CONF1_ANT_DIVERSITY)) + rt2800_set_ant_diversity(rt2x00dev, + rt2x00dev->default_ant.rx); + } rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0); break; case 2: @@ -1449,13 +1481,13 @@ static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev, { rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset); - if (rt2x00dev->default_ant.tx == 1) + if (rt2x00dev->default_ant.tx_chain_num == 1) rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_TX1, 1); - if (rt2x00dev->default_ant.rx == 1) { + if (rt2x00dev->default_ant.rx_chain_num == 1) { rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX1, 1); rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1); - } else if (rt2x00dev->default_ant.rx == 2) + } else if (rt2x00dev->default_ant.rx_chain_num == 2) rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1); if (rf->channel > 14) { @@ -1602,13 +1634,13 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, tx_pin = 0; /* Turn on unused PA or LNA when not using 1T or 1R */ - if (rt2x00dev->default_ant.tx != 1) { + if (rt2x00dev->default_ant.tx_chain_num == 2) { rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1); rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1); } /* Turn on unused PA or LNA when not using 1T or 1R */ - if (rt2x00dev->default_ant.rx != 1) { + if (rt2x00dev->default_ant.rx_chain_num == 2) { rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1); rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1); } @@ -3068,11 +3100,35 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) /* * Identify default antenna configuration. */ - rt2x00dev->default_ant.tx = + rt2x00dev->default_ant.tx_chain_num = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH); - rt2x00dev->default_ant.rx = + rt2x00dev->default_ant.rx_chain_num = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH); + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); + + if (rt2x00_rt(rt2x00dev, RT3070) || + rt2x00_rt(rt2x00dev, RT3090) || + rt2x00_rt(rt2x00dev, RT3390)) { + value = rt2x00_get_field16(eeprom, + EEPROM_NIC_CONF1_ANT_DIVERSITY); + switch (value) { + case 0: + case 1: + case 2: + rt2x00dev->default_ant.tx = ANTENNA_A; + rt2x00dev->default_ant.rx = ANTENNA_A; + break; + case 3: + rt2x00dev->default_ant.tx = ANTENNA_A; + rt2x00dev->default_ant.rx = ANTENNA_B; + break; + } + } else { + rt2x00dev->default_ant.tx = ANTENNA_A; + rt2x00dev->default_ant.rx = ANTENNA_A; + } + /* * Read frequency offset and RF programming sequence. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 39bc2faf1793..fd28836a0072 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -225,6 +225,8 @@ struct channel_info { struct antenna_setup { enum antenna rx; enum antenna tx; + u8 rx_chain_num; + u8 tx_chain_num; }; /* -- cgit v1.2.3 From e90c54b2358559bd305ff08096e077d2a7f02bf3 Mon Sep 17 00:00:00 2001 From: RA-Jay Hung Date: Sun, 20 Feb 2011 13:55:25 +0100 Subject: rt2x00: Fix rt2800 txpower setting to correct value TX_PWR_CFG_* setting need to consider below cases -compesate 20M/40M tx power delta for 2.4/5GHZ band -limit maximum EIRP tx power to power_level of regulatory requirement Signed-off-by: RA-Jay Hung Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 39 ++++-- drivers/net/wireless/rt2x00/rt2800lib.c | 236 +++++++++++++++++++++++--------- drivers/net/wireless/rt2x00/rt2x00.h | 1 + 3 files changed, 199 insertions(+), 77 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index ef8f605d1081..457887c85937 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1703,11 +1703,14 @@ struct mac_iveiv_entry { */ /* - * BBP 1: TX Antenna & Power - * POWER: 0 - normal, 1 - drop tx power by 6dBm, 2 - drop tx power by 12dBm, - * 3 - increase tx power by 6dBm - */ -#define BBP1_TX_POWER FIELD8(0x07) + * BBP 1: TX Antenna & Power Control + * POWER_CTRL: + * 0 - normal, + * 1 - drop tx power by 6dBm, + * 2 - drop tx power by 12dBm, + * 3 - increase tx power by 6dBm + */ +#define BBP1_TX_POWER_CTRL FIELD8(0x07) #define BBP1_TX_ANTENNA FIELD8(0x18) /* @@ -2001,23 +2004,26 @@ struct mac_iveiv_entry { #define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00) /* - * EEPROM Maximum TX power values + * EEPROM EIRP Maximum TX power values(unit: dbm) */ -#define EEPROM_MAX_TX_POWER 0x0027 -#define EEPROM_MAX_TX_POWER_24GHZ FIELD16(0x00ff) -#define EEPROM_MAX_TX_POWER_5GHZ FIELD16(0xff00) +#define EEPROM_EIRP_MAX_TX_POWER 0x0027 +#define EEPROM_EIRP_MAX_TX_POWER_2GHZ FIELD16(0x00ff) +#define EEPROM_EIRP_MAX_TX_POWER_5GHZ FIELD16(0xff00) /* * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power. * This is delta in 40MHZ. - * VALUE: Tx Power dalta value (MAX=4) + * VALUE: Tx Power dalta value, MAX=4(unit: dbm) * TYPE: 1: Plus the delta value, 0: minus the delta value - * TXPOWER: Enable: + * ENABLE: enable tx power compensation for 40BW */ #define EEPROM_TXPOWER_DELTA 0x0028 -#define EEPROM_TXPOWER_DELTA_VALUE FIELD16(0x003f) -#define EEPROM_TXPOWER_DELTA_TYPE FIELD16(0x0040) -#define EEPROM_TXPOWER_DELTA_TXPOWER FIELD16(0x0080) +#define EEPROM_TXPOWER_DELTA_VALUE_2G FIELD16(0x003f) +#define EEPROM_TXPOWER_DELTA_TYPE_2G FIELD16(0x0040) +#define EEPROM_TXPOWER_DELTA_ENABLE_2G FIELD16(0x0080) +#define EEPROM_TXPOWER_DELTA_VALUE_5G FIELD16(0x3f00) +#define EEPROM_TXPOWER_DELTA_TYPE_5G FIELD16(0x4000) +#define EEPROM_TXPOWER_DELTA_ENABLE_5G FIELD16(0x8000) /* * EEPROM TXPOWER 802.11BG @@ -2215,4 +2221,9 @@ struct mac_iveiv_entry { #define TXPOWER_A_TO_DEV(__txpower) \ clamp_t(char, __txpower, MIN_A_TXPOWER, MAX_A_TXPOWER) +/* + * Board's maximun TX power limitation + */ +#define EIRP_MAX_TX_POWER_LIMIT 0x50 + #endif /* RT2800_H */ diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index c62b4a593eb8..ab41f9e18ca9 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1684,30 +1684,116 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, ®); } +static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev, + enum ieee80211_band band) +{ + u16 eeprom; + u8 comp_en; + u8 comp_type; + int comp_value; + + rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_DELTA, &eeprom); + + if (eeprom == 0xffff) + return 0; + + if (band == IEEE80211_BAND_2GHZ) { + comp_en = rt2x00_get_field16(eeprom, + EEPROM_TXPOWER_DELTA_ENABLE_2G); + if (comp_en) { + comp_type = rt2x00_get_field16(eeprom, + EEPROM_TXPOWER_DELTA_TYPE_2G); + comp_value = rt2x00_get_field16(eeprom, + EEPROM_TXPOWER_DELTA_VALUE_2G); + if (!comp_type) + comp_value = -comp_value; + } + } else { + comp_en = rt2x00_get_field16(eeprom, + EEPROM_TXPOWER_DELTA_ENABLE_5G); + if (comp_en) { + comp_type = rt2x00_get_field16(eeprom, + EEPROM_TXPOWER_DELTA_TYPE_5G); + comp_value = rt2x00_get_field16(eeprom, + EEPROM_TXPOWER_DELTA_VALUE_5G); + if (!comp_type) + comp_value = -comp_value; + } + } + + return comp_value; +} + +static u8 rt2800_compesate_txpower(struct rt2x00_dev *rt2x00dev, + int is_rate_b, + enum ieee80211_band band, + int power_level, + u8 txpower) +{ + u32 reg; + u16 eeprom; + u8 criterion; + u8 eirp_txpower; + u8 eirp_txpower_criterion; + u8 reg_limit; + int bw_comp = 0; + + if (!((band == IEEE80211_BAND_5GHZ) && is_rate_b)) + return txpower; + + if (test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags)) + bw_comp = rt2800_get_txpower_bw_comp(rt2x00dev, band); + + if (test_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags)) { + /* + * Check if eirp txpower exceed txpower_limit. + * We use OFDM 6M as criterion and its eirp txpower + * is stored at EEPROM_EIRP_MAX_TX_POWER. + * .11b data rate need add additional 4dbm + * when calculating eirp txpower. + */ + rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, ®); + criterion = rt2x00_get_field32(reg, TX_PWR_CFG_0_6MBS); + + rt2x00_eeprom_read(rt2x00dev, + EEPROM_EIRP_MAX_TX_POWER, &eeprom); + + if (band == IEEE80211_BAND_2GHZ) + eirp_txpower_criterion = rt2x00_get_field16(eeprom, + EEPROM_EIRP_MAX_TX_POWER_2GHZ); + else + eirp_txpower_criterion = rt2x00_get_field16(eeprom, + EEPROM_EIRP_MAX_TX_POWER_5GHZ); + + eirp_txpower = eirp_txpower_criterion + (txpower - criterion) + + (is_rate_b ? 4 : 0) + bw_comp; + + reg_limit = (eirp_txpower > power_level) ? + (eirp_txpower - power_level) : 0; + } else + reg_limit = 0; + + return txpower + bw_comp - reg_limit; +} + static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, - const int max_txpower) + struct ieee80211_conf *conf) { u8 txpower; - u8 max_value = (u8)max_txpower; u16 eeprom; - int i; + int i, is_rate_b; u32 reg; u8 r1; u32 offset; + enum ieee80211_band band = conf->channel->band; + int power_level = conf->power_level; /* - * set to normal tx power mode: +/- 0dBm + * set to normal bbp tx power control mode: +/- 0dBm */ rt2800_bbp_read(rt2x00dev, 1, &r1); - rt2x00_set_field8(&r1, BBP1_TX_POWER, 0); + rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, 0); rt2800_bbp_write(rt2x00dev, 1, r1); - - /* - * The eeprom contains the tx power values for each rate. These - * values map to 100% tx power. Each 16bit word contains four tx - * power values and the order is the same as used in the TX_PWR_CFG - * registers. - */ offset = TX_PWR_CFG_0; for (i = 0; i < EEPROM_TXPOWER_BYRATE_SIZE; i += 2) { @@ -1721,73 +1807,99 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i, &eeprom); - /* TX_PWR_CFG_0: 1MBS, TX_PWR_CFG_1: 24MBS, + is_rate_b = i ? 0 : 1; + /* + * TX_PWR_CFG_0: 1MBS, TX_PWR_CFG_1: 24MBS, * TX_PWR_CFG_2: MCS4, TX_PWR_CFG_3: MCS12, - * TX_PWR_CFG_4: unknown */ + * TX_PWR_CFG_4: unknown + */ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0); - rt2x00_set_field32(®, TX_PWR_CFG_RATE0, - min(txpower, max_value)); + txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, + power_level, txpower); + rt2x00_set_field32(®, TX_PWR_CFG_RATE0, txpower); - /* TX_PWR_CFG_0: 2MBS, TX_PWR_CFG_1: 36MBS, + /* + * TX_PWR_CFG_0: 2MBS, TX_PWR_CFG_1: 36MBS, * TX_PWR_CFG_2: MCS5, TX_PWR_CFG_3: MCS13, - * TX_PWR_CFG_4: unknown */ + * TX_PWR_CFG_4: unknown + */ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1); - rt2x00_set_field32(®, TX_PWR_CFG_RATE1, - min(txpower, max_value)); + txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, + power_level, txpower); + rt2x00_set_field32(®, TX_PWR_CFG_RATE1, txpower); - /* TX_PWR_CFG_0: 55MBS, TX_PWR_CFG_1: 48MBS, + /* + * TX_PWR_CFG_0: 5.5MBS, TX_PWR_CFG_1: 48MBS, * TX_PWR_CFG_2: MCS6, TX_PWR_CFG_3: MCS14, - * TX_PWR_CFG_4: unknown */ + * TX_PWR_CFG_4: unknown + */ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2); - rt2x00_set_field32(®, TX_PWR_CFG_RATE2, - min(txpower, max_value)); + txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, + power_level, txpower); + rt2x00_set_field32(®, TX_PWR_CFG_RATE2, txpower); - /* TX_PWR_CFG_0: 11MBS, TX_PWR_CFG_1: 54MBS, + /* + * TX_PWR_CFG_0: 11MBS, TX_PWR_CFG_1: 54MBS, * TX_PWR_CFG_2: MCS7, TX_PWR_CFG_3: MCS15, - * TX_PWR_CFG_4: unknown */ + * TX_PWR_CFG_4: unknown + */ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3); - rt2x00_set_field32(®, TX_PWR_CFG_RATE3, - min(txpower, max_value)); + txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, + power_level, txpower); + rt2x00_set_field32(®, TX_PWR_CFG_RATE3, txpower); /* read the next four txpower values */ rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i + 1, &eeprom); - /* TX_PWR_CFG_0: 6MBS, TX_PWR_CFG_1: MCS0, + is_rate_b = 0; + /* + * TX_PWR_CFG_0: 6MBS, TX_PWR_CFG_1: MCS0, * TX_PWR_CFG_2: MCS8, TX_PWR_CFG_3: unknown, - * TX_PWR_CFG_4: unknown */ + * TX_PWR_CFG_4: unknown + */ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE0); - rt2x00_set_field32(®, TX_PWR_CFG_RATE4, - min(txpower, max_value)); + txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, + power_level, txpower); + rt2x00_set_field32(®, TX_PWR_CFG_RATE4, txpower); - /* TX_PWR_CFG_0: 9MBS, TX_PWR_CFG_1: MCS1, + /* + * TX_PWR_CFG_0: 9MBS, TX_PWR_CFG_1: MCS1, * TX_PWR_CFG_2: MCS9, TX_PWR_CFG_3: unknown, - * TX_PWR_CFG_4: unknown */ + * TX_PWR_CFG_4: unknown + */ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE1); - rt2x00_set_field32(®, TX_PWR_CFG_RATE5, - min(txpower, max_value)); + txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, + power_level, txpower); + rt2x00_set_field32(®, TX_PWR_CFG_RATE5, txpower); - /* TX_PWR_CFG_0: 12MBS, TX_PWR_CFG_1: MCS2, + /* + * TX_PWR_CFG_0: 12MBS, TX_PWR_CFG_1: MCS2, * TX_PWR_CFG_2: MCS10, TX_PWR_CFG_3: unknown, - * TX_PWR_CFG_4: unknown */ + * TX_PWR_CFG_4: unknown + */ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE2); - rt2x00_set_field32(®, TX_PWR_CFG_RATE6, - min(txpower, max_value)); + txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, + power_level, txpower); + rt2x00_set_field32(®, TX_PWR_CFG_RATE6, txpower); - /* TX_PWR_CFG_0: 18MBS, TX_PWR_CFG_1: MCS3, + /* + * TX_PWR_CFG_0: 18MBS, TX_PWR_CFG_1: MCS3, * TX_PWR_CFG_2: MCS11, TX_PWR_CFG_3: unknown, - * TX_PWR_CFG_4: unknown */ + * TX_PWR_CFG_4: unknown + */ txpower = rt2x00_get_field16(eeprom, EEPROM_TXPOWER_BYRATE_RATE3); - rt2x00_set_field32(®, TX_PWR_CFG_RATE7, - min(txpower, max_value)); + txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, + power_level, txpower); + rt2x00_set_field32(®, TX_PWR_CFG_RATE7, txpower); rt2800_register_write(rt2x00dev, offset, reg); @@ -1846,11 +1958,13 @@ void rt2800_config(struct rt2x00_dev *rt2x00dev, /* Always recalculate LNA gain before changing configuration */ rt2800_config_lna_gain(rt2x00dev, libconf); - if (flags & IEEE80211_CONF_CHANGE_CHANNEL) + if (flags & IEEE80211_CONF_CHANGE_CHANNEL) { rt2800_config_channel(rt2x00dev, libconf->conf, &libconf->rf, &libconf->channel); + rt2800_config_txpower(rt2x00dev, libconf->conf); + } if (flags & IEEE80211_CONF_CHANGE_POWER) - rt2800_config_txpower(rt2x00dev, libconf->conf->power_level); + rt2800_config_txpower(rt2x00dev, libconf->conf); if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS) rt2800_config_retry_limit(rt2x00dev, libconf); if (flags & IEEE80211_CONF_CHANGE_PS) @@ -3040,13 +3154,6 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) default_lna_gain); rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); - rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &word); - if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_24GHZ) == 0xff) - rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_24GHZ, MAX_G_TXPOWER); - if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_5GHZ) == 0xff) - rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_5GHZ, MAX_A_TXPOWER); - rt2x00_eeprom_write(rt2x00dev, EEPROM_MAX_TX_POWER, word); - return 0; } EXPORT_SYMBOL_GPL(rt2800_validate_eeprom); @@ -3162,6 +3269,15 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &rt2x00dev->led_mcu_reg); #endif /* CONFIG_RT2X00_LIB_LEDS */ + /* + * Check if support EIRP tx power limit feature. + */ + rt2x00_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER, &eeprom); + + if (rt2x00_get_field16(eeprom, EEPROM_EIRP_MAX_TX_POWER_2GHZ) < + EIRP_MAX_TX_POWER_LIMIT) + __set_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags); + return 0; } EXPORT_SYMBOL_GPL(rt2800_init_eeprom); @@ -3314,7 +3430,6 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) char *default_power1; char *default_power2; unsigned int i; - unsigned short max_power; u16 eeprom; /* @@ -3439,26 +3554,21 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) spec->channels_info = info; - rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &eeprom); - max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_24GHZ); default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); for (i = 0; i < 14; i++) { - info[i].max_power = max_power; - info[i].default_power1 = TXPOWER_G_FROM_DEV(default_power1[i]); - info[i].default_power2 = TXPOWER_G_FROM_DEV(default_power2[i]); + info[i].default_power1 = default_power1[i]; + info[i].default_power2 = default_power2[i]; } if (spec->num_channels > 14) { - max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_5GHZ); default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); for (i = 14; i < spec->num_channels; i++) { - info[i].max_power = max_power; - info[i].default_power1 = TXPOWER_A_FROM_DEV(default_power1[i]); - info[i].default_power2 = TXPOWER_A_FROM_DEV(default_power2[i]); + info[i].default_power1 = default_power1[i]; + info[i].default_power2 = default_power2[i]; } } diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index fd28836a0072..64c6ef52fe56 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -667,6 +667,7 @@ enum rt2x00_flags { */ CONFIG_SUPPORT_HW_BUTTON, CONFIG_SUPPORT_HW_CRYPTO, + CONFIG_SUPPORT_POWER_LIMIT, DRIVER_SUPPORT_CONTROL_FILTERS, DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, -- cgit v1.2.3 From 430df7980ef1a522ad2fd1d06e1b6655f2d9320f Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sun, 20 Feb 2011 13:55:46 +0100 Subject: rt2x00: Minor optimization for devices with RTS/CTS offload Only devices that don't have RTS/CTS offload need to check for IEEE80211_TX_RC_USE_RTS_CTS and IEEE80211_TX_RC_USE_CTS_PROTECT. By swapping both conditions we keep the same number of needed conditionals for devices without RTS/CTS offload but save one conditional on devices with RTS/CTS offload. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00mac.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 6a66021d8f65..1b3edef9e3d2 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -139,9 +139,9 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * either RTS or CTS-to-self frame and handles everything * inside the hardware. */ - if ((tx_info->control.rates[0].flags & (IEEE80211_TX_RC_USE_RTS_CTS | - IEEE80211_TX_RC_USE_CTS_PROTECT)) && - !rt2x00dev->ops->hw->set_rts_threshold) { + if (!rt2x00dev->ops->hw->set_rts_threshold && + (tx_info->control.rates[0].flags & (IEEE80211_TX_RC_USE_RTS_CTS | + IEEE80211_TX_RC_USE_CTS_PROTECT))) { if (rt2x00queue_available(queue) <= 1) goto exit_fail; -- cgit v1.2.3 From 1bce85cf9cea85f6b9a27326effef1e05f7cbc23 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sun, 20 Feb 2011 13:56:07 +0100 Subject: Revert "rt2x00 : avoid timestamp for monitor injected frame." This reverts commit e81e0aef32bfa7f593b14479b9c7eaa7196798ac "rt2x00 : avoid timestamp for monitor injected frame." as it breaks proper timestamp insertion into probe responses injected by hostapd for example. Signed-off-by: Helmut Schaa Cc: Benoit PAPILLAULT Cc: Alban Browaeys Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index fa17c83b9685..bf9bba356280 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -365,13 +365,10 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, /* * Beacons and probe responses require the tsf timestamp - * to be inserted into the frame, except for a frame that has been injected - * through a monitor interface. This latter is needed for testing a - * monitor interface. + * to be inserted into the frame. */ - if ((ieee80211_is_beacon(hdr->frame_control) || - ieee80211_is_probe_resp(hdr->frame_control)) && - (!(tx_info->flags & IEEE80211_TX_CTL_INJECTED))) + if (ieee80211_is_beacon(hdr->frame_control) || + ieee80211_is_probe_resp(hdr->frame_control)) __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags); /* -- cgit v1.2.3 From 47715e6473d12f265c02cebc587de51af80ed6dc Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Sun, 20 Feb 2011 13:56:26 +0100 Subject: rt2x00: Remove superfluos empty line Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00ht.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c index b7ad46ecaa1d..03d9579da681 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c @@ -69,7 +69,6 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, txdesc->mcs |= 0x08; } - /* * This frame is eligible for an AMPDU, however, don't aggregate * frames that are intended to probe a specific tx rate. -- cgit v1.2.3 From 6f492b6d38e18f8d023137231c5d717068deb28d Mon Sep 17 00:00:00 2001 From: Shiang Tu Date: Sun, 20 Feb 2011 13:56:54 +0100 Subject: rt2x00: Add/Modify protection related register definitions Make the definition of protection related registers more precisely Signed-off-by: Shiang Tu Acked-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 22 ++++++++++++++-------- drivers/net/wireless/rt2x00/rt2800lib.c | 12 ++++++------ 2 files changed, 20 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 457887c85937..d3a693b0e706 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1138,8 +1138,8 @@ * PROTECT_RATE: Protection control frame rate for CCK TX(RTS/CTS/CFEnd) * PROTECT_CTRL: Protection control frame type for CCK TX * 0:none, 1:RTS/CTS, 2:CTS-to-self - * PROTECT_NAV: TXOP protection type for CCK TX - * 0:none, 1:ShortNAVprotect, 2:LongNAVProtect + * PROTECT_NAV_SHORT: TXOP protection type for CCK TX with short NAV + * PROTECT_NAV_LONG: TXOP protection type for CCK TX with long NAV * TX_OP_ALLOW_CCK: CCK TXOP allowance, 0:disallow * TX_OP_ALLOW_OFDM: CCK TXOP allowance, 0:disallow * TX_OP_ALLOW_MM20: CCK TXOP allowance, 0:disallow @@ -1151,7 +1151,8 @@ #define CCK_PROT_CFG 0x1364 #define CCK_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff) #define CCK_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000) -#define CCK_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000) +#define CCK_PROT_CFG_PROTECT_NAV_SHORT FIELD32(0x00040000) +#define CCK_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000) #define CCK_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000) #define CCK_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000) #define CCK_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000) @@ -1166,7 +1167,8 @@ #define OFDM_PROT_CFG 0x1368 #define OFDM_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff) #define OFDM_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000) -#define OFDM_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000) +#define OFDM_PROT_CFG_PROTECT_NAV_SHORT FIELD32(0x00040000) +#define OFDM_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000) #define OFDM_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000) #define OFDM_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000) #define OFDM_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000) @@ -1181,7 +1183,8 @@ #define MM20_PROT_CFG 0x136c #define MM20_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff) #define MM20_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000) -#define MM20_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000) +#define MM20_PROT_CFG_PROTECT_NAV_SHORT FIELD32(0x00040000) +#define MM20_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000) #define MM20_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000) #define MM20_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000) #define MM20_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000) @@ -1196,7 +1199,8 @@ #define MM40_PROT_CFG 0x1370 #define MM40_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff) #define MM40_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000) -#define MM40_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000) +#define MM40_PROT_CFG_PROTECT_NAV_SHORT FIELD32(0x00040000) +#define MM40_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000) #define MM40_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000) #define MM40_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000) #define MM40_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000) @@ -1211,7 +1215,8 @@ #define GF20_PROT_CFG 0x1374 #define GF20_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff) #define GF20_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000) -#define GF20_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000) +#define GF20_PROT_CFG_PROTECT_NAV_SHORT FIELD32(0x00040000) +#define GF20_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000) #define GF20_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000) #define GF20_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000) #define GF20_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000) @@ -1226,7 +1231,8 @@ #define GF40_PROT_CFG 0x1378 #define GF40_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff) #define GF40_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000) -#define GF40_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000) +#define GF40_PROT_CFG_PROTECT_NAV_SHORT FIELD32(0x00040000) +#define GF40_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000) #define GF40_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000) #define GF40_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000) #define GF40_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index ab41f9e18ca9..55109656eabb 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2193,7 +2193,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_read(rt2x00dev, CCK_PROT_CFG, ®); rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_RATE, 3); rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_CTRL, 0); - rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_NAV, 1); + rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_NAV_SHORT, 1); rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_CCK, 1); rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_OFDM, 1); rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_MM20, 1); @@ -2206,7 +2206,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®); rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_RATE, 3); rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_CTRL, 0); - rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_NAV, 1); + rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_NAV_SHORT, 1); rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_CCK, 1); rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_OFDM, 1); rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_MM20, 1); @@ -2219,7 +2219,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_read(rt2x00dev, MM20_PROT_CFG, ®); rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_RATE, 0x4004); rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_CTRL, 0); - rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_NAV, 1); + rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_NAV_SHORT, 1); rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_CCK, 1); rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_OFDM, 1); rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_MM20, 1); @@ -2232,7 +2232,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®); rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_RATE, 0x4084); rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, 0); - rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_NAV, 1); + rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_NAV_SHORT, 1); rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1); rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1); rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_MM20, 1); @@ -2245,7 +2245,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_read(rt2x00dev, GF20_PROT_CFG, ®); rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_RATE, 0x4004); rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_CTRL, 0); - rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_NAV, 1); + rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_NAV_SHORT, 1); rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_CCK, 1); rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_OFDM, 1); rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_MM20, 1); @@ -2258,7 +2258,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_read(rt2x00dev, GF40_PROT_CFG, ®); rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_RATE, 0x4084); rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_CTRL, 0); - rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_NAV, 1); + rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_NAV_SHORT, 1); rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_CCK, 1); rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_OFDM, 1); rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_MM20, 1); -- cgit v1.2.3 From fe59147c4f42a491a77b788571c37f0a0be6f41d Mon Sep 17 00:00:00 2001 From: Shiang Tu Date: Sun, 20 Feb 2011 13:57:22 +0100 Subject: rt2x00: Add/Modify the GPIO register definition Revise/Add GPIO register related definitions Signed-off-by: Shiang Tu Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 10 ++++++++-- drivers/net/wireless/rt2x00/rt2800lib.c | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index d3a693b0e706..591ac32b014e 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -281,8 +281,14 @@ #define GPIO_CTRL_CFG_BIT5 FIELD32(0x00000020) #define GPIO_CTRL_CFG_BIT6 FIELD32(0x00000040) #define GPIO_CTRL_CFG_BIT7 FIELD32(0x00000080) -#define GPIO_CTRL_CFG_BIT8 FIELD32(0x00000100) -#define GPIO_CTRL_CFG_GPIOD FIELD32(0x00000800) +#define GPIO_CTRL_CFG_GPIOD_BIT0 FIELD32(0x00000100) +#define GPIO_CTRL_CFG_GPIOD_BIT1 FIELD32(0x00000200) +#define GPIO_CTRL_CFG_GPIOD_BIT2 FIELD32(0x00000400) +#define GPIO_CTRL_CFG_GPIOD_BIT3 FIELD32(0x00000800) +#define GPIO_CTRL_CFG_GPIOD_BIT4 FIELD32(0x00001000) +#define GPIO_CTRL_CFG_GPIOD_BIT5 FIELD32(0x00002000) +#define GPIO_CTRL_CFG_GPIOD_BIT6 FIELD32(0x00004000) +#define GPIO_CTRL_CFG_GPIOD_BIT7 FIELD32(0x00008000) /* * MCU_CMD_CFG diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 55109656eabb..5dd10589cff8 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1392,7 +1392,7 @@ static void rt2800_set_ant_diversity(struct rt2x00_dev *rt2x00dev, eesk_pin, 0); rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); - rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD, 0); + rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT3, 0); rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, gpio_bit3); rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); } -- cgit v1.2.3 From 60687ba710359f32343b7630dc05d3811ef5bf4c Mon Sep 17 00:00:00 2001 From: RA-Shiang Tu Date: Sun, 20 Feb 2011 13:57:46 +0100 Subject: rt2x00: Add support for RT5390 chip Add new RT5390 chip support Signed-off-by: Shiang Tu Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/Kconfig | 12 + drivers/net/wireless/rt2x00/rt2800.h | 59 ++++- drivers/net/wireless/rt2x00/rt2800lib.c | 413 +++++++++++++++++++++++++++----- drivers/net/wireless/rt2x00/rt2800pci.c | 10 + drivers/net/wireless/rt2x00/rt2x00.h | 1 + 5 files changed, 440 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index 6f383cd684b0..f630552427b7 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig @@ -97,6 +97,18 @@ config RT2800PCI_RT35XX Support for these devices is non-functional at the moment and is intended for testers and developers. +config RT2800PCI_RT53XX + bool "rt2800-pci - Include support for rt53xx devices (EXPERIMENTAL)" + depends on EXPERIMENTAL + default n + ---help--- + This adds support for rt53xx wireless chipset family to the + rt2800pci driver. + Supported chips: RT5390 + + Support for these devices is non-functional at the moment and is + intended for testers and developers. + endif config RT2500USB diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 591ac32b014e..6f4a2432c021 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -51,6 +51,7 @@ * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390) * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) * RF3853 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) + * RF5390 2.4G 1T1R */ #define RF2820 0x0001 #define RF2850 0x0002 @@ -65,6 +66,7 @@ #define RF3320 0x000b #define RF3322 0x000c #define RF3853 0x000d +#define RF5390 0x5390 /* * Chipset revisions. @@ -77,6 +79,7 @@ #define REV_RT3071E 0x0211 #define REV_RT3090E 0x0211 #define REV_RT3390E 0x0211 +#define REV_RT5390F 0x0502 /* * Signal information. @@ -120,6 +123,13 @@ #define E2PROM_CSR_LOAD_STATUS FIELD32(0x00000040) #define E2PROM_CSR_RELOAD FIELD32(0x00000080) +/* + * AUX_CTRL: Aux/PCI-E related configuration + */ +#define AUX_CTRL 0x10c +#define AUX_CTRL_WAKE_PCIE_EN FIELD32(0x00000002) +#define AUX_CTRL_FORCE_PCIE_CLK FIELD32(0x00000400) + /* * OPT_14: Unknown register used by rt3xxx devices. */ @@ -454,7 +464,7 @@ */ #define RF_CSR_CFG 0x0500 #define RF_CSR_CFG_DATA FIELD32(0x000000ff) -#define RF_CSR_CFG_REGNUM FIELD32(0x00001f00) +#define RF_CSR_CFG_REGNUM FIELD32(0x00003f00) #define RF_CSR_CFG_WRITE FIELD32(0x00010000) #define RF_CSR_CFG_BUSY FIELD32(0x00020000) @@ -1736,6 +1746,13 @@ struct mac_iveiv_entry { */ #define BBP4_TX_BF FIELD8(0x01) #define BBP4_BANDWIDTH FIELD8(0x18) +#define BBP4_MAC_IF_CTRL FIELD8(0x40) + +/* + * BBP 109 + */ +#define BBP109_TX0_POWER FIELD8(0x0f) +#define BBP109_TX1_POWER FIELD8(0xf0) /* * BBP 138: Unknown @@ -1745,6 +1762,11 @@ struct mac_iveiv_entry { #define BBP138_TX_DAC1 FIELD8(0x20) #define BBP138_TX_DAC2 FIELD8(0x40) +/* + * BBP 152: Rx Ant + */ +#define BBP152_RX_DEFAULT_ANT FIELD8(0x80) + /* * RFCSR registers * The wordsize of the RFCSR is 8 bits. @@ -1754,11 +1776,17 @@ struct mac_iveiv_entry { * RFCSR 1: */ #define RFCSR1_RF_BLOCK_EN FIELD8(0x01) +#define RFCSR1_PLL_PD FIELD8(0x02) #define RFCSR1_RX0_PD FIELD8(0x04) #define RFCSR1_TX0_PD FIELD8(0x08) #define RFCSR1_RX1_PD FIELD8(0x10) #define RFCSR1_TX1_PD FIELD8(0x20) +/* + * RFCSR 2: + */ +#define RFCSR2_RESCAL_EN FIELD8(0x80) + /* * RFCSR 6: */ @@ -1770,6 +1798,11 @@ struct mac_iveiv_entry { */ #define RFCSR7_RF_TUNING FIELD8(0x01) +/* + * RFCSR 11: + */ +#define RFCSR11_R FIELD8(0x03) + /* * RFCSR 12: */ @@ -1791,6 +1824,7 @@ struct mac_iveiv_entry { #define RFCSR17_TXMIXER_GAIN FIELD8(0x07) #define RFCSR17_TX_LO1_EN FIELD8(0x08) #define RFCSR17_R FIELD8(0x20) +#define RFCSR17_CODE FIELD8(0x7f) /* * RFCSR 20: @@ -1823,6 +1857,9 @@ struct mac_iveiv_entry { /* * RFCSR 30: */ +#define RFCSR30_TX_H20M FIELD8(0x02) +#define RFCSR30_RX_H20M FIELD8(0x04) +#define RFCSR30_RX_VCM FIELD8(0x18) #define RFCSR30_RF_CALIBRATION FIELD8(0x80) /* @@ -1831,6 +1868,21 @@ struct mac_iveiv_entry { #define RFCSR31_RX_AGC_FC FIELD8(0x1f) #define RFCSR31_RX_H20M FIELD8(0x20) +/* + * RFCSR 38: + */ +#define RFCSR38_RX_LO1_EN FIELD8(0x20) + +/* + * RFCSR 39: + */ +#define RFCSR39_RX_LO2_EN FIELD8(0x80) + +/* + * RFCSR 49: + */ +#define RFCSR49_TX FIELD8(0x3f) + /* * RF registers */ @@ -1863,6 +1915,11 @@ struct mac_iveiv_entry { * The wordsize of the EEPROM is 16 bits. */ +/* + * Chip ID + */ +#define EEPROM_CHIP_ID 0x0000 + /* * EEPROM Version */ diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 5dd10589cff8..3da78bf0ca26 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -400,8 +400,15 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, if (rt2800_wait_csr_ready(rt2x00dev)) return -EBUSY; - if (rt2x00_is_pci(rt2x00dev)) + if (rt2x00_is_pci(rt2x00dev)) { + if (rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_register_read(rt2x00dev, AUX_CTRL, ®); + rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); + rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); + rt2800_register_write(rt2x00dev, AUX_CTRL, reg); + } rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); + } /* * Disable DMA, will be reenabled later when enabling @@ -1573,6 +1580,99 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); } + +#define RT5390_POWER_BOUND 0x27 +#define RT5390_FREQ_OFFSET_BOUND 0x5f + +static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, + struct ieee80211_conf *conf, + struct rf_channel *rf, + struct channel_info *info) +{ + u8 rfcsr; + u16 eeprom; + + rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); + rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); + rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR11_R, rf->rf2); + rt2800_rfcsr_write(rt2x00dev, 11, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr); + if (info->default_power1 > RT5390_POWER_BOUND) + rt2x00_set_field8(&rfcsr, RFCSR49_TX, RT5390_POWER_BOUND); + else + rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); + rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); + rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1); + rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); + rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); + rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); + if (rt2x00dev->freq_offset > RT5390_FREQ_OFFSET_BOUND) + rt2x00_set_field8(&rfcsr, RFCSR17_CODE, RT5390_FREQ_OFFSET_BOUND); + else + rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); + rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); + + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); + if (rf->channel <= 14) { + int idx = rf->channel-1; + + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) { + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { + /* r55/r59 value array of channel 1~14 */ + static const char r55_bt_rev[] = {0x83, 0x83, + 0x83, 0x73, 0x73, 0x63, 0x53, 0x53, + 0x53, 0x43, 0x43, 0x43, 0x43, 0x43}; + static const char r59_bt_rev[] = {0x0e, 0x0e, + 0x0e, 0x0e, 0x0e, 0x0b, 0x0a, 0x09, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07}; + + rt2800_rfcsr_write(rt2x00dev, 55, r55_bt_rev[idx]); + rt2800_rfcsr_write(rt2x00dev, 59, r59_bt_rev[idx]); + } else { + static const char r59_bt[] = {0x8b, 0x8b, 0x8b, + 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x89, + 0x88, 0x88, 0x86, 0x85, 0x84}; + + rt2800_rfcsr_write(rt2x00dev, 59, r59_bt[idx]); + } + } else { + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { + static const char r55_nonbt_rev[] = {0x23, 0x23, + 0x23, 0x23, 0x13, 0x13, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}; + static const char r59_nonbt_rev[] = {0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x06, 0x05, 0x04, 0x04}; + + rt2800_rfcsr_write(rt2x00dev, 55, r55_nonbt_rev[idx]); + rt2800_rfcsr_write(rt2x00dev, 59, r59_nonbt_rev[idx]); + } else if (rt2x00_rt(rt2x00dev, RT5390)) { + static const char r59_non_bt[] = {0x8f, 0x8f, + 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, + 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86}; + + rt2800_rfcsr_write(rt2x00dev, 59, r59_non_bt[idx]); + } + } + } + + rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0); + rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); + rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); +} + static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf, struct rf_channel *rf, @@ -1597,6 +1697,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2x00_rf(rt2x00dev, RF3052) || rt2x00_rf(rt2x00dev, RF3320)) rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); + else if (rt2x00_rf(rt2x00dev, RF5390)) + rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); else rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); @@ -1609,12 +1711,14 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2800_bbp_write(rt2x00dev, 86, 0); if (rf->channel <= 14) { - if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) { - rt2800_bbp_write(rt2x00dev, 82, 0x62); - rt2800_bbp_write(rt2x00dev, 75, 0x46); - } else { - rt2800_bbp_write(rt2x00dev, 82, 0x84); - rt2800_bbp_write(rt2x00dev, 75, 0x50); + if (!rt2x00_rt(rt2x00dev, RT5390)) { + if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) { + rt2800_bbp_write(rt2x00dev, 82, 0x62); + rt2800_bbp_write(rt2x00dev, 75, 0x46); + } else { + rt2800_bbp_write(rt2x00dev, 82, 0x84); + rt2800_bbp_write(rt2x00dev, 75, 0x50); + } } } else { rt2800_bbp_write(rt2x00dev, 82, 0xf2); @@ -1993,7 +2097,8 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev) if (rt2x00_rt(rt2x00dev, RT3070) || rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090) || - rt2x00_rt(rt2x00dev, RT3390)) + rt2x00_rt(rt2x00dev, RT3390) || + rt2x00_rt(rt2x00dev, RT5390)) return 0x1c + (2 * rt2x00dev->lna_gain); else return 0x2e + rt2x00dev->lna_gain; @@ -2125,6 +2230,10 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x0000001f); + } else if (rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); + rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); + rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); } else { rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); @@ -2500,15 +2609,31 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_wait_bbp_ready(rt2x00dev))) return -EACCES; - if (rt2800_is_305x_soc(rt2x00dev)) + if (rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_bbp_read(rt2x00dev, 4, &value); + rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1); + rt2800_bbp_write(rt2x00dev, 4, value); + } + + if (rt2800_is_305x_soc(rt2x00dev) || + rt2x00_rt(rt2x00dev, RT5390)) rt2800_bbp_write(rt2x00dev, 31, 0x08); rt2800_bbp_write(rt2x00dev, 65, 0x2c); rt2800_bbp_write(rt2x00dev, 66, 0x38); + if (rt2x00_rt(rt2x00dev, RT5390)) + rt2800_bbp_write(rt2x00dev, 68, 0x0b); + if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) { rt2800_bbp_write(rt2x00dev, 69, 0x16); rt2800_bbp_write(rt2x00dev, 73, 0x12); + } else if (rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_bbp_write(rt2x00dev, 69, 0x12); + rt2800_bbp_write(rt2x00dev, 73, 0x13); + rt2800_bbp_write(rt2x00dev, 75, 0x46); + rt2800_bbp_write(rt2x00dev, 76, 0x28); + rt2800_bbp_write(rt2x00dev, 77, 0x59); } else { rt2800_bbp_write(rt2x00dev, 69, 0x12); rt2800_bbp_write(rt2x00dev, 73, 0x10); @@ -2519,7 +2644,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) if (rt2x00_rt(rt2x00dev, RT3070) || rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090) || - rt2x00_rt(rt2x00dev, RT3390)) { + rt2x00_rt(rt2x00dev, RT3390) || + rt2x00_rt(rt2x00dev, RT5390)) { rt2800_bbp_write(rt2x00dev, 79, 0x13); rt2800_bbp_write(rt2x00dev, 80, 0x05); rt2800_bbp_write(rt2x00dev, 81, 0x33); @@ -2531,35 +2657,62 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) } rt2800_bbp_write(rt2x00dev, 82, 0x62); - rt2800_bbp_write(rt2x00dev, 83, 0x6a); + if (rt2x00_rt(rt2x00dev, RT5390)) + rt2800_bbp_write(rt2x00dev, 83, 0x7a); + else + rt2800_bbp_write(rt2x00dev, 83, 0x6a); if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D)) rt2800_bbp_write(rt2x00dev, 84, 0x19); + else if (rt2x00_rt(rt2x00dev, RT5390)) + rt2800_bbp_write(rt2x00dev, 84, 0x9a); else rt2800_bbp_write(rt2x00dev, 84, 0x99); - rt2800_bbp_write(rt2x00dev, 86, 0x00); + if (rt2x00_rt(rt2x00dev, RT5390)) + rt2800_bbp_write(rt2x00dev, 86, 0x38); + else + rt2800_bbp_write(rt2x00dev, 86, 0x00); + rt2800_bbp_write(rt2x00dev, 91, 0x04); - rt2800_bbp_write(rt2x00dev, 92, 0x00); + + if (rt2x00_rt(rt2x00dev, RT5390)) + rt2800_bbp_write(rt2x00dev, 92, 0x02); + else + rt2800_bbp_write(rt2x00dev, 92, 0x00); if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) || rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) || rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) || rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) || + rt2x00_rt(rt2x00dev, RT5390) || rt2800_is_305x_soc(rt2x00dev)) rt2800_bbp_write(rt2x00dev, 103, 0xc0); else rt2800_bbp_write(rt2x00dev, 103, 0x00); + if (rt2x00_rt(rt2x00dev, RT5390)) + rt2800_bbp_write(rt2x00dev, 104, 0x92); + if (rt2800_is_305x_soc(rt2x00dev)) rt2800_bbp_write(rt2x00dev, 105, 0x01); + else if (rt2x00_rt(rt2x00dev, RT5390)) + rt2800_bbp_write(rt2x00dev, 105, 0x3c); else rt2800_bbp_write(rt2x00dev, 105, 0x05); - rt2800_bbp_write(rt2x00dev, 106, 0x35); + + if (rt2x00_rt(rt2x00dev, RT5390)) + rt2800_bbp_write(rt2x00dev, 106, 0x03); + else + rt2800_bbp_write(rt2x00dev, 106, 0x35); + + if (rt2x00_rt(rt2x00dev, RT5390)) + rt2800_bbp_write(rt2x00dev, 128, 0x12); if (rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090) || - rt2x00_rt(rt2x00dev, RT3390)) { + rt2x00_rt(rt2x00dev, RT3390) || + rt2x00_rt(rt2x00dev, RT5390)) { rt2800_bbp_read(rt2x00dev, 138, &value); rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); @@ -2571,6 +2724,41 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 138, value); } + if (rt2x00_rt(rt2x00dev, RT5390)) { + int ant, div_mode; + + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); + div_mode = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_ANT_DIVERSITY); + ant = (div_mode == 3) ? 1 : 0; + + /* check if this is a Bluetooth combo card */ + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) { + u32 reg; + + rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); + rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT3, 0); + rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT6, 0); + rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, 0); + rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT6, 0); + if (ant == 0) + rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, 1); + else if (ant == 1) + rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT6, 1); + rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); + } + + rt2800_bbp_read(rt2x00dev, 152, &value); + if (ant == 0) + rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1); + else + rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0); + rt2800_bbp_write(rt2x00dev, 152, value); + + /* Init frequency calibration */ + rt2800_bbp_write(rt2x00dev, 142, 1); + rt2800_bbp_write(rt2x00dev, 143, 57); + } for (i = 0; i < EEPROM_BBP_SIZE; i++) { rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); @@ -2660,18 +2848,28 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) !rt2x00_rt(rt2x00dev, RT3071) && !rt2x00_rt(rt2x00dev, RT3090) && !rt2x00_rt(rt2x00dev, RT3390) && + !rt2x00_rt(rt2x00dev, RT5390) && !rt2800_is_305x_soc(rt2x00dev)) return 0; /* * Init RF calibration. */ - rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); - rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); - msleep(1); - rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0); - rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + if (rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1); + rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); + msleep(1); + rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0); + rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); + } else { + rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + msleep(1); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + } if (rt2x00_rt(rt2x00dev, RT3070) || rt2x00_rt(rt2x00dev, RT3071) || @@ -2762,6 +2960,87 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 30, 0x00); rt2800_rfcsr_write(rt2x00dev, 31, 0x00); return 0; + } else if (rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); + rt2800_rfcsr_write(rt2x00dev, 2, 0x80); + rt2800_rfcsr_write(rt2x00dev, 3, 0x88); + rt2800_rfcsr_write(rt2x00dev, 5, 0x10); + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) + rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); + else + rt2800_rfcsr_write(rt2x00dev, 6, 0xa0); + rt2800_rfcsr_write(rt2x00dev, 7, 0x00); + rt2800_rfcsr_write(rt2x00dev, 10, 0x53); + rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); + rt2800_rfcsr_write(rt2x00dev, 12, 0xc6); + rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); + rt2800_rfcsr_write(rt2x00dev, 14, 0x00); + rt2800_rfcsr_write(rt2x00dev, 15, 0x00); + rt2800_rfcsr_write(rt2x00dev, 16, 0x00); + rt2800_rfcsr_write(rt2x00dev, 18, 0x03); + rt2800_rfcsr_write(rt2x00dev, 19, 0x00); + + rt2800_rfcsr_write(rt2x00dev, 20, 0x00); + rt2800_rfcsr_write(rt2x00dev, 21, 0x00); + rt2800_rfcsr_write(rt2x00dev, 22, 0x20); + rt2800_rfcsr_write(rt2x00dev, 23, 0x00); + rt2800_rfcsr_write(rt2x00dev, 24, 0x00); + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) + rt2800_rfcsr_write(rt2x00dev, 25, 0x80); + else + rt2800_rfcsr_write(rt2x00dev, 25, 0xc0); + rt2800_rfcsr_write(rt2x00dev, 26, 0x00); + rt2800_rfcsr_write(rt2x00dev, 27, 0x09); + rt2800_rfcsr_write(rt2x00dev, 28, 0x00); + rt2800_rfcsr_write(rt2x00dev, 29, 0x10); + + rt2800_rfcsr_write(rt2x00dev, 30, 0x00); + rt2800_rfcsr_write(rt2x00dev, 31, 0x80); + rt2800_rfcsr_write(rt2x00dev, 32, 0x80); + rt2800_rfcsr_write(rt2x00dev, 33, 0x00); + rt2800_rfcsr_write(rt2x00dev, 34, 0x07); + rt2800_rfcsr_write(rt2x00dev, 35, 0x12); + rt2800_rfcsr_write(rt2x00dev, 36, 0x00); + rt2800_rfcsr_write(rt2x00dev, 37, 0x08); + rt2800_rfcsr_write(rt2x00dev, 38, 0x85); + rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); + + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) + rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); + else + rt2800_rfcsr_write(rt2x00dev, 40, 0x4b); + rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); + rt2800_rfcsr_write(rt2x00dev, 42, 0xd2); + rt2800_rfcsr_write(rt2x00dev, 43, 0x9a); + rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); + rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) + rt2800_rfcsr_write(rt2x00dev, 46, 0x73); + else + rt2800_rfcsr_write(rt2x00dev, 46, 0x7b); + rt2800_rfcsr_write(rt2x00dev, 47, 0x00); + rt2800_rfcsr_write(rt2x00dev, 48, 0x10); + rt2800_rfcsr_write(rt2x00dev, 49, 0x94); + + rt2800_rfcsr_write(rt2x00dev, 52, 0x38); + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) + rt2800_rfcsr_write(rt2x00dev, 53, 0x00); + else + rt2800_rfcsr_write(rt2x00dev, 53, 0x84); + rt2800_rfcsr_write(rt2x00dev, 54, 0x78); + rt2800_rfcsr_write(rt2x00dev, 55, 0x44); + rt2800_rfcsr_write(rt2x00dev, 56, 0x22); + rt2800_rfcsr_write(rt2x00dev, 57, 0x80); + rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); + rt2800_rfcsr_write(rt2x00dev, 59, 0x63); + + rt2800_rfcsr_write(rt2x00dev, 60, 0x45); + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) + rt2800_rfcsr_write(rt2x00dev, 61, 0xd1); + else + rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); + rt2800_rfcsr_write(rt2x00dev, 62, 0x00); + rt2800_rfcsr_write(rt2x00dev, 63, 0x00); } if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { @@ -2815,21 +3094,23 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x15); } - /* - * Set back to initial state - */ - rt2800_bbp_write(rt2x00dev, 24, 0); + if (!rt2x00_rt(rt2x00dev, RT5390)) { + /* + * Set back to initial state + */ + rt2800_bbp_write(rt2x00dev, 24, 0); - rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0); - rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); + rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0); + rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); - /* - * set BBP back to BW20 - */ - rt2800_bbp_read(rt2x00dev, 4, &bbp); - rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0); - rt2800_bbp_write(rt2x00dev, 4, bbp); + /* + * Set BBP back to BW20 + */ + rt2800_bbp_read(rt2x00dev, 4, &bbp); + rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0); + rt2800_bbp_write(rt2x00dev, 4, bbp); + } if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) || rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || @@ -2841,21 +3122,23 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, OPT_14_CSR_BIT0, 1); rt2800_register_write(rt2x00dev, OPT_14_CSR, reg); - rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0); - if (rt2x00_rt(rt2x00dev, RT3070) || - rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || - rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || - rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { - if (!test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) - rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); - } - rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom); - if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1) - rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN, - rt2x00_get_field16(eeprom, - EEPROM_TXMIXER_GAIN_BG_VAL)); - rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); + if (!rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0); + if (rt2x00_rt(rt2x00dev, RT3070) || + rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || + rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || + rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { + if (!test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) + rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); + } + rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom); + if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1) + rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN, + rt2x00_get_field16(eeprom, + EEPROM_TXMIXER_GAIN_BG_VAL)); + rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); + } if (rt2x00_rt(rt2x00dev, RT3090)) { rt2800_bbp_read(rt2x00dev, 138, &bbp); @@ -2906,6 +3189,20 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 27, rfcsr); } + if (rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0); + rt2800_rfcsr_write(rt2x00dev, 38, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 39, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR39_RX_LO2_EN, 0); + rt2800_rfcsr_write(rt2x00dev, 39, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_RX_VCM, 2); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + } + return 0; } @@ -3170,10 +3467,15 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); /* - * Identify RF chipset. + * Identify RF chipset by EEPROM value + * RT28xx/RT30xx: defined in "EEPROM_NIC_CONF0_RF_TYPE" field + * RT53xx: defined in "EEPROM_CHIP_ID" field */ - value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); rt2800_register_read(rt2x00dev, MAC_CSR0, ®); + if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390) + rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &value); + else + value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET), value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); @@ -3185,7 +3487,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) !rt2x00_rt(rt2x00dev, RT3071) && !rt2x00_rt(rt2x00dev, RT3090) && !rt2x00_rt(rt2x00dev, RT3390) && - !rt2x00_rt(rt2x00dev, RT3572)) { + !rt2x00_rt(rt2x00dev, RT3572) && + !rt2x00_rt(rt2x00dev, RT5390)) { ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); return -ENODEV; } @@ -3199,7 +3502,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) !rt2x00_rf(rt2x00dev, RF3021) && !rt2x00_rf(rt2x00dev, RF3022) && !rt2x00_rf(rt2x00dev, RF3052) && - !rt2x00_rf(rt2x00dev, RF3320)) { + !rt2x00_rf(rt2x00dev, RF3320) && + !rt2x00_rf(rt2x00dev, RF5390)) { ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); return -ENODEV; } @@ -3496,7 +3800,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) rt2x00_rf(rt2x00dev, RF2020) || rt2x00_rf(rt2x00dev, RF3021) || rt2x00_rf(rt2x00dev, RF3022) || - rt2x00_rf(rt2x00dev, RF3320)) { + rt2x00_rf(rt2x00dev, RF3320) || + rt2x00_rf(rt2x00dev, RF5390)) { spec->num_channels = 14; spec->channels = rf_vals_3x; } else if (rt2x00_rf(rt2x00dev, RF3052)) { diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 6ac0ff236893..38605e9fe427 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -493,6 +493,13 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); + if (rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_register_read(rt2x00dev, AUX_CTRL, ®); + rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); + rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); + rt2800_register_write(rt2x00dev, AUX_CTRL, reg); + } + rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); @@ -1126,6 +1133,9 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { { PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1814, 0x3592), PCI_DEVICE_DATA(&rt2800pci_ops) }, { PCI_DEVICE(0x1814, 0x3593), PCI_DEVICE_DATA(&rt2800pci_ops) }, +#endif +#ifdef CONFIG_RT2800PCI_RT53XX + { PCI_DEVICE(0x1814, 0x5390), PCI_DEVICE_DATA(&rt2800pci_ops) }, #endif { 0, } }; diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 64c6ef52fe56..1df432c1f2c7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -189,6 +189,7 @@ struct rt2x00_chip { #define RT3572 0x3572 #define RT3593 0x3593 /* PCIe */ #define RT3883 0x3883 /* WSOC */ +#define RT5390 0x5390 /* 2.4GHz */ u16 rf; u16 rev; -- cgit v1.2.3 From 320d6c1b56de5f461c6062625b9664095f90ee95 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 17:07:12 +0530 Subject: ath9k_hw: Fix power on reset Commit "ath9k_hw: add an extra delay when reseting AR_RTC_RESET" added an extra udelay to the reset routine. As the required delay is already present, remove this. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index f9cf81551817..9a3438174f86 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1100,7 +1100,6 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) REG_WRITE(ah, AR_RC, AR_RC_AHB); REG_WRITE(ah, AR_RTC_RESET, 0); - udelay(2); REGWRITE_BUFFER_FLUSH(ah); -- cgit v1.2.3 From 98401ae43413ac374c0eb8d6018b13495e08f948 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 7 Feb 2011 21:41:30 +0100 Subject: platform-drivers: x86: pmic: Use request_irq instead of chained handler There is no need to install a chained handler for this hardware. This is a plain x86 IOAPIC interrupt which is handled by the core code perfectly fine. There is nothing special about demultiplexing these gpio interrupts which justifies a custom hack. Replace it by a plain old interrupt handler installed with request_irq. That makes the code agnostic about the underlying primary interrupt hardware. The overhead for this is minimal, but it gives us the advantage of accounting, balancing and to detect interrupt storms. gpio interrupts are not really that performance critical. Patch fixups from akpm Signed-off-by: Thomas Gleixner Signed-off-by: Matthew Garrett Signed-off-by: Andrew Morton --- drivers/platform/x86/intel_pmic_gpio.c | 50 ++++++++-------------------------- 1 file changed, 12 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/intel_pmic_gpio.c b/drivers/platform/x86/intel_pmic_gpio.c index df244c83681d..61433d492862 100644 --- a/drivers/platform/x86/intel_pmic_gpio.c +++ b/drivers/platform/x86/intel_pmic_gpio.c @@ -74,19 +74,6 @@ struct pmic_gpio { u32 trigger_type; }; -static void pmic_program_irqtype(int gpio, int type) -{ - if (type & IRQ_TYPE_EDGE_RISING) - intel_scu_ipc_update_register(GPIO0 + gpio, 0x20, 0x20); - else - intel_scu_ipc_update_register(GPIO0 + gpio, 0x00, 0x20); - - if (type & IRQ_TYPE_EDGE_FALLING) - intel_scu_ipc_update_register(GPIO0 + gpio, 0x10, 0x10); - else - intel_scu_ipc_update_register(GPIO0 + gpio, 0x00, 0x10); -}; - static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { if (offset > 8) { @@ -179,26 +166,6 @@ static int pmic_gpio_to_irq(struct gpio_chip *chip, unsigned offset) return pg->irq_base + offset; } -static void pmic_bus_lock(struct irq_data *data) -{ - struct pmic_gpio *pg = irq_data_get_irq_chip_data(data); - - mutex_lock(&pg->buslock); -} - -static void pmic_bus_sync_unlock(struct irq_data *data) -{ - struct pmic_gpio *pg = irq_data_get_irq_chip_data(data); - - if (pg->update_type) { - unsigned int gpio = pg->update_type & ~GPIO_UPDATE_TYPE; - - pmic_program_irqtype(gpio, pg->trigger_type); - pg->update_type = 0; - } - mutex_unlock(&pg->buslock); -} - /* the gpiointr register is read-clear, so just do nothing. */ static void pmic_irq_unmask(struct irq_data *data) { } @@ -211,19 +178,21 @@ static struct irq_chip pmic_irqchip = { .irq_set_type = pmic_irq_type, }; -static void pmic_irq_handler(unsigned irq, struct irq_desc *desc) +static irqreturn_t pmic_irq_handler(int irq, void *data) { - struct pmic_gpio *pg = (struct pmic_gpio *)get_irq_data(irq); + struct pmic_gpio *pg = data; u8 intsts = *((u8 *)pg->gpiointr + 4); int gpio; + irqreturn_t ret = IRQ_NONE; for (gpio = 0; gpio < 8; gpio++) { if (intsts & (1 << gpio)) { pr_debug("pmic pin %d triggered\n", gpio); generic_handle_irq(pg->irq_base + gpio); + ret = IRQ_HANDLED; } } - desc->chip->irq_eoi(get_irq_desc_chip_data(desc)); + return ret; } static int __devinit platform_pmic_gpio_probe(struct platform_device *pdev) @@ -280,8 +249,13 @@ static int __devinit platform_pmic_gpio_probe(struct platform_device *pdev) printk(KERN_ERR "%s: Can not add pmic gpio chip.\n", __func__); goto err; } - set_irq_data(pg->irq, pg); - set_irq_chained_handler(pg->irq, pmic_irq_handler); + + retval = request_irq(pg->irq, pmic_irq_handler, 0, "pmic", pg); + if (retval) { + printk(KERN_WARNING "pmic: Interrupt request failed\n"); + goto err; + } + for (i = 0; i < 8; i++) { set_irq_chip_and_handler_name(i + pg->irq_base, &pmic_irqchip, handle_simple_irq, "demux"); -- cgit v1.2.3 From 8a6a142c1286797978e4db266d22875a5f424897 Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Fri, 4 Feb 2011 15:24:03 +0300 Subject: platform: x86: tc1100-wmi: world-writable sysfs wireless and jogdial files Don't allow everybody to change WMI settings. Signed-off-by: Vasiliy Kulikov Signed-off-by: Matthew Garrett --- drivers/platform/x86/tc1100-wmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/platform/x86/tc1100-wmi.c b/drivers/platform/x86/tc1100-wmi.c index 1fe0f1feff71..865ef78d6f1a 100644 --- a/drivers/platform/x86/tc1100-wmi.c +++ b/drivers/platform/x86/tc1100-wmi.c @@ -162,7 +162,7 @@ set_bool_##value(struct device *dev, struct device_attribute *attr, \ return -EINVAL; \ return count; \ } \ -static DEVICE_ATTR(value, S_IWUGO | S_IRUGO | S_IWUSR, \ +static DEVICE_ATTR(value, S_IRUGO | S_IWUSR, \ show_bool_##value, set_bool_##value); show_set_bool(wireless, TC1100_INSTANCE_WIRELESS); -- cgit v1.2.3 From 8040835760adf0ef66876c063d47f79f015fb55d Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Fri, 4 Feb 2011 15:23:59 +0300 Subject: platform: x86: asus_acpi: world-writable procfs files Don't allow everybody to change ACPI settings. The comment says that it is done deliberatelly, however, the comment before disp_proc_write() says that at least one of these setting is experimental. Signed-off-by: Vasiliy Kulikov Signed-off-by: Matthew Garrett --- drivers/platform/x86/asus_acpi.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c index 4633fd8532cc..fe495939c307 100644 --- a/drivers/platform/x86/asus_acpi.c +++ b/drivers/platform/x86/asus_acpi.c @@ -1081,14 +1081,8 @@ static int asus_hotk_add_fs(struct acpi_device *device) struct proc_dir_entry *proc; mode_t mode; - /* - * If parameter uid or gid is not changed, keep the default setting for - * our proc entries (-rw-rw-rw-) else, it means we care about security, - * and then set to -rw-rw---- - */ - if ((asus_uid == 0) && (asus_gid == 0)) { - mode = S_IFREG | S_IRUGO | S_IWUGO; + mode = S_IFREG | S_IRUGO | S_IWUSR | S_IWGRP; } else { mode = S_IFREG | S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP; printk(KERN_WARNING " asus_uid and asus_gid parameters are " -- cgit v1.2.3 From b80b168f918bba4b847e884492415546b340e19d Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Fri, 4 Feb 2011 15:23:56 +0300 Subject: platform: x86: acer-wmi: world-writable sysfs threeg file Don't allow everybody to write to hardware registers. Signed-off-by: Vasiliy Kulikov Signed-off-by: Matthew Garrett --- drivers/platform/x86/acer-wmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index c5c4b8c32eb8..a7bcad7eb093 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -1280,7 +1280,7 @@ static ssize_t set_bool_threeg(struct device *dev, return -EINVAL; return count; } -static DEVICE_ATTR(threeg, S_IWUGO | S_IRUGO | S_IWUSR, show_bool_threeg, +static DEVICE_ATTR(threeg, S_IRUGO | S_IWUSR, show_bool_threeg, set_bool_threeg); static ssize_t show_interface(struct device *dev, struct device_attribute *attr, -- cgit v1.2.3 From ad0f43063ef18f54030b5653c9f678db60907920 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 20 Jan 2011 12:48:36 -0800 Subject: platform/x86: ideapad-laptop depends on INPUT Most platform/x86 drivers that use INPUT_SPARSEKMAP also depend on INPUT, so do the same for ideapad-laptop. This fixes a kconfig warning and subsequent build errors when CONFIG_INPUT is disabled. warning: (ACER_WMI && ASUS_LAPTOP && DELL_WMI && HP_WMI && PANASONIC_LAPTOP && IDEAPAD_LAPTOP && EEEPC_LAPTOP && EEEPC_WMI && MSI_WMI && TOPSTAR_LAPTOP && ACPI_TOSHIBA) selects INPUT_SPARSEKMAP which has unmet direct dependencies (!S390 && INPUT) ERROR: "input_free_device" [drivers/platform/x86/ideapad-laptop.ko] undefined! ERROR: "input_register_device" [drivers/platform/x86/ideapad-laptop.ko] undefined! ERROR: "sparse_keymap_setup" [drivers/platform/x86/ideapad-laptop.ko] undefined! ERROR: "input_allocate_device" [drivers/platform/x86/ideapad-laptop.ko] undefined! ERROR: "input_unregister_device" [drivers/platform/x86/ideapad-laptop.ko] undefined! ERROR: "sparse_keymap_free" [drivers/platform/x86/ideapad-laptop.ko] undefined! ERROR: "sparse_keymap_report_event" [drivers/platform/x86/ideapad-laptop.ko] undefined! Signed-off-by: Randy Dunlap Cc: David Woodhouse Cc: Matthew Garrett Cc: platform-driver-x86@vger.kernel.org Signed-off-by: Matthew Garrett --- drivers/platform/x86/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index d163bc2e2b9e..a59af5b24f0a 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -227,7 +227,7 @@ config SONYPI_COMPAT config IDEAPAD_LAPTOP tristate "Lenovo IdeaPad Laptop Extras" depends on ACPI - depends on RFKILL + depends on RFKILL && INPUT select INPUT_SPARSEKMAP help This is a driver for the rfkill switches on Lenovo IdeaPad netbooks. -- cgit v1.2.3 From bbb706079abe955a9e3f208f541de97d99449236 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Wed, 9 Feb 2011 16:39:40 -0500 Subject: acer-wmi: Fix capitalisation of GUID 6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3 needs to be 6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3 to match the hardware alias. Signed-off-by: Matthew Garrett Acked-by: Carlos Corbacho Cc: stable@kernel.org --- drivers/platform/x86/acer-wmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index a7bcad7eb093..38b34a73866a 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -84,7 +84,7 @@ MODULE_LICENSE("GPL"); */ #define AMW0_GUID1 "67C3371D-95A3-4C37-BB61-DD47B491DAAB" #define AMW0_GUID2 "431F16ED-0C2B-444C-B267-27DEB140CF9C" -#define WMID_GUID1 "6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3" +#define WMID_GUID1 "6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3" #define WMID_GUID2 "95764E09-FB56-4e83-B31A-37761F60994A" #define WMID_GUID3 "61EF69EA-865C-4BC3-A502-A0DEBA0CB531" -- cgit v1.2.3 From 5ffba7e696510c90e8327a2041764b2a60e56c6e Mon Sep 17 00:00:00 2001 From: Seth Forshee Date: Fri, 14 Jan 2011 15:54:39 -0600 Subject: thinkpad_acpi: Always report scancodes for hotkeys Some thinkpad hotkeys report key codes like KEY_FN_F8 when something like KEY_VOLUMEDOWN is desired. Always provide the scan codes in addition to the key codes to assist with debugging these issues. Also send the scan code before the key code to match what other drivers do, as some userspace utilities expect this ordering. Signed-off-by: Seth Forshee Signed-off-by: Matthew Garrett --- drivers/platform/x86/thinkpad_acpi.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index dd599585c6a9..eb9922385ef8 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -2275,16 +2275,12 @@ static void tpacpi_input_send_key(const unsigned int scancode) if (keycode != KEY_RESERVED) { mutex_lock(&tpacpi_inputdev_send_mutex); + input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, scancode); input_report_key(tpacpi_inputdev, keycode, 1); - if (keycode == KEY_UNKNOWN) - input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, - scancode); input_sync(tpacpi_inputdev); + input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, scancode); input_report_key(tpacpi_inputdev, keycode, 0); - if (keycode == KEY_UNKNOWN) - input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, - scancode); input_sync(tpacpi_inputdev); mutex_unlock(&tpacpi_inputdev_send_mutex); -- cgit v1.2.3 From a3d77411e8b2ad661958c1fbee65beb476ec6d70 Mon Sep 17 00:00:00 2001 From: Keng-Yu Lin Date: Tue, 15 Feb 2011 17:36:07 +0800 Subject: dell-laptop: Toggle the unsupported hardware killswitch It is found on Dell Inspiron 1018 that the firmware reports that the hardware killswitch is not supported. This makes the rfkill key not functional. This patch forces the driver to toggle the firmware rfkill status in the case that the hardware killswitch is indicated as unsupported by the firmware. Signed-off-by: Keng-Yu Lin Tested-by: Alessio Igor Bogani Signed-off-by: Matthew Garrett --- drivers/platform/x86/dell-laptop.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 34657f96b5a5..ad24ef36f9f7 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -290,9 +290,12 @@ static int dell_rfkill_set(void *data, bool blocked) dell_send_request(buffer, 17, 11); /* If the hardware switch controls this radio, and the hardware - switch is disabled, don't allow changing the software state */ + switch is disabled, don't allow changing the software state. + If the hardware switch is reported as not supported, always + fire the SMI to toggle the killswitch. */ if ((hwswitch_state & BIT(hwswitch_bit)) && - !(buffer->output[1] & BIT(16))) { + !(buffer->output[1] & BIT(16)) && + (buffer->output[1] & BIT(0))) { ret = -EINVAL; goto out; } @@ -398,6 +401,23 @@ static const struct file_operations dell_debugfs_fops = { static void dell_update_rfkill(struct work_struct *ignored) { + int status; + + get_buffer(); + dell_send_request(buffer, 17, 11); + status = buffer->output[1]; + release_buffer(); + + /* if hardware rfkill is not supported, set it explicitly */ + if (!(status & BIT(0))) { + if (wifi_rfkill) + dell_rfkill_set((void *)1, !((status & BIT(17)) >> 17)); + if (bluetooth_rfkill) + dell_rfkill_set((void *)2, !((status & BIT(18)) >> 18)); + if (wwan_rfkill) + dell_rfkill_set((void *)3, !((status & BIT(19)) >> 19)); + } + if (wifi_rfkill) dell_rfkill_query(wifi_rfkill, (void *)1); if (bluetooth_rfkill) -- cgit v1.2.3 From 951f3512dba5bd44cda3e5ee22b4b522e4bb09fb Mon Sep 17 00:00:00 2001 From: Indan Zupancic Date: Thu, 17 Feb 2011 02:41:49 +0100 Subject: drm/i915: Do not handle backlight combination mode specially The current code does not follow Intel documentation: It misses some things and does other, undocumented things. This causes wrong backlight values in certain conditions. Instead of adding tricky code handling badly documented and rare corner cases, don't handle combination mode specially at all. This way PCI_LBPC is never touched and weird things shouldn't happen. If combination mode is enabled, then the only downside is that changing the brightness has a greater granularity (the LBPC value), but LBPC is at most 254 and the maximum is in the thousands, so this is no real functional loss. A potential problem with not handling combined mode is that a brightness of max * PCI_LBPC is not bright enough. However, this is very unlikely because from the documentation LBPC seems to act as a scaling factor and doesn't look like it's supposed to be changed after boot. The value at boot should always result in a bright enough screen. IMPORTANT: However, although usually the above is true, it may not be when people ran an older (2.6.37) kernel which messed up the LBPC register, and they are unlucky enough to have a BIOS that saves and restores the LBPC value. Then a good kernel may seem to not work: Max brightness isn't bright enough. If this happens people should boot back into the old kernel, set brightness to the maximum, and then reboot. After that everything should be fine. For more information see the below links. This fixes bugs: http://bugzilla.kernel.org/show_bug.cgi?id=23472 http://bugzilla.kernel.org/show_bug.cgi?id=25072 Signed-off-by: Indan Zupancic Tested-by: Alex Riesen Signed-off-by: Linus Torvalds --- drivers/gpu/drm/i915/i915_reg.h | 10 ---------- drivers/gpu/drm/i915/intel_panel.c | 37 ------------------------------------- 2 files changed, 47 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 15d94c63918c..729d4233b763 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1553,17 +1553,7 @@ /* Backlight control */ #define BLC_PWM_CTL 0x61254 -#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) #define BLC_PWM_CTL2 0x61250 /* 965+ only */ -#define BLM_COMBINATION_MODE (1 << 30) -/* - * This is the most significant 15 bits of the number of backlight cycles in a - * complete cycle of the modulated backlight control. - * - * The actual value is this field multiplied by two. - */ -#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) -#define BLM_LEGACY_MODE (1 << 16) /* * This is the number of cycles out of the backlight modulation cycle for which * the backlight is on. diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index c65992df458d..d860abeda70f 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -30,8 +30,6 @@ #include "intel_drv.h" -#define PCI_LBPC 0xf4 /* legacy/combination backlight modes */ - void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, struct drm_display_mode *adjusted_mode) @@ -112,19 +110,6 @@ done: dev_priv->pch_pf_size = (width << 16) | height; } -static int is_backlight_combination_mode(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (INTEL_INFO(dev)->gen >= 4) - return I915_READ(BLC_PWM_CTL2) & BLM_COMBINATION_MODE; - - if (IS_GEN2(dev)) - return I915_READ(BLC_PWM_CTL) & BLM_LEGACY_MODE; - - return 0; -} - static u32 i915_read_blc_pwm_ctl(struct drm_i915_private *dev_priv) { u32 val; @@ -181,9 +166,6 @@ u32 intel_panel_get_max_backlight(struct drm_device *dev) if (INTEL_INFO(dev)->gen < 4) max &= ~1; } - - if (is_backlight_combination_mode(dev)) - max *= 0xff; } DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max); @@ -201,15 +183,6 @@ u32 intel_panel_get_backlight(struct drm_device *dev) val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; if (IS_PINEVIEW(dev)) val >>= 1; - - if (is_backlight_combination_mode(dev)){ - u8 lbpc; - - val &= ~1; - pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc); - val *= lbpc; - val >>= 1; - } } DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val); @@ -232,16 +205,6 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level) if (HAS_PCH_SPLIT(dev)) return intel_pch_panel_set_backlight(dev, level); - - if (is_backlight_combination_mode(dev)){ - u32 max = intel_panel_get_max_backlight(dev); - u8 lpbc; - - lpbc = level * 0xfe / max + 1; - level /= lpbc; - pci_write_config_byte(dev->pdev, PCI_LBPC, lpbc); - } - tmp = I915_READ(BLC_PWM_CTL); if (IS_PINEVIEW(dev)) { tmp &= ~(BACKLIGHT_DUTY_CYCLE_MASK - 1); -- cgit v1.2.3 From 86b27d8050b6b2aec31063fa9f40b16fb347afb3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 11 Feb 2011 20:47:45 +0000 Subject: drm/i915: Ignore a hung GPU when flushing the framebuffer prior to a switch If the gpu is hung, then whatever was inside the render cache is lost and there is little point waiting for it. Or complaining if we see an EIO or EAGAIN instead. So, if the GPU is indeed in its death throes when we need to rewrite the registers for a new framebuffer, just ignore the error and proceed with the update. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3b006536b3d2..dcb821737f38 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1630,19 +1630,19 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj; wait_event(dev_priv->pending_flip_queue, + atomic_read(&dev_priv->mm.wedged) || atomic_read(&obj->pending_flip) == 0); /* Big Hammer, we also need to ensure that any pending * MI_WAIT_FOR_EVENT inside a user batch buffer on the * current scanout is retired before unpinning the old * framebuffer. + * + * This should only fail upon a hung GPU, in which case we + * can safely continue. */ ret = i915_gem_object_flush_gpu(obj, false); - if (ret) { - i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); - mutex_unlock(&dev->struct_mutex); - return ret; - } + (void) ret; } ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y, -- cgit v1.2.3 From a36dbec57e9a665d69cd2e1a673153ddb2d62785 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 11 Feb 2011 14:44:51 -0800 Subject: drm/i915: don't enable FDI & transcoder interrupts after all We can enable some safely, but FDI and transcoder interrupts can occur and block other interrupts from being detected (like port hotplug events). So keep them disabled by default (they can be re-enabled for debugging display bringup, but should generally be off). Signed-off-by: Jesse Barnes Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_irq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 97f946dcc1aa..8a9e08bf1cf7 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -316,6 +316,8 @@ static void i915_hotplug_work_func(struct work_struct *work) struct drm_mode_config *mode_config = &dev->mode_config; struct intel_encoder *encoder; + DRM_DEBUG_KMS("running encoder hotplug functions\n"); + list_for_each_entry(encoder, &mode_config->encoder_list, base.head) if (encoder->hot_plug) encoder->hot_plug(encoder); @@ -1649,9 +1651,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) } else { hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; - hotplug_mask |= SDE_AUX_MASK | SDE_FDI_MASK | SDE_TRANS_MASK; - I915_WRITE(FDI_RXA_IMR, 0); - I915_WRITE(FDI_RXB_IMR, 0); + hotplug_mask |= SDE_AUX_MASK; } dev_priv->pch_irq_mask = ~hotplug_mask; -- cgit v1.2.3 From bdb8b975fc66e081c3f39be6267701f8226d11aa Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 22 Dec 2010 11:37:09 +0000 Subject: agp/intel: Experiment with a 855GM GWB bit Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=27187 Tested-by: Thorsten Vollmer (DFI-ACP G5M150-N w/852GME) Tested-by: Moritz Brunner <2points@gmx.org> (Asus M2400N/i855GM) Tested-by: Indan Zupancic (Thinkpad X40/855GM rev 02) Tested-by: Eric Anholt (865G) Signed-off-by: Chris Wilson --- drivers/char/agp/intel-agp.h | 1 + drivers/char/agp/intel-gtt.c | 56 +++++++++++++++++--------------------------- 2 files changed, 22 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h index c195bfeade11..5feebe2800e9 100644 --- a/drivers/char/agp/intel-agp.h +++ b/drivers/char/agp/intel-agp.h @@ -130,6 +130,7 @@ #define INTEL_GMCH_GMS_STOLEN_352M (0xd << 4) #define I915_IFPADDR 0x60 +#define I830_HIC 0x70 /* Intel 965G registers */ #define I965_MSAC 0x62 diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index fab3d3265adb..0d09b537bb9a 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "agp.h" #include "intel-agp.h" @@ -70,12 +71,8 @@ static struct _intel_private { u32 __iomem *gtt; /* I915G */ bool clear_fake_agp; /* on first access via agp, fill with scratch */ int num_dcache_entries; - union { - void __iomem *i9xx_flush_page; - void *i8xx_flush_page; - }; + void __iomem *i9xx_flush_page; char *i81x_gtt_table; - struct page *i8xx_page; struct resource ifp_resource; int resource_valid; struct page *scratch_page; @@ -722,28 +719,6 @@ static int intel_fake_agp_fetch_size(void) static void i830_cleanup(void) { - if (intel_private.i8xx_flush_page) { - kunmap(intel_private.i8xx_flush_page); - intel_private.i8xx_flush_page = NULL; - } - - __free_page(intel_private.i8xx_page); - intel_private.i8xx_page = NULL; -} - -static void intel_i830_setup_flush(void) -{ - /* return if we've already set the flush mechanism up */ - if (intel_private.i8xx_page) - return; - - intel_private.i8xx_page = alloc_page(GFP_KERNEL); - if (!intel_private.i8xx_page) - return; - - intel_private.i8xx_flush_page = kmap(intel_private.i8xx_page); - if (!intel_private.i8xx_flush_page) - i830_cleanup(); } /* The chipset_flush interface needs to get data that has already been @@ -758,14 +733,27 @@ static void intel_i830_setup_flush(void) */ static void i830_chipset_flush(void) { - unsigned int *pg = intel_private.i8xx_flush_page; + unsigned long timeout = jiffies + msecs_to_jiffies(1000); + + /* Forcibly evict everything from the CPU write buffers. + * clflush appears to be insufficient. + */ + wbinvd_on_all_cpus(); + + /* Now we've only seen documents for this magic bit on 855GM, + * we hope it exists for the other gen2 chipsets... + * + * Also works as advertised on my 845G. + */ + writel(readl(intel_private.registers+I830_HIC) | (1<<31), + intel_private.registers+I830_HIC); - memset(pg, 0, 1024); + while (readl(intel_private.registers+I830_HIC) & (1<<31)) { + if (time_after(jiffies, timeout)) + break; - if (cpu_has_clflush) - clflush_cache_range(pg, 1024); - else if (wbinvd_on_all_cpus() != 0) - printk(KERN_ERR "Timed out waiting for cache flush.\n"); + udelay(50); + } } static void i830_write_entry(dma_addr_t addr, unsigned int entry, @@ -849,8 +837,6 @@ static int i830_setup(void) intel_private.gtt_bus_addr = reg_addr + I810_PTE_BASE; - intel_i830_setup_flush(); - return 0; } -- cgit v1.2.3 From 011b9910bdaf2e52c48c012490ab444fceea1959 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 15 Feb 2011 15:08:02 -0800 Subject: drm/i915: skip FDI & PCH enabling for DP_A eDP on the CPU doesn't need the PCH set up at all, it can in fact cause problems. So avoid FDI training and PCH PLL enabling in that case. Signed-off-by: Jesse Barnes Tested-by: Andy Whitcroft Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 83 +++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index dcb821737f38..9ca1bb2554fc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2045,6 +2045,31 @@ static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) atomic_read(&obj->pending_flip) == 0); } +static bool intel_crtc_driving_pch(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_mode_config *mode_config = &dev->mode_config; + struct intel_encoder *encoder; + + /* + * If there's a non-PCH eDP on this crtc, it must be DP_A, and that + * must be driven by its own crtc; no sharing is possible. + */ + list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { + if (encoder->base.crtc != crtc) + continue; + + switch (encoder->type) { + case INTEL_OUTPUT_EDP: + if (!intel_encoder_is_pch_edp(&encoder->base)) + return false; + continue; + } + } + + return true; +} + static void ironlake_crtc_enable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -2053,6 +2078,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) int pipe = intel_crtc->pipe; int plane = intel_crtc->plane; u32 reg, temp; + bool is_pch_port = false; if (intel_crtc->active) return; @@ -2066,7 +2092,56 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN); } - ironlake_fdi_enable(crtc); + is_pch_port = intel_crtc_driving_pch(crtc); + + if (is_pch_port) + ironlake_fdi_enable(crtc); + else { + /* disable CPU FDI tx and PCH FDI rx */ + reg = FDI_TX_CTL(pipe); + temp = I915_READ(reg); + I915_WRITE(reg, temp & ~FDI_TX_ENABLE); + POSTING_READ(reg); + + reg = FDI_RX_CTL(pipe); + temp = I915_READ(reg); + temp &= ~(0x7 << 16); + temp |= (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) << 11; + I915_WRITE(reg, temp & ~FDI_RX_ENABLE); + + POSTING_READ(reg); + udelay(100); + + /* Ironlake workaround, disable clock pointer after downing FDI */ + if (HAS_PCH_IBX(dev)) + I915_WRITE(FDI_RX_CHICKEN(pipe), + I915_READ(FDI_RX_CHICKEN(pipe) & + ~FDI_RX_PHASE_SYNC_POINTER_ENABLE)); + + /* still set train pattern 1 */ + reg = FDI_TX_CTL(pipe); + temp = I915_READ(reg); + temp &= ~FDI_LINK_TRAIN_NONE; + temp |= FDI_LINK_TRAIN_PATTERN_1; + I915_WRITE(reg, temp); + + reg = FDI_RX_CTL(pipe); + temp = I915_READ(reg); + if (HAS_PCH_CPT(dev)) { + temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; + temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; + } else { + temp &= ~FDI_LINK_TRAIN_NONE; + temp |= FDI_LINK_TRAIN_PATTERN_1; + } + /* BPC in FDI rx is consistent with that in PIPECONF */ + temp &= ~(0x07 << 16); + temp |= (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) << 11; + I915_WRITE(reg, temp); + + POSTING_READ(reg); + udelay(100); + } /* Enable panel fitting for LVDS */ if (dev_priv->pch_pf_size && @@ -2100,6 +2175,10 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) intel_flush_display_plane(dev, plane); } + /* Skip the PCH stuff if possible */ + if (!is_pch_port) + goto done; + /* For PCH output, training FDI link */ if (IS_GEN6(dev)) gen6_fdi_link_train(crtc); @@ -2184,7 +2263,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) I915_WRITE(reg, temp | TRANS_ENABLE); if (wait_for(I915_READ(reg) & TRANS_STATE_ENABLE, 100)) DRM_ERROR("failed to enable transcoder %d\n", pipe); - +done: intel_crtc_load_lut(crtc); intel_update_fbc(dev); intel_crtc_update_cursor(crtc, true); -- cgit v1.2.3 From 03c5a9cf49999ca3431eb9199c9bb831b0020be2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 7 Feb 2011 19:47:42 +0300 Subject: wl12xx: change type from u8 to int ret is used to store int types. Using an u8 will break the error handling. Signed-off-by: Dan Carpenter Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index 62dc9839dd31..6072fe457135 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c @@ -483,7 +483,7 @@ static void wl1271_check_ba_support(struct wl1271 *wl) static int wl1271_set_ba_policies(struct wl1271 *wl) { u8 tid_index; - u8 ret = 0; + int ret = 0; /* Reset the BA RX indicators */ wl->ba_rx_bitmap = 0; -- cgit v1.2.3 From 1ec610ebd6390c2b028434144af204c312a68791 Mon Sep 17 00:00:00 2001 From: Gery Kahn Date: Tue, 1 Feb 2011 03:03:08 -0600 Subject: wl12xx: update PLT initialization for new firmware In revision > 6.1.3.0.0 the firmware expects memory configuration command as part of boot. This was missing if driver boots in PLT mode. The patch adds the memory configuration command, which fixes PLT commands tx continuous and rx statistics. Signed-off-by: Gery Kahn Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 61dea73f5fdc..cf8b3cebe9d6 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -482,6 +482,10 @@ static int wl1271_plt_init(struct wl1271 *wl) if (ret < 0) goto out_free_memmap; + ret = wl1271_acx_sta_mem_cfg(wl); + if (ret < 0) + goto out_free_memmap; + /* Default fragmentation threshold */ ret = wl1271_acx_frag_threshold(wl, wl->conf.tx.frag_threshold); if (ret < 0) -- cgit v1.2.3 From 92fe9b5f112c77dbb63f42f7bed885d709586106 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 9 Feb 2011 12:25:14 +0200 Subject: wl12xx: fix identification of beacon packets (debug) for debugging purposes, wl12xx determines whether a rx packet is a beacon packet. however, it checks only the frame_control subtype without checking the actual packet type, which leads to false identification in some cases. use ieee80211_is_beacon instead. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/rx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c index 00d250d8da18..3d13d7a83ea1 100644 --- a/drivers/net/wireless/wl12xx/rx.c +++ b/drivers/net/wireless/wl12xx/rx.c @@ -92,7 +92,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) { struct wl1271_rx_descriptor *desc; struct sk_buff *skb; - u16 *fc; + struct ieee80211_hdr *hdr; u8 *buf; u8 beacon = 0; @@ -118,8 +118,8 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) /* now we pull the descriptor out of the buffer */ skb_pull(skb, sizeof(*desc)); - fc = (u16 *)skb->data; - if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) + hdr = (struct ieee80211_hdr *)skb->data; + if (ieee80211_is_beacon(hdr->frame_control)) beacon = 1; wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon); -- cgit v1.2.3 From a100885d9dfd8685e0b4e442afc9041ee4c90586 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sat, 12 Feb 2011 23:24:20 +0200 Subject: wl12xx: avoid blocking while holding rcu lock on bss info change Some blocking functions were called while holding the rcu lock for accessing STA information. This can lead to a deadlock. Save the required info beforehand and release the rcu without blocking. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index cf8b3cebe9d6..d51d55998f4e 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2222,6 +2222,8 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, u32 sta_rate_set = 0; int ret; struct ieee80211_sta *sta; + bool sta_exists = false; + struct ieee80211_sta_ht_cap sta_ht_cap; if (is_ibss) { ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf, @@ -2293,16 +2295,20 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, if (sta->ht_cap.ht_supported) sta_rate_set |= (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET); + sta_ht_cap = sta->ht_cap; + sta_exists = true; + } + rcu_read_unlock(); + if (sta_exists) { /* handle new association with HT and HT information change */ if ((changed & BSS_CHANGED_HT) && (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { - ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, + ret = wl1271_acx_set_ht_capabilities(wl, &sta_ht_cap, true); if (ret < 0) { wl1271_warning("Set ht cap true failed %d", ret); - rcu_read_unlock(); goto out; } ret = wl1271_acx_set_ht_information(wl, @@ -2310,23 +2316,20 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, if (ret < 0) { wl1271_warning("Set ht information failed %d", ret); - rcu_read_unlock(); goto out; } } /* handle new association without HT and disassociation */ else if (changed & BSS_CHANGED_ASSOC) { - ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, + ret = wl1271_acx_set_ht_capabilities(wl, &sta_ht_cap, false); if (ret < 0) { wl1271_warning("Set ht cap false failed %d", ret); - rcu_read_unlock(); goto out; } } } - rcu_read_unlock(); if ((changed & BSS_CHANGED_ASSOC)) { if (bss_conf->assoc) { -- cgit v1.2.3 From b1a48cab6f47de18a989927e24025aab7ea106ff Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Tue, 22 Feb 2011 14:19:28 +0200 Subject: wl12xx: fix MODULE_AUTHOR email address Change my old email address to the new one in MODULE_AUTHOR. Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index d51d55998f4e..4bcb848437e6 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -3419,5 +3419,5 @@ module_param_named(debug_level, wl12xx_debug_level, uint, S_IRUSR | S_IWUSR); MODULE_PARM_DESC(debug_level, "wl12xx debugging level"); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Luciano Coelho "); +MODULE_AUTHOR("Luciano Coelho "); MODULE_AUTHOR("Juuso Oikarinen "); -- cgit v1.2.3 From 62c0740c4ff2a4a8850619e0f5ac56a3b6e83cec Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 2 Feb 2011 11:20:05 +0200 Subject: wl12xx: declare support for IEEE80211_HW_REPORTS_TX_ACK_STATUS The wl12xx fw supports ack status reporting for tx frames, so add the IEEE80211_HW_REPORTS_TX_ACK_STATUS flag to our supported features. Since we do the rate control in the fw, we'll probably want to adjust the STA_LOST_PKT_THRESHOLD heuristics in the future, to account for retransmissions as well. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 4bcb848437e6..13c7102f9864 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -3219,7 +3219,8 @@ int wl1271_init_ieee80211(struct wl1271 *wl) IEEE80211_HW_SUPPORTS_UAPSD | IEEE80211_HW_HAS_RATE_CONTROL | IEEE80211_HW_CONNECTION_MONITOR | - IEEE80211_HW_SUPPORTS_CQM_RSSI; + IEEE80211_HW_SUPPORTS_CQM_RSSI | + IEEE80211_HW_REPORTS_TX_ACK_STATUS; wl->hw->wiphy->cipher_suites = cipher_suites; wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); -- cgit v1.2.3 From dc19e4e5e02fb6b46cccb08b2735e38b997a6ddf Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Tue, 15 Feb 2011 21:17:32 +0000 Subject: sh: sh_eth: Add support ethtool This commit supports following functions. - get_settings - set_settings - nway_reset - get_msglevel - set_msglevel - get_link - get_strings - get_ethtool_stats - get_sset_count About other function, the device does not support. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: David S. Miller --- drivers/net/sh_eth.c | 208 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 189 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 819c1750e2ab..095e52580884 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -32,10 +32,17 @@ #include #include #include +#include #include #include "sh_eth.h" +#define SH_ETH_DEF_MSG_ENABLE \ + (NETIF_MSG_LINK | \ + NETIF_MSG_TIMER | \ + NETIF_MSG_RX_ERR| \ + NETIF_MSG_TX_ERR) + /* There is CPU dependent code */ #if defined(CONFIG_CPU_SUBTYPE_SH7724) #define SH_ETH_RESET_DEFAULT 1 @@ -817,6 +824,20 @@ static int sh_eth_rx(struct net_device *ndev) return 0; } +static void sh_eth_rcv_snd_disable(u32 ioaddr) +{ + /* disable tx and rx */ + writel(readl(ioaddr + ECMR) & + ~(ECMR_RE | ECMR_TE), ioaddr + ECMR); +} + +static void sh_eth_rcv_snd_enable(u32 ioaddr) +{ + /* enable tx and rx */ + writel(readl(ioaddr + ECMR) | + (ECMR_RE | ECMR_TE), ioaddr + ECMR); +} + /* error control function */ static void sh_eth_error(struct net_device *ndev, int intr_status) { @@ -843,11 +864,9 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) if (mdp->ether_link_active_low) link_stat = ~link_stat; } - if (!(link_stat & PHY_ST_LINK)) { - /* Link Down : disable tx and rx */ - writel(readl(ioaddr + ECMR) & - ~(ECMR_RE | ECMR_TE), ioaddr + ECMR); - } else { + if (!(link_stat & PHY_ST_LINK)) + sh_eth_rcv_snd_disable(ioaddr); + else { /* Link Up */ writel(readl(ioaddr + EESIPR) & ~DMAC_M_ECI, ioaddr + EESIPR); @@ -857,8 +876,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) writel(readl(ioaddr + EESIPR) | DMAC_M_ECI, ioaddr + EESIPR); /* enable tx and rx */ - writel(readl(ioaddr + ECMR) | - (ECMR_RE | ECMR_TE), ioaddr + ECMR); + sh_eth_rcv_snd_enable(ioaddr); } } } @@ -867,6 +885,8 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) /* Write buck end. unused write back interrupt */ if (intr_status & EESR_TABT) /* Transmit Abort int */ mdp->stats.tx_aborted_errors++; + if (netif_msg_tx_err(mdp)) + dev_err(&ndev->dev, "Transmit Abort\n"); } if (intr_status & EESR_RABT) { @@ -874,14 +894,23 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) if (intr_status & EESR_RFRMER) { /* Receive Frame Overflow int */ mdp->stats.rx_frame_errors++; - dev_err(&ndev->dev, "Receive Frame Overflow\n"); + if (netif_msg_rx_err(mdp)) + dev_err(&ndev->dev, "Receive Abort\n"); } } - if (!mdp->cd->no_ade) { - if (intr_status & EESR_ADE && intr_status & EESR_TDE && - intr_status & EESR_TFE) - mdp->stats.tx_fifo_errors++; + if (intr_status & EESR_TDE) { + /* Transmit Descriptor Empty int */ + mdp->stats.tx_fifo_errors++; + if (netif_msg_tx_err(mdp)) + dev_err(&ndev->dev, "Transmit Descriptor Empty\n"); + } + + if (intr_status & EESR_TFE) { + /* FIFO under flow */ + mdp->stats.tx_fifo_errors++; + if (netif_msg_tx_err(mdp)) + dev_err(&ndev->dev, "Transmit FIFO Under flow\n"); } if (intr_status & EESR_RDE) { @@ -890,12 +919,22 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) if (readl(ioaddr + EDRRR) ^ EDRRR_R) writel(EDRRR_R, ioaddr + EDRRR); - dev_err(&ndev->dev, "Receive Descriptor Empty\n"); + if (netif_msg_rx_err(mdp)) + dev_err(&ndev->dev, "Receive Descriptor Empty\n"); } + if (intr_status & EESR_RFE) { /* Receive FIFO Overflow int */ mdp->stats.rx_fifo_errors++; - dev_err(&ndev->dev, "Receive FIFO Overflow\n"); + if (netif_msg_rx_err(mdp)) + dev_err(&ndev->dev, "Receive FIFO Overflow\n"); + } + + if (!mdp->cd->no_ade && (intr_status & EESR_ADE)) { + /* Address Error */ + mdp->stats.tx_fifo_errors++; + if (netif_msg_tx_err(mdp)) + dev_err(&ndev->dev, "Address Error\n"); } mask = EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE; @@ -1012,7 +1051,7 @@ static void sh_eth_adjust_link(struct net_device *ndev) mdp->duplex = -1; } - if (new_state) + if (new_state && netif_msg_link(mdp)) phy_print_status(phydev); } @@ -1063,6 +1102,132 @@ static int sh_eth_phy_start(struct net_device *ndev) return 0; } +static int sh_eth_get_settings(struct net_device *ndev, + struct ethtool_cmd *ecmd) +{ + struct sh_eth_private *mdp = netdev_priv(ndev); + unsigned long flags; + int ret; + + spin_lock_irqsave(&mdp->lock, flags); + ret = phy_ethtool_gset(mdp->phydev, ecmd); + spin_unlock_irqrestore(&mdp->lock, flags); + + return ret; +} + +static int sh_eth_set_settings(struct net_device *ndev, + struct ethtool_cmd *ecmd) +{ + struct sh_eth_private *mdp = netdev_priv(ndev); + unsigned long flags; + int ret; + u32 ioaddr = ndev->base_addr; + + spin_lock_irqsave(&mdp->lock, flags); + + /* disable tx and rx */ + sh_eth_rcv_snd_disable(ioaddr); + + ret = phy_ethtool_sset(mdp->phydev, ecmd); + if (ret) + goto error_exit; + + if (ecmd->duplex == DUPLEX_FULL) + mdp->duplex = 1; + else + mdp->duplex = 0; + + if (mdp->cd->set_duplex) + mdp->cd->set_duplex(ndev); + +error_exit: + mdelay(1); + + /* enable tx and rx */ + sh_eth_rcv_snd_enable(ioaddr); + + spin_unlock_irqrestore(&mdp->lock, flags); + + return ret; +} + +static int sh_eth_nway_reset(struct net_device *ndev) +{ + struct sh_eth_private *mdp = netdev_priv(ndev); + unsigned long flags; + int ret; + + spin_lock_irqsave(&mdp->lock, flags); + ret = phy_start_aneg(mdp->phydev); + spin_unlock_irqrestore(&mdp->lock, flags); + + return ret; +} + +static u32 sh_eth_get_msglevel(struct net_device *ndev) +{ + struct sh_eth_private *mdp = netdev_priv(ndev); + return mdp->msg_enable; +} + +static void sh_eth_set_msglevel(struct net_device *ndev, u32 value) +{ + struct sh_eth_private *mdp = netdev_priv(ndev); + mdp->msg_enable = value; +} + +static const char sh_eth_gstrings_stats[][ETH_GSTRING_LEN] = { + "rx_current", "tx_current", + "rx_dirty", "tx_dirty", +}; +#define SH_ETH_STATS_LEN ARRAY_SIZE(sh_eth_gstrings_stats) + +static int sh_eth_get_sset_count(struct net_device *netdev, int sset) +{ + switch (sset) { + case ETH_SS_STATS: + return SH_ETH_STATS_LEN; + default: + return -EOPNOTSUPP; + } +} + +static void sh_eth_get_ethtool_stats(struct net_device *ndev, + struct ethtool_stats *stats, u64 *data) +{ + struct sh_eth_private *mdp = netdev_priv(ndev); + int i = 0; + + /* device-specific stats */ + data[i++] = mdp->cur_rx; + data[i++] = mdp->cur_tx; + data[i++] = mdp->dirty_rx; + data[i++] = mdp->dirty_tx; +} + +static void sh_eth_get_strings(struct net_device *ndev, u32 stringset, u8 *data) +{ + switch (stringset) { + case ETH_SS_STATS: + memcpy(data, *sh_eth_gstrings_stats, + sizeof(sh_eth_gstrings_stats)); + break; + } +} + +static struct ethtool_ops sh_eth_ethtool_ops = { + .get_settings = sh_eth_get_settings, + .set_settings = sh_eth_set_settings, + .nway_reset = sh_eth_nway_reset, + .get_msglevel = sh_eth_get_msglevel, + .set_msglevel = sh_eth_set_msglevel, + .get_link = ethtool_op_get_link, + .get_strings = sh_eth_get_strings, + .get_ethtool_stats = sh_eth_get_ethtool_stats, + .get_sset_count = sh_eth_get_sset_count, +}; + /* network device open function */ static int sh_eth_open(struct net_device *ndev) { @@ -1073,8 +1238,8 @@ static int sh_eth_open(struct net_device *ndev) ret = request_irq(ndev->irq, sh_eth_interrupt, #if defined(CONFIG_CPU_SUBTYPE_SH7763) || \ - defined(CONFIG_CPU_SUBTYPE_SH7764) || \ - defined(CONFIG_CPU_SUBTYPE_SH7757) + defined(CONFIG_CPU_SUBTYPE_SH7764) || \ + defined(CONFIG_CPU_SUBTYPE_SH7757) IRQF_SHARED, #else 0, @@ -1123,8 +1288,8 @@ static void sh_eth_tx_timeout(struct net_device *ndev) netif_stop_queue(ndev); - /* worning message out. */ - printk(KERN_WARNING "%s: transmit timed out, status %8.8x," + if (netif_msg_timer(mdp)) + dev_err(&ndev->dev, "%s: transmit timed out, status %8.8x," " resetting...\n", ndev->name, (int)readl(ioaddr + EESR)); /* tx_errors count up */ @@ -1167,6 +1332,8 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) spin_lock_irqsave(&mdp->lock, flags); if ((mdp->cur_tx - mdp->dirty_tx) >= (TX_RING_SIZE - 4)) { if (!sh_eth_txfree(ndev)) { + if (netif_msg_tx_queued(mdp)) + dev_warn(&ndev->dev, "TxFD exhausted.\n"); netif_stop_queue(ndev); spin_unlock_irqrestore(&mdp->lock, flags); return NETDEV_TX_BUSY; @@ -1497,8 +1664,11 @@ static int sh_eth_drv_probe(struct platform_device *pdev) /* set function */ ndev->netdev_ops = &sh_eth_netdev_ops; + SET_ETHTOOL_OPS(ndev, &sh_eth_ethtool_ops); ndev->watchdog_timeo = TX_TIMEOUT; + /* debug message level */ + mdp->msg_enable = SH_ETH_DEF_MSG_ENABLE; mdp->post_rx = POST_RX >> (devno << 1); mdp->post_fw = POST_FW >> (devno << 1); -- cgit v1.2.3 From 28801f351f76231e8d1e378274d6d56a577b897e Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 16 Feb 2011 03:48:38 +0000 Subject: sfc: lower stack usage in efx_ethtool_self_test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/net/sfc/ethtool.c: In function ‘efx_ethtool_self_test’: drivers/net/sfc/ethtool.c:613: warning: the frame size of 1200 bytes is larger than 1024 bytes Signed-off-by: Eric Dumazet Acked-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/ethtool.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 0e8bb19ed60d..ca886d98bdc7 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -569,9 +569,14 @@ static void efx_ethtool_self_test(struct net_device *net_dev, struct ethtool_test *test, u64 *data) { struct efx_nic *efx = netdev_priv(net_dev); - struct efx_self_tests efx_tests; + struct efx_self_tests *efx_tests; int already_up; - int rc; + int rc = -ENOMEM; + + efx_tests = kzalloc(sizeof(*efx_tests), GFP_KERNEL); + if (!efx_tests) + goto fail; + ASSERT_RTNL(); if (efx->state != STATE_RUNNING) { @@ -589,13 +594,11 @@ static void efx_ethtool_self_test(struct net_device *net_dev, if (rc) { netif_err(efx, drv, efx->net_dev, "failed opening device.\n"); - goto fail2; + goto fail1; } } - memset(&efx_tests, 0, sizeof(efx_tests)); - - rc = efx_selftest(efx, &efx_tests, test->flags); + rc = efx_selftest(efx, efx_tests, test->flags); if (!already_up) dev_close(efx->net_dev); @@ -604,10 +607,11 @@ static void efx_ethtool_self_test(struct net_device *net_dev, rc == 0 ? "passed" : "failed", (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on"); - fail2: - fail1: +fail1: /* Fill ethtool results structures */ - efx_ethtool_fill_self_tests(efx, &efx_tests, NULL, data); + efx_ethtool_fill_self_tests(efx, efx_tests, NULL, data); + kfree(efx_tests); +fail: if (rc) test->flags |= ETH_TEST_FL_FAILED; } -- cgit v1.2.3 From f6c4bf3e6927e1cc98b33c64df93aa8964349195 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Sun, 20 Feb 2011 11:41:04 +0000 Subject: be2net: add new counters to display via ethtool stats New counters: > jabber frame stats > red drop stats Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.h | 12 ++++++++++-- drivers/net/benet/be_ethtool.c | 13 +++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 91c5d2b09aa1..331e9540bc74 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -619,7 +619,10 @@ struct be_rxf_stats { u32 rx_drops_invalid_ring; /* dword 145*/ u32 forwarded_packets; /* dword 146*/ u32 rx_drops_mtu; /* dword 147*/ - u32 rsvd0[15]; + u32 rsvd0[7]; + u32 port0_jabber_events; + u32 port1_jabber_events; + u32 rsvd1[6]; }; struct be_erx_stats { @@ -630,11 +633,16 @@ struct be_erx_stats { u32 debug_pmem_pbuf_dealloc; /* dword 47*/ }; +struct be_pmem_stats { + u32 eth_red_drops; + u32 rsvd[4]; +}; + struct be_hw_stats { struct be_rxf_stats rxf; u32 rsvd[48]; struct be_erx_stats erx; - u32 rsvd1[6]; + struct be_pmem_stats pmem; }; struct be_cmd_req_get_stats { diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 07b4ab902b17..82a9a27a9812 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -26,7 +26,8 @@ struct be_ethtool_stat { int offset; }; -enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT}; +enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT, + PMEMSTAT}; #define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \ offsetof(_struct, field) #define NETSTAT_INFO(field) #field, NETSTAT,\ @@ -43,6 +44,8 @@ enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT}; field) #define ERXSTAT_INFO(field) #field, ERXSTAT,\ FIELDINFO(struct be_erx_stats, field) +#define PMEMSTAT_INFO(field) #field, PMEMSTAT,\ + FIELDINFO(struct be_pmem_stats, field) static const struct be_ethtool_stat et_stats[] = { {NETSTAT_INFO(rx_packets)}, @@ -99,7 +102,10 @@ static const struct be_ethtool_stat et_stats[] = { {MISCSTAT_INFO(rx_drops_too_many_frags)}, {MISCSTAT_INFO(rx_drops_invalid_ring)}, {MISCSTAT_INFO(forwarded_packets)}, - {MISCSTAT_INFO(rx_drops_mtu)} + {MISCSTAT_INFO(rx_drops_mtu)}, + {MISCSTAT_INFO(port0_jabber_events)}, + {MISCSTAT_INFO(port1_jabber_events)}, + {PMEMSTAT_INFO(eth_red_drops)} }; #define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats) @@ -276,6 +282,9 @@ be_get_ethtool_stats(struct net_device *netdev, case MISCSTAT: p = &hw_stats->rxf; break; + case PMEMSTAT: + p = &hw_stats->pmem; + break; } p = (u8 *)p + et_stats[i].offset; -- cgit v1.2.3 From 4ee772144f376ddf2a8c6ea5708a1362a9e85002 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Sun, 20 Feb 2011 11:41:20 +0000 Subject: be2net: fixes in ethtool selftest > add missing separator between items in ethtool self_test array > fix reporting of test resluts when link is down and when selftest command fails. From: Suresh R Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_ethtool.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 82a9a27a9812..0833cbdb9b53 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -127,7 +127,7 @@ static const char et_self_tests[][ETH_GSTRING_LEN] = { "MAC Loopback test", "PHY Loopback test", "External Loopback test", - "DDR DMA test" + "DDR DMA test", "Link test" }; @@ -642,7 +642,8 @@ be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) &qos_link_speed) != 0) { test->flags |= ETH_TEST_FL_FAILED; data[4] = -1; - } else if (mac_speed) { + } else if (!mac_speed) { + test->flags |= ETH_TEST_FL_FAILED; data[4] = 1; } } -- cgit v1.2.3 From b2aebe6d8102ed55c161371a6ac4d945c95c334c Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Sun, 20 Feb 2011 11:41:39 +0000 Subject: be2net: variable name change change occurances of stats_ioctl_sent to stats_cmd_sent Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 2 +- drivers/net/benet/be_cmds.c | 4 ++-- drivers/net/benet/be_main.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 3a800e2bc94b..fb605e83446c 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -298,7 +298,7 @@ struct be_adapter { u32 rx_fc; /* Rx flow control */ u32 tx_fc; /* Tx flow control */ bool ue_detected; - bool stats_ioctl_sent; + bool stats_cmd_sent; int link_speed; u8 port_type; u8 transceiver; diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 619ebc24602e..7120106db8cb 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -81,7 +81,7 @@ static int be_mcc_compl_process(struct be_adapter *adapter, be_dws_le_to_cpu(&resp->hw_stats, sizeof(resp->hw_stats)); netdev_stats_update(adapter); - adapter->stats_ioctl_sent = false; + adapter->stats_cmd_sent = false; } } else if ((compl_status != MCC_STATUS_NOT_SUPPORTED) && (compl->tag0 != OPCODE_COMMON_NTWK_MAC_QUERY)) { @@ -1075,7 +1075,7 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) sge->len = cpu_to_le32(nonemb_cmd->size); be_mcc_notify(adapter); - adapter->stats_ioctl_sent = true; + adapter->stats_cmd_sent = true; err: spin_unlock_bh(&adapter->mcc_lock); diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index aad7ea37d589..b9e170da12de 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1873,7 +1873,7 @@ static void be_worker(struct work_struct *work) goto reschedule; } - if (!adapter->stats_ioctl_sent) + if (!adapter->stats_cmd_sent) be_cmd_get_stats(adapter, &adapter->stats_cmd); be_tx_rate_update(adapter); -- cgit v1.2.3 From 3968fa1e58896187ee5629db0720d93b9313ad9f Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Sun, 20 Feb 2011 11:41:53 +0000 Subject: be2net: fix to ignore transparent vlan ids wrongly indicated by NIC With transparent VLAN tagging, the ASIC wrongly indicates packets with VLAN ID. Strip them off in the driver. The VLAN Tag to be stripped will be given to the host as an async message. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 1 + drivers/net/benet/be_cmds.c | 14 ++++++++++++++ drivers/net/benet/be_cmds.h | 13 +++++++++++++ drivers/net/benet/be_main.c | 6 ++++++ 4 files changed, 34 insertions(+) (limited to 'drivers') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index fb605e83446c..7bf8dd4edeb4 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -311,6 +311,7 @@ struct be_adapter { struct be_vf_cfg vf_cfg[BE_MAX_VF]; u8 is_virtfn; u32 sli_family; + u16 pvid; }; #define be_physfn(adapter) (!adapter->is_virtfn) diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 7120106db8cb..59d25acf4374 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -124,6 +124,16 @@ static void be_async_grp5_qos_speed_process(struct be_adapter *adapter, } } +/*Grp5 PVID evt*/ +static void be_async_grp5_pvid_state_process(struct be_adapter *adapter, + struct be_async_event_grp5_pvid_state *evt) +{ + if (evt->enabled) + adapter->pvid = evt->tag; + else + adapter->pvid = 0; +} + static void be_async_grp5_evt_process(struct be_adapter *adapter, u32 trailer, struct be_mcc_compl *evt) { @@ -141,6 +151,10 @@ static void be_async_grp5_evt_process(struct be_adapter *adapter, be_async_grp5_qos_speed_process(adapter, (struct be_async_event_grp5_qos_link_speed *)evt); break; + case ASYNC_EVENT_PVID_STATE: + be_async_grp5_pvid_state_process(adapter, + (struct be_async_event_grp5_pvid_state *)evt); + break; default: dev_warn(&adapter->pdev->dev, "Unknown grp5 event!\n"); break; diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 331e9540bc74..a5af2963e7ef 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -88,6 +88,7 @@ struct be_mcc_compl { #define ASYNC_EVENT_CODE_GRP_5 0x5 #define ASYNC_EVENT_QOS_SPEED 0x1 #define ASYNC_EVENT_COS_PRIORITY 0x2 +#define ASYNC_EVENT_PVID_STATE 0x3 struct be_async_event_trailer { u32 code; }; @@ -134,6 +135,18 @@ struct be_async_event_grp5_cos_priority { struct be_async_event_trailer trailer; } __packed; +/* When the event code of an async trailer is GRP5 and event type is + * PVID state, the mcc_compl must be interpreted as follows + */ +struct be_async_event_grp5_pvid_state { + u8 enabled; + u8 rsvd0; + u16 tag; + u32 event_tag; + u32 rsvd1; + struct be_async_event_trailer trailer; +} __packed; + struct be_mcc_mailbox { struct be_mcc_wrb wrb; struct be_mcc_compl compl; diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index b9e170da12de..cd6fda776d8d 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1047,6 +1047,9 @@ static void be_rx_compl_process(struct be_adapter *adapter, if ((adapter->function_mode & 0x400) && !vtm) vlanf = 0; + if ((adapter->pvid == vlanf) && !adapter->vlan_tag[vlanf]) + vlanf = 0; + if (unlikely(vlanf)) { if (!adapter->vlan_grp || adapter->vlans_added == 0) { kfree_skb(skb); @@ -1087,6 +1090,9 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, if ((adapter->function_mode & 0x400) && !vtm) vlanf = 0; + if ((adapter->pvid == vlanf) && !adapter->vlan_tag[vlanf]) + vlanf = 0; + skb = napi_get_frags(&eq_obj->napi); if (!skb) { be_rx_compl_discard(adapter, rxo, rxcp); -- cgit v1.2.3 From 609ff3bb8f6cd38c68c719bbc3c31d6b0b9ce894 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Sun, 20 Feb 2011 11:42:07 +0000 Subject: be2net: add code to display temperature of ASIC Add support to display temperature of ASIC via ethtool -S From: Somnath K Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 7 +++++++ drivers/net/benet/be_cmds.c | 44 ++++++++++++++++++++++++++++++++++++++++++ drivers/net/benet/be_cmds.h | 16 +++++++++++++++ drivers/net/benet/be_ethtool.c | 11 +++++++++-- 4 files changed, 76 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 7bf8dd4edeb4..46b951f2b045 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -225,6 +225,10 @@ struct be_rx_obj { u32 cache_line_barrier[15]; }; +struct be_drv_stats { + u8 be_on_die_temperature; +}; + struct be_vf_cfg { unsigned char vf_mac_addr[ETH_ALEN]; u32 vf_if_handle; @@ -234,6 +238,7 @@ struct be_vf_cfg { }; #define BE_INVALID_PMAC_ID 0xffffffff + struct be_adapter { struct pci_dev *pdev; struct net_device *netdev; @@ -269,6 +274,7 @@ struct be_adapter { u32 big_page_size; /* Compounded page size shared by rx wrbs */ u8 msix_vec_next_idx; + struct be_drv_stats drv_stats; struct vlan_group *vlan_grp; u16 vlans_added; @@ -281,6 +287,7 @@ struct be_adapter { struct be_dma_mem stats_cmd; /* Work queue used to perform periodic tasks like getting statistics */ struct delayed_work work; + u16 work_counter; /* Ethtool knobs and info */ bool rx_csum; /* BE card must perform rx-checksumming */ diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 59d25acf4374..ff62aaea9a45 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -18,6 +18,9 @@ #include "be.h" #include "be_cmds.h" +/* Must be a power of 2 or else MODULO will BUG_ON */ +static int be_get_temp_freq = 32; + static void be_mcc_notify(struct be_adapter *adapter) { struct be_queue_info *mccq = &adapter->mcc_obj.q; @@ -1069,6 +1072,9 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) struct be_sge *sge; int status = 0; + if (MODULO(adapter->work_counter, be_get_temp_freq) == 0) + be_cmd_get_die_temperature(adapter); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); @@ -1136,6 +1142,44 @@ err: return status; } +/* Uses synchronous mcc */ +int be_cmd_get_die_temperature(struct be_adapter *adapter) +{ + struct be_mcc_wrb *wrb; + struct be_cmd_req_get_cntl_addnl_attribs *req; + int status; + + spin_lock_bh(&adapter->mcc_lock); + + wrb = wrb_from_mccq(adapter); + if (!wrb) { + status = -EBUSY; + goto err; + } + req = embedded_payload(wrb); + + be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, + OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES); + + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, + OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES, sizeof(*req)); + + status = be_mcc_notify_wait(adapter); + if (!status) { + struct be_cmd_resp_get_cntl_addnl_attribs *resp = + embedded_payload(wrb); + adapter->drv_stats.be_on_die_temperature = + resp->on_die_temperature; + } + /* If IOCTL fails once, do not bother issuing it again */ + else + be_get_temp_freq = 0; + +err: + spin_unlock_bh(&adapter->mcc_lock); + return status; +} + /* Uses Mbox */ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver) { diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index a5af2963e7ef..6e89de82a5e9 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -189,6 +189,7 @@ struct be_mcc_mailbox { #define OPCODE_COMMON_GET_BEACON_STATE 70 #define OPCODE_COMMON_READ_TRANSRECV_DATA 73 #define OPCODE_COMMON_GET_PHY_DETAILS 102 +#define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121 #define OPCODE_ETH_RSS_CONFIG 1 #define OPCODE_ETH_ACPI_CONFIG 2 @@ -668,6 +669,20 @@ struct be_cmd_resp_get_stats { struct be_hw_stats hw_stats; }; +struct be_cmd_req_get_cntl_addnl_attribs { + struct be_cmd_req_hdr hdr; + u8 rsvd[8]; +}; + +struct be_cmd_resp_get_cntl_addnl_attribs { + struct be_cmd_resp_hdr hdr; + u16 ipl_file_number; + u8 ipl_file_version; + u8 rsvd0; + u8 on_die_temperature; /* in degrees centigrade*/ + u8 rsvd1[3]; +}; + struct be_cmd_req_vlan_config { struct be_cmd_req_hdr hdr; u8 interface_id; @@ -1099,4 +1114,5 @@ extern int be_cmd_get_phy_info(struct be_adapter *adapter, struct be_dma_mem *cmd); extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); extern void be_detect_dump_ue(struct be_adapter *adapter); +extern int be_cmd_get_die_temperature(struct be_adapter *adapter); diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 0833cbdb9b53..47666933c55a 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -27,7 +27,7 @@ struct be_ethtool_stat { }; enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT, - PMEMSTAT}; + PMEMSTAT, DRVSTAT}; #define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \ offsetof(_struct, field) #define NETSTAT_INFO(field) #field, NETSTAT,\ @@ -46,6 +46,9 @@ enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT, FIELDINFO(struct be_erx_stats, field) #define PMEMSTAT_INFO(field) #field, PMEMSTAT,\ FIELDINFO(struct be_pmem_stats, field) +#define DRVSTAT_INFO(field) #field, DRVSTAT,\ + FIELDINFO(struct be_drv_stats, \ + field) static const struct be_ethtool_stat et_stats[] = { {NETSTAT_INFO(rx_packets)}, @@ -105,7 +108,8 @@ static const struct be_ethtool_stat et_stats[] = { {MISCSTAT_INFO(rx_drops_mtu)}, {MISCSTAT_INFO(port0_jabber_events)}, {MISCSTAT_INFO(port1_jabber_events)}, - {PMEMSTAT_INFO(eth_red_drops)} + {PMEMSTAT_INFO(eth_red_drops)}, + {DRVSTAT_INFO(be_on_die_temperature)} }; #define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats) @@ -285,6 +289,9 @@ be_get_ethtool_stats(struct net_device *netdev, case PMEMSTAT: p = &hw_stats->pmem; break; + case DRVSTAT: + p = &adapter->drv_stats; + break; } p = (u8 *)p + et_stats[i].offset; -- cgit v1.2.3 From 9e1453c5c5fe670bb98a6097b262122386b0d3fe Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Sun, 20 Feb 2011 11:42:22 +0000 Subject: be2net: use hba_port_num instead of port_num Use hba_port_num for phy loopback and ethtool phy identification. From: Suresh R Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 1 + drivers/net/benet/be_cmds.c | 54 ++++++++++++++++++++++++++++++++++++++++++ drivers/net/benet/be_cmds.h | 12 ++++++++++ drivers/net/benet/be_ethtool.c | 12 +++++----- drivers/net/benet/be_hw.h | 47 ++++++++++++++++++++++++++++++++++++ drivers/net/benet/be_main.c | 4 ++++ 6 files changed, 124 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 46b951f2b045..ed709a5d07d7 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -318,6 +318,7 @@ struct be_adapter { struct be_vf_cfg vf_cfg[BE_MAX_VF]; u8 is_virtfn; u32 sli_family; + u8 hba_port_num; u16 pvid; }; diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index ff62aaea9a45..1822ecdadc7e 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -1954,3 +1954,57 @@ err: spin_unlock_bh(&adapter->mcc_lock); return status; } + +int be_cmd_get_cntl_attributes(struct be_adapter *adapter) +{ + struct be_mcc_wrb *wrb; + struct be_cmd_req_cntl_attribs *req; + struct be_cmd_resp_cntl_attribs *resp; + struct be_sge *sge; + int status; + int payload_len = max(sizeof(*req), sizeof(*resp)); + struct mgmt_controller_attrib *attribs; + struct be_dma_mem attribs_cmd; + + memset(&attribs_cmd, 0, sizeof(struct be_dma_mem)); + attribs_cmd.size = sizeof(struct be_cmd_resp_cntl_attribs); + attribs_cmd.va = pci_alloc_consistent(adapter->pdev, attribs_cmd.size, + &attribs_cmd.dma); + if (!attribs_cmd.va) { + dev_err(&adapter->pdev->dev, + "Memory allocation failure\n"); + return -ENOMEM; + } + + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; + + wrb = wrb_from_mbox(adapter); + if (!wrb) { + status = -EBUSY; + goto err; + } + req = attribs_cmd.va; + sge = nonembedded_sgl(wrb); + + be_wrb_hdr_prepare(wrb, payload_len, false, 1, + OPCODE_COMMON_GET_CNTL_ATTRIBUTES); + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, + OPCODE_COMMON_GET_CNTL_ATTRIBUTES, payload_len); + sge->pa_hi = cpu_to_le32(upper_32_bits(attribs_cmd.dma)); + sge->pa_lo = cpu_to_le32(attribs_cmd.dma & 0xFFFFFFFF); + sge->len = cpu_to_le32(attribs_cmd.size); + + status = be_mbox_notify_wait(adapter); + if (!status) { + attribs = (struct mgmt_controller_attrib *)( attribs_cmd.va + + sizeof(struct be_cmd_resp_hdr)); + adapter->hba_port_num = attribs->hba_attribs.phy_port; + } + +err: + mutex_unlock(&adapter->mbox_lock); + pci_free_consistent(adapter->pdev, attribs_cmd.size, attribs_cmd.va, + attribs_cmd.dma); + return status; +} diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 6e89de82a5e9..93e5768fc705 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -169,6 +169,7 @@ struct be_mcc_mailbox { #define OPCODE_COMMON_SET_QOS 28 #define OPCODE_COMMON_MCC_CREATE_EXT 90 #define OPCODE_COMMON_SEEPROM_READ 30 +#define OPCODE_COMMON_GET_CNTL_ATTRIBUTES 32 #define OPCODE_COMMON_NTWK_RX_FILTER 34 #define OPCODE_COMMON_GET_FW_VERSION 35 #define OPCODE_COMMON_SET_FLOW_CONTROL 36 @@ -1030,6 +1031,16 @@ struct be_cmd_resp_set_qos { u32 rsvd; }; +/*********************** Controller Attributes ***********************/ +struct be_cmd_req_cntl_attribs { + struct be_cmd_req_hdr hdr; +}; + +struct be_cmd_resp_cntl_attribs { + struct be_cmd_resp_hdr hdr; + struct mgmt_controller_attrib attribs; +}; + extern int be_pci_fnum_get(struct be_adapter *adapter); extern int be_cmd_POST(struct be_adapter *adapter); extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, @@ -1115,4 +1126,5 @@ extern int be_cmd_get_phy_info(struct be_adapter *adapter, extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); extern void be_detect_dump_ue(struct be_adapter *adapter); extern int be_cmd_get_die_temperature(struct be_adapter *adapter); +extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter); diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 47666933c55a..6e5e43380c2a 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -513,7 +513,7 @@ be_phys_id(struct net_device *netdev, u32 data) int status; u32 cur; - be_cmd_get_beacon_state(adapter, adapter->port_num, &cur); + be_cmd_get_beacon_state(adapter, adapter->hba_port_num, &cur); if (cur == BEACON_STATE_ENABLED) return 0; @@ -521,12 +521,12 @@ be_phys_id(struct net_device *netdev, u32 data) if (data < 2) data = 2; - status = be_cmd_set_beacon_state(adapter, adapter->port_num, 0, 0, + status = be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0, BEACON_STATE_ENABLED); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(data*HZ); - status = be_cmd_set_beacon_state(adapter, adapter->port_num, 0, 0, + status = be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0, BEACON_STATE_DISABLED); return status; @@ -605,12 +605,12 @@ err: static u64 be_loopback_test(struct be_adapter *adapter, u8 loopback_type, u64 *status) { - be_cmd_set_loopback(adapter, adapter->port_num, + be_cmd_set_loopback(adapter, adapter->hba_port_num, loopback_type, 1); - *status = be_cmd_loopback_test(adapter, adapter->port_num, + *status = be_cmd_loopback_test(adapter, adapter->hba_port_num, loopback_type, 1500, 2, 0xabc); - be_cmd_set_loopback(adapter, adapter->port_num, + be_cmd_set_loopback(adapter, adapter->hba_port_num, BE_NO_LOOPBACK, 1); return *status; } diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index 4096d9778234..3f459f76cd1d 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h @@ -327,6 +327,53 @@ struct be_eth_rx_compl { u32 dw[4]; }; +struct mgmt_hba_attribs { + u8 flashrom_version_string[32]; + u8 manufacturer_name[32]; + u32 supported_modes; + u32 rsvd0[3]; + u8 ncsi_ver_string[12]; + u32 default_extended_timeout; + u8 controller_model_number[32]; + u8 controller_description[64]; + u8 controller_serial_number[32]; + u8 ip_version_string[32]; + u8 firmware_version_string[32]; + u8 bios_version_string[32]; + u8 redboot_version_string[32]; + u8 driver_version_string[32]; + u8 fw_on_flash_version_string[32]; + u32 functionalities_supported; + u16 max_cdblength; + u8 asic_revision; + u8 generational_guid[16]; + u8 hba_port_count; + u16 default_link_down_timeout; + u8 iscsi_ver_min_max; + u8 multifunction_device; + u8 cache_valid; + u8 hba_status; + u8 max_domains_supported; + u8 phy_port; + u32 firmware_post_status; + u32 hba_mtu[8]; + u32 rsvd1[4]; +}; + +struct mgmt_controller_attrib { + struct mgmt_hba_attribs hba_attribs; + u16 pci_vendor_id; + u16 pci_device_id; + u16 pci_sub_vendor_id; + u16 pci_sub_system_id; + u8 pci_bus_number; + u8 pci_device_number; + u8 pci_function_number; + u8 interface_type; + u64 unique_identifier; + u32 rsvd0[5]; +}; + struct controller_id { u32 vendor; u32 device; diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index cd6fda776d8d..0bdccb10aac5 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2868,6 +2868,10 @@ static int be_get_config(struct be_adapter *adapter) else adapter->max_vlans = BE_NUM_VLANS_SUPPORTED; + status = be_cmd_get_cntl_attributes(adapter); + if (status) + return status; + return 0; } -- cgit v1.2.3 From bdcffc5a1a28b566a38a4b0d5bcefc78a97f4ecb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Feb 2011 15:41:47 -0800 Subject: tty: move Kconfig entries into drivers/tty from drivers/char The Kconfig options for the drivers/tty/ files still were hanging around in the "big" drivers/char/Kconfig file, so move them to the proper location under drivers/tty and drivers/tty/hvc/ Signed-off-by: Greg Kroah-Hartman --- drivers/char/Kconfig | 254 +----------------------------------------------- drivers/tty/Kconfig | 150 ++++++++++++++++++++++++++++ drivers/tty/hvc/Kconfig | 105 ++++++++++++++++++++ 3 files changed, 257 insertions(+), 252 deletions(-) create mode 100644 drivers/tty/Kconfig create mode 100644 drivers/tty/hvc/Kconfig (limited to 'drivers') diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 17f9b968b988..9b9ab867f50e 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -4,89 +4,7 @@ menu "Character devices" -config VT - bool "Virtual terminal" if EXPERT - depends on !S390 - select INPUT - default y - ---help--- - If you say Y here, you will get support for terminal devices with - display and keyboard devices. These are called "virtual" because you - can run several virtual terminals (also called virtual consoles) on - one physical terminal. This is rather useful, for example one - virtual terminal can collect system messages and warnings, another - one can be used for a text-mode user session, and a third could run - an X session, all in parallel. Switching between virtual terminals - is done with certain key combinations, usually Alt-. - - The setterm command ("man setterm") can be used to change the - properties (such as colors or beeping) of a virtual terminal. The - man page console_codes(4) ("man console_codes") contains the special - character sequences that can be used to change those properties - directly. The fonts used on virtual terminals can be changed with - the setfont ("man setfont") command and the key bindings are defined - with the loadkeys ("man loadkeys") command. - - You need at least one virtual terminal device in order to make use - of your keyboard and monitor. Therefore, only people configuring an - embedded system would want to say N here in order to save some - memory; the only way to log into such a system is then via a serial - or network connection. - - If unsure, say Y, or else you won't be able to do much with your new - shiny Linux system :-) - -config CONSOLE_TRANSLATIONS - depends on VT - default y - bool "Enable character translations in console" if EXPERT - ---help--- - This enables support for font mapping and Unicode translation - on virtual consoles. - -config VT_CONSOLE - bool "Support for console on virtual terminal" if EXPERT - depends on VT - default y - ---help--- - The system console is the device which receives all kernel messages - and warnings and which allows logins in single user mode. If you - answer Y here, a virtual terminal (the device used to interact with - a physical terminal) can be used as system console. This is the most - common mode of operations, so you should say Y here unless you want - the kernel messages be output only to a serial port (in which case - you should say Y to "Console on serial port", below). - - If you do say Y here, by default the currently visible virtual - terminal (/dev/tty0) will be used as system console. You can change - that with a kernel command line option such as "console=tty3" which - would use the third virtual terminal as system console. (Try "man - bootparam" or see the documentation of your boot loader (lilo or - loadlin) about how to pass options to the kernel at boot time.) - - If unsure, say Y. - -config HW_CONSOLE - bool - depends on VT && !S390 && !UML - default y - -config VT_HW_CONSOLE_BINDING - bool "Support for binding and unbinding console drivers" - depends on HW_CONSOLE - default n - ---help--- - The virtual terminal is the device that interacts with the physical - terminal through console drivers. On these systems, at least one - console driver is loaded. In other configurations, additional console - drivers may be enabled, such as the framebuffer console. If more than - 1 console driver is enabled, setting this to 'y' will allow you to - select the console driver that will serve as the backend for the - virtual terminals. - - See for more - information. For framebuffer console users, please refer to - . +source "drivers/tty/Kconfig" config DEVKMEM bool "/dev/kmem virtual device support" @@ -428,71 +346,6 @@ config SGI_MBCS source "drivers/tty/serial/Kconfig" -config UNIX98_PTYS - bool "Unix98 PTY support" if EXPERT - default y - ---help--- - A pseudo terminal (PTY) is a software device consisting of two - halves: a master and a slave. The slave device behaves identical to - a physical terminal; the master device is used by a process to - read data from and write data to the slave, thereby emulating a - terminal. Typical programs for the master side are telnet servers - and xterms. - - Linux has traditionally used the BSD-like names /dev/ptyxx for - masters and /dev/ttyxx for slaves of pseudo terminals. This scheme - has a number of problems. The GNU C library glibc 2.1 and later, - however, supports the Unix98 naming standard: in order to acquire a - pseudo terminal, a process opens /dev/ptmx; the number of the pseudo - terminal is then made available to the process and the pseudo - terminal slave can be accessed as /dev/pts/. What was - traditionally /dev/ttyp2 will then be /dev/pts/2, for example. - - All modern Linux systems use the Unix98 ptys. Say Y unless - you're on an embedded system and want to conserve memory. - -config DEVPTS_MULTIPLE_INSTANCES - bool "Support multiple instances of devpts" - depends on UNIX98_PTYS - default n - ---help--- - Enable support for multiple instances of devpts filesystem. - If you want to have isolated PTY namespaces (eg: in containers), - say Y here. Otherwise, say N. If enabled, each mount of devpts - filesystem with the '-o newinstance' option will create an - independent PTY namespace. - -config LEGACY_PTYS - bool "Legacy (BSD) PTY support" - default y - ---help--- - A pseudo terminal (PTY) is a software device consisting of two - halves: a master and a slave. The slave device behaves identical to - a physical terminal; the master device is used by a process to - read data from and write data to the slave, thereby emulating a - terminal. Typical programs for the master side are telnet servers - and xterms. - - Linux has traditionally used the BSD-like names /dev/ptyxx - for masters and /dev/ttyxx for slaves of pseudo - terminals. This scheme has a number of problems, including - security. This option enables these legacy devices; on most - systems, it is safe to say N. - - -config LEGACY_PTY_COUNT - int "Maximum number of legacy PTY in use" - depends on LEGACY_PTYS - range 0 256 - default "256" - ---help--- - The maximum number of legacy PTYs that can be used at any one time. - The default is 256, and should be more than enough. Embedded - systems may want to reduce this to save memory. - - When not in use, each legacy PTY occupies 12 bytes on 32-bit - architectures and 24 bytes on 64-bit architectures. - config TTY_PRINTK bool "TTY driver to output user messages via printk" depends on EXPERT @@ -612,93 +465,7 @@ config PPDEV If unsure, say N. -config HVC_DRIVER - bool - help - Generic "hypervisor virtual console" infrastructure for various - hypervisors (pSeries, iSeries, Xen, lguest). - It will automatically be selected if one of the back-end console drivers - is selected. - -config HVC_IRQ - bool - -config HVC_CONSOLE - bool "pSeries Hypervisor Virtual Console support" - depends on PPC_PSERIES - select HVC_DRIVER - select HVC_IRQ - help - pSeries machines when partitioned support a hypervisor virtual - console. This driver allows each pSeries partition to have a console - which is accessed via the HMC. - -config HVC_ISERIES - bool "iSeries Hypervisor Virtual Console support" - depends on PPC_ISERIES - default y - select HVC_DRIVER - select HVC_IRQ - select VIOPATH - help - iSeries machines support a hypervisor virtual console. - -config HVC_RTAS - bool "IBM RTAS Console support" - depends on PPC_RTAS - select HVC_DRIVER - help - IBM Console device driver which makes use of RTAS - -config HVC_BEAT - bool "Toshiba's Beat Hypervisor Console support" - depends on PPC_CELLEB - select HVC_DRIVER - help - Toshiba's Cell Reference Set Beat Console device driver - -config HVC_IUCV - bool "z/VM IUCV Hypervisor console support (VM only)" - depends on S390 - select HVC_DRIVER - select IUCV - default y - help - This driver provides a Hypervisor console (HVC) back-end to access - a Linux (console) terminal via a z/VM IUCV communication path. - -config HVC_XEN - bool "Xen Hypervisor Console support" - depends on XEN - select HVC_DRIVER - select HVC_IRQ - default y - help - Xen virtual console device driver - -config HVC_UDBG - bool "udbg based fake hypervisor console" - depends on PPC && EXPERIMENTAL - select HVC_DRIVER - default n - -config HVC_DCC - bool "ARM JTAG DCC console" - depends on ARM - select HVC_DRIVER - help - This console uses the JTAG DCC on ARM to create a console under the HVC - driver. This console is used through a JTAG only on ARM. If you don't have - a JTAG then you probably don't want this option. - -config HVC_BFIN_JTAG - bool "Blackfin JTAG console" - depends on BLACKFIN - select HVC_DRIVER - help - This console uses the Blackfin JTAG to create a console under the - the HVC driver. If you don't have JTAG, then you probably don't - want this option. +source "drivers/tty/hvc/Kconfig" config VIRTIO_CONSOLE tristate "Virtio console" @@ -716,23 +483,6 @@ config VIRTIO_CONSOLE the port which can be used by udev scripts to create a symlink to the device. -config HVCS - tristate "IBM Hypervisor Virtual Console Server support" - depends on PPC_PSERIES && HVC_CONSOLE - help - Partitionable IBM Power5 ppc64 machines allow hosting of - firmware virtual consoles from one Linux partition by - another Linux partition. This driver allows console data - from Linux partitions to be accessed through TTY device - interfaces in the device tree of a Linux partition running - this driver. - - To compile this driver as a module, choose M here: the - module will be called hvcs. Additionally, this module - will depend on arch specific APIs exported from hvcserver.ko - which will also be compiled when this driver is built as a - module. - config IBM_BSR tristate "IBM POWER Barrier Synchronization Register support" depends on PPC_PSERIES diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig new file mode 100644 index 000000000000..9cfbdb318ed9 --- /dev/null +++ b/drivers/tty/Kconfig @@ -0,0 +1,150 @@ +config VT + bool "Virtual terminal" if EXPERT + depends on !S390 + select INPUT + default y + ---help--- + If you say Y here, you will get support for terminal devices with + display and keyboard devices. These are called "virtual" because you + can run several virtual terminals (also called virtual consoles) on + one physical terminal. This is rather useful, for example one + virtual terminal can collect system messages and warnings, another + one can be used for a text-mode user session, and a third could run + an X session, all in parallel. Switching between virtual terminals + is done with certain key combinations, usually Alt-. + + The setterm command ("man setterm") can be used to change the + properties (such as colors or beeping) of a virtual terminal. The + man page console_codes(4) ("man console_codes") contains the special + character sequences that can be used to change those properties + directly. The fonts used on virtual terminals can be changed with + the setfont ("man setfont") command and the key bindings are defined + with the loadkeys ("man loadkeys") command. + + You need at least one virtual terminal device in order to make use + of your keyboard and monitor. Therefore, only people configuring an + embedded system would want to say N here in order to save some + memory; the only way to log into such a system is then via a serial + or network connection. + + If unsure, say Y, or else you won't be able to do much with your new + shiny Linux system :-) + +config CONSOLE_TRANSLATIONS + depends on VT + default y + bool "Enable character translations in console" if EXPERT + ---help--- + This enables support for font mapping and Unicode translation + on virtual consoles. + +config VT_CONSOLE + bool "Support for console on virtual terminal" if EXPERT + depends on VT + default y + ---help--- + The system console is the device which receives all kernel messages + and warnings and which allows logins in single user mode. If you + answer Y here, a virtual terminal (the device used to interact with + a physical terminal) can be used as system console. This is the most + common mode of operations, so you should say Y here unless you want + the kernel messages be output only to a serial port (in which case + you should say Y to "Console on serial port", below). + + If you do say Y here, by default the currently visible virtual + terminal (/dev/tty0) will be used as system console. You can change + that with a kernel command line option such as "console=tty3" which + would use the third virtual terminal as system console. (Try "man + bootparam" or see the documentation of your boot loader (lilo or + loadlin) about how to pass options to the kernel at boot time.) + + If unsure, say Y. + +config HW_CONSOLE + bool + depends on VT && !S390 && !UML + default y + +config VT_HW_CONSOLE_BINDING + bool "Support for binding and unbinding console drivers" + depends on HW_CONSOLE + default n + ---help--- + The virtual terminal is the device that interacts with the physical + terminal through console drivers. On these systems, at least one + console driver is loaded. In other configurations, additional console + drivers may be enabled, such as the framebuffer console. If more than + 1 console driver is enabled, setting this to 'y' will allow you to + select the console driver that will serve as the backend for the + virtual terminals. + + See for more + information. For framebuffer console users, please refer to + . + +config UNIX98_PTYS + bool "Unix98 PTY support" if EXPERT + default y + ---help--- + A pseudo terminal (PTY) is a software device consisting of two + halves: a master and a slave. The slave device behaves identical to + a physical terminal; the master device is used by a process to + read data from and write data to the slave, thereby emulating a + terminal. Typical programs for the master side are telnet servers + and xterms. + + Linux has traditionally used the BSD-like names /dev/ptyxx for + masters and /dev/ttyxx for slaves of pseudo terminals. This scheme + has a number of problems. The GNU C library glibc 2.1 and later, + however, supports the Unix98 naming standard: in order to acquire a + pseudo terminal, a process opens /dev/ptmx; the number of the pseudo + terminal is then made available to the process and the pseudo + terminal slave can be accessed as /dev/pts/. What was + traditionally /dev/ttyp2 will then be /dev/pts/2, for example. + + All modern Linux systems use the Unix98 ptys. Say Y unless + you're on an embedded system and want to conserve memory. + +config DEVPTS_MULTIPLE_INSTANCES + bool "Support multiple instances of devpts" + depends on UNIX98_PTYS + default n + ---help--- + Enable support for multiple instances of devpts filesystem. + If you want to have isolated PTY namespaces (eg: in containers), + say Y here. Otherwise, say N. If enabled, each mount of devpts + filesystem with the '-o newinstance' option will create an + independent PTY namespace. + +config LEGACY_PTYS + bool "Legacy (BSD) PTY support" + default y + ---help--- + A pseudo terminal (PTY) is a software device consisting of two + halves: a master and a slave. The slave device behaves identical to + a physical terminal; the master device is used by a process to + read data from and write data to the slave, thereby emulating a + terminal. Typical programs for the master side are telnet servers + and xterms. + + Linux has traditionally used the BSD-like names /dev/ptyxx + for masters and /dev/ttyxx for slaves of pseudo + terminals. This scheme has a number of problems, including + security. This option enables these legacy devices; on most + systems, it is safe to say N. + + +config LEGACY_PTY_COUNT + int "Maximum number of legacy PTY in use" + depends on LEGACY_PTYS + range 0 256 + default "256" + ---help--- + The maximum number of legacy PTYs that can be used at any one time. + The default is 256, and should be more than enough. Embedded + systems may want to reduce this to save memory. + + When not in use, each legacy PTY occupies 12 bytes on 32-bit + architectures and 24 bytes on 64-bit architectures. + + diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig new file mode 100644 index 000000000000..6f2c9809f1fb --- /dev/null +++ b/drivers/tty/hvc/Kconfig @@ -0,0 +1,105 @@ +config HVC_DRIVER + bool + help + Generic "hypervisor virtual console" infrastructure for various + hypervisors (pSeries, iSeries, Xen, lguest). + It will automatically be selected if one of the back-end console drivers + is selected. + +config HVC_IRQ + bool + +config HVC_CONSOLE + bool "pSeries Hypervisor Virtual Console support" + depends on PPC_PSERIES + select HVC_DRIVER + select HVC_IRQ + help + pSeries machines when partitioned support a hypervisor virtual + console. This driver allows each pSeries partition to have a console + which is accessed via the HMC. + +config HVC_ISERIES + bool "iSeries Hypervisor Virtual Console support" + depends on PPC_ISERIES + default y + select HVC_DRIVER + select HVC_IRQ + select VIOPATH + help + iSeries machines support a hypervisor virtual console. + +config HVC_RTAS + bool "IBM RTAS Console support" + depends on PPC_RTAS + select HVC_DRIVER + help + IBM Console device driver which makes use of RTAS + +config HVC_BEAT + bool "Toshiba's Beat Hypervisor Console support" + depends on PPC_CELLEB + select HVC_DRIVER + help + Toshiba's Cell Reference Set Beat Console device driver + +config HVC_IUCV + bool "z/VM IUCV Hypervisor console support (VM only)" + depends on S390 + select HVC_DRIVER + select IUCV + default y + help + This driver provides a Hypervisor console (HVC) back-end to access + a Linux (console) terminal via a z/VM IUCV communication path. + +config HVC_XEN + bool "Xen Hypervisor Console support" + depends on XEN + select HVC_DRIVER + select HVC_IRQ + default y + help + Xen virtual console device driver + +config HVC_UDBG + bool "udbg based fake hypervisor console" + depends on PPC && EXPERIMENTAL + select HVC_DRIVER + default n + +config HVC_DCC + bool "ARM JTAG DCC console" + depends on ARM + select HVC_DRIVER + help + This console uses the JTAG DCC on ARM to create a console under the HVC + driver. This console is used through a JTAG only on ARM. If you don't have + a JTAG then you probably don't want this option. + +config HVC_BFIN_JTAG + bool "Blackfin JTAG console" + depends on BLACKFIN + select HVC_DRIVER + help + This console uses the Blackfin JTAG to create a console under the + the HVC driver. If you don't have JTAG, then you probably don't + want this option. + +config HVCS + tristate "IBM Hypervisor Virtual Console Server support" + depends on PPC_PSERIES && HVC_CONSOLE + help + Partitionable IBM Power5 ppc64 machines allow hosting of + firmware virtual consoles from one Linux partition by + another Linux partition. This driver allows console data + from Linux partitions to be accessed through TTY device + interfaces in the device tree of a Linux partition running + this driver. + + To compile this driver as a module, choose M here: the + module will be called hvcs. Additionally, this module + will depend on arch specific APIs exported from hvcserver.ko + which will also be compiled when this driver is built as a + module. + -- cgit v1.2.3 From 085a4f758f0cf95e1865b63892bf4304a149f0ca Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Tue, 22 Feb 2011 15:28:10 +0800 Subject: serial: mfd: remove the TX full-empty interrupts workaround In A0 stepping, TX half-empty interrupt is not working, so have to use the full-empty interrupts whose performance will be 15% lower. Now re-enable the half-empty interrrupt after it is enabled in silicon. Signed-off-by: Feng Tang Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mfd.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c index 776777462937..53ff6af16273 100644 --- a/drivers/tty/serial/mfd.c +++ b/drivers/tty/serial/mfd.c @@ -16,9 +16,7 @@ * 2/3 chan to port 1, 4/5 chan to port 3. Even number chans * are used for RX, odd chans for TX * - * 2. In A0 stepping, UART will not support TX half empty flag - * - * 3. The RI/DSR/DCD/DTR are not pinned out, DCD & DSR are always + * 2. The RI/DSR/DCD/DTR are not pinned out, DCD & DSR are always * asserted, only when the HW is reset the DDCD and DDSR will * be triggered */ @@ -41,8 +39,6 @@ #include #include -#define MFD_HSU_A0_STEPPING 1 - #define HSU_DMA_BUF_SIZE 2048 #define chan_readl(chan, offset) readl(chan->reg + offset) @@ -543,16 +539,9 @@ static void transmit_chars(struct uart_hsu_port *up) return; } -#ifndef MFD_HSU_A0_STEPPING + /* The IRQ is for TX FIFO half-empty */ count = up->port.fifosize / 2; -#else - /* - * A0 only supports fully empty IRQ, and the first char written - * into it won't clear the EMPT bit, so we may need be cautious - * by useing a shorter buffer - */ - count = up->port.fifosize - 4; -#endif + do { serial_out(up, UART_TX, xmit->buf[xmit->tail]); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); @@ -761,9 +750,8 @@ static void serial_hsu_break_ctl(struct uart_port *port, int break_state) /* * What special to do: * 1. chose the 64B fifo mode - * 2. make sure not to select half empty mode for A0 stepping - * 3. start dma or pio depends on configuration - * 4. we only allocate dma memory when needed + * 2. start dma or pio depends on configuration + * 3. we only allocate dma memory when needed */ static int serial_hsu_startup(struct uart_port *port) { @@ -967,10 +955,6 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios, fcr = UART_FCR_ENABLE_FIFO | UART_FCR_HSU_64_32B; fcr |= UART_FCR_HSU_64B_FIFO; -#ifdef MFD_HSU_A0_STEPPING - /* A0 doesn't support half empty IRQ */ - fcr |= UART_FCR_FULL_EMPT_TXI; -#endif /* * Ok, we're now changing the port state. Do it with -- cgit v1.2.3 From f023eab379821365bf265a0240f30c00cecaef7c Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Tue, 22 Feb 2011 15:28:12 +0800 Subject: serial: mfd: add a module parameter for setting each port's working mode The three identical uart ports can work either in DMA or PIO mode. Adding such a module parameter "hsu_dma_enable" will enable user to chose working modes for each port. If the mfd driver is built in kernel, adding a "mfd.hsu_dma_enable=x" in kernel command line has the same effect. Signed-off-by: Feng Tang Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mfd.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c index 53ff6af16273..c111f36f5d21 100644 --- a/drivers/tty/serial/mfd.c +++ b/drivers/tty/serial/mfd.c @@ -47,6 +47,11 @@ #define mfd_readl(obj, offset) readl(obj->reg + offset) #define mfd_writel(obj, offset, val) writel(val, obj->reg + offset) +static int hsu_dma_enable; +module_param(hsu_dma_enable, int, 0); +MODULE_PARM_DESC(hsu_dma_enable, "It is a bitmap to set working mode, if \ +bit[x] is 1, then port[x] will work in DMA mode, otherwise in PIO mode."); + struct hsu_dma_buffer { u8 *buf; dma_addr_t dma_addr; @@ -1367,6 +1372,12 @@ static void hsu_global_init(void) serial_hsu_ports[i] = uport; uport->index = i; + + if (hsu_dma_enable & (1<use_dma = 1; + else + uport->use_dma = 0; + uport++; } -- cgit v1.2.3 From 2314a0f667352748a48753bf903f8c50fd2a756d Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 18 Feb 2011 16:38:37 +0100 Subject: tty: serial: altera_jtaguart: Don't use plain integer as NULL pointer This fixes a sparse warning. Signed-off-by: Tobias Klauser Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/altera_jtaguart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index f9b49b5ff5e1..0c0a8b60f2d6 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -384,7 +384,7 @@ static int __init altera_jtaguart_console_setup(struct console *co, if (co->index < 0 || co->index >= ALTERA_JTAGUART_MAXPORTS) return -EINVAL; port = &altera_jtaguart_ports[co->index].port; - if (port->membase == 0) + if (port->membase == NULL) return -ENODEV; return 0; } -- cgit v1.2.3 From 3231f075070ac61ab7174a9a82bdc6d7b1de10bb Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 18 Feb 2011 16:38:38 +0100 Subject: tty: serial: altera_jtaguart: Remove unused function early_altera_jtaguart_setup This is not even used in nios2 arch code anymore. Signed-off-by: Tobias Klauser Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/altera_jtaguart.c | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index 0c0a8b60f2d6..94ccf4741f0e 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -305,28 +305,6 @@ static struct altera_jtaguart altera_jtaguart_ports[ALTERA_JTAGUART_MAXPORTS]; #if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) -int __init early_altera_jtaguart_setup(struct altera_jtaguart_platform_uart - *platp) -{ - struct uart_port *port; - int i; - - for (i = 0; i < ALTERA_JTAGUART_MAXPORTS && platp[i].mapbase; i++) { - port = &altera_jtaguart_ports[i].port; - - port->line = i; - port->type = PORT_ALTERA_JTAGUART; - port->mapbase = platp[i].mapbase; - port->membase = ioremap(port->mapbase, ALTERA_JTAGUART_SIZE); - port->iotype = SERIAL_IO_MEM; - port->irq = platp[i].irq; - port->flags = ASYNC_BOOT_AUTOCONF; - port->ops = &altera_jtaguart_ops; - } - - return 0; -} - #if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS) static void altera_jtaguart_console_putc(struct console *co, const char c) { -- cgit v1.2.3 From 72af4762ee640b717a30761e27fc55126c686568 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 18 Feb 2011 16:38:39 +0100 Subject: tty: serial: altera_jtaguart: Support getting mapbase and IRQ from resources This will make it easier to get the driver to support device tree. The old platform data method is still supported though. Also change the driver to use only one platform device per port. Signed-off-by: Tobias Klauser Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/altera_jtaguart.c | 61 +++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index 94ccf4741f0e..aa2a4caaa1c3 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -409,22 +409,45 @@ static int __devinit altera_jtaguart_probe(struct platform_device *pdev) { struct altera_jtaguart_platform_uart *platp = pdev->dev.platform_data; struct uart_port *port; - int i; + struct resource *res_irq, *res_mem; + int i = pdev->id; - for (i = 0; i < ALTERA_JTAGUART_MAXPORTS && platp[i].mapbase; i++) { - port = &altera_jtaguart_ports[i].port; + /* -1 emphasizes that the platform must have one port, no .N suffix */ + if (i == -1) + i = 0; - port->line = i; - port->type = PORT_ALTERA_JTAGUART; - port->mapbase = platp[i].mapbase; - port->membase = ioremap(port->mapbase, ALTERA_JTAGUART_SIZE); - port->iotype = SERIAL_IO_MEM; - port->irq = platp[i].irq; - port->ops = &altera_jtaguart_ops; - port->flags = ASYNC_BOOT_AUTOCONF; + if (i >= ALTERA_JTAGUART_MAXPORTS) + return -EINVAL; - uart_add_one_port(&altera_jtaguart_driver, port); - } + port = &altera_jtaguart_ports[i].port; + + res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res_mem) + port->mapbase = res_mem->start; + else if (platp) + port->mapbase = platp->mapbase; + else + return -ENODEV; + + res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (res_irq) + port->irq = res_irq->start; + else if (platp) + port->irq = platp->irq; + else + return -ENODEV; + + port->membase = ioremap(port->mapbase, ALTERA_JTAGUART_SIZE); + if (!port->membase) + return -ENOMEM; + + port->line = i; + port->type = PORT_ALTERA_JTAGUART; + port->iotype = SERIAL_IO_MEM; + port->ops = &altera_jtaguart_ops; + port->flags = ASYNC_BOOT_AUTOCONF; + + uart_add_one_port(&altera_jtaguart_driver, port); return 0; } @@ -432,13 +455,13 @@ static int __devinit altera_jtaguart_probe(struct platform_device *pdev) static int __devexit altera_jtaguart_remove(struct platform_device *pdev) { struct uart_port *port; - int i; + int i = pdev->id; - for (i = 0; i < ALTERA_JTAGUART_MAXPORTS; i++) { - port = &altera_jtaguart_ports[i].port; - if (port) - uart_remove_one_port(&altera_jtaguart_driver, port); - } + if (i == -1) + i = 0; + + port = &altera_jtaguart_ports[i].port; + uart_remove_one_port(&altera_jtaguart_driver, port); return 0; } -- cgit v1.2.3 From 44ed76b78e158d852f640d533b7acc08b91f2132 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 18 Feb 2011 16:38:40 +0100 Subject: tty: serial: altera_jtaguart: Fixup type usage of port flags port->flags is of type upf_t, which corresponds to UPF_* flags. Signed-off-by: Tobias Klauser Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/altera_jtaguart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index aa2a4caaa1c3..8f014bb916b7 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -445,7 +445,7 @@ static int __devinit altera_jtaguart_probe(struct platform_device *pdev) port->type = PORT_ALTERA_JTAGUART; port->iotype = SERIAL_IO_MEM; port->ops = &altera_jtaguart_ops; - port->flags = ASYNC_BOOT_AUTOCONF; + port->flags = UPF_BOOT_AUTOCONF; uart_add_one_port(&altera_jtaguart_driver, port); -- cgit v1.2.3 From f10820e49585f281706ac07570a9e1652bdb5dd9 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 31 Jan 2011 15:09:23 +0100 Subject: i2c-stu300: make sure adapter-name is terminated Use strlcpy instead of strncpy. Signed-off-by: Wolfram Sang Cc: Linus Walleij Cc: Ben Dooks Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-stu300.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-stu300.c b/drivers/i2c/busses/i2c-stu300.c index 495be451d326..266135ddf7fa 100644 --- a/drivers/i2c/busses/i2c-stu300.c +++ b/drivers/i2c/busses/i2c-stu300.c @@ -942,7 +942,7 @@ stu300_probe(struct platform_device *pdev) adap->owner = THIS_MODULE; /* DDC class but actually often used for more generic I2C */ adap->class = I2C_CLASS_DDC; - strncpy(adap->name, "ST Microelectronics DDC I2C adapter", + strlcpy(adap->name, "ST Microelectronics DDC I2C adapter", sizeof(adap->name)); adap->nr = bus_nr; adap->algo = &stu300_algo; -- cgit v1.2.3 From adf6e07922255937c8bfeea777d19502b4c9a2be Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 27 Jan 2011 16:18:41 -0800 Subject: i2c-omap: fix static suspend vs. runtime suspend When runtime PM is enabled, each OMAP i2c device is suspended after each i2c xfer. However, there are two cases when the static suspend methods must be used to ensure the devices are suspended: 1) runtime PM is disabled, either at compile time or dynamically via /sys/devices/.../power/control. 2) an i2c client driver uses i2c during it's suspend callback, thus leaving the i2c driver active (NOTE: runtime suspend transitions are disabled during system suspend, so i2c activity during system suspend will runtime resume the device, but not runtime (re)suspend it.) Since the actual work to suspend the device is handled by the subsytem, call the bus methods to take care of it. NOTE: This takes care of a known suspend problem on OMAP3 where the TWL RTC driver does i2c xfers during its suspend path leaving the i2c driver in an active state (since runtime suspend transistions are disabled.) Signed-off-by: Kevin Hilman Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-omap.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index b605ff3a1fa0..0541df90b9fb 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1137,12 +1137,40 @@ omap_i2c_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_SUSPEND +static int omap_i2c_suspend(struct device *dev) +{ + if (!pm_runtime_suspended(dev)) + if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend) + dev->bus->pm->runtime_suspend(dev); + + return 0; +} + +static int omap_i2c_resume(struct device *dev) +{ + if (!pm_runtime_suspended(dev)) + if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_resume) + dev->bus->pm->runtime_resume(dev); + + return 0; +} + +static struct dev_pm_ops omap_i2c_pm_ops = { + .suspend = omap_i2c_suspend, + .resume = omap_i2c_resume, +}; +#else +#define omap_i2c_pm_ops NULL +#endif + static struct platform_driver omap_i2c_driver = { .probe = omap_i2c_probe, .remove = omap_i2c_remove, .driver = { .name = "omap_i2c", .owner = THIS_MODULE, + .pm = &omap_i2c_pm_ops, }, }; -- cgit v1.2.3 From bd6a60afeb4c9ada3ff27f1d13db1a2b5c11d8c0 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 21 Feb 2011 01:11:59 -0500 Subject: Revert "drm/radeon/kms: switch back to min->max pll post divider iteration" This reverts commit a6f9761743bf35b052180f4a8bdae4d2cc0465f6. Remove this commit as it is no longer necessary. The relevant bugs were fixed properly in: drm/radeon/kms: hopefully fix pll issues for real (v3) 5b40ddf888398ce4cccbf3b9d0a18d90149ed7ff drm/radeon/kms: add missing frac fb div flag for dce4+ 9f4283f49f0a96a64c5a45fe56f0f8c942885eef This commit also broke certain ~5 Mhz modes on old arcade monitors, so reverting this commit fixes: https://bugzilla.kernel.org/show_bug.cgi?id=29502 Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 0e657095de7c..3e7e7f9eb781 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -971,7 +971,7 @@ void radeon_compute_pll_legacy(struct radeon_pll *pll, max_fractional_feed_div = pll->max_frac_feedback_div; } - for (post_div = min_post_div; post_div <= max_post_div; ++post_div) { + for (post_div = max_post_div; post_div >= min_post_div; --post_div) { uint32_t ref_div; if ((pll->flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1)) -- cgit v1.2.3 From e40b6fc8373314666e7853733dc0ca4049a68b95 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 18 Feb 2011 15:51:57 +1000 Subject: drm/radeon/kms: align height of fb allocation. this aligns the height of the fb allocation so it doesn't trip over the size checks later when we use this from userspace to copy the buffer at X start. Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_fb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 66324b5bb5ba..cc44bdfec80f 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c @@ -113,11 +113,14 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev, u32 tiling_flags = 0; int ret; int aligned_size, size; + int height = mode_cmd->height; /* need to align pitch with crtc limits */ mode_cmd->pitch = radeon_align_pitch(rdev, mode_cmd->width, mode_cmd->bpp, fb_tiled) * ((mode_cmd->bpp + 1) / 8); - size = mode_cmd->pitch * mode_cmd->height; + if (rdev->family >= CHIP_R600) + height = ALIGN(mode_cmd->height, 8); + size = mode_cmd->pitch * height; aligned_size = ALIGN(size, PAGE_SIZE); ret = radeon_gem_object_create(rdev, aligned_size, 0, RADEON_GEM_DOMAIN_VRAM, -- cgit v1.2.3 From c4cc383915549cf14f027f374904e30c13653dac Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Mon, 21 Feb 2011 05:42:00 +0100 Subject: drm/vblank: Use abs64(diff_ns) for s64 diff_ns instead of abs(diff_ns) Use of abs() wrongly wrapped diff_ns to 32 bit, which gives a 1/4000 probability of a missed vblank increment at each vblank irq reenable if the kms driver doesn't support high precision vblank timestamping. Not a big deal in practice, but let's make it nice. Signed-off-by: Mario Kleiner Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 3dadfa2a8528..6d2d4faf8678 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -164,7 +164,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) * available. In that case we can't account for this and just * hope for the best. */ - if ((vblrc > 0) && (abs(diff_ns) > 1000000)) + if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) atomic_inc(&dev->_vblank_count[crtc]); /* Invalidate all timestamps while vblank irq's are off. */ @@ -1293,7 +1293,7 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) * e.g., due to spurious vblank interrupts. We need to * ignore those for accounting. */ - if (abs(diff_ns) > DRM_REDUNDANT_VBLIRQ_THRESH_NS) { + if (abs64(diff_ns) > DRM_REDUNDANT_VBLIRQ_THRESH_NS) { /* Store new timestamp in ringbuffer. */ vblanktimestamp(dev, crtc, vblcount + 1) = tvblank; smp_wmb(); -- cgit v1.2.3 From bc21512835a72bc1eab7abd7d8a1bff0435591d7 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Mon, 21 Feb 2011 05:42:01 +0100 Subject: drm/vblank: Use memory barriers optimized for atomic_t instead of generics. Documentation/atomic_ops.txt tells us that there are memory barriers optimized for atomic_inc and other atomic_t ops. Use these instead of smp_wmb(), and also to make the required memory barriers around vblank counter increments more explicit. Signed-off-by: Mario Kleiner Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_irq.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 6d2d4faf8678..22f3bf5ecbd2 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -164,8 +164,10 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) * available. In that case we can't account for this and just * hope for the best. */ - if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) + if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) { atomic_inc(&dev->_vblank_count[crtc]); + smp_mb__after_atomic_inc(); + } /* Invalidate all timestamps while vblank irq's are off. */ clear_vblank_timestamps(dev, crtc); @@ -858,10 +860,11 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc) if (rc) { tslot = atomic_read(&dev->_vblank_count[crtc]) + diff; vblanktimestamp(dev, crtc, tslot) = t_vblank; - smp_wmb(); } + smp_mb__before_atomic_inc(); atomic_add(diff, &dev->_vblank_count[crtc]); + smp_mb__after_atomic_inc(); } /** @@ -1296,12 +1299,13 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) if (abs64(diff_ns) > DRM_REDUNDANT_VBLIRQ_THRESH_NS) { /* Store new timestamp in ringbuffer. */ vblanktimestamp(dev, crtc, vblcount + 1) = tvblank; - smp_wmb(); /* Increment cooked vblank count. This also atomically commits * the timestamp computed above. */ + smp_mb__before_atomic_inc(); atomic_inc(&dev->_vblank_count[crtc]); + smp_mb__after_atomic_inc(); } else { DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n", crtc, (int) diff_ns); -- cgit v1.2.3 From 9be6f8a978bdcbab46474a125aa4212516b71fe7 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Mon, 21 Feb 2011 05:42:02 +0100 Subject: drm/vblank: Enable precise vblank timestamps for interlaced and doublescan modes. Testing showed the current code can already handle doublescan video modes just fine. A trivial tweak makes it work for interlaced scanout as well. Tested and shown to be precise on Radeon rv530, r600 and Intel 945-GME. Signed-off-by: Mario Kleiner Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_irq.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 22f3bf5ecbd2..53120a72a48c 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -493,6 +493,12 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc) /* Dot clock in Hz: */ dotclock = (u64) crtc->hwmode.clock * 1000; + /* Fields of interlaced scanout modes are only halve a frame duration. + * Double the dotclock to get halve the frame-/line-/pixelduration. + */ + if (crtc->hwmode.flags & DRM_MODE_FLAG_INTERLACE) + dotclock *= 2; + /* Valid dotclock? */ if (dotclock > 0) { /* Convert scanline length in pixels and video dot clock to @@ -605,14 +611,6 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, return -EAGAIN; } - /* Don't know yet how to handle interlaced or - * double scan modes. Just no-op for now. - */ - if (mode->flags & (DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLSCAN)) { - DRM_DEBUG("crtc %d: Noop due to unsupported mode.\n", crtc); - return -ENOTSUPP; - } - /* Get current scanout position with system timestamp. * Repeat query up to DRM_TIMESTAMP_MAXRETRIES times * if single query takes longer than max_error nanoseconds. -- cgit v1.2.3 From 40f2a2fabbeffa4d47c3d904b8c94a0adb07acce Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Sat, 19 Feb 2011 22:35:55 +0100 Subject: drm: drop commented out code and preceding comment r100_gpu_init() was dropped in 90aca4d ("drm/radeon/kms: simplify & improve GPU reset V2") but here it was only commented out. Signed-off-by: Paul Bolle Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r100.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 56deae5bf02e..be817f891ec8 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -3801,8 +3801,6 @@ static int r100_startup(struct radeon_device *rdev) r100_mc_program(rdev); /* Resume clock */ r100_clock_startup(rdev); - /* Initialize GPU configuration (# pipes, ...) */ -// r100_gpu_init(rdev); /* Initialize GART (initialize after TTM so we can allocate * memory through TTM but finalize after TTM) */ r100_enable_bm(rdev); -- cgit v1.2.3 From 45e4039c3aea597ede44a264cea322908cdedfe9 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 20 Feb 2011 21:57:32 +0000 Subject: drm/radeon: fix regression with AA resolve checking Some userspaces can emit a whole packet without disabling AA resolve by the looks of it, so we have to deal with them. Signed-off-by: Dave Airlie Tested-by: Jorg Otte --- drivers/gpu/drm/radeon/r100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index be817f891ec8..93fa735c8c1a 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -3490,7 +3490,7 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track track->num_texture = 16; track->maxy = 4096; track->separate_cube = 0; - track->aaresolve = true; + track->aaresolve = false; track->aa.robj = NULL; } -- cgit v1.2.3 From a6afd9f3e819de4795fcd356e5bfad446e4323f2 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Feb 2011 16:14:56 -0800 Subject: tty: move a number of tty drivers from drivers/char/ to drivers/tty/ As planned by Arnd Bergmann, this moves the following drivers from drivers/char/ to drivers/tty/ as that's where they really belong: amiserial nozomi synclink rocket cyclades moxa mxser isicom bfin_jtag_comm Cc: Arnd Bergmann Cc: Alan Cox Cc: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/char/Kconfig | 172 - drivers/char/Makefile | 11 - drivers/char/amiserial.c | 2178 ----------- drivers/char/bfin_jtag_comm.c | 366 -- drivers/char/cyclades.c | 4200 --------------------- drivers/char/isicom.c | 1736 --------- drivers/char/moxa.c | 2092 ----------- drivers/char/moxa.h | 304 -- drivers/char/mxser.c | 2757 -------------- drivers/char/mxser.h | 150 - drivers/char/nozomi.c | 1993 ---------- drivers/char/rocket.c | 3199 ---------------- drivers/char/rocket.h | 111 - drivers/char/rocket_int.h | 1214 ------ drivers/char/synclink.c | 8119 ----------------------------------------- drivers/char/synclink_gt.c | 5161 -------------------------- drivers/char/synclinkmp.c | 5600 ---------------------------- drivers/tty/Kconfig | 171 + drivers/tty/Makefile | 13 + drivers/tty/amiserial.c | 2178 +++++++++++ drivers/tty/bfin_jtag_comm.c | 366 ++ drivers/tty/cyclades.c | 4200 +++++++++++++++++++++ drivers/tty/isicom.c | 1736 +++++++++ drivers/tty/moxa.c | 2092 +++++++++++ drivers/tty/moxa.h | 304 ++ drivers/tty/mxser.c | 2757 ++++++++++++++ drivers/tty/mxser.h | 150 + drivers/tty/nozomi.c | 1993 ++++++++++ drivers/tty/rocket.c | 3199 ++++++++++++++++ drivers/tty/rocket.h | 111 + drivers/tty/rocket_int.h | 1214 ++++++ drivers/tty/synclink.c | 8119 +++++++++++++++++++++++++++++++++++++++++ drivers/tty/synclink_gt.c | 5161 ++++++++++++++++++++++++++ drivers/tty/synclinkmp.c | 5600 ++++++++++++++++++++++++++++ 34 files changed, 39364 insertions(+), 39363 deletions(-) delete mode 100644 drivers/char/amiserial.c delete mode 100644 drivers/char/bfin_jtag_comm.c delete mode 100644 drivers/char/cyclades.c delete mode 100644 drivers/char/isicom.c delete mode 100644 drivers/char/moxa.c delete mode 100644 drivers/char/moxa.h delete mode 100644 drivers/char/mxser.c delete mode 100644 drivers/char/mxser.h delete mode 100644 drivers/char/nozomi.c delete mode 100644 drivers/char/rocket.c delete mode 100644 drivers/char/rocket.h delete mode 100644 drivers/char/rocket_int.h delete mode 100644 drivers/char/synclink.c delete mode 100644 drivers/char/synclink_gt.c delete mode 100644 drivers/char/synclinkmp.c create mode 100644 drivers/tty/amiserial.c create mode 100644 drivers/tty/bfin_jtag_comm.c create mode 100644 drivers/tty/cyclades.c create mode 100644 drivers/tty/isicom.c create mode 100644 drivers/tty/moxa.c create mode 100644 drivers/tty/moxa.h create mode 100644 drivers/tty/mxser.c create mode 100644 drivers/tty/mxser.h create mode 100644 drivers/tty/nozomi.c create mode 100644 drivers/tty/rocket.c create mode 100644 drivers/tty/rocket.h create mode 100644 drivers/tty/rocket_int.h create mode 100644 drivers/tty/synclink.c create mode 100644 drivers/tty/synclink_gt.c create mode 100644 drivers/tty/synclinkmp.c (limited to 'drivers') diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 9b9ab867f50e..1adfac6a7b0b 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -15,36 +15,6 @@ config DEVKMEM kind of kernel debugging operations. When in doubt, say "N". -config BFIN_JTAG_COMM - tristate "Blackfin JTAG Communication" - depends on BLACKFIN - help - Add support for emulating a TTY device over the Blackfin JTAG. - - To compile this driver as a module, choose M here: the - module will be called bfin_jtag_comm. - -config BFIN_JTAG_COMM_CONSOLE - bool "Console on Blackfin JTAG" - depends on BFIN_JTAG_COMM=y - -config SERIAL_NONSTANDARD - bool "Non-standard serial port support" - depends on HAS_IOMEM - ---help--- - Say Y here if you have any non-standard serial boards -- boards - which aren't supported using the standard "dumb" serial driver. - This includes intelligent serial boards such as Cyclades, - Digiboards, etc. These are usually used for systems that need many - serial ports because they serve many terminals or dial-in - connections. - - Note that the answer to this question won't directly affect the - kernel: saying N will just cause the configurator to skip all - the questions about non-standard serial boards. - - Most people can say N here. - config COMPUTONE tristate "Computone IntelliPort Plus serial support" depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) @@ -60,50 +30,6 @@ config COMPUTONE To compile this driver as module, choose M here: the module will be called ip2. -config ROCKETPORT - tristate "Comtrol RocketPort support" - depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) - help - This driver supports Comtrol RocketPort and RocketModem PCI boards. - These boards provide 2, 4, 8, 16, or 32 high-speed serial ports or - modems. For information about the RocketPort/RocketModem boards - and this driver read . - - To compile this driver as a module, choose M here: the - module will be called rocket. - - If you want to compile this driver into the kernel, say Y here. If - you don't have a Comtrol RocketPort/RocketModem card installed, say N. - -config CYCLADES - tristate "Cyclades async mux support" - depends on SERIAL_NONSTANDARD && (PCI || ISA) - select FW_LOADER - ---help--- - This driver supports Cyclades Z and Y multiserial boards. - You would need something like this to connect more than two modems to - your Linux box, for instance in order to become a dial-in server. - - For information about the Cyclades-Z card, read - . - - To compile this driver as a module, choose M here: the - module will be called cyclades. - - If you haven't heard about it, it's safe to say N. - -config CYZ_INTR - bool "Cyclades-Z interrupt mode operation (EXPERIMENTAL)" - depends on EXPERIMENTAL && CYCLADES - help - The Cyclades-Z family of multiport cards allows 2 (two) driver op - modes: polling and interrupt. In polling mode, the driver will check - the status of the Cyclades-Z ports every certain amount of time - (which is called polling cycle and is configurable). In interrupt - mode, it will use an interrupt line (IRQ) in order to check the - status of the Cyclades-Z ports. The default op mode is polling. If - unsure, say N. - config DIGIEPCA tristate "Digiboard Intelligent Async Support" depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) @@ -119,94 +45,6 @@ config DIGIEPCA To compile this driver as a module, choose M here: the module will be called epca. -config MOXA_INTELLIO - tristate "Moxa Intellio support" - depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) - select FW_LOADER - help - Say Y here if you have a Moxa Intellio multiport serial card. - - To compile this driver as a module, choose M here: the - module will be called moxa. - -config MOXA_SMARTIO - tristate "Moxa SmartIO support v. 2.0" - depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) - help - Say Y here if you have a Moxa SmartIO multiport serial card and/or - want to help develop a new version of this driver. - - This is upgraded (1.9.1) driver from original Moxa drivers with - changes finally resulting in PCI probing. - - This driver can also be built as a module. The module will be called - mxser. If you want to do that, say M here. - -config ISI - tristate "Multi-Tech multiport card support (EXPERIMENTAL)" - depends on SERIAL_NONSTANDARD && PCI - select FW_LOADER - help - This is a driver for the Multi-Tech cards which provide several - serial ports. The driver is experimental and can currently only be - built as a module. The module will be called isicom. - If you want to do that, choose M here. - -config SYNCLINK - tristate "Microgate SyncLink card support" - depends on SERIAL_NONSTANDARD && PCI && ISA_DMA_API - help - Provides support for the SyncLink ISA and PCI multiprotocol serial - adapters. These adapters support asynchronous and HDLC bit - synchronous communication up to 10Mbps (PCI adapter). - - This driver can only be built as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called synclink. If you want to do that, say M - here. - -config SYNCLINKMP - tristate "SyncLink Multiport support" - depends on SERIAL_NONSTANDARD && PCI - help - Enable support for the SyncLink Multiport (2 or 4 ports) - serial adapter, running asynchronous and HDLC communications up - to 2.048Mbps. Each ports is independently selectable for - RS-232, V.35, RS-449, RS-530, and X.21 - - This driver may be built as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called synclinkmp. If you want to do that, say M - here. - -config SYNCLINK_GT - tristate "SyncLink GT/AC support" - depends on SERIAL_NONSTANDARD && PCI - help - Support for SyncLink GT and SyncLink AC families of - synchronous and asynchronous serial adapters - manufactured by Microgate Systems, Ltd. (www.microgate.com) - -config N_HDLC - tristate "HDLC line discipline support" - depends on SERIAL_NONSTANDARD - help - Allows synchronous HDLC communications with tty device drivers that - support synchronous HDLC such as the Microgate SyncLink adapter. - - This driver can be built as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called n_hdlc. If you want to do that, say M - here. - -config N_GSM - tristate "GSM MUX line discipline support (EXPERIMENTAL)" - depends on EXPERIMENTAL - depends on NET - help - This line discipline provides support for the GSM MUX protocol and - presents the mux as a set of 61 individual tty devices. - config RISCOM8 tristate "SDL RISCom/8 card support" depends on SERIAL_NONSTANDARD @@ -296,16 +134,6 @@ config ISTALLION To compile this driver as a module, choose M here: the module will be called istallion. -config NOZOMI - tristate "HSDPA Broadband Wireless Data Card - Globe Trotter" - depends on PCI && EXPERIMENTAL - help - If you have a HSDPA driver Broadband Wireless Data Card - - Globe Trotter PCMCIA card, say Y here. - - To compile this driver as a module, choose M here, the module - will be called nozomi. - config A2232 tristate "Commodore A2232 serial support (EXPERIMENTAL)" depends on EXPERIMENTAL && ZORRO && BROKEN diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 5bc765d4c3ca..f5dc7c9bce6b 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -5,29 +5,18 @@ obj-y += mem.o random.o obj-$(CONFIG_TTY_PRINTK) += ttyprintk.o obj-y += misc.o -obj-$(CONFIG_BFIN_JTAG_COMM) += bfin_jtag_comm.o obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o -obj-$(CONFIG_ROCKETPORT) += rocket.o obj-$(CONFIG_SERIAL167) += serial167.o -obj-$(CONFIG_CYCLADES) += cyclades.o obj-$(CONFIG_STALLION) += stallion.o obj-$(CONFIG_ISTALLION) += istallion.o -obj-$(CONFIG_NOZOMI) += nozomi.o obj-$(CONFIG_DIGIEPCA) += epca.o obj-$(CONFIG_SPECIALIX) += specialix.o -obj-$(CONFIG_MOXA_INTELLIO) += moxa.o obj-$(CONFIG_A2232) += ser_a2232.o generic_serial.o obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o -obj-$(CONFIG_MOXA_SMARTIO) += mxser.o obj-$(CONFIG_COMPUTONE) += ip2/ obj-$(CONFIG_RISCOM8) += riscom8.o -obj-$(CONFIG_ISI) += isicom.o -obj-$(CONFIG_SYNCLINK) += synclink.o -obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o -obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o -obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o obj-$(CONFIG_SX) += sx.o generic_serial.o obj-$(CONFIG_RIO) += rio/ generic_serial.o obj-$(CONFIG_RAW_DRIVER) += raw.o diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c deleted file mode 100644 index f214e5022472..000000000000 --- a/drivers/char/amiserial.c +++ /dev/null @@ -1,2178 +0,0 @@ -/* - * linux/drivers/char/amiserial.c - * - * Serial driver for the amiga builtin port. - * - * This code was created by taking serial.c version 4.30 from kernel - * release 2.3.22, replacing all hardware related stuff with the - * corresponding amiga hardware actions, and removing all irrelevant - * code. As a consequence, it uses many of the constants and names - * associated with the registers and bits of 16550 compatible UARTS - - * but only to keep track of status, etc in the state variables. It - * was done this was to make it easier to keep the code in line with - * (non hardware specific) changes to serial.c. - * - * The port is registered with the tty driver as minor device 64, and - * therefore other ports should should only use 65 upwards. - * - * Richard Lucock 28/12/99 - * - * Copyright (C) 1991, 1992 Linus Torvalds - * Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, - * 1998, 1999 Theodore Ts'o - * - */ - -/* - * Serial driver configuration section. Here are the various options: - * - * SERIAL_PARANOIA_CHECK - * Check the magic number for the async_structure where - * ever possible. - */ - -#include - -#undef SERIAL_PARANOIA_CHECK -#define SERIAL_DO_RESTART - -/* Set of debugging defines */ - -#undef SERIAL_DEBUG_INTR -#undef SERIAL_DEBUG_OPEN -#undef SERIAL_DEBUG_FLOW -#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - -/* Sanity checks */ - -#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) -#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \ - tty->name, (info->flags), serial_driver->refcount,info->count,tty->count,s) -#else -#define DBG_CNT(s) -#endif - -/* - * End of serial driver configuration section. - */ - -#include - -#include -#include -#include -#include -static char *serial_version = "4.30"; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include - -#include -#include - -#define custom amiga_custom -static char *serial_name = "Amiga-builtin serial driver"; - -static struct tty_driver *serial_driver; - -/* number of characters left in xmit buffer before we ask for more */ -#define WAKEUP_CHARS 256 - -static struct async_struct *IRQ_ports; - -static unsigned char current_ctl_bits; - -static void change_speed(struct async_struct *info, struct ktermios *old); -static void rs_wait_until_sent(struct tty_struct *tty, int timeout); - - -static struct serial_state rs_table[1]; - -#define NR_PORTS ARRAY_SIZE(rs_table) - -#include - -#define serial_isroot() (capable(CAP_SYS_ADMIN)) - - -static inline int serial_paranoia_check(struct async_struct *info, - char *name, const char *routine) -{ -#ifdef SERIAL_PARANOIA_CHECK - static const char *badmagic = - "Warning: bad magic number for serial struct (%s) in %s\n"; - static const char *badinfo = - "Warning: null async_struct for (%s) in %s\n"; - - if (!info) { - printk(badinfo, name, routine); - return 1; - } - if (info->magic != SERIAL_MAGIC) { - printk(badmagic, name, routine); - return 1; - } -#endif - return 0; -} - -/* some serial hardware definitions */ -#define SDR_OVRUN (1<<15) -#define SDR_RBF (1<<14) -#define SDR_TBE (1<<13) -#define SDR_TSRE (1<<12) - -#define SERPER_PARENB (1<<15) - -#define AC_SETCLR (1<<15) -#define AC_UARTBRK (1<<11) - -#define SER_DTR (1<<7) -#define SER_RTS (1<<6) -#define SER_DCD (1<<5) -#define SER_CTS (1<<4) -#define SER_DSR (1<<3) - -static __inline__ void rtsdtr_ctrl(int bits) -{ - ciab.pra = ((bits & (SER_RTS | SER_DTR)) ^ (SER_RTS | SER_DTR)) | (ciab.pra & ~(SER_RTS | SER_DTR)); -} - -/* - * ------------------------------------------------------------ - * rs_stop() and rs_start() - * - * This routines are called before setting or resetting tty->stopped. - * They enable or disable transmitter interrupts, as necessary. - * ------------------------------------------------------------ - */ -static void rs_stop(struct tty_struct *tty) -{ - struct async_struct *info = tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_stop")) - return; - - local_irq_save(flags); - if (info->IER & UART_IER_THRI) { - info->IER &= ~UART_IER_THRI; - /* disable Tx interrupt and remove any pending interrupts */ - custom.intena = IF_TBE; - mb(); - custom.intreq = IF_TBE; - mb(); - } - local_irq_restore(flags); -} - -static void rs_start(struct tty_struct *tty) -{ - struct async_struct *info = tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_start")) - return; - - local_irq_save(flags); - if (info->xmit.head != info->xmit.tail - && info->xmit.buf - && !(info->IER & UART_IER_THRI)) { - info->IER |= UART_IER_THRI; - custom.intena = IF_SETCLR | IF_TBE; - mb(); - /* set a pending Tx Interrupt, transmitter should restart now */ - custom.intreq = IF_SETCLR | IF_TBE; - mb(); - } - local_irq_restore(flags); -} - -/* - * ---------------------------------------------------------------------- - * - * Here starts the interrupt handling routines. All of the following - * subroutines are declared as inline and are folded into - * rs_interrupt(). They were separated out for readability's sake. - * - * Note: rs_interrupt() is a "fast" interrupt, which means that it - * runs with interrupts turned off. People who may want to modify - * rs_interrupt() should try to keep the interrupt handler as fast as - * possible. After you are done making modifications, it is not a bad - * idea to do: - * - * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c - * - * and look at the resulting assemble code in serial.s. - * - * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 - * ----------------------------------------------------------------------- - */ - -/* - * This routine is used by the interrupt handler to schedule - * processing in the software interrupt portion of the driver. - */ -static void rs_sched_event(struct async_struct *info, - int event) -{ - info->event |= 1 << event; - tasklet_schedule(&info->tlet); -} - -static void receive_chars(struct async_struct *info) -{ - int status; - int serdatr; - struct tty_struct *tty = info->tty; - unsigned char ch, flag; - struct async_icount *icount; - int oe = 0; - - icount = &info->state->icount; - - status = UART_LSR_DR; /* We obviously have a character! */ - serdatr = custom.serdatr; - mb(); - custom.intreq = IF_RBF; - mb(); - - if((serdatr & 0x1ff) == 0) - status |= UART_LSR_BI; - if(serdatr & SDR_OVRUN) - status |= UART_LSR_OE; - - ch = serdatr & 0xff; - icount->rx++; - -#ifdef SERIAL_DEBUG_INTR - printk("DR%02x:%02x...", ch, status); -#endif - flag = TTY_NORMAL; - - /* - * We don't handle parity or frame errors - but I have left - * the code in, since I'm not sure that the errors can't be - * detected. - */ - - if (status & (UART_LSR_BI | UART_LSR_PE | - UART_LSR_FE | UART_LSR_OE)) { - /* - * For statistics only - */ - if (status & UART_LSR_BI) { - status &= ~(UART_LSR_FE | UART_LSR_PE); - icount->brk++; - } else if (status & UART_LSR_PE) - icount->parity++; - else if (status & UART_LSR_FE) - icount->frame++; - if (status & UART_LSR_OE) - icount->overrun++; - - /* - * Now check to see if character should be - * ignored, and mask off conditions which - * should be ignored. - */ - if (status & info->ignore_status_mask) - goto out; - - status &= info->read_status_mask; - - if (status & (UART_LSR_BI)) { -#ifdef SERIAL_DEBUG_INTR - printk("handling break...."); -#endif - flag = TTY_BREAK; - if (info->flags & ASYNC_SAK) - do_SAK(tty); - } else if (status & UART_LSR_PE) - flag = TTY_PARITY; - else if (status & UART_LSR_FE) - flag = TTY_FRAME; - if (status & UART_LSR_OE) { - /* - * Overrun is special, since it's - * reported immediately, and doesn't - * affect the current character - */ - oe = 1; - } - } - tty_insert_flip_char(tty, ch, flag); - if (oe == 1) - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - tty_flip_buffer_push(tty); -out: - return; -} - -static void transmit_chars(struct async_struct *info) -{ - custom.intreq = IF_TBE; - mb(); - if (info->x_char) { - custom.serdat = info->x_char | 0x100; - mb(); - info->state->icount.tx++; - info->x_char = 0; - return; - } - if (info->xmit.head == info->xmit.tail - || info->tty->stopped - || info->tty->hw_stopped) { - info->IER &= ~UART_IER_THRI; - custom.intena = IF_TBE; - mb(); - return; - } - - custom.serdat = info->xmit.buf[info->xmit.tail++] | 0x100; - mb(); - info->xmit.tail = info->xmit.tail & (SERIAL_XMIT_SIZE-1); - info->state->icount.tx++; - - if (CIRC_CNT(info->xmit.head, - info->xmit.tail, - SERIAL_XMIT_SIZE) < WAKEUP_CHARS) - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); - -#ifdef SERIAL_DEBUG_INTR - printk("THRE..."); -#endif - if (info->xmit.head == info->xmit.tail) { - custom.intena = IF_TBE; - mb(); - info->IER &= ~UART_IER_THRI; - } -} - -static void check_modem_status(struct async_struct *info) -{ - unsigned char status = ciab.pra & (SER_DCD | SER_CTS | SER_DSR); - unsigned char dstatus; - struct async_icount *icount; - - /* Determine bits that have changed */ - dstatus = status ^ current_ctl_bits; - current_ctl_bits = status; - - if (dstatus) { - icount = &info->state->icount; - /* update input line counters */ - if (dstatus & SER_DSR) - icount->dsr++; - if (dstatus & SER_DCD) { - icount->dcd++; -#ifdef CONFIG_HARD_PPS - if ((info->flags & ASYNC_HARDPPS_CD) && - !(status & SER_DCD)) - hardpps(); -#endif - } - if (dstatus & SER_CTS) - icount->cts++; - wake_up_interruptible(&info->delta_msr_wait); - } - - if ((info->flags & ASYNC_CHECK_CD) && (dstatus & SER_DCD)) { -#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) - printk("ttyS%d CD now %s...", info->line, - (!(status & SER_DCD)) ? "on" : "off"); -#endif - if (!(status & SER_DCD)) - wake_up_interruptible(&info->open_wait); - else { -#ifdef SERIAL_DEBUG_OPEN - printk("doing serial hangup..."); -#endif - if (info->tty) - tty_hangup(info->tty); - } - } - if (info->flags & ASYNC_CTS_FLOW) { - if (info->tty->hw_stopped) { - if (!(status & SER_CTS)) { -#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) - printk("CTS tx start..."); -#endif - info->tty->hw_stopped = 0; - info->IER |= UART_IER_THRI; - custom.intena = IF_SETCLR | IF_TBE; - mb(); - /* set a pending Tx Interrupt, transmitter should restart now */ - custom.intreq = IF_SETCLR | IF_TBE; - mb(); - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); - return; - } - } else { - if ((status & SER_CTS)) { -#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) - printk("CTS tx stop..."); -#endif - info->tty->hw_stopped = 1; - info->IER &= ~UART_IER_THRI; - /* disable Tx interrupt and remove any pending interrupts */ - custom.intena = IF_TBE; - mb(); - custom.intreq = IF_TBE; - mb(); - } - } - } -} - -static irqreturn_t ser_vbl_int( int irq, void *data) -{ - /* vbl is just a periodic interrupt we tie into to update modem status */ - struct async_struct * info = IRQ_ports; - /* - * TBD - is it better to unregister from this interrupt or to - * ignore it if MSI is clear ? - */ - if(info->IER & UART_IER_MSI) - check_modem_status(info); - return IRQ_HANDLED; -} - -static irqreturn_t ser_rx_int(int irq, void *dev_id) -{ - struct async_struct * info; - -#ifdef SERIAL_DEBUG_INTR - printk("ser_rx_int..."); -#endif - - info = IRQ_ports; - if (!info || !info->tty) - return IRQ_NONE; - - receive_chars(info); - info->last_active = jiffies; -#ifdef SERIAL_DEBUG_INTR - printk("end.\n"); -#endif - return IRQ_HANDLED; -} - -static irqreturn_t ser_tx_int(int irq, void *dev_id) -{ - struct async_struct * info; - - if (custom.serdatr & SDR_TBE) { -#ifdef SERIAL_DEBUG_INTR - printk("ser_tx_int..."); -#endif - - info = IRQ_ports; - if (!info || !info->tty) - return IRQ_NONE; - - transmit_chars(info); - info->last_active = jiffies; -#ifdef SERIAL_DEBUG_INTR - printk("end.\n"); -#endif - } - return IRQ_HANDLED; -} - -/* - * ------------------------------------------------------------------- - * Here ends the serial interrupt routines. - * ------------------------------------------------------------------- - */ - -/* - * This routine is used to handle the "bottom half" processing for the - * serial driver, known also the "software interrupt" processing. - * This processing is done at the kernel interrupt level, after the - * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This - * is where time-consuming activities which can not be done in the - * interrupt driver proper are done; the interrupt driver schedules - * them using rs_sched_event(), and they get done here. - */ - -static void do_softint(unsigned long private_) -{ - struct async_struct *info = (struct async_struct *) private_; - struct tty_struct *tty; - - tty = info->tty; - if (!tty) - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) - tty_wakeup(tty); -} - -/* - * --------------------------------------------------------------- - * Low level utility subroutines for the serial driver: routines to - * figure out the appropriate timeout for an interrupt chain, routines - * to initialize and startup a serial port, and routines to shutdown a - * serial port. Useful stuff like that. - * --------------------------------------------------------------- - */ - -static int startup(struct async_struct * info) -{ - unsigned long flags; - int retval=0; - unsigned long page; - - page = get_zeroed_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - - local_irq_save(flags); - - if (info->flags & ASYNC_INITIALIZED) { - free_page(page); - goto errout; - } - - if (info->xmit.buf) - free_page(page); - else - info->xmit.buf = (unsigned char *) page; - -#ifdef SERIAL_DEBUG_OPEN - printk("starting up ttys%d ...", info->line); -#endif - - /* Clear anything in the input buffer */ - - custom.intreq = IF_RBF; - mb(); - - retval = request_irq(IRQ_AMIGA_VERTB, ser_vbl_int, 0, "serial status", info); - if (retval) { - if (serial_isroot()) { - if (info->tty) - set_bit(TTY_IO_ERROR, - &info->tty->flags); - retval = 0; - } - goto errout; - } - - /* enable both Rx and Tx interrupts */ - custom.intena = IF_SETCLR | IF_RBF | IF_TBE; - mb(); - info->IER = UART_IER_MSI; - - /* remember current state of the DCD and CTS bits */ - current_ctl_bits = ciab.pra & (SER_DCD | SER_CTS | SER_DSR); - - IRQ_ports = info; - - info->MCR = 0; - if (info->tty->termios->c_cflag & CBAUD) - info->MCR = SER_DTR | SER_RTS; - rtsdtr_ctrl(info->MCR); - - if (info->tty) - clear_bit(TTY_IO_ERROR, &info->tty->flags); - info->xmit.head = info->xmit.tail = 0; - - /* - * Set up the tty->alt_speed kludge - */ - if (info->tty) { - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - info->tty->alt_speed = 57600; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - info->tty->alt_speed = 115200; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - info->tty->alt_speed = 230400; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - info->tty->alt_speed = 460800; - } - - /* - * and set the speed of the serial port - */ - change_speed(info, NULL); - - info->flags |= ASYNC_INITIALIZED; - local_irq_restore(flags); - return 0; - -errout: - local_irq_restore(flags); - return retval; -} - -/* - * This routine will shutdown a serial port; interrupts are disabled, and - * DTR is dropped if the hangup on close termio flag is on. - */ -static void shutdown(struct async_struct * info) -{ - unsigned long flags; - struct serial_state *state; - - if (!(info->flags & ASYNC_INITIALIZED)) - return; - - state = info->state; - -#ifdef SERIAL_DEBUG_OPEN - printk("Shutting down serial port %d ....\n", info->line); -#endif - - local_irq_save(flags); /* Disable interrupts */ - - /* - * clear delta_msr_wait queue to avoid mem leaks: we may free the irq - * here so the queue might never be waken up - */ - wake_up_interruptible(&info->delta_msr_wait); - - IRQ_ports = NULL; - - /* - * Free the IRQ, if necessary - */ - free_irq(IRQ_AMIGA_VERTB, info); - - if (info->xmit.buf) { - free_page((unsigned long) info->xmit.buf); - info->xmit.buf = NULL; - } - - info->IER = 0; - custom.intena = IF_RBF | IF_TBE; - mb(); - - /* disable break condition */ - custom.adkcon = AC_UARTBRK; - mb(); - - if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) - info->MCR &= ~(SER_DTR|SER_RTS); - rtsdtr_ctrl(info->MCR); - - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - - info->flags &= ~ASYNC_INITIALIZED; - local_irq_restore(flags); -} - - -/* - * This routine is called to set the UART divisor registers to match - * the specified baud rate for a serial port. - */ -static void change_speed(struct async_struct *info, - struct ktermios *old_termios) -{ - int quot = 0, baud_base, baud; - unsigned cflag, cval = 0; - int bits; - unsigned long flags; - - if (!info->tty || !info->tty->termios) - return; - cflag = info->tty->termios->c_cflag; - - /* Byte size is always 8 bits plus parity bit if requested */ - - cval = 3; bits = 10; - if (cflag & CSTOPB) { - cval |= 0x04; - bits++; - } - if (cflag & PARENB) { - cval |= UART_LCR_PARITY; - bits++; - } - if (!(cflag & PARODD)) - cval |= UART_LCR_EPAR; -#ifdef CMSPAR - if (cflag & CMSPAR) - cval |= UART_LCR_SPAR; -#endif - - /* Determine divisor based on baud rate */ - baud = tty_get_baud_rate(info->tty); - if (!baud) - baud = 9600; /* B0 transition handled in rs_set_termios */ - baud_base = info->state->baud_base; - if (baud == 38400 && - ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) - quot = info->state->custom_divisor; - else { - if (baud == 134) - /* Special case since 134 is really 134.5 */ - quot = (2*baud_base / 269); - else if (baud) - quot = baud_base / baud; - } - /* If the quotient is zero refuse the change */ - if (!quot && old_termios) { - /* FIXME: Will need updating for new tty in the end */ - info->tty->termios->c_cflag &= ~CBAUD; - info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD); - baud = tty_get_baud_rate(info->tty); - if (!baud) - baud = 9600; - if (baud == 38400 && - ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) - quot = info->state->custom_divisor; - else { - if (baud == 134) - /* Special case since 134 is really 134.5 */ - quot = (2*baud_base / 269); - else if (baud) - quot = baud_base / baud; - } - } - /* As a last resort, if the quotient is zero, default to 9600 bps */ - if (!quot) - quot = baud_base / 9600; - info->quot = quot; - info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base); - info->timeout += HZ/50; /* Add .02 seconds of slop */ - - /* CTS flow control flag and modem status interrupts */ - info->IER &= ~UART_IER_MSI; - if (info->flags & ASYNC_HARDPPS_CD) - info->IER |= UART_IER_MSI; - if (cflag & CRTSCTS) { - info->flags |= ASYNC_CTS_FLOW; - info->IER |= UART_IER_MSI; - } else - info->flags &= ~ASYNC_CTS_FLOW; - if (cflag & CLOCAL) - info->flags &= ~ASYNC_CHECK_CD; - else { - info->flags |= ASYNC_CHECK_CD; - info->IER |= UART_IER_MSI; - } - /* TBD: - * Does clearing IER_MSI imply that we should disable the VBL interrupt ? - */ - - /* - * Set up parity check flag - */ - - info->read_status_mask = UART_LSR_OE | UART_LSR_DR; - if (I_INPCK(info->tty)) - info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; - if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) - info->read_status_mask |= UART_LSR_BI; - - /* - * Characters to ignore - */ - info->ignore_status_mask = 0; - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; - if (I_IGNBRK(info->tty)) { - info->ignore_status_mask |= UART_LSR_BI; - /* - * If we're ignore parity and break indicators, ignore - * overruns too. (For real raw support). - */ - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= UART_LSR_OE; - } - /* - * !!! ignore all characters if CREAD is not set - */ - if ((cflag & CREAD) == 0) - info->ignore_status_mask |= UART_LSR_DR; - local_irq_save(flags); - - { - short serper; - - /* Set up the baud rate */ - serper = quot - 1; - - /* Enable or disable parity bit */ - - if(cval & UART_LCR_PARITY) - serper |= (SERPER_PARENB); - - custom.serper = serper; - mb(); - } - - info->LCR = cval; /* Save LCR */ - local_irq_restore(flags); -} - -static int rs_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct async_struct *info; - unsigned long flags; - - info = tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_put_char")) - return 0; - - if (!info->xmit.buf) - return 0; - - local_irq_save(flags); - if (CIRC_SPACE(info->xmit.head, - info->xmit.tail, - SERIAL_XMIT_SIZE) == 0) { - local_irq_restore(flags); - return 0; - } - - info->xmit.buf[info->xmit.head++] = ch; - info->xmit.head &= SERIAL_XMIT_SIZE-1; - local_irq_restore(flags); - return 1; -} - -static void rs_flush_chars(struct tty_struct *tty) -{ - struct async_struct *info = tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_flush_chars")) - return; - - if (info->xmit.head == info->xmit.tail - || tty->stopped - || tty->hw_stopped - || !info->xmit.buf) - return; - - local_irq_save(flags); - info->IER |= UART_IER_THRI; - custom.intena = IF_SETCLR | IF_TBE; - mb(); - /* set a pending Tx Interrupt, transmitter should restart now */ - custom.intreq = IF_SETCLR | IF_TBE; - mb(); - local_irq_restore(flags); -} - -static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count) -{ - int c, ret = 0; - struct async_struct *info; - unsigned long flags; - - info = tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_write")) - return 0; - - if (!info->xmit.buf) - return 0; - - local_irq_save(flags); - while (1) { - c = CIRC_SPACE_TO_END(info->xmit.head, - info->xmit.tail, - SERIAL_XMIT_SIZE); - if (count < c) - c = count; - if (c <= 0) { - break; - } - memcpy(info->xmit.buf + info->xmit.head, buf, c); - info->xmit.head = ((info->xmit.head + c) & - (SERIAL_XMIT_SIZE-1)); - buf += c; - count -= c; - ret += c; - } - local_irq_restore(flags); - - if (info->xmit.head != info->xmit.tail - && !tty->stopped - && !tty->hw_stopped - && !(info->IER & UART_IER_THRI)) { - info->IER |= UART_IER_THRI; - local_irq_disable(); - custom.intena = IF_SETCLR | IF_TBE; - mb(); - /* set a pending Tx Interrupt, transmitter should restart now */ - custom.intreq = IF_SETCLR | IF_TBE; - mb(); - local_irq_restore(flags); - } - return ret; -} - -static int rs_write_room(struct tty_struct *tty) -{ - struct async_struct *info = tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_write_room")) - return 0; - return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); -} - -static int rs_chars_in_buffer(struct tty_struct *tty) -{ - struct async_struct *info = tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer")) - return 0; - return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); -} - -static void rs_flush_buffer(struct tty_struct *tty) -{ - struct async_struct *info = tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) - return; - local_irq_save(flags); - info->xmit.head = info->xmit.tail = 0; - local_irq_restore(flags); - tty_wakeup(tty); -} - -/* - * This function is used to send a high-priority XON/XOFF character to - * the device - */ -static void rs_send_xchar(struct tty_struct *tty, char ch) -{ - struct async_struct *info = tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_send_char")) - return; - - info->x_char = ch; - if (ch) { - /* Make sure transmit interrupts are on */ - - /* Check this ! */ - local_irq_save(flags); - if(!(custom.intenar & IF_TBE)) { - custom.intena = IF_SETCLR | IF_TBE; - mb(); - /* set a pending Tx Interrupt, transmitter should restart now */ - custom.intreq = IF_SETCLR | IF_TBE; - mb(); - } - local_irq_restore(flags); - - info->IER |= UART_IER_THRI; - } -} - -/* - * ------------------------------------------------------------ - * rs_throttle() - * - * This routine is called by the upper-layer tty layer to signal that - * incoming characters should be throttled. - * ------------------------------------------------------------ - */ -static void rs_throttle(struct tty_struct * tty) -{ - struct async_struct *info = tty->driver_data; - unsigned long flags; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("throttle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->name, "rs_throttle")) - return; - - if (I_IXOFF(tty)) - rs_send_xchar(tty, STOP_CHAR(tty)); - - if (tty->termios->c_cflag & CRTSCTS) - info->MCR &= ~SER_RTS; - - local_irq_save(flags); - rtsdtr_ctrl(info->MCR); - local_irq_restore(flags); -} - -static void rs_unthrottle(struct tty_struct * tty) -{ - struct async_struct *info = tty->driver_data; - unsigned long flags; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("unthrottle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->name, "rs_unthrottle")) - return; - - if (I_IXOFF(tty)) { - if (info->x_char) - info->x_char = 0; - else - rs_send_xchar(tty, START_CHAR(tty)); - } - if (tty->termios->c_cflag & CRTSCTS) - info->MCR |= SER_RTS; - local_irq_save(flags); - rtsdtr_ctrl(info->MCR); - local_irq_restore(flags); -} - -/* - * ------------------------------------------------------------ - * rs_ioctl() and friends - * ------------------------------------------------------------ - */ - -static int get_serial_info(struct async_struct * info, - struct serial_struct __user * retinfo) -{ - struct serial_struct tmp; - struct serial_state *state = info->state; - - if (!retinfo) - return -EFAULT; - memset(&tmp, 0, sizeof(tmp)); - tty_lock(); - tmp.type = state->type; - tmp.line = state->line; - tmp.port = state->port; - tmp.irq = state->irq; - tmp.flags = state->flags; - tmp.xmit_fifo_size = state->xmit_fifo_size; - tmp.baud_base = state->baud_base; - tmp.close_delay = state->close_delay; - tmp.closing_wait = state->closing_wait; - tmp.custom_divisor = state->custom_divisor; - tty_unlock(); - if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int set_serial_info(struct async_struct * info, - struct serial_struct __user * new_info) -{ - struct serial_struct new_serial; - struct serial_state old_state, *state; - unsigned int change_irq,change_port; - int retval = 0; - - if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) - return -EFAULT; - - tty_lock(); - state = info->state; - old_state = *state; - - change_irq = new_serial.irq != state->irq; - change_port = (new_serial.port != state->port); - if(change_irq || change_port || (new_serial.xmit_fifo_size != state->xmit_fifo_size)) { - tty_unlock(); - return -EINVAL; - } - - if (!serial_isroot()) { - if ((new_serial.baud_base != state->baud_base) || - (new_serial.close_delay != state->close_delay) || - (new_serial.xmit_fifo_size != state->xmit_fifo_size) || - ((new_serial.flags & ~ASYNC_USR_MASK) != - (state->flags & ~ASYNC_USR_MASK))) - return -EPERM; - state->flags = ((state->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - info->flags = ((info->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - state->custom_divisor = new_serial.custom_divisor; - goto check_and_exit; - } - - if (new_serial.baud_base < 9600) { - tty_unlock(); - return -EINVAL; - } - - /* - * OK, past this point, all the error checking has been done. - * At this point, we start making changes..... - */ - - state->baud_base = new_serial.baud_base; - state->flags = ((state->flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS)); - info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | - (info->flags & ASYNC_INTERNAL_FLAGS)); - state->custom_divisor = new_serial.custom_divisor; - state->close_delay = new_serial.close_delay * HZ/100; - state->closing_wait = new_serial.closing_wait * HZ/100; - info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - -check_and_exit: - if (info->flags & ASYNC_INITIALIZED) { - if (((old_state.flags & ASYNC_SPD_MASK) != - (state->flags & ASYNC_SPD_MASK)) || - (old_state.custom_divisor != state->custom_divisor)) { - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - info->tty->alt_speed = 57600; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - info->tty->alt_speed = 115200; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - info->tty->alt_speed = 230400; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - info->tty->alt_speed = 460800; - change_speed(info, NULL); - } - } else - retval = startup(info); - tty_unlock(); - return retval; -} - - -/* - * get_lsr_info - get line status register info - * - * Purpose: Let user call ioctl() to get info when the UART physically - * is emptied. On bus types like RS485, the transmitter must - * release the bus after transmitting. This must be done when - * the transmit shift register is empty, not be done when the - * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. - */ -static int get_lsr_info(struct async_struct * info, unsigned int __user *value) -{ - unsigned char status; - unsigned int result; - unsigned long flags; - - local_irq_save(flags); - status = custom.serdatr; - mb(); - local_irq_restore(flags); - result = ((status & SDR_TSRE) ? TIOCSER_TEMT : 0); - if (copy_to_user(value, &result, sizeof(int))) - return -EFAULT; - return 0; -} - - -static int rs_tiocmget(struct tty_struct *tty) -{ - struct async_struct * info = tty->driver_data; - unsigned char control, status; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_ioctl")) - return -ENODEV; - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - - control = info->MCR; - local_irq_save(flags); - status = ciab.pra; - local_irq_restore(flags); - return ((control & SER_RTS) ? TIOCM_RTS : 0) - | ((control & SER_DTR) ? TIOCM_DTR : 0) - | (!(status & SER_DCD) ? TIOCM_CAR : 0) - | (!(status & SER_DSR) ? TIOCM_DSR : 0) - | (!(status & SER_CTS) ? TIOCM_CTS : 0); -} - -static int rs_tiocmset(struct tty_struct *tty, unsigned int set, - unsigned int clear) -{ - struct async_struct * info = tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_ioctl")) - return -ENODEV; - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - - local_irq_save(flags); - if (set & TIOCM_RTS) - info->MCR |= SER_RTS; - if (set & TIOCM_DTR) - info->MCR |= SER_DTR; - if (clear & TIOCM_RTS) - info->MCR &= ~SER_RTS; - if (clear & TIOCM_DTR) - info->MCR &= ~SER_DTR; - rtsdtr_ctrl(info->MCR); - local_irq_restore(flags); - return 0; -} - -/* - * rs_break() --- routine which turns the break handling on or off - */ -static int rs_break(struct tty_struct *tty, int break_state) -{ - struct async_struct * info = tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_break")) - return -EINVAL; - - local_irq_save(flags); - if (break_state == -1) - custom.adkcon = AC_SETCLR | AC_UARTBRK; - else - custom.adkcon = AC_UARTBRK; - mb(); - local_irq_restore(flags); - return 0; -} - -/* - * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) - * Return: write counters to the user passed counter struct - * NB: both 1->0 and 0->1 transitions are counted except for - * RI where only 0->1 is counted. - */ -static int rs_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct async_struct *info = tty->driver_data; - struct async_icount cnow; - unsigned long flags; - - local_irq_save(flags); - cnow = info->state->icount; - local_irq_restore(flags); - icount->cts = cnow.cts; - icount->dsr = cnow.dsr; - icount->rng = cnow.rng; - icount->dcd = cnow.dcd; - icount->rx = cnow.rx; - icount->tx = cnow.tx; - icount->frame = cnow.frame; - icount->overrun = cnow.overrun; - icount->parity = cnow.parity; - icount->brk = cnow.brk; - icount->buf_overrun = cnow.buf_overrun; - - return 0; -} - -static int rs_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct async_struct * info = tty->driver_data; - struct async_icount cprev, cnow; /* kernel counter temps */ - void __user *argp = (void __user *)arg; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_ioctl")) - return -ENODEV; - - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && - (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - } - - switch (cmd) { - case TIOCGSERIAL: - return get_serial_info(info, argp); - case TIOCSSERIAL: - return set_serial_info(info, argp); - case TIOCSERCONFIG: - return 0; - - case TIOCSERGETLSR: /* Get line status register */ - return get_lsr_info(info, argp); - - case TIOCSERGSTRUCT: - if (copy_to_user(argp, - info, sizeof(struct async_struct))) - return -EFAULT; - return 0; - - /* - * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - * - mask passed in arg for lines of interest - * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) - * Caller should use TIOCGICOUNT to see which one it was - */ - case TIOCMIWAIT: - local_irq_save(flags); - /* note the counters on entry */ - cprev = info->state->icount; - local_irq_restore(flags); - while (1) { - interruptible_sleep_on(&info->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - local_irq_save(flags); - cnow = info->state->icount; /* atomic copy */ - local_irq_restore(flags); - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) - return -EIO; /* no change => error */ - if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { - return 0; - } - cprev = cnow; - } - /* NOTREACHED */ - - case TIOCSERGWILD: - case TIOCSERSWILD: - /* "setserial -W" is called in Debian boot */ - printk ("TIOCSER?WILD ioctl obsolete, ignored.\n"); - return 0; - - default: - return -ENOIOCTLCMD; - } - return 0; -} - -static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) -{ - struct async_struct *info = tty->driver_data; - unsigned long flags; - unsigned int cflag = tty->termios->c_cflag; - - change_speed(info, old_termios); - - /* Handle transition to B0 status */ - if ((old_termios->c_cflag & CBAUD) && - !(cflag & CBAUD)) { - info->MCR &= ~(SER_DTR|SER_RTS); - local_irq_save(flags); - rtsdtr_ctrl(info->MCR); - local_irq_restore(flags); - } - - /* Handle transition away from B0 status */ - if (!(old_termios->c_cflag & CBAUD) && - (cflag & CBAUD)) { - info->MCR |= SER_DTR; - if (!(tty->termios->c_cflag & CRTSCTS) || - !test_bit(TTY_THROTTLED, &tty->flags)) { - info->MCR |= SER_RTS; - } - local_irq_save(flags); - rtsdtr_ctrl(info->MCR); - local_irq_restore(flags); - } - - /* Handle turning off CRTSCTS */ - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - rs_start(tty); - } - -#if 0 - /* - * No need to wake up processes in open wait, since they - * sample the CLOCAL flag once, and don't recheck it. - * XXX It's not clear whether the current behavior is correct - * or not. Hence, this may change..... - */ - if (!(old_termios->c_cflag & CLOCAL) && - (tty->termios->c_cflag & CLOCAL)) - wake_up_interruptible(&info->open_wait); -#endif -} - -/* - * ------------------------------------------------------------ - * rs_close() - * - * This routine is called when the serial port gets closed. First, we - * wait for the last remaining data to be sent. Then, we unlink its - * async structure from the interrupt chain if necessary, and we free - * that IRQ if nothing is left in the chain. - * ------------------------------------------------------------ - */ -static void rs_close(struct tty_struct *tty, struct file * filp) -{ - struct async_struct * info = tty->driver_data; - struct serial_state *state; - unsigned long flags; - - if (!info || serial_paranoia_check(info, tty->name, "rs_close")) - return; - - state = info->state; - - local_irq_save(flags); - - if (tty_hung_up_p(filp)) { - DBG_CNT("before DEC-hung"); - local_irq_restore(flags); - return; - } - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_close ttys%d, count = %d\n", info->line, state->count); -#endif - if ((tty->count == 1) && (state->count != 1)) { - /* - * Uh, oh. tty->count is 1, which means that the tty - * structure will be freed. state->count should always - * be one in these conditions. If it's greater than - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ - printk("rs_close: bad serial port count; tty->count is 1, " - "state->count is %d\n", state->count); - state->count = 1; - } - if (--state->count < 0) { - printk("rs_close: bad serial port count for ttys%d: %d\n", - info->line, state->count); - state->count = 0; - } - if (state->count) { - DBG_CNT("before DEC-2"); - local_irq_restore(flags); - return; - } - info->flags |= ASYNC_CLOSING; - /* - * Now we wait for the transmit buffer to clear; and we notify - * the line discipline to only process XON/XOFF characters. - */ - tty->closing = 1; - if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) - tty_wait_until_sent(tty, info->closing_wait); - /* - * At this point we stop accepting input. To do this, we - * disable the receive line status interrupts, and tell the - * interrupt driver to stop checking the data ready bit in the - * line status register. - */ - info->read_status_mask &= ~UART_LSR_DR; - if (info->flags & ASYNC_INITIALIZED) { - /* disable receive interrupts */ - custom.intena = IF_RBF; - mb(); - /* clear any pending receive interrupt */ - custom.intreq = IF_RBF; - mb(); - - /* - * Before we drop DTR, make sure the UART transmitter - * has completely drained; this is especially - * important if there is a transmit FIFO! - */ - rs_wait_until_sent(tty, info->timeout); - } - shutdown(info); - rs_flush_buffer(tty); - - tty_ldisc_flush(tty); - tty->closing = 0; - info->event = 0; - info->tty = NULL; - if (info->blocked_open) { - if (info->close_delay) { - msleep_interruptible(jiffies_to_msecs(info->close_delay)); - } - wake_up_interruptible(&info->open_wait); - } - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); - wake_up_interruptible(&info->close_wait); - local_irq_restore(flags); -} - -/* - * rs_wait_until_sent() --- wait until the transmitter is empty - */ -static void rs_wait_until_sent(struct tty_struct *tty, int timeout) -{ - struct async_struct * info = tty->driver_data; - unsigned long orig_jiffies, char_time; - int tty_was_locked = tty_locked(); - int lsr; - - if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent")) - return; - - if (info->xmit_fifo_size == 0) - return; /* Just in case.... */ - - orig_jiffies = jiffies; - - /* - * tty_wait_until_sent is called from lots of places, - * with or without the BTM. - */ - if (!tty_was_locked) - tty_lock(); - /* - * Set the check interval to be 1/5 of the estimated time to - * send a single character, and make it at least 1. The check - * interval should also be less than the timeout. - * - * Note: we have to use pretty tight timings here to satisfy - * the NIST-PCTS. - */ - char_time = (info->timeout - HZ/50) / info->xmit_fifo_size; - char_time = char_time / 5; - if (char_time == 0) - char_time = 1; - if (timeout) - char_time = min_t(unsigned long, char_time, timeout); - /* - * If the transmitter hasn't cleared in twice the approximate - * amount of time to send the entire FIFO, it probably won't - * ever clear. This assumes the UART isn't doing flow - * control, which is currently the case. Hence, if it ever - * takes longer than info->timeout, this is probably due to a - * UART bug of some kind. So, we clamp the timeout parameter at - * 2*info->timeout. - */ - if (!timeout || timeout > 2*info->timeout) - timeout = 2*info->timeout; -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time); - printk("jiff=%lu...", jiffies); -#endif - while(!((lsr = custom.serdatr) & SDR_TSRE)) { -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("serdatr = %d (jiff=%lu)...", lsr, jiffies); -#endif - msleep_interruptible(jiffies_to_msecs(char_time)); - if (signal_pending(current)) - break; - if (timeout && time_after(jiffies, orig_jiffies + timeout)) - break; - } - __set_current_state(TASK_RUNNING); - if (!tty_was_locked) - tty_unlock(); -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); -#endif -} - -/* - * rs_hangup() --- called by tty_hangup() when a hangup is signaled. - */ -static void rs_hangup(struct tty_struct *tty) -{ - struct async_struct * info = tty->driver_data; - struct serial_state *state = info->state; - - if (serial_paranoia_check(info, tty->name, "rs_hangup")) - return; - - state = info->state; - - rs_flush_buffer(tty); - shutdown(info); - info->event = 0; - state->count = 0; - info->flags &= ~ASYNC_NORMAL_ACTIVE; - info->tty = NULL; - wake_up_interruptible(&info->open_wait); -} - -/* - * ------------------------------------------------------------ - * rs_open() and friends - * ------------------------------------------------------------ - */ -static int block_til_ready(struct tty_struct *tty, struct file * filp, - struct async_struct *info) -{ -#ifdef DECLARE_WAITQUEUE - DECLARE_WAITQUEUE(wait, current); -#else - struct wait_queue wait = { current, NULL }; -#endif - struct serial_state *state = info->state; - int retval; - int do_clocal = 0, extra_count = 0; - unsigned long flags; - - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); -#ifdef SERIAL_DO_RESTART - return ((info->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); -#else - return -EAGAIN; -#endif - } - - /* - * If non-blocking mode is set, or the port is not enabled, - * then make the check up front and then exit. - */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR))) { - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - if (tty->termios->c_cflag & CLOCAL) - do_clocal = 1; - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, state->count is dropped by one, so that - * rs_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; - add_wait_queue(&info->open_wait, &wait); -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready before block: ttys%d, count = %d\n", - state->line, state->count); -#endif - local_irq_save(flags); - if (!tty_hung_up_p(filp)) { - extra_count = 1; - state->count--; - } - local_irq_restore(flags); - info->blocked_open++; - while (1) { - local_irq_save(flags); - if (tty->termios->c_cflag & CBAUD) - rtsdtr_ctrl(SER_DTR|SER_RTS); - local_irq_restore(flags); - set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !(info->flags & ASYNC_INITIALIZED)) { -#ifdef SERIAL_DO_RESTART - if (info->flags & ASYNC_HUP_NOTIFY) - retval = -EAGAIN; - else - retval = -ERESTARTSYS; -#else - retval = -EAGAIN; -#endif - break; - } - if (!(info->flags & ASYNC_CLOSING) && - (do_clocal || (!(ciab.pra & SER_DCD)) )) - break; - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif - tty_unlock(); - schedule(); - tty_lock(); - } - __set_current_state(TASK_RUNNING); - remove_wait_queue(&info->open_wait, &wait); - if (extra_count) - state->count++; - info->blocked_open--; -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready after blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif - if (retval) - return retval; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; -} - -static int get_async_struct(int line, struct async_struct **ret_info) -{ - struct async_struct *info; - struct serial_state *sstate; - - sstate = rs_table + line; - sstate->count++; - if (sstate->info) { - *ret_info = sstate->info; - return 0; - } - info = kzalloc(sizeof(struct async_struct), GFP_KERNEL); - if (!info) { - sstate->count--; - return -ENOMEM; - } -#ifdef DECLARE_WAITQUEUE - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - init_waitqueue_head(&info->delta_msr_wait); -#endif - info->magic = SERIAL_MAGIC; - info->port = sstate->port; - info->flags = sstate->flags; - info->xmit_fifo_size = sstate->xmit_fifo_size; - info->line = line; - tasklet_init(&info->tlet, do_softint, (unsigned long)info); - info->state = sstate; - if (sstate->info) { - kfree(info); - *ret_info = sstate->info; - return 0; - } - *ret_info = sstate->info = info; - return 0; -} - -/* - * This routine is called whenever a serial port is opened. It - * enables interrupts for a serial port, linking in its async structure into - * the IRQ chain. It also performs the serial-specific - * initialization for the tty structure. - */ -static int rs_open(struct tty_struct *tty, struct file * filp) -{ - struct async_struct *info; - int retval, line; - - line = tty->index; - if ((line < 0) || (line >= NR_PORTS)) { - return -ENODEV; - } - retval = get_async_struct(line, &info); - if (retval) { - return retval; - } - tty->driver_data = info; - info->tty = tty; - if (serial_paranoia_check(info, tty->name, "rs_open")) - return -ENODEV; - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open %s, count = %d\n", tty->name, info->state->count); -#endif - info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - - /* - * If the port is the middle of closing, bail out now - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); -#ifdef SERIAL_DO_RESTART - return ((info->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); -#else - return -EAGAIN; -#endif - } - - /* - * Start up serial port - */ - retval = startup(info); - if (retval) { - return retval; - } - - retval = block_til_ready(tty, filp, info); - if (retval) { -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open returning after block_til_ready with %d\n", - retval); -#endif - return retval; - } - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open %s successful...", tty->name); -#endif - return 0; -} - -/* - * /proc fs routines.... - */ - -static inline void line_info(struct seq_file *m, struct serial_state *state) -{ - struct async_struct *info = state->info, scr_info; - char stat_buf[30], control, status; - unsigned long flags; - - seq_printf(m, "%d: uart:amiga_builtin",state->line); - - /* - * Figure out the current RS-232 lines - */ - if (!info) { - info = &scr_info; /* This is just for serial_{in,out} */ - - info->magic = SERIAL_MAGIC; - info->flags = state->flags; - info->quot = 0; - info->tty = NULL; - } - local_irq_save(flags); - status = ciab.pra; - control = info ? info->MCR : status; - local_irq_restore(flags); - - stat_buf[0] = 0; - stat_buf[1] = 0; - if(!(control & SER_RTS)) - strcat(stat_buf, "|RTS"); - if(!(status & SER_CTS)) - strcat(stat_buf, "|CTS"); - if(!(control & SER_DTR)) - strcat(stat_buf, "|DTR"); - if(!(status & SER_DSR)) - strcat(stat_buf, "|DSR"); - if(!(status & SER_DCD)) - strcat(stat_buf, "|CD"); - - if (info->quot) { - seq_printf(m, " baud:%d", state->baud_base / info->quot); - } - - seq_printf(m, " tx:%d rx:%d", state->icount.tx, state->icount.rx); - - if (state->icount.frame) - seq_printf(m, " fe:%d", state->icount.frame); - - if (state->icount.parity) - seq_printf(m, " pe:%d", state->icount.parity); - - if (state->icount.brk) - seq_printf(m, " brk:%d", state->icount.brk); - - if (state->icount.overrun) - seq_printf(m, " oe:%d", state->icount.overrun); - - /* - * Last thing is the RS-232 status lines - */ - seq_printf(m, " %s\n", stat_buf+1); -} - -static int rs_proc_show(struct seq_file *m, void *v) -{ - seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version); - line_info(m, &rs_table[0]); - return 0; -} - -static int rs_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, rs_proc_show, NULL); -} - -static const struct file_operations rs_proc_fops = { - .owner = THIS_MODULE, - .open = rs_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/* - * --------------------------------------------------------------------- - * rs_init() and friends - * - * rs_init() is called at boot-time to initialize the serial driver. - * --------------------------------------------------------------------- - */ - -/* - * This routine prints out the appropriate serial driver version - * number, and identifies which options were configured into this - * driver. - */ -static void show_serial_version(void) -{ - printk(KERN_INFO "%s version %s\n", serial_name, serial_version); -} - - -static const struct tty_operations serial_ops = { - .open = rs_open, - .close = rs_close, - .write = rs_write, - .put_char = rs_put_char, - .flush_chars = rs_flush_chars, - .write_room = rs_write_room, - .chars_in_buffer = rs_chars_in_buffer, - .flush_buffer = rs_flush_buffer, - .ioctl = rs_ioctl, - .throttle = rs_throttle, - .unthrottle = rs_unthrottle, - .set_termios = rs_set_termios, - .stop = rs_stop, - .start = rs_start, - .hangup = rs_hangup, - .break_ctl = rs_break, - .send_xchar = rs_send_xchar, - .wait_until_sent = rs_wait_until_sent, - .tiocmget = rs_tiocmget, - .tiocmset = rs_tiocmset, - .get_icount = rs_get_icount, - .proc_fops = &rs_proc_fops, -}; - -/* - * The serial driver boot-time initialization code! - */ -static int __init amiga_serial_probe(struct platform_device *pdev) -{ - unsigned long flags; - struct serial_state * state; - int error; - - serial_driver = alloc_tty_driver(1); - if (!serial_driver) - return -ENOMEM; - - IRQ_ports = NULL; - - show_serial_version(); - - /* Initialize the tty_driver structure */ - - serial_driver->owner = THIS_MODULE; - serial_driver->driver_name = "amiserial"; - serial_driver->name = "ttyS"; - serial_driver->major = TTY_MAJOR; - serial_driver->minor_start = 64; - serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - serial_driver->subtype = SERIAL_TYPE_NORMAL; - serial_driver->init_termios = tty_std_termios; - serial_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - serial_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(serial_driver, &serial_ops); - - error = tty_register_driver(serial_driver); - if (error) - goto fail_put_tty_driver; - - state = rs_table; - state->magic = SSTATE_MAGIC; - state->port = (int)&custom.serdatr; /* Just to give it a value */ - state->line = 0; - state->custom_divisor = 0; - state->close_delay = 5*HZ/10; - state->closing_wait = 30*HZ; - state->icount.cts = state->icount.dsr = - state->icount.rng = state->icount.dcd = 0; - state->icount.rx = state->icount.tx = 0; - state->icount.frame = state->icount.parity = 0; - state->icount.overrun = state->icount.brk = 0; - - printk(KERN_INFO "ttyS%d is the amiga builtin serial port\n", - state->line); - - /* Hardware set up */ - - state->baud_base = amiga_colorclock; - state->xmit_fifo_size = 1; - - /* set ISRs, and then disable the rx interrupts */ - error = request_irq(IRQ_AMIGA_TBE, ser_tx_int, 0, "serial TX", state); - if (error) - goto fail_unregister; - - error = request_irq(IRQ_AMIGA_RBF, ser_rx_int, IRQF_DISABLED, - "serial RX", state); - if (error) - goto fail_free_irq; - - local_irq_save(flags); - - /* turn off Rx and Tx interrupts */ - custom.intena = IF_RBF | IF_TBE; - mb(); - - /* clear any pending interrupt */ - custom.intreq = IF_RBF | IF_TBE; - mb(); - - local_irq_restore(flags); - - /* - * set the appropriate directions for the modem control flags, - * and clear RTS and DTR - */ - ciab.ddra |= (SER_DTR | SER_RTS); /* outputs */ - ciab.ddra &= ~(SER_DCD | SER_CTS | SER_DSR); /* inputs */ - - platform_set_drvdata(pdev, state); - - return 0; - -fail_free_irq: - free_irq(IRQ_AMIGA_TBE, state); -fail_unregister: - tty_unregister_driver(serial_driver); -fail_put_tty_driver: - put_tty_driver(serial_driver); - return error; -} - -static int __exit amiga_serial_remove(struct platform_device *pdev) -{ - int error; - struct serial_state *state = platform_get_drvdata(pdev); - struct async_struct *info = state->info; - - /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ - tasklet_kill(&info->tlet); - if ((error = tty_unregister_driver(serial_driver))) - printk("SERIAL: failed to unregister serial driver (%d)\n", - error); - put_tty_driver(serial_driver); - - rs_table[0].info = NULL; - kfree(info); - - free_irq(IRQ_AMIGA_TBE, rs_table); - free_irq(IRQ_AMIGA_RBF, rs_table); - - platform_set_drvdata(pdev, NULL); - - return error; -} - -static struct platform_driver amiga_serial_driver = { - .remove = __exit_p(amiga_serial_remove), - .driver = { - .name = "amiga-serial", - .owner = THIS_MODULE, - }, -}; - -static int __init amiga_serial_init(void) -{ - return platform_driver_probe(&amiga_serial_driver, amiga_serial_probe); -} - -module_init(amiga_serial_init); - -static void __exit amiga_serial_exit(void) -{ - platform_driver_unregister(&amiga_serial_driver); -} - -module_exit(amiga_serial_exit); - - -#if defined(CONFIG_SERIAL_CONSOLE) && !defined(MODULE) - -/* - * ------------------------------------------------------------ - * Serial console driver - * ------------------------------------------------------------ - */ - -static void amiga_serial_putc(char c) -{ - custom.serdat = (unsigned char)c | 0x100; - while (!(custom.serdatr & 0x2000)) - barrier(); -} - -/* - * Print a string to the serial port trying not to disturb - * any possible real use of the port... - * - * The console must be locked when we get here. - */ -static void serial_console_write(struct console *co, const char *s, - unsigned count) -{ - unsigned short intena = custom.intenar; - - custom.intena = IF_TBE; - - while (count--) { - if (*s == '\n') - amiga_serial_putc('\r'); - amiga_serial_putc(*s++); - } - - custom.intena = IF_SETCLR | (intena & IF_TBE); -} - -static struct tty_driver *serial_console_device(struct console *c, int *index) -{ - *index = 0; - return serial_driver; -} - -static struct console sercons = { - .name = "ttyS", - .write = serial_console_write, - .device = serial_console_device, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -/* - * Register console. - */ -static int __init amiserial_console_init(void) -{ - register_console(&sercons); - return 0; -} -console_initcall(amiserial_console_init); - -#endif /* CONFIG_SERIAL_CONSOLE && !MODULE */ - -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:amiga-serial"); diff --git a/drivers/char/bfin_jtag_comm.c b/drivers/char/bfin_jtag_comm.c deleted file mode 100644 index 16402445f2b2..000000000000 --- a/drivers/char/bfin_jtag_comm.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * TTY over Blackfin JTAG Communication - * - * Copyright 2008-2009 Analog Devices Inc. - * - * Enter bugs at http://blackfin.uclinux.org/ - * - * Licensed under the GPL-2 or later. - */ - -#define DRV_NAME "bfin-jtag-comm" -#define DEV_NAME "ttyBFJC" -#define pr_fmt(fmt) DRV_NAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define pr_init(fmt, args...) ({ static const __initconst char __fmt[] = fmt; printk(__fmt, ## args); }) - -/* See the Debug/Emulation chapter in the HRM */ -#define EMUDOF 0x00000001 /* EMUDAT_OUT full & valid */ -#define EMUDIF 0x00000002 /* EMUDAT_IN full & valid */ -#define EMUDOOVF 0x00000004 /* EMUDAT_OUT overflow */ -#define EMUDIOVF 0x00000008 /* EMUDAT_IN overflow */ - -static inline uint32_t bfin_write_emudat(uint32_t emudat) -{ - __asm__ __volatile__("emudat = %0;" : : "d"(emudat)); - return emudat; -} - -static inline uint32_t bfin_read_emudat(void) -{ - uint32_t emudat; - __asm__ __volatile__("%0 = emudat;" : "=d"(emudat)); - return emudat; -} - -static inline uint32_t bfin_write_emudat_chars(char a, char b, char c, char d) -{ - return bfin_write_emudat((a << 0) | (b << 8) | (c << 16) | (d << 24)); -} - -#define CIRC_SIZE 2048 /* see comment in tty_io.c:do_tty_write() */ -#define CIRC_MASK (CIRC_SIZE - 1) -#define circ_empty(circ) ((circ)->head == (circ)->tail) -#define circ_free(circ) CIRC_SPACE((circ)->head, (circ)->tail, CIRC_SIZE) -#define circ_cnt(circ) CIRC_CNT((circ)->head, (circ)->tail, CIRC_SIZE) -#define circ_byte(circ, idx) ((circ)->buf[(idx) & CIRC_MASK]) - -static struct tty_driver *bfin_jc_driver; -static struct task_struct *bfin_jc_kthread; -static struct tty_struct * volatile bfin_jc_tty; -static unsigned long bfin_jc_count; -static DEFINE_MUTEX(bfin_jc_tty_mutex); -static volatile struct circ_buf bfin_jc_write_buf; - -static int -bfin_jc_emudat_manager(void *arg) -{ - uint32_t inbound_len = 0, outbound_len = 0; - - while (!kthread_should_stop()) { - /* no one left to give data to, so sleep */ - if (bfin_jc_tty == NULL && circ_empty(&bfin_jc_write_buf)) { - pr_debug("waiting for readers\n"); - __set_current_state(TASK_UNINTERRUPTIBLE); - schedule(); - __set_current_state(TASK_RUNNING); - } - - /* no data available, so just chill */ - if (!(bfin_read_DBGSTAT() & EMUDIF) && circ_empty(&bfin_jc_write_buf)) { - pr_debug("waiting for data (in_len = %i) (circ: %i %i)\n", - inbound_len, bfin_jc_write_buf.tail, bfin_jc_write_buf.head); - if (inbound_len) - schedule(); - else - schedule_timeout_interruptible(HZ); - continue; - } - - /* if incoming data is ready, eat it */ - if (bfin_read_DBGSTAT() & EMUDIF) { - struct tty_struct *tty; - mutex_lock(&bfin_jc_tty_mutex); - tty = (struct tty_struct *)bfin_jc_tty; - if (tty != NULL) { - uint32_t emudat = bfin_read_emudat(); - if (inbound_len == 0) { - pr_debug("incoming length: 0x%08x\n", emudat); - inbound_len = emudat; - } else { - size_t num_chars = (4 <= inbound_len ? 4 : inbound_len); - pr_debug(" incoming data: 0x%08x (pushing %zu)\n", emudat, num_chars); - inbound_len -= num_chars; - tty_insert_flip_string(tty, (unsigned char *)&emudat, num_chars); - tty_flip_buffer_push(tty); - } - } - mutex_unlock(&bfin_jc_tty_mutex); - } - - /* if outgoing data is ready, post it */ - if (!(bfin_read_DBGSTAT() & EMUDOF) && !circ_empty(&bfin_jc_write_buf)) { - if (outbound_len == 0) { - outbound_len = circ_cnt(&bfin_jc_write_buf); - bfin_write_emudat(outbound_len); - pr_debug("outgoing length: 0x%08x\n", outbound_len); - } else { - struct tty_struct *tty; - int tail = bfin_jc_write_buf.tail; - size_t ate = (4 <= outbound_len ? 4 : outbound_len); - uint32_t emudat = - bfin_write_emudat_chars( - circ_byte(&bfin_jc_write_buf, tail + 0), - circ_byte(&bfin_jc_write_buf, tail + 1), - circ_byte(&bfin_jc_write_buf, tail + 2), - circ_byte(&bfin_jc_write_buf, tail + 3) - ); - bfin_jc_write_buf.tail += ate; - outbound_len -= ate; - mutex_lock(&bfin_jc_tty_mutex); - tty = (struct tty_struct *)bfin_jc_tty; - if (tty) - tty_wakeup(tty); - mutex_unlock(&bfin_jc_tty_mutex); - pr_debug(" outgoing data: 0x%08x (pushing %zu)\n", emudat, ate); - } - } - } - - __set_current_state(TASK_RUNNING); - return 0; -} - -static int -bfin_jc_open(struct tty_struct *tty, struct file *filp) -{ - mutex_lock(&bfin_jc_tty_mutex); - pr_debug("open %lu\n", bfin_jc_count); - ++bfin_jc_count; - bfin_jc_tty = tty; - wake_up_process(bfin_jc_kthread); - mutex_unlock(&bfin_jc_tty_mutex); - return 0; -} - -static void -bfin_jc_close(struct tty_struct *tty, struct file *filp) -{ - mutex_lock(&bfin_jc_tty_mutex); - pr_debug("close %lu\n", bfin_jc_count); - if (--bfin_jc_count == 0) - bfin_jc_tty = NULL; - wake_up_process(bfin_jc_kthread); - mutex_unlock(&bfin_jc_tty_mutex); -} - -/* XXX: we dont handle the put_char() case where we must handle count = 1 */ -static int -bfin_jc_circ_write(const unsigned char *buf, int count) -{ - int i; - count = min(count, circ_free(&bfin_jc_write_buf)); - pr_debug("going to write chunk of %i bytes\n", count); - for (i = 0; i < count; ++i) - circ_byte(&bfin_jc_write_buf, bfin_jc_write_buf.head + i) = buf[i]; - bfin_jc_write_buf.head += i; - return i; -} - -#ifndef CONFIG_BFIN_JTAG_COMM_CONSOLE -# define console_lock() -# define console_unlock() -#endif -static int -bfin_jc_write(struct tty_struct *tty, const unsigned char *buf, int count) -{ - int i; - console_lock(); - i = bfin_jc_circ_write(buf, count); - console_unlock(); - wake_up_process(bfin_jc_kthread); - return i; -} - -static void -bfin_jc_flush_chars(struct tty_struct *tty) -{ - wake_up_process(bfin_jc_kthread); -} - -static int -bfin_jc_write_room(struct tty_struct *tty) -{ - return circ_free(&bfin_jc_write_buf); -} - -static int -bfin_jc_chars_in_buffer(struct tty_struct *tty) -{ - return circ_cnt(&bfin_jc_write_buf); -} - -static void -bfin_jc_wait_until_sent(struct tty_struct *tty, int timeout) -{ - unsigned long expire = jiffies + timeout; - while (!circ_empty(&bfin_jc_write_buf)) { - if (signal_pending(current)) - break; - if (time_after(jiffies, expire)) - break; - } -} - -static const struct tty_operations bfin_jc_ops = { - .open = bfin_jc_open, - .close = bfin_jc_close, - .write = bfin_jc_write, - /*.put_char = bfin_jc_put_char,*/ - .flush_chars = bfin_jc_flush_chars, - .write_room = bfin_jc_write_room, - .chars_in_buffer = bfin_jc_chars_in_buffer, - .wait_until_sent = bfin_jc_wait_until_sent, -}; - -static int __init bfin_jc_init(void) -{ - int ret; - - bfin_jc_kthread = kthread_create(bfin_jc_emudat_manager, NULL, DRV_NAME); - if (IS_ERR(bfin_jc_kthread)) - return PTR_ERR(bfin_jc_kthread); - - ret = -ENOMEM; - - bfin_jc_write_buf.head = bfin_jc_write_buf.tail = 0; - bfin_jc_write_buf.buf = kmalloc(CIRC_SIZE, GFP_KERNEL); - if (!bfin_jc_write_buf.buf) - goto err; - - bfin_jc_driver = alloc_tty_driver(1); - if (!bfin_jc_driver) - goto err; - - bfin_jc_driver->owner = THIS_MODULE; - bfin_jc_driver->driver_name = DRV_NAME; - bfin_jc_driver->name = DEV_NAME; - bfin_jc_driver->type = TTY_DRIVER_TYPE_SERIAL; - bfin_jc_driver->subtype = SERIAL_TYPE_NORMAL; - bfin_jc_driver->init_termios = tty_std_termios; - tty_set_operations(bfin_jc_driver, &bfin_jc_ops); - - ret = tty_register_driver(bfin_jc_driver); - if (ret) - goto err; - - pr_init(KERN_INFO DRV_NAME ": initialized\n"); - - return 0; - - err: - put_tty_driver(bfin_jc_driver); - kfree(bfin_jc_write_buf.buf); - kthread_stop(bfin_jc_kthread); - return ret; -} -module_init(bfin_jc_init); - -static void __exit bfin_jc_exit(void) -{ - kthread_stop(bfin_jc_kthread); - kfree(bfin_jc_write_buf.buf); - tty_unregister_driver(bfin_jc_driver); - put_tty_driver(bfin_jc_driver); -} -module_exit(bfin_jc_exit); - -#if defined(CONFIG_BFIN_JTAG_COMM_CONSOLE) || defined(CONFIG_EARLY_PRINTK) -static void -bfin_jc_straight_buffer_write(const char *buf, unsigned count) -{ - unsigned ate = 0; - while (bfin_read_DBGSTAT() & EMUDOF) - continue; - bfin_write_emudat(count); - while (ate < count) { - while (bfin_read_DBGSTAT() & EMUDOF) - continue; - bfin_write_emudat_chars(buf[ate], buf[ate+1], buf[ate+2], buf[ate+3]); - ate += 4; - } -} -#endif - -#ifdef CONFIG_BFIN_JTAG_COMM_CONSOLE -static void -bfin_jc_console_write(struct console *co, const char *buf, unsigned count) -{ - if (bfin_jc_kthread == NULL) - bfin_jc_straight_buffer_write(buf, count); - else - bfin_jc_circ_write(buf, count); -} - -static struct tty_driver * -bfin_jc_console_device(struct console *co, int *index) -{ - *index = co->index; - return bfin_jc_driver; -} - -static struct console bfin_jc_console = { - .name = DEV_NAME, - .write = bfin_jc_console_write, - .device = bfin_jc_console_device, - .flags = CON_ANYTIME | CON_PRINTBUFFER, - .index = -1, -}; - -static int __init bfin_jc_console_init(void) -{ - register_console(&bfin_jc_console); - return 0; -} -console_initcall(bfin_jc_console_init); -#endif - -#ifdef CONFIG_EARLY_PRINTK -static void __init -bfin_jc_early_write(struct console *co, const char *buf, unsigned int count) -{ - bfin_jc_straight_buffer_write(buf, count); -} - -static struct __initdata console bfin_jc_early_console = { - .name = "early_BFJC", - .write = bfin_jc_early_write, - .flags = CON_ANYTIME | CON_PRINTBUFFER, - .index = -1, -}; - -struct console * __init -bfin_jc_early_init(unsigned int port, unsigned int cflag) -{ - return &bfin_jc_early_console; -} -#endif - -MODULE_AUTHOR("Mike Frysinger "); -MODULE_DESCRIPTION("TTY over Blackfin JTAG Communication"); -MODULE_LICENSE("GPL"); diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c deleted file mode 100644 index c99728f0cd9f..000000000000 --- a/drivers/char/cyclades.c +++ /dev/null @@ -1,4200 +0,0 @@ -#undef BLOCKMOVE -#define Z_WAKE -#undef Z_EXT_CHARS_IN_BUFFER - -/* - * linux/drivers/char/cyclades.c - * - * This file contains the driver for the Cyclades async multiport - * serial boards. - * - * Initially written by Randolph Bentson . - * Modified and maintained by Marcio Saito . - * - * Copyright (C) 2007-2009 Jiri Slaby - * - * Much of the design and some of the code came from serial.c - * which was copyright (C) 1991, 1992 Linus Torvalds. It was - * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92, - * and then fixed as suggested by Michael K. Johnson 12/12/92. - * Converted to pci probing and cleaned up by Jiri Slaby. - * - */ - -#define CY_VERSION "2.6" - -/* If you need to install more boards than NR_CARDS, change the constant - in the definition below. No other change is necessary to support up to - eight boards. Beyond that you'll have to extend cy_isa_addresses. */ - -#define NR_CARDS 4 - -/* - If the total number of ports is larger than NR_PORTS, change this - constant in the definition below. No other change is necessary to - support more boards/ports. */ - -#define NR_PORTS 256 - -#define ZO_V1 0 -#define ZO_V2 1 -#define ZE_V1 2 - -#define SERIAL_PARANOIA_CHECK -#undef CY_DEBUG_OPEN -#undef CY_DEBUG_THROTTLE -#undef CY_DEBUG_OTHER -#undef CY_DEBUG_IO -#undef CY_DEBUG_COUNT -#undef CY_DEBUG_DTR -#undef CY_DEBUG_WAIT_UNTIL_SENT -#undef CY_DEBUG_INTERRUPTS -#undef CY_16Y_HACK -#undef CY_ENABLE_MONITORING -#undef CY_PCI_DEBUG - -/* - * Include section - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include -#include -#include - -static void cy_send_xchar(struct tty_struct *tty, char ch); - -#ifndef SERIAL_XMIT_SIZE -#define SERIAL_XMIT_SIZE (min(PAGE_SIZE, 4096)) -#endif - -#define STD_COM_FLAGS (0) - -/* firmware stuff */ -#define ZL_MAX_BLOCKS 16 -#define DRIVER_VERSION 0x02010203 -#define RAM_SIZE 0x80000 - -enum zblock_type { - ZBLOCK_PRG = 0, - ZBLOCK_FPGA = 1 -}; - -struct zfile_header { - char name[64]; - char date[32]; - char aux[32]; - u32 n_config; - u32 config_offset; - u32 n_blocks; - u32 block_offset; - u32 reserved[9]; -} __attribute__ ((packed)); - -struct zfile_config { - char name[64]; - u32 mailbox; - u32 function; - u32 n_blocks; - u32 block_list[ZL_MAX_BLOCKS]; -} __attribute__ ((packed)); - -struct zfile_block { - u32 type; - u32 file_offset; - u32 ram_offset; - u32 size; -} __attribute__ ((packed)); - -static struct tty_driver *cy_serial_driver; - -#ifdef CONFIG_ISA -/* This is the address lookup table. The driver will probe for - Cyclom-Y/ISA boards at all addresses in here. If you want the - driver to probe addresses at a different address, add it to - this table. If the driver is probing some other board and - causing problems, remove the offending address from this table. -*/ - -static unsigned int cy_isa_addresses[] = { - 0xD0000, - 0xD2000, - 0xD4000, - 0xD6000, - 0xD8000, - 0xDA000, - 0xDC000, - 0xDE000, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - -#define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses) - -static long maddr[NR_CARDS]; -static int irq[NR_CARDS]; - -module_param_array(maddr, long, NULL, 0); -module_param_array(irq, int, NULL, 0); - -#endif /* CONFIG_ISA */ - -/* This is the per-card data structure containing address, irq, number of - channels, etc. This driver supports a maximum of NR_CARDS cards. -*/ -static struct cyclades_card cy_card[NR_CARDS]; - -static int cy_next_channel; /* next minor available */ - -/* - * This is used to look up the divisor speeds and the timeouts - * We're normally limited to 15 distinct baud rates. The extra - * are accessed via settings in info->port.flags. - * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - * 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - * HI VHI - * 20 - */ -static const int baud_table[] = { - 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, - 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200, 150000, - 230400, 0 -}; - -static const char baud_co_25[] = { /* 25 MHz clock option table */ - /* value => 00 01 02 03 04 */ - /* divide by 8 32 128 512 2048 */ - 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, - 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static const char baud_bpr_25[] = { /* 25 MHz baud rate period table */ - 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3, - 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15 -}; - -static const char baud_co_60[] = { /* 60 MHz clock option table (CD1400 J) */ - /* value => 00 01 02 03 04 */ - /* divide by 8 32 128 512 2048 */ - 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, - 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00 -}; - -static const char baud_bpr_60[] = { /* 60 MHz baud rate period table (CD1400 J) */ - 0x00, 0x82, 0x21, 0xff, 0xdb, 0xc3, 0x92, 0x62, 0xc3, 0x62, - 0x41, 0xc3, 0x62, 0xc3, 0x62, 0xc3, 0x82, 0x62, 0x41, 0x32, - 0x21 -}; - -static const char baud_cor3[] = { /* receive threshold */ - 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, - 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07, - 0x07 -}; - -/* - * The Cyclades driver implements HW flow control as any serial driver. - * The cyclades_port structure member rflow and the vector rflow_thr - * allows us to take advantage of a special feature in the CD1400 to avoid - * data loss even when the system interrupt latency is too high. These flags - * are to be used only with very special applications. Setting these flags - * requires the use of a special cable (DTR and RTS reversed). In the new - * CD1400-based boards (rev. 6.00 or later), there is no need for special - * cables. - */ - -static const char rflow_thr[] = { /* rflow threshold */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, - 0x0a -}; - -/* The Cyclom-Ye has placed the sequential chips in non-sequential - * address order. This look-up table overcomes that problem. - */ -static const unsigned int cy_chip_offset[] = { 0x0000, - 0x0400, - 0x0800, - 0x0C00, - 0x0200, - 0x0600, - 0x0A00, - 0x0E00 -}; - -/* PCI related definitions */ - -#ifdef CONFIG_PCI -static const struct pci_device_id cy_pci_dev_id[] = { - /* PCI < 1Mb */ - { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) }, - /* PCI > 1Mb */ - { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Hi) }, - /* 4Y PCI < 1Mb */ - { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Lo) }, - /* 4Y PCI > 1Mb */ - { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Hi) }, - /* 8Y PCI < 1Mb */ - { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Lo) }, - /* 8Y PCI > 1Mb */ - { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Hi) }, - /* Z PCI < 1Mb */ - { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Lo) }, - /* Z PCI > 1Mb */ - { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Hi) }, - { } /* end of table */ -}; -MODULE_DEVICE_TABLE(pci, cy_pci_dev_id); -#endif - -static void cy_start(struct tty_struct *); -static void cy_set_line_char(struct cyclades_port *, struct tty_struct *); -static int cyz_issue_cmd(struct cyclades_card *, __u32, __u8, __u32); -#ifdef CONFIG_ISA -static unsigned detect_isa_irq(void __iomem *); -#endif /* CONFIG_ISA */ - -#ifndef CONFIG_CYZ_INTR -static void cyz_poll(unsigned long); - -/* The Cyclades-Z polling cycle is defined by this variable */ -static long cyz_polling_cycle = CZ_DEF_POLL; - -static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0); - -#else /* CONFIG_CYZ_INTR */ -static void cyz_rx_restart(unsigned long); -static struct timer_list cyz_rx_full_timer[NR_PORTS]; -#endif /* CONFIG_CYZ_INTR */ - -static inline void cyy_writeb(struct cyclades_port *port, u32 reg, u8 val) -{ - struct cyclades_card *card = port->card; - - cy_writeb(port->u.cyy.base_addr + (reg << card->bus_index), val); -} - -static inline u8 cyy_readb(struct cyclades_port *port, u32 reg) -{ - struct cyclades_card *card = port->card; - - return readb(port->u.cyy.base_addr + (reg << card->bus_index)); -} - -static inline bool cy_is_Z(struct cyclades_card *card) -{ - return card->num_chips == (unsigned int)-1; -} - -static inline bool __cyz_fpga_loaded(struct RUNTIME_9060 __iomem *ctl_addr) -{ - return readl(&ctl_addr->init_ctrl) & (1 << 17); -} - -static inline bool cyz_fpga_loaded(struct cyclades_card *card) -{ - return __cyz_fpga_loaded(card->ctl_addr.p9060); -} - -static inline bool cyz_is_loaded(struct cyclades_card *card) -{ - struct FIRM_ID __iomem *fw_id = card->base_addr + ID_ADDRESS; - - return (card->hw_ver == ZO_V1 || cyz_fpga_loaded(card)) && - readl(&fw_id->signature) == ZFIRM_ID; -} - -static inline int serial_paranoia_check(struct cyclades_port *info, - const char *name, const char *routine) -{ -#ifdef SERIAL_PARANOIA_CHECK - if (!info) { - printk(KERN_WARNING "cyc Warning: null cyclades_port for (%s) " - "in %s\n", name, routine); - return 1; - } - - if (info->magic != CYCLADES_MAGIC) { - printk(KERN_WARNING "cyc Warning: bad magic number for serial " - "struct (%s) in %s\n", name, routine); - return 1; - } -#endif - return 0; -} - -/***********************************************************/ -/********* Start of block of Cyclom-Y specific code ********/ - -/* This routine waits up to 1000 micro-seconds for the previous - command to the Cirrus chip to complete and then issues the - new command. An error is returned if the previous command - didn't finish within the time limit. - - This function is only called from inside spinlock-protected code. - */ -static int __cyy_issue_cmd(void __iomem *base_addr, u8 cmd, int index) -{ - void __iomem *ccr = base_addr + (CyCCR << index); - unsigned int i; - - /* Check to see that the previous command has completed */ - for (i = 0; i < 100; i++) { - if (readb(ccr) == 0) - break; - udelay(10L); - } - /* if the CCR never cleared, the previous command - didn't finish within the "reasonable time" */ - if (i == 100) - return -1; - - /* Issue the new command */ - cy_writeb(ccr, cmd); - - return 0; -} - -static inline int cyy_issue_cmd(struct cyclades_port *port, u8 cmd) -{ - return __cyy_issue_cmd(port->u.cyy.base_addr, cmd, - port->card->bus_index); -} - -#ifdef CONFIG_ISA -/* ISA interrupt detection code */ -static unsigned detect_isa_irq(void __iomem *address) -{ - int irq; - unsigned long irqs, flags; - int save_xir, save_car; - int index = 0; /* IRQ probing is only for ISA */ - - /* forget possible initially masked and pending IRQ */ - irq = probe_irq_off(probe_irq_on()); - - /* Clear interrupts on the board first */ - cy_writeb(address + (Cy_ClrIntr << index), 0); - /* Cy_ClrIntr is 0x1800 */ - - irqs = probe_irq_on(); - /* Wait ... */ - msleep(5); - - /* Enable the Tx interrupts on the CD1400 */ - local_irq_save(flags); - cy_writeb(address + (CyCAR << index), 0); - __cyy_issue_cmd(address, CyCHAN_CTL | CyENB_XMTR, index); - - cy_writeb(address + (CyCAR << index), 0); - cy_writeb(address + (CySRER << index), - readb(address + (CySRER << index)) | CyTxRdy); - local_irq_restore(flags); - - /* Wait ... */ - msleep(5); - - /* Check which interrupt is in use */ - irq = probe_irq_off(irqs); - - /* Clean up */ - save_xir = (u_char) readb(address + (CyTIR << index)); - save_car = readb(address + (CyCAR << index)); - cy_writeb(address + (CyCAR << index), (save_xir & 0x3)); - cy_writeb(address + (CySRER << index), - readb(address + (CySRER << index)) & ~CyTxRdy); - cy_writeb(address + (CyTIR << index), (save_xir & 0x3f)); - cy_writeb(address + (CyCAR << index), (save_car)); - cy_writeb(address + (Cy_ClrIntr << index), 0); - /* Cy_ClrIntr is 0x1800 */ - - return (irq > 0) ? irq : 0; -} -#endif /* CONFIG_ISA */ - -static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, - void __iomem *base_addr) -{ - struct cyclades_port *info; - struct tty_struct *tty; - int len, index = cinfo->bus_index; - u8 ivr, save_xir, channel, save_car, data, char_count; - -#ifdef CY_DEBUG_INTERRUPTS - printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip); -#endif - /* determine the channel & change to that context */ - save_xir = readb(base_addr + (CyRIR << index)); - channel = save_xir & CyIRChannel; - info = &cinfo->ports[channel + chip * 4]; - save_car = cyy_readb(info, CyCAR); - cyy_writeb(info, CyCAR, save_xir); - ivr = cyy_readb(info, CyRIVR) & CyIVRMask; - - tty = tty_port_tty_get(&info->port); - /* if there is nowhere to put the data, discard it */ - if (tty == NULL) { - if (ivr == CyIVRRxEx) { /* exception */ - data = cyy_readb(info, CyRDSR); - } else { /* normal character reception */ - char_count = cyy_readb(info, CyRDCR); - while (char_count--) - data = cyy_readb(info, CyRDSR); - } - goto end; - } - /* there is an open port for this data */ - if (ivr == CyIVRRxEx) { /* exception */ - data = cyy_readb(info, CyRDSR); - - /* For statistics only */ - if (data & CyBREAK) - info->icount.brk++; - else if (data & CyFRAME) - info->icount.frame++; - else if (data & CyPARITY) - info->icount.parity++; - else if (data & CyOVERRUN) - info->icount.overrun++; - - if (data & info->ignore_status_mask) { - info->icount.rx++; - tty_kref_put(tty); - return; - } - if (tty_buffer_request_room(tty, 1)) { - if (data & info->read_status_mask) { - if (data & CyBREAK) { - tty_insert_flip_char(tty, - cyy_readb(info, CyRDSR), - TTY_BREAK); - info->icount.rx++; - if (info->port.flags & ASYNC_SAK) - do_SAK(tty); - } else if (data & CyFRAME) { - tty_insert_flip_char(tty, - cyy_readb(info, CyRDSR), - TTY_FRAME); - info->icount.rx++; - info->idle_stats.frame_errs++; - } else if (data & CyPARITY) { - /* Pieces of seven... */ - tty_insert_flip_char(tty, - cyy_readb(info, CyRDSR), - TTY_PARITY); - info->icount.rx++; - info->idle_stats.parity_errs++; - } else if (data & CyOVERRUN) { - tty_insert_flip_char(tty, 0, - TTY_OVERRUN); - info->icount.rx++; - /* If the flip buffer itself is - overflowing, we still lose - the next incoming character. - */ - tty_insert_flip_char(tty, - cyy_readb(info, CyRDSR), - TTY_FRAME); - info->icount.rx++; - info->idle_stats.overruns++; - /* These two conditions may imply */ - /* a normal read should be done. */ - /* } else if(data & CyTIMEOUT) { */ - /* } else if(data & CySPECHAR) { */ - } else { - tty_insert_flip_char(tty, 0, - TTY_NORMAL); - info->icount.rx++; - } - } else { - tty_insert_flip_char(tty, 0, TTY_NORMAL); - info->icount.rx++; - } - } else { - /* there was a software buffer overrun and nothing - * could be done about it!!! */ - info->icount.buf_overrun++; - info->idle_stats.overruns++; - } - } else { /* normal character reception */ - /* load # chars available from the chip */ - char_count = cyy_readb(info, CyRDCR); - -#ifdef CY_ENABLE_MONITORING - ++info->mon.int_count; - info->mon.char_count += char_count; - if (char_count > info->mon.char_max) - info->mon.char_max = char_count; - info->mon.char_last = char_count; -#endif - len = tty_buffer_request_room(tty, char_count); - while (len--) { - data = cyy_readb(info, CyRDSR); - tty_insert_flip_char(tty, data, TTY_NORMAL); - info->idle_stats.recv_bytes++; - info->icount.rx++; -#ifdef CY_16Y_HACK - udelay(10L); -#endif - } - info->idle_stats.recv_idle = jiffies; - } - tty_schedule_flip(tty); - tty_kref_put(tty); -end: - /* end of service */ - cyy_writeb(info, CyRIR, save_xir & 0x3f); - cyy_writeb(info, CyCAR, save_car); -} - -static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip, - void __iomem *base_addr) -{ - struct cyclades_port *info; - struct tty_struct *tty; - int char_count, index = cinfo->bus_index; - u8 save_xir, channel, save_car, outch; - - /* Since we only get here when the transmit buffer - is empty, we know we can always stuff a dozen - characters. */ -#ifdef CY_DEBUG_INTERRUPTS - printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip); -#endif - - /* determine the channel & change to that context */ - save_xir = readb(base_addr + (CyTIR << index)); - channel = save_xir & CyIRChannel; - save_car = readb(base_addr + (CyCAR << index)); - cy_writeb(base_addr + (CyCAR << index), save_xir); - - info = &cinfo->ports[channel + chip * 4]; - tty = tty_port_tty_get(&info->port); - if (tty == NULL) { - cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyTxRdy); - goto end; - } - - /* load the on-chip space for outbound data */ - char_count = info->xmit_fifo_size; - - if (info->x_char) { /* send special char */ - outch = info->x_char; - cyy_writeb(info, CyTDR, outch); - char_count--; - info->icount.tx++; - info->x_char = 0; - } - - if (info->breakon || info->breakoff) { - if (info->breakon) { - cyy_writeb(info, CyTDR, 0); - cyy_writeb(info, CyTDR, 0x81); - info->breakon = 0; - char_count -= 2; - } - if (info->breakoff) { - cyy_writeb(info, CyTDR, 0); - cyy_writeb(info, CyTDR, 0x83); - info->breakoff = 0; - char_count -= 2; - } - } - - while (char_count-- > 0) { - if (!info->xmit_cnt) { - if (cyy_readb(info, CySRER) & CyTxMpty) { - cyy_writeb(info, CySRER, - cyy_readb(info, CySRER) & ~CyTxMpty); - } else { - cyy_writeb(info, CySRER, CyTxMpty | - (cyy_readb(info, CySRER) & ~CyTxRdy)); - } - goto done; - } - if (info->port.xmit_buf == NULL) { - cyy_writeb(info, CySRER, - cyy_readb(info, CySRER) & ~CyTxRdy); - goto done; - } - if (tty->stopped || tty->hw_stopped) { - cyy_writeb(info, CySRER, - cyy_readb(info, CySRER) & ~CyTxRdy); - goto done; - } - /* Because the Embedded Transmit Commands have been enabled, - * we must check to see if the escape character, NULL, is being - * sent. If it is, we must ensure that there is room for it to - * be doubled in the output stream. Therefore we no longer - * advance the pointer when the character is fetched, but - * rather wait until after the check for a NULL output - * character. This is necessary because there may not be room - * for the two chars needed to send a NULL.) - */ - outch = info->port.xmit_buf[info->xmit_tail]; - if (outch) { - info->xmit_cnt--; - info->xmit_tail = (info->xmit_tail + 1) & - (SERIAL_XMIT_SIZE - 1); - cyy_writeb(info, CyTDR, outch); - info->icount.tx++; - } else { - if (char_count > 1) { - info->xmit_cnt--; - info->xmit_tail = (info->xmit_tail + 1) & - (SERIAL_XMIT_SIZE - 1); - cyy_writeb(info, CyTDR, outch); - cyy_writeb(info, CyTDR, 0); - info->icount.tx++; - char_count--; - } - } - } - -done: - tty_wakeup(tty); - tty_kref_put(tty); -end: - /* end of service */ - cyy_writeb(info, CyTIR, save_xir & 0x3f); - cyy_writeb(info, CyCAR, save_car); -} - -static void cyy_chip_modem(struct cyclades_card *cinfo, int chip, - void __iomem *base_addr) -{ - struct cyclades_port *info; - struct tty_struct *tty; - int index = cinfo->bus_index; - u8 save_xir, channel, save_car, mdm_change, mdm_status; - - /* determine the channel & change to that context */ - save_xir = readb(base_addr + (CyMIR << index)); - channel = save_xir & CyIRChannel; - info = &cinfo->ports[channel + chip * 4]; - save_car = cyy_readb(info, CyCAR); - cyy_writeb(info, CyCAR, save_xir); - - mdm_change = cyy_readb(info, CyMISR); - mdm_status = cyy_readb(info, CyMSVR1); - - tty = tty_port_tty_get(&info->port); - if (!tty) - goto end; - - if (mdm_change & CyANY_DELTA) { - /* For statistics only */ - if (mdm_change & CyDCD) - info->icount.dcd++; - if (mdm_change & CyCTS) - info->icount.cts++; - if (mdm_change & CyDSR) - info->icount.dsr++; - if (mdm_change & CyRI) - info->icount.rng++; - - wake_up_interruptible(&info->port.delta_msr_wait); - } - - if ((mdm_change & CyDCD) && (info->port.flags & ASYNC_CHECK_CD)) { - if (mdm_status & CyDCD) - wake_up_interruptible(&info->port.open_wait); - else - tty_hangup(tty); - } - if ((mdm_change & CyCTS) && (info->port.flags & ASYNC_CTS_FLOW)) { - if (tty->hw_stopped) { - if (mdm_status & CyCTS) { - /* cy_start isn't used - because... !!! */ - tty->hw_stopped = 0; - cyy_writeb(info, CySRER, - cyy_readb(info, CySRER) | CyTxRdy); - tty_wakeup(tty); - } - } else { - if (!(mdm_status & CyCTS)) { - /* cy_stop isn't used - because ... !!! */ - tty->hw_stopped = 1; - cyy_writeb(info, CySRER, - cyy_readb(info, CySRER) & ~CyTxRdy); - } - } - } -/* if (mdm_change & CyDSR) { - } - if (mdm_change & CyRI) { - }*/ - tty_kref_put(tty); -end: - /* end of service */ - cyy_writeb(info, CyMIR, save_xir & 0x3f); - cyy_writeb(info, CyCAR, save_car); -} - -/* The real interrupt service routine is called - whenever the card wants its hand held--chars - received, out buffer empty, modem change, etc. - */ -static irqreturn_t cyy_interrupt(int irq, void *dev_id) -{ - int status; - struct cyclades_card *cinfo = dev_id; - void __iomem *base_addr, *card_base_addr; - unsigned int chip, too_many, had_work; - int index; - - if (unlikely(cinfo == NULL)) { -#ifdef CY_DEBUG_INTERRUPTS - printk(KERN_DEBUG "cyy_interrupt: spurious interrupt %d\n", - irq); -#endif - return IRQ_NONE; /* spurious interrupt */ - } - - card_base_addr = cinfo->base_addr; - index = cinfo->bus_index; - - /* card was not initialized yet (e.g. DEBUG_SHIRQ) */ - if (unlikely(card_base_addr == NULL)) - return IRQ_HANDLED; - - /* This loop checks all chips in the card. Make a note whenever - _any_ chip had some work to do, as this is considered an - indication that there will be more to do. Only when no chip - has any work does this outermost loop exit. - */ - do { - had_work = 0; - for (chip = 0; chip < cinfo->num_chips; chip++) { - base_addr = cinfo->base_addr + - (cy_chip_offset[chip] << index); - too_many = 0; - while ((status = readb(base_addr + - (CySVRR << index))) != 0x00) { - had_work++; - /* The purpose of the following test is to ensure that - no chip can monopolize the driver. This forces the - chips to be checked in a round-robin fashion (after - draining each of a bunch (1000) of characters). - */ - if (1000 < too_many++) - break; - spin_lock(&cinfo->card_lock); - if (status & CySRReceive) /* rx intr */ - cyy_chip_rx(cinfo, chip, base_addr); - if (status & CySRTransmit) /* tx intr */ - cyy_chip_tx(cinfo, chip, base_addr); - if (status & CySRModem) /* modem intr */ - cyy_chip_modem(cinfo, chip, base_addr); - spin_unlock(&cinfo->card_lock); - } - } - } while (had_work); - - /* clear interrupts */ - spin_lock(&cinfo->card_lock); - cy_writeb(card_base_addr + (Cy_ClrIntr << index), 0); - /* Cy_ClrIntr is 0x1800 */ - spin_unlock(&cinfo->card_lock); - return IRQ_HANDLED; -} /* cyy_interrupt */ - -static void cyy_change_rts_dtr(struct cyclades_port *info, unsigned int set, - unsigned int clear) -{ - struct cyclades_card *card = info->card; - int channel = info->line - card->first_line; - u32 rts, dtr, msvrr, msvrd; - - channel &= 0x03; - - if (info->rtsdtr_inv) { - msvrr = CyMSVR2; - msvrd = CyMSVR1; - rts = CyDTR; - dtr = CyRTS; - } else { - msvrr = CyMSVR1; - msvrd = CyMSVR2; - rts = CyRTS; - dtr = CyDTR; - } - if (set & TIOCM_RTS) { - cyy_writeb(info, CyCAR, channel); - cyy_writeb(info, msvrr, rts); - } - if (clear & TIOCM_RTS) { - cyy_writeb(info, CyCAR, channel); - cyy_writeb(info, msvrr, ~rts); - } - if (set & TIOCM_DTR) { - cyy_writeb(info, CyCAR, channel); - cyy_writeb(info, msvrd, dtr); -#ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc:set_modem_info raising DTR\n"); - printk(KERN_DEBUG " status: 0x%x, 0x%x\n", - cyy_readb(info, CyMSVR1), - cyy_readb(info, CyMSVR2)); -#endif - } - if (clear & TIOCM_DTR) { - cyy_writeb(info, CyCAR, channel); - cyy_writeb(info, msvrd, ~dtr); -#ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc:set_modem_info dropping DTR\n"); - printk(KERN_DEBUG " status: 0x%x, 0x%x\n", - cyy_readb(info, CyMSVR1), - cyy_readb(info, CyMSVR2)); -#endif - } -} - -/***********************************************************/ -/********* End of block of Cyclom-Y specific code **********/ -/******** Start of block of Cyclades-Z specific code *******/ -/***********************************************************/ - -static int -cyz_fetch_msg(struct cyclades_card *cinfo, - __u32 *channel, __u8 *cmd, __u32 *param) -{ - struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl; - unsigned long loc_doorbell; - - loc_doorbell = readl(&cinfo->ctl_addr.p9060->loc_doorbell); - if (loc_doorbell) { - *cmd = (char)(0xff & loc_doorbell); - *channel = readl(&board_ctrl->fwcmd_channel); - *param = (__u32) readl(&board_ctrl->fwcmd_param); - cy_writel(&cinfo->ctl_addr.p9060->loc_doorbell, 0xffffffff); - return 1; - } - return 0; -} /* cyz_fetch_msg */ - -static int -cyz_issue_cmd(struct cyclades_card *cinfo, - __u32 channel, __u8 cmd, __u32 param) -{ - struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl; - __u32 __iomem *pci_doorbell; - unsigned int index; - - if (!cyz_is_loaded(cinfo)) - return -1; - - index = 0; - pci_doorbell = &cinfo->ctl_addr.p9060->pci_doorbell; - while ((readl(pci_doorbell) & 0xff) != 0) { - if (index++ == 1000) - return (int)(readl(pci_doorbell) & 0xff); - udelay(50L); - } - cy_writel(&board_ctrl->hcmd_channel, channel); - cy_writel(&board_ctrl->hcmd_param, param); - cy_writel(pci_doorbell, (long)cmd); - - return 0; -} /* cyz_issue_cmd */ - -static void cyz_handle_rx(struct cyclades_port *info, struct tty_struct *tty) -{ - struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl; - struct cyclades_card *cinfo = info->card; - unsigned int char_count; - int len; -#ifdef BLOCKMOVE - unsigned char *buf; -#else - char data; -#endif - __u32 rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr; - - rx_get = new_rx_get = readl(&buf_ctrl->rx_get); - rx_put = readl(&buf_ctrl->rx_put); - rx_bufsize = readl(&buf_ctrl->rx_bufsize); - rx_bufaddr = readl(&buf_ctrl->rx_bufaddr); - if (rx_put >= rx_get) - char_count = rx_put - rx_get; - else - char_count = rx_put - rx_get + rx_bufsize; - - if (char_count) { -#ifdef CY_ENABLE_MONITORING - info->mon.int_count++; - info->mon.char_count += char_count; - if (char_count > info->mon.char_max) - info->mon.char_max = char_count; - info->mon.char_last = char_count; -#endif - if (tty == NULL) { - /* flush received characters */ - new_rx_get = (new_rx_get + char_count) & - (rx_bufsize - 1); - info->rflush_count++; - } else { -#ifdef BLOCKMOVE - /* we'd like to use memcpy(t, f, n) and memset(s, c, count) - for performance, but because of buffer boundaries, there - may be several steps to the operation */ - while (1) { - len = tty_prepare_flip_string(tty, &buf, - char_count); - if (!len) - break; - - len = min_t(unsigned int, min(len, char_count), - rx_bufsize - new_rx_get); - - memcpy_fromio(buf, cinfo->base_addr + - rx_bufaddr + new_rx_get, len); - - new_rx_get = (new_rx_get + len) & - (rx_bufsize - 1); - char_count -= len; - info->icount.rx += len; - info->idle_stats.recv_bytes += len; - } -#else - len = tty_buffer_request_room(tty, char_count); - while (len--) { - data = readb(cinfo->base_addr + rx_bufaddr + - new_rx_get); - new_rx_get = (new_rx_get + 1) & - (rx_bufsize - 1); - tty_insert_flip_char(tty, data, TTY_NORMAL); - info->idle_stats.recv_bytes++; - info->icount.rx++; - } -#endif -#ifdef CONFIG_CYZ_INTR - /* Recalculate the number of chars in the RX buffer and issue - a cmd in case it's higher than the RX high water mark */ - rx_put = readl(&buf_ctrl->rx_put); - if (rx_put >= rx_get) - char_count = rx_put - rx_get; - else - char_count = rx_put - rx_get + rx_bufsize; - if (char_count >= readl(&buf_ctrl->rx_threshold) && - !timer_pending(&cyz_rx_full_timer[ - info->line])) - mod_timer(&cyz_rx_full_timer[info->line], - jiffies + 1); -#endif - info->idle_stats.recv_idle = jiffies; - tty_schedule_flip(tty); - } - /* Update rx_get */ - cy_writel(&buf_ctrl->rx_get, new_rx_get); - } -} - -static void cyz_handle_tx(struct cyclades_port *info, struct tty_struct *tty) -{ - struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl; - struct cyclades_card *cinfo = info->card; - u8 data; - unsigned int char_count; -#ifdef BLOCKMOVE - int small_count; -#endif - __u32 tx_put, tx_get, tx_bufsize, tx_bufaddr; - - if (info->xmit_cnt <= 0) /* Nothing to transmit */ - return; - - tx_get = readl(&buf_ctrl->tx_get); - tx_put = readl(&buf_ctrl->tx_put); - tx_bufsize = readl(&buf_ctrl->tx_bufsize); - tx_bufaddr = readl(&buf_ctrl->tx_bufaddr); - if (tx_put >= tx_get) - char_count = tx_get - tx_put - 1 + tx_bufsize; - else - char_count = tx_get - tx_put - 1; - - if (char_count) { - - if (tty == NULL) - goto ztxdone; - - if (info->x_char) { /* send special char */ - data = info->x_char; - - cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data); - tx_put = (tx_put + 1) & (tx_bufsize - 1); - info->x_char = 0; - char_count--; - info->icount.tx++; - } -#ifdef BLOCKMOVE - while (0 < (small_count = min_t(unsigned int, - tx_bufsize - tx_put, min_t(unsigned int, - (SERIAL_XMIT_SIZE - info->xmit_tail), - min_t(unsigned int, info->xmit_cnt, - char_count))))) { - - memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr + - tx_put), - &info->port.xmit_buf[info->xmit_tail], - small_count); - - tx_put = (tx_put + small_count) & (tx_bufsize - 1); - char_count -= small_count; - info->icount.tx += small_count; - info->xmit_cnt -= small_count; - info->xmit_tail = (info->xmit_tail + small_count) & - (SERIAL_XMIT_SIZE - 1); - } -#else - while (info->xmit_cnt && char_count) { - data = info->port.xmit_buf[info->xmit_tail]; - info->xmit_cnt--; - info->xmit_tail = (info->xmit_tail + 1) & - (SERIAL_XMIT_SIZE - 1); - - cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data); - tx_put = (tx_put + 1) & (tx_bufsize - 1); - char_count--; - info->icount.tx++; - } -#endif - tty_wakeup(tty); -ztxdone: - /* Update tx_put */ - cy_writel(&buf_ctrl->tx_put, tx_put); - } -} - -static void cyz_handle_cmd(struct cyclades_card *cinfo) -{ - struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl; - struct tty_struct *tty; - struct cyclades_port *info; - __u32 channel, param, fw_ver; - __u8 cmd; - int special_count; - int delta_count; - - fw_ver = readl(&board_ctrl->fw_version); - - while (cyz_fetch_msg(cinfo, &channel, &cmd, ¶m) == 1) { - special_count = 0; - delta_count = 0; - info = &cinfo->ports[channel]; - tty = tty_port_tty_get(&info->port); - if (tty == NULL) - continue; - - switch (cmd) { - case C_CM_PR_ERROR: - tty_insert_flip_char(tty, 0, TTY_PARITY); - info->icount.rx++; - special_count++; - break; - case C_CM_FR_ERROR: - tty_insert_flip_char(tty, 0, TTY_FRAME); - info->icount.rx++; - special_count++; - break; - case C_CM_RXBRK: - tty_insert_flip_char(tty, 0, TTY_BREAK); - info->icount.rx++; - special_count++; - break; - case C_CM_MDCD: - info->icount.dcd++; - delta_count++; - if (info->port.flags & ASYNC_CHECK_CD) { - u32 dcd = fw_ver > 241 ? param : - readl(&info->u.cyz.ch_ctrl->rs_status); - if (dcd & C_RS_DCD) - wake_up_interruptible(&info->port.open_wait); - else - tty_hangup(tty); - } - break; - case C_CM_MCTS: - info->icount.cts++; - delta_count++; - break; - case C_CM_MRI: - info->icount.rng++; - delta_count++; - break; - case C_CM_MDSR: - info->icount.dsr++; - delta_count++; - break; -#ifdef Z_WAKE - case C_CM_IOCTLW: - complete(&info->shutdown_wait); - break; -#endif -#ifdef CONFIG_CYZ_INTR - case C_CM_RXHIWM: - case C_CM_RXNNDT: - case C_CM_INTBACK2: - /* Reception Interrupt */ -#ifdef CY_DEBUG_INTERRUPTS - printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " - "port %ld\n", info->card, channel); -#endif - cyz_handle_rx(info, tty); - break; - case C_CM_TXBEMPTY: - case C_CM_TXLOWWM: - case C_CM_INTBACK: - /* Transmission Interrupt */ -#ifdef CY_DEBUG_INTERRUPTS - printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " - "port %ld\n", info->card, channel); -#endif - cyz_handle_tx(info, tty); - break; -#endif /* CONFIG_CYZ_INTR */ - case C_CM_FATAL: - /* should do something with this !!! */ - break; - default: - break; - } - if (delta_count) - wake_up_interruptible(&info->port.delta_msr_wait); - if (special_count) - tty_schedule_flip(tty); - tty_kref_put(tty); - } -} - -#ifdef CONFIG_CYZ_INTR -static irqreturn_t cyz_interrupt(int irq, void *dev_id) -{ - struct cyclades_card *cinfo = dev_id; - - if (unlikely(!cyz_is_loaded(cinfo))) { -#ifdef CY_DEBUG_INTERRUPTS - printk(KERN_DEBUG "cyz_interrupt: board not yet loaded " - "(IRQ%d).\n", irq); -#endif - return IRQ_NONE; - } - - /* Handle the interrupts */ - cyz_handle_cmd(cinfo); - - return IRQ_HANDLED; -} /* cyz_interrupt */ - -static void cyz_rx_restart(unsigned long arg) -{ - struct cyclades_port *info = (struct cyclades_port *)arg; - struct cyclades_card *card = info->card; - int retval; - __u32 channel = info->line - card->first_line; - unsigned long flags; - - spin_lock_irqsave(&card->card_lock, flags); - retval = cyz_issue_cmd(card, channel, C_CM_INTBACK2, 0L); - if (retval != 0) { - printk(KERN_ERR "cyc:cyz_rx_restart retval on ttyC%d was %x\n", - info->line, retval); - } - spin_unlock_irqrestore(&card->card_lock, flags); -} - -#else /* CONFIG_CYZ_INTR */ - -static void cyz_poll(unsigned long arg) -{ - struct cyclades_card *cinfo; - struct cyclades_port *info; - unsigned long expires = jiffies + HZ; - unsigned int port, card; - - for (card = 0; card < NR_CARDS; card++) { - cinfo = &cy_card[card]; - - if (!cy_is_Z(cinfo)) - continue; - if (!cyz_is_loaded(cinfo)) - continue; - - /* Skip first polling cycle to avoid racing conditions with the FW */ - if (!cinfo->intr_enabled) { - cinfo->intr_enabled = 1; - continue; - } - - cyz_handle_cmd(cinfo); - - for (port = 0; port < cinfo->nports; port++) { - struct tty_struct *tty; - - info = &cinfo->ports[port]; - tty = tty_port_tty_get(&info->port); - /* OK to pass NULL to the handle functions below. - They need to drop the data in that case. */ - - if (!info->throttle) - cyz_handle_rx(info, tty); - cyz_handle_tx(info, tty); - tty_kref_put(tty); - } - /* poll every 'cyz_polling_cycle' period */ - expires = jiffies + cyz_polling_cycle; - } - mod_timer(&cyz_timerlist, expires); -} /* cyz_poll */ - -#endif /* CONFIG_CYZ_INTR */ - -/********** End of block of Cyclades-Z specific code *********/ -/***********************************************************/ - -/* This is called whenever a port becomes active; - interrupts are enabled and DTR & RTS are turned on. - */ -static int cy_startup(struct cyclades_port *info, struct tty_struct *tty) -{ - struct cyclades_card *card; - unsigned long flags; - int retval = 0; - int channel; - unsigned long page; - - card = info->card; - channel = info->line - card->first_line; - - page = get_zeroed_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - - spin_lock_irqsave(&card->card_lock, flags); - - if (info->port.flags & ASYNC_INITIALIZED) - goto errout; - - if (!info->type) { - set_bit(TTY_IO_ERROR, &tty->flags); - goto errout; - } - - if (info->port.xmit_buf) - free_page(page); - else - info->port.xmit_buf = (unsigned char *)page; - - spin_unlock_irqrestore(&card->card_lock, flags); - - cy_set_line_char(info, tty); - - if (!cy_is_Z(card)) { - channel &= 0x03; - - spin_lock_irqsave(&card->card_lock, flags); - - cyy_writeb(info, CyCAR, channel); - - cyy_writeb(info, CyRTPR, - (info->default_timeout ? info->default_timeout : 0x02)); - /* 10ms rx timeout */ - - cyy_issue_cmd(info, CyCHAN_CTL | CyENB_RCVR | CyENB_XMTR); - - cyy_change_rts_dtr(info, TIOCM_RTS | TIOCM_DTR, 0); - - cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyRxData); - } else { - struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl; - - if (!cyz_is_loaded(card)) - return -ENODEV; - -#ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc startup Z card %d, channel %d, " - "base_addr %p\n", card, channel, card->base_addr); -#endif - spin_lock_irqsave(&card->card_lock, flags); - - cy_writel(&ch_ctrl->op_mode, C_CH_ENABLE); -#ifdef Z_WAKE -#ifdef CONFIG_CYZ_INTR - cy_writel(&ch_ctrl->intr_enable, - C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM | - C_IN_RXNNDT | C_IN_IOCTLW | C_IN_MDCD); -#else - cy_writel(&ch_ctrl->intr_enable, - C_IN_IOCTLW | C_IN_MDCD); -#endif /* CONFIG_CYZ_INTR */ -#else -#ifdef CONFIG_CYZ_INTR - cy_writel(&ch_ctrl->intr_enable, - C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM | - C_IN_RXNNDT | C_IN_MDCD); -#else - cy_writel(&ch_ctrl->intr_enable, C_IN_MDCD); -#endif /* CONFIG_CYZ_INTR */ -#endif /* Z_WAKE */ - - retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L); - if (retval != 0) { - printk(KERN_ERR "cyc:startup(1) retval on ttyC%d was " - "%x\n", info->line, retval); - } - - /* Flush RX buffers before raising DTR and RTS */ - retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_RX, 0L); - if (retval != 0) { - printk(KERN_ERR "cyc:startup(2) retval on ttyC%d was " - "%x\n", info->line, retval); - } - - /* set timeout !!! */ - /* set RTS and DTR !!! */ - tty_port_raise_dtr_rts(&info->port); - - /* enable send, recv, modem !!! */ - } - - info->port.flags |= ASYNC_INITIALIZED; - - clear_bit(TTY_IO_ERROR, &tty->flags); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - info->breakon = info->breakoff = 0; - memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats)); - info->idle_stats.in_use = - info->idle_stats.recv_idle = - info->idle_stats.xmit_idle = jiffies; - - spin_unlock_irqrestore(&card->card_lock, flags); - -#ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc startup done\n"); -#endif - return 0; - -errout: - spin_unlock_irqrestore(&card->card_lock, flags); - free_page(page); - return retval; -} /* startup */ - -static void start_xmit(struct cyclades_port *info) -{ - struct cyclades_card *card = info->card; - unsigned long flags; - int channel = info->line - card->first_line; - - if (!cy_is_Z(card)) { - spin_lock_irqsave(&card->card_lock, flags); - cyy_writeb(info, CyCAR, channel & 0x03); - cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyTxRdy); - spin_unlock_irqrestore(&card->card_lock, flags); - } else { -#ifdef CONFIG_CYZ_INTR - int retval; - - spin_lock_irqsave(&card->card_lock, flags); - retval = cyz_issue_cmd(card, channel, C_CM_INTBACK, 0L); - if (retval != 0) { - printk(KERN_ERR "cyc:start_xmit retval on ttyC%d was " - "%x\n", info->line, retval); - } - spin_unlock_irqrestore(&card->card_lock, flags); -#else /* CONFIG_CYZ_INTR */ - /* Don't have to do anything at this time */ -#endif /* CONFIG_CYZ_INTR */ - } -} /* start_xmit */ - -/* - * This routine shuts down a serial port; interrupts are disabled, - * and DTR is dropped if the hangup on close termio flag is on. - */ -static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) -{ - struct cyclades_card *card; - unsigned long flags; - int channel; - - if (!(info->port.flags & ASYNC_INITIALIZED)) - return; - - card = info->card; - channel = info->line - card->first_line; - if (!cy_is_Z(card)) { - spin_lock_irqsave(&card->card_lock, flags); - - /* Clear delta_msr_wait queue to avoid mem leaks. */ - wake_up_interruptible(&info->port.delta_msr_wait); - - if (info->port.xmit_buf) { - unsigned char *temp; - temp = info->port.xmit_buf; - info->port.xmit_buf = NULL; - free_page((unsigned long)temp); - } - if (tty->termios->c_cflag & HUPCL) - cyy_change_rts_dtr(info, 0, TIOCM_RTS | TIOCM_DTR); - - cyy_issue_cmd(info, CyCHAN_CTL | CyDIS_RCVR); - /* it may be appropriate to clear _XMIT at - some later date (after testing)!!! */ - - set_bit(TTY_IO_ERROR, &tty->flags); - info->port.flags &= ~ASYNC_INITIALIZED; - spin_unlock_irqrestore(&card->card_lock, flags); - } else { -#ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, " - "base_addr %p\n", card, channel, card->base_addr); -#endif - - if (!cyz_is_loaded(card)) - return; - - spin_lock_irqsave(&card->card_lock, flags); - - if (info->port.xmit_buf) { - unsigned char *temp; - temp = info->port.xmit_buf; - info->port.xmit_buf = NULL; - free_page((unsigned long)temp); - } - - if (tty->termios->c_cflag & HUPCL) - tty_port_lower_dtr_rts(&info->port); - - set_bit(TTY_IO_ERROR, &tty->flags); - info->port.flags &= ~ASYNC_INITIALIZED; - - spin_unlock_irqrestore(&card->card_lock, flags); - } - -#ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc shutdown done\n"); -#endif -} /* shutdown */ - -/* - * ------------------------------------------------------------ - * cy_open() and friends - * ------------------------------------------------------------ - */ - -/* - * This routine is called whenever a serial port is opened. It - * performs the serial-specific initialization for the tty structure. - */ -static int cy_open(struct tty_struct *tty, struct file *filp) -{ - struct cyclades_port *info; - unsigned int i, line; - int retval; - - line = tty->index; - if (tty->index < 0 || NR_PORTS <= line) - return -ENODEV; - - for (i = 0; i < NR_CARDS; i++) - if (line < cy_card[i].first_line + cy_card[i].nports && - line >= cy_card[i].first_line) - break; - if (i >= NR_CARDS) - return -ENODEV; - info = &cy_card[i].ports[line - cy_card[i].first_line]; - if (info->line < 0) - return -ENODEV; - - /* If the card's firmware hasn't been loaded, - treat it as absent from the system. This - will make the user pay attention. - */ - if (cy_is_Z(info->card)) { - struct cyclades_card *cinfo = info->card; - struct FIRM_ID __iomem *firm_id = cinfo->base_addr + ID_ADDRESS; - - if (!cyz_is_loaded(cinfo)) { - if (cinfo->hw_ver == ZE_V1 && cyz_fpga_loaded(cinfo) && - readl(&firm_id->signature) == - ZFIRM_HLT) { - printk(KERN_ERR "cyc:Cyclades-Z Error: you " - "need an external power supply for " - "this number of ports.\nFirmware " - "halted.\n"); - } else { - printk(KERN_ERR "cyc:Cyclades-Z firmware not " - "yet loaded\n"); - } - return -ENODEV; - } -#ifdef CONFIG_CYZ_INTR - else { - /* In case this Z board is operating in interrupt mode, its - interrupts should be enabled as soon as the first open - happens to one of its ports. */ - if (!cinfo->intr_enabled) { - u16 intr; - - /* Enable interrupts on the PLX chip */ - intr = readw(&cinfo->ctl_addr.p9060-> - intr_ctrl_stat) | 0x0900; - cy_writew(&cinfo->ctl_addr.p9060-> - intr_ctrl_stat, intr); - /* Enable interrupts on the FW */ - retval = cyz_issue_cmd(cinfo, 0, - C_CM_IRQ_ENBL, 0L); - if (retval != 0) { - printk(KERN_ERR "cyc:IRQ enable retval " - "was %x\n", retval); - } - cinfo->intr_enabled = 1; - } - } -#endif /* CONFIG_CYZ_INTR */ - /* Make sure this Z port really exists in hardware */ - if (info->line > (cinfo->first_line + cinfo->nports - 1)) - return -ENODEV; - } -#ifdef CY_DEBUG_OTHER - printk(KERN_DEBUG "cyc:cy_open ttyC%d\n", info->line); -#endif - tty->driver_data = info; - if (serial_paranoia_check(info, tty->name, "cy_open")) - return -ENODEV; - -#ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc:cy_open ttyC%d, count = %d\n", info->line, - info->port.count); -#endif - info->port.count++; -#ifdef CY_DEBUG_COUNT - printk(KERN_DEBUG "cyc:cy_open (%d): incrementing count to %d\n", - current->pid, info->port.count); -#endif - - /* - * If the port is the middle of closing, bail out now - */ - if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) { - wait_event_interruptible_tty(info->port.close_wait, - !(info->port.flags & ASYNC_CLOSING)); - return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; - } - - /* - * Start up serial port - */ - retval = cy_startup(info, tty); - if (retval) - return retval; - - retval = tty_port_block_til_ready(&info->port, tty, filp); - if (retval) { -#ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc:cy_open returning after block_til_ready " - "with %d\n", retval); -#endif - return retval; - } - - info->throttle = 0; - tty_port_tty_set(&info->port, tty); - -#ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc:cy_open done\n"); -#endif - return 0; -} /* cy_open */ - -/* - * cy_wait_until_sent() --- wait until the transmitter is empty - */ -static void cy_wait_until_sent(struct tty_struct *tty, int timeout) -{ - struct cyclades_card *card; - struct cyclades_port *info = tty->driver_data; - unsigned long orig_jiffies; - int char_time; - - if (serial_paranoia_check(info, tty->name, "cy_wait_until_sent")) - return; - - if (info->xmit_fifo_size == 0) - return; /* Just in case.... */ - - orig_jiffies = jiffies; - /* - * Set the check interval to be 1/5 of the estimated time to - * send a single character, and make it at least 1. The check - * interval should also be less than the timeout. - * - * Note: we have to use pretty tight timings here to satisfy - * the NIST-PCTS. - */ - char_time = (info->timeout - HZ / 50) / info->xmit_fifo_size; - char_time = char_time / 5; - if (char_time <= 0) - char_time = 1; - if (timeout < 0) - timeout = 0; - if (timeout) - char_time = min(char_time, timeout); - /* - * If the transmitter hasn't cleared in twice the approximate - * amount of time to send the entire FIFO, it probably won't - * ever clear. This assumes the UART isn't doing flow - * control, which is currently the case. Hence, if it ever - * takes longer than info->timeout, this is probably due to a - * UART bug of some kind. So, we clamp the timeout parameter at - * 2*info->timeout. - */ - if (!timeout || timeout > 2 * info->timeout) - timeout = 2 * info->timeout; -#ifdef CY_DEBUG_WAIT_UNTIL_SENT - printk(KERN_DEBUG "In cy_wait_until_sent(%d) check=%d, jiff=%lu...", - timeout, char_time, jiffies); -#endif - card = info->card; - if (!cy_is_Z(card)) { - while (cyy_readb(info, CySRER) & CyTxRdy) { -#ifdef CY_DEBUG_WAIT_UNTIL_SENT - printk(KERN_DEBUG "Not clean (jiff=%lu)...", jiffies); -#endif - if (msleep_interruptible(jiffies_to_msecs(char_time))) - break; - if (timeout && time_after(jiffies, orig_jiffies + - timeout)) - break; - } - } - /* Run one more char cycle */ - msleep_interruptible(jiffies_to_msecs(char_time * 5)); -#ifdef CY_DEBUG_WAIT_UNTIL_SENT - printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies); -#endif -} - -static void cy_flush_buffer(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - struct cyclades_card *card; - int channel, retval; - unsigned long flags; - -#ifdef CY_DEBUG_IO - printk(KERN_DEBUG "cyc:cy_flush_buffer ttyC%d\n", info->line); -#endif - - if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) - return; - - card = info->card; - channel = info->line - card->first_line; - - spin_lock_irqsave(&card->card_lock, flags); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - spin_unlock_irqrestore(&card->card_lock, flags); - - if (cy_is_Z(card)) { /* If it is a Z card, flush the on-board - buffers as well */ - spin_lock_irqsave(&card->card_lock, flags); - retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_TX, 0L); - if (retval != 0) { - printk(KERN_ERR "cyc: flush_buffer retval on ttyC%d " - "was %x\n", info->line, retval); - } - spin_unlock_irqrestore(&card->card_lock, flags); - } - tty_wakeup(tty); -} /* cy_flush_buffer */ - - -static void cy_do_close(struct tty_port *port) -{ - struct cyclades_port *info = container_of(port, struct cyclades_port, - port); - struct cyclades_card *card; - unsigned long flags; - int channel; - - card = info->card; - channel = info->line - card->first_line; - spin_lock_irqsave(&card->card_lock, flags); - - if (!cy_is_Z(card)) { - /* Stop accepting input */ - cyy_writeb(info, CyCAR, channel & 0x03); - cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyRxData); - if (info->port.flags & ASYNC_INITIALIZED) { - /* Waiting for on-board buffers to be empty before - closing the port */ - spin_unlock_irqrestore(&card->card_lock, flags); - cy_wait_until_sent(port->tty, info->timeout); - spin_lock_irqsave(&card->card_lock, flags); - } - } else { -#ifdef Z_WAKE - /* Waiting for on-board buffers to be empty before closing - the port */ - struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl; - int retval; - - if (readl(&ch_ctrl->flow_status) != C_FS_TXIDLE) { - retval = cyz_issue_cmd(card, channel, C_CM_IOCTLW, 0L); - if (retval != 0) { - printk(KERN_DEBUG "cyc:cy_close retval on " - "ttyC%d was %x\n", info->line, retval); - } - spin_unlock_irqrestore(&card->card_lock, flags); - wait_for_completion_interruptible(&info->shutdown_wait); - spin_lock_irqsave(&card->card_lock, flags); - } -#endif - } - spin_unlock_irqrestore(&card->card_lock, flags); - cy_shutdown(info, port->tty); -} - -/* - * This routine is called when a particular tty device is closed. - */ -static void cy_close(struct tty_struct *tty, struct file *filp) -{ - struct cyclades_port *info = tty->driver_data; - if (!info || serial_paranoia_check(info, tty->name, "cy_close")) - return; - tty_port_close(&info->port, tty, filp); -} /* cy_close */ - -/* This routine gets called when tty_write has put something into - * the write_queue. The characters may come from user space or - * kernel space. - * - * This routine will return the number of characters actually - * accepted for writing. - * - * If the port is not already transmitting stuff, start it off by - * enabling interrupts. The interrupt service routine will then - * ensure that the characters are sent. - * If the port is already active, there is no need to kick it. - * - */ -static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) -{ - struct cyclades_port *info = tty->driver_data; - unsigned long flags; - int c, ret = 0; - -#ifdef CY_DEBUG_IO - printk(KERN_DEBUG "cyc:cy_write ttyC%d\n", info->line); -#endif - - if (serial_paranoia_check(info, tty->name, "cy_write")) - return 0; - - if (!info->port.xmit_buf) - return 0; - - spin_lock_irqsave(&info->card->card_lock, flags); - while (1) { - c = min(count, (int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1)); - c = min(c, (int)(SERIAL_XMIT_SIZE - info->xmit_head)); - - if (c <= 0) - break; - - memcpy(info->port.xmit_buf + info->xmit_head, buf, c); - info->xmit_head = (info->xmit_head + c) & - (SERIAL_XMIT_SIZE - 1); - info->xmit_cnt += c; - buf += c; - count -= c; - ret += c; - } - spin_unlock_irqrestore(&info->card->card_lock, flags); - - info->idle_stats.xmit_bytes += ret; - info->idle_stats.xmit_idle = jiffies; - - if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) - start_xmit(info); - - return ret; -} /* cy_write */ - -/* - * This routine is called by the kernel to write a single - * character to the tty device. If the kernel uses this routine, - * it must call the flush_chars() routine (if defined) when it is - * done stuffing characters into the driver. If there is no room - * in the queue, the character is ignored. - */ -static int cy_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct cyclades_port *info = tty->driver_data; - unsigned long flags; - -#ifdef CY_DEBUG_IO - printk(KERN_DEBUG "cyc:cy_put_char ttyC%d\n", info->line); -#endif - - if (serial_paranoia_check(info, tty->name, "cy_put_char")) - return 0; - - if (!info->port.xmit_buf) - return 0; - - spin_lock_irqsave(&info->card->card_lock, flags); - if (info->xmit_cnt >= (int)(SERIAL_XMIT_SIZE - 1)) { - spin_unlock_irqrestore(&info->card->card_lock, flags); - return 0; - } - - info->port.xmit_buf[info->xmit_head++] = ch; - info->xmit_head &= SERIAL_XMIT_SIZE - 1; - info->xmit_cnt++; - info->idle_stats.xmit_bytes++; - info->idle_stats.xmit_idle = jiffies; - spin_unlock_irqrestore(&info->card->card_lock, flags); - return 1; -} /* cy_put_char */ - -/* - * This routine is called by the kernel after it has written a - * series of characters to the tty device using put_char(). - */ -static void cy_flush_chars(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - -#ifdef CY_DEBUG_IO - printk(KERN_DEBUG "cyc:cy_flush_chars ttyC%d\n", info->line); -#endif - - if (serial_paranoia_check(info, tty->name, "cy_flush_chars")) - return; - - if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || - !info->port.xmit_buf) - return; - - start_xmit(info); -} /* cy_flush_chars */ - -/* - * This routine returns the numbers of characters the tty driver - * will accept for queuing to be written. This number is subject - * to change as output buffers get emptied, or if the output flow - * control is activated. - */ -static int cy_write_room(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - int ret; - -#ifdef CY_DEBUG_IO - printk(KERN_DEBUG "cyc:cy_write_room ttyC%d\n", info->line); -#endif - - if (serial_paranoia_check(info, tty->name, "cy_write_room")) - return 0; - ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; - if (ret < 0) - ret = 0; - return ret; -} /* cy_write_room */ - -static int cy_chars_in_buffer(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer")) - return 0; - -#ifdef Z_EXT_CHARS_IN_BUFFER - if (!cy_is_Z(info->card)) { -#endif /* Z_EXT_CHARS_IN_BUFFER */ -#ifdef CY_DEBUG_IO - printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n", - info->line, info->xmit_cnt); -#endif - return info->xmit_cnt; -#ifdef Z_EXT_CHARS_IN_BUFFER - } else { - struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl; - int char_count; - __u32 tx_put, tx_get, tx_bufsize; - - tx_get = readl(&buf_ctrl->tx_get); - tx_put = readl(&buf_ctrl->tx_put); - tx_bufsize = readl(&buf_ctrl->tx_bufsize); - if (tx_put >= tx_get) - char_count = tx_put - tx_get; - else - char_count = tx_put - tx_get + tx_bufsize; -#ifdef CY_DEBUG_IO - printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n", - info->line, info->xmit_cnt + char_count); -#endif - return info->xmit_cnt + char_count; - } -#endif /* Z_EXT_CHARS_IN_BUFFER */ -} /* cy_chars_in_buffer */ - -/* - * ------------------------------------------------------------ - * cy_ioctl() and friends - * ------------------------------------------------------------ - */ - -static void cyy_baud_calc(struct cyclades_port *info, __u32 baud) -{ - int co, co_val, bpr; - __u32 cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 : - 25000000); - - if (baud == 0) { - info->tbpr = info->tco = info->rbpr = info->rco = 0; - return; - } - - /* determine which prescaler to use */ - for (co = 4, co_val = 2048; co; co--, co_val >>= 2) { - if (cy_clock / co_val / baud > 63) - break; - } - - bpr = (cy_clock / co_val * 2 / baud + 1) / 2; - if (bpr > 255) - bpr = 255; - - info->tbpr = info->rbpr = bpr; - info->tco = info->rco = co; -} - -/* - * This routine finds or computes the various line characteristics. - * It used to be called config_setup - */ -static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty) -{ - struct cyclades_card *card; - unsigned long flags; - int channel; - unsigned cflag, iflag; - int baud, baud_rate = 0; - int i; - - if (!tty->termios) /* XXX can this happen at all? */ - return; - - if (info->line == -1) - return; - - cflag = tty->termios->c_cflag; - iflag = tty->termios->c_iflag; - - /* - * Set up the tty->alt_speed kludge - */ - if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - tty->alt_speed = 57600; - if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - tty->alt_speed = 115200; - if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - tty->alt_speed = 230400; - if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - tty->alt_speed = 460800; - - card = info->card; - channel = info->line - card->first_line; - - if (!cy_is_Z(card)) { - u32 cflags; - - /* baud rate */ - baud = tty_get_baud_rate(tty); - if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) == - ASYNC_SPD_CUST) { - if (info->custom_divisor) - baud_rate = info->baud / info->custom_divisor; - else - baud_rate = info->baud; - } else if (baud > CD1400_MAX_SPEED) { - baud = CD1400_MAX_SPEED; - } - /* find the baud index */ - for (i = 0; i < 20; i++) { - if (baud == baud_table[i]) - break; - } - if (i == 20) - i = 19; /* CD1400_MAX_SPEED */ - - if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) == - ASYNC_SPD_CUST) { - cyy_baud_calc(info, baud_rate); - } else { - if (info->chip_rev >= CD1400_REV_J) { - /* It is a CD1400 rev. J or later */ - info->tbpr = baud_bpr_60[i]; /* Tx BPR */ - info->tco = baud_co_60[i]; /* Tx CO */ - info->rbpr = baud_bpr_60[i]; /* Rx BPR */ - info->rco = baud_co_60[i]; /* Rx CO */ - } else { - info->tbpr = baud_bpr_25[i]; /* Tx BPR */ - info->tco = baud_co_25[i]; /* Tx CO */ - info->rbpr = baud_bpr_25[i]; /* Rx BPR */ - info->rco = baud_co_25[i]; /* Rx CO */ - } - } - if (baud_table[i] == 134) { - /* get it right for 134.5 baud */ - info->timeout = (info->xmit_fifo_size * HZ * 30 / 269) + - 2; - } else if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) == - ASYNC_SPD_CUST) { - info->timeout = (info->xmit_fifo_size * HZ * 15 / - baud_rate) + 2; - } else if (baud_table[i]) { - info->timeout = (info->xmit_fifo_size * HZ * 15 / - baud_table[i]) + 2; - /* this needs to be propagated into the card info */ - } else { - info->timeout = 0; - } - /* By tradition (is it a standard?) a baud rate of zero - implies the line should be/has been closed. A bit - later in this routine such a test is performed. */ - - /* byte size and parity */ - info->cor5 = 0; - info->cor4 = 0; - /* receive threshold */ - info->cor3 = (info->default_threshold ? - info->default_threshold : baud_cor3[i]); - info->cor2 = CyETC; - switch (cflag & CSIZE) { - case CS5: - info->cor1 = Cy_5_BITS; - break; - case CS6: - info->cor1 = Cy_6_BITS; - break; - case CS7: - info->cor1 = Cy_7_BITS; - break; - case CS8: - info->cor1 = Cy_8_BITS; - break; - } - if (cflag & CSTOPB) - info->cor1 |= Cy_2_STOP; - - if (cflag & PARENB) { - if (cflag & PARODD) - info->cor1 |= CyPARITY_O; - else - info->cor1 |= CyPARITY_E; - } else - info->cor1 |= CyPARITY_NONE; - - /* CTS flow control flag */ - if (cflag & CRTSCTS) { - info->port.flags |= ASYNC_CTS_FLOW; - info->cor2 |= CyCtsAE; - } else { - info->port.flags &= ~ASYNC_CTS_FLOW; - info->cor2 &= ~CyCtsAE; - } - if (cflag & CLOCAL) - info->port.flags &= ~ASYNC_CHECK_CD; - else - info->port.flags |= ASYNC_CHECK_CD; - - /*********************************************** - The hardware option, CyRtsAO, presents RTS when - the chip has characters to send. Since most modems - use RTS as reverse (inbound) flow control, this - option is not used. If inbound flow control is - necessary, DTR can be programmed to provide the - appropriate signals for use with a non-standard - cable. Contact Marcio Saito for details. - ***********************************************/ - - channel &= 0x03; - - spin_lock_irqsave(&card->card_lock, flags); - cyy_writeb(info, CyCAR, channel); - - /* tx and rx baud rate */ - - cyy_writeb(info, CyTCOR, info->tco); - cyy_writeb(info, CyTBPR, info->tbpr); - cyy_writeb(info, CyRCOR, info->rco); - cyy_writeb(info, CyRBPR, info->rbpr); - - /* set line characteristics according configuration */ - - cyy_writeb(info, CySCHR1, START_CHAR(tty)); - cyy_writeb(info, CySCHR2, STOP_CHAR(tty)); - cyy_writeb(info, CyCOR1, info->cor1); - cyy_writeb(info, CyCOR2, info->cor2); - cyy_writeb(info, CyCOR3, info->cor3); - cyy_writeb(info, CyCOR4, info->cor4); - cyy_writeb(info, CyCOR5, info->cor5); - - cyy_issue_cmd(info, CyCOR_CHANGE | CyCOR1ch | CyCOR2ch | - CyCOR3ch); - - /* !!! Is this needed? */ - cyy_writeb(info, CyCAR, channel); - cyy_writeb(info, CyRTPR, - (info->default_timeout ? info->default_timeout : 0x02)); - /* 10ms rx timeout */ - - cflags = CyCTS; - if (!C_CLOCAL(tty)) - cflags |= CyDSR | CyRI | CyDCD; - /* without modem intr */ - cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyMdmCh); - /* act on 1->0 modem transitions */ - if ((cflag & CRTSCTS) && info->rflow) - cyy_writeb(info, CyMCOR1, cflags | rflow_thr[i]); - else - cyy_writeb(info, CyMCOR1, cflags); - /* act on 0->1 modem transitions */ - cyy_writeb(info, CyMCOR2, cflags); - - if (i == 0) /* baud rate is zero, turn off line */ - cyy_change_rts_dtr(info, 0, TIOCM_DTR); - else - cyy_change_rts_dtr(info, TIOCM_DTR, 0); - - clear_bit(TTY_IO_ERROR, &tty->flags); - spin_unlock_irqrestore(&card->card_lock, flags); - - } else { - struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl; - __u32 sw_flow; - int retval; - - if (!cyz_is_loaded(card)) - return; - - /* baud rate */ - baud = tty_get_baud_rate(tty); - if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) == - ASYNC_SPD_CUST) { - if (info->custom_divisor) - baud_rate = info->baud / info->custom_divisor; - else - baud_rate = info->baud; - } else if (baud > CYZ_MAX_SPEED) { - baud = CYZ_MAX_SPEED; - } - cy_writel(&ch_ctrl->comm_baud, baud); - - if (baud == 134) { - /* get it right for 134.5 baud */ - info->timeout = (info->xmit_fifo_size * HZ * 30 / 269) + - 2; - } else if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) == - ASYNC_SPD_CUST) { - info->timeout = (info->xmit_fifo_size * HZ * 15 / - baud_rate) + 2; - } else if (baud) { - info->timeout = (info->xmit_fifo_size * HZ * 15 / - baud) + 2; - /* this needs to be propagated into the card info */ - } else { - info->timeout = 0; - } - - /* byte size and parity */ - switch (cflag & CSIZE) { - case CS5: - cy_writel(&ch_ctrl->comm_data_l, C_DL_CS5); - break; - case CS6: - cy_writel(&ch_ctrl->comm_data_l, C_DL_CS6); - break; - case CS7: - cy_writel(&ch_ctrl->comm_data_l, C_DL_CS7); - break; - case CS8: - cy_writel(&ch_ctrl->comm_data_l, C_DL_CS8); - break; - } - if (cflag & CSTOPB) { - cy_writel(&ch_ctrl->comm_data_l, - readl(&ch_ctrl->comm_data_l) | C_DL_2STOP); - } else { - cy_writel(&ch_ctrl->comm_data_l, - readl(&ch_ctrl->comm_data_l) | C_DL_1STOP); - } - if (cflag & PARENB) { - if (cflag & PARODD) - cy_writel(&ch_ctrl->comm_parity, C_PR_ODD); - else - cy_writel(&ch_ctrl->comm_parity, C_PR_EVEN); - } else - cy_writel(&ch_ctrl->comm_parity, C_PR_NONE); - - /* CTS flow control flag */ - if (cflag & CRTSCTS) { - cy_writel(&ch_ctrl->hw_flow, - readl(&ch_ctrl->hw_flow) | C_RS_CTS | C_RS_RTS); - } else { - cy_writel(&ch_ctrl->hw_flow, readl(&ch_ctrl->hw_flow) & - ~(C_RS_CTS | C_RS_RTS)); - } - /* As the HW flow control is done in firmware, the driver - doesn't need to care about it */ - info->port.flags &= ~ASYNC_CTS_FLOW; - - /* XON/XOFF/XANY flow control flags */ - sw_flow = 0; - if (iflag & IXON) { - sw_flow |= C_FL_OXX; - if (iflag & IXANY) - sw_flow |= C_FL_OIXANY; - } - cy_writel(&ch_ctrl->sw_flow, sw_flow); - - retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L); - if (retval != 0) { - printk(KERN_ERR "cyc:set_line_char retval on ttyC%d " - "was %x\n", info->line, retval); - } - - /* CD sensitivity */ - if (cflag & CLOCAL) - info->port.flags &= ~ASYNC_CHECK_CD; - else - info->port.flags |= ASYNC_CHECK_CD; - - if (baud == 0) { /* baud rate is zero, turn off line */ - cy_writel(&ch_ctrl->rs_control, - readl(&ch_ctrl->rs_control) & ~C_RS_DTR); -#ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc:set_line_char dropping Z DTR\n"); -#endif - } else { - cy_writel(&ch_ctrl->rs_control, - readl(&ch_ctrl->rs_control) | C_RS_DTR); -#ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc:set_line_char raising Z DTR\n"); -#endif - } - - retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L); - if (retval != 0) { - printk(KERN_ERR "cyc:set_line_char(2) retval on ttyC%d " - "was %x\n", info->line, retval); - } - - clear_bit(TTY_IO_ERROR, &tty->flags); - } -} /* set_line_char */ - -static int cy_get_serial_info(struct cyclades_port *info, - struct serial_struct __user *retinfo) -{ - struct cyclades_card *cinfo = info->card; - struct serial_struct tmp = { - .type = info->type, - .line = info->line, - .port = (info->card - cy_card) * 0x100 + info->line - - cinfo->first_line, - .irq = cinfo->irq, - .flags = info->port.flags, - .close_delay = info->port.close_delay, - .closing_wait = info->port.closing_wait, - .baud_base = info->baud, - .custom_divisor = info->custom_divisor, - .hub6 = 0, /*!!! */ - }; - return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; -} - -static int -cy_set_serial_info(struct cyclades_port *info, struct tty_struct *tty, - struct serial_struct __user *new_info) -{ - struct serial_struct new_serial; - int ret; - - if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) - return -EFAULT; - - mutex_lock(&info->port.mutex); - if (!capable(CAP_SYS_ADMIN)) { - if (new_serial.close_delay != info->port.close_delay || - new_serial.baud_base != info->baud || - (new_serial.flags & ASYNC_FLAGS & - ~ASYNC_USR_MASK) != - (info->port.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)) - { - mutex_unlock(&info->port.mutex); - return -EPERM; - } - info->port.flags = (info->port.flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK); - info->baud = new_serial.baud_base; - info->custom_divisor = new_serial.custom_divisor; - goto check_and_exit; - } - - /* - * OK, past this point, all the error checking has been done. - * At this point, we start making changes..... - */ - - info->baud = new_serial.baud_base; - info->custom_divisor = new_serial.custom_divisor; - info->port.flags = (info->port.flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS); - info->port.close_delay = new_serial.close_delay * HZ / 100; - info->port.closing_wait = new_serial.closing_wait * HZ / 100; - -check_and_exit: - if (info->port.flags & ASYNC_INITIALIZED) { - cy_set_line_char(info, tty); - ret = 0; - } else { - ret = cy_startup(info, tty); - } - mutex_unlock(&info->port.mutex); - return ret; -} /* set_serial_info */ - -/* - * get_lsr_info - get line status register info - * - * Purpose: Let user call ioctl() to get info when the UART physically - * is emptied. On bus types like RS485, the transmitter must - * release the bus after transmitting. This must be done when - * the transmit shift register is empty, not be done when the - * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. - */ -static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value) -{ - struct cyclades_card *card = info->card; - unsigned int result; - unsigned long flags; - u8 status; - - if (!cy_is_Z(card)) { - spin_lock_irqsave(&card->card_lock, flags); - status = cyy_readb(info, CySRER) & (CyTxRdy | CyTxMpty); - spin_unlock_irqrestore(&card->card_lock, flags); - result = (status ? 0 : TIOCSER_TEMT); - } else { - /* Not supported yet */ - return -EINVAL; - } - return put_user(result, (unsigned long __user *)value); -} - -static int cy_tiocmget(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - struct cyclades_card *card; - int result; - - if (serial_paranoia_check(info, tty->name, __func__)) - return -ENODEV; - - card = info->card; - - if (!cy_is_Z(card)) { - unsigned long flags; - int channel = info->line - card->first_line; - u8 status; - - spin_lock_irqsave(&card->card_lock, flags); - cyy_writeb(info, CyCAR, channel & 0x03); - status = cyy_readb(info, CyMSVR1); - status |= cyy_readb(info, CyMSVR2); - spin_unlock_irqrestore(&card->card_lock, flags); - - if (info->rtsdtr_inv) { - result = ((status & CyRTS) ? TIOCM_DTR : 0) | - ((status & CyDTR) ? TIOCM_RTS : 0); - } else { - result = ((status & CyRTS) ? TIOCM_RTS : 0) | - ((status & CyDTR) ? TIOCM_DTR : 0); - } - result |= ((status & CyDCD) ? TIOCM_CAR : 0) | - ((status & CyRI) ? TIOCM_RNG : 0) | - ((status & CyDSR) ? TIOCM_DSR : 0) | - ((status & CyCTS) ? TIOCM_CTS : 0); - } else { - u32 lstatus; - - if (!cyz_is_loaded(card)) { - result = -ENODEV; - goto end; - } - - lstatus = readl(&info->u.cyz.ch_ctrl->rs_status); - result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) | - ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) | - ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) | - ((lstatus & C_RS_RI) ? TIOCM_RNG : 0) | - ((lstatus & C_RS_DSR) ? TIOCM_DSR : 0) | - ((lstatus & C_RS_CTS) ? TIOCM_CTS : 0); - } -end: - return result; -} /* cy_tiomget */ - -static int -cy_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct cyclades_port *info = tty->driver_data; - struct cyclades_card *card; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, __func__)) - return -ENODEV; - - card = info->card; - if (!cy_is_Z(card)) { - spin_lock_irqsave(&card->card_lock, flags); - cyy_change_rts_dtr(info, set, clear); - spin_unlock_irqrestore(&card->card_lock, flags); - } else { - struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl; - int retval, channel = info->line - card->first_line; - u32 rs; - - if (!cyz_is_loaded(card)) - return -ENODEV; - - spin_lock_irqsave(&card->card_lock, flags); - rs = readl(&ch_ctrl->rs_control); - if (set & TIOCM_RTS) - rs |= C_RS_RTS; - if (clear & TIOCM_RTS) - rs &= ~C_RS_RTS; - if (set & TIOCM_DTR) { - rs |= C_RS_DTR; -#ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc:set_modem_info raising Z DTR\n"); -#endif - } - if (clear & TIOCM_DTR) { - rs &= ~C_RS_DTR; -#ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc:set_modem_info clearing " - "Z DTR\n"); -#endif - } - cy_writel(&ch_ctrl->rs_control, rs); - retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L); - spin_unlock_irqrestore(&card->card_lock, flags); - if (retval != 0) { - printk(KERN_ERR "cyc:set_modem_info retval on ttyC%d " - "was %x\n", info->line, retval); - } - } - return 0; -} - -/* - * cy_break() --- routine which turns the break handling on or off - */ -static int cy_break(struct tty_struct *tty, int break_state) -{ - struct cyclades_port *info = tty->driver_data; - struct cyclades_card *card; - unsigned long flags; - int retval = 0; - - if (serial_paranoia_check(info, tty->name, "cy_break")) - return -EINVAL; - - card = info->card; - - spin_lock_irqsave(&card->card_lock, flags); - if (!cy_is_Z(card)) { - /* Let the transmit ISR take care of this (since it - requires stuffing characters into the output stream). - */ - if (break_state == -1) { - if (!info->breakon) { - info->breakon = 1; - if (!info->xmit_cnt) { - spin_unlock_irqrestore(&card->card_lock, flags); - start_xmit(info); - spin_lock_irqsave(&card->card_lock, flags); - } - } - } else { - if (!info->breakoff) { - info->breakoff = 1; - if (!info->xmit_cnt) { - spin_unlock_irqrestore(&card->card_lock, flags); - start_xmit(info); - spin_lock_irqsave(&card->card_lock, flags); - } - } - } - } else { - if (break_state == -1) { - retval = cyz_issue_cmd(card, - info->line - card->first_line, - C_CM_SET_BREAK, 0L); - if (retval != 0) { - printk(KERN_ERR "cyc:cy_break (set) retval on " - "ttyC%d was %x\n", info->line, retval); - } - } else { - retval = cyz_issue_cmd(card, - info->line - card->first_line, - C_CM_CLR_BREAK, 0L); - if (retval != 0) { - printk(KERN_DEBUG "cyc:cy_break (clr) retval " - "on ttyC%d was %x\n", info->line, - retval); - } - } - } - spin_unlock_irqrestore(&card->card_lock, flags); - return retval; -} /* cy_break */ - -static int set_threshold(struct cyclades_port *info, unsigned long value) -{ - struct cyclades_card *card = info->card; - unsigned long flags; - - if (!cy_is_Z(card)) { - info->cor3 &= ~CyREC_FIFO; - info->cor3 |= value & CyREC_FIFO; - - spin_lock_irqsave(&card->card_lock, flags); - cyy_writeb(info, CyCOR3, info->cor3); - cyy_issue_cmd(info, CyCOR_CHANGE | CyCOR3ch); - spin_unlock_irqrestore(&card->card_lock, flags); - } - return 0; -} /* set_threshold */ - -static int get_threshold(struct cyclades_port *info, - unsigned long __user *value) -{ - struct cyclades_card *card = info->card; - - if (!cy_is_Z(card)) { - u8 tmp = cyy_readb(info, CyCOR3) & CyREC_FIFO; - return put_user(tmp, value); - } - return 0; -} /* get_threshold */ - -static int set_timeout(struct cyclades_port *info, unsigned long value) -{ - struct cyclades_card *card = info->card; - unsigned long flags; - - if (!cy_is_Z(card)) { - spin_lock_irqsave(&card->card_lock, flags); - cyy_writeb(info, CyRTPR, value & 0xff); - spin_unlock_irqrestore(&card->card_lock, flags); - } - return 0; -} /* set_timeout */ - -static int get_timeout(struct cyclades_port *info, - unsigned long __user *value) -{ - struct cyclades_card *card = info->card; - - if (!cy_is_Z(card)) { - u8 tmp = cyy_readb(info, CyRTPR); - return put_user(tmp, value); - } - return 0; -} /* get_timeout */ - -static int cy_cflags_changed(struct cyclades_port *info, unsigned long arg, - struct cyclades_icount *cprev) -{ - struct cyclades_icount cnow; - unsigned long flags; - int ret; - - spin_lock_irqsave(&info->card->card_lock, flags); - cnow = info->icount; /* atomic copy */ - spin_unlock_irqrestore(&info->card->card_lock, flags); - - ret = ((arg & TIOCM_RNG) && (cnow.rng != cprev->rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev->dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev->dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev->cts)); - - *cprev = cnow; - - return ret; -} - -/* - * This routine allows the tty driver to implement device- - * specific ioctl's. If the ioctl number passed in cmd is - * not recognized by the driver, it should return ENOIOCTLCMD. - */ -static int -cy_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct cyclades_port *info = tty->driver_data; - struct cyclades_icount cnow; /* kernel counter temps */ - int ret_val = 0; - unsigned long flags; - void __user *argp = (void __user *)arg; - - if (serial_paranoia_check(info, tty->name, "cy_ioctl")) - return -ENODEV; - -#ifdef CY_DEBUG_OTHER - printk(KERN_DEBUG "cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n", - info->line, cmd, arg); -#endif - - switch (cmd) { - case CYGETMON: - if (copy_to_user(argp, &info->mon, sizeof(info->mon))) { - ret_val = -EFAULT; - break; - } - memset(&info->mon, 0, sizeof(info->mon)); - break; - case CYGETTHRESH: - ret_val = get_threshold(info, argp); - break; - case CYSETTHRESH: - ret_val = set_threshold(info, arg); - break; - case CYGETDEFTHRESH: - ret_val = put_user(info->default_threshold, - (unsigned long __user *)argp); - break; - case CYSETDEFTHRESH: - info->default_threshold = arg & 0x0f; - break; - case CYGETTIMEOUT: - ret_val = get_timeout(info, argp); - break; - case CYSETTIMEOUT: - ret_val = set_timeout(info, arg); - break; - case CYGETDEFTIMEOUT: - ret_val = put_user(info->default_timeout, - (unsigned long __user *)argp); - break; - case CYSETDEFTIMEOUT: - info->default_timeout = arg & 0xff; - break; - case CYSETRFLOW: - info->rflow = (int)arg; - break; - case CYGETRFLOW: - ret_val = info->rflow; - break; - case CYSETRTSDTR_INV: - info->rtsdtr_inv = (int)arg; - break; - case CYGETRTSDTR_INV: - ret_val = info->rtsdtr_inv; - break; - case CYGETCD1400VER: - ret_val = info->chip_rev; - break; -#ifndef CONFIG_CYZ_INTR - case CYZSETPOLLCYCLE: - cyz_polling_cycle = (arg * HZ) / 1000; - break; - case CYZGETPOLLCYCLE: - ret_val = (cyz_polling_cycle * 1000) / HZ; - break; -#endif /* CONFIG_CYZ_INTR */ - case CYSETWAIT: - info->port.closing_wait = (unsigned short)arg * HZ / 100; - break; - case CYGETWAIT: - ret_val = info->port.closing_wait / (HZ / 100); - break; - case TIOCGSERIAL: - ret_val = cy_get_serial_info(info, argp); - break; - case TIOCSSERIAL: - ret_val = cy_set_serial_info(info, tty, argp); - break; - case TIOCSERGETLSR: /* Get line status register */ - ret_val = get_lsr_info(info, argp); - break; - /* - * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - * - mask passed in arg for lines of interest - * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) - * Caller should use TIOCGICOUNT to see which one it was - */ - case TIOCMIWAIT: - spin_lock_irqsave(&info->card->card_lock, flags); - /* note the counters on entry */ - cnow = info->icount; - spin_unlock_irqrestore(&info->card->card_lock, flags); - ret_val = wait_event_interruptible(info->port.delta_msr_wait, - cy_cflags_changed(info, arg, &cnow)); - break; - - /* - * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) - * Return: write counters to the user passed counter struct - * NB: both 1->0 and 0->1 transitions are counted except for - * RI where only 0->1 is counted. - */ - default: - ret_val = -ENOIOCTLCMD; - } - -#ifdef CY_DEBUG_OTHER - printk(KERN_DEBUG "cyc:cy_ioctl done\n"); -#endif - return ret_val; -} /* cy_ioctl */ - -static int cy_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *sic) -{ - struct cyclades_port *info = tty->driver_data; - struct cyclades_icount cnow; /* Used to snapshot */ - unsigned long flags; - - spin_lock_irqsave(&info->card->card_lock, flags); - cnow = info->icount; - spin_unlock_irqrestore(&info->card->card_lock, flags); - - sic->cts = cnow.cts; - sic->dsr = cnow.dsr; - sic->rng = cnow.rng; - sic->dcd = cnow.dcd; - sic->rx = cnow.rx; - sic->tx = cnow.tx; - sic->frame = cnow.frame; - sic->overrun = cnow.overrun; - sic->parity = cnow.parity; - sic->brk = cnow.brk; - sic->buf_overrun = cnow.buf_overrun; - return 0; -} - -/* - * This routine allows the tty driver to be notified when - * device's termios settings have changed. Note that a - * well-designed tty driver should be prepared to accept the case - * where old == NULL, and try to do something rational. - */ -static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) -{ - struct cyclades_port *info = tty->driver_data; - -#ifdef CY_DEBUG_OTHER - printk(KERN_DEBUG "cyc:cy_set_termios ttyC%d\n", info->line); -#endif - - cy_set_line_char(info, tty); - - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - cy_start(tty); - } -#if 0 - /* - * No need to wake up processes in open wait, since they - * sample the CLOCAL flag once, and don't recheck it. - * XXX It's not clear whether the current behavior is correct - * or not. Hence, this may change..... - */ - if (!(old_termios->c_cflag & CLOCAL) && - (tty->termios->c_cflag & CLOCAL)) - wake_up_interruptible(&info->port.open_wait); -#endif -} /* cy_set_termios */ - -/* This function is used to send a high-priority XON/XOFF character to - the device. -*/ -static void cy_send_xchar(struct tty_struct *tty, char ch) -{ - struct cyclades_port *info = tty->driver_data; - struct cyclades_card *card; - int channel; - - if (serial_paranoia_check(info, tty->name, "cy_send_xchar")) - return; - - info->x_char = ch; - - if (ch) - cy_start(tty); - - card = info->card; - channel = info->line - card->first_line; - - if (cy_is_Z(card)) { - if (ch == STOP_CHAR(tty)) - cyz_issue_cmd(card, channel, C_CM_SENDXOFF, 0L); - else if (ch == START_CHAR(tty)) - cyz_issue_cmd(card, channel, C_CM_SENDXON, 0L); - } -} - -/* This routine is called by the upper-layer tty layer to signal - that incoming characters should be throttled because the input - buffers are close to full. - */ -static void cy_throttle(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - struct cyclades_card *card; - unsigned long flags; - -#ifdef CY_DEBUG_THROTTLE - char buf[64]; - - printk(KERN_DEBUG "cyc:throttle %s: %ld...ttyC%d\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty), info->line); -#endif - - if (serial_paranoia_check(info, tty->name, "cy_throttle")) - return; - - card = info->card; - - if (I_IXOFF(tty)) { - if (!cy_is_Z(card)) - cy_send_xchar(tty, STOP_CHAR(tty)); - else - info->throttle = 1; - } - - if (tty->termios->c_cflag & CRTSCTS) { - if (!cy_is_Z(card)) { - spin_lock_irqsave(&card->card_lock, flags); - cyy_change_rts_dtr(info, 0, TIOCM_RTS); - spin_unlock_irqrestore(&card->card_lock, flags); - } else { - info->throttle = 1; - } - } -} /* cy_throttle */ - -/* - * This routine notifies the tty driver that it should signal - * that characters can now be sent to the tty without fear of - * overrunning the input buffers of the line disciplines. - */ -static void cy_unthrottle(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - struct cyclades_card *card; - unsigned long flags; - -#ifdef CY_DEBUG_THROTTLE - char buf[64]; - - printk(KERN_DEBUG "cyc:unthrottle %s: %ld...ttyC%d\n", - tty_name(tty, buf), tty_chars_in_buffer(tty), info->line); -#endif - - if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) - return; - - if (I_IXOFF(tty)) { - if (info->x_char) - info->x_char = 0; - else - cy_send_xchar(tty, START_CHAR(tty)); - } - - if (tty->termios->c_cflag & CRTSCTS) { - card = info->card; - if (!cy_is_Z(card)) { - spin_lock_irqsave(&card->card_lock, flags); - cyy_change_rts_dtr(info, TIOCM_RTS, 0); - spin_unlock_irqrestore(&card->card_lock, flags); - } else { - info->throttle = 0; - } - } -} /* cy_unthrottle */ - -/* cy_start and cy_stop provide software output flow control as a - function of XON/XOFF, software CTS, and other such stuff. -*/ -static void cy_stop(struct tty_struct *tty) -{ - struct cyclades_card *cinfo; - struct cyclades_port *info = tty->driver_data; - int channel; - unsigned long flags; - -#ifdef CY_DEBUG_OTHER - printk(KERN_DEBUG "cyc:cy_stop ttyC%d\n", info->line); -#endif - - if (serial_paranoia_check(info, tty->name, "cy_stop")) - return; - - cinfo = info->card; - channel = info->line - cinfo->first_line; - if (!cy_is_Z(cinfo)) { - spin_lock_irqsave(&cinfo->card_lock, flags); - cyy_writeb(info, CyCAR, channel & 0x03); - cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyTxRdy); - spin_unlock_irqrestore(&cinfo->card_lock, flags); - } -} /* cy_stop */ - -static void cy_start(struct tty_struct *tty) -{ - struct cyclades_card *cinfo; - struct cyclades_port *info = tty->driver_data; - int channel; - unsigned long flags; - -#ifdef CY_DEBUG_OTHER - printk(KERN_DEBUG "cyc:cy_start ttyC%d\n", info->line); -#endif - - if (serial_paranoia_check(info, tty->name, "cy_start")) - return; - - cinfo = info->card; - channel = info->line - cinfo->first_line; - if (!cy_is_Z(cinfo)) { - spin_lock_irqsave(&cinfo->card_lock, flags); - cyy_writeb(info, CyCAR, channel & 0x03); - cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyTxRdy); - spin_unlock_irqrestore(&cinfo->card_lock, flags); - } -} /* cy_start */ - -/* - * cy_hangup() --- called by tty_hangup() when a hangup is signaled. - */ -static void cy_hangup(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - -#ifdef CY_DEBUG_OTHER - printk(KERN_DEBUG "cyc:cy_hangup ttyC%d\n", info->line); -#endif - - if (serial_paranoia_check(info, tty->name, "cy_hangup")) - return; - - cy_flush_buffer(tty); - cy_shutdown(info, tty); - tty_port_hangup(&info->port); -} /* cy_hangup */ - -static int cyy_carrier_raised(struct tty_port *port) -{ - struct cyclades_port *info = container_of(port, struct cyclades_port, - port); - struct cyclades_card *cinfo = info->card; - unsigned long flags; - int channel = info->line - cinfo->first_line; - u32 cd; - - spin_lock_irqsave(&cinfo->card_lock, flags); - cyy_writeb(info, CyCAR, channel & 0x03); - cd = cyy_readb(info, CyMSVR1) & CyDCD; - spin_unlock_irqrestore(&cinfo->card_lock, flags); - - return cd; -} - -static void cyy_dtr_rts(struct tty_port *port, int raise) -{ - struct cyclades_port *info = container_of(port, struct cyclades_port, - port); - struct cyclades_card *cinfo = info->card; - unsigned long flags; - - spin_lock_irqsave(&cinfo->card_lock, flags); - cyy_change_rts_dtr(info, raise ? TIOCM_RTS | TIOCM_DTR : 0, - raise ? 0 : TIOCM_RTS | TIOCM_DTR); - spin_unlock_irqrestore(&cinfo->card_lock, flags); -} - -static int cyz_carrier_raised(struct tty_port *port) -{ - struct cyclades_port *info = container_of(port, struct cyclades_port, - port); - - return readl(&info->u.cyz.ch_ctrl->rs_status) & C_RS_DCD; -} - -static void cyz_dtr_rts(struct tty_port *port, int raise) -{ - struct cyclades_port *info = container_of(port, struct cyclades_port, - port); - struct cyclades_card *cinfo = info->card; - struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl; - int ret, channel = info->line - cinfo->first_line; - u32 rs; - - rs = readl(&ch_ctrl->rs_control); - if (raise) - rs |= C_RS_RTS | C_RS_DTR; - else - rs &= ~(C_RS_RTS | C_RS_DTR); - cy_writel(&ch_ctrl->rs_control, rs); - ret = cyz_issue_cmd(cinfo, channel, C_CM_IOCTLM, 0L); - if (ret != 0) - printk(KERN_ERR "%s: retval on ttyC%d was %x\n", - __func__, info->line, ret); -#ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "%s: raising Z DTR\n", __func__); -#endif -} - -static const struct tty_port_operations cyy_port_ops = { - .carrier_raised = cyy_carrier_raised, - .dtr_rts = cyy_dtr_rts, - .shutdown = cy_do_close, -}; - -static const struct tty_port_operations cyz_port_ops = { - .carrier_raised = cyz_carrier_raised, - .dtr_rts = cyz_dtr_rts, - .shutdown = cy_do_close, -}; - -/* - * --------------------------------------------------------------------- - * cy_init() and friends - * - * cy_init() is called at boot-time to initialize the serial driver. - * --------------------------------------------------------------------- - */ - -static int __devinit cy_init_card(struct cyclades_card *cinfo) -{ - struct cyclades_port *info; - unsigned int channel, port; - - spin_lock_init(&cinfo->card_lock); - cinfo->intr_enabled = 0; - - cinfo->ports = kcalloc(cinfo->nports, sizeof(*cinfo->ports), - GFP_KERNEL); - if (cinfo->ports == NULL) { - printk(KERN_ERR "Cyclades: cannot allocate ports\n"); - return -ENOMEM; - } - - for (channel = 0, port = cinfo->first_line; channel < cinfo->nports; - channel++, port++) { - info = &cinfo->ports[channel]; - tty_port_init(&info->port); - info->magic = CYCLADES_MAGIC; - info->card = cinfo; - info->line = port; - - info->port.closing_wait = CLOSING_WAIT_DELAY; - info->port.close_delay = 5 * HZ / 10; - info->port.flags = STD_COM_FLAGS; - init_completion(&info->shutdown_wait); - - if (cy_is_Z(cinfo)) { - struct FIRM_ID *firm_id = cinfo->base_addr + ID_ADDRESS; - struct ZFW_CTRL *zfw_ctrl; - - info->port.ops = &cyz_port_ops; - info->type = PORT_STARTECH; - - zfw_ctrl = cinfo->base_addr + - (readl(&firm_id->zfwctrl_addr) & 0xfffff); - info->u.cyz.ch_ctrl = &zfw_ctrl->ch_ctrl[channel]; - info->u.cyz.buf_ctrl = &zfw_ctrl->buf_ctrl[channel]; - - if (cinfo->hw_ver == ZO_V1) - info->xmit_fifo_size = CYZ_FIFO_SIZE; - else - info->xmit_fifo_size = 4 * CYZ_FIFO_SIZE; -#ifdef CONFIG_CYZ_INTR - setup_timer(&cyz_rx_full_timer[port], - cyz_rx_restart, (unsigned long)info); -#endif - } else { - unsigned short chip_number; - int index = cinfo->bus_index; - - info->port.ops = &cyy_port_ops; - info->type = PORT_CIRRUS; - info->xmit_fifo_size = CyMAX_CHAR_FIFO; - info->cor1 = CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS; - info->cor2 = CyETC; - info->cor3 = 0x08; /* _very_ small rcv threshold */ - - chip_number = channel / CyPORTS_PER_CHIP; - info->u.cyy.base_addr = cinfo->base_addr + - (cy_chip_offset[chip_number] << index); - info->chip_rev = cyy_readb(info, CyGFRCR); - - if (info->chip_rev >= CD1400_REV_J) { - /* It is a CD1400 rev. J or later */ - info->tbpr = baud_bpr_60[13]; /* Tx BPR */ - info->tco = baud_co_60[13]; /* Tx CO */ - info->rbpr = baud_bpr_60[13]; /* Rx BPR */ - info->rco = baud_co_60[13]; /* Rx CO */ - info->rtsdtr_inv = 1; - } else { - info->tbpr = baud_bpr_25[13]; /* Tx BPR */ - info->tco = baud_co_25[13]; /* Tx CO */ - info->rbpr = baud_bpr_25[13]; /* Rx BPR */ - info->rco = baud_co_25[13]; /* Rx CO */ - info->rtsdtr_inv = 0; - } - info->read_status_mask = CyTIMEOUT | CySPECHAR | - CyBREAK | CyPARITY | CyFRAME | CyOVERRUN; - } - - } - -#ifndef CONFIG_CYZ_INTR - if (cy_is_Z(cinfo) && !timer_pending(&cyz_timerlist)) { - mod_timer(&cyz_timerlist, jiffies + 1); -#ifdef CY_PCI_DEBUG - printk(KERN_DEBUG "Cyclades-Z polling initialized\n"); -#endif - } -#endif - return 0; -} - -/* initialize chips on Cyclom-Y card -- return number of valid - chips (which is number of ports/4) */ -static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr, - int index) -{ - unsigned int chip_number; - void __iomem *base_addr; - - cy_writeb(true_base_addr + (Cy_HwReset << index), 0); - /* Cy_HwReset is 0x1400 */ - cy_writeb(true_base_addr + (Cy_ClrIntr << index), 0); - /* Cy_ClrIntr is 0x1800 */ - udelay(500L); - - for (chip_number = 0; chip_number < CyMAX_CHIPS_PER_CARD; - chip_number++) { - base_addr = - true_base_addr + (cy_chip_offset[chip_number] << index); - mdelay(1); - if (readb(base_addr + (CyCCR << index)) != 0x00) { - /************* - printk(" chip #%d at %#6lx is never idle (CCR != 0)\n", - chip_number, (unsigned long)base_addr); - *************/ - return chip_number; - } - - cy_writeb(base_addr + (CyGFRCR << index), 0); - udelay(10L); - - /* The Cyclom-16Y does not decode address bit 9 and therefore - cannot distinguish between references to chip 0 and a non- - existent chip 4. If the preceding clearing of the supposed - chip 4 GFRCR register appears at chip 0, there is no chip 4 - and this must be a Cyclom-16Y, not a Cyclom-32Ye. - */ - if (chip_number == 4 && readb(true_base_addr + - (cy_chip_offset[0] << index) + - (CyGFRCR << index)) == 0) { - return chip_number; - } - - cy_writeb(base_addr + (CyCCR << index), CyCHIP_RESET); - mdelay(1); - - if (readb(base_addr + (CyGFRCR << index)) == 0x00) { - /* - printk(" chip #%d at %#6lx is not responding ", - chip_number, (unsigned long)base_addr); - printk("(GFRCR stayed 0)\n", - */ - return chip_number; - } - if ((0xf0 & (readb(base_addr + (CyGFRCR << index)))) != - 0x40) { - /* - printk(" chip #%d at %#6lx is not valid (GFRCR == " - "%#2x)\n", - chip_number, (unsigned long)base_addr, - base_addr[CyGFRCR<= CD1400_REV_J) { - /* It is a CD1400 rev. J or later */ - /* Impossible to reach 5ms with this chip. - Changed to 2ms instead (f = 500 Hz). */ - cy_writeb(base_addr + (CyPPR << index), CyCLOCK_60_2MS); - } else { - /* f = 200 Hz */ - cy_writeb(base_addr + (CyPPR << index), CyCLOCK_25_5MS); - } - - /* - printk(" chip #%d at %#6lx is rev 0x%2x\n", - chip_number, (unsigned long)base_addr, - readb(base_addr+(CyGFRCR< NR_PORTS) { - printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no " - "more channels are available. Change NR_PORTS " - "in cyclades.c and recompile kernel.\n", - (unsigned long)cy_isa_address); - iounmap(cy_isa_address); - return nboard; - } - /* fill the next cy_card structure available */ - for (j = 0; j < NR_CARDS; j++) { - if (cy_card[j].base_addr == NULL) - break; - } - if (j == NR_CARDS) { /* no more cy_cards available */ - printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no " - "more cards can be used. Change NR_CARDS in " - "cyclades.c and recompile kernel.\n", - (unsigned long)cy_isa_address); - iounmap(cy_isa_address); - return nboard; - } - - /* allocate IRQ */ - if (request_irq(cy_isa_irq, cyy_interrupt, - IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) { - printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but " - "could not allocate IRQ#%d.\n", - (unsigned long)cy_isa_address, cy_isa_irq); - iounmap(cy_isa_address); - return nboard; - } - - /* set cy_card */ - cy_card[j].base_addr = cy_isa_address; - cy_card[j].ctl_addr.p9050 = NULL; - cy_card[j].irq = (int)cy_isa_irq; - cy_card[j].bus_index = 0; - cy_card[j].first_line = cy_next_channel; - cy_card[j].num_chips = cy_isa_nchan / CyPORTS_PER_CHIP; - cy_card[j].nports = cy_isa_nchan; - if (cy_init_card(&cy_card[j])) { - cy_card[j].base_addr = NULL; - free_irq(cy_isa_irq, &cy_card[j]); - iounmap(cy_isa_address); - continue; - } - nboard++; - - printk(KERN_INFO "Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d found: " - "%d channels starting from port %d\n", - j + 1, (unsigned long)cy_isa_address, - (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)), - cy_isa_irq, cy_isa_nchan, cy_next_channel); - - for (j = cy_next_channel; - j < cy_next_channel + cy_isa_nchan; j++) - tty_register_device(cy_serial_driver, j, NULL); - cy_next_channel += cy_isa_nchan; - } - return nboard; -#else - return 0; -#endif /* CONFIG_ISA */ -} /* cy_detect_isa */ - -#ifdef CONFIG_PCI -static inline int __devinit cyc_isfwstr(const char *str, unsigned int size) -{ - unsigned int a; - - for (a = 0; a < size && *str; a++, str++) - if (*str & 0x80) - return -EINVAL; - - for (; a < size; a++, str++) - if (*str) - return -EINVAL; - - return 0; -} - -static inline void __devinit cyz_fpga_copy(void __iomem *fpga, const u8 *data, - unsigned int size) -{ - for (; size > 0; size--) { - cy_writel(fpga, *data++); - udelay(10); - } -} - -static void __devinit plx_init(struct pci_dev *pdev, int irq, - struct RUNTIME_9060 __iomem *addr) -{ - /* Reset PLX */ - cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) | 0x40000000); - udelay(100L); - cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) & ~0x40000000); - - /* Reload Config. Registers from EEPROM */ - cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) | 0x20000000); - udelay(100L); - cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) & ~0x20000000); - - /* For some yet unknown reason, once the PLX9060 reloads the EEPROM, - * the IRQ is lost and, thus, we have to re-write it to the PCI config. - * registers. This will remain here until we find a permanent fix. - */ - pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq); -} - -static int __devinit __cyz_load_fw(const struct firmware *fw, - const char *name, const u32 mailbox, void __iomem *base, - void __iomem *fpga) -{ - const void *ptr = fw->data; - const struct zfile_header *h = ptr; - const struct zfile_config *c, *cs; - const struct zfile_block *b, *bs; - unsigned int a, tmp, len = fw->size; -#define BAD_FW KERN_ERR "Bad firmware: " - if (len < sizeof(*h)) { - printk(BAD_FW "too short: %u<%zu\n", len, sizeof(*h)); - return -EINVAL; - } - - cs = ptr + h->config_offset; - bs = ptr + h->block_offset; - - if ((void *)(cs + h->n_config) > ptr + len || - (void *)(bs + h->n_blocks) > ptr + len) { - printk(BAD_FW "too short"); - return -EINVAL; - } - - if (cyc_isfwstr(h->name, sizeof(h->name)) || - cyc_isfwstr(h->date, sizeof(h->date))) { - printk(BAD_FW "bad formatted header string\n"); - return -EINVAL; - } - - if (strncmp(name, h->name, sizeof(h->name))) { - printk(BAD_FW "bad name '%s' (expected '%s')\n", h->name, name); - return -EINVAL; - } - - tmp = 0; - for (c = cs; c < cs + h->n_config; c++) { - for (a = 0; a < c->n_blocks; a++) - if (c->block_list[a] > h->n_blocks) { - printk(BAD_FW "bad block ref number in cfgs\n"); - return -EINVAL; - } - if (c->mailbox == mailbox && c->function == 0) /* 0 is normal */ - tmp++; - } - if (!tmp) { - printk(BAD_FW "nothing appropriate\n"); - return -EINVAL; - } - - for (b = bs; b < bs + h->n_blocks; b++) - if (b->file_offset + b->size > len) { - printk(BAD_FW "bad block data offset\n"); - return -EINVAL; - } - - /* everything is OK, let's seek'n'load it */ - for (c = cs; c < cs + h->n_config; c++) - if (c->mailbox == mailbox && c->function == 0) - break; - - for (a = 0; a < c->n_blocks; a++) { - b = &bs[c->block_list[a]]; - if (b->type == ZBLOCK_FPGA) { - if (fpga != NULL) - cyz_fpga_copy(fpga, ptr + b->file_offset, - b->size); - } else { - if (base != NULL) - memcpy_toio(base + b->ram_offset, - ptr + b->file_offset, b->size); - } - } -#undef BAD_FW - return 0; -} - -static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr, - struct RUNTIME_9060 __iomem *ctl_addr, int irq) -{ - const struct firmware *fw; - struct FIRM_ID __iomem *fid = base_addr + ID_ADDRESS; - struct CUSTOM_REG __iomem *cust = base_addr; - struct ZFW_CTRL __iomem *pt_zfwctrl; - void __iomem *tmp; - u32 mailbox, status, nchan; - unsigned int i; - int retval; - - retval = request_firmware(&fw, "cyzfirm.bin", &pdev->dev); - if (retval) { - dev_err(&pdev->dev, "can't get firmware\n"); - goto err; - } - - /* Check whether the firmware is already loaded and running. If - positive, skip this board */ - if (__cyz_fpga_loaded(ctl_addr) && readl(&fid->signature) == ZFIRM_ID) { - u32 cntval = readl(base_addr + 0x190); - - udelay(100); - if (cntval != readl(base_addr + 0x190)) { - /* FW counter is working, FW is running */ - dev_dbg(&pdev->dev, "Cyclades-Z FW already loaded. " - "Skipping board.\n"); - retval = 0; - goto err_rel; - } - } - - /* start boot */ - cy_writel(&ctl_addr->intr_ctrl_stat, readl(&ctl_addr->intr_ctrl_stat) & - ~0x00030800UL); - - mailbox = readl(&ctl_addr->mail_box_0); - - if (mailbox == 0 || __cyz_fpga_loaded(ctl_addr)) { - /* stops CPU and set window to beginning of RAM */ - cy_writel(&ctl_addr->loc_addr_base, WIN_CREG); - cy_writel(&cust->cpu_stop, 0); - cy_writel(&ctl_addr->loc_addr_base, WIN_RAM); - udelay(100); - } - - plx_init(pdev, irq, ctl_addr); - - if (mailbox != 0) { - /* load FPGA */ - retval = __cyz_load_fw(fw, "Cyclom-Z", mailbox, NULL, - base_addr); - if (retval) - goto err_rel; - if (!__cyz_fpga_loaded(ctl_addr)) { - dev_err(&pdev->dev, "fw upload successful, but fw is " - "not loaded\n"); - goto err_rel; - } - } - - /* stops CPU and set window to beginning of RAM */ - cy_writel(&ctl_addr->loc_addr_base, WIN_CREG); - cy_writel(&cust->cpu_stop, 0); - cy_writel(&ctl_addr->loc_addr_base, WIN_RAM); - udelay(100); - - /* clear memory */ - for (tmp = base_addr; tmp < base_addr + RAM_SIZE; tmp++) - cy_writeb(tmp, 255); - if (mailbox != 0) { - /* set window to last 512K of RAM */ - cy_writel(&ctl_addr->loc_addr_base, WIN_RAM + RAM_SIZE); - for (tmp = base_addr; tmp < base_addr + RAM_SIZE; tmp++) - cy_writeb(tmp, 255); - /* set window to beginning of RAM */ - cy_writel(&ctl_addr->loc_addr_base, WIN_RAM); - } - - retval = __cyz_load_fw(fw, "Cyclom-Z", mailbox, base_addr, NULL); - release_firmware(fw); - if (retval) - goto err; - - /* finish boot and start boards */ - cy_writel(&ctl_addr->loc_addr_base, WIN_CREG); - cy_writel(&cust->cpu_start, 0); - cy_writel(&ctl_addr->loc_addr_base, WIN_RAM); - i = 0; - while ((status = readl(&fid->signature)) != ZFIRM_ID && i++ < 40) - msleep(100); - if (status != ZFIRM_ID) { - if (status == ZFIRM_HLT) { - dev_err(&pdev->dev, "you need an external power supply " - "for this number of ports. Firmware halted and " - "board reset.\n"); - retval = -EIO; - goto err; - } - dev_warn(&pdev->dev, "fid->signature = 0x%x... Waiting " - "some more time\n", status); - while ((status = readl(&fid->signature)) != ZFIRM_ID && - i++ < 200) - msleep(100); - if (status != ZFIRM_ID) { - dev_err(&pdev->dev, "Board not started in 20 seconds! " - "Giving up. (fid->signature = 0x%x)\n", - status); - dev_info(&pdev->dev, "*** Warning ***: if you are " - "upgrading the FW, please power cycle the " - "system before loading the new FW to the " - "Cyclades-Z.\n"); - - if (__cyz_fpga_loaded(ctl_addr)) - plx_init(pdev, irq, ctl_addr); - - retval = -EIO; - goto err; - } - dev_dbg(&pdev->dev, "Firmware started after %d seconds.\n", - i / 10); - } - pt_zfwctrl = base_addr + readl(&fid->zfwctrl_addr); - - dev_dbg(&pdev->dev, "fid=> %p, zfwctrl_addr=> %x, npt_zfwctrl=> %p\n", - base_addr + ID_ADDRESS, readl(&fid->zfwctrl_addr), - base_addr + readl(&fid->zfwctrl_addr)); - - nchan = readl(&pt_zfwctrl->board_ctrl.n_channel); - dev_info(&pdev->dev, "Cyclades-Z FW loaded: version = %x, ports = %u\n", - readl(&pt_zfwctrl->board_ctrl.fw_version), nchan); - - if (nchan == 0) { - dev_warn(&pdev->dev, "no Cyclades-Z ports were found. Please " - "check the connection between the Z host card and the " - "serial expanders.\n"); - - if (__cyz_fpga_loaded(ctl_addr)) - plx_init(pdev, irq, ctl_addr); - - dev_info(&pdev->dev, "Null number of ports detected. Board " - "reset.\n"); - retval = 0; - goto err; - } - - cy_writel(&pt_zfwctrl->board_ctrl.op_system, C_OS_LINUX); - cy_writel(&pt_zfwctrl->board_ctrl.dr_version, DRIVER_VERSION); - - /* - Early firmware failed to start looking for commands. - This enables firmware interrupts for those commands. - */ - cy_writel(&ctl_addr->intr_ctrl_stat, readl(&ctl_addr->intr_ctrl_stat) | - (1 << 17)); - cy_writel(&ctl_addr->intr_ctrl_stat, readl(&ctl_addr->intr_ctrl_stat) | - 0x00030800UL); - - return nchan; -err_rel: - release_firmware(fw); -err: - return retval; -} - -static int __devinit cy_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - void __iomem *addr0 = NULL, *addr2 = NULL; - char *card_name = NULL; - u32 uninitialized_var(mailbox); - unsigned int device_id, nchan = 0, card_no, i; - unsigned char plx_ver; - int retval, irq; - - retval = pci_enable_device(pdev); - if (retval) { - dev_err(&pdev->dev, "cannot enable device\n"); - goto err; - } - - /* read PCI configuration area */ - irq = pdev->irq; - device_id = pdev->device & ~PCI_DEVICE_ID_MASK; - -#if defined(__alpha__) - if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */ - dev_err(&pdev->dev, "Cyclom-Y/PCI not supported for low " - "addresses on Alpha systems.\n"); - retval = -EIO; - goto err_dis; - } -#endif - if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) { - dev_err(&pdev->dev, "Cyclades-Z/PCI not supported for low " - "addresses\n"); - retval = -EIO; - goto err_dis; - } - - if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { - dev_warn(&pdev->dev, "PCI I/O bit incorrectly set. Ignoring " - "it...\n"); - pdev->resource[2].flags &= ~IORESOURCE_IO; - } - - retval = pci_request_regions(pdev, "cyclades"); - if (retval) { - dev_err(&pdev->dev, "failed to reserve resources\n"); - goto err_dis; - } - - retval = -EIO; - if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || - device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { - card_name = "Cyclom-Y"; - - addr0 = ioremap_nocache(pci_resource_start(pdev, 0), - CyPCI_Yctl); - if (addr0 == NULL) { - dev_err(&pdev->dev, "can't remap ctl region\n"); - goto err_reg; - } - addr2 = ioremap_nocache(pci_resource_start(pdev, 2), - CyPCI_Ywin); - if (addr2 == NULL) { - dev_err(&pdev->dev, "can't remap base region\n"); - goto err_unmap; - } - - nchan = CyPORTS_PER_CHIP * cyy_init_card(addr2, 1); - if (nchan == 0) { - dev_err(&pdev->dev, "Cyclom-Y PCI host card with no " - "Serial-Modules\n"); - goto err_unmap; - } - } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) { - struct RUNTIME_9060 __iomem *ctl_addr; - - ctl_addr = addr0 = ioremap_nocache(pci_resource_start(pdev, 0), - CyPCI_Zctl); - if (addr0 == NULL) { - dev_err(&pdev->dev, "can't remap ctl region\n"); - goto err_reg; - } - - /* Disable interrupts on the PLX before resetting it */ - cy_writew(&ctl_addr->intr_ctrl_stat, - readw(&ctl_addr->intr_ctrl_stat) & ~0x0900); - - plx_init(pdev, irq, addr0); - - mailbox = readl(&ctl_addr->mail_box_0); - - addr2 = ioremap_nocache(pci_resource_start(pdev, 2), - mailbox == ZE_V1 ? CyPCI_Ze_win : CyPCI_Zwin); - if (addr2 == NULL) { - dev_err(&pdev->dev, "can't remap base region\n"); - goto err_unmap; - } - - if (mailbox == ZE_V1) { - card_name = "Cyclades-Ze"; - } else { - card_name = "Cyclades-8Zo"; -#ifdef CY_PCI_DEBUG - if (mailbox == ZO_V1) { - cy_writel(&ctl_addr->loc_addr_base, WIN_CREG); - dev_info(&pdev->dev, "Cyclades-8Zo/PCI: FPGA " - "id %lx, ver %lx\n", (ulong)(0xff & - readl(&((struct CUSTOM_REG *)addr2)-> - fpga_id)), (ulong)(0xff & - readl(&((struct CUSTOM_REG *)addr2)-> - fpga_version))); - cy_writel(&ctl_addr->loc_addr_base, WIN_RAM); - } else { - dev_info(&pdev->dev, "Cyclades-Z/PCI: New " - "Cyclades-Z board. FPGA not loaded\n"); - } -#endif - /* The following clears the firmware id word. This - ensures that the driver will not attempt to talk to - the board until it has been properly initialized. - */ - if ((mailbox == ZO_V1) || (mailbox == ZO_V2)) - cy_writel(addr2 + ID_ADDRESS, 0L); - } - - retval = cyz_load_fw(pdev, addr2, addr0, irq); - if (retval <= 0) - goto err_unmap; - nchan = retval; - } - - if ((cy_next_channel + nchan) > NR_PORTS) { - dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no " - "channels are available. Change NR_PORTS in " - "cyclades.c and recompile kernel.\n"); - goto err_unmap; - } - /* fill the next cy_card structure available */ - for (card_no = 0; card_no < NR_CARDS; card_no++) { - if (cy_card[card_no].base_addr == NULL) - break; - } - if (card_no == NR_CARDS) { /* no more cy_cards available */ - dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no " - "more cards can be used. Change NR_CARDS in " - "cyclades.c and recompile kernel.\n"); - goto err_unmap; - } - - if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || - device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { - /* allocate IRQ */ - retval = request_irq(irq, cyy_interrupt, - IRQF_SHARED, "Cyclom-Y", &cy_card[card_no]); - if (retval) { - dev_err(&pdev->dev, "could not allocate IRQ\n"); - goto err_unmap; - } - cy_card[card_no].num_chips = nchan / CyPORTS_PER_CHIP; - } else { - struct FIRM_ID __iomem *firm_id = addr2 + ID_ADDRESS; - struct ZFW_CTRL __iomem *zfw_ctrl; - - zfw_ctrl = addr2 + (readl(&firm_id->zfwctrl_addr) & 0xfffff); - - cy_card[card_no].hw_ver = mailbox; - cy_card[card_no].num_chips = (unsigned int)-1; - cy_card[card_no].board_ctrl = &zfw_ctrl->board_ctrl; -#ifdef CONFIG_CYZ_INTR - /* allocate IRQ only if board has an IRQ */ - if (irq != 0 && irq != 255) { - retval = request_irq(irq, cyz_interrupt, - IRQF_SHARED, "Cyclades-Z", - &cy_card[card_no]); - if (retval) { - dev_err(&pdev->dev, "could not allocate IRQ\n"); - goto err_unmap; - } - } -#endif /* CONFIG_CYZ_INTR */ - } - - /* set cy_card */ - cy_card[card_no].base_addr = addr2; - cy_card[card_no].ctl_addr.p9050 = addr0; - cy_card[card_no].irq = irq; - cy_card[card_no].bus_index = 1; - cy_card[card_no].first_line = cy_next_channel; - cy_card[card_no].nports = nchan; - retval = cy_init_card(&cy_card[card_no]); - if (retval) - goto err_null; - - pci_set_drvdata(pdev, &cy_card[card_no]); - - if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || - device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { - /* enable interrupts in the PCI interface */ - plx_ver = readb(addr2 + CyPLX_VER) & 0x0f; - switch (plx_ver) { - case PLX_9050: - cy_writeb(addr0 + 0x4c, 0x43); - break; - - case PLX_9060: - case PLX_9080: - default: /* Old boards, use PLX_9060 */ - { - struct RUNTIME_9060 __iomem *ctl_addr = addr0; - plx_init(pdev, irq, ctl_addr); - cy_writew(&ctl_addr->intr_ctrl_stat, - readw(&ctl_addr->intr_ctrl_stat) | 0x0900); - break; - } - } - } - - dev_info(&pdev->dev, "%s/PCI #%d found: %d channels starting from " - "port %d.\n", card_name, card_no + 1, nchan, cy_next_channel); - for (i = cy_next_channel; i < cy_next_channel + nchan; i++) - tty_register_device(cy_serial_driver, i, &pdev->dev); - cy_next_channel += nchan; - - return 0; -err_null: - cy_card[card_no].base_addr = NULL; - free_irq(irq, &cy_card[card_no]); -err_unmap: - iounmap(addr0); - if (addr2) - iounmap(addr2); -err_reg: - pci_release_regions(pdev); -err_dis: - pci_disable_device(pdev); -err: - return retval; -} - -static void __devexit cy_pci_remove(struct pci_dev *pdev) -{ - struct cyclades_card *cinfo = pci_get_drvdata(pdev); - unsigned int i; - - /* non-Z with old PLX */ - if (!cy_is_Z(cinfo) && (readb(cinfo->base_addr + CyPLX_VER) & 0x0f) == - PLX_9050) - cy_writeb(cinfo->ctl_addr.p9050 + 0x4c, 0); - else -#ifndef CONFIG_CYZ_INTR - if (!cy_is_Z(cinfo)) -#endif - cy_writew(&cinfo->ctl_addr.p9060->intr_ctrl_stat, - readw(&cinfo->ctl_addr.p9060->intr_ctrl_stat) & - ~0x0900); - - iounmap(cinfo->base_addr); - if (cinfo->ctl_addr.p9050) - iounmap(cinfo->ctl_addr.p9050); - if (cinfo->irq -#ifndef CONFIG_CYZ_INTR - && !cy_is_Z(cinfo) -#endif /* CONFIG_CYZ_INTR */ - ) - free_irq(cinfo->irq, cinfo); - pci_release_regions(pdev); - - cinfo->base_addr = NULL; - for (i = cinfo->first_line; i < cinfo->first_line + - cinfo->nports; i++) - tty_unregister_device(cy_serial_driver, i); - cinfo->nports = 0; - kfree(cinfo->ports); -} - -static struct pci_driver cy_pci_driver = { - .name = "cyclades", - .id_table = cy_pci_dev_id, - .probe = cy_pci_probe, - .remove = __devexit_p(cy_pci_remove) -}; -#endif - -static int cyclades_proc_show(struct seq_file *m, void *v) -{ - struct cyclades_port *info; - unsigned int i, j; - __u32 cur_jifs = jiffies; - - seq_puts(m, "Dev TimeOpen BytesOut IdleOut BytesIn " - "IdleIn Overruns Ldisc\n"); - - /* Output one line for each known port */ - for (i = 0; i < NR_CARDS; i++) - for (j = 0; j < cy_card[i].nports; j++) { - info = &cy_card[i].ports[j]; - - if (info->port.count) { - /* XXX is the ldisc num worth this? */ - struct tty_struct *tty; - struct tty_ldisc *ld; - int num = 0; - tty = tty_port_tty_get(&info->port); - if (tty) { - ld = tty_ldisc_ref(tty); - if (ld) { - num = ld->ops->num; - tty_ldisc_deref(ld); - } - tty_kref_put(tty); - } - seq_printf(m, "%3d %8lu %10lu %8lu " - "%10lu %8lu %9lu %6d\n", info->line, - (cur_jifs - info->idle_stats.in_use) / - HZ, info->idle_stats.xmit_bytes, - (cur_jifs - info->idle_stats.xmit_idle)/ - HZ, info->idle_stats.recv_bytes, - (cur_jifs - info->idle_stats.recv_idle)/ - HZ, info->idle_stats.overruns, - num); - } else - seq_printf(m, "%3d %8lu %10lu %8lu " - "%10lu %8lu %9lu %6ld\n", - info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L); - } - return 0; -} - -static int cyclades_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, cyclades_proc_show, NULL); -} - -static const struct file_operations cyclades_proc_fops = { - .owner = THIS_MODULE, - .open = cyclades_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/* The serial driver boot-time initialization code! - Hardware I/O ports are mapped to character special devices on a - first found, first allocated manner. That is, this code searches - for Cyclom cards in the system. As each is found, it is probed - to discover how many chips (and thus how many ports) are present. - These ports are mapped to the tty ports 32 and upward in monotonic - fashion. If an 8-port card is replaced with a 16-port card, the - port mapping on a following card will shift. - - This approach is different from what is used in the other serial - device driver because the Cyclom is more properly a multiplexer, - not just an aggregation of serial ports on one card. - - If there are more cards with more ports than have been - statically allocated above, a warning is printed and the - extra ports are ignored. - */ - -static const struct tty_operations cy_ops = { - .open = cy_open, - .close = cy_close, - .write = cy_write, - .put_char = cy_put_char, - .flush_chars = cy_flush_chars, - .write_room = cy_write_room, - .chars_in_buffer = cy_chars_in_buffer, - .flush_buffer = cy_flush_buffer, - .ioctl = cy_ioctl, - .throttle = cy_throttle, - .unthrottle = cy_unthrottle, - .set_termios = cy_set_termios, - .stop = cy_stop, - .start = cy_start, - .hangup = cy_hangup, - .break_ctl = cy_break, - .wait_until_sent = cy_wait_until_sent, - .tiocmget = cy_tiocmget, - .tiocmset = cy_tiocmset, - .get_icount = cy_get_icount, - .proc_fops = &cyclades_proc_fops, -}; - -static int __init cy_init(void) -{ - unsigned int nboards; - int retval = -ENOMEM; - - cy_serial_driver = alloc_tty_driver(NR_PORTS); - if (!cy_serial_driver) - goto err; - - printk(KERN_INFO "Cyclades driver " CY_VERSION " (built %s %s)\n", - __DATE__, __TIME__); - - /* Initialize the tty_driver structure */ - - cy_serial_driver->owner = THIS_MODULE; - cy_serial_driver->driver_name = "cyclades"; - cy_serial_driver->name = "ttyC"; - cy_serial_driver->major = CYCLADES_MAJOR; - cy_serial_driver->minor_start = 0; - cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - cy_serial_driver->subtype = SERIAL_TYPE_NORMAL; - cy_serial_driver->init_termios = tty_std_termios; - cy_serial_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - cy_serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; - tty_set_operations(cy_serial_driver, &cy_ops); - - retval = tty_register_driver(cy_serial_driver); - if (retval) { - printk(KERN_ERR "Couldn't register Cyclades serial driver\n"); - goto err_frtty; - } - - /* the code below is responsible to find the boards. Each different - type of board has its own detection routine. If a board is found, - the next cy_card structure available is set by the detection - routine. These functions are responsible for checking the - availability of cy_card and cy_port data structures and updating - the cy_next_channel. */ - - /* look for isa boards */ - nboards = cy_detect_isa(); - -#ifdef CONFIG_PCI - /* look for pci boards */ - retval = pci_register_driver(&cy_pci_driver); - if (retval && !nboards) { - tty_unregister_driver(cy_serial_driver); - goto err_frtty; - } -#endif - - return 0; -err_frtty: - put_tty_driver(cy_serial_driver); -err: - return retval; -} /* cy_init */ - -static void __exit cy_cleanup_module(void) -{ - struct cyclades_card *card; - unsigned int i, e1; - -#ifndef CONFIG_CYZ_INTR - del_timer_sync(&cyz_timerlist); -#endif /* CONFIG_CYZ_INTR */ - - e1 = tty_unregister_driver(cy_serial_driver); - if (e1) - printk(KERN_ERR "failed to unregister Cyclades serial " - "driver(%d)\n", e1); - -#ifdef CONFIG_PCI - pci_unregister_driver(&cy_pci_driver); -#endif - - for (i = 0; i < NR_CARDS; i++) { - card = &cy_card[i]; - if (card->base_addr) { - /* clear interrupt */ - cy_writeb(card->base_addr + Cy_ClrIntr, 0); - iounmap(card->base_addr); - if (card->ctl_addr.p9050) - iounmap(card->ctl_addr.p9050); - if (card->irq -#ifndef CONFIG_CYZ_INTR - && !cy_is_Z(card) -#endif /* CONFIG_CYZ_INTR */ - ) - free_irq(card->irq, card); - for (e1 = card->first_line; e1 < card->first_line + - card->nports; e1++) - tty_unregister_device(cy_serial_driver, e1); - kfree(card->ports); - } - } - - put_tty_driver(cy_serial_driver); -} /* cy_cleanup_module */ - -module_init(cy_init); -module_exit(cy_cleanup_module); - -MODULE_LICENSE("GPL"); -MODULE_VERSION(CY_VERSION); -MODULE_ALIAS_CHARDEV_MAJOR(CYCLADES_MAJOR); -MODULE_FIRMWARE("cyzfirm.bin"); diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c deleted file mode 100644 index db1cf9c328d8..000000000000 --- a/drivers/char/isicom.c +++ /dev/null @@ -1,1736 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Original driver code supplied by Multi-Tech - * - * Changes - * 1/9/98 alan@lxorguk.ukuu.org.uk - * Merge to 2.0.x kernel tree - * Obtain and use official major/minors - * Loader switched to a misc device - * (fixed range check bug as a side effect) - * Printk clean up - * 9/12/98 alan@lxorguk.ukuu.org.uk - * Rough port to 2.1.x - * - * 10/6/99 sameer Merged the ISA and PCI drivers to - * a new unified driver. - * - * 3/9/99 sameer Added support for ISI4616 cards. - * - * 16/9/99 sameer We do not force RTS low anymore. - * This is to prevent the firmware - * from getting confused. - * - * 26/10/99 sameer Cosmetic changes:The driver now - * dumps the Port Count information - * along with I/O address and IRQ. - * - * 13/12/99 sameer Fixed the problem with IRQ sharing. - * - * 10/5/00 sameer Fixed isicom_shutdown_board() - * to not lower DTR on all the ports - * when the last port on the card is - * closed. - * - * 10/5/00 sameer Signal mask setup command added - * to isicom_setup_port and - * isicom_shutdown_port. - * - * 24/5/00 sameer The driver is now SMP aware. - * - * - * 27/11/00 Vinayak P Risbud Fixed the Driver Crash Problem - * - * - * 03/01/01 anil .s Added support for resetting the - * internal modems on ISI cards. - * - * 08/02/01 anil .s Upgraded the driver for kernel - * 2.4.x - * - * 11/04/01 Kevin Fixed firmware load problem with - * ISIHP-4X card - * - * 30/04/01 anil .s Fixed the remote login through - * ISI port problem. Now the link - * does not go down before password - * prompt. - * - * 03/05/01 anil .s Fixed the problem with IRQ sharing - * among ISI-PCI cards. - * - * 03/05/01 anil .s Added support to display the version - * info during insmod as well as module - * listing by lsmod. - * - * 10/05/01 anil .s Done the modifications to the source - * file and Install script so that the - * same installation can be used for - * 2.2.x and 2.4.x kernel. - * - * 06/06/01 anil .s Now we drop both dtr and rts during - * shutdown_port as well as raise them - * during isicom_config_port. - * - * 09/06/01 acme@conectiva.com.br use capable, not suser, do - * restore_flags on failure in - * isicom_send_break, verify put_user - * result - * - * 11/02/03 ranjeeth Added support for 230 Kbps and 460 Kbps - * Baud index extended to 21 - * - * 20/03/03 ranjeeth Made to work for Linux Advanced server. - * Taken care of license warning. - * - * 10/12/03 Ravindra Made to work for Fedora Core 1 of - * Red Hat Distribution - * - * 06/01/05 Alan Cox Merged the ISI and base kernel strands - * into a single 2.6 driver - * - * *********************************************************** - * - * To use this driver you also need the support package. You - * can find this in RPM format on - * ftp://ftp.linux.org.uk/pub/linux/alan - * - * You can find the original tools for this direct from Multitech - * ftp://ftp.multitech.com/ISI-Cards/ - * - * Having installed the cards the module options (/etc/modprobe.conf) - * - * options isicom io=card1,card2,card3,card4 irq=card1,card2,card3,card4 - * - * Omit those entries for boards you don't have installed. - * - * TODO - * Merge testing - * 64-bit verification - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include - -#define InterruptTheCard(base) outw(0, (base) + 0xc) -#define ClearInterrupt(base) inw((base) + 0x0a) - -#ifdef DEBUG -#define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c)) -#else -#define isicom_paranoia_check(a, b, c) 0 -#endif - -static int isicom_probe(struct pci_dev *, const struct pci_device_id *); -static void __devexit isicom_remove(struct pci_dev *); - -static struct pci_device_id isicom_pci_tbl[] = { - { PCI_DEVICE(VENDOR_ID, 0x2028) }, - { PCI_DEVICE(VENDOR_ID, 0x2051) }, - { PCI_DEVICE(VENDOR_ID, 0x2052) }, - { PCI_DEVICE(VENDOR_ID, 0x2053) }, - { PCI_DEVICE(VENDOR_ID, 0x2054) }, - { PCI_DEVICE(VENDOR_ID, 0x2055) }, - { PCI_DEVICE(VENDOR_ID, 0x2056) }, - { PCI_DEVICE(VENDOR_ID, 0x2057) }, - { PCI_DEVICE(VENDOR_ID, 0x2058) }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, isicom_pci_tbl); - -static struct pci_driver isicom_driver = { - .name = "isicom", - .id_table = isicom_pci_tbl, - .probe = isicom_probe, - .remove = __devexit_p(isicom_remove) -}; - -static int prev_card = 3; /* start servicing isi_card[0] */ -static struct tty_driver *isicom_normal; - -static void isicom_tx(unsigned long _data); -static void isicom_start(struct tty_struct *tty); - -static DEFINE_TIMER(tx, isicom_tx, 0, 0); - -/* baud index mappings from linux defns to isi */ - -static signed char linuxb_to_isib[] = { - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19, 20, 21 -}; - -struct isi_board { - unsigned long base; - int irq; - unsigned char port_count; - unsigned short status; - unsigned short port_status; /* each bit for each port */ - unsigned short shift_count; - struct isi_port *ports; - signed char count; - spinlock_t card_lock; /* Card wide lock 11/5/00 -sameer */ - unsigned long flags; - unsigned int index; -}; - -struct isi_port { - unsigned short magic; - struct tty_port port; - u16 channel; - u16 status; - struct isi_board *card; - unsigned char *xmit_buf; - int xmit_head; - int xmit_tail; - int xmit_cnt; -}; - -static struct isi_board isi_card[BOARD_COUNT]; -static struct isi_port isi_ports[PORT_COUNT]; - -/* - * Locking functions for card level locking. We need to own both - * the kernel lock for the card and have the card in a position that - * it wants to talk. - */ - -static inline int WaitTillCardIsFree(unsigned long base) -{ - unsigned int count = 0; - unsigned int a = in_atomic(); /* do we run under spinlock? */ - - while (!(inw(base + 0xe) & 0x1) && count++ < 100) - if (a) - mdelay(1); - else - msleep(1); - - return !(inw(base + 0xe) & 0x1); -} - -static int lock_card(struct isi_board *card) -{ - unsigned long base = card->base; - unsigned int retries, a; - - for (retries = 0; retries < 10; retries++) { - spin_lock_irqsave(&card->card_lock, card->flags); - for (a = 0; a < 10; a++) { - if (inw(base + 0xe) & 0x1) - return 1; - udelay(10); - } - spin_unlock_irqrestore(&card->card_lock, card->flags); - msleep(10); - } - pr_warning("Failed to lock Card (0x%lx)\n", card->base); - - return 0; /* Failed to acquire the card! */ -} - -static void unlock_card(struct isi_board *card) -{ - spin_unlock_irqrestore(&card->card_lock, card->flags); -} - -/* - * ISI Card specific ops ... - */ - -/* card->lock HAS to be held */ -static void raise_dtr(struct isi_port *port) -{ - struct isi_board *card = port->card; - unsigned long base = card->base; - u16 channel = port->channel; - - if (WaitTillCardIsFree(base)) - return; - - outw(0x8000 | (channel << card->shift_count) | 0x02, base); - outw(0x0504, base); - InterruptTheCard(base); - port->status |= ISI_DTR; -} - -/* card->lock HAS to be held */ -static inline void drop_dtr(struct isi_port *port) -{ - struct isi_board *card = port->card; - unsigned long base = card->base; - u16 channel = port->channel; - - if (WaitTillCardIsFree(base)) - return; - - outw(0x8000 | (channel << card->shift_count) | 0x02, base); - outw(0x0404, base); - InterruptTheCard(base); - port->status &= ~ISI_DTR; -} - -/* card->lock HAS to be held */ -static inline void raise_rts(struct isi_port *port) -{ - struct isi_board *card = port->card; - unsigned long base = card->base; - u16 channel = port->channel; - - if (WaitTillCardIsFree(base)) - return; - - outw(0x8000 | (channel << card->shift_count) | 0x02, base); - outw(0x0a04, base); - InterruptTheCard(base); - port->status |= ISI_RTS; -} - -/* card->lock HAS to be held */ -static inline void drop_rts(struct isi_port *port) -{ - struct isi_board *card = port->card; - unsigned long base = card->base; - u16 channel = port->channel; - - if (WaitTillCardIsFree(base)) - return; - - outw(0x8000 | (channel << card->shift_count) | 0x02, base); - outw(0x0804, base); - InterruptTheCard(base); - port->status &= ~ISI_RTS; -} - -/* card->lock MUST NOT be held */ - -static void isicom_dtr_rts(struct tty_port *port, int on) -{ - struct isi_port *ip = container_of(port, struct isi_port, port); - struct isi_board *card = ip->card; - unsigned long base = card->base; - u16 channel = ip->channel; - - if (!lock_card(card)) - return; - - if (on) { - outw(0x8000 | (channel << card->shift_count) | 0x02, base); - outw(0x0f04, base); - InterruptTheCard(base); - ip->status |= (ISI_DTR | ISI_RTS); - } else { - outw(0x8000 | (channel << card->shift_count) | 0x02, base); - outw(0x0C04, base); - InterruptTheCard(base); - ip->status &= ~(ISI_DTR | ISI_RTS); - } - unlock_card(card); -} - -/* card->lock HAS to be held */ -static void drop_dtr_rts(struct isi_port *port) -{ - struct isi_board *card = port->card; - unsigned long base = card->base; - u16 channel = port->channel; - - if (WaitTillCardIsFree(base)) - return; - - outw(0x8000 | (channel << card->shift_count) | 0x02, base); - outw(0x0c04, base); - InterruptTheCard(base); - port->status &= ~(ISI_RTS | ISI_DTR); -} - -/* - * ISICOM Driver specific routines ... - * - */ - -static inline int __isicom_paranoia_check(struct isi_port const *port, - char *name, const char *routine) -{ - if (!port) { - pr_warning("Warning: bad isicom magic for dev %s in %s.\n", - name, routine); - return 1; - } - if (port->magic != ISICOM_MAGIC) { - pr_warning("Warning: NULL isicom port for dev %s in %s.\n", - name, routine); - return 1; - } - - return 0; -} - -/* - * Transmitter. - * - * We shovel data into the card buffers on a regular basis. The card - * will do the rest of the work for us. - */ - -static void isicom_tx(unsigned long _data) -{ - unsigned long flags, base; - unsigned int retries; - short count = (BOARD_COUNT-1), card; - short txcount, wrd, residue, word_count, cnt; - struct isi_port *port; - struct tty_struct *tty; - - /* find next active board */ - card = (prev_card + 1) & 0x0003; - while (count-- > 0) { - if (isi_card[card].status & BOARD_ACTIVE) - break; - card = (card + 1) & 0x0003; - } - if (!(isi_card[card].status & BOARD_ACTIVE)) - goto sched_again; - - prev_card = card; - - count = isi_card[card].port_count; - port = isi_card[card].ports; - base = isi_card[card].base; - - spin_lock_irqsave(&isi_card[card].card_lock, flags); - for (retries = 0; retries < 100; retries++) { - if (inw(base + 0xe) & 0x1) - break; - udelay(2); - } - if (retries >= 100) - goto unlock; - - tty = tty_port_tty_get(&port->port); - if (tty == NULL) - goto put_unlock; - - for (; count > 0; count--, port++) { - /* port not active or tx disabled to force flow control */ - if (!(port->port.flags & ASYNC_INITIALIZED) || - !(port->status & ISI_TXOK)) - continue; - - txcount = min_t(short, TX_SIZE, port->xmit_cnt); - if (txcount <= 0 || tty->stopped || tty->hw_stopped) - continue; - - if (!(inw(base + 0x02) & (1 << port->channel))) - continue; - - pr_debug("txing %d bytes, port%d.\n", - txcount, port->channel + 1); - outw((port->channel << isi_card[card].shift_count) | txcount, - base); - residue = NO; - wrd = 0; - while (1) { - cnt = min_t(int, txcount, (SERIAL_XMIT_SIZE - - port->xmit_tail)); - if (residue == YES) { - residue = NO; - if (cnt > 0) { - wrd |= (port->port.xmit_buf[port->xmit_tail] - << 8); - port->xmit_tail = (port->xmit_tail + 1) - & (SERIAL_XMIT_SIZE - 1); - port->xmit_cnt--; - txcount--; - cnt--; - outw(wrd, base); - } else { - outw(wrd, base); - break; - } - } - if (cnt <= 0) - break; - word_count = cnt >> 1; - outsw(base, port->port.xmit_buf+port->xmit_tail, word_count); - port->xmit_tail = (port->xmit_tail - + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1); - txcount -= (word_count << 1); - port->xmit_cnt -= (word_count << 1); - if (cnt & 0x0001) { - residue = YES; - wrd = port->port.xmit_buf[port->xmit_tail]; - port->xmit_tail = (port->xmit_tail + 1) - & (SERIAL_XMIT_SIZE - 1); - port->xmit_cnt--; - txcount--; - } - } - - InterruptTheCard(base); - if (port->xmit_cnt <= 0) - port->status &= ~ISI_TXOK; - if (port->xmit_cnt <= WAKEUP_CHARS) - tty_wakeup(tty); - } - -put_unlock: - tty_kref_put(tty); -unlock: - spin_unlock_irqrestore(&isi_card[card].card_lock, flags); - /* schedule another tx for hopefully in about 10ms */ -sched_again: - mod_timer(&tx, jiffies + msecs_to_jiffies(10)); -} - -/* - * Main interrupt handler routine - */ - -static irqreturn_t isicom_interrupt(int irq, void *dev_id) -{ - struct isi_board *card = dev_id; - struct isi_port *port; - struct tty_struct *tty; - unsigned long base; - u16 header, word_count, count, channel; - short byte_count; - unsigned char *rp; - - if (!card || !(card->status & FIRMWARE_LOADED)) - return IRQ_NONE; - - base = card->base; - - /* did the card interrupt us? */ - if (!(inw(base + 0x0e) & 0x02)) - return IRQ_NONE; - - spin_lock(&card->card_lock); - - /* - * disable any interrupts from the PCI card and lower the - * interrupt line - */ - outw(0x8000, base+0x04); - ClearInterrupt(base); - - inw(base); /* get the dummy word out */ - header = inw(base); - channel = (header & 0x7800) >> card->shift_count; - byte_count = header & 0xff; - - if (channel + 1 > card->port_count) { - pr_warning("%s(0x%lx): %d(channel) > port_count.\n", - __func__, base, channel+1); - outw(0x0000, base+0x04); /* enable interrupts */ - spin_unlock(&card->card_lock); - return IRQ_HANDLED; - } - port = card->ports + channel; - if (!(port->port.flags & ASYNC_INITIALIZED)) { - outw(0x0000, base+0x04); /* enable interrupts */ - spin_unlock(&card->card_lock); - return IRQ_HANDLED; - } - - tty = tty_port_tty_get(&port->port); - if (tty == NULL) { - word_count = byte_count >> 1; - while (byte_count > 1) { - inw(base); - byte_count -= 2; - } - if (byte_count & 0x01) - inw(base); - outw(0x0000, base+0x04); /* enable interrupts */ - spin_unlock(&card->card_lock); - return IRQ_HANDLED; - } - - if (header & 0x8000) { /* Status Packet */ - header = inw(base); - switch (header & 0xff) { - case 0: /* Change in EIA signals */ - if (port->port.flags & ASYNC_CHECK_CD) { - if (port->status & ISI_DCD) { - if (!(header & ISI_DCD)) { - /* Carrier has been lost */ - pr_debug("%s: DCD->low.\n", - __func__); - port->status &= ~ISI_DCD; - tty_hangup(tty); - } - } else if (header & ISI_DCD) { - /* Carrier has been detected */ - pr_debug("%s: DCD->high.\n", - __func__); - port->status |= ISI_DCD; - wake_up_interruptible(&port->port.open_wait); - } - } else { - if (header & ISI_DCD) - port->status |= ISI_DCD; - else - port->status &= ~ISI_DCD; - } - - if (port->port.flags & ASYNC_CTS_FLOW) { - if (tty->hw_stopped) { - if (header & ISI_CTS) { - port->port.tty->hw_stopped = 0; - /* start tx ing */ - port->status |= (ISI_TXOK - | ISI_CTS); - tty_wakeup(tty); - } - } else if (!(header & ISI_CTS)) { - tty->hw_stopped = 1; - /* stop tx ing */ - port->status &= ~(ISI_TXOK | ISI_CTS); - } - } else { - if (header & ISI_CTS) - port->status |= ISI_CTS; - else - port->status &= ~ISI_CTS; - } - - if (header & ISI_DSR) - port->status |= ISI_DSR; - else - port->status &= ~ISI_DSR; - - if (header & ISI_RI) - port->status |= ISI_RI; - else - port->status &= ~ISI_RI; - - break; - - case 1: /* Received Break !!! */ - tty_insert_flip_char(tty, 0, TTY_BREAK); - if (port->port.flags & ASYNC_SAK) - do_SAK(tty); - tty_flip_buffer_push(tty); - break; - - case 2: /* Statistics */ - pr_debug("%s: stats!!!\n", __func__); - break; - - default: - pr_debug("%s: Unknown code in status packet.\n", - __func__); - break; - } - } else { /* Data Packet */ - - count = tty_prepare_flip_string(tty, &rp, byte_count & ~1); - pr_debug("%s: Can rx %d of %d bytes.\n", - __func__, count, byte_count); - word_count = count >> 1; - insw(base, rp, word_count); - byte_count -= (word_count << 1); - if (count & 0x0001) { - tty_insert_flip_char(tty, inw(base) & 0xff, - TTY_NORMAL); - byte_count -= 2; - } - if (byte_count > 0) { - pr_debug("%s(0x%lx:%d): Flip buffer overflow! dropping bytes...\n", - __func__, base, channel + 1); - /* drain out unread xtra data */ - while (byte_count > 0) { - inw(base); - byte_count -= 2; - } - } - tty_flip_buffer_push(tty); - } - outw(0x0000, base+0x04); /* enable interrupts */ - spin_unlock(&card->card_lock); - tty_kref_put(tty); - - return IRQ_HANDLED; -} - -static void isicom_config_port(struct tty_struct *tty) -{ - struct isi_port *port = tty->driver_data; - struct isi_board *card = port->card; - unsigned long baud; - unsigned long base = card->base; - u16 channel_setup, channel = port->channel, - shift_count = card->shift_count; - unsigned char flow_ctrl; - - /* FIXME: Switch to new tty baud API */ - baud = C_BAUD(tty); - if (baud & CBAUDEX) { - baud &= ~CBAUDEX; - - /* if CBAUDEX bit is on and the baud is set to either 50 or 75 - * then the card is programmed for 57.6Kbps or 115Kbps - * respectively. - */ - - /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */ - if (baud < 1 || baud > 4) - tty->termios->c_cflag &= ~CBAUDEX; - else - baud += 15; - } - if (baud == 15) { - - /* the ASYNC_SPD_HI and ASYNC_SPD_VHI options are set - * by the set_serial_info ioctl ... this is done by - * the 'setserial' utility. - */ - - if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - baud++; /* 57.6 Kbps */ - if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - baud += 2; /* 115 Kbps */ - if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - baud += 3; /* 230 kbps*/ - if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - baud += 4; /* 460 kbps*/ - } - if (linuxb_to_isib[baud] == -1) { - /* hang up */ - drop_dtr(port); - return; - } else - raise_dtr(port); - - if (WaitTillCardIsFree(base) == 0) { - outw(0x8000 | (channel << shift_count) | 0x03, base); - outw(linuxb_to_isib[baud] << 8 | 0x03, base); - channel_setup = 0; - switch (C_CSIZE(tty)) { - case CS5: - channel_setup |= ISICOM_CS5; - break; - case CS6: - channel_setup |= ISICOM_CS6; - break; - case CS7: - channel_setup |= ISICOM_CS7; - break; - case CS8: - channel_setup |= ISICOM_CS8; - break; - } - - if (C_CSTOPB(tty)) - channel_setup |= ISICOM_2SB; - if (C_PARENB(tty)) { - channel_setup |= ISICOM_EVPAR; - if (C_PARODD(tty)) - channel_setup |= ISICOM_ODPAR; - } - outw(channel_setup, base); - InterruptTheCard(base); - } - if (C_CLOCAL(tty)) - port->port.flags &= ~ASYNC_CHECK_CD; - else - port->port.flags |= ASYNC_CHECK_CD; - - /* flow control settings ...*/ - flow_ctrl = 0; - port->port.flags &= ~ASYNC_CTS_FLOW; - if (C_CRTSCTS(tty)) { - port->port.flags |= ASYNC_CTS_FLOW; - flow_ctrl |= ISICOM_CTSRTS; - } - if (I_IXON(tty)) - flow_ctrl |= ISICOM_RESPOND_XONXOFF; - if (I_IXOFF(tty)) - flow_ctrl |= ISICOM_INITIATE_XONXOFF; - - if (WaitTillCardIsFree(base) == 0) { - outw(0x8000 | (channel << shift_count) | 0x04, base); - outw(flow_ctrl << 8 | 0x05, base); - outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base); - InterruptTheCard(base); - } - - /* rx enabled -> enable port for rx on the card */ - if (C_CREAD(tty)) { - card->port_status |= (1 << channel); - outw(card->port_status, base + 0x02); - } -} - -/* open et all */ - -static inline void isicom_setup_board(struct isi_board *bp) -{ - int channel; - struct isi_port *port; - - bp->count++; - if (!(bp->status & BOARD_INIT)) { - port = bp->ports; - for (channel = 0; channel < bp->port_count; channel++, port++) - drop_dtr_rts(port); - } - bp->status |= BOARD_ACTIVE | BOARD_INIT; -} - -/* Activate and thus setup board are protected from races against shutdown - by the tty_port mutex */ - -static int isicom_activate(struct tty_port *tport, struct tty_struct *tty) -{ - struct isi_port *port = container_of(tport, struct isi_port, port); - struct isi_board *card = port->card; - unsigned long flags; - - if (tty_port_alloc_xmit_buf(tport) < 0) - return -ENOMEM; - - spin_lock_irqsave(&card->card_lock, flags); - isicom_setup_board(card); - - port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; - - /* discard any residual data */ - if (WaitTillCardIsFree(card->base) == 0) { - outw(0x8000 | (port->channel << card->shift_count) | 0x02, - card->base); - outw(((ISICOM_KILLTX | ISICOM_KILLRX) << 8) | 0x06, card->base); - InterruptTheCard(card->base); - } - isicom_config_port(tty); - spin_unlock_irqrestore(&card->card_lock, flags); - - return 0; -} - -static int isicom_carrier_raised(struct tty_port *port) -{ - struct isi_port *ip = container_of(port, struct isi_port, port); - return (ip->status & ISI_DCD)?1 : 0; -} - -static struct tty_port *isicom_find_port(struct tty_struct *tty) -{ - struct isi_port *port; - struct isi_board *card; - unsigned int board; - int line = tty->index; - - if (line < 0 || line > PORT_COUNT-1) - return NULL; - board = BOARD(line); - card = &isi_card[board]; - - if (!(card->status & FIRMWARE_LOADED)) - return NULL; - - /* open on a port greater than the port count for the card !!! */ - if (line > ((board * 16) + card->port_count - 1)) - return NULL; - - port = &isi_ports[line]; - if (isicom_paranoia_check(port, tty->name, "isicom_open")) - return NULL; - - return &port->port; -} - -static int isicom_open(struct tty_struct *tty, struct file *filp) -{ - struct isi_port *port; - struct tty_port *tport; - - tport = isicom_find_port(tty); - if (tport == NULL) - return -ENODEV; - port = container_of(tport, struct isi_port, port); - - tty->driver_data = port; - return tty_port_open(tport, tty, filp); -} - -/* close et all */ - -/* card->lock HAS to be held */ -static void isicom_shutdown_port(struct isi_port *port) -{ - struct isi_board *card = port->card; - - if (--card->count < 0) { - pr_debug("%s: bad board(0x%lx) count %d.\n", - __func__, card->base, card->count); - card->count = 0; - } - /* last port was closed, shutdown that board too */ - if (!card->count) - card->status &= BOARD_ACTIVE; -} - -static void isicom_flush_buffer(struct tty_struct *tty) -{ - struct isi_port *port = tty->driver_data; - struct isi_board *card = port->card; - unsigned long flags; - - if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer")) - return; - - spin_lock_irqsave(&card->card_lock, flags); - port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; - spin_unlock_irqrestore(&card->card_lock, flags); - - tty_wakeup(tty); -} - -static void isicom_shutdown(struct tty_port *port) -{ - struct isi_port *ip = container_of(port, struct isi_port, port); - struct isi_board *card = ip->card; - unsigned long flags; - - /* indicate to the card that no more data can be received - on this port */ - spin_lock_irqsave(&card->card_lock, flags); - card->port_status &= ~(1 << ip->channel); - outw(card->port_status, card->base + 0x02); - isicom_shutdown_port(ip); - spin_unlock_irqrestore(&card->card_lock, flags); - tty_port_free_xmit_buf(port); -} - -static void isicom_close(struct tty_struct *tty, struct file *filp) -{ - struct isi_port *ip = tty->driver_data; - struct tty_port *port; - - if (ip == NULL) - return; - - port = &ip->port; - if (isicom_paranoia_check(ip, tty->name, "isicom_close")) - return; - tty_port_close(port, tty, filp); -} - -/* write et all */ -static int isicom_write(struct tty_struct *tty, const unsigned char *buf, - int count) -{ - struct isi_port *port = tty->driver_data; - struct isi_board *card = port->card; - unsigned long flags; - int cnt, total = 0; - - if (isicom_paranoia_check(port, tty->name, "isicom_write")) - return 0; - - spin_lock_irqsave(&card->card_lock, flags); - - while (1) { - cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - - 1, SERIAL_XMIT_SIZE - port->xmit_head)); - if (cnt <= 0) - break; - - memcpy(port->port.xmit_buf + port->xmit_head, buf, cnt); - port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE - - 1); - port->xmit_cnt += cnt; - buf += cnt; - count -= cnt; - total += cnt; - } - if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped) - port->status |= ISI_TXOK; - spin_unlock_irqrestore(&card->card_lock, flags); - return total; -} - -/* put_char et all */ -static int isicom_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct isi_port *port = tty->driver_data; - struct isi_board *card = port->card; - unsigned long flags; - - if (isicom_paranoia_check(port, tty->name, "isicom_put_char")) - return 0; - - spin_lock_irqsave(&card->card_lock, flags); - if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { - spin_unlock_irqrestore(&card->card_lock, flags); - return 0; - } - - port->port.xmit_buf[port->xmit_head++] = ch; - port->xmit_head &= (SERIAL_XMIT_SIZE - 1); - port->xmit_cnt++; - spin_unlock_irqrestore(&card->card_lock, flags); - return 1; -} - -/* flush_chars et all */ -static void isicom_flush_chars(struct tty_struct *tty) -{ - struct isi_port *port = tty->driver_data; - - if (isicom_paranoia_check(port, tty->name, "isicom_flush_chars")) - return; - - if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || - !port->port.xmit_buf) - return; - - /* this tells the transmitter to consider this port for - data output to the card ... that's the best we can do. */ - port->status |= ISI_TXOK; -} - -/* write_room et all */ -static int isicom_write_room(struct tty_struct *tty) -{ - struct isi_port *port = tty->driver_data; - int free; - - if (isicom_paranoia_check(port, tty->name, "isicom_write_room")) - return 0; - - free = SERIAL_XMIT_SIZE - port->xmit_cnt - 1; - if (free < 0) - free = 0; - return free; -} - -/* chars_in_buffer et all */ -static int isicom_chars_in_buffer(struct tty_struct *tty) -{ - struct isi_port *port = tty->driver_data; - if (isicom_paranoia_check(port, tty->name, "isicom_chars_in_buffer")) - return 0; - return port->xmit_cnt; -} - -/* ioctl et all */ -static int isicom_send_break(struct tty_struct *tty, int length) -{ - struct isi_port *port = tty->driver_data; - struct isi_board *card = port->card; - unsigned long base = card->base; - - if (length == -1) - return -EOPNOTSUPP; - - if (!lock_card(card)) - return -EINVAL; - - outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base); - outw((length & 0xff) << 8 | 0x00, base); - outw((length & 0xff00), base); - InterruptTheCard(base); - - unlock_card(card); - return 0; -} - -static int isicom_tiocmget(struct tty_struct *tty) -{ - struct isi_port *port = tty->driver_data; - /* just send the port status */ - u16 status = port->status; - - if (isicom_paranoia_check(port, tty->name, "isicom_ioctl")) - return -ENODEV; - - return ((status & ISI_RTS) ? TIOCM_RTS : 0) | - ((status & ISI_DTR) ? TIOCM_DTR : 0) | - ((status & ISI_DCD) ? TIOCM_CAR : 0) | - ((status & ISI_DSR) ? TIOCM_DSR : 0) | - ((status & ISI_CTS) ? TIOCM_CTS : 0) | - ((status & ISI_RI ) ? TIOCM_RI : 0); -} - -static int isicom_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct isi_port *port = tty->driver_data; - unsigned long flags; - - if (isicom_paranoia_check(port, tty->name, "isicom_ioctl")) - return -ENODEV; - - spin_lock_irqsave(&port->card->card_lock, flags); - if (set & TIOCM_RTS) - raise_rts(port); - if (set & TIOCM_DTR) - raise_dtr(port); - - if (clear & TIOCM_RTS) - drop_rts(port); - if (clear & TIOCM_DTR) - drop_dtr(port); - spin_unlock_irqrestore(&port->card->card_lock, flags); - - return 0; -} - -static int isicom_set_serial_info(struct tty_struct *tty, - struct serial_struct __user *info) -{ - struct isi_port *port = tty->driver_data; - struct serial_struct newinfo; - int reconfig_port; - - if (copy_from_user(&newinfo, info, sizeof(newinfo))) - return -EFAULT; - - mutex_lock(&port->port.mutex); - reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) != - (newinfo.flags & ASYNC_SPD_MASK)); - - if (!capable(CAP_SYS_ADMIN)) { - if ((newinfo.close_delay != port->port.close_delay) || - (newinfo.closing_wait != port->port.closing_wait) || - ((newinfo.flags & ~ASYNC_USR_MASK) != - (port->port.flags & ~ASYNC_USR_MASK))) { - mutex_unlock(&port->port.mutex); - return -EPERM; - } - port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | - (newinfo.flags & ASYNC_USR_MASK)); - } else { - port->port.close_delay = newinfo.close_delay; - port->port.closing_wait = newinfo.closing_wait; - port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) | - (newinfo.flags & ASYNC_FLAGS)); - } - if (reconfig_port) { - unsigned long flags; - spin_lock_irqsave(&port->card->card_lock, flags); - isicom_config_port(tty); - spin_unlock_irqrestore(&port->card->card_lock, flags); - } - mutex_unlock(&port->port.mutex); - return 0; -} - -static int isicom_get_serial_info(struct isi_port *port, - struct serial_struct __user *info) -{ - struct serial_struct out_info; - - mutex_lock(&port->port.mutex); - memset(&out_info, 0, sizeof(out_info)); -/* out_info.type = ? */ - out_info.line = port - isi_ports; - out_info.port = port->card->base; - out_info.irq = port->card->irq; - out_info.flags = port->port.flags; -/* out_info.baud_base = ? */ - out_info.close_delay = port->port.close_delay; - out_info.closing_wait = port->port.closing_wait; - mutex_unlock(&port->port.mutex); - if (copy_to_user(info, &out_info, sizeof(out_info))) - return -EFAULT; - return 0; -} - -static int isicom_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct isi_port *port = tty->driver_data; - void __user *argp = (void __user *)arg; - - if (isicom_paranoia_check(port, tty->name, "isicom_ioctl")) - return -ENODEV; - - switch (cmd) { - case TIOCGSERIAL: - return isicom_get_serial_info(port, argp); - - case TIOCSSERIAL: - return isicom_set_serial_info(tty, argp); - - default: - return -ENOIOCTLCMD; - } - return 0; -} - -/* set_termios et all */ -static void isicom_set_termios(struct tty_struct *tty, - struct ktermios *old_termios) -{ - struct isi_port *port = tty->driver_data; - unsigned long flags; - - if (isicom_paranoia_check(port, tty->name, "isicom_set_termios")) - return; - - if (tty->termios->c_cflag == old_termios->c_cflag && - tty->termios->c_iflag == old_termios->c_iflag) - return; - - spin_lock_irqsave(&port->card->card_lock, flags); - isicom_config_port(tty); - spin_unlock_irqrestore(&port->card->card_lock, flags); - - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - isicom_start(tty); - } -} - -/* throttle et all */ -static void isicom_throttle(struct tty_struct *tty) -{ - struct isi_port *port = tty->driver_data; - struct isi_board *card = port->card; - - if (isicom_paranoia_check(port, tty->name, "isicom_throttle")) - return; - - /* tell the card that this port cannot handle any more data for now */ - card->port_status &= ~(1 << port->channel); - outw(card->port_status, card->base + 0x02); -} - -/* unthrottle et all */ -static void isicom_unthrottle(struct tty_struct *tty) -{ - struct isi_port *port = tty->driver_data; - struct isi_board *card = port->card; - - if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle")) - return; - - /* tell the card that this port is ready to accept more data */ - card->port_status |= (1 << port->channel); - outw(card->port_status, card->base + 0x02); -} - -/* stop et all */ -static void isicom_stop(struct tty_struct *tty) -{ - struct isi_port *port = tty->driver_data; - - if (isicom_paranoia_check(port, tty->name, "isicom_stop")) - return; - - /* this tells the transmitter not to consider this port for - data output to the card. */ - port->status &= ~ISI_TXOK; -} - -/* start et all */ -static void isicom_start(struct tty_struct *tty) -{ - struct isi_port *port = tty->driver_data; - - if (isicom_paranoia_check(port, tty->name, "isicom_start")) - return; - - /* this tells the transmitter to consider this port for - data output to the card. */ - port->status |= ISI_TXOK; -} - -static void isicom_hangup(struct tty_struct *tty) -{ - struct isi_port *port = tty->driver_data; - - if (isicom_paranoia_check(port, tty->name, "isicom_hangup")) - return; - tty_port_hangup(&port->port); -} - - -/* - * Driver init and deinit functions - */ - -static const struct tty_operations isicom_ops = { - .open = isicom_open, - .close = isicom_close, - .write = isicom_write, - .put_char = isicom_put_char, - .flush_chars = isicom_flush_chars, - .write_room = isicom_write_room, - .chars_in_buffer = isicom_chars_in_buffer, - .ioctl = isicom_ioctl, - .set_termios = isicom_set_termios, - .throttle = isicom_throttle, - .unthrottle = isicom_unthrottle, - .stop = isicom_stop, - .start = isicom_start, - .hangup = isicom_hangup, - .flush_buffer = isicom_flush_buffer, - .tiocmget = isicom_tiocmget, - .tiocmset = isicom_tiocmset, - .break_ctl = isicom_send_break, -}; - -static const struct tty_port_operations isicom_port_ops = { - .carrier_raised = isicom_carrier_raised, - .dtr_rts = isicom_dtr_rts, - .activate = isicom_activate, - .shutdown = isicom_shutdown, -}; - -static int __devinit reset_card(struct pci_dev *pdev, - const unsigned int card, unsigned int *signature) -{ - struct isi_board *board = pci_get_drvdata(pdev); - unsigned long base = board->base; - unsigned int sig, portcount = 0; - int retval = 0; - - dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1, - base); - - inw(base + 0x8); - - msleep(10); - - outw(0, base + 0x8); /* Reset */ - - msleep(1000); - - sig = inw(base + 0x4) & 0xff; - - if (sig != 0xa5 && sig != 0xbb && sig != 0xcc && sig != 0xdd && - sig != 0xee) { - dev_warn(&pdev->dev, "ISILoad:Card%u reset failure (Possible " - "bad I/O Port Address 0x%lx).\n", card + 1, base); - dev_dbg(&pdev->dev, "Sig=0x%x\n", sig); - retval = -EIO; - goto end; - } - - msleep(10); - - portcount = inw(base + 0x2); - if (!(inw(base + 0xe) & 0x1) || (portcount != 0 && portcount != 4 && - portcount != 8 && portcount != 16)) { - dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n", - card + 1); - retval = -EIO; - goto end; - } - - switch (sig) { - case 0xa5: - case 0xbb: - case 0xdd: - board->port_count = (portcount == 4) ? 4 : 8; - board->shift_count = 12; - break; - case 0xcc: - case 0xee: - board->port_count = 16; - board->shift_count = 11; - break; - } - dev_info(&pdev->dev, "-Done\n"); - *signature = sig; - -end: - return retval; -} - -static int __devinit load_firmware(struct pci_dev *pdev, - const unsigned int index, const unsigned int signature) -{ - struct isi_board *board = pci_get_drvdata(pdev); - const struct firmware *fw; - unsigned long base = board->base; - unsigned int a; - u16 word_count, status; - int retval = -EIO; - char *name; - u8 *data; - - struct stframe { - u16 addr; - u16 count; - u8 data[0]; - } *frame; - - switch (signature) { - case 0xa5: - name = "isi608.bin"; - break; - case 0xbb: - name = "isi608em.bin"; - break; - case 0xcc: - name = "isi616em.bin"; - break; - case 0xdd: - name = "isi4608.bin"; - break; - case 0xee: - name = "isi4616.bin"; - break; - default: - dev_err(&pdev->dev, "Unknown signature.\n"); - goto end; - } - - retval = request_firmware(&fw, name, &pdev->dev); - if (retval) - goto end; - - retval = -EIO; - - for (frame = (struct stframe *)fw->data; - frame < (struct stframe *)(fw->data + fw->size); - frame = (struct stframe *)((u8 *)(frame + 1) + - frame->count)) { - if (WaitTillCardIsFree(base)) - goto errrelfw; - - outw(0xf0, base); /* start upload sequence */ - outw(0x00, base); - outw(frame->addr, base); /* lsb of address */ - - word_count = frame->count / 2 + frame->count % 2; - outw(word_count, base); - InterruptTheCard(base); - - udelay(100); /* 0x2f */ - - if (WaitTillCardIsFree(base)) - goto errrelfw; - - status = inw(base + 0x4); - if (status != 0) { - dev_warn(&pdev->dev, "Card%d rejected load header:\n" - "Address:0x%x\n" - "Count:0x%x\n" - "Status:0x%x\n", - index + 1, frame->addr, frame->count, status); - goto errrelfw; - } - outsw(base, frame->data, word_count); - - InterruptTheCard(base); - - udelay(50); /* 0x0f */ - - if (WaitTillCardIsFree(base)) - goto errrelfw; - - status = inw(base + 0x4); - if (status != 0) { - dev_err(&pdev->dev, "Card%d got out of sync.Card " - "Status:0x%x\n", index + 1, status); - goto errrelfw; - } - } - -/* XXX: should we test it by reading it back and comparing with original like - * in load firmware package? */ - for (frame = (struct stframe *)fw->data; - frame < (struct stframe *)(fw->data + fw->size); - frame = (struct stframe *)((u8 *)(frame + 1) + - frame->count)) { - if (WaitTillCardIsFree(base)) - goto errrelfw; - - outw(0xf1, base); /* start download sequence */ - outw(0x00, base); - outw(frame->addr, base); /* lsb of address */ - - word_count = (frame->count >> 1) + frame->count % 2; - outw(word_count + 1, base); - InterruptTheCard(base); - - udelay(50); /* 0xf */ - - if (WaitTillCardIsFree(base)) - goto errrelfw; - - status = inw(base + 0x4); - if (status != 0) { - dev_warn(&pdev->dev, "Card%d rejected verify header:\n" - "Address:0x%x\n" - "Count:0x%x\n" - "Status: 0x%x\n", - index + 1, frame->addr, frame->count, status); - goto errrelfw; - } - - data = kmalloc(word_count * 2, GFP_KERNEL); - if (data == NULL) { - dev_err(&pdev->dev, "Card%d, firmware upload " - "failed, not enough memory\n", index + 1); - goto errrelfw; - } - inw(base); - insw(base, data, word_count); - InterruptTheCard(base); - - for (a = 0; a < frame->count; a++) - if (data[a] != frame->data[a]) { - kfree(data); - dev_err(&pdev->dev, "Card%d, firmware upload " - "failed\n", index + 1); - goto errrelfw; - } - kfree(data); - - udelay(50); /* 0xf */ - - if (WaitTillCardIsFree(base)) - goto errrelfw; - - status = inw(base + 0x4); - if (status != 0) { - dev_err(&pdev->dev, "Card%d verify got out of sync. " - "Card Status:0x%x\n", index + 1, status); - goto errrelfw; - } - } - - /* xfer ctrl */ - if (WaitTillCardIsFree(base)) - goto errrelfw; - - outw(0xf2, base); - outw(0x800, base); - outw(0x0, base); - outw(0x0, base); - InterruptTheCard(base); - outw(0x0, base + 0x4); /* for ISI4608 cards */ - - board->status |= FIRMWARE_LOADED; - retval = 0; - -errrelfw: - release_firmware(fw); -end: - return retval; -} - -/* - * Insmod can set static symbols so keep these static - */ -static unsigned int card_count; - -static int __devinit isicom_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - unsigned int uninitialized_var(signature), index; - int retval = -EPERM; - struct isi_board *board = NULL; - - if (card_count >= BOARD_COUNT) - goto err; - - retval = pci_enable_device(pdev); - if (retval) { - dev_err(&pdev->dev, "failed to enable\n"); - goto err; - } - - dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device); - - /* allot the first empty slot in the array */ - for (index = 0; index < BOARD_COUNT; index++) { - if (isi_card[index].base == 0) { - board = &isi_card[index]; - break; - } - } - if (index == BOARD_COUNT) { - retval = -ENODEV; - goto err_disable; - } - - board->index = index; - board->base = pci_resource_start(pdev, 3); - board->irq = pdev->irq; - card_count++; - - pci_set_drvdata(pdev, board); - - retval = pci_request_region(pdev, 3, ISICOM_NAME); - if (retval) { - dev_err(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d " - "will be disabled.\n", board->base, board->base + 15, - index + 1); - retval = -EBUSY; - goto errdec; - } - - retval = request_irq(board->irq, isicom_interrupt, - IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board); - if (retval < 0) { - dev_err(&pdev->dev, "Could not install handler at Irq %d. " - "Card%d will be disabled.\n", board->irq, index + 1); - goto errunrr; - } - - retval = reset_card(pdev, index, &signature); - if (retval < 0) - goto errunri; - - retval = load_firmware(pdev, index, signature); - if (retval < 0) - goto errunri; - - for (index = 0; index < board->port_count; index++) - tty_register_device(isicom_normal, board->index * 16 + index, - &pdev->dev); - - return 0; - -errunri: - free_irq(board->irq, board); -errunrr: - pci_release_region(pdev, 3); -errdec: - board->base = 0; - card_count--; -err_disable: - pci_disable_device(pdev); -err: - return retval; -} - -static void __devexit isicom_remove(struct pci_dev *pdev) -{ - struct isi_board *board = pci_get_drvdata(pdev); - unsigned int i; - - for (i = 0; i < board->port_count; i++) - tty_unregister_device(isicom_normal, board->index * 16 + i); - - free_irq(board->irq, board); - pci_release_region(pdev, 3); - board->base = 0; - card_count--; - pci_disable_device(pdev); -} - -static int __init isicom_init(void) -{ - int retval, idx, channel; - struct isi_port *port; - - for (idx = 0; idx < BOARD_COUNT; idx++) { - port = &isi_ports[idx * 16]; - isi_card[idx].ports = port; - spin_lock_init(&isi_card[idx].card_lock); - for (channel = 0; channel < 16; channel++, port++) { - tty_port_init(&port->port); - port->port.ops = &isicom_port_ops; - port->magic = ISICOM_MAGIC; - port->card = &isi_card[idx]; - port->channel = channel; - port->port.close_delay = 50 * HZ/100; - port->port.closing_wait = 3000 * HZ/100; - port->status = 0; - /* . . . */ - } - isi_card[idx].base = 0; - isi_card[idx].irq = 0; - } - - /* tty driver structure initialization */ - isicom_normal = alloc_tty_driver(PORT_COUNT); - if (!isicom_normal) { - retval = -ENOMEM; - goto error; - } - - isicom_normal->owner = THIS_MODULE; - isicom_normal->name = "ttyM"; - isicom_normal->major = ISICOM_NMAJOR; - isicom_normal->minor_start = 0; - isicom_normal->type = TTY_DRIVER_TYPE_SERIAL; - isicom_normal->subtype = SERIAL_TYPE_NORMAL; - isicom_normal->init_termios = tty_std_termios; - isicom_normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | - CLOCAL; - isicom_normal->flags = TTY_DRIVER_REAL_RAW | - TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK; - tty_set_operations(isicom_normal, &isicom_ops); - - retval = tty_register_driver(isicom_normal); - if (retval) { - pr_debug("Couldn't register the dialin driver\n"); - goto err_puttty; - } - - retval = pci_register_driver(&isicom_driver); - if (retval < 0) { - pr_err("Unable to register pci driver.\n"); - goto err_unrtty; - } - - mod_timer(&tx, jiffies + 1); - - return 0; -err_unrtty: - tty_unregister_driver(isicom_normal); -err_puttty: - put_tty_driver(isicom_normal); -error: - return retval; -} - -static void __exit isicom_exit(void) -{ - del_timer_sync(&tx); - - pci_unregister_driver(&isicom_driver); - tty_unregister_driver(isicom_normal); - put_tty_driver(isicom_normal); -} - -module_init(isicom_init); -module_exit(isicom_exit); - -MODULE_AUTHOR("MultiTech"); -MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech"); -MODULE_LICENSE("GPL"); -MODULE_FIRMWARE("isi608.bin"); -MODULE_FIRMWARE("isi608em.bin"); -MODULE_FIRMWARE("isi616em.bin"); -MODULE_FIRMWARE("isi4608.bin"); -MODULE_FIRMWARE("isi4616.bin"); diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c deleted file mode 100644 index 35b0c38590e6..000000000000 --- a/drivers/char/moxa.c +++ /dev/null @@ -1,2092 +0,0 @@ -/*****************************************************************************/ -/* - * moxa.c -- MOXA Intellio family multiport serial driver. - * - * Copyright (C) 1999-2000 Moxa Technologies (support@moxa.com). - * Copyright (c) 2007 Jiri Slaby - * - * This code is loosely based on the Linux serial driver, written by - * Linus Torvalds, Theodore T'so and others. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -/* - * MOXA Intellio Series Driver - * for : LINUX - * date : 1999/1/7 - * version : 5.1 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "moxa.h" - -#define MOXA_VERSION "6.0k" - -#define MOXA_FW_HDRLEN 32 - -#define MOXAMAJOR 172 - -#define MAX_BOARDS 4 /* Don't change this value */ -#define MAX_PORTS_PER_BOARD 32 /* Don't change this value */ -#define MAX_PORTS (MAX_BOARDS * MAX_PORTS_PER_BOARD) - -#define MOXA_IS_320(brd) ((brd)->boardType == MOXA_BOARD_C320_ISA || \ - (brd)->boardType == MOXA_BOARD_C320_PCI) - -/* - * Define the Moxa PCI vendor and device IDs. - */ -#define MOXA_BUS_TYPE_ISA 0 -#define MOXA_BUS_TYPE_PCI 1 - -enum { - MOXA_BOARD_C218_PCI = 1, - MOXA_BOARD_C218_ISA, - MOXA_BOARD_C320_PCI, - MOXA_BOARD_C320_ISA, - MOXA_BOARD_CP204J, -}; - -static char *moxa_brdname[] = -{ - "C218 Turbo PCI series", - "C218 Turbo ISA series", - "C320 Turbo PCI series", - "C320 Turbo ISA series", - "CP-204J series", -}; - -#ifdef CONFIG_PCI -static struct pci_device_id moxa_pcibrds[] = { - { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C218), - .driver_data = MOXA_BOARD_C218_PCI }, - { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C320), - .driver_data = MOXA_BOARD_C320_PCI }, - { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP204J), - .driver_data = MOXA_BOARD_CP204J }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, moxa_pcibrds); -#endif /* CONFIG_PCI */ - -struct moxa_port; - -static struct moxa_board_conf { - int boardType; - int numPorts; - int busType; - - unsigned int ready; - - struct moxa_port *ports; - - void __iomem *basemem; - void __iomem *intNdx; - void __iomem *intPend; - void __iomem *intTable; -} moxa_boards[MAX_BOARDS]; - -struct mxser_mstatus { - tcflag_t cflag; - int cts; - int dsr; - int ri; - int dcd; -}; - -struct moxaq_str { - int inq; - int outq; -}; - -struct moxa_port { - struct tty_port port; - struct moxa_board_conf *board; - void __iomem *tableAddr; - - int type; - int cflag; - unsigned long statusflags; - - u8 DCDState; /* Protected by the port lock */ - u8 lineCtrl; - u8 lowChkFlag; -}; - -struct mon_str { - int tick; - int rxcnt[MAX_PORTS]; - int txcnt[MAX_PORTS]; -}; - -/* statusflags */ -#define TXSTOPPED 1 -#define LOWWAIT 2 -#define EMPTYWAIT 3 - -#define SERIAL_DO_RESTART - -#define WAKEUP_CHARS 256 - -static int ttymajor = MOXAMAJOR; -static struct mon_str moxaLog; -static unsigned int moxaFuncTout = HZ / 2; -static unsigned int moxaLowWaterChk; -static DEFINE_MUTEX(moxa_openlock); -static DEFINE_SPINLOCK(moxa_lock); - -static unsigned long baseaddr[MAX_BOARDS]; -static unsigned int type[MAX_BOARDS]; -static unsigned int numports[MAX_BOARDS]; - -MODULE_AUTHOR("William Chen"); -MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver"); -MODULE_LICENSE("GPL"); -MODULE_FIRMWARE("c218tunx.cod"); -MODULE_FIRMWARE("cp204unx.cod"); -MODULE_FIRMWARE("c320tunx.cod"); - -module_param_array(type, uint, NULL, 0); -MODULE_PARM_DESC(type, "card type: C218=2, C320=4"); -module_param_array(baseaddr, ulong, NULL, 0); -MODULE_PARM_DESC(baseaddr, "base address"); -module_param_array(numports, uint, NULL, 0); -MODULE_PARM_DESC(numports, "numports (ignored for C218)"); - -module_param(ttymajor, int, 0); - -/* - * static functions: - */ -static int moxa_open(struct tty_struct *, struct file *); -static void moxa_close(struct tty_struct *, struct file *); -static int moxa_write(struct tty_struct *, const unsigned char *, int); -static int moxa_write_room(struct tty_struct *); -static void moxa_flush_buffer(struct tty_struct *); -static int moxa_chars_in_buffer(struct tty_struct *); -static void moxa_set_termios(struct tty_struct *, struct ktermios *); -static void moxa_stop(struct tty_struct *); -static void moxa_start(struct tty_struct *); -static void moxa_hangup(struct tty_struct *); -static int moxa_tiocmget(struct tty_struct *tty); -static int moxa_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear); -static void moxa_poll(unsigned long); -static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); -static void moxa_shutdown(struct tty_port *); -static int moxa_carrier_raised(struct tty_port *); -static void moxa_dtr_rts(struct tty_port *, int); -/* - * moxa board interface functions: - */ -static void MoxaPortEnable(struct moxa_port *); -static void MoxaPortDisable(struct moxa_port *); -static int MoxaPortSetTermio(struct moxa_port *, struct ktermios *, speed_t); -static int MoxaPortGetLineOut(struct moxa_port *, int *, int *); -static void MoxaPortLineCtrl(struct moxa_port *, int, int); -static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int); -static int MoxaPortLineStatus(struct moxa_port *); -static void MoxaPortFlushData(struct moxa_port *, int); -static int MoxaPortWriteData(struct tty_struct *, const unsigned char *, int); -static int MoxaPortReadData(struct moxa_port *); -static int MoxaPortTxQueue(struct moxa_port *); -static int MoxaPortRxQueue(struct moxa_port *); -static int MoxaPortTxFree(struct moxa_port *); -static void MoxaPortTxDisable(struct moxa_port *); -static void MoxaPortTxEnable(struct moxa_port *); -static int moxa_get_serial_info(struct moxa_port *, struct serial_struct __user *); -static int moxa_set_serial_info(struct moxa_port *, struct serial_struct __user *); -static void MoxaSetFifo(struct moxa_port *port, int enable); - -/* - * I/O functions - */ - -static DEFINE_SPINLOCK(moxafunc_lock); - -static void moxa_wait_finish(void __iomem *ofsAddr) -{ - unsigned long end = jiffies + moxaFuncTout; - - while (readw(ofsAddr + FuncCode) != 0) - if (time_after(jiffies, end)) - return; - if (readw(ofsAddr + FuncCode) != 0 && printk_ratelimit()) - printk(KERN_WARNING "moxa function expired\n"); -} - -static void moxafunc(void __iomem *ofsAddr, u16 cmd, u16 arg) -{ - unsigned long flags; - spin_lock_irqsave(&moxafunc_lock, flags); - writew(arg, ofsAddr + FuncArg); - writew(cmd, ofsAddr + FuncCode); - moxa_wait_finish(ofsAddr); - spin_unlock_irqrestore(&moxafunc_lock, flags); -} - -static int moxafuncret(void __iomem *ofsAddr, u16 cmd, u16 arg) -{ - unsigned long flags; - u16 ret; - spin_lock_irqsave(&moxafunc_lock, flags); - writew(arg, ofsAddr + FuncArg); - writew(cmd, ofsAddr + FuncCode); - moxa_wait_finish(ofsAddr); - ret = readw(ofsAddr + FuncArg); - spin_unlock_irqrestore(&moxafunc_lock, flags); - return ret; -} - -static void moxa_low_water_check(void __iomem *ofsAddr) -{ - u16 rptr, wptr, mask, len; - - if (readb(ofsAddr + FlagStat) & Xoff_state) { - rptr = readw(ofsAddr + RXrptr); - wptr = readw(ofsAddr + RXwptr); - mask = readw(ofsAddr + RX_mask); - len = (wptr - rptr) & mask; - if (len <= Low_water) - moxafunc(ofsAddr, FC_SendXon, 0); - } -} - -/* - * TTY operations - */ - -static int moxa_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct moxa_port *ch = tty->driver_data; - void __user *argp = (void __user *)arg; - int status, ret = 0; - - if (tty->index == MAX_PORTS) { - if (cmd != MOXA_GETDATACOUNT && cmd != MOXA_GET_IOQUEUE && - cmd != MOXA_GETMSTATUS) - return -EINVAL; - } else if (!ch) - return -ENODEV; - - switch (cmd) { - case MOXA_GETDATACOUNT: - moxaLog.tick = jiffies; - if (copy_to_user(argp, &moxaLog, sizeof(moxaLog))) - ret = -EFAULT; - break; - case MOXA_FLUSH_QUEUE: - MoxaPortFlushData(ch, arg); - break; - case MOXA_GET_IOQUEUE: { - struct moxaq_str __user *argm = argp; - struct moxaq_str tmp; - struct moxa_port *p; - unsigned int i, j; - - for (i = 0; i < MAX_BOARDS; i++) { - p = moxa_boards[i].ports; - for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { - memset(&tmp, 0, sizeof(tmp)); - spin_lock_bh(&moxa_lock); - if (moxa_boards[i].ready) { - tmp.inq = MoxaPortRxQueue(p); - tmp.outq = MoxaPortTxQueue(p); - } - spin_unlock_bh(&moxa_lock); - if (copy_to_user(argm, &tmp, sizeof(tmp))) - return -EFAULT; - } - } - break; - } case MOXA_GET_OQUEUE: - status = MoxaPortTxQueue(ch); - ret = put_user(status, (unsigned long __user *)argp); - break; - case MOXA_GET_IQUEUE: - status = MoxaPortRxQueue(ch); - ret = put_user(status, (unsigned long __user *)argp); - break; - case MOXA_GETMSTATUS: { - struct mxser_mstatus __user *argm = argp; - struct mxser_mstatus tmp; - struct moxa_port *p; - unsigned int i, j; - - for (i = 0; i < MAX_BOARDS; i++) { - p = moxa_boards[i].ports; - for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { - struct tty_struct *ttyp; - memset(&tmp, 0, sizeof(tmp)); - spin_lock_bh(&moxa_lock); - if (!moxa_boards[i].ready) { - spin_unlock_bh(&moxa_lock); - goto copy; - } - - status = MoxaPortLineStatus(p); - spin_unlock_bh(&moxa_lock); - - if (status & 1) - tmp.cts = 1; - if (status & 2) - tmp.dsr = 1; - if (status & 4) - tmp.dcd = 1; - - ttyp = tty_port_tty_get(&p->port); - if (!ttyp || !ttyp->termios) - tmp.cflag = p->cflag; - else - tmp.cflag = ttyp->termios->c_cflag; - tty_kref_put(tty); -copy: - if (copy_to_user(argm, &tmp, sizeof(tmp))) - return -EFAULT; - } - } - break; - } - case TIOCGSERIAL: - mutex_lock(&ch->port.mutex); - ret = moxa_get_serial_info(ch, argp); - mutex_unlock(&ch->port.mutex); - break; - case TIOCSSERIAL: - mutex_lock(&ch->port.mutex); - ret = moxa_set_serial_info(ch, argp); - mutex_unlock(&ch->port.mutex); - break; - default: - ret = -ENOIOCTLCMD; - } - return ret; -} - -static int moxa_break_ctl(struct tty_struct *tty, int state) -{ - struct moxa_port *port = tty->driver_data; - - moxafunc(port->tableAddr, state ? FC_SendBreak : FC_StopBreak, - Magic_code); - return 0; -} - -static const struct tty_operations moxa_ops = { - .open = moxa_open, - .close = moxa_close, - .write = moxa_write, - .write_room = moxa_write_room, - .flush_buffer = moxa_flush_buffer, - .chars_in_buffer = moxa_chars_in_buffer, - .ioctl = moxa_ioctl, - .set_termios = moxa_set_termios, - .stop = moxa_stop, - .start = moxa_start, - .hangup = moxa_hangup, - .break_ctl = moxa_break_ctl, - .tiocmget = moxa_tiocmget, - .tiocmset = moxa_tiocmset, -}; - -static const struct tty_port_operations moxa_port_ops = { - .carrier_raised = moxa_carrier_raised, - .dtr_rts = moxa_dtr_rts, - .shutdown = moxa_shutdown, -}; - -static struct tty_driver *moxaDriver; -static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0); - -/* - * HW init - */ - -static int moxa_check_fw_model(struct moxa_board_conf *brd, u8 model) -{ - switch (brd->boardType) { - case MOXA_BOARD_C218_ISA: - case MOXA_BOARD_C218_PCI: - if (model != 1) - goto err; - break; - case MOXA_BOARD_CP204J: - if (model != 3) - goto err; - break; - default: - if (model != 2) - goto err; - break; - } - return 0; -err: - return -EINVAL; -} - -static int moxa_check_fw(const void *ptr) -{ - const __le16 *lptr = ptr; - - if (*lptr != cpu_to_le16(0x7980)) - return -EINVAL; - - return 0; -} - -static int moxa_load_bios(struct moxa_board_conf *brd, const u8 *buf, - size_t len) -{ - void __iomem *baseAddr = brd->basemem; - u16 tmp; - - writeb(HW_reset, baseAddr + Control_reg); /* reset */ - msleep(10); - memset_io(baseAddr, 0, 4096); - memcpy_toio(baseAddr, buf, len); /* download BIOS */ - writeb(0, baseAddr + Control_reg); /* restart */ - - msleep(2000); - - switch (brd->boardType) { - case MOXA_BOARD_C218_ISA: - case MOXA_BOARD_C218_PCI: - tmp = readw(baseAddr + C218_key); - if (tmp != C218_KeyCode) - goto err; - break; - case MOXA_BOARD_CP204J: - tmp = readw(baseAddr + C218_key); - if (tmp != CP204J_KeyCode) - goto err; - break; - default: - tmp = readw(baseAddr + C320_key); - if (tmp != C320_KeyCode) - goto err; - tmp = readw(baseAddr + C320_status); - if (tmp != STS_init) { - printk(KERN_ERR "MOXA: bios upload failed -- CPU/Basic " - "module not found\n"); - return -EIO; - } - break; - } - - return 0; -err: - printk(KERN_ERR "MOXA: bios upload failed -- board not found\n"); - return -EIO; -} - -static int moxa_load_320b(struct moxa_board_conf *brd, const u8 *ptr, - size_t len) -{ - void __iomem *baseAddr = brd->basemem; - - if (len < 7168) { - printk(KERN_ERR "MOXA: invalid 320 bios -- too short\n"); - return -EINVAL; - } - - writew(len - 7168 - 2, baseAddr + C320bapi_len); - writeb(1, baseAddr + Control_reg); /* Select Page 1 */ - memcpy_toio(baseAddr + DynPage_addr, ptr, 7168); - writeb(2, baseAddr + Control_reg); /* Select Page 2 */ - memcpy_toio(baseAddr + DynPage_addr, ptr + 7168, len - 7168); - - return 0; -} - -static int moxa_real_load_code(struct moxa_board_conf *brd, const void *ptr, - size_t len) -{ - void __iomem *baseAddr = brd->basemem; - const __le16 *uptr = ptr; - size_t wlen, len2, j; - unsigned long key, loadbuf, loadlen, checksum, checksum_ok; - unsigned int i, retry; - u16 usum, keycode; - - keycode = (brd->boardType == MOXA_BOARD_CP204J) ? CP204J_KeyCode : - C218_KeyCode; - - switch (brd->boardType) { - case MOXA_BOARD_CP204J: - case MOXA_BOARD_C218_ISA: - case MOXA_BOARD_C218_PCI: - key = C218_key; - loadbuf = C218_LoadBuf; - loadlen = C218DLoad_len; - checksum = C218check_sum; - checksum_ok = C218chksum_ok; - break; - default: - key = C320_key; - keycode = C320_KeyCode; - loadbuf = C320_LoadBuf; - loadlen = C320DLoad_len; - checksum = C320check_sum; - checksum_ok = C320chksum_ok; - break; - } - - usum = 0; - wlen = len >> 1; - for (i = 0; i < wlen; i++) - usum += le16_to_cpu(uptr[i]); - retry = 0; - do { - wlen = len >> 1; - j = 0; - while (wlen) { - len2 = (wlen > 2048) ? 2048 : wlen; - wlen -= len2; - memcpy_toio(baseAddr + loadbuf, ptr + j, len2 << 1); - j += len2 << 1; - - writew(len2, baseAddr + loadlen); - writew(0, baseAddr + key); - for (i = 0; i < 100; i++) { - if (readw(baseAddr + key) == keycode) - break; - msleep(10); - } - if (readw(baseAddr + key) != keycode) - return -EIO; - } - writew(0, baseAddr + loadlen); - writew(usum, baseAddr + checksum); - writew(0, baseAddr + key); - for (i = 0; i < 100; i++) { - if (readw(baseAddr + key) == keycode) - break; - msleep(10); - } - retry++; - } while ((readb(baseAddr + checksum_ok) != 1) && (retry < 3)); - if (readb(baseAddr + checksum_ok) != 1) - return -EIO; - - writew(0, baseAddr + key); - for (i = 0; i < 600; i++) { - if (readw(baseAddr + Magic_no) == Magic_code) - break; - msleep(10); - } - if (readw(baseAddr + Magic_no) != Magic_code) - return -EIO; - - if (MOXA_IS_320(brd)) { - if (brd->busType == MOXA_BUS_TYPE_PCI) { /* ASIC board */ - writew(0x3800, baseAddr + TMS320_PORT1); - writew(0x3900, baseAddr + TMS320_PORT2); - writew(28499, baseAddr + TMS320_CLOCK); - } else { - writew(0x3200, baseAddr + TMS320_PORT1); - writew(0x3400, baseAddr + TMS320_PORT2); - writew(19999, baseAddr + TMS320_CLOCK); - } - } - writew(1, baseAddr + Disable_IRQ); - writew(0, baseAddr + Magic_no); - for (i = 0; i < 500; i++) { - if (readw(baseAddr + Magic_no) == Magic_code) - break; - msleep(10); - } - if (readw(baseAddr + Magic_no) != Magic_code) - return -EIO; - - if (MOXA_IS_320(brd)) { - j = readw(baseAddr + Module_cnt); - if (j <= 0) - return -EIO; - brd->numPorts = j * 8; - writew(j, baseAddr + Module_no); - writew(0, baseAddr + Magic_no); - for (i = 0; i < 600; i++) { - if (readw(baseAddr + Magic_no) == Magic_code) - break; - msleep(10); - } - if (readw(baseAddr + Magic_no) != Magic_code) - return -EIO; - } - brd->intNdx = baseAddr + IRQindex; - brd->intPend = baseAddr + IRQpending; - brd->intTable = baseAddr + IRQtable; - - return 0; -} - -static int moxa_load_code(struct moxa_board_conf *brd, const void *ptr, - size_t len) -{ - void __iomem *ofsAddr, *baseAddr = brd->basemem; - struct moxa_port *port; - int retval, i; - - if (len % 2) { - printk(KERN_ERR "MOXA: bios length is not even\n"); - return -EINVAL; - } - - retval = moxa_real_load_code(brd, ptr, len); /* may change numPorts */ - if (retval) - return retval; - - switch (brd->boardType) { - case MOXA_BOARD_C218_ISA: - case MOXA_BOARD_C218_PCI: - case MOXA_BOARD_CP204J: - port = brd->ports; - for (i = 0; i < brd->numPorts; i++, port++) { - port->board = brd; - port->DCDState = 0; - port->tableAddr = baseAddr + Extern_table + - Extern_size * i; - ofsAddr = port->tableAddr; - writew(C218rx_mask, ofsAddr + RX_mask); - writew(C218tx_mask, ofsAddr + TX_mask); - writew(C218rx_spage + i * C218buf_pageno, ofsAddr + Page_rxb); - writew(readw(ofsAddr + Page_rxb) + C218rx_pageno, ofsAddr + EndPage_rxb); - - writew(C218tx_spage + i * C218buf_pageno, ofsAddr + Page_txb); - writew(readw(ofsAddr + Page_txb) + C218tx_pageno, ofsAddr + EndPage_txb); - - } - break; - default: - port = brd->ports; - for (i = 0; i < brd->numPorts; i++, port++) { - port->board = brd; - port->DCDState = 0; - port->tableAddr = baseAddr + Extern_table + - Extern_size * i; - ofsAddr = port->tableAddr; - switch (brd->numPorts) { - case 8: - writew(C320p8rx_mask, ofsAddr + RX_mask); - writew(C320p8tx_mask, ofsAddr + TX_mask); - writew(C320p8rx_spage + i * C320p8buf_pgno, ofsAddr + Page_rxb); - writew(readw(ofsAddr + Page_rxb) + C320p8rx_pgno, ofsAddr + EndPage_rxb); - writew(C320p8tx_spage + i * C320p8buf_pgno, ofsAddr + Page_txb); - writew(readw(ofsAddr + Page_txb) + C320p8tx_pgno, ofsAddr + EndPage_txb); - - break; - case 16: - writew(C320p16rx_mask, ofsAddr + RX_mask); - writew(C320p16tx_mask, ofsAddr + TX_mask); - writew(C320p16rx_spage + i * C320p16buf_pgno, ofsAddr + Page_rxb); - writew(readw(ofsAddr + Page_rxb) + C320p16rx_pgno, ofsAddr + EndPage_rxb); - writew(C320p16tx_spage + i * C320p16buf_pgno, ofsAddr + Page_txb); - writew(readw(ofsAddr + Page_txb) + C320p16tx_pgno, ofsAddr + EndPage_txb); - break; - - case 24: - writew(C320p24rx_mask, ofsAddr + RX_mask); - writew(C320p24tx_mask, ofsAddr + TX_mask); - writew(C320p24rx_spage + i * C320p24buf_pgno, ofsAddr + Page_rxb); - writew(readw(ofsAddr + Page_rxb) + C320p24rx_pgno, ofsAddr + EndPage_rxb); - writew(C320p24tx_spage + i * C320p24buf_pgno, ofsAddr + Page_txb); - writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb); - break; - case 32: - writew(C320p32rx_mask, ofsAddr + RX_mask); - writew(C320p32tx_mask, ofsAddr + TX_mask); - writew(C320p32tx_ofs, ofsAddr + Ofs_txb); - writew(C320p32rx_spage + i * C320p32buf_pgno, ofsAddr + Page_rxb); - writew(readb(ofsAddr + Page_rxb), ofsAddr + EndPage_rxb); - writew(C320p32tx_spage + i * C320p32buf_pgno, ofsAddr + Page_txb); - writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb); - break; - } - } - break; - } - return 0; -} - -static int moxa_load_fw(struct moxa_board_conf *brd, const struct firmware *fw) -{ - const void *ptr = fw->data; - char rsn[64]; - u16 lens[5]; - size_t len; - unsigned int a, lenp, lencnt; - int ret = -EINVAL; - struct { - __le32 magic; /* 0x34303430 */ - u8 reserved1[2]; - u8 type; /* UNIX = 3 */ - u8 model; /* C218T=1, C320T=2, CP204=3 */ - u8 reserved2[8]; - __le16 len[5]; - } const *hdr = ptr; - - BUILD_BUG_ON(ARRAY_SIZE(hdr->len) != ARRAY_SIZE(lens)); - - if (fw->size < MOXA_FW_HDRLEN) { - strcpy(rsn, "too short (even header won't fit)"); - goto err; - } - if (hdr->magic != cpu_to_le32(0x30343034)) { - sprintf(rsn, "bad magic: %.8x", le32_to_cpu(hdr->magic)); - goto err; - } - if (hdr->type != 3) { - sprintf(rsn, "not for linux, type is %u", hdr->type); - goto err; - } - if (moxa_check_fw_model(brd, hdr->model)) { - sprintf(rsn, "not for this card, model is %u", hdr->model); - goto err; - } - - len = MOXA_FW_HDRLEN; - lencnt = hdr->model == 2 ? 5 : 3; - for (a = 0; a < ARRAY_SIZE(lens); a++) { - lens[a] = le16_to_cpu(hdr->len[a]); - if (lens[a] && len + lens[a] <= fw->size && - moxa_check_fw(&fw->data[len])) - printk(KERN_WARNING "MOXA firmware: unexpected input " - "at offset %u, but going on\n", (u32)len); - if (!lens[a] && a < lencnt) { - sprintf(rsn, "too few entries in fw file"); - goto err; - } - len += lens[a]; - } - - if (len != fw->size) { - sprintf(rsn, "bad length: %u (should be %u)", (u32)fw->size, - (u32)len); - goto err; - } - - ptr += MOXA_FW_HDRLEN; - lenp = 0; /* bios */ - - strcpy(rsn, "read above"); - - ret = moxa_load_bios(brd, ptr, lens[lenp]); - if (ret) - goto err; - - /* we skip the tty section (lens[1]), since we don't need it */ - ptr += lens[lenp] + lens[lenp + 1]; - lenp += 2; /* comm */ - - if (hdr->model == 2) { - ret = moxa_load_320b(brd, ptr, lens[lenp]); - if (ret) - goto err; - /* skip another tty */ - ptr += lens[lenp] + lens[lenp + 1]; - lenp += 2; - } - - ret = moxa_load_code(brd, ptr, lens[lenp]); - if (ret) - goto err; - - return 0; -err: - printk(KERN_ERR "firmware failed to load, reason: %s\n", rsn); - return ret; -} - -static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev) -{ - const struct firmware *fw; - const char *file; - struct moxa_port *p; - unsigned int i; - int ret; - - brd->ports = kcalloc(MAX_PORTS_PER_BOARD, sizeof(*brd->ports), - GFP_KERNEL); - if (brd->ports == NULL) { - printk(KERN_ERR "cannot allocate memory for ports\n"); - ret = -ENOMEM; - goto err; - } - - for (i = 0, p = brd->ports; i < MAX_PORTS_PER_BOARD; i++, p++) { - tty_port_init(&p->port); - p->port.ops = &moxa_port_ops; - p->type = PORT_16550A; - p->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; - } - - switch (brd->boardType) { - case MOXA_BOARD_C218_ISA: - case MOXA_BOARD_C218_PCI: - file = "c218tunx.cod"; - break; - case MOXA_BOARD_CP204J: - file = "cp204unx.cod"; - break; - default: - file = "c320tunx.cod"; - break; - } - - ret = request_firmware(&fw, file, dev); - if (ret) { - printk(KERN_ERR "MOXA: request_firmware failed. Make sure " - "you've placed '%s' file into your firmware " - "loader directory (e.g. /lib/firmware)\n", - file); - goto err_free; - } - - ret = moxa_load_fw(brd, fw); - - release_firmware(fw); - - if (ret) - goto err_free; - - spin_lock_bh(&moxa_lock); - brd->ready = 1; - if (!timer_pending(&moxaTimer)) - mod_timer(&moxaTimer, jiffies + HZ / 50); - spin_unlock_bh(&moxa_lock); - - return 0; -err_free: - kfree(brd->ports); -err: - return ret; -} - -static void moxa_board_deinit(struct moxa_board_conf *brd) -{ - unsigned int a, opened; - - mutex_lock(&moxa_openlock); - spin_lock_bh(&moxa_lock); - brd->ready = 0; - spin_unlock_bh(&moxa_lock); - - /* pci hot-un-plug support */ - for (a = 0; a < brd->numPorts; a++) - if (brd->ports[a].port.flags & ASYNC_INITIALIZED) { - struct tty_struct *tty = tty_port_tty_get( - &brd->ports[a].port); - if (tty) { - tty_hangup(tty); - tty_kref_put(tty); - } - } - while (1) { - opened = 0; - for (a = 0; a < brd->numPorts; a++) - if (brd->ports[a].port.flags & ASYNC_INITIALIZED) - opened++; - mutex_unlock(&moxa_openlock); - if (!opened) - break; - msleep(50); - mutex_lock(&moxa_openlock); - } - - iounmap(brd->basemem); - brd->basemem = NULL; - kfree(brd->ports); -} - -#ifdef CONFIG_PCI -static int __devinit moxa_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct moxa_board_conf *board; - unsigned int i; - int board_type = ent->driver_data; - int retval; - - retval = pci_enable_device(pdev); - if (retval) { - dev_err(&pdev->dev, "can't enable pci device\n"); - goto err; - } - - for (i = 0; i < MAX_BOARDS; i++) - if (moxa_boards[i].basemem == NULL) - break; - - retval = -ENODEV; - if (i >= MAX_BOARDS) { - dev_warn(&pdev->dev, "more than %u MOXA Intellio family boards " - "found. Board is ignored.\n", MAX_BOARDS); - goto err; - } - - board = &moxa_boards[i]; - - retval = pci_request_region(pdev, 2, "moxa-base"); - if (retval) { - dev_err(&pdev->dev, "can't request pci region 2\n"); - goto err; - } - - board->basemem = ioremap_nocache(pci_resource_start(pdev, 2), 0x4000); - if (board->basemem == NULL) { - dev_err(&pdev->dev, "can't remap io space 2\n"); - goto err_reg; - } - - board->boardType = board_type; - switch (board_type) { - case MOXA_BOARD_C218_ISA: - case MOXA_BOARD_C218_PCI: - board->numPorts = 8; - break; - - case MOXA_BOARD_CP204J: - board->numPorts = 4; - break; - default: - board->numPorts = 0; - break; - } - board->busType = MOXA_BUS_TYPE_PCI; - - retval = moxa_init_board(board, &pdev->dev); - if (retval) - goto err_base; - - pci_set_drvdata(pdev, board); - - dev_info(&pdev->dev, "board '%s' ready (%u ports, firmware loaded)\n", - moxa_brdname[board_type - 1], board->numPorts); - - return 0; -err_base: - iounmap(board->basemem); - board->basemem = NULL; -err_reg: - pci_release_region(pdev, 2); -err: - return retval; -} - -static void __devexit moxa_pci_remove(struct pci_dev *pdev) -{ - struct moxa_board_conf *brd = pci_get_drvdata(pdev); - - moxa_board_deinit(brd); - - pci_release_region(pdev, 2); -} - -static struct pci_driver moxa_pci_driver = { - .name = "moxa", - .id_table = moxa_pcibrds, - .probe = moxa_pci_probe, - .remove = __devexit_p(moxa_pci_remove) -}; -#endif /* CONFIG_PCI */ - -static int __init moxa_init(void) -{ - unsigned int isabrds = 0; - int retval = 0; - struct moxa_board_conf *brd = moxa_boards; - unsigned int i; - - printk(KERN_INFO "MOXA Intellio family driver version %s\n", - MOXA_VERSION); - moxaDriver = alloc_tty_driver(MAX_PORTS + 1); - if (!moxaDriver) - return -ENOMEM; - - moxaDriver->owner = THIS_MODULE; - moxaDriver->name = "ttyMX"; - moxaDriver->major = ttymajor; - moxaDriver->minor_start = 0; - moxaDriver->type = TTY_DRIVER_TYPE_SERIAL; - moxaDriver->subtype = SERIAL_TYPE_NORMAL; - moxaDriver->init_termios = tty_std_termios; - moxaDriver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; - moxaDriver->init_termios.c_ispeed = 9600; - moxaDriver->init_termios.c_ospeed = 9600; - moxaDriver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(moxaDriver, &moxa_ops); - - if (tty_register_driver(moxaDriver)) { - printk(KERN_ERR "can't register MOXA Smartio tty driver!\n"); - put_tty_driver(moxaDriver); - return -1; - } - - /* Find the boards defined from module args. */ - - for (i = 0; i < MAX_BOARDS; i++) { - if (!baseaddr[i]) - break; - if (type[i] == MOXA_BOARD_C218_ISA || - type[i] == MOXA_BOARD_C320_ISA) { - pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n", - isabrds + 1, moxa_brdname[type[i] - 1], - baseaddr[i]); - brd->boardType = type[i]; - brd->numPorts = type[i] == MOXA_BOARD_C218_ISA ? 8 : - numports[i]; - brd->busType = MOXA_BUS_TYPE_ISA; - brd->basemem = ioremap_nocache(baseaddr[i], 0x4000); - if (!brd->basemem) { - printk(KERN_ERR "MOXA: can't remap %lx\n", - baseaddr[i]); - continue; - } - if (moxa_init_board(brd, NULL)) { - iounmap(brd->basemem); - brd->basemem = NULL; - continue; - } - - printk(KERN_INFO "MOXA isa board found at 0x%.8lu and " - "ready (%u ports, firmware loaded)\n", - baseaddr[i], brd->numPorts); - - brd++; - isabrds++; - } - } - -#ifdef CONFIG_PCI - retval = pci_register_driver(&moxa_pci_driver); - if (retval) { - printk(KERN_ERR "Can't register MOXA pci driver!\n"); - if (isabrds) - retval = 0; - } -#endif - - return retval; -} - -static void __exit moxa_exit(void) -{ - unsigned int i; - -#ifdef CONFIG_PCI - pci_unregister_driver(&moxa_pci_driver); -#endif - - for (i = 0; i < MAX_BOARDS; i++) /* ISA boards */ - if (moxa_boards[i].ready) - moxa_board_deinit(&moxa_boards[i]); - - del_timer_sync(&moxaTimer); - - if (tty_unregister_driver(moxaDriver)) - printk(KERN_ERR "Couldn't unregister MOXA Intellio family " - "serial driver\n"); - put_tty_driver(moxaDriver); -} - -module_init(moxa_init); -module_exit(moxa_exit); - -static void moxa_shutdown(struct tty_port *port) -{ - struct moxa_port *ch = container_of(port, struct moxa_port, port); - MoxaPortDisable(ch); - MoxaPortFlushData(ch, 2); - clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); -} - -static int moxa_carrier_raised(struct tty_port *port) -{ - struct moxa_port *ch = container_of(port, struct moxa_port, port); - int dcd; - - spin_lock_irq(&port->lock); - dcd = ch->DCDState; - spin_unlock_irq(&port->lock); - return dcd; -} - -static void moxa_dtr_rts(struct tty_port *port, int onoff) -{ - struct moxa_port *ch = container_of(port, struct moxa_port, port); - MoxaPortLineCtrl(ch, onoff, onoff); -} - - -static int moxa_open(struct tty_struct *tty, struct file *filp) -{ - struct moxa_board_conf *brd; - struct moxa_port *ch; - int port; - int retval; - - port = tty->index; - if (port == MAX_PORTS) { - return capable(CAP_SYS_ADMIN) ? 0 : -EPERM; - } - if (mutex_lock_interruptible(&moxa_openlock)) - return -ERESTARTSYS; - brd = &moxa_boards[port / MAX_PORTS_PER_BOARD]; - if (!brd->ready) { - mutex_unlock(&moxa_openlock); - return -ENODEV; - } - - if (port % MAX_PORTS_PER_BOARD >= brd->numPorts) { - mutex_unlock(&moxa_openlock); - return -ENODEV; - } - - ch = &brd->ports[port % MAX_PORTS_PER_BOARD]; - ch->port.count++; - tty->driver_data = ch; - tty_port_tty_set(&ch->port, tty); - mutex_lock(&ch->port.mutex); - if (!(ch->port.flags & ASYNC_INITIALIZED)) { - ch->statusflags = 0; - moxa_set_tty_param(tty, tty->termios); - MoxaPortLineCtrl(ch, 1, 1); - MoxaPortEnable(ch); - MoxaSetFifo(ch, ch->type == PORT_16550A); - ch->port.flags |= ASYNC_INITIALIZED; - } - mutex_unlock(&ch->port.mutex); - mutex_unlock(&moxa_openlock); - - retval = tty_port_block_til_ready(&ch->port, tty, filp); - if (retval == 0) - set_bit(ASYNCB_NORMAL_ACTIVE, &ch->port.flags); - return retval; -} - -static void moxa_close(struct tty_struct *tty, struct file *filp) -{ - struct moxa_port *ch = tty->driver_data; - ch->cflag = tty->termios->c_cflag; - tty_port_close(&ch->port, tty, filp); -} - -static int moxa_write(struct tty_struct *tty, - const unsigned char *buf, int count) -{ - struct moxa_port *ch = tty->driver_data; - int len; - - if (ch == NULL) - return 0; - - spin_lock_bh(&moxa_lock); - len = MoxaPortWriteData(tty, buf, count); - spin_unlock_bh(&moxa_lock); - - set_bit(LOWWAIT, &ch->statusflags); - return len; -} - -static int moxa_write_room(struct tty_struct *tty) -{ - struct moxa_port *ch; - - if (tty->stopped) - return 0; - ch = tty->driver_data; - if (ch == NULL) - return 0; - return MoxaPortTxFree(ch); -} - -static void moxa_flush_buffer(struct tty_struct *tty) -{ - struct moxa_port *ch = tty->driver_data; - - if (ch == NULL) - return; - MoxaPortFlushData(ch, 1); - tty_wakeup(tty); -} - -static int moxa_chars_in_buffer(struct tty_struct *tty) -{ - struct moxa_port *ch = tty->driver_data; - int chars; - - chars = MoxaPortTxQueue(ch); - if (chars) - /* - * Make it possible to wakeup anything waiting for output - * in tty_ioctl.c, etc. - */ - set_bit(EMPTYWAIT, &ch->statusflags); - return chars; -} - -static int moxa_tiocmget(struct tty_struct *tty) -{ - struct moxa_port *ch = tty->driver_data; - int flag = 0, dtr, rts; - - MoxaPortGetLineOut(ch, &dtr, &rts); - if (dtr) - flag |= TIOCM_DTR; - if (rts) - flag |= TIOCM_RTS; - dtr = MoxaPortLineStatus(ch); - if (dtr & 1) - flag |= TIOCM_CTS; - if (dtr & 2) - flag |= TIOCM_DSR; - if (dtr & 4) - flag |= TIOCM_CD; - return flag; -} - -static int moxa_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct moxa_port *ch; - int port; - int dtr, rts; - - port = tty->index; - mutex_lock(&moxa_openlock); - ch = tty->driver_data; - if (!ch) { - mutex_unlock(&moxa_openlock); - return -EINVAL; - } - - MoxaPortGetLineOut(ch, &dtr, &rts); - if (set & TIOCM_RTS) - rts = 1; - if (set & TIOCM_DTR) - dtr = 1; - if (clear & TIOCM_RTS) - rts = 0; - if (clear & TIOCM_DTR) - dtr = 0; - MoxaPortLineCtrl(ch, dtr, rts); - mutex_unlock(&moxa_openlock); - return 0; -} - -static void moxa_set_termios(struct tty_struct *tty, - struct ktermios *old_termios) -{ - struct moxa_port *ch = tty->driver_data; - - if (ch == NULL) - return; - moxa_set_tty_param(tty, old_termios); - if (!(old_termios->c_cflag & CLOCAL) && C_CLOCAL(tty)) - wake_up_interruptible(&ch->port.open_wait); -} - -static void moxa_stop(struct tty_struct *tty) -{ - struct moxa_port *ch = tty->driver_data; - - if (ch == NULL) - return; - MoxaPortTxDisable(ch); - set_bit(TXSTOPPED, &ch->statusflags); -} - - -static void moxa_start(struct tty_struct *tty) -{ - struct moxa_port *ch = tty->driver_data; - - if (ch == NULL) - return; - - if (!(ch->statusflags & TXSTOPPED)) - return; - - MoxaPortTxEnable(ch); - clear_bit(TXSTOPPED, &ch->statusflags); -} - -static void moxa_hangup(struct tty_struct *tty) -{ - struct moxa_port *ch = tty->driver_data; - tty_port_hangup(&ch->port); -} - -static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) -{ - struct tty_struct *tty; - unsigned long flags; - dcd = !!dcd; - - spin_lock_irqsave(&p->port.lock, flags); - if (dcd != p->DCDState) { - p->DCDState = dcd; - spin_unlock_irqrestore(&p->port.lock, flags); - tty = tty_port_tty_get(&p->port); - if (tty && C_CLOCAL(tty) && !dcd) - tty_hangup(tty); - tty_kref_put(tty); - } - else - spin_unlock_irqrestore(&p->port.lock, flags); -} - -static int moxa_poll_port(struct moxa_port *p, unsigned int handle, - u16 __iomem *ip) -{ - struct tty_struct *tty = tty_port_tty_get(&p->port); - void __iomem *ofsAddr; - unsigned int inited = p->port.flags & ASYNC_INITIALIZED; - u16 intr; - - if (tty) { - if (test_bit(EMPTYWAIT, &p->statusflags) && - MoxaPortTxQueue(p) == 0) { - clear_bit(EMPTYWAIT, &p->statusflags); - tty_wakeup(tty); - } - if (test_bit(LOWWAIT, &p->statusflags) && !tty->stopped && - MoxaPortTxQueue(p) <= WAKEUP_CHARS) { - clear_bit(LOWWAIT, &p->statusflags); - tty_wakeup(tty); - } - - if (inited && !test_bit(TTY_THROTTLED, &tty->flags) && - MoxaPortRxQueue(p) > 0) { /* RX */ - MoxaPortReadData(p); - tty_schedule_flip(tty); - } - } else { - clear_bit(EMPTYWAIT, &p->statusflags); - MoxaPortFlushData(p, 0); /* flush RX */ - } - - if (!handle) /* nothing else to do */ - goto put; - - intr = readw(ip); /* port irq status */ - if (intr == 0) - goto put; - - writew(0, ip); /* ACK port */ - ofsAddr = p->tableAddr; - if (intr & IntrTx) /* disable tx intr */ - writew(readw(ofsAddr + HostStat) & ~WakeupTx, - ofsAddr + HostStat); - - if (!inited) - goto put; - - if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */ - tty_insert_flip_char(tty, 0, TTY_BREAK); - tty_schedule_flip(tty); - } - - if (intr & IntrLine) - moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state); -put: - tty_kref_put(tty); - - return 0; -} - -static void moxa_poll(unsigned long ignored) -{ - struct moxa_board_conf *brd; - u16 __iomem *ip; - unsigned int card, port, served = 0; - - spin_lock(&moxa_lock); - for (card = 0; card < MAX_BOARDS; card++) { - brd = &moxa_boards[card]; - if (!brd->ready) - continue; - - served++; - - ip = NULL; - if (readb(brd->intPend) == 0xff) - ip = brd->intTable + readb(brd->intNdx); - - for (port = 0; port < brd->numPorts; port++) - moxa_poll_port(&brd->ports[port], !!ip, ip + port); - - if (ip) - writeb(0, brd->intPend); /* ACK */ - - if (moxaLowWaterChk) { - struct moxa_port *p = brd->ports; - for (port = 0; port < brd->numPorts; port++, p++) - if (p->lowChkFlag) { - p->lowChkFlag = 0; - moxa_low_water_check(p->tableAddr); - } - } - } - moxaLowWaterChk = 0; - - if (served) - mod_timer(&moxaTimer, jiffies + HZ / 50); - spin_unlock(&moxa_lock); -} - -/******************************************************************************/ - -static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_termios) -{ - register struct ktermios *ts = tty->termios; - struct moxa_port *ch = tty->driver_data; - int rts, cts, txflow, rxflow, xany, baud; - - rts = cts = txflow = rxflow = xany = 0; - if (ts->c_cflag & CRTSCTS) - rts = cts = 1; - if (ts->c_iflag & IXON) - txflow = 1; - if (ts->c_iflag & IXOFF) - rxflow = 1; - if (ts->c_iflag & IXANY) - xany = 1; - - /* Clear the features we don't support */ - ts->c_cflag &= ~CMSPAR; - MoxaPortFlowCtrl(ch, rts, cts, txflow, rxflow, xany); - baud = MoxaPortSetTermio(ch, ts, tty_get_baud_rate(tty)); - if (baud == -1) - baud = tty_termios_baud_rate(old_termios); - /* Not put the baud rate into the termios data */ - tty_encode_baud_rate(tty, baud, baud); -} - -/***************************************************************************** - * Driver level functions: * - *****************************************************************************/ - -static void MoxaPortFlushData(struct moxa_port *port, int mode) -{ - void __iomem *ofsAddr; - if (mode < 0 || mode > 2) - return; - ofsAddr = port->tableAddr; - moxafunc(ofsAddr, FC_FlushQueue, mode); - if (mode != 1) { - port->lowChkFlag = 0; - moxa_low_water_check(ofsAddr); - } -} - -/* - * Moxa Port Number Description: - * - * MOXA serial driver supports up to 4 MOXA-C218/C320 boards. And, - * the port number using in MOXA driver functions will be 0 to 31 for - * first MOXA board, 32 to 63 for second, 64 to 95 for third and 96 - * to 127 for fourth. For example, if you setup three MOXA boards, - * first board is C218, second board is C320-16 and third board is - * C320-32. The port number of first board (C218 - 8 ports) is from - * 0 to 7. The port number of second board (C320 - 16 ports) is form - * 32 to 47. The port number of third board (C320 - 32 ports) is from - * 64 to 95. And those port numbers form 8 to 31, 48 to 63 and 96 to - * 127 will be invalid. - * - * - * Moxa Functions Description: - * - * Function 1: Driver initialization routine, this routine must be - * called when initialized driver. - * Syntax: - * void MoxaDriverInit(); - * - * - * Function 2: Moxa driver private IOCTL command processing. - * Syntax: - * int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port); - * - * unsigned int cmd : IOCTL command - * unsigned long arg : IOCTL argument - * int port : port number (0 - 127) - * - * return: 0 (OK) - * -EINVAL - * -ENOIOCTLCMD - * - * - * Function 6: Enable this port to start Tx/Rx data. - * Syntax: - * void MoxaPortEnable(int port); - * int port : port number (0 - 127) - * - * - * Function 7: Disable this port - * Syntax: - * void MoxaPortDisable(int port); - * int port : port number (0 - 127) - * - * - * Function 10: Setting baud rate of this port. - * Syntax: - * speed_t MoxaPortSetBaud(int port, speed_t baud); - * int port : port number (0 - 127) - * long baud : baud rate (50 - 115200) - * - * return: 0 : this port is invalid or baud < 50 - * 50 - 115200 : the real baud rate set to the port, if - * the argument baud is large than maximun - * available baud rate, the real setting - * baud rate will be the maximun baud rate. - * - * - * Function 12: Configure the port. - * Syntax: - * int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud); - * int port : port number (0 - 127) - * struct ktermios * termio : termio structure pointer - * speed_t baud : baud rate - * - * return: -1 : this port is invalid or termio == NULL - * 0 : setting O.K. - * - * - * Function 13: Get the DTR/RTS state of this port. - * Syntax: - * int MoxaPortGetLineOut(int port, int *dtrState, int *rtsState); - * int port : port number (0 - 127) - * int * dtrState : pointer to INT to receive the current DTR - * state. (if NULL, this function will not - * write to this address) - * int * rtsState : pointer to INT to receive the current RTS - * state. (if NULL, this function will not - * write to this address) - * - * return: -1 : this port is invalid - * 0 : O.K. - * - * - * Function 14: Setting the DTR/RTS output state of this port. - * Syntax: - * void MoxaPortLineCtrl(int port, int dtrState, int rtsState); - * int port : port number (0 - 127) - * int dtrState : DTR output state (0: off, 1: on) - * int rtsState : RTS output state (0: off, 1: on) - * - * - * Function 15: Setting the flow control of this port. - * Syntax: - * void MoxaPortFlowCtrl(int port, int rtsFlow, int ctsFlow, int rxFlow, - * int txFlow,int xany); - * int port : port number (0 - 127) - * int rtsFlow : H/W RTS flow control (0: no, 1: yes) - * int ctsFlow : H/W CTS flow control (0: no, 1: yes) - * int rxFlow : S/W Rx XON/XOFF flow control (0: no, 1: yes) - * int txFlow : S/W Tx XON/XOFF flow control (0: no, 1: yes) - * int xany : S/W XANY flow control (0: no, 1: yes) - * - * - * Function 16: Get ths line status of this port - * Syntax: - * int MoxaPortLineStatus(int port); - * int port : port number (0 - 127) - * - * return: Bit 0 - CTS state (0: off, 1: on) - * Bit 1 - DSR state (0: off, 1: on) - * Bit 2 - DCD state (0: off, 1: on) - * - * - * Function 19: Flush the Rx/Tx buffer data of this port. - * Syntax: - * void MoxaPortFlushData(int port, int mode); - * int port : port number (0 - 127) - * int mode - * 0 : flush the Rx buffer - * 1 : flush the Tx buffer - * 2 : flush the Rx and Tx buffer - * - * - * Function 20: Write data. - * Syntax: - * int MoxaPortWriteData(int port, unsigned char * buffer, int length); - * int port : port number (0 - 127) - * unsigned char * buffer : pointer to write data buffer. - * int length : write data length - * - * return: 0 - length : real write data length - * - * - * Function 21: Read data. - * Syntax: - * int MoxaPortReadData(int port, struct tty_struct *tty); - * int port : port number (0 - 127) - * struct tty_struct *tty : tty for data - * - * return: 0 - length : real read data length - * - * - * Function 24: Get the Tx buffer current queued data bytes - * Syntax: - * int MoxaPortTxQueue(int port); - * int port : port number (0 - 127) - * - * return: .. : Tx buffer current queued data bytes - * - * - * Function 25: Get the Tx buffer current free space - * Syntax: - * int MoxaPortTxFree(int port); - * int port : port number (0 - 127) - * - * return: .. : Tx buffer current free space - * - * - * Function 26: Get the Rx buffer current queued data bytes - * Syntax: - * int MoxaPortRxQueue(int port); - * int port : port number (0 - 127) - * - * return: .. : Rx buffer current queued data bytes - * - * - * Function 28: Disable port data transmission. - * Syntax: - * void MoxaPortTxDisable(int port); - * int port : port number (0 - 127) - * - * - * Function 29: Enable port data transmission. - * Syntax: - * void MoxaPortTxEnable(int port); - * int port : port number (0 - 127) - * - * - * Function 31: Get the received BREAK signal count and reset it. - * Syntax: - * int MoxaPortResetBrkCnt(int port); - * int port : port number (0 - 127) - * - * return: 0 - .. : BREAK signal count - * - * - */ - -static void MoxaPortEnable(struct moxa_port *port) -{ - void __iomem *ofsAddr; - u16 lowwater = 512; - - ofsAddr = port->tableAddr; - writew(lowwater, ofsAddr + Low_water); - if (MOXA_IS_320(port->board)) - moxafunc(ofsAddr, FC_SetBreakIrq, 0); - else - writew(readw(ofsAddr + HostStat) | WakeupBreak, - ofsAddr + HostStat); - - moxafunc(ofsAddr, FC_SetLineIrq, Magic_code); - moxafunc(ofsAddr, FC_FlushQueue, 2); - - moxafunc(ofsAddr, FC_EnableCH, Magic_code); - MoxaPortLineStatus(port); -} - -static void MoxaPortDisable(struct moxa_port *port) -{ - void __iomem *ofsAddr = port->tableAddr; - - moxafunc(ofsAddr, FC_SetFlowCtl, 0); /* disable flow control */ - moxafunc(ofsAddr, FC_ClrLineIrq, Magic_code); - writew(0, ofsAddr + HostStat); - moxafunc(ofsAddr, FC_DisableCH, Magic_code); -} - -static speed_t MoxaPortSetBaud(struct moxa_port *port, speed_t baud) -{ - void __iomem *ofsAddr = port->tableAddr; - unsigned int clock, val; - speed_t max; - - max = MOXA_IS_320(port->board) ? 460800 : 921600; - if (baud < 50) - return 0; - if (baud > max) - baud = max; - clock = 921600; - val = clock / baud; - moxafunc(ofsAddr, FC_SetBaud, val); - baud = clock / val; - return baud; -} - -static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio, - speed_t baud) -{ - void __iomem *ofsAddr; - tcflag_t cflag; - tcflag_t mode = 0; - - ofsAddr = port->tableAddr; - cflag = termio->c_cflag; /* termio->c_cflag */ - - mode = termio->c_cflag & CSIZE; - if (mode == CS5) - mode = MX_CS5; - else if (mode == CS6) - mode = MX_CS6; - else if (mode == CS7) - mode = MX_CS7; - else if (mode == CS8) - mode = MX_CS8; - - if (termio->c_cflag & CSTOPB) { - if (mode == MX_CS5) - mode |= MX_STOP15; - else - mode |= MX_STOP2; - } else - mode |= MX_STOP1; - - if (termio->c_cflag & PARENB) { - if (termio->c_cflag & PARODD) - mode |= MX_PARODD; - else - mode |= MX_PAREVEN; - } else - mode |= MX_PARNONE; - - moxafunc(ofsAddr, FC_SetDataMode, (u16)mode); - - if (MOXA_IS_320(port->board) && baud >= 921600) - return -1; - - baud = MoxaPortSetBaud(port, baud); - - if (termio->c_iflag & (IXON | IXOFF | IXANY)) { - spin_lock_irq(&moxafunc_lock); - writeb(termio->c_cc[VSTART], ofsAddr + FuncArg); - writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1); - writeb(FC_SetXonXoff, ofsAddr + FuncCode); - moxa_wait_finish(ofsAddr); - spin_unlock_irq(&moxafunc_lock); - - } - return baud; -} - -static int MoxaPortGetLineOut(struct moxa_port *port, int *dtrState, - int *rtsState) -{ - if (dtrState) - *dtrState = !!(port->lineCtrl & DTR_ON); - if (rtsState) - *rtsState = !!(port->lineCtrl & RTS_ON); - - return 0; -} - -static void MoxaPortLineCtrl(struct moxa_port *port, int dtr, int rts) -{ - u8 mode = 0; - - if (dtr) - mode |= DTR_ON; - if (rts) - mode |= RTS_ON; - port->lineCtrl = mode; - moxafunc(port->tableAddr, FC_LineControl, mode); -} - -static void MoxaPortFlowCtrl(struct moxa_port *port, int rts, int cts, - int txflow, int rxflow, int txany) -{ - int mode = 0; - - if (rts) - mode |= RTS_FlowCtl; - if (cts) - mode |= CTS_FlowCtl; - if (txflow) - mode |= Tx_FlowCtl; - if (rxflow) - mode |= Rx_FlowCtl; - if (txany) - mode |= IXM_IXANY; - moxafunc(port->tableAddr, FC_SetFlowCtl, mode); -} - -static int MoxaPortLineStatus(struct moxa_port *port) -{ - void __iomem *ofsAddr; - int val; - - ofsAddr = port->tableAddr; - if (MOXA_IS_320(port->board)) - val = moxafuncret(ofsAddr, FC_LineStatus, 0); - else - val = readw(ofsAddr + FlagStat) >> 4; - val &= 0x0B; - if (val & 8) - val |= 4; - moxa_new_dcdstate(port, val & 8); - val &= 7; - return val; -} - -static int MoxaPortWriteData(struct tty_struct *tty, - const unsigned char *buffer, int len) -{ - struct moxa_port *port = tty->driver_data; - void __iomem *baseAddr, *ofsAddr, *ofs; - unsigned int c, total; - u16 head, tail, tx_mask, spage, epage; - u16 pageno, pageofs, bufhead; - - ofsAddr = port->tableAddr; - baseAddr = port->board->basemem; - tx_mask = readw(ofsAddr + TX_mask); - spage = readw(ofsAddr + Page_txb); - epage = readw(ofsAddr + EndPage_txb); - tail = readw(ofsAddr + TXwptr); - head = readw(ofsAddr + TXrptr); - c = (head > tail) ? (head - tail - 1) : (head - tail + tx_mask); - if (c > len) - c = len; - moxaLog.txcnt[port->port.tty->index] += c; - total = c; - if (spage == epage) { - bufhead = readw(ofsAddr + Ofs_txb); - writew(spage, baseAddr + Control_reg); - while (c > 0) { - if (head > tail) - len = head - tail - 1; - else - len = tx_mask + 1 - tail; - len = (c > len) ? len : c; - ofs = baseAddr + DynPage_addr + bufhead + tail; - memcpy_toio(ofs, buffer, len); - buffer += len; - tail = (tail + len) & tx_mask; - c -= len; - } - } else { - pageno = spage + (tail >> 13); - pageofs = tail & Page_mask; - while (c > 0) { - len = Page_size - pageofs; - if (len > c) - len = c; - writeb(pageno, baseAddr + Control_reg); - ofs = baseAddr + DynPage_addr + pageofs; - memcpy_toio(ofs, buffer, len); - buffer += len; - if (++pageno == epage) - pageno = spage; - pageofs = 0; - c -= len; - } - tail = (tail + total) & tx_mask; - } - writew(tail, ofsAddr + TXwptr); - writeb(1, ofsAddr + CD180TXirq); /* start to send */ - return total; -} - -static int MoxaPortReadData(struct moxa_port *port) -{ - struct tty_struct *tty = port->port.tty; - unsigned char *dst; - void __iomem *baseAddr, *ofsAddr, *ofs; - unsigned int count, len, total; - u16 tail, rx_mask, spage, epage; - u16 pageno, pageofs, bufhead, head; - - ofsAddr = port->tableAddr; - baseAddr = port->board->basemem; - head = readw(ofsAddr + RXrptr); - tail = readw(ofsAddr + RXwptr); - rx_mask = readw(ofsAddr + RX_mask); - spage = readw(ofsAddr + Page_rxb); - epage = readw(ofsAddr + EndPage_rxb); - count = (tail >= head) ? (tail - head) : (tail - head + rx_mask + 1); - if (count == 0) - return 0; - - total = count; - moxaLog.rxcnt[tty->index] += total; - if (spage == epage) { - bufhead = readw(ofsAddr + Ofs_rxb); - writew(spage, baseAddr + Control_reg); - while (count > 0) { - ofs = baseAddr + DynPage_addr + bufhead + head; - len = (tail >= head) ? (tail - head) : - (rx_mask + 1 - head); - len = tty_prepare_flip_string(tty, &dst, - min(len, count)); - memcpy_fromio(dst, ofs, len); - head = (head + len) & rx_mask; - count -= len; - } - } else { - pageno = spage + (head >> 13); - pageofs = head & Page_mask; - while (count > 0) { - writew(pageno, baseAddr + Control_reg); - ofs = baseAddr + DynPage_addr + pageofs; - len = tty_prepare_flip_string(tty, &dst, - min(Page_size - pageofs, count)); - memcpy_fromio(dst, ofs, len); - - count -= len; - pageofs = (pageofs + len) & Page_mask; - if (pageofs == 0 && ++pageno == epage) - pageno = spage; - } - head = (head + total) & rx_mask; - } - writew(head, ofsAddr + RXrptr); - if (readb(ofsAddr + FlagStat) & Xoff_state) { - moxaLowWaterChk = 1; - port->lowChkFlag = 1; - } - return total; -} - - -static int MoxaPortTxQueue(struct moxa_port *port) -{ - void __iomem *ofsAddr = port->tableAddr; - u16 rptr, wptr, mask; - - rptr = readw(ofsAddr + TXrptr); - wptr = readw(ofsAddr + TXwptr); - mask = readw(ofsAddr + TX_mask); - return (wptr - rptr) & mask; -} - -static int MoxaPortTxFree(struct moxa_port *port) -{ - void __iomem *ofsAddr = port->tableAddr; - u16 rptr, wptr, mask; - - rptr = readw(ofsAddr + TXrptr); - wptr = readw(ofsAddr + TXwptr); - mask = readw(ofsAddr + TX_mask); - return mask - ((wptr - rptr) & mask); -} - -static int MoxaPortRxQueue(struct moxa_port *port) -{ - void __iomem *ofsAddr = port->tableAddr; - u16 rptr, wptr, mask; - - rptr = readw(ofsAddr + RXrptr); - wptr = readw(ofsAddr + RXwptr); - mask = readw(ofsAddr + RX_mask); - return (wptr - rptr) & mask; -} - -static void MoxaPortTxDisable(struct moxa_port *port) -{ - moxafunc(port->tableAddr, FC_SetXoffState, Magic_code); -} - -static void MoxaPortTxEnable(struct moxa_port *port) -{ - moxafunc(port->tableAddr, FC_SetXonState, Magic_code); -} - -static int moxa_get_serial_info(struct moxa_port *info, - struct serial_struct __user *retinfo) -{ - struct serial_struct tmp = { - .type = info->type, - .line = info->port.tty->index, - .flags = info->port.flags, - .baud_base = 921600, - .close_delay = info->port.close_delay - }; - return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; -} - - -static int moxa_set_serial_info(struct moxa_port *info, - struct serial_struct __user *new_info) -{ - struct serial_struct new_serial; - - if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) - return -EFAULT; - - if (new_serial.irq != 0 || new_serial.port != 0 || - new_serial.custom_divisor != 0 || - new_serial.baud_base != 921600) - return -EPERM; - - if (!capable(CAP_SYS_ADMIN)) { - if (((new_serial.flags & ~ASYNC_USR_MASK) != - (info->port.flags & ~ASYNC_USR_MASK))) - return -EPERM; - } else - info->port.close_delay = new_serial.close_delay * HZ / 100; - - new_serial.flags = (new_serial.flags & ~ASYNC_FLAGS); - new_serial.flags |= (info->port.flags & ASYNC_FLAGS); - - MoxaSetFifo(info, new_serial.type == PORT_16550A); - - info->type = new_serial.type; - return 0; -} - - - -/***************************************************************************** - * Static local functions: * - *****************************************************************************/ - -static void MoxaSetFifo(struct moxa_port *port, int enable) -{ - void __iomem *ofsAddr = port->tableAddr; - - if (!enable) { - moxafunc(ofsAddr, FC_SetRxFIFOTrig, 0); - moxafunc(ofsAddr, FC_SetTxFIFOCnt, 1); - } else { - moxafunc(ofsAddr, FC_SetRxFIFOTrig, 3); - moxafunc(ofsAddr, FC_SetTxFIFOCnt, 16); - } -} diff --git a/drivers/char/moxa.h b/drivers/char/moxa.h deleted file mode 100644 index 87d16ce57be7..000000000000 --- a/drivers/char/moxa.h +++ /dev/null @@ -1,304 +0,0 @@ -#ifndef MOXA_H_FILE -#define MOXA_H_FILE - -#define MOXA 0x400 -#define MOXA_GET_IQUEUE (MOXA + 1) /* get input buffered count */ -#define MOXA_GET_OQUEUE (MOXA + 2) /* get output buffered count */ -#define MOXA_GETDATACOUNT (MOXA + 23) -#define MOXA_GET_IOQUEUE (MOXA + 27) -#define MOXA_FLUSH_QUEUE (MOXA + 28) -#define MOXA_GETMSTATUS (MOXA + 65) - -/* - * System Configuration - */ - -#define Magic_code 0x404 - -/* - * for C218 BIOS initialization - */ -#define C218_ConfBase 0x800 -#define C218_status (C218_ConfBase + 0) /* BIOS running status */ -#define C218_diag (C218_ConfBase + 2) /* diagnostic status */ -#define C218_key (C218_ConfBase + 4) /* WORD (0x218 for C218) */ -#define C218DLoad_len (C218_ConfBase + 6) /* WORD */ -#define C218check_sum (C218_ConfBase + 8) /* BYTE */ -#define C218chksum_ok (C218_ConfBase + 0x0a) /* BYTE (1:ok) */ -#define C218_TestRx (C218_ConfBase + 0x10) /* 8 bytes for 8 ports */ -#define C218_TestTx (C218_ConfBase + 0x18) /* 8 bytes for 8 ports */ -#define C218_RXerr (C218_ConfBase + 0x20) /* 8 bytes for 8 ports */ -#define C218_ErrFlag (C218_ConfBase + 0x28) /* 8 bytes for 8 ports */ - -#define C218_LoadBuf 0x0F00 -#define C218_KeyCode 0x218 -#define CP204J_KeyCode 0x204 - -/* - * for C320 BIOS initialization - */ -#define C320_ConfBase 0x800 -#define C320_LoadBuf 0x0f00 -#define STS_init 0x05 /* for C320_status */ - -#define C320_status C320_ConfBase + 0 /* BIOS running status */ -#define C320_diag C320_ConfBase + 2 /* diagnostic status */ -#define C320_key C320_ConfBase + 4 /* WORD (0320H for C320) */ -#define C320DLoad_len C320_ConfBase + 6 /* WORD */ -#define C320check_sum C320_ConfBase + 8 /* WORD */ -#define C320chksum_ok C320_ConfBase + 0x0a /* WORD (1:ok) */ -#define C320bapi_len C320_ConfBase + 0x0c /* WORD */ -#define C320UART_no C320_ConfBase + 0x0e /* WORD */ - -#define C320_KeyCode 0x320 - -#define FixPage_addr 0x0000 /* starting addr of static page */ -#define DynPage_addr 0x2000 /* starting addr of dynamic page */ -#define C218_start 0x3000 /* starting addr of C218 BIOS prg */ -#define Control_reg 0x1ff0 /* select page and reset control */ -#define HW_reset 0x80 - -/* - * Function Codes - */ -#define FC_CardReset 0x80 -#define FC_ChannelReset 1 /* C320 firmware not supported */ -#define FC_EnableCH 2 -#define FC_DisableCH 3 -#define FC_SetParam 4 -#define FC_SetMode 5 -#define FC_SetRate 6 -#define FC_LineControl 7 -#define FC_LineStatus 8 -#define FC_XmitControl 9 -#define FC_FlushQueue 10 -#define FC_SendBreak 11 -#define FC_StopBreak 12 -#define FC_LoopbackON 13 -#define FC_LoopbackOFF 14 -#define FC_ClrIrqTable 15 -#define FC_SendXon 16 -#define FC_SetTermIrq 17 /* C320 firmware not supported */ -#define FC_SetCntIrq 18 /* C320 firmware not supported */ -#define FC_SetBreakIrq 19 -#define FC_SetLineIrq 20 -#define FC_SetFlowCtl 21 -#define FC_GenIrq 22 -#define FC_InCD180 23 -#define FC_OutCD180 24 -#define FC_InUARTreg 23 -#define FC_OutUARTreg 24 -#define FC_SetXonXoff 25 -#define FC_OutCD180CCR 26 -#define FC_ExtIQueue 27 -#define FC_ExtOQueue 28 -#define FC_ClrLineIrq 29 -#define FC_HWFlowCtl 30 -#define FC_GetClockRate 35 -#define FC_SetBaud 36 -#define FC_SetDataMode 41 -#define FC_GetCCSR 43 -#define FC_GetDataError 45 -#define FC_RxControl 50 -#define FC_ImmSend 51 -#define FC_SetXonState 52 -#define FC_SetXoffState 53 -#define FC_SetRxFIFOTrig 54 -#define FC_SetTxFIFOCnt 55 -#define FC_UnixRate 56 -#define FC_UnixResetTimer 57 - -#define RxFIFOTrig1 0 -#define RxFIFOTrig4 1 -#define RxFIFOTrig8 2 -#define RxFIFOTrig14 3 - -/* - * Dual-Ported RAM - */ -#define DRAM_global 0 -#define INT_data (DRAM_global + 0) -#define Config_base (DRAM_global + 0x108) - -#define IRQindex (INT_data + 0) -#define IRQpending (INT_data + 4) -#define IRQtable (INT_data + 8) - -/* - * Interrupt Status - */ -#define IntrRx 0x01 /* receiver data O.K. */ -#define IntrTx 0x02 /* transmit buffer empty */ -#define IntrFunc 0x04 /* function complete */ -#define IntrBreak 0x08 /* received break */ -#define IntrLine 0x10 /* line status change - for transmitter */ -#define IntrIntr 0x20 /* received INTR code */ -#define IntrQuit 0x40 /* received QUIT code */ -#define IntrEOF 0x80 /* received EOF code */ - -#define IntrRxTrigger 0x100 /* rx data count reach tigger value */ -#define IntrTxTrigger 0x200 /* tx data count below trigger value */ - -#define Magic_no (Config_base + 0) -#define Card_model_no (Config_base + 2) -#define Total_ports (Config_base + 4) -#define Module_cnt (Config_base + 8) -#define Module_no (Config_base + 10) -#define Timer_10ms (Config_base + 14) -#define Disable_IRQ (Config_base + 20) -#define TMS320_PORT1 (Config_base + 22) -#define TMS320_PORT2 (Config_base + 24) -#define TMS320_CLOCK (Config_base + 26) - -/* - * DATA BUFFER in DRAM - */ -#define Extern_table 0x400 /* Base address of the external table - (24 words * 64) total 3K bytes - (24 words * 128) total 6K bytes */ -#define Extern_size 0x60 /* 96 bytes */ -#define RXrptr 0x00 /* read pointer for RX buffer */ -#define RXwptr 0x02 /* write pointer for RX buffer */ -#define TXrptr 0x04 /* read pointer for TX buffer */ -#define TXwptr 0x06 /* write pointer for TX buffer */ -#define HostStat 0x08 /* IRQ flag and general flag */ -#define FlagStat 0x0A -#define FlowControl 0x0C /* B7 B6 B5 B4 B3 B2 B1 B0 */ - /* x x x x | | | | */ - /* | | | + CTS flow */ - /* | | +--- RTS flow */ - /* | +------ TX Xon/Xoff */ - /* +--------- RX Xon/Xoff */ -#define Break_cnt 0x0E /* received break count */ -#define CD180TXirq 0x10 /* if non-0: enable TX irq */ -#define RX_mask 0x12 -#define TX_mask 0x14 -#define Ofs_rxb 0x16 -#define Ofs_txb 0x18 -#define Page_rxb 0x1A -#define Page_txb 0x1C -#define EndPage_rxb 0x1E -#define EndPage_txb 0x20 -#define Data_error 0x22 -#define RxTrigger 0x28 -#define TxTrigger 0x2a - -#define rRXwptr 0x34 -#define Low_water 0x36 - -#define FuncCode 0x40 -#define FuncArg 0x42 -#define FuncArg1 0x44 - -#define C218rx_size 0x2000 /* 8K bytes */ -#define C218tx_size 0x8000 /* 32K bytes */ - -#define C218rx_mask (C218rx_size - 1) -#define C218tx_mask (C218tx_size - 1) - -#define C320p8rx_size 0x2000 -#define C320p8tx_size 0x8000 -#define C320p8rx_mask (C320p8rx_size - 1) -#define C320p8tx_mask (C320p8tx_size - 1) - -#define C320p16rx_size 0x2000 -#define C320p16tx_size 0x4000 -#define C320p16rx_mask (C320p16rx_size - 1) -#define C320p16tx_mask (C320p16tx_size - 1) - -#define C320p24rx_size 0x2000 -#define C320p24tx_size 0x2000 -#define C320p24rx_mask (C320p24rx_size - 1) -#define C320p24tx_mask (C320p24tx_size - 1) - -#define C320p32rx_size 0x1000 -#define C320p32tx_size 0x1000 -#define C320p32rx_mask (C320p32rx_size - 1) -#define C320p32tx_mask (C320p32tx_size - 1) - -#define Page_size 0x2000U -#define Page_mask (Page_size - 1) -#define C218rx_spage 3 -#define C218tx_spage 4 -#define C218rx_pageno 1 -#define C218tx_pageno 4 -#define C218buf_pageno 5 - -#define C320p8rx_spage 3 -#define C320p8tx_spage 4 -#define C320p8rx_pgno 1 -#define C320p8tx_pgno 4 -#define C320p8buf_pgno 5 - -#define C320p16rx_spage 3 -#define C320p16tx_spage 4 -#define C320p16rx_pgno 1 -#define C320p16tx_pgno 2 -#define C320p16buf_pgno 3 - -#define C320p24rx_spage 3 -#define C320p24tx_spage 4 -#define C320p24rx_pgno 1 -#define C320p24tx_pgno 1 -#define C320p24buf_pgno 2 - -#define C320p32rx_spage 3 -#define C320p32tx_ofs C320p32rx_size -#define C320p32tx_spage 3 -#define C320p32buf_pgno 1 - -/* - * Host Status - */ -#define WakeupRx 0x01 -#define WakeupTx 0x02 -#define WakeupBreak 0x08 -#define WakeupLine 0x10 -#define WakeupIntr 0x20 -#define WakeupQuit 0x40 -#define WakeupEOF 0x80 /* used in VTIME control */ -#define WakeupRxTrigger 0x100 -#define WakeupTxTrigger 0x200 -/* - * Flag status - */ -#define Rx_over 0x01 -#define Xoff_state 0x02 -#define Tx_flowOff 0x04 -#define Tx_enable 0x08 -#define CTS_state 0x10 -#define DSR_state 0x20 -#define DCD_state 0x80 -/* - * FlowControl - */ -#define CTS_FlowCtl 1 -#define RTS_FlowCtl 2 -#define Tx_FlowCtl 4 -#define Rx_FlowCtl 8 -#define IXM_IXANY 0x10 - -#define LowWater 128 - -#define DTR_ON 1 -#define RTS_ON 2 -#define CTS_ON 1 -#define DSR_ON 2 -#define DCD_ON 8 - -/* mode definition */ -#define MX_CS8 0x03 -#define MX_CS7 0x02 -#define MX_CS6 0x01 -#define MX_CS5 0x00 - -#define MX_STOP1 0x00 -#define MX_STOP15 0x04 -#define MX_STOP2 0x08 - -#define MX_PARNONE 0x00 -#define MX_PAREVEN 0x40 -#define MX_PARODD 0xC0 - -#endif diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c deleted file mode 100644 index d188f378684d..000000000000 --- a/drivers/char/mxser.c +++ /dev/null @@ -1,2757 +0,0 @@ -/* - * mxser.c -- MOXA Smartio/Industio family multiport serial driver. - * - * Copyright (C) 1999-2006 Moxa Technologies (support@moxa.com). - * Copyright (C) 2006-2008 Jiri Slaby - * - * This code is loosely based on the 1.8 moxa driver which is based on - * Linux serial driver, written by Linus Torvalds, Theodore T'so and - * others. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Fed through a cleanup, indent and remove of non 2.6 code by Alan Cox - * . The original 1.8 code is available on - * www.moxa.com. - * - Fixed x86_64 cleanness - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "mxser.h" - -#define MXSER_VERSION "2.0.5" /* 1.14 */ -#define MXSERMAJOR 174 - -#define MXSER_BOARDS 4 /* Max. boards */ -#define MXSER_PORTS_PER_BOARD 8 /* Max. ports per board */ -#define MXSER_PORTS (MXSER_BOARDS * MXSER_PORTS_PER_BOARD) -#define MXSER_ISR_PASS_LIMIT 100 - -/*CheckIsMoxaMust return value*/ -#define MOXA_OTHER_UART 0x00 -#define MOXA_MUST_MU150_HWID 0x01 -#define MOXA_MUST_MU860_HWID 0x02 - -#define WAKEUP_CHARS 256 - -#define UART_MCR_AFE 0x20 -#define UART_LSR_SPECIAL 0x1E - -#define PCI_DEVICE_ID_POS104UL 0x1044 -#define PCI_DEVICE_ID_CB108 0x1080 -#define PCI_DEVICE_ID_CP102UF 0x1023 -#define PCI_DEVICE_ID_CP112UL 0x1120 -#define PCI_DEVICE_ID_CB114 0x1142 -#define PCI_DEVICE_ID_CP114UL 0x1143 -#define PCI_DEVICE_ID_CB134I 0x1341 -#define PCI_DEVICE_ID_CP138U 0x1380 - - -#define C168_ASIC_ID 1 -#define C104_ASIC_ID 2 -#define C102_ASIC_ID 0xB -#define CI132_ASIC_ID 4 -#define CI134_ASIC_ID 3 -#define CI104J_ASIC_ID 5 - -#define MXSER_HIGHBAUD 1 -#define MXSER_HAS2 2 - -/* This is only for PCI */ -static const struct { - int type; - int tx_fifo; - int rx_fifo; - int xmit_fifo_size; - int rx_high_water; - int rx_trigger; - int rx_low_water; - long max_baud; -} Gpci_uart_info[] = { - {MOXA_OTHER_UART, 16, 16, 16, 14, 14, 1, 921600L}, - {MOXA_MUST_MU150_HWID, 64, 64, 64, 48, 48, 16, 230400L}, - {MOXA_MUST_MU860_HWID, 128, 128, 128, 96, 96, 32, 921600L} -}; -#define UART_INFO_NUM ARRAY_SIZE(Gpci_uart_info) - -struct mxser_cardinfo { - char *name; - unsigned int nports; - unsigned int flags; -}; - -static const struct mxser_cardinfo mxser_cards[] = { -/* 0*/ { "C168 series", 8, }, - { "C104 series", 4, }, - { "CI-104J series", 4, }, - { "C168H/PCI series", 8, }, - { "C104H/PCI series", 4, }, -/* 5*/ { "C102 series", 4, MXSER_HAS2 }, /* C102-ISA */ - { "CI-132 series", 4, MXSER_HAS2 }, - { "CI-134 series", 4, }, - { "CP-132 series", 2, }, - { "CP-114 series", 4, }, -/*10*/ { "CT-114 series", 4, }, - { "CP-102 series", 2, MXSER_HIGHBAUD }, - { "CP-104U series", 4, }, - { "CP-168U series", 8, }, - { "CP-132U series", 2, }, -/*15*/ { "CP-134U series", 4, }, - { "CP-104JU series", 4, }, - { "Moxa UC7000 Serial", 8, }, /* RC7000 */ - { "CP-118U series", 8, }, - { "CP-102UL series", 2, }, -/*20*/ { "CP-102U series", 2, }, - { "CP-118EL series", 8, }, - { "CP-168EL series", 8, }, - { "CP-104EL series", 4, }, - { "CB-108 series", 8, }, -/*25*/ { "CB-114 series", 4, }, - { "CB-134I series", 4, }, - { "CP-138U series", 8, }, - { "POS-104UL series", 4, }, - { "CP-114UL series", 4, }, -/*30*/ { "CP-102UF series", 2, }, - { "CP-112UL series", 2, }, -}; - -/* driver_data correspond to the lines in the structure above - see also ISA probe function before you change something */ -static struct pci_device_id mxser_pcibrds[] = { - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C168), .driver_data = 3 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C104), .driver_data = 4 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132), .driver_data = 8 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP114), .driver_data = 9 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CT114), .driver_data = 10 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102), .driver_data = 11 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104U), .driver_data = 12 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168U), .driver_data = 13 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132U), .driver_data = 14 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP134U), .driver_data = 15 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104JU),.driver_data = 16 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_RC7000), .driver_data = 17 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118U), .driver_data = 18 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102UL),.driver_data = 19 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102U), .driver_data = 20 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118EL),.driver_data = 21 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168EL),.driver_data = 22 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104EL),.driver_data = 23 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB108), .driver_data = 24 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB114), .driver_data = 25 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB134I), .driver_data = 26 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP138U), .driver_data = 27 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL), .driver_data = 28 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP114UL), .driver_data = 29 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP102UF), .driver_data = 30 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP112UL), .driver_data = 31 }, - { } -}; -MODULE_DEVICE_TABLE(pci, mxser_pcibrds); - -static unsigned long ioaddr[MXSER_BOARDS]; -static int ttymajor = MXSERMAJOR; - -/* Variables for insmod */ - -MODULE_AUTHOR("Casper Yang"); -MODULE_DESCRIPTION("MOXA Smartio/Industio Family Multiport Board Device Driver"); -module_param_array(ioaddr, ulong, NULL, 0); -MODULE_PARM_DESC(ioaddr, "ISA io addresses to look for a moxa board"); -module_param(ttymajor, int, 0); -MODULE_LICENSE("GPL"); - -struct mxser_log { - int tick; - unsigned long rxcnt[MXSER_PORTS]; - unsigned long txcnt[MXSER_PORTS]; -}; - -struct mxser_mon { - unsigned long rxcnt; - unsigned long txcnt; - unsigned long up_rxcnt; - unsigned long up_txcnt; - int modem_status; - unsigned char hold_reason; -}; - -struct mxser_mon_ext { - unsigned long rx_cnt[32]; - unsigned long tx_cnt[32]; - unsigned long up_rxcnt[32]; - unsigned long up_txcnt[32]; - int modem_status[32]; - - long baudrate[32]; - int databits[32]; - int stopbits[32]; - int parity[32]; - int flowctrl[32]; - int fifo[32]; - int iftype[32]; -}; - -struct mxser_board; - -struct mxser_port { - struct tty_port port; - struct mxser_board *board; - - unsigned long ioaddr; - unsigned long opmode_ioaddr; - int max_baud; - - int rx_high_water; - int rx_trigger; /* Rx fifo trigger level */ - int rx_low_water; - int baud_base; /* max. speed */ - int type; /* UART type */ - - int x_char; /* xon/xoff character */ - int IER; /* Interrupt Enable Register */ - int MCR; /* Modem control register */ - - unsigned char stop_rx; - unsigned char ldisc_stop_rx; - - int custom_divisor; - unsigned char err_shadow; - - struct async_icount icount; /* kernel counters for 4 input interrupts */ - int timeout; - - int read_status_mask; - int ignore_status_mask; - int xmit_fifo_size; - int xmit_head; - int xmit_tail; - int xmit_cnt; - - struct ktermios normal_termios; - - struct mxser_mon mon_data; - - spinlock_t slock; -}; - -struct mxser_board { - unsigned int idx; - int irq; - const struct mxser_cardinfo *info; - unsigned long vector; - unsigned long vector_mask; - - int chip_flag; - int uart_type; - - struct mxser_port ports[MXSER_PORTS_PER_BOARD]; -}; - -struct mxser_mstatus { - tcflag_t cflag; - int cts; - int dsr; - int ri; - int dcd; -}; - -static struct mxser_board mxser_boards[MXSER_BOARDS]; -static struct tty_driver *mxvar_sdriver; -static struct mxser_log mxvar_log; -static int mxser_set_baud_method[MXSER_PORTS + 1]; - -static void mxser_enable_must_enchance_mode(unsigned long baseio) -{ - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr |= MOXA_MUST_EFR_EFRB_ENABLE; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); - outb(oldlcr, baseio + UART_LCR); -} - -#ifdef CONFIG_PCI -static void mxser_disable_must_enchance_mode(unsigned long baseio) -{ - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_EFRB_ENABLE; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); - outb(oldlcr, baseio + UART_LCR); -} -#endif - -static void mxser_set_must_xon1_value(unsigned long baseio, u8 value) -{ - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_BANK_MASK; - efr |= MOXA_MUST_EFR_BANK0; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); - outb(value, baseio + MOXA_MUST_XON1_REGISTER); - outb(oldlcr, baseio + UART_LCR); -} - -static void mxser_set_must_xoff1_value(unsigned long baseio, u8 value) -{ - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_BANK_MASK; - efr |= MOXA_MUST_EFR_BANK0; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); - outb(value, baseio + MOXA_MUST_XOFF1_REGISTER); - outb(oldlcr, baseio + UART_LCR); -} - -static void mxser_set_must_fifo_value(struct mxser_port *info) -{ - u8 oldlcr; - u8 efr; - - oldlcr = inb(info->ioaddr + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, info->ioaddr + UART_LCR); - - efr = inb(info->ioaddr + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_BANK_MASK; - efr |= MOXA_MUST_EFR_BANK1; - - outb(efr, info->ioaddr + MOXA_MUST_EFR_REGISTER); - outb((u8)info->rx_high_water, info->ioaddr + MOXA_MUST_RBRTH_REGISTER); - outb((u8)info->rx_trigger, info->ioaddr + MOXA_MUST_RBRTI_REGISTER); - outb((u8)info->rx_low_water, info->ioaddr + MOXA_MUST_RBRTL_REGISTER); - outb(oldlcr, info->ioaddr + UART_LCR); -} - -static void mxser_set_must_enum_value(unsigned long baseio, u8 value) -{ - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_BANK_MASK; - efr |= MOXA_MUST_EFR_BANK2; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); - outb(value, baseio + MOXA_MUST_ENUM_REGISTER); - outb(oldlcr, baseio + UART_LCR); -} - -#ifdef CONFIG_PCI -static void mxser_get_must_hardware_id(unsigned long baseio, u8 *pId) -{ - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_BANK_MASK; - efr |= MOXA_MUST_EFR_BANK2; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); - *pId = inb(baseio + MOXA_MUST_HWID_REGISTER); - outb(oldlcr, baseio + UART_LCR); -} -#endif - -static void SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(unsigned long baseio) -{ - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_SF_MASK; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); - outb(oldlcr, baseio + UART_LCR); -} - -static void mxser_enable_must_tx_software_flow_control(unsigned long baseio) -{ - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_SF_TX_MASK; - efr |= MOXA_MUST_EFR_SF_TX1; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); - outb(oldlcr, baseio + UART_LCR); -} - -static void mxser_disable_must_tx_software_flow_control(unsigned long baseio) -{ - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_SF_TX_MASK; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); - outb(oldlcr, baseio + UART_LCR); -} - -static void mxser_enable_must_rx_software_flow_control(unsigned long baseio) -{ - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_SF_RX_MASK; - efr |= MOXA_MUST_EFR_SF_RX1; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); - outb(oldlcr, baseio + UART_LCR); -} - -static void mxser_disable_must_rx_software_flow_control(unsigned long baseio) -{ - u8 oldlcr; - u8 efr; - - oldlcr = inb(baseio + UART_LCR); - outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); - - efr = inb(baseio + MOXA_MUST_EFR_REGISTER); - efr &= ~MOXA_MUST_EFR_SF_RX_MASK; - - outb(efr, baseio + MOXA_MUST_EFR_REGISTER); - outb(oldlcr, baseio + UART_LCR); -} - -#ifdef CONFIG_PCI -static int __devinit CheckIsMoxaMust(unsigned long io) -{ - u8 oldmcr, hwid; - int i; - - outb(0, io + UART_LCR); - mxser_disable_must_enchance_mode(io); - oldmcr = inb(io + UART_MCR); - outb(0, io + UART_MCR); - mxser_set_must_xon1_value(io, 0x11); - if ((hwid = inb(io + UART_MCR)) != 0) { - outb(oldmcr, io + UART_MCR); - return MOXA_OTHER_UART; - } - - mxser_get_must_hardware_id(io, &hwid); - for (i = 1; i < UART_INFO_NUM; i++) { /* 0 = OTHER_UART */ - if (hwid == Gpci_uart_info[i].type) - return (int)hwid; - } - return MOXA_OTHER_UART; -} -#endif - -static void process_txrx_fifo(struct mxser_port *info) -{ - int i; - - if ((info->type == PORT_16450) || (info->type == PORT_8250)) { - info->rx_trigger = 1; - info->rx_high_water = 1; - info->rx_low_water = 1; - info->xmit_fifo_size = 1; - } else - for (i = 0; i < UART_INFO_NUM; i++) - if (info->board->chip_flag == Gpci_uart_info[i].type) { - info->rx_trigger = Gpci_uart_info[i].rx_trigger; - info->rx_low_water = Gpci_uart_info[i].rx_low_water; - info->rx_high_water = Gpci_uart_info[i].rx_high_water; - info->xmit_fifo_size = Gpci_uart_info[i].xmit_fifo_size; - break; - } -} - -static unsigned char mxser_get_msr(int baseaddr, int mode, int port) -{ - static unsigned char mxser_msr[MXSER_PORTS + 1]; - unsigned char status = 0; - - status = inb(baseaddr + UART_MSR); - - mxser_msr[port] &= 0x0F; - mxser_msr[port] |= status; - status = mxser_msr[port]; - if (mode) - mxser_msr[port] = 0; - - return status; -} - -static int mxser_carrier_raised(struct tty_port *port) -{ - struct mxser_port *mp = container_of(port, struct mxser_port, port); - return (inb(mp->ioaddr + UART_MSR) & UART_MSR_DCD)?1:0; -} - -static void mxser_dtr_rts(struct tty_port *port, int on) -{ - struct mxser_port *mp = container_of(port, struct mxser_port, port); - unsigned long flags; - - spin_lock_irqsave(&mp->slock, flags); - if (on) - outb(inb(mp->ioaddr + UART_MCR) | - UART_MCR_DTR | UART_MCR_RTS, mp->ioaddr + UART_MCR); - else - outb(inb(mp->ioaddr + UART_MCR)&~(UART_MCR_DTR | UART_MCR_RTS), - mp->ioaddr + UART_MCR); - spin_unlock_irqrestore(&mp->slock, flags); -} - -static int mxser_set_baud(struct tty_struct *tty, long newspd) -{ - struct mxser_port *info = tty->driver_data; - int quot = 0, baud; - unsigned char cval; - - if (!info->ioaddr) - return -1; - - if (newspd > info->max_baud) - return -1; - - if (newspd == 134) { - quot = 2 * info->baud_base / 269; - tty_encode_baud_rate(tty, 134, 134); - } else if (newspd) { - quot = info->baud_base / newspd; - if (quot == 0) - quot = 1; - baud = info->baud_base/quot; - tty_encode_baud_rate(tty, baud, baud); - } else { - quot = 0; - } - - info->timeout = ((info->xmit_fifo_size * HZ * 10 * quot) / info->baud_base); - info->timeout += HZ / 50; /* Add .02 seconds of slop */ - - if (quot) { - info->MCR |= UART_MCR_DTR; - outb(info->MCR, info->ioaddr + UART_MCR); - } else { - info->MCR &= ~UART_MCR_DTR; - outb(info->MCR, info->ioaddr + UART_MCR); - return 0; - } - - cval = inb(info->ioaddr + UART_LCR); - - outb(cval | UART_LCR_DLAB, info->ioaddr + UART_LCR); /* set DLAB */ - - outb(quot & 0xff, info->ioaddr + UART_DLL); /* LS of divisor */ - outb(quot >> 8, info->ioaddr + UART_DLM); /* MS of divisor */ - outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */ - -#ifdef BOTHER - if (C_BAUD(tty) == BOTHER) { - quot = info->baud_base % newspd; - quot *= 8; - if (quot % newspd > newspd / 2) { - quot /= newspd; - quot++; - } else - quot /= newspd; - - mxser_set_must_enum_value(info->ioaddr, quot); - } else -#endif - mxser_set_must_enum_value(info->ioaddr, 0); - - return 0; -} - -/* - * This routine is called to set the UART divisor registers to match - * the specified baud rate for a serial port. - */ -static int mxser_change_speed(struct tty_struct *tty, - struct ktermios *old_termios) -{ - struct mxser_port *info = tty->driver_data; - unsigned cflag, cval, fcr; - int ret = 0; - unsigned char status; - - cflag = tty->termios->c_cflag; - if (!info->ioaddr) - return ret; - - if (mxser_set_baud_method[tty->index] == 0) - mxser_set_baud(tty, tty_get_baud_rate(tty)); - - /* byte size and parity */ - switch (cflag & CSIZE) { - case CS5: - cval = 0x00; - break; - case CS6: - cval = 0x01; - break; - case CS7: - cval = 0x02; - break; - case CS8: - cval = 0x03; - break; - default: - cval = 0x00; - break; /* too keep GCC shut... */ - } - if (cflag & CSTOPB) - cval |= 0x04; - if (cflag & PARENB) - cval |= UART_LCR_PARITY; - if (!(cflag & PARODD)) - cval |= UART_LCR_EPAR; - if (cflag & CMSPAR) - cval |= UART_LCR_SPAR; - - if ((info->type == PORT_8250) || (info->type == PORT_16450)) { - if (info->board->chip_flag) { - fcr = UART_FCR_ENABLE_FIFO; - fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE; - mxser_set_must_fifo_value(info); - } else - fcr = 0; - } else { - fcr = UART_FCR_ENABLE_FIFO; - if (info->board->chip_flag) { - fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE; - mxser_set_must_fifo_value(info); - } else { - switch (info->rx_trigger) { - case 1: - fcr |= UART_FCR_TRIGGER_1; - break; - case 4: - fcr |= UART_FCR_TRIGGER_4; - break; - case 8: - fcr |= UART_FCR_TRIGGER_8; - break; - default: - fcr |= UART_FCR_TRIGGER_14; - break; - } - } - } - - /* CTS flow control flag and modem status interrupts */ - info->IER &= ~UART_IER_MSI; - info->MCR &= ~UART_MCR_AFE; - if (cflag & CRTSCTS) { - info->port.flags |= ASYNC_CTS_FLOW; - info->IER |= UART_IER_MSI; - if ((info->type == PORT_16550A) || (info->board->chip_flag)) { - info->MCR |= UART_MCR_AFE; - } else { - status = inb(info->ioaddr + UART_MSR); - if (tty->hw_stopped) { - if (status & UART_MSR_CTS) { - tty->hw_stopped = 0; - if (info->type != PORT_16550A && - !info->board->chip_flag) { - outb(info->IER & ~UART_IER_THRI, - info->ioaddr + - UART_IER); - info->IER |= UART_IER_THRI; - outb(info->IER, info->ioaddr + - UART_IER); - } - tty_wakeup(tty); - } - } else { - if (!(status & UART_MSR_CTS)) { - tty->hw_stopped = 1; - if ((info->type != PORT_16550A) && - (!info->board->chip_flag)) { - info->IER &= ~UART_IER_THRI; - outb(info->IER, info->ioaddr + - UART_IER); - } - } - } - } - } else { - info->port.flags &= ~ASYNC_CTS_FLOW; - } - outb(info->MCR, info->ioaddr + UART_MCR); - if (cflag & CLOCAL) { - info->port.flags &= ~ASYNC_CHECK_CD; - } else { - info->port.flags |= ASYNC_CHECK_CD; - info->IER |= UART_IER_MSI; - } - outb(info->IER, info->ioaddr + UART_IER); - - /* - * Set up parity check flag - */ - info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; - if (I_INPCK(tty)) - info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; - if (I_BRKINT(tty) || I_PARMRK(tty)) - info->read_status_mask |= UART_LSR_BI; - - info->ignore_status_mask = 0; - - if (I_IGNBRK(tty)) { - info->ignore_status_mask |= UART_LSR_BI; - info->read_status_mask |= UART_LSR_BI; - /* - * If we're ignore parity and break indicators, ignore - * overruns too. (For real raw support). - */ - if (I_IGNPAR(tty)) { - info->ignore_status_mask |= - UART_LSR_OE | - UART_LSR_PE | - UART_LSR_FE; - info->read_status_mask |= - UART_LSR_OE | - UART_LSR_PE | - UART_LSR_FE; - } - } - if (info->board->chip_flag) { - mxser_set_must_xon1_value(info->ioaddr, START_CHAR(tty)); - mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(tty)); - if (I_IXON(tty)) { - mxser_enable_must_rx_software_flow_control( - info->ioaddr); - } else { - mxser_disable_must_rx_software_flow_control( - info->ioaddr); - } - if (I_IXOFF(tty)) { - mxser_enable_must_tx_software_flow_control( - info->ioaddr); - } else { - mxser_disable_must_tx_software_flow_control( - info->ioaddr); - } - } - - - outb(fcr, info->ioaddr + UART_FCR); /* set fcr */ - outb(cval, info->ioaddr + UART_LCR); - - return ret; -} - -static void mxser_check_modem_status(struct tty_struct *tty, - struct mxser_port *port, int status) -{ - /* update input line counters */ - if (status & UART_MSR_TERI) - port->icount.rng++; - if (status & UART_MSR_DDSR) - port->icount.dsr++; - if (status & UART_MSR_DDCD) - port->icount.dcd++; - if (status & UART_MSR_DCTS) - port->icount.cts++; - port->mon_data.modem_status = status; - wake_up_interruptible(&port->port.delta_msr_wait); - - if ((port->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { - if (status & UART_MSR_DCD) - wake_up_interruptible(&port->port.open_wait); - } - - if (port->port.flags & ASYNC_CTS_FLOW) { - if (tty->hw_stopped) { - if (status & UART_MSR_CTS) { - tty->hw_stopped = 0; - - if ((port->type != PORT_16550A) && - (!port->board->chip_flag)) { - outb(port->IER & ~UART_IER_THRI, - port->ioaddr + UART_IER); - port->IER |= UART_IER_THRI; - outb(port->IER, port->ioaddr + - UART_IER); - } - tty_wakeup(tty); - } - } else { - if (!(status & UART_MSR_CTS)) { - tty->hw_stopped = 1; - if (port->type != PORT_16550A && - !port->board->chip_flag) { - port->IER &= ~UART_IER_THRI; - outb(port->IER, port->ioaddr + - UART_IER); - } - } - } - } -} - -static int mxser_activate(struct tty_port *port, struct tty_struct *tty) -{ - struct mxser_port *info = container_of(port, struct mxser_port, port); - unsigned long page; - unsigned long flags; - - page = __get_free_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - - spin_lock_irqsave(&info->slock, flags); - - if (!info->ioaddr || !info->type) { - set_bit(TTY_IO_ERROR, &tty->flags); - free_page(page); - spin_unlock_irqrestore(&info->slock, flags); - return 0; - } - info->port.xmit_buf = (unsigned char *) page; - - /* - * Clear the FIFO buffers and disable them - * (they will be reenabled in mxser_change_speed()) - */ - if (info->board->chip_flag) - outb((UART_FCR_CLEAR_RCVR | - UART_FCR_CLEAR_XMIT | - MOXA_MUST_FCR_GDA_MODE_ENABLE), info->ioaddr + UART_FCR); - else - outb((UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), - info->ioaddr + UART_FCR); - - /* - * At this point there's no way the LSR could still be 0xFF; - * if it is, then bail out, because there's likely no UART - * here. - */ - if (inb(info->ioaddr + UART_LSR) == 0xff) { - spin_unlock_irqrestore(&info->slock, flags); - if (capable(CAP_SYS_ADMIN)) { - set_bit(TTY_IO_ERROR, &tty->flags); - return 0; - } else - return -ENODEV; - } - - /* - * Clear the interrupt registers. - */ - (void) inb(info->ioaddr + UART_LSR); - (void) inb(info->ioaddr + UART_RX); - (void) inb(info->ioaddr + UART_IIR); - (void) inb(info->ioaddr + UART_MSR); - - /* - * Now, initialize the UART - */ - outb(UART_LCR_WLEN8, info->ioaddr + UART_LCR); /* reset DLAB */ - info->MCR = UART_MCR_DTR | UART_MCR_RTS; - outb(info->MCR, info->ioaddr + UART_MCR); - - /* - * Finally, enable interrupts - */ - info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI; - - if (info->board->chip_flag) - info->IER |= MOXA_MUST_IER_EGDAI; - outb(info->IER, info->ioaddr + UART_IER); /* enable interrupts */ - - /* - * And clear the interrupt registers again for luck. - */ - (void) inb(info->ioaddr + UART_LSR); - (void) inb(info->ioaddr + UART_RX); - (void) inb(info->ioaddr + UART_IIR); - (void) inb(info->ioaddr + UART_MSR); - - clear_bit(TTY_IO_ERROR, &tty->flags); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - - /* - * and set the speed of the serial port - */ - mxser_change_speed(tty, NULL); - spin_unlock_irqrestore(&info->slock, flags); - - return 0; -} - -/* - * This routine will shutdown a serial port - */ -static void mxser_shutdown_port(struct tty_port *port) -{ - struct mxser_port *info = container_of(port, struct mxser_port, port); - unsigned long flags; - - spin_lock_irqsave(&info->slock, flags); - - /* - * clear delta_msr_wait queue to avoid mem leaks: we may free the irq - * here so the queue might never be waken up - */ - wake_up_interruptible(&info->port.delta_msr_wait); - - /* - * Free the xmit buffer, if necessary - */ - if (info->port.xmit_buf) { - free_page((unsigned long) info->port.xmit_buf); - info->port.xmit_buf = NULL; - } - - info->IER = 0; - outb(0x00, info->ioaddr + UART_IER); - - /* clear Rx/Tx FIFO's */ - if (info->board->chip_flag) - outb(UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT | - MOXA_MUST_FCR_GDA_MODE_ENABLE, - info->ioaddr + UART_FCR); - else - outb(UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, - info->ioaddr + UART_FCR); - - /* read data port to reset things */ - (void) inb(info->ioaddr + UART_RX); - - - if (info->board->chip_flag) - SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->ioaddr); - - spin_unlock_irqrestore(&info->slock, flags); -} - -/* - * This routine is called whenever a serial port is opened. It - * enables interrupts for a serial port, linking in its async structure into - * the IRQ chain. It also performs the serial-specific - * initialization for the tty structure. - */ -static int mxser_open(struct tty_struct *tty, struct file *filp) -{ - struct mxser_port *info; - int line; - - line = tty->index; - if (line == MXSER_PORTS) - return 0; - if (line < 0 || line > MXSER_PORTS) - return -ENODEV; - info = &mxser_boards[line / MXSER_PORTS_PER_BOARD].ports[line % MXSER_PORTS_PER_BOARD]; - if (!info->ioaddr) - return -ENODEV; - - tty->driver_data = info; - return tty_port_open(&info->port, tty, filp); -} - -static void mxser_flush_buffer(struct tty_struct *tty) -{ - struct mxser_port *info = tty->driver_data; - char fcr; - unsigned long flags; - - - spin_lock_irqsave(&info->slock, flags); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - - fcr = inb(info->ioaddr + UART_FCR); - outb((fcr | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), - info->ioaddr + UART_FCR); - outb(fcr, info->ioaddr + UART_FCR); - - spin_unlock_irqrestore(&info->slock, flags); - - tty_wakeup(tty); -} - - -static void mxser_close_port(struct tty_port *port) -{ - struct mxser_port *info = container_of(port, struct mxser_port, port); - unsigned long timeout; - /* - * At this point we stop accepting input. To do this, we - * disable the receive line status interrupts, and tell the - * interrupt driver to stop checking the data ready bit in the - * line status register. - */ - info->IER &= ~UART_IER_RLSI; - if (info->board->chip_flag) - info->IER &= ~MOXA_MUST_RECV_ISR; - - outb(info->IER, info->ioaddr + UART_IER); - /* - * Before we drop DTR, make sure the UART transmitter - * has completely drained; this is especially - * important if there is a transmit FIFO! - */ - timeout = jiffies + HZ; - while (!(inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT)) { - schedule_timeout_interruptible(5); - if (time_after(jiffies, timeout)) - break; - } -} - -/* - * This routine is called when the serial port gets closed. First, we - * wait for the last remaining data to be sent. Then, we unlink its - * async structure from the interrupt chain if necessary, and we free - * that IRQ if nothing is left in the chain. - */ -static void mxser_close(struct tty_struct *tty, struct file *filp) -{ - struct mxser_port *info = tty->driver_data; - struct tty_port *port = &info->port; - - if (tty->index == MXSER_PORTS || info == NULL) - return; - if (tty_port_close_start(port, tty, filp) == 0) - return; - mutex_lock(&port->mutex); - mxser_close_port(port); - mxser_flush_buffer(tty); - mxser_shutdown_port(port); - clear_bit(ASYNCB_INITIALIZED, &port->flags); - mutex_unlock(&port->mutex); - /* Right now the tty_port set is done outside of the close_end helper - as we don't yet have everyone using refcounts */ - tty_port_close_end(port, tty); - tty_port_tty_set(port, NULL); -} - -static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count) -{ - int c, total = 0; - struct mxser_port *info = tty->driver_data; - unsigned long flags; - - if (!info->port.xmit_buf) - return 0; - - while (1) { - c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - if (c <= 0) - break; - - memcpy(info->port.xmit_buf + info->xmit_head, buf, c); - spin_lock_irqsave(&info->slock, flags); - info->xmit_head = (info->xmit_head + c) & - (SERIAL_XMIT_SIZE - 1); - info->xmit_cnt += c; - spin_unlock_irqrestore(&info->slock, flags); - - buf += c; - count -= c; - total += c; - } - - if (info->xmit_cnt && !tty->stopped) { - if (!tty->hw_stopped || - (info->type == PORT_16550A) || - (info->board->chip_flag)) { - spin_lock_irqsave(&info->slock, flags); - outb(info->IER & ~UART_IER_THRI, info->ioaddr + - UART_IER); - info->IER |= UART_IER_THRI; - outb(info->IER, info->ioaddr + UART_IER); - spin_unlock_irqrestore(&info->slock, flags); - } - } - return total; -} - -static int mxser_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct mxser_port *info = tty->driver_data; - unsigned long flags; - - if (!info->port.xmit_buf) - return 0; - - if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) - return 0; - - spin_lock_irqsave(&info->slock, flags); - info->port.xmit_buf[info->xmit_head++] = ch; - info->xmit_head &= SERIAL_XMIT_SIZE - 1; - info->xmit_cnt++; - spin_unlock_irqrestore(&info->slock, flags); - if (!tty->stopped) { - if (!tty->hw_stopped || - (info->type == PORT_16550A) || - info->board->chip_flag) { - spin_lock_irqsave(&info->slock, flags); - outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER); - info->IER |= UART_IER_THRI; - outb(info->IER, info->ioaddr + UART_IER); - spin_unlock_irqrestore(&info->slock, flags); - } - } - return 1; -} - - -static void mxser_flush_chars(struct tty_struct *tty) -{ - struct mxser_port *info = tty->driver_data; - unsigned long flags; - - if (info->xmit_cnt <= 0 || tty->stopped || !info->port.xmit_buf || - (tty->hw_stopped && info->type != PORT_16550A && - !info->board->chip_flag)) - return; - - spin_lock_irqsave(&info->slock, flags); - - outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER); - info->IER |= UART_IER_THRI; - outb(info->IER, info->ioaddr + UART_IER); - - spin_unlock_irqrestore(&info->slock, flags); -} - -static int mxser_write_room(struct tty_struct *tty) -{ - struct mxser_port *info = tty->driver_data; - int ret; - - ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; - return ret < 0 ? 0 : ret; -} - -static int mxser_chars_in_buffer(struct tty_struct *tty) -{ - struct mxser_port *info = tty->driver_data; - return info->xmit_cnt; -} - -/* - * ------------------------------------------------------------ - * friends of mxser_ioctl() - * ------------------------------------------------------------ - */ -static int mxser_get_serial_info(struct tty_struct *tty, - struct serial_struct __user *retinfo) -{ - struct mxser_port *info = tty->driver_data; - struct serial_struct tmp = { - .type = info->type, - .line = tty->index, - .port = info->ioaddr, - .irq = info->board->irq, - .flags = info->port.flags, - .baud_base = info->baud_base, - .close_delay = info->port.close_delay, - .closing_wait = info->port.closing_wait, - .custom_divisor = info->custom_divisor, - .hub6 = 0 - }; - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int mxser_set_serial_info(struct tty_struct *tty, - struct serial_struct __user *new_info) -{ - struct mxser_port *info = tty->driver_data; - struct tty_port *port = &info->port; - struct serial_struct new_serial; - speed_t baud; - unsigned long sl_flags; - unsigned int flags; - int retval = 0; - - if (!new_info || !info->ioaddr) - return -ENODEV; - if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) - return -EFAULT; - - if (new_serial.irq != info->board->irq || - new_serial.port != info->ioaddr) - return -EINVAL; - - flags = port->flags & ASYNC_SPD_MASK; - - if (!capable(CAP_SYS_ADMIN)) { - if ((new_serial.baud_base != info->baud_base) || - (new_serial.close_delay != info->port.close_delay) || - ((new_serial.flags & ~ASYNC_USR_MASK) != (info->port.flags & ~ASYNC_USR_MASK))) - return -EPERM; - info->port.flags = ((info->port.flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - } else { - /* - * OK, past this point, all the error checking has been done. - * At this point, we start making changes..... - */ - port->flags = ((port->flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS)); - port->close_delay = new_serial.close_delay * HZ / 100; - port->closing_wait = new_serial.closing_wait * HZ / 100; - tty->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && - (new_serial.baud_base != info->baud_base || - new_serial.custom_divisor != - info->custom_divisor)) { - if (new_serial.custom_divisor == 0) - return -EINVAL; - baud = new_serial.baud_base / new_serial.custom_divisor; - tty_encode_baud_rate(tty, baud, baud); - } - } - - info->type = new_serial.type; - - process_txrx_fifo(info); - - if (test_bit(ASYNCB_INITIALIZED, &port->flags)) { - if (flags != (port->flags & ASYNC_SPD_MASK)) { - spin_lock_irqsave(&info->slock, sl_flags); - mxser_change_speed(tty, NULL); - spin_unlock_irqrestore(&info->slock, sl_flags); - } - } else { - retval = mxser_activate(port, tty); - if (retval == 0) - set_bit(ASYNCB_INITIALIZED, &port->flags); - } - return retval; -} - -/* - * mxser_get_lsr_info - get line status register info - * - * Purpose: Let user call ioctl() to get info when the UART physically - * is emptied. On bus types like RS485, the transmitter must - * release the bus after transmitting. This must be done when - * the transmit shift register is empty, not be done when the - * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. - */ -static int mxser_get_lsr_info(struct mxser_port *info, - unsigned int __user *value) -{ - unsigned char status; - unsigned int result; - unsigned long flags; - - spin_lock_irqsave(&info->slock, flags); - status = inb(info->ioaddr + UART_LSR); - spin_unlock_irqrestore(&info->slock, flags); - result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); - return put_user(result, value); -} - -static int mxser_tiocmget(struct tty_struct *tty) -{ - struct mxser_port *info = tty->driver_data; - unsigned char control, status; - unsigned long flags; - - - if (tty->index == MXSER_PORTS) - return -ENOIOCTLCMD; - if (test_bit(TTY_IO_ERROR, &tty->flags)) - return -EIO; - - control = info->MCR; - - spin_lock_irqsave(&info->slock, flags); - status = inb(info->ioaddr + UART_MSR); - if (status & UART_MSR_ANY_DELTA) - mxser_check_modem_status(tty, info, status); - spin_unlock_irqrestore(&info->slock, flags); - return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | - ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | - ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) | - ((status & UART_MSR_RI) ? TIOCM_RNG : 0) | - ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) | - ((status & UART_MSR_CTS) ? TIOCM_CTS : 0); -} - -static int mxser_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct mxser_port *info = tty->driver_data; - unsigned long flags; - - - if (tty->index == MXSER_PORTS) - return -ENOIOCTLCMD; - if (test_bit(TTY_IO_ERROR, &tty->flags)) - return -EIO; - - spin_lock_irqsave(&info->slock, flags); - - if (set & TIOCM_RTS) - info->MCR |= UART_MCR_RTS; - if (set & TIOCM_DTR) - info->MCR |= UART_MCR_DTR; - - if (clear & TIOCM_RTS) - info->MCR &= ~UART_MCR_RTS; - if (clear & TIOCM_DTR) - info->MCR &= ~UART_MCR_DTR; - - outb(info->MCR, info->ioaddr + UART_MCR); - spin_unlock_irqrestore(&info->slock, flags); - return 0; -} - -static int __init mxser_program_mode(int port) -{ - int id, i, j, n; - - outb(0, port); - outb(0, port); - outb(0, port); - (void)inb(port); - (void)inb(port); - outb(0, port); - (void)inb(port); - - id = inb(port + 1) & 0x1F; - if ((id != C168_ASIC_ID) && - (id != C104_ASIC_ID) && - (id != C102_ASIC_ID) && - (id != CI132_ASIC_ID) && - (id != CI134_ASIC_ID) && - (id != CI104J_ASIC_ID)) - return -1; - for (i = 0, j = 0; i < 4; i++) { - n = inb(port + 2); - if (n == 'M') { - j = 1; - } else if ((j == 1) && (n == 1)) { - j = 2; - break; - } else - j = 0; - } - if (j != 2) - id = -2; - return id; -} - -static void __init mxser_normal_mode(int port) -{ - int i, n; - - outb(0xA5, port + 1); - outb(0x80, port + 3); - outb(12, port + 0); /* 9600 bps */ - outb(0, port + 1); - outb(0x03, port + 3); /* 8 data bits */ - outb(0x13, port + 4); /* loop back mode */ - for (i = 0; i < 16; i++) { - n = inb(port + 5); - if ((n & 0x61) == 0x60) - break; - if ((n & 1) == 1) - (void)inb(port); - } - outb(0x00, port + 4); -} - -#define CHIP_SK 0x01 /* Serial Data Clock in Eprom */ -#define CHIP_DO 0x02 /* Serial Data Output in Eprom */ -#define CHIP_CS 0x04 /* Serial Chip Select in Eprom */ -#define CHIP_DI 0x08 /* Serial Data Input in Eprom */ -#define EN_CCMD 0x000 /* Chip's command register */ -#define EN0_RSARLO 0x008 /* Remote start address reg 0 */ -#define EN0_RSARHI 0x009 /* Remote start address reg 1 */ -#define EN0_RCNTLO 0x00A /* Remote byte count reg WR */ -#define EN0_RCNTHI 0x00B /* Remote byte count reg WR */ -#define EN0_DCFG 0x00E /* Data configuration reg WR */ -#define EN0_PORT 0x010 /* Rcv missed frame error counter RD */ -#define ENC_PAGE0 0x000 /* Select page 0 of chip registers */ -#define ENC_PAGE3 0x0C0 /* Select page 3 of chip registers */ -static int __init mxser_read_register(int port, unsigned short *regs) -{ - int i, k, value, id; - unsigned int j; - - id = mxser_program_mode(port); - if (id < 0) - return id; - for (i = 0; i < 14; i++) { - k = (i & 0x3F) | 0x180; - for (j = 0x100; j > 0; j >>= 1) { - outb(CHIP_CS, port); - if (k & j) { - outb(CHIP_CS | CHIP_DO, port); - outb(CHIP_CS | CHIP_DO | CHIP_SK, port); /* A? bit of read */ - } else { - outb(CHIP_CS, port); - outb(CHIP_CS | CHIP_SK, port); /* A? bit of read */ - } - } - (void)inb(port); - value = 0; - for (k = 0, j = 0x8000; k < 16; k++, j >>= 1) { - outb(CHIP_CS, port); - outb(CHIP_CS | CHIP_SK, port); - if (inb(port) & CHIP_DI) - value |= j; - } - regs[i] = value; - outb(0, port); - } - mxser_normal_mode(port); - return id; -} - -static int mxser_ioctl_special(unsigned int cmd, void __user *argp) -{ - struct mxser_port *ip; - struct tty_port *port; - struct tty_struct *tty; - int result, status; - unsigned int i, j; - int ret = 0; - - switch (cmd) { - case MOXA_GET_MAJOR: - if (printk_ratelimit()) - printk(KERN_WARNING "mxser: '%s' uses deprecated ioctl " - "%x (GET_MAJOR), fix your userspace\n", - current->comm, cmd); - return put_user(ttymajor, (int __user *)argp); - - case MOXA_CHKPORTENABLE: - result = 0; - for (i = 0; i < MXSER_BOARDS; i++) - for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) - if (mxser_boards[i].ports[j].ioaddr) - result |= (1 << i); - return put_user(result, (unsigned long __user *)argp); - case MOXA_GETDATACOUNT: - /* The receive side is locked by port->slock but it isn't - clear that an exact snapshot is worth copying here */ - if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log))) - ret = -EFAULT; - return ret; - case MOXA_GETMSTATUS: { - struct mxser_mstatus ms, __user *msu = argp; - for (i = 0; i < MXSER_BOARDS; i++) - for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) { - ip = &mxser_boards[i].ports[j]; - port = &ip->port; - memset(&ms, 0, sizeof(ms)); - - mutex_lock(&port->mutex); - if (!ip->ioaddr) - goto copy; - - tty = tty_port_tty_get(port); - - if (!tty || !tty->termios) - ms.cflag = ip->normal_termios.c_cflag; - else - ms.cflag = tty->termios->c_cflag; - tty_kref_put(tty); - spin_lock_irq(&ip->slock); - status = inb(ip->ioaddr + UART_MSR); - spin_unlock_irq(&ip->slock); - if (status & UART_MSR_DCD) - ms.dcd = 1; - if (status & UART_MSR_DSR) - ms.dsr = 1; - if (status & UART_MSR_CTS) - ms.cts = 1; - copy: - mutex_unlock(&port->mutex); - if (copy_to_user(msu, &ms, sizeof(ms))) - return -EFAULT; - msu++; - } - return 0; - } - case MOXA_ASPP_MON_EXT: { - struct mxser_mon_ext *me; /* it's 2k, stack unfriendly */ - unsigned int cflag, iflag, p; - u8 opmode; - - me = kzalloc(sizeof(*me), GFP_KERNEL); - if (!me) - return -ENOMEM; - - for (i = 0, p = 0; i < MXSER_BOARDS; i++) { - for (j = 0; j < MXSER_PORTS_PER_BOARD; j++, p++) { - if (p >= ARRAY_SIZE(me->rx_cnt)) { - i = MXSER_BOARDS; - break; - } - ip = &mxser_boards[i].ports[j]; - port = &ip->port; - - mutex_lock(&port->mutex); - if (!ip->ioaddr) { - mutex_unlock(&port->mutex); - continue; - } - - spin_lock_irq(&ip->slock); - status = mxser_get_msr(ip->ioaddr, 0, p); - - if (status & UART_MSR_TERI) - ip->icount.rng++; - if (status & UART_MSR_DDSR) - ip->icount.dsr++; - if (status & UART_MSR_DDCD) - ip->icount.dcd++; - if (status & UART_MSR_DCTS) - ip->icount.cts++; - - ip->mon_data.modem_status = status; - me->rx_cnt[p] = ip->mon_data.rxcnt; - me->tx_cnt[p] = ip->mon_data.txcnt; - me->up_rxcnt[p] = ip->mon_data.up_rxcnt; - me->up_txcnt[p] = ip->mon_data.up_txcnt; - me->modem_status[p] = - ip->mon_data.modem_status; - spin_unlock_irq(&ip->slock); - - tty = tty_port_tty_get(&ip->port); - - if (!tty || !tty->termios) { - cflag = ip->normal_termios.c_cflag; - iflag = ip->normal_termios.c_iflag; - me->baudrate[p] = tty_termios_baud_rate(&ip->normal_termios); - } else { - cflag = tty->termios->c_cflag; - iflag = tty->termios->c_iflag; - me->baudrate[p] = tty_get_baud_rate(tty); - } - tty_kref_put(tty); - - me->databits[p] = cflag & CSIZE; - me->stopbits[p] = cflag & CSTOPB; - me->parity[p] = cflag & (PARENB | PARODD | - CMSPAR); - - if (cflag & CRTSCTS) - me->flowctrl[p] |= 0x03; - - if (iflag & (IXON | IXOFF)) - me->flowctrl[p] |= 0x0C; - - if (ip->type == PORT_16550A) - me->fifo[p] = 1; - - opmode = inb(ip->opmode_ioaddr)>>((p % 4) * 2); - opmode &= OP_MODE_MASK; - me->iftype[p] = opmode; - mutex_unlock(&port->mutex); - } - } - if (copy_to_user(argp, me, sizeof(*me))) - ret = -EFAULT; - kfree(me); - return ret; - } - default: - return -ENOIOCTLCMD; - } - return 0; -} - -static int mxser_cflags_changed(struct mxser_port *info, unsigned long arg, - struct async_icount *cprev) -{ - struct async_icount cnow; - unsigned long flags; - int ret; - - spin_lock_irqsave(&info->slock, flags); - cnow = info->icount; /* atomic copy */ - spin_unlock_irqrestore(&info->slock, flags); - - ret = ((arg & TIOCM_RNG) && (cnow.rng != cprev->rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev->dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev->dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev->cts)); - - *cprev = cnow; - - return ret; -} - -static int mxser_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct mxser_port *info = tty->driver_data; - struct tty_port *port = &info->port; - struct async_icount cnow; - unsigned long flags; - void __user *argp = (void __user *)arg; - int retval; - - if (tty->index == MXSER_PORTS) - return mxser_ioctl_special(cmd, argp); - - if (cmd == MOXA_SET_OP_MODE || cmd == MOXA_GET_OP_MODE) { - int p; - unsigned long opmode; - static unsigned char ModeMask[] = { 0xfc, 0xf3, 0xcf, 0x3f }; - int shiftbit; - unsigned char val, mask; - - p = tty->index % 4; - if (cmd == MOXA_SET_OP_MODE) { - if (get_user(opmode, (int __user *) argp)) - return -EFAULT; - if (opmode != RS232_MODE && - opmode != RS485_2WIRE_MODE && - opmode != RS422_MODE && - opmode != RS485_4WIRE_MODE) - return -EFAULT; - mask = ModeMask[p]; - shiftbit = p * 2; - spin_lock_irq(&info->slock); - val = inb(info->opmode_ioaddr); - val &= mask; - val |= (opmode << shiftbit); - outb(val, info->opmode_ioaddr); - spin_unlock_irq(&info->slock); - } else { - shiftbit = p * 2; - spin_lock_irq(&info->slock); - opmode = inb(info->opmode_ioaddr) >> shiftbit; - spin_unlock_irq(&info->slock); - opmode &= OP_MODE_MASK; - if (put_user(opmode, (int __user *)argp)) - return -EFAULT; - } - return 0; - } - - if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && - test_bit(TTY_IO_ERROR, &tty->flags)) - return -EIO; - - switch (cmd) { - case TIOCGSERIAL: - mutex_lock(&port->mutex); - retval = mxser_get_serial_info(tty, argp); - mutex_unlock(&port->mutex); - return retval; - case TIOCSSERIAL: - mutex_lock(&port->mutex); - retval = mxser_set_serial_info(tty, argp); - mutex_unlock(&port->mutex); - return retval; - case TIOCSERGETLSR: /* Get line status register */ - return mxser_get_lsr_info(info, argp); - /* - * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - * - mask passed in arg for lines of interest - * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) - * Caller should use TIOCGICOUNT to see which one it was - */ - case TIOCMIWAIT: - spin_lock_irqsave(&info->slock, flags); - cnow = info->icount; /* note the counters on entry */ - spin_unlock_irqrestore(&info->slock, flags); - - return wait_event_interruptible(info->port.delta_msr_wait, - mxser_cflags_changed(info, arg, &cnow)); - case MOXA_HighSpeedOn: - return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp); - case MOXA_SDS_RSTICOUNTER: - spin_lock_irq(&info->slock); - info->mon_data.rxcnt = 0; - info->mon_data.txcnt = 0; - spin_unlock_irq(&info->slock); - return 0; - - case MOXA_ASPP_OQUEUE:{ - int len, lsr; - - len = mxser_chars_in_buffer(tty); - spin_lock_irq(&info->slock); - lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_THRE; - spin_unlock_irq(&info->slock); - len += (lsr ? 0 : 1); - - return put_user(len, (int __user *)argp); - } - case MOXA_ASPP_MON: { - int mcr, status; - - spin_lock_irq(&info->slock); - status = mxser_get_msr(info->ioaddr, 1, tty->index); - mxser_check_modem_status(tty, info, status); - - mcr = inb(info->ioaddr + UART_MCR); - spin_unlock_irq(&info->slock); - - if (mcr & MOXA_MUST_MCR_XON_FLAG) - info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD; - else - info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFHOLD; - - if (mcr & MOXA_MUST_MCR_TX_XON) - info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFXENT; - else - info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; - - if (tty->hw_stopped) - info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; - else - info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; - - if (copy_to_user(argp, &info->mon_data, - sizeof(struct mxser_mon))) - return -EFAULT; - - return 0; - } - case MOXA_ASPP_LSTATUS: { - if (put_user(info->err_shadow, (unsigned char __user *)argp)) - return -EFAULT; - - info->err_shadow = 0; - return 0; - } - case MOXA_SET_BAUD_METHOD: { - int method; - - if (get_user(method, (int __user *)argp)) - return -EFAULT; - mxser_set_baud_method[tty->index] = method; - return put_user(method, (int __user *)argp); - } - default: - return -ENOIOCTLCMD; - } - return 0; -} - - /* - * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) - * Return: write counters to the user passed counter struct - * NB: both 1->0 and 0->1 transitions are counted except for - * RI where only 0->1 is counted. - */ - -static int mxser_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) - -{ - struct mxser_port *info = tty->driver_data; - struct async_icount cnow; - unsigned long flags; - - spin_lock_irqsave(&info->slock, flags); - cnow = info->icount; - spin_unlock_irqrestore(&info->slock, flags); - - icount->frame = cnow.frame; - icount->brk = cnow.brk; - icount->overrun = cnow.overrun; - icount->buf_overrun = cnow.buf_overrun; - icount->parity = cnow.parity; - icount->rx = cnow.rx; - icount->tx = cnow.tx; - icount->cts = cnow.cts; - icount->dsr = cnow.dsr; - icount->rng = cnow.rng; - icount->dcd = cnow.dcd; - return 0; -} - -static void mxser_stoprx(struct tty_struct *tty) -{ - struct mxser_port *info = tty->driver_data; - - info->ldisc_stop_rx = 1; - if (I_IXOFF(tty)) { - if (info->board->chip_flag) { - info->IER &= ~MOXA_MUST_RECV_ISR; - outb(info->IER, info->ioaddr + UART_IER); - } else { - info->x_char = STOP_CHAR(tty); - outb(0, info->ioaddr + UART_IER); - info->IER |= UART_IER_THRI; - outb(info->IER, info->ioaddr + UART_IER); - } - } - - if (tty->termios->c_cflag & CRTSCTS) { - info->MCR &= ~UART_MCR_RTS; - outb(info->MCR, info->ioaddr + UART_MCR); - } -} - -/* - * This routine is called by the upper-layer tty layer to signal that - * incoming characters should be throttled. - */ -static void mxser_throttle(struct tty_struct *tty) -{ - mxser_stoprx(tty); -} - -static void mxser_unthrottle(struct tty_struct *tty) -{ - struct mxser_port *info = tty->driver_data; - - /* startrx */ - info->ldisc_stop_rx = 0; - if (I_IXOFF(tty)) { - if (info->x_char) - info->x_char = 0; - else { - if (info->board->chip_flag) { - info->IER |= MOXA_MUST_RECV_ISR; - outb(info->IER, info->ioaddr + UART_IER); - } else { - info->x_char = START_CHAR(tty); - outb(0, info->ioaddr + UART_IER); - info->IER |= UART_IER_THRI; - outb(info->IER, info->ioaddr + UART_IER); - } - } - } - - if (tty->termios->c_cflag & CRTSCTS) { - info->MCR |= UART_MCR_RTS; - outb(info->MCR, info->ioaddr + UART_MCR); - } -} - -/* - * mxser_stop() and mxser_start() - * - * This routines are called before setting or resetting tty->stopped. - * They enable or disable transmitter interrupts, as necessary. - */ -static void mxser_stop(struct tty_struct *tty) -{ - struct mxser_port *info = tty->driver_data; - unsigned long flags; - - spin_lock_irqsave(&info->slock, flags); - if (info->IER & UART_IER_THRI) { - info->IER &= ~UART_IER_THRI; - outb(info->IER, info->ioaddr + UART_IER); - } - spin_unlock_irqrestore(&info->slock, flags); -} - -static void mxser_start(struct tty_struct *tty) -{ - struct mxser_port *info = tty->driver_data; - unsigned long flags; - - spin_lock_irqsave(&info->slock, flags); - if (info->xmit_cnt && info->port.xmit_buf) { - outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER); - info->IER |= UART_IER_THRI; - outb(info->IER, info->ioaddr + UART_IER); - } - spin_unlock_irqrestore(&info->slock, flags); -} - -static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termios) -{ - struct mxser_port *info = tty->driver_data; - unsigned long flags; - - spin_lock_irqsave(&info->slock, flags); - mxser_change_speed(tty, old_termios); - spin_unlock_irqrestore(&info->slock, flags); - - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - mxser_start(tty); - } - - /* Handle sw stopped */ - if ((old_termios->c_iflag & IXON) && - !(tty->termios->c_iflag & IXON)) { - tty->stopped = 0; - - if (info->board->chip_flag) { - spin_lock_irqsave(&info->slock, flags); - mxser_disable_must_rx_software_flow_control( - info->ioaddr); - spin_unlock_irqrestore(&info->slock, flags); - } - - mxser_start(tty); - } -} - -/* - * mxser_wait_until_sent() --- wait until the transmitter is empty - */ -static void mxser_wait_until_sent(struct tty_struct *tty, int timeout) -{ - struct mxser_port *info = tty->driver_data; - unsigned long orig_jiffies, char_time; - unsigned long flags; - int lsr; - - if (info->type == PORT_UNKNOWN) - return; - - if (info->xmit_fifo_size == 0) - return; /* Just in case.... */ - - orig_jiffies = jiffies; - /* - * Set the check interval to be 1/5 of the estimated time to - * send a single character, and make it at least 1. The check - * interval should also be less than the timeout. - * - * Note: we have to use pretty tight timings here to satisfy - * the NIST-PCTS. - */ - char_time = (info->timeout - HZ / 50) / info->xmit_fifo_size; - char_time = char_time / 5; - if (char_time == 0) - char_time = 1; - if (timeout && timeout < char_time) - char_time = timeout; - /* - * If the transmitter hasn't cleared in twice the approximate - * amount of time to send the entire FIFO, it probably won't - * ever clear. This assumes the UART isn't doing flow - * control, which is currently the case. Hence, if it ever - * takes longer than info->timeout, this is probably due to a - * UART bug of some kind. So, we clamp the timeout parameter at - * 2*info->timeout. - */ - if (!timeout || timeout > 2 * info->timeout) - timeout = 2 * info->timeout; -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk(KERN_DEBUG "In rs_wait_until_sent(%d) check=%lu...", - timeout, char_time); - printk("jiff=%lu...", jiffies); -#endif - spin_lock_irqsave(&info->slock, flags); - while (!((lsr = inb(info->ioaddr + UART_LSR)) & UART_LSR_TEMT)) { -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("lsr = %d (jiff=%lu)...", lsr, jiffies); -#endif - spin_unlock_irqrestore(&info->slock, flags); - schedule_timeout_interruptible(char_time); - spin_lock_irqsave(&info->slock, flags); - if (signal_pending(current)) - break; - if (timeout && time_after(jiffies, orig_jiffies + timeout)) - break; - } - spin_unlock_irqrestore(&info->slock, flags); - set_current_state(TASK_RUNNING); - -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); -#endif -} - -/* - * This routine is called by tty_hangup() when a hangup is signaled. - */ -static void mxser_hangup(struct tty_struct *tty) -{ - struct mxser_port *info = tty->driver_data; - - mxser_flush_buffer(tty); - tty_port_hangup(&info->port); -} - -/* - * mxser_rs_break() --- routine which turns the break handling on or off - */ -static int mxser_rs_break(struct tty_struct *tty, int break_state) -{ - struct mxser_port *info = tty->driver_data; - unsigned long flags; - - spin_lock_irqsave(&info->slock, flags); - if (break_state == -1) - outb(inb(info->ioaddr + UART_LCR) | UART_LCR_SBC, - info->ioaddr + UART_LCR); - else - outb(inb(info->ioaddr + UART_LCR) & ~UART_LCR_SBC, - info->ioaddr + UART_LCR); - spin_unlock_irqrestore(&info->slock, flags); - return 0; -} - -static void mxser_receive_chars(struct tty_struct *tty, - struct mxser_port *port, int *status) -{ - unsigned char ch, gdl; - int ignored = 0; - int cnt = 0; - int recv_room; - int max = 256; - - recv_room = tty->receive_room; - if (recv_room == 0 && !port->ldisc_stop_rx) - mxser_stoprx(tty); - if (port->board->chip_flag != MOXA_OTHER_UART) { - - if (*status & UART_LSR_SPECIAL) - goto intr_old; - if (port->board->chip_flag == MOXA_MUST_MU860_HWID && - (*status & MOXA_MUST_LSR_RERR)) - goto intr_old; - if (*status & MOXA_MUST_LSR_RERR) - goto intr_old; - - gdl = inb(port->ioaddr + MOXA_MUST_GDL_REGISTER); - - if (port->board->chip_flag == MOXA_MUST_MU150_HWID) - gdl &= MOXA_MUST_GDL_MASK; - if (gdl >= recv_room) { - if (!port->ldisc_stop_rx) - mxser_stoprx(tty); - } - while (gdl--) { - ch = inb(port->ioaddr + UART_RX); - tty_insert_flip_char(tty, ch, 0); - cnt++; - } - goto end_intr; - } -intr_old: - - do { - if (max-- < 0) - break; - - ch = inb(port->ioaddr + UART_RX); - if (port->board->chip_flag && (*status & UART_LSR_OE)) - outb(0x23, port->ioaddr + UART_FCR); - *status &= port->read_status_mask; - if (*status & port->ignore_status_mask) { - if (++ignored > 100) - break; - } else { - char flag = 0; - if (*status & UART_LSR_SPECIAL) { - if (*status & UART_LSR_BI) { - flag = TTY_BREAK; - port->icount.brk++; - - if (port->port.flags & ASYNC_SAK) - do_SAK(tty); - } else if (*status & UART_LSR_PE) { - flag = TTY_PARITY; - port->icount.parity++; - } else if (*status & UART_LSR_FE) { - flag = TTY_FRAME; - port->icount.frame++; - } else if (*status & UART_LSR_OE) { - flag = TTY_OVERRUN; - port->icount.overrun++; - } else - flag = TTY_BREAK; - } - tty_insert_flip_char(tty, ch, flag); - cnt++; - if (cnt >= recv_room) { - if (!port->ldisc_stop_rx) - mxser_stoprx(tty); - break; - } - - } - - if (port->board->chip_flag) - break; - - *status = inb(port->ioaddr + UART_LSR); - } while (*status & UART_LSR_DR); - -end_intr: - mxvar_log.rxcnt[tty->index] += cnt; - port->mon_data.rxcnt += cnt; - port->mon_data.up_rxcnt += cnt; - - /* - * We are called from an interrupt context with &port->slock - * being held. Drop it temporarily in order to prevent - * recursive locking. - */ - spin_unlock(&port->slock); - tty_flip_buffer_push(tty); - spin_lock(&port->slock); -} - -static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port) -{ - int count, cnt; - - if (port->x_char) { - outb(port->x_char, port->ioaddr + UART_TX); - port->x_char = 0; - mxvar_log.txcnt[tty->index]++; - port->mon_data.txcnt++; - port->mon_data.up_txcnt++; - port->icount.tx++; - return; - } - - if (port->port.xmit_buf == NULL) - return; - - if (port->xmit_cnt <= 0 || tty->stopped || - (tty->hw_stopped && - (port->type != PORT_16550A) && - (!port->board->chip_flag))) { - port->IER &= ~UART_IER_THRI; - outb(port->IER, port->ioaddr + UART_IER); - return; - } - - cnt = port->xmit_cnt; - count = port->xmit_fifo_size; - do { - outb(port->port.xmit_buf[port->xmit_tail++], - port->ioaddr + UART_TX); - port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE - 1); - if (--port->xmit_cnt <= 0) - break; - } while (--count > 0); - mxvar_log.txcnt[tty->index] += (cnt - port->xmit_cnt); - - port->mon_data.txcnt += (cnt - port->xmit_cnt); - port->mon_data.up_txcnt += (cnt - port->xmit_cnt); - port->icount.tx += (cnt - port->xmit_cnt); - - if (port->xmit_cnt < WAKEUP_CHARS) - tty_wakeup(tty); - - if (port->xmit_cnt <= 0) { - port->IER &= ~UART_IER_THRI; - outb(port->IER, port->ioaddr + UART_IER); - } -} - -/* - * This is the serial driver's generic interrupt routine - */ -static irqreturn_t mxser_interrupt(int irq, void *dev_id) -{ - int status, iir, i; - struct mxser_board *brd = NULL; - struct mxser_port *port; - int max, irqbits, bits, msr; - unsigned int int_cnt, pass_counter = 0; - int handled = IRQ_NONE; - struct tty_struct *tty; - - for (i = 0; i < MXSER_BOARDS; i++) - if (dev_id == &mxser_boards[i]) { - brd = dev_id; - break; - } - - if (i == MXSER_BOARDS) - goto irq_stop; - if (brd == NULL) - goto irq_stop; - max = brd->info->nports; - while (pass_counter++ < MXSER_ISR_PASS_LIMIT) { - irqbits = inb(brd->vector) & brd->vector_mask; - if (irqbits == brd->vector_mask) - break; - - handled = IRQ_HANDLED; - for (i = 0, bits = 1; i < max; i++, irqbits |= bits, bits <<= 1) { - if (irqbits == brd->vector_mask) - break; - if (bits & irqbits) - continue; - port = &brd->ports[i]; - - int_cnt = 0; - spin_lock(&port->slock); - do { - iir = inb(port->ioaddr + UART_IIR); - if (iir & UART_IIR_NO_INT) - break; - iir &= MOXA_MUST_IIR_MASK; - tty = tty_port_tty_get(&port->port); - if (!tty || - (port->port.flags & ASYNC_CLOSING) || - !(port->port.flags & - ASYNC_INITIALIZED)) { - status = inb(port->ioaddr + UART_LSR); - outb(0x27, port->ioaddr + UART_FCR); - inb(port->ioaddr + UART_MSR); - tty_kref_put(tty); - break; - } - - status = inb(port->ioaddr + UART_LSR); - - if (status & UART_LSR_PE) - port->err_shadow |= NPPI_NOTIFY_PARITY; - if (status & UART_LSR_FE) - port->err_shadow |= NPPI_NOTIFY_FRAMING; - if (status & UART_LSR_OE) - port->err_shadow |= - NPPI_NOTIFY_HW_OVERRUN; - if (status & UART_LSR_BI) - port->err_shadow |= NPPI_NOTIFY_BREAK; - - if (port->board->chip_flag) { - if (iir == MOXA_MUST_IIR_GDA || - iir == MOXA_MUST_IIR_RDA || - iir == MOXA_MUST_IIR_RTO || - iir == MOXA_MUST_IIR_LSR) - mxser_receive_chars(tty, port, - &status); - - } else { - status &= port->read_status_mask; - if (status & UART_LSR_DR) - mxser_receive_chars(tty, port, - &status); - } - msr = inb(port->ioaddr + UART_MSR); - if (msr & UART_MSR_ANY_DELTA) - mxser_check_modem_status(tty, port, msr); - - if (port->board->chip_flag) { - if (iir == 0x02 && (status & - UART_LSR_THRE)) - mxser_transmit_chars(tty, port); - } else { - if (status & UART_LSR_THRE) - mxser_transmit_chars(tty, port); - } - tty_kref_put(tty); - } while (int_cnt++ < MXSER_ISR_PASS_LIMIT); - spin_unlock(&port->slock); - } - } - -irq_stop: - return handled; -} - -static const struct tty_operations mxser_ops = { - .open = mxser_open, - .close = mxser_close, - .write = mxser_write, - .put_char = mxser_put_char, - .flush_chars = mxser_flush_chars, - .write_room = mxser_write_room, - .chars_in_buffer = mxser_chars_in_buffer, - .flush_buffer = mxser_flush_buffer, - .ioctl = mxser_ioctl, - .throttle = mxser_throttle, - .unthrottle = mxser_unthrottle, - .set_termios = mxser_set_termios, - .stop = mxser_stop, - .start = mxser_start, - .hangup = mxser_hangup, - .break_ctl = mxser_rs_break, - .wait_until_sent = mxser_wait_until_sent, - .tiocmget = mxser_tiocmget, - .tiocmset = mxser_tiocmset, - .get_icount = mxser_get_icount, -}; - -struct tty_port_operations mxser_port_ops = { - .carrier_raised = mxser_carrier_raised, - .dtr_rts = mxser_dtr_rts, - .activate = mxser_activate, - .shutdown = mxser_shutdown_port, -}; - -/* - * The MOXA Smartio/Industio serial driver boot-time initialization code! - */ - -static void mxser_release_ISA_res(struct mxser_board *brd) -{ - free_irq(brd->irq, brd); - release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); - release_region(brd->vector, 1); -} - -static int __devinit mxser_initbrd(struct mxser_board *brd, - struct pci_dev *pdev) -{ - struct mxser_port *info; - unsigned int i; - int retval; - - printk(KERN_INFO "mxser: max. baud rate = %d bps\n", - brd->ports[0].max_baud); - - for (i = 0; i < brd->info->nports; i++) { - info = &brd->ports[i]; - tty_port_init(&info->port); - info->port.ops = &mxser_port_ops; - info->board = brd; - info->stop_rx = 0; - info->ldisc_stop_rx = 0; - - /* Enhance mode enabled here */ - if (brd->chip_flag != MOXA_OTHER_UART) - mxser_enable_must_enchance_mode(info->ioaddr); - - info->port.flags = ASYNC_SHARE_IRQ; - info->type = brd->uart_type; - - process_txrx_fifo(info); - - info->custom_divisor = info->baud_base * 16; - info->port.close_delay = 5 * HZ / 10; - info->port.closing_wait = 30 * HZ; - info->normal_termios = mxvar_sdriver->init_termios; - memset(&info->mon_data, 0, sizeof(struct mxser_mon)); - info->err_shadow = 0; - spin_lock_init(&info->slock); - - /* before set INT ISR, disable all int */ - outb(inb(info->ioaddr + UART_IER) & 0xf0, - info->ioaddr + UART_IER); - } - - retval = request_irq(brd->irq, mxser_interrupt, IRQF_SHARED, "mxser", - brd); - if (retval) - printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may " - "conflict with another device.\n", - brd->info->name, brd->irq); - - return retval; -} - -static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) -{ - int id, i, bits; - unsigned short regs[16], irq; - unsigned char scratch, scratch2; - - brd->chip_flag = MOXA_OTHER_UART; - - id = mxser_read_register(cap, regs); - switch (id) { - case C168_ASIC_ID: - brd->info = &mxser_cards[0]; - break; - case C104_ASIC_ID: - brd->info = &mxser_cards[1]; - break; - case CI104J_ASIC_ID: - brd->info = &mxser_cards[2]; - break; - case C102_ASIC_ID: - brd->info = &mxser_cards[5]; - break; - case CI132_ASIC_ID: - brd->info = &mxser_cards[6]; - break; - case CI134_ASIC_ID: - brd->info = &mxser_cards[7]; - break; - default: - return 0; - } - - irq = 0; - /* some ISA cards have 2 ports, but we want to see them as 4-port (why?) - Flag-hack checks if configuration should be read as 2-port here. */ - if (brd->info->nports == 2 || (brd->info->flags & MXSER_HAS2)) { - irq = regs[9] & 0xF000; - irq = irq | (irq >> 4); - if (irq != (regs[9] & 0xFF00)) - goto err_irqconflict; - } else if (brd->info->nports == 4) { - irq = regs[9] & 0xF000; - irq = irq | (irq >> 4); - irq = irq | (irq >> 8); - if (irq != regs[9]) - goto err_irqconflict; - } else if (brd->info->nports == 8) { - irq = regs[9] & 0xF000; - irq = irq | (irq >> 4); - irq = irq | (irq >> 8); - if ((irq != regs[9]) || (irq != regs[10])) - goto err_irqconflict; - } - - if (!irq) { - printk(KERN_ERR "mxser: interrupt number unset\n"); - return -EIO; - } - brd->irq = ((int)(irq & 0xF000) >> 12); - for (i = 0; i < 8; i++) - brd->ports[i].ioaddr = (int) regs[i + 1] & 0xFFF8; - if ((regs[12] & 0x80) == 0) { - printk(KERN_ERR "mxser: invalid interrupt vector\n"); - return -EIO; - } - brd->vector = (int)regs[11]; /* interrupt vector */ - if (id == 1) - brd->vector_mask = 0x00FF; - else - brd->vector_mask = 0x000F; - for (i = 7, bits = 0x0100; i >= 0; i--, bits <<= 1) { - if (regs[12] & bits) { - brd->ports[i].baud_base = 921600; - brd->ports[i].max_baud = 921600; - } else { - brd->ports[i].baud_base = 115200; - brd->ports[i].max_baud = 115200; - } - } - scratch2 = inb(cap + UART_LCR) & (~UART_LCR_DLAB); - outb(scratch2 | UART_LCR_DLAB, cap + UART_LCR); - outb(0, cap + UART_EFR); /* EFR is the same as FCR */ - outb(scratch2, cap + UART_LCR); - outb(UART_FCR_ENABLE_FIFO, cap + UART_FCR); - scratch = inb(cap + UART_IIR); - - if (scratch & 0xC0) - brd->uart_type = PORT_16550A; - else - brd->uart_type = PORT_16450; - if (!request_region(brd->ports[0].ioaddr, 8 * brd->info->nports, - "mxser(IO)")) { - printk(KERN_ERR "mxser: can't request ports I/O region: " - "0x%.8lx-0x%.8lx\n", - brd->ports[0].ioaddr, brd->ports[0].ioaddr + - 8 * brd->info->nports - 1); - return -EIO; - } - if (!request_region(brd->vector, 1, "mxser(vector)")) { - release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); - printk(KERN_ERR "mxser: can't request interrupt vector region: " - "0x%.8lx-0x%.8lx\n", - brd->ports[0].ioaddr, brd->ports[0].ioaddr + - 8 * brd->info->nports - 1); - return -EIO; - } - return brd->info->nports; - -err_irqconflict: - printk(KERN_ERR "mxser: invalid interrupt number\n"); - return -EIO; -} - -static int __devinit mxser_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ -#ifdef CONFIG_PCI - struct mxser_board *brd; - unsigned int i, j; - unsigned long ioaddress; - int retval = -EINVAL; - - for (i = 0; i < MXSER_BOARDS; i++) - if (mxser_boards[i].info == NULL) - break; - - if (i >= MXSER_BOARDS) { - dev_err(&pdev->dev, "too many boards found (maximum %d), board " - "not configured\n", MXSER_BOARDS); - goto err; - } - - brd = &mxser_boards[i]; - brd->idx = i * MXSER_PORTS_PER_BOARD; - dev_info(&pdev->dev, "found MOXA %s board (BusNo=%d, DevNo=%d)\n", - mxser_cards[ent->driver_data].name, - pdev->bus->number, PCI_SLOT(pdev->devfn)); - - retval = pci_enable_device(pdev); - if (retval) { - dev_err(&pdev->dev, "PCI enable failed\n"); - goto err; - } - - /* io address */ - ioaddress = pci_resource_start(pdev, 2); - retval = pci_request_region(pdev, 2, "mxser(IO)"); - if (retval) - goto err_dis; - - brd->info = &mxser_cards[ent->driver_data]; - for (i = 0; i < brd->info->nports; i++) - brd->ports[i].ioaddr = ioaddress + 8 * i; - - /* vector */ - ioaddress = pci_resource_start(pdev, 3); - retval = pci_request_region(pdev, 3, "mxser(vector)"); - if (retval) - goto err_zero; - brd->vector = ioaddress; - - /* irq */ - brd->irq = pdev->irq; - - brd->chip_flag = CheckIsMoxaMust(brd->ports[0].ioaddr); - brd->uart_type = PORT_16550A; - brd->vector_mask = 0; - - for (i = 0; i < brd->info->nports; i++) { - for (j = 0; j < UART_INFO_NUM; j++) { - if (Gpci_uart_info[j].type == brd->chip_flag) { - brd->ports[i].max_baud = - Gpci_uart_info[j].max_baud; - - /* exception....CP-102 */ - if (brd->info->flags & MXSER_HIGHBAUD) - brd->ports[i].max_baud = 921600; - break; - } - } - } - - if (brd->chip_flag == MOXA_MUST_MU860_HWID) { - for (i = 0; i < brd->info->nports; i++) { - if (i < 4) - brd->ports[i].opmode_ioaddr = ioaddress + 4; - else - brd->ports[i].opmode_ioaddr = ioaddress + 0x0c; - } - outb(0, ioaddress + 4); /* default set to RS232 mode */ - outb(0, ioaddress + 0x0c); /* default set to RS232 mode */ - } - - for (i = 0; i < brd->info->nports; i++) { - brd->vector_mask |= (1 << i); - brd->ports[i].baud_base = 921600; - } - - /* mxser_initbrd will hook ISR. */ - retval = mxser_initbrd(brd, pdev); - if (retval) - goto err_rel3; - - for (i = 0; i < brd->info->nports; i++) - tty_register_device(mxvar_sdriver, brd->idx + i, &pdev->dev); - - pci_set_drvdata(pdev, brd); - - return 0; -err_rel3: - pci_release_region(pdev, 3); -err_zero: - brd->info = NULL; - pci_release_region(pdev, 2); -err_dis: - pci_disable_device(pdev); -err: - return retval; -#else - return -ENODEV; -#endif -} - -static void __devexit mxser_remove(struct pci_dev *pdev) -{ -#ifdef CONFIG_PCI - struct mxser_board *brd = pci_get_drvdata(pdev); - unsigned int i; - - for (i = 0; i < brd->info->nports; i++) - tty_unregister_device(mxvar_sdriver, brd->idx + i); - - free_irq(pdev->irq, brd); - pci_release_region(pdev, 2); - pci_release_region(pdev, 3); - pci_disable_device(pdev); - brd->info = NULL; -#endif -} - -static struct pci_driver mxser_driver = { - .name = "mxser", - .id_table = mxser_pcibrds, - .probe = mxser_probe, - .remove = __devexit_p(mxser_remove) -}; - -static int __init mxser_module_init(void) -{ - struct mxser_board *brd; - unsigned int b, i, m; - int retval; - - mxvar_sdriver = alloc_tty_driver(MXSER_PORTS + 1); - if (!mxvar_sdriver) - return -ENOMEM; - - printk(KERN_INFO "MOXA Smartio/Industio family driver version %s\n", - MXSER_VERSION); - - /* Initialize the tty_driver structure */ - mxvar_sdriver->owner = THIS_MODULE; - mxvar_sdriver->magic = TTY_DRIVER_MAGIC; - mxvar_sdriver->name = "ttyMI"; - mxvar_sdriver->major = ttymajor; - mxvar_sdriver->minor_start = 0; - mxvar_sdriver->num = MXSER_PORTS + 1; - mxvar_sdriver->type = TTY_DRIVER_TYPE_SERIAL; - mxvar_sdriver->subtype = SERIAL_TYPE_NORMAL; - mxvar_sdriver->init_termios = tty_std_termios; - mxvar_sdriver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; - mxvar_sdriver->flags = TTY_DRIVER_REAL_RAW|TTY_DRIVER_DYNAMIC_DEV; - tty_set_operations(mxvar_sdriver, &mxser_ops); - - retval = tty_register_driver(mxvar_sdriver); - if (retval) { - printk(KERN_ERR "Couldn't install MOXA Smartio/Industio family " - "tty driver !\n"); - goto err_put; - } - - /* Start finding ISA boards here */ - for (m = 0, b = 0; b < MXSER_BOARDS; b++) { - if (!ioaddr[b]) - continue; - - brd = &mxser_boards[m]; - retval = mxser_get_ISA_conf(ioaddr[b], brd); - if (retval <= 0) { - brd->info = NULL; - continue; - } - - printk(KERN_INFO "mxser: found MOXA %s board (CAP=0x%lx)\n", - brd->info->name, ioaddr[b]); - - /* mxser_initbrd will hook ISR. */ - if (mxser_initbrd(brd, NULL) < 0) { - brd->info = NULL; - continue; - } - - brd->idx = m * MXSER_PORTS_PER_BOARD; - for (i = 0; i < brd->info->nports; i++) - tty_register_device(mxvar_sdriver, brd->idx + i, NULL); - - m++; - } - - retval = pci_register_driver(&mxser_driver); - if (retval) { - printk(KERN_ERR "mxser: can't register pci driver\n"); - if (!m) { - retval = -ENODEV; - goto err_unr; - } /* else: we have some ISA cards under control */ - } - - return 0; -err_unr: - tty_unregister_driver(mxvar_sdriver); -err_put: - put_tty_driver(mxvar_sdriver); - return retval; -} - -static void __exit mxser_module_exit(void) -{ - unsigned int i, j; - - pci_unregister_driver(&mxser_driver); - - for (i = 0; i < MXSER_BOARDS; i++) /* ISA remains */ - if (mxser_boards[i].info != NULL) - for (j = 0; j < mxser_boards[i].info->nports; j++) - tty_unregister_device(mxvar_sdriver, - mxser_boards[i].idx + j); - tty_unregister_driver(mxvar_sdriver); - put_tty_driver(mxvar_sdriver); - - for (i = 0; i < MXSER_BOARDS; i++) - if (mxser_boards[i].info != NULL) - mxser_release_ISA_res(&mxser_boards[i]); -} - -module_init(mxser_module_init); -module_exit(mxser_module_exit); diff --git a/drivers/char/mxser.h b/drivers/char/mxser.h deleted file mode 100644 index 41878a69203d..000000000000 --- a/drivers/char/mxser.h +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef _MXSER_H -#define _MXSER_H - -/* - * Semi-public control interfaces - */ - -/* - * MOXA ioctls - */ - -#define MOXA 0x400 -#define MOXA_GETDATACOUNT (MOXA + 23) -#define MOXA_DIAGNOSE (MOXA + 50) -#define MOXA_CHKPORTENABLE (MOXA + 60) -#define MOXA_HighSpeedOn (MOXA + 61) -#define MOXA_GET_MAJOR (MOXA + 63) -#define MOXA_GETMSTATUS (MOXA + 65) -#define MOXA_SET_OP_MODE (MOXA + 66) -#define MOXA_GET_OP_MODE (MOXA + 67) - -#define RS232_MODE 0 -#define RS485_2WIRE_MODE 1 -#define RS422_MODE 2 -#define RS485_4WIRE_MODE 3 -#define OP_MODE_MASK 3 - -#define MOXA_SDS_RSTICOUNTER (MOXA + 69) -#define MOXA_ASPP_OQUEUE (MOXA + 70) -#define MOXA_ASPP_MON (MOXA + 73) -#define MOXA_ASPP_LSTATUS (MOXA + 74) -#define MOXA_ASPP_MON_EXT (MOXA + 75) -#define MOXA_SET_BAUD_METHOD (MOXA + 76) - -/* --------------------------------------------------- */ - -#define NPPI_NOTIFY_PARITY 0x01 -#define NPPI_NOTIFY_FRAMING 0x02 -#define NPPI_NOTIFY_HW_OVERRUN 0x04 -#define NPPI_NOTIFY_SW_OVERRUN 0x08 -#define NPPI_NOTIFY_BREAK 0x10 - -#define NPPI_NOTIFY_CTSHOLD 0x01 /* Tx hold by CTS low */ -#define NPPI_NOTIFY_DSRHOLD 0x02 /* Tx hold by DSR low */ -#define NPPI_NOTIFY_XOFFHOLD 0x08 /* Tx hold by Xoff received */ -#define NPPI_NOTIFY_XOFFXENT 0x10 /* Xoff Sent */ - -/* follow just for Moxa Must chip define. */ -/* */ -/* when LCR register (offset 0x03) write following value, */ -/* the Must chip will enter enchance mode. And write value */ -/* on EFR (offset 0x02) bit 6,7 to change bank. */ -#define MOXA_MUST_ENTER_ENCHANCE 0xBF - -/* when enhance mode enable, access on general bank register */ -#define MOXA_MUST_GDL_REGISTER 0x07 -#define MOXA_MUST_GDL_MASK 0x7F -#define MOXA_MUST_GDL_HAS_BAD_DATA 0x80 - -#define MOXA_MUST_LSR_RERR 0x80 /* error in receive FIFO */ -/* enchance register bank select and enchance mode setting register */ -/* when LCR register equal to 0xBF */ -#define MOXA_MUST_EFR_REGISTER 0x02 -/* enchance mode enable */ -#define MOXA_MUST_EFR_EFRB_ENABLE 0x10 -/* enchance reister bank set 0, 1, 2 */ -#define MOXA_MUST_EFR_BANK0 0x00 -#define MOXA_MUST_EFR_BANK1 0x40 -#define MOXA_MUST_EFR_BANK2 0x80 -#define MOXA_MUST_EFR_BANK3 0xC0 -#define MOXA_MUST_EFR_BANK_MASK 0xC0 - -/* set XON1 value register, when LCR=0xBF and change to bank0 */ -#define MOXA_MUST_XON1_REGISTER 0x04 - -/* set XON2 value register, when LCR=0xBF and change to bank0 */ -#define MOXA_MUST_XON2_REGISTER 0x05 - -/* set XOFF1 value register, when LCR=0xBF and change to bank0 */ -#define MOXA_MUST_XOFF1_REGISTER 0x06 - -/* set XOFF2 value register, when LCR=0xBF and change to bank0 */ -#define MOXA_MUST_XOFF2_REGISTER 0x07 - -#define MOXA_MUST_RBRTL_REGISTER 0x04 -#define MOXA_MUST_RBRTH_REGISTER 0x05 -#define MOXA_MUST_RBRTI_REGISTER 0x06 -#define MOXA_MUST_THRTL_REGISTER 0x07 -#define MOXA_MUST_ENUM_REGISTER 0x04 -#define MOXA_MUST_HWID_REGISTER 0x05 -#define MOXA_MUST_ECR_REGISTER 0x06 -#define MOXA_MUST_CSR_REGISTER 0x07 - -/* good data mode enable */ -#define MOXA_MUST_FCR_GDA_MODE_ENABLE 0x20 -/* only good data put into RxFIFO */ -#define MOXA_MUST_FCR_GDA_ONLY_ENABLE 0x10 - -/* enable CTS interrupt */ -#define MOXA_MUST_IER_ECTSI 0x80 -/* enable RTS interrupt */ -#define MOXA_MUST_IER_ERTSI 0x40 -/* enable Xon/Xoff interrupt */ -#define MOXA_MUST_IER_XINT 0x20 -/* enable GDA interrupt */ -#define MOXA_MUST_IER_EGDAI 0x10 - -#define MOXA_MUST_RECV_ISR (UART_IER_RDI | MOXA_MUST_IER_EGDAI) - -/* GDA interrupt pending */ -#define MOXA_MUST_IIR_GDA 0x1C -#define MOXA_MUST_IIR_RDA 0x04 -#define MOXA_MUST_IIR_RTO 0x0C -#define MOXA_MUST_IIR_LSR 0x06 - -/* recieved Xon/Xoff or specical interrupt pending */ -#define MOXA_MUST_IIR_XSC 0x10 - -/* RTS/CTS change state interrupt pending */ -#define MOXA_MUST_IIR_RTSCTS 0x20 -#define MOXA_MUST_IIR_MASK 0x3E - -#define MOXA_MUST_MCR_XON_FLAG 0x40 -#define MOXA_MUST_MCR_XON_ANY 0x80 -#define MOXA_MUST_MCR_TX_XON 0x08 - -/* software flow control on chip mask value */ -#define MOXA_MUST_EFR_SF_MASK 0x0F -/* send Xon1/Xoff1 */ -#define MOXA_MUST_EFR_SF_TX1 0x08 -/* send Xon2/Xoff2 */ -#define MOXA_MUST_EFR_SF_TX2 0x04 -/* send Xon1,Xon2/Xoff1,Xoff2 */ -#define MOXA_MUST_EFR_SF_TX12 0x0C -/* don't send Xon/Xoff */ -#define MOXA_MUST_EFR_SF_TX_NO 0x00 -/* Tx software flow control mask */ -#define MOXA_MUST_EFR_SF_TX_MASK 0x0C -/* don't receive Xon/Xoff */ -#define MOXA_MUST_EFR_SF_RX_NO 0x00 -/* receive Xon1/Xoff1 */ -#define MOXA_MUST_EFR_SF_RX1 0x02 -/* receive Xon2/Xoff2 */ -#define MOXA_MUST_EFR_SF_RX2 0x01 -/* receive Xon1,Xon2/Xoff1,Xoff2 */ -#define MOXA_MUST_EFR_SF_RX12 0x03 -/* Rx software flow control mask */ -#define MOXA_MUST_EFR_SF_RX_MASK 0x03 - -#endif diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c deleted file mode 100644 index 513ba12064ea..000000000000 --- a/drivers/char/nozomi.c +++ /dev/null @@ -1,1993 +0,0 @@ -/* - * nozomi.c -- HSDPA driver Broadband Wireless Data Card - Globe Trotter - * - * Written by: Ulf Jakobsson, - * Jan Åkerfeldt, - * Stefan Thomasson, - * - * Maintained by: Paul Hardwick (p.hardwick@option.com) - * - * Patches: - * Locking code changes for Vodafone by Sphere Systems Ltd, - * Andrew Bird (ajb@spheresystems.co.uk ) - * & Phil Sanderson - * - * Source has been ported from an implementation made by Filip Aben @ Option - * - * -------------------------------------------------------------------------- - * - * Copyright (c) 2005,2006 Option Wireless Sweden AB - * Copyright (c) 2006 Sphere Systems Ltd - * Copyright (c) 2006 Option Wireless n/v - * All rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * -------------------------------------------------------------------------- - */ - -/* Enable this to have a lot of debug printouts */ -#define DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - - -#define VERSION_STRING DRIVER_DESC " 2.1d (build date: " \ - __DATE__ " " __TIME__ ")" - -/* Macros definitions */ - -/* Default debug printout level */ -#define NOZOMI_DEBUG_LEVEL 0x00 - -#define P_BUF_SIZE 128 -#define NFO(_err_flag_, args...) \ -do { \ - char tmp[P_BUF_SIZE]; \ - snprintf(tmp, sizeof(tmp), ##args); \ - printk(_err_flag_ "[%d] %s(): %s\n", __LINE__, \ - __func__, tmp); \ -} while (0) - -#define DBG1(args...) D_(0x01, ##args) -#define DBG2(args...) D_(0x02, ##args) -#define DBG3(args...) D_(0x04, ##args) -#define DBG4(args...) D_(0x08, ##args) -#define DBG5(args...) D_(0x10, ##args) -#define DBG6(args...) D_(0x20, ##args) -#define DBG7(args...) D_(0x40, ##args) -#define DBG8(args...) D_(0x80, ##args) - -#ifdef DEBUG -/* Do we need this settable at runtime? */ -static int debug = NOZOMI_DEBUG_LEVEL; - -#define D(lvl, args...) do \ - {if (lvl & debug) NFO(KERN_DEBUG, ##args); } \ - while (0) -#define D_(lvl, args...) D(lvl, ##args) - -/* These printouts are always printed */ - -#else -static int debug; -#define D_(lvl, args...) -#endif - -/* TODO: rewrite to optimize macros... */ - -#define TMP_BUF_MAX 256 - -#define DUMP(buf__,len__) \ - do { \ - char tbuf[TMP_BUF_MAX] = {0};\ - if (len__ > 1) {\ - snprintf(tbuf, len__ > TMP_BUF_MAX ? TMP_BUF_MAX : len__, "%s", buf__);\ - if (tbuf[len__-2] == '\r') {\ - tbuf[len__-2] = 'r';\ - } \ - DBG1("SENDING: '%s' (%d+n)", tbuf, len__);\ - } else {\ - DBG1("SENDING: '%s' (%d)", tbuf, len__);\ - } \ -} while (0) - -/* Defines */ -#define NOZOMI_NAME "nozomi" -#define NOZOMI_NAME_TTY "nozomi_tty" -#define DRIVER_DESC "Nozomi driver" - -#define NTTY_TTY_MAXMINORS 256 -#define NTTY_FIFO_BUFFER_SIZE 8192 - -/* Must be power of 2 */ -#define FIFO_BUFFER_SIZE_UL 8192 - -/* Size of tmp send buffer to card */ -#define SEND_BUF_MAX 1024 -#define RECEIVE_BUF_MAX 4 - - -#define R_IIR 0x0000 /* Interrupt Identity Register */ -#define R_FCR 0x0000 /* Flow Control Register */ -#define R_IER 0x0004 /* Interrupt Enable Register */ - -#define CONFIG_MAGIC 0xEFEFFEFE -#define TOGGLE_VALID 0x0000 - -/* Definition of interrupt tokens */ -#define MDM_DL1 0x0001 -#define MDM_UL1 0x0002 -#define MDM_DL2 0x0004 -#define MDM_UL2 0x0008 -#define DIAG_DL1 0x0010 -#define DIAG_DL2 0x0020 -#define DIAG_UL 0x0040 -#define APP1_DL 0x0080 -#define APP1_UL 0x0100 -#define APP2_DL 0x0200 -#define APP2_UL 0x0400 -#define CTRL_DL 0x0800 -#define CTRL_UL 0x1000 -#define RESET 0x8000 - -#define MDM_DL (MDM_DL1 | MDM_DL2) -#define MDM_UL (MDM_UL1 | MDM_UL2) -#define DIAG_DL (DIAG_DL1 | DIAG_DL2) - -/* modem signal definition */ -#define CTRL_DSR 0x0001 -#define CTRL_DCD 0x0002 -#define CTRL_RI 0x0004 -#define CTRL_CTS 0x0008 - -#define CTRL_DTR 0x0001 -#define CTRL_RTS 0x0002 - -#define MAX_PORT 4 -#define NOZOMI_MAX_PORTS 5 -#define NOZOMI_MAX_CARDS (NTTY_TTY_MAXMINORS / MAX_PORT) - -/* Type definitions */ - -/* - * There are two types of nozomi cards, - * one with 2048 memory and with 8192 memory - */ -enum card_type { - F32_2 = 2048, /* 512 bytes downlink + uplink * 2 -> 2048 */ - F32_8 = 8192, /* 3072 bytes downl. + 1024 bytes uplink * 2 -> 8192 */ -}; - -/* Initialization states a card can be in */ -enum card_state { - NOZOMI_STATE_UKNOWN = 0, - NOZOMI_STATE_ENABLED = 1, /* pci device enabled */ - NOZOMI_STATE_ALLOCATED = 2, /* config setup done */ - NOZOMI_STATE_READY = 3, /* flowcontrols received */ -}; - -/* Two different toggle channels exist */ -enum channel_type { - CH_A = 0, - CH_B = 1, -}; - -/* Port definition for the card regarding flow control */ -enum ctrl_port_type { - CTRL_CMD = 0, - CTRL_MDM = 1, - CTRL_DIAG = 2, - CTRL_APP1 = 3, - CTRL_APP2 = 4, - CTRL_ERROR = -1, -}; - -/* Ports that the nozomi has */ -enum port_type { - PORT_MDM = 0, - PORT_DIAG = 1, - PORT_APP1 = 2, - PORT_APP2 = 3, - PORT_CTRL = 4, - PORT_ERROR = -1, -}; - -#ifdef __BIG_ENDIAN -/* Big endian */ - -struct toggles { - unsigned int enabled:5; /* - * Toggle fields are valid if enabled is 0, - * else A-channels must always be used. - */ - unsigned int diag_dl:1; - unsigned int mdm_dl:1; - unsigned int mdm_ul:1; -} __attribute__ ((packed)); - -/* Configuration table to read at startup of card */ -/* Is for now only needed during initialization phase */ -struct config_table { - u32 signature; - u16 product_information; - u16 version; - u8 pad3[3]; - struct toggles toggle; - u8 pad1[4]; - u16 dl_mdm_len1; /* - * If this is 64, it can hold - * 60 bytes + 4 that is length field - */ - u16 dl_start; - - u16 dl_diag_len1; - u16 dl_mdm_len2; /* - * If this is 64, it can hold - * 60 bytes + 4 that is length field - */ - u16 dl_app1_len; - - u16 dl_diag_len2; - u16 dl_ctrl_len; - u16 dl_app2_len; - u8 pad2[16]; - u16 ul_mdm_len1; - u16 ul_start; - u16 ul_diag_len; - u16 ul_mdm_len2; - u16 ul_app1_len; - u16 ul_app2_len; - u16 ul_ctrl_len; -} __attribute__ ((packed)); - -/* This stores all control downlink flags */ -struct ctrl_dl { - u8 port; - unsigned int reserved:4; - unsigned int CTS:1; - unsigned int RI:1; - unsigned int DCD:1; - unsigned int DSR:1; -} __attribute__ ((packed)); - -/* This stores all control uplink flags */ -struct ctrl_ul { - u8 port; - unsigned int reserved:6; - unsigned int RTS:1; - unsigned int DTR:1; -} __attribute__ ((packed)); - -#else -/* Little endian */ - -/* This represents the toggle information */ -struct toggles { - unsigned int mdm_ul:1; - unsigned int mdm_dl:1; - unsigned int diag_dl:1; - unsigned int enabled:5; /* - * Toggle fields are valid if enabled is 0, - * else A-channels must always be used. - */ -} __attribute__ ((packed)); - -/* Configuration table to read at startup of card */ -struct config_table { - u32 signature; - u16 version; - u16 product_information; - struct toggles toggle; - u8 pad1[7]; - u16 dl_start; - u16 dl_mdm_len1; /* - * If this is 64, it can hold - * 60 bytes + 4 that is length field - */ - u16 dl_mdm_len2; - u16 dl_diag_len1; - u16 dl_diag_len2; - u16 dl_app1_len; - u16 dl_app2_len; - u16 dl_ctrl_len; - u8 pad2[16]; - u16 ul_start; - u16 ul_mdm_len2; - u16 ul_mdm_len1; - u16 ul_diag_len; - u16 ul_app1_len; - u16 ul_app2_len; - u16 ul_ctrl_len; -} __attribute__ ((packed)); - -/* This stores all control downlink flags */ -struct ctrl_dl { - unsigned int DSR:1; - unsigned int DCD:1; - unsigned int RI:1; - unsigned int CTS:1; - unsigned int reserverd:4; - u8 port; -} __attribute__ ((packed)); - -/* This stores all control uplink flags */ -struct ctrl_ul { - unsigned int DTR:1; - unsigned int RTS:1; - unsigned int reserved:6; - u8 port; -} __attribute__ ((packed)); -#endif - -/* This holds all information that is needed regarding a port */ -struct port { - struct tty_port port; - u8 update_flow_control; - struct ctrl_ul ctrl_ul; - struct ctrl_dl ctrl_dl; - struct kfifo fifo_ul; - void __iomem *dl_addr[2]; - u32 dl_size[2]; - u8 toggle_dl; - void __iomem *ul_addr[2]; - u32 ul_size[2]; - u8 toggle_ul; - u16 token_dl; - - /* mutex to ensure one access patch to this port */ - struct mutex tty_sem; - wait_queue_head_t tty_wait; - struct async_icount tty_icount; - - struct nozomi *dc; -}; - -/* Private data one for each card in the system */ -struct nozomi { - void __iomem *base_addr; - unsigned long flip; - - /* Pointers to registers */ - void __iomem *reg_iir; - void __iomem *reg_fcr; - void __iomem *reg_ier; - - u16 last_ier; - enum card_type card_type; - struct config_table config_table; /* Configuration table */ - struct pci_dev *pdev; - struct port port[NOZOMI_MAX_PORTS]; - u8 *send_buf; - - spinlock_t spin_mutex; /* secures access to registers and tty */ - - unsigned int index_start; - enum card_state state; - u32 open_ttys; -}; - -/* This is a data packet that is read or written to/from card */ -struct buffer { - u32 size; /* size is the length of the data buffer */ - u8 *data; -} __attribute__ ((packed)); - -/* Global variables */ -static const struct pci_device_id nozomi_pci_tbl[] __devinitconst = { - {PCI_DEVICE(0x1931, 0x000c)}, /* Nozomi HSDPA */ - {}, -}; - -MODULE_DEVICE_TABLE(pci, nozomi_pci_tbl); - -static struct nozomi *ndevs[NOZOMI_MAX_CARDS]; -static struct tty_driver *ntty_driver; - -static const struct tty_port_operations noz_tty_port_ops; - -/* - * find card by tty_index - */ -static inline struct nozomi *get_dc_by_tty(const struct tty_struct *tty) -{ - return tty ? ndevs[tty->index / MAX_PORT] : NULL; -} - -static inline struct port *get_port_by_tty(const struct tty_struct *tty) -{ - struct nozomi *ndev = get_dc_by_tty(tty); - return ndev ? &ndev->port[tty->index % MAX_PORT] : NULL; -} - -/* - * TODO: - * -Optimize - * -Rewrite cleaner - */ - -static void read_mem32(u32 *buf, const void __iomem *mem_addr_start, - u32 size_bytes) -{ - u32 i = 0; - const u32 __iomem *ptr = mem_addr_start; - u16 *buf16; - - if (unlikely(!ptr || !buf)) - goto out; - - /* shortcut for extremely often used cases */ - switch (size_bytes) { - case 2: /* 2 bytes */ - buf16 = (u16 *) buf; - *buf16 = __le16_to_cpu(readw(ptr)); - goto out; - break; - case 4: /* 4 bytes */ - *(buf) = __le32_to_cpu(readl(ptr)); - goto out; - break; - } - - while (i < size_bytes) { - if (size_bytes - i == 2) { - /* Handle 2 bytes in the end */ - buf16 = (u16 *) buf; - *(buf16) = __le16_to_cpu(readw(ptr)); - i += 2; - } else { - /* Read 4 bytes */ - *(buf) = __le32_to_cpu(readl(ptr)); - i += 4; - } - buf++; - ptr++; - } -out: - return; -} - -/* - * TODO: - * -Optimize - * -Rewrite cleaner - */ -static u32 write_mem32(void __iomem *mem_addr_start, const u32 *buf, - u32 size_bytes) -{ - u32 i = 0; - u32 __iomem *ptr = mem_addr_start; - const u16 *buf16; - - if (unlikely(!ptr || !buf)) - return 0; - - /* shortcut for extremely often used cases */ - switch (size_bytes) { - case 2: /* 2 bytes */ - buf16 = (const u16 *)buf; - writew(__cpu_to_le16(*buf16), ptr); - return 2; - break; - case 1: /* - * also needs to write 4 bytes in this case - * so falling through.. - */ - case 4: /* 4 bytes */ - writel(__cpu_to_le32(*buf), ptr); - return 4; - break; - } - - while (i < size_bytes) { - if (size_bytes - i == 2) { - /* 2 bytes */ - buf16 = (const u16 *)buf; - writew(__cpu_to_le16(*buf16), ptr); - i += 2; - } else { - /* 4 bytes */ - writel(__cpu_to_le32(*buf), ptr); - i += 4; - } - buf++; - ptr++; - } - return i; -} - -/* Setup pointers to different channels and also setup buffer sizes. */ -static void setup_memory(struct nozomi *dc) -{ - void __iomem *offset = dc->base_addr + dc->config_table.dl_start; - /* The length reported is including the length field of 4 bytes, - * hence subtract with 4. - */ - const u16 buff_offset = 4; - - /* Modem port dl configuration */ - dc->port[PORT_MDM].dl_addr[CH_A] = offset; - dc->port[PORT_MDM].dl_addr[CH_B] = - (offset += dc->config_table.dl_mdm_len1); - dc->port[PORT_MDM].dl_size[CH_A] = - dc->config_table.dl_mdm_len1 - buff_offset; - dc->port[PORT_MDM].dl_size[CH_B] = - dc->config_table.dl_mdm_len2 - buff_offset; - - /* Diag port dl configuration */ - dc->port[PORT_DIAG].dl_addr[CH_A] = - (offset += dc->config_table.dl_mdm_len2); - dc->port[PORT_DIAG].dl_size[CH_A] = - dc->config_table.dl_diag_len1 - buff_offset; - dc->port[PORT_DIAG].dl_addr[CH_B] = - (offset += dc->config_table.dl_diag_len1); - dc->port[PORT_DIAG].dl_size[CH_B] = - dc->config_table.dl_diag_len2 - buff_offset; - - /* App1 port dl configuration */ - dc->port[PORT_APP1].dl_addr[CH_A] = - (offset += dc->config_table.dl_diag_len2); - dc->port[PORT_APP1].dl_size[CH_A] = - dc->config_table.dl_app1_len - buff_offset; - - /* App2 port dl configuration */ - dc->port[PORT_APP2].dl_addr[CH_A] = - (offset += dc->config_table.dl_app1_len); - dc->port[PORT_APP2].dl_size[CH_A] = - dc->config_table.dl_app2_len - buff_offset; - - /* Ctrl dl configuration */ - dc->port[PORT_CTRL].dl_addr[CH_A] = - (offset += dc->config_table.dl_app2_len); - dc->port[PORT_CTRL].dl_size[CH_A] = - dc->config_table.dl_ctrl_len - buff_offset; - - offset = dc->base_addr + dc->config_table.ul_start; - - /* Modem Port ul configuration */ - dc->port[PORT_MDM].ul_addr[CH_A] = offset; - dc->port[PORT_MDM].ul_size[CH_A] = - dc->config_table.ul_mdm_len1 - buff_offset; - dc->port[PORT_MDM].ul_addr[CH_B] = - (offset += dc->config_table.ul_mdm_len1); - dc->port[PORT_MDM].ul_size[CH_B] = - dc->config_table.ul_mdm_len2 - buff_offset; - - /* Diag port ul configuration */ - dc->port[PORT_DIAG].ul_addr[CH_A] = - (offset += dc->config_table.ul_mdm_len2); - dc->port[PORT_DIAG].ul_size[CH_A] = - dc->config_table.ul_diag_len - buff_offset; - - /* App1 port ul configuration */ - dc->port[PORT_APP1].ul_addr[CH_A] = - (offset += dc->config_table.ul_diag_len); - dc->port[PORT_APP1].ul_size[CH_A] = - dc->config_table.ul_app1_len - buff_offset; - - /* App2 port ul configuration */ - dc->port[PORT_APP2].ul_addr[CH_A] = - (offset += dc->config_table.ul_app1_len); - dc->port[PORT_APP2].ul_size[CH_A] = - dc->config_table.ul_app2_len - buff_offset; - - /* Ctrl ul configuration */ - dc->port[PORT_CTRL].ul_addr[CH_A] = - (offset += dc->config_table.ul_app2_len); - dc->port[PORT_CTRL].ul_size[CH_A] = - dc->config_table.ul_ctrl_len - buff_offset; -} - -/* Dump config table under initalization phase */ -#ifdef DEBUG -static void dump_table(const struct nozomi *dc) -{ - DBG3("signature: 0x%08X", dc->config_table.signature); - DBG3("version: 0x%04X", dc->config_table.version); - DBG3("product_information: 0x%04X", \ - dc->config_table.product_information); - DBG3("toggle enabled: %d", dc->config_table.toggle.enabled); - DBG3("toggle up_mdm: %d", dc->config_table.toggle.mdm_ul); - DBG3("toggle dl_mdm: %d", dc->config_table.toggle.mdm_dl); - DBG3("toggle dl_dbg: %d", dc->config_table.toggle.diag_dl); - - DBG3("dl_start: 0x%04X", dc->config_table.dl_start); - DBG3("dl_mdm_len0: 0x%04X, %d", dc->config_table.dl_mdm_len1, - dc->config_table.dl_mdm_len1); - DBG3("dl_mdm_len1: 0x%04X, %d", dc->config_table.dl_mdm_len2, - dc->config_table.dl_mdm_len2); - DBG3("dl_diag_len0: 0x%04X, %d", dc->config_table.dl_diag_len1, - dc->config_table.dl_diag_len1); - DBG3("dl_diag_len1: 0x%04X, %d", dc->config_table.dl_diag_len2, - dc->config_table.dl_diag_len2); - DBG3("dl_app1_len: 0x%04X, %d", dc->config_table.dl_app1_len, - dc->config_table.dl_app1_len); - DBG3("dl_app2_len: 0x%04X, %d", dc->config_table.dl_app2_len, - dc->config_table.dl_app2_len); - DBG3("dl_ctrl_len: 0x%04X, %d", dc->config_table.dl_ctrl_len, - dc->config_table.dl_ctrl_len); - DBG3("ul_start: 0x%04X, %d", dc->config_table.ul_start, - dc->config_table.ul_start); - DBG3("ul_mdm_len[0]: 0x%04X, %d", dc->config_table.ul_mdm_len1, - dc->config_table.ul_mdm_len1); - DBG3("ul_mdm_len[1]: 0x%04X, %d", dc->config_table.ul_mdm_len2, - dc->config_table.ul_mdm_len2); - DBG3("ul_diag_len: 0x%04X, %d", dc->config_table.ul_diag_len, - dc->config_table.ul_diag_len); - DBG3("ul_app1_len: 0x%04X, %d", dc->config_table.ul_app1_len, - dc->config_table.ul_app1_len); - DBG3("ul_app2_len: 0x%04X, %d", dc->config_table.ul_app2_len, - dc->config_table.ul_app2_len); - DBG3("ul_ctrl_len: 0x%04X, %d", dc->config_table.ul_ctrl_len, - dc->config_table.ul_ctrl_len); -} -#else -static inline void dump_table(const struct nozomi *dc) { } -#endif - -/* - * Read configuration table from card under intalization phase - * Returns 1 if ok, else 0 - */ -static int nozomi_read_config_table(struct nozomi *dc) -{ - read_mem32((u32 *) &dc->config_table, dc->base_addr + 0, - sizeof(struct config_table)); - - if (dc->config_table.signature != CONFIG_MAGIC) { - dev_err(&dc->pdev->dev, "ConfigTable Bad! 0x%08X != 0x%08X\n", - dc->config_table.signature, CONFIG_MAGIC); - return 0; - } - - if ((dc->config_table.version == 0) - || (dc->config_table.toggle.enabled == TOGGLE_VALID)) { - int i; - DBG1("Second phase, configuring card"); - - setup_memory(dc); - - dc->port[PORT_MDM].toggle_ul = dc->config_table.toggle.mdm_ul; - dc->port[PORT_MDM].toggle_dl = dc->config_table.toggle.mdm_dl; - dc->port[PORT_DIAG].toggle_dl = dc->config_table.toggle.diag_dl; - DBG1("toggle ports: MDM UL:%d MDM DL:%d, DIAG DL:%d", - dc->port[PORT_MDM].toggle_ul, - dc->port[PORT_MDM].toggle_dl, dc->port[PORT_DIAG].toggle_dl); - - dump_table(dc); - - for (i = PORT_MDM; i < MAX_PORT; i++) { - memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl)); - memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul)); - } - - /* Enable control channel */ - dc->last_ier = dc->last_ier | CTRL_DL; - writew(dc->last_ier, dc->reg_ier); - - dc->state = NOZOMI_STATE_ALLOCATED; - dev_info(&dc->pdev->dev, "Initialization OK!\n"); - return 1; - } - - if ((dc->config_table.version > 0) - && (dc->config_table.toggle.enabled != TOGGLE_VALID)) { - u32 offset = 0; - DBG1("First phase: pushing upload buffers, clearing download"); - - dev_info(&dc->pdev->dev, "Version of card: %d\n", - dc->config_table.version); - - /* Here we should disable all I/O over F32. */ - setup_memory(dc); - - /* - * We should send ALL channel pair tokens back along - * with reset token - */ - - /* push upload modem buffers */ - write_mem32(dc->port[PORT_MDM].ul_addr[CH_A], - (u32 *) &offset, 4); - write_mem32(dc->port[PORT_MDM].ul_addr[CH_B], - (u32 *) &offset, 4); - - writew(MDM_UL | DIAG_DL | MDM_DL, dc->reg_fcr); - - DBG1("First phase done"); - } - - return 1; -} - -/* Enable uplink interrupts */ -static void enable_transmit_ul(enum port_type port, struct nozomi *dc) -{ - static const u16 mask[] = {MDM_UL, DIAG_UL, APP1_UL, APP2_UL, CTRL_UL}; - - if (port < NOZOMI_MAX_PORTS) { - dc->last_ier |= mask[port]; - writew(dc->last_ier, dc->reg_ier); - } else { - dev_err(&dc->pdev->dev, "Called with wrong port?\n"); - } -} - -/* Disable uplink interrupts */ -static void disable_transmit_ul(enum port_type port, struct nozomi *dc) -{ - static const u16 mask[] = - {~MDM_UL, ~DIAG_UL, ~APP1_UL, ~APP2_UL, ~CTRL_UL}; - - if (port < NOZOMI_MAX_PORTS) { - dc->last_ier &= mask[port]; - writew(dc->last_ier, dc->reg_ier); - } else { - dev_err(&dc->pdev->dev, "Called with wrong port?\n"); - } -} - -/* Enable downlink interrupts */ -static void enable_transmit_dl(enum port_type port, struct nozomi *dc) -{ - static const u16 mask[] = {MDM_DL, DIAG_DL, APP1_DL, APP2_DL, CTRL_DL}; - - if (port < NOZOMI_MAX_PORTS) { - dc->last_ier |= mask[port]; - writew(dc->last_ier, dc->reg_ier); - } else { - dev_err(&dc->pdev->dev, "Called with wrong port?\n"); - } -} - -/* Disable downlink interrupts */ -static void disable_transmit_dl(enum port_type port, struct nozomi *dc) -{ - static const u16 mask[] = - {~MDM_DL, ~DIAG_DL, ~APP1_DL, ~APP2_DL, ~CTRL_DL}; - - if (port < NOZOMI_MAX_PORTS) { - dc->last_ier &= mask[port]; - writew(dc->last_ier, dc->reg_ier); - } else { - dev_err(&dc->pdev->dev, "Called with wrong port?\n"); - } -} - -/* - * Return 1 - send buffer to card and ack. - * Return 0 - don't ack, don't send buffer to card. - */ -static int send_data(enum port_type index, struct nozomi *dc) -{ - u32 size = 0; - struct port *port = &dc->port[index]; - const u8 toggle = port->toggle_ul; - void __iomem *addr = port->ul_addr[toggle]; - const u32 ul_size = port->ul_size[toggle]; - struct tty_struct *tty = tty_port_tty_get(&port->port); - - /* Get data from tty and place in buf for now */ - size = kfifo_out(&port->fifo_ul, dc->send_buf, - ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX); - - if (size == 0) { - DBG4("No more data to send, disable link:"); - tty_kref_put(tty); - return 0; - } - - /* DUMP(buf, size); */ - - /* Write length + data */ - write_mem32(addr, (u32 *) &size, 4); - write_mem32(addr + 4, (u32 *) dc->send_buf, size); - - if (tty) - tty_wakeup(tty); - - tty_kref_put(tty); - return 1; -} - -/* If all data has been read, return 1, else 0 */ -static int receive_data(enum port_type index, struct nozomi *dc) -{ - u8 buf[RECEIVE_BUF_MAX] = { 0 }; - int size; - u32 offset = 4; - struct port *port = &dc->port[index]; - void __iomem *addr = port->dl_addr[port->toggle_dl]; - struct tty_struct *tty = tty_port_tty_get(&port->port); - int i, ret; - - if (unlikely(!tty)) { - DBG1("tty not open for port: %d?", index); - return 1; - } - - read_mem32((u32 *) &size, addr, 4); - /* DBG1( "%d bytes port: %d", size, index); */ - - if (test_bit(TTY_THROTTLED, &tty->flags)) { - DBG1("No room in tty, don't read data, don't ack interrupt, " - "disable interrupt"); - - /* disable interrupt in downlink... */ - disable_transmit_dl(index, dc); - ret = 0; - goto put; - } - - if (unlikely(size == 0)) { - dev_err(&dc->pdev->dev, "size == 0?\n"); - ret = 1; - goto put; - } - - while (size > 0) { - read_mem32((u32 *) buf, addr + offset, RECEIVE_BUF_MAX); - - if (size == 1) { - tty_insert_flip_char(tty, buf[0], TTY_NORMAL); - size = 0; - } else if (size < RECEIVE_BUF_MAX) { - size -= tty_insert_flip_string(tty, (char *) buf, size); - } else { - i = tty_insert_flip_string(tty, \ - (char *) buf, RECEIVE_BUF_MAX); - size -= i; - offset += i; - } - } - - set_bit(index, &dc->flip); - ret = 1; -put: - tty_kref_put(tty); - return ret; -} - -/* Debug for interrupts */ -#ifdef DEBUG -static char *interrupt2str(u16 interrupt) -{ - static char buf[TMP_BUF_MAX]; - char *p = buf; - - interrupt & MDM_DL1 ? p += snprintf(p, TMP_BUF_MAX, "MDM_DL1 ") : NULL; - interrupt & MDM_DL2 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), - "MDM_DL2 ") : NULL; - - interrupt & MDM_UL1 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), - "MDM_UL1 ") : NULL; - interrupt & MDM_UL2 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), - "MDM_UL2 ") : NULL; - - interrupt & DIAG_DL1 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), - "DIAG_DL1 ") : NULL; - interrupt & DIAG_DL2 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), - "DIAG_DL2 ") : NULL; - - interrupt & DIAG_UL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), - "DIAG_UL ") : NULL; - - interrupt & APP1_DL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), - "APP1_DL ") : NULL; - interrupt & APP2_DL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), - "APP2_DL ") : NULL; - - interrupt & APP1_UL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), - "APP1_UL ") : NULL; - interrupt & APP2_UL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), - "APP2_UL ") : NULL; - - interrupt & CTRL_DL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), - "CTRL_DL ") : NULL; - interrupt & CTRL_UL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), - "CTRL_UL ") : NULL; - - interrupt & RESET ? p += snprintf(p, TMP_BUF_MAX - (p - buf), - "RESET ") : NULL; - - return buf; -} -#endif - -/* - * Receive flow control - * Return 1 - If ok, else 0 - */ -static int receive_flow_control(struct nozomi *dc) -{ - enum port_type port = PORT_MDM; - struct ctrl_dl ctrl_dl; - struct ctrl_dl old_ctrl; - u16 enable_ier = 0; - - read_mem32((u32 *) &ctrl_dl, dc->port[PORT_CTRL].dl_addr[CH_A], 2); - - switch (ctrl_dl.port) { - case CTRL_CMD: - DBG1("The Base Band sends this value as a response to a " - "request for IMSI detach sent over the control " - "channel uplink (see section 7.6.1)."); - break; - case CTRL_MDM: - port = PORT_MDM; - enable_ier = MDM_DL; - break; - case CTRL_DIAG: - port = PORT_DIAG; - enable_ier = DIAG_DL; - break; - case CTRL_APP1: - port = PORT_APP1; - enable_ier = APP1_DL; - break; - case CTRL_APP2: - port = PORT_APP2; - enable_ier = APP2_DL; - if (dc->state == NOZOMI_STATE_ALLOCATED) { - /* - * After card initialization the flow control - * received for APP2 is always the last - */ - dc->state = NOZOMI_STATE_READY; - dev_info(&dc->pdev->dev, "Device READY!\n"); - } - break; - default: - dev_err(&dc->pdev->dev, - "ERROR: flow control received for non-existing port\n"); - return 0; - }; - - DBG1("0x%04X->0x%04X", *((u16 *)&dc->port[port].ctrl_dl), - *((u16 *)&ctrl_dl)); - - old_ctrl = dc->port[port].ctrl_dl; - dc->port[port].ctrl_dl = ctrl_dl; - - if (old_ctrl.CTS == 1 && ctrl_dl.CTS == 0) { - DBG1("Disable interrupt (0x%04X) on port: %d", - enable_ier, port); - disable_transmit_ul(port, dc); - - } else if (old_ctrl.CTS == 0 && ctrl_dl.CTS == 1) { - - if (kfifo_len(&dc->port[port].fifo_ul)) { - DBG1("Enable interrupt (0x%04X) on port: %d", - enable_ier, port); - DBG1("Data in buffer [%d], enable transmit! ", - kfifo_len(&dc->port[port].fifo_ul)); - enable_transmit_ul(port, dc); - } else { - DBG1("No data in buffer..."); - } - } - - if (*(u16 *)&old_ctrl == *(u16 *)&ctrl_dl) { - DBG1(" No change in mctrl"); - return 1; - } - /* Update statistics */ - if (old_ctrl.CTS != ctrl_dl.CTS) - dc->port[port].tty_icount.cts++; - if (old_ctrl.DSR != ctrl_dl.DSR) - dc->port[port].tty_icount.dsr++; - if (old_ctrl.RI != ctrl_dl.RI) - dc->port[port].tty_icount.rng++; - if (old_ctrl.DCD != ctrl_dl.DCD) - dc->port[port].tty_icount.dcd++; - - wake_up_interruptible(&dc->port[port].tty_wait); - - DBG1("port: %d DCD(%d), CTS(%d), RI(%d), DSR(%d)", - port, - dc->port[port].tty_icount.dcd, dc->port[port].tty_icount.cts, - dc->port[port].tty_icount.rng, dc->port[port].tty_icount.dsr); - - return 1; -} - -static enum ctrl_port_type port2ctrl(enum port_type port, - const struct nozomi *dc) -{ - switch (port) { - case PORT_MDM: - return CTRL_MDM; - case PORT_DIAG: - return CTRL_DIAG; - case PORT_APP1: - return CTRL_APP1; - case PORT_APP2: - return CTRL_APP2; - default: - dev_err(&dc->pdev->dev, - "ERROR: send flow control " \ - "received for non-existing port\n"); - }; - return CTRL_ERROR; -} - -/* - * Send flow control, can only update one channel at a time - * Return 0 - If we have updated all flow control - * Return 1 - If we need to update more flow control, ack current enable more - */ -static int send_flow_control(struct nozomi *dc) -{ - u32 i, more_flow_control_to_be_updated = 0; - u16 *ctrl; - - for (i = PORT_MDM; i < MAX_PORT; i++) { - if (dc->port[i].update_flow_control) { - if (more_flow_control_to_be_updated) { - /* We have more flow control to be updated */ - return 1; - } - dc->port[i].ctrl_ul.port = port2ctrl(i, dc); - ctrl = (u16 *)&dc->port[i].ctrl_ul; - write_mem32(dc->port[PORT_CTRL].ul_addr[0], \ - (u32 *) ctrl, 2); - dc->port[i].update_flow_control = 0; - more_flow_control_to_be_updated = 1; - } - } - return 0; -} - -/* - * Handle downlink data, ports that are handled are modem and diagnostics - * Return 1 - ok - * Return 0 - toggle fields are out of sync - */ -static int handle_data_dl(struct nozomi *dc, enum port_type port, u8 *toggle, - u16 read_iir, u16 mask1, u16 mask2) -{ - if (*toggle == 0 && read_iir & mask1) { - if (receive_data(port, dc)) { - writew(mask1, dc->reg_fcr); - *toggle = !(*toggle); - } - - if (read_iir & mask2) { - if (receive_data(port, dc)) { - writew(mask2, dc->reg_fcr); - *toggle = !(*toggle); - } - } - } else if (*toggle == 1 && read_iir & mask2) { - if (receive_data(port, dc)) { - writew(mask2, dc->reg_fcr); - *toggle = !(*toggle); - } - - if (read_iir & mask1) { - if (receive_data(port, dc)) { - writew(mask1, dc->reg_fcr); - *toggle = !(*toggle); - } - } - } else { - dev_err(&dc->pdev->dev, "port out of sync!, toggle:%d\n", - *toggle); - return 0; - } - return 1; -} - -/* - * Handle uplink data, this is currently for the modem port - * Return 1 - ok - * Return 0 - toggle field are out of sync - */ -static int handle_data_ul(struct nozomi *dc, enum port_type port, u16 read_iir) -{ - u8 *toggle = &(dc->port[port].toggle_ul); - - if (*toggle == 0 && read_iir & MDM_UL1) { - dc->last_ier &= ~MDM_UL; - writew(dc->last_ier, dc->reg_ier); - if (send_data(port, dc)) { - writew(MDM_UL1, dc->reg_fcr); - dc->last_ier = dc->last_ier | MDM_UL; - writew(dc->last_ier, dc->reg_ier); - *toggle = !*toggle; - } - - if (read_iir & MDM_UL2) { - dc->last_ier &= ~MDM_UL; - writew(dc->last_ier, dc->reg_ier); - if (send_data(port, dc)) { - writew(MDM_UL2, dc->reg_fcr); - dc->last_ier = dc->last_ier | MDM_UL; - writew(dc->last_ier, dc->reg_ier); - *toggle = !*toggle; - } - } - - } else if (*toggle == 1 && read_iir & MDM_UL2) { - dc->last_ier &= ~MDM_UL; - writew(dc->last_ier, dc->reg_ier); - if (send_data(port, dc)) { - writew(MDM_UL2, dc->reg_fcr); - dc->last_ier = dc->last_ier | MDM_UL; - writew(dc->last_ier, dc->reg_ier); - *toggle = !*toggle; - } - - if (read_iir & MDM_UL1) { - dc->last_ier &= ~MDM_UL; - writew(dc->last_ier, dc->reg_ier); - if (send_data(port, dc)) { - writew(MDM_UL1, dc->reg_fcr); - dc->last_ier = dc->last_ier | MDM_UL; - writew(dc->last_ier, dc->reg_ier); - *toggle = !*toggle; - } - } - } else { - writew(read_iir & MDM_UL, dc->reg_fcr); - dev_err(&dc->pdev->dev, "port out of sync!\n"); - return 0; - } - return 1; -} - -static irqreturn_t interrupt_handler(int irq, void *dev_id) -{ - struct nozomi *dc = dev_id; - unsigned int a; - u16 read_iir; - - if (!dc) - return IRQ_NONE; - - spin_lock(&dc->spin_mutex); - read_iir = readw(dc->reg_iir); - - /* Card removed */ - if (read_iir == (u16)-1) - goto none; - /* - * Just handle interrupt enabled in IER - * (by masking with dc->last_ier) - */ - read_iir &= dc->last_ier; - - if (read_iir == 0) - goto none; - - - DBG4("%s irq:0x%04X, prev:0x%04X", interrupt2str(read_iir), read_iir, - dc->last_ier); - - if (read_iir & RESET) { - if (unlikely(!nozomi_read_config_table(dc))) { - dc->last_ier = 0x0; - writew(dc->last_ier, dc->reg_ier); - dev_err(&dc->pdev->dev, "Could not read status from " - "card, we should disable interface\n"); - } else { - writew(RESET, dc->reg_fcr); - } - /* No more useful info if this was the reset interrupt. */ - goto exit_handler; - } - if (read_iir & CTRL_UL) { - DBG1("CTRL_UL"); - dc->last_ier &= ~CTRL_UL; - writew(dc->last_ier, dc->reg_ier); - if (send_flow_control(dc)) { - writew(CTRL_UL, dc->reg_fcr); - dc->last_ier = dc->last_ier | CTRL_UL; - writew(dc->last_ier, dc->reg_ier); - } - } - if (read_iir & CTRL_DL) { - receive_flow_control(dc); - writew(CTRL_DL, dc->reg_fcr); - } - if (read_iir & MDM_DL) { - if (!handle_data_dl(dc, PORT_MDM, - &(dc->port[PORT_MDM].toggle_dl), read_iir, - MDM_DL1, MDM_DL2)) { - dev_err(&dc->pdev->dev, "MDM_DL out of sync!\n"); - goto exit_handler; - } - } - if (read_iir & MDM_UL) { - if (!handle_data_ul(dc, PORT_MDM, read_iir)) { - dev_err(&dc->pdev->dev, "MDM_UL out of sync!\n"); - goto exit_handler; - } - } - if (read_iir & DIAG_DL) { - if (!handle_data_dl(dc, PORT_DIAG, - &(dc->port[PORT_DIAG].toggle_dl), read_iir, - DIAG_DL1, DIAG_DL2)) { - dev_err(&dc->pdev->dev, "DIAG_DL out of sync!\n"); - goto exit_handler; - } - } - if (read_iir & DIAG_UL) { - dc->last_ier &= ~DIAG_UL; - writew(dc->last_ier, dc->reg_ier); - if (send_data(PORT_DIAG, dc)) { - writew(DIAG_UL, dc->reg_fcr); - dc->last_ier = dc->last_ier | DIAG_UL; - writew(dc->last_ier, dc->reg_ier); - } - } - if (read_iir & APP1_DL) { - if (receive_data(PORT_APP1, dc)) - writew(APP1_DL, dc->reg_fcr); - } - if (read_iir & APP1_UL) { - dc->last_ier &= ~APP1_UL; - writew(dc->last_ier, dc->reg_ier); - if (send_data(PORT_APP1, dc)) { - writew(APP1_UL, dc->reg_fcr); - dc->last_ier = dc->last_ier | APP1_UL; - writew(dc->last_ier, dc->reg_ier); - } - } - if (read_iir & APP2_DL) { - if (receive_data(PORT_APP2, dc)) - writew(APP2_DL, dc->reg_fcr); - } - if (read_iir & APP2_UL) { - dc->last_ier &= ~APP2_UL; - writew(dc->last_ier, dc->reg_ier); - if (send_data(PORT_APP2, dc)) { - writew(APP2_UL, dc->reg_fcr); - dc->last_ier = dc->last_ier | APP2_UL; - writew(dc->last_ier, dc->reg_ier); - } - } - -exit_handler: - spin_unlock(&dc->spin_mutex); - for (a = 0; a < NOZOMI_MAX_PORTS; a++) { - struct tty_struct *tty; - if (test_and_clear_bit(a, &dc->flip)) { - tty = tty_port_tty_get(&dc->port[a].port); - if (tty) - tty_flip_buffer_push(tty); - tty_kref_put(tty); - } - } - return IRQ_HANDLED; -none: - spin_unlock(&dc->spin_mutex); - return IRQ_NONE; -} - -static void nozomi_get_card_type(struct nozomi *dc) -{ - int i; - u32 size = 0; - - for (i = 0; i < 6; i++) - size += pci_resource_len(dc->pdev, i); - - /* Assume card type F32_8 if no match */ - dc->card_type = size == 2048 ? F32_2 : F32_8; - - dev_info(&dc->pdev->dev, "Card type is: %d\n", dc->card_type); -} - -static void nozomi_setup_private_data(struct nozomi *dc) -{ - void __iomem *offset = dc->base_addr + dc->card_type / 2; - unsigned int i; - - dc->reg_fcr = (void __iomem *)(offset + R_FCR); - dc->reg_iir = (void __iomem *)(offset + R_IIR); - dc->reg_ier = (void __iomem *)(offset + R_IER); - dc->last_ier = 0; - dc->flip = 0; - - dc->port[PORT_MDM].token_dl = MDM_DL; - dc->port[PORT_DIAG].token_dl = DIAG_DL; - dc->port[PORT_APP1].token_dl = APP1_DL; - dc->port[PORT_APP2].token_dl = APP2_DL; - - for (i = 0; i < MAX_PORT; i++) - init_waitqueue_head(&dc->port[i].tty_wait); -} - -static ssize_t card_type_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - const struct nozomi *dc = pci_get_drvdata(to_pci_dev(dev)); - - return sprintf(buf, "%d\n", dc->card_type); -} -static DEVICE_ATTR(card_type, S_IRUGO, card_type_show, NULL); - -static ssize_t open_ttys_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - const struct nozomi *dc = pci_get_drvdata(to_pci_dev(dev)); - - return sprintf(buf, "%u\n", dc->open_ttys); -} -static DEVICE_ATTR(open_ttys, S_IRUGO, open_ttys_show, NULL); - -static void make_sysfs_files(struct nozomi *dc) -{ - if (device_create_file(&dc->pdev->dev, &dev_attr_card_type)) - dev_err(&dc->pdev->dev, - "Could not create sysfs file for card_type\n"); - if (device_create_file(&dc->pdev->dev, &dev_attr_open_ttys)) - dev_err(&dc->pdev->dev, - "Could not create sysfs file for open_ttys\n"); -} - -static void remove_sysfs_files(struct nozomi *dc) -{ - device_remove_file(&dc->pdev->dev, &dev_attr_card_type); - device_remove_file(&dc->pdev->dev, &dev_attr_open_ttys); -} - -/* Allocate memory for one device */ -static int __devinit nozomi_card_init(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - resource_size_t start; - int ret; - struct nozomi *dc = NULL; - int ndev_idx; - int i; - - dev_dbg(&pdev->dev, "Init, new card found\n"); - - for (ndev_idx = 0; ndev_idx < ARRAY_SIZE(ndevs); ndev_idx++) - if (!ndevs[ndev_idx]) - break; - - if (ndev_idx >= ARRAY_SIZE(ndevs)) { - dev_err(&pdev->dev, "no free tty range for this card left\n"); - ret = -EIO; - goto err; - } - - dc = kzalloc(sizeof(struct nozomi), GFP_KERNEL); - if (unlikely(!dc)) { - dev_err(&pdev->dev, "Could not allocate memory\n"); - ret = -ENOMEM; - goto err_free; - } - - dc->pdev = pdev; - - ret = pci_enable_device(dc->pdev); - if (ret) { - dev_err(&pdev->dev, "Failed to enable PCI Device\n"); - goto err_free; - } - - ret = pci_request_regions(dc->pdev, NOZOMI_NAME); - if (ret) { - dev_err(&pdev->dev, "I/O address 0x%04x already in use\n", - (int) /* nozomi_private.io_addr */ 0); - goto err_disable_device; - } - - start = pci_resource_start(dc->pdev, 0); - if (start == 0) { - dev_err(&pdev->dev, "No I/O address for card detected\n"); - ret = -ENODEV; - goto err_rel_regs; - } - - /* Find out what card type it is */ - nozomi_get_card_type(dc); - - dc->base_addr = ioremap_nocache(start, dc->card_type); - if (!dc->base_addr) { - dev_err(&pdev->dev, "Unable to map card MMIO\n"); - ret = -ENODEV; - goto err_rel_regs; - } - - dc->send_buf = kmalloc(SEND_BUF_MAX, GFP_KERNEL); - if (!dc->send_buf) { - dev_err(&pdev->dev, "Could not allocate send buffer?\n"); - ret = -ENOMEM; - goto err_free_sbuf; - } - - for (i = PORT_MDM; i < MAX_PORT; i++) { - if (kfifo_alloc(&dc->port[i].fifo_ul, - FIFO_BUFFER_SIZE_UL, GFP_ATOMIC)) { - dev_err(&pdev->dev, - "Could not allocate kfifo buffer\n"); - ret = -ENOMEM; - goto err_free_kfifo; - } - } - - spin_lock_init(&dc->spin_mutex); - - nozomi_setup_private_data(dc); - - /* Disable all interrupts */ - dc->last_ier = 0; - writew(dc->last_ier, dc->reg_ier); - - ret = request_irq(pdev->irq, &interrupt_handler, IRQF_SHARED, - NOZOMI_NAME, dc); - if (unlikely(ret)) { - dev_err(&pdev->dev, "can't request irq %d\n", pdev->irq); - goto err_free_kfifo; - } - - DBG1("base_addr: %p", dc->base_addr); - - make_sysfs_files(dc); - - dc->index_start = ndev_idx * MAX_PORT; - ndevs[ndev_idx] = dc; - - pci_set_drvdata(pdev, dc); - - /* Enable RESET interrupt */ - dc->last_ier = RESET; - iowrite16(dc->last_ier, dc->reg_ier); - - dc->state = NOZOMI_STATE_ENABLED; - - for (i = 0; i < MAX_PORT; i++) { - struct device *tty_dev; - struct port *port = &dc->port[i]; - port->dc = dc; - mutex_init(&port->tty_sem); - tty_port_init(&port->port); - port->port.ops = &noz_tty_port_ops; - tty_dev = tty_register_device(ntty_driver, dc->index_start + i, - &pdev->dev); - - if (IS_ERR(tty_dev)) { - ret = PTR_ERR(tty_dev); - dev_err(&pdev->dev, "Could not allocate tty?\n"); - goto err_free_tty; - } - } - - return 0; - -err_free_tty: - for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i) - tty_unregister_device(ntty_driver, i); -err_free_kfifo: - for (i = 0; i < MAX_PORT; i++) - kfifo_free(&dc->port[i].fifo_ul); -err_free_sbuf: - kfree(dc->send_buf); - iounmap(dc->base_addr); -err_rel_regs: - pci_release_regions(pdev); -err_disable_device: - pci_disable_device(pdev); -err_free: - kfree(dc); -err: - return ret; -} - -static void __devexit tty_exit(struct nozomi *dc) -{ - unsigned int i; - - DBG1(" "); - - flush_scheduled_work(); - - for (i = 0; i < MAX_PORT; ++i) { - struct tty_struct *tty = tty_port_tty_get(&dc->port[i].port); - if (tty && list_empty(&tty->hangup_work.entry)) - tty_hangup(tty); - tty_kref_put(tty); - } - /* Racy below - surely should wait for scheduled work to be done or - complete off a hangup method ? */ - while (dc->open_ttys) - msleep(1); - for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i) - tty_unregister_device(ntty_driver, i); -} - -/* Deallocate memory for one device */ -static void __devexit nozomi_card_exit(struct pci_dev *pdev) -{ - int i; - struct ctrl_ul ctrl; - struct nozomi *dc = pci_get_drvdata(pdev); - - /* Disable all interrupts */ - dc->last_ier = 0; - writew(dc->last_ier, dc->reg_ier); - - tty_exit(dc); - - /* Send 0x0001, command card to resend the reset token. */ - /* This is to get the reset when the module is reloaded. */ - ctrl.port = 0x00; - ctrl.reserved = 0; - ctrl.RTS = 0; - ctrl.DTR = 1; - DBG1("sending flow control 0x%04X", *((u16 *)&ctrl)); - - /* Setup dc->reg addresses to we can use defines here */ - write_mem32(dc->port[PORT_CTRL].ul_addr[0], (u32 *)&ctrl, 2); - writew(CTRL_UL, dc->reg_fcr); /* push the token to the card. */ - - remove_sysfs_files(dc); - - free_irq(pdev->irq, dc); - - for (i = 0; i < MAX_PORT; i++) - kfifo_free(&dc->port[i].fifo_ul); - - kfree(dc->send_buf); - - iounmap(dc->base_addr); - - pci_release_regions(pdev); - - pci_disable_device(pdev); - - ndevs[dc->index_start / MAX_PORT] = NULL; - - kfree(dc); -} - -static void set_rts(const struct tty_struct *tty, int rts) -{ - struct port *port = get_port_by_tty(tty); - - port->ctrl_ul.RTS = rts; - port->update_flow_control = 1; - enable_transmit_ul(PORT_CTRL, get_dc_by_tty(tty)); -} - -static void set_dtr(const struct tty_struct *tty, int dtr) -{ - struct port *port = get_port_by_tty(tty); - - DBG1("SETTING DTR index: %d, dtr: %d", tty->index, dtr); - - port->ctrl_ul.DTR = dtr; - port->update_flow_control = 1; - enable_transmit_ul(PORT_CTRL, get_dc_by_tty(tty)); -} - -/* - * ---------------------------------------------------------------------------- - * TTY code - * ---------------------------------------------------------------------------- - */ - -static int ntty_install(struct tty_driver *driver, struct tty_struct *tty) -{ - struct port *port = get_port_by_tty(tty); - struct nozomi *dc = get_dc_by_tty(tty); - int ret; - if (!port || !dc || dc->state != NOZOMI_STATE_READY) - return -ENODEV; - ret = tty_init_termios(tty); - if (ret == 0) { - tty_driver_kref_get(driver); - tty->count++; - tty->driver_data = port; - driver->ttys[tty->index] = tty; - } - return ret; -} - -static void ntty_cleanup(struct tty_struct *tty) -{ - tty->driver_data = NULL; -} - -static int ntty_activate(struct tty_port *tport, struct tty_struct *tty) -{ - struct port *port = container_of(tport, struct port, port); - struct nozomi *dc = port->dc; - unsigned long flags; - - DBG1("open: %d", port->token_dl); - spin_lock_irqsave(&dc->spin_mutex, flags); - dc->last_ier = dc->last_ier | port->token_dl; - writew(dc->last_ier, dc->reg_ier); - dc->open_ttys++; - spin_unlock_irqrestore(&dc->spin_mutex, flags); - printk("noz: activated %d: %p\n", tty->index, tport); - return 0; -} - -static int ntty_open(struct tty_struct *tty, struct file *filp) -{ - struct port *port = tty->driver_data; - return tty_port_open(&port->port, tty, filp); -} - -static void ntty_shutdown(struct tty_port *tport) -{ - struct port *port = container_of(tport, struct port, port); - struct nozomi *dc = port->dc; - unsigned long flags; - - DBG1("close: %d", port->token_dl); - spin_lock_irqsave(&dc->spin_mutex, flags); - dc->last_ier &= ~(port->token_dl); - writew(dc->last_ier, dc->reg_ier); - dc->open_ttys--; - spin_unlock_irqrestore(&dc->spin_mutex, flags); - printk("noz: shutdown %p\n", tport); -} - -static void ntty_close(struct tty_struct *tty, struct file *filp) -{ - struct port *port = tty->driver_data; - if (port) - tty_port_close(&port->port, tty, filp); -} - -static void ntty_hangup(struct tty_struct *tty) -{ - struct port *port = tty->driver_data; - tty_port_hangup(&port->port); -} - -/* - * called when the userspace process writes to the tty (/dev/noz*). - * Data is inserted into a fifo, which is then read and transfered to the modem. - */ -static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, - int count) -{ - int rval = -EINVAL; - struct nozomi *dc = get_dc_by_tty(tty); - struct port *port = tty->driver_data; - unsigned long flags; - - /* DBG1( "WRITEx: %d, index = %d", count, index); */ - - if (!dc || !port) - return -ENODEV; - - mutex_lock(&port->tty_sem); - - if (unlikely(!port->port.count)) { - DBG1(" "); - goto exit; - } - - rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count); - - /* notify card */ - if (unlikely(dc == NULL)) { - DBG1("No device context?"); - goto exit; - } - - spin_lock_irqsave(&dc->spin_mutex, flags); - /* CTS is only valid on the modem channel */ - if (port == &(dc->port[PORT_MDM])) { - if (port->ctrl_dl.CTS) { - DBG4("Enable interrupt"); - enable_transmit_ul(tty->index % MAX_PORT, dc); - } else { - dev_err(&dc->pdev->dev, - "CTS not active on modem port?\n"); - } - } else { - enable_transmit_ul(tty->index % MAX_PORT, dc); - } - spin_unlock_irqrestore(&dc->spin_mutex, flags); - -exit: - mutex_unlock(&port->tty_sem); - return rval; -} - -/* - * Calculate how much is left in device - * This method is called by the upper tty layer. - * #according to sources N_TTY.c it expects a value >= 0 and - * does not check for negative values. - * - * If the port is unplugged report lots of room and let the bits - * dribble away so we don't block anything. - */ -static int ntty_write_room(struct tty_struct *tty) -{ - struct port *port = tty->driver_data; - int room = 4096; - const struct nozomi *dc = get_dc_by_tty(tty); - - if (dc) { - mutex_lock(&port->tty_sem); - if (port->port.count) - room = kfifo_avail(&port->fifo_ul); - mutex_unlock(&port->tty_sem); - } - return room; -} - -/* Gets io control parameters */ -static int ntty_tiocmget(struct tty_struct *tty) -{ - const struct port *port = tty->driver_data; - const struct ctrl_dl *ctrl_dl = &port->ctrl_dl; - const struct ctrl_ul *ctrl_ul = &port->ctrl_ul; - - /* Note: these could change under us but it is not clear this - matters if so */ - return (ctrl_ul->RTS ? TIOCM_RTS : 0) | - (ctrl_ul->DTR ? TIOCM_DTR : 0) | - (ctrl_dl->DCD ? TIOCM_CAR : 0) | - (ctrl_dl->RI ? TIOCM_RNG : 0) | - (ctrl_dl->DSR ? TIOCM_DSR : 0) | - (ctrl_dl->CTS ? TIOCM_CTS : 0); -} - -/* Sets io controls parameters */ -static int ntty_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct nozomi *dc = get_dc_by_tty(tty); - unsigned long flags; - - spin_lock_irqsave(&dc->spin_mutex, flags); - if (set & TIOCM_RTS) - set_rts(tty, 1); - else if (clear & TIOCM_RTS) - set_rts(tty, 0); - - if (set & TIOCM_DTR) - set_dtr(tty, 1); - else if (clear & TIOCM_DTR) - set_dtr(tty, 0); - spin_unlock_irqrestore(&dc->spin_mutex, flags); - - return 0; -} - -static int ntty_cflags_changed(struct port *port, unsigned long flags, - struct async_icount *cprev) -{ - const struct async_icount cnow = port->tty_icount; - int ret; - - ret = ((flags & TIOCM_RNG) && (cnow.rng != cprev->rng)) || - ((flags & TIOCM_DSR) && (cnow.dsr != cprev->dsr)) || - ((flags & TIOCM_CD) && (cnow.dcd != cprev->dcd)) || - ((flags & TIOCM_CTS) && (cnow.cts != cprev->cts)); - - *cprev = cnow; - - return ret; -} - -static int ntty_tiocgicount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct port *port = tty->driver_data; - const struct async_icount cnow = port->tty_icount; - - icount->cts = cnow.cts; - icount->dsr = cnow.dsr; - icount->rng = cnow.rng; - icount->dcd = cnow.dcd; - icount->rx = cnow.rx; - icount->tx = cnow.tx; - icount->frame = cnow.frame; - icount->overrun = cnow.overrun; - icount->parity = cnow.parity; - icount->brk = cnow.brk; - icount->buf_overrun = cnow.buf_overrun; - return 0; -} - -static int ntty_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct port *port = tty->driver_data; - int rval = -ENOIOCTLCMD; - - DBG1("******** IOCTL, cmd: %d", cmd); - - switch (cmd) { - case TIOCMIWAIT: { - struct async_icount cprev = port->tty_icount; - - rval = wait_event_interruptible(port->tty_wait, - ntty_cflags_changed(port, arg, &cprev)); - break; - } - default: - DBG1("ERR: 0x%08X, %d", cmd, cmd); - break; - }; - - return rval; -} - -/* - * Called by the upper tty layer when tty buffers are ready - * to receive data again after a call to throttle. - */ -static void ntty_unthrottle(struct tty_struct *tty) -{ - struct nozomi *dc = get_dc_by_tty(tty); - unsigned long flags; - - DBG1("UNTHROTTLE"); - spin_lock_irqsave(&dc->spin_mutex, flags); - enable_transmit_dl(tty->index % MAX_PORT, dc); - set_rts(tty, 1); - - spin_unlock_irqrestore(&dc->spin_mutex, flags); -} - -/* - * Called by the upper tty layer when the tty buffers are almost full. - * The driver should stop send more data. - */ -static void ntty_throttle(struct tty_struct *tty) -{ - struct nozomi *dc = get_dc_by_tty(tty); - unsigned long flags; - - DBG1("THROTTLE"); - spin_lock_irqsave(&dc->spin_mutex, flags); - set_rts(tty, 0); - spin_unlock_irqrestore(&dc->spin_mutex, flags); -} - -/* Returns number of chars in buffer, called by tty layer */ -static s32 ntty_chars_in_buffer(struct tty_struct *tty) -{ - struct port *port = tty->driver_data; - struct nozomi *dc = get_dc_by_tty(tty); - s32 rval = 0; - - if (unlikely(!dc || !port)) { - goto exit_in_buffer; - } - - if (unlikely(!port->port.count)) { - dev_err(&dc->pdev->dev, "No tty open?\n"); - goto exit_in_buffer; - } - - rval = kfifo_len(&port->fifo_ul); - -exit_in_buffer: - return rval; -} - -static const struct tty_port_operations noz_tty_port_ops = { - .activate = ntty_activate, - .shutdown = ntty_shutdown, -}; - -static const struct tty_operations tty_ops = { - .ioctl = ntty_ioctl, - .open = ntty_open, - .close = ntty_close, - .hangup = ntty_hangup, - .write = ntty_write, - .write_room = ntty_write_room, - .unthrottle = ntty_unthrottle, - .throttle = ntty_throttle, - .chars_in_buffer = ntty_chars_in_buffer, - .tiocmget = ntty_tiocmget, - .tiocmset = ntty_tiocmset, - .get_icount = ntty_tiocgicount, - .install = ntty_install, - .cleanup = ntty_cleanup, -}; - -/* Module initialization */ -static struct pci_driver nozomi_driver = { - .name = NOZOMI_NAME, - .id_table = nozomi_pci_tbl, - .probe = nozomi_card_init, - .remove = __devexit_p(nozomi_card_exit), -}; - -static __init int nozomi_init(void) -{ - int ret; - - printk(KERN_INFO "Initializing %s\n", VERSION_STRING); - - ntty_driver = alloc_tty_driver(NTTY_TTY_MAXMINORS); - if (!ntty_driver) - return -ENOMEM; - - ntty_driver->owner = THIS_MODULE; - ntty_driver->driver_name = NOZOMI_NAME_TTY; - ntty_driver->name = "noz"; - ntty_driver->major = 0; - ntty_driver->type = TTY_DRIVER_TYPE_SERIAL; - ntty_driver->subtype = SERIAL_TYPE_NORMAL; - ntty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; - ntty_driver->init_termios = tty_std_termios; - ntty_driver->init_termios.c_cflag = B115200 | CS8 | CREAD | \ - HUPCL | CLOCAL; - ntty_driver->init_termios.c_ispeed = 115200; - ntty_driver->init_termios.c_ospeed = 115200; - tty_set_operations(ntty_driver, &tty_ops); - - ret = tty_register_driver(ntty_driver); - if (ret) { - printk(KERN_ERR "Nozomi: failed to register ntty driver\n"); - goto free_tty; - } - - ret = pci_register_driver(&nozomi_driver); - if (ret) { - printk(KERN_ERR "Nozomi: can't register pci driver\n"); - goto unr_tty; - } - - return 0; -unr_tty: - tty_unregister_driver(ntty_driver); -free_tty: - put_tty_driver(ntty_driver); - return ret; -} - -static __exit void nozomi_exit(void) -{ - printk(KERN_INFO "Unloading %s\n", DRIVER_DESC); - pci_unregister_driver(&nozomi_driver); - tty_unregister_driver(ntty_driver); - put_tty_driver(ntty_driver); -} - -module_init(nozomi_init); -module_exit(nozomi_exit); - -module_param(debug, int, S_IRUGO | S_IWUSR); - -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c deleted file mode 100644 index 3780da8ad12d..000000000000 --- a/drivers/char/rocket.c +++ /dev/null @@ -1,3199 +0,0 @@ -/* - * RocketPort device driver for Linux - * - * Written by Theodore Ts'o, 1995, 1996, 1997, 1998, 1999, 2000. - * - * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2003 by Comtrol, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * Kernel Synchronization: - * - * This driver has 2 kernel control paths - exception handlers (calls into the driver - * from user mode) and the timer bottom half (tasklet). This is a polled driver, interrupts - * are not used. - * - * Critical data: - * - rp_table[], accessed through passed "info" pointers, is a global (static) array of - * serial port state information and the xmit_buf circular buffer. Protected by - * a per port spinlock. - * - xmit_flags[], an array of ints indexed by line (port) number, indicating that there - * is data to be transmitted. Protected by atomic bit operations. - * - rp_num_ports, int indicating number of open ports, protected by atomic operations. - * - * rp_write() and rp_write_char() functions use a per port semaphore to protect against - * simultaneous access to the same port by more than one process. - */ - -/****** Defines ******/ -#define ROCKET_PARANOIA_CHECK -#define ROCKET_DISABLE_SIMUSAGE - -#undef ROCKET_SOFT_FLOW -#undef ROCKET_DEBUG_OPEN -#undef ROCKET_DEBUG_INTR -#undef ROCKET_DEBUG_WRITE -#undef ROCKET_DEBUG_FLOW -#undef ROCKET_DEBUG_THROTTLE -#undef ROCKET_DEBUG_WAIT_UNTIL_SENT -#undef ROCKET_DEBUG_RECEIVE -#undef ROCKET_DEBUG_HANGUP -#undef REV_PCI_ORDER -#undef ROCKET_DEBUG_IO - -#define POLL_PERIOD HZ/100 /* Polling period .01 seconds (10ms) */ - -/****** Kernel includes ******/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/****** RocketPort includes ******/ - -#include "rocket_int.h" -#include "rocket.h" - -#define ROCKET_VERSION "2.09" -#define ROCKET_DATE "12-June-2003" - -/****** RocketPort Local Variables ******/ - -static void rp_do_poll(unsigned long dummy); - -static struct tty_driver *rocket_driver; - -static struct rocket_version driver_version = { - ROCKET_VERSION, ROCKET_DATE -}; - -static struct r_port *rp_table[MAX_RP_PORTS]; /* The main repository of serial port state information. */ -static unsigned int xmit_flags[NUM_BOARDS]; /* Bit significant, indicates port had data to transmit. */ - /* eg. Bit 0 indicates port 0 has xmit data, ... */ -static atomic_t rp_num_ports_open; /* Number of serial ports open */ -static DEFINE_TIMER(rocket_timer, rp_do_poll, 0, 0); - -static unsigned long board1; /* ISA addresses, retrieved from rocketport.conf */ -static unsigned long board2; -static unsigned long board3; -static unsigned long board4; -static unsigned long controller; -static int support_low_speed; -static unsigned long modem1; -static unsigned long modem2; -static unsigned long modem3; -static unsigned long modem4; -static unsigned long pc104_1[8]; -static unsigned long pc104_2[8]; -static unsigned long pc104_3[8]; -static unsigned long pc104_4[8]; -static unsigned long *pc104[4] = { pc104_1, pc104_2, pc104_3, pc104_4 }; - -static int rp_baud_base[NUM_BOARDS]; /* Board config info (Someday make a per-board structure) */ -static unsigned long rcktpt_io_addr[NUM_BOARDS]; -static int rcktpt_type[NUM_BOARDS]; -static int is_PCI[NUM_BOARDS]; -static rocketModel_t rocketModel[NUM_BOARDS]; -static int max_board; -static const struct tty_port_operations rocket_port_ops; - -/* - * The following arrays define the interrupt bits corresponding to each AIOP. - * These bits are different between the ISA and regular PCI boards and the - * Universal PCI boards. - */ - -static Word_t aiop_intr_bits[AIOP_CTL_SIZE] = { - AIOP_INTR_BIT_0, - AIOP_INTR_BIT_1, - AIOP_INTR_BIT_2, - AIOP_INTR_BIT_3 -}; - -static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = { - UPCI_AIOP_INTR_BIT_0, - UPCI_AIOP_INTR_BIT_1, - UPCI_AIOP_INTR_BIT_2, - UPCI_AIOP_INTR_BIT_3 -}; - -static Byte_t RData[RDATASIZE] = { - 0x00, 0x09, 0xf6, 0x82, - 0x02, 0x09, 0x86, 0xfb, - 0x04, 0x09, 0x00, 0x0a, - 0x06, 0x09, 0x01, 0x0a, - 0x08, 0x09, 0x8a, 0x13, - 0x0a, 0x09, 0xc5, 0x11, - 0x0c, 0x09, 0x86, 0x85, - 0x0e, 0x09, 0x20, 0x0a, - 0x10, 0x09, 0x21, 0x0a, - 0x12, 0x09, 0x41, 0xff, - 0x14, 0x09, 0x82, 0x00, - 0x16, 0x09, 0x82, 0x7b, - 0x18, 0x09, 0x8a, 0x7d, - 0x1a, 0x09, 0x88, 0x81, - 0x1c, 0x09, 0x86, 0x7a, - 0x1e, 0x09, 0x84, 0x81, - 0x20, 0x09, 0x82, 0x7c, - 0x22, 0x09, 0x0a, 0x0a -}; - -static Byte_t RRegData[RREGDATASIZE] = { - 0x00, 0x09, 0xf6, 0x82, /* 00: Stop Rx processor */ - 0x08, 0x09, 0x8a, 0x13, /* 04: Tx software flow control */ - 0x0a, 0x09, 0xc5, 0x11, /* 08: XON char */ - 0x0c, 0x09, 0x86, 0x85, /* 0c: XANY */ - 0x12, 0x09, 0x41, 0xff, /* 10: Rx mask char */ - 0x14, 0x09, 0x82, 0x00, /* 14: Compare/Ignore #0 */ - 0x16, 0x09, 0x82, 0x7b, /* 18: Compare #1 */ - 0x18, 0x09, 0x8a, 0x7d, /* 1c: Compare #2 */ - 0x1a, 0x09, 0x88, 0x81, /* 20: Interrupt #1 */ - 0x1c, 0x09, 0x86, 0x7a, /* 24: Ignore/Replace #1 */ - 0x1e, 0x09, 0x84, 0x81, /* 28: Interrupt #2 */ - 0x20, 0x09, 0x82, 0x7c, /* 2c: Ignore/Replace #2 */ - 0x22, 0x09, 0x0a, 0x0a /* 30: Rx FIFO Enable */ -}; - -static CONTROLLER_T sController[CTL_SIZE] = { - {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, - {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}, - {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, - {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}, - {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, - {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}, - {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, - {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}} -}; - -static Byte_t sBitMapClrTbl[8] = { - 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f -}; - -static Byte_t sBitMapSetTbl[8] = { - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 -}; - -static int sClockPrescale = 0x14; - -/* - * Line number is the ttySIx number (x), the Minor number. We - * assign them sequentially, starting at zero. The following - * array keeps track of the line number assigned to a given board/aiop/channel. - */ -static unsigned char lineNumbers[MAX_RP_PORTS]; -static unsigned long nextLineNumber; - -/***** RocketPort Static Prototypes *********/ -static int __init init_ISA(int i); -static void rp_wait_until_sent(struct tty_struct *tty, int timeout); -static void rp_flush_buffer(struct tty_struct *tty); -static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model); -static unsigned char GetLineNumber(int ctrl, int aiop, int ch); -static unsigned char SetLineNumber(int ctrl, int aiop, int ch); -static void rp_start(struct tty_struct *tty); -static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum, - int ChanNum); -static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode); -static void sFlushRxFIFO(CHANNEL_T * ChP); -static void sFlushTxFIFO(CHANNEL_T * ChP); -static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags); -static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags); -static void sModemReset(CONTROLLER_T * CtlP, int chan, int on); -static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on); -static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data); -static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, - ByteIO_t * AiopIOList, int AiopIOListSize, - WordIO_t ConfigIO, int IRQNum, Byte_t Frequency, - int PeriodicOnly, int altChanRingIndicator, - int UPCIRingInd); -static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, - ByteIO_t * AiopIOList, int AiopIOListSize, - int IRQNum, Byte_t Frequency, int PeriodicOnly); -static int sReadAiopID(ByteIO_t io); -static int sReadAiopNumChan(WordIO_t io); - -MODULE_AUTHOR("Theodore Ts'o"); -MODULE_DESCRIPTION("Comtrol RocketPort driver"); -module_param(board1, ulong, 0); -MODULE_PARM_DESC(board1, "I/O port for (ISA) board #1"); -module_param(board2, ulong, 0); -MODULE_PARM_DESC(board2, "I/O port for (ISA) board #2"); -module_param(board3, ulong, 0); -MODULE_PARM_DESC(board3, "I/O port for (ISA) board #3"); -module_param(board4, ulong, 0); -MODULE_PARM_DESC(board4, "I/O port for (ISA) board #4"); -module_param(controller, ulong, 0); -MODULE_PARM_DESC(controller, "I/O port for (ISA) rocketport controller"); -module_param(support_low_speed, bool, 0); -MODULE_PARM_DESC(support_low_speed, "1 means support 50 baud, 0 means support 460400 baud"); -module_param(modem1, ulong, 0); -MODULE_PARM_DESC(modem1, "1 means (ISA) board #1 is a RocketModem"); -module_param(modem2, ulong, 0); -MODULE_PARM_DESC(modem2, "1 means (ISA) board #2 is a RocketModem"); -module_param(modem3, ulong, 0); -MODULE_PARM_DESC(modem3, "1 means (ISA) board #3 is a RocketModem"); -module_param(modem4, ulong, 0); -MODULE_PARM_DESC(modem4, "1 means (ISA) board #4 is a RocketModem"); -module_param_array(pc104_1, ulong, NULL, 0); -MODULE_PARM_DESC(pc104_1, "set interface types for ISA(PC104) board #1 (e.g. pc104_1=232,232,485,485,..."); -module_param_array(pc104_2, ulong, NULL, 0); -MODULE_PARM_DESC(pc104_2, "set interface types for ISA(PC104) board #2 (e.g. pc104_2=232,232,485,485,..."); -module_param_array(pc104_3, ulong, NULL, 0); -MODULE_PARM_DESC(pc104_3, "set interface types for ISA(PC104) board #3 (e.g. pc104_3=232,232,485,485,..."); -module_param_array(pc104_4, ulong, NULL, 0); -MODULE_PARM_DESC(pc104_4, "set interface types for ISA(PC104) board #4 (e.g. pc104_4=232,232,485,485,..."); - -static int rp_init(void); -static void rp_cleanup_module(void); - -module_init(rp_init); -module_exit(rp_cleanup_module); - - -MODULE_LICENSE("Dual BSD/GPL"); - -/*************************************************************************/ -/* Module code starts here */ - -static inline int rocket_paranoia_check(struct r_port *info, - const char *routine) -{ -#ifdef ROCKET_PARANOIA_CHECK - if (!info) - return 1; - if (info->magic != RPORT_MAGIC) { - printk(KERN_WARNING "Warning: bad magic number for rocketport " - "struct in %s\n", routine); - return 1; - } -#endif - return 0; -} - - -/* Serial port receive data function. Called (from timer poll) when an AIOPIC signals - * that receive data is present on a serial port. Pulls data from FIFO, moves it into the - * tty layer. - */ -static void rp_do_receive(struct r_port *info, - struct tty_struct *tty, - CHANNEL_t * cp, unsigned int ChanStatus) -{ - unsigned int CharNStat; - int ToRecv, wRecv, space; - unsigned char *cbuf; - - ToRecv = sGetRxCnt(cp); -#ifdef ROCKET_DEBUG_INTR - printk(KERN_INFO "rp_do_receive(%d)...\n", ToRecv); -#endif - if (ToRecv == 0) - return; - - /* - * if status indicates there are errored characters in the - * FIFO, then enter status mode (a word in FIFO holds - * character and status). - */ - if (ChanStatus & (RXFOVERFL | RXBREAK | RXFRAME | RXPARITY)) { - if (!(ChanStatus & STATMODE)) { -#ifdef ROCKET_DEBUG_RECEIVE - printk(KERN_INFO "Entering STATMODE...\n"); -#endif - ChanStatus |= STATMODE; - sEnRxStatusMode(cp); - } - } - - /* - * if we previously entered status mode, then read down the - * FIFO one word at a time, pulling apart the character and - * the status. Update error counters depending on status - */ - if (ChanStatus & STATMODE) { -#ifdef ROCKET_DEBUG_RECEIVE - printk(KERN_INFO "Ignore %x, read %x...\n", - info->ignore_status_mask, info->read_status_mask); -#endif - while (ToRecv) { - char flag; - - CharNStat = sInW(sGetTxRxDataIO(cp)); -#ifdef ROCKET_DEBUG_RECEIVE - printk(KERN_INFO "%x...\n", CharNStat); -#endif - if (CharNStat & STMBREAKH) - CharNStat &= ~(STMFRAMEH | STMPARITYH); - if (CharNStat & info->ignore_status_mask) { - ToRecv--; - continue; - } - CharNStat &= info->read_status_mask; - if (CharNStat & STMBREAKH) - flag = TTY_BREAK; - else if (CharNStat & STMPARITYH) - flag = TTY_PARITY; - else if (CharNStat & STMFRAMEH) - flag = TTY_FRAME; - else if (CharNStat & STMRCVROVRH) - flag = TTY_OVERRUN; - else - flag = TTY_NORMAL; - tty_insert_flip_char(tty, CharNStat & 0xff, flag); - ToRecv--; - } - - /* - * after we've emptied the FIFO in status mode, turn - * status mode back off - */ - if (sGetRxCnt(cp) == 0) { -#ifdef ROCKET_DEBUG_RECEIVE - printk(KERN_INFO "Status mode off.\n"); -#endif - sDisRxStatusMode(cp); - } - } else { - /* - * we aren't in status mode, so read down the FIFO two - * characters at time by doing repeated word IO - * transfer. - */ - space = tty_prepare_flip_string(tty, &cbuf, ToRecv); - if (space < ToRecv) { -#ifdef ROCKET_DEBUG_RECEIVE - printk(KERN_INFO "rp_do_receive:insufficient space ToRecv=%d space=%d\n", ToRecv, space); -#endif - if (space <= 0) - return; - ToRecv = space; - } - wRecv = ToRecv >> 1; - if (wRecv) - sInStrW(sGetTxRxDataIO(cp), (unsigned short *) cbuf, wRecv); - if (ToRecv & 1) - cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp)); - } - /* Push the data up to the tty layer */ - tty_flip_buffer_push(tty); -} - -/* - * Serial port transmit data function. Called from the timer polling loop as a - * result of a bit set in xmit_flags[], indicating data (from the tty layer) is ready - * to be sent out the serial port. Data is buffered in rp_table[line].xmit_buf, it is - * moved to the port's xmit FIFO. *info is critical data, protected by spinlocks. - */ -static void rp_do_transmit(struct r_port *info) -{ - int c; - CHANNEL_t *cp = &info->channel; - struct tty_struct *tty; - unsigned long flags; - -#ifdef ROCKET_DEBUG_INTR - printk(KERN_DEBUG "%s\n", __func__); -#endif - if (!info) - return; - tty = tty_port_tty_get(&info->port); - - if (tty == NULL) { - printk(KERN_WARNING "rp: WARNING %s called with tty==NULL\n", __func__); - clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); - return; - } - - spin_lock_irqsave(&info->slock, flags); - info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp); - - /* Loop sending data to FIFO until done or FIFO full */ - while (1) { - if (tty->stopped || tty->hw_stopped) - break; - c = min(info->xmit_fifo_room, info->xmit_cnt); - c = min(c, XMIT_BUF_SIZE - info->xmit_tail); - if (c <= 0 || info->xmit_fifo_room <= 0) - break; - sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) (info->xmit_buf + info->xmit_tail), c / 2); - if (c & 1) - sOutB(sGetTxRxDataIO(cp), info->xmit_buf[info->xmit_tail + c - 1]); - info->xmit_tail += c; - info->xmit_tail &= XMIT_BUF_SIZE - 1; - info->xmit_cnt -= c; - info->xmit_fifo_room -= c; -#ifdef ROCKET_DEBUG_INTR - printk(KERN_INFO "tx %d chars...\n", c); -#endif - } - - if (info->xmit_cnt == 0) - clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); - - if (info->xmit_cnt < WAKEUP_CHARS) { - tty_wakeup(tty); -#ifdef ROCKETPORT_HAVE_POLL_WAIT - wake_up_interruptible(&tty->poll_wait); -#endif - } - - spin_unlock_irqrestore(&info->slock, flags); - tty_kref_put(tty); - -#ifdef ROCKET_DEBUG_INTR - printk(KERN_DEBUG "(%d,%d,%d,%d)...\n", info->xmit_cnt, info->xmit_head, - info->xmit_tail, info->xmit_fifo_room); -#endif -} - -/* - * Called when a serial port signals it has read data in it's RX FIFO. - * It checks what interrupts are pending and services them, including - * receiving serial data. - */ -static void rp_handle_port(struct r_port *info) -{ - CHANNEL_t *cp; - struct tty_struct *tty; - unsigned int IntMask, ChanStatus; - - if (!info) - return; - - if ((info->port.flags & ASYNC_INITIALIZED) == 0) { - printk(KERN_WARNING "rp: WARNING: rp_handle_port called with " - "info->flags & NOT_INIT\n"); - return; - } - tty = tty_port_tty_get(&info->port); - if (!tty) { - printk(KERN_WARNING "rp: WARNING: rp_handle_port called with " - "tty==NULL\n"); - return; - } - cp = &info->channel; - - IntMask = sGetChanIntID(cp) & info->intmask; -#ifdef ROCKET_DEBUG_INTR - printk(KERN_INFO "rp_interrupt %02x...\n", IntMask); -#endif - ChanStatus = sGetChanStatus(cp); - if (IntMask & RXF_TRIG) { /* Rx FIFO trigger level */ - rp_do_receive(info, tty, cp, ChanStatus); - } - if (IntMask & DELTA_CD) { /* CD change */ -#if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_INTR) || defined(ROCKET_DEBUG_HANGUP)) - printk(KERN_INFO "ttyR%d CD now %s...\n", info->line, - (ChanStatus & CD_ACT) ? "on" : "off"); -#endif - if (!(ChanStatus & CD_ACT) && info->cd_status) { -#ifdef ROCKET_DEBUG_HANGUP - printk(KERN_INFO "CD drop, calling hangup.\n"); -#endif - tty_hangup(tty); - } - info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0; - wake_up_interruptible(&info->port.open_wait); - } -#ifdef ROCKET_DEBUG_INTR - if (IntMask & DELTA_CTS) { /* CTS change */ - printk(KERN_INFO "CTS change...\n"); - } - if (IntMask & DELTA_DSR) { /* DSR change */ - printk(KERN_INFO "DSR change...\n"); - } -#endif - tty_kref_put(tty); -} - -/* - * The top level polling routine. Repeats every 1/100 HZ (10ms). - */ -static void rp_do_poll(unsigned long dummy) -{ - CONTROLLER_t *ctlp; - int ctrl, aiop, ch, line; - unsigned int xmitmask, i; - unsigned int CtlMask; - unsigned char AiopMask; - Word_t bit; - - /* Walk through all the boards (ctrl's) */ - for (ctrl = 0; ctrl < max_board; ctrl++) { - if (rcktpt_io_addr[ctrl] <= 0) - continue; - - /* Get a ptr to the board's control struct */ - ctlp = sCtlNumToCtlPtr(ctrl); - - /* Get the interrupt status from the board */ -#ifdef CONFIG_PCI - if (ctlp->BusType == isPCI) - CtlMask = sPCIGetControllerIntStatus(ctlp); - else -#endif - CtlMask = sGetControllerIntStatus(ctlp); - - /* Check if any AIOP read bits are set */ - for (aiop = 0; CtlMask; aiop++) { - bit = ctlp->AiopIntrBits[aiop]; - if (CtlMask & bit) { - CtlMask &= ~bit; - AiopMask = sGetAiopIntStatus(ctlp, aiop); - - /* Check if any port read bits are set */ - for (ch = 0; AiopMask; AiopMask >>= 1, ch++) { - if (AiopMask & 1) { - - /* Get the line number (/dev/ttyRx number). */ - /* Read the data from the port. */ - line = GetLineNumber(ctrl, aiop, ch); - rp_handle_port(rp_table[line]); - } - } - } - } - - xmitmask = xmit_flags[ctrl]; - - /* - * xmit_flags contains bit-significant flags, indicating there is data - * to xmit on the port. Bit 0 is port 0 on this board, bit 1 is port - * 1, ... (32 total possible). The variable i has the aiop and ch - * numbers encoded in it (port 0-7 are aiop0, 8-15 are aiop1, etc). - */ - if (xmitmask) { - for (i = 0; i < rocketModel[ctrl].numPorts; i++) { - if (xmitmask & (1 << i)) { - aiop = (i & 0x18) >> 3; - ch = i & 0x07; - line = GetLineNumber(ctrl, aiop, ch); - rp_do_transmit(rp_table[line]); - } - } - } - } - - /* - * Reset the timer so we get called at the next clock tick (10ms). - */ - if (atomic_read(&rp_num_ports_open)) - mod_timer(&rocket_timer, jiffies + POLL_PERIOD); -} - -/* - * Initializes the r_port structure for a port, as well as enabling the port on - * the board. - * Inputs: board, aiop, chan numbers - */ -static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) -{ - unsigned rocketMode; - struct r_port *info; - int line; - CONTROLLER_T *ctlp; - - /* Get the next available line number */ - line = SetLineNumber(board, aiop, chan); - - ctlp = sCtlNumToCtlPtr(board); - - /* Get a r_port struct for the port, fill it in and save it globally, indexed by line number */ - info = kzalloc(sizeof (struct r_port), GFP_KERNEL); - if (!info) { - printk(KERN_ERR "Couldn't allocate info struct for line #%d\n", - line); - return; - } - - info->magic = RPORT_MAGIC; - info->line = line; - info->ctlp = ctlp; - info->board = board; - info->aiop = aiop; - info->chan = chan; - tty_port_init(&info->port); - info->port.ops = &rocket_port_ops; - init_completion(&info->close_wait); - info->flags &= ~ROCKET_MODE_MASK; - switch (pc104[board][line]) { - case 422: - info->flags |= ROCKET_MODE_RS422; - break; - case 485: - info->flags |= ROCKET_MODE_RS485; - break; - case 232: - default: - info->flags |= ROCKET_MODE_RS232; - break; - } - - info->intmask = RXF_TRIG | TXFIFO_MT | SRC_INT | DELTA_CD | DELTA_CTS | DELTA_DSR; - if (sInitChan(ctlp, &info->channel, aiop, chan) == 0) { - printk(KERN_ERR "RocketPort sInitChan(%d, %d, %d) failed!\n", - board, aiop, chan); - kfree(info); - return; - } - - rocketMode = info->flags & ROCKET_MODE_MASK; - - if ((info->flags & ROCKET_RTS_TOGGLE) || (rocketMode == ROCKET_MODE_RS485)) - sEnRTSToggle(&info->channel); - else - sDisRTSToggle(&info->channel); - - if (ctlp->boardType == ROCKET_TYPE_PC104) { - switch (rocketMode) { - case ROCKET_MODE_RS485: - sSetInterfaceMode(&info->channel, InterfaceModeRS485); - break; - case ROCKET_MODE_RS422: - sSetInterfaceMode(&info->channel, InterfaceModeRS422); - break; - case ROCKET_MODE_RS232: - default: - if (info->flags & ROCKET_RTS_TOGGLE) - sSetInterfaceMode(&info->channel, InterfaceModeRS232T); - else - sSetInterfaceMode(&info->channel, InterfaceModeRS232); - break; - } - } - spin_lock_init(&info->slock); - mutex_init(&info->write_mtx); - rp_table[line] = info; - tty_register_device(rocket_driver, line, pci_dev ? &pci_dev->dev : - NULL); -} - -/* - * Configures a rocketport port according to its termio settings. Called from - * user mode into the driver (exception handler). *info CD manipulation is spinlock protected. - */ -static void configure_r_port(struct tty_struct *tty, struct r_port *info, - struct ktermios *old_termios) -{ - unsigned cflag; - unsigned long flags; - unsigned rocketMode; - int bits, baud, divisor; - CHANNEL_t *cp; - struct ktermios *t = tty->termios; - - cp = &info->channel; - cflag = t->c_cflag; - - /* Byte size and parity */ - if ((cflag & CSIZE) == CS8) { - sSetData8(cp); - bits = 10; - } else { - sSetData7(cp); - bits = 9; - } - if (cflag & CSTOPB) { - sSetStop2(cp); - bits++; - } else { - sSetStop1(cp); - } - - if (cflag & PARENB) { - sEnParity(cp); - bits++; - if (cflag & PARODD) { - sSetOddParity(cp); - } else { - sSetEvenParity(cp); - } - } else { - sDisParity(cp); - } - - /* baud rate */ - baud = tty_get_baud_rate(tty); - if (!baud) - baud = 9600; - divisor = ((rp_baud_base[info->board] + (baud >> 1)) / baud) - 1; - if ((divisor >= 8192 || divisor < 0) && old_termios) { - baud = tty_termios_baud_rate(old_termios); - if (!baud) - baud = 9600; - divisor = (rp_baud_base[info->board] / baud) - 1; - } - if (divisor >= 8192 || divisor < 0) { - baud = 9600; - divisor = (rp_baud_base[info->board] / baud) - 1; - } - info->cps = baud / bits; - sSetBaud(cp, divisor); - - /* FIXME: Should really back compute a baud rate from the divisor */ - tty_encode_baud_rate(tty, baud, baud); - - if (cflag & CRTSCTS) { - info->intmask |= DELTA_CTS; - sEnCTSFlowCtl(cp); - } else { - info->intmask &= ~DELTA_CTS; - sDisCTSFlowCtl(cp); - } - if (cflag & CLOCAL) { - info->intmask &= ~DELTA_CD; - } else { - spin_lock_irqsave(&info->slock, flags); - if (sGetChanStatus(cp) & CD_ACT) - info->cd_status = 1; - else - info->cd_status = 0; - info->intmask |= DELTA_CD; - spin_unlock_irqrestore(&info->slock, flags); - } - - /* - * Handle software flow control in the board - */ -#ifdef ROCKET_SOFT_FLOW - if (I_IXON(tty)) { - sEnTxSoftFlowCtl(cp); - if (I_IXANY(tty)) { - sEnIXANY(cp); - } else { - sDisIXANY(cp); - } - sSetTxXONChar(cp, START_CHAR(tty)); - sSetTxXOFFChar(cp, STOP_CHAR(tty)); - } else { - sDisTxSoftFlowCtl(cp); - sDisIXANY(cp); - sClrTxXOFF(cp); - } -#endif - - /* - * Set up ignore/read mask words - */ - info->read_status_mask = STMRCVROVRH | 0xFF; - if (I_INPCK(tty)) - info->read_status_mask |= STMFRAMEH | STMPARITYH; - if (I_BRKINT(tty) || I_PARMRK(tty)) - info->read_status_mask |= STMBREAKH; - - /* - * Characters to ignore - */ - info->ignore_status_mask = 0; - if (I_IGNPAR(tty)) - info->ignore_status_mask |= STMFRAMEH | STMPARITYH; - if (I_IGNBRK(tty)) { - info->ignore_status_mask |= STMBREAKH; - /* - * If we're ignoring parity and break indicators, - * ignore overruns too. (For real raw support). - */ - if (I_IGNPAR(tty)) - info->ignore_status_mask |= STMRCVROVRH; - } - - rocketMode = info->flags & ROCKET_MODE_MASK; - - if ((info->flags & ROCKET_RTS_TOGGLE) - || (rocketMode == ROCKET_MODE_RS485)) - sEnRTSToggle(cp); - else - sDisRTSToggle(cp); - - sSetRTS(&info->channel); - - if (cp->CtlP->boardType == ROCKET_TYPE_PC104) { - switch (rocketMode) { - case ROCKET_MODE_RS485: - sSetInterfaceMode(cp, InterfaceModeRS485); - break; - case ROCKET_MODE_RS422: - sSetInterfaceMode(cp, InterfaceModeRS422); - break; - case ROCKET_MODE_RS232: - default: - if (info->flags & ROCKET_RTS_TOGGLE) - sSetInterfaceMode(cp, InterfaceModeRS232T); - else - sSetInterfaceMode(cp, InterfaceModeRS232); - break; - } - } -} - -static int carrier_raised(struct tty_port *port) -{ - struct r_port *info = container_of(port, struct r_port, port); - return (sGetChanStatusLo(&info->channel) & CD_ACT) ? 1 : 0; -} - -static void dtr_rts(struct tty_port *port, int on) -{ - struct r_port *info = container_of(port, struct r_port, port); - if (on) { - sSetDTR(&info->channel); - sSetRTS(&info->channel); - } else { - sClrDTR(&info->channel); - sClrRTS(&info->channel); - } -} - -/* - * Exception handler that opens a serial port. Creates xmit_buf storage, fills in - * port's r_port struct. Initializes the port hardware. - */ -static int rp_open(struct tty_struct *tty, struct file *filp) -{ - struct r_port *info; - struct tty_port *port; - int line = 0, retval; - CHANNEL_t *cp; - unsigned long page; - - line = tty->index; - if (line < 0 || line >= MAX_RP_PORTS || ((info = rp_table[line]) == NULL)) - return -ENXIO; - port = &info->port; - - page = __get_free_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - - if (port->flags & ASYNC_CLOSING) { - retval = wait_for_completion_interruptible(&info->close_wait); - free_page(page); - if (retval) - return retval; - return ((port->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); - } - - /* - * We must not sleep from here until the port is marked fully in use. - */ - if (info->xmit_buf) - free_page(page); - else - info->xmit_buf = (unsigned char *) page; - - tty->driver_data = info; - tty_port_tty_set(port, tty); - - if (port->count++ == 0) { - atomic_inc(&rp_num_ports_open); - -#ifdef ROCKET_DEBUG_OPEN - printk(KERN_INFO "rocket mod++ = %d...\n", - atomic_read(&rp_num_ports_open)); -#endif - } -#ifdef ROCKET_DEBUG_OPEN - printk(KERN_INFO "rp_open ttyR%d, count=%d\n", info->line, info->port.count); -#endif - - /* - * Info->count is now 1; so it's safe to sleep now. - */ - if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) { - cp = &info->channel; - sSetRxTrigger(cp, TRIG_1); - if (sGetChanStatus(cp) & CD_ACT) - info->cd_status = 1; - else - info->cd_status = 0; - sDisRxStatusMode(cp); - sFlushRxFIFO(cp); - sFlushTxFIFO(cp); - - sEnInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN)); - sSetRxTrigger(cp, TRIG_1); - - sGetChanStatus(cp); - sDisRxStatusMode(cp); - sClrTxXOFF(cp); - - sDisCTSFlowCtl(cp); - sDisTxSoftFlowCtl(cp); - - sEnRxFIFO(cp); - sEnTransmit(cp); - - set_bit(ASYNCB_INITIALIZED, &info->port.flags); - - /* - * Set up the tty->alt_speed kludge - */ - if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI) - tty->alt_speed = 57600; - if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI) - tty->alt_speed = 115200; - if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI) - tty->alt_speed = 230400; - if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP) - tty->alt_speed = 460800; - - configure_r_port(tty, info, NULL); - if (tty->termios->c_cflag & CBAUD) { - sSetDTR(cp); - sSetRTS(cp); - } - } - /* Starts (or resets) the maint polling loop */ - mod_timer(&rocket_timer, jiffies + POLL_PERIOD); - - retval = tty_port_block_til_ready(port, tty, filp); - if (retval) { -#ifdef ROCKET_DEBUG_OPEN - printk(KERN_INFO "rp_open returning after block_til_ready with %d\n", retval); -#endif - return retval; - } - return 0; -} - -/* - * Exception handler that closes a serial port. info->port.count is considered critical. - */ -static void rp_close(struct tty_struct *tty, struct file *filp) -{ - struct r_port *info = tty->driver_data; - struct tty_port *port = &info->port; - int timeout; - CHANNEL_t *cp; - - if (rocket_paranoia_check(info, "rp_close")) - return; - -#ifdef ROCKET_DEBUG_OPEN - printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->port.count); -#endif - - if (tty_port_close_start(port, tty, filp) == 0) - return; - - mutex_lock(&port->mutex); - cp = &info->channel; - /* - * Before we drop DTR, make sure the UART transmitter - * has completely drained; this is especially - * important if there is a transmit FIFO! - */ - timeout = (sGetTxCnt(cp) + 1) * HZ / info->cps; - if (timeout == 0) - timeout = 1; - rp_wait_until_sent(tty, timeout); - clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); - - sDisTransmit(cp); - sDisInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN)); - sDisCTSFlowCtl(cp); - sDisTxSoftFlowCtl(cp); - sClrTxXOFF(cp); - sFlushRxFIFO(cp); - sFlushTxFIFO(cp); - sClrRTS(cp); - if (C_HUPCL(tty)) - sClrDTR(cp); - - rp_flush_buffer(tty); - - tty_ldisc_flush(tty); - - clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); - - /* We can't yet use tty_port_close_end as the buffer handling in this - driver is a bit different to the usual */ - - if (port->blocked_open) { - if (port->close_delay) { - msleep_interruptible(jiffies_to_msecs(port->close_delay)); - } - wake_up_interruptible(&port->open_wait); - } else { - if (info->xmit_buf) { - free_page((unsigned long) info->xmit_buf); - info->xmit_buf = NULL; - } - } - spin_lock_irq(&port->lock); - info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING | ASYNC_NORMAL_ACTIVE); - tty->closing = 0; - spin_unlock_irq(&port->lock); - mutex_unlock(&port->mutex); - tty_port_tty_set(port, NULL); - - wake_up_interruptible(&port->close_wait); - complete_all(&info->close_wait); - atomic_dec(&rp_num_ports_open); - -#ifdef ROCKET_DEBUG_OPEN - printk(KERN_INFO "rocket mod-- = %d...\n", - atomic_read(&rp_num_ports_open)); - printk(KERN_INFO "rp_close ttyR%d complete shutdown\n", info->line); -#endif - -} - -static void rp_set_termios(struct tty_struct *tty, - struct ktermios *old_termios) -{ - struct r_port *info = tty->driver_data; - CHANNEL_t *cp; - unsigned cflag; - - if (rocket_paranoia_check(info, "rp_set_termios")) - return; - - cflag = tty->termios->c_cflag; - - /* - * This driver doesn't support CS5 or CS6 - */ - if (((cflag & CSIZE) == CS5) || ((cflag & CSIZE) == CS6)) - tty->termios->c_cflag = - ((cflag & ~CSIZE) | (old_termios->c_cflag & CSIZE)); - /* Or CMSPAR */ - tty->termios->c_cflag &= ~CMSPAR; - - configure_r_port(tty, info, old_termios); - - cp = &info->channel; - - /* Handle transition to B0 status */ - if ((old_termios->c_cflag & CBAUD) && !(tty->termios->c_cflag & CBAUD)) { - sClrDTR(cp); - sClrRTS(cp); - } - - /* Handle transition away from B0 status */ - if (!(old_termios->c_cflag & CBAUD) && (tty->termios->c_cflag & CBAUD)) { - if (!tty->hw_stopped || !(tty->termios->c_cflag & CRTSCTS)) - sSetRTS(cp); - sSetDTR(cp); - } - - if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - rp_start(tty); - } -} - -static int rp_break(struct tty_struct *tty, int break_state) -{ - struct r_port *info = tty->driver_data; - unsigned long flags; - - if (rocket_paranoia_check(info, "rp_break")) - return -EINVAL; - - spin_lock_irqsave(&info->slock, flags); - if (break_state == -1) - sSendBreak(&info->channel); - else - sClrBreak(&info->channel); - spin_unlock_irqrestore(&info->slock, flags); - return 0; -} - -/* - * sGetChanRI used to be a macro in rocket_int.h. When the functionality for - * the UPCI boards was added, it was decided to make this a function because - * the macro was getting too complicated. All cases except the first one - * (UPCIRingInd) are taken directly from the original macro. - */ -static int sGetChanRI(CHANNEL_T * ChP) -{ - CONTROLLER_t *CtlP = ChP->CtlP; - int ChanNum = ChP->ChanNum; - int RingInd = 0; - - if (CtlP->UPCIRingInd) - RingInd = !(sInB(CtlP->UPCIRingInd) & sBitMapSetTbl[ChanNum]); - else if (CtlP->AltChanRingIndicator) - RingInd = sInB((ByteIO_t) (ChP->ChanStat + 8)) & DSR_ACT; - else if (CtlP->boardType == ROCKET_TYPE_PC104) - RingInd = !(sInB(CtlP->AiopIO[3]) & sBitMapSetTbl[ChanNum]); - - return RingInd; -} - -/********************************************************************************************/ -/* Here are the routines used by rp_ioctl. These are all called from exception handlers. */ - -/* - * Returns the state of the serial modem control lines. These next 2 functions - * are the way kernel versions > 2.5 handle modem control lines rather than IOCTLs. - */ -static int rp_tiocmget(struct tty_struct *tty) -{ - struct r_port *info = tty->driver_data; - unsigned int control, result, ChanStatus; - - ChanStatus = sGetChanStatusLo(&info->channel); - control = info->channel.TxControl[3]; - result = ((control & SET_RTS) ? TIOCM_RTS : 0) | - ((control & SET_DTR) ? TIOCM_DTR : 0) | - ((ChanStatus & CD_ACT) ? TIOCM_CAR : 0) | - (sGetChanRI(&info->channel) ? TIOCM_RNG : 0) | - ((ChanStatus & DSR_ACT) ? TIOCM_DSR : 0) | - ((ChanStatus & CTS_ACT) ? TIOCM_CTS : 0); - - return result; -} - -/* - * Sets the modem control lines - */ -static int rp_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct r_port *info = tty->driver_data; - - if (set & TIOCM_RTS) - info->channel.TxControl[3] |= SET_RTS; - if (set & TIOCM_DTR) - info->channel.TxControl[3] |= SET_DTR; - if (clear & TIOCM_RTS) - info->channel.TxControl[3] &= ~SET_RTS; - if (clear & TIOCM_DTR) - info->channel.TxControl[3] &= ~SET_DTR; - - out32(info->channel.IndexAddr, info->channel.TxControl); - return 0; -} - -static int get_config(struct r_port *info, struct rocket_config __user *retinfo) -{ - struct rocket_config tmp; - - if (!retinfo) - return -EFAULT; - memset(&tmp, 0, sizeof (tmp)); - mutex_lock(&info->port.mutex); - tmp.line = info->line; - tmp.flags = info->flags; - tmp.close_delay = info->port.close_delay; - tmp.closing_wait = info->port.closing_wait; - tmp.port = rcktpt_io_addr[(info->line >> 5) & 3]; - mutex_unlock(&info->port.mutex); - - if (copy_to_user(retinfo, &tmp, sizeof (*retinfo))) - return -EFAULT; - return 0; -} - -static int set_config(struct tty_struct *tty, struct r_port *info, - struct rocket_config __user *new_info) -{ - struct rocket_config new_serial; - - if (copy_from_user(&new_serial, new_info, sizeof (new_serial))) - return -EFAULT; - - mutex_lock(&info->port.mutex); - if (!capable(CAP_SYS_ADMIN)) - { - if ((new_serial.flags & ~ROCKET_USR_MASK) != (info->flags & ~ROCKET_USR_MASK)) { - mutex_unlock(&info->port.mutex); - return -EPERM; - } - info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK)); - configure_r_port(tty, info, NULL); - mutex_unlock(&info->port.mutex); - return 0; - } - - info->flags = ((info->flags & ~ROCKET_FLAGS) | (new_serial.flags & ROCKET_FLAGS)); - info->port.close_delay = new_serial.close_delay; - info->port.closing_wait = new_serial.closing_wait; - - if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI) - tty->alt_speed = 57600; - if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI) - tty->alt_speed = 115200; - if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI) - tty->alt_speed = 230400; - if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP) - tty->alt_speed = 460800; - mutex_unlock(&info->port.mutex); - - configure_r_port(tty, info, NULL); - return 0; -} - -/* - * This function fills in a rocket_ports struct with information - * about what boards/ports are in the system. This info is passed - * to user space. See setrocket.c where the info is used to create - * the /dev/ttyRx ports. - */ -static int get_ports(struct r_port *info, struct rocket_ports __user *retports) -{ - struct rocket_ports tmp; - int board; - - if (!retports) - return -EFAULT; - memset(&tmp, 0, sizeof (tmp)); - tmp.tty_major = rocket_driver->major; - - for (board = 0; board < 4; board++) { - tmp.rocketModel[board].model = rocketModel[board].model; - strcpy(tmp.rocketModel[board].modelString, rocketModel[board].modelString); - tmp.rocketModel[board].numPorts = rocketModel[board].numPorts; - tmp.rocketModel[board].loadrm2 = rocketModel[board].loadrm2; - tmp.rocketModel[board].startingPortNumber = rocketModel[board].startingPortNumber; - } - if (copy_to_user(retports, &tmp, sizeof (*retports))) - return -EFAULT; - return 0; -} - -static int reset_rm2(struct r_port *info, void __user *arg) -{ - int reset; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (copy_from_user(&reset, arg, sizeof (int))) - return -EFAULT; - if (reset) - reset = 1; - - if (rcktpt_type[info->board] != ROCKET_TYPE_MODEMII && - rcktpt_type[info->board] != ROCKET_TYPE_MODEMIII) - return -EINVAL; - - if (info->ctlp->BusType == isISA) - sModemReset(info->ctlp, info->chan, reset); - else - sPCIModemReset(info->ctlp, info->chan, reset); - - return 0; -} - -static int get_version(struct r_port *info, struct rocket_version __user *retvers) -{ - if (copy_to_user(retvers, &driver_version, sizeof (*retvers))) - return -EFAULT; - return 0; -} - -/* IOCTL call handler into the driver */ -static int rp_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct r_port *info = tty->driver_data; - void __user *argp = (void __user *)arg; - int ret = 0; - - if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl")) - return -ENXIO; - - switch (cmd) { - case RCKP_GET_STRUCT: - if (copy_to_user(argp, info, sizeof (struct r_port))) - ret = -EFAULT; - break; - case RCKP_GET_CONFIG: - ret = get_config(info, argp); - break; - case RCKP_SET_CONFIG: - ret = set_config(tty, info, argp); - break; - case RCKP_GET_PORTS: - ret = get_ports(info, argp); - break; - case RCKP_RESET_RM2: - ret = reset_rm2(info, argp); - break; - case RCKP_GET_VERSION: - ret = get_version(info, argp); - break; - default: - ret = -ENOIOCTLCMD; - } - return ret; -} - -static void rp_send_xchar(struct tty_struct *tty, char ch) -{ - struct r_port *info = tty->driver_data; - CHANNEL_t *cp; - - if (rocket_paranoia_check(info, "rp_send_xchar")) - return; - - cp = &info->channel; - if (sGetTxCnt(cp)) - sWriteTxPrioByte(cp, ch); - else - sWriteTxByte(sGetTxRxDataIO(cp), ch); -} - -static void rp_throttle(struct tty_struct *tty) -{ - struct r_port *info = tty->driver_data; - CHANNEL_t *cp; - -#ifdef ROCKET_DEBUG_THROTTLE - printk(KERN_INFO "throttle %s: %d....\n", tty->name, - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (rocket_paranoia_check(info, "rp_throttle")) - return; - - cp = &info->channel; - if (I_IXOFF(tty)) - rp_send_xchar(tty, STOP_CHAR(tty)); - - sClrRTS(&info->channel); -} - -static void rp_unthrottle(struct tty_struct *tty) -{ - struct r_port *info = tty->driver_data; - CHANNEL_t *cp; -#ifdef ROCKET_DEBUG_THROTTLE - printk(KERN_INFO "unthrottle %s: %d....\n", tty->name, - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (rocket_paranoia_check(info, "rp_throttle")) - return; - - cp = &info->channel; - if (I_IXOFF(tty)) - rp_send_xchar(tty, START_CHAR(tty)); - - sSetRTS(&info->channel); -} - -/* - * ------------------------------------------------------------ - * rp_stop() and rp_start() - * - * This routines are called before setting or resetting tty->stopped. - * They enable or disable transmitter interrupts, as necessary. - * ------------------------------------------------------------ - */ -static void rp_stop(struct tty_struct *tty) -{ - struct r_port *info = tty->driver_data; - -#ifdef ROCKET_DEBUG_FLOW - printk(KERN_INFO "stop %s: %d %d....\n", tty->name, - info->xmit_cnt, info->xmit_fifo_room); -#endif - - if (rocket_paranoia_check(info, "rp_stop")) - return; - - if (sGetTxCnt(&info->channel)) - sDisTransmit(&info->channel); -} - -static void rp_start(struct tty_struct *tty) -{ - struct r_port *info = tty->driver_data; - -#ifdef ROCKET_DEBUG_FLOW - printk(KERN_INFO "start %s: %d %d....\n", tty->name, - info->xmit_cnt, info->xmit_fifo_room); -#endif - - if (rocket_paranoia_check(info, "rp_stop")) - return; - - sEnTransmit(&info->channel); - set_bit((info->aiop * 8) + info->chan, - (void *) &xmit_flags[info->board]); -} - -/* - * rp_wait_until_sent() --- wait until the transmitter is empty - */ -static void rp_wait_until_sent(struct tty_struct *tty, int timeout) -{ - struct r_port *info = tty->driver_data; - CHANNEL_t *cp; - unsigned long orig_jiffies; - int check_time, exit_time; - int txcnt; - - if (rocket_paranoia_check(info, "rp_wait_until_sent")) - return; - - cp = &info->channel; - - orig_jiffies = jiffies; -#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT - printk(KERN_INFO "In RP_wait_until_sent(%d) (jiff=%lu)...\n", timeout, - jiffies); - printk(KERN_INFO "cps=%d...\n", info->cps); -#endif - while (1) { - txcnt = sGetTxCnt(cp); - if (!txcnt) { - if (sGetChanStatusLo(cp) & TXSHRMT) - break; - check_time = (HZ / info->cps) / 5; - } else { - check_time = HZ * txcnt / info->cps; - } - if (timeout) { - exit_time = orig_jiffies + timeout - jiffies; - if (exit_time <= 0) - break; - if (exit_time < check_time) - check_time = exit_time; - } - if (check_time == 0) - check_time = 1; -#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT - printk(KERN_INFO "txcnt = %d (jiff=%lu,check=%d)...\n", txcnt, - jiffies, check_time); -#endif - msleep_interruptible(jiffies_to_msecs(check_time)); - if (signal_pending(current)) - break; - } - __set_current_state(TASK_RUNNING); -#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT - printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies); -#endif -} - -/* - * rp_hangup() --- called by tty_hangup() when a hangup is signaled. - */ -static void rp_hangup(struct tty_struct *tty) -{ - CHANNEL_t *cp; - struct r_port *info = tty->driver_data; - unsigned long flags; - - if (rocket_paranoia_check(info, "rp_hangup")) - return; - -#if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_HANGUP)) - printk(KERN_INFO "rp_hangup of ttyR%d...\n", info->line); -#endif - rp_flush_buffer(tty); - spin_lock_irqsave(&info->port.lock, flags); - if (info->port.flags & ASYNC_CLOSING) { - spin_unlock_irqrestore(&info->port.lock, flags); - return; - } - if (info->port.count) - atomic_dec(&rp_num_ports_open); - clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); - spin_unlock_irqrestore(&info->port.lock, flags); - - tty_port_hangup(&info->port); - - cp = &info->channel; - sDisRxFIFO(cp); - sDisTransmit(cp); - sDisInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN)); - sDisCTSFlowCtl(cp); - sDisTxSoftFlowCtl(cp); - sClrTxXOFF(cp); - clear_bit(ASYNCB_INITIALIZED, &info->port.flags); - - wake_up_interruptible(&info->port.open_wait); -} - -/* - * Exception handler - write char routine. The RocketPort driver uses a - * double-buffering strategy, with the twist that if the in-memory CPU - * buffer is empty, and there's space in the transmit FIFO, the - * writing routines will write directly to transmit FIFO. - * Write buffer and counters protected by spinlocks - */ -static int rp_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct r_port *info = tty->driver_data; - CHANNEL_t *cp; - unsigned long flags; - - if (rocket_paranoia_check(info, "rp_put_char")) - return 0; - - /* - * Grab the port write mutex, locking out other processes that try to - * write to this port - */ - mutex_lock(&info->write_mtx); - -#ifdef ROCKET_DEBUG_WRITE - printk(KERN_INFO "rp_put_char %c...\n", ch); -#endif - - spin_lock_irqsave(&info->slock, flags); - cp = &info->channel; - - if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room == 0) - info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp); - - if (tty->stopped || tty->hw_stopped || info->xmit_fifo_room == 0 || info->xmit_cnt != 0) { - info->xmit_buf[info->xmit_head++] = ch; - info->xmit_head &= XMIT_BUF_SIZE - 1; - info->xmit_cnt++; - set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); - } else { - sOutB(sGetTxRxDataIO(cp), ch); - info->xmit_fifo_room--; - } - spin_unlock_irqrestore(&info->slock, flags); - mutex_unlock(&info->write_mtx); - return 1; -} - -/* - * Exception handler - write routine, called when user app writes to the device. - * A per port write mutex is used to protect from another process writing to - * this port at the same time. This other process could be running on the other CPU - * or get control of the CPU if the copy_from_user() blocks due to a page fault (swapped out). - * Spinlocks protect the info xmit members. - */ -static int rp_write(struct tty_struct *tty, - const unsigned char *buf, int count) -{ - struct r_port *info = tty->driver_data; - CHANNEL_t *cp; - const unsigned char *b; - int c, retval = 0; - unsigned long flags; - - if (count <= 0 || rocket_paranoia_check(info, "rp_write")) - return 0; - - if (mutex_lock_interruptible(&info->write_mtx)) - return -ERESTARTSYS; - -#ifdef ROCKET_DEBUG_WRITE - printk(KERN_INFO "rp_write %d chars...\n", count); -#endif - cp = &info->channel; - - if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room < count) - info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp); - - /* - * If the write queue for the port is empty, and there is FIFO space, stuff bytes - * into FIFO. Use the write queue for temp storage. - */ - if (!tty->stopped && !tty->hw_stopped && info->xmit_cnt == 0 && info->xmit_fifo_room > 0) { - c = min(count, info->xmit_fifo_room); - b = buf; - - /* Push data into FIFO, 2 bytes at a time */ - sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) b, c / 2); - - /* If there is a byte remaining, write it */ - if (c & 1) - sOutB(sGetTxRxDataIO(cp), b[c - 1]); - - retval += c; - buf += c; - count -= c; - - spin_lock_irqsave(&info->slock, flags); - info->xmit_fifo_room -= c; - spin_unlock_irqrestore(&info->slock, flags); - } - - /* If count is zero, we wrote it all and are done */ - if (!count) - goto end; - - /* Write remaining data into the port's xmit_buf */ - while (1) { - /* Hung up ? */ - if (!test_bit(ASYNCB_NORMAL_ACTIVE, &info->port.flags)) - goto end; - c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1); - c = min(c, XMIT_BUF_SIZE - info->xmit_head); - if (c <= 0) - break; - - b = buf; - memcpy(info->xmit_buf + info->xmit_head, b, c); - - spin_lock_irqsave(&info->slock, flags); - info->xmit_head = - (info->xmit_head + c) & (XMIT_BUF_SIZE - 1); - info->xmit_cnt += c; - spin_unlock_irqrestore(&info->slock, flags); - - buf += c; - count -= c; - retval += c; - } - - if ((retval > 0) && !tty->stopped && !tty->hw_stopped) - set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); - -end: - if (info->xmit_cnt < WAKEUP_CHARS) { - tty_wakeup(tty); -#ifdef ROCKETPORT_HAVE_POLL_WAIT - wake_up_interruptible(&tty->poll_wait); -#endif - } - mutex_unlock(&info->write_mtx); - return retval; -} - -/* - * Return the number of characters that can be sent. We estimate - * only using the in-memory transmit buffer only, and ignore the - * potential space in the transmit FIFO. - */ -static int rp_write_room(struct tty_struct *tty) -{ - struct r_port *info = tty->driver_data; - int ret; - - if (rocket_paranoia_check(info, "rp_write_room")) - return 0; - - ret = XMIT_BUF_SIZE - info->xmit_cnt - 1; - if (ret < 0) - ret = 0; -#ifdef ROCKET_DEBUG_WRITE - printk(KERN_INFO "rp_write_room returns %d...\n", ret); -#endif - return ret; -} - -/* - * Return the number of characters in the buffer. Again, this only - * counts those characters in the in-memory transmit buffer. - */ -static int rp_chars_in_buffer(struct tty_struct *tty) -{ - struct r_port *info = tty->driver_data; - CHANNEL_t *cp; - - if (rocket_paranoia_check(info, "rp_chars_in_buffer")) - return 0; - - cp = &info->channel; - -#ifdef ROCKET_DEBUG_WRITE - printk(KERN_INFO "rp_chars_in_buffer returns %d...\n", info->xmit_cnt); -#endif - return info->xmit_cnt; -} - -/* - * Flushes the TX fifo for a port, deletes data in the xmit_buf stored in the - * r_port struct for the port. Note that spinlock are used to protect info members, - * do not call this function if the spinlock is already held. - */ -static void rp_flush_buffer(struct tty_struct *tty) -{ - struct r_port *info = tty->driver_data; - CHANNEL_t *cp; - unsigned long flags; - - if (rocket_paranoia_check(info, "rp_flush_buffer")) - return; - - spin_lock_irqsave(&info->slock, flags); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - spin_unlock_irqrestore(&info->slock, flags); - -#ifdef ROCKETPORT_HAVE_POLL_WAIT - wake_up_interruptible(&tty->poll_wait); -#endif - tty_wakeup(tty); - - cp = &info->channel; - sFlushTxFIFO(cp); -} - -#ifdef CONFIG_PCI - -static struct pci_device_id __devinitdata __used rocket_pci_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_ANY_ID) }, - { } -}; -MODULE_DEVICE_TABLE(pci, rocket_pci_ids); - -/* - * Called when a PCI card is found. Retrieves and stores model information, - * init's aiopic and serial port hardware. - * Inputs: i is the board number (0-n) - */ -static __init int register_PCI(int i, struct pci_dev *dev) -{ - int num_aiops, aiop, max_num_aiops, num_chan, chan; - unsigned int aiopio[MAX_AIOPS_PER_BOARD]; - char *str, *board_type; - CONTROLLER_t *ctlp; - - int fast_clock = 0; - int altChanRingIndicator = 0; - int ports_per_aiop = 8; - WordIO_t ConfigIO = 0; - ByteIO_t UPCIRingInd = 0; - - if (!dev || pci_enable_device(dev)) - return 0; - - rcktpt_io_addr[i] = pci_resource_start(dev, 0); - - rcktpt_type[i] = ROCKET_TYPE_NORMAL; - rocketModel[i].loadrm2 = 0; - rocketModel[i].startingPortNumber = nextLineNumber; - - /* Depending on the model, set up some config variables */ - switch (dev->device) { - case PCI_DEVICE_ID_RP4QUAD: - str = "Quadcable"; - max_num_aiops = 1; - ports_per_aiop = 4; - rocketModel[i].model = MODEL_RP4QUAD; - strcpy(rocketModel[i].modelString, "RocketPort 4 port w/quad cable"); - rocketModel[i].numPorts = 4; - break; - case PCI_DEVICE_ID_RP8OCTA: - str = "Octacable"; - max_num_aiops = 1; - rocketModel[i].model = MODEL_RP8OCTA; - strcpy(rocketModel[i].modelString, "RocketPort 8 port w/octa cable"); - rocketModel[i].numPorts = 8; - break; - case PCI_DEVICE_ID_URP8OCTA: - str = "Octacable"; - max_num_aiops = 1; - rocketModel[i].model = MODEL_UPCI_RP8OCTA; - strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/octa cable"); - rocketModel[i].numPorts = 8; - break; - case PCI_DEVICE_ID_RP8INTF: - str = "8"; - max_num_aiops = 1; - rocketModel[i].model = MODEL_RP8INTF; - strcpy(rocketModel[i].modelString, "RocketPort 8 port w/external I/F"); - rocketModel[i].numPorts = 8; - break; - case PCI_DEVICE_ID_URP8INTF: - str = "8"; - max_num_aiops = 1; - rocketModel[i].model = MODEL_UPCI_RP8INTF; - strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/external I/F"); - rocketModel[i].numPorts = 8; - break; - case PCI_DEVICE_ID_RP8J: - str = "8J"; - max_num_aiops = 1; - rocketModel[i].model = MODEL_RP8J; - strcpy(rocketModel[i].modelString, "RocketPort 8 port w/RJ11 connectors"); - rocketModel[i].numPorts = 8; - break; - case PCI_DEVICE_ID_RP4J: - str = "4J"; - max_num_aiops = 1; - ports_per_aiop = 4; - rocketModel[i].model = MODEL_RP4J; - strcpy(rocketModel[i].modelString, "RocketPort 4 port w/RJ45 connectors"); - rocketModel[i].numPorts = 4; - break; - case PCI_DEVICE_ID_RP8SNI: - str = "8 (DB78 Custom)"; - max_num_aiops = 1; - rocketModel[i].model = MODEL_RP8SNI; - strcpy(rocketModel[i].modelString, "RocketPort 8 port w/ custom DB78"); - rocketModel[i].numPorts = 8; - break; - case PCI_DEVICE_ID_RP16SNI: - str = "16 (DB78 Custom)"; - max_num_aiops = 2; - rocketModel[i].model = MODEL_RP16SNI; - strcpy(rocketModel[i].modelString, "RocketPort 16 port w/ custom DB78"); - rocketModel[i].numPorts = 16; - break; - case PCI_DEVICE_ID_RP16INTF: - str = "16"; - max_num_aiops = 2; - rocketModel[i].model = MODEL_RP16INTF; - strcpy(rocketModel[i].modelString, "RocketPort 16 port w/external I/F"); - rocketModel[i].numPorts = 16; - break; - case PCI_DEVICE_ID_URP16INTF: - str = "16"; - max_num_aiops = 2; - rocketModel[i].model = MODEL_UPCI_RP16INTF; - strcpy(rocketModel[i].modelString, "RocketPort UPCI 16 port w/external I/F"); - rocketModel[i].numPorts = 16; - break; - case PCI_DEVICE_ID_CRP16INTF: - str = "16"; - max_num_aiops = 2; - rocketModel[i].model = MODEL_CPCI_RP16INTF; - strcpy(rocketModel[i].modelString, "RocketPort Compact PCI 16 port w/external I/F"); - rocketModel[i].numPorts = 16; - break; - case PCI_DEVICE_ID_RP32INTF: - str = "32"; - max_num_aiops = 4; - rocketModel[i].model = MODEL_RP32INTF; - strcpy(rocketModel[i].modelString, "RocketPort 32 port w/external I/F"); - rocketModel[i].numPorts = 32; - break; - case PCI_DEVICE_ID_URP32INTF: - str = "32"; - max_num_aiops = 4; - rocketModel[i].model = MODEL_UPCI_RP32INTF; - strcpy(rocketModel[i].modelString, "RocketPort UPCI 32 port w/external I/F"); - rocketModel[i].numPorts = 32; - break; - case PCI_DEVICE_ID_RPP4: - str = "Plus Quadcable"; - max_num_aiops = 1; - ports_per_aiop = 4; - altChanRingIndicator++; - fast_clock++; - rocketModel[i].model = MODEL_RPP4; - strcpy(rocketModel[i].modelString, "RocketPort Plus 4 port"); - rocketModel[i].numPorts = 4; - break; - case PCI_DEVICE_ID_RPP8: - str = "Plus Octacable"; - max_num_aiops = 2; - ports_per_aiop = 4; - altChanRingIndicator++; - fast_clock++; - rocketModel[i].model = MODEL_RPP8; - strcpy(rocketModel[i].modelString, "RocketPort Plus 8 port"); - rocketModel[i].numPorts = 8; - break; - case PCI_DEVICE_ID_RP2_232: - str = "Plus 2 (RS-232)"; - max_num_aiops = 1; - ports_per_aiop = 2; - altChanRingIndicator++; - fast_clock++; - rocketModel[i].model = MODEL_RP2_232; - strcpy(rocketModel[i].modelString, "RocketPort Plus 2 port RS232"); - rocketModel[i].numPorts = 2; - break; - case PCI_DEVICE_ID_RP2_422: - str = "Plus 2 (RS-422)"; - max_num_aiops = 1; - ports_per_aiop = 2; - altChanRingIndicator++; - fast_clock++; - rocketModel[i].model = MODEL_RP2_422; - strcpy(rocketModel[i].modelString, "RocketPort Plus 2 port RS422"); - rocketModel[i].numPorts = 2; - break; - case PCI_DEVICE_ID_RP6M: - - max_num_aiops = 1; - ports_per_aiop = 6; - str = "6-port"; - - /* If revision is 1, the rocketmodem flash must be loaded. - * If it is 2 it is a "socketed" version. */ - if (dev->revision == 1) { - rcktpt_type[i] = ROCKET_TYPE_MODEMII; - rocketModel[i].loadrm2 = 1; - } else { - rcktpt_type[i] = ROCKET_TYPE_MODEM; - } - - rocketModel[i].model = MODEL_RP6M; - strcpy(rocketModel[i].modelString, "RocketModem 6 port"); - rocketModel[i].numPorts = 6; - break; - case PCI_DEVICE_ID_RP4M: - max_num_aiops = 1; - ports_per_aiop = 4; - str = "4-port"; - if (dev->revision == 1) { - rcktpt_type[i] = ROCKET_TYPE_MODEMII; - rocketModel[i].loadrm2 = 1; - } else { - rcktpt_type[i] = ROCKET_TYPE_MODEM; - } - - rocketModel[i].model = MODEL_RP4M; - strcpy(rocketModel[i].modelString, "RocketModem 4 port"); - rocketModel[i].numPorts = 4; - break; - default: - str = "(unknown/unsupported)"; - max_num_aiops = 0; - break; - } - - /* - * Check for UPCI boards. - */ - - switch (dev->device) { - case PCI_DEVICE_ID_URP32INTF: - case PCI_DEVICE_ID_URP8INTF: - case PCI_DEVICE_ID_URP16INTF: - case PCI_DEVICE_ID_CRP16INTF: - case PCI_DEVICE_ID_URP8OCTA: - rcktpt_io_addr[i] = pci_resource_start(dev, 2); - ConfigIO = pci_resource_start(dev, 1); - if (dev->device == PCI_DEVICE_ID_URP8OCTA) { - UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND; - - /* - * Check for octa or quad cable. - */ - if (! - (sInW(ConfigIO + _PCI_9030_GPIO_CTRL) & - PCI_GPIO_CTRL_8PORT)) { - str = "Quadcable"; - ports_per_aiop = 4; - rocketModel[i].numPorts = 4; - } - } - break; - case PCI_DEVICE_ID_UPCI_RM3_8PORT: - str = "8 ports"; - max_num_aiops = 1; - rocketModel[i].model = MODEL_UPCI_RM3_8PORT; - strcpy(rocketModel[i].modelString, "RocketModem III 8 port"); - rocketModel[i].numPorts = 8; - rcktpt_io_addr[i] = pci_resource_start(dev, 2); - UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND; - ConfigIO = pci_resource_start(dev, 1); - rcktpt_type[i] = ROCKET_TYPE_MODEMIII; - break; - case PCI_DEVICE_ID_UPCI_RM3_4PORT: - str = "4 ports"; - max_num_aiops = 1; - rocketModel[i].model = MODEL_UPCI_RM3_4PORT; - strcpy(rocketModel[i].modelString, "RocketModem III 4 port"); - rocketModel[i].numPorts = 4; - rcktpt_io_addr[i] = pci_resource_start(dev, 2); - UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND; - ConfigIO = pci_resource_start(dev, 1); - rcktpt_type[i] = ROCKET_TYPE_MODEMIII; - break; - default: - break; - } - - switch (rcktpt_type[i]) { - case ROCKET_TYPE_MODEM: - board_type = "RocketModem"; - break; - case ROCKET_TYPE_MODEMII: - board_type = "RocketModem II"; - break; - case ROCKET_TYPE_MODEMIII: - board_type = "RocketModem III"; - break; - default: - board_type = "RocketPort"; - break; - } - - if (fast_clock) { - sClockPrescale = 0x12; /* mod 2 (divide by 3) */ - rp_baud_base[i] = 921600; - } else { - /* - * If support_low_speed is set, use the slow clock - * prescale, which supports 50 bps - */ - if (support_low_speed) { - /* mod 9 (divide by 10) prescale */ - sClockPrescale = 0x19; - rp_baud_base[i] = 230400; - } else { - /* mod 4 (devide by 5) prescale */ - sClockPrescale = 0x14; - rp_baud_base[i] = 460800; - } - } - - for (aiop = 0; aiop < max_num_aiops; aiop++) - aiopio[aiop] = rcktpt_io_addr[i] + (aiop * 0x40); - ctlp = sCtlNumToCtlPtr(i); - num_aiops = sPCIInitController(ctlp, i, aiopio, max_num_aiops, ConfigIO, 0, FREQ_DIS, 0, altChanRingIndicator, UPCIRingInd); - for (aiop = 0; aiop < max_num_aiops; aiop++) - ctlp->AiopNumChan[aiop] = ports_per_aiop; - - dev_info(&dev->dev, "comtrol PCI controller #%d found at " - "address %04lx, %d AIOP(s) (%s), creating ttyR%d - %ld\n", - i, rcktpt_io_addr[i], num_aiops, rocketModel[i].modelString, - rocketModel[i].startingPortNumber, - rocketModel[i].startingPortNumber + rocketModel[i].numPorts-1); - - if (num_aiops <= 0) { - rcktpt_io_addr[i] = 0; - return (0); - } - is_PCI[i] = 1; - - /* Reset the AIOPIC, init the serial ports */ - for (aiop = 0; aiop < num_aiops; aiop++) { - sResetAiopByNum(ctlp, aiop); - num_chan = ports_per_aiop; - for (chan = 0; chan < num_chan; chan++) - init_r_port(i, aiop, chan, dev); - } - - /* Rocket modems must be reset */ - if ((rcktpt_type[i] == ROCKET_TYPE_MODEM) || - (rcktpt_type[i] == ROCKET_TYPE_MODEMII) || - (rcktpt_type[i] == ROCKET_TYPE_MODEMIII)) { - num_chan = ports_per_aiop; - for (chan = 0; chan < num_chan; chan++) - sPCIModemReset(ctlp, chan, 1); - msleep(500); - for (chan = 0; chan < num_chan; chan++) - sPCIModemReset(ctlp, chan, 0); - msleep(500); - rmSpeakerReset(ctlp, rocketModel[i].model); - } - return (1); -} - -/* - * Probes for PCI cards, inits them if found - * Input: board_found = number of ISA boards already found, or the - * starting board number - * Returns: Number of PCI boards found - */ -static int __init init_PCI(int boards_found) -{ - struct pci_dev *dev = NULL; - int count = 0; - - /* Work through the PCI device list, pulling out ours */ - while ((dev = pci_get_device(PCI_VENDOR_ID_RP, PCI_ANY_ID, dev))) { - if (register_PCI(count + boards_found, dev)) - count++; - } - return (count); -} - -#endif /* CONFIG_PCI */ - -/* - * Probes for ISA cards - * Input: i = the board number to look for - * Returns: 1 if board found, 0 else - */ -static int __init init_ISA(int i) -{ - int num_aiops, num_chan = 0, total_num_chan = 0; - int aiop, chan; - unsigned int aiopio[MAX_AIOPS_PER_BOARD]; - CONTROLLER_t *ctlp; - char *type_string; - - /* If io_addr is zero, no board configured */ - if (rcktpt_io_addr[i] == 0) - return (0); - - /* Reserve the IO region */ - if (!request_region(rcktpt_io_addr[i], 64, "Comtrol RocketPort")) { - printk(KERN_ERR "Unable to reserve IO region for configured " - "ISA RocketPort at address 0x%lx, board not " - "installed...\n", rcktpt_io_addr[i]); - rcktpt_io_addr[i] = 0; - return (0); - } - - ctlp = sCtlNumToCtlPtr(i); - - ctlp->boardType = rcktpt_type[i]; - - switch (rcktpt_type[i]) { - case ROCKET_TYPE_PC104: - type_string = "(PC104)"; - break; - case ROCKET_TYPE_MODEM: - type_string = "(RocketModem)"; - break; - case ROCKET_TYPE_MODEMII: - type_string = "(RocketModem II)"; - break; - default: - type_string = ""; - break; - } - - /* - * If support_low_speed is set, use the slow clock prescale, - * which supports 50 bps - */ - if (support_low_speed) { - sClockPrescale = 0x19; /* mod 9 (divide by 10) prescale */ - rp_baud_base[i] = 230400; - } else { - sClockPrescale = 0x14; /* mod 4 (devide by 5) prescale */ - rp_baud_base[i] = 460800; - } - - for (aiop = 0; aiop < MAX_AIOPS_PER_BOARD; aiop++) - aiopio[aiop] = rcktpt_io_addr[i] + (aiop * 0x400); - - num_aiops = sInitController(ctlp, i, controller + (i * 0x400), aiopio, MAX_AIOPS_PER_BOARD, 0, FREQ_DIS, 0); - - if (ctlp->boardType == ROCKET_TYPE_PC104) { - sEnAiop(ctlp, 2); /* only one AIOPIC, but these */ - sEnAiop(ctlp, 3); /* CSels used for other stuff */ - } - - /* If something went wrong initing the AIOP's release the ISA IO memory */ - if (num_aiops <= 0) { - release_region(rcktpt_io_addr[i], 64); - rcktpt_io_addr[i] = 0; - return (0); - } - - rocketModel[i].startingPortNumber = nextLineNumber; - - for (aiop = 0; aiop < num_aiops; aiop++) { - sResetAiopByNum(ctlp, aiop); - sEnAiop(ctlp, aiop); - num_chan = sGetAiopNumChan(ctlp, aiop); - total_num_chan += num_chan; - for (chan = 0; chan < num_chan; chan++) - init_r_port(i, aiop, chan, NULL); - } - is_PCI[i] = 0; - if ((rcktpt_type[i] == ROCKET_TYPE_MODEM) || (rcktpt_type[i] == ROCKET_TYPE_MODEMII)) { - num_chan = sGetAiopNumChan(ctlp, 0); - total_num_chan = num_chan; - for (chan = 0; chan < num_chan; chan++) - sModemReset(ctlp, chan, 1); - msleep(500); - for (chan = 0; chan < num_chan; chan++) - sModemReset(ctlp, chan, 0); - msleep(500); - strcpy(rocketModel[i].modelString, "RocketModem ISA"); - } else { - strcpy(rocketModel[i].modelString, "RocketPort ISA"); - } - rocketModel[i].numPorts = total_num_chan; - rocketModel[i].model = MODEL_ISA; - - printk(KERN_INFO "RocketPort ISA card #%d found at 0x%lx - %d AIOPs %s\n", - i, rcktpt_io_addr[i], num_aiops, type_string); - - printk(KERN_INFO "Installing %s, creating /dev/ttyR%d - %ld\n", - rocketModel[i].modelString, - rocketModel[i].startingPortNumber, - rocketModel[i].startingPortNumber + - rocketModel[i].numPorts - 1); - - return (1); -} - -static const struct tty_operations rocket_ops = { - .open = rp_open, - .close = rp_close, - .write = rp_write, - .put_char = rp_put_char, - .write_room = rp_write_room, - .chars_in_buffer = rp_chars_in_buffer, - .flush_buffer = rp_flush_buffer, - .ioctl = rp_ioctl, - .throttle = rp_throttle, - .unthrottle = rp_unthrottle, - .set_termios = rp_set_termios, - .stop = rp_stop, - .start = rp_start, - .hangup = rp_hangup, - .break_ctl = rp_break, - .send_xchar = rp_send_xchar, - .wait_until_sent = rp_wait_until_sent, - .tiocmget = rp_tiocmget, - .tiocmset = rp_tiocmset, -}; - -static const struct tty_port_operations rocket_port_ops = { - .carrier_raised = carrier_raised, - .dtr_rts = dtr_rts, -}; - -/* - * The module "startup" routine; it's run when the module is loaded. - */ -static int __init rp_init(void) -{ - int ret = -ENOMEM, pci_boards_found, isa_boards_found, i; - - printk(KERN_INFO "RocketPort device driver module, version %s, %s\n", - ROCKET_VERSION, ROCKET_DATE); - - rocket_driver = alloc_tty_driver(MAX_RP_PORTS); - if (!rocket_driver) - goto err; - - /* - * If board 1 is non-zero, there is at least one ISA configured. If controller is - * zero, use the default controller IO address of board1 + 0x40. - */ - if (board1) { - if (controller == 0) - controller = board1 + 0x40; - } else { - controller = 0; /* Used as a flag, meaning no ISA boards */ - } - - /* If an ISA card is configured, reserve the 4 byte IO space for the Mudbac controller */ - if (controller && (!request_region(controller, 4, "Comtrol RocketPort"))) { - printk(KERN_ERR "Unable to reserve IO region for first " - "configured ISA RocketPort controller 0x%lx. " - "Driver exiting\n", controller); - ret = -EBUSY; - goto err_tty; - } - - /* Store ISA variable retrieved from command line or .conf file. */ - rcktpt_io_addr[0] = board1; - rcktpt_io_addr[1] = board2; - rcktpt_io_addr[2] = board3; - rcktpt_io_addr[3] = board4; - - rcktpt_type[0] = modem1 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL; - rcktpt_type[0] = pc104_1[0] ? ROCKET_TYPE_PC104 : rcktpt_type[0]; - rcktpt_type[1] = modem2 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL; - rcktpt_type[1] = pc104_2[0] ? ROCKET_TYPE_PC104 : rcktpt_type[1]; - rcktpt_type[2] = modem3 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL; - rcktpt_type[2] = pc104_3[0] ? ROCKET_TYPE_PC104 : rcktpt_type[2]; - rcktpt_type[3] = modem4 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL; - rcktpt_type[3] = pc104_4[0] ? ROCKET_TYPE_PC104 : rcktpt_type[3]; - - /* - * Set up the tty driver structure and then register this - * driver with the tty layer. - */ - - rocket_driver->owner = THIS_MODULE; - rocket_driver->flags = TTY_DRIVER_DYNAMIC_DEV; - rocket_driver->name = "ttyR"; - rocket_driver->driver_name = "Comtrol RocketPort"; - rocket_driver->major = TTY_ROCKET_MAJOR; - rocket_driver->minor_start = 0; - rocket_driver->type = TTY_DRIVER_TYPE_SERIAL; - rocket_driver->subtype = SERIAL_TYPE_NORMAL; - rocket_driver->init_termios = tty_std_termios; - rocket_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - rocket_driver->init_termios.c_ispeed = 9600; - rocket_driver->init_termios.c_ospeed = 9600; -#ifdef ROCKET_SOFT_FLOW - rocket_driver->flags |= TTY_DRIVER_REAL_RAW; -#endif - tty_set_operations(rocket_driver, &rocket_ops); - - ret = tty_register_driver(rocket_driver); - if (ret < 0) { - printk(KERN_ERR "Couldn't install tty RocketPort driver\n"); - goto err_controller; - } - -#ifdef ROCKET_DEBUG_OPEN - printk(KERN_INFO "RocketPort driver is major %d\n", rocket_driver.major); -#endif - - /* - * OK, let's probe each of the controllers looking for boards. Any boards found - * will be initialized here. - */ - isa_boards_found = 0; - pci_boards_found = 0; - - for (i = 0; i < NUM_BOARDS; i++) { - if (init_ISA(i)) - isa_boards_found++; - } - -#ifdef CONFIG_PCI - if (isa_boards_found < NUM_BOARDS) - pci_boards_found = init_PCI(isa_boards_found); -#endif - - max_board = pci_boards_found + isa_boards_found; - - if (max_board == 0) { - printk(KERN_ERR "No rocketport ports found; unloading driver\n"); - ret = -ENXIO; - goto err_ttyu; - } - - return 0; -err_ttyu: - tty_unregister_driver(rocket_driver); -err_controller: - if (controller) - release_region(controller, 4); -err_tty: - put_tty_driver(rocket_driver); -err: - return ret; -} - - -static void rp_cleanup_module(void) -{ - int retval; - int i; - - del_timer_sync(&rocket_timer); - - retval = tty_unregister_driver(rocket_driver); - if (retval) - printk(KERN_ERR "Error %d while trying to unregister " - "rocketport driver\n", -retval); - - for (i = 0; i < MAX_RP_PORTS; i++) - if (rp_table[i]) { - tty_unregister_device(rocket_driver, i); - kfree(rp_table[i]); - } - - put_tty_driver(rocket_driver); - - for (i = 0; i < NUM_BOARDS; i++) { - if (rcktpt_io_addr[i] <= 0 || is_PCI[i]) - continue; - release_region(rcktpt_io_addr[i], 64); - } - if (controller) - release_region(controller, 4); -} - -/*************************************************************************** -Function: sInitController -Purpose: Initialization of controller global registers and controller - structure. -Call: sInitController(CtlP,CtlNum,MudbacIO,AiopIOList,AiopIOListSize, - IRQNum,Frequency,PeriodicOnly) - CONTROLLER_T *CtlP; Ptr to controller structure - int CtlNum; Controller number - ByteIO_t MudbacIO; Mudbac base I/O address. - ByteIO_t *AiopIOList; List of I/O addresses for each AIOP. - This list must be in the order the AIOPs will be found on the - controller. Once an AIOP in the list is not found, it is - assumed that there are no more AIOPs on the controller. - int AiopIOListSize; Number of addresses in AiopIOList - int IRQNum; Interrupt Request number. Can be any of the following: - 0: Disable global interrupts - 3: IRQ 3 - 4: IRQ 4 - 5: IRQ 5 - 9: IRQ 9 - 10: IRQ 10 - 11: IRQ 11 - 12: IRQ 12 - 15: IRQ 15 - Byte_t Frequency: A flag identifying the frequency - of the periodic interrupt, can be any one of the following: - FREQ_DIS - periodic interrupt disabled - FREQ_137HZ - 137 Hertz - FREQ_69HZ - 69 Hertz - FREQ_34HZ - 34 Hertz - FREQ_17HZ - 17 Hertz - FREQ_9HZ - 9 Hertz - FREQ_4HZ - 4 Hertz - If IRQNum is set to 0 the Frequency parameter is - overidden, it is forced to a value of FREQ_DIS. - int PeriodicOnly: 1 if all interrupts except the periodic - interrupt are to be blocked. - 0 is both the periodic interrupt and - other channel interrupts are allowed. - If IRQNum is set to 0 the PeriodicOnly parameter is - overidden, it is forced to a value of 0. -Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller - initialization failed. - -Comments: - If periodic interrupts are to be disabled but AIOP interrupts - are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0. - - If interrupts are to be completely disabled set IRQNum to 0. - - Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an - invalid combination. - - This function performs initialization of global interrupt modes, - but it does not actually enable global interrupts. To enable - and disable global interrupts use functions sEnGlobalInt() and - sDisGlobalInt(). Enabling of global interrupts is normally not - done until all other initializations are complete. - - Even if interrupts are globally enabled, they must also be - individually enabled for each channel that is to generate - interrupts. - -Warnings: No range checking on any of the parameters is done. - - No context switches are allowed while executing this function. - - After this function all AIOPs on the controller are disabled, - they can be enabled with sEnAiop(). -*/ -static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, - ByteIO_t * AiopIOList, int AiopIOListSize, - int IRQNum, Byte_t Frequency, int PeriodicOnly) -{ - int i; - ByteIO_t io; - int done; - - CtlP->AiopIntrBits = aiop_intr_bits; - CtlP->AltChanRingIndicator = 0; - CtlP->CtlNum = CtlNum; - CtlP->CtlID = CTLID_0001; /* controller release 1 */ - CtlP->BusType = isISA; - CtlP->MBaseIO = MudbacIO; - CtlP->MReg1IO = MudbacIO + 1; - CtlP->MReg2IO = MudbacIO + 2; - CtlP->MReg3IO = MudbacIO + 3; -#if 1 - CtlP->MReg2 = 0; /* interrupt disable */ - CtlP->MReg3 = 0; /* no periodic interrupts */ -#else - if (sIRQMap[IRQNum] == 0) { /* interrupts globally disabled */ - CtlP->MReg2 = 0; /* interrupt disable */ - CtlP->MReg3 = 0; /* no periodic interrupts */ - } else { - CtlP->MReg2 = sIRQMap[IRQNum]; /* set IRQ number */ - CtlP->MReg3 = Frequency; /* set frequency */ - if (PeriodicOnly) { /* periodic interrupt only */ - CtlP->MReg3 |= PERIODIC_ONLY; - } - } -#endif - sOutB(CtlP->MReg2IO, CtlP->MReg2); - sOutB(CtlP->MReg3IO, CtlP->MReg3); - sControllerEOI(CtlP); /* clear EOI if warm init */ - /* Init AIOPs */ - CtlP->NumAiop = 0; - for (i = done = 0; i < AiopIOListSize; i++) { - io = AiopIOList[i]; - CtlP->AiopIO[i] = (WordIO_t) io; - CtlP->AiopIntChanIO[i] = io + _INT_CHAN; - sOutB(CtlP->MReg2IO, CtlP->MReg2 | (i & 0x03)); /* AIOP index */ - sOutB(MudbacIO, (Byte_t) (io >> 6)); /* set up AIOP I/O in MUDBAC */ - if (done) - continue; - sEnAiop(CtlP, i); /* enable the AIOP */ - CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */ - if (CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */ - done = 1; /* done looking for AIOPs */ - else { - CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */ - sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE); /* clock prescaler */ - sOutB(io + _INDX_DATA, sClockPrescale); - CtlP->NumAiop++; /* bump count of AIOPs */ - } - sDisAiop(CtlP, i); /* disable AIOP */ - } - - if (CtlP->NumAiop == 0) - return (-1); - else - return (CtlP->NumAiop); -} - -/*************************************************************************** -Function: sPCIInitController -Purpose: Initialization of controller global registers and controller - structure. -Call: sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize, - IRQNum,Frequency,PeriodicOnly) - CONTROLLER_T *CtlP; Ptr to controller structure - int CtlNum; Controller number - ByteIO_t *AiopIOList; List of I/O addresses for each AIOP. - This list must be in the order the AIOPs will be found on the - controller. Once an AIOP in the list is not found, it is - assumed that there are no more AIOPs on the controller. - int AiopIOListSize; Number of addresses in AiopIOList - int IRQNum; Interrupt Request number. Can be any of the following: - 0: Disable global interrupts - 3: IRQ 3 - 4: IRQ 4 - 5: IRQ 5 - 9: IRQ 9 - 10: IRQ 10 - 11: IRQ 11 - 12: IRQ 12 - 15: IRQ 15 - Byte_t Frequency: A flag identifying the frequency - of the periodic interrupt, can be any one of the following: - FREQ_DIS - periodic interrupt disabled - FREQ_137HZ - 137 Hertz - FREQ_69HZ - 69 Hertz - FREQ_34HZ - 34 Hertz - FREQ_17HZ - 17 Hertz - FREQ_9HZ - 9 Hertz - FREQ_4HZ - 4 Hertz - If IRQNum is set to 0 the Frequency parameter is - overidden, it is forced to a value of FREQ_DIS. - int PeriodicOnly: 1 if all interrupts except the periodic - interrupt are to be blocked. - 0 is both the periodic interrupt and - other channel interrupts are allowed. - If IRQNum is set to 0 the PeriodicOnly parameter is - overidden, it is forced to a value of 0. -Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller - initialization failed. - -Comments: - If periodic interrupts are to be disabled but AIOP interrupts - are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0. - - If interrupts are to be completely disabled set IRQNum to 0. - - Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an - invalid combination. - - This function performs initialization of global interrupt modes, - but it does not actually enable global interrupts. To enable - and disable global interrupts use functions sEnGlobalInt() and - sDisGlobalInt(). Enabling of global interrupts is normally not - done until all other initializations are complete. - - Even if interrupts are globally enabled, they must also be - individually enabled for each channel that is to generate - interrupts. - -Warnings: No range checking on any of the parameters is done. - - No context switches are allowed while executing this function. - - After this function all AIOPs on the controller are disabled, - they can be enabled with sEnAiop(). -*/ -static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, - ByteIO_t * AiopIOList, int AiopIOListSize, - WordIO_t ConfigIO, int IRQNum, Byte_t Frequency, - int PeriodicOnly, int altChanRingIndicator, - int UPCIRingInd) -{ - int i; - ByteIO_t io; - - CtlP->AltChanRingIndicator = altChanRingIndicator; - CtlP->UPCIRingInd = UPCIRingInd; - CtlP->CtlNum = CtlNum; - CtlP->CtlID = CTLID_0001; /* controller release 1 */ - CtlP->BusType = isPCI; /* controller release 1 */ - - if (ConfigIO) { - CtlP->isUPCI = 1; - CtlP->PCIIO = ConfigIO + _PCI_9030_INT_CTRL; - CtlP->PCIIO2 = ConfigIO + _PCI_9030_GPIO_CTRL; - CtlP->AiopIntrBits = upci_aiop_intr_bits; - } else { - CtlP->isUPCI = 0; - CtlP->PCIIO = - (WordIO_t) ((ByteIO_t) AiopIOList[0] + _PCI_INT_FUNC); - CtlP->AiopIntrBits = aiop_intr_bits; - } - - sPCIControllerEOI(CtlP); /* clear EOI if warm init */ - /* Init AIOPs */ - CtlP->NumAiop = 0; - for (i = 0; i < AiopIOListSize; i++) { - io = AiopIOList[i]; - CtlP->AiopIO[i] = (WordIO_t) io; - CtlP->AiopIntChanIO[i] = io + _INT_CHAN; - - CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */ - if (CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */ - break; /* done looking for AIOPs */ - - CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */ - sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE); /* clock prescaler */ - sOutB(io + _INDX_DATA, sClockPrescale); - CtlP->NumAiop++; /* bump count of AIOPs */ - } - - if (CtlP->NumAiop == 0) - return (-1); - else - return (CtlP->NumAiop); -} - -/*************************************************************************** -Function: sReadAiopID -Purpose: Read the AIOP idenfication number directly from an AIOP. -Call: sReadAiopID(io) - ByteIO_t io: AIOP base I/O address -Return: int: Flag AIOPID_XXXX if a valid AIOP is found, where X - is replace by an identifying number. - Flag AIOPID_NULL if no valid AIOP is found -Warnings: No context switches are allowed while executing this function. - -*/ -static int sReadAiopID(ByteIO_t io) -{ - Byte_t AiopID; /* ID byte from AIOP */ - - sOutB(io + _CMD_REG, RESET_ALL); /* reset AIOP */ - sOutB(io + _CMD_REG, 0x0); - AiopID = sInW(io + _CHN_STAT0) & 0x07; - if (AiopID == 0x06) - return (1); - else /* AIOP does not exist */ - return (-1); -} - -/*************************************************************************** -Function: sReadAiopNumChan -Purpose: Read the number of channels available in an AIOP directly from - an AIOP. -Call: sReadAiopNumChan(io) - WordIO_t io: AIOP base I/O address -Return: int: The number of channels available -Comments: The number of channels is determined by write/reads from identical - offsets within the SRAM address spaces for channels 0 and 4. - If the channel 4 space is mirrored to channel 0 it is a 4 channel - AIOP, otherwise it is an 8 channel. -Warnings: No context switches are allowed while executing this function. -*/ -static int sReadAiopNumChan(WordIO_t io) -{ - Word_t x; - static Byte_t R[4] = { 0x00, 0x00, 0x34, 0x12 }; - - /* write to chan 0 SRAM */ - out32((DWordIO_t) io + _INDX_ADDR, R); - sOutW(io + _INDX_ADDR, 0); /* read from SRAM, chan 0 */ - x = sInW(io + _INDX_DATA); - sOutW(io + _INDX_ADDR, 0x4000); /* read from SRAM, chan 4 */ - if (x != sInW(io + _INDX_DATA)) /* if different must be 8 chan */ - return (8); - else - return (4); -} - -/*************************************************************************** -Function: sInitChan -Purpose: Initialization of a channel and channel structure -Call: sInitChan(CtlP,ChP,AiopNum,ChanNum) - CONTROLLER_T *CtlP; Ptr to controller structure - CHANNEL_T *ChP; Ptr to channel structure - int AiopNum; AIOP number within controller - int ChanNum; Channel number within AIOP -Return: int: 1 if initialization succeeded, 0 if it fails because channel - number exceeds number of channels available in AIOP. -Comments: This function must be called before a channel can be used. -Warnings: No range checking on any of the parameters is done. - - No context switches are allowed while executing this function. -*/ -static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum, - int ChanNum) -{ - int i; - WordIO_t AiopIO; - WordIO_t ChIOOff; - Byte_t *ChR; - Word_t ChOff; - static Byte_t R[4]; - int brd9600; - - if (ChanNum >= CtlP->AiopNumChan[AiopNum]) - return 0; /* exceeds num chans in AIOP */ - - /* Channel, AIOP, and controller identifiers */ - ChP->CtlP = CtlP; - ChP->ChanID = CtlP->AiopID[AiopNum]; - ChP->AiopNum = AiopNum; - ChP->ChanNum = ChanNum; - - /* Global direct addresses */ - AiopIO = CtlP->AiopIO[AiopNum]; - ChP->Cmd = (ByteIO_t) AiopIO + _CMD_REG; - ChP->IntChan = (ByteIO_t) AiopIO + _INT_CHAN; - ChP->IntMask = (ByteIO_t) AiopIO + _INT_MASK; - ChP->IndexAddr = (DWordIO_t) AiopIO + _INDX_ADDR; - ChP->IndexData = AiopIO + _INDX_DATA; - - /* Channel direct addresses */ - ChIOOff = AiopIO + ChP->ChanNum * 2; - ChP->TxRxData = ChIOOff + _TD0; - ChP->ChanStat = ChIOOff + _CHN_STAT0; - ChP->TxRxCount = ChIOOff + _FIFO_CNT0; - ChP->IntID = (ByteIO_t) AiopIO + ChP->ChanNum + _INT_ID0; - - /* Initialize the channel from the RData array */ - for (i = 0; i < RDATASIZE; i += 4) { - R[0] = RData[i]; - R[1] = RData[i + 1] + 0x10 * ChanNum; - R[2] = RData[i + 2]; - R[3] = RData[i + 3]; - out32(ChP->IndexAddr, R); - } - - ChR = ChP->R; - for (i = 0; i < RREGDATASIZE; i += 4) { - ChR[i] = RRegData[i]; - ChR[i + 1] = RRegData[i + 1] + 0x10 * ChanNum; - ChR[i + 2] = RRegData[i + 2]; - ChR[i + 3] = RRegData[i + 3]; - } - - /* Indexed registers */ - ChOff = (Word_t) ChanNum *0x1000; - - if (sClockPrescale == 0x14) - brd9600 = 47; - else - brd9600 = 23; - - ChP->BaudDiv[0] = (Byte_t) (ChOff + _BAUD); - ChP->BaudDiv[1] = (Byte_t) ((ChOff + _BAUD) >> 8); - ChP->BaudDiv[2] = (Byte_t) brd9600; - ChP->BaudDiv[3] = (Byte_t) (brd9600 >> 8); - out32(ChP->IndexAddr, ChP->BaudDiv); - - ChP->TxControl[0] = (Byte_t) (ChOff + _TX_CTRL); - ChP->TxControl[1] = (Byte_t) ((ChOff + _TX_CTRL) >> 8); - ChP->TxControl[2] = 0; - ChP->TxControl[3] = 0; - out32(ChP->IndexAddr, ChP->TxControl); - - ChP->RxControl[0] = (Byte_t) (ChOff + _RX_CTRL); - ChP->RxControl[1] = (Byte_t) ((ChOff + _RX_CTRL) >> 8); - ChP->RxControl[2] = 0; - ChP->RxControl[3] = 0; - out32(ChP->IndexAddr, ChP->RxControl); - - ChP->TxEnables[0] = (Byte_t) (ChOff + _TX_ENBLS); - ChP->TxEnables[1] = (Byte_t) ((ChOff + _TX_ENBLS) >> 8); - ChP->TxEnables[2] = 0; - ChP->TxEnables[3] = 0; - out32(ChP->IndexAddr, ChP->TxEnables); - - ChP->TxCompare[0] = (Byte_t) (ChOff + _TXCMP1); - ChP->TxCompare[1] = (Byte_t) ((ChOff + _TXCMP1) >> 8); - ChP->TxCompare[2] = 0; - ChP->TxCompare[3] = 0; - out32(ChP->IndexAddr, ChP->TxCompare); - - ChP->TxReplace1[0] = (Byte_t) (ChOff + _TXREP1B1); - ChP->TxReplace1[1] = (Byte_t) ((ChOff + _TXREP1B1) >> 8); - ChP->TxReplace1[2] = 0; - ChP->TxReplace1[3] = 0; - out32(ChP->IndexAddr, ChP->TxReplace1); - - ChP->TxReplace2[0] = (Byte_t) (ChOff + _TXREP2); - ChP->TxReplace2[1] = (Byte_t) ((ChOff + _TXREP2) >> 8); - ChP->TxReplace2[2] = 0; - ChP->TxReplace2[3] = 0; - out32(ChP->IndexAddr, ChP->TxReplace2); - - ChP->TxFIFOPtrs = ChOff + _TXF_OUTP; - ChP->TxFIFO = ChOff + _TX_FIFO; - - sOutB(ChP->Cmd, (Byte_t) ChanNum | RESTXFCNT); /* apply reset Tx FIFO count */ - sOutB(ChP->Cmd, (Byte_t) ChanNum); /* remove reset Tx FIFO count */ - sOutW((WordIO_t) ChP->IndexAddr, ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */ - sOutW(ChP->IndexData, 0); - ChP->RxFIFOPtrs = ChOff + _RXF_OUTP; - ChP->RxFIFO = ChOff + _RX_FIFO; - - sOutB(ChP->Cmd, (Byte_t) ChanNum | RESRXFCNT); /* apply reset Rx FIFO count */ - sOutB(ChP->Cmd, (Byte_t) ChanNum); /* remove reset Rx FIFO count */ - sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs); /* clear Rx out ptr */ - sOutW(ChP->IndexData, 0); - sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */ - sOutW(ChP->IndexData, 0); - ChP->TxPrioCnt = ChOff + _TXP_CNT; - sOutW((WordIO_t) ChP->IndexAddr, ChP->TxPrioCnt); - sOutB(ChP->IndexData, 0); - ChP->TxPrioPtr = ChOff + _TXP_PNTR; - sOutW((WordIO_t) ChP->IndexAddr, ChP->TxPrioPtr); - sOutB(ChP->IndexData, 0); - ChP->TxPrioBuf = ChOff + _TXP_BUF; - sEnRxProcessor(ChP); /* start the Rx processor */ - - return 1; -} - -/*************************************************************************** -Function: sStopRxProcessor -Purpose: Stop the receive processor from processing a channel. -Call: sStopRxProcessor(ChP) - CHANNEL_T *ChP; Ptr to channel structure - -Comments: The receive processor can be started again with sStartRxProcessor(). - This function causes the receive processor to skip over the - stopped channel. It does not stop it from processing other channels. - -Warnings: No context switches are allowed while executing this function. - - Do not leave the receive processor stopped for more than one - character time. - - After calling this function a delay of 4 uS is required to ensure - that the receive processor is no longer processing this channel. -*/ -static void sStopRxProcessor(CHANNEL_T * ChP) -{ - Byte_t R[4]; - - R[0] = ChP->R[0]; - R[1] = ChP->R[1]; - R[2] = 0x0a; - R[3] = ChP->R[3]; - out32(ChP->IndexAddr, R); -} - -/*************************************************************************** -Function: sFlushRxFIFO -Purpose: Flush the Rx FIFO -Call: sFlushRxFIFO(ChP) - CHANNEL_T *ChP; Ptr to channel structure -Return: void -Comments: To prevent data from being enqueued or dequeued in the Tx FIFO - while it is being flushed the receive processor is stopped - and the transmitter is disabled. After these operations a - 4 uS delay is done before clearing the pointers to allow - the receive processor to stop. These items are handled inside - this function. -Warnings: No context switches are allowed while executing this function. -*/ -static void sFlushRxFIFO(CHANNEL_T * ChP) -{ - int i; - Byte_t Ch; /* channel number within AIOP */ - int RxFIFOEnabled; /* 1 if Rx FIFO enabled */ - - if (sGetRxCnt(ChP) == 0) /* Rx FIFO empty */ - return; /* don't need to flush */ - - RxFIFOEnabled = 0; - if (ChP->R[0x32] == 0x08) { /* Rx FIFO is enabled */ - RxFIFOEnabled = 1; - sDisRxFIFO(ChP); /* disable it */ - for (i = 0; i < 2000 / 200; i++) /* delay 2 uS to allow proc to disable FIFO */ - sInB(ChP->IntChan); /* depends on bus i/o timing */ - } - sGetChanStatus(ChP); /* clear any pending Rx errors in chan stat */ - Ch = (Byte_t) sGetChanNum(ChP); - sOutB(ChP->Cmd, Ch | RESRXFCNT); /* apply reset Rx FIFO count */ - sOutB(ChP->Cmd, Ch); /* remove reset Rx FIFO count */ - sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs); /* clear Rx out ptr */ - sOutW(ChP->IndexData, 0); - sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */ - sOutW(ChP->IndexData, 0); - if (RxFIFOEnabled) - sEnRxFIFO(ChP); /* enable Rx FIFO */ -} - -/*************************************************************************** -Function: sFlushTxFIFO -Purpose: Flush the Tx FIFO -Call: sFlushTxFIFO(ChP) - CHANNEL_T *ChP; Ptr to channel structure -Return: void -Comments: To prevent data from being enqueued or dequeued in the Tx FIFO - while it is being flushed the receive processor is stopped - and the transmitter is disabled. After these operations a - 4 uS delay is done before clearing the pointers to allow - the receive processor to stop. These items are handled inside - this function. -Warnings: No context switches are allowed while executing this function. -*/ -static void sFlushTxFIFO(CHANNEL_T * ChP) -{ - int i; - Byte_t Ch; /* channel number within AIOP */ - int TxEnabled; /* 1 if transmitter enabled */ - - if (sGetTxCnt(ChP) == 0) /* Tx FIFO empty */ - return; /* don't need to flush */ - - TxEnabled = 0; - if (ChP->TxControl[3] & TX_ENABLE) { - TxEnabled = 1; - sDisTransmit(ChP); /* disable transmitter */ - } - sStopRxProcessor(ChP); /* stop Rx processor */ - for (i = 0; i < 4000 / 200; i++) /* delay 4 uS to allow proc to stop */ - sInB(ChP->IntChan); /* depends on bus i/o timing */ - Ch = (Byte_t) sGetChanNum(ChP); - sOutB(ChP->Cmd, Ch | RESTXFCNT); /* apply reset Tx FIFO count */ - sOutB(ChP->Cmd, Ch); /* remove reset Tx FIFO count */ - sOutW((WordIO_t) ChP->IndexAddr, ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */ - sOutW(ChP->IndexData, 0); - if (TxEnabled) - sEnTransmit(ChP); /* enable transmitter */ - sStartRxProcessor(ChP); /* restart Rx processor */ -} - -/*************************************************************************** -Function: sWriteTxPrioByte -Purpose: Write a byte of priority transmit data to a channel -Call: sWriteTxPrioByte(ChP,Data) - CHANNEL_T *ChP; Ptr to channel structure - Byte_t Data; The transmit data byte - -Return: int: 1 if the bytes is successfully written, otherwise 0. - -Comments: The priority byte is transmitted before any data in the Tx FIFO. - -Warnings: No context switches are allowed while executing this function. -*/ -static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data) -{ - Byte_t DWBuf[4]; /* buffer for double word writes */ - Word_t *WordPtr; /* must be far because Win SS != DS */ - register DWordIO_t IndexAddr; - - if (sGetTxCnt(ChP) > 1) { /* write it to Tx priority buffer */ - IndexAddr = ChP->IndexAddr; - sOutW((WordIO_t) IndexAddr, ChP->TxPrioCnt); /* get priority buffer status */ - if (sInB((ByteIO_t) ChP->IndexData) & PRI_PEND) /* priority buffer busy */ - return (0); /* nothing sent */ - - WordPtr = (Word_t *) (&DWBuf[0]); - *WordPtr = ChP->TxPrioBuf; /* data byte address */ - - DWBuf[2] = Data; /* data byte value */ - out32(IndexAddr, DWBuf); /* write it out */ - - *WordPtr = ChP->TxPrioCnt; /* Tx priority count address */ - - DWBuf[2] = PRI_PEND + 1; /* indicate 1 byte pending */ - DWBuf[3] = 0; /* priority buffer pointer */ - out32(IndexAddr, DWBuf); /* write it out */ - } else { /* write it to Tx FIFO */ - - sWriteTxByte(sGetTxRxDataIO(ChP), Data); - } - return (1); /* 1 byte sent */ -} - -/*************************************************************************** -Function: sEnInterrupts -Purpose: Enable one or more interrupts for a channel -Call: sEnInterrupts(ChP,Flags) - CHANNEL_T *ChP; Ptr to channel structure - Word_t Flags: Interrupt enable flags, can be any combination - of the following flags: - TXINT_EN: Interrupt on Tx FIFO empty - RXINT_EN: Interrupt on Rx FIFO at trigger level (see - sSetRxTrigger()) - SRCINT_EN: Interrupt on SRC (Special Rx Condition) - MCINT_EN: Interrupt on modem input change - CHANINT_EN: Allow channel interrupt signal to the AIOP's - Interrupt Channel Register. -Return: void -Comments: If an interrupt enable flag is set in Flags, that interrupt will be - enabled. If an interrupt enable flag is not set in Flags, that - interrupt will not be changed. Interrupts can be disabled with - function sDisInterrupts(). - - This function sets the appropriate bit for the channel in the AIOP's - Interrupt Mask Register if the CHANINT_EN flag is set. This allows - this channel's bit to be set in the AIOP's Interrupt Channel Register. - - Interrupts must also be globally enabled before channel interrupts - will be passed on to the host. This is done with function - sEnGlobalInt(). - - In some cases it may be desirable to disable interrupts globally but - enable channel interrupts. This would allow the global interrupt - status register to be used to determine which AIOPs need service. -*/ -static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags) -{ - Byte_t Mask; /* Interrupt Mask Register */ - - ChP->RxControl[2] |= - ((Byte_t) Flags & (RXINT_EN | SRCINT_EN | MCINT_EN)); - - out32(ChP->IndexAddr, ChP->RxControl); - - ChP->TxControl[2] |= ((Byte_t) Flags & TXINT_EN); - - out32(ChP->IndexAddr, ChP->TxControl); - - if (Flags & CHANINT_EN) { - Mask = sInB(ChP->IntMask) | sBitMapSetTbl[ChP->ChanNum]; - sOutB(ChP->IntMask, Mask); - } -} - -/*************************************************************************** -Function: sDisInterrupts -Purpose: Disable one or more interrupts for a channel -Call: sDisInterrupts(ChP,Flags) - CHANNEL_T *ChP; Ptr to channel structure - Word_t Flags: Interrupt flags, can be any combination - of the following flags: - TXINT_EN: Interrupt on Tx FIFO empty - RXINT_EN: Interrupt on Rx FIFO at trigger level (see - sSetRxTrigger()) - SRCINT_EN: Interrupt on SRC (Special Rx Condition) - MCINT_EN: Interrupt on modem input change - CHANINT_EN: Disable channel interrupt signal to the - AIOP's Interrupt Channel Register. -Return: void -Comments: If an interrupt flag is set in Flags, that interrupt will be - disabled. If an interrupt flag is not set in Flags, that - interrupt will not be changed. Interrupts can be enabled with - function sEnInterrupts(). - - This function clears the appropriate bit for the channel in the AIOP's - Interrupt Mask Register if the CHANINT_EN flag is set. This blocks - this channel's bit from being set in the AIOP's Interrupt Channel - Register. -*/ -static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags) -{ - Byte_t Mask; /* Interrupt Mask Register */ - - ChP->RxControl[2] &= - ~((Byte_t) Flags & (RXINT_EN | SRCINT_EN | MCINT_EN)); - out32(ChP->IndexAddr, ChP->RxControl); - ChP->TxControl[2] &= ~((Byte_t) Flags & TXINT_EN); - out32(ChP->IndexAddr, ChP->TxControl); - - if (Flags & CHANINT_EN) { - Mask = sInB(ChP->IntMask) & sBitMapClrTbl[ChP->ChanNum]; - sOutB(ChP->IntMask, Mask); - } -} - -static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode) -{ - sOutB(ChP->CtlP->AiopIO[2], (mode & 0x18) | ChP->ChanNum); -} - -/* - * Not an official SSCI function, but how to reset RocketModems. - * ISA bus version - */ -static void sModemReset(CONTROLLER_T * CtlP, int chan, int on) -{ - ByteIO_t addr; - Byte_t val; - - addr = CtlP->AiopIO[0] + 0x400; - val = sInB(CtlP->MReg3IO); - /* if AIOP[1] is not enabled, enable it */ - if ((val & 2) == 0) { - val = sInB(CtlP->MReg2IO); - sOutB(CtlP->MReg2IO, (val & 0xfc) | (1 & 0x03)); - sOutB(CtlP->MBaseIO, (unsigned char) (addr >> 6)); - } - - sEnAiop(CtlP, 1); - if (!on) - addr += 8; - sOutB(addr + chan, 0); /* apply or remove reset */ - sDisAiop(CtlP, 1); -} - -/* - * Not an official SSCI function, but how to reset RocketModems. - * PCI bus version - */ -static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on) -{ - ByteIO_t addr; - - addr = CtlP->AiopIO[0] + 0x40; /* 2nd AIOP */ - if (!on) - addr += 8; - sOutB(addr + chan, 0); /* apply or remove reset */ -} - -/* Resets the speaker controller on RocketModem II and III devices */ -static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model) -{ - ByteIO_t addr; - - /* RocketModem II speaker control is at the 8th port location of offset 0x40 */ - if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) { - addr = CtlP->AiopIO[0] + 0x4F; - sOutB(addr, 0); - } - - /* RocketModem III speaker control is at the 1st port location of offset 0x80 */ - if ((model == MODEL_UPCI_RM3_8PORT) - || (model == MODEL_UPCI_RM3_4PORT)) { - addr = CtlP->AiopIO[0] + 0x88; - sOutB(addr, 0); - } -} - -/* Returns the line number given the controller (board), aiop and channel number */ -static unsigned char GetLineNumber(int ctrl, int aiop, int ch) -{ - return lineNumbers[(ctrl << 5) | (aiop << 3) | ch]; -} - -/* - * Stores the line number associated with a given controller (board), aiop - * and channel number. - * Returns: The line number assigned - */ -static unsigned char SetLineNumber(int ctrl, int aiop, int ch) -{ - lineNumbers[(ctrl << 5) | (aiop << 3) | ch] = nextLineNumber++; - return (nextLineNumber - 1); -} diff --git a/drivers/char/rocket.h b/drivers/char/rocket.h deleted file mode 100644 index ec863f35f1a9..000000000000 --- a/drivers/char/rocket.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * rocket.h --- the exported interface of the rocket driver to its configuration program. - * - * Written by Theodore Ts'o, Copyright 1997. - * Copyright 1997 Comtrol Corporation. - * - */ - -/* Model Information Struct */ -typedef struct { - unsigned long model; - char modelString[80]; - unsigned long numPorts; - int loadrm2; - int startingPortNumber; -} rocketModel_t; - -struct rocket_config { - int line; - int flags; - int closing_wait; - int close_delay; - int port; - int reserved[32]; -}; - -struct rocket_ports { - int tty_major; - int callout_major; - rocketModel_t rocketModel[8]; -}; - -struct rocket_version { - char rocket_version[32]; - char rocket_date[32]; - char reserved[64]; -}; - -/* - * Rocketport flags - */ -/*#define ROCKET_CALLOUT_NOHUP 0x00000001 */ -#define ROCKET_FORCE_CD 0x00000002 -#define ROCKET_HUP_NOTIFY 0x00000004 -#define ROCKET_SPLIT_TERMIOS 0x00000008 -#define ROCKET_SPD_MASK 0x00000070 -#define ROCKET_SPD_HI 0x00000010 /* Use 56000 instead of 38400 bps */ -#define ROCKET_SPD_VHI 0x00000020 /* Use 115200 instead of 38400 bps */ -#define ROCKET_SPD_SHI 0x00000030 /* Use 230400 instead of 38400 bps */ -#define ROCKET_SPD_WARP 0x00000040 /* Use 460800 instead of 38400 bps */ -#define ROCKET_SAK 0x00000080 -#define ROCKET_SESSION_LOCKOUT 0x00000100 -#define ROCKET_PGRP_LOCKOUT 0x00000200 -#define ROCKET_RTS_TOGGLE 0x00000400 -#define ROCKET_MODE_MASK 0x00003000 -#define ROCKET_MODE_RS232 0x00000000 -#define ROCKET_MODE_RS485 0x00001000 -#define ROCKET_MODE_RS422 0x00002000 -#define ROCKET_FLAGS 0x00003FFF - -#define ROCKET_USR_MASK 0x0071 /* Legal flags that non-privileged - * users can set or reset */ - -/* - * For closing_wait and closing_wait2 - */ -#define ROCKET_CLOSING_WAIT_NONE ASYNC_CLOSING_WAIT_NONE -#define ROCKET_CLOSING_WAIT_INF ASYNC_CLOSING_WAIT_INF - -/* - * Rocketport ioctls -- "RP" - */ -#define RCKP_GET_STRUCT 0x00525001 -#define RCKP_GET_CONFIG 0x00525002 -#define RCKP_SET_CONFIG 0x00525003 -#define RCKP_GET_PORTS 0x00525004 -#define RCKP_RESET_RM2 0x00525005 -#define RCKP_GET_VERSION 0x00525006 - -/* Rocketport Models */ -#define MODEL_RP32INTF 0x0001 /* RP 32 port w/external I/F */ -#define MODEL_RP8INTF 0x0002 /* RP 8 port w/external I/F */ -#define MODEL_RP16INTF 0x0003 /* RP 16 port w/external I/F */ -#define MODEL_RP8OCTA 0x0005 /* RP 8 port w/octa cable */ -#define MODEL_RP4QUAD 0x0004 /* RP 4 port w/quad cable */ -#define MODEL_RP8J 0x0006 /* RP 8 port w/RJ11 connectors */ -#define MODEL_RP4J 0x0007 /* RP 4 port w/RJ45 connectors */ -#define MODEL_RP8SNI 0x0008 /* RP 8 port w/ DB78 SNI connector */ -#define MODEL_RP16SNI 0x0009 /* RP 16 port w/ DB78 SNI connector */ -#define MODEL_RPP4 0x000A /* RP Plus 4 port */ -#define MODEL_RPP8 0x000B /* RP Plus 8 port */ -#define MODEL_RP2_232 0x000E /* RP Plus 2 port RS232 */ -#define MODEL_RP2_422 0x000F /* RP Plus 2 port RS232 */ - -/* Rocketmodem II Models */ -#define MODEL_RP6M 0x000C /* RM 6 port */ -#define MODEL_RP4M 0x000D /* RM 4 port */ - -/* Universal PCI boards */ -#define MODEL_UPCI_RP32INTF 0x0801 /* RP UPCI 32 port w/external I/F */ -#define MODEL_UPCI_RP8INTF 0x0802 /* RP UPCI 8 port w/external I/F */ -#define MODEL_UPCI_RP16INTF 0x0803 /* RP UPCI 16 port w/external I/F */ -#define MODEL_UPCI_RP8OCTA 0x0805 /* RP UPCI 8 port w/octa cable */ -#define MODEL_UPCI_RM3_8PORT 0x080C /* RP UPCI Rocketmodem III 8 port */ -#define MODEL_UPCI_RM3_4PORT 0x080C /* RP UPCI Rocketmodem III 4 port */ - -/* Compact PCI 16 port */ -#define MODEL_CPCI_RP16INTF 0x0903 /* RP Compact PCI 16 port w/external I/F */ - -/* All ISA boards */ -#define MODEL_ISA 0x1000 diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h deleted file mode 100644 index 67e0f1e778a2..000000000000 --- a/drivers/char/rocket_int.h +++ /dev/null @@ -1,1214 +0,0 @@ -/* - * rocket_int.h --- internal header file for rocket.c - * - * Written by Theodore Ts'o, Copyright 1997. - * Copyright 1997 Comtrol Corporation. - * - */ - -/* - * Definition of the types in rcktpt_type - */ -#define ROCKET_TYPE_NORMAL 0 -#define ROCKET_TYPE_MODEM 1 -#define ROCKET_TYPE_MODEMII 2 -#define ROCKET_TYPE_MODEMIII 3 -#define ROCKET_TYPE_PC104 4 - -#include - -#include -#include - -typedef unsigned char Byte_t; -typedef unsigned int ByteIO_t; - -typedef unsigned int Word_t; -typedef unsigned int WordIO_t; - -typedef unsigned int DWordIO_t; - -/* - * Note! Normally the Linux I/O macros already take care of - * byte-swapping the I/O instructions. However, all accesses using - * sOutDW aren't really 32-bit accesses, but should be handled in byte - * order. Hence the use of the cpu_to_le32() macro to byte-swap - * things to no-op the byte swapping done by the big-endian outl() - * instruction. - */ - -static inline void sOutB(unsigned short port, unsigned char value) -{ -#ifdef ROCKET_DEBUG_IO - printk(KERN_DEBUG "sOutB(%x, %x)...\n", port, value); -#endif - outb_p(value, port); -} - -static inline void sOutW(unsigned short port, unsigned short value) -{ -#ifdef ROCKET_DEBUG_IO - printk(KERN_DEBUG "sOutW(%x, %x)...\n", port, value); -#endif - outw_p(value, port); -} - -static inline void out32(unsigned short port, Byte_t *p) -{ - u32 value = get_unaligned_le32(p); -#ifdef ROCKET_DEBUG_IO - printk(KERN_DEBUG "out32(%x, %lx)...\n", port, value); -#endif - outl_p(value, port); -} - -static inline unsigned char sInB(unsigned short port) -{ - return inb_p(port); -} - -static inline unsigned short sInW(unsigned short port) -{ - return inw_p(port); -} - -/* This is used to move arrays of bytes so byte swapping isn't appropriate. */ -#define sOutStrW(port, addr, count) if (count) outsw(port, addr, count) -#define sInStrW(port, addr, count) if (count) insw(port, addr, count) - -#define CTL_SIZE 8 -#define AIOP_CTL_SIZE 4 -#define CHAN_AIOP_SIZE 8 -#define MAX_PORTS_PER_AIOP 8 -#define MAX_AIOPS_PER_BOARD 4 -#define MAX_PORTS_PER_BOARD 32 - -/* Bus type ID */ -#define isISA 0 -#define isPCI 1 -#define isMC 2 - -/* Controller ID numbers */ -#define CTLID_NULL -1 /* no controller exists */ -#define CTLID_0001 0x0001 /* controller release 1 */ - -/* AIOP ID numbers, identifies AIOP type implementing channel */ -#define AIOPID_NULL -1 /* no AIOP or channel exists */ -#define AIOPID_0001 0x0001 /* AIOP release 1 */ - -/************************************************************************ - Global Register Offsets - Direct Access - Fixed values -************************************************************************/ - -#define _CMD_REG 0x38 /* Command Register 8 Write */ -#define _INT_CHAN 0x39 /* Interrupt Channel Register 8 Read */ -#define _INT_MASK 0x3A /* Interrupt Mask Register 8 Read / Write */ -#define _UNUSED 0x3B /* Unused 8 */ -#define _INDX_ADDR 0x3C /* Index Register Address 16 Write */ -#define _INDX_DATA 0x3E /* Index Register Data 8/16 Read / Write */ - -/************************************************************************ - Channel Register Offsets for 1st channel in AIOP - Direct Access -************************************************************************/ -#define _TD0 0x00 /* Transmit Data 16 Write */ -#define _RD0 0x00 /* Receive Data 16 Read */ -#define _CHN_STAT0 0x20 /* Channel Status 8/16 Read / Write */ -#define _FIFO_CNT0 0x10 /* Transmit/Receive FIFO Count 16 Read */ -#define _INT_ID0 0x30 /* Interrupt Identification 8 Read */ - -/************************************************************************ - Tx Control Register Offsets - Indexed - External - Fixed -************************************************************************/ -#define _TX_ENBLS 0x980 /* Tx Processor Enables Register 8 Read / Write */ -#define _TXCMP1 0x988 /* Transmit Compare Value #1 8 Read / Write */ -#define _TXCMP2 0x989 /* Transmit Compare Value #2 8 Read / Write */ -#define _TXREP1B1 0x98A /* Tx Replace Value #1 - Byte 1 8 Read / Write */ -#define _TXREP1B2 0x98B /* Tx Replace Value #1 - Byte 2 8 Read / Write */ -#define _TXREP2 0x98C /* Transmit Replace Value #2 8 Read / Write */ - -/************************************************************************ -Memory Controller Register Offsets - Indexed - External - Fixed -************************************************************************/ -#define _RX_FIFO 0x000 /* Rx FIFO */ -#define _TX_FIFO 0x800 /* Tx FIFO */ -#define _RXF_OUTP 0x990 /* Rx FIFO OUT pointer 16 Read / Write */ -#define _RXF_INP 0x992 /* Rx FIFO IN pointer 16 Read / Write */ -#define _TXF_OUTP 0x994 /* Tx FIFO OUT pointer 8 Read / Write */ -#define _TXF_INP 0x995 /* Tx FIFO IN pointer 8 Read / Write */ -#define _TXP_CNT 0x996 /* Tx Priority Count 8 Read / Write */ -#define _TXP_PNTR 0x997 /* Tx Priority Pointer 8 Read / Write */ - -#define PRI_PEND 0x80 /* Priority data pending (bit7, Tx pri cnt) */ -#define TXFIFO_SIZE 255 /* size of Tx FIFO */ -#define RXFIFO_SIZE 1023 /* size of Rx FIFO */ - -/************************************************************************ -Tx Priority Buffer - Indexed - External - Fixed -************************************************************************/ -#define _TXP_BUF 0x9C0 /* Tx Priority Buffer 32 Bytes Read / Write */ -#define TXP_SIZE 0x20 /* 32 bytes */ - -/************************************************************************ -Channel Register Offsets - Indexed - Internal - Fixed -************************************************************************/ - -#define _TX_CTRL 0xFF0 /* Transmit Control 16 Write */ -#define _RX_CTRL 0xFF2 /* Receive Control 8 Write */ -#define _BAUD 0xFF4 /* Baud Rate 16 Write */ -#define _CLK_PRE 0xFF6 /* Clock Prescaler 8 Write */ - -#define STMBREAK 0x08 /* BREAK */ -#define STMFRAME 0x04 /* framing error */ -#define STMRCVROVR 0x02 /* receiver over run error */ -#define STMPARITY 0x01 /* parity error */ -#define STMERROR (STMBREAK | STMFRAME | STMPARITY) -#define STMBREAKH 0x800 /* BREAK */ -#define STMFRAMEH 0x400 /* framing error */ -#define STMRCVROVRH 0x200 /* receiver over run error */ -#define STMPARITYH 0x100 /* parity error */ -#define STMERRORH (STMBREAKH | STMFRAMEH | STMPARITYH) - -#define CTS_ACT 0x20 /* CTS input asserted */ -#define DSR_ACT 0x10 /* DSR input asserted */ -#define CD_ACT 0x08 /* CD input asserted */ -#define TXFIFOMT 0x04 /* Tx FIFO is empty */ -#define TXSHRMT 0x02 /* Tx shift register is empty */ -#define RDA 0x01 /* Rx data available */ -#define DRAINED (TXFIFOMT | TXSHRMT) /* indicates Tx is drained */ - -#define STATMODE 0x8000 /* status mode enable bit */ -#define RXFOVERFL 0x2000 /* receive FIFO overflow */ -#define RX2MATCH 0x1000 /* receive compare byte 2 match */ -#define RX1MATCH 0x0800 /* receive compare byte 1 match */ -#define RXBREAK 0x0400 /* received BREAK */ -#define RXFRAME 0x0200 /* received framing error */ -#define RXPARITY 0x0100 /* received parity error */ -#define STATERROR (RXBREAK | RXFRAME | RXPARITY) - -#define CTSFC_EN 0x80 /* CTS flow control enable bit */ -#define RTSTOG_EN 0x40 /* RTS toggle enable bit */ -#define TXINT_EN 0x10 /* transmit interrupt enable */ -#define STOP2 0x08 /* enable 2 stop bits (0 = 1 stop) */ -#define PARITY_EN 0x04 /* enable parity (0 = no parity) */ -#define EVEN_PAR 0x02 /* even parity (0 = odd parity) */ -#define DATA8BIT 0x01 /* 8 bit data (0 = 7 bit data) */ - -#define SETBREAK 0x10 /* send break condition (must clear) */ -#define LOCALLOOP 0x08 /* local loopback set for test */ -#define SET_DTR 0x04 /* assert DTR */ -#define SET_RTS 0x02 /* assert RTS */ -#define TX_ENABLE 0x01 /* enable transmitter */ - -#define RTSFC_EN 0x40 /* RTS flow control enable */ -#define RXPROC_EN 0x20 /* receive processor enable */ -#define TRIG_NO 0x00 /* Rx FIFO trigger level 0 (no trigger) */ -#define TRIG_1 0x08 /* trigger level 1 char */ -#define TRIG_1_2 0x10 /* trigger level 1/2 */ -#define TRIG_7_8 0x18 /* trigger level 7/8 */ -#define TRIG_MASK 0x18 /* trigger level mask */ -#define SRCINT_EN 0x04 /* special Rx condition interrupt enable */ -#define RXINT_EN 0x02 /* Rx interrupt enable */ -#define MCINT_EN 0x01 /* modem change interrupt enable */ - -#define RXF_TRIG 0x20 /* Rx FIFO trigger level interrupt */ -#define TXFIFO_MT 0x10 /* Tx FIFO empty interrupt */ -#define SRC_INT 0x08 /* special receive condition interrupt */ -#define DELTA_CD 0x04 /* CD change interrupt */ -#define DELTA_CTS 0x02 /* CTS change interrupt */ -#define DELTA_DSR 0x01 /* DSR change interrupt */ - -#define REP1W2_EN 0x10 /* replace byte 1 with 2 bytes enable */ -#define IGN2_EN 0x08 /* ignore byte 2 enable */ -#define IGN1_EN 0x04 /* ignore byte 1 enable */ -#define COMP2_EN 0x02 /* compare byte 2 enable */ -#define COMP1_EN 0x01 /* compare byte 1 enable */ - -#define RESET_ALL 0x80 /* reset AIOP (all channels) */ -#define TXOVERIDE 0x40 /* Transmit software off override */ -#define RESETUART 0x20 /* reset channel's UART */ -#define RESTXFCNT 0x10 /* reset channel's Tx FIFO count register */ -#define RESRXFCNT 0x08 /* reset channel's Rx FIFO count register */ - -#define INTSTAT0 0x01 /* AIOP 0 interrupt status */ -#define INTSTAT1 0x02 /* AIOP 1 interrupt status */ -#define INTSTAT2 0x04 /* AIOP 2 interrupt status */ -#define INTSTAT3 0x08 /* AIOP 3 interrupt status */ - -#define INTR_EN 0x08 /* allow interrupts to host */ -#define INT_STROB 0x04 /* strobe and clear interrupt line (EOI) */ - -/************************************************************************** - MUDBAC remapped for PCI -**************************************************************************/ - -#define _CFG_INT_PCI 0x40 -#define _PCI_INT_FUNC 0x3A - -#define PCI_STROB 0x2000 /* bit 13 of int aiop register */ -#define INTR_EN_PCI 0x0010 /* allow interrupts to host */ - -/* - * Definitions for Universal PCI board registers - */ -#define _PCI_9030_INT_CTRL 0x4c /* Offsets from BAR1 */ -#define _PCI_9030_GPIO_CTRL 0x54 -#define PCI_INT_CTRL_AIOP 0x0001 -#define PCI_GPIO_CTRL_8PORT 0x4000 -#define _PCI_9030_RING_IND 0xc0 /* Offsets from BAR1 */ - -#define CHAN3_EN 0x08 /* enable AIOP 3 */ -#define CHAN2_EN 0x04 /* enable AIOP 2 */ -#define CHAN1_EN 0x02 /* enable AIOP 1 */ -#define CHAN0_EN 0x01 /* enable AIOP 0 */ -#define FREQ_DIS 0x00 -#define FREQ_274HZ 0x60 -#define FREQ_137HZ 0x50 -#define FREQ_69HZ 0x40 -#define FREQ_34HZ 0x30 -#define FREQ_17HZ 0x20 -#define FREQ_9HZ 0x10 -#define PERIODIC_ONLY 0x80 /* only PERIODIC interrupt */ - -#define CHANINT_EN 0x0100 /* flags to enable/disable channel ints */ - -#define RDATASIZE 72 -#define RREGDATASIZE 52 - -/* - * AIOP interrupt bits for ISA/PCI boards and UPCI boards. - */ -#define AIOP_INTR_BIT_0 0x0001 -#define AIOP_INTR_BIT_1 0x0002 -#define AIOP_INTR_BIT_2 0x0004 -#define AIOP_INTR_BIT_3 0x0008 - -#define AIOP_INTR_BITS ( \ - AIOP_INTR_BIT_0 \ - | AIOP_INTR_BIT_1 \ - | AIOP_INTR_BIT_2 \ - | AIOP_INTR_BIT_3) - -#define UPCI_AIOP_INTR_BIT_0 0x0004 -#define UPCI_AIOP_INTR_BIT_1 0x0020 -#define UPCI_AIOP_INTR_BIT_2 0x0100 -#define UPCI_AIOP_INTR_BIT_3 0x0800 - -#define UPCI_AIOP_INTR_BITS ( \ - UPCI_AIOP_INTR_BIT_0 \ - | UPCI_AIOP_INTR_BIT_1 \ - | UPCI_AIOP_INTR_BIT_2 \ - | UPCI_AIOP_INTR_BIT_3) - -/* Controller level information structure */ -typedef struct { - int CtlID; - int CtlNum; - int BusType; - int boardType; - int isUPCI; - WordIO_t PCIIO; - WordIO_t PCIIO2; - ByteIO_t MBaseIO; - ByteIO_t MReg1IO; - ByteIO_t MReg2IO; - ByteIO_t MReg3IO; - Byte_t MReg2; - Byte_t MReg3; - int NumAiop; - int AltChanRingIndicator; - ByteIO_t UPCIRingInd; - WordIO_t AiopIO[AIOP_CTL_SIZE]; - ByteIO_t AiopIntChanIO[AIOP_CTL_SIZE]; - int AiopID[AIOP_CTL_SIZE]; - int AiopNumChan[AIOP_CTL_SIZE]; - Word_t *AiopIntrBits; -} CONTROLLER_T; - -typedef CONTROLLER_T CONTROLLER_t; - -/* Channel level information structure */ -typedef struct { - CONTROLLER_T *CtlP; - int AiopNum; - int ChanID; - int ChanNum; - int rtsToggle; - - ByteIO_t Cmd; - ByteIO_t IntChan; - ByteIO_t IntMask; - DWordIO_t IndexAddr; - WordIO_t IndexData; - - WordIO_t TxRxData; - WordIO_t ChanStat; - WordIO_t TxRxCount; - ByteIO_t IntID; - - Word_t TxFIFO; - Word_t TxFIFOPtrs; - Word_t RxFIFO; - Word_t RxFIFOPtrs; - Word_t TxPrioCnt; - Word_t TxPrioPtr; - Word_t TxPrioBuf; - - Byte_t R[RREGDATASIZE]; - - Byte_t BaudDiv[4]; - Byte_t TxControl[4]; - Byte_t RxControl[4]; - Byte_t TxEnables[4]; - Byte_t TxCompare[4]; - Byte_t TxReplace1[4]; - Byte_t TxReplace2[4]; -} CHANNEL_T; - -typedef CHANNEL_T CHANNEL_t; -typedef CHANNEL_T *CHANPTR_T; - -#define InterfaceModeRS232 0x00 -#define InterfaceModeRS422 0x08 -#define InterfaceModeRS485 0x10 -#define InterfaceModeRS232T 0x18 - -/*************************************************************************** -Function: sClrBreak -Purpose: Stop sending a transmit BREAK signal -Call: sClrBreak(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sClrBreak(ChP) \ -do { \ - (ChP)->TxControl[3] &= ~SETBREAK; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ -} while (0) - -/*************************************************************************** -Function: sClrDTR -Purpose: Clr the DTR output -Call: sClrDTR(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sClrDTR(ChP) \ -do { \ - (ChP)->TxControl[3] &= ~SET_DTR; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ -} while (0) - -/*************************************************************************** -Function: sClrRTS -Purpose: Clr the RTS output -Call: sClrRTS(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sClrRTS(ChP) \ -do { \ - if ((ChP)->rtsToggle) break; \ - (ChP)->TxControl[3] &= ~SET_RTS; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ -} while (0) - -/*************************************************************************** -Function: sClrTxXOFF -Purpose: Clear any existing transmit software flow control off condition -Call: sClrTxXOFF(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sClrTxXOFF(ChP) \ -do { \ - sOutB((ChP)->Cmd,TXOVERIDE | (Byte_t)(ChP)->ChanNum); \ - sOutB((ChP)->Cmd,(Byte_t)(ChP)->ChanNum); \ -} while (0) - -/*************************************************************************** -Function: sCtlNumToCtlPtr -Purpose: Convert a controller number to controller structure pointer -Call: sCtlNumToCtlPtr(CtlNum) - int CtlNum; Controller number -Return: CONTROLLER_T *: Ptr to controller structure -*/ -#define sCtlNumToCtlPtr(CTLNUM) &sController[CTLNUM] - -/*************************************************************************** -Function: sControllerEOI -Purpose: Strobe the MUDBAC's End Of Interrupt bit. -Call: sControllerEOI(CtlP) - CONTROLLER_T *CtlP; Ptr to controller structure -*/ -#define sControllerEOI(CTLP) sOutB((CTLP)->MReg2IO,(CTLP)->MReg2 | INT_STROB) - -/*************************************************************************** -Function: sPCIControllerEOI -Purpose: Strobe the PCI End Of Interrupt bit. - For the UPCI boards, toggle the AIOP interrupt enable bit - (this was taken from the Windows driver). -Call: sPCIControllerEOI(CtlP) - CONTROLLER_T *CtlP; Ptr to controller structure -*/ -#define sPCIControllerEOI(CTLP) \ -do { \ - if ((CTLP)->isUPCI) { \ - Word_t w = sInW((CTLP)->PCIIO); \ - sOutW((CTLP)->PCIIO, (w ^ PCI_INT_CTRL_AIOP)); \ - sOutW((CTLP)->PCIIO, w); \ - } \ - else { \ - sOutW((CTLP)->PCIIO, PCI_STROB); \ - } \ -} while (0) - -/*************************************************************************** -Function: sDisAiop -Purpose: Disable I/O access to an AIOP -Call: sDisAiop(CltP) - CONTROLLER_T *CtlP; Ptr to controller structure - int AiopNum; Number of AIOP on controller -*/ -#define sDisAiop(CTLP,AIOPNUM) \ -do { \ - (CTLP)->MReg3 &= sBitMapClrTbl[AIOPNUM]; \ - sOutB((CTLP)->MReg3IO,(CTLP)->MReg3); \ -} while (0) - -/*************************************************************************** -Function: sDisCTSFlowCtl -Purpose: Disable output flow control using CTS -Call: sDisCTSFlowCtl(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sDisCTSFlowCtl(ChP) \ -do { \ - (ChP)->TxControl[2] &= ~CTSFC_EN; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ -} while (0) - -/*************************************************************************** -Function: sDisIXANY -Purpose: Disable IXANY Software Flow Control -Call: sDisIXANY(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sDisIXANY(ChP) \ -do { \ - (ChP)->R[0x0e] = 0x86; \ - out32((ChP)->IndexAddr,&(ChP)->R[0x0c]); \ -} while (0) - -/*************************************************************************** -Function: DisParity -Purpose: Disable parity -Call: sDisParity(ChP) - CHANNEL_T *ChP; Ptr to channel structure -Comments: Function sSetParity() can be used in place of functions sEnParity(), - sDisParity(), sSetOddParity(), and sSetEvenParity(). -*/ -#define sDisParity(ChP) \ -do { \ - (ChP)->TxControl[2] &= ~PARITY_EN; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ -} while (0) - -/*************************************************************************** -Function: sDisRTSToggle -Purpose: Disable RTS toggle -Call: sDisRTSToggle(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sDisRTSToggle(ChP) \ -do { \ - (ChP)->TxControl[2] &= ~RTSTOG_EN; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ - (ChP)->rtsToggle = 0; \ -} while (0) - -/*************************************************************************** -Function: sDisRxFIFO -Purpose: Disable Rx FIFO -Call: sDisRxFIFO(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sDisRxFIFO(ChP) \ -do { \ - (ChP)->R[0x32] = 0x0a; \ - out32((ChP)->IndexAddr,&(ChP)->R[0x30]); \ -} while (0) - -/*************************************************************************** -Function: sDisRxStatusMode -Purpose: Disable the Rx status mode -Call: sDisRxStatusMode(ChP) - CHANNEL_T *ChP; Ptr to channel structure -Comments: This takes the channel out of the receive status mode. All - subsequent reads of receive data using sReadRxWord() will return - two data bytes. -*/ -#define sDisRxStatusMode(ChP) sOutW((ChP)->ChanStat,0) - -/*************************************************************************** -Function: sDisTransmit -Purpose: Disable transmit -Call: sDisTransmit(ChP) - CHANNEL_T *ChP; Ptr to channel structure - This disables movement of Tx data from the Tx FIFO into the 1 byte - Tx buffer. Therefore there could be up to a 2 byte latency - between the time sDisTransmit() is called and the transmit buffer - and transmit shift register going completely empty. -*/ -#define sDisTransmit(ChP) \ -do { \ - (ChP)->TxControl[3] &= ~TX_ENABLE; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ -} while (0) - -/*************************************************************************** -Function: sDisTxSoftFlowCtl -Purpose: Disable Tx Software Flow Control -Call: sDisTxSoftFlowCtl(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sDisTxSoftFlowCtl(ChP) \ -do { \ - (ChP)->R[0x06] = 0x8a; \ - out32((ChP)->IndexAddr,&(ChP)->R[0x04]); \ -} while (0) - -/*************************************************************************** -Function: sEnAiop -Purpose: Enable I/O access to an AIOP -Call: sEnAiop(CltP) - CONTROLLER_T *CtlP; Ptr to controller structure - int AiopNum; Number of AIOP on controller -*/ -#define sEnAiop(CTLP,AIOPNUM) \ -do { \ - (CTLP)->MReg3 |= sBitMapSetTbl[AIOPNUM]; \ - sOutB((CTLP)->MReg3IO,(CTLP)->MReg3); \ -} while (0) - -/*************************************************************************** -Function: sEnCTSFlowCtl -Purpose: Enable output flow control using CTS -Call: sEnCTSFlowCtl(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sEnCTSFlowCtl(ChP) \ -do { \ - (ChP)->TxControl[2] |= CTSFC_EN; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ -} while (0) - -/*************************************************************************** -Function: sEnIXANY -Purpose: Enable IXANY Software Flow Control -Call: sEnIXANY(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sEnIXANY(ChP) \ -do { \ - (ChP)->R[0x0e] = 0x21; \ - out32((ChP)->IndexAddr,&(ChP)->R[0x0c]); \ -} while (0) - -/*************************************************************************** -Function: EnParity -Purpose: Enable parity -Call: sEnParity(ChP) - CHANNEL_T *ChP; Ptr to channel structure -Comments: Function sSetParity() can be used in place of functions sEnParity(), - sDisParity(), sSetOddParity(), and sSetEvenParity(). - -Warnings: Before enabling parity odd or even parity should be chosen using - functions sSetOddParity() or sSetEvenParity(). -*/ -#define sEnParity(ChP) \ -do { \ - (ChP)->TxControl[2] |= PARITY_EN; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ -} while (0) - -/*************************************************************************** -Function: sEnRTSToggle -Purpose: Enable RTS toggle -Call: sEnRTSToggle(ChP) - CHANNEL_T *ChP; Ptr to channel structure -Comments: This function will disable RTS flow control and clear the RTS - line to allow operation of RTS toggle. -*/ -#define sEnRTSToggle(ChP) \ -do { \ - (ChP)->RxControl[2] &= ~RTSFC_EN; \ - out32((ChP)->IndexAddr,(ChP)->RxControl); \ - (ChP)->TxControl[2] |= RTSTOG_EN; \ - (ChP)->TxControl[3] &= ~SET_RTS; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ - (ChP)->rtsToggle = 1; \ -} while (0) - -/*************************************************************************** -Function: sEnRxFIFO -Purpose: Enable Rx FIFO -Call: sEnRxFIFO(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sEnRxFIFO(ChP) \ -do { \ - (ChP)->R[0x32] = 0x08; \ - out32((ChP)->IndexAddr,&(ChP)->R[0x30]); \ -} while (0) - -/*************************************************************************** -Function: sEnRxProcessor -Purpose: Enable the receive processor -Call: sEnRxProcessor(ChP) - CHANNEL_T *ChP; Ptr to channel structure -Comments: This function is used to start the receive processor. When - the channel is in the reset state the receive processor is not - running. This is done to prevent the receive processor from - executing invalid microcode instructions prior to the - downloading of the microcode. - -Warnings: This function must be called after valid microcode has been - downloaded to the AIOP, and it must not be called before the - microcode has been downloaded. -*/ -#define sEnRxProcessor(ChP) \ -do { \ - (ChP)->RxControl[2] |= RXPROC_EN; \ - out32((ChP)->IndexAddr,(ChP)->RxControl); \ -} while (0) - -/*************************************************************************** -Function: sEnRxStatusMode -Purpose: Enable the Rx status mode -Call: sEnRxStatusMode(ChP) - CHANNEL_T *ChP; Ptr to channel structure -Comments: This places the channel in the receive status mode. All subsequent - reads of receive data using sReadRxWord() will return a data byte - in the low word and a status byte in the high word. - -*/ -#define sEnRxStatusMode(ChP) sOutW((ChP)->ChanStat,STATMODE) - -/*************************************************************************** -Function: sEnTransmit -Purpose: Enable transmit -Call: sEnTransmit(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sEnTransmit(ChP) \ -do { \ - (ChP)->TxControl[3] |= TX_ENABLE; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ -} while (0) - -/*************************************************************************** -Function: sEnTxSoftFlowCtl -Purpose: Enable Tx Software Flow Control -Call: sEnTxSoftFlowCtl(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sEnTxSoftFlowCtl(ChP) \ -do { \ - (ChP)->R[0x06] = 0xc5; \ - out32((ChP)->IndexAddr,&(ChP)->R[0x04]); \ -} while (0) - -/*************************************************************************** -Function: sGetAiopIntStatus -Purpose: Get the AIOP interrupt status -Call: sGetAiopIntStatus(CtlP,AiopNum) - CONTROLLER_T *CtlP; Ptr to controller structure - int AiopNum; AIOP number -Return: Byte_t: The AIOP interrupt status. Bits 0 through 7 - represent channels 0 through 7 respectively. If a - bit is set that channel is interrupting. -*/ -#define sGetAiopIntStatus(CTLP,AIOPNUM) sInB((CTLP)->AiopIntChanIO[AIOPNUM]) - -/*************************************************************************** -Function: sGetAiopNumChan -Purpose: Get the number of channels supported by an AIOP -Call: sGetAiopNumChan(CtlP,AiopNum) - CONTROLLER_T *CtlP; Ptr to controller structure - int AiopNum; AIOP number -Return: int: The number of channels supported by the AIOP -*/ -#define sGetAiopNumChan(CTLP,AIOPNUM) (CTLP)->AiopNumChan[AIOPNUM] - -/*************************************************************************** -Function: sGetChanIntID -Purpose: Get a channel's interrupt identification byte -Call: sGetChanIntID(ChP) - CHANNEL_T *ChP; Ptr to channel structure -Return: Byte_t: The channel interrupt ID. Can be any - combination of the following flags: - RXF_TRIG: Rx FIFO trigger level interrupt - TXFIFO_MT: Tx FIFO empty interrupt - SRC_INT: Special receive condition interrupt - DELTA_CD: CD change interrupt - DELTA_CTS: CTS change interrupt - DELTA_DSR: DSR change interrupt -*/ -#define sGetChanIntID(ChP) (sInB((ChP)->IntID) & (RXF_TRIG | TXFIFO_MT | SRC_INT | DELTA_CD | DELTA_CTS | DELTA_DSR)) - -/*************************************************************************** -Function: sGetChanNum -Purpose: Get the number of a channel within an AIOP -Call: sGetChanNum(ChP) - CHANNEL_T *ChP; Ptr to channel structure -Return: int: Channel number within AIOP, or NULLCHAN if channel does - not exist. -*/ -#define sGetChanNum(ChP) (ChP)->ChanNum - -/*************************************************************************** -Function: sGetChanStatus -Purpose: Get the channel status -Call: sGetChanStatus(ChP) - CHANNEL_T *ChP; Ptr to channel structure -Return: Word_t: The channel status. Can be any combination of - the following flags: - LOW BYTE FLAGS - CTS_ACT: CTS input asserted - DSR_ACT: DSR input asserted - CD_ACT: CD input asserted - TXFIFOMT: Tx FIFO is empty - TXSHRMT: Tx shift register is empty - RDA: Rx data available - - HIGH BYTE FLAGS - STATMODE: status mode enable bit - RXFOVERFL: receive FIFO overflow - RX2MATCH: receive compare byte 2 match - RX1MATCH: receive compare byte 1 match - RXBREAK: received BREAK - RXFRAME: received framing error - RXPARITY: received parity error -Warnings: This function will clear the high byte flags in the Channel - Status Register. -*/ -#define sGetChanStatus(ChP) sInW((ChP)->ChanStat) - -/*************************************************************************** -Function: sGetChanStatusLo -Purpose: Get the low byte only of the channel status -Call: sGetChanStatusLo(ChP) - CHANNEL_T *ChP; Ptr to channel structure -Return: Byte_t: The channel status low byte. Can be any combination - of the following flags: - CTS_ACT: CTS input asserted - DSR_ACT: DSR input asserted - CD_ACT: CD input asserted - TXFIFOMT: Tx FIFO is empty - TXSHRMT: Tx shift register is empty - RDA: Rx data available -*/ -#define sGetChanStatusLo(ChP) sInB((ByteIO_t)(ChP)->ChanStat) - -/********************************************************************** - * Get RI status of channel - * Defined as a function in rocket.c -aes - */ -#if 0 -#define sGetChanRI(ChP) ((ChP)->CtlP->AltChanRingIndicator ? \ - (sInB((ByteIO_t)((ChP)->ChanStat+8)) & DSR_ACT) : \ - (((ChP)->CtlP->boardType == ROCKET_TYPE_PC104) ? \ - (!(sInB((ChP)->CtlP->AiopIO[3]) & sBitMapSetTbl[(ChP)->ChanNum])) : \ - 0)) -#endif - -/*************************************************************************** -Function: sGetControllerIntStatus -Purpose: Get the controller interrupt status -Call: sGetControllerIntStatus(CtlP) - CONTROLLER_T *CtlP; Ptr to controller structure -Return: Byte_t: The controller interrupt status in the lower 4 - bits. Bits 0 through 3 represent AIOP's 0 - through 3 respectively. If a bit is set that - AIOP is interrupting. Bits 4 through 7 will - always be cleared. -*/ -#define sGetControllerIntStatus(CTLP) (sInB((CTLP)->MReg1IO) & 0x0f) - -/*************************************************************************** -Function: sPCIGetControllerIntStatus -Purpose: Get the controller interrupt status -Call: sPCIGetControllerIntStatus(CtlP) - CONTROLLER_T *CtlP; Ptr to controller structure -Return: unsigned char: The controller interrupt status in the lower 4 - bits and bit 4. Bits 0 through 3 represent AIOP's 0 - through 3 respectively. Bit 4 is set if the int - was generated from periodic. If a bit is set the - AIOP is interrupting. -*/ -#define sPCIGetControllerIntStatus(CTLP) \ - ((CTLP)->isUPCI ? \ - (sInW((CTLP)->PCIIO2) & UPCI_AIOP_INTR_BITS) : \ - ((sInW((CTLP)->PCIIO) >> 8) & AIOP_INTR_BITS)) - -/*************************************************************************** - -Function: sGetRxCnt -Purpose: Get the number of data bytes in the Rx FIFO -Call: sGetRxCnt(ChP) - CHANNEL_T *ChP; Ptr to channel structure -Return: int: The number of data bytes in the Rx FIFO. -Comments: Byte read of count register is required to obtain Rx count. - -*/ -#define sGetRxCnt(ChP) sInW((ChP)->TxRxCount) - -/*************************************************************************** -Function: sGetTxCnt -Purpose: Get the number of data bytes in the Tx FIFO -Call: sGetTxCnt(ChP) - CHANNEL_T *ChP; Ptr to channel structure -Return: Byte_t: The number of data bytes in the Tx FIFO. -Comments: Byte read of count register is required to obtain Tx count. - -*/ -#define sGetTxCnt(ChP) sInB((ByteIO_t)(ChP)->TxRxCount) - -/***************************************************************************** -Function: sGetTxRxDataIO -Purpose: Get the I/O address of a channel's TxRx Data register -Call: sGetTxRxDataIO(ChP) - CHANNEL_T *ChP; Ptr to channel structure -Return: WordIO_t: I/O address of a channel's TxRx Data register -*/ -#define sGetTxRxDataIO(ChP) (ChP)->TxRxData - -/*************************************************************************** -Function: sInitChanDefaults -Purpose: Initialize a channel structure to it's default state. -Call: sInitChanDefaults(ChP) - CHANNEL_T *ChP; Ptr to the channel structure -Comments: This function must be called once for every channel structure - that exists before any other SSCI calls can be made. - -*/ -#define sInitChanDefaults(ChP) \ -do { \ - (ChP)->CtlP = NULLCTLPTR; \ - (ChP)->AiopNum = NULLAIOP; \ - (ChP)->ChanID = AIOPID_NULL; \ - (ChP)->ChanNum = NULLCHAN; \ -} while (0) - -/*************************************************************************** -Function: sResetAiopByNum -Purpose: Reset the AIOP by number -Call: sResetAiopByNum(CTLP,AIOPNUM) - CONTROLLER_T CTLP; Ptr to controller structure - AIOPNUM; AIOP index -*/ -#define sResetAiopByNum(CTLP,AIOPNUM) \ -do { \ - sOutB((CTLP)->AiopIO[(AIOPNUM)]+_CMD_REG,RESET_ALL); \ - sOutB((CTLP)->AiopIO[(AIOPNUM)]+_CMD_REG,0x0); \ -} while (0) - -/*************************************************************************** -Function: sSendBreak -Purpose: Send a transmit BREAK signal -Call: sSendBreak(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sSendBreak(ChP) \ -do { \ - (ChP)->TxControl[3] |= SETBREAK; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ -} while (0) - -/*************************************************************************** -Function: sSetBaud -Purpose: Set baud rate -Call: sSetBaud(ChP,Divisor) - CHANNEL_T *ChP; Ptr to channel structure - Word_t Divisor; 16 bit baud rate divisor for channel -*/ -#define sSetBaud(ChP,DIVISOR) \ -do { \ - (ChP)->BaudDiv[2] = (Byte_t)(DIVISOR); \ - (ChP)->BaudDiv[3] = (Byte_t)((DIVISOR) >> 8); \ - out32((ChP)->IndexAddr,(ChP)->BaudDiv); \ -} while (0) - -/*************************************************************************** -Function: sSetData7 -Purpose: Set data bits to 7 -Call: sSetData7(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sSetData7(ChP) \ -do { \ - (ChP)->TxControl[2] &= ~DATA8BIT; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ -} while (0) - -/*************************************************************************** -Function: sSetData8 -Purpose: Set data bits to 8 -Call: sSetData8(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sSetData8(ChP) \ -do { \ - (ChP)->TxControl[2] |= DATA8BIT; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ -} while (0) - -/*************************************************************************** -Function: sSetDTR -Purpose: Set the DTR output -Call: sSetDTR(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sSetDTR(ChP) \ -do { \ - (ChP)->TxControl[3] |= SET_DTR; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ -} while (0) - -/*************************************************************************** -Function: sSetEvenParity -Purpose: Set even parity -Call: sSetEvenParity(ChP) - CHANNEL_T *ChP; Ptr to channel structure -Comments: Function sSetParity() can be used in place of functions sEnParity(), - sDisParity(), sSetOddParity(), and sSetEvenParity(). - -Warnings: This function has no effect unless parity is enabled with function - sEnParity(). -*/ -#define sSetEvenParity(ChP) \ -do { \ - (ChP)->TxControl[2] |= EVEN_PAR; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ -} while (0) - -/*************************************************************************** -Function: sSetOddParity -Purpose: Set odd parity -Call: sSetOddParity(ChP) - CHANNEL_T *ChP; Ptr to channel structure -Comments: Function sSetParity() can be used in place of functions sEnParity(), - sDisParity(), sSetOddParity(), and sSetEvenParity(). - -Warnings: This function has no effect unless parity is enabled with function - sEnParity(). -*/ -#define sSetOddParity(ChP) \ -do { \ - (ChP)->TxControl[2] &= ~EVEN_PAR; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ -} while (0) - -/*************************************************************************** -Function: sSetRTS -Purpose: Set the RTS output -Call: sSetRTS(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sSetRTS(ChP) \ -do { \ - if ((ChP)->rtsToggle) break; \ - (ChP)->TxControl[3] |= SET_RTS; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ -} while (0) - -/*************************************************************************** -Function: sSetRxTrigger -Purpose: Set the Rx FIFO trigger level -Call: sSetRxProcessor(ChP,Level) - CHANNEL_T *ChP; Ptr to channel structure - Byte_t Level; Number of characters in Rx FIFO at which the - interrupt will be generated. Can be any of the following flags: - - TRIG_NO: no trigger - TRIG_1: 1 character in FIFO - TRIG_1_2: FIFO 1/2 full - TRIG_7_8: FIFO 7/8 full -Comments: An interrupt will be generated when the trigger level is reached - only if function sEnInterrupt() has been called with flag - RXINT_EN set. The RXF_TRIG flag in the Interrupt Idenfification - register will be set whenever the trigger level is reached - regardless of the setting of RXINT_EN. - -*/ -#define sSetRxTrigger(ChP,LEVEL) \ -do { \ - (ChP)->RxControl[2] &= ~TRIG_MASK; \ - (ChP)->RxControl[2] |= LEVEL; \ - out32((ChP)->IndexAddr,(ChP)->RxControl); \ -} while (0) - -/*************************************************************************** -Function: sSetStop1 -Purpose: Set stop bits to 1 -Call: sSetStop1(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sSetStop1(ChP) \ -do { \ - (ChP)->TxControl[2] &= ~STOP2; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ -} while (0) - -/*************************************************************************** -Function: sSetStop2 -Purpose: Set stop bits to 2 -Call: sSetStop2(ChP) - CHANNEL_T *ChP; Ptr to channel structure -*/ -#define sSetStop2(ChP) \ -do { \ - (ChP)->TxControl[2] |= STOP2; \ - out32((ChP)->IndexAddr,(ChP)->TxControl); \ -} while (0) - -/*************************************************************************** -Function: sSetTxXOFFChar -Purpose: Set the Tx XOFF flow control character -Call: sSetTxXOFFChar(ChP,Ch) - CHANNEL_T *ChP; Ptr to channel structure - Byte_t Ch; The value to set the Tx XOFF character to -*/ -#define sSetTxXOFFChar(ChP,CH) \ -do { \ - (ChP)->R[0x07] = (CH); \ - out32((ChP)->IndexAddr,&(ChP)->R[0x04]); \ -} while (0) - -/*************************************************************************** -Function: sSetTxXONChar -Purpose: Set the Tx XON flow control character -Call: sSetTxXONChar(ChP,Ch) - CHANNEL_T *ChP; Ptr to channel structure - Byte_t Ch; The value to set the Tx XON character to -*/ -#define sSetTxXONChar(ChP,CH) \ -do { \ - (ChP)->R[0x0b] = (CH); \ - out32((ChP)->IndexAddr,&(ChP)->R[0x08]); \ -} while (0) - -/*************************************************************************** -Function: sStartRxProcessor -Purpose: Start a channel's receive processor -Call: sStartRxProcessor(ChP) - CHANNEL_T *ChP; Ptr to channel structure -Comments: This function is used to start a Rx processor after it was - stopped with sStopRxProcessor() or sStopSWInFlowCtl(). It - will restart both the Rx processor and software input flow control. - -*/ -#define sStartRxProcessor(ChP) out32((ChP)->IndexAddr,&(ChP)->R[0]) - -/*************************************************************************** -Function: sWriteTxByte -Purpose: Write a transmit data byte to a channel. - ByteIO_t io: Channel transmit register I/O address. This can - be obtained with sGetTxRxDataIO(). - Byte_t Data; The transmit data byte. -Warnings: This function writes the data byte without checking to see if - sMaxTxSize is exceeded in the Tx FIFO. -*/ -#define sWriteTxByte(IO,DATA) sOutB(IO,DATA) - -/* - * Begin Linux specific definitions for the Rocketport driver - * - * This code is Copyright Theodore Ts'o, 1995-1997 - */ - -struct r_port { - int magic; - struct tty_port port; - int line; - int flags; /* Don't yet match the ASY_ flags!! */ - unsigned int board:3; - unsigned int aiop:2; - unsigned int chan:3; - CONTROLLER_t *ctlp; - CHANNEL_t channel; - int intmask; - int xmit_fifo_room; /* room in xmit fifo */ - unsigned char *xmit_buf; - int xmit_head; - int xmit_tail; - int xmit_cnt; - int cd_status; - int ignore_status_mask; - int read_status_mask; - int cps; - - struct completion close_wait; /* Not yet matching the core */ - spinlock_t slock; - struct mutex write_mtx; -}; - -#define RPORT_MAGIC 0x525001 - -#define NUM_BOARDS 8 -#define MAX_RP_PORTS (32*NUM_BOARDS) - -/* - * The size of the xmit buffer is 1 page, or 4096 bytes - */ -#define XMIT_BUF_SIZE 4096 - -/* number of characters left in xmit buffer before we ask for more */ -#define WAKEUP_CHARS 256 - -/* - * Assigned major numbers for the Comtrol Rocketport - */ -#define TTY_ROCKET_MAJOR 46 -#define CUA_ROCKET_MAJOR 47 - -#ifdef PCI_VENDOR_ID_RP -#undef PCI_VENDOR_ID_RP -#undef PCI_DEVICE_ID_RP8OCTA -#undef PCI_DEVICE_ID_RP8INTF -#undef PCI_DEVICE_ID_RP16INTF -#undef PCI_DEVICE_ID_RP32INTF -#undef PCI_DEVICE_ID_URP8OCTA -#undef PCI_DEVICE_ID_URP8INTF -#undef PCI_DEVICE_ID_URP16INTF -#undef PCI_DEVICE_ID_CRP16INTF -#undef PCI_DEVICE_ID_URP32INTF -#endif - -/* Comtrol PCI Vendor ID */ -#define PCI_VENDOR_ID_RP 0x11fe - -/* Comtrol Device ID's */ -#define PCI_DEVICE_ID_RP32INTF 0x0001 /* Rocketport 32 port w/external I/F */ -#define PCI_DEVICE_ID_RP8INTF 0x0002 /* Rocketport 8 port w/external I/F */ -#define PCI_DEVICE_ID_RP16INTF 0x0003 /* Rocketport 16 port w/external I/F */ -#define PCI_DEVICE_ID_RP4QUAD 0x0004 /* Rocketport 4 port w/quad cable */ -#define PCI_DEVICE_ID_RP8OCTA 0x0005 /* Rocketport 8 port w/octa cable */ -#define PCI_DEVICE_ID_RP8J 0x0006 /* Rocketport 8 port w/RJ11 connectors */ -#define PCI_DEVICE_ID_RP4J 0x0007 /* Rocketport 4 port w/RJ11 connectors */ -#define PCI_DEVICE_ID_RP8SNI 0x0008 /* Rocketport 8 port w/ DB78 SNI (Siemens) connector */ -#define PCI_DEVICE_ID_RP16SNI 0x0009 /* Rocketport 16 port w/ DB78 SNI (Siemens) connector */ -#define PCI_DEVICE_ID_RPP4 0x000A /* Rocketport Plus 4 port */ -#define PCI_DEVICE_ID_RPP8 0x000B /* Rocketport Plus 8 port */ -#define PCI_DEVICE_ID_RP6M 0x000C /* RocketModem 6 port */ -#define PCI_DEVICE_ID_RP4M 0x000D /* RocketModem 4 port */ -#define PCI_DEVICE_ID_RP2_232 0x000E /* Rocketport Plus 2 port RS232 */ -#define PCI_DEVICE_ID_RP2_422 0x000F /* Rocketport Plus 2 port RS422 */ - -/* Universal PCI boards */ -#define PCI_DEVICE_ID_URP32INTF 0x0801 /* Rocketport UPCI 32 port w/external I/F */ -#define PCI_DEVICE_ID_URP8INTF 0x0802 /* Rocketport UPCI 8 port w/external I/F */ -#define PCI_DEVICE_ID_URP16INTF 0x0803 /* Rocketport UPCI 16 port w/external I/F */ -#define PCI_DEVICE_ID_URP8OCTA 0x0805 /* Rocketport UPCI 8 port w/octa cable */ -#define PCI_DEVICE_ID_UPCI_RM3_8PORT 0x080C /* Rocketmodem III 8 port */ -#define PCI_DEVICE_ID_UPCI_RM3_4PORT 0x080D /* Rocketmodem III 4 port */ - -/* Compact PCI device */ -#define PCI_DEVICE_ID_CRP16INTF 0x0903 /* Rocketport Compact PCI 16 port w/external I/F */ - diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c deleted file mode 100644 index 18888d005a0a..000000000000 --- a/drivers/char/synclink.c +++ /dev/null @@ -1,8119 +0,0 @@ -/* - * linux/drivers/char/synclink.c - * - * $Id: synclink.c,v 4.38 2005/11/07 16:30:34 paulkf Exp $ - * - * Device driver for Microgate SyncLink ISA and PCI - * high speed multiprotocol serial adapters. - * - * written by Paul Fulghum for Microgate Corporation - * paulkf@microgate.com - * - * Microgate and SyncLink are trademarks of Microgate Corporation - * - * Derived from serial.c written by Theodore Ts'o and Linus Torvalds - * - * Original release 01/11/99 - * - * This code is released under the GNU General Public License (GPL) - * - * This driver is primarily intended for use in synchronous - * HDLC mode. Asynchronous mode is also provided. - * - * When operating in synchronous mode, each call to mgsl_write() - * contains exactly one complete HDLC frame. Calling mgsl_put_char - * will start assembling an HDLC frame that will not be sent until - * mgsl_flush_chars or mgsl_write is called. - * - * Synchronous receive data is reported as complete frames. To accomplish - * this, the TTY flip buffer is bypassed (too small to hold largest - * frame and may fragment frames) and the line discipline - * receive entry point is called directly. - * - * This driver has been tested with a slightly modified ppp.c driver - * for synchronous PPP. - * - * 2000/02/16 - * Added interface for syncppp.c driver (an alternate synchronous PPP - * implementation that also supports Cisco HDLC). Each device instance - * registers as a tty device AND a network device (if dosyncppp option - * is set for the device). The functionality is determined by which - * device interface is opened. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if defined(__i386__) -# define BREAKPOINT() asm(" int $3"); -#else -# define BREAKPOINT() { } -#endif - -#define MAX_ISA_DEVICES 10 -#define MAX_PCI_DEVICES 10 -#define MAX_TOTAL_DEVICES 20 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_MODULE)) -#define SYNCLINK_GENERIC_HDLC 1 -#else -#define SYNCLINK_GENERIC_HDLC 0 -#endif - -#define GET_USER(error,value,addr) error = get_user(value,addr) -#define COPY_FROM_USER(error,dest,src,size) error = copy_from_user(dest,src,size) ? -EFAULT : 0 -#define PUT_USER(error,value,addr) error = put_user(value,addr) -#define COPY_TO_USER(error,dest,src,size) error = copy_to_user(dest,src,size) ? -EFAULT : 0 - -#include - -#define RCLRVALUE 0xffff - -static MGSL_PARAMS default_params = { - MGSL_MODE_HDLC, /* unsigned long mode */ - 0, /* unsigned char loopback; */ - HDLC_FLAG_UNDERRUN_ABORT15, /* unsigned short flags; */ - HDLC_ENCODING_NRZI_SPACE, /* unsigned char encoding; */ - 0, /* unsigned long clock_speed; */ - 0xff, /* unsigned char addr_filter; */ - HDLC_CRC_16_CCITT, /* unsigned short crc_type; */ - HDLC_PREAMBLE_LENGTH_8BITS, /* unsigned char preamble_length; */ - HDLC_PREAMBLE_PATTERN_NONE, /* unsigned char preamble; */ - 9600, /* unsigned long data_rate; */ - 8, /* unsigned char data_bits; */ - 1, /* unsigned char stop_bits; */ - ASYNC_PARITY_NONE /* unsigned char parity; */ -}; - -#define SHARED_MEM_ADDRESS_SIZE 0x40000 -#define BUFFERLISTSIZE 4096 -#define DMABUFFERSIZE 4096 -#define MAXRXFRAMES 7 - -typedef struct _DMABUFFERENTRY -{ - u32 phys_addr; /* 32-bit flat physical address of data buffer */ - volatile u16 count; /* buffer size/data count */ - volatile u16 status; /* Control/status field */ - volatile u16 rcc; /* character count field */ - u16 reserved; /* padding required by 16C32 */ - u32 link; /* 32-bit flat link to next buffer entry */ - char *virt_addr; /* virtual address of data buffer */ - u32 phys_entry; /* physical address of this buffer entry */ - dma_addr_t dma_addr; -} DMABUFFERENTRY, *DMAPBUFFERENTRY; - -/* The queue of BH actions to be performed */ - -#define BH_RECEIVE 1 -#define BH_TRANSMIT 2 -#define BH_STATUS 4 - -#define IO_PIN_SHUTDOWN_LIMIT 100 - -struct _input_signal_events { - int ri_up; - int ri_down; - int dsr_up; - int dsr_down; - int dcd_up; - int dcd_down; - int cts_up; - int cts_down; -}; - -/* transmit holding buffer definitions*/ -#define MAX_TX_HOLDING_BUFFERS 5 -struct tx_holding_buffer { - int buffer_size; - unsigned char * buffer; -}; - - -/* - * Device instance data structure - */ - -struct mgsl_struct { - int magic; - struct tty_port port; - int line; - int hw_version; - - struct mgsl_icount icount; - - int timeout; - int x_char; /* xon/xoff character */ - u16 read_status_mask; - u16 ignore_status_mask; - unsigned char *xmit_buf; - int xmit_head; - int xmit_tail; - int xmit_cnt; - - wait_queue_head_t status_event_wait_q; - wait_queue_head_t event_wait_q; - struct timer_list tx_timer; /* HDLC transmit timeout timer */ - struct mgsl_struct *next_device; /* device list link */ - - spinlock_t irq_spinlock; /* spinlock for synchronizing with ISR */ - struct work_struct task; /* task structure for scheduling bh */ - - u32 EventMask; /* event trigger mask */ - u32 RecordedEvents; /* pending events */ - - u32 max_frame_size; /* as set by device config */ - - u32 pending_bh; - - bool bh_running; /* Protection from multiple */ - int isr_overflow; - bool bh_requested; - - int dcd_chkcount; /* check counts to prevent */ - int cts_chkcount; /* too many IRQs if a signal */ - int dsr_chkcount; /* is floating */ - int ri_chkcount; - - char *buffer_list; /* virtual address of Rx & Tx buffer lists */ - u32 buffer_list_phys; - dma_addr_t buffer_list_dma_addr; - - unsigned int rx_buffer_count; /* count of total allocated Rx buffers */ - DMABUFFERENTRY *rx_buffer_list; /* list of receive buffer entries */ - unsigned int current_rx_buffer; - - int num_tx_dma_buffers; /* number of tx dma frames required */ - int tx_dma_buffers_used; - unsigned int tx_buffer_count; /* count of total allocated Tx buffers */ - DMABUFFERENTRY *tx_buffer_list; /* list of transmit buffer entries */ - int start_tx_dma_buffer; /* tx dma buffer to start tx dma operation */ - int current_tx_buffer; /* next tx dma buffer to be loaded */ - - unsigned char *intermediate_rxbuffer; - - int num_tx_holding_buffers; /* number of tx holding buffer allocated */ - int get_tx_holding_index; /* next tx holding buffer for adapter to load */ - int put_tx_holding_index; /* next tx holding buffer to store user request */ - int tx_holding_count; /* number of tx holding buffers waiting */ - struct tx_holding_buffer tx_holding_buffers[MAX_TX_HOLDING_BUFFERS]; - - bool rx_enabled; - bool rx_overflow; - bool rx_rcc_underrun; - - bool tx_enabled; - bool tx_active; - u32 idle_mode; - - u16 cmr_value; - u16 tcsr_value; - - char device_name[25]; /* device instance name */ - - unsigned int bus_type; /* expansion bus type (ISA,EISA,PCI) */ - unsigned char bus; /* expansion bus number (zero based) */ - unsigned char function; /* PCI device number */ - - unsigned int io_base; /* base I/O address of adapter */ - unsigned int io_addr_size; /* size of the I/O address range */ - bool io_addr_requested; /* true if I/O address requested */ - - unsigned int irq_level; /* interrupt level */ - unsigned long irq_flags; - bool irq_requested; /* true if IRQ requested */ - - unsigned int dma_level; /* DMA channel */ - bool dma_requested; /* true if dma channel requested */ - - u16 mbre_bit; - u16 loopback_bits; - u16 usc_idle_mode; - - MGSL_PARAMS params; /* communications parameters */ - - unsigned char serial_signals; /* current serial signal states */ - - bool irq_occurred; /* for diagnostics use */ - unsigned int init_error; /* Initialization startup error (DIAGS) */ - int fDiagnosticsmode; /* Driver in Diagnostic mode? (DIAGS) */ - - u32 last_mem_alloc; - unsigned char* memory_base; /* shared memory address (PCI only) */ - u32 phys_memory_base; - bool shared_mem_requested; - - unsigned char* lcr_base; /* local config registers (PCI only) */ - u32 phys_lcr_base; - u32 lcr_offset; - bool lcr_mem_requested; - - u32 misc_ctrl_value; - char flag_buf[MAX_ASYNC_BUFFER_SIZE]; - char char_buf[MAX_ASYNC_BUFFER_SIZE]; - bool drop_rts_on_tx_done; - - bool loopmode_insert_requested; - bool loopmode_send_done_requested; - - struct _input_signal_events input_signal_events; - - /* generic HDLC device parts */ - int netcount; - spinlock_t netlock; - -#if SYNCLINK_GENERIC_HDLC - struct net_device *netdev; -#endif -}; - -#define MGSL_MAGIC 0x5401 - -/* - * The size of the serial xmit buffer is 1 page, or 4096 bytes - */ -#ifndef SERIAL_XMIT_SIZE -#define SERIAL_XMIT_SIZE 4096 -#endif - -/* - * These macros define the offsets used in calculating the - * I/O address of the specified USC registers. - */ - - -#define DCPIN 2 /* Bit 1 of I/O address */ -#define SDPIN 4 /* Bit 2 of I/O address */ - -#define DCAR 0 /* DMA command/address register */ -#define CCAR SDPIN /* channel command/address register */ -#define DATAREG DCPIN + SDPIN /* serial data register */ -#define MSBONLY 0x41 -#define LSBONLY 0x40 - -/* - * These macros define the register address (ordinal number) - * used for writing address/value pairs to the USC. - */ - -#define CMR 0x02 /* Channel mode Register */ -#define CCSR 0x04 /* Channel Command/status Register */ -#define CCR 0x06 /* Channel Control Register */ -#define PSR 0x08 /* Port status Register */ -#define PCR 0x0a /* Port Control Register */ -#define TMDR 0x0c /* Test mode Data Register */ -#define TMCR 0x0e /* Test mode Control Register */ -#define CMCR 0x10 /* Clock mode Control Register */ -#define HCR 0x12 /* Hardware Configuration Register */ -#define IVR 0x14 /* Interrupt Vector Register */ -#define IOCR 0x16 /* Input/Output Control Register */ -#define ICR 0x18 /* Interrupt Control Register */ -#define DCCR 0x1a /* Daisy Chain Control Register */ -#define MISR 0x1c /* Misc Interrupt status Register */ -#define SICR 0x1e /* status Interrupt Control Register */ -#define RDR 0x20 /* Receive Data Register */ -#define RMR 0x22 /* Receive mode Register */ -#define RCSR 0x24 /* Receive Command/status Register */ -#define RICR 0x26 /* Receive Interrupt Control Register */ -#define RSR 0x28 /* Receive Sync Register */ -#define RCLR 0x2a /* Receive count Limit Register */ -#define RCCR 0x2c /* Receive Character count Register */ -#define TC0R 0x2e /* Time Constant 0 Register */ -#define TDR 0x30 /* Transmit Data Register */ -#define TMR 0x32 /* Transmit mode Register */ -#define TCSR 0x34 /* Transmit Command/status Register */ -#define TICR 0x36 /* Transmit Interrupt Control Register */ -#define TSR 0x38 /* Transmit Sync Register */ -#define TCLR 0x3a /* Transmit count Limit Register */ -#define TCCR 0x3c /* Transmit Character count Register */ -#define TC1R 0x3e /* Time Constant 1 Register */ - - -/* - * MACRO DEFINITIONS FOR DMA REGISTERS - */ - -#define DCR 0x06 /* DMA Control Register (shared) */ -#define DACR 0x08 /* DMA Array count Register (shared) */ -#define BDCR 0x12 /* Burst/Dwell Control Register (shared) */ -#define DIVR 0x14 /* DMA Interrupt Vector Register (shared) */ -#define DICR 0x18 /* DMA Interrupt Control Register (shared) */ -#define CDIR 0x1a /* Clear DMA Interrupt Register (shared) */ -#define SDIR 0x1c /* Set DMA Interrupt Register (shared) */ - -#define TDMR 0x02 /* Transmit DMA mode Register */ -#define TDIAR 0x1e /* Transmit DMA Interrupt Arm Register */ -#define TBCR 0x2a /* Transmit Byte count Register */ -#define TARL 0x2c /* Transmit Address Register (low) */ -#define TARU 0x2e /* Transmit Address Register (high) */ -#define NTBCR 0x3a /* Next Transmit Byte count Register */ -#define NTARL 0x3c /* Next Transmit Address Register (low) */ -#define NTARU 0x3e /* Next Transmit Address Register (high) */ - -#define RDMR 0x82 /* Receive DMA mode Register (non-shared) */ -#define RDIAR 0x9e /* Receive DMA Interrupt Arm Register */ -#define RBCR 0xaa /* Receive Byte count Register */ -#define RARL 0xac /* Receive Address Register (low) */ -#define RARU 0xae /* Receive Address Register (high) */ -#define NRBCR 0xba /* Next Receive Byte count Register */ -#define NRARL 0xbc /* Next Receive Address Register (low) */ -#define NRARU 0xbe /* Next Receive Address Register (high) */ - - -/* - * MACRO DEFINITIONS FOR MODEM STATUS BITS - */ - -#define MODEMSTATUS_DTR 0x80 -#define MODEMSTATUS_DSR 0x40 -#define MODEMSTATUS_RTS 0x20 -#define MODEMSTATUS_CTS 0x10 -#define MODEMSTATUS_RI 0x04 -#define MODEMSTATUS_DCD 0x01 - - -/* - * Channel Command/Address Register (CCAR) Command Codes - */ - -#define RTCmd_Null 0x0000 -#define RTCmd_ResetHighestIus 0x1000 -#define RTCmd_TriggerChannelLoadDma 0x2000 -#define RTCmd_TriggerRxDma 0x2800 -#define RTCmd_TriggerTxDma 0x3000 -#define RTCmd_TriggerRxAndTxDma 0x3800 -#define RTCmd_PurgeRxFifo 0x4800 -#define RTCmd_PurgeTxFifo 0x5000 -#define RTCmd_PurgeRxAndTxFifo 0x5800 -#define RTCmd_LoadRcc 0x6800 -#define RTCmd_LoadTcc 0x7000 -#define RTCmd_LoadRccAndTcc 0x7800 -#define RTCmd_LoadTC0 0x8800 -#define RTCmd_LoadTC1 0x9000 -#define RTCmd_LoadTC0AndTC1 0x9800 -#define RTCmd_SerialDataLSBFirst 0xa000 -#define RTCmd_SerialDataMSBFirst 0xa800 -#define RTCmd_SelectBigEndian 0xb000 -#define RTCmd_SelectLittleEndian 0xb800 - - -/* - * DMA Command/Address Register (DCAR) Command Codes - */ - -#define DmaCmd_Null 0x0000 -#define DmaCmd_ResetTxChannel 0x1000 -#define DmaCmd_ResetRxChannel 0x1200 -#define DmaCmd_StartTxChannel 0x2000 -#define DmaCmd_StartRxChannel 0x2200 -#define DmaCmd_ContinueTxChannel 0x3000 -#define DmaCmd_ContinueRxChannel 0x3200 -#define DmaCmd_PauseTxChannel 0x4000 -#define DmaCmd_PauseRxChannel 0x4200 -#define DmaCmd_AbortTxChannel 0x5000 -#define DmaCmd_AbortRxChannel 0x5200 -#define DmaCmd_InitTxChannel 0x7000 -#define DmaCmd_InitRxChannel 0x7200 -#define DmaCmd_ResetHighestDmaIus 0x8000 -#define DmaCmd_ResetAllChannels 0x9000 -#define DmaCmd_StartAllChannels 0xa000 -#define DmaCmd_ContinueAllChannels 0xb000 -#define DmaCmd_PauseAllChannels 0xc000 -#define DmaCmd_AbortAllChannels 0xd000 -#define DmaCmd_InitAllChannels 0xf000 - -#define TCmd_Null 0x0000 -#define TCmd_ClearTxCRC 0x2000 -#define TCmd_SelectTicrTtsaData 0x4000 -#define TCmd_SelectTicrTxFifostatus 0x5000 -#define TCmd_SelectTicrIntLevel 0x6000 -#define TCmd_SelectTicrdma_level 0x7000 -#define TCmd_SendFrame 0x8000 -#define TCmd_SendAbort 0x9000 -#define TCmd_EnableDleInsertion 0xc000 -#define TCmd_DisableDleInsertion 0xd000 -#define TCmd_ClearEofEom 0xe000 -#define TCmd_SetEofEom 0xf000 - -#define RCmd_Null 0x0000 -#define RCmd_ClearRxCRC 0x2000 -#define RCmd_EnterHuntmode 0x3000 -#define RCmd_SelectRicrRtsaData 0x4000 -#define RCmd_SelectRicrRxFifostatus 0x5000 -#define RCmd_SelectRicrIntLevel 0x6000 -#define RCmd_SelectRicrdma_level 0x7000 - -/* - * Bits for enabling and disabling IRQs in Interrupt Control Register (ICR) - */ - -#define RECEIVE_STATUS BIT5 -#define RECEIVE_DATA BIT4 -#define TRANSMIT_STATUS BIT3 -#define TRANSMIT_DATA BIT2 -#define IO_PIN BIT1 -#define MISC BIT0 - - -/* - * Receive status Bits in Receive Command/status Register RCSR - */ - -#define RXSTATUS_SHORT_FRAME BIT8 -#define RXSTATUS_CODE_VIOLATION BIT8 -#define RXSTATUS_EXITED_HUNT BIT7 -#define RXSTATUS_IDLE_RECEIVED BIT6 -#define RXSTATUS_BREAK_RECEIVED BIT5 -#define RXSTATUS_ABORT_RECEIVED BIT5 -#define RXSTATUS_RXBOUND BIT4 -#define RXSTATUS_CRC_ERROR BIT3 -#define RXSTATUS_FRAMING_ERROR BIT3 -#define RXSTATUS_ABORT BIT2 -#define RXSTATUS_PARITY_ERROR BIT2 -#define RXSTATUS_OVERRUN BIT1 -#define RXSTATUS_DATA_AVAILABLE BIT0 -#define RXSTATUS_ALL 0x01f6 -#define usc_UnlatchRxstatusBits(a,b) usc_OutReg( (a), RCSR, (u16)((b) & RXSTATUS_ALL) ) - -/* - * Values for setting transmit idle mode in - * Transmit Control/status Register (TCSR) - */ -#define IDLEMODE_FLAGS 0x0000 -#define IDLEMODE_ALT_ONE_ZERO 0x0100 -#define IDLEMODE_ZERO 0x0200 -#define IDLEMODE_ONE 0x0300 -#define IDLEMODE_ALT_MARK_SPACE 0x0500 -#define IDLEMODE_SPACE 0x0600 -#define IDLEMODE_MARK 0x0700 -#define IDLEMODE_MASK 0x0700 - -/* - * IUSC revision identifiers - */ -#define IUSC_SL1660 0x4d44 -#define IUSC_PRE_SL1660 0x4553 - -/* - * Transmit status Bits in Transmit Command/status Register (TCSR) - */ - -#define TCSR_PRESERVE 0x0F00 - -#define TCSR_UNDERWAIT BIT11 -#define TXSTATUS_PREAMBLE_SENT BIT7 -#define TXSTATUS_IDLE_SENT BIT6 -#define TXSTATUS_ABORT_SENT BIT5 -#define TXSTATUS_EOF_SENT BIT4 -#define TXSTATUS_EOM_SENT BIT4 -#define TXSTATUS_CRC_SENT BIT3 -#define TXSTATUS_ALL_SENT BIT2 -#define TXSTATUS_UNDERRUN BIT1 -#define TXSTATUS_FIFO_EMPTY BIT0 -#define TXSTATUS_ALL 0x00fa -#define usc_UnlatchTxstatusBits(a,b) usc_OutReg( (a), TCSR, (u16)((a)->tcsr_value + ((b) & 0x00FF)) ) - - -#define MISCSTATUS_RXC_LATCHED BIT15 -#define MISCSTATUS_RXC BIT14 -#define MISCSTATUS_TXC_LATCHED BIT13 -#define MISCSTATUS_TXC BIT12 -#define MISCSTATUS_RI_LATCHED BIT11 -#define MISCSTATUS_RI BIT10 -#define MISCSTATUS_DSR_LATCHED BIT9 -#define MISCSTATUS_DSR BIT8 -#define MISCSTATUS_DCD_LATCHED BIT7 -#define MISCSTATUS_DCD BIT6 -#define MISCSTATUS_CTS_LATCHED BIT5 -#define MISCSTATUS_CTS BIT4 -#define MISCSTATUS_RCC_UNDERRUN BIT3 -#define MISCSTATUS_DPLL_NO_SYNC BIT2 -#define MISCSTATUS_BRG1_ZERO BIT1 -#define MISCSTATUS_BRG0_ZERO BIT0 - -#define usc_UnlatchIostatusBits(a,b) usc_OutReg((a),MISR,(u16)((b) & 0xaaa0)) -#define usc_UnlatchMiscstatusBits(a,b) usc_OutReg((a),MISR,(u16)((b) & 0x000f)) - -#define SICR_RXC_ACTIVE BIT15 -#define SICR_RXC_INACTIVE BIT14 -#define SICR_RXC (BIT15+BIT14) -#define SICR_TXC_ACTIVE BIT13 -#define SICR_TXC_INACTIVE BIT12 -#define SICR_TXC (BIT13+BIT12) -#define SICR_RI_ACTIVE BIT11 -#define SICR_RI_INACTIVE BIT10 -#define SICR_RI (BIT11+BIT10) -#define SICR_DSR_ACTIVE BIT9 -#define SICR_DSR_INACTIVE BIT8 -#define SICR_DSR (BIT9+BIT8) -#define SICR_DCD_ACTIVE BIT7 -#define SICR_DCD_INACTIVE BIT6 -#define SICR_DCD (BIT7+BIT6) -#define SICR_CTS_ACTIVE BIT5 -#define SICR_CTS_INACTIVE BIT4 -#define SICR_CTS (BIT5+BIT4) -#define SICR_RCC_UNDERFLOW BIT3 -#define SICR_DPLL_NO_SYNC BIT2 -#define SICR_BRG1_ZERO BIT1 -#define SICR_BRG0_ZERO BIT0 - -void usc_DisableMasterIrqBit( struct mgsl_struct *info ); -void usc_EnableMasterIrqBit( struct mgsl_struct *info ); -void usc_EnableInterrupts( struct mgsl_struct *info, u16 IrqMask ); -void usc_DisableInterrupts( struct mgsl_struct *info, u16 IrqMask ); -void usc_ClearIrqPendingBits( struct mgsl_struct *info, u16 IrqMask ); - -#define usc_EnableInterrupts( a, b ) \ - usc_OutReg( (a), ICR, (u16)((usc_InReg((a),ICR) & 0xff00) + 0xc0 + (b)) ) - -#define usc_DisableInterrupts( a, b ) \ - usc_OutReg( (a), ICR, (u16)((usc_InReg((a),ICR) & 0xff00) + 0x80 + (b)) ) - -#define usc_EnableMasterIrqBit(a) \ - usc_OutReg( (a), ICR, (u16)((usc_InReg((a),ICR) & 0x0f00) + 0xb000) ) - -#define usc_DisableMasterIrqBit(a) \ - usc_OutReg( (a), ICR, (u16)(usc_InReg((a),ICR) & 0x7f00) ) - -#define usc_ClearIrqPendingBits( a, b ) usc_OutReg( (a), DCCR, 0x40 + (b) ) - -/* - * Transmit status Bits in Transmit Control status Register (TCSR) - * and Transmit Interrupt Control Register (TICR) (except BIT2, BIT0) - */ - -#define TXSTATUS_PREAMBLE_SENT BIT7 -#define TXSTATUS_IDLE_SENT BIT6 -#define TXSTATUS_ABORT_SENT BIT5 -#define TXSTATUS_EOF BIT4 -#define TXSTATUS_CRC_SENT BIT3 -#define TXSTATUS_ALL_SENT BIT2 -#define TXSTATUS_UNDERRUN BIT1 -#define TXSTATUS_FIFO_EMPTY BIT0 - -#define DICR_MASTER BIT15 -#define DICR_TRANSMIT BIT0 -#define DICR_RECEIVE BIT1 - -#define usc_EnableDmaInterrupts(a,b) \ - usc_OutDmaReg( (a), DICR, (u16)(usc_InDmaReg((a),DICR) | (b)) ) - -#define usc_DisableDmaInterrupts(a,b) \ - usc_OutDmaReg( (a), DICR, (u16)(usc_InDmaReg((a),DICR) & ~(b)) ) - -#define usc_EnableStatusIrqs(a,b) \ - usc_OutReg( (a), SICR, (u16)(usc_InReg((a),SICR) | (b)) ) - -#define usc_DisablestatusIrqs(a,b) \ - usc_OutReg( (a), SICR, (u16)(usc_InReg((a),SICR) & ~(b)) ) - -/* Transmit status Bits in Transmit Control status Register (TCSR) */ -/* and Transmit Interrupt Control Register (TICR) (except BIT2, BIT0) */ - - -#define DISABLE_UNCONDITIONAL 0 -#define DISABLE_END_OF_FRAME 1 -#define ENABLE_UNCONDITIONAL 2 -#define ENABLE_AUTO_CTS 3 -#define ENABLE_AUTO_DCD 3 -#define usc_EnableTransmitter(a,b) \ - usc_OutReg( (a), TMR, (u16)((usc_InReg((a),TMR) & 0xfffc) | (b)) ) -#define usc_EnableReceiver(a,b) \ - usc_OutReg( (a), RMR, (u16)((usc_InReg((a),RMR) & 0xfffc) | (b)) ) - -static u16 usc_InDmaReg( struct mgsl_struct *info, u16 Port ); -static void usc_OutDmaReg( struct mgsl_struct *info, u16 Port, u16 Value ); -static void usc_DmaCmd( struct mgsl_struct *info, u16 Cmd ); - -static u16 usc_InReg( struct mgsl_struct *info, u16 Port ); -static void usc_OutReg( struct mgsl_struct *info, u16 Port, u16 Value ); -static void usc_RTCmd( struct mgsl_struct *info, u16 Cmd ); -void usc_RCmd( struct mgsl_struct *info, u16 Cmd ); -void usc_TCmd( struct mgsl_struct *info, u16 Cmd ); - -#define usc_TCmd(a,b) usc_OutReg((a), TCSR, (u16)((a)->tcsr_value + (b))) -#define usc_RCmd(a,b) usc_OutReg((a), RCSR, (b)) - -#define usc_SetTransmitSyncChars(a,s0,s1) usc_OutReg((a), TSR, (u16)(((u16)s0<<8)|(u16)s1)) - -static void usc_process_rxoverrun_sync( struct mgsl_struct *info ); -static void usc_start_receiver( struct mgsl_struct *info ); -static void usc_stop_receiver( struct mgsl_struct *info ); - -static void usc_start_transmitter( struct mgsl_struct *info ); -static void usc_stop_transmitter( struct mgsl_struct *info ); -static void usc_set_txidle( struct mgsl_struct *info ); -static void usc_load_txfifo( struct mgsl_struct *info ); - -static void usc_enable_aux_clock( struct mgsl_struct *info, u32 DataRate ); -static void usc_enable_loopback( struct mgsl_struct *info, int enable ); - -static void usc_get_serial_signals( struct mgsl_struct *info ); -static void usc_set_serial_signals( struct mgsl_struct *info ); - -static void usc_reset( struct mgsl_struct *info ); - -static void usc_set_sync_mode( struct mgsl_struct *info ); -static void usc_set_sdlc_mode( struct mgsl_struct *info ); -static void usc_set_async_mode( struct mgsl_struct *info ); -static void usc_enable_async_clock( struct mgsl_struct *info, u32 DataRate ); - -static void usc_loopback_frame( struct mgsl_struct *info ); - -static void mgsl_tx_timeout(unsigned long context); - - -static void usc_loopmode_cancel_transmit( struct mgsl_struct * info ); -static void usc_loopmode_insert_request( struct mgsl_struct * info ); -static int usc_loopmode_active( struct mgsl_struct * info); -static void usc_loopmode_send_done( struct mgsl_struct * info ); - -static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg); - -#if SYNCLINK_GENERIC_HDLC -#define dev_to_port(D) (dev_to_hdlc(D)->priv) -static void hdlcdev_tx_done(struct mgsl_struct *info); -static void hdlcdev_rx(struct mgsl_struct *info, char *buf, int size); -static int hdlcdev_init(struct mgsl_struct *info); -static void hdlcdev_exit(struct mgsl_struct *info); -#endif - -/* - * Defines a BUS descriptor value for the PCI adapter - * local bus address ranges. - */ - -#define BUS_DESCRIPTOR( WrHold, WrDly, RdDly, Nwdd, Nwad, Nxda, Nrdd, Nrad ) \ -(0x00400020 + \ -((WrHold) << 30) + \ -((WrDly) << 28) + \ -((RdDly) << 26) + \ -((Nwdd) << 20) + \ -((Nwad) << 15) + \ -((Nxda) << 13) + \ -((Nrdd) << 11) + \ -((Nrad) << 6) ) - -static void mgsl_trace_block(struct mgsl_struct *info,const char* data, int count, int xmit); - -/* - * Adapter diagnostic routines - */ -static bool mgsl_register_test( struct mgsl_struct *info ); -static bool mgsl_irq_test( struct mgsl_struct *info ); -static bool mgsl_dma_test( struct mgsl_struct *info ); -static bool mgsl_memory_test( struct mgsl_struct *info ); -static int mgsl_adapter_test( struct mgsl_struct *info ); - -/* - * device and resource management routines - */ -static int mgsl_claim_resources(struct mgsl_struct *info); -static void mgsl_release_resources(struct mgsl_struct *info); -static void mgsl_add_device(struct mgsl_struct *info); -static struct mgsl_struct* mgsl_allocate_device(void); - -/* - * DMA buffer manupulation functions. - */ -static void mgsl_free_rx_frame_buffers( struct mgsl_struct *info, unsigned int StartIndex, unsigned int EndIndex ); -static bool mgsl_get_rx_frame( struct mgsl_struct *info ); -static bool mgsl_get_raw_rx_frame( struct mgsl_struct *info ); -static void mgsl_reset_rx_dma_buffers( struct mgsl_struct *info ); -static void mgsl_reset_tx_dma_buffers( struct mgsl_struct *info ); -static int num_free_tx_dma_buffers(struct mgsl_struct *info); -static void mgsl_load_tx_dma_buffer( struct mgsl_struct *info, const char *Buffer, unsigned int BufferSize); -static void mgsl_load_pci_memory(char* TargetPtr, const char* SourcePtr, unsigned short count); - -/* - * DMA and Shared Memory buffer allocation and formatting - */ -static int mgsl_allocate_dma_buffers(struct mgsl_struct *info); -static void mgsl_free_dma_buffers(struct mgsl_struct *info); -static int mgsl_alloc_frame_memory(struct mgsl_struct *info, DMABUFFERENTRY *BufferList,int Buffercount); -static void mgsl_free_frame_memory(struct mgsl_struct *info, DMABUFFERENTRY *BufferList,int Buffercount); -static int mgsl_alloc_buffer_list_memory(struct mgsl_struct *info); -static void mgsl_free_buffer_list_memory(struct mgsl_struct *info); -static int mgsl_alloc_intermediate_rxbuffer_memory(struct mgsl_struct *info); -static void mgsl_free_intermediate_rxbuffer_memory(struct mgsl_struct *info); -static int mgsl_alloc_intermediate_txbuffer_memory(struct mgsl_struct *info); -static void mgsl_free_intermediate_txbuffer_memory(struct mgsl_struct *info); -static bool load_next_tx_holding_buffer(struct mgsl_struct *info); -static int save_tx_buffer_request(struct mgsl_struct *info,const char *Buffer, unsigned int BufferSize); - -/* - * Bottom half interrupt handlers - */ -static void mgsl_bh_handler(struct work_struct *work); -static void mgsl_bh_receive(struct mgsl_struct *info); -static void mgsl_bh_transmit(struct mgsl_struct *info); -static void mgsl_bh_status(struct mgsl_struct *info); - -/* - * Interrupt handler routines and dispatch table. - */ -static void mgsl_isr_null( struct mgsl_struct *info ); -static void mgsl_isr_transmit_data( struct mgsl_struct *info ); -static void mgsl_isr_receive_data( struct mgsl_struct *info ); -static void mgsl_isr_receive_status( struct mgsl_struct *info ); -static void mgsl_isr_transmit_status( struct mgsl_struct *info ); -static void mgsl_isr_io_pin( struct mgsl_struct *info ); -static void mgsl_isr_misc( struct mgsl_struct *info ); -static void mgsl_isr_receive_dma( struct mgsl_struct *info ); -static void mgsl_isr_transmit_dma( struct mgsl_struct *info ); - -typedef void (*isr_dispatch_func)(struct mgsl_struct *); - -static isr_dispatch_func UscIsrTable[7] = -{ - mgsl_isr_null, - mgsl_isr_misc, - mgsl_isr_io_pin, - mgsl_isr_transmit_data, - mgsl_isr_transmit_status, - mgsl_isr_receive_data, - mgsl_isr_receive_status -}; - -/* - * ioctl call handlers - */ -static int tiocmget(struct tty_struct *tty); -static int tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear); -static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount - __user *user_icount); -static int mgsl_get_params(struct mgsl_struct * info, MGSL_PARAMS __user *user_params); -static int mgsl_set_params(struct mgsl_struct * info, MGSL_PARAMS __user *new_params); -static int mgsl_get_txidle(struct mgsl_struct * info, int __user *idle_mode); -static int mgsl_set_txidle(struct mgsl_struct * info, int idle_mode); -static int mgsl_txenable(struct mgsl_struct * info, int enable); -static int mgsl_txabort(struct mgsl_struct * info); -static int mgsl_rxenable(struct mgsl_struct * info, int enable); -static int mgsl_wait_event(struct mgsl_struct * info, int __user *mask); -static int mgsl_loopmode_send_done( struct mgsl_struct * info ); - -/* set non-zero on successful registration with PCI subsystem */ -static bool pci_registered; - -/* - * Global linked list of SyncLink devices - */ -static struct mgsl_struct *mgsl_device_list; -static int mgsl_device_count; - -/* - * Set this param to non-zero to load eax with the - * .text section address and breakpoint on module load. - * This is useful for use with gdb and add-symbol-file command. - */ -static int break_on_load; - -/* - * Driver major number, defaults to zero to get auto - * assigned major number. May be forced as module parameter. - */ -static int ttymajor; - -/* - * Array of user specified options for ISA adapters. - */ -static int io[MAX_ISA_DEVICES]; -static int irq[MAX_ISA_DEVICES]; -static int dma[MAX_ISA_DEVICES]; -static int debug_level; -static int maxframe[MAX_TOTAL_DEVICES]; -static int txdmabufs[MAX_TOTAL_DEVICES]; -static int txholdbufs[MAX_TOTAL_DEVICES]; - -module_param(break_on_load, bool, 0); -module_param(ttymajor, int, 0); -module_param_array(io, int, NULL, 0); -module_param_array(irq, int, NULL, 0); -module_param_array(dma, int, NULL, 0); -module_param(debug_level, int, 0); -module_param_array(maxframe, int, NULL, 0); -module_param_array(txdmabufs, int, NULL, 0); -module_param_array(txholdbufs, int, NULL, 0); - -static char *driver_name = "SyncLink serial driver"; -static char *driver_version = "$Revision: 4.38 $"; - -static int synclink_init_one (struct pci_dev *dev, - const struct pci_device_id *ent); -static void synclink_remove_one (struct pci_dev *dev); - -static struct pci_device_id synclink_pci_tbl[] = { - { PCI_VENDOR_ID_MICROGATE, PCI_DEVICE_ID_MICROGATE_USC, PCI_ANY_ID, PCI_ANY_ID, }, - { PCI_VENDOR_ID_MICROGATE, 0x0210, PCI_ANY_ID, PCI_ANY_ID, }, - { 0, }, /* terminate list */ -}; -MODULE_DEVICE_TABLE(pci, synclink_pci_tbl); - -MODULE_LICENSE("GPL"); - -static struct pci_driver synclink_pci_driver = { - .name = "synclink", - .id_table = synclink_pci_tbl, - .probe = synclink_init_one, - .remove = __devexit_p(synclink_remove_one), -}; - -static struct tty_driver *serial_driver; - -/* number of characters left in xmit buffer before we ask for more */ -#define WAKEUP_CHARS 256 - - -static void mgsl_change_params(struct mgsl_struct *info); -static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout); - -/* - * 1st function defined in .text section. Calling this function in - * init_module() followed by a breakpoint allows a remote debugger - * (gdb) to get the .text address for the add-symbol-file command. - * This allows remote debugging of dynamically loadable modules. - */ -static void* mgsl_get_text_ptr(void) -{ - return mgsl_get_text_ptr; -} - -static inline int mgsl_paranoia_check(struct mgsl_struct *info, - char *name, const char *routine) -{ -#ifdef MGSL_PARANOIA_CHECK - static const char *badmagic = - "Warning: bad magic number for mgsl struct (%s) in %s\n"; - static const char *badinfo = - "Warning: null mgsl_struct for (%s) in %s\n"; - - if (!info) { - printk(badinfo, name, routine); - return 1; - } - if (info->magic != MGSL_MAGIC) { - printk(badmagic, name, routine); - return 1; - } -#else - if (!info) - return 1; -#endif - return 0; -} - -/** - * line discipline callback wrappers - * - * The wrappers maintain line discipline references - * while calling into the line discipline. - * - * ldisc_receive_buf - pass receive data to line discipline - */ - -static void ldisc_receive_buf(struct tty_struct *tty, - const __u8 *data, char *flags, int count) -{ - struct tty_ldisc *ld; - if (!tty) - return; - ld = tty_ldisc_ref(tty); - if (ld) { - if (ld->ops->receive_buf) - ld->ops->receive_buf(tty, data, flags, count); - tty_ldisc_deref(ld); - } -} - -/* mgsl_stop() throttle (stop) transmitter - * - * Arguments: tty pointer to tty info structure - * Return Value: None - */ -static void mgsl_stop(struct tty_struct *tty) -{ - struct mgsl_struct *info = tty->driver_data; - unsigned long flags; - - if (mgsl_paranoia_check(info, tty->name, "mgsl_stop")) - return; - - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk("mgsl_stop(%s)\n",info->device_name); - - spin_lock_irqsave(&info->irq_spinlock,flags); - if (info->tx_enabled) - usc_stop_transmitter(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - -} /* end of mgsl_stop() */ - -/* mgsl_start() release (start) transmitter - * - * Arguments: tty pointer to tty info structure - * Return Value: None - */ -static void mgsl_start(struct tty_struct *tty) -{ - struct mgsl_struct *info = tty->driver_data; - unsigned long flags; - - if (mgsl_paranoia_check(info, tty->name, "mgsl_start")) - return; - - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk("mgsl_start(%s)\n",info->device_name); - - spin_lock_irqsave(&info->irq_spinlock,flags); - if (!info->tx_enabled) - usc_start_transmitter(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - -} /* end of mgsl_start() */ - -/* - * Bottom half work queue access functions - */ - -/* mgsl_bh_action() Return next bottom half action to perform. - * Return Value: BH action code or 0 if nothing to do. - */ -static int mgsl_bh_action(struct mgsl_struct *info) -{ - unsigned long flags; - int rc = 0; - - spin_lock_irqsave(&info->irq_spinlock,flags); - - if (info->pending_bh & BH_RECEIVE) { - info->pending_bh &= ~BH_RECEIVE; - rc = BH_RECEIVE; - } else if (info->pending_bh & BH_TRANSMIT) { - info->pending_bh &= ~BH_TRANSMIT; - rc = BH_TRANSMIT; - } else if (info->pending_bh & BH_STATUS) { - info->pending_bh &= ~BH_STATUS; - rc = BH_STATUS; - } - - if (!rc) { - /* Mark BH routine as complete */ - info->bh_running = false; - info->bh_requested = false; - } - - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - return rc; -} - -/* - * Perform bottom half processing of work items queued by ISR. - */ -static void mgsl_bh_handler(struct work_struct *work) -{ - struct mgsl_struct *info = - container_of(work, struct mgsl_struct, task); - int action; - - if (!info) - return; - - if ( debug_level >= DEBUG_LEVEL_BH ) - printk( "%s(%d):mgsl_bh_handler(%s) entry\n", - __FILE__,__LINE__,info->device_name); - - info->bh_running = true; - - while((action = mgsl_bh_action(info)) != 0) { - - /* Process work item */ - if ( debug_level >= DEBUG_LEVEL_BH ) - printk( "%s(%d):mgsl_bh_handler() work item action=%d\n", - __FILE__,__LINE__,action); - - switch (action) { - - case BH_RECEIVE: - mgsl_bh_receive(info); - break; - case BH_TRANSMIT: - mgsl_bh_transmit(info); - break; - case BH_STATUS: - mgsl_bh_status(info); - break; - default: - /* unknown work item ID */ - printk("Unknown work item ID=%08X!\n", action); - break; - } - } - - if ( debug_level >= DEBUG_LEVEL_BH ) - printk( "%s(%d):mgsl_bh_handler(%s) exit\n", - __FILE__,__LINE__,info->device_name); -} - -static void mgsl_bh_receive(struct mgsl_struct *info) -{ - bool (*get_rx_frame)(struct mgsl_struct *info) = - (info->params.mode == MGSL_MODE_HDLC ? mgsl_get_rx_frame : mgsl_get_raw_rx_frame); - - if ( debug_level >= DEBUG_LEVEL_BH ) - printk( "%s(%d):mgsl_bh_receive(%s)\n", - __FILE__,__LINE__,info->device_name); - - do - { - if (info->rx_rcc_underrun) { - unsigned long flags; - spin_lock_irqsave(&info->irq_spinlock,flags); - usc_start_receiver(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - return; - } - } while(get_rx_frame(info)); -} - -static void mgsl_bh_transmit(struct mgsl_struct *info) -{ - struct tty_struct *tty = info->port.tty; - unsigned long flags; - - if ( debug_level >= DEBUG_LEVEL_BH ) - printk( "%s(%d):mgsl_bh_transmit() entry on %s\n", - __FILE__,__LINE__,info->device_name); - - if (tty) - tty_wakeup(tty); - - /* if transmitter idle and loopmode_send_done_requested - * then start echoing RxD to TxD - */ - spin_lock_irqsave(&info->irq_spinlock,flags); - if ( !info->tx_active && info->loopmode_send_done_requested ) - usc_loopmode_send_done( info ); - spin_unlock_irqrestore(&info->irq_spinlock,flags); -} - -static void mgsl_bh_status(struct mgsl_struct *info) -{ - if ( debug_level >= DEBUG_LEVEL_BH ) - printk( "%s(%d):mgsl_bh_status() entry on %s\n", - __FILE__,__LINE__,info->device_name); - - info->ri_chkcount = 0; - info->dsr_chkcount = 0; - info->dcd_chkcount = 0; - info->cts_chkcount = 0; -} - -/* mgsl_isr_receive_status() - * - * Service a receive status interrupt. The type of status - * interrupt is indicated by the state of the RCSR. - * This is only used for HDLC mode. - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void mgsl_isr_receive_status( struct mgsl_struct *info ) -{ - u16 status = usc_InReg( info, RCSR ); - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):mgsl_isr_receive_status status=%04X\n", - __FILE__,__LINE__,status); - - if ( (status & RXSTATUS_ABORT_RECEIVED) && - info->loopmode_insert_requested && - usc_loopmode_active(info) ) - { - ++info->icount.rxabort; - info->loopmode_insert_requested = false; - - /* clear CMR:13 to start echoing RxD to TxD */ - info->cmr_value &= ~BIT13; - usc_OutReg(info, CMR, info->cmr_value); - - /* disable received abort irq (no longer required) */ - usc_OutReg(info, RICR, - (usc_InReg(info, RICR) & ~RXSTATUS_ABORT_RECEIVED)); - } - - if (status & (RXSTATUS_EXITED_HUNT + RXSTATUS_IDLE_RECEIVED)) { - if (status & RXSTATUS_EXITED_HUNT) - info->icount.exithunt++; - if (status & RXSTATUS_IDLE_RECEIVED) - info->icount.rxidle++; - wake_up_interruptible(&info->event_wait_q); - } - - if (status & RXSTATUS_OVERRUN){ - info->icount.rxover++; - usc_process_rxoverrun_sync( info ); - } - - usc_ClearIrqPendingBits( info, RECEIVE_STATUS ); - usc_UnlatchRxstatusBits( info, status ); - -} /* end of mgsl_isr_receive_status() */ - -/* mgsl_isr_transmit_status() - * - * Service a transmit status interrupt - * HDLC mode :end of transmit frame - * Async mode:all data is sent - * transmit status is indicated by bits in the TCSR. - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void mgsl_isr_transmit_status( struct mgsl_struct *info ) -{ - u16 status = usc_InReg( info, TCSR ); - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):mgsl_isr_transmit_status status=%04X\n", - __FILE__,__LINE__,status); - - usc_ClearIrqPendingBits( info, TRANSMIT_STATUS ); - usc_UnlatchTxstatusBits( info, status ); - - if ( status & (TXSTATUS_UNDERRUN | TXSTATUS_ABORT_SENT) ) - { - /* finished sending HDLC abort. This may leave */ - /* the TxFifo with data from the aborted frame */ - /* so purge the TxFifo. Also shutdown the DMA */ - /* channel in case there is data remaining in */ - /* the DMA buffer */ - usc_DmaCmd( info, DmaCmd_ResetTxChannel ); - usc_RTCmd( info, RTCmd_PurgeTxFifo ); - } - - if ( status & TXSTATUS_EOF_SENT ) - info->icount.txok++; - else if ( status & TXSTATUS_UNDERRUN ) - info->icount.txunder++; - else if ( status & TXSTATUS_ABORT_SENT ) - info->icount.txabort++; - else - info->icount.txunder++; - - info->tx_active = false; - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - del_timer(&info->tx_timer); - - if ( info->drop_rts_on_tx_done ) { - usc_get_serial_signals( info ); - if ( info->serial_signals & SerialSignal_RTS ) { - info->serial_signals &= ~SerialSignal_RTS; - usc_set_serial_signals( info ); - } - info->drop_rts_on_tx_done = false; - } - -#if SYNCLINK_GENERIC_HDLC - if (info->netcount) - hdlcdev_tx_done(info); - else -#endif - { - if (info->port.tty->stopped || info->port.tty->hw_stopped) { - usc_stop_transmitter(info); - return; - } - info->pending_bh |= BH_TRANSMIT; - } - -} /* end of mgsl_isr_transmit_status() */ - -/* mgsl_isr_io_pin() - * - * Service an Input/Output pin interrupt. The type of - * interrupt is indicated by bits in the MISR - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void mgsl_isr_io_pin( struct mgsl_struct *info ) -{ - struct mgsl_icount *icount; - u16 status = usc_InReg( info, MISR ); - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):mgsl_isr_io_pin status=%04X\n", - __FILE__,__LINE__,status); - - usc_ClearIrqPendingBits( info, IO_PIN ); - usc_UnlatchIostatusBits( info, status ); - - if (status & (MISCSTATUS_CTS_LATCHED | MISCSTATUS_DCD_LATCHED | - MISCSTATUS_DSR_LATCHED | MISCSTATUS_RI_LATCHED) ) { - icount = &info->icount; - /* update input line counters */ - if (status & MISCSTATUS_RI_LATCHED) { - if ((info->ri_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT) - usc_DisablestatusIrqs(info,SICR_RI); - icount->rng++; - if ( status & MISCSTATUS_RI ) - info->input_signal_events.ri_up++; - else - info->input_signal_events.ri_down++; - } - if (status & MISCSTATUS_DSR_LATCHED) { - if ((info->dsr_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT) - usc_DisablestatusIrqs(info,SICR_DSR); - icount->dsr++; - if ( status & MISCSTATUS_DSR ) - info->input_signal_events.dsr_up++; - else - info->input_signal_events.dsr_down++; - } - if (status & MISCSTATUS_DCD_LATCHED) { - if ((info->dcd_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT) - usc_DisablestatusIrqs(info,SICR_DCD); - icount->dcd++; - if (status & MISCSTATUS_DCD) { - info->input_signal_events.dcd_up++; - } else - info->input_signal_events.dcd_down++; -#if SYNCLINK_GENERIC_HDLC - if (info->netcount) { - if (status & MISCSTATUS_DCD) - netif_carrier_on(info->netdev); - else - netif_carrier_off(info->netdev); - } -#endif - } - if (status & MISCSTATUS_CTS_LATCHED) - { - if ((info->cts_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT) - usc_DisablestatusIrqs(info,SICR_CTS); - icount->cts++; - if ( status & MISCSTATUS_CTS ) - info->input_signal_events.cts_up++; - else - info->input_signal_events.cts_down++; - } - wake_up_interruptible(&info->status_event_wait_q); - wake_up_interruptible(&info->event_wait_q); - - if ( (info->port.flags & ASYNC_CHECK_CD) && - (status & MISCSTATUS_DCD_LATCHED) ) { - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s CD now %s...", info->device_name, - (status & MISCSTATUS_DCD) ? "on" : "off"); - if (status & MISCSTATUS_DCD) - wake_up_interruptible(&info->port.open_wait); - else { - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("doing serial hangup..."); - if (info->port.tty) - tty_hangup(info->port.tty); - } - } - - if ( (info->port.flags & ASYNC_CTS_FLOW) && - (status & MISCSTATUS_CTS_LATCHED) ) { - if (info->port.tty->hw_stopped) { - if (status & MISCSTATUS_CTS) { - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("CTS tx start..."); - if (info->port.tty) - info->port.tty->hw_stopped = 0; - usc_start_transmitter(info); - info->pending_bh |= BH_TRANSMIT; - return; - } - } else { - if (!(status & MISCSTATUS_CTS)) { - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("CTS tx stop..."); - if (info->port.tty) - info->port.tty->hw_stopped = 1; - usc_stop_transmitter(info); - } - } - } - } - - info->pending_bh |= BH_STATUS; - - /* for diagnostics set IRQ flag */ - if ( status & MISCSTATUS_TXC_LATCHED ){ - usc_OutReg( info, SICR, - (unsigned short)(usc_InReg(info,SICR) & ~(SICR_TXC_ACTIVE+SICR_TXC_INACTIVE)) ); - usc_UnlatchIostatusBits( info, MISCSTATUS_TXC_LATCHED ); - info->irq_occurred = true; - } - -} /* end of mgsl_isr_io_pin() */ - -/* mgsl_isr_transmit_data() - * - * Service a transmit data interrupt (async mode only). - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void mgsl_isr_transmit_data( struct mgsl_struct *info ) -{ - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):mgsl_isr_transmit_data xmit_cnt=%d\n", - __FILE__,__LINE__,info->xmit_cnt); - - usc_ClearIrqPendingBits( info, TRANSMIT_DATA ); - - if (info->port.tty->stopped || info->port.tty->hw_stopped) { - usc_stop_transmitter(info); - return; - } - - if ( info->xmit_cnt ) - usc_load_txfifo( info ); - else - info->tx_active = false; - - if (info->xmit_cnt < WAKEUP_CHARS) - info->pending_bh |= BH_TRANSMIT; - -} /* end of mgsl_isr_transmit_data() */ - -/* mgsl_isr_receive_data() - * - * Service a receive data interrupt. This occurs - * when operating in asynchronous interrupt transfer mode. - * The receive data FIFO is flushed to the receive data buffers. - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void mgsl_isr_receive_data( struct mgsl_struct *info ) -{ - int Fifocount; - u16 status; - int work = 0; - unsigned char DataByte; - struct tty_struct *tty = info->port.tty; - struct mgsl_icount *icount = &info->icount; - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):mgsl_isr_receive_data\n", - __FILE__,__LINE__); - - usc_ClearIrqPendingBits( info, RECEIVE_DATA ); - - /* select FIFO status for RICR readback */ - usc_RCmd( info, RCmd_SelectRicrRxFifostatus ); - - /* clear the Wordstatus bit so that status readback */ - /* only reflects the status of this byte */ - usc_OutReg( info, RICR+LSBONLY, (u16)(usc_InReg(info, RICR+LSBONLY) & ~BIT3 )); - - /* flush the receive FIFO */ - - while( (Fifocount = (usc_InReg(info,RICR) >> 8)) ) { - int flag; - - /* read one byte from RxFIFO */ - outw( (inw(info->io_base + CCAR) & 0x0780) | (RDR+LSBONLY), - info->io_base + CCAR ); - DataByte = inb( info->io_base + CCAR ); - - /* get the status of the received byte */ - status = usc_InReg(info, RCSR); - if ( status & (RXSTATUS_FRAMING_ERROR + RXSTATUS_PARITY_ERROR + - RXSTATUS_OVERRUN + RXSTATUS_BREAK_RECEIVED) ) - usc_UnlatchRxstatusBits(info,RXSTATUS_ALL); - - icount->rx++; - - flag = 0; - if ( status & (RXSTATUS_FRAMING_ERROR + RXSTATUS_PARITY_ERROR + - RXSTATUS_OVERRUN + RXSTATUS_BREAK_RECEIVED) ) { - printk("rxerr=%04X\n",status); - /* update error statistics */ - if ( status & RXSTATUS_BREAK_RECEIVED ) { - status &= ~(RXSTATUS_FRAMING_ERROR + RXSTATUS_PARITY_ERROR); - icount->brk++; - } else if (status & RXSTATUS_PARITY_ERROR) - icount->parity++; - else if (status & RXSTATUS_FRAMING_ERROR) - icount->frame++; - else if (status & RXSTATUS_OVERRUN) { - /* must issue purge fifo cmd before */ - /* 16C32 accepts more receive chars */ - usc_RTCmd(info,RTCmd_PurgeRxFifo); - icount->overrun++; - } - - /* discard char if tty control flags say so */ - if (status & info->ignore_status_mask) - continue; - - status &= info->read_status_mask; - - if (status & RXSTATUS_BREAK_RECEIVED) { - flag = TTY_BREAK; - if (info->port.flags & ASYNC_SAK) - do_SAK(tty); - } else if (status & RXSTATUS_PARITY_ERROR) - flag = TTY_PARITY; - else if (status & RXSTATUS_FRAMING_ERROR) - flag = TTY_FRAME; - } /* end of if (error) */ - tty_insert_flip_char(tty, DataByte, flag); - if (status & RXSTATUS_OVERRUN) { - /* Overrun is special, since it's - * reported immediately, and doesn't - * affect the current character - */ - work += tty_insert_flip_char(tty, 0, TTY_OVERRUN); - } - } - - if ( debug_level >= DEBUG_LEVEL_ISR ) { - printk("%s(%d):rx=%d brk=%d parity=%d frame=%d overrun=%d\n", - __FILE__,__LINE__,icount->rx,icount->brk, - icount->parity,icount->frame,icount->overrun); - } - - if(work) - tty_flip_buffer_push(tty); -} - -/* mgsl_isr_misc() - * - * Service a miscellaneous interrupt source. - * - * Arguments: info pointer to device extension (instance data) - * Return Value: None - */ -static void mgsl_isr_misc( struct mgsl_struct *info ) -{ - u16 status = usc_InReg( info, MISR ); - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):mgsl_isr_misc status=%04X\n", - __FILE__,__LINE__,status); - - if ((status & MISCSTATUS_RCC_UNDERRUN) && - (info->params.mode == MGSL_MODE_HDLC)) { - - /* turn off receiver and rx DMA */ - usc_EnableReceiver(info,DISABLE_UNCONDITIONAL); - usc_DmaCmd(info, DmaCmd_ResetRxChannel); - usc_UnlatchRxstatusBits(info, RXSTATUS_ALL); - usc_ClearIrqPendingBits(info, RECEIVE_DATA + RECEIVE_STATUS); - usc_DisableInterrupts(info, RECEIVE_DATA + RECEIVE_STATUS); - - /* schedule BH handler to restart receiver */ - info->pending_bh |= BH_RECEIVE; - info->rx_rcc_underrun = true; - } - - usc_ClearIrqPendingBits( info, MISC ); - usc_UnlatchMiscstatusBits( info, status ); - -} /* end of mgsl_isr_misc() */ - -/* mgsl_isr_null() - * - * Services undefined interrupt vectors from the - * USC. (hence this function SHOULD never be called) - * - * Arguments: info pointer to device extension (instance data) - * Return Value: None - */ -static void mgsl_isr_null( struct mgsl_struct *info ) -{ - -} /* end of mgsl_isr_null() */ - -/* mgsl_isr_receive_dma() - * - * Service a receive DMA channel interrupt. - * For this driver there are two sources of receive DMA interrupts - * as identified in the Receive DMA mode Register (RDMR): - * - * BIT3 EOA/EOL End of List, all receive buffers in receive - * buffer list have been filled (no more free buffers - * available). The DMA controller has shut down. - * - * BIT2 EOB End of Buffer. This interrupt occurs when a receive - * DMA buffer is terminated in response to completion - * of a good frame or a frame with errors. The status - * of the frame is stored in the buffer entry in the - * list of receive buffer entries. - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void mgsl_isr_receive_dma( struct mgsl_struct *info ) -{ - u16 status; - - /* clear interrupt pending and IUS bit for Rx DMA IRQ */ - usc_OutDmaReg( info, CDIR, BIT9+BIT1 ); - - /* Read the receive DMA status to identify interrupt type. */ - /* This also clears the status bits. */ - status = usc_InDmaReg( info, RDMR ); - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):mgsl_isr_receive_dma(%s) status=%04X\n", - __FILE__,__LINE__,info->device_name,status); - - info->pending_bh |= BH_RECEIVE; - - if ( status & BIT3 ) { - info->rx_overflow = true; - info->icount.buf_overrun++; - } - -} /* end of mgsl_isr_receive_dma() */ - -/* mgsl_isr_transmit_dma() - * - * This function services a transmit DMA channel interrupt. - * - * For this driver there is one source of transmit DMA interrupts - * as identified in the Transmit DMA Mode Register (TDMR): - * - * BIT2 EOB End of Buffer. This interrupt occurs when a - * transmit DMA buffer has been emptied. - * - * The driver maintains enough transmit DMA buffers to hold at least - * one max frame size transmit frame. When operating in a buffered - * transmit mode, there may be enough transmit DMA buffers to hold at - * least two or more max frame size frames. On an EOB condition, - * determine if there are any queued transmit buffers and copy into - * transmit DMA buffers if we have room. - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void mgsl_isr_transmit_dma( struct mgsl_struct *info ) -{ - u16 status; - - /* clear interrupt pending and IUS bit for Tx DMA IRQ */ - usc_OutDmaReg(info, CDIR, BIT8+BIT0 ); - - /* Read the transmit DMA status to identify interrupt type. */ - /* This also clears the status bits. */ - - status = usc_InDmaReg( info, TDMR ); - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):mgsl_isr_transmit_dma(%s) status=%04X\n", - __FILE__,__LINE__,info->device_name,status); - - if ( status & BIT2 ) { - --info->tx_dma_buffers_used; - - /* if there are transmit frames queued, - * try to load the next one - */ - if ( load_next_tx_holding_buffer(info) ) { - /* if call returns non-zero value, we have - * at least one free tx holding buffer - */ - info->pending_bh |= BH_TRANSMIT; - } - } - -} /* end of mgsl_isr_transmit_dma() */ - -/* mgsl_interrupt() - * - * Interrupt service routine entry point. - * - * Arguments: - * - * irq interrupt number that caused interrupt - * dev_id device ID supplied during interrupt registration - * - * Return Value: None - */ -static irqreturn_t mgsl_interrupt(int dummy, void *dev_id) -{ - struct mgsl_struct *info = dev_id; - u16 UscVector; - u16 DmaVector; - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk(KERN_DEBUG "%s(%d):mgsl_interrupt(%d)entry.\n", - __FILE__, __LINE__, info->irq_level); - - spin_lock(&info->irq_spinlock); - - for(;;) { - /* Read the interrupt vectors from hardware. */ - UscVector = usc_InReg(info, IVR) >> 9; - DmaVector = usc_InDmaReg(info, DIVR); - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):%s UscVector=%08X DmaVector=%08X\n", - __FILE__,__LINE__,info->device_name,UscVector,DmaVector); - - if ( !UscVector && !DmaVector ) - break; - - /* Dispatch interrupt vector */ - if ( UscVector ) - (*UscIsrTable[UscVector])(info); - else if ( (DmaVector&(BIT10|BIT9)) == BIT10) - mgsl_isr_transmit_dma(info); - else - mgsl_isr_receive_dma(info); - - if ( info->isr_overflow ) { - printk(KERN_ERR "%s(%d):%s isr overflow irq=%d\n", - __FILE__, __LINE__, info->device_name, info->irq_level); - usc_DisableMasterIrqBit(info); - usc_DisableDmaInterrupts(info,DICR_MASTER); - break; - } - } - - /* Request bottom half processing if there's something - * for it to do and the bh is not already running - */ - - if ( info->pending_bh && !info->bh_running && !info->bh_requested ) { - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):%s queueing bh task.\n", - __FILE__,__LINE__,info->device_name); - schedule_work(&info->task); - info->bh_requested = true; - } - - spin_unlock(&info->irq_spinlock); - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk(KERN_DEBUG "%s(%d):mgsl_interrupt(%d)exit.\n", - __FILE__, __LINE__, info->irq_level); - - return IRQ_HANDLED; -} /* end of mgsl_interrupt() */ - -/* startup() - * - * Initialize and start device. - * - * Arguments: info pointer to device instance data - * Return Value: 0 if success, otherwise error code - */ -static int startup(struct mgsl_struct * info) -{ - int retval = 0; - - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk("%s(%d):mgsl_startup(%s)\n",__FILE__,__LINE__,info->device_name); - - if (info->port.flags & ASYNC_INITIALIZED) - return 0; - - if (!info->xmit_buf) { - /* allocate a page of memory for a transmit buffer */ - info->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); - if (!info->xmit_buf) { - printk(KERN_ERR"%s(%d):%s can't allocate transmit buffer\n", - __FILE__,__LINE__,info->device_name); - return -ENOMEM; - } - } - - info->pending_bh = 0; - - memset(&info->icount, 0, sizeof(info->icount)); - - setup_timer(&info->tx_timer, mgsl_tx_timeout, (unsigned long)info); - - /* Allocate and claim adapter resources */ - retval = mgsl_claim_resources(info); - - /* perform existence check and diagnostics */ - if ( !retval ) - retval = mgsl_adapter_test(info); - - if ( retval ) { - if (capable(CAP_SYS_ADMIN) && info->port.tty) - set_bit(TTY_IO_ERROR, &info->port.tty->flags); - mgsl_release_resources(info); - return retval; - } - - /* program hardware for current parameters */ - mgsl_change_params(info); - - if (info->port.tty) - clear_bit(TTY_IO_ERROR, &info->port.tty->flags); - - info->port.flags |= ASYNC_INITIALIZED; - - return 0; - -} /* end of startup() */ - -/* shutdown() - * - * Called by mgsl_close() and mgsl_hangup() to shutdown hardware - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void shutdown(struct mgsl_struct * info) -{ - unsigned long flags; - - if (!(info->port.flags & ASYNC_INITIALIZED)) - return; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_shutdown(%s)\n", - __FILE__,__LINE__, info->device_name ); - - /* clear status wait queue because status changes */ - /* can't happen after shutting down the hardware */ - wake_up_interruptible(&info->status_event_wait_q); - wake_up_interruptible(&info->event_wait_q); - - del_timer_sync(&info->tx_timer); - - if (info->xmit_buf) { - free_page((unsigned long) info->xmit_buf); - info->xmit_buf = NULL; - } - - spin_lock_irqsave(&info->irq_spinlock,flags); - usc_DisableMasterIrqBit(info); - usc_stop_receiver(info); - usc_stop_transmitter(info); - usc_DisableInterrupts(info,RECEIVE_DATA + RECEIVE_STATUS + - TRANSMIT_DATA + TRANSMIT_STATUS + IO_PIN + MISC ); - usc_DisableDmaInterrupts(info,DICR_MASTER + DICR_TRANSMIT + DICR_RECEIVE); - - /* Disable DMAEN (Port 7, Bit 14) */ - /* This disconnects the DMA request signal from the ISA bus */ - /* on the ISA adapter. This has no effect for the PCI adapter */ - usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT15) | BIT14)); - - /* Disable INTEN (Port 6, Bit12) */ - /* This disconnects the IRQ request signal to the ISA bus */ - /* on the ISA adapter. This has no effect for the PCI adapter */ - usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) | BIT12)); - - if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) { - info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); - usc_set_serial_signals(info); - } - - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - mgsl_release_resources(info); - - if (info->port.tty) - set_bit(TTY_IO_ERROR, &info->port.tty->flags); - - info->port.flags &= ~ASYNC_INITIALIZED; - -} /* end of shutdown() */ - -static void mgsl_program_hw(struct mgsl_struct *info) -{ - unsigned long flags; - - spin_lock_irqsave(&info->irq_spinlock,flags); - - usc_stop_receiver(info); - usc_stop_transmitter(info); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - - if (info->params.mode == MGSL_MODE_HDLC || - info->params.mode == MGSL_MODE_RAW || - info->netcount) - usc_set_sync_mode(info); - else - usc_set_async_mode(info); - - usc_set_serial_signals(info); - - info->dcd_chkcount = 0; - info->cts_chkcount = 0; - info->ri_chkcount = 0; - info->dsr_chkcount = 0; - - usc_EnableStatusIrqs(info,SICR_CTS+SICR_DSR+SICR_DCD+SICR_RI); - usc_EnableInterrupts(info, IO_PIN); - usc_get_serial_signals(info); - - if (info->netcount || info->port.tty->termios->c_cflag & CREAD) - usc_start_receiver(info); - - spin_unlock_irqrestore(&info->irq_spinlock,flags); -} - -/* Reconfigure adapter based on new parameters - */ -static void mgsl_change_params(struct mgsl_struct *info) -{ - unsigned cflag; - int bits_per_char; - - if (!info->port.tty || !info->port.tty->termios) - return; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_change_params(%s)\n", - __FILE__,__LINE__, info->device_name ); - - cflag = info->port.tty->termios->c_cflag; - - /* if B0 rate (hangup) specified then negate DTR and RTS */ - /* otherwise assert DTR and RTS */ - if (cflag & CBAUD) - info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; - else - info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); - - /* byte size and parity */ - - switch (cflag & CSIZE) { - case CS5: info->params.data_bits = 5; break; - case CS6: info->params.data_bits = 6; break; - case CS7: info->params.data_bits = 7; break; - case CS8: info->params.data_bits = 8; break; - /* Never happens, but GCC is too dumb to figure it out */ - default: info->params.data_bits = 7; break; - } - - if (cflag & CSTOPB) - info->params.stop_bits = 2; - else - info->params.stop_bits = 1; - - info->params.parity = ASYNC_PARITY_NONE; - if (cflag & PARENB) { - if (cflag & PARODD) - info->params.parity = ASYNC_PARITY_ODD; - else - info->params.parity = ASYNC_PARITY_EVEN; -#ifdef CMSPAR - if (cflag & CMSPAR) - info->params.parity = ASYNC_PARITY_SPACE; -#endif - } - - /* calculate number of jiffies to transmit a full - * FIFO (32 bytes) at specified data rate - */ - bits_per_char = info->params.data_bits + - info->params.stop_bits + 1; - - /* if port data rate is set to 460800 or less then - * allow tty settings to override, otherwise keep the - * current data rate. - */ - if (info->params.data_rate <= 460800) - info->params.data_rate = tty_get_baud_rate(info->port.tty); - - if ( info->params.data_rate ) { - info->timeout = (32*HZ*bits_per_char) / - info->params.data_rate; - } - info->timeout += HZ/50; /* Add .02 seconds of slop */ - - if (cflag & CRTSCTS) - info->port.flags |= ASYNC_CTS_FLOW; - else - info->port.flags &= ~ASYNC_CTS_FLOW; - - if (cflag & CLOCAL) - info->port.flags &= ~ASYNC_CHECK_CD; - else - info->port.flags |= ASYNC_CHECK_CD; - - /* process tty input control flags */ - - info->read_status_mask = RXSTATUS_OVERRUN; - if (I_INPCK(info->port.tty)) - info->read_status_mask |= RXSTATUS_PARITY_ERROR | RXSTATUS_FRAMING_ERROR; - if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) - info->read_status_mask |= RXSTATUS_BREAK_RECEIVED; - - if (I_IGNPAR(info->port.tty)) - info->ignore_status_mask |= RXSTATUS_PARITY_ERROR | RXSTATUS_FRAMING_ERROR; - if (I_IGNBRK(info->port.tty)) { - info->ignore_status_mask |= RXSTATUS_BREAK_RECEIVED; - /* If ignoring parity and break indicators, ignore - * overruns too. (For real raw support). - */ - if (I_IGNPAR(info->port.tty)) - info->ignore_status_mask |= RXSTATUS_OVERRUN; - } - - mgsl_program_hw(info); - -} /* end of mgsl_change_params() */ - -/* mgsl_put_char() - * - * Add a character to the transmit buffer. - * - * Arguments: tty pointer to tty information structure - * ch character to add to transmit buffer - * - * Return Value: None - */ -static int mgsl_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct mgsl_struct *info = tty->driver_data; - unsigned long flags; - int ret = 0; - - if (debug_level >= DEBUG_LEVEL_INFO) { - printk(KERN_DEBUG "%s(%d):mgsl_put_char(%d) on %s\n", - __FILE__, __LINE__, ch, info->device_name); - } - - if (mgsl_paranoia_check(info, tty->name, "mgsl_put_char")) - return 0; - - if (!info->xmit_buf) - return 0; - - spin_lock_irqsave(&info->irq_spinlock, flags); - - if ((info->params.mode == MGSL_MODE_ASYNC ) || !info->tx_active) { - if (info->xmit_cnt < SERIAL_XMIT_SIZE - 1) { - info->xmit_buf[info->xmit_head++] = ch; - info->xmit_head &= SERIAL_XMIT_SIZE-1; - info->xmit_cnt++; - ret = 1; - } - } - spin_unlock_irqrestore(&info->irq_spinlock, flags); - return ret; - -} /* end of mgsl_put_char() */ - -/* mgsl_flush_chars() - * - * Enable transmitter so remaining characters in the - * transmit buffer are sent. - * - * Arguments: tty pointer to tty information structure - * Return Value: None - */ -static void mgsl_flush_chars(struct tty_struct *tty) -{ - struct mgsl_struct *info = tty->driver_data; - unsigned long flags; - - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):mgsl_flush_chars() entry on %s xmit_cnt=%d\n", - __FILE__,__LINE__,info->device_name,info->xmit_cnt); - - if (mgsl_paranoia_check(info, tty->name, "mgsl_flush_chars")) - return; - - if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || - !info->xmit_buf) - return; - - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):mgsl_flush_chars() entry on %s starting transmitter\n", - __FILE__,__LINE__,info->device_name ); - - spin_lock_irqsave(&info->irq_spinlock,flags); - - if (!info->tx_active) { - if ( (info->params.mode == MGSL_MODE_HDLC || - info->params.mode == MGSL_MODE_RAW) && info->xmit_cnt ) { - /* operating in synchronous (frame oriented) mode */ - /* copy data from circular xmit_buf to */ - /* transmit DMA buffer. */ - mgsl_load_tx_dma_buffer(info, - info->xmit_buf,info->xmit_cnt); - } - usc_start_transmitter(info); - } - - spin_unlock_irqrestore(&info->irq_spinlock,flags); - -} /* end of mgsl_flush_chars() */ - -/* mgsl_write() - * - * Send a block of data - * - * Arguments: - * - * tty pointer to tty information structure - * buf pointer to buffer containing send data - * count size of send data in bytes - * - * Return Value: number of characters written - */ -static int mgsl_write(struct tty_struct * tty, - const unsigned char *buf, int count) -{ - int c, ret = 0; - struct mgsl_struct *info = tty->driver_data; - unsigned long flags; - - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):mgsl_write(%s) count=%d\n", - __FILE__,__LINE__,info->device_name,count); - - if (mgsl_paranoia_check(info, tty->name, "mgsl_write")) - goto cleanup; - - if (!info->xmit_buf) - goto cleanup; - - if ( info->params.mode == MGSL_MODE_HDLC || - info->params.mode == MGSL_MODE_RAW ) { - /* operating in synchronous (frame oriented) mode */ - /* operating in synchronous (frame oriented) mode */ - if (info->tx_active) { - - if ( info->params.mode == MGSL_MODE_HDLC ) { - ret = 0; - goto cleanup; - } - /* transmitter is actively sending data - - * if we have multiple transmit dma and - * holding buffers, attempt to queue this - * frame for transmission at a later time. - */ - if (info->tx_holding_count >= info->num_tx_holding_buffers ) { - /* no tx holding buffers available */ - ret = 0; - goto cleanup; - } - - /* queue transmit frame request */ - ret = count; - save_tx_buffer_request(info,buf,count); - - /* if we have sufficient tx dma buffers, - * load the next buffered tx request - */ - spin_lock_irqsave(&info->irq_spinlock,flags); - load_next_tx_holding_buffer(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - goto cleanup; - } - - /* if operating in HDLC LoopMode and the adapter */ - /* has yet to be inserted into the loop, we can't */ - /* transmit */ - - if ( (info->params.flags & HDLC_FLAG_HDLC_LOOPMODE) && - !usc_loopmode_active(info) ) - { - ret = 0; - goto cleanup; - } - - if ( info->xmit_cnt ) { - /* Send accumulated from send_char() calls */ - /* as frame and wait before accepting more data. */ - ret = 0; - - /* copy data from circular xmit_buf to */ - /* transmit DMA buffer. */ - mgsl_load_tx_dma_buffer(info, - info->xmit_buf,info->xmit_cnt); - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):mgsl_write(%s) sync xmit_cnt flushing\n", - __FILE__,__LINE__,info->device_name); - } else { - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):mgsl_write(%s) sync transmit accepted\n", - __FILE__,__LINE__,info->device_name); - ret = count; - info->xmit_cnt = count; - mgsl_load_tx_dma_buffer(info,buf,count); - } - } else { - while (1) { - spin_lock_irqsave(&info->irq_spinlock,flags); - c = min_t(int, count, - min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - if (c <= 0) { - spin_unlock_irqrestore(&info->irq_spinlock,flags); - break; - } - memcpy(info->xmit_buf + info->xmit_head, buf, c); - info->xmit_head = ((info->xmit_head + c) & - (SERIAL_XMIT_SIZE-1)); - info->xmit_cnt += c; - spin_unlock_irqrestore(&info->irq_spinlock,flags); - buf += c; - count -= c; - ret += c; - } - } - - if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { - spin_lock_irqsave(&info->irq_spinlock,flags); - if (!info->tx_active) - usc_start_transmitter(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - } -cleanup: - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):mgsl_write(%s) returning=%d\n", - __FILE__,__LINE__,info->device_name,ret); - - return ret; - -} /* end of mgsl_write() */ - -/* mgsl_write_room() - * - * Return the count of free bytes in transmit buffer - * - * Arguments: tty pointer to tty info structure - * Return Value: None - */ -static int mgsl_write_room(struct tty_struct *tty) -{ - struct mgsl_struct *info = tty->driver_data; - int ret; - - if (mgsl_paranoia_check(info, tty->name, "mgsl_write_room")) - return 0; - ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; - if (ret < 0) - ret = 0; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_write_room(%s)=%d\n", - __FILE__,__LINE__, info->device_name,ret ); - - if ( info->params.mode == MGSL_MODE_HDLC || - info->params.mode == MGSL_MODE_RAW ) { - /* operating in synchronous (frame oriented) mode */ - if ( info->tx_active ) - return 0; - else - return HDLC_MAX_FRAME_SIZE; - } - - return ret; - -} /* end of mgsl_write_room() */ - -/* mgsl_chars_in_buffer() - * - * Return the count of bytes in transmit buffer - * - * Arguments: tty pointer to tty info structure - * Return Value: None - */ -static int mgsl_chars_in_buffer(struct tty_struct *tty) -{ - struct mgsl_struct *info = tty->driver_data; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_chars_in_buffer(%s)\n", - __FILE__,__LINE__, info->device_name ); - - if (mgsl_paranoia_check(info, tty->name, "mgsl_chars_in_buffer")) - return 0; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_chars_in_buffer(%s)=%d\n", - __FILE__,__LINE__, info->device_name,info->xmit_cnt ); - - if ( info->params.mode == MGSL_MODE_HDLC || - info->params.mode == MGSL_MODE_RAW ) { - /* operating in synchronous (frame oriented) mode */ - if ( info->tx_active ) - return info->max_frame_size; - else - return 0; - } - - return info->xmit_cnt; -} /* end of mgsl_chars_in_buffer() */ - -/* mgsl_flush_buffer() - * - * Discard all data in the send buffer - * - * Arguments: tty pointer to tty info structure - * Return Value: None - */ -static void mgsl_flush_buffer(struct tty_struct *tty) -{ - struct mgsl_struct *info = tty->driver_data; - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_flush_buffer(%s) entry\n", - __FILE__,__LINE__, info->device_name ); - - if (mgsl_paranoia_check(info, tty->name, "mgsl_flush_buffer")) - return; - - spin_lock_irqsave(&info->irq_spinlock,flags); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - del_timer(&info->tx_timer); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - tty_wakeup(tty); -} - -/* mgsl_send_xchar() - * - * Send a high-priority XON/XOFF character - * - * Arguments: tty pointer to tty info structure - * ch character to send - * Return Value: None - */ -static void mgsl_send_xchar(struct tty_struct *tty, char ch) -{ - struct mgsl_struct *info = tty->driver_data; - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_send_xchar(%s,%d)\n", - __FILE__,__LINE__, info->device_name, ch ); - - if (mgsl_paranoia_check(info, tty->name, "mgsl_send_xchar")) - return; - - info->x_char = ch; - if (ch) { - /* Make sure transmit interrupts are on */ - spin_lock_irqsave(&info->irq_spinlock,flags); - if (!info->tx_enabled) - usc_start_transmitter(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - } -} /* end of mgsl_send_xchar() */ - -/* mgsl_throttle() - * - * Signal remote device to throttle send data (our receive data) - * - * Arguments: tty pointer to tty info structure - * Return Value: None - */ -static void mgsl_throttle(struct tty_struct * tty) -{ - struct mgsl_struct *info = tty->driver_data; - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_throttle(%s) entry\n", - __FILE__,__LINE__, info->device_name ); - - if (mgsl_paranoia_check(info, tty->name, "mgsl_throttle")) - return; - - if (I_IXOFF(tty)) - mgsl_send_xchar(tty, STOP_CHAR(tty)); - - if (tty->termios->c_cflag & CRTSCTS) { - spin_lock_irqsave(&info->irq_spinlock,flags); - info->serial_signals &= ~SerialSignal_RTS; - usc_set_serial_signals(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - } -} /* end of mgsl_throttle() */ - -/* mgsl_unthrottle() - * - * Signal remote device to stop throttling send data (our receive data) - * - * Arguments: tty pointer to tty info structure - * Return Value: None - */ -static void mgsl_unthrottle(struct tty_struct * tty) -{ - struct mgsl_struct *info = tty->driver_data; - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_unthrottle(%s) entry\n", - __FILE__,__LINE__, info->device_name ); - - if (mgsl_paranoia_check(info, tty->name, "mgsl_unthrottle")) - return; - - if (I_IXOFF(tty)) { - if (info->x_char) - info->x_char = 0; - else - mgsl_send_xchar(tty, START_CHAR(tty)); - } - - if (tty->termios->c_cflag & CRTSCTS) { - spin_lock_irqsave(&info->irq_spinlock,flags); - info->serial_signals |= SerialSignal_RTS; - usc_set_serial_signals(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - } - -} /* end of mgsl_unthrottle() */ - -/* mgsl_get_stats() - * - * get the current serial parameters information - * - * Arguments: info pointer to device instance data - * user_icount pointer to buffer to hold returned stats - * - * Return Value: 0 if success, otherwise error code - */ -static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount __user *user_icount) -{ - int err; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_get_params(%s)\n", - __FILE__,__LINE__, info->device_name); - - if (!user_icount) { - memset(&info->icount, 0, sizeof(info->icount)); - } else { - mutex_lock(&info->port.mutex); - COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount)); - mutex_unlock(&info->port.mutex); - if (err) - return -EFAULT; - } - - return 0; - -} /* end of mgsl_get_stats() */ - -/* mgsl_get_params() - * - * get the current serial parameters information - * - * Arguments: info pointer to device instance data - * user_params pointer to buffer to hold returned params - * - * Return Value: 0 if success, otherwise error code - */ -static int mgsl_get_params(struct mgsl_struct * info, MGSL_PARAMS __user *user_params) -{ - int err; - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_get_params(%s)\n", - __FILE__,__LINE__, info->device_name); - - mutex_lock(&info->port.mutex); - COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS)); - mutex_unlock(&info->port.mutex); - if (err) { - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):mgsl_get_params(%s) user buffer copy failed\n", - __FILE__,__LINE__,info->device_name); - return -EFAULT; - } - - return 0; - -} /* end of mgsl_get_params() */ - -/* mgsl_set_params() - * - * set the serial parameters - * - * Arguments: - * - * info pointer to device instance data - * new_params user buffer containing new serial params - * - * Return Value: 0 if success, otherwise error code - */ -static int mgsl_set_params(struct mgsl_struct * info, MGSL_PARAMS __user *new_params) -{ - unsigned long flags; - MGSL_PARAMS tmp_params; - int err; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_set_params %s\n", __FILE__,__LINE__, - info->device_name ); - COPY_FROM_USER(err,&tmp_params, new_params, sizeof(MGSL_PARAMS)); - if (err) { - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):mgsl_set_params(%s) user buffer copy failed\n", - __FILE__,__LINE__,info->device_name); - return -EFAULT; - } - - mutex_lock(&info->port.mutex); - spin_lock_irqsave(&info->irq_spinlock,flags); - memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS)); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - mgsl_change_params(info); - mutex_unlock(&info->port.mutex); - - return 0; - -} /* end of mgsl_set_params() */ - -/* mgsl_get_txidle() - * - * get the current transmit idle mode - * - * Arguments: info pointer to device instance data - * idle_mode pointer to buffer to hold returned idle mode - * - * Return Value: 0 if success, otherwise error code - */ -static int mgsl_get_txidle(struct mgsl_struct * info, int __user *idle_mode) -{ - int err; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_get_txidle(%s)=%d\n", - __FILE__,__LINE__, info->device_name, info->idle_mode); - - COPY_TO_USER(err,idle_mode, &info->idle_mode, sizeof(int)); - if (err) { - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):mgsl_get_txidle(%s) user buffer copy failed\n", - __FILE__,__LINE__,info->device_name); - return -EFAULT; - } - - return 0; - -} /* end of mgsl_get_txidle() */ - -/* mgsl_set_txidle() service ioctl to set transmit idle mode - * - * Arguments: info pointer to device instance data - * idle_mode new idle mode - * - * Return Value: 0 if success, otherwise error code - */ -static int mgsl_set_txidle(struct mgsl_struct * info, int idle_mode) -{ - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_set_txidle(%s,%d)\n", __FILE__,__LINE__, - info->device_name, idle_mode ); - - spin_lock_irqsave(&info->irq_spinlock,flags); - info->idle_mode = idle_mode; - usc_set_txidle( info ); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - return 0; - -} /* end of mgsl_set_txidle() */ - -/* mgsl_txenable() - * - * enable or disable the transmitter - * - * Arguments: - * - * info pointer to device instance data - * enable 1 = enable, 0 = disable - * - * Return Value: 0 if success, otherwise error code - */ -static int mgsl_txenable(struct mgsl_struct * info, int enable) -{ - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_txenable(%s,%d)\n", __FILE__,__LINE__, - info->device_name, enable); - - spin_lock_irqsave(&info->irq_spinlock,flags); - if ( enable ) { - if ( !info->tx_enabled ) { - - usc_start_transmitter(info); - /*-------------------------------------------------- - * if HDLC/SDLC Loop mode, attempt to insert the - * station in the 'loop' by setting CMR:13. Upon - * receipt of the next GoAhead (RxAbort) sequence, - * the OnLoop indicator (CCSR:7) should go active - * to indicate that we are on the loop - *--------------------------------------------------*/ - if ( info->params.flags & HDLC_FLAG_HDLC_LOOPMODE ) - usc_loopmode_insert_request( info ); - } - } else { - if ( info->tx_enabled ) - usc_stop_transmitter(info); - } - spin_unlock_irqrestore(&info->irq_spinlock,flags); - return 0; - -} /* end of mgsl_txenable() */ - -/* mgsl_txabort() abort send HDLC frame - * - * Arguments: info pointer to device instance data - * Return Value: 0 if success, otherwise error code - */ -static int mgsl_txabort(struct mgsl_struct * info) -{ - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_txabort(%s)\n", __FILE__,__LINE__, - info->device_name); - - spin_lock_irqsave(&info->irq_spinlock,flags); - if ( info->tx_active && info->params.mode == MGSL_MODE_HDLC ) - { - if ( info->params.flags & HDLC_FLAG_HDLC_LOOPMODE ) - usc_loopmode_cancel_transmit( info ); - else - usc_TCmd(info,TCmd_SendAbort); - } - spin_unlock_irqrestore(&info->irq_spinlock,flags); - return 0; - -} /* end of mgsl_txabort() */ - -/* mgsl_rxenable() enable or disable the receiver - * - * Arguments: info pointer to device instance data - * enable 1 = enable, 0 = disable - * Return Value: 0 if success, otherwise error code - */ -static int mgsl_rxenable(struct mgsl_struct * info, int enable) -{ - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_rxenable(%s,%d)\n", __FILE__,__LINE__, - info->device_name, enable); - - spin_lock_irqsave(&info->irq_spinlock,flags); - if ( enable ) { - if ( !info->rx_enabled ) - usc_start_receiver(info); - } else { - if ( info->rx_enabled ) - usc_stop_receiver(info); - } - spin_unlock_irqrestore(&info->irq_spinlock,flags); - return 0; - -} /* end of mgsl_rxenable() */ - -/* mgsl_wait_event() wait for specified event to occur - * - * Arguments: info pointer to device instance data - * mask pointer to bitmask of events to wait for - * Return Value: 0 if successful and bit mask updated with - * of events triggerred, - * otherwise error code - */ -static int mgsl_wait_event(struct mgsl_struct * info, int __user * mask_ptr) -{ - unsigned long flags; - int s; - int rc=0; - struct mgsl_icount cprev, cnow; - int events; - int mask; - struct _input_signal_events oldsigs, newsigs; - DECLARE_WAITQUEUE(wait, current); - - COPY_FROM_USER(rc,&mask, mask_ptr, sizeof(int)); - if (rc) { - return -EFAULT; - } - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_wait_event(%s,%d)\n", __FILE__,__LINE__, - info->device_name, mask); - - spin_lock_irqsave(&info->irq_spinlock,flags); - - /* return immediately if state matches requested events */ - usc_get_serial_signals(info); - s = info->serial_signals; - events = mask & - ( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) + - ((s & SerialSignal_DCD) ? MgslEvent_DcdActive:MgslEvent_DcdInactive) + - ((s & SerialSignal_CTS) ? MgslEvent_CtsActive:MgslEvent_CtsInactive) + - ((s & SerialSignal_RI) ? MgslEvent_RiActive :MgslEvent_RiInactive) ); - if (events) { - spin_unlock_irqrestore(&info->irq_spinlock,flags); - goto exit; - } - - /* save current irq counts */ - cprev = info->icount; - oldsigs = info->input_signal_events; - - /* enable hunt and idle irqs if needed */ - if (mask & (MgslEvent_ExitHuntMode + MgslEvent_IdleReceived)) { - u16 oldreg = usc_InReg(info,RICR); - u16 newreg = oldreg + - (mask & MgslEvent_ExitHuntMode ? RXSTATUS_EXITED_HUNT:0) + - (mask & MgslEvent_IdleReceived ? RXSTATUS_IDLE_RECEIVED:0); - if (oldreg != newreg) - usc_OutReg(info, RICR, newreg); - } - - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&info->event_wait_q, &wait); - - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - - for(;;) { - schedule(); - if (signal_pending(current)) { - rc = -ERESTARTSYS; - break; - } - - /* get current irq counts */ - spin_lock_irqsave(&info->irq_spinlock,flags); - cnow = info->icount; - newsigs = info->input_signal_events; - set_current_state(TASK_INTERRUPTIBLE); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - /* if no change, wait aborted for some reason */ - if (newsigs.dsr_up == oldsigs.dsr_up && - newsigs.dsr_down == oldsigs.dsr_down && - newsigs.dcd_up == oldsigs.dcd_up && - newsigs.dcd_down == oldsigs.dcd_down && - newsigs.cts_up == oldsigs.cts_up && - newsigs.cts_down == oldsigs.cts_down && - newsigs.ri_up == oldsigs.ri_up && - newsigs.ri_down == oldsigs.ri_down && - cnow.exithunt == cprev.exithunt && - cnow.rxidle == cprev.rxidle) { - rc = -EIO; - break; - } - - events = mask & - ( (newsigs.dsr_up != oldsigs.dsr_up ? MgslEvent_DsrActive:0) + - (newsigs.dsr_down != oldsigs.dsr_down ? MgslEvent_DsrInactive:0) + - (newsigs.dcd_up != oldsigs.dcd_up ? MgslEvent_DcdActive:0) + - (newsigs.dcd_down != oldsigs.dcd_down ? MgslEvent_DcdInactive:0) + - (newsigs.cts_up != oldsigs.cts_up ? MgslEvent_CtsActive:0) + - (newsigs.cts_down != oldsigs.cts_down ? MgslEvent_CtsInactive:0) + - (newsigs.ri_up != oldsigs.ri_up ? MgslEvent_RiActive:0) + - (newsigs.ri_down != oldsigs.ri_down ? MgslEvent_RiInactive:0) + - (cnow.exithunt != cprev.exithunt ? MgslEvent_ExitHuntMode:0) + - (cnow.rxidle != cprev.rxidle ? MgslEvent_IdleReceived:0) ); - if (events) - break; - - cprev = cnow; - oldsigs = newsigs; - } - - remove_wait_queue(&info->event_wait_q, &wait); - set_current_state(TASK_RUNNING); - - if (mask & (MgslEvent_ExitHuntMode + MgslEvent_IdleReceived)) { - spin_lock_irqsave(&info->irq_spinlock,flags); - if (!waitqueue_active(&info->event_wait_q)) { - /* disable enable exit hunt mode/idle rcvd IRQs */ - usc_OutReg(info, RICR, usc_InReg(info,RICR) & - ~(RXSTATUS_EXITED_HUNT + RXSTATUS_IDLE_RECEIVED)); - } - spin_unlock_irqrestore(&info->irq_spinlock,flags); - } -exit: - if ( rc == 0 ) - PUT_USER(rc, events, mask_ptr); - - return rc; - -} /* end of mgsl_wait_event() */ - -static int modem_input_wait(struct mgsl_struct *info,int arg) -{ - unsigned long flags; - int rc; - struct mgsl_icount cprev, cnow; - DECLARE_WAITQUEUE(wait, current); - - /* save current irq counts */ - spin_lock_irqsave(&info->irq_spinlock,flags); - cprev = info->icount; - add_wait_queue(&info->status_event_wait_q, &wait); - set_current_state(TASK_INTERRUPTIBLE); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - for(;;) { - schedule(); - if (signal_pending(current)) { - rc = -ERESTARTSYS; - break; - } - - /* get new irq counts */ - spin_lock_irqsave(&info->irq_spinlock,flags); - cnow = info->icount; - set_current_state(TASK_INTERRUPTIBLE); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - /* if no change, wait aborted for some reason */ - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { - rc = -EIO; - break; - } - - /* check for change in caller specified modem input */ - if ((arg & TIOCM_RNG && cnow.rng != cprev.rng) || - (arg & TIOCM_DSR && cnow.dsr != cprev.dsr) || - (arg & TIOCM_CD && cnow.dcd != cprev.dcd) || - (arg & TIOCM_CTS && cnow.cts != cprev.cts)) { - rc = 0; - break; - } - - cprev = cnow; - } - remove_wait_queue(&info->status_event_wait_q, &wait); - set_current_state(TASK_RUNNING); - return rc; -} - -/* return the state of the serial control and status signals - */ -static int tiocmget(struct tty_struct *tty) -{ - struct mgsl_struct *info = tty->driver_data; - unsigned int result; - unsigned long flags; - - spin_lock_irqsave(&info->irq_spinlock,flags); - usc_get_serial_signals(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - result = ((info->serial_signals & SerialSignal_RTS) ? TIOCM_RTS:0) + - ((info->serial_signals & SerialSignal_DTR) ? TIOCM_DTR:0) + - ((info->serial_signals & SerialSignal_DCD) ? TIOCM_CAR:0) + - ((info->serial_signals & SerialSignal_RI) ? TIOCM_RNG:0) + - ((info->serial_signals & SerialSignal_DSR) ? TIOCM_DSR:0) + - ((info->serial_signals & SerialSignal_CTS) ? TIOCM_CTS:0); - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s tiocmget() value=%08X\n", - __FILE__,__LINE__, info->device_name, result ); - return result; -} - -/* set modem control signals (DTR/RTS) - */ -static int tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct mgsl_struct *info = tty->driver_data; - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s tiocmset(%x,%x)\n", - __FILE__,__LINE__,info->device_name, set, clear); - - if (set & TIOCM_RTS) - info->serial_signals |= SerialSignal_RTS; - if (set & TIOCM_DTR) - info->serial_signals |= SerialSignal_DTR; - if (clear & TIOCM_RTS) - info->serial_signals &= ~SerialSignal_RTS; - if (clear & TIOCM_DTR) - info->serial_signals &= ~SerialSignal_DTR; - - spin_lock_irqsave(&info->irq_spinlock,flags); - usc_set_serial_signals(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - return 0; -} - -/* mgsl_break() Set or clear transmit break condition - * - * Arguments: tty pointer to tty instance data - * break_state -1=set break condition, 0=clear - * Return Value: error code - */ -static int mgsl_break(struct tty_struct *tty, int break_state) -{ - struct mgsl_struct * info = tty->driver_data; - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_break(%s,%d)\n", - __FILE__,__LINE__, info->device_name, break_state); - - if (mgsl_paranoia_check(info, tty->name, "mgsl_break")) - return -EINVAL; - - spin_lock_irqsave(&info->irq_spinlock,flags); - if (break_state == -1) - usc_OutReg(info,IOCR,(u16)(usc_InReg(info,IOCR) | BIT7)); - else - usc_OutReg(info,IOCR,(u16)(usc_InReg(info,IOCR) & ~BIT7)); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - return 0; - -} /* end of mgsl_break() */ - -/* - * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) - * Return: write counters to the user passed counter struct - * NB: both 1->0 and 0->1 transitions are counted except for - * RI where only 0->1 is counted. - */ -static int msgl_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) - -{ - struct mgsl_struct * info = tty->driver_data; - struct mgsl_icount cnow; /* kernel counter temps */ - unsigned long flags; - - spin_lock_irqsave(&info->irq_spinlock,flags); - cnow = info->icount; - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - icount->cts = cnow.cts; - icount->dsr = cnow.dsr; - icount->rng = cnow.rng; - icount->dcd = cnow.dcd; - icount->rx = cnow.rx; - icount->tx = cnow.tx; - icount->frame = cnow.frame; - icount->overrun = cnow.overrun; - icount->parity = cnow.parity; - icount->brk = cnow.brk; - icount->buf_overrun = cnow.buf_overrun; - return 0; -} - -/* mgsl_ioctl() Service an IOCTL request - * - * Arguments: - * - * tty pointer to tty instance data - * cmd IOCTL command code - * arg command argument/context - * - * Return Value: 0 if success, otherwise error code - */ -static int mgsl_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct mgsl_struct * info = tty->driver_data; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_ioctl %s cmd=%08X\n", __FILE__,__LINE__, - info->device_name, cmd ); - - if (mgsl_paranoia_check(info, tty->name, "mgsl_ioctl")) - return -ENODEV; - - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCMIWAIT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - } - - return mgsl_ioctl_common(info, cmd, arg); -} - -static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg) -{ - void __user *argp = (void __user *)arg; - - switch (cmd) { - case MGSL_IOCGPARAMS: - return mgsl_get_params(info, argp); - case MGSL_IOCSPARAMS: - return mgsl_set_params(info, argp); - case MGSL_IOCGTXIDLE: - return mgsl_get_txidle(info, argp); - case MGSL_IOCSTXIDLE: - return mgsl_set_txidle(info,(int)arg); - case MGSL_IOCTXENABLE: - return mgsl_txenable(info,(int)arg); - case MGSL_IOCRXENABLE: - return mgsl_rxenable(info,(int)arg); - case MGSL_IOCTXABORT: - return mgsl_txabort(info); - case MGSL_IOCGSTATS: - return mgsl_get_stats(info, argp); - case MGSL_IOCWAITEVENT: - return mgsl_wait_event(info, argp); - case MGSL_IOCLOOPTXDONE: - return mgsl_loopmode_send_done(info); - /* Wait for modem input (DCD,RI,DSR,CTS) change - * as specified by mask in arg (TIOCM_RNG/DSR/CD/CTS) - */ - case TIOCMIWAIT: - return modem_input_wait(info,(int)arg); - - default: - return -ENOIOCTLCMD; - } - return 0; -} - -/* mgsl_set_termios() - * - * Set new termios settings - * - * Arguments: - * - * tty pointer to tty structure - * termios pointer to buffer to hold returned old termios - * - * Return Value: None - */ -static void mgsl_set_termios(struct tty_struct *tty, struct ktermios *old_termios) -{ - struct mgsl_struct *info = tty->driver_data; - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_set_termios %s\n", __FILE__,__LINE__, - tty->driver->name ); - - mgsl_change_params(info); - - /* Handle transition to B0 status */ - if (old_termios->c_cflag & CBAUD && - !(tty->termios->c_cflag & CBAUD)) { - info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); - spin_lock_irqsave(&info->irq_spinlock,flags); - usc_set_serial_signals(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - } - - /* Handle transition away from B0 status */ - if (!(old_termios->c_cflag & CBAUD) && - tty->termios->c_cflag & CBAUD) { - info->serial_signals |= SerialSignal_DTR; - if (!(tty->termios->c_cflag & CRTSCTS) || - !test_bit(TTY_THROTTLED, &tty->flags)) { - info->serial_signals |= SerialSignal_RTS; - } - spin_lock_irqsave(&info->irq_spinlock,flags); - usc_set_serial_signals(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - } - - /* Handle turning off CRTSCTS */ - if (old_termios->c_cflag & CRTSCTS && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - mgsl_start(tty); - } - -} /* end of mgsl_set_termios() */ - -/* mgsl_close() - * - * Called when port is closed. Wait for remaining data to be - * sent. Disable port and free resources. - * - * Arguments: - * - * tty pointer to open tty structure - * filp pointer to open file object - * - * Return Value: None - */ -static void mgsl_close(struct tty_struct *tty, struct file * filp) -{ - struct mgsl_struct * info = tty->driver_data; - - if (mgsl_paranoia_check(info, tty->name, "mgsl_close")) - return; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_close(%s) entry, count=%d\n", - __FILE__,__LINE__, info->device_name, info->port.count); - - if (tty_port_close_start(&info->port, tty, filp) == 0) - goto cleanup; - - mutex_lock(&info->port.mutex); - if (info->port.flags & ASYNC_INITIALIZED) - mgsl_wait_until_sent(tty, info->timeout); - mgsl_flush_buffer(tty); - tty_ldisc_flush(tty); - shutdown(info); - mutex_unlock(&info->port.mutex); - - tty_port_close_end(&info->port, tty); - info->port.tty = NULL; -cleanup: - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_close(%s) exit, count=%d\n", __FILE__,__LINE__, - tty->driver->name, info->port.count); - -} /* end of mgsl_close() */ - -/* mgsl_wait_until_sent() - * - * Wait until the transmitter is empty. - * - * Arguments: - * - * tty pointer to tty info structure - * timeout time to wait for send completion - * - * Return Value: None - */ -static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout) -{ - struct mgsl_struct * info = tty->driver_data; - unsigned long orig_jiffies, char_time; - - if (!info ) - return; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_wait_until_sent(%s) entry\n", - __FILE__,__LINE__, info->device_name ); - - if (mgsl_paranoia_check(info, tty->name, "mgsl_wait_until_sent")) - return; - - if (!(info->port.flags & ASYNC_INITIALIZED)) - goto exit; - - orig_jiffies = jiffies; - - /* Set check interval to 1/5 of estimated time to - * send a character, and make it at least 1. The check - * interval should also be less than the timeout. - * Note: use tight timings here to satisfy the NIST-PCTS. - */ - - if ( info->params.data_rate ) { - char_time = info->timeout/(32 * 5); - if (!char_time) - char_time++; - } else - char_time = 1; - - if (timeout) - char_time = min_t(unsigned long, char_time, timeout); - - if ( info->params.mode == MGSL_MODE_HDLC || - info->params.mode == MGSL_MODE_RAW ) { - while (info->tx_active) { - msleep_interruptible(jiffies_to_msecs(char_time)); - if (signal_pending(current)) - break; - if (timeout && time_after(jiffies, orig_jiffies + timeout)) - break; - } - } else { - while (!(usc_InReg(info,TCSR) & TXSTATUS_ALL_SENT) && - info->tx_enabled) { - msleep_interruptible(jiffies_to_msecs(char_time)); - if (signal_pending(current)) - break; - if (timeout && time_after(jiffies, orig_jiffies + timeout)) - break; - } - } - -exit: - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_wait_until_sent(%s) exit\n", - __FILE__,__LINE__, info->device_name ); - -} /* end of mgsl_wait_until_sent() */ - -/* mgsl_hangup() - * - * Called by tty_hangup() when a hangup is signaled. - * This is the same as to closing all open files for the port. - * - * Arguments: tty pointer to associated tty object - * Return Value: None - */ -static void mgsl_hangup(struct tty_struct *tty) -{ - struct mgsl_struct * info = tty->driver_data; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_hangup(%s)\n", - __FILE__,__LINE__, info->device_name ); - - if (mgsl_paranoia_check(info, tty->name, "mgsl_hangup")) - return; - - mgsl_flush_buffer(tty); - shutdown(info); - - info->port.count = 0; - info->port.flags &= ~ASYNC_NORMAL_ACTIVE; - info->port.tty = NULL; - - wake_up_interruptible(&info->port.open_wait); - -} /* end of mgsl_hangup() */ - -/* - * carrier_raised() - * - * Return true if carrier is raised - */ - -static int carrier_raised(struct tty_port *port) -{ - unsigned long flags; - struct mgsl_struct *info = container_of(port, struct mgsl_struct, port); - - spin_lock_irqsave(&info->irq_spinlock, flags); - usc_get_serial_signals(info); - spin_unlock_irqrestore(&info->irq_spinlock, flags); - return (info->serial_signals & SerialSignal_DCD) ? 1 : 0; -} - -static void dtr_rts(struct tty_port *port, int on) -{ - struct mgsl_struct *info = container_of(port, struct mgsl_struct, port); - unsigned long flags; - - spin_lock_irqsave(&info->irq_spinlock,flags); - if (on) - info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; - else - info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); - usc_set_serial_signals(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); -} - - -/* block_til_ready() - * - * Block the current process until the specified port - * is ready to be opened. - * - * Arguments: - * - * tty pointer to tty info structure - * filp pointer to open file object - * info pointer to device instance data - * - * Return Value: 0 if success, otherwise error code - */ -static int block_til_ready(struct tty_struct *tty, struct file * filp, - struct mgsl_struct *info) -{ - DECLARE_WAITQUEUE(wait, current); - int retval; - bool do_clocal = false; - bool extra_count = false; - unsigned long flags; - int dcd; - struct tty_port *port = &info->port; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):block_til_ready on %s\n", - __FILE__,__LINE__, tty->driver->name ); - - if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ - /* nonblock mode is set or port is not enabled */ - port->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - if (tty->termios->c_cflag & CLOCAL) - do_clocal = true; - - /* Wait for carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, port->count is dropped by one, so that - * mgsl_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - - retval = 0; - add_wait_queue(&port->open_wait, &wait); - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):block_til_ready before block on %s count=%d\n", - __FILE__,__LINE__, tty->driver->name, port->count ); - - spin_lock_irqsave(&info->irq_spinlock, flags); - if (!tty_hung_up_p(filp)) { - extra_count = true; - port->count--; - } - spin_unlock_irqrestore(&info->irq_spinlock, flags); - port->blocked_open++; - - while (1) { - if (tty->termios->c_cflag & CBAUD) - tty_port_raise_dtr_rts(port); - - set_current_state(TASK_INTERRUPTIBLE); - - if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){ - retval = (port->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS; - break; - } - - dcd = tty_port_carrier_raised(&info->port); - - if (!(port->flags & ASYNC_CLOSING) && (do_clocal || dcd)) - break; - - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):block_til_ready blocking on %s count=%d\n", - __FILE__,__LINE__, tty->driver->name, port->count ); - - tty_unlock(); - schedule(); - tty_lock(); - } - - set_current_state(TASK_RUNNING); - remove_wait_queue(&port->open_wait, &wait); - - /* FIXME: Racy on hangup during close wait */ - if (extra_count) - port->count++; - port->blocked_open--; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):block_til_ready after blocking on %s count=%d\n", - __FILE__,__LINE__, tty->driver->name, port->count ); - - if (!retval) - port->flags |= ASYNC_NORMAL_ACTIVE; - - return retval; - -} /* end of block_til_ready() */ - -/* mgsl_open() - * - * Called when a port is opened. Init and enable port. - * Perform serial-specific initialization for the tty structure. - * - * Arguments: tty pointer to tty info structure - * filp associated file pointer - * - * Return Value: 0 if success, otherwise error code - */ -static int mgsl_open(struct tty_struct *tty, struct file * filp) -{ - struct mgsl_struct *info; - int retval, line; - unsigned long flags; - - /* verify range of specified line number */ - line = tty->index; - if ((line < 0) || (line >= mgsl_device_count)) { - printk("%s(%d):mgsl_open with invalid line #%d.\n", - __FILE__,__LINE__,line); - return -ENODEV; - } - - /* find the info structure for the specified line */ - info = mgsl_device_list; - while(info && info->line != line) - info = info->next_device; - if (mgsl_paranoia_check(info, tty->name, "mgsl_open")) - return -ENODEV; - - tty->driver_data = info; - info->port.tty = tty; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_open(%s), old ref count = %d\n", - __FILE__,__LINE__,tty->driver->name, info->port.count); - - /* If port is closing, signal caller to try again */ - if (tty_hung_up_p(filp) || info->port.flags & ASYNC_CLOSING){ - if (info->port.flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->port.close_wait); - retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); - goto cleanup; - } - - info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; - - spin_lock_irqsave(&info->netlock, flags); - if (info->netcount) { - retval = -EBUSY; - spin_unlock_irqrestore(&info->netlock, flags); - goto cleanup; - } - info->port.count++; - spin_unlock_irqrestore(&info->netlock, flags); - - if (info->port.count == 1) { - /* 1st open on this device, init hardware */ - retval = startup(info); - if (retval < 0) - goto cleanup; - } - - retval = block_til_ready(tty, filp, info); - if (retval) { - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):block_til_ready(%s) returned %d\n", - __FILE__,__LINE__, info->device_name, retval); - goto cleanup; - } - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):mgsl_open(%s) success\n", - __FILE__,__LINE__, info->device_name); - retval = 0; - -cleanup: - if (retval) { - if (tty->count == 1) - info->port.tty = NULL; /* tty layer will release tty struct */ - if(info->port.count) - info->port.count--; - } - - return retval; - -} /* end of mgsl_open() */ - -/* - * /proc fs routines.... - */ - -static inline void line_info(struct seq_file *m, struct mgsl_struct *info) -{ - char stat_buf[30]; - unsigned long flags; - - if (info->bus_type == MGSL_BUS_TYPE_PCI) { - seq_printf(m, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X", - info->device_name, info->io_base, info->irq_level, - info->phys_memory_base, info->phys_lcr_base); - } else { - seq_printf(m, "%s:(E)ISA io:%04X irq:%d dma:%d", - info->device_name, info->io_base, - info->irq_level, info->dma_level); - } - - /* output current serial signal states */ - spin_lock_irqsave(&info->irq_spinlock,flags); - usc_get_serial_signals(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - stat_buf[0] = 0; - stat_buf[1] = 0; - if (info->serial_signals & SerialSignal_RTS) - strcat(stat_buf, "|RTS"); - if (info->serial_signals & SerialSignal_CTS) - strcat(stat_buf, "|CTS"); - if (info->serial_signals & SerialSignal_DTR) - strcat(stat_buf, "|DTR"); - if (info->serial_signals & SerialSignal_DSR) - strcat(stat_buf, "|DSR"); - if (info->serial_signals & SerialSignal_DCD) - strcat(stat_buf, "|CD"); - if (info->serial_signals & SerialSignal_RI) - strcat(stat_buf, "|RI"); - - if (info->params.mode == MGSL_MODE_HDLC || - info->params.mode == MGSL_MODE_RAW ) { - seq_printf(m, " HDLC txok:%d rxok:%d", - info->icount.txok, info->icount.rxok); - if (info->icount.txunder) - seq_printf(m, " txunder:%d", info->icount.txunder); - if (info->icount.txabort) - seq_printf(m, " txabort:%d", info->icount.txabort); - if (info->icount.rxshort) - seq_printf(m, " rxshort:%d", info->icount.rxshort); - if (info->icount.rxlong) - seq_printf(m, " rxlong:%d", info->icount.rxlong); - if (info->icount.rxover) - seq_printf(m, " rxover:%d", info->icount.rxover); - if (info->icount.rxcrc) - seq_printf(m, " rxcrc:%d", info->icount.rxcrc); - } else { - seq_printf(m, " ASYNC tx:%d rx:%d", - info->icount.tx, info->icount.rx); - if (info->icount.frame) - seq_printf(m, " fe:%d", info->icount.frame); - if (info->icount.parity) - seq_printf(m, " pe:%d", info->icount.parity); - if (info->icount.brk) - seq_printf(m, " brk:%d", info->icount.brk); - if (info->icount.overrun) - seq_printf(m, " oe:%d", info->icount.overrun); - } - - /* Append serial signal status to end */ - seq_printf(m, " %s\n", stat_buf+1); - - seq_printf(m, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", - info->tx_active,info->bh_requested,info->bh_running, - info->pending_bh); - - spin_lock_irqsave(&info->irq_spinlock,flags); - { - u16 Tcsr = usc_InReg( info, TCSR ); - u16 Tdmr = usc_InDmaReg( info, TDMR ); - u16 Ticr = usc_InReg( info, TICR ); - u16 Rscr = usc_InReg( info, RCSR ); - u16 Rdmr = usc_InDmaReg( info, RDMR ); - u16 Ricr = usc_InReg( info, RICR ); - u16 Icr = usc_InReg( info, ICR ); - u16 Dccr = usc_InReg( info, DCCR ); - u16 Tmr = usc_InReg( info, TMR ); - u16 Tccr = usc_InReg( info, TCCR ); - u16 Ccar = inw( info->io_base + CCAR ); - seq_printf(m, "tcsr=%04X tdmr=%04X ticr=%04X rcsr=%04X rdmr=%04X\n" - "ricr=%04X icr =%04X dccr=%04X tmr=%04X tccr=%04X ccar=%04X\n", - Tcsr,Tdmr,Ticr,Rscr,Rdmr,Ricr,Icr,Dccr,Tmr,Tccr,Ccar ); - } - spin_unlock_irqrestore(&info->irq_spinlock,flags); -} - -/* Called to print information about devices */ -static int mgsl_proc_show(struct seq_file *m, void *v) -{ - struct mgsl_struct *info; - - seq_printf(m, "synclink driver:%s\n", driver_version); - - info = mgsl_device_list; - while( info ) { - line_info(m, info); - info = info->next_device; - } - return 0; -} - -static int mgsl_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, mgsl_proc_show, NULL); -} - -static const struct file_operations mgsl_proc_fops = { - .owner = THIS_MODULE, - .open = mgsl_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/* mgsl_allocate_dma_buffers() - * - * Allocate and format DMA buffers (ISA adapter) - * or format shared memory buffers (PCI adapter). - * - * Arguments: info pointer to device instance data - * Return Value: 0 if success, otherwise error - */ -static int mgsl_allocate_dma_buffers(struct mgsl_struct *info) -{ - unsigned short BuffersPerFrame; - - info->last_mem_alloc = 0; - - /* Calculate the number of DMA buffers necessary to hold the */ - /* largest allowable frame size. Note: If the max frame size is */ - /* not an even multiple of the DMA buffer size then we need to */ - /* round the buffer count per frame up one. */ - - BuffersPerFrame = (unsigned short)(info->max_frame_size/DMABUFFERSIZE); - if ( info->max_frame_size % DMABUFFERSIZE ) - BuffersPerFrame++; - - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { - /* - * The PCI adapter has 256KBytes of shared memory to use. - * This is 64 PAGE_SIZE buffers. - * - * The first page is used for padding at this time so the - * buffer list does not begin at offset 0 of the PCI - * adapter's shared memory. - * - * The 2nd page is used for the buffer list. A 4K buffer - * list can hold 128 DMA_BUFFER structures at 32 bytes - * each. - * - * This leaves 62 4K pages. - * - * The next N pages are used for transmit frame(s). We - * reserve enough 4K page blocks to hold the required - * number of transmit dma buffers (num_tx_dma_buffers), - * each of MaxFrameSize size. - * - * Of the remaining pages (62-N), determine how many can - * be used to receive full MaxFrameSize inbound frames - */ - info->tx_buffer_count = info->num_tx_dma_buffers * BuffersPerFrame; - info->rx_buffer_count = 62 - info->tx_buffer_count; - } else { - /* Calculate the number of PAGE_SIZE buffers needed for */ - /* receive and transmit DMA buffers. */ - - - /* Calculate the number of DMA buffers necessary to */ - /* hold 7 max size receive frames and one max size transmit frame. */ - /* The receive buffer count is bumped by one so we avoid an */ - /* End of List condition if all receive buffers are used when */ - /* using linked list DMA buffers. */ - - info->tx_buffer_count = info->num_tx_dma_buffers * BuffersPerFrame; - info->rx_buffer_count = (BuffersPerFrame * MAXRXFRAMES) + 6; - - /* - * limit total TxBuffers & RxBuffers to 62 4K total - * (ala PCI Allocation) - */ - - if ( (info->tx_buffer_count + info->rx_buffer_count) > 62 ) - info->rx_buffer_count = 62 - info->tx_buffer_count; - - } - - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk("%s(%d):Allocating %d TX and %d RX DMA buffers.\n", - __FILE__,__LINE__, info->tx_buffer_count,info->rx_buffer_count); - - if ( mgsl_alloc_buffer_list_memory( info ) < 0 || - mgsl_alloc_frame_memory(info, info->rx_buffer_list, info->rx_buffer_count) < 0 || - mgsl_alloc_frame_memory(info, info->tx_buffer_list, info->tx_buffer_count) < 0 || - mgsl_alloc_intermediate_rxbuffer_memory(info) < 0 || - mgsl_alloc_intermediate_txbuffer_memory(info) < 0 ) { - printk("%s(%d):Can't allocate DMA buffer memory\n",__FILE__,__LINE__); - return -ENOMEM; - } - - mgsl_reset_rx_dma_buffers( info ); - mgsl_reset_tx_dma_buffers( info ); - - return 0; - -} /* end of mgsl_allocate_dma_buffers() */ - -/* - * mgsl_alloc_buffer_list_memory() - * - * Allocate a common DMA buffer for use as the - * receive and transmit buffer lists. - * - * A buffer list is a set of buffer entries where each entry contains - * a pointer to an actual buffer and a pointer to the next buffer entry - * (plus some other info about the buffer). - * - * The buffer entries for a list are built to form a circular list so - * that when the entire list has been traversed you start back at the - * beginning. - * - * This function allocates memory for just the buffer entries. - * The links (pointer to next entry) are filled in with the physical - * address of the next entry so the adapter can navigate the list - * using bus master DMA. The pointers to the actual buffers are filled - * out later when the actual buffers are allocated. - * - * Arguments: info pointer to device instance data - * Return Value: 0 if success, otherwise error - */ -static int mgsl_alloc_buffer_list_memory( struct mgsl_struct *info ) -{ - unsigned int i; - - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { - /* PCI adapter uses shared memory. */ - info->buffer_list = info->memory_base + info->last_mem_alloc; - info->buffer_list_phys = info->last_mem_alloc; - info->last_mem_alloc += BUFFERLISTSIZE; - } else { - /* ISA adapter uses system memory. */ - /* The buffer lists are allocated as a common buffer that both */ - /* the processor and adapter can access. This allows the driver to */ - /* inspect portions of the buffer while other portions are being */ - /* updated by the adapter using Bus Master DMA. */ - - info->buffer_list = dma_alloc_coherent(NULL, BUFFERLISTSIZE, &info->buffer_list_dma_addr, GFP_KERNEL); - if (info->buffer_list == NULL) - return -ENOMEM; - info->buffer_list_phys = (u32)(info->buffer_list_dma_addr); - } - - /* We got the memory for the buffer entry lists. */ - /* Initialize the memory block to all zeros. */ - memset( info->buffer_list, 0, BUFFERLISTSIZE ); - - /* Save virtual address pointers to the receive and */ - /* transmit buffer lists. (Receive 1st). These pointers will */ - /* be used by the processor to access the lists. */ - info->rx_buffer_list = (DMABUFFERENTRY *)info->buffer_list; - info->tx_buffer_list = (DMABUFFERENTRY *)info->buffer_list; - info->tx_buffer_list += info->rx_buffer_count; - - /* - * Build the links for the buffer entry lists such that - * two circular lists are built. (Transmit and Receive). - * - * Note: the links are physical addresses - * which are read by the adapter to determine the next - * buffer entry to use. - */ - - for ( i = 0; i < info->rx_buffer_count; i++ ) { - /* calculate and store physical address of this buffer entry */ - info->rx_buffer_list[i].phys_entry = - info->buffer_list_phys + (i * sizeof(DMABUFFERENTRY)); - - /* calculate and store physical address of */ - /* next entry in cirular list of entries */ - - info->rx_buffer_list[i].link = info->buffer_list_phys; - - if ( i < info->rx_buffer_count - 1 ) - info->rx_buffer_list[i].link += (i + 1) * sizeof(DMABUFFERENTRY); - } - - for ( i = 0; i < info->tx_buffer_count; i++ ) { - /* calculate and store physical address of this buffer entry */ - info->tx_buffer_list[i].phys_entry = info->buffer_list_phys + - ((info->rx_buffer_count + i) * sizeof(DMABUFFERENTRY)); - - /* calculate and store physical address of */ - /* next entry in cirular list of entries */ - - info->tx_buffer_list[i].link = info->buffer_list_phys + - info->rx_buffer_count * sizeof(DMABUFFERENTRY); - - if ( i < info->tx_buffer_count - 1 ) - info->tx_buffer_list[i].link += (i + 1) * sizeof(DMABUFFERENTRY); - } - - return 0; - -} /* end of mgsl_alloc_buffer_list_memory() */ - -/* Free DMA buffers allocated for use as the - * receive and transmit buffer lists. - * Warning: - * - * The data transfer buffers associated with the buffer list - * MUST be freed before freeing the buffer list itself because - * the buffer list contains the information necessary to free - * the individual buffers! - */ -static void mgsl_free_buffer_list_memory( struct mgsl_struct *info ) -{ - if (info->buffer_list && info->bus_type != MGSL_BUS_TYPE_PCI) - dma_free_coherent(NULL, BUFFERLISTSIZE, info->buffer_list, info->buffer_list_dma_addr); - - info->buffer_list = NULL; - info->rx_buffer_list = NULL; - info->tx_buffer_list = NULL; - -} /* end of mgsl_free_buffer_list_memory() */ - -/* - * mgsl_alloc_frame_memory() - * - * Allocate the frame DMA buffers used by the specified buffer list. - * Each DMA buffer will be one memory page in size. This is necessary - * because memory can fragment enough that it may be impossible - * contiguous pages. - * - * Arguments: - * - * info pointer to device instance data - * BufferList pointer to list of buffer entries - * Buffercount count of buffer entries in buffer list - * - * Return Value: 0 if success, otherwise -ENOMEM - */ -static int mgsl_alloc_frame_memory(struct mgsl_struct *info,DMABUFFERENTRY *BufferList,int Buffercount) -{ - int i; - u32 phys_addr; - - /* Allocate page sized buffers for the receive buffer list */ - - for ( i = 0; i < Buffercount; i++ ) { - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { - /* PCI adapter uses shared memory buffers. */ - BufferList[i].virt_addr = info->memory_base + info->last_mem_alloc; - phys_addr = info->last_mem_alloc; - info->last_mem_alloc += DMABUFFERSIZE; - } else { - /* ISA adapter uses system memory. */ - BufferList[i].virt_addr = dma_alloc_coherent(NULL, DMABUFFERSIZE, &BufferList[i].dma_addr, GFP_KERNEL); - if (BufferList[i].virt_addr == NULL) - return -ENOMEM; - phys_addr = (u32)(BufferList[i].dma_addr); - } - BufferList[i].phys_addr = phys_addr; - } - - return 0; - -} /* end of mgsl_alloc_frame_memory() */ - -/* - * mgsl_free_frame_memory() - * - * Free the buffers associated with - * each buffer entry of a buffer list. - * - * Arguments: - * - * info pointer to device instance data - * BufferList pointer to list of buffer entries - * Buffercount count of buffer entries in buffer list - * - * Return Value: None - */ -static void mgsl_free_frame_memory(struct mgsl_struct *info, DMABUFFERENTRY *BufferList, int Buffercount) -{ - int i; - - if ( BufferList ) { - for ( i = 0 ; i < Buffercount ; i++ ) { - if ( BufferList[i].virt_addr ) { - if ( info->bus_type != MGSL_BUS_TYPE_PCI ) - dma_free_coherent(NULL, DMABUFFERSIZE, BufferList[i].virt_addr, BufferList[i].dma_addr); - BufferList[i].virt_addr = NULL; - } - } - } - -} /* end of mgsl_free_frame_memory() */ - -/* mgsl_free_dma_buffers() - * - * Free DMA buffers - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void mgsl_free_dma_buffers( struct mgsl_struct *info ) -{ - mgsl_free_frame_memory( info, info->rx_buffer_list, info->rx_buffer_count ); - mgsl_free_frame_memory( info, info->tx_buffer_list, info->tx_buffer_count ); - mgsl_free_buffer_list_memory( info ); - -} /* end of mgsl_free_dma_buffers() */ - - -/* - * mgsl_alloc_intermediate_rxbuffer_memory() - * - * Allocate a buffer large enough to hold max_frame_size. This buffer - * is used to pass an assembled frame to the line discipline. - * - * Arguments: - * - * info pointer to device instance data - * - * Return Value: 0 if success, otherwise -ENOMEM - */ -static int mgsl_alloc_intermediate_rxbuffer_memory(struct mgsl_struct *info) -{ - info->intermediate_rxbuffer = kmalloc(info->max_frame_size, GFP_KERNEL | GFP_DMA); - if ( info->intermediate_rxbuffer == NULL ) - return -ENOMEM; - - return 0; - -} /* end of mgsl_alloc_intermediate_rxbuffer_memory() */ - -/* - * mgsl_free_intermediate_rxbuffer_memory() - * - * - * Arguments: - * - * info pointer to device instance data - * - * Return Value: None - */ -static void mgsl_free_intermediate_rxbuffer_memory(struct mgsl_struct *info) -{ - kfree(info->intermediate_rxbuffer); - info->intermediate_rxbuffer = NULL; - -} /* end of mgsl_free_intermediate_rxbuffer_memory() */ - -/* - * mgsl_alloc_intermediate_txbuffer_memory() - * - * Allocate intermdiate transmit buffer(s) large enough to hold max_frame_size. - * This buffer is used to load transmit frames into the adapter's dma transfer - * buffers when there is sufficient space. - * - * Arguments: - * - * info pointer to device instance data - * - * Return Value: 0 if success, otherwise -ENOMEM - */ -static int mgsl_alloc_intermediate_txbuffer_memory(struct mgsl_struct *info) -{ - int i; - - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk("%s %s(%d) allocating %d tx holding buffers\n", - info->device_name, __FILE__,__LINE__,info->num_tx_holding_buffers); - - memset(info->tx_holding_buffers,0,sizeof(info->tx_holding_buffers)); - - for ( i=0; inum_tx_holding_buffers; ++i) { - info->tx_holding_buffers[i].buffer = - kmalloc(info->max_frame_size, GFP_KERNEL); - if (info->tx_holding_buffers[i].buffer == NULL) { - for (--i; i >= 0; i--) { - kfree(info->tx_holding_buffers[i].buffer); - info->tx_holding_buffers[i].buffer = NULL; - } - return -ENOMEM; - } - } - - return 0; - -} /* end of mgsl_alloc_intermediate_txbuffer_memory() */ - -/* - * mgsl_free_intermediate_txbuffer_memory() - * - * - * Arguments: - * - * info pointer to device instance data - * - * Return Value: None - */ -static void mgsl_free_intermediate_txbuffer_memory(struct mgsl_struct *info) -{ - int i; - - for ( i=0; inum_tx_holding_buffers; ++i ) { - kfree(info->tx_holding_buffers[i].buffer); - info->tx_holding_buffers[i].buffer = NULL; - } - - info->get_tx_holding_index = 0; - info->put_tx_holding_index = 0; - info->tx_holding_count = 0; - -} /* end of mgsl_free_intermediate_txbuffer_memory() */ - - -/* - * load_next_tx_holding_buffer() - * - * attempts to load the next buffered tx request into the - * tx dma buffers - * - * Arguments: - * - * info pointer to device instance data - * - * Return Value: true if next buffered tx request loaded - * into adapter's tx dma buffer, - * false otherwise - */ -static bool load_next_tx_holding_buffer(struct mgsl_struct *info) -{ - bool ret = false; - - if ( info->tx_holding_count ) { - /* determine if we have enough tx dma buffers - * to accommodate the next tx frame - */ - struct tx_holding_buffer *ptx = - &info->tx_holding_buffers[info->get_tx_holding_index]; - int num_free = num_free_tx_dma_buffers(info); - int num_needed = ptx->buffer_size / DMABUFFERSIZE; - if ( ptx->buffer_size % DMABUFFERSIZE ) - ++num_needed; - - if (num_needed <= num_free) { - info->xmit_cnt = ptx->buffer_size; - mgsl_load_tx_dma_buffer(info,ptx->buffer,ptx->buffer_size); - - --info->tx_holding_count; - if ( ++info->get_tx_holding_index >= info->num_tx_holding_buffers) - info->get_tx_holding_index=0; - - /* restart transmit timer */ - mod_timer(&info->tx_timer, jiffies + msecs_to_jiffies(5000)); - - ret = true; - } - } - - return ret; -} - -/* - * save_tx_buffer_request() - * - * attempt to store transmit frame request for later transmission - * - * Arguments: - * - * info pointer to device instance data - * Buffer pointer to buffer containing frame to load - * BufferSize size in bytes of frame in Buffer - * - * Return Value: 1 if able to store, 0 otherwise - */ -static int save_tx_buffer_request(struct mgsl_struct *info,const char *Buffer, unsigned int BufferSize) -{ - struct tx_holding_buffer *ptx; - - if ( info->tx_holding_count >= info->num_tx_holding_buffers ) { - return 0; /* all buffers in use */ - } - - ptx = &info->tx_holding_buffers[info->put_tx_holding_index]; - ptx->buffer_size = BufferSize; - memcpy( ptx->buffer, Buffer, BufferSize); - - ++info->tx_holding_count; - if ( ++info->put_tx_holding_index >= info->num_tx_holding_buffers) - info->put_tx_holding_index=0; - - return 1; -} - -static int mgsl_claim_resources(struct mgsl_struct *info) -{ - if (request_region(info->io_base,info->io_addr_size,"synclink") == NULL) { - printk( "%s(%d):I/O address conflict on device %s Addr=%08X\n", - __FILE__,__LINE__,info->device_name, info->io_base); - return -ENODEV; - } - info->io_addr_requested = true; - - if ( request_irq(info->irq_level,mgsl_interrupt,info->irq_flags, - info->device_name, info ) < 0 ) { - printk( "%s(%d):Cant request interrupt on device %s IRQ=%d\n", - __FILE__,__LINE__,info->device_name, info->irq_level ); - goto errout; - } - info->irq_requested = true; - - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { - if (request_mem_region(info->phys_memory_base,0x40000,"synclink") == NULL) { - printk( "%s(%d):mem addr conflict device %s Addr=%08X\n", - __FILE__,__LINE__,info->device_name, info->phys_memory_base); - goto errout; - } - info->shared_mem_requested = true; - if (request_mem_region(info->phys_lcr_base + info->lcr_offset,128,"synclink") == NULL) { - printk( "%s(%d):lcr mem addr conflict device %s Addr=%08X\n", - __FILE__,__LINE__,info->device_name, info->phys_lcr_base + info->lcr_offset); - goto errout; - } - info->lcr_mem_requested = true; - - info->memory_base = ioremap_nocache(info->phys_memory_base, - 0x40000); - if (!info->memory_base) { - printk( "%s(%d):Cant map shared memory on device %s MemAddr=%08X\n", - __FILE__,__LINE__,info->device_name, info->phys_memory_base ); - goto errout; - } - - if ( !mgsl_memory_test(info) ) { - printk( "%s(%d):Failed shared memory test %s MemAddr=%08X\n", - __FILE__,__LINE__,info->device_name, info->phys_memory_base ); - goto errout; - } - - info->lcr_base = ioremap_nocache(info->phys_lcr_base, - PAGE_SIZE); - if (!info->lcr_base) { - printk( "%s(%d):Cant map LCR memory on device %s MemAddr=%08X\n", - __FILE__,__LINE__,info->device_name, info->phys_lcr_base ); - goto errout; - } - info->lcr_base += info->lcr_offset; - - } else { - /* claim DMA channel */ - - if (request_dma(info->dma_level,info->device_name) < 0){ - printk( "%s(%d):Cant request DMA channel on device %s DMA=%d\n", - __FILE__,__LINE__,info->device_name, info->dma_level ); - mgsl_release_resources( info ); - return -ENODEV; - } - info->dma_requested = true; - - /* ISA adapter uses bus master DMA */ - set_dma_mode(info->dma_level,DMA_MODE_CASCADE); - enable_dma(info->dma_level); - } - - if ( mgsl_allocate_dma_buffers(info) < 0 ) { - printk( "%s(%d):Cant allocate DMA buffers on device %s DMA=%d\n", - __FILE__,__LINE__,info->device_name, info->dma_level ); - goto errout; - } - - return 0; -errout: - mgsl_release_resources(info); - return -ENODEV; - -} /* end of mgsl_claim_resources() */ - -static void mgsl_release_resources(struct mgsl_struct *info) -{ - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):mgsl_release_resources(%s) entry\n", - __FILE__,__LINE__,info->device_name ); - - if ( info->irq_requested ) { - free_irq(info->irq_level, info); - info->irq_requested = false; - } - if ( info->dma_requested ) { - disable_dma(info->dma_level); - free_dma(info->dma_level); - info->dma_requested = false; - } - mgsl_free_dma_buffers(info); - mgsl_free_intermediate_rxbuffer_memory(info); - mgsl_free_intermediate_txbuffer_memory(info); - - if ( info->io_addr_requested ) { - release_region(info->io_base,info->io_addr_size); - info->io_addr_requested = false; - } - if ( info->shared_mem_requested ) { - release_mem_region(info->phys_memory_base,0x40000); - info->shared_mem_requested = false; - } - if ( info->lcr_mem_requested ) { - release_mem_region(info->phys_lcr_base + info->lcr_offset,128); - info->lcr_mem_requested = false; - } - if (info->memory_base){ - iounmap(info->memory_base); - info->memory_base = NULL; - } - if (info->lcr_base){ - iounmap(info->lcr_base - info->lcr_offset); - info->lcr_base = NULL; - } - - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):mgsl_release_resources(%s) exit\n", - __FILE__,__LINE__,info->device_name ); - -} /* end of mgsl_release_resources() */ - -/* mgsl_add_device() - * - * Add the specified device instance data structure to the - * global linked list of devices and increment the device count. - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void mgsl_add_device( struct mgsl_struct *info ) -{ - info->next_device = NULL; - info->line = mgsl_device_count; - sprintf(info->device_name,"ttySL%d",info->line); - - if (info->line < MAX_TOTAL_DEVICES) { - if (maxframe[info->line]) - info->max_frame_size = maxframe[info->line]; - - if (txdmabufs[info->line]) { - info->num_tx_dma_buffers = txdmabufs[info->line]; - if (info->num_tx_dma_buffers < 1) - info->num_tx_dma_buffers = 1; - } - - if (txholdbufs[info->line]) { - info->num_tx_holding_buffers = txholdbufs[info->line]; - if (info->num_tx_holding_buffers < 1) - info->num_tx_holding_buffers = 1; - else if (info->num_tx_holding_buffers > MAX_TX_HOLDING_BUFFERS) - info->num_tx_holding_buffers = MAX_TX_HOLDING_BUFFERS; - } - } - - mgsl_device_count++; - - if ( !mgsl_device_list ) - mgsl_device_list = info; - else { - struct mgsl_struct *current_dev = mgsl_device_list; - while( current_dev->next_device ) - current_dev = current_dev->next_device; - current_dev->next_device = info; - } - - if ( info->max_frame_size < 4096 ) - info->max_frame_size = 4096; - else if ( info->max_frame_size > 65535 ) - info->max_frame_size = 65535; - - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { - printk( "SyncLink PCI v%d %s: IO=%04X IRQ=%d Mem=%08X,%08X MaxFrameSize=%u\n", - info->hw_version + 1, info->device_name, info->io_base, info->irq_level, - info->phys_memory_base, info->phys_lcr_base, - info->max_frame_size ); - } else { - printk( "SyncLink ISA %s: IO=%04X IRQ=%d DMA=%d MaxFrameSize=%u\n", - info->device_name, info->io_base, info->irq_level, info->dma_level, - info->max_frame_size ); - } - -#if SYNCLINK_GENERIC_HDLC - hdlcdev_init(info); -#endif - -} /* end of mgsl_add_device() */ - -static const struct tty_port_operations mgsl_port_ops = { - .carrier_raised = carrier_raised, - .dtr_rts = dtr_rts, -}; - - -/* mgsl_allocate_device() - * - * Allocate and initialize a device instance structure - * - * Arguments: none - * Return Value: pointer to mgsl_struct if success, otherwise NULL - */ -static struct mgsl_struct* mgsl_allocate_device(void) -{ - struct mgsl_struct *info; - - info = kzalloc(sizeof(struct mgsl_struct), - GFP_KERNEL); - - if (!info) { - printk("Error can't allocate device instance data\n"); - } else { - tty_port_init(&info->port); - info->port.ops = &mgsl_port_ops; - info->magic = MGSL_MAGIC; - INIT_WORK(&info->task, mgsl_bh_handler); - info->max_frame_size = 4096; - info->port.close_delay = 5*HZ/10; - info->port.closing_wait = 30*HZ; - init_waitqueue_head(&info->status_event_wait_q); - init_waitqueue_head(&info->event_wait_q); - spin_lock_init(&info->irq_spinlock); - spin_lock_init(&info->netlock); - memcpy(&info->params,&default_params,sizeof(MGSL_PARAMS)); - info->idle_mode = HDLC_TXIDLE_FLAGS; - info->num_tx_dma_buffers = 1; - info->num_tx_holding_buffers = 0; - } - - return info; - -} /* end of mgsl_allocate_device()*/ - -static const struct tty_operations mgsl_ops = { - .open = mgsl_open, - .close = mgsl_close, - .write = mgsl_write, - .put_char = mgsl_put_char, - .flush_chars = mgsl_flush_chars, - .write_room = mgsl_write_room, - .chars_in_buffer = mgsl_chars_in_buffer, - .flush_buffer = mgsl_flush_buffer, - .ioctl = mgsl_ioctl, - .throttle = mgsl_throttle, - .unthrottle = mgsl_unthrottle, - .send_xchar = mgsl_send_xchar, - .break_ctl = mgsl_break, - .wait_until_sent = mgsl_wait_until_sent, - .set_termios = mgsl_set_termios, - .stop = mgsl_stop, - .start = mgsl_start, - .hangup = mgsl_hangup, - .tiocmget = tiocmget, - .tiocmset = tiocmset, - .get_icount = msgl_get_icount, - .proc_fops = &mgsl_proc_fops, -}; - -/* - * perform tty device initialization - */ -static int mgsl_init_tty(void) -{ - int rc; - - serial_driver = alloc_tty_driver(128); - if (!serial_driver) - return -ENOMEM; - - serial_driver->owner = THIS_MODULE; - serial_driver->driver_name = "synclink"; - serial_driver->name = "ttySL"; - serial_driver->major = ttymajor; - serial_driver->minor_start = 64; - serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - serial_driver->subtype = SERIAL_TYPE_NORMAL; - serial_driver->init_termios = tty_std_termios; - serial_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - serial_driver->init_termios.c_ispeed = 9600; - serial_driver->init_termios.c_ospeed = 9600; - serial_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(serial_driver, &mgsl_ops); - if ((rc = tty_register_driver(serial_driver)) < 0) { - printk("%s(%d):Couldn't register serial driver\n", - __FILE__,__LINE__); - put_tty_driver(serial_driver); - serial_driver = NULL; - return rc; - } - - printk("%s %s, tty major#%d\n", - driver_name, driver_version, - serial_driver->major); - return 0; -} - -/* enumerate user specified ISA adapters - */ -static void mgsl_enum_isa_devices(void) -{ - struct mgsl_struct *info; - int i; - - /* Check for user specified ISA devices */ - - for (i=0 ;(i < MAX_ISA_DEVICES) && io[i] && irq[i]; i++){ - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk("ISA device specified io=%04X,irq=%d,dma=%d\n", - io[i], irq[i], dma[i] ); - - info = mgsl_allocate_device(); - if ( !info ) { - /* error allocating device instance data */ - if ( debug_level >= DEBUG_LEVEL_ERROR ) - printk( "can't allocate device instance data.\n"); - continue; - } - - /* Copy user configuration info to device instance data */ - info->io_base = (unsigned int)io[i]; - info->irq_level = (unsigned int)irq[i]; - info->irq_level = irq_canonicalize(info->irq_level); - info->dma_level = (unsigned int)dma[i]; - info->bus_type = MGSL_BUS_TYPE_ISA; - info->io_addr_size = 16; - info->irq_flags = 0; - - mgsl_add_device( info ); - } -} - -static void synclink_cleanup(void) -{ - int rc; - struct mgsl_struct *info; - struct mgsl_struct *tmp; - - printk("Unloading %s: %s\n", driver_name, driver_version); - - if (serial_driver) { - if ((rc = tty_unregister_driver(serial_driver))) - printk("%s(%d) failed to unregister tty driver err=%d\n", - __FILE__,__LINE__,rc); - put_tty_driver(serial_driver); - } - - info = mgsl_device_list; - while(info) { -#if SYNCLINK_GENERIC_HDLC - hdlcdev_exit(info); -#endif - mgsl_release_resources(info); - tmp = info; - info = info->next_device; - kfree(tmp); - } - - if (pci_registered) - pci_unregister_driver(&synclink_pci_driver); -} - -static int __init synclink_init(void) -{ - int rc; - - if (break_on_load) { - mgsl_get_text_ptr(); - BREAKPOINT(); - } - - printk("%s %s\n", driver_name, driver_version); - - mgsl_enum_isa_devices(); - if ((rc = pci_register_driver(&synclink_pci_driver)) < 0) - printk("%s:failed to register PCI driver, error=%d\n",__FILE__,rc); - else - pci_registered = true; - - if ((rc = mgsl_init_tty()) < 0) - goto error; - - return 0; - -error: - synclink_cleanup(); - return rc; -} - -static void __exit synclink_exit(void) -{ - synclink_cleanup(); -} - -module_init(synclink_init); -module_exit(synclink_exit); - -/* - * usc_RTCmd() - * - * Issue a USC Receive/Transmit command to the - * Channel Command/Address Register (CCAR). - * - * Notes: - * - * The command is encoded in the most significant 5 bits <15..11> - * of the CCAR value. Bits <10..7> of the CCAR must be preserved - * and Bits <6..0> must be written as zeros. - * - * Arguments: - * - * info pointer to device information structure - * Cmd command mask (use symbolic macros) - * - * Return Value: - * - * None - */ -static void usc_RTCmd( struct mgsl_struct *info, u16 Cmd ) -{ - /* output command to CCAR in bits <15..11> */ - /* preserve bits <10..7>, bits <6..0> must be zero */ - - outw( Cmd + info->loopback_bits, info->io_base + CCAR ); - - /* Read to flush write to CCAR */ - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) - inw( info->io_base + CCAR ); - -} /* end of usc_RTCmd() */ - -/* - * usc_DmaCmd() - * - * Issue a DMA command to the DMA Command/Address Register (DCAR). - * - * Arguments: - * - * info pointer to device information structure - * Cmd DMA command mask (usc_DmaCmd_XX Macros) - * - * Return Value: - * - * None - */ -static void usc_DmaCmd( struct mgsl_struct *info, u16 Cmd ) -{ - /* write command mask to DCAR */ - outw( Cmd + info->mbre_bit, info->io_base ); - - /* Read to flush write to DCAR */ - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) - inw( info->io_base ); - -} /* end of usc_DmaCmd() */ - -/* - * usc_OutDmaReg() - * - * Write a 16-bit value to a USC DMA register - * - * Arguments: - * - * info pointer to device info structure - * RegAddr register address (number) for write - * RegValue 16-bit value to write to register - * - * Return Value: - * - * None - * - */ -static void usc_OutDmaReg( struct mgsl_struct *info, u16 RegAddr, u16 RegValue ) -{ - /* Note: The DCAR is located at the adapter base address */ - /* Note: must preserve state of BIT8 in DCAR */ - - outw( RegAddr + info->mbre_bit, info->io_base ); - outw( RegValue, info->io_base ); - - /* Read to flush write to DCAR */ - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) - inw( info->io_base ); - -} /* end of usc_OutDmaReg() */ - -/* - * usc_InDmaReg() - * - * Read a 16-bit value from a DMA register - * - * Arguments: - * - * info pointer to device info structure - * RegAddr register address (number) to read from - * - * Return Value: - * - * The 16-bit value read from register - * - */ -static u16 usc_InDmaReg( struct mgsl_struct *info, u16 RegAddr ) -{ - /* Note: The DCAR is located at the adapter base address */ - /* Note: must preserve state of BIT8 in DCAR */ - - outw( RegAddr + info->mbre_bit, info->io_base ); - return inw( info->io_base ); - -} /* end of usc_InDmaReg() */ - -/* - * - * usc_OutReg() - * - * Write a 16-bit value to a USC serial channel register - * - * Arguments: - * - * info pointer to device info structure - * RegAddr register address (number) to write to - * RegValue 16-bit value to write to register - * - * Return Value: - * - * None - * - */ -static void usc_OutReg( struct mgsl_struct *info, u16 RegAddr, u16 RegValue ) -{ - outw( RegAddr + info->loopback_bits, info->io_base + CCAR ); - outw( RegValue, info->io_base + CCAR ); - - /* Read to flush write to CCAR */ - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) - inw( info->io_base + CCAR ); - -} /* end of usc_OutReg() */ - -/* - * usc_InReg() - * - * Reads a 16-bit value from a USC serial channel register - * - * Arguments: - * - * info pointer to device extension - * RegAddr register address (number) to read from - * - * Return Value: - * - * 16-bit value read from register - */ -static u16 usc_InReg( struct mgsl_struct *info, u16 RegAddr ) -{ - outw( RegAddr + info->loopback_bits, info->io_base + CCAR ); - return inw( info->io_base + CCAR ); - -} /* end of usc_InReg() */ - -/* usc_set_sdlc_mode() - * - * Set up the adapter for SDLC DMA communications. - * - * Arguments: info pointer to device instance data - * Return Value: NONE - */ -static void usc_set_sdlc_mode( struct mgsl_struct *info ) -{ - u16 RegValue; - bool PreSL1660; - - /* - * determine if the IUSC on the adapter is pre-SL1660. If - * not, take advantage of the UnderWait feature of more - * modern chips. If an underrun occurs and this bit is set, - * the transmitter will idle the programmed idle pattern - * until the driver has time to service the underrun. Otherwise, - * the dma controller may get the cycles previously requested - * and begin transmitting queued tx data. - */ - usc_OutReg(info,TMCR,0x1f); - RegValue=usc_InReg(info,TMDR); - PreSL1660 = (RegValue == IUSC_PRE_SL1660); - - if ( info->params.flags & HDLC_FLAG_HDLC_LOOPMODE ) - { - /* - ** Channel Mode Register (CMR) - ** - ** <15..14> 10 Tx Sub Modes, Send Flag on Underrun - ** <13> 0 0 = Transmit Disabled (initially) - ** <12> 0 1 = Consecutive Idles share common 0 - ** <11..8> 1110 Transmitter Mode = HDLC/SDLC Loop - ** <7..4> 0000 Rx Sub Modes, addr/ctrl field handling - ** <3..0> 0110 Receiver Mode = HDLC/SDLC - ** - ** 1000 1110 0000 0110 = 0x8e06 - */ - RegValue = 0x8e06; - - /*-------------------------------------------------- - * ignore user options for UnderRun Actions and - * preambles - *--------------------------------------------------*/ - } - else - { - /* Channel mode Register (CMR) - * - * <15..14> 00 Tx Sub modes, Underrun Action - * <13> 0 1 = Send Preamble before opening flag - * <12> 0 1 = Consecutive Idles share common 0 - * <11..8> 0110 Transmitter mode = HDLC/SDLC - * <7..4> 0000 Rx Sub modes, addr/ctrl field handling - * <3..0> 0110 Receiver mode = HDLC/SDLC - * - * 0000 0110 0000 0110 = 0x0606 - */ - if (info->params.mode == MGSL_MODE_RAW) { - RegValue = 0x0001; /* Set Receive mode = external sync */ - - usc_OutReg( info, IOCR, /* Set IOCR DCD is RxSync Detect Input */ - (unsigned short)((usc_InReg(info, IOCR) & ~(BIT13|BIT12)) | BIT12)); - - /* - * TxSubMode: - * CMR <15> 0 Don't send CRC on Tx Underrun - * CMR <14> x undefined - * CMR <13> 0 Send preamble before openning sync - * CMR <12> 0 Send 8-bit syncs, 1=send Syncs per TxLength - * - * TxMode: - * CMR <11-8) 0100 MonoSync - * - * 0x00 0100 xxxx xxxx 04xx - */ - RegValue |= 0x0400; - } - else { - - RegValue = 0x0606; - - if ( info->params.flags & HDLC_FLAG_UNDERRUN_ABORT15 ) - RegValue |= BIT14; - else if ( info->params.flags & HDLC_FLAG_UNDERRUN_FLAG ) - RegValue |= BIT15; - else if ( info->params.flags & HDLC_FLAG_UNDERRUN_CRC ) - RegValue |= BIT15 + BIT14; - } - - if ( info->params.preamble != HDLC_PREAMBLE_PATTERN_NONE ) - RegValue |= BIT13; - } - - if ( info->params.mode == MGSL_MODE_HDLC && - (info->params.flags & HDLC_FLAG_SHARE_ZERO) ) - RegValue |= BIT12; - - if ( info->params.addr_filter != 0xff ) - { - /* set up receive address filtering */ - usc_OutReg( info, RSR, info->params.addr_filter ); - RegValue |= BIT4; - } - - usc_OutReg( info, CMR, RegValue ); - info->cmr_value = RegValue; - - /* Receiver mode Register (RMR) - * - * <15..13> 000 encoding - * <12..11> 00 FCS = 16bit CRC CCITT (x15 + x12 + x5 + 1) - * <10> 1 1 = Set CRC to all 1s (use for SDLC/HDLC) - * <9> 0 1 = Include Receive chars in CRC - * <8> 1 1 = Use Abort/PE bit as abort indicator - * <7..6> 00 Even parity - * <5> 0 parity disabled - * <4..2> 000 Receive Char Length = 8 bits - * <1..0> 00 Disable Receiver - * - * 0000 0101 0000 0000 = 0x0500 - */ - - RegValue = 0x0500; - - switch ( info->params.encoding ) { - case HDLC_ENCODING_NRZB: RegValue |= BIT13; break; - case HDLC_ENCODING_NRZI_MARK: RegValue |= BIT14; break; - case HDLC_ENCODING_NRZI_SPACE: RegValue |= BIT14 + BIT13; break; - case HDLC_ENCODING_BIPHASE_MARK: RegValue |= BIT15; break; - case HDLC_ENCODING_BIPHASE_SPACE: RegValue |= BIT15 + BIT13; break; - case HDLC_ENCODING_BIPHASE_LEVEL: RegValue |= BIT15 + BIT14; break; - case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: RegValue |= BIT15 + BIT14 + BIT13; break; - } - - if ( (info->params.crc_type & HDLC_CRC_MASK) == HDLC_CRC_16_CCITT ) - RegValue |= BIT9; - else if ( (info->params.crc_type & HDLC_CRC_MASK) == HDLC_CRC_32_CCITT ) - RegValue |= ( BIT12 | BIT10 | BIT9 ); - - usc_OutReg( info, RMR, RegValue ); - - /* Set the Receive count Limit Register (RCLR) to 0xffff. */ - /* When an opening flag of an SDLC frame is recognized the */ - /* Receive Character count (RCC) is loaded with the value in */ - /* RCLR. The RCC is decremented for each received byte. The */ - /* value of RCC is stored after the closing flag of the frame */ - /* allowing the frame size to be computed. */ - - usc_OutReg( info, RCLR, RCLRVALUE ); - - usc_RCmd( info, RCmd_SelectRicrdma_level ); - - /* Receive Interrupt Control Register (RICR) - * - * <15..8> ? RxFIFO DMA Request Level - * <7> 0 Exited Hunt IA (Interrupt Arm) - * <6> 0 Idle Received IA - * <5> 0 Break/Abort IA - * <4> 0 Rx Bound IA - * <3> 1 Queued status reflects oldest 2 bytes in FIFO - * <2> 0 Abort/PE IA - * <1> 1 Rx Overrun IA - * <0> 0 Select TC0 value for readback - * - * 0000 0000 0000 1000 = 0x000a - */ - - /* Carry over the Exit Hunt and Idle Received bits */ - /* in case they have been armed by usc_ArmEvents. */ - - RegValue = usc_InReg( info, RICR ) & 0xc0; - - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) - usc_OutReg( info, RICR, (u16)(0x030a | RegValue) ); - else - usc_OutReg( info, RICR, (u16)(0x140a | RegValue) ); - - /* Unlatch all Rx status bits and clear Rx status IRQ Pending */ - - usc_UnlatchRxstatusBits( info, RXSTATUS_ALL ); - usc_ClearIrqPendingBits( info, RECEIVE_STATUS ); - - /* Transmit mode Register (TMR) - * - * <15..13> 000 encoding - * <12..11> 00 FCS = 16bit CRC CCITT (x15 + x12 + x5 + 1) - * <10> 1 1 = Start CRC as all 1s (use for SDLC/HDLC) - * <9> 0 1 = Tx CRC Enabled - * <8> 0 1 = Append CRC to end of transmit frame - * <7..6> 00 Transmit parity Even - * <5> 0 Transmit parity Disabled - * <4..2> 000 Tx Char Length = 8 bits - * <1..0> 00 Disable Transmitter - * - * 0000 0100 0000 0000 = 0x0400 - */ - - RegValue = 0x0400; - - switch ( info->params.encoding ) { - case HDLC_ENCODING_NRZB: RegValue |= BIT13; break; - case HDLC_ENCODING_NRZI_MARK: RegValue |= BIT14; break; - case HDLC_ENCODING_NRZI_SPACE: RegValue |= BIT14 + BIT13; break; - case HDLC_ENCODING_BIPHASE_MARK: RegValue |= BIT15; break; - case HDLC_ENCODING_BIPHASE_SPACE: RegValue |= BIT15 + BIT13; break; - case HDLC_ENCODING_BIPHASE_LEVEL: RegValue |= BIT15 + BIT14; break; - case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: RegValue |= BIT15 + BIT14 + BIT13; break; - } - - if ( (info->params.crc_type & HDLC_CRC_MASK) == HDLC_CRC_16_CCITT ) - RegValue |= BIT9 + BIT8; - else if ( (info->params.crc_type & HDLC_CRC_MASK) == HDLC_CRC_32_CCITT ) - RegValue |= ( BIT12 | BIT10 | BIT9 | BIT8); - - usc_OutReg( info, TMR, RegValue ); - - usc_set_txidle( info ); - - - usc_TCmd( info, TCmd_SelectTicrdma_level ); - - /* Transmit Interrupt Control Register (TICR) - * - * <15..8> ? Transmit FIFO DMA Level - * <7> 0 Present IA (Interrupt Arm) - * <6> 0 Idle Sent IA - * <5> 1 Abort Sent IA - * <4> 1 EOF/EOM Sent IA - * <3> 0 CRC Sent IA - * <2> 1 1 = Wait for SW Trigger to Start Frame - * <1> 1 Tx Underrun IA - * <0> 0 TC0 constant on read back - * - * 0000 0000 0011 0110 = 0x0036 - */ - - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) - usc_OutReg( info, TICR, 0x0736 ); - else - usc_OutReg( info, TICR, 0x1436 ); - - usc_UnlatchTxstatusBits( info, TXSTATUS_ALL ); - usc_ClearIrqPendingBits( info, TRANSMIT_STATUS ); - - /* - ** Transmit Command/Status Register (TCSR) - ** - ** <15..12> 0000 TCmd - ** <11> 0/1 UnderWait - ** <10..08> 000 TxIdle - ** <7> x PreSent - ** <6> x IdleSent - ** <5> x AbortSent - ** <4> x EOF/EOM Sent - ** <3> x CRC Sent - ** <2> x All Sent - ** <1> x TxUnder - ** <0> x TxEmpty - ** - ** 0000 0000 0000 0000 = 0x0000 - */ - info->tcsr_value = 0; - - if ( !PreSL1660 ) - info->tcsr_value |= TCSR_UNDERWAIT; - - usc_OutReg( info, TCSR, info->tcsr_value ); - - /* Clock mode Control Register (CMCR) - * - * <15..14> 00 counter 1 Source = Disabled - * <13..12> 00 counter 0 Source = Disabled - * <11..10> 11 BRG1 Input is TxC Pin - * <9..8> 11 BRG0 Input is TxC Pin - * <7..6> 01 DPLL Input is BRG1 Output - * <5..3> XXX TxCLK comes from Port 0 - * <2..0> XXX RxCLK comes from Port 1 - * - * 0000 1111 0111 0111 = 0x0f77 - */ - - RegValue = 0x0f40; - - if ( info->params.flags & HDLC_FLAG_RXC_DPLL ) - RegValue |= 0x0003; /* RxCLK from DPLL */ - else if ( info->params.flags & HDLC_FLAG_RXC_BRG ) - RegValue |= 0x0004; /* RxCLK from BRG0 */ - else if ( info->params.flags & HDLC_FLAG_RXC_TXCPIN) - RegValue |= 0x0006; /* RxCLK from TXC Input */ - else - RegValue |= 0x0007; /* RxCLK from Port1 */ - - if ( info->params.flags & HDLC_FLAG_TXC_DPLL ) - RegValue |= 0x0018; /* TxCLK from DPLL */ - else if ( info->params.flags & HDLC_FLAG_TXC_BRG ) - RegValue |= 0x0020; /* TxCLK from BRG0 */ - else if ( info->params.flags & HDLC_FLAG_TXC_RXCPIN) - RegValue |= 0x0038; /* RxCLK from TXC Input */ - else - RegValue |= 0x0030; /* TxCLK from Port0 */ - - usc_OutReg( info, CMCR, RegValue ); - - - /* Hardware Configuration Register (HCR) - * - * <15..14> 00 CTR0 Divisor:00=32,01=16,10=8,11=4 - * <13> 0 CTR1DSel:0=CTR0Div determines CTR0Div - * <12> 0 CVOK:0=report code violation in biphase - * <11..10> 00 DPLL Divisor:00=32,01=16,10=8,11=4 - * <9..8> XX DPLL mode:00=disable,01=NRZ,10=Biphase,11=Biphase Level - * <7..6> 00 reserved - * <5> 0 BRG1 mode:0=continuous,1=single cycle - * <4> X BRG1 Enable - * <3..2> 00 reserved - * <1> 0 BRG0 mode:0=continuous,1=single cycle - * <0> 0 BRG0 Enable - */ - - RegValue = 0x0000; - - if ( info->params.flags & (HDLC_FLAG_RXC_DPLL + HDLC_FLAG_TXC_DPLL) ) { - u32 XtalSpeed; - u32 DpllDivisor; - u16 Tc; - - /* DPLL is enabled. Use BRG1 to provide continuous reference clock */ - /* for DPLL. DPLL mode in HCR is dependent on the encoding used. */ - - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) - XtalSpeed = 11059200; - else - XtalSpeed = 14745600; - - if ( info->params.flags & HDLC_FLAG_DPLL_DIV16 ) { - DpllDivisor = 16; - RegValue |= BIT10; - } - else if ( info->params.flags & HDLC_FLAG_DPLL_DIV8 ) { - DpllDivisor = 8; - RegValue |= BIT11; - } - else - DpllDivisor = 32; - - /* Tc = (Xtal/Speed) - 1 */ - /* If twice the remainder of (Xtal/Speed) is greater than Speed */ - /* then rounding up gives a more precise time constant. Instead */ - /* of rounding up and then subtracting 1 we just don't subtract */ - /* the one in this case. */ - - /*-------------------------------------------------- - * ejz: for DPLL mode, application should use the - * same clock speed as the partner system, even - * though clocking is derived from the input RxData. - * In case the user uses a 0 for the clock speed, - * default to 0xffffffff and don't try to divide by - * zero - *--------------------------------------------------*/ - if ( info->params.clock_speed ) - { - Tc = (u16)((XtalSpeed/DpllDivisor)/info->params.clock_speed); - if ( !((((XtalSpeed/DpllDivisor) % info->params.clock_speed) * 2) - / info->params.clock_speed) ) - Tc--; - } - else - Tc = -1; - - - /* Write 16-bit Time Constant for BRG1 */ - usc_OutReg( info, TC1R, Tc ); - - RegValue |= BIT4; /* enable BRG1 */ - - switch ( info->params.encoding ) { - case HDLC_ENCODING_NRZ: - case HDLC_ENCODING_NRZB: - case HDLC_ENCODING_NRZI_MARK: - case HDLC_ENCODING_NRZI_SPACE: RegValue |= BIT8; break; - case HDLC_ENCODING_BIPHASE_MARK: - case HDLC_ENCODING_BIPHASE_SPACE: RegValue |= BIT9; break; - case HDLC_ENCODING_BIPHASE_LEVEL: - case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: RegValue |= BIT9 + BIT8; break; - } - } - - usc_OutReg( info, HCR, RegValue ); - - - /* Channel Control/status Register (CCSR) - * - * <15> X RCC FIFO Overflow status (RO) - * <14> X RCC FIFO Not Empty status (RO) - * <13> 0 1 = Clear RCC FIFO (WO) - * <12> X DPLL Sync (RW) - * <11> X DPLL 2 Missed Clocks status (RO) - * <10> X DPLL 1 Missed Clock status (RO) - * <9..8> 00 DPLL Resync on rising and falling edges (RW) - * <7> X SDLC Loop On status (RO) - * <6> X SDLC Loop Send status (RO) - * <5> 1 Bypass counters for TxClk and RxClk (RW) - * <4..2> 000 Last Char of SDLC frame has 8 bits (RW) - * <1..0> 00 reserved - * - * 0000 0000 0010 0000 = 0x0020 - */ - - usc_OutReg( info, CCSR, 0x1020 ); - - - if ( info->params.flags & HDLC_FLAG_AUTO_CTS ) { - usc_OutReg( info, SICR, - (u16)(usc_InReg(info,SICR) | SICR_CTS_INACTIVE) ); - } - - - /* enable Master Interrupt Enable bit (MIE) */ - usc_EnableMasterIrqBit( info ); - - usc_ClearIrqPendingBits( info, RECEIVE_STATUS + RECEIVE_DATA + - TRANSMIT_STATUS + TRANSMIT_DATA + MISC); - - /* arm RCC underflow interrupt */ - usc_OutReg(info, SICR, (u16)(usc_InReg(info,SICR) | BIT3)); - usc_EnableInterrupts(info, MISC); - - info->mbre_bit = 0; - outw( 0, info->io_base ); /* clear Master Bus Enable (DCAR) */ - usc_DmaCmd( info, DmaCmd_ResetAllChannels ); /* disable both DMA channels */ - info->mbre_bit = BIT8; - outw( BIT8, info->io_base ); /* set Master Bus Enable (DCAR) */ - - if (info->bus_type == MGSL_BUS_TYPE_ISA) { - /* Enable DMAEN (Port 7, Bit 14) */ - /* This connects the DMA request signal to the ISA bus */ - usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT15) & ~BIT14)); - } - - /* DMA Control Register (DCR) - * - * <15..14> 10 Priority mode = Alternating Tx/Rx - * 01 Rx has priority - * 00 Tx has priority - * - * <13> 1 Enable Priority Preempt per DCR<15..14> - * (WARNING DCR<11..10> must be 00 when this is 1) - * 0 Choose activate channel per DCR<11..10> - * - * <12> 0 Little Endian for Array/List - * <11..10> 00 Both Channels can use each bus grant - * <9..6> 0000 reserved - * <5> 0 7 CLK - Minimum Bus Re-request Interval - * <4> 0 1 = drive D/C and S/D pins - * <3> 1 1 = Add one wait state to all DMA cycles. - * <2> 0 1 = Strobe /UAS on every transfer. - * <1..0> 11 Addr incrementing only affects LS24 bits - * - * 0110 0000 0000 1011 = 0x600b - */ - - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { - /* PCI adapter does not need DMA wait state */ - usc_OutDmaReg( info, DCR, 0xa00b ); - } - else - usc_OutDmaReg( info, DCR, 0x800b ); - - - /* Receive DMA mode Register (RDMR) - * - * <15..14> 11 DMA mode = Linked List Buffer mode - * <13> 1 RSBinA/L = store Rx status Block in Arrary/List entry - * <12> 1 Clear count of List Entry after fetching - * <11..10> 00 Address mode = Increment - * <9> 1 Terminate Buffer on RxBound - * <8> 0 Bus Width = 16bits - * <7..0> ? status Bits (write as 0s) - * - * 1111 0010 0000 0000 = 0xf200 - */ - - usc_OutDmaReg( info, RDMR, 0xf200 ); - - - /* Transmit DMA mode Register (TDMR) - * - * <15..14> 11 DMA mode = Linked List Buffer mode - * <13> 1 TCBinA/L = fetch Tx Control Block from List entry - * <12> 1 Clear count of List Entry after fetching - * <11..10> 00 Address mode = Increment - * <9> 1 Terminate Buffer on end of frame - * <8> 0 Bus Width = 16bits - * <7..0> ? status Bits (Read Only so write as 0) - * - * 1111 0010 0000 0000 = 0xf200 - */ - - usc_OutDmaReg( info, TDMR, 0xf200 ); - - - /* DMA Interrupt Control Register (DICR) - * - * <15> 1 DMA Interrupt Enable - * <14> 0 1 = Disable IEO from USC - * <13> 0 1 = Don't provide vector during IntAck - * <12> 1 1 = Include status in Vector - * <10..2> 0 reserved, Must be 0s - * <1> 0 1 = Rx DMA Interrupt Enabled - * <0> 0 1 = Tx DMA Interrupt Enabled - * - * 1001 0000 0000 0000 = 0x9000 - */ - - usc_OutDmaReg( info, DICR, 0x9000 ); - - usc_InDmaReg( info, RDMR ); /* clear pending receive DMA IRQ bits */ - usc_InDmaReg( info, TDMR ); /* clear pending transmit DMA IRQ bits */ - usc_OutDmaReg( info, CDIR, 0x0303 ); /* clear IUS and Pending for Tx and Rx */ - - /* Channel Control Register (CCR) - * - * <15..14> 10 Use 32-bit Tx Control Blocks (TCBs) - * <13> 0 Trigger Tx on SW Command Disabled - * <12> 0 Flag Preamble Disabled - * <11..10> 00 Preamble Length - * <9..8> 00 Preamble Pattern - * <7..6> 10 Use 32-bit Rx status Blocks (RSBs) - * <5> 0 Trigger Rx on SW Command Disabled - * <4..0> 0 reserved - * - * 1000 0000 1000 0000 = 0x8080 - */ - - RegValue = 0x8080; - - switch ( info->params.preamble_length ) { - case HDLC_PREAMBLE_LENGTH_16BITS: RegValue |= BIT10; break; - case HDLC_PREAMBLE_LENGTH_32BITS: RegValue |= BIT11; break; - case HDLC_PREAMBLE_LENGTH_64BITS: RegValue |= BIT11 + BIT10; break; - } - - switch ( info->params.preamble ) { - case HDLC_PREAMBLE_PATTERN_FLAGS: RegValue |= BIT8 + BIT12; break; - case HDLC_PREAMBLE_PATTERN_ONES: RegValue |= BIT8; break; - case HDLC_PREAMBLE_PATTERN_10: RegValue |= BIT9; break; - case HDLC_PREAMBLE_PATTERN_01: RegValue |= BIT9 + BIT8; break; - } - - usc_OutReg( info, CCR, RegValue ); - - - /* - * Burst/Dwell Control Register - * - * <15..8> 0x20 Maximum number of transfers per bus grant - * <7..0> 0x00 Maximum number of clock cycles per bus grant - */ - - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { - /* don't limit bus occupancy on PCI adapter */ - usc_OutDmaReg( info, BDCR, 0x0000 ); - } - else - usc_OutDmaReg( info, BDCR, 0x2000 ); - - usc_stop_transmitter(info); - usc_stop_receiver(info); - -} /* end of usc_set_sdlc_mode() */ - -/* usc_enable_loopback() - * - * Set the 16C32 for internal loopback mode. - * The TxCLK and RxCLK signals are generated from the BRG0 and - * the TxD is looped back to the RxD internally. - * - * Arguments: info pointer to device instance data - * enable 1 = enable loopback, 0 = disable - * Return Value: None - */ -static void usc_enable_loopback(struct mgsl_struct *info, int enable) -{ - if (enable) { - /* blank external TXD output */ - usc_OutReg(info,IOCR,usc_InReg(info,IOCR) | (BIT7+BIT6)); - - /* Clock mode Control Register (CMCR) - * - * <15..14> 00 counter 1 Disabled - * <13..12> 00 counter 0 Disabled - * <11..10> 11 BRG1 Input is TxC Pin - * <9..8> 11 BRG0 Input is TxC Pin - * <7..6> 01 DPLL Input is BRG1 Output - * <5..3> 100 TxCLK comes from BRG0 - * <2..0> 100 RxCLK comes from BRG0 - * - * 0000 1111 0110 0100 = 0x0f64 - */ - - usc_OutReg( info, CMCR, 0x0f64 ); - - /* Write 16-bit Time Constant for BRG0 */ - /* use clock speed if available, otherwise use 8 for diagnostics */ - if (info->params.clock_speed) { - if (info->bus_type == MGSL_BUS_TYPE_PCI) - usc_OutReg(info, TC0R, (u16)((11059200/info->params.clock_speed)-1)); - else - usc_OutReg(info, TC0R, (u16)((14745600/info->params.clock_speed)-1)); - } else - usc_OutReg(info, TC0R, (u16)8); - - /* Hardware Configuration Register (HCR) Clear Bit 1, BRG0 - mode = Continuous Set Bit 0 to enable BRG0. */ - usc_OutReg( info, HCR, (u16)((usc_InReg( info, HCR ) & ~BIT1) | BIT0) ); - - /* Input/Output Control Reg, <2..0> = 100, Drive RxC pin with BRG0 */ - usc_OutReg(info, IOCR, (u16)((usc_InReg(info, IOCR) & 0xfff8) | 0x0004)); - - /* set Internal Data loopback mode */ - info->loopback_bits = 0x300; - outw( 0x0300, info->io_base + CCAR ); - } else { - /* enable external TXD output */ - usc_OutReg(info,IOCR,usc_InReg(info,IOCR) & ~(BIT7+BIT6)); - - /* clear Internal Data loopback mode */ - info->loopback_bits = 0; - outw( 0,info->io_base + CCAR ); - } - -} /* end of usc_enable_loopback() */ - -/* usc_enable_aux_clock() - * - * Enabled the AUX clock output at the specified frequency. - * - * Arguments: - * - * info pointer to device extension - * data_rate data rate of clock in bits per second - * A data rate of 0 disables the AUX clock. - * - * Return Value: None - */ -static void usc_enable_aux_clock( struct mgsl_struct *info, u32 data_rate ) -{ - u32 XtalSpeed; - u16 Tc; - - if ( data_rate ) { - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) - XtalSpeed = 11059200; - else - XtalSpeed = 14745600; - - - /* Tc = (Xtal/Speed) - 1 */ - /* If twice the remainder of (Xtal/Speed) is greater than Speed */ - /* then rounding up gives a more precise time constant. Instead */ - /* of rounding up and then subtracting 1 we just don't subtract */ - /* the one in this case. */ - - - Tc = (u16)(XtalSpeed/data_rate); - if ( !(((XtalSpeed % data_rate) * 2) / data_rate) ) - Tc--; - - /* Write 16-bit Time Constant for BRG0 */ - usc_OutReg( info, TC0R, Tc ); - - /* - * Hardware Configuration Register (HCR) - * Clear Bit 1, BRG0 mode = Continuous - * Set Bit 0 to enable BRG0. - */ - - usc_OutReg( info, HCR, (u16)((usc_InReg( info, HCR ) & ~BIT1) | BIT0) ); - - /* Input/Output Control Reg, <2..0> = 100, Drive RxC pin with BRG0 */ - usc_OutReg( info, IOCR, (u16)((usc_InReg(info, IOCR) & 0xfff8) | 0x0004) ); - } else { - /* data rate == 0 so turn off BRG0 */ - usc_OutReg( info, HCR, (u16)(usc_InReg( info, HCR ) & ~BIT0) ); - } - -} /* end of usc_enable_aux_clock() */ - -/* - * - * usc_process_rxoverrun_sync() - * - * This function processes a receive overrun by resetting the - * receive DMA buffers and issuing a Purge Rx FIFO command - * to allow the receiver to continue receiving. - * - * Arguments: - * - * info pointer to device extension - * - * Return Value: None - */ -static void usc_process_rxoverrun_sync( struct mgsl_struct *info ) -{ - int start_index; - int end_index; - int frame_start_index; - bool start_of_frame_found = false; - bool end_of_frame_found = false; - bool reprogram_dma = false; - - DMABUFFERENTRY *buffer_list = info->rx_buffer_list; - u32 phys_addr; - - usc_DmaCmd( info, DmaCmd_PauseRxChannel ); - usc_RCmd( info, RCmd_EnterHuntmode ); - usc_RTCmd( info, RTCmd_PurgeRxFifo ); - - /* CurrentRxBuffer points to the 1st buffer of the next */ - /* possibly available receive frame. */ - - frame_start_index = start_index = end_index = info->current_rx_buffer; - - /* Search for an unfinished string of buffers. This means */ - /* that a receive frame started (at least one buffer with */ - /* count set to zero) but there is no terminiting buffer */ - /* (status set to non-zero). */ - - while( !buffer_list[end_index].count ) - { - /* Count field has been reset to zero by 16C32. */ - /* This buffer is currently in use. */ - - if ( !start_of_frame_found ) - { - start_of_frame_found = true; - frame_start_index = end_index; - end_of_frame_found = false; - } - - if ( buffer_list[end_index].status ) - { - /* Status field has been set by 16C32. */ - /* This is the last buffer of a received frame. */ - - /* We want to leave the buffers for this frame intact. */ - /* Move on to next possible frame. */ - - start_of_frame_found = false; - end_of_frame_found = true; - } - - /* advance to next buffer entry in linked list */ - end_index++; - if ( end_index == info->rx_buffer_count ) - end_index = 0; - - if ( start_index == end_index ) - { - /* The entire list has been searched with all Counts == 0 and */ - /* all Status == 0. The receive buffers are */ - /* completely screwed, reset all receive buffers! */ - mgsl_reset_rx_dma_buffers( info ); - frame_start_index = 0; - start_of_frame_found = false; - reprogram_dma = true; - break; - } - } - - if ( start_of_frame_found && !end_of_frame_found ) - { - /* There is an unfinished string of receive DMA buffers */ - /* as a result of the receiver overrun. */ - - /* Reset the buffers for the unfinished frame */ - /* and reprogram the receive DMA controller to start */ - /* at the 1st buffer of unfinished frame. */ - - start_index = frame_start_index; - - do - { - *((unsigned long *)&(info->rx_buffer_list[start_index++].count)) = DMABUFFERSIZE; - - /* Adjust index for wrap around. */ - if ( start_index == info->rx_buffer_count ) - start_index = 0; - - } while( start_index != end_index ); - - reprogram_dma = true; - } - - if ( reprogram_dma ) - { - usc_UnlatchRxstatusBits(info,RXSTATUS_ALL); - usc_ClearIrqPendingBits(info, RECEIVE_DATA|RECEIVE_STATUS); - usc_UnlatchRxstatusBits(info, RECEIVE_DATA|RECEIVE_STATUS); - - usc_EnableReceiver(info,DISABLE_UNCONDITIONAL); - - /* This empties the receive FIFO and loads the RCC with RCLR */ - usc_OutReg( info, CCSR, (u16)(usc_InReg(info,CCSR) | BIT13) ); - - /* program 16C32 with physical address of 1st DMA buffer entry */ - phys_addr = info->rx_buffer_list[frame_start_index].phys_entry; - usc_OutDmaReg( info, NRARL, (u16)phys_addr ); - usc_OutDmaReg( info, NRARU, (u16)(phys_addr >> 16) ); - - usc_UnlatchRxstatusBits( info, RXSTATUS_ALL ); - usc_ClearIrqPendingBits( info, RECEIVE_DATA + RECEIVE_STATUS ); - usc_EnableInterrupts( info, RECEIVE_STATUS ); - - /* 1. Arm End of Buffer (EOB) Receive DMA Interrupt (BIT2 of RDIAR) */ - /* 2. Enable Receive DMA Interrupts (BIT1 of DICR) */ - - usc_OutDmaReg( info, RDIAR, BIT3 + BIT2 ); - usc_OutDmaReg( info, DICR, (u16)(usc_InDmaReg(info,DICR) | BIT1) ); - usc_DmaCmd( info, DmaCmd_InitRxChannel ); - if ( info->params.flags & HDLC_FLAG_AUTO_DCD ) - usc_EnableReceiver(info,ENABLE_AUTO_DCD); - else - usc_EnableReceiver(info,ENABLE_UNCONDITIONAL); - } - else - { - /* This empties the receive FIFO and loads the RCC with RCLR */ - usc_OutReg( info, CCSR, (u16)(usc_InReg(info,CCSR) | BIT13) ); - usc_RTCmd( info, RTCmd_PurgeRxFifo ); - } - -} /* end of usc_process_rxoverrun_sync() */ - -/* usc_stop_receiver() - * - * Disable USC receiver - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void usc_stop_receiver( struct mgsl_struct *info ) -{ - if (debug_level >= DEBUG_LEVEL_ISR) - printk("%s(%d):usc_stop_receiver(%s)\n", - __FILE__,__LINE__, info->device_name ); - - /* Disable receive DMA channel. */ - /* This also disables receive DMA channel interrupts */ - usc_DmaCmd( info, DmaCmd_ResetRxChannel ); - - usc_UnlatchRxstatusBits( info, RXSTATUS_ALL ); - usc_ClearIrqPendingBits( info, RECEIVE_DATA + RECEIVE_STATUS ); - usc_DisableInterrupts( info, RECEIVE_DATA + RECEIVE_STATUS ); - - usc_EnableReceiver(info,DISABLE_UNCONDITIONAL); - - /* This empties the receive FIFO and loads the RCC with RCLR */ - usc_OutReg( info, CCSR, (u16)(usc_InReg(info,CCSR) | BIT13) ); - usc_RTCmd( info, RTCmd_PurgeRxFifo ); - - info->rx_enabled = false; - info->rx_overflow = false; - info->rx_rcc_underrun = false; - -} /* end of stop_receiver() */ - -/* usc_start_receiver() - * - * Enable the USC receiver - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void usc_start_receiver( struct mgsl_struct *info ) -{ - u32 phys_addr; - - if (debug_level >= DEBUG_LEVEL_ISR) - printk("%s(%d):usc_start_receiver(%s)\n", - __FILE__,__LINE__, info->device_name ); - - mgsl_reset_rx_dma_buffers( info ); - usc_stop_receiver( info ); - - usc_OutReg( info, CCSR, (u16)(usc_InReg(info,CCSR) | BIT13) ); - usc_RTCmd( info, RTCmd_PurgeRxFifo ); - - if ( info->params.mode == MGSL_MODE_HDLC || - info->params.mode == MGSL_MODE_RAW ) { - /* DMA mode Transfers */ - /* Program the DMA controller. */ - /* Enable the DMA controller end of buffer interrupt. */ - - /* program 16C32 with physical address of 1st DMA buffer entry */ - phys_addr = info->rx_buffer_list[0].phys_entry; - usc_OutDmaReg( info, NRARL, (u16)phys_addr ); - usc_OutDmaReg( info, NRARU, (u16)(phys_addr >> 16) ); - - usc_UnlatchRxstatusBits( info, RXSTATUS_ALL ); - usc_ClearIrqPendingBits( info, RECEIVE_DATA + RECEIVE_STATUS ); - usc_EnableInterrupts( info, RECEIVE_STATUS ); - - /* 1. Arm End of Buffer (EOB) Receive DMA Interrupt (BIT2 of RDIAR) */ - /* 2. Enable Receive DMA Interrupts (BIT1 of DICR) */ - - usc_OutDmaReg( info, RDIAR, BIT3 + BIT2 ); - usc_OutDmaReg( info, DICR, (u16)(usc_InDmaReg(info,DICR) | BIT1) ); - usc_DmaCmd( info, DmaCmd_InitRxChannel ); - if ( info->params.flags & HDLC_FLAG_AUTO_DCD ) - usc_EnableReceiver(info,ENABLE_AUTO_DCD); - else - usc_EnableReceiver(info,ENABLE_UNCONDITIONAL); - } else { - usc_UnlatchRxstatusBits(info, RXSTATUS_ALL); - usc_ClearIrqPendingBits(info, RECEIVE_DATA + RECEIVE_STATUS); - usc_EnableInterrupts(info, RECEIVE_DATA); - - usc_RTCmd( info, RTCmd_PurgeRxFifo ); - usc_RCmd( info, RCmd_EnterHuntmode ); - - usc_EnableReceiver(info,ENABLE_UNCONDITIONAL); - } - - usc_OutReg( info, CCSR, 0x1020 ); - - info->rx_enabled = true; - -} /* end of usc_start_receiver() */ - -/* usc_start_transmitter() - * - * Enable the USC transmitter and send a transmit frame if - * one is loaded in the DMA buffers. - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void usc_start_transmitter( struct mgsl_struct *info ) -{ - u32 phys_addr; - unsigned int FrameSize; - - if (debug_level >= DEBUG_LEVEL_ISR) - printk("%s(%d):usc_start_transmitter(%s)\n", - __FILE__,__LINE__, info->device_name ); - - if ( info->xmit_cnt ) { - - /* If auto RTS enabled and RTS is inactive, then assert */ - /* RTS and set a flag indicating that the driver should */ - /* negate RTS when the transmission completes. */ - - info->drop_rts_on_tx_done = false; - - if ( info->params.flags & HDLC_FLAG_AUTO_RTS ) { - usc_get_serial_signals( info ); - if ( !(info->serial_signals & SerialSignal_RTS) ) { - info->serial_signals |= SerialSignal_RTS; - usc_set_serial_signals( info ); - info->drop_rts_on_tx_done = true; - } - } - - - if ( info->params.mode == MGSL_MODE_ASYNC ) { - if ( !info->tx_active ) { - usc_UnlatchTxstatusBits(info, TXSTATUS_ALL); - usc_ClearIrqPendingBits(info, TRANSMIT_STATUS + TRANSMIT_DATA); - usc_EnableInterrupts(info, TRANSMIT_DATA); - usc_load_txfifo(info); - } - } else { - /* Disable transmit DMA controller while programming. */ - usc_DmaCmd( info, DmaCmd_ResetTxChannel ); - - /* Transmit DMA buffer is loaded, so program USC */ - /* to send the frame contained in the buffers. */ - - FrameSize = info->tx_buffer_list[info->start_tx_dma_buffer].rcc; - - /* if operating in Raw sync mode, reset the rcc component - * of the tx dma buffer entry, otherwise, the serial controller - * will send a closing sync char after this count. - */ - if ( info->params.mode == MGSL_MODE_RAW ) - info->tx_buffer_list[info->start_tx_dma_buffer].rcc = 0; - - /* Program the Transmit Character Length Register (TCLR) */ - /* and clear FIFO (TCC is loaded with TCLR on FIFO clear) */ - usc_OutReg( info, TCLR, (u16)FrameSize ); - - usc_RTCmd( info, RTCmd_PurgeTxFifo ); - - /* Program the address of the 1st DMA Buffer Entry in linked list */ - phys_addr = info->tx_buffer_list[info->start_tx_dma_buffer].phys_entry; - usc_OutDmaReg( info, NTARL, (u16)phys_addr ); - usc_OutDmaReg( info, NTARU, (u16)(phys_addr >> 16) ); - - usc_UnlatchTxstatusBits( info, TXSTATUS_ALL ); - usc_ClearIrqPendingBits( info, TRANSMIT_STATUS ); - usc_EnableInterrupts( info, TRANSMIT_STATUS ); - - if ( info->params.mode == MGSL_MODE_RAW && - info->num_tx_dma_buffers > 1 ) { - /* When running external sync mode, attempt to 'stream' transmit */ - /* by filling tx dma buffers as they become available. To do this */ - /* we need to enable Tx DMA EOB Status interrupts : */ - /* */ - /* 1. Arm End of Buffer (EOB) Transmit DMA Interrupt (BIT2 of TDIAR) */ - /* 2. Enable Transmit DMA Interrupts (BIT0 of DICR) */ - - usc_OutDmaReg( info, TDIAR, BIT2|BIT3 ); - usc_OutDmaReg( info, DICR, (u16)(usc_InDmaReg(info,DICR) | BIT0) ); - } - - /* Initialize Transmit DMA Channel */ - usc_DmaCmd( info, DmaCmd_InitTxChannel ); - - usc_TCmd( info, TCmd_SendFrame ); - - mod_timer(&info->tx_timer, jiffies + - msecs_to_jiffies(5000)); - } - info->tx_active = true; - } - - if ( !info->tx_enabled ) { - info->tx_enabled = true; - if ( info->params.flags & HDLC_FLAG_AUTO_CTS ) - usc_EnableTransmitter(info,ENABLE_AUTO_CTS); - else - usc_EnableTransmitter(info,ENABLE_UNCONDITIONAL); - } - -} /* end of usc_start_transmitter() */ - -/* usc_stop_transmitter() - * - * Stops the transmitter and DMA - * - * Arguments: info pointer to device isntance data - * Return Value: None - */ -static void usc_stop_transmitter( struct mgsl_struct *info ) -{ - if (debug_level >= DEBUG_LEVEL_ISR) - printk("%s(%d):usc_stop_transmitter(%s)\n", - __FILE__,__LINE__, info->device_name ); - - del_timer(&info->tx_timer); - - usc_UnlatchTxstatusBits( info, TXSTATUS_ALL ); - usc_ClearIrqPendingBits( info, TRANSMIT_STATUS + TRANSMIT_DATA ); - usc_DisableInterrupts( info, TRANSMIT_STATUS + TRANSMIT_DATA ); - - usc_EnableTransmitter(info,DISABLE_UNCONDITIONAL); - usc_DmaCmd( info, DmaCmd_ResetTxChannel ); - usc_RTCmd( info, RTCmd_PurgeTxFifo ); - - info->tx_enabled = false; - info->tx_active = false; - -} /* end of usc_stop_transmitter() */ - -/* usc_load_txfifo() - * - * Fill the transmit FIFO until the FIFO is full or - * there is no more data to load. - * - * Arguments: info pointer to device extension (instance data) - * Return Value: None - */ -static void usc_load_txfifo( struct mgsl_struct *info ) -{ - int Fifocount; - u8 TwoBytes[2]; - - if ( !info->xmit_cnt && !info->x_char ) - return; - - /* Select transmit FIFO status readback in TICR */ - usc_TCmd( info, TCmd_SelectTicrTxFifostatus ); - - /* load the Transmit FIFO until FIFOs full or all data sent */ - - while( (Fifocount = usc_InReg(info, TICR) >> 8) && info->xmit_cnt ) { - /* there is more space in the transmit FIFO and */ - /* there is more data in transmit buffer */ - - if ( (info->xmit_cnt > 1) && (Fifocount > 1) && !info->x_char ) { - /* write a 16-bit word from transmit buffer to 16C32 */ - - TwoBytes[0] = info->xmit_buf[info->xmit_tail++]; - info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); - TwoBytes[1] = info->xmit_buf[info->xmit_tail++]; - info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); - - outw( *((u16 *)TwoBytes), info->io_base + DATAREG); - - info->xmit_cnt -= 2; - info->icount.tx += 2; - } else { - /* only 1 byte left to transmit or 1 FIFO slot left */ - - outw( (inw( info->io_base + CCAR) & 0x0780) | (TDR+LSBONLY), - info->io_base + CCAR ); - - if (info->x_char) { - /* transmit pending high priority char */ - outw( info->x_char,info->io_base + CCAR ); - info->x_char = 0; - } else { - outw( info->xmit_buf[info->xmit_tail++],info->io_base + CCAR ); - info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); - info->xmit_cnt--; - } - info->icount.tx++; - } - } - -} /* end of usc_load_txfifo() */ - -/* usc_reset() - * - * Reset the adapter to a known state and prepare it for further use. - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void usc_reset( struct mgsl_struct *info ) -{ - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { - int i; - u32 readval; - - /* Set BIT30 of Misc Control Register */ - /* (Local Control Register 0x50) to force reset of USC. */ - - volatile u32 *MiscCtrl = (u32 *)(info->lcr_base + 0x50); - u32 *LCR0BRDR = (u32 *)(info->lcr_base + 0x28); - - info->misc_ctrl_value |= BIT30; - *MiscCtrl = info->misc_ctrl_value; - - /* - * Force at least 170ns delay before clearing - * reset bit. Each read from LCR takes at least - * 30ns so 10 times for 300ns to be safe. - */ - for(i=0;i<10;i++) - readval = *MiscCtrl; - - info->misc_ctrl_value &= ~BIT30; - *MiscCtrl = info->misc_ctrl_value; - - *LCR0BRDR = BUS_DESCRIPTOR( - 1, // Write Strobe Hold (0-3) - 2, // Write Strobe Delay (0-3) - 2, // Read Strobe Delay (0-3) - 0, // NWDD (Write data-data) (0-3) - 4, // NWAD (Write Addr-data) (0-31) - 0, // NXDA (Read/Write Data-Addr) (0-3) - 0, // NRDD (Read Data-Data) (0-3) - 5 // NRAD (Read Addr-Data) (0-31) - ); - } else { - /* do HW reset */ - outb( 0,info->io_base + 8 ); - } - - info->mbre_bit = 0; - info->loopback_bits = 0; - info->usc_idle_mode = 0; - - /* - * Program the Bus Configuration Register (BCR) - * - * <15> 0 Don't use separate address - * <14..6> 0 reserved - * <5..4> 00 IAckmode = Default, don't care - * <3> 1 Bus Request Totem Pole output - * <2> 1 Use 16 Bit data bus - * <1> 0 IRQ Totem Pole output - * <0> 0 Don't Shift Right Addr - * - * 0000 0000 0000 1100 = 0x000c - * - * By writing to io_base + SDPIN the Wait/Ack pin is - * programmed to work as a Wait pin. - */ - - outw( 0x000c,info->io_base + SDPIN ); - - - outw( 0,info->io_base ); - outw( 0,info->io_base + CCAR ); - - /* select little endian byte ordering */ - usc_RTCmd( info, RTCmd_SelectLittleEndian ); - - - /* Port Control Register (PCR) - * - * <15..14> 11 Port 7 is Output (~DMAEN, Bit 14 : 0 = Enabled) - * <13..12> 11 Port 6 is Output (~INTEN, Bit 12 : 0 = Enabled) - * <11..10> 00 Port 5 is Input (No Connect, Don't Care) - * <9..8> 00 Port 4 is Input (No Connect, Don't Care) - * <7..6> 11 Port 3 is Output (~RTS, Bit 6 : 0 = Enabled ) - * <5..4> 11 Port 2 is Output (~DTR, Bit 4 : 0 = Enabled ) - * <3..2> 01 Port 1 is Input (Dedicated RxC) - * <1..0> 01 Port 0 is Input (Dedicated TxC) - * - * 1111 0000 1111 0101 = 0xf0f5 - */ - - usc_OutReg( info, PCR, 0xf0f5 ); - - - /* - * Input/Output Control Register - * - * <15..14> 00 CTS is active low input - * <13..12> 00 DCD is active low input - * <11..10> 00 TxREQ pin is input (DSR) - * <9..8> 00 RxREQ pin is input (RI) - * <7..6> 00 TxD is output (Transmit Data) - * <5..3> 000 TxC Pin in Input (14.7456MHz Clock) - * <2..0> 100 RxC is Output (drive with BRG0) - * - * 0000 0000 0000 0100 = 0x0004 - */ - - usc_OutReg( info, IOCR, 0x0004 ); - -} /* end of usc_reset() */ - -/* usc_set_async_mode() - * - * Program adapter for asynchronous communications. - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void usc_set_async_mode( struct mgsl_struct *info ) -{ - u16 RegValue; - - /* disable interrupts while programming USC */ - usc_DisableMasterIrqBit( info ); - - outw( 0, info->io_base ); /* clear Master Bus Enable (DCAR) */ - usc_DmaCmd( info, DmaCmd_ResetAllChannels ); /* disable both DMA channels */ - - usc_loopback_frame( info ); - - /* Channel mode Register (CMR) - * - * <15..14> 00 Tx Sub modes, 00 = 1 Stop Bit - * <13..12> 00 00 = 16X Clock - * <11..8> 0000 Transmitter mode = Asynchronous - * <7..6> 00 reserved? - * <5..4> 00 Rx Sub modes, 00 = 16X Clock - * <3..0> 0000 Receiver mode = Asynchronous - * - * 0000 0000 0000 0000 = 0x0 - */ - - RegValue = 0; - if ( info->params.stop_bits != 1 ) - RegValue |= BIT14; - usc_OutReg( info, CMR, RegValue ); - - - /* Receiver mode Register (RMR) - * - * <15..13> 000 encoding = None - * <12..08> 00000 reserved (Sync Only) - * <7..6> 00 Even parity - * <5> 0 parity disabled - * <4..2> 000 Receive Char Length = 8 bits - * <1..0> 00 Disable Receiver - * - * 0000 0000 0000 0000 = 0x0 - */ - - RegValue = 0; - - if ( info->params.data_bits != 8 ) - RegValue |= BIT4+BIT3+BIT2; - - if ( info->params.parity != ASYNC_PARITY_NONE ) { - RegValue |= BIT5; - if ( info->params.parity != ASYNC_PARITY_ODD ) - RegValue |= BIT6; - } - - usc_OutReg( info, RMR, RegValue ); - - - /* Set IRQ trigger level */ - - usc_RCmd( info, RCmd_SelectRicrIntLevel ); - - - /* Receive Interrupt Control Register (RICR) - * - * <15..8> ? RxFIFO IRQ Request Level - * - * Note: For async mode the receive FIFO level must be set - * to 0 to avoid the situation where the FIFO contains fewer bytes - * than the trigger level and no more data is expected. - * - * <7> 0 Exited Hunt IA (Interrupt Arm) - * <6> 0 Idle Received IA - * <5> 0 Break/Abort IA - * <4> 0 Rx Bound IA - * <3> 0 Queued status reflects oldest byte in FIFO - * <2> 0 Abort/PE IA - * <1> 0 Rx Overrun IA - * <0> 0 Select TC0 value for readback - * - * 0000 0000 0100 0000 = 0x0000 + (FIFOLEVEL in MSB) - */ - - usc_OutReg( info, RICR, 0x0000 ); - - usc_UnlatchRxstatusBits( info, RXSTATUS_ALL ); - usc_ClearIrqPendingBits( info, RECEIVE_STATUS ); - - - /* Transmit mode Register (TMR) - * - * <15..13> 000 encoding = None - * <12..08> 00000 reserved (Sync Only) - * <7..6> 00 Transmit parity Even - * <5> 0 Transmit parity Disabled - * <4..2> 000 Tx Char Length = 8 bits - * <1..0> 00 Disable Transmitter - * - * 0000 0000 0000 0000 = 0x0 - */ - - RegValue = 0; - - if ( info->params.data_bits != 8 ) - RegValue |= BIT4+BIT3+BIT2; - - if ( info->params.parity != ASYNC_PARITY_NONE ) { - RegValue |= BIT5; - if ( info->params.parity != ASYNC_PARITY_ODD ) - RegValue |= BIT6; - } - - usc_OutReg( info, TMR, RegValue ); - - usc_set_txidle( info ); - - - /* Set IRQ trigger level */ - - usc_TCmd( info, TCmd_SelectTicrIntLevel ); - - - /* Transmit Interrupt Control Register (TICR) - * - * <15..8> ? Transmit FIFO IRQ Level - * <7> 0 Present IA (Interrupt Arm) - * <6> 1 Idle Sent IA - * <5> 0 Abort Sent IA - * <4> 0 EOF/EOM Sent IA - * <3> 0 CRC Sent IA - * <2> 0 1 = Wait for SW Trigger to Start Frame - * <1> 0 Tx Underrun IA - * <0> 0 TC0 constant on read back - * - * 0000 0000 0100 0000 = 0x0040 - */ - - usc_OutReg( info, TICR, 0x1f40 ); - - usc_UnlatchTxstatusBits( info, TXSTATUS_ALL ); - usc_ClearIrqPendingBits( info, TRANSMIT_STATUS ); - - usc_enable_async_clock( info, info->params.data_rate ); - - - /* Channel Control/status Register (CCSR) - * - * <15> X RCC FIFO Overflow status (RO) - * <14> X RCC FIFO Not Empty status (RO) - * <13> 0 1 = Clear RCC FIFO (WO) - * <12> X DPLL in Sync status (RO) - * <11> X DPLL 2 Missed Clocks status (RO) - * <10> X DPLL 1 Missed Clock status (RO) - * <9..8> 00 DPLL Resync on rising and falling edges (RW) - * <7> X SDLC Loop On status (RO) - * <6> X SDLC Loop Send status (RO) - * <5> 1 Bypass counters for TxClk and RxClk (RW) - * <4..2> 000 Last Char of SDLC frame has 8 bits (RW) - * <1..0> 00 reserved - * - * 0000 0000 0010 0000 = 0x0020 - */ - - usc_OutReg( info, CCSR, 0x0020 ); - - usc_DisableInterrupts( info, TRANSMIT_STATUS + TRANSMIT_DATA + - RECEIVE_DATA + RECEIVE_STATUS ); - - usc_ClearIrqPendingBits( info, TRANSMIT_STATUS + TRANSMIT_DATA + - RECEIVE_DATA + RECEIVE_STATUS ); - - usc_EnableMasterIrqBit( info ); - - if (info->bus_type == MGSL_BUS_TYPE_ISA) { - /* Enable INTEN (Port 6, Bit12) */ - /* This connects the IRQ request signal to the ISA bus */ - usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) & ~BIT12)); - } - - if (info->params.loopback) { - info->loopback_bits = 0x300; - outw(0x0300, info->io_base + CCAR); - } - -} /* end of usc_set_async_mode() */ - -/* usc_loopback_frame() - * - * Loop back a small (2 byte) dummy SDLC frame. - * Interrupts and DMA are NOT used. The purpose of this is to - * clear any 'stale' status info left over from running in async mode. - * - * The 16C32 shows the strange behaviour of marking the 1st - * received SDLC frame with a CRC error even when there is no - * CRC error. To get around this a small dummy from of 2 bytes - * is looped back when switching from async to sync mode. - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void usc_loopback_frame( struct mgsl_struct *info ) -{ - int i; - unsigned long oldmode = info->params.mode; - - info->params.mode = MGSL_MODE_HDLC; - - usc_DisableMasterIrqBit( info ); - - usc_set_sdlc_mode( info ); - usc_enable_loopback( info, 1 ); - - /* Write 16-bit Time Constant for BRG0 */ - usc_OutReg( info, TC0R, 0 ); - - /* Channel Control Register (CCR) - * - * <15..14> 00 Don't use 32-bit Tx Control Blocks (TCBs) - * <13> 0 Trigger Tx on SW Command Disabled - * <12> 0 Flag Preamble Disabled - * <11..10> 00 Preamble Length = 8-Bits - * <9..8> 01 Preamble Pattern = flags - * <7..6> 10 Don't use 32-bit Rx status Blocks (RSBs) - * <5> 0 Trigger Rx on SW Command Disabled - * <4..0> 0 reserved - * - * 0000 0001 0000 0000 = 0x0100 - */ - - usc_OutReg( info, CCR, 0x0100 ); - - /* SETUP RECEIVER */ - usc_RTCmd( info, RTCmd_PurgeRxFifo ); - usc_EnableReceiver(info,ENABLE_UNCONDITIONAL); - - /* SETUP TRANSMITTER */ - /* Program the Transmit Character Length Register (TCLR) */ - /* and clear FIFO (TCC is loaded with TCLR on FIFO clear) */ - usc_OutReg( info, TCLR, 2 ); - usc_RTCmd( info, RTCmd_PurgeTxFifo ); - - /* unlatch Tx status bits, and start transmit channel. */ - usc_UnlatchTxstatusBits(info,TXSTATUS_ALL); - outw(0,info->io_base + DATAREG); - - /* ENABLE TRANSMITTER */ - usc_TCmd( info, TCmd_SendFrame ); - usc_EnableTransmitter(info,ENABLE_UNCONDITIONAL); - - /* WAIT FOR RECEIVE COMPLETE */ - for (i=0 ; i<1000 ; i++) - if (usc_InReg( info, RCSR ) & (BIT8 + BIT4 + BIT3 + BIT1)) - break; - - /* clear Internal Data loopback mode */ - usc_enable_loopback(info, 0); - - usc_EnableMasterIrqBit(info); - - info->params.mode = oldmode; - -} /* end of usc_loopback_frame() */ - -/* usc_set_sync_mode() Programs the USC for SDLC communications. - * - * Arguments: info pointer to adapter info structure - * Return Value: None - */ -static void usc_set_sync_mode( struct mgsl_struct *info ) -{ - usc_loopback_frame( info ); - usc_set_sdlc_mode( info ); - - if (info->bus_type == MGSL_BUS_TYPE_ISA) { - /* Enable INTEN (Port 6, Bit12) */ - /* This connects the IRQ request signal to the ISA bus */ - usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) & ~BIT12)); - } - - usc_enable_aux_clock(info, info->params.clock_speed); - - if (info->params.loopback) - usc_enable_loopback(info,1); - -} /* end of mgsl_set_sync_mode() */ - -/* usc_set_txidle() Set the HDLC idle mode for the transmitter. - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void usc_set_txidle( struct mgsl_struct *info ) -{ - u16 usc_idle_mode = IDLEMODE_FLAGS; - - /* Map API idle mode to USC register bits */ - - switch( info->idle_mode ){ - case HDLC_TXIDLE_FLAGS: usc_idle_mode = IDLEMODE_FLAGS; break; - case HDLC_TXIDLE_ALT_ZEROS_ONES: usc_idle_mode = IDLEMODE_ALT_ONE_ZERO; break; - case HDLC_TXIDLE_ZEROS: usc_idle_mode = IDLEMODE_ZERO; break; - case HDLC_TXIDLE_ONES: usc_idle_mode = IDLEMODE_ONE; break; - case HDLC_TXIDLE_ALT_MARK_SPACE: usc_idle_mode = IDLEMODE_ALT_MARK_SPACE; break; - case HDLC_TXIDLE_SPACE: usc_idle_mode = IDLEMODE_SPACE; break; - case HDLC_TXIDLE_MARK: usc_idle_mode = IDLEMODE_MARK; break; - } - - info->usc_idle_mode = usc_idle_mode; - //usc_OutReg(info, TCSR, usc_idle_mode); - info->tcsr_value &= ~IDLEMODE_MASK; /* clear idle mode bits */ - info->tcsr_value += usc_idle_mode; - usc_OutReg(info, TCSR, info->tcsr_value); - - /* - * if SyncLink WAN adapter is running in external sync mode, the - * transmitter has been set to Monosync in order to try to mimic - * a true raw outbound bit stream. Monosync still sends an open/close - * sync char at the start/end of a frame. Try to match those sync - * patterns to the idle mode set here - */ - if ( info->params.mode == MGSL_MODE_RAW ) { - unsigned char syncpat = 0; - switch( info->idle_mode ) { - case HDLC_TXIDLE_FLAGS: - syncpat = 0x7e; - break; - case HDLC_TXIDLE_ALT_ZEROS_ONES: - syncpat = 0x55; - break; - case HDLC_TXIDLE_ZEROS: - case HDLC_TXIDLE_SPACE: - syncpat = 0x00; - break; - case HDLC_TXIDLE_ONES: - case HDLC_TXIDLE_MARK: - syncpat = 0xff; - break; - case HDLC_TXIDLE_ALT_MARK_SPACE: - syncpat = 0xaa; - break; - } - - usc_SetTransmitSyncChars(info,syncpat,syncpat); - } - -} /* end of usc_set_txidle() */ - -/* usc_get_serial_signals() - * - * Query the adapter for the state of the V24 status (input) signals. - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void usc_get_serial_signals( struct mgsl_struct *info ) -{ - u16 status; - - /* clear all serial signals except DTR and RTS */ - info->serial_signals &= SerialSignal_DTR + SerialSignal_RTS; - - /* Read the Misc Interrupt status Register (MISR) to get */ - /* the V24 status signals. */ - - status = usc_InReg( info, MISR ); - - /* set serial signal bits to reflect MISR */ - - if ( status & MISCSTATUS_CTS ) - info->serial_signals |= SerialSignal_CTS; - - if ( status & MISCSTATUS_DCD ) - info->serial_signals |= SerialSignal_DCD; - - if ( status & MISCSTATUS_RI ) - info->serial_signals |= SerialSignal_RI; - - if ( status & MISCSTATUS_DSR ) - info->serial_signals |= SerialSignal_DSR; - -} /* end of usc_get_serial_signals() */ - -/* usc_set_serial_signals() - * - * Set the state of DTR and RTS based on contents of - * serial_signals member of device extension. - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void usc_set_serial_signals( struct mgsl_struct *info ) -{ - u16 Control; - unsigned char V24Out = info->serial_signals; - - /* get the current value of the Port Control Register (PCR) */ - - Control = usc_InReg( info, PCR ); - - if ( V24Out & SerialSignal_RTS ) - Control &= ~(BIT6); - else - Control |= BIT6; - - if ( V24Out & SerialSignal_DTR ) - Control &= ~(BIT4); - else - Control |= BIT4; - - usc_OutReg( info, PCR, Control ); - -} /* end of usc_set_serial_signals() */ - -/* usc_enable_async_clock() - * - * Enable the async clock at the specified frequency. - * - * Arguments: info pointer to device instance data - * data_rate data rate of clock in bps - * 0 disables the AUX clock. - * Return Value: None - */ -static void usc_enable_async_clock( struct mgsl_struct *info, u32 data_rate ) -{ - if ( data_rate ) { - /* - * Clock mode Control Register (CMCR) - * - * <15..14> 00 counter 1 Disabled - * <13..12> 00 counter 0 Disabled - * <11..10> 11 BRG1 Input is TxC Pin - * <9..8> 11 BRG0 Input is TxC Pin - * <7..6> 01 DPLL Input is BRG1 Output - * <5..3> 100 TxCLK comes from BRG0 - * <2..0> 100 RxCLK comes from BRG0 - * - * 0000 1111 0110 0100 = 0x0f64 - */ - - usc_OutReg( info, CMCR, 0x0f64 ); - - - /* - * Write 16-bit Time Constant for BRG0 - * Time Constant = (ClkSpeed / data_rate) - 1 - * ClkSpeed = 921600 (ISA), 691200 (PCI) - */ - - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) - usc_OutReg( info, TC0R, (u16)((691200/data_rate) - 1) ); - else - usc_OutReg( info, TC0R, (u16)((921600/data_rate) - 1) ); - - - /* - * Hardware Configuration Register (HCR) - * Clear Bit 1, BRG0 mode = Continuous - * Set Bit 0 to enable BRG0. - */ - - usc_OutReg( info, HCR, - (u16)((usc_InReg( info, HCR ) & ~BIT1) | BIT0) ); - - - /* Input/Output Control Reg, <2..0> = 100, Drive RxC pin with BRG0 */ - - usc_OutReg( info, IOCR, - (u16)((usc_InReg(info, IOCR) & 0xfff8) | 0x0004) ); - } else { - /* data rate == 0 so turn off BRG0 */ - usc_OutReg( info, HCR, (u16)(usc_InReg( info, HCR ) & ~BIT0) ); - } - -} /* end of usc_enable_async_clock() */ - -/* - * Buffer Structures: - * - * Normal memory access uses virtual addresses that can make discontiguous - * physical memory pages appear to be contiguous in the virtual address - * space (the processors memory mapping handles the conversions). - * - * DMA transfers require physically contiguous memory. This is because - * the DMA system controller and DMA bus masters deal with memory using - * only physical addresses. - * - * This causes a problem under Windows NT when large DMA buffers are - * needed. Fragmentation of the nonpaged pool prevents allocations of - * physically contiguous buffers larger than the PAGE_SIZE. - * - * However the 16C32 supports Bus Master Scatter/Gather DMA which - * allows DMA transfers to physically discontiguous buffers. Information - * about each data transfer buffer is contained in a memory structure - * called a 'buffer entry'. A list of buffer entries is maintained - * to track and control the use of the data transfer buffers. - * - * To support this strategy we will allocate sufficient PAGE_SIZE - * contiguous memory buffers to allow for the total required buffer - * space. - * - * The 16C32 accesses the list of buffer entries using Bus Master - * DMA. Control information is read from the buffer entries by the - * 16C32 to control data transfers. status information is written to - * the buffer entries by the 16C32 to indicate the status of completed - * transfers. - * - * The CPU writes control information to the buffer entries to control - * the 16C32 and reads status information from the buffer entries to - * determine information about received and transmitted frames. - * - * Because the CPU and 16C32 (adapter) both need simultaneous access - * to the buffer entries, the buffer entry memory is allocated with - * HalAllocateCommonBuffer(). This restricts the size of the buffer - * entry list to PAGE_SIZE. - * - * The actual data buffers on the other hand will only be accessed - * by the CPU or the adapter but not by both simultaneously. This allows - * Scatter/Gather packet based DMA procedures for using physically - * discontiguous pages. - */ - -/* - * mgsl_reset_tx_dma_buffers() - * - * Set the count for all transmit buffers to 0 to indicate the - * buffer is available for use and set the current buffer to the - * first buffer. This effectively makes all buffers free and - * discards any data in buffers. - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void mgsl_reset_tx_dma_buffers( struct mgsl_struct *info ) -{ - unsigned int i; - - for ( i = 0; i < info->tx_buffer_count; i++ ) { - *((unsigned long *)&(info->tx_buffer_list[i].count)) = 0; - } - - info->current_tx_buffer = 0; - info->start_tx_dma_buffer = 0; - info->tx_dma_buffers_used = 0; - - info->get_tx_holding_index = 0; - info->put_tx_holding_index = 0; - info->tx_holding_count = 0; - -} /* end of mgsl_reset_tx_dma_buffers() */ - -/* - * num_free_tx_dma_buffers() - * - * returns the number of free tx dma buffers available - * - * Arguments: info pointer to device instance data - * Return Value: number of free tx dma buffers - */ -static int num_free_tx_dma_buffers(struct mgsl_struct *info) -{ - return info->tx_buffer_count - info->tx_dma_buffers_used; -} - -/* - * mgsl_reset_rx_dma_buffers() - * - * Set the count for all receive buffers to DMABUFFERSIZE - * and set the current buffer to the first buffer. This effectively - * makes all buffers free and discards any data in buffers. - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -static void mgsl_reset_rx_dma_buffers( struct mgsl_struct *info ) -{ - unsigned int i; - - for ( i = 0; i < info->rx_buffer_count; i++ ) { - *((unsigned long *)&(info->rx_buffer_list[i].count)) = DMABUFFERSIZE; -// info->rx_buffer_list[i].count = DMABUFFERSIZE; -// info->rx_buffer_list[i].status = 0; - } - - info->current_rx_buffer = 0; - -} /* end of mgsl_reset_rx_dma_buffers() */ - -/* - * mgsl_free_rx_frame_buffers() - * - * Free the receive buffers used by a received SDLC - * frame such that the buffers can be reused. - * - * Arguments: - * - * info pointer to device instance data - * StartIndex index of 1st receive buffer of frame - * EndIndex index of last receive buffer of frame - * - * Return Value: None - */ -static void mgsl_free_rx_frame_buffers( struct mgsl_struct *info, unsigned int StartIndex, unsigned int EndIndex ) -{ - bool Done = false; - DMABUFFERENTRY *pBufEntry; - unsigned int Index; - - /* Starting with 1st buffer entry of the frame clear the status */ - /* field and set the count field to DMA Buffer Size. */ - - Index = StartIndex; - - while( !Done ) { - pBufEntry = &(info->rx_buffer_list[Index]); - - if ( Index == EndIndex ) { - /* This is the last buffer of the frame! */ - Done = true; - } - - /* reset current buffer for reuse */ -// pBufEntry->status = 0; -// pBufEntry->count = DMABUFFERSIZE; - *((unsigned long *)&(pBufEntry->count)) = DMABUFFERSIZE; - - /* advance to next buffer entry in linked list */ - Index++; - if ( Index == info->rx_buffer_count ) - Index = 0; - } - - /* set current buffer to next buffer after last buffer of frame */ - info->current_rx_buffer = Index; - -} /* end of free_rx_frame_buffers() */ - -/* mgsl_get_rx_frame() - * - * This function attempts to return a received SDLC frame from the - * receive DMA buffers. Only frames received without errors are returned. - * - * Arguments: info pointer to device extension - * Return Value: true if frame returned, otherwise false - */ -static bool mgsl_get_rx_frame(struct mgsl_struct *info) -{ - unsigned int StartIndex, EndIndex; /* index of 1st and last buffers of Rx frame */ - unsigned short status; - DMABUFFERENTRY *pBufEntry; - unsigned int framesize = 0; - bool ReturnCode = false; - unsigned long flags; - struct tty_struct *tty = info->port.tty; - bool return_frame = false; - - /* - * current_rx_buffer points to the 1st buffer of the next available - * receive frame. To find the last buffer of the frame look for - * a non-zero status field in the buffer entries. (The status - * field is set by the 16C32 after completing a receive frame. - */ - - StartIndex = EndIndex = info->current_rx_buffer; - - while( !info->rx_buffer_list[EndIndex].status ) { - /* - * If the count field of the buffer entry is non-zero then - * this buffer has not been used. (The 16C32 clears the count - * field when it starts using the buffer.) If an unused buffer - * is encountered then there are no frames available. - */ - - if ( info->rx_buffer_list[EndIndex].count ) - goto Cleanup; - - /* advance to next buffer entry in linked list */ - EndIndex++; - if ( EndIndex == info->rx_buffer_count ) - EndIndex = 0; - - /* if entire list searched then no frame available */ - if ( EndIndex == StartIndex ) { - /* If this occurs then something bad happened, - * all buffers have been 'used' but none mark - * the end of a frame. Reset buffers and receiver. - */ - - if ( info->rx_enabled ){ - spin_lock_irqsave(&info->irq_spinlock,flags); - usc_start_receiver(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - } - goto Cleanup; - } - } - - - /* check status of receive frame */ - - status = info->rx_buffer_list[EndIndex].status; - - if ( status & (RXSTATUS_SHORT_FRAME + RXSTATUS_OVERRUN + - RXSTATUS_CRC_ERROR + RXSTATUS_ABORT) ) { - if ( status & RXSTATUS_SHORT_FRAME ) - info->icount.rxshort++; - else if ( status & RXSTATUS_ABORT ) - info->icount.rxabort++; - else if ( status & RXSTATUS_OVERRUN ) - info->icount.rxover++; - else { - info->icount.rxcrc++; - if ( info->params.crc_type & HDLC_CRC_RETURN_EX ) - return_frame = true; - } - framesize = 0; -#if SYNCLINK_GENERIC_HDLC - { - info->netdev->stats.rx_errors++; - info->netdev->stats.rx_frame_errors++; - } -#endif - } else - return_frame = true; - - if ( return_frame ) { - /* receive frame has no errors, get frame size. - * The frame size is the starting value of the RCC (which was - * set to 0xffff) minus the ending value of the RCC (decremented - * once for each receive character) minus 2 for the 16-bit CRC. - */ - - framesize = RCLRVALUE - info->rx_buffer_list[EndIndex].rcc; - - /* adjust frame size for CRC if any */ - if ( info->params.crc_type == HDLC_CRC_16_CCITT ) - framesize -= 2; - else if ( info->params.crc_type == HDLC_CRC_32_CCITT ) - framesize -= 4; - } - - if ( debug_level >= DEBUG_LEVEL_BH ) - printk("%s(%d):mgsl_get_rx_frame(%s) status=%04X size=%d\n", - __FILE__,__LINE__,info->device_name,status,framesize); - - if ( debug_level >= DEBUG_LEVEL_DATA ) - mgsl_trace_block(info,info->rx_buffer_list[StartIndex].virt_addr, - min_t(int, framesize, DMABUFFERSIZE),0); - - if (framesize) { - if ( ( (info->params.crc_type & HDLC_CRC_RETURN_EX) && - ((framesize+1) > info->max_frame_size) ) || - (framesize > info->max_frame_size) ) - info->icount.rxlong++; - else { - /* copy dma buffer(s) to contiguous intermediate buffer */ - int copy_count = framesize; - int index = StartIndex; - unsigned char *ptmp = info->intermediate_rxbuffer; - - if ( !(status & RXSTATUS_CRC_ERROR)) - info->icount.rxok++; - - while(copy_count) { - int partial_count; - if ( copy_count > DMABUFFERSIZE ) - partial_count = DMABUFFERSIZE; - else - partial_count = copy_count; - - pBufEntry = &(info->rx_buffer_list[index]); - memcpy( ptmp, pBufEntry->virt_addr, partial_count ); - ptmp += partial_count; - copy_count -= partial_count; - - if ( ++index == info->rx_buffer_count ) - index = 0; - } - - if ( info->params.crc_type & HDLC_CRC_RETURN_EX ) { - ++framesize; - *ptmp = (status & RXSTATUS_CRC_ERROR ? - RX_CRC_ERROR : - RX_OK); - - if ( debug_level >= DEBUG_LEVEL_DATA ) - printk("%s(%d):mgsl_get_rx_frame(%s) rx frame status=%d\n", - __FILE__,__LINE__,info->device_name, - *ptmp); - } - -#if SYNCLINK_GENERIC_HDLC - if (info->netcount) - hdlcdev_rx(info,info->intermediate_rxbuffer,framesize); - else -#endif - ldisc_receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize); - } - } - /* Free the buffers used by this frame. */ - mgsl_free_rx_frame_buffers( info, StartIndex, EndIndex ); - - ReturnCode = true; - -Cleanup: - - if ( info->rx_enabled && info->rx_overflow ) { - /* The receiver needs to restarted because of - * a receive overflow (buffer or FIFO). If the - * receive buffers are now empty, then restart receiver. - */ - - if ( !info->rx_buffer_list[EndIndex].status && - info->rx_buffer_list[EndIndex].count ) { - spin_lock_irqsave(&info->irq_spinlock,flags); - usc_start_receiver(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - } - } - - return ReturnCode; - -} /* end of mgsl_get_rx_frame() */ - -/* mgsl_get_raw_rx_frame() - * - * This function attempts to return a received frame from the - * receive DMA buffers when running in external loop mode. In this mode, - * we will return at most one DMABUFFERSIZE frame to the application. - * The USC receiver is triggering off of DCD going active to start a new - * frame, and DCD going inactive to terminate the frame (similar to - * processing a closing flag character). - * - * In this routine, we will return DMABUFFERSIZE "chunks" at a time. - * If DCD goes inactive, the last Rx DMA Buffer will have a non-zero - * status field and the RCC field will indicate the length of the - * entire received frame. We take this RCC field and get the modulus - * of RCC and DMABUFFERSIZE to determine if number of bytes in the - * last Rx DMA buffer and return that last portion of the frame. - * - * Arguments: info pointer to device extension - * Return Value: true if frame returned, otherwise false - */ -static bool mgsl_get_raw_rx_frame(struct mgsl_struct *info) -{ - unsigned int CurrentIndex, NextIndex; - unsigned short status; - DMABUFFERENTRY *pBufEntry; - unsigned int framesize = 0; - bool ReturnCode = false; - unsigned long flags; - struct tty_struct *tty = info->port.tty; - - /* - * current_rx_buffer points to the 1st buffer of the next available - * receive frame. The status field is set by the 16C32 after - * completing a receive frame. If the status field of this buffer - * is zero, either the USC is still filling this buffer or this - * is one of a series of buffers making up a received frame. - * - * If the count field of this buffer is zero, the USC is either - * using this buffer or has used this buffer. Look at the count - * field of the next buffer. If that next buffer's count is - * non-zero, the USC is still actively using the current buffer. - * Otherwise, if the next buffer's count field is zero, the - * current buffer is complete and the USC is using the next - * buffer. - */ - CurrentIndex = NextIndex = info->current_rx_buffer; - ++NextIndex; - if ( NextIndex == info->rx_buffer_count ) - NextIndex = 0; - - if ( info->rx_buffer_list[CurrentIndex].status != 0 || - (info->rx_buffer_list[CurrentIndex].count == 0 && - info->rx_buffer_list[NextIndex].count == 0)) { - /* - * Either the status field of this dma buffer is non-zero - * (indicating the last buffer of a receive frame) or the next - * buffer is marked as in use -- implying this buffer is complete - * and an intermediate buffer for this received frame. - */ - - status = info->rx_buffer_list[CurrentIndex].status; - - if ( status & (RXSTATUS_SHORT_FRAME + RXSTATUS_OVERRUN + - RXSTATUS_CRC_ERROR + RXSTATUS_ABORT) ) { - if ( status & RXSTATUS_SHORT_FRAME ) - info->icount.rxshort++; - else if ( status & RXSTATUS_ABORT ) - info->icount.rxabort++; - else if ( status & RXSTATUS_OVERRUN ) - info->icount.rxover++; - else - info->icount.rxcrc++; - framesize = 0; - } else { - /* - * A receive frame is available, get frame size and status. - * - * The frame size is the starting value of the RCC (which was - * set to 0xffff) minus the ending value of the RCC (decremented - * once for each receive character) minus 2 or 4 for the 16-bit - * or 32-bit CRC. - * - * If the status field is zero, this is an intermediate buffer. - * It's size is 4K. - * - * If the DMA Buffer Entry's Status field is non-zero, the - * receive operation completed normally (ie: DCD dropped). The - * RCC field is valid and holds the received frame size. - * It is possible that the RCC field will be zero on a DMA buffer - * entry with a non-zero status. This can occur if the total - * frame size (number of bytes between the time DCD goes active - * to the time DCD goes inactive) exceeds 65535 bytes. In this - * case the 16C32 has underrun on the RCC count and appears to - * stop updating this counter to let us know the actual received - * frame size. If this happens (non-zero status and zero RCC), - * simply return the entire RxDMA Buffer - */ - if ( status ) { - /* - * In the event that the final RxDMA Buffer is - * terminated with a non-zero status and the RCC - * field is zero, we interpret this as the RCC - * having underflowed (received frame > 65535 bytes). - * - * Signal the event to the user by passing back - * a status of RxStatus_CrcError returning the full - * buffer and let the app figure out what data is - * actually valid - */ - if ( info->rx_buffer_list[CurrentIndex].rcc ) - framesize = RCLRVALUE - info->rx_buffer_list[CurrentIndex].rcc; - else - framesize = DMABUFFERSIZE; - } - else - framesize = DMABUFFERSIZE; - } - - if ( framesize > DMABUFFERSIZE ) { - /* - * if running in raw sync mode, ISR handler for - * End Of Buffer events terminates all buffers at 4K. - * If this frame size is said to be >4K, get the - * actual number of bytes of the frame in this buffer. - */ - framesize = framesize % DMABUFFERSIZE; - } - - - if ( debug_level >= DEBUG_LEVEL_BH ) - printk("%s(%d):mgsl_get_raw_rx_frame(%s) status=%04X size=%d\n", - __FILE__,__LINE__,info->device_name,status,framesize); - - if ( debug_level >= DEBUG_LEVEL_DATA ) - mgsl_trace_block(info,info->rx_buffer_list[CurrentIndex].virt_addr, - min_t(int, framesize, DMABUFFERSIZE),0); - - if (framesize) { - /* copy dma buffer(s) to contiguous intermediate buffer */ - /* NOTE: we never copy more than DMABUFFERSIZE bytes */ - - pBufEntry = &(info->rx_buffer_list[CurrentIndex]); - memcpy( info->intermediate_rxbuffer, pBufEntry->virt_addr, framesize); - info->icount.rxok++; - - ldisc_receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize); - } - - /* Free the buffers used by this frame. */ - mgsl_free_rx_frame_buffers( info, CurrentIndex, CurrentIndex ); - - ReturnCode = true; - } - - - if ( info->rx_enabled && info->rx_overflow ) { - /* The receiver needs to restarted because of - * a receive overflow (buffer or FIFO). If the - * receive buffers are now empty, then restart receiver. - */ - - if ( !info->rx_buffer_list[CurrentIndex].status && - info->rx_buffer_list[CurrentIndex].count ) { - spin_lock_irqsave(&info->irq_spinlock,flags); - usc_start_receiver(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - } - } - - return ReturnCode; - -} /* end of mgsl_get_raw_rx_frame() */ - -/* mgsl_load_tx_dma_buffer() - * - * Load the transmit DMA buffer with the specified data. - * - * Arguments: - * - * info pointer to device extension - * Buffer pointer to buffer containing frame to load - * BufferSize size in bytes of frame in Buffer - * - * Return Value: None - */ -static void mgsl_load_tx_dma_buffer(struct mgsl_struct *info, - const char *Buffer, unsigned int BufferSize) -{ - unsigned short Copycount; - unsigned int i = 0; - DMABUFFERENTRY *pBufEntry; - - if ( debug_level >= DEBUG_LEVEL_DATA ) - mgsl_trace_block(info,Buffer, min_t(int, BufferSize, DMABUFFERSIZE), 1); - - if (info->params.flags & HDLC_FLAG_HDLC_LOOPMODE) { - /* set CMR:13 to start transmit when - * next GoAhead (abort) is received - */ - info->cmr_value |= BIT13; - } - - /* begin loading the frame in the next available tx dma - * buffer, remember it's starting location for setting - * up tx dma operation - */ - i = info->current_tx_buffer; - info->start_tx_dma_buffer = i; - - /* Setup the status and RCC (Frame Size) fields of the 1st */ - /* buffer entry in the transmit DMA buffer list. */ - - info->tx_buffer_list[i].status = info->cmr_value & 0xf000; - info->tx_buffer_list[i].rcc = BufferSize; - info->tx_buffer_list[i].count = BufferSize; - - /* Copy frame data from 1st source buffer to the DMA buffers. */ - /* The frame data may span multiple DMA buffers. */ - - while( BufferSize ){ - /* Get a pointer to next DMA buffer entry. */ - pBufEntry = &info->tx_buffer_list[i++]; - - if ( i == info->tx_buffer_count ) - i=0; - - /* Calculate the number of bytes that can be copied from */ - /* the source buffer to this DMA buffer. */ - if ( BufferSize > DMABUFFERSIZE ) - Copycount = DMABUFFERSIZE; - else - Copycount = BufferSize; - - /* Actually copy data from source buffer to DMA buffer. */ - /* Also set the data count for this individual DMA buffer. */ - if ( info->bus_type == MGSL_BUS_TYPE_PCI ) - mgsl_load_pci_memory(pBufEntry->virt_addr, Buffer,Copycount); - else - memcpy(pBufEntry->virt_addr, Buffer, Copycount); - - pBufEntry->count = Copycount; - - /* Advance source pointer and reduce remaining data count. */ - Buffer += Copycount; - BufferSize -= Copycount; - - ++info->tx_dma_buffers_used; - } - - /* remember next available tx dma buffer */ - info->current_tx_buffer = i; - -} /* end of mgsl_load_tx_dma_buffer() */ - -/* - * mgsl_register_test() - * - * Performs a register test of the 16C32. - * - * Arguments: info pointer to device instance data - * Return Value: true if test passed, otherwise false - */ -static bool mgsl_register_test( struct mgsl_struct *info ) -{ - static unsigned short BitPatterns[] = - { 0x0000, 0xffff, 0xaaaa, 0x5555, 0x1234, 0x6969, 0x9696, 0x0f0f }; - static unsigned int Patterncount = ARRAY_SIZE(BitPatterns); - unsigned int i; - bool rc = true; - unsigned long flags; - - spin_lock_irqsave(&info->irq_spinlock,flags); - usc_reset(info); - - /* Verify the reset state of some registers. */ - - if ( (usc_InReg( info, SICR ) != 0) || - (usc_InReg( info, IVR ) != 0) || - (usc_InDmaReg( info, DIVR ) != 0) ){ - rc = false; - } - - if ( rc ){ - /* Write bit patterns to various registers but do it out of */ - /* sync, then read back and verify values. */ - - for ( i = 0 ; i < Patterncount ; i++ ) { - usc_OutReg( info, TC0R, BitPatterns[i] ); - usc_OutReg( info, TC1R, BitPatterns[(i+1)%Patterncount] ); - usc_OutReg( info, TCLR, BitPatterns[(i+2)%Patterncount] ); - usc_OutReg( info, RCLR, BitPatterns[(i+3)%Patterncount] ); - usc_OutReg( info, RSR, BitPatterns[(i+4)%Patterncount] ); - usc_OutDmaReg( info, TBCR, BitPatterns[(i+5)%Patterncount] ); - - if ( (usc_InReg( info, TC0R ) != BitPatterns[i]) || - (usc_InReg( info, TC1R ) != BitPatterns[(i+1)%Patterncount]) || - (usc_InReg( info, TCLR ) != BitPatterns[(i+2)%Patterncount]) || - (usc_InReg( info, RCLR ) != BitPatterns[(i+3)%Patterncount]) || - (usc_InReg( info, RSR ) != BitPatterns[(i+4)%Patterncount]) || - (usc_InDmaReg( info, TBCR ) != BitPatterns[(i+5)%Patterncount]) ){ - rc = false; - break; - } - } - } - - usc_reset(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - return rc; - -} /* end of mgsl_register_test() */ - -/* mgsl_irq_test() Perform interrupt test of the 16C32. - * - * Arguments: info pointer to device instance data - * Return Value: true if test passed, otherwise false - */ -static bool mgsl_irq_test( struct mgsl_struct *info ) -{ - unsigned long EndTime; - unsigned long flags; - - spin_lock_irqsave(&info->irq_spinlock,flags); - usc_reset(info); - - /* - * Setup 16C32 to interrupt on TxC pin (14MHz clock) transition. - * The ISR sets irq_occurred to true. - */ - - info->irq_occurred = false; - - /* Enable INTEN gate for ISA adapter (Port 6, Bit12) */ - /* Enable INTEN (Port 6, Bit12) */ - /* This connects the IRQ request signal to the ISA bus */ - /* on the ISA adapter. This has no effect for the PCI adapter */ - usc_OutReg( info, PCR, (unsigned short)((usc_InReg(info, PCR) | BIT13) & ~BIT12) ); - - usc_EnableMasterIrqBit(info); - usc_EnableInterrupts(info, IO_PIN); - usc_ClearIrqPendingBits(info, IO_PIN); - - usc_UnlatchIostatusBits(info, MISCSTATUS_TXC_LATCHED); - usc_EnableStatusIrqs(info, SICR_TXC_ACTIVE + SICR_TXC_INACTIVE); - - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - EndTime=100; - while( EndTime-- && !info->irq_occurred ) { - msleep_interruptible(10); - } - - spin_lock_irqsave(&info->irq_spinlock,flags); - usc_reset(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - return info->irq_occurred; - -} /* end of mgsl_irq_test() */ - -/* mgsl_dma_test() - * - * Perform a DMA test of the 16C32. A small frame is - * transmitted via DMA from a transmit buffer to a receive buffer - * using single buffer DMA mode. - * - * Arguments: info pointer to device instance data - * Return Value: true if test passed, otherwise false - */ -static bool mgsl_dma_test( struct mgsl_struct *info ) -{ - unsigned short FifoLevel; - unsigned long phys_addr; - unsigned int FrameSize; - unsigned int i; - char *TmpPtr; - bool rc = true; - unsigned short status=0; - unsigned long EndTime; - unsigned long flags; - MGSL_PARAMS tmp_params; - - /* save current port options */ - memcpy(&tmp_params,&info->params,sizeof(MGSL_PARAMS)); - /* load default port options */ - memcpy(&info->params,&default_params,sizeof(MGSL_PARAMS)); - -#define TESTFRAMESIZE 40 - - spin_lock_irqsave(&info->irq_spinlock,flags); - - /* setup 16C32 for SDLC DMA transfer mode */ - - usc_reset(info); - usc_set_sdlc_mode(info); - usc_enable_loopback(info,1); - - /* Reprogram the RDMR so that the 16C32 does NOT clear the count - * field of the buffer entry after fetching buffer address. This - * way we can detect a DMA failure for a DMA read (which should be - * non-destructive to system memory) before we try and write to - * memory (where a failure could corrupt system memory). - */ - - /* Receive DMA mode Register (RDMR) - * - * <15..14> 11 DMA mode = Linked List Buffer mode - * <13> 1 RSBinA/L = store Rx status Block in List entry - * <12> 0 1 = Clear count of List Entry after fetching - * <11..10> 00 Address mode = Increment - * <9> 1 Terminate Buffer on RxBound - * <8> 0 Bus Width = 16bits - * <7..0> ? status Bits (write as 0s) - * - * 1110 0010 0000 0000 = 0xe200 - */ - - usc_OutDmaReg( info, RDMR, 0xe200 ); - - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - - /* SETUP TRANSMIT AND RECEIVE DMA BUFFERS */ - - FrameSize = TESTFRAMESIZE; - - /* setup 1st transmit buffer entry: */ - /* with frame size and transmit control word */ - - info->tx_buffer_list[0].count = FrameSize; - info->tx_buffer_list[0].rcc = FrameSize; - info->tx_buffer_list[0].status = 0x4000; - - /* build a transmit frame in 1st transmit DMA buffer */ - - TmpPtr = info->tx_buffer_list[0].virt_addr; - for (i = 0; i < FrameSize; i++ ) - *TmpPtr++ = i; - - /* setup 1st receive buffer entry: */ - /* clear status, set max receive buffer size */ - - info->rx_buffer_list[0].status = 0; - info->rx_buffer_list[0].count = FrameSize + 4; - - /* zero out the 1st receive buffer */ - - memset( info->rx_buffer_list[0].virt_addr, 0, FrameSize + 4 ); - - /* Set count field of next buffer entries to prevent */ - /* 16C32 from using buffers after the 1st one. */ - - info->tx_buffer_list[1].count = 0; - info->rx_buffer_list[1].count = 0; - - - /***************************/ - /* Program 16C32 receiver. */ - /***************************/ - - spin_lock_irqsave(&info->irq_spinlock,flags); - - /* setup DMA transfers */ - usc_RTCmd( info, RTCmd_PurgeRxFifo ); - - /* program 16C32 receiver with physical address of 1st DMA buffer entry */ - phys_addr = info->rx_buffer_list[0].phys_entry; - usc_OutDmaReg( info, NRARL, (unsigned short)phys_addr ); - usc_OutDmaReg( info, NRARU, (unsigned short)(phys_addr >> 16) ); - - /* Clear the Rx DMA status bits (read RDMR) and start channel */ - usc_InDmaReg( info, RDMR ); - usc_DmaCmd( info, DmaCmd_InitRxChannel ); - - /* Enable Receiver (RMR <1..0> = 10) */ - usc_OutReg( info, RMR, (unsigned short)((usc_InReg(info, RMR) & 0xfffc) | 0x0002) ); - - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - - /*************************************************************/ - /* WAIT FOR RECEIVER TO DMA ALL PARAMETERS FROM BUFFER ENTRY */ - /*************************************************************/ - - /* Wait 100ms for interrupt. */ - EndTime = jiffies + msecs_to_jiffies(100); - - for(;;) { - if (time_after(jiffies, EndTime)) { - rc = false; - break; - } - - spin_lock_irqsave(&info->irq_spinlock,flags); - status = usc_InDmaReg( info, RDMR ); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - if ( !(status & BIT4) && (status & BIT5) ) { - /* INITG (BIT 4) is inactive (no entry read in progress) AND */ - /* BUSY (BIT 5) is active (channel still active). */ - /* This means the buffer entry read has completed. */ - break; - } - } - - - /******************************/ - /* Program 16C32 transmitter. */ - /******************************/ - - spin_lock_irqsave(&info->irq_spinlock,flags); - - /* Program the Transmit Character Length Register (TCLR) */ - /* and clear FIFO (TCC is loaded with TCLR on FIFO clear) */ - - usc_OutReg( info, TCLR, (unsigned short)info->tx_buffer_list[0].count ); - usc_RTCmd( info, RTCmd_PurgeTxFifo ); - - /* Program the address of the 1st DMA Buffer Entry in linked list */ - - phys_addr = info->tx_buffer_list[0].phys_entry; - usc_OutDmaReg( info, NTARL, (unsigned short)phys_addr ); - usc_OutDmaReg( info, NTARU, (unsigned short)(phys_addr >> 16) ); - - /* unlatch Tx status bits, and start transmit channel. */ - - usc_OutReg( info, TCSR, (unsigned short)(( usc_InReg(info, TCSR) & 0x0f00) | 0xfa) ); - usc_DmaCmd( info, DmaCmd_InitTxChannel ); - - /* wait for DMA controller to fill transmit FIFO */ - - usc_TCmd( info, TCmd_SelectTicrTxFifostatus ); - - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - - /**********************************/ - /* WAIT FOR TRANSMIT FIFO TO FILL */ - /**********************************/ - - /* Wait 100ms */ - EndTime = jiffies + msecs_to_jiffies(100); - - for(;;) { - if (time_after(jiffies, EndTime)) { - rc = false; - break; - } - - spin_lock_irqsave(&info->irq_spinlock,flags); - FifoLevel = usc_InReg(info, TICR) >> 8; - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - if ( FifoLevel < 16 ) - break; - else - if ( FrameSize < 32 ) { - /* This frame is smaller than the entire transmit FIFO */ - /* so wait for the entire frame to be loaded. */ - if ( FifoLevel <= (32 - FrameSize) ) - break; - } - } - - - if ( rc ) - { - /* Enable 16C32 transmitter. */ - - spin_lock_irqsave(&info->irq_spinlock,flags); - - /* Transmit mode Register (TMR), <1..0> = 10, Enable Transmitter */ - usc_TCmd( info, TCmd_SendFrame ); - usc_OutReg( info, TMR, (unsigned short)((usc_InReg(info, TMR) & 0xfffc) | 0x0002) ); - - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - - /******************************/ - /* WAIT FOR TRANSMIT COMPLETE */ - /******************************/ - - /* Wait 100ms */ - EndTime = jiffies + msecs_to_jiffies(100); - - /* While timer not expired wait for transmit complete */ - - spin_lock_irqsave(&info->irq_spinlock,flags); - status = usc_InReg( info, TCSR ); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - while ( !(status & (BIT6+BIT5+BIT4+BIT2+BIT1)) ) { - if (time_after(jiffies, EndTime)) { - rc = false; - break; - } - - spin_lock_irqsave(&info->irq_spinlock,flags); - status = usc_InReg( info, TCSR ); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - } - } - - - if ( rc ){ - /* CHECK FOR TRANSMIT ERRORS */ - if ( status & (BIT5 + BIT1) ) - rc = false; - } - - if ( rc ) { - /* WAIT FOR RECEIVE COMPLETE */ - - /* Wait 100ms */ - EndTime = jiffies + msecs_to_jiffies(100); - - /* Wait for 16C32 to write receive status to buffer entry. */ - status=info->rx_buffer_list[0].status; - while ( status == 0 ) { - if (time_after(jiffies, EndTime)) { - rc = false; - break; - } - status=info->rx_buffer_list[0].status; - } - } - - - if ( rc ) { - /* CHECK FOR RECEIVE ERRORS */ - status = info->rx_buffer_list[0].status; - - if ( status & (BIT8 + BIT3 + BIT1) ) { - /* receive error has occurred */ - rc = false; - } else { - if ( memcmp( info->tx_buffer_list[0].virt_addr , - info->rx_buffer_list[0].virt_addr, FrameSize ) ){ - rc = false; - } - } - } - - spin_lock_irqsave(&info->irq_spinlock,flags); - usc_reset( info ); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - /* restore current port options */ - memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS)); - - return rc; - -} /* end of mgsl_dma_test() */ - -/* mgsl_adapter_test() - * - * Perform the register, IRQ, and DMA tests for the 16C32. - * - * Arguments: info pointer to device instance data - * Return Value: 0 if success, otherwise -ENODEV - */ -static int mgsl_adapter_test( struct mgsl_struct *info ) -{ - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):Testing device %s\n", - __FILE__,__LINE__,info->device_name ); - - if ( !mgsl_register_test( info ) ) { - info->init_error = DiagStatus_AddressFailure; - printk( "%s(%d):Register test failure for device %s Addr=%04X\n", - __FILE__,__LINE__,info->device_name, (unsigned short)(info->io_base) ); - return -ENODEV; - } - - if ( !mgsl_irq_test( info ) ) { - info->init_error = DiagStatus_IrqFailure; - printk( "%s(%d):Interrupt test failure for device %s IRQ=%d\n", - __FILE__,__LINE__,info->device_name, (unsigned short)(info->irq_level) ); - return -ENODEV; - } - - if ( !mgsl_dma_test( info ) ) { - info->init_error = DiagStatus_DmaFailure; - printk( "%s(%d):DMA test failure for device %s DMA=%d\n", - __FILE__,__LINE__,info->device_name, (unsigned short)(info->dma_level) ); - return -ENODEV; - } - - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):device %s passed diagnostics\n", - __FILE__,__LINE__,info->device_name ); - - return 0; - -} /* end of mgsl_adapter_test() */ - -/* mgsl_memory_test() - * - * Test the shared memory on a PCI adapter. - * - * Arguments: info pointer to device instance data - * Return Value: true if test passed, otherwise false - */ -static bool mgsl_memory_test( struct mgsl_struct *info ) -{ - static unsigned long BitPatterns[] = - { 0x0, 0x55555555, 0xaaaaaaaa, 0x66666666, 0x99999999, 0xffffffff, 0x12345678 }; - unsigned long Patterncount = ARRAY_SIZE(BitPatterns); - unsigned long i; - unsigned long TestLimit = SHARED_MEM_ADDRESS_SIZE/sizeof(unsigned long); - unsigned long * TestAddr; - - if ( info->bus_type != MGSL_BUS_TYPE_PCI ) - return true; - - TestAddr = (unsigned long *)info->memory_base; - - /* Test data lines with test pattern at one location. */ - - for ( i = 0 ; i < Patterncount ; i++ ) { - *TestAddr = BitPatterns[i]; - if ( *TestAddr != BitPatterns[i] ) - return false; - } - - /* Test address lines with incrementing pattern over */ - /* entire address range. */ - - for ( i = 0 ; i < TestLimit ; i++ ) { - *TestAddr = i * 4; - TestAddr++; - } - - TestAddr = (unsigned long *)info->memory_base; - - for ( i = 0 ; i < TestLimit ; i++ ) { - if ( *TestAddr != i * 4 ) - return false; - TestAddr++; - } - - memset( info->memory_base, 0, SHARED_MEM_ADDRESS_SIZE ); - - return true; - -} /* End Of mgsl_memory_test() */ - - -/* mgsl_load_pci_memory() - * - * Load a large block of data into the PCI shared memory. - * Use this instead of memcpy() or memmove() to move data - * into the PCI shared memory. - * - * Notes: - * - * This function prevents the PCI9050 interface chip from hogging - * the adapter local bus, which can starve the 16C32 by preventing - * 16C32 bus master cycles. - * - * The PCI9050 documentation says that the 9050 will always release - * control of the local bus after completing the current read - * or write operation. - * - * It appears that as long as the PCI9050 write FIFO is full, the - * PCI9050 treats all of the writes as a single burst transaction - * and will not release the bus. This causes DMA latency problems - * at high speeds when copying large data blocks to the shared - * memory. - * - * This function in effect, breaks the a large shared memory write - * into multiple transations by interleaving a shared memory read - * which will flush the write FIFO and 'complete' the write - * transation. This allows any pending DMA request to gain control - * of the local bus in a timely fasion. - * - * Arguments: - * - * TargetPtr pointer to target address in PCI shared memory - * SourcePtr pointer to source buffer for data - * count count in bytes of data to copy - * - * Return Value: None - */ -static void mgsl_load_pci_memory( char* TargetPtr, const char* SourcePtr, - unsigned short count ) -{ - /* 16 32-bit writes @ 60ns each = 960ns max latency on local bus */ -#define PCI_LOAD_INTERVAL 64 - - unsigned short Intervalcount = count / PCI_LOAD_INTERVAL; - unsigned short Index; - unsigned long Dummy; - - for ( Index = 0 ; Index < Intervalcount ; Index++ ) - { - memcpy(TargetPtr, SourcePtr, PCI_LOAD_INTERVAL); - Dummy = *((volatile unsigned long *)TargetPtr); - TargetPtr += PCI_LOAD_INTERVAL; - SourcePtr += PCI_LOAD_INTERVAL; - } - - memcpy( TargetPtr, SourcePtr, count % PCI_LOAD_INTERVAL ); - -} /* End Of mgsl_load_pci_memory() */ - -static void mgsl_trace_block(struct mgsl_struct *info,const char* data, int count, int xmit) -{ - int i; - int linecount; - if (xmit) - printk("%s tx data:\n",info->device_name); - else - printk("%s rx data:\n",info->device_name); - - while(count) { - if (count > 16) - linecount = 16; - else - linecount = count; - - for(i=0;i=040 && data[i]<=0176) - printk("%c",data[i]); - else - printk("."); - } - printk("\n"); - - data += linecount; - count -= linecount; - } -} /* end of mgsl_trace_block() */ - -/* mgsl_tx_timeout() - * - * called when HDLC frame times out - * update stats and do tx completion processing - * - * Arguments: context pointer to device instance data - * Return Value: None - */ -static void mgsl_tx_timeout(unsigned long context) -{ - struct mgsl_struct *info = (struct mgsl_struct*)context; - unsigned long flags; - - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):mgsl_tx_timeout(%s)\n", - __FILE__,__LINE__,info->device_name); - if(info->tx_active && - (info->params.mode == MGSL_MODE_HDLC || - info->params.mode == MGSL_MODE_RAW) ) { - info->icount.txtimeout++; - } - spin_lock_irqsave(&info->irq_spinlock,flags); - info->tx_active = false; - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - - if ( info->params.flags & HDLC_FLAG_HDLC_LOOPMODE ) - usc_loopmode_cancel_transmit( info ); - - spin_unlock_irqrestore(&info->irq_spinlock,flags); - -#if SYNCLINK_GENERIC_HDLC - if (info->netcount) - hdlcdev_tx_done(info); - else -#endif - mgsl_bh_transmit(info); - -} /* end of mgsl_tx_timeout() */ - -/* signal that there are no more frames to send, so that - * line is 'released' by echoing RxD to TxD when current - * transmission is complete (or immediately if no tx in progress). - */ -static int mgsl_loopmode_send_done( struct mgsl_struct * info ) -{ - unsigned long flags; - - spin_lock_irqsave(&info->irq_spinlock,flags); - if (info->params.flags & HDLC_FLAG_HDLC_LOOPMODE) { - if (info->tx_active) - info->loopmode_send_done_requested = true; - else - usc_loopmode_send_done(info); - } - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - return 0; -} - -/* release the line by echoing RxD to TxD - * upon completion of a transmit frame - */ -static void usc_loopmode_send_done( struct mgsl_struct * info ) -{ - info->loopmode_send_done_requested = false; - /* clear CMR:13 to 0 to start echoing RxData to TxData */ - info->cmr_value &= ~BIT13; - usc_OutReg(info, CMR, info->cmr_value); -} - -/* abort a transmit in progress while in HDLC LoopMode - */ -static void usc_loopmode_cancel_transmit( struct mgsl_struct * info ) -{ - /* reset tx dma channel and purge TxFifo */ - usc_RTCmd( info, RTCmd_PurgeTxFifo ); - usc_DmaCmd( info, DmaCmd_ResetTxChannel ); - usc_loopmode_send_done( info ); -} - -/* for HDLC/SDLC LoopMode, setting CMR:13 after the transmitter is enabled - * is an Insert Into Loop action. Upon receipt of a GoAhead sequence (RxAbort) - * we must clear CMR:13 to begin repeating TxData to RxData - */ -static void usc_loopmode_insert_request( struct mgsl_struct * info ) -{ - info->loopmode_insert_requested = true; - - /* enable RxAbort irq. On next RxAbort, clear CMR:13 to - * begin repeating TxData on RxData (complete insertion) - */ - usc_OutReg( info, RICR, - (usc_InReg( info, RICR ) | RXSTATUS_ABORT_RECEIVED ) ); - - /* set CMR:13 to insert into loop on next GoAhead (RxAbort) */ - info->cmr_value |= BIT13; - usc_OutReg(info, CMR, info->cmr_value); -} - -/* return 1 if station is inserted into the loop, otherwise 0 - */ -static int usc_loopmode_active( struct mgsl_struct * info) -{ - return usc_InReg( info, CCSR ) & BIT7 ? 1 : 0 ; -} - -#if SYNCLINK_GENERIC_HDLC - -/** - * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) - * set encoding and frame check sequence (FCS) options - * - * dev pointer to network device structure - * encoding serial encoding setting - * parity FCS setting - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_attach(struct net_device *dev, unsigned short encoding, - unsigned short parity) -{ - struct mgsl_struct *info = dev_to_port(dev); - unsigned char new_encoding; - unsigned short new_crctype; - - /* return error if TTY interface open */ - if (info->port.count) - return -EBUSY; - - switch (encoding) - { - case ENCODING_NRZ: new_encoding = HDLC_ENCODING_NRZ; break; - case ENCODING_NRZI: new_encoding = HDLC_ENCODING_NRZI_SPACE; break; - case ENCODING_FM_MARK: new_encoding = HDLC_ENCODING_BIPHASE_MARK; break; - case ENCODING_FM_SPACE: new_encoding = HDLC_ENCODING_BIPHASE_SPACE; break; - case ENCODING_MANCHESTER: new_encoding = HDLC_ENCODING_BIPHASE_LEVEL; break; - default: return -EINVAL; - } - - switch (parity) - { - case PARITY_NONE: new_crctype = HDLC_CRC_NONE; break; - case PARITY_CRC16_PR1_CCITT: new_crctype = HDLC_CRC_16_CCITT; break; - case PARITY_CRC32_PR1_CCITT: new_crctype = HDLC_CRC_32_CCITT; break; - default: return -EINVAL; - } - - info->params.encoding = new_encoding; - info->params.crc_type = new_crctype; - - /* if network interface up, reprogram hardware */ - if (info->netcount) - mgsl_program_hw(info); - - return 0; -} - -/** - * called by generic HDLC layer to send frame - * - * skb socket buffer containing HDLC frame - * dev pointer to network device structure - */ -static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb, - struct net_device *dev) -{ - struct mgsl_struct *info = dev_to_port(dev); - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk(KERN_INFO "%s:hdlc_xmit(%s)\n",__FILE__,dev->name); - - /* stop sending until this frame completes */ - netif_stop_queue(dev); - - /* copy data to device buffers */ - info->xmit_cnt = skb->len; - mgsl_load_tx_dma_buffer(info, skb->data, skb->len); - - /* update network statistics */ - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - - /* done with socket buffer, so free it */ - dev_kfree_skb(skb); - - /* save start time for transmit timeout detection */ - dev->trans_start = jiffies; - - /* start hardware transmitter if necessary */ - spin_lock_irqsave(&info->irq_spinlock,flags); - if (!info->tx_active) - usc_start_transmitter(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - return NETDEV_TX_OK; -} - -/** - * called by network layer when interface enabled - * claim resources and initialize hardware - * - * dev pointer to network device structure - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_open(struct net_device *dev) -{ - struct mgsl_struct *info = dev_to_port(dev); - int rc; - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s:hdlcdev_open(%s)\n",__FILE__,dev->name); - - /* generic HDLC layer open processing */ - if ((rc = hdlc_open(dev))) - return rc; - - /* arbitrate between network and tty opens */ - spin_lock_irqsave(&info->netlock, flags); - if (info->port.count != 0 || info->netcount != 0) { - printk(KERN_WARNING "%s: hdlc_open returning busy\n", dev->name); - spin_unlock_irqrestore(&info->netlock, flags); - return -EBUSY; - } - info->netcount=1; - spin_unlock_irqrestore(&info->netlock, flags); - - /* claim resources and init adapter */ - if ((rc = startup(info)) != 0) { - spin_lock_irqsave(&info->netlock, flags); - info->netcount=0; - spin_unlock_irqrestore(&info->netlock, flags); - return rc; - } - - /* assert DTR and RTS, apply hardware settings */ - info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; - mgsl_program_hw(info); - - /* enable network layer transmit */ - dev->trans_start = jiffies; - netif_start_queue(dev); - - /* inform generic HDLC layer of current DCD status */ - spin_lock_irqsave(&info->irq_spinlock, flags); - usc_get_serial_signals(info); - spin_unlock_irqrestore(&info->irq_spinlock, flags); - if (info->serial_signals & SerialSignal_DCD) - netif_carrier_on(dev); - else - netif_carrier_off(dev); - return 0; -} - -/** - * called by network layer when interface is disabled - * shutdown hardware and release resources - * - * dev pointer to network device structure - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_close(struct net_device *dev) -{ - struct mgsl_struct *info = dev_to_port(dev); - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s:hdlcdev_close(%s)\n",__FILE__,dev->name); - - netif_stop_queue(dev); - - /* shutdown adapter and release resources */ - shutdown(info); - - hdlc_close(dev); - - spin_lock_irqsave(&info->netlock, flags); - info->netcount=0; - spin_unlock_irqrestore(&info->netlock, flags); - - return 0; -} - -/** - * called by network layer to process IOCTL call to network device - * - * dev pointer to network device structure - * ifr pointer to network interface request structure - * cmd IOCTL command code - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - const size_t size = sizeof(sync_serial_settings); - sync_serial_settings new_line; - sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; - struct mgsl_struct *info = dev_to_port(dev); - unsigned int flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s:hdlcdev_ioctl(%s)\n",__FILE__,dev->name); - - /* return error if TTY interface open */ - if (info->port.count) - return -EBUSY; - - if (cmd != SIOCWANDEV) - return hdlc_ioctl(dev, ifr, cmd); - - switch(ifr->ifr_settings.type) { - case IF_GET_IFACE: /* return current sync_serial_settings */ - - ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL; - if (ifr->ifr_settings.size < size) { - ifr->ifr_settings.size = size; /* data size wanted */ - return -ENOBUFS; - } - - flags = info->params.flags & (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | - HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | - HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | - HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); - - switch (flags){ - case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN): new_line.clock_type = CLOCK_EXT; break; - case (HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG): new_line.clock_type = CLOCK_INT; break; - case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG): new_line.clock_type = CLOCK_TXINT; break; - case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN): new_line.clock_type = CLOCK_TXFROMRX; break; - default: new_line.clock_type = CLOCK_DEFAULT; - } - - new_line.clock_rate = info->params.clock_speed; - new_line.loopback = info->params.loopback ? 1:0; - - if (copy_to_user(line, &new_line, size)) - return -EFAULT; - return 0; - - case IF_IFACE_SYNC_SERIAL: /* set sync_serial_settings */ - - if(!capable(CAP_NET_ADMIN)) - return -EPERM; - if (copy_from_user(&new_line, line, size)) - return -EFAULT; - - switch (new_line.clock_type) - { - case CLOCK_EXT: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN; break; - case CLOCK_TXFROMRX: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN; break; - case CLOCK_INT: flags = HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG; break; - case CLOCK_TXINT: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG; break; - case CLOCK_DEFAULT: flags = info->params.flags & - (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | - HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | - HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | - HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); break; - default: return -EINVAL; - } - - if (new_line.loopback != 0 && new_line.loopback != 1) - return -EINVAL; - - info->params.flags &= ~(HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | - HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | - HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | - HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); - info->params.flags |= flags; - - info->params.loopback = new_line.loopback; - - if (flags & (HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG)) - info->params.clock_speed = new_line.clock_rate; - else - info->params.clock_speed = 0; - - /* if network interface up, reprogram hardware */ - if (info->netcount) - mgsl_program_hw(info); - return 0; - - default: - return hdlc_ioctl(dev, ifr, cmd); - } -} - -/** - * called by network layer when transmit timeout is detected - * - * dev pointer to network device structure - */ -static void hdlcdev_tx_timeout(struct net_device *dev) -{ - struct mgsl_struct *info = dev_to_port(dev); - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("hdlcdev_tx_timeout(%s)\n",dev->name); - - dev->stats.tx_errors++; - dev->stats.tx_aborted_errors++; - - spin_lock_irqsave(&info->irq_spinlock,flags); - usc_stop_transmitter(info); - spin_unlock_irqrestore(&info->irq_spinlock,flags); - - netif_wake_queue(dev); -} - -/** - * called by device driver when transmit completes - * reenable network layer transmit if stopped - * - * info pointer to device instance information - */ -static void hdlcdev_tx_done(struct mgsl_struct *info) -{ - if (netif_queue_stopped(info->netdev)) - netif_wake_queue(info->netdev); -} - -/** - * called by device driver when frame received - * pass frame to network layer - * - * info pointer to device instance information - * buf pointer to buffer contianing frame data - * size count of data bytes in buf - */ -static void hdlcdev_rx(struct mgsl_struct *info, char *buf, int size) -{ - struct sk_buff *skb = dev_alloc_skb(size); - struct net_device *dev = info->netdev; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("hdlcdev_rx(%s)\n", dev->name); - - if (skb == NULL) { - printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n", - dev->name); - dev->stats.rx_dropped++; - return; - } - - memcpy(skb_put(skb, size), buf, size); - - skb->protocol = hdlc_type_trans(skb, dev); - - dev->stats.rx_packets++; - dev->stats.rx_bytes += size; - - netif_rx(skb); -} - -static const struct net_device_ops hdlcdev_ops = { - .ndo_open = hdlcdev_open, - .ndo_stop = hdlcdev_close, - .ndo_change_mtu = hdlc_change_mtu, - .ndo_start_xmit = hdlc_start_xmit, - .ndo_do_ioctl = hdlcdev_ioctl, - .ndo_tx_timeout = hdlcdev_tx_timeout, -}; - -/** - * called by device driver when adding device instance - * do generic HDLC initialization - * - * info pointer to device instance information - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_init(struct mgsl_struct *info) -{ - int rc; - struct net_device *dev; - hdlc_device *hdlc; - - /* allocate and initialize network and HDLC layer objects */ - - if (!(dev = alloc_hdlcdev(info))) { - printk(KERN_ERR "%s:hdlc device allocation failure\n",__FILE__); - return -ENOMEM; - } - - /* for network layer reporting purposes only */ - dev->base_addr = info->io_base; - dev->irq = info->irq_level; - dev->dma = info->dma_level; - - /* network layer callbacks and settings */ - dev->netdev_ops = &hdlcdev_ops; - dev->watchdog_timeo = 10 * HZ; - dev->tx_queue_len = 50; - - /* generic HDLC layer callbacks and settings */ - hdlc = dev_to_hdlc(dev); - hdlc->attach = hdlcdev_attach; - hdlc->xmit = hdlcdev_xmit; - - /* register objects with HDLC layer */ - if ((rc = register_hdlc_device(dev))) { - printk(KERN_WARNING "%s:unable to register hdlc device\n",__FILE__); - free_netdev(dev); - return rc; - } - - info->netdev = dev; - return 0; -} - -/** - * called by device driver when removing device instance - * do generic HDLC cleanup - * - * info pointer to device instance information - */ -static void hdlcdev_exit(struct mgsl_struct *info) -{ - unregister_hdlc_device(info->netdev); - free_netdev(info->netdev); - info->netdev = NULL; -} - -#endif /* CONFIG_HDLC */ - - -static int __devinit synclink_init_one (struct pci_dev *dev, - const struct pci_device_id *ent) -{ - struct mgsl_struct *info; - - if (pci_enable_device(dev)) { - printk("error enabling pci device %p\n", dev); - return -EIO; - } - - if (!(info = mgsl_allocate_device())) { - printk("can't allocate device instance data.\n"); - return -EIO; - } - - /* Copy user configuration info to device instance data */ - - info->io_base = pci_resource_start(dev, 2); - info->irq_level = dev->irq; - info->phys_memory_base = pci_resource_start(dev, 3); - - /* Because veremap only works on page boundaries we must map - * a larger area than is actually implemented for the LCR - * memory range. We map a full page starting at the page boundary. - */ - info->phys_lcr_base = pci_resource_start(dev, 0); - info->lcr_offset = info->phys_lcr_base & (PAGE_SIZE-1); - info->phys_lcr_base &= ~(PAGE_SIZE-1); - - info->bus_type = MGSL_BUS_TYPE_PCI; - info->io_addr_size = 8; - info->irq_flags = IRQF_SHARED; - - if (dev->device == 0x0210) { - /* Version 1 PCI9030 based universal PCI adapter */ - info->misc_ctrl_value = 0x007c4080; - info->hw_version = 1; - } else { - /* Version 0 PCI9050 based 5V PCI adapter - * A PCI9050 bug prevents reading LCR registers if - * LCR base address bit 7 is set. Maintain shadow - * value so we can write to LCR misc control reg. - */ - info->misc_ctrl_value = 0x087e4546; - info->hw_version = 0; - } - - mgsl_add_device(info); - - return 0; -} - -static void __devexit synclink_remove_one (struct pci_dev *dev) -{ -} - diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c deleted file mode 100644 index a35dd549a008..000000000000 --- a/drivers/char/synclink_gt.c +++ /dev/null @@ -1,5161 +0,0 @@ -/* - * Device driver for Microgate SyncLink GT serial adapters. - * - * written by Paul Fulghum for Microgate Corporation - * paulkf@microgate.com - * - * Microgate and SyncLink are trademarks of Microgate Corporation - * - * This code is released under the GNU General Public License (GPL) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * DEBUG OUTPUT DEFINITIONS - * - * uncomment lines below to enable specific types of debug output - * - * DBGINFO information - most verbose output - * DBGERR serious errors - * DBGBH bottom half service routine debugging - * DBGISR interrupt service routine debugging - * DBGDATA output receive and transmit data - * DBGTBUF output transmit DMA buffers and registers - * DBGRBUF output receive DMA buffers and registers - */ - -#define DBGINFO(fmt) if (debug_level >= DEBUG_LEVEL_INFO) printk fmt -#define DBGERR(fmt) if (debug_level >= DEBUG_LEVEL_ERROR) printk fmt -#define DBGBH(fmt) if (debug_level >= DEBUG_LEVEL_BH) printk fmt -#define DBGISR(fmt) if (debug_level >= DEBUG_LEVEL_ISR) printk fmt -#define DBGDATA(info, buf, size, label) if (debug_level >= DEBUG_LEVEL_DATA) trace_block((info), (buf), (size), (label)) -/*#define DBGTBUF(info) dump_tbufs(info)*/ -/*#define DBGRBUF(info) dump_rbufs(info)*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_GT_MODULE)) -#define SYNCLINK_GENERIC_HDLC 1 -#else -#define SYNCLINK_GENERIC_HDLC 0 -#endif - -/* - * module identification - */ -static char *driver_name = "SyncLink GT"; -static char *tty_driver_name = "synclink_gt"; -static char *tty_dev_prefix = "ttySLG"; -MODULE_LICENSE("GPL"); -#define MGSL_MAGIC 0x5401 -#define MAX_DEVICES 32 - -static struct pci_device_id pci_table[] = { - {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, - {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT2_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, - {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT4_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, - {PCI_VENDOR_ID_MICROGATE, SYNCLINK_AC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, - {0,}, /* terminate list */ -}; -MODULE_DEVICE_TABLE(pci, pci_table); - -static int init_one(struct pci_dev *dev,const struct pci_device_id *ent); -static void remove_one(struct pci_dev *dev); -static struct pci_driver pci_driver = { - .name = "synclink_gt", - .id_table = pci_table, - .probe = init_one, - .remove = __devexit_p(remove_one), -}; - -static bool pci_registered; - -/* - * module configuration and status - */ -static struct slgt_info *slgt_device_list; -static int slgt_device_count; - -static int ttymajor; -static int debug_level; -static int maxframe[MAX_DEVICES]; - -module_param(ttymajor, int, 0); -module_param(debug_level, int, 0); -module_param_array(maxframe, int, NULL, 0); - -MODULE_PARM_DESC(ttymajor, "TTY major device number override: 0=auto assigned"); -MODULE_PARM_DESC(debug_level, "Debug syslog output: 0=disabled, 1 to 5=increasing detail"); -MODULE_PARM_DESC(maxframe, "Maximum frame size used by device (4096 to 65535)"); - -/* - * tty support and callbacks - */ -static struct tty_driver *serial_driver; - -static int open(struct tty_struct *tty, struct file * filp); -static void close(struct tty_struct *tty, struct file * filp); -static void hangup(struct tty_struct *tty); -static void set_termios(struct tty_struct *tty, struct ktermios *old_termios); - -static int write(struct tty_struct *tty, const unsigned char *buf, int count); -static int put_char(struct tty_struct *tty, unsigned char ch); -static void send_xchar(struct tty_struct *tty, char ch); -static void wait_until_sent(struct tty_struct *tty, int timeout); -static int write_room(struct tty_struct *tty); -static void flush_chars(struct tty_struct *tty); -static void flush_buffer(struct tty_struct *tty); -static void tx_hold(struct tty_struct *tty); -static void tx_release(struct tty_struct *tty); - -static int ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); -static int chars_in_buffer(struct tty_struct *tty); -static void throttle(struct tty_struct * tty); -static void unthrottle(struct tty_struct * tty); -static int set_break(struct tty_struct *tty, int break_state); - -/* - * generic HDLC support and callbacks - */ -#if SYNCLINK_GENERIC_HDLC -#define dev_to_port(D) (dev_to_hdlc(D)->priv) -static void hdlcdev_tx_done(struct slgt_info *info); -static void hdlcdev_rx(struct slgt_info *info, char *buf, int size); -static int hdlcdev_init(struct slgt_info *info); -static void hdlcdev_exit(struct slgt_info *info); -#endif - - -/* - * device specific structures, macros and functions - */ - -#define SLGT_MAX_PORTS 4 -#define SLGT_REG_SIZE 256 - -/* - * conditional wait facility - */ -struct cond_wait { - struct cond_wait *next; - wait_queue_head_t q; - wait_queue_t wait; - unsigned int data; -}; -static void init_cond_wait(struct cond_wait *w, unsigned int data); -static void add_cond_wait(struct cond_wait **head, struct cond_wait *w); -static void remove_cond_wait(struct cond_wait **head, struct cond_wait *w); -static void flush_cond_wait(struct cond_wait **head); - -/* - * DMA buffer descriptor and access macros - */ -struct slgt_desc -{ - __le16 count; - __le16 status; - __le32 pbuf; /* physical address of data buffer */ - __le32 next; /* physical address of next descriptor */ - - /* driver book keeping */ - char *buf; /* virtual address of data buffer */ - unsigned int pdesc; /* physical address of this descriptor */ - dma_addr_t buf_dma_addr; - unsigned short buf_count; -}; - -#define set_desc_buffer(a,b) (a).pbuf = cpu_to_le32((unsigned int)(b)) -#define set_desc_next(a,b) (a).next = cpu_to_le32((unsigned int)(b)) -#define set_desc_count(a,b)(a).count = cpu_to_le16((unsigned short)(b)) -#define set_desc_eof(a,b) (a).status = cpu_to_le16((b) ? (le16_to_cpu((a).status) | BIT0) : (le16_to_cpu((a).status) & ~BIT0)) -#define set_desc_status(a, b) (a).status = cpu_to_le16((unsigned short)(b)) -#define desc_count(a) (le16_to_cpu((a).count)) -#define desc_status(a) (le16_to_cpu((a).status)) -#define desc_complete(a) (le16_to_cpu((a).status) & BIT15) -#define desc_eof(a) (le16_to_cpu((a).status) & BIT2) -#define desc_crc_error(a) (le16_to_cpu((a).status) & BIT1) -#define desc_abort(a) (le16_to_cpu((a).status) & BIT0) -#define desc_residue(a) ((le16_to_cpu((a).status) & 0x38) >> 3) - -struct _input_signal_events { - int ri_up; - int ri_down; - int dsr_up; - int dsr_down; - int dcd_up; - int dcd_down; - int cts_up; - int cts_down; -}; - -/* - * device instance data structure - */ -struct slgt_info { - void *if_ptr; /* General purpose pointer (used by SPPP) */ - struct tty_port port; - - struct slgt_info *next_device; /* device list link */ - - int magic; - - char device_name[25]; - struct pci_dev *pdev; - - int port_count; /* count of ports on adapter */ - int adapter_num; /* adapter instance number */ - int port_num; /* port instance number */ - - /* array of pointers to port contexts on this adapter */ - struct slgt_info *port_array[SLGT_MAX_PORTS]; - - int line; /* tty line instance number */ - - struct mgsl_icount icount; - - int timeout; - int x_char; /* xon/xoff character */ - unsigned int read_status_mask; - unsigned int ignore_status_mask; - - wait_queue_head_t status_event_wait_q; - wait_queue_head_t event_wait_q; - struct timer_list tx_timer; - struct timer_list rx_timer; - - unsigned int gpio_present; - struct cond_wait *gpio_wait_q; - - spinlock_t lock; /* spinlock for synchronizing with ISR */ - - struct work_struct task; - u32 pending_bh; - bool bh_requested; - bool bh_running; - - int isr_overflow; - bool irq_requested; /* true if IRQ requested */ - bool irq_occurred; /* for diagnostics use */ - - /* device configuration */ - - unsigned int bus_type; - unsigned int irq_level; - unsigned long irq_flags; - - unsigned char __iomem * reg_addr; /* memory mapped registers address */ - u32 phys_reg_addr; - bool reg_addr_requested; - - MGSL_PARAMS params; /* communications parameters */ - u32 idle_mode; - u32 max_frame_size; /* as set by device config */ - - unsigned int rbuf_fill_level; - unsigned int rx_pio; - unsigned int if_mode; - unsigned int base_clock; - unsigned int xsync; - unsigned int xctrl; - - /* device status */ - - bool rx_enabled; - bool rx_restart; - - bool tx_enabled; - bool tx_active; - - unsigned char signals; /* serial signal states */ - int init_error; /* initialization error */ - - unsigned char *tx_buf; - int tx_count; - - char flag_buf[MAX_ASYNC_BUFFER_SIZE]; - char char_buf[MAX_ASYNC_BUFFER_SIZE]; - bool drop_rts_on_tx_done; - struct _input_signal_events input_signal_events; - - int dcd_chkcount; /* check counts to prevent */ - int cts_chkcount; /* too many IRQs if a signal */ - int dsr_chkcount; /* is floating */ - int ri_chkcount; - - char *bufs; /* virtual address of DMA buffer lists */ - dma_addr_t bufs_dma_addr; /* physical address of buffer descriptors */ - - unsigned int rbuf_count; - struct slgt_desc *rbufs; - unsigned int rbuf_current; - unsigned int rbuf_index; - unsigned int rbuf_fill_index; - unsigned short rbuf_fill_count; - - unsigned int tbuf_count; - struct slgt_desc *tbufs; - unsigned int tbuf_current; - unsigned int tbuf_start; - - unsigned char *tmp_rbuf; - unsigned int tmp_rbuf_count; - - /* SPPP/Cisco HDLC device parts */ - - int netcount; - spinlock_t netlock; -#if SYNCLINK_GENERIC_HDLC - struct net_device *netdev; -#endif - -}; - -static MGSL_PARAMS default_params = { - .mode = MGSL_MODE_HDLC, - .loopback = 0, - .flags = HDLC_FLAG_UNDERRUN_ABORT15, - .encoding = HDLC_ENCODING_NRZI_SPACE, - .clock_speed = 0, - .addr_filter = 0xff, - .crc_type = HDLC_CRC_16_CCITT, - .preamble_length = HDLC_PREAMBLE_LENGTH_8BITS, - .preamble = HDLC_PREAMBLE_PATTERN_NONE, - .data_rate = 9600, - .data_bits = 8, - .stop_bits = 1, - .parity = ASYNC_PARITY_NONE -}; - - -#define BH_RECEIVE 1 -#define BH_TRANSMIT 2 -#define BH_STATUS 4 -#define IO_PIN_SHUTDOWN_LIMIT 100 - -#define DMABUFSIZE 256 -#define DESC_LIST_SIZE 4096 - -#define MASK_PARITY BIT1 -#define MASK_FRAMING BIT0 -#define MASK_BREAK BIT14 -#define MASK_OVERRUN BIT4 - -#define GSR 0x00 /* global status */ -#define JCR 0x04 /* JTAG control */ -#define IODR 0x08 /* GPIO direction */ -#define IOER 0x0c /* GPIO interrupt enable */ -#define IOVR 0x10 /* GPIO value */ -#define IOSR 0x14 /* GPIO interrupt status */ -#define TDR 0x80 /* tx data */ -#define RDR 0x80 /* rx data */ -#define TCR 0x82 /* tx control */ -#define TIR 0x84 /* tx idle */ -#define TPR 0x85 /* tx preamble */ -#define RCR 0x86 /* rx control */ -#define VCR 0x88 /* V.24 control */ -#define CCR 0x89 /* clock control */ -#define BDR 0x8a /* baud divisor */ -#define SCR 0x8c /* serial control */ -#define SSR 0x8e /* serial status */ -#define RDCSR 0x90 /* rx DMA control/status */ -#define TDCSR 0x94 /* tx DMA control/status */ -#define RDDAR 0x98 /* rx DMA descriptor address */ -#define TDDAR 0x9c /* tx DMA descriptor address */ -#define XSR 0x40 /* extended sync pattern */ -#define XCR 0x44 /* extended control */ - -#define RXIDLE BIT14 -#define RXBREAK BIT14 -#define IRQ_TXDATA BIT13 -#define IRQ_TXIDLE BIT12 -#define IRQ_TXUNDER BIT11 /* HDLC */ -#define IRQ_RXDATA BIT10 -#define IRQ_RXIDLE BIT9 /* HDLC */ -#define IRQ_RXBREAK BIT9 /* async */ -#define IRQ_RXOVER BIT8 -#define IRQ_DSR BIT7 -#define IRQ_CTS BIT6 -#define IRQ_DCD BIT5 -#define IRQ_RI BIT4 -#define IRQ_ALL 0x3ff0 -#define IRQ_MASTER BIT0 - -#define slgt_irq_on(info, mask) \ - wr_reg16((info), SCR, (unsigned short)(rd_reg16((info), SCR) | (mask))) -#define slgt_irq_off(info, mask) \ - wr_reg16((info), SCR, (unsigned short)(rd_reg16((info), SCR) & ~(mask))) - -static __u8 rd_reg8(struct slgt_info *info, unsigned int addr); -static void wr_reg8(struct slgt_info *info, unsigned int addr, __u8 value); -static __u16 rd_reg16(struct slgt_info *info, unsigned int addr); -static void wr_reg16(struct slgt_info *info, unsigned int addr, __u16 value); -static __u32 rd_reg32(struct slgt_info *info, unsigned int addr); -static void wr_reg32(struct slgt_info *info, unsigned int addr, __u32 value); - -static void msc_set_vcr(struct slgt_info *info); - -static int startup(struct slgt_info *info); -static int block_til_ready(struct tty_struct *tty, struct file * filp,struct slgt_info *info); -static void shutdown(struct slgt_info *info); -static void program_hw(struct slgt_info *info); -static void change_params(struct slgt_info *info); - -static int register_test(struct slgt_info *info); -static int irq_test(struct slgt_info *info); -static int loopback_test(struct slgt_info *info); -static int adapter_test(struct slgt_info *info); - -static void reset_adapter(struct slgt_info *info); -static void reset_port(struct slgt_info *info); -static void async_mode(struct slgt_info *info); -static void sync_mode(struct slgt_info *info); - -static void rx_stop(struct slgt_info *info); -static void rx_start(struct slgt_info *info); -static void reset_rbufs(struct slgt_info *info); -static void free_rbufs(struct slgt_info *info, unsigned int first, unsigned int last); -static void rdma_reset(struct slgt_info *info); -static bool rx_get_frame(struct slgt_info *info); -static bool rx_get_buf(struct slgt_info *info); - -static void tx_start(struct slgt_info *info); -static void tx_stop(struct slgt_info *info); -static void tx_set_idle(struct slgt_info *info); -static unsigned int free_tbuf_count(struct slgt_info *info); -static unsigned int tbuf_bytes(struct slgt_info *info); -static void reset_tbufs(struct slgt_info *info); -static void tdma_reset(struct slgt_info *info); -static bool tx_load(struct slgt_info *info, const char *buf, unsigned int count); - -static void get_signals(struct slgt_info *info); -static void set_signals(struct slgt_info *info); -static void enable_loopback(struct slgt_info *info); -static void set_rate(struct slgt_info *info, u32 data_rate); - -static int bh_action(struct slgt_info *info); -static void bh_handler(struct work_struct *work); -static void bh_transmit(struct slgt_info *info); -static void isr_serial(struct slgt_info *info); -static void isr_rdma(struct slgt_info *info); -static void isr_txeom(struct slgt_info *info, unsigned short status); -static void isr_tdma(struct slgt_info *info); - -static int alloc_dma_bufs(struct slgt_info *info); -static void free_dma_bufs(struct slgt_info *info); -static int alloc_desc(struct slgt_info *info); -static void free_desc(struct slgt_info *info); -static int alloc_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count); -static void free_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count); - -static int alloc_tmp_rbuf(struct slgt_info *info); -static void free_tmp_rbuf(struct slgt_info *info); - -static void tx_timeout(unsigned long context); -static void rx_timeout(unsigned long context); - -/* - * ioctl handlers - */ -static int get_stats(struct slgt_info *info, struct mgsl_icount __user *user_icount); -static int get_params(struct slgt_info *info, MGSL_PARAMS __user *params); -static int set_params(struct slgt_info *info, MGSL_PARAMS __user *params); -static int get_txidle(struct slgt_info *info, int __user *idle_mode); -static int set_txidle(struct slgt_info *info, int idle_mode); -static int tx_enable(struct slgt_info *info, int enable); -static int tx_abort(struct slgt_info *info); -static int rx_enable(struct slgt_info *info, int enable); -static int modem_input_wait(struct slgt_info *info,int arg); -static int wait_mgsl_event(struct slgt_info *info, int __user *mask_ptr); -static int tiocmget(struct tty_struct *tty); -static int tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear); -static int set_break(struct tty_struct *tty, int break_state); -static int get_interface(struct slgt_info *info, int __user *if_mode); -static int set_interface(struct slgt_info *info, int if_mode); -static int set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); -static int get_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); -static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); -static int get_xsync(struct slgt_info *info, int __user *if_mode); -static int set_xsync(struct slgt_info *info, int if_mode); -static int get_xctrl(struct slgt_info *info, int __user *if_mode); -static int set_xctrl(struct slgt_info *info, int if_mode); - -/* - * driver functions - */ -static void add_device(struct slgt_info *info); -static void device_init(int adapter_num, struct pci_dev *pdev); -static int claim_resources(struct slgt_info *info); -static void release_resources(struct slgt_info *info); - -/* - * DEBUG OUTPUT CODE - */ -#ifndef DBGINFO -#define DBGINFO(fmt) -#endif -#ifndef DBGERR -#define DBGERR(fmt) -#endif -#ifndef DBGBH -#define DBGBH(fmt) -#endif -#ifndef DBGISR -#define DBGISR(fmt) -#endif - -#ifdef DBGDATA -static void trace_block(struct slgt_info *info, const char *data, int count, const char *label) -{ - int i; - int linecount; - printk("%s %s data:\n",info->device_name, label); - while(count) { - linecount = (count > 16) ? 16 : count; - for(i=0; i < linecount; i++) - printk("%02X ",(unsigned char)data[i]); - for(;i<17;i++) - printk(" "); - for(i=0;i=040 && data[i]<=0176) - printk("%c",data[i]); - else - printk("."); - } - printk("\n"); - data += linecount; - count -= linecount; - } -} -#else -#define DBGDATA(info, buf, size, label) -#endif - -#ifdef DBGTBUF -static void dump_tbufs(struct slgt_info *info) -{ - int i; - printk("tbuf_current=%d\n", info->tbuf_current); - for (i=0 ; i < info->tbuf_count ; i++) { - printk("%d: count=%04X status=%04X\n", - i, le16_to_cpu(info->tbufs[i].count), le16_to_cpu(info->tbufs[i].status)); - } -} -#else -#define DBGTBUF(info) -#endif - -#ifdef DBGRBUF -static void dump_rbufs(struct slgt_info *info) -{ - int i; - printk("rbuf_current=%d\n", info->rbuf_current); - for (i=0 ; i < info->rbuf_count ; i++) { - printk("%d: count=%04X status=%04X\n", - i, le16_to_cpu(info->rbufs[i].count), le16_to_cpu(info->rbufs[i].status)); - } -} -#else -#define DBGRBUF(info) -#endif - -static inline int sanity_check(struct slgt_info *info, char *devname, const char *name) -{ -#ifdef SANITY_CHECK - if (!info) { - printk("null struct slgt_info for (%s) in %s\n", devname, name); - return 1; - } - if (info->magic != MGSL_MAGIC) { - printk("bad magic number struct slgt_info (%s) in %s\n", devname, name); - return 1; - } -#else - if (!info) - return 1; -#endif - return 0; -} - -/** - * line discipline callback wrappers - * - * The wrappers maintain line discipline references - * while calling into the line discipline. - * - * ldisc_receive_buf - pass receive data to line discipline - */ -static void ldisc_receive_buf(struct tty_struct *tty, - const __u8 *data, char *flags, int count) -{ - struct tty_ldisc *ld; - if (!tty) - return; - ld = tty_ldisc_ref(tty); - if (ld) { - if (ld->ops->receive_buf) - ld->ops->receive_buf(tty, data, flags, count); - tty_ldisc_deref(ld); - } -} - -/* tty callbacks */ - -static int open(struct tty_struct *tty, struct file *filp) -{ - struct slgt_info *info; - int retval, line; - unsigned long flags; - - line = tty->index; - if ((line < 0) || (line >= slgt_device_count)) { - DBGERR(("%s: open with invalid line #%d.\n", driver_name, line)); - return -ENODEV; - } - - info = slgt_device_list; - while(info && info->line != line) - info = info->next_device; - if (sanity_check(info, tty->name, "open")) - return -ENODEV; - if (info->init_error) { - DBGERR(("%s init error=%d\n", info->device_name, info->init_error)); - return -ENODEV; - } - - tty->driver_data = info; - info->port.tty = tty; - - DBGINFO(("%s open, old ref count = %d\n", info->device_name, info->port.count)); - - /* If port is closing, signal caller to try again */ - if (tty_hung_up_p(filp) || info->port.flags & ASYNC_CLOSING){ - if (info->port.flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->port.close_wait); - retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); - goto cleanup; - } - - mutex_lock(&info->port.mutex); - info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; - - spin_lock_irqsave(&info->netlock, flags); - if (info->netcount) { - retval = -EBUSY; - spin_unlock_irqrestore(&info->netlock, flags); - mutex_unlock(&info->port.mutex); - goto cleanup; - } - info->port.count++; - spin_unlock_irqrestore(&info->netlock, flags); - - if (info->port.count == 1) { - /* 1st open on this device, init hardware */ - retval = startup(info); - if (retval < 0) { - mutex_unlock(&info->port.mutex); - goto cleanup; - } - } - mutex_unlock(&info->port.mutex); - retval = block_til_ready(tty, filp, info); - if (retval) { - DBGINFO(("%s block_til_ready rc=%d\n", info->device_name, retval)); - goto cleanup; - } - - retval = 0; - -cleanup: - if (retval) { - if (tty->count == 1) - info->port.tty = NULL; /* tty layer will release tty struct */ - if(info->port.count) - info->port.count--; - } - - DBGINFO(("%s open rc=%d\n", info->device_name, retval)); - return retval; -} - -static void close(struct tty_struct *tty, struct file *filp) -{ - struct slgt_info *info = tty->driver_data; - - if (sanity_check(info, tty->name, "close")) - return; - DBGINFO(("%s close entry, count=%d\n", info->device_name, info->port.count)); - - if (tty_port_close_start(&info->port, tty, filp) == 0) - goto cleanup; - - mutex_lock(&info->port.mutex); - if (info->port.flags & ASYNC_INITIALIZED) - wait_until_sent(tty, info->timeout); - flush_buffer(tty); - tty_ldisc_flush(tty); - - shutdown(info); - mutex_unlock(&info->port.mutex); - - tty_port_close_end(&info->port, tty); - info->port.tty = NULL; -cleanup: - DBGINFO(("%s close exit, count=%d\n", tty->driver->name, info->port.count)); -} - -static void hangup(struct tty_struct *tty) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "hangup")) - return; - DBGINFO(("%s hangup\n", info->device_name)); - - flush_buffer(tty); - - mutex_lock(&info->port.mutex); - shutdown(info); - - spin_lock_irqsave(&info->port.lock, flags); - info->port.count = 0; - info->port.flags &= ~ASYNC_NORMAL_ACTIVE; - info->port.tty = NULL; - spin_unlock_irqrestore(&info->port.lock, flags); - mutex_unlock(&info->port.mutex); - - wake_up_interruptible(&info->port.open_wait); -} - -static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - DBGINFO(("%s set_termios\n", tty->driver->name)); - - change_params(info); - - /* Handle transition to B0 status */ - if (old_termios->c_cflag & CBAUD && - !(tty->termios->c_cflag & CBAUD)) { - info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); - spin_lock_irqsave(&info->lock,flags); - set_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - } - - /* Handle transition away from B0 status */ - if (!(old_termios->c_cflag & CBAUD) && - tty->termios->c_cflag & CBAUD) { - info->signals |= SerialSignal_DTR; - if (!(tty->termios->c_cflag & CRTSCTS) || - !test_bit(TTY_THROTTLED, &tty->flags)) { - info->signals |= SerialSignal_RTS; - } - spin_lock_irqsave(&info->lock,flags); - set_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - } - - /* Handle turning off CRTSCTS */ - if (old_termios->c_cflag & CRTSCTS && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - tx_release(tty); - } -} - -static void update_tx_timer(struct slgt_info *info) -{ - /* - * use worst case speed of 1200bps to calculate transmit timeout - * based on data in buffers (tbuf_bytes) and FIFO (128 bytes) - */ - if (info->params.mode == MGSL_MODE_HDLC) { - int timeout = (tbuf_bytes(info) * 7) + 1000; - mod_timer(&info->tx_timer, jiffies + msecs_to_jiffies(timeout)); - } -} - -static int write(struct tty_struct *tty, - const unsigned char *buf, int count) -{ - int ret = 0; - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "write")) - return -EIO; - - DBGINFO(("%s write count=%d\n", info->device_name, count)); - - if (!info->tx_buf || (count > info->max_frame_size)) - return -EIO; - - if (!count || tty->stopped || tty->hw_stopped) - return 0; - - spin_lock_irqsave(&info->lock, flags); - - if (info->tx_count) { - /* send accumulated data from send_char() */ - if (!tx_load(info, info->tx_buf, info->tx_count)) - goto cleanup; - info->tx_count = 0; - } - - if (tx_load(info, buf, count)) - ret = count; - -cleanup: - spin_unlock_irqrestore(&info->lock, flags); - DBGINFO(("%s write rc=%d\n", info->device_name, ret)); - return ret; -} - -static int put_char(struct tty_struct *tty, unsigned char ch) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - int ret = 0; - - if (sanity_check(info, tty->name, "put_char")) - return 0; - DBGINFO(("%s put_char(%d)\n", info->device_name, ch)); - if (!info->tx_buf) - return 0; - spin_lock_irqsave(&info->lock,flags); - if (info->tx_count < info->max_frame_size) { - info->tx_buf[info->tx_count++] = ch; - ret = 1; - } - spin_unlock_irqrestore(&info->lock,flags); - return ret; -} - -static void send_xchar(struct tty_struct *tty, char ch) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "send_xchar")) - return; - DBGINFO(("%s send_xchar(%d)\n", info->device_name, ch)); - info->x_char = ch; - if (ch) { - spin_lock_irqsave(&info->lock,flags); - if (!info->tx_enabled) - tx_start(info); - spin_unlock_irqrestore(&info->lock,flags); - } -} - -static void wait_until_sent(struct tty_struct *tty, int timeout) -{ - struct slgt_info *info = tty->driver_data; - unsigned long orig_jiffies, char_time; - - if (!info ) - return; - if (sanity_check(info, tty->name, "wait_until_sent")) - return; - DBGINFO(("%s wait_until_sent entry\n", info->device_name)); - if (!(info->port.flags & ASYNC_INITIALIZED)) - goto exit; - - orig_jiffies = jiffies; - - /* Set check interval to 1/5 of estimated time to - * send a character, and make it at least 1. The check - * interval should also be less than the timeout. - * Note: use tight timings here to satisfy the NIST-PCTS. - */ - - if (info->params.data_rate) { - char_time = info->timeout/(32 * 5); - if (!char_time) - char_time++; - } else - char_time = 1; - - if (timeout) - char_time = min_t(unsigned long, char_time, timeout); - - while (info->tx_active) { - msleep_interruptible(jiffies_to_msecs(char_time)); - if (signal_pending(current)) - break; - if (timeout && time_after(jiffies, orig_jiffies + timeout)) - break; - } -exit: - DBGINFO(("%s wait_until_sent exit\n", info->device_name)); -} - -static int write_room(struct tty_struct *tty) -{ - struct slgt_info *info = tty->driver_data; - int ret; - - if (sanity_check(info, tty->name, "write_room")) - return 0; - ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE; - DBGINFO(("%s write_room=%d\n", info->device_name, ret)); - return ret; -} - -static void flush_chars(struct tty_struct *tty) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "flush_chars")) - return; - DBGINFO(("%s flush_chars entry tx_count=%d\n", info->device_name, info->tx_count)); - - if (info->tx_count <= 0 || tty->stopped || - tty->hw_stopped || !info->tx_buf) - return; - - DBGINFO(("%s flush_chars start transmit\n", info->device_name)); - - spin_lock_irqsave(&info->lock,flags); - if (info->tx_count && tx_load(info, info->tx_buf, info->tx_count)) - info->tx_count = 0; - spin_unlock_irqrestore(&info->lock,flags); -} - -static void flush_buffer(struct tty_struct *tty) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "flush_buffer")) - return; - DBGINFO(("%s flush_buffer\n", info->device_name)); - - spin_lock_irqsave(&info->lock, flags); - info->tx_count = 0; - spin_unlock_irqrestore(&info->lock, flags); - - tty_wakeup(tty); -} - -/* - * throttle (stop) transmitter - */ -static void tx_hold(struct tty_struct *tty) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "tx_hold")) - return; - DBGINFO(("%s tx_hold\n", info->device_name)); - spin_lock_irqsave(&info->lock,flags); - if (info->tx_enabled && info->params.mode == MGSL_MODE_ASYNC) - tx_stop(info); - spin_unlock_irqrestore(&info->lock,flags); -} - -/* - * release (start) transmitter - */ -static void tx_release(struct tty_struct *tty) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "tx_release")) - return; - DBGINFO(("%s tx_release\n", info->device_name)); - spin_lock_irqsave(&info->lock, flags); - if (info->tx_count && tx_load(info, info->tx_buf, info->tx_count)) - info->tx_count = 0; - spin_unlock_irqrestore(&info->lock, flags); -} - -/* - * Service an IOCTL request - * - * Arguments - * - * tty pointer to tty instance data - * cmd IOCTL command code - * arg command argument/context - * - * Return 0 if success, otherwise error code - */ -static int ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct slgt_info *info = tty->driver_data; - void __user *argp = (void __user *)arg; - int ret; - - if (sanity_check(info, tty->name, "ioctl")) - return -ENODEV; - DBGINFO(("%s ioctl() cmd=%08X\n", info->device_name, cmd)); - - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCMIWAIT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - } - - switch (cmd) { - case MGSL_IOCWAITEVENT: - return wait_mgsl_event(info, argp); - case TIOCMIWAIT: - return modem_input_wait(info,(int)arg); - case MGSL_IOCSGPIO: - return set_gpio(info, argp); - case MGSL_IOCGGPIO: - return get_gpio(info, argp); - case MGSL_IOCWAITGPIO: - return wait_gpio(info, argp); - case MGSL_IOCGXSYNC: - return get_xsync(info, argp); - case MGSL_IOCSXSYNC: - return set_xsync(info, (int)arg); - case MGSL_IOCGXCTRL: - return get_xctrl(info, argp); - case MGSL_IOCSXCTRL: - return set_xctrl(info, (int)arg); - } - mutex_lock(&info->port.mutex); - switch (cmd) { - case MGSL_IOCGPARAMS: - ret = get_params(info, argp); - break; - case MGSL_IOCSPARAMS: - ret = set_params(info, argp); - break; - case MGSL_IOCGTXIDLE: - ret = get_txidle(info, argp); - break; - case MGSL_IOCSTXIDLE: - ret = set_txidle(info, (int)arg); - break; - case MGSL_IOCTXENABLE: - ret = tx_enable(info, (int)arg); - break; - case MGSL_IOCRXENABLE: - ret = rx_enable(info, (int)arg); - break; - case MGSL_IOCTXABORT: - ret = tx_abort(info); - break; - case MGSL_IOCGSTATS: - ret = get_stats(info, argp); - break; - case MGSL_IOCGIF: - ret = get_interface(info, argp); - break; - case MGSL_IOCSIF: - ret = set_interface(info,(int)arg); - break; - default: - ret = -ENOIOCTLCMD; - } - mutex_unlock(&info->port.mutex); - return ret; -} - -static int get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) - -{ - struct slgt_info *info = tty->driver_data; - struct mgsl_icount cnow; /* kernel counter temps */ - unsigned long flags; - - spin_lock_irqsave(&info->lock,flags); - cnow = info->icount; - spin_unlock_irqrestore(&info->lock,flags); - - icount->cts = cnow.cts; - icount->dsr = cnow.dsr; - icount->rng = cnow.rng; - icount->dcd = cnow.dcd; - icount->rx = cnow.rx; - icount->tx = cnow.tx; - icount->frame = cnow.frame; - icount->overrun = cnow.overrun; - icount->parity = cnow.parity; - icount->brk = cnow.brk; - icount->buf_overrun = cnow.buf_overrun; - - return 0; -} - -/* - * support for 32 bit ioctl calls on 64 bit systems - */ -#ifdef CONFIG_COMPAT -static long get_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *user_params) -{ - struct MGSL_PARAMS32 tmp_params; - - DBGINFO(("%s get_params32\n", info->device_name)); - memset(&tmp_params, 0, sizeof(tmp_params)); - tmp_params.mode = (compat_ulong_t)info->params.mode; - tmp_params.loopback = info->params.loopback; - tmp_params.flags = info->params.flags; - tmp_params.encoding = info->params.encoding; - tmp_params.clock_speed = (compat_ulong_t)info->params.clock_speed; - tmp_params.addr_filter = info->params.addr_filter; - tmp_params.crc_type = info->params.crc_type; - tmp_params.preamble_length = info->params.preamble_length; - tmp_params.preamble = info->params.preamble; - tmp_params.data_rate = (compat_ulong_t)info->params.data_rate; - tmp_params.data_bits = info->params.data_bits; - tmp_params.stop_bits = info->params.stop_bits; - tmp_params.parity = info->params.parity; - if (copy_to_user(user_params, &tmp_params, sizeof(struct MGSL_PARAMS32))) - return -EFAULT; - return 0; -} - -static long set_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *new_params) -{ - struct MGSL_PARAMS32 tmp_params; - - DBGINFO(("%s set_params32\n", info->device_name)); - if (copy_from_user(&tmp_params, new_params, sizeof(struct MGSL_PARAMS32))) - return -EFAULT; - - spin_lock(&info->lock); - if (tmp_params.mode == MGSL_MODE_BASE_CLOCK) { - info->base_clock = tmp_params.clock_speed; - } else { - info->params.mode = tmp_params.mode; - info->params.loopback = tmp_params.loopback; - info->params.flags = tmp_params.flags; - info->params.encoding = tmp_params.encoding; - info->params.clock_speed = tmp_params.clock_speed; - info->params.addr_filter = tmp_params.addr_filter; - info->params.crc_type = tmp_params.crc_type; - info->params.preamble_length = tmp_params.preamble_length; - info->params.preamble = tmp_params.preamble; - info->params.data_rate = tmp_params.data_rate; - info->params.data_bits = tmp_params.data_bits; - info->params.stop_bits = tmp_params.stop_bits; - info->params.parity = tmp_params.parity; - } - spin_unlock(&info->lock); - - program_hw(info); - - return 0; -} - -static long slgt_compat_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct slgt_info *info = tty->driver_data; - int rc = -ENOIOCTLCMD; - - if (sanity_check(info, tty->name, "compat_ioctl")) - return -ENODEV; - DBGINFO(("%s compat_ioctl() cmd=%08X\n", info->device_name, cmd)); - - switch (cmd) { - - case MGSL_IOCSPARAMS32: - rc = set_params32(info, compat_ptr(arg)); - break; - - case MGSL_IOCGPARAMS32: - rc = get_params32(info, compat_ptr(arg)); - break; - - case MGSL_IOCGPARAMS: - case MGSL_IOCSPARAMS: - case MGSL_IOCGTXIDLE: - case MGSL_IOCGSTATS: - case MGSL_IOCWAITEVENT: - case MGSL_IOCGIF: - case MGSL_IOCSGPIO: - case MGSL_IOCGGPIO: - case MGSL_IOCWAITGPIO: - case MGSL_IOCGXSYNC: - case MGSL_IOCGXCTRL: - case MGSL_IOCSTXIDLE: - case MGSL_IOCTXENABLE: - case MGSL_IOCRXENABLE: - case MGSL_IOCTXABORT: - case TIOCMIWAIT: - case MGSL_IOCSIF: - case MGSL_IOCSXSYNC: - case MGSL_IOCSXCTRL: - rc = ioctl(tty, cmd, arg); - break; - } - - DBGINFO(("%s compat_ioctl() cmd=%08X rc=%d\n", info->device_name, cmd, rc)); - return rc; -} -#else -#define slgt_compat_ioctl NULL -#endif /* ifdef CONFIG_COMPAT */ - -/* - * proc fs support - */ -static inline void line_info(struct seq_file *m, struct slgt_info *info) -{ - char stat_buf[30]; - unsigned long flags; - - seq_printf(m, "%s: IO=%08X IRQ=%d MaxFrameSize=%u\n", - info->device_name, info->phys_reg_addr, - info->irq_level, info->max_frame_size); - - /* output current serial signal states */ - spin_lock_irqsave(&info->lock,flags); - get_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - - stat_buf[0] = 0; - stat_buf[1] = 0; - if (info->signals & SerialSignal_RTS) - strcat(stat_buf, "|RTS"); - if (info->signals & SerialSignal_CTS) - strcat(stat_buf, "|CTS"); - if (info->signals & SerialSignal_DTR) - strcat(stat_buf, "|DTR"); - if (info->signals & SerialSignal_DSR) - strcat(stat_buf, "|DSR"); - if (info->signals & SerialSignal_DCD) - strcat(stat_buf, "|CD"); - if (info->signals & SerialSignal_RI) - strcat(stat_buf, "|RI"); - - if (info->params.mode != MGSL_MODE_ASYNC) { - seq_printf(m, "\tHDLC txok:%d rxok:%d", - info->icount.txok, info->icount.rxok); - if (info->icount.txunder) - seq_printf(m, " txunder:%d", info->icount.txunder); - if (info->icount.txabort) - seq_printf(m, " txabort:%d", info->icount.txabort); - if (info->icount.rxshort) - seq_printf(m, " rxshort:%d", info->icount.rxshort); - if (info->icount.rxlong) - seq_printf(m, " rxlong:%d", info->icount.rxlong); - if (info->icount.rxover) - seq_printf(m, " rxover:%d", info->icount.rxover); - if (info->icount.rxcrc) - seq_printf(m, " rxcrc:%d", info->icount.rxcrc); - } else { - seq_printf(m, "\tASYNC tx:%d rx:%d", - info->icount.tx, info->icount.rx); - if (info->icount.frame) - seq_printf(m, " fe:%d", info->icount.frame); - if (info->icount.parity) - seq_printf(m, " pe:%d", info->icount.parity); - if (info->icount.brk) - seq_printf(m, " brk:%d", info->icount.brk); - if (info->icount.overrun) - seq_printf(m, " oe:%d", info->icount.overrun); - } - - /* Append serial signal status to end */ - seq_printf(m, " %s\n", stat_buf+1); - - seq_printf(m, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", - info->tx_active,info->bh_requested,info->bh_running, - info->pending_bh); -} - -/* Called to print information about devices - */ -static int synclink_gt_proc_show(struct seq_file *m, void *v) -{ - struct slgt_info *info; - - seq_puts(m, "synclink_gt driver\n"); - - info = slgt_device_list; - while( info ) { - line_info(m, info); - info = info->next_device; - } - return 0; -} - -static int synclink_gt_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, synclink_gt_proc_show, NULL); -} - -static const struct file_operations synclink_gt_proc_fops = { - .owner = THIS_MODULE, - .open = synclink_gt_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/* - * return count of bytes in transmit buffer - */ -static int chars_in_buffer(struct tty_struct *tty) -{ - struct slgt_info *info = tty->driver_data; - int count; - if (sanity_check(info, tty->name, "chars_in_buffer")) - return 0; - count = tbuf_bytes(info); - DBGINFO(("%s chars_in_buffer()=%d\n", info->device_name, count)); - return count; -} - -/* - * signal remote device to throttle send data (our receive data) - */ -static void throttle(struct tty_struct * tty) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "throttle")) - return; - DBGINFO(("%s throttle\n", info->device_name)); - if (I_IXOFF(tty)) - send_xchar(tty, STOP_CHAR(tty)); - if (tty->termios->c_cflag & CRTSCTS) { - spin_lock_irqsave(&info->lock,flags); - info->signals &= ~SerialSignal_RTS; - set_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - } -} - -/* - * signal remote device to stop throttling send data (our receive data) - */ -static void unthrottle(struct tty_struct * tty) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "unthrottle")) - return; - DBGINFO(("%s unthrottle\n", info->device_name)); - if (I_IXOFF(tty)) { - if (info->x_char) - info->x_char = 0; - else - send_xchar(tty, START_CHAR(tty)); - } - if (tty->termios->c_cflag & CRTSCTS) { - spin_lock_irqsave(&info->lock,flags); - info->signals |= SerialSignal_RTS; - set_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - } -} - -/* - * set or clear transmit break condition - * break_state -1=set break condition, 0=clear - */ -static int set_break(struct tty_struct *tty, int break_state) -{ - struct slgt_info *info = tty->driver_data; - unsigned short value; - unsigned long flags; - - if (sanity_check(info, tty->name, "set_break")) - return -EINVAL; - DBGINFO(("%s set_break(%d)\n", info->device_name, break_state)); - - spin_lock_irqsave(&info->lock,flags); - value = rd_reg16(info, TCR); - if (break_state == -1) - value |= BIT6; - else - value &= ~BIT6; - wr_reg16(info, TCR, value); - spin_unlock_irqrestore(&info->lock,flags); - return 0; -} - -#if SYNCLINK_GENERIC_HDLC - -/** - * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) - * set encoding and frame check sequence (FCS) options - * - * dev pointer to network device structure - * encoding serial encoding setting - * parity FCS setting - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_attach(struct net_device *dev, unsigned short encoding, - unsigned short parity) -{ - struct slgt_info *info = dev_to_port(dev); - unsigned char new_encoding; - unsigned short new_crctype; - - /* return error if TTY interface open */ - if (info->port.count) - return -EBUSY; - - DBGINFO(("%s hdlcdev_attach\n", info->device_name)); - - switch (encoding) - { - case ENCODING_NRZ: new_encoding = HDLC_ENCODING_NRZ; break; - case ENCODING_NRZI: new_encoding = HDLC_ENCODING_NRZI_SPACE; break; - case ENCODING_FM_MARK: new_encoding = HDLC_ENCODING_BIPHASE_MARK; break; - case ENCODING_FM_SPACE: new_encoding = HDLC_ENCODING_BIPHASE_SPACE; break; - case ENCODING_MANCHESTER: new_encoding = HDLC_ENCODING_BIPHASE_LEVEL; break; - default: return -EINVAL; - } - - switch (parity) - { - case PARITY_NONE: new_crctype = HDLC_CRC_NONE; break; - case PARITY_CRC16_PR1_CCITT: new_crctype = HDLC_CRC_16_CCITT; break; - case PARITY_CRC32_PR1_CCITT: new_crctype = HDLC_CRC_32_CCITT; break; - default: return -EINVAL; - } - - info->params.encoding = new_encoding; - info->params.crc_type = new_crctype; - - /* if network interface up, reprogram hardware */ - if (info->netcount) - program_hw(info); - - return 0; -} - -/** - * called by generic HDLC layer to send frame - * - * skb socket buffer containing HDLC frame - * dev pointer to network device structure - */ -static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb, - struct net_device *dev) -{ - struct slgt_info *info = dev_to_port(dev); - unsigned long flags; - - DBGINFO(("%s hdlc_xmit\n", dev->name)); - - if (!skb->len) - return NETDEV_TX_OK; - - /* stop sending until this frame completes */ - netif_stop_queue(dev); - - /* update network statistics */ - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - - /* save start time for transmit timeout detection */ - dev->trans_start = jiffies; - - spin_lock_irqsave(&info->lock, flags); - tx_load(info, skb->data, skb->len); - spin_unlock_irqrestore(&info->lock, flags); - - /* done with socket buffer, so free it */ - dev_kfree_skb(skb); - - return NETDEV_TX_OK; -} - -/** - * called by network layer when interface enabled - * claim resources and initialize hardware - * - * dev pointer to network device structure - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_open(struct net_device *dev) -{ - struct slgt_info *info = dev_to_port(dev); - int rc; - unsigned long flags; - - if (!try_module_get(THIS_MODULE)) - return -EBUSY; - - DBGINFO(("%s hdlcdev_open\n", dev->name)); - - /* generic HDLC layer open processing */ - if ((rc = hdlc_open(dev))) - return rc; - - /* arbitrate between network and tty opens */ - spin_lock_irqsave(&info->netlock, flags); - if (info->port.count != 0 || info->netcount != 0) { - DBGINFO(("%s hdlc_open busy\n", dev->name)); - spin_unlock_irqrestore(&info->netlock, flags); - return -EBUSY; - } - info->netcount=1; - spin_unlock_irqrestore(&info->netlock, flags); - - /* claim resources and init adapter */ - if ((rc = startup(info)) != 0) { - spin_lock_irqsave(&info->netlock, flags); - info->netcount=0; - spin_unlock_irqrestore(&info->netlock, flags); - return rc; - } - - /* assert DTR and RTS, apply hardware settings */ - info->signals |= SerialSignal_RTS + SerialSignal_DTR; - program_hw(info); - - /* enable network layer transmit */ - dev->trans_start = jiffies; - netif_start_queue(dev); - - /* inform generic HDLC layer of current DCD status */ - spin_lock_irqsave(&info->lock, flags); - get_signals(info); - spin_unlock_irqrestore(&info->lock, flags); - if (info->signals & SerialSignal_DCD) - netif_carrier_on(dev); - else - netif_carrier_off(dev); - return 0; -} - -/** - * called by network layer when interface is disabled - * shutdown hardware and release resources - * - * dev pointer to network device structure - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_close(struct net_device *dev) -{ - struct slgt_info *info = dev_to_port(dev); - unsigned long flags; - - DBGINFO(("%s hdlcdev_close\n", dev->name)); - - netif_stop_queue(dev); - - /* shutdown adapter and release resources */ - shutdown(info); - - hdlc_close(dev); - - spin_lock_irqsave(&info->netlock, flags); - info->netcount=0; - spin_unlock_irqrestore(&info->netlock, flags); - - module_put(THIS_MODULE); - return 0; -} - -/** - * called by network layer to process IOCTL call to network device - * - * dev pointer to network device structure - * ifr pointer to network interface request structure - * cmd IOCTL command code - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - const size_t size = sizeof(sync_serial_settings); - sync_serial_settings new_line; - sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; - struct slgt_info *info = dev_to_port(dev); - unsigned int flags; - - DBGINFO(("%s hdlcdev_ioctl\n", dev->name)); - - /* return error if TTY interface open */ - if (info->port.count) - return -EBUSY; - - if (cmd != SIOCWANDEV) - return hdlc_ioctl(dev, ifr, cmd); - - memset(&new_line, 0, sizeof(new_line)); - - switch(ifr->ifr_settings.type) { - case IF_GET_IFACE: /* return current sync_serial_settings */ - - ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL; - if (ifr->ifr_settings.size < size) { - ifr->ifr_settings.size = size; /* data size wanted */ - return -ENOBUFS; - } - - flags = info->params.flags & (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | - HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | - HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | - HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); - - switch (flags){ - case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN): new_line.clock_type = CLOCK_EXT; break; - case (HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG): new_line.clock_type = CLOCK_INT; break; - case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG): new_line.clock_type = CLOCK_TXINT; break; - case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN): new_line.clock_type = CLOCK_TXFROMRX; break; - default: new_line.clock_type = CLOCK_DEFAULT; - } - - new_line.clock_rate = info->params.clock_speed; - new_line.loopback = info->params.loopback ? 1:0; - - if (copy_to_user(line, &new_line, size)) - return -EFAULT; - return 0; - - case IF_IFACE_SYNC_SERIAL: /* set sync_serial_settings */ - - if(!capable(CAP_NET_ADMIN)) - return -EPERM; - if (copy_from_user(&new_line, line, size)) - return -EFAULT; - - switch (new_line.clock_type) - { - case CLOCK_EXT: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN; break; - case CLOCK_TXFROMRX: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN; break; - case CLOCK_INT: flags = HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG; break; - case CLOCK_TXINT: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG; break; - case CLOCK_DEFAULT: flags = info->params.flags & - (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | - HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | - HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | - HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); break; - default: return -EINVAL; - } - - if (new_line.loopback != 0 && new_line.loopback != 1) - return -EINVAL; - - info->params.flags &= ~(HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | - HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | - HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | - HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); - info->params.flags |= flags; - - info->params.loopback = new_line.loopback; - - if (flags & (HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG)) - info->params.clock_speed = new_line.clock_rate; - else - info->params.clock_speed = 0; - - /* if network interface up, reprogram hardware */ - if (info->netcount) - program_hw(info); - return 0; - - default: - return hdlc_ioctl(dev, ifr, cmd); - } -} - -/** - * called by network layer when transmit timeout is detected - * - * dev pointer to network device structure - */ -static void hdlcdev_tx_timeout(struct net_device *dev) -{ - struct slgt_info *info = dev_to_port(dev); - unsigned long flags; - - DBGINFO(("%s hdlcdev_tx_timeout\n", dev->name)); - - dev->stats.tx_errors++; - dev->stats.tx_aborted_errors++; - - spin_lock_irqsave(&info->lock,flags); - tx_stop(info); - spin_unlock_irqrestore(&info->lock,flags); - - netif_wake_queue(dev); -} - -/** - * called by device driver when transmit completes - * reenable network layer transmit if stopped - * - * info pointer to device instance information - */ -static void hdlcdev_tx_done(struct slgt_info *info) -{ - if (netif_queue_stopped(info->netdev)) - netif_wake_queue(info->netdev); -} - -/** - * called by device driver when frame received - * pass frame to network layer - * - * info pointer to device instance information - * buf pointer to buffer contianing frame data - * size count of data bytes in buf - */ -static void hdlcdev_rx(struct slgt_info *info, char *buf, int size) -{ - struct sk_buff *skb = dev_alloc_skb(size); - struct net_device *dev = info->netdev; - - DBGINFO(("%s hdlcdev_rx\n", dev->name)); - - if (skb == NULL) { - DBGERR(("%s: can't alloc skb, drop packet\n", dev->name)); - dev->stats.rx_dropped++; - return; - } - - memcpy(skb_put(skb, size), buf, size); - - skb->protocol = hdlc_type_trans(skb, dev); - - dev->stats.rx_packets++; - dev->stats.rx_bytes += size; - - netif_rx(skb); -} - -static const struct net_device_ops hdlcdev_ops = { - .ndo_open = hdlcdev_open, - .ndo_stop = hdlcdev_close, - .ndo_change_mtu = hdlc_change_mtu, - .ndo_start_xmit = hdlc_start_xmit, - .ndo_do_ioctl = hdlcdev_ioctl, - .ndo_tx_timeout = hdlcdev_tx_timeout, -}; - -/** - * called by device driver when adding device instance - * do generic HDLC initialization - * - * info pointer to device instance information - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_init(struct slgt_info *info) -{ - int rc; - struct net_device *dev; - hdlc_device *hdlc; - - /* allocate and initialize network and HDLC layer objects */ - - if (!(dev = alloc_hdlcdev(info))) { - printk(KERN_ERR "%s hdlc device alloc failure\n", info->device_name); - return -ENOMEM; - } - - /* for network layer reporting purposes only */ - dev->mem_start = info->phys_reg_addr; - dev->mem_end = info->phys_reg_addr + SLGT_REG_SIZE - 1; - dev->irq = info->irq_level; - - /* network layer callbacks and settings */ - dev->netdev_ops = &hdlcdev_ops; - dev->watchdog_timeo = 10 * HZ; - dev->tx_queue_len = 50; - - /* generic HDLC layer callbacks and settings */ - hdlc = dev_to_hdlc(dev); - hdlc->attach = hdlcdev_attach; - hdlc->xmit = hdlcdev_xmit; - - /* register objects with HDLC layer */ - if ((rc = register_hdlc_device(dev))) { - printk(KERN_WARNING "%s:unable to register hdlc device\n",__FILE__); - free_netdev(dev); - return rc; - } - - info->netdev = dev; - return 0; -} - -/** - * called by device driver when removing device instance - * do generic HDLC cleanup - * - * info pointer to device instance information - */ -static void hdlcdev_exit(struct slgt_info *info) -{ - unregister_hdlc_device(info->netdev); - free_netdev(info->netdev); - info->netdev = NULL; -} - -#endif /* ifdef CONFIG_HDLC */ - -/* - * get async data from rx DMA buffers - */ -static void rx_async(struct slgt_info *info) -{ - struct tty_struct *tty = info->port.tty; - struct mgsl_icount *icount = &info->icount; - unsigned int start, end; - unsigned char *p; - unsigned char status; - struct slgt_desc *bufs = info->rbufs; - int i, count; - int chars = 0; - int stat; - unsigned char ch; - - start = end = info->rbuf_current; - - while(desc_complete(bufs[end])) { - count = desc_count(bufs[end]) - info->rbuf_index; - p = bufs[end].buf + info->rbuf_index; - - DBGISR(("%s rx_async count=%d\n", info->device_name, count)); - DBGDATA(info, p, count, "rx"); - - for(i=0 ; i < count; i+=2, p+=2) { - ch = *p; - icount->rx++; - - stat = 0; - - if ((status = *(p+1) & (BIT1 + BIT0))) { - if (status & BIT1) - icount->parity++; - else if (status & BIT0) - icount->frame++; - /* discard char if tty control flags say so */ - if (status & info->ignore_status_mask) - continue; - if (status & BIT1) - stat = TTY_PARITY; - else if (status & BIT0) - stat = TTY_FRAME; - } - if (tty) { - tty_insert_flip_char(tty, ch, stat); - chars++; - } - } - - if (i < count) { - /* receive buffer not completed */ - info->rbuf_index += i; - mod_timer(&info->rx_timer, jiffies + 1); - break; - } - - info->rbuf_index = 0; - free_rbufs(info, end, end); - - if (++end == info->rbuf_count) - end = 0; - - /* if entire list searched then no frame available */ - if (end == start) - break; - } - - if (tty && chars) - tty_flip_buffer_push(tty); -} - -/* - * return next bottom half action to perform - */ -static int bh_action(struct slgt_info *info) -{ - unsigned long flags; - int rc; - - spin_lock_irqsave(&info->lock,flags); - - if (info->pending_bh & BH_RECEIVE) { - info->pending_bh &= ~BH_RECEIVE; - rc = BH_RECEIVE; - } else if (info->pending_bh & BH_TRANSMIT) { - info->pending_bh &= ~BH_TRANSMIT; - rc = BH_TRANSMIT; - } else if (info->pending_bh & BH_STATUS) { - info->pending_bh &= ~BH_STATUS; - rc = BH_STATUS; - } else { - /* Mark BH routine as complete */ - info->bh_running = false; - info->bh_requested = false; - rc = 0; - } - - spin_unlock_irqrestore(&info->lock,flags); - - return rc; -} - -/* - * perform bottom half processing - */ -static void bh_handler(struct work_struct *work) -{ - struct slgt_info *info = container_of(work, struct slgt_info, task); - int action; - - if (!info) - return; - info->bh_running = true; - - while((action = bh_action(info))) { - switch (action) { - case BH_RECEIVE: - DBGBH(("%s bh receive\n", info->device_name)); - switch(info->params.mode) { - case MGSL_MODE_ASYNC: - rx_async(info); - break; - case MGSL_MODE_HDLC: - while(rx_get_frame(info)); - break; - case MGSL_MODE_RAW: - case MGSL_MODE_MONOSYNC: - case MGSL_MODE_BISYNC: - case MGSL_MODE_XSYNC: - while(rx_get_buf(info)); - break; - } - /* restart receiver if rx DMA buffers exhausted */ - if (info->rx_restart) - rx_start(info); - break; - case BH_TRANSMIT: - bh_transmit(info); - break; - case BH_STATUS: - DBGBH(("%s bh status\n", info->device_name)); - info->ri_chkcount = 0; - info->dsr_chkcount = 0; - info->dcd_chkcount = 0; - info->cts_chkcount = 0; - break; - default: - DBGBH(("%s unknown action\n", info->device_name)); - break; - } - } - DBGBH(("%s bh_handler exit\n", info->device_name)); -} - -static void bh_transmit(struct slgt_info *info) -{ - struct tty_struct *tty = info->port.tty; - - DBGBH(("%s bh_transmit\n", info->device_name)); - if (tty) - tty_wakeup(tty); -} - -static void dsr_change(struct slgt_info *info, unsigned short status) -{ - if (status & BIT3) { - info->signals |= SerialSignal_DSR; - info->input_signal_events.dsr_up++; - } else { - info->signals &= ~SerialSignal_DSR; - info->input_signal_events.dsr_down++; - } - DBGISR(("dsr_change %s signals=%04X\n", info->device_name, info->signals)); - if ((info->dsr_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { - slgt_irq_off(info, IRQ_DSR); - return; - } - info->icount.dsr++; - wake_up_interruptible(&info->status_event_wait_q); - wake_up_interruptible(&info->event_wait_q); - info->pending_bh |= BH_STATUS; -} - -static void cts_change(struct slgt_info *info, unsigned short status) -{ - if (status & BIT2) { - info->signals |= SerialSignal_CTS; - info->input_signal_events.cts_up++; - } else { - info->signals &= ~SerialSignal_CTS; - info->input_signal_events.cts_down++; - } - DBGISR(("cts_change %s signals=%04X\n", info->device_name, info->signals)); - if ((info->cts_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { - slgt_irq_off(info, IRQ_CTS); - return; - } - info->icount.cts++; - wake_up_interruptible(&info->status_event_wait_q); - wake_up_interruptible(&info->event_wait_q); - info->pending_bh |= BH_STATUS; - - if (info->port.flags & ASYNC_CTS_FLOW) { - if (info->port.tty) { - if (info->port.tty->hw_stopped) { - if (info->signals & SerialSignal_CTS) { - info->port.tty->hw_stopped = 0; - info->pending_bh |= BH_TRANSMIT; - return; - } - } else { - if (!(info->signals & SerialSignal_CTS)) - info->port.tty->hw_stopped = 1; - } - } - } -} - -static void dcd_change(struct slgt_info *info, unsigned short status) -{ - if (status & BIT1) { - info->signals |= SerialSignal_DCD; - info->input_signal_events.dcd_up++; - } else { - info->signals &= ~SerialSignal_DCD; - info->input_signal_events.dcd_down++; - } - DBGISR(("dcd_change %s signals=%04X\n", info->device_name, info->signals)); - if ((info->dcd_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { - slgt_irq_off(info, IRQ_DCD); - return; - } - info->icount.dcd++; -#if SYNCLINK_GENERIC_HDLC - if (info->netcount) { - if (info->signals & SerialSignal_DCD) - netif_carrier_on(info->netdev); - else - netif_carrier_off(info->netdev); - } -#endif - wake_up_interruptible(&info->status_event_wait_q); - wake_up_interruptible(&info->event_wait_q); - info->pending_bh |= BH_STATUS; - - if (info->port.flags & ASYNC_CHECK_CD) { - if (info->signals & SerialSignal_DCD) - wake_up_interruptible(&info->port.open_wait); - else { - if (info->port.tty) - tty_hangup(info->port.tty); - } - } -} - -static void ri_change(struct slgt_info *info, unsigned short status) -{ - if (status & BIT0) { - info->signals |= SerialSignal_RI; - info->input_signal_events.ri_up++; - } else { - info->signals &= ~SerialSignal_RI; - info->input_signal_events.ri_down++; - } - DBGISR(("ri_change %s signals=%04X\n", info->device_name, info->signals)); - if ((info->ri_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { - slgt_irq_off(info, IRQ_RI); - return; - } - info->icount.rng++; - wake_up_interruptible(&info->status_event_wait_q); - wake_up_interruptible(&info->event_wait_q); - info->pending_bh |= BH_STATUS; -} - -static void isr_rxdata(struct slgt_info *info) -{ - unsigned int count = info->rbuf_fill_count; - unsigned int i = info->rbuf_fill_index; - unsigned short reg; - - while (rd_reg16(info, SSR) & IRQ_RXDATA) { - reg = rd_reg16(info, RDR); - DBGISR(("isr_rxdata %s RDR=%04X\n", info->device_name, reg)); - if (desc_complete(info->rbufs[i])) { - /* all buffers full */ - rx_stop(info); - info->rx_restart = 1; - continue; - } - info->rbufs[i].buf[count++] = (unsigned char)reg; - /* async mode saves status byte to buffer for each data byte */ - if (info->params.mode == MGSL_MODE_ASYNC) - info->rbufs[i].buf[count++] = (unsigned char)(reg >> 8); - if (count == info->rbuf_fill_level || (reg & BIT10)) { - /* buffer full or end of frame */ - set_desc_count(info->rbufs[i], count); - set_desc_status(info->rbufs[i], BIT15 | (reg >> 8)); - info->rbuf_fill_count = count = 0; - if (++i == info->rbuf_count) - i = 0; - info->pending_bh |= BH_RECEIVE; - } - } - - info->rbuf_fill_index = i; - info->rbuf_fill_count = count; -} - -static void isr_serial(struct slgt_info *info) -{ - unsigned short status = rd_reg16(info, SSR); - - DBGISR(("%s isr_serial status=%04X\n", info->device_name, status)); - - wr_reg16(info, SSR, status); /* clear pending */ - - info->irq_occurred = true; - - if (info->params.mode == MGSL_MODE_ASYNC) { - if (status & IRQ_TXIDLE) { - if (info->tx_active) - isr_txeom(info, status); - } - if (info->rx_pio && (status & IRQ_RXDATA)) - isr_rxdata(info); - if ((status & IRQ_RXBREAK) && (status & RXBREAK)) { - info->icount.brk++; - /* process break detection if tty control allows */ - if (info->port.tty) { - if (!(status & info->ignore_status_mask)) { - if (info->read_status_mask & MASK_BREAK) { - tty_insert_flip_char(info->port.tty, 0, TTY_BREAK); - if (info->port.flags & ASYNC_SAK) - do_SAK(info->port.tty); - } - } - } - } - } else { - if (status & (IRQ_TXIDLE + IRQ_TXUNDER)) - isr_txeom(info, status); - if (info->rx_pio && (status & IRQ_RXDATA)) - isr_rxdata(info); - if (status & IRQ_RXIDLE) { - if (status & RXIDLE) - info->icount.rxidle++; - else - info->icount.exithunt++; - wake_up_interruptible(&info->event_wait_q); - } - - if (status & IRQ_RXOVER) - rx_start(info); - } - - if (status & IRQ_DSR) - dsr_change(info, status); - if (status & IRQ_CTS) - cts_change(info, status); - if (status & IRQ_DCD) - dcd_change(info, status); - if (status & IRQ_RI) - ri_change(info, status); -} - -static void isr_rdma(struct slgt_info *info) -{ - unsigned int status = rd_reg32(info, RDCSR); - - DBGISR(("%s isr_rdma status=%08x\n", info->device_name, status)); - - /* RDCSR (rx DMA control/status) - * - * 31..07 reserved - * 06 save status byte to DMA buffer - * 05 error - * 04 eol (end of list) - * 03 eob (end of buffer) - * 02 IRQ enable - * 01 reset - * 00 enable - */ - wr_reg32(info, RDCSR, status); /* clear pending */ - - if (status & (BIT5 + BIT4)) { - DBGISR(("%s isr_rdma rx_restart=1\n", info->device_name)); - info->rx_restart = true; - } - info->pending_bh |= BH_RECEIVE; -} - -static void isr_tdma(struct slgt_info *info) -{ - unsigned int status = rd_reg32(info, TDCSR); - - DBGISR(("%s isr_tdma status=%08x\n", info->device_name, status)); - - /* TDCSR (tx DMA control/status) - * - * 31..06 reserved - * 05 error - * 04 eol (end of list) - * 03 eob (end of buffer) - * 02 IRQ enable - * 01 reset - * 00 enable - */ - wr_reg32(info, TDCSR, status); /* clear pending */ - - if (status & (BIT5 + BIT4 + BIT3)) { - // another transmit buffer has completed - // run bottom half to get more send data from user - info->pending_bh |= BH_TRANSMIT; - } -} - -/* - * return true if there are unsent tx DMA buffers, otherwise false - * - * if there are unsent buffers then info->tbuf_start - * is set to index of first unsent buffer - */ -static bool unsent_tbufs(struct slgt_info *info) -{ - unsigned int i = info->tbuf_current; - bool rc = false; - - /* - * search backwards from last loaded buffer (precedes tbuf_current) - * for first unsent buffer (desc_count > 0) - */ - - do { - if (i) - i--; - else - i = info->tbuf_count - 1; - if (!desc_count(info->tbufs[i])) - break; - info->tbuf_start = i; - rc = true; - } while (i != info->tbuf_current); - - return rc; -} - -static void isr_txeom(struct slgt_info *info, unsigned short status) -{ - DBGISR(("%s txeom status=%04x\n", info->device_name, status)); - - slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER); - tdma_reset(info); - if (status & IRQ_TXUNDER) { - unsigned short val = rd_reg16(info, TCR); - wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */ - wr_reg16(info, TCR, val); /* clear reset bit */ - } - - if (info->tx_active) { - if (info->params.mode != MGSL_MODE_ASYNC) { - if (status & IRQ_TXUNDER) - info->icount.txunder++; - else if (status & IRQ_TXIDLE) - info->icount.txok++; - } - - if (unsent_tbufs(info)) { - tx_start(info); - update_tx_timer(info); - return; - } - info->tx_active = false; - - del_timer(&info->tx_timer); - - if (info->params.mode != MGSL_MODE_ASYNC && info->drop_rts_on_tx_done) { - info->signals &= ~SerialSignal_RTS; - info->drop_rts_on_tx_done = false; - set_signals(info); - } - -#if SYNCLINK_GENERIC_HDLC - if (info->netcount) - hdlcdev_tx_done(info); - else -#endif - { - if (info->port.tty && (info->port.tty->stopped || info->port.tty->hw_stopped)) { - tx_stop(info); - return; - } - info->pending_bh |= BH_TRANSMIT; - } - } -} - -static void isr_gpio(struct slgt_info *info, unsigned int changed, unsigned int state) -{ - struct cond_wait *w, *prev; - - /* wake processes waiting for specific transitions */ - for (w = info->gpio_wait_q, prev = NULL ; w != NULL ; w = w->next) { - if (w->data & changed) { - w->data = state; - wake_up_interruptible(&w->q); - if (prev != NULL) - prev->next = w->next; - else - info->gpio_wait_q = w->next; - } else - prev = w; - } -} - -/* interrupt service routine - * - * irq interrupt number - * dev_id device ID supplied during interrupt registration - */ -static irqreturn_t slgt_interrupt(int dummy, void *dev_id) -{ - struct slgt_info *info = dev_id; - unsigned int gsr; - unsigned int i; - - DBGISR(("slgt_interrupt irq=%d entry\n", info->irq_level)); - - while((gsr = rd_reg32(info, GSR) & 0xffffff00)) { - DBGISR(("%s gsr=%08x\n", info->device_name, gsr)); - info->irq_occurred = true; - for(i=0; i < info->port_count ; i++) { - if (info->port_array[i] == NULL) - continue; - spin_lock(&info->port_array[i]->lock); - if (gsr & (BIT8 << i)) - isr_serial(info->port_array[i]); - if (gsr & (BIT16 << (i*2))) - isr_rdma(info->port_array[i]); - if (gsr & (BIT17 << (i*2))) - isr_tdma(info->port_array[i]); - spin_unlock(&info->port_array[i]->lock); - } - } - - if (info->gpio_present) { - unsigned int state; - unsigned int changed; - spin_lock(&info->lock); - while ((changed = rd_reg32(info, IOSR)) != 0) { - DBGISR(("%s iosr=%08x\n", info->device_name, changed)); - /* read latched state of GPIO signals */ - state = rd_reg32(info, IOVR); - /* clear pending GPIO interrupt bits */ - wr_reg32(info, IOSR, changed); - for (i=0 ; i < info->port_count ; i++) { - if (info->port_array[i] != NULL) - isr_gpio(info->port_array[i], changed, state); - } - } - spin_unlock(&info->lock); - } - - for(i=0; i < info->port_count ; i++) { - struct slgt_info *port = info->port_array[i]; - if (port == NULL) - continue; - spin_lock(&port->lock); - if ((port->port.count || port->netcount) && - port->pending_bh && !port->bh_running && - !port->bh_requested) { - DBGISR(("%s bh queued\n", port->device_name)); - schedule_work(&port->task); - port->bh_requested = true; - } - spin_unlock(&port->lock); - } - - DBGISR(("slgt_interrupt irq=%d exit\n", info->irq_level)); - return IRQ_HANDLED; -} - -static int startup(struct slgt_info *info) -{ - DBGINFO(("%s startup\n", info->device_name)); - - if (info->port.flags & ASYNC_INITIALIZED) - return 0; - - if (!info->tx_buf) { - info->tx_buf = kmalloc(info->max_frame_size, GFP_KERNEL); - if (!info->tx_buf) { - DBGERR(("%s can't allocate tx buffer\n", info->device_name)); - return -ENOMEM; - } - } - - info->pending_bh = 0; - - memset(&info->icount, 0, sizeof(info->icount)); - - /* program hardware for current parameters */ - change_params(info); - - if (info->port.tty) - clear_bit(TTY_IO_ERROR, &info->port.tty->flags); - - info->port.flags |= ASYNC_INITIALIZED; - - return 0; -} - -/* - * called by close() and hangup() to shutdown hardware - */ -static void shutdown(struct slgt_info *info) -{ - unsigned long flags; - - if (!(info->port.flags & ASYNC_INITIALIZED)) - return; - - DBGINFO(("%s shutdown\n", info->device_name)); - - /* clear status wait queue because status changes */ - /* can't happen after shutting down the hardware */ - wake_up_interruptible(&info->status_event_wait_q); - wake_up_interruptible(&info->event_wait_q); - - del_timer_sync(&info->tx_timer); - del_timer_sync(&info->rx_timer); - - kfree(info->tx_buf); - info->tx_buf = NULL; - - spin_lock_irqsave(&info->lock,flags); - - tx_stop(info); - rx_stop(info); - - slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); - - if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) { - info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS); - set_signals(info); - } - - flush_cond_wait(&info->gpio_wait_q); - - spin_unlock_irqrestore(&info->lock,flags); - - if (info->port.tty) - set_bit(TTY_IO_ERROR, &info->port.tty->flags); - - info->port.flags &= ~ASYNC_INITIALIZED; -} - -static void program_hw(struct slgt_info *info) -{ - unsigned long flags; - - spin_lock_irqsave(&info->lock,flags); - - rx_stop(info); - tx_stop(info); - - if (info->params.mode != MGSL_MODE_ASYNC || - info->netcount) - sync_mode(info); - else - async_mode(info); - - set_signals(info); - - info->dcd_chkcount = 0; - info->cts_chkcount = 0; - info->ri_chkcount = 0; - info->dsr_chkcount = 0; - - slgt_irq_on(info, IRQ_DCD | IRQ_CTS | IRQ_DSR | IRQ_RI); - get_signals(info); - - if (info->netcount || - (info->port.tty && info->port.tty->termios->c_cflag & CREAD)) - rx_start(info); - - spin_unlock_irqrestore(&info->lock,flags); -} - -/* - * reconfigure adapter based on new parameters - */ -static void change_params(struct slgt_info *info) -{ - unsigned cflag; - int bits_per_char; - - if (!info->port.tty || !info->port.tty->termios) - return; - DBGINFO(("%s change_params\n", info->device_name)); - - cflag = info->port.tty->termios->c_cflag; - - /* if B0 rate (hangup) specified then negate DTR and RTS */ - /* otherwise assert DTR and RTS */ - if (cflag & CBAUD) - info->signals |= SerialSignal_RTS + SerialSignal_DTR; - else - info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); - - /* byte size and parity */ - - switch (cflag & CSIZE) { - case CS5: info->params.data_bits = 5; break; - case CS6: info->params.data_bits = 6; break; - case CS7: info->params.data_bits = 7; break; - case CS8: info->params.data_bits = 8; break; - default: info->params.data_bits = 7; break; - } - - info->params.stop_bits = (cflag & CSTOPB) ? 2 : 1; - - if (cflag & PARENB) - info->params.parity = (cflag & PARODD) ? ASYNC_PARITY_ODD : ASYNC_PARITY_EVEN; - else - info->params.parity = ASYNC_PARITY_NONE; - - /* calculate number of jiffies to transmit a full - * FIFO (32 bytes) at specified data rate - */ - bits_per_char = info->params.data_bits + - info->params.stop_bits + 1; - - info->params.data_rate = tty_get_baud_rate(info->port.tty); - - if (info->params.data_rate) { - info->timeout = (32*HZ*bits_per_char) / - info->params.data_rate; - } - info->timeout += HZ/50; /* Add .02 seconds of slop */ - - if (cflag & CRTSCTS) - info->port.flags |= ASYNC_CTS_FLOW; - else - info->port.flags &= ~ASYNC_CTS_FLOW; - - if (cflag & CLOCAL) - info->port.flags &= ~ASYNC_CHECK_CD; - else - info->port.flags |= ASYNC_CHECK_CD; - - /* process tty input control flags */ - - info->read_status_mask = IRQ_RXOVER; - if (I_INPCK(info->port.tty)) - info->read_status_mask |= MASK_PARITY | MASK_FRAMING; - if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) - info->read_status_mask |= MASK_BREAK; - if (I_IGNPAR(info->port.tty)) - info->ignore_status_mask |= MASK_PARITY | MASK_FRAMING; - if (I_IGNBRK(info->port.tty)) { - info->ignore_status_mask |= MASK_BREAK; - /* If ignoring parity and break indicators, ignore - * overruns too. (For real raw support). - */ - if (I_IGNPAR(info->port.tty)) - info->ignore_status_mask |= MASK_OVERRUN; - } - - program_hw(info); -} - -static int get_stats(struct slgt_info *info, struct mgsl_icount __user *user_icount) -{ - DBGINFO(("%s get_stats\n", info->device_name)); - if (!user_icount) { - memset(&info->icount, 0, sizeof(info->icount)); - } else { - if (copy_to_user(user_icount, &info->icount, sizeof(struct mgsl_icount))) - return -EFAULT; - } - return 0; -} - -static int get_params(struct slgt_info *info, MGSL_PARAMS __user *user_params) -{ - DBGINFO(("%s get_params\n", info->device_name)); - if (copy_to_user(user_params, &info->params, sizeof(MGSL_PARAMS))) - return -EFAULT; - return 0; -} - -static int set_params(struct slgt_info *info, MGSL_PARAMS __user *new_params) -{ - unsigned long flags; - MGSL_PARAMS tmp_params; - - DBGINFO(("%s set_params\n", info->device_name)); - if (copy_from_user(&tmp_params, new_params, sizeof(MGSL_PARAMS))) - return -EFAULT; - - spin_lock_irqsave(&info->lock, flags); - if (tmp_params.mode == MGSL_MODE_BASE_CLOCK) - info->base_clock = tmp_params.clock_speed; - else - memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS)); - spin_unlock_irqrestore(&info->lock, flags); - - program_hw(info); - - return 0; -} - -static int get_txidle(struct slgt_info *info, int __user *idle_mode) -{ - DBGINFO(("%s get_txidle=%d\n", info->device_name, info->idle_mode)); - if (put_user(info->idle_mode, idle_mode)) - return -EFAULT; - return 0; -} - -static int set_txidle(struct slgt_info *info, int idle_mode) -{ - unsigned long flags; - DBGINFO(("%s set_txidle(%d)\n", info->device_name, idle_mode)); - spin_lock_irqsave(&info->lock,flags); - info->idle_mode = idle_mode; - if (info->params.mode != MGSL_MODE_ASYNC) - tx_set_idle(info); - spin_unlock_irqrestore(&info->lock,flags); - return 0; -} - -static int tx_enable(struct slgt_info *info, int enable) -{ - unsigned long flags; - DBGINFO(("%s tx_enable(%d)\n", info->device_name, enable)); - spin_lock_irqsave(&info->lock,flags); - if (enable) { - if (!info->tx_enabled) - tx_start(info); - } else { - if (info->tx_enabled) - tx_stop(info); - } - spin_unlock_irqrestore(&info->lock,flags); - return 0; -} - -/* - * abort transmit HDLC frame - */ -static int tx_abort(struct slgt_info *info) -{ - unsigned long flags; - DBGINFO(("%s tx_abort\n", info->device_name)); - spin_lock_irqsave(&info->lock,flags); - tdma_reset(info); - spin_unlock_irqrestore(&info->lock,flags); - return 0; -} - -static int rx_enable(struct slgt_info *info, int enable) -{ - unsigned long flags; - unsigned int rbuf_fill_level; - DBGINFO(("%s rx_enable(%08x)\n", info->device_name, enable)); - spin_lock_irqsave(&info->lock,flags); - /* - * enable[31..16] = receive DMA buffer fill level - * 0 = noop (leave fill level unchanged) - * fill level must be multiple of 4 and <= buffer size - */ - rbuf_fill_level = ((unsigned int)enable) >> 16; - if (rbuf_fill_level) { - if ((rbuf_fill_level > DMABUFSIZE) || (rbuf_fill_level % 4)) { - spin_unlock_irqrestore(&info->lock, flags); - return -EINVAL; - } - info->rbuf_fill_level = rbuf_fill_level; - if (rbuf_fill_level < 128) - info->rx_pio = 1; /* PIO mode */ - else - info->rx_pio = 0; /* DMA mode */ - rx_stop(info); /* restart receiver to use new fill level */ - } - - /* - * enable[1..0] = receiver enable command - * 0 = disable - * 1 = enable - * 2 = enable or force hunt mode if already enabled - */ - enable &= 3; - if (enable) { - if (!info->rx_enabled) - rx_start(info); - else if (enable == 2) { - /* force hunt mode (write 1 to RCR[3]) */ - wr_reg16(info, RCR, rd_reg16(info, RCR) | BIT3); - } - } else { - if (info->rx_enabled) - rx_stop(info); - } - spin_unlock_irqrestore(&info->lock,flags); - return 0; -} - -/* - * wait for specified event to occur - */ -static int wait_mgsl_event(struct slgt_info *info, int __user *mask_ptr) -{ - unsigned long flags; - int s; - int rc=0; - struct mgsl_icount cprev, cnow; - int events; - int mask; - struct _input_signal_events oldsigs, newsigs; - DECLARE_WAITQUEUE(wait, current); - - if (get_user(mask, mask_ptr)) - return -EFAULT; - - DBGINFO(("%s wait_mgsl_event(%d)\n", info->device_name, mask)); - - spin_lock_irqsave(&info->lock,flags); - - /* return immediately if state matches requested events */ - get_signals(info); - s = info->signals; - - events = mask & - ( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) + - ((s & SerialSignal_DCD) ? MgslEvent_DcdActive:MgslEvent_DcdInactive) + - ((s & SerialSignal_CTS) ? MgslEvent_CtsActive:MgslEvent_CtsInactive) + - ((s & SerialSignal_RI) ? MgslEvent_RiActive :MgslEvent_RiInactive) ); - if (events) { - spin_unlock_irqrestore(&info->lock,flags); - goto exit; - } - - /* save current irq counts */ - cprev = info->icount; - oldsigs = info->input_signal_events; - - /* enable hunt and idle irqs if needed */ - if (mask & (MgslEvent_ExitHuntMode+MgslEvent_IdleReceived)) { - unsigned short val = rd_reg16(info, SCR); - if (!(val & IRQ_RXIDLE)) - wr_reg16(info, SCR, (unsigned short)(val | IRQ_RXIDLE)); - } - - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&info->event_wait_q, &wait); - - spin_unlock_irqrestore(&info->lock,flags); - - for(;;) { - schedule(); - if (signal_pending(current)) { - rc = -ERESTARTSYS; - break; - } - - /* get current irq counts */ - spin_lock_irqsave(&info->lock,flags); - cnow = info->icount; - newsigs = info->input_signal_events; - set_current_state(TASK_INTERRUPTIBLE); - spin_unlock_irqrestore(&info->lock,flags); - - /* if no change, wait aborted for some reason */ - if (newsigs.dsr_up == oldsigs.dsr_up && - newsigs.dsr_down == oldsigs.dsr_down && - newsigs.dcd_up == oldsigs.dcd_up && - newsigs.dcd_down == oldsigs.dcd_down && - newsigs.cts_up == oldsigs.cts_up && - newsigs.cts_down == oldsigs.cts_down && - newsigs.ri_up == oldsigs.ri_up && - newsigs.ri_down == oldsigs.ri_down && - cnow.exithunt == cprev.exithunt && - cnow.rxidle == cprev.rxidle) { - rc = -EIO; - break; - } - - events = mask & - ( (newsigs.dsr_up != oldsigs.dsr_up ? MgslEvent_DsrActive:0) + - (newsigs.dsr_down != oldsigs.dsr_down ? MgslEvent_DsrInactive:0) + - (newsigs.dcd_up != oldsigs.dcd_up ? MgslEvent_DcdActive:0) + - (newsigs.dcd_down != oldsigs.dcd_down ? MgslEvent_DcdInactive:0) + - (newsigs.cts_up != oldsigs.cts_up ? MgslEvent_CtsActive:0) + - (newsigs.cts_down != oldsigs.cts_down ? MgslEvent_CtsInactive:0) + - (newsigs.ri_up != oldsigs.ri_up ? MgslEvent_RiActive:0) + - (newsigs.ri_down != oldsigs.ri_down ? MgslEvent_RiInactive:0) + - (cnow.exithunt != cprev.exithunt ? MgslEvent_ExitHuntMode:0) + - (cnow.rxidle != cprev.rxidle ? MgslEvent_IdleReceived:0) ); - if (events) - break; - - cprev = cnow; - oldsigs = newsigs; - } - - remove_wait_queue(&info->event_wait_q, &wait); - set_current_state(TASK_RUNNING); - - - if (mask & (MgslEvent_ExitHuntMode + MgslEvent_IdleReceived)) { - spin_lock_irqsave(&info->lock,flags); - if (!waitqueue_active(&info->event_wait_q)) { - /* disable enable exit hunt mode/idle rcvd IRQs */ - wr_reg16(info, SCR, - (unsigned short)(rd_reg16(info, SCR) & ~IRQ_RXIDLE)); - } - spin_unlock_irqrestore(&info->lock,flags); - } -exit: - if (rc == 0) - rc = put_user(events, mask_ptr); - return rc; -} - -static int get_interface(struct slgt_info *info, int __user *if_mode) -{ - DBGINFO(("%s get_interface=%x\n", info->device_name, info->if_mode)); - if (put_user(info->if_mode, if_mode)) - return -EFAULT; - return 0; -} - -static int set_interface(struct slgt_info *info, int if_mode) -{ - unsigned long flags; - unsigned short val; - - DBGINFO(("%s set_interface=%x)\n", info->device_name, if_mode)); - spin_lock_irqsave(&info->lock,flags); - info->if_mode = if_mode; - - msc_set_vcr(info); - - /* TCR (tx control) 07 1=RTS driver control */ - val = rd_reg16(info, TCR); - if (info->if_mode & MGSL_INTERFACE_RTS_EN) - val |= BIT7; - else - val &= ~BIT7; - wr_reg16(info, TCR, val); - - spin_unlock_irqrestore(&info->lock,flags); - return 0; -} - -static int get_xsync(struct slgt_info *info, int __user *xsync) -{ - DBGINFO(("%s get_xsync=%x\n", info->device_name, info->xsync)); - if (put_user(info->xsync, xsync)) - return -EFAULT; - return 0; -} - -/* - * set extended sync pattern (1 to 4 bytes) for extended sync mode - * - * sync pattern is contained in least significant bytes of value - * most significant byte of sync pattern is oldest (1st sent/detected) - */ -static int set_xsync(struct slgt_info *info, int xsync) -{ - unsigned long flags; - - DBGINFO(("%s set_xsync=%x)\n", info->device_name, xsync)); - spin_lock_irqsave(&info->lock, flags); - info->xsync = xsync; - wr_reg32(info, XSR, xsync); - spin_unlock_irqrestore(&info->lock, flags); - return 0; -} - -static int get_xctrl(struct slgt_info *info, int __user *xctrl) -{ - DBGINFO(("%s get_xctrl=%x\n", info->device_name, info->xctrl)); - if (put_user(info->xctrl, xctrl)) - return -EFAULT; - return 0; -} - -/* - * set extended control options - * - * xctrl[31:19] reserved, must be zero - * xctrl[18:17] extended sync pattern length in bytes - * 00 = 1 byte in xsr[7:0] - * 01 = 2 bytes in xsr[15:0] - * 10 = 3 bytes in xsr[23:0] - * 11 = 4 bytes in xsr[31:0] - * xctrl[16] 1 = enable terminal count, 0=disabled - * xctrl[15:0] receive terminal count for fixed length packets - * value is count minus one (0 = 1 byte packet) - * when terminal count is reached, receiver - * automatically returns to hunt mode and receive - * FIFO contents are flushed to DMA buffers with - * end of frame (EOF) status - */ -static int set_xctrl(struct slgt_info *info, int xctrl) -{ - unsigned long flags; - - DBGINFO(("%s set_xctrl=%x)\n", info->device_name, xctrl)); - spin_lock_irqsave(&info->lock, flags); - info->xctrl = xctrl; - wr_reg32(info, XCR, xctrl); - spin_unlock_irqrestore(&info->lock, flags); - return 0; -} - -/* - * set general purpose IO pin state and direction - * - * user_gpio fields: - * state each bit indicates a pin state - * smask set bit indicates pin state to set - * dir each bit indicates a pin direction (0=input, 1=output) - * dmask set bit indicates pin direction to set - */ -static int set_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio) -{ - unsigned long flags; - struct gpio_desc gpio; - __u32 data; - - if (!info->gpio_present) - return -EINVAL; - if (copy_from_user(&gpio, user_gpio, sizeof(gpio))) - return -EFAULT; - DBGINFO(("%s set_gpio state=%08x smask=%08x dir=%08x dmask=%08x\n", - info->device_name, gpio.state, gpio.smask, - gpio.dir, gpio.dmask)); - - spin_lock_irqsave(&info->port_array[0]->lock, flags); - if (gpio.dmask) { - data = rd_reg32(info, IODR); - data |= gpio.dmask & gpio.dir; - data &= ~(gpio.dmask & ~gpio.dir); - wr_reg32(info, IODR, data); - } - if (gpio.smask) { - data = rd_reg32(info, IOVR); - data |= gpio.smask & gpio.state; - data &= ~(gpio.smask & ~gpio.state); - wr_reg32(info, IOVR, data); - } - spin_unlock_irqrestore(&info->port_array[0]->lock, flags); - - return 0; -} - -/* - * get general purpose IO pin state and direction - */ -static int get_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio) -{ - struct gpio_desc gpio; - if (!info->gpio_present) - return -EINVAL; - gpio.state = rd_reg32(info, IOVR); - gpio.smask = 0xffffffff; - gpio.dir = rd_reg32(info, IODR); - gpio.dmask = 0xffffffff; - if (copy_to_user(user_gpio, &gpio, sizeof(gpio))) - return -EFAULT; - DBGINFO(("%s get_gpio state=%08x dir=%08x\n", - info->device_name, gpio.state, gpio.dir)); - return 0; -} - -/* - * conditional wait facility - */ -static void init_cond_wait(struct cond_wait *w, unsigned int data) -{ - init_waitqueue_head(&w->q); - init_waitqueue_entry(&w->wait, current); - w->data = data; -} - -static void add_cond_wait(struct cond_wait **head, struct cond_wait *w) -{ - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&w->q, &w->wait); - w->next = *head; - *head = w; -} - -static void remove_cond_wait(struct cond_wait **head, struct cond_wait *cw) -{ - struct cond_wait *w, *prev; - remove_wait_queue(&cw->q, &cw->wait); - set_current_state(TASK_RUNNING); - for (w = *head, prev = NULL ; w != NULL ; prev = w, w = w->next) { - if (w == cw) { - if (prev != NULL) - prev->next = w->next; - else - *head = w->next; - break; - } - } -} - -static void flush_cond_wait(struct cond_wait **head) -{ - while (*head != NULL) { - wake_up_interruptible(&(*head)->q); - *head = (*head)->next; - } -} - -/* - * wait for general purpose I/O pin(s) to enter specified state - * - * user_gpio fields: - * state - bit indicates target pin state - * smask - set bit indicates watched pin - * - * The wait ends when at least one watched pin enters the specified - * state. When 0 (no error) is returned, user_gpio->state is set to the - * state of all GPIO pins when the wait ends. - * - * Note: Each pin may be a dedicated input, dedicated output, or - * configurable input/output. The number and configuration of pins - * varies with the specific adapter model. Only input pins (dedicated - * or configured) can be monitored with this function. - */ -static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio) -{ - unsigned long flags; - int rc = 0; - struct gpio_desc gpio; - struct cond_wait wait; - u32 state; - - if (!info->gpio_present) - return -EINVAL; - if (copy_from_user(&gpio, user_gpio, sizeof(gpio))) - return -EFAULT; - DBGINFO(("%s wait_gpio() state=%08x smask=%08x\n", - info->device_name, gpio.state, gpio.smask)); - /* ignore output pins identified by set IODR bit */ - if ((gpio.smask &= ~rd_reg32(info, IODR)) == 0) - return -EINVAL; - init_cond_wait(&wait, gpio.smask); - - spin_lock_irqsave(&info->port_array[0]->lock, flags); - /* enable interrupts for watched pins */ - wr_reg32(info, IOER, rd_reg32(info, IOER) | gpio.smask); - /* get current pin states */ - state = rd_reg32(info, IOVR); - - if (gpio.smask & ~(state ^ gpio.state)) { - /* already in target state */ - gpio.state = state; - } else { - /* wait for target state */ - add_cond_wait(&info->gpio_wait_q, &wait); - spin_unlock_irqrestore(&info->port_array[0]->lock, flags); - schedule(); - if (signal_pending(current)) - rc = -ERESTARTSYS; - else - gpio.state = wait.data; - spin_lock_irqsave(&info->port_array[0]->lock, flags); - remove_cond_wait(&info->gpio_wait_q, &wait); - } - - /* disable all GPIO interrupts if no waiting processes */ - if (info->gpio_wait_q == NULL) - wr_reg32(info, IOER, 0); - spin_unlock_irqrestore(&info->port_array[0]->lock, flags); - - if ((rc == 0) && copy_to_user(user_gpio, &gpio, sizeof(gpio))) - rc = -EFAULT; - return rc; -} - -static int modem_input_wait(struct slgt_info *info,int arg) -{ - unsigned long flags; - int rc; - struct mgsl_icount cprev, cnow; - DECLARE_WAITQUEUE(wait, current); - - /* save current irq counts */ - spin_lock_irqsave(&info->lock,flags); - cprev = info->icount; - add_wait_queue(&info->status_event_wait_q, &wait); - set_current_state(TASK_INTERRUPTIBLE); - spin_unlock_irqrestore(&info->lock,flags); - - for(;;) { - schedule(); - if (signal_pending(current)) { - rc = -ERESTARTSYS; - break; - } - - /* get new irq counts */ - spin_lock_irqsave(&info->lock,flags); - cnow = info->icount; - set_current_state(TASK_INTERRUPTIBLE); - spin_unlock_irqrestore(&info->lock,flags); - - /* if no change, wait aborted for some reason */ - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { - rc = -EIO; - break; - } - - /* check for change in caller specified modem input */ - if ((arg & TIOCM_RNG && cnow.rng != cprev.rng) || - (arg & TIOCM_DSR && cnow.dsr != cprev.dsr) || - (arg & TIOCM_CD && cnow.dcd != cprev.dcd) || - (arg & TIOCM_CTS && cnow.cts != cprev.cts)) { - rc = 0; - break; - } - - cprev = cnow; - } - remove_wait_queue(&info->status_event_wait_q, &wait); - set_current_state(TASK_RUNNING); - return rc; -} - -/* - * return state of serial control and status signals - */ -static int tiocmget(struct tty_struct *tty) -{ - struct slgt_info *info = tty->driver_data; - unsigned int result; - unsigned long flags; - - spin_lock_irqsave(&info->lock,flags); - get_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - - result = ((info->signals & SerialSignal_RTS) ? TIOCM_RTS:0) + - ((info->signals & SerialSignal_DTR) ? TIOCM_DTR:0) + - ((info->signals & SerialSignal_DCD) ? TIOCM_CAR:0) + - ((info->signals & SerialSignal_RI) ? TIOCM_RNG:0) + - ((info->signals & SerialSignal_DSR) ? TIOCM_DSR:0) + - ((info->signals & SerialSignal_CTS) ? TIOCM_CTS:0); - - DBGINFO(("%s tiocmget value=%08X\n", info->device_name, result)); - return result; -} - -/* - * set modem control signals (DTR/RTS) - * - * cmd signal command: TIOCMBIS = set bit TIOCMBIC = clear bit - * TIOCMSET = set/clear signal values - * value bit mask for command - */ -static int tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - DBGINFO(("%s tiocmset(%x,%x)\n", info->device_name, set, clear)); - - if (set & TIOCM_RTS) - info->signals |= SerialSignal_RTS; - if (set & TIOCM_DTR) - info->signals |= SerialSignal_DTR; - if (clear & TIOCM_RTS) - info->signals &= ~SerialSignal_RTS; - if (clear & TIOCM_DTR) - info->signals &= ~SerialSignal_DTR; - - spin_lock_irqsave(&info->lock,flags); - set_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - return 0; -} - -static int carrier_raised(struct tty_port *port) -{ - unsigned long flags; - struct slgt_info *info = container_of(port, struct slgt_info, port); - - spin_lock_irqsave(&info->lock,flags); - get_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - return (info->signals & SerialSignal_DCD) ? 1 : 0; -} - -static void dtr_rts(struct tty_port *port, int on) -{ - unsigned long flags; - struct slgt_info *info = container_of(port, struct slgt_info, port); - - spin_lock_irqsave(&info->lock,flags); - if (on) - info->signals |= SerialSignal_RTS + SerialSignal_DTR; - else - info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); - set_signals(info); - spin_unlock_irqrestore(&info->lock,flags); -} - - -/* - * block current process until the device is ready to open - */ -static int block_til_ready(struct tty_struct *tty, struct file *filp, - struct slgt_info *info) -{ - DECLARE_WAITQUEUE(wait, current); - int retval; - bool do_clocal = false; - bool extra_count = false; - unsigned long flags; - int cd; - struct tty_port *port = &info->port; - - DBGINFO(("%s block_til_ready\n", tty->driver->name)); - - if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ - /* nonblock mode is set or port is not enabled */ - port->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - if (tty->termios->c_cflag & CLOCAL) - do_clocal = true; - - /* Wait for carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, port->count is dropped by one, so that - * close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - - retval = 0; - add_wait_queue(&port->open_wait, &wait); - - spin_lock_irqsave(&info->lock, flags); - if (!tty_hung_up_p(filp)) { - extra_count = true; - port->count--; - } - spin_unlock_irqrestore(&info->lock, flags); - port->blocked_open++; - - while (1) { - if ((tty->termios->c_cflag & CBAUD)) - tty_port_raise_dtr_rts(port); - - set_current_state(TASK_INTERRUPTIBLE); - - if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){ - retval = (port->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS; - break; - } - - cd = tty_port_carrier_raised(port); - - if (!(port->flags & ASYNC_CLOSING) && (do_clocal || cd )) - break; - - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } - - DBGINFO(("%s block_til_ready wait\n", tty->driver->name)); - tty_unlock(); - schedule(); - tty_lock(); - } - - set_current_state(TASK_RUNNING); - remove_wait_queue(&port->open_wait, &wait); - - if (extra_count) - port->count++; - port->blocked_open--; - - if (!retval) - port->flags |= ASYNC_NORMAL_ACTIVE; - - DBGINFO(("%s block_til_ready ready, rc=%d\n", tty->driver->name, retval)); - return retval; -} - -static int alloc_tmp_rbuf(struct slgt_info *info) -{ - info->tmp_rbuf = kmalloc(info->max_frame_size + 5, GFP_KERNEL); - if (info->tmp_rbuf == NULL) - return -ENOMEM; - return 0; -} - -static void free_tmp_rbuf(struct slgt_info *info) -{ - kfree(info->tmp_rbuf); - info->tmp_rbuf = NULL; -} - -/* - * allocate DMA descriptor lists. - */ -static int alloc_desc(struct slgt_info *info) -{ - unsigned int i; - unsigned int pbufs; - - /* allocate memory to hold descriptor lists */ - info->bufs = pci_alloc_consistent(info->pdev, DESC_LIST_SIZE, &info->bufs_dma_addr); - if (info->bufs == NULL) - return -ENOMEM; - - memset(info->bufs, 0, DESC_LIST_SIZE); - - info->rbufs = (struct slgt_desc*)info->bufs; - info->tbufs = ((struct slgt_desc*)info->bufs) + info->rbuf_count; - - pbufs = (unsigned int)info->bufs_dma_addr; - - /* - * Build circular lists of descriptors - */ - - for (i=0; i < info->rbuf_count; i++) { - /* physical address of this descriptor */ - info->rbufs[i].pdesc = pbufs + (i * sizeof(struct slgt_desc)); - - /* physical address of next descriptor */ - if (i == info->rbuf_count - 1) - info->rbufs[i].next = cpu_to_le32(pbufs); - else - info->rbufs[i].next = cpu_to_le32(pbufs + ((i+1) * sizeof(struct slgt_desc))); - set_desc_count(info->rbufs[i], DMABUFSIZE); - } - - for (i=0; i < info->tbuf_count; i++) { - /* physical address of this descriptor */ - info->tbufs[i].pdesc = pbufs + ((info->rbuf_count + i) * sizeof(struct slgt_desc)); - - /* physical address of next descriptor */ - if (i == info->tbuf_count - 1) - info->tbufs[i].next = cpu_to_le32(pbufs + info->rbuf_count * sizeof(struct slgt_desc)); - else - info->tbufs[i].next = cpu_to_le32(pbufs + ((info->rbuf_count + i + 1) * sizeof(struct slgt_desc))); - } - - return 0; -} - -static void free_desc(struct slgt_info *info) -{ - if (info->bufs != NULL) { - pci_free_consistent(info->pdev, DESC_LIST_SIZE, info->bufs, info->bufs_dma_addr); - info->bufs = NULL; - info->rbufs = NULL; - info->tbufs = NULL; - } -} - -static int alloc_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count) -{ - int i; - for (i=0; i < count; i++) { - if ((bufs[i].buf = pci_alloc_consistent(info->pdev, DMABUFSIZE, &bufs[i].buf_dma_addr)) == NULL) - return -ENOMEM; - bufs[i].pbuf = cpu_to_le32((unsigned int)bufs[i].buf_dma_addr); - } - return 0; -} - -static void free_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count) -{ - int i; - for (i=0; i < count; i++) { - if (bufs[i].buf == NULL) - continue; - pci_free_consistent(info->pdev, DMABUFSIZE, bufs[i].buf, bufs[i].buf_dma_addr); - bufs[i].buf = NULL; - } -} - -static int alloc_dma_bufs(struct slgt_info *info) -{ - info->rbuf_count = 32; - info->tbuf_count = 32; - - if (alloc_desc(info) < 0 || - alloc_bufs(info, info->rbufs, info->rbuf_count) < 0 || - alloc_bufs(info, info->tbufs, info->tbuf_count) < 0 || - alloc_tmp_rbuf(info) < 0) { - DBGERR(("%s DMA buffer alloc fail\n", info->device_name)); - return -ENOMEM; - } - reset_rbufs(info); - return 0; -} - -static void free_dma_bufs(struct slgt_info *info) -{ - if (info->bufs) { - free_bufs(info, info->rbufs, info->rbuf_count); - free_bufs(info, info->tbufs, info->tbuf_count); - free_desc(info); - } - free_tmp_rbuf(info); -} - -static int claim_resources(struct slgt_info *info) -{ - if (request_mem_region(info->phys_reg_addr, SLGT_REG_SIZE, "synclink_gt") == NULL) { - DBGERR(("%s reg addr conflict, addr=%08X\n", - info->device_name, info->phys_reg_addr)); - info->init_error = DiagStatus_AddressConflict; - goto errout; - } - else - info->reg_addr_requested = true; - - info->reg_addr = ioremap_nocache(info->phys_reg_addr, SLGT_REG_SIZE); - if (!info->reg_addr) { - DBGERR(("%s cant map device registers, addr=%08X\n", - info->device_name, info->phys_reg_addr)); - info->init_error = DiagStatus_CantAssignPciResources; - goto errout; - } - return 0; - -errout: - release_resources(info); - return -ENODEV; -} - -static void release_resources(struct slgt_info *info) -{ - if (info->irq_requested) { - free_irq(info->irq_level, info); - info->irq_requested = false; - } - - if (info->reg_addr_requested) { - release_mem_region(info->phys_reg_addr, SLGT_REG_SIZE); - info->reg_addr_requested = false; - } - - if (info->reg_addr) { - iounmap(info->reg_addr); - info->reg_addr = NULL; - } -} - -/* Add the specified device instance data structure to the - * global linked list of devices and increment the device count. - */ -static void add_device(struct slgt_info *info) -{ - char *devstr; - - info->next_device = NULL; - info->line = slgt_device_count; - sprintf(info->device_name, "%s%d", tty_dev_prefix, info->line); - - if (info->line < MAX_DEVICES) { - if (maxframe[info->line]) - info->max_frame_size = maxframe[info->line]; - } - - slgt_device_count++; - - if (!slgt_device_list) - slgt_device_list = info; - else { - struct slgt_info *current_dev = slgt_device_list; - while(current_dev->next_device) - current_dev = current_dev->next_device; - current_dev->next_device = info; - } - - if (info->max_frame_size < 4096) - info->max_frame_size = 4096; - else if (info->max_frame_size > 65535) - info->max_frame_size = 65535; - - switch(info->pdev->device) { - case SYNCLINK_GT_DEVICE_ID: - devstr = "GT"; - break; - case SYNCLINK_GT2_DEVICE_ID: - devstr = "GT2"; - break; - case SYNCLINK_GT4_DEVICE_ID: - devstr = "GT4"; - break; - case SYNCLINK_AC_DEVICE_ID: - devstr = "AC"; - info->params.mode = MGSL_MODE_ASYNC; - break; - default: - devstr = "(unknown model)"; - } - printk("SyncLink %s %s IO=%08x IRQ=%d MaxFrameSize=%u\n", - devstr, info->device_name, info->phys_reg_addr, - info->irq_level, info->max_frame_size); - -#if SYNCLINK_GENERIC_HDLC - hdlcdev_init(info); -#endif -} - -static const struct tty_port_operations slgt_port_ops = { - .carrier_raised = carrier_raised, - .dtr_rts = dtr_rts, -}; - -/* - * allocate device instance structure, return NULL on failure - */ -static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev) -{ - struct slgt_info *info; - - info = kzalloc(sizeof(struct slgt_info), GFP_KERNEL); - - if (!info) { - DBGERR(("%s device alloc failed adapter=%d port=%d\n", - driver_name, adapter_num, port_num)); - } else { - tty_port_init(&info->port); - info->port.ops = &slgt_port_ops; - info->magic = MGSL_MAGIC; - INIT_WORK(&info->task, bh_handler); - info->max_frame_size = 4096; - info->base_clock = 14745600; - info->rbuf_fill_level = DMABUFSIZE; - info->port.close_delay = 5*HZ/10; - info->port.closing_wait = 30*HZ; - init_waitqueue_head(&info->status_event_wait_q); - init_waitqueue_head(&info->event_wait_q); - spin_lock_init(&info->netlock); - memcpy(&info->params,&default_params,sizeof(MGSL_PARAMS)); - info->idle_mode = HDLC_TXIDLE_FLAGS; - info->adapter_num = adapter_num; - info->port_num = port_num; - - setup_timer(&info->tx_timer, tx_timeout, (unsigned long)info); - setup_timer(&info->rx_timer, rx_timeout, (unsigned long)info); - - /* Copy configuration info to device instance data */ - info->pdev = pdev; - info->irq_level = pdev->irq; - info->phys_reg_addr = pci_resource_start(pdev,0); - - info->bus_type = MGSL_BUS_TYPE_PCI; - info->irq_flags = IRQF_SHARED; - - info->init_error = -1; /* assume error, set to 0 on successful init */ - } - - return info; -} - -static void device_init(int adapter_num, struct pci_dev *pdev) -{ - struct slgt_info *port_array[SLGT_MAX_PORTS]; - int i; - int port_count = 1; - - if (pdev->device == SYNCLINK_GT2_DEVICE_ID) - port_count = 2; - else if (pdev->device == SYNCLINK_GT4_DEVICE_ID) - port_count = 4; - - /* allocate device instances for all ports */ - for (i=0; i < port_count; ++i) { - port_array[i] = alloc_dev(adapter_num, i, pdev); - if (port_array[i] == NULL) { - for (--i; i >= 0; --i) - kfree(port_array[i]); - return; - } - } - - /* give copy of port_array to all ports and add to device list */ - for (i=0; i < port_count; ++i) { - memcpy(port_array[i]->port_array, port_array, sizeof(port_array)); - add_device(port_array[i]); - port_array[i]->port_count = port_count; - spin_lock_init(&port_array[i]->lock); - } - - /* Allocate and claim adapter resources */ - if (!claim_resources(port_array[0])) { - - alloc_dma_bufs(port_array[0]); - - /* copy resource information from first port to others */ - for (i = 1; i < port_count; ++i) { - port_array[i]->irq_level = port_array[0]->irq_level; - port_array[i]->reg_addr = port_array[0]->reg_addr; - alloc_dma_bufs(port_array[i]); - } - - if (request_irq(port_array[0]->irq_level, - slgt_interrupt, - port_array[0]->irq_flags, - port_array[0]->device_name, - port_array[0]) < 0) { - DBGERR(("%s request_irq failed IRQ=%d\n", - port_array[0]->device_name, - port_array[0]->irq_level)); - } else { - port_array[0]->irq_requested = true; - adapter_test(port_array[0]); - for (i=1 ; i < port_count ; i++) { - port_array[i]->init_error = port_array[0]->init_error; - port_array[i]->gpio_present = port_array[0]->gpio_present; - } - } - } - - for (i=0; i < port_count; ++i) - tty_register_device(serial_driver, port_array[i]->line, &(port_array[i]->pdev->dev)); -} - -static int __devinit init_one(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - if (pci_enable_device(dev)) { - printk("error enabling pci device %p\n", dev); - return -EIO; - } - pci_set_master(dev); - device_init(slgt_device_count, dev); - return 0; -} - -static void __devexit remove_one(struct pci_dev *dev) -{ -} - -static const struct tty_operations ops = { - .open = open, - .close = close, - .write = write, - .put_char = put_char, - .flush_chars = flush_chars, - .write_room = write_room, - .chars_in_buffer = chars_in_buffer, - .flush_buffer = flush_buffer, - .ioctl = ioctl, - .compat_ioctl = slgt_compat_ioctl, - .throttle = throttle, - .unthrottle = unthrottle, - .send_xchar = send_xchar, - .break_ctl = set_break, - .wait_until_sent = wait_until_sent, - .set_termios = set_termios, - .stop = tx_hold, - .start = tx_release, - .hangup = hangup, - .tiocmget = tiocmget, - .tiocmset = tiocmset, - .get_icount = get_icount, - .proc_fops = &synclink_gt_proc_fops, -}; - -static void slgt_cleanup(void) -{ - int rc; - struct slgt_info *info; - struct slgt_info *tmp; - - printk(KERN_INFO "unload %s\n", driver_name); - - if (serial_driver) { - for (info=slgt_device_list ; info != NULL ; info=info->next_device) - tty_unregister_device(serial_driver, info->line); - if ((rc = tty_unregister_driver(serial_driver))) - DBGERR(("tty_unregister_driver error=%d\n", rc)); - put_tty_driver(serial_driver); - } - - /* reset devices */ - info = slgt_device_list; - while(info) { - reset_port(info); - info = info->next_device; - } - - /* release devices */ - info = slgt_device_list; - while(info) { -#if SYNCLINK_GENERIC_HDLC - hdlcdev_exit(info); -#endif - free_dma_bufs(info); - free_tmp_rbuf(info); - if (info->port_num == 0) - release_resources(info); - tmp = info; - info = info->next_device; - kfree(tmp); - } - - if (pci_registered) - pci_unregister_driver(&pci_driver); -} - -/* - * Driver initialization entry point. - */ -static int __init slgt_init(void) -{ - int rc; - - printk(KERN_INFO "%s\n", driver_name); - - serial_driver = alloc_tty_driver(MAX_DEVICES); - if (!serial_driver) { - printk("%s can't allocate tty driver\n", driver_name); - return -ENOMEM; - } - - /* Initialize the tty_driver structure */ - - serial_driver->owner = THIS_MODULE; - serial_driver->driver_name = tty_driver_name; - serial_driver->name = tty_dev_prefix; - serial_driver->major = ttymajor; - serial_driver->minor_start = 64; - serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - serial_driver->subtype = SERIAL_TYPE_NORMAL; - serial_driver->init_termios = tty_std_termios; - serial_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - serial_driver->init_termios.c_ispeed = 9600; - serial_driver->init_termios.c_ospeed = 9600; - serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; - tty_set_operations(serial_driver, &ops); - if ((rc = tty_register_driver(serial_driver)) < 0) { - DBGERR(("%s can't register serial driver\n", driver_name)); - put_tty_driver(serial_driver); - serial_driver = NULL; - goto error; - } - - printk(KERN_INFO "%s, tty major#%d\n", - driver_name, serial_driver->major); - - slgt_device_count = 0; - if ((rc = pci_register_driver(&pci_driver)) < 0) { - printk("%s pci_register_driver error=%d\n", driver_name, rc); - goto error; - } - pci_registered = true; - - if (!slgt_device_list) - printk("%s no devices found\n",driver_name); - - return 0; - -error: - slgt_cleanup(); - return rc; -} - -static void __exit slgt_exit(void) -{ - slgt_cleanup(); -} - -module_init(slgt_init); -module_exit(slgt_exit); - -/* - * register access routines - */ - -#define CALC_REGADDR() \ - unsigned long reg_addr = ((unsigned long)info->reg_addr) + addr; \ - if (addr >= 0x80) \ - reg_addr += (info->port_num) * 32; \ - else if (addr >= 0x40) \ - reg_addr += (info->port_num) * 16; - -static __u8 rd_reg8(struct slgt_info *info, unsigned int addr) -{ - CALC_REGADDR(); - return readb((void __iomem *)reg_addr); -} - -static void wr_reg8(struct slgt_info *info, unsigned int addr, __u8 value) -{ - CALC_REGADDR(); - writeb(value, (void __iomem *)reg_addr); -} - -static __u16 rd_reg16(struct slgt_info *info, unsigned int addr) -{ - CALC_REGADDR(); - return readw((void __iomem *)reg_addr); -} - -static void wr_reg16(struct slgt_info *info, unsigned int addr, __u16 value) -{ - CALC_REGADDR(); - writew(value, (void __iomem *)reg_addr); -} - -static __u32 rd_reg32(struct slgt_info *info, unsigned int addr) -{ - CALC_REGADDR(); - return readl((void __iomem *)reg_addr); -} - -static void wr_reg32(struct slgt_info *info, unsigned int addr, __u32 value) -{ - CALC_REGADDR(); - writel(value, (void __iomem *)reg_addr); -} - -static void rdma_reset(struct slgt_info *info) -{ - unsigned int i; - - /* set reset bit */ - wr_reg32(info, RDCSR, BIT1); - - /* wait for enable bit cleared */ - for(i=0 ; i < 1000 ; i++) - if (!(rd_reg32(info, RDCSR) & BIT0)) - break; -} - -static void tdma_reset(struct slgt_info *info) -{ - unsigned int i; - - /* set reset bit */ - wr_reg32(info, TDCSR, BIT1); - - /* wait for enable bit cleared */ - for(i=0 ; i < 1000 ; i++) - if (!(rd_reg32(info, TDCSR) & BIT0)) - break; -} - -/* - * enable internal loopback - * TxCLK and RxCLK are generated from BRG - * and TxD is looped back to RxD internally. - */ -static void enable_loopback(struct slgt_info *info) -{ - /* SCR (serial control) BIT2=looopback enable */ - wr_reg16(info, SCR, (unsigned short)(rd_reg16(info, SCR) | BIT2)); - - if (info->params.mode != MGSL_MODE_ASYNC) { - /* CCR (clock control) - * 07..05 tx clock source (010 = BRG) - * 04..02 rx clock source (010 = BRG) - * 01 auxclk enable (0 = disable) - * 00 BRG enable (1 = enable) - * - * 0100 1001 - */ - wr_reg8(info, CCR, 0x49); - - /* set speed if available, otherwise use default */ - if (info->params.clock_speed) - set_rate(info, info->params.clock_speed); - else - set_rate(info, 3686400); - } -} - -/* - * set baud rate generator to specified rate - */ -static void set_rate(struct slgt_info *info, u32 rate) -{ - unsigned int div; - unsigned int osc = info->base_clock; - - /* div = osc/rate - 1 - * - * Round div up if osc/rate is not integer to - * force to next slowest rate. - */ - - if (rate) { - div = osc/rate; - if (!(osc % rate) && div) - div--; - wr_reg16(info, BDR, (unsigned short)div); - } -} - -static void rx_stop(struct slgt_info *info) -{ - unsigned short val; - - /* disable and reset receiver */ - val = rd_reg16(info, RCR) & ~BIT1; /* clear enable bit */ - wr_reg16(info, RCR, (unsigned short)(val | BIT2)); /* set reset bit */ - wr_reg16(info, RCR, val); /* clear reset bit */ - - slgt_irq_off(info, IRQ_RXOVER + IRQ_RXDATA + IRQ_RXIDLE); - - /* clear pending rx interrupts */ - wr_reg16(info, SSR, IRQ_RXIDLE + IRQ_RXOVER); - - rdma_reset(info); - - info->rx_enabled = false; - info->rx_restart = false; -} - -static void rx_start(struct slgt_info *info) -{ - unsigned short val; - - slgt_irq_off(info, IRQ_RXOVER + IRQ_RXDATA); - - /* clear pending rx overrun IRQ */ - wr_reg16(info, SSR, IRQ_RXOVER); - - /* reset and disable receiver */ - val = rd_reg16(info, RCR) & ~BIT1; /* clear enable bit */ - wr_reg16(info, RCR, (unsigned short)(val | BIT2)); /* set reset bit */ - wr_reg16(info, RCR, val); /* clear reset bit */ - - rdma_reset(info); - reset_rbufs(info); - - if (info->rx_pio) { - /* rx request when rx FIFO not empty */ - wr_reg16(info, SCR, (unsigned short)(rd_reg16(info, SCR) & ~BIT14)); - slgt_irq_on(info, IRQ_RXDATA); - if (info->params.mode == MGSL_MODE_ASYNC) { - /* enable saving of rx status */ - wr_reg32(info, RDCSR, BIT6); - } - } else { - /* rx request when rx FIFO half full */ - wr_reg16(info, SCR, (unsigned short)(rd_reg16(info, SCR) | BIT14)); - /* set 1st descriptor address */ - wr_reg32(info, RDDAR, info->rbufs[0].pdesc); - - if (info->params.mode != MGSL_MODE_ASYNC) { - /* enable rx DMA and DMA interrupt */ - wr_reg32(info, RDCSR, (BIT2 + BIT0)); - } else { - /* enable saving of rx status, rx DMA and DMA interrupt */ - wr_reg32(info, RDCSR, (BIT6 + BIT2 + BIT0)); - } - } - - slgt_irq_on(info, IRQ_RXOVER); - - /* enable receiver */ - wr_reg16(info, RCR, (unsigned short)(rd_reg16(info, RCR) | BIT1)); - - info->rx_restart = false; - info->rx_enabled = true; -} - -static void tx_start(struct slgt_info *info) -{ - if (!info->tx_enabled) { - wr_reg16(info, TCR, - (unsigned short)((rd_reg16(info, TCR) | BIT1) & ~BIT2)); - info->tx_enabled = true; - } - - if (desc_count(info->tbufs[info->tbuf_start])) { - info->drop_rts_on_tx_done = false; - - if (info->params.mode != MGSL_MODE_ASYNC) { - if (info->params.flags & HDLC_FLAG_AUTO_RTS) { - get_signals(info); - if (!(info->signals & SerialSignal_RTS)) { - info->signals |= SerialSignal_RTS; - set_signals(info); - info->drop_rts_on_tx_done = true; - } - } - - slgt_irq_off(info, IRQ_TXDATA); - slgt_irq_on(info, IRQ_TXUNDER + IRQ_TXIDLE); - /* clear tx idle and underrun status bits */ - wr_reg16(info, SSR, (unsigned short)(IRQ_TXIDLE + IRQ_TXUNDER)); - } else { - slgt_irq_off(info, IRQ_TXDATA); - slgt_irq_on(info, IRQ_TXIDLE); - /* clear tx idle status bit */ - wr_reg16(info, SSR, IRQ_TXIDLE); - } - /* set 1st descriptor address and start DMA */ - wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc); - wr_reg32(info, TDCSR, BIT2 + BIT0); - info->tx_active = true; - } -} - -static void tx_stop(struct slgt_info *info) -{ - unsigned short val; - - del_timer(&info->tx_timer); - - tdma_reset(info); - - /* reset and disable transmitter */ - val = rd_reg16(info, TCR) & ~BIT1; /* clear enable bit */ - wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */ - - slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER); - - /* clear tx idle and underrun status bit */ - wr_reg16(info, SSR, (unsigned short)(IRQ_TXIDLE + IRQ_TXUNDER)); - - reset_tbufs(info); - - info->tx_enabled = false; - info->tx_active = false; -} - -static void reset_port(struct slgt_info *info) -{ - if (!info->reg_addr) - return; - - tx_stop(info); - rx_stop(info); - - info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS); - set_signals(info); - - slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); -} - -static void reset_adapter(struct slgt_info *info) -{ - int i; - for (i=0; i < info->port_count; ++i) { - if (info->port_array[i]) - reset_port(info->port_array[i]); - } -} - -static void async_mode(struct slgt_info *info) -{ - unsigned short val; - - slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); - tx_stop(info); - rx_stop(info); - - /* TCR (tx control) - * - * 15..13 mode, 010=async - * 12..10 encoding, 000=NRZ - * 09 parity enable - * 08 1=odd parity, 0=even parity - * 07 1=RTS driver control - * 06 1=break enable - * 05..04 character length - * 00=5 bits - * 01=6 bits - * 10=7 bits - * 11=8 bits - * 03 0=1 stop bit, 1=2 stop bits - * 02 reset - * 01 enable - * 00 auto-CTS enable - */ - val = 0x4000; - - if (info->if_mode & MGSL_INTERFACE_RTS_EN) - val |= BIT7; - - if (info->params.parity != ASYNC_PARITY_NONE) { - val |= BIT9; - if (info->params.parity == ASYNC_PARITY_ODD) - val |= BIT8; - } - - switch (info->params.data_bits) - { - case 6: val |= BIT4; break; - case 7: val |= BIT5; break; - case 8: val |= BIT5 + BIT4; break; - } - - if (info->params.stop_bits != 1) - val |= BIT3; - - if (info->params.flags & HDLC_FLAG_AUTO_CTS) - val |= BIT0; - - wr_reg16(info, TCR, val); - - /* RCR (rx control) - * - * 15..13 mode, 010=async - * 12..10 encoding, 000=NRZ - * 09 parity enable - * 08 1=odd parity, 0=even parity - * 07..06 reserved, must be 0 - * 05..04 character length - * 00=5 bits - * 01=6 bits - * 10=7 bits - * 11=8 bits - * 03 reserved, must be zero - * 02 reset - * 01 enable - * 00 auto-DCD enable - */ - val = 0x4000; - - if (info->params.parity != ASYNC_PARITY_NONE) { - val |= BIT9; - if (info->params.parity == ASYNC_PARITY_ODD) - val |= BIT8; - } - - switch (info->params.data_bits) - { - case 6: val |= BIT4; break; - case 7: val |= BIT5; break; - case 8: val |= BIT5 + BIT4; break; - } - - if (info->params.flags & HDLC_FLAG_AUTO_DCD) - val |= BIT0; - - wr_reg16(info, RCR, val); - - /* CCR (clock control) - * - * 07..05 011 = tx clock source is BRG/16 - * 04..02 010 = rx clock source is BRG - * 01 0 = auxclk disabled - * 00 1 = BRG enabled - * - * 0110 1001 - */ - wr_reg8(info, CCR, 0x69); - - msc_set_vcr(info); - - /* SCR (serial control) - * - * 15 1=tx req on FIFO half empty - * 14 1=rx req on FIFO half full - * 13 tx data IRQ enable - * 12 tx idle IRQ enable - * 11 rx break on IRQ enable - * 10 rx data IRQ enable - * 09 rx break off IRQ enable - * 08 overrun IRQ enable - * 07 DSR IRQ enable - * 06 CTS IRQ enable - * 05 DCD IRQ enable - * 04 RI IRQ enable - * 03 0=16x sampling, 1=8x sampling - * 02 1=txd->rxd internal loopback enable - * 01 reserved, must be zero - * 00 1=master IRQ enable - */ - val = BIT15 + BIT14 + BIT0; - /* JCR[8] : 1 = x8 async mode feature available */ - if ((rd_reg32(info, JCR) & BIT8) && info->params.data_rate && - ((info->base_clock < (info->params.data_rate * 16)) || - (info->base_clock % (info->params.data_rate * 16)))) { - /* use 8x sampling */ - val |= BIT3; - set_rate(info, info->params.data_rate * 8); - } else { - /* use 16x sampling */ - set_rate(info, info->params.data_rate * 16); - } - wr_reg16(info, SCR, val); - - slgt_irq_on(info, IRQ_RXBREAK | IRQ_RXOVER); - - if (info->params.loopback) - enable_loopback(info); -} - -static void sync_mode(struct slgt_info *info) -{ - unsigned short val; - - slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); - tx_stop(info); - rx_stop(info); - - /* TCR (tx control) - * - * 15..13 mode - * 000=HDLC/SDLC - * 001=raw bit synchronous - * 010=asynchronous/isochronous - * 011=monosync byte synchronous - * 100=bisync byte synchronous - * 101=xsync byte synchronous - * 12..10 encoding - * 09 CRC enable - * 08 CRC32 - * 07 1=RTS driver control - * 06 preamble enable - * 05..04 preamble length - * 03 share open/close flag - * 02 reset - * 01 enable - * 00 auto-CTS enable - */ - val = BIT2; - - switch(info->params.mode) { - case MGSL_MODE_XSYNC: - val |= BIT15 + BIT13; - break; - case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; - case MGSL_MODE_BISYNC: val |= BIT15; break; - case MGSL_MODE_RAW: val |= BIT13; break; - } - if (info->if_mode & MGSL_INTERFACE_RTS_EN) - val |= BIT7; - - switch(info->params.encoding) - { - case HDLC_ENCODING_NRZB: val |= BIT10; break; - case HDLC_ENCODING_NRZI_MARK: val |= BIT11; break; - case HDLC_ENCODING_NRZI: val |= BIT11 + BIT10; break; - case HDLC_ENCODING_BIPHASE_MARK: val |= BIT12; break; - case HDLC_ENCODING_BIPHASE_SPACE: val |= BIT12 + BIT10; break; - case HDLC_ENCODING_BIPHASE_LEVEL: val |= BIT12 + BIT11; break; - case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break; - } - - switch (info->params.crc_type & HDLC_CRC_MASK) - { - case HDLC_CRC_16_CCITT: val |= BIT9; break; - case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break; - } - - if (info->params.preamble != HDLC_PREAMBLE_PATTERN_NONE) - val |= BIT6; - - switch (info->params.preamble_length) - { - case HDLC_PREAMBLE_LENGTH_16BITS: val |= BIT5; break; - case HDLC_PREAMBLE_LENGTH_32BITS: val |= BIT4; break; - case HDLC_PREAMBLE_LENGTH_64BITS: val |= BIT5 + BIT4; break; - } - - if (info->params.flags & HDLC_FLAG_AUTO_CTS) - val |= BIT0; - - wr_reg16(info, TCR, val); - - /* TPR (transmit preamble) */ - - switch (info->params.preamble) - { - case HDLC_PREAMBLE_PATTERN_FLAGS: val = 0x7e; break; - case HDLC_PREAMBLE_PATTERN_ONES: val = 0xff; break; - case HDLC_PREAMBLE_PATTERN_ZEROS: val = 0x00; break; - case HDLC_PREAMBLE_PATTERN_10: val = 0x55; break; - case HDLC_PREAMBLE_PATTERN_01: val = 0xaa; break; - default: val = 0x7e; break; - } - wr_reg8(info, TPR, (unsigned char)val); - - /* RCR (rx control) - * - * 15..13 mode - * 000=HDLC/SDLC - * 001=raw bit synchronous - * 010=asynchronous/isochronous - * 011=monosync byte synchronous - * 100=bisync byte synchronous - * 101=xsync byte synchronous - * 12..10 encoding - * 09 CRC enable - * 08 CRC32 - * 07..03 reserved, must be 0 - * 02 reset - * 01 enable - * 00 auto-DCD enable - */ - val = 0; - - switch(info->params.mode) { - case MGSL_MODE_XSYNC: - val |= BIT15 + BIT13; - break; - case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; - case MGSL_MODE_BISYNC: val |= BIT15; break; - case MGSL_MODE_RAW: val |= BIT13; break; - } - - switch(info->params.encoding) - { - case HDLC_ENCODING_NRZB: val |= BIT10; break; - case HDLC_ENCODING_NRZI_MARK: val |= BIT11; break; - case HDLC_ENCODING_NRZI: val |= BIT11 + BIT10; break; - case HDLC_ENCODING_BIPHASE_MARK: val |= BIT12; break; - case HDLC_ENCODING_BIPHASE_SPACE: val |= BIT12 + BIT10; break; - case HDLC_ENCODING_BIPHASE_LEVEL: val |= BIT12 + BIT11; break; - case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break; - } - - switch (info->params.crc_type & HDLC_CRC_MASK) - { - case HDLC_CRC_16_CCITT: val |= BIT9; break; - case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break; - } - - if (info->params.flags & HDLC_FLAG_AUTO_DCD) - val |= BIT0; - - wr_reg16(info, RCR, val); - - /* CCR (clock control) - * - * 07..05 tx clock source - * 04..02 rx clock source - * 01 auxclk enable - * 00 BRG enable - */ - val = 0; - - if (info->params.flags & HDLC_FLAG_TXC_BRG) - { - // when RxC source is DPLL, BRG generates 16X DPLL - // reference clock, so take TxC from BRG/16 to get - // transmit clock at actual data rate - if (info->params.flags & HDLC_FLAG_RXC_DPLL) - val |= BIT6 + BIT5; /* 011, txclk = BRG/16 */ - else - val |= BIT6; /* 010, txclk = BRG */ - } - else if (info->params.flags & HDLC_FLAG_TXC_DPLL) - val |= BIT7; /* 100, txclk = DPLL Input */ - else if (info->params.flags & HDLC_FLAG_TXC_RXCPIN) - val |= BIT5; /* 001, txclk = RXC Input */ - - if (info->params.flags & HDLC_FLAG_RXC_BRG) - val |= BIT3; /* 010, rxclk = BRG */ - else if (info->params.flags & HDLC_FLAG_RXC_DPLL) - val |= BIT4; /* 100, rxclk = DPLL */ - else if (info->params.flags & HDLC_FLAG_RXC_TXCPIN) - val |= BIT2; /* 001, rxclk = TXC Input */ - - if (info->params.clock_speed) - val |= BIT1 + BIT0; - - wr_reg8(info, CCR, (unsigned char)val); - - if (info->params.flags & (HDLC_FLAG_TXC_DPLL + HDLC_FLAG_RXC_DPLL)) - { - // program DPLL mode - switch(info->params.encoding) - { - case HDLC_ENCODING_BIPHASE_MARK: - case HDLC_ENCODING_BIPHASE_SPACE: - val = BIT7; break; - case HDLC_ENCODING_BIPHASE_LEVEL: - case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: - val = BIT7 + BIT6; break; - default: val = BIT6; // NRZ encodings - } - wr_reg16(info, RCR, (unsigned short)(rd_reg16(info, RCR) | val)); - - // DPLL requires a 16X reference clock from BRG - set_rate(info, info->params.clock_speed * 16); - } - else - set_rate(info, info->params.clock_speed); - - tx_set_idle(info); - - msc_set_vcr(info); - - /* SCR (serial control) - * - * 15 1=tx req on FIFO half empty - * 14 1=rx req on FIFO half full - * 13 tx data IRQ enable - * 12 tx idle IRQ enable - * 11 underrun IRQ enable - * 10 rx data IRQ enable - * 09 rx idle IRQ enable - * 08 overrun IRQ enable - * 07 DSR IRQ enable - * 06 CTS IRQ enable - * 05 DCD IRQ enable - * 04 RI IRQ enable - * 03 reserved, must be zero - * 02 1=txd->rxd internal loopback enable - * 01 reserved, must be zero - * 00 1=master IRQ enable - */ - wr_reg16(info, SCR, BIT15 + BIT14 + BIT0); - - if (info->params.loopback) - enable_loopback(info); -} - -/* - * set transmit idle mode - */ -static void tx_set_idle(struct slgt_info *info) -{ - unsigned char val; - unsigned short tcr; - - /* if preamble enabled (tcr[6] == 1) then tx idle size = 8 bits - * else tcr[5:4] = tx idle size: 00 = 8 bits, 01 = 16 bits - */ - tcr = rd_reg16(info, TCR); - if (info->idle_mode & HDLC_TXIDLE_CUSTOM_16) { - /* disable preamble, set idle size to 16 bits */ - tcr = (tcr & ~(BIT6 + BIT5)) | BIT4; - /* MSB of 16 bit idle specified in tx preamble register (TPR) */ - wr_reg8(info, TPR, (unsigned char)((info->idle_mode >> 8) & 0xff)); - } else if (!(tcr & BIT6)) { - /* preamble is disabled, set idle size to 8 bits */ - tcr &= ~(BIT5 + BIT4); - } - wr_reg16(info, TCR, tcr); - - if (info->idle_mode & (HDLC_TXIDLE_CUSTOM_8 | HDLC_TXIDLE_CUSTOM_16)) { - /* LSB of custom tx idle specified in tx idle register */ - val = (unsigned char)(info->idle_mode & 0xff); - } else { - /* standard 8 bit idle patterns */ - switch(info->idle_mode) - { - case HDLC_TXIDLE_FLAGS: val = 0x7e; break; - case HDLC_TXIDLE_ALT_ZEROS_ONES: - case HDLC_TXIDLE_ALT_MARK_SPACE: val = 0xaa; break; - case HDLC_TXIDLE_ZEROS: - case HDLC_TXIDLE_SPACE: val = 0x00; break; - default: val = 0xff; - } - } - - wr_reg8(info, TIR, val); -} - -/* - * get state of V24 status (input) signals - */ -static void get_signals(struct slgt_info *info) -{ - unsigned short status = rd_reg16(info, SSR); - - /* clear all serial signals except DTR and RTS */ - info->signals &= SerialSignal_DTR + SerialSignal_RTS; - - if (status & BIT3) - info->signals |= SerialSignal_DSR; - if (status & BIT2) - info->signals |= SerialSignal_CTS; - if (status & BIT1) - info->signals |= SerialSignal_DCD; - if (status & BIT0) - info->signals |= SerialSignal_RI; -} - -/* - * set V.24 Control Register based on current configuration - */ -static void msc_set_vcr(struct slgt_info *info) -{ - unsigned char val = 0; - - /* VCR (V.24 control) - * - * 07..04 serial IF select - * 03 DTR - * 02 RTS - * 01 LL - * 00 RL - */ - - switch(info->if_mode & MGSL_INTERFACE_MASK) - { - case MGSL_INTERFACE_RS232: - val |= BIT5; /* 0010 */ - break; - case MGSL_INTERFACE_V35: - val |= BIT7 + BIT6 + BIT5; /* 1110 */ - break; - case MGSL_INTERFACE_RS422: - val |= BIT6; /* 0100 */ - break; - } - - if (info->if_mode & MGSL_INTERFACE_MSB_FIRST) - val |= BIT4; - if (info->signals & SerialSignal_DTR) - val |= BIT3; - if (info->signals & SerialSignal_RTS) - val |= BIT2; - if (info->if_mode & MGSL_INTERFACE_LL) - val |= BIT1; - if (info->if_mode & MGSL_INTERFACE_RL) - val |= BIT0; - wr_reg8(info, VCR, val); -} - -/* - * set state of V24 control (output) signals - */ -static void set_signals(struct slgt_info *info) -{ - unsigned char val = rd_reg8(info, VCR); - if (info->signals & SerialSignal_DTR) - val |= BIT3; - else - val &= ~BIT3; - if (info->signals & SerialSignal_RTS) - val |= BIT2; - else - val &= ~BIT2; - wr_reg8(info, VCR, val); -} - -/* - * free range of receive DMA buffers (i to last) - */ -static void free_rbufs(struct slgt_info *info, unsigned int i, unsigned int last) -{ - int done = 0; - - while(!done) { - /* reset current buffer for reuse */ - info->rbufs[i].status = 0; - set_desc_count(info->rbufs[i], info->rbuf_fill_level); - if (i == last) - done = 1; - if (++i == info->rbuf_count) - i = 0; - } - info->rbuf_current = i; -} - -/* - * mark all receive DMA buffers as free - */ -static void reset_rbufs(struct slgt_info *info) -{ - free_rbufs(info, 0, info->rbuf_count - 1); - info->rbuf_fill_index = 0; - info->rbuf_fill_count = 0; -} - -/* - * pass receive HDLC frame to upper layer - * - * return true if frame available, otherwise false - */ -static bool rx_get_frame(struct slgt_info *info) -{ - unsigned int start, end; - unsigned short status; - unsigned int framesize = 0; - unsigned long flags; - struct tty_struct *tty = info->port.tty; - unsigned char addr_field = 0xff; - unsigned int crc_size = 0; - - switch (info->params.crc_type & HDLC_CRC_MASK) { - case HDLC_CRC_16_CCITT: crc_size = 2; break; - case HDLC_CRC_32_CCITT: crc_size = 4; break; - } - -check_again: - - framesize = 0; - addr_field = 0xff; - start = end = info->rbuf_current; - - for (;;) { - if (!desc_complete(info->rbufs[end])) - goto cleanup; - - if (framesize == 0 && info->params.addr_filter != 0xff) - addr_field = info->rbufs[end].buf[0]; - - framesize += desc_count(info->rbufs[end]); - - if (desc_eof(info->rbufs[end])) - break; - - if (++end == info->rbuf_count) - end = 0; - - if (end == info->rbuf_current) { - if (info->rx_enabled){ - spin_lock_irqsave(&info->lock,flags); - rx_start(info); - spin_unlock_irqrestore(&info->lock,flags); - } - goto cleanup; - } - } - - /* status - * - * 15 buffer complete - * 14..06 reserved - * 05..04 residue - * 02 eof (end of frame) - * 01 CRC error - * 00 abort - */ - status = desc_status(info->rbufs[end]); - - /* ignore CRC bit if not using CRC (bit is undefined) */ - if ((info->params.crc_type & HDLC_CRC_MASK) == HDLC_CRC_NONE) - status &= ~BIT1; - - if (framesize == 0 || - (addr_field != 0xff && addr_field != info->params.addr_filter)) { - free_rbufs(info, start, end); - goto check_again; - } - - if (framesize < (2 + crc_size) || status & BIT0) { - info->icount.rxshort++; - framesize = 0; - } else if (status & BIT1) { - info->icount.rxcrc++; - if (!(info->params.crc_type & HDLC_CRC_RETURN_EX)) - framesize = 0; - } - -#if SYNCLINK_GENERIC_HDLC - if (framesize == 0) { - info->netdev->stats.rx_errors++; - info->netdev->stats.rx_frame_errors++; - } -#endif - - DBGBH(("%s rx frame status=%04X size=%d\n", - info->device_name, status, framesize)); - DBGDATA(info, info->rbufs[start].buf, min_t(int, framesize, info->rbuf_fill_level), "rx"); - - if (framesize) { - if (!(info->params.crc_type & HDLC_CRC_RETURN_EX)) { - framesize -= crc_size; - crc_size = 0; - } - - if (framesize > info->max_frame_size + crc_size) - info->icount.rxlong++; - else { - /* copy dma buffer(s) to contiguous temp buffer */ - int copy_count = framesize; - int i = start; - unsigned char *p = info->tmp_rbuf; - info->tmp_rbuf_count = framesize; - - info->icount.rxok++; - - while(copy_count) { - int partial_count = min_t(int, copy_count, info->rbuf_fill_level); - memcpy(p, info->rbufs[i].buf, partial_count); - p += partial_count; - copy_count -= partial_count; - if (++i == info->rbuf_count) - i = 0; - } - - if (info->params.crc_type & HDLC_CRC_RETURN_EX) { - *p = (status & BIT1) ? RX_CRC_ERROR : RX_OK; - framesize++; - } - -#if SYNCLINK_GENERIC_HDLC - if (info->netcount) - hdlcdev_rx(info,info->tmp_rbuf, framesize); - else -#endif - ldisc_receive_buf(tty, info->tmp_rbuf, info->flag_buf, framesize); - } - } - free_rbufs(info, start, end); - return true; - -cleanup: - return false; -} - -/* - * pass receive buffer (RAW synchronous mode) to tty layer - * return true if buffer available, otherwise false - */ -static bool rx_get_buf(struct slgt_info *info) -{ - unsigned int i = info->rbuf_current; - unsigned int count; - - if (!desc_complete(info->rbufs[i])) - return false; - count = desc_count(info->rbufs[i]); - switch(info->params.mode) { - case MGSL_MODE_MONOSYNC: - case MGSL_MODE_BISYNC: - case MGSL_MODE_XSYNC: - /* ignore residue in byte synchronous modes */ - if (desc_residue(info->rbufs[i])) - count--; - break; - } - DBGDATA(info, info->rbufs[i].buf, count, "rx"); - DBGINFO(("rx_get_buf size=%d\n", count)); - if (count) - ldisc_receive_buf(info->port.tty, info->rbufs[i].buf, - info->flag_buf, count); - free_rbufs(info, i, i); - return true; -} - -static void reset_tbufs(struct slgt_info *info) -{ - unsigned int i; - info->tbuf_current = 0; - for (i=0 ; i < info->tbuf_count ; i++) { - info->tbufs[i].status = 0; - info->tbufs[i].count = 0; - } -} - -/* - * return number of free transmit DMA buffers - */ -static unsigned int free_tbuf_count(struct slgt_info *info) -{ - unsigned int count = 0; - unsigned int i = info->tbuf_current; - - do - { - if (desc_count(info->tbufs[i])) - break; /* buffer in use */ - ++count; - if (++i == info->tbuf_count) - i=0; - } while (i != info->tbuf_current); - - /* if tx DMA active, last zero count buffer is in use */ - if (count && (rd_reg32(info, TDCSR) & BIT0)) - --count; - - return count; -} - -/* - * return number of bytes in unsent transmit DMA buffers - * and the serial controller tx FIFO - */ -static unsigned int tbuf_bytes(struct slgt_info *info) -{ - unsigned int total_count = 0; - unsigned int i = info->tbuf_current; - unsigned int reg_value; - unsigned int count; - unsigned int active_buf_count = 0; - - /* - * Add descriptor counts for all tx DMA buffers. - * If count is zero (cleared by DMA controller after read), - * the buffer is complete or is actively being read from. - * - * Record buf_count of last buffer with zero count starting - * from current ring position. buf_count is mirror - * copy of count and is not cleared by serial controller. - * If DMA controller is active, that buffer is actively - * being read so add to total. - */ - do { - count = desc_count(info->tbufs[i]); - if (count) - total_count += count; - else if (!total_count) - active_buf_count = info->tbufs[i].buf_count; - if (++i == info->tbuf_count) - i = 0; - } while (i != info->tbuf_current); - - /* read tx DMA status register */ - reg_value = rd_reg32(info, TDCSR); - - /* if tx DMA active, last zero count buffer is in use */ - if (reg_value & BIT0) - total_count += active_buf_count; - - /* add tx FIFO count = reg_value[15..8] */ - total_count += (reg_value >> 8) & 0xff; - - /* if transmitter active add one byte for shift register */ - if (info->tx_active) - total_count++; - - return total_count; -} - -/* - * load data into transmit DMA buffer ring and start transmitter if needed - * return true if data accepted, otherwise false (buffers full) - */ -static bool tx_load(struct slgt_info *info, const char *buf, unsigned int size) -{ - unsigned short count; - unsigned int i; - struct slgt_desc *d; - - /* check required buffer space */ - if (DIV_ROUND_UP(size, DMABUFSIZE) > free_tbuf_count(info)) - return false; - - DBGDATA(info, buf, size, "tx"); - - /* - * copy data to one or more DMA buffers in circular ring - * tbuf_start = first buffer for this data - * tbuf_current = next free buffer - * - * Copy all data before making data visible to DMA controller by - * setting descriptor count of the first buffer. - * This prevents an active DMA controller from reading the first DMA - * buffers of a frame and stopping before the final buffers are filled. - */ - - info->tbuf_start = i = info->tbuf_current; - - while (size) { - d = &info->tbufs[i]; - - count = (unsigned short)((size > DMABUFSIZE) ? DMABUFSIZE : size); - memcpy(d->buf, buf, count); - - size -= count; - buf += count; - - /* - * set EOF bit for last buffer of HDLC frame or - * for every buffer in raw mode - */ - if ((!size && info->params.mode == MGSL_MODE_HDLC) || - info->params.mode == MGSL_MODE_RAW) - set_desc_eof(*d, 1); - else - set_desc_eof(*d, 0); - - /* set descriptor count for all but first buffer */ - if (i != info->tbuf_start) - set_desc_count(*d, count); - d->buf_count = count; - - if (++i == info->tbuf_count) - i = 0; - } - - info->tbuf_current = i; - - /* set first buffer count to make new data visible to DMA controller */ - d = &info->tbufs[info->tbuf_start]; - set_desc_count(*d, d->buf_count); - - /* start transmitter if needed and update transmit timeout */ - if (!info->tx_active) - tx_start(info); - update_tx_timer(info); - - return true; -} - -static int register_test(struct slgt_info *info) -{ - static unsigned short patterns[] = - {0x0000, 0xffff, 0xaaaa, 0x5555, 0x6969, 0x9696}; - static unsigned int count = ARRAY_SIZE(patterns); - unsigned int i; - int rc = 0; - - for (i=0 ; i < count ; i++) { - wr_reg16(info, TIR, patterns[i]); - wr_reg16(info, BDR, patterns[(i+1)%count]); - if ((rd_reg16(info, TIR) != patterns[i]) || - (rd_reg16(info, BDR) != patterns[(i+1)%count])) { - rc = -ENODEV; - break; - } - } - info->gpio_present = (rd_reg32(info, JCR) & BIT5) ? 1 : 0; - info->init_error = rc ? 0 : DiagStatus_AddressFailure; - return rc; -} - -static int irq_test(struct slgt_info *info) -{ - unsigned long timeout; - unsigned long flags; - struct tty_struct *oldtty = info->port.tty; - u32 speed = info->params.data_rate; - - info->params.data_rate = 921600; - info->port.tty = NULL; - - spin_lock_irqsave(&info->lock, flags); - async_mode(info); - slgt_irq_on(info, IRQ_TXIDLE); - - /* enable transmitter */ - wr_reg16(info, TCR, - (unsigned short)(rd_reg16(info, TCR) | BIT1)); - - /* write one byte and wait for tx idle */ - wr_reg16(info, TDR, 0); - - /* assume failure */ - info->init_error = DiagStatus_IrqFailure; - info->irq_occurred = false; - - spin_unlock_irqrestore(&info->lock, flags); - - timeout=100; - while(timeout-- && !info->irq_occurred) - msleep_interruptible(10); - - spin_lock_irqsave(&info->lock,flags); - reset_port(info); - spin_unlock_irqrestore(&info->lock,flags); - - info->params.data_rate = speed; - info->port.tty = oldtty; - - info->init_error = info->irq_occurred ? 0 : DiagStatus_IrqFailure; - return info->irq_occurred ? 0 : -ENODEV; -} - -static int loopback_test_rx(struct slgt_info *info) -{ - unsigned char *src, *dest; - int count; - - if (desc_complete(info->rbufs[0])) { - count = desc_count(info->rbufs[0]); - src = info->rbufs[0].buf; - dest = info->tmp_rbuf; - - for( ; count ; count-=2, src+=2) { - /* src=data byte (src+1)=status byte */ - if (!(*(src+1) & (BIT9 + BIT8))) { - *dest = *src; - dest++; - info->tmp_rbuf_count++; - } - } - DBGDATA(info, info->tmp_rbuf, info->tmp_rbuf_count, "rx"); - return 1; - } - return 0; -} - -static int loopback_test(struct slgt_info *info) -{ -#define TESTFRAMESIZE 20 - - unsigned long timeout; - u16 count = TESTFRAMESIZE; - unsigned char buf[TESTFRAMESIZE]; - int rc = -ENODEV; - unsigned long flags; - - struct tty_struct *oldtty = info->port.tty; - MGSL_PARAMS params; - - memcpy(¶ms, &info->params, sizeof(params)); - - info->params.mode = MGSL_MODE_ASYNC; - info->params.data_rate = 921600; - info->params.loopback = 1; - info->port.tty = NULL; - - /* build and send transmit frame */ - for (count = 0; count < TESTFRAMESIZE; ++count) - buf[count] = (unsigned char)count; - - info->tmp_rbuf_count = 0; - memset(info->tmp_rbuf, 0, TESTFRAMESIZE); - - /* program hardware for HDLC and enabled receiver */ - spin_lock_irqsave(&info->lock,flags); - async_mode(info); - rx_start(info); - tx_load(info, buf, count); - spin_unlock_irqrestore(&info->lock, flags); - - /* wait for receive complete */ - for (timeout = 100; timeout; --timeout) { - msleep_interruptible(10); - if (loopback_test_rx(info)) { - rc = 0; - break; - } - } - - /* verify received frame length and contents */ - if (!rc && (info->tmp_rbuf_count != count || - memcmp(buf, info->tmp_rbuf, count))) { - rc = -ENODEV; - } - - spin_lock_irqsave(&info->lock,flags); - reset_adapter(info); - spin_unlock_irqrestore(&info->lock,flags); - - memcpy(&info->params, ¶ms, sizeof(info->params)); - info->port.tty = oldtty; - - info->init_error = rc ? DiagStatus_DmaFailure : 0; - return rc; -} - -static int adapter_test(struct slgt_info *info) -{ - DBGINFO(("testing %s\n", info->device_name)); - if (register_test(info) < 0) { - printk("register test failure %s addr=%08X\n", - info->device_name, info->phys_reg_addr); - } else if (irq_test(info) < 0) { - printk("IRQ test failure %s IRQ=%d\n", - info->device_name, info->irq_level); - } else if (loopback_test(info) < 0) { - printk("loopback test failure %s\n", info->device_name); - } - return info->init_error; -} - -/* - * transmit timeout handler - */ -static void tx_timeout(unsigned long context) -{ - struct slgt_info *info = (struct slgt_info*)context; - unsigned long flags; - - DBGINFO(("%s tx_timeout\n", info->device_name)); - if(info->tx_active && info->params.mode == MGSL_MODE_HDLC) { - info->icount.txtimeout++; - } - spin_lock_irqsave(&info->lock,flags); - tx_stop(info); - spin_unlock_irqrestore(&info->lock,flags); - -#if SYNCLINK_GENERIC_HDLC - if (info->netcount) - hdlcdev_tx_done(info); - else -#endif - bh_transmit(info); -} - -/* - * receive buffer polling timer - */ -static void rx_timeout(unsigned long context) -{ - struct slgt_info *info = (struct slgt_info*)context; - unsigned long flags; - - DBGINFO(("%s rx_timeout\n", info->device_name)); - spin_lock_irqsave(&info->lock, flags); - info->pending_bh |= BH_RECEIVE; - spin_unlock_irqrestore(&info->lock, flags); - bh_handler(&info->task); -} - diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c deleted file mode 100644 index 327343694473..000000000000 --- a/drivers/char/synclinkmp.c +++ /dev/null @@ -1,5600 +0,0 @@ -/* - * $Id: synclinkmp.c,v 4.38 2005/07/15 13:29:44 paulkf Exp $ - * - * Device driver for Microgate SyncLink Multiport - * high speed multiprotocol serial adapter. - * - * written by Paul Fulghum for Microgate Corporation - * paulkf@microgate.com - * - * Microgate and SyncLink are trademarks of Microgate Corporation - * - * Derived from serial.c written by Theodore Ts'o and Linus Torvalds - * This code is released under the GNU General Public License (GPL) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define VERSION(ver,rel,seq) (((ver)<<16) | ((rel)<<8) | (seq)) -#if defined(__i386__) -# define BREAKPOINT() asm(" int $3"); -#else -# define BREAKPOINT() { } -#endif - -#define MAX_DEVICES 12 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINKMP_MODULE)) -#define SYNCLINK_GENERIC_HDLC 1 -#else -#define SYNCLINK_GENERIC_HDLC 0 -#endif - -#define GET_USER(error,value,addr) error = get_user(value,addr) -#define COPY_FROM_USER(error,dest,src,size) error = copy_from_user(dest,src,size) ? -EFAULT : 0 -#define PUT_USER(error,value,addr) error = put_user(value,addr) -#define COPY_TO_USER(error,dest,src,size) error = copy_to_user(dest,src,size) ? -EFAULT : 0 - -#include - -static MGSL_PARAMS default_params = { - MGSL_MODE_HDLC, /* unsigned long mode */ - 0, /* unsigned char loopback; */ - HDLC_FLAG_UNDERRUN_ABORT15, /* unsigned short flags; */ - HDLC_ENCODING_NRZI_SPACE, /* unsigned char encoding; */ - 0, /* unsigned long clock_speed; */ - 0xff, /* unsigned char addr_filter; */ - HDLC_CRC_16_CCITT, /* unsigned short crc_type; */ - HDLC_PREAMBLE_LENGTH_8BITS, /* unsigned char preamble_length; */ - HDLC_PREAMBLE_PATTERN_NONE, /* unsigned char preamble; */ - 9600, /* unsigned long data_rate; */ - 8, /* unsigned char data_bits; */ - 1, /* unsigned char stop_bits; */ - ASYNC_PARITY_NONE /* unsigned char parity; */ -}; - -/* size in bytes of DMA data buffers */ -#define SCABUFSIZE 1024 -#define SCA_MEM_SIZE 0x40000 -#define SCA_BASE_SIZE 512 -#define SCA_REG_SIZE 16 -#define SCA_MAX_PORTS 4 -#define SCAMAXDESC 128 - -#define BUFFERLISTSIZE 4096 - -/* SCA-I style DMA buffer descriptor */ -typedef struct _SCADESC -{ - u16 next; /* lower l6 bits of next descriptor addr */ - u16 buf_ptr; /* lower 16 bits of buffer addr */ - u8 buf_base; /* upper 8 bits of buffer addr */ - u8 pad1; - u16 length; /* length of buffer */ - u8 status; /* status of buffer */ - u8 pad2; -} SCADESC, *PSCADESC; - -typedef struct _SCADESC_EX -{ - /* device driver bookkeeping section */ - char *virt_addr; /* virtual address of data buffer */ - u16 phys_entry; /* lower 16-bits of physical address of this descriptor */ -} SCADESC_EX, *PSCADESC_EX; - -/* The queue of BH actions to be performed */ - -#define BH_RECEIVE 1 -#define BH_TRANSMIT 2 -#define BH_STATUS 4 - -#define IO_PIN_SHUTDOWN_LIMIT 100 - -struct _input_signal_events { - int ri_up; - int ri_down; - int dsr_up; - int dsr_down; - int dcd_up; - int dcd_down; - int cts_up; - int cts_down; -}; - -/* - * Device instance data structure - */ -typedef struct _synclinkmp_info { - void *if_ptr; /* General purpose pointer (used by SPPP) */ - int magic; - struct tty_port port; - int line; - unsigned short close_delay; - unsigned short closing_wait; /* time to wait before closing */ - - struct mgsl_icount icount; - - int timeout; - int x_char; /* xon/xoff character */ - u16 read_status_mask1; /* break detection (SR1 indications) */ - u16 read_status_mask2; /* parity/framing/overun (SR2 indications) */ - unsigned char ignore_status_mask1; /* break detection (SR1 indications) */ - unsigned char ignore_status_mask2; /* parity/framing/overun (SR2 indications) */ - unsigned char *tx_buf; - int tx_put; - int tx_get; - int tx_count; - - wait_queue_head_t status_event_wait_q; - wait_queue_head_t event_wait_q; - struct timer_list tx_timer; /* HDLC transmit timeout timer */ - struct _synclinkmp_info *next_device; /* device list link */ - struct timer_list status_timer; /* input signal status check timer */ - - spinlock_t lock; /* spinlock for synchronizing with ISR */ - struct work_struct task; /* task structure for scheduling bh */ - - u32 max_frame_size; /* as set by device config */ - - u32 pending_bh; - - bool bh_running; /* Protection from multiple */ - int isr_overflow; - bool bh_requested; - - int dcd_chkcount; /* check counts to prevent */ - int cts_chkcount; /* too many IRQs if a signal */ - int dsr_chkcount; /* is floating */ - int ri_chkcount; - - char *buffer_list; /* virtual address of Rx & Tx buffer lists */ - unsigned long buffer_list_phys; - - unsigned int rx_buf_count; /* count of total allocated Rx buffers */ - SCADESC *rx_buf_list; /* list of receive buffer entries */ - SCADESC_EX rx_buf_list_ex[SCAMAXDESC]; /* list of receive buffer entries */ - unsigned int current_rx_buf; - - unsigned int tx_buf_count; /* count of total allocated Tx buffers */ - SCADESC *tx_buf_list; /* list of transmit buffer entries */ - SCADESC_EX tx_buf_list_ex[SCAMAXDESC]; /* list of transmit buffer entries */ - unsigned int last_tx_buf; - - unsigned char *tmp_rx_buf; - unsigned int tmp_rx_buf_count; - - bool rx_enabled; - bool rx_overflow; - - bool tx_enabled; - bool tx_active; - u32 idle_mode; - - unsigned char ie0_value; - unsigned char ie1_value; - unsigned char ie2_value; - unsigned char ctrlreg_value; - unsigned char old_signals; - - char device_name[25]; /* device instance name */ - - int port_count; - int adapter_num; - int port_num; - - struct _synclinkmp_info *port_array[SCA_MAX_PORTS]; - - unsigned int bus_type; /* expansion bus type (ISA,EISA,PCI) */ - - unsigned int irq_level; /* interrupt level */ - unsigned long irq_flags; - bool irq_requested; /* true if IRQ requested */ - - MGSL_PARAMS params; /* communications parameters */ - - unsigned char serial_signals; /* current serial signal states */ - - bool irq_occurred; /* for diagnostics use */ - unsigned int init_error; /* Initialization startup error */ - - u32 last_mem_alloc; - unsigned char* memory_base; /* shared memory address (PCI only) */ - u32 phys_memory_base; - int shared_mem_requested; - - unsigned char* sca_base; /* HD64570 SCA Memory address */ - u32 phys_sca_base; - u32 sca_offset; - bool sca_base_requested; - - unsigned char* lcr_base; /* local config registers (PCI only) */ - u32 phys_lcr_base; - u32 lcr_offset; - int lcr_mem_requested; - - unsigned char* statctrl_base; /* status/control register memory */ - u32 phys_statctrl_base; - u32 statctrl_offset; - bool sca_statctrl_requested; - - u32 misc_ctrl_value; - char flag_buf[MAX_ASYNC_BUFFER_SIZE]; - char char_buf[MAX_ASYNC_BUFFER_SIZE]; - bool drop_rts_on_tx_done; - - struct _input_signal_events input_signal_events; - - /* SPPP/Cisco HDLC device parts */ - int netcount; - spinlock_t netlock; - -#if SYNCLINK_GENERIC_HDLC - struct net_device *netdev; -#endif - -} SLMP_INFO; - -#define MGSL_MAGIC 0x5401 - -/* - * define serial signal status change macros - */ -#define MISCSTATUS_DCD_LATCHED (SerialSignal_DCD<<8) /* indicates change in DCD */ -#define MISCSTATUS_RI_LATCHED (SerialSignal_RI<<8) /* indicates change in RI */ -#define MISCSTATUS_CTS_LATCHED (SerialSignal_CTS<<8) /* indicates change in CTS */ -#define MISCSTATUS_DSR_LATCHED (SerialSignal_DSR<<8) /* change in DSR */ - -/* Common Register macros */ -#define LPR 0x00 -#define PABR0 0x02 -#define PABR1 0x03 -#define WCRL 0x04 -#define WCRM 0x05 -#define WCRH 0x06 -#define DPCR 0x08 -#define DMER 0x09 -#define ISR0 0x10 -#define ISR1 0x11 -#define ISR2 0x12 -#define IER0 0x14 -#define IER1 0x15 -#define IER2 0x16 -#define ITCR 0x18 -#define INTVR 0x1a -#define IMVR 0x1c - -/* MSCI Register macros */ -#define TRB 0x20 -#define TRBL 0x20 -#define TRBH 0x21 -#define SR0 0x22 -#define SR1 0x23 -#define SR2 0x24 -#define SR3 0x25 -#define FST 0x26 -#define IE0 0x28 -#define IE1 0x29 -#define IE2 0x2a -#define FIE 0x2b -#define CMD 0x2c -#define MD0 0x2e -#define MD1 0x2f -#define MD2 0x30 -#define CTL 0x31 -#define SA0 0x32 -#define SA1 0x33 -#define IDL 0x34 -#define TMC 0x35 -#define RXS 0x36 -#define TXS 0x37 -#define TRC0 0x38 -#define TRC1 0x39 -#define RRC 0x3a -#define CST0 0x3c -#define CST1 0x3d - -/* Timer Register Macros */ -#define TCNT 0x60 -#define TCNTL 0x60 -#define TCNTH 0x61 -#define TCONR 0x62 -#define TCONRL 0x62 -#define TCONRH 0x63 -#define TMCS 0x64 -#define TEPR 0x65 - -/* DMA Controller Register macros */ -#define DARL 0x80 -#define DARH 0x81 -#define DARB 0x82 -#define BAR 0x80 -#define BARL 0x80 -#define BARH 0x81 -#define BARB 0x82 -#define SAR 0x84 -#define SARL 0x84 -#define SARH 0x85 -#define SARB 0x86 -#define CPB 0x86 -#define CDA 0x88 -#define CDAL 0x88 -#define CDAH 0x89 -#define EDA 0x8a -#define EDAL 0x8a -#define EDAH 0x8b -#define BFL 0x8c -#define BFLL 0x8c -#define BFLH 0x8d -#define BCR 0x8e -#define BCRL 0x8e -#define BCRH 0x8f -#define DSR 0x90 -#define DMR 0x91 -#define FCT 0x93 -#define DIR 0x94 -#define DCMD 0x95 - -/* combine with timer or DMA register address */ -#define TIMER0 0x00 -#define TIMER1 0x08 -#define TIMER2 0x10 -#define TIMER3 0x18 -#define RXDMA 0x00 -#define TXDMA 0x20 - -/* SCA Command Codes */ -#define NOOP 0x00 -#define TXRESET 0x01 -#define TXENABLE 0x02 -#define TXDISABLE 0x03 -#define TXCRCINIT 0x04 -#define TXCRCEXCL 0x05 -#define TXEOM 0x06 -#define TXABORT 0x07 -#define MPON 0x08 -#define TXBUFCLR 0x09 -#define RXRESET 0x11 -#define RXENABLE 0x12 -#define RXDISABLE 0x13 -#define RXCRCINIT 0x14 -#define RXREJECT 0x15 -#define SEARCHMP 0x16 -#define RXCRCEXCL 0x17 -#define RXCRCCALC 0x18 -#define CHRESET 0x21 -#define HUNT 0x31 - -/* DMA command codes */ -#define SWABORT 0x01 -#define FEICLEAR 0x02 - -/* IE0 */ -#define TXINTE BIT7 -#define RXINTE BIT6 -#define TXRDYE BIT1 -#define RXRDYE BIT0 - -/* IE1 & SR1 */ -#define UDRN BIT7 -#define IDLE BIT6 -#define SYNCD BIT4 -#define FLGD BIT4 -#define CCTS BIT3 -#define CDCD BIT2 -#define BRKD BIT1 -#define ABTD BIT1 -#define GAPD BIT1 -#define BRKE BIT0 -#define IDLD BIT0 - -/* IE2 & SR2 */ -#define EOM BIT7 -#define PMP BIT6 -#define SHRT BIT6 -#define PE BIT5 -#define ABT BIT5 -#define FRME BIT4 -#define RBIT BIT4 -#define OVRN BIT3 -#define CRCE BIT2 - - -/* - * Global linked list of SyncLink devices - */ -static SLMP_INFO *synclinkmp_device_list = NULL; -static int synclinkmp_adapter_count = -1; -static int synclinkmp_device_count = 0; - -/* - * Set this param to non-zero to load eax with the - * .text section address and breakpoint on module load. - * This is useful for use with gdb and add-symbol-file command. - */ -static int break_on_load = 0; - -/* - * Driver major number, defaults to zero to get auto - * assigned major number. May be forced as module parameter. - */ -static int ttymajor = 0; - -/* - * Array of user specified options for ISA adapters. - */ -static int debug_level = 0; -static int maxframe[MAX_DEVICES] = {0,}; - -module_param(break_on_load, bool, 0); -module_param(ttymajor, int, 0); -module_param(debug_level, int, 0); -module_param_array(maxframe, int, NULL, 0); - -static char *driver_name = "SyncLink MultiPort driver"; -static char *driver_version = "$Revision: 4.38 $"; - -static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent); -static void synclinkmp_remove_one(struct pci_dev *dev); - -static struct pci_device_id synclinkmp_pci_tbl[] = { - { PCI_VENDOR_ID_MICROGATE, PCI_DEVICE_ID_MICROGATE_SCA, PCI_ANY_ID, PCI_ANY_ID, }, - { 0, }, /* terminate list */ -}; -MODULE_DEVICE_TABLE(pci, synclinkmp_pci_tbl); - -MODULE_LICENSE("GPL"); - -static struct pci_driver synclinkmp_pci_driver = { - .name = "synclinkmp", - .id_table = synclinkmp_pci_tbl, - .probe = synclinkmp_init_one, - .remove = __devexit_p(synclinkmp_remove_one), -}; - - -static struct tty_driver *serial_driver; - -/* number of characters left in xmit buffer before we ask for more */ -#define WAKEUP_CHARS 256 - - -/* tty callbacks */ - -static int open(struct tty_struct *tty, struct file * filp); -static void close(struct tty_struct *tty, struct file * filp); -static void hangup(struct tty_struct *tty); -static void set_termios(struct tty_struct *tty, struct ktermios *old_termios); - -static int write(struct tty_struct *tty, const unsigned char *buf, int count); -static int put_char(struct tty_struct *tty, unsigned char ch); -static void send_xchar(struct tty_struct *tty, char ch); -static void wait_until_sent(struct tty_struct *tty, int timeout); -static int write_room(struct tty_struct *tty); -static void flush_chars(struct tty_struct *tty); -static void flush_buffer(struct tty_struct *tty); -static void tx_hold(struct tty_struct *tty); -static void tx_release(struct tty_struct *tty); - -static int ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); -static int chars_in_buffer(struct tty_struct *tty); -static void throttle(struct tty_struct * tty); -static void unthrottle(struct tty_struct * tty); -static int set_break(struct tty_struct *tty, int break_state); - -#if SYNCLINK_GENERIC_HDLC -#define dev_to_port(D) (dev_to_hdlc(D)->priv) -static void hdlcdev_tx_done(SLMP_INFO *info); -static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size); -static int hdlcdev_init(SLMP_INFO *info); -static void hdlcdev_exit(SLMP_INFO *info); -#endif - -/* ioctl handlers */ - -static int get_stats(SLMP_INFO *info, struct mgsl_icount __user *user_icount); -static int get_params(SLMP_INFO *info, MGSL_PARAMS __user *params); -static int set_params(SLMP_INFO *info, MGSL_PARAMS __user *params); -static int get_txidle(SLMP_INFO *info, int __user *idle_mode); -static int set_txidle(SLMP_INFO *info, int idle_mode); -static int tx_enable(SLMP_INFO *info, int enable); -static int tx_abort(SLMP_INFO *info); -static int rx_enable(SLMP_INFO *info, int enable); -static int modem_input_wait(SLMP_INFO *info,int arg); -static int wait_mgsl_event(SLMP_INFO *info, int __user *mask_ptr); -static int tiocmget(struct tty_struct *tty); -static int tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear); -static int set_break(struct tty_struct *tty, int break_state); - -static void add_device(SLMP_INFO *info); -static void device_init(int adapter_num, struct pci_dev *pdev); -static int claim_resources(SLMP_INFO *info); -static void release_resources(SLMP_INFO *info); - -static int startup(SLMP_INFO *info); -static int block_til_ready(struct tty_struct *tty, struct file * filp,SLMP_INFO *info); -static int carrier_raised(struct tty_port *port); -static void shutdown(SLMP_INFO *info); -static void program_hw(SLMP_INFO *info); -static void change_params(SLMP_INFO *info); - -static bool init_adapter(SLMP_INFO *info); -static bool register_test(SLMP_INFO *info); -static bool irq_test(SLMP_INFO *info); -static bool loopback_test(SLMP_INFO *info); -static int adapter_test(SLMP_INFO *info); -static bool memory_test(SLMP_INFO *info); - -static void reset_adapter(SLMP_INFO *info); -static void reset_port(SLMP_INFO *info); -static void async_mode(SLMP_INFO *info); -static void hdlc_mode(SLMP_INFO *info); - -static void rx_stop(SLMP_INFO *info); -static void rx_start(SLMP_INFO *info); -static void rx_reset_buffers(SLMP_INFO *info); -static void rx_free_frame_buffers(SLMP_INFO *info, unsigned int first, unsigned int last); -static bool rx_get_frame(SLMP_INFO *info); - -static void tx_start(SLMP_INFO *info); -static void tx_stop(SLMP_INFO *info); -static void tx_load_fifo(SLMP_INFO *info); -static void tx_set_idle(SLMP_INFO *info); -static void tx_load_dma_buffer(SLMP_INFO *info, const char *buf, unsigned int count); - -static void get_signals(SLMP_INFO *info); -static void set_signals(SLMP_INFO *info); -static void enable_loopback(SLMP_INFO *info, int enable); -static void set_rate(SLMP_INFO *info, u32 data_rate); - -static int bh_action(SLMP_INFO *info); -static void bh_handler(struct work_struct *work); -static void bh_receive(SLMP_INFO *info); -static void bh_transmit(SLMP_INFO *info); -static void bh_status(SLMP_INFO *info); -static void isr_timer(SLMP_INFO *info); -static void isr_rxint(SLMP_INFO *info); -static void isr_rxrdy(SLMP_INFO *info); -static void isr_txint(SLMP_INFO *info); -static void isr_txrdy(SLMP_INFO *info); -static void isr_rxdmaok(SLMP_INFO *info); -static void isr_rxdmaerror(SLMP_INFO *info); -static void isr_txdmaok(SLMP_INFO *info); -static void isr_txdmaerror(SLMP_INFO *info); -static void isr_io_pin(SLMP_INFO *info, u16 status); - -static int alloc_dma_bufs(SLMP_INFO *info); -static void free_dma_bufs(SLMP_INFO *info); -static int alloc_buf_list(SLMP_INFO *info); -static int alloc_frame_bufs(SLMP_INFO *info, SCADESC *list, SCADESC_EX *list_ex,int count); -static int alloc_tmp_rx_buf(SLMP_INFO *info); -static void free_tmp_rx_buf(SLMP_INFO *info); - -static void load_pci_memory(SLMP_INFO *info, char* dest, const char* src, unsigned short count); -static void trace_block(SLMP_INFO *info, const char* data, int count, int xmit); -static void tx_timeout(unsigned long context); -static void status_timeout(unsigned long context); - -static unsigned char read_reg(SLMP_INFO *info, unsigned char addr); -static void write_reg(SLMP_INFO *info, unsigned char addr, unsigned char val); -static u16 read_reg16(SLMP_INFO *info, unsigned char addr); -static void write_reg16(SLMP_INFO *info, unsigned char addr, u16 val); -static unsigned char read_status_reg(SLMP_INFO * info); -static void write_control_reg(SLMP_INFO * info); - - -static unsigned char rx_active_fifo_level = 16; // rx request FIFO activation level in bytes -static unsigned char tx_active_fifo_level = 16; // tx request FIFO activation level in bytes -static unsigned char tx_negate_fifo_level = 32; // tx request FIFO negation level in bytes - -static u32 misc_ctrl_value = 0x007e4040; -static u32 lcr1_brdr_value = 0x00800028; - -static u32 read_ahead_count = 8; - -/* DPCR, DMA Priority Control - * - * 07..05 Not used, must be 0 - * 04 BRC, bus release condition: 0=all transfers complete - * 1=release after 1 xfer on all channels - * 03 CCC, channel change condition: 0=every cycle - * 1=after each channel completes all xfers - * 02..00 PR<2..0>, priority 100=round robin - * - * 00000100 = 0x00 - */ -static unsigned char dma_priority = 0x04; - -// Number of bytes that can be written to shared RAM -// in a single write operation -static u32 sca_pci_load_interval = 64; - -/* - * 1st function defined in .text section. Calling this function in - * init_module() followed by a breakpoint allows a remote debugger - * (gdb) to get the .text address for the add-symbol-file command. - * This allows remote debugging of dynamically loadable modules. - */ -static void* synclinkmp_get_text_ptr(void); -static void* synclinkmp_get_text_ptr(void) {return synclinkmp_get_text_ptr;} - -static inline int sanity_check(SLMP_INFO *info, - char *name, const char *routine) -{ -#ifdef SANITY_CHECK - static const char *badmagic = - "Warning: bad magic number for synclinkmp_struct (%s) in %s\n"; - static const char *badinfo = - "Warning: null synclinkmp_struct for (%s) in %s\n"; - - if (!info) { - printk(badinfo, name, routine); - return 1; - } - if (info->magic != MGSL_MAGIC) { - printk(badmagic, name, routine); - return 1; - } -#else - if (!info) - return 1; -#endif - return 0; -} - -/** - * line discipline callback wrappers - * - * The wrappers maintain line discipline references - * while calling into the line discipline. - * - * ldisc_receive_buf - pass receive data to line discipline - */ - -static void ldisc_receive_buf(struct tty_struct *tty, - const __u8 *data, char *flags, int count) -{ - struct tty_ldisc *ld; - if (!tty) - return; - ld = tty_ldisc_ref(tty); - if (ld) { - if (ld->ops->receive_buf) - ld->ops->receive_buf(tty, data, flags, count); - tty_ldisc_deref(ld); - } -} - -/* tty callbacks */ - -/* Called when a port is opened. Init and enable port. - */ -static int open(struct tty_struct *tty, struct file *filp) -{ - SLMP_INFO *info; - int retval, line; - unsigned long flags; - - line = tty->index; - if ((line < 0) || (line >= synclinkmp_device_count)) { - printk("%s(%d): open with invalid line #%d.\n", - __FILE__,__LINE__,line); - return -ENODEV; - } - - info = synclinkmp_device_list; - while(info && info->line != line) - info = info->next_device; - if (sanity_check(info, tty->name, "open")) - return -ENODEV; - if ( info->init_error ) { - printk("%s(%d):%s device is not allocated, init error=%d\n", - __FILE__,__LINE__,info->device_name,info->init_error); - return -ENODEV; - } - - tty->driver_data = info; - info->port.tty = tty; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s open(), old ref count = %d\n", - __FILE__,__LINE__,tty->driver->name, info->port.count); - - /* If port is closing, signal caller to try again */ - if (tty_hung_up_p(filp) || info->port.flags & ASYNC_CLOSING){ - if (info->port.flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->port.close_wait); - retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); - goto cleanup; - } - - info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; - - spin_lock_irqsave(&info->netlock, flags); - if (info->netcount) { - retval = -EBUSY; - spin_unlock_irqrestore(&info->netlock, flags); - goto cleanup; - } - info->port.count++; - spin_unlock_irqrestore(&info->netlock, flags); - - if (info->port.count == 1) { - /* 1st open on this device, init hardware */ - retval = startup(info); - if (retval < 0) - goto cleanup; - } - - retval = block_til_ready(tty, filp, info); - if (retval) { - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s block_til_ready() returned %d\n", - __FILE__,__LINE__, info->device_name, retval); - goto cleanup; - } - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s open() success\n", - __FILE__,__LINE__, info->device_name); - retval = 0; - -cleanup: - if (retval) { - if (tty->count == 1) - info->port.tty = NULL; /* tty layer will release tty struct */ - if(info->port.count) - info->port.count--; - } - - return retval; -} - -/* Called when port is closed. Wait for remaining data to be - * sent. Disable port and free resources. - */ -static void close(struct tty_struct *tty, struct file *filp) -{ - SLMP_INFO * info = tty->driver_data; - - if (sanity_check(info, tty->name, "close")) - return; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s close() entry, count=%d\n", - __FILE__,__LINE__, info->device_name, info->port.count); - - if (tty_port_close_start(&info->port, tty, filp) == 0) - goto cleanup; - - mutex_lock(&info->port.mutex); - if (info->port.flags & ASYNC_INITIALIZED) - wait_until_sent(tty, info->timeout); - - flush_buffer(tty); - tty_ldisc_flush(tty); - shutdown(info); - mutex_unlock(&info->port.mutex); - - tty_port_close_end(&info->port, tty); - info->port.tty = NULL; -cleanup: - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s close() exit, count=%d\n", __FILE__,__LINE__, - tty->driver->name, info->port.count); -} - -/* Called by tty_hangup() when a hangup is signaled. - * This is the same as closing all open descriptors for the port. - */ -static void hangup(struct tty_struct *tty) -{ - SLMP_INFO *info = tty->driver_data; - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s hangup()\n", - __FILE__,__LINE__, info->device_name ); - - if (sanity_check(info, tty->name, "hangup")) - return; - - mutex_lock(&info->port.mutex); - flush_buffer(tty); - shutdown(info); - - spin_lock_irqsave(&info->port.lock, flags); - info->port.count = 0; - info->port.flags &= ~ASYNC_NORMAL_ACTIVE; - info->port.tty = NULL; - spin_unlock_irqrestore(&info->port.lock, flags); - mutex_unlock(&info->port.mutex); - - wake_up_interruptible(&info->port.open_wait); -} - -/* Set new termios settings - */ -static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) -{ - SLMP_INFO *info = tty->driver_data; - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s set_termios()\n", __FILE__,__LINE__, - tty->driver->name ); - - change_params(info); - - /* Handle transition to B0 status */ - if (old_termios->c_cflag & CBAUD && - !(tty->termios->c_cflag & CBAUD)) { - info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); - spin_lock_irqsave(&info->lock,flags); - set_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - } - - /* Handle transition away from B0 status */ - if (!(old_termios->c_cflag & CBAUD) && - tty->termios->c_cflag & CBAUD) { - info->serial_signals |= SerialSignal_DTR; - if (!(tty->termios->c_cflag & CRTSCTS) || - !test_bit(TTY_THROTTLED, &tty->flags)) { - info->serial_signals |= SerialSignal_RTS; - } - spin_lock_irqsave(&info->lock,flags); - set_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - } - - /* Handle turning off CRTSCTS */ - if (old_termios->c_cflag & CRTSCTS && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - tx_release(tty); - } -} - -/* Send a block of data - * - * Arguments: - * - * tty pointer to tty information structure - * buf pointer to buffer containing send data - * count size of send data in bytes - * - * Return Value: number of characters written - */ -static int write(struct tty_struct *tty, - const unsigned char *buf, int count) -{ - int c, ret = 0; - SLMP_INFO *info = tty->driver_data; - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s write() count=%d\n", - __FILE__,__LINE__,info->device_name,count); - - if (sanity_check(info, tty->name, "write")) - goto cleanup; - - if (!info->tx_buf) - goto cleanup; - - if (info->params.mode == MGSL_MODE_HDLC) { - if (count > info->max_frame_size) { - ret = -EIO; - goto cleanup; - } - if (info->tx_active) - goto cleanup; - if (info->tx_count) { - /* send accumulated data from send_char() calls */ - /* as frame and wait before accepting more data. */ - tx_load_dma_buffer(info, info->tx_buf, info->tx_count); - goto start; - } - ret = info->tx_count = count; - tx_load_dma_buffer(info, buf, count); - goto start; - } - - for (;;) { - c = min_t(int, count, - min(info->max_frame_size - info->tx_count - 1, - info->max_frame_size - info->tx_put)); - if (c <= 0) - break; - - memcpy(info->tx_buf + info->tx_put, buf, c); - - spin_lock_irqsave(&info->lock,flags); - info->tx_put += c; - if (info->tx_put >= info->max_frame_size) - info->tx_put -= info->max_frame_size; - info->tx_count += c; - spin_unlock_irqrestore(&info->lock,flags); - - buf += c; - count -= c; - ret += c; - } - - if (info->params.mode == MGSL_MODE_HDLC) { - if (count) { - ret = info->tx_count = 0; - goto cleanup; - } - tx_load_dma_buffer(info, info->tx_buf, info->tx_count); - } -start: - if (info->tx_count && !tty->stopped && !tty->hw_stopped) { - spin_lock_irqsave(&info->lock,flags); - if (!info->tx_active) - tx_start(info); - spin_unlock_irqrestore(&info->lock,flags); - } - -cleanup: - if (debug_level >= DEBUG_LEVEL_INFO) - printk( "%s(%d):%s write() returning=%d\n", - __FILE__,__LINE__,info->device_name,ret); - return ret; -} - -/* Add a character to the transmit buffer. - */ -static int put_char(struct tty_struct *tty, unsigned char ch) -{ - SLMP_INFO *info = tty->driver_data; - unsigned long flags; - int ret = 0; - - if ( debug_level >= DEBUG_LEVEL_INFO ) { - printk( "%s(%d):%s put_char(%d)\n", - __FILE__,__LINE__,info->device_name,ch); - } - - if (sanity_check(info, tty->name, "put_char")) - return 0; - - if (!info->tx_buf) - return 0; - - spin_lock_irqsave(&info->lock,flags); - - if ( (info->params.mode != MGSL_MODE_HDLC) || - !info->tx_active ) { - - if (info->tx_count < info->max_frame_size - 1) { - info->tx_buf[info->tx_put++] = ch; - if (info->tx_put >= info->max_frame_size) - info->tx_put -= info->max_frame_size; - info->tx_count++; - ret = 1; - } - } - - spin_unlock_irqrestore(&info->lock,flags); - return ret; -} - -/* Send a high-priority XON/XOFF character - */ -static void send_xchar(struct tty_struct *tty, char ch) -{ - SLMP_INFO *info = tty->driver_data; - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s send_xchar(%d)\n", - __FILE__,__LINE__, info->device_name, ch ); - - if (sanity_check(info, tty->name, "send_xchar")) - return; - - info->x_char = ch; - if (ch) { - /* Make sure transmit interrupts are on */ - spin_lock_irqsave(&info->lock,flags); - if (!info->tx_enabled) - tx_start(info); - spin_unlock_irqrestore(&info->lock,flags); - } -} - -/* Wait until the transmitter is empty. - */ -static void wait_until_sent(struct tty_struct *tty, int timeout) -{ - SLMP_INFO * info = tty->driver_data; - unsigned long orig_jiffies, char_time; - - if (!info ) - return; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s wait_until_sent() entry\n", - __FILE__,__LINE__, info->device_name ); - - if (sanity_check(info, tty->name, "wait_until_sent")) - return; - - if (!test_bit(ASYNCB_INITIALIZED, &info->port.flags)) - goto exit; - - orig_jiffies = jiffies; - - /* Set check interval to 1/5 of estimated time to - * send a character, and make it at least 1. The check - * interval should also be less than the timeout. - * Note: use tight timings here to satisfy the NIST-PCTS. - */ - - if ( info->params.data_rate ) { - char_time = info->timeout/(32 * 5); - if (!char_time) - char_time++; - } else - char_time = 1; - - if (timeout) - char_time = min_t(unsigned long, char_time, timeout); - - if ( info->params.mode == MGSL_MODE_HDLC ) { - while (info->tx_active) { - msleep_interruptible(jiffies_to_msecs(char_time)); - if (signal_pending(current)) - break; - if (timeout && time_after(jiffies, orig_jiffies + timeout)) - break; - } - } else { - /* - * TODO: determine if there is something similar to USC16C32 - * TXSTATUS_ALL_SENT status - */ - while ( info->tx_active && info->tx_enabled) { - msleep_interruptible(jiffies_to_msecs(char_time)); - if (signal_pending(current)) - break; - if (timeout && time_after(jiffies, orig_jiffies + timeout)) - break; - } - } - -exit: - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s wait_until_sent() exit\n", - __FILE__,__LINE__, info->device_name ); -} - -/* Return the count of free bytes in transmit buffer - */ -static int write_room(struct tty_struct *tty) -{ - SLMP_INFO *info = tty->driver_data; - int ret; - - if (sanity_check(info, tty->name, "write_room")) - return 0; - - if (info->params.mode == MGSL_MODE_HDLC) { - ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE; - } else { - ret = info->max_frame_size - info->tx_count - 1; - if (ret < 0) - ret = 0; - } - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s write_room()=%d\n", - __FILE__, __LINE__, info->device_name, ret); - - return ret; -} - -/* enable transmitter and send remaining buffered characters - */ -static void flush_chars(struct tty_struct *tty) -{ - SLMP_INFO *info = tty->driver_data; - unsigned long flags; - - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):%s flush_chars() entry tx_count=%d\n", - __FILE__,__LINE__,info->device_name,info->tx_count); - - if (sanity_check(info, tty->name, "flush_chars")) - return; - - if (info->tx_count <= 0 || tty->stopped || tty->hw_stopped || - !info->tx_buf) - return; - - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):%s flush_chars() entry, starting transmitter\n", - __FILE__,__LINE__,info->device_name ); - - spin_lock_irqsave(&info->lock,flags); - - if (!info->tx_active) { - if ( (info->params.mode == MGSL_MODE_HDLC) && - info->tx_count ) { - /* operating in synchronous (frame oriented) mode */ - /* copy data from circular tx_buf to */ - /* transmit DMA buffer. */ - tx_load_dma_buffer(info, - info->tx_buf,info->tx_count); - } - tx_start(info); - } - - spin_unlock_irqrestore(&info->lock,flags); -} - -/* Discard all data in the send buffer - */ -static void flush_buffer(struct tty_struct *tty) -{ - SLMP_INFO *info = tty->driver_data; - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s flush_buffer() entry\n", - __FILE__,__LINE__, info->device_name ); - - if (sanity_check(info, tty->name, "flush_buffer")) - return; - - spin_lock_irqsave(&info->lock,flags); - info->tx_count = info->tx_put = info->tx_get = 0; - del_timer(&info->tx_timer); - spin_unlock_irqrestore(&info->lock,flags); - - tty_wakeup(tty); -} - -/* throttle (stop) transmitter - */ -static void tx_hold(struct tty_struct *tty) -{ - SLMP_INFO *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "tx_hold")) - return; - - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk("%s(%d):%s tx_hold()\n", - __FILE__,__LINE__,info->device_name); - - spin_lock_irqsave(&info->lock,flags); - if (info->tx_enabled) - tx_stop(info); - spin_unlock_irqrestore(&info->lock,flags); -} - -/* release (start) transmitter - */ -static void tx_release(struct tty_struct *tty) -{ - SLMP_INFO *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "tx_release")) - return; - - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk("%s(%d):%s tx_release()\n", - __FILE__,__LINE__,info->device_name); - - spin_lock_irqsave(&info->lock,flags); - if (!info->tx_enabled) - tx_start(info); - spin_unlock_irqrestore(&info->lock,flags); -} - -/* Service an IOCTL request - * - * Arguments: - * - * tty pointer to tty instance data - * cmd IOCTL command code - * arg command argument/context - * - * Return Value: 0 if success, otherwise error code - */ -static int ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - SLMP_INFO *info = tty->driver_data; - void __user *argp = (void __user *)arg; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s ioctl() cmd=%08X\n", __FILE__,__LINE__, - info->device_name, cmd ); - - if (sanity_check(info, tty->name, "ioctl")) - return -ENODEV; - - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCMIWAIT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - } - - switch (cmd) { - case MGSL_IOCGPARAMS: - return get_params(info, argp); - case MGSL_IOCSPARAMS: - return set_params(info, argp); - case MGSL_IOCGTXIDLE: - return get_txidle(info, argp); - case MGSL_IOCSTXIDLE: - return set_txidle(info, (int)arg); - case MGSL_IOCTXENABLE: - return tx_enable(info, (int)arg); - case MGSL_IOCRXENABLE: - return rx_enable(info, (int)arg); - case MGSL_IOCTXABORT: - return tx_abort(info); - case MGSL_IOCGSTATS: - return get_stats(info, argp); - case MGSL_IOCWAITEVENT: - return wait_mgsl_event(info, argp); - case MGSL_IOCLOOPTXDONE: - return 0; // TODO: Not supported, need to document - /* Wait for modem input (DCD,RI,DSR,CTS) change - * as specified by mask in arg (TIOCM_RNG/DSR/CD/CTS) - */ - case TIOCMIWAIT: - return modem_input_wait(info,(int)arg); - - /* - * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) - * Return: write counters to the user passed counter struct - * NB: both 1->0 and 0->1 transitions are counted except for - * RI where only 0->1 is counted. - */ - default: - return -ENOIOCTLCMD; - } - return 0; -} - -static int get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - SLMP_INFO *info = tty->driver_data; - struct mgsl_icount cnow; /* kernel counter temps */ - unsigned long flags; - - spin_lock_irqsave(&info->lock,flags); - cnow = info->icount; - spin_unlock_irqrestore(&info->lock,flags); - - icount->cts = cnow.cts; - icount->dsr = cnow.dsr; - icount->rng = cnow.rng; - icount->dcd = cnow.dcd; - icount->rx = cnow.rx; - icount->tx = cnow.tx; - icount->frame = cnow.frame; - icount->overrun = cnow.overrun; - icount->parity = cnow.parity; - icount->brk = cnow.brk; - icount->buf_overrun = cnow.buf_overrun; - - return 0; -} - -/* - * /proc fs routines.... - */ - -static inline void line_info(struct seq_file *m, SLMP_INFO *info) -{ - char stat_buf[30]; - unsigned long flags; - - seq_printf(m, "%s: SCABase=%08x Mem=%08X StatusControl=%08x LCR=%08X\n" - "\tIRQ=%d MaxFrameSize=%u\n", - info->device_name, - info->phys_sca_base, - info->phys_memory_base, - info->phys_statctrl_base, - info->phys_lcr_base, - info->irq_level, - info->max_frame_size ); - - /* output current serial signal states */ - spin_lock_irqsave(&info->lock,flags); - get_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - - stat_buf[0] = 0; - stat_buf[1] = 0; - if (info->serial_signals & SerialSignal_RTS) - strcat(stat_buf, "|RTS"); - if (info->serial_signals & SerialSignal_CTS) - strcat(stat_buf, "|CTS"); - if (info->serial_signals & SerialSignal_DTR) - strcat(stat_buf, "|DTR"); - if (info->serial_signals & SerialSignal_DSR) - strcat(stat_buf, "|DSR"); - if (info->serial_signals & SerialSignal_DCD) - strcat(stat_buf, "|CD"); - if (info->serial_signals & SerialSignal_RI) - strcat(stat_buf, "|RI"); - - if (info->params.mode == MGSL_MODE_HDLC) { - seq_printf(m, "\tHDLC txok:%d rxok:%d", - info->icount.txok, info->icount.rxok); - if (info->icount.txunder) - seq_printf(m, " txunder:%d", info->icount.txunder); - if (info->icount.txabort) - seq_printf(m, " txabort:%d", info->icount.txabort); - if (info->icount.rxshort) - seq_printf(m, " rxshort:%d", info->icount.rxshort); - if (info->icount.rxlong) - seq_printf(m, " rxlong:%d", info->icount.rxlong); - if (info->icount.rxover) - seq_printf(m, " rxover:%d", info->icount.rxover); - if (info->icount.rxcrc) - seq_printf(m, " rxlong:%d", info->icount.rxcrc); - } else { - seq_printf(m, "\tASYNC tx:%d rx:%d", - info->icount.tx, info->icount.rx); - if (info->icount.frame) - seq_printf(m, " fe:%d", info->icount.frame); - if (info->icount.parity) - seq_printf(m, " pe:%d", info->icount.parity); - if (info->icount.brk) - seq_printf(m, " brk:%d", info->icount.brk); - if (info->icount.overrun) - seq_printf(m, " oe:%d", info->icount.overrun); - } - - /* Append serial signal status to end */ - seq_printf(m, " %s\n", stat_buf+1); - - seq_printf(m, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", - info->tx_active,info->bh_requested,info->bh_running, - info->pending_bh); -} - -/* Called to print information about devices - */ -static int synclinkmp_proc_show(struct seq_file *m, void *v) -{ - SLMP_INFO *info; - - seq_printf(m, "synclinkmp driver:%s\n", driver_version); - - info = synclinkmp_device_list; - while( info ) { - line_info(m, info); - info = info->next_device; - } - return 0; -} - -static int synclinkmp_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, synclinkmp_proc_show, NULL); -} - -static const struct file_operations synclinkmp_proc_fops = { - .owner = THIS_MODULE, - .open = synclinkmp_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/* Return the count of bytes in transmit buffer - */ -static int chars_in_buffer(struct tty_struct *tty) -{ - SLMP_INFO *info = tty->driver_data; - - if (sanity_check(info, tty->name, "chars_in_buffer")) - return 0; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s chars_in_buffer()=%d\n", - __FILE__, __LINE__, info->device_name, info->tx_count); - - return info->tx_count; -} - -/* Signal remote device to throttle send data (our receive data) - */ -static void throttle(struct tty_struct * tty) -{ - SLMP_INFO *info = tty->driver_data; - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s throttle() entry\n", - __FILE__,__LINE__, info->device_name ); - - if (sanity_check(info, tty->name, "throttle")) - return; - - if (I_IXOFF(tty)) - send_xchar(tty, STOP_CHAR(tty)); - - if (tty->termios->c_cflag & CRTSCTS) { - spin_lock_irqsave(&info->lock,flags); - info->serial_signals &= ~SerialSignal_RTS; - set_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - } -} - -/* Signal remote device to stop throttling send data (our receive data) - */ -static void unthrottle(struct tty_struct * tty) -{ - SLMP_INFO *info = tty->driver_data; - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s unthrottle() entry\n", - __FILE__,__LINE__, info->device_name ); - - if (sanity_check(info, tty->name, "unthrottle")) - return; - - if (I_IXOFF(tty)) { - if (info->x_char) - info->x_char = 0; - else - send_xchar(tty, START_CHAR(tty)); - } - - if (tty->termios->c_cflag & CRTSCTS) { - spin_lock_irqsave(&info->lock,flags); - info->serial_signals |= SerialSignal_RTS; - set_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - } -} - -/* set or clear transmit break condition - * break_state -1=set break condition, 0=clear - */ -static int set_break(struct tty_struct *tty, int break_state) -{ - unsigned char RegValue; - SLMP_INFO * info = tty->driver_data; - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s set_break(%d)\n", - __FILE__,__LINE__, info->device_name, break_state); - - if (sanity_check(info, tty->name, "set_break")) - return -EINVAL; - - spin_lock_irqsave(&info->lock,flags); - RegValue = read_reg(info, CTL); - if (break_state == -1) - RegValue |= BIT3; - else - RegValue &= ~BIT3; - write_reg(info, CTL, RegValue); - spin_unlock_irqrestore(&info->lock,flags); - return 0; -} - -#if SYNCLINK_GENERIC_HDLC - -/** - * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) - * set encoding and frame check sequence (FCS) options - * - * dev pointer to network device structure - * encoding serial encoding setting - * parity FCS setting - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_attach(struct net_device *dev, unsigned short encoding, - unsigned short parity) -{ - SLMP_INFO *info = dev_to_port(dev); - unsigned char new_encoding; - unsigned short new_crctype; - - /* return error if TTY interface open */ - if (info->port.count) - return -EBUSY; - - switch (encoding) - { - case ENCODING_NRZ: new_encoding = HDLC_ENCODING_NRZ; break; - case ENCODING_NRZI: new_encoding = HDLC_ENCODING_NRZI_SPACE; break; - case ENCODING_FM_MARK: new_encoding = HDLC_ENCODING_BIPHASE_MARK; break; - case ENCODING_FM_SPACE: new_encoding = HDLC_ENCODING_BIPHASE_SPACE; break; - case ENCODING_MANCHESTER: new_encoding = HDLC_ENCODING_BIPHASE_LEVEL; break; - default: return -EINVAL; - } - - switch (parity) - { - case PARITY_NONE: new_crctype = HDLC_CRC_NONE; break; - case PARITY_CRC16_PR1_CCITT: new_crctype = HDLC_CRC_16_CCITT; break; - case PARITY_CRC32_PR1_CCITT: new_crctype = HDLC_CRC_32_CCITT; break; - default: return -EINVAL; - } - - info->params.encoding = new_encoding; - info->params.crc_type = new_crctype; - - /* if network interface up, reprogram hardware */ - if (info->netcount) - program_hw(info); - - return 0; -} - -/** - * called by generic HDLC layer to send frame - * - * skb socket buffer containing HDLC frame - * dev pointer to network device structure - */ -static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb, - struct net_device *dev) -{ - SLMP_INFO *info = dev_to_port(dev); - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk(KERN_INFO "%s:hdlc_xmit(%s)\n",__FILE__,dev->name); - - /* stop sending until this frame completes */ - netif_stop_queue(dev); - - /* copy data to device buffers */ - info->tx_count = skb->len; - tx_load_dma_buffer(info, skb->data, skb->len); - - /* update network statistics */ - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - - /* done with socket buffer, so free it */ - dev_kfree_skb(skb); - - /* save start time for transmit timeout detection */ - dev->trans_start = jiffies; - - /* start hardware transmitter if necessary */ - spin_lock_irqsave(&info->lock,flags); - if (!info->tx_active) - tx_start(info); - spin_unlock_irqrestore(&info->lock,flags); - - return NETDEV_TX_OK; -} - -/** - * called by network layer when interface enabled - * claim resources and initialize hardware - * - * dev pointer to network device structure - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_open(struct net_device *dev) -{ - SLMP_INFO *info = dev_to_port(dev); - int rc; - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s:hdlcdev_open(%s)\n",__FILE__,dev->name); - - /* generic HDLC layer open processing */ - if ((rc = hdlc_open(dev))) - return rc; - - /* arbitrate between network and tty opens */ - spin_lock_irqsave(&info->netlock, flags); - if (info->port.count != 0 || info->netcount != 0) { - printk(KERN_WARNING "%s: hdlc_open returning busy\n", dev->name); - spin_unlock_irqrestore(&info->netlock, flags); - return -EBUSY; - } - info->netcount=1; - spin_unlock_irqrestore(&info->netlock, flags); - - /* claim resources and init adapter */ - if ((rc = startup(info)) != 0) { - spin_lock_irqsave(&info->netlock, flags); - info->netcount=0; - spin_unlock_irqrestore(&info->netlock, flags); - return rc; - } - - /* assert DTR and RTS, apply hardware settings */ - info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; - program_hw(info); - - /* enable network layer transmit */ - dev->trans_start = jiffies; - netif_start_queue(dev); - - /* inform generic HDLC layer of current DCD status */ - spin_lock_irqsave(&info->lock, flags); - get_signals(info); - spin_unlock_irqrestore(&info->lock, flags); - if (info->serial_signals & SerialSignal_DCD) - netif_carrier_on(dev); - else - netif_carrier_off(dev); - return 0; -} - -/** - * called by network layer when interface is disabled - * shutdown hardware and release resources - * - * dev pointer to network device structure - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_close(struct net_device *dev) -{ - SLMP_INFO *info = dev_to_port(dev); - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s:hdlcdev_close(%s)\n",__FILE__,dev->name); - - netif_stop_queue(dev); - - /* shutdown adapter and release resources */ - shutdown(info); - - hdlc_close(dev); - - spin_lock_irqsave(&info->netlock, flags); - info->netcount=0; - spin_unlock_irqrestore(&info->netlock, flags); - - return 0; -} - -/** - * called by network layer to process IOCTL call to network device - * - * dev pointer to network device structure - * ifr pointer to network interface request structure - * cmd IOCTL command code - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - const size_t size = sizeof(sync_serial_settings); - sync_serial_settings new_line; - sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; - SLMP_INFO *info = dev_to_port(dev); - unsigned int flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s:hdlcdev_ioctl(%s)\n",__FILE__,dev->name); - - /* return error if TTY interface open */ - if (info->port.count) - return -EBUSY; - - if (cmd != SIOCWANDEV) - return hdlc_ioctl(dev, ifr, cmd); - - switch(ifr->ifr_settings.type) { - case IF_GET_IFACE: /* return current sync_serial_settings */ - - ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL; - if (ifr->ifr_settings.size < size) { - ifr->ifr_settings.size = size; /* data size wanted */ - return -ENOBUFS; - } - - flags = info->params.flags & (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | - HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | - HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | - HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); - - switch (flags){ - case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN): new_line.clock_type = CLOCK_EXT; break; - case (HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG): new_line.clock_type = CLOCK_INT; break; - case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG): new_line.clock_type = CLOCK_TXINT; break; - case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN): new_line.clock_type = CLOCK_TXFROMRX; break; - default: new_line.clock_type = CLOCK_DEFAULT; - } - - new_line.clock_rate = info->params.clock_speed; - new_line.loopback = info->params.loopback ? 1:0; - - if (copy_to_user(line, &new_line, size)) - return -EFAULT; - return 0; - - case IF_IFACE_SYNC_SERIAL: /* set sync_serial_settings */ - - if(!capable(CAP_NET_ADMIN)) - return -EPERM; - if (copy_from_user(&new_line, line, size)) - return -EFAULT; - - switch (new_line.clock_type) - { - case CLOCK_EXT: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN; break; - case CLOCK_TXFROMRX: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN; break; - case CLOCK_INT: flags = HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG; break; - case CLOCK_TXINT: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG; break; - case CLOCK_DEFAULT: flags = info->params.flags & - (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | - HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | - HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | - HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); break; - default: return -EINVAL; - } - - if (new_line.loopback != 0 && new_line.loopback != 1) - return -EINVAL; - - info->params.flags &= ~(HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | - HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | - HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | - HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); - info->params.flags |= flags; - - info->params.loopback = new_line.loopback; - - if (flags & (HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG)) - info->params.clock_speed = new_line.clock_rate; - else - info->params.clock_speed = 0; - - /* if network interface up, reprogram hardware */ - if (info->netcount) - program_hw(info); - return 0; - - default: - return hdlc_ioctl(dev, ifr, cmd); - } -} - -/** - * called by network layer when transmit timeout is detected - * - * dev pointer to network device structure - */ -static void hdlcdev_tx_timeout(struct net_device *dev) -{ - SLMP_INFO *info = dev_to_port(dev); - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("hdlcdev_tx_timeout(%s)\n",dev->name); - - dev->stats.tx_errors++; - dev->stats.tx_aborted_errors++; - - spin_lock_irqsave(&info->lock,flags); - tx_stop(info); - spin_unlock_irqrestore(&info->lock,flags); - - netif_wake_queue(dev); -} - -/** - * called by device driver when transmit completes - * reenable network layer transmit if stopped - * - * info pointer to device instance information - */ -static void hdlcdev_tx_done(SLMP_INFO *info) -{ - if (netif_queue_stopped(info->netdev)) - netif_wake_queue(info->netdev); -} - -/** - * called by device driver when frame received - * pass frame to network layer - * - * info pointer to device instance information - * buf pointer to buffer contianing frame data - * size count of data bytes in buf - */ -static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size) -{ - struct sk_buff *skb = dev_alloc_skb(size); - struct net_device *dev = info->netdev; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("hdlcdev_rx(%s)\n",dev->name); - - if (skb == NULL) { - printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n", - dev->name); - dev->stats.rx_dropped++; - return; - } - - memcpy(skb_put(skb, size), buf, size); - - skb->protocol = hdlc_type_trans(skb, dev); - - dev->stats.rx_packets++; - dev->stats.rx_bytes += size; - - netif_rx(skb); -} - -static const struct net_device_ops hdlcdev_ops = { - .ndo_open = hdlcdev_open, - .ndo_stop = hdlcdev_close, - .ndo_change_mtu = hdlc_change_mtu, - .ndo_start_xmit = hdlc_start_xmit, - .ndo_do_ioctl = hdlcdev_ioctl, - .ndo_tx_timeout = hdlcdev_tx_timeout, -}; - -/** - * called by device driver when adding device instance - * do generic HDLC initialization - * - * info pointer to device instance information - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_init(SLMP_INFO *info) -{ - int rc; - struct net_device *dev; - hdlc_device *hdlc; - - /* allocate and initialize network and HDLC layer objects */ - - if (!(dev = alloc_hdlcdev(info))) { - printk(KERN_ERR "%s:hdlc device allocation failure\n",__FILE__); - return -ENOMEM; - } - - /* for network layer reporting purposes only */ - dev->mem_start = info->phys_sca_base; - dev->mem_end = info->phys_sca_base + SCA_BASE_SIZE - 1; - dev->irq = info->irq_level; - - /* network layer callbacks and settings */ - dev->netdev_ops = &hdlcdev_ops; - dev->watchdog_timeo = 10 * HZ; - dev->tx_queue_len = 50; - - /* generic HDLC layer callbacks and settings */ - hdlc = dev_to_hdlc(dev); - hdlc->attach = hdlcdev_attach; - hdlc->xmit = hdlcdev_xmit; - - /* register objects with HDLC layer */ - if ((rc = register_hdlc_device(dev))) { - printk(KERN_WARNING "%s:unable to register hdlc device\n",__FILE__); - free_netdev(dev); - return rc; - } - - info->netdev = dev; - return 0; -} - -/** - * called by device driver when removing device instance - * do generic HDLC cleanup - * - * info pointer to device instance information - */ -static void hdlcdev_exit(SLMP_INFO *info) -{ - unregister_hdlc_device(info->netdev); - free_netdev(info->netdev); - info->netdev = NULL; -} - -#endif /* CONFIG_HDLC */ - - -/* Return next bottom half action to perform. - * Return Value: BH action code or 0 if nothing to do. - */ -static int bh_action(SLMP_INFO *info) -{ - unsigned long flags; - int rc = 0; - - spin_lock_irqsave(&info->lock,flags); - - if (info->pending_bh & BH_RECEIVE) { - info->pending_bh &= ~BH_RECEIVE; - rc = BH_RECEIVE; - } else if (info->pending_bh & BH_TRANSMIT) { - info->pending_bh &= ~BH_TRANSMIT; - rc = BH_TRANSMIT; - } else if (info->pending_bh & BH_STATUS) { - info->pending_bh &= ~BH_STATUS; - rc = BH_STATUS; - } - - if (!rc) { - /* Mark BH routine as complete */ - info->bh_running = false; - info->bh_requested = false; - } - - spin_unlock_irqrestore(&info->lock,flags); - - return rc; -} - -/* Perform bottom half processing of work items queued by ISR. - */ -static void bh_handler(struct work_struct *work) -{ - SLMP_INFO *info = container_of(work, SLMP_INFO, task); - int action; - - if (!info) - return; - - if ( debug_level >= DEBUG_LEVEL_BH ) - printk( "%s(%d):%s bh_handler() entry\n", - __FILE__,__LINE__,info->device_name); - - info->bh_running = true; - - while((action = bh_action(info)) != 0) { - - /* Process work item */ - if ( debug_level >= DEBUG_LEVEL_BH ) - printk( "%s(%d):%s bh_handler() work item action=%d\n", - __FILE__,__LINE__,info->device_name, action); - - switch (action) { - - case BH_RECEIVE: - bh_receive(info); - break; - case BH_TRANSMIT: - bh_transmit(info); - break; - case BH_STATUS: - bh_status(info); - break; - default: - /* unknown work item ID */ - printk("%s(%d):%s Unknown work item ID=%08X!\n", - __FILE__,__LINE__,info->device_name,action); - break; - } - } - - if ( debug_level >= DEBUG_LEVEL_BH ) - printk( "%s(%d):%s bh_handler() exit\n", - __FILE__,__LINE__,info->device_name); -} - -static void bh_receive(SLMP_INFO *info) -{ - if ( debug_level >= DEBUG_LEVEL_BH ) - printk( "%s(%d):%s bh_receive()\n", - __FILE__,__LINE__,info->device_name); - - while( rx_get_frame(info) ); -} - -static void bh_transmit(SLMP_INFO *info) -{ - struct tty_struct *tty = info->port.tty; - - if ( debug_level >= DEBUG_LEVEL_BH ) - printk( "%s(%d):%s bh_transmit() entry\n", - __FILE__,__LINE__,info->device_name); - - if (tty) - tty_wakeup(tty); -} - -static void bh_status(SLMP_INFO *info) -{ - if ( debug_level >= DEBUG_LEVEL_BH ) - printk( "%s(%d):%s bh_status() entry\n", - __FILE__,__LINE__,info->device_name); - - info->ri_chkcount = 0; - info->dsr_chkcount = 0; - info->dcd_chkcount = 0; - info->cts_chkcount = 0; -} - -static void isr_timer(SLMP_INFO * info) -{ - unsigned char timer = (info->port_num & 1) ? TIMER2 : TIMER0; - - /* IER2<7..4> = timer<3..0> interrupt enables (0=disabled) */ - write_reg(info, IER2, 0); - - /* TMCS, Timer Control/Status Register - * - * 07 CMF, Compare match flag (read only) 1=match - * 06 ECMI, CMF Interrupt Enable: 0=disabled - * 05 Reserved, must be 0 - * 04 TME, Timer Enable - * 03..00 Reserved, must be 0 - * - * 0000 0000 - */ - write_reg(info, (unsigned char)(timer + TMCS), 0); - - info->irq_occurred = true; - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):%s isr_timer()\n", - __FILE__,__LINE__,info->device_name); -} - -static void isr_rxint(SLMP_INFO * info) -{ - struct tty_struct *tty = info->port.tty; - struct mgsl_icount *icount = &info->icount; - unsigned char status = read_reg(info, SR1) & info->ie1_value & (FLGD + IDLD + CDCD + BRKD); - unsigned char status2 = read_reg(info, SR2) & info->ie2_value & OVRN; - - /* clear status bits */ - if (status) - write_reg(info, SR1, status); - - if (status2) - write_reg(info, SR2, status2); - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):%s isr_rxint status=%02X %02x\n", - __FILE__,__LINE__,info->device_name,status,status2); - - if (info->params.mode == MGSL_MODE_ASYNC) { - if (status & BRKD) { - icount->brk++; - - /* process break detection if tty control - * is not set to ignore it - */ - if ( tty ) { - if (!(status & info->ignore_status_mask1)) { - if (info->read_status_mask1 & BRKD) { - tty_insert_flip_char(tty, 0, TTY_BREAK); - if (info->port.flags & ASYNC_SAK) - do_SAK(tty); - } - } - } - } - } - else { - if (status & (FLGD|IDLD)) { - if (status & FLGD) - info->icount.exithunt++; - else if (status & IDLD) - info->icount.rxidle++; - wake_up_interruptible(&info->event_wait_q); - } - } - - if (status & CDCD) { - /* simulate a common modem status change interrupt - * for our handler - */ - get_signals( info ); - isr_io_pin(info, - MISCSTATUS_DCD_LATCHED|(info->serial_signals&SerialSignal_DCD)); - } -} - -/* - * handle async rx data interrupts - */ -static void isr_rxrdy(SLMP_INFO * info) -{ - u16 status; - unsigned char DataByte; - struct tty_struct *tty = info->port.tty; - struct mgsl_icount *icount = &info->icount; - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):%s isr_rxrdy\n", - __FILE__,__LINE__,info->device_name); - - while((status = read_reg(info,CST0)) & BIT0) - { - int flag = 0; - bool over = false; - DataByte = read_reg(info,TRB); - - icount->rx++; - - if ( status & (PE + FRME + OVRN) ) { - printk("%s(%d):%s rxerr=%04X\n", - __FILE__,__LINE__,info->device_name,status); - - /* update error statistics */ - if (status & PE) - icount->parity++; - else if (status & FRME) - icount->frame++; - else if (status & OVRN) - icount->overrun++; - - /* discard char if tty control flags say so */ - if (status & info->ignore_status_mask2) - continue; - - status &= info->read_status_mask2; - - if ( tty ) { - if (status & PE) - flag = TTY_PARITY; - else if (status & FRME) - flag = TTY_FRAME; - if (status & OVRN) { - /* Overrun is special, since it's - * reported immediately, and doesn't - * affect the current character - */ - over = true; - } - } - } /* end of if (error) */ - - if ( tty ) { - tty_insert_flip_char(tty, DataByte, flag); - if (over) - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - } - } - - if ( debug_level >= DEBUG_LEVEL_ISR ) { - printk("%s(%d):%s rx=%d brk=%d parity=%d frame=%d overrun=%d\n", - __FILE__,__LINE__,info->device_name, - icount->rx,icount->brk,icount->parity, - icount->frame,icount->overrun); - } - - if ( tty ) - tty_flip_buffer_push(tty); -} - -static void isr_txeom(SLMP_INFO * info, unsigned char status) -{ - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):%s isr_txeom status=%02x\n", - __FILE__,__LINE__,info->device_name,status); - - write_reg(info, TXDMA + DIR, 0x00); /* disable Tx DMA IRQs */ - write_reg(info, TXDMA + DSR, 0xc0); /* clear IRQs and disable DMA */ - write_reg(info, TXDMA + DCMD, SWABORT); /* reset/init DMA channel */ - - if (status & UDRN) { - write_reg(info, CMD, TXRESET); - write_reg(info, CMD, TXENABLE); - } else - write_reg(info, CMD, TXBUFCLR); - - /* disable and clear tx interrupts */ - info->ie0_value &= ~TXRDYE; - info->ie1_value &= ~(IDLE + UDRN); - write_reg16(info, IE0, (unsigned short)((info->ie1_value << 8) + info->ie0_value)); - write_reg(info, SR1, (unsigned char)(UDRN + IDLE)); - - if ( info->tx_active ) { - if (info->params.mode != MGSL_MODE_ASYNC) { - if (status & UDRN) - info->icount.txunder++; - else if (status & IDLE) - info->icount.txok++; - } - - info->tx_active = false; - info->tx_count = info->tx_put = info->tx_get = 0; - - del_timer(&info->tx_timer); - - if (info->params.mode != MGSL_MODE_ASYNC && info->drop_rts_on_tx_done ) { - info->serial_signals &= ~SerialSignal_RTS; - info->drop_rts_on_tx_done = false; - set_signals(info); - } - -#if SYNCLINK_GENERIC_HDLC - if (info->netcount) - hdlcdev_tx_done(info); - else -#endif - { - if (info->port.tty && (info->port.tty->stopped || info->port.tty->hw_stopped)) { - tx_stop(info); - return; - } - info->pending_bh |= BH_TRANSMIT; - } - } -} - - -/* - * handle tx status interrupts - */ -static void isr_txint(SLMP_INFO * info) -{ - unsigned char status = read_reg(info, SR1) & info->ie1_value & (UDRN + IDLE + CCTS); - - /* clear status bits */ - write_reg(info, SR1, status); - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):%s isr_txint status=%02x\n", - __FILE__,__LINE__,info->device_name,status); - - if (status & (UDRN + IDLE)) - isr_txeom(info, status); - - if (status & CCTS) { - /* simulate a common modem status change interrupt - * for our handler - */ - get_signals( info ); - isr_io_pin(info, - MISCSTATUS_CTS_LATCHED|(info->serial_signals&SerialSignal_CTS)); - - } -} - -/* - * handle async tx data interrupts - */ -static void isr_txrdy(SLMP_INFO * info) -{ - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):%s isr_txrdy() tx_count=%d\n", - __FILE__,__LINE__,info->device_name,info->tx_count); - - if (info->params.mode != MGSL_MODE_ASYNC) { - /* disable TXRDY IRQ, enable IDLE IRQ */ - info->ie0_value &= ~TXRDYE; - info->ie1_value |= IDLE; - write_reg16(info, IE0, (unsigned short)((info->ie1_value << 8) + info->ie0_value)); - return; - } - - if (info->port.tty && (info->port.tty->stopped || info->port.tty->hw_stopped)) { - tx_stop(info); - return; - } - - if ( info->tx_count ) - tx_load_fifo( info ); - else { - info->tx_active = false; - info->ie0_value &= ~TXRDYE; - write_reg(info, IE0, info->ie0_value); - } - - if (info->tx_count < WAKEUP_CHARS) - info->pending_bh |= BH_TRANSMIT; -} - -static void isr_rxdmaok(SLMP_INFO * info) -{ - /* BIT7 = EOT (end of transfer) - * BIT6 = EOM (end of message/frame) - */ - unsigned char status = read_reg(info,RXDMA + DSR) & 0xc0; - - /* clear IRQ (BIT0 must be 1 to prevent clearing DE bit) */ - write_reg(info, RXDMA + DSR, (unsigned char)(status | 1)); - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):%s isr_rxdmaok(), status=%02x\n", - __FILE__,__LINE__,info->device_name,status); - - info->pending_bh |= BH_RECEIVE; -} - -static void isr_rxdmaerror(SLMP_INFO * info) -{ - /* BIT5 = BOF (buffer overflow) - * BIT4 = COF (counter overflow) - */ - unsigned char status = read_reg(info,RXDMA + DSR) & 0x30; - - /* clear IRQ (BIT0 must be 1 to prevent clearing DE bit) */ - write_reg(info, RXDMA + DSR, (unsigned char)(status | 1)); - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):%s isr_rxdmaerror(), status=%02x\n", - __FILE__,__LINE__,info->device_name,status); - - info->rx_overflow = true; - info->pending_bh |= BH_RECEIVE; -} - -static void isr_txdmaok(SLMP_INFO * info) -{ - unsigned char status_reg1 = read_reg(info, SR1); - - write_reg(info, TXDMA + DIR, 0x00); /* disable Tx DMA IRQs */ - write_reg(info, TXDMA + DSR, 0xc0); /* clear IRQs and disable DMA */ - write_reg(info, TXDMA + DCMD, SWABORT); /* reset/init DMA channel */ - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):%s isr_txdmaok(), status=%02x\n", - __FILE__,__LINE__,info->device_name,status_reg1); - - /* program TXRDY as FIFO empty flag, enable TXRDY IRQ */ - write_reg16(info, TRC0, 0); - info->ie0_value |= TXRDYE; - write_reg(info, IE0, info->ie0_value); -} - -static void isr_txdmaerror(SLMP_INFO * info) -{ - /* BIT5 = BOF (buffer overflow) - * BIT4 = COF (counter overflow) - */ - unsigned char status = read_reg(info,TXDMA + DSR) & 0x30; - - /* clear IRQ (BIT0 must be 1 to prevent clearing DE bit) */ - write_reg(info, TXDMA + DSR, (unsigned char)(status | 1)); - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):%s isr_txdmaerror(), status=%02x\n", - __FILE__,__LINE__,info->device_name,status); -} - -/* handle input serial signal changes - */ -static void isr_io_pin( SLMP_INFO *info, u16 status ) -{ - struct mgsl_icount *icount; - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):isr_io_pin status=%04X\n", - __FILE__,__LINE__,status); - - if (status & (MISCSTATUS_CTS_LATCHED | MISCSTATUS_DCD_LATCHED | - MISCSTATUS_DSR_LATCHED | MISCSTATUS_RI_LATCHED) ) { - icount = &info->icount; - /* update input line counters */ - if (status & MISCSTATUS_RI_LATCHED) { - icount->rng++; - if ( status & SerialSignal_RI ) - info->input_signal_events.ri_up++; - else - info->input_signal_events.ri_down++; - } - if (status & MISCSTATUS_DSR_LATCHED) { - icount->dsr++; - if ( status & SerialSignal_DSR ) - info->input_signal_events.dsr_up++; - else - info->input_signal_events.dsr_down++; - } - if (status & MISCSTATUS_DCD_LATCHED) { - if ((info->dcd_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT) { - info->ie1_value &= ~CDCD; - write_reg(info, IE1, info->ie1_value); - } - icount->dcd++; - if (status & SerialSignal_DCD) { - info->input_signal_events.dcd_up++; - } else - info->input_signal_events.dcd_down++; -#if SYNCLINK_GENERIC_HDLC - if (info->netcount) { - if (status & SerialSignal_DCD) - netif_carrier_on(info->netdev); - else - netif_carrier_off(info->netdev); - } -#endif - } - if (status & MISCSTATUS_CTS_LATCHED) - { - if ((info->cts_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT) { - info->ie1_value &= ~CCTS; - write_reg(info, IE1, info->ie1_value); - } - icount->cts++; - if ( status & SerialSignal_CTS ) - info->input_signal_events.cts_up++; - else - info->input_signal_events.cts_down++; - } - wake_up_interruptible(&info->status_event_wait_q); - wake_up_interruptible(&info->event_wait_q); - - if ( (info->port.flags & ASYNC_CHECK_CD) && - (status & MISCSTATUS_DCD_LATCHED) ) { - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s CD now %s...", info->device_name, - (status & SerialSignal_DCD) ? "on" : "off"); - if (status & SerialSignal_DCD) - wake_up_interruptible(&info->port.open_wait); - else { - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("doing serial hangup..."); - if (info->port.tty) - tty_hangup(info->port.tty); - } - } - - if ( (info->port.flags & ASYNC_CTS_FLOW) && - (status & MISCSTATUS_CTS_LATCHED) ) { - if ( info->port.tty ) { - if (info->port.tty->hw_stopped) { - if (status & SerialSignal_CTS) { - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("CTS tx start..."); - info->port.tty->hw_stopped = 0; - tx_start(info); - info->pending_bh |= BH_TRANSMIT; - return; - } - } else { - if (!(status & SerialSignal_CTS)) { - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("CTS tx stop..."); - info->port.tty->hw_stopped = 1; - tx_stop(info); - } - } - } - } - } - - info->pending_bh |= BH_STATUS; -} - -/* Interrupt service routine entry point. - * - * Arguments: - * irq interrupt number that caused interrupt - * dev_id device ID supplied during interrupt registration - * regs interrupted processor context - */ -static irqreturn_t synclinkmp_interrupt(int dummy, void *dev_id) -{ - SLMP_INFO *info = dev_id; - unsigned char status, status0, status1=0; - unsigned char dmastatus, dmastatus0, dmastatus1=0; - unsigned char timerstatus0, timerstatus1=0; - unsigned char shift; - unsigned int i; - unsigned short tmp; - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk(KERN_DEBUG "%s(%d): synclinkmp_interrupt(%d)entry.\n", - __FILE__, __LINE__, info->irq_level); - - spin_lock(&info->lock); - - for(;;) { - - /* get status for SCA0 (ports 0-1) */ - tmp = read_reg16(info, ISR0); /* get ISR0 and ISR1 in one read */ - status0 = (unsigned char)tmp; - dmastatus0 = (unsigned char)(tmp>>8); - timerstatus0 = read_reg(info, ISR2); - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk(KERN_DEBUG "%s(%d):%s status0=%02x, dmastatus0=%02x, timerstatus0=%02x\n", - __FILE__, __LINE__, info->device_name, - status0, dmastatus0, timerstatus0); - - if (info->port_count == 4) { - /* get status for SCA1 (ports 2-3) */ - tmp = read_reg16(info->port_array[2], ISR0); - status1 = (unsigned char)tmp; - dmastatus1 = (unsigned char)(tmp>>8); - timerstatus1 = read_reg(info->port_array[2], ISR2); - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):%s status1=%02x, dmastatus1=%02x, timerstatus1=%02x\n", - __FILE__,__LINE__,info->device_name, - status1,dmastatus1,timerstatus1); - } - - if (!status0 && !dmastatus0 && !timerstatus0 && - !status1 && !dmastatus1 && !timerstatus1) - break; - - for(i=0; i < info->port_count ; i++) { - if (info->port_array[i] == NULL) - continue; - if (i < 2) { - status = status0; - dmastatus = dmastatus0; - } else { - status = status1; - dmastatus = dmastatus1; - } - - shift = i & 1 ? 4 :0; - - if (status & BIT0 << shift) - isr_rxrdy(info->port_array[i]); - if (status & BIT1 << shift) - isr_txrdy(info->port_array[i]); - if (status & BIT2 << shift) - isr_rxint(info->port_array[i]); - if (status & BIT3 << shift) - isr_txint(info->port_array[i]); - - if (dmastatus & BIT0 << shift) - isr_rxdmaerror(info->port_array[i]); - if (dmastatus & BIT1 << shift) - isr_rxdmaok(info->port_array[i]); - if (dmastatus & BIT2 << shift) - isr_txdmaerror(info->port_array[i]); - if (dmastatus & BIT3 << shift) - isr_txdmaok(info->port_array[i]); - } - - if (timerstatus0 & (BIT5 | BIT4)) - isr_timer(info->port_array[0]); - if (timerstatus0 & (BIT7 | BIT6)) - isr_timer(info->port_array[1]); - if (timerstatus1 & (BIT5 | BIT4)) - isr_timer(info->port_array[2]); - if (timerstatus1 & (BIT7 | BIT6)) - isr_timer(info->port_array[3]); - } - - for(i=0; i < info->port_count ; i++) { - SLMP_INFO * port = info->port_array[i]; - - /* Request bottom half processing if there's something - * for it to do and the bh is not already running. - * - * Note: startup adapter diags require interrupts. - * do not request bottom half processing if the - * device is not open in a normal mode. - */ - if ( port && (port->port.count || port->netcount) && - port->pending_bh && !port->bh_running && - !port->bh_requested ) { - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk("%s(%d):%s queueing bh task.\n", - __FILE__,__LINE__,port->device_name); - schedule_work(&port->task); - port->bh_requested = true; - } - } - - spin_unlock(&info->lock); - - if ( debug_level >= DEBUG_LEVEL_ISR ) - printk(KERN_DEBUG "%s(%d):synclinkmp_interrupt(%d)exit.\n", - __FILE__, __LINE__, info->irq_level); - return IRQ_HANDLED; -} - -/* Initialize and start device. - */ -static int startup(SLMP_INFO * info) -{ - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk("%s(%d):%s tx_releaseup()\n",__FILE__,__LINE__,info->device_name); - - if (info->port.flags & ASYNC_INITIALIZED) - return 0; - - if (!info->tx_buf) { - info->tx_buf = kmalloc(info->max_frame_size, GFP_KERNEL); - if (!info->tx_buf) { - printk(KERN_ERR"%s(%d):%s can't allocate transmit buffer\n", - __FILE__,__LINE__,info->device_name); - return -ENOMEM; - } - } - - info->pending_bh = 0; - - memset(&info->icount, 0, sizeof(info->icount)); - - /* program hardware for current parameters */ - reset_port(info); - - change_params(info); - - mod_timer(&info->status_timer, jiffies + msecs_to_jiffies(10)); - - if (info->port.tty) - clear_bit(TTY_IO_ERROR, &info->port.tty->flags); - - info->port.flags |= ASYNC_INITIALIZED; - - return 0; -} - -/* Called by close() and hangup() to shutdown hardware - */ -static void shutdown(SLMP_INFO * info) -{ - unsigned long flags; - - if (!(info->port.flags & ASYNC_INITIALIZED)) - return; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s synclinkmp_shutdown()\n", - __FILE__,__LINE__, info->device_name ); - - /* clear status wait queue because status changes */ - /* can't happen after shutting down the hardware */ - wake_up_interruptible(&info->status_event_wait_q); - wake_up_interruptible(&info->event_wait_q); - - del_timer(&info->tx_timer); - del_timer(&info->status_timer); - - kfree(info->tx_buf); - info->tx_buf = NULL; - - spin_lock_irqsave(&info->lock,flags); - - reset_port(info); - - if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) { - info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); - set_signals(info); - } - - spin_unlock_irqrestore(&info->lock,flags); - - if (info->port.tty) - set_bit(TTY_IO_ERROR, &info->port.tty->flags); - - info->port.flags &= ~ASYNC_INITIALIZED; -} - -static void program_hw(SLMP_INFO *info) -{ - unsigned long flags; - - spin_lock_irqsave(&info->lock,flags); - - rx_stop(info); - tx_stop(info); - - info->tx_count = info->tx_put = info->tx_get = 0; - - if (info->params.mode == MGSL_MODE_HDLC || info->netcount) - hdlc_mode(info); - else - async_mode(info); - - set_signals(info); - - info->dcd_chkcount = 0; - info->cts_chkcount = 0; - info->ri_chkcount = 0; - info->dsr_chkcount = 0; - - info->ie1_value |= (CDCD|CCTS); - write_reg(info, IE1, info->ie1_value); - - get_signals(info); - - if (info->netcount || (info->port.tty && info->port.tty->termios->c_cflag & CREAD) ) - rx_start(info); - - spin_unlock_irqrestore(&info->lock,flags); -} - -/* Reconfigure adapter based on new parameters - */ -static void change_params(SLMP_INFO *info) -{ - unsigned cflag; - int bits_per_char; - - if (!info->port.tty || !info->port.tty->termios) - return; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s change_params()\n", - __FILE__,__LINE__, info->device_name ); - - cflag = info->port.tty->termios->c_cflag; - - /* if B0 rate (hangup) specified then negate DTR and RTS */ - /* otherwise assert DTR and RTS */ - if (cflag & CBAUD) - info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; - else - info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); - - /* byte size and parity */ - - switch (cflag & CSIZE) { - case CS5: info->params.data_bits = 5; break; - case CS6: info->params.data_bits = 6; break; - case CS7: info->params.data_bits = 7; break; - case CS8: info->params.data_bits = 8; break; - /* Never happens, but GCC is too dumb to figure it out */ - default: info->params.data_bits = 7; break; - } - - if (cflag & CSTOPB) - info->params.stop_bits = 2; - else - info->params.stop_bits = 1; - - info->params.parity = ASYNC_PARITY_NONE; - if (cflag & PARENB) { - if (cflag & PARODD) - info->params.parity = ASYNC_PARITY_ODD; - else - info->params.parity = ASYNC_PARITY_EVEN; -#ifdef CMSPAR - if (cflag & CMSPAR) - info->params.parity = ASYNC_PARITY_SPACE; -#endif - } - - /* calculate number of jiffies to transmit a full - * FIFO (32 bytes) at specified data rate - */ - bits_per_char = info->params.data_bits + - info->params.stop_bits + 1; - - /* if port data rate is set to 460800 or less then - * allow tty settings to override, otherwise keep the - * current data rate. - */ - if (info->params.data_rate <= 460800) { - info->params.data_rate = tty_get_baud_rate(info->port.tty); - } - - if ( info->params.data_rate ) { - info->timeout = (32*HZ*bits_per_char) / - info->params.data_rate; - } - info->timeout += HZ/50; /* Add .02 seconds of slop */ - - if (cflag & CRTSCTS) - info->port.flags |= ASYNC_CTS_FLOW; - else - info->port.flags &= ~ASYNC_CTS_FLOW; - - if (cflag & CLOCAL) - info->port.flags &= ~ASYNC_CHECK_CD; - else - info->port.flags |= ASYNC_CHECK_CD; - - /* process tty input control flags */ - - info->read_status_mask2 = OVRN; - if (I_INPCK(info->port.tty)) - info->read_status_mask2 |= PE | FRME; - if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) - info->read_status_mask1 |= BRKD; - if (I_IGNPAR(info->port.tty)) - info->ignore_status_mask2 |= PE | FRME; - if (I_IGNBRK(info->port.tty)) { - info->ignore_status_mask1 |= BRKD; - /* If ignoring parity and break indicators, ignore - * overruns too. (For real raw support). - */ - if (I_IGNPAR(info->port.tty)) - info->ignore_status_mask2 |= OVRN; - } - - program_hw(info); -} - -static int get_stats(SLMP_INFO * info, struct mgsl_icount __user *user_icount) -{ - int err; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s get_params()\n", - __FILE__,__LINE__, info->device_name); - - if (!user_icount) { - memset(&info->icount, 0, sizeof(info->icount)); - } else { - mutex_lock(&info->port.mutex); - COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount)); - mutex_unlock(&info->port.mutex); - if (err) - return -EFAULT; - } - - return 0; -} - -static int get_params(SLMP_INFO * info, MGSL_PARAMS __user *user_params) -{ - int err; - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s get_params()\n", - __FILE__,__LINE__, info->device_name); - - mutex_lock(&info->port.mutex); - COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS)); - mutex_unlock(&info->port.mutex); - if (err) { - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):%s get_params() user buffer copy failed\n", - __FILE__,__LINE__,info->device_name); - return -EFAULT; - } - - return 0; -} - -static int set_params(SLMP_INFO * info, MGSL_PARAMS __user *new_params) -{ - unsigned long flags; - MGSL_PARAMS tmp_params; - int err; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s set_params\n", - __FILE__,__LINE__,info->device_name ); - COPY_FROM_USER(err,&tmp_params, new_params, sizeof(MGSL_PARAMS)); - if (err) { - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):%s set_params() user buffer copy failed\n", - __FILE__,__LINE__,info->device_name); - return -EFAULT; - } - - mutex_lock(&info->port.mutex); - spin_lock_irqsave(&info->lock,flags); - memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS)); - spin_unlock_irqrestore(&info->lock,flags); - - change_params(info); - mutex_unlock(&info->port.mutex); - - return 0; -} - -static int get_txidle(SLMP_INFO * info, int __user *idle_mode) -{ - int err; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s get_txidle()=%d\n", - __FILE__,__LINE__, info->device_name, info->idle_mode); - - COPY_TO_USER(err,idle_mode, &info->idle_mode, sizeof(int)); - if (err) { - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):%s get_txidle() user buffer copy failed\n", - __FILE__,__LINE__,info->device_name); - return -EFAULT; - } - - return 0; -} - -static int set_txidle(SLMP_INFO * info, int idle_mode) -{ - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s set_txidle(%d)\n", - __FILE__,__LINE__,info->device_name, idle_mode ); - - spin_lock_irqsave(&info->lock,flags); - info->idle_mode = idle_mode; - tx_set_idle( info ); - spin_unlock_irqrestore(&info->lock,flags); - return 0; -} - -static int tx_enable(SLMP_INFO * info, int enable) -{ - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s tx_enable(%d)\n", - __FILE__,__LINE__,info->device_name, enable); - - spin_lock_irqsave(&info->lock,flags); - if ( enable ) { - if ( !info->tx_enabled ) { - tx_start(info); - } - } else { - if ( info->tx_enabled ) - tx_stop(info); - } - spin_unlock_irqrestore(&info->lock,flags); - return 0; -} - -/* abort send HDLC frame - */ -static int tx_abort(SLMP_INFO * info) -{ - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s tx_abort()\n", - __FILE__,__LINE__,info->device_name); - - spin_lock_irqsave(&info->lock,flags); - if ( info->tx_active && info->params.mode == MGSL_MODE_HDLC ) { - info->ie1_value &= ~UDRN; - info->ie1_value |= IDLE; - write_reg(info, IE1, info->ie1_value); /* disable tx status interrupts */ - write_reg(info, SR1, (unsigned char)(IDLE + UDRN)); /* clear pending */ - - write_reg(info, TXDMA + DSR, 0); /* disable DMA channel */ - write_reg(info, TXDMA + DCMD, SWABORT); /* reset/init DMA channel */ - - write_reg(info, CMD, TXABORT); - } - spin_unlock_irqrestore(&info->lock,flags); - return 0; -} - -static int rx_enable(SLMP_INFO * info, int enable) -{ - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s rx_enable(%d)\n", - __FILE__,__LINE__,info->device_name,enable); - - spin_lock_irqsave(&info->lock,flags); - if ( enable ) { - if ( !info->rx_enabled ) - rx_start(info); - } else { - if ( info->rx_enabled ) - rx_stop(info); - } - spin_unlock_irqrestore(&info->lock,flags); - return 0; -} - -/* wait for specified event to occur - */ -static int wait_mgsl_event(SLMP_INFO * info, int __user *mask_ptr) -{ - unsigned long flags; - int s; - int rc=0; - struct mgsl_icount cprev, cnow; - int events; - int mask; - struct _input_signal_events oldsigs, newsigs; - DECLARE_WAITQUEUE(wait, current); - - COPY_FROM_USER(rc,&mask, mask_ptr, sizeof(int)); - if (rc) { - return -EFAULT; - } - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s wait_mgsl_event(%d)\n", - __FILE__,__LINE__,info->device_name,mask); - - spin_lock_irqsave(&info->lock,flags); - - /* return immediately if state matches requested events */ - get_signals(info); - s = info->serial_signals; - - events = mask & - ( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) + - ((s & SerialSignal_DCD) ? MgslEvent_DcdActive:MgslEvent_DcdInactive) + - ((s & SerialSignal_CTS) ? MgslEvent_CtsActive:MgslEvent_CtsInactive) + - ((s & SerialSignal_RI) ? MgslEvent_RiActive :MgslEvent_RiInactive) ); - if (events) { - spin_unlock_irqrestore(&info->lock,flags); - goto exit; - } - - /* save current irq counts */ - cprev = info->icount; - oldsigs = info->input_signal_events; - - /* enable hunt and idle irqs if needed */ - if (mask & (MgslEvent_ExitHuntMode+MgslEvent_IdleReceived)) { - unsigned char oldval = info->ie1_value; - unsigned char newval = oldval + - (mask & MgslEvent_ExitHuntMode ? FLGD:0) + - (mask & MgslEvent_IdleReceived ? IDLD:0); - if ( oldval != newval ) { - info->ie1_value = newval; - write_reg(info, IE1, info->ie1_value); - } - } - - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&info->event_wait_q, &wait); - - spin_unlock_irqrestore(&info->lock,flags); - - for(;;) { - schedule(); - if (signal_pending(current)) { - rc = -ERESTARTSYS; - break; - } - - /* get current irq counts */ - spin_lock_irqsave(&info->lock,flags); - cnow = info->icount; - newsigs = info->input_signal_events; - set_current_state(TASK_INTERRUPTIBLE); - spin_unlock_irqrestore(&info->lock,flags); - - /* if no change, wait aborted for some reason */ - if (newsigs.dsr_up == oldsigs.dsr_up && - newsigs.dsr_down == oldsigs.dsr_down && - newsigs.dcd_up == oldsigs.dcd_up && - newsigs.dcd_down == oldsigs.dcd_down && - newsigs.cts_up == oldsigs.cts_up && - newsigs.cts_down == oldsigs.cts_down && - newsigs.ri_up == oldsigs.ri_up && - newsigs.ri_down == oldsigs.ri_down && - cnow.exithunt == cprev.exithunt && - cnow.rxidle == cprev.rxidle) { - rc = -EIO; - break; - } - - events = mask & - ( (newsigs.dsr_up != oldsigs.dsr_up ? MgslEvent_DsrActive:0) + - (newsigs.dsr_down != oldsigs.dsr_down ? MgslEvent_DsrInactive:0) + - (newsigs.dcd_up != oldsigs.dcd_up ? MgslEvent_DcdActive:0) + - (newsigs.dcd_down != oldsigs.dcd_down ? MgslEvent_DcdInactive:0) + - (newsigs.cts_up != oldsigs.cts_up ? MgslEvent_CtsActive:0) + - (newsigs.cts_down != oldsigs.cts_down ? MgslEvent_CtsInactive:0) + - (newsigs.ri_up != oldsigs.ri_up ? MgslEvent_RiActive:0) + - (newsigs.ri_down != oldsigs.ri_down ? MgslEvent_RiInactive:0) + - (cnow.exithunt != cprev.exithunt ? MgslEvent_ExitHuntMode:0) + - (cnow.rxidle != cprev.rxidle ? MgslEvent_IdleReceived:0) ); - if (events) - break; - - cprev = cnow; - oldsigs = newsigs; - } - - remove_wait_queue(&info->event_wait_q, &wait); - set_current_state(TASK_RUNNING); - - - if (mask & (MgslEvent_ExitHuntMode + MgslEvent_IdleReceived)) { - spin_lock_irqsave(&info->lock,flags); - if (!waitqueue_active(&info->event_wait_q)) { - /* disable enable exit hunt mode/idle rcvd IRQs */ - info->ie1_value &= ~(FLGD|IDLD); - write_reg(info, IE1, info->ie1_value); - } - spin_unlock_irqrestore(&info->lock,flags); - } -exit: - if ( rc == 0 ) - PUT_USER(rc, events, mask_ptr); - - return rc; -} - -static int modem_input_wait(SLMP_INFO *info,int arg) -{ - unsigned long flags; - int rc; - struct mgsl_icount cprev, cnow; - DECLARE_WAITQUEUE(wait, current); - - /* save current irq counts */ - spin_lock_irqsave(&info->lock,flags); - cprev = info->icount; - add_wait_queue(&info->status_event_wait_q, &wait); - set_current_state(TASK_INTERRUPTIBLE); - spin_unlock_irqrestore(&info->lock,flags); - - for(;;) { - schedule(); - if (signal_pending(current)) { - rc = -ERESTARTSYS; - break; - } - - /* get new irq counts */ - spin_lock_irqsave(&info->lock,flags); - cnow = info->icount; - set_current_state(TASK_INTERRUPTIBLE); - spin_unlock_irqrestore(&info->lock,flags); - - /* if no change, wait aborted for some reason */ - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { - rc = -EIO; - break; - } - - /* check for change in caller specified modem input */ - if ((arg & TIOCM_RNG && cnow.rng != cprev.rng) || - (arg & TIOCM_DSR && cnow.dsr != cprev.dsr) || - (arg & TIOCM_CD && cnow.dcd != cprev.dcd) || - (arg & TIOCM_CTS && cnow.cts != cprev.cts)) { - rc = 0; - break; - } - - cprev = cnow; - } - remove_wait_queue(&info->status_event_wait_q, &wait); - set_current_state(TASK_RUNNING); - return rc; -} - -/* return the state of the serial control and status signals - */ -static int tiocmget(struct tty_struct *tty) -{ - SLMP_INFO *info = tty->driver_data; - unsigned int result; - unsigned long flags; - - spin_lock_irqsave(&info->lock,flags); - get_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - - result = ((info->serial_signals & SerialSignal_RTS) ? TIOCM_RTS:0) + - ((info->serial_signals & SerialSignal_DTR) ? TIOCM_DTR:0) + - ((info->serial_signals & SerialSignal_DCD) ? TIOCM_CAR:0) + - ((info->serial_signals & SerialSignal_RI) ? TIOCM_RNG:0) + - ((info->serial_signals & SerialSignal_DSR) ? TIOCM_DSR:0) + - ((info->serial_signals & SerialSignal_CTS) ? TIOCM_CTS:0); - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s tiocmget() value=%08X\n", - __FILE__,__LINE__, info->device_name, result ); - return result; -} - -/* set modem control signals (DTR/RTS) - */ -static int tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - SLMP_INFO *info = tty->driver_data; - unsigned long flags; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s tiocmset(%x,%x)\n", - __FILE__,__LINE__,info->device_name, set, clear); - - if (set & TIOCM_RTS) - info->serial_signals |= SerialSignal_RTS; - if (set & TIOCM_DTR) - info->serial_signals |= SerialSignal_DTR; - if (clear & TIOCM_RTS) - info->serial_signals &= ~SerialSignal_RTS; - if (clear & TIOCM_DTR) - info->serial_signals &= ~SerialSignal_DTR; - - spin_lock_irqsave(&info->lock,flags); - set_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - - return 0; -} - -static int carrier_raised(struct tty_port *port) -{ - SLMP_INFO *info = container_of(port, SLMP_INFO, port); - unsigned long flags; - - spin_lock_irqsave(&info->lock,flags); - get_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - - return (info->serial_signals & SerialSignal_DCD) ? 1 : 0; -} - -static void dtr_rts(struct tty_port *port, int on) -{ - SLMP_INFO *info = container_of(port, SLMP_INFO, port); - unsigned long flags; - - spin_lock_irqsave(&info->lock,flags); - if (on) - info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; - else - info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); - set_signals(info); - spin_unlock_irqrestore(&info->lock,flags); -} - -/* Block the current process until the specified port is ready to open. - */ -static int block_til_ready(struct tty_struct *tty, struct file *filp, - SLMP_INFO *info) -{ - DECLARE_WAITQUEUE(wait, current); - int retval; - bool do_clocal = false; - bool extra_count = false; - unsigned long flags; - int cd; - struct tty_port *port = &info->port; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s block_til_ready()\n", - __FILE__,__LINE__, tty->driver->name ); - - if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ - /* nonblock mode is set or port is not enabled */ - /* just verify that callout device is not active */ - port->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - if (tty->termios->c_cflag & CLOCAL) - do_clocal = true; - - /* Wait for carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, port->count is dropped by one, so that - * close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - - retval = 0; - add_wait_queue(&port->open_wait, &wait); - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s block_til_ready() before block, count=%d\n", - __FILE__,__LINE__, tty->driver->name, port->count ); - - spin_lock_irqsave(&info->lock, flags); - if (!tty_hung_up_p(filp)) { - extra_count = true; - port->count--; - } - spin_unlock_irqrestore(&info->lock, flags); - port->blocked_open++; - - while (1) { - if (tty->termios->c_cflag & CBAUD) - tty_port_raise_dtr_rts(port); - - set_current_state(TASK_INTERRUPTIBLE); - - if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){ - retval = (port->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS; - break; - } - - cd = tty_port_carrier_raised(port); - - if (!(port->flags & ASYNC_CLOSING) && (do_clocal || cd)) - break; - - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s block_til_ready() count=%d\n", - __FILE__,__LINE__, tty->driver->name, port->count ); - - tty_unlock(); - schedule(); - tty_lock(); - } - - set_current_state(TASK_RUNNING); - remove_wait_queue(&port->open_wait, &wait); - - if (extra_count) - port->count++; - port->blocked_open--; - - if (debug_level >= DEBUG_LEVEL_INFO) - printk("%s(%d):%s block_til_ready() after, count=%d\n", - __FILE__,__LINE__, tty->driver->name, port->count ); - - if (!retval) - port->flags |= ASYNC_NORMAL_ACTIVE; - - return retval; -} - -static int alloc_dma_bufs(SLMP_INFO *info) -{ - unsigned short BuffersPerFrame; - unsigned short BufferCount; - - // Force allocation to start at 64K boundary for each port. - // This is necessary because *all* buffer descriptors for a port - // *must* be in the same 64K block. All descriptors on a port - // share a common 'base' address (upper 8 bits of 24 bits) programmed - // into the CBP register. - info->port_array[0]->last_mem_alloc = (SCA_MEM_SIZE/4) * info->port_num; - - /* Calculate the number of DMA buffers necessary to hold the */ - /* largest allowable frame size. Note: If the max frame size is */ - /* not an even multiple of the DMA buffer size then we need to */ - /* round the buffer count per frame up one. */ - - BuffersPerFrame = (unsigned short)(info->max_frame_size/SCABUFSIZE); - if ( info->max_frame_size % SCABUFSIZE ) - BuffersPerFrame++; - - /* calculate total number of data buffers (SCABUFSIZE) possible - * in one ports memory (SCA_MEM_SIZE/4) after allocating memory - * for the descriptor list (BUFFERLISTSIZE). - */ - BufferCount = (SCA_MEM_SIZE/4 - BUFFERLISTSIZE)/SCABUFSIZE; - - /* limit number of buffers to maximum amount of descriptors */ - if (BufferCount > BUFFERLISTSIZE/sizeof(SCADESC)) - BufferCount = BUFFERLISTSIZE/sizeof(SCADESC); - - /* use enough buffers to transmit one max size frame */ - info->tx_buf_count = BuffersPerFrame + 1; - - /* never use more than half the available buffers for transmit */ - if (info->tx_buf_count > (BufferCount/2)) - info->tx_buf_count = BufferCount/2; - - if (info->tx_buf_count > SCAMAXDESC) - info->tx_buf_count = SCAMAXDESC; - - /* use remaining buffers for receive */ - info->rx_buf_count = BufferCount - info->tx_buf_count; - - if (info->rx_buf_count > SCAMAXDESC) - info->rx_buf_count = SCAMAXDESC; - - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk("%s(%d):%s Allocating %d TX and %d RX DMA buffers.\n", - __FILE__,__LINE__, info->device_name, - info->tx_buf_count,info->rx_buf_count); - - if ( alloc_buf_list( info ) < 0 || - alloc_frame_bufs(info, - info->rx_buf_list, - info->rx_buf_list_ex, - info->rx_buf_count) < 0 || - alloc_frame_bufs(info, - info->tx_buf_list, - info->tx_buf_list_ex, - info->tx_buf_count) < 0 || - alloc_tmp_rx_buf(info) < 0 ) { - printk("%s(%d):%s Can't allocate DMA buffer memory\n", - __FILE__,__LINE__, info->device_name); - return -ENOMEM; - } - - rx_reset_buffers( info ); - - return 0; -} - -/* Allocate DMA buffers for the transmit and receive descriptor lists. - */ -static int alloc_buf_list(SLMP_INFO *info) -{ - unsigned int i; - - /* build list in adapter shared memory */ - info->buffer_list = info->memory_base + info->port_array[0]->last_mem_alloc; - info->buffer_list_phys = info->port_array[0]->last_mem_alloc; - info->port_array[0]->last_mem_alloc += BUFFERLISTSIZE; - - memset(info->buffer_list, 0, BUFFERLISTSIZE); - - /* Save virtual address pointers to the receive and */ - /* transmit buffer lists. (Receive 1st). These pointers will */ - /* be used by the processor to access the lists. */ - info->rx_buf_list = (SCADESC *)info->buffer_list; - - info->tx_buf_list = (SCADESC *)info->buffer_list; - info->tx_buf_list += info->rx_buf_count; - - /* Build links for circular buffer entry lists (tx and rx) - * - * Note: links are physical addresses read by the SCA device - * to determine the next buffer entry to use. - */ - - for ( i = 0; i < info->rx_buf_count; i++ ) { - /* calculate and store physical address of this buffer entry */ - info->rx_buf_list_ex[i].phys_entry = - info->buffer_list_phys + (i * sizeof(SCABUFSIZE)); - - /* calculate and store physical address of */ - /* next entry in cirular list of entries */ - info->rx_buf_list[i].next = info->buffer_list_phys; - if ( i < info->rx_buf_count - 1 ) - info->rx_buf_list[i].next += (i + 1) * sizeof(SCADESC); - - info->rx_buf_list[i].length = SCABUFSIZE; - } - - for ( i = 0; i < info->tx_buf_count; i++ ) { - /* calculate and store physical address of this buffer entry */ - info->tx_buf_list_ex[i].phys_entry = info->buffer_list_phys + - ((info->rx_buf_count + i) * sizeof(SCADESC)); - - /* calculate and store physical address of */ - /* next entry in cirular list of entries */ - - info->tx_buf_list[i].next = info->buffer_list_phys + - info->rx_buf_count * sizeof(SCADESC); - - if ( i < info->tx_buf_count - 1 ) - info->tx_buf_list[i].next += (i + 1) * sizeof(SCADESC); - } - - return 0; -} - -/* Allocate the frame DMA buffers used by the specified buffer list. - */ -static int alloc_frame_bufs(SLMP_INFO *info, SCADESC *buf_list,SCADESC_EX *buf_list_ex,int count) -{ - int i; - unsigned long phys_addr; - - for ( i = 0; i < count; i++ ) { - buf_list_ex[i].virt_addr = info->memory_base + info->port_array[0]->last_mem_alloc; - phys_addr = info->port_array[0]->last_mem_alloc; - info->port_array[0]->last_mem_alloc += SCABUFSIZE; - - buf_list[i].buf_ptr = (unsigned short)phys_addr; - buf_list[i].buf_base = (unsigned char)(phys_addr >> 16); - } - - return 0; -} - -static void free_dma_bufs(SLMP_INFO *info) -{ - info->buffer_list = NULL; - info->rx_buf_list = NULL; - info->tx_buf_list = NULL; -} - -/* allocate buffer large enough to hold max_frame_size. - * This buffer is used to pass an assembled frame to the line discipline. - */ -static int alloc_tmp_rx_buf(SLMP_INFO *info) -{ - info->tmp_rx_buf = kmalloc(info->max_frame_size, GFP_KERNEL); - if (info->tmp_rx_buf == NULL) - return -ENOMEM; - return 0; -} - -static void free_tmp_rx_buf(SLMP_INFO *info) -{ - kfree(info->tmp_rx_buf); - info->tmp_rx_buf = NULL; -} - -static int claim_resources(SLMP_INFO *info) -{ - if (request_mem_region(info->phys_memory_base,SCA_MEM_SIZE,"synclinkmp") == NULL) { - printk( "%s(%d):%s mem addr conflict, Addr=%08X\n", - __FILE__,__LINE__,info->device_name, info->phys_memory_base); - info->init_error = DiagStatus_AddressConflict; - goto errout; - } - else - info->shared_mem_requested = true; - - if (request_mem_region(info->phys_lcr_base + info->lcr_offset,128,"synclinkmp") == NULL) { - printk( "%s(%d):%s lcr mem addr conflict, Addr=%08X\n", - __FILE__,__LINE__,info->device_name, info->phys_lcr_base); - info->init_error = DiagStatus_AddressConflict; - goto errout; - } - else - info->lcr_mem_requested = true; - - if (request_mem_region(info->phys_sca_base + info->sca_offset,SCA_BASE_SIZE,"synclinkmp") == NULL) { - printk( "%s(%d):%s sca mem addr conflict, Addr=%08X\n", - __FILE__,__LINE__,info->device_name, info->phys_sca_base); - info->init_error = DiagStatus_AddressConflict; - goto errout; - } - else - info->sca_base_requested = true; - - if (request_mem_region(info->phys_statctrl_base + info->statctrl_offset,SCA_REG_SIZE,"synclinkmp") == NULL) { - printk( "%s(%d):%s stat/ctrl mem addr conflict, Addr=%08X\n", - __FILE__,__LINE__,info->device_name, info->phys_statctrl_base); - info->init_error = DiagStatus_AddressConflict; - goto errout; - } - else - info->sca_statctrl_requested = true; - - info->memory_base = ioremap_nocache(info->phys_memory_base, - SCA_MEM_SIZE); - if (!info->memory_base) { - printk( "%s(%d):%s Cant map shared memory, MemAddr=%08X\n", - __FILE__,__LINE__,info->device_name, info->phys_memory_base ); - info->init_error = DiagStatus_CantAssignPciResources; - goto errout; - } - - info->lcr_base = ioremap_nocache(info->phys_lcr_base, PAGE_SIZE); - if (!info->lcr_base) { - printk( "%s(%d):%s Cant map LCR memory, MemAddr=%08X\n", - __FILE__,__LINE__,info->device_name, info->phys_lcr_base ); - info->init_error = DiagStatus_CantAssignPciResources; - goto errout; - } - info->lcr_base += info->lcr_offset; - - info->sca_base = ioremap_nocache(info->phys_sca_base, PAGE_SIZE); - if (!info->sca_base) { - printk( "%s(%d):%s Cant map SCA memory, MemAddr=%08X\n", - __FILE__,__LINE__,info->device_name, info->phys_sca_base ); - info->init_error = DiagStatus_CantAssignPciResources; - goto errout; - } - info->sca_base += info->sca_offset; - - info->statctrl_base = ioremap_nocache(info->phys_statctrl_base, - PAGE_SIZE); - if (!info->statctrl_base) { - printk( "%s(%d):%s Cant map SCA Status/Control memory, MemAddr=%08X\n", - __FILE__,__LINE__,info->device_name, info->phys_statctrl_base ); - info->init_error = DiagStatus_CantAssignPciResources; - goto errout; - } - info->statctrl_base += info->statctrl_offset; - - if ( !memory_test(info) ) { - printk( "%s(%d):Shared Memory Test failed for device %s MemAddr=%08X\n", - __FILE__,__LINE__,info->device_name, info->phys_memory_base ); - info->init_error = DiagStatus_MemoryError; - goto errout; - } - - return 0; - -errout: - release_resources( info ); - return -ENODEV; -} - -static void release_resources(SLMP_INFO *info) -{ - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):%s release_resources() entry\n", - __FILE__,__LINE__,info->device_name ); - - if ( info->irq_requested ) { - free_irq(info->irq_level, info); - info->irq_requested = false; - } - - if ( info->shared_mem_requested ) { - release_mem_region(info->phys_memory_base,SCA_MEM_SIZE); - info->shared_mem_requested = false; - } - if ( info->lcr_mem_requested ) { - release_mem_region(info->phys_lcr_base + info->lcr_offset,128); - info->lcr_mem_requested = false; - } - if ( info->sca_base_requested ) { - release_mem_region(info->phys_sca_base + info->sca_offset,SCA_BASE_SIZE); - info->sca_base_requested = false; - } - if ( info->sca_statctrl_requested ) { - release_mem_region(info->phys_statctrl_base + info->statctrl_offset,SCA_REG_SIZE); - info->sca_statctrl_requested = false; - } - - if (info->memory_base){ - iounmap(info->memory_base); - info->memory_base = NULL; - } - - if (info->sca_base) { - iounmap(info->sca_base - info->sca_offset); - info->sca_base=NULL; - } - - if (info->statctrl_base) { - iounmap(info->statctrl_base - info->statctrl_offset); - info->statctrl_base=NULL; - } - - if (info->lcr_base){ - iounmap(info->lcr_base - info->lcr_offset); - info->lcr_base = NULL; - } - - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):%s release_resources() exit\n", - __FILE__,__LINE__,info->device_name ); -} - -/* Add the specified device instance data structure to the - * global linked list of devices and increment the device count. - */ -static void add_device(SLMP_INFO *info) -{ - info->next_device = NULL; - info->line = synclinkmp_device_count; - sprintf(info->device_name,"ttySLM%dp%d",info->adapter_num,info->port_num); - - if (info->line < MAX_DEVICES) { - if (maxframe[info->line]) - info->max_frame_size = maxframe[info->line]; - } - - synclinkmp_device_count++; - - if ( !synclinkmp_device_list ) - synclinkmp_device_list = info; - else { - SLMP_INFO *current_dev = synclinkmp_device_list; - while( current_dev->next_device ) - current_dev = current_dev->next_device; - current_dev->next_device = info; - } - - if ( info->max_frame_size < 4096 ) - info->max_frame_size = 4096; - else if ( info->max_frame_size > 65535 ) - info->max_frame_size = 65535; - - printk( "SyncLink MultiPort %s: " - "Mem=(%08x %08X %08x %08X) IRQ=%d MaxFrameSize=%u\n", - info->device_name, - info->phys_sca_base, - info->phys_memory_base, - info->phys_statctrl_base, - info->phys_lcr_base, - info->irq_level, - info->max_frame_size ); - -#if SYNCLINK_GENERIC_HDLC - hdlcdev_init(info); -#endif -} - -static const struct tty_port_operations port_ops = { - .carrier_raised = carrier_raised, - .dtr_rts = dtr_rts, -}; - -/* Allocate and initialize a device instance structure - * - * Return Value: pointer to SLMP_INFO if success, otherwise NULL - */ -static SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev) -{ - SLMP_INFO *info; - - info = kzalloc(sizeof(SLMP_INFO), - GFP_KERNEL); - - if (!info) { - printk("%s(%d) Error can't allocate device instance data for adapter %d, port %d\n", - __FILE__,__LINE__, adapter_num, port_num); - } else { - tty_port_init(&info->port); - info->port.ops = &port_ops; - info->magic = MGSL_MAGIC; - INIT_WORK(&info->task, bh_handler); - info->max_frame_size = 4096; - info->port.close_delay = 5*HZ/10; - info->port.closing_wait = 30*HZ; - init_waitqueue_head(&info->status_event_wait_q); - init_waitqueue_head(&info->event_wait_q); - spin_lock_init(&info->netlock); - memcpy(&info->params,&default_params,sizeof(MGSL_PARAMS)); - info->idle_mode = HDLC_TXIDLE_FLAGS; - info->adapter_num = adapter_num; - info->port_num = port_num; - - /* Copy configuration info to device instance data */ - info->irq_level = pdev->irq; - info->phys_lcr_base = pci_resource_start(pdev,0); - info->phys_sca_base = pci_resource_start(pdev,2); - info->phys_memory_base = pci_resource_start(pdev,3); - info->phys_statctrl_base = pci_resource_start(pdev,4); - - /* Because veremap only works on page boundaries we must map - * a larger area than is actually implemented for the LCR - * memory range. We map a full page starting at the page boundary. - */ - info->lcr_offset = info->phys_lcr_base & (PAGE_SIZE-1); - info->phys_lcr_base &= ~(PAGE_SIZE-1); - - info->sca_offset = info->phys_sca_base & (PAGE_SIZE-1); - info->phys_sca_base &= ~(PAGE_SIZE-1); - - info->statctrl_offset = info->phys_statctrl_base & (PAGE_SIZE-1); - info->phys_statctrl_base &= ~(PAGE_SIZE-1); - - info->bus_type = MGSL_BUS_TYPE_PCI; - info->irq_flags = IRQF_SHARED; - - setup_timer(&info->tx_timer, tx_timeout, (unsigned long)info); - setup_timer(&info->status_timer, status_timeout, - (unsigned long)info); - - /* Store the PCI9050 misc control register value because a flaw - * in the PCI9050 prevents LCR registers from being read if - * BIOS assigns an LCR base address with bit 7 set. - * - * Only the misc control register is accessed for which only - * write access is needed, so set an initial value and change - * bits to the device instance data as we write the value - * to the actual misc control register. - */ - info->misc_ctrl_value = 0x087e4546; - - /* initial port state is unknown - if startup errors - * occur, init_error will be set to indicate the - * problem. Once the port is fully initialized, - * this value will be set to 0 to indicate the - * port is available. - */ - info->init_error = -1; - } - - return info; -} - -static void device_init(int adapter_num, struct pci_dev *pdev) -{ - SLMP_INFO *port_array[SCA_MAX_PORTS]; - int port; - - /* allocate device instances for up to SCA_MAX_PORTS devices */ - for ( port = 0; port < SCA_MAX_PORTS; ++port ) { - port_array[port] = alloc_dev(adapter_num,port,pdev); - if( port_array[port] == NULL ) { - for ( --port; port >= 0; --port ) - kfree(port_array[port]); - return; - } - } - - /* give copy of port_array to all ports and add to device list */ - for ( port = 0; port < SCA_MAX_PORTS; ++port ) { - memcpy(port_array[port]->port_array,port_array,sizeof(port_array)); - add_device( port_array[port] ); - spin_lock_init(&port_array[port]->lock); - } - - /* Allocate and claim adapter resources */ - if ( !claim_resources(port_array[0]) ) { - - alloc_dma_bufs(port_array[0]); - - /* copy resource information from first port to others */ - for ( port = 1; port < SCA_MAX_PORTS; ++port ) { - port_array[port]->lock = port_array[0]->lock; - port_array[port]->irq_level = port_array[0]->irq_level; - port_array[port]->memory_base = port_array[0]->memory_base; - port_array[port]->sca_base = port_array[0]->sca_base; - port_array[port]->statctrl_base = port_array[0]->statctrl_base; - port_array[port]->lcr_base = port_array[0]->lcr_base; - alloc_dma_bufs(port_array[port]); - } - - if ( request_irq(port_array[0]->irq_level, - synclinkmp_interrupt, - port_array[0]->irq_flags, - port_array[0]->device_name, - port_array[0]) < 0 ) { - printk( "%s(%d):%s Cant request interrupt, IRQ=%d\n", - __FILE__,__LINE__, - port_array[0]->device_name, - port_array[0]->irq_level ); - } - else { - port_array[0]->irq_requested = true; - adapter_test(port_array[0]); - } - } -} - -static const struct tty_operations ops = { - .open = open, - .close = close, - .write = write, - .put_char = put_char, - .flush_chars = flush_chars, - .write_room = write_room, - .chars_in_buffer = chars_in_buffer, - .flush_buffer = flush_buffer, - .ioctl = ioctl, - .throttle = throttle, - .unthrottle = unthrottle, - .send_xchar = send_xchar, - .break_ctl = set_break, - .wait_until_sent = wait_until_sent, - .set_termios = set_termios, - .stop = tx_hold, - .start = tx_release, - .hangup = hangup, - .tiocmget = tiocmget, - .tiocmset = tiocmset, - .get_icount = get_icount, - .proc_fops = &synclinkmp_proc_fops, -}; - - -static void synclinkmp_cleanup(void) -{ - int rc; - SLMP_INFO *info; - SLMP_INFO *tmp; - - printk("Unloading %s %s\n", driver_name, driver_version); - - if (serial_driver) { - if ((rc = tty_unregister_driver(serial_driver))) - printk("%s(%d) failed to unregister tty driver err=%d\n", - __FILE__,__LINE__,rc); - put_tty_driver(serial_driver); - } - - /* reset devices */ - info = synclinkmp_device_list; - while(info) { - reset_port(info); - info = info->next_device; - } - - /* release devices */ - info = synclinkmp_device_list; - while(info) { -#if SYNCLINK_GENERIC_HDLC - hdlcdev_exit(info); -#endif - free_dma_bufs(info); - free_tmp_rx_buf(info); - if ( info->port_num == 0 ) { - if (info->sca_base) - write_reg(info, LPR, 1); /* set low power mode */ - release_resources(info); - } - tmp = info; - info = info->next_device; - kfree(tmp); - } - - pci_unregister_driver(&synclinkmp_pci_driver); -} - -/* Driver initialization entry point. - */ - -static int __init synclinkmp_init(void) -{ - int rc; - - if (break_on_load) { - synclinkmp_get_text_ptr(); - BREAKPOINT(); - } - - printk("%s %s\n", driver_name, driver_version); - - if ((rc = pci_register_driver(&synclinkmp_pci_driver)) < 0) { - printk("%s:failed to register PCI driver, error=%d\n",__FILE__,rc); - return rc; - } - - serial_driver = alloc_tty_driver(128); - if (!serial_driver) { - rc = -ENOMEM; - goto error; - } - - /* Initialize the tty_driver structure */ - - serial_driver->owner = THIS_MODULE; - serial_driver->driver_name = "synclinkmp"; - serial_driver->name = "ttySLM"; - serial_driver->major = ttymajor; - serial_driver->minor_start = 64; - serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - serial_driver->subtype = SERIAL_TYPE_NORMAL; - serial_driver->init_termios = tty_std_termios; - serial_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - serial_driver->init_termios.c_ispeed = 9600; - serial_driver->init_termios.c_ospeed = 9600; - serial_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(serial_driver, &ops); - if ((rc = tty_register_driver(serial_driver)) < 0) { - printk("%s(%d):Couldn't register serial driver\n", - __FILE__,__LINE__); - put_tty_driver(serial_driver); - serial_driver = NULL; - goto error; - } - - printk("%s %s, tty major#%d\n", - driver_name, driver_version, - serial_driver->major); - - return 0; - -error: - synclinkmp_cleanup(); - return rc; -} - -static void __exit synclinkmp_exit(void) -{ - synclinkmp_cleanup(); -} - -module_init(synclinkmp_init); -module_exit(synclinkmp_exit); - -/* Set the port for internal loopback mode. - * The TxCLK and RxCLK signals are generated from the BRG and - * the TxD is looped back to the RxD internally. - */ -static void enable_loopback(SLMP_INFO *info, int enable) -{ - if (enable) { - /* MD2 (Mode Register 2) - * 01..00 CNCT<1..0> Channel Connection 11=Local Loopback - */ - write_reg(info, MD2, (unsigned char)(read_reg(info, MD2) | (BIT1 + BIT0))); - - /* degate external TxC clock source */ - info->port_array[0]->ctrlreg_value |= (BIT0 << (info->port_num * 2)); - write_control_reg(info); - - /* RXS/TXS (Rx/Tx clock source) - * 07 Reserved, must be 0 - * 06..04 Clock Source, 100=BRG - * 03..00 Clock Divisor, 0000=1 - */ - write_reg(info, RXS, 0x40); - write_reg(info, TXS, 0x40); - - } else { - /* MD2 (Mode Register 2) - * 01..00 CNCT<1..0> Channel connection, 0=normal - */ - write_reg(info, MD2, (unsigned char)(read_reg(info, MD2) & ~(BIT1 + BIT0))); - - /* RXS/TXS (Rx/Tx clock source) - * 07 Reserved, must be 0 - * 06..04 Clock Source, 000=RxC/TxC Pin - * 03..00 Clock Divisor, 0000=1 - */ - write_reg(info, RXS, 0x00); - write_reg(info, TXS, 0x00); - } - - /* set LinkSpeed if available, otherwise default to 2Mbps */ - if (info->params.clock_speed) - set_rate(info, info->params.clock_speed); - else - set_rate(info, 3686400); -} - -/* Set the baud rate register to the desired speed - * - * data_rate data rate of clock in bits per second - * A data rate of 0 disables the AUX clock. - */ -static void set_rate( SLMP_INFO *info, u32 data_rate ) -{ - u32 TMCValue; - unsigned char BRValue; - u32 Divisor=0; - - /* fBRG = fCLK/(TMC * 2^BR) - */ - if (data_rate != 0) { - Divisor = 14745600/data_rate; - if (!Divisor) - Divisor = 1; - - TMCValue = Divisor; - - BRValue = 0; - if (TMCValue != 1 && TMCValue != 2) { - /* BRValue of 0 provides 50/50 duty cycle *only* when - * TMCValue is 1 or 2. BRValue of 1 to 9 always provides - * 50/50 duty cycle. - */ - BRValue = 1; - TMCValue >>= 1; - } - - /* while TMCValue is too big for TMC register, divide - * by 2 and increment BR exponent. - */ - for(; TMCValue > 256 && BRValue < 10; BRValue++) - TMCValue >>= 1; - - write_reg(info, TXS, - (unsigned char)((read_reg(info, TXS) & 0xf0) | BRValue)); - write_reg(info, RXS, - (unsigned char)((read_reg(info, RXS) & 0xf0) | BRValue)); - write_reg(info, TMC, (unsigned char)TMCValue); - } - else { - write_reg(info, TXS,0); - write_reg(info, RXS,0); - write_reg(info, TMC, 0); - } -} - -/* Disable receiver - */ -static void rx_stop(SLMP_INFO *info) -{ - if (debug_level >= DEBUG_LEVEL_ISR) - printk("%s(%d):%s rx_stop()\n", - __FILE__,__LINE__, info->device_name ); - - write_reg(info, CMD, RXRESET); - - info->ie0_value &= ~RXRDYE; - write_reg(info, IE0, info->ie0_value); /* disable Rx data interrupts */ - - write_reg(info, RXDMA + DSR, 0); /* disable Rx DMA */ - write_reg(info, RXDMA + DCMD, SWABORT); /* reset/init Rx DMA */ - write_reg(info, RXDMA + DIR, 0); /* disable Rx DMA interrupts */ - - info->rx_enabled = false; - info->rx_overflow = false; -} - -/* enable the receiver - */ -static void rx_start(SLMP_INFO *info) -{ - int i; - - if (debug_level >= DEBUG_LEVEL_ISR) - printk("%s(%d):%s rx_start()\n", - __FILE__,__LINE__, info->device_name ); - - write_reg(info, CMD, RXRESET); - - if ( info->params.mode == MGSL_MODE_HDLC ) { - /* HDLC, disabe IRQ on rxdata */ - info->ie0_value &= ~RXRDYE; - write_reg(info, IE0, info->ie0_value); - - /* Reset all Rx DMA buffers and program rx dma */ - write_reg(info, RXDMA + DSR, 0); /* disable Rx DMA */ - write_reg(info, RXDMA + DCMD, SWABORT); /* reset/init Rx DMA */ - - for (i = 0; i < info->rx_buf_count; i++) { - info->rx_buf_list[i].status = 0xff; - - // throttle to 4 shared memory writes at a time to prevent - // hogging local bus (keep latency time for DMA requests low). - if (!(i % 4)) - read_status_reg(info); - } - info->current_rx_buf = 0; - - /* set current/1st descriptor address */ - write_reg16(info, RXDMA + CDA, - info->rx_buf_list_ex[0].phys_entry); - - /* set new last rx descriptor address */ - write_reg16(info, RXDMA + EDA, - info->rx_buf_list_ex[info->rx_buf_count - 1].phys_entry); - - /* set buffer length (shared by all rx dma data buffers) */ - write_reg16(info, RXDMA + BFL, SCABUFSIZE); - - write_reg(info, RXDMA + DIR, 0x60); /* enable Rx DMA interrupts (EOM/BOF) */ - write_reg(info, RXDMA + DSR, 0xf2); /* clear Rx DMA IRQs, enable Rx DMA */ - } else { - /* async, enable IRQ on rxdata */ - info->ie0_value |= RXRDYE; - write_reg(info, IE0, info->ie0_value); - } - - write_reg(info, CMD, RXENABLE); - - info->rx_overflow = false; - info->rx_enabled = true; -} - -/* Enable the transmitter and send a transmit frame if - * one is loaded in the DMA buffers. - */ -static void tx_start(SLMP_INFO *info) -{ - if (debug_level >= DEBUG_LEVEL_ISR) - printk("%s(%d):%s tx_start() tx_count=%d\n", - __FILE__,__LINE__, info->device_name,info->tx_count ); - - if (!info->tx_enabled ) { - write_reg(info, CMD, TXRESET); - write_reg(info, CMD, TXENABLE); - info->tx_enabled = true; - } - - if ( info->tx_count ) { - - /* If auto RTS enabled and RTS is inactive, then assert */ - /* RTS and set a flag indicating that the driver should */ - /* negate RTS when the transmission completes. */ - - info->drop_rts_on_tx_done = false; - - if (info->params.mode != MGSL_MODE_ASYNC) { - - if ( info->params.flags & HDLC_FLAG_AUTO_RTS ) { - get_signals( info ); - if ( !(info->serial_signals & SerialSignal_RTS) ) { - info->serial_signals |= SerialSignal_RTS; - set_signals( info ); - info->drop_rts_on_tx_done = true; - } - } - - write_reg16(info, TRC0, - (unsigned short)(((tx_negate_fifo_level-1)<<8) + tx_active_fifo_level)); - - write_reg(info, TXDMA + DSR, 0); /* disable DMA channel */ - write_reg(info, TXDMA + DCMD, SWABORT); /* reset/init DMA channel */ - - /* set TX CDA (current descriptor address) */ - write_reg16(info, TXDMA + CDA, - info->tx_buf_list_ex[0].phys_entry); - - /* set TX EDA (last descriptor address) */ - write_reg16(info, TXDMA + EDA, - info->tx_buf_list_ex[info->last_tx_buf].phys_entry); - - /* enable underrun IRQ */ - info->ie1_value &= ~IDLE; - info->ie1_value |= UDRN; - write_reg(info, IE1, info->ie1_value); - write_reg(info, SR1, (unsigned char)(IDLE + UDRN)); - - write_reg(info, TXDMA + DIR, 0x40); /* enable Tx DMA interrupts (EOM) */ - write_reg(info, TXDMA + DSR, 0xf2); /* clear Tx DMA IRQs, enable Tx DMA */ - - mod_timer(&info->tx_timer, jiffies + - msecs_to_jiffies(5000)); - } - else { - tx_load_fifo(info); - /* async, enable IRQ on txdata */ - info->ie0_value |= TXRDYE; - write_reg(info, IE0, info->ie0_value); - } - - info->tx_active = true; - } -} - -/* stop the transmitter and DMA - */ -static void tx_stop( SLMP_INFO *info ) -{ - if (debug_level >= DEBUG_LEVEL_ISR) - printk("%s(%d):%s tx_stop()\n", - __FILE__,__LINE__, info->device_name ); - - del_timer(&info->tx_timer); - - write_reg(info, TXDMA + DSR, 0); /* disable DMA channel */ - write_reg(info, TXDMA + DCMD, SWABORT); /* reset/init DMA channel */ - - write_reg(info, CMD, TXRESET); - - info->ie1_value &= ~(UDRN + IDLE); - write_reg(info, IE1, info->ie1_value); /* disable tx status interrupts */ - write_reg(info, SR1, (unsigned char)(IDLE + UDRN)); /* clear pending */ - - info->ie0_value &= ~TXRDYE; - write_reg(info, IE0, info->ie0_value); /* disable tx data interrupts */ - - info->tx_enabled = false; - info->tx_active = false; -} - -/* Fill the transmit FIFO until the FIFO is full or - * there is no more data to load. - */ -static void tx_load_fifo(SLMP_INFO *info) -{ - u8 TwoBytes[2]; - - /* do nothing is now tx data available and no XON/XOFF pending */ - - if ( !info->tx_count && !info->x_char ) - return; - - /* load the Transmit FIFO until FIFOs full or all data sent */ - - while( info->tx_count && (read_reg(info,SR0) & BIT1) ) { - - /* there is more space in the transmit FIFO and */ - /* there is more data in transmit buffer */ - - if ( (info->tx_count > 1) && !info->x_char ) { - /* write 16-bits */ - TwoBytes[0] = info->tx_buf[info->tx_get++]; - if (info->tx_get >= info->max_frame_size) - info->tx_get -= info->max_frame_size; - TwoBytes[1] = info->tx_buf[info->tx_get++]; - if (info->tx_get >= info->max_frame_size) - info->tx_get -= info->max_frame_size; - - write_reg16(info, TRB, *((u16 *)TwoBytes)); - - info->tx_count -= 2; - info->icount.tx += 2; - } else { - /* only 1 byte left to transmit or 1 FIFO slot left */ - - if (info->x_char) { - /* transmit pending high priority char */ - write_reg(info, TRB, info->x_char); - info->x_char = 0; - } else { - write_reg(info, TRB, info->tx_buf[info->tx_get++]); - if (info->tx_get >= info->max_frame_size) - info->tx_get -= info->max_frame_size; - info->tx_count--; - } - info->icount.tx++; - } - } -} - -/* Reset a port to a known state - */ -static void reset_port(SLMP_INFO *info) -{ - if (info->sca_base) { - - tx_stop(info); - rx_stop(info); - - info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); - set_signals(info); - - /* disable all port interrupts */ - info->ie0_value = 0; - info->ie1_value = 0; - info->ie2_value = 0; - write_reg(info, IE0, info->ie0_value); - write_reg(info, IE1, info->ie1_value); - write_reg(info, IE2, info->ie2_value); - - write_reg(info, CMD, CHRESET); - } -} - -/* Reset all the ports to a known state. - */ -static void reset_adapter(SLMP_INFO *info) -{ - int i; - - for ( i=0; i < SCA_MAX_PORTS; ++i) { - if (info->port_array[i]) - reset_port(info->port_array[i]); - } -} - -/* Program port for asynchronous communications. - */ -static void async_mode(SLMP_INFO *info) -{ - - unsigned char RegValue; - - tx_stop(info); - rx_stop(info); - - /* MD0, Mode Register 0 - * - * 07..05 PRCTL<2..0>, Protocol Mode, 000=async - * 04 AUTO, Auto-enable (RTS/CTS/DCD) - * 03 Reserved, must be 0 - * 02 CRCCC, CRC Calculation, 0=disabled - * 01..00 STOP<1..0> Stop bits (00=1,10=2) - * - * 0000 0000 - */ - RegValue = 0x00; - if (info->params.stop_bits != 1) - RegValue |= BIT1; - write_reg(info, MD0, RegValue); - - /* MD1, Mode Register 1 - * - * 07..06 BRATE<1..0>, bit rate, 00=1/1 01=1/16 10=1/32 11=1/64 - * 05..04 TXCHR<1..0>, tx char size, 00=8 bits,01=7,10=6,11=5 - * 03..02 RXCHR<1..0>, rx char size - * 01..00 PMPM<1..0>, Parity mode, 00=none 10=even 11=odd - * - * 0100 0000 - */ - RegValue = 0x40; - switch (info->params.data_bits) { - case 7: RegValue |= BIT4 + BIT2; break; - case 6: RegValue |= BIT5 + BIT3; break; - case 5: RegValue |= BIT5 + BIT4 + BIT3 + BIT2; break; - } - if (info->params.parity != ASYNC_PARITY_NONE) { - RegValue |= BIT1; - if (info->params.parity == ASYNC_PARITY_ODD) - RegValue |= BIT0; - } - write_reg(info, MD1, RegValue); - - /* MD2, Mode Register 2 - * - * 07..02 Reserved, must be 0 - * 01..00 CNCT<1..0> Channel connection, 00=normal 11=local loopback - * - * 0000 0000 - */ - RegValue = 0x00; - if (info->params.loopback) - RegValue |= (BIT1 + BIT0); - write_reg(info, MD2, RegValue); - - /* RXS, Receive clock source - * - * 07 Reserved, must be 0 - * 06..04 RXCS<2..0>, clock source, 000=RxC Pin, 100=BRG, 110=DPLL - * 03..00 RXBR<3..0>, rate divisor, 0000=1 - */ - RegValue=BIT6; - write_reg(info, RXS, RegValue); - - /* TXS, Transmit clock source - * - * 07 Reserved, must be 0 - * 06..04 RXCS<2..0>, clock source, 000=TxC Pin, 100=BRG, 110=Receive Clock - * 03..00 RXBR<3..0>, rate divisor, 0000=1 - */ - RegValue=BIT6; - write_reg(info, TXS, RegValue); - - /* Control Register - * - * 6,4,2,0 CLKSEL<3..0>, 0 = TcCLK in, 1 = Auxclk out - */ - info->port_array[0]->ctrlreg_value |= (BIT0 << (info->port_num * 2)); - write_control_reg(info); - - tx_set_idle(info); - - /* RRC Receive Ready Control 0 - * - * 07..05 Reserved, must be 0 - * 04..00 RRC<4..0> Rx FIFO trigger active 0x00 = 1 byte - */ - write_reg(info, RRC, 0x00); - - /* TRC0 Transmit Ready Control 0 - * - * 07..05 Reserved, must be 0 - * 04..00 TRC<4..0> Tx FIFO trigger active 0x10 = 16 bytes - */ - write_reg(info, TRC0, 0x10); - - /* TRC1 Transmit Ready Control 1 - * - * 07..05 Reserved, must be 0 - * 04..00 TRC<4..0> Tx FIFO trigger inactive 0x1e = 31 bytes (full-1) - */ - write_reg(info, TRC1, 0x1e); - - /* CTL, MSCI control register - * - * 07..06 Reserved, set to 0 - * 05 UDRNC, underrun control, 0=abort 1=CRC+flag (HDLC/BSC) - * 04 IDLC, idle control, 0=mark 1=idle register - * 03 BRK, break, 0=off 1 =on (async) - * 02 SYNCLD, sync char load enable (BSC) 1=enabled - * 01 GOP, go active on poll (LOOP mode) 1=enabled - * 00 RTS, RTS output control, 0=active 1=inactive - * - * 0001 0001 - */ - RegValue = 0x10; - if (!(info->serial_signals & SerialSignal_RTS)) - RegValue |= 0x01; - write_reg(info, CTL, RegValue); - - /* enable status interrupts */ - info->ie0_value |= TXINTE + RXINTE; - write_reg(info, IE0, info->ie0_value); - - /* enable break detect interrupt */ - info->ie1_value = BRKD; - write_reg(info, IE1, info->ie1_value); - - /* enable rx overrun interrupt */ - info->ie2_value = OVRN; - write_reg(info, IE2, info->ie2_value); - - set_rate( info, info->params.data_rate * 16 ); -} - -/* Program the SCA for HDLC communications. - */ -static void hdlc_mode(SLMP_INFO *info) -{ - unsigned char RegValue; - u32 DpllDivisor; - - // Can't use DPLL because SCA outputs recovered clock on RxC when - // DPLL mode selected. This causes output contention with RxC receiver. - // Use of DPLL would require external hardware to disable RxC receiver - // when DPLL mode selected. - info->params.flags &= ~(HDLC_FLAG_TXC_DPLL + HDLC_FLAG_RXC_DPLL); - - /* disable DMA interrupts */ - write_reg(info, TXDMA + DIR, 0); - write_reg(info, RXDMA + DIR, 0); - - /* MD0, Mode Register 0 - * - * 07..05 PRCTL<2..0>, Protocol Mode, 100=HDLC - * 04 AUTO, Auto-enable (RTS/CTS/DCD) - * 03 Reserved, must be 0 - * 02 CRCCC, CRC Calculation, 1=enabled - * 01 CRC1, CRC selection, 0=CRC-16,1=CRC-CCITT-16 - * 00 CRC0, CRC initial value, 1 = all 1s - * - * 1000 0001 - */ - RegValue = 0x81; - if (info->params.flags & HDLC_FLAG_AUTO_CTS) - RegValue |= BIT4; - if (info->params.flags & HDLC_FLAG_AUTO_DCD) - RegValue |= BIT4; - if (info->params.crc_type == HDLC_CRC_16_CCITT) - RegValue |= BIT2 + BIT1; - write_reg(info, MD0, RegValue); - - /* MD1, Mode Register 1 - * - * 07..06 ADDRS<1..0>, Address detect, 00=no addr check - * 05..04 TXCHR<1..0>, tx char size, 00=8 bits - * 03..02 RXCHR<1..0>, rx char size, 00=8 bits - * 01..00 PMPM<1..0>, Parity mode, 00=no parity - * - * 0000 0000 - */ - RegValue = 0x00; - write_reg(info, MD1, RegValue); - - /* MD2, Mode Register 2 - * - * 07 NRZFM, 0=NRZ, 1=FM - * 06..05 CODE<1..0> Encoding, 00=NRZ - * 04..03 DRATE<1..0> DPLL Divisor, 00=8 - * 02 Reserved, must be 0 - * 01..00 CNCT<1..0> Channel connection, 0=normal - * - * 0000 0000 - */ - RegValue = 0x00; - switch(info->params.encoding) { - case HDLC_ENCODING_NRZI: RegValue |= BIT5; break; - case HDLC_ENCODING_BIPHASE_MARK: RegValue |= BIT7 + BIT5; break; /* aka FM1 */ - case HDLC_ENCODING_BIPHASE_SPACE: RegValue |= BIT7 + BIT6; break; /* aka FM0 */ - case HDLC_ENCODING_BIPHASE_LEVEL: RegValue |= BIT7; break; /* aka Manchester */ -#if 0 - case HDLC_ENCODING_NRZB: /* not supported */ - case HDLC_ENCODING_NRZI_MARK: /* not supported */ - case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: /* not supported */ -#endif - } - if ( info->params.flags & HDLC_FLAG_DPLL_DIV16 ) { - DpllDivisor = 16; - RegValue |= BIT3; - } else if ( info->params.flags & HDLC_FLAG_DPLL_DIV8 ) { - DpllDivisor = 8; - } else { - DpllDivisor = 32; - RegValue |= BIT4; - } - write_reg(info, MD2, RegValue); - - - /* RXS, Receive clock source - * - * 07 Reserved, must be 0 - * 06..04 RXCS<2..0>, clock source, 000=RxC Pin, 100=BRG, 110=DPLL - * 03..00 RXBR<3..0>, rate divisor, 0000=1 - */ - RegValue=0; - if (info->params.flags & HDLC_FLAG_RXC_BRG) - RegValue |= BIT6; - if (info->params.flags & HDLC_FLAG_RXC_DPLL) - RegValue |= BIT6 + BIT5; - write_reg(info, RXS, RegValue); - - /* TXS, Transmit clock source - * - * 07 Reserved, must be 0 - * 06..04 RXCS<2..0>, clock source, 000=TxC Pin, 100=BRG, 110=Receive Clock - * 03..00 RXBR<3..0>, rate divisor, 0000=1 - */ - RegValue=0; - if (info->params.flags & HDLC_FLAG_TXC_BRG) - RegValue |= BIT6; - if (info->params.flags & HDLC_FLAG_TXC_DPLL) - RegValue |= BIT6 + BIT5; - write_reg(info, TXS, RegValue); - - if (info->params.flags & HDLC_FLAG_RXC_DPLL) - set_rate(info, info->params.clock_speed * DpllDivisor); - else - set_rate(info, info->params.clock_speed); - - /* GPDATA (General Purpose I/O Data Register) - * - * 6,4,2,0 CLKSEL<3..0>, 0 = TcCLK in, 1 = Auxclk out - */ - if (info->params.flags & HDLC_FLAG_TXC_BRG) - info->port_array[0]->ctrlreg_value |= (BIT0 << (info->port_num * 2)); - else - info->port_array[0]->ctrlreg_value &= ~(BIT0 << (info->port_num * 2)); - write_control_reg(info); - - /* RRC Receive Ready Control 0 - * - * 07..05 Reserved, must be 0 - * 04..00 RRC<4..0> Rx FIFO trigger active - */ - write_reg(info, RRC, rx_active_fifo_level); - - /* TRC0 Transmit Ready Control 0 - * - * 07..05 Reserved, must be 0 - * 04..00 TRC<4..0> Tx FIFO trigger active - */ - write_reg(info, TRC0, tx_active_fifo_level); - - /* TRC1 Transmit Ready Control 1 - * - * 07..05 Reserved, must be 0 - * 04..00 TRC<4..0> Tx FIFO trigger inactive 0x1f = 32 bytes (full) - */ - write_reg(info, TRC1, (unsigned char)(tx_negate_fifo_level - 1)); - - /* DMR, DMA Mode Register - * - * 07..05 Reserved, must be 0 - * 04 TMOD, Transfer Mode: 1=chained-block - * 03 Reserved, must be 0 - * 02 NF, Number of Frames: 1=multi-frame - * 01 CNTE, Frame End IRQ Counter enable: 0=disabled - * 00 Reserved, must be 0 - * - * 0001 0100 - */ - write_reg(info, TXDMA + DMR, 0x14); - write_reg(info, RXDMA + DMR, 0x14); - - /* Set chain pointer base (upper 8 bits of 24 bit addr) */ - write_reg(info, RXDMA + CPB, - (unsigned char)(info->buffer_list_phys >> 16)); - - /* Set chain pointer base (upper 8 bits of 24 bit addr) */ - write_reg(info, TXDMA + CPB, - (unsigned char)(info->buffer_list_phys >> 16)); - - /* enable status interrupts. other code enables/disables - * the individual sources for these two interrupt classes. - */ - info->ie0_value |= TXINTE + RXINTE; - write_reg(info, IE0, info->ie0_value); - - /* CTL, MSCI control register - * - * 07..06 Reserved, set to 0 - * 05 UDRNC, underrun control, 0=abort 1=CRC+flag (HDLC/BSC) - * 04 IDLC, idle control, 0=mark 1=idle register - * 03 BRK, break, 0=off 1 =on (async) - * 02 SYNCLD, sync char load enable (BSC) 1=enabled - * 01 GOP, go active on poll (LOOP mode) 1=enabled - * 00 RTS, RTS output control, 0=active 1=inactive - * - * 0001 0001 - */ - RegValue = 0x10; - if (!(info->serial_signals & SerialSignal_RTS)) - RegValue |= 0x01; - write_reg(info, CTL, RegValue); - - /* preamble not supported ! */ - - tx_set_idle(info); - tx_stop(info); - rx_stop(info); - - set_rate(info, info->params.clock_speed); - - if (info->params.loopback) - enable_loopback(info,1); -} - -/* Set the transmit HDLC idle mode - */ -static void tx_set_idle(SLMP_INFO *info) -{ - unsigned char RegValue = 0xff; - - /* Map API idle mode to SCA register bits */ - switch(info->idle_mode) { - case HDLC_TXIDLE_FLAGS: RegValue = 0x7e; break; - case HDLC_TXIDLE_ALT_ZEROS_ONES: RegValue = 0xaa; break; - case HDLC_TXIDLE_ZEROS: RegValue = 0x00; break; - case HDLC_TXIDLE_ONES: RegValue = 0xff; break; - case HDLC_TXIDLE_ALT_MARK_SPACE: RegValue = 0xaa; break; - case HDLC_TXIDLE_SPACE: RegValue = 0x00; break; - case HDLC_TXIDLE_MARK: RegValue = 0xff; break; - } - - write_reg(info, IDL, RegValue); -} - -/* Query the adapter for the state of the V24 status (input) signals. - */ -static void get_signals(SLMP_INFO *info) -{ - u16 status = read_reg(info, SR3); - u16 gpstatus = read_status_reg(info); - u16 testbit; - - /* clear all serial signals except DTR and RTS */ - info->serial_signals &= SerialSignal_DTR + SerialSignal_RTS; - - /* set serial signal bits to reflect MISR */ - - if (!(status & BIT3)) - info->serial_signals |= SerialSignal_CTS; - - if ( !(status & BIT2)) - info->serial_signals |= SerialSignal_DCD; - - testbit = BIT1 << (info->port_num * 2); // Port 0..3 RI is GPDATA<1,3,5,7> - if (!(gpstatus & testbit)) - info->serial_signals |= SerialSignal_RI; - - testbit = BIT0 << (info->port_num * 2); // Port 0..3 DSR is GPDATA<0,2,4,6> - if (!(gpstatus & testbit)) - info->serial_signals |= SerialSignal_DSR; -} - -/* Set the state of DTR and RTS based on contents of - * serial_signals member of device context. - */ -static void set_signals(SLMP_INFO *info) -{ - unsigned char RegValue; - u16 EnableBit; - - RegValue = read_reg(info, CTL); - if (info->serial_signals & SerialSignal_RTS) - RegValue &= ~BIT0; - else - RegValue |= BIT0; - write_reg(info, CTL, RegValue); - - // Port 0..3 DTR is ctrl reg <1,3,5,7> - EnableBit = BIT1 << (info->port_num*2); - if (info->serial_signals & SerialSignal_DTR) - info->port_array[0]->ctrlreg_value &= ~EnableBit; - else - info->port_array[0]->ctrlreg_value |= EnableBit; - write_control_reg(info); -} - -/*******************/ -/* DMA Buffer Code */ -/*******************/ - -/* Set the count for all receive buffers to SCABUFSIZE - * and set the current buffer to the first buffer. This effectively - * makes all buffers free and discards any data in buffers. - */ -static void rx_reset_buffers(SLMP_INFO *info) -{ - rx_free_frame_buffers(info, 0, info->rx_buf_count - 1); -} - -/* Free the buffers used by a received frame - * - * info pointer to device instance data - * first index of 1st receive buffer of frame - * last index of last receive buffer of frame - */ -static void rx_free_frame_buffers(SLMP_INFO *info, unsigned int first, unsigned int last) -{ - bool done = false; - - while(!done) { - /* reset current buffer for reuse */ - info->rx_buf_list[first].status = 0xff; - - if (first == last) { - done = true; - /* set new last rx descriptor address */ - write_reg16(info, RXDMA + EDA, info->rx_buf_list_ex[first].phys_entry); - } - - first++; - if (first == info->rx_buf_count) - first = 0; - } - - /* set current buffer to next buffer after last buffer of frame */ - info->current_rx_buf = first; -} - -/* Return a received frame from the receive DMA buffers. - * Only frames received without errors are returned. - * - * Return Value: true if frame returned, otherwise false - */ -static bool rx_get_frame(SLMP_INFO *info) -{ - unsigned int StartIndex, EndIndex; /* index of 1st and last buffers of Rx frame */ - unsigned short status; - unsigned int framesize = 0; - bool ReturnCode = false; - unsigned long flags; - struct tty_struct *tty = info->port.tty; - unsigned char addr_field = 0xff; - SCADESC *desc; - SCADESC_EX *desc_ex; - -CheckAgain: - /* assume no frame returned, set zero length */ - framesize = 0; - addr_field = 0xff; - - /* - * current_rx_buf points to the 1st buffer of the next available - * receive frame. To find the last buffer of the frame look for - * a non-zero status field in the buffer entries. (The status - * field is set by the 16C32 after completing a receive frame. - */ - StartIndex = EndIndex = info->current_rx_buf; - - for ( ;; ) { - desc = &info->rx_buf_list[EndIndex]; - desc_ex = &info->rx_buf_list_ex[EndIndex]; - - if (desc->status == 0xff) - goto Cleanup; /* current desc still in use, no frames available */ - - if (framesize == 0 && info->params.addr_filter != 0xff) - addr_field = desc_ex->virt_addr[0]; - - framesize += desc->length; - - /* Status != 0 means last buffer of frame */ - if (desc->status) - break; - - EndIndex++; - if (EndIndex == info->rx_buf_count) - EndIndex = 0; - - if (EndIndex == info->current_rx_buf) { - /* all buffers have been 'used' but none mark */ - /* the end of a frame. Reset buffers and receiver. */ - if ( info->rx_enabled ){ - spin_lock_irqsave(&info->lock,flags); - rx_start(info); - spin_unlock_irqrestore(&info->lock,flags); - } - goto Cleanup; - } - - } - - /* check status of receive frame */ - - /* frame status is byte stored after frame data - * - * 7 EOM (end of msg), 1 = last buffer of frame - * 6 Short Frame, 1 = short frame - * 5 Abort, 1 = frame aborted - * 4 Residue, 1 = last byte is partial - * 3 Overrun, 1 = overrun occurred during frame reception - * 2 CRC, 1 = CRC error detected - * - */ - status = desc->status; - - /* ignore CRC bit if not using CRC (bit is undefined) */ - /* Note:CRC is not save to data buffer */ - if (info->params.crc_type == HDLC_CRC_NONE) - status &= ~BIT2; - - if (framesize == 0 || - (addr_field != 0xff && addr_field != info->params.addr_filter)) { - /* discard 0 byte frames, this seems to occur sometime - * when remote is idling flags. - */ - rx_free_frame_buffers(info, StartIndex, EndIndex); - goto CheckAgain; - } - - if (framesize < 2) - status |= BIT6; - - if (status & (BIT6+BIT5+BIT3+BIT2)) { - /* received frame has errors, - * update counts and mark frame size as 0 - */ - if (status & BIT6) - info->icount.rxshort++; - else if (status & BIT5) - info->icount.rxabort++; - else if (status & BIT3) - info->icount.rxover++; - else - info->icount.rxcrc++; - - framesize = 0; -#if SYNCLINK_GENERIC_HDLC - { - info->netdev->stats.rx_errors++; - info->netdev->stats.rx_frame_errors++; - } -#endif - } - - if ( debug_level >= DEBUG_LEVEL_BH ) - printk("%s(%d):%s rx_get_frame() status=%04X size=%d\n", - __FILE__,__LINE__,info->device_name,status,framesize); - - if ( debug_level >= DEBUG_LEVEL_DATA ) - trace_block(info,info->rx_buf_list_ex[StartIndex].virt_addr, - min_t(int, framesize,SCABUFSIZE),0); - - if (framesize) { - if (framesize > info->max_frame_size) - info->icount.rxlong++; - else { - /* copy dma buffer(s) to contiguous intermediate buffer */ - int copy_count = framesize; - int index = StartIndex; - unsigned char *ptmp = info->tmp_rx_buf; - info->tmp_rx_buf_count = framesize; - - info->icount.rxok++; - - while(copy_count) { - int partial_count = min(copy_count,SCABUFSIZE); - memcpy( ptmp, - info->rx_buf_list_ex[index].virt_addr, - partial_count ); - ptmp += partial_count; - copy_count -= partial_count; - - if ( ++index == info->rx_buf_count ) - index = 0; - } - -#if SYNCLINK_GENERIC_HDLC - if (info->netcount) - hdlcdev_rx(info,info->tmp_rx_buf,framesize); - else -#endif - ldisc_receive_buf(tty,info->tmp_rx_buf, - info->flag_buf, framesize); - } - } - /* Free the buffers used by this frame. */ - rx_free_frame_buffers( info, StartIndex, EndIndex ); - - ReturnCode = true; - -Cleanup: - if ( info->rx_enabled && info->rx_overflow ) { - /* Receiver is enabled, but needs to restarted due to - * rx buffer overflow. If buffers are empty, restart receiver. - */ - if (info->rx_buf_list[EndIndex].status == 0xff) { - spin_lock_irqsave(&info->lock,flags); - rx_start(info); - spin_unlock_irqrestore(&info->lock,flags); - } - } - - return ReturnCode; -} - -/* load the transmit DMA buffer with data - */ -static void tx_load_dma_buffer(SLMP_INFO *info, const char *buf, unsigned int count) -{ - unsigned short copy_count; - unsigned int i = 0; - SCADESC *desc; - SCADESC_EX *desc_ex; - - if ( debug_level >= DEBUG_LEVEL_DATA ) - trace_block(info,buf, min_t(int, count,SCABUFSIZE), 1); - - /* Copy source buffer to one or more DMA buffers, starting with - * the first transmit dma buffer. - */ - for(i=0;;) - { - copy_count = min_t(unsigned short,count,SCABUFSIZE); - - desc = &info->tx_buf_list[i]; - desc_ex = &info->tx_buf_list_ex[i]; - - load_pci_memory(info, desc_ex->virt_addr,buf,copy_count); - - desc->length = copy_count; - desc->status = 0; - - buf += copy_count; - count -= copy_count; - - if (!count) - break; - - i++; - if (i >= info->tx_buf_count) - i = 0; - } - - info->tx_buf_list[i].status = 0x81; /* set EOM and EOT status */ - info->last_tx_buf = ++i; -} - -static bool register_test(SLMP_INFO *info) -{ - static unsigned char testval[] = {0x00, 0xff, 0xaa, 0x55, 0x69, 0x96}; - static unsigned int count = ARRAY_SIZE(testval); - unsigned int i; - bool rc = true; - unsigned long flags; - - spin_lock_irqsave(&info->lock,flags); - reset_port(info); - - /* assume failure */ - info->init_error = DiagStatus_AddressFailure; - - /* Write bit patterns to various registers but do it out of */ - /* sync, then read back and verify values. */ - - for (i = 0 ; i < count ; i++) { - write_reg(info, TMC, testval[i]); - write_reg(info, IDL, testval[(i+1)%count]); - write_reg(info, SA0, testval[(i+2)%count]); - write_reg(info, SA1, testval[(i+3)%count]); - - if ( (read_reg(info, TMC) != testval[i]) || - (read_reg(info, IDL) != testval[(i+1)%count]) || - (read_reg(info, SA0) != testval[(i+2)%count]) || - (read_reg(info, SA1) != testval[(i+3)%count]) ) - { - rc = false; - break; - } - } - - reset_port(info); - spin_unlock_irqrestore(&info->lock,flags); - - return rc; -} - -static bool irq_test(SLMP_INFO *info) -{ - unsigned long timeout; - unsigned long flags; - - unsigned char timer = (info->port_num & 1) ? TIMER2 : TIMER0; - - spin_lock_irqsave(&info->lock,flags); - reset_port(info); - - /* assume failure */ - info->init_error = DiagStatus_IrqFailure; - info->irq_occurred = false; - - /* setup timer0 on SCA0 to interrupt */ - - /* IER2<7..4> = timer<3..0> interrupt enables (1=enabled) */ - write_reg(info, IER2, (unsigned char)((info->port_num & 1) ? BIT6 : BIT4)); - - write_reg(info, (unsigned char)(timer + TEPR), 0); /* timer expand prescale */ - write_reg16(info, (unsigned char)(timer + TCONR), 1); /* timer constant */ - - - /* TMCS, Timer Control/Status Register - * - * 07 CMF, Compare match flag (read only) 1=match - * 06 ECMI, CMF Interrupt Enable: 1=enabled - * 05 Reserved, must be 0 - * 04 TME, Timer Enable - * 03..00 Reserved, must be 0 - * - * 0101 0000 - */ - write_reg(info, (unsigned char)(timer + TMCS), 0x50); - - spin_unlock_irqrestore(&info->lock,flags); - - timeout=100; - while( timeout-- && !info->irq_occurred ) { - msleep_interruptible(10); - } - - spin_lock_irqsave(&info->lock,flags); - reset_port(info); - spin_unlock_irqrestore(&info->lock,flags); - - return info->irq_occurred; -} - -/* initialize individual SCA device (2 ports) - */ -static bool sca_init(SLMP_INFO *info) -{ - /* set wait controller to single mem partition (low), no wait states */ - write_reg(info, PABR0, 0); /* wait controller addr boundary 0 */ - write_reg(info, PABR1, 0); /* wait controller addr boundary 1 */ - write_reg(info, WCRL, 0); /* wait controller low range */ - write_reg(info, WCRM, 0); /* wait controller mid range */ - write_reg(info, WCRH, 0); /* wait controller high range */ - - /* DPCR, DMA Priority Control - * - * 07..05 Not used, must be 0 - * 04 BRC, bus release condition: 0=all transfers complete - * 03 CCC, channel change condition: 0=every cycle - * 02..00 PR<2..0>, priority 100=round robin - * - * 00000100 = 0x04 - */ - write_reg(info, DPCR, dma_priority); - - /* DMA Master Enable, BIT7: 1=enable all channels */ - write_reg(info, DMER, 0x80); - - /* enable all interrupt classes */ - write_reg(info, IER0, 0xff); /* TxRDY,RxRDY,TxINT,RxINT (ports 0-1) */ - write_reg(info, IER1, 0xff); /* DMIB,DMIA (channels 0-3) */ - write_reg(info, IER2, 0xf0); /* TIRQ (timers 0-3) */ - - /* ITCR, interrupt control register - * 07 IPC, interrupt priority, 0=MSCI->DMA - * 06..05 IAK<1..0>, Acknowledge cycle, 00=non-ack cycle - * 04 VOS, Vector Output, 0=unmodified vector - * 03..00 Reserved, must be 0 - */ - write_reg(info, ITCR, 0); - - return true; -} - -/* initialize adapter hardware - */ -static bool init_adapter(SLMP_INFO *info) -{ - int i; - - /* Set BIT30 of Local Control Reg 0x50 to reset SCA */ - volatile u32 *MiscCtrl = (u32 *)(info->lcr_base + 0x50); - u32 readval; - - info->misc_ctrl_value |= BIT30; - *MiscCtrl = info->misc_ctrl_value; - - /* - * Force at least 170ns delay before clearing - * reset bit. Each read from LCR takes at least - * 30ns so 10 times for 300ns to be safe. - */ - for(i=0;i<10;i++) - readval = *MiscCtrl; - - info->misc_ctrl_value &= ~BIT30; - *MiscCtrl = info->misc_ctrl_value; - - /* init control reg (all DTRs off, all clksel=input) */ - info->ctrlreg_value = 0xaa; - write_control_reg(info); - - { - volatile u32 *LCR1BRDR = (u32 *)(info->lcr_base + 0x2c); - lcr1_brdr_value &= ~(BIT5 + BIT4 + BIT3); - - switch(read_ahead_count) - { - case 16: - lcr1_brdr_value |= BIT5 + BIT4 + BIT3; - break; - case 8: - lcr1_brdr_value |= BIT5 + BIT4; - break; - case 4: - lcr1_brdr_value |= BIT5 + BIT3; - break; - case 0: - lcr1_brdr_value |= BIT5; - break; - } - - *LCR1BRDR = lcr1_brdr_value; - *MiscCtrl = misc_ctrl_value; - } - - sca_init(info->port_array[0]); - sca_init(info->port_array[2]); - - return true; -} - -/* Loopback an HDLC frame to test the hardware - * interrupt and DMA functions. - */ -static bool loopback_test(SLMP_INFO *info) -{ -#define TESTFRAMESIZE 20 - - unsigned long timeout; - u16 count = TESTFRAMESIZE; - unsigned char buf[TESTFRAMESIZE]; - bool rc = false; - unsigned long flags; - - struct tty_struct *oldtty = info->port.tty; - u32 speed = info->params.clock_speed; - - info->params.clock_speed = 3686400; - info->port.tty = NULL; - - /* assume failure */ - info->init_error = DiagStatus_DmaFailure; - - /* build and send transmit frame */ - for (count = 0; count < TESTFRAMESIZE;++count) - buf[count] = (unsigned char)count; - - memset(info->tmp_rx_buf,0,TESTFRAMESIZE); - - /* program hardware for HDLC and enabled receiver */ - spin_lock_irqsave(&info->lock,flags); - hdlc_mode(info); - enable_loopback(info,1); - rx_start(info); - info->tx_count = count; - tx_load_dma_buffer(info,buf,count); - tx_start(info); - spin_unlock_irqrestore(&info->lock,flags); - - /* wait for receive complete */ - /* Set a timeout for waiting for interrupt. */ - for ( timeout = 100; timeout; --timeout ) { - msleep_interruptible(10); - - if (rx_get_frame(info)) { - rc = true; - break; - } - } - - /* verify received frame length and contents */ - if (rc && - ( info->tmp_rx_buf_count != count || - memcmp(buf, info->tmp_rx_buf,count))) { - rc = false; - } - - spin_lock_irqsave(&info->lock,flags); - reset_adapter(info); - spin_unlock_irqrestore(&info->lock,flags); - - info->params.clock_speed = speed; - info->port.tty = oldtty; - - return rc; -} - -/* Perform diagnostics on hardware - */ -static int adapter_test( SLMP_INFO *info ) -{ - unsigned long flags; - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):Testing device %s\n", - __FILE__,__LINE__,info->device_name ); - - spin_lock_irqsave(&info->lock,flags); - init_adapter(info); - spin_unlock_irqrestore(&info->lock,flags); - - info->port_array[0]->port_count = 0; - - if ( register_test(info->port_array[0]) && - register_test(info->port_array[1])) { - - info->port_array[0]->port_count = 2; - - if ( register_test(info->port_array[2]) && - register_test(info->port_array[3]) ) - info->port_array[0]->port_count += 2; - } - else { - printk( "%s(%d):Register test failure for device %s Addr=%08lX\n", - __FILE__,__LINE__,info->device_name, (unsigned long)(info->phys_sca_base)); - return -ENODEV; - } - - if ( !irq_test(info->port_array[0]) || - !irq_test(info->port_array[1]) || - (info->port_count == 4 && !irq_test(info->port_array[2])) || - (info->port_count == 4 && !irq_test(info->port_array[3]))) { - printk( "%s(%d):Interrupt test failure for device %s IRQ=%d\n", - __FILE__,__LINE__,info->device_name, (unsigned short)(info->irq_level) ); - return -ENODEV; - } - - if (!loopback_test(info->port_array[0]) || - !loopback_test(info->port_array[1]) || - (info->port_count == 4 && !loopback_test(info->port_array[2])) || - (info->port_count == 4 && !loopback_test(info->port_array[3]))) { - printk( "%s(%d):DMA test failure for device %s\n", - __FILE__,__LINE__,info->device_name); - return -ENODEV; - } - - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):device %s passed diagnostics\n", - __FILE__,__LINE__,info->device_name ); - - info->port_array[0]->init_error = 0; - info->port_array[1]->init_error = 0; - if ( info->port_count > 2 ) { - info->port_array[2]->init_error = 0; - info->port_array[3]->init_error = 0; - } - - return 0; -} - -/* Test the shared memory on a PCI adapter. - */ -static bool memory_test(SLMP_INFO *info) -{ - static unsigned long testval[] = { 0x0, 0x55555555, 0xaaaaaaaa, - 0x66666666, 0x99999999, 0xffffffff, 0x12345678 }; - unsigned long count = ARRAY_SIZE(testval); - unsigned long i; - unsigned long limit = SCA_MEM_SIZE/sizeof(unsigned long); - unsigned long * addr = (unsigned long *)info->memory_base; - - /* Test data lines with test pattern at one location. */ - - for ( i = 0 ; i < count ; i++ ) { - *addr = testval[i]; - if ( *addr != testval[i] ) - return false; - } - - /* Test address lines with incrementing pattern over */ - /* entire address range. */ - - for ( i = 0 ; i < limit ; i++ ) { - *addr = i * 4; - addr++; - } - - addr = (unsigned long *)info->memory_base; - - for ( i = 0 ; i < limit ; i++ ) { - if ( *addr != i * 4 ) - return false; - addr++; - } - - memset( info->memory_base, 0, SCA_MEM_SIZE ); - return true; -} - -/* Load data into PCI adapter shared memory. - * - * The PCI9050 releases control of the local bus - * after completing the current read or write operation. - * - * While the PCI9050 write FIFO not empty, the - * PCI9050 treats all of the writes as a single transaction - * and does not release the bus. This causes DMA latency problems - * at high speeds when copying large data blocks to the shared memory. - * - * This function breaks a write into multiple transations by - * interleaving a read which flushes the write FIFO and 'completes' - * the write transation. This allows any pending DMA request to gain control - * of the local bus in a timely fasion. - */ -static void load_pci_memory(SLMP_INFO *info, char* dest, const char* src, unsigned short count) -{ - /* A load interval of 16 allows for 4 32-bit writes at */ - /* 136ns each for a maximum latency of 542ns on the local bus.*/ - - unsigned short interval = count / sca_pci_load_interval; - unsigned short i; - - for ( i = 0 ; i < interval ; i++ ) - { - memcpy(dest, src, sca_pci_load_interval); - read_status_reg(info); - dest += sca_pci_load_interval; - src += sca_pci_load_interval; - } - - memcpy(dest, src, count % sca_pci_load_interval); -} - -static void trace_block(SLMP_INFO *info,const char* data, int count, int xmit) -{ - int i; - int linecount; - if (xmit) - printk("%s tx data:\n",info->device_name); - else - printk("%s rx data:\n",info->device_name); - - while(count) { - if (count > 16) - linecount = 16; - else - linecount = count; - - for(i=0;i=040 && data[i]<=0176) - printk("%c",data[i]); - else - printk("."); - } - printk("\n"); - - data += linecount; - count -= linecount; - } -} /* end of trace_block() */ - -/* called when HDLC frame times out - * update stats and do tx completion processing - */ -static void tx_timeout(unsigned long context) -{ - SLMP_INFO *info = (SLMP_INFO*)context; - unsigned long flags; - - if ( debug_level >= DEBUG_LEVEL_INFO ) - printk( "%s(%d):%s tx_timeout()\n", - __FILE__,__LINE__,info->device_name); - if(info->tx_active && info->params.mode == MGSL_MODE_HDLC) { - info->icount.txtimeout++; - } - spin_lock_irqsave(&info->lock,flags); - info->tx_active = false; - info->tx_count = info->tx_put = info->tx_get = 0; - - spin_unlock_irqrestore(&info->lock,flags); - -#if SYNCLINK_GENERIC_HDLC - if (info->netcount) - hdlcdev_tx_done(info); - else -#endif - bh_transmit(info); -} - -/* called to periodically check the DSR/RI modem signal input status - */ -static void status_timeout(unsigned long context) -{ - u16 status = 0; - SLMP_INFO *info = (SLMP_INFO*)context; - unsigned long flags; - unsigned char delta; - - - spin_lock_irqsave(&info->lock,flags); - get_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - - /* check for DSR/RI state change */ - - delta = info->old_signals ^ info->serial_signals; - info->old_signals = info->serial_signals; - - if (delta & SerialSignal_DSR) - status |= MISCSTATUS_DSR_LATCHED|(info->serial_signals&SerialSignal_DSR); - - if (delta & SerialSignal_RI) - status |= MISCSTATUS_RI_LATCHED|(info->serial_signals&SerialSignal_RI); - - if (delta & SerialSignal_DCD) - status |= MISCSTATUS_DCD_LATCHED|(info->serial_signals&SerialSignal_DCD); - - if (delta & SerialSignal_CTS) - status |= MISCSTATUS_CTS_LATCHED|(info->serial_signals&SerialSignal_CTS); - - if (status) - isr_io_pin(info,status); - - mod_timer(&info->status_timer, jiffies + msecs_to_jiffies(10)); -} - - -/* Register Access Routines - - * All registers are memory mapped - */ -#define CALC_REGADDR() \ - unsigned char * RegAddr = (unsigned char*)(info->sca_base + Addr); \ - if (info->port_num > 1) \ - RegAddr += 256; /* port 0-1 SCA0, 2-3 SCA1 */ \ - if ( info->port_num & 1) { \ - if (Addr > 0x7f) \ - RegAddr += 0x40; /* DMA access */ \ - else if (Addr > 0x1f && Addr < 0x60) \ - RegAddr += 0x20; /* MSCI access */ \ - } - - -static unsigned char read_reg(SLMP_INFO * info, unsigned char Addr) -{ - CALC_REGADDR(); - return *RegAddr; -} -static void write_reg(SLMP_INFO * info, unsigned char Addr, unsigned char Value) -{ - CALC_REGADDR(); - *RegAddr = Value; -} - -static u16 read_reg16(SLMP_INFO * info, unsigned char Addr) -{ - CALC_REGADDR(); - return *((u16 *)RegAddr); -} - -static void write_reg16(SLMP_INFO * info, unsigned char Addr, u16 Value) -{ - CALC_REGADDR(); - *((u16 *)RegAddr) = Value; -} - -static unsigned char read_status_reg(SLMP_INFO * info) -{ - unsigned char *RegAddr = (unsigned char *)info->statctrl_base; - return *RegAddr; -} - -static void write_control_reg(SLMP_INFO * info) -{ - unsigned char *RegAddr = (unsigned char *)info->statctrl_base; - *RegAddr = info->port_array[0]->ctrlreg_value; -} - - -static int __devinit synclinkmp_init_one (struct pci_dev *dev, - const struct pci_device_id *ent) -{ - if (pci_enable_device(dev)) { - printk("error enabling pci device %p\n", dev); - return -EIO; - } - device_init( ++synclinkmp_adapter_count, dev ); - return 0; -} - -static void __devexit synclinkmp_remove_one (struct pci_dev *dev) -{ -} diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index 9cfbdb318ed9..3fd7199301b6 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig @@ -147,4 +147,175 @@ config LEGACY_PTY_COUNT When not in use, each legacy PTY occupies 12 bytes on 32-bit architectures and 24 bytes on 64-bit architectures. +config BFIN_JTAG_COMM + tristate "Blackfin JTAG Communication" + depends on BLACKFIN + help + Add support for emulating a TTY device over the Blackfin JTAG. + + To compile this driver as a module, choose M here: the + module will be called bfin_jtag_comm. + +config BFIN_JTAG_COMM_CONSOLE + bool "Console on Blackfin JTAG" + depends on BFIN_JTAG_COMM=y + +config SERIAL_NONSTANDARD + bool "Non-standard serial port support" + depends on HAS_IOMEM + ---help--- + Say Y here if you have any non-standard serial boards -- boards + which aren't supported using the standard "dumb" serial driver. + This includes intelligent serial boards such as Cyclades, + Digiboards, etc. These are usually used for systems that need many + serial ports because they serve many terminals or dial-in + connections. + + Note that the answer to this question won't directly affect the + kernel: saying N will just cause the configurator to skip all + the questions about non-standard serial boards. + + Most people can say N here. + +config ROCKETPORT + tristate "Comtrol RocketPort support" + depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) + help + This driver supports Comtrol RocketPort and RocketModem PCI boards. + These boards provide 2, 4, 8, 16, or 32 high-speed serial ports or + modems. For information about the RocketPort/RocketModem boards + and this driver read . + + To compile this driver as a module, choose M here: the + module will be called rocket. + + If you want to compile this driver into the kernel, say Y here. If + you don't have a Comtrol RocketPort/RocketModem card installed, say N. + +config CYCLADES + tristate "Cyclades async mux support" + depends on SERIAL_NONSTANDARD && (PCI || ISA) + select FW_LOADER + ---help--- + This driver supports Cyclades Z and Y multiserial boards. + You would need something like this to connect more than two modems to + your Linux box, for instance in order to become a dial-in server. + + For information about the Cyclades-Z card, read + . + + To compile this driver as a module, choose M here: the + module will be called cyclades. + + If you haven't heard about it, it's safe to say N. + +config CYZ_INTR + bool "Cyclades-Z interrupt mode operation (EXPERIMENTAL)" + depends on EXPERIMENTAL && CYCLADES + help + The Cyclades-Z family of multiport cards allows 2 (two) driver op + modes: polling and interrupt. In polling mode, the driver will check + the status of the Cyclades-Z ports every certain amount of time + (which is called polling cycle and is configurable). In interrupt + mode, it will use an interrupt line (IRQ) in order to check the + status of the Cyclades-Z ports. The default op mode is polling. If + unsure, say N. + +config MOXA_INTELLIO + tristate "Moxa Intellio support" + depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) + select FW_LOADER + help + Say Y here if you have a Moxa Intellio multiport serial card. + + To compile this driver as a module, choose M here: the + module will be called moxa. + +config MOXA_SMARTIO + tristate "Moxa SmartIO support v. 2.0" + depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) + help + Say Y here if you have a Moxa SmartIO multiport serial card and/or + want to help develop a new version of this driver. + + This is upgraded (1.9.1) driver from original Moxa drivers with + changes finally resulting in PCI probing. + + This driver can also be built as a module. The module will be called + mxser. If you want to do that, say M here. + +config SYNCLINK + tristate "Microgate SyncLink card support" + depends on SERIAL_NONSTANDARD && PCI && ISA_DMA_API + help + Provides support for the SyncLink ISA and PCI multiprotocol serial + adapters. These adapters support asynchronous and HDLC bit + synchronous communication up to 10Mbps (PCI adapter). + + This driver can only be built as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called synclink. If you want to do that, say M + here. + +config SYNCLINKMP + tristate "SyncLink Multiport support" + depends on SERIAL_NONSTANDARD && PCI + help + Enable support for the SyncLink Multiport (2 or 4 ports) + serial adapter, running asynchronous and HDLC communications up + to 2.048Mbps. Each ports is independently selectable for + RS-232, V.35, RS-449, RS-530, and X.21 + + This driver may be built as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called synclinkmp. If you want to do that, say M + here. + +config SYNCLINK_GT + tristate "SyncLink GT/AC support" + depends on SERIAL_NONSTANDARD && PCI + help + Support for SyncLink GT and SyncLink AC families of + synchronous and asynchronous serial adapters + manufactured by Microgate Systems, Ltd. (www.microgate.com) + +config NOZOMI + tristate "HSDPA Broadband Wireless Data Card - Globe Trotter" + depends on PCI && EXPERIMENTAL + help + If you have a HSDPA driver Broadband Wireless Data Card - + Globe Trotter PCMCIA card, say Y here. + + To compile this driver as a module, choose M here, the module + will be called nozomi. + +config ISI + tristate "Multi-Tech multiport card support (EXPERIMENTAL)" + depends on SERIAL_NONSTANDARD && PCI + select FW_LOADER + help + This is a driver for the Multi-Tech cards which provide several + serial ports. The driver is experimental and can currently only be + built as a module. The module will be called isicom. + If you want to do that, choose M here. + +config N_HDLC + tristate "HDLC line discipline support" + depends on SERIAL_NONSTANDARD + help + Allows synchronous HDLC communications with tty device drivers that + support synchronous HDLC such as the Microgate SyncLink adapter. + + This driver can be built as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called n_hdlc. If you want to do that, say M + here. + +config N_GSM + tristate "GSM MUX line discipline support (EXPERIMENTAL)" + depends on EXPERIMENTAL + depends on NET + help + This line discipline provides support for the GSM MUX protocol and + presents the mux as a set of 61 individual tty devices. diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index 396277216e4f..e549da348a04 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile @@ -11,3 +11,16 @@ obj-$(CONFIG_R3964) += n_r3964.o obj-y += vt/ obj-$(CONFIG_HVC_DRIVER) += hvc/ obj-y += serial/ + +# tty drivers +obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o +obj-$(CONFIG_BFIN_JTAG_COMM) += bfin_jtag_comm.o +obj-$(CONFIG_CYCLADES) += cyclades.o +obj-$(CONFIG_ISI) += isicom.o +obj-$(CONFIG_MOXA_INTELLIO) += moxa.o +obj-$(CONFIG_MOXA_SMARTIO) += mxser.o +obj-$(CONFIG_NOZOMI) += nozomi.o +obj-$(CONFIG_ROCKETPORT) += rocket.o +obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o +obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o +obj-$(CONFIG_SYNCLINK) += synclink.o diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c new file mode 100644 index 000000000000..f214e5022472 --- /dev/null +++ b/drivers/tty/amiserial.c @@ -0,0 +1,2178 @@ +/* + * linux/drivers/char/amiserial.c + * + * Serial driver for the amiga builtin port. + * + * This code was created by taking serial.c version 4.30 from kernel + * release 2.3.22, replacing all hardware related stuff with the + * corresponding amiga hardware actions, and removing all irrelevant + * code. As a consequence, it uses many of the constants and names + * associated with the registers and bits of 16550 compatible UARTS - + * but only to keep track of status, etc in the state variables. It + * was done this was to make it easier to keep the code in line with + * (non hardware specific) changes to serial.c. + * + * The port is registered with the tty driver as minor device 64, and + * therefore other ports should should only use 65 upwards. + * + * Richard Lucock 28/12/99 + * + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, + * 1998, 1999 Theodore Ts'o + * + */ + +/* + * Serial driver configuration section. Here are the various options: + * + * SERIAL_PARANOIA_CHECK + * Check the magic number for the async_structure where + * ever possible. + */ + +#include + +#undef SERIAL_PARANOIA_CHECK +#define SERIAL_DO_RESTART + +/* Set of debugging defines */ + +#undef SERIAL_DEBUG_INTR +#undef SERIAL_DEBUG_OPEN +#undef SERIAL_DEBUG_FLOW +#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + +/* Sanity checks */ + +#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) +#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \ + tty->name, (info->flags), serial_driver->refcount,info->count,tty->count,s) +#else +#define DBG_CNT(s) +#endif + +/* + * End of serial driver configuration section. + */ + +#include + +#include +#include +#include +#include +static char *serial_version = "4.30"; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include +#include + +#define custom amiga_custom +static char *serial_name = "Amiga-builtin serial driver"; + +static struct tty_driver *serial_driver; + +/* number of characters left in xmit buffer before we ask for more */ +#define WAKEUP_CHARS 256 + +static struct async_struct *IRQ_ports; + +static unsigned char current_ctl_bits; + +static void change_speed(struct async_struct *info, struct ktermios *old); +static void rs_wait_until_sent(struct tty_struct *tty, int timeout); + + +static struct serial_state rs_table[1]; + +#define NR_PORTS ARRAY_SIZE(rs_table) + +#include + +#define serial_isroot() (capable(CAP_SYS_ADMIN)) + + +static inline int serial_paranoia_check(struct async_struct *info, + char *name, const char *routine) +{ +#ifdef SERIAL_PARANOIA_CHECK + static const char *badmagic = + "Warning: bad magic number for serial struct (%s) in %s\n"; + static const char *badinfo = + "Warning: null async_struct for (%s) in %s\n"; + + if (!info) { + printk(badinfo, name, routine); + return 1; + } + if (info->magic != SERIAL_MAGIC) { + printk(badmagic, name, routine); + return 1; + } +#endif + return 0; +} + +/* some serial hardware definitions */ +#define SDR_OVRUN (1<<15) +#define SDR_RBF (1<<14) +#define SDR_TBE (1<<13) +#define SDR_TSRE (1<<12) + +#define SERPER_PARENB (1<<15) + +#define AC_SETCLR (1<<15) +#define AC_UARTBRK (1<<11) + +#define SER_DTR (1<<7) +#define SER_RTS (1<<6) +#define SER_DCD (1<<5) +#define SER_CTS (1<<4) +#define SER_DSR (1<<3) + +static __inline__ void rtsdtr_ctrl(int bits) +{ + ciab.pra = ((bits & (SER_RTS | SER_DTR)) ^ (SER_RTS | SER_DTR)) | (ciab.pra & ~(SER_RTS | SER_DTR)); +} + +/* + * ------------------------------------------------------------ + * rs_stop() and rs_start() + * + * This routines are called before setting or resetting tty->stopped. + * They enable or disable transmitter interrupts, as necessary. + * ------------------------------------------------------------ + */ +static void rs_stop(struct tty_struct *tty) +{ + struct async_struct *info = tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->name, "rs_stop")) + return; + + local_irq_save(flags); + if (info->IER & UART_IER_THRI) { + info->IER &= ~UART_IER_THRI; + /* disable Tx interrupt and remove any pending interrupts */ + custom.intena = IF_TBE; + mb(); + custom.intreq = IF_TBE; + mb(); + } + local_irq_restore(flags); +} + +static void rs_start(struct tty_struct *tty) +{ + struct async_struct *info = tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->name, "rs_start")) + return; + + local_irq_save(flags); + if (info->xmit.head != info->xmit.tail + && info->xmit.buf + && !(info->IER & UART_IER_THRI)) { + info->IER |= UART_IER_THRI; + custom.intena = IF_SETCLR | IF_TBE; + mb(); + /* set a pending Tx Interrupt, transmitter should restart now */ + custom.intreq = IF_SETCLR | IF_TBE; + mb(); + } + local_irq_restore(flags); +} + +/* + * ---------------------------------------------------------------------- + * + * Here starts the interrupt handling routines. All of the following + * subroutines are declared as inline and are folded into + * rs_interrupt(). They were separated out for readability's sake. + * + * Note: rs_interrupt() is a "fast" interrupt, which means that it + * runs with interrupts turned off. People who may want to modify + * rs_interrupt() should try to keep the interrupt handler as fast as + * possible. After you are done making modifications, it is not a bad + * idea to do: + * + * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c + * + * and look at the resulting assemble code in serial.s. + * + * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 + * ----------------------------------------------------------------------- + */ + +/* + * This routine is used by the interrupt handler to schedule + * processing in the software interrupt portion of the driver. + */ +static void rs_sched_event(struct async_struct *info, + int event) +{ + info->event |= 1 << event; + tasklet_schedule(&info->tlet); +} + +static void receive_chars(struct async_struct *info) +{ + int status; + int serdatr; + struct tty_struct *tty = info->tty; + unsigned char ch, flag; + struct async_icount *icount; + int oe = 0; + + icount = &info->state->icount; + + status = UART_LSR_DR; /* We obviously have a character! */ + serdatr = custom.serdatr; + mb(); + custom.intreq = IF_RBF; + mb(); + + if((serdatr & 0x1ff) == 0) + status |= UART_LSR_BI; + if(serdatr & SDR_OVRUN) + status |= UART_LSR_OE; + + ch = serdatr & 0xff; + icount->rx++; + +#ifdef SERIAL_DEBUG_INTR + printk("DR%02x:%02x...", ch, status); +#endif + flag = TTY_NORMAL; + + /* + * We don't handle parity or frame errors - but I have left + * the code in, since I'm not sure that the errors can't be + * detected. + */ + + if (status & (UART_LSR_BI | UART_LSR_PE | + UART_LSR_FE | UART_LSR_OE)) { + /* + * For statistics only + */ + if (status & UART_LSR_BI) { + status &= ~(UART_LSR_FE | UART_LSR_PE); + icount->brk++; + } else if (status & UART_LSR_PE) + icount->parity++; + else if (status & UART_LSR_FE) + icount->frame++; + if (status & UART_LSR_OE) + icount->overrun++; + + /* + * Now check to see if character should be + * ignored, and mask off conditions which + * should be ignored. + */ + if (status & info->ignore_status_mask) + goto out; + + status &= info->read_status_mask; + + if (status & (UART_LSR_BI)) { +#ifdef SERIAL_DEBUG_INTR + printk("handling break...."); +#endif + flag = TTY_BREAK; + if (info->flags & ASYNC_SAK) + do_SAK(tty); + } else if (status & UART_LSR_PE) + flag = TTY_PARITY; + else if (status & UART_LSR_FE) + flag = TTY_FRAME; + if (status & UART_LSR_OE) { + /* + * Overrun is special, since it's + * reported immediately, and doesn't + * affect the current character + */ + oe = 1; + } + } + tty_insert_flip_char(tty, ch, flag); + if (oe == 1) + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + tty_flip_buffer_push(tty); +out: + return; +} + +static void transmit_chars(struct async_struct *info) +{ + custom.intreq = IF_TBE; + mb(); + if (info->x_char) { + custom.serdat = info->x_char | 0x100; + mb(); + info->state->icount.tx++; + info->x_char = 0; + return; + } + if (info->xmit.head == info->xmit.tail + || info->tty->stopped + || info->tty->hw_stopped) { + info->IER &= ~UART_IER_THRI; + custom.intena = IF_TBE; + mb(); + return; + } + + custom.serdat = info->xmit.buf[info->xmit.tail++] | 0x100; + mb(); + info->xmit.tail = info->xmit.tail & (SERIAL_XMIT_SIZE-1); + info->state->icount.tx++; + + if (CIRC_CNT(info->xmit.head, + info->xmit.tail, + SERIAL_XMIT_SIZE) < WAKEUP_CHARS) + rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); + +#ifdef SERIAL_DEBUG_INTR + printk("THRE..."); +#endif + if (info->xmit.head == info->xmit.tail) { + custom.intena = IF_TBE; + mb(); + info->IER &= ~UART_IER_THRI; + } +} + +static void check_modem_status(struct async_struct *info) +{ + unsigned char status = ciab.pra & (SER_DCD | SER_CTS | SER_DSR); + unsigned char dstatus; + struct async_icount *icount; + + /* Determine bits that have changed */ + dstatus = status ^ current_ctl_bits; + current_ctl_bits = status; + + if (dstatus) { + icount = &info->state->icount; + /* update input line counters */ + if (dstatus & SER_DSR) + icount->dsr++; + if (dstatus & SER_DCD) { + icount->dcd++; +#ifdef CONFIG_HARD_PPS + if ((info->flags & ASYNC_HARDPPS_CD) && + !(status & SER_DCD)) + hardpps(); +#endif + } + if (dstatus & SER_CTS) + icount->cts++; + wake_up_interruptible(&info->delta_msr_wait); + } + + if ((info->flags & ASYNC_CHECK_CD) && (dstatus & SER_DCD)) { +#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) + printk("ttyS%d CD now %s...", info->line, + (!(status & SER_DCD)) ? "on" : "off"); +#endif + if (!(status & SER_DCD)) + wake_up_interruptible(&info->open_wait); + else { +#ifdef SERIAL_DEBUG_OPEN + printk("doing serial hangup..."); +#endif + if (info->tty) + tty_hangup(info->tty); + } + } + if (info->flags & ASYNC_CTS_FLOW) { + if (info->tty->hw_stopped) { + if (!(status & SER_CTS)) { +#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) + printk("CTS tx start..."); +#endif + info->tty->hw_stopped = 0; + info->IER |= UART_IER_THRI; + custom.intena = IF_SETCLR | IF_TBE; + mb(); + /* set a pending Tx Interrupt, transmitter should restart now */ + custom.intreq = IF_SETCLR | IF_TBE; + mb(); + rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); + return; + } + } else { + if ((status & SER_CTS)) { +#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) + printk("CTS tx stop..."); +#endif + info->tty->hw_stopped = 1; + info->IER &= ~UART_IER_THRI; + /* disable Tx interrupt and remove any pending interrupts */ + custom.intena = IF_TBE; + mb(); + custom.intreq = IF_TBE; + mb(); + } + } + } +} + +static irqreturn_t ser_vbl_int( int irq, void *data) +{ + /* vbl is just a periodic interrupt we tie into to update modem status */ + struct async_struct * info = IRQ_ports; + /* + * TBD - is it better to unregister from this interrupt or to + * ignore it if MSI is clear ? + */ + if(info->IER & UART_IER_MSI) + check_modem_status(info); + return IRQ_HANDLED; +} + +static irqreturn_t ser_rx_int(int irq, void *dev_id) +{ + struct async_struct * info; + +#ifdef SERIAL_DEBUG_INTR + printk("ser_rx_int..."); +#endif + + info = IRQ_ports; + if (!info || !info->tty) + return IRQ_NONE; + + receive_chars(info); + info->last_active = jiffies; +#ifdef SERIAL_DEBUG_INTR + printk("end.\n"); +#endif + return IRQ_HANDLED; +} + +static irqreturn_t ser_tx_int(int irq, void *dev_id) +{ + struct async_struct * info; + + if (custom.serdatr & SDR_TBE) { +#ifdef SERIAL_DEBUG_INTR + printk("ser_tx_int..."); +#endif + + info = IRQ_ports; + if (!info || !info->tty) + return IRQ_NONE; + + transmit_chars(info); + info->last_active = jiffies; +#ifdef SERIAL_DEBUG_INTR + printk("end.\n"); +#endif + } + return IRQ_HANDLED; +} + +/* + * ------------------------------------------------------------------- + * Here ends the serial interrupt routines. + * ------------------------------------------------------------------- + */ + +/* + * This routine is used to handle the "bottom half" processing for the + * serial driver, known also the "software interrupt" processing. + * This processing is done at the kernel interrupt level, after the + * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This + * is where time-consuming activities which can not be done in the + * interrupt driver proper are done; the interrupt driver schedules + * them using rs_sched_event(), and they get done here. + */ + +static void do_softint(unsigned long private_) +{ + struct async_struct *info = (struct async_struct *) private_; + struct tty_struct *tty; + + tty = info->tty; + if (!tty) + return; + + if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) + tty_wakeup(tty); +} + +/* + * --------------------------------------------------------------- + * Low level utility subroutines for the serial driver: routines to + * figure out the appropriate timeout for an interrupt chain, routines + * to initialize and startup a serial port, and routines to shutdown a + * serial port. Useful stuff like that. + * --------------------------------------------------------------- + */ + +static int startup(struct async_struct * info) +{ + unsigned long flags; + int retval=0; + unsigned long page; + + page = get_zeroed_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + + local_irq_save(flags); + + if (info->flags & ASYNC_INITIALIZED) { + free_page(page); + goto errout; + } + + if (info->xmit.buf) + free_page(page); + else + info->xmit.buf = (unsigned char *) page; + +#ifdef SERIAL_DEBUG_OPEN + printk("starting up ttys%d ...", info->line); +#endif + + /* Clear anything in the input buffer */ + + custom.intreq = IF_RBF; + mb(); + + retval = request_irq(IRQ_AMIGA_VERTB, ser_vbl_int, 0, "serial status", info); + if (retval) { + if (serial_isroot()) { + if (info->tty) + set_bit(TTY_IO_ERROR, + &info->tty->flags); + retval = 0; + } + goto errout; + } + + /* enable both Rx and Tx interrupts */ + custom.intena = IF_SETCLR | IF_RBF | IF_TBE; + mb(); + info->IER = UART_IER_MSI; + + /* remember current state of the DCD and CTS bits */ + current_ctl_bits = ciab.pra & (SER_DCD | SER_CTS | SER_DSR); + + IRQ_ports = info; + + info->MCR = 0; + if (info->tty->termios->c_cflag & CBAUD) + info->MCR = SER_DTR | SER_RTS; + rtsdtr_ctrl(info->MCR); + + if (info->tty) + clear_bit(TTY_IO_ERROR, &info->tty->flags); + info->xmit.head = info->xmit.tail = 0; + + /* + * Set up the tty->alt_speed kludge + */ + if (info->tty) { + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + info->tty->alt_speed = 57600; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + info->tty->alt_speed = 115200; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + info->tty->alt_speed = 230400; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + info->tty->alt_speed = 460800; + } + + /* + * and set the speed of the serial port + */ + change_speed(info, NULL); + + info->flags |= ASYNC_INITIALIZED; + local_irq_restore(flags); + return 0; + +errout: + local_irq_restore(flags); + return retval; +} + +/* + * This routine will shutdown a serial port; interrupts are disabled, and + * DTR is dropped if the hangup on close termio flag is on. + */ +static void shutdown(struct async_struct * info) +{ + unsigned long flags; + struct serial_state *state; + + if (!(info->flags & ASYNC_INITIALIZED)) + return; + + state = info->state; + +#ifdef SERIAL_DEBUG_OPEN + printk("Shutting down serial port %d ....\n", info->line); +#endif + + local_irq_save(flags); /* Disable interrupts */ + + /* + * clear delta_msr_wait queue to avoid mem leaks: we may free the irq + * here so the queue might never be waken up + */ + wake_up_interruptible(&info->delta_msr_wait); + + IRQ_ports = NULL; + + /* + * Free the IRQ, if necessary + */ + free_irq(IRQ_AMIGA_VERTB, info); + + if (info->xmit.buf) { + free_page((unsigned long) info->xmit.buf); + info->xmit.buf = NULL; + } + + info->IER = 0; + custom.intena = IF_RBF | IF_TBE; + mb(); + + /* disable break condition */ + custom.adkcon = AC_UARTBRK; + mb(); + + if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) + info->MCR &= ~(SER_DTR|SER_RTS); + rtsdtr_ctrl(info->MCR); + + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + + info->flags &= ~ASYNC_INITIALIZED; + local_irq_restore(flags); +} + + +/* + * This routine is called to set the UART divisor registers to match + * the specified baud rate for a serial port. + */ +static void change_speed(struct async_struct *info, + struct ktermios *old_termios) +{ + int quot = 0, baud_base, baud; + unsigned cflag, cval = 0; + int bits; + unsigned long flags; + + if (!info->tty || !info->tty->termios) + return; + cflag = info->tty->termios->c_cflag; + + /* Byte size is always 8 bits plus parity bit if requested */ + + cval = 3; bits = 10; + if (cflag & CSTOPB) { + cval |= 0x04; + bits++; + } + if (cflag & PARENB) { + cval |= UART_LCR_PARITY; + bits++; + } + if (!(cflag & PARODD)) + cval |= UART_LCR_EPAR; +#ifdef CMSPAR + if (cflag & CMSPAR) + cval |= UART_LCR_SPAR; +#endif + + /* Determine divisor based on baud rate */ + baud = tty_get_baud_rate(info->tty); + if (!baud) + baud = 9600; /* B0 transition handled in rs_set_termios */ + baud_base = info->state->baud_base; + if (baud == 38400 && + ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) + quot = info->state->custom_divisor; + else { + if (baud == 134) + /* Special case since 134 is really 134.5 */ + quot = (2*baud_base / 269); + else if (baud) + quot = baud_base / baud; + } + /* If the quotient is zero refuse the change */ + if (!quot && old_termios) { + /* FIXME: Will need updating for new tty in the end */ + info->tty->termios->c_cflag &= ~CBAUD; + info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD); + baud = tty_get_baud_rate(info->tty); + if (!baud) + baud = 9600; + if (baud == 38400 && + ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) + quot = info->state->custom_divisor; + else { + if (baud == 134) + /* Special case since 134 is really 134.5 */ + quot = (2*baud_base / 269); + else if (baud) + quot = baud_base / baud; + } + } + /* As a last resort, if the quotient is zero, default to 9600 bps */ + if (!quot) + quot = baud_base / 9600; + info->quot = quot; + info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base); + info->timeout += HZ/50; /* Add .02 seconds of slop */ + + /* CTS flow control flag and modem status interrupts */ + info->IER &= ~UART_IER_MSI; + if (info->flags & ASYNC_HARDPPS_CD) + info->IER |= UART_IER_MSI; + if (cflag & CRTSCTS) { + info->flags |= ASYNC_CTS_FLOW; + info->IER |= UART_IER_MSI; + } else + info->flags &= ~ASYNC_CTS_FLOW; + if (cflag & CLOCAL) + info->flags &= ~ASYNC_CHECK_CD; + else { + info->flags |= ASYNC_CHECK_CD; + info->IER |= UART_IER_MSI; + } + /* TBD: + * Does clearing IER_MSI imply that we should disable the VBL interrupt ? + */ + + /* + * Set up parity check flag + */ + + info->read_status_mask = UART_LSR_OE | UART_LSR_DR; + if (I_INPCK(info->tty)) + info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; + if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) + info->read_status_mask |= UART_LSR_BI; + + /* + * Characters to ignore + */ + info->ignore_status_mask = 0; + if (I_IGNPAR(info->tty)) + info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; + if (I_IGNBRK(info->tty)) { + info->ignore_status_mask |= UART_LSR_BI; + /* + * If we're ignore parity and break indicators, ignore + * overruns too. (For real raw support). + */ + if (I_IGNPAR(info->tty)) + info->ignore_status_mask |= UART_LSR_OE; + } + /* + * !!! ignore all characters if CREAD is not set + */ + if ((cflag & CREAD) == 0) + info->ignore_status_mask |= UART_LSR_DR; + local_irq_save(flags); + + { + short serper; + + /* Set up the baud rate */ + serper = quot - 1; + + /* Enable or disable parity bit */ + + if(cval & UART_LCR_PARITY) + serper |= (SERPER_PARENB); + + custom.serper = serper; + mb(); + } + + info->LCR = cval; /* Save LCR */ + local_irq_restore(flags); +} + +static int rs_put_char(struct tty_struct *tty, unsigned char ch) +{ + struct async_struct *info; + unsigned long flags; + + info = tty->driver_data; + + if (serial_paranoia_check(info, tty->name, "rs_put_char")) + return 0; + + if (!info->xmit.buf) + return 0; + + local_irq_save(flags); + if (CIRC_SPACE(info->xmit.head, + info->xmit.tail, + SERIAL_XMIT_SIZE) == 0) { + local_irq_restore(flags); + return 0; + } + + info->xmit.buf[info->xmit.head++] = ch; + info->xmit.head &= SERIAL_XMIT_SIZE-1; + local_irq_restore(flags); + return 1; +} + +static void rs_flush_chars(struct tty_struct *tty) +{ + struct async_struct *info = tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->name, "rs_flush_chars")) + return; + + if (info->xmit.head == info->xmit.tail + || tty->stopped + || tty->hw_stopped + || !info->xmit.buf) + return; + + local_irq_save(flags); + info->IER |= UART_IER_THRI; + custom.intena = IF_SETCLR | IF_TBE; + mb(); + /* set a pending Tx Interrupt, transmitter should restart now */ + custom.intreq = IF_SETCLR | IF_TBE; + mb(); + local_irq_restore(flags); +} + +static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count) +{ + int c, ret = 0; + struct async_struct *info; + unsigned long flags; + + info = tty->driver_data; + + if (serial_paranoia_check(info, tty->name, "rs_write")) + return 0; + + if (!info->xmit.buf) + return 0; + + local_irq_save(flags); + while (1) { + c = CIRC_SPACE_TO_END(info->xmit.head, + info->xmit.tail, + SERIAL_XMIT_SIZE); + if (count < c) + c = count; + if (c <= 0) { + break; + } + memcpy(info->xmit.buf + info->xmit.head, buf, c); + info->xmit.head = ((info->xmit.head + c) & + (SERIAL_XMIT_SIZE-1)); + buf += c; + count -= c; + ret += c; + } + local_irq_restore(flags); + + if (info->xmit.head != info->xmit.tail + && !tty->stopped + && !tty->hw_stopped + && !(info->IER & UART_IER_THRI)) { + info->IER |= UART_IER_THRI; + local_irq_disable(); + custom.intena = IF_SETCLR | IF_TBE; + mb(); + /* set a pending Tx Interrupt, transmitter should restart now */ + custom.intreq = IF_SETCLR | IF_TBE; + mb(); + local_irq_restore(flags); + } + return ret; +} + +static int rs_write_room(struct tty_struct *tty) +{ + struct async_struct *info = tty->driver_data; + + if (serial_paranoia_check(info, tty->name, "rs_write_room")) + return 0; + return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); +} + +static int rs_chars_in_buffer(struct tty_struct *tty) +{ + struct async_struct *info = tty->driver_data; + + if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer")) + return 0; + return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); +} + +static void rs_flush_buffer(struct tty_struct *tty) +{ + struct async_struct *info = tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) + return; + local_irq_save(flags); + info->xmit.head = info->xmit.tail = 0; + local_irq_restore(flags); + tty_wakeup(tty); +} + +/* + * This function is used to send a high-priority XON/XOFF character to + * the device + */ +static void rs_send_xchar(struct tty_struct *tty, char ch) +{ + struct async_struct *info = tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->name, "rs_send_char")) + return; + + info->x_char = ch; + if (ch) { + /* Make sure transmit interrupts are on */ + + /* Check this ! */ + local_irq_save(flags); + if(!(custom.intenar & IF_TBE)) { + custom.intena = IF_SETCLR | IF_TBE; + mb(); + /* set a pending Tx Interrupt, transmitter should restart now */ + custom.intreq = IF_SETCLR | IF_TBE; + mb(); + } + local_irq_restore(flags); + + info->IER |= UART_IER_THRI; + } +} + +/* + * ------------------------------------------------------------ + * rs_throttle() + * + * This routine is called by the upper-layer tty layer to signal that + * incoming characters should be throttled. + * ------------------------------------------------------------ + */ +static void rs_throttle(struct tty_struct * tty) +{ + struct async_struct *info = tty->driver_data; + unsigned long flags; +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + printk("throttle %s: %d....\n", tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (serial_paranoia_check(info, tty->name, "rs_throttle")) + return; + + if (I_IXOFF(tty)) + rs_send_xchar(tty, STOP_CHAR(tty)); + + if (tty->termios->c_cflag & CRTSCTS) + info->MCR &= ~SER_RTS; + + local_irq_save(flags); + rtsdtr_ctrl(info->MCR); + local_irq_restore(flags); +} + +static void rs_unthrottle(struct tty_struct * tty) +{ + struct async_struct *info = tty->driver_data; + unsigned long flags; +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + printk("unthrottle %s: %d....\n", tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (serial_paranoia_check(info, tty->name, "rs_unthrottle")) + return; + + if (I_IXOFF(tty)) { + if (info->x_char) + info->x_char = 0; + else + rs_send_xchar(tty, START_CHAR(tty)); + } + if (tty->termios->c_cflag & CRTSCTS) + info->MCR |= SER_RTS; + local_irq_save(flags); + rtsdtr_ctrl(info->MCR); + local_irq_restore(flags); +} + +/* + * ------------------------------------------------------------ + * rs_ioctl() and friends + * ------------------------------------------------------------ + */ + +static int get_serial_info(struct async_struct * info, + struct serial_struct __user * retinfo) +{ + struct serial_struct tmp; + struct serial_state *state = info->state; + + if (!retinfo) + return -EFAULT; + memset(&tmp, 0, sizeof(tmp)); + tty_lock(); + tmp.type = state->type; + tmp.line = state->line; + tmp.port = state->port; + tmp.irq = state->irq; + tmp.flags = state->flags; + tmp.xmit_fifo_size = state->xmit_fifo_size; + tmp.baud_base = state->baud_base; + tmp.close_delay = state->close_delay; + tmp.closing_wait = state->closing_wait; + tmp.custom_divisor = state->custom_divisor; + tty_unlock(); + if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) + return -EFAULT; + return 0; +} + +static int set_serial_info(struct async_struct * info, + struct serial_struct __user * new_info) +{ + struct serial_struct new_serial; + struct serial_state old_state, *state; + unsigned int change_irq,change_port; + int retval = 0; + + if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) + return -EFAULT; + + tty_lock(); + state = info->state; + old_state = *state; + + change_irq = new_serial.irq != state->irq; + change_port = (new_serial.port != state->port); + if(change_irq || change_port || (new_serial.xmit_fifo_size != state->xmit_fifo_size)) { + tty_unlock(); + return -EINVAL; + } + + if (!serial_isroot()) { + if ((new_serial.baud_base != state->baud_base) || + (new_serial.close_delay != state->close_delay) || + (new_serial.xmit_fifo_size != state->xmit_fifo_size) || + ((new_serial.flags & ~ASYNC_USR_MASK) != + (state->flags & ~ASYNC_USR_MASK))) + return -EPERM; + state->flags = ((state->flags & ~ASYNC_USR_MASK) | + (new_serial.flags & ASYNC_USR_MASK)); + info->flags = ((info->flags & ~ASYNC_USR_MASK) | + (new_serial.flags & ASYNC_USR_MASK)); + state->custom_divisor = new_serial.custom_divisor; + goto check_and_exit; + } + + if (new_serial.baud_base < 9600) { + tty_unlock(); + return -EINVAL; + } + + /* + * OK, past this point, all the error checking has been done. + * At this point, we start making changes..... + */ + + state->baud_base = new_serial.baud_base; + state->flags = ((state->flags & ~ASYNC_FLAGS) | + (new_serial.flags & ASYNC_FLAGS)); + info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | + (info->flags & ASYNC_INTERNAL_FLAGS)); + state->custom_divisor = new_serial.custom_divisor; + state->close_delay = new_serial.close_delay * HZ/100; + state->closing_wait = new_serial.closing_wait * HZ/100; + info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; + +check_and_exit: + if (info->flags & ASYNC_INITIALIZED) { + if (((old_state.flags & ASYNC_SPD_MASK) != + (state->flags & ASYNC_SPD_MASK)) || + (old_state.custom_divisor != state->custom_divisor)) { + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + info->tty->alt_speed = 57600; + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + info->tty->alt_speed = 115200; + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + info->tty->alt_speed = 230400; + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + info->tty->alt_speed = 460800; + change_speed(info, NULL); + } + } else + retval = startup(info); + tty_unlock(); + return retval; +} + + +/* + * get_lsr_info - get line status register info + * + * Purpose: Let user call ioctl() to get info when the UART physically + * is emptied. On bus types like RS485, the transmitter must + * release the bus after transmitting. This must be done when + * the transmit shift register is empty, not be done when the + * transmit holding register is empty. This functionality + * allows an RS485 driver to be written in user space. + */ +static int get_lsr_info(struct async_struct * info, unsigned int __user *value) +{ + unsigned char status; + unsigned int result; + unsigned long flags; + + local_irq_save(flags); + status = custom.serdatr; + mb(); + local_irq_restore(flags); + result = ((status & SDR_TSRE) ? TIOCSER_TEMT : 0); + if (copy_to_user(value, &result, sizeof(int))) + return -EFAULT; + return 0; +} + + +static int rs_tiocmget(struct tty_struct *tty) +{ + struct async_struct * info = tty->driver_data; + unsigned char control, status; + unsigned long flags; + + if (serial_paranoia_check(info, tty->name, "rs_ioctl")) + return -ENODEV; + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + + control = info->MCR; + local_irq_save(flags); + status = ciab.pra; + local_irq_restore(flags); + return ((control & SER_RTS) ? TIOCM_RTS : 0) + | ((control & SER_DTR) ? TIOCM_DTR : 0) + | (!(status & SER_DCD) ? TIOCM_CAR : 0) + | (!(status & SER_DSR) ? TIOCM_DSR : 0) + | (!(status & SER_CTS) ? TIOCM_CTS : 0); +} + +static int rs_tiocmset(struct tty_struct *tty, unsigned int set, + unsigned int clear) +{ + struct async_struct * info = tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->name, "rs_ioctl")) + return -ENODEV; + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + + local_irq_save(flags); + if (set & TIOCM_RTS) + info->MCR |= SER_RTS; + if (set & TIOCM_DTR) + info->MCR |= SER_DTR; + if (clear & TIOCM_RTS) + info->MCR &= ~SER_RTS; + if (clear & TIOCM_DTR) + info->MCR &= ~SER_DTR; + rtsdtr_ctrl(info->MCR); + local_irq_restore(flags); + return 0; +} + +/* + * rs_break() --- routine which turns the break handling on or off + */ +static int rs_break(struct tty_struct *tty, int break_state) +{ + struct async_struct * info = tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->name, "rs_break")) + return -EINVAL; + + local_irq_save(flags); + if (break_state == -1) + custom.adkcon = AC_SETCLR | AC_UARTBRK; + else + custom.adkcon = AC_UARTBRK; + mb(); + local_irq_restore(flags); + return 0; +} + +/* + * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) + * Return: write counters to the user passed counter struct + * NB: both 1->0 and 0->1 transitions are counted except for + * RI where only 0->1 is counted. + */ +static int rs_get_icount(struct tty_struct *tty, + struct serial_icounter_struct *icount) +{ + struct async_struct *info = tty->driver_data; + struct async_icount cnow; + unsigned long flags; + + local_irq_save(flags); + cnow = info->state->icount; + local_irq_restore(flags); + icount->cts = cnow.cts; + icount->dsr = cnow.dsr; + icount->rng = cnow.rng; + icount->dcd = cnow.dcd; + icount->rx = cnow.rx; + icount->tx = cnow.tx; + icount->frame = cnow.frame; + icount->overrun = cnow.overrun; + icount->parity = cnow.parity; + icount->brk = cnow.brk; + icount->buf_overrun = cnow.buf_overrun; + + return 0; +} + +static int rs_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + struct async_struct * info = tty->driver_data; + struct async_icount cprev, cnow; /* kernel counter temps */ + void __user *argp = (void __user *)arg; + unsigned long flags; + + if (serial_paranoia_check(info, tty->name, "rs_ioctl")) + return -ENODEV; + + if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && + (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && + (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + } + + switch (cmd) { + case TIOCGSERIAL: + return get_serial_info(info, argp); + case TIOCSSERIAL: + return set_serial_info(info, argp); + case TIOCSERCONFIG: + return 0; + + case TIOCSERGETLSR: /* Get line status register */ + return get_lsr_info(info, argp); + + case TIOCSERGSTRUCT: + if (copy_to_user(argp, + info, sizeof(struct async_struct))) + return -EFAULT; + return 0; + + /* + * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change + * - mask passed in arg for lines of interest + * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) + * Caller should use TIOCGICOUNT to see which one it was + */ + case TIOCMIWAIT: + local_irq_save(flags); + /* note the counters on entry */ + cprev = info->state->icount; + local_irq_restore(flags); + while (1) { + interruptible_sleep_on(&info->delta_msr_wait); + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; + local_irq_save(flags); + cnow = info->state->icount; /* atomic copy */ + local_irq_restore(flags); + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && + cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) + return -EIO; /* no change => error */ + if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || + ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || + ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || + ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { + return 0; + } + cprev = cnow; + } + /* NOTREACHED */ + + case TIOCSERGWILD: + case TIOCSERSWILD: + /* "setserial -W" is called in Debian boot */ + printk ("TIOCSER?WILD ioctl obsolete, ignored.\n"); + return 0; + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) +{ + struct async_struct *info = tty->driver_data; + unsigned long flags; + unsigned int cflag = tty->termios->c_cflag; + + change_speed(info, old_termios); + + /* Handle transition to B0 status */ + if ((old_termios->c_cflag & CBAUD) && + !(cflag & CBAUD)) { + info->MCR &= ~(SER_DTR|SER_RTS); + local_irq_save(flags); + rtsdtr_ctrl(info->MCR); + local_irq_restore(flags); + } + + /* Handle transition away from B0 status */ + if (!(old_termios->c_cflag & CBAUD) && + (cflag & CBAUD)) { + info->MCR |= SER_DTR; + if (!(tty->termios->c_cflag & CRTSCTS) || + !test_bit(TTY_THROTTLED, &tty->flags)) { + info->MCR |= SER_RTS; + } + local_irq_save(flags); + rtsdtr_ctrl(info->MCR); + local_irq_restore(flags); + } + + /* Handle turning off CRTSCTS */ + if ((old_termios->c_cflag & CRTSCTS) && + !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + rs_start(tty); + } + +#if 0 + /* + * No need to wake up processes in open wait, since they + * sample the CLOCAL flag once, and don't recheck it. + * XXX It's not clear whether the current behavior is correct + * or not. Hence, this may change..... + */ + if (!(old_termios->c_cflag & CLOCAL) && + (tty->termios->c_cflag & CLOCAL)) + wake_up_interruptible(&info->open_wait); +#endif +} + +/* + * ------------------------------------------------------------ + * rs_close() + * + * This routine is called when the serial port gets closed. First, we + * wait for the last remaining data to be sent. Then, we unlink its + * async structure from the interrupt chain if necessary, and we free + * that IRQ if nothing is left in the chain. + * ------------------------------------------------------------ + */ +static void rs_close(struct tty_struct *tty, struct file * filp) +{ + struct async_struct * info = tty->driver_data; + struct serial_state *state; + unsigned long flags; + + if (!info || serial_paranoia_check(info, tty->name, "rs_close")) + return; + + state = info->state; + + local_irq_save(flags); + + if (tty_hung_up_p(filp)) { + DBG_CNT("before DEC-hung"); + local_irq_restore(flags); + return; + } + +#ifdef SERIAL_DEBUG_OPEN + printk("rs_close ttys%d, count = %d\n", info->line, state->count); +#endif + if ((tty->count == 1) && (state->count != 1)) { + /* + * Uh, oh. tty->count is 1, which means that the tty + * structure will be freed. state->count should always + * be one in these conditions. If it's greater than + * one, we've got real problems, since it means the + * serial port won't be shutdown. + */ + printk("rs_close: bad serial port count; tty->count is 1, " + "state->count is %d\n", state->count); + state->count = 1; + } + if (--state->count < 0) { + printk("rs_close: bad serial port count for ttys%d: %d\n", + info->line, state->count); + state->count = 0; + } + if (state->count) { + DBG_CNT("before DEC-2"); + local_irq_restore(flags); + return; + } + info->flags |= ASYNC_CLOSING; + /* + * Now we wait for the transmit buffer to clear; and we notify + * the line discipline to only process XON/XOFF characters. + */ + tty->closing = 1; + if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) + tty_wait_until_sent(tty, info->closing_wait); + /* + * At this point we stop accepting input. To do this, we + * disable the receive line status interrupts, and tell the + * interrupt driver to stop checking the data ready bit in the + * line status register. + */ + info->read_status_mask &= ~UART_LSR_DR; + if (info->flags & ASYNC_INITIALIZED) { + /* disable receive interrupts */ + custom.intena = IF_RBF; + mb(); + /* clear any pending receive interrupt */ + custom.intreq = IF_RBF; + mb(); + + /* + * Before we drop DTR, make sure the UART transmitter + * has completely drained; this is especially + * important if there is a transmit FIFO! + */ + rs_wait_until_sent(tty, info->timeout); + } + shutdown(info); + rs_flush_buffer(tty); + + tty_ldisc_flush(tty); + tty->closing = 0; + info->event = 0; + info->tty = NULL; + if (info->blocked_open) { + if (info->close_delay) { + msleep_interruptible(jiffies_to_msecs(info->close_delay)); + } + wake_up_interruptible(&info->open_wait); + } + info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); + wake_up_interruptible(&info->close_wait); + local_irq_restore(flags); +} + +/* + * rs_wait_until_sent() --- wait until the transmitter is empty + */ +static void rs_wait_until_sent(struct tty_struct *tty, int timeout) +{ + struct async_struct * info = tty->driver_data; + unsigned long orig_jiffies, char_time; + int tty_was_locked = tty_locked(); + int lsr; + + if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent")) + return; + + if (info->xmit_fifo_size == 0) + return; /* Just in case.... */ + + orig_jiffies = jiffies; + + /* + * tty_wait_until_sent is called from lots of places, + * with or without the BTM. + */ + if (!tty_was_locked) + tty_lock(); + /* + * Set the check interval to be 1/5 of the estimated time to + * send a single character, and make it at least 1. The check + * interval should also be less than the timeout. + * + * Note: we have to use pretty tight timings here to satisfy + * the NIST-PCTS. + */ + char_time = (info->timeout - HZ/50) / info->xmit_fifo_size; + char_time = char_time / 5; + if (char_time == 0) + char_time = 1; + if (timeout) + char_time = min_t(unsigned long, char_time, timeout); + /* + * If the transmitter hasn't cleared in twice the approximate + * amount of time to send the entire FIFO, it probably won't + * ever clear. This assumes the UART isn't doing flow + * control, which is currently the case. Hence, if it ever + * takes longer than info->timeout, this is probably due to a + * UART bug of some kind. So, we clamp the timeout parameter at + * 2*info->timeout. + */ + if (!timeout || timeout > 2*info->timeout) + timeout = 2*info->timeout; +#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time); + printk("jiff=%lu...", jiffies); +#endif + while(!((lsr = custom.serdatr) & SDR_TSRE)) { +#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + printk("serdatr = %d (jiff=%lu)...", lsr, jiffies); +#endif + msleep_interruptible(jiffies_to_msecs(char_time)); + if (signal_pending(current)) + break; + if (timeout && time_after(jiffies, orig_jiffies + timeout)) + break; + } + __set_current_state(TASK_RUNNING); + if (!tty_was_locked) + tty_unlock(); +#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); +#endif +} + +/* + * rs_hangup() --- called by tty_hangup() when a hangup is signaled. + */ +static void rs_hangup(struct tty_struct *tty) +{ + struct async_struct * info = tty->driver_data; + struct serial_state *state = info->state; + + if (serial_paranoia_check(info, tty->name, "rs_hangup")) + return; + + state = info->state; + + rs_flush_buffer(tty); + shutdown(info); + info->event = 0; + state->count = 0; + info->flags &= ~ASYNC_NORMAL_ACTIVE; + info->tty = NULL; + wake_up_interruptible(&info->open_wait); +} + +/* + * ------------------------------------------------------------ + * rs_open() and friends + * ------------------------------------------------------------ + */ +static int block_til_ready(struct tty_struct *tty, struct file * filp, + struct async_struct *info) +{ +#ifdef DECLARE_WAITQUEUE + DECLARE_WAITQUEUE(wait, current); +#else + struct wait_queue wait = { current, NULL }; +#endif + struct serial_state *state = info->state; + int retval; + int do_clocal = 0, extra_count = 0; + unsigned long flags; + + /* + * If the device is in the middle of being closed, then block + * until it's done, and then try again. + */ + if (tty_hung_up_p(filp) || + (info->flags & ASYNC_CLOSING)) { + if (info->flags & ASYNC_CLOSING) + interruptible_sleep_on(&info->close_wait); +#ifdef SERIAL_DO_RESTART + return ((info->flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS); +#else + return -EAGAIN; +#endif + } + + /* + * If non-blocking mode is set, or the port is not enabled, + * then make the check up front and then exit. + */ + if ((filp->f_flags & O_NONBLOCK) || + (tty->flags & (1 << TTY_IO_ERROR))) { + info->flags |= ASYNC_NORMAL_ACTIVE; + return 0; + } + + if (tty->termios->c_cflag & CLOCAL) + do_clocal = 1; + + /* + * Block waiting for the carrier detect and the line to become + * free (i.e., not in use by the callout). While we are in + * this loop, state->count is dropped by one, so that + * rs_close() knows when to free things. We restore it upon + * exit, either normal or abnormal. + */ + retval = 0; + add_wait_queue(&info->open_wait, &wait); +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready before block: ttys%d, count = %d\n", + state->line, state->count); +#endif + local_irq_save(flags); + if (!tty_hung_up_p(filp)) { + extra_count = 1; + state->count--; + } + local_irq_restore(flags); + info->blocked_open++; + while (1) { + local_irq_save(flags); + if (tty->termios->c_cflag & CBAUD) + rtsdtr_ctrl(SER_DTR|SER_RTS); + local_irq_restore(flags); + set_current_state(TASK_INTERRUPTIBLE); + if (tty_hung_up_p(filp) || + !(info->flags & ASYNC_INITIALIZED)) { +#ifdef SERIAL_DO_RESTART + if (info->flags & ASYNC_HUP_NOTIFY) + retval = -EAGAIN; + else + retval = -ERESTARTSYS; +#else + retval = -EAGAIN; +#endif + break; + } + if (!(info->flags & ASYNC_CLOSING) && + (do_clocal || (!(ciab.pra & SER_DCD)) )) + break; + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready blocking: ttys%d, count = %d\n", + info->line, state->count); +#endif + tty_unlock(); + schedule(); + tty_lock(); + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&info->open_wait, &wait); + if (extra_count) + state->count++; + info->blocked_open--; +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready after blocking: ttys%d, count = %d\n", + info->line, state->count); +#endif + if (retval) + return retval; + info->flags |= ASYNC_NORMAL_ACTIVE; + return 0; +} + +static int get_async_struct(int line, struct async_struct **ret_info) +{ + struct async_struct *info; + struct serial_state *sstate; + + sstate = rs_table + line; + sstate->count++; + if (sstate->info) { + *ret_info = sstate->info; + return 0; + } + info = kzalloc(sizeof(struct async_struct), GFP_KERNEL); + if (!info) { + sstate->count--; + return -ENOMEM; + } +#ifdef DECLARE_WAITQUEUE + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + init_waitqueue_head(&info->delta_msr_wait); +#endif + info->magic = SERIAL_MAGIC; + info->port = sstate->port; + info->flags = sstate->flags; + info->xmit_fifo_size = sstate->xmit_fifo_size; + info->line = line; + tasklet_init(&info->tlet, do_softint, (unsigned long)info); + info->state = sstate; + if (sstate->info) { + kfree(info); + *ret_info = sstate->info; + return 0; + } + *ret_info = sstate->info = info; + return 0; +} + +/* + * This routine is called whenever a serial port is opened. It + * enables interrupts for a serial port, linking in its async structure into + * the IRQ chain. It also performs the serial-specific + * initialization for the tty structure. + */ +static int rs_open(struct tty_struct *tty, struct file * filp) +{ + struct async_struct *info; + int retval, line; + + line = tty->index; + if ((line < 0) || (line >= NR_PORTS)) { + return -ENODEV; + } + retval = get_async_struct(line, &info); + if (retval) { + return retval; + } + tty->driver_data = info; + info->tty = tty; + if (serial_paranoia_check(info, tty->name, "rs_open")) + return -ENODEV; + +#ifdef SERIAL_DEBUG_OPEN + printk("rs_open %s, count = %d\n", tty->name, info->state->count); +#endif + info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; + + /* + * If the port is the middle of closing, bail out now + */ + if (tty_hung_up_p(filp) || + (info->flags & ASYNC_CLOSING)) { + if (info->flags & ASYNC_CLOSING) + interruptible_sleep_on(&info->close_wait); +#ifdef SERIAL_DO_RESTART + return ((info->flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS); +#else + return -EAGAIN; +#endif + } + + /* + * Start up serial port + */ + retval = startup(info); + if (retval) { + return retval; + } + + retval = block_til_ready(tty, filp, info); + if (retval) { +#ifdef SERIAL_DEBUG_OPEN + printk("rs_open returning after block_til_ready with %d\n", + retval); +#endif + return retval; + } + +#ifdef SERIAL_DEBUG_OPEN + printk("rs_open %s successful...", tty->name); +#endif + return 0; +} + +/* + * /proc fs routines.... + */ + +static inline void line_info(struct seq_file *m, struct serial_state *state) +{ + struct async_struct *info = state->info, scr_info; + char stat_buf[30], control, status; + unsigned long flags; + + seq_printf(m, "%d: uart:amiga_builtin",state->line); + + /* + * Figure out the current RS-232 lines + */ + if (!info) { + info = &scr_info; /* This is just for serial_{in,out} */ + + info->magic = SERIAL_MAGIC; + info->flags = state->flags; + info->quot = 0; + info->tty = NULL; + } + local_irq_save(flags); + status = ciab.pra; + control = info ? info->MCR : status; + local_irq_restore(flags); + + stat_buf[0] = 0; + stat_buf[1] = 0; + if(!(control & SER_RTS)) + strcat(stat_buf, "|RTS"); + if(!(status & SER_CTS)) + strcat(stat_buf, "|CTS"); + if(!(control & SER_DTR)) + strcat(stat_buf, "|DTR"); + if(!(status & SER_DSR)) + strcat(stat_buf, "|DSR"); + if(!(status & SER_DCD)) + strcat(stat_buf, "|CD"); + + if (info->quot) { + seq_printf(m, " baud:%d", state->baud_base / info->quot); + } + + seq_printf(m, " tx:%d rx:%d", state->icount.tx, state->icount.rx); + + if (state->icount.frame) + seq_printf(m, " fe:%d", state->icount.frame); + + if (state->icount.parity) + seq_printf(m, " pe:%d", state->icount.parity); + + if (state->icount.brk) + seq_printf(m, " brk:%d", state->icount.brk); + + if (state->icount.overrun) + seq_printf(m, " oe:%d", state->icount.overrun); + + /* + * Last thing is the RS-232 status lines + */ + seq_printf(m, " %s\n", stat_buf+1); +} + +static int rs_proc_show(struct seq_file *m, void *v) +{ + seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version); + line_info(m, &rs_table[0]); + return 0; +} + +static int rs_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, rs_proc_show, NULL); +} + +static const struct file_operations rs_proc_fops = { + .owner = THIS_MODULE, + .open = rs_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* + * --------------------------------------------------------------------- + * rs_init() and friends + * + * rs_init() is called at boot-time to initialize the serial driver. + * --------------------------------------------------------------------- + */ + +/* + * This routine prints out the appropriate serial driver version + * number, and identifies which options were configured into this + * driver. + */ +static void show_serial_version(void) +{ + printk(KERN_INFO "%s version %s\n", serial_name, serial_version); +} + + +static const struct tty_operations serial_ops = { + .open = rs_open, + .close = rs_close, + .write = rs_write, + .put_char = rs_put_char, + .flush_chars = rs_flush_chars, + .write_room = rs_write_room, + .chars_in_buffer = rs_chars_in_buffer, + .flush_buffer = rs_flush_buffer, + .ioctl = rs_ioctl, + .throttle = rs_throttle, + .unthrottle = rs_unthrottle, + .set_termios = rs_set_termios, + .stop = rs_stop, + .start = rs_start, + .hangup = rs_hangup, + .break_ctl = rs_break, + .send_xchar = rs_send_xchar, + .wait_until_sent = rs_wait_until_sent, + .tiocmget = rs_tiocmget, + .tiocmset = rs_tiocmset, + .get_icount = rs_get_icount, + .proc_fops = &rs_proc_fops, +}; + +/* + * The serial driver boot-time initialization code! + */ +static int __init amiga_serial_probe(struct platform_device *pdev) +{ + unsigned long flags; + struct serial_state * state; + int error; + + serial_driver = alloc_tty_driver(1); + if (!serial_driver) + return -ENOMEM; + + IRQ_ports = NULL; + + show_serial_version(); + + /* Initialize the tty_driver structure */ + + serial_driver->owner = THIS_MODULE; + serial_driver->driver_name = "amiserial"; + serial_driver->name = "ttyS"; + serial_driver->major = TTY_MAJOR; + serial_driver->minor_start = 64; + serial_driver->type = TTY_DRIVER_TYPE_SERIAL; + serial_driver->subtype = SERIAL_TYPE_NORMAL; + serial_driver->init_termios = tty_std_termios; + serial_driver->init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + serial_driver->flags = TTY_DRIVER_REAL_RAW; + tty_set_operations(serial_driver, &serial_ops); + + error = tty_register_driver(serial_driver); + if (error) + goto fail_put_tty_driver; + + state = rs_table; + state->magic = SSTATE_MAGIC; + state->port = (int)&custom.serdatr; /* Just to give it a value */ + state->line = 0; + state->custom_divisor = 0; + state->close_delay = 5*HZ/10; + state->closing_wait = 30*HZ; + state->icount.cts = state->icount.dsr = + state->icount.rng = state->icount.dcd = 0; + state->icount.rx = state->icount.tx = 0; + state->icount.frame = state->icount.parity = 0; + state->icount.overrun = state->icount.brk = 0; + + printk(KERN_INFO "ttyS%d is the amiga builtin serial port\n", + state->line); + + /* Hardware set up */ + + state->baud_base = amiga_colorclock; + state->xmit_fifo_size = 1; + + /* set ISRs, and then disable the rx interrupts */ + error = request_irq(IRQ_AMIGA_TBE, ser_tx_int, 0, "serial TX", state); + if (error) + goto fail_unregister; + + error = request_irq(IRQ_AMIGA_RBF, ser_rx_int, IRQF_DISABLED, + "serial RX", state); + if (error) + goto fail_free_irq; + + local_irq_save(flags); + + /* turn off Rx and Tx interrupts */ + custom.intena = IF_RBF | IF_TBE; + mb(); + + /* clear any pending interrupt */ + custom.intreq = IF_RBF | IF_TBE; + mb(); + + local_irq_restore(flags); + + /* + * set the appropriate directions for the modem control flags, + * and clear RTS and DTR + */ + ciab.ddra |= (SER_DTR | SER_RTS); /* outputs */ + ciab.ddra &= ~(SER_DCD | SER_CTS | SER_DSR); /* inputs */ + + platform_set_drvdata(pdev, state); + + return 0; + +fail_free_irq: + free_irq(IRQ_AMIGA_TBE, state); +fail_unregister: + tty_unregister_driver(serial_driver); +fail_put_tty_driver: + put_tty_driver(serial_driver); + return error; +} + +static int __exit amiga_serial_remove(struct platform_device *pdev) +{ + int error; + struct serial_state *state = platform_get_drvdata(pdev); + struct async_struct *info = state->info; + + /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ + tasklet_kill(&info->tlet); + if ((error = tty_unregister_driver(serial_driver))) + printk("SERIAL: failed to unregister serial driver (%d)\n", + error); + put_tty_driver(serial_driver); + + rs_table[0].info = NULL; + kfree(info); + + free_irq(IRQ_AMIGA_TBE, rs_table); + free_irq(IRQ_AMIGA_RBF, rs_table); + + platform_set_drvdata(pdev, NULL); + + return error; +} + +static struct platform_driver amiga_serial_driver = { + .remove = __exit_p(amiga_serial_remove), + .driver = { + .name = "amiga-serial", + .owner = THIS_MODULE, + }, +}; + +static int __init amiga_serial_init(void) +{ + return platform_driver_probe(&amiga_serial_driver, amiga_serial_probe); +} + +module_init(amiga_serial_init); + +static void __exit amiga_serial_exit(void) +{ + platform_driver_unregister(&amiga_serial_driver); +} + +module_exit(amiga_serial_exit); + + +#if defined(CONFIG_SERIAL_CONSOLE) && !defined(MODULE) + +/* + * ------------------------------------------------------------ + * Serial console driver + * ------------------------------------------------------------ + */ + +static void amiga_serial_putc(char c) +{ + custom.serdat = (unsigned char)c | 0x100; + while (!(custom.serdatr & 0x2000)) + barrier(); +} + +/* + * Print a string to the serial port trying not to disturb + * any possible real use of the port... + * + * The console must be locked when we get here. + */ +static void serial_console_write(struct console *co, const char *s, + unsigned count) +{ + unsigned short intena = custom.intenar; + + custom.intena = IF_TBE; + + while (count--) { + if (*s == '\n') + amiga_serial_putc('\r'); + amiga_serial_putc(*s++); + } + + custom.intena = IF_SETCLR | (intena & IF_TBE); +} + +static struct tty_driver *serial_console_device(struct console *c, int *index) +{ + *index = 0; + return serial_driver; +} + +static struct console sercons = { + .name = "ttyS", + .write = serial_console_write, + .device = serial_console_device, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +/* + * Register console. + */ +static int __init amiserial_console_init(void) +{ + register_console(&sercons); + return 0; +} +console_initcall(amiserial_console_init); + +#endif /* CONFIG_SERIAL_CONSOLE && !MODULE */ + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:amiga-serial"); diff --git a/drivers/tty/bfin_jtag_comm.c b/drivers/tty/bfin_jtag_comm.c new file mode 100644 index 000000000000..16402445f2b2 --- /dev/null +++ b/drivers/tty/bfin_jtag_comm.c @@ -0,0 +1,366 @@ +/* + * TTY over Blackfin JTAG Communication + * + * Copyright 2008-2009 Analog Devices Inc. + * + * Enter bugs at http://blackfin.uclinux.org/ + * + * Licensed under the GPL-2 or later. + */ + +#define DRV_NAME "bfin-jtag-comm" +#define DEV_NAME "ttyBFJC" +#define pr_fmt(fmt) DRV_NAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define pr_init(fmt, args...) ({ static const __initconst char __fmt[] = fmt; printk(__fmt, ## args); }) + +/* See the Debug/Emulation chapter in the HRM */ +#define EMUDOF 0x00000001 /* EMUDAT_OUT full & valid */ +#define EMUDIF 0x00000002 /* EMUDAT_IN full & valid */ +#define EMUDOOVF 0x00000004 /* EMUDAT_OUT overflow */ +#define EMUDIOVF 0x00000008 /* EMUDAT_IN overflow */ + +static inline uint32_t bfin_write_emudat(uint32_t emudat) +{ + __asm__ __volatile__("emudat = %0;" : : "d"(emudat)); + return emudat; +} + +static inline uint32_t bfin_read_emudat(void) +{ + uint32_t emudat; + __asm__ __volatile__("%0 = emudat;" : "=d"(emudat)); + return emudat; +} + +static inline uint32_t bfin_write_emudat_chars(char a, char b, char c, char d) +{ + return bfin_write_emudat((a << 0) | (b << 8) | (c << 16) | (d << 24)); +} + +#define CIRC_SIZE 2048 /* see comment in tty_io.c:do_tty_write() */ +#define CIRC_MASK (CIRC_SIZE - 1) +#define circ_empty(circ) ((circ)->head == (circ)->tail) +#define circ_free(circ) CIRC_SPACE((circ)->head, (circ)->tail, CIRC_SIZE) +#define circ_cnt(circ) CIRC_CNT((circ)->head, (circ)->tail, CIRC_SIZE) +#define circ_byte(circ, idx) ((circ)->buf[(idx) & CIRC_MASK]) + +static struct tty_driver *bfin_jc_driver; +static struct task_struct *bfin_jc_kthread; +static struct tty_struct * volatile bfin_jc_tty; +static unsigned long bfin_jc_count; +static DEFINE_MUTEX(bfin_jc_tty_mutex); +static volatile struct circ_buf bfin_jc_write_buf; + +static int +bfin_jc_emudat_manager(void *arg) +{ + uint32_t inbound_len = 0, outbound_len = 0; + + while (!kthread_should_stop()) { + /* no one left to give data to, so sleep */ + if (bfin_jc_tty == NULL && circ_empty(&bfin_jc_write_buf)) { + pr_debug("waiting for readers\n"); + __set_current_state(TASK_UNINTERRUPTIBLE); + schedule(); + __set_current_state(TASK_RUNNING); + } + + /* no data available, so just chill */ + if (!(bfin_read_DBGSTAT() & EMUDIF) && circ_empty(&bfin_jc_write_buf)) { + pr_debug("waiting for data (in_len = %i) (circ: %i %i)\n", + inbound_len, bfin_jc_write_buf.tail, bfin_jc_write_buf.head); + if (inbound_len) + schedule(); + else + schedule_timeout_interruptible(HZ); + continue; + } + + /* if incoming data is ready, eat it */ + if (bfin_read_DBGSTAT() & EMUDIF) { + struct tty_struct *tty; + mutex_lock(&bfin_jc_tty_mutex); + tty = (struct tty_struct *)bfin_jc_tty; + if (tty != NULL) { + uint32_t emudat = bfin_read_emudat(); + if (inbound_len == 0) { + pr_debug("incoming length: 0x%08x\n", emudat); + inbound_len = emudat; + } else { + size_t num_chars = (4 <= inbound_len ? 4 : inbound_len); + pr_debug(" incoming data: 0x%08x (pushing %zu)\n", emudat, num_chars); + inbound_len -= num_chars; + tty_insert_flip_string(tty, (unsigned char *)&emudat, num_chars); + tty_flip_buffer_push(tty); + } + } + mutex_unlock(&bfin_jc_tty_mutex); + } + + /* if outgoing data is ready, post it */ + if (!(bfin_read_DBGSTAT() & EMUDOF) && !circ_empty(&bfin_jc_write_buf)) { + if (outbound_len == 0) { + outbound_len = circ_cnt(&bfin_jc_write_buf); + bfin_write_emudat(outbound_len); + pr_debug("outgoing length: 0x%08x\n", outbound_len); + } else { + struct tty_struct *tty; + int tail = bfin_jc_write_buf.tail; + size_t ate = (4 <= outbound_len ? 4 : outbound_len); + uint32_t emudat = + bfin_write_emudat_chars( + circ_byte(&bfin_jc_write_buf, tail + 0), + circ_byte(&bfin_jc_write_buf, tail + 1), + circ_byte(&bfin_jc_write_buf, tail + 2), + circ_byte(&bfin_jc_write_buf, tail + 3) + ); + bfin_jc_write_buf.tail += ate; + outbound_len -= ate; + mutex_lock(&bfin_jc_tty_mutex); + tty = (struct tty_struct *)bfin_jc_tty; + if (tty) + tty_wakeup(tty); + mutex_unlock(&bfin_jc_tty_mutex); + pr_debug(" outgoing data: 0x%08x (pushing %zu)\n", emudat, ate); + } + } + } + + __set_current_state(TASK_RUNNING); + return 0; +} + +static int +bfin_jc_open(struct tty_struct *tty, struct file *filp) +{ + mutex_lock(&bfin_jc_tty_mutex); + pr_debug("open %lu\n", bfin_jc_count); + ++bfin_jc_count; + bfin_jc_tty = tty; + wake_up_process(bfin_jc_kthread); + mutex_unlock(&bfin_jc_tty_mutex); + return 0; +} + +static void +bfin_jc_close(struct tty_struct *tty, struct file *filp) +{ + mutex_lock(&bfin_jc_tty_mutex); + pr_debug("close %lu\n", bfin_jc_count); + if (--bfin_jc_count == 0) + bfin_jc_tty = NULL; + wake_up_process(bfin_jc_kthread); + mutex_unlock(&bfin_jc_tty_mutex); +} + +/* XXX: we dont handle the put_char() case where we must handle count = 1 */ +static int +bfin_jc_circ_write(const unsigned char *buf, int count) +{ + int i; + count = min(count, circ_free(&bfin_jc_write_buf)); + pr_debug("going to write chunk of %i bytes\n", count); + for (i = 0; i < count; ++i) + circ_byte(&bfin_jc_write_buf, bfin_jc_write_buf.head + i) = buf[i]; + bfin_jc_write_buf.head += i; + return i; +} + +#ifndef CONFIG_BFIN_JTAG_COMM_CONSOLE +# define console_lock() +# define console_unlock() +#endif +static int +bfin_jc_write(struct tty_struct *tty, const unsigned char *buf, int count) +{ + int i; + console_lock(); + i = bfin_jc_circ_write(buf, count); + console_unlock(); + wake_up_process(bfin_jc_kthread); + return i; +} + +static void +bfin_jc_flush_chars(struct tty_struct *tty) +{ + wake_up_process(bfin_jc_kthread); +} + +static int +bfin_jc_write_room(struct tty_struct *tty) +{ + return circ_free(&bfin_jc_write_buf); +} + +static int +bfin_jc_chars_in_buffer(struct tty_struct *tty) +{ + return circ_cnt(&bfin_jc_write_buf); +} + +static void +bfin_jc_wait_until_sent(struct tty_struct *tty, int timeout) +{ + unsigned long expire = jiffies + timeout; + while (!circ_empty(&bfin_jc_write_buf)) { + if (signal_pending(current)) + break; + if (time_after(jiffies, expire)) + break; + } +} + +static const struct tty_operations bfin_jc_ops = { + .open = bfin_jc_open, + .close = bfin_jc_close, + .write = bfin_jc_write, + /*.put_char = bfin_jc_put_char,*/ + .flush_chars = bfin_jc_flush_chars, + .write_room = bfin_jc_write_room, + .chars_in_buffer = bfin_jc_chars_in_buffer, + .wait_until_sent = bfin_jc_wait_until_sent, +}; + +static int __init bfin_jc_init(void) +{ + int ret; + + bfin_jc_kthread = kthread_create(bfin_jc_emudat_manager, NULL, DRV_NAME); + if (IS_ERR(bfin_jc_kthread)) + return PTR_ERR(bfin_jc_kthread); + + ret = -ENOMEM; + + bfin_jc_write_buf.head = bfin_jc_write_buf.tail = 0; + bfin_jc_write_buf.buf = kmalloc(CIRC_SIZE, GFP_KERNEL); + if (!bfin_jc_write_buf.buf) + goto err; + + bfin_jc_driver = alloc_tty_driver(1); + if (!bfin_jc_driver) + goto err; + + bfin_jc_driver->owner = THIS_MODULE; + bfin_jc_driver->driver_name = DRV_NAME; + bfin_jc_driver->name = DEV_NAME; + bfin_jc_driver->type = TTY_DRIVER_TYPE_SERIAL; + bfin_jc_driver->subtype = SERIAL_TYPE_NORMAL; + bfin_jc_driver->init_termios = tty_std_termios; + tty_set_operations(bfin_jc_driver, &bfin_jc_ops); + + ret = tty_register_driver(bfin_jc_driver); + if (ret) + goto err; + + pr_init(KERN_INFO DRV_NAME ": initialized\n"); + + return 0; + + err: + put_tty_driver(bfin_jc_driver); + kfree(bfin_jc_write_buf.buf); + kthread_stop(bfin_jc_kthread); + return ret; +} +module_init(bfin_jc_init); + +static void __exit bfin_jc_exit(void) +{ + kthread_stop(bfin_jc_kthread); + kfree(bfin_jc_write_buf.buf); + tty_unregister_driver(bfin_jc_driver); + put_tty_driver(bfin_jc_driver); +} +module_exit(bfin_jc_exit); + +#if defined(CONFIG_BFIN_JTAG_COMM_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +static void +bfin_jc_straight_buffer_write(const char *buf, unsigned count) +{ + unsigned ate = 0; + while (bfin_read_DBGSTAT() & EMUDOF) + continue; + bfin_write_emudat(count); + while (ate < count) { + while (bfin_read_DBGSTAT() & EMUDOF) + continue; + bfin_write_emudat_chars(buf[ate], buf[ate+1], buf[ate+2], buf[ate+3]); + ate += 4; + } +} +#endif + +#ifdef CONFIG_BFIN_JTAG_COMM_CONSOLE +static void +bfin_jc_console_write(struct console *co, const char *buf, unsigned count) +{ + if (bfin_jc_kthread == NULL) + bfin_jc_straight_buffer_write(buf, count); + else + bfin_jc_circ_write(buf, count); +} + +static struct tty_driver * +bfin_jc_console_device(struct console *co, int *index) +{ + *index = co->index; + return bfin_jc_driver; +} + +static struct console bfin_jc_console = { + .name = DEV_NAME, + .write = bfin_jc_console_write, + .device = bfin_jc_console_device, + .flags = CON_ANYTIME | CON_PRINTBUFFER, + .index = -1, +}; + +static int __init bfin_jc_console_init(void) +{ + register_console(&bfin_jc_console); + return 0; +} +console_initcall(bfin_jc_console_init); +#endif + +#ifdef CONFIG_EARLY_PRINTK +static void __init +bfin_jc_early_write(struct console *co, const char *buf, unsigned int count) +{ + bfin_jc_straight_buffer_write(buf, count); +} + +static struct __initdata console bfin_jc_early_console = { + .name = "early_BFJC", + .write = bfin_jc_early_write, + .flags = CON_ANYTIME | CON_PRINTBUFFER, + .index = -1, +}; + +struct console * __init +bfin_jc_early_init(unsigned int port, unsigned int cflag) +{ + return &bfin_jc_early_console; +} +#endif + +MODULE_AUTHOR("Mike Frysinger "); +MODULE_DESCRIPTION("TTY over Blackfin JTAG Communication"); +MODULE_LICENSE("GPL"); diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c new file mode 100644 index 000000000000..c99728f0cd9f --- /dev/null +++ b/drivers/tty/cyclades.c @@ -0,0 +1,4200 @@ +#undef BLOCKMOVE +#define Z_WAKE +#undef Z_EXT_CHARS_IN_BUFFER + +/* + * linux/drivers/char/cyclades.c + * + * This file contains the driver for the Cyclades async multiport + * serial boards. + * + * Initially written by Randolph Bentson . + * Modified and maintained by Marcio Saito . + * + * Copyright (C) 2007-2009 Jiri Slaby + * + * Much of the design and some of the code came from serial.c + * which was copyright (C) 1991, 1992 Linus Torvalds. It was + * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92, + * and then fixed as suggested by Michael K. Johnson 12/12/92. + * Converted to pci probing and cleaned up by Jiri Slaby. + * + */ + +#define CY_VERSION "2.6" + +/* If you need to install more boards than NR_CARDS, change the constant + in the definition below. No other change is necessary to support up to + eight boards. Beyond that you'll have to extend cy_isa_addresses. */ + +#define NR_CARDS 4 + +/* + If the total number of ports is larger than NR_PORTS, change this + constant in the definition below. No other change is necessary to + support more boards/ports. */ + +#define NR_PORTS 256 + +#define ZO_V1 0 +#define ZO_V2 1 +#define ZE_V1 2 + +#define SERIAL_PARANOIA_CHECK +#undef CY_DEBUG_OPEN +#undef CY_DEBUG_THROTTLE +#undef CY_DEBUG_OTHER +#undef CY_DEBUG_IO +#undef CY_DEBUG_COUNT +#undef CY_DEBUG_DTR +#undef CY_DEBUG_WAIT_UNTIL_SENT +#undef CY_DEBUG_INTERRUPTS +#undef CY_16Y_HACK +#undef CY_ENABLE_MONITORING +#undef CY_PCI_DEBUG + +/* + * Include section + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + +static void cy_send_xchar(struct tty_struct *tty, char ch); + +#ifndef SERIAL_XMIT_SIZE +#define SERIAL_XMIT_SIZE (min(PAGE_SIZE, 4096)) +#endif + +#define STD_COM_FLAGS (0) + +/* firmware stuff */ +#define ZL_MAX_BLOCKS 16 +#define DRIVER_VERSION 0x02010203 +#define RAM_SIZE 0x80000 + +enum zblock_type { + ZBLOCK_PRG = 0, + ZBLOCK_FPGA = 1 +}; + +struct zfile_header { + char name[64]; + char date[32]; + char aux[32]; + u32 n_config; + u32 config_offset; + u32 n_blocks; + u32 block_offset; + u32 reserved[9]; +} __attribute__ ((packed)); + +struct zfile_config { + char name[64]; + u32 mailbox; + u32 function; + u32 n_blocks; + u32 block_list[ZL_MAX_BLOCKS]; +} __attribute__ ((packed)); + +struct zfile_block { + u32 type; + u32 file_offset; + u32 ram_offset; + u32 size; +} __attribute__ ((packed)); + +static struct tty_driver *cy_serial_driver; + +#ifdef CONFIG_ISA +/* This is the address lookup table. The driver will probe for + Cyclom-Y/ISA boards at all addresses in here. If you want the + driver to probe addresses at a different address, add it to + this table. If the driver is probing some other board and + causing problems, remove the offending address from this table. +*/ + +static unsigned int cy_isa_addresses[] = { + 0xD0000, + 0xD2000, + 0xD4000, + 0xD6000, + 0xD8000, + 0xDA000, + 0xDC000, + 0xDE000, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +#define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses) + +static long maddr[NR_CARDS]; +static int irq[NR_CARDS]; + +module_param_array(maddr, long, NULL, 0); +module_param_array(irq, int, NULL, 0); + +#endif /* CONFIG_ISA */ + +/* This is the per-card data structure containing address, irq, number of + channels, etc. This driver supports a maximum of NR_CARDS cards. +*/ +static struct cyclades_card cy_card[NR_CARDS]; + +static int cy_next_channel; /* next minor available */ + +/* + * This is used to look up the divisor speeds and the timeouts + * We're normally limited to 15 distinct baud rates. The extra + * are accessed via settings in info->port.flags. + * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + * 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + * HI VHI + * 20 + */ +static const int baud_table[] = { + 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, + 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200, 150000, + 230400, 0 +}; + +static const char baud_co_25[] = { /* 25 MHz clock option table */ + /* value => 00 01 02 03 04 */ + /* divide by 8 32 128 512 2048 */ + 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, + 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const char baud_bpr_25[] = { /* 25 MHz baud rate period table */ + 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3, + 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15 +}; + +static const char baud_co_60[] = { /* 60 MHz clock option table (CD1400 J) */ + /* value => 00 01 02 03 04 */ + /* divide by 8 32 128 512 2048 */ + 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, + 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +static const char baud_bpr_60[] = { /* 60 MHz baud rate period table (CD1400 J) */ + 0x00, 0x82, 0x21, 0xff, 0xdb, 0xc3, 0x92, 0x62, 0xc3, 0x62, + 0x41, 0xc3, 0x62, 0xc3, 0x62, 0xc3, 0x82, 0x62, 0x41, 0x32, + 0x21 +}; + +static const char baud_cor3[] = { /* receive threshold */ + 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, + 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07, + 0x07 +}; + +/* + * The Cyclades driver implements HW flow control as any serial driver. + * The cyclades_port structure member rflow and the vector rflow_thr + * allows us to take advantage of a special feature in the CD1400 to avoid + * data loss even when the system interrupt latency is too high. These flags + * are to be used only with very special applications. Setting these flags + * requires the use of a special cable (DTR and RTS reversed). In the new + * CD1400-based boards (rev. 6.00 or later), there is no need for special + * cables. + */ + +static const char rflow_thr[] = { /* rflow threshold */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, + 0x0a +}; + +/* The Cyclom-Ye has placed the sequential chips in non-sequential + * address order. This look-up table overcomes that problem. + */ +static const unsigned int cy_chip_offset[] = { 0x0000, + 0x0400, + 0x0800, + 0x0C00, + 0x0200, + 0x0600, + 0x0A00, + 0x0E00 +}; + +/* PCI related definitions */ + +#ifdef CONFIG_PCI +static const struct pci_device_id cy_pci_dev_id[] = { + /* PCI < 1Mb */ + { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) }, + /* PCI > 1Mb */ + { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Hi) }, + /* 4Y PCI < 1Mb */ + { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Lo) }, + /* 4Y PCI > 1Mb */ + { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Hi) }, + /* 8Y PCI < 1Mb */ + { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Lo) }, + /* 8Y PCI > 1Mb */ + { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Hi) }, + /* Z PCI < 1Mb */ + { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Lo) }, + /* Z PCI > 1Mb */ + { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Hi) }, + { } /* end of table */ +}; +MODULE_DEVICE_TABLE(pci, cy_pci_dev_id); +#endif + +static void cy_start(struct tty_struct *); +static void cy_set_line_char(struct cyclades_port *, struct tty_struct *); +static int cyz_issue_cmd(struct cyclades_card *, __u32, __u8, __u32); +#ifdef CONFIG_ISA +static unsigned detect_isa_irq(void __iomem *); +#endif /* CONFIG_ISA */ + +#ifndef CONFIG_CYZ_INTR +static void cyz_poll(unsigned long); + +/* The Cyclades-Z polling cycle is defined by this variable */ +static long cyz_polling_cycle = CZ_DEF_POLL; + +static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0); + +#else /* CONFIG_CYZ_INTR */ +static void cyz_rx_restart(unsigned long); +static struct timer_list cyz_rx_full_timer[NR_PORTS]; +#endif /* CONFIG_CYZ_INTR */ + +static inline void cyy_writeb(struct cyclades_port *port, u32 reg, u8 val) +{ + struct cyclades_card *card = port->card; + + cy_writeb(port->u.cyy.base_addr + (reg << card->bus_index), val); +} + +static inline u8 cyy_readb(struct cyclades_port *port, u32 reg) +{ + struct cyclades_card *card = port->card; + + return readb(port->u.cyy.base_addr + (reg << card->bus_index)); +} + +static inline bool cy_is_Z(struct cyclades_card *card) +{ + return card->num_chips == (unsigned int)-1; +} + +static inline bool __cyz_fpga_loaded(struct RUNTIME_9060 __iomem *ctl_addr) +{ + return readl(&ctl_addr->init_ctrl) & (1 << 17); +} + +static inline bool cyz_fpga_loaded(struct cyclades_card *card) +{ + return __cyz_fpga_loaded(card->ctl_addr.p9060); +} + +static inline bool cyz_is_loaded(struct cyclades_card *card) +{ + struct FIRM_ID __iomem *fw_id = card->base_addr + ID_ADDRESS; + + return (card->hw_ver == ZO_V1 || cyz_fpga_loaded(card)) && + readl(&fw_id->signature) == ZFIRM_ID; +} + +static inline int serial_paranoia_check(struct cyclades_port *info, + const char *name, const char *routine) +{ +#ifdef SERIAL_PARANOIA_CHECK + if (!info) { + printk(KERN_WARNING "cyc Warning: null cyclades_port for (%s) " + "in %s\n", name, routine); + return 1; + } + + if (info->magic != CYCLADES_MAGIC) { + printk(KERN_WARNING "cyc Warning: bad magic number for serial " + "struct (%s) in %s\n", name, routine); + return 1; + } +#endif + return 0; +} + +/***********************************************************/ +/********* Start of block of Cyclom-Y specific code ********/ + +/* This routine waits up to 1000 micro-seconds for the previous + command to the Cirrus chip to complete and then issues the + new command. An error is returned if the previous command + didn't finish within the time limit. + + This function is only called from inside spinlock-protected code. + */ +static int __cyy_issue_cmd(void __iomem *base_addr, u8 cmd, int index) +{ + void __iomem *ccr = base_addr + (CyCCR << index); + unsigned int i; + + /* Check to see that the previous command has completed */ + for (i = 0; i < 100; i++) { + if (readb(ccr) == 0) + break; + udelay(10L); + } + /* if the CCR never cleared, the previous command + didn't finish within the "reasonable time" */ + if (i == 100) + return -1; + + /* Issue the new command */ + cy_writeb(ccr, cmd); + + return 0; +} + +static inline int cyy_issue_cmd(struct cyclades_port *port, u8 cmd) +{ + return __cyy_issue_cmd(port->u.cyy.base_addr, cmd, + port->card->bus_index); +} + +#ifdef CONFIG_ISA +/* ISA interrupt detection code */ +static unsigned detect_isa_irq(void __iomem *address) +{ + int irq; + unsigned long irqs, flags; + int save_xir, save_car; + int index = 0; /* IRQ probing is only for ISA */ + + /* forget possible initially masked and pending IRQ */ + irq = probe_irq_off(probe_irq_on()); + + /* Clear interrupts on the board first */ + cy_writeb(address + (Cy_ClrIntr << index), 0); + /* Cy_ClrIntr is 0x1800 */ + + irqs = probe_irq_on(); + /* Wait ... */ + msleep(5); + + /* Enable the Tx interrupts on the CD1400 */ + local_irq_save(flags); + cy_writeb(address + (CyCAR << index), 0); + __cyy_issue_cmd(address, CyCHAN_CTL | CyENB_XMTR, index); + + cy_writeb(address + (CyCAR << index), 0); + cy_writeb(address + (CySRER << index), + readb(address + (CySRER << index)) | CyTxRdy); + local_irq_restore(flags); + + /* Wait ... */ + msleep(5); + + /* Check which interrupt is in use */ + irq = probe_irq_off(irqs); + + /* Clean up */ + save_xir = (u_char) readb(address + (CyTIR << index)); + save_car = readb(address + (CyCAR << index)); + cy_writeb(address + (CyCAR << index), (save_xir & 0x3)); + cy_writeb(address + (CySRER << index), + readb(address + (CySRER << index)) & ~CyTxRdy); + cy_writeb(address + (CyTIR << index), (save_xir & 0x3f)); + cy_writeb(address + (CyCAR << index), (save_car)); + cy_writeb(address + (Cy_ClrIntr << index), 0); + /* Cy_ClrIntr is 0x1800 */ + + return (irq > 0) ? irq : 0; +} +#endif /* CONFIG_ISA */ + +static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, + void __iomem *base_addr) +{ + struct cyclades_port *info; + struct tty_struct *tty; + int len, index = cinfo->bus_index; + u8 ivr, save_xir, channel, save_car, data, char_count; + +#ifdef CY_DEBUG_INTERRUPTS + printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip); +#endif + /* determine the channel & change to that context */ + save_xir = readb(base_addr + (CyRIR << index)); + channel = save_xir & CyIRChannel; + info = &cinfo->ports[channel + chip * 4]; + save_car = cyy_readb(info, CyCAR); + cyy_writeb(info, CyCAR, save_xir); + ivr = cyy_readb(info, CyRIVR) & CyIVRMask; + + tty = tty_port_tty_get(&info->port); + /* if there is nowhere to put the data, discard it */ + if (tty == NULL) { + if (ivr == CyIVRRxEx) { /* exception */ + data = cyy_readb(info, CyRDSR); + } else { /* normal character reception */ + char_count = cyy_readb(info, CyRDCR); + while (char_count--) + data = cyy_readb(info, CyRDSR); + } + goto end; + } + /* there is an open port for this data */ + if (ivr == CyIVRRxEx) { /* exception */ + data = cyy_readb(info, CyRDSR); + + /* For statistics only */ + if (data & CyBREAK) + info->icount.brk++; + else if (data & CyFRAME) + info->icount.frame++; + else if (data & CyPARITY) + info->icount.parity++; + else if (data & CyOVERRUN) + info->icount.overrun++; + + if (data & info->ignore_status_mask) { + info->icount.rx++; + tty_kref_put(tty); + return; + } + if (tty_buffer_request_room(tty, 1)) { + if (data & info->read_status_mask) { + if (data & CyBREAK) { + tty_insert_flip_char(tty, + cyy_readb(info, CyRDSR), + TTY_BREAK); + info->icount.rx++; + if (info->port.flags & ASYNC_SAK) + do_SAK(tty); + } else if (data & CyFRAME) { + tty_insert_flip_char(tty, + cyy_readb(info, CyRDSR), + TTY_FRAME); + info->icount.rx++; + info->idle_stats.frame_errs++; + } else if (data & CyPARITY) { + /* Pieces of seven... */ + tty_insert_flip_char(tty, + cyy_readb(info, CyRDSR), + TTY_PARITY); + info->icount.rx++; + info->idle_stats.parity_errs++; + } else if (data & CyOVERRUN) { + tty_insert_flip_char(tty, 0, + TTY_OVERRUN); + info->icount.rx++; + /* If the flip buffer itself is + overflowing, we still lose + the next incoming character. + */ + tty_insert_flip_char(tty, + cyy_readb(info, CyRDSR), + TTY_FRAME); + info->icount.rx++; + info->idle_stats.overruns++; + /* These two conditions may imply */ + /* a normal read should be done. */ + /* } else if(data & CyTIMEOUT) { */ + /* } else if(data & CySPECHAR) { */ + } else { + tty_insert_flip_char(tty, 0, + TTY_NORMAL); + info->icount.rx++; + } + } else { + tty_insert_flip_char(tty, 0, TTY_NORMAL); + info->icount.rx++; + } + } else { + /* there was a software buffer overrun and nothing + * could be done about it!!! */ + info->icount.buf_overrun++; + info->idle_stats.overruns++; + } + } else { /* normal character reception */ + /* load # chars available from the chip */ + char_count = cyy_readb(info, CyRDCR); + +#ifdef CY_ENABLE_MONITORING + ++info->mon.int_count; + info->mon.char_count += char_count; + if (char_count > info->mon.char_max) + info->mon.char_max = char_count; + info->mon.char_last = char_count; +#endif + len = tty_buffer_request_room(tty, char_count); + while (len--) { + data = cyy_readb(info, CyRDSR); + tty_insert_flip_char(tty, data, TTY_NORMAL); + info->idle_stats.recv_bytes++; + info->icount.rx++; +#ifdef CY_16Y_HACK + udelay(10L); +#endif + } + info->idle_stats.recv_idle = jiffies; + } + tty_schedule_flip(tty); + tty_kref_put(tty); +end: + /* end of service */ + cyy_writeb(info, CyRIR, save_xir & 0x3f); + cyy_writeb(info, CyCAR, save_car); +} + +static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip, + void __iomem *base_addr) +{ + struct cyclades_port *info; + struct tty_struct *tty; + int char_count, index = cinfo->bus_index; + u8 save_xir, channel, save_car, outch; + + /* Since we only get here when the transmit buffer + is empty, we know we can always stuff a dozen + characters. */ +#ifdef CY_DEBUG_INTERRUPTS + printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip); +#endif + + /* determine the channel & change to that context */ + save_xir = readb(base_addr + (CyTIR << index)); + channel = save_xir & CyIRChannel; + save_car = readb(base_addr + (CyCAR << index)); + cy_writeb(base_addr + (CyCAR << index), save_xir); + + info = &cinfo->ports[channel + chip * 4]; + tty = tty_port_tty_get(&info->port); + if (tty == NULL) { + cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyTxRdy); + goto end; + } + + /* load the on-chip space for outbound data */ + char_count = info->xmit_fifo_size; + + if (info->x_char) { /* send special char */ + outch = info->x_char; + cyy_writeb(info, CyTDR, outch); + char_count--; + info->icount.tx++; + info->x_char = 0; + } + + if (info->breakon || info->breakoff) { + if (info->breakon) { + cyy_writeb(info, CyTDR, 0); + cyy_writeb(info, CyTDR, 0x81); + info->breakon = 0; + char_count -= 2; + } + if (info->breakoff) { + cyy_writeb(info, CyTDR, 0); + cyy_writeb(info, CyTDR, 0x83); + info->breakoff = 0; + char_count -= 2; + } + } + + while (char_count-- > 0) { + if (!info->xmit_cnt) { + if (cyy_readb(info, CySRER) & CyTxMpty) { + cyy_writeb(info, CySRER, + cyy_readb(info, CySRER) & ~CyTxMpty); + } else { + cyy_writeb(info, CySRER, CyTxMpty | + (cyy_readb(info, CySRER) & ~CyTxRdy)); + } + goto done; + } + if (info->port.xmit_buf == NULL) { + cyy_writeb(info, CySRER, + cyy_readb(info, CySRER) & ~CyTxRdy); + goto done; + } + if (tty->stopped || tty->hw_stopped) { + cyy_writeb(info, CySRER, + cyy_readb(info, CySRER) & ~CyTxRdy); + goto done; + } + /* Because the Embedded Transmit Commands have been enabled, + * we must check to see if the escape character, NULL, is being + * sent. If it is, we must ensure that there is room for it to + * be doubled in the output stream. Therefore we no longer + * advance the pointer when the character is fetched, but + * rather wait until after the check for a NULL output + * character. This is necessary because there may not be room + * for the two chars needed to send a NULL.) + */ + outch = info->port.xmit_buf[info->xmit_tail]; + if (outch) { + info->xmit_cnt--; + info->xmit_tail = (info->xmit_tail + 1) & + (SERIAL_XMIT_SIZE - 1); + cyy_writeb(info, CyTDR, outch); + info->icount.tx++; + } else { + if (char_count > 1) { + info->xmit_cnt--; + info->xmit_tail = (info->xmit_tail + 1) & + (SERIAL_XMIT_SIZE - 1); + cyy_writeb(info, CyTDR, outch); + cyy_writeb(info, CyTDR, 0); + info->icount.tx++; + char_count--; + } + } + } + +done: + tty_wakeup(tty); + tty_kref_put(tty); +end: + /* end of service */ + cyy_writeb(info, CyTIR, save_xir & 0x3f); + cyy_writeb(info, CyCAR, save_car); +} + +static void cyy_chip_modem(struct cyclades_card *cinfo, int chip, + void __iomem *base_addr) +{ + struct cyclades_port *info; + struct tty_struct *tty; + int index = cinfo->bus_index; + u8 save_xir, channel, save_car, mdm_change, mdm_status; + + /* determine the channel & change to that context */ + save_xir = readb(base_addr + (CyMIR << index)); + channel = save_xir & CyIRChannel; + info = &cinfo->ports[channel + chip * 4]; + save_car = cyy_readb(info, CyCAR); + cyy_writeb(info, CyCAR, save_xir); + + mdm_change = cyy_readb(info, CyMISR); + mdm_status = cyy_readb(info, CyMSVR1); + + tty = tty_port_tty_get(&info->port); + if (!tty) + goto end; + + if (mdm_change & CyANY_DELTA) { + /* For statistics only */ + if (mdm_change & CyDCD) + info->icount.dcd++; + if (mdm_change & CyCTS) + info->icount.cts++; + if (mdm_change & CyDSR) + info->icount.dsr++; + if (mdm_change & CyRI) + info->icount.rng++; + + wake_up_interruptible(&info->port.delta_msr_wait); + } + + if ((mdm_change & CyDCD) && (info->port.flags & ASYNC_CHECK_CD)) { + if (mdm_status & CyDCD) + wake_up_interruptible(&info->port.open_wait); + else + tty_hangup(tty); + } + if ((mdm_change & CyCTS) && (info->port.flags & ASYNC_CTS_FLOW)) { + if (tty->hw_stopped) { + if (mdm_status & CyCTS) { + /* cy_start isn't used + because... !!! */ + tty->hw_stopped = 0; + cyy_writeb(info, CySRER, + cyy_readb(info, CySRER) | CyTxRdy); + tty_wakeup(tty); + } + } else { + if (!(mdm_status & CyCTS)) { + /* cy_stop isn't used + because ... !!! */ + tty->hw_stopped = 1; + cyy_writeb(info, CySRER, + cyy_readb(info, CySRER) & ~CyTxRdy); + } + } + } +/* if (mdm_change & CyDSR) { + } + if (mdm_change & CyRI) { + }*/ + tty_kref_put(tty); +end: + /* end of service */ + cyy_writeb(info, CyMIR, save_xir & 0x3f); + cyy_writeb(info, CyCAR, save_car); +} + +/* The real interrupt service routine is called + whenever the card wants its hand held--chars + received, out buffer empty, modem change, etc. + */ +static irqreturn_t cyy_interrupt(int irq, void *dev_id) +{ + int status; + struct cyclades_card *cinfo = dev_id; + void __iomem *base_addr, *card_base_addr; + unsigned int chip, too_many, had_work; + int index; + + if (unlikely(cinfo == NULL)) { +#ifdef CY_DEBUG_INTERRUPTS + printk(KERN_DEBUG "cyy_interrupt: spurious interrupt %d\n", + irq); +#endif + return IRQ_NONE; /* spurious interrupt */ + } + + card_base_addr = cinfo->base_addr; + index = cinfo->bus_index; + + /* card was not initialized yet (e.g. DEBUG_SHIRQ) */ + if (unlikely(card_base_addr == NULL)) + return IRQ_HANDLED; + + /* This loop checks all chips in the card. Make a note whenever + _any_ chip had some work to do, as this is considered an + indication that there will be more to do. Only when no chip + has any work does this outermost loop exit. + */ + do { + had_work = 0; + for (chip = 0; chip < cinfo->num_chips; chip++) { + base_addr = cinfo->base_addr + + (cy_chip_offset[chip] << index); + too_many = 0; + while ((status = readb(base_addr + + (CySVRR << index))) != 0x00) { + had_work++; + /* The purpose of the following test is to ensure that + no chip can monopolize the driver. This forces the + chips to be checked in a round-robin fashion (after + draining each of a bunch (1000) of characters). + */ + if (1000 < too_many++) + break; + spin_lock(&cinfo->card_lock); + if (status & CySRReceive) /* rx intr */ + cyy_chip_rx(cinfo, chip, base_addr); + if (status & CySRTransmit) /* tx intr */ + cyy_chip_tx(cinfo, chip, base_addr); + if (status & CySRModem) /* modem intr */ + cyy_chip_modem(cinfo, chip, base_addr); + spin_unlock(&cinfo->card_lock); + } + } + } while (had_work); + + /* clear interrupts */ + spin_lock(&cinfo->card_lock); + cy_writeb(card_base_addr + (Cy_ClrIntr << index), 0); + /* Cy_ClrIntr is 0x1800 */ + spin_unlock(&cinfo->card_lock); + return IRQ_HANDLED; +} /* cyy_interrupt */ + +static void cyy_change_rts_dtr(struct cyclades_port *info, unsigned int set, + unsigned int clear) +{ + struct cyclades_card *card = info->card; + int channel = info->line - card->first_line; + u32 rts, dtr, msvrr, msvrd; + + channel &= 0x03; + + if (info->rtsdtr_inv) { + msvrr = CyMSVR2; + msvrd = CyMSVR1; + rts = CyDTR; + dtr = CyRTS; + } else { + msvrr = CyMSVR1; + msvrd = CyMSVR2; + rts = CyRTS; + dtr = CyDTR; + } + if (set & TIOCM_RTS) { + cyy_writeb(info, CyCAR, channel); + cyy_writeb(info, msvrr, rts); + } + if (clear & TIOCM_RTS) { + cyy_writeb(info, CyCAR, channel); + cyy_writeb(info, msvrr, ~rts); + } + if (set & TIOCM_DTR) { + cyy_writeb(info, CyCAR, channel); + cyy_writeb(info, msvrd, dtr); +#ifdef CY_DEBUG_DTR + printk(KERN_DEBUG "cyc:set_modem_info raising DTR\n"); + printk(KERN_DEBUG " status: 0x%x, 0x%x\n", + cyy_readb(info, CyMSVR1), + cyy_readb(info, CyMSVR2)); +#endif + } + if (clear & TIOCM_DTR) { + cyy_writeb(info, CyCAR, channel); + cyy_writeb(info, msvrd, ~dtr); +#ifdef CY_DEBUG_DTR + printk(KERN_DEBUG "cyc:set_modem_info dropping DTR\n"); + printk(KERN_DEBUG " status: 0x%x, 0x%x\n", + cyy_readb(info, CyMSVR1), + cyy_readb(info, CyMSVR2)); +#endif + } +} + +/***********************************************************/ +/********* End of block of Cyclom-Y specific code **********/ +/******** Start of block of Cyclades-Z specific code *******/ +/***********************************************************/ + +static int +cyz_fetch_msg(struct cyclades_card *cinfo, + __u32 *channel, __u8 *cmd, __u32 *param) +{ + struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl; + unsigned long loc_doorbell; + + loc_doorbell = readl(&cinfo->ctl_addr.p9060->loc_doorbell); + if (loc_doorbell) { + *cmd = (char)(0xff & loc_doorbell); + *channel = readl(&board_ctrl->fwcmd_channel); + *param = (__u32) readl(&board_ctrl->fwcmd_param); + cy_writel(&cinfo->ctl_addr.p9060->loc_doorbell, 0xffffffff); + return 1; + } + return 0; +} /* cyz_fetch_msg */ + +static int +cyz_issue_cmd(struct cyclades_card *cinfo, + __u32 channel, __u8 cmd, __u32 param) +{ + struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl; + __u32 __iomem *pci_doorbell; + unsigned int index; + + if (!cyz_is_loaded(cinfo)) + return -1; + + index = 0; + pci_doorbell = &cinfo->ctl_addr.p9060->pci_doorbell; + while ((readl(pci_doorbell) & 0xff) != 0) { + if (index++ == 1000) + return (int)(readl(pci_doorbell) & 0xff); + udelay(50L); + } + cy_writel(&board_ctrl->hcmd_channel, channel); + cy_writel(&board_ctrl->hcmd_param, param); + cy_writel(pci_doorbell, (long)cmd); + + return 0; +} /* cyz_issue_cmd */ + +static void cyz_handle_rx(struct cyclades_port *info, struct tty_struct *tty) +{ + struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl; + struct cyclades_card *cinfo = info->card; + unsigned int char_count; + int len; +#ifdef BLOCKMOVE + unsigned char *buf; +#else + char data; +#endif + __u32 rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr; + + rx_get = new_rx_get = readl(&buf_ctrl->rx_get); + rx_put = readl(&buf_ctrl->rx_put); + rx_bufsize = readl(&buf_ctrl->rx_bufsize); + rx_bufaddr = readl(&buf_ctrl->rx_bufaddr); + if (rx_put >= rx_get) + char_count = rx_put - rx_get; + else + char_count = rx_put - rx_get + rx_bufsize; + + if (char_count) { +#ifdef CY_ENABLE_MONITORING + info->mon.int_count++; + info->mon.char_count += char_count; + if (char_count > info->mon.char_max) + info->mon.char_max = char_count; + info->mon.char_last = char_count; +#endif + if (tty == NULL) { + /* flush received characters */ + new_rx_get = (new_rx_get + char_count) & + (rx_bufsize - 1); + info->rflush_count++; + } else { +#ifdef BLOCKMOVE + /* we'd like to use memcpy(t, f, n) and memset(s, c, count) + for performance, but because of buffer boundaries, there + may be several steps to the operation */ + while (1) { + len = tty_prepare_flip_string(tty, &buf, + char_count); + if (!len) + break; + + len = min_t(unsigned int, min(len, char_count), + rx_bufsize - new_rx_get); + + memcpy_fromio(buf, cinfo->base_addr + + rx_bufaddr + new_rx_get, len); + + new_rx_get = (new_rx_get + len) & + (rx_bufsize - 1); + char_count -= len; + info->icount.rx += len; + info->idle_stats.recv_bytes += len; + } +#else + len = tty_buffer_request_room(tty, char_count); + while (len--) { + data = readb(cinfo->base_addr + rx_bufaddr + + new_rx_get); + new_rx_get = (new_rx_get + 1) & + (rx_bufsize - 1); + tty_insert_flip_char(tty, data, TTY_NORMAL); + info->idle_stats.recv_bytes++; + info->icount.rx++; + } +#endif +#ifdef CONFIG_CYZ_INTR + /* Recalculate the number of chars in the RX buffer and issue + a cmd in case it's higher than the RX high water mark */ + rx_put = readl(&buf_ctrl->rx_put); + if (rx_put >= rx_get) + char_count = rx_put - rx_get; + else + char_count = rx_put - rx_get + rx_bufsize; + if (char_count >= readl(&buf_ctrl->rx_threshold) && + !timer_pending(&cyz_rx_full_timer[ + info->line])) + mod_timer(&cyz_rx_full_timer[info->line], + jiffies + 1); +#endif + info->idle_stats.recv_idle = jiffies; + tty_schedule_flip(tty); + } + /* Update rx_get */ + cy_writel(&buf_ctrl->rx_get, new_rx_get); + } +} + +static void cyz_handle_tx(struct cyclades_port *info, struct tty_struct *tty) +{ + struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl; + struct cyclades_card *cinfo = info->card; + u8 data; + unsigned int char_count; +#ifdef BLOCKMOVE + int small_count; +#endif + __u32 tx_put, tx_get, tx_bufsize, tx_bufaddr; + + if (info->xmit_cnt <= 0) /* Nothing to transmit */ + return; + + tx_get = readl(&buf_ctrl->tx_get); + tx_put = readl(&buf_ctrl->tx_put); + tx_bufsize = readl(&buf_ctrl->tx_bufsize); + tx_bufaddr = readl(&buf_ctrl->tx_bufaddr); + if (tx_put >= tx_get) + char_count = tx_get - tx_put - 1 + tx_bufsize; + else + char_count = tx_get - tx_put - 1; + + if (char_count) { + + if (tty == NULL) + goto ztxdone; + + if (info->x_char) { /* send special char */ + data = info->x_char; + + cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data); + tx_put = (tx_put + 1) & (tx_bufsize - 1); + info->x_char = 0; + char_count--; + info->icount.tx++; + } +#ifdef BLOCKMOVE + while (0 < (small_count = min_t(unsigned int, + tx_bufsize - tx_put, min_t(unsigned int, + (SERIAL_XMIT_SIZE - info->xmit_tail), + min_t(unsigned int, info->xmit_cnt, + char_count))))) { + + memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr + + tx_put), + &info->port.xmit_buf[info->xmit_tail], + small_count); + + tx_put = (tx_put + small_count) & (tx_bufsize - 1); + char_count -= small_count; + info->icount.tx += small_count; + info->xmit_cnt -= small_count; + info->xmit_tail = (info->xmit_tail + small_count) & + (SERIAL_XMIT_SIZE - 1); + } +#else + while (info->xmit_cnt && char_count) { + data = info->port.xmit_buf[info->xmit_tail]; + info->xmit_cnt--; + info->xmit_tail = (info->xmit_tail + 1) & + (SERIAL_XMIT_SIZE - 1); + + cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data); + tx_put = (tx_put + 1) & (tx_bufsize - 1); + char_count--; + info->icount.tx++; + } +#endif + tty_wakeup(tty); +ztxdone: + /* Update tx_put */ + cy_writel(&buf_ctrl->tx_put, tx_put); + } +} + +static void cyz_handle_cmd(struct cyclades_card *cinfo) +{ + struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl; + struct tty_struct *tty; + struct cyclades_port *info; + __u32 channel, param, fw_ver; + __u8 cmd; + int special_count; + int delta_count; + + fw_ver = readl(&board_ctrl->fw_version); + + while (cyz_fetch_msg(cinfo, &channel, &cmd, ¶m) == 1) { + special_count = 0; + delta_count = 0; + info = &cinfo->ports[channel]; + tty = tty_port_tty_get(&info->port); + if (tty == NULL) + continue; + + switch (cmd) { + case C_CM_PR_ERROR: + tty_insert_flip_char(tty, 0, TTY_PARITY); + info->icount.rx++; + special_count++; + break; + case C_CM_FR_ERROR: + tty_insert_flip_char(tty, 0, TTY_FRAME); + info->icount.rx++; + special_count++; + break; + case C_CM_RXBRK: + tty_insert_flip_char(tty, 0, TTY_BREAK); + info->icount.rx++; + special_count++; + break; + case C_CM_MDCD: + info->icount.dcd++; + delta_count++; + if (info->port.flags & ASYNC_CHECK_CD) { + u32 dcd = fw_ver > 241 ? param : + readl(&info->u.cyz.ch_ctrl->rs_status); + if (dcd & C_RS_DCD) + wake_up_interruptible(&info->port.open_wait); + else + tty_hangup(tty); + } + break; + case C_CM_MCTS: + info->icount.cts++; + delta_count++; + break; + case C_CM_MRI: + info->icount.rng++; + delta_count++; + break; + case C_CM_MDSR: + info->icount.dsr++; + delta_count++; + break; +#ifdef Z_WAKE + case C_CM_IOCTLW: + complete(&info->shutdown_wait); + break; +#endif +#ifdef CONFIG_CYZ_INTR + case C_CM_RXHIWM: + case C_CM_RXNNDT: + case C_CM_INTBACK2: + /* Reception Interrupt */ +#ifdef CY_DEBUG_INTERRUPTS + printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " + "port %ld\n", info->card, channel); +#endif + cyz_handle_rx(info, tty); + break; + case C_CM_TXBEMPTY: + case C_CM_TXLOWWM: + case C_CM_INTBACK: + /* Transmission Interrupt */ +#ifdef CY_DEBUG_INTERRUPTS + printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " + "port %ld\n", info->card, channel); +#endif + cyz_handle_tx(info, tty); + break; +#endif /* CONFIG_CYZ_INTR */ + case C_CM_FATAL: + /* should do something with this !!! */ + break; + default: + break; + } + if (delta_count) + wake_up_interruptible(&info->port.delta_msr_wait); + if (special_count) + tty_schedule_flip(tty); + tty_kref_put(tty); + } +} + +#ifdef CONFIG_CYZ_INTR +static irqreturn_t cyz_interrupt(int irq, void *dev_id) +{ + struct cyclades_card *cinfo = dev_id; + + if (unlikely(!cyz_is_loaded(cinfo))) { +#ifdef CY_DEBUG_INTERRUPTS + printk(KERN_DEBUG "cyz_interrupt: board not yet loaded " + "(IRQ%d).\n", irq); +#endif + return IRQ_NONE; + } + + /* Handle the interrupts */ + cyz_handle_cmd(cinfo); + + return IRQ_HANDLED; +} /* cyz_interrupt */ + +static void cyz_rx_restart(unsigned long arg) +{ + struct cyclades_port *info = (struct cyclades_port *)arg; + struct cyclades_card *card = info->card; + int retval; + __u32 channel = info->line - card->first_line; + unsigned long flags; + + spin_lock_irqsave(&card->card_lock, flags); + retval = cyz_issue_cmd(card, channel, C_CM_INTBACK2, 0L); + if (retval != 0) { + printk(KERN_ERR "cyc:cyz_rx_restart retval on ttyC%d was %x\n", + info->line, retval); + } + spin_unlock_irqrestore(&card->card_lock, flags); +} + +#else /* CONFIG_CYZ_INTR */ + +static void cyz_poll(unsigned long arg) +{ + struct cyclades_card *cinfo; + struct cyclades_port *info; + unsigned long expires = jiffies + HZ; + unsigned int port, card; + + for (card = 0; card < NR_CARDS; card++) { + cinfo = &cy_card[card]; + + if (!cy_is_Z(cinfo)) + continue; + if (!cyz_is_loaded(cinfo)) + continue; + + /* Skip first polling cycle to avoid racing conditions with the FW */ + if (!cinfo->intr_enabled) { + cinfo->intr_enabled = 1; + continue; + } + + cyz_handle_cmd(cinfo); + + for (port = 0; port < cinfo->nports; port++) { + struct tty_struct *tty; + + info = &cinfo->ports[port]; + tty = tty_port_tty_get(&info->port); + /* OK to pass NULL to the handle functions below. + They need to drop the data in that case. */ + + if (!info->throttle) + cyz_handle_rx(info, tty); + cyz_handle_tx(info, tty); + tty_kref_put(tty); + } + /* poll every 'cyz_polling_cycle' period */ + expires = jiffies + cyz_polling_cycle; + } + mod_timer(&cyz_timerlist, expires); +} /* cyz_poll */ + +#endif /* CONFIG_CYZ_INTR */ + +/********** End of block of Cyclades-Z specific code *********/ +/***********************************************************/ + +/* This is called whenever a port becomes active; + interrupts are enabled and DTR & RTS are turned on. + */ +static int cy_startup(struct cyclades_port *info, struct tty_struct *tty) +{ + struct cyclades_card *card; + unsigned long flags; + int retval = 0; + int channel; + unsigned long page; + + card = info->card; + channel = info->line - card->first_line; + + page = get_zeroed_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + + spin_lock_irqsave(&card->card_lock, flags); + + if (info->port.flags & ASYNC_INITIALIZED) + goto errout; + + if (!info->type) { + set_bit(TTY_IO_ERROR, &tty->flags); + goto errout; + } + + if (info->port.xmit_buf) + free_page(page); + else + info->port.xmit_buf = (unsigned char *)page; + + spin_unlock_irqrestore(&card->card_lock, flags); + + cy_set_line_char(info, tty); + + if (!cy_is_Z(card)) { + channel &= 0x03; + + spin_lock_irqsave(&card->card_lock, flags); + + cyy_writeb(info, CyCAR, channel); + + cyy_writeb(info, CyRTPR, + (info->default_timeout ? info->default_timeout : 0x02)); + /* 10ms rx timeout */ + + cyy_issue_cmd(info, CyCHAN_CTL | CyENB_RCVR | CyENB_XMTR); + + cyy_change_rts_dtr(info, TIOCM_RTS | TIOCM_DTR, 0); + + cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyRxData); + } else { + struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl; + + if (!cyz_is_loaded(card)) + return -ENODEV; + +#ifdef CY_DEBUG_OPEN + printk(KERN_DEBUG "cyc startup Z card %d, channel %d, " + "base_addr %p\n", card, channel, card->base_addr); +#endif + spin_lock_irqsave(&card->card_lock, flags); + + cy_writel(&ch_ctrl->op_mode, C_CH_ENABLE); +#ifdef Z_WAKE +#ifdef CONFIG_CYZ_INTR + cy_writel(&ch_ctrl->intr_enable, + C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM | + C_IN_RXNNDT | C_IN_IOCTLW | C_IN_MDCD); +#else + cy_writel(&ch_ctrl->intr_enable, + C_IN_IOCTLW | C_IN_MDCD); +#endif /* CONFIG_CYZ_INTR */ +#else +#ifdef CONFIG_CYZ_INTR + cy_writel(&ch_ctrl->intr_enable, + C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM | + C_IN_RXNNDT | C_IN_MDCD); +#else + cy_writel(&ch_ctrl->intr_enable, C_IN_MDCD); +#endif /* CONFIG_CYZ_INTR */ +#endif /* Z_WAKE */ + + retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L); + if (retval != 0) { + printk(KERN_ERR "cyc:startup(1) retval on ttyC%d was " + "%x\n", info->line, retval); + } + + /* Flush RX buffers before raising DTR and RTS */ + retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_RX, 0L); + if (retval != 0) { + printk(KERN_ERR "cyc:startup(2) retval on ttyC%d was " + "%x\n", info->line, retval); + } + + /* set timeout !!! */ + /* set RTS and DTR !!! */ + tty_port_raise_dtr_rts(&info->port); + + /* enable send, recv, modem !!! */ + } + + info->port.flags |= ASYNC_INITIALIZED; + + clear_bit(TTY_IO_ERROR, &tty->flags); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + info->breakon = info->breakoff = 0; + memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats)); + info->idle_stats.in_use = + info->idle_stats.recv_idle = + info->idle_stats.xmit_idle = jiffies; + + spin_unlock_irqrestore(&card->card_lock, flags); + +#ifdef CY_DEBUG_OPEN + printk(KERN_DEBUG "cyc startup done\n"); +#endif + return 0; + +errout: + spin_unlock_irqrestore(&card->card_lock, flags); + free_page(page); + return retval; +} /* startup */ + +static void start_xmit(struct cyclades_port *info) +{ + struct cyclades_card *card = info->card; + unsigned long flags; + int channel = info->line - card->first_line; + + if (!cy_is_Z(card)) { + spin_lock_irqsave(&card->card_lock, flags); + cyy_writeb(info, CyCAR, channel & 0x03); + cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyTxRdy); + spin_unlock_irqrestore(&card->card_lock, flags); + } else { +#ifdef CONFIG_CYZ_INTR + int retval; + + spin_lock_irqsave(&card->card_lock, flags); + retval = cyz_issue_cmd(card, channel, C_CM_INTBACK, 0L); + if (retval != 0) { + printk(KERN_ERR "cyc:start_xmit retval on ttyC%d was " + "%x\n", info->line, retval); + } + spin_unlock_irqrestore(&card->card_lock, flags); +#else /* CONFIG_CYZ_INTR */ + /* Don't have to do anything at this time */ +#endif /* CONFIG_CYZ_INTR */ + } +} /* start_xmit */ + +/* + * This routine shuts down a serial port; interrupts are disabled, + * and DTR is dropped if the hangup on close termio flag is on. + */ +static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) +{ + struct cyclades_card *card; + unsigned long flags; + int channel; + + if (!(info->port.flags & ASYNC_INITIALIZED)) + return; + + card = info->card; + channel = info->line - card->first_line; + if (!cy_is_Z(card)) { + spin_lock_irqsave(&card->card_lock, flags); + + /* Clear delta_msr_wait queue to avoid mem leaks. */ + wake_up_interruptible(&info->port.delta_msr_wait); + + if (info->port.xmit_buf) { + unsigned char *temp; + temp = info->port.xmit_buf; + info->port.xmit_buf = NULL; + free_page((unsigned long)temp); + } + if (tty->termios->c_cflag & HUPCL) + cyy_change_rts_dtr(info, 0, TIOCM_RTS | TIOCM_DTR); + + cyy_issue_cmd(info, CyCHAN_CTL | CyDIS_RCVR); + /* it may be appropriate to clear _XMIT at + some later date (after testing)!!! */ + + set_bit(TTY_IO_ERROR, &tty->flags); + info->port.flags &= ~ASYNC_INITIALIZED; + spin_unlock_irqrestore(&card->card_lock, flags); + } else { +#ifdef CY_DEBUG_OPEN + printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, " + "base_addr %p\n", card, channel, card->base_addr); +#endif + + if (!cyz_is_loaded(card)) + return; + + spin_lock_irqsave(&card->card_lock, flags); + + if (info->port.xmit_buf) { + unsigned char *temp; + temp = info->port.xmit_buf; + info->port.xmit_buf = NULL; + free_page((unsigned long)temp); + } + + if (tty->termios->c_cflag & HUPCL) + tty_port_lower_dtr_rts(&info->port); + + set_bit(TTY_IO_ERROR, &tty->flags); + info->port.flags &= ~ASYNC_INITIALIZED; + + spin_unlock_irqrestore(&card->card_lock, flags); + } + +#ifdef CY_DEBUG_OPEN + printk(KERN_DEBUG "cyc shutdown done\n"); +#endif +} /* shutdown */ + +/* + * ------------------------------------------------------------ + * cy_open() and friends + * ------------------------------------------------------------ + */ + +/* + * This routine is called whenever a serial port is opened. It + * performs the serial-specific initialization for the tty structure. + */ +static int cy_open(struct tty_struct *tty, struct file *filp) +{ + struct cyclades_port *info; + unsigned int i, line; + int retval; + + line = tty->index; + if (tty->index < 0 || NR_PORTS <= line) + return -ENODEV; + + for (i = 0; i < NR_CARDS; i++) + if (line < cy_card[i].first_line + cy_card[i].nports && + line >= cy_card[i].first_line) + break; + if (i >= NR_CARDS) + return -ENODEV; + info = &cy_card[i].ports[line - cy_card[i].first_line]; + if (info->line < 0) + return -ENODEV; + + /* If the card's firmware hasn't been loaded, + treat it as absent from the system. This + will make the user pay attention. + */ + if (cy_is_Z(info->card)) { + struct cyclades_card *cinfo = info->card; + struct FIRM_ID __iomem *firm_id = cinfo->base_addr + ID_ADDRESS; + + if (!cyz_is_loaded(cinfo)) { + if (cinfo->hw_ver == ZE_V1 && cyz_fpga_loaded(cinfo) && + readl(&firm_id->signature) == + ZFIRM_HLT) { + printk(KERN_ERR "cyc:Cyclades-Z Error: you " + "need an external power supply for " + "this number of ports.\nFirmware " + "halted.\n"); + } else { + printk(KERN_ERR "cyc:Cyclades-Z firmware not " + "yet loaded\n"); + } + return -ENODEV; + } +#ifdef CONFIG_CYZ_INTR + else { + /* In case this Z board is operating in interrupt mode, its + interrupts should be enabled as soon as the first open + happens to one of its ports. */ + if (!cinfo->intr_enabled) { + u16 intr; + + /* Enable interrupts on the PLX chip */ + intr = readw(&cinfo->ctl_addr.p9060-> + intr_ctrl_stat) | 0x0900; + cy_writew(&cinfo->ctl_addr.p9060-> + intr_ctrl_stat, intr); + /* Enable interrupts on the FW */ + retval = cyz_issue_cmd(cinfo, 0, + C_CM_IRQ_ENBL, 0L); + if (retval != 0) { + printk(KERN_ERR "cyc:IRQ enable retval " + "was %x\n", retval); + } + cinfo->intr_enabled = 1; + } + } +#endif /* CONFIG_CYZ_INTR */ + /* Make sure this Z port really exists in hardware */ + if (info->line > (cinfo->first_line + cinfo->nports - 1)) + return -ENODEV; + } +#ifdef CY_DEBUG_OTHER + printk(KERN_DEBUG "cyc:cy_open ttyC%d\n", info->line); +#endif + tty->driver_data = info; + if (serial_paranoia_check(info, tty->name, "cy_open")) + return -ENODEV; + +#ifdef CY_DEBUG_OPEN + printk(KERN_DEBUG "cyc:cy_open ttyC%d, count = %d\n", info->line, + info->port.count); +#endif + info->port.count++; +#ifdef CY_DEBUG_COUNT + printk(KERN_DEBUG "cyc:cy_open (%d): incrementing count to %d\n", + current->pid, info->port.count); +#endif + + /* + * If the port is the middle of closing, bail out now + */ + if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) { + wait_event_interruptible_tty(info->port.close_wait, + !(info->port.flags & ASYNC_CLOSING)); + return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; + } + + /* + * Start up serial port + */ + retval = cy_startup(info, tty); + if (retval) + return retval; + + retval = tty_port_block_til_ready(&info->port, tty, filp); + if (retval) { +#ifdef CY_DEBUG_OPEN + printk(KERN_DEBUG "cyc:cy_open returning after block_til_ready " + "with %d\n", retval); +#endif + return retval; + } + + info->throttle = 0; + tty_port_tty_set(&info->port, tty); + +#ifdef CY_DEBUG_OPEN + printk(KERN_DEBUG "cyc:cy_open done\n"); +#endif + return 0; +} /* cy_open */ + +/* + * cy_wait_until_sent() --- wait until the transmitter is empty + */ +static void cy_wait_until_sent(struct tty_struct *tty, int timeout) +{ + struct cyclades_card *card; + struct cyclades_port *info = tty->driver_data; + unsigned long orig_jiffies; + int char_time; + + if (serial_paranoia_check(info, tty->name, "cy_wait_until_sent")) + return; + + if (info->xmit_fifo_size == 0) + return; /* Just in case.... */ + + orig_jiffies = jiffies; + /* + * Set the check interval to be 1/5 of the estimated time to + * send a single character, and make it at least 1. The check + * interval should also be less than the timeout. + * + * Note: we have to use pretty tight timings here to satisfy + * the NIST-PCTS. + */ + char_time = (info->timeout - HZ / 50) / info->xmit_fifo_size; + char_time = char_time / 5; + if (char_time <= 0) + char_time = 1; + if (timeout < 0) + timeout = 0; + if (timeout) + char_time = min(char_time, timeout); + /* + * If the transmitter hasn't cleared in twice the approximate + * amount of time to send the entire FIFO, it probably won't + * ever clear. This assumes the UART isn't doing flow + * control, which is currently the case. Hence, if it ever + * takes longer than info->timeout, this is probably due to a + * UART bug of some kind. So, we clamp the timeout parameter at + * 2*info->timeout. + */ + if (!timeout || timeout > 2 * info->timeout) + timeout = 2 * info->timeout; +#ifdef CY_DEBUG_WAIT_UNTIL_SENT + printk(KERN_DEBUG "In cy_wait_until_sent(%d) check=%d, jiff=%lu...", + timeout, char_time, jiffies); +#endif + card = info->card; + if (!cy_is_Z(card)) { + while (cyy_readb(info, CySRER) & CyTxRdy) { +#ifdef CY_DEBUG_WAIT_UNTIL_SENT + printk(KERN_DEBUG "Not clean (jiff=%lu)...", jiffies); +#endif + if (msleep_interruptible(jiffies_to_msecs(char_time))) + break; + if (timeout && time_after(jiffies, orig_jiffies + + timeout)) + break; + } + } + /* Run one more char cycle */ + msleep_interruptible(jiffies_to_msecs(char_time * 5)); +#ifdef CY_DEBUG_WAIT_UNTIL_SENT + printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies); +#endif +} + +static void cy_flush_buffer(struct tty_struct *tty) +{ + struct cyclades_port *info = tty->driver_data; + struct cyclades_card *card; + int channel, retval; + unsigned long flags; + +#ifdef CY_DEBUG_IO + printk(KERN_DEBUG "cyc:cy_flush_buffer ttyC%d\n", info->line); +#endif + + if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) + return; + + card = info->card; + channel = info->line - card->first_line; + + spin_lock_irqsave(&card->card_lock, flags); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + spin_unlock_irqrestore(&card->card_lock, flags); + + if (cy_is_Z(card)) { /* If it is a Z card, flush the on-board + buffers as well */ + spin_lock_irqsave(&card->card_lock, flags); + retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_TX, 0L); + if (retval != 0) { + printk(KERN_ERR "cyc: flush_buffer retval on ttyC%d " + "was %x\n", info->line, retval); + } + spin_unlock_irqrestore(&card->card_lock, flags); + } + tty_wakeup(tty); +} /* cy_flush_buffer */ + + +static void cy_do_close(struct tty_port *port) +{ + struct cyclades_port *info = container_of(port, struct cyclades_port, + port); + struct cyclades_card *card; + unsigned long flags; + int channel; + + card = info->card; + channel = info->line - card->first_line; + spin_lock_irqsave(&card->card_lock, flags); + + if (!cy_is_Z(card)) { + /* Stop accepting input */ + cyy_writeb(info, CyCAR, channel & 0x03); + cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyRxData); + if (info->port.flags & ASYNC_INITIALIZED) { + /* Waiting for on-board buffers to be empty before + closing the port */ + spin_unlock_irqrestore(&card->card_lock, flags); + cy_wait_until_sent(port->tty, info->timeout); + spin_lock_irqsave(&card->card_lock, flags); + } + } else { +#ifdef Z_WAKE + /* Waiting for on-board buffers to be empty before closing + the port */ + struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl; + int retval; + + if (readl(&ch_ctrl->flow_status) != C_FS_TXIDLE) { + retval = cyz_issue_cmd(card, channel, C_CM_IOCTLW, 0L); + if (retval != 0) { + printk(KERN_DEBUG "cyc:cy_close retval on " + "ttyC%d was %x\n", info->line, retval); + } + spin_unlock_irqrestore(&card->card_lock, flags); + wait_for_completion_interruptible(&info->shutdown_wait); + spin_lock_irqsave(&card->card_lock, flags); + } +#endif + } + spin_unlock_irqrestore(&card->card_lock, flags); + cy_shutdown(info, port->tty); +} + +/* + * This routine is called when a particular tty device is closed. + */ +static void cy_close(struct tty_struct *tty, struct file *filp) +{ + struct cyclades_port *info = tty->driver_data; + if (!info || serial_paranoia_check(info, tty->name, "cy_close")) + return; + tty_port_close(&info->port, tty, filp); +} /* cy_close */ + +/* This routine gets called when tty_write has put something into + * the write_queue. The characters may come from user space or + * kernel space. + * + * This routine will return the number of characters actually + * accepted for writing. + * + * If the port is not already transmitting stuff, start it off by + * enabling interrupts. The interrupt service routine will then + * ensure that the characters are sent. + * If the port is already active, there is no need to kick it. + * + */ +static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) +{ + struct cyclades_port *info = tty->driver_data; + unsigned long flags; + int c, ret = 0; + +#ifdef CY_DEBUG_IO + printk(KERN_DEBUG "cyc:cy_write ttyC%d\n", info->line); +#endif + + if (serial_paranoia_check(info, tty->name, "cy_write")) + return 0; + + if (!info->port.xmit_buf) + return 0; + + spin_lock_irqsave(&info->card->card_lock, flags); + while (1) { + c = min(count, (int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1)); + c = min(c, (int)(SERIAL_XMIT_SIZE - info->xmit_head)); + + if (c <= 0) + break; + + memcpy(info->port.xmit_buf + info->xmit_head, buf, c); + info->xmit_head = (info->xmit_head + c) & + (SERIAL_XMIT_SIZE - 1); + info->xmit_cnt += c; + buf += c; + count -= c; + ret += c; + } + spin_unlock_irqrestore(&info->card->card_lock, flags); + + info->idle_stats.xmit_bytes += ret; + info->idle_stats.xmit_idle = jiffies; + + if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) + start_xmit(info); + + return ret; +} /* cy_write */ + +/* + * This routine is called by the kernel to write a single + * character to the tty device. If the kernel uses this routine, + * it must call the flush_chars() routine (if defined) when it is + * done stuffing characters into the driver. If there is no room + * in the queue, the character is ignored. + */ +static int cy_put_char(struct tty_struct *tty, unsigned char ch) +{ + struct cyclades_port *info = tty->driver_data; + unsigned long flags; + +#ifdef CY_DEBUG_IO + printk(KERN_DEBUG "cyc:cy_put_char ttyC%d\n", info->line); +#endif + + if (serial_paranoia_check(info, tty->name, "cy_put_char")) + return 0; + + if (!info->port.xmit_buf) + return 0; + + spin_lock_irqsave(&info->card->card_lock, flags); + if (info->xmit_cnt >= (int)(SERIAL_XMIT_SIZE - 1)) { + spin_unlock_irqrestore(&info->card->card_lock, flags); + return 0; + } + + info->port.xmit_buf[info->xmit_head++] = ch; + info->xmit_head &= SERIAL_XMIT_SIZE - 1; + info->xmit_cnt++; + info->idle_stats.xmit_bytes++; + info->idle_stats.xmit_idle = jiffies; + spin_unlock_irqrestore(&info->card->card_lock, flags); + return 1; +} /* cy_put_char */ + +/* + * This routine is called by the kernel after it has written a + * series of characters to the tty device using put_char(). + */ +static void cy_flush_chars(struct tty_struct *tty) +{ + struct cyclades_port *info = tty->driver_data; + +#ifdef CY_DEBUG_IO + printk(KERN_DEBUG "cyc:cy_flush_chars ttyC%d\n", info->line); +#endif + + if (serial_paranoia_check(info, tty->name, "cy_flush_chars")) + return; + + if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || + !info->port.xmit_buf) + return; + + start_xmit(info); +} /* cy_flush_chars */ + +/* + * This routine returns the numbers of characters the tty driver + * will accept for queuing to be written. This number is subject + * to change as output buffers get emptied, or if the output flow + * control is activated. + */ +static int cy_write_room(struct tty_struct *tty) +{ + struct cyclades_port *info = tty->driver_data; + int ret; + +#ifdef CY_DEBUG_IO + printk(KERN_DEBUG "cyc:cy_write_room ttyC%d\n", info->line); +#endif + + if (serial_paranoia_check(info, tty->name, "cy_write_room")) + return 0; + ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; + if (ret < 0) + ret = 0; + return ret; +} /* cy_write_room */ + +static int cy_chars_in_buffer(struct tty_struct *tty) +{ + struct cyclades_port *info = tty->driver_data; + + if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer")) + return 0; + +#ifdef Z_EXT_CHARS_IN_BUFFER + if (!cy_is_Z(info->card)) { +#endif /* Z_EXT_CHARS_IN_BUFFER */ +#ifdef CY_DEBUG_IO + printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n", + info->line, info->xmit_cnt); +#endif + return info->xmit_cnt; +#ifdef Z_EXT_CHARS_IN_BUFFER + } else { + struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl; + int char_count; + __u32 tx_put, tx_get, tx_bufsize; + + tx_get = readl(&buf_ctrl->tx_get); + tx_put = readl(&buf_ctrl->tx_put); + tx_bufsize = readl(&buf_ctrl->tx_bufsize); + if (tx_put >= tx_get) + char_count = tx_put - tx_get; + else + char_count = tx_put - tx_get + tx_bufsize; +#ifdef CY_DEBUG_IO + printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n", + info->line, info->xmit_cnt + char_count); +#endif + return info->xmit_cnt + char_count; + } +#endif /* Z_EXT_CHARS_IN_BUFFER */ +} /* cy_chars_in_buffer */ + +/* + * ------------------------------------------------------------ + * cy_ioctl() and friends + * ------------------------------------------------------------ + */ + +static void cyy_baud_calc(struct cyclades_port *info, __u32 baud) +{ + int co, co_val, bpr; + __u32 cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 : + 25000000); + + if (baud == 0) { + info->tbpr = info->tco = info->rbpr = info->rco = 0; + return; + } + + /* determine which prescaler to use */ + for (co = 4, co_val = 2048; co; co--, co_val >>= 2) { + if (cy_clock / co_val / baud > 63) + break; + } + + bpr = (cy_clock / co_val * 2 / baud + 1) / 2; + if (bpr > 255) + bpr = 255; + + info->tbpr = info->rbpr = bpr; + info->tco = info->rco = co; +} + +/* + * This routine finds or computes the various line characteristics. + * It used to be called config_setup + */ +static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty) +{ + struct cyclades_card *card; + unsigned long flags; + int channel; + unsigned cflag, iflag; + int baud, baud_rate = 0; + int i; + + if (!tty->termios) /* XXX can this happen at all? */ + return; + + if (info->line == -1) + return; + + cflag = tty->termios->c_cflag; + iflag = tty->termios->c_iflag; + + /* + * Set up the tty->alt_speed kludge + */ + if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + tty->alt_speed = 57600; + if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + tty->alt_speed = 115200; + if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + tty->alt_speed = 230400; + if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + tty->alt_speed = 460800; + + card = info->card; + channel = info->line - card->first_line; + + if (!cy_is_Z(card)) { + u32 cflags; + + /* baud rate */ + baud = tty_get_baud_rate(tty); + if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) == + ASYNC_SPD_CUST) { + if (info->custom_divisor) + baud_rate = info->baud / info->custom_divisor; + else + baud_rate = info->baud; + } else if (baud > CD1400_MAX_SPEED) { + baud = CD1400_MAX_SPEED; + } + /* find the baud index */ + for (i = 0; i < 20; i++) { + if (baud == baud_table[i]) + break; + } + if (i == 20) + i = 19; /* CD1400_MAX_SPEED */ + + if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) == + ASYNC_SPD_CUST) { + cyy_baud_calc(info, baud_rate); + } else { + if (info->chip_rev >= CD1400_REV_J) { + /* It is a CD1400 rev. J or later */ + info->tbpr = baud_bpr_60[i]; /* Tx BPR */ + info->tco = baud_co_60[i]; /* Tx CO */ + info->rbpr = baud_bpr_60[i]; /* Rx BPR */ + info->rco = baud_co_60[i]; /* Rx CO */ + } else { + info->tbpr = baud_bpr_25[i]; /* Tx BPR */ + info->tco = baud_co_25[i]; /* Tx CO */ + info->rbpr = baud_bpr_25[i]; /* Rx BPR */ + info->rco = baud_co_25[i]; /* Rx CO */ + } + } + if (baud_table[i] == 134) { + /* get it right for 134.5 baud */ + info->timeout = (info->xmit_fifo_size * HZ * 30 / 269) + + 2; + } else if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) == + ASYNC_SPD_CUST) { + info->timeout = (info->xmit_fifo_size * HZ * 15 / + baud_rate) + 2; + } else if (baud_table[i]) { + info->timeout = (info->xmit_fifo_size * HZ * 15 / + baud_table[i]) + 2; + /* this needs to be propagated into the card info */ + } else { + info->timeout = 0; + } + /* By tradition (is it a standard?) a baud rate of zero + implies the line should be/has been closed. A bit + later in this routine such a test is performed. */ + + /* byte size and parity */ + info->cor5 = 0; + info->cor4 = 0; + /* receive threshold */ + info->cor3 = (info->default_threshold ? + info->default_threshold : baud_cor3[i]); + info->cor2 = CyETC; + switch (cflag & CSIZE) { + case CS5: + info->cor1 = Cy_5_BITS; + break; + case CS6: + info->cor1 = Cy_6_BITS; + break; + case CS7: + info->cor1 = Cy_7_BITS; + break; + case CS8: + info->cor1 = Cy_8_BITS; + break; + } + if (cflag & CSTOPB) + info->cor1 |= Cy_2_STOP; + + if (cflag & PARENB) { + if (cflag & PARODD) + info->cor1 |= CyPARITY_O; + else + info->cor1 |= CyPARITY_E; + } else + info->cor1 |= CyPARITY_NONE; + + /* CTS flow control flag */ + if (cflag & CRTSCTS) { + info->port.flags |= ASYNC_CTS_FLOW; + info->cor2 |= CyCtsAE; + } else { + info->port.flags &= ~ASYNC_CTS_FLOW; + info->cor2 &= ~CyCtsAE; + } + if (cflag & CLOCAL) + info->port.flags &= ~ASYNC_CHECK_CD; + else + info->port.flags |= ASYNC_CHECK_CD; + + /*********************************************** + The hardware option, CyRtsAO, presents RTS when + the chip has characters to send. Since most modems + use RTS as reverse (inbound) flow control, this + option is not used. If inbound flow control is + necessary, DTR can be programmed to provide the + appropriate signals for use with a non-standard + cable. Contact Marcio Saito for details. + ***********************************************/ + + channel &= 0x03; + + spin_lock_irqsave(&card->card_lock, flags); + cyy_writeb(info, CyCAR, channel); + + /* tx and rx baud rate */ + + cyy_writeb(info, CyTCOR, info->tco); + cyy_writeb(info, CyTBPR, info->tbpr); + cyy_writeb(info, CyRCOR, info->rco); + cyy_writeb(info, CyRBPR, info->rbpr); + + /* set line characteristics according configuration */ + + cyy_writeb(info, CySCHR1, START_CHAR(tty)); + cyy_writeb(info, CySCHR2, STOP_CHAR(tty)); + cyy_writeb(info, CyCOR1, info->cor1); + cyy_writeb(info, CyCOR2, info->cor2); + cyy_writeb(info, CyCOR3, info->cor3); + cyy_writeb(info, CyCOR4, info->cor4); + cyy_writeb(info, CyCOR5, info->cor5); + + cyy_issue_cmd(info, CyCOR_CHANGE | CyCOR1ch | CyCOR2ch | + CyCOR3ch); + + /* !!! Is this needed? */ + cyy_writeb(info, CyCAR, channel); + cyy_writeb(info, CyRTPR, + (info->default_timeout ? info->default_timeout : 0x02)); + /* 10ms rx timeout */ + + cflags = CyCTS; + if (!C_CLOCAL(tty)) + cflags |= CyDSR | CyRI | CyDCD; + /* without modem intr */ + cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyMdmCh); + /* act on 1->0 modem transitions */ + if ((cflag & CRTSCTS) && info->rflow) + cyy_writeb(info, CyMCOR1, cflags | rflow_thr[i]); + else + cyy_writeb(info, CyMCOR1, cflags); + /* act on 0->1 modem transitions */ + cyy_writeb(info, CyMCOR2, cflags); + + if (i == 0) /* baud rate is zero, turn off line */ + cyy_change_rts_dtr(info, 0, TIOCM_DTR); + else + cyy_change_rts_dtr(info, TIOCM_DTR, 0); + + clear_bit(TTY_IO_ERROR, &tty->flags); + spin_unlock_irqrestore(&card->card_lock, flags); + + } else { + struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl; + __u32 sw_flow; + int retval; + + if (!cyz_is_loaded(card)) + return; + + /* baud rate */ + baud = tty_get_baud_rate(tty); + if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) == + ASYNC_SPD_CUST) { + if (info->custom_divisor) + baud_rate = info->baud / info->custom_divisor; + else + baud_rate = info->baud; + } else if (baud > CYZ_MAX_SPEED) { + baud = CYZ_MAX_SPEED; + } + cy_writel(&ch_ctrl->comm_baud, baud); + + if (baud == 134) { + /* get it right for 134.5 baud */ + info->timeout = (info->xmit_fifo_size * HZ * 30 / 269) + + 2; + } else if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) == + ASYNC_SPD_CUST) { + info->timeout = (info->xmit_fifo_size * HZ * 15 / + baud_rate) + 2; + } else if (baud) { + info->timeout = (info->xmit_fifo_size * HZ * 15 / + baud) + 2; + /* this needs to be propagated into the card info */ + } else { + info->timeout = 0; + } + + /* byte size and parity */ + switch (cflag & CSIZE) { + case CS5: + cy_writel(&ch_ctrl->comm_data_l, C_DL_CS5); + break; + case CS6: + cy_writel(&ch_ctrl->comm_data_l, C_DL_CS6); + break; + case CS7: + cy_writel(&ch_ctrl->comm_data_l, C_DL_CS7); + break; + case CS8: + cy_writel(&ch_ctrl->comm_data_l, C_DL_CS8); + break; + } + if (cflag & CSTOPB) { + cy_writel(&ch_ctrl->comm_data_l, + readl(&ch_ctrl->comm_data_l) | C_DL_2STOP); + } else { + cy_writel(&ch_ctrl->comm_data_l, + readl(&ch_ctrl->comm_data_l) | C_DL_1STOP); + } + if (cflag & PARENB) { + if (cflag & PARODD) + cy_writel(&ch_ctrl->comm_parity, C_PR_ODD); + else + cy_writel(&ch_ctrl->comm_parity, C_PR_EVEN); + } else + cy_writel(&ch_ctrl->comm_parity, C_PR_NONE); + + /* CTS flow control flag */ + if (cflag & CRTSCTS) { + cy_writel(&ch_ctrl->hw_flow, + readl(&ch_ctrl->hw_flow) | C_RS_CTS | C_RS_RTS); + } else { + cy_writel(&ch_ctrl->hw_flow, readl(&ch_ctrl->hw_flow) & + ~(C_RS_CTS | C_RS_RTS)); + } + /* As the HW flow control is done in firmware, the driver + doesn't need to care about it */ + info->port.flags &= ~ASYNC_CTS_FLOW; + + /* XON/XOFF/XANY flow control flags */ + sw_flow = 0; + if (iflag & IXON) { + sw_flow |= C_FL_OXX; + if (iflag & IXANY) + sw_flow |= C_FL_OIXANY; + } + cy_writel(&ch_ctrl->sw_flow, sw_flow); + + retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L); + if (retval != 0) { + printk(KERN_ERR "cyc:set_line_char retval on ttyC%d " + "was %x\n", info->line, retval); + } + + /* CD sensitivity */ + if (cflag & CLOCAL) + info->port.flags &= ~ASYNC_CHECK_CD; + else + info->port.flags |= ASYNC_CHECK_CD; + + if (baud == 0) { /* baud rate is zero, turn off line */ + cy_writel(&ch_ctrl->rs_control, + readl(&ch_ctrl->rs_control) & ~C_RS_DTR); +#ifdef CY_DEBUG_DTR + printk(KERN_DEBUG "cyc:set_line_char dropping Z DTR\n"); +#endif + } else { + cy_writel(&ch_ctrl->rs_control, + readl(&ch_ctrl->rs_control) | C_RS_DTR); +#ifdef CY_DEBUG_DTR + printk(KERN_DEBUG "cyc:set_line_char raising Z DTR\n"); +#endif + } + + retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L); + if (retval != 0) { + printk(KERN_ERR "cyc:set_line_char(2) retval on ttyC%d " + "was %x\n", info->line, retval); + } + + clear_bit(TTY_IO_ERROR, &tty->flags); + } +} /* set_line_char */ + +static int cy_get_serial_info(struct cyclades_port *info, + struct serial_struct __user *retinfo) +{ + struct cyclades_card *cinfo = info->card; + struct serial_struct tmp = { + .type = info->type, + .line = info->line, + .port = (info->card - cy_card) * 0x100 + info->line - + cinfo->first_line, + .irq = cinfo->irq, + .flags = info->port.flags, + .close_delay = info->port.close_delay, + .closing_wait = info->port.closing_wait, + .baud_base = info->baud, + .custom_divisor = info->custom_divisor, + .hub6 = 0, /*!!! */ + }; + return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; +} + +static int +cy_set_serial_info(struct cyclades_port *info, struct tty_struct *tty, + struct serial_struct __user *new_info) +{ + struct serial_struct new_serial; + int ret; + + if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) + return -EFAULT; + + mutex_lock(&info->port.mutex); + if (!capable(CAP_SYS_ADMIN)) { + if (new_serial.close_delay != info->port.close_delay || + new_serial.baud_base != info->baud || + (new_serial.flags & ASYNC_FLAGS & + ~ASYNC_USR_MASK) != + (info->port.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)) + { + mutex_unlock(&info->port.mutex); + return -EPERM; + } + info->port.flags = (info->port.flags & ~ASYNC_USR_MASK) | + (new_serial.flags & ASYNC_USR_MASK); + info->baud = new_serial.baud_base; + info->custom_divisor = new_serial.custom_divisor; + goto check_and_exit; + } + + /* + * OK, past this point, all the error checking has been done. + * At this point, we start making changes..... + */ + + info->baud = new_serial.baud_base; + info->custom_divisor = new_serial.custom_divisor; + info->port.flags = (info->port.flags & ~ASYNC_FLAGS) | + (new_serial.flags & ASYNC_FLAGS); + info->port.close_delay = new_serial.close_delay * HZ / 100; + info->port.closing_wait = new_serial.closing_wait * HZ / 100; + +check_and_exit: + if (info->port.flags & ASYNC_INITIALIZED) { + cy_set_line_char(info, tty); + ret = 0; + } else { + ret = cy_startup(info, tty); + } + mutex_unlock(&info->port.mutex); + return ret; +} /* set_serial_info */ + +/* + * get_lsr_info - get line status register info + * + * Purpose: Let user call ioctl() to get info when the UART physically + * is emptied. On bus types like RS485, the transmitter must + * release the bus after transmitting. This must be done when + * the transmit shift register is empty, not be done when the + * transmit holding register is empty. This functionality + * allows an RS485 driver to be written in user space. + */ +static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value) +{ + struct cyclades_card *card = info->card; + unsigned int result; + unsigned long flags; + u8 status; + + if (!cy_is_Z(card)) { + spin_lock_irqsave(&card->card_lock, flags); + status = cyy_readb(info, CySRER) & (CyTxRdy | CyTxMpty); + spin_unlock_irqrestore(&card->card_lock, flags); + result = (status ? 0 : TIOCSER_TEMT); + } else { + /* Not supported yet */ + return -EINVAL; + } + return put_user(result, (unsigned long __user *)value); +} + +static int cy_tiocmget(struct tty_struct *tty) +{ + struct cyclades_port *info = tty->driver_data; + struct cyclades_card *card; + int result; + + if (serial_paranoia_check(info, tty->name, __func__)) + return -ENODEV; + + card = info->card; + + if (!cy_is_Z(card)) { + unsigned long flags; + int channel = info->line - card->first_line; + u8 status; + + spin_lock_irqsave(&card->card_lock, flags); + cyy_writeb(info, CyCAR, channel & 0x03); + status = cyy_readb(info, CyMSVR1); + status |= cyy_readb(info, CyMSVR2); + spin_unlock_irqrestore(&card->card_lock, flags); + + if (info->rtsdtr_inv) { + result = ((status & CyRTS) ? TIOCM_DTR : 0) | + ((status & CyDTR) ? TIOCM_RTS : 0); + } else { + result = ((status & CyRTS) ? TIOCM_RTS : 0) | + ((status & CyDTR) ? TIOCM_DTR : 0); + } + result |= ((status & CyDCD) ? TIOCM_CAR : 0) | + ((status & CyRI) ? TIOCM_RNG : 0) | + ((status & CyDSR) ? TIOCM_DSR : 0) | + ((status & CyCTS) ? TIOCM_CTS : 0); + } else { + u32 lstatus; + + if (!cyz_is_loaded(card)) { + result = -ENODEV; + goto end; + } + + lstatus = readl(&info->u.cyz.ch_ctrl->rs_status); + result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) | + ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) | + ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) | + ((lstatus & C_RS_RI) ? TIOCM_RNG : 0) | + ((lstatus & C_RS_DSR) ? TIOCM_DSR : 0) | + ((lstatus & C_RS_CTS) ? TIOCM_CTS : 0); + } +end: + return result; +} /* cy_tiomget */ + +static int +cy_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + struct cyclades_port *info = tty->driver_data; + struct cyclades_card *card; + unsigned long flags; + + if (serial_paranoia_check(info, tty->name, __func__)) + return -ENODEV; + + card = info->card; + if (!cy_is_Z(card)) { + spin_lock_irqsave(&card->card_lock, flags); + cyy_change_rts_dtr(info, set, clear); + spin_unlock_irqrestore(&card->card_lock, flags); + } else { + struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl; + int retval, channel = info->line - card->first_line; + u32 rs; + + if (!cyz_is_loaded(card)) + return -ENODEV; + + spin_lock_irqsave(&card->card_lock, flags); + rs = readl(&ch_ctrl->rs_control); + if (set & TIOCM_RTS) + rs |= C_RS_RTS; + if (clear & TIOCM_RTS) + rs &= ~C_RS_RTS; + if (set & TIOCM_DTR) { + rs |= C_RS_DTR; +#ifdef CY_DEBUG_DTR + printk(KERN_DEBUG "cyc:set_modem_info raising Z DTR\n"); +#endif + } + if (clear & TIOCM_DTR) { + rs &= ~C_RS_DTR; +#ifdef CY_DEBUG_DTR + printk(KERN_DEBUG "cyc:set_modem_info clearing " + "Z DTR\n"); +#endif + } + cy_writel(&ch_ctrl->rs_control, rs); + retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L); + spin_unlock_irqrestore(&card->card_lock, flags); + if (retval != 0) { + printk(KERN_ERR "cyc:set_modem_info retval on ttyC%d " + "was %x\n", info->line, retval); + } + } + return 0; +} + +/* + * cy_break() --- routine which turns the break handling on or off + */ +static int cy_break(struct tty_struct *tty, int break_state) +{ + struct cyclades_port *info = tty->driver_data; + struct cyclades_card *card; + unsigned long flags; + int retval = 0; + + if (serial_paranoia_check(info, tty->name, "cy_break")) + return -EINVAL; + + card = info->card; + + spin_lock_irqsave(&card->card_lock, flags); + if (!cy_is_Z(card)) { + /* Let the transmit ISR take care of this (since it + requires stuffing characters into the output stream). + */ + if (break_state == -1) { + if (!info->breakon) { + info->breakon = 1; + if (!info->xmit_cnt) { + spin_unlock_irqrestore(&card->card_lock, flags); + start_xmit(info); + spin_lock_irqsave(&card->card_lock, flags); + } + } + } else { + if (!info->breakoff) { + info->breakoff = 1; + if (!info->xmit_cnt) { + spin_unlock_irqrestore(&card->card_lock, flags); + start_xmit(info); + spin_lock_irqsave(&card->card_lock, flags); + } + } + } + } else { + if (break_state == -1) { + retval = cyz_issue_cmd(card, + info->line - card->first_line, + C_CM_SET_BREAK, 0L); + if (retval != 0) { + printk(KERN_ERR "cyc:cy_break (set) retval on " + "ttyC%d was %x\n", info->line, retval); + } + } else { + retval = cyz_issue_cmd(card, + info->line - card->first_line, + C_CM_CLR_BREAK, 0L); + if (retval != 0) { + printk(KERN_DEBUG "cyc:cy_break (clr) retval " + "on ttyC%d was %x\n", info->line, + retval); + } + } + } + spin_unlock_irqrestore(&card->card_lock, flags); + return retval; +} /* cy_break */ + +static int set_threshold(struct cyclades_port *info, unsigned long value) +{ + struct cyclades_card *card = info->card; + unsigned long flags; + + if (!cy_is_Z(card)) { + info->cor3 &= ~CyREC_FIFO; + info->cor3 |= value & CyREC_FIFO; + + spin_lock_irqsave(&card->card_lock, flags); + cyy_writeb(info, CyCOR3, info->cor3); + cyy_issue_cmd(info, CyCOR_CHANGE | CyCOR3ch); + spin_unlock_irqrestore(&card->card_lock, flags); + } + return 0; +} /* set_threshold */ + +static int get_threshold(struct cyclades_port *info, + unsigned long __user *value) +{ + struct cyclades_card *card = info->card; + + if (!cy_is_Z(card)) { + u8 tmp = cyy_readb(info, CyCOR3) & CyREC_FIFO; + return put_user(tmp, value); + } + return 0; +} /* get_threshold */ + +static int set_timeout(struct cyclades_port *info, unsigned long value) +{ + struct cyclades_card *card = info->card; + unsigned long flags; + + if (!cy_is_Z(card)) { + spin_lock_irqsave(&card->card_lock, flags); + cyy_writeb(info, CyRTPR, value & 0xff); + spin_unlock_irqrestore(&card->card_lock, flags); + } + return 0; +} /* set_timeout */ + +static int get_timeout(struct cyclades_port *info, + unsigned long __user *value) +{ + struct cyclades_card *card = info->card; + + if (!cy_is_Z(card)) { + u8 tmp = cyy_readb(info, CyRTPR); + return put_user(tmp, value); + } + return 0; +} /* get_timeout */ + +static int cy_cflags_changed(struct cyclades_port *info, unsigned long arg, + struct cyclades_icount *cprev) +{ + struct cyclades_icount cnow; + unsigned long flags; + int ret; + + spin_lock_irqsave(&info->card->card_lock, flags); + cnow = info->icount; /* atomic copy */ + spin_unlock_irqrestore(&info->card->card_lock, flags); + + ret = ((arg & TIOCM_RNG) && (cnow.rng != cprev->rng)) || + ((arg & TIOCM_DSR) && (cnow.dsr != cprev->dsr)) || + ((arg & TIOCM_CD) && (cnow.dcd != cprev->dcd)) || + ((arg & TIOCM_CTS) && (cnow.cts != cprev->cts)); + + *cprev = cnow; + + return ret; +} + +/* + * This routine allows the tty driver to implement device- + * specific ioctl's. If the ioctl number passed in cmd is + * not recognized by the driver, it should return ENOIOCTLCMD. + */ +static int +cy_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + struct cyclades_port *info = tty->driver_data; + struct cyclades_icount cnow; /* kernel counter temps */ + int ret_val = 0; + unsigned long flags; + void __user *argp = (void __user *)arg; + + if (serial_paranoia_check(info, tty->name, "cy_ioctl")) + return -ENODEV; + +#ifdef CY_DEBUG_OTHER + printk(KERN_DEBUG "cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n", + info->line, cmd, arg); +#endif + + switch (cmd) { + case CYGETMON: + if (copy_to_user(argp, &info->mon, sizeof(info->mon))) { + ret_val = -EFAULT; + break; + } + memset(&info->mon, 0, sizeof(info->mon)); + break; + case CYGETTHRESH: + ret_val = get_threshold(info, argp); + break; + case CYSETTHRESH: + ret_val = set_threshold(info, arg); + break; + case CYGETDEFTHRESH: + ret_val = put_user(info->default_threshold, + (unsigned long __user *)argp); + break; + case CYSETDEFTHRESH: + info->default_threshold = arg & 0x0f; + break; + case CYGETTIMEOUT: + ret_val = get_timeout(info, argp); + break; + case CYSETTIMEOUT: + ret_val = set_timeout(info, arg); + break; + case CYGETDEFTIMEOUT: + ret_val = put_user(info->default_timeout, + (unsigned long __user *)argp); + break; + case CYSETDEFTIMEOUT: + info->default_timeout = arg & 0xff; + break; + case CYSETRFLOW: + info->rflow = (int)arg; + break; + case CYGETRFLOW: + ret_val = info->rflow; + break; + case CYSETRTSDTR_INV: + info->rtsdtr_inv = (int)arg; + break; + case CYGETRTSDTR_INV: + ret_val = info->rtsdtr_inv; + break; + case CYGETCD1400VER: + ret_val = info->chip_rev; + break; +#ifndef CONFIG_CYZ_INTR + case CYZSETPOLLCYCLE: + cyz_polling_cycle = (arg * HZ) / 1000; + break; + case CYZGETPOLLCYCLE: + ret_val = (cyz_polling_cycle * 1000) / HZ; + break; +#endif /* CONFIG_CYZ_INTR */ + case CYSETWAIT: + info->port.closing_wait = (unsigned short)arg * HZ / 100; + break; + case CYGETWAIT: + ret_val = info->port.closing_wait / (HZ / 100); + break; + case TIOCGSERIAL: + ret_val = cy_get_serial_info(info, argp); + break; + case TIOCSSERIAL: + ret_val = cy_set_serial_info(info, tty, argp); + break; + case TIOCSERGETLSR: /* Get line status register */ + ret_val = get_lsr_info(info, argp); + break; + /* + * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change + * - mask passed in arg for lines of interest + * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) + * Caller should use TIOCGICOUNT to see which one it was + */ + case TIOCMIWAIT: + spin_lock_irqsave(&info->card->card_lock, flags); + /* note the counters on entry */ + cnow = info->icount; + spin_unlock_irqrestore(&info->card->card_lock, flags); + ret_val = wait_event_interruptible(info->port.delta_msr_wait, + cy_cflags_changed(info, arg, &cnow)); + break; + + /* + * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) + * Return: write counters to the user passed counter struct + * NB: both 1->0 and 0->1 transitions are counted except for + * RI where only 0->1 is counted. + */ + default: + ret_val = -ENOIOCTLCMD; + } + +#ifdef CY_DEBUG_OTHER + printk(KERN_DEBUG "cyc:cy_ioctl done\n"); +#endif + return ret_val; +} /* cy_ioctl */ + +static int cy_get_icount(struct tty_struct *tty, + struct serial_icounter_struct *sic) +{ + struct cyclades_port *info = tty->driver_data; + struct cyclades_icount cnow; /* Used to snapshot */ + unsigned long flags; + + spin_lock_irqsave(&info->card->card_lock, flags); + cnow = info->icount; + spin_unlock_irqrestore(&info->card->card_lock, flags); + + sic->cts = cnow.cts; + sic->dsr = cnow.dsr; + sic->rng = cnow.rng; + sic->dcd = cnow.dcd; + sic->rx = cnow.rx; + sic->tx = cnow.tx; + sic->frame = cnow.frame; + sic->overrun = cnow.overrun; + sic->parity = cnow.parity; + sic->brk = cnow.brk; + sic->buf_overrun = cnow.buf_overrun; + return 0; +} + +/* + * This routine allows the tty driver to be notified when + * device's termios settings have changed. Note that a + * well-designed tty driver should be prepared to accept the case + * where old == NULL, and try to do something rational. + */ +static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) +{ + struct cyclades_port *info = tty->driver_data; + +#ifdef CY_DEBUG_OTHER + printk(KERN_DEBUG "cyc:cy_set_termios ttyC%d\n", info->line); +#endif + + cy_set_line_char(info, tty); + + if ((old_termios->c_cflag & CRTSCTS) && + !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + cy_start(tty); + } +#if 0 + /* + * No need to wake up processes in open wait, since they + * sample the CLOCAL flag once, and don't recheck it. + * XXX It's not clear whether the current behavior is correct + * or not. Hence, this may change..... + */ + if (!(old_termios->c_cflag & CLOCAL) && + (tty->termios->c_cflag & CLOCAL)) + wake_up_interruptible(&info->port.open_wait); +#endif +} /* cy_set_termios */ + +/* This function is used to send a high-priority XON/XOFF character to + the device. +*/ +static void cy_send_xchar(struct tty_struct *tty, char ch) +{ + struct cyclades_port *info = tty->driver_data; + struct cyclades_card *card; + int channel; + + if (serial_paranoia_check(info, tty->name, "cy_send_xchar")) + return; + + info->x_char = ch; + + if (ch) + cy_start(tty); + + card = info->card; + channel = info->line - card->first_line; + + if (cy_is_Z(card)) { + if (ch == STOP_CHAR(tty)) + cyz_issue_cmd(card, channel, C_CM_SENDXOFF, 0L); + else if (ch == START_CHAR(tty)) + cyz_issue_cmd(card, channel, C_CM_SENDXON, 0L); + } +} + +/* This routine is called by the upper-layer tty layer to signal + that incoming characters should be throttled because the input + buffers are close to full. + */ +static void cy_throttle(struct tty_struct *tty) +{ + struct cyclades_port *info = tty->driver_data; + struct cyclades_card *card; + unsigned long flags; + +#ifdef CY_DEBUG_THROTTLE + char buf[64]; + + printk(KERN_DEBUG "cyc:throttle %s: %ld...ttyC%d\n", tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty), info->line); +#endif + + if (serial_paranoia_check(info, tty->name, "cy_throttle")) + return; + + card = info->card; + + if (I_IXOFF(tty)) { + if (!cy_is_Z(card)) + cy_send_xchar(tty, STOP_CHAR(tty)); + else + info->throttle = 1; + } + + if (tty->termios->c_cflag & CRTSCTS) { + if (!cy_is_Z(card)) { + spin_lock_irqsave(&card->card_lock, flags); + cyy_change_rts_dtr(info, 0, TIOCM_RTS); + spin_unlock_irqrestore(&card->card_lock, flags); + } else { + info->throttle = 1; + } + } +} /* cy_throttle */ + +/* + * This routine notifies the tty driver that it should signal + * that characters can now be sent to the tty without fear of + * overrunning the input buffers of the line disciplines. + */ +static void cy_unthrottle(struct tty_struct *tty) +{ + struct cyclades_port *info = tty->driver_data; + struct cyclades_card *card; + unsigned long flags; + +#ifdef CY_DEBUG_THROTTLE + char buf[64]; + + printk(KERN_DEBUG "cyc:unthrottle %s: %ld...ttyC%d\n", + tty_name(tty, buf), tty_chars_in_buffer(tty), info->line); +#endif + + if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) + return; + + if (I_IXOFF(tty)) { + if (info->x_char) + info->x_char = 0; + else + cy_send_xchar(tty, START_CHAR(tty)); + } + + if (tty->termios->c_cflag & CRTSCTS) { + card = info->card; + if (!cy_is_Z(card)) { + spin_lock_irqsave(&card->card_lock, flags); + cyy_change_rts_dtr(info, TIOCM_RTS, 0); + spin_unlock_irqrestore(&card->card_lock, flags); + } else { + info->throttle = 0; + } + } +} /* cy_unthrottle */ + +/* cy_start and cy_stop provide software output flow control as a + function of XON/XOFF, software CTS, and other such stuff. +*/ +static void cy_stop(struct tty_struct *tty) +{ + struct cyclades_card *cinfo; + struct cyclades_port *info = tty->driver_data; + int channel; + unsigned long flags; + +#ifdef CY_DEBUG_OTHER + printk(KERN_DEBUG "cyc:cy_stop ttyC%d\n", info->line); +#endif + + if (serial_paranoia_check(info, tty->name, "cy_stop")) + return; + + cinfo = info->card; + channel = info->line - cinfo->first_line; + if (!cy_is_Z(cinfo)) { + spin_lock_irqsave(&cinfo->card_lock, flags); + cyy_writeb(info, CyCAR, channel & 0x03); + cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyTxRdy); + spin_unlock_irqrestore(&cinfo->card_lock, flags); + } +} /* cy_stop */ + +static void cy_start(struct tty_struct *tty) +{ + struct cyclades_card *cinfo; + struct cyclades_port *info = tty->driver_data; + int channel; + unsigned long flags; + +#ifdef CY_DEBUG_OTHER + printk(KERN_DEBUG "cyc:cy_start ttyC%d\n", info->line); +#endif + + if (serial_paranoia_check(info, tty->name, "cy_start")) + return; + + cinfo = info->card; + channel = info->line - cinfo->first_line; + if (!cy_is_Z(cinfo)) { + spin_lock_irqsave(&cinfo->card_lock, flags); + cyy_writeb(info, CyCAR, channel & 0x03); + cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyTxRdy); + spin_unlock_irqrestore(&cinfo->card_lock, flags); + } +} /* cy_start */ + +/* + * cy_hangup() --- called by tty_hangup() when a hangup is signaled. + */ +static void cy_hangup(struct tty_struct *tty) +{ + struct cyclades_port *info = tty->driver_data; + +#ifdef CY_DEBUG_OTHER + printk(KERN_DEBUG "cyc:cy_hangup ttyC%d\n", info->line); +#endif + + if (serial_paranoia_check(info, tty->name, "cy_hangup")) + return; + + cy_flush_buffer(tty); + cy_shutdown(info, tty); + tty_port_hangup(&info->port); +} /* cy_hangup */ + +static int cyy_carrier_raised(struct tty_port *port) +{ + struct cyclades_port *info = container_of(port, struct cyclades_port, + port); + struct cyclades_card *cinfo = info->card; + unsigned long flags; + int channel = info->line - cinfo->first_line; + u32 cd; + + spin_lock_irqsave(&cinfo->card_lock, flags); + cyy_writeb(info, CyCAR, channel & 0x03); + cd = cyy_readb(info, CyMSVR1) & CyDCD; + spin_unlock_irqrestore(&cinfo->card_lock, flags); + + return cd; +} + +static void cyy_dtr_rts(struct tty_port *port, int raise) +{ + struct cyclades_port *info = container_of(port, struct cyclades_port, + port); + struct cyclades_card *cinfo = info->card; + unsigned long flags; + + spin_lock_irqsave(&cinfo->card_lock, flags); + cyy_change_rts_dtr(info, raise ? TIOCM_RTS | TIOCM_DTR : 0, + raise ? 0 : TIOCM_RTS | TIOCM_DTR); + spin_unlock_irqrestore(&cinfo->card_lock, flags); +} + +static int cyz_carrier_raised(struct tty_port *port) +{ + struct cyclades_port *info = container_of(port, struct cyclades_port, + port); + + return readl(&info->u.cyz.ch_ctrl->rs_status) & C_RS_DCD; +} + +static void cyz_dtr_rts(struct tty_port *port, int raise) +{ + struct cyclades_port *info = container_of(port, struct cyclades_port, + port); + struct cyclades_card *cinfo = info->card; + struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl; + int ret, channel = info->line - cinfo->first_line; + u32 rs; + + rs = readl(&ch_ctrl->rs_control); + if (raise) + rs |= C_RS_RTS | C_RS_DTR; + else + rs &= ~(C_RS_RTS | C_RS_DTR); + cy_writel(&ch_ctrl->rs_control, rs); + ret = cyz_issue_cmd(cinfo, channel, C_CM_IOCTLM, 0L); + if (ret != 0) + printk(KERN_ERR "%s: retval on ttyC%d was %x\n", + __func__, info->line, ret); +#ifdef CY_DEBUG_DTR + printk(KERN_DEBUG "%s: raising Z DTR\n", __func__); +#endif +} + +static const struct tty_port_operations cyy_port_ops = { + .carrier_raised = cyy_carrier_raised, + .dtr_rts = cyy_dtr_rts, + .shutdown = cy_do_close, +}; + +static const struct tty_port_operations cyz_port_ops = { + .carrier_raised = cyz_carrier_raised, + .dtr_rts = cyz_dtr_rts, + .shutdown = cy_do_close, +}; + +/* + * --------------------------------------------------------------------- + * cy_init() and friends + * + * cy_init() is called at boot-time to initialize the serial driver. + * --------------------------------------------------------------------- + */ + +static int __devinit cy_init_card(struct cyclades_card *cinfo) +{ + struct cyclades_port *info; + unsigned int channel, port; + + spin_lock_init(&cinfo->card_lock); + cinfo->intr_enabled = 0; + + cinfo->ports = kcalloc(cinfo->nports, sizeof(*cinfo->ports), + GFP_KERNEL); + if (cinfo->ports == NULL) { + printk(KERN_ERR "Cyclades: cannot allocate ports\n"); + return -ENOMEM; + } + + for (channel = 0, port = cinfo->first_line; channel < cinfo->nports; + channel++, port++) { + info = &cinfo->ports[channel]; + tty_port_init(&info->port); + info->magic = CYCLADES_MAGIC; + info->card = cinfo; + info->line = port; + + info->port.closing_wait = CLOSING_WAIT_DELAY; + info->port.close_delay = 5 * HZ / 10; + info->port.flags = STD_COM_FLAGS; + init_completion(&info->shutdown_wait); + + if (cy_is_Z(cinfo)) { + struct FIRM_ID *firm_id = cinfo->base_addr + ID_ADDRESS; + struct ZFW_CTRL *zfw_ctrl; + + info->port.ops = &cyz_port_ops; + info->type = PORT_STARTECH; + + zfw_ctrl = cinfo->base_addr + + (readl(&firm_id->zfwctrl_addr) & 0xfffff); + info->u.cyz.ch_ctrl = &zfw_ctrl->ch_ctrl[channel]; + info->u.cyz.buf_ctrl = &zfw_ctrl->buf_ctrl[channel]; + + if (cinfo->hw_ver == ZO_V1) + info->xmit_fifo_size = CYZ_FIFO_SIZE; + else + info->xmit_fifo_size = 4 * CYZ_FIFO_SIZE; +#ifdef CONFIG_CYZ_INTR + setup_timer(&cyz_rx_full_timer[port], + cyz_rx_restart, (unsigned long)info); +#endif + } else { + unsigned short chip_number; + int index = cinfo->bus_index; + + info->port.ops = &cyy_port_ops; + info->type = PORT_CIRRUS; + info->xmit_fifo_size = CyMAX_CHAR_FIFO; + info->cor1 = CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS; + info->cor2 = CyETC; + info->cor3 = 0x08; /* _very_ small rcv threshold */ + + chip_number = channel / CyPORTS_PER_CHIP; + info->u.cyy.base_addr = cinfo->base_addr + + (cy_chip_offset[chip_number] << index); + info->chip_rev = cyy_readb(info, CyGFRCR); + + if (info->chip_rev >= CD1400_REV_J) { + /* It is a CD1400 rev. J or later */ + info->tbpr = baud_bpr_60[13]; /* Tx BPR */ + info->tco = baud_co_60[13]; /* Tx CO */ + info->rbpr = baud_bpr_60[13]; /* Rx BPR */ + info->rco = baud_co_60[13]; /* Rx CO */ + info->rtsdtr_inv = 1; + } else { + info->tbpr = baud_bpr_25[13]; /* Tx BPR */ + info->tco = baud_co_25[13]; /* Tx CO */ + info->rbpr = baud_bpr_25[13]; /* Rx BPR */ + info->rco = baud_co_25[13]; /* Rx CO */ + info->rtsdtr_inv = 0; + } + info->read_status_mask = CyTIMEOUT | CySPECHAR | + CyBREAK | CyPARITY | CyFRAME | CyOVERRUN; + } + + } + +#ifndef CONFIG_CYZ_INTR + if (cy_is_Z(cinfo) && !timer_pending(&cyz_timerlist)) { + mod_timer(&cyz_timerlist, jiffies + 1); +#ifdef CY_PCI_DEBUG + printk(KERN_DEBUG "Cyclades-Z polling initialized\n"); +#endif + } +#endif + return 0; +} + +/* initialize chips on Cyclom-Y card -- return number of valid + chips (which is number of ports/4) */ +static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr, + int index) +{ + unsigned int chip_number; + void __iomem *base_addr; + + cy_writeb(true_base_addr + (Cy_HwReset << index), 0); + /* Cy_HwReset is 0x1400 */ + cy_writeb(true_base_addr + (Cy_ClrIntr << index), 0); + /* Cy_ClrIntr is 0x1800 */ + udelay(500L); + + for (chip_number = 0; chip_number < CyMAX_CHIPS_PER_CARD; + chip_number++) { + base_addr = + true_base_addr + (cy_chip_offset[chip_number] << index); + mdelay(1); + if (readb(base_addr + (CyCCR << index)) != 0x00) { + /************* + printk(" chip #%d at %#6lx is never idle (CCR != 0)\n", + chip_number, (unsigned long)base_addr); + *************/ + return chip_number; + } + + cy_writeb(base_addr + (CyGFRCR << index), 0); + udelay(10L); + + /* The Cyclom-16Y does not decode address bit 9 and therefore + cannot distinguish between references to chip 0 and a non- + existent chip 4. If the preceding clearing of the supposed + chip 4 GFRCR register appears at chip 0, there is no chip 4 + and this must be a Cyclom-16Y, not a Cyclom-32Ye. + */ + if (chip_number == 4 && readb(true_base_addr + + (cy_chip_offset[0] << index) + + (CyGFRCR << index)) == 0) { + return chip_number; + } + + cy_writeb(base_addr + (CyCCR << index), CyCHIP_RESET); + mdelay(1); + + if (readb(base_addr + (CyGFRCR << index)) == 0x00) { + /* + printk(" chip #%d at %#6lx is not responding ", + chip_number, (unsigned long)base_addr); + printk("(GFRCR stayed 0)\n", + */ + return chip_number; + } + if ((0xf0 & (readb(base_addr + (CyGFRCR << index)))) != + 0x40) { + /* + printk(" chip #%d at %#6lx is not valid (GFRCR == " + "%#2x)\n", + chip_number, (unsigned long)base_addr, + base_addr[CyGFRCR<= CD1400_REV_J) { + /* It is a CD1400 rev. J or later */ + /* Impossible to reach 5ms with this chip. + Changed to 2ms instead (f = 500 Hz). */ + cy_writeb(base_addr + (CyPPR << index), CyCLOCK_60_2MS); + } else { + /* f = 200 Hz */ + cy_writeb(base_addr + (CyPPR << index), CyCLOCK_25_5MS); + } + + /* + printk(" chip #%d at %#6lx is rev 0x%2x\n", + chip_number, (unsigned long)base_addr, + readb(base_addr+(CyGFRCR< NR_PORTS) { + printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no " + "more channels are available. Change NR_PORTS " + "in cyclades.c and recompile kernel.\n", + (unsigned long)cy_isa_address); + iounmap(cy_isa_address); + return nboard; + } + /* fill the next cy_card structure available */ + for (j = 0; j < NR_CARDS; j++) { + if (cy_card[j].base_addr == NULL) + break; + } + if (j == NR_CARDS) { /* no more cy_cards available */ + printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no " + "more cards can be used. Change NR_CARDS in " + "cyclades.c and recompile kernel.\n", + (unsigned long)cy_isa_address); + iounmap(cy_isa_address); + return nboard; + } + + /* allocate IRQ */ + if (request_irq(cy_isa_irq, cyy_interrupt, + IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) { + printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but " + "could not allocate IRQ#%d.\n", + (unsigned long)cy_isa_address, cy_isa_irq); + iounmap(cy_isa_address); + return nboard; + } + + /* set cy_card */ + cy_card[j].base_addr = cy_isa_address; + cy_card[j].ctl_addr.p9050 = NULL; + cy_card[j].irq = (int)cy_isa_irq; + cy_card[j].bus_index = 0; + cy_card[j].first_line = cy_next_channel; + cy_card[j].num_chips = cy_isa_nchan / CyPORTS_PER_CHIP; + cy_card[j].nports = cy_isa_nchan; + if (cy_init_card(&cy_card[j])) { + cy_card[j].base_addr = NULL; + free_irq(cy_isa_irq, &cy_card[j]); + iounmap(cy_isa_address); + continue; + } + nboard++; + + printk(KERN_INFO "Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d found: " + "%d channels starting from port %d\n", + j + 1, (unsigned long)cy_isa_address, + (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)), + cy_isa_irq, cy_isa_nchan, cy_next_channel); + + for (j = cy_next_channel; + j < cy_next_channel + cy_isa_nchan; j++) + tty_register_device(cy_serial_driver, j, NULL); + cy_next_channel += cy_isa_nchan; + } + return nboard; +#else + return 0; +#endif /* CONFIG_ISA */ +} /* cy_detect_isa */ + +#ifdef CONFIG_PCI +static inline int __devinit cyc_isfwstr(const char *str, unsigned int size) +{ + unsigned int a; + + for (a = 0; a < size && *str; a++, str++) + if (*str & 0x80) + return -EINVAL; + + for (; a < size; a++, str++) + if (*str) + return -EINVAL; + + return 0; +} + +static inline void __devinit cyz_fpga_copy(void __iomem *fpga, const u8 *data, + unsigned int size) +{ + for (; size > 0; size--) { + cy_writel(fpga, *data++); + udelay(10); + } +} + +static void __devinit plx_init(struct pci_dev *pdev, int irq, + struct RUNTIME_9060 __iomem *addr) +{ + /* Reset PLX */ + cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) | 0x40000000); + udelay(100L); + cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) & ~0x40000000); + + /* Reload Config. Registers from EEPROM */ + cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) | 0x20000000); + udelay(100L); + cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) & ~0x20000000); + + /* For some yet unknown reason, once the PLX9060 reloads the EEPROM, + * the IRQ is lost and, thus, we have to re-write it to the PCI config. + * registers. This will remain here until we find a permanent fix. + */ + pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq); +} + +static int __devinit __cyz_load_fw(const struct firmware *fw, + const char *name, const u32 mailbox, void __iomem *base, + void __iomem *fpga) +{ + const void *ptr = fw->data; + const struct zfile_header *h = ptr; + const struct zfile_config *c, *cs; + const struct zfile_block *b, *bs; + unsigned int a, tmp, len = fw->size; +#define BAD_FW KERN_ERR "Bad firmware: " + if (len < sizeof(*h)) { + printk(BAD_FW "too short: %u<%zu\n", len, sizeof(*h)); + return -EINVAL; + } + + cs = ptr + h->config_offset; + bs = ptr + h->block_offset; + + if ((void *)(cs + h->n_config) > ptr + len || + (void *)(bs + h->n_blocks) > ptr + len) { + printk(BAD_FW "too short"); + return -EINVAL; + } + + if (cyc_isfwstr(h->name, sizeof(h->name)) || + cyc_isfwstr(h->date, sizeof(h->date))) { + printk(BAD_FW "bad formatted header string\n"); + return -EINVAL; + } + + if (strncmp(name, h->name, sizeof(h->name))) { + printk(BAD_FW "bad name '%s' (expected '%s')\n", h->name, name); + return -EINVAL; + } + + tmp = 0; + for (c = cs; c < cs + h->n_config; c++) { + for (a = 0; a < c->n_blocks; a++) + if (c->block_list[a] > h->n_blocks) { + printk(BAD_FW "bad block ref number in cfgs\n"); + return -EINVAL; + } + if (c->mailbox == mailbox && c->function == 0) /* 0 is normal */ + tmp++; + } + if (!tmp) { + printk(BAD_FW "nothing appropriate\n"); + return -EINVAL; + } + + for (b = bs; b < bs + h->n_blocks; b++) + if (b->file_offset + b->size > len) { + printk(BAD_FW "bad block data offset\n"); + return -EINVAL; + } + + /* everything is OK, let's seek'n'load it */ + for (c = cs; c < cs + h->n_config; c++) + if (c->mailbox == mailbox && c->function == 0) + break; + + for (a = 0; a < c->n_blocks; a++) { + b = &bs[c->block_list[a]]; + if (b->type == ZBLOCK_FPGA) { + if (fpga != NULL) + cyz_fpga_copy(fpga, ptr + b->file_offset, + b->size); + } else { + if (base != NULL) + memcpy_toio(base + b->ram_offset, + ptr + b->file_offset, b->size); + } + } +#undef BAD_FW + return 0; +} + +static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr, + struct RUNTIME_9060 __iomem *ctl_addr, int irq) +{ + const struct firmware *fw; + struct FIRM_ID __iomem *fid = base_addr + ID_ADDRESS; + struct CUSTOM_REG __iomem *cust = base_addr; + struct ZFW_CTRL __iomem *pt_zfwctrl; + void __iomem *tmp; + u32 mailbox, status, nchan; + unsigned int i; + int retval; + + retval = request_firmware(&fw, "cyzfirm.bin", &pdev->dev); + if (retval) { + dev_err(&pdev->dev, "can't get firmware\n"); + goto err; + } + + /* Check whether the firmware is already loaded and running. If + positive, skip this board */ + if (__cyz_fpga_loaded(ctl_addr) && readl(&fid->signature) == ZFIRM_ID) { + u32 cntval = readl(base_addr + 0x190); + + udelay(100); + if (cntval != readl(base_addr + 0x190)) { + /* FW counter is working, FW is running */ + dev_dbg(&pdev->dev, "Cyclades-Z FW already loaded. " + "Skipping board.\n"); + retval = 0; + goto err_rel; + } + } + + /* start boot */ + cy_writel(&ctl_addr->intr_ctrl_stat, readl(&ctl_addr->intr_ctrl_stat) & + ~0x00030800UL); + + mailbox = readl(&ctl_addr->mail_box_0); + + if (mailbox == 0 || __cyz_fpga_loaded(ctl_addr)) { + /* stops CPU and set window to beginning of RAM */ + cy_writel(&ctl_addr->loc_addr_base, WIN_CREG); + cy_writel(&cust->cpu_stop, 0); + cy_writel(&ctl_addr->loc_addr_base, WIN_RAM); + udelay(100); + } + + plx_init(pdev, irq, ctl_addr); + + if (mailbox != 0) { + /* load FPGA */ + retval = __cyz_load_fw(fw, "Cyclom-Z", mailbox, NULL, + base_addr); + if (retval) + goto err_rel; + if (!__cyz_fpga_loaded(ctl_addr)) { + dev_err(&pdev->dev, "fw upload successful, but fw is " + "not loaded\n"); + goto err_rel; + } + } + + /* stops CPU and set window to beginning of RAM */ + cy_writel(&ctl_addr->loc_addr_base, WIN_CREG); + cy_writel(&cust->cpu_stop, 0); + cy_writel(&ctl_addr->loc_addr_base, WIN_RAM); + udelay(100); + + /* clear memory */ + for (tmp = base_addr; tmp < base_addr + RAM_SIZE; tmp++) + cy_writeb(tmp, 255); + if (mailbox != 0) { + /* set window to last 512K of RAM */ + cy_writel(&ctl_addr->loc_addr_base, WIN_RAM + RAM_SIZE); + for (tmp = base_addr; tmp < base_addr + RAM_SIZE; tmp++) + cy_writeb(tmp, 255); + /* set window to beginning of RAM */ + cy_writel(&ctl_addr->loc_addr_base, WIN_RAM); + } + + retval = __cyz_load_fw(fw, "Cyclom-Z", mailbox, base_addr, NULL); + release_firmware(fw); + if (retval) + goto err; + + /* finish boot and start boards */ + cy_writel(&ctl_addr->loc_addr_base, WIN_CREG); + cy_writel(&cust->cpu_start, 0); + cy_writel(&ctl_addr->loc_addr_base, WIN_RAM); + i = 0; + while ((status = readl(&fid->signature)) != ZFIRM_ID && i++ < 40) + msleep(100); + if (status != ZFIRM_ID) { + if (status == ZFIRM_HLT) { + dev_err(&pdev->dev, "you need an external power supply " + "for this number of ports. Firmware halted and " + "board reset.\n"); + retval = -EIO; + goto err; + } + dev_warn(&pdev->dev, "fid->signature = 0x%x... Waiting " + "some more time\n", status); + while ((status = readl(&fid->signature)) != ZFIRM_ID && + i++ < 200) + msleep(100); + if (status != ZFIRM_ID) { + dev_err(&pdev->dev, "Board not started in 20 seconds! " + "Giving up. (fid->signature = 0x%x)\n", + status); + dev_info(&pdev->dev, "*** Warning ***: if you are " + "upgrading the FW, please power cycle the " + "system before loading the new FW to the " + "Cyclades-Z.\n"); + + if (__cyz_fpga_loaded(ctl_addr)) + plx_init(pdev, irq, ctl_addr); + + retval = -EIO; + goto err; + } + dev_dbg(&pdev->dev, "Firmware started after %d seconds.\n", + i / 10); + } + pt_zfwctrl = base_addr + readl(&fid->zfwctrl_addr); + + dev_dbg(&pdev->dev, "fid=> %p, zfwctrl_addr=> %x, npt_zfwctrl=> %p\n", + base_addr + ID_ADDRESS, readl(&fid->zfwctrl_addr), + base_addr + readl(&fid->zfwctrl_addr)); + + nchan = readl(&pt_zfwctrl->board_ctrl.n_channel); + dev_info(&pdev->dev, "Cyclades-Z FW loaded: version = %x, ports = %u\n", + readl(&pt_zfwctrl->board_ctrl.fw_version), nchan); + + if (nchan == 0) { + dev_warn(&pdev->dev, "no Cyclades-Z ports were found. Please " + "check the connection between the Z host card and the " + "serial expanders.\n"); + + if (__cyz_fpga_loaded(ctl_addr)) + plx_init(pdev, irq, ctl_addr); + + dev_info(&pdev->dev, "Null number of ports detected. Board " + "reset.\n"); + retval = 0; + goto err; + } + + cy_writel(&pt_zfwctrl->board_ctrl.op_system, C_OS_LINUX); + cy_writel(&pt_zfwctrl->board_ctrl.dr_version, DRIVER_VERSION); + + /* + Early firmware failed to start looking for commands. + This enables firmware interrupts for those commands. + */ + cy_writel(&ctl_addr->intr_ctrl_stat, readl(&ctl_addr->intr_ctrl_stat) | + (1 << 17)); + cy_writel(&ctl_addr->intr_ctrl_stat, readl(&ctl_addr->intr_ctrl_stat) | + 0x00030800UL); + + return nchan; +err_rel: + release_firmware(fw); +err: + return retval; +} + +static int __devinit cy_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + void __iomem *addr0 = NULL, *addr2 = NULL; + char *card_name = NULL; + u32 uninitialized_var(mailbox); + unsigned int device_id, nchan = 0, card_no, i; + unsigned char plx_ver; + int retval, irq; + + retval = pci_enable_device(pdev); + if (retval) { + dev_err(&pdev->dev, "cannot enable device\n"); + goto err; + } + + /* read PCI configuration area */ + irq = pdev->irq; + device_id = pdev->device & ~PCI_DEVICE_ID_MASK; + +#if defined(__alpha__) + if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */ + dev_err(&pdev->dev, "Cyclom-Y/PCI not supported for low " + "addresses on Alpha systems.\n"); + retval = -EIO; + goto err_dis; + } +#endif + if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) { + dev_err(&pdev->dev, "Cyclades-Z/PCI not supported for low " + "addresses\n"); + retval = -EIO; + goto err_dis; + } + + if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { + dev_warn(&pdev->dev, "PCI I/O bit incorrectly set. Ignoring " + "it...\n"); + pdev->resource[2].flags &= ~IORESOURCE_IO; + } + + retval = pci_request_regions(pdev, "cyclades"); + if (retval) { + dev_err(&pdev->dev, "failed to reserve resources\n"); + goto err_dis; + } + + retval = -EIO; + if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || + device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { + card_name = "Cyclom-Y"; + + addr0 = ioremap_nocache(pci_resource_start(pdev, 0), + CyPCI_Yctl); + if (addr0 == NULL) { + dev_err(&pdev->dev, "can't remap ctl region\n"); + goto err_reg; + } + addr2 = ioremap_nocache(pci_resource_start(pdev, 2), + CyPCI_Ywin); + if (addr2 == NULL) { + dev_err(&pdev->dev, "can't remap base region\n"); + goto err_unmap; + } + + nchan = CyPORTS_PER_CHIP * cyy_init_card(addr2, 1); + if (nchan == 0) { + dev_err(&pdev->dev, "Cyclom-Y PCI host card with no " + "Serial-Modules\n"); + goto err_unmap; + } + } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) { + struct RUNTIME_9060 __iomem *ctl_addr; + + ctl_addr = addr0 = ioremap_nocache(pci_resource_start(pdev, 0), + CyPCI_Zctl); + if (addr0 == NULL) { + dev_err(&pdev->dev, "can't remap ctl region\n"); + goto err_reg; + } + + /* Disable interrupts on the PLX before resetting it */ + cy_writew(&ctl_addr->intr_ctrl_stat, + readw(&ctl_addr->intr_ctrl_stat) & ~0x0900); + + plx_init(pdev, irq, addr0); + + mailbox = readl(&ctl_addr->mail_box_0); + + addr2 = ioremap_nocache(pci_resource_start(pdev, 2), + mailbox == ZE_V1 ? CyPCI_Ze_win : CyPCI_Zwin); + if (addr2 == NULL) { + dev_err(&pdev->dev, "can't remap base region\n"); + goto err_unmap; + } + + if (mailbox == ZE_V1) { + card_name = "Cyclades-Ze"; + } else { + card_name = "Cyclades-8Zo"; +#ifdef CY_PCI_DEBUG + if (mailbox == ZO_V1) { + cy_writel(&ctl_addr->loc_addr_base, WIN_CREG); + dev_info(&pdev->dev, "Cyclades-8Zo/PCI: FPGA " + "id %lx, ver %lx\n", (ulong)(0xff & + readl(&((struct CUSTOM_REG *)addr2)-> + fpga_id)), (ulong)(0xff & + readl(&((struct CUSTOM_REG *)addr2)-> + fpga_version))); + cy_writel(&ctl_addr->loc_addr_base, WIN_RAM); + } else { + dev_info(&pdev->dev, "Cyclades-Z/PCI: New " + "Cyclades-Z board. FPGA not loaded\n"); + } +#endif + /* The following clears the firmware id word. This + ensures that the driver will not attempt to talk to + the board until it has been properly initialized. + */ + if ((mailbox == ZO_V1) || (mailbox == ZO_V2)) + cy_writel(addr2 + ID_ADDRESS, 0L); + } + + retval = cyz_load_fw(pdev, addr2, addr0, irq); + if (retval <= 0) + goto err_unmap; + nchan = retval; + } + + if ((cy_next_channel + nchan) > NR_PORTS) { + dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no " + "channels are available. Change NR_PORTS in " + "cyclades.c and recompile kernel.\n"); + goto err_unmap; + } + /* fill the next cy_card structure available */ + for (card_no = 0; card_no < NR_CARDS; card_no++) { + if (cy_card[card_no].base_addr == NULL) + break; + } + if (card_no == NR_CARDS) { /* no more cy_cards available */ + dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no " + "more cards can be used. Change NR_CARDS in " + "cyclades.c and recompile kernel.\n"); + goto err_unmap; + } + + if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || + device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { + /* allocate IRQ */ + retval = request_irq(irq, cyy_interrupt, + IRQF_SHARED, "Cyclom-Y", &cy_card[card_no]); + if (retval) { + dev_err(&pdev->dev, "could not allocate IRQ\n"); + goto err_unmap; + } + cy_card[card_no].num_chips = nchan / CyPORTS_PER_CHIP; + } else { + struct FIRM_ID __iomem *firm_id = addr2 + ID_ADDRESS; + struct ZFW_CTRL __iomem *zfw_ctrl; + + zfw_ctrl = addr2 + (readl(&firm_id->zfwctrl_addr) & 0xfffff); + + cy_card[card_no].hw_ver = mailbox; + cy_card[card_no].num_chips = (unsigned int)-1; + cy_card[card_no].board_ctrl = &zfw_ctrl->board_ctrl; +#ifdef CONFIG_CYZ_INTR + /* allocate IRQ only if board has an IRQ */ + if (irq != 0 && irq != 255) { + retval = request_irq(irq, cyz_interrupt, + IRQF_SHARED, "Cyclades-Z", + &cy_card[card_no]); + if (retval) { + dev_err(&pdev->dev, "could not allocate IRQ\n"); + goto err_unmap; + } + } +#endif /* CONFIG_CYZ_INTR */ + } + + /* set cy_card */ + cy_card[card_no].base_addr = addr2; + cy_card[card_no].ctl_addr.p9050 = addr0; + cy_card[card_no].irq = irq; + cy_card[card_no].bus_index = 1; + cy_card[card_no].first_line = cy_next_channel; + cy_card[card_no].nports = nchan; + retval = cy_init_card(&cy_card[card_no]); + if (retval) + goto err_null; + + pci_set_drvdata(pdev, &cy_card[card_no]); + + if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || + device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { + /* enable interrupts in the PCI interface */ + plx_ver = readb(addr2 + CyPLX_VER) & 0x0f; + switch (plx_ver) { + case PLX_9050: + cy_writeb(addr0 + 0x4c, 0x43); + break; + + case PLX_9060: + case PLX_9080: + default: /* Old boards, use PLX_9060 */ + { + struct RUNTIME_9060 __iomem *ctl_addr = addr0; + plx_init(pdev, irq, ctl_addr); + cy_writew(&ctl_addr->intr_ctrl_stat, + readw(&ctl_addr->intr_ctrl_stat) | 0x0900); + break; + } + } + } + + dev_info(&pdev->dev, "%s/PCI #%d found: %d channels starting from " + "port %d.\n", card_name, card_no + 1, nchan, cy_next_channel); + for (i = cy_next_channel; i < cy_next_channel + nchan; i++) + tty_register_device(cy_serial_driver, i, &pdev->dev); + cy_next_channel += nchan; + + return 0; +err_null: + cy_card[card_no].base_addr = NULL; + free_irq(irq, &cy_card[card_no]); +err_unmap: + iounmap(addr0); + if (addr2) + iounmap(addr2); +err_reg: + pci_release_regions(pdev); +err_dis: + pci_disable_device(pdev); +err: + return retval; +} + +static void __devexit cy_pci_remove(struct pci_dev *pdev) +{ + struct cyclades_card *cinfo = pci_get_drvdata(pdev); + unsigned int i; + + /* non-Z with old PLX */ + if (!cy_is_Z(cinfo) && (readb(cinfo->base_addr + CyPLX_VER) & 0x0f) == + PLX_9050) + cy_writeb(cinfo->ctl_addr.p9050 + 0x4c, 0); + else +#ifndef CONFIG_CYZ_INTR + if (!cy_is_Z(cinfo)) +#endif + cy_writew(&cinfo->ctl_addr.p9060->intr_ctrl_stat, + readw(&cinfo->ctl_addr.p9060->intr_ctrl_stat) & + ~0x0900); + + iounmap(cinfo->base_addr); + if (cinfo->ctl_addr.p9050) + iounmap(cinfo->ctl_addr.p9050); + if (cinfo->irq +#ifndef CONFIG_CYZ_INTR + && !cy_is_Z(cinfo) +#endif /* CONFIG_CYZ_INTR */ + ) + free_irq(cinfo->irq, cinfo); + pci_release_regions(pdev); + + cinfo->base_addr = NULL; + for (i = cinfo->first_line; i < cinfo->first_line + + cinfo->nports; i++) + tty_unregister_device(cy_serial_driver, i); + cinfo->nports = 0; + kfree(cinfo->ports); +} + +static struct pci_driver cy_pci_driver = { + .name = "cyclades", + .id_table = cy_pci_dev_id, + .probe = cy_pci_probe, + .remove = __devexit_p(cy_pci_remove) +}; +#endif + +static int cyclades_proc_show(struct seq_file *m, void *v) +{ + struct cyclades_port *info; + unsigned int i, j; + __u32 cur_jifs = jiffies; + + seq_puts(m, "Dev TimeOpen BytesOut IdleOut BytesIn " + "IdleIn Overruns Ldisc\n"); + + /* Output one line for each known port */ + for (i = 0; i < NR_CARDS; i++) + for (j = 0; j < cy_card[i].nports; j++) { + info = &cy_card[i].ports[j]; + + if (info->port.count) { + /* XXX is the ldisc num worth this? */ + struct tty_struct *tty; + struct tty_ldisc *ld; + int num = 0; + tty = tty_port_tty_get(&info->port); + if (tty) { + ld = tty_ldisc_ref(tty); + if (ld) { + num = ld->ops->num; + tty_ldisc_deref(ld); + } + tty_kref_put(tty); + } + seq_printf(m, "%3d %8lu %10lu %8lu " + "%10lu %8lu %9lu %6d\n", info->line, + (cur_jifs - info->idle_stats.in_use) / + HZ, info->idle_stats.xmit_bytes, + (cur_jifs - info->idle_stats.xmit_idle)/ + HZ, info->idle_stats.recv_bytes, + (cur_jifs - info->idle_stats.recv_idle)/ + HZ, info->idle_stats.overruns, + num); + } else + seq_printf(m, "%3d %8lu %10lu %8lu " + "%10lu %8lu %9lu %6ld\n", + info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L); + } + return 0; +} + +static int cyclades_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, cyclades_proc_show, NULL); +} + +static const struct file_operations cyclades_proc_fops = { + .owner = THIS_MODULE, + .open = cyclades_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* The serial driver boot-time initialization code! + Hardware I/O ports are mapped to character special devices on a + first found, first allocated manner. That is, this code searches + for Cyclom cards in the system. As each is found, it is probed + to discover how many chips (and thus how many ports) are present. + These ports are mapped to the tty ports 32 and upward in monotonic + fashion. If an 8-port card is replaced with a 16-port card, the + port mapping on a following card will shift. + + This approach is different from what is used in the other serial + device driver because the Cyclom is more properly a multiplexer, + not just an aggregation of serial ports on one card. + + If there are more cards with more ports than have been + statically allocated above, a warning is printed and the + extra ports are ignored. + */ + +static const struct tty_operations cy_ops = { + .open = cy_open, + .close = cy_close, + .write = cy_write, + .put_char = cy_put_char, + .flush_chars = cy_flush_chars, + .write_room = cy_write_room, + .chars_in_buffer = cy_chars_in_buffer, + .flush_buffer = cy_flush_buffer, + .ioctl = cy_ioctl, + .throttle = cy_throttle, + .unthrottle = cy_unthrottle, + .set_termios = cy_set_termios, + .stop = cy_stop, + .start = cy_start, + .hangup = cy_hangup, + .break_ctl = cy_break, + .wait_until_sent = cy_wait_until_sent, + .tiocmget = cy_tiocmget, + .tiocmset = cy_tiocmset, + .get_icount = cy_get_icount, + .proc_fops = &cyclades_proc_fops, +}; + +static int __init cy_init(void) +{ + unsigned int nboards; + int retval = -ENOMEM; + + cy_serial_driver = alloc_tty_driver(NR_PORTS); + if (!cy_serial_driver) + goto err; + + printk(KERN_INFO "Cyclades driver " CY_VERSION " (built %s %s)\n", + __DATE__, __TIME__); + + /* Initialize the tty_driver structure */ + + cy_serial_driver->owner = THIS_MODULE; + cy_serial_driver->driver_name = "cyclades"; + cy_serial_driver->name = "ttyC"; + cy_serial_driver->major = CYCLADES_MAJOR; + cy_serial_driver->minor_start = 0; + cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL; + cy_serial_driver->subtype = SERIAL_TYPE_NORMAL; + cy_serial_driver->init_termios = tty_std_termios; + cy_serial_driver->init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + cy_serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + tty_set_operations(cy_serial_driver, &cy_ops); + + retval = tty_register_driver(cy_serial_driver); + if (retval) { + printk(KERN_ERR "Couldn't register Cyclades serial driver\n"); + goto err_frtty; + } + + /* the code below is responsible to find the boards. Each different + type of board has its own detection routine. If a board is found, + the next cy_card structure available is set by the detection + routine. These functions are responsible for checking the + availability of cy_card and cy_port data structures and updating + the cy_next_channel. */ + + /* look for isa boards */ + nboards = cy_detect_isa(); + +#ifdef CONFIG_PCI + /* look for pci boards */ + retval = pci_register_driver(&cy_pci_driver); + if (retval && !nboards) { + tty_unregister_driver(cy_serial_driver); + goto err_frtty; + } +#endif + + return 0; +err_frtty: + put_tty_driver(cy_serial_driver); +err: + return retval; +} /* cy_init */ + +static void __exit cy_cleanup_module(void) +{ + struct cyclades_card *card; + unsigned int i, e1; + +#ifndef CONFIG_CYZ_INTR + del_timer_sync(&cyz_timerlist); +#endif /* CONFIG_CYZ_INTR */ + + e1 = tty_unregister_driver(cy_serial_driver); + if (e1) + printk(KERN_ERR "failed to unregister Cyclades serial " + "driver(%d)\n", e1); + +#ifdef CONFIG_PCI + pci_unregister_driver(&cy_pci_driver); +#endif + + for (i = 0; i < NR_CARDS; i++) { + card = &cy_card[i]; + if (card->base_addr) { + /* clear interrupt */ + cy_writeb(card->base_addr + Cy_ClrIntr, 0); + iounmap(card->base_addr); + if (card->ctl_addr.p9050) + iounmap(card->ctl_addr.p9050); + if (card->irq +#ifndef CONFIG_CYZ_INTR + && !cy_is_Z(card) +#endif /* CONFIG_CYZ_INTR */ + ) + free_irq(card->irq, card); + for (e1 = card->first_line; e1 < card->first_line + + card->nports; e1++) + tty_unregister_device(cy_serial_driver, e1); + kfree(card->ports); + } + } + + put_tty_driver(cy_serial_driver); +} /* cy_cleanup_module */ + +module_init(cy_init); +module_exit(cy_cleanup_module); + +MODULE_LICENSE("GPL"); +MODULE_VERSION(CY_VERSION); +MODULE_ALIAS_CHARDEV_MAJOR(CYCLADES_MAJOR); +MODULE_FIRMWARE("cyzfirm.bin"); diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c new file mode 100644 index 000000000000..db1cf9c328d8 --- /dev/null +++ b/drivers/tty/isicom.c @@ -0,0 +1,1736 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Original driver code supplied by Multi-Tech + * + * Changes + * 1/9/98 alan@lxorguk.ukuu.org.uk + * Merge to 2.0.x kernel tree + * Obtain and use official major/minors + * Loader switched to a misc device + * (fixed range check bug as a side effect) + * Printk clean up + * 9/12/98 alan@lxorguk.ukuu.org.uk + * Rough port to 2.1.x + * + * 10/6/99 sameer Merged the ISA and PCI drivers to + * a new unified driver. + * + * 3/9/99 sameer Added support for ISI4616 cards. + * + * 16/9/99 sameer We do not force RTS low anymore. + * This is to prevent the firmware + * from getting confused. + * + * 26/10/99 sameer Cosmetic changes:The driver now + * dumps the Port Count information + * along with I/O address and IRQ. + * + * 13/12/99 sameer Fixed the problem with IRQ sharing. + * + * 10/5/00 sameer Fixed isicom_shutdown_board() + * to not lower DTR on all the ports + * when the last port on the card is + * closed. + * + * 10/5/00 sameer Signal mask setup command added + * to isicom_setup_port and + * isicom_shutdown_port. + * + * 24/5/00 sameer The driver is now SMP aware. + * + * + * 27/11/00 Vinayak P Risbud Fixed the Driver Crash Problem + * + * + * 03/01/01 anil .s Added support for resetting the + * internal modems on ISI cards. + * + * 08/02/01 anil .s Upgraded the driver for kernel + * 2.4.x + * + * 11/04/01 Kevin Fixed firmware load problem with + * ISIHP-4X card + * + * 30/04/01 anil .s Fixed the remote login through + * ISI port problem. Now the link + * does not go down before password + * prompt. + * + * 03/05/01 anil .s Fixed the problem with IRQ sharing + * among ISI-PCI cards. + * + * 03/05/01 anil .s Added support to display the version + * info during insmod as well as module + * listing by lsmod. + * + * 10/05/01 anil .s Done the modifications to the source + * file and Install script so that the + * same installation can be used for + * 2.2.x and 2.4.x kernel. + * + * 06/06/01 anil .s Now we drop both dtr and rts during + * shutdown_port as well as raise them + * during isicom_config_port. + * + * 09/06/01 acme@conectiva.com.br use capable, not suser, do + * restore_flags on failure in + * isicom_send_break, verify put_user + * result + * + * 11/02/03 ranjeeth Added support for 230 Kbps and 460 Kbps + * Baud index extended to 21 + * + * 20/03/03 ranjeeth Made to work for Linux Advanced server. + * Taken care of license warning. + * + * 10/12/03 Ravindra Made to work for Fedora Core 1 of + * Red Hat Distribution + * + * 06/01/05 Alan Cox Merged the ISI and base kernel strands + * into a single 2.6 driver + * + * *********************************************************** + * + * To use this driver you also need the support package. You + * can find this in RPM format on + * ftp://ftp.linux.org.uk/pub/linux/alan + * + * You can find the original tools for this direct from Multitech + * ftp://ftp.multitech.com/ISI-Cards/ + * + * Having installed the cards the module options (/etc/modprobe.conf) + * + * options isicom io=card1,card2,card3,card4 irq=card1,card2,card3,card4 + * + * Omit those entries for boards you don't have installed. + * + * TODO + * Merge testing + * 64-bit verification + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#define InterruptTheCard(base) outw(0, (base) + 0xc) +#define ClearInterrupt(base) inw((base) + 0x0a) + +#ifdef DEBUG +#define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c)) +#else +#define isicom_paranoia_check(a, b, c) 0 +#endif + +static int isicom_probe(struct pci_dev *, const struct pci_device_id *); +static void __devexit isicom_remove(struct pci_dev *); + +static struct pci_device_id isicom_pci_tbl[] = { + { PCI_DEVICE(VENDOR_ID, 0x2028) }, + { PCI_DEVICE(VENDOR_ID, 0x2051) }, + { PCI_DEVICE(VENDOR_ID, 0x2052) }, + { PCI_DEVICE(VENDOR_ID, 0x2053) }, + { PCI_DEVICE(VENDOR_ID, 0x2054) }, + { PCI_DEVICE(VENDOR_ID, 0x2055) }, + { PCI_DEVICE(VENDOR_ID, 0x2056) }, + { PCI_DEVICE(VENDOR_ID, 0x2057) }, + { PCI_DEVICE(VENDOR_ID, 0x2058) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, isicom_pci_tbl); + +static struct pci_driver isicom_driver = { + .name = "isicom", + .id_table = isicom_pci_tbl, + .probe = isicom_probe, + .remove = __devexit_p(isicom_remove) +}; + +static int prev_card = 3; /* start servicing isi_card[0] */ +static struct tty_driver *isicom_normal; + +static void isicom_tx(unsigned long _data); +static void isicom_start(struct tty_struct *tty); + +static DEFINE_TIMER(tx, isicom_tx, 0, 0); + +/* baud index mappings from linux defns to isi */ + +static signed char linuxb_to_isib[] = { + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19, 20, 21 +}; + +struct isi_board { + unsigned long base; + int irq; + unsigned char port_count; + unsigned short status; + unsigned short port_status; /* each bit for each port */ + unsigned short shift_count; + struct isi_port *ports; + signed char count; + spinlock_t card_lock; /* Card wide lock 11/5/00 -sameer */ + unsigned long flags; + unsigned int index; +}; + +struct isi_port { + unsigned short magic; + struct tty_port port; + u16 channel; + u16 status; + struct isi_board *card; + unsigned char *xmit_buf; + int xmit_head; + int xmit_tail; + int xmit_cnt; +}; + +static struct isi_board isi_card[BOARD_COUNT]; +static struct isi_port isi_ports[PORT_COUNT]; + +/* + * Locking functions for card level locking. We need to own both + * the kernel lock for the card and have the card in a position that + * it wants to talk. + */ + +static inline int WaitTillCardIsFree(unsigned long base) +{ + unsigned int count = 0; + unsigned int a = in_atomic(); /* do we run under spinlock? */ + + while (!(inw(base + 0xe) & 0x1) && count++ < 100) + if (a) + mdelay(1); + else + msleep(1); + + return !(inw(base + 0xe) & 0x1); +} + +static int lock_card(struct isi_board *card) +{ + unsigned long base = card->base; + unsigned int retries, a; + + for (retries = 0; retries < 10; retries++) { + spin_lock_irqsave(&card->card_lock, card->flags); + for (a = 0; a < 10; a++) { + if (inw(base + 0xe) & 0x1) + return 1; + udelay(10); + } + spin_unlock_irqrestore(&card->card_lock, card->flags); + msleep(10); + } + pr_warning("Failed to lock Card (0x%lx)\n", card->base); + + return 0; /* Failed to acquire the card! */ +} + +static void unlock_card(struct isi_board *card) +{ + spin_unlock_irqrestore(&card->card_lock, card->flags); +} + +/* + * ISI Card specific ops ... + */ + +/* card->lock HAS to be held */ +static void raise_dtr(struct isi_port *port) +{ + struct isi_board *card = port->card; + unsigned long base = card->base; + u16 channel = port->channel; + + if (WaitTillCardIsFree(base)) + return; + + outw(0x8000 | (channel << card->shift_count) | 0x02, base); + outw(0x0504, base); + InterruptTheCard(base); + port->status |= ISI_DTR; +} + +/* card->lock HAS to be held */ +static inline void drop_dtr(struct isi_port *port) +{ + struct isi_board *card = port->card; + unsigned long base = card->base; + u16 channel = port->channel; + + if (WaitTillCardIsFree(base)) + return; + + outw(0x8000 | (channel << card->shift_count) | 0x02, base); + outw(0x0404, base); + InterruptTheCard(base); + port->status &= ~ISI_DTR; +} + +/* card->lock HAS to be held */ +static inline void raise_rts(struct isi_port *port) +{ + struct isi_board *card = port->card; + unsigned long base = card->base; + u16 channel = port->channel; + + if (WaitTillCardIsFree(base)) + return; + + outw(0x8000 | (channel << card->shift_count) | 0x02, base); + outw(0x0a04, base); + InterruptTheCard(base); + port->status |= ISI_RTS; +} + +/* card->lock HAS to be held */ +static inline void drop_rts(struct isi_port *port) +{ + struct isi_board *card = port->card; + unsigned long base = card->base; + u16 channel = port->channel; + + if (WaitTillCardIsFree(base)) + return; + + outw(0x8000 | (channel << card->shift_count) | 0x02, base); + outw(0x0804, base); + InterruptTheCard(base); + port->status &= ~ISI_RTS; +} + +/* card->lock MUST NOT be held */ + +static void isicom_dtr_rts(struct tty_port *port, int on) +{ + struct isi_port *ip = container_of(port, struct isi_port, port); + struct isi_board *card = ip->card; + unsigned long base = card->base; + u16 channel = ip->channel; + + if (!lock_card(card)) + return; + + if (on) { + outw(0x8000 | (channel << card->shift_count) | 0x02, base); + outw(0x0f04, base); + InterruptTheCard(base); + ip->status |= (ISI_DTR | ISI_RTS); + } else { + outw(0x8000 | (channel << card->shift_count) | 0x02, base); + outw(0x0C04, base); + InterruptTheCard(base); + ip->status &= ~(ISI_DTR | ISI_RTS); + } + unlock_card(card); +} + +/* card->lock HAS to be held */ +static void drop_dtr_rts(struct isi_port *port) +{ + struct isi_board *card = port->card; + unsigned long base = card->base; + u16 channel = port->channel; + + if (WaitTillCardIsFree(base)) + return; + + outw(0x8000 | (channel << card->shift_count) | 0x02, base); + outw(0x0c04, base); + InterruptTheCard(base); + port->status &= ~(ISI_RTS | ISI_DTR); +} + +/* + * ISICOM Driver specific routines ... + * + */ + +static inline int __isicom_paranoia_check(struct isi_port const *port, + char *name, const char *routine) +{ + if (!port) { + pr_warning("Warning: bad isicom magic for dev %s in %s.\n", + name, routine); + return 1; + } + if (port->magic != ISICOM_MAGIC) { + pr_warning("Warning: NULL isicom port for dev %s in %s.\n", + name, routine); + return 1; + } + + return 0; +} + +/* + * Transmitter. + * + * We shovel data into the card buffers on a regular basis. The card + * will do the rest of the work for us. + */ + +static void isicom_tx(unsigned long _data) +{ + unsigned long flags, base; + unsigned int retries; + short count = (BOARD_COUNT-1), card; + short txcount, wrd, residue, word_count, cnt; + struct isi_port *port; + struct tty_struct *tty; + + /* find next active board */ + card = (prev_card + 1) & 0x0003; + while (count-- > 0) { + if (isi_card[card].status & BOARD_ACTIVE) + break; + card = (card + 1) & 0x0003; + } + if (!(isi_card[card].status & BOARD_ACTIVE)) + goto sched_again; + + prev_card = card; + + count = isi_card[card].port_count; + port = isi_card[card].ports; + base = isi_card[card].base; + + spin_lock_irqsave(&isi_card[card].card_lock, flags); + for (retries = 0; retries < 100; retries++) { + if (inw(base + 0xe) & 0x1) + break; + udelay(2); + } + if (retries >= 100) + goto unlock; + + tty = tty_port_tty_get(&port->port); + if (tty == NULL) + goto put_unlock; + + for (; count > 0; count--, port++) { + /* port not active or tx disabled to force flow control */ + if (!(port->port.flags & ASYNC_INITIALIZED) || + !(port->status & ISI_TXOK)) + continue; + + txcount = min_t(short, TX_SIZE, port->xmit_cnt); + if (txcount <= 0 || tty->stopped || tty->hw_stopped) + continue; + + if (!(inw(base + 0x02) & (1 << port->channel))) + continue; + + pr_debug("txing %d bytes, port%d.\n", + txcount, port->channel + 1); + outw((port->channel << isi_card[card].shift_count) | txcount, + base); + residue = NO; + wrd = 0; + while (1) { + cnt = min_t(int, txcount, (SERIAL_XMIT_SIZE + - port->xmit_tail)); + if (residue == YES) { + residue = NO; + if (cnt > 0) { + wrd |= (port->port.xmit_buf[port->xmit_tail] + << 8); + port->xmit_tail = (port->xmit_tail + 1) + & (SERIAL_XMIT_SIZE - 1); + port->xmit_cnt--; + txcount--; + cnt--; + outw(wrd, base); + } else { + outw(wrd, base); + break; + } + } + if (cnt <= 0) + break; + word_count = cnt >> 1; + outsw(base, port->port.xmit_buf+port->xmit_tail, word_count); + port->xmit_tail = (port->xmit_tail + + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1); + txcount -= (word_count << 1); + port->xmit_cnt -= (word_count << 1); + if (cnt & 0x0001) { + residue = YES; + wrd = port->port.xmit_buf[port->xmit_tail]; + port->xmit_tail = (port->xmit_tail + 1) + & (SERIAL_XMIT_SIZE - 1); + port->xmit_cnt--; + txcount--; + } + } + + InterruptTheCard(base); + if (port->xmit_cnt <= 0) + port->status &= ~ISI_TXOK; + if (port->xmit_cnt <= WAKEUP_CHARS) + tty_wakeup(tty); + } + +put_unlock: + tty_kref_put(tty); +unlock: + spin_unlock_irqrestore(&isi_card[card].card_lock, flags); + /* schedule another tx for hopefully in about 10ms */ +sched_again: + mod_timer(&tx, jiffies + msecs_to_jiffies(10)); +} + +/* + * Main interrupt handler routine + */ + +static irqreturn_t isicom_interrupt(int irq, void *dev_id) +{ + struct isi_board *card = dev_id; + struct isi_port *port; + struct tty_struct *tty; + unsigned long base; + u16 header, word_count, count, channel; + short byte_count; + unsigned char *rp; + + if (!card || !(card->status & FIRMWARE_LOADED)) + return IRQ_NONE; + + base = card->base; + + /* did the card interrupt us? */ + if (!(inw(base + 0x0e) & 0x02)) + return IRQ_NONE; + + spin_lock(&card->card_lock); + + /* + * disable any interrupts from the PCI card and lower the + * interrupt line + */ + outw(0x8000, base+0x04); + ClearInterrupt(base); + + inw(base); /* get the dummy word out */ + header = inw(base); + channel = (header & 0x7800) >> card->shift_count; + byte_count = header & 0xff; + + if (channel + 1 > card->port_count) { + pr_warning("%s(0x%lx): %d(channel) > port_count.\n", + __func__, base, channel+1); + outw(0x0000, base+0x04); /* enable interrupts */ + spin_unlock(&card->card_lock); + return IRQ_HANDLED; + } + port = card->ports + channel; + if (!(port->port.flags & ASYNC_INITIALIZED)) { + outw(0x0000, base+0x04); /* enable interrupts */ + spin_unlock(&card->card_lock); + return IRQ_HANDLED; + } + + tty = tty_port_tty_get(&port->port); + if (tty == NULL) { + word_count = byte_count >> 1; + while (byte_count > 1) { + inw(base); + byte_count -= 2; + } + if (byte_count & 0x01) + inw(base); + outw(0x0000, base+0x04); /* enable interrupts */ + spin_unlock(&card->card_lock); + return IRQ_HANDLED; + } + + if (header & 0x8000) { /* Status Packet */ + header = inw(base); + switch (header & 0xff) { + case 0: /* Change in EIA signals */ + if (port->port.flags & ASYNC_CHECK_CD) { + if (port->status & ISI_DCD) { + if (!(header & ISI_DCD)) { + /* Carrier has been lost */ + pr_debug("%s: DCD->low.\n", + __func__); + port->status &= ~ISI_DCD; + tty_hangup(tty); + } + } else if (header & ISI_DCD) { + /* Carrier has been detected */ + pr_debug("%s: DCD->high.\n", + __func__); + port->status |= ISI_DCD; + wake_up_interruptible(&port->port.open_wait); + } + } else { + if (header & ISI_DCD) + port->status |= ISI_DCD; + else + port->status &= ~ISI_DCD; + } + + if (port->port.flags & ASYNC_CTS_FLOW) { + if (tty->hw_stopped) { + if (header & ISI_CTS) { + port->port.tty->hw_stopped = 0; + /* start tx ing */ + port->status |= (ISI_TXOK + | ISI_CTS); + tty_wakeup(tty); + } + } else if (!(header & ISI_CTS)) { + tty->hw_stopped = 1; + /* stop tx ing */ + port->status &= ~(ISI_TXOK | ISI_CTS); + } + } else { + if (header & ISI_CTS) + port->status |= ISI_CTS; + else + port->status &= ~ISI_CTS; + } + + if (header & ISI_DSR) + port->status |= ISI_DSR; + else + port->status &= ~ISI_DSR; + + if (header & ISI_RI) + port->status |= ISI_RI; + else + port->status &= ~ISI_RI; + + break; + + case 1: /* Received Break !!! */ + tty_insert_flip_char(tty, 0, TTY_BREAK); + if (port->port.flags & ASYNC_SAK) + do_SAK(tty); + tty_flip_buffer_push(tty); + break; + + case 2: /* Statistics */ + pr_debug("%s: stats!!!\n", __func__); + break; + + default: + pr_debug("%s: Unknown code in status packet.\n", + __func__); + break; + } + } else { /* Data Packet */ + + count = tty_prepare_flip_string(tty, &rp, byte_count & ~1); + pr_debug("%s: Can rx %d of %d bytes.\n", + __func__, count, byte_count); + word_count = count >> 1; + insw(base, rp, word_count); + byte_count -= (word_count << 1); + if (count & 0x0001) { + tty_insert_flip_char(tty, inw(base) & 0xff, + TTY_NORMAL); + byte_count -= 2; + } + if (byte_count > 0) { + pr_debug("%s(0x%lx:%d): Flip buffer overflow! dropping bytes...\n", + __func__, base, channel + 1); + /* drain out unread xtra data */ + while (byte_count > 0) { + inw(base); + byte_count -= 2; + } + } + tty_flip_buffer_push(tty); + } + outw(0x0000, base+0x04); /* enable interrupts */ + spin_unlock(&card->card_lock); + tty_kref_put(tty); + + return IRQ_HANDLED; +} + +static void isicom_config_port(struct tty_struct *tty) +{ + struct isi_port *port = tty->driver_data; + struct isi_board *card = port->card; + unsigned long baud; + unsigned long base = card->base; + u16 channel_setup, channel = port->channel, + shift_count = card->shift_count; + unsigned char flow_ctrl; + + /* FIXME: Switch to new tty baud API */ + baud = C_BAUD(tty); + if (baud & CBAUDEX) { + baud &= ~CBAUDEX; + + /* if CBAUDEX bit is on and the baud is set to either 50 or 75 + * then the card is programmed for 57.6Kbps or 115Kbps + * respectively. + */ + + /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */ + if (baud < 1 || baud > 4) + tty->termios->c_cflag &= ~CBAUDEX; + else + baud += 15; + } + if (baud == 15) { + + /* the ASYNC_SPD_HI and ASYNC_SPD_VHI options are set + * by the set_serial_info ioctl ... this is done by + * the 'setserial' utility. + */ + + if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + baud++; /* 57.6 Kbps */ + if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + baud += 2; /* 115 Kbps */ + if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + baud += 3; /* 230 kbps*/ + if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + baud += 4; /* 460 kbps*/ + } + if (linuxb_to_isib[baud] == -1) { + /* hang up */ + drop_dtr(port); + return; + } else + raise_dtr(port); + + if (WaitTillCardIsFree(base) == 0) { + outw(0x8000 | (channel << shift_count) | 0x03, base); + outw(linuxb_to_isib[baud] << 8 | 0x03, base); + channel_setup = 0; + switch (C_CSIZE(tty)) { + case CS5: + channel_setup |= ISICOM_CS5; + break; + case CS6: + channel_setup |= ISICOM_CS6; + break; + case CS7: + channel_setup |= ISICOM_CS7; + break; + case CS8: + channel_setup |= ISICOM_CS8; + break; + } + + if (C_CSTOPB(tty)) + channel_setup |= ISICOM_2SB; + if (C_PARENB(tty)) { + channel_setup |= ISICOM_EVPAR; + if (C_PARODD(tty)) + channel_setup |= ISICOM_ODPAR; + } + outw(channel_setup, base); + InterruptTheCard(base); + } + if (C_CLOCAL(tty)) + port->port.flags &= ~ASYNC_CHECK_CD; + else + port->port.flags |= ASYNC_CHECK_CD; + + /* flow control settings ...*/ + flow_ctrl = 0; + port->port.flags &= ~ASYNC_CTS_FLOW; + if (C_CRTSCTS(tty)) { + port->port.flags |= ASYNC_CTS_FLOW; + flow_ctrl |= ISICOM_CTSRTS; + } + if (I_IXON(tty)) + flow_ctrl |= ISICOM_RESPOND_XONXOFF; + if (I_IXOFF(tty)) + flow_ctrl |= ISICOM_INITIATE_XONXOFF; + + if (WaitTillCardIsFree(base) == 0) { + outw(0x8000 | (channel << shift_count) | 0x04, base); + outw(flow_ctrl << 8 | 0x05, base); + outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base); + InterruptTheCard(base); + } + + /* rx enabled -> enable port for rx on the card */ + if (C_CREAD(tty)) { + card->port_status |= (1 << channel); + outw(card->port_status, base + 0x02); + } +} + +/* open et all */ + +static inline void isicom_setup_board(struct isi_board *bp) +{ + int channel; + struct isi_port *port; + + bp->count++; + if (!(bp->status & BOARD_INIT)) { + port = bp->ports; + for (channel = 0; channel < bp->port_count; channel++, port++) + drop_dtr_rts(port); + } + bp->status |= BOARD_ACTIVE | BOARD_INIT; +} + +/* Activate and thus setup board are protected from races against shutdown + by the tty_port mutex */ + +static int isicom_activate(struct tty_port *tport, struct tty_struct *tty) +{ + struct isi_port *port = container_of(tport, struct isi_port, port); + struct isi_board *card = port->card; + unsigned long flags; + + if (tty_port_alloc_xmit_buf(tport) < 0) + return -ENOMEM; + + spin_lock_irqsave(&card->card_lock, flags); + isicom_setup_board(card); + + port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; + + /* discard any residual data */ + if (WaitTillCardIsFree(card->base) == 0) { + outw(0x8000 | (port->channel << card->shift_count) | 0x02, + card->base); + outw(((ISICOM_KILLTX | ISICOM_KILLRX) << 8) | 0x06, card->base); + InterruptTheCard(card->base); + } + isicom_config_port(tty); + spin_unlock_irqrestore(&card->card_lock, flags); + + return 0; +} + +static int isicom_carrier_raised(struct tty_port *port) +{ + struct isi_port *ip = container_of(port, struct isi_port, port); + return (ip->status & ISI_DCD)?1 : 0; +} + +static struct tty_port *isicom_find_port(struct tty_struct *tty) +{ + struct isi_port *port; + struct isi_board *card; + unsigned int board; + int line = tty->index; + + if (line < 0 || line > PORT_COUNT-1) + return NULL; + board = BOARD(line); + card = &isi_card[board]; + + if (!(card->status & FIRMWARE_LOADED)) + return NULL; + + /* open on a port greater than the port count for the card !!! */ + if (line > ((board * 16) + card->port_count - 1)) + return NULL; + + port = &isi_ports[line]; + if (isicom_paranoia_check(port, tty->name, "isicom_open")) + return NULL; + + return &port->port; +} + +static int isicom_open(struct tty_struct *tty, struct file *filp) +{ + struct isi_port *port; + struct tty_port *tport; + + tport = isicom_find_port(tty); + if (tport == NULL) + return -ENODEV; + port = container_of(tport, struct isi_port, port); + + tty->driver_data = port; + return tty_port_open(tport, tty, filp); +} + +/* close et all */ + +/* card->lock HAS to be held */ +static void isicom_shutdown_port(struct isi_port *port) +{ + struct isi_board *card = port->card; + + if (--card->count < 0) { + pr_debug("%s: bad board(0x%lx) count %d.\n", + __func__, card->base, card->count); + card->count = 0; + } + /* last port was closed, shutdown that board too */ + if (!card->count) + card->status &= BOARD_ACTIVE; +} + +static void isicom_flush_buffer(struct tty_struct *tty) +{ + struct isi_port *port = tty->driver_data; + struct isi_board *card = port->card; + unsigned long flags; + + if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer")) + return; + + spin_lock_irqsave(&card->card_lock, flags); + port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; + spin_unlock_irqrestore(&card->card_lock, flags); + + tty_wakeup(tty); +} + +static void isicom_shutdown(struct tty_port *port) +{ + struct isi_port *ip = container_of(port, struct isi_port, port); + struct isi_board *card = ip->card; + unsigned long flags; + + /* indicate to the card that no more data can be received + on this port */ + spin_lock_irqsave(&card->card_lock, flags); + card->port_status &= ~(1 << ip->channel); + outw(card->port_status, card->base + 0x02); + isicom_shutdown_port(ip); + spin_unlock_irqrestore(&card->card_lock, flags); + tty_port_free_xmit_buf(port); +} + +static void isicom_close(struct tty_struct *tty, struct file *filp) +{ + struct isi_port *ip = tty->driver_data; + struct tty_port *port; + + if (ip == NULL) + return; + + port = &ip->port; + if (isicom_paranoia_check(ip, tty->name, "isicom_close")) + return; + tty_port_close(port, tty, filp); +} + +/* write et all */ +static int isicom_write(struct tty_struct *tty, const unsigned char *buf, + int count) +{ + struct isi_port *port = tty->driver_data; + struct isi_board *card = port->card; + unsigned long flags; + int cnt, total = 0; + + if (isicom_paranoia_check(port, tty->name, "isicom_write")) + return 0; + + spin_lock_irqsave(&card->card_lock, flags); + + while (1) { + cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt + - 1, SERIAL_XMIT_SIZE - port->xmit_head)); + if (cnt <= 0) + break; + + memcpy(port->port.xmit_buf + port->xmit_head, buf, cnt); + port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE + - 1); + port->xmit_cnt += cnt; + buf += cnt; + count -= cnt; + total += cnt; + } + if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped) + port->status |= ISI_TXOK; + spin_unlock_irqrestore(&card->card_lock, flags); + return total; +} + +/* put_char et all */ +static int isicom_put_char(struct tty_struct *tty, unsigned char ch) +{ + struct isi_port *port = tty->driver_data; + struct isi_board *card = port->card; + unsigned long flags; + + if (isicom_paranoia_check(port, tty->name, "isicom_put_char")) + return 0; + + spin_lock_irqsave(&card->card_lock, flags); + if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { + spin_unlock_irqrestore(&card->card_lock, flags); + return 0; + } + + port->port.xmit_buf[port->xmit_head++] = ch; + port->xmit_head &= (SERIAL_XMIT_SIZE - 1); + port->xmit_cnt++; + spin_unlock_irqrestore(&card->card_lock, flags); + return 1; +} + +/* flush_chars et all */ +static void isicom_flush_chars(struct tty_struct *tty) +{ + struct isi_port *port = tty->driver_data; + + if (isicom_paranoia_check(port, tty->name, "isicom_flush_chars")) + return; + + if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || + !port->port.xmit_buf) + return; + + /* this tells the transmitter to consider this port for + data output to the card ... that's the best we can do. */ + port->status |= ISI_TXOK; +} + +/* write_room et all */ +static int isicom_write_room(struct tty_struct *tty) +{ + struct isi_port *port = tty->driver_data; + int free; + + if (isicom_paranoia_check(port, tty->name, "isicom_write_room")) + return 0; + + free = SERIAL_XMIT_SIZE - port->xmit_cnt - 1; + if (free < 0) + free = 0; + return free; +} + +/* chars_in_buffer et all */ +static int isicom_chars_in_buffer(struct tty_struct *tty) +{ + struct isi_port *port = tty->driver_data; + if (isicom_paranoia_check(port, tty->name, "isicom_chars_in_buffer")) + return 0; + return port->xmit_cnt; +} + +/* ioctl et all */ +static int isicom_send_break(struct tty_struct *tty, int length) +{ + struct isi_port *port = tty->driver_data; + struct isi_board *card = port->card; + unsigned long base = card->base; + + if (length == -1) + return -EOPNOTSUPP; + + if (!lock_card(card)) + return -EINVAL; + + outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base); + outw((length & 0xff) << 8 | 0x00, base); + outw((length & 0xff00), base); + InterruptTheCard(base); + + unlock_card(card); + return 0; +} + +static int isicom_tiocmget(struct tty_struct *tty) +{ + struct isi_port *port = tty->driver_data; + /* just send the port status */ + u16 status = port->status; + + if (isicom_paranoia_check(port, tty->name, "isicom_ioctl")) + return -ENODEV; + + return ((status & ISI_RTS) ? TIOCM_RTS : 0) | + ((status & ISI_DTR) ? TIOCM_DTR : 0) | + ((status & ISI_DCD) ? TIOCM_CAR : 0) | + ((status & ISI_DSR) ? TIOCM_DSR : 0) | + ((status & ISI_CTS) ? TIOCM_CTS : 0) | + ((status & ISI_RI ) ? TIOCM_RI : 0); +} + +static int isicom_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + struct isi_port *port = tty->driver_data; + unsigned long flags; + + if (isicom_paranoia_check(port, tty->name, "isicom_ioctl")) + return -ENODEV; + + spin_lock_irqsave(&port->card->card_lock, flags); + if (set & TIOCM_RTS) + raise_rts(port); + if (set & TIOCM_DTR) + raise_dtr(port); + + if (clear & TIOCM_RTS) + drop_rts(port); + if (clear & TIOCM_DTR) + drop_dtr(port); + spin_unlock_irqrestore(&port->card->card_lock, flags); + + return 0; +} + +static int isicom_set_serial_info(struct tty_struct *tty, + struct serial_struct __user *info) +{ + struct isi_port *port = tty->driver_data; + struct serial_struct newinfo; + int reconfig_port; + + if (copy_from_user(&newinfo, info, sizeof(newinfo))) + return -EFAULT; + + mutex_lock(&port->port.mutex); + reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) != + (newinfo.flags & ASYNC_SPD_MASK)); + + if (!capable(CAP_SYS_ADMIN)) { + if ((newinfo.close_delay != port->port.close_delay) || + (newinfo.closing_wait != port->port.closing_wait) || + ((newinfo.flags & ~ASYNC_USR_MASK) != + (port->port.flags & ~ASYNC_USR_MASK))) { + mutex_unlock(&port->port.mutex); + return -EPERM; + } + port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | + (newinfo.flags & ASYNC_USR_MASK)); + } else { + port->port.close_delay = newinfo.close_delay; + port->port.closing_wait = newinfo.closing_wait; + port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) | + (newinfo.flags & ASYNC_FLAGS)); + } + if (reconfig_port) { + unsigned long flags; + spin_lock_irqsave(&port->card->card_lock, flags); + isicom_config_port(tty); + spin_unlock_irqrestore(&port->card->card_lock, flags); + } + mutex_unlock(&port->port.mutex); + return 0; +} + +static int isicom_get_serial_info(struct isi_port *port, + struct serial_struct __user *info) +{ + struct serial_struct out_info; + + mutex_lock(&port->port.mutex); + memset(&out_info, 0, sizeof(out_info)); +/* out_info.type = ? */ + out_info.line = port - isi_ports; + out_info.port = port->card->base; + out_info.irq = port->card->irq; + out_info.flags = port->port.flags; +/* out_info.baud_base = ? */ + out_info.close_delay = port->port.close_delay; + out_info.closing_wait = port->port.closing_wait; + mutex_unlock(&port->port.mutex); + if (copy_to_user(info, &out_info, sizeof(out_info))) + return -EFAULT; + return 0; +} + +static int isicom_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + struct isi_port *port = tty->driver_data; + void __user *argp = (void __user *)arg; + + if (isicom_paranoia_check(port, tty->name, "isicom_ioctl")) + return -ENODEV; + + switch (cmd) { + case TIOCGSERIAL: + return isicom_get_serial_info(port, argp); + + case TIOCSSERIAL: + return isicom_set_serial_info(tty, argp); + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +/* set_termios et all */ +static void isicom_set_termios(struct tty_struct *tty, + struct ktermios *old_termios) +{ + struct isi_port *port = tty->driver_data; + unsigned long flags; + + if (isicom_paranoia_check(port, tty->name, "isicom_set_termios")) + return; + + if (tty->termios->c_cflag == old_termios->c_cflag && + tty->termios->c_iflag == old_termios->c_iflag) + return; + + spin_lock_irqsave(&port->card->card_lock, flags); + isicom_config_port(tty); + spin_unlock_irqrestore(&port->card->card_lock, flags); + + if ((old_termios->c_cflag & CRTSCTS) && + !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + isicom_start(tty); + } +} + +/* throttle et all */ +static void isicom_throttle(struct tty_struct *tty) +{ + struct isi_port *port = tty->driver_data; + struct isi_board *card = port->card; + + if (isicom_paranoia_check(port, tty->name, "isicom_throttle")) + return; + + /* tell the card that this port cannot handle any more data for now */ + card->port_status &= ~(1 << port->channel); + outw(card->port_status, card->base + 0x02); +} + +/* unthrottle et all */ +static void isicom_unthrottle(struct tty_struct *tty) +{ + struct isi_port *port = tty->driver_data; + struct isi_board *card = port->card; + + if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle")) + return; + + /* tell the card that this port is ready to accept more data */ + card->port_status |= (1 << port->channel); + outw(card->port_status, card->base + 0x02); +} + +/* stop et all */ +static void isicom_stop(struct tty_struct *tty) +{ + struct isi_port *port = tty->driver_data; + + if (isicom_paranoia_check(port, tty->name, "isicom_stop")) + return; + + /* this tells the transmitter not to consider this port for + data output to the card. */ + port->status &= ~ISI_TXOK; +} + +/* start et all */ +static void isicom_start(struct tty_struct *tty) +{ + struct isi_port *port = tty->driver_data; + + if (isicom_paranoia_check(port, tty->name, "isicom_start")) + return; + + /* this tells the transmitter to consider this port for + data output to the card. */ + port->status |= ISI_TXOK; +} + +static void isicom_hangup(struct tty_struct *tty) +{ + struct isi_port *port = tty->driver_data; + + if (isicom_paranoia_check(port, tty->name, "isicom_hangup")) + return; + tty_port_hangup(&port->port); +} + + +/* + * Driver init and deinit functions + */ + +static const struct tty_operations isicom_ops = { + .open = isicom_open, + .close = isicom_close, + .write = isicom_write, + .put_char = isicom_put_char, + .flush_chars = isicom_flush_chars, + .write_room = isicom_write_room, + .chars_in_buffer = isicom_chars_in_buffer, + .ioctl = isicom_ioctl, + .set_termios = isicom_set_termios, + .throttle = isicom_throttle, + .unthrottle = isicom_unthrottle, + .stop = isicom_stop, + .start = isicom_start, + .hangup = isicom_hangup, + .flush_buffer = isicom_flush_buffer, + .tiocmget = isicom_tiocmget, + .tiocmset = isicom_tiocmset, + .break_ctl = isicom_send_break, +}; + +static const struct tty_port_operations isicom_port_ops = { + .carrier_raised = isicom_carrier_raised, + .dtr_rts = isicom_dtr_rts, + .activate = isicom_activate, + .shutdown = isicom_shutdown, +}; + +static int __devinit reset_card(struct pci_dev *pdev, + const unsigned int card, unsigned int *signature) +{ + struct isi_board *board = pci_get_drvdata(pdev); + unsigned long base = board->base; + unsigned int sig, portcount = 0; + int retval = 0; + + dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1, + base); + + inw(base + 0x8); + + msleep(10); + + outw(0, base + 0x8); /* Reset */ + + msleep(1000); + + sig = inw(base + 0x4) & 0xff; + + if (sig != 0xa5 && sig != 0xbb && sig != 0xcc && sig != 0xdd && + sig != 0xee) { + dev_warn(&pdev->dev, "ISILoad:Card%u reset failure (Possible " + "bad I/O Port Address 0x%lx).\n", card + 1, base); + dev_dbg(&pdev->dev, "Sig=0x%x\n", sig); + retval = -EIO; + goto end; + } + + msleep(10); + + portcount = inw(base + 0x2); + if (!(inw(base + 0xe) & 0x1) || (portcount != 0 && portcount != 4 && + portcount != 8 && portcount != 16)) { + dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n", + card + 1); + retval = -EIO; + goto end; + } + + switch (sig) { + case 0xa5: + case 0xbb: + case 0xdd: + board->port_count = (portcount == 4) ? 4 : 8; + board->shift_count = 12; + break; + case 0xcc: + case 0xee: + board->port_count = 16; + board->shift_count = 11; + break; + } + dev_info(&pdev->dev, "-Done\n"); + *signature = sig; + +end: + return retval; +} + +static int __devinit load_firmware(struct pci_dev *pdev, + const unsigned int index, const unsigned int signature) +{ + struct isi_board *board = pci_get_drvdata(pdev); + const struct firmware *fw; + unsigned long base = board->base; + unsigned int a; + u16 word_count, status; + int retval = -EIO; + char *name; + u8 *data; + + struct stframe { + u16 addr; + u16 count; + u8 data[0]; + } *frame; + + switch (signature) { + case 0xa5: + name = "isi608.bin"; + break; + case 0xbb: + name = "isi608em.bin"; + break; + case 0xcc: + name = "isi616em.bin"; + break; + case 0xdd: + name = "isi4608.bin"; + break; + case 0xee: + name = "isi4616.bin"; + break; + default: + dev_err(&pdev->dev, "Unknown signature.\n"); + goto end; + } + + retval = request_firmware(&fw, name, &pdev->dev); + if (retval) + goto end; + + retval = -EIO; + + for (frame = (struct stframe *)fw->data; + frame < (struct stframe *)(fw->data + fw->size); + frame = (struct stframe *)((u8 *)(frame + 1) + + frame->count)) { + if (WaitTillCardIsFree(base)) + goto errrelfw; + + outw(0xf0, base); /* start upload sequence */ + outw(0x00, base); + outw(frame->addr, base); /* lsb of address */ + + word_count = frame->count / 2 + frame->count % 2; + outw(word_count, base); + InterruptTheCard(base); + + udelay(100); /* 0x2f */ + + if (WaitTillCardIsFree(base)) + goto errrelfw; + + status = inw(base + 0x4); + if (status != 0) { + dev_warn(&pdev->dev, "Card%d rejected load header:\n" + "Address:0x%x\n" + "Count:0x%x\n" + "Status:0x%x\n", + index + 1, frame->addr, frame->count, status); + goto errrelfw; + } + outsw(base, frame->data, word_count); + + InterruptTheCard(base); + + udelay(50); /* 0x0f */ + + if (WaitTillCardIsFree(base)) + goto errrelfw; + + status = inw(base + 0x4); + if (status != 0) { + dev_err(&pdev->dev, "Card%d got out of sync.Card " + "Status:0x%x\n", index + 1, status); + goto errrelfw; + } + } + +/* XXX: should we test it by reading it back and comparing with original like + * in load firmware package? */ + for (frame = (struct stframe *)fw->data; + frame < (struct stframe *)(fw->data + fw->size); + frame = (struct stframe *)((u8 *)(frame + 1) + + frame->count)) { + if (WaitTillCardIsFree(base)) + goto errrelfw; + + outw(0xf1, base); /* start download sequence */ + outw(0x00, base); + outw(frame->addr, base); /* lsb of address */ + + word_count = (frame->count >> 1) + frame->count % 2; + outw(word_count + 1, base); + InterruptTheCard(base); + + udelay(50); /* 0xf */ + + if (WaitTillCardIsFree(base)) + goto errrelfw; + + status = inw(base + 0x4); + if (status != 0) { + dev_warn(&pdev->dev, "Card%d rejected verify header:\n" + "Address:0x%x\n" + "Count:0x%x\n" + "Status: 0x%x\n", + index + 1, frame->addr, frame->count, status); + goto errrelfw; + } + + data = kmalloc(word_count * 2, GFP_KERNEL); + if (data == NULL) { + dev_err(&pdev->dev, "Card%d, firmware upload " + "failed, not enough memory\n", index + 1); + goto errrelfw; + } + inw(base); + insw(base, data, word_count); + InterruptTheCard(base); + + for (a = 0; a < frame->count; a++) + if (data[a] != frame->data[a]) { + kfree(data); + dev_err(&pdev->dev, "Card%d, firmware upload " + "failed\n", index + 1); + goto errrelfw; + } + kfree(data); + + udelay(50); /* 0xf */ + + if (WaitTillCardIsFree(base)) + goto errrelfw; + + status = inw(base + 0x4); + if (status != 0) { + dev_err(&pdev->dev, "Card%d verify got out of sync. " + "Card Status:0x%x\n", index + 1, status); + goto errrelfw; + } + } + + /* xfer ctrl */ + if (WaitTillCardIsFree(base)) + goto errrelfw; + + outw(0xf2, base); + outw(0x800, base); + outw(0x0, base); + outw(0x0, base); + InterruptTheCard(base); + outw(0x0, base + 0x4); /* for ISI4608 cards */ + + board->status |= FIRMWARE_LOADED; + retval = 0; + +errrelfw: + release_firmware(fw); +end: + return retval; +} + +/* + * Insmod can set static symbols so keep these static + */ +static unsigned int card_count; + +static int __devinit isicom_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + unsigned int uninitialized_var(signature), index; + int retval = -EPERM; + struct isi_board *board = NULL; + + if (card_count >= BOARD_COUNT) + goto err; + + retval = pci_enable_device(pdev); + if (retval) { + dev_err(&pdev->dev, "failed to enable\n"); + goto err; + } + + dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device); + + /* allot the first empty slot in the array */ + for (index = 0; index < BOARD_COUNT; index++) { + if (isi_card[index].base == 0) { + board = &isi_card[index]; + break; + } + } + if (index == BOARD_COUNT) { + retval = -ENODEV; + goto err_disable; + } + + board->index = index; + board->base = pci_resource_start(pdev, 3); + board->irq = pdev->irq; + card_count++; + + pci_set_drvdata(pdev, board); + + retval = pci_request_region(pdev, 3, ISICOM_NAME); + if (retval) { + dev_err(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d " + "will be disabled.\n", board->base, board->base + 15, + index + 1); + retval = -EBUSY; + goto errdec; + } + + retval = request_irq(board->irq, isicom_interrupt, + IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board); + if (retval < 0) { + dev_err(&pdev->dev, "Could not install handler at Irq %d. " + "Card%d will be disabled.\n", board->irq, index + 1); + goto errunrr; + } + + retval = reset_card(pdev, index, &signature); + if (retval < 0) + goto errunri; + + retval = load_firmware(pdev, index, signature); + if (retval < 0) + goto errunri; + + for (index = 0; index < board->port_count; index++) + tty_register_device(isicom_normal, board->index * 16 + index, + &pdev->dev); + + return 0; + +errunri: + free_irq(board->irq, board); +errunrr: + pci_release_region(pdev, 3); +errdec: + board->base = 0; + card_count--; +err_disable: + pci_disable_device(pdev); +err: + return retval; +} + +static void __devexit isicom_remove(struct pci_dev *pdev) +{ + struct isi_board *board = pci_get_drvdata(pdev); + unsigned int i; + + for (i = 0; i < board->port_count; i++) + tty_unregister_device(isicom_normal, board->index * 16 + i); + + free_irq(board->irq, board); + pci_release_region(pdev, 3); + board->base = 0; + card_count--; + pci_disable_device(pdev); +} + +static int __init isicom_init(void) +{ + int retval, idx, channel; + struct isi_port *port; + + for (idx = 0; idx < BOARD_COUNT; idx++) { + port = &isi_ports[idx * 16]; + isi_card[idx].ports = port; + spin_lock_init(&isi_card[idx].card_lock); + for (channel = 0; channel < 16; channel++, port++) { + tty_port_init(&port->port); + port->port.ops = &isicom_port_ops; + port->magic = ISICOM_MAGIC; + port->card = &isi_card[idx]; + port->channel = channel; + port->port.close_delay = 50 * HZ/100; + port->port.closing_wait = 3000 * HZ/100; + port->status = 0; + /* . . . */ + } + isi_card[idx].base = 0; + isi_card[idx].irq = 0; + } + + /* tty driver structure initialization */ + isicom_normal = alloc_tty_driver(PORT_COUNT); + if (!isicom_normal) { + retval = -ENOMEM; + goto error; + } + + isicom_normal->owner = THIS_MODULE; + isicom_normal->name = "ttyM"; + isicom_normal->major = ISICOM_NMAJOR; + isicom_normal->minor_start = 0; + isicom_normal->type = TTY_DRIVER_TYPE_SERIAL; + isicom_normal->subtype = SERIAL_TYPE_NORMAL; + isicom_normal->init_termios = tty_std_termios; + isicom_normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | + CLOCAL; + isicom_normal->flags = TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK; + tty_set_operations(isicom_normal, &isicom_ops); + + retval = tty_register_driver(isicom_normal); + if (retval) { + pr_debug("Couldn't register the dialin driver\n"); + goto err_puttty; + } + + retval = pci_register_driver(&isicom_driver); + if (retval < 0) { + pr_err("Unable to register pci driver.\n"); + goto err_unrtty; + } + + mod_timer(&tx, jiffies + 1); + + return 0; +err_unrtty: + tty_unregister_driver(isicom_normal); +err_puttty: + put_tty_driver(isicom_normal); +error: + return retval; +} + +static void __exit isicom_exit(void) +{ + del_timer_sync(&tx); + + pci_unregister_driver(&isicom_driver); + tty_unregister_driver(isicom_normal); + put_tty_driver(isicom_normal); +} + +module_init(isicom_init); +module_exit(isicom_exit); + +MODULE_AUTHOR("MultiTech"); +MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech"); +MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("isi608.bin"); +MODULE_FIRMWARE("isi608em.bin"); +MODULE_FIRMWARE("isi616em.bin"); +MODULE_FIRMWARE("isi4608.bin"); +MODULE_FIRMWARE("isi4616.bin"); diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c new file mode 100644 index 000000000000..35b0c38590e6 --- /dev/null +++ b/drivers/tty/moxa.c @@ -0,0 +1,2092 @@ +/*****************************************************************************/ +/* + * moxa.c -- MOXA Intellio family multiport serial driver. + * + * Copyright (C) 1999-2000 Moxa Technologies (support@moxa.com). + * Copyright (c) 2007 Jiri Slaby + * + * This code is loosely based on the Linux serial driver, written by + * Linus Torvalds, Theodore T'so and others. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +/* + * MOXA Intellio Series Driver + * for : LINUX + * date : 1999/1/7 + * version : 5.1 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "moxa.h" + +#define MOXA_VERSION "6.0k" + +#define MOXA_FW_HDRLEN 32 + +#define MOXAMAJOR 172 + +#define MAX_BOARDS 4 /* Don't change this value */ +#define MAX_PORTS_PER_BOARD 32 /* Don't change this value */ +#define MAX_PORTS (MAX_BOARDS * MAX_PORTS_PER_BOARD) + +#define MOXA_IS_320(brd) ((brd)->boardType == MOXA_BOARD_C320_ISA || \ + (brd)->boardType == MOXA_BOARD_C320_PCI) + +/* + * Define the Moxa PCI vendor and device IDs. + */ +#define MOXA_BUS_TYPE_ISA 0 +#define MOXA_BUS_TYPE_PCI 1 + +enum { + MOXA_BOARD_C218_PCI = 1, + MOXA_BOARD_C218_ISA, + MOXA_BOARD_C320_PCI, + MOXA_BOARD_C320_ISA, + MOXA_BOARD_CP204J, +}; + +static char *moxa_brdname[] = +{ + "C218 Turbo PCI series", + "C218 Turbo ISA series", + "C320 Turbo PCI series", + "C320 Turbo ISA series", + "CP-204J series", +}; + +#ifdef CONFIG_PCI +static struct pci_device_id moxa_pcibrds[] = { + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C218), + .driver_data = MOXA_BOARD_C218_PCI }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C320), + .driver_data = MOXA_BOARD_C320_PCI }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP204J), + .driver_data = MOXA_BOARD_CP204J }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, moxa_pcibrds); +#endif /* CONFIG_PCI */ + +struct moxa_port; + +static struct moxa_board_conf { + int boardType; + int numPorts; + int busType; + + unsigned int ready; + + struct moxa_port *ports; + + void __iomem *basemem; + void __iomem *intNdx; + void __iomem *intPend; + void __iomem *intTable; +} moxa_boards[MAX_BOARDS]; + +struct mxser_mstatus { + tcflag_t cflag; + int cts; + int dsr; + int ri; + int dcd; +}; + +struct moxaq_str { + int inq; + int outq; +}; + +struct moxa_port { + struct tty_port port; + struct moxa_board_conf *board; + void __iomem *tableAddr; + + int type; + int cflag; + unsigned long statusflags; + + u8 DCDState; /* Protected by the port lock */ + u8 lineCtrl; + u8 lowChkFlag; +}; + +struct mon_str { + int tick; + int rxcnt[MAX_PORTS]; + int txcnt[MAX_PORTS]; +}; + +/* statusflags */ +#define TXSTOPPED 1 +#define LOWWAIT 2 +#define EMPTYWAIT 3 + +#define SERIAL_DO_RESTART + +#define WAKEUP_CHARS 256 + +static int ttymajor = MOXAMAJOR; +static struct mon_str moxaLog; +static unsigned int moxaFuncTout = HZ / 2; +static unsigned int moxaLowWaterChk; +static DEFINE_MUTEX(moxa_openlock); +static DEFINE_SPINLOCK(moxa_lock); + +static unsigned long baseaddr[MAX_BOARDS]; +static unsigned int type[MAX_BOARDS]; +static unsigned int numports[MAX_BOARDS]; + +MODULE_AUTHOR("William Chen"); +MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver"); +MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("c218tunx.cod"); +MODULE_FIRMWARE("cp204unx.cod"); +MODULE_FIRMWARE("c320tunx.cod"); + +module_param_array(type, uint, NULL, 0); +MODULE_PARM_DESC(type, "card type: C218=2, C320=4"); +module_param_array(baseaddr, ulong, NULL, 0); +MODULE_PARM_DESC(baseaddr, "base address"); +module_param_array(numports, uint, NULL, 0); +MODULE_PARM_DESC(numports, "numports (ignored for C218)"); + +module_param(ttymajor, int, 0); + +/* + * static functions: + */ +static int moxa_open(struct tty_struct *, struct file *); +static void moxa_close(struct tty_struct *, struct file *); +static int moxa_write(struct tty_struct *, const unsigned char *, int); +static int moxa_write_room(struct tty_struct *); +static void moxa_flush_buffer(struct tty_struct *); +static int moxa_chars_in_buffer(struct tty_struct *); +static void moxa_set_termios(struct tty_struct *, struct ktermios *); +static void moxa_stop(struct tty_struct *); +static void moxa_start(struct tty_struct *); +static void moxa_hangup(struct tty_struct *); +static int moxa_tiocmget(struct tty_struct *tty); +static int moxa_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear); +static void moxa_poll(unsigned long); +static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); +static void moxa_shutdown(struct tty_port *); +static int moxa_carrier_raised(struct tty_port *); +static void moxa_dtr_rts(struct tty_port *, int); +/* + * moxa board interface functions: + */ +static void MoxaPortEnable(struct moxa_port *); +static void MoxaPortDisable(struct moxa_port *); +static int MoxaPortSetTermio(struct moxa_port *, struct ktermios *, speed_t); +static int MoxaPortGetLineOut(struct moxa_port *, int *, int *); +static void MoxaPortLineCtrl(struct moxa_port *, int, int); +static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int); +static int MoxaPortLineStatus(struct moxa_port *); +static void MoxaPortFlushData(struct moxa_port *, int); +static int MoxaPortWriteData(struct tty_struct *, const unsigned char *, int); +static int MoxaPortReadData(struct moxa_port *); +static int MoxaPortTxQueue(struct moxa_port *); +static int MoxaPortRxQueue(struct moxa_port *); +static int MoxaPortTxFree(struct moxa_port *); +static void MoxaPortTxDisable(struct moxa_port *); +static void MoxaPortTxEnable(struct moxa_port *); +static int moxa_get_serial_info(struct moxa_port *, struct serial_struct __user *); +static int moxa_set_serial_info(struct moxa_port *, struct serial_struct __user *); +static void MoxaSetFifo(struct moxa_port *port, int enable); + +/* + * I/O functions + */ + +static DEFINE_SPINLOCK(moxafunc_lock); + +static void moxa_wait_finish(void __iomem *ofsAddr) +{ + unsigned long end = jiffies + moxaFuncTout; + + while (readw(ofsAddr + FuncCode) != 0) + if (time_after(jiffies, end)) + return; + if (readw(ofsAddr + FuncCode) != 0 && printk_ratelimit()) + printk(KERN_WARNING "moxa function expired\n"); +} + +static void moxafunc(void __iomem *ofsAddr, u16 cmd, u16 arg) +{ + unsigned long flags; + spin_lock_irqsave(&moxafunc_lock, flags); + writew(arg, ofsAddr + FuncArg); + writew(cmd, ofsAddr + FuncCode); + moxa_wait_finish(ofsAddr); + spin_unlock_irqrestore(&moxafunc_lock, flags); +} + +static int moxafuncret(void __iomem *ofsAddr, u16 cmd, u16 arg) +{ + unsigned long flags; + u16 ret; + spin_lock_irqsave(&moxafunc_lock, flags); + writew(arg, ofsAddr + FuncArg); + writew(cmd, ofsAddr + FuncCode); + moxa_wait_finish(ofsAddr); + ret = readw(ofsAddr + FuncArg); + spin_unlock_irqrestore(&moxafunc_lock, flags); + return ret; +} + +static void moxa_low_water_check(void __iomem *ofsAddr) +{ + u16 rptr, wptr, mask, len; + + if (readb(ofsAddr + FlagStat) & Xoff_state) { + rptr = readw(ofsAddr + RXrptr); + wptr = readw(ofsAddr + RXwptr); + mask = readw(ofsAddr + RX_mask); + len = (wptr - rptr) & mask; + if (len <= Low_water) + moxafunc(ofsAddr, FC_SendXon, 0); + } +} + +/* + * TTY operations + */ + +static int moxa_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + struct moxa_port *ch = tty->driver_data; + void __user *argp = (void __user *)arg; + int status, ret = 0; + + if (tty->index == MAX_PORTS) { + if (cmd != MOXA_GETDATACOUNT && cmd != MOXA_GET_IOQUEUE && + cmd != MOXA_GETMSTATUS) + return -EINVAL; + } else if (!ch) + return -ENODEV; + + switch (cmd) { + case MOXA_GETDATACOUNT: + moxaLog.tick = jiffies; + if (copy_to_user(argp, &moxaLog, sizeof(moxaLog))) + ret = -EFAULT; + break; + case MOXA_FLUSH_QUEUE: + MoxaPortFlushData(ch, arg); + break; + case MOXA_GET_IOQUEUE: { + struct moxaq_str __user *argm = argp; + struct moxaq_str tmp; + struct moxa_port *p; + unsigned int i, j; + + for (i = 0; i < MAX_BOARDS; i++) { + p = moxa_boards[i].ports; + for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { + memset(&tmp, 0, sizeof(tmp)); + spin_lock_bh(&moxa_lock); + if (moxa_boards[i].ready) { + tmp.inq = MoxaPortRxQueue(p); + tmp.outq = MoxaPortTxQueue(p); + } + spin_unlock_bh(&moxa_lock); + if (copy_to_user(argm, &tmp, sizeof(tmp))) + return -EFAULT; + } + } + break; + } case MOXA_GET_OQUEUE: + status = MoxaPortTxQueue(ch); + ret = put_user(status, (unsigned long __user *)argp); + break; + case MOXA_GET_IQUEUE: + status = MoxaPortRxQueue(ch); + ret = put_user(status, (unsigned long __user *)argp); + break; + case MOXA_GETMSTATUS: { + struct mxser_mstatus __user *argm = argp; + struct mxser_mstatus tmp; + struct moxa_port *p; + unsigned int i, j; + + for (i = 0; i < MAX_BOARDS; i++) { + p = moxa_boards[i].ports; + for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { + struct tty_struct *ttyp; + memset(&tmp, 0, sizeof(tmp)); + spin_lock_bh(&moxa_lock); + if (!moxa_boards[i].ready) { + spin_unlock_bh(&moxa_lock); + goto copy; + } + + status = MoxaPortLineStatus(p); + spin_unlock_bh(&moxa_lock); + + if (status & 1) + tmp.cts = 1; + if (status & 2) + tmp.dsr = 1; + if (status & 4) + tmp.dcd = 1; + + ttyp = tty_port_tty_get(&p->port); + if (!ttyp || !ttyp->termios) + tmp.cflag = p->cflag; + else + tmp.cflag = ttyp->termios->c_cflag; + tty_kref_put(tty); +copy: + if (copy_to_user(argm, &tmp, sizeof(tmp))) + return -EFAULT; + } + } + break; + } + case TIOCGSERIAL: + mutex_lock(&ch->port.mutex); + ret = moxa_get_serial_info(ch, argp); + mutex_unlock(&ch->port.mutex); + break; + case TIOCSSERIAL: + mutex_lock(&ch->port.mutex); + ret = moxa_set_serial_info(ch, argp); + mutex_unlock(&ch->port.mutex); + break; + default: + ret = -ENOIOCTLCMD; + } + return ret; +} + +static int moxa_break_ctl(struct tty_struct *tty, int state) +{ + struct moxa_port *port = tty->driver_data; + + moxafunc(port->tableAddr, state ? FC_SendBreak : FC_StopBreak, + Magic_code); + return 0; +} + +static const struct tty_operations moxa_ops = { + .open = moxa_open, + .close = moxa_close, + .write = moxa_write, + .write_room = moxa_write_room, + .flush_buffer = moxa_flush_buffer, + .chars_in_buffer = moxa_chars_in_buffer, + .ioctl = moxa_ioctl, + .set_termios = moxa_set_termios, + .stop = moxa_stop, + .start = moxa_start, + .hangup = moxa_hangup, + .break_ctl = moxa_break_ctl, + .tiocmget = moxa_tiocmget, + .tiocmset = moxa_tiocmset, +}; + +static const struct tty_port_operations moxa_port_ops = { + .carrier_raised = moxa_carrier_raised, + .dtr_rts = moxa_dtr_rts, + .shutdown = moxa_shutdown, +}; + +static struct tty_driver *moxaDriver; +static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0); + +/* + * HW init + */ + +static int moxa_check_fw_model(struct moxa_board_conf *brd, u8 model) +{ + switch (brd->boardType) { + case MOXA_BOARD_C218_ISA: + case MOXA_BOARD_C218_PCI: + if (model != 1) + goto err; + break; + case MOXA_BOARD_CP204J: + if (model != 3) + goto err; + break; + default: + if (model != 2) + goto err; + break; + } + return 0; +err: + return -EINVAL; +} + +static int moxa_check_fw(const void *ptr) +{ + const __le16 *lptr = ptr; + + if (*lptr != cpu_to_le16(0x7980)) + return -EINVAL; + + return 0; +} + +static int moxa_load_bios(struct moxa_board_conf *brd, const u8 *buf, + size_t len) +{ + void __iomem *baseAddr = brd->basemem; + u16 tmp; + + writeb(HW_reset, baseAddr + Control_reg); /* reset */ + msleep(10); + memset_io(baseAddr, 0, 4096); + memcpy_toio(baseAddr, buf, len); /* download BIOS */ + writeb(0, baseAddr + Control_reg); /* restart */ + + msleep(2000); + + switch (brd->boardType) { + case MOXA_BOARD_C218_ISA: + case MOXA_BOARD_C218_PCI: + tmp = readw(baseAddr + C218_key); + if (tmp != C218_KeyCode) + goto err; + break; + case MOXA_BOARD_CP204J: + tmp = readw(baseAddr + C218_key); + if (tmp != CP204J_KeyCode) + goto err; + break; + default: + tmp = readw(baseAddr + C320_key); + if (tmp != C320_KeyCode) + goto err; + tmp = readw(baseAddr + C320_status); + if (tmp != STS_init) { + printk(KERN_ERR "MOXA: bios upload failed -- CPU/Basic " + "module not found\n"); + return -EIO; + } + break; + } + + return 0; +err: + printk(KERN_ERR "MOXA: bios upload failed -- board not found\n"); + return -EIO; +} + +static int moxa_load_320b(struct moxa_board_conf *brd, const u8 *ptr, + size_t len) +{ + void __iomem *baseAddr = brd->basemem; + + if (len < 7168) { + printk(KERN_ERR "MOXA: invalid 320 bios -- too short\n"); + return -EINVAL; + } + + writew(len - 7168 - 2, baseAddr + C320bapi_len); + writeb(1, baseAddr + Control_reg); /* Select Page 1 */ + memcpy_toio(baseAddr + DynPage_addr, ptr, 7168); + writeb(2, baseAddr + Control_reg); /* Select Page 2 */ + memcpy_toio(baseAddr + DynPage_addr, ptr + 7168, len - 7168); + + return 0; +} + +static int moxa_real_load_code(struct moxa_board_conf *brd, const void *ptr, + size_t len) +{ + void __iomem *baseAddr = brd->basemem; + const __le16 *uptr = ptr; + size_t wlen, len2, j; + unsigned long key, loadbuf, loadlen, checksum, checksum_ok; + unsigned int i, retry; + u16 usum, keycode; + + keycode = (brd->boardType == MOXA_BOARD_CP204J) ? CP204J_KeyCode : + C218_KeyCode; + + switch (brd->boardType) { + case MOXA_BOARD_CP204J: + case MOXA_BOARD_C218_ISA: + case MOXA_BOARD_C218_PCI: + key = C218_key; + loadbuf = C218_LoadBuf; + loadlen = C218DLoad_len; + checksum = C218check_sum; + checksum_ok = C218chksum_ok; + break; + default: + key = C320_key; + keycode = C320_KeyCode; + loadbuf = C320_LoadBuf; + loadlen = C320DLoad_len; + checksum = C320check_sum; + checksum_ok = C320chksum_ok; + break; + } + + usum = 0; + wlen = len >> 1; + for (i = 0; i < wlen; i++) + usum += le16_to_cpu(uptr[i]); + retry = 0; + do { + wlen = len >> 1; + j = 0; + while (wlen) { + len2 = (wlen > 2048) ? 2048 : wlen; + wlen -= len2; + memcpy_toio(baseAddr + loadbuf, ptr + j, len2 << 1); + j += len2 << 1; + + writew(len2, baseAddr + loadlen); + writew(0, baseAddr + key); + for (i = 0; i < 100; i++) { + if (readw(baseAddr + key) == keycode) + break; + msleep(10); + } + if (readw(baseAddr + key) != keycode) + return -EIO; + } + writew(0, baseAddr + loadlen); + writew(usum, baseAddr + checksum); + writew(0, baseAddr + key); + for (i = 0; i < 100; i++) { + if (readw(baseAddr + key) == keycode) + break; + msleep(10); + } + retry++; + } while ((readb(baseAddr + checksum_ok) != 1) && (retry < 3)); + if (readb(baseAddr + checksum_ok) != 1) + return -EIO; + + writew(0, baseAddr + key); + for (i = 0; i < 600; i++) { + if (readw(baseAddr + Magic_no) == Magic_code) + break; + msleep(10); + } + if (readw(baseAddr + Magic_no) != Magic_code) + return -EIO; + + if (MOXA_IS_320(brd)) { + if (brd->busType == MOXA_BUS_TYPE_PCI) { /* ASIC board */ + writew(0x3800, baseAddr + TMS320_PORT1); + writew(0x3900, baseAddr + TMS320_PORT2); + writew(28499, baseAddr + TMS320_CLOCK); + } else { + writew(0x3200, baseAddr + TMS320_PORT1); + writew(0x3400, baseAddr + TMS320_PORT2); + writew(19999, baseAddr + TMS320_CLOCK); + } + } + writew(1, baseAddr + Disable_IRQ); + writew(0, baseAddr + Magic_no); + for (i = 0; i < 500; i++) { + if (readw(baseAddr + Magic_no) == Magic_code) + break; + msleep(10); + } + if (readw(baseAddr + Magic_no) != Magic_code) + return -EIO; + + if (MOXA_IS_320(brd)) { + j = readw(baseAddr + Module_cnt); + if (j <= 0) + return -EIO; + brd->numPorts = j * 8; + writew(j, baseAddr + Module_no); + writew(0, baseAddr + Magic_no); + for (i = 0; i < 600; i++) { + if (readw(baseAddr + Magic_no) == Magic_code) + break; + msleep(10); + } + if (readw(baseAddr + Magic_no) != Magic_code) + return -EIO; + } + brd->intNdx = baseAddr + IRQindex; + brd->intPend = baseAddr + IRQpending; + brd->intTable = baseAddr + IRQtable; + + return 0; +} + +static int moxa_load_code(struct moxa_board_conf *brd, const void *ptr, + size_t len) +{ + void __iomem *ofsAddr, *baseAddr = brd->basemem; + struct moxa_port *port; + int retval, i; + + if (len % 2) { + printk(KERN_ERR "MOXA: bios length is not even\n"); + return -EINVAL; + } + + retval = moxa_real_load_code(brd, ptr, len); /* may change numPorts */ + if (retval) + return retval; + + switch (brd->boardType) { + case MOXA_BOARD_C218_ISA: + case MOXA_BOARD_C218_PCI: + case MOXA_BOARD_CP204J: + port = brd->ports; + for (i = 0; i < brd->numPorts; i++, port++) { + port->board = brd; + port->DCDState = 0; + port->tableAddr = baseAddr + Extern_table + + Extern_size * i; + ofsAddr = port->tableAddr; + writew(C218rx_mask, ofsAddr + RX_mask); + writew(C218tx_mask, ofsAddr + TX_mask); + writew(C218rx_spage + i * C218buf_pageno, ofsAddr + Page_rxb); + writew(readw(ofsAddr + Page_rxb) + C218rx_pageno, ofsAddr + EndPage_rxb); + + writew(C218tx_spage + i * C218buf_pageno, ofsAddr + Page_txb); + writew(readw(ofsAddr + Page_txb) + C218tx_pageno, ofsAddr + EndPage_txb); + + } + break; + default: + port = brd->ports; + for (i = 0; i < brd->numPorts; i++, port++) { + port->board = brd; + port->DCDState = 0; + port->tableAddr = baseAddr + Extern_table + + Extern_size * i; + ofsAddr = port->tableAddr; + switch (brd->numPorts) { + case 8: + writew(C320p8rx_mask, ofsAddr + RX_mask); + writew(C320p8tx_mask, ofsAddr + TX_mask); + writew(C320p8rx_spage + i * C320p8buf_pgno, ofsAddr + Page_rxb); + writew(readw(ofsAddr + Page_rxb) + C320p8rx_pgno, ofsAddr + EndPage_rxb); + writew(C320p8tx_spage + i * C320p8buf_pgno, ofsAddr + Page_txb); + writew(readw(ofsAddr + Page_txb) + C320p8tx_pgno, ofsAddr + EndPage_txb); + + break; + case 16: + writew(C320p16rx_mask, ofsAddr + RX_mask); + writew(C320p16tx_mask, ofsAddr + TX_mask); + writew(C320p16rx_spage + i * C320p16buf_pgno, ofsAddr + Page_rxb); + writew(readw(ofsAddr + Page_rxb) + C320p16rx_pgno, ofsAddr + EndPage_rxb); + writew(C320p16tx_spage + i * C320p16buf_pgno, ofsAddr + Page_txb); + writew(readw(ofsAddr + Page_txb) + C320p16tx_pgno, ofsAddr + EndPage_txb); + break; + + case 24: + writew(C320p24rx_mask, ofsAddr + RX_mask); + writew(C320p24tx_mask, ofsAddr + TX_mask); + writew(C320p24rx_spage + i * C320p24buf_pgno, ofsAddr + Page_rxb); + writew(readw(ofsAddr + Page_rxb) + C320p24rx_pgno, ofsAddr + EndPage_rxb); + writew(C320p24tx_spage + i * C320p24buf_pgno, ofsAddr + Page_txb); + writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb); + break; + case 32: + writew(C320p32rx_mask, ofsAddr + RX_mask); + writew(C320p32tx_mask, ofsAddr + TX_mask); + writew(C320p32tx_ofs, ofsAddr + Ofs_txb); + writew(C320p32rx_spage + i * C320p32buf_pgno, ofsAddr + Page_rxb); + writew(readb(ofsAddr + Page_rxb), ofsAddr + EndPage_rxb); + writew(C320p32tx_spage + i * C320p32buf_pgno, ofsAddr + Page_txb); + writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb); + break; + } + } + break; + } + return 0; +} + +static int moxa_load_fw(struct moxa_board_conf *brd, const struct firmware *fw) +{ + const void *ptr = fw->data; + char rsn[64]; + u16 lens[5]; + size_t len; + unsigned int a, lenp, lencnt; + int ret = -EINVAL; + struct { + __le32 magic; /* 0x34303430 */ + u8 reserved1[2]; + u8 type; /* UNIX = 3 */ + u8 model; /* C218T=1, C320T=2, CP204=3 */ + u8 reserved2[8]; + __le16 len[5]; + } const *hdr = ptr; + + BUILD_BUG_ON(ARRAY_SIZE(hdr->len) != ARRAY_SIZE(lens)); + + if (fw->size < MOXA_FW_HDRLEN) { + strcpy(rsn, "too short (even header won't fit)"); + goto err; + } + if (hdr->magic != cpu_to_le32(0x30343034)) { + sprintf(rsn, "bad magic: %.8x", le32_to_cpu(hdr->magic)); + goto err; + } + if (hdr->type != 3) { + sprintf(rsn, "not for linux, type is %u", hdr->type); + goto err; + } + if (moxa_check_fw_model(brd, hdr->model)) { + sprintf(rsn, "not for this card, model is %u", hdr->model); + goto err; + } + + len = MOXA_FW_HDRLEN; + lencnt = hdr->model == 2 ? 5 : 3; + for (a = 0; a < ARRAY_SIZE(lens); a++) { + lens[a] = le16_to_cpu(hdr->len[a]); + if (lens[a] && len + lens[a] <= fw->size && + moxa_check_fw(&fw->data[len])) + printk(KERN_WARNING "MOXA firmware: unexpected input " + "at offset %u, but going on\n", (u32)len); + if (!lens[a] && a < lencnt) { + sprintf(rsn, "too few entries in fw file"); + goto err; + } + len += lens[a]; + } + + if (len != fw->size) { + sprintf(rsn, "bad length: %u (should be %u)", (u32)fw->size, + (u32)len); + goto err; + } + + ptr += MOXA_FW_HDRLEN; + lenp = 0; /* bios */ + + strcpy(rsn, "read above"); + + ret = moxa_load_bios(brd, ptr, lens[lenp]); + if (ret) + goto err; + + /* we skip the tty section (lens[1]), since we don't need it */ + ptr += lens[lenp] + lens[lenp + 1]; + lenp += 2; /* comm */ + + if (hdr->model == 2) { + ret = moxa_load_320b(brd, ptr, lens[lenp]); + if (ret) + goto err; + /* skip another tty */ + ptr += lens[lenp] + lens[lenp + 1]; + lenp += 2; + } + + ret = moxa_load_code(brd, ptr, lens[lenp]); + if (ret) + goto err; + + return 0; +err: + printk(KERN_ERR "firmware failed to load, reason: %s\n", rsn); + return ret; +} + +static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev) +{ + const struct firmware *fw; + const char *file; + struct moxa_port *p; + unsigned int i; + int ret; + + brd->ports = kcalloc(MAX_PORTS_PER_BOARD, sizeof(*brd->ports), + GFP_KERNEL); + if (brd->ports == NULL) { + printk(KERN_ERR "cannot allocate memory for ports\n"); + ret = -ENOMEM; + goto err; + } + + for (i = 0, p = brd->ports; i < MAX_PORTS_PER_BOARD; i++, p++) { + tty_port_init(&p->port); + p->port.ops = &moxa_port_ops; + p->type = PORT_16550A; + p->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; + } + + switch (brd->boardType) { + case MOXA_BOARD_C218_ISA: + case MOXA_BOARD_C218_PCI: + file = "c218tunx.cod"; + break; + case MOXA_BOARD_CP204J: + file = "cp204unx.cod"; + break; + default: + file = "c320tunx.cod"; + break; + } + + ret = request_firmware(&fw, file, dev); + if (ret) { + printk(KERN_ERR "MOXA: request_firmware failed. Make sure " + "you've placed '%s' file into your firmware " + "loader directory (e.g. /lib/firmware)\n", + file); + goto err_free; + } + + ret = moxa_load_fw(brd, fw); + + release_firmware(fw); + + if (ret) + goto err_free; + + spin_lock_bh(&moxa_lock); + brd->ready = 1; + if (!timer_pending(&moxaTimer)) + mod_timer(&moxaTimer, jiffies + HZ / 50); + spin_unlock_bh(&moxa_lock); + + return 0; +err_free: + kfree(brd->ports); +err: + return ret; +} + +static void moxa_board_deinit(struct moxa_board_conf *brd) +{ + unsigned int a, opened; + + mutex_lock(&moxa_openlock); + spin_lock_bh(&moxa_lock); + brd->ready = 0; + spin_unlock_bh(&moxa_lock); + + /* pci hot-un-plug support */ + for (a = 0; a < brd->numPorts; a++) + if (brd->ports[a].port.flags & ASYNC_INITIALIZED) { + struct tty_struct *tty = tty_port_tty_get( + &brd->ports[a].port); + if (tty) { + tty_hangup(tty); + tty_kref_put(tty); + } + } + while (1) { + opened = 0; + for (a = 0; a < brd->numPorts; a++) + if (brd->ports[a].port.flags & ASYNC_INITIALIZED) + opened++; + mutex_unlock(&moxa_openlock); + if (!opened) + break; + msleep(50); + mutex_lock(&moxa_openlock); + } + + iounmap(brd->basemem); + brd->basemem = NULL; + kfree(brd->ports); +} + +#ifdef CONFIG_PCI +static int __devinit moxa_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct moxa_board_conf *board; + unsigned int i; + int board_type = ent->driver_data; + int retval; + + retval = pci_enable_device(pdev); + if (retval) { + dev_err(&pdev->dev, "can't enable pci device\n"); + goto err; + } + + for (i = 0; i < MAX_BOARDS; i++) + if (moxa_boards[i].basemem == NULL) + break; + + retval = -ENODEV; + if (i >= MAX_BOARDS) { + dev_warn(&pdev->dev, "more than %u MOXA Intellio family boards " + "found. Board is ignored.\n", MAX_BOARDS); + goto err; + } + + board = &moxa_boards[i]; + + retval = pci_request_region(pdev, 2, "moxa-base"); + if (retval) { + dev_err(&pdev->dev, "can't request pci region 2\n"); + goto err; + } + + board->basemem = ioremap_nocache(pci_resource_start(pdev, 2), 0x4000); + if (board->basemem == NULL) { + dev_err(&pdev->dev, "can't remap io space 2\n"); + goto err_reg; + } + + board->boardType = board_type; + switch (board_type) { + case MOXA_BOARD_C218_ISA: + case MOXA_BOARD_C218_PCI: + board->numPorts = 8; + break; + + case MOXA_BOARD_CP204J: + board->numPorts = 4; + break; + default: + board->numPorts = 0; + break; + } + board->busType = MOXA_BUS_TYPE_PCI; + + retval = moxa_init_board(board, &pdev->dev); + if (retval) + goto err_base; + + pci_set_drvdata(pdev, board); + + dev_info(&pdev->dev, "board '%s' ready (%u ports, firmware loaded)\n", + moxa_brdname[board_type - 1], board->numPorts); + + return 0; +err_base: + iounmap(board->basemem); + board->basemem = NULL; +err_reg: + pci_release_region(pdev, 2); +err: + return retval; +} + +static void __devexit moxa_pci_remove(struct pci_dev *pdev) +{ + struct moxa_board_conf *brd = pci_get_drvdata(pdev); + + moxa_board_deinit(brd); + + pci_release_region(pdev, 2); +} + +static struct pci_driver moxa_pci_driver = { + .name = "moxa", + .id_table = moxa_pcibrds, + .probe = moxa_pci_probe, + .remove = __devexit_p(moxa_pci_remove) +}; +#endif /* CONFIG_PCI */ + +static int __init moxa_init(void) +{ + unsigned int isabrds = 0; + int retval = 0; + struct moxa_board_conf *brd = moxa_boards; + unsigned int i; + + printk(KERN_INFO "MOXA Intellio family driver version %s\n", + MOXA_VERSION); + moxaDriver = alloc_tty_driver(MAX_PORTS + 1); + if (!moxaDriver) + return -ENOMEM; + + moxaDriver->owner = THIS_MODULE; + moxaDriver->name = "ttyMX"; + moxaDriver->major = ttymajor; + moxaDriver->minor_start = 0; + moxaDriver->type = TTY_DRIVER_TYPE_SERIAL; + moxaDriver->subtype = SERIAL_TYPE_NORMAL; + moxaDriver->init_termios = tty_std_termios; + moxaDriver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; + moxaDriver->init_termios.c_ispeed = 9600; + moxaDriver->init_termios.c_ospeed = 9600; + moxaDriver->flags = TTY_DRIVER_REAL_RAW; + tty_set_operations(moxaDriver, &moxa_ops); + + if (tty_register_driver(moxaDriver)) { + printk(KERN_ERR "can't register MOXA Smartio tty driver!\n"); + put_tty_driver(moxaDriver); + return -1; + } + + /* Find the boards defined from module args. */ + + for (i = 0; i < MAX_BOARDS; i++) { + if (!baseaddr[i]) + break; + if (type[i] == MOXA_BOARD_C218_ISA || + type[i] == MOXA_BOARD_C320_ISA) { + pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n", + isabrds + 1, moxa_brdname[type[i] - 1], + baseaddr[i]); + brd->boardType = type[i]; + brd->numPorts = type[i] == MOXA_BOARD_C218_ISA ? 8 : + numports[i]; + brd->busType = MOXA_BUS_TYPE_ISA; + brd->basemem = ioremap_nocache(baseaddr[i], 0x4000); + if (!brd->basemem) { + printk(KERN_ERR "MOXA: can't remap %lx\n", + baseaddr[i]); + continue; + } + if (moxa_init_board(brd, NULL)) { + iounmap(brd->basemem); + brd->basemem = NULL; + continue; + } + + printk(KERN_INFO "MOXA isa board found at 0x%.8lu and " + "ready (%u ports, firmware loaded)\n", + baseaddr[i], brd->numPorts); + + brd++; + isabrds++; + } + } + +#ifdef CONFIG_PCI + retval = pci_register_driver(&moxa_pci_driver); + if (retval) { + printk(KERN_ERR "Can't register MOXA pci driver!\n"); + if (isabrds) + retval = 0; + } +#endif + + return retval; +} + +static void __exit moxa_exit(void) +{ + unsigned int i; + +#ifdef CONFIG_PCI + pci_unregister_driver(&moxa_pci_driver); +#endif + + for (i = 0; i < MAX_BOARDS; i++) /* ISA boards */ + if (moxa_boards[i].ready) + moxa_board_deinit(&moxa_boards[i]); + + del_timer_sync(&moxaTimer); + + if (tty_unregister_driver(moxaDriver)) + printk(KERN_ERR "Couldn't unregister MOXA Intellio family " + "serial driver\n"); + put_tty_driver(moxaDriver); +} + +module_init(moxa_init); +module_exit(moxa_exit); + +static void moxa_shutdown(struct tty_port *port) +{ + struct moxa_port *ch = container_of(port, struct moxa_port, port); + MoxaPortDisable(ch); + MoxaPortFlushData(ch, 2); + clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); +} + +static int moxa_carrier_raised(struct tty_port *port) +{ + struct moxa_port *ch = container_of(port, struct moxa_port, port); + int dcd; + + spin_lock_irq(&port->lock); + dcd = ch->DCDState; + spin_unlock_irq(&port->lock); + return dcd; +} + +static void moxa_dtr_rts(struct tty_port *port, int onoff) +{ + struct moxa_port *ch = container_of(port, struct moxa_port, port); + MoxaPortLineCtrl(ch, onoff, onoff); +} + + +static int moxa_open(struct tty_struct *tty, struct file *filp) +{ + struct moxa_board_conf *brd; + struct moxa_port *ch; + int port; + int retval; + + port = tty->index; + if (port == MAX_PORTS) { + return capable(CAP_SYS_ADMIN) ? 0 : -EPERM; + } + if (mutex_lock_interruptible(&moxa_openlock)) + return -ERESTARTSYS; + brd = &moxa_boards[port / MAX_PORTS_PER_BOARD]; + if (!brd->ready) { + mutex_unlock(&moxa_openlock); + return -ENODEV; + } + + if (port % MAX_PORTS_PER_BOARD >= brd->numPorts) { + mutex_unlock(&moxa_openlock); + return -ENODEV; + } + + ch = &brd->ports[port % MAX_PORTS_PER_BOARD]; + ch->port.count++; + tty->driver_data = ch; + tty_port_tty_set(&ch->port, tty); + mutex_lock(&ch->port.mutex); + if (!(ch->port.flags & ASYNC_INITIALIZED)) { + ch->statusflags = 0; + moxa_set_tty_param(tty, tty->termios); + MoxaPortLineCtrl(ch, 1, 1); + MoxaPortEnable(ch); + MoxaSetFifo(ch, ch->type == PORT_16550A); + ch->port.flags |= ASYNC_INITIALIZED; + } + mutex_unlock(&ch->port.mutex); + mutex_unlock(&moxa_openlock); + + retval = tty_port_block_til_ready(&ch->port, tty, filp); + if (retval == 0) + set_bit(ASYNCB_NORMAL_ACTIVE, &ch->port.flags); + return retval; +} + +static void moxa_close(struct tty_struct *tty, struct file *filp) +{ + struct moxa_port *ch = tty->driver_data; + ch->cflag = tty->termios->c_cflag; + tty_port_close(&ch->port, tty, filp); +} + +static int moxa_write(struct tty_struct *tty, + const unsigned char *buf, int count) +{ + struct moxa_port *ch = tty->driver_data; + int len; + + if (ch == NULL) + return 0; + + spin_lock_bh(&moxa_lock); + len = MoxaPortWriteData(tty, buf, count); + spin_unlock_bh(&moxa_lock); + + set_bit(LOWWAIT, &ch->statusflags); + return len; +} + +static int moxa_write_room(struct tty_struct *tty) +{ + struct moxa_port *ch; + + if (tty->stopped) + return 0; + ch = tty->driver_data; + if (ch == NULL) + return 0; + return MoxaPortTxFree(ch); +} + +static void moxa_flush_buffer(struct tty_struct *tty) +{ + struct moxa_port *ch = tty->driver_data; + + if (ch == NULL) + return; + MoxaPortFlushData(ch, 1); + tty_wakeup(tty); +} + +static int moxa_chars_in_buffer(struct tty_struct *tty) +{ + struct moxa_port *ch = tty->driver_data; + int chars; + + chars = MoxaPortTxQueue(ch); + if (chars) + /* + * Make it possible to wakeup anything waiting for output + * in tty_ioctl.c, etc. + */ + set_bit(EMPTYWAIT, &ch->statusflags); + return chars; +} + +static int moxa_tiocmget(struct tty_struct *tty) +{ + struct moxa_port *ch = tty->driver_data; + int flag = 0, dtr, rts; + + MoxaPortGetLineOut(ch, &dtr, &rts); + if (dtr) + flag |= TIOCM_DTR; + if (rts) + flag |= TIOCM_RTS; + dtr = MoxaPortLineStatus(ch); + if (dtr & 1) + flag |= TIOCM_CTS; + if (dtr & 2) + flag |= TIOCM_DSR; + if (dtr & 4) + flag |= TIOCM_CD; + return flag; +} + +static int moxa_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + struct moxa_port *ch; + int port; + int dtr, rts; + + port = tty->index; + mutex_lock(&moxa_openlock); + ch = tty->driver_data; + if (!ch) { + mutex_unlock(&moxa_openlock); + return -EINVAL; + } + + MoxaPortGetLineOut(ch, &dtr, &rts); + if (set & TIOCM_RTS) + rts = 1; + if (set & TIOCM_DTR) + dtr = 1; + if (clear & TIOCM_RTS) + rts = 0; + if (clear & TIOCM_DTR) + dtr = 0; + MoxaPortLineCtrl(ch, dtr, rts); + mutex_unlock(&moxa_openlock); + return 0; +} + +static void moxa_set_termios(struct tty_struct *tty, + struct ktermios *old_termios) +{ + struct moxa_port *ch = tty->driver_data; + + if (ch == NULL) + return; + moxa_set_tty_param(tty, old_termios); + if (!(old_termios->c_cflag & CLOCAL) && C_CLOCAL(tty)) + wake_up_interruptible(&ch->port.open_wait); +} + +static void moxa_stop(struct tty_struct *tty) +{ + struct moxa_port *ch = tty->driver_data; + + if (ch == NULL) + return; + MoxaPortTxDisable(ch); + set_bit(TXSTOPPED, &ch->statusflags); +} + + +static void moxa_start(struct tty_struct *tty) +{ + struct moxa_port *ch = tty->driver_data; + + if (ch == NULL) + return; + + if (!(ch->statusflags & TXSTOPPED)) + return; + + MoxaPortTxEnable(ch); + clear_bit(TXSTOPPED, &ch->statusflags); +} + +static void moxa_hangup(struct tty_struct *tty) +{ + struct moxa_port *ch = tty->driver_data; + tty_port_hangup(&ch->port); +} + +static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) +{ + struct tty_struct *tty; + unsigned long flags; + dcd = !!dcd; + + spin_lock_irqsave(&p->port.lock, flags); + if (dcd != p->DCDState) { + p->DCDState = dcd; + spin_unlock_irqrestore(&p->port.lock, flags); + tty = tty_port_tty_get(&p->port); + if (tty && C_CLOCAL(tty) && !dcd) + tty_hangup(tty); + tty_kref_put(tty); + } + else + spin_unlock_irqrestore(&p->port.lock, flags); +} + +static int moxa_poll_port(struct moxa_port *p, unsigned int handle, + u16 __iomem *ip) +{ + struct tty_struct *tty = tty_port_tty_get(&p->port); + void __iomem *ofsAddr; + unsigned int inited = p->port.flags & ASYNC_INITIALIZED; + u16 intr; + + if (tty) { + if (test_bit(EMPTYWAIT, &p->statusflags) && + MoxaPortTxQueue(p) == 0) { + clear_bit(EMPTYWAIT, &p->statusflags); + tty_wakeup(tty); + } + if (test_bit(LOWWAIT, &p->statusflags) && !tty->stopped && + MoxaPortTxQueue(p) <= WAKEUP_CHARS) { + clear_bit(LOWWAIT, &p->statusflags); + tty_wakeup(tty); + } + + if (inited && !test_bit(TTY_THROTTLED, &tty->flags) && + MoxaPortRxQueue(p) > 0) { /* RX */ + MoxaPortReadData(p); + tty_schedule_flip(tty); + } + } else { + clear_bit(EMPTYWAIT, &p->statusflags); + MoxaPortFlushData(p, 0); /* flush RX */ + } + + if (!handle) /* nothing else to do */ + goto put; + + intr = readw(ip); /* port irq status */ + if (intr == 0) + goto put; + + writew(0, ip); /* ACK port */ + ofsAddr = p->tableAddr; + if (intr & IntrTx) /* disable tx intr */ + writew(readw(ofsAddr + HostStat) & ~WakeupTx, + ofsAddr + HostStat); + + if (!inited) + goto put; + + if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */ + tty_insert_flip_char(tty, 0, TTY_BREAK); + tty_schedule_flip(tty); + } + + if (intr & IntrLine) + moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state); +put: + tty_kref_put(tty); + + return 0; +} + +static void moxa_poll(unsigned long ignored) +{ + struct moxa_board_conf *brd; + u16 __iomem *ip; + unsigned int card, port, served = 0; + + spin_lock(&moxa_lock); + for (card = 0; card < MAX_BOARDS; card++) { + brd = &moxa_boards[card]; + if (!brd->ready) + continue; + + served++; + + ip = NULL; + if (readb(brd->intPend) == 0xff) + ip = brd->intTable + readb(brd->intNdx); + + for (port = 0; port < brd->numPorts; port++) + moxa_poll_port(&brd->ports[port], !!ip, ip + port); + + if (ip) + writeb(0, brd->intPend); /* ACK */ + + if (moxaLowWaterChk) { + struct moxa_port *p = brd->ports; + for (port = 0; port < brd->numPorts; port++, p++) + if (p->lowChkFlag) { + p->lowChkFlag = 0; + moxa_low_water_check(p->tableAddr); + } + } + } + moxaLowWaterChk = 0; + + if (served) + mod_timer(&moxaTimer, jiffies + HZ / 50); + spin_unlock(&moxa_lock); +} + +/******************************************************************************/ + +static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_termios) +{ + register struct ktermios *ts = tty->termios; + struct moxa_port *ch = tty->driver_data; + int rts, cts, txflow, rxflow, xany, baud; + + rts = cts = txflow = rxflow = xany = 0; + if (ts->c_cflag & CRTSCTS) + rts = cts = 1; + if (ts->c_iflag & IXON) + txflow = 1; + if (ts->c_iflag & IXOFF) + rxflow = 1; + if (ts->c_iflag & IXANY) + xany = 1; + + /* Clear the features we don't support */ + ts->c_cflag &= ~CMSPAR; + MoxaPortFlowCtrl(ch, rts, cts, txflow, rxflow, xany); + baud = MoxaPortSetTermio(ch, ts, tty_get_baud_rate(tty)); + if (baud == -1) + baud = tty_termios_baud_rate(old_termios); + /* Not put the baud rate into the termios data */ + tty_encode_baud_rate(tty, baud, baud); +} + +/***************************************************************************** + * Driver level functions: * + *****************************************************************************/ + +static void MoxaPortFlushData(struct moxa_port *port, int mode) +{ + void __iomem *ofsAddr; + if (mode < 0 || mode > 2) + return; + ofsAddr = port->tableAddr; + moxafunc(ofsAddr, FC_FlushQueue, mode); + if (mode != 1) { + port->lowChkFlag = 0; + moxa_low_water_check(ofsAddr); + } +} + +/* + * Moxa Port Number Description: + * + * MOXA serial driver supports up to 4 MOXA-C218/C320 boards. And, + * the port number using in MOXA driver functions will be 0 to 31 for + * first MOXA board, 32 to 63 for second, 64 to 95 for third and 96 + * to 127 for fourth. For example, if you setup three MOXA boards, + * first board is C218, second board is C320-16 and third board is + * C320-32. The port number of first board (C218 - 8 ports) is from + * 0 to 7. The port number of second board (C320 - 16 ports) is form + * 32 to 47. The port number of third board (C320 - 32 ports) is from + * 64 to 95. And those port numbers form 8 to 31, 48 to 63 and 96 to + * 127 will be invalid. + * + * + * Moxa Functions Description: + * + * Function 1: Driver initialization routine, this routine must be + * called when initialized driver. + * Syntax: + * void MoxaDriverInit(); + * + * + * Function 2: Moxa driver private IOCTL command processing. + * Syntax: + * int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port); + * + * unsigned int cmd : IOCTL command + * unsigned long arg : IOCTL argument + * int port : port number (0 - 127) + * + * return: 0 (OK) + * -EINVAL + * -ENOIOCTLCMD + * + * + * Function 6: Enable this port to start Tx/Rx data. + * Syntax: + * void MoxaPortEnable(int port); + * int port : port number (0 - 127) + * + * + * Function 7: Disable this port + * Syntax: + * void MoxaPortDisable(int port); + * int port : port number (0 - 127) + * + * + * Function 10: Setting baud rate of this port. + * Syntax: + * speed_t MoxaPortSetBaud(int port, speed_t baud); + * int port : port number (0 - 127) + * long baud : baud rate (50 - 115200) + * + * return: 0 : this port is invalid or baud < 50 + * 50 - 115200 : the real baud rate set to the port, if + * the argument baud is large than maximun + * available baud rate, the real setting + * baud rate will be the maximun baud rate. + * + * + * Function 12: Configure the port. + * Syntax: + * int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud); + * int port : port number (0 - 127) + * struct ktermios * termio : termio structure pointer + * speed_t baud : baud rate + * + * return: -1 : this port is invalid or termio == NULL + * 0 : setting O.K. + * + * + * Function 13: Get the DTR/RTS state of this port. + * Syntax: + * int MoxaPortGetLineOut(int port, int *dtrState, int *rtsState); + * int port : port number (0 - 127) + * int * dtrState : pointer to INT to receive the current DTR + * state. (if NULL, this function will not + * write to this address) + * int * rtsState : pointer to INT to receive the current RTS + * state. (if NULL, this function will not + * write to this address) + * + * return: -1 : this port is invalid + * 0 : O.K. + * + * + * Function 14: Setting the DTR/RTS output state of this port. + * Syntax: + * void MoxaPortLineCtrl(int port, int dtrState, int rtsState); + * int port : port number (0 - 127) + * int dtrState : DTR output state (0: off, 1: on) + * int rtsState : RTS output state (0: off, 1: on) + * + * + * Function 15: Setting the flow control of this port. + * Syntax: + * void MoxaPortFlowCtrl(int port, int rtsFlow, int ctsFlow, int rxFlow, + * int txFlow,int xany); + * int port : port number (0 - 127) + * int rtsFlow : H/W RTS flow control (0: no, 1: yes) + * int ctsFlow : H/W CTS flow control (0: no, 1: yes) + * int rxFlow : S/W Rx XON/XOFF flow control (0: no, 1: yes) + * int txFlow : S/W Tx XON/XOFF flow control (0: no, 1: yes) + * int xany : S/W XANY flow control (0: no, 1: yes) + * + * + * Function 16: Get ths line status of this port + * Syntax: + * int MoxaPortLineStatus(int port); + * int port : port number (0 - 127) + * + * return: Bit 0 - CTS state (0: off, 1: on) + * Bit 1 - DSR state (0: off, 1: on) + * Bit 2 - DCD state (0: off, 1: on) + * + * + * Function 19: Flush the Rx/Tx buffer data of this port. + * Syntax: + * void MoxaPortFlushData(int port, int mode); + * int port : port number (0 - 127) + * int mode + * 0 : flush the Rx buffer + * 1 : flush the Tx buffer + * 2 : flush the Rx and Tx buffer + * + * + * Function 20: Write data. + * Syntax: + * int MoxaPortWriteData(int port, unsigned char * buffer, int length); + * int port : port number (0 - 127) + * unsigned char * buffer : pointer to write data buffer. + * int length : write data length + * + * return: 0 - length : real write data length + * + * + * Function 21: Read data. + * Syntax: + * int MoxaPortReadData(int port, struct tty_struct *tty); + * int port : port number (0 - 127) + * struct tty_struct *tty : tty for data + * + * return: 0 - length : real read data length + * + * + * Function 24: Get the Tx buffer current queued data bytes + * Syntax: + * int MoxaPortTxQueue(int port); + * int port : port number (0 - 127) + * + * return: .. : Tx buffer current queued data bytes + * + * + * Function 25: Get the Tx buffer current free space + * Syntax: + * int MoxaPortTxFree(int port); + * int port : port number (0 - 127) + * + * return: .. : Tx buffer current free space + * + * + * Function 26: Get the Rx buffer current queued data bytes + * Syntax: + * int MoxaPortRxQueue(int port); + * int port : port number (0 - 127) + * + * return: .. : Rx buffer current queued data bytes + * + * + * Function 28: Disable port data transmission. + * Syntax: + * void MoxaPortTxDisable(int port); + * int port : port number (0 - 127) + * + * + * Function 29: Enable port data transmission. + * Syntax: + * void MoxaPortTxEnable(int port); + * int port : port number (0 - 127) + * + * + * Function 31: Get the received BREAK signal count and reset it. + * Syntax: + * int MoxaPortResetBrkCnt(int port); + * int port : port number (0 - 127) + * + * return: 0 - .. : BREAK signal count + * + * + */ + +static void MoxaPortEnable(struct moxa_port *port) +{ + void __iomem *ofsAddr; + u16 lowwater = 512; + + ofsAddr = port->tableAddr; + writew(lowwater, ofsAddr + Low_water); + if (MOXA_IS_320(port->board)) + moxafunc(ofsAddr, FC_SetBreakIrq, 0); + else + writew(readw(ofsAddr + HostStat) | WakeupBreak, + ofsAddr + HostStat); + + moxafunc(ofsAddr, FC_SetLineIrq, Magic_code); + moxafunc(ofsAddr, FC_FlushQueue, 2); + + moxafunc(ofsAddr, FC_EnableCH, Magic_code); + MoxaPortLineStatus(port); +} + +static void MoxaPortDisable(struct moxa_port *port) +{ + void __iomem *ofsAddr = port->tableAddr; + + moxafunc(ofsAddr, FC_SetFlowCtl, 0); /* disable flow control */ + moxafunc(ofsAddr, FC_ClrLineIrq, Magic_code); + writew(0, ofsAddr + HostStat); + moxafunc(ofsAddr, FC_DisableCH, Magic_code); +} + +static speed_t MoxaPortSetBaud(struct moxa_port *port, speed_t baud) +{ + void __iomem *ofsAddr = port->tableAddr; + unsigned int clock, val; + speed_t max; + + max = MOXA_IS_320(port->board) ? 460800 : 921600; + if (baud < 50) + return 0; + if (baud > max) + baud = max; + clock = 921600; + val = clock / baud; + moxafunc(ofsAddr, FC_SetBaud, val); + baud = clock / val; + return baud; +} + +static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio, + speed_t baud) +{ + void __iomem *ofsAddr; + tcflag_t cflag; + tcflag_t mode = 0; + + ofsAddr = port->tableAddr; + cflag = termio->c_cflag; /* termio->c_cflag */ + + mode = termio->c_cflag & CSIZE; + if (mode == CS5) + mode = MX_CS5; + else if (mode == CS6) + mode = MX_CS6; + else if (mode == CS7) + mode = MX_CS7; + else if (mode == CS8) + mode = MX_CS8; + + if (termio->c_cflag & CSTOPB) { + if (mode == MX_CS5) + mode |= MX_STOP15; + else + mode |= MX_STOP2; + } else + mode |= MX_STOP1; + + if (termio->c_cflag & PARENB) { + if (termio->c_cflag & PARODD) + mode |= MX_PARODD; + else + mode |= MX_PAREVEN; + } else + mode |= MX_PARNONE; + + moxafunc(ofsAddr, FC_SetDataMode, (u16)mode); + + if (MOXA_IS_320(port->board) && baud >= 921600) + return -1; + + baud = MoxaPortSetBaud(port, baud); + + if (termio->c_iflag & (IXON | IXOFF | IXANY)) { + spin_lock_irq(&moxafunc_lock); + writeb(termio->c_cc[VSTART], ofsAddr + FuncArg); + writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1); + writeb(FC_SetXonXoff, ofsAddr + FuncCode); + moxa_wait_finish(ofsAddr); + spin_unlock_irq(&moxafunc_lock); + + } + return baud; +} + +static int MoxaPortGetLineOut(struct moxa_port *port, int *dtrState, + int *rtsState) +{ + if (dtrState) + *dtrState = !!(port->lineCtrl & DTR_ON); + if (rtsState) + *rtsState = !!(port->lineCtrl & RTS_ON); + + return 0; +} + +static void MoxaPortLineCtrl(struct moxa_port *port, int dtr, int rts) +{ + u8 mode = 0; + + if (dtr) + mode |= DTR_ON; + if (rts) + mode |= RTS_ON; + port->lineCtrl = mode; + moxafunc(port->tableAddr, FC_LineControl, mode); +} + +static void MoxaPortFlowCtrl(struct moxa_port *port, int rts, int cts, + int txflow, int rxflow, int txany) +{ + int mode = 0; + + if (rts) + mode |= RTS_FlowCtl; + if (cts) + mode |= CTS_FlowCtl; + if (txflow) + mode |= Tx_FlowCtl; + if (rxflow) + mode |= Rx_FlowCtl; + if (txany) + mode |= IXM_IXANY; + moxafunc(port->tableAddr, FC_SetFlowCtl, mode); +} + +static int MoxaPortLineStatus(struct moxa_port *port) +{ + void __iomem *ofsAddr; + int val; + + ofsAddr = port->tableAddr; + if (MOXA_IS_320(port->board)) + val = moxafuncret(ofsAddr, FC_LineStatus, 0); + else + val = readw(ofsAddr + FlagStat) >> 4; + val &= 0x0B; + if (val & 8) + val |= 4; + moxa_new_dcdstate(port, val & 8); + val &= 7; + return val; +} + +static int MoxaPortWriteData(struct tty_struct *tty, + const unsigned char *buffer, int len) +{ + struct moxa_port *port = tty->driver_data; + void __iomem *baseAddr, *ofsAddr, *ofs; + unsigned int c, total; + u16 head, tail, tx_mask, spage, epage; + u16 pageno, pageofs, bufhead; + + ofsAddr = port->tableAddr; + baseAddr = port->board->basemem; + tx_mask = readw(ofsAddr + TX_mask); + spage = readw(ofsAddr + Page_txb); + epage = readw(ofsAddr + EndPage_txb); + tail = readw(ofsAddr + TXwptr); + head = readw(ofsAddr + TXrptr); + c = (head > tail) ? (head - tail - 1) : (head - tail + tx_mask); + if (c > len) + c = len; + moxaLog.txcnt[port->port.tty->index] += c; + total = c; + if (spage == epage) { + bufhead = readw(ofsAddr + Ofs_txb); + writew(spage, baseAddr + Control_reg); + while (c > 0) { + if (head > tail) + len = head - tail - 1; + else + len = tx_mask + 1 - tail; + len = (c > len) ? len : c; + ofs = baseAddr + DynPage_addr + bufhead + tail; + memcpy_toio(ofs, buffer, len); + buffer += len; + tail = (tail + len) & tx_mask; + c -= len; + } + } else { + pageno = spage + (tail >> 13); + pageofs = tail & Page_mask; + while (c > 0) { + len = Page_size - pageofs; + if (len > c) + len = c; + writeb(pageno, baseAddr + Control_reg); + ofs = baseAddr + DynPage_addr + pageofs; + memcpy_toio(ofs, buffer, len); + buffer += len; + if (++pageno == epage) + pageno = spage; + pageofs = 0; + c -= len; + } + tail = (tail + total) & tx_mask; + } + writew(tail, ofsAddr + TXwptr); + writeb(1, ofsAddr + CD180TXirq); /* start to send */ + return total; +} + +static int MoxaPortReadData(struct moxa_port *port) +{ + struct tty_struct *tty = port->port.tty; + unsigned char *dst; + void __iomem *baseAddr, *ofsAddr, *ofs; + unsigned int count, len, total; + u16 tail, rx_mask, spage, epage; + u16 pageno, pageofs, bufhead, head; + + ofsAddr = port->tableAddr; + baseAddr = port->board->basemem; + head = readw(ofsAddr + RXrptr); + tail = readw(ofsAddr + RXwptr); + rx_mask = readw(ofsAddr + RX_mask); + spage = readw(ofsAddr + Page_rxb); + epage = readw(ofsAddr + EndPage_rxb); + count = (tail >= head) ? (tail - head) : (tail - head + rx_mask + 1); + if (count == 0) + return 0; + + total = count; + moxaLog.rxcnt[tty->index] += total; + if (spage == epage) { + bufhead = readw(ofsAddr + Ofs_rxb); + writew(spage, baseAddr + Control_reg); + while (count > 0) { + ofs = baseAddr + DynPage_addr + bufhead + head; + len = (tail >= head) ? (tail - head) : + (rx_mask + 1 - head); + len = tty_prepare_flip_string(tty, &dst, + min(len, count)); + memcpy_fromio(dst, ofs, len); + head = (head + len) & rx_mask; + count -= len; + } + } else { + pageno = spage + (head >> 13); + pageofs = head & Page_mask; + while (count > 0) { + writew(pageno, baseAddr + Control_reg); + ofs = baseAddr + DynPage_addr + pageofs; + len = tty_prepare_flip_string(tty, &dst, + min(Page_size - pageofs, count)); + memcpy_fromio(dst, ofs, len); + + count -= len; + pageofs = (pageofs + len) & Page_mask; + if (pageofs == 0 && ++pageno == epage) + pageno = spage; + } + head = (head + total) & rx_mask; + } + writew(head, ofsAddr + RXrptr); + if (readb(ofsAddr + FlagStat) & Xoff_state) { + moxaLowWaterChk = 1; + port->lowChkFlag = 1; + } + return total; +} + + +static int MoxaPortTxQueue(struct moxa_port *port) +{ + void __iomem *ofsAddr = port->tableAddr; + u16 rptr, wptr, mask; + + rptr = readw(ofsAddr + TXrptr); + wptr = readw(ofsAddr + TXwptr); + mask = readw(ofsAddr + TX_mask); + return (wptr - rptr) & mask; +} + +static int MoxaPortTxFree(struct moxa_port *port) +{ + void __iomem *ofsAddr = port->tableAddr; + u16 rptr, wptr, mask; + + rptr = readw(ofsAddr + TXrptr); + wptr = readw(ofsAddr + TXwptr); + mask = readw(ofsAddr + TX_mask); + return mask - ((wptr - rptr) & mask); +} + +static int MoxaPortRxQueue(struct moxa_port *port) +{ + void __iomem *ofsAddr = port->tableAddr; + u16 rptr, wptr, mask; + + rptr = readw(ofsAddr + RXrptr); + wptr = readw(ofsAddr + RXwptr); + mask = readw(ofsAddr + RX_mask); + return (wptr - rptr) & mask; +} + +static void MoxaPortTxDisable(struct moxa_port *port) +{ + moxafunc(port->tableAddr, FC_SetXoffState, Magic_code); +} + +static void MoxaPortTxEnable(struct moxa_port *port) +{ + moxafunc(port->tableAddr, FC_SetXonState, Magic_code); +} + +static int moxa_get_serial_info(struct moxa_port *info, + struct serial_struct __user *retinfo) +{ + struct serial_struct tmp = { + .type = info->type, + .line = info->port.tty->index, + .flags = info->port.flags, + .baud_base = 921600, + .close_delay = info->port.close_delay + }; + return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; +} + + +static int moxa_set_serial_info(struct moxa_port *info, + struct serial_struct __user *new_info) +{ + struct serial_struct new_serial; + + if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) + return -EFAULT; + + if (new_serial.irq != 0 || new_serial.port != 0 || + new_serial.custom_divisor != 0 || + new_serial.baud_base != 921600) + return -EPERM; + + if (!capable(CAP_SYS_ADMIN)) { + if (((new_serial.flags & ~ASYNC_USR_MASK) != + (info->port.flags & ~ASYNC_USR_MASK))) + return -EPERM; + } else + info->port.close_delay = new_serial.close_delay * HZ / 100; + + new_serial.flags = (new_serial.flags & ~ASYNC_FLAGS); + new_serial.flags |= (info->port.flags & ASYNC_FLAGS); + + MoxaSetFifo(info, new_serial.type == PORT_16550A); + + info->type = new_serial.type; + return 0; +} + + + +/***************************************************************************** + * Static local functions: * + *****************************************************************************/ + +static void MoxaSetFifo(struct moxa_port *port, int enable) +{ + void __iomem *ofsAddr = port->tableAddr; + + if (!enable) { + moxafunc(ofsAddr, FC_SetRxFIFOTrig, 0); + moxafunc(ofsAddr, FC_SetTxFIFOCnt, 1); + } else { + moxafunc(ofsAddr, FC_SetRxFIFOTrig, 3); + moxafunc(ofsAddr, FC_SetTxFIFOCnt, 16); + } +} diff --git a/drivers/tty/moxa.h b/drivers/tty/moxa.h new file mode 100644 index 000000000000..87d16ce57be7 --- /dev/null +++ b/drivers/tty/moxa.h @@ -0,0 +1,304 @@ +#ifndef MOXA_H_FILE +#define MOXA_H_FILE + +#define MOXA 0x400 +#define MOXA_GET_IQUEUE (MOXA + 1) /* get input buffered count */ +#define MOXA_GET_OQUEUE (MOXA + 2) /* get output buffered count */ +#define MOXA_GETDATACOUNT (MOXA + 23) +#define MOXA_GET_IOQUEUE (MOXA + 27) +#define MOXA_FLUSH_QUEUE (MOXA + 28) +#define MOXA_GETMSTATUS (MOXA + 65) + +/* + * System Configuration + */ + +#define Magic_code 0x404 + +/* + * for C218 BIOS initialization + */ +#define C218_ConfBase 0x800 +#define C218_status (C218_ConfBase + 0) /* BIOS running status */ +#define C218_diag (C218_ConfBase + 2) /* diagnostic status */ +#define C218_key (C218_ConfBase + 4) /* WORD (0x218 for C218) */ +#define C218DLoad_len (C218_ConfBase + 6) /* WORD */ +#define C218check_sum (C218_ConfBase + 8) /* BYTE */ +#define C218chksum_ok (C218_ConfBase + 0x0a) /* BYTE (1:ok) */ +#define C218_TestRx (C218_ConfBase + 0x10) /* 8 bytes for 8 ports */ +#define C218_TestTx (C218_ConfBase + 0x18) /* 8 bytes for 8 ports */ +#define C218_RXerr (C218_ConfBase + 0x20) /* 8 bytes for 8 ports */ +#define C218_ErrFlag (C218_ConfBase + 0x28) /* 8 bytes for 8 ports */ + +#define C218_LoadBuf 0x0F00 +#define C218_KeyCode 0x218 +#define CP204J_KeyCode 0x204 + +/* + * for C320 BIOS initialization + */ +#define C320_ConfBase 0x800 +#define C320_LoadBuf 0x0f00 +#define STS_init 0x05 /* for C320_status */ + +#define C320_status C320_ConfBase + 0 /* BIOS running status */ +#define C320_diag C320_ConfBase + 2 /* diagnostic status */ +#define C320_key C320_ConfBase + 4 /* WORD (0320H for C320) */ +#define C320DLoad_len C320_ConfBase + 6 /* WORD */ +#define C320check_sum C320_ConfBase + 8 /* WORD */ +#define C320chksum_ok C320_ConfBase + 0x0a /* WORD (1:ok) */ +#define C320bapi_len C320_ConfBase + 0x0c /* WORD */ +#define C320UART_no C320_ConfBase + 0x0e /* WORD */ + +#define C320_KeyCode 0x320 + +#define FixPage_addr 0x0000 /* starting addr of static page */ +#define DynPage_addr 0x2000 /* starting addr of dynamic page */ +#define C218_start 0x3000 /* starting addr of C218 BIOS prg */ +#define Control_reg 0x1ff0 /* select page and reset control */ +#define HW_reset 0x80 + +/* + * Function Codes + */ +#define FC_CardReset 0x80 +#define FC_ChannelReset 1 /* C320 firmware not supported */ +#define FC_EnableCH 2 +#define FC_DisableCH 3 +#define FC_SetParam 4 +#define FC_SetMode 5 +#define FC_SetRate 6 +#define FC_LineControl 7 +#define FC_LineStatus 8 +#define FC_XmitControl 9 +#define FC_FlushQueue 10 +#define FC_SendBreak 11 +#define FC_StopBreak 12 +#define FC_LoopbackON 13 +#define FC_LoopbackOFF 14 +#define FC_ClrIrqTable 15 +#define FC_SendXon 16 +#define FC_SetTermIrq 17 /* C320 firmware not supported */ +#define FC_SetCntIrq 18 /* C320 firmware not supported */ +#define FC_SetBreakIrq 19 +#define FC_SetLineIrq 20 +#define FC_SetFlowCtl 21 +#define FC_GenIrq 22 +#define FC_InCD180 23 +#define FC_OutCD180 24 +#define FC_InUARTreg 23 +#define FC_OutUARTreg 24 +#define FC_SetXonXoff 25 +#define FC_OutCD180CCR 26 +#define FC_ExtIQueue 27 +#define FC_ExtOQueue 28 +#define FC_ClrLineIrq 29 +#define FC_HWFlowCtl 30 +#define FC_GetClockRate 35 +#define FC_SetBaud 36 +#define FC_SetDataMode 41 +#define FC_GetCCSR 43 +#define FC_GetDataError 45 +#define FC_RxControl 50 +#define FC_ImmSend 51 +#define FC_SetXonState 52 +#define FC_SetXoffState 53 +#define FC_SetRxFIFOTrig 54 +#define FC_SetTxFIFOCnt 55 +#define FC_UnixRate 56 +#define FC_UnixResetTimer 57 + +#define RxFIFOTrig1 0 +#define RxFIFOTrig4 1 +#define RxFIFOTrig8 2 +#define RxFIFOTrig14 3 + +/* + * Dual-Ported RAM + */ +#define DRAM_global 0 +#define INT_data (DRAM_global + 0) +#define Config_base (DRAM_global + 0x108) + +#define IRQindex (INT_data + 0) +#define IRQpending (INT_data + 4) +#define IRQtable (INT_data + 8) + +/* + * Interrupt Status + */ +#define IntrRx 0x01 /* receiver data O.K. */ +#define IntrTx 0x02 /* transmit buffer empty */ +#define IntrFunc 0x04 /* function complete */ +#define IntrBreak 0x08 /* received break */ +#define IntrLine 0x10 /* line status change + for transmitter */ +#define IntrIntr 0x20 /* received INTR code */ +#define IntrQuit 0x40 /* received QUIT code */ +#define IntrEOF 0x80 /* received EOF code */ + +#define IntrRxTrigger 0x100 /* rx data count reach tigger value */ +#define IntrTxTrigger 0x200 /* tx data count below trigger value */ + +#define Magic_no (Config_base + 0) +#define Card_model_no (Config_base + 2) +#define Total_ports (Config_base + 4) +#define Module_cnt (Config_base + 8) +#define Module_no (Config_base + 10) +#define Timer_10ms (Config_base + 14) +#define Disable_IRQ (Config_base + 20) +#define TMS320_PORT1 (Config_base + 22) +#define TMS320_PORT2 (Config_base + 24) +#define TMS320_CLOCK (Config_base + 26) + +/* + * DATA BUFFER in DRAM + */ +#define Extern_table 0x400 /* Base address of the external table + (24 words * 64) total 3K bytes + (24 words * 128) total 6K bytes */ +#define Extern_size 0x60 /* 96 bytes */ +#define RXrptr 0x00 /* read pointer for RX buffer */ +#define RXwptr 0x02 /* write pointer for RX buffer */ +#define TXrptr 0x04 /* read pointer for TX buffer */ +#define TXwptr 0x06 /* write pointer for TX buffer */ +#define HostStat 0x08 /* IRQ flag and general flag */ +#define FlagStat 0x0A +#define FlowControl 0x0C /* B7 B6 B5 B4 B3 B2 B1 B0 */ + /* x x x x | | | | */ + /* | | | + CTS flow */ + /* | | +--- RTS flow */ + /* | +------ TX Xon/Xoff */ + /* +--------- RX Xon/Xoff */ +#define Break_cnt 0x0E /* received break count */ +#define CD180TXirq 0x10 /* if non-0: enable TX irq */ +#define RX_mask 0x12 +#define TX_mask 0x14 +#define Ofs_rxb 0x16 +#define Ofs_txb 0x18 +#define Page_rxb 0x1A +#define Page_txb 0x1C +#define EndPage_rxb 0x1E +#define EndPage_txb 0x20 +#define Data_error 0x22 +#define RxTrigger 0x28 +#define TxTrigger 0x2a + +#define rRXwptr 0x34 +#define Low_water 0x36 + +#define FuncCode 0x40 +#define FuncArg 0x42 +#define FuncArg1 0x44 + +#define C218rx_size 0x2000 /* 8K bytes */ +#define C218tx_size 0x8000 /* 32K bytes */ + +#define C218rx_mask (C218rx_size - 1) +#define C218tx_mask (C218tx_size - 1) + +#define C320p8rx_size 0x2000 +#define C320p8tx_size 0x8000 +#define C320p8rx_mask (C320p8rx_size - 1) +#define C320p8tx_mask (C320p8tx_size - 1) + +#define C320p16rx_size 0x2000 +#define C320p16tx_size 0x4000 +#define C320p16rx_mask (C320p16rx_size - 1) +#define C320p16tx_mask (C320p16tx_size - 1) + +#define C320p24rx_size 0x2000 +#define C320p24tx_size 0x2000 +#define C320p24rx_mask (C320p24rx_size - 1) +#define C320p24tx_mask (C320p24tx_size - 1) + +#define C320p32rx_size 0x1000 +#define C320p32tx_size 0x1000 +#define C320p32rx_mask (C320p32rx_size - 1) +#define C320p32tx_mask (C320p32tx_size - 1) + +#define Page_size 0x2000U +#define Page_mask (Page_size - 1) +#define C218rx_spage 3 +#define C218tx_spage 4 +#define C218rx_pageno 1 +#define C218tx_pageno 4 +#define C218buf_pageno 5 + +#define C320p8rx_spage 3 +#define C320p8tx_spage 4 +#define C320p8rx_pgno 1 +#define C320p8tx_pgno 4 +#define C320p8buf_pgno 5 + +#define C320p16rx_spage 3 +#define C320p16tx_spage 4 +#define C320p16rx_pgno 1 +#define C320p16tx_pgno 2 +#define C320p16buf_pgno 3 + +#define C320p24rx_spage 3 +#define C320p24tx_spage 4 +#define C320p24rx_pgno 1 +#define C320p24tx_pgno 1 +#define C320p24buf_pgno 2 + +#define C320p32rx_spage 3 +#define C320p32tx_ofs C320p32rx_size +#define C320p32tx_spage 3 +#define C320p32buf_pgno 1 + +/* + * Host Status + */ +#define WakeupRx 0x01 +#define WakeupTx 0x02 +#define WakeupBreak 0x08 +#define WakeupLine 0x10 +#define WakeupIntr 0x20 +#define WakeupQuit 0x40 +#define WakeupEOF 0x80 /* used in VTIME control */ +#define WakeupRxTrigger 0x100 +#define WakeupTxTrigger 0x200 +/* + * Flag status + */ +#define Rx_over 0x01 +#define Xoff_state 0x02 +#define Tx_flowOff 0x04 +#define Tx_enable 0x08 +#define CTS_state 0x10 +#define DSR_state 0x20 +#define DCD_state 0x80 +/* + * FlowControl + */ +#define CTS_FlowCtl 1 +#define RTS_FlowCtl 2 +#define Tx_FlowCtl 4 +#define Rx_FlowCtl 8 +#define IXM_IXANY 0x10 + +#define LowWater 128 + +#define DTR_ON 1 +#define RTS_ON 2 +#define CTS_ON 1 +#define DSR_ON 2 +#define DCD_ON 8 + +/* mode definition */ +#define MX_CS8 0x03 +#define MX_CS7 0x02 +#define MX_CS6 0x01 +#define MX_CS5 0x00 + +#define MX_STOP1 0x00 +#define MX_STOP15 0x04 +#define MX_STOP2 0x08 + +#define MX_PARNONE 0x00 +#define MX_PAREVEN 0x40 +#define MX_PARODD 0xC0 + +#endif diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c new file mode 100644 index 000000000000..d188f378684d --- /dev/null +++ b/drivers/tty/mxser.c @@ -0,0 +1,2757 @@ +/* + * mxser.c -- MOXA Smartio/Industio family multiport serial driver. + * + * Copyright (C) 1999-2006 Moxa Technologies (support@moxa.com). + * Copyright (C) 2006-2008 Jiri Slaby + * + * This code is loosely based on the 1.8 moxa driver which is based on + * Linux serial driver, written by Linus Torvalds, Theodore T'so and + * others. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Fed through a cleanup, indent and remove of non 2.6 code by Alan Cox + * . The original 1.8 code is available on + * www.moxa.com. + * - Fixed x86_64 cleanness + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "mxser.h" + +#define MXSER_VERSION "2.0.5" /* 1.14 */ +#define MXSERMAJOR 174 + +#define MXSER_BOARDS 4 /* Max. boards */ +#define MXSER_PORTS_PER_BOARD 8 /* Max. ports per board */ +#define MXSER_PORTS (MXSER_BOARDS * MXSER_PORTS_PER_BOARD) +#define MXSER_ISR_PASS_LIMIT 100 + +/*CheckIsMoxaMust return value*/ +#define MOXA_OTHER_UART 0x00 +#define MOXA_MUST_MU150_HWID 0x01 +#define MOXA_MUST_MU860_HWID 0x02 + +#define WAKEUP_CHARS 256 + +#define UART_MCR_AFE 0x20 +#define UART_LSR_SPECIAL 0x1E + +#define PCI_DEVICE_ID_POS104UL 0x1044 +#define PCI_DEVICE_ID_CB108 0x1080 +#define PCI_DEVICE_ID_CP102UF 0x1023 +#define PCI_DEVICE_ID_CP112UL 0x1120 +#define PCI_DEVICE_ID_CB114 0x1142 +#define PCI_DEVICE_ID_CP114UL 0x1143 +#define PCI_DEVICE_ID_CB134I 0x1341 +#define PCI_DEVICE_ID_CP138U 0x1380 + + +#define C168_ASIC_ID 1 +#define C104_ASIC_ID 2 +#define C102_ASIC_ID 0xB +#define CI132_ASIC_ID 4 +#define CI134_ASIC_ID 3 +#define CI104J_ASIC_ID 5 + +#define MXSER_HIGHBAUD 1 +#define MXSER_HAS2 2 + +/* This is only for PCI */ +static const struct { + int type; + int tx_fifo; + int rx_fifo; + int xmit_fifo_size; + int rx_high_water; + int rx_trigger; + int rx_low_water; + long max_baud; +} Gpci_uart_info[] = { + {MOXA_OTHER_UART, 16, 16, 16, 14, 14, 1, 921600L}, + {MOXA_MUST_MU150_HWID, 64, 64, 64, 48, 48, 16, 230400L}, + {MOXA_MUST_MU860_HWID, 128, 128, 128, 96, 96, 32, 921600L} +}; +#define UART_INFO_NUM ARRAY_SIZE(Gpci_uart_info) + +struct mxser_cardinfo { + char *name; + unsigned int nports; + unsigned int flags; +}; + +static const struct mxser_cardinfo mxser_cards[] = { +/* 0*/ { "C168 series", 8, }, + { "C104 series", 4, }, + { "CI-104J series", 4, }, + { "C168H/PCI series", 8, }, + { "C104H/PCI series", 4, }, +/* 5*/ { "C102 series", 4, MXSER_HAS2 }, /* C102-ISA */ + { "CI-132 series", 4, MXSER_HAS2 }, + { "CI-134 series", 4, }, + { "CP-132 series", 2, }, + { "CP-114 series", 4, }, +/*10*/ { "CT-114 series", 4, }, + { "CP-102 series", 2, MXSER_HIGHBAUD }, + { "CP-104U series", 4, }, + { "CP-168U series", 8, }, + { "CP-132U series", 2, }, +/*15*/ { "CP-134U series", 4, }, + { "CP-104JU series", 4, }, + { "Moxa UC7000 Serial", 8, }, /* RC7000 */ + { "CP-118U series", 8, }, + { "CP-102UL series", 2, }, +/*20*/ { "CP-102U series", 2, }, + { "CP-118EL series", 8, }, + { "CP-168EL series", 8, }, + { "CP-104EL series", 4, }, + { "CB-108 series", 8, }, +/*25*/ { "CB-114 series", 4, }, + { "CB-134I series", 4, }, + { "CP-138U series", 8, }, + { "POS-104UL series", 4, }, + { "CP-114UL series", 4, }, +/*30*/ { "CP-102UF series", 2, }, + { "CP-112UL series", 2, }, +}; + +/* driver_data correspond to the lines in the structure above + see also ISA probe function before you change something */ +static struct pci_device_id mxser_pcibrds[] = { + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C168), .driver_data = 3 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C104), .driver_data = 4 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132), .driver_data = 8 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP114), .driver_data = 9 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CT114), .driver_data = 10 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102), .driver_data = 11 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104U), .driver_data = 12 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168U), .driver_data = 13 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132U), .driver_data = 14 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP134U), .driver_data = 15 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104JU),.driver_data = 16 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_RC7000), .driver_data = 17 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118U), .driver_data = 18 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102UL),.driver_data = 19 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102U), .driver_data = 20 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118EL),.driver_data = 21 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168EL),.driver_data = 22 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104EL),.driver_data = 23 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB108), .driver_data = 24 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB114), .driver_data = 25 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB134I), .driver_data = 26 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP138U), .driver_data = 27 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL), .driver_data = 28 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP114UL), .driver_data = 29 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP102UF), .driver_data = 30 }, + { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP112UL), .driver_data = 31 }, + { } +}; +MODULE_DEVICE_TABLE(pci, mxser_pcibrds); + +static unsigned long ioaddr[MXSER_BOARDS]; +static int ttymajor = MXSERMAJOR; + +/* Variables for insmod */ + +MODULE_AUTHOR("Casper Yang"); +MODULE_DESCRIPTION("MOXA Smartio/Industio Family Multiport Board Device Driver"); +module_param_array(ioaddr, ulong, NULL, 0); +MODULE_PARM_DESC(ioaddr, "ISA io addresses to look for a moxa board"); +module_param(ttymajor, int, 0); +MODULE_LICENSE("GPL"); + +struct mxser_log { + int tick; + unsigned long rxcnt[MXSER_PORTS]; + unsigned long txcnt[MXSER_PORTS]; +}; + +struct mxser_mon { + unsigned long rxcnt; + unsigned long txcnt; + unsigned long up_rxcnt; + unsigned long up_txcnt; + int modem_status; + unsigned char hold_reason; +}; + +struct mxser_mon_ext { + unsigned long rx_cnt[32]; + unsigned long tx_cnt[32]; + unsigned long up_rxcnt[32]; + unsigned long up_txcnt[32]; + int modem_status[32]; + + long baudrate[32]; + int databits[32]; + int stopbits[32]; + int parity[32]; + int flowctrl[32]; + int fifo[32]; + int iftype[32]; +}; + +struct mxser_board; + +struct mxser_port { + struct tty_port port; + struct mxser_board *board; + + unsigned long ioaddr; + unsigned long opmode_ioaddr; + int max_baud; + + int rx_high_water; + int rx_trigger; /* Rx fifo trigger level */ + int rx_low_water; + int baud_base; /* max. speed */ + int type; /* UART type */ + + int x_char; /* xon/xoff character */ + int IER; /* Interrupt Enable Register */ + int MCR; /* Modem control register */ + + unsigned char stop_rx; + unsigned char ldisc_stop_rx; + + int custom_divisor; + unsigned char err_shadow; + + struct async_icount icount; /* kernel counters for 4 input interrupts */ + int timeout; + + int read_status_mask; + int ignore_status_mask; + int xmit_fifo_size; + int xmit_head; + int xmit_tail; + int xmit_cnt; + + struct ktermios normal_termios; + + struct mxser_mon mon_data; + + spinlock_t slock; +}; + +struct mxser_board { + unsigned int idx; + int irq; + const struct mxser_cardinfo *info; + unsigned long vector; + unsigned long vector_mask; + + int chip_flag; + int uart_type; + + struct mxser_port ports[MXSER_PORTS_PER_BOARD]; +}; + +struct mxser_mstatus { + tcflag_t cflag; + int cts; + int dsr; + int ri; + int dcd; +}; + +static struct mxser_board mxser_boards[MXSER_BOARDS]; +static struct tty_driver *mxvar_sdriver; +static struct mxser_log mxvar_log; +static int mxser_set_baud_method[MXSER_PORTS + 1]; + +static void mxser_enable_must_enchance_mode(unsigned long baseio) +{ + u8 oldlcr; + u8 efr; + + oldlcr = inb(baseio + UART_LCR); + outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); + + efr = inb(baseio + MOXA_MUST_EFR_REGISTER); + efr |= MOXA_MUST_EFR_EFRB_ENABLE; + + outb(efr, baseio + MOXA_MUST_EFR_REGISTER); + outb(oldlcr, baseio + UART_LCR); +} + +#ifdef CONFIG_PCI +static void mxser_disable_must_enchance_mode(unsigned long baseio) +{ + u8 oldlcr; + u8 efr; + + oldlcr = inb(baseio + UART_LCR); + outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); + + efr = inb(baseio + MOXA_MUST_EFR_REGISTER); + efr &= ~MOXA_MUST_EFR_EFRB_ENABLE; + + outb(efr, baseio + MOXA_MUST_EFR_REGISTER); + outb(oldlcr, baseio + UART_LCR); +} +#endif + +static void mxser_set_must_xon1_value(unsigned long baseio, u8 value) +{ + u8 oldlcr; + u8 efr; + + oldlcr = inb(baseio + UART_LCR); + outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); + + efr = inb(baseio + MOXA_MUST_EFR_REGISTER); + efr &= ~MOXA_MUST_EFR_BANK_MASK; + efr |= MOXA_MUST_EFR_BANK0; + + outb(efr, baseio + MOXA_MUST_EFR_REGISTER); + outb(value, baseio + MOXA_MUST_XON1_REGISTER); + outb(oldlcr, baseio + UART_LCR); +} + +static void mxser_set_must_xoff1_value(unsigned long baseio, u8 value) +{ + u8 oldlcr; + u8 efr; + + oldlcr = inb(baseio + UART_LCR); + outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); + + efr = inb(baseio + MOXA_MUST_EFR_REGISTER); + efr &= ~MOXA_MUST_EFR_BANK_MASK; + efr |= MOXA_MUST_EFR_BANK0; + + outb(efr, baseio + MOXA_MUST_EFR_REGISTER); + outb(value, baseio + MOXA_MUST_XOFF1_REGISTER); + outb(oldlcr, baseio + UART_LCR); +} + +static void mxser_set_must_fifo_value(struct mxser_port *info) +{ + u8 oldlcr; + u8 efr; + + oldlcr = inb(info->ioaddr + UART_LCR); + outb(MOXA_MUST_ENTER_ENCHANCE, info->ioaddr + UART_LCR); + + efr = inb(info->ioaddr + MOXA_MUST_EFR_REGISTER); + efr &= ~MOXA_MUST_EFR_BANK_MASK; + efr |= MOXA_MUST_EFR_BANK1; + + outb(efr, info->ioaddr + MOXA_MUST_EFR_REGISTER); + outb((u8)info->rx_high_water, info->ioaddr + MOXA_MUST_RBRTH_REGISTER); + outb((u8)info->rx_trigger, info->ioaddr + MOXA_MUST_RBRTI_REGISTER); + outb((u8)info->rx_low_water, info->ioaddr + MOXA_MUST_RBRTL_REGISTER); + outb(oldlcr, info->ioaddr + UART_LCR); +} + +static void mxser_set_must_enum_value(unsigned long baseio, u8 value) +{ + u8 oldlcr; + u8 efr; + + oldlcr = inb(baseio + UART_LCR); + outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); + + efr = inb(baseio + MOXA_MUST_EFR_REGISTER); + efr &= ~MOXA_MUST_EFR_BANK_MASK; + efr |= MOXA_MUST_EFR_BANK2; + + outb(efr, baseio + MOXA_MUST_EFR_REGISTER); + outb(value, baseio + MOXA_MUST_ENUM_REGISTER); + outb(oldlcr, baseio + UART_LCR); +} + +#ifdef CONFIG_PCI +static void mxser_get_must_hardware_id(unsigned long baseio, u8 *pId) +{ + u8 oldlcr; + u8 efr; + + oldlcr = inb(baseio + UART_LCR); + outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); + + efr = inb(baseio + MOXA_MUST_EFR_REGISTER); + efr &= ~MOXA_MUST_EFR_BANK_MASK; + efr |= MOXA_MUST_EFR_BANK2; + + outb(efr, baseio + MOXA_MUST_EFR_REGISTER); + *pId = inb(baseio + MOXA_MUST_HWID_REGISTER); + outb(oldlcr, baseio + UART_LCR); +} +#endif + +static void SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(unsigned long baseio) +{ + u8 oldlcr; + u8 efr; + + oldlcr = inb(baseio + UART_LCR); + outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); + + efr = inb(baseio + MOXA_MUST_EFR_REGISTER); + efr &= ~MOXA_MUST_EFR_SF_MASK; + + outb(efr, baseio + MOXA_MUST_EFR_REGISTER); + outb(oldlcr, baseio + UART_LCR); +} + +static void mxser_enable_must_tx_software_flow_control(unsigned long baseio) +{ + u8 oldlcr; + u8 efr; + + oldlcr = inb(baseio + UART_LCR); + outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); + + efr = inb(baseio + MOXA_MUST_EFR_REGISTER); + efr &= ~MOXA_MUST_EFR_SF_TX_MASK; + efr |= MOXA_MUST_EFR_SF_TX1; + + outb(efr, baseio + MOXA_MUST_EFR_REGISTER); + outb(oldlcr, baseio + UART_LCR); +} + +static void mxser_disable_must_tx_software_flow_control(unsigned long baseio) +{ + u8 oldlcr; + u8 efr; + + oldlcr = inb(baseio + UART_LCR); + outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); + + efr = inb(baseio + MOXA_MUST_EFR_REGISTER); + efr &= ~MOXA_MUST_EFR_SF_TX_MASK; + + outb(efr, baseio + MOXA_MUST_EFR_REGISTER); + outb(oldlcr, baseio + UART_LCR); +} + +static void mxser_enable_must_rx_software_flow_control(unsigned long baseio) +{ + u8 oldlcr; + u8 efr; + + oldlcr = inb(baseio + UART_LCR); + outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); + + efr = inb(baseio + MOXA_MUST_EFR_REGISTER); + efr &= ~MOXA_MUST_EFR_SF_RX_MASK; + efr |= MOXA_MUST_EFR_SF_RX1; + + outb(efr, baseio + MOXA_MUST_EFR_REGISTER); + outb(oldlcr, baseio + UART_LCR); +} + +static void mxser_disable_must_rx_software_flow_control(unsigned long baseio) +{ + u8 oldlcr; + u8 efr; + + oldlcr = inb(baseio + UART_LCR); + outb(MOXA_MUST_ENTER_ENCHANCE, baseio + UART_LCR); + + efr = inb(baseio + MOXA_MUST_EFR_REGISTER); + efr &= ~MOXA_MUST_EFR_SF_RX_MASK; + + outb(efr, baseio + MOXA_MUST_EFR_REGISTER); + outb(oldlcr, baseio + UART_LCR); +} + +#ifdef CONFIG_PCI +static int __devinit CheckIsMoxaMust(unsigned long io) +{ + u8 oldmcr, hwid; + int i; + + outb(0, io + UART_LCR); + mxser_disable_must_enchance_mode(io); + oldmcr = inb(io + UART_MCR); + outb(0, io + UART_MCR); + mxser_set_must_xon1_value(io, 0x11); + if ((hwid = inb(io + UART_MCR)) != 0) { + outb(oldmcr, io + UART_MCR); + return MOXA_OTHER_UART; + } + + mxser_get_must_hardware_id(io, &hwid); + for (i = 1; i < UART_INFO_NUM; i++) { /* 0 = OTHER_UART */ + if (hwid == Gpci_uart_info[i].type) + return (int)hwid; + } + return MOXA_OTHER_UART; +} +#endif + +static void process_txrx_fifo(struct mxser_port *info) +{ + int i; + + if ((info->type == PORT_16450) || (info->type == PORT_8250)) { + info->rx_trigger = 1; + info->rx_high_water = 1; + info->rx_low_water = 1; + info->xmit_fifo_size = 1; + } else + for (i = 0; i < UART_INFO_NUM; i++) + if (info->board->chip_flag == Gpci_uart_info[i].type) { + info->rx_trigger = Gpci_uart_info[i].rx_trigger; + info->rx_low_water = Gpci_uart_info[i].rx_low_water; + info->rx_high_water = Gpci_uart_info[i].rx_high_water; + info->xmit_fifo_size = Gpci_uart_info[i].xmit_fifo_size; + break; + } +} + +static unsigned char mxser_get_msr(int baseaddr, int mode, int port) +{ + static unsigned char mxser_msr[MXSER_PORTS + 1]; + unsigned char status = 0; + + status = inb(baseaddr + UART_MSR); + + mxser_msr[port] &= 0x0F; + mxser_msr[port] |= status; + status = mxser_msr[port]; + if (mode) + mxser_msr[port] = 0; + + return status; +} + +static int mxser_carrier_raised(struct tty_port *port) +{ + struct mxser_port *mp = container_of(port, struct mxser_port, port); + return (inb(mp->ioaddr + UART_MSR) & UART_MSR_DCD)?1:0; +} + +static void mxser_dtr_rts(struct tty_port *port, int on) +{ + struct mxser_port *mp = container_of(port, struct mxser_port, port); + unsigned long flags; + + spin_lock_irqsave(&mp->slock, flags); + if (on) + outb(inb(mp->ioaddr + UART_MCR) | + UART_MCR_DTR | UART_MCR_RTS, mp->ioaddr + UART_MCR); + else + outb(inb(mp->ioaddr + UART_MCR)&~(UART_MCR_DTR | UART_MCR_RTS), + mp->ioaddr + UART_MCR); + spin_unlock_irqrestore(&mp->slock, flags); +} + +static int mxser_set_baud(struct tty_struct *tty, long newspd) +{ + struct mxser_port *info = tty->driver_data; + int quot = 0, baud; + unsigned char cval; + + if (!info->ioaddr) + return -1; + + if (newspd > info->max_baud) + return -1; + + if (newspd == 134) { + quot = 2 * info->baud_base / 269; + tty_encode_baud_rate(tty, 134, 134); + } else if (newspd) { + quot = info->baud_base / newspd; + if (quot == 0) + quot = 1; + baud = info->baud_base/quot; + tty_encode_baud_rate(tty, baud, baud); + } else { + quot = 0; + } + + info->timeout = ((info->xmit_fifo_size * HZ * 10 * quot) / info->baud_base); + info->timeout += HZ / 50; /* Add .02 seconds of slop */ + + if (quot) { + info->MCR |= UART_MCR_DTR; + outb(info->MCR, info->ioaddr + UART_MCR); + } else { + info->MCR &= ~UART_MCR_DTR; + outb(info->MCR, info->ioaddr + UART_MCR); + return 0; + } + + cval = inb(info->ioaddr + UART_LCR); + + outb(cval | UART_LCR_DLAB, info->ioaddr + UART_LCR); /* set DLAB */ + + outb(quot & 0xff, info->ioaddr + UART_DLL); /* LS of divisor */ + outb(quot >> 8, info->ioaddr + UART_DLM); /* MS of divisor */ + outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */ + +#ifdef BOTHER + if (C_BAUD(tty) == BOTHER) { + quot = info->baud_base % newspd; + quot *= 8; + if (quot % newspd > newspd / 2) { + quot /= newspd; + quot++; + } else + quot /= newspd; + + mxser_set_must_enum_value(info->ioaddr, quot); + } else +#endif + mxser_set_must_enum_value(info->ioaddr, 0); + + return 0; +} + +/* + * This routine is called to set the UART divisor registers to match + * the specified baud rate for a serial port. + */ +static int mxser_change_speed(struct tty_struct *tty, + struct ktermios *old_termios) +{ + struct mxser_port *info = tty->driver_data; + unsigned cflag, cval, fcr; + int ret = 0; + unsigned char status; + + cflag = tty->termios->c_cflag; + if (!info->ioaddr) + return ret; + + if (mxser_set_baud_method[tty->index] == 0) + mxser_set_baud(tty, tty_get_baud_rate(tty)); + + /* byte size and parity */ + switch (cflag & CSIZE) { + case CS5: + cval = 0x00; + break; + case CS6: + cval = 0x01; + break; + case CS7: + cval = 0x02; + break; + case CS8: + cval = 0x03; + break; + default: + cval = 0x00; + break; /* too keep GCC shut... */ + } + if (cflag & CSTOPB) + cval |= 0x04; + if (cflag & PARENB) + cval |= UART_LCR_PARITY; + if (!(cflag & PARODD)) + cval |= UART_LCR_EPAR; + if (cflag & CMSPAR) + cval |= UART_LCR_SPAR; + + if ((info->type == PORT_8250) || (info->type == PORT_16450)) { + if (info->board->chip_flag) { + fcr = UART_FCR_ENABLE_FIFO; + fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE; + mxser_set_must_fifo_value(info); + } else + fcr = 0; + } else { + fcr = UART_FCR_ENABLE_FIFO; + if (info->board->chip_flag) { + fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE; + mxser_set_must_fifo_value(info); + } else { + switch (info->rx_trigger) { + case 1: + fcr |= UART_FCR_TRIGGER_1; + break; + case 4: + fcr |= UART_FCR_TRIGGER_4; + break; + case 8: + fcr |= UART_FCR_TRIGGER_8; + break; + default: + fcr |= UART_FCR_TRIGGER_14; + break; + } + } + } + + /* CTS flow control flag and modem status interrupts */ + info->IER &= ~UART_IER_MSI; + info->MCR &= ~UART_MCR_AFE; + if (cflag & CRTSCTS) { + info->port.flags |= ASYNC_CTS_FLOW; + info->IER |= UART_IER_MSI; + if ((info->type == PORT_16550A) || (info->board->chip_flag)) { + info->MCR |= UART_MCR_AFE; + } else { + status = inb(info->ioaddr + UART_MSR); + if (tty->hw_stopped) { + if (status & UART_MSR_CTS) { + tty->hw_stopped = 0; + if (info->type != PORT_16550A && + !info->board->chip_flag) { + outb(info->IER & ~UART_IER_THRI, + info->ioaddr + + UART_IER); + info->IER |= UART_IER_THRI; + outb(info->IER, info->ioaddr + + UART_IER); + } + tty_wakeup(tty); + } + } else { + if (!(status & UART_MSR_CTS)) { + tty->hw_stopped = 1; + if ((info->type != PORT_16550A) && + (!info->board->chip_flag)) { + info->IER &= ~UART_IER_THRI; + outb(info->IER, info->ioaddr + + UART_IER); + } + } + } + } + } else { + info->port.flags &= ~ASYNC_CTS_FLOW; + } + outb(info->MCR, info->ioaddr + UART_MCR); + if (cflag & CLOCAL) { + info->port.flags &= ~ASYNC_CHECK_CD; + } else { + info->port.flags |= ASYNC_CHECK_CD; + info->IER |= UART_IER_MSI; + } + outb(info->IER, info->ioaddr + UART_IER); + + /* + * Set up parity check flag + */ + info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; + if (I_INPCK(tty)) + info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; + if (I_BRKINT(tty) || I_PARMRK(tty)) + info->read_status_mask |= UART_LSR_BI; + + info->ignore_status_mask = 0; + + if (I_IGNBRK(tty)) { + info->ignore_status_mask |= UART_LSR_BI; + info->read_status_mask |= UART_LSR_BI; + /* + * If we're ignore parity and break indicators, ignore + * overruns too. (For real raw support). + */ + if (I_IGNPAR(tty)) { + info->ignore_status_mask |= + UART_LSR_OE | + UART_LSR_PE | + UART_LSR_FE; + info->read_status_mask |= + UART_LSR_OE | + UART_LSR_PE | + UART_LSR_FE; + } + } + if (info->board->chip_flag) { + mxser_set_must_xon1_value(info->ioaddr, START_CHAR(tty)); + mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(tty)); + if (I_IXON(tty)) { + mxser_enable_must_rx_software_flow_control( + info->ioaddr); + } else { + mxser_disable_must_rx_software_flow_control( + info->ioaddr); + } + if (I_IXOFF(tty)) { + mxser_enable_must_tx_software_flow_control( + info->ioaddr); + } else { + mxser_disable_must_tx_software_flow_control( + info->ioaddr); + } + } + + + outb(fcr, info->ioaddr + UART_FCR); /* set fcr */ + outb(cval, info->ioaddr + UART_LCR); + + return ret; +} + +static void mxser_check_modem_status(struct tty_struct *tty, + struct mxser_port *port, int status) +{ + /* update input line counters */ + if (status & UART_MSR_TERI) + port->icount.rng++; + if (status & UART_MSR_DDSR) + port->icount.dsr++; + if (status & UART_MSR_DDCD) + port->icount.dcd++; + if (status & UART_MSR_DCTS) + port->icount.cts++; + port->mon_data.modem_status = status; + wake_up_interruptible(&port->port.delta_msr_wait); + + if ((port->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { + if (status & UART_MSR_DCD) + wake_up_interruptible(&port->port.open_wait); + } + + if (port->port.flags & ASYNC_CTS_FLOW) { + if (tty->hw_stopped) { + if (status & UART_MSR_CTS) { + tty->hw_stopped = 0; + + if ((port->type != PORT_16550A) && + (!port->board->chip_flag)) { + outb(port->IER & ~UART_IER_THRI, + port->ioaddr + UART_IER); + port->IER |= UART_IER_THRI; + outb(port->IER, port->ioaddr + + UART_IER); + } + tty_wakeup(tty); + } + } else { + if (!(status & UART_MSR_CTS)) { + tty->hw_stopped = 1; + if (port->type != PORT_16550A && + !port->board->chip_flag) { + port->IER &= ~UART_IER_THRI; + outb(port->IER, port->ioaddr + + UART_IER); + } + } + } + } +} + +static int mxser_activate(struct tty_port *port, struct tty_struct *tty) +{ + struct mxser_port *info = container_of(port, struct mxser_port, port); + unsigned long page; + unsigned long flags; + + page = __get_free_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + + spin_lock_irqsave(&info->slock, flags); + + if (!info->ioaddr || !info->type) { + set_bit(TTY_IO_ERROR, &tty->flags); + free_page(page); + spin_unlock_irqrestore(&info->slock, flags); + return 0; + } + info->port.xmit_buf = (unsigned char *) page; + + /* + * Clear the FIFO buffers and disable them + * (they will be reenabled in mxser_change_speed()) + */ + if (info->board->chip_flag) + outb((UART_FCR_CLEAR_RCVR | + UART_FCR_CLEAR_XMIT | + MOXA_MUST_FCR_GDA_MODE_ENABLE), info->ioaddr + UART_FCR); + else + outb((UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), + info->ioaddr + UART_FCR); + + /* + * At this point there's no way the LSR could still be 0xFF; + * if it is, then bail out, because there's likely no UART + * here. + */ + if (inb(info->ioaddr + UART_LSR) == 0xff) { + spin_unlock_irqrestore(&info->slock, flags); + if (capable(CAP_SYS_ADMIN)) { + set_bit(TTY_IO_ERROR, &tty->flags); + return 0; + } else + return -ENODEV; + } + + /* + * Clear the interrupt registers. + */ + (void) inb(info->ioaddr + UART_LSR); + (void) inb(info->ioaddr + UART_RX); + (void) inb(info->ioaddr + UART_IIR); + (void) inb(info->ioaddr + UART_MSR); + + /* + * Now, initialize the UART + */ + outb(UART_LCR_WLEN8, info->ioaddr + UART_LCR); /* reset DLAB */ + info->MCR = UART_MCR_DTR | UART_MCR_RTS; + outb(info->MCR, info->ioaddr + UART_MCR); + + /* + * Finally, enable interrupts + */ + info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI; + + if (info->board->chip_flag) + info->IER |= MOXA_MUST_IER_EGDAI; + outb(info->IER, info->ioaddr + UART_IER); /* enable interrupts */ + + /* + * And clear the interrupt registers again for luck. + */ + (void) inb(info->ioaddr + UART_LSR); + (void) inb(info->ioaddr + UART_RX); + (void) inb(info->ioaddr + UART_IIR); + (void) inb(info->ioaddr + UART_MSR); + + clear_bit(TTY_IO_ERROR, &tty->flags); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + + /* + * and set the speed of the serial port + */ + mxser_change_speed(tty, NULL); + spin_unlock_irqrestore(&info->slock, flags); + + return 0; +} + +/* + * This routine will shutdown a serial port + */ +static void mxser_shutdown_port(struct tty_port *port) +{ + struct mxser_port *info = container_of(port, struct mxser_port, port); + unsigned long flags; + + spin_lock_irqsave(&info->slock, flags); + + /* + * clear delta_msr_wait queue to avoid mem leaks: we may free the irq + * here so the queue might never be waken up + */ + wake_up_interruptible(&info->port.delta_msr_wait); + + /* + * Free the xmit buffer, if necessary + */ + if (info->port.xmit_buf) { + free_page((unsigned long) info->port.xmit_buf); + info->port.xmit_buf = NULL; + } + + info->IER = 0; + outb(0x00, info->ioaddr + UART_IER); + + /* clear Rx/Tx FIFO's */ + if (info->board->chip_flag) + outb(UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT | + MOXA_MUST_FCR_GDA_MODE_ENABLE, + info->ioaddr + UART_FCR); + else + outb(UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, + info->ioaddr + UART_FCR); + + /* read data port to reset things */ + (void) inb(info->ioaddr + UART_RX); + + + if (info->board->chip_flag) + SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->ioaddr); + + spin_unlock_irqrestore(&info->slock, flags); +} + +/* + * This routine is called whenever a serial port is opened. It + * enables interrupts for a serial port, linking in its async structure into + * the IRQ chain. It also performs the serial-specific + * initialization for the tty structure. + */ +static int mxser_open(struct tty_struct *tty, struct file *filp) +{ + struct mxser_port *info; + int line; + + line = tty->index; + if (line == MXSER_PORTS) + return 0; + if (line < 0 || line > MXSER_PORTS) + return -ENODEV; + info = &mxser_boards[line / MXSER_PORTS_PER_BOARD].ports[line % MXSER_PORTS_PER_BOARD]; + if (!info->ioaddr) + return -ENODEV; + + tty->driver_data = info; + return tty_port_open(&info->port, tty, filp); +} + +static void mxser_flush_buffer(struct tty_struct *tty) +{ + struct mxser_port *info = tty->driver_data; + char fcr; + unsigned long flags; + + + spin_lock_irqsave(&info->slock, flags); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + + fcr = inb(info->ioaddr + UART_FCR); + outb((fcr | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), + info->ioaddr + UART_FCR); + outb(fcr, info->ioaddr + UART_FCR); + + spin_unlock_irqrestore(&info->slock, flags); + + tty_wakeup(tty); +} + + +static void mxser_close_port(struct tty_port *port) +{ + struct mxser_port *info = container_of(port, struct mxser_port, port); + unsigned long timeout; + /* + * At this point we stop accepting input. To do this, we + * disable the receive line status interrupts, and tell the + * interrupt driver to stop checking the data ready bit in the + * line status register. + */ + info->IER &= ~UART_IER_RLSI; + if (info->board->chip_flag) + info->IER &= ~MOXA_MUST_RECV_ISR; + + outb(info->IER, info->ioaddr + UART_IER); + /* + * Before we drop DTR, make sure the UART transmitter + * has completely drained; this is especially + * important if there is a transmit FIFO! + */ + timeout = jiffies + HZ; + while (!(inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT)) { + schedule_timeout_interruptible(5); + if (time_after(jiffies, timeout)) + break; + } +} + +/* + * This routine is called when the serial port gets closed. First, we + * wait for the last remaining data to be sent. Then, we unlink its + * async structure from the interrupt chain if necessary, and we free + * that IRQ if nothing is left in the chain. + */ +static void mxser_close(struct tty_struct *tty, struct file *filp) +{ + struct mxser_port *info = tty->driver_data; + struct tty_port *port = &info->port; + + if (tty->index == MXSER_PORTS || info == NULL) + return; + if (tty_port_close_start(port, tty, filp) == 0) + return; + mutex_lock(&port->mutex); + mxser_close_port(port); + mxser_flush_buffer(tty); + mxser_shutdown_port(port); + clear_bit(ASYNCB_INITIALIZED, &port->flags); + mutex_unlock(&port->mutex); + /* Right now the tty_port set is done outside of the close_end helper + as we don't yet have everyone using refcounts */ + tty_port_close_end(port, tty); + tty_port_tty_set(port, NULL); +} + +static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count) +{ + int c, total = 0; + struct mxser_port *info = tty->driver_data; + unsigned long flags; + + if (!info->port.xmit_buf) + return 0; + + while (1) { + c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + if (c <= 0) + break; + + memcpy(info->port.xmit_buf + info->xmit_head, buf, c); + spin_lock_irqsave(&info->slock, flags); + info->xmit_head = (info->xmit_head + c) & + (SERIAL_XMIT_SIZE - 1); + info->xmit_cnt += c; + spin_unlock_irqrestore(&info->slock, flags); + + buf += c; + count -= c; + total += c; + } + + if (info->xmit_cnt && !tty->stopped) { + if (!tty->hw_stopped || + (info->type == PORT_16550A) || + (info->board->chip_flag)) { + spin_lock_irqsave(&info->slock, flags); + outb(info->IER & ~UART_IER_THRI, info->ioaddr + + UART_IER); + info->IER |= UART_IER_THRI; + outb(info->IER, info->ioaddr + UART_IER); + spin_unlock_irqrestore(&info->slock, flags); + } + } + return total; +} + +static int mxser_put_char(struct tty_struct *tty, unsigned char ch) +{ + struct mxser_port *info = tty->driver_data; + unsigned long flags; + + if (!info->port.xmit_buf) + return 0; + + if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) + return 0; + + spin_lock_irqsave(&info->slock, flags); + info->port.xmit_buf[info->xmit_head++] = ch; + info->xmit_head &= SERIAL_XMIT_SIZE - 1; + info->xmit_cnt++; + spin_unlock_irqrestore(&info->slock, flags); + if (!tty->stopped) { + if (!tty->hw_stopped || + (info->type == PORT_16550A) || + info->board->chip_flag) { + spin_lock_irqsave(&info->slock, flags); + outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER); + info->IER |= UART_IER_THRI; + outb(info->IER, info->ioaddr + UART_IER); + spin_unlock_irqrestore(&info->slock, flags); + } + } + return 1; +} + + +static void mxser_flush_chars(struct tty_struct *tty) +{ + struct mxser_port *info = tty->driver_data; + unsigned long flags; + + if (info->xmit_cnt <= 0 || tty->stopped || !info->port.xmit_buf || + (tty->hw_stopped && info->type != PORT_16550A && + !info->board->chip_flag)) + return; + + spin_lock_irqsave(&info->slock, flags); + + outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER); + info->IER |= UART_IER_THRI; + outb(info->IER, info->ioaddr + UART_IER); + + spin_unlock_irqrestore(&info->slock, flags); +} + +static int mxser_write_room(struct tty_struct *tty) +{ + struct mxser_port *info = tty->driver_data; + int ret; + + ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; + return ret < 0 ? 0 : ret; +} + +static int mxser_chars_in_buffer(struct tty_struct *tty) +{ + struct mxser_port *info = tty->driver_data; + return info->xmit_cnt; +} + +/* + * ------------------------------------------------------------ + * friends of mxser_ioctl() + * ------------------------------------------------------------ + */ +static int mxser_get_serial_info(struct tty_struct *tty, + struct serial_struct __user *retinfo) +{ + struct mxser_port *info = tty->driver_data; + struct serial_struct tmp = { + .type = info->type, + .line = tty->index, + .port = info->ioaddr, + .irq = info->board->irq, + .flags = info->port.flags, + .baud_base = info->baud_base, + .close_delay = info->port.close_delay, + .closing_wait = info->port.closing_wait, + .custom_divisor = info->custom_divisor, + .hub6 = 0 + }; + if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) + return -EFAULT; + return 0; +} + +static int mxser_set_serial_info(struct tty_struct *tty, + struct serial_struct __user *new_info) +{ + struct mxser_port *info = tty->driver_data; + struct tty_port *port = &info->port; + struct serial_struct new_serial; + speed_t baud; + unsigned long sl_flags; + unsigned int flags; + int retval = 0; + + if (!new_info || !info->ioaddr) + return -ENODEV; + if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) + return -EFAULT; + + if (new_serial.irq != info->board->irq || + new_serial.port != info->ioaddr) + return -EINVAL; + + flags = port->flags & ASYNC_SPD_MASK; + + if (!capable(CAP_SYS_ADMIN)) { + if ((new_serial.baud_base != info->baud_base) || + (new_serial.close_delay != info->port.close_delay) || + ((new_serial.flags & ~ASYNC_USR_MASK) != (info->port.flags & ~ASYNC_USR_MASK))) + return -EPERM; + info->port.flags = ((info->port.flags & ~ASYNC_USR_MASK) | + (new_serial.flags & ASYNC_USR_MASK)); + } else { + /* + * OK, past this point, all the error checking has been done. + * At this point, we start making changes..... + */ + port->flags = ((port->flags & ~ASYNC_FLAGS) | + (new_serial.flags & ASYNC_FLAGS)); + port->close_delay = new_serial.close_delay * HZ / 100; + port->closing_wait = new_serial.closing_wait * HZ / 100; + tty->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; + if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && + (new_serial.baud_base != info->baud_base || + new_serial.custom_divisor != + info->custom_divisor)) { + if (new_serial.custom_divisor == 0) + return -EINVAL; + baud = new_serial.baud_base / new_serial.custom_divisor; + tty_encode_baud_rate(tty, baud, baud); + } + } + + info->type = new_serial.type; + + process_txrx_fifo(info); + + if (test_bit(ASYNCB_INITIALIZED, &port->flags)) { + if (flags != (port->flags & ASYNC_SPD_MASK)) { + spin_lock_irqsave(&info->slock, sl_flags); + mxser_change_speed(tty, NULL); + spin_unlock_irqrestore(&info->slock, sl_flags); + } + } else { + retval = mxser_activate(port, tty); + if (retval == 0) + set_bit(ASYNCB_INITIALIZED, &port->flags); + } + return retval; +} + +/* + * mxser_get_lsr_info - get line status register info + * + * Purpose: Let user call ioctl() to get info when the UART physically + * is emptied. On bus types like RS485, the transmitter must + * release the bus after transmitting. This must be done when + * the transmit shift register is empty, not be done when the + * transmit holding register is empty. This functionality + * allows an RS485 driver to be written in user space. + */ +static int mxser_get_lsr_info(struct mxser_port *info, + unsigned int __user *value) +{ + unsigned char status; + unsigned int result; + unsigned long flags; + + spin_lock_irqsave(&info->slock, flags); + status = inb(info->ioaddr + UART_LSR); + spin_unlock_irqrestore(&info->slock, flags); + result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); + return put_user(result, value); +} + +static int mxser_tiocmget(struct tty_struct *tty) +{ + struct mxser_port *info = tty->driver_data; + unsigned char control, status; + unsigned long flags; + + + if (tty->index == MXSER_PORTS) + return -ENOIOCTLCMD; + if (test_bit(TTY_IO_ERROR, &tty->flags)) + return -EIO; + + control = info->MCR; + + spin_lock_irqsave(&info->slock, flags); + status = inb(info->ioaddr + UART_MSR); + if (status & UART_MSR_ANY_DELTA) + mxser_check_modem_status(tty, info, status); + spin_unlock_irqrestore(&info->slock, flags); + return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | + ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | + ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) | + ((status & UART_MSR_RI) ? TIOCM_RNG : 0) | + ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) | + ((status & UART_MSR_CTS) ? TIOCM_CTS : 0); +} + +static int mxser_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + struct mxser_port *info = tty->driver_data; + unsigned long flags; + + + if (tty->index == MXSER_PORTS) + return -ENOIOCTLCMD; + if (test_bit(TTY_IO_ERROR, &tty->flags)) + return -EIO; + + spin_lock_irqsave(&info->slock, flags); + + if (set & TIOCM_RTS) + info->MCR |= UART_MCR_RTS; + if (set & TIOCM_DTR) + info->MCR |= UART_MCR_DTR; + + if (clear & TIOCM_RTS) + info->MCR &= ~UART_MCR_RTS; + if (clear & TIOCM_DTR) + info->MCR &= ~UART_MCR_DTR; + + outb(info->MCR, info->ioaddr + UART_MCR); + spin_unlock_irqrestore(&info->slock, flags); + return 0; +} + +static int __init mxser_program_mode(int port) +{ + int id, i, j, n; + + outb(0, port); + outb(0, port); + outb(0, port); + (void)inb(port); + (void)inb(port); + outb(0, port); + (void)inb(port); + + id = inb(port + 1) & 0x1F; + if ((id != C168_ASIC_ID) && + (id != C104_ASIC_ID) && + (id != C102_ASIC_ID) && + (id != CI132_ASIC_ID) && + (id != CI134_ASIC_ID) && + (id != CI104J_ASIC_ID)) + return -1; + for (i = 0, j = 0; i < 4; i++) { + n = inb(port + 2); + if (n == 'M') { + j = 1; + } else if ((j == 1) && (n == 1)) { + j = 2; + break; + } else + j = 0; + } + if (j != 2) + id = -2; + return id; +} + +static void __init mxser_normal_mode(int port) +{ + int i, n; + + outb(0xA5, port + 1); + outb(0x80, port + 3); + outb(12, port + 0); /* 9600 bps */ + outb(0, port + 1); + outb(0x03, port + 3); /* 8 data bits */ + outb(0x13, port + 4); /* loop back mode */ + for (i = 0; i < 16; i++) { + n = inb(port + 5); + if ((n & 0x61) == 0x60) + break; + if ((n & 1) == 1) + (void)inb(port); + } + outb(0x00, port + 4); +} + +#define CHIP_SK 0x01 /* Serial Data Clock in Eprom */ +#define CHIP_DO 0x02 /* Serial Data Output in Eprom */ +#define CHIP_CS 0x04 /* Serial Chip Select in Eprom */ +#define CHIP_DI 0x08 /* Serial Data Input in Eprom */ +#define EN_CCMD 0x000 /* Chip's command register */ +#define EN0_RSARLO 0x008 /* Remote start address reg 0 */ +#define EN0_RSARHI 0x009 /* Remote start address reg 1 */ +#define EN0_RCNTLO 0x00A /* Remote byte count reg WR */ +#define EN0_RCNTHI 0x00B /* Remote byte count reg WR */ +#define EN0_DCFG 0x00E /* Data configuration reg WR */ +#define EN0_PORT 0x010 /* Rcv missed frame error counter RD */ +#define ENC_PAGE0 0x000 /* Select page 0 of chip registers */ +#define ENC_PAGE3 0x0C0 /* Select page 3 of chip registers */ +static int __init mxser_read_register(int port, unsigned short *regs) +{ + int i, k, value, id; + unsigned int j; + + id = mxser_program_mode(port); + if (id < 0) + return id; + for (i = 0; i < 14; i++) { + k = (i & 0x3F) | 0x180; + for (j = 0x100; j > 0; j >>= 1) { + outb(CHIP_CS, port); + if (k & j) { + outb(CHIP_CS | CHIP_DO, port); + outb(CHIP_CS | CHIP_DO | CHIP_SK, port); /* A? bit of read */ + } else { + outb(CHIP_CS, port); + outb(CHIP_CS | CHIP_SK, port); /* A? bit of read */ + } + } + (void)inb(port); + value = 0; + for (k = 0, j = 0x8000; k < 16; k++, j >>= 1) { + outb(CHIP_CS, port); + outb(CHIP_CS | CHIP_SK, port); + if (inb(port) & CHIP_DI) + value |= j; + } + regs[i] = value; + outb(0, port); + } + mxser_normal_mode(port); + return id; +} + +static int mxser_ioctl_special(unsigned int cmd, void __user *argp) +{ + struct mxser_port *ip; + struct tty_port *port; + struct tty_struct *tty; + int result, status; + unsigned int i, j; + int ret = 0; + + switch (cmd) { + case MOXA_GET_MAJOR: + if (printk_ratelimit()) + printk(KERN_WARNING "mxser: '%s' uses deprecated ioctl " + "%x (GET_MAJOR), fix your userspace\n", + current->comm, cmd); + return put_user(ttymajor, (int __user *)argp); + + case MOXA_CHKPORTENABLE: + result = 0; + for (i = 0; i < MXSER_BOARDS; i++) + for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) + if (mxser_boards[i].ports[j].ioaddr) + result |= (1 << i); + return put_user(result, (unsigned long __user *)argp); + case MOXA_GETDATACOUNT: + /* The receive side is locked by port->slock but it isn't + clear that an exact snapshot is worth copying here */ + if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log))) + ret = -EFAULT; + return ret; + case MOXA_GETMSTATUS: { + struct mxser_mstatus ms, __user *msu = argp; + for (i = 0; i < MXSER_BOARDS; i++) + for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) { + ip = &mxser_boards[i].ports[j]; + port = &ip->port; + memset(&ms, 0, sizeof(ms)); + + mutex_lock(&port->mutex); + if (!ip->ioaddr) + goto copy; + + tty = tty_port_tty_get(port); + + if (!tty || !tty->termios) + ms.cflag = ip->normal_termios.c_cflag; + else + ms.cflag = tty->termios->c_cflag; + tty_kref_put(tty); + spin_lock_irq(&ip->slock); + status = inb(ip->ioaddr + UART_MSR); + spin_unlock_irq(&ip->slock); + if (status & UART_MSR_DCD) + ms.dcd = 1; + if (status & UART_MSR_DSR) + ms.dsr = 1; + if (status & UART_MSR_CTS) + ms.cts = 1; + copy: + mutex_unlock(&port->mutex); + if (copy_to_user(msu, &ms, sizeof(ms))) + return -EFAULT; + msu++; + } + return 0; + } + case MOXA_ASPP_MON_EXT: { + struct mxser_mon_ext *me; /* it's 2k, stack unfriendly */ + unsigned int cflag, iflag, p; + u8 opmode; + + me = kzalloc(sizeof(*me), GFP_KERNEL); + if (!me) + return -ENOMEM; + + for (i = 0, p = 0; i < MXSER_BOARDS; i++) { + for (j = 0; j < MXSER_PORTS_PER_BOARD; j++, p++) { + if (p >= ARRAY_SIZE(me->rx_cnt)) { + i = MXSER_BOARDS; + break; + } + ip = &mxser_boards[i].ports[j]; + port = &ip->port; + + mutex_lock(&port->mutex); + if (!ip->ioaddr) { + mutex_unlock(&port->mutex); + continue; + } + + spin_lock_irq(&ip->slock); + status = mxser_get_msr(ip->ioaddr, 0, p); + + if (status & UART_MSR_TERI) + ip->icount.rng++; + if (status & UART_MSR_DDSR) + ip->icount.dsr++; + if (status & UART_MSR_DDCD) + ip->icount.dcd++; + if (status & UART_MSR_DCTS) + ip->icount.cts++; + + ip->mon_data.modem_status = status; + me->rx_cnt[p] = ip->mon_data.rxcnt; + me->tx_cnt[p] = ip->mon_data.txcnt; + me->up_rxcnt[p] = ip->mon_data.up_rxcnt; + me->up_txcnt[p] = ip->mon_data.up_txcnt; + me->modem_status[p] = + ip->mon_data.modem_status; + spin_unlock_irq(&ip->slock); + + tty = tty_port_tty_get(&ip->port); + + if (!tty || !tty->termios) { + cflag = ip->normal_termios.c_cflag; + iflag = ip->normal_termios.c_iflag; + me->baudrate[p] = tty_termios_baud_rate(&ip->normal_termios); + } else { + cflag = tty->termios->c_cflag; + iflag = tty->termios->c_iflag; + me->baudrate[p] = tty_get_baud_rate(tty); + } + tty_kref_put(tty); + + me->databits[p] = cflag & CSIZE; + me->stopbits[p] = cflag & CSTOPB; + me->parity[p] = cflag & (PARENB | PARODD | + CMSPAR); + + if (cflag & CRTSCTS) + me->flowctrl[p] |= 0x03; + + if (iflag & (IXON | IXOFF)) + me->flowctrl[p] |= 0x0C; + + if (ip->type == PORT_16550A) + me->fifo[p] = 1; + + opmode = inb(ip->opmode_ioaddr)>>((p % 4) * 2); + opmode &= OP_MODE_MASK; + me->iftype[p] = opmode; + mutex_unlock(&port->mutex); + } + } + if (copy_to_user(argp, me, sizeof(*me))) + ret = -EFAULT; + kfree(me); + return ret; + } + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static int mxser_cflags_changed(struct mxser_port *info, unsigned long arg, + struct async_icount *cprev) +{ + struct async_icount cnow; + unsigned long flags; + int ret; + + spin_lock_irqsave(&info->slock, flags); + cnow = info->icount; /* atomic copy */ + spin_unlock_irqrestore(&info->slock, flags); + + ret = ((arg & TIOCM_RNG) && (cnow.rng != cprev->rng)) || + ((arg & TIOCM_DSR) && (cnow.dsr != cprev->dsr)) || + ((arg & TIOCM_CD) && (cnow.dcd != cprev->dcd)) || + ((arg & TIOCM_CTS) && (cnow.cts != cprev->cts)); + + *cprev = cnow; + + return ret; +} + +static int mxser_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + struct mxser_port *info = tty->driver_data; + struct tty_port *port = &info->port; + struct async_icount cnow; + unsigned long flags; + void __user *argp = (void __user *)arg; + int retval; + + if (tty->index == MXSER_PORTS) + return mxser_ioctl_special(cmd, argp); + + if (cmd == MOXA_SET_OP_MODE || cmd == MOXA_GET_OP_MODE) { + int p; + unsigned long opmode; + static unsigned char ModeMask[] = { 0xfc, 0xf3, 0xcf, 0x3f }; + int shiftbit; + unsigned char val, mask; + + p = tty->index % 4; + if (cmd == MOXA_SET_OP_MODE) { + if (get_user(opmode, (int __user *) argp)) + return -EFAULT; + if (opmode != RS232_MODE && + opmode != RS485_2WIRE_MODE && + opmode != RS422_MODE && + opmode != RS485_4WIRE_MODE) + return -EFAULT; + mask = ModeMask[p]; + shiftbit = p * 2; + spin_lock_irq(&info->slock); + val = inb(info->opmode_ioaddr); + val &= mask; + val |= (opmode << shiftbit); + outb(val, info->opmode_ioaddr); + spin_unlock_irq(&info->slock); + } else { + shiftbit = p * 2; + spin_lock_irq(&info->slock); + opmode = inb(info->opmode_ioaddr) >> shiftbit; + spin_unlock_irq(&info->slock); + opmode &= OP_MODE_MASK; + if (put_user(opmode, (int __user *)argp)) + return -EFAULT; + } + return 0; + } + + if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && + test_bit(TTY_IO_ERROR, &tty->flags)) + return -EIO; + + switch (cmd) { + case TIOCGSERIAL: + mutex_lock(&port->mutex); + retval = mxser_get_serial_info(tty, argp); + mutex_unlock(&port->mutex); + return retval; + case TIOCSSERIAL: + mutex_lock(&port->mutex); + retval = mxser_set_serial_info(tty, argp); + mutex_unlock(&port->mutex); + return retval; + case TIOCSERGETLSR: /* Get line status register */ + return mxser_get_lsr_info(info, argp); + /* + * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change + * - mask passed in arg for lines of interest + * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) + * Caller should use TIOCGICOUNT to see which one it was + */ + case TIOCMIWAIT: + spin_lock_irqsave(&info->slock, flags); + cnow = info->icount; /* note the counters on entry */ + spin_unlock_irqrestore(&info->slock, flags); + + return wait_event_interruptible(info->port.delta_msr_wait, + mxser_cflags_changed(info, arg, &cnow)); + case MOXA_HighSpeedOn: + return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp); + case MOXA_SDS_RSTICOUNTER: + spin_lock_irq(&info->slock); + info->mon_data.rxcnt = 0; + info->mon_data.txcnt = 0; + spin_unlock_irq(&info->slock); + return 0; + + case MOXA_ASPP_OQUEUE:{ + int len, lsr; + + len = mxser_chars_in_buffer(tty); + spin_lock_irq(&info->slock); + lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_THRE; + spin_unlock_irq(&info->slock); + len += (lsr ? 0 : 1); + + return put_user(len, (int __user *)argp); + } + case MOXA_ASPP_MON: { + int mcr, status; + + spin_lock_irq(&info->slock); + status = mxser_get_msr(info->ioaddr, 1, tty->index); + mxser_check_modem_status(tty, info, status); + + mcr = inb(info->ioaddr + UART_MCR); + spin_unlock_irq(&info->slock); + + if (mcr & MOXA_MUST_MCR_XON_FLAG) + info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD; + else + info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFHOLD; + + if (mcr & MOXA_MUST_MCR_TX_XON) + info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFXENT; + else + info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; + + if (tty->hw_stopped) + info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; + else + info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; + + if (copy_to_user(argp, &info->mon_data, + sizeof(struct mxser_mon))) + return -EFAULT; + + return 0; + } + case MOXA_ASPP_LSTATUS: { + if (put_user(info->err_shadow, (unsigned char __user *)argp)) + return -EFAULT; + + info->err_shadow = 0; + return 0; + } + case MOXA_SET_BAUD_METHOD: { + int method; + + if (get_user(method, (int __user *)argp)) + return -EFAULT; + mxser_set_baud_method[tty->index] = method; + return put_user(method, (int __user *)argp); + } + default: + return -ENOIOCTLCMD; + } + return 0; +} + + /* + * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) + * Return: write counters to the user passed counter struct + * NB: both 1->0 and 0->1 transitions are counted except for + * RI where only 0->1 is counted. + */ + +static int mxser_get_icount(struct tty_struct *tty, + struct serial_icounter_struct *icount) + +{ + struct mxser_port *info = tty->driver_data; + struct async_icount cnow; + unsigned long flags; + + spin_lock_irqsave(&info->slock, flags); + cnow = info->icount; + spin_unlock_irqrestore(&info->slock, flags); + + icount->frame = cnow.frame; + icount->brk = cnow.brk; + icount->overrun = cnow.overrun; + icount->buf_overrun = cnow.buf_overrun; + icount->parity = cnow.parity; + icount->rx = cnow.rx; + icount->tx = cnow.tx; + icount->cts = cnow.cts; + icount->dsr = cnow.dsr; + icount->rng = cnow.rng; + icount->dcd = cnow.dcd; + return 0; +} + +static void mxser_stoprx(struct tty_struct *tty) +{ + struct mxser_port *info = tty->driver_data; + + info->ldisc_stop_rx = 1; + if (I_IXOFF(tty)) { + if (info->board->chip_flag) { + info->IER &= ~MOXA_MUST_RECV_ISR; + outb(info->IER, info->ioaddr + UART_IER); + } else { + info->x_char = STOP_CHAR(tty); + outb(0, info->ioaddr + UART_IER); + info->IER |= UART_IER_THRI; + outb(info->IER, info->ioaddr + UART_IER); + } + } + + if (tty->termios->c_cflag & CRTSCTS) { + info->MCR &= ~UART_MCR_RTS; + outb(info->MCR, info->ioaddr + UART_MCR); + } +} + +/* + * This routine is called by the upper-layer tty layer to signal that + * incoming characters should be throttled. + */ +static void mxser_throttle(struct tty_struct *tty) +{ + mxser_stoprx(tty); +} + +static void mxser_unthrottle(struct tty_struct *tty) +{ + struct mxser_port *info = tty->driver_data; + + /* startrx */ + info->ldisc_stop_rx = 0; + if (I_IXOFF(tty)) { + if (info->x_char) + info->x_char = 0; + else { + if (info->board->chip_flag) { + info->IER |= MOXA_MUST_RECV_ISR; + outb(info->IER, info->ioaddr + UART_IER); + } else { + info->x_char = START_CHAR(tty); + outb(0, info->ioaddr + UART_IER); + info->IER |= UART_IER_THRI; + outb(info->IER, info->ioaddr + UART_IER); + } + } + } + + if (tty->termios->c_cflag & CRTSCTS) { + info->MCR |= UART_MCR_RTS; + outb(info->MCR, info->ioaddr + UART_MCR); + } +} + +/* + * mxser_stop() and mxser_start() + * + * This routines are called before setting or resetting tty->stopped. + * They enable or disable transmitter interrupts, as necessary. + */ +static void mxser_stop(struct tty_struct *tty) +{ + struct mxser_port *info = tty->driver_data; + unsigned long flags; + + spin_lock_irqsave(&info->slock, flags); + if (info->IER & UART_IER_THRI) { + info->IER &= ~UART_IER_THRI; + outb(info->IER, info->ioaddr + UART_IER); + } + spin_unlock_irqrestore(&info->slock, flags); +} + +static void mxser_start(struct tty_struct *tty) +{ + struct mxser_port *info = tty->driver_data; + unsigned long flags; + + spin_lock_irqsave(&info->slock, flags); + if (info->xmit_cnt && info->port.xmit_buf) { + outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER); + info->IER |= UART_IER_THRI; + outb(info->IER, info->ioaddr + UART_IER); + } + spin_unlock_irqrestore(&info->slock, flags); +} + +static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termios) +{ + struct mxser_port *info = tty->driver_data; + unsigned long flags; + + spin_lock_irqsave(&info->slock, flags); + mxser_change_speed(tty, old_termios); + spin_unlock_irqrestore(&info->slock, flags); + + if ((old_termios->c_cflag & CRTSCTS) && + !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + mxser_start(tty); + } + + /* Handle sw stopped */ + if ((old_termios->c_iflag & IXON) && + !(tty->termios->c_iflag & IXON)) { + tty->stopped = 0; + + if (info->board->chip_flag) { + spin_lock_irqsave(&info->slock, flags); + mxser_disable_must_rx_software_flow_control( + info->ioaddr); + spin_unlock_irqrestore(&info->slock, flags); + } + + mxser_start(tty); + } +} + +/* + * mxser_wait_until_sent() --- wait until the transmitter is empty + */ +static void mxser_wait_until_sent(struct tty_struct *tty, int timeout) +{ + struct mxser_port *info = tty->driver_data; + unsigned long orig_jiffies, char_time; + unsigned long flags; + int lsr; + + if (info->type == PORT_UNKNOWN) + return; + + if (info->xmit_fifo_size == 0) + return; /* Just in case.... */ + + orig_jiffies = jiffies; + /* + * Set the check interval to be 1/5 of the estimated time to + * send a single character, and make it at least 1. The check + * interval should also be less than the timeout. + * + * Note: we have to use pretty tight timings here to satisfy + * the NIST-PCTS. + */ + char_time = (info->timeout - HZ / 50) / info->xmit_fifo_size; + char_time = char_time / 5; + if (char_time == 0) + char_time = 1; + if (timeout && timeout < char_time) + char_time = timeout; + /* + * If the transmitter hasn't cleared in twice the approximate + * amount of time to send the entire FIFO, it probably won't + * ever clear. This assumes the UART isn't doing flow + * control, which is currently the case. Hence, if it ever + * takes longer than info->timeout, this is probably due to a + * UART bug of some kind. So, we clamp the timeout parameter at + * 2*info->timeout. + */ + if (!timeout || timeout > 2 * info->timeout) + timeout = 2 * info->timeout; +#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + printk(KERN_DEBUG "In rs_wait_until_sent(%d) check=%lu...", + timeout, char_time); + printk("jiff=%lu...", jiffies); +#endif + spin_lock_irqsave(&info->slock, flags); + while (!((lsr = inb(info->ioaddr + UART_LSR)) & UART_LSR_TEMT)) { +#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + printk("lsr = %d (jiff=%lu)...", lsr, jiffies); +#endif + spin_unlock_irqrestore(&info->slock, flags); + schedule_timeout_interruptible(char_time); + spin_lock_irqsave(&info->slock, flags); + if (signal_pending(current)) + break; + if (timeout && time_after(jiffies, orig_jiffies + timeout)) + break; + } + spin_unlock_irqrestore(&info->slock, flags); + set_current_state(TASK_RUNNING); + +#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); +#endif +} + +/* + * This routine is called by tty_hangup() when a hangup is signaled. + */ +static void mxser_hangup(struct tty_struct *tty) +{ + struct mxser_port *info = tty->driver_data; + + mxser_flush_buffer(tty); + tty_port_hangup(&info->port); +} + +/* + * mxser_rs_break() --- routine which turns the break handling on or off + */ +static int mxser_rs_break(struct tty_struct *tty, int break_state) +{ + struct mxser_port *info = tty->driver_data; + unsigned long flags; + + spin_lock_irqsave(&info->slock, flags); + if (break_state == -1) + outb(inb(info->ioaddr + UART_LCR) | UART_LCR_SBC, + info->ioaddr + UART_LCR); + else + outb(inb(info->ioaddr + UART_LCR) & ~UART_LCR_SBC, + info->ioaddr + UART_LCR); + spin_unlock_irqrestore(&info->slock, flags); + return 0; +} + +static void mxser_receive_chars(struct tty_struct *tty, + struct mxser_port *port, int *status) +{ + unsigned char ch, gdl; + int ignored = 0; + int cnt = 0; + int recv_room; + int max = 256; + + recv_room = tty->receive_room; + if (recv_room == 0 && !port->ldisc_stop_rx) + mxser_stoprx(tty); + if (port->board->chip_flag != MOXA_OTHER_UART) { + + if (*status & UART_LSR_SPECIAL) + goto intr_old; + if (port->board->chip_flag == MOXA_MUST_MU860_HWID && + (*status & MOXA_MUST_LSR_RERR)) + goto intr_old; + if (*status & MOXA_MUST_LSR_RERR) + goto intr_old; + + gdl = inb(port->ioaddr + MOXA_MUST_GDL_REGISTER); + + if (port->board->chip_flag == MOXA_MUST_MU150_HWID) + gdl &= MOXA_MUST_GDL_MASK; + if (gdl >= recv_room) { + if (!port->ldisc_stop_rx) + mxser_stoprx(tty); + } + while (gdl--) { + ch = inb(port->ioaddr + UART_RX); + tty_insert_flip_char(tty, ch, 0); + cnt++; + } + goto end_intr; + } +intr_old: + + do { + if (max-- < 0) + break; + + ch = inb(port->ioaddr + UART_RX); + if (port->board->chip_flag && (*status & UART_LSR_OE)) + outb(0x23, port->ioaddr + UART_FCR); + *status &= port->read_status_mask; + if (*status & port->ignore_status_mask) { + if (++ignored > 100) + break; + } else { + char flag = 0; + if (*status & UART_LSR_SPECIAL) { + if (*status & UART_LSR_BI) { + flag = TTY_BREAK; + port->icount.brk++; + + if (port->port.flags & ASYNC_SAK) + do_SAK(tty); + } else if (*status & UART_LSR_PE) { + flag = TTY_PARITY; + port->icount.parity++; + } else if (*status & UART_LSR_FE) { + flag = TTY_FRAME; + port->icount.frame++; + } else if (*status & UART_LSR_OE) { + flag = TTY_OVERRUN; + port->icount.overrun++; + } else + flag = TTY_BREAK; + } + tty_insert_flip_char(tty, ch, flag); + cnt++; + if (cnt >= recv_room) { + if (!port->ldisc_stop_rx) + mxser_stoprx(tty); + break; + } + + } + + if (port->board->chip_flag) + break; + + *status = inb(port->ioaddr + UART_LSR); + } while (*status & UART_LSR_DR); + +end_intr: + mxvar_log.rxcnt[tty->index] += cnt; + port->mon_data.rxcnt += cnt; + port->mon_data.up_rxcnt += cnt; + + /* + * We are called from an interrupt context with &port->slock + * being held. Drop it temporarily in order to prevent + * recursive locking. + */ + spin_unlock(&port->slock); + tty_flip_buffer_push(tty); + spin_lock(&port->slock); +} + +static void mxser_transmit_chars(struct tty_struct *tty, struct mxser_port *port) +{ + int count, cnt; + + if (port->x_char) { + outb(port->x_char, port->ioaddr + UART_TX); + port->x_char = 0; + mxvar_log.txcnt[tty->index]++; + port->mon_data.txcnt++; + port->mon_data.up_txcnt++; + port->icount.tx++; + return; + } + + if (port->port.xmit_buf == NULL) + return; + + if (port->xmit_cnt <= 0 || tty->stopped || + (tty->hw_stopped && + (port->type != PORT_16550A) && + (!port->board->chip_flag))) { + port->IER &= ~UART_IER_THRI; + outb(port->IER, port->ioaddr + UART_IER); + return; + } + + cnt = port->xmit_cnt; + count = port->xmit_fifo_size; + do { + outb(port->port.xmit_buf[port->xmit_tail++], + port->ioaddr + UART_TX); + port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE - 1); + if (--port->xmit_cnt <= 0) + break; + } while (--count > 0); + mxvar_log.txcnt[tty->index] += (cnt - port->xmit_cnt); + + port->mon_data.txcnt += (cnt - port->xmit_cnt); + port->mon_data.up_txcnt += (cnt - port->xmit_cnt); + port->icount.tx += (cnt - port->xmit_cnt); + + if (port->xmit_cnt < WAKEUP_CHARS) + tty_wakeup(tty); + + if (port->xmit_cnt <= 0) { + port->IER &= ~UART_IER_THRI; + outb(port->IER, port->ioaddr + UART_IER); + } +} + +/* + * This is the serial driver's generic interrupt routine + */ +static irqreturn_t mxser_interrupt(int irq, void *dev_id) +{ + int status, iir, i; + struct mxser_board *brd = NULL; + struct mxser_port *port; + int max, irqbits, bits, msr; + unsigned int int_cnt, pass_counter = 0; + int handled = IRQ_NONE; + struct tty_struct *tty; + + for (i = 0; i < MXSER_BOARDS; i++) + if (dev_id == &mxser_boards[i]) { + brd = dev_id; + break; + } + + if (i == MXSER_BOARDS) + goto irq_stop; + if (brd == NULL) + goto irq_stop; + max = brd->info->nports; + while (pass_counter++ < MXSER_ISR_PASS_LIMIT) { + irqbits = inb(brd->vector) & brd->vector_mask; + if (irqbits == brd->vector_mask) + break; + + handled = IRQ_HANDLED; + for (i = 0, bits = 1; i < max; i++, irqbits |= bits, bits <<= 1) { + if (irqbits == brd->vector_mask) + break; + if (bits & irqbits) + continue; + port = &brd->ports[i]; + + int_cnt = 0; + spin_lock(&port->slock); + do { + iir = inb(port->ioaddr + UART_IIR); + if (iir & UART_IIR_NO_INT) + break; + iir &= MOXA_MUST_IIR_MASK; + tty = tty_port_tty_get(&port->port); + if (!tty || + (port->port.flags & ASYNC_CLOSING) || + !(port->port.flags & + ASYNC_INITIALIZED)) { + status = inb(port->ioaddr + UART_LSR); + outb(0x27, port->ioaddr + UART_FCR); + inb(port->ioaddr + UART_MSR); + tty_kref_put(tty); + break; + } + + status = inb(port->ioaddr + UART_LSR); + + if (status & UART_LSR_PE) + port->err_shadow |= NPPI_NOTIFY_PARITY; + if (status & UART_LSR_FE) + port->err_shadow |= NPPI_NOTIFY_FRAMING; + if (status & UART_LSR_OE) + port->err_shadow |= + NPPI_NOTIFY_HW_OVERRUN; + if (status & UART_LSR_BI) + port->err_shadow |= NPPI_NOTIFY_BREAK; + + if (port->board->chip_flag) { + if (iir == MOXA_MUST_IIR_GDA || + iir == MOXA_MUST_IIR_RDA || + iir == MOXA_MUST_IIR_RTO || + iir == MOXA_MUST_IIR_LSR) + mxser_receive_chars(tty, port, + &status); + + } else { + status &= port->read_status_mask; + if (status & UART_LSR_DR) + mxser_receive_chars(tty, port, + &status); + } + msr = inb(port->ioaddr + UART_MSR); + if (msr & UART_MSR_ANY_DELTA) + mxser_check_modem_status(tty, port, msr); + + if (port->board->chip_flag) { + if (iir == 0x02 && (status & + UART_LSR_THRE)) + mxser_transmit_chars(tty, port); + } else { + if (status & UART_LSR_THRE) + mxser_transmit_chars(tty, port); + } + tty_kref_put(tty); + } while (int_cnt++ < MXSER_ISR_PASS_LIMIT); + spin_unlock(&port->slock); + } + } + +irq_stop: + return handled; +} + +static const struct tty_operations mxser_ops = { + .open = mxser_open, + .close = mxser_close, + .write = mxser_write, + .put_char = mxser_put_char, + .flush_chars = mxser_flush_chars, + .write_room = mxser_write_room, + .chars_in_buffer = mxser_chars_in_buffer, + .flush_buffer = mxser_flush_buffer, + .ioctl = mxser_ioctl, + .throttle = mxser_throttle, + .unthrottle = mxser_unthrottle, + .set_termios = mxser_set_termios, + .stop = mxser_stop, + .start = mxser_start, + .hangup = mxser_hangup, + .break_ctl = mxser_rs_break, + .wait_until_sent = mxser_wait_until_sent, + .tiocmget = mxser_tiocmget, + .tiocmset = mxser_tiocmset, + .get_icount = mxser_get_icount, +}; + +struct tty_port_operations mxser_port_ops = { + .carrier_raised = mxser_carrier_raised, + .dtr_rts = mxser_dtr_rts, + .activate = mxser_activate, + .shutdown = mxser_shutdown_port, +}; + +/* + * The MOXA Smartio/Industio serial driver boot-time initialization code! + */ + +static void mxser_release_ISA_res(struct mxser_board *brd) +{ + free_irq(brd->irq, brd); + release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); + release_region(brd->vector, 1); +} + +static int __devinit mxser_initbrd(struct mxser_board *brd, + struct pci_dev *pdev) +{ + struct mxser_port *info; + unsigned int i; + int retval; + + printk(KERN_INFO "mxser: max. baud rate = %d bps\n", + brd->ports[0].max_baud); + + for (i = 0; i < brd->info->nports; i++) { + info = &brd->ports[i]; + tty_port_init(&info->port); + info->port.ops = &mxser_port_ops; + info->board = brd; + info->stop_rx = 0; + info->ldisc_stop_rx = 0; + + /* Enhance mode enabled here */ + if (brd->chip_flag != MOXA_OTHER_UART) + mxser_enable_must_enchance_mode(info->ioaddr); + + info->port.flags = ASYNC_SHARE_IRQ; + info->type = brd->uart_type; + + process_txrx_fifo(info); + + info->custom_divisor = info->baud_base * 16; + info->port.close_delay = 5 * HZ / 10; + info->port.closing_wait = 30 * HZ; + info->normal_termios = mxvar_sdriver->init_termios; + memset(&info->mon_data, 0, sizeof(struct mxser_mon)); + info->err_shadow = 0; + spin_lock_init(&info->slock); + + /* before set INT ISR, disable all int */ + outb(inb(info->ioaddr + UART_IER) & 0xf0, + info->ioaddr + UART_IER); + } + + retval = request_irq(brd->irq, mxser_interrupt, IRQF_SHARED, "mxser", + brd); + if (retval) + printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may " + "conflict with another device.\n", + brd->info->name, brd->irq); + + return retval; +} + +static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) +{ + int id, i, bits; + unsigned short regs[16], irq; + unsigned char scratch, scratch2; + + brd->chip_flag = MOXA_OTHER_UART; + + id = mxser_read_register(cap, regs); + switch (id) { + case C168_ASIC_ID: + brd->info = &mxser_cards[0]; + break; + case C104_ASIC_ID: + brd->info = &mxser_cards[1]; + break; + case CI104J_ASIC_ID: + brd->info = &mxser_cards[2]; + break; + case C102_ASIC_ID: + brd->info = &mxser_cards[5]; + break; + case CI132_ASIC_ID: + brd->info = &mxser_cards[6]; + break; + case CI134_ASIC_ID: + brd->info = &mxser_cards[7]; + break; + default: + return 0; + } + + irq = 0; + /* some ISA cards have 2 ports, but we want to see them as 4-port (why?) + Flag-hack checks if configuration should be read as 2-port here. */ + if (brd->info->nports == 2 || (brd->info->flags & MXSER_HAS2)) { + irq = regs[9] & 0xF000; + irq = irq | (irq >> 4); + if (irq != (regs[9] & 0xFF00)) + goto err_irqconflict; + } else if (brd->info->nports == 4) { + irq = regs[9] & 0xF000; + irq = irq | (irq >> 4); + irq = irq | (irq >> 8); + if (irq != regs[9]) + goto err_irqconflict; + } else if (brd->info->nports == 8) { + irq = regs[9] & 0xF000; + irq = irq | (irq >> 4); + irq = irq | (irq >> 8); + if ((irq != regs[9]) || (irq != regs[10])) + goto err_irqconflict; + } + + if (!irq) { + printk(KERN_ERR "mxser: interrupt number unset\n"); + return -EIO; + } + brd->irq = ((int)(irq & 0xF000) >> 12); + for (i = 0; i < 8; i++) + brd->ports[i].ioaddr = (int) regs[i + 1] & 0xFFF8; + if ((regs[12] & 0x80) == 0) { + printk(KERN_ERR "mxser: invalid interrupt vector\n"); + return -EIO; + } + brd->vector = (int)regs[11]; /* interrupt vector */ + if (id == 1) + brd->vector_mask = 0x00FF; + else + brd->vector_mask = 0x000F; + for (i = 7, bits = 0x0100; i >= 0; i--, bits <<= 1) { + if (regs[12] & bits) { + brd->ports[i].baud_base = 921600; + brd->ports[i].max_baud = 921600; + } else { + brd->ports[i].baud_base = 115200; + brd->ports[i].max_baud = 115200; + } + } + scratch2 = inb(cap + UART_LCR) & (~UART_LCR_DLAB); + outb(scratch2 | UART_LCR_DLAB, cap + UART_LCR); + outb(0, cap + UART_EFR); /* EFR is the same as FCR */ + outb(scratch2, cap + UART_LCR); + outb(UART_FCR_ENABLE_FIFO, cap + UART_FCR); + scratch = inb(cap + UART_IIR); + + if (scratch & 0xC0) + brd->uart_type = PORT_16550A; + else + brd->uart_type = PORT_16450; + if (!request_region(brd->ports[0].ioaddr, 8 * brd->info->nports, + "mxser(IO)")) { + printk(KERN_ERR "mxser: can't request ports I/O region: " + "0x%.8lx-0x%.8lx\n", + brd->ports[0].ioaddr, brd->ports[0].ioaddr + + 8 * brd->info->nports - 1); + return -EIO; + } + if (!request_region(brd->vector, 1, "mxser(vector)")) { + release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); + printk(KERN_ERR "mxser: can't request interrupt vector region: " + "0x%.8lx-0x%.8lx\n", + brd->ports[0].ioaddr, brd->ports[0].ioaddr + + 8 * brd->info->nports - 1); + return -EIO; + } + return brd->info->nports; + +err_irqconflict: + printk(KERN_ERR "mxser: invalid interrupt number\n"); + return -EIO; +} + +static int __devinit mxser_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ +#ifdef CONFIG_PCI + struct mxser_board *brd; + unsigned int i, j; + unsigned long ioaddress; + int retval = -EINVAL; + + for (i = 0; i < MXSER_BOARDS; i++) + if (mxser_boards[i].info == NULL) + break; + + if (i >= MXSER_BOARDS) { + dev_err(&pdev->dev, "too many boards found (maximum %d), board " + "not configured\n", MXSER_BOARDS); + goto err; + } + + brd = &mxser_boards[i]; + brd->idx = i * MXSER_PORTS_PER_BOARD; + dev_info(&pdev->dev, "found MOXA %s board (BusNo=%d, DevNo=%d)\n", + mxser_cards[ent->driver_data].name, + pdev->bus->number, PCI_SLOT(pdev->devfn)); + + retval = pci_enable_device(pdev); + if (retval) { + dev_err(&pdev->dev, "PCI enable failed\n"); + goto err; + } + + /* io address */ + ioaddress = pci_resource_start(pdev, 2); + retval = pci_request_region(pdev, 2, "mxser(IO)"); + if (retval) + goto err_dis; + + brd->info = &mxser_cards[ent->driver_data]; + for (i = 0; i < brd->info->nports; i++) + brd->ports[i].ioaddr = ioaddress + 8 * i; + + /* vector */ + ioaddress = pci_resource_start(pdev, 3); + retval = pci_request_region(pdev, 3, "mxser(vector)"); + if (retval) + goto err_zero; + brd->vector = ioaddress; + + /* irq */ + brd->irq = pdev->irq; + + brd->chip_flag = CheckIsMoxaMust(brd->ports[0].ioaddr); + brd->uart_type = PORT_16550A; + brd->vector_mask = 0; + + for (i = 0; i < brd->info->nports; i++) { + for (j = 0; j < UART_INFO_NUM; j++) { + if (Gpci_uart_info[j].type == brd->chip_flag) { + brd->ports[i].max_baud = + Gpci_uart_info[j].max_baud; + + /* exception....CP-102 */ + if (brd->info->flags & MXSER_HIGHBAUD) + brd->ports[i].max_baud = 921600; + break; + } + } + } + + if (brd->chip_flag == MOXA_MUST_MU860_HWID) { + for (i = 0; i < brd->info->nports; i++) { + if (i < 4) + brd->ports[i].opmode_ioaddr = ioaddress + 4; + else + brd->ports[i].opmode_ioaddr = ioaddress + 0x0c; + } + outb(0, ioaddress + 4); /* default set to RS232 mode */ + outb(0, ioaddress + 0x0c); /* default set to RS232 mode */ + } + + for (i = 0; i < brd->info->nports; i++) { + brd->vector_mask |= (1 << i); + brd->ports[i].baud_base = 921600; + } + + /* mxser_initbrd will hook ISR. */ + retval = mxser_initbrd(brd, pdev); + if (retval) + goto err_rel3; + + for (i = 0; i < brd->info->nports; i++) + tty_register_device(mxvar_sdriver, brd->idx + i, &pdev->dev); + + pci_set_drvdata(pdev, brd); + + return 0; +err_rel3: + pci_release_region(pdev, 3); +err_zero: + brd->info = NULL; + pci_release_region(pdev, 2); +err_dis: + pci_disable_device(pdev); +err: + return retval; +#else + return -ENODEV; +#endif +} + +static void __devexit mxser_remove(struct pci_dev *pdev) +{ +#ifdef CONFIG_PCI + struct mxser_board *brd = pci_get_drvdata(pdev); + unsigned int i; + + for (i = 0; i < brd->info->nports; i++) + tty_unregister_device(mxvar_sdriver, brd->idx + i); + + free_irq(pdev->irq, brd); + pci_release_region(pdev, 2); + pci_release_region(pdev, 3); + pci_disable_device(pdev); + brd->info = NULL; +#endif +} + +static struct pci_driver mxser_driver = { + .name = "mxser", + .id_table = mxser_pcibrds, + .probe = mxser_probe, + .remove = __devexit_p(mxser_remove) +}; + +static int __init mxser_module_init(void) +{ + struct mxser_board *brd; + unsigned int b, i, m; + int retval; + + mxvar_sdriver = alloc_tty_driver(MXSER_PORTS + 1); + if (!mxvar_sdriver) + return -ENOMEM; + + printk(KERN_INFO "MOXA Smartio/Industio family driver version %s\n", + MXSER_VERSION); + + /* Initialize the tty_driver structure */ + mxvar_sdriver->owner = THIS_MODULE; + mxvar_sdriver->magic = TTY_DRIVER_MAGIC; + mxvar_sdriver->name = "ttyMI"; + mxvar_sdriver->major = ttymajor; + mxvar_sdriver->minor_start = 0; + mxvar_sdriver->num = MXSER_PORTS + 1; + mxvar_sdriver->type = TTY_DRIVER_TYPE_SERIAL; + mxvar_sdriver->subtype = SERIAL_TYPE_NORMAL; + mxvar_sdriver->init_termios = tty_std_termios; + mxvar_sdriver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; + mxvar_sdriver->flags = TTY_DRIVER_REAL_RAW|TTY_DRIVER_DYNAMIC_DEV; + tty_set_operations(mxvar_sdriver, &mxser_ops); + + retval = tty_register_driver(mxvar_sdriver); + if (retval) { + printk(KERN_ERR "Couldn't install MOXA Smartio/Industio family " + "tty driver !\n"); + goto err_put; + } + + /* Start finding ISA boards here */ + for (m = 0, b = 0; b < MXSER_BOARDS; b++) { + if (!ioaddr[b]) + continue; + + brd = &mxser_boards[m]; + retval = mxser_get_ISA_conf(ioaddr[b], brd); + if (retval <= 0) { + brd->info = NULL; + continue; + } + + printk(KERN_INFO "mxser: found MOXA %s board (CAP=0x%lx)\n", + brd->info->name, ioaddr[b]); + + /* mxser_initbrd will hook ISR. */ + if (mxser_initbrd(brd, NULL) < 0) { + brd->info = NULL; + continue; + } + + brd->idx = m * MXSER_PORTS_PER_BOARD; + for (i = 0; i < brd->info->nports; i++) + tty_register_device(mxvar_sdriver, brd->idx + i, NULL); + + m++; + } + + retval = pci_register_driver(&mxser_driver); + if (retval) { + printk(KERN_ERR "mxser: can't register pci driver\n"); + if (!m) { + retval = -ENODEV; + goto err_unr; + } /* else: we have some ISA cards under control */ + } + + return 0; +err_unr: + tty_unregister_driver(mxvar_sdriver); +err_put: + put_tty_driver(mxvar_sdriver); + return retval; +} + +static void __exit mxser_module_exit(void) +{ + unsigned int i, j; + + pci_unregister_driver(&mxser_driver); + + for (i = 0; i < MXSER_BOARDS; i++) /* ISA remains */ + if (mxser_boards[i].info != NULL) + for (j = 0; j < mxser_boards[i].info->nports; j++) + tty_unregister_device(mxvar_sdriver, + mxser_boards[i].idx + j); + tty_unregister_driver(mxvar_sdriver); + put_tty_driver(mxvar_sdriver); + + for (i = 0; i < MXSER_BOARDS; i++) + if (mxser_boards[i].info != NULL) + mxser_release_ISA_res(&mxser_boards[i]); +} + +module_init(mxser_module_init); +module_exit(mxser_module_exit); diff --git a/drivers/tty/mxser.h b/drivers/tty/mxser.h new file mode 100644 index 000000000000..41878a69203d --- /dev/null +++ b/drivers/tty/mxser.h @@ -0,0 +1,150 @@ +#ifndef _MXSER_H +#define _MXSER_H + +/* + * Semi-public control interfaces + */ + +/* + * MOXA ioctls + */ + +#define MOXA 0x400 +#define MOXA_GETDATACOUNT (MOXA + 23) +#define MOXA_DIAGNOSE (MOXA + 50) +#define MOXA_CHKPORTENABLE (MOXA + 60) +#define MOXA_HighSpeedOn (MOXA + 61) +#define MOXA_GET_MAJOR (MOXA + 63) +#define MOXA_GETMSTATUS (MOXA + 65) +#define MOXA_SET_OP_MODE (MOXA + 66) +#define MOXA_GET_OP_MODE (MOXA + 67) + +#define RS232_MODE 0 +#define RS485_2WIRE_MODE 1 +#define RS422_MODE 2 +#define RS485_4WIRE_MODE 3 +#define OP_MODE_MASK 3 + +#define MOXA_SDS_RSTICOUNTER (MOXA + 69) +#define MOXA_ASPP_OQUEUE (MOXA + 70) +#define MOXA_ASPP_MON (MOXA + 73) +#define MOXA_ASPP_LSTATUS (MOXA + 74) +#define MOXA_ASPP_MON_EXT (MOXA + 75) +#define MOXA_SET_BAUD_METHOD (MOXA + 76) + +/* --------------------------------------------------- */ + +#define NPPI_NOTIFY_PARITY 0x01 +#define NPPI_NOTIFY_FRAMING 0x02 +#define NPPI_NOTIFY_HW_OVERRUN 0x04 +#define NPPI_NOTIFY_SW_OVERRUN 0x08 +#define NPPI_NOTIFY_BREAK 0x10 + +#define NPPI_NOTIFY_CTSHOLD 0x01 /* Tx hold by CTS low */ +#define NPPI_NOTIFY_DSRHOLD 0x02 /* Tx hold by DSR low */ +#define NPPI_NOTIFY_XOFFHOLD 0x08 /* Tx hold by Xoff received */ +#define NPPI_NOTIFY_XOFFXENT 0x10 /* Xoff Sent */ + +/* follow just for Moxa Must chip define. */ +/* */ +/* when LCR register (offset 0x03) write following value, */ +/* the Must chip will enter enchance mode. And write value */ +/* on EFR (offset 0x02) bit 6,7 to change bank. */ +#define MOXA_MUST_ENTER_ENCHANCE 0xBF + +/* when enhance mode enable, access on general bank register */ +#define MOXA_MUST_GDL_REGISTER 0x07 +#define MOXA_MUST_GDL_MASK 0x7F +#define MOXA_MUST_GDL_HAS_BAD_DATA 0x80 + +#define MOXA_MUST_LSR_RERR 0x80 /* error in receive FIFO */ +/* enchance register bank select and enchance mode setting register */ +/* when LCR register equal to 0xBF */ +#define MOXA_MUST_EFR_REGISTER 0x02 +/* enchance mode enable */ +#define MOXA_MUST_EFR_EFRB_ENABLE 0x10 +/* enchance reister bank set 0, 1, 2 */ +#define MOXA_MUST_EFR_BANK0 0x00 +#define MOXA_MUST_EFR_BANK1 0x40 +#define MOXA_MUST_EFR_BANK2 0x80 +#define MOXA_MUST_EFR_BANK3 0xC0 +#define MOXA_MUST_EFR_BANK_MASK 0xC0 + +/* set XON1 value register, when LCR=0xBF and change to bank0 */ +#define MOXA_MUST_XON1_REGISTER 0x04 + +/* set XON2 value register, when LCR=0xBF and change to bank0 */ +#define MOXA_MUST_XON2_REGISTER 0x05 + +/* set XOFF1 value register, when LCR=0xBF and change to bank0 */ +#define MOXA_MUST_XOFF1_REGISTER 0x06 + +/* set XOFF2 value register, when LCR=0xBF and change to bank0 */ +#define MOXA_MUST_XOFF2_REGISTER 0x07 + +#define MOXA_MUST_RBRTL_REGISTER 0x04 +#define MOXA_MUST_RBRTH_REGISTER 0x05 +#define MOXA_MUST_RBRTI_REGISTER 0x06 +#define MOXA_MUST_THRTL_REGISTER 0x07 +#define MOXA_MUST_ENUM_REGISTER 0x04 +#define MOXA_MUST_HWID_REGISTER 0x05 +#define MOXA_MUST_ECR_REGISTER 0x06 +#define MOXA_MUST_CSR_REGISTER 0x07 + +/* good data mode enable */ +#define MOXA_MUST_FCR_GDA_MODE_ENABLE 0x20 +/* only good data put into RxFIFO */ +#define MOXA_MUST_FCR_GDA_ONLY_ENABLE 0x10 + +/* enable CTS interrupt */ +#define MOXA_MUST_IER_ECTSI 0x80 +/* enable RTS interrupt */ +#define MOXA_MUST_IER_ERTSI 0x40 +/* enable Xon/Xoff interrupt */ +#define MOXA_MUST_IER_XINT 0x20 +/* enable GDA interrupt */ +#define MOXA_MUST_IER_EGDAI 0x10 + +#define MOXA_MUST_RECV_ISR (UART_IER_RDI | MOXA_MUST_IER_EGDAI) + +/* GDA interrupt pending */ +#define MOXA_MUST_IIR_GDA 0x1C +#define MOXA_MUST_IIR_RDA 0x04 +#define MOXA_MUST_IIR_RTO 0x0C +#define MOXA_MUST_IIR_LSR 0x06 + +/* recieved Xon/Xoff or specical interrupt pending */ +#define MOXA_MUST_IIR_XSC 0x10 + +/* RTS/CTS change state interrupt pending */ +#define MOXA_MUST_IIR_RTSCTS 0x20 +#define MOXA_MUST_IIR_MASK 0x3E + +#define MOXA_MUST_MCR_XON_FLAG 0x40 +#define MOXA_MUST_MCR_XON_ANY 0x80 +#define MOXA_MUST_MCR_TX_XON 0x08 + +/* software flow control on chip mask value */ +#define MOXA_MUST_EFR_SF_MASK 0x0F +/* send Xon1/Xoff1 */ +#define MOXA_MUST_EFR_SF_TX1 0x08 +/* send Xon2/Xoff2 */ +#define MOXA_MUST_EFR_SF_TX2 0x04 +/* send Xon1,Xon2/Xoff1,Xoff2 */ +#define MOXA_MUST_EFR_SF_TX12 0x0C +/* don't send Xon/Xoff */ +#define MOXA_MUST_EFR_SF_TX_NO 0x00 +/* Tx software flow control mask */ +#define MOXA_MUST_EFR_SF_TX_MASK 0x0C +/* don't receive Xon/Xoff */ +#define MOXA_MUST_EFR_SF_RX_NO 0x00 +/* receive Xon1/Xoff1 */ +#define MOXA_MUST_EFR_SF_RX1 0x02 +/* receive Xon2/Xoff2 */ +#define MOXA_MUST_EFR_SF_RX2 0x01 +/* receive Xon1,Xon2/Xoff1,Xoff2 */ +#define MOXA_MUST_EFR_SF_RX12 0x03 +/* Rx software flow control mask */ +#define MOXA_MUST_EFR_SF_RX_MASK 0x03 + +#endif diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c new file mode 100644 index 000000000000..513ba12064ea --- /dev/null +++ b/drivers/tty/nozomi.c @@ -0,0 +1,1993 @@ +/* + * nozomi.c -- HSDPA driver Broadband Wireless Data Card - Globe Trotter + * + * Written by: Ulf Jakobsson, + * Jan Åkerfeldt, + * Stefan Thomasson, + * + * Maintained by: Paul Hardwick (p.hardwick@option.com) + * + * Patches: + * Locking code changes for Vodafone by Sphere Systems Ltd, + * Andrew Bird (ajb@spheresystems.co.uk ) + * & Phil Sanderson + * + * Source has been ported from an implementation made by Filip Aben @ Option + * + * -------------------------------------------------------------------------- + * + * Copyright (c) 2005,2006 Option Wireless Sweden AB + * Copyright (c) 2006 Sphere Systems Ltd + * Copyright (c) 2006 Option Wireless n/v + * All rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * -------------------------------------------------------------------------- + */ + +/* Enable this to have a lot of debug printouts */ +#define DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#define VERSION_STRING DRIVER_DESC " 2.1d (build date: " \ + __DATE__ " " __TIME__ ")" + +/* Macros definitions */ + +/* Default debug printout level */ +#define NOZOMI_DEBUG_LEVEL 0x00 + +#define P_BUF_SIZE 128 +#define NFO(_err_flag_, args...) \ +do { \ + char tmp[P_BUF_SIZE]; \ + snprintf(tmp, sizeof(tmp), ##args); \ + printk(_err_flag_ "[%d] %s(): %s\n", __LINE__, \ + __func__, tmp); \ +} while (0) + +#define DBG1(args...) D_(0x01, ##args) +#define DBG2(args...) D_(0x02, ##args) +#define DBG3(args...) D_(0x04, ##args) +#define DBG4(args...) D_(0x08, ##args) +#define DBG5(args...) D_(0x10, ##args) +#define DBG6(args...) D_(0x20, ##args) +#define DBG7(args...) D_(0x40, ##args) +#define DBG8(args...) D_(0x80, ##args) + +#ifdef DEBUG +/* Do we need this settable at runtime? */ +static int debug = NOZOMI_DEBUG_LEVEL; + +#define D(lvl, args...) do \ + {if (lvl & debug) NFO(KERN_DEBUG, ##args); } \ + while (0) +#define D_(lvl, args...) D(lvl, ##args) + +/* These printouts are always printed */ + +#else +static int debug; +#define D_(lvl, args...) +#endif + +/* TODO: rewrite to optimize macros... */ + +#define TMP_BUF_MAX 256 + +#define DUMP(buf__,len__) \ + do { \ + char tbuf[TMP_BUF_MAX] = {0};\ + if (len__ > 1) {\ + snprintf(tbuf, len__ > TMP_BUF_MAX ? TMP_BUF_MAX : len__, "%s", buf__);\ + if (tbuf[len__-2] == '\r') {\ + tbuf[len__-2] = 'r';\ + } \ + DBG1("SENDING: '%s' (%d+n)", tbuf, len__);\ + } else {\ + DBG1("SENDING: '%s' (%d)", tbuf, len__);\ + } \ +} while (0) + +/* Defines */ +#define NOZOMI_NAME "nozomi" +#define NOZOMI_NAME_TTY "nozomi_tty" +#define DRIVER_DESC "Nozomi driver" + +#define NTTY_TTY_MAXMINORS 256 +#define NTTY_FIFO_BUFFER_SIZE 8192 + +/* Must be power of 2 */ +#define FIFO_BUFFER_SIZE_UL 8192 + +/* Size of tmp send buffer to card */ +#define SEND_BUF_MAX 1024 +#define RECEIVE_BUF_MAX 4 + + +#define R_IIR 0x0000 /* Interrupt Identity Register */ +#define R_FCR 0x0000 /* Flow Control Register */ +#define R_IER 0x0004 /* Interrupt Enable Register */ + +#define CONFIG_MAGIC 0xEFEFFEFE +#define TOGGLE_VALID 0x0000 + +/* Definition of interrupt tokens */ +#define MDM_DL1 0x0001 +#define MDM_UL1 0x0002 +#define MDM_DL2 0x0004 +#define MDM_UL2 0x0008 +#define DIAG_DL1 0x0010 +#define DIAG_DL2 0x0020 +#define DIAG_UL 0x0040 +#define APP1_DL 0x0080 +#define APP1_UL 0x0100 +#define APP2_DL 0x0200 +#define APP2_UL 0x0400 +#define CTRL_DL 0x0800 +#define CTRL_UL 0x1000 +#define RESET 0x8000 + +#define MDM_DL (MDM_DL1 | MDM_DL2) +#define MDM_UL (MDM_UL1 | MDM_UL2) +#define DIAG_DL (DIAG_DL1 | DIAG_DL2) + +/* modem signal definition */ +#define CTRL_DSR 0x0001 +#define CTRL_DCD 0x0002 +#define CTRL_RI 0x0004 +#define CTRL_CTS 0x0008 + +#define CTRL_DTR 0x0001 +#define CTRL_RTS 0x0002 + +#define MAX_PORT 4 +#define NOZOMI_MAX_PORTS 5 +#define NOZOMI_MAX_CARDS (NTTY_TTY_MAXMINORS / MAX_PORT) + +/* Type definitions */ + +/* + * There are two types of nozomi cards, + * one with 2048 memory and with 8192 memory + */ +enum card_type { + F32_2 = 2048, /* 512 bytes downlink + uplink * 2 -> 2048 */ + F32_8 = 8192, /* 3072 bytes downl. + 1024 bytes uplink * 2 -> 8192 */ +}; + +/* Initialization states a card can be in */ +enum card_state { + NOZOMI_STATE_UKNOWN = 0, + NOZOMI_STATE_ENABLED = 1, /* pci device enabled */ + NOZOMI_STATE_ALLOCATED = 2, /* config setup done */ + NOZOMI_STATE_READY = 3, /* flowcontrols received */ +}; + +/* Two different toggle channels exist */ +enum channel_type { + CH_A = 0, + CH_B = 1, +}; + +/* Port definition for the card regarding flow control */ +enum ctrl_port_type { + CTRL_CMD = 0, + CTRL_MDM = 1, + CTRL_DIAG = 2, + CTRL_APP1 = 3, + CTRL_APP2 = 4, + CTRL_ERROR = -1, +}; + +/* Ports that the nozomi has */ +enum port_type { + PORT_MDM = 0, + PORT_DIAG = 1, + PORT_APP1 = 2, + PORT_APP2 = 3, + PORT_CTRL = 4, + PORT_ERROR = -1, +}; + +#ifdef __BIG_ENDIAN +/* Big endian */ + +struct toggles { + unsigned int enabled:5; /* + * Toggle fields are valid if enabled is 0, + * else A-channels must always be used. + */ + unsigned int diag_dl:1; + unsigned int mdm_dl:1; + unsigned int mdm_ul:1; +} __attribute__ ((packed)); + +/* Configuration table to read at startup of card */ +/* Is for now only needed during initialization phase */ +struct config_table { + u32 signature; + u16 product_information; + u16 version; + u8 pad3[3]; + struct toggles toggle; + u8 pad1[4]; + u16 dl_mdm_len1; /* + * If this is 64, it can hold + * 60 bytes + 4 that is length field + */ + u16 dl_start; + + u16 dl_diag_len1; + u16 dl_mdm_len2; /* + * If this is 64, it can hold + * 60 bytes + 4 that is length field + */ + u16 dl_app1_len; + + u16 dl_diag_len2; + u16 dl_ctrl_len; + u16 dl_app2_len; + u8 pad2[16]; + u16 ul_mdm_len1; + u16 ul_start; + u16 ul_diag_len; + u16 ul_mdm_len2; + u16 ul_app1_len; + u16 ul_app2_len; + u16 ul_ctrl_len; +} __attribute__ ((packed)); + +/* This stores all control downlink flags */ +struct ctrl_dl { + u8 port; + unsigned int reserved:4; + unsigned int CTS:1; + unsigned int RI:1; + unsigned int DCD:1; + unsigned int DSR:1; +} __attribute__ ((packed)); + +/* This stores all control uplink flags */ +struct ctrl_ul { + u8 port; + unsigned int reserved:6; + unsigned int RTS:1; + unsigned int DTR:1; +} __attribute__ ((packed)); + +#else +/* Little endian */ + +/* This represents the toggle information */ +struct toggles { + unsigned int mdm_ul:1; + unsigned int mdm_dl:1; + unsigned int diag_dl:1; + unsigned int enabled:5; /* + * Toggle fields are valid if enabled is 0, + * else A-channels must always be used. + */ +} __attribute__ ((packed)); + +/* Configuration table to read at startup of card */ +struct config_table { + u32 signature; + u16 version; + u16 product_information; + struct toggles toggle; + u8 pad1[7]; + u16 dl_start; + u16 dl_mdm_len1; /* + * If this is 64, it can hold + * 60 bytes + 4 that is length field + */ + u16 dl_mdm_len2; + u16 dl_diag_len1; + u16 dl_diag_len2; + u16 dl_app1_len; + u16 dl_app2_len; + u16 dl_ctrl_len; + u8 pad2[16]; + u16 ul_start; + u16 ul_mdm_len2; + u16 ul_mdm_len1; + u16 ul_diag_len; + u16 ul_app1_len; + u16 ul_app2_len; + u16 ul_ctrl_len; +} __attribute__ ((packed)); + +/* This stores all control downlink flags */ +struct ctrl_dl { + unsigned int DSR:1; + unsigned int DCD:1; + unsigned int RI:1; + unsigned int CTS:1; + unsigned int reserverd:4; + u8 port; +} __attribute__ ((packed)); + +/* This stores all control uplink flags */ +struct ctrl_ul { + unsigned int DTR:1; + unsigned int RTS:1; + unsigned int reserved:6; + u8 port; +} __attribute__ ((packed)); +#endif + +/* This holds all information that is needed regarding a port */ +struct port { + struct tty_port port; + u8 update_flow_control; + struct ctrl_ul ctrl_ul; + struct ctrl_dl ctrl_dl; + struct kfifo fifo_ul; + void __iomem *dl_addr[2]; + u32 dl_size[2]; + u8 toggle_dl; + void __iomem *ul_addr[2]; + u32 ul_size[2]; + u8 toggle_ul; + u16 token_dl; + + /* mutex to ensure one access patch to this port */ + struct mutex tty_sem; + wait_queue_head_t tty_wait; + struct async_icount tty_icount; + + struct nozomi *dc; +}; + +/* Private data one for each card in the system */ +struct nozomi { + void __iomem *base_addr; + unsigned long flip; + + /* Pointers to registers */ + void __iomem *reg_iir; + void __iomem *reg_fcr; + void __iomem *reg_ier; + + u16 last_ier; + enum card_type card_type; + struct config_table config_table; /* Configuration table */ + struct pci_dev *pdev; + struct port port[NOZOMI_MAX_PORTS]; + u8 *send_buf; + + spinlock_t spin_mutex; /* secures access to registers and tty */ + + unsigned int index_start; + enum card_state state; + u32 open_ttys; +}; + +/* This is a data packet that is read or written to/from card */ +struct buffer { + u32 size; /* size is the length of the data buffer */ + u8 *data; +} __attribute__ ((packed)); + +/* Global variables */ +static const struct pci_device_id nozomi_pci_tbl[] __devinitconst = { + {PCI_DEVICE(0x1931, 0x000c)}, /* Nozomi HSDPA */ + {}, +}; + +MODULE_DEVICE_TABLE(pci, nozomi_pci_tbl); + +static struct nozomi *ndevs[NOZOMI_MAX_CARDS]; +static struct tty_driver *ntty_driver; + +static const struct tty_port_operations noz_tty_port_ops; + +/* + * find card by tty_index + */ +static inline struct nozomi *get_dc_by_tty(const struct tty_struct *tty) +{ + return tty ? ndevs[tty->index / MAX_PORT] : NULL; +} + +static inline struct port *get_port_by_tty(const struct tty_struct *tty) +{ + struct nozomi *ndev = get_dc_by_tty(tty); + return ndev ? &ndev->port[tty->index % MAX_PORT] : NULL; +} + +/* + * TODO: + * -Optimize + * -Rewrite cleaner + */ + +static void read_mem32(u32 *buf, const void __iomem *mem_addr_start, + u32 size_bytes) +{ + u32 i = 0; + const u32 __iomem *ptr = mem_addr_start; + u16 *buf16; + + if (unlikely(!ptr || !buf)) + goto out; + + /* shortcut for extremely often used cases */ + switch (size_bytes) { + case 2: /* 2 bytes */ + buf16 = (u16 *) buf; + *buf16 = __le16_to_cpu(readw(ptr)); + goto out; + break; + case 4: /* 4 bytes */ + *(buf) = __le32_to_cpu(readl(ptr)); + goto out; + break; + } + + while (i < size_bytes) { + if (size_bytes - i == 2) { + /* Handle 2 bytes in the end */ + buf16 = (u16 *) buf; + *(buf16) = __le16_to_cpu(readw(ptr)); + i += 2; + } else { + /* Read 4 bytes */ + *(buf) = __le32_to_cpu(readl(ptr)); + i += 4; + } + buf++; + ptr++; + } +out: + return; +} + +/* + * TODO: + * -Optimize + * -Rewrite cleaner + */ +static u32 write_mem32(void __iomem *mem_addr_start, const u32 *buf, + u32 size_bytes) +{ + u32 i = 0; + u32 __iomem *ptr = mem_addr_start; + const u16 *buf16; + + if (unlikely(!ptr || !buf)) + return 0; + + /* shortcut for extremely often used cases */ + switch (size_bytes) { + case 2: /* 2 bytes */ + buf16 = (const u16 *)buf; + writew(__cpu_to_le16(*buf16), ptr); + return 2; + break; + case 1: /* + * also needs to write 4 bytes in this case + * so falling through.. + */ + case 4: /* 4 bytes */ + writel(__cpu_to_le32(*buf), ptr); + return 4; + break; + } + + while (i < size_bytes) { + if (size_bytes - i == 2) { + /* 2 bytes */ + buf16 = (const u16 *)buf; + writew(__cpu_to_le16(*buf16), ptr); + i += 2; + } else { + /* 4 bytes */ + writel(__cpu_to_le32(*buf), ptr); + i += 4; + } + buf++; + ptr++; + } + return i; +} + +/* Setup pointers to different channels and also setup buffer sizes. */ +static void setup_memory(struct nozomi *dc) +{ + void __iomem *offset = dc->base_addr + dc->config_table.dl_start; + /* The length reported is including the length field of 4 bytes, + * hence subtract with 4. + */ + const u16 buff_offset = 4; + + /* Modem port dl configuration */ + dc->port[PORT_MDM].dl_addr[CH_A] = offset; + dc->port[PORT_MDM].dl_addr[CH_B] = + (offset += dc->config_table.dl_mdm_len1); + dc->port[PORT_MDM].dl_size[CH_A] = + dc->config_table.dl_mdm_len1 - buff_offset; + dc->port[PORT_MDM].dl_size[CH_B] = + dc->config_table.dl_mdm_len2 - buff_offset; + + /* Diag port dl configuration */ + dc->port[PORT_DIAG].dl_addr[CH_A] = + (offset += dc->config_table.dl_mdm_len2); + dc->port[PORT_DIAG].dl_size[CH_A] = + dc->config_table.dl_diag_len1 - buff_offset; + dc->port[PORT_DIAG].dl_addr[CH_B] = + (offset += dc->config_table.dl_diag_len1); + dc->port[PORT_DIAG].dl_size[CH_B] = + dc->config_table.dl_diag_len2 - buff_offset; + + /* App1 port dl configuration */ + dc->port[PORT_APP1].dl_addr[CH_A] = + (offset += dc->config_table.dl_diag_len2); + dc->port[PORT_APP1].dl_size[CH_A] = + dc->config_table.dl_app1_len - buff_offset; + + /* App2 port dl configuration */ + dc->port[PORT_APP2].dl_addr[CH_A] = + (offset += dc->config_table.dl_app1_len); + dc->port[PORT_APP2].dl_size[CH_A] = + dc->config_table.dl_app2_len - buff_offset; + + /* Ctrl dl configuration */ + dc->port[PORT_CTRL].dl_addr[CH_A] = + (offset += dc->config_table.dl_app2_len); + dc->port[PORT_CTRL].dl_size[CH_A] = + dc->config_table.dl_ctrl_len - buff_offset; + + offset = dc->base_addr + dc->config_table.ul_start; + + /* Modem Port ul configuration */ + dc->port[PORT_MDM].ul_addr[CH_A] = offset; + dc->port[PORT_MDM].ul_size[CH_A] = + dc->config_table.ul_mdm_len1 - buff_offset; + dc->port[PORT_MDM].ul_addr[CH_B] = + (offset += dc->config_table.ul_mdm_len1); + dc->port[PORT_MDM].ul_size[CH_B] = + dc->config_table.ul_mdm_len2 - buff_offset; + + /* Diag port ul configuration */ + dc->port[PORT_DIAG].ul_addr[CH_A] = + (offset += dc->config_table.ul_mdm_len2); + dc->port[PORT_DIAG].ul_size[CH_A] = + dc->config_table.ul_diag_len - buff_offset; + + /* App1 port ul configuration */ + dc->port[PORT_APP1].ul_addr[CH_A] = + (offset += dc->config_table.ul_diag_len); + dc->port[PORT_APP1].ul_size[CH_A] = + dc->config_table.ul_app1_len - buff_offset; + + /* App2 port ul configuration */ + dc->port[PORT_APP2].ul_addr[CH_A] = + (offset += dc->config_table.ul_app1_len); + dc->port[PORT_APP2].ul_size[CH_A] = + dc->config_table.ul_app2_len - buff_offset; + + /* Ctrl ul configuration */ + dc->port[PORT_CTRL].ul_addr[CH_A] = + (offset += dc->config_table.ul_app2_len); + dc->port[PORT_CTRL].ul_size[CH_A] = + dc->config_table.ul_ctrl_len - buff_offset; +} + +/* Dump config table under initalization phase */ +#ifdef DEBUG +static void dump_table(const struct nozomi *dc) +{ + DBG3("signature: 0x%08X", dc->config_table.signature); + DBG3("version: 0x%04X", dc->config_table.version); + DBG3("product_information: 0x%04X", \ + dc->config_table.product_information); + DBG3("toggle enabled: %d", dc->config_table.toggle.enabled); + DBG3("toggle up_mdm: %d", dc->config_table.toggle.mdm_ul); + DBG3("toggle dl_mdm: %d", dc->config_table.toggle.mdm_dl); + DBG3("toggle dl_dbg: %d", dc->config_table.toggle.diag_dl); + + DBG3("dl_start: 0x%04X", dc->config_table.dl_start); + DBG3("dl_mdm_len0: 0x%04X, %d", dc->config_table.dl_mdm_len1, + dc->config_table.dl_mdm_len1); + DBG3("dl_mdm_len1: 0x%04X, %d", dc->config_table.dl_mdm_len2, + dc->config_table.dl_mdm_len2); + DBG3("dl_diag_len0: 0x%04X, %d", dc->config_table.dl_diag_len1, + dc->config_table.dl_diag_len1); + DBG3("dl_diag_len1: 0x%04X, %d", dc->config_table.dl_diag_len2, + dc->config_table.dl_diag_len2); + DBG3("dl_app1_len: 0x%04X, %d", dc->config_table.dl_app1_len, + dc->config_table.dl_app1_len); + DBG3("dl_app2_len: 0x%04X, %d", dc->config_table.dl_app2_len, + dc->config_table.dl_app2_len); + DBG3("dl_ctrl_len: 0x%04X, %d", dc->config_table.dl_ctrl_len, + dc->config_table.dl_ctrl_len); + DBG3("ul_start: 0x%04X, %d", dc->config_table.ul_start, + dc->config_table.ul_start); + DBG3("ul_mdm_len[0]: 0x%04X, %d", dc->config_table.ul_mdm_len1, + dc->config_table.ul_mdm_len1); + DBG3("ul_mdm_len[1]: 0x%04X, %d", dc->config_table.ul_mdm_len2, + dc->config_table.ul_mdm_len2); + DBG3("ul_diag_len: 0x%04X, %d", dc->config_table.ul_diag_len, + dc->config_table.ul_diag_len); + DBG3("ul_app1_len: 0x%04X, %d", dc->config_table.ul_app1_len, + dc->config_table.ul_app1_len); + DBG3("ul_app2_len: 0x%04X, %d", dc->config_table.ul_app2_len, + dc->config_table.ul_app2_len); + DBG3("ul_ctrl_len: 0x%04X, %d", dc->config_table.ul_ctrl_len, + dc->config_table.ul_ctrl_len); +} +#else +static inline void dump_table(const struct nozomi *dc) { } +#endif + +/* + * Read configuration table from card under intalization phase + * Returns 1 if ok, else 0 + */ +static int nozomi_read_config_table(struct nozomi *dc) +{ + read_mem32((u32 *) &dc->config_table, dc->base_addr + 0, + sizeof(struct config_table)); + + if (dc->config_table.signature != CONFIG_MAGIC) { + dev_err(&dc->pdev->dev, "ConfigTable Bad! 0x%08X != 0x%08X\n", + dc->config_table.signature, CONFIG_MAGIC); + return 0; + } + + if ((dc->config_table.version == 0) + || (dc->config_table.toggle.enabled == TOGGLE_VALID)) { + int i; + DBG1("Second phase, configuring card"); + + setup_memory(dc); + + dc->port[PORT_MDM].toggle_ul = dc->config_table.toggle.mdm_ul; + dc->port[PORT_MDM].toggle_dl = dc->config_table.toggle.mdm_dl; + dc->port[PORT_DIAG].toggle_dl = dc->config_table.toggle.diag_dl; + DBG1("toggle ports: MDM UL:%d MDM DL:%d, DIAG DL:%d", + dc->port[PORT_MDM].toggle_ul, + dc->port[PORT_MDM].toggle_dl, dc->port[PORT_DIAG].toggle_dl); + + dump_table(dc); + + for (i = PORT_MDM; i < MAX_PORT; i++) { + memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl)); + memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul)); + } + + /* Enable control channel */ + dc->last_ier = dc->last_ier | CTRL_DL; + writew(dc->last_ier, dc->reg_ier); + + dc->state = NOZOMI_STATE_ALLOCATED; + dev_info(&dc->pdev->dev, "Initialization OK!\n"); + return 1; + } + + if ((dc->config_table.version > 0) + && (dc->config_table.toggle.enabled != TOGGLE_VALID)) { + u32 offset = 0; + DBG1("First phase: pushing upload buffers, clearing download"); + + dev_info(&dc->pdev->dev, "Version of card: %d\n", + dc->config_table.version); + + /* Here we should disable all I/O over F32. */ + setup_memory(dc); + + /* + * We should send ALL channel pair tokens back along + * with reset token + */ + + /* push upload modem buffers */ + write_mem32(dc->port[PORT_MDM].ul_addr[CH_A], + (u32 *) &offset, 4); + write_mem32(dc->port[PORT_MDM].ul_addr[CH_B], + (u32 *) &offset, 4); + + writew(MDM_UL | DIAG_DL | MDM_DL, dc->reg_fcr); + + DBG1("First phase done"); + } + + return 1; +} + +/* Enable uplink interrupts */ +static void enable_transmit_ul(enum port_type port, struct nozomi *dc) +{ + static const u16 mask[] = {MDM_UL, DIAG_UL, APP1_UL, APP2_UL, CTRL_UL}; + + if (port < NOZOMI_MAX_PORTS) { + dc->last_ier |= mask[port]; + writew(dc->last_ier, dc->reg_ier); + } else { + dev_err(&dc->pdev->dev, "Called with wrong port?\n"); + } +} + +/* Disable uplink interrupts */ +static void disable_transmit_ul(enum port_type port, struct nozomi *dc) +{ + static const u16 mask[] = + {~MDM_UL, ~DIAG_UL, ~APP1_UL, ~APP2_UL, ~CTRL_UL}; + + if (port < NOZOMI_MAX_PORTS) { + dc->last_ier &= mask[port]; + writew(dc->last_ier, dc->reg_ier); + } else { + dev_err(&dc->pdev->dev, "Called with wrong port?\n"); + } +} + +/* Enable downlink interrupts */ +static void enable_transmit_dl(enum port_type port, struct nozomi *dc) +{ + static const u16 mask[] = {MDM_DL, DIAG_DL, APP1_DL, APP2_DL, CTRL_DL}; + + if (port < NOZOMI_MAX_PORTS) { + dc->last_ier |= mask[port]; + writew(dc->last_ier, dc->reg_ier); + } else { + dev_err(&dc->pdev->dev, "Called with wrong port?\n"); + } +} + +/* Disable downlink interrupts */ +static void disable_transmit_dl(enum port_type port, struct nozomi *dc) +{ + static const u16 mask[] = + {~MDM_DL, ~DIAG_DL, ~APP1_DL, ~APP2_DL, ~CTRL_DL}; + + if (port < NOZOMI_MAX_PORTS) { + dc->last_ier &= mask[port]; + writew(dc->last_ier, dc->reg_ier); + } else { + dev_err(&dc->pdev->dev, "Called with wrong port?\n"); + } +} + +/* + * Return 1 - send buffer to card and ack. + * Return 0 - don't ack, don't send buffer to card. + */ +static int send_data(enum port_type index, struct nozomi *dc) +{ + u32 size = 0; + struct port *port = &dc->port[index]; + const u8 toggle = port->toggle_ul; + void __iomem *addr = port->ul_addr[toggle]; + const u32 ul_size = port->ul_size[toggle]; + struct tty_struct *tty = tty_port_tty_get(&port->port); + + /* Get data from tty and place in buf for now */ + size = kfifo_out(&port->fifo_ul, dc->send_buf, + ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX); + + if (size == 0) { + DBG4("No more data to send, disable link:"); + tty_kref_put(tty); + return 0; + } + + /* DUMP(buf, size); */ + + /* Write length + data */ + write_mem32(addr, (u32 *) &size, 4); + write_mem32(addr + 4, (u32 *) dc->send_buf, size); + + if (tty) + tty_wakeup(tty); + + tty_kref_put(tty); + return 1; +} + +/* If all data has been read, return 1, else 0 */ +static int receive_data(enum port_type index, struct nozomi *dc) +{ + u8 buf[RECEIVE_BUF_MAX] = { 0 }; + int size; + u32 offset = 4; + struct port *port = &dc->port[index]; + void __iomem *addr = port->dl_addr[port->toggle_dl]; + struct tty_struct *tty = tty_port_tty_get(&port->port); + int i, ret; + + if (unlikely(!tty)) { + DBG1("tty not open for port: %d?", index); + return 1; + } + + read_mem32((u32 *) &size, addr, 4); + /* DBG1( "%d bytes port: %d", size, index); */ + + if (test_bit(TTY_THROTTLED, &tty->flags)) { + DBG1("No room in tty, don't read data, don't ack interrupt, " + "disable interrupt"); + + /* disable interrupt in downlink... */ + disable_transmit_dl(index, dc); + ret = 0; + goto put; + } + + if (unlikely(size == 0)) { + dev_err(&dc->pdev->dev, "size == 0?\n"); + ret = 1; + goto put; + } + + while (size > 0) { + read_mem32((u32 *) buf, addr + offset, RECEIVE_BUF_MAX); + + if (size == 1) { + tty_insert_flip_char(tty, buf[0], TTY_NORMAL); + size = 0; + } else if (size < RECEIVE_BUF_MAX) { + size -= tty_insert_flip_string(tty, (char *) buf, size); + } else { + i = tty_insert_flip_string(tty, \ + (char *) buf, RECEIVE_BUF_MAX); + size -= i; + offset += i; + } + } + + set_bit(index, &dc->flip); + ret = 1; +put: + tty_kref_put(tty); + return ret; +} + +/* Debug for interrupts */ +#ifdef DEBUG +static char *interrupt2str(u16 interrupt) +{ + static char buf[TMP_BUF_MAX]; + char *p = buf; + + interrupt & MDM_DL1 ? p += snprintf(p, TMP_BUF_MAX, "MDM_DL1 ") : NULL; + interrupt & MDM_DL2 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), + "MDM_DL2 ") : NULL; + + interrupt & MDM_UL1 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), + "MDM_UL1 ") : NULL; + interrupt & MDM_UL2 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), + "MDM_UL2 ") : NULL; + + interrupt & DIAG_DL1 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), + "DIAG_DL1 ") : NULL; + interrupt & DIAG_DL2 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), + "DIAG_DL2 ") : NULL; + + interrupt & DIAG_UL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), + "DIAG_UL ") : NULL; + + interrupt & APP1_DL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), + "APP1_DL ") : NULL; + interrupt & APP2_DL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), + "APP2_DL ") : NULL; + + interrupt & APP1_UL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), + "APP1_UL ") : NULL; + interrupt & APP2_UL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), + "APP2_UL ") : NULL; + + interrupt & CTRL_DL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), + "CTRL_DL ") : NULL; + interrupt & CTRL_UL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), + "CTRL_UL ") : NULL; + + interrupt & RESET ? p += snprintf(p, TMP_BUF_MAX - (p - buf), + "RESET ") : NULL; + + return buf; +} +#endif + +/* + * Receive flow control + * Return 1 - If ok, else 0 + */ +static int receive_flow_control(struct nozomi *dc) +{ + enum port_type port = PORT_MDM; + struct ctrl_dl ctrl_dl; + struct ctrl_dl old_ctrl; + u16 enable_ier = 0; + + read_mem32((u32 *) &ctrl_dl, dc->port[PORT_CTRL].dl_addr[CH_A], 2); + + switch (ctrl_dl.port) { + case CTRL_CMD: + DBG1("The Base Band sends this value as a response to a " + "request for IMSI detach sent over the control " + "channel uplink (see section 7.6.1)."); + break; + case CTRL_MDM: + port = PORT_MDM; + enable_ier = MDM_DL; + break; + case CTRL_DIAG: + port = PORT_DIAG; + enable_ier = DIAG_DL; + break; + case CTRL_APP1: + port = PORT_APP1; + enable_ier = APP1_DL; + break; + case CTRL_APP2: + port = PORT_APP2; + enable_ier = APP2_DL; + if (dc->state == NOZOMI_STATE_ALLOCATED) { + /* + * After card initialization the flow control + * received for APP2 is always the last + */ + dc->state = NOZOMI_STATE_READY; + dev_info(&dc->pdev->dev, "Device READY!\n"); + } + break; + default: + dev_err(&dc->pdev->dev, + "ERROR: flow control received for non-existing port\n"); + return 0; + }; + + DBG1("0x%04X->0x%04X", *((u16 *)&dc->port[port].ctrl_dl), + *((u16 *)&ctrl_dl)); + + old_ctrl = dc->port[port].ctrl_dl; + dc->port[port].ctrl_dl = ctrl_dl; + + if (old_ctrl.CTS == 1 && ctrl_dl.CTS == 0) { + DBG1("Disable interrupt (0x%04X) on port: %d", + enable_ier, port); + disable_transmit_ul(port, dc); + + } else if (old_ctrl.CTS == 0 && ctrl_dl.CTS == 1) { + + if (kfifo_len(&dc->port[port].fifo_ul)) { + DBG1("Enable interrupt (0x%04X) on port: %d", + enable_ier, port); + DBG1("Data in buffer [%d], enable transmit! ", + kfifo_len(&dc->port[port].fifo_ul)); + enable_transmit_ul(port, dc); + } else { + DBG1("No data in buffer..."); + } + } + + if (*(u16 *)&old_ctrl == *(u16 *)&ctrl_dl) { + DBG1(" No change in mctrl"); + return 1; + } + /* Update statistics */ + if (old_ctrl.CTS != ctrl_dl.CTS) + dc->port[port].tty_icount.cts++; + if (old_ctrl.DSR != ctrl_dl.DSR) + dc->port[port].tty_icount.dsr++; + if (old_ctrl.RI != ctrl_dl.RI) + dc->port[port].tty_icount.rng++; + if (old_ctrl.DCD != ctrl_dl.DCD) + dc->port[port].tty_icount.dcd++; + + wake_up_interruptible(&dc->port[port].tty_wait); + + DBG1("port: %d DCD(%d), CTS(%d), RI(%d), DSR(%d)", + port, + dc->port[port].tty_icount.dcd, dc->port[port].tty_icount.cts, + dc->port[port].tty_icount.rng, dc->port[port].tty_icount.dsr); + + return 1; +} + +static enum ctrl_port_type port2ctrl(enum port_type port, + const struct nozomi *dc) +{ + switch (port) { + case PORT_MDM: + return CTRL_MDM; + case PORT_DIAG: + return CTRL_DIAG; + case PORT_APP1: + return CTRL_APP1; + case PORT_APP2: + return CTRL_APP2; + default: + dev_err(&dc->pdev->dev, + "ERROR: send flow control " \ + "received for non-existing port\n"); + }; + return CTRL_ERROR; +} + +/* + * Send flow control, can only update one channel at a time + * Return 0 - If we have updated all flow control + * Return 1 - If we need to update more flow control, ack current enable more + */ +static int send_flow_control(struct nozomi *dc) +{ + u32 i, more_flow_control_to_be_updated = 0; + u16 *ctrl; + + for (i = PORT_MDM; i < MAX_PORT; i++) { + if (dc->port[i].update_flow_control) { + if (more_flow_control_to_be_updated) { + /* We have more flow control to be updated */ + return 1; + } + dc->port[i].ctrl_ul.port = port2ctrl(i, dc); + ctrl = (u16 *)&dc->port[i].ctrl_ul; + write_mem32(dc->port[PORT_CTRL].ul_addr[0], \ + (u32 *) ctrl, 2); + dc->port[i].update_flow_control = 0; + more_flow_control_to_be_updated = 1; + } + } + return 0; +} + +/* + * Handle downlink data, ports that are handled are modem and diagnostics + * Return 1 - ok + * Return 0 - toggle fields are out of sync + */ +static int handle_data_dl(struct nozomi *dc, enum port_type port, u8 *toggle, + u16 read_iir, u16 mask1, u16 mask2) +{ + if (*toggle == 0 && read_iir & mask1) { + if (receive_data(port, dc)) { + writew(mask1, dc->reg_fcr); + *toggle = !(*toggle); + } + + if (read_iir & mask2) { + if (receive_data(port, dc)) { + writew(mask2, dc->reg_fcr); + *toggle = !(*toggle); + } + } + } else if (*toggle == 1 && read_iir & mask2) { + if (receive_data(port, dc)) { + writew(mask2, dc->reg_fcr); + *toggle = !(*toggle); + } + + if (read_iir & mask1) { + if (receive_data(port, dc)) { + writew(mask1, dc->reg_fcr); + *toggle = !(*toggle); + } + } + } else { + dev_err(&dc->pdev->dev, "port out of sync!, toggle:%d\n", + *toggle); + return 0; + } + return 1; +} + +/* + * Handle uplink data, this is currently for the modem port + * Return 1 - ok + * Return 0 - toggle field are out of sync + */ +static int handle_data_ul(struct nozomi *dc, enum port_type port, u16 read_iir) +{ + u8 *toggle = &(dc->port[port].toggle_ul); + + if (*toggle == 0 && read_iir & MDM_UL1) { + dc->last_ier &= ~MDM_UL; + writew(dc->last_ier, dc->reg_ier); + if (send_data(port, dc)) { + writew(MDM_UL1, dc->reg_fcr); + dc->last_ier = dc->last_ier | MDM_UL; + writew(dc->last_ier, dc->reg_ier); + *toggle = !*toggle; + } + + if (read_iir & MDM_UL2) { + dc->last_ier &= ~MDM_UL; + writew(dc->last_ier, dc->reg_ier); + if (send_data(port, dc)) { + writew(MDM_UL2, dc->reg_fcr); + dc->last_ier = dc->last_ier | MDM_UL; + writew(dc->last_ier, dc->reg_ier); + *toggle = !*toggle; + } + } + + } else if (*toggle == 1 && read_iir & MDM_UL2) { + dc->last_ier &= ~MDM_UL; + writew(dc->last_ier, dc->reg_ier); + if (send_data(port, dc)) { + writew(MDM_UL2, dc->reg_fcr); + dc->last_ier = dc->last_ier | MDM_UL; + writew(dc->last_ier, dc->reg_ier); + *toggle = !*toggle; + } + + if (read_iir & MDM_UL1) { + dc->last_ier &= ~MDM_UL; + writew(dc->last_ier, dc->reg_ier); + if (send_data(port, dc)) { + writew(MDM_UL1, dc->reg_fcr); + dc->last_ier = dc->last_ier | MDM_UL; + writew(dc->last_ier, dc->reg_ier); + *toggle = !*toggle; + } + } + } else { + writew(read_iir & MDM_UL, dc->reg_fcr); + dev_err(&dc->pdev->dev, "port out of sync!\n"); + return 0; + } + return 1; +} + +static irqreturn_t interrupt_handler(int irq, void *dev_id) +{ + struct nozomi *dc = dev_id; + unsigned int a; + u16 read_iir; + + if (!dc) + return IRQ_NONE; + + spin_lock(&dc->spin_mutex); + read_iir = readw(dc->reg_iir); + + /* Card removed */ + if (read_iir == (u16)-1) + goto none; + /* + * Just handle interrupt enabled in IER + * (by masking with dc->last_ier) + */ + read_iir &= dc->last_ier; + + if (read_iir == 0) + goto none; + + + DBG4("%s irq:0x%04X, prev:0x%04X", interrupt2str(read_iir), read_iir, + dc->last_ier); + + if (read_iir & RESET) { + if (unlikely(!nozomi_read_config_table(dc))) { + dc->last_ier = 0x0; + writew(dc->last_ier, dc->reg_ier); + dev_err(&dc->pdev->dev, "Could not read status from " + "card, we should disable interface\n"); + } else { + writew(RESET, dc->reg_fcr); + } + /* No more useful info if this was the reset interrupt. */ + goto exit_handler; + } + if (read_iir & CTRL_UL) { + DBG1("CTRL_UL"); + dc->last_ier &= ~CTRL_UL; + writew(dc->last_ier, dc->reg_ier); + if (send_flow_control(dc)) { + writew(CTRL_UL, dc->reg_fcr); + dc->last_ier = dc->last_ier | CTRL_UL; + writew(dc->last_ier, dc->reg_ier); + } + } + if (read_iir & CTRL_DL) { + receive_flow_control(dc); + writew(CTRL_DL, dc->reg_fcr); + } + if (read_iir & MDM_DL) { + if (!handle_data_dl(dc, PORT_MDM, + &(dc->port[PORT_MDM].toggle_dl), read_iir, + MDM_DL1, MDM_DL2)) { + dev_err(&dc->pdev->dev, "MDM_DL out of sync!\n"); + goto exit_handler; + } + } + if (read_iir & MDM_UL) { + if (!handle_data_ul(dc, PORT_MDM, read_iir)) { + dev_err(&dc->pdev->dev, "MDM_UL out of sync!\n"); + goto exit_handler; + } + } + if (read_iir & DIAG_DL) { + if (!handle_data_dl(dc, PORT_DIAG, + &(dc->port[PORT_DIAG].toggle_dl), read_iir, + DIAG_DL1, DIAG_DL2)) { + dev_err(&dc->pdev->dev, "DIAG_DL out of sync!\n"); + goto exit_handler; + } + } + if (read_iir & DIAG_UL) { + dc->last_ier &= ~DIAG_UL; + writew(dc->last_ier, dc->reg_ier); + if (send_data(PORT_DIAG, dc)) { + writew(DIAG_UL, dc->reg_fcr); + dc->last_ier = dc->last_ier | DIAG_UL; + writew(dc->last_ier, dc->reg_ier); + } + } + if (read_iir & APP1_DL) { + if (receive_data(PORT_APP1, dc)) + writew(APP1_DL, dc->reg_fcr); + } + if (read_iir & APP1_UL) { + dc->last_ier &= ~APP1_UL; + writew(dc->last_ier, dc->reg_ier); + if (send_data(PORT_APP1, dc)) { + writew(APP1_UL, dc->reg_fcr); + dc->last_ier = dc->last_ier | APP1_UL; + writew(dc->last_ier, dc->reg_ier); + } + } + if (read_iir & APP2_DL) { + if (receive_data(PORT_APP2, dc)) + writew(APP2_DL, dc->reg_fcr); + } + if (read_iir & APP2_UL) { + dc->last_ier &= ~APP2_UL; + writew(dc->last_ier, dc->reg_ier); + if (send_data(PORT_APP2, dc)) { + writew(APP2_UL, dc->reg_fcr); + dc->last_ier = dc->last_ier | APP2_UL; + writew(dc->last_ier, dc->reg_ier); + } + } + +exit_handler: + spin_unlock(&dc->spin_mutex); + for (a = 0; a < NOZOMI_MAX_PORTS; a++) { + struct tty_struct *tty; + if (test_and_clear_bit(a, &dc->flip)) { + tty = tty_port_tty_get(&dc->port[a].port); + if (tty) + tty_flip_buffer_push(tty); + tty_kref_put(tty); + } + } + return IRQ_HANDLED; +none: + spin_unlock(&dc->spin_mutex); + return IRQ_NONE; +} + +static void nozomi_get_card_type(struct nozomi *dc) +{ + int i; + u32 size = 0; + + for (i = 0; i < 6; i++) + size += pci_resource_len(dc->pdev, i); + + /* Assume card type F32_8 if no match */ + dc->card_type = size == 2048 ? F32_2 : F32_8; + + dev_info(&dc->pdev->dev, "Card type is: %d\n", dc->card_type); +} + +static void nozomi_setup_private_data(struct nozomi *dc) +{ + void __iomem *offset = dc->base_addr + dc->card_type / 2; + unsigned int i; + + dc->reg_fcr = (void __iomem *)(offset + R_FCR); + dc->reg_iir = (void __iomem *)(offset + R_IIR); + dc->reg_ier = (void __iomem *)(offset + R_IER); + dc->last_ier = 0; + dc->flip = 0; + + dc->port[PORT_MDM].token_dl = MDM_DL; + dc->port[PORT_DIAG].token_dl = DIAG_DL; + dc->port[PORT_APP1].token_dl = APP1_DL; + dc->port[PORT_APP2].token_dl = APP2_DL; + + for (i = 0; i < MAX_PORT; i++) + init_waitqueue_head(&dc->port[i].tty_wait); +} + +static ssize_t card_type_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + const struct nozomi *dc = pci_get_drvdata(to_pci_dev(dev)); + + return sprintf(buf, "%d\n", dc->card_type); +} +static DEVICE_ATTR(card_type, S_IRUGO, card_type_show, NULL); + +static ssize_t open_ttys_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + const struct nozomi *dc = pci_get_drvdata(to_pci_dev(dev)); + + return sprintf(buf, "%u\n", dc->open_ttys); +} +static DEVICE_ATTR(open_ttys, S_IRUGO, open_ttys_show, NULL); + +static void make_sysfs_files(struct nozomi *dc) +{ + if (device_create_file(&dc->pdev->dev, &dev_attr_card_type)) + dev_err(&dc->pdev->dev, + "Could not create sysfs file for card_type\n"); + if (device_create_file(&dc->pdev->dev, &dev_attr_open_ttys)) + dev_err(&dc->pdev->dev, + "Could not create sysfs file for open_ttys\n"); +} + +static void remove_sysfs_files(struct nozomi *dc) +{ + device_remove_file(&dc->pdev->dev, &dev_attr_card_type); + device_remove_file(&dc->pdev->dev, &dev_attr_open_ttys); +} + +/* Allocate memory for one device */ +static int __devinit nozomi_card_init(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + resource_size_t start; + int ret; + struct nozomi *dc = NULL; + int ndev_idx; + int i; + + dev_dbg(&pdev->dev, "Init, new card found\n"); + + for (ndev_idx = 0; ndev_idx < ARRAY_SIZE(ndevs); ndev_idx++) + if (!ndevs[ndev_idx]) + break; + + if (ndev_idx >= ARRAY_SIZE(ndevs)) { + dev_err(&pdev->dev, "no free tty range for this card left\n"); + ret = -EIO; + goto err; + } + + dc = kzalloc(sizeof(struct nozomi), GFP_KERNEL); + if (unlikely(!dc)) { + dev_err(&pdev->dev, "Could not allocate memory\n"); + ret = -ENOMEM; + goto err_free; + } + + dc->pdev = pdev; + + ret = pci_enable_device(dc->pdev); + if (ret) { + dev_err(&pdev->dev, "Failed to enable PCI Device\n"); + goto err_free; + } + + ret = pci_request_regions(dc->pdev, NOZOMI_NAME); + if (ret) { + dev_err(&pdev->dev, "I/O address 0x%04x already in use\n", + (int) /* nozomi_private.io_addr */ 0); + goto err_disable_device; + } + + start = pci_resource_start(dc->pdev, 0); + if (start == 0) { + dev_err(&pdev->dev, "No I/O address for card detected\n"); + ret = -ENODEV; + goto err_rel_regs; + } + + /* Find out what card type it is */ + nozomi_get_card_type(dc); + + dc->base_addr = ioremap_nocache(start, dc->card_type); + if (!dc->base_addr) { + dev_err(&pdev->dev, "Unable to map card MMIO\n"); + ret = -ENODEV; + goto err_rel_regs; + } + + dc->send_buf = kmalloc(SEND_BUF_MAX, GFP_KERNEL); + if (!dc->send_buf) { + dev_err(&pdev->dev, "Could not allocate send buffer?\n"); + ret = -ENOMEM; + goto err_free_sbuf; + } + + for (i = PORT_MDM; i < MAX_PORT; i++) { + if (kfifo_alloc(&dc->port[i].fifo_ul, + FIFO_BUFFER_SIZE_UL, GFP_ATOMIC)) { + dev_err(&pdev->dev, + "Could not allocate kfifo buffer\n"); + ret = -ENOMEM; + goto err_free_kfifo; + } + } + + spin_lock_init(&dc->spin_mutex); + + nozomi_setup_private_data(dc); + + /* Disable all interrupts */ + dc->last_ier = 0; + writew(dc->last_ier, dc->reg_ier); + + ret = request_irq(pdev->irq, &interrupt_handler, IRQF_SHARED, + NOZOMI_NAME, dc); + if (unlikely(ret)) { + dev_err(&pdev->dev, "can't request irq %d\n", pdev->irq); + goto err_free_kfifo; + } + + DBG1("base_addr: %p", dc->base_addr); + + make_sysfs_files(dc); + + dc->index_start = ndev_idx * MAX_PORT; + ndevs[ndev_idx] = dc; + + pci_set_drvdata(pdev, dc); + + /* Enable RESET interrupt */ + dc->last_ier = RESET; + iowrite16(dc->last_ier, dc->reg_ier); + + dc->state = NOZOMI_STATE_ENABLED; + + for (i = 0; i < MAX_PORT; i++) { + struct device *tty_dev; + struct port *port = &dc->port[i]; + port->dc = dc; + mutex_init(&port->tty_sem); + tty_port_init(&port->port); + port->port.ops = &noz_tty_port_ops; + tty_dev = tty_register_device(ntty_driver, dc->index_start + i, + &pdev->dev); + + if (IS_ERR(tty_dev)) { + ret = PTR_ERR(tty_dev); + dev_err(&pdev->dev, "Could not allocate tty?\n"); + goto err_free_tty; + } + } + + return 0; + +err_free_tty: + for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i) + tty_unregister_device(ntty_driver, i); +err_free_kfifo: + for (i = 0; i < MAX_PORT; i++) + kfifo_free(&dc->port[i].fifo_ul); +err_free_sbuf: + kfree(dc->send_buf); + iounmap(dc->base_addr); +err_rel_regs: + pci_release_regions(pdev); +err_disable_device: + pci_disable_device(pdev); +err_free: + kfree(dc); +err: + return ret; +} + +static void __devexit tty_exit(struct nozomi *dc) +{ + unsigned int i; + + DBG1(" "); + + flush_scheduled_work(); + + for (i = 0; i < MAX_PORT; ++i) { + struct tty_struct *tty = tty_port_tty_get(&dc->port[i].port); + if (tty && list_empty(&tty->hangup_work.entry)) + tty_hangup(tty); + tty_kref_put(tty); + } + /* Racy below - surely should wait for scheduled work to be done or + complete off a hangup method ? */ + while (dc->open_ttys) + msleep(1); + for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i) + tty_unregister_device(ntty_driver, i); +} + +/* Deallocate memory for one device */ +static void __devexit nozomi_card_exit(struct pci_dev *pdev) +{ + int i; + struct ctrl_ul ctrl; + struct nozomi *dc = pci_get_drvdata(pdev); + + /* Disable all interrupts */ + dc->last_ier = 0; + writew(dc->last_ier, dc->reg_ier); + + tty_exit(dc); + + /* Send 0x0001, command card to resend the reset token. */ + /* This is to get the reset when the module is reloaded. */ + ctrl.port = 0x00; + ctrl.reserved = 0; + ctrl.RTS = 0; + ctrl.DTR = 1; + DBG1("sending flow control 0x%04X", *((u16 *)&ctrl)); + + /* Setup dc->reg addresses to we can use defines here */ + write_mem32(dc->port[PORT_CTRL].ul_addr[0], (u32 *)&ctrl, 2); + writew(CTRL_UL, dc->reg_fcr); /* push the token to the card. */ + + remove_sysfs_files(dc); + + free_irq(pdev->irq, dc); + + for (i = 0; i < MAX_PORT; i++) + kfifo_free(&dc->port[i].fifo_ul); + + kfree(dc->send_buf); + + iounmap(dc->base_addr); + + pci_release_regions(pdev); + + pci_disable_device(pdev); + + ndevs[dc->index_start / MAX_PORT] = NULL; + + kfree(dc); +} + +static void set_rts(const struct tty_struct *tty, int rts) +{ + struct port *port = get_port_by_tty(tty); + + port->ctrl_ul.RTS = rts; + port->update_flow_control = 1; + enable_transmit_ul(PORT_CTRL, get_dc_by_tty(tty)); +} + +static void set_dtr(const struct tty_struct *tty, int dtr) +{ + struct port *port = get_port_by_tty(tty); + + DBG1("SETTING DTR index: %d, dtr: %d", tty->index, dtr); + + port->ctrl_ul.DTR = dtr; + port->update_flow_control = 1; + enable_transmit_ul(PORT_CTRL, get_dc_by_tty(tty)); +} + +/* + * ---------------------------------------------------------------------------- + * TTY code + * ---------------------------------------------------------------------------- + */ + +static int ntty_install(struct tty_driver *driver, struct tty_struct *tty) +{ + struct port *port = get_port_by_tty(tty); + struct nozomi *dc = get_dc_by_tty(tty); + int ret; + if (!port || !dc || dc->state != NOZOMI_STATE_READY) + return -ENODEV; + ret = tty_init_termios(tty); + if (ret == 0) { + tty_driver_kref_get(driver); + tty->count++; + tty->driver_data = port; + driver->ttys[tty->index] = tty; + } + return ret; +} + +static void ntty_cleanup(struct tty_struct *tty) +{ + tty->driver_data = NULL; +} + +static int ntty_activate(struct tty_port *tport, struct tty_struct *tty) +{ + struct port *port = container_of(tport, struct port, port); + struct nozomi *dc = port->dc; + unsigned long flags; + + DBG1("open: %d", port->token_dl); + spin_lock_irqsave(&dc->spin_mutex, flags); + dc->last_ier = dc->last_ier | port->token_dl; + writew(dc->last_ier, dc->reg_ier); + dc->open_ttys++; + spin_unlock_irqrestore(&dc->spin_mutex, flags); + printk("noz: activated %d: %p\n", tty->index, tport); + return 0; +} + +static int ntty_open(struct tty_struct *tty, struct file *filp) +{ + struct port *port = tty->driver_data; + return tty_port_open(&port->port, tty, filp); +} + +static void ntty_shutdown(struct tty_port *tport) +{ + struct port *port = container_of(tport, struct port, port); + struct nozomi *dc = port->dc; + unsigned long flags; + + DBG1("close: %d", port->token_dl); + spin_lock_irqsave(&dc->spin_mutex, flags); + dc->last_ier &= ~(port->token_dl); + writew(dc->last_ier, dc->reg_ier); + dc->open_ttys--; + spin_unlock_irqrestore(&dc->spin_mutex, flags); + printk("noz: shutdown %p\n", tport); +} + +static void ntty_close(struct tty_struct *tty, struct file *filp) +{ + struct port *port = tty->driver_data; + if (port) + tty_port_close(&port->port, tty, filp); +} + +static void ntty_hangup(struct tty_struct *tty) +{ + struct port *port = tty->driver_data; + tty_port_hangup(&port->port); +} + +/* + * called when the userspace process writes to the tty (/dev/noz*). + * Data is inserted into a fifo, which is then read and transfered to the modem. + */ +static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, + int count) +{ + int rval = -EINVAL; + struct nozomi *dc = get_dc_by_tty(tty); + struct port *port = tty->driver_data; + unsigned long flags; + + /* DBG1( "WRITEx: %d, index = %d", count, index); */ + + if (!dc || !port) + return -ENODEV; + + mutex_lock(&port->tty_sem); + + if (unlikely(!port->port.count)) { + DBG1(" "); + goto exit; + } + + rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count); + + /* notify card */ + if (unlikely(dc == NULL)) { + DBG1("No device context?"); + goto exit; + } + + spin_lock_irqsave(&dc->spin_mutex, flags); + /* CTS is only valid on the modem channel */ + if (port == &(dc->port[PORT_MDM])) { + if (port->ctrl_dl.CTS) { + DBG4("Enable interrupt"); + enable_transmit_ul(tty->index % MAX_PORT, dc); + } else { + dev_err(&dc->pdev->dev, + "CTS not active on modem port?\n"); + } + } else { + enable_transmit_ul(tty->index % MAX_PORT, dc); + } + spin_unlock_irqrestore(&dc->spin_mutex, flags); + +exit: + mutex_unlock(&port->tty_sem); + return rval; +} + +/* + * Calculate how much is left in device + * This method is called by the upper tty layer. + * #according to sources N_TTY.c it expects a value >= 0 and + * does not check for negative values. + * + * If the port is unplugged report lots of room and let the bits + * dribble away so we don't block anything. + */ +static int ntty_write_room(struct tty_struct *tty) +{ + struct port *port = tty->driver_data; + int room = 4096; + const struct nozomi *dc = get_dc_by_tty(tty); + + if (dc) { + mutex_lock(&port->tty_sem); + if (port->port.count) + room = kfifo_avail(&port->fifo_ul); + mutex_unlock(&port->tty_sem); + } + return room; +} + +/* Gets io control parameters */ +static int ntty_tiocmget(struct tty_struct *tty) +{ + const struct port *port = tty->driver_data; + const struct ctrl_dl *ctrl_dl = &port->ctrl_dl; + const struct ctrl_ul *ctrl_ul = &port->ctrl_ul; + + /* Note: these could change under us but it is not clear this + matters if so */ + return (ctrl_ul->RTS ? TIOCM_RTS : 0) | + (ctrl_ul->DTR ? TIOCM_DTR : 0) | + (ctrl_dl->DCD ? TIOCM_CAR : 0) | + (ctrl_dl->RI ? TIOCM_RNG : 0) | + (ctrl_dl->DSR ? TIOCM_DSR : 0) | + (ctrl_dl->CTS ? TIOCM_CTS : 0); +} + +/* Sets io controls parameters */ +static int ntty_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + struct nozomi *dc = get_dc_by_tty(tty); + unsigned long flags; + + spin_lock_irqsave(&dc->spin_mutex, flags); + if (set & TIOCM_RTS) + set_rts(tty, 1); + else if (clear & TIOCM_RTS) + set_rts(tty, 0); + + if (set & TIOCM_DTR) + set_dtr(tty, 1); + else if (clear & TIOCM_DTR) + set_dtr(tty, 0); + spin_unlock_irqrestore(&dc->spin_mutex, flags); + + return 0; +} + +static int ntty_cflags_changed(struct port *port, unsigned long flags, + struct async_icount *cprev) +{ + const struct async_icount cnow = port->tty_icount; + int ret; + + ret = ((flags & TIOCM_RNG) && (cnow.rng != cprev->rng)) || + ((flags & TIOCM_DSR) && (cnow.dsr != cprev->dsr)) || + ((flags & TIOCM_CD) && (cnow.dcd != cprev->dcd)) || + ((flags & TIOCM_CTS) && (cnow.cts != cprev->cts)); + + *cprev = cnow; + + return ret; +} + +static int ntty_tiocgicount(struct tty_struct *tty, + struct serial_icounter_struct *icount) +{ + struct port *port = tty->driver_data; + const struct async_icount cnow = port->tty_icount; + + icount->cts = cnow.cts; + icount->dsr = cnow.dsr; + icount->rng = cnow.rng; + icount->dcd = cnow.dcd; + icount->rx = cnow.rx; + icount->tx = cnow.tx; + icount->frame = cnow.frame; + icount->overrun = cnow.overrun; + icount->parity = cnow.parity; + icount->brk = cnow.brk; + icount->buf_overrun = cnow.buf_overrun; + return 0; +} + +static int ntty_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + struct port *port = tty->driver_data; + int rval = -ENOIOCTLCMD; + + DBG1("******** IOCTL, cmd: %d", cmd); + + switch (cmd) { + case TIOCMIWAIT: { + struct async_icount cprev = port->tty_icount; + + rval = wait_event_interruptible(port->tty_wait, + ntty_cflags_changed(port, arg, &cprev)); + break; + } + default: + DBG1("ERR: 0x%08X, %d", cmd, cmd); + break; + }; + + return rval; +} + +/* + * Called by the upper tty layer when tty buffers are ready + * to receive data again after a call to throttle. + */ +static void ntty_unthrottle(struct tty_struct *tty) +{ + struct nozomi *dc = get_dc_by_tty(tty); + unsigned long flags; + + DBG1("UNTHROTTLE"); + spin_lock_irqsave(&dc->spin_mutex, flags); + enable_transmit_dl(tty->index % MAX_PORT, dc); + set_rts(tty, 1); + + spin_unlock_irqrestore(&dc->spin_mutex, flags); +} + +/* + * Called by the upper tty layer when the tty buffers are almost full. + * The driver should stop send more data. + */ +static void ntty_throttle(struct tty_struct *tty) +{ + struct nozomi *dc = get_dc_by_tty(tty); + unsigned long flags; + + DBG1("THROTTLE"); + spin_lock_irqsave(&dc->spin_mutex, flags); + set_rts(tty, 0); + spin_unlock_irqrestore(&dc->spin_mutex, flags); +} + +/* Returns number of chars in buffer, called by tty layer */ +static s32 ntty_chars_in_buffer(struct tty_struct *tty) +{ + struct port *port = tty->driver_data; + struct nozomi *dc = get_dc_by_tty(tty); + s32 rval = 0; + + if (unlikely(!dc || !port)) { + goto exit_in_buffer; + } + + if (unlikely(!port->port.count)) { + dev_err(&dc->pdev->dev, "No tty open?\n"); + goto exit_in_buffer; + } + + rval = kfifo_len(&port->fifo_ul); + +exit_in_buffer: + return rval; +} + +static const struct tty_port_operations noz_tty_port_ops = { + .activate = ntty_activate, + .shutdown = ntty_shutdown, +}; + +static const struct tty_operations tty_ops = { + .ioctl = ntty_ioctl, + .open = ntty_open, + .close = ntty_close, + .hangup = ntty_hangup, + .write = ntty_write, + .write_room = ntty_write_room, + .unthrottle = ntty_unthrottle, + .throttle = ntty_throttle, + .chars_in_buffer = ntty_chars_in_buffer, + .tiocmget = ntty_tiocmget, + .tiocmset = ntty_tiocmset, + .get_icount = ntty_tiocgicount, + .install = ntty_install, + .cleanup = ntty_cleanup, +}; + +/* Module initialization */ +static struct pci_driver nozomi_driver = { + .name = NOZOMI_NAME, + .id_table = nozomi_pci_tbl, + .probe = nozomi_card_init, + .remove = __devexit_p(nozomi_card_exit), +}; + +static __init int nozomi_init(void) +{ + int ret; + + printk(KERN_INFO "Initializing %s\n", VERSION_STRING); + + ntty_driver = alloc_tty_driver(NTTY_TTY_MAXMINORS); + if (!ntty_driver) + return -ENOMEM; + + ntty_driver->owner = THIS_MODULE; + ntty_driver->driver_name = NOZOMI_NAME_TTY; + ntty_driver->name = "noz"; + ntty_driver->major = 0; + ntty_driver->type = TTY_DRIVER_TYPE_SERIAL; + ntty_driver->subtype = SERIAL_TYPE_NORMAL; + ntty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + ntty_driver->init_termios = tty_std_termios; + ntty_driver->init_termios.c_cflag = B115200 | CS8 | CREAD | \ + HUPCL | CLOCAL; + ntty_driver->init_termios.c_ispeed = 115200; + ntty_driver->init_termios.c_ospeed = 115200; + tty_set_operations(ntty_driver, &tty_ops); + + ret = tty_register_driver(ntty_driver); + if (ret) { + printk(KERN_ERR "Nozomi: failed to register ntty driver\n"); + goto free_tty; + } + + ret = pci_register_driver(&nozomi_driver); + if (ret) { + printk(KERN_ERR "Nozomi: can't register pci driver\n"); + goto unr_tty; + } + + return 0; +unr_tty: + tty_unregister_driver(ntty_driver); +free_tty: + put_tty_driver(ntty_driver); + return ret; +} + +static __exit void nozomi_exit(void) +{ + printk(KERN_INFO "Unloading %s\n", DRIVER_DESC); + pci_unregister_driver(&nozomi_driver); + tty_unregister_driver(ntty_driver); + put_tty_driver(ntty_driver); +} + +module_init(nozomi_init); +module_exit(nozomi_exit); + +module_param(debug, int, S_IRUGO | S_IWUSR); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c new file mode 100644 index 000000000000..3780da8ad12d --- /dev/null +++ b/drivers/tty/rocket.c @@ -0,0 +1,3199 @@ +/* + * RocketPort device driver for Linux + * + * Written by Theodore Ts'o, 1995, 1996, 1997, 1998, 1999, 2000. + * + * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2003 by Comtrol, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Kernel Synchronization: + * + * This driver has 2 kernel control paths - exception handlers (calls into the driver + * from user mode) and the timer bottom half (tasklet). This is a polled driver, interrupts + * are not used. + * + * Critical data: + * - rp_table[], accessed through passed "info" pointers, is a global (static) array of + * serial port state information and the xmit_buf circular buffer. Protected by + * a per port spinlock. + * - xmit_flags[], an array of ints indexed by line (port) number, indicating that there + * is data to be transmitted. Protected by atomic bit operations. + * - rp_num_ports, int indicating number of open ports, protected by atomic operations. + * + * rp_write() and rp_write_char() functions use a per port semaphore to protect against + * simultaneous access to the same port by more than one process. + */ + +/****** Defines ******/ +#define ROCKET_PARANOIA_CHECK +#define ROCKET_DISABLE_SIMUSAGE + +#undef ROCKET_SOFT_FLOW +#undef ROCKET_DEBUG_OPEN +#undef ROCKET_DEBUG_INTR +#undef ROCKET_DEBUG_WRITE +#undef ROCKET_DEBUG_FLOW +#undef ROCKET_DEBUG_THROTTLE +#undef ROCKET_DEBUG_WAIT_UNTIL_SENT +#undef ROCKET_DEBUG_RECEIVE +#undef ROCKET_DEBUG_HANGUP +#undef REV_PCI_ORDER +#undef ROCKET_DEBUG_IO + +#define POLL_PERIOD HZ/100 /* Polling period .01 seconds (10ms) */ + +/****** Kernel includes ******/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/****** RocketPort includes ******/ + +#include "rocket_int.h" +#include "rocket.h" + +#define ROCKET_VERSION "2.09" +#define ROCKET_DATE "12-June-2003" + +/****** RocketPort Local Variables ******/ + +static void rp_do_poll(unsigned long dummy); + +static struct tty_driver *rocket_driver; + +static struct rocket_version driver_version = { + ROCKET_VERSION, ROCKET_DATE +}; + +static struct r_port *rp_table[MAX_RP_PORTS]; /* The main repository of serial port state information. */ +static unsigned int xmit_flags[NUM_BOARDS]; /* Bit significant, indicates port had data to transmit. */ + /* eg. Bit 0 indicates port 0 has xmit data, ... */ +static atomic_t rp_num_ports_open; /* Number of serial ports open */ +static DEFINE_TIMER(rocket_timer, rp_do_poll, 0, 0); + +static unsigned long board1; /* ISA addresses, retrieved from rocketport.conf */ +static unsigned long board2; +static unsigned long board3; +static unsigned long board4; +static unsigned long controller; +static int support_low_speed; +static unsigned long modem1; +static unsigned long modem2; +static unsigned long modem3; +static unsigned long modem4; +static unsigned long pc104_1[8]; +static unsigned long pc104_2[8]; +static unsigned long pc104_3[8]; +static unsigned long pc104_4[8]; +static unsigned long *pc104[4] = { pc104_1, pc104_2, pc104_3, pc104_4 }; + +static int rp_baud_base[NUM_BOARDS]; /* Board config info (Someday make a per-board structure) */ +static unsigned long rcktpt_io_addr[NUM_BOARDS]; +static int rcktpt_type[NUM_BOARDS]; +static int is_PCI[NUM_BOARDS]; +static rocketModel_t rocketModel[NUM_BOARDS]; +static int max_board; +static const struct tty_port_operations rocket_port_ops; + +/* + * The following arrays define the interrupt bits corresponding to each AIOP. + * These bits are different between the ISA and regular PCI boards and the + * Universal PCI boards. + */ + +static Word_t aiop_intr_bits[AIOP_CTL_SIZE] = { + AIOP_INTR_BIT_0, + AIOP_INTR_BIT_1, + AIOP_INTR_BIT_2, + AIOP_INTR_BIT_3 +}; + +static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = { + UPCI_AIOP_INTR_BIT_0, + UPCI_AIOP_INTR_BIT_1, + UPCI_AIOP_INTR_BIT_2, + UPCI_AIOP_INTR_BIT_3 +}; + +static Byte_t RData[RDATASIZE] = { + 0x00, 0x09, 0xf6, 0x82, + 0x02, 0x09, 0x86, 0xfb, + 0x04, 0x09, 0x00, 0x0a, + 0x06, 0x09, 0x01, 0x0a, + 0x08, 0x09, 0x8a, 0x13, + 0x0a, 0x09, 0xc5, 0x11, + 0x0c, 0x09, 0x86, 0x85, + 0x0e, 0x09, 0x20, 0x0a, + 0x10, 0x09, 0x21, 0x0a, + 0x12, 0x09, 0x41, 0xff, + 0x14, 0x09, 0x82, 0x00, + 0x16, 0x09, 0x82, 0x7b, + 0x18, 0x09, 0x8a, 0x7d, + 0x1a, 0x09, 0x88, 0x81, + 0x1c, 0x09, 0x86, 0x7a, + 0x1e, 0x09, 0x84, 0x81, + 0x20, 0x09, 0x82, 0x7c, + 0x22, 0x09, 0x0a, 0x0a +}; + +static Byte_t RRegData[RREGDATASIZE] = { + 0x00, 0x09, 0xf6, 0x82, /* 00: Stop Rx processor */ + 0x08, 0x09, 0x8a, 0x13, /* 04: Tx software flow control */ + 0x0a, 0x09, 0xc5, 0x11, /* 08: XON char */ + 0x0c, 0x09, 0x86, 0x85, /* 0c: XANY */ + 0x12, 0x09, 0x41, 0xff, /* 10: Rx mask char */ + 0x14, 0x09, 0x82, 0x00, /* 14: Compare/Ignore #0 */ + 0x16, 0x09, 0x82, 0x7b, /* 18: Compare #1 */ + 0x18, 0x09, 0x8a, 0x7d, /* 1c: Compare #2 */ + 0x1a, 0x09, 0x88, 0x81, /* 20: Interrupt #1 */ + 0x1c, 0x09, 0x86, 0x7a, /* 24: Ignore/Replace #1 */ + 0x1e, 0x09, 0x84, 0x81, /* 28: Interrupt #2 */ + 0x20, 0x09, 0x82, 0x7c, /* 2c: Ignore/Replace #2 */ + 0x22, 0x09, 0x0a, 0x0a /* 30: Rx FIFO Enable */ +}; + +static CONTROLLER_T sController[CTL_SIZE] = { + {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, + {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}, + {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, + {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}, + {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, + {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}, + {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, + {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}} +}; + +static Byte_t sBitMapClrTbl[8] = { + 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f +}; + +static Byte_t sBitMapSetTbl[8] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 +}; + +static int sClockPrescale = 0x14; + +/* + * Line number is the ttySIx number (x), the Minor number. We + * assign them sequentially, starting at zero. The following + * array keeps track of the line number assigned to a given board/aiop/channel. + */ +static unsigned char lineNumbers[MAX_RP_PORTS]; +static unsigned long nextLineNumber; + +/***** RocketPort Static Prototypes *********/ +static int __init init_ISA(int i); +static void rp_wait_until_sent(struct tty_struct *tty, int timeout); +static void rp_flush_buffer(struct tty_struct *tty); +static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model); +static unsigned char GetLineNumber(int ctrl, int aiop, int ch); +static unsigned char SetLineNumber(int ctrl, int aiop, int ch); +static void rp_start(struct tty_struct *tty); +static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum, + int ChanNum); +static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode); +static void sFlushRxFIFO(CHANNEL_T * ChP); +static void sFlushTxFIFO(CHANNEL_T * ChP); +static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags); +static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags); +static void sModemReset(CONTROLLER_T * CtlP, int chan, int on); +static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on); +static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data); +static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, + ByteIO_t * AiopIOList, int AiopIOListSize, + WordIO_t ConfigIO, int IRQNum, Byte_t Frequency, + int PeriodicOnly, int altChanRingIndicator, + int UPCIRingInd); +static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, + ByteIO_t * AiopIOList, int AiopIOListSize, + int IRQNum, Byte_t Frequency, int PeriodicOnly); +static int sReadAiopID(ByteIO_t io); +static int sReadAiopNumChan(WordIO_t io); + +MODULE_AUTHOR("Theodore Ts'o"); +MODULE_DESCRIPTION("Comtrol RocketPort driver"); +module_param(board1, ulong, 0); +MODULE_PARM_DESC(board1, "I/O port for (ISA) board #1"); +module_param(board2, ulong, 0); +MODULE_PARM_DESC(board2, "I/O port for (ISA) board #2"); +module_param(board3, ulong, 0); +MODULE_PARM_DESC(board3, "I/O port for (ISA) board #3"); +module_param(board4, ulong, 0); +MODULE_PARM_DESC(board4, "I/O port for (ISA) board #4"); +module_param(controller, ulong, 0); +MODULE_PARM_DESC(controller, "I/O port for (ISA) rocketport controller"); +module_param(support_low_speed, bool, 0); +MODULE_PARM_DESC(support_low_speed, "1 means support 50 baud, 0 means support 460400 baud"); +module_param(modem1, ulong, 0); +MODULE_PARM_DESC(modem1, "1 means (ISA) board #1 is a RocketModem"); +module_param(modem2, ulong, 0); +MODULE_PARM_DESC(modem2, "1 means (ISA) board #2 is a RocketModem"); +module_param(modem3, ulong, 0); +MODULE_PARM_DESC(modem3, "1 means (ISA) board #3 is a RocketModem"); +module_param(modem4, ulong, 0); +MODULE_PARM_DESC(modem4, "1 means (ISA) board #4 is a RocketModem"); +module_param_array(pc104_1, ulong, NULL, 0); +MODULE_PARM_DESC(pc104_1, "set interface types for ISA(PC104) board #1 (e.g. pc104_1=232,232,485,485,..."); +module_param_array(pc104_2, ulong, NULL, 0); +MODULE_PARM_DESC(pc104_2, "set interface types for ISA(PC104) board #2 (e.g. pc104_2=232,232,485,485,..."); +module_param_array(pc104_3, ulong, NULL, 0); +MODULE_PARM_DESC(pc104_3, "set interface types for ISA(PC104) board #3 (e.g. pc104_3=232,232,485,485,..."); +module_param_array(pc104_4, ulong, NULL, 0); +MODULE_PARM_DESC(pc104_4, "set interface types for ISA(PC104) board #4 (e.g. pc104_4=232,232,485,485,..."); + +static int rp_init(void); +static void rp_cleanup_module(void); + +module_init(rp_init); +module_exit(rp_cleanup_module); + + +MODULE_LICENSE("Dual BSD/GPL"); + +/*************************************************************************/ +/* Module code starts here */ + +static inline int rocket_paranoia_check(struct r_port *info, + const char *routine) +{ +#ifdef ROCKET_PARANOIA_CHECK + if (!info) + return 1; + if (info->magic != RPORT_MAGIC) { + printk(KERN_WARNING "Warning: bad magic number for rocketport " + "struct in %s\n", routine); + return 1; + } +#endif + return 0; +} + + +/* Serial port receive data function. Called (from timer poll) when an AIOPIC signals + * that receive data is present on a serial port. Pulls data from FIFO, moves it into the + * tty layer. + */ +static void rp_do_receive(struct r_port *info, + struct tty_struct *tty, + CHANNEL_t * cp, unsigned int ChanStatus) +{ + unsigned int CharNStat; + int ToRecv, wRecv, space; + unsigned char *cbuf; + + ToRecv = sGetRxCnt(cp); +#ifdef ROCKET_DEBUG_INTR + printk(KERN_INFO "rp_do_receive(%d)...\n", ToRecv); +#endif + if (ToRecv == 0) + return; + + /* + * if status indicates there are errored characters in the + * FIFO, then enter status mode (a word in FIFO holds + * character and status). + */ + if (ChanStatus & (RXFOVERFL | RXBREAK | RXFRAME | RXPARITY)) { + if (!(ChanStatus & STATMODE)) { +#ifdef ROCKET_DEBUG_RECEIVE + printk(KERN_INFO "Entering STATMODE...\n"); +#endif + ChanStatus |= STATMODE; + sEnRxStatusMode(cp); + } + } + + /* + * if we previously entered status mode, then read down the + * FIFO one word at a time, pulling apart the character and + * the status. Update error counters depending on status + */ + if (ChanStatus & STATMODE) { +#ifdef ROCKET_DEBUG_RECEIVE + printk(KERN_INFO "Ignore %x, read %x...\n", + info->ignore_status_mask, info->read_status_mask); +#endif + while (ToRecv) { + char flag; + + CharNStat = sInW(sGetTxRxDataIO(cp)); +#ifdef ROCKET_DEBUG_RECEIVE + printk(KERN_INFO "%x...\n", CharNStat); +#endif + if (CharNStat & STMBREAKH) + CharNStat &= ~(STMFRAMEH | STMPARITYH); + if (CharNStat & info->ignore_status_mask) { + ToRecv--; + continue; + } + CharNStat &= info->read_status_mask; + if (CharNStat & STMBREAKH) + flag = TTY_BREAK; + else if (CharNStat & STMPARITYH) + flag = TTY_PARITY; + else if (CharNStat & STMFRAMEH) + flag = TTY_FRAME; + else if (CharNStat & STMRCVROVRH) + flag = TTY_OVERRUN; + else + flag = TTY_NORMAL; + tty_insert_flip_char(tty, CharNStat & 0xff, flag); + ToRecv--; + } + + /* + * after we've emptied the FIFO in status mode, turn + * status mode back off + */ + if (sGetRxCnt(cp) == 0) { +#ifdef ROCKET_DEBUG_RECEIVE + printk(KERN_INFO "Status mode off.\n"); +#endif + sDisRxStatusMode(cp); + } + } else { + /* + * we aren't in status mode, so read down the FIFO two + * characters at time by doing repeated word IO + * transfer. + */ + space = tty_prepare_flip_string(tty, &cbuf, ToRecv); + if (space < ToRecv) { +#ifdef ROCKET_DEBUG_RECEIVE + printk(KERN_INFO "rp_do_receive:insufficient space ToRecv=%d space=%d\n", ToRecv, space); +#endif + if (space <= 0) + return; + ToRecv = space; + } + wRecv = ToRecv >> 1; + if (wRecv) + sInStrW(sGetTxRxDataIO(cp), (unsigned short *) cbuf, wRecv); + if (ToRecv & 1) + cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp)); + } + /* Push the data up to the tty layer */ + tty_flip_buffer_push(tty); +} + +/* + * Serial port transmit data function. Called from the timer polling loop as a + * result of a bit set in xmit_flags[], indicating data (from the tty layer) is ready + * to be sent out the serial port. Data is buffered in rp_table[line].xmit_buf, it is + * moved to the port's xmit FIFO. *info is critical data, protected by spinlocks. + */ +static void rp_do_transmit(struct r_port *info) +{ + int c; + CHANNEL_t *cp = &info->channel; + struct tty_struct *tty; + unsigned long flags; + +#ifdef ROCKET_DEBUG_INTR + printk(KERN_DEBUG "%s\n", __func__); +#endif + if (!info) + return; + tty = tty_port_tty_get(&info->port); + + if (tty == NULL) { + printk(KERN_WARNING "rp: WARNING %s called with tty==NULL\n", __func__); + clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); + return; + } + + spin_lock_irqsave(&info->slock, flags); + info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp); + + /* Loop sending data to FIFO until done or FIFO full */ + while (1) { + if (tty->stopped || tty->hw_stopped) + break; + c = min(info->xmit_fifo_room, info->xmit_cnt); + c = min(c, XMIT_BUF_SIZE - info->xmit_tail); + if (c <= 0 || info->xmit_fifo_room <= 0) + break; + sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) (info->xmit_buf + info->xmit_tail), c / 2); + if (c & 1) + sOutB(sGetTxRxDataIO(cp), info->xmit_buf[info->xmit_tail + c - 1]); + info->xmit_tail += c; + info->xmit_tail &= XMIT_BUF_SIZE - 1; + info->xmit_cnt -= c; + info->xmit_fifo_room -= c; +#ifdef ROCKET_DEBUG_INTR + printk(KERN_INFO "tx %d chars...\n", c); +#endif + } + + if (info->xmit_cnt == 0) + clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); + + if (info->xmit_cnt < WAKEUP_CHARS) { + tty_wakeup(tty); +#ifdef ROCKETPORT_HAVE_POLL_WAIT + wake_up_interruptible(&tty->poll_wait); +#endif + } + + spin_unlock_irqrestore(&info->slock, flags); + tty_kref_put(tty); + +#ifdef ROCKET_DEBUG_INTR + printk(KERN_DEBUG "(%d,%d,%d,%d)...\n", info->xmit_cnt, info->xmit_head, + info->xmit_tail, info->xmit_fifo_room); +#endif +} + +/* + * Called when a serial port signals it has read data in it's RX FIFO. + * It checks what interrupts are pending and services them, including + * receiving serial data. + */ +static void rp_handle_port(struct r_port *info) +{ + CHANNEL_t *cp; + struct tty_struct *tty; + unsigned int IntMask, ChanStatus; + + if (!info) + return; + + if ((info->port.flags & ASYNC_INITIALIZED) == 0) { + printk(KERN_WARNING "rp: WARNING: rp_handle_port called with " + "info->flags & NOT_INIT\n"); + return; + } + tty = tty_port_tty_get(&info->port); + if (!tty) { + printk(KERN_WARNING "rp: WARNING: rp_handle_port called with " + "tty==NULL\n"); + return; + } + cp = &info->channel; + + IntMask = sGetChanIntID(cp) & info->intmask; +#ifdef ROCKET_DEBUG_INTR + printk(KERN_INFO "rp_interrupt %02x...\n", IntMask); +#endif + ChanStatus = sGetChanStatus(cp); + if (IntMask & RXF_TRIG) { /* Rx FIFO trigger level */ + rp_do_receive(info, tty, cp, ChanStatus); + } + if (IntMask & DELTA_CD) { /* CD change */ +#if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_INTR) || defined(ROCKET_DEBUG_HANGUP)) + printk(KERN_INFO "ttyR%d CD now %s...\n", info->line, + (ChanStatus & CD_ACT) ? "on" : "off"); +#endif + if (!(ChanStatus & CD_ACT) && info->cd_status) { +#ifdef ROCKET_DEBUG_HANGUP + printk(KERN_INFO "CD drop, calling hangup.\n"); +#endif + tty_hangup(tty); + } + info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0; + wake_up_interruptible(&info->port.open_wait); + } +#ifdef ROCKET_DEBUG_INTR + if (IntMask & DELTA_CTS) { /* CTS change */ + printk(KERN_INFO "CTS change...\n"); + } + if (IntMask & DELTA_DSR) { /* DSR change */ + printk(KERN_INFO "DSR change...\n"); + } +#endif + tty_kref_put(tty); +} + +/* + * The top level polling routine. Repeats every 1/100 HZ (10ms). + */ +static void rp_do_poll(unsigned long dummy) +{ + CONTROLLER_t *ctlp; + int ctrl, aiop, ch, line; + unsigned int xmitmask, i; + unsigned int CtlMask; + unsigned char AiopMask; + Word_t bit; + + /* Walk through all the boards (ctrl's) */ + for (ctrl = 0; ctrl < max_board; ctrl++) { + if (rcktpt_io_addr[ctrl] <= 0) + continue; + + /* Get a ptr to the board's control struct */ + ctlp = sCtlNumToCtlPtr(ctrl); + + /* Get the interrupt status from the board */ +#ifdef CONFIG_PCI + if (ctlp->BusType == isPCI) + CtlMask = sPCIGetControllerIntStatus(ctlp); + else +#endif + CtlMask = sGetControllerIntStatus(ctlp); + + /* Check if any AIOP read bits are set */ + for (aiop = 0; CtlMask; aiop++) { + bit = ctlp->AiopIntrBits[aiop]; + if (CtlMask & bit) { + CtlMask &= ~bit; + AiopMask = sGetAiopIntStatus(ctlp, aiop); + + /* Check if any port read bits are set */ + for (ch = 0; AiopMask; AiopMask >>= 1, ch++) { + if (AiopMask & 1) { + + /* Get the line number (/dev/ttyRx number). */ + /* Read the data from the port. */ + line = GetLineNumber(ctrl, aiop, ch); + rp_handle_port(rp_table[line]); + } + } + } + } + + xmitmask = xmit_flags[ctrl]; + + /* + * xmit_flags contains bit-significant flags, indicating there is data + * to xmit on the port. Bit 0 is port 0 on this board, bit 1 is port + * 1, ... (32 total possible). The variable i has the aiop and ch + * numbers encoded in it (port 0-7 are aiop0, 8-15 are aiop1, etc). + */ + if (xmitmask) { + for (i = 0; i < rocketModel[ctrl].numPorts; i++) { + if (xmitmask & (1 << i)) { + aiop = (i & 0x18) >> 3; + ch = i & 0x07; + line = GetLineNumber(ctrl, aiop, ch); + rp_do_transmit(rp_table[line]); + } + } + } + } + + /* + * Reset the timer so we get called at the next clock tick (10ms). + */ + if (atomic_read(&rp_num_ports_open)) + mod_timer(&rocket_timer, jiffies + POLL_PERIOD); +} + +/* + * Initializes the r_port structure for a port, as well as enabling the port on + * the board. + * Inputs: board, aiop, chan numbers + */ +static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) +{ + unsigned rocketMode; + struct r_port *info; + int line; + CONTROLLER_T *ctlp; + + /* Get the next available line number */ + line = SetLineNumber(board, aiop, chan); + + ctlp = sCtlNumToCtlPtr(board); + + /* Get a r_port struct for the port, fill it in and save it globally, indexed by line number */ + info = kzalloc(sizeof (struct r_port), GFP_KERNEL); + if (!info) { + printk(KERN_ERR "Couldn't allocate info struct for line #%d\n", + line); + return; + } + + info->magic = RPORT_MAGIC; + info->line = line; + info->ctlp = ctlp; + info->board = board; + info->aiop = aiop; + info->chan = chan; + tty_port_init(&info->port); + info->port.ops = &rocket_port_ops; + init_completion(&info->close_wait); + info->flags &= ~ROCKET_MODE_MASK; + switch (pc104[board][line]) { + case 422: + info->flags |= ROCKET_MODE_RS422; + break; + case 485: + info->flags |= ROCKET_MODE_RS485; + break; + case 232: + default: + info->flags |= ROCKET_MODE_RS232; + break; + } + + info->intmask = RXF_TRIG | TXFIFO_MT | SRC_INT | DELTA_CD | DELTA_CTS | DELTA_DSR; + if (sInitChan(ctlp, &info->channel, aiop, chan) == 0) { + printk(KERN_ERR "RocketPort sInitChan(%d, %d, %d) failed!\n", + board, aiop, chan); + kfree(info); + return; + } + + rocketMode = info->flags & ROCKET_MODE_MASK; + + if ((info->flags & ROCKET_RTS_TOGGLE) || (rocketMode == ROCKET_MODE_RS485)) + sEnRTSToggle(&info->channel); + else + sDisRTSToggle(&info->channel); + + if (ctlp->boardType == ROCKET_TYPE_PC104) { + switch (rocketMode) { + case ROCKET_MODE_RS485: + sSetInterfaceMode(&info->channel, InterfaceModeRS485); + break; + case ROCKET_MODE_RS422: + sSetInterfaceMode(&info->channel, InterfaceModeRS422); + break; + case ROCKET_MODE_RS232: + default: + if (info->flags & ROCKET_RTS_TOGGLE) + sSetInterfaceMode(&info->channel, InterfaceModeRS232T); + else + sSetInterfaceMode(&info->channel, InterfaceModeRS232); + break; + } + } + spin_lock_init(&info->slock); + mutex_init(&info->write_mtx); + rp_table[line] = info; + tty_register_device(rocket_driver, line, pci_dev ? &pci_dev->dev : + NULL); +} + +/* + * Configures a rocketport port according to its termio settings. Called from + * user mode into the driver (exception handler). *info CD manipulation is spinlock protected. + */ +static void configure_r_port(struct tty_struct *tty, struct r_port *info, + struct ktermios *old_termios) +{ + unsigned cflag; + unsigned long flags; + unsigned rocketMode; + int bits, baud, divisor; + CHANNEL_t *cp; + struct ktermios *t = tty->termios; + + cp = &info->channel; + cflag = t->c_cflag; + + /* Byte size and parity */ + if ((cflag & CSIZE) == CS8) { + sSetData8(cp); + bits = 10; + } else { + sSetData7(cp); + bits = 9; + } + if (cflag & CSTOPB) { + sSetStop2(cp); + bits++; + } else { + sSetStop1(cp); + } + + if (cflag & PARENB) { + sEnParity(cp); + bits++; + if (cflag & PARODD) { + sSetOddParity(cp); + } else { + sSetEvenParity(cp); + } + } else { + sDisParity(cp); + } + + /* baud rate */ + baud = tty_get_baud_rate(tty); + if (!baud) + baud = 9600; + divisor = ((rp_baud_base[info->board] + (baud >> 1)) / baud) - 1; + if ((divisor >= 8192 || divisor < 0) && old_termios) { + baud = tty_termios_baud_rate(old_termios); + if (!baud) + baud = 9600; + divisor = (rp_baud_base[info->board] / baud) - 1; + } + if (divisor >= 8192 || divisor < 0) { + baud = 9600; + divisor = (rp_baud_base[info->board] / baud) - 1; + } + info->cps = baud / bits; + sSetBaud(cp, divisor); + + /* FIXME: Should really back compute a baud rate from the divisor */ + tty_encode_baud_rate(tty, baud, baud); + + if (cflag & CRTSCTS) { + info->intmask |= DELTA_CTS; + sEnCTSFlowCtl(cp); + } else { + info->intmask &= ~DELTA_CTS; + sDisCTSFlowCtl(cp); + } + if (cflag & CLOCAL) { + info->intmask &= ~DELTA_CD; + } else { + spin_lock_irqsave(&info->slock, flags); + if (sGetChanStatus(cp) & CD_ACT) + info->cd_status = 1; + else + info->cd_status = 0; + info->intmask |= DELTA_CD; + spin_unlock_irqrestore(&info->slock, flags); + } + + /* + * Handle software flow control in the board + */ +#ifdef ROCKET_SOFT_FLOW + if (I_IXON(tty)) { + sEnTxSoftFlowCtl(cp); + if (I_IXANY(tty)) { + sEnIXANY(cp); + } else { + sDisIXANY(cp); + } + sSetTxXONChar(cp, START_CHAR(tty)); + sSetTxXOFFChar(cp, STOP_CHAR(tty)); + } else { + sDisTxSoftFlowCtl(cp); + sDisIXANY(cp); + sClrTxXOFF(cp); + } +#endif + + /* + * Set up ignore/read mask words + */ + info->read_status_mask = STMRCVROVRH | 0xFF; + if (I_INPCK(tty)) + info->read_status_mask |= STMFRAMEH | STMPARITYH; + if (I_BRKINT(tty) || I_PARMRK(tty)) + info->read_status_mask |= STMBREAKH; + + /* + * Characters to ignore + */ + info->ignore_status_mask = 0; + if (I_IGNPAR(tty)) + info->ignore_status_mask |= STMFRAMEH | STMPARITYH; + if (I_IGNBRK(tty)) { + info->ignore_status_mask |= STMBREAKH; + /* + * If we're ignoring parity and break indicators, + * ignore overruns too. (For real raw support). + */ + if (I_IGNPAR(tty)) + info->ignore_status_mask |= STMRCVROVRH; + } + + rocketMode = info->flags & ROCKET_MODE_MASK; + + if ((info->flags & ROCKET_RTS_TOGGLE) + || (rocketMode == ROCKET_MODE_RS485)) + sEnRTSToggle(cp); + else + sDisRTSToggle(cp); + + sSetRTS(&info->channel); + + if (cp->CtlP->boardType == ROCKET_TYPE_PC104) { + switch (rocketMode) { + case ROCKET_MODE_RS485: + sSetInterfaceMode(cp, InterfaceModeRS485); + break; + case ROCKET_MODE_RS422: + sSetInterfaceMode(cp, InterfaceModeRS422); + break; + case ROCKET_MODE_RS232: + default: + if (info->flags & ROCKET_RTS_TOGGLE) + sSetInterfaceMode(cp, InterfaceModeRS232T); + else + sSetInterfaceMode(cp, InterfaceModeRS232); + break; + } + } +} + +static int carrier_raised(struct tty_port *port) +{ + struct r_port *info = container_of(port, struct r_port, port); + return (sGetChanStatusLo(&info->channel) & CD_ACT) ? 1 : 0; +} + +static void dtr_rts(struct tty_port *port, int on) +{ + struct r_port *info = container_of(port, struct r_port, port); + if (on) { + sSetDTR(&info->channel); + sSetRTS(&info->channel); + } else { + sClrDTR(&info->channel); + sClrRTS(&info->channel); + } +} + +/* + * Exception handler that opens a serial port. Creates xmit_buf storage, fills in + * port's r_port struct. Initializes the port hardware. + */ +static int rp_open(struct tty_struct *tty, struct file *filp) +{ + struct r_port *info; + struct tty_port *port; + int line = 0, retval; + CHANNEL_t *cp; + unsigned long page; + + line = tty->index; + if (line < 0 || line >= MAX_RP_PORTS || ((info = rp_table[line]) == NULL)) + return -ENXIO; + port = &info->port; + + page = __get_free_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + + if (port->flags & ASYNC_CLOSING) { + retval = wait_for_completion_interruptible(&info->close_wait); + free_page(page); + if (retval) + return retval; + return ((port->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); + } + + /* + * We must not sleep from here until the port is marked fully in use. + */ + if (info->xmit_buf) + free_page(page); + else + info->xmit_buf = (unsigned char *) page; + + tty->driver_data = info; + tty_port_tty_set(port, tty); + + if (port->count++ == 0) { + atomic_inc(&rp_num_ports_open); + +#ifdef ROCKET_DEBUG_OPEN + printk(KERN_INFO "rocket mod++ = %d...\n", + atomic_read(&rp_num_ports_open)); +#endif + } +#ifdef ROCKET_DEBUG_OPEN + printk(KERN_INFO "rp_open ttyR%d, count=%d\n", info->line, info->port.count); +#endif + + /* + * Info->count is now 1; so it's safe to sleep now. + */ + if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) { + cp = &info->channel; + sSetRxTrigger(cp, TRIG_1); + if (sGetChanStatus(cp) & CD_ACT) + info->cd_status = 1; + else + info->cd_status = 0; + sDisRxStatusMode(cp); + sFlushRxFIFO(cp); + sFlushTxFIFO(cp); + + sEnInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN)); + sSetRxTrigger(cp, TRIG_1); + + sGetChanStatus(cp); + sDisRxStatusMode(cp); + sClrTxXOFF(cp); + + sDisCTSFlowCtl(cp); + sDisTxSoftFlowCtl(cp); + + sEnRxFIFO(cp); + sEnTransmit(cp); + + set_bit(ASYNCB_INITIALIZED, &info->port.flags); + + /* + * Set up the tty->alt_speed kludge + */ + if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI) + tty->alt_speed = 57600; + if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI) + tty->alt_speed = 115200; + if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI) + tty->alt_speed = 230400; + if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP) + tty->alt_speed = 460800; + + configure_r_port(tty, info, NULL); + if (tty->termios->c_cflag & CBAUD) { + sSetDTR(cp); + sSetRTS(cp); + } + } + /* Starts (or resets) the maint polling loop */ + mod_timer(&rocket_timer, jiffies + POLL_PERIOD); + + retval = tty_port_block_til_ready(port, tty, filp); + if (retval) { +#ifdef ROCKET_DEBUG_OPEN + printk(KERN_INFO "rp_open returning after block_til_ready with %d\n", retval); +#endif + return retval; + } + return 0; +} + +/* + * Exception handler that closes a serial port. info->port.count is considered critical. + */ +static void rp_close(struct tty_struct *tty, struct file *filp) +{ + struct r_port *info = tty->driver_data; + struct tty_port *port = &info->port; + int timeout; + CHANNEL_t *cp; + + if (rocket_paranoia_check(info, "rp_close")) + return; + +#ifdef ROCKET_DEBUG_OPEN + printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->port.count); +#endif + + if (tty_port_close_start(port, tty, filp) == 0) + return; + + mutex_lock(&port->mutex); + cp = &info->channel; + /* + * Before we drop DTR, make sure the UART transmitter + * has completely drained; this is especially + * important if there is a transmit FIFO! + */ + timeout = (sGetTxCnt(cp) + 1) * HZ / info->cps; + if (timeout == 0) + timeout = 1; + rp_wait_until_sent(tty, timeout); + clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); + + sDisTransmit(cp); + sDisInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN)); + sDisCTSFlowCtl(cp); + sDisTxSoftFlowCtl(cp); + sClrTxXOFF(cp); + sFlushRxFIFO(cp); + sFlushTxFIFO(cp); + sClrRTS(cp); + if (C_HUPCL(tty)) + sClrDTR(cp); + + rp_flush_buffer(tty); + + tty_ldisc_flush(tty); + + clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); + + /* We can't yet use tty_port_close_end as the buffer handling in this + driver is a bit different to the usual */ + + if (port->blocked_open) { + if (port->close_delay) { + msleep_interruptible(jiffies_to_msecs(port->close_delay)); + } + wake_up_interruptible(&port->open_wait); + } else { + if (info->xmit_buf) { + free_page((unsigned long) info->xmit_buf); + info->xmit_buf = NULL; + } + } + spin_lock_irq(&port->lock); + info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING | ASYNC_NORMAL_ACTIVE); + tty->closing = 0; + spin_unlock_irq(&port->lock); + mutex_unlock(&port->mutex); + tty_port_tty_set(port, NULL); + + wake_up_interruptible(&port->close_wait); + complete_all(&info->close_wait); + atomic_dec(&rp_num_ports_open); + +#ifdef ROCKET_DEBUG_OPEN + printk(KERN_INFO "rocket mod-- = %d...\n", + atomic_read(&rp_num_ports_open)); + printk(KERN_INFO "rp_close ttyR%d complete shutdown\n", info->line); +#endif + +} + +static void rp_set_termios(struct tty_struct *tty, + struct ktermios *old_termios) +{ + struct r_port *info = tty->driver_data; + CHANNEL_t *cp; + unsigned cflag; + + if (rocket_paranoia_check(info, "rp_set_termios")) + return; + + cflag = tty->termios->c_cflag; + + /* + * This driver doesn't support CS5 or CS6 + */ + if (((cflag & CSIZE) == CS5) || ((cflag & CSIZE) == CS6)) + tty->termios->c_cflag = + ((cflag & ~CSIZE) | (old_termios->c_cflag & CSIZE)); + /* Or CMSPAR */ + tty->termios->c_cflag &= ~CMSPAR; + + configure_r_port(tty, info, old_termios); + + cp = &info->channel; + + /* Handle transition to B0 status */ + if ((old_termios->c_cflag & CBAUD) && !(tty->termios->c_cflag & CBAUD)) { + sClrDTR(cp); + sClrRTS(cp); + } + + /* Handle transition away from B0 status */ + if (!(old_termios->c_cflag & CBAUD) && (tty->termios->c_cflag & CBAUD)) { + if (!tty->hw_stopped || !(tty->termios->c_cflag & CRTSCTS)) + sSetRTS(cp); + sSetDTR(cp); + } + + if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + rp_start(tty); + } +} + +static int rp_break(struct tty_struct *tty, int break_state) +{ + struct r_port *info = tty->driver_data; + unsigned long flags; + + if (rocket_paranoia_check(info, "rp_break")) + return -EINVAL; + + spin_lock_irqsave(&info->slock, flags); + if (break_state == -1) + sSendBreak(&info->channel); + else + sClrBreak(&info->channel); + spin_unlock_irqrestore(&info->slock, flags); + return 0; +} + +/* + * sGetChanRI used to be a macro in rocket_int.h. When the functionality for + * the UPCI boards was added, it was decided to make this a function because + * the macro was getting too complicated. All cases except the first one + * (UPCIRingInd) are taken directly from the original macro. + */ +static int sGetChanRI(CHANNEL_T * ChP) +{ + CONTROLLER_t *CtlP = ChP->CtlP; + int ChanNum = ChP->ChanNum; + int RingInd = 0; + + if (CtlP->UPCIRingInd) + RingInd = !(sInB(CtlP->UPCIRingInd) & sBitMapSetTbl[ChanNum]); + else if (CtlP->AltChanRingIndicator) + RingInd = sInB((ByteIO_t) (ChP->ChanStat + 8)) & DSR_ACT; + else if (CtlP->boardType == ROCKET_TYPE_PC104) + RingInd = !(sInB(CtlP->AiopIO[3]) & sBitMapSetTbl[ChanNum]); + + return RingInd; +} + +/********************************************************************************************/ +/* Here are the routines used by rp_ioctl. These are all called from exception handlers. */ + +/* + * Returns the state of the serial modem control lines. These next 2 functions + * are the way kernel versions > 2.5 handle modem control lines rather than IOCTLs. + */ +static int rp_tiocmget(struct tty_struct *tty) +{ + struct r_port *info = tty->driver_data; + unsigned int control, result, ChanStatus; + + ChanStatus = sGetChanStatusLo(&info->channel); + control = info->channel.TxControl[3]; + result = ((control & SET_RTS) ? TIOCM_RTS : 0) | + ((control & SET_DTR) ? TIOCM_DTR : 0) | + ((ChanStatus & CD_ACT) ? TIOCM_CAR : 0) | + (sGetChanRI(&info->channel) ? TIOCM_RNG : 0) | + ((ChanStatus & DSR_ACT) ? TIOCM_DSR : 0) | + ((ChanStatus & CTS_ACT) ? TIOCM_CTS : 0); + + return result; +} + +/* + * Sets the modem control lines + */ +static int rp_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + struct r_port *info = tty->driver_data; + + if (set & TIOCM_RTS) + info->channel.TxControl[3] |= SET_RTS; + if (set & TIOCM_DTR) + info->channel.TxControl[3] |= SET_DTR; + if (clear & TIOCM_RTS) + info->channel.TxControl[3] &= ~SET_RTS; + if (clear & TIOCM_DTR) + info->channel.TxControl[3] &= ~SET_DTR; + + out32(info->channel.IndexAddr, info->channel.TxControl); + return 0; +} + +static int get_config(struct r_port *info, struct rocket_config __user *retinfo) +{ + struct rocket_config tmp; + + if (!retinfo) + return -EFAULT; + memset(&tmp, 0, sizeof (tmp)); + mutex_lock(&info->port.mutex); + tmp.line = info->line; + tmp.flags = info->flags; + tmp.close_delay = info->port.close_delay; + tmp.closing_wait = info->port.closing_wait; + tmp.port = rcktpt_io_addr[(info->line >> 5) & 3]; + mutex_unlock(&info->port.mutex); + + if (copy_to_user(retinfo, &tmp, sizeof (*retinfo))) + return -EFAULT; + return 0; +} + +static int set_config(struct tty_struct *tty, struct r_port *info, + struct rocket_config __user *new_info) +{ + struct rocket_config new_serial; + + if (copy_from_user(&new_serial, new_info, sizeof (new_serial))) + return -EFAULT; + + mutex_lock(&info->port.mutex); + if (!capable(CAP_SYS_ADMIN)) + { + if ((new_serial.flags & ~ROCKET_USR_MASK) != (info->flags & ~ROCKET_USR_MASK)) { + mutex_unlock(&info->port.mutex); + return -EPERM; + } + info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK)); + configure_r_port(tty, info, NULL); + mutex_unlock(&info->port.mutex); + return 0; + } + + info->flags = ((info->flags & ~ROCKET_FLAGS) | (new_serial.flags & ROCKET_FLAGS)); + info->port.close_delay = new_serial.close_delay; + info->port.closing_wait = new_serial.closing_wait; + + if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI) + tty->alt_speed = 57600; + if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI) + tty->alt_speed = 115200; + if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI) + tty->alt_speed = 230400; + if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP) + tty->alt_speed = 460800; + mutex_unlock(&info->port.mutex); + + configure_r_port(tty, info, NULL); + return 0; +} + +/* + * This function fills in a rocket_ports struct with information + * about what boards/ports are in the system. This info is passed + * to user space. See setrocket.c where the info is used to create + * the /dev/ttyRx ports. + */ +static int get_ports(struct r_port *info, struct rocket_ports __user *retports) +{ + struct rocket_ports tmp; + int board; + + if (!retports) + return -EFAULT; + memset(&tmp, 0, sizeof (tmp)); + tmp.tty_major = rocket_driver->major; + + for (board = 0; board < 4; board++) { + tmp.rocketModel[board].model = rocketModel[board].model; + strcpy(tmp.rocketModel[board].modelString, rocketModel[board].modelString); + tmp.rocketModel[board].numPorts = rocketModel[board].numPorts; + tmp.rocketModel[board].loadrm2 = rocketModel[board].loadrm2; + tmp.rocketModel[board].startingPortNumber = rocketModel[board].startingPortNumber; + } + if (copy_to_user(retports, &tmp, sizeof (*retports))) + return -EFAULT; + return 0; +} + +static int reset_rm2(struct r_port *info, void __user *arg) +{ + int reset; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (copy_from_user(&reset, arg, sizeof (int))) + return -EFAULT; + if (reset) + reset = 1; + + if (rcktpt_type[info->board] != ROCKET_TYPE_MODEMII && + rcktpt_type[info->board] != ROCKET_TYPE_MODEMIII) + return -EINVAL; + + if (info->ctlp->BusType == isISA) + sModemReset(info->ctlp, info->chan, reset); + else + sPCIModemReset(info->ctlp, info->chan, reset); + + return 0; +} + +static int get_version(struct r_port *info, struct rocket_version __user *retvers) +{ + if (copy_to_user(retvers, &driver_version, sizeof (*retvers))) + return -EFAULT; + return 0; +} + +/* IOCTL call handler into the driver */ +static int rp_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + struct r_port *info = tty->driver_data; + void __user *argp = (void __user *)arg; + int ret = 0; + + if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl")) + return -ENXIO; + + switch (cmd) { + case RCKP_GET_STRUCT: + if (copy_to_user(argp, info, sizeof (struct r_port))) + ret = -EFAULT; + break; + case RCKP_GET_CONFIG: + ret = get_config(info, argp); + break; + case RCKP_SET_CONFIG: + ret = set_config(tty, info, argp); + break; + case RCKP_GET_PORTS: + ret = get_ports(info, argp); + break; + case RCKP_RESET_RM2: + ret = reset_rm2(info, argp); + break; + case RCKP_GET_VERSION: + ret = get_version(info, argp); + break; + default: + ret = -ENOIOCTLCMD; + } + return ret; +} + +static void rp_send_xchar(struct tty_struct *tty, char ch) +{ + struct r_port *info = tty->driver_data; + CHANNEL_t *cp; + + if (rocket_paranoia_check(info, "rp_send_xchar")) + return; + + cp = &info->channel; + if (sGetTxCnt(cp)) + sWriteTxPrioByte(cp, ch); + else + sWriteTxByte(sGetTxRxDataIO(cp), ch); +} + +static void rp_throttle(struct tty_struct *tty) +{ + struct r_port *info = tty->driver_data; + CHANNEL_t *cp; + +#ifdef ROCKET_DEBUG_THROTTLE + printk(KERN_INFO "throttle %s: %d....\n", tty->name, + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (rocket_paranoia_check(info, "rp_throttle")) + return; + + cp = &info->channel; + if (I_IXOFF(tty)) + rp_send_xchar(tty, STOP_CHAR(tty)); + + sClrRTS(&info->channel); +} + +static void rp_unthrottle(struct tty_struct *tty) +{ + struct r_port *info = tty->driver_data; + CHANNEL_t *cp; +#ifdef ROCKET_DEBUG_THROTTLE + printk(KERN_INFO "unthrottle %s: %d....\n", tty->name, + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (rocket_paranoia_check(info, "rp_throttle")) + return; + + cp = &info->channel; + if (I_IXOFF(tty)) + rp_send_xchar(tty, START_CHAR(tty)); + + sSetRTS(&info->channel); +} + +/* + * ------------------------------------------------------------ + * rp_stop() and rp_start() + * + * This routines are called before setting or resetting tty->stopped. + * They enable or disable transmitter interrupts, as necessary. + * ------------------------------------------------------------ + */ +static void rp_stop(struct tty_struct *tty) +{ + struct r_port *info = tty->driver_data; + +#ifdef ROCKET_DEBUG_FLOW + printk(KERN_INFO "stop %s: %d %d....\n", tty->name, + info->xmit_cnt, info->xmit_fifo_room); +#endif + + if (rocket_paranoia_check(info, "rp_stop")) + return; + + if (sGetTxCnt(&info->channel)) + sDisTransmit(&info->channel); +} + +static void rp_start(struct tty_struct *tty) +{ + struct r_port *info = tty->driver_data; + +#ifdef ROCKET_DEBUG_FLOW + printk(KERN_INFO "start %s: %d %d....\n", tty->name, + info->xmit_cnt, info->xmit_fifo_room); +#endif + + if (rocket_paranoia_check(info, "rp_stop")) + return; + + sEnTransmit(&info->channel); + set_bit((info->aiop * 8) + info->chan, + (void *) &xmit_flags[info->board]); +} + +/* + * rp_wait_until_sent() --- wait until the transmitter is empty + */ +static void rp_wait_until_sent(struct tty_struct *tty, int timeout) +{ + struct r_port *info = tty->driver_data; + CHANNEL_t *cp; + unsigned long orig_jiffies; + int check_time, exit_time; + int txcnt; + + if (rocket_paranoia_check(info, "rp_wait_until_sent")) + return; + + cp = &info->channel; + + orig_jiffies = jiffies; +#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT + printk(KERN_INFO "In RP_wait_until_sent(%d) (jiff=%lu)...\n", timeout, + jiffies); + printk(KERN_INFO "cps=%d...\n", info->cps); +#endif + while (1) { + txcnt = sGetTxCnt(cp); + if (!txcnt) { + if (sGetChanStatusLo(cp) & TXSHRMT) + break; + check_time = (HZ / info->cps) / 5; + } else { + check_time = HZ * txcnt / info->cps; + } + if (timeout) { + exit_time = orig_jiffies + timeout - jiffies; + if (exit_time <= 0) + break; + if (exit_time < check_time) + check_time = exit_time; + } + if (check_time == 0) + check_time = 1; +#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT + printk(KERN_INFO "txcnt = %d (jiff=%lu,check=%d)...\n", txcnt, + jiffies, check_time); +#endif + msleep_interruptible(jiffies_to_msecs(check_time)); + if (signal_pending(current)) + break; + } + __set_current_state(TASK_RUNNING); +#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT + printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies); +#endif +} + +/* + * rp_hangup() --- called by tty_hangup() when a hangup is signaled. + */ +static void rp_hangup(struct tty_struct *tty) +{ + CHANNEL_t *cp; + struct r_port *info = tty->driver_data; + unsigned long flags; + + if (rocket_paranoia_check(info, "rp_hangup")) + return; + +#if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_HANGUP)) + printk(KERN_INFO "rp_hangup of ttyR%d...\n", info->line); +#endif + rp_flush_buffer(tty); + spin_lock_irqsave(&info->port.lock, flags); + if (info->port.flags & ASYNC_CLOSING) { + spin_unlock_irqrestore(&info->port.lock, flags); + return; + } + if (info->port.count) + atomic_dec(&rp_num_ports_open); + clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); + spin_unlock_irqrestore(&info->port.lock, flags); + + tty_port_hangup(&info->port); + + cp = &info->channel; + sDisRxFIFO(cp); + sDisTransmit(cp); + sDisInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN)); + sDisCTSFlowCtl(cp); + sDisTxSoftFlowCtl(cp); + sClrTxXOFF(cp); + clear_bit(ASYNCB_INITIALIZED, &info->port.flags); + + wake_up_interruptible(&info->port.open_wait); +} + +/* + * Exception handler - write char routine. The RocketPort driver uses a + * double-buffering strategy, with the twist that if the in-memory CPU + * buffer is empty, and there's space in the transmit FIFO, the + * writing routines will write directly to transmit FIFO. + * Write buffer and counters protected by spinlocks + */ +static int rp_put_char(struct tty_struct *tty, unsigned char ch) +{ + struct r_port *info = tty->driver_data; + CHANNEL_t *cp; + unsigned long flags; + + if (rocket_paranoia_check(info, "rp_put_char")) + return 0; + + /* + * Grab the port write mutex, locking out other processes that try to + * write to this port + */ + mutex_lock(&info->write_mtx); + +#ifdef ROCKET_DEBUG_WRITE + printk(KERN_INFO "rp_put_char %c...\n", ch); +#endif + + spin_lock_irqsave(&info->slock, flags); + cp = &info->channel; + + if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room == 0) + info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp); + + if (tty->stopped || tty->hw_stopped || info->xmit_fifo_room == 0 || info->xmit_cnt != 0) { + info->xmit_buf[info->xmit_head++] = ch; + info->xmit_head &= XMIT_BUF_SIZE - 1; + info->xmit_cnt++; + set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); + } else { + sOutB(sGetTxRxDataIO(cp), ch); + info->xmit_fifo_room--; + } + spin_unlock_irqrestore(&info->slock, flags); + mutex_unlock(&info->write_mtx); + return 1; +} + +/* + * Exception handler - write routine, called when user app writes to the device. + * A per port write mutex is used to protect from another process writing to + * this port at the same time. This other process could be running on the other CPU + * or get control of the CPU if the copy_from_user() blocks due to a page fault (swapped out). + * Spinlocks protect the info xmit members. + */ +static int rp_write(struct tty_struct *tty, + const unsigned char *buf, int count) +{ + struct r_port *info = tty->driver_data; + CHANNEL_t *cp; + const unsigned char *b; + int c, retval = 0; + unsigned long flags; + + if (count <= 0 || rocket_paranoia_check(info, "rp_write")) + return 0; + + if (mutex_lock_interruptible(&info->write_mtx)) + return -ERESTARTSYS; + +#ifdef ROCKET_DEBUG_WRITE + printk(KERN_INFO "rp_write %d chars...\n", count); +#endif + cp = &info->channel; + + if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room < count) + info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp); + + /* + * If the write queue for the port is empty, and there is FIFO space, stuff bytes + * into FIFO. Use the write queue for temp storage. + */ + if (!tty->stopped && !tty->hw_stopped && info->xmit_cnt == 0 && info->xmit_fifo_room > 0) { + c = min(count, info->xmit_fifo_room); + b = buf; + + /* Push data into FIFO, 2 bytes at a time */ + sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) b, c / 2); + + /* If there is a byte remaining, write it */ + if (c & 1) + sOutB(sGetTxRxDataIO(cp), b[c - 1]); + + retval += c; + buf += c; + count -= c; + + spin_lock_irqsave(&info->slock, flags); + info->xmit_fifo_room -= c; + spin_unlock_irqrestore(&info->slock, flags); + } + + /* If count is zero, we wrote it all and are done */ + if (!count) + goto end; + + /* Write remaining data into the port's xmit_buf */ + while (1) { + /* Hung up ? */ + if (!test_bit(ASYNCB_NORMAL_ACTIVE, &info->port.flags)) + goto end; + c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1); + c = min(c, XMIT_BUF_SIZE - info->xmit_head); + if (c <= 0) + break; + + b = buf; + memcpy(info->xmit_buf + info->xmit_head, b, c); + + spin_lock_irqsave(&info->slock, flags); + info->xmit_head = + (info->xmit_head + c) & (XMIT_BUF_SIZE - 1); + info->xmit_cnt += c; + spin_unlock_irqrestore(&info->slock, flags); + + buf += c; + count -= c; + retval += c; + } + + if ((retval > 0) && !tty->stopped && !tty->hw_stopped) + set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); + +end: + if (info->xmit_cnt < WAKEUP_CHARS) { + tty_wakeup(tty); +#ifdef ROCKETPORT_HAVE_POLL_WAIT + wake_up_interruptible(&tty->poll_wait); +#endif + } + mutex_unlock(&info->write_mtx); + return retval; +} + +/* + * Return the number of characters that can be sent. We estimate + * only using the in-memory transmit buffer only, and ignore the + * potential space in the transmit FIFO. + */ +static int rp_write_room(struct tty_struct *tty) +{ + struct r_port *info = tty->driver_data; + int ret; + + if (rocket_paranoia_check(info, "rp_write_room")) + return 0; + + ret = XMIT_BUF_SIZE - info->xmit_cnt - 1; + if (ret < 0) + ret = 0; +#ifdef ROCKET_DEBUG_WRITE + printk(KERN_INFO "rp_write_room returns %d...\n", ret); +#endif + return ret; +} + +/* + * Return the number of characters in the buffer. Again, this only + * counts those characters in the in-memory transmit buffer. + */ +static int rp_chars_in_buffer(struct tty_struct *tty) +{ + struct r_port *info = tty->driver_data; + CHANNEL_t *cp; + + if (rocket_paranoia_check(info, "rp_chars_in_buffer")) + return 0; + + cp = &info->channel; + +#ifdef ROCKET_DEBUG_WRITE + printk(KERN_INFO "rp_chars_in_buffer returns %d...\n", info->xmit_cnt); +#endif + return info->xmit_cnt; +} + +/* + * Flushes the TX fifo for a port, deletes data in the xmit_buf stored in the + * r_port struct for the port. Note that spinlock are used to protect info members, + * do not call this function if the spinlock is already held. + */ +static void rp_flush_buffer(struct tty_struct *tty) +{ + struct r_port *info = tty->driver_data; + CHANNEL_t *cp; + unsigned long flags; + + if (rocket_paranoia_check(info, "rp_flush_buffer")) + return; + + spin_lock_irqsave(&info->slock, flags); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + spin_unlock_irqrestore(&info->slock, flags); + +#ifdef ROCKETPORT_HAVE_POLL_WAIT + wake_up_interruptible(&tty->poll_wait); +#endif + tty_wakeup(tty); + + cp = &info->channel; + sFlushTxFIFO(cp); +} + +#ifdef CONFIG_PCI + +static struct pci_device_id __devinitdata __used rocket_pci_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_ANY_ID) }, + { } +}; +MODULE_DEVICE_TABLE(pci, rocket_pci_ids); + +/* + * Called when a PCI card is found. Retrieves and stores model information, + * init's aiopic and serial port hardware. + * Inputs: i is the board number (0-n) + */ +static __init int register_PCI(int i, struct pci_dev *dev) +{ + int num_aiops, aiop, max_num_aiops, num_chan, chan; + unsigned int aiopio[MAX_AIOPS_PER_BOARD]; + char *str, *board_type; + CONTROLLER_t *ctlp; + + int fast_clock = 0; + int altChanRingIndicator = 0; + int ports_per_aiop = 8; + WordIO_t ConfigIO = 0; + ByteIO_t UPCIRingInd = 0; + + if (!dev || pci_enable_device(dev)) + return 0; + + rcktpt_io_addr[i] = pci_resource_start(dev, 0); + + rcktpt_type[i] = ROCKET_TYPE_NORMAL; + rocketModel[i].loadrm2 = 0; + rocketModel[i].startingPortNumber = nextLineNumber; + + /* Depending on the model, set up some config variables */ + switch (dev->device) { + case PCI_DEVICE_ID_RP4QUAD: + str = "Quadcable"; + max_num_aiops = 1; + ports_per_aiop = 4; + rocketModel[i].model = MODEL_RP4QUAD; + strcpy(rocketModel[i].modelString, "RocketPort 4 port w/quad cable"); + rocketModel[i].numPorts = 4; + break; + case PCI_DEVICE_ID_RP8OCTA: + str = "Octacable"; + max_num_aiops = 1; + rocketModel[i].model = MODEL_RP8OCTA; + strcpy(rocketModel[i].modelString, "RocketPort 8 port w/octa cable"); + rocketModel[i].numPorts = 8; + break; + case PCI_DEVICE_ID_URP8OCTA: + str = "Octacable"; + max_num_aiops = 1; + rocketModel[i].model = MODEL_UPCI_RP8OCTA; + strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/octa cable"); + rocketModel[i].numPorts = 8; + break; + case PCI_DEVICE_ID_RP8INTF: + str = "8"; + max_num_aiops = 1; + rocketModel[i].model = MODEL_RP8INTF; + strcpy(rocketModel[i].modelString, "RocketPort 8 port w/external I/F"); + rocketModel[i].numPorts = 8; + break; + case PCI_DEVICE_ID_URP8INTF: + str = "8"; + max_num_aiops = 1; + rocketModel[i].model = MODEL_UPCI_RP8INTF; + strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/external I/F"); + rocketModel[i].numPorts = 8; + break; + case PCI_DEVICE_ID_RP8J: + str = "8J"; + max_num_aiops = 1; + rocketModel[i].model = MODEL_RP8J; + strcpy(rocketModel[i].modelString, "RocketPort 8 port w/RJ11 connectors"); + rocketModel[i].numPorts = 8; + break; + case PCI_DEVICE_ID_RP4J: + str = "4J"; + max_num_aiops = 1; + ports_per_aiop = 4; + rocketModel[i].model = MODEL_RP4J; + strcpy(rocketModel[i].modelString, "RocketPort 4 port w/RJ45 connectors"); + rocketModel[i].numPorts = 4; + break; + case PCI_DEVICE_ID_RP8SNI: + str = "8 (DB78 Custom)"; + max_num_aiops = 1; + rocketModel[i].model = MODEL_RP8SNI; + strcpy(rocketModel[i].modelString, "RocketPort 8 port w/ custom DB78"); + rocketModel[i].numPorts = 8; + break; + case PCI_DEVICE_ID_RP16SNI: + str = "16 (DB78 Custom)"; + max_num_aiops = 2; + rocketModel[i].model = MODEL_RP16SNI; + strcpy(rocketModel[i].modelString, "RocketPort 16 port w/ custom DB78"); + rocketModel[i].numPorts = 16; + break; + case PCI_DEVICE_ID_RP16INTF: + str = "16"; + max_num_aiops = 2; + rocketModel[i].model = MODEL_RP16INTF; + strcpy(rocketModel[i].modelString, "RocketPort 16 port w/external I/F"); + rocketModel[i].numPorts = 16; + break; + case PCI_DEVICE_ID_URP16INTF: + str = "16"; + max_num_aiops = 2; + rocketModel[i].model = MODEL_UPCI_RP16INTF; + strcpy(rocketModel[i].modelString, "RocketPort UPCI 16 port w/external I/F"); + rocketModel[i].numPorts = 16; + break; + case PCI_DEVICE_ID_CRP16INTF: + str = "16"; + max_num_aiops = 2; + rocketModel[i].model = MODEL_CPCI_RP16INTF; + strcpy(rocketModel[i].modelString, "RocketPort Compact PCI 16 port w/external I/F"); + rocketModel[i].numPorts = 16; + break; + case PCI_DEVICE_ID_RP32INTF: + str = "32"; + max_num_aiops = 4; + rocketModel[i].model = MODEL_RP32INTF; + strcpy(rocketModel[i].modelString, "RocketPort 32 port w/external I/F"); + rocketModel[i].numPorts = 32; + break; + case PCI_DEVICE_ID_URP32INTF: + str = "32"; + max_num_aiops = 4; + rocketModel[i].model = MODEL_UPCI_RP32INTF; + strcpy(rocketModel[i].modelString, "RocketPort UPCI 32 port w/external I/F"); + rocketModel[i].numPorts = 32; + break; + case PCI_DEVICE_ID_RPP4: + str = "Plus Quadcable"; + max_num_aiops = 1; + ports_per_aiop = 4; + altChanRingIndicator++; + fast_clock++; + rocketModel[i].model = MODEL_RPP4; + strcpy(rocketModel[i].modelString, "RocketPort Plus 4 port"); + rocketModel[i].numPorts = 4; + break; + case PCI_DEVICE_ID_RPP8: + str = "Plus Octacable"; + max_num_aiops = 2; + ports_per_aiop = 4; + altChanRingIndicator++; + fast_clock++; + rocketModel[i].model = MODEL_RPP8; + strcpy(rocketModel[i].modelString, "RocketPort Plus 8 port"); + rocketModel[i].numPorts = 8; + break; + case PCI_DEVICE_ID_RP2_232: + str = "Plus 2 (RS-232)"; + max_num_aiops = 1; + ports_per_aiop = 2; + altChanRingIndicator++; + fast_clock++; + rocketModel[i].model = MODEL_RP2_232; + strcpy(rocketModel[i].modelString, "RocketPort Plus 2 port RS232"); + rocketModel[i].numPorts = 2; + break; + case PCI_DEVICE_ID_RP2_422: + str = "Plus 2 (RS-422)"; + max_num_aiops = 1; + ports_per_aiop = 2; + altChanRingIndicator++; + fast_clock++; + rocketModel[i].model = MODEL_RP2_422; + strcpy(rocketModel[i].modelString, "RocketPort Plus 2 port RS422"); + rocketModel[i].numPorts = 2; + break; + case PCI_DEVICE_ID_RP6M: + + max_num_aiops = 1; + ports_per_aiop = 6; + str = "6-port"; + + /* If revision is 1, the rocketmodem flash must be loaded. + * If it is 2 it is a "socketed" version. */ + if (dev->revision == 1) { + rcktpt_type[i] = ROCKET_TYPE_MODEMII; + rocketModel[i].loadrm2 = 1; + } else { + rcktpt_type[i] = ROCKET_TYPE_MODEM; + } + + rocketModel[i].model = MODEL_RP6M; + strcpy(rocketModel[i].modelString, "RocketModem 6 port"); + rocketModel[i].numPorts = 6; + break; + case PCI_DEVICE_ID_RP4M: + max_num_aiops = 1; + ports_per_aiop = 4; + str = "4-port"; + if (dev->revision == 1) { + rcktpt_type[i] = ROCKET_TYPE_MODEMII; + rocketModel[i].loadrm2 = 1; + } else { + rcktpt_type[i] = ROCKET_TYPE_MODEM; + } + + rocketModel[i].model = MODEL_RP4M; + strcpy(rocketModel[i].modelString, "RocketModem 4 port"); + rocketModel[i].numPorts = 4; + break; + default: + str = "(unknown/unsupported)"; + max_num_aiops = 0; + break; + } + + /* + * Check for UPCI boards. + */ + + switch (dev->device) { + case PCI_DEVICE_ID_URP32INTF: + case PCI_DEVICE_ID_URP8INTF: + case PCI_DEVICE_ID_URP16INTF: + case PCI_DEVICE_ID_CRP16INTF: + case PCI_DEVICE_ID_URP8OCTA: + rcktpt_io_addr[i] = pci_resource_start(dev, 2); + ConfigIO = pci_resource_start(dev, 1); + if (dev->device == PCI_DEVICE_ID_URP8OCTA) { + UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND; + + /* + * Check for octa or quad cable. + */ + if (! + (sInW(ConfigIO + _PCI_9030_GPIO_CTRL) & + PCI_GPIO_CTRL_8PORT)) { + str = "Quadcable"; + ports_per_aiop = 4; + rocketModel[i].numPorts = 4; + } + } + break; + case PCI_DEVICE_ID_UPCI_RM3_8PORT: + str = "8 ports"; + max_num_aiops = 1; + rocketModel[i].model = MODEL_UPCI_RM3_8PORT; + strcpy(rocketModel[i].modelString, "RocketModem III 8 port"); + rocketModel[i].numPorts = 8; + rcktpt_io_addr[i] = pci_resource_start(dev, 2); + UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND; + ConfigIO = pci_resource_start(dev, 1); + rcktpt_type[i] = ROCKET_TYPE_MODEMIII; + break; + case PCI_DEVICE_ID_UPCI_RM3_4PORT: + str = "4 ports"; + max_num_aiops = 1; + rocketModel[i].model = MODEL_UPCI_RM3_4PORT; + strcpy(rocketModel[i].modelString, "RocketModem III 4 port"); + rocketModel[i].numPorts = 4; + rcktpt_io_addr[i] = pci_resource_start(dev, 2); + UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND; + ConfigIO = pci_resource_start(dev, 1); + rcktpt_type[i] = ROCKET_TYPE_MODEMIII; + break; + default: + break; + } + + switch (rcktpt_type[i]) { + case ROCKET_TYPE_MODEM: + board_type = "RocketModem"; + break; + case ROCKET_TYPE_MODEMII: + board_type = "RocketModem II"; + break; + case ROCKET_TYPE_MODEMIII: + board_type = "RocketModem III"; + break; + default: + board_type = "RocketPort"; + break; + } + + if (fast_clock) { + sClockPrescale = 0x12; /* mod 2 (divide by 3) */ + rp_baud_base[i] = 921600; + } else { + /* + * If support_low_speed is set, use the slow clock + * prescale, which supports 50 bps + */ + if (support_low_speed) { + /* mod 9 (divide by 10) prescale */ + sClockPrescale = 0x19; + rp_baud_base[i] = 230400; + } else { + /* mod 4 (devide by 5) prescale */ + sClockPrescale = 0x14; + rp_baud_base[i] = 460800; + } + } + + for (aiop = 0; aiop < max_num_aiops; aiop++) + aiopio[aiop] = rcktpt_io_addr[i] + (aiop * 0x40); + ctlp = sCtlNumToCtlPtr(i); + num_aiops = sPCIInitController(ctlp, i, aiopio, max_num_aiops, ConfigIO, 0, FREQ_DIS, 0, altChanRingIndicator, UPCIRingInd); + for (aiop = 0; aiop < max_num_aiops; aiop++) + ctlp->AiopNumChan[aiop] = ports_per_aiop; + + dev_info(&dev->dev, "comtrol PCI controller #%d found at " + "address %04lx, %d AIOP(s) (%s), creating ttyR%d - %ld\n", + i, rcktpt_io_addr[i], num_aiops, rocketModel[i].modelString, + rocketModel[i].startingPortNumber, + rocketModel[i].startingPortNumber + rocketModel[i].numPorts-1); + + if (num_aiops <= 0) { + rcktpt_io_addr[i] = 0; + return (0); + } + is_PCI[i] = 1; + + /* Reset the AIOPIC, init the serial ports */ + for (aiop = 0; aiop < num_aiops; aiop++) { + sResetAiopByNum(ctlp, aiop); + num_chan = ports_per_aiop; + for (chan = 0; chan < num_chan; chan++) + init_r_port(i, aiop, chan, dev); + } + + /* Rocket modems must be reset */ + if ((rcktpt_type[i] == ROCKET_TYPE_MODEM) || + (rcktpt_type[i] == ROCKET_TYPE_MODEMII) || + (rcktpt_type[i] == ROCKET_TYPE_MODEMIII)) { + num_chan = ports_per_aiop; + for (chan = 0; chan < num_chan; chan++) + sPCIModemReset(ctlp, chan, 1); + msleep(500); + for (chan = 0; chan < num_chan; chan++) + sPCIModemReset(ctlp, chan, 0); + msleep(500); + rmSpeakerReset(ctlp, rocketModel[i].model); + } + return (1); +} + +/* + * Probes for PCI cards, inits them if found + * Input: board_found = number of ISA boards already found, or the + * starting board number + * Returns: Number of PCI boards found + */ +static int __init init_PCI(int boards_found) +{ + struct pci_dev *dev = NULL; + int count = 0; + + /* Work through the PCI device list, pulling out ours */ + while ((dev = pci_get_device(PCI_VENDOR_ID_RP, PCI_ANY_ID, dev))) { + if (register_PCI(count + boards_found, dev)) + count++; + } + return (count); +} + +#endif /* CONFIG_PCI */ + +/* + * Probes for ISA cards + * Input: i = the board number to look for + * Returns: 1 if board found, 0 else + */ +static int __init init_ISA(int i) +{ + int num_aiops, num_chan = 0, total_num_chan = 0; + int aiop, chan; + unsigned int aiopio[MAX_AIOPS_PER_BOARD]; + CONTROLLER_t *ctlp; + char *type_string; + + /* If io_addr is zero, no board configured */ + if (rcktpt_io_addr[i] == 0) + return (0); + + /* Reserve the IO region */ + if (!request_region(rcktpt_io_addr[i], 64, "Comtrol RocketPort")) { + printk(KERN_ERR "Unable to reserve IO region for configured " + "ISA RocketPort at address 0x%lx, board not " + "installed...\n", rcktpt_io_addr[i]); + rcktpt_io_addr[i] = 0; + return (0); + } + + ctlp = sCtlNumToCtlPtr(i); + + ctlp->boardType = rcktpt_type[i]; + + switch (rcktpt_type[i]) { + case ROCKET_TYPE_PC104: + type_string = "(PC104)"; + break; + case ROCKET_TYPE_MODEM: + type_string = "(RocketModem)"; + break; + case ROCKET_TYPE_MODEMII: + type_string = "(RocketModem II)"; + break; + default: + type_string = ""; + break; + } + + /* + * If support_low_speed is set, use the slow clock prescale, + * which supports 50 bps + */ + if (support_low_speed) { + sClockPrescale = 0x19; /* mod 9 (divide by 10) prescale */ + rp_baud_base[i] = 230400; + } else { + sClockPrescale = 0x14; /* mod 4 (devide by 5) prescale */ + rp_baud_base[i] = 460800; + } + + for (aiop = 0; aiop < MAX_AIOPS_PER_BOARD; aiop++) + aiopio[aiop] = rcktpt_io_addr[i] + (aiop * 0x400); + + num_aiops = sInitController(ctlp, i, controller + (i * 0x400), aiopio, MAX_AIOPS_PER_BOARD, 0, FREQ_DIS, 0); + + if (ctlp->boardType == ROCKET_TYPE_PC104) { + sEnAiop(ctlp, 2); /* only one AIOPIC, but these */ + sEnAiop(ctlp, 3); /* CSels used for other stuff */ + } + + /* If something went wrong initing the AIOP's release the ISA IO memory */ + if (num_aiops <= 0) { + release_region(rcktpt_io_addr[i], 64); + rcktpt_io_addr[i] = 0; + return (0); + } + + rocketModel[i].startingPortNumber = nextLineNumber; + + for (aiop = 0; aiop < num_aiops; aiop++) { + sResetAiopByNum(ctlp, aiop); + sEnAiop(ctlp, aiop); + num_chan = sGetAiopNumChan(ctlp, aiop); + total_num_chan += num_chan; + for (chan = 0; chan < num_chan; chan++) + init_r_port(i, aiop, chan, NULL); + } + is_PCI[i] = 0; + if ((rcktpt_type[i] == ROCKET_TYPE_MODEM) || (rcktpt_type[i] == ROCKET_TYPE_MODEMII)) { + num_chan = sGetAiopNumChan(ctlp, 0); + total_num_chan = num_chan; + for (chan = 0; chan < num_chan; chan++) + sModemReset(ctlp, chan, 1); + msleep(500); + for (chan = 0; chan < num_chan; chan++) + sModemReset(ctlp, chan, 0); + msleep(500); + strcpy(rocketModel[i].modelString, "RocketModem ISA"); + } else { + strcpy(rocketModel[i].modelString, "RocketPort ISA"); + } + rocketModel[i].numPorts = total_num_chan; + rocketModel[i].model = MODEL_ISA; + + printk(KERN_INFO "RocketPort ISA card #%d found at 0x%lx - %d AIOPs %s\n", + i, rcktpt_io_addr[i], num_aiops, type_string); + + printk(KERN_INFO "Installing %s, creating /dev/ttyR%d - %ld\n", + rocketModel[i].modelString, + rocketModel[i].startingPortNumber, + rocketModel[i].startingPortNumber + + rocketModel[i].numPorts - 1); + + return (1); +} + +static const struct tty_operations rocket_ops = { + .open = rp_open, + .close = rp_close, + .write = rp_write, + .put_char = rp_put_char, + .write_room = rp_write_room, + .chars_in_buffer = rp_chars_in_buffer, + .flush_buffer = rp_flush_buffer, + .ioctl = rp_ioctl, + .throttle = rp_throttle, + .unthrottle = rp_unthrottle, + .set_termios = rp_set_termios, + .stop = rp_stop, + .start = rp_start, + .hangup = rp_hangup, + .break_ctl = rp_break, + .send_xchar = rp_send_xchar, + .wait_until_sent = rp_wait_until_sent, + .tiocmget = rp_tiocmget, + .tiocmset = rp_tiocmset, +}; + +static const struct tty_port_operations rocket_port_ops = { + .carrier_raised = carrier_raised, + .dtr_rts = dtr_rts, +}; + +/* + * The module "startup" routine; it's run when the module is loaded. + */ +static int __init rp_init(void) +{ + int ret = -ENOMEM, pci_boards_found, isa_boards_found, i; + + printk(KERN_INFO "RocketPort device driver module, version %s, %s\n", + ROCKET_VERSION, ROCKET_DATE); + + rocket_driver = alloc_tty_driver(MAX_RP_PORTS); + if (!rocket_driver) + goto err; + + /* + * If board 1 is non-zero, there is at least one ISA configured. If controller is + * zero, use the default controller IO address of board1 + 0x40. + */ + if (board1) { + if (controller == 0) + controller = board1 + 0x40; + } else { + controller = 0; /* Used as a flag, meaning no ISA boards */ + } + + /* If an ISA card is configured, reserve the 4 byte IO space for the Mudbac controller */ + if (controller && (!request_region(controller, 4, "Comtrol RocketPort"))) { + printk(KERN_ERR "Unable to reserve IO region for first " + "configured ISA RocketPort controller 0x%lx. " + "Driver exiting\n", controller); + ret = -EBUSY; + goto err_tty; + } + + /* Store ISA variable retrieved from command line or .conf file. */ + rcktpt_io_addr[0] = board1; + rcktpt_io_addr[1] = board2; + rcktpt_io_addr[2] = board3; + rcktpt_io_addr[3] = board4; + + rcktpt_type[0] = modem1 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL; + rcktpt_type[0] = pc104_1[0] ? ROCKET_TYPE_PC104 : rcktpt_type[0]; + rcktpt_type[1] = modem2 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL; + rcktpt_type[1] = pc104_2[0] ? ROCKET_TYPE_PC104 : rcktpt_type[1]; + rcktpt_type[2] = modem3 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL; + rcktpt_type[2] = pc104_3[0] ? ROCKET_TYPE_PC104 : rcktpt_type[2]; + rcktpt_type[3] = modem4 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL; + rcktpt_type[3] = pc104_4[0] ? ROCKET_TYPE_PC104 : rcktpt_type[3]; + + /* + * Set up the tty driver structure and then register this + * driver with the tty layer. + */ + + rocket_driver->owner = THIS_MODULE; + rocket_driver->flags = TTY_DRIVER_DYNAMIC_DEV; + rocket_driver->name = "ttyR"; + rocket_driver->driver_name = "Comtrol RocketPort"; + rocket_driver->major = TTY_ROCKET_MAJOR; + rocket_driver->minor_start = 0; + rocket_driver->type = TTY_DRIVER_TYPE_SERIAL; + rocket_driver->subtype = SERIAL_TYPE_NORMAL; + rocket_driver->init_termios = tty_std_termios; + rocket_driver->init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + rocket_driver->init_termios.c_ispeed = 9600; + rocket_driver->init_termios.c_ospeed = 9600; +#ifdef ROCKET_SOFT_FLOW + rocket_driver->flags |= TTY_DRIVER_REAL_RAW; +#endif + tty_set_operations(rocket_driver, &rocket_ops); + + ret = tty_register_driver(rocket_driver); + if (ret < 0) { + printk(KERN_ERR "Couldn't install tty RocketPort driver\n"); + goto err_controller; + } + +#ifdef ROCKET_DEBUG_OPEN + printk(KERN_INFO "RocketPort driver is major %d\n", rocket_driver.major); +#endif + + /* + * OK, let's probe each of the controllers looking for boards. Any boards found + * will be initialized here. + */ + isa_boards_found = 0; + pci_boards_found = 0; + + for (i = 0; i < NUM_BOARDS; i++) { + if (init_ISA(i)) + isa_boards_found++; + } + +#ifdef CONFIG_PCI + if (isa_boards_found < NUM_BOARDS) + pci_boards_found = init_PCI(isa_boards_found); +#endif + + max_board = pci_boards_found + isa_boards_found; + + if (max_board == 0) { + printk(KERN_ERR "No rocketport ports found; unloading driver\n"); + ret = -ENXIO; + goto err_ttyu; + } + + return 0; +err_ttyu: + tty_unregister_driver(rocket_driver); +err_controller: + if (controller) + release_region(controller, 4); +err_tty: + put_tty_driver(rocket_driver); +err: + return ret; +} + + +static void rp_cleanup_module(void) +{ + int retval; + int i; + + del_timer_sync(&rocket_timer); + + retval = tty_unregister_driver(rocket_driver); + if (retval) + printk(KERN_ERR "Error %d while trying to unregister " + "rocketport driver\n", -retval); + + for (i = 0; i < MAX_RP_PORTS; i++) + if (rp_table[i]) { + tty_unregister_device(rocket_driver, i); + kfree(rp_table[i]); + } + + put_tty_driver(rocket_driver); + + for (i = 0; i < NUM_BOARDS; i++) { + if (rcktpt_io_addr[i] <= 0 || is_PCI[i]) + continue; + release_region(rcktpt_io_addr[i], 64); + } + if (controller) + release_region(controller, 4); +} + +/*************************************************************************** +Function: sInitController +Purpose: Initialization of controller global registers and controller + structure. +Call: sInitController(CtlP,CtlNum,MudbacIO,AiopIOList,AiopIOListSize, + IRQNum,Frequency,PeriodicOnly) + CONTROLLER_T *CtlP; Ptr to controller structure + int CtlNum; Controller number + ByteIO_t MudbacIO; Mudbac base I/O address. + ByteIO_t *AiopIOList; List of I/O addresses for each AIOP. + This list must be in the order the AIOPs will be found on the + controller. Once an AIOP in the list is not found, it is + assumed that there are no more AIOPs on the controller. + int AiopIOListSize; Number of addresses in AiopIOList + int IRQNum; Interrupt Request number. Can be any of the following: + 0: Disable global interrupts + 3: IRQ 3 + 4: IRQ 4 + 5: IRQ 5 + 9: IRQ 9 + 10: IRQ 10 + 11: IRQ 11 + 12: IRQ 12 + 15: IRQ 15 + Byte_t Frequency: A flag identifying the frequency + of the periodic interrupt, can be any one of the following: + FREQ_DIS - periodic interrupt disabled + FREQ_137HZ - 137 Hertz + FREQ_69HZ - 69 Hertz + FREQ_34HZ - 34 Hertz + FREQ_17HZ - 17 Hertz + FREQ_9HZ - 9 Hertz + FREQ_4HZ - 4 Hertz + If IRQNum is set to 0 the Frequency parameter is + overidden, it is forced to a value of FREQ_DIS. + int PeriodicOnly: 1 if all interrupts except the periodic + interrupt are to be blocked. + 0 is both the periodic interrupt and + other channel interrupts are allowed. + If IRQNum is set to 0 the PeriodicOnly parameter is + overidden, it is forced to a value of 0. +Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller + initialization failed. + +Comments: + If periodic interrupts are to be disabled but AIOP interrupts + are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0. + + If interrupts are to be completely disabled set IRQNum to 0. + + Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an + invalid combination. + + This function performs initialization of global interrupt modes, + but it does not actually enable global interrupts. To enable + and disable global interrupts use functions sEnGlobalInt() and + sDisGlobalInt(). Enabling of global interrupts is normally not + done until all other initializations are complete. + + Even if interrupts are globally enabled, they must also be + individually enabled for each channel that is to generate + interrupts. + +Warnings: No range checking on any of the parameters is done. + + No context switches are allowed while executing this function. + + After this function all AIOPs on the controller are disabled, + they can be enabled with sEnAiop(). +*/ +static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, + ByteIO_t * AiopIOList, int AiopIOListSize, + int IRQNum, Byte_t Frequency, int PeriodicOnly) +{ + int i; + ByteIO_t io; + int done; + + CtlP->AiopIntrBits = aiop_intr_bits; + CtlP->AltChanRingIndicator = 0; + CtlP->CtlNum = CtlNum; + CtlP->CtlID = CTLID_0001; /* controller release 1 */ + CtlP->BusType = isISA; + CtlP->MBaseIO = MudbacIO; + CtlP->MReg1IO = MudbacIO + 1; + CtlP->MReg2IO = MudbacIO + 2; + CtlP->MReg3IO = MudbacIO + 3; +#if 1 + CtlP->MReg2 = 0; /* interrupt disable */ + CtlP->MReg3 = 0; /* no periodic interrupts */ +#else + if (sIRQMap[IRQNum] == 0) { /* interrupts globally disabled */ + CtlP->MReg2 = 0; /* interrupt disable */ + CtlP->MReg3 = 0; /* no periodic interrupts */ + } else { + CtlP->MReg2 = sIRQMap[IRQNum]; /* set IRQ number */ + CtlP->MReg3 = Frequency; /* set frequency */ + if (PeriodicOnly) { /* periodic interrupt only */ + CtlP->MReg3 |= PERIODIC_ONLY; + } + } +#endif + sOutB(CtlP->MReg2IO, CtlP->MReg2); + sOutB(CtlP->MReg3IO, CtlP->MReg3); + sControllerEOI(CtlP); /* clear EOI if warm init */ + /* Init AIOPs */ + CtlP->NumAiop = 0; + for (i = done = 0; i < AiopIOListSize; i++) { + io = AiopIOList[i]; + CtlP->AiopIO[i] = (WordIO_t) io; + CtlP->AiopIntChanIO[i] = io + _INT_CHAN; + sOutB(CtlP->MReg2IO, CtlP->MReg2 | (i & 0x03)); /* AIOP index */ + sOutB(MudbacIO, (Byte_t) (io >> 6)); /* set up AIOP I/O in MUDBAC */ + if (done) + continue; + sEnAiop(CtlP, i); /* enable the AIOP */ + CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */ + if (CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */ + done = 1; /* done looking for AIOPs */ + else { + CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */ + sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE); /* clock prescaler */ + sOutB(io + _INDX_DATA, sClockPrescale); + CtlP->NumAiop++; /* bump count of AIOPs */ + } + sDisAiop(CtlP, i); /* disable AIOP */ + } + + if (CtlP->NumAiop == 0) + return (-1); + else + return (CtlP->NumAiop); +} + +/*************************************************************************** +Function: sPCIInitController +Purpose: Initialization of controller global registers and controller + structure. +Call: sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize, + IRQNum,Frequency,PeriodicOnly) + CONTROLLER_T *CtlP; Ptr to controller structure + int CtlNum; Controller number + ByteIO_t *AiopIOList; List of I/O addresses for each AIOP. + This list must be in the order the AIOPs will be found on the + controller. Once an AIOP in the list is not found, it is + assumed that there are no more AIOPs on the controller. + int AiopIOListSize; Number of addresses in AiopIOList + int IRQNum; Interrupt Request number. Can be any of the following: + 0: Disable global interrupts + 3: IRQ 3 + 4: IRQ 4 + 5: IRQ 5 + 9: IRQ 9 + 10: IRQ 10 + 11: IRQ 11 + 12: IRQ 12 + 15: IRQ 15 + Byte_t Frequency: A flag identifying the frequency + of the periodic interrupt, can be any one of the following: + FREQ_DIS - periodic interrupt disabled + FREQ_137HZ - 137 Hertz + FREQ_69HZ - 69 Hertz + FREQ_34HZ - 34 Hertz + FREQ_17HZ - 17 Hertz + FREQ_9HZ - 9 Hertz + FREQ_4HZ - 4 Hertz + If IRQNum is set to 0 the Frequency parameter is + overidden, it is forced to a value of FREQ_DIS. + int PeriodicOnly: 1 if all interrupts except the periodic + interrupt are to be blocked. + 0 is both the periodic interrupt and + other channel interrupts are allowed. + If IRQNum is set to 0 the PeriodicOnly parameter is + overidden, it is forced to a value of 0. +Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller + initialization failed. + +Comments: + If periodic interrupts are to be disabled but AIOP interrupts + are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0. + + If interrupts are to be completely disabled set IRQNum to 0. + + Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an + invalid combination. + + This function performs initialization of global interrupt modes, + but it does not actually enable global interrupts. To enable + and disable global interrupts use functions sEnGlobalInt() and + sDisGlobalInt(). Enabling of global interrupts is normally not + done until all other initializations are complete. + + Even if interrupts are globally enabled, they must also be + individually enabled for each channel that is to generate + interrupts. + +Warnings: No range checking on any of the parameters is done. + + No context switches are allowed while executing this function. + + After this function all AIOPs on the controller are disabled, + they can be enabled with sEnAiop(). +*/ +static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, + ByteIO_t * AiopIOList, int AiopIOListSize, + WordIO_t ConfigIO, int IRQNum, Byte_t Frequency, + int PeriodicOnly, int altChanRingIndicator, + int UPCIRingInd) +{ + int i; + ByteIO_t io; + + CtlP->AltChanRingIndicator = altChanRingIndicator; + CtlP->UPCIRingInd = UPCIRingInd; + CtlP->CtlNum = CtlNum; + CtlP->CtlID = CTLID_0001; /* controller release 1 */ + CtlP->BusType = isPCI; /* controller release 1 */ + + if (ConfigIO) { + CtlP->isUPCI = 1; + CtlP->PCIIO = ConfigIO + _PCI_9030_INT_CTRL; + CtlP->PCIIO2 = ConfigIO + _PCI_9030_GPIO_CTRL; + CtlP->AiopIntrBits = upci_aiop_intr_bits; + } else { + CtlP->isUPCI = 0; + CtlP->PCIIO = + (WordIO_t) ((ByteIO_t) AiopIOList[0] + _PCI_INT_FUNC); + CtlP->AiopIntrBits = aiop_intr_bits; + } + + sPCIControllerEOI(CtlP); /* clear EOI if warm init */ + /* Init AIOPs */ + CtlP->NumAiop = 0; + for (i = 0; i < AiopIOListSize; i++) { + io = AiopIOList[i]; + CtlP->AiopIO[i] = (WordIO_t) io; + CtlP->AiopIntChanIO[i] = io + _INT_CHAN; + + CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */ + if (CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */ + break; /* done looking for AIOPs */ + + CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */ + sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE); /* clock prescaler */ + sOutB(io + _INDX_DATA, sClockPrescale); + CtlP->NumAiop++; /* bump count of AIOPs */ + } + + if (CtlP->NumAiop == 0) + return (-1); + else + return (CtlP->NumAiop); +} + +/*************************************************************************** +Function: sReadAiopID +Purpose: Read the AIOP idenfication number directly from an AIOP. +Call: sReadAiopID(io) + ByteIO_t io: AIOP base I/O address +Return: int: Flag AIOPID_XXXX if a valid AIOP is found, where X + is replace by an identifying number. + Flag AIOPID_NULL if no valid AIOP is found +Warnings: No context switches are allowed while executing this function. + +*/ +static int sReadAiopID(ByteIO_t io) +{ + Byte_t AiopID; /* ID byte from AIOP */ + + sOutB(io + _CMD_REG, RESET_ALL); /* reset AIOP */ + sOutB(io + _CMD_REG, 0x0); + AiopID = sInW(io + _CHN_STAT0) & 0x07; + if (AiopID == 0x06) + return (1); + else /* AIOP does not exist */ + return (-1); +} + +/*************************************************************************** +Function: sReadAiopNumChan +Purpose: Read the number of channels available in an AIOP directly from + an AIOP. +Call: sReadAiopNumChan(io) + WordIO_t io: AIOP base I/O address +Return: int: The number of channels available +Comments: The number of channels is determined by write/reads from identical + offsets within the SRAM address spaces for channels 0 and 4. + If the channel 4 space is mirrored to channel 0 it is a 4 channel + AIOP, otherwise it is an 8 channel. +Warnings: No context switches are allowed while executing this function. +*/ +static int sReadAiopNumChan(WordIO_t io) +{ + Word_t x; + static Byte_t R[4] = { 0x00, 0x00, 0x34, 0x12 }; + + /* write to chan 0 SRAM */ + out32((DWordIO_t) io + _INDX_ADDR, R); + sOutW(io + _INDX_ADDR, 0); /* read from SRAM, chan 0 */ + x = sInW(io + _INDX_DATA); + sOutW(io + _INDX_ADDR, 0x4000); /* read from SRAM, chan 4 */ + if (x != sInW(io + _INDX_DATA)) /* if different must be 8 chan */ + return (8); + else + return (4); +} + +/*************************************************************************** +Function: sInitChan +Purpose: Initialization of a channel and channel structure +Call: sInitChan(CtlP,ChP,AiopNum,ChanNum) + CONTROLLER_T *CtlP; Ptr to controller structure + CHANNEL_T *ChP; Ptr to channel structure + int AiopNum; AIOP number within controller + int ChanNum; Channel number within AIOP +Return: int: 1 if initialization succeeded, 0 if it fails because channel + number exceeds number of channels available in AIOP. +Comments: This function must be called before a channel can be used. +Warnings: No range checking on any of the parameters is done. + + No context switches are allowed while executing this function. +*/ +static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum, + int ChanNum) +{ + int i; + WordIO_t AiopIO; + WordIO_t ChIOOff; + Byte_t *ChR; + Word_t ChOff; + static Byte_t R[4]; + int brd9600; + + if (ChanNum >= CtlP->AiopNumChan[AiopNum]) + return 0; /* exceeds num chans in AIOP */ + + /* Channel, AIOP, and controller identifiers */ + ChP->CtlP = CtlP; + ChP->ChanID = CtlP->AiopID[AiopNum]; + ChP->AiopNum = AiopNum; + ChP->ChanNum = ChanNum; + + /* Global direct addresses */ + AiopIO = CtlP->AiopIO[AiopNum]; + ChP->Cmd = (ByteIO_t) AiopIO + _CMD_REG; + ChP->IntChan = (ByteIO_t) AiopIO + _INT_CHAN; + ChP->IntMask = (ByteIO_t) AiopIO + _INT_MASK; + ChP->IndexAddr = (DWordIO_t) AiopIO + _INDX_ADDR; + ChP->IndexData = AiopIO + _INDX_DATA; + + /* Channel direct addresses */ + ChIOOff = AiopIO + ChP->ChanNum * 2; + ChP->TxRxData = ChIOOff + _TD0; + ChP->ChanStat = ChIOOff + _CHN_STAT0; + ChP->TxRxCount = ChIOOff + _FIFO_CNT0; + ChP->IntID = (ByteIO_t) AiopIO + ChP->ChanNum + _INT_ID0; + + /* Initialize the channel from the RData array */ + for (i = 0; i < RDATASIZE; i += 4) { + R[0] = RData[i]; + R[1] = RData[i + 1] + 0x10 * ChanNum; + R[2] = RData[i + 2]; + R[3] = RData[i + 3]; + out32(ChP->IndexAddr, R); + } + + ChR = ChP->R; + for (i = 0; i < RREGDATASIZE; i += 4) { + ChR[i] = RRegData[i]; + ChR[i + 1] = RRegData[i + 1] + 0x10 * ChanNum; + ChR[i + 2] = RRegData[i + 2]; + ChR[i + 3] = RRegData[i + 3]; + } + + /* Indexed registers */ + ChOff = (Word_t) ChanNum *0x1000; + + if (sClockPrescale == 0x14) + brd9600 = 47; + else + brd9600 = 23; + + ChP->BaudDiv[0] = (Byte_t) (ChOff + _BAUD); + ChP->BaudDiv[1] = (Byte_t) ((ChOff + _BAUD) >> 8); + ChP->BaudDiv[2] = (Byte_t) brd9600; + ChP->BaudDiv[3] = (Byte_t) (brd9600 >> 8); + out32(ChP->IndexAddr, ChP->BaudDiv); + + ChP->TxControl[0] = (Byte_t) (ChOff + _TX_CTRL); + ChP->TxControl[1] = (Byte_t) ((ChOff + _TX_CTRL) >> 8); + ChP->TxControl[2] = 0; + ChP->TxControl[3] = 0; + out32(ChP->IndexAddr, ChP->TxControl); + + ChP->RxControl[0] = (Byte_t) (ChOff + _RX_CTRL); + ChP->RxControl[1] = (Byte_t) ((ChOff + _RX_CTRL) >> 8); + ChP->RxControl[2] = 0; + ChP->RxControl[3] = 0; + out32(ChP->IndexAddr, ChP->RxControl); + + ChP->TxEnables[0] = (Byte_t) (ChOff + _TX_ENBLS); + ChP->TxEnables[1] = (Byte_t) ((ChOff + _TX_ENBLS) >> 8); + ChP->TxEnables[2] = 0; + ChP->TxEnables[3] = 0; + out32(ChP->IndexAddr, ChP->TxEnables); + + ChP->TxCompare[0] = (Byte_t) (ChOff + _TXCMP1); + ChP->TxCompare[1] = (Byte_t) ((ChOff + _TXCMP1) >> 8); + ChP->TxCompare[2] = 0; + ChP->TxCompare[3] = 0; + out32(ChP->IndexAddr, ChP->TxCompare); + + ChP->TxReplace1[0] = (Byte_t) (ChOff + _TXREP1B1); + ChP->TxReplace1[1] = (Byte_t) ((ChOff + _TXREP1B1) >> 8); + ChP->TxReplace1[2] = 0; + ChP->TxReplace1[3] = 0; + out32(ChP->IndexAddr, ChP->TxReplace1); + + ChP->TxReplace2[0] = (Byte_t) (ChOff + _TXREP2); + ChP->TxReplace2[1] = (Byte_t) ((ChOff + _TXREP2) >> 8); + ChP->TxReplace2[2] = 0; + ChP->TxReplace2[3] = 0; + out32(ChP->IndexAddr, ChP->TxReplace2); + + ChP->TxFIFOPtrs = ChOff + _TXF_OUTP; + ChP->TxFIFO = ChOff + _TX_FIFO; + + sOutB(ChP->Cmd, (Byte_t) ChanNum | RESTXFCNT); /* apply reset Tx FIFO count */ + sOutB(ChP->Cmd, (Byte_t) ChanNum); /* remove reset Tx FIFO count */ + sOutW((WordIO_t) ChP->IndexAddr, ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */ + sOutW(ChP->IndexData, 0); + ChP->RxFIFOPtrs = ChOff + _RXF_OUTP; + ChP->RxFIFO = ChOff + _RX_FIFO; + + sOutB(ChP->Cmd, (Byte_t) ChanNum | RESRXFCNT); /* apply reset Rx FIFO count */ + sOutB(ChP->Cmd, (Byte_t) ChanNum); /* remove reset Rx FIFO count */ + sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs); /* clear Rx out ptr */ + sOutW(ChP->IndexData, 0); + sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */ + sOutW(ChP->IndexData, 0); + ChP->TxPrioCnt = ChOff + _TXP_CNT; + sOutW((WordIO_t) ChP->IndexAddr, ChP->TxPrioCnt); + sOutB(ChP->IndexData, 0); + ChP->TxPrioPtr = ChOff + _TXP_PNTR; + sOutW((WordIO_t) ChP->IndexAddr, ChP->TxPrioPtr); + sOutB(ChP->IndexData, 0); + ChP->TxPrioBuf = ChOff + _TXP_BUF; + sEnRxProcessor(ChP); /* start the Rx processor */ + + return 1; +} + +/*************************************************************************** +Function: sStopRxProcessor +Purpose: Stop the receive processor from processing a channel. +Call: sStopRxProcessor(ChP) + CHANNEL_T *ChP; Ptr to channel structure + +Comments: The receive processor can be started again with sStartRxProcessor(). + This function causes the receive processor to skip over the + stopped channel. It does not stop it from processing other channels. + +Warnings: No context switches are allowed while executing this function. + + Do not leave the receive processor stopped for more than one + character time. + + After calling this function a delay of 4 uS is required to ensure + that the receive processor is no longer processing this channel. +*/ +static void sStopRxProcessor(CHANNEL_T * ChP) +{ + Byte_t R[4]; + + R[0] = ChP->R[0]; + R[1] = ChP->R[1]; + R[2] = 0x0a; + R[3] = ChP->R[3]; + out32(ChP->IndexAddr, R); +} + +/*************************************************************************** +Function: sFlushRxFIFO +Purpose: Flush the Rx FIFO +Call: sFlushRxFIFO(ChP) + CHANNEL_T *ChP; Ptr to channel structure +Return: void +Comments: To prevent data from being enqueued or dequeued in the Tx FIFO + while it is being flushed the receive processor is stopped + and the transmitter is disabled. After these operations a + 4 uS delay is done before clearing the pointers to allow + the receive processor to stop. These items are handled inside + this function. +Warnings: No context switches are allowed while executing this function. +*/ +static void sFlushRxFIFO(CHANNEL_T * ChP) +{ + int i; + Byte_t Ch; /* channel number within AIOP */ + int RxFIFOEnabled; /* 1 if Rx FIFO enabled */ + + if (sGetRxCnt(ChP) == 0) /* Rx FIFO empty */ + return; /* don't need to flush */ + + RxFIFOEnabled = 0; + if (ChP->R[0x32] == 0x08) { /* Rx FIFO is enabled */ + RxFIFOEnabled = 1; + sDisRxFIFO(ChP); /* disable it */ + for (i = 0; i < 2000 / 200; i++) /* delay 2 uS to allow proc to disable FIFO */ + sInB(ChP->IntChan); /* depends on bus i/o timing */ + } + sGetChanStatus(ChP); /* clear any pending Rx errors in chan stat */ + Ch = (Byte_t) sGetChanNum(ChP); + sOutB(ChP->Cmd, Ch | RESRXFCNT); /* apply reset Rx FIFO count */ + sOutB(ChP->Cmd, Ch); /* remove reset Rx FIFO count */ + sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs); /* clear Rx out ptr */ + sOutW(ChP->IndexData, 0); + sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */ + sOutW(ChP->IndexData, 0); + if (RxFIFOEnabled) + sEnRxFIFO(ChP); /* enable Rx FIFO */ +} + +/*************************************************************************** +Function: sFlushTxFIFO +Purpose: Flush the Tx FIFO +Call: sFlushTxFIFO(ChP) + CHANNEL_T *ChP; Ptr to channel structure +Return: void +Comments: To prevent data from being enqueued or dequeued in the Tx FIFO + while it is being flushed the receive processor is stopped + and the transmitter is disabled. After these operations a + 4 uS delay is done before clearing the pointers to allow + the receive processor to stop. These items are handled inside + this function. +Warnings: No context switches are allowed while executing this function. +*/ +static void sFlushTxFIFO(CHANNEL_T * ChP) +{ + int i; + Byte_t Ch; /* channel number within AIOP */ + int TxEnabled; /* 1 if transmitter enabled */ + + if (sGetTxCnt(ChP) == 0) /* Tx FIFO empty */ + return; /* don't need to flush */ + + TxEnabled = 0; + if (ChP->TxControl[3] & TX_ENABLE) { + TxEnabled = 1; + sDisTransmit(ChP); /* disable transmitter */ + } + sStopRxProcessor(ChP); /* stop Rx processor */ + for (i = 0; i < 4000 / 200; i++) /* delay 4 uS to allow proc to stop */ + sInB(ChP->IntChan); /* depends on bus i/o timing */ + Ch = (Byte_t) sGetChanNum(ChP); + sOutB(ChP->Cmd, Ch | RESTXFCNT); /* apply reset Tx FIFO count */ + sOutB(ChP->Cmd, Ch); /* remove reset Tx FIFO count */ + sOutW((WordIO_t) ChP->IndexAddr, ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */ + sOutW(ChP->IndexData, 0); + if (TxEnabled) + sEnTransmit(ChP); /* enable transmitter */ + sStartRxProcessor(ChP); /* restart Rx processor */ +} + +/*************************************************************************** +Function: sWriteTxPrioByte +Purpose: Write a byte of priority transmit data to a channel +Call: sWriteTxPrioByte(ChP,Data) + CHANNEL_T *ChP; Ptr to channel structure + Byte_t Data; The transmit data byte + +Return: int: 1 if the bytes is successfully written, otherwise 0. + +Comments: The priority byte is transmitted before any data in the Tx FIFO. + +Warnings: No context switches are allowed while executing this function. +*/ +static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data) +{ + Byte_t DWBuf[4]; /* buffer for double word writes */ + Word_t *WordPtr; /* must be far because Win SS != DS */ + register DWordIO_t IndexAddr; + + if (sGetTxCnt(ChP) > 1) { /* write it to Tx priority buffer */ + IndexAddr = ChP->IndexAddr; + sOutW((WordIO_t) IndexAddr, ChP->TxPrioCnt); /* get priority buffer status */ + if (sInB((ByteIO_t) ChP->IndexData) & PRI_PEND) /* priority buffer busy */ + return (0); /* nothing sent */ + + WordPtr = (Word_t *) (&DWBuf[0]); + *WordPtr = ChP->TxPrioBuf; /* data byte address */ + + DWBuf[2] = Data; /* data byte value */ + out32(IndexAddr, DWBuf); /* write it out */ + + *WordPtr = ChP->TxPrioCnt; /* Tx priority count address */ + + DWBuf[2] = PRI_PEND + 1; /* indicate 1 byte pending */ + DWBuf[3] = 0; /* priority buffer pointer */ + out32(IndexAddr, DWBuf); /* write it out */ + } else { /* write it to Tx FIFO */ + + sWriteTxByte(sGetTxRxDataIO(ChP), Data); + } + return (1); /* 1 byte sent */ +} + +/*************************************************************************** +Function: sEnInterrupts +Purpose: Enable one or more interrupts for a channel +Call: sEnInterrupts(ChP,Flags) + CHANNEL_T *ChP; Ptr to channel structure + Word_t Flags: Interrupt enable flags, can be any combination + of the following flags: + TXINT_EN: Interrupt on Tx FIFO empty + RXINT_EN: Interrupt on Rx FIFO at trigger level (see + sSetRxTrigger()) + SRCINT_EN: Interrupt on SRC (Special Rx Condition) + MCINT_EN: Interrupt on modem input change + CHANINT_EN: Allow channel interrupt signal to the AIOP's + Interrupt Channel Register. +Return: void +Comments: If an interrupt enable flag is set in Flags, that interrupt will be + enabled. If an interrupt enable flag is not set in Flags, that + interrupt will not be changed. Interrupts can be disabled with + function sDisInterrupts(). + + This function sets the appropriate bit for the channel in the AIOP's + Interrupt Mask Register if the CHANINT_EN flag is set. This allows + this channel's bit to be set in the AIOP's Interrupt Channel Register. + + Interrupts must also be globally enabled before channel interrupts + will be passed on to the host. This is done with function + sEnGlobalInt(). + + In some cases it may be desirable to disable interrupts globally but + enable channel interrupts. This would allow the global interrupt + status register to be used to determine which AIOPs need service. +*/ +static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags) +{ + Byte_t Mask; /* Interrupt Mask Register */ + + ChP->RxControl[2] |= + ((Byte_t) Flags & (RXINT_EN | SRCINT_EN | MCINT_EN)); + + out32(ChP->IndexAddr, ChP->RxControl); + + ChP->TxControl[2] |= ((Byte_t) Flags & TXINT_EN); + + out32(ChP->IndexAddr, ChP->TxControl); + + if (Flags & CHANINT_EN) { + Mask = sInB(ChP->IntMask) | sBitMapSetTbl[ChP->ChanNum]; + sOutB(ChP->IntMask, Mask); + } +} + +/*************************************************************************** +Function: sDisInterrupts +Purpose: Disable one or more interrupts for a channel +Call: sDisInterrupts(ChP,Flags) + CHANNEL_T *ChP; Ptr to channel structure + Word_t Flags: Interrupt flags, can be any combination + of the following flags: + TXINT_EN: Interrupt on Tx FIFO empty + RXINT_EN: Interrupt on Rx FIFO at trigger level (see + sSetRxTrigger()) + SRCINT_EN: Interrupt on SRC (Special Rx Condition) + MCINT_EN: Interrupt on modem input change + CHANINT_EN: Disable channel interrupt signal to the + AIOP's Interrupt Channel Register. +Return: void +Comments: If an interrupt flag is set in Flags, that interrupt will be + disabled. If an interrupt flag is not set in Flags, that + interrupt will not be changed. Interrupts can be enabled with + function sEnInterrupts(). + + This function clears the appropriate bit for the channel in the AIOP's + Interrupt Mask Register if the CHANINT_EN flag is set. This blocks + this channel's bit from being set in the AIOP's Interrupt Channel + Register. +*/ +static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags) +{ + Byte_t Mask; /* Interrupt Mask Register */ + + ChP->RxControl[2] &= + ~((Byte_t) Flags & (RXINT_EN | SRCINT_EN | MCINT_EN)); + out32(ChP->IndexAddr, ChP->RxControl); + ChP->TxControl[2] &= ~((Byte_t) Flags & TXINT_EN); + out32(ChP->IndexAddr, ChP->TxControl); + + if (Flags & CHANINT_EN) { + Mask = sInB(ChP->IntMask) & sBitMapClrTbl[ChP->ChanNum]; + sOutB(ChP->IntMask, Mask); + } +} + +static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode) +{ + sOutB(ChP->CtlP->AiopIO[2], (mode & 0x18) | ChP->ChanNum); +} + +/* + * Not an official SSCI function, but how to reset RocketModems. + * ISA bus version + */ +static void sModemReset(CONTROLLER_T * CtlP, int chan, int on) +{ + ByteIO_t addr; + Byte_t val; + + addr = CtlP->AiopIO[0] + 0x400; + val = sInB(CtlP->MReg3IO); + /* if AIOP[1] is not enabled, enable it */ + if ((val & 2) == 0) { + val = sInB(CtlP->MReg2IO); + sOutB(CtlP->MReg2IO, (val & 0xfc) | (1 & 0x03)); + sOutB(CtlP->MBaseIO, (unsigned char) (addr >> 6)); + } + + sEnAiop(CtlP, 1); + if (!on) + addr += 8; + sOutB(addr + chan, 0); /* apply or remove reset */ + sDisAiop(CtlP, 1); +} + +/* + * Not an official SSCI function, but how to reset RocketModems. + * PCI bus version + */ +static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on) +{ + ByteIO_t addr; + + addr = CtlP->AiopIO[0] + 0x40; /* 2nd AIOP */ + if (!on) + addr += 8; + sOutB(addr + chan, 0); /* apply or remove reset */ +} + +/* Resets the speaker controller on RocketModem II and III devices */ +static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model) +{ + ByteIO_t addr; + + /* RocketModem II speaker control is at the 8th port location of offset 0x40 */ + if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) { + addr = CtlP->AiopIO[0] + 0x4F; + sOutB(addr, 0); + } + + /* RocketModem III speaker control is at the 1st port location of offset 0x80 */ + if ((model == MODEL_UPCI_RM3_8PORT) + || (model == MODEL_UPCI_RM3_4PORT)) { + addr = CtlP->AiopIO[0] + 0x88; + sOutB(addr, 0); + } +} + +/* Returns the line number given the controller (board), aiop and channel number */ +static unsigned char GetLineNumber(int ctrl, int aiop, int ch) +{ + return lineNumbers[(ctrl << 5) | (aiop << 3) | ch]; +} + +/* + * Stores the line number associated with a given controller (board), aiop + * and channel number. + * Returns: The line number assigned + */ +static unsigned char SetLineNumber(int ctrl, int aiop, int ch) +{ + lineNumbers[(ctrl << 5) | (aiop << 3) | ch] = nextLineNumber++; + return (nextLineNumber - 1); +} diff --git a/drivers/tty/rocket.h b/drivers/tty/rocket.h new file mode 100644 index 000000000000..ec863f35f1a9 --- /dev/null +++ b/drivers/tty/rocket.h @@ -0,0 +1,111 @@ +/* + * rocket.h --- the exported interface of the rocket driver to its configuration program. + * + * Written by Theodore Ts'o, Copyright 1997. + * Copyright 1997 Comtrol Corporation. + * + */ + +/* Model Information Struct */ +typedef struct { + unsigned long model; + char modelString[80]; + unsigned long numPorts; + int loadrm2; + int startingPortNumber; +} rocketModel_t; + +struct rocket_config { + int line; + int flags; + int closing_wait; + int close_delay; + int port; + int reserved[32]; +}; + +struct rocket_ports { + int tty_major; + int callout_major; + rocketModel_t rocketModel[8]; +}; + +struct rocket_version { + char rocket_version[32]; + char rocket_date[32]; + char reserved[64]; +}; + +/* + * Rocketport flags + */ +/*#define ROCKET_CALLOUT_NOHUP 0x00000001 */ +#define ROCKET_FORCE_CD 0x00000002 +#define ROCKET_HUP_NOTIFY 0x00000004 +#define ROCKET_SPLIT_TERMIOS 0x00000008 +#define ROCKET_SPD_MASK 0x00000070 +#define ROCKET_SPD_HI 0x00000010 /* Use 56000 instead of 38400 bps */ +#define ROCKET_SPD_VHI 0x00000020 /* Use 115200 instead of 38400 bps */ +#define ROCKET_SPD_SHI 0x00000030 /* Use 230400 instead of 38400 bps */ +#define ROCKET_SPD_WARP 0x00000040 /* Use 460800 instead of 38400 bps */ +#define ROCKET_SAK 0x00000080 +#define ROCKET_SESSION_LOCKOUT 0x00000100 +#define ROCKET_PGRP_LOCKOUT 0x00000200 +#define ROCKET_RTS_TOGGLE 0x00000400 +#define ROCKET_MODE_MASK 0x00003000 +#define ROCKET_MODE_RS232 0x00000000 +#define ROCKET_MODE_RS485 0x00001000 +#define ROCKET_MODE_RS422 0x00002000 +#define ROCKET_FLAGS 0x00003FFF + +#define ROCKET_USR_MASK 0x0071 /* Legal flags that non-privileged + * users can set or reset */ + +/* + * For closing_wait and closing_wait2 + */ +#define ROCKET_CLOSING_WAIT_NONE ASYNC_CLOSING_WAIT_NONE +#define ROCKET_CLOSING_WAIT_INF ASYNC_CLOSING_WAIT_INF + +/* + * Rocketport ioctls -- "RP" + */ +#define RCKP_GET_STRUCT 0x00525001 +#define RCKP_GET_CONFIG 0x00525002 +#define RCKP_SET_CONFIG 0x00525003 +#define RCKP_GET_PORTS 0x00525004 +#define RCKP_RESET_RM2 0x00525005 +#define RCKP_GET_VERSION 0x00525006 + +/* Rocketport Models */ +#define MODEL_RP32INTF 0x0001 /* RP 32 port w/external I/F */ +#define MODEL_RP8INTF 0x0002 /* RP 8 port w/external I/F */ +#define MODEL_RP16INTF 0x0003 /* RP 16 port w/external I/F */ +#define MODEL_RP8OCTA 0x0005 /* RP 8 port w/octa cable */ +#define MODEL_RP4QUAD 0x0004 /* RP 4 port w/quad cable */ +#define MODEL_RP8J 0x0006 /* RP 8 port w/RJ11 connectors */ +#define MODEL_RP4J 0x0007 /* RP 4 port w/RJ45 connectors */ +#define MODEL_RP8SNI 0x0008 /* RP 8 port w/ DB78 SNI connector */ +#define MODEL_RP16SNI 0x0009 /* RP 16 port w/ DB78 SNI connector */ +#define MODEL_RPP4 0x000A /* RP Plus 4 port */ +#define MODEL_RPP8 0x000B /* RP Plus 8 port */ +#define MODEL_RP2_232 0x000E /* RP Plus 2 port RS232 */ +#define MODEL_RP2_422 0x000F /* RP Plus 2 port RS232 */ + +/* Rocketmodem II Models */ +#define MODEL_RP6M 0x000C /* RM 6 port */ +#define MODEL_RP4M 0x000D /* RM 4 port */ + +/* Universal PCI boards */ +#define MODEL_UPCI_RP32INTF 0x0801 /* RP UPCI 32 port w/external I/F */ +#define MODEL_UPCI_RP8INTF 0x0802 /* RP UPCI 8 port w/external I/F */ +#define MODEL_UPCI_RP16INTF 0x0803 /* RP UPCI 16 port w/external I/F */ +#define MODEL_UPCI_RP8OCTA 0x0805 /* RP UPCI 8 port w/octa cable */ +#define MODEL_UPCI_RM3_8PORT 0x080C /* RP UPCI Rocketmodem III 8 port */ +#define MODEL_UPCI_RM3_4PORT 0x080C /* RP UPCI Rocketmodem III 4 port */ + +/* Compact PCI 16 port */ +#define MODEL_CPCI_RP16INTF 0x0903 /* RP Compact PCI 16 port w/external I/F */ + +/* All ISA boards */ +#define MODEL_ISA 0x1000 diff --git a/drivers/tty/rocket_int.h b/drivers/tty/rocket_int.h new file mode 100644 index 000000000000..67e0f1e778a2 --- /dev/null +++ b/drivers/tty/rocket_int.h @@ -0,0 +1,1214 @@ +/* + * rocket_int.h --- internal header file for rocket.c + * + * Written by Theodore Ts'o, Copyright 1997. + * Copyright 1997 Comtrol Corporation. + * + */ + +/* + * Definition of the types in rcktpt_type + */ +#define ROCKET_TYPE_NORMAL 0 +#define ROCKET_TYPE_MODEM 1 +#define ROCKET_TYPE_MODEMII 2 +#define ROCKET_TYPE_MODEMIII 3 +#define ROCKET_TYPE_PC104 4 + +#include + +#include +#include + +typedef unsigned char Byte_t; +typedef unsigned int ByteIO_t; + +typedef unsigned int Word_t; +typedef unsigned int WordIO_t; + +typedef unsigned int DWordIO_t; + +/* + * Note! Normally the Linux I/O macros already take care of + * byte-swapping the I/O instructions. However, all accesses using + * sOutDW aren't really 32-bit accesses, but should be handled in byte + * order. Hence the use of the cpu_to_le32() macro to byte-swap + * things to no-op the byte swapping done by the big-endian outl() + * instruction. + */ + +static inline void sOutB(unsigned short port, unsigned char value) +{ +#ifdef ROCKET_DEBUG_IO + printk(KERN_DEBUG "sOutB(%x, %x)...\n", port, value); +#endif + outb_p(value, port); +} + +static inline void sOutW(unsigned short port, unsigned short value) +{ +#ifdef ROCKET_DEBUG_IO + printk(KERN_DEBUG "sOutW(%x, %x)...\n", port, value); +#endif + outw_p(value, port); +} + +static inline void out32(unsigned short port, Byte_t *p) +{ + u32 value = get_unaligned_le32(p); +#ifdef ROCKET_DEBUG_IO + printk(KERN_DEBUG "out32(%x, %lx)...\n", port, value); +#endif + outl_p(value, port); +} + +static inline unsigned char sInB(unsigned short port) +{ + return inb_p(port); +} + +static inline unsigned short sInW(unsigned short port) +{ + return inw_p(port); +} + +/* This is used to move arrays of bytes so byte swapping isn't appropriate. */ +#define sOutStrW(port, addr, count) if (count) outsw(port, addr, count) +#define sInStrW(port, addr, count) if (count) insw(port, addr, count) + +#define CTL_SIZE 8 +#define AIOP_CTL_SIZE 4 +#define CHAN_AIOP_SIZE 8 +#define MAX_PORTS_PER_AIOP 8 +#define MAX_AIOPS_PER_BOARD 4 +#define MAX_PORTS_PER_BOARD 32 + +/* Bus type ID */ +#define isISA 0 +#define isPCI 1 +#define isMC 2 + +/* Controller ID numbers */ +#define CTLID_NULL -1 /* no controller exists */ +#define CTLID_0001 0x0001 /* controller release 1 */ + +/* AIOP ID numbers, identifies AIOP type implementing channel */ +#define AIOPID_NULL -1 /* no AIOP or channel exists */ +#define AIOPID_0001 0x0001 /* AIOP release 1 */ + +/************************************************************************ + Global Register Offsets - Direct Access - Fixed values +************************************************************************/ + +#define _CMD_REG 0x38 /* Command Register 8 Write */ +#define _INT_CHAN 0x39 /* Interrupt Channel Register 8 Read */ +#define _INT_MASK 0x3A /* Interrupt Mask Register 8 Read / Write */ +#define _UNUSED 0x3B /* Unused 8 */ +#define _INDX_ADDR 0x3C /* Index Register Address 16 Write */ +#define _INDX_DATA 0x3E /* Index Register Data 8/16 Read / Write */ + +/************************************************************************ + Channel Register Offsets for 1st channel in AIOP - Direct Access +************************************************************************/ +#define _TD0 0x00 /* Transmit Data 16 Write */ +#define _RD0 0x00 /* Receive Data 16 Read */ +#define _CHN_STAT0 0x20 /* Channel Status 8/16 Read / Write */ +#define _FIFO_CNT0 0x10 /* Transmit/Receive FIFO Count 16 Read */ +#define _INT_ID0 0x30 /* Interrupt Identification 8 Read */ + +/************************************************************************ + Tx Control Register Offsets - Indexed - External - Fixed +************************************************************************/ +#define _TX_ENBLS 0x980 /* Tx Processor Enables Register 8 Read / Write */ +#define _TXCMP1 0x988 /* Transmit Compare Value #1 8 Read / Write */ +#define _TXCMP2 0x989 /* Transmit Compare Value #2 8 Read / Write */ +#define _TXREP1B1 0x98A /* Tx Replace Value #1 - Byte 1 8 Read / Write */ +#define _TXREP1B2 0x98B /* Tx Replace Value #1 - Byte 2 8 Read / Write */ +#define _TXREP2 0x98C /* Transmit Replace Value #2 8 Read / Write */ + +/************************************************************************ +Memory Controller Register Offsets - Indexed - External - Fixed +************************************************************************/ +#define _RX_FIFO 0x000 /* Rx FIFO */ +#define _TX_FIFO 0x800 /* Tx FIFO */ +#define _RXF_OUTP 0x990 /* Rx FIFO OUT pointer 16 Read / Write */ +#define _RXF_INP 0x992 /* Rx FIFO IN pointer 16 Read / Write */ +#define _TXF_OUTP 0x994 /* Tx FIFO OUT pointer 8 Read / Write */ +#define _TXF_INP 0x995 /* Tx FIFO IN pointer 8 Read / Write */ +#define _TXP_CNT 0x996 /* Tx Priority Count 8 Read / Write */ +#define _TXP_PNTR 0x997 /* Tx Priority Pointer 8 Read / Write */ + +#define PRI_PEND 0x80 /* Priority data pending (bit7, Tx pri cnt) */ +#define TXFIFO_SIZE 255 /* size of Tx FIFO */ +#define RXFIFO_SIZE 1023 /* size of Rx FIFO */ + +/************************************************************************ +Tx Priority Buffer - Indexed - External - Fixed +************************************************************************/ +#define _TXP_BUF 0x9C0 /* Tx Priority Buffer 32 Bytes Read / Write */ +#define TXP_SIZE 0x20 /* 32 bytes */ + +/************************************************************************ +Channel Register Offsets - Indexed - Internal - Fixed +************************************************************************/ + +#define _TX_CTRL 0xFF0 /* Transmit Control 16 Write */ +#define _RX_CTRL 0xFF2 /* Receive Control 8 Write */ +#define _BAUD 0xFF4 /* Baud Rate 16 Write */ +#define _CLK_PRE 0xFF6 /* Clock Prescaler 8 Write */ + +#define STMBREAK 0x08 /* BREAK */ +#define STMFRAME 0x04 /* framing error */ +#define STMRCVROVR 0x02 /* receiver over run error */ +#define STMPARITY 0x01 /* parity error */ +#define STMERROR (STMBREAK | STMFRAME | STMPARITY) +#define STMBREAKH 0x800 /* BREAK */ +#define STMFRAMEH 0x400 /* framing error */ +#define STMRCVROVRH 0x200 /* receiver over run error */ +#define STMPARITYH 0x100 /* parity error */ +#define STMERRORH (STMBREAKH | STMFRAMEH | STMPARITYH) + +#define CTS_ACT 0x20 /* CTS input asserted */ +#define DSR_ACT 0x10 /* DSR input asserted */ +#define CD_ACT 0x08 /* CD input asserted */ +#define TXFIFOMT 0x04 /* Tx FIFO is empty */ +#define TXSHRMT 0x02 /* Tx shift register is empty */ +#define RDA 0x01 /* Rx data available */ +#define DRAINED (TXFIFOMT | TXSHRMT) /* indicates Tx is drained */ + +#define STATMODE 0x8000 /* status mode enable bit */ +#define RXFOVERFL 0x2000 /* receive FIFO overflow */ +#define RX2MATCH 0x1000 /* receive compare byte 2 match */ +#define RX1MATCH 0x0800 /* receive compare byte 1 match */ +#define RXBREAK 0x0400 /* received BREAK */ +#define RXFRAME 0x0200 /* received framing error */ +#define RXPARITY 0x0100 /* received parity error */ +#define STATERROR (RXBREAK | RXFRAME | RXPARITY) + +#define CTSFC_EN 0x80 /* CTS flow control enable bit */ +#define RTSTOG_EN 0x40 /* RTS toggle enable bit */ +#define TXINT_EN 0x10 /* transmit interrupt enable */ +#define STOP2 0x08 /* enable 2 stop bits (0 = 1 stop) */ +#define PARITY_EN 0x04 /* enable parity (0 = no parity) */ +#define EVEN_PAR 0x02 /* even parity (0 = odd parity) */ +#define DATA8BIT 0x01 /* 8 bit data (0 = 7 bit data) */ + +#define SETBREAK 0x10 /* send break condition (must clear) */ +#define LOCALLOOP 0x08 /* local loopback set for test */ +#define SET_DTR 0x04 /* assert DTR */ +#define SET_RTS 0x02 /* assert RTS */ +#define TX_ENABLE 0x01 /* enable transmitter */ + +#define RTSFC_EN 0x40 /* RTS flow control enable */ +#define RXPROC_EN 0x20 /* receive processor enable */ +#define TRIG_NO 0x00 /* Rx FIFO trigger level 0 (no trigger) */ +#define TRIG_1 0x08 /* trigger level 1 char */ +#define TRIG_1_2 0x10 /* trigger level 1/2 */ +#define TRIG_7_8 0x18 /* trigger level 7/8 */ +#define TRIG_MASK 0x18 /* trigger level mask */ +#define SRCINT_EN 0x04 /* special Rx condition interrupt enable */ +#define RXINT_EN 0x02 /* Rx interrupt enable */ +#define MCINT_EN 0x01 /* modem change interrupt enable */ + +#define RXF_TRIG 0x20 /* Rx FIFO trigger level interrupt */ +#define TXFIFO_MT 0x10 /* Tx FIFO empty interrupt */ +#define SRC_INT 0x08 /* special receive condition interrupt */ +#define DELTA_CD 0x04 /* CD change interrupt */ +#define DELTA_CTS 0x02 /* CTS change interrupt */ +#define DELTA_DSR 0x01 /* DSR change interrupt */ + +#define REP1W2_EN 0x10 /* replace byte 1 with 2 bytes enable */ +#define IGN2_EN 0x08 /* ignore byte 2 enable */ +#define IGN1_EN 0x04 /* ignore byte 1 enable */ +#define COMP2_EN 0x02 /* compare byte 2 enable */ +#define COMP1_EN 0x01 /* compare byte 1 enable */ + +#define RESET_ALL 0x80 /* reset AIOP (all channels) */ +#define TXOVERIDE 0x40 /* Transmit software off override */ +#define RESETUART 0x20 /* reset channel's UART */ +#define RESTXFCNT 0x10 /* reset channel's Tx FIFO count register */ +#define RESRXFCNT 0x08 /* reset channel's Rx FIFO count register */ + +#define INTSTAT0 0x01 /* AIOP 0 interrupt status */ +#define INTSTAT1 0x02 /* AIOP 1 interrupt status */ +#define INTSTAT2 0x04 /* AIOP 2 interrupt status */ +#define INTSTAT3 0x08 /* AIOP 3 interrupt status */ + +#define INTR_EN 0x08 /* allow interrupts to host */ +#define INT_STROB 0x04 /* strobe and clear interrupt line (EOI) */ + +/************************************************************************** + MUDBAC remapped for PCI +**************************************************************************/ + +#define _CFG_INT_PCI 0x40 +#define _PCI_INT_FUNC 0x3A + +#define PCI_STROB 0x2000 /* bit 13 of int aiop register */ +#define INTR_EN_PCI 0x0010 /* allow interrupts to host */ + +/* + * Definitions for Universal PCI board registers + */ +#define _PCI_9030_INT_CTRL 0x4c /* Offsets from BAR1 */ +#define _PCI_9030_GPIO_CTRL 0x54 +#define PCI_INT_CTRL_AIOP 0x0001 +#define PCI_GPIO_CTRL_8PORT 0x4000 +#define _PCI_9030_RING_IND 0xc0 /* Offsets from BAR1 */ + +#define CHAN3_EN 0x08 /* enable AIOP 3 */ +#define CHAN2_EN 0x04 /* enable AIOP 2 */ +#define CHAN1_EN 0x02 /* enable AIOP 1 */ +#define CHAN0_EN 0x01 /* enable AIOP 0 */ +#define FREQ_DIS 0x00 +#define FREQ_274HZ 0x60 +#define FREQ_137HZ 0x50 +#define FREQ_69HZ 0x40 +#define FREQ_34HZ 0x30 +#define FREQ_17HZ 0x20 +#define FREQ_9HZ 0x10 +#define PERIODIC_ONLY 0x80 /* only PERIODIC interrupt */ + +#define CHANINT_EN 0x0100 /* flags to enable/disable channel ints */ + +#define RDATASIZE 72 +#define RREGDATASIZE 52 + +/* + * AIOP interrupt bits for ISA/PCI boards and UPCI boards. + */ +#define AIOP_INTR_BIT_0 0x0001 +#define AIOP_INTR_BIT_1 0x0002 +#define AIOP_INTR_BIT_2 0x0004 +#define AIOP_INTR_BIT_3 0x0008 + +#define AIOP_INTR_BITS ( \ + AIOP_INTR_BIT_0 \ + | AIOP_INTR_BIT_1 \ + | AIOP_INTR_BIT_2 \ + | AIOP_INTR_BIT_3) + +#define UPCI_AIOP_INTR_BIT_0 0x0004 +#define UPCI_AIOP_INTR_BIT_1 0x0020 +#define UPCI_AIOP_INTR_BIT_2 0x0100 +#define UPCI_AIOP_INTR_BIT_3 0x0800 + +#define UPCI_AIOP_INTR_BITS ( \ + UPCI_AIOP_INTR_BIT_0 \ + | UPCI_AIOP_INTR_BIT_1 \ + | UPCI_AIOP_INTR_BIT_2 \ + | UPCI_AIOP_INTR_BIT_3) + +/* Controller level information structure */ +typedef struct { + int CtlID; + int CtlNum; + int BusType; + int boardType; + int isUPCI; + WordIO_t PCIIO; + WordIO_t PCIIO2; + ByteIO_t MBaseIO; + ByteIO_t MReg1IO; + ByteIO_t MReg2IO; + ByteIO_t MReg3IO; + Byte_t MReg2; + Byte_t MReg3; + int NumAiop; + int AltChanRingIndicator; + ByteIO_t UPCIRingInd; + WordIO_t AiopIO[AIOP_CTL_SIZE]; + ByteIO_t AiopIntChanIO[AIOP_CTL_SIZE]; + int AiopID[AIOP_CTL_SIZE]; + int AiopNumChan[AIOP_CTL_SIZE]; + Word_t *AiopIntrBits; +} CONTROLLER_T; + +typedef CONTROLLER_T CONTROLLER_t; + +/* Channel level information structure */ +typedef struct { + CONTROLLER_T *CtlP; + int AiopNum; + int ChanID; + int ChanNum; + int rtsToggle; + + ByteIO_t Cmd; + ByteIO_t IntChan; + ByteIO_t IntMask; + DWordIO_t IndexAddr; + WordIO_t IndexData; + + WordIO_t TxRxData; + WordIO_t ChanStat; + WordIO_t TxRxCount; + ByteIO_t IntID; + + Word_t TxFIFO; + Word_t TxFIFOPtrs; + Word_t RxFIFO; + Word_t RxFIFOPtrs; + Word_t TxPrioCnt; + Word_t TxPrioPtr; + Word_t TxPrioBuf; + + Byte_t R[RREGDATASIZE]; + + Byte_t BaudDiv[4]; + Byte_t TxControl[4]; + Byte_t RxControl[4]; + Byte_t TxEnables[4]; + Byte_t TxCompare[4]; + Byte_t TxReplace1[4]; + Byte_t TxReplace2[4]; +} CHANNEL_T; + +typedef CHANNEL_T CHANNEL_t; +typedef CHANNEL_T *CHANPTR_T; + +#define InterfaceModeRS232 0x00 +#define InterfaceModeRS422 0x08 +#define InterfaceModeRS485 0x10 +#define InterfaceModeRS232T 0x18 + +/*************************************************************************** +Function: sClrBreak +Purpose: Stop sending a transmit BREAK signal +Call: sClrBreak(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sClrBreak(ChP) \ +do { \ + (ChP)->TxControl[3] &= ~SETBREAK; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ +} while (0) + +/*************************************************************************** +Function: sClrDTR +Purpose: Clr the DTR output +Call: sClrDTR(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sClrDTR(ChP) \ +do { \ + (ChP)->TxControl[3] &= ~SET_DTR; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ +} while (0) + +/*************************************************************************** +Function: sClrRTS +Purpose: Clr the RTS output +Call: sClrRTS(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sClrRTS(ChP) \ +do { \ + if ((ChP)->rtsToggle) break; \ + (ChP)->TxControl[3] &= ~SET_RTS; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ +} while (0) + +/*************************************************************************** +Function: sClrTxXOFF +Purpose: Clear any existing transmit software flow control off condition +Call: sClrTxXOFF(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sClrTxXOFF(ChP) \ +do { \ + sOutB((ChP)->Cmd,TXOVERIDE | (Byte_t)(ChP)->ChanNum); \ + sOutB((ChP)->Cmd,(Byte_t)(ChP)->ChanNum); \ +} while (0) + +/*************************************************************************** +Function: sCtlNumToCtlPtr +Purpose: Convert a controller number to controller structure pointer +Call: sCtlNumToCtlPtr(CtlNum) + int CtlNum; Controller number +Return: CONTROLLER_T *: Ptr to controller structure +*/ +#define sCtlNumToCtlPtr(CTLNUM) &sController[CTLNUM] + +/*************************************************************************** +Function: sControllerEOI +Purpose: Strobe the MUDBAC's End Of Interrupt bit. +Call: sControllerEOI(CtlP) + CONTROLLER_T *CtlP; Ptr to controller structure +*/ +#define sControllerEOI(CTLP) sOutB((CTLP)->MReg2IO,(CTLP)->MReg2 | INT_STROB) + +/*************************************************************************** +Function: sPCIControllerEOI +Purpose: Strobe the PCI End Of Interrupt bit. + For the UPCI boards, toggle the AIOP interrupt enable bit + (this was taken from the Windows driver). +Call: sPCIControllerEOI(CtlP) + CONTROLLER_T *CtlP; Ptr to controller structure +*/ +#define sPCIControllerEOI(CTLP) \ +do { \ + if ((CTLP)->isUPCI) { \ + Word_t w = sInW((CTLP)->PCIIO); \ + sOutW((CTLP)->PCIIO, (w ^ PCI_INT_CTRL_AIOP)); \ + sOutW((CTLP)->PCIIO, w); \ + } \ + else { \ + sOutW((CTLP)->PCIIO, PCI_STROB); \ + } \ +} while (0) + +/*************************************************************************** +Function: sDisAiop +Purpose: Disable I/O access to an AIOP +Call: sDisAiop(CltP) + CONTROLLER_T *CtlP; Ptr to controller structure + int AiopNum; Number of AIOP on controller +*/ +#define sDisAiop(CTLP,AIOPNUM) \ +do { \ + (CTLP)->MReg3 &= sBitMapClrTbl[AIOPNUM]; \ + sOutB((CTLP)->MReg3IO,(CTLP)->MReg3); \ +} while (0) + +/*************************************************************************** +Function: sDisCTSFlowCtl +Purpose: Disable output flow control using CTS +Call: sDisCTSFlowCtl(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sDisCTSFlowCtl(ChP) \ +do { \ + (ChP)->TxControl[2] &= ~CTSFC_EN; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ +} while (0) + +/*************************************************************************** +Function: sDisIXANY +Purpose: Disable IXANY Software Flow Control +Call: sDisIXANY(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sDisIXANY(ChP) \ +do { \ + (ChP)->R[0x0e] = 0x86; \ + out32((ChP)->IndexAddr,&(ChP)->R[0x0c]); \ +} while (0) + +/*************************************************************************** +Function: DisParity +Purpose: Disable parity +Call: sDisParity(ChP) + CHANNEL_T *ChP; Ptr to channel structure +Comments: Function sSetParity() can be used in place of functions sEnParity(), + sDisParity(), sSetOddParity(), and sSetEvenParity(). +*/ +#define sDisParity(ChP) \ +do { \ + (ChP)->TxControl[2] &= ~PARITY_EN; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ +} while (0) + +/*************************************************************************** +Function: sDisRTSToggle +Purpose: Disable RTS toggle +Call: sDisRTSToggle(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sDisRTSToggle(ChP) \ +do { \ + (ChP)->TxControl[2] &= ~RTSTOG_EN; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ + (ChP)->rtsToggle = 0; \ +} while (0) + +/*************************************************************************** +Function: sDisRxFIFO +Purpose: Disable Rx FIFO +Call: sDisRxFIFO(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sDisRxFIFO(ChP) \ +do { \ + (ChP)->R[0x32] = 0x0a; \ + out32((ChP)->IndexAddr,&(ChP)->R[0x30]); \ +} while (0) + +/*************************************************************************** +Function: sDisRxStatusMode +Purpose: Disable the Rx status mode +Call: sDisRxStatusMode(ChP) + CHANNEL_T *ChP; Ptr to channel structure +Comments: This takes the channel out of the receive status mode. All + subsequent reads of receive data using sReadRxWord() will return + two data bytes. +*/ +#define sDisRxStatusMode(ChP) sOutW((ChP)->ChanStat,0) + +/*************************************************************************** +Function: sDisTransmit +Purpose: Disable transmit +Call: sDisTransmit(ChP) + CHANNEL_T *ChP; Ptr to channel structure + This disables movement of Tx data from the Tx FIFO into the 1 byte + Tx buffer. Therefore there could be up to a 2 byte latency + between the time sDisTransmit() is called and the transmit buffer + and transmit shift register going completely empty. +*/ +#define sDisTransmit(ChP) \ +do { \ + (ChP)->TxControl[3] &= ~TX_ENABLE; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ +} while (0) + +/*************************************************************************** +Function: sDisTxSoftFlowCtl +Purpose: Disable Tx Software Flow Control +Call: sDisTxSoftFlowCtl(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sDisTxSoftFlowCtl(ChP) \ +do { \ + (ChP)->R[0x06] = 0x8a; \ + out32((ChP)->IndexAddr,&(ChP)->R[0x04]); \ +} while (0) + +/*************************************************************************** +Function: sEnAiop +Purpose: Enable I/O access to an AIOP +Call: sEnAiop(CltP) + CONTROLLER_T *CtlP; Ptr to controller structure + int AiopNum; Number of AIOP on controller +*/ +#define sEnAiop(CTLP,AIOPNUM) \ +do { \ + (CTLP)->MReg3 |= sBitMapSetTbl[AIOPNUM]; \ + sOutB((CTLP)->MReg3IO,(CTLP)->MReg3); \ +} while (0) + +/*************************************************************************** +Function: sEnCTSFlowCtl +Purpose: Enable output flow control using CTS +Call: sEnCTSFlowCtl(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sEnCTSFlowCtl(ChP) \ +do { \ + (ChP)->TxControl[2] |= CTSFC_EN; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ +} while (0) + +/*************************************************************************** +Function: sEnIXANY +Purpose: Enable IXANY Software Flow Control +Call: sEnIXANY(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sEnIXANY(ChP) \ +do { \ + (ChP)->R[0x0e] = 0x21; \ + out32((ChP)->IndexAddr,&(ChP)->R[0x0c]); \ +} while (0) + +/*************************************************************************** +Function: EnParity +Purpose: Enable parity +Call: sEnParity(ChP) + CHANNEL_T *ChP; Ptr to channel structure +Comments: Function sSetParity() can be used in place of functions sEnParity(), + sDisParity(), sSetOddParity(), and sSetEvenParity(). + +Warnings: Before enabling parity odd or even parity should be chosen using + functions sSetOddParity() or sSetEvenParity(). +*/ +#define sEnParity(ChP) \ +do { \ + (ChP)->TxControl[2] |= PARITY_EN; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ +} while (0) + +/*************************************************************************** +Function: sEnRTSToggle +Purpose: Enable RTS toggle +Call: sEnRTSToggle(ChP) + CHANNEL_T *ChP; Ptr to channel structure +Comments: This function will disable RTS flow control and clear the RTS + line to allow operation of RTS toggle. +*/ +#define sEnRTSToggle(ChP) \ +do { \ + (ChP)->RxControl[2] &= ~RTSFC_EN; \ + out32((ChP)->IndexAddr,(ChP)->RxControl); \ + (ChP)->TxControl[2] |= RTSTOG_EN; \ + (ChP)->TxControl[3] &= ~SET_RTS; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ + (ChP)->rtsToggle = 1; \ +} while (0) + +/*************************************************************************** +Function: sEnRxFIFO +Purpose: Enable Rx FIFO +Call: sEnRxFIFO(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sEnRxFIFO(ChP) \ +do { \ + (ChP)->R[0x32] = 0x08; \ + out32((ChP)->IndexAddr,&(ChP)->R[0x30]); \ +} while (0) + +/*************************************************************************** +Function: sEnRxProcessor +Purpose: Enable the receive processor +Call: sEnRxProcessor(ChP) + CHANNEL_T *ChP; Ptr to channel structure +Comments: This function is used to start the receive processor. When + the channel is in the reset state the receive processor is not + running. This is done to prevent the receive processor from + executing invalid microcode instructions prior to the + downloading of the microcode. + +Warnings: This function must be called after valid microcode has been + downloaded to the AIOP, and it must not be called before the + microcode has been downloaded. +*/ +#define sEnRxProcessor(ChP) \ +do { \ + (ChP)->RxControl[2] |= RXPROC_EN; \ + out32((ChP)->IndexAddr,(ChP)->RxControl); \ +} while (0) + +/*************************************************************************** +Function: sEnRxStatusMode +Purpose: Enable the Rx status mode +Call: sEnRxStatusMode(ChP) + CHANNEL_T *ChP; Ptr to channel structure +Comments: This places the channel in the receive status mode. All subsequent + reads of receive data using sReadRxWord() will return a data byte + in the low word and a status byte in the high word. + +*/ +#define sEnRxStatusMode(ChP) sOutW((ChP)->ChanStat,STATMODE) + +/*************************************************************************** +Function: sEnTransmit +Purpose: Enable transmit +Call: sEnTransmit(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sEnTransmit(ChP) \ +do { \ + (ChP)->TxControl[3] |= TX_ENABLE; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ +} while (0) + +/*************************************************************************** +Function: sEnTxSoftFlowCtl +Purpose: Enable Tx Software Flow Control +Call: sEnTxSoftFlowCtl(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sEnTxSoftFlowCtl(ChP) \ +do { \ + (ChP)->R[0x06] = 0xc5; \ + out32((ChP)->IndexAddr,&(ChP)->R[0x04]); \ +} while (0) + +/*************************************************************************** +Function: sGetAiopIntStatus +Purpose: Get the AIOP interrupt status +Call: sGetAiopIntStatus(CtlP,AiopNum) + CONTROLLER_T *CtlP; Ptr to controller structure + int AiopNum; AIOP number +Return: Byte_t: The AIOP interrupt status. Bits 0 through 7 + represent channels 0 through 7 respectively. If a + bit is set that channel is interrupting. +*/ +#define sGetAiopIntStatus(CTLP,AIOPNUM) sInB((CTLP)->AiopIntChanIO[AIOPNUM]) + +/*************************************************************************** +Function: sGetAiopNumChan +Purpose: Get the number of channels supported by an AIOP +Call: sGetAiopNumChan(CtlP,AiopNum) + CONTROLLER_T *CtlP; Ptr to controller structure + int AiopNum; AIOP number +Return: int: The number of channels supported by the AIOP +*/ +#define sGetAiopNumChan(CTLP,AIOPNUM) (CTLP)->AiopNumChan[AIOPNUM] + +/*************************************************************************** +Function: sGetChanIntID +Purpose: Get a channel's interrupt identification byte +Call: sGetChanIntID(ChP) + CHANNEL_T *ChP; Ptr to channel structure +Return: Byte_t: The channel interrupt ID. Can be any + combination of the following flags: + RXF_TRIG: Rx FIFO trigger level interrupt + TXFIFO_MT: Tx FIFO empty interrupt + SRC_INT: Special receive condition interrupt + DELTA_CD: CD change interrupt + DELTA_CTS: CTS change interrupt + DELTA_DSR: DSR change interrupt +*/ +#define sGetChanIntID(ChP) (sInB((ChP)->IntID) & (RXF_TRIG | TXFIFO_MT | SRC_INT | DELTA_CD | DELTA_CTS | DELTA_DSR)) + +/*************************************************************************** +Function: sGetChanNum +Purpose: Get the number of a channel within an AIOP +Call: sGetChanNum(ChP) + CHANNEL_T *ChP; Ptr to channel structure +Return: int: Channel number within AIOP, or NULLCHAN if channel does + not exist. +*/ +#define sGetChanNum(ChP) (ChP)->ChanNum + +/*************************************************************************** +Function: sGetChanStatus +Purpose: Get the channel status +Call: sGetChanStatus(ChP) + CHANNEL_T *ChP; Ptr to channel structure +Return: Word_t: The channel status. Can be any combination of + the following flags: + LOW BYTE FLAGS + CTS_ACT: CTS input asserted + DSR_ACT: DSR input asserted + CD_ACT: CD input asserted + TXFIFOMT: Tx FIFO is empty + TXSHRMT: Tx shift register is empty + RDA: Rx data available + + HIGH BYTE FLAGS + STATMODE: status mode enable bit + RXFOVERFL: receive FIFO overflow + RX2MATCH: receive compare byte 2 match + RX1MATCH: receive compare byte 1 match + RXBREAK: received BREAK + RXFRAME: received framing error + RXPARITY: received parity error +Warnings: This function will clear the high byte flags in the Channel + Status Register. +*/ +#define sGetChanStatus(ChP) sInW((ChP)->ChanStat) + +/*************************************************************************** +Function: sGetChanStatusLo +Purpose: Get the low byte only of the channel status +Call: sGetChanStatusLo(ChP) + CHANNEL_T *ChP; Ptr to channel structure +Return: Byte_t: The channel status low byte. Can be any combination + of the following flags: + CTS_ACT: CTS input asserted + DSR_ACT: DSR input asserted + CD_ACT: CD input asserted + TXFIFOMT: Tx FIFO is empty + TXSHRMT: Tx shift register is empty + RDA: Rx data available +*/ +#define sGetChanStatusLo(ChP) sInB((ByteIO_t)(ChP)->ChanStat) + +/********************************************************************** + * Get RI status of channel + * Defined as a function in rocket.c -aes + */ +#if 0 +#define sGetChanRI(ChP) ((ChP)->CtlP->AltChanRingIndicator ? \ + (sInB((ByteIO_t)((ChP)->ChanStat+8)) & DSR_ACT) : \ + (((ChP)->CtlP->boardType == ROCKET_TYPE_PC104) ? \ + (!(sInB((ChP)->CtlP->AiopIO[3]) & sBitMapSetTbl[(ChP)->ChanNum])) : \ + 0)) +#endif + +/*************************************************************************** +Function: sGetControllerIntStatus +Purpose: Get the controller interrupt status +Call: sGetControllerIntStatus(CtlP) + CONTROLLER_T *CtlP; Ptr to controller structure +Return: Byte_t: The controller interrupt status in the lower 4 + bits. Bits 0 through 3 represent AIOP's 0 + through 3 respectively. If a bit is set that + AIOP is interrupting. Bits 4 through 7 will + always be cleared. +*/ +#define sGetControllerIntStatus(CTLP) (sInB((CTLP)->MReg1IO) & 0x0f) + +/*************************************************************************** +Function: sPCIGetControllerIntStatus +Purpose: Get the controller interrupt status +Call: sPCIGetControllerIntStatus(CtlP) + CONTROLLER_T *CtlP; Ptr to controller structure +Return: unsigned char: The controller interrupt status in the lower 4 + bits and bit 4. Bits 0 through 3 represent AIOP's 0 + through 3 respectively. Bit 4 is set if the int + was generated from periodic. If a bit is set the + AIOP is interrupting. +*/ +#define sPCIGetControllerIntStatus(CTLP) \ + ((CTLP)->isUPCI ? \ + (sInW((CTLP)->PCIIO2) & UPCI_AIOP_INTR_BITS) : \ + ((sInW((CTLP)->PCIIO) >> 8) & AIOP_INTR_BITS)) + +/*************************************************************************** + +Function: sGetRxCnt +Purpose: Get the number of data bytes in the Rx FIFO +Call: sGetRxCnt(ChP) + CHANNEL_T *ChP; Ptr to channel structure +Return: int: The number of data bytes in the Rx FIFO. +Comments: Byte read of count register is required to obtain Rx count. + +*/ +#define sGetRxCnt(ChP) sInW((ChP)->TxRxCount) + +/*************************************************************************** +Function: sGetTxCnt +Purpose: Get the number of data bytes in the Tx FIFO +Call: sGetTxCnt(ChP) + CHANNEL_T *ChP; Ptr to channel structure +Return: Byte_t: The number of data bytes in the Tx FIFO. +Comments: Byte read of count register is required to obtain Tx count. + +*/ +#define sGetTxCnt(ChP) sInB((ByteIO_t)(ChP)->TxRxCount) + +/***************************************************************************** +Function: sGetTxRxDataIO +Purpose: Get the I/O address of a channel's TxRx Data register +Call: sGetTxRxDataIO(ChP) + CHANNEL_T *ChP; Ptr to channel structure +Return: WordIO_t: I/O address of a channel's TxRx Data register +*/ +#define sGetTxRxDataIO(ChP) (ChP)->TxRxData + +/*************************************************************************** +Function: sInitChanDefaults +Purpose: Initialize a channel structure to it's default state. +Call: sInitChanDefaults(ChP) + CHANNEL_T *ChP; Ptr to the channel structure +Comments: This function must be called once for every channel structure + that exists before any other SSCI calls can be made. + +*/ +#define sInitChanDefaults(ChP) \ +do { \ + (ChP)->CtlP = NULLCTLPTR; \ + (ChP)->AiopNum = NULLAIOP; \ + (ChP)->ChanID = AIOPID_NULL; \ + (ChP)->ChanNum = NULLCHAN; \ +} while (0) + +/*************************************************************************** +Function: sResetAiopByNum +Purpose: Reset the AIOP by number +Call: sResetAiopByNum(CTLP,AIOPNUM) + CONTROLLER_T CTLP; Ptr to controller structure + AIOPNUM; AIOP index +*/ +#define sResetAiopByNum(CTLP,AIOPNUM) \ +do { \ + sOutB((CTLP)->AiopIO[(AIOPNUM)]+_CMD_REG,RESET_ALL); \ + sOutB((CTLP)->AiopIO[(AIOPNUM)]+_CMD_REG,0x0); \ +} while (0) + +/*************************************************************************** +Function: sSendBreak +Purpose: Send a transmit BREAK signal +Call: sSendBreak(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sSendBreak(ChP) \ +do { \ + (ChP)->TxControl[3] |= SETBREAK; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ +} while (0) + +/*************************************************************************** +Function: sSetBaud +Purpose: Set baud rate +Call: sSetBaud(ChP,Divisor) + CHANNEL_T *ChP; Ptr to channel structure + Word_t Divisor; 16 bit baud rate divisor for channel +*/ +#define sSetBaud(ChP,DIVISOR) \ +do { \ + (ChP)->BaudDiv[2] = (Byte_t)(DIVISOR); \ + (ChP)->BaudDiv[3] = (Byte_t)((DIVISOR) >> 8); \ + out32((ChP)->IndexAddr,(ChP)->BaudDiv); \ +} while (0) + +/*************************************************************************** +Function: sSetData7 +Purpose: Set data bits to 7 +Call: sSetData7(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sSetData7(ChP) \ +do { \ + (ChP)->TxControl[2] &= ~DATA8BIT; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ +} while (0) + +/*************************************************************************** +Function: sSetData8 +Purpose: Set data bits to 8 +Call: sSetData8(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sSetData8(ChP) \ +do { \ + (ChP)->TxControl[2] |= DATA8BIT; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ +} while (0) + +/*************************************************************************** +Function: sSetDTR +Purpose: Set the DTR output +Call: sSetDTR(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sSetDTR(ChP) \ +do { \ + (ChP)->TxControl[3] |= SET_DTR; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ +} while (0) + +/*************************************************************************** +Function: sSetEvenParity +Purpose: Set even parity +Call: sSetEvenParity(ChP) + CHANNEL_T *ChP; Ptr to channel structure +Comments: Function sSetParity() can be used in place of functions sEnParity(), + sDisParity(), sSetOddParity(), and sSetEvenParity(). + +Warnings: This function has no effect unless parity is enabled with function + sEnParity(). +*/ +#define sSetEvenParity(ChP) \ +do { \ + (ChP)->TxControl[2] |= EVEN_PAR; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ +} while (0) + +/*************************************************************************** +Function: sSetOddParity +Purpose: Set odd parity +Call: sSetOddParity(ChP) + CHANNEL_T *ChP; Ptr to channel structure +Comments: Function sSetParity() can be used in place of functions sEnParity(), + sDisParity(), sSetOddParity(), and sSetEvenParity(). + +Warnings: This function has no effect unless parity is enabled with function + sEnParity(). +*/ +#define sSetOddParity(ChP) \ +do { \ + (ChP)->TxControl[2] &= ~EVEN_PAR; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ +} while (0) + +/*************************************************************************** +Function: sSetRTS +Purpose: Set the RTS output +Call: sSetRTS(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sSetRTS(ChP) \ +do { \ + if ((ChP)->rtsToggle) break; \ + (ChP)->TxControl[3] |= SET_RTS; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ +} while (0) + +/*************************************************************************** +Function: sSetRxTrigger +Purpose: Set the Rx FIFO trigger level +Call: sSetRxProcessor(ChP,Level) + CHANNEL_T *ChP; Ptr to channel structure + Byte_t Level; Number of characters in Rx FIFO at which the + interrupt will be generated. Can be any of the following flags: + + TRIG_NO: no trigger + TRIG_1: 1 character in FIFO + TRIG_1_2: FIFO 1/2 full + TRIG_7_8: FIFO 7/8 full +Comments: An interrupt will be generated when the trigger level is reached + only if function sEnInterrupt() has been called with flag + RXINT_EN set. The RXF_TRIG flag in the Interrupt Idenfification + register will be set whenever the trigger level is reached + regardless of the setting of RXINT_EN. + +*/ +#define sSetRxTrigger(ChP,LEVEL) \ +do { \ + (ChP)->RxControl[2] &= ~TRIG_MASK; \ + (ChP)->RxControl[2] |= LEVEL; \ + out32((ChP)->IndexAddr,(ChP)->RxControl); \ +} while (0) + +/*************************************************************************** +Function: sSetStop1 +Purpose: Set stop bits to 1 +Call: sSetStop1(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sSetStop1(ChP) \ +do { \ + (ChP)->TxControl[2] &= ~STOP2; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ +} while (0) + +/*************************************************************************** +Function: sSetStop2 +Purpose: Set stop bits to 2 +Call: sSetStop2(ChP) + CHANNEL_T *ChP; Ptr to channel structure +*/ +#define sSetStop2(ChP) \ +do { \ + (ChP)->TxControl[2] |= STOP2; \ + out32((ChP)->IndexAddr,(ChP)->TxControl); \ +} while (0) + +/*************************************************************************** +Function: sSetTxXOFFChar +Purpose: Set the Tx XOFF flow control character +Call: sSetTxXOFFChar(ChP,Ch) + CHANNEL_T *ChP; Ptr to channel structure + Byte_t Ch; The value to set the Tx XOFF character to +*/ +#define sSetTxXOFFChar(ChP,CH) \ +do { \ + (ChP)->R[0x07] = (CH); \ + out32((ChP)->IndexAddr,&(ChP)->R[0x04]); \ +} while (0) + +/*************************************************************************** +Function: sSetTxXONChar +Purpose: Set the Tx XON flow control character +Call: sSetTxXONChar(ChP,Ch) + CHANNEL_T *ChP; Ptr to channel structure + Byte_t Ch; The value to set the Tx XON character to +*/ +#define sSetTxXONChar(ChP,CH) \ +do { \ + (ChP)->R[0x0b] = (CH); \ + out32((ChP)->IndexAddr,&(ChP)->R[0x08]); \ +} while (0) + +/*************************************************************************** +Function: sStartRxProcessor +Purpose: Start a channel's receive processor +Call: sStartRxProcessor(ChP) + CHANNEL_T *ChP; Ptr to channel structure +Comments: This function is used to start a Rx processor after it was + stopped with sStopRxProcessor() or sStopSWInFlowCtl(). It + will restart both the Rx processor and software input flow control. + +*/ +#define sStartRxProcessor(ChP) out32((ChP)->IndexAddr,&(ChP)->R[0]) + +/*************************************************************************** +Function: sWriteTxByte +Purpose: Write a transmit data byte to a channel. + ByteIO_t io: Channel transmit register I/O address. This can + be obtained with sGetTxRxDataIO(). + Byte_t Data; The transmit data byte. +Warnings: This function writes the data byte without checking to see if + sMaxTxSize is exceeded in the Tx FIFO. +*/ +#define sWriteTxByte(IO,DATA) sOutB(IO,DATA) + +/* + * Begin Linux specific definitions for the Rocketport driver + * + * This code is Copyright Theodore Ts'o, 1995-1997 + */ + +struct r_port { + int magic; + struct tty_port port; + int line; + int flags; /* Don't yet match the ASY_ flags!! */ + unsigned int board:3; + unsigned int aiop:2; + unsigned int chan:3; + CONTROLLER_t *ctlp; + CHANNEL_t channel; + int intmask; + int xmit_fifo_room; /* room in xmit fifo */ + unsigned char *xmit_buf; + int xmit_head; + int xmit_tail; + int xmit_cnt; + int cd_status; + int ignore_status_mask; + int read_status_mask; + int cps; + + struct completion close_wait; /* Not yet matching the core */ + spinlock_t slock; + struct mutex write_mtx; +}; + +#define RPORT_MAGIC 0x525001 + +#define NUM_BOARDS 8 +#define MAX_RP_PORTS (32*NUM_BOARDS) + +/* + * The size of the xmit buffer is 1 page, or 4096 bytes + */ +#define XMIT_BUF_SIZE 4096 + +/* number of characters left in xmit buffer before we ask for more */ +#define WAKEUP_CHARS 256 + +/* + * Assigned major numbers for the Comtrol Rocketport + */ +#define TTY_ROCKET_MAJOR 46 +#define CUA_ROCKET_MAJOR 47 + +#ifdef PCI_VENDOR_ID_RP +#undef PCI_VENDOR_ID_RP +#undef PCI_DEVICE_ID_RP8OCTA +#undef PCI_DEVICE_ID_RP8INTF +#undef PCI_DEVICE_ID_RP16INTF +#undef PCI_DEVICE_ID_RP32INTF +#undef PCI_DEVICE_ID_URP8OCTA +#undef PCI_DEVICE_ID_URP8INTF +#undef PCI_DEVICE_ID_URP16INTF +#undef PCI_DEVICE_ID_CRP16INTF +#undef PCI_DEVICE_ID_URP32INTF +#endif + +/* Comtrol PCI Vendor ID */ +#define PCI_VENDOR_ID_RP 0x11fe + +/* Comtrol Device ID's */ +#define PCI_DEVICE_ID_RP32INTF 0x0001 /* Rocketport 32 port w/external I/F */ +#define PCI_DEVICE_ID_RP8INTF 0x0002 /* Rocketport 8 port w/external I/F */ +#define PCI_DEVICE_ID_RP16INTF 0x0003 /* Rocketport 16 port w/external I/F */ +#define PCI_DEVICE_ID_RP4QUAD 0x0004 /* Rocketport 4 port w/quad cable */ +#define PCI_DEVICE_ID_RP8OCTA 0x0005 /* Rocketport 8 port w/octa cable */ +#define PCI_DEVICE_ID_RP8J 0x0006 /* Rocketport 8 port w/RJ11 connectors */ +#define PCI_DEVICE_ID_RP4J 0x0007 /* Rocketport 4 port w/RJ11 connectors */ +#define PCI_DEVICE_ID_RP8SNI 0x0008 /* Rocketport 8 port w/ DB78 SNI (Siemens) connector */ +#define PCI_DEVICE_ID_RP16SNI 0x0009 /* Rocketport 16 port w/ DB78 SNI (Siemens) connector */ +#define PCI_DEVICE_ID_RPP4 0x000A /* Rocketport Plus 4 port */ +#define PCI_DEVICE_ID_RPP8 0x000B /* Rocketport Plus 8 port */ +#define PCI_DEVICE_ID_RP6M 0x000C /* RocketModem 6 port */ +#define PCI_DEVICE_ID_RP4M 0x000D /* RocketModem 4 port */ +#define PCI_DEVICE_ID_RP2_232 0x000E /* Rocketport Plus 2 port RS232 */ +#define PCI_DEVICE_ID_RP2_422 0x000F /* Rocketport Plus 2 port RS422 */ + +/* Universal PCI boards */ +#define PCI_DEVICE_ID_URP32INTF 0x0801 /* Rocketport UPCI 32 port w/external I/F */ +#define PCI_DEVICE_ID_URP8INTF 0x0802 /* Rocketport UPCI 8 port w/external I/F */ +#define PCI_DEVICE_ID_URP16INTF 0x0803 /* Rocketport UPCI 16 port w/external I/F */ +#define PCI_DEVICE_ID_URP8OCTA 0x0805 /* Rocketport UPCI 8 port w/octa cable */ +#define PCI_DEVICE_ID_UPCI_RM3_8PORT 0x080C /* Rocketmodem III 8 port */ +#define PCI_DEVICE_ID_UPCI_RM3_4PORT 0x080D /* Rocketmodem III 4 port */ + +/* Compact PCI device */ +#define PCI_DEVICE_ID_CRP16INTF 0x0903 /* Rocketport Compact PCI 16 port w/external I/F */ + diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c new file mode 100644 index 000000000000..18888d005a0a --- /dev/null +++ b/drivers/tty/synclink.c @@ -0,0 +1,8119 @@ +/* + * linux/drivers/char/synclink.c + * + * $Id: synclink.c,v 4.38 2005/11/07 16:30:34 paulkf Exp $ + * + * Device driver for Microgate SyncLink ISA and PCI + * high speed multiprotocol serial adapters. + * + * written by Paul Fulghum for Microgate Corporation + * paulkf@microgate.com + * + * Microgate and SyncLink are trademarks of Microgate Corporation + * + * Derived from serial.c written by Theodore Ts'o and Linus Torvalds + * + * Original release 01/11/99 + * + * This code is released under the GNU General Public License (GPL) + * + * This driver is primarily intended for use in synchronous + * HDLC mode. Asynchronous mode is also provided. + * + * When operating in synchronous mode, each call to mgsl_write() + * contains exactly one complete HDLC frame. Calling mgsl_put_char + * will start assembling an HDLC frame that will not be sent until + * mgsl_flush_chars or mgsl_write is called. + * + * Synchronous receive data is reported as complete frames. To accomplish + * this, the TTY flip buffer is bypassed (too small to hold largest + * frame and may fragment frames) and the line discipline + * receive entry point is called directly. + * + * This driver has been tested with a slightly modified ppp.c driver + * for synchronous PPP. + * + * 2000/02/16 + * Added interface for syncppp.c driver (an alternate synchronous PPP + * implementation that also supports Cisco HDLC). Each device instance + * registers as a tty device AND a network device (if dosyncppp option + * is set for the device). The functionality is determined by which + * device interface is opened. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if defined(__i386__) +# define BREAKPOINT() asm(" int $3"); +#else +# define BREAKPOINT() { } +#endif + +#define MAX_ISA_DEVICES 10 +#define MAX_PCI_DEVICES 10 +#define MAX_TOTAL_DEVICES 20 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_MODULE)) +#define SYNCLINK_GENERIC_HDLC 1 +#else +#define SYNCLINK_GENERIC_HDLC 0 +#endif + +#define GET_USER(error,value,addr) error = get_user(value,addr) +#define COPY_FROM_USER(error,dest,src,size) error = copy_from_user(dest,src,size) ? -EFAULT : 0 +#define PUT_USER(error,value,addr) error = put_user(value,addr) +#define COPY_TO_USER(error,dest,src,size) error = copy_to_user(dest,src,size) ? -EFAULT : 0 + +#include + +#define RCLRVALUE 0xffff + +static MGSL_PARAMS default_params = { + MGSL_MODE_HDLC, /* unsigned long mode */ + 0, /* unsigned char loopback; */ + HDLC_FLAG_UNDERRUN_ABORT15, /* unsigned short flags; */ + HDLC_ENCODING_NRZI_SPACE, /* unsigned char encoding; */ + 0, /* unsigned long clock_speed; */ + 0xff, /* unsigned char addr_filter; */ + HDLC_CRC_16_CCITT, /* unsigned short crc_type; */ + HDLC_PREAMBLE_LENGTH_8BITS, /* unsigned char preamble_length; */ + HDLC_PREAMBLE_PATTERN_NONE, /* unsigned char preamble; */ + 9600, /* unsigned long data_rate; */ + 8, /* unsigned char data_bits; */ + 1, /* unsigned char stop_bits; */ + ASYNC_PARITY_NONE /* unsigned char parity; */ +}; + +#define SHARED_MEM_ADDRESS_SIZE 0x40000 +#define BUFFERLISTSIZE 4096 +#define DMABUFFERSIZE 4096 +#define MAXRXFRAMES 7 + +typedef struct _DMABUFFERENTRY +{ + u32 phys_addr; /* 32-bit flat physical address of data buffer */ + volatile u16 count; /* buffer size/data count */ + volatile u16 status; /* Control/status field */ + volatile u16 rcc; /* character count field */ + u16 reserved; /* padding required by 16C32 */ + u32 link; /* 32-bit flat link to next buffer entry */ + char *virt_addr; /* virtual address of data buffer */ + u32 phys_entry; /* physical address of this buffer entry */ + dma_addr_t dma_addr; +} DMABUFFERENTRY, *DMAPBUFFERENTRY; + +/* The queue of BH actions to be performed */ + +#define BH_RECEIVE 1 +#define BH_TRANSMIT 2 +#define BH_STATUS 4 + +#define IO_PIN_SHUTDOWN_LIMIT 100 + +struct _input_signal_events { + int ri_up; + int ri_down; + int dsr_up; + int dsr_down; + int dcd_up; + int dcd_down; + int cts_up; + int cts_down; +}; + +/* transmit holding buffer definitions*/ +#define MAX_TX_HOLDING_BUFFERS 5 +struct tx_holding_buffer { + int buffer_size; + unsigned char * buffer; +}; + + +/* + * Device instance data structure + */ + +struct mgsl_struct { + int magic; + struct tty_port port; + int line; + int hw_version; + + struct mgsl_icount icount; + + int timeout; + int x_char; /* xon/xoff character */ + u16 read_status_mask; + u16 ignore_status_mask; + unsigned char *xmit_buf; + int xmit_head; + int xmit_tail; + int xmit_cnt; + + wait_queue_head_t status_event_wait_q; + wait_queue_head_t event_wait_q; + struct timer_list tx_timer; /* HDLC transmit timeout timer */ + struct mgsl_struct *next_device; /* device list link */ + + spinlock_t irq_spinlock; /* spinlock for synchronizing with ISR */ + struct work_struct task; /* task structure for scheduling bh */ + + u32 EventMask; /* event trigger mask */ + u32 RecordedEvents; /* pending events */ + + u32 max_frame_size; /* as set by device config */ + + u32 pending_bh; + + bool bh_running; /* Protection from multiple */ + int isr_overflow; + bool bh_requested; + + int dcd_chkcount; /* check counts to prevent */ + int cts_chkcount; /* too many IRQs if a signal */ + int dsr_chkcount; /* is floating */ + int ri_chkcount; + + char *buffer_list; /* virtual address of Rx & Tx buffer lists */ + u32 buffer_list_phys; + dma_addr_t buffer_list_dma_addr; + + unsigned int rx_buffer_count; /* count of total allocated Rx buffers */ + DMABUFFERENTRY *rx_buffer_list; /* list of receive buffer entries */ + unsigned int current_rx_buffer; + + int num_tx_dma_buffers; /* number of tx dma frames required */ + int tx_dma_buffers_used; + unsigned int tx_buffer_count; /* count of total allocated Tx buffers */ + DMABUFFERENTRY *tx_buffer_list; /* list of transmit buffer entries */ + int start_tx_dma_buffer; /* tx dma buffer to start tx dma operation */ + int current_tx_buffer; /* next tx dma buffer to be loaded */ + + unsigned char *intermediate_rxbuffer; + + int num_tx_holding_buffers; /* number of tx holding buffer allocated */ + int get_tx_holding_index; /* next tx holding buffer for adapter to load */ + int put_tx_holding_index; /* next tx holding buffer to store user request */ + int tx_holding_count; /* number of tx holding buffers waiting */ + struct tx_holding_buffer tx_holding_buffers[MAX_TX_HOLDING_BUFFERS]; + + bool rx_enabled; + bool rx_overflow; + bool rx_rcc_underrun; + + bool tx_enabled; + bool tx_active; + u32 idle_mode; + + u16 cmr_value; + u16 tcsr_value; + + char device_name[25]; /* device instance name */ + + unsigned int bus_type; /* expansion bus type (ISA,EISA,PCI) */ + unsigned char bus; /* expansion bus number (zero based) */ + unsigned char function; /* PCI device number */ + + unsigned int io_base; /* base I/O address of adapter */ + unsigned int io_addr_size; /* size of the I/O address range */ + bool io_addr_requested; /* true if I/O address requested */ + + unsigned int irq_level; /* interrupt level */ + unsigned long irq_flags; + bool irq_requested; /* true if IRQ requested */ + + unsigned int dma_level; /* DMA channel */ + bool dma_requested; /* true if dma channel requested */ + + u16 mbre_bit; + u16 loopback_bits; + u16 usc_idle_mode; + + MGSL_PARAMS params; /* communications parameters */ + + unsigned char serial_signals; /* current serial signal states */ + + bool irq_occurred; /* for diagnostics use */ + unsigned int init_error; /* Initialization startup error (DIAGS) */ + int fDiagnosticsmode; /* Driver in Diagnostic mode? (DIAGS) */ + + u32 last_mem_alloc; + unsigned char* memory_base; /* shared memory address (PCI only) */ + u32 phys_memory_base; + bool shared_mem_requested; + + unsigned char* lcr_base; /* local config registers (PCI only) */ + u32 phys_lcr_base; + u32 lcr_offset; + bool lcr_mem_requested; + + u32 misc_ctrl_value; + char flag_buf[MAX_ASYNC_BUFFER_SIZE]; + char char_buf[MAX_ASYNC_BUFFER_SIZE]; + bool drop_rts_on_tx_done; + + bool loopmode_insert_requested; + bool loopmode_send_done_requested; + + struct _input_signal_events input_signal_events; + + /* generic HDLC device parts */ + int netcount; + spinlock_t netlock; + +#if SYNCLINK_GENERIC_HDLC + struct net_device *netdev; +#endif +}; + +#define MGSL_MAGIC 0x5401 + +/* + * The size of the serial xmit buffer is 1 page, or 4096 bytes + */ +#ifndef SERIAL_XMIT_SIZE +#define SERIAL_XMIT_SIZE 4096 +#endif + +/* + * These macros define the offsets used in calculating the + * I/O address of the specified USC registers. + */ + + +#define DCPIN 2 /* Bit 1 of I/O address */ +#define SDPIN 4 /* Bit 2 of I/O address */ + +#define DCAR 0 /* DMA command/address register */ +#define CCAR SDPIN /* channel command/address register */ +#define DATAREG DCPIN + SDPIN /* serial data register */ +#define MSBONLY 0x41 +#define LSBONLY 0x40 + +/* + * These macros define the register address (ordinal number) + * used for writing address/value pairs to the USC. + */ + +#define CMR 0x02 /* Channel mode Register */ +#define CCSR 0x04 /* Channel Command/status Register */ +#define CCR 0x06 /* Channel Control Register */ +#define PSR 0x08 /* Port status Register */ +#define PCR 0x0a /* Port Control Register */ +#define TMDR 0x0c /* Test mode Data Register */ +#define TMCR 0x0e /* Test mode Control Register */ +#define CMCR 0x10 /* Clock mode Control Register */ +#define HCR 0x12 /* Hardware Configuration Register */ +#define IVR 0x14 /* Interrupt Vector Register */ +#define IOCR 0x16 /* Input/Output Control Register */ +#define ICR 0x18 /* Interrupt Control Register */ +#define DCCR 0x1a /* Daisy Chain Control Register */ +#define MISR 0x1c /* Misc Interrupt status Register */ +#define SICR 0x1e /* status Interrupt Control Register */ +#define RDR 0x20 /* Receive Data Register */ +#define RMR 0x22 /* Receive mode Register */ +#define RCSR 0x24 /* Receive Command/status Register */ +#define RICR 0x26 /* Receive Interrupt Control Register */ +#define RSR 0x28 /* Receive Sync Register */ +#define RCLR 0x2a /* Receive count Limit Register */ +#define RCCR 0x2c /* Receive Character count Register */ +#define TC0R 0x2e /* Time Constant 0 Register */ +#define TDR 0x30 /* Transmit Data Register */ +#define TMR 0x32 /* Transmit mode Register */ +#define TCSR 0x34 /* Transmit Command/status Register */ +#define TICR 0x36 /* Transmit Interrupt Control Register */ +#define TSR 0x38 /* Transmit Sync Register */ +#define TCLR 0x3a /* Transmit count Limit Register */ +#define TCCR 0x3c /* Transmit Character count Register */ +#define TC1R 0x3e /* Time Constant 1 Register */ + + +/* + * MACRO DEFINITIONS FOR DMA REGISTERS + */ + +#define DCR 0x06 /* DMA Control Register (shared) */ +#define DACR 0x08 /* DMA Array count Register (shared) */ +#define BDCR 0x12 /* Burst/Dwell Control Register (shared) */ +#define DIVR 0x14 /* DMA Interrupt Vector Register (shared) */ +#define DICR 0x18 /* DMA Interrupt Control Register (shared) */ +#define CDIR 0x1a /* Clear DMA Interrupt Register (shared) */ +#define SDIR 0x1c /* Set DMA Interrupt Register (shared) */ + +#define TDMR 0x02 /* Transmit DMA mode Register */ +#define TDIAR 0x1e /* Transmit DMA Interrupt Arm Register */ +#define TBCR 0x2a /* Transmit Byte count Register */ +#define TARL 0x2c /* Transmit Address Register (low) */ +#define TARU 0x2e /* Transmit Address Register (high) */ +#define NTBCR 0x3a /* Next Transmit Byte count Register */ +#define NTARL 0x3c /* Next Transmit Address Register (low) */ +#define NTARU 0x3e /* Next Transmit Address Register (high) */ + +#define RDMR 0x82 /* Receive DMA mode Register (non-shared) */ +#define RDIAR 0x9e /* Receive DMA Interrupt Arm Register */ +#define RBCR 0xaa /* Receive Byte count Register */ +#define RARL 0xac /* Receive Address Register (low) */ +#define RARU 0xae /* Receive Address Register (high) */ +#define NRBCR 0xba /* Next Receive Byte count Register */ +#define NRARL 0xbc /* Next Receive Address Register (low) */ +#define NRARU 0xbe /* Next Receive Address Register (high) */ + + +/* + * MACRO DEFINITIONS FOR MODEM STATUS BITS + */ + +#define MODEMSTATUS_DTR 0x80 +#define MODEMSTATUS_DSR 0x40 +#define MODEMSTATUS_RTS 0x20 +#define MODEMSTATUS_CTS 0x10 +#define MODEMSTATUS_RI 0x04 +#define MODEMSTATUS_DCD 0x01 + + +/* + * Channel Command/Address Register (CCAR) Command Codes + */ + +#define RTCmd_Null 0x0000 +#define RTCmd_ResetHighestIus 0x1000 +#define RTCmd_TriggerChannelLoadDma 0x2000 +#define RTCmd_TriggerRxDma 0x2800 +#define RTCmd_TriggerTxDma 0x3000 +#define RTCmd_TriggerRxAndTxDma 0x3800 +#define RTCmd_PurgeRxFifo 0x4800 +#define RTCmd_PurgeTxFifo 0x5000 +#define RTCmd_PurgeRxAndTxFifo 0x5800 +#define RTCmd_LoadRcc 0x6800 +#define RTCmd_LoadTcc 0x7000 +#define RTCmd_LoadRccAndTcc 0x7800 +#define RTCmd_LoadTC0 0x8800 +#define RTCmd_LoadTC1 0x9000 +#define RTCmd_LoadTC0AndTC1 0x9800 +#define RTCmd_SerialDataLSBFirst 0xa000 +#define RTCmd_SerialDataMSBFirst 0xa800 +#define RTCmd_SelectBigEndian 0xb000 +#define RTCmd_SelectLittleEndian 0xb800 + + +/* + * DMA Command/Address Register (DCAR) Command Codes + */ + +#define DmaCmd_Null 0x0000 +#define DmaCmd_ResetTxChannel 0x1000 +#define DmaCmd_ResetRxChannel 0x1200 +#define DmaCmd_StartTxChannel 0x2000 +#define DmaCmd_StartRxChannel 0x2200 +#define DmaCmd_ContinueTxChannel 0x3000 +#define DmaCmd_ContinueRxChannel 0x3200 +#define DmaCmd_PauseTxChannel 0x4000 +#define DmaCmd_PauseRxChannel 0x4200 +#define DmaCmd_AbortTxChannel 0x5000 +#define DmaCmd_AbortRxChannel 0x5200 +#define DmaCmd_InitTxChannel 0x7000 +#define DmaCmd_InitRxChannel 0x7200 +#define DmaCmd_ResetHighestDmaIus 0x8000 +#define DmaCmd_ResetAllChannels 0x9000 +#define DmaCmd_StartAllChannels 0xa000 +#define DmaCmd_ContinueAllChannels 0xb000 +#define DmaCmd_PauseAllChannels 0xc000 +#define DmaCmd_AbortAllChannels 0xd000 +#define DmaCmd_InitAllChannels 0xf000 + +#define TCmd_Null 0x0000 +#define TCmd_ClearTxCRC 0x2000 +#define TCmd_SelectTicrTtsaData 0x4000 +#define TCmd_SelectTicrTxFifostatus 0x5000 +#define TCmd_SelectTicrIntLevel 0x6000 +#define TCmd_SelectTicrdma_level 0x7000 +#define TCmd_SendFrame 0x8000 +#define TCmd_SendAbort 0x9000 +#define TCmd_EnableDleInsertion 0xc000 +#define TCmd_DisableDleInsertion 0xd000 +#define TCmd_ClearEofEom 0xe000 +#define TCmd_SetEofEom 0xf000 + +#define RCmd_Null 0x0000 +#define RCmd_ClearRxCRC 0x2000 +#define RCmd_EnterHuntmode 0x3000 +#define RCmd_SelectRicrRtsaData 0x4000 +#define RCmd_SelectRicrRxFifostatus 0x5000 +#define RCmd_SelectRicrIntLevel 0x6000 +#define RCmd_SelectRicrdma_level 0x7000 + +/* + * Bits for enabling and disabling IRQs in Interrupt Control Register (ICR) + */ + +#define RECEIVE_STATUS BIT5 +#define RECEIVE_DATA BIT4 +#define TRANSMIT_STATUS BIT3 +#define TRANSMIT_DATA BIT2 +#define IO_PIN BIT1 +#define MISC BIT0 + + +/* + * Receive status Bits in Receive Command/status Register RCSR + */ + +#define RXSTATUS_SHORT_FRAME BIT8 +#define RXSTATUS_CODE_VIOLATION BIT8 +#define RXSTATUS_EXITED_HUNT BIT7 +#define RXSTATUS_IDLE_RECEIVED BIT6 +#define RXSTATUS_BREAK_RECEIVED BIT5 +#define RXSTATUS_ABORT_RECEIVED BIT5 +#define RXSTATUS_RXBOUND BIT4 +#define RXSTATUS_CRC_ERROR BIT3 +#define RXSTATUS_FRAMING_ERROR BIT3 +#define RXSTATUS_ABORT BIT2 +#define RXSTATUS_PARITY_ERROR BIT2 +#define RXSTATUS_OVERRUN BIT1 +#define RXSTATUS_DATA_AVAILABLE BIT0 +#define RXSTATUS_ALL 0x01f6 +#define usc_UnlatchRxstatusBits(a,b) usc_OutReg( (a), RCSR, (u16)((b) & RXSTATUS_ALL) ) + +/* + * Values for setting transmit idle mode in + * Transmit Control/status Register (TCSR) + */ +#define IDLEMODE_FLAGS 0x0000 +#define IDLEMODE_ALT_ONE_ZERO 0x0100 +#define IDLEMODE_ZERO 0x0200 +#define IDLEMODE_ONE 0x0300 +#define IDLEMODE_ALT_MARK_SPACE 0x0500 +#define IDLEMODE_SPACE 0x0600 +#define IDLEMODE_MARK 0x0700 +#define IDLEMODE_MASK 0x0700 + +/* + * IUSC revision identifiers + */ +#define IUSC_SL1660 0x4d44 +#define IUSC_PRE_SL1660 0x4553 + +/* + * Transmit status Bits in Transmit Command/status Register (TCSR) + */ + +#define TCSR_PRESERVE 0x0F00 + +#define TCSR_UNDERWAIT BIT11 +#define TXSTATUS_PREAMBLE_SENT BIT7 +#define TXSTATUS_IDLE_SENT BIT6 +#define TXSTATUS_ABORT_SENT BIT5 +#define TXSTATUS_EOF_SENT BIT4 +#define TXSTATUS_EOM_SENT BIT4 +#define TXSTATUS_CRC_SENT BIT3 +#define TXSTATUS_ALL_SENT BIT2 +#define TXSTATUS_UNDERRUN BIT1 +#define TXSTATUS_FIFO_EMPTY BIT0 +#define TXSTATUS_ALL 0x00fa +#define usc_UnlatchTxstatusBits(a,b) usc_OutReg( (a), TCSR, (u16)((a)->tcsr_value + ((b) & 0x00FF)) ) + + +#define MISCSTATUS_RXC_LATCHED BIT15 +#define MISCSTATUS_RXC BIT14 +#define MISCSTATUS_TXC_LATCHED BIT13 +#define MISCSTATUS_TXC BIT12 +#define MISCSTATUS_RI_LATCHED BIT11 +#define MISCSTATUS_RI BIT10 +#define MISCSTATUS_DSR_LATCHED BIT9 +#define MISCSTATUS_DSR BIT8 +#define MISCSTATUS_DCD_LATCHED BIT7 +#define MISCSTATUS_DCD BIT6 +#define MISCSTATUS_CTS_LATCHED BIT5 +#define MISCSTATUS_CTS BIT4 +#define MISCSTATUS_RCC_UNDERRUN BIT3 +#define MISCSTATUS_DPLL_NO_SYNC BIT2 +#define MISCSTATUS_BRG1_ZERO BIT1 +#define MISCSTATUS_BRG0_ZERO BIT0 + +#define usc_UnlatchIostatusBits(a,b) usc_OutReg((a),MISR,(u16)((b) & 0xaaa0)) +#define usc_UnlatchMiscstatusBits(a,b) usc_OutReg((a),MISR,(u16)((b) & 0x000f)) + +#define SICR_RXC_ACTIVE BIT15 +#define SICR_RXC_INACTIVE BIT14 +#define SICR_RXC (BIT15+BIT14) +#define SICR_TXC_ACTIVE BIT13 +#define SICR_TXC_INACTIVE BIT12 +#define SICR_TXC (BIT13+BIT12) +#define SICR_RI_ACTIVE BIT11 +#define SICR_RI_INACTIVE BIT10 +#define SICR_RI (BIT11+BIT10) +#define SICR_DSR_ACTIVE BIT9 +#define SICR_DSR_INACTIVE BIT8 +#define SICR_DSR (BIT9+BIT8) +#define SICR_DCD_ACTIVE BIT7 +#define SICR_DCD_INACTIVE BIT6 +#define SICR_DCD (BIT7+BIT6) +#define SICR_CTS_ACTIVE BIT5 +#define SICR_CTS_INACTIVE BIT4 +#define SICR_CTS (BIT5+BIT4) +#define SICR_RCC_UNDERFLOW BIT3 +#define SICR_DPLL_NO_SYNC BIT2 +#define SICR_BRG1_ZERO BIT1 +#define SICR_BRG0_ZERO BIT0 + +void usc_DisableMasterIrqBit( struct mgsl_struct *info ); +void usc_EnableMasterIrqBit( struct mgsl_struct *info ); +void usc_EnableInterrupts( struct mgsl_struct *info, u16 IrqMask ); +void usc_DisableInterrupts( struct mgsl_struct *info, u16 IrqMask ); +void usc_ClearIrqPendingBits( struct mgsl_struct *info, u16 IrqMask ); + +#define usc_EnableInterrupts( a, b ) \ + usc_OutReg( (a), ICR, (u16)((usc_InReg((a),ICR) & 0xff00) + 0xc0 + (b)) ) + +#define usc_DisableInterrupts( a, b ) \ + usc_OutReg( (a), ICR, (u16)((usc_InReg((a),ICR) & 0xff00) + 0x80 + (b)) ) + +#define usc_EnableMasterIrqBit(a) \ + usc_OutReg( (a), ICR, (u16)((usc_InReg((a),ICR) & 0x0f00) + 0xb000) ) + +#define usc_DisableMasterIrqBit(a) \ + usc_OutReg( (a), ICR, (u16)(usc_InReg((a),ICR) & 0x7f00) ) + +#define usc_ClearIrqPendingBits( a, b ) usc_OutReg( (a), DCCR, 0x40 + (b) ) + +/* + * Transmit status Bits in Transmit Control status Register (TCSR) + * and Transmit Interrupt Control Register (TICR) (except BIT2, BIT0) + */ + +#define TXSTATUS_PREAMBLE_SENT BIT7 +#define TXSTATUS_IDLE_SENT BIT6 +#define TXSTATUS_ABORT_SENT BIT5 +#define TXSTATUS_EOF BIT4 +#define TXSTATUS_CRC_SENT BIT3 +#define TXSTATUS_ALL_SENT BIT2 +#define TXSTATUS_UNDERRUN BIT1 +#define TXSTATUS_FIFO_EMPTY BIT0 + +#define DICR_MASTER BIT15 +#define DICR_TRANSMIT BIT0 +#define DICR_RECEIVE BIT1 + +#define usc_EnableDmaInterrupts(a,b) \ + usc_OutDmaReg( (a), DICR, (u16)(usc_InDmaReg((a),DICR) | (b)) ) + +#define usc_DisableDmaInterrupts(a,b) \ + usc_OutDmaReg( (a), DICR, (u16)(usc_InDmaReg((a),DICR) & ~(b)) ) + +#define usc_EnableStatusIrqs(a,b) \ + usc_OutReg( (a), SICR, (u16)(usc_InReg((a),SICR) | (b)) ) + +#define usc_DisablestatusIrqs(a,b) \ + usc_OutReg( (a), SICR, (u16)(usc_InReg((a),SICR) & ~(b)) ) + +/* Transmit status Bits in Transmit Control status Register (TCSR) */ +/* and Transmit Interrupt Control Register (TICR) (except BIT2, BIT0) */ + + +#define DISABLE_UNCONDITIONAL 0 +#define DISABLE_END_OF_FRAME 1 +#define ENABLE_UNCONDITIONAL 2 +#define ENABLE_AUTO_CTS 3 +#define ENABLE_AUTO_DCD 3 +#define usc_EnableTransmitter(a,b) \ + usc_OutReg( (a), TMR, (u16)((usc_InReg((a),TMR) & 0xfffc) | (b)) ) +#define usc_EnableReceiver(a,b) \ + usc_OutReg( (a), RMR, (u16)((usc_InReg((a),RMR) & 0xfffc) | (b)) ) + +static u16 usc_InDmaReg( struct mgsl_struct *info, u16 Port ); +static void usc_OutDmaReg( struct mgsl_struct *info, u16 Port, u16 Value ); +static void usc_DmaCmd( struct mgsl_struct *info, u16 Cmd ); + +static u16 usc_InReg( struct mgsl_struct *info, u16 Port ); +static void usc_OutReg( struct mgsl_struct *info, u16 Port, u16 Value ); +static void usc_RTCmd( struct mgsl_struct *info, u16 Cmd ); +void usc_RCmd( struct mgsl_struct *info, u16 Cmd ); +void usc_TCmd( struct mgsl_struct *info, u16 Cmd ); + +#define usc_TCmd(a,b) usc_OutReg((a), TCSR, (u16)((a)->tcsr_value + (b))) +#define usc_RCmd(a,b) usc_OutReg((a), RCSR, (b)) + +#define usc_SetTransmitSyncChars(a,s0,s1) usc_OutReg((a), TSR, (u16)(((u16)s0<<8)|(u16)s1)) + +static void usc_process_rxoverrun_sync( struct mgsl_struct *info ); +static void usc_start_receiver( struct mgsl_struct *info ); +static void usc_stop_receiver( struct mgsl_struct *info ); + +static void usc_start_transmitter( struct mgsl_struct *info ); +static void usc_stop_transmitter( struct mgsl_struct *info ); +static void usc_set_txidle( struct mgsl_struct *info ); +static void usc_load_txfifo( struct mgsl_struct *info ); + +static void usc_enable_aux_clock( struct mgsl_struct *info, u32 DataRate ); +static void usc_enable_loopback( struct mgsl_struct *info, int enable ); + +static void usc_get_serial_signals( struct mgsl_struct *info ); +static void usc_set_serial_signals( struct mgsl_struct *info ); + +static void usc_reset( struct mgsl_struct *info ); + +static void usc_set_sync_mode( struct mgsl_struct *info ); +static void usc_set_sdlc_mode( struct mgsl_struct *info ); +static void usc_set_async_mode( struct mgsl_struct *info ); +static void usc_enable_async_clock( struct mgsl_struct *info, u32 DataRate ); + +static void usc_loopback_frame( struct mgsl_struct *info ); + +static void mgsl_tx_timeout(unsigned long context); + + +static void usc_loopmode_cancel_transmit( struct mgsl_struct * info ); +static void usc_loopmode_insert_request( struct mgsl_struct * info ); +static int usc_loopmode_active( struct mgsl_struct * info); +static void usc_loopmode_send_done( struct mgsl_struct * info ); + +static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg); + +#if SYNCLINK_GENERIC_HDLC +#define dev_to_port(D) (dev_to_hdlc(D)->priv) +static void hdlcdev_tx_done(struct mgsl_struct *info); +static void hdlcdev_rx(struct mgsl_struct *info, char *buf, int size); +static int hdlcdev_init(struct mgsl_struct *info); +static void hdlcdev_exit(struct mgsl_struct *info); +#endif + +/* + * Defines a BUS descriptor value for the PCI adapter + * local bus address ranges. + */ + +#define BUS_DESCRIPTOR( WrHold, WrDly, RdDly, Nwdd, Nwad, Nxda, Nrdd, Nrad ) \ +(0x00400020 + \ +((WrHold) << 30) + \ +((WrDly) << 28) + \ +((RdDly) << 26) + \ +((Nwdd) << 20) + \ +((Nwad) << 15) + \ +((Nxda) << 13) + \ +((Nrdd) << 11) + \ +((Nrad) << 6) ) + +static void mgsl_trace_block(struct mgsl_struct *info,const char* data, int count, int xmit); + +/* + * Adapter diagnostic routines + */ +static bool mgsl_register_test( struct mgsl_struct *info ); +static bool mgsl_irq_test( struct mgsl_struct *info ); +static bool mgsl_dma_test( struct mgsl_struct *info ); +static bool mgsl_memory_test( struct mgsl_struct *info ); +static int mgsl_adapter_test( struct mgsl_struct *info ); + +/* + * device and resource management routines + */ +static int mgsl_claim_resources(struct mgsl_struct *info); +static void mgsl_release_resources(struct mgsl_struct *info); +static void mgsl_add_device(struct mgsl_struct *info); +static struct mgsl_struct* mgsl_allocate_device(void); + +/* + * DMA buffer manupulation functions. + */ +static void mgsl_free_rx_frame_buffers( struct mgsl_struct *info, unsigned int StartIndex, unsigned int EndIndex ); +static bool mgsl_get_rx_frame( struct mgsl_struct *info ); +static bool mgsl_get_raw_rx_frame( struct mgsl_struct *info ); +static void mgsl_reset_rx_dma_buffers( struct mgsl_struct *info ); +static void mgsl_reset_tx_dma_buffers( struct mgsl_struct *info ); +static int num_free_tx_dma_buffers(struct mgsl_struct *info); +static void mgsl_load_tx_dma_buffer( struct mgsl_struct *info, const char *Buffer, unsigned int BufferSize); +static void mgsl_load_pci_memory(char* TargetPtr, const char* SourcePtr, unsigned short count); + +/* + * DMA and Shared Memory buffer allocation and formatting + */ +static int mgsl_allocate_dma_buffers(struct mgsl_struct *info); +static void mgsl_free_dma_buffers(struct mgsl_struct *info); +static int mgsl_alloc_frame_memory(struct mgsl_struct *info, DMABUFFERENTRY *BufferList,int Buffercount); +static void mgsl_free_frame_memory(struct mgsl_struct *info, DMABUFFERENTRY *BufferList,int Buffercount); +static int mgsl_alloc_buffer_list_memory(struct mgsl_struct *info); +static void mgsl_free_buffer_list_memory(struct mgsl_struct *info); +static int mgsl_alloc_intermediate_rxbuffer_memory(struct mgsl_struct *info); +static void mgsl_free_intermediate_rxbuffer_memory(struct mgsl_struct *info); +static int mgsl_alloc_intermediate_txbuffer_memory(struct mgsl_struct *info); +static void mgsl_free_intermediate_txbuffer_memory(struct mgsl_struct *info); +static bool load_next_tx_holding_buffer(struct mgsl_struct *info); +static int save_tx_buffer_request(struct mgsl_struct *info,const char *Buffer, unsigned int BufferSize); + +/* + * Bottom half interrupt handlers + */ +static void mgsl_bh_handler(struct work_struct *work); +static void mgsl_bh_receive(struct mgsl_struct *info); +static void mgsl_bh_transmit(struct mgsl_struct *info); +static void mgsl_bh_status(struct mgsl_struct *info); + +/* + * Interrupt handler routines and dispatch table. + */ +static void mgsl_isr_null( struct mgsl_struct *info ); +static void mgsl_isr_transmit_data( struct mgsl_struct *info ); +static void mgsl_isr_receive_data( struct mgsl_struct *info ); +static void mgsl_isr_receive_status( struct mgsl_struct *info ); +static void mgsl_isr_transmit_status( struct mgsl_struct *info ); +static void mgsl_isr_io_pin( struct mgsl_struct *info ); +static void mgsl_isr_misc( struct mgsl_struct *info ); +static void mgsl_isr_receive_dma( struct mgsl_struct *info ); +static void mgsl_isr_transmit_dma( struct mgsl_struct *info ); + +typedef void (*isr_dispatch_func)(struct mgsl_struct *); + +static isr_dispatch_func UscIsrTable[7] = +{ + mgsl_isr_null, + mgsl_isr_misc, + mgsl_isr_io_pin, + mgsl_isr_transmit_data, + mgsl_isr_transmit_status, + mgsl_isr_receive_data, + mgsl_isr_receive_status +}; + +/* + * ioctl call handlers + */ +static int tiocmget(struct tty_struct *tty); +static int tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear); +static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount + __user *user_icount); +static int mgsl_get_params(struct mgsl_struct * info, MGSL_PARAMS __user *user_params); +static int mgsl_set_params(struct mgsl_struct * info, MGSL_PARAMS __user *new_params); +static int mgsl_get_txidle(struct mgsl_struct * info, int __user *idle_mode); +static int mgsl_set_txidle(struct mgsl_struct * info, int idle_mode); +static int mgsl_txenable(struct mgsl_struct * info, int enable); +static int mgsl_txabort(struct mgsl_struct * info); +static int mgsl_rxenable(struct mgsl_struct * info, int enable); +static int mgsl_wait_event(struct mgsl_struct * info, int __user *mask); +static int mgsl_loopmode_send_done( struct mgsl_struct * info ); + +/* set non-zero on successful registration with PCI subsystem */ +static bool pci_registered; + +/* + * Global linked list of SyncLink devices + */ +static struct mgsl_struct *mgsl_device_list; +static int mgsl_device_count; + +/* + * Set this param to non-zero to load eax with the + * .text section address and breakpoint on module load. + * This is useful for use with gdb and add-symbol-file command. + */ +static int break_on_load; + +/* + * Driver major number, defaults to zero to get auto + * assigned major number. May be forced as module parameter. + */ +static int ttymajor; + +/* + * Array of user specified options for ISA adapters. + */ +static int io[MAX_ISA_DEVICES]; +static int irq[MAX_ISA_DEVICES]; +static int dma[MAX_ISA_DEVICES]; +static int debug_level; +static int maxframe[MAX_TOTAL_DEVICES]; +static int txdmabufs[MAX_TOTAL_DEVICES]; +static int txholdbufs[MAX_TOTAL_DEVICES]; + +module_param(break_on_load, bool, 0); +module_param(ttymajor, int, 0); +module_param_array(io, int, NULL, 0); +module_param_array(irq, int, NULL, 0); +module_param_array(dma, int, NULL, 0); +module_param(debug_level, int, 0); +module_param_array(maxframe, int, NULL, 0); +module_param_array(txdmabufs, int, NULL, 0); +module_param_array(txholdbufs, int, NULL, 0); + +static char *driver_name = "SyncLink serial driver"; +static char *driver_version = "$Revision: 4.38 $"; + +static int synclink_init_one (struct pci_dev *dev, + const struct pci_device_id *ent); +static void synclink_remove_one (struct pci_dev *dev); + +static struct pci_device_id synclink_pci_tbl[] = { + { PCI_VENDOR_ID_MICROGATE, PCI_DEVICE_ID_MICROGATE_USC, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_MICROGATE, 0x0210, PCI_ANY_ID, PCI_ANY_ID, }, + { 0, }, /* terminate list */ +}; +MODULE_DEVICE_TABLE(pci, synclink_pci_tbl); + +MODULE_LICENSE("GPL"); + +static struct pci_driver synclink_pci_driver = { + .name = "synclink", + .id_table = synclink_pci_tbl, + .probe = synclink_init_one, + .remove = __devexit_p(synclink_remove_one), +}; + +static struct tty_driver *serial_driver; + +/* number of characters left in xmit buffer before we ask for more */ +#define WAKEUP_CHARS 256 + + +static void mgsl_change_params(struct mgsl_struct *info); +static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout); + +/* + * 1st function defined in .text section. Calling this function in + * init_module() followed by a breakpoint allows a remote debugger + * (gdb) to get the .text address for the add-symbol-file command. + * This allows remote debugging of dynamically loadable modules. + */ +static void* mgsl_get_text_ptr(void) +{ + return mgsl_get_text_ptr; +} + +static inline int mgsl_paranoia_check(struct mgsl_struct *info, + char *name, const char *routine) +{ +#ifdef MGSL_PARANOIA_CHECK + static const char *badmagic = + "Warning: bad magic number for mgsl struct (%s) in %s\n"; + static const char *badinfo = + "Warning: null mgsl_struct for (%s) in %s\n"; + + if (!info) { + printk(badinfo, name, routine); + return 1; + } + if (info->magic != MGSL_MAGIC) { + printk(badmagic, name, routine); + return 1; + } +#else + if (!info) + return 1; +#endif + return 0; +} + +/** + * line discipline callback wrappers + * + * The wrappers maintain line discipline references + * while calling into the line discipline. + * + * ldisc_receive_buf - pass receive data to line discipline + */ + +static void ldisc_receive_buf(struct tty_struct *tty, + const __u8 *data, char *flags, int count) +{ + struct tty_ldisc *ld; + if (!tty) + return; + ld = tty_ldisc_ref(tty); + if (ld) { + if (ld->ops->receive_buf) + ld->ops->receive_buf(tty, data, flags, count); + tty_ldisc_deref(ld); + } +} + +/* mgsl_stop() throttle (stop) transmitter + * + * Arguments: tty pointer to tty info structure + * Return Value: None + */ +static void mgsl_stop(struct tty_struct *tty) +{ + struct mgsl_struct *info = tty->driver_data; + unsigned long flags; + + if (mgsl_paranoia_check(info, tty->name, "mgsl_stop")) + return; + + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk("mgsl_stop(%s)\n",info->device_name); + + spin_lock_irqsave(&info->irq_spinlock,flags); + if (info->tx_enabled) + usc_stop_transmitter(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + +} /* end of mgsl_stop() */ + +/* mgsl_start() release (start) transmitter + * + * Arguments: tty pointer to tty info structure + * Return Value: None + */ +static void mgsl_start(struct tty_struct *tty) +{ + struct mgsl_struct *info = tty->driver_data; + unsigned long flags; + + if (mgsl_paranoia_check(info, tty->name, "mgsl_start")) + return; + + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk("mgsl_start(%s)\n",info->device_name); + + spin_lock_irqsave(&info->irq_spinlock,flags); + if (!info->tx_enabled) + usc_start_transmitter(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + +} /* end of mgsl_start() */ + +/* + * Bottom half work queue access functions + */ + +/* mgsl_bh_action() Return next bottom half action to perform. + * Return Value: BH action code or 0 if nothing to do. + */ +static int mgsl_bh_action(struct mgsl_struct *info) +{ + unsigned long flags; + int rc = 0; + + spin_lock_irqsave(&info->irq_spinlock,flags); + + if (info->pending_bh & BH_RECEIVE) { + info->pending_bh &= ~BH_RECEIVE; + rc = BH_RECEIVE; + } else if (info->pending_bh & BH_TRANSMIT) { + info->pending_bh &= ~BH_TRANSMIT; + rc = BH_TRANSMIT; + } else if (info->pending_bh & BH_STATUS) { + info->pending_bh &= ~BH_STATUS; + rc = BH_STATUS; + } + + if (!rc) { + /* Mark BH routine as complete */ + info->bh_running = false; + info->bh_requested = false; + } + + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + return rc; +} + +/* + * Perform bottom half processing of work items queued by ISR. + */ +static void mgsl_bh_handler(struct work_struct *work) +{ + struct mgsl_struct *info = + container_of(work, struct mgsl_struct, task); + int action; + + if (!info) + return; + + if ( debug_level >= DEBUG_LEVEL_BH ) + printk( "%s(%d):mgsl_bh_handler(%s) entry\n", + __FILE__,__LINE__,info->device_name); + + info->bh_running = true; + + while((action = mgsl_bh_action(info)) != 0) { + + /* Process work item */ + if ( debug_level >= DEBUG_LEVEL_BH ) + printk( "%s(%d):mgsl_bh_handler() work item action=%d\n", + __FILE__,__LINE__,action); + + switch (action) { + + case BH_RECEIVE: + mgsl_bh_receive(info); + break; + case BH_TRANSMIT: + mgsl_bh_transmit(info); + break; + case BH_STATUS: + mgsl_bh_status(info); + break; + default: + /* unknown work item ID */ + printk("Unknown work item ID=%08X!\n", action); + break; + } + } + + if ( debug_level >= DEBUG_LEVEL_BH ) + printk( "%s(%d):mgsl_bh_handler(%s) exit\n", + __FILE__,__LINE__,info->device_name); +} + +static void mgsl_bh_receive(struct mgsl_struct *info) +{ + bool (*get_rx_frame)(struct mgsl_struct *info) = + (info->params.mode == MGSL_MODE_HDLC ? mgsl_get_rx_frame : mgsl_get_raw_rx_frame); + + if ( debug_level >= DEBUG_LEVEL_BH ) + printk( "%s(%d):mgsl_bh_receive(%s)\n", + __FILE__,__LINE__,info->device_name); + + do + { + if (info->rx_rcc_underrun) { + unsigned long flags; + spin_lock_irqsave(&info->irq_spinlock,flags); + usc_start_receiver(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + return; + } + } while(get_rx_frame(info)); +} + +static void mgsl_bh_transmit(struct mgsl_struct *info) +{ + struct tty_struct *tty = info->port.tty; + unsigned long flags; + + if ( debug_level >= DEBUG_LEVEL_BH ) + printk( "%s(%d):mgsl_bh_transmit() entry on %s\n", + __FILE__,__LINE__,info->device_name); + + if (tty) + tty_wakeup(tty); + + /* if transmitter idle and loopmode_send_done_requested + * then start echoing RxD to TxD + */ + spin_lock_irqsave(&info->irq_spinlock,flags); + if ( !info->tx_active && info->loopmode_send_done_requested ) + usc_loopmode_send_done( info ); + spin_unlock_irqrestore(&info->irq_spinlock,flags); +} + +static void mgsl_bh_status(struct mgsl_struct *info) +{ + if ( debug_level >= DEBUG_LEVEL_BH ) + printk( "%s(%d):mgsl_bh_status() entry on %s\n", + __FILE__,__LINE__,info->device_name); + + info->ri_chkcount = 0; + info->dsr_chkcount = 0; + info->dcd_chkcount = 0; + info->cts_chkcount = 0; +} + +/* mgsl_isr_receive_status() + * + * Service a receive status interrupt. The type of status + * interrupt is indicated by the state of the RCSR. + * This is only used for HDLC mode. + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void mgsl_isr_receive_status( struct mgsl_struct *info ) +{ + u16 status = usc_InReg( info, RCSR ); + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):mgsl_isr_receive_status status=%04X\n", + __FILE__,__LINE__,status); + + if ( (status & RXSTATUS_ABORT_RECEIVED) && + info->loopmode_insert_requested && + usc_loopmode_active(info) ) + { + ++info->icount.rxabort; + info->loopmode_insert_requested = false; + + /* clear CMR:13 to start echoing RxD to TxD */ + info->cmr_value &= ~BIT13; + usc_OutReg(info, CMR, info->cmr_value); + + /* disable received abort irq (no longer required) */ + usc_OutReg(info, RICR, + (usc_InReg(info, RICR) & ~RXSTATUS_ABORT_RECEIVED)); + } + + if (status & (RXSTATUS_EXITED_HUNT + RXSTATUS_IDLE_RECEIVED)) { + if (status & RXSTATUS_EXITED_HUNT) + info->icount.exithunt++; + if (status & RXSTATUS_IDLE_RECEIVED) + info->icount.rxidle++; + wake_up_interruptible(&info->event_wait_q); + } + + if (status & RXSTATUS_OVERRUN){ + info->icount.rxover++; + usc_process_rxoverrun_sync( info ); + } + + usc_ClearIrqPendingBits( info, RECEIVE_STATUS ); + usc_UnlatchRxstatusBits( info, status ); + +} /* end of mgsl_isr_receive_status() */ + +/* mgsl_isr_transmit_status() + * + * Service a transmit status interrupt + * HDLC mode :end of transmit frame + * Async mode:all data is sent + * transmit status is indicated by bits in the TCSR. + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void mgsl_isr_transmit_status( struct mgsl_struct *info ) +{ + u16 status = usc_InReg( info, TCSR ); + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):mgsl_isr_transmit_status status=%04X\n", + __FILE__,__LINE__,status); + + usc_ClearIrqPendingBits( info, TRANSMIT_STATUS ); + usc_UnlatchTxstatusBits( info, status ); + + if ( status & (TXSTATUS_UNDERRUN | TXSTATUS_ABORT_SENT) ) + { + /* finished sending HDLC abort. This may leave */ + /* the TxFifo with data from the aborted frame */ + /* so purge the TxFifo. Also shutdown the DMA */ + /* channel in case there is data remaining in */ + /* the DMA buffer */ + usc_DmaCmd( info, DmaCmd_ResetTxChannel ); + usc_RTCmd( info, RTCmd_PurgeTxFifo ); + } + + if ( status & TXSTATUS_EOF_SENT ) + info->icount.txok++; + else if ( status & TXSTATUS_UNDERRUN ) + info->icount.txunder++; + else if ( status & TXSTATUS_ABORT_SENT ) + info->icount.txabort++; + else + info->icount.txunder++; + + info->tx_active = false; + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + del_timer(&info->tx_timer); + + if ( info->drop_rts_on_tx_done ) { + usc_get_serial_signals( info ); + if ( info->serial_signals & SerialSignal_RTS ) { + info->serial_signals &= ~SerialSignal_RTS; + usc_set_serial_signals( info ); + } + info->drop_rts_on_tx_done = false; + } + +#if SYNCLINK_GENERIC_HDLC + if (info->netcount) + hdlcdev_tx_done(info); + else +#endif + { + if (info->port.tty->stopped || info->port.tty->hw_stopped) { + usc_stop_transmitter(info); + return; + } + info->pending_bh |= BH_TRANSMIT; + } + +} /* end of mgsl_isr_transmit_status() */ + +/* mgsl_isr_io_pin() + * + * Service an Input/Output pin interrupt. The type of + * interrupt is indicated by bits in the MISR + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void mgsl_isr_io_pin( struct mgsl_struct *info ) +{ + struct mgsl_icount *icount; + u16 status = usc_InReg( info, MISR ); + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):mgsl_isr_io_pin status=%04X\n", + __FILE__,__LINE__,status); + + usc_ClearIrqPendingBits( info, IO_PIN ); + usc_UnlatchIostatusBits( info, status ); + + if (status & (MISCSTATUS_CTS_LATCHED | MISCSTATUS_DCD_LATCHED | + MISCSTATUS_DSR_LATCHED | MISCSTATUS_RI_LATCHED) ) { + icount = &info->icount; + /* update input line counters */ + if (status & MISCSTATUS_RI_LATCHED) { + if ((info->ri_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT) + usc_DisablestatusIrqs(info,SICR_RI); + icount->rng++; + if ( status & MISCSTATUS_RI ) + info->input_signal_events.ri_up++; + else + info->input_signal_events.ri_down++; + } + if (status & MISCSTATUS_DSR_LATCHED) { + if ((info->dsr_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT) + usc_DisablestatusIrqs(info,SICR_DSR); + icount->dsr++; + if ( status & MISCSTATUS_DSR ) + info->input_signal_events.dsr_up++; + else + info->input_signal_events.dsr_down++; + } + if (status & MISCSTATUS_DCD_LATCHED) { + if ((info->dcd_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT) + usc_DisablestatusIrqs(info,SICR_DCD); + icount->dcd++; + if (status & MISCSTATUS_DCD) { + info->input_signal_events.dcd_up++; + } else + info->input_signal_events.dcd_down++; +#if SYNCLINK_GENERIC_HDLC + if (info->netcount) { + if (status & MISCSTATUS_DCD) + netif_carrier_on(info->netdev); + else + netif_carrier_off(info->netdev); + } +#endif + } + if (status & MISCSTATUS_CTS_LATCHED) + { + if ((info->cts_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT) + usc_DisablestatusIrqs(info,SICR_CTS); + icount->cts++; + if ( status & MISCSTATUS_CTS ) + info->input_signal_events.cts_up++; + else + info->input_signal_events.cts_down++; + } + wake_up_interruptible(&info->status_event_wait_q); + wake_up_interruptible(&info->event_wait_q); + + if ( (info->port.flags & ASYNC_CHECK_CD) && + (status & MISCSTATUS_DCD_LATCHED) ) { + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s CD now %s...", info->device_name, + (status & MISCSTATUS_DCD) ? "on" : "off"); + if (status & MISCSTATUS_DCD) + wake_up_interruptible(&info->port.open_wait); + else { + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("doing serial hangup..."); + if (info->port.tty) + tty_hangup(info->port.tty); + } + } + + if ( (info->port.flags & ASYNC_CTS_FLOW) && + (status & MISCSTATUS_CTS_LATCHED) ) { + if (info->port.tty->hw_stopped) { + if (status & MISCSTATUS_CTS) { + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("CTS tx start..."); + if (info->port.tty) + info->port.tty->hw_stopped = 0; + usc_start_transmitter(info); + info->pending_bh |= BH_TRANSMIT; + return; + } + } else { + if (!(status & MISCSTATUS_CTS)) { + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("CTS tx stop..."); + if (info->port.tty) + info->port.tty->hw_stopped = 1; + usc_stop_transmitter(info); + } + } + } + } + + info->pending_bh |= BH_STATUS; + + /* for diagnostics set IRQ flag */ + if ( status & MISCSTATUS_TXC_LATCHED ){ + usc_OutReg( info, SICR, + (unsigned short)(usc_InReg(info,SICR) & ~(SICR_TXC_ACTIVE+SICR_TXC_INACTIVE)) ); + usc_UnlatchIostatusBits( info, MISCSTATUS_TXC_LATCHED ); + info->irq_occurred = true; + } + +} /* end of mgsl_isr_io_pin() */ + +/* mgsl_isr_transmit_data() + * + * Service a transmit data interrupt (async mode only). + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void mgsl_isr_transmit_data( struct mgsl_struct *info ) +{ + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):mgsl_isr_transmit_data xmit_cnt=%d\n", + __FILE__,__LINE__,info->xmit_cnt); + + usc_ClearIrqPendingBits( info, TRANSMIT_DATA ); + + if (info->port.tty->stopped || info->port.tty->hw_stopped) { + usc_stop_transmitter(info); + return; + } + + if ( info->xmit_cnt ) + usc_load_txfifo( info ); + else + info->tx_active = false; + + if (info->xmit_cnt < WAKEUP_CHARS) + info->pending_bh |= BH_TRANSMIT; + +} /* end of mgsl_isr_transmit_data() */ + +/* mgsl_isr_receive_data() + * + * Service a receive data interrupt. This occurs + * when operating in asynchronous interrupt transfer mode. + * The receive data FIFO is flushed to the receive data buffers. + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void mgsl_isr_receive_data( struct mgsl_struct *info ) +{ + int Fifocount; + u16 status; + int work = 0; + unsigned char DataByte; + struct tty_struct *tty = info->port.tty; + struct mgsl_icount *icount = &info->icount; + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):mgsl_isr_receive_data\n", + __FILE__,__LINE__); + + usc_ClearIrqPendingBits( info, RECEIVE_DATA ); + + /* select FIFO status for RICR readback */ + usc_RCmd( info, RCmd_SelectRicrRxFifostatus ); + + /* clear the Wordstatus bit so that status readback */ + /* only reflects the status of this byte */ + usc_OutReg( info, RICR+LSBONLY, (u16)(usc_InReg(info, RICR+LSBONLY) & ~BIT3 )); + + /* flush the receive FIFO */ + + while( (Fifocount = (usc_InReg(info,RICR) >> 8)) ) { + int flag; + + /* read one byte from RxFIFO */ + outw( (inw(info->io_base + CCAR) & 0x0780) | (RDR+LSBONLY), + info->io_base + CCAR ); + DataByte = inb( info->io_base + CCAR ); + + /* get the status of the received byte */ + status = usc_InReg(info, RCSR); + if ( status & (RXSTATUS_FRAMING_ERROR + RXSTATUS_PARITY_ERROR + + RXSTATUS_OVERRUN + RXSTATUS_BREAK_RECEIVED) ) + usc_UnlatchRxstatusBits(info,RXSTATUS_ALL); + + icount->rx++; + + flag = 0; + if ( status & (RXSTATUS_FRAMING_ERROR + RXSTATUS_PARITY_ERROR + + RXSTATUS_OVERRUN + RXSTATUS_BREAK_RECEIVED) ) { + printk("rxerr=%04X\n",status); + /* update error statistics */ + if ( status & RXSTATUS_BREAK_RECEIVED ) { + status &= ~(RXSTATUS_FRAMING_ERROR + RXSTATUS_PARITY_ERROR); + icount->brk++; + } else if (status & RXSTATUS_PARITY_ERROR) + icount->parity++; + else if (status & RXSTATUS_FRAMING_ERROR) + icount->frame++; + else if (status & RXSTATUS_OVERRUN) { + /* must issue purge fifo cmd before */ + /* 16C32 accepts more receive chars */ + usc_RTCmd(info,RTCmd_PurgeRxFifo); + icount->overrun++; + } + + /* discard char if tty control flags say so */ + if (status & info->ignore_status_mask) + continue; + + status &= info->read_status_mask; + + if (status & RXSTATUS_BREAK_RECEIVED) { + flag = TTY_BREAK; + if (info->port.flags & ASYNC_SAK) + do_SAK(tty); + } else if (status & RXSTATUS_PARITY_ERROR) + flag = TTY_PARITY; + else if (status & RXSTATUS_FRAMING_ERROR) + flag = TTY_FRAME; + } /* end of if (error) */ + tty_insert_flip_char(tty, DataByte, flag); + if (status & RXSTATUS_OVERRUN) { + /* Overrun is special, since it's + * reported immediately, and doesn't + * affect the current character + */ + work += tty_insert_flip_char(tty, 0, TTY_OVERRUN); + } + } + + if ( debug_level >= DEBUG_LEVEL_ISR ) { + printk("%s(%d):rx=%d brk=%d parity=%d frame=%d overrun=%d\n", + __FILE__,__LINE__,icount->rx,icount->brk, + icount->parity,icount->frame,icount->overrun); + } + + if(work) + tty_flip_buffer_push(tty); +} + +/* mgsl_isr_misc() + * + * Service a miscellaneous interrupt source. + * + * Arguments: info pointer to device extension (instance data) + * Return Value: None + */ +static void mgsl_isr_misc( struct mgsl_struct *info ) +{ + u16 status = usc_InReg( info, MISR ); + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):mgsl_isr_misc status=%04X\n", + __FILE__,__LINE__,status); + + if ((status & MISCSTATUS_RCC_UNDERRUN) && + (info->params.mode == MGSL_MODE_HDLC)) { + + /* turn off receiver and rx DMA */ + usc_EnableReceiver(info,DISABLE_UNCONDITIONAL); + usc_DmaCmd(info, DmaCmd_ResetRxChannel); + usc_UnlatchRxstatusBits(info, RXSTATUS_ALL); + usc_ClearIrqPendingBits(info, RECEIVE_DATA + RECEIVE_STATUS); + usc_DisableInterrupts(info, RECEIVE_DATA + RECEIVE_STATUS); + + /* schedule BH handler to restart receiver */ + info->pending_bh |= BH_RECEIVE; + info->rx_rcc_underrun = true; + } + + usc_ClearIrqPendingBits( info, MISC ); + usc_UnlatchMiscstatusBits( info, status ); + +} /* end of mgsl_isr_misc() */ + +/* mgsl_isr_null() + * + * Services undefined interrupt vectors from the + * USC. (hence this function SHOULD never be called) + * + * Arguments: info pointer to device extension (instance data) + * Return Value: None + */ +static void mgsl_isr_null( struct mgsl_struct *info ) +{ + +} /* end of mgsl_isr_null() */ + +/* mgsl_isr_receive_dma() + * + * Service a receive DMA channel interrupt. + * For this driver there are two sources of receive DMA interrupts + * as identified in the Receive DMA mode Register (RDMR): + * + * BIT3 EOA/EOL End of List, all receive buffers in receive + * buffer list have been filled (no more free buffers + * available). The DMA controller has shut down. + * + * BIT2 EOB End of Buffer. This interrupt occurs when a receive + * DMA buffer is terminated in response to completion + * of a good frame or a frame with errors. The status + * of the frame is stored in the buffer entry in the + * list of receive buffer entries. + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void mgsl_isr_receive_dma( struct mgsl_struct *info ) +{ + u16 status; + + /* clear interrupt pending and IUS bit for Rx DMA IRQ */ + usc_OutDmaReg( info, CDIR, BIT9+BIT1 ); + + /* Read the receive DMA status to identify interrupt type. */ + /* This also clears the status bits. */ + status = usc_InDmaReg( info, RDMR ); + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):mgsl_isr_receive_dma(%s) status=%04X\n", + __FILE__,__LINE__,info->device_name,status); + + info->pending_bh |= BH_RECEIVE; + + if ( status & BIT3 ) { + info->rx_overflow = true; + info->icount.buf_overrun++; + } + +} /* end of mgsl_isr_receive_dma() */ + +/* mgsl_isr_transmit_dma() + * + * This function services a transmit DMA channel interrupt. + * + * For this driver there is one source of transmit DMA interrupts + * as identified in the Transmit DMA Mode Register (TDMR): + * + * BIT2 EOB End of Buffer. This interrupt occurs when a + * transmit DMA buffer has been emptied. + * + * The driver maintains enough transmit DMA buffers to hold at least + * one max frame size transmit frame. When operating in a buffered + * transmit mode, there may be enough transmit DMA buffers to hold at + * least two or more max frame size frames. On an EOB condition, + * determine if there are any queued transmit buffers and copy into + * transmit DMA buffers if we have room. + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void mgsl_isr_transmit_dma( struct mgsl_struct *info ) +{ + u16 status; + + /* clear interrupt pending and IUS bit for Tx DMA IRQ */ + usc_OutDmaReg(info, CDIR, BIT8+BIT0 ); + + /* Read the transmit DMA status to identify interrupt type. */ + /* This also clears the status bits. */ + + status = usc_InDmaReg( info, TDMR ); + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):mgsl_isr_transmit_dma(%s) status=%04X\n", + __FILE__,__LINE__,info->device_name,status); + + if ( status & BIT2 ) { + --info->tx_dma_buffers_used; + + /* if there are transmit frames queued, + * try to load the next one + */ + if ( load_next_tx_holding_buffer(info) ) { + /* if call returns non-zero value, we have + * at least one free tx holding buffer + */ + info->pending_bh |= BH_TRANSMIT; + } + } + +} /* end of mgsl_isr_transmit_dma() */ + +/* mgsl_interrupt() + * + * Interrupt service routine entry point. + * + * Arguments: + * + * irq interrupt number that caused interrupt + * dev_id device ID supplied during interrupt registration + * + * Return Value: None + */ +static irqreturn_t mgsl_interrupt(int dummy, void *dev_id) +{ + struct mgsl_struct *info = dev_id; + u16 UscVector; + u16 DmaVector; + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk(KERN_DEBUG "%s(%d):mgsl_interrupt(%d)entry.\n", + __FILE__, __LINE__, info->irq_level); + + spin_lock(&info->irq_spinlock); + + for(;;) { + /* Read the interrupt vectors from hardware. */ + UscVector = usc_InReg(info, IVR) >> 9; + DmaVector = usc_InDmaReg(info, DIVR); + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):%s UscVector=%08X DmaVector=%08X\n", + __FILE__,__LINE__,info->device_name,UscVector,DmaVector); + + if ( !UscVector && !DmaVector ) + break; + + /* Dispatch interrupt vector */ + if ( UscVector ) + (*UscIsrTable[UscVector])(info); + else if ( (DmaVector&(BIT10|BIT9)) == BIT10) + mgsl_isr_transmit_dma(info); + else + mgsl_isr_receive_dma(info); + + if ( info->isr_overflow ) { + printk(KERN_ERR "%s(%d):%s isr overflow irq=%d\n", + __FILE__, __LINE__, info->device_name, info->irq_level); + usc_DisableMasterIrqBit(info); + usc_DisableDmaInterrupts(info,DICR_MASTER); + break; + } + } + + /* Request bottom half processing if there's something + * for it to do and the bh is not already running + */ + + if ( info->pending_bh && !info->bh_running && !info->bh_requested ) { + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):%s queueing bh task.\n", + __FILE__,__LINE__,info->device_name); + schedule_work(&info->task); + info->bh_requested = true; + } + + spin_unlock(&info->irq_spinlock); + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk(KERN_DEBUG "%s(%d):mgsl_interrupt(%d)exit.\n", + __FILE__, __LINE__, info->irq_level); + + return IRQ_HANDLED; +} /* end of mgsl_interrupt() */ + +/* startup() + * + * Initialize and start device. + * + * Arguments: info pointer to device instance data + * Return Value: 0 if success, otherwise error code + */ +static int startup(struct mgsl_struct * info) +{ + int retval = 0; + + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk("%s(%d):mgsl_startup(%s)\n",__FILE__,__LINE__,info->device_name); + + if (info->port.flags & ASYNC_INITIALIZED) + return 0; + + if (!info->xmit_buf) { + /* allocate a page of memory for a transmit buffer */ + info->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); + if (!info->xmit_buf) { + printk(KERN_ERR"%s(%d):%s can't allocate transmit buffer\n", + __FILE__,__LINE__,info->device_name); + return -ENOMEM; + } + } + + info->pending_bh = 0; + + memset(&info->icount, 0, sizeof(info->icount)); + + setup_timer(&info->tx_timer, mgsl_tx_timeout, (unsigned long)info); + + /* Allocate and claim adapter resources */ + retval = mgsl_claim_resources(info); + + /* perform existence check and diagnostics */ + if ( !retval ) + retval = mgsl_adapter_test(info); + + if ( retval ) { + if (capable(CAP_SYS_ADMIN) && info->port.tty) + set_bit(TTY_IO_ERROR, &info->port.tty->flags); + mgsl_release_resources(info); + return retval; + } + + /* program hardware for current parameters */ + mgsl_change_params(info); + + if (info->port.tty) + clear_bit(TTY_IO_ERROR, &info->port.tty->flags); + + info->port.flags |= ASYNC_INITIALIZED; + + return 0; + +} /* end of startup() */ + +/* shutdown() + * + * Called by mgsl_close() and mgsl_hangup() to shutdown hardware + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void shutdown(struct mgsl_struct * info) +{ + unsigned long flags; + + if (!(info->port.flags & ASYNC_INITIALIZED)) + return; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_shutdown(%s)\n", + __FILE__,__LINE__, info->device_name ); + + /* clear status wait queue because status changes */ + /* can't happen after shutting down the hardware */ + wake_up_interruptible(&info->status_event_wait_q); + wake_up_interruptible(&info->event_wait_q); + + del_timer_sync(&info->tx_timer); + + if (info->xmit_buf) { + free_page((unsigned long) info->xmit_buf); + info->xmit_buf = NULL; + } + + spin_lock_irqsave(&info->irq_spinlock,flags); + usc_DisableMasterIrqBit(info); + usc_stop_receiver(info); + usc_stop_transmitter(info); + usc_DisableInterrupts(info,RECEIVE_DATA + RECEIVE_STATUS + + TRANSMIT_DATA + TRANSMIT_STATUS + IO_PIN + MISC ); + usc_DisableDmaInterrupts(info,DICR_MASTER + DICR_TRANSMIT + DICR_RECEIVE); + + /* Disable DMAEN (Port 7, Bit 14) */ + /* This disconnects the DMA request signal from the ISA bus */ + /* on the ISA adapter. This has no effect for the PCI adapter */ + usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT15) | BIT14)); + + /* Disable INTEN (Port 6, Bit12) */ + /* This disconnects the IRQ request signal to the ISA bus */ + /* on the ISA adapter. This has no effect for the PCI adapter */ + usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) | BIT12)); + + if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) { + info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); + usc_set_serial_signals(info); + } + + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + mgsl_release_resources(info); + + if (info->port.tty) + set_bit(TTY_IO_ERROR, &info->port.tty->flags); + + info->port.flags &= ~ASYNC_INITIALIZED; + +} /* end of shutdown() */ + +static void mgsl_program_hw(struct mgsl_struct *info) +{ + unsigned long flags; + + spin_lock_irqsave(&info->irq_spinlock,flags); + + usc_stop_receiver(info); + usc_stop_transmitter(info); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + + if (info->params.mode == MGSL_MODE_HDLC || + info->params.mode == MGSL_MODE_RAW || + info->netcount) + usc_set_sync_mode(info); + else + usc_set_async_mode(info); + + usc_set_serial_signals(info); + + info->dcd_chkcount = 0; + info->cts_chkcount = 0; + info->ri_chkcount = 0; + info->dsr_chkcount = 0; + + usc_EnableStatusIrqs(info,SICR_CTS+SICR_DSR+SICR_DCD+SICR_RI); + usc_EnableInterrupts(info, IO_PIN); + usc_get_serial_signals(info); + + if (info->netcount || info->port.tty->termios->c_cflag & CREAD) + usc_start_receiver(info); + + spin_unlock_irqrestore(&info->irq_spinlock,flags); +} + +/* Reconfigure adapter based on new parameters + */ +static void mgsl_change_params(struct mgsl_struct *info) +{ + unsigned cflag; + int bits_per_char; + + if (!info->port.tty || !info->port.tty->termios) + return; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_change_params(%s)\n", + __FILE__,__LINE__, info->device_name ); + + cflag = info->port.tty->termios->c_cflag; + + /* if B0 rate (hangup) specified then negate DTR and RTS */ + /* otherwise assert DTR and RTS */ + if (cflag & CBAUD) + info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; + else + info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); + + /* byte size and parity */ + + switch (cflag & CSIZE) { + case CS5: info->params.data_bits = 5; break; + case CS6: info->params.data_bits = 6; break; + case CS7: info->params.data_bits = 7; break; + case CS8: info->params.data_bits = 8; break; + /* Never happens, but GCC is too dumb to figure it out */ + default: info->params.data_bits = 7; break; + } + + if (cflag & CSTOPB) + info->params.stop_bits = 2; + else + info->params.stop_bits = 1; + + info->params.parity = ASYNC_PARITY_NONE; + if (cflag & PARENB) { + if (cflag & PARODD) + info->params.parity = ASYNC_PARITY_ODD; + else + info->params.parity = ASYNC_PARITY_EVEN; +#ifdef CMSPAR + if (cflag & CMSPAR) + info->params.parity = ASYNC_PARITY_SPACE; +#endif + } + + /* calculate number of jiffies to transmit a full + * FIFO (32 bytes) at specified data rate + */ + bits_per_char = info->params.data_bits + + info->params.stop_bits + 1; + + /* if port data rate is set to 460800 or less then + * allow tty settings to override, otherwise keep the + * current data rate. + */ + if (info->params.data_rate <= 460800) + info->params.data_rate = tty_get_baud_rate(info->port.tty); + + if ( info->params.data_rate ) { + info->timeout = (32*HZ*bits_per_char) / + info->params.data_rate; + } + info->timeout += HZ/50; /* Add .02 seconds of slop */ + + if (cflag & CRTSCTS) + info->port.flags |= ASYNC_CTS_FLOW; + else + info->port.flags &= ~ASYNC_CTS_FLOW; + + if (cflag & CLOCAL) + info->port.flags &= ~ASYNC_CHECK_CD; + else + info->port.flags |= ASYNC_CHECK_CD; + + /* process tty input control flags */ + + info->read_status_mask = RXSTATUS_OVERRUN; + if (I_INPCK(info->port.tty)) + info->read_status_mask |= RXSTATUS_PARITY_ERROR | RXSTATUS_FRAMING_ERROR; + if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) + info->read_status_mask |= RXSTATUS_BREAK_RECEIVED; + + if (I_IGNPAR(info->port.tty)) + info->ignore_status_mask |= RXSTATUS_PARITY_ERROR | RXSTATUS_FRAMING_ERROR; + if (I_IGNBRK(info->port.tty)) { + info->ignore_status_mask |= RXSTATUS_BREAK_RECEIVED; + /* If ignoring parity and break indicators, ignore + * overruns too. (For real raw support). + */ + if (I_IGNPAR(info->port.tty)) + info->ignore_status_mask |= RXSTATUS_OVERRUN; + } + + mgsl_program_hw(info); + +} /* end of mgsl_change_params() */ + +/* mgsl_put_char() + * + * Add a character to the transmit buffer. + * + * Arguments: tty pointer to tty information structure + * ch character to add to transmit buffer + * + * Return Value: None + */ +static int mgsl_put_char(struct tty_struct *tty, unsigned char ch) +{ + struct mgsl_struct *info = tty->driver_data; + unsigned long flags; + int ret = 0; + + if (debug_level >= DEBUG_LEVEL_INFO) { + printk(KERN_DEBUG "%s(%d):mgsl_put_char(%d) on %s\n", + __FILE__, __LINE__, ch, info->device_name); + } + + if (mgsl_paranoia_check(info, tty->name, "mgsl_put_char")) + return 0; + + if (!info->xmit_buf) + return 0; + + spin_lock_irqsave(&info->irq_spinlock, flags); + + if ((info->params.mode == MGSL_MODE_ASYNC ) || !info->tx_active) { + if (info->xmit_cnt < SERIAL_XMIT_SIZE - 1) { + info->xmit_buf[info->xmit_head++] = ch; + info->xmit_head &= SERIAL_XMIT_SIZE-1; + info->xmit_cnt++; + ret = 1; + } + } + spin_unlock_irqrestore(&info->irq_spinlock, flags); + return ret; + +} /* end of mgsl_put_char() */ + +/* mgsl_flush_chars() + * + * Enable transmitter so remaining characters in the + * transmit buffer are sent. + * + * Arguments: tty pointer to tty information structure + * Return Value: None + */ +static void mgsl_flush_chars(struct tty_struct *tty) +{ + struct mgsl_struct *info = tty->driver_data; + unsigned long flags; + + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):mgsl_flush_chars() entry on %s xmit_cnt=%d\n", + __FILE__,__LINE__,info->device_name,info->xmit_cnt); + + if (mgsl_paranoia_check(info, tty->name, "mgsl_flush_chars")) + return; + + if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || + !info->xmit_buf) + return; + + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):mgsl_flush_chars() entry on %s starting transmitter\n", + __FILE__,__LINE__,info->device_name ); + + spin_lock_irqsave(&info->irq_spinlock,flags); + + if (!info->tx_active) { + if ( (info->params.mode == MGSL_MODE_HDLC || + info->params.mode == MGSL_MODE_RAW) && info->xmit_cnt ) { + /* operating in synchronous (frame oriented) mode */ + /* copy data from circular xmit_buf to */ + /* transmit DMA buffer. */ + mgsl_load_tx_dma_buffer(info, + info->xmit_buf,info->xmit_cnt); + } + usc_start_transmitter(info); + } + + spin_unlock_irqrestore(&info->irq_spinlock,flags); + +} /* end of mgsl_flush_chars() */ + +/* mgsl_write() + * + * Send a block of data + * + * Arguments: + * + * tty pointer to tty information structure + * buf pointer to buffer containing send data + * count size of send data in bytes + * + * Return Value: number of characters written + */ +static int mgsl_write(struct tty_struct * tty, + const unsigned char *buf, int count) +{ + int c, ret = 0; + struct mgsl_struct *info = tty->driver_data; + unsigned long flags; + + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):mgsl_write(%s) count=%d\n", + __FILE__,__LINE__,info->device_name,count); + + if (mgsl_paranoia_check(info, tty->name, "mgsl_write")) + goto cleanup; + + if (!info->xmit_buf) + goto cleanup; + + if ( info->params.mode == MGSL_MODE_HDLC || + info->params.mode == MGSL_MODE_RAW ) { + /* operating in synchronous (frame oriented) mode */ + /* operating in synchronous (frame oriented) mode */ + if (info->tx_active) { + + if ( info->params.mode == MGSL_MODE_HDLC ) { + ret = 0; + goto cleanup; + } + /* transmitter is actively sending data - + * if we have multiple transmit dma and + * holding buffers, attempt to queue this + * frame for transmission at a later time. + */ + if (info->tx_holding_count >= info->num_tx_holding_buffers ) { + /* no tx holding buffers available */ + ret = 0; + goto cleanup; + } + + /* queue transmit frame request */ + ret = count; + save_tx_buffer_request(info,buf,count); + + /* if we have sufficient tx dma buffers, + * load the next buffered tx request + */ + spin_lock_irqsave(&info->irq_spinlock,flags); + load_next_tx_holding_buffer(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + goto cleanup; + } + + /* if operating in HDLC LoopMode and the adapter */ + /* has yet to be inserted into the loop, we can't */ + /* transmit */ + + if ( (info->params.flags & HDLC_FLAG_HDLC_LOOPMODE) && + !usc_loopmode_active(info) ) + { + ret = 0; + goto cleanup; + } + + if ( info->xmit_cnt ) { + /* Send accumulated from send_char() calls */ + /* as frame and wait before accepting more data. */ + ret = 0; + + /* copy data from circular xmit_buf to */ + /* transmit DMA buffer. */ + mgsl_load_tx_dma_buffer(info, + info->xmit_buf,info->xmit_cnt); + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):mgsl_write(%s) sync xmit_cnt flushing\n", + __FILE__,__LINE__,info->device_name); + } else { + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):mgsl_write(%s) sync transmit accepted\n", + __FILE__,__LINE__,info->device_name); + ret = count; + info->xmit_cnt = count; + mgsl_load_tx_dma_buffer(info,buf,count); + } + } else { + while (1) { + spin_lock_irqsave(&info->irq_spinlock,flags); + c = min_t(int, count, + min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + if (c <= 0) { + spin_unlock_irqrestore(&info->irq_spinlock,flags); + break; + } + memcpy(info->xmit_buf + info->xmit_head, buf, c); + info->xmit_head = ((info->xmit_head + c) & + (SERIAL_XMIT_SIZE-1)); + info->xmit_cnt += c; + spin_unlock_irqrestore(&info->irq_spinlock,flags); + buf += c; + count -= c; + ret += c; + } + } + + if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { + spin_lock_irqsave(&info->irq_spinlock,flags); + if (!info->tx_active) + usc_start_transmitter(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + } +cleanup: + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):mgsl_write(%s) returning=%d\n", + __FILE__,__LINE__,info->device_name,ret); + + return ret; + +} /* end of mgsl_write() */ + +/* mgsl_write_room() + * + * Return the count of free bytes in transmit buffer + * + * Arguments: tty pointer to tty info structure + * Return Value: None + */ +static int mgsl_write_room(struct tty_struct *tty) +{ + struct mgsl_struct *info = tty->driver_data; + int ret; + + if (mgsl_paranoia_check(info, tty->name, "mgsl_write_room")) + return 0; + ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; + if (ret < 0) + ret = 0; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_write_room(%s)=%d\n", + __FILE__,__LINE__, info->device_name,ret ); + + if ( info->params.mode == MGSL_MODE_HDLC || + info->params.mode == MGSL_MODE_RAW ) { + /* operating in synchronous (frame oriented) mode */ + if ( info->tx_active ) + return 0; + else + return HDLC_MAX_FRAME_SIZE; + } + + return ret; + +} /* end of mgsl_write_room() */ + +/* mgsl_chars_in_buffer() + * + * Return the count of bytes in transmit buffer + * + * Arguments: tty pointer to tty info structure + * Return Value: None + */ +static int mgsl_chars_in_buffer(struct tty_struct *tty) +{ + struct mgsl_struct *info = tty->driver_data; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_chars_in_buffer(%s)\n", + __FILE__,__LINE__, info->device_name ); + + if (mgsl_paranoia_check(info, tty->name, "mgsl_chars_in_buffer")) + return 0; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_chars_in_buffer(%s)=%d\n", + __FILE__,__LINE__, info->device_name,info->xmit_cnt ); + + if ( info->params.mode == MGSL_MODE_HDLC || + info->params.mode == MGSL_MODE_RAW ) { + /* operating in synchronous (frame oriented) mode */ + if ( info->tx_active ) + return info->max_frame_size; + else + return 0; + } + + return info->xmit_cnt; +} /* end of mgsl_chars_in_buffer() */ + +/* mgsl_flush_buffer() + * + * Discard all data in the send buffer + * + * Arguments: tty pointer to tty info structure + * Return Value: None + */ +static void mgsl_flush_buffer(struct tty_struct *tty) +{ + struct mgsl_struct *info = tty->driver_data; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_flush_buffer(%s) entry\n", + __FILE__,__LINE__, info->device_name ); + + if (mgsl_paranoia_check(info, tty->name, "mgsl_flush_buffer")) + return; + + spin_lock_irqsave(&info->irq_spinlock,flags); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + del_timer(&info->tx_timer); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + tty_wakeup(tty); +} + +/* mgsl_send_xchar() + * + * Send a high-priority XON/XOFF character + * + * Arguments: tty pointer to tty info structure + * ch character to send + * Return Value: None + */ +static void mgsl_send_xchar(struct tty_struct *tty, char ch) +{ + struct mgsl_struct *info = tty->driver_data; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_send_xchar(%s,%d)\n", + __FILE__,__LINE__, info->device_name, ch ); + + if (mgsl_paranoia_check(info, tty->name, "mgsl_send_xchar")) + return; + + info->x_char = ch; + if (ch) { + /* Make sure transmit interrupts are on */ + spin_lock_irqsave(&info->irq_spinlock,flags); + if (!info->tx_enabled) + usc_start_transmitter(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + } +} /* end of mgsl_send_xchar() */ + +/* mgsl_throttle() + * + * Signal remote device to throttle send data (our receive data) + * + * Arguments: tty pointer to tty info structure + * Return Value: None + */ +static void mgsl_throttle(struct tty_struct * tty) +{ + struct mgsl_struct *info = tty->driver_data; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_throttle(%s) entry\n", + __FILE__,__LINE__, info->device_name ); + + if (mgsl_paranoia_check(info, tty->name, "mgsl_throttle")) + return; + + if (I_IXOFF(tty)) + mgsl_send_xchar(tty, STOP_CHAR(tty)); + + if (tty->termios->c_cflag & CRTSCTS) { + spin_lock_irqsave(&info->irq_spinlock,flags); + info->serial_signals &= ~SerialSignal_RTS; + usc_set_serial_signals(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + } +} /* end of mgsl_throttle() */ + +/* mgsl_unthrottle() + * + * Signal remote device to stop throttling send data (our receive data) + * + * Arguments: tty pointer to tty info structure + * Return Value: None + */ +static void mgsl_unthrottle(struct tty_struct * tty) +{ + struct mgsl_struct *info = tty->driver_data; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_unthrottle(%s) entry\n", + __FILE__,__LINE__, info->device_name ); + + if (mgsl_paranoia_check(info, tty->name, "mgsl_unthrottle")) + return; + + if (I_IXOFF(tty)) { + if (info->x_char) + info->x_char = 0; + else + mgsl_send_xchar(tty, START_CHAR(tty)); + } + + if (tty->termios->c_cflag & CRTSCTS) { + spin_lock_irqsave(&info->irq_spinlock,flags); + info->serial_signals |= SerialSignal_RTS; + usc_set_serial_signals(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + } + +} /* end of mgsl_unthrottle() */ + +/* mgsl_get_stats() + * + * get the current serial parameters information + * + * Arguments: info pointer to device instance data + * user_icount pointer to buffer to hold returned stats + * + * Return Value: 0 if success, otherwise error code + */ +static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount __user *user_icount) +{ + int err; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_get_params(%s)\n", + __FILE__,__LINE__, info->device_name); + + if (!user_icount) { + memset(&info->icount, 0, sizeof(info->icount)); + } else { + mutex_lock(&info->port.mutex); + COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount)); + mutex_unlock(&info->port.mutex); + if (err) + return -EFAULT; + } + + return 0; + +} /* end of mgsl_get_stats() */ + +/* mgsl_get_params() + * + * get the current serial parameters information + * + * Arguments: info pointer to device instance data + * user_params pointer to buffer to hold returned params + * + * Return Value: 0 if success, otherwise error code + */ +static int mgsl_get_params(struct mgsl_struct * info, MGSL_PARAMS __user *user_params) +{ + int err; + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_get_params(%s)\n", + __FILE__,__LINE__, info->device_name); + + mutex_lock(&info->port.mutex); + COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS)); + mutex_unlock(&info->port.mutex); + if (err) { + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):mgsl_get_params(%s) user buffer copy failed\n", + __FILE__,__LINE__,info->device_name); + return -EFAULT; + } + + return 0; + +} /* end of mgsl_get_params() */ + +/* mgsl_set_params() + * + * set the serial parameters + * + * Arguments: + * + * info pointer to device instance data + * new_params user buffer containing new serial params + * + * Return Value: 0 if success, otherwise error code + */ +static int mgsl_set_params(struct mgsl_struct * info, MGSL_PARAMS __user *new_params) +{ + unsigned long flags; + MGSL_PARAMS tmp_params; + int err; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_set_params %s\n", __FILE__,__LINE__, + info->device_name ); + COPY_FROM_USER(err,&tmp_params, new_params, sizeof(MGSL_PARAMS)); + if (err) { + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):mgsl_set_params(%s) user buffer copy failed\n", + __FILE__,__LINE__,info->device_name); + return -EFAULT; + } + + mutex_lock(&info->port.mutex); + spin_lock_irqsave(&info->irq_spinlock,flags); + memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS)); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + mgsl_change_params(info); + mutex_unlock(&info->port.mutex); + + return 0; + +} /* end of mgsl_set_params() */ + +/* mgsl_get_txidle() + * + * get the current transmit idle mode + * + * Arguments: info pointer to device instance data + * idle_mode pointer to buffer to hold returned idle mode + * + * Return Value: 0 if success, otherwise error code + */ +static int mgsl_get_txidle(struct mgsl_struct * info, int __user *idle_mode) +{ + int err; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_get_txidle(%s)=%d\n", + __FILE__,__LINE__, info->device_name, info->idle_mode); + + COPY_TO_USER(err,idle_mode, &info->idle_mode, sizeof(int)); + if (err) { + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):mgsl_get_txidle(%s) user buffer copy failed\n", + __FILE__,__LINE__,info->device_name); + return -EFAULT; + } + + return 0; + +} /* end of mgsl_get_txidle() */ + +/* mgsl_set_txidle() service ioctl to set transmit idle mode + * + * Arguments: info pointer to device instance data + * idle_mode new idle mode + * + * Return Value: 0 if success, otherwise error code + */ +static int mgsl_set_txidle(struct mgsl_struct * info, int idle_mode) +{ + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_set_txidle(%s,%d)\n", __FILE__,__LINE__, + info->device_name, idle_mode ); + + spin_lock_irqsave(&info->irq_spinlock,flags); + info->idle_mode = idle_mode; + usc_set_txidle( info ); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + return 0; + +} /* end of mgsl_set_txidle() */ + +/* mgsl_txenable() + * + * enable or disable the transmitter + * + * Arguments: + * + * info pointer to device instance data + * enable 1 = enable, 0 = disable + * + * Return Value: 0 if success, otherwise error code + */ +static int mgsl_txenable(struct mgsl_struct * info, int enable) +{ + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_txenable(%s,%d)\n", __FILE__,__LINE__, + info->device_name, enable); + + spin_lock_irqsave(&info->irq_spinlock,flags); + if ( enable ) { + if ( !info->tx_enabled ) { + + usc_start_transmitter(info); + /*-------------------------------------------------- + * if HDLC/SDLC Loop mode, attempt to insert the + * station in the 'loop' by setting CMR:13. Upon + * receipt of the next GoAhead (RxAbort) sequence, + * the OnLoop indicator (CCSR:7) should go active + * to indicate that we are on the loop + *--------------------------------------------------*/ + if ( info->params.flags & HDLC_FLAG_HDLC_LOOPMODE ) + usc_loopmode_insert_request( info ); + } + } else { + if ( info->tx_enabled ) + usc_stop_transmitter(info); + } + spin_unlock_irqrestore(&info->irq_spinlock,flags); + return 0; + +} /* end of mgsl_txenable() */ + +/* mgsl_txabort() abort send HDLC frame + * + * Arguments: info pointer to device instance data + * Return Value: 0 if success, otherwise error code + */ +static int mgsl_txabort(struct mgsl_struct * info) +{ + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_txabort(%s)\n", __FILE__,__LINE__, + info->device_name); + + spin_lock_irqsave(&info->irq_spinlock,flags); + if ( info->tx_active && info->params.mode == MGSL_MODE_HDLC ) + { + if ( info->params.flags & HDLC_FLAG_HDLC_LOOPMODE ) + usc_loopmode_cancel_transmit( info ); + else + usc_TCmd(info,TCmd_SendAbort); + } + spin_unlock_irqrestore(&info->irq_spinlock,flags); + return 0; + +} /* end of mgsl_txabort() */ + +/* mgsl_rxenable() enable or disable the receiver + * + * Arguments: info pointer to device instance data + * enable 1 = enable, 0 = disable + * Return Value: 0 if success, otherwise error code + */ +static int mgsl_rxenable(struct mgsl_struct * info, int enable) +{ + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_rxenable(%s,%d)\n", __FILE__,__LINE__, + info->device_name, enable); + + spin_lock_irqsave(&info->irq_spinlock,flags); + if ( enable ) { + if ( !info->rx_enabled ) + usc_start_receiver(info); + } else { + if ( info->rx_enabled ) + usc_stop_receiver(info); + } + spin_unlock_irqrestore(&info->irq_spinlock,flags); + return 0; + +} /* end of mgsl_rxenable() */ + +/* mgsl_wait_event() wait for specified event to occur + * + * Arguments: info pointer to device instance data + * mask pointer to bitmask of events to wait for + * Return Value: 0 if successful and bit mask updated with + * of events triggerred, + * otherwise error code + */ +static int mgsl_wait_event(struct mgsl_struct * info, int __user * mask_ptr) +{ + unsigned long flags; + int s; + int rc=0; + struct mgsl_icount cprev, cnow; + int events; + int mask; + struct _input_signal_events oldsigs, newsigs; + DECLARE_WAITQUEUE(wait, current); + + COPY_FROM_USER(rc,&mask, mask_ptr, sizeof(int)); + if (rc) { + return -EFAULT; + } + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_wait_event(%s,%d)\n", __FILE__,__LINE__, + info->device_name, mask); + + spin_lock_irqsave(&info->irq_spinlock,flags); + + /* return immediately if state matches requested events */ + usc_get_serial_signals(info); + s = info->serial_signals; + events = mask & + ( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) + + ((s & SerialSignal_DCD) ? MgslEvent_DcdActive:MgslEvent_DcdInactive) + + ((s & SerialSignal_CTS) ? MgslEvent_CtsActive:MgslEvent_CtsInactive) + + ((s & SerialSignal_RI) ? MgslEvent_RiActive :MgslEvent_RiInactive) ); + if (events) { + spin_unlock_irqrestore(&info->irq_spinlock,flags); + goto exit; + } + + /* save current irq counts */ + cprev = info->icount; + oldsigs = info->input_signal_events; + + /* enable hunt and idle irqs if needed */ + if (mask & (MgslEvent_ExitHuntMode + MgslEvent_IdleReceived)) { + u16 oldreg = usc_InReg(info,RICR); + u16 newreg = oldreg + + (mask & MgslEvent_ExitHuntMode ? RXSTATUS_EXITED_HUNT:0) + + (mask & MgslEvent_IdleReceived ? RXSTATUS_IDLE_RECEIVED:0); + if (oldreg != newreg) + usc_OutReg(info, RICR, newreg); + } + + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&info->event_wait_q, &wait); + + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + + for(;;) { + schedule(); + if (signal_pending(current)) { + rc = -ERESTARTSYS; + break; + } + + /* get current irq counts */ + spin_lock_irqsave(&info->irq_spinlock,flags); + cnow = info->icount; + newsigs = info->input_signal_events; + set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + /* if no change, wait aborted for some reason */ + if (newsigs.dsr_up == oldsigs.dsr_up && + newsigs.dsr_down == oldsigs.dsr_down && + newsigs.dcd_up == oldsigs.dcd_up && + newsigs.dcd_down == oldsigs.dcd_down && + newsigs.cts_up == oldsigs.cts_up && + newsigs.cts_down == oldsigs.cts_down && + newsigs.ri_up == oldsigs.ri_up && + newsigs.ri_down == oldsigs.ri_down && + cnow.exithunt == cprev.exithunt && + cnow.rxidle == cprev.rxidle) { + rc = -EIO; + break; + } + + events = mask & + ( (newsigs.dsr_up != oldsigs.dsr_up ? MgslEvent_DsrActive:0) + + (newsigs.dsr_down != oldsigs.dsr_down ? MgslEvent_DsrInactive:0) + + (newsigs.dcd_up != oldsigs.dcd_up ? MgslEvent_DcdActive:0) + + (newsigs.dcd_down != oldsigs.dcd_down ? MgslEvent_DcdInactive:0) + + (newsigs.cts_up != oldsigs.cts_up ? MgslEvent_CtsActive:0) + + (newsigs.cts_down != oldsigs.cts_down ? MgslEvent_CtsInactive:0) + + (newsigs.ri_up != oldsigs.ri_up ? MgslEvent_RiActive:0) + + (newsigs.ri_down != oldsigs.ri_down ? MgslEvent_RiInactive:0) + + (cnow.exithunt != cprev.exithunt ? MgslEvent_ExitHuntMode:0) + + (cnow.rxidle != cprev.rxidle ? MgslEvent_IdleReceived:0) ); + if (events) + break; + + cprev = cnow; + oldsigs = newsigs; + } + + remove_wait_queue(&info->event_wait_q, &wait); + set_current_state(TASK_RUNNING); + + if (mask & (MgslEvent_ExitHuntMode + MgslEvent_IdleReceived)) { + spin_lock_irqsave(&info->irq_spinlock,flags); + if (!waitqueue_active(&info->event_wait_q)) { + /* disable enable exit hunt mode/idle rcvd IRQs */ + usc_OutReg(info, RICR, usc_InReg(info,RICR) & + ~(RXSTATUS_EXITED_HUNT + RXSTATUS_IDLE_RECEIVED)); + } + spin_unlock_irqrestore(&info->irq_spinlock,flags); + } +exit: + if ( rc == 0 ) + PUT_USER(rc, events, mask_ptr); + + return rc; + +} /* end of mgsl_wait_event() */ + +static int modem_input_wait(struct mgsl_struct *info,int arg) +{ + unsigned long flags; + int rc; + struct mgsl_icount cprev, cnow; + DECLARE_WAITQUEUE(wait, current); + + /* save current irq counts */ + spin_lock_irqsave(&info->irq_spinlock,flags); + cprev = info->icount; + add_wait_queue(&info->status_event_wait_q, &wait); + set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + for(;;) { + schedule(); + if (signal_pending(current)) { + rc = -ERESTARTSYS; + break; + } + + /* get new irq counts */ + spin_lock_irqsave(&info->irq_spinlock,flags); + cnow = info->icount; + set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + /* if no change, wait aborted for some reason */ + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && + cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { + rc = -EIO; + break; + } + + /* check for change in caller specified modem input */ + if ((arg & TIOCM_RNG && cnow.rng != cprev.rng) || + (arg & TIOCM_DSR && cnow.dsr != cprev.dsr) || + (arg & TIOCM_CD && cnow.dcd != cprev.dcd) || + (arg & TIOCM_CTS && cnow.cts != cprev.cts)) { + rc = 0; + break; + } + + cprev = cnow; + } + remove_wait_queue(&info->status_event_wait_q, &wait); + set_current_state(TASK_RUNNING); + return rc; +} + +/* return the state of the serial control and status signals + */ +static int tiocmget(struct tty_struct *tty) +{ + struct mgsl_struct *info = tty->driver_data; + unsigned int result; + unsigned long flags; + + spin_lock_irqsave(&info->irq_spinlock,flags); + usc_get_serial_signals(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + result = ((info->serial_signals & SerialSignal_RTS) ? TIOCM_RTS:0) + + ((info->serial_signals & SerialSignal_DTR) ? TIOCM_DTR:0) + + ((info->serial_signals & SerialSignal_DCD) ? TIOCM_CAR:0) + + ((info->serial_signals & SerialSignal_RI) ? TIOCM_RNG:0) + + ((info->serial_signals & SerialSignal_DSR) ? TIOCM_DSR:0) + + ((info->serial_signals & SerialSignal_CTS) ? TIOCM_CTS:0); + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s tiocmget() value=%08X\n", + __FILE__,__LINE__, info->device_name, result ); + return result; +} + +/* set modem control signals (DTR/RTS) + */ +static int tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + struct mgsl_struct *info = tty->driver_data; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s tiocmset(%x,%x)\n", + __FILE__,__LINE__,info->device_name, set, clear); + + if (set & TIOCM_RTS) + info->serial_signals |= SerialSignal_RTS; + if (set & TIOCM_DTR) + info->serial_signals |= SerialSignal_DTR; + if (clear & TIOCM_RTS) + info->serial_signals &= ~SerialSignal_RTS; + if (clear & TIOCM_DTR) + info->serial_signals &= ~SerialSignal_DTR; + + spin_lock_irqsave(&info->irq_spinlock,flags); + usc_set_serial_signals(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + return 0; +} + +/* mgsl_break() Set or clear transmit break condition + * + * Arguments: tty pointer to tty instance data + * break_state -1=set break condition, 0=clear + * Return Value: error code + */ +static int mgsl_break(struct tty_struct *tty, int break_state) +{ + struct mgsl_struct * info = tty->driver_data; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_break(%s,%d)\n", + __FILE__,__LINE__, info->device_name, break_state); + + if (mgsl_paranoia_check(info, tty->name, "mgsl_break")) + return -EINVAL; + + spin_lock_irqsave(&info->irq_spinlock,flags); + if (break_state == -1) + usc_OutReg(info,IOCR,(u16)(usc_InReg(info,IOCR) | BIT7)); + else + usc_OutReg(info,IOCR,(u16)(usc_InReg(info,IOCR) & ~BIT7)); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + return 0; + +} /* end of mgsl_break() */ + +/* + * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) + * Return: write counters to the user passed counter struct + * NB: both 1->0 and 0->1 transitions are counted except for + * RI where only 0->1 is counted. + */ +static int msgl_get_icount(struct tty_struct *tty, + struct serial_icounter_struct *icount) + +{ + struct mgsl_struct * info = tty->driver_data; + struct mgsl_icount cnow; /* kernel counter temps */ + unsigned long flags; + + spin_lock_irqsave(&info->irq_spinlock,flags); + cnow = info->icount; + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + icount->cts = cnow.cts; + icount->dsr = cnow.dsr; + icount->rng = cnow.rng; + icount->dcd = cnow.dcd; + icount->rx = cnow.rx; + icount->tx = cnow.tx; + icount->frame = cnow.frame; + icount->overrun = cnow.overrun; + icount->parity = cnow.parity; + icount->brk = cnow.brk; + icount->buf_overrun = cnow.buf_overrun; + return 0; +} + +/* mgsl_ioctl() Service an IOCTL request + * + * Arguments: + * + * tty pointer to tty instance data + * cmd IOCTL command code + * arg command argument/context + * + * Return Value: 0 if success, otherwise error code + */ +static int mgsl_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + struct mgsl_struct * info = tty->driver_data; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_ioctl %s cmd=%08X\n", __FILE__,__LINE__, + info->device_name, cmd ); + + if (mgsl_paranoia_check(info, tty->name, "mgsl_ioctl")) + return -ENODEV; + + if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && + (cmd != TIOCMIWAIT)) { + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + } + + return mgsl_ioctl_common(info, cmd, arg); +} + +static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg) +{ + void __user *argp = (void __user *)arg; + + switch (cmd) { + case MGSL_IOCGPARAMS: + return mgsl_get_params(info, argp); + case MGSL_IOCSPARAMS: + return mgsl_set_params(info, argp); + case MGSL_IOCGTXIDLE: + return mgsl_get_txidle(info, argp); + case MGSL_IOCSTXIDLE: + return mgsl_set_txidle(info,(int)arg); + case MGSL_IOCTXENABLE: + return mgsl_txenable(info,(int)arg); + case MGSL_IOCRXENABLE: + return mgsl_rxenable(info,(int)arg); + case MGSL_IOCTXABORT: + return mgsl_txabort(info); + case MGSL_IOCGSTATS: + return mgsl_get_stats(info, argp); + case MGSL_IOCWAITEVENT: + return mgsl_wait_event(info, argp); + case MGSL_IOCLOOPTXDONE: + return mgsl_loopmode_send_done(info); + /* Wait for modem input (DCD,RI,DSR,CTS) change + * as specified by mask in arg (TIOCM_RNG/DSR/CD/CTS) + */ + case TIOCMIWAIT: + return modem_input_wait(info,(int)arg); + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +/* mgsl_set_termios() + * + * Set new termios settings + * + * Arguments: + * + * tty pointer to tty structure + * termios pointer to buffer to hold returned old termios + * + * Return Value: None + */ +static void mgsl_set_termios(struct tty_struct *tty, struct ktermios *old_termios) +{ + struct mgsl_struct *info = tty->driver_data; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_set_termios %s\n", __FILE__,__LINE__, + tty->driver->name ); + + mgsl_change_params(info); + + /* Handle transition to B0 status */ + if (old_termios->c_cflag & CBAUD && + !(tty->termios->c_cflag & CBAUD)) { + info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); + spin_lock_irqsave(&info->irq_spinlock,flags); + usc_set_serial_signals(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + } + + /* Handle transition away from B0 status */ + if (!(old_termios->c_cflag & CBAUD) && + tty->termios->c_cflag & CBAUD) { + info->serial_signals |= SerialSignal_DTR; + if (!(tty->termios->c_cflag & CRTSCTS) || + !test_bit(TTY_THROTTLED, &tty->flags)) { + info->serial_signals |= SerialSignal_RTS; + } + spin_lock_irqsave(&info->irq_spinlock,flags); + usc_set_serial_signals(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + } + + /* Handle turning off CRTSCTS */ + if (old_termios->c_cflag & CRTSCTS && + !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + mgsl_start(tty); + } + +} /* end of mgsl_set_termios() */ + +/* mgsl_close() + * + * Called when port is closed. Wait for remaining data to be + * sent. Disable port and free resources. + * + * Arguments: + * + * tty pointer to open tty structure + * filp pointer to open file object + * + * Return Value: None + */ +static void mgsl_close(struct tty_struct *tty, struct file * filp) +{ + struct mgsl_struct * info = tty->driver_data; + + if (mgsl_paranoia_check(info, tty->name, "mgsl_close")) + return; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_close(%s) entry, count=%d\n", + __FILE__,__LINE__, info->device_name, info->port.count); + + if (tty_port_close_start(&info->port, tty, filp) == 0) + goto cleanup; + + mutex_lock(&info->port.mutex); + if (info->port.flags & ASYNC_INITIALIZED) + mgsl_wait_until_sent(tty, info->timeout); + mgsl_flush_buffer(tty); + tty_ldisc_flush(tty); + shutdown(info); + mutex_unlock(&info->port.mutex); + + tty_port_close_end(&info->port, tty); + info->port.tty = NULL; +cleanup: + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_close(%s) exit, count=%d\n", __FILE__,__LINE__, + tty->driver->name, info->port.count); + +} /* end of mgsl_close() */ + +/* mgsl_wait_until_sent() + * + * Wait until the transmitter is empty. + * + * Arguments: + * + * tty pointer to tty info structure + * timeout time to wait for send completion + * + * Return Value: None + */ +static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout) +{ + struct mgsl_struct * info = tty->driver_data; + unsigned long orig_jiffies, char_time; + + if (!info ) + return; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_wait_until_sent(%s) entry\n", + __FILE__,__LINE__, info->device_name ); + + if (mgsl_paranoia_check(info, tty->name, "mgsl_wait_until_sent")) + return; + + if (!(info->port.flags & ASYNC_INITIALIZED)) + goto exit; + + orig_jiffies = jiffies; + + /* Set check interval to 1/5 of estimated time to + * send a character, and make it at least 1. The check + * interval should also be less than the timeout. + * Note: use tight timings here to satisfy the NIST-PCTS. + */ + + if ( info->params.data_rate ) { + char_time = info->timeout/(32 * 5); + if (!char_time) + char_time++; + } else + char_time = 1; + + if (timeout) + char_time = min_t(unsigned long, char_time, timeout); + + if ( info->params.mode == MGSL_MODE_HDLC || + info->params.mode == MGSL_MODE_RAW ) { + while (info->tx_active) { + msleep_interruptible(jiffies_to_msecs(char_time)); + if (signal_pending(current)) + break; + if (timeout && time_after(jiffies, orig_jiffies + timeout)) + break; + } + } else { + while (!(usc_InReg(info,TCSR) & TXSTATUS_ALL_SENT) && + info->tx_enabled) { + msleep_interruptible(jiffies_to_msecs(char_time)); + if (signal_pending(current)) + break; + if (timeout && time_after(jiffies, orig_jiffies + timeout)) + break; + } + } + +exit: + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_wait_until_sent(%s) exit\n", + __FILE__,__LINE__, info->device_name ); + +} /* end of mgsl_wait_until_sent() */ + +/* mgsl_hangup() + * + * Called by tty_hangup() when a hangup is signaled. + * This is the same as to closing all open files for the port. + * + * Arguments: tty pointer to associated tty object + * Return Value: None + */ +static void mgsl_hangup(struct tty_struct *tty) +{ + struct mgsl_struct * info = tty->driver_data; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_hangup(%s)\n", + __FILE__,__LINE__, info->device_name ); + + if (mgsl_paranoia_check(info, tty->name, "mgsl_hangup")) + return; + + mgsl_flush_buffer(tty); + shutdown(info); + + info->port.count = 0; + info->port.flags &= ~ASYNC_NORMAL_ACTIVE; + info->port.tty = NULL; + + wake_up_interruptible(&info->port.open_wait); + +} /* end of mgsl_hangup() */ + +/* + * carrier_raised() + * + * Return true if carrier is raised + */ + +static int carrier_raised(struct tty_port *port) +{ + unsigned long flags; + struct mgsl_struct *info = container_of(port, struct mgsl_struct, port); + + spin_lock_irqsave(&info->irq_spinlock, flags); + usc_get_serial_signals(info); + spin_unlock_irqrestore(&info->irq_spinlock, flags); + return (info->serial_signals & SerialSignal_DCD) ? 1 : 0; +} + +static void dtr_rts(struct tty_port *port, int on) +{ + struct mgsl_struct *info = container_of(port, struct mgsl_struct, port); + unsigned long flags; + + spin_lock_irqsave(&info->irq_spinlock,flags); + if (on) + info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; + else + info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); + usc_set_serial_signals(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); +} + + +/* block_til_ready() + * + * Block the current process until the specified port + * is ready to be opened. + * + * Arguments: + * + * tty pointer to tty info structure + * filp pointer to open file object + * info pointer to device instance data + * + * Return Value: 0 if success, otherwise error code + */ +static int block_til_ready(struct tty_struct *tty, struct file * filp, + struct mgsl_struct *info) +{ + DECLARE_WAITQUEUE(wait, current); + int retval; + bool do_clocal = false; + bool extra_count = false; + unsigned long flags; + int dcd; + struct tty_port *port = &info->port; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):block_til_ready on %s\n", + __FILE__,__LINE__, tty->driver->name ); + + if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ + /* nonblock mode is set or port is not enabled */ + port->flags |= ASYNC_NORMAL_ACTIVE; + return 0; + } + + if (tty->termios->c_cflag & CLOCAL) + do_clocal = true; + + /* Wait for carrier detect and the line to become + * free (i.e., not in use by the callout). While we are in + * this loop, port->count is dropped by one, so that + * mgsl_close() knows when to free things. We restore it upon + * exit, either normal or abnormal. + */ + + retval = 0; + add_wait_queue(&port->open_wait, &wait); + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):block_til_ready before block on %s count=%d\n", + __FILE__,__LINE__, tty->driver->name, port->count ); + + spin_lock_irqsave(&info->irq_spinlock, flags); + if (!tty_hung_up_p(filp)) { + extra_count = true; + port->count--; + } + spin_unlock_irqrestore(&info->irq_spinlock, flags); + port->blocked_open++; + + while (1) { + if (tty->termios->c_cflag & CBAUD) + tty_port_raise_dtr_rts(port); + + set_current_state(TASK_INTERRUPTIBLE); + + if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){ + retval = (port->flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS; + break; + } + + dcd = tty_port_carrier_raised(&info->port); + + if (!(port->flags & ASYNC_CLOSING) && (do_clocal || dcd)) + break; + + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):block_til_ready blocking on %s count=%d\n", + __FILE__,__LINE__, tty->driver->name, port->count ); + + tty_unlock(); + schedule(); + tty_lock(); + } + + set_current_state(TASK_RUNNING); + remove_wait_queue(&port->open_wait, &wait); + + /* FIXME: Racy on hangup during close wait */ + if (extra_count) + port->count++; + port->blocked_open--; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):block_til_ready after blocking on %s count=%d\n", + __FILE__,__LINE__, tty->driver->name, port->count ); + + if (!retval) + port->flags |= ASYNC_NORMAL_ACTIVE; + + return retval; + +} /* end of block_til_ready() */ + +/* mgsl_open() + * + * Called when a port is opened. Init and enable port. + * Perform serial-specific initialization for the tty structure. + * + * Arguments: tty pointer to tty info structure + * filp associated file pointer + * + * Return Value: 0 if success, otherwise error code + */ +static int mgsl_open(struct tty_struct *tty, struct file * filp) +{ + struct mgsl_struct *info; + int retval, line; + unsigned long flags; + + /* verify range of specified line number */ + line = tty->index; + if ((line < 0) || (line >= mgsl_device_count)) { + printk("%s(%d):mgsl_open with invalid line #%d.\n", + __FILE__,__LINE__,line); + return -ENODEV; + } + + /* find the info structure for the specified line */ + info = mgsl_device_list; + while(info && info->line != line) + info = info->next_device; + if (mgsl_paranoia_check(info, tty->name, "mgsl_open")) + return -ENODEV; + + tty->driver_data = info; + info->port.tty = tty; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_open(%s), old ref count = %d\n", + __FILE__,__LINE__,tty->driver->name, info->port.count); + + /* If port is closing, signal caller to try again */ + if (tty_hung_up_p(filp) || info->port.flags & ASYNC_CLOSING){ + if (info->port.flags & ASYNC_CLOSING) + interruptible_sleep_on(&info->port.close_wait); + retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS); + goto cleanup; + } + + info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; + + spin_lock_irqsave(&info->netlock, flags); + if (info->netcount) { + retval = -EBUSY; + spin_unlock_irqrestore(&info->netlock, flags); + goto cleanup; + } + info->port.count++; + spin_unlock_irqrestore(&info->netlock, flags); + + if (info->port.count == 1) { + /* 1st open on this device, init hardware */ + retval = startup(info); + if (retval < 0) + goto cleanup; + } + + retval = block_til_ready(tty, filp, info); + if (retval) { + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):block_til_ready(%s) returned %d\n", + __FILE__,__LINE__, info->device_name, retval); + goto cleanup; + } + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_open(%s) success\n", + __FILE__,__LINE__, info->device_name); + retval = 0; + +cleanup: + if (retval) { + if (tty->count == 1) + info->port.tty = NULL; /* tty layer will release tty struct */ + if(info->port.count) + info->port.count--; + } + + return retval; + +} /* end of mgsl_open() */ + +/* + * /proc fs routines.... + */ + +static inline void line_info(struct seq_file *m, struct mgsl_struct *info) +{ + char stat_buf[30]; + unsigned long flags; + + if (info->bus_type == MGSL_BUS_TYPE_PCI) { + seq_printf(m, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X", + info->device_name, info->io_base, info->irq_level, + info->phys_memory_base, info->phys_lcr_base); + } else { + seq_printf(m, "%s:(E)ISA io:%04X irq:%d dma:%d", + info->device_name, info->io_base, + info->irq_level, info->dma_level); + } + + /* output current serial signal states */ + spin_lock_irqsave(&info->irq_spinlock,flags); + usc_get_serial_signals(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + stat_buf[0] = 0; + stat_buf[1] = 0; + if (info->serial_signals & SerialSignal_RTS) + strcat(stat_buf, "|RTS"); + if (info->serial_signals & SerialSignal_CTS) + strcat(stat_buf, "|CTS"); + if (info->serial_signals & SerialSignal_DTR) + strcat(stat_buf, "|DTR"); + if (info->serial_signals & SerialSignal_DSR) + strcat(stat_buf, "|DSR"); + if (info->serial_signals & SerialSignal_DCD) + strcat(stat_buf, "|CD"); + if (info->serial_signals & SerialSignal_RI) + strcat(stat_buf, "|RI"); + + if (info->params.mode == MGSL_MODE_HDLC || + info->params.mode == MGSL_MODE_RAW ) { + seq_printf(m, " HDLC txok:%d rxok:%d", + info->icount.txok, info->icount.rxok); + if (info->icount.txunder) + seq_printf(m, " txunder:%d", info->icount.txunder); + if (info->icount.txabort) + seq_printf(m, " txabort:%d", info->icount.txabort); + if (info->icount.rxshort) + seq_printf(m, " rxshort:%d", info->icount.rxshort); + if (info->icount.rxlong) + seq_printf(m, " rxlong:%d", info->icount.rxlong); + if (info->icount.rxover) + seq_printf(m, " rxover:%d", info->icount.rxover); + if (info->icount.rxcrc) + seq_printf(m, " rxcrc:%d", info->icount.rxcrc); + } else { + seq_printf(m, " ASYNC tx:%d rx:%d", + info->icount.tx, info->icount.rx); + if (info->icount.frame) + seq_printf(m, " fe:%d", info->icount.frame); + if (info->icount.parity) + seq_printf(m, " pe:%d", info->icount.parity); + if (info->icount.brk) + seq_printf(m, " brk:%d", info->icount.brk); + if (info->icount.overrun) + seq_printf(m, " oe:%d", info->icount.overrun); + } + + /* Append serial signal status to end */ + seq_printf(m, " %s\n", stat_buf+1); + + seq_printf(m, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", + info->tx_active,info->bh_requested,info->bh_running, + info->pending_bh); + + spin_lock_irqsave(&info->irq_spinlock,flags); + { + u16 Tcsr = usc_InReg( info, TCSR ); + u16 Tdmr = usc_InDmaReg( info, TDMR ); + u16 Ticr = usc_InReg( info, TICR ); + u16 Rscr = usc_InReg( info, RCSR ); + u16 Rdmr = usc_InDmaReg( info, RDMR ); + u16 Ricr = usc_InReg( info, RICR ); + u16 Icr = usc_InReg( info, ICR ); + u16 Dccr = usc_InReg( info, DCCR ); + u16 Tmr = usc_InReg( info, TMR ); + u16 Tccr = usc_InReg( info, TCCR ); + u16 Ccar = inw( info->io_base + CCAR ); + seq_printf(m, "tcsr=%04X tdmr=%04X ticr=%04X rcsr=%04X rdmr=%04X\n" + "ricr=%04X icr =%04X dccr=%04X tmr=%04X tccr=%04X ccar=%04X\n", + Tcsr,Tdmr,Ticr,Rscr,Rdmr,Ricr,Icr,Dccr,Tmr,Tccr,Ccar ); + } + spin_unlock_irqrestore(&info->irq_spinlock,flags); +} + +/* Called to print information about devices */ +static int mgsl_proc_show(struct seq_file *m, void *v) +{ + struct mgsl_struct *info; + + seq_printf(m, "synclink driver:%s\n", driver_version); + + info = mgsl_device_list; + while( info ) { + line_info(m, info); + info = info->next_device; + } + return 0; +} + +static int mgsl_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, mgsl_proc_show, NULL); +} + +static const struct file_operations mgsl_proc_fops = { + .owner = THIS_MODULE, + .open = mgsl_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* mgsl_allocate_dma_buffers() + * + * Allocate and format DMA buffers (ISA adapter) + * or format shared memory buffers (PCI adapter). + * + * Arguments: info pointer to device instance data + * Return Value: 0 if success, otherwise error + */ +static int mgsl_allocate_dma_buffers(struct mgsl_struct *info) +{ + unsigned short BuffersPerFrame; + + info->last_mem_alloc = 0; + + /* Calculate the number of DMA buffers necessary to hold the */ + /* largest allowable frame size. Note: If the max frame size is */ + /* not an even multiple of the DMA buffer size then we need to */ + /* round the buffer count per frame up one. */ + + BuffersPerFrame = (unsigned short)(info->max_frame_size/DMABUFFERSIZE); + if ( info->max_frame_size % DMABUFFERSIZE ) + BuffersPerFrame++; + + if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { + /* + * The PCI adapter has 256KBytes of shared memory to use. + * This is 64 PAGE_SIZE buffers. + * + * The first page is used for padding at this time so the + * buffer list does not begin at offset 0 of the PCI + * adapter's shared memory. + * + * The 2nd page is used for the buffer list. A 4K buffer + * list can hold 128 DMA_BUFFER structures at 32 bytes + * each. + * + * This leaves 62 4K pages. + * + * The next N pages are used for transmit frame(s). We + * reserve enough 4K page blocks to hold the required + * number of transmit dma buffers (num_tx_dma_buffers), + * each of MaxFrameSize size. + * + * Of the remaining pages (62-N), determine how many can + * be used to receive full MaxFrameSize inbound frames + */ + info->tx_buffer_count = info->num_tx_dma_buffers * BuffersPerFrame; + info->rx_buffer_count = 62 - info->tx_buffer_count; + } else { + /* Calculate the number of PAGE_SIZE buffers needed for */ + /* receive and transmit DMA buffers. */ + + + /* Calculate the number of DMA buffers necessary to */ + /* hold 7 max size receive frames and one max size transmit frame. */ + /* The receive buffer count is bumped by one so we avoid an */ + /* End of List condition if all receive buffers are used when */ + /* using linked list DMA buffers. */ + + info->tx_buffer_count = info->num_tx_dma_buffers * BuffersPerFrame; + info->rx_buffer_count = (BuffersPerFrame * MAXRXFRAMES) + 6; + + /* + * limit total TxBuffers & RxBuffers to 62 4K total + * (ala PCI Allocation) + */ + + if ( (info->tx_buffer_count + info->rx_buffer_count) > 62 ) + info->rx_buffer_count = 62 - info->tx_buffer_count; + + } + + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk("%s(%d):Allocating %d TX and %d RX DMA buffers.\n", + __FILE__,__LINE__, info->tx_buffer_count,info->rx_buffer_count); + + if ( mgsl_alloc_buffer_list_memory( info ) < 0 || + mgsl_alloc_frame_memory(info, info->rx_buffer_list, info->rx_buffer_count) < 0 || + mgsl_alloc_frame_memory(info, info->tx_buffer_list, info->tx_buffer_count) < 0 || + mgsl_alloc_intermediate_rxbuffer_memory(info) < 0 || + mgsl_alloc_intermediate_txbuffer_memory(info) < 0 ) { + printk("%s(%d):Can't allocate DMA buffer memory\n",__FILE__,__LINE__); + return -ENOMEM; + } + + mgsl_reset_rx_dma_buffers( info ); + mgsl_reset_tx_dma_buffers( info ); + + return 0; + +} /* end of mgsl_allocate_dma_buffers() */ + +/* + * mgsl_alloc_buffer_list_memory() + * + * Allocate a common DMA buffer for use as the + * receive and transmit buffer lists. + * + * A buffer list is a set of buffer entries where each entry contains + * a pointer to an actual buffer and a pointer to the next buffer entry + * (plus some other info about the buffer). + * + * The buffer entries for a list are built to form a circular list so + * that when the entire list has been traversed you start back at the + * beginning. + * + * This function allocates memory for just the buffer entries. + * The links (pointer to next entry) are filled in with the physical + * address of the next entry so the adapter can navigate the list + * using bus master DMA. The pointers to the actual buffers are filled + * out later when the actual buffers are allocated. + * + * Arguments: info pointer to device instance data + * Return Value: 0 if success, otherwise error + */ +static int mgsl_alloc_buffer_list_memory( struct mgsl_struct *info ) +{ + unsigned int i; + + if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { + /* PCI adapter uses shared memory. */ + info->buffer_list = info->memory_base + info->last_mem_alloc; + info->buffer_list_phys = info->last_mem_alloc; + info->last_mem_alloc += BUFFERLISTSIZE; + } else { + /* ISA adapter uses system memory. */ + /* The buffer lists are allocated as a common buffer that both */ + /* the processor and adapter can access. This allows the driver to */ + /* inspect portions of the buffer while other portions are being */ + /* updated by the adapter using Bus Master DMA. */ + + info->buffer_list = dma_alloc_coherent(NULL, BUFFERLISTSIZE, &info->buffer_list_dma_addr, GFP_KERNEL); + if (info->buffer_list == NULL) + return -ENOMEM; + info->buffer_list_phys = (u32)(info->buffer_list_dma_addr); + } + + /* We got the memory for the buffer entry lists. */ + /* Initialize the memory block to all zeros. */ + memset( info->buffer_list, 0, BUFFERLISTSIZE ); + + /* Save virtual address pointers to the receive and */ + /* transmit buffer lists. (Receive 1st). These pointers will */ + /* be used by the processor to access the lists. */ + info->rx_buffer_list = (DMABUFFERENTRY *)info->buffer_list; + info->tx_buffer_list = (DMABUFFERENTRY *)info->buffer_list; + info->tx_buffer_list += info->rx_buffer_count; + + /* + * Build the links for the buffer entry lists such that + * two circular lists are built. (Transmit and Receive). + * + * Note: the links are physical addresses + * which are read by the adapter to determine the next + * buffer entry to use. + */ + + for ( i = 0; i < info->rx_buffer_count; i++ ) { + /* calculate and store physical address of this buffer entry */ + info->rx_buffer_list[i].phys_entry = + info->buffer_list_phys + (i * sizeof(DMABUFFERENTRY)); + + /* calculate and store physical address of */ + /* next entry in cirular list of entries */ + + info->rx_buffer_list[i].link = info->buffer_list_phys; + + if ( i < info->rx_buffer_count - 1 ) + info->rx_buffer_list[i].link += (i + 1) * sizeof(DMABUFFERENTRY); + } + + for ( i = 0; i < info->tx_buffer_count; i++ ) { + /* calculate and store physical address of this buffer entry */ + info->tx_buffer_list[i].phys_entry = info->buffer_list_phys + + ((info->rx_buffer_count + i) * sizeof(DMABUFFERENTRY)); + + /* calculate and store physical address of */ + /* next entry in cirular list of entries */ + + info->tx_buffer_list[i].link = info->buffer_list_phys + + info->rx_buffer_count * sizeof(DMABUFFERENTRY); + + if ( i < info->tx_buffer_count - 1 ) + info->tx_buffer_list[i].link += (i + 1) * sizeof(DMABUFFERENTRY); + } + + return 0; + +} /* end of mgsl_alloc_buffer_list_memory() */ + +/* Free DMA buffers allocated for use as the + * receive and transmit buffer lists. + * Warning: + * + * The data transfer buffers associated with the buffer list + * MUST be freed before freeing the buffer list itself because + * the buffer list contains the information necessary to free + * the individual buffers! + */ +static void mgsl_free_buffer_list_memory( struct mgsl_struct *info ) +{ + if (info->buffer_list && info->bus_type != MGSL_BUS_TYPE_PCI) + dma_free_coherent(NULL, BUFFERLISTSIZE, info->buffer_list, info->buffer_list_dma_addr); + + info->buffer_list = NULL; + info->rx_buffer_list = NULL; + info->tx_buffer_list = NULL; + +} /* end of mgsl_free_buffer_list_memory() */ + +/* + * mgsl_alloc_frame_memory() + * + * Allocate the frame DMA buffers used by the specified buffer list. + * Each DMA buffer will be one memory page in size. This is necessary + * because memory can fragment enough that it may be impossible + * contiguous pages. + * + * Arguments: + * + * info pointer to device instance data + * BufferList pointer to list of buffer entries + * Buffercount count of buffer entries in buffer list + * + * Return Value: 0 if success, otherwise -ENOMEM + */ +static int mgsl_alloc_frame_memory(struct mgsl_struct *info,DMABUFFERENTRY *BufferList,int Buffercount) +{ + int i; + u32 phys_addr; + + /* Allocate page sized buffers for the receive buffer list */ + + for ( i = 0; i < Buffercount; i++ ) { + if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { + /* PCI adapter uses shared memory buffers. */ + BufferList[i].virt_addr = info->memory_base + info->last_mem_alloc; + phys_addr = info->last_mem_alloc; + info->last_mem_alloc += DMABUFFERSIZE; + } else { + /* ISA adapter uses system memory. */ + BufferList[i].virt_addr = dma_alloc_coherent(NULL, DMABUFFERSIZE, &BufferList[i].dma_addr, GFP_KERNEL); + if (BufferList[i].virt_addr == NULL) + return -ENOMEM; + phys_addr = (u32)(BufferList[i].dma_addr); + } + BufferList[i].phys_addr = phys_addr; + } + + return 0; + +} /* end of mgsl_alloc_frame_memory() */ + +/* + * mgsl_free_frame_memory() + * + * Free the buffers associated with + * each buffer entry of a buffer list. + * + * Arguments: + * + * info pointer to device instance data + * BufferList pointer to list of buffer entries + * Buffercount count of buffer entries in buffer list + * + * Return Value: None + */ +static void mgsl_free_frame_memory(struct mgsl_struct *info, DMABUFFERENTRY *BufferList, int Buffercount) +{ + int i; + + if ( BufferList ) { + for ( i = 0 ; i < Buffercount ; i++ ) { + if ( BufferList[i].virt_addr ) { + if ( info->bus_type != MGSL_BUS_TYPE_PCI ) + dma_free_coherent(NULL, DMABUFFERSIZE, BufferList[i].virt_addr, BufferList[i].dma_addr); + BufferList[i].virt_addr = NULL; + } + } + } + +} /* end of mgsl_free_frame_memory() */ + +/* mgsl_free_dma_buffers() + * + * Free DMA buffers + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void mgsl_free_dma_buffers( struct mgsl_struct *info ) +{ + mgsl_free_frame_memory( info, info->rx_buffer_list, info->rx_buffer_count ); + mgsl_free_frame_memory( info, info->tx_buffer_list, info->tx_buffer_count ); + mgsl_free_buffer_list_memory( info ); + +} /* end of mgsl_free_dma_buffers() */ + + +/* + * mgsl_alloc_intermediate_rxbuffer_memory() + * + * Allocate a buffer large enough to hold max_frame_size. This buffer + * is used to pass an assembled frame to the line discipline. + * + * Arguments: + * + * info pointer to device instance data + * + * Return Value: 0 if success, otherwise -ENOMEM + */ +static int mgsl_alloc_intermediate_rxbuffer_memory(struct mgsl_struct *info) +{ + info->intermediate_rxbuffer = kmalloc(info->max_frame_size, GFP_KERNEL | GFP_DMA); + if ( info->intermediate_rxbuffer == NULL ) + return -ENOMEM; + + return 0; + +} /* end of mgsl_alloc_intermediate_rxbuffer_memory() */ + +/* + * mgsl_free_intermediate_rxbuffer_memory() + * + * + * Arguments: + * + * info pointer to device instance data + * + * Return Value: None + */ +static void mgsl_free_intermediate_rxbuffer_memory(struct mgsl_struct *info) +{ + kfree(info->intermediate_rxbuffer); + info->intermediate_rxbuffer = NULL; + +} /* end of mgsl_free_intermediate_rxbuffer_memory() */ + +/* + * mgsl_alloc_intermediate_txbuffer_memory() + * + * Allocate intermdiate transmit buffer(s) large enough to hold max_frame_size. + * This buffer is used to load transmit frames into the adapter's dma transfer + * buffers when there is sufficient space. + * + * Arguments: + * + * info pointer to device instance data + * + * Return Value: 0 if success, otherwise -ENOMEM + */ +static int mgsl_alloc_intermediate_txbuffer_memory(struct mgsl_struct *info) +{ + int i; + + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk("%s %s(%d) allocating %d tx holding buffers\n", + info->device_name, __FILE__,__LINE__,info->num_tx_holding_buffers); + + memset(info->tx_holding_buffers,0,sizeof(info->tx_holding_buffers)); + + for ( i=0; inum_tx_holding_buffers; ++i) { + info->tx_holding_buffers[i].buffer = + kmalloc(info->max_frame_size, GFP_KERNEL); + if (info->tx_holding_buffers[i].buffer == NULL) { + for (--i; i >= 0; i--) { + kfree(info->tx_holding_buffers[i].buffer); + info->tx_holding_buffers[i].buffer = NULL; + } + return -ENOMEM; + } + } + + return 0; + +} /* end of mgsl_alloc_intermediate_txbuffer_memory() */ + +/* + * mgsl_free_intermediate_txbuffer_memory() + * + * + * Arguments: + * + * info pointer to device instance data + * + * Return Value: None + */ +static void mgsl_free_intermediate_txbuffer_memory(struct mgsl_struct *info) +{ + int i; + + for ( i=0; inum_tx_holding_buffers; ++i ) { + kfree(info->tx_holding_buffers[i].buffer); + info->tx_holding_buffers[i].buffer = NULL; + } + + info->get_tx_holding_index = 0; + info->put_tx_holding_index = 0; + info->tx_holding_count = 0; + +} /* end of mgsl_free_intermediate_txbuffer_memory() */ + + +/* + * load_next_tx_holding_buffer() + * + * attempts to load the next buffered tx request into the + * tx dma buffers + * + * Arguments: + * + * info pointer to device instance data + * + * Return Value: true if next buffered tx request loaded + * into adapter's tx dma buffer, + * false otherwise + */ +static bool load_next_tx_holding_buffer(struct mgsl_struct *info) +{ + bool ret = false; + + if ( info->tx_holding_count ) { + /* determine if we have enough tx dma buffers + * to accommodate the next tx frame + */ + struct tx_holding_buffer *ptx = + &info->tx_holding_buffers[info->get_tx_holding_index]; + int num_free = num_free_tx_dma_buffers(info); + int num_needed = ptx->buffer_size / DMABUFFERSIZE; + if ( ptx->buffer_size % DMABUFFERSIZE ) + ++num_needed; + + if (num_needed <= num_free) { + info->xmit_cnt = ptx->buffer_size; + mgsl_load_tx_dma_buffer(info,ptx->buffer,ptx->buffer_size); + + --info->tx_holding_count; + if ( ++info->get_tx_holding_index >= info->num_tx_holding_buffers) + info->get_tx_holding_index=0; + + /* restart transmit timer */ + mod_timer(&info->tx_timer, jiffies + msecs_to_jiffies(5000)); + + ret = true; + } + } + + return ret; +} + +/* + * save_tx_buffer_request() + * + * attempt to store transmit frame request for later transmission + * + * Arguments: + * + * info pointer to device instance data + * Buffer pointer to buffer containing frame to load + * BufferSize size in bytes of frame in Buffer + * + * Return Value: 1 if able to store, 0 otherwise + */ +static int save_tx_buffer_request(struct mgsl_struct *info,const char *Buffer, unsigned int BufferSize) +{ + struct tx_holding_buffer *ptx; + + if ( info->tx_holding_count >= info->num_tx_holding_buffers ) { + return 0; /* all buffers in use */ + } + + ptx = &info->tx_holding_buffers[info->put_tx_holding_index]; + ptx->buffer_size = BufferSize; + memcpy( ptx->buffer, Buffer, BufferSize); + + ++info->tx_holding_count; + if ( ++info->put_tx_holding_index >= info->num_tx_holding_buffers) + info->put_tx_holding_index=0; + + return 1; +} + +static int mgsl_claim_resources(struct mgsl_struct *info) +{ + if (request_region(info->io_base,info->io_addr_size,"synclink") == NULL) { + printk( "%s(%d):I/O address conflict on device %s Addr=%08X\n", + __FILE__,__LINE__,info->device_name, info->io_base); + return -ENODEV; + } + info->io_addr_requested = true; + + if ( request_irq(info->irq_level,mgsl_interrupt,info->irq_flags, + info->device_name, info ) < 0 ) { + printk( "%s(%d):Cant request interrupt on device %s IRQ=%d\n", + __FILE__,__LINE__,info->device_name, info->irq_level ); + goto errout; + } + info->irq_requested = true; + + if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { + if (request_mem_region(info->phys_memory_base,0x40000,"synclink") == NULL) { + printk( "%s(%d):mem addr conflict device %s Addr=%08X\n", + __FILE__,__LINE__,info->device_name, info->phys_memory_base); + goto errout; + } + info->shared_mem_requested = true; + if (request_mem_region(info->phys_lcr_base + info->lcr_offset,128,"synclink") == NULL) { + printk( "%s(%d):lcr mem addr conflict device %s Addr=%08X\n", + __FILE__,__LINE__,info->device_name, info->phys_lcr_base + info->lcr_offset); + goto errout; + } + info->lcr_mem_requested = true; + + info->memory_base = ioremap_nocache(info->phys_memory_base, + 0x40000); + if (!info->memory_base) { + printk( "%s(%d):Cant map shared memory on device %s MemAddr=%08X\n", + __FILE__,__LINE__,info->device_name, info->phys_memory_base ); + goto errout; + } + + if ( !mgsl_memory_test(info) ) { + printk( "%s(%d):Failed shared memory test %s MemAddr=%08X\n", + __FILE__,__LINE__,info->device_name, info->phys_memory_base ); + goto errout; + } + + info->lcr_base = ioremap_nocache(info->phys_lcr_base, + PAGE_SIZE); + if (!info->lcr_base) { + printk( "%s(%d):Cant map LCR memory on device %s MemAddr=%08X\n", + __FILE__,__LINE__,info->device_name, info->phys_lcr_base ); + goto errout; + } + info->lcr_base += info->lcr_offset; + + } else { + /* claim DMA channel */ + + if (request_dma(info->dma_level,info->device_name) < 0){ + printk( "%s(%d):Cant request DMA channel on device %s DMA=%d\n", + __FILE__,__LINE__,info->device_name, info->dma_level ); + mgsl_release_resources( info ); + return -ENODEV; + } + info->dma_requested = true; + + /* ISA adapter uses bus master DMA */ + set_dma_mode(info->dma_level,DMA_MODE_CASCADE); + enable_dma(info->dma_level); + } + + if ( mgsl_allocate_dma_buffers(info) < 0 ) { + printk( "%s(%d):Cant allocate DMA buffers on device %s DMA=%d\n", + __FILE__,__LINE__,info->device_name, info->dma_level ); + goto errout; + } + + return 0; +errout: + mgsl_release_resources(info); + return -ENODEV; + +} /* end of mgsl_claim_resources() */ + +static void mgsl_release_resources(struct mgsl_struct *info) +{ + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):mgsl_release_resources(%s) entry\n", + __FILE__,__LINE__,info->device_name ); + + if ( info->irq_requested ) { + free_irq(info->irq_level, info); + info->irq_requested = false; + } + if ( info->dma_requested ) { + disable_dma(info->dma_level); + free_dma(info->dma_level); + info->dma_requested = false; + } + mgsl_free_dma_buffers(info); + mgsl_free_intermediate_rxbuffer_memory(info); + mgsl_free_intermediate_txbuffer_memory(info); + + if ( info->io_addr_requested ) { + release_region(info->io_base,info->io_addr_size); + info->io_addr_requested = false; + } + if ( info->shared_mem_requested ) { + release_mem_region(info->phys_memory_base,0x40000); + info->shared_mem_requested = false; + } + if ( info->lcr_mem_requested ) { + release_mem_region(info->phys_lcr_base + info->lcr_offset,128); + info->lcr_mem_requested = false; + } + if (info->memory_base){ + iounmap(info->memory_base); + info->memory_base = NULL; + } + if (info->lcr_base){ + iounmap(info->lcr_base - info->lcr_offset); + info->lcr_base = NULL; + } + + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):mgsl_release_resources(%s) exit\n", + __FILE__,__LINE__,info->device_name ); + +} /* end of mgsl_release_resources() */ + +/* mgsl_add_device() + * + * Add the specified device instance data structure to the + * global linked list of devices and increment the device count. + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void mgsl_add_device( struct mgsl_struct *info ) +{ + info->next_device = NULL; + info->line = mgsl_device_count; + sprintf(info->device_name,"ttySL%d",info->line); + + if (info->line < MAX_TOTAL_DEVICES) { + if (maxframe[info->line]) + info->max_frame_size = maxframe[info->line]; + + if (txdmabufs[info->line]) { + info->num_tx_dma_buffers = txdmabufs[info->line]; + if (info->num_tx_dma_buffers < 1) + info->num_tx_dma_buffers = 1; + } + + if (txholdbufs[info->line]) { + info->num_tx_holding_buffers = txholdbufs[info->line]; + if (info->num_tx_holding_buffers < 1) + info->num_tx_holding_buffers = 1; + else if (info->num_tx_holding_buffers > MAX_TX_HOLDING_BUFFERS) + info->num_tx_holding_buffers = MAX_TX_HOLDING_BUFFERS; + } + } + + mgsl_device_count++; + + if ( !mgsl_device_list ) + mgsl_device_list = info; + else { + struct mgsl_struct *current_dev = mgsl_device_list; + while( current_dev->next_device ) + current_dev = current_dev->next_device; + current_dev->next_device = info; + } + + if ( info->max_frame_size < 4096 ) + info->max_frame_size = 4096; + else if ( info->max_frame_size > 65535 ) + info->max_frame_size = 65535; + + if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { + printk( "SyncLink PCI v%d %s: IO=%04X IRQ=%d Mem=%08X,%08X MaxFrameSize=%u\n", + info->hw_version + 1, info->device_name, info->io_base, info->irq_level, + info->phys_memory_base, info->phys_lcr_base, + info->max_frame_size ); + } else { + printk( "SyncLink ISA %s: IO=%04X IRQ=%d DMA=%d MaxFrameSize=%u\n", + info->device_name, info->io_base, info->irq_level, info->dma_level, + info->max_frame_size ); + } + +#if SYNCLINK_GENERIC_HDLC + hdlcdev_init(info); +#endif + +} /* end of mgsl_add_device() */ + +static const struct tty_port_operations mgsl_port_ops = { + .carrier_raised = carrier_raised, + .dtr_rts = dtr_rts, +}; + + +/* mgsl_allocate_device() + * + * Allocate and initialize a device instance structure + * + * Arguments: none + * Return Value: pointer to mgsl_struct if success, otherwise NULL + */ +static struct mgsl_struct* mgsl_allocate_device(void) +{ + struct mgsl_struct *info; + + info = kzalloc(sizeof(struct mgsl_struct), + GFP_KERNEL); + + if (!info) { + printk("Error can't allocate device instance data\n"); + } else { + tty_port_init(&info->port); + info->port.ops = &mgsl_port_ops; + info->magic = MGSL_MAGIC; + INIT_WORK(&info->task, mgsl_bh_handler); + info->max_frame_size = 4096; + info->port.close_delay = 5*HZ/10; + info->port.closing_wait = 30*HZ; + init_waitqueue_head(&info->status_event_wait_q); + init_waitqueue_head(&info->event_wait_q); + spin_lock_init(&info->irq_spinlock); + spin_lock_init(&info->netlock); + memcpy(&info->params,&default_params,sizeof(MGSL_PARAMS)); + info->idle_mode = HDLC_TXIDLE_FLAGS; + info->num_tx_dma_buffers = 1; + info->num_tx_holding_buffers = 0; + } + + return info; + +} /* end of mgsl_allocate_device()*/ + +static const struct tty_operations mgsl_ops = { + .open = mgsl_open, + .close = mgsl_close, + .write = mgsl_write, + .put_char = mgsl_put_char, + .flush_chars = mgsl_flush_chars, + .write_room = mgsl_write_room, + .chars_in_buffer = mgsl_chars_in_buffer, + .flush_buffer = mgsl_flush_buffer, + .ioctl = mgsl_ioctl, + .throttle = mgsl_throttle, + .unthrottle = mgsl_unthrottle, + .send_xchar = mgsl_send_xchar, + .break_ctl = mgsl_break, + .wait_until_sent = mgsl_wait_until_sent, + .set_termios = mgsl_set_termios, + .stop = mgsl_stop, + .start = mgsl_start, + .hangup = mgsl_hangup, + .tiocmget = tiocmget, + .tiocmset = tiocmset, + .get_icount = msgl_get_icount, + .proc_fops = &mgsl_proc_fops, +}; + +/* + * perform tty device initialization + */ +static int mgsl_init_tty(void) +{ + int rc; + + serial_driver = alloc_tty_driver(128); + if (!serial_driver) + return -ENOMEM; + + serial_driver->owner = THIS_MODULE; + serial_driver->driver_name = "synclink"; + serial_driver->name = "ttySL"; + serial_driver->major = ttymajor; + serial_driver->minor_start = 64; + serial_driver->type = TTY_DRIVER_TYPE_SERIAL; + serial_driver->subtype = SERIAL_TYPE_NORMAL; + serial_driver->init_termios = tty_std_termios; + serial_driver->init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + serial_driver->init_termios.c_ispeed = 9600; + serial_driver->init_termios.c_ospeed = 9600; + serial_driver->flags = TTY_DRIVER_REAL_RAW; + tty_set_operations(serial_driver, &mgsl_ops); + if ((rc = tty_register_driver(serial_driver)) < 0) { + printk("%s(%d):Couldn't register serial driver\n", + __FILE__,__LINE__); + put_tty_driver(serial_driver); + serial_driver = NULL; + return rc; + } + + printk("%s %s, tty major#%d\n", + driver_name, driver_version, + serial_driver->major); + return 0; +} + +/* enumerate user specified ISA adapters + */ +static void mgsl_enum_isa_devices(void) +{ + struct mgsl_struct *info; + int i; + + /* Check for user specified ISA devices */ + + for (i=0 ;(i < MAX_ISA_DEVICES) && io[i] && irq[i]; i++){ + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk("ISA device specified io=%04X,irq=%d,dma=%d\n", + io[i], irq[i], dma[i] ); + + info = mgsl_allocate_device(); + if ( !info ) { + /* error allocating device instance data */ + if ( debug_level >= DEBUG_LEVEL_ERROR ) + printk( "can't allocate device instance data.\n"); + continue; + } + + /* Copy user configuration info to device instance data */ + info->io_base = (unsigned int)io[i]; + info->irq_level = (unsigned int)irq[i]; + info->irq_level = irq_canonicalize(info->irq_level); + info->dma_level = (unsigned int)dma[i]; + info->bus_type = MGSL_BUS_TYPE_ISA; + info->io_addr_size = 16; + info->irq_flags = 0; + + mgsl_add_device( info ); + } +} + +static void synclink_cleanup(void) +{ + int rc; + struct mgsl_struct *info; + struct mgsl_struct *tmp; + + printk("Unloading %s: %s\n", driver_name, driver_version); + + if (serial_driver) { + if ((rc = tty_unregister_driver(serial_driver))) + printk("%s(%d) failed to unregister tty driver err=%d\n", + __FILE__,__LINE__,rc); + put_tty_driver(serial_driver); + } + + info = mgsl_device_list; + while(info) { +#if SYNCLINK_GENERIC_HDLC + hdlcdev_exit(info); +#endif + mgsl_release_resources(info); + tmp = info; + info = info->next_device; + kfree(tmp); + } + + if (pci_registered) + pci_unregister_driver(&synclink_pci_driver); +} + +static int __init synclink_init(void) +{ + int rc; + + if (break_on_load) { + mgsl_get_text_ptr(); + BREAKPOINT(); + } + + printk("%s %s\n", driver_name, driver_version); + + mgsl_enum_isa_devices(); + if ((rc = pci_register_driver(&synclink_pci_driver)) < 0) + printk("%s:failed to register PCI driver, error=%d\n",__FILE__,rc); + else + pci_registered = true; + + if ((rc = mgsl_init_tty()) < 0) + goto error; + + return 0; + +error: + synclink_cleanup(); + return rc; +} + +static void __exit synclink_exit(void) +{ + synclink_cleanup(); +} + +module_init(synclink_init); +module_exit(synclink_exit); + +/* + * usc_RTCmd() + * + * Issue a USC Receive/Transmit command to the + * Channel Command/Address Register (CCAR). + * + * Notes: + * + * The command is encoded in the most significant 5 bits <15..11> + * of the CCAR value. Bits <10..7> of the CCAR must be preserved + * and Bits <6..0> must be written as zeros. + * + * Arguments: + * + * info pointer to device information structure + * Cmd command mask (use symbolic macros) + * + * Return Value: + * + * None + */ +static void usc_RTCmd( struct mgsl_struct *info, u16 Cmd ) +{ + /* output command to CCAR in bits <15..11> */ + /* preserve bits <10..7>, bits <6..0> must be zero */ + + outw( Cmd + info->loopback_bits, info->io_base + CCAR ); + + /* Read to flush write to CCAR */ + if ( info->bus_type == MGSL_BUS_TYPE_PCI ) + inw( info->io_base + CCAR ); + +} /* end of usc_RTCmd() */ + +/* + * usc_DmaCmd() + * + * Issue a DMA command to the DMA Command/Address Register (DCAR). + * + * Arguments: + * + * info pointer to device information structure + * Cmd DMA command mask (usc_DmaCmd_XX Macros) + * + * Return Value: + * + * None + */ +static void usc_DmaCmd( struct mgsl_struct *info, u16 Cmd ) +{ + /* write command mask to DCAR */ + outw( Cmd + info->mbre_bit, info->io_base ); + + /* Read to flush write to DCAR */ + if ( info->bus_type == MGSL_BUS_TYPE_PCI ) + inw( info->io_base ); + +} /* end of usc_DmaCmd() */ + +/* + * usc_OutDmaReg() + * + * Write a 16-bit value to a USC DMA register + * + * Arguments: + * + * info pointer to device info structure + * RegAddr register address (number) for write + * RegValue 16-bit value to write to register + * + * Return Value: + * + * None + * + */ +static void usc_OutDmaReg( struct mgsl_struct *info, u16 RegAddr, u16 RegValue ) +{ + /* Note: The DCAR is located at the adapter base address */ + /* Note: must preserve state of BIT8 in DCAR */ + + outw( RegAddr + info->mbre_bit, info->io_base ); + outw( RegValue, info->io_base ); + + /* Read to flush write to DCAR */ + if ( info->bus_type == MGSL_BUS_TYPE_PCI ) + inw( info->io_base ); + +} /* end of usc_OutDmaReg() */ + +/* + * usc_InDmaReg() + * + * Read a 16-bit value from a DMA register + * + * Arguments: + * + * info pointer to device info structure + * RegAddr register address (number) to read from + * + * Return Value: + * + * The 16-bit value read from register + * + */ +static u16 usc_InDmaReg( struct mgsl_struct *info, u16 RegAddr ) +{ + /* Note: The DCAR is located at the adapter base address */ + /* Note: must preserve state of BIT8 in DCAR */ + + outw( RegAddr + info->mbre_bit, info->io_base ); + return inw( info->io_base ); + +} /* end of usc_InDmaReg() */ + +/* + * + * usc_OutReg() + * + * Write a 16-bit value to a USC serial channel register + * + * Arguments: + * + * info pointer to device info structure + * RegAddr register address (number) to write to + * RegValue 16-bit value to write to register + * + * Return Value: + * + * None + * + */ +static void usc_OutReg( struct mgsl_struct *info, u16 RegAddr, u16 RegValue ) +{ + outw( RegAddr + info->loopback_bits, info->io_base + CCAR ); + outw( RegValue, info->io_base + CCAR ); + + /* Read to flush write to CCAR */ + if ( info->bus_type == MGSL_BUS_TYPE_PCI ) + inw( info->io_base + CCAR ); + +} /* end of usc_OutReg() */ + +/* + * usc_InReg() + * + * Reads a 16-bit value from a USC serial channel register + * + * Arguments: + * + * info pointer to device extension + * RegAddr register address (number) to read from + * + * Return Value: + * + * 16-bit value read from register + */ +static u16 usc_InReg( struct mgsl_struct *info, u16 RegAddr ) +{ + outw( RegAddr + info->loopback_bits, info->io_base + CCAR ); + return inw( info->io_base + CCAR ); + +} /* end of usc_InReg() */ + +/* usc_set_sdlc_mode() + * + * Set up the adapter for SDLC DMA communications. + * + * Arguments: info pointer to device instance data + * Return Value: NONE + */ +static void usc_set_sdlc_mode( struct mgsl_struct *info ) +{ + u16 RegValue; + bool PreSL1660; + + /* + * determine if the IUSC on the adapter is pre-SL1660. If + * not, take advantage of the UnderWait feature of more + * modern chips. If an underrun occurs and this bit is set, + * the transmitter will idle the programmed idle pattern + * until the driver has time to service the underrun. Otherwise, + * the dma controller may get the cycles previously requested + * and begin transmitting queued tx data. + */ + usc_OutReg(info,TMCR,0x1f); + RegValue=usc_InReg(info,TMDR); + PreSL1660 = (RegValue == IUSC_PRE_SL1660); + + if ( info->params.flags & HDLC_FLAG_HDLC_LOOPMODE ) + { + /* + ** Channel Mode Register (CMR) + ** + ** <15..14> 10 Tx Sub Modes, Send Flag on Underrun + ** <13> 0 0 = Transmit Disabled (initially) + ** <12> 0 1 = Consecutive Idles share common 0 + ** <11..8> 1110 Transmitter Mode = HDLC/SDLC Loop + ** <7..4> 0000 Rx Sub Modes, addr/ctrl field handling + ** <3..0> 0110 Receiver Mode = HDLC/SDLC + ** + ** 1000 1110 0000 0110 = 0x8e06 + */ + RegValue = 0x8e06; + + /*-------------------------------------------------- + * ignore user options for UnderRun Actions and + * preambles + *--------------------------------------------------*/ + } + else + { + /* Channel mode Register (CMR) + * + * <15..14> 00 Tx Sub modes, Underrun Action + * <13> 0 1 = Send Preamble before opening flag + * <12> 0 1 = Consecutive Idles share common 0 + * <11..8> 0110 Transmitter mode = HDLC/SDLC + * <7..4> 0000 Rx Sub modes, addr/ctrl field handling + * <3..0> 0110 Receiver mode = HDLC/SDLC + * + * 0000 0110 0000 0110 = 0x0606 + */ + if (info->params.mode == MGSL_MODE_RAW) { + RegValue = 0x0001; /* Set Receive mode = external sync */ + + usc_OutReg( info, IOCR, /* Set IOCR DCD is RxSync Detect Input */ + (unsigned short)((usc_InReg(info, IOCR) & ~(BIT13|BIT12)) | BIT12)); + + /* + * TxSubMode: + * CMR <15> 0 Don't send CRC on Tx Underrun + * CMR <14> x undefined + * CMR <13> 0 Send preamble before openning sync + * CMR <12> 0 Send 8-bit syncs, 1=send Syncs per TxLength + * + * TxMode: + * CMR <11-8) 0100 MonoSync + * + * 0x00 0100 xxxx xxxx 04xx + */ + RegValue |= 0x0400; + } + else { + + RegValue = 0x0606; + + if ( info->params.flags & HDLC_FLAG_UNDERRUN_ABORT15 ) + RegValue |= BIT14; + else if ( info->params.flags & HDLC_FLAG_UNDERRUN_FLAG ) + RegValue |= BIT15; + else if ( info->params.flags & HDLC_FLAG_UNDERRUN_CRC ) + RegValue |= BIT15 + BIT14; + } + + if ( info->params.preamble != HDLC_PREAMBLE_PATTERN_NONE ) + RegValue |= BIT13; + } + + if ( info->params.mode == MGSL_MODE_HDLC && + (info->params.flags & HDLC_FLAG_SHARE_ZERO) ) + RegValue |= BIT12; + + if ( info->params.addr_filter != 0xff ) + { + /* set up receive address filtering */ + usc_OutReg( info, RSR, info->params.addr_filter ); + RegValue |= BIT4; + } + + usc_OutReg( info, CMR, RegValue ); + info->cmr_value = RegValue; + + /* Receiver mode Register (RMR) + * + * <15..13> 000 encoding + * <12..11> 00 FCS = 16bit CRC CCITT (x15 + x12 + x5 + 1) + * <10> 1 1 = Set CRC to all 1s (use for SDLC/HDLC) + * <9> 0 1 = Include Receive chars in CRC + * <8> 1 1 = Use Abort/PE bit as abort indicator + * <7..6> 00 Even parity + * <5> 0 parity disabled + * <4..2> 000 Receive Char Length = 8 bits + * <1..0> 00 Disable Receiver + * + * 0000 0101 0000 0000 = 0x0500 + */ + + RegValue = 0x0500; + + switch ( info->params.encoding ) { + case HDLC_ENCODING_NRZB: RegValue |= BIT13; break; + case HDLC_ENCODING_NRZI_MARK: RegValue |= BIT14; break; + case HDLC_ENCODING_NRZI_SPACE: RegValue |= BIT14 + BIT13; break; + case HDLC_ENCODING_BIPHASE_MARK: RegValue |= BIT15; break; + case HDLC_ENCODING_BIPHASE_SPACE: RegValue |= BIT15 + BIT13; break; + case HDLC_ENCODING_BIPHASE_LEVEL: RegValue |= BIT15 + BIT14; break; + case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: RegValue |= BIT15 + BIT14 + BIT13; break; + } + + if ( (info->params.crc_type & HDLC_CRC_MASK) == HDLC_CRC_16_CCITT ) + RegValue |= BIT9; + else if ( (info->params.crc_type & HDLC_CRC_MASK) == HDLC_CRC_32_CCITT ) + RegValue |= ( BIT12 | BIT10 | BIT9 ); + + usc_OutReg( info, RMR, RegValue ); + + /* Set the Receive count Limit Register (RCLR) to 0xffff. */ + /* When an opening flag of an SDLC frame is recognized the */ + /* Receive Character count (RCC) is loaded with the value in */ + /* RCLR. The RCC is decremented for each received byte. The */ + /* value of RCC is stored after the closing flag of the frame */ + /* allowing the frame size to be computed. */ + + usc_OutReg( info, RCLR, RCLRVALUE ); + + usc_RCmd( info, RCmd_SelectRicrdma_level ); + + /* Receive Interrupt Control Register (RICR) + * + * <15..8> ? RxFIFO DMA Request Level + * <7> 0 Exited Hunt IA (Interrupt Arm) + * <6> 0 Idle Received IA + * <5> 0 Break/Abort IA + * <4> 0 Rx Bound IA + * <3> 1 Queued status reflects oldest 2 bytes in FIFO + * <2> 0 Abort/PE IA + * <1> 1 Rx Overrun IA + * <0> 0 Select TC0 value for readback + * + * 0000 0000 0000 1000 = 0x000a + */ + + /* Carry over the Exit Hunt and Idle Received bits */ + /* in case they have been armed by usc_ArmEvents. */ + + RegValue = usc_InReg( info, RICR ) & 0xc0; + + if ( info->bus_type == MGSL_BUS_TYPE_PCI ) + usc_OutReg( info, RICR, (u16)(0x030a | RegValue) ); + else + usc_OutReg( info, RICR, (u16)(0x140a | RegValue) ); + + /* Unlatch all Rx status bits and clear Rx status IRQ Pending */ + + usc_UnlatchRxstatusBits( info, RXSTATUS_ALL ); + usc_ClearIrqPendingBits( info, RECEIVE_STATUS ); + + /* Transmit mode Register (TMR) + * + * <15..13> 000 encoding + * <12..11> 00 FCS = 16bit CRC CCITT (x15 + x12 + x5 + 1) + * <10> 1 1 = Start CRC as all 1s (use for SDLC/HDLC) + * <9> 0 1 = Tx CRC Enabled + * <8> 0 1 = Append CRC to end of transmit frame + * <7..6> 00 Transmit parity Even + * <5> 0 Transmit parity Disabled + * <4..2> 000 Tx Char Length = 8 bits + * <1..0> 00 Disable Transmitter + * + * 0000 0100 0000 0000 = 0x0400 + */ + + RegValue = 0x0400; + + switch ( info->params.encoding ) { + case HDLC_ENCODING_NRZB: RegValue |= BIT13; break; + case HDLC_ENCODING_NRZI_MARK: RegValue |= BIT14; break; + case HDLC_ENCODING_NRZI_SPACE: RegValue |= BIT14 + BIT13; break; + case HDLC_ENCODING_BIPHASE_MARK: RegValue |= BIT15; break; + case HDLC_ENCODING_BIPHASE_SPACE: RegValue |= BIT15 + BIT13; break; + case HDLC_ENCODING_BIPHASE_LEVEL: RegValue |= BIT15 + BIT14; break; + case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: RegValue |= BIT15 + BIT14 + BIT13; break; + } + + if ( (info->params.crc_type & HDLC_CRC_MASK) == HDLC_CRC_16_CCITT ) + RegValue |= BIT9 + BIT8; + else if ( (info->params.crc_type & HDLC_CRC_MASK) == HDLC_CRC_32_CCITT ) + RegValue |= ( BIT12 | BIT10 | BIT9 | BIT8); + + usc_OutReg( info, TMR, RegValue ); + + usc_set_txidle( info ); + + + usc_TCmd( info, TCmd_SelectTicrdma_level ); + + /* Transmit Interrupt Control Register (TICR) + * + * <15..8> ? Transmit FIFO DMA Level + * <7> 0 Present IA (Interrupt Arm) + * <6> 0 Idle Sent IA + * <5> 1 Abort Sent IA + * <4> 1 EOF/EOM Sent IA + * <3> 0 CRC Sent IA + * <2> 1 1 = Wait for SW Trigger to Start Frame + * <1> 1 Tx Underrun IA + * <0> 0 TC0 constant on read back + * + * 0000 0000 0011 0110 = 0x0036 + */ + + if ( info->bus_type == MGSL_BUS_TYPE_PCI ) + usc_OutReg( info, TICR, 0x0736 ); + else + usc_OutReg( info, TICR, 0x1436 ); + + usc_UnlatchTxstatusBits( info, TXSTATUS_ALL ); + usc_ClearIrqPendingBits( info, TRANSMIT_STATUS ); + + /* + ** Transmit Command/Status Register (TCSR) + ** + ** <15..12> 0000 TCmd + ** <11> 0/1 UnderWait + ** <10..08> 000 TxIdle + ** <7> x PreSent + ** <6> x IdleSent + ** <5> x AbortSent + ** <4> x EOF/EOM Sent + ** <3> x CRC Sent + ** <2> x All Sent + ** <1> x TxUnder + ** <0> x TxEmpty + ** + ** 0000 0000 0000 0000 = 0x0000 + */ + info->tcsr_value = 0; + + if ( !PreSL1660 ) + info->tcsr_value |= TCSR_UNDERWAIT; + + usc_OutReg( info, TCSR, info->tcsr_value ); + + /* Clock mode Control Register (CMCR) + * + * <15..14> 00 counter 1 Source = Disabled + * <13..12> 00 counter 0 Source = Disabled + * <11..10> 11 BRG1 Input is TxC Pin + * <9..8> 11 BRG0 Input is TxC Pin + * <7..6> 01 DPLL Input is BRG1 Output + * <5..3> XXX TxCLK comes from Port 0 + * <2..0> XXX RxCLK comes from Port 1 + * + * 0000 1111 0111 0111 = 0x0f77 + */ + + RegValue = 0x0f40; + + if ( info->params.flags & HDLC_FLAG_RXC_DPLL ) + RegValue |= 0x0003; /* RxCLK from DPLL */ + else if ( info->params.flags & HDLC_FLAG_RXC_BRG ) + RegValue |= 0x0004; /* RxCLK from BRG0 */ + else if ( info->params.flags & HDLC_FLAG_RXC_TXCPIN) + RegValue |= 0x0006; /* RxCLK from TXC Input */ + else + RegValue |= 0x0007; /* RxCLK from Port1 */ + + if ( info->params.flags & HDLC_FLAG_TXC_DPLL ) + RegValue |= 0x0018; /* TxCLK from DPLL */ + else if ( info->params.flags & HDLC_FLAG_TXC_BRG ) + RegValue |= 0x0020; /* TxCLK from BRG0 */ + else if ( info->params.flags & HDLC_FLAG_TXC_RXCPIN) + RegValue |= 0x0038; /* RxCLK from TXC Input */ + else + RegValue |= 0x0030; /* TxCLK from Port0 */ + + usc_OutReg( info, CMCR, RegValue ); + + + /* Hardware Configuration Register (HCR) + * + * <15..14> 00 CTR0 Divisor:00=32,01=16,10=8,11=4 + * <13> 0 CTR1DSel:0=CTR0Div determines CTR0Div + * <12> 0 CVOK:0=report code violation in biphase + * <11..10> 00 DPLL Divisor:00=32,01=16,10=8,11=4 + * <9..8> XX DPLL mode:00=disable,01=NRZ,10=Biphase,11=Biphase Level + * <7..6> 00 reserved + * <5> 0 BRG1 mode:0=continuous,1=single cycle + * <4> X BRG1 Enable + * <3..2> 00 reserved + * <1> 0 BRG0 mode:0=continuous,1=single cycle + * <0> 0 BRG0 Enable + */ + + RegValue = 0x0000; + + if ( info->params.flags & (HDLC_FLAG_RXC_DPLL + HDLC_FLAG_TXC_DPLL) ) { + u32 XtalSpeed; + u32 DpllDivisor; + u16 Tc; + + /* DPLL is enabled. Use BRG1 to provide continuous reference clock */ + /* for DPLL. DPLL mode in HCR is dependent on the encoding used. */ + + if ( info->bus_type == MGSL_BUS_TYPE_PCI ) + XtalSpeed = 11059200; + else + XtalSpeed = 14745600; + + if ( info->params.flags & HDLC_FLAG_DPLL_DIV16 ) { + DpllDivisor = 16; + RegValue |= BIT10; + } + else if ( info->params.flags & HDLC_FLAG_DPLL_DIV8 ) { + DpllDivisor = 8; + RegValue |= BIT11; + } + else + DpllDivisor = 32; + + /* Tc = (Xtal/Speed) - 1 */ + /* If twice the remainder of (Xtal/Speed) is greater than Speed */ + /* then rounding up gives a more precise time constant. Instead */ + /* of rounding up and then subtracting 1 we just don't subtract */ + /* the one in this case. */ + + /*-------------------------------------------------- + * ejz: for DPLL mode, application should use the + * same clock speed as the partner system, even + * though clocking is derived from the input RxData. + * In case the user uses a 0 for the clock speed, + * default to 0xffffffff and don't try to divide by + * zero + *--------------------------------------------------*/ + if ( info->params.clock_speed ) + { + Tc = (u16)((XtalSpeed/DpllDivisor)/info->params.clock_speed); + if ( !((((XtalSpeed/DpllDivisor) % info->params.clock_speed) * 2) + / info->params.clock_speed) ) + Tc--; + } + else + Tc = -1; + + + /* Write 16-bit Time Constant for BRG1 */ + usc_OutReg( info, TC1R, Tc ); + + RegValue |= BIT4; /* enable BRG1 */ + + switch ( info->params.encoding ) { + case HDLC_ENCODING_NRZ: + case HDLC_ENCODING_NRZB: + case HDLC_ENCODING_NRZI_MARK: + case HDLC_ENCODING_NRZI_SPACE: RegValue |= BIT8; break; + case HDLC_ENCODING_BIPHASE_MARK: + case HDLC_ENCODING_BIPHASE_SPACE: RegValue |= BIT9; break; + case HDLC_ENCODING_BIPHASE_LEVEL: + case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: RegValue |= BIT9 + BIT8; break; + } + } + + usc_OutReg( info, HCR, RegValue ); + + + /* Channel Control/status Register (CCSR) + * + * <15> X RCC FIFO Overflow status (RO) + * <14> X RCC FIFO Not Empty status (RO) + * <13> 0 1 = Clear RCC FIFO (WO) + * <12> X DPLL Sync (RW) + * <11> X DPLL 2 Missed Clocks status (RO) + * <10> X DPLL 1 Missed Clock status (RO) + * <9..8> 00 DPLL Resync on rising and falling edges (RW) + * <7> X SDLC Loop On status (RO) + * <6> X SDLC Loop Send status (RO) + * <5> 1 Bypass counters for TxClk and RxClk (RW) + * <4..2> 000 Last Char of SDLC frame has 8 bits (RW) + * <1..0> 00 reserved + * + * 0000 0000 0010 0000 = 0x0020 + */ + + usc_OutReg( info, CCSR, 0x1020 ); + + + if ( info->params.flags & HDLC_FLAG_AUTO_CTS ) { + usc_OutReg( info, SICR, + (u16)(usc_InReg(info,SICR) | SICR_CTS_INACTIVE) ); + } + + + /* enable Master Interrupt Enable bit (MIE) */ + usc_EnableMasterIrqBit( info ); + + usc_ClearIrqPendingBits( info, RECEIVE_STATUS + RECEIVE_DATA + + TRANSMIT_STATUS + TRANSMIT_DATA + MISC); + + /* arm RCC underflow interrupt */ + usc_OutReg(info, SICR, (u16)(usc_InReg(info,SICR) | BIT3)); + usc_EnableInterrupts(info, MISC); + + info->mbre_bit = 0; + outw( 0, info->io_base ); /* clear Master Bus Enable (DCAR) */ + usc_DmaCmd( info, DmaCmd_ResetAllChannels ); /* disable both DMA channels */ + info->mbre_bit = BIT8; + outw( BIT8, info->io_base ); /* set Master Bus Enable (DCAR) */ + + if (info->bus_type == MGSL_BUS_TYPE_ISA) { + /* Enable DMAEN (Port 7, Bit 14) */ + /* This connects the DMA request signal to the ISA bus */ + usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT15) & ~BIT14)); + } + + /* DMA Control Register (DCR) + * + * <15..14> 10 Priority mode = Alternating Tx/Rx + * 01 Rx has priority + * 00 Tx has priority + * + * <13> 1 Enable Priority Preempt per DCR<15..14> + * (WARNING DCR<11..10> must be 00 when this is 1) + * 0 Choose activate channel per DCR<11..10> + * + * <12> 0 Little Endian for Array/List + * <11..10> 00 Both Channels can use each bus grant + * <9..6> 0000 reserved + * <5> 0 7 CLK - Minimum Bus Re-request Interval + * <4> 0 1 = drive D/C and S/D pins + * <3> 1 1 = Add one wait state to all DMA cycles. + * <2> 0 1 = Strobe /UAS on every transfer. + * <1..0> 11 Addr incrementing only affects LS24 bits + * + * 0110 0000 0000 1011 = 0x600b + */ + + if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { + /* PCI adapter does not need DMA wait state */ + usc_OutDmaReg( info, DCR, 0xa00b ); + } + else + usc_OutDmaReg( info, DCR, 0x800b ); + + + /* Receive DMA mode Register (RDMR) + * + * <15..14> 11 DMA mode = Linked List Buffer mode + * <13> 1 RSBinA/L = store Rx status Block in Arrary/List entry + * <12> 1 Clear count of List Entry after fetching + * <11..10> 00 Address mode = Increment + * <9> 1 Terminate Buffer on RxBound + * <8> 0 Bus Width = 16bits + * <7..0> ? status Bits (write as 0s) + * + * 1111 0010 0000 0000 = 0xf200 + */ + + usc_OutDmaReg( info, RDMR, 0xf200 ); + + + /* Transmit DMA mode Register (TDMR) + * + * <15..14> 11 DMA mode = Linked List Buffer mode + * <13> 1 TCBinA/L = fetch Tx Control Block from List entry + * <12> 1 Clear count of List Entry after fetching + * <11..10> 00 Address mode = Increment + * <9> 1 Terminate Buffer on end of frame + * <8> 0 Bus Width = 16bits + * <7..0> ? status Bits (Read Only so write as 0) + * + * 1111 0010 0000 0000 = 0xf200 + */ + + usc_OutDmaReg( info, TDMR, 0xf200 ); + + + /* DMA Interrupt Control Register (DICR) + * + * <15> 1 DMA Interrupt Enable + * <14> 0 1 = Disable IEO from USC + * <13> 0 1 = Don't provide vector during IntAck + * <12> 1 1 = Include status in Vector + * <10..2> 0 reserved, Must be 0s + * <1> 0 1 = Rx DMA Interrupt Enabled + * <0> 0 1 = Tx DMA Interrupt Enabled + * + * 1001 0000 0000 0000 = 0x9000 + */ + + usc_OutDmaReg( info, DICR, 0x9000 ); + + usc_InDmaReg( info, RDMR ); /* clear pending receive DMA IRQ bits */ + usc_InDmaReg( info, TDMR ); /* clear pending transmit DMA IRQ bits */ + usc_OutDmaReg( info, CDIR, 0x0303 ); /* clear IUS and Pending for Tx and Rx */ + + /* Channel Control Register (CCR) + * + * <15..14> 10 Use 32-bit Tx Control Blocks (TCBs) + * <13> 0 Trigger Tx on SW Command Disabled + * <12> 0 Flag Preamble Disabled + * <11..10> 00 Preamble Length + * <9..8> 00 Preamble Pattern + * <7..6> 10 Use 32-bit Rx status Blocks (RSBs) + * <5> 0 Trigger Rx on SW Command Disabled + * <4..0> 0 reserved + * + * 1000 0000 1000 0000 = 0x8080 + */ + + RegValue = 0x8080; + + switch ( info->params.preamble_length ) { + case HDLC_PREAMBLE_LENGTH_16BITS: RegValue |= BIT10; break; + case HDLC_PREAMBLE_LENGTH_32BITS: RegValue |= BIT11; break; + case HDLC_PREAMBLE_LENGTH_64BITS: RegValue |= BIT11 + BIT10; break; + } + + switch ( info->params.preamble ) { + case HDLC_PREAMBLE_PATTERN_FLAGS: RegValue |= BIT8 + BIT12; break; + case HDLC_PREAMBLE_PATTERN_ONES: RegValue |= BIT8; break; + case HDLC_PREAMBLE_PATTERN_10: RegValue |= BIT9; break; + case HDLC_PREAMBLE_PATTERN_01: RegValue |= BIT9 + BIT8; break; + } + + usc_OutReg( info, CCR, RegValue ); + + + /* + * Burst/Dwell Control Register + * + * <15..8> 0x20 Maximum number of transfers per bus grant + * <7..0> 0x00 Maximum number of clock cycles per bus grant + */ + + if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { + /* don't limit bus occupancy on PCI adapter */ + usc_OutDmaReg( info, BDCR, 0x0000 ); + } + else + usc_OutDmaReg( info, BDCR, 0x2000 ); + + usc_stop_transmitter(info); + usc_stop_receiver(info); + +} /* end of usc_set_sdlc_mode() */ + +/* usc_enable_loopback() + * + * Set the 16C32 for internal loopback mode. + * The TxCLK and RxCLK signals are generated from the BRG0 and + * the TxD is looped back to the RxD internally. + * + * Arguments: info pointer to device instance data + * enable 1 = enable loopback, 0 = disable + * Return Value: None + */ +static void usc_enable_loopback(struct mgsl_struct *info, int enable) +{ + if (enable) { + /* blank external TXD output */ + usc_OutReg(info,IOCR,usc_InReg(info,IOCR) | (BIT7+BIT6)); + + /* Clock mode Control Register (CMCR) + * + * <15..14> 00 counter 1 Disabled + * <13..12> 00 counter 0 Disabled + * <11..10> 11 BRG1 Input is TxC Pin + * <9..8> 11 BRG0 Input is TxC Pin + * <7..6> 01 DPLL Input is BRG1 Output + * <5..3> 100 TxCLK comes from BRG0 + * <2..0> 100 RxCLK comes from BRG0 + * + * 0000 1111 0110 0100 = 0x0f64 + */ + + usc_OutReg( info, CMCR, 0x0f64 ); + + /* Write 16-bit Time Constant for BRG0 */ + /* use clock speed if available, otherwise use 8 for diagnostics */ + if (info->params.clock_speed) { + if (info->bus_type == MGSL_BUS_TYPE_PCI) + usc_OutReg(info, TC0R, (u16)((11059200/info->params.clock_speed)-1)); + else + usc_OutReg(info, TC0R, (u16)((14745600/info->params.clock_speed)-1)); + } else + usc_OutReg(info, TC0R, (u16)8); + + /* Hardware Configuration Register (HCR) Clear Bit 1, BRG0 + mode = Continuous Set Bit 0 to enable BRG0. */ + usc_OutReg( info, HCR, (u16)((usc_InReg( info, HCR ) & ~BIT1) | BIT0) ); + + /* Input/Output Control Reg, <2..0> = 100, Drive RxC pin with BRG0 */ + usc_OutReg(info, IOCR, (u16)((usc_InReg(info, IOCR) & 0xfff8) | 0x0004)); + + /* set Internal Data loopback mode */ + info->loopback_bits = 0x300; + outw( 0x0300, info->io_base + CCAR ); + } else { + /* enable external TXD output */ + usc_OutReg(info,IOCR,usc_InReg(info,IOCR) & ~(BIT7+BIT6)); + + /* clear Internal Data loopback mode */ + info->loopback_bits = 0; + outw( 0,info->io_base + CCAR ); + } + +} /* end of usc_enable_loopback() */ + +/* usc_enable_aux_clock() + * + * Enabled the AUX clock output at the specified frequency. + * + * Arguments: + * + * info pointer to device extension + * data_rate data rate of clock in bits per second + * A data rate of 0 disables the AUX clock. + * + * Return Value: None + */ +static void usc_enable_aux_clock( struct mgsl_struct *info, u32 data_rate ) +{ + u32 XtalSpeed; + u16 Tc; + + if ( data_rate ) { + if ( info->bus_type == MGSL_BUS_TYPE_PCI ) + XtalSpeed = 11059200; + else + XtalSpeed = 14745600; + + + /* Tc = (Xtal/Speed) - 1 */ + /* If twice the remainder of (Xtal/Speed) is greater than Speed */ + /* then rounding up gives a more precise time constant. Instead */ + /* of rounding up and then subtracting 1 we just don't subtract */ + /* the one in this case. */ + + + Tc = (u16)(XtalSpeed/data_rate); + if ( !(((XtalSpeed % data_rate) * 2) / data_rate) ) + Tc--; + + /* Write 16-bit Time Constant for BRG0 */ + usc_OutReg( info, TC0R, Tc ); + + /* + * Hardware Configuration Register (HCR) + * Clear Bit 1, BRG0 mode = Continuous + * Set Bit 0 to enable BRG0. + */ + + usc_OutReg( info, HCR, (u16)((usc_InReg( info, HCR ) & ~BIT1) | BIT0) ); + + /* Input/Output Control Reg, <2..0> = 100, Drive RxC pin with BRG0 */ + usc_OutReg( info, IOCR, (u16)((usc_InReg(info, IOCR) & 0xfff8) | 0x0004) ); + } else { + /* data rate == 0 so turn off BRG0 */ + usc_OutReg( info, HCR, (u16)(usc_InReg( info, HCR ) & ~BIT0) ); + } + +} /* end of usc_enable_aux_clock() */ + +/* + * + * usc_process_rxoverrun_sync() + * + * This function processes a receive overrun by resetting the + * receive DMA buffers and issuing a Purge Rx FIFO command + * to allow the receiver to continue receiving. + * + * Arguments: + * + * info pointer to device extension + * + * Return Value: None + */ +static void usc_process_rxoverrun_sync( struct mgsl_struct *info ) +{ + int start_index; + int end_index; + int frame_start_index; + bool start_of_frame_found = false; + bool end_of_frame_found = false; + bool reprogram_dma = false; + + DMABUFFERENTRY *buffer_list = info->rx_buffer_list; + u32 phys_addr; + + usc_DmaCmd( info, DmaCmd_PauseRxChannel ); + usc_RCmd( info, RCmd_EnterHuntmode ); + usc_RTCmd( info, RTCmd_PurgeRxFifo ); + + /* CurrentRxBuffer points to the 1st buffer of the next */ + /* possibly available receive frame. */ + + frame_start_index = start_index = end_index = info->current_rx_buffer; + + /* Search for an unfinished string of buffers. This means */ + /* that a receive frame started (at least one buffer with */ + /* count set to zero) but there is no terminiting buffer */ + /* (status set to non-zero). */ + + while( !buffer_list[end_index].count ) + { + /* Count field has been reset to zero by 16C32. */ + /* This buffer is currently in use. */ + + if ( !start_of_frame_found ) + { + start_of_frame_found = true; + frame_start_index = end_index; + end_of_frame_found = false; + } + + if ( buffer_list[end_index].status ) + { + /* Status field has been set by 16C32. */ + /* This is the last buffer of a received frame. */ + + /* We want to leave the buffers for this frame intact. */ + /* Move on to next possible frame. */ + + start_of_frame_found = false; + end_of_frame_found = true; + } + + /* advance to next buffer entry in linked list */ + end_index++; + if ( end_index == info->rx_buffer_count ) + end_index = 0; + + if ( start_index == end_index ) + { + /* The entire list has been searched with all Counts == 0 and */ + /* all Status == 0. The receive buffers are */ + /* completely screwed, reset all receive buffers! */ + mgsl_reset_rx_dma_buffers( info ); + frame_start_index = 0; + start_of_frame_found = false; + reprogram_dma = true; + break; + } + } + + if ( start_of_frame_found && !end_of_frame_found ) + { + /* There is an unfinished string of receive DMA buffers */ + /* as a result of the receiver overrun. */ + + /* Reset the buffers for the unfinished frame */ + /* and reprogram the receive DMA controller to start */ + /* at the 1st buffer of unfinished frame. */ + + start_index = frame_start_index; + + do + { + *((unsigned long *)&(info->rx_buffer_list[start_index++].count)) = DMABUFFERSIZE; + + /* Adjust index for wrap around. */ + if ( start_index == info->rx_buffer_count ) + start_index = 0; + + } while( start_index != end_index ); + + reprogram_dma = true; + } + + if ( reprogram_dma ) + { + usc_UnlatchRxstatusBits(info,RXSTATUS_ALL); + usc_ClearIrqPendingBits(info, RECEIVE_DATA|RECEIVE_STATUS); + usc_UnlatchRxstatusBits(info, RECEIVE_DATA|RECEIVE_STATUS); + + usc_EnableReceiver(info,DISABLE_UNCONDITIONAL); + + /* This empties the receive FIFO and loads the RCC with RCLR */ + usc_OutReg( info, CCSR, (u16)(usc_InReg(info,CCSR) | BIT13) ); + + /* program 16C32 with physical address of 1st DMA buffer entry */ + phys_addr = info->rx_buffer_list[frame_start_index].phys_entry; + usc_OutDmaReg( info, NRARL, (u16)phys_addr ); + usc_OutDmaReg( info, NRARU, (u16)(phys_addr >> 16) ); + + usc_UnlatchRxstatusBits( info, RXSTATUS_ALL ); + usc_ClearIrqPendingBits( info, RECEIVE_DATA + RECEIVE_STATUS ); + usc_EnableInterrupts( info, RECEIVE_STATUS ); + + /* 1. Arm End of Buffer (EOB) Receive DMA Interrupt (BIT2 of RDIAR) */ + /* 2. Enable Receive DMA Interrupts (BIT1 of DICR) */ + + usc_OutDmaReg( info, RDIAR, BIT3 + BIT2 ); + usc_OutDmaReg( info, DICR, (u16)(usc_InDmaReg(info,DICR) | BIT1) ); + usc_DmaCmd( info, DmaCmd_InitRxChannel ); + if ( info->params.flags & HDLC_FLAG_AUTO_DCD ) + usc_EnableReceiver(info,ENABLE_AUTO_DCD); + else + usc_EnableReceiver(info,ENABLE_UNCONDITIONAL); + } + else + { + /* This empties the receive FIFO and loads the RCC with RCLR */ + usc_OutReg( info, CCSR, (u16)(usc_InReg(info,CCSR) | BIT13) ); + usc_RTCmd( info, RTCmd_PurgeRxFifo ); + } + +} /* end of usc_process_rxoverrun_sync() */ + +/* usc_stop_receiver() + * + * Disable USC receiver + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void usc_stop_receiver( struct mgsl_struct *info ) +{ + if (debug_level >= DEBUG_LEVEL_ISR) + printk("%s(%d):usc_stop_receiver(%s)\n", + __FILE__,__LINE__, info->device_name ); + + /* Disable receive DMA channel. */ + /* This also disables receive DMA channel interrupts */ + usc_DmaCmd( info, DmaCmd_ResetRxChannel ); + + usc_UnlatchRxstatusBits( info, RXSTATUS_ALL ); + usc_ClearIrqPendingBits( info, RECEIVE_DATA + RECEIVE_STATUS ); + usc_DisableInterrupts( info, RECEIVE_DATA + RECEIVE_STATUS ); + + usc_EnableReceiver(info,DISABLE_UNCONDITIONAL); + + /* This empties the receive FIFO and loads the RCC with RCLR */ + usc_OutReg( info, CCSR, (u16)(usc_InReg(info,CCSR) | BIT13) ); + usc_RTCmd( info, RTCmd_PurgeRxFifo ); + + info->rx_enabled = false; + info->rx_overflow = false; + info->rx_rcc_underrun = false; + +} /* end of stop_receiver() */ + +/* usc_start_receiver() + * + * Enable the USC receiver + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void usc_start_receiver( struct mgsl_struct *info ) +{ + u32 phys_addr; + + if (debug_level >= DEBUG_LEVEL_ISR) + printk("%s(%d):usc_start_receiver(%s)\n", + __FILE__,__LINE__, info->device_name ); + + mgsl_reset_rx_dma_buffers( info ); + usc_stop_receiver( info ); + + usc_OutReg( info, CCSR, (u16)(usc_InReg(info,CCSR) | BIT13) ); + usc_RTCmd( info, RTCmd_PurgeRxFifo ); + + if ( info->params.mode == MGSL_MODE_HDLC || + info->params.mode == MGSL_MODE_RAW ) { + /* DMA mode Transfers */ + /* Program the DMA controller. */ + /* Enable the DMA controller end of buffer interrupt. */ + + /* program 16C32 with physical address of 1st DMA buffer entry */ + phys_addr = info->rx_buffer_list[0].phys_entry; + usc_OutDmaReg( info, NRARL, (u16)phys_addr ); + usc_OutDmaReg( info, NRARU, (u16)(phys_addr >> 16) ); + + usc_UnlatchRxstatusBits( info, RXSTATUS_ALL ); + usc_ClearIrqPendingBits( info, RECEIVE_DATA + RECEIVE_STATUS ); + usc_EnableInterrupts( info, RECEIVE_STATUS ); + + /* 1. Arm End of Buffer (EOB) Receive DMA Interrupt (BIT2 of RDIAR) */ + /* 2. Enable Receive DMA Interrupts (BIT1 of DICR) */ + + usc_OutDmaReg( info, RDIAR, BIT3 + BIT2 ); + usc_OutDmaReg( info, DICR, (u16)(usc_InDmaReg(info,DICR) | BIT1) ); + usc_DmaCmd( info, DmaCmd_InitRxChannel ); + if ( info->params.flags & HDLC_FLAG_AUTO_DCD ) + usc_EnableReceiver(info,ENABLE_AUTO_DCD); + else + usc_EnableReceiver(info,ENABLE_UNCONDITIONAL); + } else { + usc_UnlatchRxstatusBits(info, RXSTATUS_ALL); + usc_ClearIrqPendingBits(info, RECEIVE_DATA + RECEIVE_STATUS); + usc_EnableInterrupts(info, RECEIVE_DATA); + + usc_RTCmd( info, RTCmd_PurgeRxFifo ); + usc_RCmd( info, RCmd_EnterHuntmode ); + + usc_EnableReceiver(info,ENABLE_UNCONDITIONAL); + } + + usc_OutReg( info, CCSR, 0x1020 ); + + info->rx_enabled = true; + +} /* end of usc_start_receiver() */ + +/* usc_start_transmitter() + * + * Enable the USC transmitter and send a transmit frame if + * one is loaded in the DMA buffers. + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void usc_start_transmitter( struct mgsl_struct *info ) +{ + u32 phys_addr; + unsigned int FrameSize; + + if (debug_level >= DEBUG_LEVEL_ISR) + printk("%s(%d):usc_start_transmitter(%s)\n", + __FILE__,__LINE__, info->device_name ); + + if ( info->xmit_cnt ) { + + /* If auto RTS enabled and RTS is inactive, then assert */ + /* RTS and set a flag indicating that the driver should */ + /* negate RTS when the transmission completes. */ + + info->drop_rts_on_tx_done = false; + + if ( info->params.flags & HDLC_FLAG_AUTO_RTS ) { + usc_get_serial_signals( info ); + if ( !(info->serial_signals & SerialSignal_RTS) ) { + info->serial_signals |= SerialSignal_RTS; + usc_set_serial_signals( info ); + info->drop_rts_on_tx_done = true; + } + } + + + if ( info->params.mode == MGSL_MODE_ASYNC ) { + if ( !info->tx_active ) { + usc_UnlatchTxstatusBits(info, TXSTATUS_ALL); + usc_ClearIrqPendingBits(info, TRANSMIT_STATUS + TRANSMIT_DATA); + usc_EnableInterrupts(info, TRANSMIT_DATA); + usc_load_txfifo(info); + } + } else { + /* Disable transmit DMA controller while programming. */ + usc_DmaCmd( info, DmaCmd_ResetTxChannel ); + + /* Transmit DMA buffer is loaded, so program USC */ + /* to send the frame contained in the buffers. */ + + FrameSize = info->tx_buffer_list[info->start_tx_dma_buffer].rcc; + + /* if operating in Raw sync mode, reset the rcc component + * of the tx dma buffer entry, otherwise, the serial controller + * will send a closing sync char after this count. + */ + if ( info->params.mode == MGSL_MODE_RAW ) + info->tx_buffer_list[info->start_tx_dma_buffer].rcc = 0; + + /* Program the Transmit Character Length Register (TCLR) */ + /* and clear FIFO (TCC is loaded with TCLR on FIFO clear) */ + usc_OutReg( info, TCLR, (u16)FrameSize ); + + usc_RTCmd( info, RTCmd_PurgeTxFifo ); + + /* Program the address of the 1st DMA Buffer Entry in linked list */ + phys_addr = info->tx_buffer_list[info->start_tx_dma_buffer].phys_entry; + usc_OutDmaReg( info, NTARL, (u16)phys_addr ); + usc_OutDmaReg( info, NTARU, (u16)(phys_addr >> 16) ); + + usc_UnlatchTxstatusBits( info, TXSTATUS_ALL ); + usc_ClearIrqPendingBits( info, TRANSMIT_STATUS ); + usc_EnableInterrupts( info, TRANSMIT_STATUS ); + + if ( info->params.mode == MGSL_MODE_RAW && + info->num_tx_dma_buffers > 1 ) { + /* When running external sync mode, attempt to 'stream' transmit */ + /* by filling tx dma buffers as they become available. To do this */ + /* we need to enable Tx DMA EOB Status interrupts : */ + /* */ + /* 1. Arm End of Buffer (EOB) Transmit DMA Interrupt (BIT2 of TDIAR) */ + /* 2. Enable Transmit DMA Interrupts (BIT0 of DICR) */ + + usc_OutDmaReg( info, TDIAR, BIT2|BIT3 ); + usc_OutDmaReg( info, DICR, (u16)(usc_InDmaReg(info,DICR) | BIT0) ); + } + + /* Initialize Transmit DMA Channel */ + usc_DmaCmd( info, DmaCmd_InitTxChannel ); + + usc_TCmd( info, TCmd_SendFrame ); + + mod_timer(&info->tx_timer, jiffies + + msecs_to_jiffies(5000)); + } + info->tx_active = true; + } + + if ( !info->tx_enabled ) { + info->tx_enabled = true; + if ( info->params.flags & HDLC_FLAG_AUTO_CTS ) + usc_EnableTransmitter(info,ENABLE_AUTO_CTS); + else + usc_EnableTransmitter(info,ENABLE_UNCONDITIONAL); + } + +} /* end of usc_start_transmitter() */ + +/* usc_stop_transmitter() + * + * Stops the transmitter and DMA + * + * Arguments: info pointer to device isntance data + * Return Value: None + */ +static void usc_stop_transmitter( struct mgsl_struct *info ) +{ + if (debug_level >= DEBUG_LEVEL_ISR) + printk("%s(%d):usc_stop_transmitter(%s)\n", + __FILE__,__LINE__, info->device_name ); + + del_timer(&info->tx_timer); + + usc_UnlatchTxstatusBits( info, TXSTATUS_ALL ); + usc_ClearIrqPendingBits( info, TRANSMIT_STATUS + TRANSMIT_DATA ); + usc_DisableInterrupts( info, TRANSMIT_STATUS + TRANSMIT_DATA ); + + usc_EnableTransmitter(info,DISABLE_UNCONDITIONAL); + usc_DmaCmd( info, DmaCmd_ResetTxChannel ); + usc_RTCmd( info, RTCmd_PurgeTxFifo ); + + info->tx_enabled = false; + info->tx_active = false; + +} /* end of usc_stop_transmitter() */ + +/* usc_load_txfifo() + * + * Fill the transmit FIFO until the FIFO is full or + * there is no more data to load. + * + * Arguments: info pointer to device extension (instance data) + * Return Value: None + */ +static void usc_load_txfifo( struct mgsl_struct *info ) +{ + int Fifocount; + u8 TwoBytes[2]; + + if ( !info->xmit_cnt && !info->x_char ) + return; + + /* Select transmit FIFO status readback in TICR */ + usc_TCmd( info, TCmd_SelectTicrTxFifostatus ); + + /* load the Transmit FIFO until FIFOs full or all data sent */ + + while( (Fifocount = usc_InReg(info, TICR) >> 8) && info->xmit_cnt ) { + /* there is more space in the transmit FIFO and */ + /* there is more data in transmit buffer */ + + if ( (info->xmit_cnt > 1) && (Fifocount > 1) && !info->x_char ) { + /* write a 16-bit word from transmit buffer to 16C32 */ + + TwoBytes[0] = info->xmit_buf[info->xmit_tail++]; + info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); + TwoBytes[1] = info->xmit_buf[info->xmit_tail++]; + info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); + + outw( *((u16 *)TwoBytes), info->io_base + DATAREG); + + info->xmit_cnt -= 2; + info->icount.tx += 2; + } else { + /* only 1 byte left to transmit or 1 FIFO slot left */ + + outw( (inw( info->io_base + CCAR) & 0x0780) | (TDR+LSBONLY), + info->io_base + CCAR ); + + if (info->x_char) { + /* transmit pending high priority char */ + outw( info->x_char,info->io_base + CCAR ); + info->x_char = 0; + } else { + outw( info->xmit_buf[info->xmit_tail++],info->io_base + CCAR ); + info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); + info->xmit_cnt--; + } + info->icount.tx++; + } + } + +} /* end of usc_load_txfifo() */ + +/* usc_reset() + * + * Reset the adapter to a known state and prepare it for further use. + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void usc_reset( struct mgsl_struct *info ) +{ + if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { + int i; + u32 readval; + + /* Set BIT30 of Misc Control Register */ + /* (Local Control Register 0x50) to force reset of USC. */ + + volatile u32 *MiscCtrl = (u32 *)(info->lcr_base + 0x50); + u32 *LCR0BRDR = (u32 *)(info->lcr_base + 0x28); + + info->misc_ctrl_value |= BIT30; + *MiscCtrl = info->misc_ctrl_value; + + /* + * Force at least 170ns delay before clearing + * reset bit. Each read from LCR takes at least + * 30ns so 10 times for 300ns to be safe. + */ + for(i=0;i<10;i++) + readval = *MiscCtrl; + + info->misc_ctrl_value &= ~BIT30; + *MiscCtrl = info->misc_ctrl_value; + + *LCR0BRDR = BUS_DESCRIPTOR( + 1, // Write Strobe Hold (0-3) + 2, // Write Strobe Delay (0-3) + 2, // Read Strobe Delay (0-3) + 0, // NWDD (Write data-data) (0-3) + 4, // NWAD (Write Addr-data) (0-31) + 0, // NXDA (Read/Write Data-Addr) (0-3) + 0, // NRDD (Read Data-Data) (0-3) + 5 // NRAD (Read Addr-Data) (0-31) + ); + } else { + /* do HW reset */ + outb( 0,info->io_base + 8 ); + } + + info->mbre_bit = 0; + info->loopback_bits = 0; + info->usc_idle_mode = 0; + + /* + * Program the Bus Configuration Register (BCR) + * + * <15> 0 Don't use separate address + * <14..6> 0 reserved + * <5..4> 00 IAckmode = Default, don't care + * <3> 1 Bus Request Totem Pole output + * <2> 1 Use 16 Bit data bus + * <1> 0 IRQ Totem Pole output + * <0> 0 Don't Shift Right Addr + * + * 0000 0000 0000 1100 = 0x000c + * + * By writing to io_base + SDPIN the Wait/Ack pin is + * programmed to work as a Wait pin. + */ + + outw( 0x000c,info->io_base + SDPIN ); + + + outw( 0,info->io_base ); + outw( 0,info->io_base + CCAR ); + + /* select little endian byte ordering */ + usc_RTCmd( info, RTCmd_SelectLittleEndian ); + + + /* Port Control Register (PCR) + * + * <15..14> 11 Port 7 is Output (~DMAEN, Bit 14 : 0 = Enabled) + * <13..12> 11 Port 6 is Output (~INTEN, Bit 12 : 0 = Enabled) + * <11..10> 00 Port 5 is Input (No Connect, Don't Care) + * <9..8> 00 Port 4 is Input (No Connect, Don't Care) + * <7..6> 11 Port 3 is Output (~RTS, Bit 6 : 0 = Enabled ) + * <5..4> 11 Port 2 is Output (~DTR, Bit 4 : 0 = Enabled ) + * <3..2> 01 Port 1 is Input (Dedicated RxC) + * <1..0> 01 Port 0 is Input (Dedicated TxC) + * + * 1111 0000 1111 0101 = 0xf0f5 + */ + + usc_OutReg( info, PCR, 0xf0f5 ); + + + /* + * Input/Output Control Register + * + * <15..14> 00 CTS is active low input + * <13..12> 00 DCD is active low input + * <11..10> 00 TxREQ pin is input (DSR) + * <9..8> 00 RxREQ pin is input (RI) + * <7..6> 00 TxD is output (Transmit Data) + * <5..3> 000 TxC Pin in Input (14.7456MHz Clock) + * <2..0> 100 RxC is Output (drive with BRG0) + * + * 0000 0000 0000 0100 = 0x0004 + */ + + usc_OutReg( info, IOCR, 0x0004 ); + +} /* end of usc_reset() */ + +/* usc_set_async_mode() + * + * Program adapter for asynchronous communications. + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void usc_set_async_mode( struct mgsl_struct *info ) +{ + u16 RegValue; + + /* disable interrupts while programming USC */ + usc_DisableMasterIrqBit( info ); + + outw( 0, info->io_base ); /* clear Master Bus Enable (DCAR) */ + usc_DmaCmd( info, DmaCmd_ResetAllChannels ); /* disable both DMA channels */ + + usc_loopback_frame( info ); + + /* Channel mode Register (CMR) + * + * <15..14> 00 Tx Sub modes, 00 = 1 Stop Bit + * <13..12> 00 00 = 16X Clock + * <11..8> 0000 Transmitter mode = Asynchronous + * <7..6> 00 reserved? + * <5..4> 00 Rx Sub modes, 00 = 16X Clock + * <3..0> 0000 Receiver mode = Asynchronous + * + * 0000 0000 0000 0000 = 0x0 + */ + + RegValue = 0; + if ( info->params.stop_bits != 1 ) + RegValue |= BIT14; + usc_OutReg( info, CMR, RegValue ); + + + /* Receiver mode Register (RMR) + * + * <15..13> 000 encoding = None + * <12..08> 00000 reserved (Sync Only) + * <7..6> 00 Even parity + * <5> 0 parity disabled + * <4..2> 000 Receive Char Length = 8 bits + * <1..0> 00 Disable Receiver + * + * 0000 0000 0000 0000 = 0x0 + */ + + RegValue = 0; + + if ( info->params.data_bits != 8 ) + RegValue |= BIT4+BIT3+BIT2; + + if ( info->params.parity != ASYNC_PARITY_NONE ) { + RegValue |= BIT5; + if ( info->params.parity != ASYNC_PARITY_ODD ) + RegValue |= BIT6; + } + + usc_OutReg( info, RMR, RegValue ); + + + /* Set IRQ trigger level */ + + usc_RCmd( info, RCmd_SelectRicrIntLevel ); + + + /* Receive Interrupt Control Register (RICR) + * + * <15..8> ? RxFIFO IRQ Request Level + * + * Note: For async mode the receive FIFO level must be set + * to 0 to avoid the situation where the FIFO contains fewer bytes + * than the trigger level and no more data is expected. + * + * <7> 0 Exited Hunt IA (Interrupt Arm) + * <6> 0 Idle Received IA + * <5> 0 Break/Abort IA + * <4> 0 Rx Bound IA + * <3> 0 Queued status reflects oldest byte in FIFO + * <2> 0 Abort/PE IA + * <1> 0 Rx Overrun IA + * <0> 0 Select TC0 value for readback + * + * 0000 0000 0100 0000 = 0x0000 + (FIFOLEVEL in MSB) + */ + + usc_OutReg( info, RICR, 0x0000 ); + + usc_UnlatchRxstatusBits( info, RXSTATUS_ALL ); + usc_ClearIrqPendingBits( info, RECEIVE_STATUS ); + + + /* Transmit mode Register (TMR) + * + * <15..13> 000 encoding = None + * <12..08> 00000 reserved (Sync Only) + * <7..6> 00 Transmit parity Even + * <5> 0 Transmit parity Disabled + * <4..2> 000 Tx Char Length = 8 bits + * <1..0> 00 Disable Transmitter + * + * 0000 0000 0000 0000 = 0x0 + */ + + RegValue = 0; + + if ( info->params.data_bits != 8 ) + RegValue |= BIT4+BIT3+BIT2; + + if ( info->params.parity != ASYNC_PARITY_NONE ) { + RegValue |= BIT5; + if ( info->params.parity != ASYNC_PARITY_ODD ) + RegValue |= BIT6; + } + + usc_OutReg( info, TMR, RegValue ); + + usc_set_txidle( info ); + + + /* Set IRQ trigger level */ + + usc_TCmd( info, TCmd_SelectTicrIntLevel ); + + + /* Transmit Interrupt Control Register (TICR) + * + * <15..8> ? Transmit FIFO IRQ Level + * <7> 0 Present IA (Interrupt Arm) + * <6> 1 Idle Sent IA + * <5> 0 Abort Sent IA + * <4> 0 EOF/EOM Sent IA + * <3> 0 CRC Sent IA + * <2> 0 1 = Wait for SW Trigger to Start Frame + * <1> 0 Tx Underrun IA + * <0> 0 TC0 constant on read back + * + * 0000 0000 0100 0000 = 0x0040 + */ + + usc_OutReg( info, TICR, 0x1f40 ); + + usc_UnlatchTxstatusBits( info, TXSTATUS_ALL ); + usc_ClearIrqPendingBits( info, TRANSMIT_STATUS ); + + usc_enable_async_clock( info, info->params.data_rate ); + + + /* Channel Control/status Register (CCSR) + * + * <15> X RCC FIFO Overflow status (RO) + * <14> X RCC FIFO Not Empty status (RO) + * <13> 0 1 = Clear RCC FIFO (WO) + * <12> X DPLL in Sync status (RO) + * <11> X DPLL 2 Missed Clocks status (RO) + * <10> X DPLL 1 Missed Clock status (RO) + * <9..8> 00 DPLL Resync on rising and falling edges (RW) + * <7> X SDLC Loop On status (RO) + * <6> X SDLC Loop Send status (RO) + * <5> 1 Bypass counters for TxClk and RxClk (RW) + * <4..2> 000 Last Char of SDLC frame has 8 bits (RW) + * <1..0> 00 reserved + * + * 0000 0000 0010 0000 = 0x0020 + */ + + usc_OutReg( info, CCSR, 0x0020 ); + + usc_DisableInterrupts( info, TRANSMIT_STATUS + TRANSMIT_DATA + + RECEIVE_DATA + RECEIVE_STATUS ); + + usc_ClearIrqPendingBits( info, TRANSMIT_STATUS + TRANSMIT_DATA + + RECEIVE_DATA + RECEIVE_STATUS ); + + usc_EnableMasterIrqBit( info ); + + if (info->bus_type == MGSL_BUS_TYPE_ISA) { + /* Enable INTEN (Port 6, Bit12) */ + /* This connects the IRQ request signal to the ISA bus */ + usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) & ~BIT12)); + } + + if (info->params.loopback) { + info->loopback_bits = 0x300; + outw(0x0300, info->io_base + CCAR); + } + +} /* end of usc_set_async_mode() */ + +/* usc_loopback_frame() + * + * Loop back a small (2 byte) dummy SDLC frame. + * Interrupts and DMA are NOT used. The purpose of this is to + * clear any 'stale' status info left over from running in async mode. + * + * The 16C32 shows the strange behaviour of marking the 1st + * received SDLC frame with a CRC error even when there is no + * CRC error. To get around this a small dummy from of 2 bytes + * is looped back when switching from async to sync mode. + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void usc_loopback_frame( struct mgsl_struct *info ) +{ + int i; + unsigned long oldmode = info->params.mode; + + info->params.mode = MGSL_MODE_HDLC; + + usc_DisableMasterIrqBit( info ); + + usc_set_sdlc_mode( info ); + usc_enable_loopback( info, 1 ); + + /* Write 16-bit Time Constant for BRG0 */ + usc_OutReg( info, TC0R, 0 ); + + /* Channel Control Register (CCR) + * + * <15..14> 00 Don't use 32-bit Tx Control Blocks (TCBs) + * <13> 0 Trigger Tx on SW Command Disabled + * <12> 0 Flag Preamble Disabled + * <11..10> 00 Preamble Length = 8-Bits + * <9..8> 01 Preamble Pattern = flags + * <7..6> 10 Don't use 32-bit Rx status Blocks (RSBs) + * <5> 0 Trigger Rx on SW Command Disabled + * <4..0> 0 reserved + * + * 0000 0001 0000 0000 = 0x0100 + */ + + usc_OutReg( info, CCR, 0x0100 ); + + /* SETUP RECEIVER */ + usc_RTCmd( info, RTCmd_PurgeRxFifo ); + usc_EnableReceiver(info,ENABLE_UNCONDITIONAL); + + /* SETUP TRANSMITTER */ + /* Program the Transmit Character Length Register (TCLR) */ + /* and clear FIFO (TCC is loaded with TCLR on FIFO clear) */ + usc_OutReg( info, TCLR, 2 ); + usc_RTCmd( info, RTCmd_PurgeTxFifo ); + + /* unlatch Tx status bits, and start transmit channel. */ + usc_UnlatchTxstatusBits(info,TXSTATUS_ALL); + outw(0,info->io_base + DATAREG); + + /* ENABLE TRANSMITTER */ + usc_TCmd( info, TCmd_SendFrame ); + usc_EnableTransmitter(info,ENABLE_UNCONDITIONAL); + + /* WAIT FOR RECEIVE COMPLETE */ + for (i=0 ; i<1000 ; i++) + if (usc_InReg( info, RCSR ) & (BIT8 + BIT4 + BIT3 + BIT1)) + break; + + /* clear Internal Data loopback mode */ + usc_enable_loopback(info, 0); + + usc_EnableMasterIrqBit(info); + + info->params.mode = oldmode; + +} /* end of usc_loopback_frame() */ + +/* usc_set_sync_mode() Programs the USC for SDLC communications. + * + * Arguments: info pointer to adapter info structure + * Return Value: None + */ +static void usc_set_sync_mode( struct mgsl_struct *info ) +{ + usc_loopback_frame( info ); + usc_set_sdlc_mode( info ); + + if (info->bus_type == MGSL_BUS_TYPE_ISA) { + /* Enable INTEN (Port 6, Bit12) */ + /* This connects the IRQ request signal to the ISA bus */ + usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) & ~BIT12)); + } + + usc_enable_aux_clock(info, info->params.clock_speed); + + if (info->params.loopback) + usc_enable_loopback(info,1); + +} /* end of mgsl_set_sync_mode() */ + +/* usc_set_txidle() Set the HDLC idle mode for the transmitter. + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void usc_set_txidle( struct mgsl_struct *info ) +{ + u16 usc_idle_mode = IDLEMODE_FLAGS; + + /* Map API idle mode to USC register bits */ + + switch( info->idle_mode ){ + case HDLC_TXIDLE_FLAGS: usc_idle_mode = IDLEMODE_FLAGS; break; + case HDLC_TXIDLE_ALT_ZEROS_ONES: usc_idle_mode = IDLEMODE_ALT_ONE_ZERO; break; + case HDLC_TXIDLE_ZEROS: usc_idle_mode = IDLEMODE_ZERO; break; + case HDLC_TXIDLE_ONES: usc_idle_mode = IDLEMODE_ONE; break; + case HDLC_TXIDLE_ALT_MARK_SPACE: usc_idle_mode = IDLEMODE_ALT_MARK_SPACE; break; + case HDLC_TXIDLE_SPACE: usc_idle_mode = IDLEMODE_SPACE; break; + case HDLC_TXIDLE_MARK: usc_idle_mode = IDLEMODE_MARK; break; + } + + info->usc_idle_mode = usc_idle_mode; + //usc_OutReg(info, TCSR, usc_idle_mode); + info->tcsr_value &= ~IDLEMODE_MASK; /* clear idle mode bits */ + info->tcsr_value += usc_idle_mode; + usc_OutReg(info, TCSR, info->tcsr_value); + + /* + * if SyncLink WAN adapter is running in external sync mode, the + * transmitter has been set to Monosync in order to try to mimic + * a true raw outbound bit stream. Monosync still sends an open/close + * sync char at the start/end of a frame. Try to match those sync + * patterns to the idle mode set here + */ + if ( info->params.mode == MGSL_MODE_RAW ) { + unsigned char syncpat = 0; + switch( info->idle_mode ) { + case HDLC_TXIDLE_FLAGS: + syncpat = 0x7e; + break; + case HDLC_TXIDLE_ALT_ZEROS_ONES: + syncpat = 0x55; + break; + case HDLC_TXIDLE_ZEROS: + case HDLC_TXIDLE_SPACE: + syncpat = 0x00; + break; + case HDLC_TXIDLE_ONES: + case HDLC_TXIDLE_MARK: + syncpat = 0xff; + break; + case HDLC_TXIDLE_ALT_MARK_SPACE: + syncpat = 0xaa; + break; + } + + usc_SetTransmitSyncChars(info,syncpat,syncpat); + } + +} /* end of usc_set_txidle() */ + +/* usc_get_serial_signals() + * + * Query the adapter for the state of the V24 status (input) signals. + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void usc_get_serial_signals( struct mgsl_struct *info ) +{ + u16 status; + + /* clear all serial signals except DTR and RTS */ + info->serial_signals &= SerialSignal_DTR + SerialSignal_RTS; + + /* Read the Misc Interrupt status Register (MISR) to get */ + /* the V24 status signals. */ + + status = usc_InReg( info, MISR ); + + /* set serial signal bits to reflect MISR */ + + if ( status & MISCSTATUS_CTS ) + info->serial_signals |= SerialSignal_CTS; + + if ( status & MISCSTATUS_DCD ) + info->serial_signals |= SerialSignal_DCD; + + if ( status & MISCSTATUS_RI ) + info->serial_signals |= SerialSignal_RI; + + if ( status & MISCSTATUS_DSR ) + info->serial_signals |= SerialSignal_DSR; + +} /* end of usc_get_serial_signals() */ + +/* usc_set_serial_signals() + * + * Set the state of DTR and RTS based on contents of + * serial_signals member of device extension. + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void usc_set_serial_signals( struct mgsl_struct *info ) +{ + u16 Control; + unsigned char V24Out = info->serial_signals; + + /* get the current value of the Port Control Register (PCR) */ + + Control = usc_InReg( info, PCR ); + + if ( V24Out & SerialSignal_RTS ) + Control &= ~(BIT6); + else + Control |= BIT6; + + if ( V24Out & SerialSignal_DTR ) + Control &= ~(BIT4); + else + Control |= BIT4; + + usc_OutReg( info, PCR, Control ); + +} /* end of usc_set_serial_signals() */ + +/* usc_enable_async_clock() + * + * Enable the async clock at the specified frequency. + * + * Arguments: info pointer to device instance data + * data_rate data rate of clock in bps + * 0 disables the AUX clock. + * Return Value: None + */ +static void usc_enable_async_clock( struct mgsl_struct *info, u32 data_rate ) +{ + if ( data_rate ) { + /* + * Clock mode Control Register (CMCR) + * + * <15..14> 00 counter 1 Disabled + * <13..12> 00 counter 0 Disabled + * <11..10> 11 BRG1 Input is TxC Pin + * <9..8> 11 BRG0 Input is TxC Pin + * <7..6> 01 DPLL Input is BRG1 Output + * <5..3> 100 TxCLK comes from BRG0 + * <2..0> 100 RxCLK comes from BRG0 + * + * 0000 1111 0110 0100 = 0x0f64 + */ + + usc_OutReg( info, CMCR, 0x0f64 ); + + + /* + * Write 16-bit Time Constant for BRG0 + * Time Constant = (ClkSpeed / data_rate) - 1 + * ClkSpeed = 921600 (ISA), 691200 (PCI) + */ + + if ( info->bus_type == MGSL_BUS_TYPE_PCI ) + usc_OutReg( info, TC0R, (u16)((691200/data_rate) - 1) ); + else + usc_OutReg( info, TC0R, (u16)((921600/data_rate) - 1) ); + + + /* + * Hardware Configuration Register (HCR) + * Clear Bit 1, BRG0 mode = Continuous + * Set Bit 0 to enable BRG0. + */ + + usc_OutReg( info, HCR, + (u16)((usc_InReg( info, HCR ) & ~BIT1) | BIT0) ); + + + /* Input/Output Control Reg, <2..0> = 100, Drive RxC pin with BRG0 */ + + usc_OutReg( info, IOCR, + (u16)((usc_InReg(info, IOCR) & 0xfff8) | 0x0004) ); + } else { + /* data rate == 0 so turn off BRG0 */ + usc_OutReg( info, HCR, (u16)(usc_InReg( info, HCR ) & ~BIT0) ); + } + +} /* end of usc_enable_async_clock() */ + +/* + * Buffer Structures: + * + * Normal memory access uses virtual addresses that can make discontiguous + * physical memory pages appear to be contiguous in the virtual address + * space (the processors memory mapping handles the conversions). + * + * DMA transfers require physically contiguous memory. This is because + * the DMA system controller and DMA bus masters deal with memory using + * only physical addresses. + * + * This causes a problem under Windows NT when large DMA buffers are + * needed. Fragmentation of the nonpaged pool prevents allocations of + * physically contiguous buffers larger than the PAGE_SIZE. + * + * However the 16C32 supports Bus Master Scatter/Gather DMA which + * allows DMA transfers to physically discontiguous buffers. Information + * about each data transfer buffer is contained in a memory structure + * called a 'buffer entry'. A list of buffer entries is maintained + * to track and control the use of the data transfer buffers. + * + * To support this strategy we will allocate sufficient PAGE_SIZE + * contiguous memory buffers to allow for the total required buffer + * space. + * + * The 16C32 accesses the list of buffer entries using Bus Master + * DMA. Control information is read from the buffer entries by the + * 16C32 to control data transfers. status information is written to + * the buffer entries by the 16C32 to indicate the status of completed + * transfers. + * + * The CPU writes control information to the buffer entries to control + * the 16C32 and reads status information from the buffer entries to + * determine information about received and transmitted frames. + * + * Because the CPU and 16C32 (adapter) both need simultaneous access + * to the buffer entries, the buffer entry memory is allocated with + * HalAllocateCommonBuffer(). This restricts the size of the buffer + * entry list to PAGE_SIZE. + * + * The actual data buffers on the other hand will only be accessed + * by the CPU or the adapter but not by both simultaneously. This allows + * Scatter/Gather packet based DMA procedures for using physically + * discontiguous pages. + */ + +/* + * mgsl_reset_tx_dma_buffers() + * + * Set the count for all transmit buffers to 0 to indicate the + * buffer is available for use and set the current buffer to the + * first buffer. This effectively makes all buffers free and + * discards any data in buffers. + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void mgsl_reset_tx_dma_buffers( struct mgsl_struct *info ) +{ + unsigned int i; + + for ( i = 0; i < info->tx_buffer_count; i++ ) { + *((unsigned long *)&(info->tx_buffer_list[i].count)) = 0; + } + + info->current_tx_buffer = 0; + info->start_tx_dma_buffer = 0; + info->tx_dma_buffers_used = 0; + + info->get_tx_holding_index = 0; + info->put_tx_holding_index = 0; + info->tx_holding_count = 0; + +} /* end of mgsl_reset_tx_dma_buffers() */ + +/* + * num_free_tx_dma_buffers() + * + * returns the number of free tx dma buffers available + * + * Arguments: info pointer to device instance data + * Return Value: number of free tx dma buffers + */ +static int num_free_tx_dma_buffers(struct mgsl_struct *info) +{ + return info->tx_buffer_count - info->tx_dma_buffers_used; +} + +/* + * mgsl_reset_rx_dma_buffers() + * + * Set the count for all receive buffers to DMABUFFERSIZE + * and set the current buffer to the first buffer. This effectively + * makes all buffers free and discards any data in buffers. + * + * Arguments: info pointer to device instance data + * Return Value: None + */ +static void mgsl_reset_rx_dma_buffers( struct mgsl_struct *info ) +{ + unsigned int i; + + for ( i = 0; i < info->rx_buffer_count; i++ ) { + *((unsigned long *)&(info->rx_buffer_list[i].count)) = DMABUFFERSIZE; +// info->rx_buffer_list[i].count = DMABUFFERSIZE; +// info->rx_buffer_list[i].status = 0; + } + + info->current_rx_buffer = 0; + +} /* end of mgsl_reset_rx_dma_buffers() */ + +/* + * mgsl_free_rx_frame_buffers() + * + * Free the receive buffers used by a received SDLC + * frame such that the buffers can be reused. + * + * Arguments: + * + * info pointer to device instance data + * StartIndex index of 1st receive buffer of frame + * EndIndex index of last receive buffer of frame + * + * Return Value: None + */ +static void mgsl_free_rx_frame_buffers( struct mgsl_struct *info, unsigned int StartIndex, unsigned int EndIndex ) +{ + bool Done = false; + DMABUFFERENTRY *pBufEntry; + unsigned int Index; + + /* Starting with 1st buffer entry of the frame clear the status */ + /* field and set the count field to DMA Buffer Size. */ + + Index = StartIndex; + + while( !Done ) { + pBufEntry = &(info->rx_buffer_list[Index]); + + if ( Index == EndIndex ) { + /* This is the last buffer of the frame! */ + Done = true; + } + + /* reset current buffer for reuse */ +// pBufEntry->status = 0; +// pBufEntry->count = DMABUFFERSIZE; + *((unsigned long *)&(pBufEntry->count)) = DMABUFFERSIZE; + + /* advance to next buffer entry in linked list */ + Index++; + if ( Index == info->rx_buffer_count ) + Index = 0; + } + + /* set current buffer to next buffer after last buffer of frame */ + info->current_rx_buffer = Index; + +} /* end of free_rx_frame_buffers() */ + +/* mgsl_get_rx_frame() + * + * This function attempts to return a received SDLC frame from the + * receive DMA buffers. Only frames received without errors are returned. + * + * Arguments: info pointer to device extension + * Return Value: true if frame returned, otherwise false + */ +static bool mgsl_get_rx_frame(struct mgsl_struct *info) +{ + unsigned int StartIndex, EndIndex; /* index of 1st and last buffers of Rx frame */ + unsigned short status; + DMABUFFERENTRY *pBufEntry; + unsigned int framesize = 0; + bool ReturnCode = false; + unsigned long flags; + struct tty_struct *tty = info->port.tty; + bool return_frame = false; + + /* + * current_rx_buffer points to the 1st buffer of the next available + * receive frame. To find the last buffer of the frame look for + * a non-zero status field in the buffer entries. (The status + * field is set by the 16C32 after completing a receive frame. + */ + + StartIndex = EndIndex = info->current_rx_buffer; + + while( !info->rx_buffer_list[EndIndex].status ) { + /* + * If the count field of the buffer entry is non-zero then + * this buffer has not been used. (The 16C32 clears the count + * field when it starts using the buffer.) If an unused buffer + * is encountered then there are no frames available. + */ + + if ( info->rx_buffer_list[EndIndex].count ) + goto Cleanup; + + /* advance to next buffer entry in linked list */ + EndIndex++; + if ( EndIndex == info->rx_buffer_count ) + EndIndex = 0; + + /* if entire list searched then no frame available */ + if ( EndIndex == StartIndex ) { + /* If this occurs then something bad happened, + * all buffers have been 'used' but none mark + * the end of a frame. Reset buffers and receiver. + */ + + if ( info->rx_enabled ){ + spin_lock_irqsave(&info->irq_spinlock,flags); + usc_start_receiver(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + } + goto Cleanup; + } + } + + + /* check status of receive frame */ + + status = info->rx_buffer_list[EndIndex].status; + + if ( status & (RXSTATUS_SHORT_FRAME + RXSTATUS_OVERRUN + + RXSTATUS_CRC_ERROR + RXSTATUS_ABORT) ) { + if ( status & RXSTATUS_SHORT_FRAME ) + info->icount.rxshort++; + else if ( status & RXSTATUS_ABORT ) + info->icount.rxabort++; + else if ( status & RXSTATUS_OVERRUN ) + info->icount.rxover++; + else { + info->icount.rxcrc++; + if ( info->params.crc_type & HDLC_CRC_RETURN_EX ) + return_frame = true; + } + framesize = 0; +#if SYNCLINK_GENERIC_HDLC + { + info->netdev->stats.rx_errors++; + info->netdev->stats.rx_frame_errors++; + } +#endif + } else + return_frame = true; + + if ( return_frame ) { + /* receive frame has no errors, get frame size. + * The frame size is the starting value of the RCC (which was + * set to 0xffff) minus the ending value of the RCC (decremented + * once for each receive character) minus 2 for the 16-bit CRC. + */ + + framesize = RCLRVALUE - info->rx_buffer_list[EndIndex].rcc; + + /* adjust frame size for CRC if any */ + if ( info->params.crc_type == HDLC_CRC_16_CCITT ) + framesize -= 2; + else if ( info->params.crc_type == HDLC_CRC_32_CCITT ) + framesize -= 4; + } + + if ( debug_level >= DEBUG_LEVEL_BH ) + printk("%s(%d):mgsl_get_rx_frame(%s) status=%04X size=%d\n", + __FILE__,__LINE__,info->device_name,status,framesize); + + if ( debug_level >= DEBUG_LEVEL_DATA ) + mgsl_trace_block(info,info->rx_buffer_list[StartIndex].virt_addr, + min_t(int, framesize, DMABUFFERSIZE),0); + + if (framesize) { + if ( ( (info->params.crc_type & HDLC_CRC_RETURN_EX) && + ((framesize+1) > info->max_frame_size) ) || + (framesize > info->max_frame_size) ) + info->icount.rxlong++; + else { + /* copy dma buffer(s) to contiguous intermediate buffer */ + int copy_count = framesize; + int index = StartIndex; + unsigned char *ptmp = info->intermediate_rxbuffer; + + if ( !(status & RXSTATUS_CRC_ERROR)) + info->icount.rxok++; + + while(copy_count) { + int partial_count; + if ( copy_count > DMABUFFERSIZE ) + partial_count = DMABUFFERSIZE; + else + partial_count = copy_count; + + pBufEntry = &(info->rx_buffer_list[index]); + memcpy( ptmp, pBufEntry->virt_addr, partial_count ); + ptmp += partial_count; + copy_count -= partial_count; + + if ( ++index == info->rx_buffer_count ) + index = 0; + } + + if ( info->params.crc_type & HDLC_CRC_RETURN_EX ) { + ++framesize; + *ptmp = (status & RXSTATUS_CRC_ERROR ? + RX_CRC_ERROR : + RX_OK); + + if ( debug_level >= DEBUG_LEVEL_DATA ) + printk("%s(%d):mgsl_get_rx_frame(%s) rx frame status=%d\n", + __FILE__,__LINE__,info->device_name, + *ptmp); + } + +#if SYNCLINK_GENERIC_HDLC + if (info->netcount) + hdlcdev_rx(info,info->intermediate_rxbuffer,framesize); + else +#endif + ldisc_receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize); + } + } + /* Free the buffers used by this frame. */ + mgsl_free_rx_frame_buffers( info, StartIndex, EndIndex ); + + ReturnCode = true; + +Cleanup: + + if ( info->rx_enabled && info->rx_overflow ) { + /* The receiver needs to restarted because of + * a receive overflow (buffer or FIFO). If the + * receive buffers are now empty, then restart receiver. + */ + + if ( !info->rx_buffer_list[EndIndex].status && + info->rx_buffer_list[EndIndex].count ) { + spin_lock_irqsave(&info->irq_spinlock,flags); + usc_start_receiver(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + } + } + + return ReturnCode; + +} /* end of mgsl_get_rx_frame() */ + +/* mgsl_get_raw_rx_frame() + * + * This function attempts to return a received frame from the + * receive DMA buffers when running in external loop mode. In this mode, + * we will return at most one DMABUFFERSIZE frame to the application. + * The USC receiver is triggering off of DCD going active to start a new + * frame, and DCD going inactive to terminate the frame (similar to + * processing a closing flag character). + * + * In this routine, we will return DMABUFFERSIZE "chunks" at a time. + * If DCD goes inactive, the last Rx DMA Buffer will have a non-zero + * status field and the RCC field will indicate the length of the + * entire received frame. We take this RCC field and get the modulus + * of RCC and DMABUFFERSIZE to determine if number of bytes in the + * last Rx DMA buffer and return that last portion of the frame. + * + * Arguments: info pointer to device extension + * Return Value: true if frame returned, otherwise false + */ +static bool mgsl_get_raw_rx_frame(struct mgsl_struct *info) +{ + unsigned int CurrentIndex, NextIndex; + unsigned short status; + DMABUFFERENTRY *pBufEntry; + unsigned int framesize = 0; + bool ReturnCode = false; + unsigned long flags; + struct tty_struct *tty = info->port.tty; + + /* + * current_rx_buffer points to the 1st buffer of the next available + * receive frame. The status field is set by the 16C32 after + * completing a receive frame. If the status field of this buffer + * is zero, either the USC is still filling this buffer or this + * is one of a series of buffers making up a received frame. + * + * If the count field of this buffer is zero, the USC is either + * using this buffer or has used this buffer. Look at the count + * field of the next buffer. If that next buffer's count is + * non-zero, the USC is still actively using the current buffer. + * Otherwise, if the next buffer's count field is zero, the + * current buffer is complete and the USC is using the next + * buffer. + */ + CurrentIndex = NextIndex = info->current_rx_buffer; + ++NextIndex; + if ( NextIndex == info->rx_buffer_count ) + NextIndex = 0; + + if ( info->rx_buffer_list[CurrentIndex].status != 0 || + (info->rx_buffer_list[CurrentIndex].count == 0 && + info->rx_buffer_list[NextIndex].count == 0)) { + /* + * Either the status field of this dma buffer is non-zero + * (indicating the last buffer of a receive frame) or the next + * buffer is marked as in use -- implying this buffer is complete + * and an intermediate buffer for this received frame. + */ + + status = info->rx_buffer_list[CurrentIndex].status; + + if ( status & (RXSTATUS_SHORT_FRAME + RXSTATUS_OVERRUN + + RXSTATUS_CRC_ERROR + RXSTATUS_ABORT) ) { + if ( status & RXSTATUS_SHORT_FRAME ) + info->icount.rxshort++; + else if ( status & RXSTATUS_ABORT ) + info->icount.rxabort++; + else if ( status & RXSTATUS_OVERRUN ) + info->icount.rxover++; + else + info->icount.rxcrc++; + framesize = 0; + } else { + /* + * A receive frame is available, get frame size and status. + * + * The frame size is the starting value of the RCC (which was + * set to 0xffff) minus the ending value of the RCC (decremented + * once for each receive character) minus 2 or 4 for the 16-bit + * or 32-bit CRC. + * + * If the status field is zero, this is an intermediate buffer. + * It's size is 4K. + * + * If the DMA Buffer Entry's Status field is non-zero, the + * receive operation completed normally (ie: DCD dropped). The + * RCC field is valid and holds the received frame size. + * It is possible that the RCC field will be zero on a DMA buffer + * entry with a non-zero status. This can occur if the total + * frame size (number of bytes between the time DCD goes active + * to the time DCD goes inactive) exceeds 65535 bytes. In this + * case the 16C32 has underrun on the RCC count and appears to + * stop updating this counter to let us know the actual received + * frame size. If this happens (non-zero status and zero RCC), + * simply return the entire RxDMA Buffer + */ + if ( status ) { + /* + * In the event that the final RxDMA Buffer is + * terminated with a non-zero status and the RCC + * field is zero, we interpret this as the RCC + * having underflowed (received frame > 65535 bytes). + * + * Signal the event to the user by passing back + * a status of RxStatus_CrcError returning the full + * buffer and let the app figure out what data is + * actually valid + */ + if ( info->rx_buffer_list[CurrentIndex].rcc ) + framesize = RCLRVALUE - info->rx_buffer_list[CurrentIndex].rcc; + else + framesize = DMABUFFERSIZE; + } + else + framesize = DMABUFFERSIZE; + } + + if ( framesize > DMABUFFERSIZE ) { + /* + * if running in raw sync mode, ISR handler for + * End Of Buffer events terminates all buffers at 4K. + * If this frame size is said to be >4K, get the + * actual number of bytes of the frame in this buffer. + */ + framesize = framesize % DMABUFFERSIZE; + } + + + if ( debug_level >= DEBUG_LEVEL_BH ) + printk("%s(%d):mgsl_get_raw_rx_frame(%s) status=%04X size=%d\n", + __FILE__,__LINE__,info->device_name,status,framesize); + + if ( debug_level >= DEBUG_LEVEL_DATA ) + mgsl_trace_block(info,info->rx_buffer_list[CurrentIndex].virt_addr, + min_t(int, framesize, DMABUFFERSIZE),0); + + if (framesize) { + /* copy dma buffer(s) to contiguous intermediate buffer */ + /* NOTE: we never copy more than DMABUFFERSIZE bytes */ + + pBufEntry = &(info->rx_buffer_list[CurrentIndex]); + memcpy( info->intermediate_rxbuffer, pBufEntry->virt_addr, framesize); + info->icount.rxok++; + + ldisc_receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize); + } + + /* Free the buffers used by this frame. */ + mgsl_free_rx_frame_buffers( info, CurrentIndex, CurrentIndex ); + + ReturnCode = true; + } + + + if ( info->rx_enabled && info->rx_overflow ) { + /* The receiver needs to restarted because of + * a receive overflow (buffer or FIFO). If the + * receive buffers are now empty, then restart receiver. + */ + + if ( !info->rx_buffer_list[CurrentIndex].status && + info->rx_buffer_list[CurrentIndex].count ) { + spin_lock_irqsave(&info->irq_spinlock,flags); + usc_start_receiver(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + } + } + + return ReturnCode; + +} /* end of mgsl_get_raw_rx_frame() */ + +/* mgsl_load_tx_dma_buffer() + * + * Load the transmit DMA buffer with the specified data. + * + * Arguments: + * + * info pointer to device extension + * Buffer pointer to buffer containing frame to load + * BufferSize size in bytes of frame in Buffer + * + * Return Value: None + */ +static void mgsl_load_tx_dma_buffer(struct mgsl_struct *info, + const char *Buffer, unsigned int BufferSize) +{ + unsigned short Copycount; + unsigned int i = 0; + DMABUFFERENTRY *pBufEntry; + + if ( debug_level >= DEBUG_LEVEL_DATA ) + mgsl_trace_block(info,Buffer, min_t(int, BufferSize, DMABUFFERSIZE), 1); + + if (info->params.flags & HDLC_FLAG_HDLC_LOOPMODE) { + /* set CMR:13 to start transmit when + * next GoAhead (abort) is received + */ + info->cmr_value |= BIT13; + } + + /* begin loading the frame in the next available tx dma + * buffer, remember it's starting location for setting + * up tx dma operation + */ + i = info->current_tx_buffer; + info->start_tx_dma_buffer = i; + + /* Setup the status and RCC (Frame Size) fields of the 1st */ + /* buffer entry in the transmit DMA buffer list. */ + + info->tx_buffer_list[i].status = info->cmr_value & 0xf000; + info->tx_buffer_list[i].rcc = BufferSize; + info->tx_buffer_list[i].count = BufferSize; + + /* Copy frame data from 1st source buffer to the DMA buffers. */ + /* The frame data may span multiple DMA buffers. */ + + while( BufferSize ){ + /* Get a pointer to next DMA buffer entry. */ + pBufEntry = &info->tx_buffer_list[i++]; + + if ( i == info->tx_buffer_count ) + i=0; + + /* Calculate the number of bytes that can be copied from */ + /* the source buffer to this DMA buffer. */ + if ( BufferSize > DMABUFFERSIZE ) + Copycount = DMABUFFERSIZE; + else + Copycount = BufferSize; + + /* Actually copy data from source buffer to DMA buffer. */ + /* Also set the data count for this individual DMA buffer. */ + if ( info->bus_type == MGSL_BUS_TYPE_PCI ) + mgsl_load_pci_memory(pBufEntry->virt_addr, Buffer,Copycount); + else + memcpy(pBufEntry->virt_addr, Buffer, Copycount); + + pBufEntry->count = Copycount; + + /* Advance source pointer and reduce remaining data count. */ + Buffer += Copycount; + BufferSize -= Copycount; + + ++info->tx_dma_buffers_used; + } + + /* remember next available tx dma buffer */ + info->current_tx_buffer = i; + +} /* end of mgsl_load_tx_dma_buffer() */ + +/* + * mgsl_register_test() + * + * Performs a register test of the 16C32. + * + * Arguments: info pointer to device instance data + * Return Value: true if test passed, otherwise false + */ +static bool mgsl_register_test( struct mgsl_struct *info ) +{ + static unsigned short BitPatterns[] = + { 0x0000, 0xffff, 0xaaaa, 0x5555, 0x1234, 0x6969, 0x9696, 0x0f0f }; + static unsigned int Patterncount = ARRAY_SIZE(BitPatterns); + unsigned int i; + bool rc = true; + unsigned long flags; + + spin_lock_irqsave(&info->irq_spinlock,flags); + usc_reset(info); + + /* Verify the reset state of some registers. */ + + if ( (usc_InReg( info, SICR ) != 0) || + (usc_InReg( info, IVR ) != 0) || + (usc_InDmaReg( info, DIVR ) != 0) ){ + rc = false; + } + + if ( rc ){ + /* Write bit patterns to various registers but do it out of */ + /* sync, then read back and verify values. */ + + for ( i = 0 ; i < Patterncount ; i++ ) { + usc_OutReg( info, TC0R, BitPatterns[i] ); + usc_OutReg( info, TC1R, BitPatterns[(i+1)%Patterncount] ); + usc_OutReg( info, TCLR, BitPatterns[(i+2)%Patterncount] ); + usc_OutReg( info, RCLR, BitPatterns[(i+3)%Patterncount] ); + usc_OutReg( info, RSR, BitPatterns[(i+4)%Patterncount] ); + usc_OutDmaReg( info, TBCR, BitPatterns[(i+5)%Patterncount] ); + + if ( (usc_InReg( info, TC0R ) != BitPatterns[i]) || + (usc_InReg( info, TC1R ) != BitPatterns[(i+1)%Patterncount]) || + (usc_InReg( info, TCLR ) != BitPatterns[(i+2)%Patterncount]) || + (usc_InReg( info, RCLR ) != BitPatterns[(i+3)%Patterncount]) || + (usc_InReg( info, RSR ) != BitPatterns[(i+4)%Patterncount]) || + (usc_InDmaReg( info, TBCR ) != BitPatterns[(i+5)%Patterncount]) ){ + rc = false; + break; + } + } + } + + usc_reset(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + return rc; + +} /* end of mgsl_register_test() */ + +/* mgsl_irq_test() Perform interrupt test of the 16C32. + * + * Arguments: info pointer to device instance data + * Return Value: true if test passed, otherwise false + */ +static bool mgsl_irq_test( struct mgsl_struct *info ) +{ + unsigned long EndTime; + unsigned long flags; + + spin_lock_irqsave(&info->irq_spinlock,flags); + usc_reset(info); + + /* + * Setup 16C32 to interrupt on TxC pin (14MHz clock) transition. + * The ISR sets irq_occurred to true. + */ + + info->irq_occurred = false; + + /* Enable INTEN gate for ISA adapter (Port 6, Bit12) */ + /* Enable INTEN (Port 6, Bit12) */ + /* This connects the IRQ request signal to the ISA bus */ + /* on the ISA adapter. This has no effect for the PCI adapter */ + usc_OutReg( info, PCR, (unsigned short)((usc_InReg(info, PCR) | BIT13) & ~BIT12) ); + + usc_EnableMasterIrqBit(info); + usc_EnableInterrupts(info, IO_PIN); + usc_ClearIrqPendingBits(info, IO_PIN); + + usc_UnlatchIostatusBits(info, MISCSTATUS_TXC_LATCHED); + usc_EnableStatusIrqs(info, SICR_TXC_ACTIVE + SICR_TXC_INACTIVE); + + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + EndTime=100; + while( EndTime-- && !info->irq_occurred ) { + msleep_interruptible(10); + } + + spin_lock_irqsave(&info->irq_spinlock,flags); + usc_reset(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + return info->irq_occurred; + +} /* end of mgsl_irq_test() */ + +/* mgsl_dma_test() + * + * Perform a DMA test of the 16C32. A small frame is + * transmitted via DMA from a transmit buffer to a receive buffer + * using single buffer DMA mode. + * + * Arguments: info pointer to device instance data + * Return Value: true if test passed, otherwise false + */ +static bool mgsl_dma_test( struct mgsl_struct *info ) +{ + unsigned short FifoLevel; + unsigned long phys_addr; + unsigned int FrameSize; + unsigned int i; + char *TmpPtr; + bool rc = true; + unsigned short status=0; + unsigned long EndTime; + unsigned long flags; + MGSL_PARAMS tmp_params; + + /* save current port options */ + memcpy(&tmp_params,&info->params,sizeof(MGSL_PARAMS)); + /* load default port options */ + memcpy(&info->params,&default_params,sizeof(MGSL_PARAMS)); + +#define TESTFRAMESIZE 40 + + spin_lock_irqsave(&info->irq_spinlock,flags); + + /* setup 16C32 for SDLC DMA transfer mode */ + + usc_reset(info); + usc_set_sdlc_mode(info); + usc_enable_loopback(info,1); + + /* Reprogram the RDMR so that the 16C32 does NOT clear the count + * field of the buffer entry after fetching buffer address. This + * way we can detect a DMA failure for a DMA read (which should be + * non-destructive to system memory) before we try and write to + * memory (where a failure could corrupt system memory). + */ + + /* Receive DMA mode Register (RDMR) + * + * <15..14> 11 DMA mode = Linked List Buffer mode + * <13> 1 RSBinA/L = store Rx status Block in List entry + * <12> 0 1 = Clear count of List Entry after fetching + * <11..10> 00 Address mode = Increment + * <9> 1 Terminate Buffer on RxBound + * <8> 0 Bus Width = 16bits + * <7..0> ? status Bits (write as 0s) + * + * 1110 0010 0000 0000 = 0xe200 + */ + + usc_OutDmaReg( info, RDMR, 0xe200 ); + + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + + /* SETUP TRANSMIT AND RECEIVE DMA BUFFERS */ + + FrameSize = TESTFRAMESIZE; + + /* setup 1st transmit buffer entry: */ + /* with frame size and transmit control word */ + + info->tx_buffer_list[0].count = FrameSize; + info->tx_buffer_list[0].rcc = FrameSize; + info->tx_buffer_list[0].status = 0x4000; + + /* build a transmit frame in 1st transmit DMA buffer */ + + TmpPtr = info->tx_buffer_list[0].virt_addr; + for (i = 0; i < FrameSize; i++ ) + *TmpPtr++ = i; + + /* setup 1st receive buffer entry: */ + /* clear status, set max receive buffer size */ + + info->rx_buffer_list[0].status = 0; + info->rx_buffer_list[0].count = FrameSize + 4; + + /* zero out the 1st receive buffer */ + + memset( info->rx_buffer_list[0].virt_addr, 0, FrameSize + 4 ); + + /* Set count field of next buffer entries to prevent */ + /* 16C32 from using buffers after the 1st one. */ + + info->tx_buffer_list[1].count = 0; + info->rx_buffer_list[1].count = 0; + + + /***************************/ + /* Program 16C32 receiver. */ + /***************************/ + + spin_lock_irqsave(&info->irq_spinlock,flags); + + /* setup DMA transfers */ + usc_RTCmd( info, RTCmd_PurgeRxFifo ); + + /* program 16C32 receiver with physical address of 1st DMA buffer entry */ + phys_addr = info->rx_buffer_list[0].phys_entry; + usc_OutDmaReg( info, NRARL, (unsigned short)phys_addr ); + usc_OutDmaReg( info, NRARU, (unsigned short)(phys_addr >> 16) ); + + /* Clear the Rx DMA status bits (read RDMR) and start channel */ + usc_InDmaReg( info, RDMR ); + usc_DmaCmd( info, DmaCmd_InitRxChannel ); + + /* Enable Receiver (RMR <1..0> = 10) */ + usc_OutReg( info, RMR, (unsigned short)((usc_InReg(info, RMR) & 0xfffc) | 0x0002) ); + + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + + /*************************************************************/ + /* WAIT FOR RECEIVER TO DMA ALL PARAMETERS FROM BUFFER ENTRY */ + /*************************************************************/ + + /* Wait 100ms for interrupt. */ + EndTime = jiffies + msecs_to_jiffies(100); + + for(;;) { + if (time_after(jiffies, EndTime)) { + rc = false; + break; + } + + spin_lock_irqsave(&info->irq_spinlock,flags); + status = usc_InDmaReg( info, RDMR ); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + if ( !(status & BIT4) && (status & BIT5) ) { + /* INITG (BIT 4) is inactive (no entry read in progress) AND */ + /* BUSY (BIT 5) is active (channel still active). */ + /* This means the buffer entry read has completed. */ + break; + } + } + + + /******************************/ + /* Program 16C32 transmitter. */ + /******************************/ + + spin_lock_irqsave(&info->irq_spinlock,flags); + + /* Program the Transmit Character Length Register (TCLR) */ + /* and clear FIFO (TCC is loaded with TCLR on FIFO clear) */ + + usc_OutReg( info, TCLR, (unsigned short)info->tx_buffer_list[0].count ); + usc_RTCmd( info, RTCmd_PurgeTxFifo ); + + /* Program the address of the 1st DMA Buffer Entry in linked list */ + + phys_addr = info->tx_buffer_list[0].phys_entry; + usc_OutDmaReg( info, NTARL, (unsigned short)phys_addr ); + usc_OutDmaReg( info, NTARU, (unsigned short)(phys_addr >> 16) ); + + /* unlatch Tx status bits, and start transmit channel. */ + + usc_OutReg( info, TCSR, (unsigned short)(( usc_InReg(info, TCSR) & 0x0f00) | 0xfa) ); + usc_DmaCmd( info, DmaCmd_InitTxChannel ); + + /* wait for DMA controller to fill transmit FIFO */ + + usc_TCmd( info, TCmd_SelectTicrTxFifostatus ); + + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + + /**********************************/ + /* WAIT FOR TRANSMIT FIFO TO FILL */ + /**********************************/ + + /* Wait 100ms */ + EndTime = jiffies + msecs_to_jiffies(100); + + for(;;) { + if (time_after(jiffies, EndTime)) { + rc = false; + break; + } + + spin_lock_irqsave(&info->irq_spinlock,flags); + FifoLevel = usc_InReg(info, TICR) >> 8; + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + if ( FifoLevel < 16 ) + break; + else + if ( FrameSize < 32 ) { + /* This frame is smaller than the entire transmit FIFO */ + /* so wait for the entire frame to be loaded. */ + if ( FifoLevel <= (32 - FrameSize) ) + break; + } + } + + + if ( rc ) + { + /* Enable 16C32 transmitter. */ + + spin_lock_irqsave(&info->irq_spinlock,flags); + + /* Transmit mode Register (TMR), <1..0> = 10, Enable Transmitter */ + usc_TCmd( info, TCmd_SendFrame ); + usc_OutReg( info, TMR, (unsigned short)((usc_InReg(info, TMR) & 0xfffc) | 0x0002) ); + + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + + /******************************/ + /* WAIT FOR TRANSMIT COMPLETE */ + /******************************/ + + /* Wait 100ms */ + EndTime = jiffies + msecs_to_jiffies(100); + + /* While timer not expired wait for transmit complete */ + + spin_lock_irqsave(&info->irq_spinlock,flags); + status = usc_InReg( info, TCSR ); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + while ( !(status & (BIT6+BIT5+BIT4+BIT2+BIT1)) ) { + if (time_after(jiffies, EndTime)) { + rc = false; + break; + } + + spin_lock_irqsave(&info->irq_spinlock,flags); + status = usc_InReg( info, TCSR ); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + } + } + + + if ( rc ){ + /* CHECK FOR TRANSMIT ERRORS */ + if ( status & (BIT5 + BIT1) ) + rc = false; + } + + if ( rc ) { + /* WAIT FOR RECEIVE COMPLETE */ + + /* Wait 100ms */ + EndTime = jiffies + msecs_to_jiffies(100); + + /* Wait for 16C32 to write receive status to buffer entry. */ + status=info->rx_buffer_list[0].status; + while ( status == 0 ) { + if (time_after(jiffies, EndTime)) { + rc = false; + break; + } + status=info->rx_buffer_list[0].status; + } + } + + + if ( rc ) { + /* CHECK FOR RECEIVE ERRORS */ + status = info->rx_buffer_list[0].status; + + if ( status & (BIT8 + BIT3 + BIT1) ) { + /* receive error has occurred */ + rc = false; + } else { + if ( memcmp( info->tx_buffer_list[0].virt_addr , + info->rx_buffer_list[0].virt_addr, FrameSize ) ){ + rc = false; + } + } + } + + spin_lock_irqsave(&info->irq_spinlock,flags); + usc_reset( info ); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + /* restore current port options */ + memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS)); + + return rc; + +} /* end of mgsl_dma_test() */ + +/* mgsl_adapter_test() + * + * Perform the register, IRQ, and DMA tests for the 16C32. + * + * Arguments: info pointer to device instance data + * Return Value: 0 if success, otherwise -ENODEV + */ +static int mgsl_adapter_test( struct mgsl_struct *info ) +{ + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):Testing device %s\n", + __FILE__,__LINE__,info->device_name ); + + if ( !mgsl_register_test( info ) ) { + info->init_error = DiagStatus_AddressFailure; + printk( "%s(%d):Register test failure for device %s Addr=%04X\n", + __FILE__,__LINE__,info->device_name, (unsigned short)(info->io_base) ); + return -ENODEV; + } + + if ( !mgsl_irq_test( info ) ) { + info->init_error = DiagStatus_IrqFailure; + printk( "%s(%d):Interrupt test failure for device %s IRQ=%d\n", + __FILE__,__LINE__,info->device_name, (unsigned short)(info->irq_level) ); + return -ENODEV; + } + + if ( !mgsl_dma_test( info ) ) { + info->init_error = DiagStatus_DmaFailure; + printk( "%s(%d):DMA test failure for device %s DMA=%d\n", + __FILE__,__LINE__,info->device_name, (unsigned short)(info->dma_level) ); + return -ENODEV; + } + + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):device %s passed diagnostics\n", + __FILE__,__LINE__,info->device_name ); + + return 0; + +} /* end of mgsl_adapter_test() */ + +/* mgsl_memory_test() + * + * Test the shared memory on a PCI adapter. + * + * Arguments: info pointer to device instance data + * Return Value: true if test passed, otherwise false + */ +static bool mgsl_memory_test( struct mgsl_struct *info ) +{ + static unsigned long BitPatterns[] = + { 0x0, 0x55555555, 0xaaaaaaaa, 0x66666666, 0x99999999, 0xffffffff, 0x12345678 }; + unsigned long Patterncount = ARRAY_SIZE(BitPatterns); + unsigned long i; + unsigned long TestLimit = SHARED_MEM_ADDRESS_SIZE/sizeof(unsigned long); + unsigned long * TestAddr; + + if ( info->bus_type != MGSL_BUS_TYPE_PCI ) + return true; + + TestAddr = (unsigned long *)info->memory_base; + + /* Test data lines with test pattern at one location. */ + + for ( i = 0 ; i < Patterncount ; i++ ) { + *TestAddr = BitPatterns[i]; + if ( *TestAddr != BitPatterns[i] ) + return false; + } + + /* Test address lines with incrementing pattern over */ + /* entire address range. */ + + for ( i = 0 ; i < TestLimit ; i++ ) { + *TestAddr = i * 4; + TestAddr++; + } + + TestAddr = (unsigned long *)info->memory_base; + + for ( i = 0 ; i < TestLimit ; i++ ) { + if ( *TestAddr != i * 4 ) + return false; + TestAddr++; + } + + memset( info->memory_base, 0, SHARED_MEM_ADDRESS_SIZE ); + + return true; + +} /* End Of mgsl_memory_test() */ + + +/* mgsl_load_pci_memory() + * + * Load a large block of data into the PCI shared memory. + * Use this instead of memcpy() or memmove() to move data + * into the PCI shared memory. + * + * Notes: + * + * This function prevents the PCI9050 interface chip from hogging + * the adapter local bus, which can starve the 16C32 by preventing + * 16C32 bus master cycles. + * + * The PCI9050 documentation says that the 9050 will always release + * control of the local bus after completing the current read + * or write operation. + * + * It appears that as long as the PCI9050 write FIFO is full, the + * PCI9050 treats all of the writes as a single burst transaction + * and will not release the bus. This causes DMA latency problems + * at high speeds when copying large data blocks to the shared + * memory. + * + * This function in effect, breaks the a large shared memory write + * into multiple transations by interleaving a shared memory read + * which will flush the write FIFO and 'complete' the write + * transation. This allows any pending DMA request to gain control + * of the local bus in a timely fasion. + * + * Arguments: + * + * TargetPtr pointer to target address in PCI shared memory + * SourcePtr pointer to source buffer for data + * count count in bytes of data to copy + * + * Return Value: None + */ +static void mgsl_load_pci_memory( char* TargetPtr, const char* SourcePtr, + unsigned short count ) +{ + /* 16 32-bit writes @ 60ns each = 960ns max latency on local bus */ +#define PCI_LOAD_INTERVAL 64 + + unsigned short Intervalcount = count / PCI_LOAD_INTERVAL; + unsigned short Index; + unsigned long Dummy; + + for ( Index = 0 ; Index < Intervalcount ; Index++ ) + { + memcpy(TargetPtr, SourcePtr, PCI_LOAD_INTERVAL); + Dummy = *((volatile unsigned long *)TargetPtr); + TargetPtr += PCI_LOAD_INTERVAL; + SourcePtr += PCI_LOAD_INTERVAL; + } + + memcpy( TargetPtr, SourcePtr, count % PCI_LOAD_INTERVAL ); + +} /* End Of mgsl_load_pci_memory() */ + +static void mgsl_trace_block(struct mgsl_struct *info,const char* data, int count, int xmit) +{ + int i; + int linecount; + if (xmit) + printk("%s tx data:\n",info->device_name); + else + printk("%s rx data:\n",info->device_name); + + while(count) { + if (count > 16) + linecount = 16; + else + linecount = count; + + for(i=0;i=040 && data[i]<=0176) + printk("%c",data[i]); + else + printk("."); + } + printk("\n"); + + data += linecount; + count -= linecount; + } +} /* end of mgsl_trace_block() */ + +/* mgsl_tx_timeout() + * + * called when HDLC frame times out + * update stats and do tx completion processing + * + * Arguments: context pointer to device instance data + * Return Value: None + */ +static void mgsl_tx_timeout(unsigned long context) +{ + struct mgsl_struct *info = (struct mgsl_struct*)context; + unsigned long flags; + + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):mgsl_tx_timeout(%s)\n", + __FILE__,__LINE__,info->device_name); + if(info->tx_active && + (info->params.mode == MGSL_MODE_HDLC || + info->params.mode == MGSL_MODE_RAW) ) { + info->icount.txtimeout++; + } + spin_lock_irqsave(&info->irq_spinlock,flags); + info->tx_active = false; + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + + if ( info->params.flags & HDLC_FLAG_HDLC_LOOPMODE ) + usc_loopmode_cancel_transmit( info ); + + spin_unlock_irqrestore(&info->irq_spinlock,flags); + +#if SYNCLINK_GENERIC_HDLC + if (info->netcount) + hdlcdev_tx_done(info); + else +#endif + mgsl_bh_transmit(info); + +} /* end of mgsl_tx_timeout() */ + +/* signal that there are no more frames to send, so that + * line is 'released' by echoing RxD to TxD when current + * transmission is complete (or immediately if no tx in progress). + */ +static int mgsl_loopmode_send_done( struct mgsl_struct * info ) +{ + unsigned long flags; + + spin_lock_irqsave(&info->irq_spinlock,flags); + if (info->params.flags & HDLC_FLAG_HDLC_LOOPMODE) { + if (info->tx_active) + info->loopmode_send_done_requested = true; + else + usc_loopmode_send_done(info); + } + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + return 0; +} + +/* release the line by echoing RxD to TxD + * upon completion of a transmit frame + */ +static void usc_loopmode_send_done( struct mgsl_struct * info ) +{ + info->loopmode_send_done_requested = false; + /* clear CMR:13 to 0 to start echoing RxData to TxData */ + info->cmr_value &= ~BIT13; + usc_OutReg(info, CMR, info->cmr_value); +} + +/* abort a transmit in progress while in HDLC LoopMode + */ +static void usc_loopmode_cancel_transmit( struct mgsl_struct * info ) +{ + /* reset tx dma channel and purge TxFifo */ + usc_RTCmd( info, RTCmd_PurgeTxFifo ); + usc_DmaCmd( info, DmaCmd_ResetTxChannel ); + usc_loopmode_send_done( info ); +} + +/* for HDLC/SDLC LoopMode, setting CMR:13 after the transmitter is enabled + * is an Insert Into Loop action. Upon receipt of a GoAhead sequence (RxAbort) + * we must clear CMR:13 to begin repeating TxData to RxData + */ +static void usc_loopmode_insert_request( struct mgsl_struct * info ) +{ + info->loopmode_insert_requested = true; + + /* enable RxAbort irq. On next RxAbort, clear CMR:13 to + * begin repeating TxData on RxData (complete insertion) + */ + usc_OutReg( info, RICR, + (usc_InReg( info, RICR ) | RXSTATUS_ABORT_RECEIVED ) ); + + /* set CMR:13 to insert into loop on next GoAhead (RxAbort) */ + info->cmr_value |= BIT13; + usc_OutReg(info, CMR, info->cmr_value); +} + +/* return 1 if station is inserted into the loop, otherwise 0 + */ +static int usc_loopmode_active( struct mgsl_struct * info) +{ + return usc_InReg( info, CCSR ) & BIT7 ? 1 : 0 ; +} + +#if SYNCLINK_GENERIC_HDLC + +/** + * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) + * set encoding and frame check sequence (FCS) options + * + * dev pointer to network device structure + * encoding serial encoding setting + * parity FCS setting + * + * returns 0 if success, otherwise error code + */ +static int hdlcdev_attach(struct net_device *dev, unsigned short encoding, + unsigned short parity) +{ + struct mgsl_struct *info = dev_to_port(dev); + unsigned char new_encoding; + unsigned short new_crctype; + + /* return error if TTY interface open */ + if (info->port.count) + return -EBUSY; + + switch (encoding) + { + case ENCODING_NRZ: new_encoding = HDLC_ENCODING_NRZ; break; + case ENCODING_NRZI: new_encoding = HDLC_ENCODING_NRZI_SPACE; break; + case ENCODING_FM_MARK: new_encoding = HDLC_ENCODING_BIPHASE_MARK; break; + case ENCODING_FM_SPACE: new_encoding = HDLC_ENCODING_BIPHASE_SPACE; break; + case ENCODING_MANCHESTER: new_encoding = HDLC_ENCODING_BIPHASE_LEVEL; break; + default: return -EINVAL; + } + + switch (parity) + { + case PARITY_NONE: new_crctype = HDLC_CRC_NONE; break; + case PARITY_CRC16_PR1_CCITT: new_crctype = HDLC_CRC_16_CCITT; break; + case PARITY_CRC32_PR1_CCITT: new_crctype = HDLC_CRC_32_CCITT; break; + default: return -EINVAL; + } + + info->params.encoding = new_encoding; + info->params.crc_type = new_crctype; + + /* if network interface up, reprogram hardware */ + if (info->netcount) + mgsl_program_hw(info); + + return 0; +} + +/** + * called by generic HDLC layer to send frame + * + * skb socket buffer containing HDLC frame + * dev pointer to network device structure + */ +static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct mgsl_struct *info = dev_to_port(dev); + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk(KERN_INFO "%s:hdlc_xmit(%s)\n",__FILE__,dev->name); + + /* stop sending until this frame completes */ + netif_stop_queue(dev); + + /* copy data to device buffers */ + info->xmit_cnt = skb->len; + mgsl_load_tx_dma_buffer(info, skb->data, skb->len); + + /* update network statistics */ + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + + /* done with socket buffer, so free it */ + dev_kfree_skb(skb); + + /* save start time for transmit timeout detection */ + dev->trans_start = jiffies; + + /* start hardware transmitter if necessary */ + spin_lock_irqsave(&info->irq_spinlock,flags); + if (!info->tx_active) + usc_start_transmitter(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + return NETDEV_TX_OK; +} + +/** + * called by network layer when interface enabled + * claim resources and initialize hardware + * + * dev pointer to network device structure + * + * returns 0 if success, otherwise error code + */ +static int hdlcdev_open(struct net_device *dev) +{ + struct mgsl_struct *info = dev_to_port(dev); + int rc; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s:hdlcdev_open(%s)\n",__FILE__,dev->name); + + /* generic HDLC layer open processing */ + if ((rc = hdlc_open(dev))) + return rc; + + /* arbitrate between network and tty opens */ + spin_lock_irqsave(&info->netlock, flags); + if (info->port.count != 0 || info->netcount != 0) { + printk(KERN_WARNING "%s: hdlc_open returning busy\n", dev->name); + spin_unlock_irqrestore(&info->netlock, flags); + return -EBUSY; + } + info->netcount=1; + spin_unlock_irqrestore(&info->netlock, flags); + + /* claim resources and init adapter */ + if ((rc = startup(info)) != 0) { + spin_lock_irqsave(&info->netlock, flags); + info->netcount=0; + spin_unlock_irqrestore(&info->netlock, flags); + return rc; + } + + /* assert DTR and RTS, apply hardware settings */ + info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; + mgsl_program_hw(info); + + /* enable network layer transmit */ + dev->trans_start = jiffies; + netif_start_queue(dev); + + /* inform generic HDLC layer of current DCD status */ + spin_lock_irqsave(&info->irq_spinlock, flags); + usc_get_serial_signals(info); + spin_unlock_irqrestore(&info->irq_spinlock, flags); + if (info->serial_signals & SerialSignal_DCD) + netif_carrier_on(dev); + else + netif_carrier_off(dev); + return 0; +} + +/** + * called by network layer when interface is disabled + * shutdown hardware and release resources + * + * dev pointer to network device structure + * + * returns 0 if success, otherwise error code + */ +static int hdlcdev_close(struct net_device *dev) +{ + struct mgsl_struct *info = dev_to_port(dev); + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s:hdlcdev_close(%s)\n",__FILE__,dev->name); + + netif_stop_queue(dev); + + /* shutdown adapter and release resources */ + shutdown(info); + + hdlc_close(dev); + + spin_lock_irqsave(&info->netlock, flags); + info->netcount=0; + spin_unlock_irqrestore(&info->netlock, flags); + + return 0; +} + +/** + * called by network layer to process IOCTL call to network device + * + * dev pointer to network device structure + * ifr pointer to network interface request structure + * cmd IOCTL command code + * + * returns 0 if success, otherwise error code + */ +static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + const size_t size = sizeof(sync_serial_settings); + sync_serial_settings new_line; + sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; + struct mgsl_struct *info = dev_to_port(dev); + unsigned int flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s:hdlcdev_ioctl(%s)\n",__FILE__,dev->name); + + /* return error if TTY interface open */ + if (info->port.count) + return -EBUSY; + + if (cmd != SIOCWANDEV) + return hdlc_ioctl(dev, ifr, cmd); + + switch(ifr->ifr_settings.type) { + case IF_GET_IFACE: /* return current sync_serial_settings */ + + ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL; + if (ifr->ifr_settings.size < size) { + ifr->ifr_settings.size = size; /* data size wanted */ + return -ENOBUFS; + } + + flags = info->params.flags & (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | + HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | + HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | + HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); + + switch (flags){ + case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN): new_line.clock_type = CLOCK_EXT; break; + case (HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG): new_line.clock_type = CLOCK_INT; break; + case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG): new_line.clock_type = CLOCK_TXINT; break; + case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN): new_line.clock_type = CLOCK_TXFROMRX; break; + default: new_line.clock_type = CLOCK_DEFAULT; + } + + new_line.clock_rate = info->params.clock_speed; + new_line.loopback = info->params.loopback ? 1:0; + + if (copy_to_user(line, &new_line, size)) + return -EFAULT; + return 0; + + case IF_IFACE_SYNC_SERIAL: /* set sync_serial_settings */ + + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + if (copy_from_user(&new_line, line, size)) + return -EFAULT; + + switch (new_line.clock_type) + { + case CLOCK_EXT: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN; break; + case CLOCK_TXFROMRX: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN; break; + case CLOCK_INT: flags = HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG; break; + case CLOCK_TXINT: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG; break; + case CLOCK_DEFAULT: flags = info->params.flags & + (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | + HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | + HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | + HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); break; + default: return -EINVAL; + } + + if (new_line.loopback != 0 && new_line.loopback != 1) + return -EINVAL; + + info->params.flags &= ~(HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | + HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | + HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | + HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); + info->params.flags |= flags; + + info->params.loopback = new_line.loopback; + + if (flags & (HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG)) + info->params.clock_speed = new_line.clock_rate; + else + info->params.clock_speed = 0; + + /* if network interface up, reprogram hardware */ + if (info->netcount) + mgsl_program_hw(info); + return 0; + + default: + return hdlc_ioctl(dev, ifr, cmd); + } +} + +/** + * called by network layer when transmit timeout is detected + * + * dev pointer to network device structure + */ +static void hdlcdev_tx_timeout(struct net_device *dev) +{ + struct mgsl_struct *info = dev_to_port(dev); + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("hdlcdev_tx_timeout(%s)\n",dev->name); + + dev->stats.tx_errors++; + dev->stats.tx_aborted_errors++; + + spin_lock_irqsave(&info->irq_spinlock,flags); + usc_stop_transmitter(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + netif_wake_queue(dev); +} + +/** + * called by device driver when transmit completes + * reenable network layer transmit if stopped + * + * info pointer to device instance information + */ +static void hdlcdev_tx_done(struct mgsl_struct *info) +{ + if (netif_queue_stopped(info->netdev)) + netif_wake_queue(info->netdev); +} + +/** + * called by device driver when frame received + * pass frame to network layer + * + * info pointer to device instance information + * buf pointer to buffer contianing frame data + * size count of data bytes in buf + */ +static void hdlcdev_rx(struct mgsl_struct *info, char *buf, int size) +{ + struct sk_buff *skb = dev_alloc_skb(size); + struct net_device *dev = info->netdev; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("hdlcdev_rx(%s)\n", dev->name); + + if (skb == NULL) { + printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n", + dev->name); + dev->stats.rx_dropped++; + return; + } + + memcpy(skb_put(skb, size), buf, size); + + skb->protocol = hdlc_type_trans(skb, dev); + + dev->stats.rx_packets++; + dev->stats.rx_bytes += size; + + netif_rx(skb); +} + +static const struct net_device_ops hdlcdev_ops = { + .ndo_open = hdlcdev_open, + .ndo_stop = hdlcdev_close, + .ndo_change_mtu = hdlc_change_mtu, + .ndo_start_xmit = hdlc_start_xmit, + .ndo_do_ioctl = hdlcdev_ioctl, + .ndo_tx_timeout = hdlcdev_tx_timeout, +}; + +/** + * called by device driver when adding device instance + * do generic HDLC initialization + * + * info pointer to device instance information + * + * returns 0 if success, otherwise error code + */ +static int hdlcdev_init(struct mgsl_struct *info) +{ + int rc; + struct net_device *dev; + hdlc_device *hdlc; + + /* allocate and initialize network and HDLC layer objects */ + + if (!(dev = alloc_hdlcdev(info))) { + printk(KERN_ERR "%s:hdlc device allocation failure\n",__FILE__); + return -ENOMEM; + } + + /* for network layer reporting purposes only */ + dev->base_addr = info->io_base; + dev->irq = info->irq_level; + dev->dma = info->dma_level; + + /* network layer callbacks and settings */ + dev->netdev_ops = &hdlcdev_ops; + dev->watchdog_timeo = 10 * HZ; + dev->tx_queue_len = 50; + + /* generic HDLC layer callbacks and settings */ + hdlc = dev_to_hdlc(dev); + hdlc->attach = hdlcdev_attach; + hdlc->xmit = hdlcdev_xmit; + + /* register objects with HDLC layer */ + if ((rc = register_hdlc_device(dev))) { + printk(KERN_WARNING "%s:unable to register hdlc device\n",__FILE__); + free_netdev(dev); + return rc; + } + + info->netdev = dev; + return 0; +} + +/** + * called by device driver when removing device instance + * do generic HDLC cleanup + * + * info pointer to device instance information + */ +static void hdlcdev_exit(struct mgsl_struct *info) +{ + unregister_hdlc_device(info->netdev); + free_netdev(info->netdev); + info->netdev = NULL; +} + +#endif /* CONFIG_HDLC */ + + +static int __devinit synclink_init_one (struct pci_dev *dev, + const struct pci_device_id *ent) +{ + struct mgsl_struct *info; + + if (pci_enable_device(dev)) { + printk("error enabling pci device %p\n", dev); + return -EIO; + } + + if (!(info = mgsl_allocate_device())) { + printk("can't allocate device instance data.\n"); + return -EIO; + } + + /* Copy user configuration info to device instance data */ + + info->io_base = pci_resource_start(dev, 2); + info->irq_level = dev->irq; + info->phys_memory_base = pci_resource_start(dev, 3); + + /* Because veremap only works on page boundaries we must map + * a larger area than is actually implemented for the LCR + * memory range. We map a full page starting at the page boundary. + */ + info->phys_lcr_base = pci_resource_start(dev, 0); + info->lcr_offset = info->phys_lcr_base & (PAGE_SIZE-1); + info->phys_lcr_base &= ~(PAGE_SIZE-1); + + info->bus_type = MGSL_BUS_TYPE_PCI; + info->io_addr_size = 8; + info->irq_flags = IRQF_SHARED; + + if (dev->device == 0x0210) { + /* Version 1 PCI9030 based universal PCI adapter */ + info->misc_ctrl_value = 0x007c4080; + info->hw_version = 1; + } else { + /* Version 0 PCI9050 based 5V PCI adapter + * A PCI9050 bug prevents reading LCR registers if + * LCR base address bit 7 is set. Maintain shadow + * value so we can write to LCR misc control reg. + */ + info->misc_ctrl_value = 0x087e4546; + info->hw_version = 0; + } + + mgsl_add_device(info); + + return 0; +} + +static void __devexit synclink_remove_one (struct pci_dev *dev) +{ +} + diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c new file mode 100644 index 000000000000..a35dd549a008 --- /dev/null +++ b/drivers/tty/synclink_gt.c @@ -0,0 +1,5161 @@ +/* + * Device driver for Microgate SyncLink GT serial adapters. + * + * written by Paul Fulghum for Microgate Corporation + * paulkf@microgate.com + * + * Microgate and SyncLink are trademarks of Microgate Corporation + * + * This code is released under the GNU General Public License (GPL) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * DEBUG OUTPUT DEFINITIONS + * + * uncomment lines below to enable specific types of debug output + * + * DBGINFO information - most verbose output + * DBGERR serious errors + * DBGBH bottom half service routine debugging + * DBGISR interrupt service routine debugging + * DBGDATA output receive and transmit data + * DBGTBUF output transmit DMA buffers and registers + * DBGRBUF output receive DMA buffers and registers + */ + +#define DBGINFO(fmt) if (debug_level >= DEBUG_LEVEL_INFO) printk fmt +#define DBGERR(fmt) if (debug_level >= DEBUG_LEVEL_ERROR) printk fmt +#define DBGBH(fmt) if (debug_level >= DEBUG_LEVEL_BH) printk fmt +#define DBGISR(fmt) if (debug_level >= DEBUG_LEVEL_ISR) printk fmt +#define DBGDATA(info, buf, size, label) if (debug_level >= DEBUG_LEVEL_DATA) trace_block((info), (buf), (size), (label)) +/*#define DBGTBUF(info) dump_tbufs(info)*/ +/*#define DBGRBUF(info) dump_rbufs(info)*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_GT_MODULE)) +#define SYNCLINK_GENERIC_HDLC 1 +#else +#define SYNCLINK_GENERIC_HDLC 0 +#endif + +/* + * module identification + */ +static char *driver_name = "SyncLink GT"; +static char *tty_driver_name = "synclink_gt"; +static char *tty_dev_prefix = "ttySLG"; +MODULE_LICENSE("GPL"); +#define MGSL_MAGIC 0x5401 +#define MAX_DEVICES 32 + +static struct pci_device_id pci_table[] = { + {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, + {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT2_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, + {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT4_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, + {PCI_VENDOR_ID_MICROGATE, SYNCLINK_AC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, + {0,}, /* terminate list */ +}; +MODULE_DEVICE_TABLE(pci, pci_table); + +static int init_one(struct pci_dev *dev,const struct pci_device_id *ent); +static void remove_one(struct pci_dev *dev); +static struct pci_driver pci_driver = { + .name = "synclink_gt", + .id_table = pci_table, + .probe = init_one, + .remove = __devexit_p(remove_one), +}; + +static bool pci_registered; + +/* + * module configuration and status + */ +static struct slgt_info *slgt_device_list; +static int slgt_device_count; + +static int ttymajor; +static int debug_level; +static int maxframe[MAX_DEVICES]; + +module_param(ttymajor, int, 0); +module_param(debug_level, int, 0); +module_param_array(maxframe, int, NULL, 0); + +MODULE_PARM_DESC(ttymajor, "TTY major device number override: 0=auto assigned"); +MODULE_PARM_DESC(debug_level, "Debug syslog output: 0=disabled, 1 to 5=increasing detail"); +MODULE_PARM_DESC(maxframe, "Maximum frame size used by device (4096 to 65535)"); + +/* + * tty support and callbacks + */ +static struct tty_driver *serial_driver; + +static int open(struct tty_struct *tty, struct file * filp); +static void close(struct tty_struct *tty, struct file * filp); +static void hangup(struct tty_struct *tty); +static void set_termios(struct tty_struct *tty, struct ktermios *old_termios); + +static int write(struct tty_struct *tty, const unsigned char *buf, int count); +static int put_char(struct tty_struct *tty, unsigned char ch); +static void send_xchar(struct tty_struct *tty, char ch); +static void wait_until_sent(struct tty_struct *tty, int timeout); +static int write_room(struct tty_struct *tty); +static void flush_chars(struct tty_struct *tty); +static void flush_buffer(struct tty_struct *tty); +static void tx_hold(struct tty_struct *tty); +static void tx_release(struct tty_struct *tty); + +static int ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); +static int chars_in_buffer(struct tty_struct *tty); +static void throttle(struct tty_struct * tty); +static void unthrottle(struct tty_struct * tty); +static int set_break(struct tty_struct *tty, int break_state); + +/* + * generic HDLC support and callbacks + */ +#if SYNCLINK_GENERIC_HDLC +#define dev_to_port(D) (dev_to_hdlc(D)->priv) +static void hdlcdev_tx_done(struct slgt_info *info); +static void hdlcdev_rx(struct slgt_info *info, char *buf, int size); +static int hdlcdev_init(struct slgt_info *info); +static void hdlcdev_exit(struct slgt_info *info); +#endif + + +/* + * device specific structures, macros and functions + */ + +#define SLGT_MAX_PORTS 4 +#define SLGT_REG_SIZE 256 + +/* + * conditional wait facility + */ +struct cond_wait { + struct cond_wait *next; + wait_queue_head_t q; + wait_queue_t wait; + unsigned int data; +}; +static void init_cond_wait(struct cond_wait *w, unsigned int data); +static void add_cond_wait(struct cond_wait **head, struct cond_wait *w); +static void remove_cond_wait(struct cond_wait **head, struct cond_wait *w); +static void flush_cond_wait(struct cond_wait **head); + +/* + * DMA buffer descriptor and access macros + */ +struct slgt_desc +{ + __le16 count; + __le16 status; + __le32 pbuf; /* physical address of data buffer */ + __le32 next; /* physical address of next descriptor */ + + /* driver book keeping */ + char *buf; /* virtual address of data buffer */ + unsigned int pdesc; /* physical address of this descriptor */ + dma_addr_t buf_dma_addr; + unsigned short buf_count; +}; + +#define set_desc_buffer(a,b) (a).pbuf = cpu_to_le32((unsigned int)(b)) +#define set_desc_next(a,b) (a).next = cpu_to_le32((unsigned int)(b)) +#define set_desc_count(a,b)(a).count = cpu_to_le16((unsigned short)(b)) +#define set_desc_eof(a,b) (a).status = cpu_to_le16((b) ? (le16_to_cpu((a).status) | BIT0) : (le16_to_cpu((a).status) & ~BIT0)) +#define set_desc_status(a, b) (a).status = cpu_to_le16((unsigned short)(b)) +#define desc_count(a) (le16_to_cpu((a).count)) +#define desc_status(a) (le16_to_cpu((a).status)) +#define desc_complete(a) (le16_to_cpu((a).status) & BIT15) +#define desc_eof(a) (le16_to_cpu((a).status) & BIT2) +#define desc_crc_error(a) (le16_to_cpu((a).status) & BIT1) +#define desc_abort(a) (le16_to_cpu((a).status) & BIT0) +#define desc_residue(a) ((le16_to_cpu((a).status) & 0x38) >> 3) + +struct _input_signal_events { + int ri_up; + int ri_down; + int dsr_up; + int dsr_down; + int dcd_up; + int dcd_down; + int cts_up; + int cts_down; +}; + +/* + * device instance data structure + */ +struct slgt_info { + void *if_ptr; /* General purpose pointer (used by SPPP) */ + struct tty_port port; + + struct slgt_info *next_device; /* device list link */ + + int magic; + + char device_name[25]; + struct pci_dev *pdev; + + int port_count; /* count of ports on adapter */ + int adapter_num; /* adapter instance number */ + int port_num; /* port instance number */ + + /* array of pointers to port contexts on this adapter */ + struct slgt_info *port_array[SLGT_MAX_PORTS]; + + int line; /* tty line instance number */ + + struct mgsl_icount icount; + + int timeout; + int x_char; /* xon/xoff character */ + unsigned int read_status_mask; + unsigned int ignore_status_mask; + + wait_queue_head_t status_event_wait_q; + wait_queue_head_t event_wait_q; + struct timer_list tx_timer; + struct timer_list rx_timer; + + unsigned int gpio_present; + struct cond_wait *gpio_wait_q; + + spinlock_t lock; /* spinlock for synchronizing with ISR */ + + struct work_struct task; + u32 pending_bh; + bool bh_requested; + bool bh_running; + + int isr_overflow; + bool irq_requested; /* true if IRQ requested */ + bool irq_occurred; /* for diagnostics use */ + + /* device configuration */ + + unsigned int bus_type; + unsigned int irq_level; + unsigned long irq_flags; + + unsigned char __iomem * reg_addr; /* memory mapped registers address */ + u32 phys_reg_addr; + bool reg_addr_requested; + + MGSL_PARAMS params; /* communications parameters */ + u32 idle_mode; + u32 max_frame_size; /* as set by device config */ + + unsigned int rbuf_fill_level; + unsigned int rx_pio; + unsigned int if_mode; + unsigned int base_clock; + unsigned int xsync; + unsigned int xctrl; + + /* device status */ + + bool rx_enabled; + bool rx_restart; + + bool tx_enabled; + bool tx_active; + + unsigned char signals; /* serial signal states */ + int init_error; /* initialization error */ + + unsigned char *tx_buf; + int tx_count; + + char flag_buf[MAX_ASYNC_BUFFER_SIZE]; + char char_buf[MAX_ASYNC_BUFFER_SIZE]; + bool drop_rts_on_tx_done; + struct _input_signal_events input_signal_events; + + int dcd_chkcount; /* check counts to prevent */ + int cts_chkcount; /* too many IRQs if a signal */ + int dsr_chkcount; /* is floating */ + int ri_chkcount; + + char *bufs; /* virtual address of DMA buffer lists */ + dma_addr_t bufs_dma_addr; /* physical address of buffer descriptors */ + + unsigned int rbuf_count; + struct slgt_desc *rbufs; + unsigned int rbuf_current; + unsigned int rbuf_index; + unsigned int rbuf_fill_index; + unsigned short rbuf_fill_count; + + unsigned int tbuf_count; + struct slgt_desc *tbufs; + unsigned int tbuf_current; + unsigned int tbuf_start; + + unsigned char *tmp_rbuf; + unsigned int tmp_rbuf_count; + + /* SPPP/Cisco HDLC device parts */ + + int netcount; + spinlock_t netlock; +#if SYNCLINK_GENERIC_HDLC + struct net_device *netdev; +#endif + +}; + +static MGSL_PARAMS default_params = { + .mode = MGSL_MODE_HDLC, + .loopback = 0, + .flags = HDLC_FLAG_UNDERRUN_ABORT15, + .encoding = HDLC_ENCODING_NRZI_SPACE, + .clock_speed = 0, + .addr_filter = 0xff, + .crc_type = HDLC_CRC_16_CCITT, + .preamble_length = HDLC_PREAMBLE_LENGTH_8BITS, + .preamble = HDLC_PREAMBLE_PATTERN_NONE, + .data_rate = 9600, + .data_bits = 8, + .stop_bits = 1, + .parity = ASYNC_PARITY_NONE +}; + + +#define BH_RECEIVE 1 +#define BH_TRANSMIT 2 +#define BH_STATUS 4 +#define IO_PIN_SHUTDOWN_LIMIT 100 + +#define DMABUFSIZE 256 +#define DESC_LIST_SIZE 4096 + +#define MASK_PARITY BIT1 +#define MASK_FRAMING BIT0 +#define MASK_BREAK BIT14 +#define MASK_OVERRUN BIT4 + +#define GSR 0x00 /* global status */ +#define JCR 0x04 /* JTAG control */ +#define IODR 0x08 /* GPIO direction */ +#define IOER 0x0c /* GPIO interrupt enable */ +#define IOVR 0x10 /* GPIO value */ +#define IOSR 0x14 /* GPIO interrupt status */ +#define TDR 0x80 /* tx data */ +#define RDR 0x80 /* rx data */ +#define TCR 0x82 /* tx control */ +#define TIR 0x84 /* tx idle */ +#define TPR 0x85 /* tx preamble */ +#define RCR 0x86 /* rx control */ +#define VCR 0x88 /* V.24 control */ +#define CCR 0x89 /* clock control */ +#define BDR 0x8a /* baud divisor */ +#define SCR 0x8c /* serial control */ +#define SSR 0x8e /* serial status */ +#define RDCSR 0x90 /* rx DMA control/status */ +#define TDCSR 0x94 /* tx DMA control/status */ +#define RDDAR 0x98 /* rx DMA descriptor address */ +#define TDDAR 0x9c /* tx DMA descriptor address */ +#define XSR 0x40 /* extended sync pattern */ +#define XCR 0x44 /* extended control */ + +#define RXIDLE BIT14 +#define RXBREAK BIT14 +#define IRQ_TXDATA BIT13 +#define IRQ_TXIDLE BIT12 +#define IRQ_TXUNDER BIT11 /* HDLC */ +#define IRQ_RXDATA BIT10 +#define IRQ_RXIDLE BIT9 /* HDLC */ +#define IRQ_RXBREAK BIT9 /* async */ +#define IRQ_RXOVER BIT8 +#define IRQ_DSR BIT7 +#define IRQ_CTS BIT6 +#define IRQ_DCD BIT5 +#define IRQ_RI BIT4 +#define IRQ_ALL 0x3ff0 +#define IRQ_MASTER BIT0 + +#define slgt_irq_on(info, mask) \ + wr_reg16((info), SCR, (unsigned short)(rd_reg16((info), SCR) | (mask))) +#define slgt_irq_off(info, mask) \ + wr_reg16((info), SCR, (unsigned short)(rd_reg16((info), SCR) & ~(mask))) + +static __u8 rd_reg8(struct slgt_info *info, unsigned int addr); +static void wr_reg8(struct slgt_info *info, unsigned int addr, __u8 value); +static __u16 rd_reg16(struct slgt_info *info, unsigned int addr); +static void wr_reg16(struct slgt_info *info, unsigned int addr, __u16 value); +static __u32 rd_reg32(struct slgt_info *info, unsigned int addr); +static void wr_reg32(struct slgt_info *info, unsigned int addr, __u32 value); + +static void msc_set_vcr(struct slgt_info *info); + +static int startup(struct slgt_info *info); +static int block_til_ready(struct tty_struct *tty, struct file * filp,struct slgt_info *info); +static void shutdown(struct slgt_info *info); +static void program_hw(struct slgt_info *info); +static void change_params(struct slgt_info *info); + +static int register_test(struct slgt_info *info); +static int irq_test(struct slgt_info *info); +static int loopback_test(struct slgt_info *info); +static int adapter_test(struct slgt_info *info); + +static void reset_adapter(struct slgt_info *info); +static void reset_port(struct slgt_info *info); +static void async_mode(struct slgt_info *info); +static void sync_mode(struct slgt_info *info); + +static void rx_stop(struct slgt_info *info); +static void rx_start(struct slgt_info *info); +static void reset_rbufs(struct slgt_info *info); +static void free_rbufs(struct slgt_info *info, unsigned int first, unsigned int last); +static void rdma_reset(struct slgt_info *info); +static bool rx_get_frame(struct slgt_info *info); +static bool rx_get_buf(struct slgt_info *info); + +static void tx_start(struct slgt_info *info); +static void tx_stop(struct slgt_info *info); +static void tx_set_idle(struct slgt_info *info); +static unsigned int free_tbuf_count(struct slgt_info *info); +static unsigned int tbuf_bytes(struct slgt_info *info); +static void reset_tbufs(struct slgt_info *info); +static void tdma_reset(struct slgt_info *info); +static bool tx_load(struct slgt_info *info, const char *buf, unsigned int count); + +static void get_signals(struct slgt_info *info); +static void set_signals(struct slgt_info *info); +static void enable_loopback(struct slgt_info *info); +static void set_rate(struct slgt_info *info, u32 data_rate); + +static int bh_action(struct slgt_info *info); +static void bh_handler(struct work_struct *work); +static void bh_transmit(struct slgt_info *info); +static void isr_serial(struct slgt_info *info); +static void isr_rdma(struct slgt_info *info); +static void isr_txeom(struct slgt_info *info, unsigned short status); +static void isr_tdma(struct slgt_info *info); + +static int alloc_dma_bufs(struct slgt_info *info); +static void free_dma_bufs(struct slgt_info *info); +static int alloc_desc(struct slgt_info *info); +static void free_desc(struct slgt_info *info); +static int alloc_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count); +static void free_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count); + +static int alloc_tmp_rbuf(struct slgt_info *info); +static void free_tmp_rbuf(struct slgt_info *info); + +static void tx_timeout(unsigned long context); +static void rx_timeout(unsigned long context); + +/* + * ioctl handlers + */ +static int get_stats(struct slgt_info *info, struct mgsl_icount __user *user_icount); +static int get_params(struct slgt_info *info, MGSL_PARAMS __user *params); +static int set_params(struct slgt_info *info, MGSL_PARAMS __user *params); +static int get_txidle(struct slgt_info *info, int __user *idle_mode); +static int set_txidle(struct slgt_info *info, int idle_mode); +static int tx_enable(struct slgt_info *info, int enable); +static int tx_abort(struct slgt_info *info); +static int rx_enable(struct slgt_info *info, int enable); +static int modem_input_wait(struct slgt_info *info,int arg); +static int wait_mgsl_event(struct slgt_info *info, int __user *mask_ptr); +static int tiocmget(struct tty_struct *tty); +static int tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear); +static int set_break(struct tty_struct *tty, int break_state); +static int get_interface(struct slgt_info *info, int __user *if_mode); +static int set_interface(struct slgt_info *info, int if_mode); +static int set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); +static int get_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); +static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); +static int get_xsync(struct slgt_info *info, int __user *if_mode); +static int set_xsync(struct slgt_info *info, int if_mode); +static int get_xctrl(struct slgt_info *info, int __user *if_mode); +static int set_xctrl(struct slgt_info *info, int if_mode); + +/* + * driver functions + */ +static void add_device(struct slgt_info *info); +static void device_init(int adapter_num, struct pci_dev *pdev); +static int claim_resources(struct slgt_info *info); +static void release_resources(struct slgt_info *info); + +/* + * DEBUG OUTPUT CODE + */ +#ifndef DBGINFO +#define DBGINFO(fmt) +#endif +#ifndef DBGERR +#define DBGERR(fmt) +#endif +#ifndef DBGBH +#define DBGBH(fmt) +#endif +#ifndef DBGISR +#define DBGISR(fmt) +#endif + +#ifdef DBGDATA +static void trace_block(struct slgt_info *info, const char *data, int count, const char *label) +{ + int i; + int linecount; + printk("%s %s data:\n",info->device_name, label); + while(count) { + linecount = (count > 16) ? 16 : count; + for(i=0; i < linecount; i++) + printk("%02X ",(unsigned char)data[i]); + for(;i<17;i++) + printk(" "); + for(i=0;i=040 && data[i]<=0176) + printk("%c",data[i]); + else + printk("."); + } + printk("\n"); + data += linecount; + count -= linecount; + } +} +#else +#define DBGDATA(info, buf, size, label) +#endif + +#ifdef DBGTBUF +static void dump_tbufs(struct slgt_info *info) +{ + int i; + printk("tbuf_current=%d\n", info->tbuf_current); + for (i=0 ; i < info->tbuf_count ; i++) { + printk("%d: count=%04X status=%04X\n", + i, le16_to_cpu(info->tbufs[i].count), le16_to_cpu(info->tbufs[i].status)); + } +} +#else +#define DBGTBUF(info) +#endif + +#ifdef DBGRBUF +static void dump_rbufs(struct slgt_info *info) +{ + int i; + printk("rbuf_current=%d\n", info->rbuf_current); + for (i=0 ; i < info->rbuf_count ; i++) { + printk("%d: count=%04X status=%04X\n", + i, le16_to_cpu(info->rbufs[i].count), le16_to_cpu(info->rbufs[i].status)); + } +} +#else +#define DBGRBUF(info) +#endif + +static inline int sanity_check(struct slgt_info *info, char *devname, const char *name) +{ +#ifdef SANITY_CHECK + if (!info) { + printk("null struct slgt_info for (%s) in %s\n", devname, name); + return 1; + } + if (info->magic != MGSL_MAGIC) { + printk("bad magic number struct slgt_info (%s) in %s\n", devname, name); + return 1; + } +#else + if (!info) + return 1; +#endif + return 0; +} + +/** + * line discipline callback wrappers + * + * The wrappers maintain line discipline references + * while calling into the line discipline. + * + * ldisc_receive_buf - pass receive data to line discipline + */ +static void ldisc_receive_buf(struct tty_struct *tty, + const __u8 *data, char *flags, int count) +{ + struct tty_ldisc *ld; + if (!tty) + return; + ld = tty_ldisc_ref(tty); + if (ld) { + if (ld->ops->receive_buf) + ld->ops->receive_buf(tty, data, flags, count); + tty_ldisc_deref(ld); + } +} + +/* tty callbacks */ + +static int open(struct tty_struct *tty, struct file *filp) +{ + struct slgt_info *info; + int retval, line; + unsigned long flags; + + line = tty->index; + if ((line < 0) || (line >= slgt_device_count)) { + DBGERR(("%s: open with invalid line #%d.\n", driver_name, line)); + return -ENODEV; + } + + info = slgt_device_list; + while(info && info->line != line) + info = info->next_device; + if (sanity_check(info, tty->name, "open")) + return -ENODEV; + if (info->init_error) { + DBGERR(("%s init error=%d\n", info->device_name, info->init_error)); + return -ENODEV; + } + + tty->driver_data = info; + info->port.tty = tty; + + DBGINFO(("%s open, old ref count = %d\n", info->device_name, info->port.count)); + + /* If port is closing, signal caller to try again */ + if (tty_hung_up_p(filp) || info->port.flags & ASYNC_CLOSING){ + if (info->port.flags & ASYNC_CLOSING) + interruptible_sleep_on(&info->port.close_wait); + retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS); + goto cleanup; + } + + mutex_lock(&info->port.mutex); + info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; + + spin_lock_irqsave(&info->netlock, flags); + if (info->netcount) { + retval = -EBUSY; + spin_unlock_irqrestore(&info->netlock, flags); + mutex_unlock(&info->port.mutex); + goto cleanup; + } + info->port.count++; + spin_unlock_irqrestore(&info->netlock, flags); + + if (info->port.count == 1) { + /* 1st open on this device, init hardware */ + retval = startup(info); + if (retval < 0) { + mutex_unlock(&info->port.mutex); + goto cleanup; + } + } + mutex_unlock(&info->port.mutex); + retval = block_til_ready(tty, filp, info); + if (retval) { + DBGINFO(("%s block_til_ready rc=%d\n", info->device_name, retval)); + goto cleanup; + } + + retval = 0; + +cleanup: + if (retval) { + if (tty->count == 1) + info->port.tty = NULL; /* tty layer will release tty struct */ + if(info->port.count) + info->port.count--; + } + + DBGINFO(("%s open rc=%d\n", info->device_name, retval)); + return retval; +} + +static void close(struct tty_struct *tty, struct file *filp) +{ + struct slgt_info *info = tty->driver_data; + + if (sanity_check(info, tty->name, "close")) + return; + DBGINFO(("%s close entry, count=%d\n", info->device_name, info->port.count)); + + if (tty_port_close_start(&info->port, tty, filp) == 0) + goto cleanup; + + mutex_lock(&info->port.mutex); + if (info->port.flags & ASYNC_INITIALIZED) + wait_until_sent(tty, info->timeout); + flush_buffer(tty); + tty_ldisc_flush(tty); + + shutdown(info); + mutex_unlock(&info->port.mutex); + + tty_port_close_end(&info->port, tty); + info->port.tty = NULL; +cleanup: + DBGINFO(("%s close exit, count=%d\n", tty->driver->name, info->port.count)); +} + +static void hangup(struct tty_struct *tty) +{ + struct slgt_info *info = tty->driver_data; + unsigned long flags; + + if (sanity_check(info, tty->name, "hangup")) + return; + DBGINFO(("%s hangup\n", info->device_name)); + + flush_buffer(tty); + + mutex_lock(&info->port.mutex); + shutdown(info); + + spin_lock_irqsave(&info->port.lock, flags); + info->port.count = 0; + info->port.flags &= ~ASYNC_NORMAL_ACTIVE; + info->port.tty = NULL; + spin_unlock_irqrestore(&info->port.lock, flags); + mutex_unlock(&info->port.mutex); + + wake_up_interruptible(&info->port.open_wait); +} + +static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) +{ + struct slgt_info *info = tty->driver_data; + unsigned long flags; + + DBGINFO(("%s set_termios\n", tty->driver->name)); + + change_params(info); + + /* Handle transition to B0 status */ + if (old_termios->c_cflag & CBAUD && + !(tty->termios->c_cflag & CBAUD)) { + info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); + spin_lock_irqsave(&info->lock,flags); + set_signals(info); + spin_unlock_irqrestore(&info->lock,flags); + } + + /* Handle transition away from B0 status */ + if (!(old_termios->c_cflag & CBAUD) && + tty->termios->c_cflag & CBAUD) { + info->signals |= SerialSignal_DTR; + if (!(tty->termios->c_cflag & CRTSCTS) || + !test_bit(TTY_THROTTLED, &tty->flags)) { + info->signals |= SerialSignal_RTS; + } + spin_lock_irqsave(&info->lock,flags); + set_signals(info); + spin_unlock_irqrestore(&info->lock,flags); + } + + /* Handle turning off CRTSCTS */ + if (old_termios->c_cflag & CRTSCTS && + !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + tx_release(tty); + } +} + +static void update_tx_timer(struct slgt_info *info) +{ + /* + * use worst case speed of 1200bps to calculate transmit timeout + * based on data in buffers (tbuf_bytes) and FIFO (128 bytes) + */ + if (info->params.mode == MGSL_MODE_HDLC) { + int timeout = (tbuf_bytes(info) * 7) + 1000; + mod_timer(&info->tx_timer, jiffies + msecs_to_jiffies(timeout)); + } +} + +static int write(struct tty_struct *tty, + const unsigned char *buf, int count) +{ + int ret = 0; + struct slgt_info *info = tty->driver_data; + unsigned long flags; + + if (sanity_check(info, tty->name, "write")) + return -EIO; + + DBGINFO(("%s write count=%d\n", info->device_name, count)); + + if (!info->tx_buf || (count > info->max_frame_size)) + return -EIO; + + if (!count || tty->stopped || tty->hw_stopped) + return 0; + + spin_lock_irqsave(&info->lock, flags); + + if (info->tx_count) { + /* send accumulated data from send_char() */ + if (!tx_load(info, info->tx_buf, info->tx_count)) + goto cleanup; + info->tx_count = 0; + } + + if (tx_load(info, buf, count)) + ret = count; + +cleanup: + spin_unlock_irqrestore(&info->lock, flags); + DBGINFO(("%s write rc=%d\n", info->device_name, ret)); + return ret; +} + +static int put_char(struct tty_struct *tty, unsigned char ch) +{ + struct slgt_info *info = tty->driver_data; + unsigned long flags; + int ret = 0; + + if (sanity_check(info, tty->name, "put_char")) + return 0; + DBGINFO(("%s put_char(%d)\n", info->device_name, ch)); + if (!info->tx_buf) + return 0; + spin_lock_irqsave(&info->lock,flags); + if (info->tx_count < info->max_frame_size) { + info->tx_buf[info->tx_count++] = ch; + ret = 1; + } + spin_unlock_irqrestore(&info->lock,flags); + return ret; +} + +static void send_xchar(struct tty_struct *tty, char ch) +{ + struct slgt_info *info = tty->driver_data; + unsigned long flags; + + if (sanity_check(info, tty->name, "send_xchar")) + return; + DBGINFO(("%s send_xchar(%d)\n", info->device_name, ch)); + info->x_char = ch; + if (ch) { + spin_lock_irqsave(&info->lock,flags); + if (!info->tx_enabled) + tx_start(info); + spin_unlock_irqrestore(&info->lock,flags); + } +} + +static void wait_until_sent(struct tty_struct *tty, int timeout) +{ + struct slgt_info *info = tty->driver_data; + unsigned long orig_jiffies, char_time; + + if (!info ) + return; + if (sanity_check(info, tty->name, "wait_until_sent")) + return; + DBGINFO(("%s wait_until_sent entry\n", info->device_name)); + if (!(info->port.flags & ASYNC_INITIALIZED)) + goto exit; + + orig_jiffies = jiffies; + + /* Set check interval to 1/5 of estimated time to + * send a character, and make it at least 1. The check + * interval should also be less than the timeout. + * Note: use tight timings here to satisfy the NIST-PCTS. + */ + + if (info->params.data_rate) { + char_time = info->timeout/(32 * 5); + if (!char_time) + char_time++; + } else + char_time = 1; + + if (timeout) + char_time = min_t(unsigned long, char_time, timeout); + + while (info->tx_active) { + msleep_interruptible(jiffies_to_msecs(char_time)); + if (signal_pending(current)) + break; + if (timeout && time_after(jiffies, orig_jiffies + timeout)) + break; + } +exit: + DBGINFO(("%s wait_until_sent exit\n", info->device_name)); +} + +static int write_room(struct tty_struct *tty) +{ + struct slgt_info *info = tty->driver_data; + int ret; + + if (sanity_check(info, tty->name, "write_room")) + return 0; + ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE; + DBGINFO(("%s write_room=%d\n", info->device_name, ret)); + return ret; +} + +static void flush_chars(struct tty_struct *tty) +{ + struct slgt_info *info = tty->driver_data; + unsigned long flags; + + if (sanity_check(info, tty->name, "flush_chars")) + return; + DBGINFO(("%s flush_chars entry tx_count=%d\n", info->device_name, info->tx_count)); + + if (info->tx_count <= 0 || tty->stopped || + tty->hw_stopped || !info->tx_buf) + return; + + DBGINFO(("%s flush_chars start transmit\n", info->device_name)); + + spin_lock_irqsave(&info->lock,flags); + if (info->tx_count && tx_load(info, info->tx_buf, info->tx_count)) + info->tx_count = 0; + spin_unlock_irqrestore(&info->lock,flags); +} + +static void flush_buffer(struct tty_struct *tty) +{ + struct slgt_info *info = tty->driver_data; + unsigned long flags; + + if (sanity_check(info, tty->name, "flush_buffer")) + return; + DBGINFO(("%s flush_buffer\n", info->device_name)); + + spin_lock_irqsave(&info->lock, flags); + info->tx_count = 0; + spin_unlock_irqrestore(&info->lock, flags); + + tty_wakeup(tty); +} + +/* + * throttle (stop) transmitter + */ +static void tx_hold(struct tty_struct *tty) +{ + struct slgt_info *info = tty->driver_data; + unsigned long flags; + + if (sanity_check(info, tty->name, "tx_hold")) + return; + DBGINFO(("%s tx_hold\n", info->device_name)); + spin_lock_irqsave(&info->lock,flags); + if (info->tx_enabled && info->params.mode == MGSL_MODE_ASYNC) + tx_stop(info); + spin_unlock_irqrestore(&info->lock,flags); +} + +/* + * release (start) transmitter + */ +static void tx_release(struct tty_struct *tty) +{ + struct slgt_info *info = tty->driver_data; + unsigned long flags; + + if (sanity_check(info, tty->name, "tx_release")) + return; + DBGINFO(("%s tx_release\n", info->device_name)); + spin_lock_irqsave(&info->lock, flags); + if (info->tx_count && tx_load(info, info->tx_buf, info->tx_count)) + info->tx_count = 0; + spin_unlock_irqrestore(&info->lock, flags); +} + +/* + * Service an IOCTL request + * + * Arguments + * + * tty pointer to tty instance data + * cmd IOCTL command code + * arg command argument/context + * + * Return 0 if success, otherwise error code + */ +static int ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + struct slgt_info *info = tty->driver_data; + void __user *argp = (void __user *)arg; + int ret; + + if (sanity_check(info, tty->name, "ioctl")) + return -ENODEV; + DBGINFO(("%s ioctl() cmd=%08X\n", info->device_name, cmd)); + + if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && + (cmd != TIOCMIWAIT)) { + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + } + + switch (cmd) { + case MGSL_IOCWAITEVENT: + return wait_mgsl_event(info, argp); + case TIOCMIWAIT: + return modem_input_wait(info,(int)arg); + case MGSL_IOCSGPIO: + return set_gpio(info, argp); + case MGSL_IOCGGPIO: + return get_gpio(info, argp); + case MGSL_IOCWAITGPIO: + return wait_gpio(info, argp); + case MGSL_IOCGXSYNC: + return get_xsync(info, argp); + case MGSL_IOCSXSYNC: + return set_xsync(info, (int)arg); + case MGSL_IOCGXCTRL: + return get_xctrl(info, argp); + case MGSL_IOCSXCTRL: + return set_xctrl(info, (int)arg); + } + mutex_lock(&info->port.mutex); + switch (cmd) { + case MGSL_IOCGPARAMS: + ret = get_params(info, argp); + break; + case MGSL_IOCSPARAMS: + ret = set_params(info, argp); + break; + case MGSL_IOCGTXIDLE: + ret = get_txidle(info, argp); + break; + case MGSL_IOCSTXIDLE: + ret = set_txidle(info, (int)arg); + break; + case MGSL_IOCTXENABLE: + ret = tx_enable(info, (int)arg); + break; + case MGSL_IOCRXENABLE: + ret = rx_enable(info, (int)arg); + break; + case MGSL_IOCTXABORT: + ret = tx_abort(info); + break; + case MGSL_IOCGSTATS: + ret = get_stats(info, argp); + break; + case MGSL_IOCGIF: + ret = get_interface(info, argp); + break; + case MGSL_IOCSIF: + ret = set_interface(info,(int)arg); + break; + default: + ret = -ENOIOCTLCMD; + } + mutex_unlock(&info->port.mutex); + return ret; +} + +static int get_icount(struct tty_struct *tty, + struct serial_icounter_struct *icount) + +{ + struct slgt_info *info = tty->driver_data; + struct mgsl_icount cnow; /* kernel counter temps */ + unsigned long flags; + + spin_lock_irqsave(&info->lock,flags); + cnow = info->icount; + spin_unlock_irqrestore(&info->lock,flags); + + icount->cts = cnow.cts; + icount->dsr = cnow.dsr; + icount->rng = cnow.rng; + icount->dcd = cnow.dcd; + icount->rx = cnow.rx; + icount->tx = cnow.tx; + icount->frame = cnow.frame; + icount->overrun = cnow.overrun; + icount->parity = cnow.parity; + icount->brk = cnow.brk; + icount->buf_overrun = cnow.buf_overrun; + + return 0; +} + +/* + * support for 32 bit ioctl calls on 64 bit systems + */ +#ifdef CONFIG_COMPAT +static long get_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *user_params) +{ + struct MGSL_PARAMS32 tmp_params; + + DBGINFO(("%s get_params32\n", info->device_name)); + memset(&tmp_params, 0, sizeof(tmp_params)); + tmp_params.mode = (compat_ulong_t)info->params.mode; + tmp_params.loopback = info->params.loopback; + tmp_params.flags = info->params.flags; + tmp_params.encoding = info->params.encoding; + tmp_params.clock_speed = (compat_ulong_t)info->params.clock_speed; + tmp_params.addr_filter = info->params.addr_filter; + tmp_params.crc_type = info->params.crc_type; + tmp_params.preamble_length = info->params.preamble_length; + tmp_params.preamble = info->params.preamble; + tmp_params.data_rate = (compat_ulong_t)info->params.data_rate; + tmp_params.data_bits = info->params.data_bits; + tmp_params.stop_bits = info->params.stop_bits; + tmp_params.parity = info->params.parity; + if (copy_to_user(user_params, &tmp_params, sizeof(struct MGSL_PARAMS32))) + return -EFAULT; + return 0; +} + +static long set_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *new_params) +{ + struct MGSL_PARAMS32 tmp_params; + + DBGINFO(("%s set_params32\n", info->device_name)); + if (copy_from_user(&tmp_params, new_params, sizeof(struct MGSL_PARAMS32))) + return -EFAULT; + + spin_lock(&info->lock); + if (tmp_params.mode == MGSL_MODE_BASE_CLOCK) { + info->base_clock = tmp_params.clock_speed; + } else { + info->params.mode = tmp_params.mode; + info->params.loopback = tmp_params.loopback; + info->params.flags = tmp_params.flags; + info->params.encoding = tmp_params.encoding; + info->params.clock_speed = tmp_params.clock_speed; + info->params.addr_filter = tmp_params.addr_filter; + info->params.crc_type = tmp_params.crc_type; + info->params.preamble_length = tmp_params.preamble_length; + info->params.preamble = tmp_params.preamble; + info->params.data_rate = tmp_params.data_rate; + info->params.data_bits = tmp_params.data_bits; + info->params.stop_bits = tmp_params.stop_bits; + info->params.parity = tmp_params.parity; + } + spin_unlock(&info->lock); + + program_hw(info); + + return 0; +} + +static long slgt_compat_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + struct slgt_info *info = tty->driver_data; + int rc = -ENOIOCTLCMD; + + if (sanity_check(info, tty->name, "compat_ioctl")) + return -ENODEV; + DBGINFO(("%s compat_ioctl() cmd=%08X\n", info->device_name, cmd)); + + switch (cmd) { + + case MGSL_IOCSPARAMS32: + rc = set_params32(info, compat_ptr(arg)); + break; + + case MGSL_IOCGPARAMS32: + rc = get_params32(info, compat_ptr(arg)); + break; + + case MGSL_IOCGPARAMS: + case MGSL_IOCSPARAMS: + case MGSL_IOCGTXIDLE: + case MGSL_IOCGSTATS: + case MGSL_IOCWAITEVENT: + case MGSL_IOCGIF: + case MGSL_IOCSGPIO: + case MGSL_IOCGGPIO: + case MGSL_IOCWAITGPIO: + case MGSL_IOCGXSYNC: + case MGSL_IOCGXCTRL: + case MGSL_IOCSTXIDLE: + case MGSL_IOCTXENABLE: + case MGSL_IOCRXENABLE: + case MGSL_IOCTXABORT: + case TIOCMIWAIT: + case MGSL_IOCSIF: + case MGSL_IOCSXSYNC: + case MGSL_IOCSXCTRL: + rc = ioctl(tty, cmd, arg); + break; + } + + DBGINFO(("%s compat_ioctl() cmd=%08X rc=%d\n", info->device_name, cmd, rc)); + return rc; +} +#else +#define slgt_compat_ioctl NULL +#endif /* ifdef CONFIG_COMPAT */ + +/* + * proc fs support + */ +static inline void line_info(struct seq_file *m, struct slgt_info *info) +{ + char stat_buf[30]; + unsigned long flags; + + seq_printf(m, "%s: IO=%08X IRQ=%d MaxFrameSize=%u\n", + info->device_name, info->phys_reg_addr, + info->irq_level, info->max_frame_size); + + /* output current serial signal states */ + spin_lock_irqsave(&info->lock,flags); + get_signals(info); + spin_unlock_irqrestore(&info->lock,flags); + + stat_buf[0] = 0; + stat_buf[1] = 0; + if (info->signals & SerialSignal_RTS) + strcat(stat_buf, "|RTS"); + if (info->signals & SerialSignal_CTS) + strcat(stat_buf, "|CTS"); + if (info->signals & SerialSignal_DTR) + strcat(stat_buf, "|DTR"); + if (info->signals & SerialSignal_DSR) + strcat(stat_buf, "|DSR"); + if (info->signals & SerialSignal_DCD) + strcat(stat_buf, "|CD"); + if (info->signals & SerialSignal_RI) + strcat(stat_buf, "|RI"); + + if (info->params.mode != MGSL_MODE_ASYNC) { + seq_printf(m, "\tHDLC txok:%d rxok:%d", + info->icount.txok, info->icount.rxok); + if (info->icount.txunder) + seq_printf(m, " txunder:%d", info->icount.txunder); + if (info->icount.txabort) + seq_printf(m, " txabort:%d", info->icount.txabort); + if (info->icount.rxshort) + seq_printf(m, " rxshort:%d", info->icount.rxshort); + if (info->icount.rxlong) + seq_printf(m, " rxlong:%d", info->icount.rxlong); + if (info->icount.rxover) + seq_printf(m, " rxover:%d", info->icount.rxover); + if (info->icount.rxcrc) + seq_printf(m, " rxcrc:%d", info->icount.rxcrc); + } else { + seq_printf(m, "\tASYNC tx:%d rx:%d", + info->icount.tx, info->icount.rx); + if (info->icount.frame) + seq_printf(m, " fe:%d", info->icount.frame); + if (info->icount.parity) + seq_printf(m, " pe:%d", info->icount.parity); + if (info->icount.brk) + seq_printf(m, " brk:%d", info->icount.brk); + if (info->icount.overrun) + seq_printf(m, " oe:%d", info->icount.overrun); + } + + /* Append serial signal status to end */ + seq_printf(m, " %s\n", stat_buf+1); + + seq_printf(m, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", + info->tx_active,info->bh_requested,info->bh_running, + info->pending_bh); +} + +/* Called to print information about devices + */ +static int synclink_gt_proc_show(struct seq_file *m, void *v) +{ + struct slgt_info *info; + + seq_puts(m, "synclink_gt driver\n"); + + info = slgt_device_list; + while( info ) { + line_info(m, info); + info = info->next_device; + } + return 0; +} + +static int synclink_gt_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, synclink_gt_proc_show, NULL); +} + +static const struct file_operations synclink_gt_proc_fops = { + .owner = THIS_MODULE, + .open = synclink_gt_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* + * return count of bytes in transmit buffer + */ +static int chars_in_buffer(struct tty_struct *tty) +{ + struct slgt_info *info = tty->driver_data; + int count; + if (sanity_check(info, tty->name, "chars_in_buffer")) + return 0; + count = tbuf_bytes(info); + DBGINFO(("%s chars_in_buffer()=%d\n", info->device_name, count)); + return count; +} + +/* + * signal remote device to throttle send data (our receive data) + */ +static void throttle(struct tty_struct * tty) +{ + struct slgt_info *info = tty->driver_data; + unsigned long flags; + + if (sanity_check(info, tty->name, "throttle")) + return; + DBGINFO(("%s throttle\n", info->device_name)); + if (I_IXOFF(tty)) + send_xchar(tty, STOP_CHAR(tty)); + if (tty->termios->c_cflag & CRTSCTS) { + spin_lock_irqsave(&info->lock,flags); + info->signals &= ~SerialSignal_RTS; + set_signals(info); + spin_unlock_irqrestore(&info->lock,flags); + } +} + +/* + * signal remote device to stop throttling send data (our receive data) + */ +static void unthrottle(struct tty_struct * tty) +{ + struct slgt_info *info = tty->driver_data; + unsigned long flags; + + if (sanity_check(info, tty->name, "unthrottle")) + return; + DBGINFO(("%s unthrottle\n", info->device_name)); + if (I_IXOFF(tty)) { + if (info->x_char) + info->x_char = 0; + else + send_xchar(tty, START_CHAR(tty)); + } + if (tty->termios->c_cflag & CRTSCTS) { + spin_lock_irqsave(&info->lock,flags); + info->signals |= SerialSignal_RTS; + set_signals(info); + spin_unlock_irqrestore(&info->lock,flags); + } +} + +/* + * set or clear transmit break condition + * break_state -1=set break condition, 0=clear + */ +static int set_break(struct tty_struct *tty, int break_state) +{ + struct slgt_info *info = tty->driver_data; + unsigned short value; + unsigned long flags; + + if (sanity_check(info, tty->name, "set_break")) + return -EINVAL; + DBGINFO(("%s set_break(%d)\n", info->device_name, break_state)); + + spin_lock_irqsave(&info->lock,flags); + value = rd_reg16(info, TCR); + if (break_state == -1) + value |= BIT6; + else + value &= ~BIT6; + wr_reg16(info, TCR, value); + spin_unlock_irqrestore(&info->lock,flags); + return 0; +} + +#if SYNCLINK_GENERIC_HDLC + +/** + * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) + * set encoding and frame check sequence (FCS) options + * + * dev pointer to network device structure + * encoding serial encoding setting + * parity FCS setting + * + * returns 0 if success, otherwise error code + */ +static int hdlcdev_attach(struct net_device *dev, unsigned short encoding, + unsigned short parity) +{ + struct slgt_info *info = dev_to_port(dev); + unsigned char new_encoding; + unsigned short new_crctype; + + /* return error if TTY interface open */ + if (info->port.count) + return -EBUSY; + + DBGINFO(("%s hdlcdev_attach\n", info->device_name)); + + switch (encoding) + { + case ENCODING_NRZ: new_encoding = HDLC_ENCODING_NRZ; break; + case ENCODING_NRZI: new_encoding = HDLC_ENCODING_NRZI_SPACE; break; + case ENCODING_FM_MARK: new_encoding = HDLC_ENCODING_BIPHASE_MARK; break; + case ENCODING_FM_SPACE: new_encoding = HDLC_ENCODING_BIPHASE_SPACE; break; + case ENCODING_MANCHESTER: new_encoding = HDLC_ENCODING_BIPHASE_LEVEL; break; + default: return -EINVAL; + } + + switch (parity) + { + case PARITY_NONE: new_crctype = HDLC_CRC_NONE; break; + case PARITY_CRC16_PR1_CCITT: new_crctype = HDLC_CRC_16_CCITT; break; + case PARITY_CRC32_PR1_CCITT: new_crctype = HDLC_CRC_32_CCITT; break; + default: return -EINVAL; + } + + info->params.encoding = new_encoding; + info->params.crc_type = new_crctype; + + /* if network interface up, reprogram hardware */ + if (info->netcount) + program_hw(info); + + return 0; +} + +/** + * called by generic HDLC layer to send frame + * + * skb socket buffer containing HDLC frame + * dev pointer to network device structure + */ +static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct slgt_info *info = dev_to_port(dev); + unsigned long flags; + + DBGINFO(("%s hdlc_xmit\n", dev->name)); + + if (!skb->len) + return NETDEV_TX_OK; + + /* stop sending until this frame completes */ + netif_stop_queue(dev); + + /* update network statistics */ + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + + /* save start time for transmit timeout detection */ + dev->trans_start = jiffies; + + spin_lock_irqsave(&info->lock, flags); + tx_load(info, skb->data, skb->len); + spin_unlock_irqrestore(&info->lock, flags); + + /* done with socket buffer, so free it */ + dev_kfree_skb(skb); + + return NETDEV_TX_OK; +} + +/** + * called by network layer when interface enabled + * claim resources and initialize hardware + * + * dev pointer to network device structure + * + * returns 0 if success, otherwise error code + */ +static int hdlcdev_open(struct net_device *dev) +{ + struct slgt_info *info = dev_to_port(dev); + int rc; + unsigned long flags; + + if (!try_module_get(THIS_MODULE)) + return -EBUSY; + + DBGINFO(("%s hdlcdev_open\n", dev->name)); + + /* generic HDLC layer open processing */ + if ((rc = hdlc_open(dev))) + return rc; + + /* arbitrate between network and tty opens */ + spin_lock_irqsave(&info->netlock, flags); + if (info->port.count != 0 || info->netcount != 0) { + DBGINFO(("%s hdlc_open busy\n", dev->name)); + spin_unlock_irqrestore(&info->netlock, flags); + return -EBUSY; + } + info->netcount=1; + spin_unlock_irqrestore(&info->netlock, flags); + + /* claim resources and init adapter */ + if ((rc = startup(info)) != 0) { + spin_lock_irqsave(&info->netlock, flags); + info->netcount=0; + spin_unlock_irqrestore(&info->netlock, flags); + return rc; + } + + /* assert DTR and RTS, apply hardware settings */ + info->signals |= SerialSignal_RTS + SerialSignal_DTR; + program_hw(info); + + /* enable network layer transmit */ + dev->trans_start = jiffies; + netif_start_queue(dev); + + /* inform generic HDLC layer of current DCD status */ + spin_lock_irqsave(&info->lock, flags); + get_signals(info); + spin_unlock_irqrestore(&info->lock, flags); + if (info->signals & SerialSignal_DCD) + netif_carrier_on(dev); + else + netif_carrier_off(dev); + return 0; +} + +/** + * called by network layer when interface is disabled + * shutdown hardware and release resources + * + * dev pointer to network device structure + * + * returns 0 if success, otherwise error code + */ +static int hdlcdev_close(struct net_device *dev) +{ + struct slgt_info *info = dev_to_port(dev); + unsigned long flags; + + DBGINFO(("%s hdlcdev_close\n", dev->name)); + + netif_stop_queue(dev); + + /* shutdown adapter and release resources */ + shutdown(info); + + hdlc_close(dev); + + spin_lock_irqsave(&info->netlock, flags); + info->netcount=0; + spin_unlock_irqrestore(&info->netlock, flags); + + module_put(THIS_MODULE); + return 0; +} + +/** + * called by network layer to process IOCTL call to network device + * + * dev pointer to network device structure + * ifr pointer to network interface request structure + * cmd IOCTL command code + * + * returns 0 if success, otherwise error code + */ +static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + const size_t size = sizeof(sync_serial_settings); + sync_serial_settings new_line; + sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; + struct slgt_info *info = dev_to_port(dev); + unsigned int flags; + + DBGINFO(("%s hdlcdev_ioctl\n", dev->name)); + + /* return error if TTY interface open */ + if (info->port.count) + return -EBUSY; + + if (cmd != SIOCWANDEV) + return hdlc_ioctl(dev, ifr, cmd); + + memset(&new_line, 0, sizeof(new_line)); + + switch(ifr->ifr_settings.type) { + case IF_GET_IFACE: /* return current sync_serial_settings */ + + ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL; + if (ifr->ifr_settings.size < size) { + ifr->ifr_settings.size = size; /* data size wanted */ + return -ENOBUFS; + } + + flags = info->params.flags & (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | + HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | + HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | + HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); + + switch (flags){ + case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN): new_line.clock_type = CLOCK_EXT; break; + case (HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG): new_line.clock_type = CLOCK_INT; break; + case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG): new_line.clock_type = CLOCK_TXINT; break; + case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN): new_line.clock_type = CLOCK_TXFROMRX; break; + default: new_line.clock_type = CLOCK_DEFAULT; + } + + new_line.clock_rate = info->params.clock_speed; + new_line.loopback = info->params.loopback ? 1:0; + + if (copy_to_user(line, &new_line, size)) + return -EFAULT; + return 0; + + case IF_IFACE_SYNC_SERIAL: /* set sync_serial_settings */ + + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + if (copy_from_user(&new_line, line, size)) + return -EFAULT; + + switch (new_line.clock_type) + { + case CLOCK_EXT: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN; break; + case CLOCK_TXFROMRX: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN; break; + case CLOCK_INT: flags = HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG; break; + case CLOCK_TXINT: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG; break; + case CLOCK_DEFAULT: flags = info->params.flags & + (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | + HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | + HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | + HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); break; + default: return -EINVAL; + } + + if (new_line.loopback != 0 && new_line.loopback != 1) + return -EINVAL; + + info->params.flags &= ~(HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | + HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | + HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | + HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); + info->params.flags |= flags; + + info->params.loopback = new_line.loopback; + + if (flags & (HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG)) + info->params.clock_speed = new_line.clock_rate; + else + info->params.clock_speed = 0; + + /* if network interface up, reprogram hardware */ + if (info->netcount) + program_hw(info); + return 0; + + default: + return hdlc_ioctl(dev, ifr, cmd); + } +} + +/** + * called by network layer when transmit timeout is detected + * + * dev pointer to network device structure + */ +static void hdlcdev_tx_timeout(struct net_device *dev) +{ + struct slgt_info *info = dev_to_port(dev); + unsigned long flags; + + DBGINFO(("%s hdlcdev_tx_timeout\n", dev->name)); + + dev->stats.tx_errors++; + dev->stats.tx_aborted_errors++; + + spin_lock_irqsave(&info->lock,flags); + tx_stop(info); + spin_unlock_irqrestore(&info->lock,flags); + + netif_wake_queue(dev); +} + +/** + * called by device driver when transmit completes + * reenable network layer transmit if stopped + * + * info pointer to device instance information + */ +static void hdlcdev_tx_done(struct slgt_info *info) +{ + if (netif_queue_stopped(info->netdev)) + netif_wake_queue(info->netdev); +} + +/** + * called by device driver when frame received + * pass frame to network layer + * + * info pointer to device instance information + * buf pointer to buffer contianing frame data + * size count of data bytes in buf + */ +static void hdlcdev_rx(struct slgt_info *info, char *buf, int size) +{ + struct sk_buff *skb = dev_alloc_skb(size); + struct net_device *dev = info->netdev; + + DBGINFO(("%s hdlcdev_rx\n", dev->name)); + + if (skb == NULL) { + DBGERR(("%s: can't alloc skb, drop packet\n", dev->name)); + dev->stats.rx_dropped++; + return; + } + + memcpy(skb_put(skb, size), buf, size); + + skb->protocol = hdlc_type_trans(skb, dev); + + dev->stats.rx_packets++; + dev->stats.rx_bytes += size; + + netif_rx(skb); +} + +static const struct net_device_ops hdlcdev_ops = { + .ndo_open = hdlcdev_open, + .ndo_stop = hdlcdev_close, + .ndo_change_mtu = hdlc_change_mtu, + .ndo_start_xmit = hdlc_start_xmit, + .ndo_do_ioctl = hdlcdev_ioctl, + .ndo_tx_timeout = hdlcdev_tx_timeout, +}; + +/** + * called by device driver when adding device instance + * do generic HDLC initialization + * + * info pointer to device instance information + * + * returns 0 if success, otherwise error code + */ +static int hdlcdev_init(struct slgt_info *info) +{ + int rc; + struct net_device *dev; + hdlc_device *hdlc; + + /* allocate and initialize network and HDLC layer objects */ + + if (!(dev = alloc_hdlcdev(info))) { + printk(KERN_ERR "%s hdlc device alloc failure\n", info->device_name); + return -ENOMEM; + } + + /* for network layer reporting purposes only */ + dev->mem_start = info->phys_reg_addr; + dev->mem_end = info->phys_reg_addr + SLGT_REG_SIZE - 1; + dev->irq = info->irq_level; + + /* network layer callbacks and settings */ + dev->netdev_ops = &hdlcdev_ops; + dev->watchdog_timeo = 10 * HZ; + dev->tx_queue_len = 50; + + /* generic HDLC layer callbacks and settings */ + hdlc = dev_to_hdlc(dev); + hdlc->attach = hdlcdev_attach; + hdlc->xmit = hdlcdev_xmit; + + /* register objects with HDLC layer */ + if ((rc = register_hdlc_device(dev))) { + printk(KERN_WARNING "%s:unable to register hdlc device\n",__FILE__); + free_netdev(dev); + return rc; + } + + info->netdev = dev; + return 0; +} + +/** + * called by device driver when removing device instance + * do generic HDLC cleanup + * + * info pointer to device instance information + */ +static void hdlcdev_exit(struct slgt_info *info) +{ + unregister_hdlc_device(info->netdev); + free_netdev(info->netdev); + info->netdev = NULL; +} + +#endif /* ifdef CONFIG_HDLC */ + +/* + * get async data from rx DMA buffers + */ +static void rx_async(struct slgt_info *info) +{ + struct tty_struct *tty = info->port.tty; + struct mgsl_icount *icount = &info->icount; + unsigned int start, end; + unsigned char *p; + unsigned char status; + struct slgt_desc *bufs = info->rbufs; + int i, count; + int chars = 0; + int stat; + unsigned char ch; + + start = end = info->rbuf_current; + + while(desc_complete(bufs[end])) { + count = desc_count(bufs[end]) - info->rbuf_index; + p = bufs[end].buf + info->rbuf_index; + + DBGISR(("%s rx_async count=%d\n", info->device_name, count)); + DBGDATA(info, p, count, "rx"); + + for(i=0 ; i < count; i+=2, p+=2) { + ch = *p; + icount->rx++; + + stat = 0; + + if ((status = *(p+1) & (BIT1 + BIT0))) { + if (status & BIT1) + icount->parity++; + else if (status & BIT0) + icount->frame++; + /* discard char if tty control flags say so */ + if (status & info->ignore_status_mask) + continue; + if (status & BIT1) + stat = TTY_PARITY; + else if (status & BIT0) + stat = TTY_FRAME; + } + if (tty) { + tty_insert_flip_char(tty, ch, stat); + chars++; + } + } + + if (i < count) { + /* receive buffer not completed */ + info->rbuf_index += i; + mod_timer(&info->rx_timer, jiffies + 1); + break; + } + + info->rbuf_index = 0; + free_rbufs(info, end, end); + + if (++end == info->rbuf_count) + end = 0; + + /* if entire list searched then no frame available */ + if (end == start) + break; + } + + if (tty && chars) + tty_flip_buffer_push(tty); +} + +/* + * return next bottom half action to perform + */ +static int bh_action(struct slgt_info *info) +{ + unsigned long flags; + int rc; + + spin_lock_irqsave(&info->lock,flags); + + if (info->pending_bh & BH_RECEIVE) { + info->pending_bh &= ~BH_RECEIVE; + rc = BH_RECEIVE; + } else if (info->pending_bh & BH_TRANSMIT) { + info->pending_bh &= ~BH_TRANSMIT; + rc = BH_TRANSMIT; + } else if (info->pending_bh & BH_STATUS) { + info->pending_bh &= ~BH_STATUS; + rc = BH_STATUS; + } else { + /* Mark BH routine as complete */ + info->bh_running = false; + info->bh_requested = false; + rc = 0; + } + + spin_unlock_irqrestore(&info->lock,flags); + + return rc; +} + +/* + * perform bottom half processing + */ +static void bh_handler(struct work_struct *work) +{ + struct slgt_info *info = container_of(work, struct slgt_info, task); + int action; + + if (!info) + return; + info->bh_running = true; + + while((action = bh_action(info))) { + switch (action) { + case BH_RECEIVE: + DBGBH(("%s bh receive\n", info->device_name)); + switch(info->params.mode) { + case MGSL_MODE_ASYNC: + rx_async(info); + break; + case MGSL_MODE_HDLC: + while(rx_get_frame(info)); + break; + case MGSL_MODE_RAW: + case MGSL_MODE_MONOSYNC: + case MGSL_MODE_BISYNC: + case MGSL_MODE_XSYNC: + while(rx_get_buf(info)); + break; + } + /* restart receiver if rx DMA buffers exhausted */ + if (info->rx_restart) + rx_start(info); + break; + case BH_TRANSMIT: + bh_transmit(info); + break; + case BH_STATUS: + DBGBH(("%s bh status\n", info->device_name)); + info->ri_chkcount = 0; + info->dsr_chkcount = 0; + info->dcd_chkcount = 0; + info->cts_chkcount = 0; + break; + default: + DBGBH(("%s unknown action\n", info->device_name)); + break; + } + } + DBGBH(("%s bh_handler exit\n", info->device_name)); +} + +static void bh_transmit(struct slgt_info *info) +{ + struct tty_struct *tty = info->port.tty; + + DBGBH(("%s bh_transmit\n", info->device_name)); + if (tty) + tty_wakeup(tty); +} + +static void dsr_change(struct slgt_info *info, unsigned short status) +{ + if (status & BIT3) { + info->signals |= SerialSignal_DSR; + info->input_signal_events.dsr_up++; + } else { + info->signals &= ~SerialSignal_DSR; + info->input_signal_events.dsr_down++; + } + DBGISR(("dsr_change %s signals=%04X\n", info->device_name, info->signals)); + if ((info->dsr_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { + slgt_irq_off(info, IRQ_DSR); + return; + } + info->icount.dsr++; + wake_up_interruptible(&info->status_event_wait_q); + wake_up_interruptible(&info->event_wait_q); + info->pending_bh |= BH_STATUS; +} + +static void cts_change(struct slgt_info *info, unsigned short status) +{ + if (status & BIT2) { + info->signals |= SerialSignal_CTS; + info->input_signal_events.cts_up++; + } else { + info->signals &= ~SerialSignal_CTS; + info->input_signal_events.cts_down++; + } + DBGISR(("cts_change %s signals=%04X\n", info->device_name, info->signals)); + if ((info->cts_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { + slgt_irq_off(info, IRQ_CTS); + return; + } + info->icount.cts++; + wake_up_interruptible(&info->status_event_wait_q); + wake_up_interruptible(&info->event_wait_q); + info->pending_bh |= BH_STATUS; + + if (info->port.flags & ASYNC_CTS_FLOW) { + if (info->port.tty) { + if (info->port.tty->hw_stopped) { + if (info->signals & SerialSignal_CTS) { + info->port.tty->hw_stopped = 0; + info->pending_bh |= BH_TRANSMIT; + return; + } + } else { + if (!(info->signals & SerialSignal_CTS)) + info->port.tty->hw_stopped = 1; + } + } + } +} + +static void dcd_change(struct slgt_info *info, unsigned short status) +{ + if (status & BIT1) { + info->signals |= SerialSignal_DCD; + info->input_signal_events.dcd_up++; + } else { + info->signals &= ~SerialSignal_DCD; + info->input_signal_events.dcd_down++; + } + DBGISR(("dcd_change %s signals=%04X\n", info->device_name, info->signals)); + if ((info->dcd_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { + slgt_irq_off(info, IRQ_DCD); + return; + } + info->icount.dcd++; +#if SYNCLINK_GENERIC_HDLC + if (info->netcount) { + if (info->signals & SerialSignal_DCD) + netif_carrier_on(info->netdev); + else + netif_carrier_off(info->netdev); + } +#endif + wake_up_interruptible(&info->status_event_wait_q); + wake_up_interruptible(&info->event_wait_q); + info->pending_bh |= BH_STATUS; + + if (info->port.flags & ASYNC_CHECK_CD) { + if (info->signals & SerialSignal_DCD) + wake_up_interruptible(&info->port.open_wait); + else { + if (info->port.tty) + tty_hangup(info->port.tty); + } + } +} + +static void ri_change(struct slgt_info *info, unsigned short status) +{ + if (status & BIT0) { + info->signals |= SerialSignal_RI; + info->input_signal_events.ri_up++; + } else { + info->signals &= ~SerialSignal_RI; + info->input_signal_events.ri_down++; + } + DBGISR(("ri_change %s signals=%04X\n", info->device_name, info->signals)); + if ((info->ri_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { + slgt_irq_off(info, IRQ_RI); + return; + } + info->icount.rng++; + wake_up_interruptible(&info->status_event_wait_q); + wake_up_interruptible(&info->event_wait_q); + info->pending_bh |= BH_STATUS; +} + +static void isr_rxdata(struct slgt_info *info) +{ + unsigned int count = info->rbuf_fill_count; + unsigned int i = info->rbuf_fill_index; + unsigned short reg; + + while (rd_reg16(info, SSR) & IRQ_RXDATA) { + reg = rd_reg16(info, RDR); + DBGISR(("isr_rxdata %s RDR=%04X\n", info->device_name, reg)); + if (desc_complete(info->rbufs[i])) { + /* all buffers full */ + rx_stop(info); + info->rx_restart = 1; + continue; + } + info->rbufs[i].buf[count++] = (unsigned char)reg; + /* async mode saves status byte to buffer for each data byte */ + if (info->params.mode == MGSL_MODE_ASYNC) + info->rbufs[i].buf[count++] = (unsigned char)(reg >> 8); + if (count == info->rbuf_fill_level || (reg & BIT10)) { + /* buffer full or end of frame */ + set_desc_count(info->rbufs[i], count); + set_desc_status(info->rbufs[i], BIT15 | (reg >> 8)); + info->rbuf_fill_count = count = 0; + if (++i == info->rbuf_count) + i = 0; + info->pending_bh |= BH_RECEIVE; + } + } + + info->rbuf_fill_index = i; + info->rbuf_fill_count = count; +} + +static void isr_serial(struct slgt_info *info) +{ + unsigned short status = rd_reg16(info, SSR); + + DBGISR(("%s isr_serial status=%04X\n", info->device_name, status)); + + wr_reg16(info, SSR, status); /* clear pending */ + + info->irq_occurred = true; + + if (info->params.mode == MGSL_MODE_ASYNC) { + if (status & IRQ_TXIDLE) { + if (info->tx_active) + isr_txeom(info, status); + } + if (info->rx_pio && (status & IRQ_RXDATA)) + isr_rxdata(info); + if ((status & IRQ_RXBREAK) && (status & RXBREAK)) { + info->icount.brk++; + /* process break detection if tty control allows */ + if (info->port.tty) { + if (!(status & info->ignore_status_mask)) { + if (info->read_status_mask & MASK_BREAK) { + tty_insert_flip_char(info->port.tty, 0, TTY_BREAK); + if (info->port.flags & ASYNC_SAK) + do_SAK(info->port.tty); + } + } + } + } + } else { + if (status & (IRQ_TXIDLE + IRQ_TXUNDER)) + isr_txeom(info, status); + if (info->rx_pio && (status & IRQ_RXDATA)) + isr_rxdata(info); + if (status & IRQ_RXIDLE) { + if (status & RXIDLE) + info->icount.rxidle++; + else + info->icount.exithunt++; + wake_up_interruptible(&info->event_wait_q); + } + + if (status & IRQ_RXOVER) + rx_start(info); + } + + if (status & IRQ_DSR) + dsr_change(info, status); + if (status & IRQ_CTS) + cts_change(info, status); + if (status & IRQ_DCD) + dcd_change(info, status); + if (status & IRQ_RI) + ri_change(info, status); +} + +static void isr_rdma(struct slgt_info *info) +{ + unsigned int status = rd_reg32(info, RDCSR); + + DBGISR(("%s isr_rdma status=%08x\n", info->device_name, status)); + + /* RDCSR (rx DMA control/status) + * + * 31..07 reserved + * 06 save status byte to DMA buffer + * 05 error + * 04 eol (end of list) + * 03 eob (end of buffer) + * 02 IRQ enable + * 01 reset + * 00 enable + */ + wr_reg32(info, RDCSR, status); /* clear pending */ + + if (status & (BIT5 + BIT4)) { + DBGISR(("%s isr_rdma rx_restart=1\n", info->device_name)); + info->rx_restart = true; + } + info->pending_bh |= BH_RECEIVE; +} + +static void isr_tdma(struct slgt_info *info) +{ + unsigned int status = rd_reg32(info, TDCSR); + + DBGISR(("%s isr_tdma status=%08x\n", info->device_name, status)); + + /* TDCSR (tx DMA control/status) + * + * 31..06 reserved + * 05 error + * 04 eol (end of list) + * 03 eob (end of buffer) + * 02 IRQ enable + * 01 reset + * 00 enable + */ + wr_reg32(info, TDCSR, status); /* clear pending */ + + if (status & (BIT5 + BIT4 + BIT3)) { + // another transmit buffer has completed + // run bottom half to get more send data from user + info->pending_bh |= BH_TRANSMIT; + } +} + +/* + * return true if there are unsent tx DMA buffers, otherwise false + * + * if there are unsent buffers then info->tbuf_start + * is set to index of first unsent buffer + */ +static bool unsent_tbufs(struct slgt_info *info) +{ + unsigned int i = info->tbuf_current; + bool rc = false; + + /* + * search backwards from last loaded buffer (precedes tbuf_current) + * for first unsent buffer (desc_count > 0) + */ + + do { + if (i) + i--; + else + i = info->tbuf_count - 1; + if (!desc_count(info->tbufs[i])) + break; + info->tbuf_start = i; + rc = true; + } while (i != info->tbuf_current); + + return rc; +} + +static void isr_txeom(struct slgt_info *info, unsigned short status) +{ + DBGISR(("%s txeom status=%04x\n", info->device_name, status)); + + slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER); + tdma_reset(info); + if (status & IRQ_TXUNDER) { + unsigned short val = rd_reg16(info, TCR); + wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */ + wr_reg16(info, TCR, val); /* clear reset bit */ + } + + if (info->tx_active) { + if (info->params.mode != MGSL_MODE_ASYNC) { + if (status & IRQ_TXUNDER) + info->icount.txunder++; + else if (status & IRQ_TXIDLE) + info->icount.txok++; + } + + if (unsent_tbufs(info)) { + tx_start(info); + update_tx_timer(info); + return; + } + info->tx_active = false; + + del_timer(&info->tx_timer); + + if (info->params.mode != MGSL_MODE_ASYNC && info->drop_rts_on_tx_done) { + info->signals &= ~SerialSignal_RTS; + info->drop_rts_on_tx_done = false; + set_signals(info); + } + +#if SYNCLINK_GENERIC_HDLC + if (info->netcount) + hdlcdev_tx_done(info); + else +#endif + { + if (info->port.tty && (info->port.tty->stopped || info->port.tty->hw_stopped)) { + tx_stop(info); + return; + } + info->pending_bh |= BH_TRANSMIT; + } + } +} + +static void isr_gpio(struct slgt_info *info, unsigned int changed, unsigned int state) +{ + struct cond_wait *w, *prev; + + /* wake processes waiting for specific transitions */ + for (w = info->gpio_wait_q, prev = NULL ; w != NULL ; w = w->next) { + if (w->data & changed) { + w->data = state; + wake_up_interruptible(&w->q); + if (prev != NULL) + prev->next = w->next; + else + info->gpio_wait_q = w->next; + } else + prev = w; + } +} + +/* interrupt service routine + * + * irq interrupt number + * dev_id device ID supplied during interrupt registration + */ +static irqreturn_t slgt_interrupt(int dummy, void *dev_id) +{ + struct slgt_info *info = dev_id; + unsigned int gsr; + unsigned int i; + + DBGISR(("slgt_interrupt irq=%d entry\n", info->irq_level)); + + while((gsr = rd_reg32(info, GSR) & 0xffffff00)) { + DBGISR(("%s gsr=%08x\n", info->device_name, gsr)); + info->irq_occurred = true; + for(i=0; i < info->port_count ; i++) { + if (info->port_array[i] == NULL) + continue; + spin_lock(&info->port_array[i]->lock); + if (gsr & (BIT8 << i)) + isr_serial(info->port_array[i]); + if (gsr & (BIT16 << (i*2))) + isr_rdma(info->port_array[i]); + if (gsr & (BIT17 << (i*2))) + isr_tdma(info->port_array[i]); + spin_unlock(&info->port_array[i]->lock); + } + } + + if (info->gpio_present) { + unsigned int state; + unsigned int changed; + spin_lock(&info->lock); + while ((changed = rd_reg32(info, IOSR)) != 0) { + DBGISR(("%s iosr=%08x\n", info->device_name, changed)); + /* read latched state of GPIO signals */ + state = rd_reg32(info, IOVR); + /* clear pending GPIO interrupt bits */ + wr_reg32(info, IOSR, changed); + for (i=0 ; i < info->port_count ; i++) { + if (info->port_array[i] != NULL) + isr_gpio(info->port_array[i], changed, state); + } + } + spin_unlock(&info->lock); + } + + for(i=0; i < info->port_count ; i++) { + struct slgt_info *port = info->port_array[i]; + if (port == NULL) + continue; + spin_lock(&port->lock); + if ((port->port.count || port->netcount) && + port->pending_bh && !port->bh_running && + !port->bh_requested) { + DBGISR(("%s bh queued\n", port->device_name)); + schedule_work(&port->task); + port->bh_requested = true; + } + spin_unlock(&port->lock); + } + + DBGISR(("slgt_interrupt irq=%d exit\n", info->irq_level)); + return IRQ_HANDLED; +} + +static int startup(struct slgt_info *info) +{ + DBGINFO(("%s startup\n", info->device_name)); + + if (info->port.flags & ASYNC_INITIALIZED) + return 0; + + if (!info->tx_buf) { + info->tx_buf = kmalloc(info->max_frame_size, GFP_KERNEL); + if (!info->tx_buf) { + DBGERR(("%s can't allocate tx buffer\n", info->device_name)); + return -ENOMEM; + } + } + + info->pending_bh = 0; + + memset(&info->icount, 0, sizeof(info->icount)); + + /* program hardware for current parameters */ + change_params(info); + + if (info->port.tty) + clear_bit(TTY_IO_ERROR, &info->port.tty->flags); + + info->port.flags |= ASYNC_INITIALIZED; + + return 0; +} + +/* + * called by close() and hangup() to shutdown hardware + */ +static void shutdown(struct slgt_info *info) +{ + unsigned long flags; + + if (!(info->port.flags & ASYNC_INITIALIZED)) + return; + + DBGINFO(("%s shutdown\n", info->device_name)); + + /* clear status wait queue because status changes */ + /* can't happen after shutting down the hardware */ + wake_up_interruptible(&info->status_event_wait_q); + wake_up_interruptible(&info->event_wait_q); + + del_timer_sync(&info->tx_timer); + del_timer_sync(&info->rx_timer); + + kfree(info->tx_buf); + info->tx_buf = NULL; + + spin_lock_irqsave(&info->lock,flags); + + tx_stop(info); + rx_stop(info); + + slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); + + if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) { + info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS); + set_signals(info); + } + + flush_cond_wait(&info->gpio_wait_q); + + spin_unlock_irqrestore(&info->lock,flags); + + if (info->port.tty) + set_bit(TTY_IO_ERROR, &info->port.tty->flags); + + info->port.flags &= ~ASYNC_INITIALIZED; +} + +static void program_hw(struct slgt_info *info) +{ + unsigned long flags; + + spin_lock_irqsave(&info->lock,flags); + + rx_stop(info); + tx_stop(info); + + if (info->params.mode != MGSL_MODE_ASYNC || + info->netcount) + sync_mode(info); + else + async_mode(info); + + set_signals(info); + + info->dcd_chkcount = 0; + info->cts_chkcount = 0; + info->ri_chkcount = 0; + info->dsr_chkcount = 0; + + slgt_irq_on(info, IRQ_DCD | IRQ_CTS | IRQ_DSR | IRQ_RI); + get_signals(info); + + if (info->netcount || + (info->port.tty && info->port.tty->termios->c_cflag & CREAD)) + rx_start(info); + + spin_unlock_irqrestore(&info->lock,flags); +} + +/* + * reconfigure adapter based on new parameters + */ +static void change_params(struct slgt_info *info) +{ + unsigned cflag; + int bits_per_char; + + if (!info->port.tty || !info->port.tty->termios) + return; + DBGINFO(("%s change_params\n", info->device_name)); + + cflag = info->port.tty->termios->c_cflag; + + /* if B0 rate (hangup) specified then negate DTR and RTS */ + /* otherwise assert DTR and RTS */ + if (cflag & CBAUD) + info->signals |= SerialSignal_RTS + SerialSignal_DTR; + else + info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); + + /* byte size and parity */ + + switch (cflag & CSIZE) { + case CS5: info->params.data_bits = 5; break; + case CS6: info->params.data_bits = 6; break; + case CS7: info->params.data_bits = 7; break; + case CS8: info->params.data_bits = 8; break; + default: info->params.data_bits = 7; break; + } + + info->params.stop_bits = (cflag & CSTOPB) ? 2 : 1; + + if (cflag & PARENB) + info->params.parity = (cflag & PARODD) ? ASYNC_PARITY_ODD : ASYNC_PARITY_EVEN; + else + info->params.parity = ASYNC_PARITY_NONE; + + /* calculate number of jiffies to transmit a full + * FIFO (32 bytes) at specified data rate + */ + bits_per_char = info->params.data_bits + + info->params.stop_bits + 1; + + info->params.data_rate = tty_get_baud_rate(info->port.tty); + + if (info->params.data_rate) { + info->timeout = (32*HZ*bits_per_char) / + info->params.data_rate; + } + info->timeout += HZ/50; /* Add .02 seconds of slop */ + + if (cflag & CRTSCTS) + info->port.flags |= ASYNC_CTS_FLOW; + else + info->port.flags &= ~ASYNC_CTS_FLOW; + + if (cflag & CLOCAL) + info->port.flags &= ~ASYNC_CHECK_CD; + else + info->port.flags |= ASYNC_CHECK_CD; + + /* process tty input control flags */ + + info->read_status_mask = IRQ_RXOVER; + if (I_INPCK(info->port.tty)) + info->read_status_mask |= MASK_PARITY | MASK_FRAMING; + if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) + info->read_status_mask |= MASK_BREAK; + if (I_IGNPAR(info->port.tty)) + info->ignore_status_mask |= MASK_PARITY | MASK_FRAMING; + if (I_IGNBRK(info->port.tty)) { + info->ignore_status_mask |= MASK_BREAK; + /* If ignoring parity and break indicators, ignore + * overruns too. (For real raw support). + */ + if (I_IGNPAR(info->port.tty)) + info->ignore_status_mask |= MASK_OVERRUN; + } + + program_hw(info); +} + +static int get_stats(struct slgt_info *info, struct mgsl_icount __user *user_icount) +{ + DBGINFO(("%s get_stats\n", info->device_name)); + if (!user_icount) { + memset(&info->icount, 0, sizeof(info->icount)); + } else { + if (copy_to_user(user_icount, &info->icount, sizeof(struct mgsl_icount))) + return -EFAULT; + } + return 0; +} + +static int get_params(struct slgt_info *info, MGSL_PARAMS __user *user_params) +{ + DBGINFO(("%s get_params\n", info->device_name)); + if (copy_to_user(user_params, &info->params, sizeof(MGSL_PARAMS))) + return -EFAULT; + return 0; +} + +static int set_params(struct slgt_info *info, MGSL_PARAMS __user *new_params) +{ + unsigned long flags; + MGSL_PARAMS tmp_params; + + DBGINFO(("%s set_params\n", info->device_name)); + if (copy_from_user(&tmp_params, new_params, sizeof(MGSL_PARAMS))) + return -EFAULT; + + spin_lock_irqsave(&info->lock, flags); + if (tmp_params.mode == MGSL_MODE_BASE_CLOCK) + info->base_clock = tmp_params.clock_speed; + else + memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS)); + spin_unlock_irqrestore(&info->lock, flags); + + program_hw(info); + + return 0; +} + +static int get_txidle(struct slgt_info *info, int __user *idle_mode) +{ + DBGINFO(("%s get_txidle=%d\n", info->device_name, info->idle_mode)); + if (put_user(info->idle_mode, idle_mode)) + return -EFAULT; + return 0; +} + +static int set_txidle(struct slgt_info *info, int idle_mode) +{ + unsigned long flags; + DBGINFO(("%s set_txidle(%d)\n", info->device_name, idle_mode)); + spin_lock_irqsave(&info->lock,flags); + info->idle_mode = idle_mode; + if (info->params.mode != MGSL_MODE_ASYNC) + tx_set_idle(info); + spin_unlock_irqrestore(&info->lock,flags); + return 0; +} + +static int tx_enable(struct slgt_info *info, int enable) +{ + unsigned long flags; + DBGINFO(("%s tx_enable(%d)\n", info->device_name, enable)); + spin_lock_irqsave(&info->lock,flags); + if (enable) { + if (!info->tx_enabled) + tx_start(info); + } else { + if (info->tx_enabled) + tx_stop(info); + } + spin_unlock_irqrestore(&info->lock,flags); + return 0; +} + +/* + * abort transmit HDLC frame + */ +static int tx_abort(struct slgt_info *info) +{ + unsigned long flags; + DBGINFO(("%s tx_abort\n", info->device_name)); + spin_lock_irqsave(&info->lock,flags); + tdma_reset(info); + spin_unlock_irqrestore(&info->lock,flags); + return 0; +} + +static int rx_enable(struct slgt_info *info, int enable) +{ + unsigned long flags; + unsigned int rbuf_fill_level; + DBGINFO(("%s rx_enable(%08x)\n", info->device_name, enable)); + spin_lock_irqsave(&info->lock,flags); + /* + * enable[31..16] = receive DMA buffer fill level + * 0 = noop (leave fill level unchanged) + * fill level must be multiple of 4 and <= buffer size + */ + rbuf_fill_level = ((unsigned int)enable) >> 16; + if (rbuf_fill_level) { + if ((rbuf_fill_level > DMABUFSIZE) || (rbuf_fill_level % 4)) { + spin_unlock_irqrestore(&info->lock, flags); + return -EINVAL; + } + info->rbuf_fill_level = rbuf_fill_level; + if (rbuf_fill_level < 128) + info->rx_pio = 1; /* PIO mode */ + else + info->rx_pio = 0; /* DMA mode */ + rx_stop(info); /* restart receiver to use new fill level */ + } + + /* + * enable[1..0] = receiver enable command + * 0 = disable + * 1 = enable + * 2 = enable or force hunt mode if already enabled + */ + enable &= 3; + if (enable) { + if (!info->rx_enabled) + rx_start(info); + else if (enable == 2) { + /* force hunt mode (write 1 to RCR[3]) */ + wr_reg16(info, RCR, rd_reg16(info, RCR) | BIT3); + } + } else { + if (info->rx_enabled) + rx_stop(info); + } + spin_unlock_irqrestore(&info->lock,flags); + return 0; +} + +/* + * wait for specified event to occur + */ +static int wait_mgsl_event(struct slgt_info *info, int __user *mask_ptr) +{ + unsigned long flags; + int s; + int rc=0; + struct mgsl_icount cprev, cnow; + int events; + int mask; + struct _input_signal_events oldsigs, newsigs; + DECLARE_WAITQUEUE(wait, current); + + if (get_user(mask, mask_ptr)) + return -EFAULT; + + DBGINFO(("%s wait_mgsl_event(%d)\n", info->device_name, mask)); + + spin_lock_irqsave(&info->lock,flags); + + /* return immediately if state matches requested events */ + get_signals(info); + s = info->signals; + + events = mask & + ( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) + + ((s & SerialSignal_DCD) ? MgslEvent_DcdActive:MgslEvent_DcdInactive) + + ((s & SerialSignal_CTS) ? MgslEvent_CtsActive:MgslEvent_CtsInactive) + + ((s & SerialSignal_RI) ? MgslEvent_RiActive :MgslEvent_RiInactive) ); + if (events) { + spin_unlock_irqrestore(&info->lock,flags); + goto exit; + } + + /* save current irq counts */ + cprev = info->icount; + oldsigs = info->input_signal_events; + + /* enable hunt and idle irqs if needed */ + if (mask & (MgslEvent_ExitHuntMode+MgslEvent_IdleReceived)) { + unsigned short val = rd_reg16(info, SCR); + if (!(val & IRQ_RXIDLE)) + wr_reg16(info, SCR, (unsigned short)(val | IRQ_RXIDLE)); + } + + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&info->event_wait_q, &wait); + + spin_unlock_irqrestore(&info->lock,flags); + + for(;;) { + schedule(); + if (signal_pending(current)) { + rc = -ERESTARTSYS; + break; + } + + /* get current irq counts */ + spin_lock_irqsave(&info->lock,flags); + cnow = info->icount; + newsigs = info->input_signal_events; + set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irqrestore(&info->lock,flags); + + /* if no change, wait aborted for some reason */ + if (newsigs.dsr_up == oldsigs.dsr_up && + newsigs.dsr_down == oldsigs.dsr_down && + newsigs.dcd_up == oldsigs.dcd_up && + newsigs.dcd_down == oldsigs.dcd_down && + newsigs.cts_up == oldsigs.cts_up && + newsigs.cts_down == oldsigs.cts_down && + newsigs.ri_up == oldsigs.ri_up && + newsigs.ri_down == oldsigs.ri_down && + cnow.exithunt == cprev.exithunt && + cnow.rxidle == cprev.rxidle) { + rc = -EIO; + break; + } + + events = mask & + ( (newsigs.dsr_up != oldsigs.dsr_up ? MgslEvent_DsrActive:0) + + (newsigs.dsr_down != oldsigs.dsr_down ? MgslEvent_DsrInactive:0) + + (newsigs.dcd_up != oldsigs.dcd_up ? MgslEvent_DcdActive:0) + + (newsigs.dcd_down != oldsigs.dcd_down ? MgslEvent_DcdInactive:0) + + (newsigs.cts_up != oldsigs.cts_up ? MgslEvent_CtsActive:0) + + (newsigs.cts_down != oldsigs.cts_down ? MgslEvent_CtsInactive:0) + + (newsigs.ri_up != oldsigs.ri_up ? MgslEvent_RiActive:0) + + (newsigs.ri_down != oldsigs.ri_down ? MgslEvent_RiInactive:0) + + (cnow.exithunt != cprev.exithunt ? MgslEvent_ExitHuntMode:0) + + (cnow.rxidle != cprev.rxidle ? MgslEvent_IdleReceived:0) ); + if (events) + break; + + cprev = cnow; + oldsigs = newsigs; + } + + remove_wait_queue(&info->event_wait_q, &wait); + set_current_state(TASK_RUNNING); + + + if (mask & (MgslEvent_ExitHuntMode + MgslEvent_IdleReceived)) { + spin_lock_irqsave(&info->lock,flags); + if (!waitqueue_active(&info->event_wait_q)) { + /* disable enable exit hunt mode/idle rcvd IRQs */ + wr_reg16(info, SCR, + (unsigned short)(rd_reg16(info, SCR) & ~IRQ_RXIDLE)); + } + spin_unlock_irqrestore(&info->lock,flags); + } +exit: + if (rc == 0) + rc = put_user(events, mask_ptr); + return rc; +} + +static int get_interface(struct slgt_info *info, int __user *if_mode) +{ + DBGINFO(("%s get_interface=%x\n", info->device_name, info->if_mode)); + if (put_user(info->if_mode, if_mode)) + return -EFAULT; + return 0; +} + +static int set_interface(struct slgt_info *info, int if_mode) +{ + unsigned long flags; + unsigned short val; + + DBGINFO(("%s set_interface=%x)\n", info->device_name, if_mode)); + spin_lock_irqsave(&info->lock,flags); + info->if_mode = if_mode; + + msc_set_vcr(info); + + /* TCR (tx control) 07 1=RTS driver control */ + val = rd_reg16(info, TCR); + if (info->if_mode & MGSL_INTERFACE_RTS_EN) + val |= BIT7; + else + val &= ~BIT7; + wr_reg16(info, TCR, val); + + spin_unlock_irqrestore(&info->lock,flags); + return 0; +} + +static int get_xsync(struct slgt_info *info, int __user *xsync) +{ + DBGINFO(("%s get_xsync=%x\n", info->device_name, info->xsync)); + if (put_user(info->xsync, xsync)) + return -EFAULT; + return 0; +} + +/* + * set extended sync pattern (1 to 4 bytes) for extended sync mode + * + * sync pattern is contained in least significant bytes of value + * most significant byte of sync pattern is oldest (1st sent/detected) + */ +static int set_xsync(struct slgt_info *info, int xsync) +{ + unsigned long flags; + + DBGINFO(("%s set_xsync=%x)\n", info->device_name, xsync)); + spin_lock_irqsave(&info->lock, flags); + info->xsync = xsync; + wr_reg32(info, XSR, xsync); + spin_unlock_irqrestore(&info->lock, flags); + return 0; +} + +static int get_xctrl(struct slgt_info *info, int __user *xctrl) +{ + DBGINFO(("%s get_xctrl=%x\n", info->device_name, info->xctrl)); + if (put_user(info->xctrl, xctrl)) + return -EFAULT; + return 0; +} + +/* + * set extended control options + * + * xctrl[31:19] reserved, must be zero + * xctrl[18:17] extended sync pattern length in bytes + * 00 = 1 byte in xsr[7:0] + * 01 = 2 bytes in xsr[15:0] + * 10 = 3 bytes in xsr[23:0] + * 11 = 4 bytes in xsr[31:0] + * xctrl[16] 1 = enable terminal count, 0=disabled + * xctrl[15:0] receive terminal count for fixed length packets + * value is count minus one (0 = 1 byte packet) + * when terminal count is reached, receiver + * automatically returns to hunt mode and receive + * FIFO contents are flushed to DMA buffers with + * end of frame (EOF) status + */ +static int set_xctrl(struct slgt_info *info, int xctrl) +{ + unsigned long flags; + + DBGINFO(("%s set_xctrl=%x)\n", info->device_name, xctrl)); + spin_lock_irqsave(&info->lock, flags); + info->xctrl = xctrl; + wr_reg32(info, XCR, xctrl); + spin_unlock_irqrestore(&info->lock, flags); + return 0; +} + +/* + * set general purpose IO pin state and direction + * + * user_gpio fields: + * state each bit indicates a pin state + * smask set bit indicates pin state to set + * dir each bit indicates a pin direction (0=input, 1=output) + * dmask set bit indicates pin direction to set + */ +static int set_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio) +{ + unsigned long flags; + struct gpio_desc gpio; + __u32 data; + + if (!info->gpio_present) + return -EINVAL; + if (copy_from_user(&gpio, user_gpio, sizeof(gpio))) + return -EFAULT; + DBGINFO(("%s set_gpio state=%08x smask=%08x dir=%08x dmask=%08x\n", + info->device_name, gpio.state, gpio.smask, + gpio.dir, gpio.dmask)); + + spin_lock_irqsave(&info->port_array[0]->lock, flags); + if (gpio.dmask) { + data = rd_reg32(info, IODR); + data |= gpio.dmask & gpio.dir; + data &= ~(gpio.dmask & ~gpio.dir); + wr_reg32(info, IODR, data); + } + if (gpio.smask) { + data = rd_reg32(info, IOVR); + data |= gpio.smask & gpio.state; + data &= ~(gpio.smask & ~gpio.state); + wr_reg32(info, IOVR, data); + } + spin_unlock_irqrestore(&info->port_array[0]->lock, flags); + + return 0; +} + +/* + * get general purpose IO pin state and direction + */ +static int get_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio) +{ + struct gpio_desc gpio; + if (!info->gpio_present) + return -EINVAL; + gpio.state = rd_reg32(info, IOVR); + gpio.smask = 0xffffffff; + gpio.dir = rd_reg32(info, IODR); + gpio.dmask = 0xffffffff; + if (copy_to_user(user_gpio, &gpio, sizeof(gpio))) + return -EFAULT; + DBGINFO(("%s get_gpio state=%08x dir=%08x\n", + info->device_name, gpio.state, gpio.dir)); + return 0; +} + +/* + * conditional wait facility + */ +static void init_cond_wait(struct cond_wait *w, unsigned int data) +{ + init_waitqueue_head(&w->q); + init_waitqueue_entry(&w->wait, current); + w->data = data; +} + +static void add_cond_wait(struct cond_wait **head, struct cond_wait *w) +{ + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&w->q, &w->wait); + w->next = *head; + *head = w; +} + +static void remove_cond_wait(struct cond_wait **head, struct cond_wait *cw) +{ + struct cond_wait *w, *prev; + remove_wait_queue(&cw->q, &cw->wait); + set_current_state(TASK_RUNNING); + for (w = *head, prev = NULL ; w != NULL ; prev = w, w = w->next) { + if (w == cw) { + if (prev != NULL) + prev->next = w->next; + else + *head = w->next; + break; + } + } +} + +static void flush_cond_wait(struct cond_wait **head) +{ + while (*head != NULL) { + wake_up_interruptible(&(*head)->q); + *head = (*head)->next; + } +} + +/* + * wait for general purpose I/O pin(s) to enter specified state + * + * user_gpio fields: + * state - bit indicates target pin state + * smask - set bit indicates watched pin + * + * The wait ends when at least one watched pin enters the specified + * state. When 0 (no error) is returned, user_gpio->state is set to the + * state of all GPIO pins when the wait ends. + * + * Note: Each pin may be a dedicated input, dedicated output, or + * configurable input/output. The number and configuration of pins + * varies with the specific adapter model. Only input pins (dedicated + * or configured) can be monitored with this function. + */ +static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio) +{ + unsigned long flags; + int rc = 0; + struct gpio_desc gpio; + struct cond_wait wait; + u32 state; + + if (!info->gpio_present) + return -EINVAL; + if (copy_from_user(&gpio, user_gpio, sizeof(gpio))) + return -EFAULT; + DBGINFO(("%s wait_gpio() state=%08x smask=%08x\n", + info->device_name, gpio.state, gpio.smask)); + /* ignore output pins identified by set IODR bit */ + if ((gpio.smask &= ~rd_reg32(info, IODR)) == 0) + return -EINVAL; + init_cond_wait(&wait, gpio.smask); + + spin_lock_irqsave(&info->port_array[0]->lock, flags); + /* enable interrupts for watched pins */ + wr_reg32(info, IOER, rd_reg32(info, IOER) | gpio.smask); + /* get current pin states */ + state = rd_reg32(info, IOVR); + + if (gpio.smask & ~(state ^ gpio.state)) { + /* already in target state */ + gpio.state = state; + } else { + /* wait for target state */ + add_cond_wait(&info->gpio_wait_q, &wait); + spin_unlock_irqrestore(&info->port_array[0]->lock, flags); + schedule(); + if (signal_pending(current)) + rc = -ERESTARTSYS; + else + gpio.state = wait.data; + spin_lock_irqsave(&info->port_array[0]->lock, flags); + remove_cond_wait(&info->gpio_wait_q, &wait); + } + + /* disable all GPIO interrupts if no waiting processes */ + if (info->gpio_wait_q == NULL) + wr_reg32(info, IOER, 0); + spin_unlock_irqrestore(&info->port_array[0]->lock, flags); + + if ((rc == 0) && copy_to_user(user_gpio, &gpio, sizeof(gpio))) + rc = -EFAULT; + return rc; +} + +static int modem_input_wait(struct slgt_info *info,int arg) +{ + unsigned long flags; + int rc; + struct mgsl_icount cprev, cnow; + DECLARE_WAITQUEUE(wait, current); + + /* save current irq counts */ + spin_lock_irqsave(&info->lock,flags); + cprev = info->icount; + add_wait_queue(&info->status_event_wait_q, &wait); + set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irqrestore(&info->lock,flags); + + for(;;) { + schedule(); + if (signal_pending(current)) { + rc = -ERESTARTSYS; + break; + } + + /* get new irq counts */ + spin_lock_irqsave(&info->lock,flags); + cnow = info->icount; + set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irqrestore(&info->lock,flags); + + /* if no change, wait aborted for some reason */ + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && + cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { + rc = -EIO; + break; + } + + /* check for change in caller specified modem input */ + if ((arg & TIOCM_RNG && cnow.rng != cprev.rng) || + (arg & TIOCM_DSR && cnow.dsr != cprev.dsr) || + (arg & TIOCM_CD && cnow.dcd != cprev.dcd) || + (arg & TIOCM_CTS && cnow.cts != cprev.cts)) { + rc = 0; + break; + } + + cprev = cnow; + } + remove_wait_queue(&info->status_event_wait_q, &wait); + set_current_state(TASK_RUNNING); + return rc; +} + +/* + * return state of serial control and status signals + */ +static int tiocmget(struct tty_struct *tty) +{ + struct slgt_info *info = tty->driver_data; + unsigned int result; + unsigned long flags; + + spin_lock_irqsave(&info->lock,flags); + get_signals(info); + spin_unlock_irqrestore(&info->lock,flags); + + result = ((info->signals & SerialSignal_RTS) ? TIOCM_RTS:0) + + ((info->signals & SerialSignal_DTR) ? TIOCM_DTR:0) + + ((info->signals & SerialSignal_DCD) ? TIOCM_CAR:0) + + ((info->signals & SerialSignal_RI) ? TIOCM_RNG:0) + + ((info->signals & SerialSignal_DSR) ? TIOCM_DSR:0) + + ((info->signals & SerialSignal_CTS) ? TIOCM_CTS:0); + + DBGINFO(("%s tiocmget value=%08X\n", info->device_name, result)); + return result; +} + +/* + * set modem control signals (DTR/RTS) + * + * cmd signal command: TIOCMBIS = set bit TIOCMBIC = clear bit + * TIOCMSET = set/clear signal values + * value bit mask for command + */ +static int tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + struct slgt_info *info = tty->driver_data; + unsigned long flags; + + DBGINFO(("%s tiocmset(%x,%x)\n", info->device_name, set, clear)); + + if (set & TIOCM_RTS) + info->signals |= SerialSignal_RTS; + if (set & TIOCM_DTR) + info->signals |= SerialSignal_DTR; + if (clear & TIOCM_RTS) + info->signals &= ~SerialSignal_RTS; + if (clear & TIOCM_DTR) + info->signals &= ~SerialSignal_DTR; + + spin_lock_irqsave(&info->lock,flags); + set_signals(info); + spin_unlock_irqrestore(&info->lock,flags); + return 0; +} + +static int carrier_raised(struct tty_port *port) +{ + unsigned long flags; + struct slgt_info *info = container_of(port, struct slgt_info, port); + + spin_lock_irqsave(&info->lock,flags); + get_signals(info); + spin_unlock_irqrestore(&info->lock,flags); + return (info->signals & SerialSignal_DCD) ? 1 : 0; +} + +static void dtr_rts(struct tty_port *port, int on) +{ + unsigned long flags; + struct slgt_info *info = container_of(port, struct slgt_info, port); + + spin_lock_irqsave(&info->lock,flags); + if (on) + info->signals |= SerialSignal_RTS + SerialSignal_DTR; + else + info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); + set_signals(info); + spin_unlock_irqrestore(&info->lock,flags); +} + + +/* + * block current process until the device is ready to open + */ +static int block_til_ready(struct tty_struct *tty, struct file *filp, + struct slgt_info *info) +{ + DECLARE_WAITQUEUE(wait, current); + int retval; + bool do_clocal = false; + bool extra_count = false; + unsigned long flags; + int cd; + struct tty_port *port = &info->port; + + DBGINFO(("%s block_til_ready\n", tty->driver->name)); + + if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ + /* nonblock mode is set or port is not enabled */ + port->flags |= ASYNC_NORMAL_ACTIVE; + return 0; + } + + if (tty->termios->c_cflag & CLOCAL) + do_clocal = true; + + /* Wait for carrier detect and the line to become + * free (i.e., not in use by the callout). While we are in + * this loop, port->count is dropped by one, so that + * close() knows when to free things. We restore it upon + * exit, either normal or abnormal. + */ + + retval = 0; + add_wait_queue(&port->open_wait, &wait); + + spin_lock_irqsave(&info->lock, flags); + if (!tty_hung_up_p(filp)) { + extra_count = true; + port->count--; + } + spin_unlock_irqrestore(&info->lock, flags); + port->blocked_open++; + + while (1) { + if ((tty->termios->c_cflag & CBAUD)) + tty_port_raise_dtr_rts(port); + + set_current_state(TASK_INTERRUPTIBLE); + + if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){ + retval = (port->flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS; + break; + } + + cd = tty_port_carrier_raised(port); + + if (!(port->flags & ASYNC_CLOSING) && (do_clocal || cd )) + break; + + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } + + DBGINFO(("%s block_til_ready wait\n", tty->driver->name)); + tty_unlock(); + schedule(); + tty_lock(); + } + + set_current_state(TASK_RUNNING); + remove_wait_queue(&port->open_wait, &wait); + + if (extra_count) + port->count++; + port->blocked_open--; + + if (!retval) + port->flags |= ASYNC_NORMAL_ACTIVE; + + DBGINFO(("%s block_til_ready ready, rc=%d\n", tty->driver->name, retval)); + return retval; +} + +static int alloc_tmp_rbuf(struct slgt_info *info) +{ + info->tmp_rbuf = kmalloc(info->max_frame_size + 5, GFP_KERNEL); + if (info->tmp_rbuf == NULL) + return -ENOMEM; + return 0; +} + +static void free_tmp_rbuf(struct slgt_info *info) +{ + kfree(info->tmp_rbuf); + info->tmp_rbuf = NULL; +} + +/* + * allocate DMA descriptor lists. + */ +static int alloc_desc(struct slgt_info *info) +{ + unsigned int i; + unsigned int pbufs; + + /* allocate memory to hold descriptor lists */ + info->bufs = pci_alloc_consistent(info->pdev, DESC_LIST_SIZE, &info->bufs_dma_addr); + if (info->bufs == NULL) + return -ENOMEM; + + memset(info->bufs, 0, DESC_LIST_SIZE); + + info->rbufs = (struct slgt_desc*)info->bufs; + info->tbufs = ((struct slgt_desc*)info->bufs) + info->rbuf_count; + + pbufs = (unsigned int)info->bufs_dma_addr; + + /* + * Build circular lists of descriptors + */ + + for (i=0; i < info->rbuf_count; i++) { + /* physical address of this descriptor */ + info->rbufs[i].pdesc = pbufs + (i * sizeof(struct slgt_desc)); + + /* physical address of next descriptor */ + if (i == info->rbuf_count - 1) + info->rbufs[i].next = cpu_to_le32(pbufs); + else + info->rbufs[i].next = cpu_to_le32(pbufs + ((i+1) * sizeof(struct slgt_desc))); + set_desc_count(info->rbufs[i], DMABUFSIZE); + } + + for (i=0; i < info->tbuf_count; i++) { + /* physical address of this descriptor */ + info->tbufs[i].pdesc = pbufs + ((info->rbuf_count + i) * sizeof(struct slgt_desc)); + + /* physical address of next descriptor */ + if (i == info->tbuf_count - 1) + info->tbufs[i].next = cpu_to_le32(pbufs + info->rbuf_count * sizeof(struct slgt_desc)); + else + info->tbufs[i].next = cpu_to_le32(pbufs + ((info->rbuf_count + i + 1) * sizeof(struct slgt_desc))); + } + + return 0; +} + +static void free_desc(struct slgt_info *info) +{ + if (info->bufs != NULL) { + pci_free_consistent(info->pdev, DESC_LIST_SIZE, info->bufs, info->bufs_dma_addr); + info->bufs = NULL; + info->rbufs = NULL; + info->tbufs = NULL; + } +} + +static int alloc_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count) +{ + int i; + for (i=0; i < count; i++) { + if ((bufs[i].buf = pci_alloc_consistent(info->pdev, DMABUFSIZE, &bufs[i].buf_dma_addr)) == NULL) + return -ENOMEM; + bufs[i].pbuf = cpu_to_le32((unsigned int)bufs[i].buf_dma_addr); + } + return 0; +} + +static void free_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count) +{ + int i; + for (i=0; i < count; i++) { + if (bufs[i].buf == NULL) + continue; + pci_free_consistent(info->pdev, DMABUFSIZE, bufs[i].buf, bufs[i].buf_dma_addr); + bufs[i].buf = NULL; + } +} + +static int alloc_dma_bufs(struct slgt_info *info) +{ + info->rbuf_count = 32; + info->tbuf_count = 32; + + if (alloc_desc(info) < 0 || + alloc_bufs(info, info->rbufs, info->rbuf_count) < 0 || + alloc_bufs(info, info->tbufs, info->tbuf_count) < 0 || + alloc_tmp_rbuf(info) < 0) { + DBGERR(("%s DMA buffer alloc fail\n", info->device_name)); + return -ENOMEM; + } + reset_rbufs(info); + return 0; +} + +static void free_dma_bufs(struct slgt_info *info) +{ + if (info->bufs) { + free_bufs(info, info->rbufs, info->rbuf_count); + free_bufs(info, info->tbufs, info->tbuf_count); + free_desc(info); + } + free_tmp_rbuf(info); +} + +static int claim_resources(struct slgt_info *info) +{ + if (request_mem_region(info->phys_reg_addr, SLGT_REG_SIZE, "synclink_gt") == NULL) { + DBGERR(("%s reg addr conflict, addr=%08X\n", + info->device_name, info->phys_reg_addr)); + info->init_error = DiagStatus_AddressConflict; + goto errout; + } + else + info->reg_addr_requested = true; + + info->reg_addr = ioremap_nocache(info->phys_reg_addr, SLGT_REG_SIZE); + if (!info->reg_addr) { + DBGERR(("%s cant map device registers, addr=%08X\n", + info->device_name, info->phys_reg_addr)); + info->init_error = DiagStatus_CantAssignPciResources; + goto errout; + } + return 0; + +errout: + release_resources(info); + return -ENODEV; +} + +static void release_resources(struct slgt_info *info) +{ + if (info->irq_requested) { + free_irq(info->irq_level, info); + info->irq_requested = false; + } + + if (info->reg_addr_requested) { + release_mem_region(info->phys_reg_addr, SLGT_REG_SIZE); + info->reg_addr_requested = false; + } + + if (info->reg_addr) { + iounmap(info->reg_addr); + info->reg_addr = NULL; + } +} + +/* Add the specified device instance data structure to the + * global linked list of devices and increment the device count. + */ +static void add_device(struct slgt_info *info) +{ + char *devstr; + + info->next_device = NULL; + info->line = slgt_device_count; + sprintf(info->device_name, "%s%d", tty_dev_prefix, info->line); + + if (info->line < MAX_DEVICES) { + if (maxframe[info->line]) + info->max_frame_size = maxframe[info->line]; + } + + slgt_device_count++; + + if (!slgt_device_list) + slgt_device_list = info; + else { + struct slgt_info *current_dev = slgt_device_list; + while(current_dev->next_device) + current_dev = current_dev->next_device; + current_dev->next_device = info; + } + + if (info->max_frame_size < 4096) + info->max_frame_size = 4096; + else if (info->max_frame_size > 65535) + info->max_frame_size = 65535; + + switch(info->pdev->device) { + case SYNCLINK_GT_DEVICE_ID: + devstr = "GT"; + break; + case SYNCLINK_GT2_DEVICE_ID: + devstr = "GT2"; + break; + case SYNCLINK_GT4_DEVICE_ID: + devstr = "GT4"; + break; + case SYNCLINK_AC_DEVICE_ID: + devstr = "AC"; + info->params.mode = MGSL_MODE_ASYNC; + break; + default: + devstr = "(unknown model)"; + } + printk("SyncLink %s %s IO=%08x IRQ=%d MaxFrameSize=%u\n", + devstr, info->device_name, info->phys_reg_addr, + info->irq_level, info->max_frame_size); + +#if SYNCLINK_GENERIC_HDLC + hdlcdev_init(info); +#endif +} + +static const struct tty_port_operations slgt_port_ops = { + .carrier_raised = carrier_raised, + .dtr_rts = dtr_rts, +}; + +/* + * allocate device instance structure, return NULL on failure + */ +static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev) +{ + struct slgt_info *info; + + info = kzalloc(sizeof(struct slgt_info), GFP_KERNEL); + + if (!info) { + DBGERR(("%s device alloc failed adapter=%d port=%d\n", + driver_name, adapter_num, port_num)); + } else { + tty_port_init(&info->port); + info->port.ops = &slgt_port_ops; + info->magic = MGSL_MAGIC; + INIT_WORK(&info->task, bh_handler); + info->max_frame_size = 4096; + info->base_clock = 14745600; + info->rbuf_fill_level = DMABUFSIZE; + info->port.close_delay = 5*HZ/10; + info->port.closing_wait = 30*HZ; + init_waitqueue_head(&info->status_event_wait_q); + init_waitqueue_head(&info->event_wait_q); + spin_lock_init(&info->netlock); + memcpy(&info->params,&default_params,sizeof(MGSL_PARAMS)); + info->idle_mode = HDLC_TXIDLE_FLAGS; + info->adapter_num = adapter_num; + info->port_num = port_num; + + setup_timer(&info->tx_timer, tx_timeout, (unsigned long)info); + setup_timer(&info->rx_timer, rx_timeout, (unsigned long)info); + + /* Copy configuration info to device instance data */ + info->pdev = pdev; + info->irq_level = pdev->irq; + info->phys_reg_addr = pci_resource_start(pdev,0); + + info->bus_type = MGSL_BUS_TYPE_PCI; + info->irq_flags = IRQF_SHARED; + + info->init_error = -1; /* assume error, set to 0 on successful init */ + } + + return info; +} + +static void device_init(int adapter_num, struct pci_dev *pdev) +{ + struct slgt_info *port_array[SLGT_MAX_PORTS]; + int i; + int port_count = 1; + + if (pdev->device == SYNCLINK_GT2_DEVICE_ID) + port_count = 2; + else if (pdev->device == SYNCLINK_GT4_DEVICE_ID) + port_count = 4; + + /* allocate device instances for all ports */ + for (i=0; i < port_count; ++i) { + port_array[i] = alloc_dev(adapter_num, i, pdev); + if (port_array[i] == NULL) { + for (--i; i >= 0; --i) + kfree(port_array[i]); + return; + } + } + + /* give copy of port_array to all ports and add to device list */ + for (i=0; i < port_count; ++i) { + memcpy(port_array[i]->port_array, port_array, sizeof(port_array)); + add_device(port_array[i]); + port_array[i]->port_count = port_count; + spin_lock_init(&port_array[i]->lock); + } + + /* Allocate and claim adapter resources */ + if (!claim_resources(port_array[0])) { + + alloc_dma_bufs(port_array[0]); + + /* copy resource information from first port to others */ + for (i = 1; i < port_count; ++i) { + port_array[i]->irq_level = port_array[0]->irq_level; + port_array[i]->reg_addr = port_array[0]->reg_addr; + alloc_dma_bufs(port_array[i]); + } + + if (request_irq(port_array[0]->irq_level, + slgt_interrupt, + port_array[0]->irq_flags, + port_array[0]->device_name, + port_array[0]) < 0) { + DBGERR(("%s request_irq failed IRQ=%d\n", + port_array[0]->device_name, + port_array[0]->irq_level)); + } else { + port_array[0]->irq_requested = true; + adapter_test(port_array[0]); + for (i=1 ; i < port_count ; i++) { + port_array[i]->init_error = port_array[0]->init_error; + port_array[i]->gpio_present = port_array[0]->gpio_present; + } + } + } + + for (i=0; i < port_count; ++i) + tty_register_device(serial_driver, port_array[i]->line, &(port_array[i]->pdev->dev)); +} + +static int __devinit init_one(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + if (pci_enable_device(dev)) { + printk("error enabling pci device %p\n", dev); + return -EIO; + } + pci_set_master(dev); + device_init(slgt_device_count, dev); + return 0; +} + +static void __devexit remove_one(struct pci_dev *dev) +{ +} + +static const struct tty_operations ops = { + .open = open, + .close = close, + .write = write, + .put_char = put_char, + .flush_chars = flush_chars, + .write_room = write_room, + .chars_in_buffer = chars_in_buffer, + .flush_buffer = flush_buffer, + .ioctl = ioctl, + .compat_ioctl = slgt_compat_ioctl, + .throttle = throttle, + .unthrottle = unthrottle, + .send_xchar = send_xchar, + .break_ctl = set_break, + .wait_until_sent = wait_until_sent, + .set_termios = set_termios, + .stop = tx_hold, + .start = tx_release, + .hangup = hangup, + .tiocmget = tiocmget, + .tiocmset = tiocmset, + .get_icount = get_icount, + .proc_fops = &synclink_gt_proc_fops, +}; + +static void slgt_cleanup(void) +{ + int rc; + struct slgt_info *info; + struct slgt_info *tmp; + + printk(KERN_INFO "unload %s\n", driver_name); + + if (serial_driver) { + for (info=slgt_device_list ; info != NULL ; info=info->next_device) + tty_unregister_device(serial_driver, info->line); + if ((rc = tty_unregister_driver(serial_driver))) + DBGERR(("tty_unregister_driver error=%d\n", rc)); + put_tty_driver(serial_driver); + } + + /* reset devices */ + info = slgt_device_list; + while(info) { + reset_port(info); + info = info->next_device; + } + + /* release devices */ + info = slgt_device_list; + while(info) { +#if SYNCLINK_GENERIC_HDLC + hdlcdev_exit(info); +#endif + free_dma_bufs(info); + free_tmp_rbuf(info); + if (info->port_num == 0) + release_resources(info); + tmp = info; + info = info->next_device; + kfree(tmp); + } + + if (pci_registered) + pci_unregister_driver(&pci_driver); +} + +/* + * Driver initialization entry point. + */ +static int __init slgt_init(void) +{ + int rc; + + printk(KERN_INFO "%s\n", driver_name); + + serial_driver = alloc_tty_driver(MAX_DEVICES); + if (!serial_driver) { + printk("%s can't allocate tty driver\n", driver_name); + return -ENOMEM; + } + + /* Initialize the tty_driver structure */ + + serial_driver->owner = THIS_MODULE; + serial_driver->driver_name = tty_driver_name; + serial_driver->name = tty_dev_prefix; + serial_driver->major = ttymajor; + serial_driver->minor_start = 64; + serial_driver->type = TTY_DRIVER_TYPE_SERIAL; + serial_driver->subtype = SERIAL_TYPE_NORMAL; + serial_driver->init_termios = tty_std_termios; + serial_driver->init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + serial_driver->init_termios.c_ispeed = 9600; + serial_driver->init_termios.c_ospeed = 9600; + serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + tty_set_operations(serial_driver, &ops); + if ((rc = tty_register_driver(serial_driver)) < 0) { + DBGERR(("%s can't register serial driver\n", driver_name)); + put_tty_driver(serial_driver); + serial_driver = NULL; + goto error; + } + + printk(KERN_INFO "%s, tty major#%d\n", + driver_name, serial_driver->major); + + slgt_device_count = 0; + if ((rc = pci_register_driver(&pci_driver)) < 0) { + printk("%s pci_register_driver error=%d\n", driver_name, rc); + goto error; + } + pci_registered = true; + + if (!slgt_device_list) + printk("%s no devices found\n",driver_name); + + return 0; + +error: + slgt_cleanup(); + return rc; +} + +static void __exit slgt_exit(void) +{ + slgt_cleanup(); +} + +module_init(slgt_init); +module_exit(slgt_exit); + +/* + * register access routines + */ + +#define CALC_REGADDR() \ + unsigned long reg_addr = ((unsigned long)info->reg_addr) + addr; \ + if (addr >= 0x80) \ + reg_addr += (info->port_num) * 32; \ + else if (addr >= 0x40) \ + reg_addr += (info->port_num) * 16; + +static __u8 rd_reg8(struct slgt_info *info, unsigned int addr) +{ + CALC_REGADDR(); + return readb((void __iomem *)reg_addr); +} + +static void wr_reg8(struct slgt_info *info, unsigned int addr, __u8 value) +{ + CALC_REGADDR(); + writeb(value, (void __iomem *)reg_addr); +} + +static __u16 rd_reg16(struct slgt_info *info, unsigned int addr) +{ + CALC_REGADDR(); + return readw((void __iomem *)reg_addr); +} + +static void wr_reg16(struct slgt_info *info, unsigned int addr, __u16 value) +{ + CALC_REGADDR(); + writew(value, (void __iomem *)reg_addr); +} + +static __u32 rd_reg32(struct slgt_info *info, unsigned int addr) +{ + CALC_REGADDR(); + return readl((void __iomem *)reg_addr); +} + +static void wr_reg32(struct slgt_info *info, unsigned int addr, __u32 value) +{ + CALC_REGADDR(); + writel(value, (void __iomem *)reg_addr); +} + +static void rdma_reset(struct slgt_info *info) +{ + unsigned int i; + + /* set reset bit */ + wr_reg32(info, RDCSR, BIT1); + + /* wait for enable bit cleared */ + for(i=0 ; i < 1000 ; i++) + if (!(rd_reg32(info, RDCSR) & BIT0)) + break; +} + +static void tdma_reset(struct slgt_info *info) +{ + unsigned int i; + + /* set reset bit */ + wr_reg32(info, TDCSR, BIT1); + + /* wait for enable bit cleared */ + for(i=0 ; i < 1000 ; i++) + if (!(rd_reg32(info, TDCSR) & BIT0)) + break; +} + +/* + * enable internal loopback + * TxCLK and RxCLK are generated from BRG + * and TxD is looped back to RxD internally. + */ +static void enable_loopback(struct slgt_info *info) +{ + /* SCR (serial control) BIT2=looopback enable */ + wr_reg16(info, SCR, (unsigned short)(rd_reg16(info, SCR) | BIT2)); + + if (info->params.mode != MGSL_MODE_ASYNC) { + /* CCR (clock control) + * 07..05 tx clock source (010 = BRG) + * 04..02 rx clock source (010 = BRG) + * 01 auxclk enable (0 = disable) + * 00 BRG enable (1 = enable) + * + * 0100 1001 + */ + wr_reg8(info, CCR, 0x49); + + /* set speed if available, otherwise use default */ + if (info->params.clock_speed) + set_rate(info, info->params.clock_speed); + else + set_rate(info, 3686400); + } +} + +/* + * set baud rate generator to specified rate + */ +static void set_rate(struct slgt_info *info, u32 rate) +{ + unsigned int div; + unsigned int osc = info->base_clock; + + /* div = osc/rate - 1 + * + * Round div up if osc/rate is not integer to + * force to next slowest rate. + */ + + if (rate) { + div = osc/rate; + if (!(osc % rate) && div) + div--; + wr_reg16(info, BDR, (unsigned short)div); + } +} + +static void rx_stop(struct slgt_info *info) +{ + unsigned short val; + + /* disable and reset receiver */ + val = rd_reg16(info, RCR) & ~BIT1; /* clear enable bit */ + wr_reg16(info, RCR, (unsigned short)(val | BIT2)); /* set reset bit */ + wr_reg16(info, RCR, val); /* clear reset bit */ + + slgt_irq_off(info, IRQ_RXOVER + IRQ_RXDATA + IRQ_RXIDLE); + + /* clear pending rx interrupts */ + wr_reg16(info, SSR, IRQ_RXIDLE + IRQ_RXOVER); + + rdma_reset(info); + + info->rx_enabled = false; + info->rx_restart = false; +} + +static void rx_start(struct slgt_info *info) +{ + unsigned short val; + + slgt_irq_off(info, IRQ_RXOVER + IRQ_RXDATA); + + /* clear pending rx overrun IRQ */ + wr_reg16(info, SSR, IRQ_RXOVER); + + /* reset and disable receiver */ + val = rd_reg16(info, RCR) & ~BIT1; /* clear enable bit */ + wr_reg16(info, RCR, (unsigned short)(val | BIT2)); /* set reset bit */ + wr_reg16(info, RCR, val); /* clear reset bit */ + + rdma_reset(info); + reset_rbufs(info); + + if (info->rx_pio) { + /* rx request when rx FIFO not empty */ + wr_reg16(info, SCR, (unsigned short)(rd_reg16(info, SCR) & ~BIT14)); + slgt_irq_on(info, IRQ_RXDATA); + if (info->params.mode == MGSL_MODE_ASYNC) { + /* enable saving of rx status */ + wr_reg32(info, RDCSR, BIT6); + } + } else { + /* rx request when rx FIFO half full */ + wr_reg16(info, SCR, (unsigned short)(rd_reg16(info, SCR) | BIT14)); + /* set 1st descriptor address */ + wr_reg32(info, RDDAR, info->rbufs[0].pdesc); + + if (info->params.mode != MGSL_MODE_ASYNC) { + /* enable rx DMA and DMA interrupt */ + wr_reg32(info, RDCSR, (BIT2 + BIT0)); + } else { + /* enable saving of rx status, rx DMA and DMA interrupt */ + wr_reg32(info, RDCSR, (BIT6 + BIT2 + BIT0)); + } + } + + slgt_irq_on(info, IRQ_RXOVER); + + /* enable receiver */ + wr_reg16(info, RCR, (unsigned short)(rd_reg16(info, RCR) | BIT1)); + + info->rx_restart = false; + info->rx_enabled = true; +} + +static void tx_start(struct slgt_info *info) +{ + if (!info->tx_enabled) { + wr_reg16(info, TCR, + (unsigned short)((rd_reg16(info, TCR) | BIT1) & ~BIT2)); + info->tx_enabled = true; + } + + if (desc_count(info->tbufs[info->tbuf_start])) { + info->drop_rts_on_tx_done = false; + + if (info->params.mode != MGSL_MODE_ASYNC) { + if (info->params.flags & HDLC_FLAG_AUTO_RTS) { + get_signals(info); + if (!(info->signals & SerialSignal_RTS)) { + info->signals |= SerialSignal_RTS; + set_signals(info); + info->drop_rts_on_tx_done = true; + } + } + + slgt_irq_off(info, IRQ_TXDATA); + slgt_irq_on(info, IRQ_TXUNDER + IRQ_TXIDLE); + /* clear tx idle and underrun status bits */ + wr_reg16(info, SSR, (unsigned short)(IRQ_TXIDLE + IRQ_TXUNDER)); + } else { + slgt_irq_off(info, IRQ_TXDATA); + slgt_irq_on(info, IRQ_TXIDLE); + /* clear tx idle status bit */ + wr_reg16(info, SSR, IRQ_TXIDLE); + } + /* set 1st descriptor address and start DMA */ + wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc); + wr_reg32(info, TDCSR, BIT2 + BIT0); + info->tx_active = true; + } +} + +static void tx_stop(struct slgt_info *info) +{ + unsigned short val; + + del_timer(&info->tx_timer); + + tdma_reset(info); + + /* reset and disable transmitter */ + val = rd_reg16(info, TCR) & ~BIT1; /* clear enable bit */ + wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */ + + slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER); + + /* clear tx idle and underrun status bit */ + wr_reg16(info, SSR, (unsigned short)(IRQ_TXIDLE + IRQ_TXUNDER)); + + reset_tbufs(info); + + info->tx_enabled = false; + info->tx_active = false; +} + +static void reset_port(struct slgt_info *info) +{ + if (!info->reg_addr) + return; + + tx_stop(info); + rx_stop(info); + + info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS); + set_signals(info); + + slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); +} + +static void reset_adapter(struct slgt_info *info) +{ + int i; + for (i=0; i < info->port_count; ++i) { + if (info->port_array[i]) + reset_port(info->port_array[i]); + } +} + +static void async_mode(struct slgt_info *info) +{ + unsigned short val; + + slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); + tx_stop(info); + rx_stop(info); + + /* TCR (tx control) + * + * 15..13 mode, 010=async + * 12..10 encoding, 000=NRZ + * 09 parity enable + * 08 1=odd parity, 0=even parity + * 07 1=RTS driver control + * 06 1=break enable + * 05..04 character length + * 00=5 bits + * 01=6 bits + * 10=7 bits + * 11=8 bits + * 03 0=1 stop bit, 1=2 stop bits + * 02 reset + * 01 enable + * 00 auto-CTS enable + */ + val = 0x4000; + + if (info->if_mode & MGSL_INTERFACE_RTS_EN) + val |= BIT7; + + if (info->params.parity != ASYNC_PARITY_NONE) { + val |= BIT9; + if (info->params.parity == ASYNC_PARITY_ODD) + val |= BIT8; + } + + switch (info->params.data_bits) + { + case 6: val |= BIT4; break; + case 7: val |= BIT5; break; + case 8: val |= BIT5 + BIT4; break; + } + + if (info->params.stop_bits != 1) + val |= BIT3; + + if (info->params.flags & HDLC_FLAG_AUTO_CTS) + val |= BIT0; + + wr_reg16(info, TCR, val); + + /* RCR (rx control) + * + * 15..13 mode, 010=async + * 12..10 encoding, 000=NRZ + * 09 parity enable + * 08 1=odd parity, 0=even parity + * 07..06 reserved, must be 0 + * 05..04 character length + * 00=5 bits + * 01=6 bits + * 10=7 bits + * 11=8 bits + * 03 reserved, must be zero + * 02 reset + * 01 enable + * 00 auto-DCD enable + */ + val = 0x4000; + + if (info->params.parity != ASYNC_PARITY_NONE) { + val |= BIT9; + if (info->params.parity == ASYNC_PARITY_ODD) + val |= BIT8; + } + + switch (info->params.data_bits) + { + case 6: val |= BIT4; break; + case 7: val |= BIT5; break; + case 8: val |= BIT5 + BIT4; break; + } + + if (info->params.flags & HDLC_FLAG_AUTO_DCD) + val |= BIT0; + + wr_reg16(info, RCR, val); + + /* CCR (clock control) + * + * 07..05 011 = tx clock source is BRG/16 + * 04..02 010 = rx clock source is BRG + * 01 0 = auxclk disabled + * 00 1 = BRG enabled + * + * 0110 1001 + */ + wr_reg8(info, CCR, 0x69); + + msc_set_vcr(info); + + /* SCR (serial control) + * + * 15 1=tx req on FIFO half empty + * 14 1=rx req on FIFO half full + * 13 tx data IRQ enable + * 12 tx idle IRQ enable + * 11 rx break on IRQ enable + * 10 rx data IRQ enable + * 09 rx break off IRQ enable + * 08 overrun IRQ enable + * 07 DSR IRQ enable + * 06 CTS IRQ enable + * 05 DCD IRQ enable + * 04 RI IRQ enable + * 03 0=16x sampling, 1=8x sampling + * 02 1=txd->rxd internal loopback enable + * 01 reserved, must be zero + * 00 1=master IRQ enable + */ + val = BIT15 + BIT14 + BIT0; + /* JCR[8] : 1 = x8 async mode feature available */ + if ((rd_reg32(info, JCR) & BIT8) && info->params.data_rate && + ((info->base_clock < (info->params.data_rate * 16)) || + (info->base_clock % (info->params.data_rate * 16)))) { + /* use 8x sampling */ + val |= BIT3; + set_rate(info, info->params.data_rate * 8); + } else { + /* use 16x sampling */ + set_rate(info, info->params.data_rate * 16); + } + wr_reg16(info, SCR, val); + + slgt_irq_on(info, IRQ_RXBREAK | IRQ_RXOVER); + + if (info->params.loopback) + enable_loopback(info); +} + +static void sync_mode(struct slgt_info *info) +{ + unsigned short val; + + slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); + tx_stop(info); + rx_stop(info); + + /* TCR (tx control) + * + * 15..13 mode + * 000=HDLC/SDLC + * 001=raw bit synchronous + * 010=asynchronous/isochronous + * 011=monosync byte synchronous + * 100=bisync byte synchronous + * 101=xsync byte synchronous + * 12..10 encoding + * 09 CRC enable + * 08 CRC32 + * 07 1=RTS driver control + * 06 preamble enable + * 05..04 preamble length + * 03 share open/close flag + * 02 reset + * 01 enable + * 00 auto-CTS enable + */ + val = BIT2; + + switch(info->params.mode) { + case MGSL_MODE_XSYNC: + val |= BIT15 + BIT13; + break; + case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; + case MGSL_MODE_BISYNC: val |= BIT15; break; + case MGSL_MODE_RAW: val |= BIT13; break; + } + if (info->if_mode & MGSL_INTERFACE_RTS_EN) + val |= BIT7; + + switch(info->params.encoding) + { + case HDLC_ENCODING_NRZB: val |= BIT10; break; + case HDLC_ENCODING_NRZI_MARK: val |= BIT11; break; + case HDLC_ENCODING_NRZI: val |= BIT11 + BIT10; break; + case HDLC_ENCODING_BIPHASE_MARK: val |= BIT12; break; + case HDLC_ENCODING_BIPHASE_SPACE: val |= BIT12 + BIT10; break; + case HDLC_ENCODING_BIPHASE_LEVEL: val |= BIT12 + BIT11; break; + case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break; + } + + switch (info->params.crc_type & HDLC_CRC_MASK) + { + case HDLC_CRC_16_CCITT: val |= BIT9; break; + case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break; + } + + if (info->params.preamble != HDLC_PREAMBLE_PATTERN_NONE) + val |= BIT6; + + switch (info->params.preamble_length) + { + case HDLC_PREAMBLE_LENGTH_16BITS: val |= BIT5; break; + case HDLC_PREAMBLE_LENGTH_32BITS: val |= BIT4; break; + case HDLC_PREAMBLE_LENGTH_64BITS: val |= BIT5 + BIT4; break; + } + + if (info->params.flags & HDLC_FLAG_AUTO_CTS) + val |= BIT0; + + wr_reg16(info, TCR, val); + + /* TPR (transmit preamble) */ + + switch (info->params.preamble) + { + case HDLC_PREAMBLE_PATTERN_FLAGS: val = 0x7e; break; + case HDLC_PREAMBLE_PATTERN_ONES: val = 0xff; break; + case HDLC_PREAMBLE_PATTERN_ZEROS: val = 0x00; break; + case HDLC_PREAMBLE_PATTERN_10: val = 0x55; break; + case HDLC_PREAMBLE_PATTERN_01: val = 0xaa; break; + default: val = 0x7e; break; + } + wr_reg8(info, TPR, (unsigned char)val); + + /* RCR (rx control) + * + * 15..13 mode + * 000=HDLC/SDLC + * 001=raw bit synchronous + * 010=asynchronous/isochronous + * 011=monosync byte synchronous + * 100=bisync byte synchronous + * 101=xsync byte synchronous + * 12..10 encoding + * 09 CRC enable + * 08 CRC32 + * 07..03 reserved, must be 0 + * 02 reset + * 01 enable + * 00 auto-DCD enable + */ + val = 0; + + switch(info->params.mode) { + case MGSL_MODE_XSYNC: + val |= BIT15 + BIT13; + break; + case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; + case MGSL_MODE_BISYNC: val |= BIT15; break; + case MGSL_MODE_RAW: val |= BIT13; break; + } + + switch(info->params.encoding) + { + case HDLC_ENCODING_NRZB: val |= BIT10; break; + case HDLC_ENCODING_NRZI_MARK: val |= BIT11; break; + case HDLC_ENCODING_NRZI: val |= BIT11 + BIT10; break; + case HDLC_ENCODING_BIPHASE_MARK: val |= BIT12; break; + case HDLC_ENCODING_BIPHASE_SPACE: val |= BIT12 + BIT10; break; + case HDLC_ENCODING_BIPHASE_LEVEL: val |= BIT12 + BIT11; break; + case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break; + } + + switch (info->params.crc_type & HDLC_CRC_MASK) + { + case HDLC_CRC_16_CCITT: val |= BIT9; break; + case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break; + } + + if (info->params.flags & HDLC_FLAG_AUTO_DCD) + val |= BIT0; + + wr_reg16(info, RCR, val); + + /* CCR (clock control) + * + * 07..05 tx clock source + * 04..02 rx clock source + * 01 auxclk enable + * 00 BRG enable + */ + val = 0; + + if (info->params.flags & HDLC_FLAG_TXC_BRG) + { + // when RxC source is DPLL, BRG generates 16X DPLL + // reference clock, so take TxC from BRG/16 to get + // transmit clock at actual data rate + if (info->params.flags & HDLC_FLAG_RXC_DPLL) + val |= BIT6 + BIT5; /* 011, txclk = BRG/16 */ + else + val |= BIT6; /* 010, txclk = BRG */ + } + else if (info->params.flags & HDLC_FLAG_TXC_DPLL) + val |= BIT7; /* 100, txclk = DPLL Input */ + else if (info->params.flags & HDLC_FLAG_TXC_RXCPIN) + val |= BIT5; /* 001, txclk = RXC Input */ + + if (info->params.flags & HDLC_FLAG_RXC_BRG) + val |= BIT3; /* 010, rxclk = BRG */ + else if (info->params.flags & HDLC_FLAG_RXC_DPLL) + val |= BIT4; /* 100, rxclk = DPLL */ + else if (info->params.flags & HDLC_FLAG_RXC_TXCPIN) + val |= BIT2; /* 001, rxclk = TXC Input */ + + if (info->params.clock_speed) + val |= BIT1 + BIT0; + + wr_reg8(info, CCR, (unsigned char)val); + + if (info->params.flags & (HDLC_FLAG_TXC_DPLL + HDLC_FLAG_RXC_DPLL)) + { + // program DPLL mode + switch(info->params.encoding) + { + case HDLC_ENCODING_BIPHASE_MARK: + case HDLC_ENCODING_BIPHASE_SPACE: + val = BIT7; break; + case HDLC_ENCODING_BIPHASE_LEVEL: + case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: + val = BIT7 + BIT6; break; + default: val = BIT6; // NRZ encodings + } + wr_reg16(info, RCR, (unsigned short)(rd_reg16(info, RCR) | val)); + + // DPLL requires a 16X reference clock from BRG + set_rate(info, info->params.clock_speed * 16); + } + else + set_rate(info, info->params.clock_speed); + + tx_set_idle(info); + + msc_set_vcr(info); + + /* SCR (serial control) + * + * 15 1=tx req on FIFO half empty + * 14 1=rx req on FIFO half full + * 13 tx data IRQ enable + * 12 tx idle IRQ enable + * 11 underrun IRQ enable + * 10 rx data IRQ enable + * 09 rx idle IRQ enable + * 08 overrun IRQ enable + * 07 DSR IRQ enable + * 06 CTS IRQ enable + * 05 DCD IRQ enable + * 04 RI IRQ enable + * 03 reserved, must be zero + * 02 1=txd->rxd internal loopback enable + * 01 reserved, must be zero + * 00 1=master IRQ enable + */ + wr_reg16(info, SCR, BIT15 + BIT14 + BIT0); + + if (info->params.loopback) + enable_loopback(info); +} + +/* + * set transmit idle mode + */ +static void tx_set_idle(struct slgt_info *info) +{ + unsigned char val; + unsigned short tcr; + + /* if preamble enabled (tcr[6] == 1) then tx idle size = 8 bits + * else tcr[5:4] = tx idle size: 00 = 8 bits, 01 = 16 bits + */ + tcr = rd_reg16(info, TCR); + if (info->idle_mode & HDLC_TXIDLE_CUSTOM_16) { + /* disable preamble, set idle size to 16 bits */ + tcr = (tcr & ~(BIT6 + BIT5)) | BIT4; + /* MSB of 16 bit idle specified in tx preamble register (TPR) */ + wr_reg8(info, TPR, (unsigned char)((info->idle_mode >> 8) & 0xff)); + } else if (!(tcr & BIT6)) { + /* preamble is disabled, set idle size to 8 bits */ + tcr &= ~(BIT5 + BIT4); + } + wr_reg16(info, TCR, tcr); + + if (info->idle_mode & (HDLC_TXIDLE_CUSTOM_8 | HDLC_TXIDLE_CUSTOM_16)) { + /* LSB of custom tx idle specified in tx idle register */ + val = (unsigned char)(info->idle_mode & 0xff); + } else { + /* standard 8 bit idle patterns */ + switch(info->idle_mode) + { + case HDLC_TXIDLE_FLAGS: val = 0x7e; break; + case HDLC_TXIDLE_ALT_ZEROS_ONES: + case HDLC_TXIDLE_ALT_MARK_SPACE: val = 0xaa; break; + case HDLC_TXIDLE_ZEROS: + case HDLC_TXIDLE_SPACE: val = 0x00; break; + default: val = 0xff; + } + } + + wr_reg8(info, TIR, val); +} + +/* + * get state of V24 status (input) signals + */ +static void get_signals(struct slgt_info *info) +{ + unsigned short status = rd_reg16(info, SSR); + + /* clear all serial signals except DTR and RTS */ + info->signals &= SerialSignal_DTR + SerialSignal_RTS; + + if (status & BIT3) + info->signals |= SerialSignal_DSR; + if (status & BIT2) + info->signals |= SerialSignal_CTS; + if (status & BIT1) + info->signals |= SerialSignal_DCD; + if (status & BIT0) + info->signals |= SerialSignal_RI; +} + +/* + * set V.24 Control Register based on current configuration + */ +static void msc_set_vcr(struct slgt_info *info) +{ + unsigned char val = 0; + + /* VCR (V.24 control) + * + * 07..04 serial IF select + * 03 DTR + * 02 RTS + * 01 LL + * 00 RL + */ + + switch(info->if_mode & MGSL_INTERFACE_MASK) + { + case MGSL_INTERFACE_RS232: + val |= BIT5; /* 0010 */ + break; + case MGSL_INTERFACE_V35: + val |= BIT7 + BIT6 + BIT5; /* 1110 */ + break; + case MGSL_INTERFACE_RS422: + val |= BIT6; /* 0100 */ + break; + } + + if (info->if_mode & MGSL_INTERFACE_MSB_FIRST) + val |= BIT4; + if (info->signals & SerialSignal_DTR) + val |= BIT3; + if (info->signals & SerialSignal_RTS) + val |= BIT2; + if (info->if_mode & MGSL_INTERFACE_LL) + val |= BIT1; + if (info->if_mode & MGSL_INTERFACE_RL) + val |= BIT0; + wr_reg8(info, VCR, val); +} + +/* + * set state of V24 control (output) signals + */ +static void set_signals(struct slgt_info *info) +{ + unsigned char val = rd_reg8(info, VCR); + if (info->signals & SerialSignal_DTR) + val |= BIT3; + else + val &= ~BIT3; + if (info->signals & SerialSignal_RTS) + val |= BIT2; + else + val &= ~BIT2; + wr_reg8(info, VCR, val); +} + +/* + * free range of receive DMA buffers (i to last) + */ +static void free_rbufs(struct slgt_info *info, unsigned int i, unsigned int last) +{ + int done = 0; + + while(!done) { + /* reset current buffer for reuse */ + info->rbufs[i].status = 0; + set_desc_count(info->rbufs[i], info->rbuf_fill_level); + if (i == last) + done = 1; + if (++i == info->rbuf_count) + i = 0; + } + info->rbuf_current = i; +} + +/* + * mark all receive DMA buffers as free + */ +static void reset_rbufs(struct slgt_info *info) +{ + free_rbufs(info, 0, info->rbuf_count - 1); + info->rbuf_fill_index = 0; + info->rbuf_fill_count = 0; +} + +/* + * pass receive HDLC frame to upper layer + * + * return true if frame available, otherwise false + */ +static bool rx_get_frame(struct slgt_info *info) +{ + unsigned int start, end; + unsigned short status; + unsigned int framesize = 0; + unsigned long flags; + struct tty_struct *tty = info->port.tty; + unsigned char addr_field = 0xff; + unsigned int crc_size = 0; + + switch (info->params.crc_type & HDLC_CRC_MASK) { + case HDLC_CRC_16_CCITT: crc_size = 2; break; + case HDLC_CRC_32_CCITT: crc_size = 4; break; + } + +check_again: + + framesize = 0; + addr_field = 0xff; + start = end = info->rbuf_current; + + for (;;) { + if (!desc_complete(info->rbufs[end])) + goto cleanup; + + if (framesize == 0 && info->params.addr_filter != 0xff) + addr_field = info->rbufs[end].buf[0]; + + framesize += desc_count(info->rbufs[end]); + + if (desc_eof(info->rbufs[end])) + break; + + if (++end == info->rbuf_count) + end = 0; + + if (end == info->rbuf_current) { + if (info->rx_enabled){ + spin_lock_irqsave(&info->lock,flags); + rx_start(info); + spin_unlock_irqrestore(&info->lock,flags); + } + goto cleanup; + } + } + + /* status + * + * 15 buffer complete + * 14..06 reserved + * 05..04 residue + * 02 eof (end of frame) + * 01 CRC error + * 00 abort + */ + status = desc_status(info->rbufs[end]); + + /* ignore CRC bit if not using CRC (bit is undefined) */ + if ((info->params.crc_type & HDLC_CRC_MASK) == HDLC_CRC_NONE) + status &= ~BIT1; + + if (framesize == 0 || + (addr_field != 0xff && addr_field != info->params.addr_filter)) { + free_rbufs(info, start, end); + goto check_again; + } + + if (framesize < (2 + crc_size) || status & BIT0) { + info->icount.rxshort++; + framesize = 0; + } else if (status & BIT1) { + info->icount.rxcrc++; + if (!(info->params.crc_type & HDLC_CRC_RETURN_EX)) + framesize = 0; + } + +#if SYNCLINK_GENERIC_HDLC + if (framesize == 0) { + info->netdev->stats.rx_errors++; + info->netdev->stats.rx_frame_errors++; + } +#endif + + DBGBH(("%s rx frame status=%04X size=%d\n", + info->device_name, status, framesize)); + DBGDATA(info, info->rbufs[start].buf, min_t(int, framesize, info->rbuf_fill_level), "rx"); + + if (framesize) { + if (!(info->params.crc_type & HDLC_CRC_RETURN_EX)) { + framesize -= crc_size; + crc_size = 0; + } + + if (framesize > info->max_frame_size + crc_size) + info->icount.rxlong++; + else { + /* copy dma buffer(s) to contiguous temp buffer */ + int copy_count = framesize; + int i = start; + unsigned char *p = info->tmp_rbuf; + info->tmp_rbuf_count = framesize; + + info->icount.rxok++; + + while(copy_count) { + int partial_count = min_t(int, copy_count, info->rbuf_fill_level); + memcpy(p, info->rbufs[i].buf, partial_count); + p += partial_count; + copy_count -= partial_count; + if (++i == info->rbuf_count) + i = 0; + } + + if (info->params.crc_type & HDLC_CRC_RETURN_EX) { + *p = (status & BIT1) ? RX_CRC_ERROR : RX_OK; + framesize++; + } + +#if SYNCLINK_GENERIC_HDLC + if (info->netcount) + hdlcdev_rx(info,info->tmp_rbuf, framesize); + else +#endif + ldisc_receive_buf(tty, info->tmp_rbuf, info->flag_buf, framesize); + } + } + free_rbufs(info, start, end); + return true; + +cleanup: + return false; +} + +/* + * pass receive buffer (RAW synchronous mode) to tty layer + * return true if buffer available, otherwise false + */ +static bool rx_get_buf(struct slgt_info *info) +{ + unsigned int i = info->rbuf_current; + unsigned int count; + + if (!desc_complete(info->rbufs[i])) + return false; + count = desc_count(info->rbufs[i]); + switch(info->params.mode) { + case MGSL_MODE_MONOSYNC: + case MGSL_MODE_BISYNC: + case MGSL_MODE_XSYNC: + /* ignore residue in byte synchronous modes */ + if (desc_residue(info->rbufs[i])) + count--; + break; + } + DBGDATA(info, info->rbufs[i].buf, count, "rx"); + DBGINFO(("rx_get_buf size=%d\n", count)); + if (count) + ldisc_receive_buf(info->port.tty, info->rbufs[i].buf, + info->flag_buf, count); + free_rbufs(info, i, i); + return true; +} + +static void reset_tbufs(struct slgt_info *info) +{ + unsigned int i; + info->tbuf_current = 0; + for (i=0 ; i < info->tbuf_count ; i++) { + info->tbufs[i].status = 0; + info->tbufs[i].count = 0; + } +} + +/* + * return number of free transmit DMA buffers + */ +static unsigned int free_tbuf_count(struct slgt_info *info) +{ + unsigned int count = 0; + unsigned int i = info->tbuf_current; + + do + { + if (desc_count(info->tbufs[i])) + break; /* buffer in use */ + ++count; + if (++i == info->tbuf_count) + i=0; + } while (i != info->tbuf_current); + + /* if tx DMA active, last zero count buffer is in use */ + if (count && (rd_reg32(info, TDCSR) & BIT0)) + --count; + + return count; +} + +/* + * return number of bytes in unsent transmit DMA buffers + * and the serial controller tx FIFO + */ +static unsigned int tbuf_bytes(struct slgt_info *info) +{ + unsigned int total_count = 0; + unsigned int i = info->tbuf_current; + unsigned int reg_value; + unsigned int count; + unsigned int active_buf_count = 0; + + /* + * Add descriptor counts for all tx DMA buffers. + * If count is zero (cleared by DMA controller after read), + * the buffer is complete or is actively being read from. + * + * Record buf_count of last buffer with zero count starting + * from current ring position. buf_count is mirror + * copy of count and is not cleared by serial controller. + * If DMA controller is active, that buffer is actively + * being read so add to total. + */ + do { + count = desc_count(info->tbufs[i]); + if (count) + total_count += count; + else if (!total_count) + active_buf_count = info->tbufs[i].buf_count; + if (++i == info->tbuf_count) + i = 0; + } while (i != info->tbuf_current); + + /* read tx DMA status register */ + reg_value = rd_reg32(info, TDCSR); + + /* if tx DMA active, last zero count buffer is in use */ + if (reg_value & BIT0) + total_count += active_buf_count; + + /* add tx FIFO count = reg_value[15..8] */ + total_count += (reg_value >> 8) & 0xff; + + /* if transmitter active add one byte for shift register */ + if (info->tx_active) + total_count++; + + return total_count; +} + +/* + * load data into transmit DMA buffer ring and start transmitter if needed + * return true if data accepted, otherwise false (buffers full) + */ +static bool tx_load(struct slgt_info *info, const char *buf, unsigned int size) +{ + unsigned short count; + unsigned int i; + struct slgt_desc *d; + + /* check required buffer space */ + if (DIV_ROUND_UP(size, DMABUFSIZE) > free_tbuf_count(info)) + return false; + + DBGDATA(info, buf, size, "tx"); + + /* + * copy data to one or more DMA buffers in circular ring + * tbuf_start = first buffer for this data + * tbuf_current = next free buffer + * + * Copy all data before making data visible to DMA controller by + * setting descriptor count of the first buffer. + * This prevents an active DMA controller from reading the first DMA + * buffers of a frame and stopping before the final buffers are filled. + */ + + info->tbuf_start = i = info->tbuf_current; + + while (size) { + d = &info->tbufs[i]; + + count = (unsigned short)((size > DMABUFSIZE) ? DMABUFSIZE : size); + memcpy(d->buf, buf, count); + + size -= count; + buf += count; + + /* + * set EOF bit for last buffer of HDLC frame or + * for every buffer in raw mode + */ + if ((!size && info->params.mode == MGSL_MODE_HDLC) || + info->params.mode == MGSL_MODE_RAW) + set_desc_eof(*d, 1); + else + set_desc_eof(*d, 0); + + /* set descriptor count for all but first buffer */ + if (i != info->tbuf_start) + set_desc_count(*d, count); + d->buf_count = count; + + if (++i == info->tbuf_count) + i = 0; + } + + info->tbuf_current = i; + + /* set first buffer count to make new data visible to DMA controller */ + d = &info->tbufs[info->tbuf_start]; + set_desc_count(*d, d->buf_count); + + /* start transmitter if needed and update transmit timeout */ + if (!info->tx_active) + tx_start(info); + update_tx_timer(info); + + return true; +} + +static int register_test(struct slgt_info *info) +{ + static unsigned short patterns[] = + {0x0000, 0xffff, 0xaaaa, 0x5555, 0x6969, 0x9696}; + static unsigned int count = ARRAY_SIZE(patterns); + unsigned int i; + int rc = 0; + + for (i=0 ; i < count ; i++) { + wr_reg16(info, TIR, patterns[i]); + wr_reg16(info, BDR, patterns[(i+1)%count]); + if ((rd_reg16(info, TIR) != patterns[i]) || + (rd_reg16(info, BDR) != patterns[(i+1)%count])) { + rc = -ENODEV; + break; + } + } + info->gpio_present = (rd_reg32(info, JCR) & BIT5) ? 1 : 0; + info->init_error = rc ? 0 : DiagStatus_AddressFailure; + return rc; +} + +static int irq_test(struct slgt_info *info) +{ + unsigned long timeout; + unsigned long flags; + struct tty_struct *oldtty = info->port.tty; + u32 speed = info->params.data_rate; + + info->params.data_rate = 921600; + info->port.tty = NULL; + + spin_lock_irqsave(&info->lock, flags); + async_mode(info); + slgt_irq_on(info, IRQ_TXIDLE); + + /* enable transmitter */ + wr_reg16(info, TCR, + (unsigned short)(rd_reg16(info, TCR) | BIT1)); + + /* write one byte and wait for tx idle */ + wr_reg16(info, TDR, 0); + + /* assume failure */ + info->init_error = DiagStatus_IrqFailure; + info->irq_occurred = false; + + spin_unlock_irqrestore(&info->lock, flags); + + timeout=100; + while(timeout-- && !info->irq_occurred) + msleep_interruptible(10); + + spin_lock_irqsave(&info->lock,flags); + reset_port(info); + spin_unlock_irqrestore(&info->lock,flags); + + info->params.data_rate = speed; + info->port.tty = oldtty; + + info->init_error = info->irq_occurred ? 0 : DiagStatus_IrqFailure; + return info->irq_occurred ? 0 : -ENODEV; +} + +static int loopback_test_rx(struct slgt_info *info) +{ + unsigned char *src, *dest; + int count; + + if (desc_complete(info->rbufs[0])) { + count = desc_count(info->rbufs[0]); + src = info->rbufs[0].buf; + dest = info->tmp_rbuf; + + for( ; count ; count-=2, src+=2) { + /* src=data byte (src+1)=status byte */ + if (!(*(src+1) & (BIT9 + BIT8))) { + *dest = *src; + dest++; + info->tmp_rbuf_count++; + } + } + DBGDATA(info, info->tmp_rbuf, info->tmp_rbuf_count, "rx"); + return 1; + } + return 0; +} + +static int loopback_test(struct slgt_info *info) +{ +#define TESTFRAMESIZE 20 + + unsigned long timeout; + u16 count = TESTFRAMESIZE; + unsigned char buf[TESTFRAMESIZE]; + int rc = -ENODEV; + unsigned long flags; + + struct tty_struct *oldtty = info->port.tty; + MGSL_PARAMS params; + + memcpy(¶ms, &info->params, sizeof(params)); + + info->params.mode = MGSL_MODE_ASYNC; + info->params.data_rate = 921600; + info->params.loopback = 1; + info->port.tty = NULL; + + /* build and send transmit frame */ + for (count = 0; count < TESTFRAMESIZE; ++count) + buf[count] = (unsigned char)count; + + info->tmp_rbuf_count = 0; + memset(info->tmp_rbuf, 0, TESTFRAMESIZE); + + /* program hardware for HDLC and enabled receiver */ + spin_lock_irqsave(&info->lock,flags); + async_mode(info); + rx_start(info); + tx_load(info, buf, count); + spin_unlock_irqrestore(&info->lock, flags); + + /* wait for receive complete */ + for (timeout = 100; timeout; --timeout) { + msleep_interruptible(10); + if (loopback_test_rx(info)) { + rc = 0; + break; + } + } + + /* verify received frame length and contents */ + if (!rc && (info->tmp_rbuf_count != count || + memcmp(buf, info->tmp_rbuf, count))) { + rc = -ENODEV; + } + + spin_lock_irqsave(&info->lock,flags); + reset_adapter(info); + spin_unlock_irqrestore(&info->lock,flags); + + memcpy(&info->params, ¶ms, sizeof(info->params)); + info->port.tty = oldtty; + + info->init_error = rc ? DiagStatus_DmaFailure : 0; + return rc; +} + +static int adapter_test(struct slgt_info *info) +{ + DBGINFO(("testing %s\n", info->device_name)); + if (register_test(info) < 0) { + printk("register test failure %s addr=%08X\n", + info->device_name, info->phys_reg_addr); + } else if (irq_test(info) < 0) { + printk("IRQ test failure %s IRQ=%d\n", + info->device_name, info->irq_level); + } else if (loopback_test(info) < 0) { + printk("loopback test failure %s\n", info->device_name); + } + return info->init_error; +} + +/* + * transmit timeout handler + */ +static void tx_timeout(unsigned long context) +{ + struct slgt_info *info = (struct slgt_info*)context; + unsigned long flags; + + DBGINFO(("%s tx_timeout\n", info->device_name)); + if(info->tx_active && info->params.mode == MGSL_MODE_HDLC) { + info->icount.txtimeout++; + } + spin_lock_irqsave(&info->lock,flags); + tx_stop(info); + spin_unlock_irqrestore(&info->lock,flags); + +#if SYNCLINK_GENERIC_HDLC + if (info->netcount) + hdlcdev_tx_done(info); + else +#endif + bh_transmit(info); +} + +/* + * receive buffer polling timer + */ +static void rx_timeout(unsigned long context) +{ + struct slgt_info *info = (struct slgt_info*)context; + unsigned long flags; + + DBGINFO(("%s rx_timeout\n", info->device_name)); + spin_lock_irqsave(&info->lock, flags); + info->pending_bh |= BH_RECEIVE; + spin_unlock_irqrestore(&info->lock, flags); + bh_handler(&info->task); +} + diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c new file mode 100644 index 000000000000..327343694473 --- /dev/null +++ b/drivers/tty/synclinkmp.c @@ -0,0 +1,5600 @@ +/* + * $Id: synclinkmp.c,v 4.38 2005/07/15 13:29:44 paulkf Exp $ + * + * Device driver for Microgate SyncLink Multiport + * high speed multiprotocol serial adapter. + * + * written by Paul Fulghum for Microgate Corporation + * paulkf@microgate.com + * + * Microgate and SyncLink are trademarks of Microgate Corporation + * + * Derived from serial.c written by Theodore Ts'o and Linus Torvalds + * This code is released under the GNU General Public License (GPL) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define VERSION(ver,rel,seq) (((ver)<<16) | ((rel)<<8) | (seq)) +#if defined(__i386__) +# define BREAKPOINT() asm(" int $3"); +#else +# define BREAKPOINT() { } +#endif + +#define MAX_DEVICES 12 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINKMP_MODULE)) +#define SYNCLINK_GENERIC_HDLC 1 +#else +#define SYNCLINK_GENERIC_HDLC 0 +#endif + +#define GET_USER(error,value,addr) error = get_user(value,addr) +#define COPY_FROM_USER(error,dest,src,size) error = copy_from_user(dest,src,size) ? -EFAULT : 0 +#define PUT_USER(error,value,addr) error = put_user(value,addr) +#define COPY_TO_USER(error,dest,src,size) error = copy_to_user(dest,src,size) ? -EFAULT : 0 + +#include + +static MGSL_PARAMS default_params = { + MGSL_MODE_HDLC, /* unsigned long mode */ + 0, /* unsigned char loopback; */ + HDLC_FLAG_UNDERRUN_ABORT15, /* unsigned short flags; */ + HDLC_ENCODING_NRZI_SPACE, /* unsigned char encoding; */ + 0, /* unsigned long clock_speed; */ + 0xff, /* unsigned char addr_filter; */ + HDLC_CRC_16_CCITT, /* unsigned short crc_type; */ + HDLC_PREAMBLE_LENGTH_8BITS, /* unsigned char preamble_length; */ + HDLC_PREAMBLE_PATTERN_NONE, /* unsigned char preamble; */ + 9600, /* unsigned long data_rate; */ + 8, /* unsigned char data_bits; */ + 1, /* unsigned char stop_bits; */ + ASYNC_PARITY_NONE /* unsigned char parity; */ +}; + +/* size in bytes of DMA data buffers */ +#define SCABUFSIZE 1024 +#define SCA_MEM_SIZE 0x40000 +#define SCA_BASE_SIZE 512 +#define SCA_REG_SIZE 16 +#define SCA_MAX_PORTS 4 +#define SCAMAXDESC 128 + +#define BUFFERLISTSIZE 4096 + +/* SCA-I style DMA buffer descriptor */ +typedef struct _SCADESC +{ + u16 next; /* lower l6 bits of next descriptor addr */ + u16 buf_ptr; /* lower 16 bits of buffer addr */ + u8 buf_base; /* upper 8 bits of buffer addr */ + u8 pad1; + u16 length; /* length of buffer */ + u8 status; /* status of buffer */ + u8 pad2; +} SCADESC, *PSCADESC; + +typedef struct _SCADESC_EX +{ + /* device driver bookkeeping section */ + char *virt_addr; /* virtual address of data buffer */ + u16 phys_entry; /* lower 16-bits of physical address of this descriptor */ +} SCADESC_EX, *PSCADESC_EX; + +/* The queue of BH actions to be performed */ + +#define BH_RECEIVE 1 +#define BH_TRANSMIT 2 +#define BH_STATUS 4 + +#define IO_PIN_SHUTDOWN_LIMIT 100 + +struct _input_signal_events { + int ri_up; + int ri_down; + int dsr_up; + int dsr_down; + int dcd_up; + int dcd_down; + int cts_up; + int cts_down; +}; + +/* + * Device instance data structure + */ +typedef struct _synclinkmp_info { + void *if_ptr; /* General purpose pointer (used by SPPP) */ + int magic; + struct tty_port port; + int line; + unsigned short close_delay; + unsigned short closing_wait; /* time to wait before closing */ + + struct mgsl_icount icount; + + int timeout; + int x_char; /* xon/xoff character */ + u16 read_status_mask1; /* break detection (SR1 indications) */ + u16 read_status_mask2; /* parity/framing/overun (SR2 indications) */ + unsigned char ignore_status_mask1; /* break detection (SR1 indications) */ + unsigned char ignore_status_mask2; /* parity/framing/overun (SR2 indications) */ + unsigned char *tx_buf; + int tx_put; + int tx_get; + int tx_count; + + wait_queue_head_t status_event_wait_q; + wait_queue_head_t event_wait_q; + struct timer_list tx_timer; /* HDLC transmit timeout timer */ + struct _synclinkmp_info *next_device; /* device list link */ + struct timer_list status_timer; /* input signal status check timer */ + + spinlock_t lock; /* spinlock for synchronizing with ISR */ + struct work_struct task; /* task structure for scheduling bh */ + + u32 max_frame_size; /* as set by device config */ + + u32 pending_bh; + + bool bh_running; /* Protection from multiple */ + int isr_overflow; + bool bh_requested; + + int dcd_chkcount; /* check counts to prevent */ + int cts_chkcount; /* too many IRQs if a signal */ + int dsr_chkcount; /* is floating */ + int ri_chkcount; + + char *buffer_list; /* virtual address of Rx & Tx buffer lists */ + unsigned long buffer_list_phys; + + unsigned int rx_buf_count; /* count of total allocated Rx buffers */ + SCADESC *rx_buf_list; /* list of receive buffer entries */ + SCADESC_EX rx_buf_list_ex[SCAMAXDESC]; /* list of receive buffer entries */ + unsigned int current_rx_buf; + + unsigned int tx_buf_count; /* count of total allocated Tx buffers */ + SCADESC *tx_buf_list; /* list of transmit buffer entries */ + SCADESC_EX tx_buf_list_ex[SCAMAXDESC]; /* list of transmit buffer entries */ + unsigned int last_tx_buf; + + unsigned char *tmp_rx_buf; + unsigned int tmp_rx_buf_count; + + bool rx_enabled; + bool rx_overflow; + + bool tx_enabled; + bool tx_active; + u32 idle_mode; + + unsigned char ie0_value; + unsigned char ie1_value; + unsigned char ie2_value; + unsigned char ctrlreg_value; + unsigned char old_signals; + + char device_name[25]; /* device instance name */ + + int port_count; + int adapter_num; + int port_num; + + struct _synclinkmp_info *port_array[SCA_MAX_PORTS]; + + unsigned int bus_type; /* expansion bus type (ISA,EISA,PCI) */ + + unsigned int irq_level; /* interrupt level */ + unsigned long irq_flags; + bool irq_requested; /* true if IRQ requested */ + + MGSL_PARAMS params; /* communications parameters */ + + unsigned char serial_signals; /* current serial signal states */ + + bool irq_occurred; /* for diagnostics use */ + unsigned int init_error; /* Initialization startup error */ + + u32 last_mem_alloc; + unsigned char* memory_base; /* shared memory address (PCI only) */ + u32 phys_memory_base; + int shared_mem_requested; + + unsigned char* sca_base; /* HD64570 SCA Memory address */ + u32 phys_sca_base; + u32 sca_offset; + bool sca_base_requested; + + unsigned char* lcr_base; /* local config registers (PCI only) */ + u32 phys_lcr_base; + u32 lcr_offset; + int lcr_mem_requested; + + unsigned char* statctrl_base; /* status/control register memory */ + u32 phys_statctrl_base; + u32 statctrl_offset; + bool sca_statctrl_requested; + + u32 misc_ctrl_value; + char flag_buf[MAX_ASYNC_BUFFER_SIZE]; + char char_buf[MAX_ASYNC_BUFFER_SIZE]; + bool drop_rts_on_tx_done; + + struct _input_signal_events input_signal_events; + + /* SPPP/Cisco HDLC device parts */ + int netcount; + spinlock_t netlock; + +#if SYNCLINK_GENERIC_HDLC + struct net_device *netdev; +#endif + +} SLMP_INFO; + +#define MGSL_MAGIC 0x5401 + +/* + * define serial signal status change macros + */ +#define MISCSTATUS_DCD_LATCHED (SerialSignal_DCD<<8) /* indicates change in DCD */ +#define MISCSTATUS_RI_LATCHED (SerialSignal_RI<<8) /* indicates change in RI */ +#define MISCSTATUS_CTS_LATCHED (SerialSignal_CTS<<8) /* indicates change in CTS */ +#define MISCSTATUS_DSR_LATCHED (SerialSignal_DSR<<8) /* change in DSR */ + +/* Common Register macros */ +#define LPR 0x00 +#define PABR0 0x02 +#define PABR1 0x03 +#define WCRL 0x04 +#define WCRM 0x05 +#define WCRH 0x06 +#define DPCR 0x08 +#define DMER 0x09 +#define ISR0 0x10 +#define ISR1 0x11 +#define ISR2 0x12 +#define IER0 0x14 +#define IER1 0x15 +#define IER2 0x16 +#define ITCR 0x18 +#define INTVR 0x1a +#define IMVR 0x1c + +/* MSCI Register macros */ +#define TRB 0x20 +#define TRBL 0x20 +#define TRBH 0x21 +#define SR0 0x22 +#define SR1 0x23 +#define SR2 0x24 +#define SR3 0x25 +#define FST 0x26 +#define IE0 0x28 +#define IE1 0x29 +#define IE2 0x2a +#define FIE 0x2b +#define CMD 0x2c +#define MD0 0x2e +#define MD1 0x2f +#define MD2 0x30 +#define CTL 0x31 +#define SA0 0x32 +#define SA1 0x33 +#define IDL 0x34 +#define TMC 0x35 +#define RXS 0x36 +#define TXS 0x37 +#define TRC0 0x38 +#define TRC1 0x39 +#define RRC 0x3a +#define CST0 0x3c +#define CST1 0x3d + +/* Timer Register Macros */ +#define TCNT 0x60 +#define TCNTL 0x60 +#define TCNTH 0x61 +#define TCONR 0x62 +#define TCONRL 0x62 +#define TCONRH 0x63 +#define TMCS 0x64 +#define TEPR 0x65 + +/* DMA Controller Register macros */ +#define DARL 0x80 +#define DARH 0x81 +#define DARB 0x82 +#define BAR 0x80 +#define BARL 0x80 +#define BARH 0x81 +#define BARB 0x82 +#define SAR 0x84 +#define SARL 0x84 +#define SARH 0x85 +#define SARB 0x86 +#define CPB 0x86 +#define CDA 0x88 +#define CDAL 0x88 +#define CDAH 0x89 +#define EDA 0x8a +#define EDAL 0x8a +#define EDAH 0x8b +#define BFL 0x8c +#define BFLL 0x8c +#define BFLH 0x8d +#define BCR 0x8e +#define BCRL 0x8e +#define BCRH 0x8f +#define DSR 0x90 +#define DMR 0x91 +#define FCT 0x93 +#define DIR 0x94 +#define DCMD 0x95 + +/* combine with timer or DMA register address */ +#define TIMER0 0x00 +#define TIMER1 0x08 +#define TIMER2 0x10 +#define TIMER3 0x18 +#define RXDMA 0x00 +#define TXDMA 0x20 + +/* SCA Command Codes */ +#define NOOP 0x00 +#define TXRESET 0x01 +#define TXENABLE 0x02 +#define TXDISABLE 0x03 +#define TXCRCINIT 0x04 +#define TXCRCEXCL 0x05 +#define TXEOM 0x06 +#define TXABORT 0x07 +#define MPON 0x08 +#define TXBUFCLR 0x09 +#define RXRESET 0x11 +#define RXENABLE 0x12 +#define RXDISABLE 0x13 +#define RXCRCINIT 0x14 +#define RXREJECT 0x15 +#define SEARCHMP 0x16 +#define RXCRCEXCL 0x17 +#define RXCRCCALC 0x18 +#define CHRESET 0x21 +#define HUNT 0x31 + +/* DMA command codes */ +#define SWABORT 0x01 +#define FEICLEAR 0x02 + +/* IE0 */ +#define TXINTE BIT7 +#define RXINTE BIT6 +#define TXRDYE BIT1 +#define RXRDYE BIT0 + +/* IE1 & SR1 */ +#define UDRN BIT7 +#define IDLE BIT6 +#define SYNCD BIT4 +#define FLGD BIT4 +#define CCTS BIT3 +#define CDCD BIT2 +#define BRKD BIT1 +#define ABTD BIT1 +#define GAPD BIT1 +#define BRKE BIT0 +#define IDLD BIT0 + +/* IE2 & SR2 */ +#define EOM BIT7 +#define PMP BIT6 +#define SHRT BIT6 +#define PE BIT5 +#define ABT BIT5 +#define FRME BIT4 +#define RBIT BIT4 +#define OVRN BIT3 +#define CRCE BIT2 + + +/* + * Global linked list of SyncLink devices + */ +static SLMP_INFO *synclinkmp_device_list = NULL; +static int synclinkmp_adapter_count = -1; +static int synclinkmp_device_count = 0; + +/* + * Set this param to non-zero to load eax with the + * .text section address and breakpoint on module load. + * This is useful for use with gdb and add-symbol-file command. + */ +static int break_on_load = 0; + +/* + * Driver major number, defaults to zero to get auto + * assigned major number. May be forced as module parameter. + */ +static int ttymajor = 0; + +/* + * Array of user specified options for ISA adapters. + */ +static int debug_level = 0; +static int maxframe[MAX_DEVICES] = {0,}; + +module_param(break_on_load, bool, 0); +module_param(ttymajor, int, 0); +module_param(debug_level, int, 0); +module_param_array(maxframe, int, NULL, 0); + +static char *driver_name = "SyncLink MultiPort driver"; +static char *driver_version = "$Revision: 4.38 $"; + +static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent); +static void synclinkmp_remove_one(struct pci_dev *dev); + +static struct pci_device_id synclinkmp_pci_tbl[] = { + { PCI_VENDOR_ID_MICROGATE, PCI_DEVICE_ID_MICROGATE_SCA, PCI_ANY_ID, PCI_ANY_ID, }, + { 0, }, /* terminate list */ +}; +MODULE_DEVICE_TABLE(pci, synclinkmp_pci_tbl); + +MODULE_LICENSE("GPL"); + +static struct pci_driver synclinkmp_pci_driver = { + .name = "synclinkmp", + .id_table = synclinkmp_pci_tbl, + .probe = synclinkmp_init_one, + .remove = __devexit_p(synclinkmp_remove_one), +}; + + +static struct tty_driver *serial_driver; + +/* number of characters left in xmit buffer before we ask for more */ +#define WAKEUP_CHARS 256 + + +/* tty callbacks */ + +static int open(struct tty_struct *tty, struct file * filp); +static void close(struct tty_struct *tty, struct file * filp); +static void hangup(struct tty_struct *tty); +static void set_termios(struct tty_struct *tty, struct ktermios *old_termios); + +static int write(struct tty_struct *tty, const unsigned char *buf, int count); +static int put_char(struct tty_struct *tty, unsigned char ch); +static void send_xchar(struct tty_struct *tty, char ch); +static void wait_until_sent(struct tty_struct *tty, int timeout); +static int write_room(struct tty_struct *tty); +static void flush_chars(struct tty_struct *tty); +static void flush_buffer(struct tty_struct *tty); +static void tx_hold(struct tty_struct *tty); +static void tx_release(struct tty_struct *tty); + +static int ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); +static int chars_in_buffer(struct tty_struct *tty); +static void throttle(struct tty_struct * tty); +static void unthrottle(struct tty_struct * tty); +static int set_break(struct tty_struct *tty, int break_state); + +#if SYNCLINK_GENERIC_HDLC +#define dev_to_port(D) (dev_to_hdlc(D)->priv) +static void hdlcdev_tx_done(SLMP_INFO *info); +static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size); +static int hdlcdev_init(SLMP_INFO *info); +static void hdlcdev_exit(SLMP_INFO *info); +#endif + +/* ioctl handlers */ + +static int get_stats(SLMP_INFO *info, struct mgsl_icount __user *user_icount); +static int get_params(SLMP_INFO *info, MGSL_PARAMS __user *params); +static int set_params(SLMP_INFO *info, MGSL_PARAMS __user *params); +static int get_txidle(SLMP_INFO *info, int __user *idle_mode); +static int set_txidle(SLMP_INFO *info, int idle_mode); +static int tx_enable(SLMP_INFO *info, int enable); +static int tx_abort(SLMP_INFO *info); +static int rx_enable(SLMP_INFO *info, int enable); +static int modem_input_wait(SLMP_INFO *info,int arg); +static int wait_mgsl_event(SLMP_INFO *info, int __user *mask_ptr); +static int tiocmget(struct tty_struct *tty); +static int tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear); +static int set_break(struct tty_struct *tty, int break_state); + +static void add_device(SLMP_INFO *info); +static void device_init(int adapter_num, struct pci_dev *pdev); +static int claim_resources(SLMP_INFO *info); +static void release_resources(SLMP_INFO *info); + +static int startup(SLMP_INFO *info); +static int block_til_ready(struct tty_struct *tty, struct file * filp,SLMP_INFO *info); +static int carrier_raised(struct tty_port *port); +static void shutdown(SLMP_INFO *info); +static void program_hw(SLMP_INFO *info); +static void change_params(SLMP_INFO *info); + +static bool init_adapter(SLMP_INFO *info); +static bool register_test(SLMP_INFO *info); +static bool irq_test(SLMP_INFO *info); +static bool loopback_test(SLMP_INFO *info); +static int adapter_test(SLMP_INFO *info); +static bool memory_test(SLMP_INFO *info); + +static void reset_adapter(SLMP_INFO *info); +static void reset_port(SLMP_INFO *info); +static void async_mode(SLMP_INFO *info); +static void hdlc_mode(SLMP_INFO *info); + +static void rx_stop(SLMP_INFO *info); +static void rx_start(SLMP_INFO *info); +static void rx_reset_buffers(SLMP_INFO *info); +static void rx_free_frame_buffers(SLMP_INFO *info, unsigned int first, unsigned int last); +static bool rx_get_frame(SLMP_INFO *info); + +static void tx_start(SLMP_INFO *info); +static void tx_stop(SLMP_INFO *info); +static void tx_load_fifo(SLMP_INFO *info); +static void tx_set_idle(SLMP_INFO *info); +static void tx_load_dma_buffer(SLMP_INFO *info, const char *buf, unsigned int count); + +static void get_signals(SLMP_INFO *info); +static void set_signals(SLMP_INFO *info); +static void enable_loopback(SLMP_INFO *info, int enable); +static void set_rate(SLMP_INFO *info, u32 data_rate); + +static int bh_action(SLMP_INFO *info); +static void bh_handler(struct work_struct *work); +static void bh_receive(SLMP_INFO *info); +static void bh_transmit(SLMP_INFO *info); +static void bh_status(SLMP_INFO *info); +static void isr_timer(SLMP_INFO *info); +static void isr_rxint(SLMP_INFO *info); +static void isr_rxrdy(SLMP_INFO *info); +static void isr_txint(SLMP_INFO *info); +static void isr_txrdy(SLMP_INFO *info); +static void isr_rxdmaok(SLMP_INFO *info); +static void isr_rxdmaerror(SLMP_INFO *info); +static void isr_txdmaok(SLMP_INFO *info); +static void isr_txdmaerror(SLMP_INFO *info); +static void isr_io_pin(SLMP_INFO *info, u16 status); + +static int alloc_dma_bufs(SLMP_INFO *info); +static void free_dma_bufs(SLMP_INFO *info); +static int alloc_buf_list(SLMP_INFO *info); +static int alloc_frame_bufs(SLMP_INFO *info, SCADESC *list, SCADESC_EX *list_ex,int count); +static int alloc_tmp_rx_buf(SLMP_INFO *info); +static void free_tmp_rx_buf(SLMP_INFO *info); + +static void load_pci_memory(SLMP_INFO *info, char* dest, const char* src, unsigned short count); +static void trace_block(SLMP_INFO *info, const char* data, int count, int xmit); +static void tx_timeout(unsigned long context); +static void status_timeout(unsigned long context); + +static unsigned char read_reg(SLMP_INFO *info, unsigned char addr); +static void write_reg(SLMP_INFO *info, unsigned char addr, unsigned char val); +static u16 read_reg16(SLMP_INFO *info, unsigned char addr); +static void write_reg16(SLMP_INFO *info, unsigned char addr, u16 val); +static unsigned char read_status_reg(SLMP_INFO * info); +static void write_control_reg(SLMP_INFO * info); + + +static unsigned char rx_active_fifo_level = 16; // rx request FIFO activation level in bytes +static unsigned char tx_active_fifo_level = 16; // tx request FIFO activation level in bytes +static unsigned char tx_negate_fifo_level = 32; // tx request FIFO negation level in bytes + +static u32 misc_ctrl_value = 0x007e4040; +static u32 lcr1_brdr_value = 0x00800028; + +static u32 read_ahead_count = 8; + +/* DPCR, DMA Priority Control + * + * 07..05 Not used, must be 0 + * 04 BRC, bus release condition: 0=all transfers complete + * 1=release after 1 xfer on all channels + * 03 CCC, channel change condition: 0=every cycle + * 1=after each channel completes all xfers + * 02..00 PR<2..0>, priority 100=round robin + * + * 00000100 = 0x00 + */ +static unsigned char dma_priority = 0x04; + +// Number of bytes that can be written to shared RAM +// in a single write operation +static u32 sca_pci_load_interval = 64; + +/* + * 1st function defined in .text section. Calling this function in + * init_module() followed by a breakpoint allows a remote debugger + * (gdb) to get the .text address for the add-symbol-file command. + * This allows remote debugging of dynamically loadable modules. + */ +static void* synclinkmp_get_text_ptr(void); +static void* synclinkmp_get_text_ptr(void) {return synclinkmp_get_text_ptr;} + +static inline int sanity_check(SLMP_INFO *info, + char *name, const char *routine) +{ +#ifdef SANITY_CHECK + static const char *badmagic = + "Warning: bad magic number for synclinkmp_struct (%s) in %s\n"; + static const char *badinfo = + "Warning: null synclinkmp_struct for (%s) in %s\n"; + + if (!info) { + printk(badinfo, name, routine); + return 1; + } + if (info->magic != MGSL_MAGIC) { + printk(badmagic, name, routine); + return 1; + } +#else + if (!info) + return 1; +#endif + return 0; +} + +/** + * line discipline callback wrappers + * + * The wrappers maintain line discipline references + * while calling into the line discipline. + * + * ldisc_receive_buf - pass receive data to line discipline + */ + +static void ldisc_receive_buf(struct tty_struct *tty, + const __u8 *data, char *flags, int count) +{ + struct tty_ldisc *ld; + if (!tty) + return; + ld = tty_ldisc_ref(tty); + if (ld) { + if (ld->ops->receive_buf) + ld->ops->receive_buf(tty, data, flags, count); + tty_ldisc_deref(ld); + } +} + +/* tty callbacks */ + +/* Called when a port is opened. Init and enable port. + */ +static int open(struct tty_struct *tty, struct file *filp) +{ + SLMP_INFO *info; + int retval, line; + unsigned long flags; + + line = tty->index; + if ((line < 0) || (line >= synclinkmp_device_count)) { + printk("%s(%d): open with invalid line #%d.\n", + __FILE__,__LINE__,line); + return -ENODEV; + } + + info = synclinkmp_device_list; + while(info && info->line != line) + info = info->next_device; + if (sanity_check(info, tty->name, "open")) + return -ENODEV; + if ( info->init_error ) { + printk("%s(%d):%s device is not allocated, init error=%d\n", + __FILE__,__LINE__,info->device_name,info->init_error); + return -ENODEV; + } + + tty->driver_data = info; + info->port.tty = tty; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s open(), old ref count = %d\n", + __FILE__,__LINE__,tty->driver->name, info->port.count); + + /* If port is closing, signal caller to try again */ + if (tty_hung_up_p(filp) || info->port.flags & ASYNC_CLOSING){ + if (info->port.flags & ASYNC_CLOSING) + interruptible_sleep_on(&info->port.close_wait); + retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS); + goto cleanup; + } + + info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; + + spin_lock_irqsave(&info->netlock, flags); + if (info->netcount) { + retval = -EBUSY; + spin_unlock_irqrestore(&info->netlock, flags); + goto cleanup; + } + info->port.count++; + spin_unlock_irqrestore(&info->netlock, flags); + + if (info->port.count == 1) { + /* 1st open on this device, init hardware */ + retval = startup(info); + if (retval < 0) + goto cleanup; + } + + retval = block_til_ready(tty, filp, info); + if (retval) { + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s block_til_ready() returned %d\n", + __FILE__,__LINE__, info->device_name, retval); + goto cleanup; + } + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s open() success\n", + __FILE__,__LINE__, info->device_name); + retval = 0; + +cleanup: + if (retval) { + if (tty->count == 1) + info->port.tty = NULL; /* tty layer will release tty struct */ + if(info->port.count) + info->port.count--; + } + + return retval; +} + +/* Called when port is closed. Wait for remaining data to be + * sent. Disable port and free resources. + */ +static void close(struct tty_struct *tty, struct file *filp) +{ + SLMP_INFO * info = tty->driver_data; + + if (sanity_check(info, tty->name, "close")) + return; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s close() entry, count=%d\n", + __FILE__,__LINE__, info->device_name, info->port.count); + + if (tty_port_close_start(&info->port, tty, filp) == 0) + goto cleanup; + + mutex_lock(&info->port.mutex); + if (info->port.flags & ASYNC_INITIALIZED) + wait_until_sent(tty, info->timeout); + + flush_buffer(tty); + tty_ldisc_flush(tty); + shutdown(info); + mutex_unlock(&info->port.mutex); + + tty_port_close_end(&info->port, tty); + info->port.tty = NULL; +cleanup: + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s close() exit, count=%d\n", __FILE__,__LINE__, + tty->driver->name, info->port.count); +} + +/* Called by tty_hangup() when a hangup is signaled. + * This is the same as closing all open descriptors for the port. + */ +static void hangup(struct tty_struct *tty) +{ + SLMP_INFO *info = tty->driver_data; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s hangup()\n", + __FILE__,__LINE__, info->device_name ); + + if (sanity_check(info, tty->name, "hangup")) + return; + + mutex_lock(&info->port.mutex); + flush_buffer(tty); + shutdown(info); + + spin_lock_irqsave(&info->port.lock, flags); + info->port.count = 0; + info->port.flags &= ~ASYNC_NORMAL_ACTIVE; + info->port.tty = NULL; + spin_unlock_irqrestore(&info->port.lock, flags); + mutex_unlock(&info->port.mutex); + + wake_up_interruptible(&info->port.open_wait); +} + +/* Set new termios settings + */ +static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) +{ + SLMP_INFO *info = tty->driver_data; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s set_termios()\n", __FILE__,__LINE__, + tty->driver->name ); + + change_params(info); + + /* Handle transition to B0 status */ + if (old_termios->c_cflag & CBAUD && + !(tty->termios->c_cflag & CBAUD)) { + info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); + spin_lock_irqsave(&info->lock,flags); + set_signals(info); + spin_unlock_irqrestore(&info->lock,flags); + } + + /* Handle transition away from B0 status */ + if (!(old_termios->c_cflag & CBAUD) && + tty->termios->c_cflag & CBAUD) { + info->serial_signals |= SerialSignal_DTR; + if (!(tty->termios->c_cflag & CRTSCTS) || + !test_bit(TTY_THROTTLED, &tty->flags)) { + info->serial_signals |= SerialSignal_RTS; + } + spin_lock_irqsave(&info->lock,flags); + set_signals(info); + spin_unlock_irqrestore(&info->lock,flags); + } + + /* Handle turning off CRTSCTS */ + if (old_termios->c_cflag & CRTSCTS && + !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + tx_release(tty); + } +} + +/* Send a block of data + * + * Arguments: + * + * tty pointer to tty information structure + * buf pointer to buffer containing send data + * count size of send data in bytes + * + * Return Value: number of characters written + */ +static int write(struct tty_struct *tty, + const unsigned char *buf, int count) +{ + int c, ret = 0; + SLMP_INFO *info = tty->driver_data; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s write() count=%d\n", + __FILE__,__LINE__,info->device_name,count); + + if (sanity_check(info, tty->name, "write")) + goto cleanup; + + if (!info->tx_buf) + goto cleanup; + + if (info->params.mode == MGSL_MODE_HDLC) { + if (count > info->max_frame_size) { + ret = -EIO; + goto cleanup; + } + if (info->tx_active) + goto cleanup; + if (info->tx_count) { + /* send accumulated data from send_char() calls */ + /* as frame and wait before accepting more data. */ + tx_load_dma_buffer(info, info->tx_buf, info->tx_count); + goto start; + } + ret = info->tx_count = count; + tx_load_dma_buffer(info, buf, count); + goto start; + } + + for (;;) { + c = min_t(int, count, + min(info->max_frame_size - info->tx_count - 1, + info->max_frame_size - info->tx_put)); + if (c <= 0) + break; + + memcpy(info->tx_buf + info->tx_put, buf, c); + + spin_lock_irqsave(&info->lock,flags); + info->tx_put += c; + if (info->tx_put >= info->max_frame_size) + info->tx_put -= info->max_frame_size; + info->tx_count += c; + spin_unlock_irqrestore(&info->lock,flags); + + buf += c; + count -= c; + ret += c; + } + + if (info->params.mode == MGSL_MODE_HDLC) { + if (count) { + ret = info->tx_count = 0; + goto cleanup; + } + tx_load_dma_buffer(info, info->tx_buf, info->tx_count); + } +start: + if (info->tx_count && !tty->stopped && !tty->hw_stopped) { + spin_lock_irqsave(&info->lock,flags); + if (!info->tx_active) + tx_start(info); + spin_unlock_irqrestore(&info->lock,flags); + } + +cleanup: + if (debug_level >= DEBUG_LEVEL_INFO) + printk( "%s(%d):%s write() returning=%d\n", + __FILE__,__LINE__,info->device_name,ret); + return ret; +} + +/* Add a character to the transmit buffer. + */ +static int put_char(struct tty_struct *tty, unsigned char ch) +{ + SLMP_INFO *info = tty->driver_data; + unsigned long flags; + int ret = 0; + + if ( debug_level >= DEBUG_LEVEL_INFO ) { + printk( "%s(%d):%s put_char(%d)\n", + __FILE__,__LINE__,info->device_name,ch); + } + + if (sanity_check(info, tty->name, "put_char")) + return 0; + + if (!info->tx_buf) + return 0; + + spin_lock_irqsave(&info->lock,flags); + + if ( (info->params.mode != MGSL_MODE_HDLC) || + !info->tx_active ) { + + if (info->tx_count < info->max_frame_size - 1) { + info->tx_buf[info->tx_put++] = ch; + if (info->tx_put >= info->max_frame_size) + info->tx_put -= info->max_frame_size; + info->tx_count++; + ret = 1; + } + } + + spin_unlock_irqrestore(&info->lock,flags); + return ret; +} + +/* Send a high-priority XON/XOFF character + */ +static void send_xchar(struct tty_struct *tty, char ch) +{ + SLMP_INFO *info = tty->driver_data; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s send_xchar(%d)\n", + __FILE__,__LINE__, info->device_name, ch ); + + if (sanity_check(info, tty->name, "send_xchar")) + return; + + info->x_char = ch; + if (ch) { + /* Make sure transmit interrupts are on */ + spin_lock_irqsave(&info->lock,flags); + if (!info->tx_enabled) + tx_start(info); + spin_unlock_irqrestore(&info->lock,flags); + } +} + +/* Wait until the transmitter is empty. + */ +static void wait_until_sent(struct tty_struct *tty, int timeout) +{ + SLMP_INFO * info = tty->driver_data; + unsigned long orig_jiffies, char_time; + + if (!info ) + return; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s wait_until_sent() entry\n", + __FILE__,__LINE__, info->device_name ); + + if (sanity_check(info, tty->name, "wait_until_sent")) + return; + + if (!test_bit(ASYNCB_INITIALIZED, &info->port.flags)) + goto exit; + + orig_jiffies = jiffies; + + /* Set check interval to 1/5 of estimated time to + * send a character, and make it at least 1. The check + * interval should also be less than the timeout. + * Note: use tight timings here to satisfy the NIST-PCTS. + */ + + if ( info->params.data_rate ) { + char_time = info->timeout/(32 * 5); + if (!char_time) + char_time++; + } else + char_time = 1; + + if (timeout) + char_time = min_t(unsigned long, char_time, timeout); + + if ( info->params.mode == MGSL_MODE_HDLC ) { + while (info->tx_active) { + msleep_interruptible(jiffies_to_msecs(char_time)); + if (signal_pending(current)) + break; + if (timeout && time_after(jiffies, orig_jiffies + timeout)) + break; + } + } else { + /* + * TODO: determine if there is something similar to USC16C32 + * TXSTATUS_ALL_SENT status + */ + while ( info->tx_active && info->tx_enabled) { + msleep_interruptible(jiffies_to_msecs(char_time)); + if (signal_pending(current)) + break; + if (timeout && time_after(jiffies, orig_jiffies + timeout)) + break; + } + } + +exit: + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s wait_until_sent() exit\n", + __FILE__,__LINE__, info->device_name ); +} + +/* Return the count of free bytes in transmit buffer + */ +static int write_room(struct tty_struct *tty) +{ + SLMP_INFO *info = tty->driver_data; + int ret; + + if (sanity_check(info, tty->name, "write_room")) + return 0; + + if (info->params.mode == MGSL_MODE_HDLC) { + ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE; + } else { + ret = info->max_frame_size - info->tx_count - 1; + if (ret < 0) + ret = 0; + } + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s write_room()=%d\n", + __FILE__, __LINE__, info->device_name, ret); + + return ret; +} + +/* enable transmitter and send remaining buffered characters + */ +static void flush_chars(struct tty_struct *tty) +{ + SLMP_INFO *info = tty->driver_data; + unsigned long flags; + + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):%s flush_chars() entry tx_count=%d\n", + __FILE__,__LINE__,info->device_name,info->tx_count); + + if (sanity_check(info, tty->name, "flush_chars")) + return; + + if (info->tx_count <= 0 || tty->stopped || tty->hw_stopped || + !info->tx_buf) + return; + + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):%s flush_chars() entry, starting transmitter\n", + __FILE__,__LINE__,info->device_name ); + + spin_lock_irqsave(&info->lock,flags); + + if (!info->tx_active) { + if ( (info->params.mode == MGSL_MODE_HDLC) && + info->tx_count ) { + /* operating in synchronous (frame oriented) mode */ + /* copy data from circular tx_buf to */ + /* transmit DMA buffer. */ + tx_load_dma_buffer(info, + info->tx_buf,info->tx_count); + } + tx_start(info); + } + + spin_unlock_irqrestore(&info->lock,flags); +} + +/* Discard all data in the send buffer + */ +static void flush_buffer(struct tty_struct *tty) +{ + SLMP_INFO *info = tty->driver_data; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s flush_buffer() entry\n", + __FILE__,__LINE__, info->device_name ); + + if (sanity_check(info, tty->name, "flush_buffer")) + return; + + spin_lock_irqsave(&info->lock,flags); + info->tx_count = info->tx_put = info->tx_get = 0; + del_timer(&info->tx_timer); + spin_unlock_irqrestore(&info->lock,flags); + + tty_wakeup(tty); +} + +/* throttle (stop) transmitter + */ +static void tx_hold(struct tty_struct *tty) +{ + SLMP_INFO *info = tty->driver_data; + unsigned long flags; + + if (sanity_check(info, tty->name, "tx_hold")) + return; + + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk("%s(%d):%s tx_hold()\n", + __FILE__,__LINE__,info->device_name); + + spin_lock_irqsave(&info->lock,flags); + if (info->tx_enabled) + tx_stop(info); + spin_unlock_irqrestore(&info->lock,flags); +} + +/* release (start) transmitter + */ +static void tx_release(struct tty_struct *tty) +{ + SLMP_INFO *info = tty->driver_data; + unsigned long flags; + + if (sanity_check(info, tty->name, "tx_release")) + return; + + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk("%s(%d):%s tx_release()\n", + __FILE__,__LINE__,info->device_name); + + spin_lock_irqsave(&info->lock,flags); + if (!info->tx_enabled) + tx_start(info); + spin_unlock_irqrestore(&info->lock,flags); +} + +/* Service an IOCTL request + * + * Arguments: + * + * tty pointer to tty instance data + * cmd IOCTL command code + * arg command argument/context + * + * Return Value: 0 if success, otherwise error code + */ +static int ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + SLMP_INFO *info = tty->driver_data; + void __user *argp = (void __user *)arg; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s ioctl() cmd=%08X\n", __FILE__,__LINE__, + info->device_name, cmd ); + + if (sanity_check(info, tty->name, "ioctl")) + return -ENODEV; + + if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && + (cmd != TIOCMIWAIT)) { + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + } + + switch (cmd) { + case MGSL_IOCGPARAMS: + return get_params(info, argp); + case MGSL_IOCSPARAMS: + return set_params(info, argp); + case MGSL_IOCGTXIDLE: + return get_txidle(info, argp); + case MGSL_IOCSTXIDLE: + return set_txidle(info, (int)arg); + case MGSL_IOCTXENABLE: + return tx_enable(info, (int)arg); + case MGSL_IOCRXENABLE: + return rx_enable(info, (int)arg); + case MGSL_IOCTXABORT: + return tx_abort(info); + case MGSL_IOCGSTATS: + return get_stats(info, argp); + case MGSL_IOCWAITEVENT: + return wait_mgsl_event(info, argp); + case MGSL_IOCLOOPTXDONE: + return 0; // TODO: Not supported, need to document + /* Wait for modem input (DCD,RI,DSR,CTS) change + * as specified by mask in arg (TIOCM_RNG/DSR/CD/CTS) + */ + case TIOCMIWAIT: + return modem_input_wait(info,(int)arg); + + /* + * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) + * Return: write counters to the user passed counter struct + * NB: both 1->0 and 0->1 transitions are counted except for + * RI where only 0->1 is counted. + */ + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static int get_icount(struct tty_struct *tty, + struct serial_icounter_struct *icount) +{ + SLMP_INFO *info = tty->driver_data; + struct mgsl_icount cnow; /* kernel counter temps */ + unsigned long flags; + + spin_lock_irqsave(&info->lock,flags); + cnow = info->icount; + spin_unlock_irqrestore(&info->lock,flags); + + icount->cts = cnow.cts; + icount->dsr = cnow.dsr; + icount->rng = cnow.rng; + icount->dcd = cnow.dcd; + icount->rx = cnow.rx; + icount->tx = cnow.tx; + icount->frame = cnow.frame; + icount->overrun = cnow.overrun; + icount->parity = cnow.parity; + icount->brk = cnow.brk; + icount->buf_overrun = cnow.buf_overrun; + + return 0; +} + +/* + * /proc fs routines.... + */ + +static inline void line_info(struct seq_file *m, SLMP_INFO *info) +{ + char stat_buf[30]; + unsigned long flags; + + seq_printf(m, "%s: SCABase=%08x Mem=%08X StatusControl=%08x LCR=%08X\n" + "\tIRQ=%d MaxFrameSize=%u\n", + info->device_name, + info->phys_sca_base, + info->phys_memory_base, + info->phys_statctrl_base, + info->phys_lcr_base, + info->irq_level, + info->max_frame_size ); + + /* output current serial signal states */ + spin_lock_irqsave(&info->lock,flags); + get_signals(info); + spin_unlock_irqrestore(&info->lock,flags); + + stat_buf[0] = 0; + stat_buf[1] = 0; + if (info->serial_signals & SerialSignal_RTS) + strcat(stat_buf, "|RTS"); + if (info->serial_signals & SerialSignal_CTS) + strcat(stat_buf, "|CTS"); + if (info->serial_signals & SerialSignal_DTR) + strcat(stat_buf, "|DTR"); + if (info->serial_signals & SerialSignal_DSR) + strcat(stat_buf, "|DSR"); + if (info->serial_signals & SerialSignal_DCD) + strcat(stat_buf, "|CD"); + if (info->serial_signals & SerialSignal_RI) + strcat(stat_buf, "|RI"); + + if (info->params.mode == MGSL_MODE_HDLC) { + seq_printf(m, "\tHDLC txok:%d rxok:%d", + info->icount.txok, info->icount.rxok); + if (info->icount.txunder) + seq_printf(m, " txunder:%d", info->icount.txunder); + if (info->icount.txabort) + seq_printf(m, " txabort:%d", info->icount.txabort); + if (info->icount.rxshort) + seq_printf(m, " rxshort:%d", info->icount.rxshort); + if (info->icount.rxlong) + seq_printf(m, " rxlong:%d", info->icount.rxlong); + if (info->icount.rxover) + seq_printf(m, " rxover:%d", info->icount.rxover); + if (info->icount.rxcrc) + seq_printf(m, " rxlong:%d", info->icount.rxcrc); + } else { + seq_printf(m, "\tASYNC tx:%d rx:%d", + info->icount.tx, info->icount.rx); + if (info->icount.frame) + seq_printf(m, " fe:%d", info->icount.frame); + if (info->icount.parity) + seq_printf(m, " pe:%d", info->icount.parity); + if (info->icount.brk) + seq_printf(m, " brk:%d", info->icount.brk); + if (info->icount.overrun) + seq_printf(m, " oe:%d", info->icount.overrun); + } + + /* Append serial signal status to end */ + seq_printf(m, " %s\n", stat_buf+1); + + seq_printf(m, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", + info->tx_active,info->bh_requested,info->bh_running, + info->pending_bh); +} + +/* Called to print information about devices + */ +static int synclinkmp_proc_show(struct seq_file *m, void *v) +{ + SLMP_INFO *info; + + seq_printf(m, "synclinkmp driver:%s\n", driver_version); + + info = synclinkmp_device_list; + while( info ) { + line_info(m, info); + info = info->next_device; + } + return 0; +} + +static int synclinkmp_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, synclinkmp_proc_show, NULL); +} + +static const struct file_operations synclinkmp_proc_fops = { + .owner = THIS_MODULE, + .open = synclinkmp_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* Return the count of bytes in transmit buffer + */ +static int chars_in_buffer(struct tty_struct *tty) +{ + SLMP_INFO *info = tty->driver_data; + + if (sanity_check(info, tty->name, "chars_in_buffer")) + return 0; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s chars_in_buffer()=%d\n", + __FILE__, __LINE__, info->device_name, info->tx_count); + + return info->tx_count; +} + +/* Signal remote device to throttle send data (our receive data) + */ +static void throttle(struct tty_struct * tty) +{ + SLMP_INFO *info = tty->driver_data; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s throttle() entry\n", + __FILE__,__LINE__, info->device_name ); + + if (sanity_check(info, tty->name, "throttle")) + return; + + if (I_IXOFF(tty)) + send_xchar(tty, STOP_CHAR(tty)); + + if (tty->termios->c_cflag & CRTSCTS) { + spin_lock_irqsave(&info->lock,flags); + info->serial_signals &= ~SerialSignal_RTS; + set_signals(info); + spin_unlock_irqrestore(&info->lock,flags); + } +} + +/* Signal remote device to stop throttling send data (our receive data) + */ +static void unthrottle(struct tty_struct * tty) +{ + SLMP_INFO *info = tty->driver_data; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s unthrottle() entry\n", + __FILE__,__LINE__, info->device_name ); + + if (sanity_check(info, tty->name, "unthrottle")) + return; + + if (I_IXOFF(tty)) { + if (info->x_char) + info->x_char = 0; + else + send_xchar(tty, START_CHAR(tty)); + } + + if (tty->termios->c_cflag & CRTSCTS) { + spin_lock_irqsave(&info->lock,flags); + info->serial_signals |= SerialSignal_RTS; + set_signals(info); + spin_unlock_irqrestore(&info->lock,flags); + } +} + +/* set or clear transmit break condition + * break_state -1=set break condition, 0=clear + */ +static int set_break(struct tty_struct *tty, int break_state) +{ + unsigned char RegValue; + SLMP_INFO * info = tty->driver_data; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s set_break(%d)\n", + __FILE__,__LINE__, info->device_name, break_state); + + if (sanity_check(info, tty->name, "set_break")) + return -EINVAL; + + spin_lock_irqsave(&info->lock,flags); + RegValue = read_reg(info, CTL); + if (break_state == -1) + RegValue |= BIT3; + else + RegValue &= ~BIT3; + write_reg(info, CTL, RegValue); + spin_unlock_irqrestore(&info->lock,flags); + return 0; +} + +#if SYNCLINK_GENERIC_HDLC + +/** + * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) + * set encoding and frame check sequence (FCS) options + * + * dev pointer to network device structure + * encoding serial encoding setting + * parity FCS setting + * + * returns 0 if success, otherwise error code + */ +static int hdlcdev_attach(struct net_device *dev, unsigned short encoding, + unsigned short parity) +{ + SLMP_INFO *info = dev_to_port(dev); + unsigned char new_encoding; + unsigned short new_crctype; + + /* return error if TTY interface open */ + if (info->port.count) + return -EBUSY; + + switch (encoding) + { + case ENCODING_NRZ: new_encoding = HDLC_ENCODING_NRZ; break; + case ENCODING_NRZI: new_encoding = HDLC_ENCODING_NRZI_SPACE; break; + case ENCODING_FM_MARK: new_encoding = HDLC_ENCODING_BIPHASE_MARK; break; + case ENCODING_FM_SPACE: new_encoding = HDLC_ENCODING_BIPHASE_SPACE; break; + case ENCODING_MANCHESTER: new_encoding = HDLC_ENCODING_BIPHASE_LEVEL; break; + default: return -EINVAL; + } + + switch (parity) + { + case PARITY_NONE: new_crctype = HDLC_CRC_NONE; break; + case PARITY_CRC16_PR1_CCITT: new_crctype = HDLC_CRC_16_CCITT; break; + case PARITY_CRC32_PR1_CCITT: new_crctype = HDLC_CRC_32_CCITT; break; + default: return -EINVAL; + } + + info->params.encoding = new_encoding; + info->params.crc_type = new_crctype; + + /* if network interface up, reprogram hardware */ + if (info->netcount) + program_hw(info); + + return 0; +} + +/** + * called by generic HDLC layer to send frame + * + * skb socket buffer containing HDLC frame + * dev pointer to network device structure + */ +static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + SLMP_INFO *info = dev_to_port(dev); + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk(KERN_INFO "%s:hdlc_xmit(%s)\n",__FILE__,dev->name); + + /* stop sending until this frame completes */ + netif_stop_queue(dev); + + /* copy data to device buffers */ + info->tx_count = skb->len; + tx_load_dma_buffer(info, skb->data, skb->len); + + /* update network statistics */ + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + + /* done with socket buffer, so free it */ + dev_kfree_skb(skb); + + /* save start time for transmit timeout detection */ + dev->trans_start = jiffies; + + /* start hardware transmitter if necessary */ + spin_lock_irqsave(&info->lock,flags); + if (!info->tx_active) + tx_start(info); + spin_unlock_irqrestore(&info->lock,flags); + + return NETDEV_TX_OK; +} + +/** + * called by network layer when interface enabled + * claim resources and initialize hardware + * + * dev pointer to network device structure + * + * returns 0 if success, otherwise error code + */ +static int hdlcdev_open(struct net_device *dev) +{ + SLMP_INFO *info = dev_to_port(dev); + int rc; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s:hdlcdev_open(%s)\n",__FILE__,dev->name); + + /* generic HDLC layer open processing */ + if ((rc = hdlc_open(dev))) + return rc; + + /* arbitrate between network and tty opens */ + spin_lock_irqsave(&info->netlock, flags); + if (info->port.count != 0 || info->netcount != 0) { + printk(KERN_WARNING "%s: hdlc_open returning busy\n", dev->name); + spin_unlock_irqrestore(&info->netlock, flags); + return -EBUSY; + } + info->netcount=1; + spin_unlock_irqrestore(&info->netlock, flags); + + /* claim resources and init adapter */ + if ((rc = startup(info)) != 0) { + spin_lock_irqsave(&info->netlock, flags); + info->netcount=0; + spin_unlock_irqrestore(&info->netlock, flags); + return rc; + } + + /* assert DTR and RTS, apply hardware settings */ + info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; + program_hw(info); + + /* enable network layer transmit */ + dev->trans_start = jiffies; + netif_start_queue(dev); + + /* inform generic HDLC layer of current DCD status */ + spin_lock_irqsave(&info->lock, flags); + get_signals(info); + spin_unlock_irqrestore(&info->lock, flags); + if (info->serial_signals & SerialSignal_DCD) + netif_carrier_on(dev); + else + netif_carrier_off(dev); + return 0; +} + +/** + * called by network layer when interface is disabled + * shutdown hardware and release resources + * + * dev pointer to network device structure + * + * returns 0 if success, otherwise error code + */ +static int hdlcdev_close(struct net_device *dev) +{ + SLMP_INFO *info = dev_to_port(dev); + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s:hdlcdev_close(%s)\n",__FILE__,dev->name); + + netif_stop_queue(dev); + + /* shutdown adapter and release resources */ + shutdown(info); + + hdlc_close(dev); + + spin_lock_irqsave(&info->netlock, flags); + info->netcount=0; + spin_unlock_irqrestore(&info->netlock, flags); + + return 0; +} + +/** + * called by network layer to process IOCTL call to network device + * + * dev pointer to network device structure + * ifr pointer to network interface request structure + * cmd IOCTL command code + * + * returns 0 if success, otherwise error code + */ +static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + const size_t size = sizeof(sync_serial_settings); + sync_serial_settings new_line; + sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; + SLMP_INFO *info = dev_to_port(dev); + unsigned int flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s:hdlcdev_ioctl(%s)\n",__FILE__,dev->name); + + /* return error if TTY interface open */ + if (info->port.count) + return -EBUSY; + + if (cmd != SIOCWANDEV) + return hdlc_ioctl(dev, ifr, cmd); + + switch(ifr->ifr_settings.type) { + case IF_GET_IFACE: /* return current sync_serial_settings */ + + ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL; + if (ifr->ifr_settings.size < size) { + ifr->ifr_settings.size = size; /* data size wanted */ + return -ENOBUFS; + } + + flags = info->params.flags & (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | + HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | + HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | + HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); + + switch (flags){ + case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN): new_line.clock_type = CLOCK_EXT; break; + case (HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG): new_line.clock_type = CLOCK_INT; break; + case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG): new_line.clock_type = CLOCK_TXINT; break; + case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN): new_line.clock_type = CLOCK_TXFROMRX; break; + default: new_line.clock_type = CLOCK_DEFAULT; + } + + new_line.clock_rate = info->params.clock_speed; + new_line.loopback = info->params.loopback ? 1:0; + + if (copy_to_user(line, &new_line, size)) + return -EFAULT; + return 0; + + case IF_IFACE_SYNC_SERIAL: /* set sync_serial_settings */ + + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + if (copy_from_user(&new_line, line, size)) + return -EFAULT; + + switch (new_line.clock_type) + { + case CLOCK_EXT: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN; break; + case CLOCK_TXFROMRX: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN; break; + case CLOCK_INT: flags = HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG; break; + case CLOCK_TXINT: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG; break; + case CLOCK_DEFAULT: flags = info->params.flags & + (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | + HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | + HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | + HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); break; + default: return -EINVAL; + } + + if (new_line.loopback != 0 && new_line.loopback != 1) + return -EINVAL; + + info->params.flags &= ~(HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | + HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | + HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | + HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); + info->params.flags |= flags; + + info->params.loopback = new_line.loopback; + + if (flags & (HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG)) + info->params.clock_speed = new_line.clock_rate; + else + info->params.clock_speed = 0; + + /* if network interface up, reprogram hardware */ + if (info->netcount) + program_hw(info); + return 0; + + default: + return hdlc_ioctl(dev, ifr, cmd); + } +} + +/** + * called by network layer when transmit timeout is detected + * + * dev pointer to network device structure + */ +static void hdlcdev_tx_timeout(struct net_device *dev) +{ + SLMP_INFO *info = dev_to_port(dev); + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("hdlcdev_tx_timeout(%s)\n",dev->name); + + dev->stats.tx_errors++; + dev->stats.tx_aborted_errors++; + + spin_lock_irqsave(&info->lock,flags); + tx_stop(info); + spin_unlock_irqrestore(&info->lock,flags); + + netif_wake_queue(dev); +} + +/** + * called by device driver when transmit completes + * reenable network layer transmit if stopped + * + * info pointer to device instance information + */ +static void hdlcdev_tx_done(SLMP_INFO *info) +{ + if (netif_queue_stopped(info->netdev)) + netif_wake_queue(info->netdev); +} + +/** + * called by device driver when frame received + * pass frame to network layer + * + * info pointer to device instance information + * buf pointer to buffer contianing frame data + * size count of data bytes in buf + */ +static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size) +{ + struct sk_buff *skb = dev_alloc_skb(size); + struct net_device *dev = info->netdev; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("hdlcdev_rx(%s)\n",dev->name); + + if (skb == NULL) { + printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n", + dev->name); + dev->stats.rx_dropped++; + return; + } + + memcpy(skb_put(skb, size), buf, size); + + skb->protocol = hdlc_type_trans(skb, dev); + + dev->stats.rx_packets++; + dev->stats.rx_bytes += size; + + netif_rx(skb); +} + +static const struct net_device_ops hdlcdev_ops = { + .ndo_open = hdlcdev_open, + .ndo_stop = hdlcdev_close, + .ndo_change_mtu = hdlc_change_mtu, + .ndo_start_xmit = hdlc_start_xmit, + .ndo_do_ioctl = hdlcdev_ioctl, + .ndo_tx_timeout = hdlcdev_tx_timeout, +}; + +/** + * called by device driver when adding device instance + * do generic HDLC initialization + * + * info pointer to device instance information + * + * returns 0 if success, otherwise error code + */ +static int hdlcdev_init(SLMP_INFO *info) +{ + int rc; + struct net_device *dev; + hdlc_device *hdlc; + + /* allocate and initialize network and HDLC layer objects */ + + if (!(dev = alloc_hdlcdev(info))) { + printk(KERN_ERR "%s:hdlc device allocation failure\n",__FILE__); + return -ENOMEM; + } + + /* for network layer reporting purposes only */ + dev->mem_start = info->phys_sca_base; + dev->mem_end = info->phys_sca_base + SCA_BASE_SIZE - 1; + dev->irq = info->irq_level; + + /* network layer callbacks and settings */ + dev->netdev_ops = &hdlcdev_ops; + dev->watchdog_timeo = 10 * HZ; + dev->tx_queue_len = 50; + + /* generic HDLC layer callbacks and settings */ + hdlc = dev_to_hdlc(dev); + hdlc->attach = hdlcdev_attach; + hdlc->xmit = hdlcdev_xmit; + + /* register objects with HDLC layer */ + if ((rc = register_hdlc_device(dev))) { + printk(KERN_WARNING "%s:unable to register hdlc device\n",__FILE__); + free_netdev(dev); + return rc; + } + + info->netdev = dev; + return 0; +} + +/** + * called by device driver when removing device instance + * do generic HDLC cleanup + * + * info pointer to device instance information + */ +static void hdlcdev_exit(SLMP_INFO *info) +{ + unregister_hdlc_device(info->netdev); + free_netdev(info->netdev); + info->netdev = NULL; +} + +#endif /* CONFIG_HDLC */ + + +/* Return next bottom half action to perform. + * Return Value: BH action code or 0 if nothing to do. + */ +static int bh_action(SLMP_INFO *info) +{ + unsigned long flags; + int rc = 0; + + spin_lock_irqsave(&info->lock,flags); + + if (info->pending_bh & BH_RECEIVE) { + info->pending_bh &= ~BH_RECEIVE; + rc = BH_RECEIVE; + } else if (info->pending_bh & BH_TRANSMIT) { + info->pending_bh &= ~BH_TRANSMIT; + rc = BH_TRANSMIT; + } else if (info->pending_bh & BH_STATUS) { + info->pending_bh &= ~BH_STATUS; + rc = BH_STATUS; + } + + if (!rc) { + /* Mark BH routine as complete */ + info->bh_running = false; + info->bh_requested = false; + } + + spin_unlock_irqrestore(&info->lock,flags); + + return rc; +} + +/* Perform bottom half processing of work items queued by ISR. + */ +static void bh_handler(struct work_struct *work) +{ + SLMP_INFO *info = container_of(work, SLMP_INFO, task); + int action; + + if (!info) + return; + + if ( debug_level >= DEBUG_LEVEL_BH ) + printk( "%s(%d):%s bh_handler() entry\n", + __FILE__,__LINE__,info->device_name); + + info->bh_running = true; + + while((action = bh_action(info)) != 0) { + + /* Process work item */ + if ( debug_level >= DEBUG_LEVEL_BH ) + printk( "%s(%d):%s bh_handler() work item action=%d\n", + __FILE__,__LINE__,info->device_name, action); + + switch (action) { + + case BH_RECEIVE: + bh_receive(info); + break; + case BH_TRANSMIT: + bh_transmit(info); + break; + case BH_STATUS: + bh_status(info); + break; + default: + /* unknown work item ID */ + printk("%s(%d):%s Unknown work item ID=%08X!\n", + __FILE__,__LINE__,info->device_name,action); + break; + } + } + + if ( debug_level >= DEBUG_LEVEL_BH ) + printk( "%s(%d):%s bh_handler() exit\n", + __FILE__,__LINE__,info->device_name); +} + +static void bh_receive(SLMP_INFO *info) +{ + if ( debug_level >= DEBUG_LEVEL_BH ) + printk( "%s(%d):%s bh_receive()\n", + __FILE__,__LINE__,info->device_name); + + while( rx_get_frame(info) ); +} + +static void bh_transmit(SLMP_INFO *info) +{ + struct tty_struct *tty = info->port.tty; + + if ( debug_level >= DEBUG_LEVEL_BH ) + printk( "%s(%d):%s bh_transmit() entry\n", + __FILE__,__LINE__,info->device_name); + + if (tty) + tty_wakeup(tty); +} + +static void bh_status(SLMP_INFO *info) +{ + if ( debug_level >= DEBUG_LEVEL_BH ) + printk( "%s(%d):%s bh_status() entry\n", + __FILE__,__LINE__,info->device_name); + + info->ri_chkcount = 0; + info->dsr_chkcount = 0; + info->dcd_chkcount = 0; + info->cts_chkcount = 0; +} + +static void isr_timer(SLMP_INFO * info) +{ + unsigned char timer = (info->port_num & 1) ? TIMER2 : TIMER0; + + /* IER2<7..4> = timer<3..0> interrupt enables (0=disabled) */ + write_reg(info, IER2, 0); + + /* TMCS, Timer Control/Status Register + * + * 07 CMF, Compare match flag (read only) 1=match + * 06 ECMI, CMF Interrupt Enable: 0=disabled + * 05 Reserved, must be 0 + * 04 TME, Timer Enable + * 03..00 Reserved, must be 0 + * + * 0000 0000 + */ + write_reg(info, (unsigned char)(timer + TMCS), 0); + + info->irq_occurred = true; + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):%s isr_timer()\n", + __FILE__,__LINE__,info->device_name); +} + +static void isr_rxint(SLMP_INFO * info) +{ + struct tty_struct *tty = info->port.tty; + struct mgsl_icount *icount = &info->icount; + unsigned char status = read_reg(info, SR1) & info->ie1_value & (FLGD + IDLD + CDCD + BRKD); + unsigned char status2 = read_reg(info, SR2) & info->ie2_value & OVRN; + + /* clear status bits */ + if (status) + write_reg(info, SR1, status); + + if (status2) + write_reg(info, SR2, status2); + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):%s isr_rxint status=%02X %02x\n", + __FILE__,__LINE__,info->device_name,status,status2); + + if (info->params.mode == MGSL_MODE_ASYNC) { + if (status & BRKD) { + icount->brk++; + + /* process break detection if tty control + * is not set to ignore it + */ + if ( tty ) { + if (!(status & info->ignore_status_mask1)) { + if (info->read_status_mask1 & BRKD) { + tty_insert_flip_char(tty, 0, TTY_BREAK); + if (info->port.flags & ASYNC_SAK) + do_SAK(tty); + } + } + } + } + } + else { + if (status & (FLGD|IDLD)) { + if (status & FLGD) + info->icount.exithunt++; + else if (status & IDLD) + info->icount.rxidle++; + wake_up_interruptible(&info->event_wait_q); + } + } + + if (status & CDCD) { + /* simulate a common modem status change interrupt + * for our handler + */ + get_signals( info ); + isr_io_pin(info, + MISCSTATUS_DCD_LATCHED|(info->serial_signals&SerialSignal_DCD)); + } +} + +/* + * handle async rx data interrupts + */ +static void isr_rxrdy(SLMP_INFO * info) +{ + u16 status; + unsigned char DataByte; + struct tty_struct *tty = info->port.tty; + struct mgsl_icount *icount = &info->icount; + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):%s isr_rxrdy\n", + __FILE__,__LINE__,info->device_name); + + while((status = read_reg(info,CST0)) & BIT0) + { + int flag = 0; + bool over = false; + DataByte = read_reg(info,TRB); + + icount->rx++; + + if ( status & (PE + FRME + OVRN) ) { + printk("%s(%d):%s rxerr=%04X\n", + __FILE__,__LINE__,info->device_name,status); + + /* update error statistics */ + if (status & PE) + icount->parity++; + else if (status & FRME) + icount->frame++; + else if (status & OVRN) + icount->overrun++; + + /* discard char if tty control flags say so */ + if (status & info->ignore_status_mask2) + continue; + + status &= info->read_status_mask2; + + if ( tty ) { + if (status & PE) + flag = TTY_PARITY; + else if (status & FRME) + flag = TTY_FRAME; + if (status & OVRN) { + /* Overrun is special, since it's + * reported immediately, and doesn't + * affect the current character + */ + over = true; + } + } + } /* end of if (error) */ + + if ( tty ) { + tty_insert_flip_char(tty, DataByte, flag); + if (over) + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + } + } + + if ( debug_level >= DEBUG_LEVEL_ISR ) { + printk("%s(%d):%s rx=%d brk=%d parity=%d frame=%d overrun=%d\n", + __FILE__,__LINE__,info->device_name, + icount->rx,icount->brk,icount->parity, + icount->frame,icount->overrun); + } + + if ( tty ) + tty_flip_buffer_push(tty); +} + +static void isr_txeom(SLMP_INFO * info, unsigned char status) +{ + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):%s isr_txeom status=%02x\n", + __FILE__,__LINE__,info->device_name,status); + + write_reg(info, TXDMA + DIR, 0x00); /* disable Tx DMA IRQs */ + write_reg(info, TXDMA + DSR, 0xc0); /* clear IRQs and disable DMA */ + write_reg(info, TXDMA + DCMD, SWABORT); /* reset/init DMA channel */ + + if (status & UDRN) { + write_reg(info, CMD, TXRESET); + write_reg(info, CMD, TXENABLE); + } else + write_reg(info, CMD, TXBUFCLR); + + /* disable and clear tx interrupts */ + info->ie0_value &= ~TXRDYE; + info->ie1_value &= ~(IDLE + UDRN); + write_reg16(info, IE0, (unsigned short)((info->ie1_value << 8) + info->ie0_value)); + write_reg(info, SR1, (unsigned char)(UDRN + IDLE)); + + if ( info->tx_active ) { + if (info->params.mode != MGSL_MODE_ASYNC) { + if (status & UDRN) + info->icount.txunder++; + else if (status & IDLE) + info->icount.txok++; + } + + info->tx_active = false; + info->tx_count = info->tx_put = info->tx_get = 0; + + del_timer(&info->tx_timer); + + if (info->params.mode != MGSL_MODE_ASYNC && info->drop_rts_on_tx_done ) { + info->serial_signals &= ~SerialSignal_RTS; + info->drop_rts_on_tx_done = false; + set_signals(info); + } + +#if SYNCLINK_GENERIC_HDLC + if (info->netcount) + hdlcdev_tx_done(info); + else +#endif + { + if (info->port.tty && (info->port.tty->stopped || info->port.tty->hw_stopped)) { + tx_stop(info); + return; + } + info->pending_bh |= BH_TRANSMIT; + } + } +} + + +/* + * handle tx status interrupts + */ +static void isr_txint(SLMP_INFO * info) +{ + unsigned char status = read_reg(info, SR1) & info->ie1_value & (UDRN + IDLE + CCTS); + + /* clear status bits */ + write_reg(info, SR1, status); + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):%s isr_txint status=%02x\n", + __FILE__,__LINE__,info->device_name,status); + + if (status & (UDRN + IDLE)) + isr_txeom(info, status); + + if (status & CCTS) { + /* simulate a common modem status change interrupt + * for our handler + */ + get_signals( info ); + isr_io_pin(info, + MISCSTATUS_CTS_LATCHED|(info->serial_signals&SerialSignal_CTS)); + + } +} + +/* + * handle async tx data interrupts + */ +static void isr_txrdy(SLMP_INFO * info) +{ + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):%s isr_txrdy() tx_count=%d\n", + __FILE__,__LINE__,info->device_name,info->tx_count); + + if (info->params.mode != MGSL_MODE_ASYNC) { + /* disable TXRDY IRQ, enable IDLE IRQ */ + info->ie0_value &= ~TXRDYE; + info->ie1_value |= IDLE; + write_reg16(info, IE0, (unsigned short)((info->ie1_value << 8) + info->ie0_value)); + return; + } + + if (info->port.tty && (info->port.tty->stopped || info->port.tty->hw_stopped)) { + tx_stop(info); + return; + } + + if ( info->tx_count ) + tx_load_fifo( info ); + else { + info->tx_active = false; + info->ie0_value &= ~TXRDYE; + write_reg(info, IE0, info->ie0_value); + } + + if (info->tx_count < WAKEUP_CHARS) + info->pending_bh |= BH_TRANSMIT; +} + +static void isr_rxdmaok(SLMP_INFO * info) +{ + /* BIT7 = EOT (end of transfer) + * BIT6 = EOM (end of message/frame) + */ + unsigned char status = read_reg(info,RXDMA + DSR) & 0xc0; + + /* clear IRQ (BIT0 must be 1 to prevent clearing DE bit) */ + write_reg(info, RXDMA + DSR, (unsigned char)(status | 1)); + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):%s isr_rxdmaok(), status=%02x\n", + __FILE__,__LINE__,info->device_name,status); + + info->pending_bh |= BH_RECEIVE; +} + +static void isr_rxdmaerror(SLMP_INFO * info) +{ + /* BIT5 = BOF (buffer overflow) + * BIT4 = COF (counter overflow) + */ + unsigned char status = read_reg(info,RXDMA + DSR) & 0x30; + + /* clear IRQ (BIT0 must be 1 to prevent clearing DE bit) */ + write_reg(info, RXDMA + DSR, (unsigned char)(status | 1)); + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):%s isr_rxdmaerror(), status=%02x\n", + __FILE__,__LINE__,info->device_name,status); + + info->rx_overflow = true; + info->pending_bh |= BH_RECEIVE; +} + +static void isr_txdmaok(SLMP_INFO * info) +{ + unsigned char status_reg1 = read_reg(info, SR1); + + write_reg(info, TXDMA + DIR, 0x00); /* disable Tx DMA IRQs */ + write_reg(info, TXDMA + DSR, 0xc0); /* clear IRQs and disable DMA */ + write_reg(info, TXDMA + DCMD, SWABORT); /* reset/init DMA channel */ + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):%s isr_txdmaok(), status=%02x\n", + __FILE__,__LINE__,info->device_name,status_reg1); + + /* program TXRDY as FIFO empty flag, enable TXRDY IRQ */ + write_reg16(info, TRC0, 0); + info->ie0_value |= TXRDYE; + write_reg(info, IE0, info->ie0_value); +} + +static void isr_txdmaerror(SLMP_INFO * info) +{ + /* BIT5 = BOF (buffer overflow) + * BIT4 = COF (counter overflow) + */ + unsigned char status = read_reg(info,TXDMA + DSR) & 0x30; + + /* clear IRQ (BIT0 must be 1 to prevent clearing DE bit) */ + write_reg(info, TXDMA + DSR, (unsigned char)(status | 1)); + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):%s isr_txdmaerror(), status=%02x\n", + __FILE__,__LINE__,info->device_name,status); +} + +/* handle input serial signal changes + */ +static void isr_io_pin( SLMP_INFO *info, u16 status ) +{ + struct mgsl_icount *icount; + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):isr_io_pin status=%04X\n", + __FILE__,__LINE__,status); + + if (status & (MISCSTATUS_CTS_LATCHED | MISCSTATUS_DCD_LATCHED | + MISCSTATUS_DSR_LATCHED | MISCSTATUS_RI_LATCHED) ) { + icount = &info->icount; + /* update input line counters */ + if (status & MISCSTATUS_RI_LATCHED) { + icount->rng++; + if ( status & SerialSignal_RI ) + info->input_signal_events.ri_up++; + else + info->input_signal_events.ri_down++; + } + if (status & MISCSTATUS_DSR_LATCHED) { + icount->dsr++; + if ( status & SerialSignal_DSR ) + info->input_signal_events.dsr_up++; + else + info->input_signal_events.dsr_down++; + } + if (status & MISCSTATUS_DCD_LATCHED) { + if ((info->dcd_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT) { + info->ie1_value &= ~CDCD; + write_reg(info, IE1, info->ie1_value); + } + icount->dcd++; + if (status & SerialSignal_DCD) { + info->input_signal_events.dcd_up++; + } else + info->input_signal_events.dcd_down++; +#if SYNCLINK_GENERIC_HDLC + if (info->netcount) { + if (status & SerialSignal_DCD) + netif_carrier_on(info->netdev); + else + netif_carrier_off(info->netdev); + } +#endif + } + if (status & MISCSTATUS_CTS_LATCHED) + { + if ((info->cts_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT) { + info->ie1_value &= ~CCTS; + write_reg(info, IE1, info->ie1_value); + } + icount->cts++; + if ( status & SerialSignal_CTS ) + info->input_signal_events.cts_up++; + else + info->input_signal_events.cts_down++; + } + wake_up_interruptible(&info->status_event_wait_q); + wake_up_interruptible(&info->event_wait_q); + + if ( (info->port.flags & ASYNC_CHECK_CD) && + (status & MISCSTATUS_DCD_LATCHED) ) { + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s CD now %s...", info->device_name, + (status & SerialSignal_DCD) ? "on" : "off"); + if (status & SerialSignal_DCD) + wake_up_interruptible(&info->port.open_wait); + else { + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("doing serial hangup..."); + if (info->port.tty) + tty_hangup(info->port.tty); + } + } + + if ( (info->port.flags & ASYNC_CTS_FLOW) && + (status & MISCSTATUS_CTS_LATCHED) ) { + if ( info->port.tty ) { + if (info->port.tty->hw_stopped) { + if (status & SerialSignal_CTS) { + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("CTS tx start..."); + info->port.tty->hw_stopped = 0; + tx_start(info); + info->pending_bh |= BH_TRANSMIT; + return; + } + } else { + if (!(status & SerialSignal_CTS)) { + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("CTS tx stop..."); + info->port.tty->hw_stopped = 1; + tx_stop(info); + } + } + } + } + } + + info->pending_bh |= BH_STATUS; +} + +/* Interrupt service routine entry point. + * + * Arguments: + * irq interrupt number that caused interrupt + * dev_id device ID supplied during interrupt registration + * regs interrupted processor context + */ +static irqreturn_t synclinkmp_interrupt(int dummy, void *dev_id) +{ + SLMP_INFO *info = dev_id; + unsigned char status, status0, status1=0; + unsigned char dmastatus, dmastatus0, dmastatus1=0; + unsigned char timerstatus0, timerstatus1=0; + unsigned char shift; + unsigned int i; + unsigned short tmp; + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk(KERN_DEBUG "%s(%d): synclinkmp_interrupt(%d)entry.\n", + __FILE__, __LINE__, info->irq_level); + + spin_lock(&info->lock); + + for(;;) { + + /* get status for SCA0 (ports 0-1) */ + tmp = read_reg16(info, ISR0); /* get ISR0 and ISR1 in one read */ + status0 = (unsigned char)tmp; + dmastatus0 = (unsigned char)(tmp>>8); + timerstatus0 = read_reg(info, ISR2); + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk(KERN_DEBUG "%s(%d):%s status0=%02x, dmastatus0=%02x, timerstatus0=%02x\n", + __FILE__, __LINE__, info->device_name, + status0, dmastatus0, timerstatus0); + + if (info->port_count == 4) { + /* get status for SCA1 (ports 2-3) */ + tmp = read_reg16(info->port_array[2], ISR0); + status1 = (unsigned char)tmp; + dmastatus1 = (unsigned char)(tmp>>8); + timerstatus1 = read_reg(info->port_array[2], ISR2); + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):%s status1=%02x, dmastatus1=%02x, timerstatus1=%02x\n", + __FILE__,__LINE__,info->device_name, + status1,dmastatus1,timerstatus1); + } + + if (!status0 && !dmastatus0 && !timerstatus0 && + !status1 && !dmastatus1 && !timerstatus1) + break; + + for(i=0; i < info->port_count ; i++) { + if (info->port_array[i] == NULL) + continue; + if (i < 2) { + status = status0; + dmastatus = dmastatus0; + } else { + status = status1; + dmastatus = dmastatus1; + } + + shift = i & 1 ? 4 :0; + + if (status & BIT0 << shift) + isr_rxrdy(info->port_array[i]); + if (status & BIT1 << shift) + isr_txrdy(info->port_array[i]); + if (status & BIT2 << shift) + isr_rxint(info->port_array[i]); + if (status & BIT3 << shift) + isr_txint(info->port_array[i]); + + if (dmastatus & BIT0 << shift) + isr_rxdmaerror(info->port_array[i]); + if (dmastatus & BIT1 << shift) + isr_rxdmaok(info->port_array[i]); + if (dmastatus & BIT2 << shift) + isr_txdmaerror(info->port_array[i]); + if (dmastatus & BIT3 << shift) + isr_txdmaok(info->port_array[i]); + } + + if (timerstatus0 & (BIT5 | BIT4)) + isr_timer(info->port_array[0]); + if (timerstatus0 & (BIT7 | BIT6)) + isr_timer(info->port_array[1]); + if (timerstatus1 & (BIT5 | BIT4)) + isr_timer(info->port_array[2]); + if (timerstatus1 & (BIT7 | BIT6)) + isr_timer(info->port_array[3]); + } + + for(i=0; i < info->port_count ; i++) { + SLMP_INFO * port = info->port_array[i]; + + /* Request bottom half processing if there's something + * for it to do and the bh is not already running. + * + * Note: startup adapter diags require interrupts. + * do not request bottom half processing if the + * device is not open in a normal mode. + */ + if ( port && (port->port.count || port->netcount) && + port->pending_bh && !port->bh_running && + !port->bh_requested ) { + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk("%s(%d):%s queueing bh task.\n", + __FILE__,__LINE__,port->device_name); + schedule_work(&port->task); + port->bh_requested = true; + } + } + + spin_unlock(&info->lock); + + if ( debug_level >= DEBUG_LEVEL_ISR ) + printk(KERN_DEBUG "%s(%d):synclinkmp_interrupt(%d)exit.\n", + __FILE__, __LINE__, info->irq_level); + return IRQ_HANDLED; +} + +/* Initialize and start device. + */ +static int startup(SLMP_INFO * info) +{ + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk("%s(%d):%s tx_releaseup()\n",__FILE__,__LINE__,info->device_name); + + if (info->port.flags & ASYNC_INITIALIZED) + return 0; + + if (!info->tx_buf) { + info->tx_buf = kmalloc(info->max_frame_size, GFP_KERNEL); + if (!info->tx_buf) { + printk(KERN_ERR"%s(%d):%s can't allocate transmit buffer\n", + __FILE__,__LINE__,info->device_name); + return -ENOMEM; + } + } + + info->pending_bh = 0; + + memset(&info->icount, 0, sizeof(info->icount)); + + /* program hardware for current parameters */ + reset_port(info); + + change_params(info); + + mod_timer(&info->status_timer, jiffies + msecs_to_jiffies(10)); + + if (info->port.tty) + clear_bit(TTY_IO_ERROR, &info->port.tty->flags); + + info->port.flags |= ASYNC_INITIALIZED; + + return 0; +} + +/* Called by close() and hangup() to shutdown hardware + */ +static void shutdown(SLMP_INFO * info) +{ + unsigned long flags; + + if (!(info->port.flags & ASYNC_INITIALIZED)) + return; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s synclinkmp_shutdown()\n", + __FILE__,__LINE__, info->device_name ); + + /* clear status wait queue because status changes */ + /* can't happen after shutting down the hardware */ + wake_up_interruptible(&info->status_event_wait_q); + wake_up_interruptible(&info->event_wait_q); + + del_timer(&info->tx_timer); + del_timer(&info->status_timer); + + kfree(info->tx_buf); + info->tx_buf = NULL; + + spin_lock_irqsave(&info->lock,flags); + + reset_port(info); + + if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) { + info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); + set_signals(info); + } + + spin_unlock_irqrestore(&info->lock,flags); + + if (info->port.tty) + set_bit(TTY_IO_ERROR, &info->port.tty->flags); + + info->port.flags &= ~ASYNC_INITIALIZED; +} + +static void program_hw(SLMP_INFO *info) +{ + unsigned long flags; + + spin_lock_irqsave(&info->lock,flags); + + rx_stop(info); + tx_stop(info); + + info->tx_count = info->tx_put = info->tx_get = 0; + + if (info->params.mode == MGSL_MODE_HDLC || info->netcount) + hdlc_mode(info); + else + async_mode(info); + + set_signals(info); + + info->dcd_chkcount = 0; + info->cts_chkcount = 0; + info->ri_chkcount = 0; + info->dsr_chkcount = 0; + + info->ie1_value |= (CDCD|CCTS); + write_reg(info, IE1, info->ie1_value); + + get_signals(info); + + if (info->netcount || (info->port.tty && info->port.tty->termios->c_cflag & CREAD) ) + rx_start(info); + + spin_unlock_irqrestore(&info->lock,flags); +} + +/* Reconfigure adapter based on new parameters + */ +static void change_params(SLMP_INFO *info) +{ + unsigned cflag; + int bits_per_char; + + if (!info->port.tty || !info->port.tty->termios) + return; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s change_params()\n", + __FILE__,__LINE__, info->device_name ); + + cflag = info->port.tty->termios->c_cflag; + + /* if B0 rate (hangup) specified then negate DTR and RTS */ + /* otherwise assert DTR and RTS */ + if (cflag & CBAUD) + info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; + else + info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); + + /* byte size and parity */ + + switch (cflag & CSIZE) { + case CS5: info->params.data_bits = 5; break; + case CS6: info->params.data_bits = 6; break; + case CS7: info->params.data_bits = 7; break; + case CS8: info->params.data_bits = 8; break; + /* Never happens, but GCC is too dumb to figure it out */ + default: info->params.data_bits = 7; break; + } + + if (cflag & CSTOPB) + info->params.stop_bits = 2; + else + info->params.stop_bits = 1; + + info->params.parity = ASYNC_PARITY_NONE; + if (cflag & PARENB) { + if (cflag & PARODD) + info->params.parity = ASYNC_PARITY_ODD; + else + info->params.parity = ASYNC_PARITY_EVEN; +#ifdef CMSPAR + if (cflag & CMSPAR) + info->params.parity = ASYNC_PARITY_SPACE; +#endif + } + + /* calculate number of jiffies to transmit a full + * FIFO (32 bytes) at specified data rate + */ + bits_per_char = info->params.data_bits + + info->params.stop_bits + 1; + + /* if port data rate is set to 460800 or less then + * allow tty settings to override, otherwise keep the + * current data rate. + */ + if (info->params.data_rate <= 460800) { + info->params.data_rate = tty_get_baud_rate(info->port.tty); + } + + if ( info->params.data_rate ) { + info->timeout = (32*HZ*bits_per_char) / + info->params.data_rate; + } + info->timeout += HZ/50; /* Add .02 seconds of slop */ + + if (cflag & CRTSCTS) + info->port.flags |= ASYNC_CTS_FLOW; + else + info->port.flags &= ~ASYNC_CTS_FLOW; + + if (cflag & CLOCAL) + info->port.flags &= ~ASYNC_CHECK_CD; + else + info->port.flags |= ASYNC_CHECK_CD; + + /* process tty input control flags */ + + info->read_status_mask2 = OVRN; + if (I_INPCK(info->port.tty)) + info->read_status_mask2 |= PE | FRME; + if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) + info->read_status_mask1 |= BRKD; + if (I_IGNPAR(info->port.tty)) + info->ignore_status_mask2 |= PE | FRME; + if (I_IGNBRK(info->port.tty)) { + info->ignore_status_mask1 |= BRKD; + /* If ignoring parity and break indicators, ignore + * overruns too. (For real raw support). + */ + if (I_IGNPAR(info->port.tty)) + info->ignore_status_mask2 |= OVRN; + } + + program_hw(info); +} + +static int get_stats(SLMP_INFO * info, struct mgsl_icount __user *user_icount) +{ + int err; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s get_params()\n", + __FILE__,__LINE__, info->device_name); + + if (!user_icount) { + memset(&info->icount, 0, sizeof(info->icount)); + } else { + mutex_lock(&info->port.mutex); + COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount)); + mutex_unlock(&info->port.mutex); + if (err) + return -EFAULT; + } + + return 0; +} + +static int get_params(SLMP_INFO * info, MGSL_PARAMS __user *user_params) +{ + int err; + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s get_params()\n", + __FILE__,__LINE__, info->device_name); + + mutex_lock(&info->port.mutex); + COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS)); + mutex_unlock(&info->port.mutex); + if (err) { + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):%s get_params() user buffer copy failed\n", + __FILE__,__LINE__,info->device_name); + return -EFAULT; + } + + return 0; +} + +static int set_params(SLMP_INFO * info, MGSL_PARAMS __user *new_params) +{ + unsigned long flags; + MGSL_PARAMS tmp_params; + int err; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s set_params\n", + __FILE__,__LINE__,info->device_name ); + COPY_FROM_USER(err,&tmp_params, new_params, sizeof(MGSL_PARAMS)); + if (err) { + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):%s set_params() user buffer copy failed\n", + __FILE__,__LINE__,info->device_name); + return -EFAULT; + } + + mutex_lock(&info->port.mutex); + spin_lock_irqsave(&info->lock,flags); + memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS)); + spin_unlock_irqrestore(&info->lock,flags); + + change_params(info); + mutex_unlock(&info->port.mutex); + + return 0; +} + +static int get_txidle(SLMP_INFO * info, int __user *idle_mode) +{ + int err; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s get_txidle()=%d\n", + __FILE__,__LINE__, info->device_name, info->idle_mode); + + COPY_TO_USER(err,idle_mode, &info->idle_mode, sizeof(int)); + if (err) { + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):%s get_txidle() user buffer copy failed\n", + __FILE__,__LINE__,info->device_name); + return -EFAULT; + } + + return 0; +} + +static int set_txidle(SLMP_INFO * info, int idle_mode) +{ + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s set_txidle(%d)\n", + __FILE__,__LINE__,info->device_name, idle_mode ); + + spin_lock_irqsave(&info->lock,flags); + info->idle_mode = idle_mode; + tx_set_idle( info ); + spin_unlock_irqrestore(&info->lock,flags); + return 0; +} + +static int tx_enable(SLMP_INFO * info, int enable) +{ + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s tx_enable(%d)\n", + __FILE__,__LINE__,info->device_name, enable); + + spin_lock_irqsave(&info->lock,flags); + if ( enable ) { + if ( !info->tx_enabled ) { + tx_start(info); + } + } else { + if ( info->tx_enabled ) + tx_stop(info); + } + spin_unlock_irqrestore(&info->lock,flags); + return 0; +} + +/* abort send HDLC frame + */ +static int tx_abort(SLMP_INFO * info) +{ + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s tx_abort()\n", + __FILE__,__LINE__,info->device_name); + + spin_lock_irqsave(&info->lock,flags); + if ( info->tx_active && info->params.mode == MGSL_MODE_HDLC ) { + info->ie1_value &= ~UDRN; + info->ie1_value |= IDLE; + write_reg(info, IE1, info->ie1_value); /* disable tx status interrupts */ + write_reg(info, SR1, (unsigned char)(IDLE + UDRN)); /* clear pending */ + + write_reg(info, TXDMA + DSR, 0); /* disable DMA channel */ + write_reg(info, TXDMA + DCMD, SWABORT); /* reset/init DMA channel */ + + write_reg(info, CMD, TXABORT); + } + spin_unlock_irqrestore(&info->lock,flags); + return 0; +} + +static int rx_enable(SLMP_INFO * info, int enable) +{ + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s rx_enable(%d)\n", + __FILE__,__LINE__,info->device_name,enable); + + spin_lock_irqsave(&info->lock,flags); + if ( enable ) { + if ( !info->rx_enabled ) + rx_start(info); + } else { + if ( info->rx_enabled ) + rx_stop(info); + } + spin_unlock_irqrestore(&info->lock,flags); + return 0; +} + +/* wait for specified event to occur + */ +static int wait_mgsl_event(SLMP_INFO * info, int __user *mask_ptr) +{ + unsigned long flags; + int s; + int rc=0; + struct mgsl_icount cprev, cnow; + int events; + int mask; + struct _input_signal_events oldsigs, newsigs; + DECLARE_WAITQUEUE(wait, current); + + COPY_FROM_USER(rc,&mask, mask_ptr, sizeof(int)); + if (rc) { + return -EFAULT; + } + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s wait_mgsl_event(%d)\n", + __FILE__,__LINE__,info->device_name,mask); + + spin_lock_irqsave(&info->lock,flags); + + /* return immediately if state matches requested events */ + get_signals(info); + s = info->serial_signals; + + events = mask & + ( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) + + ((s & SerialSignal_DCD) ? MgslEvent_DcdActive:MgslEvent_DcdInactive) + + ((s & SerialSignal_CTS) ? MgslEvent_CtsActive:MgslEvent_CtsInactive) + + ((s & SerialSignal_RI) ? MgslEvent_RiActive :MgslEvent_RiInactive) ); + if (events) { + spin_unlock_irqrestore(&info->lock,flags); + goto exit; + } + + /* save current irq counts */ + cprev = info->icount; + oldsigs = info->input_signal_events; + + /* enable hunt and idle irqs if needed */ + if (mask & (MgslEvent_ExitHuntMode+MgslEvent_IdleReceived)) { + unsigned char oldval = info->ie1_value; + unsigned char newval = oldval + + (mask & MgslEvent_ExitHuntMode ? FLGD:0) + + (mask & MgslEvent_IdleReceived ? IDLD:0); + if ( oldval != newval ) { + info->ie1_value = newval; + write_reg(info, IE1, info->ie1_value); + } + } + + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&info->event_wait_q, &wait); + + spin_unlock_irqrestore(&info->lock,flags); + + for(;;) { + schedule(); + if (signal_pending(current)) { + rc = -ERESTARTSYS; + break; + } + + /* get current irq counts */ + spin_lock_irqsave(&info->lock,flags); + cnow = info->icount; + newsigs = info->input_signal_events; + set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irqrestore(&info->lock,flags); + + /* if no change, wait aborted for some reason */ + if (newsigs.dsr_up == oldsigs.dsr_up && + newsigs.dsr_down == oldsigs.dsr_down && + newsigs.dcd_up == oldsigs.dcd_up && + newsigs.dcd_down == oldsigs.dcd_down && + newsigs.cts_up == oldsigs.cts_up && + newsigs.cts_down == oldsigs.cts_down && + newsigs.ri_up == oldsigs.ri_up && + newsigs.ri_down == oldsigs.ri_down && + cnow.exithunt == cprev.exithunt && + cnow.rxidle == cprev.rxidle) { + rc = -EIO; + break; + } + + events = mask & + ( (newsigs.dsr_up != oldsigs.dsr_up ? MgslEvent_DsrActive:0) + + (newsigs.dsr_down != oldsigs.dsr_down ? MgslEvent_DsrInactive:0) + + (newsigs.dcd_up != oldsigs.dcd_up ? MgslEvent_DcdActive:0) + + (newsigs.dcd_down != oldsigs.dcd_down ? MgslEvent_DcdInactive:0) + + (newsigs.cts_up != oldsigs.cts_up ? MgslEvent_CtsActive:0) + + (newsigs.cts_down != oldsigs.cts_down ? MgslEvent_CtsInactive:0) + + (newsigs.ri_up != oldsigs.ri_up ? MgslEvent_RiActive:0) + + (newsigs.ri_down != oldsigs.ri_down ? MgslEvent_RiInactive:0) + + (cnow.exithunt != cprev.exithunt ? MgslEvent_ExitHuntMode:0) + + (cnow.rxidle != cprev.rxidle ? MgslEvent_IdleReceived:0) ); + if (events) + break; + + cprev = cnow; + oldsigs = newsigs; + } + + remove_wait_queue(&info->event_wait_q, &wait); + set_current_state(TASK_RUNNING); + + + if (mask & (MgslEvent_ExitHuntMode + MgslEvent_IdleReceived)) { + spin_lock_irqsave(&info->lock,flags); + if (!waitqueue_active(&info->event_wait_q)) { + /* disable enable exit hunt mode/idle rcvd IRQs */ + info->ie1_value &= ~(FLGD|IDLD); + write_reg(info, IE1, info->ie1_value); + } + spin_unlock_irqrestore(&info->lock,flags); + } +exit: + if ( rc == 0 ) + PUT_USER(rc, events, mask_ptr); + + return rc; +} + +static int modem_input_wait(SLMP_INFO *info,int arg) +{ + unsigned long flags; + int rc; + struct mgsl_icount cprev, cnow; + DECLARE_WAITQUEUE(wait, current); + + /* save current irq counts */ + spin_lock_irqsave(&info->lock,flags); + cprev = info->icount; + add_wait_queue(&info->status_event_wait_q, &wait); + set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irqrestore(&info->lock,flags); + + for(;;) { + schedule(); + if (signal_pending(current)) { + rc = -ERESTARTSYS; + break; + } + + /* get new irq counts */ + spin_lock_irqsave(&info->lock,flags); + cnow = info->icount; + set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irqrestore(&info->lock,flags); + + /* if no change, wait aborted for some reason */ + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && + cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { + rc = -EIO; + break; + } + + /* check for change in caller specified modem input */ + if ((arg & TIOCM_RNG && cnow.rng != cprev.rng) || + (arg & TIOCM_DSR && cnow.dsr != cprev.dsr) || + (arg & TIOCM_CD && cnow.dcd != cprev.dcd) || + (arg & TIOCM_CTS && cnow.cts != cprev.cts)) { + rc = 0; + break; + } + + cprev = cnow; + } + remove_wait_queue(&info->status_event_wait_q, &wait); + set_current_state(TASK_RUNNING); + return rc; +} + +/* return the state of the serial control and status signals + */ +static int tiocmget(struct tty_struct *tty) +{ + SLMP_INFO *info = tty->driver_data; + unsigned int result; + unsigned long flags; + + spin_lock_irqsave(&info->lock,flags); + get_signals(info); + spin_unlock_irqrestore(&info->lock,flags); + + result = ((info->serial_signals & SerialSignal_RTS) ? TIOCM_RTS:0) + + ((info->serial_signals & SerialSignal_DTR) ? TIOCM_DTR:0) + + ((info->serial_signals & SerialSignal_DCD) ? TIOCM_CAR:0) + + ((info->serial_signals & SerialSignal_RI) ? TIOCM_RNG:0) + + ((info->serial_signals & SerialSignal_DSR) ? TIOCM_DSR:0) + + ((info->serial_signals & SerialSignal_CTS) ? TIOCM_CTS:0); + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s tiocmget() value=%08X\n", + __FILE__,__LINE__, info->device_name, result ); + return result; +} + +/* set modem control signals (DTR/RTS) + */ +static int tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + SLMP_INFO *info = tty->driver_data; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s tiocmset(%x,%x)\n", + __FILE__,__LINE__,info->device_name, set, clear); + + if (set & TIOCM_RTS) + info->serial_signals |= SerialSignal_RTS; + if (set & TIOCM_DTR) + info->serial_signals |= SerialSignal_DTR; + if (clear & TIOCM_RTS) + info->serial_signals &= ~SerialSignal_RTS; + if (clear & TIOCM_DTR) + info->serial_signals &= ~SerialSignal_DTR; + + spin_lock_irqsave(&info->lock,flags); + set_signals(info); + spin_unlock_irqrestore(&info->lock,flags); + + return 0; +} + +static int carrier_raised(struct tty_port *port) +{ + SLMP_INFO *info = container_of(port, SLMP_INFO, port); + unsigned long flags; + + spin_lock_irqsave(&info->lock,flags); + get_signals(info); + spin_unlock_irqrestore(&info->lock,flags); + + return (info->serial_signals & SerialSignal_DCD) ? 1 : 0; +} + +static void dtr_rts(struct tty_port *port, int on) +{ + SLMP_INFO *info = container_of(port, SLMP_INFO, port); + unsigned long flags; + + spin_lock_irqsave(&info->lock,flags); + if (on) + info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; + else + info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); + set_signals(info); + spin_unlock_irqrestore(&info->lock,flags); +} + +/* Block the current process until the specified port is ready to open. + */ +static int block_til_ready(struct tty_struct *tty, struct file *filp, + SLMP_INFO *info) +{ + DECLARE_WAITQUEUE(wait, current); + int retval; + bool do_clocal = false; + bool extra_count = false; + unsigned long flags; + int cd; + struct tty_port *port = &info->port; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s block_til_ready()\n", + __FILE__,__LINE__, tty->driver->name ); + + if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ + /* nonblock mode is set or port is not enabled */ + /* just verify that callout device is not active */ + port->flags |= ASYNC_NORMAL_ACTIVE; + return 0; + } + + if (tty->termios->c_cflag & CLOCAL) + do_clocal = true; + + /* Wait for carrier detect and the line to become + * free (i.e., not in use by the callout). While we are in + * this loop, port->count is dropped by one, so that + * close() knows when to free things. We restore it upon + * exit, either normal or abnormal. + */ + + retval = 0; + add_wait_queue(&port->open_wait, &wait); + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s block_til_ready() before block, count=%d\n", + __FILE__,__LINE__, tty->driver->name, port->count ); + + spin_lock_irqsave(&info->lock, flags); + if (!tty_hung_up_p(filp)) { + extra_count = true; + port->count--; + } + spin_unlock_irqrestore(&info->lock, flags); + port->blocked_open++; + + while (1) { + if (tty->termios->c_cflag & CBAUD) + tty_port_raise_dtr_rts(port); + + set_current_state(TASK_INTERRUPTIBLE); + + if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){ + retval = (port->flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS; + break; + } + + cd = tty_port_carrier_raised(port); + + if (!(port->flags & ASYNC_CLOSING) && (do_clocal || cd)) + break; + + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s block_til_ready() count=%d\n", + __FILE__,__LINE__, tty->driver->name, port->count ); + + tty_unlock(); + schedule(); + tty_lock(); + } + + set_current_state(TASK_RUNNING); + remove_wait_queue(&port->open_wait, &wait); + + if (extra_count) + port->count++; + port->blocked_open--; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):%s block_til_ready() after, count=%d\n", + __FILE__,__LINE__, tty->driver->name, port->count ); + + if (!retval) + port->flags |= ASYNC_NORMAL_ACTIVE; + + return retval; +} + +static int alloc_dma_bufs(SLMP_INFO *info) +{ + unsigned short BuffersPerFrame; + unsigned short BufferCount; + + // Force allocation to start at 64K boundary for each port. + // This is necessary because *all* buffer descriptors for a port + // *must* be in the same 64K block. All descriptors on a port + // share a common 'base' address (upper 8 bits of 24 bits) programmed + // into the CBP register. + info->port_array[0]->last_mem_alloc = (SCA_MEM_SIZE/4) * info->port_num; + + /* Calculate the number of DMA buffers necessary to hold the */ + /* largest allowable frame size. Note: If the max frame size is */ + /* not an even multiple of the DMA buffer size then we need to */ + /* round the buffer count per frame up one. */ + + BuffersPerFrame = (unsigned short)(info->max_frame_size/SCABUFSIZE); + if ( info->max_frame_size % SCABUFSIZE ) + BuffersPerFrame++; + + /* calculate total number of data buffers (SCABUFSIZE) possible + * in one ports memory (SCA_MEM_SIZE/4) after allocating memory + * for the descriptor list (BUFFERLISTSIZE). + */ + BufferCount = (SCA_MEM_SIZE/4 - BUFFERLISTSIZE)/SCABUFSIZE; + + /* limit number of buffers to maximum amount of descriptors */ + if (BufferCount > BUFFERLISTSIZE/sizeof(SCADESC)) + BufferCount = BUFFERLISTSIZE/sizeof(SCADESC); + + /* use enough buffers to transmit one max size frame */ + info->tx_buf_count = BuffersPerFrame + 1; + + /* never use more than half the available buffers for transmit */ + if (info->tx_buf_count > (BufferCount/2)) + info->tx_buf_count = BufferCount/2; + + if (info->tx_buf_count > SCAMAXDESC) + info->tx_buf_count = SCAMAXDESC; + + /* use remaining buffers for receive */ + info->rx_buf_count = BufferCount - info->tx_buf_count; + + if (info->rx_buf_count > SCAMAXDESC) + info->rx_buf_count = SCAMAXDESC; + + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk("%s(%d):%s Allocating %d TX and %d RX DMA buffers.\n", + __FILE__,__LINE__, info->device_name, + info->tx_buf_count,info->rx_buf_count); + + if ( alloc_buf_list( info ) < 0 || + alloc_frame_bufs(info, + info->rx_buf_list, + info->rx_buf_list_ex, + info->rx_buf_count) < 0 || + alloc_frame_bufs(info, + info->tx_buf_list, + info->tx_buf_list_ex, + info->tx_buf_count) < 0 || + alloc_tmp_rx_buf(info) < 0 ) { + printk("%s(%d):%s Can't allocate DMA buffer memory\n", + __FILE__,__LINE__, info->device_name); + return -ENOMEM; + } + + rx_reset_buffers( info ); + + return 0; +} + +/* Allocate DMA buffers for the transmit and receive descriptor lists. + */ +static int alloc_buf_list(SLMP_INFO *info) +{ + unsigned int i; + + /* build list in adapter shared memory */ + info->buffer_list = info->memory_base + info->port_array[0]->last_mem_alloc; + info->buffer_list_phys = info->port_array[0]->last_mem_alloc; + info->port_array[0]->last_mem_alloc += BUFFERLISTSIZE; + + memset(info->buffer_list, 0, BUFFERLISTSIZE); + + /* Save virtual address pointers to the receive and */ + /* transmit buffer lists. (Receive 1st). These pointers will */ + /* be used by the processor to access the lists. */ + info->rx_buf_list = (SCADESC *)info->buffer_list; + + info->tx_buf_list = (SCADESC *)info->buffer_list; + info->tx_buf_list += info->rx_buf_count; + + /* Build links for circular buffer entry lists (tx and rx) + * + * Note: links are physical addresses read by the SCA device + * to determine the next buffer entry to use. + */ + + for ( i = 0; i < info->rx_buf_count; i++ ) { + /* calculate and store physical address of this buffer entry */ + info->rx_buf_list_ex[i].phys_entry = + info->buffer_list_phys + (i * sizeof(SCABUFSIZE)); + + /* calculate and store physical address of */ + /* next entry in cirular list of entries */ + info->rx_buf_list[i].next = info->buffer_list_phys; + if ( i < info->rx_buf_count - 1 ) + info->rx_buf_list[i].next += (i + 1) * sizeof(SCADESC); + + info->rx_buf_list[i].length = SCABUFSIZE; + } + + for ( i = 0; i < info->tx_buf_count; i++ ) { + /* calculate and store physical address of this buffer entry */ + info->tx_buf_list_ex[i].phys_entry = info->buffer_list_phys + + ((info->rx_buf_count + i) * sizeof(SCADESC)); + + /* calculate and store physical address of */ + /* next entry in cirular list of entries */ + + info->tx_buf_list[i].next = info->buffer_list_phys + + info->rx_buf_count * sizeof(SCADESC); + + if ( i < info->tx_buf_count - 1 ) + info->tx_buf_list[i].next += (i + 1) * sizeof(SCADESC); + } + + return 0; +} + +/* Allocate the frame DMA buffers used by the specified buffer list. + */ +static int alloc_frame_bufs(SLMP_INFO *info, SCADESC *buf_list,SCADESC_EX *buf_list_ex,int count) +{ + int i; + unsigned long phys_addr; + + for ( i = 0; i < count; i++ ) { + buf_list_ex[i].virt_addr = info->memory_base + info->port_array[0]->last_mem_alloc; + phys_addr = info->port_array[0]->last_mem_alloc; + info->port_array[0]->last_mem_alloc += SCABUFSIZE; + + buf_list[i].buf_ptr = (unsigned short)phys_addr; + buf_list[i].buf_base = (unsigned char)(phys_addr >> 16); + } + + return 0; +} + +static void free_dma_bufs(SLMP_INFO *info) +{ + info->buffer_list = NULL; + info->rx_buf_list = NULL; + info->tx_buf_list = NULL; +} + +/* allocate buffer large enough to hold max_frame_size. + * This buffer is used to pass an assembled frame to the line discipline. + */ +static int alloc_tmp_rx_buf(SLMP_INFO *info) +{ + info->tmp_rx_buf = kmalloc(info->max_frame_size, GFP_KERNEL); + if (info->tmp_rx_buf == NULL) + return -ENOMEM; + return 0; +} + +static void free_tmp_rx_buf(SLMP_INFO *info) +{ + kfree(info->tmp_rx_buf); + info->tmp_rx_buf = NULL; +} + +static int claim_resources(SLMP_INFO *info) +{ + if (request_mem_region(info->phys_memory_base,SCA_MEM_SIZE,"synclinkmp") == NULL) { + printk( "%s(%d):%s mem addr conflict, Addr=%08X\n", + __FILE__,__LINE__,info->device_name, info->phys_memory_base); + info->init_error = DiagStatus_AddressConflict; + goto errout; + } + else + info->shared_mem_requested = true; + + if (request_mem_region(info->phys_lcr_base + info->lcr_offset,128,"synclinkmp") == NULL) { + printk( "%s(%d):%s lcr mem addr conflict, Addr=%08X\n", + __FILE__,__LINE__,info->device_name, info->phys_lcr_base); + info->init_error = DiagStatus_AddressConflict; + goto errout; + } + else + info->lcr_mem_requested = true; + + if (request_mem_region(info->phys_sca_base + info->sca_offset,SCA_BASE_SIZE,"synclinkmp") == NULL) { + printk( "%s(%d):%s sca mem addr conflict, Addr=%08X\n", + __FILE__,__LINE__,info->device_name, info->phys_sca_base); + info->init_error = DiagStatus_AddressConflict; + goto errout; + } + else + info->sca_base_requested = true; + + if (request_mem_region(info->phys_statctrl_base + info->statctrl_offset,SCA_REG_SIZE,"synclinkmp") == NULL) { + printk( "%s(%d):%s stat/ctrl mem addr conflict, Addr=%08X\n", + __FILE__,__LINE__,info->device_name, info->phys_statctrl_base); + info->init_error = DiagStatus_AddressConflict; + goto errout; + } + else + info->sca_statctrl_requested = true; + + info->memory_base = ioremap_nocache(info->phys_memory_base, + SCA_MEM_SIZE); + if (!info->memory_base) { + printk( "%s(%d):%s Cant map shared memory, MemAddr=%08X\n", + __FILE__,__LINE__,info->device_name, info->phys_memory_base ); + info->init_error = DiagStatus_CantAssignPciResources; + goto errout; + } + + info->lcr_base = ioremap_nocache(info->phys_lcr_base, PAGE_SIZE); + if (!info->lcr_base) { + printk( "%s(%d):%s Cant map LCR memory, MemAddr=%08X\n", + __FILE__,__LINE__,info->device_name, info->phys_lcr_base ); + info->init_error = DiagStatus_CantAssignPciResources; + goto errout; + } + info->lcr_base += info->lcr_offset; + + info->sca_base = ioremap_nocache(info->phys_sca_base, PAGE_SIZE); + if (!info->sca_base) { + printk( "%s(%d):%s Cant map SCA memory, MemAddr=%08X\n", + __FILE__,__LINE__,info->device_name, info->phys_sca_base ); + info->init_error = DiagStatus_CantAssignPciResources; + goto errout; + } + info->sca_base += info->sca_offset; + + info->statctrl_base = ioremap_nocache(info->phys_statctrl_base, + PAGE_SIZE); + if (!info->statctrl_base) { + printk( "%s(%d):%s Cant map SCA Status/Control memory, MemAddr=%08X\n", + __FILE__,__LINE__,info->device_name, info->phys_statctrl_base ); + info->init_error = DiagStatus_CantAssignPciResources; + goto errout; + } + info->statctrl_base += info->statctrl_offset; + + if ( !memory_test(info) ) { + printk( "%s(%d):Shared Memory Test failed for device %s MemAddr=%08X\n", + __FILE__,__LINE__,info->device_name, info->phys_memory_base ); + info->init_error = DiagStatus_MemoryError; + goto errout; + } + + return 0; + +errout: + release_resources( info ); + return -ENODEV; +} + +static void release_resources(SLMP_INFO *info) +{ + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):%s release_resources() entry\n", + __FILE__,__LINE__,info->device_name ); + + if ( info->irq_requested ) { + free_irq(info->irq_level, info); + info->irq_requested = false; + } + + if ( info->shared_mem_requested ) { + release_mem_region(info->phys_memory_base,SCA_MEM_SIZE); + info->shared_mem_requested = false; + } + if ( info->lcr_mem_requested ) { + release_mem_region(info->phys_lcr_base + info->lcr_offset,128); + info->lcr_mem_requested = false; + } + if ( info->sca_base_requested ) { + release_mem_region(info->phys_sca_base + info->sca_offset,SCA_BASE_SIZE); + info->sca_base_requested = false; + } + if ( info->sca_statctrl_requested ) { + release_mem_region(info->phys_statctrl_base + info->statctrl_offset,SCA_REG_SIZE); + info->sca_statctrl_requested = false; + } + + if (info->memory_base){ + iounmap(info->memory_base); + info->memory_base = NULL; + } + + if (info->sca_base) { + iounmap(info->sca_base - info->sca_offset); + info->sca_base=NULL; + } + + if (info->statctrl_base) { + iounmap(info->statctrl_base - info->statctrl_offset); + info->statctrl_base=NULL; + } + + if (info->lcr_base){ + iounmap(info->lcr_base - info->lcr_offset); + info->lcr_base = NULL; + } + + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):%s release_resources() exit\n", + __FILE__,__LINE__,info->device_name ); +} + +/* Add the specified device instance data structure to the + * global linked list of devices and increment the device count. + */ +static void add_device(SLMP_INFO *info) +{ + info->next_device = NULL; + info->line = synclinkmp_device_count; + sprintf(info->device_name,"ttySLM%dp%d",info->adapter_num,info->port_num); + + if (info->line < MAX_DEVICES) { + if (maxframe[info->line]) + info->max_frame_size = maxframe[info->line]; + } + + synclinkmp_device_count++; + + if ( !synclinkmp_device_list ) + synclinkmp_device_list = info; + else { + SLMP_INFO *current_dev = synclinkmp_device_list; + while( current_dev->next_device ) + current_dev = current_dev->next_device; + current_dev->next_device = info; + } + + if ( info->max_frame_size < 4096 ) + info->max_frame_size = 4096; + else if ( info->max_frame_size > 65535 ) + info->max_frame_size = 65535; + + printk( "SyncLink MultiPort %s: " + "Mem=(%08x %08X %08x %08X) IRQ=%d MaxFrameSize=%u\n", + info->device_name, + info->phys_sca_base, + info->phys_memory_base, + info->phys_statctrl_base, + info->phys_lcr_base, + info->irq_level, + info->max_frame_size ); + +#if SYNCLINK_GENERIC_HDLC + hdlcdev_init(info); +#endif +} + +static const struct tty_port_operations port_ops = { + .carrier_raised = carrier_raised, + .dtr_rts = dtr_rts, +}; + +/* Allocate and initialize a device instance structure + * + * Return Value: pointer to SLMP_INFO if success, otherwise NULL + */ +static SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev) +{ + SLMP_INFO *info; + + info = kzalloc(sizeof(SLMP_INFO), + GFP_KERNEL); + + if (!info) { + printk("%s(%d) Error can't allocate device instance data for adapter %d, port %d\n", + __FILE__,__LINE__, adapter_num, port_num); + } else { + tty_port_init(&info->port); + info->port.ops = &port_ops; + info->magic = MGSL_MAGIC; + INIT_WORK(&info->task, bh_handler); + info->max_frame_size = 4096; + info->port.close_delay = 5*HZ/10; + info->port.closing_wait = 30*HZ; + init_waitqueue_head(&info->status_event_wait_q); + init_waitqueue_head(&info->event_wait_q); + spin_lock_init(&info->netlock); + memcpy(&info->params,&default_params,sizeof(MGSL_PARAMS)); + info->idle_mode = HDLC_TXIDLE_FLAGS; + info->adapter_num = adapter_num; + info->port_num = port_num; + + /* Copy configuration info to device instance data */ + info->irq_level = pdev->irq; + info->phys_lcr_base = pci_resource_start(pdev,0); + info->phys_sca_base = pci_resource_start(pdev,2); + info->phys_memory_base = pci_resource_start(pdev,3); + info->phys_statctrl_base = pci_resource_start(pdev,4); + + /* Because veremap only works on page boundaries we must map + * a larger area than is actually implemented for the LCR + * memory range. We map a full page starting at the page boundary. + */ + info->lcr_offset = info->phys_lcr_base & (PAGE_SIZE-1); + info->phys_lcr_base &= ~(PAGE_SIZE-1); + + info->sca_offset = info->phys_sca_base & (PAGE_SIZE-1); + info->phys_sca_base &= ~(PAGE_SIZE-1); + + info->statctrl_offset = info->phys_statctrl_base & (PAGE_SIZE-1); + info->phys_statctrl_base &= ~(PAGE_SIZE-1); + + info->bus_type = MGSL_BUS_TYPE_PCI; + info->irq_flags = IRQF_SHARED; + + setup_timer(&info->tx_timer, tx_timeout, (unsigned long)info); + setup_timer(&info->status_timer, status_timeout, + (unsigned long)info); + + /* Store the PCI9050 misc control register value because a flaw + * in the PCI9050 prevents LCR registers from being read if + * BIOS assigns an LCR base address with bit 7 set. + * + * Only the misc control register is accessed for which only + * write access is needed, so set an initial value and change + * bits to the device instance data as we write the value + * to the actual misc control register. + */ + info->misc_ctrl_value = 0x087e4546; + + /* initial port state is unknown - if startup errors + * occur, init_error will be set to indicate the + * problem. Once the port is fully initialized, + * this value will be set to 0 to indicate the + * port is available. + */ + info->init_error = -1; + } + + return info; +} + +static void device_init(int adapter_num, struct pci_dev *pdev) +{ + SLMP_INFO *port_array[SCA_MAX_PORTS]; + int port; + + /* allocate device instances for up to SCA_MAX_PORTS devices */ + for ( port = 0; port < SCA_MAX_PORTS; ++port ) { + port_array[port] = alloc_dev(adapter_num,port,pdev); + if( port_array[port] == NULL ) { + for ( --port; port >= 0; --port ) + kfree(port_array[port]); + return; + } + } + + /* give copy of port_array to all ports and add to device list */ + for ( port = 0; port < SCA_MAX_PORTS; ++port ) { + memcpy(port_array[port]->port_array,port_array,sizeof(port_array)); + add_device( port_array[port] ); + spin_lock_init(&port_array[port]->lock); + } + + /* Allocate and claim adapter resources */ + if ( !claim_resources(port_array[0]) ) { + + alloc_dma_bufs(port_array[0]); + + /* copy resource information from first port to others */ + for ( port = 1; port < SCA_MAX_PORTS; ++port ) { + port_array[port]->lock = port_array[0]->lock; + port_array[port]->irq_level = port_array[0]->irq_level; + port_array[port]->memory_base = port_array[0]->memory_base; + port_array[port]->sca_base = port_array[0]->sca_base; + port_array[port]->statctrl_base = port_array[0]->statctrl_base; + port_array[port]->lcr_base = port_array[0]->lcr_base; + alloc_dma_bufs(port_array[port]); + } + + if ( request_irq(port_array[0]->irq_level, + synclinkmp_interrupt, + port_array[0]->irq_flags, + port_array[0]->device_name, + port_array[0]) < 0 ) { + printk( "%s(%d):%s Cant request interrupt, IRQ=%d\n", + __FILE__,__LINE__, + port_array[0]->device_name, + port_array[0]->irq_level ); + } + else { + port_array[0]->irq_requested = true; + adapter_test(port_array[0]); + } + } +} + +static const struct tty_operations ops = { + .open = open, + .close = close, + .write = write, + .put_char = put_char, + .flush_chars = flush_chars, + .write_room = write_room, + .chars_in_buffer = chars_in_buffer, + .flush_buffer = flush_buffer, + .ioctl = ioctl, + .throttle = throttle, + .unthrottle = unthrottle, + .send_xchar = send_xchar, + .break_ctl = set_break, + .wait_until_sent = wait_until_sent, + .set_termios = set_termios, + .stop = tx_hold, + .start = tx_release, + .hangup = hangup, + .tiocmget = tiocmget, + .tiocmset = tiocmset, + .get_icount = get_icount, + .proc_fops = &synclinkmp_proc_fops, +}; + + +static void synclinkmp_cleanup(void) +{ + int rc; + SLMP_INFO *info; + SLMP_INFO *tmp; + + printk("Unloading %s %s\n", driver_name, driver_version); + + if (serial_driver) { + if ((rc = tty_unregister_driver(serial_driver))) + printk("%s(%d) failed to unregister tty driver err=%d\n", + __FILE__,__LINE__,rc); + put_tty_driver(serial_driver); + } + + /* reset devices */ + info = synclinkmp_device_list; + while(info) { + reset_port(info); + info = info->next_device; + } + + /* release devices */ + info = synclinkmp_device_list; + while(info) { +#if SYNCLINK_GENERIC_HDLC + hdlcdev_exit(info); +#endif + free_dma_bufs(info); + free_tmp_rx_buf(info); + if ( info->port_num == 0 ) { + if (info->sca_base) + write_reg(info, LPR, 1); /* set low power mode */ + release_resources(info); + } + tmp = info; + info = info->next_device; + kfree(tmp); + } + + pci_unregister_driver(&synclinkmp_pci_driver); +} + +/* Driver initialization entry point. + */ + +static int __init synclinkmp_init(void) +{ + int rc; + + if (break_on_load) { + synclinkmp_get_text_ptr(); + BREAKPOINT(); + } + + printk("%s %s\n", driver_name, driver_version); + + if ((rc = pci_register_driver(&synclinkmp_pci_driver)) < 0) { + printk("%s:failed to register PCI driver, error=%d\n",__FILE__,rc); + return rc; + } + + serial_driver = alloc_tty_driver(128); + if (!serial_driver) { + rc = -ENOMEM; + goto error; + } + + /* Initialize the tty_driver structure */ + + serial_driver->owner = THIS_MODULE; + serial_driver->driver_name = "synclinkmp"; + serial_driver->name = "ttySLM"; + serial_driver->major = ttymajor; + serial_driver->minor_start = 64; + serial_driver->type = TTY_DRIVER_TYPE_SERIAL; + serial_driver->subtype = SERIAL_TYPE_NORMAL; + serial_driver->init_termios = tty_std_termios; + serial_driver->init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + serial_driver->init_termios.c_ispeed = 9600; + serial_driver->init_termios.c_ospeed = 9600; + serial_driver->flags = TTY_DRIVER_REAL_RAW; + tty_set_operations(serial_driver, &ops); + if ((rc = tty_register_driver(serial_driver)) < 0) { + printk("%s(%d):Couldn't register serial driver\n", + __FILE__,__LINE__); + put_tty_driver(serial_driver); + serial_driver = NULL; + goto error; + } + + printk("%s %s, tty major#%d\n", + driver_name, driver_version, + serial_driver->major); + + return 0; + +error: + synclinkmp_cleanup(); + return rc; +} + +static void __exit synclinkmp_exit(void) +{ + synclinkmp_cleanup(); +} + +module_init(synclinkmp_init); +module_exit(synclinkmp_exit); + +/* Set the port for internal loopback mode. + * The TxCLK and RxCLK signals are generated from the BRG and + * the TxD is looped back to the RxD internally. + */ +static void enable_loopback(SLMP_INFO *info, int enable) +{ + if (enable) { + /* MD2 (Mode Register 2) + * 01..00 CNCT<1..0> Channel Connection 11=Local Loopback + */ + write_reg(info, MD2, (unsigned char)(read_reg(info, MD2) | (BIT1 + BIT0))); + + /* degate external TxC clock source */ + info->port_array[0]->ctrlreg_value |= (BIT0 << (info->port_num * 2)); + write_control_reg(info); + + /* RXS/TXS (Rx/Tx clock source) + * 07 Reserved, must be 0 + * 06..04 Clock Source, 100=BRG + * 03..00 Clock Divisor, 0000=1 + */ + write_reg(info, RXS, 0x40); + write_reg(info, TXS, 0x40); + + } else { + /* MD2 (Mode Register 2) + * 01..00 CNCT<1..0> Channel connection, 0=normal + */ + write_reg(info, MD2, (unsigned char)(read_reg(info, MD2) & ~(BIT1 + BIT0))); + + /* RXS/TXS (Rx/Tx clock source) + * 07 Reserved, must be 0 + * 06..04 Clock Source, 000=RxC/TxC Pin + * 03..00 Clock Divisor, 0000=1 + */ + write_reg(info, RXS, 0x00); + write_reg(info, TXS, 0x00); + } + + /* set LinkSpeed if available, otherwise default to 2Mbps */ + if (info->params.clock_speed) + set_rate(info, info->params.clock_speed); + else + set_rate(info, 3686400); +} + +/* Set the baud rate register to the desired speed + * + * data_rate data rate of clock in bits per second + * A data rate of 0 disables the AUX clock. + */ +static void set_rate( SLMP_INFO *info, u32 data_rate ) +{ + u32 TMCValue; + unsigned char BRValue; + u32 Divisor=0; + + /* fBRG = fCLK/(TMC * 2^BR) + */ + if (data_rate != 0) { + Divisor = 14745600/data_rate; + if (!Divisor) + Divisor = 1; + + TMCValue = Divisor; + + BRValue = 0; + if (TMCValue != 1 && TMCValue != 2) { + /* BRValue of 0 provides 50/50 duty cycle *only* when + * TMCValue is 1 or 2. BRValue of 1 to 9 always provides + * 50/50 duty cycle. + */ + BRValue = 1; + TMCValue >>= 1; + } + + /* while TMCValue is too big for TMC register, divide + * by 2 and increment BR exponent. + */ + for(; TMCValue > 256 && BRValue < 10; BRValue++) + TMCValue >>= 1; + + write_reg(info, TXS, + (unsigned char)((read_reg(info, TXS) & 0xf0) | BRValue)); + write_reg(info, RXS, + (unsigned char)((read_reg(info, RXS) & 0xf0) | BRValue)); + write_reg(info, TMC, (unsigned char)TMCValue); + } + else { + write_reg(info, TXS,0); + write_reg(info, RXS,0); + write_reg(info, TMC, 0); + } +} + +/* Disable receiver + */ +static void rx_stop(SLMP_INFO *info) +{ + if (debug_level >= DEBUG_LEVEL_ISR) + printk("%s(%d):%s rx_stop()\n", + __FILE__,__LINE__, info->device_name ); + + write_reg(info, CMD, RXRESET); + + info->ie0_value &= ~RXRDYE; + write_reg(info, IE0, info->ie0_value); /* disable Rx data interrupts */ + + write_reg(info, RXDMA + DSR, 0); /* disable Rx DMA */ + write_reg(info, RXDMA + DCMD, SWABORT); /* reset/init Rx DMA */ + write_reg(info, RXDMA + DIR, 0); /* disable Rx DMA interrupts */ + + info->rx_enabled = false; + info->rx_overflow = false; +} + +/* enable the receiver + */ +static void rx_start(SLMP_INFO *info) +{ + int i; + + if (debug_level >= DEBUG_LEVEL_ISR) + printk("%s(%d):%s rx_start()\n", + __FILE__,__LINE__, info->device_name ); + + write_reg(info, CMD, RXRESET); + + if ( info->params.mode == MGSL_MODE_HDLC ) { + /* HDLC, disabe IRQ on rxdata */ + info->ie0_value &= ~RXRDYE; + write_reg(info, IE0, info->ie0_value); + + /* Reset all Rx DMA buffers and program rx dma */ + write_reg(info, RXDMA + DSR, 0); /* disable Rx DMA */ + write_reg(info, RXDMA + DCMD, SWABORT); /* reset/init Rx DMA */ + + for (i = 0; i < info->rx_buf_count; i++) { + info->rx_buf_list[i].status = 0xff; + + // throttle to 4 shared memory writes at a time to prevent + // hogging local bus (keep latency time for DMA requests low). + if (!(i % 4)) + read_status_reg(info); + } + info->current_rx_buf = 0; + + /* set current/1st descriptor address */ + write_reg16(info, RXDMA + CDA, + info->rx_buf_list_ex[0].phys_entry); + + /* set new last rx descriptor address */ + write_reg16(info, RXDMA + EDA, + info->rx_buf_list_ex[info->rx_buf_count - 1].phys_entry); + + /* set buffer length (shared by all rx dma data buffers) */ + write_reg16(info, RXDMA + BFL, SCABUFSIZE); + + write_reg(info, RXDMA + DIR, 0x60); /* enable Rx DMA interrupts (EOM/BOF) */ + write_reg(info, RXDMA + DSR, 0xf2); /* clear Rx DMA IRQs, enable Rx DMA */ + } else { + /* async, enable IRQ on rxdata */ + info->ie0_value |= RXRDYE; + write_reg(info, IE0, info->ie0_value); + } + + write_reg(info, CMD, RXENABLE); + + info->rx_overflow = false; + info->rx_enabled = true; +} + +/* Enable the transmitter and send a transmit frame if + * one is loaded in the DMA buffers. + */ +static void tx_start(SLMP_INFO *info) +{ + if (debug_level >= DEBUG_LEVEL_ISR) + printk("%s(%d):%s tx_start() tx_count=%d\n", + __FILE__,__LINE__, info->device_name,info->tx_count ); + + if (!info->tx_enabled ) { + write_reg(info, CMD, TXRESET); + write_reg(info, CMD, TXENABLE); + info->tx_enabled = true; + } + + if ( info->tx_count ) { + + /* If auto RTS enabled and RTS is inactive, then assert */ + /* RTS and set a flag indicating that the driver should */ + /* negate RTS when the transmission completes. */ + + info->drop_rts_on_tx_done = false; + + if (info->params.mode != MGSL_MODE_ASYNC) { + + if ( info->params.flags & HDLC_FLAG_AUTO_RTS ) { + get_signals( info ); + if ( !(info->serial_signals & SerialSignal_RTS) ) { + info->serial_signals |= SerialSignal_RTS; + set_signals( info ); + info->drop_rts_on_tx_done = true; + } + } + + write_reg16(info, TRC0, + (unsigned short)(((tx_negate_fifo_level-1)<<8) + tx_active_fifo_level)); + + write_reg(info, TXDMA + DSR, 0); /* disable DMA channel */ + write_reg(info, TXDMA + DCMD, SWABORT); /* reset/init DMA channel */ + + /* set TX CDA (current descriptor address) */ + write_reg16(info, TXDMA + CDA, + info->tx_buf_list_ex[0].phys_entry); + + /* set TX EDA (last descriptor address) */ + write_reg16(info, TXDMA + EDA, + info->tx_buf_list_ex[info->last_tx_buf].phys_entry); + + /* enable underrun IRQ */ + info->ie1_value &= ~IDLE; + info->ie1_value |= UDRN; + write_reg(info, IE1, info->ie1_value); + write_reg(info, SR1, (unsigned char)(IDLE + UDRN)); + + write_reg(info, TXDMA + DIR, 0x40); /* enable Tx DMA interrupts (EOM) */ + write_reg(info, TXDMA + DSR, 0xf2); /* clear Tx DMA IRQs, enable Tx DMA */ + + mod_timer(&info->tx_timer, jiffies + + msecs_to_jiffies(5000)); + } + else { + tx_load_fifo(info); + /* async, enable IRQ on txdata */ + info->ie0_value |= TXRDYE; + write_reg(info, IE0, info->ie0_value); + } + + info->tx_active = true; + } +} + +/* stop the transmitter and DMA + */ +static void tx_stop( SLMP_INFO *info ) +{ + if (debug_level >= DEBUG_LEVEL_ISR) + printk("%s(%d):%s tx_stop()\n", + __FILE__,__LINE__, info->device_name ); + + del_timer(&info->tx_timer); + + write_reg(info, TXDMA + DSR, 0); /* disable DMA channel */ + write_reg(info, TXDMA + DCMD, SWABORT); /* reset/init DMA channel */ + + write_reg(info, CMD, TXRESET); + + info->ie1_value &= ~(UDRN + IDLE); + write_reg(info, IE1, info->ie1_value); /* disable tx status interrupts */ + write_reg(info, SR1, (unsigned char)(IDLE + UDRN)); /* clear pending */ + + info->ie0_value &= ~TXRDYE; + write_reg(info, IE0, info->ie0_value); /* disable tx data interrupts */ + + info->tx_enabled = false; + info->tx_active = false; +} + +/* Fill the transmit FIFO until the FIFO is full or + * there is no more data to load. + */ +static void tx_load_fifo(SLMP_INFO *info) +{ + u8 TwoBytes[2]; + + /* do nothing is now tx data available and no XON/XOFF pending */ + + if ( !info->tx_count && !info->x_char ) + return; + + /* load the Transmit FIFO until FIFOs full or all data sent */ + + while( info->tx_count && (read_reg(info,SR0) & BIT1) ) { + + /* there is more space in the transmit FIFO and */ + /* there is more data in transmit buffer */ + + if ( (info->tx_count > 1) && !info->x_char ) { + /* write 16-bits */ + TwoBytes[0] = info->tx_buf[info->tx_get++]; + if (info->tx_get >= info->max_frame_size) + info->tx_get -= info->max_frame_size; + TwoBytes[1] = info->tx_buf[info->tx_get++]; + if (info->tx_get >= info->max_frame_size) + info->tx_get -= info->max_frame_size; + + write_reg16(info, TRB, *((u16 *)TwoBytes)); + + info->tx_count -= 2; + info->icount.tx += 2; + } else { + /* only 1 byte left to transmit or 1 FIFO slot left */ + + if (info->x_char) { + /* transmit pending high priority char */ + write_reg(info, TRB, info->x_char); + info->x_char = 0; + } else { + write_reg(info, TRB, info->tx_buf[info->tx_get++]); + if (info->tx_get >= info->max_frame_size) + info->tx_get -= info->max_frame_size; + info->tx_count--; + } + info->icount.tx++; + } + } +} + +/* Reset a port to a known state + */ +static void reset_port(SLMP_INFO *info) +{ + if (info->sca_base) { + + tx_stop(info); + rx_stop(info); + + info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); + set_signals(info); + + /* disable all port interrupts */ + info->ie0_value = 0; + info->ie1_value = 0; + info->ie2_value = 0; + write_reg(info, IE0, info->ie0_value); + write_reg(info, IE1, info->ie1_value); + write_reg(info, IE2, info->ie2_value); + + write_reg(info, CMD, CHRESET); + } +} + +/* Reset all the ports to a known state. + */ +static void reset_adapter(SLMP_INFO *info) +{ + int i; + + for ( i=0; i < SCA_MAX_PORTS; ++i) { + if (info->port_array[i]) + reset_port(info->port_array[i]); + } +} + +/* Program port for asynchronous communications. + */ +static void async_mode(SLMP_INFO *info) +{ + + unsigned char RegValue; + + tx_stop(info); + rx_stop(info); + + /* MD0, Mode Register 0 + * + * 07..05 PRCTL<2..0>, Protocol Mode, 000=async + * 04 AUTO, Auto-enable (RTS/CTS/DCD) + * 03 Reserved, must be 0 + * 02 CRCCC, CRC Calculation, 0=disabled + * 01..00 STOP<1..0> Stop bits (00=1,10=2) + * + * 0000 0000 + */ + RegValue = 0x00; + if (info->params.stop_bits != 1) + RegValue |= BIT1; + write_reg(info, MD0, RegValue); + + /* MD1, Mode Register 1 + * + * 07..06 BRATE<1..0>, bit rate, 00=1/1 01=1/16 10=1/32 11=1/64 + * 05..04 TXCHR<1..0>, tx char size, 00=8 bits,01=7,10=6,11=5 + * 03..02 RXCHR<1..0>, rx char size + * 01..00 PMPM<1..0>, Parity mode, 00=none 10=even 11=odd + * + * 0100 0000 + */ + RegValue = 0x40; + switch (info->params.data_bits) { + case 7: RegValue |= BIT4 + BIT2; break; + case 6: RegValue |= BIT5 + BIT3; break; + case 5: RegValue |= BIT5 + BIT4 + BIT3 + BIT2; break; + } + if (info->params.parity != ASYNC_PARITY_NONE) { + RegValue |= BIT1; + if (info->params.parity == ASYNC_PARITY_ODD) + RegValue |= BIT0; + } + write_reg(info, MD1, RegValue); + + /* MD2, Mode Register 2 + * + * 07..02 Reserved, must be 0 + * 01..00 CNCT<1..0> Channel connection, 00=normal 11=local loopback + * + * 0000 0000 + */ + RegValue = 0x00; + if (info->params.loopback) + RegValue |= (BIT1 + BIT0); + write_reg(info, MD2, RegValue); + + /* RXS, Receive clock source + * + * 07 Reserved, must be 0 + * 06..04 RXCS<2..0>, clock source, 000=RxC Pin, 100=BRG, 110=DPLL + * 03..00 RXBR<3..0>, rate divisor, 0000=1 + */ + RegValue=BIT6; + write_reg(info, RXS, RegValue); + + /* TXS, Transmit clock source + * + * 07 Reserved, must be 0 + * 06..04 RXCS<2..0>, clock source, 000=TxC Pin, 100=BRG, 110=Receive Clock + * 03..00 RXBR<3..0>, rate divisor, 0000=1 + */ + RegValue=BIT6; + write_reg(info, TXS, RegValue); + + /* Control Register + * + * 6,4,2,0 CLKSEL<3..0>, 0 = TcCLK in, 1 = Auxclk out + */ + info->port_array[0]->ctrlreg_value |= (BIT0 << (info->port_num * 2)); + write_control_reg(info); + + tx_set_idle(info); + + /* RRC Receive Ready Control 0 + * + * 07..05 Reserved, must be 0 + * 04..00 RRC<4..0> Rx FIFO trigger active 0x00 = 1 byte + */ + write_reg(info, RRC, 0x00); + + /* TRC0 Transmit Ready Control 0 + * + * 07..05 Reserved, must be 0 + * 04..00 TRC<4..0> Tx FIFO trigger active 0x10 = 16 bytes + */ + write_reg(info, TRC0, 0x10); + + /* TRC1 Transmit Ready Control 1 + * + * 07..05 Reserved, must be 0 + * 04..00 TRC<4..0> Tx FIFO trigger inactive 0x1e = 31 bytes (full-1) + */ + write_reg(info, TRC1, 0x1e); + + /* CTL, MSCI control register + * + * 07..06 Reserved, set to 0 + * 05 UDRNC, underrun control, 0=abort 1=CRC+flag (HDLC/BSC) + * 04 IDLC, idle control, 0=mark 1=idle register + * 03 BRK, break, 0=off 1 =on (async) + * 02 SYNCLD, sync char load enable (BSC) 1=enabled + * 01 GOP, go active on poll (LOOP mode) 1=enabled + * 00 RTS, RTS output control, 0=active 1=inactive + * + * 0001 0001 + */ + RegValue = 0x10; + if (!(info->serial_signals & SerialSignal_RTS)) + RegValue |= 0x01; + write_reg(info, CTL, RegValue); + + /* enable status interrupts */ + info->ie0_value |= TXINTE + RXINTE; + write_reg(info, IE0, info->ie0_value); + + /* enable break detect interrupt */ + info->ie1_value = BRKD; + write_reg(info, IE1, info->ie1_value); + + /* enable rx overrun interrupt */ + info->ie2_value = OVRN; + write_reg(info, IE2, info->ie2_value); + + set_rate( info, info->params.data_rate * 16 ); +} + +/* Program the SCA for HDLC communications. + */ +static void hdlc_mode(SLMP_INFO *info) +{ + unsigned char RegValue; + u32 DpllDivisor; + + // Can't use DPLL because SCA outputs recovered clock on RxC when + // DPLL mode selected. This causes output contention with RxC receiver. + // Use of DPLL would require external hardware to disable RxC receiver + // when DPLL mode selected. + info->params.flags &= ~(HDLC_FLAG_TXC_DPLL + HDLC_FLAG_RXC_DPLL); + + /* disable DMA interrupts */ + write_reg(info, TXDMA + DIR, 0); + write_reg(info, RXDMA + DIR, 0); + + /* MD0, Mode Register 0 + * + * 07..05 PRCTL<2..0>, Protocol Mode, 100=HDLC + * 04 AUTO, Auto-enable (RTS/CTS/DCD) + * 03 Reserved, must be 0 + * 02 CRCCC, CRC Calculation, 1=enabled + * 01 CRC1, CRC selection, 0=CRC-16,1=CRC-CCITT-16 + * 00 CRC0, CRC initial value, 1 = all 1s + * + * 1000 0001 + */ + RegValue = 0x81; + if (info->params.flags & HDLC_FLAG_AUTO_CTS) + RegValue |= BIT4; + if (info->params.flags & HDLC_FLAG_AUTO_DCD) + RegValue |= BIT4; + if (info->params.crc_type == HDLC_CRC_16_CCITT) + RegValue |= BIT2 + BIT1; + write_reg(info, MD0, RegValue); + + /* MD1, Mode Register 1 + * + * 07..06 ADDRS<1..0>, Address detect, 00=no addr check + * 05..04 TXCHR<1..0>, tx char size, 00=8 bits + * 03..02 RXCHR<1..0>, rx char size, 00=8 bits + * 01..00 PMPM<1..0>, Parity mode, 00=no parity + * + * 0000 0000 + */ + RegValue = 0x00; + write_reg(info, MD1, RegValue); + + /* MD2, Mode Register 2 + * + * 07 NRZFM, 0=NRZ, 1=FM + * 06..05 CODE<1..0> Encoding, 00=NRZ + * 04..03 DRATE<1..0> DPLL Divisor, 00=8 + * 02 Reserved, must be 0 + * 01..00 CNCT<1..0> Channel connection, 0=normal + * + * 0000 0000 + */ + RegValue = 0x00; + switch(info->params.encoding) { + case HDLC_ENCODING_NRZI: RegValue |= BIT5; break; + case HDLC_ENCODING_BIPHASE_MARK: RegValue |= BIT7 + BIT5; break; /* aka FM1 */ + case HDLC_ENCODING_BIPHASE_SPACE: RegValue |= BIT7 + BIT6; break; /* aka FM0 */ + case HDLC_ENCODING_BIPHASE_LEVEL: RegValue |= BIT7; break; /* aka Manchester */ +#if 0 + case HDLC_ENCODING_NRZB: /* not supported */ + case HDLC_ENCODING_NRZI_MARK: /* not supported */ + case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: /* not supported */ +#endif + } + if ( info->params.flags & HDLC_FLAG_DPLL_DIV16 ) { + DpllDivisor = 16; + RegValue |= BIT3; + } else if ( info->params.flags & HDLC_FLAG_DPLL_DIV8 ) { + DpllDivisor = 8; + } else { + DpllDivisor = 32; + RegValue |= BIT4; + } + write_reg(info, MD2, RegValue); + + + /* RXS, Receive clock source + * + * 07 Reserved, must be 0 + * 06..04 RXCS<2..0>, clock source, 000=RxC Pin, 100=BRG, 110=DPLL + * 03..00 RXBR<3..0>, rate divisor, 0000=1 + */ + RegValue=0; + if (info->params.flags & HDLC_FLAG_RXC_BRG) + RegValue |= BIT6; + if (info->params.flags & HDLC_FLAG_RXC_DPLL) + RegValue |= BIT6 + BIT5; + write_reg(info, RXS, RegValue); + + /* TXS, Transmit clock source + * + * 07 Reserved, must be 0 + * 06..04 RXCS<2..0>, clock source, 000=TxC Pin, 100=BRG, 110=Receive Clock + * 03..00 RXBR<3..0>, rate divisor, 0000=1 + */ + RegValue=0; + if (info->params.flags & HDLC_FLAG_TXC_BRG) + RegValue |= BIT6; + if (info->params.flags & HDLC_FLAG_TXC_DPLL) + RegValue |= BIT6 + BIT5; + write_reg(info, TXS, RegValue); + + if (info->params.flags & HDLC_FLAG_RXC_DPLL) + set_rate(info, info->params.clock_speed * DpllDivisor); + else + set_rate(info, info->params.clock_speed); + + /* GPDATA (General Purpose I/O Data Register) + * + * 6,4,2,0 CLKSEL<3..0>, 0 = TcCLK in, 1 = Auxclk out + */ + if (info->params.flags & HDLC_FLAG_TXC_BRG) + info->port_array[0]->ctrlreg_value |= (BIT0 << (info->port_num * 2)); + else + info->port_array[0]->ctrlreg_value &= ~(BIT0 << (info->port_num * 2)); + write_control_reg(info); + + /* RRC Receive Ready Control 0 + * + * 07..05 Reserved, must be 0 + * 04..00 RRC<4..0> Rx FIFO trigger active + */ + write_reg(info, RRC, rx_active_fifo_level); + + /* TRC0 Transmit Ready Control 0 + * + * 07..05 Reserved, must be 0 + * 04..00 TRC<4..0> Tx FIFO trigger active + */ + write_reg(info, TRC0, tx_active_fifo_level); + + /* TRC1 Transmit Ready Control 1 + * + * 07..05 Reserved, must be 0 + * 04..00 TRC<4..0> Tx FIFO trigger inactive 0x1f = 32 bytes (full) + */ + write_reg(info, TRC1, (unsigned char)(tx_negate_fifo_level - 1)); + + /* DMR, DMA Mode Register + * + * 07..05 Reserved, must be 0 + * 04 TMOD, Transfer Mode: 1=chained-block + * 03 Reserved, must be 0 + * 02 NF, Number of Frames: 1=multi-frame + * 01 CNTE, Frame End IRQ Counter enable: 0=disabled + * 00 Reserved, must be 0 + * + * 0001 0100 + */ + write_reg(info, TXDMA + DMR, 0x14); + write_reg(info, RXDMA + DMR, 0x14); + + /* Set chain pointer base (upper 8 bits of 24 bit addr) */ + write_reg(info, RXDMA + CPB, + (unsigned char)(info->buffer_list_phys >> 16)); + + /* Set chain pointer base (upper 8 bits of 24 bit addr) */ + write_reg(info, TXDMA + CPB, + (unsigned char)(info->buffer_list_phys >> 16)); + + /* enable status interrupts. other code enables/disables + * the individual sources for these two interrupt classes. + */ + info->ie0_value |= TXINTE + RXINTE; + write_reg(info, IE0, info->ie0_value); + + /* CTL, MSCI control register + * + * 07..06 Reserved, set to 0 + * 05 UDRNC, underrun control, 0=abort 1=CRC+flag (HDLC/BSC) + * 04 IDLC, idle control, 0=mark 1=idle register + * 03 BRK, break, 0=off 1 =on (async) + * 02 SYNCLD, sync char load enable (BSC) 1=enabled + * 01 GOP, go active on poll (LOOP mode) 1=enabled + * 00 RTS, RTS output control, 0=active 1=inactive + * + * 0001 0001 + */ + RegValue = 0x10; + if (!(info->serial_signals & SerialSignal_RTS)) + RegValue |= 0x01; + write_reg(info, CTL, RegValue); + + /* preamble not supported ! */ + + tx_set_idle(info); + tx_stop(info); + rx_stop(info); + + set_rate(info, info->params.clock_speed); + + if (info->params.loopback) + enable_loopback(info,1); +} + +/* Set the transmit HDLC idle mode + */ +static void tx_set_idle(SLMP_INFO *info) +{ + unsigned char RegValue = 0xff; + + /* Map API idle mode to SCA register bits */ + switch(info->idle_mode) { + case HDLC_TXIDLE_FLAGS: RegValue = 0x7e; break; + case HDLC_TXIDLE_ALT_ZEROS_ONES: RegValue = 0xaa; break; + case HDLC_TXIDLE_ZEROS: RegValue = 0x00; break; + case HDLC_TXIDLE_ONES: RegValue = 0xff; break; + case HDLC_TXIDLE_ALT_MARK_SPACE: RegValue = 0xaa; break; + case HDLC_TXIDLE_SPACE: RegValue = 0x00; break; + case HDLC_TXIDLE_MARK: RegValue = 0xff; break; + } + + write_reg(info, IDL, RegValue); +} + +/* Query the adapter for the state of the V24 status (input) signals. + */ +static void get_signals(SLMP_INFO *info) +{ + u16 status = read_reg(info, SR3); + u16 gpstatus = read_status_reg(info); + u16 testbit; + + /* clear all serial signals except DTR and RTS */ + info->serial_signals &= SerialSignal_DTR + SerialSignal_RTS; + + /* set serial signal bits to reflect MISR */ + + if (!(status & BIT3)) + info->serial_signals |= SerialSignal_CTS; + + if ( !(status & BIT2)) + info->serial_signals |= SerialSignal_DCD; + + testbit = BIT1 << (info->port_num * 2); // Port 0..3 RI is GPDATA<1,3,5,7> + if (!(gpstatus & testbit)) + info->serial_signals |= SerialSignal_RI; + + testbit = BIT0 << (info->port_num * 2); // Port 0..3 DSR is GPDATA<0,2,4,6> + if (!(gpstatus & testbit)) + info->serial_signals |= SerialSignal_DSR; +} + +/* Set the state of DTR and RTS based on contents of + * serial_signals member of device context. + */ +static void set_signals(SLMP_INFO *info) +{ + unsigned char RegValue; + u16 EnableBit; + + RegValue = read_reg(info, CTL); + if (info->serial_signals & SerialSignal_RTS) + RegValue &= ~BIT0; + else + RegValue |= BIT0; + write_reg(info, CTL, RegValue); + + // Port 0..3 DTR is ctrl reg <1,3,5,7> + EnableBit = BIT1 << (info->port_num*2); + if (info->serial_signals & SerialSignal_DTR) + info->port_array[0]->ctrlreg_value &= ~EnableBit; + else + info->port_array[0]->ctrlreg_value |= EnableBit; + write_control_reg(info); +} + +/*******************/ +/* DMA Buffer Code */ +/*******************/ + +/* Set the count for all receive buffers to SCABUFSIZE + * and set the current buffer to the first buffer. This effectively + * makes all buffers free and discards any data in buffers. + */ +static void rx_reset_buffers(SLMP_INFO *info) +{ + rx_free_frame_buffers(info, 0, info->rx_buf_count - 1); +} + +/* Free the buffers used by a received frame + * + * info pointer to device instance data + * first index of 1st receive buffer of frame + * last index of last receive buffer of frame + */ +static void rx_free_frame_buffers(SLMP_INFO *info, unsigned int first, unsigned int last) +{ + bool done = false; + + while(!done) { + /* reset current buffer for reuse */ + info->rx_buf_list[first].status = 0xff; + + if (first == last) { + done = true; + /* set new last rx descriptor address */ + write_reg16(info, RXDMA + EDA, info->rx_buf_list_ex[first].phys_entry); + } + + first++; + if (first == info->rx_buf_count) + first = 0; + } + + /* set current buffer to next buffer after last buffer of frame */ + info->current_rx_buf = first; +} + +/* Return a received frame from the receive DMA buffers. + * Only frames received without errors are returned. + * + * Return Value: true if frame returned, otherwise false + */ +static bool rx_get_frame(SLMP_INFO *info) +{ + unsigned int StartIndex, EndIndex; /* index of 1st and last buffers of Rx frame */ + unsigned short status; + unsigned int framesize = 0; + bool ReturnCode = false; + unsigned long flags; + struct tty_struct *tty = info->port.tty; + unsigned char addr_field = 0xff; + SCADESC *desc; + SCADESC_EX *desc_ex; + +CheckAgain: + /* assume no frame returned, set zero length */ + framesize = 0; + addr_field = 0xff; + + /* + * current_rx_buf points to the 1st buffer of the next available + * receive frame. To find the last buffer of the frame look for + * a non-zero status field in the buffer entries. (The status + * field is set by the 16C32 after completing a receive frame. + */ + StartIndex = EndIndex = info->current_rx_buf; + + for ( ;; ) { + desc = &info->rx_buf_list[EndIndex]; + desc_ex = &info->rx_buf_list_ex[EndIndex]; + + if (desc->status == 0xff) + goto Cleanup; /* current desc still in use, no frames available */ + + if (framesize == 0 && info->params.addr_filter != 0xff) + addr_field = desc_ex->virt_addr[0]; + + framesize += desc->length; + + /* Status != 0 means last buffer of frame */ + if (desc->status) + break; + + EndIndex++; + if (EndIndex == info->rx_buf_count) + EndIndex = 0; + + if (EndIndex == info->current_rx_buf) { + /* all buffers have been 'used' but none mark */ + /* the end of a frame. Reset buffers and receiver. */ + if ( info->rx_enabled ){ + spin_lock_irqsave(&info->lock,flags); + rx_start(info); + spin_unlock_irqrestore(&info->lock,flags); + } + goto Cleanup; + } + + } + + /* check status of receive frame */ + + /* frame status is byte stored after frame data + * + * 7 EOM (end of msg), 1 = last buffer of frame + * 6 Short Frame, 1 = short frame + * 5 Abort, 1 = frame aborted + * 4 Residue, 1 = last byte is partial + * 3 Overrun, 1 = overrun occurred during frame reception + * 2 CRC, 1 = CRC error detected + * + */ + status = desc->status; + + /* ignore CRC bit if not using CRC (bit is undefined) */ + /* Note:CRC is not save to data buffer */ + if (info->params.crc_type == HDLC_CRC_NONE) + status &= ~BIT2; + + if (framesize == 0 || + (addr_field != 0xff && addr_field != info->params.addr_filter)) { + /* discard 0 byte frames, this seems to occur sometime + * when remote is idling flags. + */ + rx_free_frame_buffers(info, StartIndex, EndIndex); + goto CheckAgain; + } + + if (framesize < 2) + status |= BIT6; + + if (status & (BIT6+BIT5+BIT3+BIT2)) { + /* received frame has errors, + * update counts and mark frame size as 0 + */ + if (status & BIT6) + info->icount.rxshort++; + else if (status & BIT5) + info->icount.rxabort++; + else if (status & BIT3) + info->icount.rxover++; + else + info->icount.rxcrc++; + + framesize = 0; +#if SYNCLINK_GENERIC_HDLC + { + info->netdev->stats.rx_errors++; + info->netdev->stats.rx_frame_errors++; + } +#endif + } + + if ( debug_level >= DEBUG_LEVEL_BH ) + printk("%s(%d):%s rx_get_frame() status=%04X size=%d\n", + __FILE__,__LINE__,info->device_name,status,framesize); + + if ( debug_level >= DEBUG_LEVEL_DATA ) + trace_block(info,info->rx_buf_list_ex[StartIndex].virt_addr, + min_t(int, framesize,SCABUFSIZE),0); + + if (framesize) { + if (framesize > info->max_frame_size) + info->icount.rxlong++; + else { + /* copy dma buffer(s) to contiguous intermediate buffer */ + int copy_count = framesize; + int index = StartIndex; + unsigned char *ptmp = info->tmp_rx_buf; + info->tmp_rx_buf_count = framesize; + + info->icount.rxok++; + + while(copy_count) { + int partial_count = min(copy_count,SCABUFSIZE); + memcpy( ptmp, + info->rx_buf_list_ex[index].virt_addr, + partial_count ); + ptmp += partial_count; + copy_count -= partial_count; + + if ( ++index == info->rx_buf_count ) + index = 0; + } + +#if SYNCLINK_GENERIC_HDLC + if (info->netcount) + hdlcdev_rx(info,info->tmp_rx_buf,framesize); + else +#endif + ldisc_receive_buf(tty,info->tmp_rx_buf, + info->flag_buf, framesize); + } + } + /* Free the buffers used by this frame. */ + rx_free_frame_buffers( info, StartIndex, EndIndex ); + + ReturnCode = true; + +Cleanup: + if ( info->rx_enabled && info->rx_overflow ) { + /* Receiver is enabled, but needs to restarted due to + * rx buffer overflow. If buffers are empty, restart receiver. + */ + if (info->rx_buf_list[EndIndex].status == 0xff) { + spin_lock_irqsave(&info->lock,flags); + rx_start(info); + spin_unlock_irqrestore(&info->lock,flags); + } + } + + return ReturnCode; +} + +/* load the transmit DMA buffer with data + */ +static void tx_load_dma_buffer(SLMP_INFO *info, const char *buf, unsigned int count) +{ + unsigned short copy_count; + unsigned int i = 0; + SCADESC *desc; + SCADESC_EX *desc_ex; + + if ( debug_level >= DEBUG_LEVEL_DATA ) + trace_block(info,buf, min_t(int, count,SCABUFSIZE), 1); + + /* Copy source buffer to one or more DMA buffers, starting with + * the first transmit dma buffer. + */ + for(i=0;;) + { + copy_count = min_t(unsigned short,count,SCABUFSIZE); + + desc = &info->tx_buf_list[i]; + desc_ex = &info->tx_buf_list_ex[i]; + + load_pci_memory(info, desc_ex->virt_addr,buf,copy_count); + + desc->length = copy_count; + desc->status = 0; + + buf += copy_count; + count -= copy_count; + + if (!count) + break; + + i++; + if (i >= info->tx_buf_count) + i = 0; + } + + info->tx_buf_list[i].status = 0x81; /* set EOM and EOT status */ + info->last_tx_buf = ++i; +} + +static bool register_test(SLMP_INFO *info) +{ + static unsigned char testval[] = {0x00, 0xff, 0xaa, 0x55, 0x69, 0x96}; + static unsigned int count = ARRAY_SIZE(testval); + unsigned int i; + bool rc = true; + unsigned long flags; + + spin_lock_irqsave(&info->lock,flags); + reset_port(info); + + /* assume failure */ + info->init_error = DiagStatus_AddressFailure; + + /* Write bit patterns to various registers but do it out of */ + /* sync, then read back and verify values. */ + + for (i = 0 ; i < count ; i++) { + write_reg(info, TMC, testval[i]); + write_reg(info, IDL, testval[(i+1)%count]); + write_reg(info, SA0, testval[(i+2)%count]); + write_reg(info, SA1, testval[(i+3)%count]); + + if ( (read_reg(info, TMC) != testval[i]) || + (read_reg(info, IDL) != testval[(i+1)%count]) || + (read_reg(info, SA0) != testval[(i+2)%count]) || + (read_reg(info, SA1) != testval[(i+3)%count]) ) + { + rc = false; + break; + } + } + + reset_port(info); + spin_unlock_irqrestore(&info->lock,flags); + + return rc; +} + +static bool irq_test(SLMP_INFO *info) +{ + unsigned long timeout; + unsigned long flags; + + unsigned char timer = (info->port_num & 1) ? TIMER2 : TIMER0; + + spin_lock_irqsave(&info->lock,flags); + reset_port(info); + + /* assume failure */ + info->init_error = DiagStatus_IrqFailure; + info->irq_occurred = false; + + /* setup timer0 on SCA0 to interrupt */ + + /* IER2<7..4> = timer<3..0> interrupt enables (1=enabled) */ + write_reg(info, IER2, (unsigned char)((info->port_num & 1) ? BIT6 : BIT4)); + + write_reg(info, (unsigned char)(timer + TEPR), 0); /* timer expand prescale */ + write_reg16(info, (unsigned char)(timer + TCONR), 1); /* timer constant */ + + + /* TMCS, Timer Control/Status Register + * + * 07 CMF, Compare match flag (read only) 1=match + * 06 ECMI, CMF Interrupt Enable: 1=enabled + * 05 Reserved, must be 0 + * 04 TME, Timer Enable + * 03..00 Reserved, must be 0 + * + * 0101 0000 + */ + write_reg(info, (unsigned char)(timer + TMCS), 0x50); + + spin_unlock_irqrestore(&info->lock,flags); + + timeout=100; + while( timeout-- && !info->irq_occurred ) { + msleep_interruptible(10); + } + + spin_lock_irqsave(&info->lock,flags); + reset_port(info); + spin_unlock_irqrestore(&info->lock,flags); + + return info->irq_occurred; +} + +/* initialize individual SCA device (2 ports) + */ +static bool sca_init(SLMP_INFO *info) +{ + /* set wait controller to single mem partition (low), no wait states */ + write_reg(info, PABR0, 0); /* wait controller addr boundary 0 */ + write_reg(info, PABR1, 0); /* wait controller addr boundary 1 */ + write_reg(info, WCRL, 0); /* wait controller low range */ + write_reg(info, WCRM, 0); /* wait controller mid range */ + write_reg(info, WCRH, 0); /* wait controller high range */ + + /* DPCR, DMA Priority Control + * + * 07..05 Not used, must be 0 + * 04 BRC, bus release condition: 0=all transfers complete + * 03 CCC, channel change condition: 0=every cycle + * 02..00 PR<2..0>, priority 100=round robin + * + * 00000100 = 0x04 + */ + write_reg(info, DPCR, dma_priority); + + /* DMA Master Enable, BIT7: 1=enable all channels */ + write_reg(info, DMER, 0x80); + + /* enable all interrupt classes */ + write_reg(info, IER0, 0xff); /* TxRDY,RxRDY,TxINT,RxINT (ports 0-1) */ + write_reg(info, IER1, 0xff); /* DMIB,DMIA (channels 0-3) */ + write_reg(info, IER2, 0xf0); /* TIRQ (timers 0-3) */ + + /* ITCR, interrupt control register + * 07 IPC, interrupt priority, 0=MSCI->DMA + * 06..05 IAK<1..0>, Acknowledge cycle, 00=non-ack cycle + * 04 VOS, Vector Output, 0=unmodified vector + * 03..00 Reserved, must be 0 + */ + write_reg(info, ITCR, 0); + + return true; +} + +/* initialize adapter hardware + */ +static bool init_adapter(SLMP_INFO *info) +{ + int i; + + /* Set BIT30 of Local Control Reg 0x50 to reset SCA */ + volatile u32 *MiscCtrl = (u32 *)(info->lcr_base + 0x50); + u32 readval; + + info->misc_ctrl_value |= BIT30; + *MiscCtrl = info->misc_ctrl_value; + + /* + * Force at least 170ns delay before clearing + * reset bit. Each read from LCR takes at least + * 30ns so 10 times for 300ns to be safe. + */ + for(i=0;i<10;i++) + readval = *MiscCtrl; + + info->misc_ctrl_value &= ~BIT30; + *MiscCtrl = info->misc_ctrl_value; + + /* init control reg (all DTRs off, all clksel=input) */ + info->ctrlreg_value = 0xaa; + write_control_reg(info); + + { + volatile u32 *LCR1BRDR = (u32 *)(info->lcr_base + 0x2c); + lcr1_brdr_value &= ~(BIT5 + BIT4 + BIT3); + + switch(read_ahead_count) + { + case 16: + lcr1_brdr_value |= BIT5 + BIT4 + BIT3; + break; + case 8: + lcr1_brdr_value |= BIT5 + BIT4; + break; + case 4: + lcr1_brdr_value |= BIT5 + BIT3; + break; + case 0: + lcr1_brdr_value |= BIT5; + break; + } + + *LCR1BRDR = lcr1_brdr_value; + *MiscCtrl = misc_ctrl_value; + } + + sca_init(info->port_array[0]); + sca_init(info->port_array[2]); + + return true; +} + +/* Loopback an HDLC frame to test the hardware + * interrupt and DMA functions. + */ +static bool loopback_test(SLMP_INFO *info) +{ +#define TESTFRAMESIZE 20 + + unsigned long timeout; + u16 count = TESTFRAMESIZE; + unsigned char buf[TESTFRAMESIZE]; + bool rc = false; + unsigned long flags; + + struct tty_struct *oldtty = info->port.tty; + u32 speed = info->params.clock_speed; + + info->params.clock_speed = 3686400; + info->port.tty = NULL; + + /* assume failure */ + info->init_error = DiagStatus_DmaFailure; + + /* build and send transmit frame */ + for (count = 0; count < TESTFRAMESIZE;++count) + buf[count] = (unsigned char)count; + + memset(info->tmp_rx_buf,0,TESTFRAMESIZE); + + /* program hardware for HDLC and enabled receiver */ + spin_lock_irqsave(&info->lock,flags); + hdlc_mode(info); + enable_loopback(info,1); + rx_start(info); + info->tx_count = count; + tx_load_dma_buffer(info,buf,count); + tx_start(info); + spin_unlock_irqrestore(&info->lock,flags); + + /* wait for receive complete */ + /* Set a timeout for waiting for interrupt. */ + for ( timeout = 100; timeout; --timeout ) { + msleep_interruptible(10); + + if (rx_get_frame(info)) { + rc = true; + break; + } + } + + /* verify received frame length and contents */ + if (rc && + ( info->tmp_rx_buf_count != count || + memcmp(buf, info->tmp_rx_buf,count))) { + rc = false; + } + + spin_lock_irqsave(&info->lock,flags); + reset_adapter(info); + spin_unlock_irqrestore(&info->lock,flags); + + info->params.clock_speed = speed; + info->port.tty = oldtty; + + return rc; +} + +/* Perform diagnostics on hardware + */ +static int adapter_test( SLMP_INFO *info ) +{ + unsigned long flags; + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):Testing device %s\n", + __FILE__,__LINE__,info->device_name ); + + spin_lock_irqsave(&info->lock,flags); + init_adapter(info); + spin_unlock_irqrestore(&info->lock,flags); + + info->port_array[0]->port_count = 0; + + if ( register_test(info->port_array[0]) && + register_test(info->port_array[1])) { + + info->port_array[0]->port_count = 2; + + if ( register_test(info->port_array[2]) && + register_test(info->port_array[3]) ) + info->port_array[0]->port_count += 2; + } + else { + printk( "%s(%d):Register test failure for device %s Addr=%08lX\n", + __FILE__,__LINE__,info->device_name, (unsigned long)(info->phys_sca_base)); + return -ENODEV; + } + + if ( !irq_test(info->port_array[0]) || + !irq_test(info->port_array[1]) || + (info->port_count == 4 && !irq_test(info->port_array[2])) || + (info->port_count == 4 && !irq_test(info->port_array[3]))) { + printk( "%s(%d):Interrupt test failure for device %s IRQ=%d\n", + __FILE__,__LINE__,info->device_name, (unsigned short)(info->irq_level) ); + return -ENODEV; + } + + if (!loopback_test(info->port_array[0]) || + !loopback_test(info->port_array[1]) || + (info->port_count == 4 && !loopback_test(info->port_array[2])) || + (info->port_count == 4 && !loopback_test(info->port_array[3]))) { + printk( "%s(%d):DMA test failure for device %s\n", + __FILE__,__LINE__,info->device_name); + return -ENODEV; + } + + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):device %s passed diagnostics\n", + __FILE__,__LINE__,info->device_name ); + + info->port_array[0]->init_error = 0; + info->port_array[1]->init_error = 0; + if ( info->port_count > 2 ) { + info->port_array[2]->init_error = 0; + info->port_array[3]->init_error = 0; + } + + return 0; +} + +/* Test the shared memory on a PCI adapter. + */ +static bool memory_test(SLMP_INFO *info) +{ + static unsigned long testval[] = { 0x0, 0x55555555, 0xaaaaaaaa, + 0x66666666, 0x99999999, 0xffffffff, 0x12345678 }; + unsigned long count = ARRAY_SIZE(testval); + unsigned long i; + unsigned long limit = SCA_MEM_SIZE/sizeof(unsigned long); + unsigned long * addr = (unsigned long *)info->memory_base; + + /* Test data lines with test pattern at one location. */ + + for ( i = 0 ; i < count ; i++ ) { + *addr = testval[i]; + if ( *addr != testval[i] ) + return false; + } + + /* Test address lines with incrementing pattern over */ + /* entire address range. */ + + for ( i = 0 ; i < limit ; i++ ) { + *addr = i * 4; + addr++; + } + + addr = (unsigned long *)info->memory_base; + + for ( i = 0 ; i < limit ; i++ ) { + if ( *addr != i * 4 ) + return false; + addr++; + } + + memset( info->memory_base, 0, SCA_MEM_SIZE ); + return true; +} + +/* Load data into PCI adapter shared memory. + * + * The PCI9050 releases control of the local bus + * after completing the current read or write operation. + * + * While the PCI9050 write FIFO not empty, the + * PCI9050 treats all of the writes as a single transaction + * and does not release the bus. This causes DMA latency problems + * at high speeds when copying large data blocks to the shared memory. + * + * This function breaks a write into multiple transations by + * interleaving a read which flushes the write FIFO and 'completes' + * the write transation. This allows any pending DMA request to gain control + * of the local bus in a timely fasion. + */ +static void load_pci_memory(SLMP_INFO *info, char* dest, const char* src, unsigned short count) +{ + /* A load interval of 16 allows for 4 32-bit writes at */ + /* 136ns each for a maximum latency of 542ns on the local bus.*/ + + unsigned short interval = count / sca_pci_load_interval; + unsigned short i; + + for ( i = 0 ; i < interval ; i++ ) + { + memcpy(dest, src, sca_pci_load_interval); + read_status_reg(info); + dest += sca_pci_load_interval; + src += sca_pci_load_interval; + } + + memcpy(dest, src, count % sca_pci_load_interval); +} + +static void trace_block(SLMP_INFO *info,const char* data, int count, int xmit) +{ + int i; + int linecount; + if (xmit) + printk("%s tx data:\n",info->device_name); + else + printk("%s rx data:\n",info->device_name); + + while(count) { + if (count > 16) + linecount = 16; + else + linecount = count; + + for(i=0;i=040 && data[i]<=0176) + printk("%c",data[i]); + else + printk("."); + } + printk("\n"); + + data += linecount; + count -= linecount; + } +} /* end of trace_block() */ + +/* called when HDLC frame times out + * update stats and do tx completion processing + */ +static void tx_timeout(unsigned long context) +{ + SLMP_INFO *info = (SLMP_INFO*)context; + unsigned long flags; + + if ( debug_level >= DEBUG_LEVEL_INFO ) + printk( "%s(%d):%s tx_timeout()\n", + __FILE__,__LINE__,info->device_name); + if(info->tx_active && info->params.mode == MGSL_MODE_HDLC) { + info->icount.txtimeout++; + } + spin_lock_irqsave(&info->lock,flags); + info->tx_active = false; + info->tx_count = info->tx_put = info->tx_get = 0; + + spin_unlock_irqrestore(&info->lock,flags); + +#if SYNCLINK_GENERIC_HDLC + if (info->netcount) + hdlcdev_tx_done(info); + else +#endif + bh_transmit(info); +} + +/* called to periodically check the DSR/RI modem signal input status + */ +static void status_timeout(unsigned long context) +{ + u16 status = 0; + SLMP_INFO *info = (SLMP_INFO*)context; + unsigned long flags; + unsigned char delta; + + + spin_lock_irqsave(&info->lock,flags); + get_signals(info); + spin_unlock_irqrestore(&info->lock,flags); + + /* check for DSR/RI state change */ + + delta = info->old_signals ^ info->serial_signals; + info->old_signals = info->serial_signals; + + if (delta & SerialSignal_DSR) + status |= MISCSTATUS_DSR_LATCHED|(info->serial_signals&SerialSignal_DSR); + + if (delta & SerialSignal_RI) + status |= MISCSTATUS_RI_LATCHED|(info->serial_signals&SerialSignal_RI); + + if (delta & SerialSignal_DCD) + status |= MISCSTATUS_DCD_LATCHED|(info->serial_signals&SerialSignal_DCD); + + if (delta & SerialSignal_CTS) + status |= MISCSTATUS_CTS_LATCHED|(info->serial_signals&SerialSignal_CTS); + + if (status) + isr_io_pin(info,status); + + mod_timer(&info->status_timer, jiffies + msecs_to_jiffies(10)); +} + + +/* Register Access Routines - + * All registers are memory mapped + */ +#define CALC_REGADDR() \ + unsigned char * RegAddr = (unsigned char*)(info->sca_base + Addr); \ + if (info->port_num > 1) \ + RegAddr += 256; /* port 0-1 SCA0, 2-3 SCA1 */ \ + if ( info->port_num & 1) { \ + if (Addr > 0x7f) \ + RegAddr += 0x40; /* DMA access */ \ + else if (Addr > 0x1f && Addr < 0x60) \ + RegAddr += 0x20; /* MSCI access */ \ + } + + +static unsigned char read_reg(SLMP_INFO * info, unsigned char Addr) +{ + CALC_REGADDR(); + return *RegAddr; +} +static void write_reg(SLMP_INFO * info, unsigned char Addr, unsigned char Value) +{ + CALC_REGADDR(); + *RegAddr = Value; +} + +static u16 read_reg16(SLMP_INFO * info, unsigned char Addr) +{ + CALC_REGADDR(); + return *((u16 *)RegAddr); +} + +static void write_reg16(SLMP_INFO * info, unsigned char Addr, u16 Value) +{ + CALC_REGADDR(); + *((u16 *)RegAddr) = Value; +} + +static unsigned char read_status_reg(SLMP_INFO * info) +{ + unsigned char *RegAddr = (unsigned char *)info->statctrl_base; + return *RegAddr; +} + +static void write_control_reg(SLMP_INFO * info) +{ + unsigned char *RegAddr = (unsigned char *)info->statctrl_base; + *RegAddr = info->port_array[0]->ctrlreg_value; +} + + +static int __devinit synclinkmp_init_one (struct pci_dev *dev, + const struct pci_device_id *ent) +{ + if (pci_enable_device(dev)) { + printk("error enabling pci device %p\n", dev); + return -EIO; + } + device_init( ++synclinkmp_adapter_count, dev ); + return 0; +} + +static void __devexit synclinkmp_remove_one (struct pci_dev *dev) +{ +} -- cgit v1.2.3 From 282361a046edd9d58a134f358a3f65a7cb8655d9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Feb 2011 16:23:22 -0800 Subject: tty: move ipwireless driver from drivers/char/pcmcia/ to drivers/tty/ As planned by Arnd Bergmann, this moves the ipwireless driver to the drivers/tty/ directory as that's where it really belongs. Cc: Arnd Bergmann Cc: Alan Cox Cc: Jiri Slaby Cc: David Sterba Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 2 +- drivers/char/pcmcia/ipwireless/Makefile | 10 - drivers/char/pcmcia/ipwireless/hardware.c | 1764 ----------------------- drivers/char/pcmcia/ipwireless/hardware.h | 62 - drivers/char/pcmcia/ipwireless/main.c | 335 ----- drivers/char/pcmcia/ipwireless/main.h | 68 - drivers/char/pcmcia/ipwireless/network.c | 508 ------- drivers/char/pcmcia/ipwireless/network.h | 53 - drivers/char/pcmcia/ipwireless/setup_protocol.h | 108 -- drivers/char/pcmcia/ipwireless/tty.c | 679 --------- drivers/char/pcmcia/ipwireless/tty.h | 45 - drivers/tty/Makefile | 2 + drivers/tty/ipwireless/Makefile | 10 + drivers/tty/ipwireless/hardware.c | 1764 +++++++++++++++++++++++ drivers/tty/ipwireless/hardware.h | 62 + drivers/tty/ipwireless/main.c | 335 +++++ drivers/tty/ipwireless/main.h | 68 + drivers/tty/ipwireless/network.c | 508 +++++++ drivers/tty/ipwireless/network.h | 53 + drivers/tty/ipwireless/setup_protocol.h | 108 ++ drivers/tty/ipwireless/tty.c | 679 +++++++++ drivers/tty/ipwireless/tty.h | 45 + 22 files changed, 3635 insertions(+), 3633 deletions(-) delete mode 100644 drivers/char/pcmcia/ipwireless/Makefile delete mode 100644 drivers/char/pcmcia/ipwireless/hardware.c delete mode 100644 drivers/char/pcmcia/ipwireless/hardware.h delete mode 100644 drivers/char/pcmcia/ipwireless/main.c delete mode 100644 drivers/char/pcmcia/ipwireless/main.h delete mode 100644 drivers/char/pcmcia/ipwireless/network.c delete mode 100644 drivers/char/pcmcia/ipwireless/network.h delete mode 100644 drivers/char/pcmcia/ipwireless/setup_protocol.h delete mode 100644 drivers/char/pcmcia/ipwireless/tty.c delete mode 100644 drivers/char/pcmcia/ipwireless/tty.h create mode 100644 drivers/tty/ipwireless/Makefile create mode 100644 drivers/tty/ipwireless/hardware.c create mode 100644 drivers/tty/ipwireless/hardware.h create mode 100644 drivers/tty/ipwireless/main.c create mode 100644 drivers/tty/ipwireless/main.h create mode 100644 drivers/tty/ipwireless/network.c create mode 100644 drivers/tty/ipwireless/network.h create mode 100644 drivers/tty/ipwireless/setup_protocol.h create mode 100644 drivers/tty/ipwireless/tty.c create mode 100644 drivers/tty/ipwireless/tty.h (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index 1eaeda66a525..e39337a1b958 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3423,7 +3423,7 @@ M: Jiri Kosina M: David Sterba S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/ipwireless_cs.git -F: drivers/char/pcmcia/ipwireless/ +F: drivers/tty/ipwireless/ IPX NETWORK LAYER M: Arnaldo Carvalho de Melo diff --git a/drivers/char/pcmcia/ipwireless/Makefile b/drivers/char/pcmcia/ipwireless/Makefile deleted file mode 100644 index db80873d7f20..000000000000 --- a/drivers/char/pcmcia/ipwireless/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# drivers/char/pcmcia/ipwireless/Makefile -# -# Makefile for the IPWireless driver -# - -obj-$(CONFIG_IPWIRELESS) += ipwireless.o - -ipwireless-y := hardware.o main.o network.o tty.o - diff --git a/drivers/char/pcmcia/ipwireless/hardware.c b/drivers/char/pcmcia/ipwireless/hardware.c deleted file mode 100644 index 0aeb5a38d296..000000000000 --- a/drivers/char/pcmcia/ipwireless/hardware.c +++ /dev/null @@ -1,1764 +0,0 @@ -/* - * IPWireless 3G PCMCIA Network Driver - * - * Original code - * by Stephen Blackheath , - * Ben Martel - * - * Copyrighted as follows: - * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) - * - * Various driver changes and rewrites, port to new kernels - * Copyright (C) 2006-2007 Jiri Kosina - * - * Misc code cleanups and updates - * Copyright (C) 2007 David Sterba - */ - -#include -#include -#include -#include -#include -#include - -#include "hardware.h" -#include "setup_protocol.h" -#include "network.h" -#include "main.h" - -static void ipw_send_setup_packet(struct ipw_hardware *hw); -static void handle_received_SETUP_packet(struct ipw_hardware *ipw, - unsigned int address, - const unsigned char *data, int len, - int is_last); -static void ipwireless_setup_timer(unsigned long data); -static void handle_received_CTRL_packet(struct ipw_hardware *hw, - unsigned int channel_idx, const unsigned char *data, int len); - -/*#define TIMING_DIAGNOSTICS*/ - -#ifdef TIMING_DIAGNOSTICS - -static struct timing_stats { - unsigned long last_report_time; - unsigned long read_time; - unsigned long write_time; - unsigned long read_bytes; - unsigned long write_bytes; - unsigned long start_time; -}; - -static void start_timing(void) -{ - timing_stats.start_time = jiffies; -} - -static void end_read_timing(unsigned length) -{ - timing_stats.read_time += (jiffies - start_time); - timing_stats.read_bytes += length + 2; - report_timing(); -} - -static void end_write_timing(unsigned length) -{ - timing_stats.write_time += (jiffies - start_time); - timing_stats.write_bytes += length + 2; - report_timing(); -} - -static void report_timing(void) -{ - unsigned long since = jiffies - timing_stats.last_report_time; - - /* If it's been more than one second... */ - if (since >= HZ) { - int first = (timing_stats.last_report_time == 0); - - timing_stats.last_report_time = jiffies; - if (!first) - printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": %u us elapsed - read %lu bytes in %u us, wrote %lu bytes in %u us\n", - jiffies_to_usecs(since), - timing_stats.read_bytes, - jiffies_to_usecs(timing_stats.read_time), - timing_stats.write_bytes, - jiffies_to_usecs(timing_stats.write_time)); - - timing_stats.read_time = 0; - timing_stats.write_time = 0; - timing_stats.read_bytes = 0; - timing_stats.write_bytes = 0; - } -} -#else -static void start_timing(void) { } -static void end_read_timing(unsigned length) { } -static void end_write_timing(unsigned length) { } -#endif - -/* Imported IPW definitions */ - -#define LL_MTU_V1 318 -#define LL_MTU_V2 250 -#define LL_MTU_MAX (LL_MTU_V1 > LL_MTU_V2 ? LL_MTU_V1 : LL_MTU_V2) - -#define PRIO_DATA 2 -#define PRIO_CTRL 1 -#define PRIO_SETUP 0 - -/* Addresses */ -#define ADDR_SETUP_PROT 0 - -/* Protocol ids */ -enum { - /* Identifier for the Com Data protocol */ - TL_PROTOCOLID_COM_DATA = 0, - - /* Identifier for the Com Control protocol */ - TL_PROTOCOLID_COM_CTRL = 1, - - /* Identifier for the Setup protocol */ - TL_PROTOCOLID_SETUP = 2 -}; - -/* Number of bytes in NL packet header (cannot do - * sizeof(nl_packet_header) since it's a bitfield) */ -#define NL_FIRST_PACKET_HEADER_SIZE 3 - -/* Number of bytes in NL packet header (cannot do - * sizeof(nl_packet_header) since it's a bitfield) */ -#define NL_FOLLOWING_PACKET_HEADER_SIZE 1 - -struct nl_first_packet_header { - unsigned char protocol:3; - unsigned char address:3; - unsigned char packet_rank:2; - unsigned char length_lsb; - unsigned char length_msb; -}; - -struct nl_packet_header { - unsigned char protocol:3; - unsigned char address:3; - unsigned char packet_rank:2; -}; - -/* Value of 'packet_rank' above */ -#define NL_INTERMEDIATE_PACKET 0x0 -#define NL_LAST_PACKET 0x1 -#define NL_FIRST_PACKET 0x2 - -union nl_packet { - /* Network packet header of the first packet (a special case) */ - struct nl_first_packet_header hdr_first; - /* Network packet header of the following packets (if any) */ - struct nl_packet_header hdr; - /* Complete network packet (header + data) */ - unsigned char rawpkt[LL_MTU_MAX]; -} __attribute__ ((__packed__)); - -#define HW_VERSION_UNKNOWN -1 -#define HW_VERSION_1 1 -#define HW_VERSION_2 2 - -/* IPW I/O ports */ -#define IOIER 0x00 /* Interrupt Enable Register */ -#define IOIR 0x02 /* Interrupt Source/ACK register */ -#define IODCR 0x04 /* Data Control Register */ -#define IODRR 0x06 /* Data Read Register */ -#define IODWR 0x08 /* Data Write Register */ -#define IOESR 0x0A /* Embedded Driver Status Register */ -#define IORXR 0x0C /* Rx Fifo Register (Host to Embedded) */ -#define IOTXR 0x0E /* Tx Fifo Register (Embedded to Host) */ - -/* I/O ports and bit definitions for version 1 of the hardware */ - -/* IER bits*/ -#define IER_RXENABLED 0x1 -#define IER_TXENABLED 0x2 - -/* ISR bits */ -#define IR_RXINTR 0x1 -#define IR_TXINTR 0x2 - -/* DCR bits */ -#define DCR_RXDONE 0x1 -#define DCR_TXDONE 0x2 -#define DCR_RXRESET 0x4 -#define DCR_TXRESET 0x8 - -/* I/O ports and bit definitions for version 2 of the hardware */ - -struct MEMCCR { - unsigned short reg_config_option; /* PCCOR: Configuration Option Register */ - unsigned short reg_config_and_status; /* PCCSR: Configuration and Status Register */ - unsigned short reg_pin_replacement; /* PCPRR: Pin Replacemant Register */ - unsigned short reg_socket_and_copy; /* PCSCR: Socket and Copy Register */ - unsigned short reg_ext_status; /* PCESR: Extendend Status Register */ - unsigned short reg_io_base; /* PCIOB: I/O Base Register */ -}; - -struct MEMINFREG { - unsigned short memreg_tx_old; /* TX Register (R/W) */ - unsigned short pad1; - unsigned short memreg_rx_done; /* RXDone Register (R/W) */ - unsigned short pad2; - unsigned short memreg_rx; /* RX Register (R/W) */ - unsigned short pad3; - unsigned short memreg_pc_interrupt_ack; /* PC intr Ack Register (W) */ - unsigned short pad4; - unsigned long memreg_card_present;/* Mask for Host to check (R) for - * CARD_PRESENT_VALUE */ - unsigned short memreg_tx_new; /* TX2 (new) Register (R/W) */ -}; - -#define CARD_PRESENT_VALUE (0xBEEFCAFEUL) - -#define MEMTX_TX 0x0001 -#define MEMRX_RX 0x0001 -#define MEMRX_RX_DONE 0x0001 -#define MEMRX_PCINTACKK 0x0001 - -#define NL_NUM_OF_PRIORITIES 3 -#define NL_NUM_OF_PROTOCOLS 3 -#define NL_NUM_OF_ADDRESSES NO_OF_IPW_CHANNELS - -struct ipw_hardware { - unsigned int base_port; - short hw_version; - unsigned short ll_mtu; - spinlock_t lock; - - int initializing; - int init_loops; - struct timer_list setup_timer; - - /* Flag if hw is ready to send next packet */ - int tx_ready; - /* Count of pending packets to be sent */ - int tx_queued; - struct list_head tx_queue[NL_NUM_OF_PRIORITIES]; - - int rx_bytes_queued; - struct list_head rx_queue; - /* Pool of rx_packet structures that are not currently used. */ - struct list_head rx_pool; - int rx_pool_size; - /* True if reception of data is blocked while userspace processes it. */ - int blocking_rx; - /* True if there is RX data ready on the hardware. */ - int rx_ready; - unsigned short last_memtx_serial; - /* - * Newer versions of the V2 card firmware send serial numbers in the - * MemTX register. 'serial_number_detected' is set true when we detect - * a non-zero serial number (indicating the new firmware). Thereafter, - * the driver can safely ignore the Timer Recovery re-sends to avoid - * out-of-sync problems. - */ - int serial_number_detected; - struct work_struct work_rx; - - /* True if we are to send the set-up data to the hardware. */ - int to_setup; - - /* Card has been removed */ - int removed; - /* Saved irq value when we disable the interrupt. */ - int irq; - /* True if this driver is shutting down. */ - int shutting_down; - /* Modem control lines */ - unsigned int control_lines[NL_NUM_OF_ADDRESSES]; - struct ipw_rx_packet *packet_assembler[NL_NUM_OF_ADDRESSES]; - - struct tasklet_struct tasklet; - - /* The handle for the network layer, for the sending of events to it. */ - struct ipw_network *network; - struct MEMINFREG __iomem *memory_info_regs; - struct MEMCCR __iomem *memregs_CCR; - void (*reboot_callback) (void *data); - void *reboot_callback_data; - - unsigned short __iomem *memreg_tx; -}; - -/* - * Packet info structure for tx packets. - * Note: not all the fields defined here are required for all protocols - */ -struct ipw_tx_packet { - struct list_head queue; - /* channel idx + 1 */ - unsigned char dest_addr; - /* SETUP, CTRL or DATA */ - unsigned char protocol; - /* Length of data block, which starts at the end of this structure */ - unsigned short length; - /* Sending state */ - /* Offset of where we've sent up to so far */ - unsigned long offset; - /* Count of packet fragments, starting at 0 */ - int fragment_count; - - /* Called after packet is sent and before is freed */ - void (*packet_callback) (void *cb_data, unsigned int packet_length); - void *callback_data; -}; - -/* Signals from DTE */ -#define COMCTRL_RTS 0 -#define COMCTRL_DTR 1 - -/* Signals from DCE */ -#define COMCTRL_CTS 2 -#define COMCTRL_DCD 3 -#define COMCTRL_DSR 4 -#define COMCTRL_RI 5 - -struct ipw_control_packet_body { - /* DTE signal or DCE signal */ - unsigned char sig_no; - /* 0: set signal, 1: clear signal */ - unsigned char value; -} __attribute__ ((__packed__)); - -struct ipw_control_packet { - struct ipw_tx_packet header; - struct ipw_control_packet_body body; -}; - -struct ipw_rx_packet { - struct list_head queue; - unsigned int capacity; - unsigned int length; - unsigned int protocol; - unsigned int channel_idx; -}; - -static char *data_type(const unsigned char *buf, unsigned length) -{ - struct nl_packet_header *hdr = (struct nl_packet_header *) buf; - - if (length == 0) - return " "; - - if (hdr->packet_rank & NL_FIRST_PACKET) { - switch (hdr->protocol) { - case TL_PROTOCOLID_COM_DATA: return "DATA "; - case TL_PROTOCOLID_COM_CTRL: return "CTRL "; - case TL_PROTOCOLID_SETUP: return "SETUP"; - default: return "???? "; - } - } else - return " "; -} - -#define DUMP_MAX_BYTES 64 - -static void dump_data_bytes(const char *type, const unsigned char *data, - unsigned length) -{ - char prefix[56]; - - sprintf(prefix, IPWIRELESS_PCCARD_NAME ": %s %s ", - type, data_type(data, length)); - print_hex_dump_bytes(prefix, 0, (void *)data, - length < DUMP_MAX_BYTES ? length : DUMP_MAX_BYTES); -} - -static void swap_packet_bitfield_to_le(unsigned char *data) -{ -#ifdef __BIG_ENDIAN_BITFIELD - unsigned char tmp = *data, ret = 0; - - /* - * transform bits from aa.bbb.ccc to ccc.bbb.aa - */ - ret |= tmp & 0xc0 >> 6; - ret |= tmp & 0x38 >> 1; - ret |= tmp & 0x07 << 5; - *data = ret & 0xff; -#endif -} - -static void swap_packet_bitfield_from_le(unsigned char *data) -{ -#ifdef __BIG_ENDIAN_BITFIELD - unsigned char tmp = *data, ret = 0; - - /* - * transform bits from ccc.bbb.aa to aa.bbb.ccc - */ - ret |= tmp & 0xe0 >> 5; - ret |= tmp & 0x1c << 1; - ret |= tmp & 0x03 << 6; - *data = ret & 0xff; -#endif -} - -static void do_send_fragment(struct ipw_hardware *hw, unsigned char *data, - unsigned length) -{ - unsigned i; - unsigned long flags; - - start_timing(); - BUG_ON(length > hw->ll_mtu); - - if (ipwireless_debug) - dump_data_bytes("send", data, length); - - spin_lock_irqsave(&hw->lock, flags); - - hw->tx_ready = 0; - swap_packet_bitfield_to_le(data); - - if (hw->hw_version == HW_VERSION_1) { - outw((unsigned short) length, hw->base_port + IODWR); - - for (i = 0; i < length; i += 2) { - unsigned short d = data[i]; - __le16 raw_data; - - if (i + 1 < length) - d |= data[i + 1] << 8; - raw_data = cpu_to_le16(d); - outw(raw_data, hw->base_port + IODWR); - } - - outw(DCR_TXDONE, hw->base_port + IODCR); - } else if (hw->hw_version == HW_VERSION_2) { - outw((unsigned short) length, hw->base_port); - - for (i = 0; i < length; i += 2) { - unsigned short d = data[i]; - __le16 raw_data; - - if (i + 1 < length) - d |= data[i + 1] << 8; - raw_data = cpu_to_le16(d); - outw(raw_data, hw->base_port); - } - while ((i & 3) != 2) { - outw((unsigned short) 0xDEAD, hw->base_port); - i += 2; - } - writew(MEMRX_RX, &hw->memory_info_regs->memreg_rx); - } - - spin_unlock_irqrestore(&hw->lock, flags); - - end_write_timing(length); -} - -static void do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet) -{ - unsigned short fragment_data_len; - unsigned short data_left = packet->length - packet->offset; - unsigned short header_size; - union nl_packet pkt; - - header_size = - (packet->fragment_count == 0) - ? NL_FIRST_PACKET_HEADER_SIZE - : NL_FOLLOWING_PACKET_HEADER_SIZE; - fragment_data_len = hw->ll_mtu - header_size; - if (data_left < fragment_data_len) - fragment_data_len = data_left; - - /* - * hdr_first is now in machine bitfield order, which will be swapped - * to le just before it goes to hw - */ - pkt.hdr_first.protocol = packet->protocol; - pkt.hdr_first.address = packet->dest_addr; - pkt.hdr_first.packet_rank = 0; - - /* First packet? */ - if (packet->fragment_count == 0) { - pkt.hdr_first.packet_rank |= NL_FIRST_PACKET; - pkt.hdr_first.length_lsb = (unsigned char) packet->length; - pkt.hdr_first.length_msb = - (unsigned char) (packet->length >> 8); - } - - memcpy(pkt.rawpkt + header_size, - ((unsigned char *) packet) + sizeof(struct ipw_tx_packet) + - packet->offset, fragment_data_len); - packet->offset += fragment_data_len; - packet->fragment_count++; - - /* Last packet? (May also be first packet.) */ - if (packet->offset == packet->length) - pkt.hdr_first.packet_rank |= NL_LAST_PACKET; - do_send_fragment(hw, pkt.rawpkt, header_size + fragment_data_len); - - /* If this packet has unsent data, then re-queue it. */ - if (packet->offset < packet->length) { - /* - * Re-queue it at the head of the highest priority queue so - * it goes before all other packets - */ - unsigned long flags; - - spin_lock_irqsave(&hw->lock, flags); - list_add(&packet->queue, &hw->tx_queue[0]); - hw->tx_queued++; - spin_unlock_irqrestore(&hw->lock, flags); - } else { - if (packet->packet_callback) - packet->packet_callback(packet->callback_data, - packet->length); - kfree(packet); - } -} - -static void ipw_setup_hardware(struct ipw_hardware *hw) -{ - unsigned long flags; - - spin_lock_irqsave(&hw->lock, flags); - if (hw->hw_version == HW_VERSION_1) { - /* Reset RX FIFO */ - outw(DCR_RXRESET, hw->base_port + IODCR); - /* SB: Reset TX FIFO */ - outw(DCR_TXRESET, hw->base_port + IODCR); - - /* Enable TX and RX interrupts. */ - outw(IER_TXENABLED | IER_RXENABLED, hw->base_port + IOIER); - } else { - /* - * Set INTRACK bit (bit 0), which means we must explicitly - * acknowledge interrupts by clearing bit 2 of reg_config_and_status. - */ - unsigned short csr = readw(&hw->memregs_CCR->reg_config_and_status); - - csr |= 1; - writew(csr, &hw->memregs_CCR->reg_config_and_status); - } - spin_unlock_irqrestore(&hw->lock, flags); -} - -/* - * If 'packet' is NULL, then this function allocates a new packet, setting its - * length to 0 and ensuring it has the specified minimum amount of free space. - * - * If 'packet' is not NULL, then this function enlarges it if it doesn't - * have the specified minimum amount of free space. - * - */ -static struct ipw_rx_packet *pool_allocate(struct ipw_hardware *hw, - struct ipw_rx_packet *packet, - int minimum_free_space) -{ - - if (!packet) { - unsigned long flags; - - spin_lock_irqsave(&hw->lock, flags); - if (!list_empty(&hw->rx_pool)) { - packet = list_first_entry(&hw->rx_pool, - struct ipw_rx_packet, queue); - hw->rx_pool_size--; - spin_unlock_irqrestore(&hw->lock, flags); - list_del(&packet->queue); - } else { - const int min_capacity = - ipwireless_ppp_mru(hw->network) + 2; - int new_capacity; - - spin_unlock_irqrestore(&hw->lock, flags); - new_capacity = - (minimum_free_space > min_capacity - ? minimum_free_space - : min_capacity); - packet = kmalloc(sizeof(struct ipw_rx_packet) - + new_capacity, GFP_ATOMIC); - if (!packet) - return NULL; - packet->capacity = new_capacity; - } - packet->length = 0; - } - - if (packet->length + minimum_free_space > packet->capacity) { - struct ipw_rx_packet *old_packet = packet; - - packet = kmalloc(sizeof(struct ipw_rx_packet) + - old_packet->length + minimum_free_space, - GFP_ATOMIC); - if (!packet) { - kfree(old_packet); - return NULL; - } - memcpy(packet, old_packet, - sizeof(struct ipw_rx_packet) - + old_packet->length); - packet->capacity = old_packet->length + minimum_free_space; - kfree(old_packet); - } - - return packet; -} - -static void pool_free(struct ipw_hardware *hw, struct ipw_rx_packet *packet) -{ - if (hw->rx_pool_size > 6) - kfree(packet); - else { - hw->rx_pool_size++; - list_add(&packet->queue, &hw->rx_pool); - } -} - -static void queue_received_packet(struct ipw_hardware *hw, - unsigned int protocol, - unsigned int address, - const unsigned char *data, int length, - int is_last) -{ - unsigned int channel_idx = address - 1; - struct ipw_rx_packet *packet = NULL; - unsigned long flags; - - /* Discard packet if channel index is out of range. */ - if (channel_idx >= NL_NUM_OF_ADDRESSES) { - printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": data packet has bad address %u\n", address); - return; - } - - /* - * ->packet_assembler is safe to touch unlocked, this is the only place - */ - if (protocol == TL_PROTOCOLID_COM_DATA) { - struct ipw_rx_packet **assem = - &hw->packet_assembler[channel_idx]; - - /* - * Create a new packet, or assembler already contains one - * enlarge it by 'length' bytes. - */ - (*assem) = pool_allocate(hw, *assem, length); - if (!(*assem)) { - printk(KERN_ERR IPWIRELESS_PCCARD_NAME - ": no memory for incomming data packet, dropped!\n"); - return; - } - (*assem)->protocol = protocol; - (*assem)->channel_idx = channel_idx; - - /* Append this packet data onto existing data. */ - memcpy((unsigned char *)(*assem) + - sizeof(struct ipw_rx_packet) - + (*assem)->length, data, length); - (*assem)->length += length; - if (is_last) { - packet = *assem; - *assem = NULL; - /* Count queued DATA bytes only */ - spin_lock_irqsave(&hw->lock, flags); - hw->rx_bytes_queued += packet->length; - spin_unlock_irqrestore(&hw->lock, flags); - } - } else { - /* If it's a CTRL packet, don't assemble, just queue it. */ - packet = pool_allocate(hw, NULL, length); - if (!packet) { - printk(KERN_ERR IPWIRELESS_PCCARD_NAME - ": no memory for incomming ctrl packet, dropped!\n"); - return; - } - packet->protocol = protocol; - packet->channel_idx = channel_idx; - memcpy((unsigned char *)packet + sizeof(struct ipw_rx_packet), - data, length); - packet->length = length; - } - - /* - * If this is the last packet, then send the assembled packet on to the - * network layer. - */ - if (packet) { - spin_lock_irqsave(&hw->lock, flags); - list_add_tail(&packet->queue, &hw->rx_queue); - /* Block reception of incoming packets if queue is full. */ - hw->blocking_rx = - (hw->rx_bytes_queued >= IPWIRELESS_RX_QUEUE_SIZE); - - spin_unlock_irqrestore(&hw->lock, flags); - schedule_work(&hw->work_rx); - } -} - -/* - * Workqueue callback - */ -static void ipw_receive_data_work(struct work_struct *work_rx) -{ - struct ipw_hardware *hw = - container_of(work_rx, struct ipw_hardware, work_rx); - unsigned long flags; - - spin_lock_irqsave(&hw->lock, flags); - while (!list_empty(&hw->rx_queue)) { - struct ipw_rx_packet *packet = - list_first_entry(&hw->rx_queue, - struct ipw_rx_packet, queue); - - if (hw->shutting_down) - break; - list_del(&packet->queue); - - /* - * Note: ipwireless_network_packet_received must be called in a - * process context (i.e. via schedule_work) because the tty - * output code can sleep in the tty_flip_buffer_push call. - */ - if (packet->protocol == TL_PROTOCOLID_COM_DATA) { - if (hw->network != NULL) { - /* If the network hasn't been disconnected. */ - spin_unlock_irqrestore(&hw->lock, flags); - /* - * This must run unlocked due to tty processing - * and mutex locking - */ - ipwireless_network_packet_received( - hw->network, - packet->channel_idx, - (unsigned char *)packet - + sizeof(struct ipw_rx_packet), - packet->length); - spin_lock_irqsave(&hw->lock, flags); - } - /* Count queued DATA bytes only */ - hw->rx_bytes_queued -= packet->length; - } else { - /* - * This is safe to be called locked, callchain does - * not block - */ - handle_received_CTRL_packet(hw, packet->channel_idx, - (unsigned char *)packet - + sizeof(struct ipw_rx_packet), - packet->length); - } - pool_free(hw, packet); - /* - * Unblock reception of incoming packets if queue is no longer - * full. - */ - hw->blocking_rx = - hw->rx_bytes_queued >= IPWIRELESS_RX_QUEUE_SIZE; - if (hw->shutting_down) - break; - } - spin_unlock_irqrestore(&hw->lock, flags); -} - -static void handle_received_CTRL_packet(struct ipw_hardware *hw, - unsigned int channel_idx, - const unsigned char *data, int len) -{ - const struct ipw_control_packet_body *body = - (const struct ipw_control_packet_body *) data; - unsigned int changed_mask; - - if (len != sizeof(struct ipw_control_packet_body)) { - printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": control packet was %d bytes - wrong size!\n", - len); - return; - } - - switch (body->sig_no) { - case COMCTRL_CTS: - changed_mask = IPW_CONTROL_LINE_CTS; - break; - case COMCTRL_DCD: - changed_mask = IPW_CONTROL_LINE_DCD; - break; - case COMCTRL_DSR: - changed_mask = IPW_CONTROL_LINE_DSR; - break; - case COMCTRL_RI: - changed_mask = IPW_CONTROL_LINE_RI; - break; - default: - changed_mask = 0; - } - - if (changed_mask != 0) { - if (body->value) - hw->control_lines[channel_idx] |= changed_mask; - else - hw->control_lines[channel_idx] &= ~changed_mask; - if (hw->network) - ipwireless_network_notify_control_line_change( - hw->network, - channel_idx, - hw->control_lines[channel_idx], - changed_mask); - } -} - -static void handle_received_packet(struct ipw_hardware *hw, - const union nl_packet *packet, - unsigned short len) -{ - unsigned int protocol = packet->hdr.protocol; - unsigned int address = packet->hdr.address; - unsigned int header_length; - const unsigned char *data; - unsigned int data_len; - int is_last = packet->hdr.packet_rank & NL_LAST_PACKET; - - if (packet->hdr.packet_rank & NL_FIRST_PACKET) - header_length = NL_FIRST_PACKET_HEADER_SIZE; - else - header_length = NL_FOLLOWING_PACKET_HEADER_SIZE; - - data = packet->rawpkt + header_length; - data_len = len - header_length; - switch (protocol) { - case TL_PROTOCOLID_COM_DATA: - case TL_PROTOCOLID_COM_CTRL: - queue_received_packet(hw, protocol, address, data, data_len, - is_last); - break; - case TL_PROTOCOLID_SETUP: - handle_received_SETUP_packet(hw, address, data, data_len, - is_last); - break; - } -} - -static void acknowledge_data_read(struct ipw_hardware *hw) -{ - if (hw->hw_version == HW_VERSION_1) - outw(DCR_RXDONE, hw->base_port + IODCR); - else - writew(MEMRX_PCINTACKK, - &hw->memory_info_regs->memreg_pc_interrupt_ack); -} - -/* - * Retrieve a packet from the IPW hardware. - */ -static void do_receive_packet(struct ipw_hardware *hw) -{ - unsigned len; - unsigned i; - unsigned char pkt[LL_MTU_MAX]; - - start_timing(); - - if (hw->hw_version == HW_VERSION_1) { - len = inw(hw->base_port + IODRR); - if (len > hw->ll_mtu) { - printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": received a packet of %u bytes - longer than the MTU!\n", len); - outw(DCR_RXDONE | DCR_RXRESET, hw->base_port + IODCR); - return; - } - - for (i = 0; i < len; i += 2) { - __le16 raw_data = inw(hw->base_port + IODRR); - unsigned short data = le16_to_cpu(raw_data); - - pkt[i] = (unsigned char) data; - pkt[i + 1] = (unsigned char) (data >> 8); - } - } else { - len = inw(hw->base_port); - if (len > hw->ll_mtu) { - printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": received a packet of %u bytes - longer than the MTU!\n", len); - writew(MEMRX_PCINTACKK, - &hw->memory_info_regs->memreg_pc_interrupt_ack); - return; - } - - for (i = 0; i < len; i += 2) { - __le16 raw_data = inw(hw->base_port); - unsigned short data = le16_to_cpu(raw_data); - - pkt[i] = (unsigned char) data; - pkt[i + 1] = (unsigned char) (data >> 8); - } - - while ((i & 3) != 2) { - inw(hw->base_port); - i += 2; - } - } - - acknowledge_data_read(hw); - - swap_packet_bitfield_from_le(pkt); - - if (ipwireless_debug) - dump_data_bytes("recv", pkt, len); - - handle_received_packet(hw, (union nl_packet *) pkt, len); - - end_read_timing(len); -} - -static int get_current_packet_priority(struct ipw_hardware *hw) -{ - /* - * If we're initializing, don't send anything of higher priority than - * PRIO_SETUP. The network layer therefore need not care about - * hardware initialization - any of its stuff will simply be queued - * until setup is complete. - */ - return (hw->to_setup || hw->initializing - ? PRIO_SETUP + 1 : NL_NUM_OF_PRIORITIES); -} - -/* - * return 1 if something has been received from hw - */ -static int get_packets_from_hw(struct ipw_hardware *hw) -{ - int received = 0; - unsigned long flags; - - spin_lock_irqsave(&hw->lock, flags); - while (hw->rx_ready && !hw->blocking_rx) { - received = 1; - hw->rx_ready--; - spin_unlock_irqrestore(&hw->lock, flags); - - do_receive_packet(hw); - - spin_lock_irqsave(&hw->lock, flags); - } - spin_unlock_irqrestore(&hw->lock, flags); - - return received; -} - -/* - * Send pending packet up to given priority, prioritize SETUP data until - * hardware is fully setup. - * - * return 1 if more packets can be sent - */ -static int send_pending_packet(struct ipw_hardware *hw, int priority_limit) -{ - int more_to_send = 0; - unsigned long flags; - - spin_lock_irqsave(&hw->lock, flags); - if (hw->tx_queued && hw->tx_ready) { - int priority; - struct ipw_tx_packet *packet = NULL; - - /* Pick a packet */ - for (priority = 0; priority < priority_limit; priority++) { - if (!list_empty(&hw->tx_queue[priority])) { - packet = list_first_entry( - &hw->tx_queue[priority], - struct ipw_tx_packet, - queue); - - hw->tx_queued--; - list_del(&packet->queue); - - break; - } - } - if (!packet) { - hw->tx_queued = 0; - spin_unlock_irqrestore(&hw->lock, flags); - return 0; - } - - spin_unlock_irqrestore(&hw->lock, flags); - - /* Send */ - do_send_packet(hw, packet); - - /* Check if more to send */ - spin_lock_irqsave(&hw->lock, flags); - for (priority = 0; priority < priority_limit; priority++) - if (!list_empty(&hw->tx_queue[priority])) { - more_to_send = 1; - break; - } - - if (!more_to_send) - hw->tx_queued = 0; - } - spin_unlock_irqrestore(&hw->lock, flags); - - return more_to_send; -} - -/* - * Send and receive all queued packets. - */ -static void ipwireless_do_tasklet(unsigned long hw_) -{ - struct ipw_hardware *hw = (struct ipw_hardware *) hw_; - unsigned long flags; - - spin_lock_irqsave(&hw->lock, flags); - if (hw->shutting_down) { - spin_unlock_irqrestore(&hw->lock, flags); - return; - } - - if (hw->to_setup == 1) { - /* - * Initial setup data sent to hardware - */ - hw->to_setup = 2; - spin_unlock_irqrestore(&hw->lock, flags); - - ipw_setup_hardware(hw); - ipw_send_setup_packet(hw); - - send_pending_packet(hw, PRIO_SETUP + 1); - get_packets_from_hw(hw); - } else { - int priority_limit = get_current_packet_priority(hw); - int again; - - spin_unlock_irqrestore(&hw->lock, flags); - - do { - again = send_pending_packet(hw, priority_limit); - again |= get_packets_from_hw(hw); - } while (again); - } -} - -/* - * return true if the card is physically present. - */ -static int is_card_present(struct ipw_hardware *hw) -{ - if (hw->hw_version == HW_VERSION_1) - return inw(hw->base_port + IOIR) != 0xFFFF; - else - return readl(&hw->memory_info_regs->memreg_card_present) == - CARD_PRESENT_VALUE; -} - -static irqreturn_t ipwireless_handle_v1_interrupt(int irq, - struct ipw_hardware *hw) -{ - unsigned short irqn; - - irqn = inw(hw->base_port + IOIR); - - /* Check if card is present */ - if (irqn == 0xFFFF) - return IRQ_NONE; - else if (irqn != 0) { - unsigned short ack = 0; - unsigned long flags; - - /* Transmit complete. */ - if (irqn & IR_TXINTR) { - ack |= IR_TXINTR; - spin_lock_irqsave(&hw->lock, flags); - hw->tx_ready = 1; - spin_unlock_irqrestore(&hw->lock, flags); - } - /* Received data */ - if (irqn & IR_RXINTR) { - ack |= IR_RXINTR; - spin_lock_irqsave(&hw->lock, flags); - hw->rx_ready++; - spin_unlock_irqrestore(&hw->lock, flags); - } - if (ack != 0) { - outw(ack, hw->base_port + IOIR); - tasklet_schedule(&hw->tasklet); - } - return IRQ_HANDLED; - } - return IRQ_NONE; -} - -static void acknowledge_pcmcia_interrupt(struct ipw_hardware *hw) -{ - unsigned short csr = readw(&hw->memregs_CCR->reg_config_and_status); - - csr &= 0xfffd; - writew(csr, &hw->memregs_CCR->reg_config_and_status); -} - -static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq, - struct ipw_hardware *hw) -{ - int tx = 0; - int rx = 0; - int rx_repeat = 0; - int try_mem_tx_old; - unsigned long flags; - - do { - - unsigned short memtx = readw(hw->memreg_tx); - unsigned short memtx_serial; - unsigned short memrxdone = - readw(&hw->memory_info_regs->memreg_rx_done); - - try_mem_tx_old = 0; - - /* check whether the interrupt was generated by ipwireless card */ - if (!(memtx & MEMTX_TX) && !(memrxdone & MEMRX_RX_DONE)) { - - /* check if the card uses memreg_tx_old register */ - if (hw->memreg_tx == &hw->memory_info_regs->memreg_tx_new) { - memtx = readw(&hw->memory_info_regs->memreg_tx_old); - if (memtx & MEMTX_TX) { - printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": Using memreg_tx_old\n"); - hw->memreg_tx = - &hw->memory_info_regs->memreg_tx_old; - } else { - return IRQ_NONE; - } - } else - return IRQ_NONE; - } - - /* - * See if the card is physically present. Note that while it is - * powering up, it appears not to be present. - */ - if (!is_card_present(hw)) { - acknowledge_pcmcia_interrupt(hw); - return IRQ_HANDLED; - } - - memtx_serial = memtx & (unsigned short) 0xff00; - if (memtx & MEMTX_TX) { - writew(memtx_serial, hw->memreg_tx); - - if (hw->serial_number_detected) { - if (memtx_serial != hw->last_memtx_serial) { - hw->last_memtx_serial = memtx_serial; - spin_lock_irqsave(&hw->lock, flags); - hw->rx_ready++; - spin_unlock_irqrestore(&hw->lock, flags); - rx = 1; - } else - /* Ignore 'Timer Recovery' duplicates. */ - rx_repeat = 1; - } else { - /* - * If a non-zero serial number is seen, then enable - * serial number checking. - */ - if (memtx_serial != 0) { - hw->serial_number_detected = 1; - printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME - ": memreg_tx serial num detected\n"); - - spin_lock_irqsave(&hw->lock, flags); - hw->rx_ready++; - spin_unlock_irqrestore(&hw->lock, flags); - } - rx = 1; - } - } - if (memrxdone & MEMRX_RX_DONE) { - writew(0, &hw->memory_info_regs->memreg_rx_done); - spin_lock_irqsave(&hw->lock, flags); - hw->tx_ready = 1; - spin_unlock_irqrestore(&hw->lock, flags); - tx = 1; - } - if (tx) - writew(MEMRX_PCINTACKK, - &hw->memory_info_regs->memreg_pc_interrupt_ack); - - acknowledge_pcmcia_interrupt(hw); - - if (tx || rx) - tasklet_schedule(&hw->tasklet); - else if (!rx_repeat) { - if (hw->memreg_tx == &hw->memory_info_regs->memreg_tx_new) { - if (hw->serial_number_detected) - printk(KERN_WARNING IPWIRELESS_PCCARD_NAME - ": spurious interrupt - new_tx mode\n"); - else { - printk(KERN_WARNING IPWIRELESS_PCCARD_NAME - ": no valid memreg_tx value - switching to the old memreg_tx\n"); - hw->memreg_tx = - &hw->memory_info_regs->memreg_tx_old; - try_mem_tx_old = 1; - } - } else - printk(KERN_WARNING IPWIRELESS_PCCARD_NAME - ": spurious interrupt - old_tx mode\n"); - } - - } while (try_mem_tx_old == 1); - - return IRQ_HANDLED; -} - -irqreturn_t ipwireless_interrupt(int irq, void *dev_id) -{ - struct ipw_dev *ipw = dev_id; - - if (ipw->hardware->hw_version == HW_VERSION_1) - return ipwireless_handle_v1_interrupt(irq, ipw->hardware); - else - return ipwireless_handle_v2_v3_interrupt(irq, ipw->hardware); -} - -static void flush_packets_to_hw(struct ipw_hardware *hw) -{ - int priority_limit; - unsigned long flags; - - spin_lock_irqsave(&hw->lock, flags); - priority_limit = get_current_packet_priority(hw); - spin_unlock_irqrestore(&hw->lock, flags); - - while (send_pending_packet(hw, priority_limit)); -} - -static void send_packet(struct ipw_hardware *hw, int priority, - struct ipw_tx_packet *packet) -{ - unsigned long flags; - - spin_lock_irqsave(&hw->lock, flags); - list_add_tail(&packet->queue, &hw->tx_queue[priority]); - hw->tx_queued++; - spin_unlock_irqrestore(&hw->lock, flags); - - flush_packets_to_hw(hw); -} - -/* Create data packet, non-atomic allocation */ -static void *alloc_data_packet(int data_size, - unsigned char dest_addr, - unsigned char protocol) -{ - struct ipw_tx_packet *packet = kzalloc( - sizeof(struct ipw_tx_packet) + data_size, - GFP_ATOMIC); - - if (!packet) - return NULL; - - INIT_LIST_HEAD(&packet->queue); - packet->dest_addr = dest_addr; - packet->protocol = protocol; - packet->length = data_size; - - return packet; -} - -static void *alloc_ctrl_packet(int header_size, - unsigned char dest_addr, - unsigned char protocol, - unsigned char sig_no) -{ - /* - * sig_no is located right after ipw_tx_packet struct in every - * CTRL or SETUP packets, we can use ipw_control_packet as a - * common struct - */ - struct ipw_control_packet *packet = kzalloc(header_size, GFP_ATOMIC); - - if (!packet) - return NULL; - - INIT_LIST_HEAD(&packet->header.queue); - packet->header.dest_addr = dest_addr; - packet->header.protocol = protocol; - packet->header.length = header_size - sizeof(struct ipw_tx_packet); - packet->body.sig_no = sig_no; - - return packet; -} - -int ipwireless_send_packet(struct ipw_hardware *hw, unsigned int channel_idx, - const unsigned char *data, unsigned int length, - void (*callback) (void *cb, unsigned int length), - void *callback_data) -{ - struct ipw_tx_packet *packet; - - packet = alloc_data_packet(length, (channel_idx + 1), - TL_PROTOCOLID_COM_DATA); - if (!packet) - return -ENOMEM; - packet->packet_callback = callback; - packet->callback_data = callback_data; - memcpy((unsigned char *) packet + sizeof(struct ipw_tx_packet), data, - length); - - send_packet(hw, PRIO_DATA, packet); - return 0; -} - -static int set_control_line(struct ipw_hardware *hw, int prio, - unsigned int channel_idx, int line, int state) -{ - struct ipw_control_packet *packet; - int protocolid = TL_PROTOCOLID_COM_CTRL; - - if (prio == PRIO_SETUP) - protocolid = TL_PROTOCOLID_SETUP; - - packet = alloc_ctrl_packet(sizeof(struct ipw_control_packet), - (channel_idx + 1), protocolid, line); - if (!packet) - return -ENOMEM; - packet->header.length = sizeof(struct ipw_control_packet_body); - packet->body.value = (state == 0 ? 0 : 1); - send_packet(hw, prio, &packet->header); - return 0; -} - - -static int set_DTR(struct ipw_hardware *hw, int priority, - unsigned int channel_idx, int state) -{ - if (state != 0) - hw->control_lines[channel_idx] |= IPW_CONTROL_LINE_DTR; - else - hw->control_lines[channel_idx] &= ~IPW_CONTROL_LINE_DTR; - - return set_control_line(hw, priority, channel_idx, COMCTRL_DTR, state); -} - -static int set_RTS(struct ipw_hardware *hw, int priority, - unsigned int channel_idx, int state) -{ - if (state != 0) - hw->control_lines[channel_idx] |= IPW_CONTROL_LINE_RTS; - else - hw->control_lines[channel_idx] &= ~IPW_CONTROL_LINE_RTS; - - return set_control_line(hw, priority, channel_idx, COMCTRL_RTS, state); -} - -int ipwireless_set_DTR(struct ipw_hardware *hw, unsigned int channel_idx, - int state) -{ - return set_DTR(hw, PRIO_CTRL, channel_idx, state); -} - -int ipwireless_set_RTS(struct ipw_hardware *hw, unsigned int channel_idx, - int state) -{ - return set_RTS(hw, PRIO_CTRL, channel_idx, state); -} - -struct ipw_setup_get_version_query_packet { - struct ipw_tx_packet header; - struct tl_setup_get_version_qry body; -}; - -struct ipw_setup_config_packet { - struct ipw_tx_packet header; - struct tl_setup_config_msg body; -}; - -struct ipw_setup_config_done_packet { - struct ipw_tx_packet header; - struct tl_setup_config_done_msg body; -}; - -struct ipw_setup_open_packet { - struct ipw_tx_packet header; - struct tl_setup_open_msg body; -}; - -struct ipw_setup_info_packet { - struct ipw_tx_packet header; - struct tl_setup_info_msg body; -}; - -struct ipw_setup_reboot_msg_ack { - struct ipw_tx_packet header; - struct TlSetupRebootMsgAck body; -}; - -/* This handles the actual initialization of the card */ -static void __handle_setup_get_version_rsp(struct ipw_hardware *hw) -{ - struct ipw_setup_config_packet *config_packet; - struct ipw_setup_config_done_packet *config_done_packet; - struct ipw_setup_open_packet *open_packet; - struct ipw_setup_info_packet *info_packet; - int port; - unsigned int channel_idx; - - /* generate config packet */ - for (port = 1; port <= NL_NUM_OF_ADDRESSES; port++) { - config_packet = alloc_ctrl_packet( - sizeof(struct ipw_setup_config_packet), - ADDR_SETUP_PROT, - TL_PROTOCOLID_SETUP, - TL_SETUP_SIGNO_CONFIG_MSG); - if (!config_packet) - goto exit_nomem; - config_packet->header.length = sizeof(struct tl_setup_config_msg); - config_packet->body.port_no = port; - config_packet->body.prio_data = PRIO_DATA; - config_packet->body.prio_ctrl = PRIO_CTRL; - send_packet(hw, PRIO_SETUP, &config_packet->header); - } - config_done_packet = alloc_ctrl_packet( - sizeof(struct ipw_setup_config_done_packet), - ADDR_SETUP_PROT, - TL_PROTOCOLID_SETUP, - TL_SETUP_SIGNO_CONFIG_DONE_MSG); - if (!config_done_packet) - goto exit_nomem; - config_done_packet->header.length = sizeof(struct tl_setup_config_done_msg); - send_packet(hw, PRIO_SETUP, &config_done_packet->header); - - /* generate open packet */ - for (port = 1; port <= NL_NUM_OF_ADDRESSES; port++) { - open_packet = alloc_ctrl_packet( - sizeof(struct ipw_setup_open_packet), - ADDR_SETUP_PROT, - TL_PROTOCOLID_SETUP, - TL_SETUP_SIGNO_OPEN_MSG); - if (!open_packet) - goto exit_nomem; - open_packet->header.length = sizeof(struct tl_setup_open_msg); - open_packet->body.port_no = port; - send_packet(hw, PRIO_SETUP, &open_packet->header); - } - for (channel_idx = 0; - channel_idx < NL_NUM_OF_ADDRESSES; channel_idx++) { - int ret; - - ret = set_DTR(hw, PRIO_SETUP, channel_idx, - (hw->control_lines[channel_idx] & - IPW_CONTROL_LINE_DTR) != 0); - if (ret) { - printk(KERN_ERR IPWIRELESS_PCCARD_NAME - ": error setting DTR (%d)\n", ret); - return; - } - - set_RTS(hw, PRIO_SETUP, channel_idx, - (hw->control_lines [channel_idx] & - IPW_CONTROL_LINE_RTS) != 0); - if (ret) { - printk(KERN_ERR IPWIRELESS_PCCARD_NAME - ": error setting RTS (%d)\n", ret); - return; - } - } - /* - * For NDIS we assume that we are using sync PPP frames, for COM async. - * This driver uses NDIS mode too. We don't bother with translation - * from async -> sync PPP. - */ - info_packet = alloc_ctrl_packet(sizeof(struct ipw_setup_info_packet), - ADDR_SETUP_PROT, - TL_PROTOCOLID_SETUP, - TL_SETUP_SIGNO_INFO_MSG); - if (!info_packet) - goto exit_nomem; - info_packet->header.length = sizeof(struct tl_setup_info_msg); - info_packet->body.driver_type = NDISWAN_DRIVER; - info_packet->body.major_version = NDISWAN_DRIVER_MAJOR_VERSION; - info_packet->body.minor_version = NDISWAN_DRIVER_MINOR_VERSION; - send_packet(hw, PRIO_SETUP, &info_packet->header); - - /* Initialization is now complete, so we clear the 'to_setup' flag */ - hw->to_setup = 0; - - return; - -exit_nomem: - printk(KERN_ERR IPWIRELESS_PCCARD_NAME - ": not enough memory to alloc control packet\n"); - hw->to_setup = -1; -} - -static void handle_setup_get_version_rsp(struct ipw_hardware *hw, - unsigned char vers_no) -{ - del_timer(&hw->setup_timer); - hw->initializing = 0; - printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": card is ready.\n"); - - if (vers_no == TL_SETUP_VERSION) - __handle_setup_get_version_rsp(hw); - else - printk(KERN_ERR IPWIRELESS_PCCARD_NAME - ": invalid hardware version no %u\n", - (unsigned int) vers_no); -} - -static void ipw_send_setup_packet(struct ipw_hardware *hw) -{ - struct ipw_setup_get_version_query_packet *ver_packet; - - ver_packet = alloc_ctrl_packet( - sizeof(struct ipw_setup_get_version_query_packet), - ADDR_SETUP_PROT, TL_PROTOCOLID_SETUP, - TL_SETUP_SIGNO_GET_VERSION_QRY); - ver_packet->header.length = sizeof(struct tl_setup_get_version_qry); - - /* - * Response is handled in handle_received_SETUP_packet - */ - send_packet(hw, PRIO_SETUP, &ver_packet->header); -} - -static void handle_received_SETUP_packet(struct ipw_hardware *hw, - unsigned int address, - const unsigned char *data, int len, - int is_last) -{ - const union ipw_setup_rx_msg *rx_msg = (const union ipw_setup_rx_msg *) data; - - if (address != ADDR_SETUP_PROT) { - printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": setup packet has bad address %d\n", address); - return; - } - - switch (rx_msg->sig_no) { - case TL_SETUP_SIGNO_GET_VERSION_RSP: - if (hw->to_setup) - handle_setup_get_version_rsp(hw, - rx_msg->version_rsp_msg.version); - break; - - case TL_SETUP_SIGNO_OPEN_MSG: - if (ipwireless_debug) { - unsigned int channel_idx = rx_msg->open_msg.port_no - 1; - - printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": OPEN_MSG [channel %u] reply received\n", - channel_idx); - } - break; - - case TL_SETUP_SIGNO_INFO_MSG_ACK: - if (ipwireless_debug) - printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME - ": card successfully configured as NDISWAN\n"); - break; - - case TL_SETUP_SIGNO_REBOOT_MSG: - if (hw->to_setup) - printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME - ": Setup not completed - ignoring reboot msg\n"); - else { - struct ipw_setup_reboot_msg_ack *packet; - - printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME - ": Acknowledging REBOOT message\n"); - packet = alloc_ctrl_packet( - sizeof(struct ipw_setup_reboot_msg_ack), - ADDR_SETUP_PROT, TL_PROTOCOLID_SETUP, - TL_SETUP_SIGNO_REBOOT_MSG_ACK); - packet->header.length = - sizeof(struct TlSetupRebootMsgAck); - send_packet(hw, PRIO_SETUP, &packet->header); - if (hw->reboot_callback) - hw->reboot_callback(hw->reboot_callback_data); - } - break; - - default: - printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": unknown setup message %u received\n", - (unsigned int) rx_msg->sig_no); - } -} - -static void do_close_hardware(struct ipw_hardware *hw) -{ - unsigned int irqn; - - if (hw->hw_version == HW_VERSION_1) { - /* Disable TX and RX interrupts. */ - outw(0, hw->base_port + IOIER); - - /* Acknowledge any outstanding interrupt requests */ - irqn = inw(hw->base_port + IOIR); - if (irqn & IR_TXINTR) - outw(IR_TXINTR, hw->base_port + IOIR); - if (irqn & IR_RXINTR) - outw(IR_RXINTR, hw->base_port + IOIR); - - synchronize_irq(hw->irq); - } -} - -struct ipw_hardware *ipwireless_hardware_create(void) -{ - int i; - struct ipw_hardware *hw = - kzalloc(sizeof(struct ipw_hardware), GFP_KERNEL); - - if (!hw) - return NULL; - - hw->irq = -1; - hw->initializing = 1; - hw->tx_ready = 1; - hw->rx_bytes_queued = 0; - hw->rx_pool_size = 0; - hw->last_memtx_serial = (unsigned short) 0xffff; - for (i = 0; i < NL_NUM_OF_PRIORITIES; i++) - INIT_LIST_HEAD(&hw->tx_queue[i]); - - INIT_LIST_HEAD(&hw->rx_queue); - INIT_LIST_HEAD(&hw->rx_pool); - spin_lock_init(&hw->lock); - tasklet_init(&hw->tasklet, ipwireless_do_tasklet, (unsigned long) hw); - INIT_WORK(&hw->work_rx, ipw_receive_data_work); - setup_timer(&hw->setup_timer, ipwireless_setup_timer, - (unsigned long) hw); - - return hw; -} - -void ipwireless_init_hardware_v1(struct ipw_hardware *hw, - unsigned int base_port, - void __iomem *attr_memory, - void __iomem *common_memory, - int is_v2_card, - void (*reboot_callback) (void *data), - void *reboot_callback_data) -{ - if (hw->removed) { - hw->removed = 0; - enable_irq(hw->irq); - } - hw->base_port = base_port; - hw->hw_version = (is_v2_card ? HW_VERSION_2 : HW_VERSION_1); - hw->ll_mtu = (hw->hw_version == HW_VERSION_1 ? LL_MTU_V1 : LL_MTU_V2); - hw->memregs_CCR = (struct MEMCCR __iomem *) - ((unsigned short __iomem *) attr_memory + 0x200); - hw->memory_info_regs = (struct MEMINFREG __iomem *) common_memory; - hw->memreg_tx = &hw->memory_info_regs->memreg_tx_new; - hw->reboot_callback = reboot_callback; - hw->reboot_callback_data = reboot_callback_data; -} - -void ipwireless_init_hardware_v2_v3(struct ipw_hardware *hw) -{ - hw->initializing = 1; - hw->init_loops = 0; - printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": waiting for card to start up...\n"); - ipwireless_setup_timer((unsigned long) hw); -} - -static void ipwireless_setup_timer(unsigned long data) -{ - struct ipw_hardware *hw = (struct ipw_hardware *) data; - - hw->init_loops++; - - if (hw->init_loops == TL_SETUP_MAX_VERSION_QRY && - hw->hw_version == HW_VERSION_2 && - hw->memreg_tx == &hw->memory_info_regs->memreg_tx_new) { - printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": failed to startup using TX2, trying TX\n"); - - hw->memreg_tx = &hw->memory_info_regs->memreg_tx_old; - hw->init_loops = 0; - } - /* Give up after a certain number of retries */ - if (hw->init_loops == TL_SETUP_MAX_VERSION_QRY) { - printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": card failed to start up!\n"); - hw->initializing = 0; - } else { - /* Do not attempt to write to the board if it is not present. */ - if (is_card_present(hw)) { - unsigned long flags; - - spin_lock_irqsave(&hw->lock, flags); - hw->to_setup = 1; - hw->tx_ready = 1; - spin_unlock_irqrestore(&hw->lock, flags); - tasklet_schedule(&hw->tasklet); - } - - mod_timer(&hw->setup_timer, - jiffies + msecs_to_jiffies(TL_SETUP_VERSION_QRY_TMO)); - } -} - -/* - * Stop any interrupts from executing so that, once this function returns, - * other layers of the driver can be sure they won't get any more callbacks. - * Thus must be called on a proper process context. - */ -void ipwireless_stop_interrupts(struct ipw_hardware *hw) -{ - if (!hw->shutting_down) { - /* Tell everyone we are going down. */ - hw->shutting_down = 1; - del_timer(&hw->setup_timer); - - /* Prevent the hardware from sending any more interrupts */ - do_close_hardware(hw); - } -} - -void ipwireless_hardware_free(struct ipw_hardware *hw) -{ - int i; - struct ipw_rx_packet *rp, *rq; - struct ipw_tx_packet *tp, *tq; - - ipwireless_stop_interrupts(hw); - - flush_work_sync(&hw->work_rx); - - for (i = 0; i < NL_NUM_OF_ADDRESSES; i++) - if (hw->packet_assembler[i] != NULL) - kfree(hw->packet_assembler[i]); - - for (i = 0; i < NL_NUM_OF_PRIORITIES; i++) - list_for_each_entry_safe(tp, tq, &hw->tx_queue[i], queue) { - list_del(&tp->queue); - kfree(tp); - } - - list_for_each_entry_safe(rp, rq, &hw->rx_queue, queue) { - list_del(&rp->queue); - kfree(rp); - } - - list_for_each_entry_safe(rp, rq, &hw->rx_pool, queue) { - list_del(&rp->queue); - kfree(rp); - } - kfree(hw); -} - -/* - * Associate the specified network with this hardware, so it will receive events - * from it. - */ -void ipwireless_associate_network(struct ipw_hardware *hw, - struct ipw_network *network) -{ - hw->network = network; -} diff --git a/drivers/char/pcmcia/ipwireless/hardware.h b/drivers/char/pcmcia/ipwireless/hardware.h deleted file mode 100644 index 90a8590e43b0..000000000000 --- a/drivers/char/pcmcia/ipwireless/hardware.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * IPWireless 3G PCMCIA Network Driver - * - * Original code - * by Stephen Blackheath , - * Ben Martel - * - * Copyrighted as follows: - * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) - * - * Various driver changes and rewrites, port to new kernels - * Copyright (C) 2006-2007 Jiri Kosina - * - * Misc code cleanups and updates - * Copyright (C) 2007 David Sterba - */ - -#ifndef _IPWIRELESS_CS_HARDWARE_H_ -#define _IPWIRELESS_CS_HARDWARE_H_ - -#include -#include -#include - -#define IPW_CONTROL_LINE_CTS 0x0001 -#define IPW_CONTROL_LINE_DCD 0x0002 -#define IPW_CONTROL_LINE_DSR 0x0004 -#define IPW_CONTROL_LINE_RI 0x0008 -#define IPW_CONTROL_LINE_DTR 0x0010 -#define IPW_CONTROL_LINE_RTS 0x0020 - -struct ipw_hardware; -struct ipw_network; - -struct ipw_hardware *ipwireless_hardware_create(void); -void ipwireless_hardware_free(struct ipw_hardware *hw); -irqreturn_t ipwireless_interrupt(int irq, void *dev_id); -int ipwireless_set_DTR(struct ipw_hardware *hw, unsigned int channel_idx, - int state); -int ipwireless_set_RTS(struct ipw_hardware *hw, unsigned int channel_idx, - int state); -int ipwireless_send_packet(struct ipw_hardware *hw, - unsigned int channel_idx, - const unsigned char *data, - unsigned int length, - void (*packet_sent_callback) (void *cb, - unsigned int length), - void *sent_cb_data); -void ipwireless_associate_network(struct ipw_hardware *hw, - struct ipw_network *net); -void ipwireless_stop_interrupts(struct ipw_hardware *hw); -void ipwireless_init_hardware_v1(struct ipw_hardware *hw, - unsigned int base_port, - void __iomem *attr_memory, - void __iomem *common_memory, - int is_v2_card, - void (*reboot_cb) (void *data), - void *reboot_cb_data); -void ipwireless_init_hardware_v2_v3(struct ipw_hardware *hw); -void ipwireless_sleep(unsigned int tenths); - -#endif diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c deleted file mode 100644 index 94b8eb4d691d..000000000000 --- a/drivers/char/pcmcia/ipwireless/main.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * IPWireless 3G PCMCIA Network Driver - * - * Original code - * by Stephen Blackheath , - * Ben Martel - * - * Copyrighted as follows: - * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) - * - * Various driver changes and rewrites, port to new kernels - * Copyright (C) 2006-2007 Jiri Kosina - * - * Misc code cleanups and updates - * Copyright (C) 2007 David Sterba - */ - -#include "hardware.h" -#include "network.h" -#include "main.h" -#include "tty.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static struct pcmcia_device_id ipw_ids[] = { - PCMCIA_DEVICE_MANF_CARD(0x02f2, 0x0100), - PCMCIA_DEVICE_MANF_CARD(0x02f2, 0x0200), - PCMCIA_DEVICE_NULL -}; -MODULE_DEVICE_TABLE(pcmcia, ipw_ids); - -static void ipwireless_detach(struct pcmcia_device *link); - -/* - * Module params - */ -/* Debug mode: more verbose, print sent/recv bytes */ -int ipwireless_debug; -int ipwireless_loopback; -int ipwireless_out_queue = 10; - -module_param_named(debug, ipwireless_debug, int, 0); -module_param_named(loopback, ipwireless_loopback, int, 0); -module_param_named(out_queue, ipwireless_out_queue, int, 0); -MODULE_PARM_DESC(debug, "switch on debug messages [0]"); -MODULE_PARM_DESC(loopback, - "debug: enable ras_raw channel [0]"); -MODULE_PARM_DESC(out_queue, "debug: set size of outgoing PPP queue [10]"); - -/* Executes in process context. */ -static void signalled_reboot_work(struct work_struct *work_reboot) -{ - struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev, - work_reboot); - struct pcmcia_device *link = ipw->link; - pcmcia_reset_card(link->socket); -} - -static void signalled_reboot_callback(void *callback_data) -{ - struct ipw_dev *ipw = (struct ipw_dev *) callback_data; - - /* Delegate to process context. */ - schedule_work(&ipw->work_reboot); -} - -static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data) -{ - struct ipw_dev *ipw = priv_data; - struct resource *io_resource; - int ret; - - p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; - p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; - - /* 0x40 causes it to generate level mode interrupts. */ - /* 0x04 enables IREQ pin. */ - p_dev->config_index |= 0x44; - p_dev->io_lines = 16; - ret = pcmcia_request_io(p_dev); - if (ret) - return ret; - - io_resource = request_region(p_dev->resource[0]->start, - resource_size(p_dev->resource[0]), - IPWIRELESS_PCCARD_NAME); - - p_dev->resource[2]->flags |= - WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE; - - ret = pcmcia_request_window(p_dev, p_dev->resource[2], 0); - if (ret != 0) - goto exit1; - - ret = pcmcia_map_mem_page(p_dev, p_dev->resource[2], p_dev->card_addr); - if (ret != 0) - goto exit2; - - ipw->is_v2_card = resource_size(p_dev->resource[2]) == 0x100; - - ipw->attr_memory = ioremap(p_dev->resource[2]->start, - resource_size(p_dev->resource[2])); - request_mem_region(p_dev->resource[2]->start, - resource_size(p_dev->resource[2]), - IPWIRELESS_PCCARD_NAME); - - p_dev->resource[3]->flags |= WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | - WIN_ENABLE; - p_dev->resource[3]->end = 0; /* this used to be 0x1000 */ - ret = pcmcia_request_window(p_dev, p_dev->resource[3], 0); - if (ret != 0) - goto exit2; - - ret = pcmcia_map_mem_page(p_dev, p_dev->resource[3], 0); - if (ret != 0) - goto exit3; - - ipw->attr_memory = ioremap(p_dev->resource[3]->start, - resource_size(p_dev->resource[3])); - request_mem_region(p_dev->resource[3]->start, - resource_size(p_dev->resource[3]), - IPWIRELESS_PCCARD_NAME); - - return 0; - -exit3: -exit2: - if (ipw->common_memory) { - release_mem_region(p_dev->resource[2]->start, - resource_size(p_dev->resource[2])); - iounmap(ipw->common_memory); - } -exit1: - release_resource(io_resource); - pcmcia_disable_device(p_dev); - return -1; -} - -static int config_ipwireless(struct ipw_dev *ipw) -{ - struct pcmcia_device *link = ipw->link; - int ret = 0; - - ipw->is_v2_card = 0; - link->config_flags |= CONF_AUTO_SET_IO | CONF_AUTO_SET_IOMEM | - CONF_ENABLE_IRQ; - - ret = pcmcia_loop_config(link, ipwireless_probe, ipw); - if (ret != 0) - return ret; - - INIT_WORK(&ipw->work_reboot, signalled_reboot_work); - - ipwireless_init_hardware_v1(ipw->hardware, link->resource[0]->start, - ipw->attr_memory, ipw->common_memory, - ipw->is_v2_card, signalled_reboot_callback, - ipw); - - ret = pcmcia_request_irq(link, ipwireless_interrupt); - if (ret != 0) - goto exit; - - printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n", - ipw->is_v2_card ? "V2/V3" : "V1"); - printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": I/O ports %pR, irq %d\n", link->resource[0], - (unsigned int) link->irq); - if (ipw->attr_memory && ipw->common_memory) - printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": attr memory %pR, common memory %pR\n", - link->resource[3], - link->resource[2]); - - ipw->network = ipwireless_network_create(ipw->hardware); - if (!ipw->network) - goto exit; - - ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network); - if (!ipw->tty) - goto exit; - - ipwireless_init_hardware_v2_v3(ipw->hardware); - - /* - * Do the RequestConfiguration last, because it enables interrupts. - * Then we don't get any interrupts before we're ready for them. - */ - ret = pcmcia_enable_device(link); - if (ret != 0) - goto exit; - - return 0; - -exit: - if (ipw->common_memory) { - release_mem_region(link->resource[2]->start, - resource_size(link->resource[2])); - iounmap(ipw->common_memory); - } - if (ipw->attr_memory) { - release_mem_region(link->resource[3]->start, - resource_size(link->resource[3])); - iounmap(ipw->attr_memory); - } - pcmcia_disable_device(link); - return -1; -} - -static void release_ipwireless(struct ipw_dev *ipw) -{ - if (ipw->common_memory) { - release_mem_region(ipw->link->resource[2]->start, - resource_size(ipw->link->resource[2])); - iounmap(ipw->common_memory); - } - if (ipw->attr_memory) { - release_mem_region(ipw->link->resource[3]->start, - resource_size(ipw->link->resource[3])); - iounmap(ipw->attr_memory); - } - pcmcia_disable_device(ipw->link); -} - -/* - * ipwireless_attach() creates an "instance" of the driver, allocating - * local data structures for one device (one interface). The device - * is registered with Card Services. - * - * The pcmcia_device structure is initialized, but we don't actually - * configure the card at this point -- we wait until we receive a - * card insertion event. - */ -static int ipwireless_attach(struct pcmcia_device *link) -{ - struct ipw_dev *ipw; - int ret; - - ipw = kzalloc(sizeof(struct ipw_dev), GFP_KERNEL); - if (!ipw) - return -ENOMEM; - - ipw->link = link; - link->priv = ipw; - - ipw->hardware = ipwireless_hardware_create(); - if (!ipw->hardware) { - kfree(ipw); - return -ENOMEM; - } - /* RegisterClient will call config_ipwireless */ - - ret = config_ipwireless(ipw); - - if (ret != 0) { - ipwireless_detach(link); - return ret; - } - - return 0; -} - -/* - * This deletes a driver "instance". The device is de-registered with - * Card Services. If it has been released, all local data structures - * are freed. Otherwise, the structures will be freed when the device - * is released. - */ -static void ipwireless_detach(struct pcmcia_device *link) -{ - struct ipw_dev *ipw = link->priv; - - release_ipwireless(ipw); - - if (ipw->tty != NULL) - ipwireless_tty_free(ipw->tty); - if (ipw->network != NULL) - ipwireless_network_free(ipw->network); - if (ipw->hardware != NULL) - ipwireless_hardware_free(ipw->hardware); - kfree(ipw); -} - -static struct pcmcia_driver me = { - .owner = THIS_MODULE, - .probe = ipwireless_attach, - .remove = ipwireless_detach, - .name = IPWIRELESS_PCCARD_NAME, - .id_table = ipw_ids -}; - -/* - * Module insertion : initialisation of the module. - * Register the card with cardmgr... - */ -static int __init init_ipwireless(void) -{ - int ret; - - ret = ipwireless_tty_init(); - if (ret != 0) - return ret; - - ret = pcmcia_register_driver(&me); - if (ret != 0) - ipwireless_tty_release(); - - return ret; -} - -/* - * Module removal - */ -static void __exit exit_ipwireless(void) -{ - pcmcia_unregister_driver(&me); - ipwireless_tty_release(); -} - -module_init(init_ipwireless); -module_exit(exit_ipwireless); - -MODULE_AUTHOR(IPWIRELESS_PCMCIA_AUTHOR); -MODULE_DESCRIPTION(IPWIRELESS_PCCARD_NAME " " IPWIRELESS_PCMCIA_VERSION); -MODULE_LICENSE("GPL"); diff --git a/drivers/char/pcmcia/ipwireless/main.h b/drivers/char/pcmcia/ipwireless/main.h deleted file mode 100644 index f2cbb116bccb..000000000000 --- a/drivers/char/pcmcia/ipwireless/main.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * IPWireless 3G PCMCIA Network Driver - * - * Original code - * by Stephen Blackheath , - * Ben Martel - * - * Copyrighted as follows: - * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) - * - * Various driver changes and rewrites, port to new kernels - * Copyright (C) 2006-2007 Jiri Kosina - * - * Misc code cleanups and updates - * Copyright (C) 2007 David Sterba - */ - -#ifndef _IPWIRELESS_CS_H_ -#define _IPWIRELESS_CS_H_ - -#include -#include - -#include -#include - -#include "hardware.h" - -#define IPWIRELESS_PCCARD_NAME "ipwireless" -#define IPWIRELESS_PCMCIA_VERSION "1.1" -#define IPWIRELESS_PCMCIA_AUTHOR \ - "Stephen Blackheath, Ben Martel, Jiri Kosina and David Sterba" - -#define IPWIRELESS_TX_QUEUE_SIZE 262144 -#define IPWIRELESS_RX_QUEUE_SIZE 262144 - -#define IPWIRELESS_STATE_DEBUG - -struct ipw_hardware; -struct ipw_network; -struct ipw_tty; - -struct ipw_dev { - struct pcmcia_device *link; - int is_v2_card; - - void __iomem *attr_memory; - - void __iomem *common_memory; - - /* Reference to attribute memory, containing CIS data */ - void *attribute_memory; - - /* Hardware context */ - struct ipw_hardware *hardware; - /* Network layer context */ - struct ipw_network *network; - /* TTY device context */ - struct ipw_tty *tty; - struct work_struct work_reboot; -}; - -/* Module parametres */ -extern int ipwireless_debug; -extern int ipwireless_loopback; -extern int ipwireless_out_queue; - -#endif diff --git a/drivers/char/pcmcia/ipwireless/network.c b/drivers/char/pcmcia/ipwireless/network.c deleted file mode 100644 index f7daeea598e4..000000000000 --- a/drivers/char/pcmcia/ipwireless/network.c +++ /dev/null @@ -1,508 +0,0 @@ -/* - * IPWireless 3G PCMCIA Network Driver - * - * Original code - * by Stephen Blackheath , - * Ben Martel - * - * Copyrighted as follows: - * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) - * - * Various driver changes and rewrites, port to new kernels - * Copyright (C) 2006-2007 Jiri Kosina - * - * Misc code cleanups and updates - * Copyright (C) 2007 David Sterba - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "network.h" -#include "hardware.h" -#include "main.h" -#include "tty.h" - -#define MAX_ASSOCIATED_TTYS 2 - -#define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP) - -struct ipw_network { - /* Hardware context, used for calls to hardware layer. */ - struct ipw_hardware *hardware; - /* Context for kernel 'generic_ppp' functionality */ - struct ppp_channel *ppp_channel; - /* tty context connected with IPW console */ - struct ipw_tty *associated_ttys[NO_OF_IPW_CHANNELS][MAX_ASSOCIATED_TTYS]; - /* True if ppp needs waking up once we're ready to xmit */ - int ppp_blocked; - /* Number of packets queued up in hardware module. */ - int outgoing_packets_queued; - /* Spinlock to avoid interrupts during shutdown */ - spinlock_t lock; - struct mutex close_lock; - - /* PPP ioctl data, not actually used anywere */ - unsigned int flags; - unsigned int rbits; - u32 xaccm[8]; - u32 raccm; - int mru; - - int shutting_down; - unsigned int ras_control_lines; - - struct work_struct work_go_online; - struct work_struct work_go_offline; -}; - -static void notify_packet_sent(void *callback_data, unsigned int packet_length) -{ - struct ipw_network *network = callback_data; - unsigned long flags; - - spin_lock_irqsave(&network->lock, flags); - network->outgoing_packets_queued--; - if (network->ppp_channel != NULL) { - if (network->ppp_blocked) { - network->ppp_blocked = 0; - spin_unlock_irqrestore(&network->lock, flags); - ppp_output_wakeup(network->ppp_channel); - if (ipwireless_debug) - printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME - ": ppp unblocked\n"); - } else - spin_unlock_irqrestore(&network->lock, flags); - } else - spin_unlock_irqrestore(&network->lock, flags); -} - -/* - * Called by the ppp system when it has a packet to send to the hardware. - */ -static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel, - struct sk_buff *skb) -{ - struct ipw_network *network = ppp_channel->private; - unsigned long flags; - - spin_lock_irqsave(&network->lock, flags); - if (network->outgoing_packets_queued < ipwireless_out_queue) { - unsigned char *buf; - static unsigned char header[] = { - PPP_ALLSTATIONS, /* 0xff */ - PPP_UI, /* 0x03 */ - }; - int ret; - - network->outgoing_packets_queued++; - spin_unlock_irqrestore(&network->lock, flags); - - /* - * If we have the requested amount of headroom in the skb we - * were handed, then we can add the header efficiently. - */ - if (skb_headroom(skb) >= 2) { - memcpy(skb_push(skb, 2), header, 2); - ret = ipwireless_send_packet(network->hardware, - IPW_CHANNEL_RAS, skb->data, - skb->len, - notify_packet_sent, - network); - if (ret == -1) { - skb_pull(skb, 2); - return 0; - } - } else { - /* Otherwise (rarely) we do it inefficiently. */ - buf = kmalloc(skb->len + 2, GFP_ATOMIC); - if (!buf) - return 0; - memcpy(buf + 2, skb->data, skb->len); - memcpy(buf, header, 2); - ret = ipwireless_send_packet(network->hardware, - IPW_CHANNEL_RAS, buf, - skb->len + 2, - notify_packet_sent, - network); - kfree(buf); - if (ret == -1) - return 0; - } - kfree_skb(skb); - return 1; - } else { - /* - * Otherwise reject the packet, and flag that the ppp system - * needs to be unblocked once we are ready to send. - */ - network->ppp_blocked = 1; - spin_unlock_irqrestore(&network->lock, flags); - if (ipwireless_debug) - printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME ": ppp blocked\n"); - return 0; - } -} - -/* Handle an ioctl call that has come in via ppp. (copy of ppp_async_ioctl() */ -static int ipwireless_ppp_ioctl(struct ppp_channel *ppp_channel, - unsigned int cmd, unsigned long arg) -{ - struct ipw_network *network = ppp_channel->private; - int err, val; - u32 accm[8]; - int __user *user_arg = (int __user *) arg; - - err = -EFAULT; - switch (cmd) { - case PPPIOCGFLAGS: - val = network->flags | network->rbits; - if (put_user(val, user_arg)) - break; - err = 0; - break; - - case PPPIOCSFLAGS: - if (get_user(val, user_arg)) - break; - network->flags = val & ~SC_RCV_BITS; - network->rbits = val & SC_RCV_BITS; - err = 0; - break; - - case PPPIOCGASYNCMAP: - if (put_user(network->xaccm[0], user_arg)) - break; - err = 0; - break; - - case PPPIOCSASYNCMAP: - if (get_user(network->xaccm[0], user_arg)) - break; - err = 0; - break; - - case PPPIOCGRASYNCMAP: - if (put_user(network->raccm, user_arg)) - break; - err = 0; - break; - - case PPPIOCSRASYNCMAP: - if (get_user(network->raccm, user_arg)) - break; - err = 0; - break; - - case PPPIOCGXASYNCMAP: - if (copy_to_user((void __user *) arg, network->xaccm, - sizeof(network->xaccm))) - break; - err = 0; - break; - - case PPPIOCSXASYNCMAP: - if (copy_from_user(accm, (void __user *) arg, sizeof(accm))) - break; - accm[2] &= ~0x40000000U; /* can't escape 0x5e */ - accm[3] |= 0x60000000U; /* must escape 0x7d, 0x7e */ - memcpy(network->xaccm, accm, sizeof(network->xaccm)); - err = 0; - break; - - case PPPIOCGMRU: - if (put_user(network->mru, user_arg)) - break; - err = 0; - break; - - case PPPIOCSMRU: - if (get_user(val, user_arg)) - break; - if (val < PPP_MRU) - val = PPP_MRU; - network->mru = val; - err = 0; - break; - - default: - err = -ENOTTY; - } - - return err; -} - -static const struct ppp_channel_ops ipwireless_ppp_channel_ops = { - .start_xmit = ipwireless_ppp_start_xmit, - .ioctl = ipwireless_ppp_ioctl -}; - -static void do_go_online(struct work_struct *work_go_online) -{ - struct ipw_network *network = - container_of(work_go_online, struct ipw_network, - work_go_online); - unsigned long flags; - - spin_lock_irqsave(&network->lock, flags); - if (!network->ppp_channel) { - struct ppp_channel *channel; - - spin_unlock_irqrestore(&network->lock, flags); - channel = kzalloc(sizeof(struct ppp_channel), GFP_KERNEL); - if (!channel) { - printk(KERN_ERR IPWIRELESS_PCCARD_NAME - ": unable to allocate PPP channel\n"); - return; - } - channel->private = network; - channel->mtu = 16384; /* Wild guess */ - channel->hdrlen = 2; - channel->ops = &ipwireless_ppp_channel_ops; - - network->flags = 0; - network->rbits = 0; - network->mru = PPP_MRU; - memset(network->xaccm, 0, sizeof(network->xaccm)); - network->xaccm[0] = ~0U; - network->xaccm[3] = 0x60000000U; - network->raccm = ~0U; - ppp_register_channel(channel); - spin_lock_irqsave(&network->lock, flags); - network->ppp_channel = channel; - } - spin_unlock_irqrestore(&network->lock, flags); -} - -static void do_go_offline(struct work_struct *work_go_offline) -{ - struct ipw_network *network = - container_of(work_go_offline, struct ipw_network, - work_go_offline); - unsigned long flags; - - mutex_lock(&network->close_lock); - spin_lock_irqsave(&network->lock, flags); - if (network->ppp_channel != NULL) { - struct ppp_channel *channel = network->ppp_channel; - - network->ppp_channel = NULL; - spin_unlock_irqrestore(&network->lock, flags); - mutex_unlock(&network->close_lock); - ppp_unregister_channel(channel); - } else { - spin_unlock_irqrestore(&network->lock, flags); - mutex_unlock(&network->close_lock); - } -} - -void ipwireless_network_notify_control_line_change(struct ipw_network *network, - unsigned int channel_idx, - unsigned int control_lines, - unsigned int changed_mask) -{ - int i; - - if (channel_idx == IPW_CHANNEL_RAS) - network->ras_control_lines = control_lines; - - for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) { - struct ipw_tty *tty = - network->associated_ttys[channel_idx][i]; - - /* - * If it's associated with a tty (other than the RAS channel - * when we're online), then send the data to that tty. The RAS - * channel's data is handled above - it always goes through - * ppp_generic. - */ - if (tty) - ipwireless_tty_notify_control_line_change(tty, - channel_idx, - control_lines, - changed_mask); - } -} - -/* - * Some versions of firmware stuff packets with 0xff 0x03 (PPP: ALLSTATIONS, UI) - * bytes, which are required on sent packet, but not always present on received - * packets - */ -static struct sk_buff *ipw_packet_received_skb(unsigned char *data, - unsigned int length) -{ - struct sk_buff *skb; - - if (length > 2 && data[0] == PPP_ALLSTATIONS && data[1] == PPP_UI) { - length -= 2; - data += 2; - } - - skb = dev_alloc_skb(length + 4); - skb_reserve(skb, 2); - memcpy(skb_put(skb, length), data, length); - - return skb; -} - -void ipwireless_network_packet_received(struct ipw_network *network, - unsigned int channel_idx, - unsigned char *data, - unsigned int length) -{ - int i; - unsigned long flags; - - for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) { - struct ipw_tty *tty = network->associated_ttys[channel_idx][i]; - - if (!tty) - continue; - - /* - * If it's associated with a tty (other than the RAS channel - * when we're online), then send the data to that tty. The RAS - * channel's data is handled above - it always goes through - * ppp_generic. - */ - if (channel_idx == IPW_CHANNEL_RAS - && (network->ras_control_lines & - IPW_CONTROL_LINE_DCD) != 0 - && ipwireless_tty_is_modem(tty)) { - /* - * If data came in on the RAS channel and this tty is - * the modem tty, and we are online, then we send it to - * the PPP layer. - */ - mutex_lock(&network->close_lock); - spin_lock_irqsave(&network->lock, flags); - if (network->ppp_channel != NULL) { - struct sk_buff *skb; - - spin_unlock_irqrestore(&network->lock, - flags); - - /* Send the data to the ppp_generic module. */ - skb = ipw_packet_received_skb(data, length); - ppp_input(network->ppp_channel, skb); - } else - spin_unlock_irqrestore(&network->lock, - flags); - mutex_unlock(&network->close_lock); - } - /* Otherwise we send it out the tty. */ - else - ipwireless_tty_received(tty, data, length); - } -} - -struct ipw_network *ipwireless_network_create(struct ipw_hardware *hw) -{ - struct ipw_network *network = - kzalloc(sizeof(struct ipw_network), GFP_ATOMIC); - - if (!network) - return NULL; - - spin_lock_init(&network->lock); - mutex_init(&network->close_lock); - - network->hardware = hw; - - INIT_WORK(&network->work_go_online, do_go_online); - INIT_WORK(&network->work_go_offline, do_go_offline); - - ipwireless_associate_network(hw, network); - - return network; -} - -void ipwireless_network_free(struct ipw_network *network) -{ - network->shutting_down = 1; - - ipwireless_ppp_close(network); - flush_work_sync(&network->work_go_online); - flush_work_sync(&network->work_go_offline); - - ipwireless_stop_interrupts(network->hardware); - ipwireless_associate_network(network->hardware, NULL); - - kfree(network); -} - -void ipwireless_associate_network_tty(struct ipw_network *network, - unsigned int channel_idx, - struct ipw_tty *tty) -{ - int i; - - for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) - if (network->associated_ttys[channel_idx][i] == NULL) { - network->associated_ttys[channel_idx][i] = tty; - break; - } -} - -void ipwireless_disassociate_network_ttys(struct ipw_network *network, - unsigned int channel_idx) -{ - int i; - - for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) - network->associated_ttys[channel_idx][i] = NULL; -} - -void ipwireless_ppp_open(struct ipw_network *network) -{ - if (ipwireless_debug) - printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME ": online\n"); - schedule_work(&network->work_go_online); -} - -void ipwireless_ppp_close(struct ipw_network *network) -{ - /* Disconnect from the wireless network. */ - if (ipwireless_debug) - printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME ": offline\n"); - schedule_work(&network->work_go_offline); -} - -int ipwireless_ppp_channel_index(struct ipw_network *network) -{ - int ret = -1; - unsigned long flags; - - spin_lock_irqsave(&network->lock, flags); - if (network->ppp_channel != NULL) - ret = ppp_channel_index(network->ppp_channel); - spin_unlock_irqrestore(&network->lock, flags); - - return ret; -} - -int ipwireless_ppp_unit_number(struct ipw_network *network) -{ - int ret = -1; - unsigned long flags; - - spin_lock_irqsave(&network->lock, flags); - if (network->ppp_channel != NULL) - ret = ppp_unit_number(network->ppp_channel); - spin_unlock_irqrestore(&network->lock, flags); - - return ret; -} - -int ipwireless_ppp_mru(const struct ipw_network *network) -{ - return network->mru; -} diff --git a/drivers/char/pcmcia/ipwireless/network.h b/drivers/char/pcmcia/ipwireless/network.h deleted file mode 100644 index 561f765b3334..000000000000 --- a/drivers/char/pcmcia/ipwireless/network.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * IPWireless 3G PCMCIA Network Driver - * - * Original code - * by Stephen Blackheath , - * Ben Martel - * - * Copyrighted as follows: - * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) - * - * Various driver changes and rewrites, port to new kernels - * Copyright (C) 2006-2007 Jiri Kosina - * - * Misc code cleanups and updates - * Copyright (C) 2007 David Sterba - */ - -#ifndef _IPWIRELESS_CS_NETWORK_H_ -#define _IPWIRELESS_CS_NETWORK_H_ - -#include - -struct ipw_network; -struct ipw_tty; -struct ipw_hardware; - -/* Definitions of the different channels on the PCMCIA UE */ -#define IPW_CHANNEL_RAS 0 -#define IPW_CHANNEL_DIALLER 1 -#define IPW_CHANNEL_CONSOLE 2 -#define NO_OF_IPW_CHANNELS 5 - -void ipwireless_network_notify_control_line_change(struct ipw_network *net, - unsigned int channel_idx, unsigned int control_lines, - unsigned int control_mask); -void ipwireless_network_packet_received(struct ipw_network *net, - unsigned int channel_idx, unsigned char *data, - unsigned int length); -struct ipw_network *ipwireless_network_create(struct ipw_hardware *hw); -void ipwireless_network_free(struct ipw_network *net); -void ipwireless_associate_network_tty(struct ipw_network *net, - unsigned int channel_idx, struct ipw_tty *tty); -void ipwireless_disassociate_network_ttys(struct ipw_network *net, - unsigned int channel_idx); - -void ipwireless_ppp_open(struct ipw_network *net); - -void ipwireless_ppp_close(struct ipw_network *net); -int ipwireless_ppp_channel_index(struct ipw_network *net); -int ipwireless_ppp_unit_number(struct ipw_network *net); -int ipwireless_ppp_mru(const struct ipw_network *net); - -#endif diff --git a/drivers/char/pcmcia/ipwireless/setup_protocol.h b/drivers/char/pcmcia/ipwireless/setup_protocol.h deleted file mode 100644 index 9d6bcc77c73c..000000000000 --- a/drivers/char/pcmcia/ipwireless/setup_protocol.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * IPWireless 3G PCMCIA Network Driver - * - * Original code - * by Stephen Blackheath , - * Ben Martel - * - * Copyrighted as follows: - * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) - * - * Various driver changes and rewrites, port to new kernels - * Copyright (C) 2006-2007 Jiri Kosina - * - * Misc code cleanups and updates - * Copyright (C) 2007 David Sterba - */ - -#ifndef _IPWIRELESS_CS_SETUP_PROTOCOL_H_ -#define _IPWIRELESS_CS_SETUP_PROTOCOL_H_ - -/* Version of the setup protocol and transport protocols */ -#define TL_SETUP_VERSION 1 - -#define TL_SETUP_VERSION_QRY_TMO 1000 -#define TL_SETUP_MAX_VERSION_QRY 30 - -/* Message numbers 0-9 are obsoleted and must not be reused! */ -#define TL_SETUP_SIGNO_GET_VERSION_QRY 10 -#define TL_SETUP_SIGNO_GET_VERSION_RSP 11 -#define TL_SETUP_SIGNO_CONFIG_MSG 12 -#define TL_SETUP_SIGNO_CONFIG_DONE_MSG 13 -#define TL_SETUP_SIGNO_OPEN_MSG 14 -#define TL_SETUP_SIGNO_CLOSE_MSG 15 - -#define TL_SETUP_SIGNO_INFO_MSG 20 -#define TL_SETUP_SIGNO_INFO_MSG_ACK 21 - -#define TL_SETUP_SIGNO_REBOOT_MSG 22 -#define TL_SETUP_SIGNO_REBOOT_MSG_ACK 23 - -/* Synchronous start-messages */ -struct tl_setup_get_version_qry { - unsigned char sig_no; /* TL_SETUP_SIGNO_GET_VERSION_QRY */ -} __attribute__ ((__packed__)); - -struct tl_setup_get_version_rsp { - unsigned char sig_no; /* TL_SETUP_SIGNO_GET_VERSION_RSP */ - unsigned char version; /* TL_SETUP_VERSION */ -} __attribute__ ((__packed__)); - -struct tl_setup_config_msg { - unsigned char sig_no; /* TL_SETUP_SIGNO_CONFIG_MSG */ - unsigned char port_no; - unsigned char prio_data; - unsigned char prio_ctrl; -} __attribute__ ((__packed__)); - -struct tl_setup_config_done_msg { - unsigned char sig_no; /* TL_SETUP_SIGNO_CONFIG_DONE_MSG */ -} __attribute__ ((__packed__)); - -/* Asyncronous messages */ -struct tl_setup_open_msg { - unsigned char sig_no; /* TL_SETUP_SIGNO_OPEN_MSG */ - unsigned char port_no; -} __attribute__ ((__packed__)); - -struct tl_setup_close_msg { - unsigned char sig_no; /* TL_SETUP_SIGNO_CLOSE_MSG */ - unsigned char port_no; -} __attribute__ ((__packed__)); - -/* Driver type - for use in tl_setup_info_msg.driver_type */ -#define COMM_DRIVER 0 -#define NDISWAN_DRIVER 1 -#define NDISWAN_DRIVER_MAJOR_VERSION 2 -#define NDISWAN_DRIVER_MINOR_VERSION 0 - -/* - * It should not matter when this message comes over as we just store the - * results and send the ACK. - */ -struct tl_setup_info_msg { - unsigned char sig_no; /* TL_SETUP_SIGNO_INFO_MSG */ - unsigned char driver_type; - unsigned char major_version; - unsigned char minor_version; -} __attribute__ ((__packed__)); - -struct tl_setup_info_msgAck { - unsigned char sig_no; /* TL_SETUP_SIGNO_INFO_MSG_ACK */ -} __attribute__ ((__packed__)); - -struct TlSetupRebootMsgAck { - unsigned char sig_no; /* TL_SETUP_SIGNO_REBOOT_MSG_ACK */ -} __attribute__ ((__packed__)); - -/* Define a union of all the msgs that the driver can receive from the card.*/ -union ipw_setup_rx_msg { - unsigned char sig_no; - struct tl_setup_get_version_rsp version_rsp_msg; - struct tl_setup_open_msg open_msg; - struct tl_setup_close_msg close_msg; - struct tl_setup_info_msg InfoMsg; - struct tl_setup_info_msgAck info_msg_ack; -} __attribute__ ((__packed__)); - -#endif /* _IPWIRELESS_CS_SETUP_PROTOCOL_H_ */ diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c deleted file mode 100644 index ef92869502a7..000000000000 --- a/drivers/char/pcmcia/ipwireless/tty.c +++ /dev/null @@ -1,679 +0,0 @@ -/* - * IPWireless 3G PCMCIA Network Driver - * - * Original code - * by Stephen Blackheath , - * Ben Martel - * - * Copyrighted as follows: - * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) - * - * Various driver changes and rewrites, port to new kernels - * Copyright (C) 2006-2007 Jiri Kosina - * - * Misc code cleanups and updates - * Copyright (C) 2007 David Sterba - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tty.h" -#include "network.h" -#include "hardware.h" -#include "main.h" - -#define IPWIRELESS_PCMCIA_START (0) -#define IPWIRELESS_PCMCIA_MINORS (24) -#define IPWIRELESS_PCMCIA_MINOR_RANGE (8) - -#define TTYTYPE_MODEM (0) -#define TTYTYPE_MONITOR (1) -#define TTYTYPE_RAS_RAW (2) - -struct ipw_tty { - int index; - struct ipw_hardware *hardware; - unsigned int channel_idx; - unsigned int secondary_channel_idx; - int tty_type; - struct ipw_network *network; - struct tty_struct *linux_tty; - int open_count; - unsigned int control_lines; - struct mutex ipw_tty_mutex; - int tx_bytes_queued; - int closing; -}; - -static struct ipw_tty *ttys[IPWIRELESS_PCMCIA_MINORS]; - -static struct tty_driver *ipw_tty_driver; - -static char *tty_type_name(int tty_type) -{ - static char *channel_names[] = { - "modem", - "monitor", - "RAS-raw" - }; - - return channel_names[tty_type]; -} - -static void report_registering(struct ipw_tty *tty) -{ - char *iftype = tty_type_name(tty->tty_type); - - printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": registering %s device ttyIPWp%d\n", iftype, tty->index); -} - -static void report_deregistering(struct ipw_tty *tty) -{ - char *iftype = tty_type_name(tty->tty_type); - - printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": deregistering %s device ttyIPWp%d\n", iftype, - tty->index); -} - -static struct ipw_tty *get_tty(int minor) -{ - if (minor < ipw_tty_driver->minor_start - || minor >= ipw_tty_driver->minor_start + - IPWIRELESS_PCMCIA_MINORS) - return NULL; - else { - int minor_offset = minor - ipw_tty_driver->minor_start; - - /* - * The 'ras_raw' channel is only available when 'loopback' mode - * is enabled. - * Number of minor starts with 16 (_RANGE * _RAS_RAW). - */ - if (!ipwireless_loopback && - minor_offset >= - IPWIRELESS_PCMCIA_MINOR_RANGE * TTYTYPE_RAS_RAW) - return NULL; - - return ttys[minor_offset]; - } -} - -static int ipw_open(struct tty_struct *linux_tty, struct file *filp) -{ - int minor = linux_tty->index; - struct ipw_tty *tty = get_tty(minor); - - if (!tty) - return -ENODEV; - - mutex_lock(&tty->ipw_tty_mutex); - - if (tty->closing) { - mutex_unlock(&tty->ipw_tty_mutex); - return -ENODEV; - } - if (tty->open_count == 0) - tty->tx_bytes_queued = 0; - - tty->open_count++; - - tty->linux_tty = linux_tty; - linux_tty->driver_data = tty; - linux_tty->low_latency = 1; - - if (tty->tty_type == TTYTYPE_MODEM) - ipwireless_ppp_open(tty->network); - - mutex_unlock(&tty->ipw_tty_mutex); - - return 0; -} - -static void do_ipw_close(struct ipw_tty *tty) -{ - tty->open_count--; - - if (tty->open_count == 0) { - struct tty_struct *linux_tty = tty->linux_tty; - - if (linux_tty != NULL) { - tty->linux_tty = NULL; - linux_tty->driver_data = NULL; - - if (tty->tty_type == TTYTYPE_MODEM) - ipwireless_ppp_close(tty->network); - } - } -} - -static void ipw_hangup(struct tty_struct *linux_tty) -{ - struct ipw_tty *tty = linux_tty->driver_data; - - if (!tty) - return; - - mutex_lock(&tty->ipw_tty_mutex); - if (tty->open_count == 0) { - mutex_unlock(&tty->ipw_tty_mutex); - return; - } - - do_ipw_close(tty); - - mutex_unlock(&tty->ipw_tty_mutex); -} - -static void ipw_close(struct tty_struct *linux_tty, struct file *filp) -{ - ipw_hangup(linux_tty); -} - -/* Take data received from hardware, and send it out the tty */ -void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data, - unsigned int length) -{ - struct tty_struct *linux_tty; - int work = 0; - - mutex_lock(&tty->ipw_tty_mutex); - linux_tty = tty->linux_tty; - if (linux_tty == NULL) { - mutex_unlock(&tty->ipw_tty_mutex); - return; - } - - if (!tty->open_count) { - mutex_unlock(&tty->ipw_tty_mutex); - return; - } - mutex_unlock(&tty->ipw_tty_mutex); - - work = tty_insert_flip_string(linux_tty, data, length); - - if (work != length) - printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME - ": %d chars not inserted to flip buffer!\n", - length - work); - - /* - * This may sleep if ->low_latency is set - */ - if (work) - tty_flip_buffer_push(linux_tty); -} - -static void ipw_write_packet_sent_callback(void *callback_data, - unsigned int packet_length) -{ - struct ipw_tty *tty = callback_data; - - /* - * Packet has been sent, so we subtract the number of bytes from our - * tally of outstanding TX bytes. - */ - tty->tx_bytes_queued -= packet_length; -} - -static int ipw_write(struct tty_struct *linux_tty, - const unsigned char *buf, int count) -{ - struct ipw_tty *tty = linux_tty->driver_data; - int room, ret; - - if (!tty) - return -ENODEV; - - mutex_lock(&tty->ipw_tty_mutex); - if (!tty->open_count) { - mutex_unlock(&tty->ipw_tty_mutex); - return -EINVAL; - } - - room = IPWIRELESS_TX_QUEUE_SIZE - tty->tx_bytes_queued; - if (room < 0) - room = 0; - /* Don't allow caller to write any more than we have room for */ - if (count > room) - count = room; - - if (count == 0) { - mutex_unlock(&tty->ipw_tty_mutex); - return 0; - } - - ret = ipwireless_send_packet(tty->hardware, IPW_CHANNEL_RAS, - buf, count, - ipw_write_packet_sent_callback, tty); - if (ret == -1) { - mutex_unlock(&tty->ipw_tty_mutex); - return 0; - } - - tty->tx_bytes_queued += count; - mutex_unlock(&tty->ipw_tty_mutex); - - return count; -} - -static int ipw_write_room(struct tty_struct *linux_tty) -{ - struct ipw_tty *tty = linux_tty->driver_data; - int room; - - /* FIXME: Exactly how is the tty object locked here .. */ - if (!tty) - return -ENODEV; - - if (!tty->open_count) - return -EINVAL; - - room = IPWIRELESS_TX_QUEUE_SIZE - tty->tx_bytes_queued; - if (room < 0) - room = 0; - - return room; -} - -static int ipwireless_get_serial_info(struct ipw_tty *tty, - struct serial_struct __user *retinfo) -{ - struct serial_struct tmp; - - if (!retinfo) - return (-EFAULT); - - memset(&tmp, 0, sizeof(tmp)); - tmp.type = PORT_UNKNOWN; - tmp.line = tty->index; - tmp.port = 0; - tmp.irq = 0; - tmp.flags = 0; - tmp.baud_base = 115200; - tmp.close_delay = 0; - tmp.closing_wait = 0; - tmp.custom_divisor = 0; - tmp.hub6 = 0; - if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) - return -EFAULT; - - return 0; -} - -static int ipw_chars_in_buffer(struct tty_struct *linux_tty) -{ - struct ipw_tty *tty = linux_tty->driver_data; - - if (!tty) - return 0; - - if (!tty->open_count) - return 0; - - return tty->tx_bytes_queued; -} - -static int get_control_lines(struct ipw_tty *tty) -{ - unsigned int my = tty->control_lines; - unsigned int out = 0; - - if (my & IPW_CONTROL_LINE_RTS) - out |= TIOCM_RTS; - if (my & IPW_CONTROL_LINE_DTR) - out |= TIOCM_DTR; - if (my & IPW_CONTROL_LINE_CTS) - out |= TIOCM_CTS; - if (my & IPW_CONTROL_LINE_DSR) - out |= TIOCM_DSR; - if (my & IPW_CONTROL_LINE_DCD) - out |= TIOCM_CD; - - return out; -} - -static int set_control_lines(struct ipw_tty *tty, unsigned int set, - unsigned int clear) -{ - int ret; - - if (set & TIOCM_RTS) { - ret = ipwireless_set_RTS(tty->hardware, tty->channel_idx, 1); - if (ret) - return ret; - if (tty->secondary_channel_idx != -1) { - ret = ipwireless_set_RTS(tty->hardware, - tty->secondary_channel_idx, 1); - if (ret) - return ret; - } - } - if (set & TIOCM_DTR) { - ret = ipwireless_set_DTR(tty->hardware, tty->channel_idx, 1); - if (ret) - return ret; - if (tty->secondary_channel_idx != -1) { - ret = ipwireless_set_DTR(tty->hardware, - tty->secondary_channel_idx, 1); - if (ret) - return ret; - } - } - if (clear & TIOCM_RTS) { - ret = ipwireless_set_RTS(tty->hardware, tty->channel_idx, 0); - if (tty->secondary_channel_idx != -1) { - ret = ipwireless_set_RTS(tty->hardware, - tty->secondary_channel_idx, 0); - if (ret) - return ret; - } - } - if (clear & TIOCM_DTR) { - ret = ipwireless_set_DTR(tty->hardware, tty->channel_idx, 0); - if (tty->secondary_channel_idx != -1) { - ret = ipwireless_set_DTR(tty->hardware, - tty->secondary_channel_idx, 0); - if (ret) - return ret; - } - } - return 0; -} - -static int ipw_tiocmget(struct tty_struct *linux_tty) -{ - struct ipw_tty *tty = linux_tty->driver_data; - /* FIXME: Exactly how is the tty object locked here .. */ - - if (!tty) - return -ENODEV; - - if (!tty->open_count) - return -EINVAL; - - return get_control_lines(tty); -} - -static int -ipw_tiocmset(struct tty_struct *linux_tty, - unsigned int set, unsigned int clear) -{ - struct ipw_tty *tty = linux_tty->driver_data; - /* FIXME: Exactly how is the tty object locked here .. */ - - if (!tty) - return -ENODEV; - - if (!tty->open_count) - return -EINVAL; - - return set_control_lines(tty, set, clear); -} - -static int ipw_ioctl(struct tty_struct *linux_tty, - unsigned int cmd, unsigned long arg) -{ - struct ipw_tty *tty = linux_tty->driver_data; - - if (!tty) - return -ENODEV; - - if (!tty->open_count) - return -EINVAL; - - /* FIXME: Exactly how is the tty object locked here .. */ - - switch (cmd) { - case TIOCGSERIAL: - return ipwireless_get_serial_info(tty, (void __user *) arg); - - case TIOCSSERIAL: - return 0; /* Keeps the PCMCIA scripts happy. */ - } - - if (tty->tty_type == TTYTYPE_MODEM) { - switch (cmd) { - case PPPIOCGCHAN: - { - int chan = ipwireless_ppp_channel_index( - tty->network); - - if (chan < 0) - return -ENODEV; - if (put_user(chan, (int __user *) arg)) - return -EFAULT; - } - return 0; - - case PPPIOCGUNIT: - { - int unit = ipwireless_ppp_unit_number( - tty->network); - - if (unit < 0) - return -ENODEV; - if (put_user(unit, (int __user *) arg)) - return -EFAULT; - } - return 0; - - case FIONREAD: - { - int val = 0; - - if (put_user(val, (int __user *) arg)) - return -EFAULT; - } - return 0; - case TCFLSH: - return tty_perform_flush(linux_tty, arg); - } - } - return -ENOIOCTLCMD; -} - -static int add_tty(int j, - struct ipw_hardware *hardware, - struct ipw_network *network, int channel_idx, - int secondary_channel_idx, int tty_type) -{ - ttys[j] = kzalloc(sizeof(struct ipw_tty), GFP_KERNEL); - if (!ttys[j]) - return -ENOMEM; - ttys[j]->index = j; - ttys[j]->hardware = hardware; - ttys[j]->channel_idx = channel_idx; - ttys[j]->secondary_channel_idx = secondary_channel_idx; - ttys[j]->network = network; - ttys[j]->tty_type = tty_type; - mutex_init(&ttys[j]->ipw_tty_mutex); - - tty_register_device(ipw_tty_driver, j, NULL); - ipwireless_associate_network_tty(network, channel_idx, ttys[j]); - - if (secondary_channel_idx != -1) - ipwireless_associate_network_tty(network, - secondary_channel_idx, - ttys[j]); - if (get_tty(j + ipw_tty_driver->minor_start) == ttys[j]) - report_registering(ttys[j]); - return 0; -} - -struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hardware, - struct ipw_network *network) -{ - int i, j; - - for (i = 0; i < IPWIRELESS_PCMCIA_MINOR_RANGE; i++) { - int allfree = 1; - - for (j = i; j < IPWIRELESS_PCMCIA_MINORS; - j += IPWIRELESS_PCMCIA_MINOR_RANGE) - if (ttys[j] != NULL) { - allfree = 0; - break; - } - - if (allfree) { - j = i; - - if (add_tty(j, hardware, network, - IPW_CHANNEL_DIALLER, IPW_CHANNEL_RAS, - TTYTYPE_MODEM)) - return NULL; - - j += IPWIRELESS_PCMCIA_MINOR_RANGE; - if (add_tty(j, hardware, network, - IPW_CHANNEL_DIALLER, -1, - TTYTYPE_MONITOR)) - return NULL; - - j += IPWIRELESS_PCMCIA_MINOR_RANGE; - if (add_tty(j, hardware, network, - IPW_CHANNEL_RAS, -1, - TTYTYPE_RAS_RAW)) - return NULL; - - return ttys[i]; - } - } - return NULL; -} - -/* - * Must be called before ipwireless_network_free(). - */ -void ipwireless_tty_free(struct ipw_tty *tty) -{ - int j; - struct ipw_network *network = ttys[tty->index]->network; - - for (j = tty->index; j < IPWIRELESS_PCMCIA_MINORS; - j += IPWIRELESS_PCMCIA_MINOR_RANGE) { - struct ipw_tty *ttyj = ttys[j]; - - if (ttyj) { - mutex_lock(&ttyj->ipw_tty_mutex); - if (get_tty(j + ipw_tty_driver->minor_start) == ttyj) - report_deregistering(ttyj); - ttyj->closing = 1; - if (ttyj->linux_tty != NULL) { - mutex_unlock(&ttyj->ipw_tty_mutex); - tty_hangup(ttyj->linux_tty); - /* Wait till the tty_hangup has completed */ - flush_work_sync(&ttyj->linux_tty->hangup_work); - /* FIXME: Exactly how is the tty object locked here - against a parallel ioctl etc */ - mutex_lock(&ttyj->ipw_tty_mutex); - } - while (ttyj->open_count) - do_ipw_close(ttyj); - ipwireless_disassociate_network_ttys(network, - ttyj->channel_idx); - tty_unregister_device(ipw_tty_driver, j); - ttys[j] = NULL; - mutex_unlock(&ttyj->ipw_tty_mutex); - kfree(ttyj); - } - } -} - -static const struct tty_operations tty_ops = { - .open = ipw_open, - .close = ipw_close, - .hangup = ipw_hangup, - .write = ipw_write, - .write_room = ipw_write_room, - .ioctl = ipw_ioctl, - .chars_in_buffer = ipw_chars_in_buffer, - .tiocmget = ipw_tiocmget, - .tiocmset = ipw_tiocmset, -}; - -int ipwireless_tty_init(void) -{ - int result; - - ipw_tty_driver = alloc_tty_driver(IPWIRELESS_PCMCIA_MINORS); - if (!ipw_tty_driver) - return -ENOMEM; - - ipw_tty_driver->owner = THIS_MODULE; - ipw_tty_driver->driver_name = IPWIRELESS_PCCARD_NAME; - ipw_tty_driver->name = "ttyIPWp"; - ipw_tty_driver->major = 0; - ipw_tty_driver->minor_start = IPWIRELESS_PCMCIA_START; - ipw_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - ipw_tty_driver->subtype = SERIAL_TYPE_NORMAL; - ipw_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; - ipw_tty_driver->init_termios = tty_std_termios; - ipw_tty_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - ipw_tty_driver->init_termios.c_ispeed = 9600; - ipw_tty_driver->init_termios.c_ospeed = 9600; - tty_set_operations(ipw_tty_driver, &tty_ops); - result = tty_register_driver(ipw_tty_driver); - if (result) { - printk(KERN_ERR IPWIRELESS_PCCARD_NAME - ": failed to register tty driver\n"); - put_tty_driver(ipw_tty_driver); - return result; - } - - return 0; -} - -void ipwireless_tty_release(void) -{ - int ret; - - ret = tty_unregister_driver(ipw_tty_driver); - put_tty_driver(ipw_tty_driver); - if (ret != 0) - printk(KERN_ERR IPWIRELESS_PCCARD_NAME - ": tty_unregister_driver failed with code %d\n", ret); -} - -int ipwireless_tty_is_modem(struct ipw_tty *tty) -{ - return tty->tty_type == TTYTYPE_MODEM; -} - -void -ipwireless_tty_notify_control_line_change(struct ipw_tty *tty, - unsigned int channel_idx, - unsigned int control_lines, - unsigned int changed_mask) -{ - unsigned int old_control_lines = tty->control_lines; - - tty->control_lines = (tty->control_lines & ~changed_mask) - | (control_lines & changed_mask); - - /* - * If DCD is de-asserted, we close the tty so pppd can tell that we - * have gone offline. - */ - if ((old_control_lines & IPW_CONTROL_LINE_DCD) - && !(tty->control_lines & IPW_CONTROL_LINE_DCD) - && tty->linux_tty) { - tty_hangup(tty->linux_tty); - } -} - diff --git a/drivers/char/pcmcia/ipwireless/tty.h b/drivers/char/pcmcia/ipwireless/tty.h deleted file mode 100644 index 747b2d637860..000000000000 --- a/drivers/char/pcmcia/ipwireless/tty.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * IPWireless 3G PCMCIA Network Driver - * - * Original code - * by Stephen Blackheath , - * Ben Martel - * - * Copyrighted as follows: - * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) - * - * Various driver changes and rewrites, port to new kernels - * Copyright (C) 2006-2007 Jiri Kosina - * - * Misc code cleanups and updates - * Copyright (C) 2007 David Sterba - */ - -#ifndef _IPWIRELESS_CS_TTY_H_ -#define _IPWIRELESS_CS_TTY_H_ - -#include -#include - -#include -#include - -struct ipw_tty; -struct ipw_network; -struct ipw_hardware; - -int ipwireless_tty_init(void); -void ipwireless_tty_release(void); - -struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hw, - struct ipw_network *net); -void ipwireless_tty_free(struct ipw_tty *tty); -void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data, - unsigned int length); -int ipwireless_tty_is_modem(struct ipw_tty *tty); -void ipwireless_tty_notify_control_line_change(struct ipw_tty *tty, - unsigned int channel_idx, - unsigned int control_lines, - unsigned int changed_mask); - -#endif diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index e549da348a04..690522fcb338 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile @@ -24,3 +24,5 @@ obj-$(CONFIG_ROCKETPORT) += rocket.o obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o obj-$(CONFIG_SYNCLINK) += synclink.o + +obj-y += ipwireless/ diff --git a/drivers/tty/ipwireless/Makefile b/drivers/tty/ipwireless/Makefile new file mode 100644 index 000000000000..db80873d7f20 --- /dev/null +++ b/drivers/tty/ipwireless/Makefile @@ -0,0 +1,10 @@ +# +# drivers/char/pcmcia/ipwireless/Makefile +# +# Makefile for the IPWireless driver +# + +obj-$(CONFIG_IPWIRELESS) += ipwireless.o + +ipwireless-y := hardware.o main.o network.o tty.o + diff --git a/drivers/tty/ipwireless/hardware.c b/drivers/tty/ipwireless/hardware.c new file mode 100644 index 000000000000..0aeb5a38d296 --- /dev/null +++ b/drivers/tty/ipwireless/hardware.c @@ -0,0 +1,1764 @@ +/* + * IPWireless 3G PCMCIA Network Driver + * + * Original code + * by Stephen Blackheath , + * Ben Martel + * + * Copyrighted as follows: + * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) + * + * Various driver changes and rewrites, port to new kernels + * Copyright (C) 2006-2007 Jiri Kosina + * + * Misc code cleanups and updates + * Copyright (C) 2007 David Sterba + */ + +#include +#include +#include +#include +#include +#include + +#include "hardware.h" +#include "setup_protocol.h" +#include "network.h" +#include "main.h" + +static void ipw_send_setup_packet(struct ipw_hardware *hw); +static void handle_received_SETUP_packet(struct ipw_hardware *ipw, + unsigned int address, + const unsigned char *data, int len, + int is_last); +static void ipwireless_setup_timer(unsigned long data); +static void handle_received_CTRL_packet(struct ipw_hardware *hw, + unsigned int channel_idx, const unsigned char *data, int len); + +/*#define TIMING_DIAGNOSTICS*/ + +#ifdef TIMING_DIAGNOSTICS + +static struct timing_stats { + unsigned long last_report_time; + unsigned long read_time; + unsigned long write_time; + unsigned long read_bytes; + unsigned long write_bytes; + unsigned long start_time; +}; + +static void start_timing(void) +{ + timing_stats.start_time = jiffies; +} + +static void end_read_timing(unsigned length) +{ + timing_stats.read_time += (jiffies - start_time); + timing_stats.read_bytes += length + 2; + report_timing(); +} + +static void end_write_timing(unsigned length) +{ + timing_stats.write_time += (jiffies - start_time); + timing_stats.write_bytes += length + 2; + report_timing(); +} + +static void report_timing(void) +{ + unsigned long since = jiffies - timing_stats.last_report_time; + + /* If it's been more than one second... */ + if (since >= HZ) { + int first = (timing_stats.last_report_time == 0); + + timing_stats.last_report_time = jiffies; + if (!first) + printk(KERN_INFO IPWIRELESS_PCCARD_NAME + ": %u us elapsed - read %lu bytes in %u us, wrote %lu bytes in %u us\n", + jiffies_to_usecs(since), + timing_stats.read_bytes, + jiffies_to_usecs(timing_stats.read_time), + timing_stats.write_bytes, + jiffies_to_usecs(timing_stats.write_time)); + + timing_stats.read_time = 0; + timing_stats.write_time = 0; + timing_stats.read_bytes = 0; + timing_stats.write_bytes = 0; + } +} +#else +static void start_timing(void) { } +static void end_read_timing(unsigned length) { } +static void end_write_timing(unsigned length) { } +#endif + +/* Imported IPW definitions */ + +#define LL_MTU_V1 318 +#define LL_MTU_V2 250 +#define LL_MTU_MAX (LL_MTU_V1 > LL_MTU_V2 ? LL_MTU_V1 : LL_MTU_V2) + +#define PRIO_DATA 2 +#define PRIO_CTRL 1 +#define PRIO_SETUP 0 + +/* Addresses */ +#define ADDR_SETUP_PROT 0 + +/* Protocol ids */ +enum { + /* Identifier for the Com Data protocol */ + TL_PROTOCOLID_COM_DATA = 0, + + /* Identifier for the Com Control protocol */ + TL_PROTOCOLID_COM_CTRL = 1, + + /* Identifier for the Setup protocol */ + TL_PROTOCOLID_SETUP = 2 +}; + +/* Number of bytes in NL packet header (cannot do + * sizeof(nl_packet_header) since it's a bitfield) */ +#define NL_FIRST_PACKET_HEADER_SIZE 3 + +/* Number of bytes in NL packet header (cannot do + * sizeof(nl_packet_header) since it's a bitfield) */ +#define NL_FOLLOWING_PACKET_HEADER_SIZE 1 + +struct nl_first_packet_header { + unsigned char protocol:3; + unsigned char address:3; + unsigned char packet_rank:2; + unsigned char length_lsb; + unsigned char length_msb; +}; + +struct nl_packet_header { + unsigned char protocol:3; + unsigned char address:3; + unsigned char packet_rank:2; +}; + +/* Value of 'packet_rank' above */ +#define NL_INTERMEDIATE_PACKET 0x0 +#define NL_LAST_PACKET 0x1 +#define NL_FIRST_PACKET 0x2 + +union nl_packet { + /* Network packet header of the first packet (a special case) */ + struct nl_first_packet_header hdr_first; + /* Network packet header of the following packets (if any) */ + struct nl_packet_header hdr; + /* Complete network packet (header + data) */ + unsigned char rawpkt[LL_MTU_MAX]; +} __attribute__ ((__packed__)); + +#define HW_VERSION_UNKNOWN -1 +#define HW_VERSION_1 1 +#define HW_VERSION_2 2 + +/* IPW I/O ports */ +#define IOIER 0x00 /* Interrupt Enable Register */ +#define IOIR 0x02 /* Interrupt Source/ACK register */ +#define IODCR 0x04 /* Data Control Register */ +#define IODRR 0x06 /* Data Read Register */ +#define IODWR 0x08 /* Data Write Register */ +#define IOESR 0x0A /* Embedded Driver Status Register */ +#define IORXR 0x0C /* Rx Fifo Register (Host to Embedded) */ +#define IOTXR 0x0E /* Tx Fifo Register (Embedded to Host) */ + +/* I/O ports and bit definitions for version 1 of the hardware */ + +/* IER bits*/ +#define IER_RXENABLED 0x1 +#define IER_TXENABLED 0x2 + +/* ISR bits */ +#define IR_RXINTR 0x1 +#define IR_TXINTR 0x2 + +/* DCR bits */ +#define DCR_RXDONE 0x1 +#define DCR_TXDONE 0x2 +#define DCR_RXRESET 0x4 +#define DCR_TXRESET 0x8 + +/* I/O ports and bit definitions for version 2 of the hardware */ + +struct MEMCCR { + unsigned short reg_config_option; /* PCCOR: Configuration Option Register */ + unsigned short reg_config_and_status; /* PCCSR: Configuration and Status Register */ + unsigned short reg_pin_replacement; /* PCPRR: Pin Replacemant Register */ + unsigned short reg_socket_and_copy; /* PCSCR: Socket and Copy Register */ + unsigned short reg_ext_status; /* PCESR: Extendend Status Register */ + unsigned short reg_io_base; /* PCIOB: I/O Base Register */ +}; + +struct MEMINFREG { + unsigned short memreg_tx_old; /* TX Register (R/W) */ + unsigned short pad1; + unsigned short memreg_rx_done; /* RXDone Register (R/W) */ + unsigned short pad2; + unsigned short memreg_rx; /* RX Register (R/W) */ + unsigned short pad3; + unsigned short memreg_pc_interrupt_ack; /* PC intr Ack Register (W) */ + unsigned short pad4; + unsigned long memreg_card_present;/* Mask for Host to check (R) for + * CARD_PRESENT_VALUE */ + unsigned short memreg_tx_new; /* TX2 (new) Register (R/W) */ +}; + +#define CARD_PRESENT_VALUE (0xBEEFCAFEUL) + +#define MEMTX_TX 0x0001 +#define MEMRX_RX 0x0001 +#define MEMRX_RX_DONE 0x0001 +#define MEMRX_PCINTACKK 0x0001 + +#define NL_NUM_OF_PRIORITIES 3 +#define NL_NUM_OF_PROTOCOLS 3 +#define NL_NUM_OF_ADDRESSES NO_OF_IPW_CHANNELS + +struct ipw_hardware { + unsigned int base_port; + short hw_version; + unsigned short ll_mtu; + spinlock_t lock; + + int initializing; + int init_loops; + struct timer_list setup_timer; + + /* Flag if hw is ready to send next packet */ + int tx_ready; + /* Count of pending packets to be sent */ + int tx_queued; + struct list_head tx_queue[NL_NUM_OF_PRIORITIES]; + + int rx_bytes_queued; + struct list_head rx_queue; + /* Pool of rx_packet structures that are not currently used. */ + struct list_head rx_pool; + int rx_pool_size; + /* True if reception of data is blocked while userspace processes it. */ + int blocking_rx; + /* True if there is RX data ready on the hardware. */ + int rx_ready; + unsigned short last_memtx_serial; + /* + * Newer versions of the V2 card firmware send serial numbers in the + * MemTX register. 'serial_number_detected' is set true when we detect + * a non-zero serial number (indicating the new firmware). Thereafter, + * the driver can safely ignore the Timer Recovery re-sends to avoid + * out-of-sync problems. + */ + int serial_number_detected; + struct work_struct work_rx; + + /* True if we are to send the set-up data to the hardware. */ + int to_setup; + + /* Card has been removed */ + int removed; + /* Saved irq value when we disable the interrupt. */ + int irq; + /* True if this driver is shutting down. */ + int shutting_down; + /* Modem control lines */ + unsigned int control_lines[NL_NUM_OF_ADDRESSES]; + struct ipw_rx_packet *packet_assembler[NL_NUM_OF_ADDRESSES]; + + struct tasklet_struct tasklet; + + /* The handle for the network layer, for the sending of events to it. */ + struct ipw_network *network; + struct MEMINFREG __iomem *memory_info_regs; + struct MEMCCR __iomem *memregs_CCR; + void (*reboot_callback) (void *data); + void *reboot_callback_data; + + unsigned short __iomem *memreg_tx; +}; + +/* + * Packet info structure for tx packets. + * Note: not all the fields defined here are required for all protocols + */ +struct ipw_tx_packet { + struct list_head queue; + /* channel idx + 1 */ + unsigned char dest_addr; + /* SETUP, CTRL or DATA */ + unsigned char protocol; + /* Length of data block, which starts at the end of this structure */ + unsigned short length; + /* Sending state */ + /* Offset of where we've sent up to so far */ + unsigned long offset; + /* Count of packet fragments, starting at 0 */ + int fragment_count; + + /* Called after packet is sent and before is freed */ + void (*packet_callback) (void *cb_data, unsigned int packet_length); + void *callback_data; +}; + +/* Signals from DTE */ +#define COMCTRL_RTS 0 +#define COMCTRL_DTR 1 + +/* Signals from DCE */ +#define COMCTRL_CTS 2 +#define COMCTRL_DCD 3 +#define COMCTRL_DSR 4 +#define COMCTRL_RI 5 + +struct ipw_control_packet_body { + /* DTE signal or DCE signal */ + unsigned char sig_no; + /* 0: set signal, 1: clear signal */ + unsigned char value; +} __attribute__ ((__packed__)); + +struct ipw_control_packet { + struct ipw_tx_packet header; + struct ipw_control_packet_body body; +}; + +struct ipw_rx_packet { + struct list_head queue; + unsigned int capacity; + unsigned int length; + unsigned int protocol; + unsigned int channel_idx; +}; + +static char *data_type(const unsigned char *buf, unsigned length) +{ + struct nl_packet_header *hdr = (struct nl_packet_header *) buf; + + if (length == 0) + return " "; + + if (hdr->packet_rank & NL_FIRST_PACKET) { + switch (hdr->protocol) { + case TL_PROTOCOLID_COM_DATA: return "DATA "; + case TL_PROTOCOLID_COM_CTRL: return "CTRL "; + case TL_PROTOCOLID_SETUP: return "SETUP"; + default: return "???? "; + } + } else + return " "; +} + +#define DUMP_MAX_BYTES 64 + +static void dump_data_bytes(const char *type, const unsigned char *data, + unsigned length) +{ + char prefix[56]; + + sprintf(prefix, IPWIRELESS_PCCARD_NAME ": %s %s ", + type, data_type(data, length)); + print_hex_dump_bytes(prefix, 0, (void *)data, + length < DUMP_MAX_BYTES ? length : DUMP_MAX_BYTES); +} + +static void swap_packet_bitfield_to_le(unsigned char *data) +{ +#ifdef __BIG_ENDIAN_BITFIELD + unsigned char tmp = *data, ret = 0; + + /* + * transform bits from aa.bbb.ccc to ccc.bbb.aa + */ + ret |= tmp & 0xc0 >> 6; + ret |= tmp & 0x38 >> 1; + ret |= tmp & 0x07 << 5; + *data = ret & 0xff; +#endif +} + +static void swap_packet_bitfield_from_le(unsigned char *data) +{ +#ifdef __BIG_ENDIAN_BITFIELD + unsigned char tmp = *data, ret = 0; + + /* + * transform bits from ccc.bbb.aa to aa.bbb.ccc + */ + ret |= tmp & 0xe0 >> 5; + ret |= tmp & 0x1c << 1; + ret |= tmp & 0x03 << 6; + *data = ret & 0xff; +#endif +} + +static void do_send_fragment(struct ipw_hardware *hw, unsigned char *data, + unsigned length) +{ + unsigned i; + unsigned long flags; + + start_timing(); + BUG_ON(length > hw->ll_mtu); + + if (ipwireless_debug) + dump_data_bytes("send", data, length); + + spin_lock_irqsave(&hw->lock, flags); + + hw->tx_ready = 0; + swap_packet_bitfield_to_le(data); + + if (hw->hw_version == HW_VERSION_1) { + outw((unsigned short) length, hw->base_port + IODWR); + + for (i = 0; i < length; i += 2) { + unsigned short d = data[i]; + __le16 raw_data; + + if (i + 1 < length) + d |= data[i + 1] << 8; + raw_data = cpu_to_le16(d); + outw(raw_data, hw->base_port + IODWR); + } + + outw(DCR_TXDONE, hw->base_port + IODCR); + } else if (hw->hw_version == HW_VERSION_2) { + outw((unsigned short) length, hw->base_port); + + for (i = 0; i < length; i += 2) { + unsigned short d = data[i]; + __le16 raw_data; + + if (i + 1 < length) + d |= data[i + 1] << 8; + raw_data = cpu_to_le16(d); + outw(raw_data, hw->base_port); + } + while ((i & 3) != 2) { + outw((unsigned short) 0xDEAD, hw->base_port); + i += 2; + } + writew(MEMRX_RX, &hw->memory_info_regs->memreg_rx); + } + + spin_unlock_irqrestore(&hw->lock, flags); + + end_write_timing(length); +} + +static void do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet) +{ + unsigned short fragment_data_len; + unsigned short data_left = packet->length - packet->offset; + unsigned short header_size; + union nl_packet pkt; + + header_size = + (packet->fragment_count == 0) + ? NL_FIRST_PACKET_HEADER_SIZE + : NL_FOLLOWING_PACKET_HEADER_SIZE; + fragment_data_len = hw->ll_mtu - header_size; + if (data_left < fragment_data_len) + fragment_data_len = data_left; + + /* + * hdr_first is now in machine bitfield order, which will be swapped + * to le just before it goes to hw + */ + pkt.hdr_first.protocol = packet->protocol; + pkt.hdr_first.address = packet->dest_addr; + pkt.hdr_first.packet_rank = 0; + + /* First packet? */ + if (packet->fragment_count == 0) { + pkt.hdr_first.packet_rank |= NL_FIRST_PACKET; + pkt.hdr_first.length_lsb = (unsigned char) packet->length; + pkt.hdr_first.length_msb = + (unsigned char) (packet->length >> 8); + } + + memcpy(pkt.rawpkt + header_size, + ((unsigned char *) packet) + sizeof(struct ipw_tx_packet) + + packet->offset, fragment_data_len); + packet->offset += fragment_data_len; + packet->fragment_count++; + + /* Last packet? (May also be first packet.) */ + if (packet->offset == packet->length) + pkt.hdr_first.packet_rank |= NL_LAST_PACKET; + do_send_fragment(hw, pkt.rawpkt, header_size + fragment_data_len); + + /* If this packet has unsent data, then re-queue it. */ + if (packet->offset < packet->length) { + /* + * Re-queue it at the head of the highest priority queue so + * it goes before all other packets + */ + unsigned long flags; + + spin_lock_irqsave(&hw->lock, flags); + list_add(&packet->queue, &hw->tx_queue[0]); + hw->tx_queued++; + spin_unlock_irqrestore(&hw->lock, flags); + } else { + if (packet->packet_callback) + packet->packet_callback(packet->callback_data, + packet->length); + kfree(packet); + } +} + +static void ipw_setup_hardware(struct ipw_hardware *hw) +{ + unsigned long flags; + + spin_lock_irqsave(&hw->lock, flags); + if (hw->hw_version == HW_VERSION_1) { + /* Reset RX FIFO */ + outw(DCR_RXRESET, hw->base_port + IODCR); + /* SB: Reset TX FIFO */ + outw(DCR_TXRESET, hw->base_port + IODCR); + + /* Enable TX and RX interrupts. */ + outw(IER_TXENABLED | IER_RXENABLED, hw->base_port + IOIER); + } else { + /* + * Set INTRACK bit (bit 0), which means we must explicitly + * acknowledge interrupts by clearing bit 2 of reg_config_and_status. + */ + unsigned short csr = readw(&hw->memregs_CCR->reg_config_and_status); + + csr |= 1; + writew(csr, &hw->memregs_CCR->reg_config_and_status); + } + spin_unlock_irqrestore(&hw->lock, flags); +} + +/* + * If 'packet' is NULL, then this function allocates a new packet, setting its + * length to 0 and ensuring it has the specified minimum amount of free space. + * + * If 'packet' is not NULL, then this function enlarges it if it doesn't + * have the specified minimum amount of free space. + * + */ +static struct ipw_rx_packet *pool_allocate(struct ipw_hardware *hw, + struct ipw_rx_packet *packet, + int minimum_free_space) +{ + + if (!packet) { + unsigned long flags; + + spin_lock_irqsave(&hw->lock, flags); + if (!list_empty(&hw->rx_pool)) { + packet = list_first_entry(&hw->rx_pool, + struct ipw_rx_packet, queue); + hw->rx_pool_size--; + spin_unlock_irqrestore(&hw->lock, flags); + list_del(&packet->queue); + } else { + const int min_capacity = + ipwireless_ppp_mru(hw->network) + 2; + int new_capacity; + + spin_unlock_irqrestore(&hw->lock, flags); + new_capacity = + (minimum_free_space > min_capacity + ? minimum_free_space + : min_capacity); + packet = kmalloc(sizeof(struct ipw_rx_packet) + + new_capacity, GFP_ATOMIC); + if (!packet) + return NULL; + packet->capacity = new_capacity; + } + packet->length = 0; + } + + if (packet->length + minimum_free_space > packet->capacity) { + struct ipw_rx_packet *old_packet = packet; + + packet = kmalloc(sizeof(struct ipw_rx_packet) + + old_packet->length + minimum_free_space, + GFP_ATOMIC); + if (!packet) { + kfree(old_packet); + return NULL; + } + memcpy(packet, old_packet, + sizeof(struct ipw_rx_packet) + + old_packet->length); + packet->capacity = old_packet->length + minimum_free_space; + kfree(old_packet); + } + + return packet; +} + +static void pool_free(struct ipw_hardware *hw, struct ipw_rx_packet *packet) +{ + if (hw->rx_pool_size > 6) + kfree(packet); + else { + hw->rx_pool_size++; + list_add(&packet->queue, &hw->rx_pool); + } +} + +static void queue_received_packet(struct ipw_hardware *hw, + unsigned int protocol, + unsigned int address, + const unsigned char *data, int length, + int is_last) +{ + unsigned int channel_idx = address - 1; + struct ipw_rx_packet *packet = NULL; + unsigned long flags; + + /* Discard packet if channel index is out of range. */ + if (channel_idx >= NL_NUM_OF_ADDRESSES) { + printk(KERN_INFO IPWIRELESS_PCCARD_NAME + ": data packet has bad address %u\n", address); + return; + } + + /* + * ->packet_assembler is safe to touch unlocked, this is the only place + */ + if (protocol == TL_PROTOCOLID_COM_DATA) { + struct ipw_rx_packet **assem = + &hw->packet_assembler[channel_idx]; + + /* + * Create a new packet, or assembler already contains one + * enlarge it by 'length' bytes. + */ + (*assem) = pool_allocate(hw, *assem, length); + if (!(*assem)) { + printk(KERN_ERR IPWIRELESS_PCCARD_NAME + ": no memory for incomming data packet, dropped!\n"); + return; + } + (*assem)->protocol = protocol; + (*assem)->channel_idx = channel_idx; + + /* Append this packet data onto existing data. */ + memcpy((unsigned char *)(*assem) + + sizeof(struct ipw_rx_packet) + + (*assem)->length, data, length); + (*assem)->length += length; + if (is_last) { + packet = *assem; + *assem = NULL; + /* Count queued DATA bytes only */ + spin_lock_irqsave(&hw->lock, flags); + hw->rx_bytes_queued += packet->length; + spin_unlock_irqrestore(&hw->lock, flags); + } + } else { + /* If it's a CTRL packet, don't assemble, just queue it. */ + packet = pool_allocate(hw, NULL, length); + if (!packet) { + printk(KERN_ERR IPWIRELESS_PCCARD_NAME + ": no memory for incomming ctrl packet, dropped!\n"); + return; + } + packet->protocol = protocol; + packet->channel_idx = channel_idx; + memcpy((unsigned char *)packet + sizeof(struct ipw_rx_packet), + data, length); + packet->length = length; + } + + /* + * If this is the last packet, then send the assembled packet on to the + * network layer. + */ + if (packet) { + spin_lock_irqsave(&hw->lock, flags); + list_add_tail(&packet->queue, &hw->rx_queue); + /* Block reception of incoming packets if queue is full. */ + hw->blocking_rx = + (hw->rx_bytes_queued >= IPWIRELESS_RX_QUEUE_SIZE); + + spin_unlock_irqrestore(&hw->lock, flags); + schedule_work(&hw->work_rx); + } +} + +/* + * Workqueue callback + */ +static void ipw_receive_data_work(struct work_struct *work_rx) +{ + struct ipw_hardware *hw = + container_of(work_rx, struct ipw_hardware, work_rx); + unsigned long flags; + + spin_lock_irqsave(&hw->lock, flags); + while (!list_empty(&hw->rx_queue)) { + struct ipw_rx_packet *packet = + list_first_entry(&hw->rx_queue, + struct ipw_rx_packet, queue); + + if (hw->shutting_down) + break; + list_del(&packet->queue); + + /* + * Note: ipwireless_network_packet_received must be called in a + * process context (i.e. via schedule_work) because the tty + * output code can sleep in the tty_flip_buffer_push call. + */ + if (packet->protocol == TL_PROTOCOLID_COM_DATA) { + if (hw->network != NULL) { + /* If the network hasn't been disconnected. */ + spin_unlock_irqrestore(&hw->lock, flags); + /* + * This must run unlocked due to tty processing + * and mutex locking + */ + ipwireless_network_packet_received( + hw->network, + packet->channel_idx, + (unsigned char *)packet + + sizeof(struct ipw_rx_packet), + packet->length); + spin_lock_irqsave(&hw->lock, flags); + } + /* Count queued DATA bytes only */ + hw->rx_bytes_queued -= packet->length; + } else { + /* + * This is safe to be called locked, callchain does + * not block + */ + handle_received_CTRL_packet(hw, packet->channel_idx, + (unsigned char *)packet + + sizeof(struct ipw_rx_packet), + packet->length); + } + pool_free(hw, packet); + /* + * Unblock reception of incoming packets if queue is no longer + * full. + */ + hw->blocking_rx = + hw->rx_bytes_queued >= IPWIRELESS_RX_QUEUE_SIZE; + if (hw->shutting_down) + break; + } + spin_unlock_irqrestore(&hw->lock, flags); +} + +static void handle_received_CTRL_packet(struct ipw_hardware *hw, + unsigned int channel_idx, + const unsigned char *data, int len) +{ + const struct ipw_control_packet_body *body = + (const struct ipw_control_packet_body *) data; + unsigned int changed_mask; + + if (len != sizeof(struct ipw_control_packet_body)) { + printk(KERN_INFO IPWIRELESS_PCCARD_NAME + ": control packet was %d bytes - wrong size!\n", + len); + return; + } + + switch (body->sig_no) { + case COMCTRL_CTS: + changed_mask = IPW_CONTROL_LINE_CTS; + break; + case COMCTRL_DCD: + changed_mask = IPW_CONTROL_LINE_DCD; + break; + case COMCTRL_DSR: + changed_mask = IPW_CONTROL_LINE_DSR; + break; + case COMCTRL_RI: + changed_mask = IPW_CONTROL_LINE_RI; + break; + default: + changed_mask = 0; + } + + if (changed_mask != 0) { + if (body->value) + hw->control_lines[channel_idx] |= changed_mask; + else + hw->control_lines[channel_idx] &= ~changed_mask; + if (hw->network) + ipwireless_network_notify_control_line_change( + hw->network, + channel_idx, + hw->control_lines[channel_idx], + changed_mask); + } +} + +static void handle_received_packet(struct ipw_hardware *hw, + const union nl_packet *packet, + unsigned short len) +{ + unsigned int protocol = packet->hdr.protocol; + unsigned int address = packet->hdr.address; + unsigned int header_length; + const unsigned char *data; + unsigned int data_len; + int is_last = packet->hdr.packet_rank & NL_LAST_PACKET; + + if (packet->hdr.packet_rank & NL_FIRST_PACKET) + header_length = NL_FIRST_PACKET_HEADER_SIZE; + else + header_length = NL_FOLLOWING_PACKET_HEADER_SIZE; + + data = packet->rawpkt + header_length; + data_len = len - header_length; + switch (protocol) { + case TL_PROTOCOLID_COM_DATA: + case TL_PROTOCOLID_COM_CTRL: + queue_received_packet(hw, protocol, address, data, data_len, + is_last); + break; + case TL_PROTOCOLID_SETUP: + handle_received_SETUP_packet(hw, address, data, data_len, + is_last); + break; + } +} + +static void acknowledge_data_read(struct ipw_hardware *hw) +{ + if (hw->hw_version == HW_VERSION_1) + outw(DCR_RXDONE, hw->base_port + IODCR); + else + writew(MEMRX_PCINTACKK, + &hw->memory_info_regs->memreg_pc_interrupt_ack); +} + +/* + * Retrieve a packet from the IPW hardware. + */ +static void do_receive_packet(struct ipw_hardware *hw) +{ + unsigned len; + unsigned i; + unsigned char pkt[LL_MTU_MAX]; + + start_timing(); + + if (hw->hw_version == HW_VERSION_1) { + len = inw(hw->base_port + IODRR); + if (len > hw->ll_mtu) { + printk(KERN_INFO IPWIRELESS_PCCARD_NAME + ": received a packet of %u bytes - longer than the MTU!\n", len); + outw(DCR_RXDONE | DCR_RXRESET, hw->base_port + IODCR); + return; + } + + for (i = 0; i < len; i += 2) { + __le16 raw_data = inw(hw->base_port + IODRR); + unsigned short data = le16_to_cpu(raw_data); + + pkt[i] = (unsigned char) data; + pkt[i + 1] = (unsigned char) (data >> 8); + } + } else { + len = inw(hw->base_port); + if (len > hw->ll_mtu) { + printk(KERN_INFO IPWIRELESS_PCCARD_NAME + ": received a packet of %u bytes - longer than the MTU!\n", len); + writew(MEMRX_PCINTACKK, + &hw->memory_info_regs->memreg_pc_interrupt_ack); + return; + } + + for (i = 0; i < len; i += 2) { + __le16 raw_data = inw(hw->base_port); + unsigned short data = le16_to_cpu(raw_data); + + pkt[i] = (unsigned char) data; + pkt[i + 1] = (unsigned char) (data >> 8); + } + + while ((i & 3) != 2) { + inw(hw->base_port); + i += 2; + } + } + + acknowledge_data_read(hw); + + swap_packet_bitfield_from_le(pkt); + + if (ipwireless_debug) + dump_data_bytes("recv", pkt, len); + + handle_received_packet(hw, (union nl_packet *) pkt, len); + + end_read_timing(len); +} + +static int get_current_packet_priority(struct ipw_hardware *hw) +{ + /* + * If we're initializing, don't send anything of higher priority than + * PRIO_SETUP. The network layer therefore need not care about + * hardware initialization - any of its stuff will simply be queued + * until setup is complete. + */ + return (hw->to_setup || hw->initializing + ? PRIO_SETUP + 1 : NL_NUM_OF_PRIORITIES); +} + +/* + * return 1 if something has been received from hw + */ +static int get_packets_from_hw(struct ipw_hardware *hw) +{ + int received = 0; + unsigned long flags; + + spin_lock_irqsave(&hw->lock, flags); + while (hw->rx_ready && !hw->blocking_rx) { + received = 1; + hw->rx_ready--; + spin_unlock_irqrestore(&hw->lock, flags); + + do_receive_packet(hw); + + spin_lock_irqsave(&hw->lock, flags); + } + spin_unlock_irqrestore(&hw->lock, flags); + + return received; +} + +/* + * Send pending packet up to given priority, prioritize SETUP data until + * hardware is fully setup. + * + * return 1 if more packets can be sent + */ +static int send_pending_packet(struct ipw_hardware *hw, int priority_limit) +{ + int more_to_send = 0; + unsigned long flags; + + spin_lock_irqsave(&hw->lock, flags); + if (hw->tx_queued && hw->tx_ready) { + int priority; + struct ipw_tx_packet *packet = NULL; + + /* Pick a packet */ + for (priority = 0; priority < priority_limit; priority++) { + if (!list_empty(&hw->tx_queue[priority])) { + packet = list_first_entry( + &hw->tx_queue[priority], + struct ipw_tx_packet, + queue); + + hw->tx_queued--; + list_del(&packet->queue); + + break; + } + } + if (!packet) { + hw->tx_queued = 0; + spin_unlock_irqrestore(&hw->lock, flags); + return 0; + } + + spin_unlock_irqrestore(&hw->lock, flags); + + /* Send */ + do_send_packet(hw, packet); + + /* Check if more to send */ + spin_lock_irqsave(&hw->lock, flags); + for (priority = 0; priority < priority_limit; priority++) + if (!list_empty(&hw->tx_queue[priority])) { + more_to_send = 1; + break; + } + + if (!more_to_send) + hw->tx_queued = 0; + } + spin_unlock_irqrestore(&hw->lock, flags); + + return more_to_send; +} + +/* + * Send and receive all queued packets. + */ +static void ipwireless_do_tasklet(unsigned long hw_) +{ + struct ipw_hardware *hw = (struct ipw_hardware *) hw_; + unsigned long flags; + + spin_lock_irqsave(&hw->lock, flags); + if (hw->shutting_down) { + spin_unlock_irqrestore(&hw->lock, flags); + return; + } + + if (hw->to_setup == 1) { + /* + * Initial setup data sent to hardware + */ + hw->to_setup = 2; + spin_unlock_irqrestore(&hw->lock, flags); + + ipw_setup_hardware(hw); + ipw_send_setup_packet(hw); + + send_pending_packet(hw, PRIO_SETUP + 1); + get_packets_from_hw(hw); + } else { + int priority_limit = get_current_packet_priority(hw); + int again; + + spin_unlock_irqrestore(&hw->lock, flags); + + do { + again = send_pending_packet(hw, priority_limit); + again |= get_packets_from_hw(hw); + } while (again); + } +} + +/* + * return true if the card is physically present. + */ +static int is_card_present(struct ipw_hardware *hw) +{ + if (hw->hw_version == HW_VERSION_1) + return inw(hw->base_port + IOIR) != 0xFFFF; + else + return readl(&hw->memory_info_regs->memreg_card_present) == + CARD_PRESENT_VALUE; +} + +static irqreturn_t ipwireless_handle_v1_interrupt(int irq, + struct ipw_hardware *hw) +{ + unsigned short irqn; + + irqn = inw(hw->base_port + IOIR); + + /* Check if card is present */ + if (irqn == 0xFFFF) + return IRQ_NONE; + else if (irqn != 0) { + unsigned short ack = 0; + unsigned long flags; + + /* Transmit complete. */ + if (irqn & IR_TXINTR) { + ack |= IR_TXINTR; + spin_lock_irqsave(&hw->lock, flags); + hw->tx_ready = 1; + spin_unlock_irqrestore(&hw->lock, flags); + } + /* Received data */ + if (irqn & IR_RXINTR) { + ack |= IR_RXINTR; + spin_lock_irqsave(&hw->lock, flags); + hw->rx_ready++; + spin_unlock_irqrestore(&hw->lock, flags); + } + if (ack != 0) { + outw(ack, hw->base_port + IOIR); + tasklet_schedule(&hw->tasklet); + } + return IRQ_HANDLED; + } + return IRQ_NONE; +} + +static void acknowledge_pcmcia_interrupt(struct ipw_hardware *hw) +{ + unsigned short csr = readw(&hw->memregs_CCR->reg_config_and_status); + + csr &= 0xfffd; + writew(csr, &hw->memregs_CCR->reg_config_and_status); +} + +static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq, + struct ipw_hardware *hw) +{ + int tx = 0; + int rx = 0; + int rx_repeat = 0; + int try_mem_tx_old; + unsigned long flags; + + do { + + unsigned short memtx = readw(hw->memreg_tx); + unsigned short memtx_serial; + unsigned short memrxdone = + readw(&hw->memory_info_regs->memreg_rx_done); + + try_mem_tx_old = 0; + + /* check whether the interrupt was generated by ipwireless card */ + if (!(memtx & MEMTX_TX) && !(memrxdone & MEMRX_RX_DONE)) { + + /* check if the card uses memreg_tx_old register */ + if (hw->memreg_tx == &hw->memory_info_regs->memreg_tx_new) { + memtx = readw(&hw->memory_info_regs->memreg_tx_old); + if (memtx & MEMTX_TX) { + printk(KERN_INFO IPWIRELESS_PCCARD_NAME + ": Using memreg_tx_old\n"); + hw->memreg_tx = + &hw->memory_info_regs->memreg_tx_old; + } else { + return IRQ_NONE; + } + } else + return IRQ_NONE; + } + + /* + * See if the card is physically present. Note that while it is + * powering up, it appears not to be present. + */ + if (!is_card_present(hw)) { + acknowledge_pcmcia_interrupt(hw); + return IRQ_HANDLED; + } + + memtx_serial = memtx & (unsigned short) 0xff00; + if (memtx & MEMTX_TX) { + writew(memtx_serial, hw->memreg_tx); + + if (hw->serial_number_detected) { + if (memtx_serial != hw->last_memtx_serial) { + hw->last_memtx_serial = memtx_serial; + spin_lock_irqsave(&hw->lock, flags); + hw->rx_ready++; + spin_unlock_irqrestore(&hw->lock, flags); + rx = 1; + } else + /* Ignore 'Timer Recovery' duplicates. */ + rx_repeat = 1; + } else { + /* + * If a non-zero serial number is seen, then enable + * serial number checking. + */ + if (memtx_serial != 0) { + hw->serial_number_detected = 1; + printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME + ": memreg_tx serial num detected\n"); + + spin_lock_irqsave(&hw->lock, flags); + hw->rx_ready++; + spin_unlock_irqrestore(&hw->lock, flags); + } + rx = 1; + } + } + if (memrxdone & MEMRX_RX_DONE) { + writew(0, &hw->memory_info_regs->memreg_rx_done); + spin_lock_irqsave(&hw->lock, flags); + hw->tx_ready = 1; + spin_unlock_irqrestore(&hw->lock, flags); + tx = 1; + } + if (tx) + writew(MEMRX_PCINTACKK, + &hw->memory_info_regs->memreg_pc_interrupt_ack); + + acknowledge_pcmcia_interrupt(hw); + + if (tx || rx) + tasklet_schedule(&hw->tasklet); + else if (!rx_repeat) { + if (hw->memreg_tx == &hw->memory_info_regs->memreg_tx_new) { + if (hw->serial_number_detected) + printk(KERN_WARNING IPWIRELESS_PCCARD_NAME + ": spurious interrupt - new_tx mode\n"); + else { + printk(KERN_WARNING IPWIRELESS_PCCARD_NAME + ": no valid memreg_tx value - switching to the old memreg_tx\n"); + hw->memreg_tx = + &hw->memory_info_regs->memreg_tx_old; + try_mem_tx_old = 1; + } + } else + printk(KERN_WARNING IPWIRELESS_PCCARD_NAME + ": spurious interrupt - old_tx mode\n"); + } + + } while (try_mem_tx_old == 1); + + return IRQ_HANDLED; +} + +irqreturn_t ipwireless_interrupt(int irq, void *dev_id) +{ + struct ipw_dev *ipw = dev_id; + + if (ipw->hardware->hw_version == HW_VERSION_1) + return ipwireless_handle_v1_interrupt(irq, ipw->hardware); + else + return ipwireless_handle_v2_v3_interrupt(irq, ipw->hardware); +} + +static void flush_packets_to_hw(struct ipw_hardware *hw) +{ + int priority_limit; + unsigned long flags; + + spin_lock_irqsave(&hw->lock, flags); + priority_limit = get_current_packet_priority(hw); + spin_unlock_irqrestore(&hw->lock, flags); + + while (send_pending_packet(hw, priority_limit)); +} + +static void send_packet(struct ipw_hardware *hw, int priority, + struct ipw_tx_packet *packet) +{ + unsigned long flags; + + spin_lock_irqsave(&hw->lock, flags); + list_add_tail(&packet->queue, &hw->tx_queue[priority]); + hw->tx_queued++; + spin_unlock_irqrestore(&hw->lock, flags); + + flush_packets_to_hw(hw); +} + +/* Create data packet, non-atomic allocation */ +static void *alloc_data_packet(int data_size, + unsigned char dest_addr, + unsigned char protocol) +{ + struct ipw_tx_packet *packet = kzalloc( + sizeof(struct ipw_tx_packet) + data_size, + GFP_ATOMIC); + + if (!packet) + return NULL; + + INIT_LIST_HEAD(&packet->queue); + packet->dest_addr = dest_addr; + packet->protocol = protocol; + packet->length = data_size; + + return packet; +} + +static void *alloc_ctrl_packet(int header_size, + unsigned char dest_addr, + unsigned char protocol, + unsigned char sig_no) +{ + /* + * sig_no is located right after ipw_tx_packet struct in every + * CTRL or SETUP packets, we can use ipw_control_packet as a + * common struct + */ + struct ipw_control_packet *packet = kzalloc(header_size, GFP_ATOMIC); + + if (!packet) + return NULL; + + INIT_LIST_HEAD(&packet->header.queue); + packet->header.dest_addr = dest_addr; + packet->header.protocol = protocol; + packet->header.length = header_size - sizeof(struct ipw_tx_packet); + packet->body.sig_no = sig_no; + + return packet; +} + +int ipwireless_send_packet(struct ipw_hardware *hw, unsigned int channel_idx, + const unsigned char *data, unsigned int length, + void (*callback) (void *cb, unsigned int length), + void *callback_data) +{ + struct ipw_tx_packet *packet; + + packet = alloc_data_packet(length, (channel_idx + 1), + TL_PROTOCOLID_COM_DATA); + if (!packet) + return -ENOMEM; + packet->packet_callback = callback; + packet->callback_data = callback_data; + memcpy((unsigned char *) packet + sizeof(struct ipw_tx_packet), data, + length); + + send_packet(hw, PRIO_DATA, packet); + return 0; +} + +static int set_control_line(struct ipw_hardware *hw, int prio, + unsigned int channel_idx, int line, int state) +{ + struct ipw_control_packet *packet; + int protocolid = TL_PROTOCOLID_COM_CTRL; + + if (prio == PRIO_SETUP) + protocolid = TL_PROTOCOLID_SETUP; + + packet = alloc_ctrl_packet(sizeof(struct ipw_control_packet), + (channel_idx + 1), protocolid, line); + if (!packet) + return -ENOMEM; + packet->header.length = sizeof(struct ipw_control_packet_body); + packet->body.value = (state == 0 ? 0 : 1); + send_packet(hw, prio, &packet->header); + return 0; +} + + +static int set_DTR(struct ipw_hardware *hw, int priority, + unsigned int channel_idx, int state) +{ + if (state != 0) + hw->control_lines[channel_idx] |= IPW_CONTROL_LINE_DTR; + else + hw->control_lines[channel_idx] &= ~IPW_CONTROL_LINE_DTR; + + return set_control_line(hw, priority, channel_idx, COMCTRL_DTR, state); +} + +static int set_RTS(struct ipw_hardware *hw, int priority, + unsigned int channel_idx, int state) +{ + if (state != 0) + hw->control_lines[channel_idx] |= IPW_CONTROL_LINE_RTS; + else + hw->control_lines[channel_idx] &= ~IPW_CONTROL_LINE_RTS; + + return set_control_line(hw, priority, channel_idx, COMCTRL_RTS, state); +} + +int ipwireless_set_DTR(struct ipw_hardware *hw, unsigned int channel_idx, + int state) +{ + return set_DTR(hw, PRIO_CTRL, channel_idx, state); +} + +int ipwireless_set_RTS(struct ipw_hardware *hw, unsigned int channel_idx, + int state) +{ + return set_RTS(hw, PRIO_CTRL, channel_idx, state); +} + +struct ipw_setup_get_version_query_packet { + struct ipw_tx_packet header; + struct tl_setup_get_version_qry body; +}; + +struct ipw_setup_config_packet { + struct ipw_tx_packet header; + struct tl_setup_config_msg body; +}; + +struct ipw_setup_config_done_packet { + struct ipw_tx_packet header; + struct tl_setup_config_done_msg body; +}; + +struct ipw_setup_open_packet { + struct ipw_tx_packet header; + struct tl_setup_open_msg body; +}; + +struct ipw_setup_info_packet { + struct ipw_tx_packet header; + struct tl_setup_info_msg body; +}; + +struct ipw_setup_reboot_msg_ack { + struct ipw_tx_packet header; + struct TlSetupRebootMsgAck body; +}; + +/* This handles the actual initialization of the card */ +static void __handle_setup_get_version_rsp(struct ipw_hardware *hw) +{ + struct ipw_setup_config_packet *config_packet; + struct ipw_setup_config_done_packet *config_done_packet; + struct ipw_setup_open_packet *open_packet; + struct ipw_setup_info_packet *info_packet; + int port; + unsigned int channel_idx; + + /* generate config packet */ + for (port = 1; port <= NL_NUM_OF_ADDRESSES; port++) { + config_packet = alloc_ctrl_packet( + sizeof(struct ipw_setup_config_packet), + ADDR_SETUP_PROT, + TL_PROTOCOLID_SETUP, + TL_SETUP_SIGNO_CONFIG_MSG); + if (!config_packet) + goto exit_nomem; + config_packet->header.length = sizeof(struct tl_setup_config_msg); + config_packet->body.port_no = port; + config_packet->body.prio_data = PRIO_DATA; + config_packet->body.prio_ctrl = PRIO_CTRL; + send_packet(hw, PRIO_SETUP, &config_packet->header); + } + config_done_packet = alloc_ctrl_packet( + sizeof(struct ipw_setup_config_done_packet), + ADDR_SETUP_PROT, + TL_PROTOCOLID_SETUP, + TL_SETUP_SIGNO_CONFIG_DONE_MSG); + if (!config_done_packet) + goto exit_nomem; + config_done_packet->header.length = sizeof(struct tl_setup_config_done_msg); + send_packet(hw, PRIO_SETUP, &config_done_packet->header); + + /* generate open packet */ + for (port = 1; port <= NL_NUM_OF_ADDRESSES; port++) { + open_packet = alloc_ctrl_packet( + sizeof(struct ipw_setup_open_packet), + ADDR_SETUP_PROT, + TL_PROTOCOLID_SETUP, + TL_SETUP_SIGNO_OPEN_MSG); + if (!open_packet) + goto exit_nomem; + open_packet->header.length = sizeof(struct tl_setup_open_msg); + open_packet->body.port_no = port; + send_packet(hw, PRIO_SETUP, &open_packet->header); + } + for (channel_idx = 0; + channel_idx < NL_NUM_OF_ADDRESSES; channel_idx++) { + int ret; + + ret = set_DTR(hw, PRIO_SETUP, channel_idx, + (hw->control_lines[channel_idx] & + IPW_CONTROL_LINE_DTR) != 0); + if (ret) { + printk(KERN_ERR IPWIRELESS_PCCARD_NAME + ": error setting DTR (%d)\n", ret); + return; + } + + set_RTS(hw, PRIO_SETUP, channel_idx, + (hw->control_lines [channel_idx] & + IPW_CONTROL_LINE_RTS) != 0); + if (ret) { + printk(KERN_ERR IPWIRELESS_PCCARD_NAME + ": error setting RTS (%d)\n", ret); + return; + } + } + /* + * For NDIS we assume that we are using sync PPP frames, for COM async. + * This driver uses NDIS mode too. We don't bother with translation + * from async -> sync PPP. + */ + info_packet = alloc_ctrl_packet(sizeof(struct ipw_setup_info_packet), + ADDR_SETUP_PROT, + TL_PROTOCOLID_SETUP, + TL_SETUP_SIGNO_INFO_MSG); + if (!info_packet) + goto exit_nomem; + info_packet->header.length = sizeof(struct tl_setup_info_msg); + info_packet->body.driver_type = NDISWAN_DRIVER; + info_packet->body.major_version = NDISWAN_DRIVER_MAJOR_VERSION; + info_packet->body.minor_version = NDISWAN_DRIVER_MINOR_VERSION; + send_packet(hw, PRIO_SETUP, &info_packet->header); + + /* Initialization is now complete, so we clear the 'to_setup' flag */ + hw->to_setup = 0; + + return; + +exit_nomem: + printk(KERN_ERR IPWIRELESS_PCCARD_NAME + ": not enough memory to alloc control packet\n"); + hw->to_setup = -1; +} + +static void handle_setup_get_version_rsp(struct ipw_hardware *hw, + unsigned char vers_no) +{ + del_timer(&hw->setup_timer); + hw->initializing = 0; + printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": card is ready.\n"); + + if (vers_no == TL_SETUP_VERSION) + __handle_setup_get_version_rsp(hw); + else + printk(KERN_ERR IPWIRELESS_PCCARD_NAME + ": invalid hardware version no %u\n", + (unsigned int) vers_no); +} + +static void ipw_send_setup_packet(struct ipw_hardware *hw) +{ + struct ipw_setup_get_version_query_packet *ver_packet; + + ver_packet = alloc_ctrl_packet( + sizeof(struct ipw_setup_get_version_query_packet), + ADDR_SETUP_PROT, TL_PROTOCOLID_SETUP, + TL_SETUP_SIGNO_GET_VERSION_QRY); + ver_packet->header.length = sizeof(struct tl_setup_get_version_qry); + + /* + * Response is handled in handle_received_SETUP_packet + */ + send_packet(hw, PRIO_SETUP, &ver_packet->header); +} + +static void handle_received_SETUP_packet(struct ipw_hardware *hw, + unsigned int address, + const unsigned char *data, int len, + int is_last) +{ + const union ipw_setup_rx_msg *rx_msg = (const union ipw_setup_rx_msg *) data; + + if (address != ADDR_SETUP_PROT) { + printk(KERN_INFO IPWIRELESS_PCCARD_NAME + ": setup packet has bad address %d\n", address); + return; + } + + switch (rx_msg->sig_no) { + case TL_SETUP_SIGNO_GET_VERSION_RSP: + if (hw->to_setup) + handle_setup_get_version_rsp(hw, + rx_msg->version_rsp_msg.version); + break; + + case TL_SETUP_SIGNO_OPEN_MSG: + if (ipwireless_debug) { + unsigned int channel_idx = rx_msg->open_msg.port_no - 1; + + printk(KERN_INFO IPWIRELESS_PCCARD_NAME + ": OPEN_MSG [channel %u] reply received\n", + channel_idx); + } + break; + + case TL_SETUP_SIGNO_INFO_MSG_ACK: + if (ipwireless_debug) + printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME + ": card successfully configured as NDISWAN\n"); + break; + + case TL_SETUP_SIGNO_REBOOT_MSG: + if (hw->to_setup) + printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME + ": Setup not completed - ignoring reboot msg\n"); + else { + struct ipw_setup_reboot_msg_ack *packet; + + printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME + ": Acknowledging REBOOT message\n"); + packet = alloc_ctrl_packet( + sizeof(struct ipw_setup_reboot_msg_ack), + ADDR_SETUP_PROT, TL_PROTOCOLID_SETUP, + TL_SETUP_SIGNO_REBOOT_MSG_ACK); + packet->header.length = + sizeof(struct TlSetupRebootMsgAck); + send_packet(hw, PRIO_SETUP, &packet->header); + if (hw->reboot_callback) + hw->reboot_callback(hw->reboot_callback_data); + } + break; + + default: + printk(KERN_INFO IPWIRELESS_PCCARD_NAME + ": unknown setup message %u received\n", + (unsigned int) rx_msg->sig_no); + } +} + +static void do_close_hardware(struct ipw_hardware *hw) +{ + unsigned int irqn; + + if (hw->hw_version == HW_VERSION_1) { + /* Disable TX and RX interrupts. */ + outw(0, hw->base_port + IOIER); + + /* Acknowledge any outstanding interrupt requests */ + irqn = inw(hw->base_port + IOIR); + if (irqn & IR_TXINTR) + outw(IR_TXINTR, hw->base_port + IOIR); + if (irqn & IR_RXINTR) + outw(IR_RXINTR, hw->base_port + IOIR); + + synchronize_irq(hw->irq); + } +} + +struct ipw_hardware *ipwireless_hardware_create(void) +{ + int i; + struct ipw_hardware *hw = + kzalloc(sizeof(struct ipw_hardware), GFP_KERNEL); + + if (!hw) + return NULL; + + hw->irq = -1; + hw->initializing = 1; + hw->tx_ready = 1; + hw->rx_bytes_queued = 0; + hw->rx_pool_size = 0; + hw->last_memtx_serial = (unsigned short) 0xffff; + for (i = 0; i < NL_NUM_OF_PRIORITIES; i++) + INIT_LIST_HEAD(&hw->tx_queue[i]); + + INIT_LIST_HEAD(&hw->rx_queue); + INIT_LIST_HEAD(&hw->rx_pool); + spin_lock_init(&hw->lock); + tasklet_init(&hw->tasklet, ipwireless_do_tasklet, (unsigned long) hw); + INIT_WORK(&hw->work_rx, ipw_receive_data_work); + setup_timer(&hw->setup_timer, ipwireless_setup_timer, + (unsigned long) hw); + + return hw; +} + +void ipwireless_init_hardware_v1(struct ipw_hardware *hw, + unsigned int base_port, + void __iomem *attr_memory, + void __iomem *common_memory, + int is_v2_card, + void (*reboot_callback) (void *data), + void *reboot_callback_data) +{ + if (hw->removed) { + hw->removed = 0; + enable_irq(hw->irq); + } + hw->base_port = base_port; + hw->hw_version = (is_v2_card ? HW_VERSION_2 : HW_VERSION_1); + hw->ll_mtu = (hw->hw_version == HW_VERSION_1 ? LL_MTU_V1 : LL_MTU_V2); + hw->memregs_CCR = (struct MEMCCR __iomem *) + ((unsigned short __iomem *) attr_memory + 0x200); + hw->memory_info_regs = (struct MEMINFREG __iomem *) common_memory; + hw->memreg_tx = &hw->memory_info_regs->memreg_tx_new; + hw->reboot_callback = reboot_callback; + hw->reboot_callback_data = reboot_callback_data; +} + +void ipwireless_init_hardware_v2_v3(struct ipw_hardware *hw) +{ + hw->initializing = 1; + hw->init_loops = 0; + printk(KERN_INFO IPWIRELESS_PCCARD_NAME + ": waiting for card to start up...\n"); + ipwireless_setup_timer((unsigned long) hw); +} + +static void ipwireless_setup_timer(unsigned long data) +{ + struct ipw_hardware *hw = (struct ipw_hardware *) data; + + hw->init_loops++; + + if (hw->init_loops == TL_SETUP_MAX_VERSION_QRY && + hw->hw_version == HW_VERSION_2 && + hw->memreg_tx == &hw->memory_info_regs->memreg_tx_new) { + printk(KERN_INFO IPWIRELESS_PCCARD_NAME + ": failed to startup using TX2, trying TX\n"); + + hw->memreg_tx = &hw->memory_info_regs->memreg_tx_old; + hw->init_loops = 0; + } + /* Give up after a certain number of retries */ + if (hw->init_loops == TL_SETUP_MAX_VERSION_QRY) { + printk(KERN_INFO IPWIRELESS_PCCARD_NAME + ": card failed to start up!\n"); + hw->initializing = 0; + } else { + /* Do not attempt to write to the board if it is not present. */ + if (is_card_present(hw)) { + unsigned long flags; + + spin_lock_irqsave(&hw->lock, flags); + hw->to_setup = 1; + hw->tx_ready = 1; + spin_unlock_irqrestore(&hw->lock, flags); + tasklet_schedule(&hw->tasklet); + } + + mod_timer(&hw->setup_timer, + jiffies + msecs_to_jiffies(TL_SETUP_VERSION_QRY_TMO)); + } +} + +/* + * Stop any interrupts from executing so that, once this function returns, + * other layers of the driver can be sure they won't get any more callbacks. + * Thus must be called on a proper process context. + */ +void ipwireless_stop_interrupts(struct ipw_hardware *hw) +{ + if (!hw->shutting_down) { + /* Tell everyone we are going down. */ + hw->shutting_down = 1; + del_timer(&hw->setup_timer); + + /* Prevent the hardware from sending any more interrupts */ + do_close_hardware(hw); + } +} + +void ipwireless_hardware_free(struct ipw_hardware *hw) +{ + int i; + struct ipw_rx_packet *rp, *rq; + struct ipw_tx_packet *tp, *tq; + + ipwireless_stop_interrupts(hw); + + flush_work_sync(&hw->work_rx); + + for (i = 0; i < NL_NUM_OF_ADDRESSES; i++) + if (hw->packet_assembler[i] != NULL) + kfree(hw->packet_assembler[i]); + + for (i = 0; i < NL_NUM_OF_PRIORITIES; i++) + list_for_each_entry_safe(tp, tq, &hw->tx_queue[i], queue) { + list_del(&tp->queue); + kfree(tp); + } + + list_for_each_entry_safe(rp, rq, &hw->rx_queue, queue) { + list_del(&rp->queue); + kfree(rp); + } + + list_for_each_entry_safe(rp, rq, &hw->rx_pool, queue) { + list_del(&rp->queue); + kfree(rp); + } + kfree(hw); +} + +/* + * Associate the specified network with this hardware, so it will receive events + * from it. + */ +void ipwireless_associate_network(struct ipw_hardware *hw, + struct ipw_network *network) +{ + hw->network = network; +} diff --git a/drivers/tty/ipwireless/hardware.h b/drivers/tty/ipwireless/hardware.h new file mode 100644 index 000000000000..90a8590e43b0 --- /dev/null +++ b/drivers/tty/ipwireless/hardware.h @@ -0,0 +1,62 @@ +/* + * IPWireless 3G PCMCIA Network Driver + * + * Original code + * by Stephen Blackheath , + * Ben Martel + * + * Copyrighted as follows: + * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) + * + * Various driver changes and rewrites, port to new kernels + * Copyright (C) 2006-2007 Jiri Kosina + * + * Misc code cleanups and updates + * Copyright (C) 2007 David Sterba + */ + +#ifndef _IPWIRELESS_CS_HARDWARE_H_ +#define _IPWIRELESS_CS_HARDWARE_H_ + +#include +#include +#include + +#define IPW_CONTROL_LINE_CTS 0x0001 +#define IPW_CONTROL_LINE_DCD 0x0002 +#define IPW_CONTROL_LINE_DSR 0x0004 +#define IPW_CONTROL_LINE_RI 0x0008 +#define IPW_CONTROL_LINE_DTR 0x0010 +#define IPW_CONTROL_LINE_RTS 0x0020 + +struct ipw_hardware; +struct ipw_network; + +struct ipw_hardware *ipwireless_hardware_create(void); +void ipwireless_hardware_free(struct ipw_hardware *hw); +irqreturn_t ipwireless_interrupt(int irq, void *dev_id); +int ipwireless_set_DTR(struct ipw_hardware *hw, unsigned int channel_idx, + int state); +int ipwireless_set_RTS(struct ipw_hardware *hw, unsigned int channel_idx, + int state); +int ipwireless_send_packet(struct ipw_hardware *hw, + unsigned int channel_idx, + const unsigned char *data, + unsigned int length, + void (*packet_sent_callback) (void *cb, + unsigned int length), + void *sent_cb_data); +void ipwireless_associate_network(struct ipw_hardware *hw, + struct ipw_network *net); +void ipwireless_stop_interrupts(struct ipw_hardware *hw); +void ipwireless_init_hardware_v1(struct ipw_hardware *hw, + unsigned int base_port, + void __iomem *attr_memory, + void __iomem *common_memory, + int is_v2_card, + void (*reboot_cb) (void *data), + void *reboot_cb_data); +void ipwireless_init_hardware_v2_v3(struct ipw_hardware *hw); +void ipwireless_sleep(unsigned int tenths); + +#endif diff --git a/drivers/tty/ipwireless/main.c b/drivers/tty/ipwireless/main.c new file mode 100644 index 000000000000..94b8eb4d691d --- /dev/null +++ b/drivers/tty/ipwireless/main.c @@ -0,0 +1,335 @@ +/* + * IPWireless 3G PCMCIA Network Driver + * + * Original code + * by Stephen Blackheath , + * Ben Martel + * + * Copyrighted as follows: + * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) + * + * Various driver changes and rewrites, port to new kernels + * Copyright (C) 2006-2007 Jiri Kosina + * + * Misc code cleanups and updates + * Copyright (C) 2007 David Sterba + */ + +#include "hardware.h" +#include "network.h" +#include "main.h" +#include "tty.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static struct pcmcia_device_id ipw_ids[] = { + PCMCIA_DEVICE_MANF_CARD(0x02f2, 0x0100), + PCMCIA_DEVICE_MANF_CARD(0x02f2, 0x0200), + PCMCIA_DEVICE_NULL +}; +MODULE_DEVICE_TABLE(pcmcia, ipw_ids); + +static void ipwireless_detach(struct pcmcia_device *link); + +/* + * Module params + */ +/* Debug mode: more verbose, print sent/recv bytes */ +int ipwireless_debug; +int ipwireless_loopback; +int ipwireless_out_queue = 10; + +module_param_named(debug, ipwireless_debug, int, 0); +module_param_named(loopback, ipwireless_loopback, int, 0); +module_param_named(out_queue, ipwireless_out_queue, int, 0); +MODULE_PARM_DESC(debug, "switch on debug messages [0]"); +MODULE_PARM_DESC(loopback, + "debug: enable ras_raw channel [0]"); +MODULE_PARM_DESC(out_queue, "debug: set size of outgoing PPP queue [10]"); + +/* Executes in process context. */ +static void signalled_reboot_work(struct work_struct *work_reboot) +{ + struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev, + work_reboot); + struct pcmcia_device *link = ipw->link; + pcmcia_reset_card(link->socket); +} + +static void signalled_reboot_callback(void *callback_data) +{ + struct ipw_dev *ipw = (struct ipw_dev *) callback_data; + + /* Delegate to process context. */ + schedule_work(&ipw->work_reboot); +} + +static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data) +{ + struct ipw_dev *ipw = priv_data; + struct resource *io_resource; + int ret; + + p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; + p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; + + /* 0x40 causes it to generate level mode interrupts. */ + /* 0x04 enables IREQ pin. */ + p_dev->config_index |= 0x44; + p_dev->io_lines = 16; + ret = pcmcia_request_io(p_dev); + if (ret) + return ret; + + io_resource = request_region(p_dev->resource[0]->start, + resource_size(p_dev->resource[0]), + IPWIRELESS_PCCARD_NAME); + + p_dev->resource[2]->flags |= + WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE; + + ret = pcmcia_request_window(p_dev, p_dev->resource[2], 0); + if (ret != 0) + goto exit1; + + ret = pcmcia_map_mem_page(p_dev, p_dev->resource[2], p_dev->card_addr); + if (ret != 0) + goto exit2; + + ipw->is_v2_card = resource_size(p_dev->resource[2]) == 0x100; + + ipw->attr_memory = ioremap(p_dev->resource[2]->start, + resource_size(p_dev->resource[2])); + request_mem_region(p_dev->resource[2]->start, + resource_size(p_dev->resource[2]), + IPWIRELESS_PCCARD_NAME); + + p_dev->resource[3]->flags |= WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | + WIN_ENABLE; + p_dev->resource[3]->end = 0; /* this used to be 0x1000 */ + ret = pcmcia_request_window(p_dev, p_dev->resource[3], 0); + if (ret != 0) + goto exit2; + + ret = pcmcia_map_mem_page(p_dev, p_dev->resource[3], 0); + if (ret != 0) + goto exit3; + + ipw->attr_memory = ioremap(p_dev->resource[3]->start, + resource_size(p_dev->resource[3])); + request_mem_region(p_dev->resource[3]->start, + resource_size(p_dev->resource[3]), + IPWIRELESS_PCCARD_NAME); + + return 0; + +exit3: +exit2: + if (ipw->common_memory) { + release_mem_region(p_dev->resource[2]->start, + resource_size(p_dev->resource[2])); + iounmap(ipw->common_memory); + } +exit1: + release_resource(io_resource); + pcmcia_disable_device(p_dev); + return -1; +} + +static int config_ipwireless(struct ipw_dev *ipw) +{ + struct pcmcia_device *link = ipw->link; + int ret = 0; + + ipw->is_v2_card = 0; + link->config_flags |= CONF_AUTO_SET_IO | CONF_AUTO_SET_IOMEM | + CONF_ENABLE_IRQ; + + ret = pcmcia_loop_config(link, ipwireless_probe, ipw); + if (ret != 0) + return ret; + + INIT_WORK(&ipw->work_reboot, signalled_reboot_work); + + ipwireless_init_hardware_v1(ipw->hardware, link->resource[0]->start, + ipw->attr_memory, ipw->common_memory, + ipw->is_v2_card, signalled_reboot_callback, + ipw); + + ret = pcmcia_request_irq(link, ipwireless_interrupt); + if (ret != 0) + goto exit; + + printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n", + ipw->is_v2_card ? "V2/V3" : "V1"); + printk(KERN_INFO IPWIRELESS_PCCARD_NAME + ": I/O ports %pR, irq %d\n", link->resource[0], + (unsigned int) link->irq); + if (ipw->attr_memory && ipw->common_memory) + printk(KERN_INFO IPWIRELESS_PCCARD_NAME + ": attr memory %pR, common memory %pR\n", + link->resource[3], + link->resource[2]); + + ipw->network = ipwireless_network_create(ipw->hardware); + if (!ipw->network) + goto exit; + + ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network); + if (!ipw->tty) + goto exit; + + ipwireless_init_hardware_v2_v3(ipw->hardware); + + /* + * Do the RequestConfiguration last, because it enables interrupts. + * Then we don't get any interrupts before we're ready for them. + */ + ret = pcmcia_enable_device(link); + if (ret != 0) + goto exit; + + return 0; + +exit: + if (ipw->common_memory) { + release_mem_region(link->resource[2]->start, + resource_size(link->resource[2])); + iounmap(ipw->common_memory); + } + if (ipw->attr_memory) { + release_mem_region(link->resource[3]->start, + resource_size(link->resource[3])); + iounmap(ipw->attr_memory); + } + pcmcia_disable_device(link); + return -1; +} + +static void release_ipwireless(struct ipw_dev *ipw) +{ + if (ipw->common_memory) { + release_mem_region(ipw->link->resource[2]->start, + resource_size(ipw->link->resource[2])); + iounmap(ipw->common_memory); + } + if (ipw->attr_memory) { + release_mem_region(ipw->link->resource[3]->start, + resource_size(ipw->link->resource[3])); + iounmap(ipw->attr_memory); + } + pcmcia_disable_device(ipw->link); +} + +/* + * ipwireless_attach() creates an "instance" of the driver, allocating + * local data structures for one device (one interface). The device + * is registered with Card Services. + * + * The pcmcia_device structure is initialized, but we don't actually + * configure the card at this point -- we wait until we receive a + * card insertion event. + */ +static int ipwireless_attach(struct pcmcia_device *link) +{ + struct ipw_dev *ipw; + int ret; + + ipw = kzalloc(sizeof(struct ipw_dev), GFP_KERNEL); + if (!ipw) + return -ENOMEM; + + ipw->link = link; + link->priv = ipw; + + ipw->hardware = ipwireless_hardware_create(); + if (!ipw->hardware) { + kfree(ipw); + return -ENOMEM; + } + /* RegisterClient will call config_ipwireless */ + + ret = config_ipwireless(ipw); + + if (ret != 0) { + ipwireless_detach(link); + return ret; + } + + return 0; +} + +/* + * This deletes a driver "instance". The device is de-registered with + * Card Services. If it has been released, all local data structures + * are freed. Otherwise, the structures will be freed when the device + * is released. + */ +static void ipwireless_detach(struct pcmcia_device *link) +{ + struct ipw_dev *ipw = link->priv; + + release_ipwireless(ipw); + + if (ipw->tty != NULL) + ipwireless_tty_free(ipw->tty); + if (ipw->network != NULL) + ipwireless_network_free(ipw->network); + if (ipw->hardware != NULL) + ipwireless_hardware_free(ipw->hardware); + kfree(ipw); +} + +static struct pcmcia_driver me = { + .owner = THIS_MODULE, + .probe = ipwireless_attach, + .remove = ipwireless_detach, + .name = IPWIRELESS_PCCARD_NAME, + .id_table = ipw_ids +}; + +/* + * Module insertion : initialisation of the module. + * Register the card with cardmgr... + */ +static int __init init_ipwireless(void) +{ + int ret; + + ret = ipwireless_tty_init(); + if (ret != 0) + return ret; + + ret = pcmcia_register_driver(&me); + if (ret != 0) + ipwireless_tty_release(); + + return ret; +} + +/* + * Module removal + */ +static void __exit exit_ipwireless(void) +{ + pcmcia_unregister_driver(&me); + ipwireless_tty_release(); +} + +module_init(init_ipwireless); +module_exit(exit_ipwireless); + +MODULE_AUTHOR(IPWIRELESS_PCMCIA_AUTHOR); +MODULE_DESCRIPTION(IPWIRELESS_PCCARD_NAME " " IPWIRELESS_PCMCIA_VERSION); +MODULE_LICENSE("GPL"); diff --git a/drivers/tty/ipwireless/main.h b/drivers/tty/ipwireless/main.h new file mode 100644 index 000000000000..f2cbb116bccb --- /dev/null +++ b/drivers/tty/ipwireless/main.h @@ -0,0 +1,68 @@ +/* + * IPWireless 3G PCMCIA Network Driver + * + * Original code + * by Stephen Blackheath , + * Ben Martel + * + * Copyrighted as follows: + * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) + * + * Various driver changes and rewrites, port to new kernels + * Copyright (C) 2006-2007 Jiri Kosina + * + * Misc code cleanups and updates + * Copyright (C) 2007 David Sterba + */ + +#ifndef _IPWIRELESS_CS_H_ +#define _IPWIRELESS_CS_H_ + +#include +#include + +#include +#include + +#include "hardware.h" + +#define IPWIRELESS_PCCARD_NAME "ipwireless" +#define IPWIRELESS_PCMCIA_VERSION "1.1" +#define IPWIRELESS_PCMCIA_AUTHOR \ + "Stephen Blackheath, Ben Martel, Jiri Kosina and David Sterba" + +#define IPWIRELESS_TX_QUEUE_SIZE 262144 +#define IPWIRELESS_RX_QUEUE_SIZE 262144 + +#define IPWIRELESS_STATE_DEBUG + +struct ipw_hardware; +struct ipw_network; +struct ipw_tty; + +struct ipw_dev { + struct pcmcia_device *link; + int is_v2_card; + + void __iomem *attr_memory; + + void __iomem *common_memory; + + /* Reference to attribute memory, containing CIS data */ + void *attribute_memory; + + /* Hardware context */ + struct ipw_hardware *hardware; + /* Network layer context */ + struct ipw_network *network; + /* TTY device context */ + struct ipw_tty *tty; + struct work_struct work_reboot; +}; + +/* Module parametres */ +extern int ipwireless_debug; +extern int ipwireless_loopback; +extern int ipwireless_out_queue; + +#endif diff --git a/drivers/tty/ipwireless/network.c b/drivers/tty/ipwireless/network.c new file mode 100644 index 000000000000..f7daeea598e4 --- /dev/null +++ b/drivers/tty/ipwireless/network.c @@ -0,0 +1,508 @@ +/* + * IPWireless 3G PCMCIA Network Driver + * + * Original code + * by Stephen Blackheath , + * Ben Martel + * + * Copyrighted as follows: + * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) + * + * Various driver changes and rewrites, port to new kernels + * Copyright (C) 2006-2007 Jiri Kosina + * + * Misc code cleanups and updates + * Copyright (C) 2007 David Sterba + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "network.h" +#include "hardware.h" +#include "main.h" +#include "tty.h" + +#define MAX_ASSOCIATED_TTYS 2 + +#define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP) + +struct ipw_network { + /* Hardware context, used for calls to hardware layer. */ + struct ipw_hardware *hardware; + /* Context for kernel 'generic_ppp' functionality */ + struct ppp_channel *ppp_channel; + /* tty context connected with IPW console */ + struct ipw_tty *associated_ttys[NO_OF_IPW_CHANNELS][MAX_ASSOCIATED_TTYS]; + /* True if ppp needs waking up once we're ready to xmit */ + int ppp_blocked; + /* Number of packets queued up in hardware module. */ + int outgoing_packets_queued; + /* Spinlock to avoid interrupts during shutdown */ + spinlock_t lock; + struct mutex close_lock; + + /* PPP ioctl data, not actually used anywere */ + unsigned int flags; + unsigned int rbits; + u32 xaccm[8]; + u32 raccm; + int mru; + + int shutting_down; + unsigned int ras_control_lines; + + struct work_struct work_go_online; + struct work_struct work_go_offline; +}; + +static void notify_packet_sent(void *callback_data, unsigned int packet_length) +{ + struct ipw_network *network = callback_data; + unsigned long flags; + + spin_lock_irqsave(&network->lock, flags); + network->outgoing_packets_queued--; + if (network->ppp_channel != NULL) { + if (network->ppp_blocked) { + network->ppp_blocked = 0; + spin_unlock_irqrestore(&network->lock, flags); + ppp_output_wakeup(network->ppp_channel); + if (ipwireless_debug) + printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME + ": ppp unblocked\n"); + } else + spin_unlock_irqrestore(&network->lock, flags); + } else + spin_unlock_irqrestore(&network->lock, flags); +} + +/* + * Called by the ppp system when it has a packet to send to the hardware. + */ +static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel, + struct sk_buff *skb) +{ + struct ipw_network *network = ppp_channel->private; + unsigned long flags; + + spin_lock_irqsave(&network->lock, flags); + if (network->outgoing_packets_queued < ipwireless_out_queue) { + unsigned char *buf; + static unsigned char header[] = { + PPP_ALLSTATIONS, /* 0xff */ + PPP_UI, /* 0x03 */ + }; + int ret; + + network->outgoing_packets_queued++; + spin_unlock_irqrestore(&network->lock, flags); + + /* + * If we have the requested amount of headroom in the skb we + * were handed, then we can add the header efficiently. + */ + if (skb_headroom(skb) >= 2) { + memcpy(skb_push(skb, 2), header, 2); + ret = ipwireless_send_packet(network->hardware, + IPW_CHANNEL_RAS, skb->data, + skb->len, + notify_packet_sent, + network); + if (ret == -1) { + skb_pull(skb, 2); + return 0; + } + } else { + /* Otherwise (rarely) we do it inefficiently. */ + buf = kmalloc(skb->len + 2, GFP_ATOMIC); + if (!buf) + return 0; + memcpy(buf + 2, skb->data, skb->len); + memcpy(buf, header, 2); + ret = ipwireless_send_packet(network->hardware, + IPW_CHANNEL_RAS, buf, + skb->len + 2, + notify_packet_sent, + network); + kfree(buf); + if (ret == -1) + return 0; + } + kfree_skb(skb); + return 1; + } else { + /* + * Otherwise reject the packet, and flag that the ppp system + * needs to be unblocked once we are ready to send. + */ + network->ppp_blocked = 1; + spin_unlock_irqrestore(&network->lock, flags); + if (ipwireless_debug) + printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME ": ppp blocked\n"); + return 0; + } +} + +/* Handle an ioctl call that has come in via ppp. (copy of ppp_async_ioctl() */ +static int ipwireless_ppp_ioctl(struct ppp_channel *ppp_channel, + unsigned int cmd, unsigned long arg) +{ + struct ipw_network *network = ppp_channel->private; + int err, val; + u32 accm[8]; + int __user *user_arg = (int __user *) arg; + + err = -EFAULT; + switch (cmd) { + case PPPIOCGFLAGS: + val = network->flags | network->rbits; + if (put_user(val, user_arg)) + break; + err = 0; + break; + + case PPPIOCSFLAGS: + if (get_user(val, user_arg)) + break; + network->flags = val & ~SC_RCV_BITS; + network->rbits = val & SC_RCV_BITS; + err = 0; + break; + + case PPPIOCGASYNCMAP: + if (put_user(network->xaccm[0], user_arg)) + break; + err = 0; + break; + + case PPPIOCSASYNCMAP: + if (get_user(network->xaccm[0], user_arg)) + break; + err = 0; + break; + + case PPPIOCGRASYNCMAP: + if (put_user(network->raccm, user_arg)) + break; + err = 0; + break; + + case PPPIOCSRASYNCMAP: + if (get_user(network->raccm, user_arg)) + break; + err = 0; + break; + + case PPPIOCGXASYNCMAP: + if (copy_to_user((void __user *) arg, network->xaccm, + sizeof(network->xaccm))) + break; + err = 0; + break; + + case PPPIOCSXASYNCMAP: + if (copy_from_user(accm, (void __user *) arg, sizeof(accm))) + break; + accm[2] &= ~0x40000000U; /* can't escape 0x5e */ + accm[3] |= 0x60000000U; /* must escape 0x7d, 0x7e */ + memcpy(network->xaccm, accm, sizeof(network->xaccm)); + err = 0; + break; + + case PPPIOCGMRU: + if (put_user(network->mru, user_arg)) + break; + err = 0; + break; + + case PPPIOCSMRU: + if (get_user(val, user_arg)) + break; + if (val < PPP_MRU) + val = PPP_MRU; + network->mru = val; + err = 0; + break; + + default: + err = -ENOTTY; + } + + return err; +} + +static const struct ppp_channel_ops ipwireless_ppp_channel_ops = { + .start_xmit = ipwireless_ppp_start_xmit, + .ioctl = ipwireless_ppp_ioctl +}; + +static void do_go_online(struct work_struct *work_go_online) +{ + struct ipw_network *network = + container_of(work_go_online, struct ipw_network, + work_go_online); + unsigned long flags; + + spin_lock_irqsave(&network->lock, flags); + if (!network->ppp_channel) { + struct ppp_channel *channel; + + spin_unlock_irqrestore(&network->lock, flags); + channel = kzalloc(sizeof(struct ppp_channel), GFP_KERNEL); + if (!channel) { + printk(KERN_ERR IPWIRELESS_PCCARD_NAME + ": unable to allocate PPP channel\n"); + return; + } + channel->private = network; + channel->mtu = 16384; /* Wild guess */ + channel->hdrlen = 2; + channel->ops = &ipwireless_ppp_channel_ops; + + network->flags = 0; + network->rbits = 0; + network->mru = PPP_MRU; + memset(network->xaccm, 0, sizeof(network->xaccm)); + network->xaccm[0] = ~0U; + network->xaccm[3] = 0x60000000U; + network->raccm = ~0U; + ppp_register_channel(channel); + spin_lock_irqsave(&network->lock, flags); + network->ppp_channel = channel; + } + spin_unlock_irqrestore(&network->lock, flags); +} + +static void do_go_offline(struct work_struct *work_go_offline) +{ + struct ipw_network *network = + container_of(work_go_offline, struct ipw_network, + work_go_offline); + unsigned long flags; + + mutex_lock(&network->close_lock); + spin_lock_irqsave(&network->lock, flags); + if (network->ppp_channel != NULL) { + struct ppp_channel *channel = network->ppp_channel; + + network->ppp_channel = NULL; + spin_unlock_irqrestore(&network->lock, flags); + mutex_unlock(&network->close_lock); + ppp_unregister_channel(channel); + } else { + spin_unlock_irqrestore(&network->lock, flags); + mutex_unlock(&network->close_lock); + } +} + +void ipwireless_network_notify_control_line_change(struct ipw_network *network, + unsigned int channel_idx, + unsigned int control_lines, + unsigned int changed_mask) +{ + int i; + + if (channel_idx == IPW_CHANNEL_RAS) + network->ras_control_lines = control_lines; + + for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) { + struct ipw_tty *tty = + network->associated_ttys[channel_idx][i]; + + /* + * If it's associated with a tty (other than the RAS channel + * when we're online), then send the data to that tty. The RAS + * channel's data is handled above - it always goes through + * ppp_generic. + */ + if (tty) + ipwireless_tty_notify_control_line_change(tty, + channel_idx, + control_lines, + changed_mask); + } +} + +/* + * Some versions of firmware stuff packets with 0xff 0x03 (PPP: ALLSTATIONS, UI) + * bytes, which are required on sent packet, but not always present on received + * packets + */ +static struct sk_buff *ipw_packet_received_skb(unsigned char *data, + unsigned int length) +{ + struct sk_buff *skb; + + if (length > 2 && data[0] == PPP_ALLSTATIONS && data[1] == PPP_UI) { + length -= 2; + data += 2; + } + + skb = dev_alloc_skb(length + 4); + skb_reserve(skb, 2); + memcpy(skb_put(skb, length), data, length); + + return skb; +} + +void ipwireless_network_packet_received(struct ipw_network *network, + unsigned int channel_idx, + unsigned char *data, + unsigned int length) +{ + int i; + unsigned long flags; + + for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) { + struct ipw_tty *tty = network->associated_ttys[channel_idx][i]; + + if (!tty) + continue; + + /* + * If it's associated with a tty (other than the RAS channel + * when we're online), then send the data to that tty. The RAS + * channel's data is handled above - it always goes through + * ppp_generic. + */ + if (channel_idx == IPW_CHANNEL_RAS + && (network->ras_control_lines & + IPW_CONTROL_LINE_DCD) != 0 + && ipwireless_tty_is_modem(tty)) { + /* + * If data came in on the RAS channel and this tty is + * the modem tty, and we are online, then we send it to + * the PPP layer. + */ + mutex_lock(&network->close_lock); + spin_lock_irqsave(&network->lock, flags); + if (network->ppp_channel != NULL) { + struct sk_buff *skb; + + spin_unlock_irqrestore(&network->lock, + flags); + + /* Send the data to the ppp_generic module. */ + skb = ipw_packet_received_skb(data, length); + ppp_input(network->ppp_channel, skb); + } else + spin_unlock_irqrestore(&network->lock, + flags); + mutex_unlock(&network->close_lock); + } + /* Otherwise we send it out the tty. */ + else + ipwireless_tty_received(tty, data, length); + } +} + +struct ipw_network *ipwireless_network_create(struct ipw_hardware *hw) +{ + struct ipw_network *network = + kzalloc(sizeof(struct ipw_network), GFP_ATOMIC); + + if (!network) + return NULL; + + spin_lock_init(&network->lock); + mutex_init(&network->close_lock); + + network->hardware = hw; + + INIT_WORK(&network->work_go_online, do_go_online); + INIT_WORK(&network->work_go_offline, do_go_offline); + + ipwireless_associate_network(hw, network); + + return network; +} + +void ipwireless_network_free(struct ipw_network *network) +{ + network->shutting_down = 1; + + ipwireless_ppp_close(network); + flush_work_sync(&network->work_go_online); + flush_work_sync(&network->work_go_offline); + + ipwireless_stop_interrupts(network->hardware); + ipwireless_associate_network(network->hardware, NULL); + + kfree(network); +} + +void ipwireless_associate_network_tty(struct ipw_network *network, + unsigned int channel_idx, + struct ipw_tty *tty) +{ + int i; + + for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) + if (network->associated_ttys[channel_idx][i] == NULL) { + network->associated_ttys[channel_idx][i] = tty; + break; + } +} + +void ipwireless_disassociate_network_ttys(struct ipw_network *network, + unsigned int channel_idx) +{ + int i; + + for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) + network->associated_ttys[channel_idx][i] = NULL; +} + +void ipwireless_ppp_open(struct ipw_network *network) +{ + if (ipwireless_debug) + printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME ": online\n"); + schedule_work(&network->work_go_online); +} + +void ipwireless_ppp_close(struct ipw_network *network) +{ + /* Disconnect from the wireless network. */ + if (ipwireless_debug) + printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME ": offline\n"); + schedule_work(&network->work_go_offline); +} + +int ipwireless_ppp_channel_index(struct ipw_network *network) +{ + int ret = -1; + unsigned long flags; + + spin_lock_irqsave(&network->lock, flags); + if (network->ppp_channel != NULL) + ret = ppp_channel_index(network->ppp_channel); + spin_unlock_irqrestore(&network->lock, flags); + + return ret; +} + +int ipwireless_ppp_unit_number(struct ipw_network *network) +{ + int ret = -1; + unsigned long flags; + + spin_lock_irqsave(&network->lock, flags); + if (network->ppp_channel != NULL) + ret = ppp_unit_number(network->ppp_channel); + spin_unlock_irqrestore(&network->lock, flags); + + return ret; +} + +int ipwireless_ppp_mru(const struct ipw_network *network) +{ + return network->mru; +} diff --git a/drivers/tty/ipwireless/network.h b/drivers/tty/ipwireless/network.h new file mode 100644 index 000000000000..561f765b3334 --- /dev/null +++ b/drivers/tty/ipwireless/network.h @@ -0,0 +1,53 @@ +/* + * IPWireless 3G PCMCIA Network Driver + * + * Original code + * by Stephen Blackheath , + * Ben Martel + * + * Copyrighted as follows: + * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) + * + * Various driver changes and rewrites, port to new kernels + * Copyright (C) 2006-2007 Jiri Kosina + * + * Misc code cleanups and updates + * Copyright (C) 2007 David Sterba + */ + +#ifndef _IPWIRELESS_CS_NETWORK_H_ +#define _IPWIRELESS_CS_NETWORK_H_ + +#include + +struct ipw_network; +struct ipw_tty; +struct ipw_hardware; + +/* Definitions of the different channels on the PCMCIA UE */ +#define IPW_CHANNEL_RAS 0 +#define IPW_CHANNEL_DIALLER 1 +#define IPW_CHANNEL_CONSOLE 2 +#define NO_OF_IPW_CHANNELS 5 + +void ipwireless_network_notify_control_line_change(struct ipw_network *net, + unsigned int channel_idx, unsigned int control_lines, + unsigned int control_mask); +void ipwireless_network_packet_received(struct ipw_network *net, + unsigned int channel_idx, unsigned char *data, + unsigned int length); +struct ipw_network *ipwireless_network_create(struct ipw_hardware *hw); +void ipwireless_network_free(struct ipw_network *net); +void ipwireless_associate_network_tty(struct ipw_network *net, + unsigned int channel_idx, struct ipw_tty *tty); +void ipwireless_disassociate_network_ttys(struct ipw_network *net, + unsigned int channel_idx); + +void ipwireless_ppp_open(struct ipw_network *net); + +void ipwireless_ppp_close(struct ipw_network *net); +int ipwireless_ppp_channel_index(struct ipw_network *net); +int ipwireless_ppp_unit_number(struct ipw_network *net); +int ipwireless_ppp_mru(const struct ipw_network *net); + +#endif diff --git a/drivers/tty/ipwireless/setup_protocol.h b/drivers/tty/ipwireless/setup_protocol.h new file mode 100644 index 000000000000..9d6bcc77c73c --- /dev/null +++ b/drivers/tty/ipwireless/setup_protocol.h @@ -0,0 +1,108 @@ +/* + * IPWireless 3G PCMCIA Network Driver + * + * Original code + * by Stephen Blackheath , + * Ben Martel + * + * Copyrighted as follows: + * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) + * + * Various driver changes and rewrites, port to new kernels + * Copyright (C) 2006-2007 Jiri Kosina + * + * Misc code cleanups and updates + * Copyright (C) 2007 David Sterba + */ + +#ifndef _IPWIRELESS_CS_SETUP_PROTOCOL_H_ +#define _IPWIRELESS_CS_SETUP_PROTOCOL_H_ + +/* Version of the setup protocol and transport protocols */ +#define TL_SETUP_VERSION 1 + +#define TL_SETUP_VERSION_QRY_TMO 1000 +#define TL_SETUP_MAX_VERSION_QRY 30 + +/* Message numbers 0-9 are obsoleted and must not be reused! */ +#define TL_SETUP_SIGNO_GET_VERSION_QRY 10 +#define TL_SETUP_SIGNO_GET_VERSION_RSP 11 +#define TL_SETUP_SIGNO_CONFIG_MSG 12 +#define TL_SETUP_SIGNO_CONFIG_DONE_MSG 13 +#define TL_SETUP_SIGNO_OPEN_MSG 14 +#define TL_SETUP_SIGNO_CLOSE_MSG 15 + +#define TL_SETUP_SIGNO_INFO_MSG 20 +#define TL_SETUP_SIGNO_INFO_MSG_ACK 21 + +#define TL_SETUP_SIGNO_REBOOT_MSG 22 +#define TL_SETUP_SIGNO_REBOOT_MSG_ACK 23 + +/* Synchronous start-messages */ +struct tl_setup_get_version_qry { + unsigned char sig_no; /* TL_SETUP_SIGNO_GET_VERSION_QRY */ +} __attribute__ ((__packed__)); + +struct tl_setup_get_version_rsp { + unsigned char sig_no; /* TL_SETUP_SIGNO_GET_VERSION_RSP */ + unsigned char version; /* TL_SETUP_VERSION */ +} __attribute__ ((__packed__)); + +struct tl_setup_config_msg { + unsigned char sig_no; /* TL_SETUP_SIGNO_CONFIG_MSG */ + unsigned char port_no; + unsigned char prio_data; + unsigned char prio_ctrl; +} __attribute__ ((__packed__)); + +struct tl_setup_config_done_msg { + unsigned char sig_no; /* TL_SETUP_SIGNO_CONFIG_DONE_MSG */ +} __attribute__ ((__packed__)); + +/* Asyncronous messages */ +struct tl_setup_open_msg { + unsigned char sig_no; /* TL_SETUP_SIGNO_OPEN_MSG */ + unsigned char port_no; +} __attribute__ ((__packed__)); + +struct tl_setup_close_msg { + unsigned char sig_no; /* TL_SETUP_SIGNO_CLOSE_MSG */ + unsigned char port_no; +} __attribute__ ((__packed__)); + +/* Driver type - for use in tl_setup_info_msg.driver_type */ +#define COMM_DRIVER 0 +#define NDISWAN_DRIVER 1 +#define NDISWAN_DRIVER_MAJOR_VERSION 2 +#define NDISWAN_DRIVER_MINOR_VERSION 0 + +/* + * It should not matter when this message comes over as we just store the + * results and send the ACK. + */ +struct tl_setup_info_msg { + unsigned char sig_no; /* TL_SETUP_SIGNO_INFO_MSG */ + unsigned char driver_type; + unsigned char major_version; + unsigned char minor_version; +} __attribute__ ((__packed__)); + +struct tl_setup_info_msgAck { + unsigned char sig_no; /* TL_SETUP_SIGNO_INFO_MSG_ACK */ +} __attribute__ ((__packed__)); + +struct TlSetupRebootMsgAck { + unsigned char sig_no; /* TL_SETUP_SIGNO_REBOOT_MSG_ACK */ +} __attribute__ ((__packed__)); + +/* Define a union of all the msgs that the driver can receive from the card.*/ +union ipw_setup_rx_msg { + unsigned char sig_no; + struct tl_setup_get_version_rsp version_rsp_msg; + struct tl_setup_open_msg open_msg; + struct tl_setup_close_msg close_msg; + struct tl_setup_info_msg InfoMsg; + struct tl_setup_info_msgAck info_msg_ack; +} __attribute__ ((__packed__)); + +#endif /* _IPWIRELESS_CS_SETUP_PROTOCOL_H_ */ diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c new file mode 100644 index 000000000000..ef92869502a7 --- /dev/null +++ b/drivers/tty/ipwireless/tty.c @@ -0,0 +1,679 @@ +/* + * IPWireless 3G PCMCIA Network Driver + * + * Original code + * by Stephen Blackheath , + * Ben Martel + * + * Copyrighted as follows: + * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) + * + * Various driver changes and rewrites, port to new kernels + * Copyright (C) 2006-2007 Jiri Kosina + * + * Misc code cleanups and updates + * Copyright (C) 2007 David Sterba + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tty.h" +#include "network.h" +#include "hardware.h" +#include "main.h" + +#define IPWIRELESS_PCMCIA_START (0) +#define IPWIRELESS_PCMCIA_MINORS (24) +#define IPWIRELESS_PCMCIA_MINOR_RANGE (8) + +#define TTYTYPE_MODEM (0) +#define TTYTYPE_MONITOR (1) +#define TTYTYPE_RAS_RAW (2) + +struct ipw_tty { + int index; + struct ipw_hardware *hardware; + unsigned int channel_idx; + unsigned int secondary_channel_idx; + int tty_type; + struct ipw_network *network; + struct tty_struct *linux_tty; + int open_count; + unsigned int control_lines; + struct mutex ipw_tty_mutex; + int tx_bytes_queued; + int closing; +}; + +static struct ipw_tty *ttys[IPWIRELESS_PCMCIA_MINORS]; + +static struct tty_driver *ipw_tty_driver; + +static char *tty_type_name(int tty_type) +{ + static char *channel_names[] = { + "modem", + "monitor", + "RAS-raw" + }; + + return channel_names[tty_type]; +} + +static void report_registering(struct ipw_tty *tty) +{ + char *iftype = tty_type_name(tty->tty_type); + + printk(KERN_INFO IPWIRELESS_PCCARD_NAME + ": registering %s device ttyIPWp%d\n", iftype, tty->index); +} + +static void report_deregistering(struct ipw_tty *tty) +{ + char *iftype = tty_type_name(tty->tty_type); + + printk(KERN_INFO IPWIRELESS_PCCARD_NAME + ": deregistering %s device ttyIPWp%d\n", iftype, + tty->index); +} + +static struct ipw_tty *get_tty(int minor) +{ + if (minor < ipw_tty_driver->minor_start + || minor >= ipw_tty_driver->minor_start + + IPWIRELESS_PCMCIA_MINORS) + return NULL; + else { + int minor_offset = minor - ipw_tty_driver->minor_start; + + /* + * The 'ras_raw' channel is only available when 'loopback' mode + * is enabled. + * Number of minor starts with 16 (_RANGE * _RAS_RAW). + */ + if (!ipwireless_loopback && + minor_offset >= + IPWIRELESS_PCMCIA_MINOR_RANGE * TTYTYPE_RAS_RAW) + return NULL; + + return ttys[minor_offset]; + } +} + +static int ipw_open(struct tty_struct *linux_tty, struct file *filp) +{ + int minor = linux_tty->index; + struct ipw_tty *tty = get_tty(minor); + + if (!tty) + return -ENODEV; + + mutex_lock(&tty->ipw_tty_mutex); + + if (tty->closing) { + mutex_unlock(&tty->ipw_tty_mutex); + return -ENODEV; + } + if (tty->open_count == 0) + tty->tx_bytes_queued = 0; + + tty->open_count++; + + tty->linux_tty = linux_tty; + linux_tty->driver_data = tty; + linux_tty->low_latency = 1; + + if (tty->tty_type == TTYTYPE_MODEM) + ipwireless_ppp_open(tty->network); + + mutex_unlock(&tty->ipw_tty_mutex); + + return 0; +} + +static void do_ipw_close(struct ipw_tty *tty) +{ + tty->open_count--; + + if (tty->open_count == 0) { + struct tty_struct *linux_tty = tty->linux_tty; + + if (linux_tty != NULL) { + tty->linux_tty = NULL; + linux_tty->driver_data = NULL; + + if (tty->tty_type == TTYTYPE_MODEM) + ipwireless_ppp_close(tty->network); + } + } +} + +static void ipw_hangup(struct tty_struct *linux_tty) +{ + struct ipw_tty *tty = linux_tty->driver_data; + + if (!tty) + return; + + mutex_lock(&tty->ipw_tty_mutex); + if (tty->open_count == 0) { + mutex_unlock(&tty->ipw_tty_mutex); + return; + } + + do_ipw_close(tty); + + mutex_unlock(&tty->ipw_tty_mutex); +} + +static void ipw_close(struct tty_struct *linux_tty, struct file *filp) +{ + ipw_hangup(linux_tty); +} + +/* Take data received from hardware, and send it out the tty */ +void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data, + unsigned int length) +{ + struct tty_struct *linux_tty; + int work = 0; + + mutex_lock(&tty->ipw_tty_mutex); + linux_tty = tty->linux_tty; + if (linux_tty == NULL) { + mutex_unlock(&tty->ipw_tty_mutex); + return; + } + + if (!tty->open_count) { + mutex_unlock(&tty->ipw_tty_mutex); + return; + } + mutex_unlock(&tty->ipw_tty_mutex); + + work = tty_insert_flip_string(linux_tty, data, length); + + if (work != length) + printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME + ": %d chars not inserted to flip buffer!\n", + length - work); + + /* + * This may sleep if ->low_latency is set + */ + if (work) + tty_flip_buffer_push(linux_tty); +} + +static void ipw_write_packet_sent_callback(void *callback_data, + unsigned int packet_length) +{ + struct ipw_tty *tty = callback_data; + + /* + * Packet has been sent, so we subtract the number of bytes from our + * tally of outstanding TX bytes. + */ + tty->tx_bytes_queued -= packet_length; +} + +static int ipw_write(struct tty_struct *linux_tty, + const unsigned char *buf, int count) +{ + struct ipw_tty *tty = linux_tty->driver_data; + int room, ret; + + if (!tty) + return -ENODEV; + + mutex_lock(&tty->ipw_tty_mutex); + if (!tty->open_count) { + mutex_unlock(&tty->ipw_tty_mutex); + return -EINVAL; + } + + room = IPWIRELESS_TX_QUEUE_SIZE - tty->tx_bytes_queued; + if (room < 0) + room = 0; + /* Don't allow caller to write any more than we have room for */ + if (count > room) + count = room; + + if (count == 0) { + mutex_unlock(&tty->ipw_tty_mutex); + return 0; + } + + ret = ipwireless_send_packet(tty->hardware, IPW_CHANNEL_RAS, + buf, count, + ipw_write_packet_sent_callback, tty); + if (ret == -1) { + mutex_unlock(&tty->ipw_tty_mutex); + return 0; + } + + tty->tx_bytes_queued += count; + mutex_unlock(&tty->ipw_tty_mutex); + + return count; +} + +static int ipw_write_room(struct tty_struct *linux_tty) +{ + struct ipw_tty *tty = linux_tty->driver_data; + int room; + + /* FIXME: Exactly how is the tty object locked here .. */ + if (!tty) + return -ENODEV; + + if (!tty->open_count) + return -EINVAL; + + room = IPWIRELESS_TX_QUEUE_SIZE - tty->tx_bytes_queued; + if (room < 0) + room = 0; + + return room; +} + +static int ipwireless_get_serial_info(struct ipw_tty *tty, + struct serial_struct __user *retinfo) +{ + struct serial_struct tmp; + + if (!retinfo) + return (-EFAULT); + + memset(&tmp, 0, sizeof(tmp)); + tmp.type = PORT_UNKNOWN; + tmp.line = tty->index; + tmp.port = 0; + tmp.irq = 0; + tmp.flags = 0; + tmp.baud_base = 115200; + tmp.close_delay = 0; + tmp.closing_wait = 0; + tmp.custom_divisor = 0; + tmp.hub6 = 0; + if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) + return -EFAULT; + + return 0; +} + +static int ipw_chars_in_buffer(struct tty_struct *linux_tty) +{ + struct ipw_tty *tty = linux_tty->driver_data; + + if (!tty) + return 0; + + if (!tty->open_count) + return 0; + + return tty->tx_bytes_queued; +} + +static int get_control_lines(struct ipw_tty *tty) +{ + unsigned int my = tty->control_lines; + unsigned int out = 0; + + if (my & IPW_CONTROL_LINE_RTS) + out |= TIOCM_RTS; + if (my & IPW_CONTROL_LINE_DTR) + out |= TIOCM_DTR; + if (my & IPW_CONTROL_LINE_CTS) + out |= TIOCM_CTS; + if (my & IPW_CONTROL_LINE_DSR) + out |= TIOCM_DSR; + if (my & IPW_CONTROL_LINE_DCD) + out |= TIOCM_CD; + + return out; +} + +static int set_control_lines(struct ipw_tty *tty, unsigned int set, + unsigned int clear) +{ + int ret; + + if (set & TIOCM_RTS) { + ret = ipwireless_set_RTS(tty->hardware, tty->channel_idx, 1); + if (ret) + return ret; + if (tty->secondary_channel_idx != -1) { + ret = ipwireless_set_RTS(tty->hardware, + tty->secondary_channel_idx, 1); + if (ret) + return ret; + } + } + if (set & TIOCM_DTR) { + ret = ipwireless_set_DTR(tty->hardware, tty->channel_idx, 1); + if (ret) + return ret; + if (tty->secondary_channel_idx != -1) { + ret = ipwireless_set_DTR(tty->hardware, + tty->secondary_channel_idx, 1); + if (ret) + return ret; + } + } + if (clear & TIOCM_RTS) { + ret = ipwireless_set_RTS(tty->hardware, tty->channel_idx, 0); + if (tty->secondary_channel_idx != -1) { + ret = ipwireless_set_RTS(tty->hardware, + tty->secondary_channel_idx, 0); + if (ret) + return ret; + } + } + if (clear & TIOCM_DTR) { + ret = ipwireless_set_DTR(tty->hardware, tty->channel_idx, 0); + if (tty->secondary_channel_idx != -1) { + ret = ipwireless_set_DTR(tty->hardware, + tty->secondary_channel_idx, 0); + if (ret) + return ret; + } + } + return 0; +} + +static int ipw_tiocmget(struct tty_struct *linux_tty) +{ + struct ipw_tty *tty = linux_tty->driver_data; + /* FIXME: Exactly how is the tty object locked here .. */ + + if (!tty) + return -ENODEV; + + if (!tty->open_count) + return -EINVAL; + + return get_control_lines(tty); +} + +static int +ipw_tiocmset(struct tty_struct *linux_tty, + unsigned int set, unsigned int clear) +{ + struct ipw_tty *tty = linux_tty->driver_data; + /* FIXME: Exactly how is the tty object locked here .. */ + + if (!tty) + return -ENODEV; + + if (!tty->open_count) + return -EINVAL; + + return set_control_lines(tty, set, clear); +} + +static int ipw_ioctl(struct tty_struct *linux_tty, + unsigned int cmd, unsigned long arg) +{ + struct ipw_tty *tty = linux_tty->driver_data; + + if (!tty) + return -ENODEV; + + if (!tty->open_count) + return -EINVAL; + + /* FIXME: Exactly how is the tty object locked here .. */ + + switch (cmd) { + case TIOCGSERIAL: + return ipwireless_get_serial_info(tty, (void __user *) arg); + + case TIOCSSERIAL: + return 0; /* Keeps the PCMCIA scripts happy. */ + } + + if (tty->tty_type == TTYTYPE_MODEM) { + switch (cmd) { + case PPPIOCGCHAN: + { + int chan = ipwireless_ppp_channel_index( + tty->network); + + if (chan < 0) + return -ENODEV; + if (put_user(chan, (int __user *) arg)) + return -EFAULT; + } + return 0; + + case PPPIOCGUNIT: + { + int unit = ipwireless_ppp_unit_number( + tty->network); + + if (unit < 0) + return -ENODEV; + if (put_user(unit, (int __user *) arg)) + return -EFAULT; + } + return 0; + + case FIONREAD: + { + int val = 0; + + if (put_user(val, (int __user *) arg)) + return -EFAULT; + } + return 0; + case TCFLSH: + return tty_perform_flush(linux_tty, arg); + } + } + return -ENOIOCTLCMD; +} + +static int add_tty(int j, + struct ipw_hardware *hardware, + struct ipw_network *network, int channel_idx, + int secondary_channel_idx, int tty_type) +{ + ttys[j] = kzalloc(sizeof(struct ipw_tty), GFP_KERNEL); + if (!ttys[j]) + return -ENOMEM; + ttys[j]->index = j; + ttys[j]->hardware = hardware; + ttys[j]->channel_idx = channel_idx; + ttys[j]->secondary_channel_idx = secondary_channel_idx; + ttys[j]->network = network; + ttys[j]->tty_type = tty_type; + mutex_init(&ttys[j]->ipw_tty_mutex); + + tty_register_device(ipw_tty_driver, j, NULL); + ipwireless_associate_network_tty(network, channel_idx, ttys[j]); + + if (secondary_channel_idx != -1) + ipwireless_associate_network_tty(network, + secondary_channel_idx, + ttys[j]); + if (get_tty(j + ipw_tty_driver->minor_start) == ttys[j]) + report_registering(ttys[j]); + return 0; +} + +struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hardware, + struct ipw_network *network) +{ + int i, j; + + for (i = 0; i < IPWIRELESS_PCMCIA_MINOR_RANGE; i++) { + int allfree = 1; + + for (j = i; j < IPWIRELESS_PCMCIA_MINORS; + j += IPWIRELESS_PCMCIA_MINOR_RANGE) + if (ttys[j] != NULL) { + allfree = 0; + break; + } + + if (allfree) { + j = i; + + if (add_tty(j, hardware, network, + IPW_CHANNEL_DIALLER, IPW_CHANNEL_RAS, + TTYTYPE_MODEM)) + return NULL; + + j += IPWIRELESS_PCMCIA_MINOR_RANGE; + if (add_tty(j, hardware, network, + IPW_CHANNEL_DIALLER, -1, + TTYTYPE_MONITOR)) + return NULL; + + j += IPWIRELESS_PCMCIA_MINOR_RANGE; + if (add_tty(j, hardware, network, + IPW_CHANNEL_RAS, -1, + TTYTYPE_RAS_RAW)) + return NULL; + + return ttys[i]; + } + } + return NULL; +} + +/* + * Must be called before ipwireless_network_free(). + */ +void ipwireless_tty_free(struct ipw_tty *tty) +{ + int j; + struct ipw_network *network = ttys[tty->index]->network; + + for (j = tty->index; j < IPWIRELESS_PCMCIA_MINORS; + j += IPWIRELESS_PCMCIA_MINOR_RANGE) { + struct ipw_tty *ttyj = ttys[j]; + + if (ttyj) { + mutex_lock(&ttyj->ipw_tty_mutex); + if (get_tty(j + ipw_tty_driver->minor_start) == ttyj) + report_deregistering(ttyj); + ttyj->closing = 1; + if (ttyj->linux_tty != NULL) { + mutex_unlock(&ttyj->ipw_tty_mutex); + tty_hangup(ttyj->linux_tty); + /* Wait till the tty_hangup has completed */ + flush_work_sync(&ttyj->linux_tty->hangup_work); + /* FIXME: Exactly how is the tty object locked here + against a parallel ioctl etc */ + mutex_lock(&ttyj->ipw_tty_mutex); + } + while (ttyj->open_count) + do_ipw_close(ttyj); + ipwireless_disassociate_network_ttys(network, + ttyj->channel_idx); + tty_unregister_device(ipw_tty_driver, j); + ttys[j] = NULL; + mutex_unlock(&ttyj->ipw_tty_mutex); + kfree(ttyj); + } + } +} + +static const struct tty_operations tty_ops = { + .open = ipw_open, + .close = ipw_close, + .hangup = ipw_hangup, + .write = ipw_write, + .write_room = ipw_write_room, + .ioctl = ipw_ioctl, + .chars_in_buffer = ipw_chars_in_buffer, + .tiocmget = ipw_tiocmget, + .tiocmset = ipw_tiocmset, +}; + +int ipwireless_tty_init(void) +{ + int result; + + ipw_tty_driver = alloc_tty_driver(IPWIRELESS_PCMCIA_MINORS); + if (!ipw_tty_driver) + return -ENOMEM; + + ipw_tty_driver->owner = THIS_MODULE; + ipw_tty_driver->driver_name = IPWIRELESS_PCCARD_NAME; + ipw_tty_driver->name = "ttyIPWp"; + ipw_tty_driver->major = 0; + ipw_tty_driver->minor_start = IPWIRELESS_PCMCIA_START; + ipw_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; + ipw_tty_driver->subtype = SERIAL_TYPE_NORMAL; + ipw_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + ipw_tty_driver->init_termios = tty_std_termios; + ipw_tty_driver->init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + ipw_tty_driver->init_termios.c_ispeed = 9600; + ipw_tty_driver->init_termios.c_ospeed = 9600; + tty_set_operations(ipw_tty_driver, &tty_ops); + result = tty_register_driver(ipw_tty_driver); + if (result) { + printk(KERN_ERR IPWIRELESS_PCCARD_NAME + ": failed to register tty driver\n"); + put_tty_driver(ipw_tty_driver); + return result; + } + + return 0; +} + +void ipwireless_tty_release(void) +{ + int ret; + + ret = tty_unregister_driver(ipw_tty_driver); + put_tty_driver(ipw_tty_driver); + if (ret != 0) + printk(KERN_ERR IPWIRELESS_PCCARD_NAME + ": tty_unregister_driver failed with code %d\n", ret); +} + +int ipwireless_tty_is_modem(struct ipw_tty *tty) +{ + return tty->tty_type == TTYTYPE_MODEM; +} + +void +ipwireless_tty_notify_control_line_change(struct ipw_tty *tty, + unsigned int channel_idx, + unsigned int control_lines, + unsigned int changed_mask) +{ + unsigned int old_control_lines = tty->control_lines; + + tty->control_lines = (tty->control_lines & ~changed_mask) + | (control_lines & changed_mask); + + /* + * If DCD is de-asserted, we close the tty so pppd can tell that we + * have gone offline. + */ + if ((old_control_lines & IPW_CONTROL_LINE_DCD) + && !(tty->control_lines & IPW_CONTROL_LINE_DCD) + && tty->linux_tty) { + tty_hangup(tty->linux_tty); + } +} + diff --git a/drivers/tty/ipwireless/tty.h b/drivers/tty/ipwireless/tty.h new file mode 100644 index 000000000000..747b2d637860 --- /dev/null +++ b/drivers/tty/ipwireless/tty.h @@ -0,0 +1,45 @@ +/* + * IPWireless 3G PCMCIA Network Driver + * + * Original code + * by Stephen Blackheath , + * Ben Martel + * + * Copyrighted as follows: + * Copyright (C) 2004 by Symmetric Systems Ltd (NZ) + * + * Various driver changes and rewrites, port to new kernels + * Copyright (C) 2006-2007 Jiri Kosina + * + * Misc code cleanups and updates + * Copyright (C) 2007 David Sterba + */ + +#ifndef _IPWIRELESS_CS_TTY_H_ +#define _IPWIRELESS_CS_TTY_H_ + +#include +#include + +#include +#include + +struct ipw_tty; +struct ipw_network; +struct ipw_hardware; + +int ipwireless_tty_init(void); +void ipwireless_tty_release(void); + +struct ipw_tty *ipwireless_tty_create(struct ipw_hardware *hw, + struct ipw_network *net); +void ipwireless_tty_free(struct ipw_tty *tty); +void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data, + unsigned int length); +int ipwireless_tty_is_modem(struct ipw_tty *tty); +void ipwireless_tty_notify_control_line_change(struct ipw_tty *tty, + unsigned int channel_idx, + unsigned int control_lines, + unsigned int changed_mask); + +#endif -- cgit v1.2.3 From f72487e7a1827f5e95425b80ec4fcc4f928329e8 Mon Sep 17 00:00:00 2001 From: Balaji T K Date: Tue, 22 Feb 2011 12:25:39 +0530 Subject: i2c-omap: fix build for !CONFIG_SUSPEND fix the build break when !CONFIG_SUSPEND drivers/i2c/busses/i2c-omap.c:1173: error: lvalue required as unary '&' operand make[3]: *** [drivers/i2c/busses/i2c-omap.o] Error 1 make[2]: *** [drivers/i2c/busses] Error 2 make[1]: *** [drivers/i2c] Error 2 make: *** [drivers] Error 2 Signed-off-by: Balaji T K Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-omap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 0541df90b9fb..adc1ee53b1a1 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1160,8 +1160,9 @@ static struct dev_pm_ops omap_i2c_pm_ops = { .suspend = omap_i2c_suspend, .resume = omap_i2c_resume, }; +#define OMAP_I2C_PM_OPS (&omap_i2c_pm_ops) #else -#define omap_i2c_pm_ops NULL +#define OMAP_I2C_PM_OPS NULL #endif static struct platform_driver omap_i2c_driver = { @@ -1170,7 +1171,7 @@ static struct platform_driver omap_i2c_driver = { .driver = { .name = "omap_i2c", .owner = THIS_MODULE, - .pm = &omap_i2c_pm_ops, + .pm = OMAP_I2C_PM_OPS, }, }; -- cgit v1.2.3 From cb527ede1bf6ff2008a025606f25344b8ed7b4ac Mon Sep 17 00:00:00 2001 From: Richard woodruff Date: Wed, 16 Feb 2011 10:24:16 +0530 Subject: i2c-omap: Double clear of ARDY status in IRQ handler This errata occurs when the ARDY interrupt generation is enabled. At the begining of every new transaction the ARDY interrupt is cleared. On continuous i2c transactions where after clearing the ARDY bit from I2C_STAT register (clearing the interrupt), the IRQ line is reasserted and the I2C_STAT[ARDY] bit set again on 1. In fact, the ARDY status bit is not cleared at the write access to I2C_STAT[ARDY] and only the IRQ line is deasserted and then reasserted. This is not captured in the usual errata documents. The workaround is to have a double clear of ARDY status in irq handler. Signed-off-by: Richard woodruff Signed-off-by: Keerthy Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-omap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index adc1ee53b1a1..e3f925ac1c39 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -847,11 +847,15 @@ complete: dev_err(dev->dev, "Arbitration lost\n"); err |= OMAP_I2C_STAT_AL; } + /* + * ProDB0017052: Clear ARDY bit twice + */ if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { omap_i2c_ack_stat(dev, stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR | - OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); + OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR | + OMAP_I2C_STAT_ARDY)); omap_i2c_complete_cmd(dev, err); return IRQ_HANDLED; } -- cgit v1.2.3 From a5a595cc36bbbe16f6a3f0e6968f94a0604bfd28 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 23 Feb 2011 00:43:55 +0000 Subject: i2c-omap: fixup commit cb527ede1bf6ff2008a025606f25344b8ed7b4ac whitespace Fixup the whitespace error noticed in cb527ede1bf6ff2008a025606f25344b8ed7b4ac Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-omap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index e3f925ac1c39..829a2a1029f7 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -847,9 +847,9 @@ complete: dev_err(dev->dev, "Arbitration lost\n"); err |= OMAP_I2C_STAT_AL; } - /* + /* * ProDB0017052: Clear ARDY bit twice - */ + */ if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { omap_i2c_ack_stat(dev, stat & -- cgit v1.2.3 From cc7fb05946fb1cd2fd0582f9e39f759e20dfeefa Mon Sep 17 00:00:00 2001 From: Mitko Haralanov Date: Tue, 22 Feb 2011 16:56:37 -0800 Subject: IB/qib: Return correct MAD when setting link width to 255 Fix a bug which causes the driver to return incorrect MADs as a response to Set(PortInfo) which sets the link width to 0xFF or link speed to 0xF. Signed-off-by: Mitko Haralanov Signed-off-by: Mike Marciniszyn Signed-off-by: Roland Dreier --- drivers/infiniband/hw/qib/qib_mad.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/qib/qib_mad.c b/drivers/infiniband/hw/qib/qib_mad.c index 5ad224e4a38b..4b9e11cc561b 100644 --- a/drivers/infiniband/hw/qib/qib_mad.c +++ b/drivers/infiniband/hw/qib/qib_mad.c @@ -705,7 +705,7 @@ static int subn_set_portinfo(struct ib_smp *smp, struct ib_device *ibdev, lwe = pip->link_width_enabled; if (lwe) { if (lwe == 0xFF) - lwe = ppd->link_width_supported; + set_link_width_enabled(ppd, ppd->link_width_supported); else if (lwe >= 16 || (lwe & ~ppd->link_width_supported)) smp->status |= IB_SMP_INVALID_FIELD; else if (lwe != ppd->link_width_enabled) @@ -720,7 +720,8 @@ static int subn_set_portinfo(struct ib_smp *smp, struct ib_device *ibdev, * speeds. */ if (lse == 15) - lse = ppd->link_speed_supported; + set_link_speed_enabled(ppd, + ppd->link_speed_supported); else if (lse >= 8 || (lse & ~ppd->link_speed_supported)) smp->status |= IB_SMP_INVALID_FIELD; else if (lse != ppd->link_speed_enabled) @@ -849,7 +850,7 @@ static int subn_set_portinfo(struct ib_smp *smp, struct ib_device *ibdev, if (clientrereg) pip->clientrereg_resv_subnetto |= 0x80; - goto done; + goto get_only; err: smp->status |= IB_SMP_INVALID_FIELD; -- cgit v1.2.3 From 4a6514e6d096716fb7bedf238efaaca877e2a7e8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Feb 2011 16:57:21 -0800 Subject: tty: move obsolete and broken tty drivers to drivers/staging/tty/ As planned by Arnd Bergmann, this moves the following drivers to the drivers/staging/tty/ directory where they will be removed after 2.6.41 if no one steps up to claim them. epca epca ip2 istallion riscom8 serial167 specialix stallion Cc: Arnd Bergmann Cc: Alan Cox Cc: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- arch/m68k/Kconfig | 8 - drivers/char/Kconfig | 79 - drivers/char/Makefile | 7 - drivers/char/epca.c | 2784 --------------------- drivers/char/epca.h | 158 -- drivers/char/epcaconfig.h | 7 - drivers/char/ip2/Makefile | 8 - drivers/char/ip2/i2cmd.c | 210 -- drivers/char/ip2/i2cmd.h | 630 ----- drivers/char/ip2/i2ellis.c | 1403 ----------- drivers/char/ip2/i2ellis.h | 566 ----- drivers/char/ip2/i2hw.h | 652 ----- drivers/char/ip2/i2lib.c | 2214 ----------------- drivers/char/ip2/i2lib.h | 351 --- drivers/char/ip2/i2pack.h | 364 --- drivers/char/ip2/ip2.h | 107 - drivers/char/ip2/ip2ioctl.h | 35 - drivers/char/ip2/ip2main.c | 3234 ------------------------ drivers/char/ip2/ip2trace.h | 42 - drivers/char/ip2/ip2types.h | 57 - drivers/char/istallion.c | 4507 --------------------------------- drivers/char/riscom8.c | 1560 ------------ drivers/char/riscom8.h | 91 - drivers/char/riscom8_reg.h | 254 -- drivers/char/serial167.c | 2489 ------------------- drivers/char/specialix.c | 2368 ------------------ drivers/char/specialix_io8.h | 140 -- drivers/char/stallion.c | 4651 ----------------------------------- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/tty/Kconfig | 87 + drivers/staging/tty/Makefile | 7 + drivers/staging/tty/TODO | 6 + drivers/staging/tty/epca.c | 2784 +++++++++++++++++++++ drivers/staging/tty/epca.h | 158 ++ drivers/staging/tty/epcaconfig.h | 7 + drivers/staging/tty/ip2/Makefile | 8 + drivers/staging/tty/ip2/i2cmd.c | 210 ++ drivers/staging/tty/ip2/i2cmd.h | 630 +++++ drivers/staging/tty/ip2/i2ellis.c | 1403 +++++++++++ drivers/staging/tty/ip2/i2ellis.h | 566 +++++ drivers/staging/tty/ip2/i2hw.h | 652 +++++ drivers/staging/tty/ip2/i2lib.c | 2214 +++++++++++++++++ drivers/staging/tty/ip2/i2lib.h | 351 +++ drivers/staging/tty/ip2/i2pack.h | 364 +++ drivers/staging/tty/ip2/ip2.h | 107 + drivers/staging/tty/ip2/ip2ioctl.h | 35 + drivers/staging/tty/ip2/ip2main.c | 3234 ++++++++++++++++++++++++ drivers/staging/tty/ip2/ip2trace.h | 42 + drivers/staging/tty/ip2/ip2types.h | 57 + drivers/staging/tty/istallion.c | 4507 +++++++++++++++++++++++++++++++++ drivers/staging/tty/riscom8.c | 1560 ++++++++++++ drivers/staging/tty/riscom8.h | 91 + drivers/staging/tty/riscom8_reg.h | 254 ++ drivers/staging/tty/serial167.c | 2489 +++++++++++++++++++ drivers/staging/tty/specialix.c | 2368 ++++++++++++++++++ drivers/staging/tty/specialix_io8.h | 140 ++ drivers/staging/tty/stallion.c | 4651 +++++++++++++++++++++++++++++++++++ 58 files changed, 28985 insertions(+), 28976 deletions(-) delete mode 100644 drivers/char/epca.c delete mode 100644 drivers/char/epca.h delete mode 100644 drivers/char/epcaconfig.h delete mode 100644 drivers/char/ip2/Makefile delete mode 100644 drivers/char/ip2/i2cmd.c delete mode 100644 drivers/char/ip2/i2cmd.h delete mode 100644 drivers/char/ip2/i2ellis.c delete mode 100644 drivers/char/ip2/i2ellis.h delete mode 100644 drivers/char/ip2/i2hw.h delete mode 100644 drivers/char/ip2/i2lib.c delete mode 100644 drivers/char/ip2/i2lib.h delete mode 100644 drivers/char/ip2/i2pack.h delete mode 100644 drivers/char/ip2/ip2.h delete mode 100644 drivers/char/ip2/ip2ioctl.h delete mode 100644 drivers/char/ip2/ip2main.c delete mode 100644 drivers/char/ip2/ip2trace.h delete mode 100644 drivers/char/ip2/ip2types.h delete mode 100644 drivers/char/istallion.c delete mode 100644 drivers/char/riscom8.c delete mode 100644 drivers/char/riscom8.h delete mode 100644 drivers/char/riscom8_reg.h delete mode 100644 drivers/char/serial167.c delete mode 100644 drivers/char/specialix.c delete mode 100644 drivers/char/specialix_io8.h delete mode 100644 drivers/char/stallion.c create mode 100644 drivers/staging/tty/Kconfig create mode 100644 drivers/staging/tty/Makefile create mode 100644 drivers/staging/tty/TODO create mode 100644 drivers/staging/tty/epca.c create mode 100644 drivers/staging/tty/epca.h create mode 100644 drivers/staging/tty/epcaconfig.h create mode 100644 drivers/staging/tty/ip2/Makefile create mode 100644 drivers/staging/tty/ip2/i2cmd.c create mode 100644 drivers/staging/tty/ip2/i2cmd.h create mode 100644 drivers/staging/tty/ip2/i2ellis.c create mode 100644 drivers/staging/tty/ip2/i2ellis.h create mode 100644 drivers/staging/tty/ip2/i2hw.h create mode 100644 drivers/staging/tty/ip2/i2lib.c create mode 100644 drivers/staging/tty/ip2/i2lib.h create mode 100644 drivers/staging/tty/ip2/i2pack.h create mode 100644 drivers/staging/tty/ip2/ip2.h create mode 100644 drivers/staging/tty/ip2/ip2ioctl.h create mode 100644 drivers/staging/tty/ip2/ip2main.c create mode 100644 drivers/staging/tty/ip2/ip2trace.h create mode 100644 drivers/staging/tty/ip2/ip2types.h create mode 100644 drivers/staging/tty/istallion.c create mode 100644 drivers/staging/tty/riscom8.c create mode 100644 drivers/staging/tty/riscom8.h create mode 100644 drivers/staging/tty/riscom8_reg.h create mode 100644 drivers/staging/tty/serial167.c create mode 100644 drivers/staging/tty/specialix.c create mode 100644 drivers/staging/tty/specialix_io8.h create mode 100644 drivers/staging/tty/stallion.c (limited to 'drivers') diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index bc9271b85759..a85e251c411f 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -554,14 +554,6 @@ config MVME147_SCC This is the driver for the serial ports on the Motorola MVME147 boards. Everyone using one of these boards should say Y here. -config SERIAL167 - bool "CD2401 support for MVME166/7 serial ports" - depends on MVME16x - help - This is the driver for the serial ports on the Motorola MVME166, - 167, and 172 boards. Everyone using one of these boards should say - Y here. - config MVME162_SCC bool "SCC support for MVME162 serial ports" depends on MVME16x && BROKEN diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 1adfac6a7b0b..7b8cf0295f6c 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -15,63 +15,6 @@ config DEVKMEM kind of kernel debugging operations. When in doubt, say "N". -config COMPUTONE - tristate "Computone IntelliPort Plus serial support" - depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) - ---help--- - This driver supports the entire family of Intelliport II/Plus - controllers with the exception of the MicroChannel controllers and - products previous to the Intelliport II. These are multiport cards, - which give you many serial ports. You would need something like this - to connect more than two modems to your Linux box, for instance in - order to become a dial-in server. If you have a card like that, say - Y here and read . - - To compile this driver as module, choose M here: the - module will be called ip2. - -config DIGIEPCA - tristate "Digiboard Intelligent Async Support" - depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) - ---help--- - This is a driver for Digi International's Xx, Xeve, and Xem series - of cards which provide multiple serial ports. You would need - something like this to connect more than two modems to your Linux - box, for instance in order to become a dial-in server. This driver - supports the original PC (ISA) boards as well as PCI, and EISA. If - you have a card like this, say Y here and read the file - . - - To compile this driver as a module, choose M here: the - module will be called epca. - -config RISCOM8 - tristate "SDL RISCom/8 card support" - depends on SERIAL_NONSTANDARD - help - This is a driver for the SDL Communications RISCom/8 multiport card, - which gives you many serial ports. You would need something like - this to connect more than two modems to your Linux box, for instance - in order to become a dial-in server. If you have a card like that, - say Y here and read the file . - - Also it's possible to say M here and compile this driver as kernel - loadable module; the module will be called riscom8. - -config SPECIALIX - tristate "Specialix IO8+ card support" - depends on SERIAL_NONSTANDARD - help - This is a driver for the Specialix IO8+ multiport card (both the - ISA and the PCI version) which gives you many serial ports. You - would need something like this to connect more than two modems to - your Linux box, for instance in order to become a dial-in server. - - If you have a card like that, say Y here and read the file - . Also it's possible to say - M here and compile this driver as kernel loadable module which will be - called specialix. - config SX tristate "Specialix SX (and SI) card support" depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) && BROKEN @@ -112,28 +55,6 @@ config STALDRV in this case. If you have never heard about all this, it's safe to say N. -config STALLION - tristate "Stallion EasyIO or EC8/32 support" - depends on STALDRV && (ISA || EISA || PCI) - help - If you have an EasyIO or EasyConnection 8/32 multiport Stallion - card, then this is for you; say Y. Make sure to read - . - - To compile this driver as a module, choose M here: the - module will be called stallion. - -config ISTALLION - tristate "Stallion EC8/64, ONboard, Brumby support" - depends on STALDRV && (ISA || EISA || PCI) - help - If you have an EasyConnection 8/64, ONboard, Brumby or Stallion - serial multiport card, say Y here. Make sure to read - . - - To compile this driver as a module, choose M here: the - module will be called istallion. - config A2232 tristate "Commodore A2232 serial support (EXPERIMENTAL)" depends on EXPERIMENTAL && ZORRO && BROKEN diff --git a/drivers/char/Makefile b/drivers/char/Makefile index f5dc7c9bce6b..48bb8acbea49 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -8,15 +8,8 @@ obj-y += misc.o obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o -obj-$(CONFIG_SERIAL167) += serial167.o -obj-$(CONFIG_STALLION) += stallion.o -obj-$(CONFIG_ISTALLION) += istallion.o -obj-$(CONFIG_DIGIEPCA) += epca.o -obj-$(CONFIG_SPECIALIX) += specialix.o obj-$(CONFIG_A2232) += ser_a2232.o generic_serial.o obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o -obj-$(CONFIG_COMPUTONE) += ip2/ -obj-$(CONFIG_RISCOM8) += riscom8.o obj-$(CONFIG_SX) += sx.o generic_serial.o obj-$(CONFIG_RIO) += rio/ generic_serial.o obj-$(CONFIG_RAW_DRIVER) += raw.o diff --git a/drivers/char/epca.c b/drivers/char/epca.c deleted file mode 100644 index 7ad3638967ae..000000000000 --- a/drivers/char/epca.c +++ /dev/null @@ -1,2784 +0,0 @@ -/* - Copyright (C) 1996 Digi International. - - For technical support please email digiLinux@dgii.com or - call Digi tech support at (612) 912-3456 - - ** This driver is no longer supported by Digi ** - - Much of this design and code came from epca.c which was - copyright (C) 1994, 1995 Troy De Jongh, and subsquently - modified by David Nugent, Christoph Lameter, Mike McLagan. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ -/* See README.epca for change history --DAT*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "digiPCI.h" - - -#include "digi1.h" -#include "digiFep1.h" -#include "epca.h" -#include "epcaconfig.h" - -#define VERSION "1.3.0.1-LK2.6" - -/* This major needs to be submitted to Linux to join the majors list */ -#define DIGIINFOMAJOR 35 /* For Digi specific ioctl */ - - -#define MAXCARDS 7 -#define epcaassert(x, msg) if (!(x)) epca_error(__LINE__, msg) - -#define PFX "epca: " - -static int nbdevs, num_cards, liloconfig; -static int digi_poller_inhibited = 1 ; - -static int setup_error_code; -static int invalid_lilo_config; - -/* - * The ISA boards do window flipping into the same spaces so its only sane with - * a single lock. It's still pretty efficient. This lock guards the hardware - * and the tty_port lock guards the kernel side stuff like use counts. Take - * this lock inside the port lock if you must take both. - */ -static DEFINE_SPINLOCK(epca_lock); - -/* MAXBOARDS is typically 12, but ISA and EISA cards are restricted - to 7 below. */ -static struct board_info boards[MAXBOARDS]; - -static struct tty_driver *pc_driver; -static struct tty_driver *pc_info; - -/* ------------------ Begin Digi specific structures -------------------- */ - -/* - * digi_channels represents an array of structures that keep track of each - * channel of the Digi product. Information such as transmit and receive - * pointers, termio data, and signal definitions (DTR, CTS, etc ...) are stored - * here. This structure is NOT used to overlay the cards physical channel - * structure. - */ -static struct channel digi_channels[MAX_ALLOC]; - -/* - * card_ptr is an array used to hold the address of the first channel structure - * of each card. This array will hold the addresses of various channels located - * in digi_channels. - */ -static struct channel *card_ptr[MAXCARDS]; - -static struct timer_list epca_timer; - -/* - * Begin generic memory functions. These functions will be alias (point at) - * more specific functions dependent on the board being configured. - */ -static void memwinon(struct board_info *b, unsigned int win); -static void memwinoff(struct board_info *b, unsigned int win); -static void globalwinon(struct channel *ch); -static void rxwinon(struct channel *ch); -static void txwinon(struct channel *ch); -static void memoff(struct channel *ch); -static void assertgwinon(struct channel *ch); -static void assertmemoff(struct channel *ch); - -/* ---- Begin more 'specific' memory functions for cx_like products --- */ - -static void pcxem_memwinon(struct board_info *b, unsigned int win); -static void pcxem_memwinoff(struct board_info *b, unsigned int win); -static void pcxem_globalwinon(struct channel *ch); -static void pcxem_rxwinon(struct channel *ch); -static void pcxem_txwinon(struct channel *ch); -static void pcxem_memoff(struct channel *ch); - -/* ------ Begin more 'specific' memory functions for the pcxe ------- */ - -static void pcxe_memwinon(struct board_info *b, unsigned int win); -static void pcxe_memwinoff(struct board_info *b, unsigned int win); -static void pcxe_globalwinon(struct channel *ch); -static void pcxe_rxwinon(struct channel *ch); -static void pcxe_txwinon(struct channel *ch); -static void pcxe_memoff(struct channel *ch); - -/* ---- Begin more 'specific' memory functions for the pc64xe and pcxi ---- */ -/* Note : pc64xe and pcxi share the same windowing routines */ - -static void pcxi_memwinon(struct board_info *b, unsigned int win); -static void pcxi_memwinoff(struct board_info *b, unsigned int win); -static void pcxi_globalwinon(struct channel *ch); -static void pcxi_rxwinon(struct channel *ch); -static void pcxi_txwinon(struct channel *ch); -static void pcxi_memoff(struct channel *ch); - -/* - Begin 'specific' do nothing memory functions needed for some cards - */ - -static void dummy_memwinon(struct board_info *b, unsigned int win); -static void dummy_memwinoff(struct board_info *b, unsigned int win); -static void dummy_globalwinon(struct channel *ch); -static void dummy_rxwinon(struct channel *ch); -static void dummy_txwinon(struct channel *ch); -static void dummy_memoff(struct channel *ch); -static void dummy_assertgwinon(struct channel *ch); -static void dummy_assertmemoff(struct channel *ch); - -static struct channel *verifyChannel(struct tty_struct *); -static void pc_sched_event(struct channel *, int); -static void epca_error(int, char *); -static void pc_close(struct tty_struct *, struct file *); -static void shutdown(struct channel *, struct tty_struct *tty); -static void pc_hangup(struct tty_struct *); -static int pc_write_room(struct tty_struct *); -static int pc_chars_in_buffer(struct tty_struct *); -static void pc_flush_buffer(struct tty_struct *); -static void pc_flush_chars(struct tty_struct *); -static int pc_open(struct tty_struct *, struct file *); -static void post_fep_init(unsigned int crd); -static void epcapoll(unsigned long); -static void doevent(int); -static void fepcmd(struct channel *, int, int, int, int, int); -static unsigned termios2digi_h(struct channel *ch, unsigned); -static unsigned termios2digi_i(struct channel *ch, unsigned); -static unsigned termios2digi_c(struct channel *ch, unsigned); -static void epcaparam(struct tty_struct *, struct channel *); -static void receive_data(struct channel *, struct tty_struct *tty); -static int pc_ioctl(struct tty_struct *, - unsigned int, unsigned long); -static int info_ioctl(struct tty_struct *, - unsigned int, unsigned long); -static void pc_set_termios(struct tty_struct *, struct ktermios *); -static void do_softint(struct work_struct *work); -static void pc_stop(struct tty_struct *); -static void pc_start(struct tty_struct *); -static void pc_throttle(struct tty_struct *tty); -static void pc_unthrottle(struct tty_struct *tty); -static int pc_send_break(struct tty_struct *tty, int msec); -static void setup_empty_event(struct tty_struct *tty, struct channel *ch); - -static int pc_write(struct tty_struct *, const unsigned char *, int); -static int pc_init(void); -static int init_PCI(void); - -/* - * Table of functions for each board to handle memory. Mantaining parallelism - * is a *very* good idea here. The idea is for the runtime code to blindly call - * these functions, not knowing/caring about the underlying hardware. This - * stuff should contain no conditionals; if more functionality is needed a - * different entry should be established. These calls are the interface calls - * and are the only functions that should be accessed. Anyone caught making - * direct calls deserves what they get. - */ -static void memwinon(struct board_info *b, unsigned int win) -{ - b->memwinon(b, win); -} - -static void memwinoff(struct board_info *b, unsigned int win) -{ - b->memwinoff(b, win); -} - -static void globalwinon(struct channel *ch) -{ - ch->board->globalwinon(ch); -} - -static void rxwinon(struct channel *ch) -{ - ch->board->rxwinon(ch); -} - -static void txwinon(struct channel *ch) -{ - ch->board->txwinon(ch); -} - -static void memoff(struct channel *ch) -{ - ch->board->memoff(ch); -} -static void assertgwinon(struct channel *ch) -{ - ch->board->assertgwinon(ch); -} - -static void assertmemoff(struct channel *ch) -{ - ch->board->assertmemoff(ch); -} - -/* PCXEM windowing is the same as that used in the PCXR and CX series cards. */ -static void pcxem_memwinon(struct board_info *b, unsigned int win) -{ - outb_p(FEPWIN | win, b->port + 1); -} - -static void pcxem_memwinoff(struct board_info *b, unsigned int win) -{ - outb_p(0, b->port + 1); -} - -static void pcxem_globalwinon(struct channel *ch) -{ - outb_p(FEPWIN, (int)ch->board->port + 1); -} - -static void pcxem_rxwinon(struct channel *ch) -{ - outb_p(ch->rxwin, (int)ch->board->port + 1); -} - -static void pcxem_txwinon(struct channel *ch) -{ - outb_p(ch->txwin, (int)ch->board->port + 1); -} - -static void pcxem_memoff(struct channel *ch) -{ - outb_p(0, (int)ch->board->port + 1); -} - -/* ----------------- Begin pcxe memory window stuff ------------------ */ -static void pcxe_memwinon(struct board_info *b, unsigned int win) -{ - outb_p(FEPWIN | win, b->port + 1); -} - -static void pcxe_memwinoff(struct board_info *b, unsigned int win) -{ - outb_p(inb(b->port) & ~FEPMEM, b->port + 1); - outb_p(0, b->port + 1); -} - -static void pcxe_globalwinon(struct channel *ch) -{ - outb_p(FEPWIN, (int)ch->board->port + 1); -} - -static void pcxe_rxwinon(struct channel *ch) -{ - outb_p(ch->rxwin, (int)ch->board->port + 1); -} - -static void pcxe_txwinon(struct channel *ch) -{ - outb_p(ch->txwin, (int)ch->board->port + 1); -} - -static void pcxe_memoff(struct channel *ch) -{ - outb_p(0, (int)ch->board->port); - outb_p(0, (int)ch->board->port + 1); -} - -/* ------------- Begin pc64xe and pcxi memory window stuff -------------- */ -static void pcxi_memwinon(struct board_info *b, unsigned int win) -{ - outb_p(inb(b->port) | FEPMEM, b->port); -} - -static void pcxi_memwinoff(struct board_info *b, unsigned int win) -{ - outb_p(inb(b->port) & ~FEPMEM, b->port); -} - -static void pcxi_globalwinon(struct channel *ch) -{ - outb_p(FEPMEM, ch->board->port); -} - -static void pcxi_rxwinon(struct channel *ch) -{ - outb_p(FEPMEM, ch->board->port); -} - -static void pcxi_txwinon(struct channel *ch) -{ - outb_p(FEPMEM, ch->board->port); -} - -static void pcxi_memoff(struct channel *ch) -{ - outb_p(0, ch->board->port); -} - -static void pcxi_assertgwinon(struct channel *ch) -{ - epcaassert(inb(ch->board->port) & FEPMEM, "Global memory off"); -} - -static void pcxi_assertmemoff(struct channel *ch) -{ - epcaassert(!(inb(ch->board->port) & FEPMEM), "Memory on"); -} - -/* - * Not all of the cards need specific memory windowing routines. Some cards - * (Such as PCI) needs no windowing routines at all. We provide these do - * nothing routines so that the same code base can be used. The driver will - * ALWAYS call a windowing routine if it thinks it needs to; regardless of the - * card. However, dependent on the card the routine may or may not do anything. - */ -static void dummy_memwinon(struct board_info *b, unsigned int win) -{ -} - -static void dummy_memwinoff(struct board_info *b, unsigned int win) -{ -} - -static void dummy_globalwinon(struct channel *ch) -{ -} - -static void dummy_rxwinon(struct channel *ch) -{ -} - -static void dummy_txwinon(struct channel *ch) -{ -} - -static void dummy_memoff(struct channel *ch) -{ -} - -static void dummy_assertgwinon(struct channel *ch) -{ -} - -static void dummy_assertmemoff(struct channel *ch) -{ -} - -static struct channel *verifyChannel(struct tty_struct *tty) -{ - /* - * This routine basically provides a sanity check. It insures that the - * channel returned is within the proper range of addresses as well as - * properly initialized. If some bogus info gets passed in - * through tty->driver_data this should catch it. - */ - if (tty) { - struct channel *ch = tty->driver_data; - if (ch >= &digi_channels[0] && ch < &digi_channels[nbdevs]) { - if (ch->magic == EPCA_MAGIC) - return ch; - } - } - return NULL; -} - -static void pc_sched_event(struct channel *ch, int event) -{ - /* - * We call this to schedule interrupt processing on some event. The - * kernel sees our request and calls the related routine in OUR driver. - */ - ch->event |= 1 << event; - schedule_work(&ch->tqueue); -} - -static void epca_error(int line, char *msg) -{ - printk(KERN_ERR "epca_error (Digi): line = %d %s\n", line, msg); -} - -static void pc_close(struct tty_struct *tty, struct file *filp) -{ - struct channel *ch; - struct tty_port *port; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch == NULL) - return; - port = &ch->port; - - if (tty_port_close_start(port, tty, filp) == 0) - return; - - pc_flush_buffer(tty); - shutdown(ch, tty); - - tty_port_close_end(port, tty); - ch->event = 0; /* FIXME: review ch->event locking */ - tty_port_tty_set(port, NULL); -} - -static void shutdown(struct channel *ch, struct tty_struct *tty) -{ - unsigned long flags; - struct board_chan __iomem *bc; - struct tty_port *port = &ch->port; - - if (!(port->flags & ASYNC_INITIALIZED)) - return; - - spin_lock_irqsave(&epca_lock, flags); - - globalwinon(ch); - bc = ch->brdchan; - - /* - * In order for an event to be generated on the receipt of data the - * idata flag must be set. Since we are shutting down, this is not - * necessary clear this flag. - */ - if (bc) - writeb(0, &bc->idata); - - /* If we're a modem control device and HUPCL is on, drop RTS & DTR. */ - if (tty->termios->c_cflag & HUPCL) { - ch->omodem &= ~(ch->m_rts | ch->m_dtr); - fepcmd(ch, SETMODEM, 0, ch->m_dtr | ch->m_rts, 10, 1); - } - memoff(ch); - - /* - * The channel has officialy been closed. The next time it is opened it - * will have to reinitialized. Set a flag to indicate this. - */ - /* Prevent future Digi programmed interrupts from coming active */ - port->flags &= ~ASYNC_INITIALIZED; - spin_unlock_irqrestore(&epca_lock, flags); -} - -static void pc_hangup(struct tty_struct *tty) -{ - struct channel *ch; - - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch != NULL) { - pc_flush_buffer(tty); - tty_ldisc_flush(tty); - shutdown(ch, tty); - - ch->event = 0; /* FIXME: review locking of ch->event */ - tty_port_hangup(&ch->port); - } -} - -static int pc_write(struct tty_struct *tty, - const unsigned char *buf, int bytesAvailable) -{ - unsigned int head, tail; - int dataLen; - int size; - int amountCopied; - struct channel *ch; - unsigned long flags; - int remain; - struct board_chan __iomem *bc; - - /* - * pc_write is primarily called directly by the kernel routine - * tty_write (Though it can also be called by put_char) found in - * tty_io.c. pc_write is passed a line discipline buffer where the data - * to be written out is stored. The line discipline implementation - * itself is done at the kernel level and is not brought into the - * driver. - */ - - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch == NULL) - return 0; - - /* Make a pointer to the channel data structure found on the board. */ - bc = ch->brdchan; - size = ch->txbufsize; - amountCopied = 0; - - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - - head = readw(&bc->tin) & (size - 1); - tail = readw(&bc->tout); - - if (tail != readw(&bc->tout)) - tail = readw(&bc->tout); - tail &= (size - 1); - - if (head >= tail) { - /* head has not wrapped */ - /* - * remain (much like dataLen above) represents the total amount - * of space available on the card for data. Here dataLen - * represents the space existing between the head pointer and - * the end of buffer. This is important because a memcpy cannot - * be told to automatically wrap around when it hits the buffer - * end. - */ - dataLen = size - head; - remain = size - (head - tail) - 1; - } else { - /* head has wrapped around */ - remain = tail - head - 1; - dataLen = remain; - } - /* - * Check the space on the card. If we have more data than space; reduce - * the amount of data to fit the space. - */ - bytesAvailable = min(remain, bytesAvailable); - txwinon(ch); - while (bytesAvailable > 0) { - /* there is data to copy onto card */ - - /* - * If head is not wrapped, the below will make sure the first - * data copy fills to the end of card buffer. - */ - dataLen = min(bytesAvailable, dataLen); - memcpy_toio(ch->txptr + head, buf, dataLen); - buf += dataLen; - head += dataLen; - amountCopied += dataLen; - bytesAvailable -= dataLen; - - if (head >= size) { - head = 0; - dataLen = tail; - } - } - ch->statusflags |= TXBUSY; - globalwinon(ch); - writew(head, &bc->tin); - - if ((ch->statusflags & LOWWAIT) == 0) { - ch->statusflags |= LOWWAIT; - writeb(1, &bc->ilow); - } - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - return amountCopied; -} - -static int pc_write_room(struct tty_struct *tty) -{ - int remain = 0; - struct channel *ch; - unsigned long flags; - unsigned int head, tail; - struct board_chan __iomem *bc; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch != NULL) { - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - - bc = ch->brdchan; - head = readw(&bc->tin) & (ch->txbufsize - 1); - tail = readw(&bc->tout); - - if (tail != readw(&bc->tout)) - tail = readw(&bc->tout); - /* Wrap tail if necessary */ - tail &= (ch->txbufsize - 1); - remain = tail - head - 1; - if (remain < 0) - remain += ch->txbufsize; - - if (remain && (ch->statusflags & LOWWAIT) == 0) { - ch->statusflags |= LOWWAIT; - writeb(1, &bc->ilow); - } - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - } - /* Return how much room is left on card */ - return remain; -} - -static int pc_chars_in_buffer(struct tty_struct *tty) -{ - int chars; - unsigned int ctail, head, tail; - int remain; - unsigned long flags; - struct channel *ch; - struct board_chan __iomem *bc; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch == NULL) - return 0; - - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - - bc = ch->brdchan; - tail = readw(&bc->tout); - head = readw(&bc->tin); - ctail = readw(&ch->mailbox->cout); - - if (tail == head && readw(&ch->mailbox->cin) == ctail && - readb(&bc->tbusy) == 0) - chars = 0; - else { /* Begin if some space on the card has been used */ - head = readw(&bc->tin) & (ch->txbufsize - 1); - tail &= (ch->txbufsize - 1); - /* - * The logic here is basically opposite of the above - * pc_write_room here we are finding the amount of bytes in the - * buffer filled. Not the amount of bytes empty. - */ - remain = tail - head - 1; - if (remain < 0) - remain += ch->txbufsize; - chars = (int)(ch->txbufsize - remain); - /* - * Make it possible to wakeup anything waiting for output in - * tty_ioctl.c, etc. - * - * If not already set. Setup an event to indicate when the - * transmit buffer empties. - */ - if (!(ch->statusflags & EMPTYWAIT)) - setup_empty_event(tty, ch); - } /* End if some space on the card has been used */ - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - /* Return number of characters residing on card. */ - return chars; -} - -static void pc_flush_buffer(struct tty_struct *tty) -{ - unsigned int tail; - unsigned long flags; - struct channel *ch; - struct board_chan __iomem *bc; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch == NULL) - return; - - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - bc = ch->brdchan; - tail = readw(&bc->tout); - /* Have FEP move tout pointer; effectively flushing transmit buffer */ - fepcmd(ch, STOUT, (unsigned) tail, 0, 0, 0); - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - tty_wakeup(tty); -} - -static void pc_flush_chars(struct tty_struct *tty) -{ - struct channel *ch; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch != NULL) { - unsigned long flags; - spin_lock_irqsave(&epca_lock, flags); - /* - * If not already set and the transmitter is busy setup an - * event to indicate when the transmit empties. - */ - if ((ch->statusflags & TXBUSY) && - !(ch->statusflags & EMPTYWAIT)) - setup_empty_event(tty, ch); - spin_unlock_irqrestore(&epca_lock, flags); - } -} - -static int epca_carrier_raised(struct tty_port *port) -{ - struct channel *ch = container_of(port, struct channel, port); - if (ch->imodem & ch->dcd) - return 1; - return 0; -} - -static void epca_dtr_rts(struct tty_port *port, int onoff) -{ -} - -static int pc_open(struct tty_struct *tty, struct file *filp) -{ - struct channel *ch; - struct tty_port *port; - unsigned long flags; - int line, retval, boardnum; - struct board_chan __iomem *bc; - unsigned int head; - - line = tty->index; - if (line < 0 || line >= nbdevs) - return -ENODEV; - - ch = &digi_channels[line]; - port = &ch->port; - boardnum = ch->boardnum; - - /* Check status of board configured in system. */ - - /* - * I check to see if the epca_setup routine detected a user error. It - * might be better to put this in pc_init, but for the moment it goes - * here. - */ - if (invalid_lilo_config) { - if (setup_error_code & INVALID_BOARD_TYPE) - printk(KERN_ERR "epca: pc_open: Invalid board type specified in kernel options.\n"); - if (setup_error_code & INVALID_NUM_PORTS) - printk(KERN_ERR "epca: pc_open: Invalid number of ports specified in kernel options.\n"); - if (setup_error_code & INVALID_MEM_BASE) - printk(KERN_ERR "epca: pc_open: Invalid board memory address specified in kernel options.\n"); - if (setup_error_code & INVALID_PORT_BASE) - printk(KERN_ERR "epca; pc_open: Invalid board port address specified in kernel options.\n"); - if (setup_error_code & INVALID_BOARD_STATUS) - printk(KERN_ERR "epca: pc_open: Invalid board status specified in kernel options.\n"); - if (setup_error_code & INVALID_ALTPIN) - printk(KERN_ERR "epca: pc_open: Invalid board altpin specified in kernel options;\n"); - tty->driver_data = NULL; /* Mark this device as 'down' */ - return -ENODEV; - } - if (boardnum >= num_cards || boards[boardnum].status == DISABLED) { - tty->driver_data = NULL; /* Mark this device as 'down' */ - return(-ENODEV); - } - - bc = ch->brdchan; - if (bc == NULL) { - tty->driver_data = NULL; - return -ENODEV; - } - - spin_lock_irqsave(&port->lock, flags); - /* - * Every time a channel is opened, increment a counter. This is - * necessary because we do not wish to flush and shutdown the channel - * until the last app holding the channel open, closes it. - */ - port->count++; - /* - * Set a kernel structures pointer to our local channel structure. This - * way we can get to it when passed only a tty struct. - */ - tty->driver_data = ch; - port->tty = tty; - /* - * If this is the first time the channel has been opened, initialize - * the tty->termios struct otherwise let pc_close handle it. - */ - spin_lock(&epca_lock); - globalwinon(ch); - ch->statusflags = 0; - - /* Save boards current modem status */ - ch->imodem = readb(&bc->mstat); - - /* - * Set receive head and tail ptrs to each other. This indicates no data - * available to read. - */ - head = readw(&bc->rin); - writew(head, &bc->rout); - - /* Set the channels associated tty structure */ - - /* - * The below routine generally sets up parity, baud, flow control - * issues, etc.... It effect both control flags and input flags. - */ - epcaparam(tty, ch); - memoff(ch); - spin_unlock(&epca_lock); - port->flags |= ASYNC_INITIALIZED; - spin_unlock_irqrestore(&port->lock, flags); - - retval = tty_port_block_til_ready(port, tty, filp); - if (retval) - return retval; - /* - * Set this again in case a hangup set it to zero while this open() was - * waiting for the line... - */ - spin_lock_irqsave(&port->lock, flags); - port->tty = tty; - spin_lock(&epca_lock); - globalwinon(ch); - /* Enable Digi Data events */ - writeb(1, &bc->idata); - memoff(ch); - spin_unlock(&epca_lock); - spin_unlock_irqrestore(&port->lock, flags); - return 0; -} - -static int __init epca_module_init(void) -{ - return pc_init(); -} -module_init(epca_module_init); - -static struct pci_driver epca_driver; - -static void __exit epca_module_exit(void) -{ - int count, crd; - struct board_info *bd; - struct channel *ch; - - del_timer_sync(&epca_timer); - - if (tty_unregister_driver(pc_driver) || - tty_unregister_driver(pc_info)) { - printk(KERN_WARNING "epca: cleanup_module failed to un-register tty driver\n"); - return; - } - put_tty_driver(pc_driver); - put_tty_driver(pc_info); - - for (crd = 0; crd < num_cards; crd++) { - bd = &boards[crd]; - if (!bd) { /* sanity check */ - printk(KERN_ERR " - Digi : cleanup_module failed\n"); - return; - } - ch = card_ptr[crd]; - for (count = 0; count < bd->numports; count++, ch++) { - struct tty_struct *tty = tty_port_tty_get(&ch->port); - if (tty) { - tty_hangup(tty); - tty_kref_put(tty); - } - } - } - pci_unregister_driver(&epca_driver); -} -module_exit(epca_module_exit); - -static const struct tty_operations pc_ops = { - .open = pc_open, - .close = pc_close, - .write = pc_write, - .write_room = pc_write_room, - .flush_buffer = pc_flush_buffer, - .chars_in_buffer = pc_chars_in_buffer, - .flush_chars = pc_flush_chars, - .ioctl = pc_ioctl, - .set_termios = pc_set_termios, - .stop = pc_stop, - .start = pc_start, - .throttle = pc_throttle, - .unthrottle = pc_unthrottle, - .hangup = pc_hangup, - .break_ctl = pc_send_break -}; - -static const struct tty_port_operations epca_port_ops = { - .carrier_raised = epca_carrier_raised, - .dtr_rts = epca_dtr_rts, -}; - -static int info_open(struct tty_struct *tty, struct file *filp) -{ - return 0; -} - -static const struct tty_operations info_ops = { - .open = info_open, - .ioctl = info_ioctl, -}; - -static int __init pc_init(void) -{ - int crd; - struct board_info *bd; - unsigned char board_id = 0; - int err = -ENOMEM; - - int pci_boards_found, pci_count; - - pci_count = 0; - - pc_driver = alloc_tty_driver(MAX_ALLOC); - if (!pc_driver) - goto out1; - - pc_info = alloc_tty_driver(MAX_ALLOC); - if (!pc_info) - goto out2; - - /* - * If epca_setup has not been ran by LILO set num_cards to defaults; - * copy board structure defined by digiConfig into drivers board - * structure. Note : If LILO has ran epca_setup then epca_setup will - * handle defining num_cards as well as copying the data into the board - * structure. - */ - if (!liloconfig) { - /* driver has been configured via. epcaconfig */ - nbdevs = NBDEVS; - num_cards = NUMCARDS; - memcpy(&boards, &static_boards, - sizeof(struct board_info) * NUMCARDS); - } - - /* - * Note : If lilo was used to configure the driver and the ignore - * epcaconfig option was choosen (digiepca=2) then nbdevs and num_cards - * will equal 0 at this point. This is okay; PCI cards will still be - * picked up if detected. - */ - - /* - * Set up interrupt, we will worry about memory allocation in - * post_fep_init. - */ - printk(KERN_INFO "DIGI epca driver version %s loaded.\n", VERSION); - - /* - * NOTE : This code assumes that the number of ports found in the - * boards array is correct. This could be wrong if the card in question - * is PCI (And therefore has no ports entry in the boards structure.) - * The rest of the information will be valid for PCI because the - * beginning of pc_init scans for PCI and determines i/o and base - * memory addresses. I am not sure if it is possible to read the number - * of ports supported by the card prior to it being booted (Since that - * is the state it is in when pc_init is run). Because it is not - * possible to query the number of supported ports until after the card - * has booted; we are required to calculate the card_ptrs as the card - * is initialized (Inside post_fep_init). The negative thing about this - * approach is that digiDload's call to GET_INFO will have a bad port - * value. (Since this is called prior to post_fep_init.) - */ - pci_boards_found = 0; - if (num_cards < MAXBOARDS) - pci_boards_found += init_PCI(); - num_cards += pci_boards_found; - - pc_driver->owner = THIS_MODULE; - pc_driver->name = "ttyD"; - pc_driver->major = DIGI_MAJOR; - pc_driver->minor_start = 0; - pc_driver->type = TTY_DRIVER_TYPE_SERIAL; - pc_driver->subtype = SERIAL_TYPE_NORMAL; - pc_driver->init_termios = tty_std_termios; - pc_driver->init_termios.c_iflag = 0; - pc_driver->init_termios.c_oflag = 0; - pc_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; - pc_driver->init_termios.c_lflag = 0; - pc_driver->init_termios.c_ispeed = 9600; - pc_driver->init_termios.c_ospeed = 9600; - pc_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_HARDWARE_BREAK; - tty_set_operations(pc_driver, &pc_ops); - - pc_info->owner = THIS_MODULE; - pc_info->name = "digi_ctl"; - pc_info->major = DIGIINFOMAJOR; - pc_info->minor_start = 0; - pc_info->type = TTY_DRIVER_TYPE_SERIAL; - pc_info->subtype = SERIAL_TYPE_INFO; - pc_info->init_termios = tty_std_termios; - pc_info->init_termios.c_iflag = 0; - pc_info->init_termios.c_oflag = 0; - pc_info->init_termios.c_lflag = 0; - pc_info->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL; - pc_info->init_termios.c_ispeed = 9600; - pc_info->init_termios.c_ospeed = 9600; - pc_info->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(pc_info, &info_ops); - - - for (crd = 0; crd < num_cards; crd++) { - /* - * This is where the appropriate memory handlers for the - * hardware is set. Everything at runtime blindly jumps through - * these vectors. - */ - - /* defined in epcaconfig.h */ - bd = &boards[crd]; - - switch (bd->type) { - case PCXEM: - case EISAXEM: - bd->memwinon = pcxem_memwinon; - bd->memwinoff = pcxem_memwinoff; - bd->globalwinon = pcxem_globalwinon; - bd->txwinon = pcxem_txwinon; - bd->rxwinon = pcxem_rxwinon; - bd->memoff = pcxem_memoff; - bd->assertgwinon = dummy_assertgwinon; - bd->assertmemoff = dummy_assertmemoff; - break; - - case PCIXEM: - case PCIXRJ: - case PCIXR: - bd->memwinon = dummy_memwinon; - bd->memwinoff = dummy_memwinoff; - bd->globalwinon = dummy_globalwinon; - bd->txwinon = dummy_txwinon; - bd->rxwinon = dummy_rxwinon; - bd->memoff = dummy_memoff; - bd->assertgwinon = dummy_assertgwinon; - bd->assertmemoff = dummy_assertmemoff; - break; - - case PCXE: - case PCXEVE: - bd->memwinon = pcxe_memwinon; - bd->memwinoff = pcxe_memwinoff; - bd->globalwinon = pcxe_globalwinon; - bd->txwinon = pcxe_txwinon; - bd->rxwinon = pcxe_rxwinon; - bd->memoff = pcxe_memoff; - bd->assertgwinon = dummy_assertgwinon; - bd->assertmemoff = dummy_assertmemoff; - break; - - case PCXI: - case PC64XE: - bd->memwinon = pcxi_memwinon; - bd->memwinoff = pcxi_memwinoff; - bd->globalwinon = pcxi_globalwinon; - bd->txwinon = pcxi_txwinon; - bd->rxwinon = pcxi_rxwinon; - bd->memoff = pcxi_memoff; - bd->assertgwinon = pcxi_assertgwinon; - bd->assertmemoff = pcxi_assertmemoff; - break; - - default: - break; - } - - /* - * Some cards need a memory segment to be defined for use in - * transmit and receive windowing operations. These boards are - * listed in the below switch. In the case of the XI the amount - * of memory on the board is variable so the memory_seg is also - * variable. This code determines what they segment should be. - */ - switch (bd->type) { - case PCXE: - case PCXEVE: - case PC64XE: - bd->memory_seg = 0xf000; - break; - - case PCXI: - board_id = inb((int)bd->port); - if ((board_id & 0x1) == 0x1) { - /* it's an XI card */ - /* Is it a 64K board */ - if ((board_id & 0x30) == 0) - bd->memory_seg = 0xf000; - - /* Is it a 128K board */ - if ((board_id & 0x30) == 0x10) - bd->memory_seg = 0xe000; - - /* Is is a 256K board */ - if ((board_id & 0x30) == 0x20) - bd->memory_seg = 0xc000; - - /* Is it a 512K board */ - if ((board_id & 0x30) == 0x30) - bd->memory_seg = 0x8000; - } else - printk(KERN_ERR "epca: Board at 0x%x doesn't appear to be an XI\n", (int)bd->port); - break; - } - } - - err = tty_register_driver(pc_driver); - if (err) { - printk(KERN_ERR "Couldn't register Digi PC/ driver"); - goto out3; - } - - err = tty_register_driver(pc_info); - if (err) { - printk(KERN_ERR "Couldn't register Digi PC/ info "); - goto out4; - } - - /* Start up the poller to check for events on all enabled boards */ - init_timer(&epca_timer); - epca_timer.function = epcapoll; - mod_timer(&epca_timer, jiffies + HZ/25); - return 0; - -out4: - tty_unregister_driver(pc_driver); -out3: - put_tty_driver(pc_info); -out2: - put_tty_driver(pc_driver); -out1: - return err; -} - -static void post_fep_init(unsigned int crd) -{ - int i; - void __iomem *memaddr; - struct global_data __iomem *gd; - struct board_info *bd; - struct board_chan __iomem *bc; - struct channel *ch; - int shrinkmem = 0, lowwater; - - /* - * This call is made by the user via. the ioctl call DIGI_INIT. It is - * responsible for setting up all the card specific stuff. - */ - bd = &boards[crd]; - - /* - * If this is a PCI board, get the port info. Remember PCI cards do not - * have entries into the epcaconfig.h file, so we can't get the number - * of ports from it. Unfortunetly, this means that anyone doing a - * DIGI_GETINFO before the board has booted will get an invalid number - * of ports returned (It should return 0). Calls to DIGI_GETINFO after - * DIGI_INIT has been called will return the proper values. - */ - if (bd->type >= PCIXEM) { /* Begin get PCI number of ports */ - /* - * Below we use XEMPORTS as a memory offset regardless of which - * PCI card it is. This is because all of the supported PCI - * cards have the same memory offset for the channel data. This - * will have to be changed if we ever develop a PCI/XE card. - * NOTE : The FEP manual states that the port offset is 0xC22 - * as opposed to 0xC02. This is only true for PC/XE, and PC/XI - * cards; not for the XEM, or CX series. On the PCI cards the - * number of ports is determined by reading a ID PROM located - * in the box attached to the card. The card can then determine - * the index the id to determine the number of ports available. - * (FYI - The id should be located at 0x1ac (And may use up to - * 4 bytes if the box in question is a XEM or CX)). - */ - /* PCI cards are already remapped at this point ISA are not */ - bd->numports = readw(bd->re_map_membase + XEMPORTS); - epcaassert(bd->numports <= 64, "PCI returned a invalid number of ports"); - nbdevs += (bd->numports); - } else { - /* Fix up the mappings for ISA/EISA etc */ - /* FIXME: 64K - can we be smarter ? */ - bd->re_map_membase = ioremap_nocache(bd->membase, 0x10000); - } - - if (crd != 0) - card_ptr[crd] = card_ptr[crd-1] + boards[crd-1].numports; - else - card_ptr[crd] = &digi_channels[crd]; /* <- For card 0 only */ - - ch = card_ptr[crd]; - epcaassert(ch <= &digi_channels[nbdevs - 1], "ch out of range"); - - memaddr = bd->re_map_membase; - - /* - * The below assignment will set bc to point at the BEGINING of the - * cards channel structures. For 1 card there will be between 8 and 64 - * of these structures. - */ - bc = memaddr + CHANSTRUCT; - - /* - * The below assignment will set gd to point at the BEGINING of global - * memory address 0xc00. The first data in that global memory actually - * starts at address 0xc1a. The command in pointer begins at 0xd10. - */ - gd = memaddr + GLOBAL; - - /* - * XEPORTS (address 0xc22) points at the number of channels the card - * supports. (For 64XE, XI, XEM, and XR use 0xc02) - */ - if ((bd->type == PCXEVE || bd->type == PCXE) && - (readw(memaddr + XEPORTS) < 3)) - shrinkmem = 1; - if (bd->type < PCIXEM) - if (!request_region((int)bd->port, 4, board_desc[bd->type])) - return; - memwinon(bd, 0); - - /* - * Remember ch is the main drivers channels structure, while bc is the - * cards channel structure. - */ - for (i = 0; i < bd->numports; i++, ch++, bc++) { - unsigned long flags; - u16 tseg, rseg; - - tty_port_init(&ch->port); - ch->port.ops = &epca_port_ops; - ch->brdchan = bc; - ch->mailbox = gd; - INIT_WORK(&ch->tqueue, do_softint); - ch->board = &boards[crd]; - - spin_lock_irqsave(&epca_lock, flags); - switch (bd->type) { - /* - * Since some of the boards use different bitmaps for - * their control signals we cannot hard code these - * values and retain portability. We virtualize this - * data here. - */ - case EISAXEM: - case PCXEM: - case PCIXEM: - case PCIXRJ: - case PCIXR: - ch->m_rts = 0x02; - ch->m_dcd = 0x80; - ch->m_dsr = 0x20; - ch->m_cts = 0x10; - ch->m_ri = 0x40; - ch->m_dtr = 0x01; - break; - - case PCXE: - case PCXEVE: - case PCXI: - case PC64XE: - ch->m_rts = 0x02; - ch->m_dcd = 0x08; - ch->m_dsr = 0x10; - ch->m_cts = 0x20; - ch->m_ri = 0x40; - ch->m_dtr = 0x80; - break; - } - - if (boards[crd].altpin) { - ch->dsr = ch->m_dcd; - ch->dcd = ch->m_dsr; - ch->digiext.digi_flags |= DIGI_ALTPIN; - } else { - ch->dcd = ch->m_dcd; - ch->dsr = ch->m_dsr; - } - - ch->boardnum = crd; - ch->channelnum = i; - ch->magic = EPCA_MAGIC; - tty_port_tty_set(&ch->port, NULL); - - if (shrinkmem) { - fepcmd(ch, SETBUFFER, 32, 0, 0, 0); - shrinkmem = 0; - } - - tseg = readw(&bc->tseg); - rseg = readw(&bc->rseg); - - switch (bd->type) { - case PCIXEM: - case PCIXRJ: - case PCIXR: - /* Cover all the 2MEG cards */ - ch->txptr = memaddr + ((tseg << 4) & 0x1fffff); - ch->rxptr = memaddr + ((rseg << 4) & 0x1fffff); - ch->txwin = FEPWIN | (tseg >> 11); - ch->rxwin = FEPWIN | (rseg >> 11); - break; - - case PCXEM: - case EISAXEM: - /* Cover all the 32K windowed cards */ - /* Mask equal to window size - 1 */ - ch->txptr = memaddr + ((tseg << 4) & 0x7fff); - ch->rxptr = memaddr + ((rseg << 4) & 0x7fff); - ch->txwin = FEPWIN | (tseg >> 11); - ch->rxwin = FEPWIN | (rseg >> 11); - break; - - case PCXEVE: - case PCXE: - ch->txptr = memaddr + (((tseg - bd->memory_seg) << 4) - & 0x1fff); - ch->txwin = FEPWIN | ((tseg - bd->memory_seg) >> 9); - ch->rxptr = memaddr + (((rseg - bd->memory_seg) << 4) - & 0x1fff); - ch->rxwin = FEPWIN | ((rseg - bd->memory_seg) >> 9); - break; - - case PCXI: - case PC64XE: - ch->txptr = memaddr + ((tseg - bd->memory_seg) << 4); - ch->rxptr = memaddr + ((rseg - bd->memory_seg) << 4); - ch->txwin = ch->rxwin = 0; - break; - } - - ch->txbufhead = 0; - ch->txbufsize = readw(&bc->tmax) + 1; - - ch->rxbufhead = 0; - ch->rxbufsize = readw(&bc->rmax) + 1; - - lowwater = ch->txbufsize >= 2000 ? 1024 : (ch->txbufsize / 2); - - /* Set transmitter low water mark */ - fepcmd(ch, STXLWATER, lowwater, 0, 10, 0); - - /* Set receiver low water mark */ - fepcmd(ch, SRXLWATER, (ch->rxbufsize / 4), 0, 10, 0); - - /* Set receiver high water mark */ - fepcmd(ch, SRXHWATER, (3 * ch->rxbufsize / 4), 0, 10, 0); - - writew(100, &bc->edelay); - writeb(1, &bc->idata); - - ch->startc = readb(&bc->startc); - ch->stopc = readb(&bc->stopc); - ch->startca = readb(&bc->startca); - ch->stopca = readb(&bc->stopca); - - ch->fepcflag = 0; - ch->fepiflag = 0; - ch->fepoflag = 0; - ch->fepstartc = 0; - ch->fepstopc = 0; - ch->fepstartca = 0; - ch->fepstopca = 0; - - ch->port.close_delay = 50; - - spin_unlock_irqrestore(&epca_lock, flags); - } - - printk(KERN_INFO - "Digi PC/Xx Driver V%s: %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n", - VERSION, board_desc[bd->type], (long)bd->port, - (long)bd->membase, bd->numports); - memwinoff(bd, 0); -} - -static void epcapoll(unsigned long ignored) -{ - unsigned long flags; - int crd; - unsigned int head, tail; - struct channel *ch; - struct board_info *bd; - - /* - * This routine is called upon every timer interrupt. Even though the - * Digi series cards are capable of generating interrupts this method - * of non-looping polling is more efficient. This routine checks for - * card generated events (Such as receive data, are transmit buffer - * empty) and acts on those events. - */ - for (crd = 0; crd < num_cards; crd++) { - bd = &boards[crd]; - ch = card_ptr[crd]; - - if ((bd->status == DISABLED) || digi_poller_inhibited) - continue; - - /* - * assertmemoff is not needed here; indeed it is an empty - * subroutine. It is being kept because future boards may need - * this as well as some legacy boards. - */ - spin_lock_irqsave(&epca_lock, flags); - - assertmemoff(ch); - - globalwinon(ch); - - /* - * In this case head and tail actually refer to the event queue - * not the transmit or receive queue. - */ - head = readw(&ch->mailbox->ein); - tail = readw(&ch->mailbox->eout); - - /* If head isn't equal to tail we have an event */ - if (head != tail) - doevent(crd); - memoff(ch); - - spin_unlock_irqrestore(&epca_lock, flags); - } /* End for each card */ - mod_timer(&epca_timer, jiffies + (HZ / 25)); -} - -static void doevent(int crd) -{ - void __iomem *eventbuf; - struct channel *ch, *chan0; - static struct tty_struct *tty; - struct board_info *bd; - struct board_chan __iomem *bc; - unsigned int tail, head; - int event, channel; - int mstat, lstat; - - /* - * This subroutine is called by epcapoll when an event is detected - * in the event queue. This routine responds to those events. - */ - bd = &boards[crd]; - - chan0 = card_ptr[crd]; - epcaassert(chan0 <= &digi_channels[nbdevs - 1], "ch out of range"); - assertgwinon(chan0); - while ((tail = readw(&chan0->mailbox->eout)) != - (head = readw(&chan0->mailbox->ein))) { - /* Begin while something in event queue */ - assertgwinon(chan0); - eventbuf = bd->re_map_membase + tail + ISTART; - /* Get the channel the event occurred on */ - channel = readb(eventbuf); - /* Get the actual event code that occurred */ - event = readb(eventbuf + 1); - /* - * The two assignments below get the current modem status - * (mstat) and the previous modem status (lstat). These are - * useful becuase an event could signal a change in modem - * signals itself. - */ - mstat = readb(eventbuf + 2); - lstat = readb(eventbuf + 3); - - ch = chan0 + channel; - if ((unsigned)channel >= bd->numports || !ch) { - if (channel >= bd->numports) - ch = chan0; - bc = ch->brdchan; - goto next; - } - - bc = ch->brdchan; - if (bc == NULL) - goto next; - - tty = tty_port_tty_get(&ch->port); - if (event & DATA_IND) { /* Begin DATA_IND */ - receive_data(ch, tty); - assertgwinon(ch); - } /* End DATA_IND */ - /* else *//* Fix for DCD transition missed bug */ - if (event & MODEMCHG_IND) { - /* A modem signal change has been indicated */ - ch->imodem = mstat; - if (test_bit(ASYNCB_CHECK_CD, &ch->port.flags)) { - /* We are now receiving dcd */ - if (mstat & ch->dcd) - wake_up_interruptible(&ch->port.open_wait); - else /* No dcd; hangup */ - pc_sched_event(ch, EPCA_EVENT_HANGUP); - } - } - if (tty) { - if (event & BREAK_IND) { - /* A break has been indicated */ - tty_insert_flip_char(tty, 0, TTY_BREAK); - tty_schedule_flip(tty); - } else if (event & LOWTX_IND) { - if (ch->statusflags & LOWWAIT) { - ch->statusflags &= ~LOWWAIT; - tty_wakeup(tty); - } - } else if (event & EMPTYTX_IND) { - /* This event is generated by - setup_empty_event */ - ch->statusflags &= ~TXBUSY; - if (ch->statusflags & EMPTYWAIT) { - ch->statusflags &= ~EMPTYWAIT; - tty_wakeup(tty); - } - } - tty_kref_put(tty); - } -next: - globalwinon(ch); - BUG_ON(!bc); - writew(1, &bc->idata); - writew((tail + 4) & (IMAX - ISTART - 4), &chan0->mailbox->eout); - globalwinon(chan0); - } /* End while something in event queue */ -} - -static void fepcmd(struct channel *ch, int cmd, int word_or_byte, - int byte2, int ncmds, int bytecmd) -{ - unchar __iomem *memaddr; - unsigned int head, cmdTail, cmdStart, cmdMax; - long count; - int n; - - /* This is the routine in which commands may be passed to the card. */ - - if (ch->board->status == DISABLED) - return; - assertgwinon(ch); - /* Remember head (As well as max) is just an offset not a base addr */ - head = readw(&ch->mailbox->cin); - /* cmdStart is a base address */ - cmdStart = readw(&ch->mailbox->cstart); - /* - * We do the addition below because we do not want a max pointer - * relative to cmdStart. We want a max pointer that points at the - * physical end of the command queue. - */ - cmdMax = (cmdStart + 4 + readw(&ch->mailbox->cmax)); - memaddr = ch->board->re_map_membase; - - if (head >= (cmdMax - cmdStart) || (head & 03)) { - printk(KERN_ERR "line %d: Out of range, cmd = %x, head = %x\n", - __LINE__, cmd, head); - printk(KERN_ERR "line %d: Out of range, cmdMax = %x, cmdStart = %x\n", - __LINE__, cmdMax, cmdStart); - return; - } - if (bytecmd) { - writeb(cmd, memaddr + head + cmdStart + 0); - writeb(ch->channelnum, memaddr + head + cmdStart + 1); - /* Below word_or_byte is bits to set */ - writeb(word_or_byte, memaddr + head + cmdStart + 2); - /* Below byte2 is bits to reset */ - writeb(byte2, memaddr + head + cmdStart + 3); - } else { - writeb(cmd, memaddr + head + cmdStart + 0); - writeb(ch->channelnum, memaddr + head + cmdStart + 1); - writeb(word_or_byte, memaddr + head + cmdStart + 2); - } - head = (head + 4) & (cmdMax - cmdStart - 4); - writew(head, &ch->mailbox->cin); - count = FEPTIMEOUT; - - for (;;) { - count--; - if (count == 0) { - printk(KERN_ERR " - Fep not responding in fepcmd()\n"); - return; - } - head = readw(&ch->mailbox->cin); - cmdTail = readw(&ch->mailbox->cout); - n = (head - cmdTail) & (cmdMax - cmdStart - 4); - /* - * Basically this will break when the FEP acknowledges the - * command by incrementing cmdTail (Making it equal to head). - */ - if (n <= ncmds * (sizeof(short) * 4)) - break; - } -} - -/* - * Digi products use fields in their channels structures that are very similar - * to the c_cflag and c_iflag fields typically found in UNIX termios - * structures. The below three routines allow mappings between these hardware - * "flags" and their respective Linux flags. - */ -static unsigned termios2digi_h(struct channel *ch, unsigned cflag) -{ - unsigned res = 0; - - if (cflag & CRTSCTS) { - ch->digiext.digi_flags |= (RTSPACE | CTSPACE); - res |= ((ch->m_cts) | (ch->m_rts)); - } - - if (ch->digiext.digi_flags & RTSPACE) - res |= ch->m_rts; - - if (ch->digiext.digi_flags & DTRPACE) - res |= ch->m_dtr; - - if (ch->digiext.digi_flags & CTSPACE) - res |= ch->m_cts; - - if (ch->digiext.digi_flags & DSRPACE) - res |= ch->dsr; - - if (ch->digiext.digi_flags & DCDPACE) - res |= ch->dcd; - - if (res & (ch->m_rts)) - ch->digiext.digi_flags |= RTSPACE; - - if (res & (ch->m_cts)) - ch->digiext.digi_flags |= CTSPACE; - - return res; -} - -static unsigned termios2digi_i(struct channel *ch, unsigned iflag) -{ - unsigned res = iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK | - INPCK | ISTRIP | IXON | IXANY | IXOFF); - if (ch->digiext.digi_flags & DIGI_AIXON) - res |= IAIXON; - return res; -} - -static unsigned termios2digi_c(struct channel *ch, unsigned cflag) -{ - unsigned res = 0; - if (cflag & CBAUDEX) { - ch->digiext.digi_flags |= DIGI_FAST; - /* - * HUPCL bit is used by FEP to indicate fast baud table is to - * be used. - */ - res |= FEP_HUPCL; - } else - ch->digiext.digi_flags &= ~DIGI_FAST; - /* - * CBAUD has bit position 0x1000 set these days to indicate Linux - * baud rate remap. Digi hardware can't handle the bit assignment. - * (We use a different bit assignment for high speed.). Clear this - * bit out. - */ - res |= cflag & ((CBAUD ^ CBAUDEX) | PARODD | PARENB | CSTOPB | CSIZE); - /* - * This gets a little confusing. The Digi cards have their own - * representation of c_cflags controlling baud rate. For the most part - * this is identical to the Linux implementation. However; Digi - * supports one rate (76800) that Linux doesn't. This means that the - * c_cflag entry that would normally mean 76800 for Digi actually means - * 115200 under Linux. Without the below mapping, a stty 115200 would - * only drive the board at 76800. Since the rate 230400 is also found - * after 76800, the same problem afflicts us when we choose a rate of - * 230400. Without the below modificiation stty 230400 would actually - * give us 115200. - * - * There are two additional differences. The Linux value for CLOCAL - * (0x800; 0004000) has no meaning to the Digi hardware. Also in later - * releases of Linux; the CBAUD define has CBAUDEX (0x1000; 0010000) - * ored into it (CBAUD = 0x100f as opposed to 0xf). CBAUDEX should be - * checked for a screened out prior to termios2digi_c returning. Since - * CLOCAL isn't used by the board this can be ignored as long as the - * returned value is used only by Digi hardware. - */ - if (cflag & CBAUDEX) { - /* - * The below code is trying to guarantee that only baud rates - * 115200 and 230400 are remapped. We use exclusive or because - * the various baud rates share common bit positions and - * therefore can't be tested for easily. - */ - if ((!((cflag & 0x7) ^ (B115200 & ~CBAUDEX))) || - (!((cflag & 0x7) ^ (B230400 & ~CBAUDEX)))) - res += 1; - } - return res; -} - -/* Caller must hold the locks */ -static void epcaparam(struct tty_struct *tty, struct channel *ch) -{ - unsigned int cmdHead; - struct ktermios *ts; - struct board_chan __iomem *bc; - unsigned mval, hflow, cflag, iflag; - - bc = ch->brdchan; - epcaassert(bc != NULL, "bc out of range"); - - assertgwinon(ch); - ts = tty->termios; - if ((ts->c_cflag & CBAUD) == 0) { /* Begin CBAUD detected */ - cmdHead = readw(&bc->rin); - writew(cmdHead, &bc->rout); - cmdHead = readw(&bc->tin); - /* Changing baud in mid-stream transmission can be wonderful */ - /* - * Flush current transmit buffer by setting cmdTail pointer - * (tout) to cmdHead pointer (tin). Hopefully the transmit - * buffer is empty. - */ - fepcmd(ch, STOUT, (unsigned) cmdHead, 0, 0, 0); - mval = 0; - } else { /* Begin CBAUD not detected */ - /* - * c_cflags have changed but that change had nothing to do with - * BAUD. Propagate the change to the card. - */ - cflag = termios2digi_c(ch, ts->c_cflag); - if (cflag != ch->fepcflag) { - ch->fepcflag = cflag; - /* Set baud rate, char size, stop bits, parity */ - fepcmd(ch, SETCTRLFLAGS, (unsigned) cflag, 0, 0, 0); - } - /* - * If the user has not forced CLOCAL and if the device is not a - * CALLOUT device (Which is always CLOCAL) we set flags such - * that the driver will wait on carrier detect. - */ - if (ts->c_cflag & CLOCAL) - clear_bit(ASYNCB_CHECK_CD, &ch->port.flags); - else - set_bit(ASYNCB_CHECK_CD, &ch->port.flags); - mval = ch->m_dtr | ch->m_rts; - } /* End CBAUD not detected */ - iflag = termios2digi_i(ch, ts->c_iflag); - /* Check input mode flags */ - if (iflag != ch->fepiflag) { - ch->fepiflag = iflag; - /* - * Command sets channels iflag structure on the board. Such - * things as input soft flow control, handling of parity - * errors, and break handling are all set here. - * - * break handling, parity handling, input stripping, - * flow control chars - */ - fepcmd(ch, SETIFLAGS, (unsigned int) ch->fepiflag, 0, 0, 0); - } - /* - * Set the board mint value for this channel. This will cause hardware - * events to be generated each time the DCD signal (Described in mint) - * changes. - */ - writeb(ch->dcd, &bc->mint); - if ((ts->c_cflag & CLOCAL) || (ch->digiext.digi_flags & DIGI_FORCEDCD)) - if (ch->digiext.digi_flags & DIGI_FORCEDCD) - writeb(0, &bc->mint); - ch->imodem = readb(&bc->mstat); - hflow = termios2digi_h(ch, ts->c_cflag); - if (hflow != ch->hflow) { - ch->hflow = hflow; - /* - * Hard flow control has been selected but the board is not - * using it. Activate hard flow control now. - */ - fepcmd(ch, SETHFLOW, hflow, 0xff, 0, 1); - } - mval ^= ch->modemfake & (mval ^ ch->modem); - - if (ch->omodem ^ mval) { - ch->omodem = mval; - /* - * The below command sets the DTR and RTS mstat structure. If - * hard flow control is NOT active these changes will drive the - * output of the actual DTR and RTS lines. If hard flow control - * is active, the changes will be saved in the mstat structure - * and only asserted when hard flow control is turned off. - */ - - /* First reset DTR & RTS; then set them */ - fepcmd(ch, SETMODEM, 0, ((ch->m_dtr)|(ch->m_rts)), 0, 1); - fepcmd(ch, SETMODEM, mval, 0, 0, 1); - } - if (ch->startc != ch->fepstartc || ch->stopc != ch->fepstopc) { - ch->fepstartc = ch->startc; - ch->fepstopc = ch->stopc; - /* - * The XON / XOFF characters have changed; propagate these - * changes to the card. - */ - fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1); - } - if (ch->startca != ch->fepstartca || ch->stopca != ch->fepstopca) { - ch->fepstartca = ch->startca; - ch->fepstopca = ch->stopca; - /* - * Similar to the above, this time the auxilarly XON / XOFF - * characters have changed; propagate these changes to the card. - */ - fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1); - } -} - -/* Caller holds lock */ -static void receive_data(struct channel *ch, struct tty_struct *tty) -{ - unchar *rptr; - struct ktermios *ts = NULL; - struct board_chan __iomem *bc; - int dataToRead, wrapgap, bytesAvailable; - unsigned int tail, head; - unsigned int wrapmask; - - /* - * This routine is called by doint when a receive data event has taken - * place. - */ - globalwinon(ch); - if (ch->statusflags & RXSTOPPED) - return; - if (tty) - ts = tty->termios; - bc = ch->brdchan; - BUG_ON(!bc); - wrapmask = ch->rxbufsize - 1; - - /* - * Get the head and tail pointers to the receiver queue. Wrap the head - * pointer if it has reached the end of the buffer. - */ - head = readw(&bc->rin); - head &= wrapmask; - tail = readw(&bc->rout) & wrapmask; - - bytesAvailable = (head - tail) & wrapmask; - if (bytesAvailable == 0) - return; - - /* If CREAD bit is off or device not open, set TX tail to head */ - if (!tty || !ts || !(ts->c_cflag & CREAD)) { - writew(head, &bc->rout); - return; - } - - if (tty_buffer_request_room(tty, bytesAvailable + 1) == 0) - return; - - if (readb(&bc->orun)) { - writeb(0, &bc->orun); - printk(KERN_WARNING "epca; overrun! DigiBoard device %s\n", - tty->name); - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - } - rxwinon(ch); - while (bytesAvailable > 0) { - /* Begin while there is data on the card */ - wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail; - /* - * Even if head has wrapped around only report the amount of - * data to be equal to the size - tail. Remember memcpy can't - * automaticly wrap around the receive buffer. - */ - dataToRead = (wrapgap < bytesAvailable) ? wrapgap - : bytesAvailable; - /* Make sure we don't overflow the buffer */ - dataToRead = tty_prepare_flip_string(tty, &rptr, dataToRead); - if (dataToRead == 0) - break; - /* - * Move data read from our card into the line disciplines - * buffer for translation if necessary. - */ - memcpy_fromio(rptr, ch->rxptr + tail, dataToRead); - tail = (tail + dataToRead) & wrapmask; - bytesAvailable -= dataToRead; - } /* End while there is data on the card */ - globalwinon(ch); - writew(tail, &bc->rout); - /* Must be called with global data */ - tty_schedule_flip(tty); -} - -static int info_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - switch (cmd) { - case DIGI_GETINFO: - { - struct digi_info di; - int brd; - - if (get_user(brd, (unsigned int __user *)arg)) - return -EFAULT; - if (brd < 0 || brd >= num_cards || num_cards == 0) - return -ENODEV; - - memset(&di, 0, sizeof(di)); - - di.board = brd; - di.status = boards[brd].status; - di.type = boards[brd].type ; - di.numports = boards[brd].numports ; - /* Legacy fixups - just move along nothing to see */ - di.port = (unsigned char *)boards[brd].port ; - di.membase = (unsigned char *)boards[brd].membase ; - - if (copy_to_user((void __user *)arg, &di, sizeof(di))) - return -EFAULT; - break; - - } - - case DIGI_POLLER: - { - int brd = arg & 0xff000000 >> 16; - unsigned char state = arg & 0xff; - - if (brd < 0 || brd >= num_cards) { - printk(KERN_ERR "epca: DIGI POLLER : brd not valid!\n"); - return -ENODEV; - } - digi_poller_inhibited = state; - break; - } - - case DIGI_INIT: - { - /* - * This call is made by the apps to complete the - * initialization of the board(s). This routine is - * responsible for setting the card to its initial - * state and setting the drivers control fields to the - * sutianle settings for the card in question. - */ - int crd; - for (crd = 0; crd < num_cards; crd++) - post_fep_init(crd); - break; - } - default: - return -ENOTTY; - } - return 0; -} - -static int pc_tiocmget(struct tty_struct *tty) -{ - struct channel *ch = tty->driver_data; - struct board_chan __iomem *bc; - unsigned int mstat, mflag = 0; - unsigned long flags; - - if (ch) - bc = ch->brdchan; - else - return -EINVAL; - - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - mstat = readb(&bc->mstat); - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - - if (mstat & ch->m_dtr) - mflag |= TIOCM_DTR; - if (mstat & ch->m_rts) - mflag |= TIOCM_RTS; - if (mstat & ch->m_cts) - mflag |= TIOCM_CTS; - if (mstat & ch->dsr) - mflag |= TIOCM_DSR; - if (mstat & ch->m_ri) - mflag |= TIOCM_RI; - if (mstat & ch->dcd) - mflag |= TIOCM_CD; - return mflag; -} - -static int pc_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct channel *ch = tty->driver_data; - unsigned long flags; - - if (!ch) - return -EINVAL; - - spin_lock_irqsave(&epca_lock, flags); - /* - * I think this modemfake stuff is broken. It doesn't correctly reflect - * the behaviour desired by the TIOCM* ioctls. Therefore this is - * probably broken. - */ - if (set & TIOCM_RTS) { - ch->modemfake |= ch->m_rts; - ch->modem |= ch->m_rts; - } - if (set & TIOCM_DTR) { - ch->modemfake |= ch->m_dtr; - ch->modem |= ch->m_dtr; - } - if (clear & TIOCM_RTS) { - ch->modemfake |= ch->m_rts; - ch->modem &= ~ch->m_rts; - } - if (clear & TIOCM_DTR) { - ch->modemfake |= ch->m_dtr; - ch->modem &= ~ch->m_dtr; - } - globalwinon(ch); - /* - * The below routine generally sets up parity, baud, flow control - * issues, etc.... It effect both control flags and input flags. - */ - epcaparam(tty, ch); - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - return 0; -} - -static int pc_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - digiflow_t dflow; - unsigned long flags; - unsigned int mflag, mstat; - unsigned char startc, stopc; - struct board_chan __iomem *bc; - struct channel *ch = tty->driver_data; - void __user *argp = (void __user *)arg; - - if (ch) - bc = ch->brdchan; - else - return -EINVAL; - switch (cmd) { - case TIOCMODG: - mflag = pc_tiocmget(tty); - if (put_user(mflag, (unsigned long __user *)argp)) - return -EFAULT; - break; - case TIOCMODS: - if (get_user(mstat, (unsigned __user *)argp)) - return -EFAULT; - return pc_tiocmset(tty, mstat, ~mstat); - case TIOCSDTR: - spin_lock_irqsave(&epca_lock, flags); - ch->omodem |= ch->m_dtr; - globalwinon(ch); - fepcmd(ch, SETMODEM, ch->m_dtr, 0, 10, 1); - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - break; - - case TIOCCDTR: - spin_lock_irqsave(&epca_lock, flags); - ch->omodem &= ~ch->m_dtr; - globalwinon(ch); - fepcmd(ch, SETMODEM, 0, ch->m_dtr, 10, 1); - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - break; - case DIGI_GETA: - if (copy_to_user(argp, &ch->digiext, sizeof(digi_t))) - return -EFAULT; - break; - case DIGI_SETAW: - case DIGI_SETAF: - if (cmd == DIGI_SETAW) { - /* Setup an event to indicate when the transmit - buffer empties */ - spin_lock_irqsave(&epca_lock, flags); - setup_empty_event(tty, ch); - spin_unlock_irqrestore(&epca_lock, flags); - tty_wait_until_sent(tty, 0); - } else { - /* ldisc lock already held in ioctl */ - if (tty->ldisc->ops->flush_buffer) - tty->ldisc->ops->flush_buffer(tty); - } - /* Fall Thru */ - case DIGI_SETA: - if (copy_from_user(&ch->digiext, argp, sizeof(digi_t))) - return -EFAULT; - - if (ch->digiext.digi_flags & DIGI_ALTPIN) { - ch->dcd = ch->m_dsr; - ch->dsr = ch->m_dcd; - } else { - ch->dcd = ch->m_dcd; - ch->dsr = ch->m_dsr; - } - - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - - /* - * The below routine generally sets up parity, baud, flow - * control issues, etc.... It effect both control flags and - * input flags. - */ - epcaparam(tty, ch); - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - break; - - case DIGI_GETFLOW: - case DIGI_GETAFLOW: - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - if (cmd == DIGI_GETFLOW) { - dflow.startc = readb(&bc->startc); - dflow.stopc = readb(&bc->stopc); - } else { - dflow.startc = readb(&bc->startca); - dflow.stopc = readb(&bc->stopca); - } - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - - if (copy_to_user(argp, &dflow, sizeof(dflow))) - return -EFAULT; - break; - - case DIGI_SETAFLOW: - case DIGI_SETFLOW: - if (cmd == DIGI_SETFLOW) { - startc = ch->startc; - stopc = ch->stopc; - } else { - startc = ch->startca; - stopc = ch->stopca; - } - - if (copy_from_user(&dflow, argp, sizeof(dflow))) - return -EFAULT; - - if (dflow.startc != startc || dflow.stopc != stopc) { - /* Begin if setflow toggled */ - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - - if (cmd == DIGI_SETFLOW) { - ch->fepstartc = ch->startc = dflow.startc; - ch->fepstopc = ch->stopc = dflow.stopc; - fepcmd(ch, SONOFFC, ch->fepstartc, - ch->fepstopc, 0, 1); - } else { - ch->fepstartca = ch->startca = dflow.startc; - ch->fepstopca = ch->stopca = dflow.stopc; - fepcmd(ch, SAUXONOFFC, ch->fepstartca, - ch->fepstopca, 0, 1); - } - - if (ch->statusflags & TXSTOPPED) - pc_start(tty); - - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - } /* End if setflow toggled */ - break; - default: - return -ENOIOCTLCMD; - } - return 0; -} - -static void pc_set_termios(struct tty_struct *tty, struct ktermios *old_termios) -{ - struct channel *ch; - unsigned long flags; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - - if (ch != NULL) { /* Begin if channel valid */ - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - epcaparam(tty, ch); - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - - if ((old_termios->c_cflag & CRTSCTS) && - ((tty->termios->c_cflag & CRTSCTS) == 0)) - tty->hw_stopped = 0; - - if (!(old_termios->c_cflag & CLOCAL) && - (tty->termios->c_cflag & CLOCAL)) - wake_up_interruptible(&ch->port.open_wait); - - } /* End if channel valid */ -} - -static void do_softint(struct work_struct *work) -{ - struct channel *ch = container_of(work, struct channel, tqueue); - /* Called in response to a modem change event */ - if (ch && ch->magic == EPCA_MAGIC) { - struct tty_struct *tty = tty_port_tty_get(&ch->port); - - if (tty && tty->driver_data) { - if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) { - tty_hangup(tty); - wake_up_interruptible(&ch->port.open_wait); - clear_bit(ASYNCB_NORMAL_ACTIVE, - &ch->port.flags); - } - } - tty_kref_put(tty); - } -} - -/* - * pc_stop and pc_start provide software flow control to the routine and the - * pc_ioctl routine. - */ -static void pc_stop(struct tty_struct *tty) -{ - struct channel *ch; - unsigned long flags; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch != NULL) { - spin_lock_irqsave(&epca_lock, flags); - if ((ch->statusflags & TXSTOPPED) == 0) { - /* Begin if transmit stop requested */ - globalwinon(ch); - /* STOP transmitting now !! */ - fepcmd(ch, PAUSETX, 0, 0, 0, 0); - ch->statusflags |= TXSTOPPED; - memoff(ch); - } /* End if transmit stop requested */ - spin_unlock_irqrestore(&epca_lock, flags); - } -} - -static void pc_start(struct tty_struct *tty) -{ - struct channel *ch; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch != NULL) { - unsigned long flags; - spin_lock_irqsave(&epca_lock, flags); - /* Just in case output was resumed because of a change - in Digi-flow */ - if (ch->statusflags & TXSTOPPED) { - /* Begin transmit resume requested */ - struct board_chan __iomem *bc; - globalwinon(ch); - bc = ch->brdchan; - if (ch->statusflags & LOWWAIT) - writeb(1, &bc->ilow); - /* Okay, you can start transmitting again... */ - fepcmd(ch, RESUMETX, 0, 0, 0, 0); - ch->statusflags &= ~TXSTOPPED; - memoff(ch); - } /* End transmit resume requested */ - spin_unlock_irqrestore(&epca_lock, flags); - } -} - -/* - * The below routines pc_throttle and pc_unthrottle are used to slow (And - * resume) the receipt of data into the kernels receive buffers. The exact - * occurrence of this depends on the size of the kernels receive buffer and - * what the 'watermarks' are set to for that buffer. See the n_ttys.c file for - * more details. - */ -static void pc_throttle(struct tty_struct *tty) -{ - struct channel *ch; - unsigned long flags; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch != NULL) { - spin_lock_irqsave(&epca_lock, flags); - if ((ch->statusflags & RXSTOPPED) == 0) { - globalwinon(ch); - fepcmd(ch, PAUSERX, 0, 0, 0, 0); - ch->statusflags |= RXSTOPPED; - memoff(ch); - } - spin_unlock_irqrestore(&epca_lock, flags); - } -} - -static void pc_unthrottle(struct tty_struct *tty) -{ - struct channel *ch; - unsigned long flags; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch != NULL) { - /* Just in case output was resumed because of a change - in Digi-flow */ - spin_lock_irqsave(&epca_lock, flags); - if (ch->statusflags & RXSTOPPED) { - globalwinon(ch); - fepcmd(ch, RESUMERX, 0, 0, 0, 0); - ch->statusflags &= ~RXSTOPPED; - memoff(ch); - } - spin_unlock_irqrestore(&epca_lock, flags); - } -} - -static int pc_send_break(struct tty_struct *tty, int msec) -{ - struct channel *ch = tty->driver_data; - unsigned long flags; - - if (msec == -1) - msec = 0xFFFF; - else if (msec > 0xFFFE) - msec = 0xFFFE; - else if (msec < 1) - msec = 1; - - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - /* - * Maybe I should send an infinite break here, schedule() for msec - * amount of time, and then stop the break. This way, the user can't - * screw up the FEP by causing digi_send_break() to be called (i.e. via - * an ioctl()) more than once in msec amount of time. - * Try this for now... - */ - fepcmd(ch, SENDBREAK, msec, 0, 10, 0); - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - return 0; -} - -/* Caller MUST hold the lock */ -static void setup_empty_event(struct tty_struct *tty, struct channel *ch) -{ - struct board_chan __iomem *bc = ch->brdchan; - - globalwinon(ch); - ch->statusflags |= EMPTYWAIT; - /* - * When set the iempty flag request a event to be generated when the - * transmit buffer is empty (If there is no BREAK in progress). - */ - writeb(1, &bc->iempty); - memoff(ch); -} - -#ifndef MODULE -static void __init epca_setup(char *str, int *ints) -{ - struct board_info board; - int index, loop, last; - char *temp, *t2; - unsigned len; - - /* - * If this routine looks a little strange it is because it is only - * called if a LILO append command is given to boot the kernel with - * parameters. In this way, we can provide the user a method of - * changing his board configuration without rebuilding the kernel. - */ - if (!liloconfig) - liloconfig = 1; - - memset(&board, 0, sizeof(board)); - - /* Assume the data is int first, later we can change it */ - /* I think that array position 0 of ints holds the number of args */ - for (last = 0, index = 1; index <= ints[0]; index++) - switch (index) { /* Begin parse switch */ - case 1: - board.status = ints[index]; - /* - * We check for 2 (As opposed to 1; because 2 is a flag - * instructing the driver to ignore epcaconfig.) For - * this reason we check for 2. - */ - if (board.status == 2) { - /* Begin ignore epcaconfig as well as lilo cmd line */ - nbdevs = 0; - num_cards = 0; - return; - } /* End ignore epcaconfig as well as lilo cmd line */ - - if (board.status > 2) { - printk(KERN_ERR "epca_setup: Invalid board status 0x%x\n", - board.status); - invalid_lilo_config = 1; - setup_error_code |= INVALID_BOARD_STATUS; - return; - } - last = index; - break; - case 2: - board.type = ints[index]; - if (board.type >= PCIXEM) { - printk(KERN_ERR "epca_setup: Invalid board type 0x%x\n", board.type); - invalid_lilo_config = 1; - setup_error_code |= INVALID_BOARD_TYPE; - return; - } - last = index; - break; - case 3: - board.altpin = ints[index]; - if (board.altpin > 1) { - printk(KERN_ERR "epca_setup: Invalid board altpin 0x%x\n", board.altpin); - invalid_lilo_config = 1; - setup_error_code |= INVALID_ALTPIN; - return; - } - last = index; - break; - - case 4: - board.numports = ints[index]; - if (board.numports < 2 || board.numports > 256) { - printk(KERN_ERR "epca_setup: Invalid board numports 0x%x\n", board.numports); - invalid_lilo_config = 1; - setup_error_code |= INVALID_NUM_PORTS; - return; - } - nbdevs += board.numports; - last = index; - break; - - case 5: - board.port = ints[index]; - if (ints[index] <= 0) { - printk(KERN_ERR "epca_setup: Invalid io port 0x%x\n", (unsigned int)board.port); - invalid_lilo_config = 1; - setup_error_code |= INVALID_PORT_BASE; - return; - } - last = index; - break; - - case 6: - board.membase = ints[index]; - if (ints[index] <= 0) { - printk(KERN_ERR "epca_setup: Invalid memory base 0x%x\n", - (unsigned int)board.membase); - invalid_lilo_config = 1; - setup_error_code |= INVALID_MEM_BASE; - return; - } - last = index; - break; - - default: - printk(KERN_ERR " - epca_setup: Too many integer parms\n"); - return; - - } /* End parse switch */ - - while (str && *str) { /* Begin while there is a string arg */ - /* find the next comma or terminator */ - temp = str; - /* While string is not null, and a comma hasn't been found */ - while (*temp && (*temp != ',')) - temp++; - if (!*temp) - temp = NULL; - else - *temp++ = 0; - /* Set index to the number of args + 1 */ - index = last + 1; - - switch (index) { - case 1: - len = strlen(str); - if (strncmp("Disable", str, len) == 0) - board.status = 0; - else if (strncmp("Enable", str, len) == 0) - board.status = 1; - else { - printk(KERN_ERR "epca_setup: Invalid status %s\n", str); - invalid_lilo_config = 1; - setup_error_code |= INVALID_BOARD_STATUS; - return; - } - last = index; - break; - - case 2: - for (loop = 0; loop < EPCA_NUM_TYPES; loop++) - if (strcmp(board_desc[loop], str) == 0) - break; - /* - * If the index incremented above refers to a - * legitamate board type set it here. - */ - if (index < EPCA_NUM_TYPES) - board.type = loop; - else { - printk(KERN_ERR "epca_setup: Invalid board type: %s\n", str); - invalid_lilo_config = 1; - setup_error_code |= INVALID_BOARD_TYPE; - return; - } - last = index; - break; - - case 3: - len = strlen(str); - if (strncmp("Disable", str, len) == 0) - board.altpin = 0; - else if (strncmp("Enable", str, len) == 0) - board.altpin = 1; - else { - printk(KERN_ERR "epca_setup: Invalid altpin %s\n", str); - invalid_lilo_config = 1; - setup_error_code |= INVALID_ALTPIN; - return; - } - last = index; - break; - - case 4: - t2 = str; - while (isdigit(*t2)) - t2++; - - if (*t2) { - printk(KERN_ERR "epca_setup: Invalid port count %s\n", str); - invalid_lilo_config = 1; - setup_error_code |= INVALID_NUM_PORTS; - return; - } - - /* - * There is not a man page for simple_strtoul but the - * code can be found in vsprintf.c. The first argument - * is the string to translate (To an unsigned long - * obviously), the second argument can be the address - * of any character variable or a NULL. If a variable - * is given, the end pointer of the string will be - * stored in that variable; if a NULL is given the end - * pointer will not be returned. The last argument is - * the base to use. If a 0 is indicated, the routine - * will attempt to determine the proper base by looking - * at the values prefix (A '0' for octal, a 'x' for - * hex, etc ... If a value is given it will use that - * value as the base. - */ - board.numports = simple_strtoul(str, NULL, 0); - nbdevs += board.numports; - last = index; - break; - - case 5: - t2 = str; - while (isxdigit(*t2)) - t2++; - - if (*t2) { - printk(KERN_ERR "epca_setup: Invalid i/o address %s\n", str); - invalid_lilo_config = 1; - setup_error_code |= INVALID_PORT_BASE; - return; - } - - board.port = simple_strtoul(str, NULL, 16); - last = index; - break; - - case 6: - t2 = str; - while (isxdigit(*t2)) - t2++; - - if (*t2) { - printk(KERN_ERR "epca_setup: Invalid memory base %s\n", str); - invalid_lilo_config = 1; - setup_error_code |= INVALID_MEM_BASE; - return; - } - board.membase = simple_strtoul(str, NULL, 16); - last = index; - break; - default: - printk(KERN_ERR "epca: Too many string parms\n"); - return; - } - str = temp; - } /* End while there is a string arg */ - - if (last < 6) { - printk(KERN_ERR "epca: Insufficient parms specified\n"); - return; - } - - /* I should REALLY validate the stuff here */ - /* Copies our local copy of board into boards */ - memcpy((void *)&boards[num_cards], (void *)&board, sizeof(board)); - /* Does this get called once per lilo arg are what ? */ - printk(KERN_INFO "PC/Xx: Added board %i, %s %i ports at 0x%4.4X base 0x%6.6X\n", - num_cards, board_desc[board.type], - board.numports, (int)board.port, (unsigned int) board.membase); - num_cards++; -} - -static int __init epca_real_setup(char *str) -{ - int ints[11]; - - epca_setup(get_options(str, 11, ints), ints); - return 1; -} - -__setup("digiepca", epca_real_setup); -#endif - -enum epic_board_types { - brd_xr = 0, - brd_xem, - brd_cx, - brd_xrj, -}; - -/* indexed directly by epic_board_types enum */ -static struct { - unsigned char board_type; - unsigned bar_idx; /* PCI base address region */ -} epca_info_tbl[] = { - { PCIXR, 0, }, - { PCIXEM, 0, }, - { PCICX, 0, }, - { PCIXRJ, 2, }, -}; - -static int __devinit epca_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - static int board_num = -1; - int board_idx, info_idx = ent->driver_data; - unsigned long addr; - - if (pci_enable_device(pdev)) - return -EIO; - - board_num++; - board_idx = board_num + num_cards; - if (board_idx >= MAXBOARDS) - goto err_out; - - addr = pci_resource_start(pdev, epca_info_tbl[info_idx].bar_idx); - if (!addr) { - printk(KERN_ERR PFX "PCI region #%d not available (size 0)\n", - epca_info_tbl[info_idx].bar_idx); - goto err_out; - } - - boards[board_idx].status = ENABLED; - boards[board_idx].type = epca_info_tbl[info_idx].board_type; - boards[board_idx].numports = 0x0; - boards[board_idx].port = addr + PCI_IO_OFFSET; - boards[board_idx].membase = addr; - - if (!request_mem_region(addr + PCI_IO_OFFSET, 0x200000, "epca")) { - printk(KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n", - 0x200000, addr + PCI_IO_OFFSET); - goto err_out; - } - - boards[board_idx].re_map_port = ioremap_nocache(addr + PCI_IO_OFFSET, - 0x200000); - if (!boards[board_idx].re_map_port) { - printk(KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n", - 0x200000, addr + PCI_IO_OFFSET); - goto err_out_free_pciio; - } - - if (!request_mem_region(addr, 0x200000, "epca")) { - printk(KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n", - 0x200000, addr); - goto err_out_free_iounmap; - } - - boards[board_idx].re_map_membase = ioremap_nocache(addr, 0x200000); - if (!boards[board_idx].re_map_membase) { - printk(KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n", - 0x200000, addr + PCI_IO_OFFSET); - goto err_out_free_memregion; - } - - /* - * I don't know what the below does, but the hardware guys say its - * required on everything except PLX (In this case XRJ). - */ - if (info_idx != brd_xrj) { - pci_write_config_byte(pdev, 0x40, 0); - pci_write_config_byte(pdev, 0x46, 0); - } - - return 0; - -err_out_free_memregion: - release_mem_region(addr, 0x200000); -err_out_free_iounmap: - iounmap(boards[board_idx].re_map_port); -err_out_free_pciio: - release_mem_region(addr + PCI_IO_OFFSET, 0x200000); -err_out: - return -ENODEV; -} - - -static struct pci_device_id epca_pci_tbl[] = { - { PCI_VENDOR_DIGI, PCI_DEVICE_XR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xr }, - { PCI_VENDOR_DIGI, PCI_DEVICE_XEM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xem }, - { PCI_VENDOR_DIGI, PCI_DEVICE_CX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_cx }, - { PCI_VENDOR_DIGI, PCI_DEVICE_XRJ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xrj }, - { 0, } -}; - -MODULE_DEVICE_TABLE(pci, epca_pci_tbl); - -static int __init init_PCI(void) -{ - memset(&epca_driver, 0, sizeof(epca_driver)); - epca_driver.name = "epca"; - epca_driver.id_table = epca_pci_tbl; - epca_driver.probe = epca_init_one; - - return pci_register_driver(&epca_driver); -} - -MODULE_LICENSE("GPL"); diff --git a/drivers/char/epca.h b/drivers/char/epca.h deleted file mode 100644 index d414bf2dbf7c..000000000000 --- a/drivers/char/epca.h +++ /dev/null @@ -1,158 +0,0 @@ -#define XEMPORTS 0xC02 -#define XEPORTS 0xC22 - -#define MAX_ALLOC 0x100 - -#define MAXBOARDS 12 -#define FEPCODESEG 0x0200L -#define FEPCODE 0x2000L -#define BIOSCODE 0xf800L - -#define MISCGLOBAL 0x0C00L -#define NPORT 0x0C22L -#define MBOX 0x0C40L -#define PORTBASE 0x0C90L - -/* Begin code defines used for epca_setup */ - -#define INVALID_BOARD_TYPE 0x1 -#define INVALID_NUM_PORTS 0x2 -#define INVALID_MEM_BASE 0x4 -#define INVALID_PORT_BASE 0x8 -#define INVALID_BOARD_STATUS 0x10 -#define INVALID_ALTPIN 0x20 - -/* End code defines used for epca_setup */ - - -#define FEPCLR 0x00 -#define FEPMEM 0x02 -#define FEPRST 0x04 -#define FEPINT 0x08 -#define FEPMASK 0x0e -#define FEPWIN 0x80 - -#define PCXE 0 -#define PCXEVE 1 -#define PCXEM 2 -#define EISAXEM 3 -#define PC64XE 4 -#define PCXI 5 -#define PCIXEM 7 -#define PCICX 8 -#define PCIXR 9 -#define PCIXRJ 10 -#define EPCA_NUM_TYPES 6 - - -static char *board_desc[] = -{ - "PC/Xe", - "PC/Xeve", - "PC/Xem", - "EISA/Xem", - "PC/64Xe", - "PC/Xi", - "unknown", - "PCI/Xem", - "PCI/CX", - "PCI/Xr", - "PCI/Xrj", -}; - -#define STARTC 021 -#define STOPC 023 -#define IAIXON 0x2000 - - -#define TXSTOPPED 0x1 -#define LOWWAIT 0x2 -#define EMPTYWAIT 0x4 -#define RXSTOPPED 0x8 -#define TXBUSY 0x10 - -#define DISABLED 0 -#define ENABLED 1 -#define OFF 0 -#define ON 1 - -#define FEPTIMEOUT 200000 -#define SERIAL_TYPE_INFO 3 -#define EPCA_EVENT_HANGUP 1 -#define EPCA_MAGIC 0x5c6df104L - -struct channel -{ - long magic; - struct tty_port port; - unsigned char boardnum; - unsigned char channelnum; - unsigned char omodem; /* FEP output modem status */ - unsigned char imodem; /* FEP input modem status */ - unsigned char modemfake; /* Modem values to be forced */ - unsigned char modem; /* Force values */ - unsigned char hflow; - unsigned char dsr; - unsigned char dcd; - unsigned char m_rts ; /* The bits used in whatever FEP */ - unsigned char m_dcd ; /* is indiginous to this board to */ - unsigned char m_dsr ; /* represent each of the physical */ - unsigned char m_cts ; /* handshake lines */ - unsigned char m_ri ; - unsigned char m_dtr ; - unsigned char stopc; - unsigned char startc; - unsigned char stopca; - unsigned char startca; - unsigned char fepstopc; - unsigned char fepstartc; - unsigned char fepstopca; - unsigned char fepstartca; - unsigned char txwin; - unsigned char rxwin; - unsigned short fepiflag; - unsigned short fepcflag; - unsigned short fepoflag; - unsigned short txbufhead; - unsigned short txbufsize; - unsigned short rxbufhead; - unsigned short rxbufsize; - int close_delay; - unsigned long event; - uint dev; - unsigned long statusflags; - unsigned long c_iflag; - unsigned long c_cflag; - unsigned long c_lflag; - unsigned long c_oflag; - unsigned char __iomem *txptr; - unsigned char __iomem *rxptr; - struct board_info *board; - struct board_chan __iomem *brdchan; - struct digi_struct digiext; - struct work_struct tqueue; - struct global_data __iomem *mailbox; -}; - -struct board_info -{ - unsigned char status; - unsigned char type; - unsigned char altpin; - unsigned short numports; - unsigned long port; - unsigned long membase; - void __iomem *re_map_port; - void __iomem *re_map_membase; - unsigned long memory_seg; - void ( * memwinon ) (struct board_info *, unsigned int) ; - void ( * memwinoff ) (struct board_info *, unsigned int) ; - void ( * globalwinon ) (struct channel *) ; - void ( * txwinon ) (struct channel *) ; - void ( * rxwinon ) (struct channel *) ; - void ( * memoff ) (struct channel *) ; - void ( * assertgwinon ) (struct channel *) ; - void ( * assertmemoff ) (struct channel *) ; - unsigned char poller_inhibited ; -}; - diff --git a/drivers/char/epcaconfig.h b/drivers/char/epcaconfig.h deleted file mode 100644 index 55dec067078e..000000000000 --- a/drivers/char/epcaconfig.h +++ /dev/null @@ -1,7 +0,0 @@ -#define NUMCARDS 0 -#define NBDEVS 0 - -struct board_info static_boards[NUMCARDS]={ -}; - -/* DO NOT HAND EDIT THIS FILE! */ diff --git a/drivers/char/ip2/Makefile b/drivers/char/ip2/Makefile deleted file mode 100644 index 7b78e0dfc5b0..000000000000 --- a/drivers/char/ip2/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for the Computone IntelliPort Plus Driver -# - -obj-$(CONFIG_COMPUTONE) += ip2.o - -ip2-y := ip2main.o - diff --git a/drivers/char/ip2/i2cmd.c b/drivers/char/ip2/i2cmd.c deleted file mode 100644 index e7af647800b6..000000000000 --- a/drivers/char/ip2/i2cmd.c +++ /dev/null @@ -1,210 +0,0 @@ -/******************************************************************************* -* -* (c) 1998 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Definition table for In-line and Bypass commands. Applicable -* only when the standard loadware is active. (This is included -* source code, not a separate compilation module.) -* -*******************************************************************************/ - -//------------------------------------------------------------------------------ -// -// Revision History: -// -// 10 October 1991 MAG First Draft -// 7 November 1991 MAG Reflects additional commands. -// 24 February 1992 MAG Additional commands for 1.4.x loadware -// 11 March 1992 MAG Additional commands -// 30 March 1992 MAG Additional command: CMD_DSS_NOW -// 18 May 1992 MAG Discovered commands 39 & 40 must be at the end of a -// packet: affects implementation. -//------------------------------------------------------------------------------ - -//************ -//* Includes * -//************ - -#include "i2cmd.h" /* To get some bit-defines */ - -//------------------------------------------------------------------------------ -// Here is the table of global arrays which represent each type of command -// supported in the IntelliPort standard loadware. See also i2cmd.h -// for a more complete explanation of what is going on. -//------------------------------------------------------------------------------ - -// Here are the various globals: note that the names are not used except through -// the macros defined in i2cmd.h. Also note that although they are character -// arrays here (for extendability) they are cast to structure pointers in the -// i2cmd.h macros. See i2cmd.h for flags definitions. - -// Length Flags Command -static UCHAR ct02[] = { 1, BTH, 0x02 }; // DTR UP -static UCHAR ct03[] = { 1, BTH, 0x03 }; // DTR DN -static UCHAR ct04[] = { 1, BTH, 0x04 }; // RTS UP -static UCHAR ct05[] = { 1, BTH, 0x05 }; // RTS DN -static UCHAR ct06[] = { 1, BYP, 0x06 }; // START FL -static UCHAR ct07[] = { 2, BTH, 0x07,0 }; // BAUD -static UCHAR ct08[] = { 2, BTH, 0x08,0 }; // BITS -static UCHAR ct09[] = { 2, BTH, 0x09,0 }; // STOP -static UCHAR ct10[] = { 2, BTH, 0x0A,0 }; // PARITY -static UCHAR ct11[] = { 2, BTH, 0x0B,0 }; // XON -static UCHAR ct12[] = { 2, BTH, 0x0C,0 }; // XOFF -static UCHAR ct13[] = { 1, BTH, 0x0D }; // STOP FL -static UCHAR ct14[] = { 1, BYP|VIP, 0x0E }; // ACK HOTK -//static UCHAR ct15[]={ 2, BTH|VIP, 0x0F,0 }; // IRQ SET -static UCHAR ct16[] = { 2, INL, 0x10,0 }; // IXONOPTS -static UCHAR ct17[] = { 2, INL, 0x11,0 }; // OXONOPTS -static UCHAR ct18[] = { 1, INL, 0x12 }; // CTSENAB -static UCHAR ct19[] = { 1, BTH, 0x13 }; // CTSDSAB -static UCHAR ct20[] = { 1, INL, 0x14 }; // DCDENAB -static UCHAR ct21[] = { 1, BTH, 0x15 }; // DCDDSAB -static UCHAR ct22[] = { 1, BTH, 0x16 }; // DSRENAB -static UCHAR ct23[] = { 1, BTH, 0x17 }; // DSRDSAB -static UCHAR ct24[] = { 1, BTH, 0x18 }; // RIENAB -static UCHAR ct25[] = { 1, BTH, 0x19 }; // RIDSAB -static UCHAR ct26[] = { 2, BTH, 0x1A,0 }; // BRKENAB -static UCHAR ct27[] = { 1, BTH, 0x1B }; // BRKDSAB -//static UCHAR ct28[]={ 2, BTH, 0x1C,0 }; // MAXBLOKSIZE -//static UCHAR ct29[]={ 2, 0, 0x1D,0 }; // reserved -static UCHAR ct30[] = { 1, INL, 0x1E }; // CTSFLOWENAB -static UCHAR ct31[] = { 1, INL, 0x1F }; // CTSFLOWDSAB -static UCHAR ct32[] = { 1, INL, 0x20 }; // RTSFLOWENAB -static UCHAR ct33[] = { 1, INL, 0x21 }; // RTSFLOWDSAB -static UCHAR ct34[] = { 2, BTH, 0x22,0 }; // ISTRIPMODE -static UCHAR ct35[] = { 2, BTH|END, 0x23,0 }; // SENDBREAK -static UCHAR ct36[] = { 2, BTH, 0x24,0 }; // SETERRMODE -//static UCHAR ct36a[]={ 3, INL, 0x24,0,0 }; // SET_REPLACE - -// The following is listed for completeness, but should never be sent directly -// by user-level code. It is sent only by library routines in response to data -// movement. -//static UCHAR ct37[]={ 5, BYP|VIP, 0x25,0,0,0,0 }; // FLOW PACKET - -// Back to normal -//static UCHAR ct38[] = {11, BTH|VAR, 0x26,0,0,0,0,0,0,0,0,0,0 }; // DEF KEY SEQ -//static UCHAR ct39[]={ 3, BTH|END, 0x27,0,0 }; // OPOSTON -//static UCHAR ct40[]={ 1, BTH|END, 0x28 }; // OPOSTOFF -static UCHAR ct41[] = { 1, BYP, 0x29 }; // RESUME -//static UCHAR ct42[]={ 2, BTH, 0x2A,0 }; // TXBAUD -//static UCHAR ct43[]={ 2, BTH, 0x2B,0 }; // RXBAUD -//static UCHAR ct44[]={ 2, BTH, 0x2C,0 }; // MS PING -//static UCHAR ct45[]={ 1, BTH, 0x2D }; // HOTENAB -//static UCHAR ct46[]={ 1, BTH, 0x2E }; // HOTDSAB -//static UCHAR ct47[]={ 7, BTH, 0x2F,0,0,0,0,0,0 }; // UNIX FLAGS -//static UCHAR ct48[]={ 1, BTH, 0x30 }; // DSRFLOWENAB -//static UCHAR ct49[]={ 1, BTH, 0x31 }; // DSRFLOWDSAB -//static UCHAR ct50[]={ 1, BTH, 0x32 }; // DTRFLOWENAB -//static UCHAR ct51[]={ 1, BTH, 0x33 }; // DTRFLOWDSAB -//static UCHAR ct52[]={ 1, BTH, 0x34 }; // BAUDTABRESET -//static UCHAR ct53[] = { 3, BTH, 0x35,0,0 }; // BAUDREMAP -static UCHAR ct54[] = { 3, BTH, 0x36,0,0 }; // CUSTOMBAUD1 -static UCHAR ct55[] = { 3, BTH, 0x37,0,0 }; // CUSTOMBAUD2 -static UCHAR ct56[] = { 2, BTH|END, 0x38,0 }; // PAUSE -static UCHAR ct57[] = { 1, BYP, 0x39 }; // SUSPEND -static UCHAR ct58[] = { 1, BYP, 0x3A }; // UNSUSPEND -static UCHAR ct59[] = { 2, BTH, 0x3B,0 }; // PARITYCHK -static UCHAR ct60[] = { 1, INL|VIP, 0x3C }; // BOOKMARKREQ -//static UCHAR ct61[]={ 2, BTH, 0x3D,0 }; // INTERNALLOOP -//static UCHAR ct62[]={ 2, BTH, 0x3E,0 }; // HOTKTIMEOUT -static UCHAR ct63[] = { 2, INL, 0x3F,0 }; // SETTXON -static UCHAR ct64[] = { 2, INL, 0x40,0 }; // SETTXOFF -//static UCHAR ct65[]={ 2, BTH, 0x41,0 }; // SETAUTORTS -//static UCHAR ct66[]={ 2, BTH, 0x42,0 }; // SETHIGHWAT -//static UCHAR ct67[]={ 2, BYP, 0x43,0 }; // STARTSELFL -//static UCHAR ct68[]={ 2, INL, 0x44,0 }; // ENDSELFL -//static UCHAR ct69[]={ 1, BYP, 0x45 }; // HWFLOW_OFF -//static UCHAR ct70[]={ 1, BTH, 0x46 }; // ODSRFL_ENAB -//static UCHAR ct71[]={ 1, BTH, 0x47 }; // ODSRFL_DSAB -//static UCHAR ct72[]={ 1, BTH, 0x48 }; // ODCDFL_ENAB -//static UCHAR ct73[]={ 1, BTH, 0x49 }; // ODCDFL_DSAB -//static UCHAR ct74[]={ 2, BTH, 0x4A,0 }; // LOADLEVEL -//static UCHAR ct75[]={ 2, BTH, 0x4B,0 }; // STATDATA -//static UCHAR ct76[]={ 1, BYP, 0x4C }; // BREAK_ON -//static UCHAR ct77[]={ 1, BYP, 0x4D }; // BREAK_OFF -//static UCHAR ct78[]={ 1, BYP, 0x4E }; // GETFC -static UCHAR ct79[] = { 2, BYP, 0x4F,0 }; // XMIT_NOW -//static UCHAR ct80[]={ 4, BTH, 0x50,0,0,0 }; // DIVISOR_LATCH -//static UCHAR ct81[]={ 1, BYP, 0x51 }; // GET_STATUS -//static UCHAR ct82[]={ 1, BYP, 0x52 }; // GET_TXCNT -//static UCHAR ct83[]={ 1, BYP, 0x53 }; // GET_RXCNT -//static UCHAR ct84[]={ 1, BYP, 0x54 }; // GET_BOXIDS -//static UCHAR ct85[]={10, BYP, 0x55,0,0,0,0,0,0,0,0,0 }; // ENAB_MULT -//static UCHAR ct86[]={ 2, BTH, 0x56,0 }; // RCV_ENABLE -static UCHAR ct87[] = { 1, BYP, 0x57 }; // HW_TEST -//static UCHAR ct88[]={ 3, BTH, 0x58,0,0 }; // RCV_THRESHOLD -//static UCHAR ct90[]={ 3, BYP, 0x5A,0,0 }; // Set SILO -//static UCHAR ct91[]={ 2, BYP, 0x5B,0 }; // timed break - -// Some composite commands as well -//static UCHAR cc01[]={ 2, BTH, 0x02,0x04 }; // DTR & RTS UP -//static UCHAR cc02[]={ 2, BTH, 0x03,0x05 }; // DTR & RTS DN - -//******** -//* Code * -//******** - -//****************************************************************************** -// Function: i2cmdUnixFlags(iflag, cflag, lflag) -// Parameters: Unix tty flags -// -// Returns: Pointer to command structure -// -// Description: -// -// This routine sets the parameters of command 47 and returns a pointer to the -// appropriate structure. -//****************************************************************************** -#if 0 -cmdSyntaxPtr -i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag) -{ - cmdSyntaxPtr pCM = (cmdSyntaxPtr) ct47; - - pCM->cmd[1] = (unsigned char) iflag; - pCM->cmd[2] = (unsigned char) (iflag >> 8); - pCM->cmd[3] = (unsigned char) cflag; - pCM->cmd[4] = (unsigned char) (cflag >> 8); - pCM->cmd[5] = (unsigned char) lflag; - pCM->cmd[6] = (unsigned char) (lflag >> 8); - return pCM; -} -#endif /* 0 */ - -//****************************************************************************** -// Function: i2cmdBaudDef(which, rate) -// Parameters: ? -// -// Returns: Pointer to command structure -// -// Description: -// -// This routine sets the parameters of commands 54 or 55 (according to the -// argument which), and returns a pointer to the appropriate structure. -//****************************************************************************** -static cmdSyntaxPtr -i2cmdBaudDef(int which, unsigned short rate) -{ - cmdSyntaxPtr pCM; - - switch(which) - { - case 1: - pCM = (cmdSyntaxPtr) ct54; - break; - default: - case 2: - pCM = (cmdSyntaxPtr) ct55; - break; - } - pCM->cmd[1] = (unsigned char) rate; - pCM->cmd[2] = (unsigned char) (rate >> 8); - return pCM; -} - diff --git a/drivers/char/ip2/i2cmd.h b/drivers/char/ip2/i2cmd.h deleted file mode 100644 index 29277ec6b8ed..000000000000 --- a/drivers/char/ip2/i2cmd.h +++ /dev/null @@ -1,630 +0,0 @@ -/******************************************************************************* -* -* (c) 1999 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Definitions and support for In-line and Bypass commands. -* Applicable only when the standard loadware is active. -* -*******************************************************************************/ -//------------------------------------------------------------------------------ -// Revision History: -// -// 10 October 1991 MAG First Draft -// 7 November 1991 MAG Reflects some new commands -// 20 February 1992 MAG CMD_HOTACK corrected: no argument. -// 24 February 1992 MAG Support added for new commands for 1.4.x loadware. -// 11 March 1992 MAG Additional commands. -// 16 March 1992 MAG Additional commands. -// 30 March 1992 MAG Additional command: CMD_DSS_NOW -// 18 May 1992 MAG Changed CMD_OPOST -// -//------------------------------------------------------------------------------ -#ifndef I2CMD_H // To prevent multiple includes -#define I2CMD_H 1 - -#include "ip2types.h" - -// This module is designed to provide a uniform method of sending commands to -// the board through command packets. The difficulty is, some commands take -// parameters, others do not. Furthermore, it is often useful to send several -// commands to the same channel as part of the same packet. (See also i2pack.h.) -// -// This module is designed so that the caller should not be responsible for -// remembering the exact syntax of each command, or at least so that the -// compiler could check things somewhat. I'll explain as we go... -// -// First, a structure which can embody the syntax of each type of command. -// -typedef struct _cmdSyntax -{ - UCHAR length; // Number of bytes in the command - UCHAR flags; // Information about the command (see below) - - // The command and its parameters, which may be of arbitrary length. Don't - // worry yet how the parameters will be initialized; macros later take care - // of it. Also, don't worry about the arbitrary length issue; this structure - // is never used to allocate space (see i2cmd.c). - UCHAR cmd[2]; -} cmdSyntax, *cmdSyntaxPtr; - -// Bit assignments for flags - -#define INL 1 // Set if suitable for inline commands -#define BYP 2 // Set if suitable for bypass commands -#define BTH (INL|BYP) // suitable for either! -#define END 4 // Set if this must be the last command in a block -#define VIP 8 // Set if this command is special in some way and really - // should only be sent from the library-level and not - // directly from user-level -#define VAR 0x10 // This command is of variable length! - -// Declarations for the global arrays used to bear the commands and their -// arguments. -// -// Note: Since these are globals and the arguments might change, it is important -// that the library routine COPY these into buffers from whence they would be -// sent, rather than merely storing the pointers. In multi-threaded -// environments, important that the copy should obtain before any context switch -// is allowed. Also, for parameterized commands, DO NOT ISSUE THE SAME COMMAND -// MORE THAN ONCE WITH THE SAME PARAMETERS in the same call. -// -static UCHAR ct02[]; -static UCHAR ct03[]; -static UCHAR ct04[]; -static UCHAR ct05[]; -static UCHAR ct06[]; -static UCHAR ct07[]; -static UCHAR ct08[]; -static UCHAR ct09[]; -static UCHAR ct10[]; -static UCHAR ct11[]; -static UCHAR ct12[]; -static UCHAR ct13[]; -static UCHAR ct14[]; -static UCHAR ct15[]; -static UCHAR ct16[]; -static UCHAR ct17[]; -static UCHAR ct18[]; -static UCHAR ct19[]; -static UCHAR ct20[]; -static UCHAR ct21[]; -static UCHAR ct22[]; -static UCHAR ct23[]; -static UCHAR ct24[]; -static UCHAR ct25[]; -static UCHAR ct26[]; -static UCHAR ct27[]; -static UCHAR ct28[]; -static UCHAR ct29[]; -static UCHAR ct30[]; -static UCHAR ct31[]; -static UCHAR ct32[]; -static UCHAR ct33[]; -static UCHAR ct34[]; -static UCHAR ct35[]; -static UCHAR ct36[]; -static UCHAR ct36a[]; -static UCHAR ct41[]; -static UCHAR ct42[]; -static UCHAR ct43[]; -static UCHAR ct44[]; -static UCHAR ct45[]; -static UCHAR ct46[]; -static UCHAR ct48[]; -static UCHAR ct49[]; -static UCHAR ct50[]; -static UCHAR ct51[]; -static UCHAR ct52[]; -static UCHAR ct56[]; -static UCHAR ct57[]; -static UCHAR ct58[]; -static UCHAR ct59[]; -static UCHAR ct60[]; -static UCHAR ct61[]; -static UCHAR ct62[]; -static UCHAR ct63[]; -static UCHAR ct64[]; -static UCHAR ct65[]; -static UCHAR ct66[]; -static UCHAR ct67[]; -static UCHAR ct68[]; -static UCHAR ct69[]; -static UCHAR ct70[]; -static UCHAR ct71[]; -static UCHAR ct72[]; -static UCHAR ct73[]; -static UCHAR ct74[]; -static UCHAR ct75[]; -static UCHAR ct76[]; -static UCHAR ct77[]; -static UCHAR ct78[]; -static UCHAR ct79[]; -static UCHAR ct80[]; -static UCHAR ct81[]; -static UCHAR ct82[]; -static UCHAR ct83[]; -static UCHAR ct84[]; -static UCHAR ct85[]; -static UCHAR ct86[]; -static UCHAR ct87[]; -static UCHAR ct88[]; -static UCHAR ct89[]; -static UCHAR ct90[]; -static UCHAR ct91[]; -static UCHAR cc01[]; -static UCHAR cc02[]; - -// Now, refer to i2cmd.c, and see the character arrays defined there. They are -// cast here to cmdSyntaxPtr. -// -// There are library functions for issuing bypass or inline commands. These -// functions take one or more arguments of the type cmdSyntaxPtr. The routine -// then can figure out how long each command is supposed to be and easily add it -// to the list. -// -// For ease of use, we define manifests which return pointers to appropriate -// cmdSyntaxPtr things. But some commands also take arguments. If a single -// argument is used, we define a macro which performs the single assignment and -// (through the expedient of a comma expression) references the appropriate -// pointer. For commands requiring several arguments, we actually define a -// function to perform the assignments. - -#define CMD_DTRUP (cmdSyntaxPtr)(ct02) // Raise DTR -#define CMD_DTRDN (cmdSyntaxPtr)(ct03) // Lower DTR -#define CMD_RTSUP (cmdSyntaxPtr)(ct04) // Raise RTS -#define CMD_RTSDN (cmdSyntaxPtr)(ct05) // Lower RTS -#define CMD_STARTFL (cmdSyntaxPtr)(ct06) // Start Flushing Data - -#define CMD_DTRRTS_UP (cmdSyntaxPtr)(cc01) // Raise DTR and RTS -#define CMD_DTRRTS_DN (cmdSyntaxPtr)(cc02) // Lower DTR and RTS - -// Set Baud Rate for transmit and receive -#define CMD_SETBAUD(arg) \ - (((cmdSyntaxPtr)(ct07))->cmd[1] = (arg),(cmdSyntaxPtr)(ct07)) - -#define CBR_50 1 -#define CBR_75 2 -#define CBR_110 3 -#define CBR_134 4 -#define CBR_150 5 -#define CBR_200 6 -#define CBR_300 7 -#define CBR_600 8 -#define CBR_1200 9 -#define CBR_1800 10 -#define CBR_2400 11 -#define CBR_4800 12 -#define CBR_9600 13 -#define CBR_19200 14 -#define CBR_38400 15 -#define CBR_2000 16 -#define CBR_3600 17 -#define CBR_7200 18 -#define CBR_56000 19 -#define CBR_57600 20 -#define CBR_64000 21 -#define CBR_76800 22 -#define CBR_115200 23 -#define CBR_C1 24 // Custom baud rate 1 -#define CBR_C2 25 // Custom baud rate 2 -#define CBR_153600 26 -#define CBR_230400 27 -#define CBR_307200 28 -#define CBR_460800 29 -#define CBR_921600 30 - -// Set Character size -// -#define CMD_SETBITS(arg) \ - (((cmdSyntaxPtr)(ct08))->cmd[1] = (arg),(cmdSyntaxPtr)(ct08)) - -#define CSZ_5 0 -#define CSZ_6 1 -#define CSZ_7 2 -#define CSZ_8 3 - -// Set number of stop bits -// -#define CMD_SETSTOP(arg) \ - (((cmdSyntaxPtr)(ct09))->cmd[1] = (arg),(cmdSyntaxPtr)(ct09)) - -#define CST_1 0 -#define CST_15 1 // 1.5 stop bits -#define CST_2 2 - -// Set parity option -// -#define CMD_SETPAR(arg) \ - (((cmdSyntaxPtr)(ct10))->cmd[1] = (arg),(cmdSyntaxPtr)(ct10)) - -#define CSP_NP 0 // no parity -#define CSP_OD 1 // odd parity -#define CSP_EV 2 // Even parity -#define CSP_SP 3 // Space parity -#define CSP_MK 4 // Mark parity - -// Define xon char for transmitter flow control -// -#define CMD_DEF_IXON(arg) \ - (((cmdSyntaxPtr)(ct11))->cmd[1] = (arg),(cmdSyntaxPtr)(ct11)) - -// Define xoff char for transmitter flow control -// -#define CMD_DEF_IXOFF(arg) \ - (((cmdSyntaxPtr)(ct12))->cmd[1] = (arg),(cmdSyntaxPtr)(ct12)) - -#define CMD_STOPFL (cmdSyntaxPtr)(ct13) // Stop Flushing data - -// Acknowledge receipt of hotkey signal -// -#define CMD_HOTACK (cmdSyntaxPtr)(ct14) - -// Define irq level to use. Should actually be sent by library-level code, not -// directly from user... -// -#define CMDVALUE_IRQ 15 // For library use at initialization. Until this command - // is sent, board processing doesn't really start. -#define CMD_SET_IRQ(arg) \ - (((cmdSyntaxPtr)(ct15))->cmd[1] = (arg),(cmdSyntaxPtr)(ct15)) - -#define CIR_POLL 0 // No IRQ - Poll -#define CIR_3 3 // IRQ 3 -#define CIR_4 4 // IRQ 4 -#define CIR_5 5 // IRQ 5 -#define CIR_7 7 // IRQ 7 -#define CIR_10 10 // IRQ 10 -#define CIR_11 11 // IRQ 11 -#define CIR_12 12 // IRQ 12 -#define CIR_15 15 // IRQ 15 - -// Select transmit flow xon/xoff options -// -#define CMD_IXON_OPT(arg) \ - (((cmdSyntaxPtr)(ct16))->cmd[1] = (arg),(cmdSyntaxPtr)(ct16)) - -#define CIX_NONE 0 // Incoming Xon/Xoff characters not special -#define CIX_XON 1 // Xoff disable, Xon enable -#define CIX_XANY 2 // Xoff disable, any key enable - -// Select receive flow xon/xoff options -// -#define CMD_OXON_OPT(arg) \ - (((cmdSyntaxPtr)(ct17))->cmd[1] = (arg),(cmdSyntaxPtr)(ct17)) - -#define COX_NONE 0 // Don't send Xon/Xoff -#define COX_XON 1 // Send xon/xoff to start/stop incoming data - - -#define CMD_CTS_REP (cmdSyntaxPtr)(ct18) // Enable CTS reporting -#define CMD_CTS_NREP (cmdSyntaxPtr)(ct19) // Disable CTS reporting - -#define CMD_DCD_REP (cmdSyntaxPtr)(ct20) // Enable DCD reporting -#define CMD_DCD_NREP (cmdSyntaxPtr)(ct21) // Disable DCD reporting - -#define CMD_DSR_REP (cmdSyntaxPtr)(ct22) // Enable DSR reporting -#define CMD_DSR_NREP (cmdSyntaxPtr)(ct23) // Disable DSR reporting - -#define CMD_RI_REP (cmdSyntaxPtr)(ct24) // Enable RI reporting -#define CMD_RI_NREP (cmdSyntaxPtr)(ct25) // Disable RI reporting - -// Enable break reporting and select style -// -#define CMD_BRK_REP(arg) \ - (((cmdSyntaxPtr)(ct26))->cmd[1] = (arg),(cmdSyntaxPtr)(ct26)) - -#define CBK_STAT 0x00 // Report breaks as a status (exception,irq) -#define CBK_NULL 0x01 // Report breaks as a good null -#define CBK_STAT_SEQ 0x02 // Report breaks as a status AND as in-band character - // sequence FFh, 01h, 10h -#define CBK_SEQ 0x03 // Report breaks as the in-band - //sequence FFh, 01h, 10h ONLY. -#define CBK_FLSH 0x04 // if this bit set also flush input data -#define CBK_POSIX 0x08 // if this bit set report as FF,0,0 sequence -#define CBK_SINGLE 0x10 // if this bit set with CBK_SEQ or CBK_STAT_SEQ - //then reports single null instead of triple - -#define CMD_BRK_NREP (cmdSyntaxPtr)(ct27) // Disable break reporting - -// Specify maximum block size for received data -// -#define CMD_MAX_BLOCK(arg) \ - (((cmdSyntaxPtr)(ct28))->cmd[1] = (arg),(cmdSyntaxPtr)(ct28)) - -// -- COMMAND 29 is reserved -- - -#define CMD_CTSFL_ENAB (cmdSyntaxPtr)(ct30) // Enable CTS flow control -#define CMD_CTSFL_DSAB (cmdSyntaxPtr)(ct31) // Disable CTS flow control -#define CMD_RTSFL_ENAB (cmdSyntaxPtr)(ct32) // Enable RTS flow control -#define CMD_RTSFL_DSAB (cmdSyntaxPtr)(ct33) // Disable RTS flow control - -// Specify istrip option -// -#define CMD_ISTRIP_OPT(arg) \ - (((cmdSyntaxPtr)(ct34))->cmd[1] = (arg),(cmdSyntaxPtr)(ct34)) - -#define CIS_NOSTRIP 0 // Strip characters to character size -#define CIS_STRIP 1 // Strip any 8-bit characters to 7 bits - -// Send a break of arg milliseconds -// -#define CMD_SEND_BRK(arg) \ - (((cmdSyntaxPtr)(ct35))->cmd[1] = (arg),(cmdSyntaxPtr)(ct35)) - -// Set error reporting mode -// -#define CMD_SET_ERROR(arg) \ - (((cmdSyntaxPtr)(ct36))->cmd[1] = (arg),(cmdSyntaxPtr)(ct36)) - -#define CSE_ESTAT 0 // Report error in a status packet -#define CSE_NOREP 1 // Treat character as though it were good -#define CSE_DROP 2 // Discard the character -#define CSE_NULL 3 // Replace with a null -#define CSE_MARK 4 // Replace with a 3-character sequence (as Unix) - -#define CSE_REPLACE 0x8 // Replace the errored character with the - // replacement character defined here - -#define CSE_STAT_REPLACE 0x18 // Replace the errored character with the - // replacement character defined here AND - // report the error as a status packet (as in - // CSE_ESTAT). - - -// COMMAND 37, to send flow control packets, is handled only by low-level -// library code in response to data movement and shouldn't ever be sent by the -// user code. See i2pack.h and the body of i2lib.c for details. - -// Enable on-board post-processing, using options given in oflag argument. -// Formerly, this command was automatically preceded by a CMD_OPOST_OFF command -// because the loadware does not permit sending back-to-back CMD_OPOST_ON -// commands without an intervening CMD_OPOST_OFF. BUT, WE LEARN 18 MAY 92, that -// CMD_OPOST_ON and CMD_OPOST_OFF must each be at the end of a packet (or in a -// solo packet). This means the caller must specify separately CMD_OPOST_OFF, -// CMD_OPOST_ON(parm) when he calls i2QueueCommands(). That function will ensure -// each gets a separate packet. Extra CMD_OPOST_OFF's are always ok. -// -#define CMD_OPOST_ON(oflag) \ - (*(USHORT *)(((cmdSyntaxPtr)(ct39))->cmd[1]) = (oflag), \ - (cmdSyntaxPtr)(ct39)) - -#define CMD_OPOST_OFF (cmdSyntaxPtr)(ct40) // Disable on-board post-proc - -#define CMD_RESUME (cmdSyntaxPtr)(ct41) // Resume: behave as though an XON - // were received; - -// Set Transmit baud rate (see command 7 for arguments) -// -#define CMD_SETBAUD_TX(arg) \ - (((cmdSyntaxPtr)(ct42))->cmd[1] = (arg),(cmdSyntaxPtr)(ct42)) - -// Set Receive baud rate (see command 7 for arguments) -// -#define CMD_SETBAUD_RX(arg) \ - (((cmdSyntaxPtr)(ct43))->cmd[1] = (arg),(cmdSyntaxPtr)(ct43)) - -// Request interrupt from board each arg milliseconds. Interrupt will specify -// "received data", even though there may be no data present. If arg == 0, -// disables any such interrupts. -// -#define CMD_PING_REQ(arg) \ - (((cmdSyntaxPtr)(ct44))->cmd[1] = (arg),(cmdSyntaxPtr)(ct44)) - -#define CMD_HOT_ENAB (cmdSyntaxPtr)(ct45) // Enable Hot-key checking -#define CMD_HOT_DSAB (cmdSyntaxPtr)(ct46) // Disable Hot-key checking - -#if 0 -// COMMAND 47: Send Protocol info via Unix flags: -// iflag = Unix tty t_iflag -// cflag = Unix tty t_cflag -// lflag = Unix tty t_lflag -// See System V Unix/Xenix documentation for the meanings of the bit fields -// within these flags -// -#define CMD_UNIX_FLAGS(iflag,cflag,lflag) i2cmdUnixFlags(iflag,cflag,lflag) -#endif /* 0 */ - -#define CMD_DSRFL_ENAB (cmdSyntaxPtr)(ct48) // Enable DSR receiver ctrl -#define CMD_DSRFL_DSAB (cmdSyntaxPtr)(ct49) // Disable DSR receiver ctrl -#define CMD_DTRFL_ENAB (cmdSyntaxPtr)(ct50) // Enable DTR flow control -#define CMD_DTRFL_DSAB (cmdSyntaxPtr)(ct51) // Disable DTR flow control -#define CMD_BAUD_RESET (cmdSyntaxPtr)(ct52) // Reset baudrate table - -// COMMAND 54: Define custom rate #1 -// rate = (short) 1/10 of the desired baud rate -// -#define CMD_BAUD_DEF1(rate) i2cmdBaudDef(1,rate) - -// COMMAND 55: Define custom rate #2 -// rate = (short) 1/10 of the desired baud rate -// -#define CMD_BAUD_DEF2(rate) i2cmdBaudDef(2,rate) - -// Pause arg hundredths of seconds. (Note, this is NOT milliseconds.) -// -#define CMD_PAUSE(arg) \ - (((cmdSyntaxPtr)(ct56))->cmd[1] = (arg),(cmdSyntaxPtr)(ct56)) - -#define CMD_SUSPEND (cmdSyntaxPtr)(ct57) // Suspend output -#define CMD_UNSUSPEND (cmdSyntaxPtr)(ct58) // Un-Suspend output - -// Set parity-checking options -// -#define CMD_PARCHK(arg) \ - (((cmdSyntaxPtr)(ct59))->cmd[1] = (arg),(cmdSyntaxPtr)(ct59)) - -#define CPK_ENAB 0 // Enable parity checking on input -#define CPK_DSAB 1 // Disable parity checking on input - -#define CMD_BMARK_REQ (cmdSyntaxPtr)(ct60) // Bookmark request - - -// Enable/Disable internal loopback mode -// -#define CMD_INLOOP(arg) \ - (((cmdSyntaxPtr)(ct61))->cmd[1] = (arg),(cmdSyntaxPtr)(ct61)) - -#define CIN_DISABLE 0 // Normal operation (default) -#define CIN_ENABLE 1 // Internal (local) loopback -#define CIN_REMOTE 2 // Remote loopback - -// Specify timeout for hotkeys: Delay will be (arg x 10) milliseconds, arg == 0 -// --> no timeout: wait forever. -// -#define CMD_HOT_TIME(arg) \ - (((cmdSyntaxPtr)(ct62))->cmd[1] = (arg),(cmdSyntaxPtr)(ct62)) - - -// Define (outgoing) xon for receive flow control -// -#define CMD_DEF_OXON(arg) \ - (((cmdSyntaxPtr)(ct63))->cmd[1] = (arg),(cmdSyntaxPtr)(ct63)) - -// Define (outgoing) xoff for receiver flow control -// -#define CMD_DEF_OXOFF(arg) \ - (((cmdSyntaxPtr)(ct64))->cmd[1] = (arg),(cmdSyntaxPtr)(ct64)) - -// Enable/Disable RTS on transmit (1/2 duplex-style) -// -#define CMD_RTS_XMIT(arg) \ - (((cmdSyntaxPtr)(ct65))->cmd[1] = (arg),(cmdSyntaxPtr)(ct65)) - -#define CHD_DISABLE 0 -#define CHD_ENABLE 1 - -// Set high-water-mark level (debugging use only) -// -#define CMD_SETHIGHWAT(arg) \ - (((cmdSyntaxPtr)(ct66))->cmd[1] = (arg),(cmdSyntaxPtr)(ct66)) - -// Start flushing tagged data (tag = 0-14) -// -#define CMD_START_SELFL(tag) \ - (((cmdSyntaxPtr)(ct67))->cmd[1] = (tag),(cmdSyntaxPtr)(ct67)) - -// End flushing tagged data (tag = 0-14) -// -#define CMD_END_SELFL(tag) \ - (((cmdSyntaxPtr)(ct68))->cmd[1] = (tag),(cmdSyntaxPtr)(ct68)) - -#define CMD_HWFLOW_OFF (cmdSyntaxPtr)(ct69) // Disable HW TX flow control -#define CMD_ODSRFL_ENAB (cmdSyntaxPtr)(ct70) // Enable DSR output f/c -#define CMD_ODSRFL_DSAB (cmdSyntaxPtr)(ct71) // Disable DSR output f/c -#define CMD_ODCDFL_ENAB (cmdSyntaxPtr)(ct72) // Enable DCD output f/c -#define CMD_ODCDFL_DSAB (cmdSyntaxPtr)(ct73) // Disable DCD output f/c - -// Set transmit interrupt load level. Count should be an even value 2-12 -// -#define CMD_LOADLEVEL(count) \ - (((cmdSyntaxPtr)(ct74))->cmd[1] = (count),(cmdSyntaxPtr)(ct74)) - -// If reporting DSS changes, map to character sequence FFh, 2, MSR -// -#define CMD_STATDATA(arg) \ - (((cmdSyntaxPtr)(ct75))->cmd[1] = (arg),(cmdSyntaxPtr)(ct75)) - -#define CSTD_DISABLE// Report DSS changes as status packets only (default) -#define CSTD_ENABLE // Report DSS changes as in-band data sequence as well as - // by status packet. - -#define CMD_BREAK_ON (cmdSyntaxPtr)(ct76)// Set break and stop xmit -#define CMD_BREAK_OFF (cmdSyntaxPtr)(ct77)// End break and restart xmit -#define CMD_GETFC (cmdSyntaxPtr)(ct78)// Request for flow control packet - // from board. - -// Transmit this character immediately -// -#define CMD_XMIT_NOW(ch) \ - (((cmdSyntaxPtr)(ct79))->cmd[1] = (ch),(cmdSyntaxPtr)(ct79)) - -// Set baud rate via "divisor latch" -// -#define CMD_DIVISOR_LATCH(which,value) \ - (((cmdSyntaxPtr)(ct80))->cmd[1] = (which), \ - *(USHORT *)(((cmdSyntaxPtr)(ct80))->cmd[2]) = (value), \ - (cmdSyntaxPtr)(ct80)) - -#define CDL_RX 1 // Set receiver rate -#define CDL_TX 2 // Set transmit rate - // (CDL_TX | CDL_RX) Set both rates - -// Request for special diagnostic status pkt from the board. -// -#define CMD_GET_STATUS (cmdSyntaxPtr)(ct81) - -// Request time-stamped transmit character count packet. -// -#define CMD_GET_TXCNT (cmdSyntaxPtr)(ct82) - -// Request time-stamped receive character count packet. -// -#define CMD_GET_RXCNT (cmdSyntaxPtr)(ct83) - -// Request for box/board I.D. packet. -#define CMD_GET_BOXIDS (cmdSyntaxPtr)(ct84) - -// Enable or disable multiple channels according to bit-mapped ushorts box 1-4 -// -#define CMD_ENAB_MULT(enable, box1, box2, box3, box4) \ - (((cmdSytaxPtr)(ct85))->cmd[1] = (enable), \ - *(USHORT *)(((cmdSyntaxPtr)(ct85))->cmd[2]) = (box1), \ - *(USHORT *)(((cmdSyntaxPtr)(ct85))->cmd[4]) = (box2), \ - *(USHORT *)(((cmdSyntaxPtr)(ct85))->cmd[6]) = (box3), \ - *(USHORT *)(((cmdSyntaxPtr)(ct85))->cmd[8]) = (box4), \ - (cmdSyntaxPtr)(ct85)) - -#define CEM_DISABLE 0 -#define CEM_ENABLE 1 - -// Enable or disable receiver or receiver interrupts (default both enabled) -// -#define CMD_RCV_ENABLE(ch) \ - (((cmdSyntaxPtr)(ct86))->cmd[1] = (ch),(cmdSyntaxPtr)(ct86)) - -#define CRE_OFF 0 // Disable the receiver -#define CRE_ON 1 // Enable the receiver -#define CRE_INTOFF 2 // Disable receiver interrupts (to loadware) -#define CRE_INTON 3 // Enable receiver interrupts (to loadware) - -// Starts up a hardware test process, which runs transparently, and sends a -// STAT_HWFAIL packet in case a hardware failure is detected. -// -#define CMD_HW_TEST (cmdSyntaxPtr)(ct87) - -// Change receiver threshold and timeout value: -// Defaults: timeout = 20mS -// threshold count = 8 when DTRflow not in use, -// threshold count = 5 when DTRflow in use. -// -#define CMD_RCV_THRESHOLD(count,ms) \ - (((cmdSyntaxPtr)(ct88))->cmd[1] = (count), \ - ((cmdSyntaxPtr)(ct88))->cmd[2] = (ms), \ - (cmdSyntaxPtr)(ct88)) - -// Makes the loadware report DSS signals for this channel immediately. -// -#define CMD_DSS_NOW (cmdSyntaxPtr)(ct89) - -// Set the receive silo parameters -// timeout is ms idle wait until delivery (~VTIME) -// threshold is max characters cause interrupt (~VMIN) -// -#define CMD_SET_SILO(timeout,threshold) \ - (((cmdSyntaxPtr)(ct90))->cmd[1] = (timeout), \ - ((cmdSyntaxPtr)(ct90))->cmd[2] = (threshold), \ - (cmdSyntaxPtr)(ct90)) - -// Set timed break in decisecond (1/10s) -// -#define CMD_LBREAK(ds) \ - (((cmdSyntaxPtr)(ct91))->cmd[1] = (ds),(cmdSyntaxPtr)(ct66)) - - - -#endif // I2CMD_H diff --git a/drivers/char/ip2/i2ellis.c b/drivers/char/ip2/i2ellis.c deleted file mode 100644 index 29db44de399f..000000000000 --- a/drivers/char/ip2/i2ellis.c +++ /dev/null @@ -1,1403 +0,0 @@ -/******************************************************************************* -* -* (c) 1998 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Low-level interface code for the device driver -* (This is included source code, not a separate compilation -* module.) -* -*******************************************************************************/ -//--------------------------------------------- -// Function declarations private to this module -//--------------------------------------------- -// Functions called only indirectly through i2eBordStr entries. - -static int iiWriteBuf16(i2eBordStrPtr, unsigned char *, int); -static int iiWriteBuf8(i2eBordStrPtr, unsigned char *, int); -static int iiReadBuf16(i2eBordStrPtr, unsigned char *, int); -static int iiReadBuf8(i2eBordStrPtr, unsigned char *, int); - -static unsigned short iiReadWord16(i2eBordStrPtr); -static unsigned short iiReadWord8(i2eBordStrPtr); -static void iiWriteWord16(i2eBordStrPtr, unsigned short); -static void iiWriteWord8(i2eBordStrPtr, unsigned short); - -static int iiWaitForTxEmptyII(i2eBordStrPtr, int); -static int iiWaitForTxEmptyIIEX(i2eBordStrPtr, int); -static int iiTxMailEmptyII(i2eBordStrPtr); -static int iiTxMailEmptyIIEX(i2eBordStrPtr); -static int iiTrySendMailII(i2eBordStrPtr, unsigned char); -static int iiTrySendMailIIEX(i2eBordStrPtr, unsigned char); - -static unsigned short iiGetMailII(i2eBordStrPtr); -static unsigned short iiGetMailIIEX(i2eBordStrPtr); - -static void iiEnableMailIrqII(i2eBordStrPtr); -static void iiEnableMailIrqIIEX(i2eBordStrPtr); -static void iiWriteMaskII(i2eBordStrPtr, unsigned char); -static void iiWriteMaskIIEX(i2eBordStrPtr, unsigned char); - -static void ii2Nop(void); - -//*************** -//* Static Data * -//*************** - -static int ii2Safe; // Safe I/O address for delay routine - -static int iiDelayed; // Set when the iiResetDelay function is - // called. Cleared when ANY board is reset. -static DEFINE_RWLOCK(Dl_spinlock); - -//******** -//* Code * -//******** - -//======================================================= -// Initialization Routines -// -// iiSetAddress -// iiReset -// iiResetDelay -// iiInitialize -//======================================================= - -//****************************************************************************** -// Function: iiSetAddress(pB, address, delay) -// Parameters: pB - pointer to the board structure -// address - the purported I/O address of the board -// delay - pointer to the 1-ms delay function to use -// in this and any future operations to this board -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// This routine (roughly) checks for address validity, sets the i2eValid OK and -// sets the state to II_STATE_COLD which means that we haven't even sent a reset -// yet. -// -//****************************************************************************** -static int -iiSetAddress( i2eBordStrPtr pB, int address, delayFunc_t delay ) -{ - // Should any failure occur before init is finished... - pB->i2eValid = I2E_INCOMPLETE; - - // Cannot check upper limit except extremely: Might be microchannel - // Address must be on an 8-byte boundary - - if ((unsigned int)address <= 0x100 - || (unsigned int)address >= 0xfff8 - || (address & 0x7) - ) - { - I2_COMPLETE(pB, I2EE_BADADDR); - } - - // Initialize accelerators - pB->i2eBase = address; - pB->i2eData = address + FIFO_DATA; - pB->i2eStatus = address + FIFO_STATUS; - pB->i2ePointer = address + FIFO_PTR; - pB->i2eXMail = address + FIFO_MAIL; - pB->i2eXMask = address + FIFO_MASK; - - // Initialize i/o address for ii2DelayIO - ii2Safe = address + FIFO_NOP; - - // Initialize the delay routine - pB->i2eDelay = ((delay != (delayFunc_t)NULL) ? delay : (delayFunc_t)ii2Nop); - - pB->i2eValid = I2E_MAGIC; - pB->i2eState = II_STATE_COLD; - - I2_COMPLETE(pB, I2EE_GOOD); -} - -//****************************************************************************** -// Function: iiReset(pB) -// Parameters: pB - pointer to the board structure -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Attempts to reset the board (see also i2hw.h). Normally, we would use this to -// reset a board immediately after iiSetAddress(), but it is valid to reset a -// board from any state, say, in order to change or re-load loadware. (Under -// such circumstances, no reason to re-run iiSetAddress(), which is why it is a -// separate routine and not included in this routine. -// -//****************************************************************************** -static int -iiReset(i2eBordStrPtr pB) -{ - // Magic number should be set, else even the address is suspect - if (pB->i2eValid != I2E_MAGIC) - { - I2_COMPLETE(pB, I2EE_BADMAGIC); - } - - outb(0, pB->i2eBase + FIFO_RESET); /* Any data will do */ - iiDelay(pB, 50); // Pause between resets - outb(0, pB->i2eBase + FIFO_RESET); /* Second reset */ - - // We must wait before even attempting to read anything from the FIFO: the - // board's P.O.S.T may actually attempt to read and write its end of the - // FIFO in order to check flags, loop back (where supported), etc. On - // completion of this testing it would reset the FIFO, and on completion - // of all // P.O.S.T., write the message. We must not mistake data which - // might have been sent for testing as part of the reset message. To - // better utilize time, say, when resetting several boards, we allow the - // delay to be performed externally; in this way the caller can reset - // several boards, delay a single time, then call the initialization - // routine for all. - - pB->i2eState = II_STATE_RESET; - - iiDelayed = 0; // i.e., the delay routine hasn't been called since the most - // recent reset. - - // Ensure anything which would have been of use to standard loadware is - // blanked out, since board has now forgotten everything!. - - pB->i2eUsingIrq = I2_IRQ_UNDEFINED; /* to not use an interrupt so far */ - pB->i2eWaitingForEmptyFifo = 0; - pB->i2eOutMailWaiting = 0; - pB->i2eChannelPtr = NULL; - pB->i2eChannelCnt = 0; - - pB->i2eLeadoffWord[0] = 0; - pB->i2eFifoInInts = 0; - pB->i2eFifoOutInts = 0; - pB->i2eFatalTrap = NULL; - pB->i2eFatal = 0; - - I2_COMPLETE(pB, I2EE_GOOD); -} - -//****************************************************************************** -// Function: iiResetDelay(pB) -// Parameters: pB - pointer to the board structure -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Using the delay defined in board structure, waits two seconds (for board to -// reset). -// -//****************************************************************************** -static int -iiResetDelay(i2eBordStrPtr pB) -{ - if (pB->i2eValid != I2E_MAGIC) { - I2_COMPLETE(pB, I2EE_BADMAGIC); - } - if (pB->i2eState != II_STATE_RESET) { - I2_COMPLETE(pB, I2EE_BADSTATE); - } - iiDelay(pB,2000); /* Now we wait for two seconds. */ - iiDelayed = 1; /* Delay has been called: ok to initialize */ - I2_COMPLETE(pB, I2EE_GOOD); -} - -//****************************************************************************** -// Function: iiInitialize(pB) -// Parameters: pB - pointer to the board structure -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Attempts to read the Power-on reset message. Initializes any remaining fields -// in the pB structure. -// -// This should be called as the third step of a process beginning with -// iiReset(), then iiResetDelay(). This routine checks to see that the structure -// is "valid" and in the reset state, also confirms that the delay routine has -// been called since the latest reset (to any board! overly strong!). -// -//****************************************************************************** -static int -iiInitialize(i2eBordStrPtr pB) -{ - int itemp; - unsigned char c; - unsigned short utemp; - unsigned int ilimit; - - if (pB->i2eValid != I2E_MAGIC) - { - I2_COMPLETE(pB, I2EE_BADMAGIC); - } - - if (pB->i2eState != II_STATE_RESET || !iiDelayed) - { - I2_COMPLETE(pB, I2EE_BADSTATE); - } - - // In case there is a failure short of our completely reading the power-up - // message. - pB->i2eValid = I2E_INCOMPLETE; - - - // Now attempt to read the message. - - for (itemp = 0; itemp < sizeof(porStr); itemp++) - { - // We expect the entire message is ready. - if (!I2_HAS_INPUT(pB)) { - pB->i2ePomSize = itemp; - I2_COMPLETE(pB, I2EE_PORM_SHORT); - } - - pB->i2ePom.c[itemp] = c = inb(pB->i2eData); - - // We check the magic numbers as soon as they are supposed to be read - // (rather than after) to minimize effect of reading something we - // already suspect can't be "us". - if ( (itemp == POR_1_INDEX && c != POR_MAGIC_1) || - (itemp == POR_2_INDEX && c != POR_MAGIC_2)) - { - pB->i2ePomSize = itemp+1; - I2_COMPLETE(pB, I2EE_BADMAGIC); - } - } - - pB->i2ePomSize = itemp; - - // Ensure that this was all the data... - if (I2_HAS_INPUT(pB)) - I2_COMPLETE(pB, I2EE_PORM_LONG); - - // For now, we'll fail to initialize if P.O.S.T reports bad chip mapper: - // Implying we will not be able to download any code either: That's ok: the - // condition is pretty explicit. - if (pB->i2ePom.e.porDiag1 & POR_BAD_MAPPER) - { - I2_COMPLETE(pB, I2EE_POSTERR); - } - - // Determine anything which must be done differently depending on the family - // of boards! - switch (pB->i2ePom.e.porID & POR_ID_FAMILY) - { - case POR_ID_FII: // IntelliPort-II - - pB->i2eFifoStyle = FIFO_II; - pB->i2eFifoSize = 512; // 512 bytes, always - pB->i2eDataWidth16 = false; - - pB->i2eMaxIrq = 15; // Because board cannot tell us it is in an 8-bit - // slot, we do allow it to be done (documentation!) - - pB->i2eGoodMap[1] = - pB->i2eGoodMap[2] = - pB->i2eGoodMap[3] = - pB->i2eChannelMap[1] = - pB->i2eChannelMap[2] = - pB->i2eChannelMap[3] = 0; - - switch (pB->i2ePom.e.porID & POR_ID_SIZE) - { - case POR_ID_II_4: - pB->i2eGoodMap[0] = - pB->i2eChannelMap[0] = 0x0f; // four-port - - // Since porPorts1 is based on the Hardware ID register, the numbers - // should always be consistent for IntelliPort-II. Ditto below... - if (pB->i2ePom.e.porPorts1 != 4) - { - I2_COMPLETE(pB, I2EE_INCONSIST); - } - break; - - case POR_ID_II_8: - case POR_ID_II_8R: - pB->i2eGoodMap[0] = - pB->i2eChannelMap[0] = 0xff; // Eight port - if (pB->i2ePom.e.porPorts1 != 8) - { - I2_COMPLETE(pB, I2EE_INCONSIST); - } - break; - - case POR_ID_II_6: - pB->i2eGoodMap[0] = - pB->i2eChannelMap[0] = 0x3f; // Six Port - if (pB->i2ePom.e.porPorts1 != 6) - { - I2_COMPLETE(pB, I2EE_INCONSIST); - } - break; - } - - // Fix up the "good channel list based on any errors reported. - if (pB->i2ePom.e.porDiag1 & POR_BAD_UART1) - { - pB->i2eGoodMap[0] &= ~0x0f; - } - - if (pB->i2ePom.e.porDiag1 & POR_BAD_UART2) - { - pB->i2eGoodMap[0] &= ~0xf0; - } - - break; // POR_ID_FII case - - case POR_ID_FIIEX: // IntelliPort-IIEX - - pB->i2eFifoStyle = FIFO_IIEX; - - itemp = pB->i2ePom.e.porFifoSize; - - // Implicit assumption that fifo would not grow beyond 32k, - // nor would ever be less than 256. - - if (itemp < 8 || itemp > 15) - { - I2_COMPLETE(pB, I2EE_INCONSIST); - } - pB->i2eFifoSize = (1 << itemp); - - // These are based on what P.O.S.T thinks should be there, based on - // box ID registers - ilimit = pB->i2ePom.e.porNumBoxes; - if (ilimit > ABS_MAX_BOXES) - { - ilimit = ABS_MAX_BOXES; - } - - // For as many boxes as EXIST, gives the type of box. - // Added 8/6/93: check for the ISA-4 (asic) which looks like an - // expandable but for whom "8 or 16?" is not the right question. - - utemp = pB->i2ePom.e.porFlags; - if (utemp & POR_CEX4) - { - pB->i2eChannelMap[0] = 0x000f; - } else { - utemp &= POR_BOXES; - for (itemp = 0; itemp < ilimit; itemp++) - { - pB->i2eChannelMap[itemp] = - ((utemp & POR_BOX_16) ? 0xffff : 0x00ff); - utemp >>= 1; - } - } - - // These are based on what P.O.S.T actually found. - - utemp = (pB->i2ePom.e.porPorts2 << 8) + pB->i2ePom.e.porPorts1; - - for (itemp = 0; itemp < ilimit; itemp++) - { - pB->i2eGoodMap[itemp] = 0; - if (utemp & 1) pB->i2eGoodMap[itemp] |= 0x000f; - if (utemp & 2) pB->i2eGoodMap[itemp] |= 0x00f0; - if (utemp & 4) pB->i2eGoodMap[itemp] |= 0x0f00; - if (utemp & 8) pB->i2eGoodMap[itemp] |= 0xf000; - utemp >>= 4; - } - - // Now determine whether we should transfer in 8 or 16-bit mode. - switch (pB->i2ePom.e.porBus & (POR_BUS_SLOT16 | POR_BUS_DIP16) ) - { - case POR_BUS_SLOT16 | POR_BUS_DIP16: - pB->i2eDataWidth16 = true; - pB->i2eMaxIrq = 15; - break; - - case POR_BUS_SLOT16: - pB->i2eDataWidth16 = false; - pB->i2eMaxIrq = 15; - break; - - case 0: - case POR_BUS_DIP16: // In an 8-bit slot, DIP switch don't care. - default: - pB->i2eDataWidth16 = false; - pB->i2eMaxIrq = 7; - break; - } - break; // POR_ID_FIIEX case - - default: // Unknown type of board - I2_COMPLETE(pB, I2EE_BAD_FAMILY); - break; - } // End the switch based on family - - // Temporarily, claim there is no room in the outbound fifo. - // We will maintain this whenever we check for an empty outbound FIFO. - pB->i2eFifoRemains = 0; - - // Now, based on the bus type, should we expect to be able to re-configure - // interrupts (say, for testing purposes). - switch (pB->i2ePom.e.porBus & POR_BUS_TYPE) - { - case POR_BUS_T_ISA: - case POR_BUS_T_UNK: // If the type of bus is undeclared, assume ok. - case POR_BUS_T_MCA: - case POR_BUS_T_EISA: - break; - default: - I2_COMPLETE(pB, I2EE_BADBUS); - } - - if (pB->i2eDataWidth16) - { - pB->i2eWriteBuf = iiWriteBuf16; - pB->i2eReadBuf = iiReadBuf16; - pB->i2eWriteWord = iiWriteWord16; - pB->i2eReadWord = iiReadWord16; - } else { - pB->i2eWriteBuf = iiWriteBuf8; - pB->i2eReadBuf = iiReadBuf8; - pB->i2eWriteWord = iiWriteWord8; - pB->i2eReadWord = iiReadWord8; - } - - switch(pB->i2eFifoStyle) - { - case FIFO_II: - pB->i2eWaitForTxEmpty = iiWaitForTxEmptyII; - pB->i2eTxMailEmpty = iiTxMailEmptyII; - pB->i2eTrySendMail = iiTrySendMailII; - pB->i2eGetMail = iiGetMailII; - pB->i2eEnableMailIrq = iiEnableMailIrqII; - pB->i2eWriteMask = iiWriteMaskII; - - break; - - case FIFO_IIEX: - pB->i2eWaitForTxEmpty = iiWaitForTxEmptyIIEX; - pB->i2eTxMailEmpty = iiTxMailEmptyIIEX; - pB->i2eTrySendMail = iiTrySendMailIIEX; - pB->i2eGetMail = iiGetMailIIEX; - pB->i2eEnableMailIrq = iiEnableMailIrqIIEX; - pB->i2eWriteMask = iiWriteMaskIIEX; - - break; - - default: - I2_COMPLETE(pB, I2EE_INCONSIST); - } - - // Initialize state information. - pB->i2eState = II_STATE_READY; // Ready to load loadware. - - // Some Final cleanup: - // For some boards, the bootstrap firmware may perform some sort of test - // resulting in a stray character pending in the incoming mailbox. If one is - // there, it should be read and discarded, especially since for the standard - // firmware, it's the mailbox that interrupts the host. - - pB->i2eStartMail = iiGetMail(pB); - - // Throw it away and clear the mailbox structure element - pB->i2eStartMail = NO_MAIL_HERE; - - // Everything is ok now, return with good status/ - - pB->i2eValid = I2E_MAGIC; - I2_COMPLETE(pB, I2EE_GOOD); -} - -//****************************************************************************** -// Function: ii2DelayTimer(mseconds) -// Parameters: mseconds - number of milliseconds to delay -// -// Returns: Nothing -// -// Description: -// -// This routine delays for approximately mseconds milliseconds and is intended -// to be called indirectly through i2Delay field in i2eBordStr. It uses the -// Linux timer_list mechanism. -// -// The Linux timers use a unit called "jiffies" which are 10mS in the Intel -// architecture. This function rounds the delay period up to the next "jiffy". -// In the Alpha architecture the "jiffy" is 1mS, but this driver is not intended -// for Alpha platforms at this time. -// -//****************************************************************************** -static void -ii2DelayTimer(unsigned int mseconds) -{ - msleep_interruptible(mseconds); -} - -#if 0 -//static void ii2DelayIO(unsigned int); -//****************************************************************************** -// !!! Not Used, this is DOS crap, some of you young folks may be interested in -// in how things were done in the stone age of caculating machines !!! -// Function: ii2DelayIO(mseconds) -// Parameters: mseconds - number of milliseconds to delay -// -// Returns: Nothing -// -// Description: -// -// This routine delays for approximately mseconds milliseconds and is intended -// to be called indirectly through i2Delay field in i2eBordStr. It is intended -// for use where a clock-based function is impossible: for example, DOS drivers. -// -// This function uses the IN instruction to place bounds on the timing and -// assumes that ii2Safe has been set. This is because I/O instructions are not -// subject to caching and will therefore take a certain minimum time. To ensure -// the delay is at least long enough on fast machines, it is based on some -// fastest-case calculations. On slower machines this may cause VERY long -// delays. (3 x fastest case). In the fastest case, everything is cached except -// the I/O instruction itself. -// -// Timing calculations: -// The fastest bus speed for I/O operations is likely to be 10 MHz. The I/O -// operation in question is a byte operation to an odd address. For 8-bit -// operations, the architecture generally enforces two wait states. At 10 MHz, a -// single cycle time is 100nS. A read operation at two wait states takes 6 -// cycles for a total time of 600nS. Therefore approximately 1666 iterations -// would be required to generate a single millisecond delay. The worst -// (reasonable) case would be an 8MHz system with no cacheing. In this case, the -// I/O instruction would take 125nS x 6 cyles = 750 nS. More importantly, code -// fetch of other instructions in the loop would take time (zero wait states, -// however) and would be hard to estimate. This is minimized by using in-line -// assembler for the in inner loop of IN instructions. This consists of just a -// few bytes. So we'll guess about four code fetches per loop. Each code fetch -// should take four cycles, so we have 125nS * 8 = 1000nS. Worst case then is -// that what should have taken 1 mS takes instead 1666 * (1750) = 2.9 mS. -// -// So much for theoretical timings: results using 1666 value on some actual -// machines: -// IBM 286 6MHz 3.15 mS -// Zenith 386 33MHz 2.45 mS -// (brandX) 386 33MHz 1.90 mS (has cache) -// (brandY) 486 33MHz 2.35 mS -// NCR 486 ?? 1.65 mS (microchannel) -// -// For most machines, it is probably safe to scale this number back (remember, -// for robust operation use an actual timed delay if possible), so we are using -// a value of 1190. This yields 1.17 mS for the fastest machine in our sample, -// 1.75 mS for typical 386 machines, and 2.25 mS the absolute slowest machine. -// -// 1/29/93: -// The above timings are too slow. Actual cycle times might be faster. ISA cycle -// times could approach 500 nS, and ... -// The IBM model 77 being microchannel has no wait states for 8-bit reads and -// seems to be accessing the I/O at 440 nS per access (from start of one to -// start of next). This would imply we need 1000/.440 = 2272 iterations to -// guarantee we are fast enough. In actual testing, we see that 2 * 1190 are in -// fact enough. For diagnostics, we keep the level at 1190, but developers note -// this needs tuning. -// -// Safe assumption: 2270 i/o reads = 1 millisecond -// -//****************************************************************************** - - -static int ii2DelValue = 1190; // See timing calculations below - // 1666 for fastest theoretical machine - // 1190 safe for most fast 386 machines - // 1000 for fastest machine tested here - // 540 (sic) for AT286/6Mhz -static void -ii2DelayIO(unsigned int mseconds) -{ - if (!ii2Safe) - return; /* Do nothing if this variable uninitialized */ - - while(mseconds--) { - int i = ii2DelValue; - while ( i-- ) { - inb(ii2Safe); - } - } -} -#endif - -//****************************************************************************** -// Function: ii2Nop() -// Parameters: None -// -// Returns: Nothing -// -// Description: -// -// iiInitialize will set i2eDelay to this if the delay parameter is NULL. This -// saves checking for a NULL pointer at every call. -//****************************************************************************** -static void -ii2Nop(void) -{ - return; // no mystery here -} - -//======================================================= -// Routines which are available in 8/16-bit versions, or -// in different fifo styles. These are ALL called -// indirectly through the board structure. -//======================================================= - -//****************************************************************************** -// Function: iiWriteBuf16(pB, address, count) -// Parameters: pB - pointer to board structure -// address - address of data to write -// count - number of data bytes to write -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Writes 'count' bytes from 'address' to the data fifo specified by the board -// structure pointer pB. Should count happen to be odd, an extra pad byte is -// sent (identity unknown...). Uses 16-bit (word) operations. Is called -// indirectly through pB->i2eWriteBuf. -// -//****************************************************************************** -static int -iiWriteBuf16(i2eBordStrPtr pB, unsigned char *address, int count) -{ - // Rudimentary sanity checking here. - if (pB->i2eValid != I2E_MAGIC) - I2_COMPLETE(pB, I2EE_INVALID); - - I2_OUTSW(pB->i2eData, address, count); - - I2_COMPLETE(pB, I2EE_GOOD); -} - -//****************************************************************************** -// Function: iiWriteBuf8(pB, address, count) -// Parameters: pB - pointer to board structure -// address - address of data to write -// count - number of data bytes to write -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Writes 'count' bytes from 'address' to the data fifo specified by the board -// structure pointer pB. Should count happen to be odd, an extra pad byte is -// sent (identity unknown...). This is to be consistent with the 16-bit version. -// Uses 8-bit (byte) operations. Is called indirectly through pB->i2eWriteBuf. -// -//****************************************************************************** -static int -iiWriteBuf8(i2eBordStrPtr pB, unsigned char *address, int count) -{ - /* Rudimentary sanity checking here */ - if (pB->i2eValid != I2E_MAGIC) - I2_COMPLETE(pB, I2EE_INVALID); - - I2_OUTSB(pB->i2eData, address, count); - - I2_COMPLETE(pB, I2EE_GOOD); -} - -//****************************************************************************** -// Function: iiReadBuf16(pB, address, count) -// Parameters: pB - pointer to board structure -// address - address to put data read -// count - number of data bytes to read -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Reads 'count' bytes into 'address' from the data fifo specified by the board -// structure pointer pB. Should count happen to be odd, an extra pad byte is -// received (identity unknown...). Uses 16-bit (word) operations. Is called -// indirectly through pB->i2eReadBuf. -// -//****************************************************************************** -static int -iiReadBuf16(i2eBordStrPtr pB, unsigned char *address, int count) -{ - // Rudimentary sanity checking here. - if (pB->i2eValid != I2E_MAGIC) - I2_COMPLETE(pB, I2EE_INVALID); - - I2_INSW(pB->i2eData, address, count); - - I2_COMPLETE(pB, I2EE_GOOD); -} - -//****************************************************************************** -// Function: iiReadBuf8(pB, address, count) -// Parameters: pB - pointer to board structure -// address - address to put data read -// count - number of data bytes to read -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Reads 'count' bytes into 'address' from the data fifo specified by the board -// structure pointer pB. Should count happen to be odd, an extra pad byte is -// received (identity unknown...). This to match the 16-bit behaviour. Uses -// 8-bit (byte) operations. Is called indirectly through pB->i2eReadBuf. -// -//****************************************************************************** -static int -iiReadBuf8(i2eBordStrPtr pB, unsigned char *address, int count) -{ - // Rudimentary sanity checking here. - if (pB->i2eValid != I2E_MAGIC) - I2_COMPLETE(pB, I2EE_INVALID); - - I2_INSB(pB->i2eData, address, count); - - I2_COMPLETE(pB, I2EE_GOOD); -} - -//****************************************************************************** -// Function: iiReadWord16(pB) -// Parameters: pB - pointer to board structure -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Returns the word read from the data fifo specified by the board-structure -// pointer pB. Uses a 16-bit operation. Is called indirectly through -// pB->i2eReadWord. -// -//****************************************************************************** -static unsigned short -iiReadWord16(i2eBordStrPtr pB) -{ - return inw(pB->i2eData); -} - -//****************************************************************************** -// Function: iiReadWord8(pB) -// Parameters: pB - pointer to board structure -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Returns the word read from the data fifo specified by the board-structure -// pointer pB. Uses two 8-bit operations. Bytes are assumed to be LSB first. Is -// called indirectly through pB->i2eReadWord. -// -//****************************************************************************** -static unsigned short -iiReadWord8(i2eBordStrPtr pB) -{ - unsigned short urs; - - urs = inb(pB->i2eData); - - return (inb(pB->i2eData) << 8) | urs; -} - -//****************************************************************************** -// Function: iiWriteWord16(pB, value) -// Parameters: pB - pointer to board structure -// value - data to write -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Writes the word 'value' to the data fifo specified by the board-structure -// pointer pB. Uses 16-bit operation. Is called indirectly through -// pB->i2eWriteWord. -// -//****************************************************************************** -static void -iiWriteWord16(i2eBordStrPtr pB, unsigned short value) -{ - outw((int)value, pB->i2eData); -} - -//****************************************************************************** -// Function: iiWriteWord8(pB, value) -// Parameters: pB - pointer to board structure -// value - data to write -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Writes the word 'value' to the data fifo specified by the board-structure -// pointer pB. Uses two 8-bit operations (writes LSB first). Is called -// indirectly through pB->i2eWriteWord. -// -//****************************************************************************** -static void -iiWriteWord8(i2eBordStrPtr pB, unsigned short value) -{ - outb((char)value, pB->i2eData); - outb((char)(value >> 8), pB->i2eData); -} - -//****************************************************************************** -// Function: iiWaitForTxEmptyII(pB, mSdelay) -// Parameters: pB - pointer to board structure -// mSdelay - period to wait before returning -// -// Returns: True if the FIFO is empty. -// False if it not empty in the required time: the pB->i2eError -// field has the error. -// -// Description: -// -// Waits up to "mSdelay" milliseconds for the outgoing FIFO to become empty; if -// not empty by the required time, returns false and error in pB->i2eError, -// otherwise returns true. -// -// mSdelay == 0 is taken to mean must be empty on the first test. -// -// This version operates on IntelliPort-II - style FIFO's -// -// Note this routine is organized so that if status is ok there is no delay at -// all called either before or after the test. Is called indirectly through -// pB->i2eWaitForTxEmpty. -// -//****************************************************************************** -static int -iiWaitForTxEmptyII(i2eBordStrPtr pB, int mSdelay) -{ - unsigned long flags; - int itemp; - - for (;;) - { - // This routine hinges on being able to see the "other" status register - // (as seen by the local processor). His incoming fifo is our outgoing - // FIFO. - // - // By the nature of this routine, you would be using this as part of a - // larger atomic context: i.e., you would use this routine to ensure the - // fifo empty, then act on this information. Between these two halves, - // you will generally not want to service interrupts or in any way - // disrupt the assumptions implicit in the larger context. - // - // Even worse, however, this routine "shifts" the status register to - // point to the local status register which is not the usual situation. - // Therefore for extra safety, we force the critical section to be - // completely atomic, and pick up after ourselves before allowing any - // interrupts of any kind. - - - write_lock_irqsave(&Dl_spinlock, flags); - outb(SEL_COMMAND, pB->i2ePointer); - outb(SEL_CMD_SH, pB->i2ePointer); - - itemp = inb(pB->i2eStatus); - - outb(SEL_COMMAND, pB->i2ePointer); - outb(SEL_CMD_UNSH, pB->i2ePointer); - - if (itemp & ST_IN_EMPTY) - { - I2_UPDATE_FIFO_ROOM(pB); - write_unlock_irqrestore(&Dl_spinlock, flags); - I2_COMPLETE(pB, I2EE_GOOD); - } - - write_unlock_irqrestore(&Dl_spinlock, flags); - - if (mSdelay-- == 0) - break; - - iiDelay(pB, 1); /* 1 mS granularity on checking condition */ - } - I2_COMPLETE(pB, I2EE_TXE_TIME); -} - -//****************************************************************************** -// Function: iiWaitForTxEmptyIIEX(pB, mSdelay) -// Parameters: pB - pointer to board structure -// mSdelay - period to wait before returning -// -// Returns: True if the FIFO is empty. -// False if it not empty in the required time: the pB->i2eError -// field has the error. -// -// Description: -// -// Waits up to "mSdelay" milliseconds for the outgoing FIFO to become empty; if -// not empty by the required time, returns false and error in pB->i2eError, -// otherwise returns true. -// -// mSdelay == 0 is taken to mean must be empty on the first test. -// -// This version operates on IntelliPort-IIEX - style FIFO's -// -// Note this routine is organized so that if status is ok there is no delay at -// all called either before or after the test. Is called indirectly through -// pB->i2eWaitForTxEmpty. -// -//****************************************************************************** -static int -iiWaitForTxEmptyIIEX(i2eBordStrPtr pB, int mSdelay) -{ - unsigned long flags; - - for (;;) - { - // By the nature of this routine, you would be using this as part of a - // larger atomic context: i.e., you would use this routine to ensure the - // fifo empty, then act on this information. Between these two halves, - // you will generally not want to service interrupts or in any way - // disrupt the assumptions implicit in the larger context. - - write_lock_irqsave(&Dl_spinlock, flags); - - if (inb(pB->i2eStatus) & STE_OUT_MT) { - I2_UPDATE_FIFO_ROOM(pB); - write_unlock_irqrestore(&Dl_spinlock, flags); - I2_COMPLETE(pB, I2EE_GOOD); - } - write_unlock_irqrestore(&Dl_spinlock, flags); - - if (mSdelay-- == 0) - break; - - iiDelay(pB, 1); // 1 mS granularity on checking condition - } - I2_COMPLETE(pB, I2EE_TXE_TIME); -} - -//****************************************************************************** -// Function: iiTxMailEmptyII(pB) -// Parameters: pB - pointer to board structure -// -// Returns: True if the transmit mailbox is empty. -// False if it not empty. -// -// Description: -// -// Returns true or false according to whether the transmit mailbox is empty (and -// therefore able to accept more mail) -// -// This version operates on IntelliPort-II - style FIFO's -// -//****************************************************************************** -static int -iiTxMailEmptyII(i2eBordStrPtr pB) -{ - int port = pB->i2ePointer; - outb(SEL_OUTMAIL, port); - return inb(port) == 0; -} - -//****************************************************************************** -// Function: iiTxMailEmptyIIEX(pB) -// Parameters: pB - pointer to board structure -// -// Returns: True if the transmit mailbox is empty. -// False if it not empty. -// -// Description: -// -// Returns true or false according to whether the transmit mailbox is empty (and -// therefore able to accept more mail) -// -// This version operates on IntelliPort-IIEX - style FIFO's -// -//****************************************************************************** -static int -iiTxMailEmptyIIEX(i2eBordStrPtr pB) -{ - return !(inb(pB->i2eStatus) & STE_OUT_MAIL); -} - -//****************************************************************************** -// Function: iiTrySendMailII(pB,mail) -// Parameters: pB - pointer to board structure -// mail - value to write to mailbox -// -// Returns: True if the transmit mailbox is empty, and mail is sent. -// False if it not empty. -// -// Description: -// -// If outgoing mailbox is empty, sends mail and returns true. If outgoing -// mailbox is not empty, returns false. -// -// This version operates on IntelliPort-II - style FIFO's -// -//****************************************************************************** -static int -iiTrySendMailII(i2eBordStrPtr pB, unsigned char mail) -{ - int port = pB->i2ePointer; - - outb(SEL_OUTMAIL, port); - if (inb(port) == 0) { - outb(SEL_OUTMAIL, port); - outb(mail, port); - return 1; - } - return 0; -} - -//****************************************************************************** -// Function: iiTrySendMailIIEX(pB,mail) -// Parameters: pB - pointer to board structure -// mail - value to write to mailbox -// -// Returns: True if the transmit mailbox is empty, and mail is sent. -// False if it not empty. -// -// Description: -// -// If outgoing mailbox is empty, sends mail and returns true. If outgoing -// mailbox is not empty, returns false. -// -// This version operates on IntelliPort-IIEX - style FIFO's -// -//****************************************************************************** -static int -iiTrySendMailIIEX(i2eBordStrPtr pB, unsigned char mail) -{ - if (inb(pB->i2eStatus) & STE_OUT_MAIL) - return 0; - outb(mail, pB->i2eXMail); - return 1; -} - -//****************************************************************************** -// Function: iiGetMailII(pB,mail) -// Parameters: pB - pointer to board structure -// -// Returns: Mailbox data or NO_MAIL_HERE. -// -// Description: -// -// If no mail available, returns NO_MAIL_HERE otherwise returns the data from -// the mailbox, which is guaranteed != NO_MAIL_HERE. -// -// This version operates on IntelliPort-II - style FIFO's -// -//****************************************************************************** -static unsigned short -iiGetMailII(i2eBordStrPtr pB) -{ - if (I2_HAS_MAIL(pB)) { - outb(SEL_INMAIL, pB->i2ePointer); - return inb(pB->i2ePointer); - } else { - return NO_MAIL_HERE; - } -} - -//****************************************************************************** -// Function: iiGetMailIIEX(pB,mail) -// Parameters: pB - pointer to board structure -// -// Returns: Mailbox data or NO_MAIL_HERE. -// -// Description: -// -// If no mail available, returns NO_MAIL_HERE otherwise returns the data from -// the mailbox, which is guaranteed != NO_MAIL_HERE. -// -// This version operates on IntelliPort-IIEX - style FIFO's -// -//****************************************************************************** -static unsigned short -iiGetMailIIEX(i2eBordStrPtr pB) -{ - if (I2_HAS_MAIL(pB)) - return inb(pB->i2eXMail); - else - return NO_MAIL_HERE; -} - -//****************************************************************************** -// Function: iiEnableMailIrqII(pB) -// Parameters: pB - pointer to board structure -// -// Returns: Nothing -// -// Description: -// -// Enables board to interrupt host (only) by writing to host's in-bound mailbox. -// -// This version operates on IntelliPort-II - style FIFO's -// -//****************************************************************************** -static void -iiEnableMailIrqII(i2eBordStrPtr pB) -{ - outb(SEL_MASK, pB->i2ePointer); - outb(ST_IN_MAIL, pB->i2ePointer); -} - -//****************************************************************************** -// Function: iiEnableMailIrqIIEX(pB) -// Parameters: pB - pointer to board structure -// -// Returns: Nothing -// -// Description: -// -// Enables board to interrupt host (only) by writing to host's in-bound mailbox. -// -// This version operates on IntelliPort-IIEX - style FIFO's -// -//****************************************************************************** -static void -iiEnableMailIrqIIEX(i2eBordStrPtr pB) -{ - outb(MX_IN_MAIL, pB->i2eXMask); -} - -//****************************************************************************** -// Function: iiWriteMaskII(pB) -// Parameters: pB - pointer to board structure -// -// Returns: Nothing -// -// Description: -// -// Writes arbitrary value to the mask register. -// -// This version operates on IntelliPort-II - style FIFO's -// -//****************************************************************************** -static void -iiWriteMaskII(i2eBordStrPtr pB, unsigned char value) -{ - outb(SEL_MASK, pB->i2ePointer); - outb(value, pB->i2ePointer); -} - -//****************************************************************************** -// Function: iiWriteMaskIIEX(pB) -// Parameters: pB - pointer to board structure -// -// Returns: Nothing -// -// Description: -// -// Writes arbitrary value to the mask register. -// -// This version operates on IntelliPort-IIEX - style FIFO's -// -//****************************************************************************** -static void -iiWriteMaskIIEX(i2eBordStrPtr pB, unsigned char value) -{ - outb(value, pB->i2eXMask); -} - -//****************************************************************************** -// Function: iiDownloadBlock(pB, pSource, isStandard) -// Parameters: pB - pointer to board structure -// pSource - loadware block to download -// isStandard - True if "standard" loadware, else false. -// -// Returns: Success or Failure -// -// Description: -// -// Downloads a single block (at pSource)to the board referenced by pB. Caller -// sets isStandard to true/false according to whether the "standard" loadware is -// what's being loaded. The normal process, then, is to perform an iiInitialize -// to the board, then perform some number of iiDownloadBlocks using the returned -// state to determine when download is complete. -// -// Possible return values: (see I2ELLIS.H) -// II_DOWN_BADVALID -// II_DOWN_BADFILE -// II_DOWN_CONTINUING -// II_DOWN_GOOD -// II_DOWN_BAD -// II_DOWN_BADSTATE -// II_DOWN_TIMEOUT -// -// Uses the i2eState and i2eToLoad fields (initialized at iiInitialize) to -// determine whether this is the first block, whether to check for magic -// numbers, how many blocks there are to go... -// -//****************************************************************************** -static int -iiDownloadBlock ( i2eBordStrPtr pB, loadHdrStrPtr pSource, int isStandard) -{ - int itemp; - int loadedFirst; - - if (pB->i2eValid != I2E_MAGIC) return II_DOWN_BADVALID; - - switch(pB->i2eState) - { - case II_STATE_READY: - - // Loading the first block after reset. Must check the magic number of the - // loadfile, store the number of blocks we expect to load. - if (pSource->e.loadMagic != MAGIC_LOADFILE) - { - return II_DOWN_BADFILE; - } - - // Next we store the total number of blocks to load, including this one. - pB->i2eToLoad = 1 + pSource->e.loadBlocksMore; - - // Set the state, store the version numbers. ('Cause this may have come - // from a file - we might want to report these versions and revisions in - // case of an error! - pB->i2eState = II_STATE_LOADING; - pB->i2eLVersion = pSource->e.loadVersion; - pB->i2eLRevision = pSource->e.loadRevision; - pB->i2eLSub = pSource->e.loadSubRevision; - - // The time and date of compilation is also available but don't bother - // storing it for normal purposes. - loadedFirst = 1; - break; - - case II_STATE_LOADING: - loadedFirst = 0; - break; - - default: - return II_DOWN_BADSTATE; - } - - // Now we must be in the II_STATE_LOADING state, and we assume i2eToLoad - // must be positive still, because otherwise we would have cleaned up last - // time and set the state to II_STATE_LOADED. - if (!iiWaitForTxEmpty(pB, MAX_DLOAD_READ_TIME)) { - return II_DOWN_TIMEOUT; - } - - if (!iiWriteBuf(pB, pSource->c, LOADWARE_BLOCK_SIZE)) { - return II_DOWN_BADVALID; - } - - // If we just loaded the first block, wait for the fifo to empty an extra - // long time to allow for any special startup code in the firmware, like - // sending status messages to the LCD's. - - if (loadedFirst) { - if (!iiWaitForTxEmpty(pB, MAX_DLOAD_START_TIME)) { - return II_DOWN_TIMEOUT; - } - } - - // Determine whether this was our last block! - if (--(pB->i2eToLoad)) { - return II_DOWN_CONTINUING; // more to come... - } - - // It WAS our last block: Clean up operations... - // ...Wait for last buffer to drain from the board... - if (!iiWaitForTxEmpty(pB, MAX_DLOAD_READ_TIME)) { - return II_DOWN_TIMEOUT; - } - // If there were only a single block written, this would come back - // immediately and be harmless, though not strictly necessary. - itemp = MAX_DLOAD_ACK_TIME/10; - while (--itemp) { - if (I2_HAS_INPUT(pB)) { - switch (inb(pB->i2eData)) { - case LOADWARE_OK: - pB->i2eState = - isStandard ? II_STATE_STDLOADED :II_STATE_LOADED; - - // Some revisions of the bootstrap firmware (e.g. ISA-8 1.0.2) - // will, // if there is a debug port attached, require some - // time to send information to the debug port now. It will do - // this before // executing any of the code we just downloaded. - // It may take up to 700 milliseconds. - if (pB->i2ePom.e.porDiag2 & POR_DEBUG_PORT) { - iiDelay(pB, 700); - } - - return II_DOWN_GOOD; - - case LOADWARE_BAD: - default: - return II_DOWN_BAD; - } - } - - iiDelay(pB, 10); // 10 mS granularity on checking condition - } - - // Drop-through --> timed out waiting for firmware confirmation - - pB->i2eState = II_STATE_BADLOAD; - return II_DOWN_TIMEOUT; -} - -//****************************************************************************** -// Function: iiDownloadAll(pB, pSource, isStandard, size) -// Parameters: pB - pointer to board structure -// pSource - loadware block to download -// isStandard - True if "standard" loadware, else false. -// size - size of data to download (in bytes) -// -// Returns: Success or Failure -// -// Description: -// -// Given a pointer to a board structure, a pointer to the beginning of some -// loadware, whether it is considered the "standard loadware", and the size of -// the array in bytes loads the entire array to the board as loadware. -// -// Assumes the board has been freshly reset and the power-up reset message read. -// (i.e., in II_STATE_READY). Complains if state is bad, or if there seems to be -// too much or too little data to load, or if iiDownloadBlock complains. -//****************************************************************************** -static int -iiDownloadAll(i2eBordStrPtr pB, loadHdrStrPtr pSource, int isStandard, int size) -{ - int status; - - // We know (from context) board should be ready for the first block of - // download. Complain if not. - if (pB->i2eState != II_STATE_READY) return II_DOWN_BADSTATE; - - while (size > 0) { - size -= LOADWARE_BLOCK_SIZE; // How much data should there be left to - // load after the following operation ? - - // Note we just bump pSource by "one", because its size is actually that - // of an entire block, same as LOADWARE_BLOCK_SIZE. - status = iiDownloadBlock(pB, pSource++, isStandard); - - switch(status) - { - case II_DOWN_GOOD: - return ( (size > 0) ? II_DOWN_OVER : II_DOWN_GOOD); - - case II_DOWN_CONTINUING: - break; - - default: - return status; - } - } - - // We shouldn't drop out: it means "while" caught us with nothing left to - // download, yet the previous DownloadBlock did not return complete. Ergo, - // not enough data to match the size byte in the header. - return II_DOWN_UNDER; -} diff --git a/drivers/char/ip2/i2ellis.h b/drivers/char/ip2/i2ellis.h deleted file mode 100644 index fb6df2456018..000000000000 --- a/drivers/char/ip2/i2ellis.h +++ /dev/null @@ -1,566 +0,0 @@ -/******************************************************************************* -* -* (c) 1999 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Mainline code for the device driver -* -*******************************************************************************/ -//------------------------------------------------------------------------------ -// i2ellis.h -// -// IntelliPort-II and IntelliPort-IIEX -// -// Extremely -// Low -// Level -// Interface -// Services -// -// Structure Definitions and declarations for "ELLIS" service routines found in -// i2ellis.c -// -// These routines are based on properties of the IntelliPort-II and -IIEX -// hardware and bootstrap firmware, and are not sensitive to particular -// conventions of any particular loadware. -// -// Unlike i2hw.h, which provides IRONCLAD hardware definitions, the material -// here and in i2ellis.c is intended to provice a useful, but not required, -// layer of insulation from the hardware specifics. -//------------------------------------------------------------------------------ -#ifndef I2ELLIS_H /* To prevent multiple includes */ -#define I2ELLIS_H 1 -//------------------------------------------------ -// Revision History: -// -// 30 September 1991 MAG First Draft Started -// 12 October 1991 ...continued... -// -// 20 December 1996 AKM Linux version -//------------------------------------------------- - -//---------------------- -// Mandatory Includes: -//---------------------- -#include "ip2types.h" -#include "i2hw.h" // The hardware definitions - -//------------------------------------------ -// STAT_BOXIDS packets -//------------------------------------------ -#define MAX_BOX 4 - -typedef struct _bidStat -{ - unsigned char bid_value[MAX_BOX]; -} bidStat, *bidStatPtr; - -// This packet is sent in response to a CMD_GET_BOXIDS bypass command. For -IIEX -// boards, reports the hardware-specific "asynchronous resource register" on -// each expansion box. Boxes not present report 0xff. For -II boards, the first -// element contains 0x80 for 8-port, 0x40 for 4-port boards. - -// Box IDs aka ARR or Async Resource Register (more than you want to know) -// 7 6 5 4 3 2 1 0 -// F F N N L S S S -// ============================= -// F F - Product Family Designator -// =====+++++++++++++++++++++++++++++++ -// 0 0 - Intelliport II EX / ISA-8 -// 1 0 - IntelliServer -// 0 1 - SAC - Port Device (Intelliport III ??? ) -// =====+++++++++++++++++++++++++++++++++++++++ -// N N - Number of Ports -// 0 0 - 8 (eight) -// 0 1 - 4 (four) -// 1 0 - 12 (twelve) -// 1 1 - 16 (sixteen) -// =++++++++++++++++++++++++++++++++++ -// L - LCD Display Module Present -// 0 - No -// 1 - LCD module present -// =========+++++++++++++++++++++++++++++++++++++ -// S S S - Async Signals Supported Designator -// 0 0 0 - 8dss, Mod DCE DB25 Female -// 0 0 1 - 6dss, RJ-45 -// 0 1 0 - RS-232/422 dss, DB25 Female -// 0 1 1 - RS-232/422 dss, separate 232/422 DB25 Female -// 1 0 0 - 6dss, 921.6 I/F with ST654's -// 1 0 1 - RS-423/232 8dss, RJ-45 10Pin -// 1 1 0 - 6dss, Mod DCE DB25 Female -// 1 1 1 - NO BOX PRESENT - -#define FF(c) ((c & 0xC0) >> 6) -#define NN(c) ((c & 0x30) >> 4) -#define L(c) ((c & 0x08) >> 3) -#define SSS(c) (c & 0x07) - -#define BID_HAS_654(x) (SSS(x) == 0x04) -#define BID_NO_BOX 0xff /* no box */ -#define BID_8PORT 0x80 /* IP2-8 port */ -#define BID_4PORT 0x81 /* IP2-4 port */ -#define BID_EXP_MASK 0x30 /* IP2-EX */ -#define BID_EXP_8PORT 0x00 /* 8, */ -#define BID_EXP_4PORT 0x10 /* 4, */ -#define BID_EXP_UNDEF 0x20 /* UNDEF, */ -#define BID_EXP_16PORT 0x30 /* 16, */ -#define BID_LCD_CTRL 0x08 /* LCD Controller */ -#define BID_LCD_NONE 0x00 /* - no controller present */ -#define BID_LCD_PRES 0x08 /* - controller present */ -#define BID_CON_MASK 0x07 /* - connector pinouts */ -#define BID_CON_DB25 0x00 /* - DB-25 F */ -#define BID_CON_RJ45 0x01 /* - rj45 */ - -//------------------------------------------------------------------------------ -// i2eBordStr -// -// This structure contains all the information the ELLIS routines require in -// dealing with a particular board. -//------------------------------------------------------------------------------ -// There are some queues here which are guaranteed to never contain the entry -// for a single channel twice. So they must be slightly larger to allow -// unambiguous full/empty management -// -#define CH_QUEUE_SIZE ABS_MOST_PORTS+2 - -typedef struct _i2eBordStr -{ - porStr i2ePom; // Structure containing the power-on message. - - unsigned short i2ePomSize; - // The number of bytes actually read if - // different from sizeof i2ePom, indicates - // there is an error! - - unsigned short i2eStartMail; - // Contains whatever inbound mailbox data - // present at startup. NO_MAIL_HERE indicates - // nothing was present. No special - // significance as of this writing, but may be - // useful for diagnostic reasons. - - unsigned short i2eValid; - // Indicates validity of the structure; if - // i2eValid == I2E_MAGIC, then we can trust - // the other fields. Some (especially - // initialization) functions are good about - // checking for validity. Many functions do - // not, it being assumed that the larger - // context assures we are using a valid - // i2eBordStrPtr. - - unsigned short i2eError; - // Used for returning an error condition from - // several functions which use i2eBordStrPtr - // as an argument. - - // Accelerators to characterize separate features of a board, derived from a - // number of sources. - - unsigned short i2eFifoSize; - // Always, the size of the FIFO. For - // IntelliPort-II, always the same, for -IIEX - // taken from the Power-On reset message. - - volatile - unsigned short i2eFifoRemains; - // Used during normal operation to indicate a - // lower bound on the amount of data which - // might be in the outbound fifo. - - unsigned char i2eFifoStyle; - // Accelerator which tells which style (-II or - // -IIEX) FIFO we are using. - - unsigned char i2eDataWidth16; - // Accelerator which tells whether we should - // do 8 or 16-bit data transfers. - - unsigned char i2eMaxIrq; - // The highest allowable IRQ, based on the - // slot size. - - // Accelerators for various addresses on the board - int i2eBase; // I/O Address of the Board - int i2eData; // From here data transfers happen - int i2eStatus; // From here status reads happen - int i2ePointer; // (IntelliPort-II: pointer/commands) - int i2eXMail; // (IntelliPOrt-IIEX: mailboxes - int i2eXMask; // (IntelliPort-IIEX: mask write - - //------------------------------------------------------- - // Information presented in a common format across boards - // For each box, bit map of the channels present. Box closest to - // the host is box 0. LSB is channel 0. IntelliPort-II (non-expandable) - // is taken to be box 0. These are derived from product i.d. registers. - - unsigned short i2eChannelMap[ABS_MAX_BOXES]; - - // Same as above, except each is derived from firmware attempting to detect - // the uart presence (by reading a valid GFRCR register). If bits are set in - // i2eChannelMap and not in i2eGoodMap, there is a potential problem. - - unsigned short i2eGoodMap[ABS_MAX_BOXES]; - - // --------------------------- - // For indirect function calls - - // Routine to cause an N-millisecond delay: Patched by the ii2Initialize - // function. - - void (*i2eDelay)(unsigned int); - - // Routine to write N bytes to the board through the FIFO. Returns true if - // all copacetic, otherwise returns false and error is in i2eError field. - // IF COUNT IS ODD, ROUNDS UP TO THE NEXT EVEN NUMBER. - - int (*i2eWriteBuf)(struct _i2eBordStr *, unsigned char *, int); - - // Routine to read N bytes from the board through the FIFO. Returns true if - // copacetic, otherwise returns false and error in i2eError. - // IF COUNT IS ODD, ROUNDS UP TO THE NEXT EVEN NUMBER. - - int (*i2eReadBuf)(struct _i2eBordStr *, unsigned char *, int); - - // Returns a word from FIFO. Will use 2 byte operations if needed. - - unsigned short (*i2eReadWord)(struct _i2eBordStr *); - - // Writes a word to FIFO. Will use 2 byte operations if needed. - - void (*i2eWriteWord)(struct _i2eBordStr *, unsigned short); - - // Waits specified time for the Transmit FIFO to go empty. Returns true if - // ok, otherwise returns false and error in i2eError. - - int (*i2eWaitForTxEmpty)(struct _i2eBordStr *, int); - - // Returns true or false according to whether the outgoing mailbox is empty. - - int (*i2eTxMailEmpty)(struct _i2eBordStr *); - - // Checks whether outgoing mailbox is empty. If so, sends mail and returns - // true. Otherwise returns false. - - int (*i2eTrySendMail)(struct _i2eBordStr *, unsigned char); - - // If no mail available, returns NO_MAIL_HERE, else returns the value in the - // mailbox (guaranteed can't be NO_MAIL_HERE). - - unsigned short (*i2eGetMail)(struct _i2eBordStr *); - - // Enables the board to interrupt the host when it writes to the mailbox. - // Irqs will not occur, however, until the loadware separately enables - // interrupt generation to the host. The standard loadware does this in - // response to a command packet sent by the host. (Also, disables - // any other potential interrupt sources from the board -- other than the - // inbound mailbox). - - void (*i2eEnableMailIrq)(struct _i2eBordStr *); - - // Writes an arbitrary value to the mask register. - - void (*i2eWriteMask)(struct _i2eBordStr *, unsigned char); - - - // State information - - // During downloading, indicates the number of blocks remaining to download - // to the board. - - short i2eToLoad; - - // State of board (see manifests below) (e.g., whether in reset condition, - // whether standard loadware is installed, etc. - - unsigned char i2eState; - - // These three fields are only valid when there is loadware running on the - // board. (i2eState == II_STATE_LOADED or i2eState == II_STATE_STDLOADED ) - - unsigned char i2eLVersion; // Loadware version - unsigned char i2eLRevision; // Loadware revision - unsigned char i2eLSub; // Loadware subrevision - - // Flags which only have meaning in the context of the standard loadware. - // Somewhat violates the layering concept, but there is so little additional - // needed at the board level (while much additional at the channel level), - // that this beats maintaining two different per-board structures. - - // Indicates which IRQ the board has been initialized (from software) to use - // For MicroChannel boards, any value different from IRQ_UNDEFINED means - // that the software command has been sent to enable interrupts (or specify - // they are disabled). Special value: IRQ_UNDEFINED indicates that the - // software command to select the interrupt has not yet been sent, therefore - // (since the standard loadware insists that it be sent before any other - // packets are sent) no other packets should be sent yet. - - unsigned short i2eUsingIrq; - - // This is set when we hit the MB_OUT_STUFFED mailbox, which prevents us - // putting more in the mailbox until an appropriate mailbox message is - // received. - - unsigned char i2eWaitingForEmptyFifo; - - // Any mailbox bits waiting to be sent to the board are OR'ed in here. - - unsigned char i2eOutMailWaiting; - - // The head of any incoming packet is read into here, is then examined and - // we dispatch accordingly. - - unsigned short i2eLeadoffWord[1]; - - // Running counter of interrupts where the mailbox indicated incoming data. - - unsigned short i2eFifoInInts; - - // Running counter of interrupts where the mailbox indicated outgoing data - // had been stripped. - - unsigned short i2eFifoOutInts; - - // If not void, gives the address of a routine to call if fatal board error - // is found (only applies to standard l/w). - - void (*i2eFatalTrap)(struct _i2eBordStr *); - - // Will point to an array of some sort of channel structures (whose format - // is unknown at this level, being a function of what loadware is - // installed and the code configuration (max sizes of buffers, etc.)). - - void *i2eChannelPtr; - - // Set indicates that the board has gone fatal. - - unsigned short i2eFatal; - - // The number of elements pointed to by i2eChannelPtr. - - unsigned short i2eChannelCnt; - - // Ring-buffers of channel structures whose channels have particular needs. - - rwlock_t Fbuf_spinlock; - volatile - unsigned short i2Fbuf_strip; // Strip index - volatile - unsigned short i2Fbuf_stuff; // Stuff index - void *i2Fbuf[CH_QUEUE_SIZE]; // An array of channel pointers - // of channels who need to send - // flow control packets. - rwlock_t Dbuf_spinlock; - volatile - unsigned short i2Dbuf_strip; // Strip index - volatile - unsigned short i2Dbuf_stuff; // Stuff index - void *i2Dbuf[CH_QUEUE_SIZE]; // An array of channel pointers - // of channels who need to send - // data or in-line command packets. - rwlock_t Bbuf_spinlock; - volatile - unsigned short i2Bbuf_strip; // Strip index - volatile - unsigned short i2Bbuf_stuff; // Stuff index - void *i2Bbuf[CH_QUEUE_SIZE]; // An array of channel pointers - // of channels who need to send - // bypass command packets. - - /* - * A set of flags to indicate that certain events have occurred on at least - * one of the ports on this board. We use this to decide whether to spin - * through the channels looking for breaks, etc. - */ - int got_input; - int status_change; - bidStat channelBtypes; - - /* - * Debugging counters, etc. - */ - unsigned long debugFlowQueued; - unsigned long debugInlineQueued; - unsigned long debugDataQueued; - unsigned long debugBypassQueued; - unsigned long debugFlowCount; - unsigned long debugInlineCount; - unsigned long debugBypassCount; - - rwlock_t read_fifo_spinlock; - rwlock_t write_fifo_spinlock; - -// For queuing interrupt bottom half handlers. /\/\|=mhw=|\/\/ - struct work_struct tqueue_interrupt; - - struct timer_list SendPendingTimer; // Used by iiSendPending - unsigned int SendPendingRetry; -} i2eBordStr, *i2eBordStrPtr; - -//------------------------------------------------------------------- -// Macro Definitions for the indirect calls defined in the i2eBordStr -//------------------------------------------------------------------- -// -#define iiDelay(a,b) (*(a)->i2eDelay)(b) -#define iiWriteBuf(a,b,c) (*(a)->i2eWriteBuf)(a,b,c) -#define iiReadBuf(a,b,c) (*(a)->i2eReadBuf)(a,b,c) - -#define iiWriteWord(a,b) (*(a)->i2eWriteWord)(a,b) -#define iiReadWord(a) (*(a)->i2eReadWord)(a) - -#define iiWaitForTxEmpty(a,b) (*(a)->i2eWaitForTxEmpty)(a,b) - -#define iiTxMailEmpty(a) (*(a)->i2eTxMailEmpty)(a) -#define iiTrySendMail(a,b) (*(a)->i2eTrySendMail)(a,b) - -#define iiGetMail(a) (*(a)->i2eGetMail)(a) -#define iiEnableMailIrq(a) (*(a)->i2eEnableMailIrq)(a) -#define iiDisableMailIrq(a) (*(a)->i2eWriteMask)(a,0) -#define iiWriteMask(a,b) (*(a)->i2eWriteMask)(a,b) - -//------------------------------------------- -// Manifests for i2eBordStr: -//------------------------------------------- - -typedef void (*delayFunc_t)(unsigned int); - -// i2eValid -// -#define I2E_MAGIC 0x4251 // Structure is valid. -#define I2E_INCOMPLETE 0x1122 // Structure failed during init. - - -// i2eError -// -#define I2EE_GOOD 0 // Operation successful -#define I2EE_BADADDR 1 // Address out of range -#define I2EE_BADSTATE 2 // Attempt to perform a function when the board - // structure was in the incorrect state -#define I2EE_BADMAGIC 3 // Bad magic number from Power On test (i2ePomSize - // reflects what was read -#define I2EE_PORM_SHORT 4 // Power On message too short -#define I2EE_PORM_LONG 5 // Power On message too long -#define I2EE_BAD_FAMILY 6 // Un-supported board family type -#define I2EE_INCONSIST 7 // Firmware reports something impossible, - // e.g. unexpected number of ports... Almost no - // excuse other than bad FIFO... -#define I2EE_POSTERR 8 // Power-On self test reported a bad error -#define I2EE_BADBUS 9 // Unknown Bus type declared in message -#define I2EE_TXE_TIME 10 // Timed out waiting for TX Fifo to empty -#define I2EE_INVALID 11 // i2eValid field does not indicate a valid and - // complete board structure (for functions which - // require this be so.) -#define I2EE_BAD_PORT 12 // Discrepancy between channels actually found and - // what the product is supposed to have. Check - // i2eGoodMap vs i2eChannelMap for details. -#define I2EE_BAD_IRQ 13 // Someone specified an unsupported IRQ -#define I2EE_NOCHANNELS 14 // No channel structures have been defined (for - // functions requiring this). - -// i2eFifoStyle -// -#define FIFO_II 0 /* IntelliPort-II style: see also i2hw.h */ -#define FIFO_IIEX 1 /* IntelliPort-IIEX style */ - -// i2eGetMail -// -#define NO_MAIL_HERE 0x1111 // Since mail is unsigned char, cannot possibly - // promote to 0x1111. -// i2eState -// -#define II_STATE_COLD 0 // Addresses have been defined, but board not even - // reset yet. -#define II_STATE_RESET 1 // Board,if it exists, has just been reset -#define II_STATE_READY 2 // Board ready for its first block -#define II_STATE_LOADING 3 // Board continuing load -#define II_STATE_LOADED 4 // Board has finished load: status ok -#define II_STATE_BADLOAD 5 // Board has finished load: failed! -#define II_STATE_STDLOADED 6 // Board has finished load: standard firmware - -// i2eUsingIrq -// -#define I2_IRQ_UNDEFINED 0x1352 /* No valid irq (or polling = 0) can - * ever promote to this! */ -//------------------------------------------ -// Handy Macros for i2ellis.c and others -// Note these are common to -II and -IIEX -//------------------------------------------ - -// Given a pointer to the board structure, does the input FIFO have any data or -// not? -// -#define I2_HAS_INPUT(pB) !(inb(pB->i2eStatus) & ST_IN_EMPTY) - -// Given a pointer to the board structure, is there anything in the incoming -// mailbox? -// -#define I2_HAS_MAIL(pB) (inb(pB->i2eStatus) & ST_IN_MAIL) - -#define I2_UPDATE_FIFO_ROOM(pB) ((pB)->i2eFifoRemains = (pB)->i2eFifoSize) - -//------------------------------------------ -// Function Declarations for i2ellis.c -//------------------------------------------ -// -// Functions called directly -// -// Initialization of a board & structure is in four (five!) parts: -// -// 1) iiSetAddress() - Define the board address & delay function for a board. -// 2) iiReset() - Reset the board (provided it exists) -// -- Note you may do this to several boards -- -// 3) iiResetDelay() - Delay for 2 seconds (once for all boards) -// 4) iiInitialize() - Attempt to read Power-up message; further initialize -// accelerators -// -// Then you may use iiDownloadAll() or iiDownloadFile() (in i2file.c) to write -// loadware. To change loadware, you must begin again with step 2, resetting -// the board again (step 1 not needed). - -static int iiSetAddress(i2eBordStrPtr, int, delayFunc_t ); -static int iiReset(i2eBordStrPtr); -static int iiResetDelay(i2eBordStrPtr); -static int iiInitialize(i2eBordStrPtr); - -// Routine to validate that all channels expected are there. -// -extern int iiValidateChannels(i2eBordStrPtr); - -// Routine used to download a block of loadware. -// -static int iiDownloadBlock(i2eBordStrPtr, loadHdrStrPtr, int); - -// Return values given by iiDownloadBlock, iiDownloadAll, iiDownloadFile: -// -#define II_DOWN_BADVALID 0 // board structure is invalid -#define II_DOWN_CONTINUING 1 // So far, so good, firmware expects more -#define II_DOWN_GOOD 2 // Download complete, CRC good -#define II_DOWN_BAD 3 // Download complete, but CRC bad -#define II_DOWN_BADFILE 4 // Bad magic number in loadware file -#define II_DOWN_BADSTATE 5 // Board is in an inappropriate state for - // downloading loadware. (see i2eState) -#define II_DOWN_TIMEOUT 6 // Timeout waiting for firmware -#define II_DOWN_OVER 7 // Too much data -#define II_DOWN_UNDER 8 // Not enough data -#define II_DOWN_NOFILE 9 // Loadware file not found - -// Routine to download an entire loadware module: Return values are a subset of -// iiDownloadBlock's, excluding, of course, II_DOWN_CONTINUING -// -static int iiDownloadAll(i2eBordStrPtr, loadHdrStrPtr, int, int); - -// Many functions defined here return True if good, False otherwise, with an -// error code in i2eError field. Here is a handy macro for setting the error -// code and returning. -// -#define I2_COMPLETE(pB,code) do { \ - pB->i2eError = code; \ - return (code == I2EE_GOOD);\ - } while (0) - -#endif // I2ELLIS_H diff --git a/drivers/char/ip2/i2hw.h b/drivers/char/ip2/i2hw.h deleted file mode 100644 index c0ba6c05f0cd..000000000000 --- a/drivers/char/ip2/i2hw.h +++ /dev/null @@ -1,652 +0,0 @@ -/******************************************************************************* -* -* (c) 1999 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Definitions limited to properties of the hardware or the -* bootstrap firmware. As such, they are applicable regardless of -* operating system or loadware (standard or diagnostic). -* -*******************************************************************************/ -#ifndef I2HW_H -#define I2HW_H 1 -//------------------------------------------------------------------------------ -// Revision History: -// -// 23 September 1991 MAG First Draft Started...through... -// 11 October 1991 ... Continuing development... -// 6 August 1993 Added support for ISA-4 (asic) which is architected -// as an ISA-CEX with a single 4-port box. -// -// 20 December 1996 AKM Version for Linux -// -//------------------------------------------------------------------------------ -/*------------------------------------------------------------------------------ - -HARDWARE DESCRIPTION: - -Introduction: - -The IntelliPort-II and IntelliPort-IIEX products occupy a block of eight (8) -addresses in the host's I/O space. - -Some addresses are used to transfer data to/from the board, some to transfer -so-called "mailbox" messages, and some to read bit-mapped status information. -While all the products in the line are functionally similar, some use a 16-bit -data path to transfer data while others use an 8-bit path. Also, the use of -command /status/mailbox registers differs slightly between the II and IIEX -branches of the family. - -The host determines what type of board it is dealing with by reading a string of -sixteen characters from the board. These characters are always placed in the -fifo by the board's local processor whenever the board is reset (either from -power-on or under software control) and are known as the "Power-on Reset -Message." In order that this message can be read from either type of board, the -hardware registers used in reading this message are the same. Once this message -has been read by the host, then it has the information required to operate. - -General Differences between boards: - -The greatest structural difference is between the -II and -IIEX families of -product. The -II boards use the Am4701 dual 512x8 bidirectional fifo to support -the data path, mailbox registers, and status registers. This chip contains some -features which are not used in the IntelliPort-II products; a description of -these is omitted here. Because of these many features, it contains many -registers, too many to access directly within a small address space. They are -accessed by first writing a value to a "pointer" register. This value selects -the register to be accessed. The next read or write to that address accesses -the selected register rather than the pointer register. - -The -IIEX boards use a proprietary design similar to the Am4701 in function. But -because of a simpler, more streamlined design it doesn't require so many -registers. This means they can be accessed directly in single operations rather -than through a pointer register. - -Besides these differences, there are differences in whether 8-bit or 16-bit -transfers are used to move data to the board. - -The -II boards are capable only of 8-bit data transfers, while the -IIEX boards -may be configured for either 8-bit or 16-bit data transfers. If the on-board DIP -switch #8 is ON, and the card has been installed in a 16-bit slot, 16-bit -transfers are supported (and will be expected by the standard loadware). The -on-board firmware can determine the position of the switch, and whether the -board is installed in a 16-bit slot; it supplies this information to the host as -part of the power-up reset message. - -The configuration switch (#8) and slot selection do not directly configure the -hardware. It is up to the on-board loadware and host-based drivers to act -according to the selected options. That is, loadware and drivers could be -written to perform 8-bit transfers regardless of the state of the DIP switch or -slot (and in a diagnostic environment might well do so). Likewise, 16-bit -transfers could be performed as long as the card is in a 16-bit slot. - -Note the slot selection and DIP switch selection are provided separately: a -board running in 8-bit mode in a 16-bit slot has a greater range of possible -interrupts to choose from; information of potential use to the host. - -All 8-bit data transfers are done in the same way, regardless of whether on a --II board or a -IIEX board. - -The host must consider two things then: 1) whether a -II or -IIEX product is -being used, and 2) whether an 8-bit or 16-bit data path is used. - -A further difference is that -II boards always have a 512-byte fifo operating in -each direction. -IIEX boards may use fifos of varying size; this size is -reported as part of the power-up message. - -I/O Map Of IntelliPort-II and IntelliPort-IIEX boards: -(Relative to the chosen base address) - -Addr R/W IntelliPort-II IntelliPort-IIEX ----- --- -------------- ---------------- -0 R/W Data Port (byte) Data Port (byte or word) -1 R/W (Not used) (MSB of word-wide data written to Data Port) -2 R Status Register Status Register -2 W Pointer Register Interrupt Mask Register -3 R/W (Not used) Mailbox Registers (6 bits: 11111100) -4,5 -- Reserved for future products -6 -- Reserved for future products -7 R Guaranteed to have no effect -7 W Hardware reset of board. - - -Rules: -All data transfers are performed using the even i/o address. If byte-wide data -transfers are being used, do INB/OUTB operations on the data port. If word-wide -transfers are used, do INW/OUTW operations. In some circumstances (such as -reading the power-up message) you will do INB from the data port, but in this -case the MSB of each word read is lost. When accessing all other unreserved -registers, use byte operations only. -------------------------------------------------------------------------------*/ - -//------------------------------------------------ -// Mandatory Includes: -//------------------------------------------------ -// -#include "ip2types.h" - -//------------------------------------------------------------------------- -// Manifests for the I/O map: -//------------------------------------------------------------------------- -// R/W: Data port (byte) for IntelliPort-II, -// R/W: Data port (byte or word) for IntelliPort-IIEX -// Incoming or outgoing data passes through a FIFO, the status of which is -// available in some of the bits in FIFO_STATUS. This (bidirectional) FIFO is -// the primary means of transferring data, commands, flow-control, and status -// information between the host and board. -// -#define FIFO_DATA 0 - -// Another way of passing information between the board and the host is -// through "mailboxes". Unlike a FIFO, a mailbox holds only a single byte of -// data. Writing data to the mailbox causes a status bit to be set, and -// potentially interrupting the intended receiver. The sender has some way to -// determine whether the data has been read yet; as soon as it has, it may send -// more. The mailboxes are handled differently on -II and -IIEX products, as -// suggested below. -//------------------------------------------------------------------------------ -// Read: Status Register for IntelliPort-II or -IIEX -// The presence of any bit set here will cause an interrupt to the host, -// provided the corresponding bit has been unmasked in the interrupt mask -// register. Furthermore, interrupts to the host are disabled globally until the -// loadware selects the irq line to use. With the exception of STN_MR, the bits -// remain set so long as the associated condition is true. -// -#define FIFO_STATUS 2 - -// Bit map of status bits which are identical for -II and -IIEX -// -#define ST_OUT_FULL 0x40 // Outbound FIFO full -#define ST_IN_EMPTY 0x20 // Inbound FIFO empty -#define ST_IN_MAIL 0x04 // Inbound Mailbox full - -// The following exists only on the Intelliport-IIEX, and indicates that the -// board has not read the last outgoing mailbox data yet. In the IntelliPort-II, -// the outgoing mailbox may be read back: a zero indicates the board has read -// the data. -// -#define STE_OUT_MAIL 0x80 // Outbound mailbox full (!) - -// The following bits are defined differently for -II and -IIEX boards. Code -// which relies on these bits will need to be functionally different for the two -// types of boards and should be generally avoided because of the additional -// complexity this creates: - -// Bit map of status bits only on -II - -// Fifo has been RESET (cleared when the status register is read). Note that -// this condition cannot be masked and would always interrupt the host, except -// that the hardware reset also disables interrupts globally from the board -// until re-enabled by loadware. This could also arise from the -// Am4701-supported command to reset the chip, but this command is generally not -// used here. -// -#define STN_MR 0x80 - -// See the AMD Am4701 data sheet for details on the following four bits. They -// are not presently used by Computone drivers. -// -#define STN_OUT_AF 0x10 // Outbound FIFO almost full (programmable) -#define STN_IN_AE 0x08 // Inbound FIFO almost empty (programmable) -#define STN_BD 0x02 // Inbound byte detected -#define STN_PE 0x01 // Parity/Framing condition detected - -// Bit-map of status bits only on -IIEX -// -#define STE_OUT_HF 0x10 // Outbound FIFO half full -#define STE_IN_HF 0x08 // Inbound FIFO half full -#define STE_IN_FULL 0x02 // Inbound FIFO full -#define STE_OUT_MT 0x01 // Outbound FIFO empty - -//------------------------------------------------------------------------------ - -// Intelliport-II -- Write Only: the pointer register. -// Values are written to this register to select the Am4701 internal register to -// be accessed on the next operation. -// -#define FIFO_PTR 0x02 - -// Values for the pointer register -// -#define SEL_COMMAND 0x1 // Selects the Am4701 command register - -// Some possible commands: -// -#define SEL_CMD_MR 0x80 // Am4701 command to reset the chip -#define SEL_CMD_SH 0x40 // Am4701 command to map the "other" port into the - // status register. -#define SEL_CMD_UNSH 0 // Am4701 command to "unshift": port maps into its - // own status register. -#define SEL_MASK 0x2 // Selects the Am4701 interrupt mask register. The - // interrupt mask register is bit-mapped to match - // the status register (FIFO_STATUS) except for - // STN_MR. (See above.) -#define SEL_BYTE_DET 0x3 // Selects the Am4701 byte-detect register. (Not - // normally used except in diagnostics.) -#define SEL_OUTMAIL 0x4 // Selects the outbound mailbox (R/W). Reading back - // a value of zero indicates that the mailbox has - // been read by the board and is available for more - // data./ Writing to the mailbox optionally - // interrupts the board, depending on the loadware's - // setting of its interrupt mask register. -#define SEL_AEAF 0x5 // Selects AE/AF threshold register. -#define SEL_INMAIL 0x6 // Selects the inbound mailbox (Read) - -//------------------------------------------------------------------------------ -// IntelliPort-IIEX -- Write Only: interrupt mask (and misc flags) register: -// Unlike IntelliPort-II, bit assignments do NOT match those of the status -// register. -// -#define FIFO_MASK 0x2 - -// Mailbox readback select: -// If set, reads to FIFO_MAIL will read the OUTBOUND mailbox (host to board). If -// clear (default on reset) reads to FIFO_MAIL will read the INBOUND mailbox. -// This is the normal situation. The clearing of a mailbox is determined on -// -IIEX boards by waiting for the STE_OUT_MAIL bit to clear. Readback -// capability is provided for diagnostic purposes only. -// -#define MX_OUTMAIL_RSEL 0x80 - -#define MX_IN_MAIL 0x40 // Enables interrupts when incoming mailbox goes - // full (ST_IN_MAIL set). -#define MX_IN_FULL 0x20 // Enables interrupts when incoming FIFO goes full - // (STE_IN_FULL). -#define MX_IN_MT 0x08 // Enables interrupts when incoming FIFO goes empty - // (ST_IN_MT). -#define MX_OUT_FULL 0x04 // Enables interrupts when outgoing FIFO goes full - // (ST_OUT_FULL). -#define MX_OUT_MT 0x01 // Enables interrupts when outgoing FIFO goes empty - // (STE_OUT_MT). - -// Any remaining bits are reserved, and should be written to ZERO for -// compatibility with future Computone products. - -//------------------------------------------------------------------------------ -// IntelliPort-IIEX: -- These are only 6-bit mailboxes !!! -- 11111100 (low two -// bits always read back 0). -// Read: One of the mailboxes, usually Inbound. -// Inbound Mailbox (MX_OUTMAIL_RSEL = 0) -// Outbound Mailbox (MX_OUTMAIL_RSEL = 1) -// Write: Outbound Mailbox -// For the IntelliPort-II boards, the outbound mailbox is read back to determine -// whether the board has read the data (0 --> data has been read). For the -// IntelliPort-IIEX, this is done by reading a status register. To determine -// whether mailbox is available for more outbound data, use the STE_OUT_MAIL bit -// in FIFO_STATUS. Moreover, although the Outbound Mailbox can be read back by -// setting MX_OUTMAIL_RSEL, it is NOT cleared when the board reads it, as is the -// case with the -II boards. For this reason, FIFO_MAIL is normally used to read -// the inbound FIFO, and MX_OUTMAIL_RSEL kept clear. (See above for -// MX_OUTMAIL_RSEL description.) -// -#define FIFO_MAIL 0x3 - -//------------------------------------------------------------------------------ -// WRITE ONLY: Resets the board. (Data doesn't matter). -// -#define FIFO_RESET 0x7 - -//------------------------------------------------------------------------------ -// READ ONLY: Will have no effect. (Data is undefined.) -// Actually, there will be an effect, in that the operation is sure to generate -// a bus cycle: viz., an I/O byte Read. This fact can be used to enforce short -// delays when no comparable time constant is available. -// -#define FIFO_NOP 0x7 - -//------------------------------------------------------------------------------ -// RESET & POWER-ON RESET MESSAGE -/*------------------------------------------------------------------------------ -RESET: - -The IntelliPort-II and -IIEX boards are reset in three ways: Power-up, channel -reset, and via a write to the reset register described above. For products using -the ISA bus, these three sources of reset are equvalent. For MCA and EISA buses, -the Power-up and channel reset sources cause additional hardware initialization -which should only occur at system startup time. - -The third type of reset, called a "command reset", is done by writing any data -to the FIFO_RESET address described above. This resets the on-board processor, -FIFO, UARTS, and associated hardware. - -This passes control of the board to the bootstrap firmware, which performs a -Power-On Self Test and which detects its current configuration. For example, --IIEX products determine the size of FIFO which has been installed, and the -number and type of expansion boxes attached. - -This and other information is then written to the FIFO in a 16-byte data block -to be read by the host. This block is guaranteed to be present within two (2) -seconds of having received the command reset. The firmware is now ready to -receive loadware from the host. - -It is good practice to perform a command reset to the board explicitly as part -of your software initialization. This allows your code to properly restart from -a soft boot. (Many systems do not issue channel reset on soft boot). - -Because of a hardware reset problem on some of the Cirrus Logic 1400's which are -used on the product, it is recommended that you reset the board twice, separated -by an approximately 50 milliseconds delay. (VERY approximately: probably ok to -be off by a factor of five. The important point is that the first command reset -in fact generates a reset pulse on the board. This pulse is guaranteed to last -less than 10 milliseconds. The additional delay ensures the 1400 has had the -chance to respond sufficiently to the first reset. Why not a longer delay? Much -more than 50 milliseconds gets to be noticable, but the board would still work. - -Once all 16 bytes of the Power-on Reset Message have been read, the bootstrap -firmware is ready to receive loadware. - -Note on Power-on Reset Message format: -The various fields have been designed with future expansion in view. -Combinations of bitfields and values have been defined which define products -which may not currently exist. This has been done to allow drivers to anticipate -the possible introduction of products in a systematic fashion. This is not -intended to suggest that each potential product is actually under consideration. -------------------------------------------------------------------------------*/ - -//---------------------------------------- -// Format of Power-on Reset Message -//---------------------------------------- - -typedef union _porStr // "por" stands for Power On Reset -{ - unsigned char c[16]; // array used when considering the message as a - // string of undifferentiated characters - - struct // Elements used when considering values - { - // The first two bytes out of the FIFO are two magic numbers. These are - // intended to establish that there is indeed a member of the - // IntelliPort-II(EX) family present. The remaining bytes may be - // expected // to be valid. When reading the Power-on Reset message, - // if the magic numbers do not match it is probably best to stop - // reading immediately. You are certainly not reading our board (unless - // hardware is faulty), and may in fact be reading some other piece of - // hardware. - - unsigned char porMagic1; // magic number: first byte == POR_MAGIC_1 - unsigned char porMagic2; // magic number: second byte == POR_MAGIC_2 - - // The Version, Revision, and Subrevision are stored as absolute numbers - // and would normally be displayed in the format V.R.S (e.g. 1.0.2) - - unsigned char porVersion; // Bootstrap firmware version number - unsigned char porRevision; // Bootstrap firmware revision number - unsigned char porSubRev; // Bootstrap firmware sub-revision number - - unsigned char porID; // Product ID: Bit-mapped according to - // conventions described below. Among other - // things, this allows us to distinguish - // IntelliPort-II boards from IntelliPort-IIEX - // boards. - - unsigned char porBus; // IntelliPort-II: Unused - // IntelliPort-IIEX: Bus Information: - // Bit-mapped below - - unsigned char porMemory; // On-board DRAM size: in 32k blocks - - // porPorts1 (and porPorts2) are used to determine the ports which are - // available to the board. For non-expandable product, a single number - // is sufficient. For expandable product, the board may be connected - // to as many as four boxes. Each box may be (so far) either a 16-port - // or an 8-port size. Whenever an 8-port box is used, the remaining 8 - // ports leave gaps between existing channels. For that reason, - // expandable products must report a MAP of available channels. Since - // each UART supports four ports, we represent each UART found by a - // single bit. Using two bytes to supply the mapping information we - // report the presense or absense of up to 16 UARTS, or 64 ports in - // steps of 4 ports. For -IIEX products, the ports are numbered - // starting at the box closest to the controller in the "chain". - - // Interpreted Differently for IntelliPort-II and -IIEX. - // -II: Number of ports (Derived actually from product ID). See - // Diag1&2 to indicate if uart was actually detected. - // -IIEX: Bit-map of UARTS found, LSB (see below for MSB of this). This - // bitmap is based on detecting the uarts themselves; - // see porFlags for information from the box i.d's. - unsigned char porPorts1; - - unsigned char porDiag1; // Results of on-board P.O.S.T, 1st byte - unsigned char porDiag2; // Results of on-board P.O.S.T, 2nd byte - unsigned char porSpeed; // Speed of local CPU: given as MHz x10 - // e.g., 16.0 MHz CPU is reported as 160 - unsigned char porFlags; // Misc information (see manifests below) - // Bit-mapped: CPU type, UART's present - - unsigned char porPorts2; // -II: Undefined - // -IIEX: Bit-map of UARTS found, MSB (see - // above for LSB) - - // IntelliPort-II: undefined - // IntelliPort-IIEX: 1 << porFifoSize gives the size, in bytes, of the - // host interface FIFO, in each direction. When running the -IIEX in - // 8-bit mode, fifo capacity is halved. The bootstrap firmware will - // have already accounted for this fact in generating this number. - unsigned char porFifoSize; - - // IntelliPort-II: undefined - // IntelliPort-IIEX: The number of boxes connected. (Presently 1-4) - unsigned char porNumBoxes; - } e; -} porStr, *porStrPtr; - -//-------------------------- -// Values for porStr fields -//-------------------------- - -//--------------------- -// porMagic1, porMagic2 -//---------------------- -// -#define POR_MAGIC_1 0x96 // The only valid value for porMagic1 -#define POR_MAGIC_2 0x35 // The only valid value for porMagic2 -#define POR_1_INDEX 0 // Byte position of POR_MAGIC_1 -#define POR_2_INDEX 1 // Ditto for POR_MAGIC_2 - -//---------------------- -// porID -//---------------------- -// -#define POR_ID_FAMILY 0xc0 // These bits indicate the general family of - // product. -#define POR_ID_FII 0x00 // Family is "IntelliPort-II" -#define POR_ID_FIIEX 0x40 // Family is "IntelliPort-IIEX" - -// These bits are reserved, presently zero. May be used at a later date to -// convey other product information. -// -#define POR_ID_RESERVED 0x3c - -#define POR_ID_SIZE 0x03 // Remaining bits indicate number of ports & - // Connector information. -#define POR_ID_II_8 0x00 // For IntelliPort-II, indicates 8-port using - // standard brick. -#define POR_ID_II_8R 0x01 // For IntelliPort-II, indicates 8-port using - // RJ11's (no CTS) -#define POR_ID_II_6 0x02 // For IntelliPort-II, indicates 6-port using - // RJ45's -#define POR_ID_II_4 0x03 // For IntelliPort-II, indicates 4-port using - // 4xRJ45 connectors -#define POR_ID_EX 0x00 // For IntelliPort-IIEX, indicates standard - // expandable controller (other values reserved) - -//---------------------- -// porBus -//---------------------- - -// IntelliPort-IIEX only: Board is installed in a 16-bit slot -// -#define POR_BUS_SLOT16 0x20 - -// IntelliPort-IIEX only: DIP switch #8 is on, selecting 16-bit host interface -// operation. -// -#define POR_BUS_DIP16 0x10 - -// Bits 0-2 indicate type of bus: This information is stored in the bootstrap -// loadware, different loadware being used on different products for different -// buses. For most situations, the drivers do not need this information; but it -// is handy in a diagnostic environment. For example, on microchannel boards, -// you would not want to try to test several interrupts, only the one for which -// you were configured. -// -#define POR_BUS_TYPE 0x07 - -// Unknown: this product doesn't know what bus it is running in. (e.g. if same -// bootstrap firmware were wanted for two different buses.) -// -#define POR_BUS_T_UNK 0 - -// Note: existing firmware for ISA-8 and MC-8 currently report the POR_BUS_T_UNK -// state, since the same bootstrap firmware is used for each. - -#define POR_BUS_T_MCA 1 // MCA BUS */ -#define POR_BUS_T_EISA 2 // EISA BUS */ -#define POR_BUS_T_ISA 3 // ISA BUS */ - -// Values 4-7 Reserved - -// Remaining bits are reserved - -//---------------------- -// porDiag1 -//---------------------- - -#define POR_BAD_MAPPER 0x80 // HW failure on P.O.S.T: Chip mapper failed - -// These two bits valid only for the IntelliPort-II -// -#define POR_BAD_UART1 0x01 // First 1400 bad -#define POR_BAD_UART2 0x02 // Second 1400 bad - -//---------------------- -// porDiag2 -//---------------------- - -#define POR_DEBUG_PORT 0x80 // debug port was detected by the P.O.S.T -#define POR_DIAG_OK 0x00 // Indicates passage: Failure codes not yet - // available. - // Other bits undefined. -//---------------------- -// porFlags -//---------------------- - -#define POR_CPU 0x03 // These bits indicate supposed CPU type -#define POR_CPU_8 0x01 // Board uses an 80188 (no such thing yet) -#define POR_CPU_6 0x02 // Board uses an 80186 (all existing products) -#define POR_CEX4 0x04 // If set, this is an ISA-CEX/4: An ISA-4 (asic) - // which is architected like an ISA-CEX connected - // to a (hitherto impossible) 4-port box. -#define POR_BOXES 0xf0 // Valid for IntelliPort-IIEX only: Map of Box - // sizes based on box I.D. -#define POR_BOX_16 0x10 // Set indicates 16-port, clear 8-port - -//------------------------------------- -// LOADWARE and DOWNLOADING CODE -//------------------------------------- - -/* -Loadware may be sent to the board in two ways: -1) It may be read from a (binary image) data file block by block as each block - is sent to the board. This is only possible when the initialization is - performed by code which can access your file system. This is most suitable - for diagnostics and appications which use the interface library directly. - -2) It may be hard-coded into your source by including a .h file (typically - supplied by Computone), which declares a data array and initializes every - element. This achieves the same result as if an entire loadware file had - been read into the array. - - This requires more data space in your program, but access to the file system - is not required. This method is more suited to driver code, which typically - is running at a level too low to access the file system directly. - -At present, loadware can only be generated at Computone. - -All Loadware begins with a header area which has a particular format. This -includes a magic number which identifies the file as being (purportedly) -loadware, CRC (for the loader), and version information. -*/ - - -//----------------------------------------------------------------------------- -// Format of loadware block -// -// This is defined as a union so we can pass a pointer to one of these items -// and (if it is the first block) pick out the version information, etc. -// -// Otherwise, to deal with this as a simple character array -//------------------------------------------------------------------------------ - -#define LOADWARE_BLOCK_SIZE 512 // Number of bytes in each block of loadware - -typedef union _loadHdrStr -{ - unsigned char c[LOADWARE_BLOCK_SIZE]; // Valid for every block - - struct // These fields are valid for only the first block of loadware. - { - unsigned char loadMagic; // Magic number: see below - unsigned char loadBlocksMore; // How many more blocks? - unsigned char loadCRC[2]; // Two CRC bytes: used by loader - unsigned char loadVersion; // Version number - unsigned char loadRevision; // Revision number - unsigned char loadSubRevision; // Sub-revision number - unsigned char loadSpares[9]; // Presently unused - unsigned char loadDates[32]; // Null-terminated string which can give - // date and time of compilation - } e; -} loadHdrStr, *loadHdrStrPtr; - -//------------------------------------ -// Defines for downloading code: -//------------------------------------ - -// The loadMagic field in the first block of the loadfile must be this, else the -// file is not valid. -// -#define MAGIC_LOADFILE 0x3c - -// How do we know the load was successful? On completion of the load, the -// bootstrap firmware returns a code to indicate whether it thought the download -// was valid and intends to execute it. These are the only possible valid codes: -// -#define LOADWARE_OK 0xc3 // Download was ok -#define LOADWARE_BAD 0x5a // Download was bad (CRC error) - -// Constants applicable to writing blocks of loadware: -// The first block of loadware might take 600 mS to load, in extreme cases. -// (Expandable board: worst case for sending startup messages to the LCD's). -// The 600mS figure is not really a calculation, but a conservative -// guess/guarantee. Usually this will be within 100 mS, like subsequent blocks. -// -#define MAX_DLOAD_START_TIME 1000 // 1000 mS -#define MAX_DLOAD_READ_TIME 100 // 100 mS - -// Firmware should respond with status (see above) within this long of host -// having sent the final block. -// -#define MAX_DLOAD_ACK_TIME 100 // 100 mS, again! - -//------------------------------------------------------ -// MAXIMUM NUMBER OF PORTS PER BOARD: -// This is fixed for now (with the expandable), but may -// be expanding according to even newer products. -//------------------------------------------------------ -// -#define ABS_MAX_BOXES 4 // Absolute most boxes per board -#define ABS_BIGGEST_BOX 16 // Absolute the most ports per box -#define ABS_MOST_PORTS (ABS_MAX_BOXES * ABS_BIGGEST_BOX) - -#define I2_OUTSW(port, addr, count) outsw((port), (addr), (((count)+1)/2)) -#define I2_OUTSB(port, addr, count) outsb((port), (addr), (((count)+1))&-2) -#define I2_INSW(port, addr, count) insw((port), (addr), (((count)+1)/2)) -#define I2_INSB(port, addr, count) insb((port), (addr), (((count)+1))&-2) - -#endif // I2HW_H - diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c deleted file mode 100644 index 0d10b89218ed..000000000000 --- a/drivers/char/ip2/i2lib.c +++ /dev/null @@ -1,2214 +0,0 @@ -/******************************************************************************* -* -* (c) 1999 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort family of multiport -* serial I/O controllers. -* -* DESCRIPTION: High-level interface code for the device driver. Uses the -* Extremely Low Level Interface Support (i2ellis.c). Provides an -* interface to the standard loadware, to support drivers or -* application code. (This is included source code, not a separate -* compilation module.) -* -*******************************************************************************/ -//------------------------------------------------------------------------------ -// Note on Strategy: -// Once the board has been initialized, it will interrupt us when: -// 1) It has something in the fifo for us to read (incoming data, flow control -// packets, or whatever). -// 2) It has stripped whatever we have sent last time in the FIFO (and -// consequently is ready for more). -// -// Note also that the buffer sizes declared in i2lib.h are VERY SMALL. This -// worsens performance considerably, but is done so that a great many channels -// might use only a little memory. -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -// Revision History: -// -// 0.00 - 4/16/91 --- First Draft -// 0.01 - 4/29/91 --- 1st beta release -// 0.02 - 6/14/91 --- Changes to allow small model compilation -// 0.03 - 6/17/91 MAG Break reporting protected from interrupts routines with -// in-line asm added for moving data to/from ring buffers, -// replacing a variety of methods used previously. -// 0.04 - 6/21/91 MAG Initial flow-control packets not queued until -// i2_enable_interrupts time. Former versions would enqueue -// them at i2_init_channel time, before we knew how many -// channels were supposed to exist! -// 0.05 - 10/12/91 MAG Major changes: works through the ellis.c routines now; -// supports new 16-bit protocol and expandable boards. -// - 10/24/91 MAG Most changes in place and stable. -// 0.06 - 2/20/92 MAG Format of CMD_HOTACK corrected: the command takes no -// argument. -// 0.07 -- 3/11/92 MAG Support added to store special packet types at interrupt -// level (mostly responses to specific commands.) -// 0.08 -- 3/30/92 MAG Support added for STAT_MODEM packet -// 0.09 -- 6/24/93 MAG i2Link... needed to update number of boards BEFORE -// turning on the interrupt. -// 0.10 -- 6/25/93 MAG To avoid gruesome death from a bad board, we sanity check -// some incoming. -// -// 1.1 - 12/25/96 AKM Linux version. -// - 10/09/98 DMC Revised Linux version. -//------------------------------------------------------------------------------ - -//************ -//* Includes * -//************ - -#include -#include "i2lib.h" - - -//*********************** -//* Function Prototypes * -//*********************** -static void i2QueueNeeds(i2eBordStrPtr, i2ChanStrPtr, int); -static i2ChanStrPtr i2DeQueueNeeds(i2eBordStrPtr, int ); -static void i2StripFifo(i2eBordStrPtr); -static void i2StuffFifoBypass(i2eBordStrPtr); -static void i2StuffFifoFlow(i2eBordStrPtr); -static void i2StuffFifoInline(i2eBordStrPtr); -static int i2RetryFlushOutput(i2ChanStrPtr); - -// Not a documented part of the library routines (careful...) but the Diagnostic -// i2diag.c finds them useful to help the throughput in certain limited -// single-threaded operations. -static void iiSendPendingMail(i2eBordStrPtr); -static void serviceOutgoingFifo(i2eBordStrPtr); - -// Functions defined in ip2.c as part of interrupt handling -static void do_input(struct work_struct *); -static void do_status(struct work_struct *); - -//*************** -//* Debug Data * -//*************** -#ifdef DEBUG_FIFO - -unsigned char DBGBuf[0x4000]; -unsigned short I = 0; - -static void -WriteDBGBuf(char *s, unsigned char *src, unsigned short n ) -{ - char *p = src; - - // XXX: We need a spin lock here if we ever use this again - - while (*s) { // copy label - DBGBuf[I] = *s++; - I = I++ & 0x3fff; - } - while (n--) { // copy data - DBGBuf[I] = *p++; - I = I++ & 0x3fff; - } -} - -static void -fatality(i2eBordStrPtr pB ) -{ - int i; - - for (i=0;i= ' ' && DBGBuf[i] <= '~') { - printk(" %c ",DBGBuf[i]); - } else { - printk(" . "); - } - } - printk("\n"); - printk("Last index %x\n",I); -} -#endif /* DEBUG_FIFO */ - -//******** -//* Code * -//******** - -static inline int -i2Validate ( i2ChanStrPtr pCh ) -{ - //ip2trace(pCh->port_index, ITRC_VERIFY,ITRC_ENTER,2,pCh->validity, - // (CHANNEL_MAGIC | CHANNEL_SUPPORT)); - return ((pCh->validity & (CHANNEL_MAGIC_BITS | CHANNEL_SUPPORT)) - == (CHANNEL_MAGIC | CHANNEL_SUPPORT)); -} - -static void iiSendPendingMail_t(unsigned long data) -{ - i2eBordStrPtr pB = (i2eBordStrPtr)data; - - iiSendPendingMail(pB); -} - -//****************************************************************************** -// Function: iiSendPendingMail(pB) -// Parameters: Pointer to a board structure -// Returns: Nothing -// -// Description: -// If any outgoing mail bits are set and there is outgoing mailbox is empty, -// send the mail and clear the bits. -//****************************************************************************** -static void -iiSendPendingMail(i2eBordStrPtr pB) -{ - if (pB->i2eOutMailWaiting && (!pB->i2eWaitingForEmptyFifo) ) - { - if (iiTrySendMail(pB, pB->i2eOutMailWaiting)) - { - /* If we were already waiting for fifo to empty, - * or just sent MB_OUT_STUFFED, then we are - * still waiting for it to empty, until we should - * receive an MB_IN_STRIPPED from the board. - */ - pB->i2eWaitingForEmptyFifo |= - (pB->i2eOutMailWaiting & MB_OUT_STUFFED); - pB->i2eOutMailWaiting = 0; - pB->SendPendingRetry = 0; - } else { -/* The only time we hit this area is when "iiTrySendMail" has - failed. That only occurs when the outbound mailbox is - still busy with the last message. We take a short breather - to let the board catch up with itself and then try again. - 16 Retries is the limit - then we got a borked board. - /\/\|=mhw=|\/\/ */ - - if( ++pB->SendPendingRetry < 16 ) { - setup_timer(&pB->SendPendingTimer, - iiSendPendingMail_t, (unsigned long)pB); - mod_timer(&pB->SendPendingTimer, jiffies + 1); - } else { - printk( KERN_ERR "IP2: iiSendPendingMail unable to queue outbound mail\n" ); - } - } - } -} - -//****************************************************************************** -// Function: i2InitChannels(pB, nChannels, pCh) -// Parameters: Pointer to Ellis Board structure -// Number of channels to initialize -// Pointer to first element in an array of channel structures -// Returns: Success or failure -// -// Description: -// -// This function patches pointers, back-pointers, and initializes all the -// elements in the channel structure array. -// -// This should be run after the board structure is initialized, through having -// loaded the standard loadware (otherwise it complains). -// -// In any case, it must be done before any serious work begins initializing the -// irq's or sending commands... -// -//****************************************************************************** -static int -i2InitChannels ( i2eBordStrPtr pB, int nChannels, i2ChanStrPtr pCh) -{ - int index, stuffIndex; - i2ChanStrPtr *ppCh; - - if (pB->i2eValid != I2E_MAGIC) { - I2_COMPLETE(pB, I2EE_BADMAGIC); - } - if (pB->i2eState != II_STATE_STDLOADED) { - I2_COMPLETE(pB, I2EE_BADSTATE); - } - - rwlock_init(&pB->read_fifo_spinlock); - rwlock_init(&pB->write_fifo_spinlock); - rwlock_init(&pB->Dbuf_spinlock); - rwlock_init(&pB->Bbuf_spinlock); - rwlock_init(&pB->Fbuf_spinlock); - - // NO LOCK needed yet - this is init - - pB->i2eChannelPtr = pCh; - pB->i2eChannelCnt = nChannels; - - pB->i2Fbuf_strip = pB->i2Fbuf_stuff = 0; - pB->i2Dbuf_strip = pB->i2Dbuf_stuff = 0; - pB->i2Bbuf_strip = pB->i2Bbuf_stuff = 0; - - pB->SendPendingRetry = 0; - - memset ( pCh, 0, sizeof (i2ChanStr) * nChannels ); - - for (index = stuffIndex = 0, ppCh = (i2ChanStrPtr *)(pB->i2Fbuf); - nChannels && index < ABS_MOST_PORTS; - index++) - { - if ( !(pB->i2eChannelMap[index >> 4] & (1 << (index & 0xf)) ) ) { - continue; - } - rwlock_init(&pCh->Ibuf_spinlock); - rwlock_init(&pCh->Obuf_spinlock); - rwlock_init(&pCh->Cbuf_spinlock); - rwlock_init(&pCh->Pbuf_spinlock); - // NO LOCK needed yet - this is init - // Set up validity flag according to support level - if (pB->i2eGoodMap[index >> 4] & (1 << (index & 0xf)) ) { - pCh->validity = CHANNEL_MAGIC | CHANNEL_SUPPORT; - } else { - pCh->validity = CHANNEL_MAGIC; - } - pCh->pMyBord = pB; /* Back-pointer */ - - // Prepare an outgoing flow-control packet to send as soon as the chance - // occurs. - if ( pCh->validity & CHANNEL_SUPPORT ) { - pCh->infl.hd.i2sChannel = index; - pCh->infl.hd.i2sCount = 5; - pCh->infl.hd.i2sType = PTYPE_BYPASS; - pCh->infl.fcmd = 37; - pCh->infl.asof = 0; - pCh->infl.room = IBUF_SIZE - 1; - - pCh->whenSendFlow = (IBUF_SIZE/5)*4; // when 80% full - - // The following is similar to calling i2QueueNeeds, except that this - // is done in longhand, since we are setting up initial conditions on - // many channels at once. - pCh->channelNeeds = NEED_FLOW; // Since starting from scratch - pCh->sinceLastFlow = 0; // No bytes received since last flow - // control packet was queued - stuffIndex++; - *ppCh++ = pCh; // List this channel as needing - // initial flow control packet sent - } - - // Don't allow anything to be sent until the status packets come in from - // the board. - - pCh->outfl.asof = 0; - pCh->outfl.room = 0; - - // Initialize all the ring buffers - - pCh->Ibuf_stuff = pCh->Ibuf_strip = 0; - pCh->Obuf_stuff = pCh->Obuf_strip = 0; - pCh->Cbuf_stuff = pCh->Cbuf_strip = 0; - - memset( &pCh->icount, 0, sizeof (struct async_icount) ); - pCh->hotKeyIn = HOT_CLEAR; - pCh->channelOptions = 0; - pCh->bookMarks = 0; - init_waitqueue_head(&pCh->pBookmarkWait); - - init_waitqueue_head(&pCh->open_wait); - init_waitqueue_head(&pCh->close_wait); - init_waitqueue_head(&pCh->delta_msr_wait); - - // Set base and divisor so default custom rate is 9600 - pCh->BaudBase = 921600; // MAX for ST654, changed after we get - pCh->BaudDivisor = 96; // the boxids (UART types) later - - pCh->dataSetIn = 0; - pCh->dataSetOut = 0; - - pCh->wopen = 0; - pCh->throttled = 0; - - pCh->speed = CBR_9600; - - pCh->flags = 0; - - pCh->ClosingDelay = 5*HZ/10; - pCh->ClosingWaitTime = 30*HZ; - - // Initialize task queue objects - INIT_WORK(&pCh->tqueue_input, do_input); - INIT_WORK(&pCh->tqueue_status, do_status); - -#ifdef IP2DEBUG_TRACE - pCh->trace = ip2trace; -#endif - - ++pCh; - --nChannels; - } - // No need to check for wrap here; this is initialization. - pB->i2Fbuf_stuff = stuffIndex; - I2_COMPLETE(pB, I2EE_GOOD); - -} - -//****************************************************************************** -// Function: i2DeQueueNeeds(pB, type) -// Parameters: Pointer to a board structure -// type bit map: may include NEED_INLINE, NEED_BYPASS, or NEED_FLOW -// Returns: -// Pointer to a channel structure -// -// Description: Returns pointer struct of next channel that needs service of -// the type specified. Otherwise returns a NULL reference. -// -//****************************************************************************** -static i2ChanStrPtr -i2DeQueueNeeds(i2eBordStrPtr pB, int type) -{ - unsigned short queueIndex; - unsigned long flags; - - i2ChanStrPtr pCh = NULL; - - switch(type) { - - case NEED_INLINE: - - write_lock_irqsave(&pB->Dbuf_spinlock, flags); - if ( pB->i2Dbuf_stuff != pB->i2Dbuf_strip) - { - queueIndex = pB->i2Dbuf_strip; - pCh = pB->i2Dbuf[queueIndex]; - queueIndex++; - if (queueIndex >= CH_QUEUE_SIZE) { - queueIndex = 0; - } - pB->i2Dbuf_strip = queueIndex; - pCh->channelNeeds &= ~NEED_INLINE; - } - write_unlock_irqrestore(&pB->Dbuf_spinlock, flags); - break; - - case NEED_BYPASS: - - write_lock_irqsave(&pB->Bbuf_spinlock, flags); - if (pB->i2Bbuf_stuff != pB->i2Bbuf_strip) - { - queueIndex = pB->i2Bbuf_strip; - pCh = pB->i2Bbuf[queueIndex]; - queueIndex++; - if (queueIndex >= CH_QUEUE_SIZE) { - queueIndex = 0; - } - pB->i2Bbuf_strip = queueIndex; - pCh->channelNeeds &= ~NEED_BYPASS; - } - write_unlock_irqrestore(&pB->Bbuf_spinlock, flags); - break; - - case NEED_FLOW: - - write_lock_irqsave(&pB->Fbuf_spinlock, flags); - if (pB->i2Fbuf_stuff != pB->i2Fbuf_strip) - { - queueIndex = pB->i2Fbuf_strip; - pCh = pB->i2Fbuf[queueIndex]; - queueIndex++; - if (queueIndex >= CH_QUEUE_SIZE) { - queueIndex = 0; - } - pB->i2Fbuf_strip = queueIndex; - pCh->channelNeeds &= ~NEED_FLOW; - } - write_unlock_irqrestore(&pB->Fbuf_spinlock, flags); - break; - default: - printk(KERN_ERR "i2DeQueueNeeds called with bad type:%x\n",type); - break; - } - return pCh; -} - -//****************************************************************************** -// Function: i2QueueNeeds(pB, pCh, type) -// Parameters: Pointer to a board structure -// Pointer to a channel structure -// type bit map: may include NEED_INLINE, NEED_BYPASS, or NEED_FLOW -// Returns: Nothing -// -// Description: -// For each type of need selected, if the given channel is not already in the -// queue, adds it, and sets the flag indicating it is in the queue. -//****************************************************************************** -static void -i2QueueNeeds(i2eBordStrPtr pB, i2ChanStrPtr pCh, int type) -{ - unsigned short queueIndex; - unsigned long flags; - - // We turn off all the interrupts during this brief process, since the - // interrupt-level code might want to put things on the queue as well. - - switch (type) { - - case NEED_INLINE: - - write_lock_irqsave(&pB->Dbuf_spinlock, flags); - if ( !(pCh->channelNeeds & NEED_INLINE) ) - { - pCh->channelNeeds |= NEED_INLINE; - queueIndex = pB->i2Dbuf_stuff; - pB->i2Dbuf[queueIndex++] = pCh; - if (queueIndex >= CH_QUEUE_SIZE) - queueIndex = 0; - pB->i2Dbuf_stuff = queueIndex; - } - write_unlock_irqrestore(&pB->Dbuf_spinlock, flags); - break; - - case NEED_BYPASS: - - write_lock_irqsave(&pB->Bbuf_spinlock, flags); - if ((type & NEED_BYPASS) && !(pCh->channelNeeds & NEED_BYPASS)) - { - pCh->channelNeeds |= NEED_BYPASS; - queueIndex = pB->i2Bbuf_stuff; - pB->i2Bbuf[queueIndex++] = pCh; - if (queueIndex >= CH_QUEUE_SIZE) - queueIndex = 0; - pB->i2Bbuf_stuff = queueIndex; - } - write_unlock_irqrestore(&pB->Bbuf_spinlock, flags); - break; - - case NEED_FLOW: - - write_lock_irqsave(&pB->Fbuf_spinlock, flags); - if ((type & NEED_FLOW) && !(pCh->channelNeeds & NEED_FLOW)) - { - pCh->channelNeeds |= NEED_FLOW; - queueIndex = pB->i2Fbuf_stuff; - pB->i2Fbuf[queueIndex++] = pCh; - if (queueIndex >= CH_QUEUE_SIZE) - queueIndex = 0; - pB->i2Fbuf_stuff = queueIndex; - } - write_unlock_irqrestore(&pB->Fbuf_spinlock, flags); - break; - - case NEED_CREDIT: - pCh->channelNeeds |= NEED_CREDIT; - break; - default: - printk(KERN_ERR "i2QueueNeeds called with bad type:%x\n",type); - break; - } - return; -} - -//****************************************************************************** -// Function: i2QueueCommands(type, pCh, timeout, nCommands, pCs,...) -// Parameters: type - PTYPE_BYPASS or PTYPE_INLINE -// pointer to the channel structure -// maximum period to wait -// number of commands (n) -// n commands -// Returns: Number of commands sent, or -1 for error -// -// get board lock before calling -// -// Description: -// Queues up some commands to be sent to a channel. To send possibly several -// bypass or inline commands to the given channel. The timeout parameter -// indicates how many HUNDREDTHS OF SECONDS to wait until there is room: -// 0 = return immediately if no room, -ive = wait forever, +ive = number of -// 1/100 seconds to wait. Return values: -// -1 Some kind of nasty error: bad channel structure or invalid arguments. -// 0 No room to send all the commands -// (+) Number of commands sent -//****************************************************************************** -static int -i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands, - cmdSyntaxPtr pCs0,...) -{ - int totalsize = 0; - int blocksize; - int lastended; - cmdSyntaxPtr *ppCs; - cmdSyntaxPtr pCs; - int count; - int flag; - i2eBordStrPtr pB; - - unsigned short maxBlock; - unsigned short maxBuff; - short bufroom; - unsigned short stuffIndex; - unsigned char *pBuf; - unsigned char *pInsert; - unsigned char *pDest, *pSource; - unsigned short channel; - int cnt; - unsigned long flags = 0; - rwlock_t *lock_var_p = NULL; - - // Make sure the channel exists, otherwise do nothing - if ( !i2Validate ( pCh ) ) { - return -1; - } - - ip2trace (CHANN, ITRC_QUEUE, ITRC_ENTER, 0 ); - - pB = pCh->pMyBord; - - // Board must also exist, and THE INTERRUPT COMMAND ALREADY SENT - if (pB->i2eValid != I2E_MAGIC || pB->i2eUsingIrq == I2_IRQ_UNDEFINED) - return -2; - // If the board has gone fatal, return bad, and also hit the trap routine if - // it exists. - if (pB->i2eFatal) { - if ( pB->i2eFatalTrap ) { - (*(pB)->i2eFatalTrap)(pB); - } - return -3; - } - // Set up some variables, Which buffers are we using? How big are they? - switch(type) - { - case PTYPE_INLINE: - flag = INL; - maxBlock = MAX_OBUF_BLOCK; - maxBuff = OBUF_SIZE; - pBuf = pCh->Obuf; - break; - case PTYPE_BYPASS: - flag = BYP; - maxBlock = MAX_CBUF_BLOCK; - maxBuff = CBUF_SIZE; - pBuf = pCh->Cbuf; - break; - default: - return -4; - } - // Determine the total size required for all the commands - totalsize = blocksize = sizeof(i2CmdHeader); - lastended = 0; - ppCs = &pCs0; - for ( count = nCommands; count; count--, ppCs++) - { - pCs = *ppCs; - cnt = pCs->length; - // Will a new block be needed for this one? - // Two possible reasons: too - // big or previous command has to be at the end of a packet. - if ((blocksize + cnt > maxBlock) || lastended) { - blocksize = sizeof(i2CmdHeader); - totalsize += sizeof(i2CmdHeader); - } - totalsize += cnt; - blocksize += cnt; - - // If this command had to end a block, then we will make sure to - // account for it should there be any more blocks. - lastended = pCs->flags & END; - } - for (;;) { - // Make sure any pending flush commands go out before we add more data. - if ( !( pCh->flush_flags && i2RetryFlushOutput( pCh ) ) ) { - // How much room (this time through) ? - switch(type) { - case PTYPE_INLINE: - lock_var_p = &pCh->Obuf_spinlock; - write_lock_irqsave(lock_var_p, flags); - stuffIndex = pCh->Obuf_stuff; - bufroom = pCh->Obuf_strip - stuffIndex; - break; - case PTYPE_BYPASS: - lock_var_p = &pCh->Cbuf_spinlock; - write_lock_irqsave(lock_var_p, flags); - stuffIndex = pCh->Cbuf_stuff; - bufroom = pCh->Cbuf_strip - stuffIndex; - break; - default: - return -5; - } - if (--bufroom < 0) { - bufroom += maxBuff; - } - - ip2trace (CHANN, ITRC_QUEUE, 2, 1, bufroom ); - - // Check for overflow - if (totalsize <= bufroom) { - // Normal Expected path - We still hold LOCK - break; /* from for()- Enough room: goto proceed */ - } - ip2trace(CHANN, ITRC_QUEUE, 3, 1, totalsize); - write_unlock_irqrestore(lock_var_p, flags); - } else - ip2trace(CHANN, ITRC_QUEUE, 3, 1, totalsize); - - /* Prepare to wait for buffers to empty */ - serviceOutgoingFifo(pB); // Dump what we got - - if (timeout == 0) { - return 0; // Tired of waiting - } - if (timeout > 0) - timeout--; // So negative values == forever - - if (!in_interrupt()) { - schedule_timeout_interruptible(1); // short nap - } else { - // we cannot sched/sleep in interrupt silly - return 0; - } - if (signal_pending(current)) { - return 0; // Wake up! Time to die!!! - } - - ip2trace (CHANN, ITRC_QUEUE, 4, 0 ); - - } // end of for(;;) - - // At this point we have room and the lock - stick them in. - channel = pCh->infl.hd.i2sChannel; - pInsert = &pBuf[stuffIndex]; // Pointer to start of packet - pDest = CMD_OF(pInsert); // Pointer to start of command - - // When we start counting, the block is the size of the header - for (blocksize = sizeof(i2CmdHeader), count = nCommands, - lastended = 0, ppCs = &pCs0; - count; - count--, ppCs++) - { - pCs = *ppCs; // Points to command protocol structure - - // If this is a bookmark request command, post the fact that a bookmark - // request is pending. NOTE THIS TRICK ONLY WORKS BECAUSE CMD_BMARK_REQ - // has no parameters! The more general solution would be to reference - // pCs->cmd[0]. - if (pCs == CMD_BMARK_REQ) { - pCh->bookMarks++; - - ip2trace (CHANN, ITRC_DRAIN, 30, 1, pCh->bookMarks ); - - } - cnt = pCs->length; - - // If this command would put us over the maximum block size or - // if the last command had to be at the end of a block, we end - // the existing block here and start a new one. - if ((blocksize + cnt > maxBlock) || lastended) { - - ip2trace (CHANN, ITRC_QUEUE, 5, 0 ); - - PTYPE_OF(pInsert) = type; - CHANNEL_OF(pInsert) = channel; - // count here does not include the header - CMD_COUNT_OF(pInsert) = blocksize - sizeof(i2CmdHeader); - stuffIndex += blocksize; - if(stuffIndex >= maxBuff) { - stuffIndex = 0; - pInsert = pBuf; - } - pInsert = &pBuf[stuffIndex]; // Pointer to start of next pkt - pDest = CMD_OF(pInsert); - blocksize = sizeof(i2CmdHeader); - } - // Now we know there is room for this one in the current block - - blocksize += cnt; // Total bytes in this command - pSource = pCs->cmd; // Copy the command into the buffer - while (cnt--) { - *pDest++ = *pSource++; - } - // If this command had to end a block, then we will make sure to account - // for it should there be any more blocks. - lastended = pCs->flags & END; - } // end for - // Clean up the final block by writing header, etc - - PTYPE_OF(pInsert) = type; - CHANNEL_OF(pInsert) = channel; - // count here does not include the header - CMD_COUNT_OF(pInsert) = blocksize - sizeof(i2CmdHeader); - stuffIndex += blocksize; - if(stuffIndex >= maxBuff) { - stuffIndex = 0; - pInsert = pBuf; - } - // Updates the index, and post the need for service. When adding these to - // the queue of channels, we turn off the interrupt while doing so, - // because at interrupt level we might want to push a channel back to the - // end of the queue. - switch(type) - { - case PTYPE_INLINE: - pCh->Obuf_stuff = stuffIndex; // Store buffer pointer - write_unlock_irqrestore(&pCh->Obuf_spinlock, flags); - - pB->debugInlineQueued++; - // Add the channel pointer to list of channels needing service (first - // come...), if it's not already there. - i2QueueNeeds(pB, pCh, NEED_INLINE); - break; - - case PTYPE_BYPASS: - pCh->Cbuf_stuff = stuffIndex; // Store buffer pointer - write_unlock_irqrestore(&pCh->Cbuf_spinlock, flags); - - pB->debugBypassQueued++; - // Add the channel pointer to list of channels needing service (first - // come...), if it's not already there. - i2QueueNeeds(pB, pCh, NEED_BYPASS); - break; - } - - ip2trace (CHANN, ITRC_QUEUE, ITRC_RETURN, 1, nCommands ); - - return nCommands; // Good status: number of commands sent -} - -//****************************************************************************** -// Function: i2GetStatus(pCh,resetBits) -// Parameters: Pointer to a channel structure -// Bit map of status bits to clear -// Returns: Bit map of current status bits -// -// Description: -// Returns the state of data set signals, and whether a break has been received, -// (see i2lib.h for bit-mapped result). resetBits is a bit-map of any status -// bits to be cleared: I2_BRK, I2_PAR, I2_FRA, I2_OVR,... These are cleared -// AFTER the condition is passed. If pCh does not point to a valid channel, -// returns -1 (which would be impossible otherwise. -//****************************************************************************** -static int -i2GetStatus(i2ChanStrPtr pCh, int resetBits) -{ - unsigned short status; - i2eBordStrPtr pB; - - ip2trace (CHANN, ITRC_STATUS, ITRC_ENTER, 2, pCh->dataSetIn, resetBits ); - - // Make sure the channel exists, otherwise do nothing */ - if ( !i2Validate ( pCh ) ) - return -1; - - pB = pCh->pMyBord; - - status = pCh->dataSetIn; - - // Clear any specified error bits: but note that only actual error bits can - // be cleared, regardless of the value passed. - if (resetBits) - { - pCh->dataSetIn &= ~(resetBits & (I2_BRK | I2_PAR | I2_FRA | I2_OVR)); - pCh->dataSetIn &= ~(I2_DDCD | I2_DCTS | I2_DDSR | I2_DRI); - } - - ip2trace (CHANN, ITRC_STATUS, ITRC_RETURN, 1, pCh->dataSetIn ); - - return status; -} - -//****************************************************************************** -// Function: i2Input(pChpDest,count) -// Parameters: Pointer to a channel structure -// Pointer to data buffer -// Number of bytes to read -// Returns: Number of bytes read, or -1 for error -// -// Description: -// Strips data from the input buffer and writes it to pDest. If there is a -// collosal blunder, (invalid structure pointers or the like), returns -1. -// Otherwise, returns the number of bytes read. -//****************************************************************************** -static int -i2Input(i2ChanStrPtr pCh) -{ - int amountToMove; - unsigned short stripIndex; - int count; - unsigned long flags = 0; - - ip2trace (CHANN, ITRC_INPUT, ITRC_ENTER, 0); - - // Ensure channel structure seems real - if ( !i2Validate( pCh ) ) { - count = -1; - goto i2Input_exit; - } - write_lock_irqsave(&pCh->Ibuf_spinlock, flags); - - // initialize some accelerators and private copies - stripIndex = pCh->Ibuf_strip; - - count = pCh->Ibuf_stuff - stripIndex; - - // If buffer is empty or requested data count was 0, (trivial case) return - // without any further thought. - if ( count == 0 ) { - write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); - goto i2Input_exit; - } - // Adjust for buffer wrap - if ( count < 0 ) { - count += IBUF_SIZE; - } - // Don't give more than can be taken by the line discipline - amountToMove = pCh->pTTY->receive_room; - if (count > amountToMove) { - count = amountToMove; - } - // How much could we copy without a wrap? - amountToMove = IBUF_SIZE - stripIndex; - - if (amountToMove > count) { - amountToMove = count; - } - // Move the first block - pCh->pTTY->ldisc->ops->receive_buf( pCh->pTTY, - &(pCh->Ibuf[stripIndex]), NULL, amountToMove ); - // If we needed to wrap, do the second data move - if (count > amountToMove) { - pCh->pTTY->ldisc->ops->receive_buf( pCh->pTTY, - pCh->Ibuf, NULL, count - amountToMove ); - } - // Bump and wrap the stripIndex all at once by the amount of data read. This - // method is good regardless of whether the data was in one or two pieces. - stripIndex += count; - if (stripIndex >= IBUF_SIZE) { - stripIndex -= IBUF_SIZE; - } - pCh->Ibuf_strip = stripIndex; - - // Update our flow control information and possibly queue ourselves to send - // it, depending on how much data has been stripped since the last time a - // packet was sent. - pCh->infl.asof += count; - - if ((pCh->sinceLastFlow += count) >= pCh->whenSendFlow) { - pCh->sinceLastFlow -= pCh->whenSendFlow; - write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); - i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW); - } else { - write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); - } - -i2Input_exit: - - ip2trace (CHANN, ITRC_INPUT, ITRC_RETURN, 1, count); - - return count; -} - -//****************************************************************************** -// Function: i2InputFlush(pCh) -// Parameters: Pointer to a channel structure -// Returns: Number of bytes stripped, or -1 for error -// -// Description: -// Strips any data from the input buffer. If there is a collosal blunder, -// (invalid structure pointers or the like), returns -1. Otherwise, returns the -// number of bytes stripped. -//****************************************************************************** -static int -i2InputFlush(i2ChanStrPtr pCh) -{ - int count; - unsigned long flags; - - // Ensure channel structure seems real - if ( !i2Validate ( pCh ) ) - return -1; - - ip2trace (CHANN, ITRC_INPUT, 10, 0); - - write_lock_irqsave(&pCh->Ibuf_spinlock, flags); - count = pCh->Ibuf_stuff - pCh->Ibuf_strip; - - // Adjust for buffer wrap - if (count < 0) { - count += IBUF_SIZE; - } - - // Expedient way to zero out the buffer - pCh->Ibuf_strip = pCh->Ibuf_stuff; - - - // Update our flow control information and possibly queue ourselves to send - // it, depending on how much data has been stripped since the last time a - // packet was sent. - - pCh->infl.asof += count; - - if ( (pCh->sinceLastFlow += count) >= pCh->whenSendFlow ) - { - pCh->sinceLastFlow -= pCh->whenSendFlow; - write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); - i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW); - } else { - write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); - } - - ip2trace (CHANN, ITRC_INPUT, 19, 1, count); - - return count; -} - -//****************************************************************************** -// Function: i2InputAvailable(pCh) -// Parameters: Pointer to a channel structure -// Returns: Number of bytes available, or -1 for error -// -// Description: -// If there is a collosal blunder, (invalid structure pointers or the like), -// returns -1. Otherwise, returns the number of bytes stripped. Otherwise, -// returns the number of bytes available in the buffer. -//****************************************************************************** -#if 0 -static int -i2InputAvailable(i2ChanStrPtr pCh) -{ - int count; - - // Ensure channel structure seems real - if ( !i2Validate ( pCh ) ) return -1; - - - // initialize some accelerators and private copies - read_lock_irqsave(&pCh->Ibuf_spinlock, flags); - count = pCh->Ibuf_stuff - pCh->Ibuf_strip; - read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); - - // Adjust for buffer wrap - if (count < 0) - { - count += IBUF_SIZE; - } - - return count; -} -#endif - -//****************************************************************************** -// Function: i2Output(pCh, pSource, count) -// Parameters: Pointer to channel structure -// Pointer to source data -// Number of bytes to send -// Returns: Number of bytes sent, or -1 for error -// -// Description: -// Queues the data at pSource to be sent as data packets to the board. If there -// is a collosal blunder, (invalid structure pointers or the like), returns -1. -// Otherwise, returns the number of bytes written. What if there is not enough -// room for all the data? If pCh->channelOptions & CO_NBLOCK_WRITE is set, then -// we transfer as many characters as we can now, then return. If this bit is -// clear (default), routine will spin along until all the data is buffered. -// Should this occur, the 1-ms delay routine is called while waiting to avoid -// applications that one cannot break out of. -//****************************************************************************** -static int -i2Output(i2ChanStrPtr pCh, const char *pSource, int count) -{ - i2eBordStrPtr pB; - unsigned char *pInsert; - int amountToMove; - int countOriginal = count; - unsigned short channel; - unsigned short stuffIndex; - unsigned long flags; - - int bailout = 10; - - ip2trace (CHANN, ITRC_OUTPUT, ITRC_ENTER, 2, count, 0 ); - - // Ensure channel structure seems real - if ( !i2Validate ( pCh ) ) - return -1; - - // initialize some accelerators and private copies - pB = pCh->pMyBord; - channel = pCh->infl.hd.i2sChannel; - - // If the board has gone fatal, return bad, and also hit the trap routine if - // it exists. - if (pB->i2eFatal) { - if (pB->i2eFatalTrap) { - (*(pB)->i2eFatalTrap)(pB); - } - return -1; - } - // Proceed as though we would do everything - while ( count > 0 ) { - - // How much room in output buffer is there? - read_lock_irqsave(&pCh->Obuf_spinlock, flags); - amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1; - read_unlock_irqrestore(&pCh->Obuf_spinlock, flags); - if (amountToMove < 0) { - amountToMove += OBUF_SIZE; - } - // Subtract off the headers size and see how much room there is for real - // data. If this is negative, we will discover later. - amountToMove -= sizeof (i2DataHeader); - - // Don't move more (now) than can go in a single packet - if ( amountToMove > (int)(MAX_OBUF_BLOCK - sizeof(i2DataHeader)) ) { - amountToMove = MAX_OBUF_BLOCK - sizeof(i2DataHeader); - } - // Don't move more than the count we were given - if (amountToMove > count) { - amountToMove = count; - } - // Now we know how much we must move: NB because the ring buffers have - // an overflow area at the end, we needn't worry about wrapping in the - // middle of a packet. - -// Small WINDOW here with no LOCK but I can't call Flush with LOCK -// We would be flushing (or ending flush) anyway - - ip2trace (CHANN, ITRC_OUTPUT, 10, 1, amountToMove ); - - if ( !(pCh->flush_flags && i2RetryFlushOutput(pCh) ) - && amountToMove > 0 ) - { - write_lock_irqsave(&pCh->Obuf_spinlock, flags); - stuffIndex = pCh->Obuf_stuff; - - // Had room to move some data: don't know whether the block size, - // buffer space, or what was the limiting factor... - pInsert = &(pCh->Obuf[stuffIndex]); - - // Set up the header - CHANNEL_OF(pInsert) = channel; - PTYPE_OF(pInsert) = PTYPE_DATA; - TAG_OF(pInsert) = 0; - ID_OF(pInsert) = ID_ORDINARY_DATA; - DATA_COUNT_OF(pInsert) = amountToMove; - - // Move the data - memcpy( (char*)(DATA_OF(pInsert)), pSource, amountToMove ); - // Adjust pointers and indices - pSource += amountToMove; - pCh->Obuf_char_count += amountToMove; - stuffIndex += amountToMove + sizeof(i2DataHeader); - count -= amountToMove; - - if (stuffIndex >= OBUF_SIZE) { - stuffIndex = 0; - } - pCh->Obuf_stuff = stuffIndex; - - write_unlock_irqrestore(&pCh->Obuf_spinlock, flags); - - ip2trace (CHANN, ITRC_OUTPUT, 13, 1, stuffIndex ); - - } else { - - // Cannot move data - // becuz we need to stuff a flush - // or amount to move is <= 0 - - ip2trace(CHANN, ITRC_OUTPUT, 14, 3, - amountToMove, pB->i2eFifoRemains, - pB->i2eWaitingForEmptyFifo ); - - // Put this channel back on queue - // this ultimatly gets more data or wakes write output - i2QueueNeeds(pB, pCh, NEED_INLINE); - - if ( pB->i2eWaitingForEmptyFifo ) { - - ip2trace (CHANN, ITRC_OUTPUT, 16, 0 ); - - // or schedule - if (!in_interrupt()) { - - ip2trace (CHANN, ITRC_OUTPUT, 61, 0 ); - - schedule_timeout_interruptible(2); - if (signal_pending(current)) { - break; - } - continue; - } else { - - ip2trace (CHANN, ITRC_OUTPUT, 62, 0 ); - - // let interrupt in = WAS restore_flags() - // We hold no lock nor is irq off anymore??? - - break; - } - break; // from while(count) - } - else if ( pB->i2eFifoRemains < 32 && !pB->i2eTxMailEmpty ( pB ) ) - { - ip2trace (CHANN, ITRC_OUTPUT, 19, 2, - pB->i2eFifoRemains, - pB->i2eTxMailEmpty ); - - break; // from while(count) - } else if ( pCh->channelNeeds & NEED_CREDIT ) { - - ip2trace (CHANN, ITRC_OUTPUT, 22, 0 ); - - break; // from while(count) - } else if ( --bailout) { - - // Try to throw more things (maybe not us) in the fifo if we're - // not already waiting for it. - - ip2trace (CHANN, ITRC_OUTPUT, 20, 0 ); - - serviceOutgoingFifo(pB); - //break; CONTINUE; - } else { - ip2trace (CHANN, ITRC_OUTPUT, 21, 3, - pB->i2eFifoRemains, - pB->i2eOutMailWaiting, - pB->i2eWaitingForEmptyFifo ); - - break; // from while(count) - } - } - } // End of while(count) - - i2QueueNeeds(pB, pCh, NEED_INLINE); - - // We drop through either when the count expires, or when there is some - // count left, but there was a non-blocking write. - if (countOriginal > count) { - - ip2trace (CHANN, ITRC_OUTPUT, 17, 2, countOriginal, count ); - - serviceOutgoingFifo( pB ); - } - - ip2trace (CHANN, ITRC_OUTPUT, ITRC_RETURN, 2, countOriginal, count ); - - return countOriginal - count; -} - -//****************************************************************************** -// Function: i2FlushOutput(pCh) -// Parameters: Pointer to a channel structure -// Returns: Nothing -// -// Description: -// Sends bypass command to start flushing (waiting possibly forever until there -// is room), then sends inline command to stop flushing output, (again waiting -// possibly forever). -//****************************************************************************** -static inline void -i2FlushOutput(i2ChanStrPtr pCh) -{ - - ip2trace (CHANN, ITRC_FLUSH, 1, 1, pCh->flush_flags ); - - if (pCh->flush_flags) - return; - - if ( 1 != i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_STARTFL) ) { - pCh->flush_flags = STARTFL_FLAG; // Failed - flag for later - - ip2trace (CHANN, ITRC_FLUSH, 2, 0 ); - - } else if ( 1 != i2QueueCommands(PTYPE_INLINE, pCh, 0, 1, CMD_STOPFL) ) { - pCh->flush_flags = STOPFL_FLAG; // Failed - flag for later - - ip2trace (CHANN, ITRC_FLUSH, 3, 0 ); - } -} - -static int -i2RetryFlushOutput(i2ChanStrPtr pCh) -{ - int old_flags = pCh->flush_flags; - - ip2trace (CHANN, ITRC_FLUSH, 14, 1, old_flags ); - - pCh->flush_flags = 0; // Clear flag so we can avoid recursion - // and queue the commands - - if ( old_flags & STARTFL_FLAG ) { - if ( 1 == i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_STARTFL) ) { - old_flags = STOPFL_FLAG; //Success - send stop flush - } else { - old_flags = STARTFL_FLAG; //Failure - Flag for retry later - } - - ip2trace (CHANN, ITRC_FLUSH, 15, 1, old_flags ); - - } - if ( old_flags & STOPFL_FLAG ) { - if (1 == i2QueueCommands(PTYPE_INLINE, pCh, 0, 1, CMD_STOPFL)) { - old_flags = 0; // Success - clear flags - } - - ip2trace (CHANN, ITRC_FLUSH, 16, 1, old_flags ); - } - pCh->flush_flags = old_flags; - - ip2trace (CHANN, ITRC_FLUSH, 17, 1, old_flags ); - - return old_flags; -} - -//****************************************************************************** -// Function: i2DrainOutput(pCh,timeout) -// Parameters: Pointer to a channel structure -// Maximum period to wait -// Returns: ? -// -// Description: -// Uses the bookmark request command to ask the board to send a bookmark back as -// soon as all the data is completely sent. -//****************************************************************************** -static void -i2DrainWakeup(unsigned long d) -{ - i2ChanStrPtr pCh = (i2ChanStrPtr)d; - - ip2trace (CHANN, ITRC_DRAIN, 10, 1, pCh->BookmarkTimer.expires ); - - pCh->BookmarkTimer.expires = 0; - wake_up_interruptible( &pCh->pBookmarkWait ); -} - -static void -i2DrainOutput(i2ChanStrPtr pCh, int timeout) -{ - wait_queue_t wait; - i2eBordStrPtr pB; - - ip2trace (CHANN, ITRC_DRAIN, ITRC_ENTER, 1, pCh->BookmarkTimer.expires); - - pB = pCh->pMyBord; - // If the board has gone fatal, return bad, - // and also hit the trap routine if it exists. - if (pB->i2eFatal) { - if (pB->i2eFatalTrap) { - (*(pB)->i2eFatalTrap)(pB); - } - return; - } - if ((timeout > 0) && (pCh->BookmarkTimer.expires == 0 )) { - // One per customer (channel) - setup_timer(&pCh->BookmarkTimer, i2DrainWakeup, - (unsigned long)pCh); - - ip2trace (CHANN, ITRC_DRAIN, 1, 1, pCh->BookmarkTimer.expires ); - - mod_timer(&pCh->BookmarkTimer, jiffies + timeout); - } - - i2QueueCommands( PTYPE_INLINE, pCh, -1, 1, CMD_BMARK_REQ ); - - init_waitqueue_entry(&wait, current); - add_wait_queue(&(pCh->pBookmarkWait), &wait); - set_current_state( TASK_INTERRUPTIBLE ); - - serviceOutgoingFifo( pB ); - - schedule(); // Now we take our interruptible sleep on - - // Clean up the queue - set_current_state( TASK_RUNNING ); - remove_wait_queue(&(pCh->pBookmarkWait), &wait); - - // if expires == 0 then timer poped, then do not need to del_timer - if ((timeout > 0) && pCh->BookmarkTimer.expires && - time_before(jiffies, pCh->BookmarkTimer.expires)) { - del_timer( &(pCh->BookmarkTimer) ); - pCh->BookmarkTimer.expires = 0; - - ip2trace (CHANN, ITRC_DRAIN, 3, 1, pCh->BookmarkTimer.expires ); - - } - ip2trace (CHANN, ITRC_DRAIN, ITRC_RETURN, 1, pCh->BookmarkTimer.expires ); - return; -} - -//****************************************************************************** -// Function: i2OutputFree(pCh) -// Parameters: Pointer to a channel structure -// Returns: Space in output buffer -// -// Description: -// Returns -1 if very gross error. Otherwise returns the amount of bytes still -// free in the output buffer. -//****************************************************************************** -static int -i2OutputFree(i2ChanStrPtr pCh) -{ - int amountToMove; - unsigned long flags; - - // Ensure channel structure seems real - if ( !i2Validate ( pCh ) ) { - return -1; - } - read_lock_irqsave(&pCh->Obuf_spinlock, flags); - amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1; - read_unlock_irqrestore(&pCh->Obuf_spinlock, flags); - - if (amountToMove < 0) { - amountToMove += OBUF_SIZE; - } - // If this is negative, we will discover later - amountToMove -= sizeof(i2DataHeader); - - return (amountToMove < 0) ? 0 : amountToMove; -} -static void - -ip2_owake( PTTY tp) -{ - i2ChanStrPtr pCh; - - if (tp == NULL) return; - - pCh = tp->driver_data; - - ip2trace (CHANN, ITRC_SICMD, 10, 2, tp->flags, - (1 << TTY_DO_WRITE_WAKEUP) ); - - tty_wakeup(tp); -} - -static inline void -set_baud_params(i2eBordStrPtr pB) -{ - int i,j; - i2ChanStrPtr *pCh; - - pCh = (i2ChanStrPtr *) pB->i2eChannelPtr; - - for (i = 0; i < ABS_MAX_BOXES; i++) { - if (pB->channelBtypes.bid_value[i]) { - if (BID_HAS_654(pB->channelBtypes.bid_value[i])) { - for (j = 0; j < ABS_BIGGEST_BOX; j++) { - if (pCh[i*16+j] == NULL) - break; - (pCh[i*16+j])->BaudBase = 921600; // MAX for ST654 - (pCh[i*16+j])->BaudDivisor = 96; - } - } else { // has cirrus cd1400 - for (j = 0; j < ABS_BIGGEST_BOX; j++) { - if (pCh[i*16+j] == NULL) - break; - (pCh[i*16+j])->BaudBase = 115200; // MAX for CD1400 - (pCh[i*16+j])->BaudDivisor = 12; - } - } - } - } -} - -//****************************************************************************** -// Function: i2StripFifo(pB) -// Parameters: Pointer to a board structure -// Returns: ? -// -// Description: -// Strips all the available data from the incoming FIFO, identifies the type of -// packet, and either buffers the data or does what needs to be done. -// -// Note there is no overflow checking here: if the board sends more data than it -// ought to, we will not detect it here, but blindly overflow... -//****************************************************************************** - -// A buffer for reading in blocks for unknown channels -static unsigned char junkBuffer[IBUF_SIZE]; - -// A buffer to read in a status packet. Because of the size of the count field -// for these things, the maximum packet size must be less than MAX_CMD_PACK_SIZE -static unsigned char cmdBuffer[MAX_CMD_PACK_SIZE + 4]; - -// This table changes the bit order from MSR order given by STAT_MODEM packet to -// status bits used in our library. -static char xlatDss[16] = { -0 | 0 | 0 | 0 , -0 | 0 | 0 | I2_CTS , -0 | 0 | I2_DSR | 0 , -0 | 0 | I2_DSR | I2_CTS , -0 | I2_RI | 0 | 0 , -0 | I2_RI | 0 | I2_CTS , -0 | I2_RI | I2_DSR | 0 , -0 | I2_RI | I2_DSR | I2_CTS , -I2_DCD | 0 | 0 | 0 , -I2_DCD | 0 | 0 | I2_CTS , -I2_DCD | 0 | I2_DSR | 0 , -I2_DCD | 0 | I2_DSR | I2_CTS , -I2_DCD | I2_RI | 0 | 0 , -I2_DCD | I2_RI | 0 | I2_CTS , -I2_DCD | I2_RI | I2_DSR | 0 , -I2_DCD | I2_RI | I2_DSR | I2_CTS }; - -static inline void -i2StripFifo(i2eBordStrPtr pB) -{ - i2ChanStrPtr pCh; - int channel; - int count; - unsigned short stuffIndex; - int amountToRead; - unsigned char *pc, *pcLimit; - unsigned char uc; - unsigned char dss_change; - unsigned long bflags,cflags; - -// ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_ENTER, 0 ); - - while (I2_HAS_INPUT(pB)) { -// ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 2, 0 ); - - // Process packet from fifo a one atomic unit - write_lock_irqsave(&pB->read_fifo_spinlock, bflags); - - // The first word (or two bytes) will have channel number and type of - // packet, possibly other information - pB->i2eLeadoffWord[0] = iiReadWord(pB); - - switch(PTYPE_OF(pB->i2eLeadoffWord)) - { - case PTYPE_DATA: - pB->got_input = 1; - -// ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 3, 0 ); - - channel = CHANNEL_OF(pB->i2eLeadoffWord); /* Store channel */ - count = iiReadWord(pB); /* Count is in the next word */ - -// NEW: Check the count for sanity! Should the hardware fail, our death -// is more pleasant. While an oversize channel is acceptable (just more -// than the driver supports), an over-length count clearly means we are -// sick! - if ( ((unsigned int)count) > IBUF_SIZE ) { - pB->i2eFatal = 2; - write_unlock_irqrestore(&pB->read_fifo_spinlock, - bflags); - return; /* Bail out ASAP */ - } - // Channel is illegally big ? - if ((channel >= pB->i2eChannelCnt) || - (NULL==(pCh = ((i2ChanStrPtr*)pB->i2eChannelPtr)[channel]))) - { - iiReadBuf(pB, junkBuffer, count); - write_unlock_irqrestore(&pB->read_fifo_spinlock, - bflags); - break; /* From switch: ready for next packet */ - } - - // Channel should be valid, then - - // If this is a hot-key, merely post its receipt for now. These are - // always supposed to be 1-byte packets, so we won't even check the - // count. Also we will post an acknowledgement to the board so that - // more data can be forthcoming. Note that we are not trying to use - // these sequences in this driver, merely to robustly ignore them. - if(ID_OF(pB->i2eLeadoffWord) == ID_HOT_KEY) - { - pCh->hotKeyIn = iiReadWord(pB) & 0xff; - write_unlock_irqrestore(&pB->read_fifo_spinlock, - bflags); - i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_HOTACK); - break; /* From the switch: ready for next packet */ - } - - // Normal data! We crudely assume there is room for the data in our - // buffer because the board wouldn't have exceeded his credit limit. - write_lock_irqsave(&pCh->Ibuf_spinlock, cflags); - // We have 2 locks now - stuffIndex = pCh->Ibuf_stuff; - amountToRead = IBUF_SIZE - stuffIndex; - if (amountToRead > count) - amountToRead = count; - - // stuffIndex would have been already adjusted so there would - // always be room for at least one, and count is always at least - // one. - - iiReadBuf(pB, &(pCh->Ibuf[stuffIndex]), amountToRead); - pCh->icount.rx += amountToRead; - - // Update the stuffIndex by the amount of data moved. Note we could - // never ask for more data than would just fit. However, we might - // have read in one more byte than we wanted because the read - // rounds up to even bytes. If this byte is on the end of the - // packet, and is padding, we ignore it. If the byte is part of - // the actual data, we need to move it. - - stuffIndex += amountToRead; - - if (stuffIndex >= IBUF_SIZE) { - if ((amountToRead & 1) && (count > amountToRead)) { - pCh->Ibuf[0] = pCh->Ibuf[IBUF_SIZE]; - amountToRead++; - stuffIndex = 1; - } else { - stuffIndex = 0; - } - } - - // If there is anything left over, read it as well - if (count > amountToRead) { - amountToRead = count - amountToRead; - iiReadBuf(pB, &(pCh->Ibuf[stuffIndex]), amountToRead); - pCh->icount.rx += amountToRead; - stuffIndex += amountToRead; - } - - // Update stuff index - pCh->Ibuf_stuff = stuffIndex; - write_unlock_irqrestore(&pCh->Ibuf_spinlock, cflags); - write_unlock_irqrestore(&pB->read_fifo_spinlock, - bflags); - -#ifdef USE_IQ - schedule_work(&pCh->tqueue_input); -#else - do_input(&pCh->tqueue_input); -#endif - - // Note we do not need to maintain any flow-control credits at this - // time: if we were to increment .asof and decrement .room, there - // would be no net effect. Instead, when we strip data, we will - // increment .asof and leave .room unchanged. - - break; // From switch: ready for next packet - - case PTYPE_STATUS: - ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 4, 0 ); - - count = CMD_COUNT_OF(pB->i2eLeadoffWord); - - iiReadBuf(pB, cmdBuffer, count); - // We can release early with buffer grab - write_unlock_irqrestore(&pB->read_fifo_spinlock, - bflags); - - pc = cmdBuffer; - pcLimit = &(cmdBuffer[count]); - - while (pc < pcLimit) { - channel = *pc++; - - ip2trace (channel, ITRC_SFIFO, 7, 2, channel, *pc ); - - /* check for valid channel */ - if (channel < pB->i2eChannelCnt - && - (pCh = (((i2ChanStrPtr*)pB->i2eChannelPtr)[channel])) != NULL - ) - { - dss_change = 0; - - switch (uc = *pc++) - { - /* Breaks and modem signals are easy: just update status */ - case STAT_CTS_UP: - if ( !(pCh->dataSetIn & I2_CTS) ) - { - pCh->dataSetIn |= I2_DCTS; - pCh->icount.cts++; - dss_change = 1; - } - pCh->dataSetIn |= I2_CTS; - break; - - case STAT_CTS_DN: - if ( pCh->dataSetIn & I2_CTS ) - { - pCh->dataSetIn |= I2_DCTS; - pCh->icount.cts++; - dss_change = 1; - } - pCh->dataSetIn &= ~I2_CTS; - break; - - case STAT_DCD_UP: - ip2trace (channel, ITRC_MODEM, 1, 1, pCh->dataSetIn ); - - if ( !(pCh->dataSetIn & I2_DCD) ) - { - ip2trace (CHANN, ITRC_MODEM, 2, 0 ); - pCh->dataSetIn |= I2_DDCD; - pCh->icount.dcd++; - dss_change = 1; - } - pCh->dataSetIn |= I2_DCD; - - ip2trace (channel, ITRC_MODEM, 3, 1, pCh->dataSetIn ); - break; - - case STAT_DCD_DN: - ip2trace (channel, ITRC_MODEM, 4, 1, pCh->dataSetIn ); - if ( pCh->dataSetIn & I2_DCD ) - { - ip2trace (channel, ITRC_MODEM, 5, 0 ); - pCh->dataSetIn |= I2_DDCD; - pCh->icount.dcd++; - dss_change = 1; - } - pCh->dataSetIn &= ~I2_DCD; - - ip2trace (channel, ITRC_MODEM, 6, 1, pCh->dataSetIn ); - break; - - case STAT_DSR_UP: - if ( !(pCh->dataSetIn & I2_DSR) ) - { - pCh->dataSetIn |= I2_DDSR; - pCh->icount.dsr++; - dss_change = 1; - } - pCh->dataSetIn |= I2_DSR; - break; - - case STAT_DSR_DN: - if ( pCh->dataSetIn & I2_DSR ) - { - pCh->dataSetIn |= I2_DDSR; - pCh->icount.dsr++; - dss_change = 1; - } - pCh->dataSetIn &= ~I2_DSR; - break; - - case STAT_RI_UP: - if ( !(pCh->dataSetIn & I2_RI) ) - { - pCh->dataSetIn |= I2_DRI; - pCh->icount.rng++; - dss_change = 1; - } - pCh->dataSetIn |= I2_RI ; - break; - - case STAT_RI_DN: - // to be compat with serial.c - //if ( pCh->dataSetIn & I2_RI ) - //{ - // pCh->dataSetIn |= I2_DRI; - // pCh->icount.rng++; - // dss_change = 1; - //} - pCh->dataSetIn &= ~I2_RI ; - break; - - case STAT_BRK_DET: - pCh->dataSetIn |= I2_BRK; - pCh->icount.brk++; - dss_change = 1; - break; - - // Bookmarks? one less request we're waiting for - case STAT_BMARK: - pCh->bookMarks--; - if (pCh->bookMarks <= 0 ) { - pCh->bookMarks = 0; - wake_up_interruptible( &pCh->pBookmarkWait ); - - ip2trace (channel, ITRC_DRAIN, 20, 1, pCh->BookmarkTimer.expires ); - } - break; - - // Flow control packets? Update the new credits, and if - // someone was waiting for output, queue him up again. - case STAT_FLOW: - pCh->outfl.room = - ((flowStatPtr)pc)->room - - (pCh->outfl.asof - ((flowStatPtr)pc)->asof); - - ip2trace (channel, ITRC_STFLW, 1, 1, pCh->outfl.room ); - - if (pCh->channelNeeds & NEED_CREDIT) - { - ip2trace (channel, ITRC_STFLW, 2, 1, pCh->channelNeeds); - - pCh->channelNeeds &= ~NEED_CREDIT; - i2QueueNeeds(pB, pCh, NEED_INLINE); - if ( pCh->pTTY ) - ip2_owake(pCh->pTTY); - } - - ip2trace (channel, ITRC_STFLW, 3, 1, pCh->channelNeeds); - - pc += sizeof(flowStat); - break; - - /* Special packets: */ - /* Just copy the information into the channel structure */ - - case STAT_STATUS: - - pCh->channelStatus = *((debugStatPtr)pc); - pc += sizeof(debugStat); - break; - - case STAT_TXCNT: - - pCh->channelTcount = *((cntStatPtr)pc); - pc += sizeof(cntStat); - break; - - case STAT_RXCNT: - - pCh->channelRcount = *((cntStatPtr)pc); - pc += sizeof(cntStat); - break; - - case STAT_BOXIDS: - pB->channelBtypes = *((bidStatPtr)pc); - pc += sizeof(bidStat); - set_baud_params(pB); - break; - - case STAT_HWFAIL: - i2QueueCommands (PTYPE_INLINE, pCh, 0, 1, CMD_HW_TEST); - pCh->channelFail = *((failStatPtr)pc); - pc += sizeof(failStat); - break; - - /* No explicit match? then - * Might be an error packet... - */ - default: - switch (uc & STAT_MOD_ERROR) - { - case STAT_ERROR: - if (uc & STAT_E_PARITY) { - pCh->dataSetIn |= I2_PAR; - pCh->icount.parity++; - } - if (uc & STAT_E_FRAMING){ - pCh->dataSetIn |= I2_FRA; - pCh->icount.frame++; - } - if (uc & STAT_E_OVERRUN){ - pCh->dataSetIn |= I2_OVR; - pCh->icount.overrun++; - } - break; - - case STAT_MODEM: - // the answer to DSS_NOW request (not change) - pCh->dataSetIn = (pCh->dataSetIn - & ~(I2_RI | I2_CTS | I2_DCD | I2_DSR) ) - | xlatDss[uc & 0xf]; - wake_up_interruptible ( &pCh->dss_now_wait ); - default: - break; - } - } /* End of switch on status type */ - if (dss_change) { -#ifdef USE_IQ - schedule_work(&pCh->tqueue_status); -#else - do_status(&pCh->tqueue_status); -#endif - } - } - else /* Or else, channel is invalid */ - { - // Even though the channel is invalid, we must test the - // status to see how much additional data it has (to be - // skipped) - switch (*pc++) - { - case STAT_FLOW: - pc += 4; /* Skip the data */ - break; - - default: - break; - } - } - } // End of while (there is still some status packet left) - break; - - default: // Neither packet? should be impossible - ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 5, 1, - PTYPE_OF(pB->i2eLeadoffWord) ); - write_unlock_irqrestore(&pB->read_fifo_spinlock, - bflags); - - break; - } // End of switch on type of packets - } /*while(board I2_HAS_INPUT)*/ - - ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_RETURN, 0 ); - - // Send acknowledgement to the board even if there was no data! - pB->i2eOutMailWaiting |= MB_IN_STRIPPED; - return; -} - -//****************************************************************************** -// Function: i2Write2Fifo(pB,address,count) -// Parameters: Pointer to a board structure, source address, byte count -// Returns: bytes written -// -// Description: -// Writes count bytes to board io address(implied) from source -// Adjusts count, leaves reserve for next time around bypass cmds -//****************************************************************************** -static int -i2Write2Fifo(i2eBordStrPtr pB, unsigned char *source, int count,int reserve) -{ - int rc = 0; - unsigned long flags; - write_lock_irqsave(&pB->write_fifo_spinlock, flags); - if (!pB->i2eWaitingForEmptyFifo) { - if (pB->i2eFifoRemains > (count+reserve)) { - pB->i2eFifoRemains -= count; - iiWriteBuf(pB, source, count); - pB->i2eOutMailWaiting |= MB_OUT_STUFFED; - rc = count; - } - } - write_unlock_irqrestore(&pB->write_fifo_spinlock, flags); - return rc; -} -//****************************************************************************** -// Function: i2StuffFifoBypass(pB) -// Parameters: Pointer to a board structure -// Returns: Nothing -// -// Description: -// Stuffs as many bypass commands into the fifo as possible. This is simpler -// than stuffing data or inline commands to fifo, since we do not have -// flow-control to deal with. -//****************************************************************************** -static inline void -i2StuffFifoBypass(i2eBordStrPtr pB) -{ - i2ChanStrPtr pCh; - unsigned char *pRemove; - unsigned short stripIndex; - unsigned short packetSize; - unsigned short paddedSize; - unsigned short notClogged = 1; - unsigned long flags; - - int bailout = 1000; - - // Continue processing so long as there are entries, or there is room in the - // fifo. Each entry represents a channel with something to do. - while ( --bailout && notClogged && - (NULL != (pCh = i2DeQueueNeeds(pB,NEED_BYPASS)))) - { - write_lock_irqsave(&pCh->Cbuf_spinlock, flags); - stripIndex = pCh->Cbuf_strip; - - // as long as there are packets for this channel... - - while (stripIndex != pCh->Cbuf_stuff) { - pRemove = &(pCh->Cbuf[stripIndex]); - packetSize = CMD_COUNT_OF(pRemove) + sizeof(i2CmdHeader); - paddedSize = roundup(packetSize, 2); - - if (paddedSize > 0) { - if ( 0 == i2Write2Fifo(pB, pRemove, paddedSize,0)) { - notClogged = 0; /* fifo full */ - i2QueueNeeds(pB, pCh, NEED_BYPASS); // Put back on queue - break; // Break from the channel - } - } -#ifdef DEBUG_FIFO -WriteDBGBuf("BYPS", pRemove, paddedSize); -#endif /* DEBUG_FIFO */ - pB->debugBypassCount++; - - pRemove += packetSize; - stripIndex += packetSize; - if (stripIndex >= CBUF_SIZE) { - stripIndex = 0; - pRemove = pCh->Cbuf; - } - } - // Done with this channel. Move to next, removing this one from - // the queue of channels if we cleaned it out (i.e., didn't get clogged. - pCh->Cbuf_strip = stripIndex; - write_unlock_irqrestore(&pCh->Cbuf_spinlock, flags); - } // Either clogged or finished all the work - -#ifdef IP2DEBUG_TRACE - if ( !bailout ) { - ip2trace (ITRC_NO_PORT, ITRC_ERROR, 1, 0 ); - } -#endif -} - -//****************************************************************************** -// Function: i2StuffFifoFlow(pB) -// Parameters: Pointer to a board structure -// Returns: Nothing -// -// Description: -// Stuffs as many flow control packets into the fifo as possible. This is easier -// even than doing normal bypass commands, because there is always at most one -// packet, already assembled, for each channel. -//****************************************************************************** -static inline void -i2StuffFifoFlow(i2eBordStrPtr pB) -{ - i2ChanStrPtr pCh; - unsigned short paddedSize = roundup(sizeof(flowIn), 2); - - ip2trace (ITRC_NO_PORT, ITRC_SFLOW, ITRC_ENTER, 2, - pB->i2eFifoRemains, paddedSize ); - - // Continue processing so long as there are entries, or there is room in the - // fifo. Each entry represents a channel with something to do. - while ( (NULL != (pCh = i2DeQueueNeeds(pB,NEED_FLOW)))) { - pB->debugFlowCount++; - - // NO Chan LOCK needed ??? - if ( 0 == i2Write2Fifo(pB,(unsigned char *)&(pCh->infl),paddedSize,0)) { - break; - } -#ifdef DEBUG_FIFO - WriteDBGBuf("FLOW",(unsigned char *) &(pCh->infl), paddedSize); -#endif /* DEBUG_FIFO */ - - } // Either clogged or finished all the work - - ip2trace (ITRC_NO_PORT, ITRC_SFLOW, ITRC_RETURN, 0 ); -} - -//****************************************************************************** -// Function: i2StuffFifoInline(pB) -// Parameters: Pointer to a board structure -// Returns: Nothing -// -// Description: -// Stuffs as much data and inline commands into the fifo as possible. This is -// the most complex fifo-stuffing operation, since there if now the channel -// flow-control issue to deal with. -//****************************************************************************** -static inline void -i2StuffFifoInline(i2eBordStrPtr pB) -{ - i2ChanStrPtr pCh; - unsigned char *pRemove; - unsigned short stripIndex; - unsigned short packetSize; - unsigned short paddedSize; - unsigned short notClogged = 1; - unsigned short flowsize; - unsigned long flags; - - int bailout = 1000; - int bailout2; - - ip2trace (ITRC_NO_PORT, ITRC_SICMD, ITRC_ENTER, 3, pB->i2eFifoRemains, - pB->i2Dbuf_strip, pB->i2Dbuf_stuff ); - - // Continue processing so long as there are entries, or there is room in the - // fifo. Each entry represents a channel with something to do. - while ( --bailout && notClogged && - (NULL != (pCh = i2DeQueueNeeds(pB,NEED_INLINE))) ) - { - write_lock_irqsave(&pCh->Obuf_spinlock, flags); - stripIndex = pCh->Obuf_strip; - - ip2trace (CHANN, ITRC_SICMD, 3, 2, stripIndex, pCh->Obuf_stuff ); - - // as long as there are packets for this channel... - bailout2 = 1000; - while ( --bailout2 && stripIndex != pCh->Obuf_stuff) { - pRemove = &(pCh->Obuf[stripIndex]); - - // Must determine whether this be a data or command packet to - // calculate correctly the header size and the amount of - // flow-control credit this type of packet will use. - if (PTYPE_OF(pRemove) == PTYPE_DATA) { - flowsize = DATA_COUNT_OF(pRemove); - packetSize = flowsize + sizeof(i2DataHeader); - } else { - flowsize = CMD_COUNT_OF(pRemove); - packetSize = flowsize + sizeof(i2CmdHeader); - } - flowsize = CREDIT_USAGE(flowsize); - paddedSize = roundup(packetSize, 2); - - ip2trace (CHANN, ITRC_SICMD, 4, 2, pB->i2eFifoRemains, paddedSize ); - - // If we don't have enough credits from the board to send the data, - // flag the channel that we are waiting for flow control credit, and - // break out. This will clean up this channel and remove us from the - // queue of hot things to do. - - ip2trace (CHANN, ITRC_SICMD, 5, 2, pCh->outfl.room, flowsize ); - - if (pCh->outfl.room <= flowsize) { - // Do Not have the credits to send this packet. - i2QueueNeeds(pB, pCh, NEED_CREDIT); - notClogged = 0; - break; // So to do next channel - } - if ( (paddedSize > 0) - && ( 0 == i2Write2Fifo(pB, pRemove, paddedSize, 128))) { - // Do Not have room in fifo to send this packet. - notClogged = 0; - i2QueueNeeds(pB, pCh, NEED_INLINE); - break; // Break from the channel - } -#ifdef DEBUG_FIFO -WriteDBGBuf("DATA", pRemove, paddedSize); -#endif /* DEBUG_FIFO */ - pB->debugInlineCount++; - - pCh->icount.tx += flowsize; - // Update current credits - pCh->outfl.room -= flowsize; - pCh->outfl.asof += flowsize; - if (PTYPE_OF(pRemove) == PTYPE_DATA) { - pCh->Obuf_char_count -= DATA_COUNT_OF(pRemove); - } - pRemove += packetSize; - stripIndex += packetSize; - - ip2trace (CHANN, ITRC_SICMD, 6, 2, stripIndex, pCh->Obuf_strip); - - if (stripIndex >= OBUF_SIZE) { - stripIndex = 0; - pRemove = pCh->Obuf; - - ip2trace (CHANN, ITRC_SICMD, 7, 1, stripIndex ); - - } - } /* while */ - if ( !bailout2 ) { - ip2trace (CHANN, ITRC_ERROR, 3, 0 ); - } - // Done with this channel. Move to next, removing this one from the - // queue of channels if we cleaned it out (i.e., didn't get clogged. - pCh->Obuf_strip = stripIndex; - write_unlock_irqrestore(&pCh->Obuf_spinlock, flags); - if ( notClogged ) - { - - ip2trace (CHANN, ITRC_SICMD, 8, 0 ); - - if ( pCh->pTTY ) { - ip2_owake(pCh->pTTY); - } - } - } // Either clogged or finished all the work - - if ( !bailout ) { - ip2trace (ITRC_NO_PORT, ITRC_ERROR, 4, 0 ); - } - - ip2trace (ITRC_NO_PORT, ITRC_SICMD, ITRC_RETURN, 1,pB->i2Dbuf_strip); -} - -//****************************************************************************** -// Function: serviceOutgoingFifo(pB) -// Parameters: Pointer to a board structure -// Returns: Nothing -// -// Description: -// Helper routine to put data in the outgoing fifo, if we aren't already waiting -// for something to be there. If the fifo has only room for a very little data, -// go head and hit the board with a mailbox hit immediately. Otherwise, it will -// have to happen later in the interrupt processing. Since this routine may be -// called both at interrupt and foreground time, we must turn off interrupts -// during the entire process. -//****************************************************************************** -static void -serviceOutgoingFifo(i2eBordStrPtr pB) -{ - // If we aren't currently waiting for the board to empty our fifo, service - // everything that is pending, in priority order (especially, Bypass before - // Inline). - if ( ! pB->i2eWaitingForEmptyFifo ) - { - i2StuffFifoFlow(pB); - i2StuffFifoBypass(pB); - i2StuffFifoInline(pB); - - iiSendPendingMail(pB); - } -} - -//****************************************************************************** -// Function: i2ServiceBoard(pB) -// Parameters: Pointer to a board structure -// Returns: Nothing -// -// Description: -// Normally this is called from interrupt level, but there is deliberately -// nothing in here specific to being called from interrupt level. All the -// hardware-specific, interrupt-specific things happen at the outer levels. -// -// For example, a timer interrupt could drive this routine for some sort of -// polled operation. The only requirement is that the programmer deal with any -// atomiticity/concurrency issues that result. -// -// This routine responds to the board's having sent mailbox information to the -// host (which would normally cause an interrupt). This routine reads the -// incoming mailbox. If there is no data in it, this board did not create the -// interrupt and/or has nothing to be done to it. (Except, if we have been -// waiting to write mailbox data to it, we may do so. -// -// Based on the value in the mailbox, we may take various actions. -// -// No checking here of pB validity: after all, it shouldn't have been called by -// the handler unless pB were on the list. -//****************************************************************************** -static inline int -i2ServiceBoard ( i2eBordStrPtr pB ) -{ - unsigned inmail; - unsigned long flags; - - - /* This should be atomic because of the way we are called... */ - if (NO_MAIL_HERE == ( inmail = pB->i2eStartMail ) ) { - inmail = iiGetMail(pB); - } - pB->i2eStartMail = NO_MAIL_HERE; - - ip2trace (ITRC_NO_PORT, ITRC_INTR, 2, 1, inmail ); - - if (inmail != NO_MAIL_HERE) { - // If the board has gone fatal, nothing to do but hit a bit that will - // alert foreground tasks to protest! - if ( inmail & MB_FATAL_ERROR ) { - pB->i2eFatal = 1; - goto exit_i2ServiceBoard; - } - - /* Assuming no fatal condition, we proceed to do work */ - if ( inmail & MB_IN_STUFFED ) { - pB->i2eFifoInInts++; - i2StripFifo(pB); /* There might be incoming packets */ - } - - if (inmail & MB_OUT_STRIPPED) { - pB->i2eFifoOutInts++; - write_lock_irqsave(&pB->write_fifo_spinlock, flags); - pB->i2eFifoRemains = pB->i2eFifoSize; - pB->i2eWaitingForEmptyFifo = 0; - write_unlock_irqrestore(&pB->write_fifo_spinlock, - flags); - - ip2trace (ITRC_NO_PORT, ITRC_INTR, 30, 1, pB->i2eFifoRemains ); - - } - serviceOutgoingFifo(pB); - } - - ip2trace (ITRC_NO_PORT, ITRC_INTR, 8, 0 ); - -exit_i2ServiceBoard: - - return 0; -} diff --git a/drivers/char/ip2/i2lib.h b/drivers/char/ip2/i2lib.h deleted file mode 100644 index e559e9bac06d..000000000000 --- a/drivers/char/ip2/i2lib.h +++ /dev/null @@ -1,351 +0,0 @@ -/******************************************************************************* -* -* (c) 1998 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Header file for high level library functions -* -*******************************************************************************/ -#ifndef I2LIB_H -#define I2LIB_H 1 -//------------------------------------------------------------------------------ -// I2LIB.H -// -// IntelliPort-II and IntelliPort-IIEX -// -// Defines, structure definitions, and external declarations for i2lib.c -//------------------------------------------------------------------------------ -//-------------------------------------- -// Mandatory Includes: -//-------------------------------------- -#include "ip2types.h" -#include "i2ellis.h" -#include "i2pack.h" -#include "i2cmd.h" -#include - -//------------------------------------------------------------------------------ -// i2ChanStr -- Channel Structure: -// Used to track per-channel information for the library routines using standard -// loadware. Note also, a pointer to an array of these structures is patched -// into the i2eBordStr (see i2ellis.h) -//------------------------------------------------------------------------------ -// -// If we make some limits on the maximum block sizes, we can avoid dealing with -// buffer wrap. The wrapping of the buffer is based on where the start of the -// packet is. Then there is always room for the packet contiguously. -// -// Maximum total length of an outgoing data or in-line command block. The limit -// of 36 on data is quite arbitrary and based more on DOS memory limitations -// than the board interface. However, for commands, the maximum packet length is -// MAX_CMD_PACK_SIZE, because the field size for the count is only a few bits -// (see I2PACK.H) in such packets. For data packets, the count field size is not -// the limiting factor. As of this writing, MAX_OBUF_BLOCK < MAX_CMD_PACK_SIZE, -// but be careful if wanting to modify either. -// -#define MAX_OBUF_BLOCK 36 - -// Another note on maximum block sizes: we are buffering packets here. Data is -// put into the buffer (if there is room) regardless of the credits from the -// board. The board sends new credits whenever it has removed from his buffers a -// number of characters equal to 80% of total buffer size. (Of course, the total -// buffer size is what is reported when the very first set of flow control -// status packets are received from the board. Therefore, to be robust, you must -// always fill the board to at least 80% of the current credit limit, else you -// might not give it enough to trigger a new report. These conditions are -// obtained here so long as the maximum output block size is less than 20% the -// size of the board's output buffers. This is true at present by "coincidence" -// or "infernal knowledge": the board's output buffers are at least 700 bytes -// long (20% = 140 bytes, at least). The 80% figure is "official", so the safest -// strategy might be to trap the first flow control report and guarantee that -// the effective maxObufBlock is the minimum of MAX_OBUF_BLOCK and 20% of first -// reported buffer credit. -// -#define MAX_CBUF_BLOCK 6 // Maximum total length of a bypass command block - -#define IBUF_SIZE 512 // character capacity of input buffer per channel -#define OBUF_SIZE 1024// character capacity of output buffer per channel -#define CBUF_SIZE 10 // character capacity of output bypass buffer - -typedef struct _i2ChanStr -{ - // First, back-pointers so that given a pointer to this structure, you can - // determine the correct board and channel number to reference, (say, when - // issuing commands, etc. (Note, channel number is in infl.hd.i2sChannel.) - - int port_index; // Index of port in channel structure array attached - // to board structure. - PTTY pTTY; // Pointer to tty structure for port (OS specific) - USHORT validity; // Indicates whether the given channel has been - // initialized, really exists (or is a missing - // channel, e.g. channel 9 on an 8-port box.) - - i2eBordStrPtr pMyBord; // Back-pointer to this channel's board structure - - int wopen; // waiting fer carrier - - int throttled; // Set if upper layer can take no data - - int flags; // Defined in tty.h - - PWAITQ open_wait; // Pointer for OS sleep function. - PWAITQ close_wait; // Pointer for OS sleep function. - PWAITQ delta_msr_wait;// Pointer for OS sleep function. - PWAITQ dss_now_wait; // Pointer for OS sleep function. - - struct timer_list BookmarkTimer; // Used by i2DrainOutput - wait_queue_head_t pBookmarkWait; // Used by i2DrainOutput - - int BaudBase; - int BaudDivisor; - - USHORT ClosingDelay; - USHORT ClosingWaitTime; - - volatile - flowIn infl; // This structure is initialized as a completely - // formed flow-control command packet, and as such - // has the channel number, also the capacity and - // "as-of" data needed continuously. - - USHORT sinceLastFlow; // Counts the number of characters read from input - // buffers, since the last time flow control info - // was sent. - - USHORT whenSendFlow; // Determines when new flow control is to be sent to - // the board. Note unlike earlier manifestations of - // the driver, these packets can be sent from - // in-place. - - USHORT channelNeeds; // Bit map of important things which must be done - // for this channel. (See bits below ) - - volatile - flowStat outfl; // Same type of structure is used to hold current - // flow control information used to control our - // output. "asof" is kept updated as data is sent, - // and "room" never goes to zero. - - // The incoming ring buffer - // Unlike the outgoing buffers, this holds raw data, not packets. The two - // extra bytes are used to hold the byte-padding when there is room for an - // odd number of bytes before we must wrap. - // - UCHAR Ibuf[IBUF_SIZE + 2]; - volatile - USHORT Ibuf_stuff; // Stuffing index - volatile - USHORT Ibuf_strip; // Stripping index - - // The outgoing ring-buffer: Holds Data and command packets. N.B., even - // though these are in the channel structure, the channel is also written - // here, the easier to send it to the fifo when ready. HOWEVER, individual - // packets here are NOT padded to even length: the routines for writing - // blocks to the fifo will pad to even byte counts. - // - UCHAR Obuf[OBUF_SIZE+MAX_OBUF_BLOCK+4]; - volatile - USHORT Obuf_stuff; // Stuffing index - volatile - USHORT Obuf_strip; // Stripping index - int Obuf_char_count; - - // The outgoing bypass-command buffer. Unlike earlier manifestations, the - // flow control packets are sent directly from the structures. As above, the - // channel number is included in the packet, but they are NOT padded to even - // size. - // - UCHAR Cbuf[CBUF_SIZE+MAX_CBUF_BLOCK+2]; - volatile - USHORT Cbuf_stuff; // Stuffing index - volatile - USHORT Cbuf_strip; // Stripping index - - // The temporary buffer for the Linux tty driver PutChar entry. - // - UCHAR Pbuf[MAX_OBUF_BLOCK - sizeof (i2DataHeader)]; - volatile - USHORT Pbuf_stuff; // Stuffing index - - // The state of incoming data-set signals - // - USHORT dataSetIn; // Bit-mapped according to below. Also indicates - // whether a break has been detected since last - // inquiry. - - // The state of outcoming data-set signals (as far as we can tell!) - // - USHORT dataSetOut; // Bit-mapped according to below. - - // Most recent hot-key identifier detected - // - USHORT hotKeyIn; // Hot key as sent by the board, HOT_CLEAR indicates - // no hot key detected since last examined. - - // Counter of outstanding requests for bookmarks - // - short bookMarks; // Number of outstanding bookmark requests, (+ive - // whenever a bookmark request if queued up, -ive - // whenever a bookmark is received). - - // Misc options - // - USHORT channelOptions; // See below - - // To store various incoming special packets - // - debugStat channelStatus; - cntStat channelRcount; - cntStat channelTcount; - failStat channelFail; - - // To store the last values for line characteristics we sent to the board. - // - int speed; - - int flush_flags; - - void (*trace)(unsigned short,unsigned char,unsigned char,unsigned long,...); - - /* - * Kernel counters for the 4 input interrupts - */ - struct async_icount icount; - - /* - * Task queues for processing input packets from the board. - */ - struct work_struct tqueue_input; - struct work_struct tqueue_status; - struct work_struct tqueue_hangup; - - rwlock_t Ibuf_spinlock; - rwlock_t Obuf_spinlock; - rwlock_t Cbuf_spinlock; - rwlock_t Pbuf_spinlock; - -} i2ChanStr, *i2ChanStrPtr; - -//--------------------------------------------------- -// Manifests and bit-maps for elements in i2ChanStr -//--------------------------------------------------- -// -// flush flags -// -#define STARTFL_FLAG 1 -#define STOPFL_FLAG 2 - -// validity -// -#define CHANNEL_MAGIC_BITS 0xff00 -#define CHANNEL_MAGIC 0x5300 // (validity & CHANNEL_MAGIC_BITS) == - // CHANNEL_MAGIC --> structure good - -#define CHANNEL_SUPPORT 0x0001 // Indicates channel is supported, exists, - // and passed P.O.S.T. - -// channelNeeds -// -#define NEED_FLOW 1 // Indicates flow control has been queued -#define NEED_INLINE 2 // Indicates inline commands or data queued -#define NEED_BYPASS 4 // Indicates bypass commands queued -#define NEED_CREDIT 8 // Indicates would be sending except has not sufficient - // credit. The data is still in the channel structure, - // but the channel is not enqueued in the board - // structure again until there is a credit received from - // the board. - -// dataSetIn (Also the bits for i2GetStatus return value) -// -#define I2_DCD 1 -#define I2_CTS 2 -#define I2_DSR 4 -#define I2_RI 8 - -// dataSetOut (Also the bits for i2GetStatus return value) -// -#define I2_DTR 1 -#define I2_RTS 2 - -// i2GetStatus() can optionally clear these bits -// -#define I2_BRK 0x10 // A break was detected -#define I2_PAR 0x20 // A parity error was received -#define I2_FRA 0x40 // A framing error was received -#define I2_OVR 0x80 // An overrun error was received - -// i2GetStatus() automatically clears these bits */ -// -#define I2_DDCD 0x100 // DCD changed from its former value -#define I2_DCTS 0x200 // CTS changed from its former value -#define I2_DDSR 0x400 // DSR changed from its former value -#define I2_DRI 0x800 // RI changed from its former value - -// hotKeyIn -// -#define HOT_CLEAR 0x1322 // Indicates that no hot-key has been detected - -// channelOptions -// -#define CO_NBLOCK_WRITE 1 // Writes don't block waiting for buffer. (Default - // is, they do wait.) - -// fcmodes -// -#define I2_OUTFLOW_CTS 0x0001 -#define I2_INFLOW_RTS 0x0002 -#define I2_INFLOW_DSR 0x0004 -#define I2_INFLOW_DTR 0x0008 -#define I2_OUTFLOW_DSR 0x0010 -#define I2_OUTFLOW_DTR 0x0020 -#define I2_OUTFLOW_XON 0x0040 -#define I2_OUTFLOW_XANY 0x0080 -#define I2_INFLOW_XON 0x0100 - -#define I2_CRTSCTS (I2_OUTFLOW_CTS|I2_INFLOW_RTS) -#define I2_IXANY_MODE (I2_OUTFLOW_XON|I2_OUTFLOW_XANY) - -//------------------------------------------- -// Macros used from user level like functions -//------------------------------------------- - -// Macros to set and clear channel options -// -#define i2SetOption(pCh, option) pCh->channelOptions |= option -#define i2ClrOption(pCh, option) pCh->channelOptions &= ~option - -// Macro to set fatal-error trap -// -#define i2SetFatalTrap(pB, routine) pB->i2eFatalTrap = routine - -//-------------------------------------------- -// Declarations and prototypes for i2lib.c -//-------------------------------------------- -// -static int i2InitChannels(i2eBordStrPtr, int, i2ChanStrPtr); -static int i2QueueCommands(int, i2ChanStrPtr, int, int, cmdSyntaxPtr,...); -static int i2GetStatus(i2ChanStrPtr, int); -static int i2Input(i2ChanStrPtr); -static int i2InputFlush(i2ChanStrPtr); -static int i2Output(i2ChanStrPtr, const char *, int); -static int i2OutputFree(i2ChanStrPtr); -static int i2ServiceBoard(i2eBordStrPtr); -static void i2DrainOutput(i2ChanStrPtr, int); - -#ifdef IP2DEBUG_TRACE -void ip2trace(unsigned short,unsigned char,unsigned char,unsigned long,...); -#else -#define ip2trace(a,b,c,d...) do {} while (0) -#endif - -// Argument to i2QueueCommands -// -#define C_IN_LINE 1 -#define C_BYPASS 0 - -#endif // I2LIB_H diff --git a/drivers/char/ip2/i2pack.h b/drivers/char/ip2/i2pack.h deleted file mode 100644 index 00342a677c90..000000000000 --- a/drivers/char/ip2/i2pack.h +++ /dev/null @@ -1,364 +0,0 @@ -/******************************************************************************* -* -* (c) 1998 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Definitions of the packets used to transfer data and commands -* Host <--> Board. Information provided here is only applicable -* when the standard loadware is active. -* -*******************************************************************************/ -#ifndef I2PACK_H -#define I2PACK_H 1 - -//----------------------------------------------- -// Revision History: -// -// 10 October 1991 MAG First draft -// 24 February 1992 MAG Additions for 1.4.x loadware -// 11 March 1992 MAG New status packets -// -//----------------------------------------------- - -//------------------------------------------------------------------------------ -// Packet Formats: -// -// Information passes between the host and board through the FIFO in packets. -// These have headers which indicate the type of packet. Because the fifo data -// path may be 16-bits wide, the protocol is constrained such that each packet -// is always padded to an even byte count. (The lower-level interface routines -// -- i2ellis.c -- are designed to do this). -// -// The sender (be it host or board) must place some number of complete packets -// in the fifo, then place a message in the mailbox that packets are available. -// Placing such a message interrupts the "receiver" (be it board or host), who -// reads the mailbox message and determines that there are incoming packets -// ready. Since there are no partial packets, and the length of a packet is -// given in the header, the remainder of the packet can be read without checking -// for FIFO empty condition. The process is repeated, packet by packet, until -// the incoming FIFO is empty. Then the receiver uses the outbound mailbox to -// signal the board that it has read the data. Only then can the sender place -// additional data in the fifo. -//------------------------------------------------------------------------------ -// -//------------------------------------------------ -// Definition of Packet Header Area -//------------------------------------------------ -// -// Caution: these only define header areas. In actual use the data runs off -// beyond the end of these structures. -// -// Since these structures are based on sequences of bytes which go to the board, -// there cannot be ANY padding between the elements. -#pragma pack(1) - -//---------------------------- -// DATA PACKETS -//---------------------------- - -typedef struct _i2DataHeader -{ - unsigned char i2sChannel; /* The channel number: 0-255 */ - - // -- Bitfields are allocated LSB first -- - - // For incoming data, indicates whether this is an ordinary packet or a - // special one (e.g., hot key hit). - unsigned i2sId : 2 __attribute__ ((__packed__)); - - // For tagging data packets. There are flush commands which flush only data - // packets bearing a particular tag. (used in implementing IntelliView and - // IntelliPrint). THE TAG VALUE 0xf is RESERVED and must not be used (it has - // meaning internally to the loadware). - unsigned i2sTag : 4; - - // These two bits determine the type of packet sent/received. - unsigned i2sType : 2; - - // The count of data to follow: does not include the possible additional - // padding byte. MAXIMUM COUNT: 4094. The top four bits must be 0. - unsigned short i2sCount; - -} i2DataHeader, *i2DataHeaderPtr; - -// Structure is immediately followed by the data, proper. - -//---------------------------- -// NON-DATA PACKETS -//---------------------------- - -typedef struct _i2CmdHeader -{ - unsigned char i2sChannel; // The channel number: 0-255 (Except where noted - // - see below - - // Number of bytes of commands, status or whatever to follow - unsigned i2sCount : 6; - - // These two bits determine the type of packet sent/received. - unsigned i2sType : 2; - -} i2CmdHeader, *i2CmdHeaderPtr; - -// Structure is immediately followed by the applicable data. - -//--------------------------------------- -// Flow Control Packets (Outbound) -//--------------------------------------- - -// One type of outbound command packet is so important that the entire structure -// is explicitly defined here. That is the flow-control packet. This is never -// sent by user-level code (as would be the commands to raise/lower DTR, for -// example). These are only sent by the library routines in response to reading -// incoming data into the buffers. -// -// The parameters inside the command block are maintained in place, then the -// block is sent at the appropriate time. - -typedef struct _flowIn -{ - i2CmdHeader hd; // Channel #, count, type (see above) - unsigned char fcmd; // The flow control command (37) - unsigned short asof; // As of byte number "asof" (LSB first!) I have room - // for "room" bytes - unsigned short room; -} flowIn, *flowInPtr; - -//---------------------------------------- -// (Incoming) Status Packets -//---------------------------------------- - -// Incoming packets which are non-data packets are status packets. In this case, -// the channel number in the header is unimportant. What follows are one or more -// sub-packets, the first word of which consists of the channel (first or low -// byte) and the status indicator (second or high byte), followed by possibly -// more data. - -#define STAT_CTS_UP 0 /* CTS raised (no other bytes) */ -#define STAT_CTS_DN 1 /* CTS dropped (no other bytes) */ -#define STAT_DCD_UP 2 /* DCD raised (no other bytes) */ -#define STAT_DCD_DN 3 /* DCD dropped (no other bytes) */ -#define STAT_DSR_UP 4 /* DSR raised (no other bytes) */ -#define STAT_DSR_DN 5 /* DSR dropped (no other bytes) */ -#define STAT_RI_UP 6 /* RI raised (no other bytes) */ -#define STAT_RI_DN 7 /* RI dropped (no other bytes) */ -#define STAT_BRK_DET 8 /* BRK detect (no other bytes) */ -#define STAT_FLOW 9 /* Flow control(-- more: see below */ -#define STAT_BMARK 10 /* Bookmark (no other bytes) - * Bookmark is sent as a response to - * a command 60: request for bookmark - */ -#define STAT_STATUS 11 /* Special packet: see below */ -#define STAT_TXCNT 12 /* Special packet: see below */ -#define STAT_RXCNT 13 /* Special packet: see below */ -#define STAT_BOXIDS 14 /* Special packet: see below */ -#define STAT_HWFAIL 15 /* Special packet: see below */ - -#define STAT_MOD_ERROR 0xc0 -#define STAT_MODEM 0xc0/* If status & STAT_MOD_ERROR: - * == STAT_MODEM, then this is a modem - * status packet, given in response to a - * CMD_DSS_NOW command. - * The low nibble has each data signal: - */ -#define STAT_MOD_DCD 0x8 -#define STAT_MOD_RI 0x4 -#define STAT_MOD_DSR 0x2 -#define STAT_MOD_CTS 0x1 - -#define STAT_ERROR 0x80/* If status & STAT_MOD_ERROR - * == STAT_ERROR, then - * sort of error on the channel. - * The remaining seven bits indicate - * what sort of error it is. - */ -/* The low three bits indicate parity, framing, or overrun errors */ - -#define STAT_E_PARITY 4 /* Parity error */ -#define STAT_E_FRAMING 2 /* Framing error */ -#define STAT_E_OVERRUN 1 /* (uxart) overrun error */ - -//--------------------------------------- -// STAT_FLOW packets -//--------------------------------------- - -typedef struct _flowStat -{ - unsigned short asof; - unsigned short room; -}flowStat, *flowStatPtr; - -// flowStat packets are received from the board to regulate the flow of outgoing -// data. A local copy of this structure is also kept to track the amount of -// credits used and credits remaining. "room" is the amount of space in the -// board's buffers, "as of" having received a certain byte number. When sending -// data to the fifo, you must calculate how much buffer space your packet will -// use. Add this to the current "asof" and subtract it from the current "room". -// -// The calculation for the board's buffer is given by CREDIT_USAGE, where size -// is the un-rounded count of either data characters or command characters. -// (Which is to say, the count rounded up, plus two). - -#define CREDIT_USAGE(size) (((size) + 3) & ~1) - -//--------------------------------------- -// STAT_STATUS packets -//--------------------------------------- - -typedef struct _debugStat -{ - unsigned char d_ccsr; - unsigned char d_txinh; - unsigned char d_stat1; - unsigned char d_stat2; -} debugStat, *debugStatPtr; - -// debugStat packets are sent to the host in response to a CMD_GET_STATUS -// command. Each byte is bit-mapped as described below: - -#define D_CCSR_XON 2 /* Has received XON, ready to transmit */ -#define D_CCSR_XOFF 4 /* Has received XOFF, not transmitting */ -#define D_CCSR_TXENAB 8 /* Transmitter is enabled */ -#define D_CCSR_RXENAB 0x80 /* Receiver is enabled */ - -#define D_TXINH_BREAK 1 /* We are sending a break */ -#define D_TXINH_EMPTY 2 /* No data to send */ -#define D_TXINH_SUSP 4 /* Output suspended via command 57 */ -#define D_TXINH_CMD 8 /* We are processing an in-line command */ -#define D_TXINH_LCD 0x10 /* LCD diagnostics are running */ -#define D_TXINH_PAUSE 0x20 /* We are processing a PAUSE command */ -#define D_TXINH_DCD 0x40 /* DCD is low, preventing transmission */ -#define D_TXINH_DSR 0x80 /* DSR is low, preventing transmission */ - -#define D_STAT1_TXEN 1 /* Transmit INTERRUPTS enabled */ -#define D_STAT1_RXEN 2 /* Receiver INTERRUPTS enabled */ -#define D_STAT1_MDEN 4 /* Modem (data set sigs) interrupts enabled */ -#define D_STAT1_RLM 8 /* Remote loopback mode selected */ -#define D_STAT1_LLM 0x10 /* Local internal loopback mode selected */ -#define D_STAT1_CTS 0x20 /* CTS is low, preventing transmission */ -#define D_STAT1_DTR 0x40 /* DTR is low, to stop remote transmission */ -#define D_STAT1_RTS 0x80 /* RTS is low, to stop remote transmission */ - -#define D_STAT2_TXMT 1 /* Transmit buffers are all empty */ -#define D_STAT2_RXMT 2 /* Receive buffers are all empty */ -#define D_STAT2_RXINH 4 /* Loadware has tried to inhibit remote - * transmission: dropped DTR, sent XOFF, - * whatever... - */ -#define D_STAT2_RXFLO 8 /* Loadware can send no more data to host - * until it receives a flow-control packet - */ -//----------------------------------------- -// STAT_TXCNT and STAT_RXCNT packets -//---------------------------------------- - -typedef struct _cntStat -{ - unsigned short cs_time; // (Assumes host is little-endian!) - unsigned short cs_count; -} cntStat, *cntStatPtr; - -// These packets are sent in response to a CMD_GET_RXCNT or a CMD_GET_TXCNT -// bypass command. cs_time is a running 1 Millisecond counter which acts as a -// time stamp. cs_count is a running counter of data sent or received from the -// uxarts. (Not including data added by the chip itself, as with CRLF -// processing). -//------------------------------------------ -// STAT_HWFAIL packets -//------------------------------------------ - -typedef struct _failStat -{ - unsigned char fs_written; - unsigned char fs_read; - unsigned short fs_address; -} failStat, *failStatPtr; - -// This packet is sent whenever the on-board diagnostic process detects an -// error. At startup, this process is dormant. The host can wake it up by -// issuing the bypass command CMD_HW_TEST. The process runs at low priority and -// performs continuous hardware verification; writing data to certain on-board -// registers, reading it back, and comparing. If it detects an error, this -// packet is sent to the host, and the process goes dormant again until the host -// sends another CMD_HW_TEST. It then continues with the next register to be -// tested. - -//------------------------------------------------------------------------------ -// Macros to deal with the headers more easily! Note that these are defined so -// they may be used as "left" as well as "right" expressions. -//------------------------------------------------------------------------------ - -// Given a pointer to the packet, reference the channel number -// -#define CHANNEL_OF(pP) ((i2DataHeaderPtr)(pP))->i2sChannel - -// Given a pointer to the packet, reference the Packet type -// -#define PTYPE_OF(pP) ((i2DataHeaderPtr)(pP))->i2sType - -// The possible types of packets -// -#define PTYPE_DATA 0 /* Host <--> Board */ -#define PTYPE_BYPASS 1 /* Host ---> Board */ -#define PTYPE_INLINE 2 /* Host ---> Board */ -#define PTYPE_STATUS 2 /* Host <--- Board */ - -// Given a pointer to a Data packet, reference the Tag -// -#define TAG_OF(pP) ((i2DataHeaderPtr)(pP))->i2sTag - -// Given a pointer to a Data packet, reference the data i.d. -// -#define ID_OF(pP) ((i2DataHeaderPtr)(pP))->i2sId - -// The possible types of ID's -// -#define ID_ORDINARY_DATA 0 -#define ID_HOT_KEY 1 - -// Given a pointer to a Data packet, reference the count -// -#define DATA_COUNT_OF(pP) ((i2DataHeaderPtr)(pP))->i2sCount - -// Given a pointer to a Data packet, reference the beginning of data -// -#define DATA_OF(pP) &((unsigned char *)(pP))[4] // 4 = size of header - -// Given a pointer to a Non-Data packet, reference the count -// -#define CMD_COUNT_OF(pP) ((i2CmdHeaderPtr)(pP))->i2sCount - -#define MAX_CMD_PACK_SIZE 62 // Maximum size of such a count - -// Given a pointer to a Non-Data packet, reference the beginning of data -// -#define CMD_OF(pP) &((unsigned char *)(pP))[2] // 2 = size of header - -//-------------------------------- -// MailBox Bits: -//-------------------------------- - -//-------------------------- -// Outgoing (host to board) -//-------------------------- -// -#define MB_OUT_STUFFED 0x80 // Host has placed output in fifo -#define MB_IN_STRIPPED 0x40 // Host has read in all input from fifo - -//-------------------------- -// Incoming (board to host) -//-------------------------- -// -#define MB_IN_STUFFED 0x80 // Board has placed input in fifo -#define MB_OUT_STRIPPED 0x40 // Board has read all output from fifo -#define MB_FATAL_ERROR 0x20 // Board has encountered a fatal error - -#pragma pack() // Reset padding to command-line default - -#endif // I2PACK_H - diff --git a/drivers/char/ip2/ip2.h b/drivers/char/ip2/ip2.h deleted file mode 100644 index 936ccc533949..000000000000 --- a/drivers/char/ip2/ip2.h +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* -* -* (c) 1998 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Driver constants for configuration and tuning -* -* NOTES: -* -*******************************************************************************/ -#ifndef IP2_H -#define IP2_H - -#include "ip2types.h" -#include "i2cmd.h" - -/*************/ -/* Constants */ -/*************/ - -/* Device major numbers - since version 2.0.26. */ -#define IP2_TTY_MAJOR 71 -#define IP2_CALLOUT_MAJOR 72 -#define IP2_IPL_MAJOR 73 - -/* Board configuration array. - * This array defines the hardware irq and address for up to IP2_MAX_BOARDS - * (4 supported per ip2_types.h) ISA board addresses and irqs MUST be specified, - * PCI and EISA boards are probed for and automagicly configed - * iff the addresses are set to 1 and 2 respectivily. - * 0x0100 - 0x03f0 == ISA - * 1 == PCI - * 2 == EISA - * 0 == (skip this board) - * This array defines the hardware addresses for them. Special - * addresses are EISA and PCI which go sniffing for boards. - - * In a multiboard system the position in the array determines which port - * devices are assigned to each board: - * board 0 is assigned ttyF0.. to ttyF63, - * board 1 is assigned ttyF64 to ttyF127, - * board 2 is assigned ttyF128 to ttyF191, - * board 3 is assigned ttyF192 to ttyF255. - * - * In PCI and EISA bus systems each range is mapped to card in - * monotonically increasing slot number order, ISA position is as specified - * here. - - * If the irqs are ALL set to 0,0,0,0 all boards operate in - * polled mode. For interrupt operation ISA boards require that the IRQ be - * specified, while PCI and EISA boards any nonzero entry - * will enable interrupts using the BIOS configured irq for the board. - * An invalid irq entry will default to polled mode for that card and print - * console warning. - - * When the driver is loaded as a module these setting can be overridden on the - * modprobe command line or on an option line in /etc/modprobe.conf. - * If the driver is built-in the configuration must be - * set here for ISA cards and address set to 1 and 2 for PCI and EISA. - * - * Here is an example that shows most if not all possibe combinations: - - *static ip2config_t ip2config = - *{ - * {11,1,0,0}, // irqs - * { // Addresses - * 0x0308, // Board 0, ttyF0 - ttyF63// ISA card at io=0x308, irq=11 - * 0x0001, // Board 1, ttyF64 - ttyF127//PCI card configured by BIOS - * 0x0000, // Board 2, ttyF128 - ttyF191// Slot skipped - * 0x0002 // Board 3, ttyF192 - ttyF255//EISA card configured by BIOS - * // but polled not irq driven - * } - *}; - */ - - /* this structure is zeroed out because the suggested method is to configure - * the driver as a module, set up the parameters with an options line in - * /etc/modprobe.conf and load with modprobe or kmod, the kernel - * module loader - */ - - /* This structure is NOW always initialized when the driver is initialized. - * Compiled in defaults MUST be added to the io and irq arrays in - * ip2.c. Those values are configurable from insmod parameters in the - * case of modules or from command line parameters (ip2=io,irq) when - * compiled in. - */ - -static ip2config_t ip2config = -{ - {0,0,0,0}, // irqs - { // Addresses - /* Do NOT set compile time defaults HERE! Use the arrays in - ip2.c! These WILL be overwritten! =mhw= */ - 0x0000, // Board 0, ttyF0 - ttyF63 - 0x0000, // Board 1, ttyF64 - ttyF127 - 0x0000, // Board 2, ttyF128 - ttyF191 - 0x0000 // Board 3, ttyF192 - ttyF255 - } -}; - -#endif diff --git a/drivers/char/ip2/ip2ioctl.h b/drivers/char/ip2/ip2ioctl.h deleted file mode 100644 index aa0a9da85e05..000000000000 --- a/drivers/char/ip2/ip2ioctl.h +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* -* -* (c) 1998 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Driver constants for configuration and tuning -* -* NOTES: -* -*******************************************************************************/ - -#ifndef IP2IOCTL_H -#define IP2IOCTL_H - -//************* -//* Constants * -//************* - -// High baud rates (if not defined elsewhere. -#ifndef B153600 -# define B153600 0010005 -#endif -#ifndef B307200 -# define B307200 0010006 -#endif -#ifndef B921600 -# define B921600 0010007 -#endif - -#endif diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c deleted file mode 100644 index ea7a8fb08283..000000000000 --- a/drivers/char/ip2/ip2main.c +++ /dev/null @@ -1,3234 +0,0 @@ -/* -* -* (c) 1999 by Computone Corporation -* -******************************************************************************** -* -* PACKAGE: Linux tty Device Driver for IntelliPort family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Mainline code for the device driver -* -*******************************************************************************/ -// ToDo: -// -// Fix the immediate DSS_NOW problem. -// Work over the channel stats return logic in ip2_ipl_ioctl so they -// make sense for all 256 possible channels and so the user space -// utilities will compile and work properly. -// -// Done: -// -// 1.2.14 /\/\|=mhw=|\/\/ -// Added bounds checking to ip2_ipl_ioctl to avoid potential terroristic acts. -// Changed the definition of ip2trace to be more consistent with kernel style -// Thanks to Andreas Dilger for these updates -// -// 1.2.13 /\/\|=mhw=|\/\/ -// DEVFS: Renamed ttf/{n} to tts/F{n} and cuf/{n} to cua/F{n} to conform -// to agreed devfs serial device naming convention. -// -// 1.2.12 /\/\|=mhw=|\/\/ -// Cleaned up some remove queue cut and paste errors -// -// 1.2.11 /\/\|=mhw=|\/\/ -// Clean up potential NULL pointer dereferences -// Clean up devfs registration -// Add kernel command line parsing for io and irq -// Compile defaults for io and irq are now set in ip2.c not ip2.h! -// Reworked poll_only hack for explicit parameter setting -// You must now EXPLICITLY set poll_only = 1 or set all irqs to 0 -// Merged ip2_loadmain and old_ip2_init -// Converted all instances of interruptible_sleep_on into queue calls -// Most of these had no race conditions but better to clean up now -// -// 1.2.10 /\/\|=mhw=|\/\/ -// Fixed the bottom half interrupt handler and enabled USE_IQI -// to split the interrupt handler into a formal top-half / bottom-half -// Fixed timing window on high speed processors that queued messages to -// the outbound mail fifo faster than the board could handle. -// -// 1.2.9 -// Four box EX was barfing on >128k kmalloc, made structure smaller by -// reducing output buffer size -// -// 1.2.8 -// Device file system support (MHW) -// -// 1.2.7 -// Fixed -// Reload of ip2 without unloading ip2main hangs system on cat of /proc/modules -// -// 1.2.6 -//Fixes DCD problems -// DCD was not reported when CLOCAL was set on call to TIOCMGET -// -//Enhancements: -// TIOCMGET requests and waits for status return -// No DSS interrupts enabled except for DCD when needed -// -// For internal use only -// -//#define IP2DEBUG_INIT -//#define IP2DEBUG_OPEN -//#define IP2DEBUG_WRITE -//#define IP2DEBUG_READ -//#define IP2DEBUG_IOCTL -//#define IP2DEBUG_IPL - -//#define IP2DEBUG_TRACE -//#define DEBUG_FIFO - -/************/ -/* Includes */ -/************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include - -#include "ip2types.h" -#include "ip2trace.h" -#include "ip2ioctl.h" -#include "ip2.h" -#include "i2ellis.h" -#include "i2lib.h" - -/***************** - * /proc/ip2mem * - *****************/ - -#include -#include - -static DEFINE_MUTEX(ip2_mutex); -static const struct file_operations ip2mem_proc_fops; -static const struct file_operations ip2_proc_fops; - -/********************/ -/* Type Definitions */ -/********************/ - -/*************/ -/* Constants */ -/*************/ - -/* String constants to identify ourselves */ -static const char pcName[] = "Computone IntelliPort Plus multiport driver"; -static const char pcVersion[] = "1.2.14"; - -/* String constants for port names */ -static const char pcDriver_name[] = "ip2"; -static const char pcIpl[] = "ip2ipl"; - -/***********************/ -/* Function Prototypes */ -/***********************/ - -/* Global module entry functions */ - -/* Private (static) functions */ -static int ip2_open(PTTY, struct file *); -static void ip2_close(PTTY, struct file *); -static int ip2_write(PTTY, const unsigned char *, int); -static int ip2_putchar(PTTY, unsigned char); -static void ip2_flush_chars(PTTY); -static int ip2_write_room(PTTY); -static int ip2_chars_in_buf(PTTY); -static void ip2_flush_buffer(PTTY); -static int ip2_ioctl(PTTY, UINT, ULONG); -static void ip2_set_termios(PTTY, struct ktermios *); -static void ip2_set_line_discipline(PTTY); -static void ip2_throttle(PTTY); -static void ip2_unthrottle(PTTY); -static void ip2_stop(PTTY); -static void ip2_start(PTTY); -static void ip2_hangup(PTTY); -static int ip2_tiocmget(struct tty_struct *tty); -static int ip2_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear); -static int ip2_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount); - -static void set_irq(int, int); -static void ip2_interrupt_bh(struct work_struct *work); -static irqreturn_t ip2_interrupt(int irq, void *dev_id); -static void ip2_poll(unsigned long arg); -static inline void service_all_boards(void); -static void do_input(struct work_struct *); -static void do_status(struct work_struct *); - -static void ip2_wait_until_sent(PTTY,int); - -static void set_params (i2ChanStrPtr, struct ktermios *); -static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *); -static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *); - -static ssize_t ip2_ipl_read(struct file *, char __user *, size_t, loff_t *); -static ssize_t ip2_ipl_write(struct file *, const char __user *, size_t, loff_t *); -static long ip2_ipl_ioctl(struct file *, UINT, ULONG); -static int ip2_ipl_open(struct inode *, struct file *); - -static int DumpTraceBuffer(char __user *, int); -static int DumpFifoBuffer( char __user *, int); - -static void ip2_init_board(int, const struct firmware *); -static unsigned short find_eisa_board(int); -static int ip2_setup(char *str); - -/***************/ -/* Static Data */ -/***************/ - -static struct tty_driver *ip2_tty_driver; - -/* Here, then is a table of board pointers which the interrupt routine should - * scan through to determine who it must service. - */ -static unsigned short i2nBoards; // Number of boards here - -static i2eBordStrPtr i2BoardPtrTable[IP2_MAX_BOARDS]; - -static i2ChanStrPtr DevTable[IP2_MAX_PORTS]; -//DevTableMem just used to save addresses for kfree -static void *DevTableMem[IP2_MAX_BOARDS]; - -/* This is the driver descriptor for the ip2ipl device, which is used to - * download the loadware to the boards. - */ -static const struct file_operations ip2_ipl = { - .owner = THIS_MODULE, - .read = ip2_ipl_read, - .write = ip2_ipl_write, - .unlocked_ioctl = ip2_ipl_ioctl, - .open = ip2_ipl_open, - .llseek = noop_llseek, -}; - -static unsigned long irq_counter; -static unsigned long bh_counter; - -// Use immediate queue to service interrupts -#define USE_IQI -//#define USE_IQ // PCI&2.2 needs work - -/* The timer_list entry for our poll routine. If interrupt operation is not - * selected, the board is serviced periodically to see if anything needs doing. - */ -#define POLL_TIMEOUT (jiffies + 1) -static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0); - -#ifdef IP2DEBUG_TRACE -/* Trace (debug) buffer data */ -#define TRACEMAX 1000 -static unsigned long tracebuf[TRACEMAX]; -static int tracestuff; -static int tracestrip; -static int tracewrap; -#endif - -/**********/ -/* Macros */ -/**********/ - -#ifdef IP2DEBUG_OPEN -#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] ttyc=%d, modc=%x -> %s\n", \ - tty->name,(pCh->flags), \ - tty->count,/*GET_USE_COUNT(module)*/0,s) -#else -#define DBG_CNT(s) -#endif - -/********/ -/* Code */ -/********/ - -#include "i2ellis.c" /* Extremely low-level interface services */ -#include "i2cmd.c" /* Standard loadware command definitions */ -#include "i2lib.c" /* High level interface services */ - -/* Configuration area for modprobe */ - -MODULE_AUTHOR("Doug McNash"); -MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); -MODULE_LICENSE("GPL"); - -#define MAX_CMD_STR 50 - -static int poll_only; -static char cmd[MAX_CMD_STR]; - -static int Eisa_irq; -static int Eisa_slot; - -static int iindx; -static char rirqs[IP2_MAX_BOARDS]; -static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0}; - -/* Note: Add compiled in defaults to these arrays, not to the structure - in ip2.h any longer. That structure WILL get overridden - by these values, or command line values, or insmod values!!! =mhw= -*/ -static int io[IP2_MAX_BOARDS]; -static int irq[IP2_MAX_BOARDS] = { -1, -1, -1, -1 }; - -MODULE_AUTHOR("Doug McNash"); -MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); -module_param_array(irq, int, NULL, 0); -MODULE_PARM_DESC(irq, "Interrupts for IntelliPort Cards"); -module_param_array(io, int, NULL, 0); -MODULE_PARM_DESC(io, "I/O ports for IntelliPort Cards"); -module_param(poll_only, bool, 0); -MODULE_PARM_DESC(poll_only, "Do not use card interrupts"); -module_param_string(ip2, cmd, MAX_CMD_STR, 0); -MODULE_PARM_DESC(ip2, "Contains module parameter passed with 'ip2='"); - -/* for sysfs class support */ -static struct class *ip2_class; - -/* Some functions to keep track of what irqs we have */ - -static int __init is_valid_irq(int irq) -{ - int *i = Valid_Irqs; - - while (*i != 0 && *i != irq) - i++; - - return *i; -} - -static void __init mark_requested_irq(char irq) -{ - rirqs[iindx++] = irq; -} - -static int __exit clear_requested_irq(char irq) -{ - int i; - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - if (rirqs[i] == irq) { - rirqs[i] = 0; - return 1; - } - } - return 0; -} - -static int have_requested_irq(char irq) -{ - /* array init to zeros so 0 irq will not be requested as a side - * effect */ - int i; - for (i = 0; i < IP2_MAX_BOARDS; ++i) - if (rirqs[i] == irq) - return 1; - return 0; -} - -/******************************************************************************/ -/* Function: cleanup_module() */ -/* Parameters: None */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* This is a required entry point for an installable module. It has to return */ -/* the device and the driver to a passive state. It should not be necessary */ -/* to reset the board fully, especially as the loadware is downloaded */ -/* externally rather than in the driver. We just want to disable the board */ -/* and clear the loadware to a reset state. To allow this there has to be a */ -/* way to detect whether the board has the loadware running at init time to */ -/* handle subsequent installations of the driver. All memory allocated by the */ -/* driver should be returned since it may be unloaded from memory. */ -/******************************************************************************/ -static void __exit ip2_cleanup_module(void) -{ - int err; - int i; - - del_timer_sync(&PollTimer); - - /* Reset the boards we have. */ - for (i = 0; i < IP2_MAX_BOARDS; i++) - if (i2BoardPtrTable[i]) - iiReset(i2BoardPtrTable[i]); - - /* The following is done at most once, if any boards were installed. */ - for (i = 0; i < IP2_MAX_BOARDS; i++) { - if (i2BoardPtrTable[i]) { - iiResetDelay(i2BoardPtrTable[i]); - /* free io addresses and Tibet */ - release_region(ip2config.addr[i], 8); - device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i)); - device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, - 4 * i + 1)); - } - /* Disable and remove interrupt handler. */ - if (ip2config.irq[i] > 0 && - have_requested_irq(ip2config.irq[i])) { - free_irq(ip2config.irq[i], (void *)&pcName); - clear_requested_irq(ip2config.irq[i]); - } - } - class_destroy(ip2_class); - err = tty_unregister_driver(ip2_tty_driver); - if (err) - printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", - err); - put_tty_driver(ip2_tty_driver); - unregister_chrdev(IP2_IPL_MAJOR, pcIpl); - remove_proc_entry("ip2mem", NULL); - - /* free memory */ - for (i = 0; i < IP2_MAX_BOARDS; i++) { - void *pB; -#ifdef CONFIG_PCI - if (ip2config.type[i] == PCI && ip2config.pci_dev[i]) { - pci_disable_device(ip2config.pci_dev[i]); - pci_dev_put(ip2config.pci_dev[i]); - ip2config.pci_dev[i] = NULL; - } -#endif - pB = i2BoardPtrTable[i]; - if (pB != NULL) { - kfree(pB); - i2BoardPtrTable[i] = NULL; - } - if (DevTableMem[i] != NULL) { - kfree(DevTableMem[i]); - DevTableMem[i] = NULL; - } - } -} -module_exit(ip2_cleanup_module); - -static const struct tty_operations ip2_ops = { - .open = ip2_open, - .close = ip2_close, - .write = ip2_write, - .put_char = ip2_putchar, - .flush_chars = ip2_flush_chars, - .write_room = ip2_write_room, - .chars_in_buffer = ip2_chars_in_buf, - .flush_buffer = ip2_flush_buffer, - .ioctl = ip2_ioctl, - .throttle = ip2_throttle, - .unthrottle = ip2_unthrottle, - .set_termios = ip2_set_termios, - .set_ldisc = ip2_set_line_discipline, - .stop = ip2_stop, - .start = ip2_start, - .hangup = ip2_hangup, - .tiocmget = ip2_tiocmget, - .tiocmset = ip2_tiocmset, - .get_icount = ip2_get_icount, - .proc_fops = &ip2_proc_fops, -}; - -/******************************************************************************/ -/* Function: ip2_loadmain() */ -/* Parameters: irq, io from command line of insmod et. al. */ -/* pointer to fip firmware and firmware size for boards */ -/* Returns: Success (0) */ -/* */ -/* Description: */ -/* This was the required entry point for all drivers (now in ip2.c) */ -/* It performs all */ -/* initialisation of the devices and driver structures, and registers itself */ -/* with the relevant kernel modules. */ -/******************************************************************************/ -/* IRQF_DISABLED - if set blocks all interrupts else only this line */ -/* IRQF_SHARED - for shared irq PCI or maybe EISA only */ -/* SA_RANDOM - can be source for cert. random number generators */ -#define IP2_SA_FLAGS 0 - - -static const struct firmware *ip2_request_firmware(void) -{ - struct platform_device *pdev; - const struct firmware *fw; - - pdev = platform_device_register_simple("ip2", 0, NULL, 0); - if (IS_ERR(pdev)) { - printk(KERN_ERR "Failed to register platform device for ip2\n"); - return NULL; - } - if (request_firmware(&fw, "intelliport2.bin", &pdev->dev)) { - printk(KERN_ERR "Failed to load firmware 'intelliport2.bin'\n"); - fw = NULL; - } - platform_device_unregister(pdev); - return fw; -} - -/****************************************************************************** - * ip2_setup: - * str: kernel command line string - * - * Can't autoprobe the boards so user must specify configuration on - * kernel command line. Sane people build it modular but the others - * come here. - * - * Alternating pairs of io,irq for up to 4 boards. - * ip2=io0,irq0,io1,irq1,io2,irq2,io3,irq3 - * - * io=0 => No board - * io=1 => PCI - * io=2 => EISA - * else => ISA I/O address - * - * irq=0 or invalid for ISA will revert to polling mode - * - * Any value = -1, do not overwrite compiled in value. - * - ******************************************************************************/ -static int __init ip2_setup(char *str) -{ - int j, ints[10]; /* 4 boards, 2 parameters + 2 */ - unsigned int i; - - str = get_options(str, ARRAY_SIZE(ints), ints); - - for (i = 0, j = 1; i < 4; i++) { - if (j > ints[0]) - break; - if (ints[j] >= 0) - io[i] = ints[j]; - j++; - if (j > ints[0]) - break; - if (ints[j] >= 0) - irq[i] = ints[j]; - j++; - } - return 1; -} -__setup("ip2=", ip2_setup); - -static int __init ip2_loadmain(void) -{ - int i, j, box; - int err = 0; - i2eBordStrPtr pB = NULL; - int rc = -1; - const struct firmware *fw = NULL; - char *str; - - str = cmd; - - if (poll_only) { - /* Hard lock the interrupts to zero */ - irq[0] = irq[1] = irq[2] = irq[3] = poll_only = 0; - } - - /* Check module parameter with 'ip2=' has been passed or not */ - if (!poll_only && (!strncmp(str, "ip2=", 4))) - ip2_setup(str); - - ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0); - - /* process command line arguments to modprobe or - insmod i.e. iop & irqp */ - /* irqp and iop should ALWAYS be specified now... But we check - them individually just to be sure, anyways... */ - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - ip2config.addr[i] = io[i]; - if (irq[i] >= 0) - ip2config.irq[i] = irq[i]; - else - ip2config.irq[i] = 0; - /* This is a little bit of a hack. If poll_only=1 on command - line back in ip2.c OR all IRQs on all specified boards are - explicitly set to 0, then drop to poll only mode and override - PCI or EISA interrupts. This superceeds the old hack of - triggering if all interrupts were zero (like da default). - Still a hack but less prone to random acts of terrorism. - - What we really should do, now that the IRQ default is set - to -1, is to use 0 as a hard coded, do not probe. - - /\/\|=mhw=|\/\/ - */ - poll_only |= irq[i]; - } - poll_only = !poll_only; - - /* Announce our presence */ - printk(KERN_INFO "%s version %s\n", pcName, pcVersion); - - ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS); - if (!ip2_tty_driver) - return -ENOMEM; - - /* Initialise all the boards we can find (up to the maximum). */ - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - switch (ip2config.addr[i]) { - case 0: /* skip this slot even if card is present */ - break; - default: /* ISA */ - /* ISA address must be specified */ - if (ip2config.addr[i] < 0x100 || - ip2config.addr[i] > 0x3f8) { - printk(KERN_ERR "IP2: Bad ISA board %d " - "address %x\n", i, - ip2config.addr[i]); - ip2config.addr[i] = 0; - break; - } - ip2config.type[i] = ISA; - - /* Check for valid irq argument, set for polling if - * invalid */ - if (ip2config.irq[i] && - !is_valid_irq(ip2config.irq[i])) { - printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n", - ip2config.irq[i]); - /* 0 is polling and is valid in that sense */ - ip2config.irq[i] = 0; - } - break; - case PCI: -#ifdef CONFIG_PCI - { - struct pci_dev *pdev = NULL; - u32 addr; - int status; - - pdev = pci_get_device(PCI_VENDOR_ID_COMPUTONE, - PCI_DEVICE_ID_COMPUTONE_IP2EX, pdev); - if (pdev == NULL) { - ip2config.addr[i] = 0; - printk(KERN_ERR "IP2: PCI board %d not " - "found\n", i); - break; - } - - if (pci_enable_device(pdev)) { - dev_err(&pdev->dev, "can't enable device\n"); - goto out; - } - ip2config.type[i] = PCI; - ip2config.pci_dev[i] = pci_dev_get(pdev); - status = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_1, - &addr); - if (addr & 1) - ip2config.addr[i] = (USHORT)(addr & 0xfffe); - else - dev_err(&pdev->dev, "I/O address error\n"); - - ip2config.irq[i] = pdev->irq; -out: - pci_dev_put(pdev); - } -#else - printk(KERN_ERR "IP2: PCI card specified but PCI " - "support not enabled.\n"); - printk(KERN_ERR "IP2: Recompile kernel with CONFIG_PCI " - "defined!\n"); -#endif /* CONFIG_PCI */ - break; - case EISA: - ip2config.addr[i] = find_eisa_board(Eisa_slot + 1); - if (ip2config.addr[i] != 0) { - /* Eisa_irq set as side effect, boo */ - ip2config.type[i] = EISA; - } - ip2config.irq[i] = Eisa_irq; - break; - } /* switch */ - } /* for */ - - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - if (ip2config.addr[i]) { - pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL); - if (pB) { - i2BoardPtrTable[i] = pB; - iiSetAddress(pB, ip2config.addr[i], - ii2DelayTimer); - iiReset(pB); - } else - printk(KERN_ERR "IP2: board memory allocation " - "error\n"); - } - } - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - pB = i2BoardPtrTable[i]; - if (pB != NULL) { - iiResetDelay(pB); - break; - } - } - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - /* We don't want to request the firmware unless we have at - least one board */ - if (i2BoardPtrTable[i] != NULL) { - if (!fw) - fw = ip2_request_firmware(); - if (!fw) - break; - ip2_init_board(i, fw); - } - } - if (fw) - release_firmware(fw); - - ip2trace(ITRC_NO_PORT, ITRC_INIT, 2, 0); - - ip2_tty_driver->owner = THIS_MODULE; - ip2_tty_driver->name = "ttyF"; - ip2_tty_driver->driver_name = pcDriver_name; - ip2_tty_driver->major = IP2_TTY_MAJOR; - ip2_tty_driver->minor_start = 0; - ip2_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL; - ip2_tty_driver->init_termios = tty_std_termios; - ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; - ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW | - TTY_DRIVER_DYNAMIC_DEV; - tty_set_operations(ip2_tty_driver, &ip2_ops); - - ip2trace(ITRC_NO_PORT, ITRC_INIT, 3, 0); - - err = tty_register_driver(ip2_tty_driver); - if (err) { - printk(KERN_ERR "IP2: failed to register tty driver\n"); - put_tty_driver(ip2_tty_driver); - return err; /* leaking resources */ - } - - err = register_chrdev(IP2_IPL_MAJOR, pcIpl, &ip2_ipl); - if (err) { - printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", - err); - } else { - /* create the sysfs class */ - ip2_class = class_create(THIS_MODULE, "ip2"); - if (IS_ERR(ip2_class)) { - err = PTR_ERR(ip2_class); - goto out_chrdev; - } - } - /* Register the read_procmem thing */ - if (!proc_create("ip2mem",0,NULL,&ip2mem_proc_fops)) { - printk(KERN_ERR "IP2: failed to register read_procmem\n"); - return -EIO; /* leaking resources */ - } - - ip2trace(ITRC_NO_PORT, ITRC_INIT, 4, 0); - /* Register the interrupt handler or poll handler, depending upon the - * specified interrupt. - */ - - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - if (ip2config.addr[i] == 0) - continue; - - pB = i2BoardPtrTable[i]; - if (pB != NULL) { - device_create(ip2_class, NULL, - MKDEV(IP2_IPL_MAJOR, 4 * i), - NULL, "ipl%d", i); - device_create(ip2_class, NULL, - MKDEV(IP2_IPL_MAJOR, 4 * i + 1), - NULL, "stat%d", i); - - for (box = 0; box < ABS_MAX_BOXES; box++) - for (j = 0; j < ABS_BIGGEST_BOX; j++) - if (pB->i2eChannelMap[box] & (1 << j)) - tty_register_device( - ip2_tty_driver, - j + ABS_BIGGEST_BOX * - (box+i*ABS_MAX_BOXES), - NULL); - } - - if (poll_only) { - /* Poll only forces driver to only use polling and - to ignore the probed PCI or EISA interrupts. */ - ip2config.irq[i] = CIR_POLL; - } - if (ip2config.irq[i] == CIR_POLL) { -retry: - if (!timer_pending(&PollTimer)) { - mod_timer(&PollTimer, POLL_TIMEOUT); - printk(KERN_INFO "IP2: polling\n"); - } - } else { - if (have_requested_irq(ip2config.irq[i])) - continue; - rc = request_irq(ip2config.irq[i], ip2_interrupt, - IP2_SA_FLAGS | - (ip2config.type[i] == PCI ? IRQF_SHARED : 0), - pcName, i2BoardPtrTable[i]); - if (rc) { - printk(KERN_ERR "IP2: request_irq failed: " - "error %d\n", rc); - ip2config.irq[i] = CIR_POLL; - printk(KERN_INFO "IP2: Polling %ld/sec.\n", - (POLL_TIMEOUT - jiffies)); - goto retry; - } - mark_requested_irq(ip2config.irq[i]); - /* Initialise the interrupt handler bottom half - * (aka slih). */ - } - } - - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - if (i2BoardPtrTable[i]) { - /* set and enable board interrupt */ - set_irq(i, ip2config.irq[i]); - } - } - - ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0); - - return 0; - -out_chrdev: - unregister_chrdev(IP2_IPL_MAJOR, "ip2"); - /* unregister and put tty here */ - return err; -} -module_init(ip2_loadmain); - -/******************************************************************************/ -/* Function: ip2_init_board() */ -/* Parameters: Index of board in configuration structure */ -/* Returns: Success (0) */ -/* */ -/* Description: */ -/* This function initializes the specified board. The loadware is copied to */ -/* the board, the channel structures are initialized, and the board details */ -/* are reported on the console. */ -/******************************************************************************/ -static void -ip2_init_board(int boardnum, const struct firmware *fw) -{ - int i; - int nports = 0, nboxes = 0; - i2ChanStrPtr pCh; - i2eBordStrPtr pB = i2BoardPtrTable[boardnum]; - - if ( !iiInitialize ( pB ) ) { - printk ( KERN_ERR "IP2: Failed to initialize board at 0x%x, error %d\n", - pB->i2eBase, pB->i2eError ); - goto err_initialize; - } - printk(KERN_INFO "IP2: Board %d: addr=0x%x irq=%d\n", boardnum + 1, - ip2config.addr[boardnum], ip2config.irq[boardnum] ); - - if (!request_region( ip2config.addr[boardnum], 8, pcName )) { - printk(KERN_ERR "IP2: bad addr=0x%x\n", ip2config.addr[boardnum]); - goto err_initialize; - } - - if ( iiDownloadAll ( pB, (loadHdrStrPtr)fw->data, 1, fw->size ) - != II_DOWN_GOOD ) { - printk ( KERN_ERR "IP2: failed to download loadware\n" ); - goto err_release_region; - } else { - printk ( KERN_INFO "IP2: fv=%d.%d.%d lv=%d.%d.%d\n", - pB->i2ePom.e.porVersion, - pB->i2ePom.e.porRevision, - pB->i2ePom.e.porSubRev, pB->i2eLVersion, - pB->i2eLRevision, pB->i2eLSub ); - } - - switch ( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) { - - default: - printk( KERN_ERR "IP2: Unknown board type, ID = %x\n", - pB->i2ePom.e.porID ); - nports = 0; - goto err_release_region; - break; - - case POR_ID_II_4: /* IntelliPort-II, ISA-4 (4xRJ45) */ - printk ( KERN_INFO "IP2: ISA-4\n" ); - nports = 4; - break; - - case POR_ID_II_8: /* IntelliPort-II, 8-port using standard brick. */ - printk ( KERN_INFO "IP2: ISA-8 std\n" ); - nports = 8; - break; - - case POR_ID_II_8R: /* IntelliPort-II, 8-port using RJ11's (no CTS) */ - printk ( KERN_INFO "IP2: ISA-8 RJ11\n" ); - nports = 8; - break; - - case POR_ID_FIIEX: /* IntelliPort IIEX */ - { - int portnum = IP2_PORTS_PER_BOARD * boardnum; - int box; - - for( box = 0; box < ABS_MAX_BOXES; ++box ) { - if ( pB->i2eChannelMap[box] != 0 ) { - ++nboxes; - } - for( i = 0; i < ABS_BIGGEST_BOX; ++i ) { - if ( pB->i2eChannelMap[box] & 1<< i ) { - ++nports; - } - } - } - DevTableMem[boardnum] = pCh = - kmalloc( sizeof(i2ChanStr) * nports, GFP_KERNEL ); - if ( !pCh ) { - printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n"); - goto err_release_region; - } - if ( !i2InitChannels( pB, nports, pCh ) ) { - printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError); - kfree ( pCh ); - goto err_release_region; - } - pB->i2eChannelPtr = &DevTable[portnum]; - pB->i2eChannelCnt = ABS_MOST_PORTS; - - for( box = 0; box < ABS_MAX_BOXES; ++box, portnum += ABS_BIGGEST_BOX ) { - for( i = 0; i < ABS_BIGGEST_BOX; ++i ) { - if ( pB->i2eChannelMap[box] & (1 << i) ) { - DevTable[portnum + i] = pCh; - pCh->port_index = portnum + i; - pCh++; - } - } - } - printk(KERN_INFO "IP2: EX box=%d ports=%d %d bit\n", - nboxes, nports, pB->i2eDataWidth16 ? 16 : 8 ); - } - goto ex_exit; - } - DevTableMem[boardnum] = pCh = - kmalloc ( sizeof (i2ChanStr) * nports, GFP_KERNEL ); - if ( !pCh ) { - printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n"); - goto err_release_region; - } - pB->i2eChannelPtr = pCh; - pB->i2eChannelCnt = nports; - if ( !i2InitChannels( pB, nports, pCh ) ) { - printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError); - kfree ( pCh ); - goto err_release_region; - } - pB->i2eChannelPtr = &DevTable[IP2_PORTS_PER_BOARD * boardnum]; - - for( i = 0; i < pB->i2eChannelCnt; ++i ) { - DevTable[IP2_PORTS_PER_BOARD * boardnum + i] = pCh; - pCh->port_index = (IP2_PORTS_PER_BOARD * boardnum) + i; - pCh++; - } -ex_exit: - INIT_WORK(&pB->tqueue_interrupt, ip2_interrupt_bh); - return; - -err_release_region: - release_region(ip2config.addr[boardnum], 8); -err_initialize: - kfree ( pB ); - i2BoardPtrTable[boardnum] = NULL; - return; -} - -/******************************************************************************/ -/* Function: find_eisa_board ( int start_slot ) */ -/* Parameters: First slot to check */ -/* Returns: Address of EISA IntelliPort II controller */ -/* */ -/* Description: */ -/* This function searches for an EISA IntelliPort controller, starting */ -/* from the specified slot number. If the motherboard is not identified as an */ -/* EISA motherboard, or no valid board ID is selected it returns 0. Otherwise */ -/* it returns the base address of the controller. */ -/******************************************************************************/ -static unsigned short -find_eisa_board( int start_slot ) -{ - int i, j; - unsigned int idm = 0; - unsigned int idp = 0; - unsigned int base = 0; - unsigned int value; - int setup_address; - int setup_irq; - int ismine = 0; - - /* - * First a check for an EISA motherboard, which we do by comparing the - * EISA ID registers for the system board and the first couple of slots. - * No slot ID should match the system board ID, but on an ISA or PCI - * machine the odds are that an empty bus will return similar values for - * each slot. - */ - i = 0x0c80; - value = (inb(i) << 24) + (inb(i+1) << 16) + (inb(i+2) << 8) + inb(i+3); - for( i = 0x1c80; i <= 0x4c80; i += 0x1000 ) { - j = (inb(i)<<24)+(inb(i+1)<<16)+(inb(i+2)<<8)+inb(i+3); - if ( value == j ) - return 0; - } - - /* - * OK, so we are inclined to believe that this is an EISA machine. Find - * an IntelliPort controller. - */ - for( i = start_slot; i < 16; i++ ) { - base = i << 12; - idm = (inb(base + 0xc80) << 8) | (inb(base + 0xc81) & 0xff); - idp = (inb(base + 0xc82) << 8) | (inb(base + 0xc83) & 0xff); - ismine = 0; - if ( idm == 0x0e8e ) { - if ( idp == 0x0281 || idp == 0x0218 ) { - ismine = 1; - } else if ( idp == 0x0282 || idp == 0x0283 ) { - ismine = 3; /* Can do edge-trigger */ - } - if ( ismine ) { - Eisa_slot = i; - break; - } - } - } - if ( !ismine ) - return 0; - - /* It's some sort of EISA card, but at what address is it configured? */ - - setup_address = base + 0xc88; - value = inb(base + 0xc86); - setup_irq = (value & 8) ? Valid_Irqs[value & 7] : 0; - - if ( (ismine & 2) && !(value & 0x10) ) { - ismine = 1; /* Could be edging, but not */ - } - - if ( Eisa_irq == 0 ) { - Eisa_irq = setup_irq; - } else if ( Eisa_irq != setup_irq ) { - printk ( KERN_ERR "IP2: EISA irq mismatch between EISA controllers\n" ); - } - -#ifdef IP2DEBUG_INIT -printk(KERN_DEBUG "Computone EISA board in slot %d, I.D. 0x%x%x, Address 0x%x", - base >> 12, idm, idp, setup_address); - if ( Eisa_irq ) { - printk(KERN_DEBUG ", Interrupt %d %s\n", - setup_irq, (ismine & 2) ? "(edge)" : "(level)"); - } else { - printk(KERN_DEBUG ", (polled)\n"); - } -#endif - return setup_address; -} - -/******************************************************************************/ -/* Function: set_irq() */ -/* Parameters: index to board in board table */ -/* IRQ to use */ -/* Returns: Success (0) */ -/* */ -/* Description: */ -/******************************************************************************/ -static void -set_irq( int boardnum, int boardIrq ) -{ - unsigned char tempCommand[16]; - i2eBordStrPtr pB = i2BoardPtrTable[boardnum]; - unsigned long flags; - - /* - * Notify the boards they may generate interrupts. This is done by - * sending an in-line command to channel 0 on each board. This is why - * the channels have to be defined already. For each board, if the - * interrupt has never been defined, we must do so NOW, directly, since - * board will not send flow control or even give an interrupt until this - * is done. If polling we must send 0 as the interrupt parameter. - */ - - // We will get an interrupt here at the end of this function - - iiDisableMailIrq(pB); - - /* We build up the entire packet header. */ - CHANNEL_OF(tempCommand) = 0; - PTYPE_OF(tempCommand) = PTYPE_INLINE; - CMD_COUNT_OF(tempCommand) = 2; - (CMD_OF(tempCommand))[0] = CMDVALUE_IRQ; - (CMD_OF(tempCommand))[1] = boardIrq; - /* - * Write to FIFO; don't bother to adjust fifo capacity for this, since - * board will respond almost immediately after SendMail hit. - */ - write_lock_irqsave(&pB->write_fifo_spinlock, flags); - iiWriteBuf(pB, tempCommand, 4); - write_unlock_irqrestore(&pB->write_fifo_spinlock, flags); - pB->i2eUsingIrq = boardIrq; - pB->i2eOutMailWaiting |= MB_OUT_STUFFED; - - /* Need to update number of boards before you enable mailbox int */ - ++i2nBoards; - - CHANNEL_OF(tempCommand) = 0; - PTYPE_OF(tempCommand) = PTYPE_BYPASS; - CMD_COUNT_OF(tempCommand) = 6; - (CMD_OF(tempCommand))[0] = 88; // SILO - (CMD_OF(tempCommand))[1] = 64; // chars - (CMD_OF(tempCommand))[2] = 32; // ms - - (CMD_OF(tempCommand))[3] = 28; // MAX_BLOCK - (CMD_OF(tempCommand))[4] = 64; // chars - - (CMD_OF(tempCommand))[5] = 87; // HW_TEST - write_lock_irqsave(&pB->write_fifo_spinlock, flags); - iiWriteBuf(pB, tempCommand, 8); - write_unlock_irqrestore(&pB->write_fifo_spinlock, flags); - - CHANNEL_OF(tempCommand) = 0; - PTYPE_OF(tempCommand) = PTYPE_BYPASS; - CMD_COUNT_OF(tempCommand) = 1; - (CMD_OF(tempCommand))[0] = 84; /* get BOX_IDS */ - iiWriteBuf(pB, tempCommand, 3); - -#ifdef XXX - // enable heartbeat for test porpoises - CHANNEL_OF(tempCommand) = 0; - PTYPE_OF(tempCommand) = PTYPE_BYPASS; - CMD_COUNT_OF(tempCommand) = 2; - (CMD_OF(tempCommand))[0] = 44; /* get ping */ - (CMD_OF(tempCommand))[1] = 200; /* 200 ms */ - write_lock_irqsave(&pB->write_fifo_spinlock, flags); - iiWriteBuf(pB, tempCommand, 4); - write_unlock_irqrestore(&pB->write_fifo_spinlock, flags); -#endif - - iiEnableMailIrq(pB); - iiSendPendingMail(pB); -} - -/******************************************************************************/ -/* Interrupt Handler Section */ -/******************************************************************************/ - -static inline void -service_all_boards(void) -{ - int i; - i2eBordStrPtr pB; - - /* Service every board on the list */ - for( i = 0; i < IP2_MAX_BOARDS; ++i ) { - pB = i2BoardPtrTable[i]; - if ( pB ) { - i2ServiceBoard( pB ); - } - } -} - - -/******************************************************************************/ -/* Function: ip2_interrupt_bh(work) */ -/* Parameters: work - pointer to the board structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* Service the board in a bottom half interrupt handler and then */ -/* reenable the board's interrupts if it has an IRQ number */ -/* */ -/******************************************************************************/ -static void -ip2_interrupt_bh(struct work_struct *work) -{ - i2eBordStrPtr pB = container_of(work, i2eBordStr, tqueue_interrupt); -// pB better well be set or we have a problem! We can only get -// here from the IMMEDIATE queue. Here, we process the boards. -// Checking pB doesn't cost much and it saves us from the sanity checkers. - - bh_counter++; - - if ( pB ) { - i2ServiceBoard( pB ); - if( pB->i2eUsingIrq ) { -// Re-enable his interrupts - iiEnableMailIrq(pB); - } - } -} - - -/******************************************************************************/ -/* Function: ip2_interrupt(int irq, void *dev_id) */ -/* Parameters: irq - interrupt number */ -/* pointer to optional device ID structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/* Our task here is simply to identify each board which needs servicing. */ -/* If we are queuing then, queue it to be serviced, and disable its irq */ -/* mask otherwise process the board directly. */ -/* */ -/* We could queue by IRQ but that just complicates things on both ends */ -/* with very little gain in performance (how many instructions does */ -/* it take to iterate on the immediate queue). */ -/* */ -/* */ -/******************************************************************************/ -static void -ip2_irq_work(i2eBordStrPtr pB) -{ -#ifdef USE_IQI - if (NO_MAIL_HERE != ( pB->i2eStartMail = iiGetMail(pB))) { -// Disable his interrupt (will be enabled when serviced) -// This is mostly to protect from reentrancy. - iiDisableMailIrq(pB); - -// Park the board on the immediate queue for processing. - schedule_work(&pB->tqueue_interrupt); - -// Make sure the immediate queue is flagged to fire. - } -#else - -// We are using immediate servicing here. This sucks and can -// cause all sorts of havoc with ppp and others. The failsafe -// check on iiSendPendingMail could also throw a hairball. - - i2ServiceBoard( pB ); - -#endif /* USE_IQI */ -} - -static void -ip2_polled_interrupt(void) -{ - int i; - i2eBordStrPtr pB; - - ip2trace(ITRC_NO_PORT, ITRC_INTR, 99, 1, 0); - - /* Service just the boards on the list using this irq */ - for( i = 0; i < i2nBoards; ++i ) { - pB = i2BoardPtrTable[i]; - -// Only process those boards which match our IRQ. -// IRQ = 0 for polled boards, we won't poll "IRQ" boards - - if (pB && pB->i2eUsingIrq == 0) - ip2_irq_work(pB); - } - - ++irq_counter; - - ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); -} - -static irqreturn_t -ip2_interrupt(int irq, void *dev_id) -{ - i2eBordStrPtr pB = dev_id; - - ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, pB->i2eUsingIrq ); - - ip2_irq_work(pB); - - ++irq_counter; - - ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); - return IRQ_HANDLED; -} - -/******************************************************************************/ -/* Function: ip2_poll(unsigned long arg) */ -/* Parameters: ? */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* This function calls the library routine i2ServiceBoard for each board in */ -/* the board table. This is used instead of the interrupt routine when polled */ -/* mode is specified. */ -/******************************************************************************/ -static void -ip2_poll(unsigned long arg) -{ - ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 ); - - // Just polled boards, IRQ = 0 will hit all non-interrupt boards. - // It will NOT poll boards handled by hard interrupts. - // The issue of queued BH interrupts is handled in ip2_interrupt(). - ip2_polled_interrupt(); - - mod_timer(&PollTimer, POLL_TIMEOUT); - - ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); -} - -static void do_input(struct work_struct *work) -{ - i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_input); - unsigned long flags; - - ip2trace(CHANN, ITRC_INPUT, 21, 0 ); - - // Data input - if ( pCh->pTTY != NULL ) { - read_lock_irqsave(&pCh->Ibuf_spinlock, flags); - if (!pCh->throttled && (pCh->Ibuf_stuff != pCh->Ibuf_strip)) { - read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); - i2Input( pCh ); - } else - read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); - } else { - ip2trace(CHANN, ITRC_INPUT, 22, 0 ); - - i2InputFlush( pCh ); - } -} - -// code duplicated from n_tty (ldisc) -static inline void isig(int sig, struct tty_struct *tty, int flush) -{ - /* FIXME: This is completely bogus */ - if (tty->pgrp) - kill_pgrp(tty->pgrp, sig, 1); - if (flush || !L_NOFLSH(tty)) { - if ( tty->ldisc->ops->flush_buffer ) - tty->ldisc->ops->flush_buffer(tty); - i2InputFlush( tty->driver_data ); - } -} - -static void do_status(struct work_struct *work) -{ - i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_status); - int status; - - status = i2GetStatus( pCh, (I2_BRK|I2_PAR|I2_FRA|I2_OVR) ); - - ip2trace (CHANN, ITRC_STATUS, 21, 1, status ); - - if (pCh->pTTY && (status & (I2_BRK|I2_PAR|I2_FRA|I2_OVR)) ) { - if ( (status & I2_BRK) ) { - // code duplicated from n_tty (ldisc) - if (I_IGNBRK(pCh->pTTY)) - goto skip_this; - if (I_BRKINT(pCh->pTTY)) { - isig(SIGINT, pCh->pTTY, 1); - goto skip_this; - } - wake_up_interruptible(&pCh->pTTY->read_wait); - } -#ifdef NEVER_HAPPENS_AS_SETUP_XXX - // and can't work because we don't know the_char - // as the_char is reported on a separate path - // The intelligent board does this stuff as setup - { - char brkf = TTY_NORMAL; - unsigned char brkc = '\0'; - unsigned char tmp; - if ( (status & I2_BRK) ) { - brkf = TTY_BREAK; - brkc = '\0'; - } - else if (status & I2_PAR) { - brkf = TTY_PARITY; - brkc = the_char; - } else if (status & I2_FRA) { - brkf = TTY_FRAME; - brkc = the_char; - } else if (status & I2_OVR) { - brkf = TTY_OVERRUN; - brkc = the_char; - } - tmp = pCh->pTTY->real_raw; - pCh->pTTY->real_raw = 0; - pCh->pTTY->ldisc->ops.receive_buf( pCh->pTTY, &brkc, &brkf, 1 ); - pCh->pTTY->real_raw = tmp; - } -#endif /* NEVER_HAPPENS_AS_SETUP_XXX */ - } -skip_this: - - if ( status & (I2_DDCD | I2_DDSR | I2_DCTS | I2_DRI) ) { - wake_up_interruptible(&pCh->delta_msr_wait); - - if ( (pCh->flags & ASYNC_CHECK_CD) && (status & I2_DDCD) ) { - if ( status & I2_DCD ) { - if ( pCh->wopen ) { - wake_up_interruptible ( &pCh->open_wait ); - } - } else { - if (pCh->pTTY && (!(pCh->pTTY->termios->c_cflag & CLOCAL)) ) { - tty_hangup( pCh->pTTY ); - } - } - } - } - - ip2trace (CHANN, ITRC_STATUS, 26, 0 ); -} - -/******************************************************************************/ -/* Device Open/Close/Ioctl Entry Point Section */ -/******************************************************************************/ - -/******************************************************************************/ -/* Function: open_sanity_check() */ -/* Parameters: Pointer to tty structure */ -/* Pointer to file structure */ -/* Returns: Success or failure */ -/* */ -/* Description: */ -/* Verifies the structure magic numbers and cross links. */ -/******************************************************************************/ -#ifdef IP2DEBUG_OPEN -static void -open_sanity_check( i2ChanStrPtr pCh, i2eBordStrPtr pBrd ) -{ - if ( pBrd->i2eValid != I2E_MAGIC ) { - printk(KERN_ERR "IP2: invalid board structure\n" ); - } else if ( pBrd != pCh->pMyBord ) { - printk(KERN_ERR "IP2: board structure pointer mismatch (%p)\n", - pCh->pMyBord ); - } else if ( pBrd->i2eChannelCnt < pCh->port_index ) { - printk(KERN_ERR "IP2: bad device index (%d)\n", pCh->port_index ); - } else if (&((i2ChanStrPtr)pBrd->i2eChannelPtr)[pCh->port_index] != pCh) { - } else { - printk(KERN_INFO "IP2: all pointers check out!\n" ); - } -} -#endif - - -/******************************************************************************/ -/* Function: ip2_open() */ -/* Parameters: Pointer to tty structure */ -/* Pointer to file structure */ -/* Returns: Success or failure */ -/* */ -/* Description: (MANDATORY) */ -/* A successful device open has to run a gauntlet of checks before it */ -/* completes. After some sanity checking and pointer setup, the function */ -/* blocks until all conditions are satisfied. It then initialises the port to */ -/* the default characteristics and returns. */ -/******************************************************************************/ -static int -ip2_open( PTTY tty, struct file *pFile ) -{ - wait_queue_t wait; - int rc = 0; - int do_clocal = 0; - i2ChanStrPtr pCh = DevTable[tty->index]; - - ip2trace (tty->index, ITRC_OPEN, ITRC_ENTER, 0 ); - - if ( pCh == NULL ) { - return -ENODEV; - } - /* Setup pointer links in device and tty structures */ - pCh->pTTY = tty; - tty->driver_data = pCh; - -#ifdef IP2DEBUG_OPEN - printk(KERN_DEBUG \ - "IP2:open(tty=%p,pFile=%p):dev=%s,ch=%d,idx=%d\n", - tty, pFile, tty->name, pCh->infl.hd.i2sChannel, pCh->port_index); - open_sanity_check ( pCh, pCh->pMyBord ); -#endif - - i2QueueCommands(PTYPE_INLINE, pCh, 100, 3, CMD_DTRUP,CMD_RTSUP,CMD_DCD_REP); - pCh->dataSetOut |= (I2_DTR | I2_RTS); - serviceOutgoingFifo( pCh->pMyBord ); - - /* Block here until the port is ready (per serial and istallion) */ - /* - * 1. If the port is in the middle of closing wait for the completion - * and then return the appropriate error. - */ - init_waitqueue_entry(&wait, current); - add_wait_queue(&pCh->close_wait, &wait); - set_current_state( TASK_INTERRUPTIBLE ); - - if ( tty_hung_up_p(pFile) || ( pCh->flags & ASYNC_CLOSING )) { - if ( pCh->flags & ASYNC_CLOSING ) { - tty_unlock(); - schedule(); - tty_lock(); - } - if ( tty_hung_up_p(pFile) ) { - set_current_state( TASK_RUNNING ); - remove_wait_queue(&pCh->close_wait, &wait); - return( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS; - } - } - set_current_state( TASK_RUNNING ); - remove_wait_queue(&pCh->close_wait, &wait); - - /* - * 3. Handle a non-blocking open of a normal port. - */ - if ( (pFile->f_flags & O_NONBLOCK) || (tty->flags & (1<flags |= ASYNC_NORMAL_ACTIVE; - goto noblock; - } - /* - * 4. Now loop waiting for the port to be free and carrier present - * (if required). - */ - if ( tty->termios->c_cflag & CLOCAL ) - do_clocal = 1; - -#ifdef IP2DEBUG_OPEN - printk(KERN_DEBUG "OpenBlock: do_clocal = %d\n", do_clocal); -#endif - - ++pCh->wopen; - - init_waitqueue_entry(&wait, current); - add_wait_queue(&pCh->open_wait, &wait); - - for(;;) { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP); - pCh->dataSetOut |= (I2_DTR | I2_RTS); - set_current_state( TASK_INTERRUPTIBLE ); - serviceOutgoingFifo( pCh->pMyBord ); - if ( tty_hung_up_p(pFile) ) { - set_current_state( TASK_RUNNING ); - remove_wait_queue(&pCh->open_wait, &wait); - return ( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EBUSY : -ERESTARTSYS; - } - if (!(pCh->flags & ASYNC_CLOSING) && - (do_clocal || (pCh->dataSetIn & I2_DCD) )) { - rc = 0; - break; - } - -#ifdef IP2DEBUG_OPEN - printk(KERN_DEBUG "ASYNC_CLOSING = %s\n", - (pCh->flags & ASYNC_CLOSING)?"True":"False"); - printk(KERN_DEBUG "OpenBlock: waiting for CD or signal\n"); -#endif - ip2trace (CHANN, ITRC_OPEN, 3, 2, 0, - (pCh->flags & ASYNC_CLOSING) ); - /* check for signal */ - if (signal_pending(current)) { - rc = (( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS); - break; - } - tty_unlock(); - schedule(); - tty_lock(); - } - set_current_state( TASK_RUNNING ); - remove_wait_queue(&pCh->open_wait, &wait); - - --pCh->wopen; //why count? - - ip2trace (CHANN, ITRC_OPEN, 4, 0 ); - - if (rc != 0 ) { - return rc; - } - pCh->flags |= ASYNC_NORMAL_ACTIVE; - -noblock: - - /* first open - Assign termios structure to port */ - if ( tty->count == 1 ) { - i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB); - /* Now we must send the termios settings to the loadware */ - set_params( pCh, NULL ); - } - - /* - * Now set any i2lib options. These may go away if the i2lib code ends - * up rolled into the mainline. - */ - pCh->channelOptions |= CO_NBLOCK_WRITE; - -#ifdef IP2DEBUG_OPEN - printk (KERN_DEBUG "IP2: open completed\n" ); -#endif - serviceOutgoingFifo( pCh->pMyBord ); - - ip2trace (CHANN, ITRC_OPEN, ITRC_RETURN, 0 ); - - return 0; -} - -/******************************************************************************/ -/* Function: ip2_close() */ -/* Parameters: Pointer to tty structure */ -/* Pointer to file structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static void -ip2_close( PTTY tty, struct file *pFile ) -{ - i2ChanStrPtr pCh = tty->driver_data; - - if ( !pCh ) { - return; - } - - ip2trace (CHANN, ITRC_CLOSE, ITRC_ENTER, 0 ); - -#ifdef IP2DEBUG_OPEN - printk(KERN_DEBUG "IP2:close %s:\n",tty->name); -#endif - - if ( tty_hung_up_p ( pFile ) ) { - - ip2trace (CHANN, ITRC_CLOSE, 2, 1, 2 ); - - return; - } - if ( tty->count > 1 ) { /* not the last close */ - - ip2trace (CHANN, ITRC_CLOSE, 2, 1, 3 ); - - return; - } - pCh->flags |= ASYNC_CLOSING; // last close actually - - tty->closing = 1; - - if (pCh->ClosingWaitTime != ASYNC_CLOSING_WAIT_NONE) { - /* - * Before we drop DTR, make sure the transmitter has completely drained. - * This uses an timeout, after which the close - * completes. - */ - ip2_wait_until_sent(tty, pCh->ClosingWaitTime ); - } - /* - * At this point we stop accepting input. Here we flush the channel - * input buffer which will allow the board to send up more data. Any - * additional input is tossed at interrupt/poll time. - */ - i2InputFlush( pCh ); - - /* disable DSS reporting */ - i2QueueCommands(PTYPE_INLINE, pCh, 100, 4, - CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP); - if (tty->termios->c_cflag & HUPCL) { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN); - pCh->dataSetOut &= ~(I2_DTR | I2_RTS); - i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25)); - } - - serviceOutgoingFifo ( pCh->pMyBord ); - - tty_ldisc_flush(tty); - tty_driver_flush_buffer(tty); - tty->closing = 0; - - pCh->pTTY = NULL; - - if (pCh->wopen) { - if (pCh->ClosingDelay) { - msleep_interruptible(jiffies_to_msecs(pCh->ClosingDelay)); - } - wake_up_interruptible(&pCh->open_wait); - } - - pCh->flags &=~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); - wake_up_interruptible(&pCh->close_wait); - -#ifdef IP2DEBUG_OPEN - DBG_CNT("ip2_close: after wakeups--"); -#endif - - - ip2trace (CHANN, ITRC_CLOSE, ITRC_RETURN, 1, 1 ); - - return; -} - -/******************************************************************************/ -/* Function: ip2_hangup() */ -/* Parameters: Pointer to tty structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static void -ip2_hangup ( PTTY tty ) -{ - i2ChanStrPtr pCh = tty->driver_data; - - if( !pCh ) { - return; - } - - ip2trace (CHANN, ITRC_HANGUP, ITRC_ENTER, 0 ); - - ip2_flush_buffer(tty); - - /* disable DSS reporting */ - - i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_DCD_NREP); - i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB); - if ( (tty->termios->c_cflag & HUPCL) ) { - i2QueueCommands(PTYPE_BYPASS, pCh, 0, 2, CMD_RTSDN, CMD_DTRDN); - pCh->dataSetOut &= ~(I2_DTR | I2_RTS); - i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25)); - } - i2QueueCommands(PTYPE_INLINE, pCh, 1, 3, - CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP); - serviceOutgoingFifo ( pCh->pMyBord ); - - wake_up_interruptible ( &pCh->delta_msr_wait ); - - pCh->flags &= ~ASYNC_NORMAL_ACTIVE; - pCh->pTTY = NULL; - wake_up_interruptible ( &pCh->open_wait ); - - ip2trace (CHANN, ITRC_HANGUP, ITRC_RETURN, 0 ); -} - -/******************************************************************************/ -/******************************************************************************/ -/* Device Output Section */ -/******************************************************************************/ -/******************************************************************************/ - -/******************************************************************************/ -/* Function: ip2_write() */ -/* Parameters: Pointer to tty structure */ -/* Flag denoting data is in user (1) or kernel (0) space */ -/* Pointer to data */ -/* Number of bytes to write */ -/* Returns: Number of bytes actually written */ -/* */ -/* Description: (MANDATORY) */ -/* */ -/* */ -/******************************************************************************/ -static int -ip2_write( PTTY tty, const unsigned char *pData, int count) -{ - i2ChanStrPtr pCh = tty->driver_data; - int bytesSent = 0; - unsigned long flags; - - ip2trace (CHANN, ITRC_WRITE, ITRC_ENTER, 2, count, -1 ); - - /* Flush out any buffered data left over from ip2_putchar() calls. */ - ip2_flush_chars( tty ); - - /* This is the actual move bit. Make sure it does what we need!!!!! */ - write_lock_irqsave(&pCh->Pbuf_spinlock, flags); - bytesSent = i2Output( pCh, pData, count); - write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); - - ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent ); - - return bytesSent > 0 ? bytesSent : 0; -} - -/******************************************************************************/ -/* Function: ip2_putchar() */ -/* Parameters: Pointer to tty structure */ -/* Character to write */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static int -ip2_putchar( PTTY tty, unsigned char ch ) -{ - i2ChanStrPtr pCh = tty->driver_data; - unsigned long flags; - -// ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch ); - - write_lock_irqsave(&pCh->Pbuf_spinlock, flags); - pCh->Pbuf[pCh->Pbuf_stuff++] = ch; - if ( pCh->Pbuf_stuff == sizeof pCh->Pbuf ) { - write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); - ip2_flush_chars( tty ); - } else - write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); - return 1; - -// ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch ); -} - -/******************************************************************************/ -/* Function: ip2_flush_chars() */ -/* Parameters: Pointer to tty structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/******************************************************************************/ -static void -ip2_flush_chars( PTTY tty ) -{ - int strip; - i2ChanStrPtr pCh = tty->driver_data; - unsigned long flags; - - write_lock_irqsave(&pCh->Pbuf_spinlock, flags); - if ( pCh->Pbuf_stuff ) { - -// ip2trace (CHANN, ITRC_PUTC, 10, 1, strip ); - - // - // We may need to restart i2Output if it does not fullfill this request - // - strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff); - if ( strip != pCh->Pbuf_stuff ) { - memmove( pCh->Pbuf, &pCh->Pbuf[strip], pCh->Pbuf_stuff - strip ); - } - pCh->Pbuf_stuff -= strip; - } - write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); -} - -/******************************************************************************/ -/* Function: ip2_write_room() */ -/* Parameters: Pointer to tty structure */ -/* Returns: Number of bytes that the driver can accept */ -/* */ -/* Description: */ -/* */ -/******************************************************************************/ -static int -ip2_write_room ( PTTY tty ) -{ - int bytesFree; - i2ChanStrPtr pCh = tty->driver_data; - unsigned long flags; - - read_lock_irqsave(&pCh->Pbuf_spinlock, flags); - bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff; - read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); - - ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree ); - - return ((bytesFree > 0) ? bytesFree : 0); -} - -/******************************************************************************/ -/* Function: ip2_chars_in_buf() */ -/* Parameters: Pointer to tty structure */ -/* Returns: Number of bytes queued for transmission */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static int -ip2_chars_in_buf ( PTTY tty ) -{ - i2ChanStrPtr pCh = tty->driver_data; - int rc; - unsigned long flags; - - ip2trace (CHANN, ITRC_WRITE, 12, 1, pCh->Obuf_char_count + pCh->Pbuf_stuff ); - -#ifdef IP2DEBUG_WRITE - printk (KERN_DEBUG "IP2: chars in buffer = %d (%d,%d)\n", - pCh->Obuf_char_count + pCh->Pbuf_stuff, - pCh->Obuf_char_count, pCh->Pbuf_stuff ); -#endif - read_lock_irqsave(&pCh->Obuf_spinlock, flags); - rc = pCh->Obuf_char_count; - read_unlock_irqrestore(&pCh->Obuf_spinlock, flags); - read_lock_irqsave(&pCh->Pbuf_spinlock, flags); - rc += pCh->Pbuf_stuff; - read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); - return rc; -} - -/******************************************************************************/ -/* Function: ip2_flush_buffer() */ -/* Parameters: Pointer to tty structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static void -ip2_flush_buffer( PTTY tty ) -{ - i2ChanStrPtr pCh = tty->driver_data; - unsigned long flags; - - ip2trace (CHANN, ITRC_FLUSH, ITRC_ENTER, 0 ); - -#ifdef IP2DEBUG_WRITE - printk (KERN_DEBUG "IP2: flush buffer\n" ); -#endif - write_lock_irqsave(&pCh->Pbuf_spinlock, flags); - pCh->Pbuf_stuff = 0; - write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); - i2FlushOutput( pCh ); - ip2_owake(tty); - - ip2trace (CHANN, ITRC_FLUSH, ITRC_RETURN, 0 ); - -} - -/******************************************************************************/ -/* Function: ip2_wait_until_sent() */ -/* Parameters: Pointer to tty structure */ -/* Timeout for wait. */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* This function is used in place of the normal tty_wait_until_sent, which */ -/* only waits for the driver buffers to be empty (or rather, those buffers */ -/* reported by chars_in_buffer) which doesn't work for IP2 due to the */ -/* indeterminate number of bytes buffered on the board. */ -/******************************************************************************/ -static void -ip2_wait_until_sent ( PTTY tty, int timeout ) -{ - int i = jiffies; - i2ChanStrPtr pCh = tty->driver_data; - - tty_wait_until_sent(tty, timeout ); - if ( (i = timeout - (jiffies -i)) > 0) - i2DrainOutput( pCh, i ); -} - -/******************************************************************************/ -/******************************************************************************/ -/* Device Input Section */ -/******************************************************************************/ -/******************************************************************************/ - -/******************************************************************************/ -/* Function: ip2_throttle() */ -/* Parameters: Pointer to tty structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static void -ip2_throttle ( PTTY tty ) -{ - i2ChanStrPtr pCh = tty->driver_data; - -#ifdef IP2DEBUG_READ - printk (KERN_DEBUG "IP2: throttle\n" ); -#endif - /* - * Signal the poll/interrupt handlers not to forward incoming data to - * the line discipline. This will cause the buffers to fill up in the - * library and thus cause the library routines to send the flow control - * stuff. - */ - pCh->throttled = 1; -} - -/******************************************************************************/ -/* Function: ip2_unthrottle() */ -/* Parameters: Pointer to tty structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static void -ip2_unthrottle ( PTTY tty ) -{ - i2ChanStrPtr pCh = tty->driver_data; - unsigned long flags; - -#ifdef IP2DEBUG_READ - printk (KERN_DEBUG "IP2: unthrottle\n" ); -#endif - - /* Pass incoming data up to the line discipline again. */ - pCh->throttled = 0; - i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME); - serviceOutgoingFifo( pCh->pMyBord ); - read_lock_irqsave(&pCh->Ibuf_spinlock, flags); - if ( pCh->Ibuf_stuff != pCh->Ibuf_strip ) { - read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); -#ifdef IP2DEBUG_READ - printk (KERN_DEBUG "i2Input called from unthrottle\n" ); -#endif - i2Input( pCh ); - } else - read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); -} - -static void -ip2_start ( PTTY tty ) -{ - i2ChanStrPtr pCh = DevTable[tty->index]; - - i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME); - i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_UNSUSPEND); - i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_RESUME); -#ifdef IP2DEBUG_WRITE - printk (KERN_DEBUG "IP2: start tx\n" ); -#endif -} - -static void -ip2_stop ( PTTY tty ) -{ - i2ChanStrPtr pCh = DevTable[tty->index]; - - i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_SUSPEND); -#ifdef IP2DEBUG_WRITE - printk (KERN_DEBUG "IP2: stop tx\n" ); -#endif -} - -/******************************************************************************/ -/* Device Ioctl Section */ -/******************************************************************************/ - -static int ip2_tiocmget(struct tty_struct *tty) -{ - i2ChanStrPtr pCh = DevTable[tty->index]; -#ifdef ENABLE_DSSNOW - wait_queue_t wait; -#endif - - if (pCh == NULL) - return -ENODEV; - -/* - FIXME - the following code is causing a NULL pointer dereference in - 2.3.51 in an interrupt handler. It's suppose to prompt the board - to return the DSS signal status immediately. Why doesn't it do - the same thing in 2.2.14? -*/ - -/* This thing is still busted in the 1.2.12 driver on 2.4.x - and even hoses the serial console so the oops can be trapped. - /\/\|=mhw=|\/\/ */ - -#ifdef ENABLE_DSSNOW - i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DSS_NOW); - - init_waitqueue_entry(&wait, current); - add_wait_queue(&pCh->dss_now_wait, &wait); - set_current_state( TASK_INTERRUPTIBLE ); - - serviceOutgoingFifo( pCh->pMyBord ); - - schedule(); - - set_current_state( TASK_RUNNING ); - remove_wait_queue(&pCh->dss_now_wait, &wait); - - if (signal_pending(current)) { - return -EINTR; - } -#endif - return ((pCh->dataSetOut & I2_RTS) ? TIOCM_RTS : 0) - | ((pCh->dataSetOut & I2_DTR) ? TIOCM_DTR : 0) - | ((pCh->dataSetIn & I2_DCD) ? TIOCM_CAR : 0) - | ((pCh->dataSetIn & I2_RI) ? TIOCM_RNG : 0) - | ((pCh->dataSetIn & I2_DSR) ? TIOCM_DSR : 0) - | ((pCh->dataSetIn & I2_CTS) ? TIOCM_CTS : 0); -} - -static int ip2_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - i2ChanStrPtr pCh = DevTable[tty->index]; - - if (pCh == NULL) - return -ENODEV; - - if (set & TIOCM_RTS) { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSUP); - pCh->dataSetOut |= I2_RTS; - } - if (set & TIOCM_DTR) { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRUP); - pCh->dataSetOut |= I2_DTR; - } - - if (clear & TIOCM_RTS) { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSDN); - pCh->dataSetOut &= ~I2_RTS; - } - if (clear & TIOCM_DTR) { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRDN); - pCh->dataSetOut &= ~I2_DTR; - } - serviceOutgoingFifo( pCh->pMyBord ); - return 0; -} - -/******************************************************************************/ -/* Function: ip2_ioctl() */ -/* Parameters: Pointer to tty structure */ -/* Pointer to file structure */ -/* Command */ -/* Argument */ -/* Returns: Success or failure */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static int -ip2_ioctl ( PTTY tty, UINT cmd, ULONG arg ) -{ - wait_queue_t wait; - i2ChanStrPtr pCh = DevTable[tty->index]; - i2eBordStrPtr pB; - struct async_icount cprev, cnow; /* kernel counter temps */ - int rc = 0; - unsigned long flags; - void __user *argp = (void __user *)arg; - - if ( pCh == NULL ) - return -ENODEV; - - pB = pCh->pMyBord; - - ip2trace (CHANN, ITRC_IOCTL, ITRC_ENTER, 2, cmd, arg ); - -#ifdef IP2DEBUG_IOCTL - printk(KERN_DEBUG "IP2: ioctl cmd (%x), arg (%lx)\n", cmd, arg ); -#endif - - switch(cmd) { - case TIOCGSERIAL: - - ip2trace (CHANN, ITRC_IOCTL, 2, 1, rc ); - - rc = get_serial_info(pCh, argp); - if (rc) - return rc; - break; - - case TIOCSSERIAL: - - ip2trace (CHANN, ITRC_IOCTL, 3, 1, rc ); - - rc = set_serial_info(pCh, argp); - if (rc) - return rc; - break; - - case TCXONC: - rc = tty_check_change(tty); - if (rc) - return rc; - switch (arg) { - case TCOOFF: - //return -ENOIOCTLCMD; - break; - case TCOON: - //return -ENOIOCTLCMD; - break; - case TCIOFF: - if (STOP_CHAR(tty) != __DISABLED_CHAR) { - i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1, - CMD_XMIT_NOW(STOP_CHAR(tty))); - } - break; - case TCION: - if (START_CHAR(tty) != __DISABLED_CHAR) { - i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1, - CMD_XMIT_NOW(START_CHAR(tty))); - } - break; - default: - return -EINVAL; - } - return 0; - - case TCSBRK: /* SVID version: non-zero arg --> no break */ - rc = tty_check_change(tty); - - ip2trace (CHANN, ITRC_IOCTL, 4, 1, rc ); - - if (!rc) { - ip2_wait_until_sent(tty,0); - if (!arg) { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SEND_BRK(250)); - serviceOutgoingFifo( pCh->pMyBord ); - } - } - break; - - case TCSBRKP: /* support for POSIX tcsendbreak() */ - rc = tty_check_change(tty); - - ip2trace (CHANN, ITRC_IOCTL, 5, 1, rc ); - - if (!rc) { - ip2_wait_until_sent(tty,0); - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, - CMD_SEND_BRK(arg ? arg*100 : 250)); - serviceOutgoingFifo ( pCh->pMyBord ); - } - break; - - case TIOCGSOFTCAR: - - ip2trace (CHANN, ITRC_IOCTL, 6, 1, rc ); - - rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp); - if (rc) - return rc; - break; - - case TIOCSSOFTCAR: - - ip2trace (CHANN, ITRC_IOCTL, 7, 1, rc ); - - rc = get_user(arg,(unsigned long __user *) argp); - if (rc) - return rc; - tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) - | (arg ? CLOCAL : 0)); - - break; - - /* - * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - mask - * passed in arg for lines of interest (use |'ed TIOCM_RNG/DSR/CD/CTS - * for masking). Caller should use TIOCGICOUNT to see which one it was - */ - case TIOCMIWAIT: - write_lock_irqsave(&pB->read_fifo_spinlock, flags); - cprev = pCh->icount; /* note the counters on entry */ - write_unlock_irqrestore(&pB->read_fifo_spinlock, flags); - i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4, - CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP); - init_waitqueue_entry(&wait, current); - add_wait_queue(&pCh->delta_msr_wait, &wait); - set_current_state( TASK_INTERRUPTIBLE ); - - serviceOutgoingFifo( pCh->pMyBord ); - for(;;) { - ip2trace (CHANN, ITRC_IOCTL, 10, 0 ); - - schedule(); - - ip2trace (CHANN, ITRC_IOCTL, 11, 0 ); - - /* see if a signal did it */ - if (signal_pending(current)) { - rc = -ERESTARTSYS; - break; - } - write_lock_irqsave(&pB->read_fifo_spinlock, flags); - cnow = pCh->icount; /* atomic copy */ - write_unlock_irqrestore(&pB->read_fifo_spinlock, flags); - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { - rc = -EIO; /* no change => rc */ - break; - } - if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { - rc = 0; - break; - } - cprev = cnow; - } - set_current_state( TASK_RUNNING ); - remove_wait_queue(&pCh->delta_msr_wait, &wait); - - i2QueueCommands(PTYPE_BYPASS, pCh, 100, 3, - CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP); - if ( ! (pCh->flags & ASYNC_CHECK_CD)) { - i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DCD_NREP); - } - serviceOutgoingFifo( pCh->pMyBord ); - return rc; - break; - - /* - * The rest are not supported by this driver. By returning -ENOIOCTLCMD they - * will be passed to the line discipline for it to handle. - */ - case TIOCSERCONFIG: - case TIOCSERGWILD: - case TIOCSERGETLSR: - case TIOCSERSWILD: - case TIOCSERGSTRUCT: - case TIOCSERGETMULTI: - case TIOCSERSETMULTI: - - default: - ip2trace (CHANN, ITRC_IOCTL, 12, 0 ); - - rc = -ENOIOCTLCMD; - break; - } - - ip2trace (CHANN, ITRC_IOCTL, ITRC_RETURN, 0 ); - - return rc; -} - -static int ip2_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - i2ChanStrPtr pCh = DevTable[tty->index]; - i2eBordStrPtr pB; - struct async_icount cnow; /* kernel counter temp */ - unsigned long flags; - - if ( pCh == NULL ) - return -ENODEV; - - pB = pCh->pMyBord; - - /* - * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) - * Return: write counters to the user passed counter struct - * NB: both 1->0 and 0->1 transitions are counted except for RI where - * only 0->1 is counted. The controller is quite capable of counting - * both, but this done to preserve compatibility with the standard - * serial driver. - */ - - write_lock_irqsave(&pB->read_fifo_spinlock, flags); - cnow = pCh->icount; - write_unlock_irqrestore(&pB->read_fifo_spinlock, flags); - - icount->cts = cnow.cts; - icount->dsr = cnow.dsr; - icount->rng = cnow.rng; - icount->dcd = cnow.dcd; - icount->rx = cnow.rx; - icount->tx = cnow.tx; - icount->frame = cnow.frame; - icount->overrun = cnow.overrun; - icount->parity = cnow.parity; - icount->brk = cnow.brk; - icount->buf_overrun = cnow.buf_overrun; - return 0; -} - -/******************************************************************************/ -/* Function: GetSerialInfo() */ -/* Parameters: Pointer to channel structure */ -/* Pointer to old termios structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* This is to support the setserial command, and requires processing of the */ -/* standard Linux serial structure. */ -/******************************************************************************/ -static int -get_serial_info ( i2ChanStrPtr pCh, struct serial_struct __user *retinfo ) -{ - struct serial_struct tmp; - - memset ( &tmp, 0, sizeof(tmp) ); - tmp.type = pCh->pMyBord->channelBtypes.bid_value[(pCh->port_index & (IP2_PORTS_PER_BOARD-1))/16]; - if (BID_HAS_654(tmp.type)) { - tmp.type = PORT_16650; - } else { - tmp.type = PORT_CIRRUS; - } - tmp.line = pCh->port_index; - tmp.port = pCh->pMyBord->i2eBase; - tmp.irq = ip2config.irq[pCh->port_index/64]; - tmp.flags = pCh->flags; - tmp.baud_base = pCh->BaudBase; - tmp.close_delay = pCh->ClosingDelay; - tmp.closing_wait = pCh->ClosingWaitTime; - tmp.custom_divisor = pCh->BaudDivisor; - return copy_to_user(retinfo,&tmp,sizeof(*retinfo)); -} - -/******************************************************************************/ -/* Function: SetSerialInfo() */ -/* Parameters: Pointer to channel structure */ -/* Pointer to old termios structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* This function provides support for setserial, which uses the TIOCSSERIAL */ -/* ioctl. Not all setserial parameters are relevant. If the user attempts to */ -/* change the IRQ, address or type of the port the ioctl fails. */ -/******************************************************************************/ -static int -set_serial_info( i2ChanStrPtr pCh, struct serial_struct __user *new_info ) -{ - struct serial_struct ns; - int old_flags, old_baud_divisor; - - if (copy_from_user(&ns, new_info, sizeof (ns))) - return -EFAULT; - - /* - * We don't allow setserial to change IRQ, board address, type or baud - * base. Also line nunber as such is meaningless but we use it for our - * array index so it is fixed also. - */ - if ( (ns.irq != ip2config.irq[pCh->port_index]) - || ((int) ns.port != ((int) (pCh->pMyBord->i2eBase))) - || (ns.baud_base != pCh->BaudBase) - || (ns.line != pCh->port_index) ) { - return -EINVAL; - } - - old_flags = pCh->flags; - old_baud_divisor = pCh->BaudDivisor; - - if ( !capable(CAP_SYS_ADMIN) ) { - if ( ( ns.close_delay != pCh->ClosingDelay ) || - ( (ns.flags & ~ASYNC_USR_MASK) != - (pCh->flags & ~ASYNC_USR_MASK) ) ) { - return -EPERM; - } - - pCh->flags = (pCh->flags & ~ASYNC_USR_MASK) | - (ns.flags & ASYNC_USR_MASK); - pCh->BaudDivisor = ns.custom_divisor; - } else { - pCh->flags = (pCh->flags & ~ASYNC_FLAGS) | - (ns.flags & ASYNC_FLAGS); - pCh->BaudDivisor = ns.custom_divisor; - pCh->ClosingDelay = ns.close_delay * HZ/100; - pCh->ClosingWaitTime = ns.closing_wait * HZ/100; - } - - if ( ( (old_flags & ASYNC_SPD_MASK) != (pCh->flags & ASYNC_SPD_MASK) ) - || (old_baud_divisor != pCh->BaudDivisor) ) { - // Invalidate speed and reset parameters - set_params( pCh, NULL ); - } - - return 0; -} - -/******************************************************************************/ -/* Function: ip2_set_termios() */ -/* Parameters: Pointer to tty structure */ -/* Pointer to old termios structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static void -ip2_set_termios( PTTY tty, struct ktermios *old_termios ) -{ - i2ChanStrPtr pCh = (i2ChanStrPtr)tty->driver_data; - -#ifdef IP2DEBUG_IOCTL - printk (KERN_DEBUG "IP2: set termios %p\n", old_termios ); -#endif - - set_params( pCh, old_termios ); -} - -/******************************************************************************/ -/* Function: ip2_set_line_discipline() */ -/* Parameters: Pointer to tty structure */ -/* Returns: Nothing */ -/* */ -/* Description: Does nothing */ -/* */ -/* */ -/******************************************************************************/ -static void -ip2_set_line_discipline ( PTTY tty ) -{ -#ifdef IP2DEBUG_IOCTL - printk (KERN_DEBUG "IP2: set line discipline\n" ); -#endif - - ip2trace (((i2ChanStrPtr)tty->driver_data)->port_index, ITRC_IOCTL, 16, 0 ); - -} - -/******************************************************************************/ -/* Function: SetLine Characteristics() */ -/* Parameters: Pointer to channel structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* This routine is called to update the channel structure with the new line */ -/* characteristics, and send the appropriate commands to the board when they */ -/* change. */ -/******************************************************************************/ -static void -set_params( i2ChanStrPtr pCh, struct ktermios *o_tios ) -{ - tcflag_t cflag, iflag, lflag; - char stop_char, start_char; - struct ktermios dummy; - - lflag = pCh->pTTY->termios->c_lflag; - cflag = pCh->pTTY->termios->c_cflag; - iflag = pCh->pTTY->termios->c_iflag; - - if (o_tios == NULL) { - dummy.c_lflag = ~lflag; - dummy.c_cflag = ~cflag; - dummy.c_iflag = ~iflag; - o_tios = &dummy; - } - - { - switch ( cflag & CBAUD ) { - case B0: - i2QueueCommands( PTYPE_BYPASS, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN); - pCh->dataSetOut &= ~(I2_DTR | I2_RTS); - i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25)); - pCh->pTTY->termios->c_cflag |= (CBAUD & o_tios->c_cflag); - goto service_it; - break; - case B38400: - /* - * This is the speed that is overloaded with all the other high - * speeds, depending upon the flag settings. - */ - if ( ( pCh->flags & ASYNC_SPD_MASK ) == ASYNC_SPD_HI ) { - pCh->speed = CBR_57600; - } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI ) { - pCh->speed = CBR_115200; - } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST ) { - pCh->speed = CBR_C1; - } else { - pCh->speed = CBR_38400; - } - break; - case B50: pCh->speed = CBR_50; break; - case B75: pCh->speed = CBR_75; break; - case B110: pCh->speed = CBR_110; break; - case B134: pCh->speed = CBR_134; break; - case B150: pCh->speed = CBR_150; break; - case B200: pCh->speed = CBR_200; break; - case B300: pCh->speed = CBR_300; break; - case B600: pCh->speed = CBR_600; break; - case B1200: pCh->speed = CBR_1200; break; - case B1800: pCh->speed = CBR_1800; break; - case B2400: pCh->speed = CBR_2400; break; - case B4800: pCh->speed = CBR_4800; break; - case B9600: pCh->speed = CBR_9600; break; - case B19200: pCh->speed = CBR_19200; break; - case B57600: pCh->speed = CBR_57600; break; - case B115200: pCh->speed = CBR_115200; break; - case B153600: pCh->speed = CBR_153600; break; - case B230400: pCh->speed = CBR_230400; break; - case B307200: pCh->speed = CBR_307200; break; - case B460800: pCh->speed = CBR_460800; break; - case B921600: pCh->speed = CBR_921600; break; - default: pCh->speed = CBR_9600; break; - } - if ( pCh->speed == CBR_C1 ) { - // Process the custom speed parameters. - int bps = pCh->BaudBase / pCh->BaudDivisor; - if ( bps == 921600 ) { - pCh->speed = CBR_921600; - } else { - bps = bps/10; - i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_BAUD_DEF1(bps) ); - } - } - i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_SETBAUD(pCh->speed)); - - i2QueueCommands ( PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP); - pCh->dataSetOut |= (I2_DTR | I2_RTS); - } - if ( (CSTOPB & cflag) ^ (CSTOPB & o_tios->c_cflag)) - { - i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, - CMD_SETSTOP( ( cflag & CSTOPB ) ? CST_2 : CST_1)); - } - if (((PARENB|PARODD) & cflag) ^ ((PARENB|PARODD) & o_tios->c_cflag)) - { - i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, - CMD_SETPAR( - (cflag & PARENB ? (cflag & PARODD ? CSP_OD : CSP_EV) : CSP_NP) - ) - ); - } - /* byte size and parity */ - if ( (CSIZE & cflag)^(CSIZE & o_tios->c_cflag)) - { - int datasize; - switch ( cflag & CSIZE ) { - case CS5: datasize = CSZ_5; break; - case CS6: datasize = CSZ_6; break; - case CS7: datasize = CSZ_7; break; - case CS8: datasize = CSZ_8; break; - default: datasize = CSZ_5; break; /* as per serial.c */ - } - i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, CMD_SETBITS(datasize) ); - } - /* Process CTS flow control flag setting */ - if ( (cflag & CRTSCTS) ) { - i2QueueCommands(PTYPE_INLINE, pCh, 100, - 2, CMD_CTSFL_ENAB, CMD_RTSFL_ENAB); - } else { - i2QueueCommands(PTYPE_INLINE, pCh, 100, - 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB); - } - // - // Process XON/XOFF flow control flags settings - // - stop_char = STOP_CHAR(pCh->pTTY); - start_char = START_CHAR(pCh->pTTY); - - //////////// can't be \000 - if (stop_char == __DISABLED_CHAR ) - { - stop_char = ~__DISABLED_CHAR; - } - if (start_char == __DISABLED_CHAR ) - { - start_char = ~__DISABLED_CHAR; - } - ///////////////////////////////// - - if ( o_tios->c_cc[VSTART] != start_char ) - { - i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXON(start_char)); - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXON(start_char)); - } - if ( o_tios->c_cc[VSTOP] != stop_char ) - { - i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXOFF(stop_char)); - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXOFF(stop_char)); - } - if (stop_char == __DISABLED_CHAR ) - { - stop_char = ~__DISABLED_CHAR; //TEST123 - goto no_xoff; - } - if ((iflag & (IXOFF))^(o_tios->c_iflag & (IXOFF))) - { - if ( iflag & IXOFF ) { // Enable XOFF output flow control - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_XON)); - } else { // Disable XOFF output flow control -no_xoff: - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_NONE)); - } - } - if (start_char == __DISABLED_CHAR ) - { - goto no_xon; - } - if ((iflag & (IXON|IXANY)) ^ (o_tios->c_iflag & (IXON|IXANY))) - { - if ( iflag & IXON ) { - if ( iflag & IXANY ) { // Enable XON/XANY output flow control - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XANY)); - } else { // Enable XON output flow control - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XON)); - } - } else { // Disable XON output flow control -no_xon: - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_NONE)); - } - } - if ( (iflag & ISTRIP) ^ ( o_tios->c_iflag & (ISTRIP)) ) - { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, - CMD_ISTRIP_OPT((iflag & ISTRIP ? 1 : 0))); - } - if ( (iflag & INPCK) ^ ( o_tios->c_iflag & (INPCK)) ) - { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, - CMD_PARCHK((iflag & INPCK) ? CPK_ENAB : CPK_DSAB)); - } - - if ( (iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) - ^ ( o_tios->c_iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) ) - { - char brkrpt = 0; - char parrpt = 0; - - if ( iflag & IGNBRK ) { /* Ignore breaks altogether */ - /* Ignore breaks altogether */ - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_NREP); - } else { - if ( iflag & BRKINT ) { - if ( iflag & PARMRK ) { - brkrpt = 0x0a; // exception an inline triple - } else { - brkrpt = 0x1a; // exception and NULL - } - brkrpt |= 0x04; // flush input - } else { - if ( iflag & PARMRK ) { - brkrpt = 0x0b; //POSIX triple \0377 \0 \0 - } else { - brkrpt = 0x01; // Null only - } - } - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_REP(brkrpt)); - } - - if (iflag & IGNPAR) { - parrpt = 0x20; - /* would be 2 for not cirrus bug */ - /* would be 0x20 cept for cirrus bug */ - } else { - if ( iflag & PARMRK ) { - /* - * Replace error characters with 3-byte sequence (\0377,\0,char) - */ - parrpt = 0x04 ; - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_ISTRIP_OPT((char)0)); - } else { - parrpt = 0x03; - } - } - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SET_ERROR(parrpt)); - } - if (cflag & CLOCAL) { - // Status reporting fails for DCD if this is off - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_NREP); - pCh->flags &= ~ASYNC_CHECK_CD; - } else { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_REP); - pCh->flags |= ASYNC_CHECK_CD; - } - -service_it: - i2DrainOutput( pCh, 100 ); -} - -/******************************************************************************/ -/* IPL Device Section */ -/******************************************************************************/ - -/******************************************************************************/ -/* Function: ip2_ipl_read() */ -/* Parameters: Pointer to device inode */ -/* Pointer to file structure */ -/* Pointer to data */ -/* Number of bytes to read */ -/* Returns: Success or failure */ -/* */ -/* Description: Ugly */ -/* */ -/* */ -/******************************************************************************/ - -static -ssize_t -ip2_ipl_read(struct file *pFile, char __user *pData, size_t count, loff_t *off ) -{ - unsigned int minor = iminor(pFile->f_path.dentry->d_inode); - int rc = 0; - -#ifdef IP2DEBUG_IPL - printk (KERN_DEBUG "IP2IPL: read %p, %d bytes\n", pData, count ); -#endif - - switch( minor ) { - case 0: // IPL device - rc = -EINVAL; - break; - case 1: // Status dump - rc = -EINVAL; - break; - case 2: // Ping device - rc = -EINVAL; - break; - case 3: // Trace device - rc = DumpTraceBuffer ( pData, count ); - break; - case 4: // Trace device - rc = DumpFifoBuffer ( pData, count ); - break; - default: - rc = -ENODEV; - break; - } - return rc; -} - -static int -DumpFifoBuffer ( char __user *pData, int count ) -{ -#ifdef DEBUG_FIFO - int rc; - rc = copy_to_user(pData, DBGBuf, count); - - printk(KERN_DEBUG "Last index %d\n", I ); - - return count; -#endif /* DEBUG_FIFO */ - return 0; -} - -static int -DumpTraceBuffer ( char __user *pData, int count ) -{ -#ifdef IP2DEBUG_TRACE - int rc; - int dumpcount; - int chunk; - int *pIndex = (int __user *)pData; - - if ( count < (sizeof(int) * 6) ) { - return -EIO; - } - rc = put_user(tracewrap, pIndex ); - rc = put_user(TRACEMAX, ++pIndex ); - rc = put_user(tracestrip, ++pIndex ); - rc = put_user(tracestuff, ++pIndex ); - pData += sizeof(int) * 6; - count -= sizeof(int) * 6; - - dumpcount = tracestuff - tracestrip; - if ( dumpcount < 0 ) { - dumpcount += TRACEMAX; - } - if ( dumpcount > count ) { - dumpcount = count; - } - chunk = TRACEMAX - tracestrip; - if ( dumpcount > chunk ) { - rc = copy_to_user(pData, &tracebuf[tracestrip], - chunk * sizeof(tracebuf[0]) ); - pData += chunk * sizeof(tracebuf[0]); - tracestrip = 0; - chunk = dumpcount - chunk; - } else { - chunk = dumpcount; - } - rc = copy_to_user(pData, &tracebuf[tracestrip], - chunk * sizeof(tracebuf[0]) ); - tracestrip += chunk; - tracewrap = 0; - - rc = put_user(tracestrip, ++pIndex ); - rc = put_user(tracestuff, ++pIndex ); - - return dumpcount; -#else - return 0; -#endif -} - -/******************************************************************************/ -/* Function: ip2_ipl_write() */ -/* Parameters: */ -/* Pointer to file structure */ -/* Pointer to data */ -/* Number of bytes to write */ -/* Returns: Success or failure */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static ssize_t -ip2_ipl_write(struct file *pFile, const char __user *pData, size_t count, loff_t *off) -{ -#ifdef IP2DEBUG_IPL - printk (KERN_DEBUG "IP2IPL: write %p, %d bytes\n", pData, count ); -#endif - return 0; -} - -/******************************************************************************/ -/* Function: ip2_ipl_ioctl() */ -/* Parameters: Pointer to device inode */ -/* Pointer to file structure */ -/* Command */ -/* Argument */ -/* Returns: Success or failure */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static long -ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg ) -{ - unsigned int iplminor = iminor(pFile->f_path.dentry->d_inode); - int rc = 0; - void __user *argp = (void __user *)arg; - ULONG __user *pIndex = argp; - i2eBordStrPtr pB = i2BoardPtrTable[iplminor / 4]; - i2ChanStrPtr pCh; - -#ifdef IP2DEBUG_IPL - printk (KERN_DEBUG "IP2IPL: ioctl cmd %d, arg %ld\n", cmd, arg ); -#endif - - mutex_lock(&ip2_mutex); - - switch ( iplminor ) { - case 0: // IPL device - rc = -EINVAL; - break; - case 1: // Status dump - case 5: - case 9: - case 13: - switch ( cmd ) { - case 64: /* Driver - ip2stat */ - rc = put_user(-1, pIndex++ ); - rc = put_user(irq_counter, pIndex++ ); - rc = put_user(bh_counter, pIndex++ ); - break; - - case 65: /* Board - ip2stat */ - if ( pB ) { - rc = copy_to_user(argp, pB, sizeof(i2eBordStr)); - rc = put_user(inb(pB->i2eStatus), - (ULONG __user *)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) ); - } else { - rc = -ENODEV; - } - break; - - default: - if (cmd < IP2_MAX_PORTS) { - pCh = DevTable[cmd]; - if ( pCh ) - { - rc = copy_to_user(argp, pCh, sizeof(i2ChanStr)); - if (rc) - rc = -EFAULT; - } else { - rc = -ENODEV; - } - } else { - rc = -EINVAL; - } - } - break; - - case 2: // Ping device - rc = -EINVAL; - break; - case 3: // Trace device - /* - * akpm: This used to write a whole bunch of function addresses - * to userspace, which generated lots of put_user() warnings. - * I killed it all. Just return "success" and don't do - * anything. - */ - if (cmd == 1) - rc = 0; - else - rc = -EINVAL; - break; - - default: - rc = -ENODEV; - break; - } - mutex_unlock(&ip2_mutex); - return rc; -} - -/******************************************************************************/ -/* Function: ip2_ipl_open() */ -/* Parameters: Pointer to device inode */ -/* Pointer to file structure */ -/* Returns: Success or failure */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static int -ip2_ipl_open( struct inode *pInode, struct file *pFile ) -{ - -#ifdef IP2DEBUG_IPL - printk (KERN_DEBUG "IP2IPL: open\n" ); -#endif - return 0; -} - -static int -proc_ip2mem_show(struct seq_file *m, void *v) -{ - i2eBordStrPtr pB; - i2ChanStrPtr pCh; - PTTY tty; - int i; - -#define FMTLINE "%3d: 0x%08x 0x%08x 0%011o 0%011o\n" -#define FMTLIN2 " 0x%04x 0x%04x tx flow 0x%x\n" -#define FMTLIN3 " 0x%04x 0x%04x rc flow\n" - - seq_printf(m,"\n"); - - for( i = 0; i < IP2_MAX_BOARDS; ++i ) { - pB = i2BoardPtrTable[i]; - if ( pB ) { - seq_printf(m,"board %d:\n",i); - seq_printf(m,"\tFifo rem: %d mty: %x outM %x\n", - pB->i2eFifoRemains,pB->i2eWaitingForEmptyFifo,pB->i2eOutMailWaiting); - } - } - - seq_printf(m,"#: tty flags, port flags, cflags, iflags\n"); - for (i=0; i < IP2_MAX_PORTS; i++) { - pCh = DevTable[i]; - if (pCh) { - tty = pCh->pTTY; - if (tty && tty->count) { - seq_printf(m,FMTLINE,i,(int)tty->flags,pCh->flags, - tty->termios->c_cflag,tty->termios->c_iflag); - - seq_printf(m,FMTLIN2, - pCh->outfl.asof,pCh->outfl.room,pCh->channelNeeds); - seq_printf(m,FMTLIN3,pCh->infl.asof,pCh->infl.room); - } - } - } - return 0; -} - -static int proc_ip2mem_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_ip2mem_show, NULL); -} - -static const struct file_operations ip2mem_proc_fops = { - .owner = THIS_MODULE, - .open = proc_ip2mem_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/* - * This is the handler for /proc/tty/driver/ip2 - * - * This stretch of code has been largely plagerized from at least three - * different sources including ip2mkdev.c and a couple of other drivers. - * The bugs are all mine. :-) =mhw= - */ -static int ip2_proc_show(struct seq_file *m, void *v) -{ - int i, j, box; - int boxes = 0; - int ports = 0; - int tports = 0; - i2eBordStrPtr pB; - char *sep; - - seq_printf(m, "ip2info: 1.0 driver: %s\n", pcVersion); - seq_printf(m, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n", - IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR, - IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX); - - for( i = 0; i < IP2_MAX_BOARDS; ++i ) { - /* This need to be reset for a board by board count... */ - boxes = 0; - pB = i2BoardPtrTable[i]; - if( pB ) { - switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) - { - case POR_ID_FIIEX: - seq_printf(m, "Board %d: EX ports=", i); - sep = ""; - for( box = 0; box < ABS_MAX_BOXES; ++box ) - { - ports = 0; - - if( pB->i2eChannelMap[box] != 0 ) ++boxes; - for( j = 0; j < ABS_BIGGEST_BOX; ++j ) - { - if( pB->i2eChannelMap[box] & 1<< j ) { - ++ports; - } - } - seq_printf(m, "%s%d", sep, ports); - sep = ","; - tports += ports; - } - seq_printf(m, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8); - break; - - case POR_ID_II_4: - seq_printf(m, "Board %d: ISA-4 ports=4 boxes=1", i); - tports = ports = 4; - break; - - case POR_ID_II_8: - seq_printf(m, "Board %d: ISA-8-std ports=8 boxes=1", i); - tports = ports = 8; - break; - - case POR_ID_II_8R: - seq_printf(m, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i); - tports = ports = 8; - break; - - default: - seq_printf(m, "Board %d: unknown", i); - /* Don't try and probe for minor numbers */ - tports = ports = 0; - } - - } else { - /* Don't try and probe for minor numbers */ - seq_printf(m, "Board %d: vacant", i); - tports = ports = 0; - } - - if( tports ) { - seq_puts(m, " minors="); - sep = ""; - for ( box = 0; box < ABS_MAX_BOXES; ++box ) - { - for ( j = 0; j < ABS_BIGGEST_BOX; ++j ) - { - if ( pB->i2eChannelMap[box] & (1 << j) ) - { - seq_printf(m, "%s%d", sep, - j + ABS_BIGGEST_BOX * - (box+i*ABS_MAX_BOXES)); - sep = ","; - } - } - } - } - seq_putc(m, '\n'); - } - return 0; - } - -static int ip2_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, ip2_proc_show, NULL); -} - -static const struct file_operations ip2_proc_fops = { - .owner = THIS_MODULE, - .open = ip2_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/******************************************************************************/ -/* Function: ip2trace() */ -/* Parameters: Value to add to trace buffer */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -#ifdef IP2DEBUG_TRACE -void -ip2trace (unsigned short pn, unsigned char cat, unsigned char label, unsigned long codes, ...) -{ - long flags; - unsigned long *pCode = &codes; - union ip2breadcrumb bc; - i2ChanStrPtr pCh; - - - tracebuf[tracestuff++] = jiffies; - if ( tracestuff == TRACEMAX ) { - tracestuff = 0; - } - if ( tracestuff == tracestrip ) { - if ( ++tracestrip == TRACEMAX ) { - tracestrip = 0; - } - ++tracewrap; - } - - bc.hdr.port = 0xff & pn; - bc.hdr.cat = cat; - bc.hdr.codes = (unsigned char)( codes & 0xff ); - bc.hdr.label = label; - tracebuf[tracestuff++] = bc.value; - - for (;;) { - if ( tracestuff == TRACEMAX ) { - tracestuff = 0; - } - if ( tracestuff == tracestrip ) { - if ( ++tracestrip == TRACEMAX ) { - tracestrip = 0; - } - ++tracewrap; - } - - if ( !codes-- ) - break; - - tracebuf[tracestuff++] = *++pCode; - } -} -#endif - - -MODULE_LICENSE("GPL"); - -static struct pci_device_id ip2main_pci_tbl[] __devinitdata __used = { - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_IP2EX) }, - { } -}; - -MODULE_DEVICE_TABLE(pci, ip2main_pci_tbl); - -MODULE_FIRMWARE("intelliport2.bin"); diff --git a/drivers/char/ip2/ip2trace.h b/drivers/char/ip2/ip2trace.h deleted file mode 100644 index da20435dc8a6..000000000000 --- a/drivers/char/ip2/ip2trace.h +++ /dev/null @@ -1,42 +0,0 @@ - -// -union ip2breadcrumb -{ - struct { - unsigned char port, cat, codes, label; - } __attribute__ ((packed)) hdr; - unsigned long value; -}; - -#define ITRC_NO_PORT 0xFF -#define CHANN (pCh->port_index) - -#define ITRC_ERROR '!' -#define ITRC_INIT 'A' -#define ITRC_OPEN 'B' -#define ITRC_CLOSE 'C' -#define ITRC_DRAIN 'D' -#define ITRC_IOCTL 'E' -#define ITRC_FLUSH 'F' -#define ITRC_STATUS 'G' -#define ITRC_HANGUP 'H' -#define ITRC_INTR 'I' -#define ITRC_SFLOW 'J' -#define ITRC_SBCMD 'K' -#define ITRC_SICMD 'L' -#define ITRC_MODEM 'M' -#define ITRC_INPUT 'N' -#define ITRC_OUTPUT 'O' -#define ITRC_PUTC 'P' -#define ITRC_QUEUE 'Q' -#define ITRC_STFLW 'R' -#define ITRC_SFIFO 'S' -#define ITRC_VERIFY 'V' -#define ITRC_WRITE 'W' - -#define ITRC_ENTER 0x00 -#define ITRC_RETURN 0xFF - -#define ITRC_QUEUE_ROOM 2 -#define ITRC_QUEUE_CMD 6 - diff --git a/drivers/char/ip2/ip2types.h b/drivers/char/ip2/ip2types.h deleted file mode 100644 index 9d67b260b2f6..000000000000 --- a/drivers/char/ip2/ip2types.h +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* -* -* (c) 1998 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Driver constants and type definitions. -* -* NOTES: -* -*******************************************************************************/ -#ifndef IP2TYPES_H -#define IP2TYPES_H - -//************* -//* Constants * -//************* - -// Define some limits for this driver. Ports per board is a hardware limitation -// that will not change. Current hardware limits this to 64 ports per board. -// Boards per driver is a self-imposed limit. -// -#define IP2_MAX_BOARDS 4 -#define IP2_PORTS_PER_BOARD ABS_MOST_PORTS -#define IP2_MAX_PORTS (IP2_MAX_BOARDS*IP2_PORTS_PER_BOARD) - -#define ISA 0 -#define PCI 1 -#define EISA 2 - -//******************** -//* Type Definitions * -//******************** - -typedef struct tty_struct * PTTY; -typedef wait_queue_head_t PWAITQ; - -typedef unsigned char UCHAR; -typedef unsigned int UINT; -typedef unsigned short USHORT; -typedef unsigned long ULONG; - -typedef struct -{ - short irq[IP2_MAX_BOARDS]; - unsigned short addr[IP2_MAX_BOARDS]; - int type[IP2_MAX_BOARDS]; -#ifdef CONFIG_PCI - struct pci_dev *pci_dev[IP2_MAX_BOARDS]; -#endif -} ip2config_t; - -#endif diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c deleted file mode 100644 index 0b266272cccd..000000000000 --- a/drivers/char/istallion.c +++ /dev/null @@ -1,4507 +0,0 @@ -/*****************************************************************************/ - -/* - * istallion.c -- stallion intelligent multiport serial driver. - * - * Copyright (C) 1996-1999 Stallion Technologies - * Copyright (C) 1994-1996 Greg Ungerer. - * - * This code is loosely based on the Linux serial driver, written by - * Linus Torvalds, Theodore T'so and others. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ - -/*****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -/*****************************************************************************/ - -/* - * Define different board types. Not all of the following board types - * are supported by this driver. But I will use the standard "assigned" - * board numbers. Currently supported boards are abbreviated as: - * ECP = EasyConnection 8/64, ONB = ONboard, BBY = Brumby and - * STAL = Stallion. - */ -#define BRD_UNKNOWN 0 -#define BRD_STALLION 1 -#define BRD_BRUMBY4 2 -#define BRD_ONBOARD2 3 -#define BRD_ONBOARD 4 -#define BRD_ONBOARDE 7 -#define BRD_ECP 23 -#define BRD_ECPE 24 -#define BRD_ECPMC 25 -#define BRD_ECPPCI 29 - -#define BRD_BRUMBY BRD_BRUMBY4 - -/* - * Define a configuration structure to hold the board configuration. - * Need to set this up in the code (for now) with the boards that are - * to be configured into the system. This is what needs to be modified - * when adding/removing/modifying boards. Each line entry in the - * stli_brdconf[] array is a board. Each line contains io/irq/memory - * ranges for that board (as well as what type of board it is). - * Some examples: - * { BRD_ECP, 0x2a0, 0, 0xcc000, 0, 0 }, - * This line will configure an EasyConnection 8/64 at io address 2a0, - * and shared memory address of cc000. Multiple EasyConnection 8/64 - * boards can share the same shared memory address space. No interrupt - * is required for this board type. - * Another example: - * { BRD_ECPE, 0x5000, 0, 0x80000000, 0, 0 }, - * This line will configure an EasyConnection 8/64 EISA in slot 5 and - * shared memory address of 0x80000000 (2 GByte). Multiple - * EasyConnection 8/64 EISA boards can share the same shared memory - * address space. No interrupt is required for this board type. - * Another example: - * { BRD_ONBOARD, 0x240, 0, 0xd0000, 0, 0 }, - * This line will configure an ONboard (ISA type) at io address 240, - * and shared memory address of d0000. Multiple ONboards can share - * the same shared memory address space. No interrupt required. - * Another example: - * { BRD_BRUMBY4, 0x360, 0, 0xc8000, 0, 0 }, - * This line will configure a Brumby board (any number of ports!) at - * io address 360 and shared memory address of c8000. All Brumby boards - * configured into a system must have their own separate io and memory - * addresses. No interrupt is required. - * Another example: - * { BRD_STALLION, 0x330, 0, 0xd0000, 0, 0 }, - * This line will configure an original Stallion board at io address 330 - * and shared memory address d0000 (this would only be valid for a "V4.0" - * or Rev.O Stallion board). All Stallion boards configured into the - * system must have their own separate io and memory addresses. No - * interrupt is required. - */ - -struct stlconf { - int brdtype; - int ioaddr1; - int ioaddr2; - unsigned long memaddr; - int irq; - int irqtype; -}; - -static unsigned int stli_nrbrds; - -/* stli_lock must NOT be taken holding brd_lock */ -static spinlock_t stli_lock; /* TTY logic lock */ -static spinlock_t brd_lock; /* Board logic lock */ - -/* - * There is some experimental EISA board detection code in this driver. - * By default it is disabled, but for those that want to try it out, - * then set the define below to be 1. - */ -#define STLI_EISAPROBE 0 - -/*****************************************************************************/ - -/* - * Define some important driver characteristics. Device major numbers - * allocated as per Linux Device Registry. - */ -#ifndef STL_SIOMEMMAJOR -#define STL_SIOMEMMAJOR 28 -#endif -#ifndef STL_SERIALMAJOR -#define STL_SERIALMAJOR 24 -#endif -#ifndef STL_CALLOUTMAJOR -#define STL_CALLOUTMAJOR 25 -#endif - -/*****************************************************************************/ - -/* - * Define our local driver identity first. Set up stuff to deal with - * all the local structures required by a serial tty driver. - */ -static char *stli_drvtitle = "Stallion Intelligent Multiport Serial Driver"; -static char *stli_drvname = "istallion"; -static char *stli_drvversion = "5.6.0"; -static char *stli_serialname = "ttyE"; - -static struct tty_driver *stli_serial; -static const struct tty_port_operations stli_port_ops; - -#define STLI_TXBUFSIZE 4096 - -/* - * Use a fast local buffer for cooked characters. Typically a whole - * bunch of cooked characters come in for a port, 1 at a time. So we - * save those up into a local buffer, then write out the whole lot - * with a large memcpy. Just use 1 buffer for all ports, since its - * use it is only need for short periods of time by each port. - */ -static char *stli_txcookbuf; -static int stli_txcooksize; -static int stli_txcookrealsize; -static struct tty_struct *stli_txcooktty; - -/* - * Define a local default termios struct. All ports will be created - * with this termios initially. Basically all it defines is a raw port - * at 9600 baud, 8 data bits, no parity, 1 stop bit. - */ -static struct ktermios stli_deftermios = { - .c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL), - .c_cc = INIT_C_CC, - .c_ispeed = 9600, - .c_ospeed = 9600, -}; - -/* - * Define global stats structures. Not used often, and can be - * re-used for each stats call. - */ -static comstats_t stli_comstats; -static combrd_t stli_brdstats; -static struct asystats stli_cdkstats; - -/*****************************************************************************/ - -static DEFINE_MUTEX(stli_brdslock); -static struct stlibrd *stli_brds[STL_MAXBRDS]; - -static int stli_shared; - -/* - * Per board state flags. Used with the state field of the board struct. - * Not really much here... All we need to do is keep track of whether - * the board has been detected, and whether it is actually running a slave - * or not. - */ -#define BST_FOUND 0 -#define BST_STARTED 1 -#define BST_PROBED 2 - -/* - * Define the set of port state flags. These are marked for internal - * state purposes only, usually to do with the state of communications - * with the slave. Most of them need to be updated atomically, so always - * use the bit setting operations (unless protected by cli/sti). - */ -#define ST_OPENING 2 -#define ST_CLOSING 3 -#define ST_CMDING 4 -#define ST_TXBUSY 5 -#define ST_RXING 6 -#define ST_DOFLUSHRX 7 -#define ST_DOFLUSHTX 8 -#define ST_DOSIGS 9 -#define ST_RXSTOP 10 -#define ST_GETSIGS 11 - -/* - * Define an array of board names as printable strings. Handy for - * referencing boards when printing trace and stuff. - */ -static char *stli_brdnames[] = { - "Unknown", - "Stallion", - "Brumby", - "ONboard-MC", - "ONboard", - "Brumby", - "Brumby", - "ONboard-EI", - NULL, - "ONboard", - "ONboard-MC", - "ONboard-MC", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "EasyIO", - "EC8/32-AT", - "EC8/32-MC", - "EC8/64-AT", - "EC8/64-EI", - "EC8/64-MC", - "EC8/32-PCI", - "EC8/64-PCI", - "EasyIO-PCI", - "EC/RA-PCI", -}; - -/*****************************************************************************/ - -/* - * Define some string labels for arguments passed from the module - * load line. These allow for easy board definitions, and easy - * modification of the io, memory and irq resoucres. - */ - -static char *board0[8]; -static char *board1[8]; -static char *board2[8]; -static char *board3[8]; - -static char **stli_brdsp[] = { - (char **) &board0, - (char **) &board1, - (char **) &board2, - (char **) &board3 -}; - -/* - * Define a set of common board names, and types. This is used to - * parse any module arguments. - */ - -static struct stlibrdtype { - char *name; - int type; -} stli_brdstr[] = { - { "stallion", BRD_STALLION }, - { "1", BRD_STALLION }, - { "brumby", BRD_BRUMBY }, - { "brumby4", BRD_BRUMBY }, - { "brumby/4", BRD_BRUMBY }, - { "brumby-4", BRD_BRUMBY }, - { "brumby8", BRD_BRUMBY }, - { "brumby/8", BRD_BRUMBY }, - { "brumby-8", BRD_BRUMBY }, - { "brumby16", BRD_BRUMBY }, - { "brumby/16", BRD_BRUMBY }, - { "brumby-16", BRD_BRUMBY }, - { "2", BRD_BRUMBY }, - { "onboard2", BRD_ONBOARD2 }, - { "onboard-2", BRD_ONBOARD2 }, - { "onboard/2", BRD_ONBOARD2 }, - { "onboard-mc", BRD_ONBOARD2 }, - { "onboard/mc", BRD_ONBOARD2 }, - { "onboard-mca", BRD_ONBOARD2 }, - { "onboard/mca", BRD_ONBOARD2 }, - { "3", BRD_ONBOARD2 }, - { "onboard", BRD_ONBOARD }, - { "onboardat", BRD_ONBOARD }, - { "4", BRD_ONBOARD }, - { "onboarde", BRD_ONBOARDE }, - { "onboard-e", BRD_ONBOARDE }, - { "onboard/e", BRD_ONBOARDE }, - { "onboard-ei", BRD_ONBOARDE }, - { "onboard/ei", BRD_ONBOARDE }, - { "7", BRD_ONBOARDE }, - { "ecp", BRD_ECP }, - { "ecpat", BRD_ECP }, - { "ec8/64", BRD_ECP }, - { "ec8/64-at", BRD_ECP }, - { "ec8/64-isa", BRD_ECP }, - { "23", BRD_ECP }, - { "ecpe", BRD_ECPE }, - { "ecpei", BRD_ECPE }, - { "ec8/64-e", BRD_ECPE }, - { "ec8/64-ei", BRD_ECPE }, - { "24", BRD_ECPE }, - { "ecpmc", BRD_ECPMC }, - { "ec8/64-mc", BRD_ECPMC }, - { "ec8/64-mca", BRD_ECPMC }, - { "25", BRD_ECPMC }, - { "ecppci", BRD_ECPPCI }, - { "ec/ra", BRD_ECPPCI }, - { "ec/ra-pc", BRD_ECPPCI }, - { "ec/ra-pci", BRD_ECPPCI }, - { "29", BRD_ECPPCI }, -}; - -/* - * Define the module agruments. - */ -MODULE_AUTHOR("Greg Ungerer"); -MODULE_DESCRIPTION("Stallion Intelligent Multiport Serial Driver"); -MODULE_LICENSE("GPL"); - - -module_param_array(board0, charp, NULL, 0); -MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,memaddr]"); -module_param_array(board1, charp, NULL, 0); -MODULE_PARM_DESC(board1, "Board 1 config -> name[,ioaddr[,memaddr]"); -module_param_array(board2, charp, NULL, 0); -MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,memaddr]"); -module_param_array(board3, charp, NULL, 0); -MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,memaddr]"); - -#if STLI_EISAPROBE != 0 -/* - * Set up a default memory address table for EISA board probing. - * The default addresses are all bellow 1Mbyte, which has to be the - * case anyway. They should be safe, since we only read values from - * them, and interrupts are disabled while we do it. If the higher - * memory support is compiled in then we also try probing around - * the 1Gb, 2Gb and 3Gb areas as well... - */ -static unsigned long stli_eisamemprobeaddrs[] = { - 0xc0000, 0xd0000, 0xe0000, 0xf0000, - 0x80000000, 0x80010000, 0x80020000, 0x80030000, - 0x40000000, 0x40010000, 0x40020000, 0x40030000, - 0xc0000000, 0xc0010000, 0xc0020000, 0xc0030000, - 0xff000000, 0xff010000, 0xff020000, 0xff030000, -}; - -static int stli_eisamempsize = ARRAY_SIZE(stli_eisamemprobeaddrs); -#endif - -/* - * Define the Stallion PCI vendor and device IDs. - */ -#ifndef PCI_DEVICE_ID_ECRA -#define PCI_DEVICE_ID_ECRA 0x0004 -#endif - -static struct pci_device_id istallion_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA), }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, istallion_pci_tbl); - -static struct pci_driver stli_pcidriver; - -/*****************************************************************************/ - -/* - * Hardware configuration info for ECP boards. These defines apply - * to the directly accessible io ports of the ECP. There is a set of - * defines for each ECP board type, ISA, EISA, MCA and PCI. - */ -#define ECP_IOSIZE 4 - -#define ECP_MEMSIZE (128 * 1024) -#define ECP_PCIMEMSIZE (256 * 1024) - -#define ECP_ATPAGESIZE (4 * 1024) -#define ECP_MCPAGESIZE (4 * 1024) -#define ECP_EIPAGESIZE (64 * 1024) -#define ECP_PCIPAGESIZE (64 * 1024) - -#define STL_EISAID 0x8c4e - -/* - * Important defines for the ISA class of ECP board. - */ -#define ECP_ATIREG 0 -#define ECP_ATCONFR 1 -#define ECP_ATMEMAR 2 -#define ECP_ATMEMPR 3 -#define ECP_ATSTOP 0x1 -#define ECP_ATINTENAB 0x10 -#define ECP_ATENABLE 0x20 -#define ECP_ATDISABLE 0x00 -#define ECP_ATADDRMASK 0x3f000 -#define ECP_ATADDRSHFT 12 - -/* - * Important defines for the EISA class of ECP board. - */ -#define ECP_EIIREG 0 -#define ECP_EIMEMARL 1 -#define ECP_EICONFR 2 -#define ECP_EIMEMARH 3 -#define ECP_EIENABLE 0x1 -#define ECP_EIDISABLE 0x0 -#define ECP_EISTOP 0x4 -#define ECP_EIEDGE 0x00 -#define ECP_EILEVEL 0x80 -#define ECP_EIADDRMASKL 0x00ff0000 -#define ECP_EIADDRSHFTL 16 -#define ECP_EIADDRMASKH 0xff000000 -#define ECP_EIADDRSHFTH 24 -#define ECP_EIBRDENAB 0xc84 - -#define ECP_EISAID 0x4 - -/* - * Important defines for the Micro-channel class of ECP board. - * (It has a lot in common with the ISA boards.) - */ -#define ECP_MCIREG 0 -#define ECP_MCCONFR 1 -#define ECP_MCSTOP 0x20 -#define ECP_MCENABLE 0x80 -#define ECP_MCDISABLE 0x00 - -/* - * Important defines for the PCI class of ECP board. - * (It has a lot in common with the other ECP boards.) - */ -#define ECP_PCIIREG 0 -#define ECP_PCICONFR 1 -#define ECP_PCISTOP 0x01 - -/* - * Hardware configuration info for ONboard and Brumby boards. These - * defines apply to the directly accessible io ports of these boards. - */ -#define ONB_IOSIZE 16 -#define ONB_MEMSIZE (64 * 1024) -#define ONB_ATPAGESIZE (64 * 1024) -#define ONB_MCPAGESIZE (64 * 1024) -#define ONB_EIMEMSIZE (128 * 1024) -#define ONB_EIPAGESIZE (64 * 1024) - -/* - * Important defines for the ISA class of ONboard board. - */ -#define ONB_ATIREG 0 -#define ONB_ATMEMAR 1 -#define ONB_ATCONFR 2 -#define ONB_ATSTOP 0x4 -#define ONB_ATENABLE 0x01 -#define ONB_ATDISABLE 0x00 -#define ONB_ATADDRMASK 0xff0000 -#define ONB_ATADDRSHFT 16 - -#define ONB_MEMENABLO 0 -#define ONB_MEMENABHI 0x02 - -/* - * Important defines for the EISA class of ONboard board. - */ -#define ONB_EIIREG 0 -#define ONB_EIMEMARL 1 -#define ONB_EICONFR 2 -#define ONB_EIMEMARH 3 -#define ONB_EIENABLE 0x1 -#define ONB_EIDISABLE 0x0 -#define ONB_EISTOP 0x4 -#define ONB_EIEDGE 0x00 -#define ONB_EILEVEL 0x80 -#define ONB_EIADDRMASKL 0x00ff0000 -#define ONB_EIADDRSHFTL 16 -#define ONB_EIADDRMASKH 0xff000000 -#define ONB_EIADDRSHFTH 24 -#define ONB_EIBRDENAB 0xc84 - -#define ONB_EISAID 0x1 - -/* - * Important defines for the Brumby boards. They are pretty simple, - * there is not much that is programmably configurable. - */ -#define BBY_IOSIZE 16 -#define BBY_MEMSIZE (64 * 1024) -#define BBY_PAGESIZE (16 * 1024) - -#define BBY_ATIREG 0 -#define BBY_ATCONFR 1 -#define BBY_ATSTOP 0x4 - -/* - * Important defines for the Stallion boards. They are pretty simple, - * there is not much that is programmably configurable. - */ -#define STAL_IOSIZE 16 -#define STAL_MEMSIZE (64 * 1024) -#define STAL_PAGESIZE (64 * 1024) - -/* - * Define the set of status register values for EasyConnection panels. - * The signature will return with the status value for each panel. From - * this we can determine what is attached to the board - before we have - * actually down loaded any code to it. - */ -#define ECH_PNLSTATUS 2 -#define ECH_PNL16PORT 0x20 -#define ECH_PNLIDMASK 0x07 -#define ECH_PNLXPID 0x40 -#define ECH_PNLINTRPEND 0x80 - -/* - * Define some macros to do things to the board. Even those these boards - * are somewhat related there is often significantly different ways of - * doing some operation on it (like enable, paging, reset, etc). So each - * board class has a set of functions which do the commonly required - * operations. The macros below basically just call these functions, - * generally checking for a NULL function - which means that the board - * needs nothing done to it to achieve this operation! - */ -#define EBRDINIT(brdp) \ - if (brdp->init != NULL) \ - (* brdp->init)(brdp) - -#define EBRDENABLE(brdp) \ - if (brdp->enable != NULL) \ - (* brdp->enable)(brdp); - -#define EBRDDISABLE(brdp) \ - if (brdp->disable != NULL) \ - (* brdp->disable)(brdp); - -#define EBRDINTR(brdp) \ - if (brdp->intr != NULL) \ - (* brdp->intr)(brdp); - -#define EBRDRESET(brdp) \ - if (brdp->reset != NULL) \ - (* brdp->reset)(brdp); - -#define EBRDGETMEMPTR(brdp,offset) \ - (* brdp->getmemptr)(brdp, offset, __LINE__) - -/* - * Define the maximal baud rate, and the default baud base for ports. - */ -#define STL_MAXBAUD 460800 -#define STL_BAUDBASE 115200 -#define STL_CLOSEDELAY (5 * HZ / 10) - -/*****************************************************************************/ - -/* - * Define macros to extract a brd or port number from a minor number. - */ -#define MINOR2BRD(min) (((min) & 0xc0) >> 6) -#define MINOR2PORT(min) ((min) & 0x3f) - -/*****************************************************************************/ - -/* - * Prototype all functions in this driver! - */ - -static int stli_parsebrd(struct stlconf *confp, char **argp); -static int stli_open(struct tty_struct *tty, struct file *filp); -static void stli_close(struct tty_struct *tty, struct file *filp); -static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count); -static int stli_putchar(struct tty_struct *tty, unsigned char ch); -static void stli_flushchars(struct tty_struct *tty); -static int stli_writeroom(struct tty_struct *tty); -static int stli_charsinbuffer(struct tty_struct *tty); -static int stli_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); -static void stli_settermios(struct tty_struct *tty, struct ktermios *old); -static void stli_throttle(struct tty_struct *tty); -static void stli_unthrottle(struct tty_struct *tty); -static void stli_stop(struct tty_struct *tty); -static void stli_start(struct tty_struct *tty); -static void stli_flushbuffer(struct tty_struct *tty); -static int stli_breakctl(struct tty_struct *tty, int state); -static void stli_waituntilsent(struct tty_struct *tty, int timeout); -static void stli_sendxchar(struct tty_struct *tty, char ch); -static void stli_hangup(struct tty_struct *tty); - -static int stli_brdinit(struct stlibrd *brdp); -static int stli_startbrd(struct stlibrd *brdp); -static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp); -static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp); -static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg); -static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp); -static void stli_poll(unsigned long arg); -static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp); -static int stli_initopen(struct tty_struct *tty, struct stlibrd *brdp, struct stliport *portp); -static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); -static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); -static int stli_setport(struct tty_struct *tty); -static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); -static void stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); -static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); -static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp); -static void stli_mkasyport(struct tty_struct *tty, struct stliport *portp, asyport_t *pp, struct ktermios *tiosp); -static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts); -static long stli_mktiocm(unsigned long sigvalue); -static void stli_read(struct stlibrd *brdp, struct stliport *portp); -static int stli_getserial(struct stliport *portp, struct serial_struct __user *sp); -static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *sp); -static int stli_getbrdstats(combrd_t __user *bp); -static int stli_getportstats(struct tty_struct *tty, struct stliport *portp, comstats_t __user *cp); -static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp); -static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp); -static int stli_getportstruct(struct stliport __user *arg); -static int stli_getbrdstruct(struct stlibrd __user *arg); -static struct stlibrd *stli_allocbrd(void); - -static void stli_ecpinit(struct stlibrd *brdp); -static void stli_ecpenable(struct stlibrd *brdp); -static void stli_ecpdisable(struct stlibrd *brdp); -static void __iomem *stli_ecpgetmemptr(struct stlibrd *brdp, unsigned long offset, int line); -static void stli_ecpreset(struct stlibrd *brdp); -static void stli_ecpintr(struct stlibrd *brdp); -static void stli_ecpeiinit(struct stlibrd *brdp); -static void stli_ecpeienable(struct stlibrd *brdp); -static void stli_ecpeidisable(struct stlibrd *brdp); -static void __iomem *stli_ecpeigetmemptr(struct stlibrd *brdp, unsigned long offset, int line); -static void stli_ecpeireset(struct stlibrd *brdp); -static void stli_ecpmcenable(struct stlibrd *brdp); -static void stli_ecpmcdisable(struct stlibrd *brdp); -static void __iomem *stli_ecpmcgetmemptr(struct stlibrd *brdp, unsigned long offset, int line); -static void stli_ecpmcreset(struct stlibrd *brdp); -static void stli_ecppciinit(struct stlibrd *brdp); -static void __iomem *stli_ecppcigetmemptr(struct stlibrd *brdp, unsigned long offset, int line); -static void stli_ecppcireset(struct stlibrd *brdp); - -static void stli_onbinit(struct stlibrd *brdp); -static void stli_onbenable(struct stlibrd *brdp); -static void stli_onbdisable(struct stlibrd *brdp); -static void __iomem *stli_onbgetmemptr(struct stlibrd *brdp, unsigned long offset, int line); -static void stli_onbreset(struct stlibrd *brdp); -static void stli_onbeinit(struct stlibrd *brdp); -static void stli_onbeenable(struct stlibrd *brdp); -static void stli_onbedisable(struct stlibrd *brdp); -static void __iomem *stli_onbegetmemptr(struct stlibrd *brdp, unsigned long offset, int line); -static void stli_onbereset(struct stlibrd *brdp); -static void stli_bbyinit(struct stlibrd *brdp); -static void __iomem *stli_bbygetmemptr(struct stlibrd *brdp, unsigned long offset, int line); -static void stli_bbyreset(struct stlibrd *brdp); -static void stli_stalinit(struct stlibrd *brdp); -static void __iomem *stli_stalgetmemptr(struct stlibrd *brdp, unsigned long offset, int line); -static void stli_stalreset(struct stlibrd *brdp); - -static struct stliport *stli_getport(unsigned int brdnr, unsigned int panelnr, unsigned int portnr); - -static int stli_initecp(struct stlibrd *brdp); -static int stli_initonb(struct stlibrd *brdp); -#if STLI_EISAPROBE != 0 -static int stli_eisamemprobe(struct stlibrd *brdp); -#endif -static int stli_initports(struct stlibrd *brdp); - -/*****************************************************************************/ - -/* - * Define the driver info for a user level shared memory device. This - * device will work sort of like the /dev/kmem device - except that it - * will give access to the shared memory on the Stallion intelligent - * board. This is also a very useful debugging tool. - */ -static const struct file_operations stli_fsiomem = { - .owner = THIS_MODULE, - .read = stli_memread, - .write = stli_memwrite, - .unlocked_ioctl = stli_memioctl, - .llseek = default_llseek, -}; - -/*****************************************************************************/ - -/* - * Define a timer_list entry for our poll routine. The slave board - * is polled every so often to see if anything needs doing. This is - * much cheaper on host cpu than using interrupts. It turns out to - * not increase character latency by much either... - */ -static DEFINE_TIMER(stli_timerlist, stli_poll, 0, 0); - -static int stli_timeron; - -/* - * Define the calculation for the timeout routine. - */ -#define STLI_TIMEOUT (jiffies + 1) - -/*****************************************************************************/ - -static struct class *istallion_class; - -static void stli_cleanup_ports(struct stlibrd *brdp) -{ - struct stliport *portp; - unsigned int j; - struct tty_struct *tty; - - for (j = 0; j < STL_MAXPORTS; j++) { - portp = brdp->ports[j]; - if (portp != NULL) { - tty = tty_port_tty_get(&portp->port); - if (tty != NULL) { - tty_hangup(tty); - tty_kref_put(tty); - } - kfree(portp); - } - } -} - -/*****************************************************************************/ - -/* - * Parse the supplied argument string, into the board conf struct. - */ - -static int stli_parsebrd(struct stlconf *confp, char **argp) -{ - unsigned int i; - char *sp; - - if (argp[0] == NULL || *argp[0] == 0) - return 0; - - for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++) - *sp = tolower(*sp); - - for (i = 0; i < ARRAY_SIZE(stli_brdstr); i++) { - if (strcmp(stli_brdstr[i].name, argp[0]) == 0) - break; - } - if (i == ARRAY_SIZE(stli_brdstr)) { - printk(KERN_WARNING "istallion: unknown board name, %s?\n", argp[0]); - return 0; - } - - confp->brdtype = stli_brdstr[i].type; - if (argp[1] != NULL && *argp[1] != 0) - confp->ioaddr1 = simple_strtoul(argp[1], NULL, 0); - if (argp[2] != NULL && *argp[2] != 0) - confp->memaddr = simple_strtoul(argp[2], NULL, 0); - return(1); -} - -/*****************************************************************************/ - -/* - * On the first open of the device setup the port hardware, and - * initialize the per port data structure. Since initializing the port - * requires several commands to the board we will need to wait for any - * other open that is already initializing the port. - * - * Locking: protected by the port mutex. - */ - -static int stli_activate(struct tty_port *port, struct tty_struct *tty) -{ - struct stliport *portp = container_of(port, struct stliport, port); - struct stlibrd *brdp = stli_brds[portp->brdnr]; - int rc; - - if ((rc = stli_initopen(tty, brdp, portp)) >= 0) - clear_bit(TTY_IO_ERROR, &tty->flags); - wake_up_interruptible(&portp->raw_wait); - return rc; -} - -static int stli_open(struct tty_struct *tty, struct file *filp) -{ - struct stlibrd *brdp; - struct stliport *portp; - unsigned int minordev, brdnr, portnr; - - minordev = tty->index; - brdnr = MINOR2BRD(minordev); - if (brdnr >= stli_nrbrds) - return -ENODEV; - brdp = stli_brds[brdnr]; - if (brdp == NULL) - return -ENODEV; - if (!test_bit(BST_STARTED, &brdp->state)) - return -ENODEV; - portnr = MINOR2PORT(minordev); - if (portnr > brdp->nrports) - return -ENODEV; - - portp = brdp->ports[portnr]; - if (portp == NULL) - return -ENODEV; - if (portp->devnr < 1) - return -ENODEV; - - tty->driver_data = portp; - return tty_port_open(&portp->port, tty, filp); -} - - -/*****************************************************************************/ - -static void stli_shutdown(struct tty_port *port) -{ - struct stlibrd *brdp; - unsigned long ftype; - unsigned long flags; - struct stliport *portp = container_of(port, struct stliport, port); - - if (portp->brdnr >= stli_nrbrds) - return; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return; - - /* - * May want to wait for data to drain before closing. The BUSY - * flag keeps track of whether we are still transmitting or not. - * It is updated by messages from the slave - indicating when all - * chars really have drained. - */ - - if (!test_bit(ST_CLOSING, &portp->state)) - stli_rawclose(brdp, portp, 0, 0); - - spin_lock_irqsave(&stli_lock, flags); - clear_bit(ST_TXBUSY, &portp->state); - clear_bit(ST_RXSTOP, &portp->state); - spin_unlock_irqrestore(&stli_lock, flags); - - ftype = FLUSHTX | FLUSHRX; - stli_cmdwait(brdp, portp, A_FLUSH, &ftype, sizeof(u32), 0); -} - -static void stli_close(struct tty_struct *tty, struct file *filp) -{ - struct stliport *portp = tty->driver_data; - unsigned long flags; - if (portp == NULL) - return; - spin_lock_irqsave(&stli_lock, flags); - /* Flush any internal buffering out first */ - if (tty == stli_txcooktty) - stli_flushchars(tty); - spin_unlock_irqrestore(&stli_lock, flags); - tty_port_close(&portp->port, tty, filp); -} - -/*****************************************************************************/ - -/* - * Carry out first open operations on a port. This involves a number of - * commands to be sent to the slave. We need to open the port, set the - * notification events, set the initial port settings, get and set the - * initial signal values. We sleep and wait in between each one. But - * this still all happens pretty quickly. - */ - -static int stli_initopen(struct tty_struct *tty, - struct stlibrd *brdp, struct stliport *portp) -{ - asynotify_t nt; - asyport_t aport; - int rc; - - if ((rc = stli_rawopen(brdp, portp, 0, 1)) < 0) - return rc; - - memset(&nt, 0, sizeof(asynotify_t)); - nt.data = (DT_TXLOW | DT_TXEMPTY | DT_RXBUSY | DT_RXBREAK); - nt.signal = SG_DCD; - if ((rc = stli_cmdwait(brdp, portp, A_SETNOTIFY, &nt, - sizeof(asynotify_t), 0)) < 0) - return rc; - - stli_mkasyport(tty, portp, &aport, tty->termios); - if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport, - sizeof(asyport_t), 0)) < 0) - return rc; - - set_bit(ST_GETSIGS, &portp->state); - if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig, - sizeof(asysigs_t), 1)) < 0) - return rc; - if (test_and_clear_bit(ST_GETSIGS, &portp->state)) - portp->sigs = stli_mktiocm(portp->asig.sigvalue); - stli_mkasysigs(&portp->asig, 1, 1); - if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, - sizeof(asysigs_t), 0)) < 0) - return rc; - - return 0; -} - -/*****************************************************************************/ - -/* - * Send an open message to the slave. This will sleep waiting for the - * acknowledgement, so must have user context. We need to co-ordinate - * with close events here, since we don't want open and close events - * to overlap. - */ - -static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait) -{ - cdkhdr_t __iomem *hdrp; - cdkctrl_t __iomem *cp; - unsigned char __iomem *bits; - unsigned long flags; - int rc; - -/* - * Send a message to the slave to open this port. - */ - -/* - * Slave is already closing this port. This can happen if a hangup - * occurs on this port. So we must wait until it is complete. The - * order of opens and closes may not be preserved across shared - * memory, so we must wait until it is complete. - */ - wait_event_interruptible_tty(portp->raw_wait, - !test_bit(ST_CLOSING, &portp->state)); - if (signal_pending(current)) { - return -ERESTARTSYS; - } - -/* - * Everything is ready now, so write the open message into shared - * memory. Once the message is in set the service bits to say that - * this port wants service. - */ - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; - writel(arg, &cp->openarg); - writeb(1, &cp->open); - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + - portp->portidx; - writeb(readb(bits) | portp->portbit, bits); - EBRDDISABLE(brdp); - - if (wait == 0) { - spin_unlock_irqrestore(&brd_lock, flags); - return 0; - } - -/* - * Slave is in action, so now we must wait for the open acknowledgment - * to come back. - */ - rc = 0; - set_bit(ST_OPENING, &portp->state); - spin_unlock_irqrestore(&brd_lock, flags); - - wait_event_interruptible_tty(portp->raw_wait, - !test_bit(ST_OPENING, &portp->state)); - if (signal_pending(current)) - rc = -ERESTARTSYS; - - if ((rc == 0) && (portp->rc != 0)) - rc = -EIO; - return rc; -} - -/*****************************************************************************/ - -/* - * Send a close message to the slave. Normally this will sleep waiting - * for the acknowledgement, but if wait parameter is 0 it will not. If - * wait is true then must have user context (to sleep). - */ - -static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait) -{ - cdkhdr_t __iomem *hdrp; - cdkctrl_t __iomem *cp; - unsigned char __iomem *bits; - unsigned long flags; - int rc; - -/* - * Slave is already closing this port. This can happen if a hangup - * occurs on this port. - */ - if (wait) { - wait_event_interruptible_tty(portp->raw_wait, - !test_bit(ST_CLOSING, &portp->state)); - if (signal_pending(current)) { - return -ERESTARTSYS; - } - } - -/* - * Write the close command into shared memory. - */ - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; - writel(arg, &cp->closearg); - writeb(1, &cp->close); - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + - portp->portidx; - writeb(readb(bits) |portp->portbit, bits); - EBRDDISABLE(brdp); - - set_bit(ST_CLOSING, &portp->state); - spin_unlock_irqrestore(&brd_lock, flags); - - if (wait == 0) - return 0; - -/* - * Slave is in action, so now we must wait for the open acknowledgment - * to come back. - */ - rc = 0; - wait_event_interruptible_tty(portp->raw_wait, - !test_bit(ST_CLOSING, &portp->state)); - if (signal_pending(current)) - rc = -ERESTARTSYS; - - if ((rc == 0) && (portp->rc != 0)) - rc = -EIO; - return rc; -} - -/*****************************************************************************/ - -/* - * Send a command to the slave and wait for the response. This must - * have user context (it sleeps). This routine is generic in that it - * can send any type of command. Its purpose is to wait for that command - * to complete (as opposed to initiating the command then returning). - */ - -static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback) -{ - /* - * no need for wait_event_tty because clearing ST_CMDING cannot block - * on BTM - */ - wait_event_interruptible(portp->raw_wait, - !test_bit(ST_CMDING, &portp->state)); - if (signal_pending(current)) - return -ERESTARTSYS; - - stli_sendcmd(brdp, portp, cmd, arg, size, copyback); - - wait_event_interruptible(portp->raw_wait, - !test_bit(ST_CMDING, &portp->state)); - if (signal_pending(current)) - return -ERESTARTSYS; - - if (portp->rc != 0) - return -EIO; - return 0; -} - -/*****************************************************************************/ - -/* - * Send the termios settings for this port to the slave. This sleeps - * waiting for the command to complete - so must have user context. - */ - -static int stli_setport(struct tty_struct *tty) -{ - struct stliport *portp = tty->driver_data; - struct stlibrd *brdp; - asyport_t aport; - - if (portp == NULL) - return -ENODEV; - if (portp->brdnr >= stli_nrbrds) - return -ENODEV; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return -ENODEV; - - stli_mkasyport(tty, portp, &aport, tty->termios); - return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)); -} - -/*****************************************************************************/ - -static int stli_carrier_raised(struct tty_port *port) -{ - struct stliport *portp = container_of(port, struct stliport, port); - return (portp->sigs & TIOCM_CD) ? 1 : 0; -} - -static void stli_dtr_rts(struct tty_port *port, int on) -{ - struct stliport *portp = container_of(port, struct stliport, port); - struct stlibrd *brdp = stli_brds[portp->brdnr]; - stli_mkasysigs(&portp->asig, on, on); - if (stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, - sizeof(asysigs_t), 0) < 0) - printk(KERN_WARNING "istallion: dtr set failed.\n"); -} - - -/*****************************************************************************/ - -/* - * Write routine. Take the data and put it in the shared memory ring - * queue. If port is not already sending chars then need to mark the - * service bits for this port. - */ - -static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count) -{ - cdkasy_t __iomem *ap; - cdkhdr_t __iomem *hdrp; - unsigned char __iomem *bits; - unsigned char __iomem *shbuf; - unsigned char *chbuf; - struct stliport *portp; - struct stlibrd *brdp; - unsigned int len, stlen, head, tail, size; - unsigned long flags; - - if (tty == stli_txcooktty) - stli_flushchars(tty); - portp = tty->driver_data; - if (portp == NULL) - return 0; - if (portp->brdnr >= stli_nrbrds) - return 0; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return 0; - chbuf = (unsigned char *) buf; - -/* - * All data is now local, shove as much as possible into shared memory. - */ - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); - head = (unsigned int) readw(&ap->txq.head); - tail = (unsigned int) readw(&ap->txq.tail); - if (tail != ((unsigned int) readw(&ap->txq.tail))) - tail = (unsigned int) readw(&ap->txq.tail); - size = portp->txsize; - if (head >= tail) { - len = size - (head - tail) - 1; - stlen = size - head; - } else { - len = tail - head - 1; - stlen = len; - } - - len = min(len, (unsigned int)count); - count = 0; - shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->txoffset); - - while (len > 0) { - stlen = min(len, stlen); - memcpy_toio(shbuf + head, chbuf, stlen); - chbuf += stlen; - len -= stlen; - count += stlen; - head += stlen; - if (head >= size) { - head = 0; - stlen = tail; - } - } - - ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); - writew(head, &ap->txq.head); - if (test_bit(ST_TXBUSY, &portp->state)) { - if (readl(&ap->changed.data) & DT_TXEMPTY) - writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data); - } - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + - portp->portidx; - writeb(readb(bits) | portp->portbit, bits); - set_bit(ST_TXBUSY, &portp->state); - EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); - - return(count); -} - -/*****************************************************************************/ - -/* - * Output a single character. We put it into a temporary local buffer - * (for speed) then write out that buffer when the flushchars routine - * is called. There is a safety catch here so that if some other port - * writes chars before the current buffer has been, then we write them - * first them do the new ports. - */ - -static int stli_putchar(struct tty_struct *tty, unsigned char ch) -{ - if (tty != stli_txcooktty) { - if (stli_txcooktty != NULL) - stli_flushchars(stli_txcooktty); - stli_txcooktty = tty; - } - - stli_txcookbuf[stli_txcooksize++] = ch; - return 0; -} - -/*****************************************************************************/ - -/* - * Transfer characters from the local TX cooking buffer to the board. - * We sort of ignore the tty that gets passed in here. We rely on the - * info stored with the TX cook buffer to tell us which port to flush - * the data on. In any case we clean out the TX cook buffer, for re-use - * by someone else. - */ - -static void stli_flushchars(struct tty_struct *tty) -{ - cdkhdr_t __iomem *hdrp; - unsigned char __iomem *bits; - cdkasy_t __iomem *ap; - struct tty_struct *cooktty; - struct stliport *portp; - struct stlibrd *brdp; - unsigned int len, stlen, head, tail, size, count, cooksize; - unsigned char *buf; - unsigned char __iomem *shbuf; - unsigned long flags; - - cooksize = stli_txcooksize; - cooktty = stli_txcooktty; - stli_txcooksize = 0; - stli_txcookrealsize = 0; - stli_txcooktty = NULL; - - if (cooktty == NULL) - return; - if (tty != cooktty) - tty = cooktty; - if (cooksize == 0) - return; - - portp = tty->driver_data; - if (portp == NULL) - return; - if (portp->brdnr >= stli_nrbrds) - return; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return; - - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - - ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); - head = (unsigned int) readw(&ap->txq.head); - tail = (unsigned int) readw(&ap->txq.tail); - if (tail != ((unsigned int) readw(&ap->txq.tail))) - tail = (unsigned int) readw(&ap->txq.tail); - size = portp->txsize; - if (head >= tail) { - len = size - (head - tail) - 1; - stlen = size - head; - } else { - len = tail - head - 1; - stlen = len; - } - - len = min(len, cooksize); - count = 0; - shbuf = EBRDGETMEMPTR(brdp, portp->txoffset); - buf = stli_txcookbuf; - - while (len > 0) { - stlen = min(len, stlen); - memcpy_toio(shbuf + head, buf, stlen); - buf += stlen; - len -= stlen; - count += stlen; - head += stlen; - if (head >= size) { - head = 0; - stlen = tail; - } - } - - ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); - writew(head, &ap->txq.head); - - if (test_bit(ST_TXBUSY, &portp->state)) { - if (readl(&ap->changed.data) & DT_TXEMPTY) - writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data); - } - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + - portp->portidx; - writeb(readb(bits) | portp->portbit, bits); - set_bit(ST_TXBUSY, &portp->state); - - EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -static int stli_writeroom(struct tty_struct *tty) -{ - cdkasyrq_t __iomem *rp; - struct stliport *portp; - struct stlibrd *brdp; - unsigned int head, tail, len; - unsigned long flags; - - if (tty == stli_txcooktty) { - if (stli_txcookrealsize != 0) { - len = stli_txcookrealsize - stli_txcooksize; - return len; - } - } - - portp = tty->driver_data; - if (portp == NULL) - return 0; - if (portp->brdnr >= stli_nrbrds) - return 0; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return 0; - - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq; - head = (unsigned int) readw(&rp->head); - tail = (unsigned int) readw(&rp->tail); - if (tail != ((unsigned int) readw(&rp->tail))) - tail = (unsigned int) readw(&rp->tail); - len = (head >= tail) ? (portp->txsize - (head - tail)) : (tail - head); - len--; - EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); - - if (tty == stli_txcooktty) { - stli_txcookrealsize = len; - len -= stli_txcooksize; - } - return len; -} - -/*****************************************************************************/ - -/* - * Return the number of characters in the transmit buffer. Normally we - * will return the number of chars in the shared memory ring queue. - * We need to kludge around the case where the shared memory buffer is - * empty but not all characters have drained yet, for this case just - * return that there is 1 character in the buffer! - */ - -static int stli_charsinbuffer(struct tty_struct *tty) -{ - cdkasyrq_t __iomem *rp; - struct stliport *portp; - struct stlibrd *brdp; - unsigned int head, tail, len; - unsigned long flags; - - if (tty == stli_txcooktty) - stli_flushchars(tty); - portp = tty->driver_data; - if (portp == NULL) - return 0; - if (portp->brdnr >= stli_nrbrds) - return 0; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return 0; - - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq; - head = (unsigned int) readw(&rp->head); - tail = (unsigned int) readw(&rp->tail); - if (tail != ((unsigned int) readw(&rp->tail))) - tail = (unsigned int) readw(&rp->tail); - len = (head >= tail) ? (head - tail) : (portp->txsize - (tail - head)); - if ((len == 0) && test_bit(ST_TXBUSY, &portp->state)) - len = 1; - EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); - - return len; -} - -/*****************************************************************************/ - -/* - * Generate the serial struct info. - */ - -static int stli_getserial(struct stliport *portp, struct serial_struct __user *sp) -{ - struct serial_struct sio; - struct stlibrd *brdp; - - memset(&sio, 0, sizeof(struct serial_struct)); - sio.type = PORT_UNKNOWN; - sio.line = portp->portnr; - sio.irq = 0; - sio.flags = portp->port.flags; - sio.baud_base = portp->baud_base; - sio.close_delay = portp->port.close_delay; - sio.closing_wait = portp->closing_wait; - sio.custom_divisor = portp->custom_divisor; - sio.xmit_fifo_size = 0; - sio.hub6 = 0; - - brdp = stli_brds[portp->brdnr]; - if (brdp != NULL) - sio.port = brdp->iobase; - - return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? - -EFAULT : 0; -} - -/*****************************************************************************/ - -/* - * Set port according to the serial struct info. - * At this point we do not do any auto-configure stuff, so we will - * just quietly ignore any requests to change irq, etc. - */ - -static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *sp) -{ - struct serial_struct sio; - int rc; - struct stliport *portp = tty->driver_data; - - if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) - return -EFAULT; - if (!capable(CAP_SYS_ADMIN)) { - if ((sio.baud_base != portp->baud_base) || - (sio.close_delay != portp->port.close_delay) || - ((sio.flags & ~ASYNC_USR_MASK) != - (portp->port.flags & ~ASYNC_USR_MASK))) - return -EPERM; - } - - portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) | - (sio.flags & ASYNC_USR_MASK); - portp->baud_base = sio.baud_base; - portp->port.close_delay = sio.close_delay; - portp->closing_wait = sio.closing_wait; - portp->custom_divisor = sio.custom_divisor; - - if ((rc = stli_setport(tty)) < 0) - return rc; - return 0; -} - -/*****************************************************************************/ - -static int stli_tiocmget(struct tty_struct *tty) -{ - struct stliport *portp = tty->driver_data; - struct stlibrd *brdp; - int rc; - - if (portp == NULL) - return -ENODEV; - if (portp->brdnr >= stli_nrbrds) - return 0; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return 0; - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - - if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, - &portp->asig, sizeof(asysigs_t), 1)) < 0) - return rc; - - return stli_mktiocm(portp->asig.sigvalue); -} - -static int stli_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct stliport *portp = tty->driver_data; - struct stlibrd *brdp; - int rts = -1, dtr = -1; - - if (portp == NULL) - return -ENODEV; - if (portp->brdnr >= stli_nrbrds) - return 0; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return 0; - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - - if (set & TIOCM_RTS) - rts = 1; - if (set & TIOCM_DTR) - dtr = 1; - if (clear & TIOCM_RTS) - rts = 0; - if (clear & TIOCM_DTR) - dtr = 0; - - stli_mkasysigs(&portp->asig, dtr, rts); - - return stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, - sizeof(asysigs_t), 0); -} - -static int stli_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) -{ - struct stliport *portp; - struct stlibrd *brdp; - int rc; - void __user *argp = (void __user *)arg; - - portp = tty->driver_data; - if (portp == NULL) - return -ENODEV; - if (portp->brdnr >= stli_nrbrds) - return 0; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return 0; - - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) { - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - } - - rc = 0; - - switch (cmd) { - case TIOCGSERIAL: - rc = stli_getserial(portp, argp); - break; - case TIOCSSERIAL: - rc = stli_setserial(tty, argp); - break; - case STL_GETPFLAG: - rc = put_user(portp->pflag, (unsigned __user *)argp); - break; - case STL_SETPFLAG: - if ((rc = get_user(portp->pflag, (unsigned __user *)argp)) == 0) - stli_setport(tty); - break; - case COM_GETPORTSTATS: - rc = stli_getportstats(tty, portp, argp); - break; - case COM_CLRPORTSTATS: - rc = stli_clrportstats(portp, argp); - break; - case TIOCSERCONFIG: - case TIOCSERGWILD: - case TIOCSERSWILD: - case TIOCSERGETLSR: - case TIOCSERGSTRUCT: - case TIOCSERGETMULTI: - case TIOCSERSETMULTI: - default: - rc = -ENOIOCTLCMD; - break; - } - - return rc; -} - -/*****************************************************************************/ - -/* - * This routine assumes that we have user context and can sleep. - * Looks like it is true for the current ttys implementation..!! - */ - -static void stli_settermios(struct tty_struct *tty, struct ktermios *old) -{ - struct stliport *portp; - struct stlibrd *brdp; - struct ktermios *tiosp; - asyport_t aport; - - portp = tty->driver_data; - if (portp == NULL) - return; - if (portp->brdnr >= stli_nrbrds) - return; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return; - - tiosp = tty->termios; - - stli_mkasyport(tty, portp, &aport, tiosp); - stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0); - stli_mkasysigs(&portp->asig, ((tiosp->c_cflag & CBAUD) ? 1 : 0), -1); - stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, - sizeof(asysigs_t), 0); - if ((old->c_cflag & CRTSCTS) && ((tiosp->c_cflag & CRTSCTS) == 0)) - tty->hw_stopped = 0; - if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL)) - wake_up_interruptible(&portp->port.open_wait); -} - -/*****************************************************************************/ - -/* - * Attempt to flow control who ever is sending us data. We won't really - * do any flow control action here. We can't directly, and even if we - * wanted to we would have to send a command to the slave. The slave - * knows how to flow control, and will do so when its buffers reach its - * internal high water marks. So what we will do is set a local state - * bit that will stop us sending any RX data up from the poll routine - * (which is the place where RX data from the slave is handled). - */ - -static void stli_throttle(struct tty_struct *tty) -{ - struct stliport *portp = tty->driver_data; - if (portp == NULL) - return; - set_bit(ST_RXSTOP, &portp->state); -} - -/*****************************************************************************/ - -/* - * Unflow control the device sending us data... That means that all - * we have to do is clear the RXSTOP state bit. The next poll call - * will then be able to pass the RX data back up. - */ - -static void stli_unthrottle(struct tty_struct *tty) -{ - struct stliport *portp = tty->driver_data; - if (portp == NULL) - return; - clear_bit(ST_RXSTOP, &portp->state); -} - -/*****************************************************************************/ - -/* - * Stop the transmitter. - */ - -static void stli_stop(struct tty_struct *tty) -{ -} - -/*****************************************************************************/ - -/* - * Start the transmitter again. - */ - -static void stli_start(struct tty_struct *tty) -{ -} - -/*****************************************************************************/ - - -/* - * Hangup this port. This is pretty much like closing the port, only - * a little more brutal. No waiting for data to drain. Shutdown the - * port and maybe drop signals. This is rather tricky really. We want - * to close the port as well. - */ - -static void stli_hangup(struct tty_struct *tty) -{ - struct stliport *portp = tty->driver_data; - tty_port_hangup(&portp->port); -} - -/*****************************************************************************/ - -/* - * Flush characters from the lower buffer. We may not have user context - * so we cannot sleep waiting for it to complete. Also we need to check - * if there is chars for this port in the TX cook buffer, and flush them - * as well. - */ - -static void stli_flushbuffer(struct tty_struct *tty) -{ - struct stliport *portp; - struct stlibrd *brdp; - unsigned long ftype, flags; - - portp = tty->driver_data; - if (portp == NULL) - return; - if (portp->brdnr >= stli_nrbrds) - return; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return; - - spin_lock_irqsave(&brd_lock, flags); - if (tty == stli_txcooktty) { - stli_txcooktty = NULL; - stli_txcooksize = 0; - stli_txcookrealsize = 0; - } - if (test_bit(ST_CMDING, &portp->state)) { - set_bit(ST_DOFLUSHTX, &portp->state); - } else { - ftype = FLUSHTX; - if (test_bit(ST_DOFLUSHRX, &portp->state)) { - ftype |= FLUSHRX; - clear_bit(ST_DOFLUSHRX, &portp->state); - } - __stli_sendcmd(brdp, portp, A_FLUSH, &ftype, sizeof(u32), 0); - } - spin_unlock_irqrestore(&brd_lock, flags); - tty_wakeup(tty); -} - -/*****************************************************************************/ - -static int stli_breakctl(struct tty_struct *tty, int state) -{ - struct stlibrd *brdp; - struct stliport *portp; - long arg; - - portp = tty->driver_data; - if (portp == NULL) - return -EINVAL; - if (portp->brdnr >= stli_nrbrds) - return -EINVAL; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return -EINVAL; - - arg = (state == -1) ? BREAKON : BREAKOFF; - stli_cmdwait(brdp, portp, A_BREAK, &arg, sizeof(long), 0); - return 0; -} - -/*****************************************************************************/ - -static void stli_waituntilsent(struct tty_struct *tty, int timeout) -{ - struct stliport *portp; - unsigned long tend; - - portp = tty->driver_data; - if (portp == NULL) - return; - - if (timeout == 0) - timeout = HZ; - tend = jiffies + timeout; - - while (test_bit(ST_TXBUSY, &portp->state)) { - if (signal_pending(current)) - break; - msleep_interruptible(20); - if (time_after_eq(jiffies, tend)) - break; - } -} - -/*****************************************************************************/ - -static void stli_sendxchar(struct tty_struct *tty, char ch) -{ - struct stlibrd *brdp; - struct stliport *portp; - asyctrl_t actrl; - - portp = tty->driver_data; - if (portp == NULL) - return; - if (portp->brdnr >= stli_nrbrds) - return; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return; - - memset(&actrl, 0, sizeof(asyctrl_t)); - if (ch == STOP_CHAR(tty)) { - actrl.rxctrl = CT_STOPFLOW; - } else if (ch == START_CHAR(tty)) { - actrl.rxctrl = CT_STARTFLOW; - } else { - actrl.txctrl = CT_SENDCHR; - actrl.tximdch = ch; - } - stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0); -} - -static void stli_portinfo(struct seq_file *m, struct stlibrd *brdp, struct stliport *portp, int portnr) -{ - char *uart; - int rc; - - rc = stli_portcmdstats(NULL, portp); - - uart = "UNKNOWN"; - if (test_bit(BST_STARTED, &brdp->state)) { - switch (stli_comstats.hwid) { - case 0: uart = "2681"; break; - case 1: uart = "SC26198"; break; - default:uart = "CD1400"; break; - } - } - seq_printf(m, "%d: uart:%s ", portnr, uart); - - if (test_bit(BST_STARTED, &brdp->state) && rc >= 0) { - char sep; - - seq_printf(m, "tx:%d rx:%d", (int) stli_comstats.txtotal, - (int) stli_comstats.rxtotal); - - if (stli_comstats.rxframing) - seq_printf(m, " fe:%d", - (int) stli_comstats.rxframing); - if (stli_comstats.rxparity) - seq_printf(m, " pe:%d", - (int) stli_comstats.rxparity); - if (stli_comstats.rxbreaks) - seq_printf(m, " brk:%d", - (int) stli_comstats.rxbreaks); - if (stli_comstats.rxoverrun) - seq_printf(m, " oe:%d", - (int) stli_comstats.rxoverrun); - - sep = ' '; - if (stli_comstats.signals & TIOCM_RTS) { - seq_printf(m, "%c%s", sep, "RTS"); - sep = '|'; - } - if (stli_comstats.signals & TIOCM_CTS) { - seq_printf(m, "%c%s", sep, "CTS"); - sep = '|'; - } - if (stli_comstats.signals & TIOCM_DTR) { - seq_printf(m, "%c%s", sep, "DTR"); - sep = '|'; - } - if (stli_comstats.signals & TIOCM_CD) { - seq_printf(m, "%c%s", sep, "DCD"); - sep = '|'; - } - if (stli_comstats.signals & TIOCM_DSR) { - seq_printf(m, "%c%s", sep, "DSR"); - sep = '|'; - } - } - seq_putc(m, '\n'); -} - -/*****************************************************************************/ - -/* - * Port info, read from the /proc file system. - */ - -static int stli_proc_show(struct seq_file *m, void *v) -{ - struct stlibrd *brdp; - struct stliport *portp; - unsigned int brdnr, portnr, totalport; - - totalport = 0; - - seq_printf(m, "%s: version %s\n", stli_drvtitle, stli_drvversion); - -/* - * We scan through for each board, panel and port. The offset is - * calculated on the fly, and irrelevant ports are skipped. - */ - for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) { - brdp = stli_brds[brdnr]; - if (brdp == NULL) - continue; - if (brdp->state == 0) - continue; - - totalport = brdnr * STL_MAXPORTS; - for (portnr = 0; (portnr < brdp->nrports); portnr++, - totalport++) { - portp = brdp->ports[portnr]; - if (portp == NULL) - continue; - stli_portinfo(m, brdp, portp, totalport); - } - } - return 0; -} - -static int stli_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, stli_proc_show, NULL); -} - -static const struct file_operations stli_proc_fops = { - .owner = THIS_MODULE, - .open = stli_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/*****************************************************************************/ - -/* - * Generic send command routine. This will send a message to the slave, - * of the specified type with the specified argument. Must be very - * careful of data that will be copied out from shared memory - - * containing command results. The command completion is all done from - * a poll routine that does not have user context. Therefore you cannot - * copy back directly into user space, or to the kernel stack of a - * process. This routine does not sleep, so can be called from anywhere. - * - * The caller must hold the brd_lock (see also stli_sendcmd the usual - * entry point) - */ - -static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback) -{ - cdkhdr_t __iomem *hdrp; - cdkctrl_t __iomem *cp; - unsigned char __iomem *bits; - - if (test_bit(ST_CMDING, &portp->state)) { - printk(KERN_ERR "istallion: command already busy, cmd=%x!\n", - (int) cmd); - return; - } - - EBRDENABLE(brdp); - cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; - if (size > 0) { - memcpy_toio((void __iomem *) &(cp->args[0]), arg, size); - if (copyback) { - portp->argp = arg; - portp->argsize = size; - } - } - writel(0, &cp->status); - writel(cmd, &cp->cmd); - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + - portp->portidx; - writeb(readb(bits) | portp->portbit, bits); - set_bit(ST_CMDING, &portp->state); - EBRDDISABLE(brdp); -} - -static void stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback) -{ - unsigned long flags; - - spin_lock_irqsave(&brd_lock, flags); - __stli_sendcmd(brdp, portp, cmd, arg, size, copyback); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Read data from shared memory. This assumes that the shared memory - * is enabled and that interrupts are off. Basically we just empty out - * the shared memory buffer into the tty buffer. Must be careful to - * handle the case where we fill up the tty buffer, but still have - * more chars to unload. - */ - -static void stli_read(struct stlibrd *brdp, struct stliport *portp) -{ - cdkasyrq_t __iomem *rp; - char __iomem *shbuf; - struct tty_struct *tty; - unsigned int head, tail, size; - unsigned int len, stlen; - - if (test_bit(ST_RXSTOP, &portp->state)) - return; - tty = tty_port_tty_get(&portp->port); - if (tty == NULL) - return; - - rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq; - head = (unsigned int) readw(&rp->head); - if (head != ((unsigned int) readw(&rp->head))) - head = (unsigned int) readw(&rp->head); - tail = (unsigned int) readw(&rp->tail); - size = portp->rxsize; - if (head >= tail) { - len = head - tail; - stlen = len; - } else { - len = size - (tail - head); - stlen = size - tail; - } - - len = tty_buffer_request_room(tty, len); - - shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->rxoffset); - - while (len > 0) { - unsigned char *cptr; - - stlen = min(len, stlen); - tty_prepare_flip_string(tty, &cptr, stlen); - memcpy_fromio(cptr, shbuf + tail, stlen); - len -= stlen; - tail += stlen; - if (tail >= size) { - tail = 0; - stlen = head; - } - } - rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq; - writew(tail, &rp->tail); - - if (head != tail) - set_bit(ST_RXING, &portp->state); - - tty_schedule_flip(tty); - tty_kref_put(tty); -} - -/*****************************************************************************/ - -/* - * Set up and carry out any delayed commands. There is only a small set - * of slave commands that can be done "off-level". So it is not too - * difficult to deal with them here. - */ - -static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp) -{ - int cmd; - - if (test_bit(ST_DOSIGS, &portp->state)) { - if (test_bit(ST_DOFLUSHTX, &portp->state) && - test_bit(ST_DOFLUSHRX, &portp->state)) - cmd = A_SETSIGNALSF; - else if (test_bit(ST_DOFLUSHTX, &portp->state)) - cmd = A_SETSIGNALSFTX; - else if (test_bit(ST_DOFLUSHRX, &portp->state)) - cmd = A_SETSIGNALSFRX; - else - cmd = A_SETSIGNALS; - clear_bit(ST_DOFLUSHTX, &portp->state); - clear_bit(ST_DOFLUSHRX, &portp->state); - clear_bit(ST_DOSIGS, &portp->state); - memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &portp->asig, - sizeof(asysigs_t)); - writel(0, &cp->status); - writel(cmd, &cp->cmd); - set_bit(ST_CMDING, &portp->state); - } else if (test_bit(ST_DOFLUSHTX, &portp->state) || - test_bit(ST_DOFLUSHRX, &portp->state)) { - cmd = ((test_bit(ST_DOFLUSHTX, &portp->state)) ? FLUSHTX : 0); - cmd |= ((test_bit(ST_DOFLUSHRX, &portp->state)) ? FLUSHRX : 0); - clear_bit(ST_DOFLUSHTX, &portp->state); - clear_bit(ST_DOFLUSHRX, &portp->state); - memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &cmd, sizeof(int)); - writel(0, &cp->status); - writel(A_FLUSH, &cp->cmd); - set_bit(ST_CMDING, &portp->state); - } -} - -/*****************************************************************************/ - -/* - * Host command service checking. This handles commands or messages - * coming from the slave to the host. Must have board shared memory - * enabled and interrupts off when called. Notice that by servicing the - * read data last we don't need to change the shared memory pointer - * during processing (which is a slow IO operation). - * Return value indicates if this port is still awaiting actions from - * the slave (like open, command, or even TX data being sent). If 0 - * then port is still busy, otherwise no longer busy. - */ - -static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp) -{ - cdkasy_t __iomem *ap; - cdkctrl_t __iomem *cp; - struct tty_struct *tty; - asynotify_t nt; - unsigned long oldsigs; - int rc, donerx; - - ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); - cp = &ap->ctrl; - -/* - * Check if we are waiting for an open completion message. - */ - if (test_bit(ST_OPENING, &portp->state)) { - rc = readl(&cp->openarg); - if (readb(&cp->open) == 0 && rc != 0) { - if (rc > 0) - rc--; - writel(0, &cp->openarg); - portp->rc = rc; - clear_bit(ST_OPENING, &portp->state); - wake_up_interruptible(&portp->raw_wait); - } - } - -/* - * Check if we are waiting for a close completion message. - */ - if (test_bit(ST_CLOSING, &portp->state)) { - rc = (int) readl(&cp->closearg); - if (readb(&cp->close) == 0 && rc != 0) { - if (rc > 0) - rc--; - writel(0, &cp->closearg); - portp->rc = rc; - clear_bit(ST_CLOSING, &portp->state); - wake_up_interruptible(&portp->raw_wait); - } - } - -/* - * Check if we are waiting for a command completion message. We may - * need to copy out the command results associated with this command. - */ - if (test_bit(ST_CMDING, &portp->state)) { - rc = readl(&cp->status); - if (readl(&cp->cmd) == 0 && rc != 0) { - if (rc > 0) - rc--; - if (portp->argp != NULL) { - memcpy_fromio(portp->argp, (void __iomem *) &(cp->args[0]), - portp->argsize); - portp->argp = NULL; - } - writel(0, &cp->status); - portp->rc = rc; - clear_bit(ST_CMDING, &portp->state); - stli_dodelaycmd(portp, cp); - wake_up_interruptible(&portp->raw_wait); - } - } - -/* - * Check for any notification messages ready. This includes lots of - * different types of events - RX chars ready, RX break received, - * TX data low or empty in the slave, modem signals changed state. - */ - donerx = 0; - - if (ap->notify) { - nt = ap->changed; - ap->notify = 0; - tty = tty_port_tty_get(&portp->port); - - if (nt.signal & SG_DCD) { - oldsigs = portp->sigs; - portp->sigs = stli_mktiocm(nt.sigvalue); - clear_bit(ST_GETSIGS, &portp->state); - if ((portp->sigs & TIOCM_CD) && - ((oldsigs & TIOCM_CD) == 0)) - wake_up_interruptible(&portp->port.open_wait); - if ((oldsigs & TIOCM_CD) && - ((portp->sigs & TIOCM_CD) == 0)) { - if (portp->port.flags & ASYNC_CHECK_CD) { - if (tty) - tty_hangup(tty); - } - } - } - - if (nt.data & DT_TXEMPTY) - clear_bit(ST_TXBUSY, &portp->state); - if (nt.data & (DT_TXEMPTY | DT_TXLOW)) { - if (tty != NULL) { - tty_wakeup(tty); - EBRDENABLE(brdp); - } - } - - if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) { - if (tty != NULL) { - tty_insert_flip_char(tty, 0, TTY_BREAK); - if (portp->port.flags & ASYNC_SAK) { - do_SAK(tty); - EBRDENABLE(brdp); - } - tty_schedule_flip(tty); - } - } - tty_kref_put(tty); - - if (nt.data & DT_RXBUSY) { - donerx++; - stli_read(brdp, portp); - } - } - -/* - * It might seem odd that we are checking for more RX chars here. - * But, we need to handle the case where the tty buffer was previously - * filled, but we had more characters to pass up. The slave will not - * send any more RX notify messages until the RX buffer has been emptied. - * But it will leave the service bits on (since the buffer is not empty). - * So from here we can try to process more RX chars. - */ - if ((!donerx) && test_bit(ST_RXING, &portp->state)) { - clear_bit(ST_RXING, &portp->state); - stli_read(brdp, portp); - } - - return((test_bit(ST_OPENING, &portp->state) || - test_bit(ST_CLOSING, &portp->state) || - test_bit(ST_CMDING, &portp->state) || - test_bit(ST_TXBUSY, &portp->state) || - test_bit(ST_RXING, &portp->state)) ? 0 : 1); -} - -/*****************************************************************************/ - -/* - * Service all ports on a particular board. Assumes that the boards - * shared memory is enabled, and that the page pointer is pointed - * at the cdk header structure. - */ - -static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp) -{ - struct stliport *portp; - unsigned char hostbits[(STL_MAXCHANS / 8) + 1]; - unsigned char slavebits[(STL_MAXCHANS / 8) + 1]; - unsigned char __iomem *slavep; - int bitpos, bitat, bitsize; - int channr, nrdevs, slavebitchange; - - bitsize = brdp->bitsize; - nrdevs = brdp->nrdevs; - -/* - * Check if slave wants any service. Basically we try to do as - * little work as possible here. There are 2 levels of service - * bits. So if there is nothing to do we bail early. We check - * 8 service bits at a time in the inner loop, so we can bypass - * the lot if none of them want service. - */ - memcpy_fromio(&hostbits[0], (((unsigned char __iomem *) hdrp) + brdp->hostoffset), - bitsize); - - memset(&slavebits[0], 0, bitsize); - slavebitchange = 0; - - for (bitpos = 0; (bitpos < bitsize); bitpos++) { - if (hostbits[bitpos] == 0) - continue; - channr = bitpos * 8; - for (bitat = 0x1; (channr < nrdevs); channr++, bitat <<= 1) { - if (hostbits[bitpos] & bitat) { - portp = brdp->ports[(channr - 1)]; - if (stli_hostcmd(brdp, portp)) { - slavebitchange++; - slavebits[bitpos] |= bitat; - } - } - } - } - -/* - * If any of the ports are no longer busy then update them in the - * slave request bits. We need to do this after, since a host port - * service may initiate more slave requests. - */ - if (slavebitchange) { - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - slavep = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset; - for (bitpos = 0; (bitpos < bitsize); bitpos++) { - if (readb(slavebits + bitpos)) - writeb(readb(slavep + bitpos) & ~slavebits[bitpos], slavebits + bitpos); - } - } -} - -/*****************************************************************************/ - -/* - * Driver poll routine. This routine polls the boards in use and passes - * messages back up to host when necessary. This is actually very - * CPU efficient, since we will always have the kernel poll clock, it - * adds only a few cycles when idle (since board service can be - * determined very easily), but when loaded generates no interrupts - * (with their expensive associated context change). - */ - -static void stli_poll(unsigned long arg) -{ - cdkhdr_t __iomem *hdrp; - struct stlibrd *brdp; - unsigned int brdnr; - - mod_timer(&stli_timerlist, STLI_TIMEOUT); - -/* - * Check each board and do any servicing required. - */ - for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) { - brdp = stli_brds[brdnr]; - if (brdp == NULL) - continue; - if (!test_bit(BST_STARTED, &brdp->state)) - continue; - - spin_lock(&brd_lock); - EBRDENABLE(brdp); - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - if (readb(&hdrp->hostreq)) - stli_brdpoll(brdp, hdrp); - EBRDDISABLE(brdp); - spin_unlock(&brd_lock); - } -} - -/*****************************************************************************/ - -/* - * Translate the termios settings into the port setting structure of - * the slave. - */ - -static void stli_mkasyport(struct tty_struct *tty, struct stliport *portp, - asyport_t *pp, struct ktermios *tiosp) -{ - memset(pp, 0, sizeof(asyport_t)); - -/* - * Start of by setting the baud, char size, parity and stop bit info. - */ - pp->baudout = tty_get_baud_rate(tty); - if ((tiosp->c_cflag & CBAUD) == B38400) { - if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - pp->baudout = 57600; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - pp->baudout = 115200; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - pp->baudout = 230400; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - pp->baudout = 460800; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) - pp->baudout = (portp->baud_base / portp->custom_divisor); - } - if (pp->baudout > STL_MAXBAUD) - pp->baudout = STL_MAXBAUD; - pp->baudin = pp->baudout; - - switch (tiosp->c_cflag & CSIZE) { - case CS5: - pp->csize = 5; - break; - case CS6: - pp->csize = 6; - break; - case CS7: - pp->csize = 7; - break; - default: - pp->csize = 8; - break; - } - - if (tiosp->c_cflag & CSTOPB) - pp->stopbs = PT_STOP2; - else - pp->stopbs = PT_STOP1; - - if (tiosp->c_cflag & PARENB) { - if (tiosp->c_cflag & PARODD) - pp->parity = PT_ODDPARITY; - else - pp->parity = PT_EVENPARITY; - } else { - pp->parity = PT_NOPARITY; - } - -/* - * Set up any flow control options enabled. - */ - if (tiosp->c_iflag & IXON) { - pp->flow |= F_IXON; - if (tiosp->c_iflag & IXANY) - pp->flow |= F_IXANY; - } - if (tiosp->c_cflag & CRTSCTS) - pp->flow |= (F_RTSFLOW | F_CTSFLOW); - - pp->startin = tiosp->c_cc[VSTART]; - pp->stopin = tiosp->c_cc[VSTOP]; - pp->startout = tiosp->c_cc[VSTART]; - pp->stopout = tiosp->c_cc[VSTOP]; - -/* - * Set up the RX char marking mask with those RX error types we must - * catch. We can get the slave to help us out a little here, it will - * ignore parity errors and breaks for us, and mark parity errors in - * the data stream. - */ - if (tiosp->c_iflag & IGNPAR) - pp->iflag |= FI_IGNRXERRS; - if (tiosp->c_iflag & IGNBRK) - pp->iflag |= FI_IGNBREAK; - - portp->rxmarkmsk = 0; - if (tiosp->c_iflag & (INPCK | PARMRK)) - pp->iflag |= FI_1MARKRXERRS; - if (tiosp->c_iflag & BRKINT) - portp->rxmarkmsk |= BRKINT; - -/* - * Set up clocal processing as required. - */ - if (tiosp->c_cflag & CLOCAL) - portp->port.flags &= ~ASYNC_CHECK_CD; - else - portp->port.flags |= ASYNC_CHECK_CD; - -/* - * Transfer any persistent flags into the asyport structure. - */ - pp->pflag = (portp->pflag & 0xffff); - pp->vmin = (portp->pflag & P_RXIMIN) ? 1 : 0; - pp->vtime = (portp->pflag & P_RXITIME) ? 1 : 0; - pp->cc[1] = (portp->pflag & P_RXTHOLD) ? 1 : 0; -} - -/*****************************************************************************/ - -/* - * Construct a slave signals structure for setting the DTR and RTS - * signals as specified. - */ - -static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts) -{ - memset(sp, 0, sizeof(asysigs_t)); - if (dtr >= 0) { - sp->signal |= SG_DTR; - sp->sigvalue |= ((dtr > 0) ? SG_DTR : 0); - } - if (rts >= 0) { - sp->signal |= SG_RTS; - sp->sigvalue |= ((rts > 0) ? SG_RTS : 0); - } -} - -/*****************************************************************************/ - -/* - * Convert the signals returned from the slave into a local TIOCM type - * signals value. We keep them locally in TIOCM format. - */ - -static long stli_mktiocm(unsigned long sigvalue) -{ - long tiocm = 0; - tiocm |= ((sigvalue & SG_DCD) ? TIOCM_CD : 0); - tiocm |= ((sigvalue & SG_CTS) ? TIOCM_CTS : 0); - tiocm |= ((sigvalue & SG_RI) ? TIOCM_RI : 0); - tiocm |= ((sigvalue & SG_DSR) ? TIOCM_DSR : 0); - tiocm |= ((sigvalue & SG_DTR) ? TIOCM_DTR : 0); - tiocm |= ((sigvalue & SG_RTS) ? TIOCM_RTS : 0); - return(tiocm); -} - -/*****************************************************************************/ - -/* - * All panels and ports actually attached have been worked out. All - * we need to do here is set up the appropriate per port data structures. - */ - -static int stli_initports(struct stlibrd *brdp) -{ - struct stliport *portp; - unsigned int i, panelnr, panelport; - - for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) { - portp = kzalloc(sizeof(struct stliport), GFP_KERNEL); - if (!portp) { - printk(KERN_WARNING "istallion: failed to allocate port structure\n"); - continue; - } - tty_port_init(&portp->port); - portp->port.ops = &stli_port_ops; - portp->magic = STLI_PORTMAGIC; - portp->portnr = i; - portp->brdnr = brdp->brdnr; - portp->panelnr = panelnr; - portp->baud_base = STL_BAUDBASE; - portp->port.close_delay = STL_CLOSEDELAY; - portp->closing_wait = 30 * HZ; - init_waitqueue_head(&portp->port.open_wait); - init_waitqueue_head(&portp->port.close_wait); - init_waitqueue_head(&portp->raw_wait); - panelport++; - if (panelport >= brdp->panels[panelnr]) { - panelport = 0; - panelnr++; - } - brdp->ports[i] = portp; - } - - return 0; -} - -/*****************************************************************************/ - -/* - * All the following routines are board specific hardware operations. - */ - -static void stli_ecpinit(struct stlibrd *brdp) -{ - unsigned long memconf; - - outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR)); - udelay(10); - outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); - udelay(100); - - memconf = (brdp->memaddr & ECP_ATADDRMASK) >> ECP_ATADDRSHFT; - outb(memconf, (brdp->iobase + ECP_ATMEMAR)); -} - -/*****************************************************************************/ - -static void stli_ecpenable(struct stlibrd *brdp) -{ - outb(ECP_ATENABLE, (brdp->iobase + ECP_ATCONFR)); -} - -/*****************************************************************************/ - -static void stli_ecpdisable(struct stlibrd *brdp) -{ - outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); -} - -/*****************************************************************************/ - -static void __iomem *stli_ecpgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) -{ - void __iomem *ptr; - unsigned char val; - - if (offset > brdp->memsize) { - printk(KERN_ERR "istallion: shared memory pointer=%x out of " - "range at line=%d(%d), brd=%d\n", - (int) offset, line, __LINE__, brdp->brdnr); - ptr = NULL; - val = 0; - } else { - ptr = brdp->membase + (offset % ECP_ATPAGESIZE); - val = (unsigned char) (offset / ECP_ATPAGESIZE); - } - outb(val, (brdp->iobase + ECP_ATMEMPR)); - return(ptr); -} - -/*****************************************************************************/ - -static void stli_ecpreset(struct stlibrd *brdp) -{ - outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR)); - udelay(10); - outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); - udelay(500); -} - -/*****************************************************************************/ - -static void stli_ecpintr(struct stlibrd *brdp) -{ - outb(0x1, brdp->iobase); -} - -/*****************************************************************************/ - -/* - * The following set of functions act on ECP EISA boards. - */ - -static void stli_ecpeiinit(struct stlibrd *brdp) -{ - unsigned long memconf; - - outb(0x1, (brdp->iobase + ECP_EIBRDENAB)); - outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR)); - udelay(10); - outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR)); - udelay(500); - - memconf = (brdp->memaddr & ECP_EIADDRMASKL) >> ECP_EIADDRSHFTL; - outb(memconf, (brdp->iobase + ECP_EIMEMARL)); - memconf = (brdp->memaddr & ECP_EIADDRMASKH) >> ECP_EIADDRSHFTH; - outb(memconf, (brdp->iobase + ECP_EIMEMARH)); -} - -/*****************************************************************************/ - -static void stli_ecpeienable(struct stlibrd *brdp) -{ - outb(ECP_EIENABLE, (brdp->iobase + ECP_EICONFR)); -} - -/*****************************************************************************/ - -static void stli_ecpeidisable(struct stlibrd *brdp) -{ - outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR)); -} - -/*****************************************************************************/ - -static void __iomem *stli_ecpeigetmemptr(struct stlibrd *brdp, unsigned long offset, int line) -{ - void __iomem *ptr; - unsigned char val; - - if (offset > brdp->memsize) { - printk(KERN_ERR "istallion: shared memory pointer=%x out of " - "range at line=%d(%d), brd=%d\n", - (int) offset, line, __LINE__, brdp->brdnr); - ptr = NULL; - val = 0; - } else { - ptr = brdp->membase + (offset % ECP_EIPAGESIZE); - if (offset < ECP_EIPAGESIZE) - val = ECP_EIENABLE; - else - val = ECP_EIENABLE | 0x40; - } - outb(val, (brdp->iobase + ECP_EICONFR)); - return(ptr); -} - -/*****************************************************************************/ - -static void stli_ecpeireset(struct stlibrd *brdp) -{ - outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR)); - udelay(10); - outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR)); - udelay(500); -} - -/*****************************************************************************/ - -/* - * The following set of functions act on ECP MCA boards. - */ - -static void stli_ecpmcenable(struct stlibrd *brdp) -{ - outb(ECP_MCENABLE, (brdp->iobase + ECP_MCCONFR)); -} - -/*****************************************************************************/ - -static void stli_ecpmcdisable(struct stlibrd *brdp) -{ - outb(ECP_MCDISABLE, (brdp->iobase + ECP_MCCONFR)); -} - -/*****************************************************************************/ - -static void __iomem *stli_ecpmcgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) -{ - void __iomem *ptr; - unsigned char val; - - if (offset > brdp->memsize) { - printk(KERN_ERR "istallion: shared memory pointer=%x out of " - "range at line=%d(%d), brd=%d\n", - (int) offset, line, __LINE__, brdp->brdnr); - ptr = NULL; - val = 0; - } else { - ptr = brdp->membase + (offset % ECP_MCPAGESIZE); - val = ((unsigned char) (offset / ECP_MCPAGESIZE)) | ECP_MCENABLE; - } - outb(val, (brdp->iobase + ECP_MCCONFR)); - return(ptr); -} - -/*****************************************************************************/ - -static void stli_ecpmcreset(struct stlibrd *brdp) -{ - outb(ECP_MCSTOP, (brdp->iobase + ECP_MCCONFR)); - udelay(10); - outb(ECP_MCDISABLE, (brdp->iobase + ECP_MCCONFR)); - udelay(500); -} - -/*****************************************************************************/ - -/* - * The following set of functions act on ECP PCI boards. - */ - -static void stli_ecppciinit(struct stlibrd *brdp) -{ - outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR)); - udelay(10); - outb(0, (brdp->iobase + ECP_PCICONFR)); - udelay(500); -} - -/*****************************************************************************/ - -static void __iomem *stli_ecppcigetmemptr(struct stlibrd *brdp, unsigned long offset, int line) -{ - void __iomem *ptr; - unsigned char val; - - if (offset > brdp->memsize) { - printk(KERN_ERR "istallion: shared memory pointer=%x out of " - "range at line=%d(%d), board=%d\n", - (int) offset, line, __LINE__, brdp->brdnr); - ptr = NULL; - val = 0; - } else { - ptr = brdp->membase + (offset % ECP_PCIPAGESIZE); - val = (offset / ECP_PCIPAGESIZE) << 1; - } - outb(val, (brdp->iobase + ECP_PCICONFR)); - return(ptr); -} - -/*****************************************************************************/ - -static void stli_ecppcireset(struct stlibrd *brdp) -{ - outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR)); - udelay(10); - outb(0, (brdp->iobase + ECP_PCICONFR)); - udelay(500); -} - -/*****************************************************************************/ - -/* - * The following routines act on ONboards. - */ - -static void stli_onbinit(struct stlibrd *brdp) -{ - unsigned long memconf; - - outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR)); - udelay(10); - outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR)); - mdelay(1000); - - memconf = (brdp->memaddr & ONB_ATADDRMASK) >> ONB_ATADDRSHFT; - outb(memconf, (brdp->iobase + ONB_ATMEMAR)); - outb(0x1, brdp->iobase); - mdelay(1); -} - -/*****************************************************************************/ - -static void stli_onbenable(struct stlibrd *brdp) -{ - outb((brdp->enabval | ONB_ATENABLE), (brdp->iobase + ONB_ATCONFR)); -} - -/*****************************************************************************/ - -static void stli_onbdisable(struct stlibrd *brdp) -{ - outb((brdp->enabval | ONB_ATDISABLE), (brdp->iobase + ONB_ATCONFR)); -} - -/*****************************************************************************/ - -static void __iomem *stli_onbgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) -{ - void __iomem *ptr; - - if (offset > brdp->memsize) { - printk(KERN_ERR "istallion: shared memory pointer=%x out of " - "range at line=%d(%d), brd=%d\n", - (int) offset, line, __LINE__, brdp->brdnr); - ptr = NULL; - } else { - ptr = brdp->membase + (offset % ONB_ATPAGESIZE); - } - return(ptr); -} - -/*****************************************************************************/ - -static void stli_onbreset(struct stlibrd *brdp) -{ - outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR)); - udelay(10); - outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR)); - mdelay(1000); -} - -/*****************************************************************************/ - -/* - * The following routines act on ONboard EISA. - */ - -static void stli_onbeinit(struct stlibrd *brdp) -{ - unsigned long memconf; - - outb(0x1, (brdp->iobase + ONB_EIBRDENAB)); - outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); - udelay(10); - outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); - mdelay(1000); - - memconf = (brdp->memaddr & ONB_EIADDRMASKL) >> ONB_EIADDRSHFTL; - outb(memconf, (brdp->iobase + ONB_EIMEMARL)); - memconf = (brdp->memaddr & ONB_EIADDRMASKH) >> ONB_EIADDRSHFTH; - outb(memconf, (brdp->iobase + ONB_EIMEMARH)); - outb(0x1, brdp->iobase); - mdelay(1); -} - -/*****************************************************************************/ - -static void stli_onbeenable(struct stlibrd *brdp) -{ - outb(ONB_EIENABLE, (brdp->iobase + ONB_EICONFR)); -} - -/*****************************************************************************/ - -static void stli_onbedisable(struct stlibrd *brdp) -{ - outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); -} - -/*****************************************************************************/ - -static void __iomem *stli_onbegetmemptr(struct stlibrd *brdp, unsigned long offset, int line) -{ - void __iomem *ptr; - unsigned char val; - - if (offset > brdp->memsize) { - printk(KERN_ERR "istallion: shared memory pointer=%x out of " - "range at line=%d(%d), brd=%d\n", - (int) offset, line, __LINE__, brdp->brdnr); - ptr = NULL; - val = 0; - } else { - ptr = brdp->membase + (offset % ONB_EIPAGESIZE); - if (offset < ONB_EIPAGESIZE) - val = ONB_EIENABLE; - else - val = ONB_EIENABLE | 0x40; - } - outb(val, (brdp->iobase + ONB_EICONFR)); - return(ptr); -} - -/*****************************************************************************/ - -static void stli_onbereset(struct stlibrd *brdp) -{ - outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); - udelay(10); - outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); - mdelay(1000); -} - -/*****************************************************************************/ - -/* - * The following routines act on Brumby boards. - */ - -static void stli_bbyinit(struct stlibrd *brdp) -{ - outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); - udelay(10); - outb(0, (brdp->iobase + BBY_ATCONFR)); - mdelay(1000); - outb(0x1, brdp->iobase); - mdelay(1); -} - -/*****************************************************************************/ - -static void __iomem *stli_bbygetmemptr(struct stlibrd *brdp, unsigned long offset, int line) -{ - void __iomem *ptr; - unsigned char val; - - BUG_ON(offset > brdp->memsize); - - ptr = brdp->membase + (offset % BBY_PAGESIZE); - val = (unsigned char) (offset / BBY_PAGESIZE); - outb(val, (brdp->iobase + BBY_ATCONFR)); - return(ptr); -} - -/*****************************************************************************/ - -static void stli_bbyreset(struct stlibrd *brdp) -{ - outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); - udelay(10); - outb(0, (brdp->iobase + BBY_ATCONFR)); - mdelay(1000); -} - -/*****************************************************************************/ - -/* - * The following routines act on original old Stallion boards. - */ - -static void stli_stalinit(struct stlibrd *brdp) -{ - outb(0x1, brdp->iobase); - mdelay(1000); -} - -/*****************************************************************************/ - -static void __iomem *stli_stalgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) -{ - BUG_ON(offset > brdp->memsize); - return brdp->membase + (offset % STAL_PAGESIZE); -} - -/*****************************************************************************/ - -static void stli_stalreset(struct stlibrd *brdp) -{ - u32 __iomem *vecp; - - vecp = (u32 __iomem *) (brdp->membase + 0x30); - writel(0xffff0000, vecp); - outb(0, brdp->iobase); - mdelay(1000); -} - -/*****************************************************************************/ - -/* - * Try to find an ECP board and initialize it. This handles only ECP - * board types. - */ - -static int stli_initecp(struct stlibrd *brdp) -{ - cdkecpsig_t sig; - cdkecpsig_t __iomem *sigsp; - unsigned int status, nxtid; - char *name; - int retval, panelnr, nrports; - - if ((brdp->iobase == 0) || (brdp->memaddr == 0)) { - retval = -ENODEV; - goto err; - } - - brdp->iosize = ECP_IOSIZE; - - if (!request_region(brdp->iobase, brdp->iosize, "istallion")) { - retval = -EIO; - goto err; - } - -/* - * Based on the specific board type setup the common vars to access - * and enable shared memory. Set all board specific information now - * as well. - */ - switch (brdp->brdtype) { - case BRD_ECP: - brdp->memsize = ECP_MEMSIZE; - brdp->pagesize = ECP_ATPAGESIZE; - brdp->init = stli_ecpinit; - brdp->enable = stli_ecpenable; - brdp->reenable = stli_ecpenable; - brdp->disable = stli_ecpdisable; - brdp->getmemptr = stli_ecpgetmemptr; - brdp->intr = stli_ecpintr; - brdp->reset = stli_ecpreset; - name = "serial(EC8/64)"; - break; - - case BRD_ECPE: - brdp->memsize = ECP_MEMSIZE; - brdp->pagesize = ECP_EIPAGESIZE; - brdp->init = stli_ecpeiinit; - brdp->enable = stli_ecpeienable; - brdp->reenable = stli_ecpeienable; - brdp->disable = stli_ecpeidisable; - brdp->getmemptr = stli_ecpeigetmemptr; - brdp->intr = stli_ecpintr; - brdp->reset = stli_ecpeireset; - name = "serial(EC8/64-EI)"; - break; - - case BRD_ECPMC: - brdp->memsize = ECP_MEMSIZE; - brdp->pagesize = ECP_MCPAGESIZE; - brdp->init = NULL; - brdp->enable = stli_ecpmcenable; - brdp->reenable = stli_ecpmcenable; - brdp->disable = stli_ecpmcdisable; - brdp->getmemptr = stli_ecpmcgetmemptr; - brdp->intr = stli_ecpintr; - brdp->reset = stli_ecpmcreset; - name = "serial(EC8/64-MCA)"; - break; - - case BRD_ECPPCI: - brdp->memsize = ECP_PCIMEMSIZE; - brdp->pagesize = ECP_PCIPAGESIZE; - brdp->init = stli_ecppciinit; - brdp->enable = NULL; - brdp->reenable = NULL; - brdp->disable = NULL; - brdp->getmemptr = stli_ecppcigetmemptr; - brdp->intr = stli_ecpintr; - brdp->reset = stli_ecppcireset; - name = "serial(EC/RA-PCI)"; - break; - - default: - retval = -EINVAL; - goto err_reg; - } - -/* - * The per-board operations structure is all set up, so now let's go - * and get the board operational. Firstly initialize board configuration - * registers. Set the memory mapping info so we can get at the boards - * shared memory. - */ - EBRDINIT(brdp); - - brdp->membase = ioremap_nocache(brdp->memaddr, brdp->memsize); - if (brdp->membase == NULL) { - retval = -ENOMEM; - goto err_reg; - } - -/* - * Now that all specific code is set up, enable the shared memory and - * look for the a signature area that will tell us exactly what board - * this is, and what it is connected to it. - */ - EBRDENABLE(brdp); - sigsp = (cdkecpsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR); - memcpy_fromio(&sig, sigsp, sizeof(cdkecpsig_t)); - EBRDDISABLE(brdp); - - if (sig.magic != cpu_to_le32(ECP_MAGIC)) { - retval = -ENODEV; - goto err_unmap; - } - -/* - * Scan through the signature looking at the panels connected to the - * board. Calculate the total number of ports as we go. - */ - for (panelnr = 0, nxtid = 0; (panelnr < STL_MAXPANELS); panelnr++) { - status = sig.panelid[nxtid]; - if ((status & ECH_PNLIDMASK) != nxtid) - break; - - brdp->panelids[panelnr] = status; - nrports = (status & ECH_PNL16PORT) ? 16 : 8; - if ((nrports == 16) && ((status & ECH_PNLXPID) == 0)) - nxtid++; - brdp->panels[panelnr] = nrports; - brdp->nrports += nrports; - nxtid++; - brdp->nrpanels++; - } - - - set_bit(BST_FOUND, &brdp->state); - return 0; -err_unmap: - iounmap(brdp->membase); - brdp->membase = NULL; -err_reg: - release_region(brdp->iobase, brdp->iosize); -err: - return retval; -} - -/*****************************************************************************/ - -/* - * Try to find an ONboard, Brumby or Stallion board and initialize it. - * This handles only these board types. - */ - -static int stli_initonb(struct stlibrd *brdp) -{ - cdkonbsig_t sig; - cdkonbsig_t __iomem *sigsp; - char *name; - int i, retval; - -/* - * Do a basic sanity check on the IO and memory addresses. - */ - if (brdp->iobase == 0 || brdp->memaddr == 0) { - retval = -ENODEV; - goto err; - } - - brdp->iosize = ONB_IOSIZE; - - if (!request_region(brdp->iobase, brdp->iosize, "istallion")) { - retval = -EIO; - goto err; - } - -/* - * Based on the specific board type setup the common vars to access - * and enable shared memory. Set all board specific information now - * as well. - */ - switch (brdp->brdtype) { - case BRD_ONBOARD: - case BRD_ONBOARD2: - brdp->memsize = ONB_MEMSIZE; - brdp->pagesize = ONB_ATPAGESIZE; - brdp->init = stli_onbinit; - brdp->enable = stli_onbenable; - brdp->reenable = stli_onbenable; - brdp->disable = stli_onbdisable; - brdp->getmemptr = stli_onbgetmemptr; - brdp->intr = stli_ecpintr; - brdp->reset = stli_onbreset; - if (brdp->memaddr > 0x100000) - brdp->enabval = ONB_MEMENABHI; - else - brdp->enabval = ONB_MEMENABLO; - name = "serial(ONBoard)"; - break; - - case BRD_ONBOARDE: - brdp->memsize = ONB_EIMEMSIZE; - brdp->pagesize = ONB_EIPAGESIZE; - brdp->init = stli_onbeinit; - brdp->enable = stli_onbeenable; - brdp->reenable = stli_onbeenable; - brdp->disable = stli_onbedisable; - brdp->getmemptr = stli_onbegetmemptr; - brdp->intr = stli_ecpintr; - brdp->reset = stli_onbereset; - name = "serial(ONBoard/E)"; - break; - - case BRD_BRUMBY4: - brdp->memsize = BBY_MEMSIZE; - brdp->pagesize = BBY_PAGESIZE; - brdp->init = stli_bbyinit; - brdp->enable = NULL; - brdp->reenable = NULL; - brdp->disable = NULL; - brdp->getmemptr = stli_bbygetmemptr; - brdp->intr = stli_ecpintr; - brdp->reset = stli_bbyreset; - name = "serial(Brumby)"; - break; - - case BRD_STALLION: - brdp->memsize = STAL_MEMSIZE; - brdp->pagesize = STAL_PAGESIZE; - brdp->init = stli_stalinit; - brdp->enable = NULL; - brdp->reenable = NULL; - brdp->disable = NULL; - brdp->getmemptr = stli_stalgetmemptr; - brdp->intr = stli_ecpintr; - brdp->reset = stli_stalreset; - name = "serial(Stallion)"; - break; - - default: - retval = -EINVAL; - goto err_reg; - } - -/* - * The per-board operations structure is all set up, so now let's go - * and get the board operational. Firstly initialize board configuration - * registers. Set the memory mapping info so we can get at the boards - * shared memory. - */ - EBRDINIT(brdp); - - brdp->membase = ioremap_nocache(brdp->memaddr, brdp->memsize); - if (brdp->membase == NULL) { - retval = -ENOMEM; - goto err_reg; - } - -/* - * Now that all specific code is set up, enable the shared memory and - * look for the a signature area that will tell us exactly what board - * this is, and how many ports. - */ - EBRDENABLE(brdp); - sigsp = (cdkonbsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR); - memcpy_fromio(&sig, sigsp, sizeof(cdkonbsig_t)); - EBRDDISABLE(brdp); - - if (sig.magic0 != cpu_to_le16(ONB_MAGIC0) || - sig.magic1 != cpu_to_le16(ONB_MAGIC1) || - sig.magic2 != cpu_to_le16(ONB_MAGIC2) || - sig.magic3 != cpu_to_le16(ONB_MAGIC3)) { - retval = -ENODEV; - goto err_unmap; - } - -/* - * Scan through the signature alive mask and calculate how many ports - * there are on this board. - */ - brdp->nrpanels = 1; - if (sig.amask1) { - brdp->nrports = 32; - } else { - for (i = 0; (i < 16); i++) { - if (((sig.amask0 << i) & 0x8000) == 0) - break; - } - brdp->nrports = i; - } - brdp->panels[0] = brdp->nrports; - - - set_bit(BST_FOUND, &brdp->state); - return 0; -err_unmap: - iounmap(brdp->membase); - brdp->membase = NULL; -err_reg: - release_region(brdp->iobase, brdp->iosize); -err: - return retval; -} - -/*****************************************************************************/ - -/* - * Start up a running board. This routine is only called after the - * code has been down loaded to the board and is operational. It will - * read in the memory map, and get the show on the road... - */ - -static int stli_startbrd(struct stlibrd *brdp) -{ - cdkhdr_t __iomem *hdrp; - cdkmem_t __iomem *memp; - cdkasy_t __iomem *ap; - unsigned long flags; - unsigned int portnr, nrdevs, i; - struct stliport *portp; - int rc = 0; - u32 memoff; - - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - nrdevs = hdrp->nrdevs; - -#if 0 - printk("%s(%d): CDK version %d.%d.%d --> " - "nrdevs=%d memp=%x hostp=%x slavep=%x\n", - __FILE__, __LINE__, readb(&hdrp->ver_release), readb(&hdrp->ver_modification), - readb(&hdrp->ver_fix), nrdevs, (int) readl(&hdrp->memp), readl(&hdrp->hostp), - readl(&hdrp->slavep)); -#endif - - if (nrdevs < (brdp->nrports + 1)) { - printk(KERN_ERR "istallion: slave failed to allocate memory for " - "all devices, devices=%d\n", nrdevs); - brdp->nrports = nrdevs - 1; - } - brdp->nrdevs = nrdevs; - brdp->hostoffset = hdrp->hostp - CDK_CDKADDR; - brdp->slaveoffset = hdrp->slavep - CDK_CDKADDR; - brdp->bitsize = (nrdevs + 7) / 8; - memoff = readl(&hdrp->memp); - if (memoff > brdp->memsize) { - printk(KERN_ERR "istallion: corrupted shared memory region?\n"); - rc = -EIO; - goto stli_donestartup; - } - memp = (cdkmem_t __iomem *) EBRDGETMEMPTR(brdp, memoff); - if (readw(&memp->dtype) != TYP_ASYNCTRL) { - printk(KERN_ERR "istallion: no slave control device found\n"); - goto stli_donestartup; - } - memp++; - -/* - * Cycle through memory allocation of each port. We are guaranteed to - * have all ports inside the first page of slave window, so no need to - * change pages while reading memory map. - */ - for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++, memp++) { - if (readw(&memp->dtype) != TYP_ASYNC) - break; - portp = brdp->ports[portnr]; - if (portp == NULL) - break; - portp->devnr = i; - portp->addr = readl(&memp->offset); - portp->reqbit = (unsigned char) (0x1 << (i * 8 / nrdevs)); - portp->portidx = (unsigned char) (i / 8); - portp->portbit = (unsigned char) (0x1 << (i % 8)); - } - - writeb(0xff, &hdrp->slavereq); - -/* - * For each port setup a local copy of the RX and TX buffer offsets - * and sizes. We do this separate from the above, because we need to - * move the shared memory page... - */ - for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++) { - portp = brdp->ports[portnr]; - if (portp == NULL) - break; - if (portp->addr == 0) - break; - ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); - if (ap != NULL) { - portp->rxsize = readw(&ap->rxq.size); - portp->txsize = readw(&ap->txq.size); - portp->rxoffset = readl(&ap->rxq.offset); - portp->txoffset = readl(&ap->txq.offset); - } - } - -stli_donestartup: - EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); - - if (rc == 0) - set_bit(BST_STARTED, &brdp->state); - - if (! stli_timeron) { - stli_timeron++; - mod_timer(&stli_timerlist, STLI_TIMEOUT); - } - - return rc; -} - -/*****************************************************************************/ - -/* - * Probe and initialize the specified board. - */ - -static int __devinit stli_brdinit(struct stlibrd *brdp) -{ - int retval; - - switch (brdp->brdtype) { - case BRD_ECP: - case BRD_ECPE: - case BRD_ECPMC: - case BRD_ECPPCI: - retval = stli_initecp(brdp); - break; - case BRD_ONBOARD: - case BRD_ONBOARDE: - case BRD_ONBOARD2: - case BRD_BRUMBY4: - case BRD_STALLION: - retval = stli_initonb(brdp); - break; - default: - printk(KERN_ERR "istallion: board=%d is unknown board " - "type=%d\n", brdp->brdnr, brdp->brdtype); - retval = -ENODEV; - } - - if (retval) - return retval; - - stli_initports(brdp); - printk(KERN_INFO "istallion: %s found, board=%d io=%x mem=%x " - "nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype], - brdp->brdnr, brdp->iobase, (int) brdp->memaddr, - brdp->nrpanels, brdp->nrports); - return 0; -} - -#if STLI_EISAPROBE != 0 -/*****************************************************************************/ - -/* - * Probe around trying to find where the EISA boards shared memory - * might be. This is a bit if hack, but it is the best we can do. - */ - -static int stli_eisamemprobe(struct stlibrd *brdp) -{ - cdkecpsig_t ecpsig, __iomem *ecpsigp; - cdkonbsig_t onbsig, __iomem *onbsigp; - int i, foundit; - -/* - * First up we reset the board, to get it into a known state. There - * is only 2 board types here we need to worry about. Don;t use the - * standard board init routine here, it programs up the shared - * memory address, and we don't know it yet... - */ - if (brdp->brdtype == BRD_ECPE) { - outb(0x1, (brdp->iobase + ECP_EIBRDENAB)); - outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR)); - udelay(10); - outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR)); - udelay(500); - stli_ecpeienable(brdp); - } else if (brdp->brdtype == BRD_ONBOARDE) { - outb(0x1, (brdp->iobase + ONB_EIBRDENAB)); - outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); - udelay(10); - outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); - mdelay(100); - outb(0x1, brdp->iobase); - mdelay(1); - stli_onbeenable(brdp); - } else { - return -ENODEV; - } - - foundit = 0; - brdp->memsize = ECP_MEMSIZE; - -/* - * Board shared memory is enabled, so now we have a poke around and - * see if we can find it. - */ - for (i = 0; (i < stli_eisamempsize); i++) { - brdp->memaddr = stli_eisamemprobeaddrs[i]; - brdp->membase = ioremap_nocache(brdp->memaddr, brdp->memsize); - if (brdp->membase == NULL) - continue; - - if (brdp->brdtype == BRD_ECPE) { - ecpsigp = stli_ecpeigetmemptr(brdp, - CDK_SIGADDR, __LINE__); - memcpy_fromio(&ecpsig, ecpsigp, sizeof(cdkecpsig_t)); - if (ecpsig.magic == cpu_to_le32(ECP_MAGIC)) - foundit = 1; - } else { - onbsigp = (cdkonbsig_t __iomem *) stli_onbegetmemptr(brdp, - CDK_SIGADDR, __LINE__); - memcpy_fromio(&onbsig, onbsigp, sizeof(cdkonbsig_t)); - if ((onbsig.magic0 == cpu_to_le16(ONB_MAGIC0)) && - (onbsig.magic1 == cpu_to_le16(ONB_MAGIC1)) && - (onbsig.magic2 == cpu_to_le16(ONB_MAGIC2)) && - (onbsig.magic3 == cpu_to_le16(ONB_MAGIC3))) - foundit = 1; - } - - iounmap(brdp->membase); - if (foundit) - break; - } - -/* - * Regardless of whether we found the shared memory or not we must - * disable the region. After that return success or failure. - */ - if (brdp->brdtype == BRD_ECPE) - stli_ecpeidisable(brdp); - else - stli_onbedisable(brdp); - - if (! foundit) { - brdp->memaddr = 0; - brdp->membase = NULL; - printk(KERN_ERR "istallion: failed to probe shared memory " - "region for %s in EISA slot=%d\n", - stli_brdnames[brdp->brdtype], (brdp->iobase >> 12)); - return -ENODEV; - } - return 0; -} -#endif - -static int stli_getbrdnr(void) -{ - unsigned int i; - - for (i = 0; i < STL_MAXBRDS; i++) { - if (!stli_brds[i]) { - if (i >= stli_nrbrds) - stli_nrbrds = i + 1; - return i; - } - } - return -1; -} - -#if STLI_EISAPROBE != 0 -/*****************************************************************************/ - -/* - * Probe around and try to find any EISA boards in system. The biggest - * problem here is finding out what memory address is associated with - * an EISA board after it is found. The registers of the ECPE and - * ONboardE are not readable - so we can't read them from there. We - * don't have access to the EISA CMOS (or EISA BIOS) so we don't - * actually have any way to find out the real value. The best we can - * do is go probing around in the usual places hoping we can find it. - */ - -static int __init stli_findeisabrds(void) -{ - struct stlibrd *brdp; - unsigned int iobase, eid, i; - int brdnr, found = 0; - -/* - * Firstly check if this is an EISA system. If this is not an EISA system then - * don't bother going any further! - */ - if (EISA_bus) - return 0; - -/* - * Looks like an EISA system, so go searching for EISA boards. - */ - for (iobase = 0x1000; (iobase <= 0xc000); iobase += 0x1000) { - outb(0xff, (iobase + 0xc80)); - eid = inb(iobase + 0xc80); - eid |= inb(iobase + 0xc81) << 8; - if (eid != STL_EISAID) - continue; - -/* - * We have found a board. Need to check if this board was - * statically configured already (just in case!). - */ - for (i = 0; (i < STL_MAXBRDS); i++) { - brdp = stli_brds[i]; - if (brdp == NULL) - continue; - if (brdp->iobase == iobase) - break; - } - if (i < STL_MAXBRDS) - continue; - -/* - * We have found a Stallion board and it is not configured already. - * Allocate a board structure and initialize it. - */ - if ((brdp = stli_allocbrd()) == NULL) - return found ? : -ENOMEM; - brdnr = stli_getbrdnr(); - if (brdnr < 0) - return found ? : -ENOMEM; - brdp->brdnr = (unsigned int)brdnr; - eid = inb(iobase + 0xc82); - if (eid == ECP_EISAID) - brdp->brdtype = BRD_ECPE; - else if (eid == ONB_EISAID) - brdp->brdtype = BRD_ONBOARDE; - else - brdp->brdtype = BRD_UNKNOWN; - brdp->iobase = iobase; - outb(0x1, (iobase + 0xc84)); - if (stli_eisamemprobe(brdp)) - outb(0, (iobase + 0xc84)); - if (stli_brdinit(brdp) < 0) { - kfree(brdp); - continue; - } - - stli_brds[brdp->brdnr] = brdp; - found++; - - for (i = 0; i < brdp->nrports; i++) - tty_register_device(stli_serial, - brdp->brdnr * STL_MAXPORTS + i, NULL); - } - - return found; -} -#else -static inline int stli_findeisabrds(void) { return 0; } -#endif - -/*****************************************************************************/ - -/* - * Find the next available board number that is free. - */ - -/*****************************************************************************/ - -/* - * We have a Stallion board. Allocate a board structure and - * initialize it. Read its IO and MEMORY resources from PCI - * configuration space. - */ - -static int __devinit stli_pciprobe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct stlibrd *brdp; - unsigned int i; - int brdnr, retval = -EIO; - - retval = pci_enable_device(pdev); - if (retval) - goto err; - brdp = stli_allocbrd(); - if (brdp == NULL) { - retval = -ENOMEM; - goto err; - } - mutex_lock(&stli_brdslock); - brdnr = stli_getbrdnr(); - if (brdnr < 0) { - printk(KERN_INFO "istallion: too many boards found, " - "maximum supported %d\n", STL_MAXBRDS); - mutex_unlock(&stli_brdslock); - retval = -EIO; - goto err_fr; - } - brdp->brdnr = (unsigned int)brdnr; - stli_brds[brdp->brdnr] = brdp; - mutex_unlock(&stli_brdslock); - brdp->brdtype = BRD_ECPPCI; -/* - * We have all resources from the board, so lets setup the actual - * board structure now. - */ - brdp->iobase = pci_resource_start(pdev, 3); - brdp->memaddr = pci_resource_start(pdev, 2); - retval = stli_brdinit(brdp); - if (retval) - goto err_null; - - set_bit(BST_PROBED, &brdp->state); - pci_set_drvdata(pdev, brdp); - - EBRDENABLE(brdp); - brdp->enable = NULL; - brdp->disable = NULL; - - for (i = 0; i < brdp->nrports; i++) - tty_register_device(stli_serial, brdp->brdnr * STL_MAXPORTS + i, - &pdev->dev); - - return 0; -err_null: - stli_brds[brdp->brdnr] = NULL; -err_fr: - kfree(brdp); -err: - return retval; -} - -static void __devexit stli_pciremove(struct pci_dev *pdev) -{ - struct stlibrd *brdp = pci_get_drvdata(pdev); - - stli_cleanup_ports(brdp); - - iounmap(brdp->membase); - if (brdp->iosize > 0) - release_region(brdp->iobase, brdp->iosize); - - stli_brds[brdp->brdnr] = NULL; - kfree(brdp); -} - -static struct pci_driver stli_pcidriver = { - .name = "istallion", - .id_table = istallion_pci_tbl, - .probe = stli_pciprobe, - .remove = __devexit_p(stli_pciremove) -}; -/*****************************************************************************/ - -/* - * Allocate a new board structure. Fill out the basic info in it. - */ - -static struct stlibrd *stli_allocbrd(void) -{ - struct stlibrd *brdp; - - brdp = kzalloc(sizeof(struct stlibrd), GFP_KERNEL); - if (!brdp) { - printk(KERN_ERR "istallion: failed to allocate memory " - "(size=%Zd)\n", sizeof(struct stlibrd)); - return NULL; - } - brdp->magic = STLI_BOARDMAGIC; - return brdp; -} - -/*****************************************************************************/ - -/* - * Scan through all the boards in the configuration and see what we - * can find. - */ - -static int __init stli_initbrds(void) -{ - struct stlibrd *brdp, *nxtbrdp; - struct stlconf conf; - unsigned int i, j, found = 0; - int retval; - - for (stli_nrbrds = 0; stli_nrbrds < ARRAY_SIZE(stli_brdsp); - stli_nrbrds++) { - memset(&conf, 0, sizeof(conf)); - if (stli_parsebrd(&conf, stli_brdsp[stli_nrbrds]) == 0) - continue; - if ((brdp = stli_allocbrd()) == NULL) - continue; - brdp->brdnr = stli_nrbrds; - brdp->brdtype = conf.brdtype; - brdp->iobase = conf.ioaddr1; - brdp->memaddr = conf.memaddr; - if (stli_brdinit(brdp) < 0) { - kfree(brdp); - continue; - } - stli_brds[brdp->brdnr] = brdp; - found++; - - for (i = 0; i < brdp->nrports; i++) - tty_register_device(stli_serial, - brdp->brdnr * STL_MAXPORTS + i, NULL); - } - - retval = stli_findeisabrds(); - if (retval > 0) - found += retval; - -/* - * All found boards are initialized. Now for a little optimization, if - * no boards are sharing the "shared memory" regions then we can just - * leave them all enabled. This is in fact the usual case. - */ - stli_shared = 0; - if (stli_nrbrds > 1) { - for (i = 0; (i < stli_nrbrds); i++) { - brdp = stli_brds[i]; - if (brdp == NULL) - continue; - for (j = i + 1; (j < stli_nrbrds); j++) { - nxtbrdp = stli_brds[j]; - if (nxtbrdp == NULL) - continue; - if ((brdp->membase >= nxtbrdp->membase) && - (brdp->membase <= (nxtbrdp->membase + - nxtbrdp->memsize - 1))) { - stli_shared++; - break; - } - } - } - } - - if (stli_shared == 0) { - for (i = 0; (i < stli_nrbrds); i++) { - brdp = stli_brds[i]; - if (brdp == NULL) - continue; - if (test_bit(BST_FOUND, &brdp->state)) { - EBRDENABLE(brdp); - brdp->enable = NULL; - brdp->disable = NULL; - } - } - } - - retval = pci_register_driver(&stli_pcidriver); - if (retval && found == 0) { - printk(KERN_ERR "Neither isa nor eisa cards found nor pci " - "driver can be registered!\n"); - goto err; - } - - return 0; -err: - return retval; -} - -/*****************************************************************************/ - -/* - * Code to handle an "staliomem" read operation. This device is the - * contents of the board shared memory. It is used for down loading - * the slave image (and debugging :-) - */ - -static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp) -{ - unsigned long flags; - void __iomem *memptr; - struct stlibrd *brdp; - unsigned int brdnr; - int size, n; - void *p; - loff_t off = *offp; - - brdnr = iminor(fp->f_path.dentry->d_inode); - if (brdnr >= stli_nrbrds) - return -ENODEV; - brdp = stli_brds[brdnr]; - if (brdp == NULL) - return -ENODEV; - if (brdp->state == 0) - return -ENODEV; - if (off >= brdp->memsize || off + count < off) - return 0; - - size = min(count, (size_t)(brdp->memsize - off)); - - /* - * Copy the data a page at a time - */ - - p = (void *)__get_free_page(GFP_KERNEL); - if(p == NULL) - return -ENOMEM; - - while (size > 0) { - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - memptr = EBRDGETMEMPTR(brdp, off); - n = min(size, (int)(brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); - n = min(n, (int)PAGE_SIZE); - memcpy_fromio(p, memptr, n); - EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); - if (copy_to_user(buf, p, n)) { - count = -EFAULT; - goto out; - } - off += n; - buf += n; - size -= n; - } -out: - *offp = off; - free_page((unsigned long)p); - return count; -} - -/*****************************************************************************/ - -/* - * Code to handle an "staliomem" write operation. This device is the - * contents of the board shared memory. It is used for down loading - * the slave image (and debugging :-) - * - * FIXME: copy under lock - */ - -static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp) -{ - unsigned long flags; - void __iomem *memptr; - struct stlibrd *brdp; - char __user *chbuf; - unsigned int brdnr; - int size, n; - void *p; - loff_t off = *offp; - - brdnr = iminor(fp->f_path.dentry->d_inode); - - if (brdnr >= stli_nrbrds) - return -ENODEV; - brdp = stli_brds[brdnr]; - if (brdp == NULL) - return -ENODEV; - if (brdp->state == 0) - return -ENODEV; - if (off >= brdp->memsize || off + count < off) - return 0; - - chbuf = (char __user *) buf; - size = min(count, (size_t)(brdp->memsize - off)); - - /* - * Copy the data a page at a time - */ - - p = (void *)__get_free_page(GFP_KERNEL); - if(p == NULL) - return -ENOMEM; - - while (size > 0) { - n = min(size, (int)(brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); - n = min(n, (int)PAGE_SIZE); - if (copy_from_user(p, chbuf, n)) { - if (count == 0) - count = -EFAULT; - goto out; - } - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - memptr = EBRDGETMEMPTR(brdp, off); - memcpy_toio(memptr, p, n); - EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); - off += n; - chbuf += n; - size -= n; - } -out: - free_page((unsigned long) p); - *offp = off; - return count; -} - -/*****************************************************************************/ - -/* - * Return the board stats structure to user app. - */ - -static int stli_getbrdstats(combrd_t __user *bp) -{ - struct stlibrd *brdp; - unsigned int i; - - if (copy_from_user(&stli_brdstats, bp, sizeof(combrd_t))) - return -EFAULT; - if (stli_brdstats.brd >= STL_MAXBRDS) - return -ENODEV; - brdp = stli_brds[stli_brdstats.brd]; - if (brdp == NULL) - return -ENODEV; - - memset(&stli_brdstats, 0, sizeof(combrd_t)); - - stli_brdstats.brd = brdp->brdnr; - stli_brdstats.type = brdp->brdtype; - stli_brdstats.hwid = 0; - stli_brdstats.state = brdp->state; - stli_brdstats.ioaddr = brdp->iobase; - stli_brdstats.memaddr = brdp->memaddr; - stli_brdstats.nrpanels = brdp->nrpanels; - stli_brdstats.nrports = brdp->nrports; - for (i = 0; (i < brdp->nrpanels); i++) { - stli_brdstats.panels[i].panel = i; - stli_brdstats.panels[i].hwid = brdp->panelids[i]; - stli_brdstats.panels[i].nrports = brdp->panels[i]; - } - - if (copy_to_user(bp, &stli_brdstats, sizeof(combrd_t))) - return -EFAULT; - return 0; -} - -/*****************************************************************************/ - -/* - * Resolve the referenced port number into a port struct pointer. - */ - -static struct stliport *stli_getport(unsigned int brdnr, unsigned int panelnr, - unsigned int portnr) -{ - struct stlibrd *brdp; - unsigned int i; - - if (brdnr >= STL_MAXBRDS) - return NULL; - brdp = stli_brds[brdnr]; - if (brdp == NULL) - return NULL; - for (i = 0; (i < panelnr); i++) - portnr += brdp->panels[i]; - if (portnr >= brdp->nrports) - return NULL; - return brdp->ports[portnr]; -} - -/*****************************************************************************/ - -/* - * Return the port stats structure to user app. A NULL port struct - * pointer passed in means that we need to find out from the app - * what port to get stats for (used through board control device). - */ - -static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp) -{ - unsigned long flags; - struct stlibrd *brdp; - int rc; - - memset(&stli_comstats, 0, sizeof(comstats_t)); - - if (portp == NULL) - return -ENODEV; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return -ENODEV; - - mutex_lock(&portp->port.mutex); - if (test_bit(BST_STARTED, &brdp->state)) { - if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS, - &stli_cdkstats, sizeof(asystats_t), 1)) < 0) { - mutex_unlock(&portp->port.mutex); - return rc; - } - } else { - memset(&stli_cdkstats, 0, sizeof(asystats_t)); - } - - stli_comstats.brd = portp->brdnr; - stli_comstats.panel = portp->panelnr; - stli_comstats.port = portp->portnr; - stli_comstats.state = portp->state; - stli_comstats.flags = portp->port.flags; - - spin_lock_irqsave(&brd_lock, flags); - if (tty != NULL) { - if (portp->port.tty == tty) { - stli_comstats.ttystate = tty->flags; - stli_comstats.rxbuffered = -1; - if (tty->termios != NULL) { - stli_comstats.cflags = tty->termios->c_cflag; - stli_comstats.iflags = tty->termios->c_iflag; - stli_comstats.oflags = tty->termios->c_oflag; - stli_comstats.lflags = tty->termios->c_lflag; - } - } - } - spin_unlock_irqrestore(&brd_lock, flags); - - stli_comstats.txtotal = stli_cdkstats.txchars; - stli_comstats.rxtotal = stli_cdkstats.rxchars + stli_cdkstats.ringover; - stli_comstats.txbuffered = stli_cdkstats.txringq; - stli_comstats.rxbuffered += stli_cdkstats.rxringq; - stli_comstats.rxoverrun = stli_cdkstats.overruns; - stli_comstats.rxparity = stli_cdkstats.parity; - stli_comstats.rxframing = stli_cdkstats.framing; - stli_comstats.rxlost = stli_cdkstats.ringover; - stli_comstats.rxbreaks = stli_cdkstats.rxbreaks; - stli_comstats.txbreaks = stli_cdkstats.txbreaks; - stli_comstats.txxon = stli_cdkstats.txstart; - stli_comstats.txxoff = stli_cdkstats.txstop; - stli_comstats.rxxon = stli_cdkstats.rxstart; - stli_comstats.rxxoff = stli_cdkstats.rxstop; - stli_comstats.rxrtsoff = stli_cdkstats.rtscnt / 2; - stli_comstats.rxrtson = stli_cdkstats.rtscnt - stli_comstats.rxrtsoff; - stli_comstats.modem = stli_cdkstats.dcdcnt; - stli_comstats.hwid = stli_cdkstats.hwid; - stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals); - mutex_unlock(&portp->port.mutex); - - return 0; -} - -/*****************************************************************************/ - -/* - * Return the port stats structure to user app. A NULL port struct - * pointer passed in means that we need to find out from the app - * what port to get stats for (used through board control device). - */ - -static int stli_getportstats(struct tty_struct *tty, struct stliport *portp, - comstats_t __user *cp) -{ - struct stlibrd *brdp; - int rc; - - if (!portp) { - if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t))) - return -EFAULT; - portp = stli_getport(stli_comstats.brd, stli_comstats.panel, - stli_comstats.port); - if (!portp) - return -ENODEV; - } - - brdp = stli_brds[portp->brdnr]; - if (!brdp) - return -ENODEV; - - if ((rc = stli_portcmdstats(tty, portp)) < 0) - return rc; - - return copy_to_user(cp, &stli_comstats, sizeof(comstats_t)) ? - -EFAULT : 0; -} - -/*****************************************************************************/ - -/* - * Clear the port stats structure. We also return it zeroed out... - */ - -static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp) -{ - struct stlibrd *brdp; - int rc; - - if (!portp) { - if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t))) - return -EFAULT; - portp = stli_getport(stli_comstats.brd, stli_comstats.panel, - stli_comstats.port); - if (!portp) - return -ENODEV; - } - - brdp = stli_brds[portp->brdnr]; - if (!brdp) - return -ENODEV; - - mutex_lock(&portp->port.mutex); - - if (test_bit(BST_STARTED, &brdp->state)) { - if ((rc = stli_cmdwait(brdp, portp, A_CLEARSTATS, NULL, 0, 0)) < 0) { - mutex_unlock(&portp->port.mutex); - return rc; - } - } - - memset(&stli_comstats, 0, sizeof(comstats_t)); - stli_comstats.brd = portp->brdnr; - stli_comstats.panel = portp->panelnr; - stli_comstats.port = portp->portnr; - mutex_unlock(&portp->port.mutex); - - if (copy_to_user(cp, &stli_comstats, sizeof(comstats_t))) - return -EFAULT; - return 0; -} - -/*****************************************************************************/ - -/* - * Return the entire driver ports structure to a user app. - */ - -static int stli_getportstruct(struct stliport __user *arg) -{ - struct stliport stli_dummyport; - struct stliport *portp; - - if (copy_from_user(&stli_dummyport, arg, sizeof(struct stliport))) - return -EFAULT; - portp = stli_getport(stli_dummyport.brdnr, stli_dummyport.panelnr, - stli_dummyport.portnr); - if (!portp) - return -ENODEV; - if (copy_to_user(arg, portp, sizeof(struct stliport))) - return -EFAULT; - return 0; -} - -/*****************************************************************************/ - -/* - * Return the entire driver board structure to a user app. - */ - -static int stli_getbrdstruct(struct stlibrd __user *arg) -{ - struct stlibrd stli_dummybrd; - struct stlibrd *brdp; - - if (copy_from_user(&stli_dummybrd, arg, sizeof(struct stlibrd))) - return -EFAULT; - if (stli_dummybrd.brdnr >= STL_MAXBRDS) - return -ENODEV; - brdp = stli_brds[stli_dummybrd.brdnr]; - if (!brdp) - return -ENODEV; - if (copy_to_user(arg, brdp, sizeof(struct stlibrd))) - return -EFAULT; - return 0; -} - -/*****************************************************************************/ - -/* - * The "staliomem" device is also required to do some special operations on - * the board. We need to be able to send an interrupt to the board, - * reset it, and start/stop it. - */ - -static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) -{ - struct stlibrd *brdp; - int brdnr, rc, done; - void __user *argp = (void __user *)arg; - -/* - * First up handle the board independent ioctls. - */ - done = 0; - rc = 0; - - switch (cmd) { - case COM_GETPORTSTATS: - rc = stli_getportstats(NULL, NULL, argp); - done++; - break; - case COM_CLRPORTSTATS: - rc = stli_clrportstats(NULL, argp); - done++; - break; - case COM_GETBRDSTATS: - rc = stli_getbrdstats(argp); - done++; - break; - case COM_READPORT: - rc = stli_getportstruct(argp); - done++; - break; - case COM_READBOARD: - rc = stli_getbrdstruct(argp); - done++; - break; - } - if (done) - return rc; - -/* - * Now handle the board specific ioctls. These all depend on the - * minor number of the device they were called from. - */ - brdnr = iminor(fp->f_dentry->d_inode); - if (brdnr >= STL_MAXBRDS) - return -ENODEV; - brdp = stli_brds[brdnr]; - if (!brdp) - return -ENODEV; - if (brdp->state == 0) - return -ENODEV; - - switch (cmd) { - case STL_BINTR: - EBRDINTR(brdp); - break; - case STL_BSTART: - rc = stli_startbrd(brdp); - break; - case STL_BSTOP: - clear_bit(BST_STARTED, &brdp->state); - break; - case STL_BRESET: - clear_bit(BST_STARTED, &brdp->state); - EBRDRESET(brdp); - if (stli_shared == 0) { - if (brdp->reenable != NULL) - (* brdp->reenable)(brdp); - } - break; - default: - rc = -ENOIOCTLCMD; - break; - } - return rc; -} - -static const struct tty_operations stli_ops = { - .open = stli_open, - .close = stli_close, - .write = stli_write, - .put_char = stli_putchar, - .flush_chars = stli_flushchars, - .write_room = stli_writeroom, - .chars_in_buffer = stli_charsinbuffer, - .ioctl = stli_ioctl, - .set_termios = stli_settermios, - .throttle = stli_throttle, - .unthrottle = stli_unthrottle, - .stop = stli_stop, - .start = stli_start, - .hangup = stli_hangup, - .flush_buffer = stli_flushbuffer, - .break_ctl = stli_breakctl, - .wait_until_sent = stli_waituntilsent, - .send_xchar = stli_sendxchar, - .tiocmget = stli_tiocmget, - .tiocmset = stli_tiocmset, - .proc_fops = &stli_proc_fops, -}; - -static const struct tty_port_operations stli_port_ops = { - .carrier_raised = stli_carrier_raised, - .dtr_rts = stli_dtr_rts, - .activate = stli_activate, - .shutdown = stli_shutdown, -}; - -/*****************************************************************************/ -/* - * Loadable module initialization stuff. - */ - -static void istallion_cleanup_isa(void) -{ - struct stlibrd *brdp; - unsigned int j; - - for (j = 0; (j < stli_nrbrds); j++) { - if ((brdp = stli_brds[j]) == NULL || - test_bit(BST_PROBED, &brdp->state)) - continue; - - stli_cleanup_ports(brdp); - - iounmap(brdp->membase); - if (brdp->iosize > 0) - release_region(brdp->iobase, brdp->iosize); - kfree(brdp); - stli_brds[j] = NULL; - } -} - -static int __init istallion_module_init(void) -{ - unsigned int i; - int retval; - - printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion); - - spin_lock_init(&stli_lock); - spin_lock_init(&brd_lock); - - stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); - if (!stli_txcookbuf) { - printk(KERN_ERR "istallion: failed to allocate memory " - "(size=%d)\n", STLI_TXBUFSIZE); - retval = -ENOMEM; - goto err; - } - - stli_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); - if (!stli_serial) { - retval = -ENOMEM; - goto err_free; - } - - stli_serial->owner = THIS_MODULE; - stli_serial->driver_name = stli_drvname; - stli_serial->name = stli_serialname; - stli_serial->major = STL_SERIALMAJOR; - stli_serial->minor_start = 0; - stli_serial->type = TTY_DRIVER_TYPE_SERIAL; - stli_serial->subtype = SERIAL_TYPE_NORMAL; - stli_serial->init_termios = stli_deftermios; - stli_serial->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; - tty_set_operations(stli_serial, &stli_ops); - - retval = tty_register_driver(stli_serial); - if (retval) { - printk(KERN_ERR "istallion: failed to register serial driver\n"); - goto err_ttyput; - } - - retval = stli_initbrds(); - if (retval) - goto err_ttyunr; - -/* - * Set up a character driver for the shared memory region. We need this - * to down load the slave code image. Also it is a useful debugging tool. - */ - retval = register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stli_fsiomem); - if (retval) { - printk(KERN_ERR "istallion: failed to register serial memory " - "device\n"); - goto err_deinit; - } - - istallion_class = class_create(THIS_MODULE, "staliomem"); - for (i = 0; i < 4; i++) - device_create(istallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i), - NULL, "staliomem%d", i); - - return 0; -err_deinit: - pci_unregister_driver(&stli_pcidriver); - istallion_cleanup_isa(); -err_ttyunr: - tty_unregister_driver(stli_serial); -err_ttyput: - put_tty_driver(stli_serial); -err_free: - kfree(stli_txcookbuf); -err: - return retval; -} - -/*****************************************************************************/ - -static void __exit istallion_module_exit(void) -{ - unsigned int j; - - printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle, - stli_drvversion); - - if (stli_timeron) { - stli_timeron = 0; - del_timer_sync(&stli_timerlist); - } - - unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"); - - for (j = 0; j < 4; j++) - device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, j)); - class_destroy(istallion_class); - - pci_unregister_driver(&stli_pcidriver); - istallion_cleanup_isa(); - - tty_unregister_driver(stli_serial); - put_tty_driver(stli_serial); - - kfree(stli_txcookbuf); -} - -module_init(istallion_module_init); -module_exit(istallion_module_exit); diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c deleted file mode 100644 index 602643a40b4b..000000000000 --- a/drivers/char/riscom8.c +++ /dev/null @@ -1,1560 +0,0 @@ -/* - * linux/drivers/char/riscom.c -- RISCom/8 multiport serial driver. - * - * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) - * - * This code is loosely based on the Linux serial driver, written by - * Linus Torvalds, Theodore T'so and others. The RISCom/8 card - * programming info was obtained from various drivers for other OSes - * (FreeBSD, ISC, etc), but no source code from those drivers were - * directly included in this driver. - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Revision 1.1 - * - * ChangeLog: - * Arnaldo Carvalho de Melo - 27-Jun-2001 - * - get rid of check_region and several cleanups - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "riscom8.h" -#include "riscom8_reg.h" - -/* Am I paranoid or not ? ;-) */ -#define RISCOM_PARANOIA_CHECK - -/* - * Crazy InteliCom/8 boards sometimes have swapped CTS & DSR signals. - * You can slightly speed up things by #undefing the following option, - * if you are REALLY sure that your board is correct one. - */ - -#define RISCOM_BRAIN_DAMAGED_CTS - -/* - * The following defines are mostly for testing purposes. But if you need - * some nice reporting in your syslog, you can define them also. - */ -#undef RC_REPORT_FIFO -#undef RC_REPORT_OVERRUN - - -#define RISCOM_LEGAL_FLAGS \ - (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \ - ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \ - ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP) - -static struct tty_driver *riscom_driver; - -static DEFINE_SPINLOCK(riscom_lock); - -static struct riscom_board rc_board[RC_NBOARD] = { - { - .base = RC_IOBASE1, - }, - { - .base = RC_IOBASE2, - }, - { - .base = RC_IOBASE3, - }, - { - .base = RC_IOBASE4, - }, -}; - -static struct riscom_port rc_port[RC_NBOARD * RC_NPORT]; - -/* RISCom/8 I/O ports addresses (without address translation) */ -static unsigned short rc_ioport[] = { -#if 1 - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c, -#else - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c, 0x10, - 0x11, 0x12, 0x18, 0x28, 0x31, 0x32, 0x39, 0x3a, 0x40, 0x41, 0x61, 0x62, - 0x63, 0x64, 0x6b, 0x70, 0x71, 0x78, 0x7a, 0x7b, 0x7f, 0x100, 0x101 -#endif -}; -#define RC_NIOPORT ARRAY_SIZE(rc_ioport) - - -static int rc_paranoia_check(struct riscom_port const *port, - char *name, const char *routine) -{ -#ifdef RISCOM_PARANOIA_CHECK - static const char badmagic[] = KERN_INFO - "rc: Warning: bad riscom port magic number for device %s in %s\n"; - static const char badinfo[] = KERN_INFO - "rc: Warning: null riscom port for device %s in %s\n"; - - if (!port) { - printk(badinfo, name, routine); - return 1; - } - if (port->magic != RISCOM8_MAGIC) { - printk(badmagic, name, routine); - return 1; - } -#endif - return 0; -} - -/* - * - * Service functions for RISCom/8 driver. - * - */ - -/* Get board number from pointer */ -static inline int board_No(struct riscom_board const *bp) -{ - return bp - rc_board; -} - -/* Get port number from pointer */ -static inline int port_No(struct riscom_port const *port) -{ - return RC_PORT(port - rc_port); -} - -/* Get pointer to board from pointer to port */ -static inline struct riscom_board *port_Board(struct riscom_port const *port) -{ - return &rc_board[RC_BOARD(port - rc_port)]; -} - -/* Input Byte from CL CD180 register */ -static inline unsigned char rc_in(struct riscom_board const *bp, - unsigned short reg) -{ - return inb(bp->base + RC_TO_ISA(reg)); -} - -/* Output Byte to CL CD180 register */ -static inline void rc_out(struct riscom_board const *bp, unsigned short reg, - unsigned char val) -{ - outb(val, bp->base + RC_TO_ISA(reg)); -} - -/* Wait for Channel Command Register ready */ -static void rc_wait_CCR(struct riscom_board const *bp) -{ - unsigned long delay; - - /* FIXME: need something more descriptive then 100000 :) */ - for (delay = 100000; delay; delay--) - if (!rc_in(bp, CD180_CCR)) - return; - - printk(KERN_INFO "rc%d: Timeout waiting for CCR.\n", board_No(bp)); -} - -/* - * RISCom/8 probe functions. - */ - -static int rc_request_io_range(struct riscom_board * const bp) -{ - int i; - - for (i = 0; i < RC_NIOPORT; i++) - if (!request_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1, - "RISCom/8")) { - goto out_release; - } - return 0; -out_release: - printk(KERN_INFO "rc%d: Skipping probe at 0x%03x. IO address in use.\n", - board_No(bp), bp->base); - while (--i >= 0) - release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1); - return 1; -} - -static void rc_release_io_range(struct riscom_board * const bp) -{ - int i; - - for (i = 0; i < RC_NIOPORT; i++) - release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1); -} - -/* Reset and setup CD180 chip */ -static void __init rc_init_CD180(struct riscom_board const *bp) -{ - unsigned long flags; - - spin_lock_irqsave(&riscom_lock, flags); - - rc_out(bp, RC_CTOUT, 0); /* Clear timeout */ - rc_wait_CCR(bp); /* Wait for CCR ready */ - rc_out(bp, CD180_CCR, CCR_HARDRESET); /* Reset CD180 chip */ - spin_unlock_irqrestore(&riscom_lock, flags); - msleep(50); /* Delay 0.05 sec */ - spin_lock_irqsave(&riscom_lock, flags); - rc_out(bp, CD180_GIVR, RC_ID); /* Set ID for this chip */ - rc_out(bp, CD180_GICR, 0); /* Clear all bits */ - rc_out(bp, CD180_PILR1, RC_ACK_MINT); /* Prio for modem intr */ - rc_out(bp, CD180_PILR2, RC_ACK_TINT); /* Prio for tx intr */ - rc_out(bp, CD180_PILR3, RC_ACK_RINT); /* Prio for rx intr */ - - /* Setting up prescaler. We need 4 ticks per 1 ms */ - rc_out(bp, CD180_PPRH, (RC_OSCFREQ/(1000000/RISCOM_TPS)) >> 8); - rc_out(bp, CD180_PPRL, (RC_OSCFREQ/(1000000/RISCOM_TPS)) & 0xff); - - spin_unlock_irqrestore(&riscom_lock, flags); -} - -/* Main probing routine, also sets irq. */ -static int __init rc_probe(struct riscom_board *bp) -{ - unsigned char val1, val2; - int irqs = 0; - int retries; - - bp->irq = 0; - - if (rc_request_io_range(bp)) - return 1; - - /* Are the I/O ports here ? */ - rc_out(bp, CD180_PPRL, 0x5a); - outb(0xff, 0x80); - val1 = rc_in(bp, CD180_PPRL); - rc_out(bp, CD180_PPRL, 0xa5); - outb(0x00, 0x80); - val2 = rc_in(bp, CD180_PPRL); - - if ((val1 != 0x5a) || (val2 != 0xa5)) { - printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not found.\n", - board_No(bp), bp->base); - goto out_release; - } - - /* It's time to find IRQ for this board */ - for (retries = 0; retries < 5 && irqs <= 0; retries++) { - irqs = probe_irq_on(); - rc_init_CD180(bp); /* Reset CD180 chip */ - rc_out(bp, CD180_CAR, 2); /* Select port 2 */ - rc_wait_CCR(bp); - rc_out(bp, CD180_CCR, CCR_TXEN); /* Enable transmitter */ - rc_out(bp, CD180_IER, IER_TXRDY);/* Enable tx empty intr */ - msleep(50); - irqs = probe_irq_off(irqs); - val1 = rc_in(bp, RC_BSR); /* Get Board Status reg */ - val2 = rc_in(bp, RC_ACK_TINT); /* ACK interrupt */ - rc_init_CD180(bp); /* Reset CD180 again */ - - if ((val1 & RC_BSR_TINT) || (val2 != (RC_ID | GIVR_IT_TX))) { - printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not " - "found.\n", board_No(bp), bp->base); - goto out_release; - } - } - - if (irqs <= 0) { - printk(KERN_ERR "rc%d: Can't find IRQ for RISCom/8 board " - "at 0x%03x.\n", board_No(bp), bp->base); - goto out_release; - } - bp->irq = irqs; - bp->flags |= RC_BOARD_PRESENT; - - printk(KERN_INFO "rc%d: RISCom/8 Rev. %c board detected at " - "0x%03x, IRQ %d.\n", - board_No(bp), - (rc_in(bp, CD180_GFRCR) & 0x0f) + 'A', /* Board revision */ - bp->base, bp->irq); - - return 0; -out_release: - rc_release_io_range(bp); - return 1; -} - -/* - * - * Interrupt processing routines. - * - */ - -static struct riscom_port *rc_get_port(struct riscom_board const *bp, - unsigned char const *what) -{ - unsigned char channel; - struct riscom_port *port; - - channel = rc_in(bp, CD180_GICR) >> GICR_CHAN_OFF; - if (channel < CD180_NCH) { - port = &rc_port[board_No(bp) * RC_NPORT + channel]; - if (port->port.flags & ASYNC_INITIALIZED) - return port; - } - printk(KERN_ERR "rc%d: %s interrupt from invalid port %d\n", - board_No(bp), what, channel); - return NULL; -} - -static void rc_receive_exc(struct riscom_board const *bp) -{ - struct riscom_port *port; - struct tty_struct *tty; - unsigned char status; - unsigned char ch, flag; - - port = rc_get_port(bp, "Receive"); - if (port == NULL) - return; - - tty = tty_port_tty_get(&port->port); - -#ifdef RC_REPORT_OVERRUN - status = rc_in(bp, CD180_RCSR); - if (status & RCSR_OE) - port->overrun++; - status &= port->mark_mask; -#else - status = rc_in(bp, CD180_RCSR) & port->mark_mask; -#endif - ch = rc_in(bp, CD180_RDR); - if (!status) - goto out; - if (status & RCSR_TOUT) { - printk(KERN_WARNING "rc%d: port %d: Receiver timeout. " - "Hardware problems ?\n", - board_No(bp), port_No(port)); - goto out; - - } else if (status & RCSR_BREAK) { - printk(KERN_INFO "rc%d: port %d: Handling break...\n", - board_No(bp), port_No(port)); - flag = TTY_BREAK; - if (tty && (port->port.flags & ASYNC_SAK)) - do_SAK(tty); - - } else if (status & RCSR_PE) - flag = TTY_PARITY; - - else if (status & RCSR_FE) - flag = TTY_FRAME; - - else if (status & RCSR_OE) - flag = TTY_OVERRUN; - else - flag = TTY_NORMAL; - - if (tty) { - tty_insert_flip_char(tty, ch, flag); - tty_flip_buffer_push(tty); - } -out: - tty_kref_put(tty); -} - -static void rc_receive(struct riscom_board const *bp) -{ - struct riscom_port *port; - struct tty_struct *tty; - unsigned char count; - - port = rc_get_port(bp, "Receive"); - if (port == NULL) - return; - - tty = tty_port_tty_get(&port->port); - - count = rc_in(bp, CD180_RDCR); - -#ifdef RC_REPORT_FIFO - port->hits[count > 8 ? 9 : count]++; -#endif - - while (count--) { - u8 ch = rc_in(bp, CD180_RDR); - if (tty) - tty_insert_flip_char(tty, ch, TTY_NORMAL); - } - if (tty) { - tty_flip_buffer_push(tty); - tty_kref_put(tty); - } -} - -static void rc_transmit(struct riscom_board const *bp) -{ - struct riscom_port *port; - struct tty_struct *tty; - unsigned char count; - - port = rc_get_port(bp, "Transmit"); - if (port == NULL) - return; - - tty = tty_port_tty_get(&port->port); - - if (port->IER & IER_TXEMPTY) { - /* FIFO drained */ - rc_out(bp, CD180_CAR, port_No(port)); - port->IER &= ~IER_TXEMPTY; - rc_out(bp, CD180_IER, port->IER); - goto out; - } - - if ((port->xmit_cnt <= 0 && !port->break_length) - || (tty && (tty->stopped || tty->hw_stopped))) { - rc_out(bp, CD180_CAR, port_No(port)); - port->IER &= ~IER_TXRDY; - rc_out(bp, CD180_IER, port->IER); - goto out; - } - - if (port->break_length) { - if (port->break_length > 0) { - if (port->COR2 & COR2_ETC) { - rc_out(bp, CD180_TDR, CD180_C_ESC); - rc_out(bp, CD180_TDR, CD180_C_SBRK); - port->COR2 &= ~COR2_ETC; - } - count = min_t(int, port->break_length, 0xff); - rc_out(bp, CD180_TDR, CD180_C_ESC); - rc_out(bp, CD180_TDR, CD180_C_DELAY); - rc_out(bp, CD180_TDR, count); - port->break_length -= count; - if (port->break_length == 0) - port->break_length--; - } else { - rc_out(bp, CD180_TDR, CD180_C_ESC); - rc_out(bp, CD180_TDR, CD180_C_EBRK); - rc_out(bp, CD180_COR2, port->COR2); - rc_wait_CCR(bp); - rc_out(bp, CD180_CCR, CCR_CORCHG2); - port->break_length = 0; - } - goto out; - } - - count = CD180_NFIFO; - do { - rc_out(bp, CD180_TDR, port->port.xmit_buf[port->xmit_tail++]); - port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1); - if (--port->xmit_cnt <= 0) - break; - } while (--count > 0); - - if (port->xmit_cnt <= 0) { - rc_out(bp, CD180_CAR, port_No(port)); - port->IER &= ~IER_TXRDY; - rc_out(bp, CD180_IER, port->IER); - } - if (tty && port->xmit_cnt <= port->wakeup_chars) - tty_wakeup(tty); -out: - tty_kref_put(tty); -} - -static void rc_check_modem(struct riscom_board const *bp) -{ - struct riscom_port *port; - struct tty_struct *tty; - unsigned char mcr; - - port = rc_get_port(bp, "Modem"); - if (port == NULL) - return; - - tty = tty_port_tty_get(&port->port); - - mcr = rc_in(bp, CD180_MCR); - if (mcr & MCR_CDCHG) { - if (rc_in(bp, CD180_MSVR) & MSVR_CD) - wake_up_interruptible(&port->port.open_wait); - else if (tty) - tty_hangup(tty); - } - -#ifdef RISCOM_BRAIN_DAMAGED_CTS - if (mcr & MCR_CTSCHG) { - if (rc_in(bp, CD180_MSVR) & MSVR_CTS) { - port->IER |= IER_TXRDY; - if (tty) { - tty->hw_stopped = 0; - if (port->xmit_cnt <= port->wakeup_chars) - tty_wakeup(tty); - } - } else { - if (tty) - tty->hw_stopped = 1; - port->IER &= ~IER_TXRDY; - } - rc_out(bp, CD180_IER, port->IER); - } - if (mcr & MCR_DSRCHG) { - if (rc_in(bp, CD180_MSVR) & MSVR_DSR) { - port->IER |= IER_TXRDY; - if (tty) { - tty->hw_stopped = 0; - if (port->xmit_cnt <= port->wakeup_chars) - tty_wakeup(tty); - } - } else { - if (tty) - tty->hw_stopped = 1; - port->IER &= ~IER_TXRDY; - } - rc_out(bp, CD180_IER, port->IER); - } -#endif /* RISCOM_BRAIN_DAMAGED_CTS */ - - /* Clear change bits */ - rc_out(bp, CD180_MCR, 0); - tty_kref_put(tty); -} - -/* The main interrupt processing routine */ -static irqreturn_t rc_interrupt(int dummy, void *dev_id) -{ - unsigned char status; - unsigned char ack; - struct riscom_board *bp = dev_id; - unsigned long loop = 0; - int handled = 0; - - if (!(bp->flags & RC_BOARD_ACTIVE)) - return IRQ_NONE; - - while ((++loop < 16) && ((status = ~(rc_in(bp, RC_BSR))) & - (RC_BSR_TOUT | RC_BSR_TINT | - RC_BSR_MINT | RC_BSR_RINT))) { - handled = 1; - if (status & RC_BSR_TOUT) - printk(KERN_WARNING "rc%d: Got timeout. Hardware " - "error?\n", board_No(bp)); - else if (status & RC_BSR_RINT) { - ack = rc_in(bp, RC_ACK_RINT); - if (ack == (RC_ID | GIVR_IT_RCV)) - rc_receive(bp); - else if (ack == (RC_ID | GIVR_IT_REXC)) - rc_receive_exc(bp); - else - printk(KERN_WARNING "rc%d: Bad receive ack " - "0x%02x.\n", - board_No(bp), ack); - } else if (status & RC_BSR_TINT) { - ack = rc_in(bp, RC_ACK_TINT); - if (ack == (RC_ID | GIVR_IT_TX)) - rc_transmit(bp); - else - printk(KERN_WARNING "rc%d: Bad transmit ack " - "0x%02x.\n", - board_No(bp), ack); - } else /* if (status & RC_BSR_MINT) */ { - ack = rc_in(bp, RC_ACK_MINT); - if (ack == (RC_ID | GIVR_IT_MODEM)) - rc_check_modem(bp); - else - printk(KERN_WARNING "rc%d: Bad modem ack " - "0x%02x.\n", - board_No(bp), ack); - } - rc_out(bp, CD180_EOIR, 0); /* Mark end of interrupt */ - rc_out(bp, RC_CTOUT, 0); /* Clear timeout flag */ - } - return IRQ_RETVAL(handled); -} - -/* - * Routines for open & close processing. - */ - -/* Called with disabled interrupts */ -static int rc_setup_board(struct riscom_board *bp) -{ - int error; - - if (bp->flags & RC_BOARD_ACTIVE) - return 0; - - error = request_irq(bp->irq, rc_interrupt, IRQF_DISABLED, - "RISCom/8", bp); - if (error) - return error; - - rc_out(bp, RC_CTOUT, 0); /* Just in case */ - bp->DTR = ~0; - rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */ - - bp->flags |= RC_BOARD_ACTIVE; - - return 0; -} - -/* Called with disabled interrupts */ -static void rc_shutdown_board(struct riscom_board *bp) -{ - if (!(bp->flags & RC_BOARD_ACTIVE)) - return; - - bp->flags &= ~RC_BOARD_ACTIVE; - - free_irq(bp->irq, NULL); - - bp->DTR = ~0; - rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */ - -} - -/* - * Setting up port characteristics. - * Must be called with disabled interrupts - */ -static void rc_change_speed(struct tty_struct *tty, struct riscom_board *bp, - struct riscom_port *port) -{ - unsigned long baud; - long tmp; - unsigned char cor1 = 0, cor3 = 0; - unsigned char mcor1 = 0, mcor2 = 0; - - port->IER = 0; - port->COR2 = 0; - port->MSVR = MSVR_RTS; - - baud = tty_get_baud_rate(tty); - - /* Select port on the board */ - rc_out(bp, CD180_CAR, port_No(port)); - - if (!baud) { - /* Drop DTR & exit */ - bp->DTR |= (1u << port_No(port)); - rc_out(bp, RC_DTR, bp->DTR); - return; - } else { - /* Set DTR on */ - bp->DTR &= ~(1u << port_No(port)); - rc_out(bp, RC_DTR, bp->DTR); - } - - /* - * Now we must calculate some speed depended things - */ - - /* Set baud rate for port */ - tmp = (((RC_OSCFREQ + baud/2) / baud + - CD180_TPC/2) / CD180_TPC); - - rc_out(bp, CD180_RBPRH, (tmp >> 8) & 0xff); - rc_out(bp, CD180_TBPRH, (tmp >> 8) & 0xff); - rc_out(bp, CD180_RBPRL, tmp & 0xff); - rc_out(bp, CD180_TBPRL, tmp & 0xff); - - baud = (baud + 5) / 10; /* Estimated CPS */ - - /* Two timer ticks seems enough to wakeup something like SLIP driver */ - tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO; - port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ? - SERIAL_XMIT_SIZE - 1 : tmp); - - /* Receiver timeout will be transmission time for 1.5 chars */ - tmp = (RISCOM_TPS + RISCOM_TPS/2 + baud/2) / baud; - tmp = (tmp > 0xff) ? 0xff : tmp; - rc_out(bp, CD180_RTPR, tmp); - - switch (C_CSIZE(tty)) { - case CS5: - cor1 |= COR1_5BITS; - break; - case CS6: - cor1 |= COR1_6BITS; - break; - case CS7: - cor1 |= COR1_7BITS; - break; - case CS8: - cor1 |= COR1_8BITS; - break; - } - if (C_CSTOPB(tty)) - cor1 |= COR1_2SB; - - cor1 |= COR1_IGNORE; - if (C_PARENB(tty)) { - cor1 |= COR1_NORMPAR; - if (C_PARODD(tty)) - cor1 |= COR1_ODDP; - if (I_INPCK(tty)) - cor1 &= ~COR1_IGNORE; - } - /* Set marking of some errors */ - port->mark_mask = RCSR_OE | RCSR_TOUT; - if (I_INPCK(tty)) - port->mark_mask |= RCSR_FE | RCSR_PE; - if (I_BRKINT(tty) || I_PARMRK(tty)) - port->mark_mask |= RCSR_BREAK; - if (I_IGNPAR(tty)) - port->mark_mask &= ~(RCSR_FE | RCSR_PE); - if (I_IGNBRK(tty)) { - port->mark_mask &= ~RCSR_BREAK; - if (I_IGNPAR(tty)) - /* Real raw mode. Ignore all */ - port->mark_mask &= ~RCSR_OE; - } - /* Enable Hardware Flow Control */ - if (C_CRTSCTS(tty)) { -#ifdef RISCOM_BRAIN_DAMAGED_CTS - port->IER |= IER_DSR | IER_CTS; - mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD; - mcor2 |= MCOR2_DSROD | MCOR2_CTSOD; - tty->hw_stopped = !(rc_in(bp, CD180_MSVR) & - (MSVR_CTS|MSVR_DSR)); -#else - port->COR2 |= COR2_CTSAE; -#endif - } - /* Enable Software Flow Control. FIXME: I'm not sure about this */ - /* Some people reported that it works, but I still doubt */ - if (I_IXON(tty)) { - port->COR2 |= COR2_TXIBE; - cor3 |= (COR3_FCT | COR3_SCDE); - if (I_IXANY(tty)) - port->COR2 |= COR2_IXM; - rc_out(bp, CD180_SCHR1, START_CHAR(tty)); - rc_out(bp, CD180_SCHR2, STOP_CHAR(tty)); - rc_out(bp, CD180_SCHR3, START_CHAR(tty)); - rc_out(bp, CD180_SCHR4, STOP_CHAR(tty)); - } - if (!C_CLOCAL(tty)) { - /* Enable CD check */ - port->IER |= IER_CD; - mcor1 |= MCOR1_CDZD; - mcor2 |= MCOR2_CDOD; - } - - if (C_CREAD(tty)) - /* Enable receiver */ - port->IER |= IER_RXD; - - /* Set input FIFO size (1-8 bytes) */ - cor3 |= RISCOM_RXFIFO; - /* Setting up CD180 channel registers */ - rc_out(bp, CD180_COR1, cor1); - rc_out(bp, CD180_COR2, port->COR2); - rc_out(bp, CD180_COR3, cor3); - /* Make CD180 know about registers change */ - rc_wait_CCR(bp); - rc_out(bp, CD180_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3); - /* Setting up modem option registers */ - rc_out(bp, CD180_MCOR1, mcor1); - rc_out(bp, CD180_MCOR2, mcor2); - /* Enable CD180 transmitter & receiver */ - rc_wait_CCR(bp); - rc_out(bp, CD180_CCR, CCR_TXEN | CCR_RXEN); - /* Enable interrupts */ - rc_out(bp, CD180_IER, port->IER); - /* And finally set RTS on */ - rc_out(bp, CD180_MSVR, port->MSVR); -} - -/* Must be called with interrupts enabled */ -static int rc_activate_port(struct tty_port *port, struct tty_struct *tty) -{ - struct riscom_port *rp = container_of(port, struct riscom_port, port); - struct riscom_board *bp = port_Board(rp); - unsigned long flags; - - if (tty_port_alloc_xmit_buf(port) < 0) - return -ENOMEM; - - spin_lock_irqsave(&riscom_lock, flags); - - clear_bit(TTY_IO_ERROR, &tty->flags); - bp->count++; - rp->xmit_cnt = rp->xmit_head = rp->xmit_tail = 0; - rc_change_speed(tty, bp, rp); - spin_unlock_irqrestore(&riscom_lock, flags); - return 0; -} - -/* Must be called with interrupts disabled */ -static void rc_shutdown_port(struct tty_struct *tty, - struct riscom_board *bp, struct riscom_port *port) -{ -#ifdef RC_REPORT_OVERRUN - printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n", - board_No(bp), port_No(port), port->overrun); -#endif -#ifdef RC_REPORT_FIFO - { - int i; - - printk(KERN_INFO "rc%d: port %d: FIFO hits [ ", - board_No(bp), port_No(port)); - for (i = 0; i < 10; i++) - printk("%ld ", port->hits[i]); - printk("].\n"); - } -#endif - tty_port_free_xmit_buf(&port->port); - - /* Select port */ - rc_out(bp, CD180_CAR, port_No(port)); - /* Reset port */ - rc_wait_CCR(bp); - rc_out(bp, CD180_CCR, CCR_SOFTRESET); - /* Disable all interrupts from this port */ - port->IER = 0; - rc_out(bp, CD180_IER, port->IER); - - set_bit(TTY_IO_ERROR, &tty->flags); - - if (--bp->count < 0) { - printk(KERN_INFO "rc%d: rc_shutdown_port: " - "bad board count: %d\n", - board_No(bp), bp->count); - bp->count = 0; - } - /* - * If this is the last opened port on the board - * shutdown whole board - */ - if (!bp->count) - rc_shutdown_board(bp); -} - -static int carrier_raised(struct tty_port *port) -{ - struct riscom_port *p = container_of(port, struct riscom_port, port); - struct riscom_board *bp = port_Board(p); - unsigned long flags; - int CD; - - spin_lock_irqsave(&riscom_lock, flags); - rc_out(bp, CD180_CAR, port_No(p)); - CD = rc_in(bp, CD180_MSVR) & MSVR_CD; - rc_out(bp, CD180_MSVR, MSVR_RTS); - bp->DTR &= ~(1u << port_No(p)); - rc_out(bp, RC_DTR, bp->DTR); - spin_unlock_irqrestore(&riscom_lock, flags); - return CD; -} - -static void dtr_rts(struct tty_port *port, int onoff) -{ - struct riscom_port *p = container_of(port, struct riscom_port, port); - struct riscom_board *bp = port_Board(p); - unsigned long flags; - - spin_lock_irqsave(&riscom_lock, flags); - bp->DTR &= ~(1u << port_No(p)); - if (onoff == 0) - bp->DTR |= (1u << port_No(p)); - rc_out(bp, RC_DTR, bp->DTR); - spin_unlock_irqrestore(&riscom_lock, flags); -} - -static int rc_open(struct tty_struct *tty, struct file *filp) -{ - int board; - int error; - struct riscom_port *port; - struct riscom_board *bp; - - board = RC_BOARD(tty->index); - if (board >= RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT)) - return -ENODEV; - - bp = &rc_board[board]; - port = rc_port + board * RC_NPORT + RC_PORT(tty->index); - if (rc_paranoia_check(port, tty->name, "rc_open")) - return -ENODEV; - - error = rc_setup_board(bp); - if (error) - return error; - - tty->driver_data = port; - return tty_port_open(&port->port, tty, filp); -} - -static void rc_flush_buffer(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - unsigned long flags; - - if (rc_paranoia_check(port, tty->name, "rc_flush_buffer")) - return; - - spin_lock_irqsave(&riscom_lock, flags); - port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; - spin_unlock_irqrestore(&riscom_lock, flags); - - tty_wakeup(tty); -} - -static void rc_close_port(struct tty_port *port) -{ - unsigned long flags; - struct riscom_port *rp = container_of(port, struct riscom_port, port); - struct riscom_board *bp = port_Board(rp); - unsigned long timeout; - - /* - * At this point we stop accepting input. To do this, we - * disable the receive line status interrupts, and tell the - * interrupt driver to stop checking the data ready bit in the - * line status register. - */ - - spin_lock_irqsave(&riscom_lock, flags); - rp->IER &= ~IER_RXD; - - rp->IER &= ~IER_TXRDY; - rp->IER |= IER_TXEMPTY; - rc_out(bp, CD180_CAR, port_No(rp)); - rc_out(bp, CD180_IER, rp->IER); - /* - * Before we drop DTR, make sure the UART transmitter - * has completely drained; this is especially - * important if there is a transmit FIFO! - */ - timeout = jiffies + HZ; - while (rp->IER & IER_TXEMPTY) { - spin_unlock_irqrestore(&riscom_lock, flags); - msleep_interruptible(jiffies_to_msecs(rp->timeout)); - spin_lock_irqsave(&riscom_lock, flags); - if (time_after(jiffies, timeout)) - break; - } - rc_shutdown_port(port->tty, bp, rp); - spin_unlock_irqrestore(&riscom_lock, flags); -} - -static void rc_close(struct tty_struct *tty, struct file *filp) -{ - struct riscom_port *port = tty->driver_data; - - if (!port || rc_paranoia_check(port, tty->name, "close")) - return; - tty_port_close(&port->port, tty, filp); -} - -static int rc_write(struct tty_struct *tty, - const unsigned char *buf, int count) -{ - struct riscom_port *port = tty->driver_data; - struct riscom_board *bp; - int c, total = 0; - unsigned long flags; - - if (rc_paranoia_check(port, tty->name, "rc_write")) - return 0; - - bp = port_Board(port); - - while (1) { - spin_lock_irqsave(&riscom_lock, flags); - - c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, - SERIAL_XMIT_SIZE - port->xmit_head)); - if (c <= 0) - break; /* lock continues to be held */ - - memcpy(port->port.xmit_buf + port->xmit_head, buf, c); - port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); - port->xmit_cnt += c; - - spin_unlock_irqrestore(&riscom_lock, flags); - - buf += c; - count -= c; - total += c; - } - - if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped && - !(port->IER & IER_TXRDY)) { - port->IER |= IER_TXRDY; - rc_out(bp, CD180_CAR, port_No(port)); - rc_out(bp, CD180_IER, port->IER); - } - - spin_unlock_irqrestore(&riscom_lock, flags); - - return total; -} - -static int rc_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct riscom_port *port = tty->driver_data; - unsigned long flags; - int ret = 0; - - if (rc_paranoia_check(port, tty->name, "rc_put_char")) - return 0; - - spin_lock_irqsave(&riscom_lock, flags); - - if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) - goto out; - - port->port.xmit_buf[port->xmit_head++] = ch; - port->xmit_head &= SERIAL_XMIT_SIZE - 1; - port->xmit_cnt++; - ret = 1; - -out: - spin_unlock_irqrestore(&riscom_lock, flags); - return ret; -} - -static void rc_flush_chars(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - unsigned long flags; - - if (rc_paranoia_check(port, tty->name, "rc_flush_chars")) - return; - - if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped) - return; - - spin_lock_irqsave(&riscom_lock, flags); - - port->IER |= IER_TXRDY; - rc_out(port_Board(port), CD180_CAR, port_No(port)); - rc_out(port_Board(port), CD180_IER, port->IER); - - spin_unlock_irqrestore(&riscom_lock, flags); -} - -static int rc_write_room(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - int ret; - - if (rc_paranoia_check(port, tty->name, "rc_write_room")) - return 0; - - ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1; - if (ret < 0) - ret = 0; - return ret; -} - -static int rc_chars_in_buffer(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - - if (rc_paranoia_check(port, tty->name, "rc_chars_in_buffer")) - return 0; - - return port->xmit_cnt; -} - -static int rc_tiocmget(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - struct riscom_board *bp; - unsigned char status; - unsigned int result; - unsigned long flags; - - if (rc_paranoia_check(port, tty->name, __func__)) - return -ENODEV; - - bp = port_Board(port); - - spin_lock_irqsave(&riscom_lock, flags); - - rc_out(bp, CD180_CAR, port_No(port)); - status = rc_in(bp, CD180_MSVR); - result = rc_in(bp, RC_RI) & (1u << port_No(port)) ? 0 : TIOCM_RNG; - - spin_unlock_irqrestore(&riscom_lock, flags); - - result |= ((status & MSVR_RTS) ? TIOCM_RTS : 0) - | ((status & MSVR_DTR) ? TIOCM_DTR : 0) - | ((status & MSVR_CD) ? TIOCM_CAR : 0) - | ((status & MSVR_DSR) ? TIOCM_DSR : 0) - | ((status & MSVR_CTS) ? TIOCM_CTS : 0); - return result; -} - -static int rc_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct riscom_port *port = tty->driver_data; - unsigned long flags; - struct riscom_board *bp; - - if (rc_paranoia_check(port, tty->name, __func__)) - return -ENODEV; - - bp = port_Board(port); - - spin_lock_irqsave(&riscom_lock, flags); - - if (set & TIOCM_RTS) - port->MSVR |= MSVR_RTS; - if (set & TIOCM_DTR) - bp->DTR &= ~(1u << port_No(port)); - - if (clear & TIOCM_RTS) - port->MSVR &= ~MSVR_RTS; - if (clear & TIOCM_DTR) - bp->DTR |= (1u << port_No(port)); - - rc_out(bp, CD180_CAR, port_No(port)); - rc_out(bp, CD180_MSVR, port->MSVR); - rc_out(bp, RC_DTR, bp->DTR); - - spin_unlock_irqrestore(&riscom_lock, flags); - - return 0; -} - -static int rc_send_break(struct tty_struct *tty, int length) -{ - struct riscom_port *port = tty->driver_data; - struct riscom_board *bp = port_Board(port); - unsigned long flags; - - if (length == 0 || length == -1) - return -EOPNOTSUPP; - - spin_lock_irqsave(&riscom_lock, flags); - - port->break_length = RISCOM_TPS / HZ * length; - port->COR2 |= COR2_ETC; - port->IER |= IER_TXRDY; - rc_out(bp, CD180_CAR, port_No(port)); - rc_out(bp, CD180_COR2, port->COR2); - rc_out(bp, CD180_IER, port->IER); - rc_wait_CCR(bp); - rc_out(bp, CD180_CCR, CCR_CORCHG2); - rc_wait_CCR(bp); - - spin_unlock_irqrestore(&riscom_lock, flags); - return 0; -} - -static int rc_set_serial_info(struct tty_struct *tty, struct riscom_port *port, - struct serial_struct __user *newinfo) -{ - struct serial_struct tmp; - struct riscom_board *bp = port_Board(port); - int change_speed; - - if (copy_from_user(&tmp, newinfo, sizeof(tmp))) - return -EFAULT; - - mutex_lock(&port->port.mutex); - change_speed = ((port->port.flags & ASYNC_SPD_MASK) != - (tmp.flags & ASYNC_SPD_MASK)); - - if (!capable(CAP_SYS_ADMIN)) { - if ((tmp.close_delay != port->port.close_delay) || - (tmp.closing_wait != port->port.closing_wait) || - ((tmp.flags & ~ASYNC_USR_MASK) != - (port->port.flags & ~ASYNC_USR_MASK))) { - mutex_unlock(&port->port.mutex); - return -EPERM; - } - port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | - (tmp.flags & ASYNC_USR_MASK)); - } else { - port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) | - (tmp.flags & ASYNC_FLAGS)); - port->port.close_delay = tmp.close_delay; - port->port.closing_wait = tmp.closing_wait; - } - if (change_speed) { - unsigned long flags; - - spin_lock_irqsave(&riscom_lock, flags); - rc_change_speed(tty, bp, port); - spin_unlock_irqrestore(&riscom_lock, flags); - } - mutex_unlock(&port->port.mutex); - return 0; -} - -static int rc_get_serial_info(struct riscom_port *port, - struct serial_struct __user *retinfo) -{ - struct serial_struct tmp; - struct riscom_board *bp = port_Board(port); - - memset(&tmp, 0, sizeof(tmp)); - tmp.type = PORT_CIRRUS; - tmp.line = port - rc_port; - - mutex_lock(&port->port.mutex); - tmp.port = bp->base; - tmp.irq = bp->irq; - tmp.flags = port->port.flags; - tmp.baud_base = (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC; - tmp.close_delay = port->port.close_delay * HZ/100; - tmp.closing_wait = port->port.closing_wait * HZ/100; - mutex_unlock(&port->port.mutex); - tmp.xmit_fifo_size = CD180_NFIFO; - return copy_to_user(retinfo, &tmp, sizeof(tmp)) ? -EFAULT : 0; -} - -static int rc_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct riscom_port *port = tty->driver_data; - void __user *argp = (void __user *)arg; - int retval; - - if (rc_paranoia_check(port, tty->name, "rc_ioctl")) - return -ENODEV; - - switch (cmd) { - case TIOCGSERIAL: - retval = rc_get_serial_info(port, argp); - break; - case TIOCSSERIAL: - retval = rc_set_serial_info(tty, port, argp); - break; - default: - retval = -ENOIOCTLCMD; - } - return retval; -} - -static void rc_throttle(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - struct riscom_board *bp; - unsigned long flags; - - if (rc_paranoia_check(port, tty->name, "rc_throttle")) - return; - bp = port_Board(port); - - spin_lock_irqsave(&riscom_lock, flags); - port->MSVR &= ~MSVR_RTS; - rc_out(bp, CD180_CAR, port_No(port)); - if (I_IXOFF(tty)) { - rc_wait_CCR(bp); - rc_out(bp, CD180_CCR, CCR_SSCH2); - rc_wait_CCR(bp); - } - rc_out(bp, CD180_MSVR, port->MSVR); - spin_unlock_irqrestore(&riscom_lock, flags); -} - -static void rc_unthrottle(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - struct riscom_board *bp; - unsigned long flags; - - if (rc_paranoia_check(port, tty->name, "rc_unthrottle")) - return; - bp = port_Board(port); - - spin_lock_irqsave(&riscom_lock, flags); - port->MSVR |= MSVR_RTS; - rc_out(bp, CD180_CAR, port_No(port)); - if (I_IXOFF(tty)) { - rc_wait_CCR(bp); - rc_out(bp, CD180_CCR, CCR_SSCH1); - rc_wait_CCR(bp); - } - rc_out(bp, CD180_MSVR, port->MSVR); - spin_unlock_irqrestore(&riscom_lock, flags); -} - -static void rc_stop(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - struct riscom_board *bp; - unsigned long flags; - - if (rc_paranoia_check(port, tty->name, "rc_stop")) - return; - - bp = port_Board(port); - - spin_lock_irqsave(&riscom_lock, flags); - port->IER &= ~IER_TXRDY; - rc_out(bp, CD180_CAR, port_No(port)); - rc_out(bp, CD180_IER, port->IER); - spin_unlock_irqrestore(&riscom_lock, flags); -} - -static void rc_start(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - struct riscom_board *bp; - unsigned long flags; - - if (rc_paranoia_check(port, tty->name, "rc_start")) - return; - - bp = port_Board(port); - - spin_lock_irqsave(&riscom_lock, flags); - - if (port->xmit_cnt && port->port.xmit_buf && !(port->IER & IER_TXRDY)) { - port->IER |= IER_TXRDY; - rc_out(bp, CD180_CAR, port_No(port)); - rc_out(bp, CD180_IER, port->IER); - } - spin_unlock_irqrestore(&riscom_lock, flags); -} - -static void rc_hangup(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - - if (rc_paranoia_check(port, tty->name, "rc_hangup")) - return; - - tty_port_hangup(&port->port); -} - -static void rc_set_termios(struct tty_struct *tty, - struct ktermios *old_termios) -{ - struct riscom_port *port = tty->driver_data; - unsigned long flags; - - if (rc_paranoia_check(port, tty->name, "rc_set_termios")) - return; - - spin_lock_irqsave(&riscom_lock, flags); - rc_change_speed(tty, port_Board(port), port); - spin_unlock_irqrestore(&riscom_lock, flags); - - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - rc_start(tty); - } -} - -static const struct tty_operations riscom_ops = { - .open = rc_open, - .close = rc_close, - .write = rc_write, - .put_char = rc_put_char, - .flush_chars = rc_flush_chars, - .write_room = rc_write_room, - .chars_in_buffer = rc_chars_in_buffer, - .flush_buffer = rc_flush_buffer, - .ioctl = rc_ioctl, - .throttle = rc_throttle, - .unthrottle = rc_unthrottle, - .set_termios = rc_set_termios, - .stop = rc_stop, - .start = rc_start, - .hangup = rc_hangup, - .tiocmget = rc_tiocmget, - .tiocmset = rc_tiocmset, - .break_ctl = rc_send_break, -}; - -static const struct tty_port_operations riscom_port_ops = { - .carrier_raised = carrier_raised, - .dtr_rts = dtr_rts, - .shutdown = rc_close_port, - .activate = rc_activate_port, -}; - - -static int __init rc_init_drivers(void) -{ - int error; - int i; - - riscom_driver = alloc_tty_driver(RC_NBOARD * RC_NPORT); - if (!riscom_driver) - return -ENOMEM; - - riscom_driver->owner = THIS_MODULE; - riscom_driver->name = "ttyL"; - riscom_driver->major = RISCOM8_NORMAL_MAJOR; - riscom_driver->type = TTY_DRIVER_TYPE_SERIAL; - riscom_driver->subtype = SERIAL_TYPE_NORMAL; - riscom_driver->init_termios = tty_std_termios; - riscom_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - riscom_driver->init_termios.c_ispeed = 9600; - riscom_driver->init_termios.c_ospeed = 9600; - riscom_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_HARDWARE_BREAK; - tty_set_operations(riscom_driver, &riscom_ops); - error = tty_register_driver(riscom_driver); - if (error != 0) { - put_tty_driver(riscom_driver); - printk(KERN_ERR "rc: Couldn't register RISCom/8 driver, " - "error = %d\n", error); - return 1; - } - memset(rc_port, 0, sizeof(rc_port)); - for (i = 0; i < RC_NPORT * RC_NBOARD; i++) { - tty_port_init(&rc_port[i].port); - rc_port[i].port.ops = &riscom_port_ops; - rc_port[i].magic = RISCOM8_MAGIC; - } - return 0; -} - -static void rc_release_drivers(void) -{ - tty_unregister_driver(riscom_driver); - put_tty_driver(riscom_driver); -} - -#ifndef MODULE -/* - * Called at boot time. - * - * You can specify IO base for up to RC_NBOARD cards, - * using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt. - * Note that there will be no probing at default - * addresses in this case. - * - */ -static int __init riscom8_setup(char *str) -{ - int ints[RC_NBOARD]; - int i; - - str = get_options(str, ARRAY_SIZE(ints), ints); - - for (i = 0; i < RC_NBOARD; i++) { - if (i < ints[0]) - rc_board[i].base = ints[i+1]; - else - rc_board[i].base = 0; - } - return 1; -} - -__setup("riscom8=", riscom8_setup); -#endif - -static char banner[] __initdata = - KERN_INFO "rc: SDL RISCom/8 card driver v1.1, (c) D.Gorodchanin " - "1994-1996.\n"; -static char no_boards_msg[] __initdata = - KERN_INFO "rc: No RISCom/8 boards detected.\n"; - -/* - * This routine must be called by kernel at boot time - */ -static int __init riscom8_init(void) -{ - int i; - int found = 0; - - printk(banner); - - if (rc_init_drivers()) - return -EIO; - - for (i = 0; i < RC_NBOARD; i++) - if (rc_board[i].base && !rc_probe(&rc_board[i])) - found++; - if (!found) { - rc_release_drivers(); - printk(no_boards_msg); - return -EIO; - } - return 0; -} - -#ifdef MODULE -static int iobase; -static int iobase1; -static int iobase2; -static int iobase3; -module_param(iobase, int, 0); -module_param(iobase1, int, 0); -module_param(iobase2, int, 0); -module_param(iobase3, int, 0); - -MODULE_LICENSE("GPL"); -MODULE_ALIAS_CHARDEV_MAJOR(RISCOM8_NORMAL_MAJOR); -#endif /* MODULE */ - -/* - * You can setup up to 4 boards (current value of RC_NBOARD) - * by specifying "iobase=0xXXX iobase1=0xXXX ..." as insmod parameter. - * - */ -static int __init riscom8_init_module(void) -{ -#ifdef MODULE - int i; - - if (iobase || iobase1 || iobase2 || iobase3) { - for (i = 0; i < RC_NBOARD; i++) - rc_board[i].base = 0; - } - - if (iobase) - rc_board[0].base = iobase; - if (iobase1) - rc_board[1].base = iobase1; - if (iobase2) - rc_board[2].base = iobase2; - if (iobase3) - rc_board[3].base = iobase3; -#endif /* MODULE */ - - return riscom8_init(); -} - -static void __exit riscom8_exit_module(void) -{ - int i; - - rc_release_drivers(); - for (i = 0; i < RC_NBOARD; i++) - if (rc_board[i].flags & RC_BOARD_PRESENT) - rc_release_io_range(&rc_board[i]); - -} - -module_init(riscom8_init_module); -module_exit(riscom8_exit_module); diff --git a/drivers/char/riscom8.h b/drivers/char/riscom8.h deleted file mode 100644 index c9876b3f9714..000000000000 --- a/drivers/char/riscom8.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * linux/drivers/char/riscom8.h -- RISCom/8 multiport serial driver. - * - * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) - * - * This code is loosely based on the Linux serial driver, written by - * Linus Torvalds, Theodore T'so and others. The RISCom/8 card - * programming info was obtained from various drivers for other OSes - * (FreeBSD, ISC, etc), but no source code from those drivers were - * directly included in this driver. - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __LINUX_RISCOM8_H -#define __LINUX_RISCOM8_H - -#include - -#ifdef __KERNEL__ - -#define RC_NBOARD 4 -/* NOTE: RISCom decoder recognizes 16 addresses... */ -#define RC_NPORT 8 -#define RC_BOARD(line) (((line) >> 3) & 0x07) -#define RC_PORT(line) ((line) & (RC_NPORT - 1)) - -/* Ticks per sec. Used for setting receiver timeout and break length */ -#define RISCOM_TPS 4000 - -/* Yeah, after heavy testing I decided it must be 6. - * Sure, You can change it if needed. - */ -#define RISCOM_RXFIFO 6 /* Max. receiver FIFO size (1-8) */ - -#define RISCOM8_MAGIC 0x0907 - -#define RC_IOBASE1 0x220 -#define RC_IOBASE2 0x240 -#define RC_IOBASE3 0x250 -#define RC_IOBASE4 0x260 - -struct riscom_board { - unsigned long flags; - unsigned short base; - unsigned char irq; - signed char count; - unsigned char DTR; -}; - -#define RC_BOARD_PRESENT 0x00000001 -#define RC_BOARD_ACTIVE 0x00000002 - -struct riscom_port { - int magic; - struct tty_port port; - int baud_base; - int timeout; - int custom_divisor; - int xmit_head; - int xmit_tail; - int xmit_cnt; - short wakeup_chars; - short break_length; - unsigned char mark_mask; - unsigned char IER; - unsigned char MSVR; - unsigned char COR2; -#ifdef RC_REPORT_OVERRUN - unsigned long overrun; -#endif -#ifdef RC_REPORT_FIFO - unsigned long hits[10]; -#endif -}; - -#endif /* __KERNEL__ */ -#endif /* __LINUX_RISCOM8_H */ diff --git a/drivers/char/riscom8_reg.h b/drivers/char/riscom8_reg.h deleted file mode 100644 index a32475ed0d18..000000000000 --- a/drivers/char/riscom8_reg.h +++ /dev/null @@ -1,254 +0,0 @@ -/* - * linux/drivers/char/riscom8_reg.h -- RISCom/8 multiport serial driver. - */ - -/* - * Definitions for RISCom/8 Async Mux card by SDL Communications, Inc. - */ - -/* - * Address mapping between Cirrus Logic CD180 chip internal registers - * and ISA port addresses: - * - * CL-CD180 A6 A5 A4 A3 A2 A1 A0 - * ISA A15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0 - */ -#define RC_TO_ISA(r) ((((r)&0x07)<<1) | (((r)&~0x07)<<7)) - - -/* RISCom/8 On-Board Registers (assuming address translation) */ - -#define RC_RI 0x100 /* Ring Indicator Register (R/O) */ -#define RC_DTR 0x100 /* DTR Register (W/O) */ -#define RC_BSR 0x101 /* Board Status Register (R/O) */ -#define RC_CTOUT 0x101 /* Clear Timeout (W/O) */ - - -/* Board Status Register */ - -#define RC_BSR_TOUT 0x08 /* Hardware Timeout */ -#define RC_BSR_RINT 0x04 /* Receiver Interrupt */ -#define RC_BSR_TINT 0x02 /* Transmitter Interrupt */ -#define RC_BSR_MINT 0x01 /* Modem Ctl Interrupt */ - - -/* On-board oscillator frequency (in Hz) */ -#define RC_OSCFREQ 9830400 - -/* Values of choice for Interrupt ACKs */ -#define RC_ACK_MINT 0x81 /* goes to PILR1 */ -#define RC_ACK_RINT 0x82 /* goes to PILR3 */ -#define RC_ACK_TINT 0x84 /* goes to PILR2 */ - -/* Chip ID (sorry, only one chip now) */ -#define RC_ID 0x10 - -/* Definitions for Cirrus Logic CL-CD180 8-port async mux chip */ - -#define CD180_NCH 8 /* Total number of channels */ -#define CD180_TPC 16 /* Ticks per character */ -#define CD180_NFIFO 8 /* TX FIFO size */ - - -/* Global registers */ - -#define CD180_GIVR 0x40 /* Global Interrupt Vector Register */ -#define CD180_GICR 0x41 /* Global Interrupting Channel Register */ -#define CD180_PILR1 0x61 /* Priority Interrupt Level Register 1 */ -#define CD180_PILR2 0x62 /* Priority Interrupt Level Register 2 */ -#define CD180_PILR3 0x63 /* Priority Interrupt Level Register 3 */ -#define CD180_CAR 0x64 /* Channel Access Register */ -#define CD180_GFRCR 0x6b /* Global Firmware Revision Code Register */ -#define CD180_PPRH 0x70 /* Prescaler Period Register High */ -#define CD180_PPRL 0x71 /* Prescaler Period Register Low */ -#define CD180_RDR 0x78 /* Receiver Data Register */ -#define CD180_RCSR 0x7a /* Receiver Character Status Register */ -#define CD180_TDR 0x7b /* Transmit Data Register */ -#define CD180_EOIR 0x7f /* End of Interrupt Register */ - - -/* Channel Registers */ - -#define CD180_CCR 0x01 /* Channel Command Register */ -#define CD180_IER 0x02 /* Interrupt Enable Register */ -#define CD180_COR1 0x03 /* Channel Option Register 1 */ -#define CD180_COR2 0x04 /* Channel Option Register 2 */ -#define CD180_COR3 0x05 /* Channel Option Register 3 */ -#define CD180_CCSR 0x06 /* Channel Control Status Register */ -#define CD180_RDCR 0x07 /* Receive Data Count Register */ -#define CD180_SCHR1 0x09 /* Special Character Register 1 */ -#define CD180_SCHR2 0x0a /* Special Character Register 2 */ -#define CD180_SCHR3 0x0b /* Special Character Register 3 */ -#define CD180_SCHR4 0x0c /* Special Character Register 4 */ -#define CD180_MCOR1 0x10 /* Modem Change Option 1 Register */ -#define CD180_MCOR2 0x11 /* Modem Change Option 2 Register */ -#define CD180_MCR 0x12 /* Modem Change Register */ -#define CD180_RTPR 0x18 /* Receive Timeout Period Register */ -#define CD180_MSVR 0x28 /* Modem Signal Value Register */ -#define CD180_RBPRH 0x31 /* Receive Baud Rate Period Register High */ -#define CD180_RBPRL 0x32 /* Receive Baud Rate Period Register Low */ -#define CD180_TBPRH 0x39 /* Transmit Baud Rate Period Register High */ -#define CD180_TBPRL 0x3a /* Transmit Baud Rate Period Register Low */ - - -/* Global Interrupt Vector Register (R/W) */ - -#define GIVR_ITMASK 0x07 /* Interrupt type mask */ -#define GIVR_IT_MODEM 0x01 /* Modem Signal Change Interrupt */ -#define GIVR_IT_TX 0x02 /* Transmit Data Interrupt */ -#define GIVR_IT_RCV 0x03 /* Receive Good Data Interrupt */ -#define GIVR_IT_REXC 0x07 /* Receive Exception Interrupt */ - - -/* Global Interrupt Channel Register (R/W) */ - -#define GICR_CHAN 0x1c /* Channel Number Mask */ -#define GICR_CHAN_OFF 2 /* Channel Number Offset */ - - -/* Channel Address Register (R/W) */ - -#define CAR_CHAN 0x07 /* Channel Number Mask */ -#define CAR_A7 0x08 /* A7 Address Extension (unused) */ - - -/* Receive Character Status Register (R/O) */ - -#define RCSR_TOUT 0x80 /* Rx Timeout */ -#define RCSR_SCDET 0x70 /* Special Character Detected Mask */ -#define RCSR_NO_SC 0x00 /* No Special Characters Detected */ -#define RCSR_SC_1 0x10 /* Special Char 1 (or 1 & 3) Detected */ -#define RCSR_SC_2 0x20 /* Special Char 2 (or 2 & 4) Detected */ -#define RCSR_SC_3 0x30 /* Special Char 3 Detected */ -#define RCSR_SC_4 0x40 /* Special Char 4 Detected */ -#define RCSR_BREAK 0x08 /* Break has been detected */ -#define RCSR_PE 0x04 /* Parity Error */ -#define RCSR_FE 0x02 /* Frame Error */ -#define RCSR_OE 0x01 /* Overrun Error */ - - -/* Channel Command Register (R/W) (commands in groups can be OR-ed) */ - -#define CCR_HARDRESET 0x81 /* Reset the chip */ - -#define CCR_SOFTRESET 0x80 /* Soft Channel Reset */ - -#define CCR_CORCHG1 0x42 /* Channel Option Register 1 Changed */ -#define CCR_CORCHG2 0x44 /* Channel Option Register 2 Changed */ -#define CCR_CORCHG3 0x48 /* Channel Option Register 3 Changed */ - -#define CCR_SSCH1 0x21 /* Send Special Character 1 */ - -#define CCR_SSCH2 0x22 /* Send Special Character 2 */ - -#define CCR_SSCH3 0x23 /* Send Special Character 3 */ - -#define CCR_SSCH4 0x24 /* Send Special Character 4 */ - -#define CCR_TXEN 0x18 /* Enable Transmitter */ -#define CCR_RXEN 0x12 /* Enable Receiver */ - -#define CCR_TXDIS 0x14 /* Disable Transmitter */ -#define CCR_RXDIS 0x11 /* Disable Receiver */ - - -/* Interrupt Enable Register (R/W) */ - -#define IER_DSR 0x80 /* Enable interrupt on DSR change */ -#define IER_CD 0x40 /* Enable interrupt on CD change */ -#define IER_CTS 0x20 /* Enable interrupt on CTS change */ -#define IER_RXD 0x10 /* Enable interrupt on Receive Data */ -#define IER_RXSC 0x08 /* Enable interrupt on Receive Spec. Char */ -#define IER_TXRDY 0x04 /* Enable interrupt on TX FIFO empty */ -#define IER_TXEMPTY 0x02 /* Enable interrupt on TX completely empty */ -#define IER_RET 0x01 /* Enable interrupt on RX Exc. Timeout */ - - -/* Channel Option Register 1 (R/W) */ - -#define COR1_ODDP 0x80 /* Odd Parity */ -#define COR1_PARMODE 0x60 /* Parity Mode mask */ -#define COR1_NOPAR 0x00 /* No Parity */ -#define COR1_FORCEPAR 0x20 /* Force Parity */ -#define COR1_NORMPAR 0x40 /* Normal Parity */ -#define COR1_IGNORE 0x10 /* Ignore Parity on RX */ -#define COR1_STOPBITS 0x0c /* Number of Stop Bits */ -#define COR1_1SB 0x00 /* 1 Stop Bit */ -#define COR1_15SB 0x04 /* 1.5 Stop Bits */ -#define COR1_2SB 0x08 /* 2 Stop Bits */ -#define COR1_CHARLEN 0x03 /* Character Length */ -#define COR1_5BITS 0x00 /* 5 bits */ -#define COR1_6BITS 0x01 /* 6 bits */ -#define COR1_7BITS 0x02 /* 7 bits */ -#define COR1_8BITS 0x03 /* 8 bits */ - - -/* Channel Option Register 2 (R/W) */ - -#define COR2_IXM 0x80 /* Implied XON mode */ -#define COR2_TXIBE 0x40 /* Enable In-Band (XON/XOFF) Flow Control */ -#define COR2_ETC 0x20 /* Embedded Tx Commands Enable */ -#define COR2_LLM 0x10 /* Local Loopback Mode */ -#define COR2_RLM 0x08 /* Remote Loopback Mode */ -#define COR2_RTSAO 0x04 /* RTS Automatic Output Enable */ -#define COR2_CTSAE 0x02 /* CTS Automatic Enable */ -#define COR2_DSRAE 0x01 /* DSR Automatic Enable */ - - -/* Channel Option Register 3 (R/W) */ - -#define COR3_XONCH 0x80 /* XON is a pair of characters (1 & 3) */ -#define COR3_XOFFCH 0x40 /* XOFF is a pair of characters (2 & 4) */ -#define COR3_FCT 0x20 /* Flow-Control Transparency Mode */ -#define COR3_SCDE 0x10 /* Special Character Detection Enable */ -#define COR3_RXTH 0x0f /* RX FIFO Threshold value (1-8) */ - - -/* Channel Control Status Register (R/O) */ - -#define CCSR_RXEN 0x80 /* Receiver Enabled */ -#define CCSR_RXFLOFF 0x40 /* Receive Flow Off (XOFF was sent) */ -#define CCSR_RXFLON 0x20 /* Receive Flow On (XON was sent) */ -#define CCSR_TXEN 0x08 /* Transmitter Enabled */ -#define CCSR_TXFLOFF 0x04 /* Transmit Flow Off (got XOFF) */ -#define CCSR_TXFLON 0x02 /* Transmit Flow On (got XON) */ - - -/* Modem Change Option Register 1 (R/W) */ - -#define MCOR1_DSRZD 0x80 /* Detect 0->1 transition of DSR */ -#define MCOR1_CDZD 0x40 /* Detect 0->1 transition of CD */ -#define MCOR1_CTSZD 0x20 /* Detect 0->1 transition of CTS */ -#define MCOR1_DTRTH 0x0f /* Auto DTR flow control Threshold (1-8) */ -#define MCOR1_NODTRFC 0x0 /* Automatic DTR flow control disabled */ - - -/* Modem Change Option Register 2 (R/W) */ - -#define MCOR2_DSROD 0x80 /* Detect 1->0 transition of DSR */ -#define MCOR2_CDOD 0x40 /* Detect 1->0 transition of CD */ -#define MCOR2_CTSOD 0x20 /* Detect 1->0 transition of CTS */ - - -/* Modem Change Register (R/W) */ - -#define MCR_DSRCHG 0x80 /* DSR Changed */ -#define MCR_CDCHG 0x40 /* CD Changed */ -#define MCR_CTSCHG 0x20 /* CTS Changed */ - - -/* Modem Signal Value Register (R/W) */ - -#define MSVR_DSR 0x80 /* Current state of DSR input */ -#define MSVR_CD 0x40 /* Current state of CD input */ -#define MSVR_CTS 0x20 /* Current state of CTS input */ -#define MSVR_DTR 0x02 /* Current state of DTR output */ -#define MSVR_RTS 0x01 /* Current state of RTS output */ - - -/* Escape characters */ - -#define CD180_C_ESC 0x00 /* Escape character */ -#define CD180_C_SBRK 0x81 /* Start sending BREAK */ -#define CD180_C_DELAY 0x82 /* Delay output */ -#define CD180_C_EBRK 0x83 /* Stop sending BREAK */ diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c deleted file mode 100644 index 674af6933978..000000000000 --- a/drivers/char/serial167.c +++ /dev/null @@ -1,2489 +0,0 @@ -/* - * linux/drivers/char/serial167.c - * - * Driver for MVME166/7 board serial ports, which are via a CD2401. - * Based very much on cyclades.c. - * - * MVME166/7 work by Richard Hirst [richard@sleepie.demon.co.uk] - * - * ============================================================== - * - * static char rcsid[] = - * "$Revision: 1.36.1.4 $$Date: 1995/03/29 06:14:14 $"; - * - * linux/kernel/cyclades.c - * - * Maintained by Marcio Saito (cyclades@netcom.com) and - * Randolph Bentson (bentson@grieg.seaslug.org) - * - * Much of the design and some of the code came from serial.c - * which was copyright (C) 1991, 1992 Linus Torvalds. It was - * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92, - * and then fixed as suggested by Michael K. Johnson 12/12/92. - * - * This version does not support shared irq's. - * - * $Log: cyclades.c,v $ - * Revision 1.36.1.4 1995/03/29 06:14:14 bentson - * disambiguate between Cyclom-16Y and Cyclom-32Ye; - * - * Changes: - * - * 200 lines of changes record removed - RGH 11-10-95, starting work on - * converting this to drive serial ports on mvme166 (cd2401). - * - * Arnaldo Carvalho de Melo - 2000/08/25 - * - get rid of verify_area - * - use get_user to access memory from userspace in set_threshold, - * set_default_threshold and set_timeout - * - don't use the panic function in serial167_init - * - do resource release on failure on serial167_init - * - include missing restore_flags in mvme167_serial_console_setup - * - * Kars de Jong - 2004/09/06 - * - replace bottom half handler with task queue handler - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#define SERIAL_PARANOIA_CHECK -#undef SERIAL_DEBUG_OPEN -#undef SERIAL_DEBUG_THROTTLE -#undef SERIAL_DEBUG_OTHER -#undef SERIAL_DEBUG_IO -#undef SERIAL_DEBUG_COUNT -#undef SERIAL_DEBUG_DTR -#undef CYCLOM_16Y_HACK -#define CYCLOM_ENABLE_MONITORING - -#define WAKEUP_CHARS 256 - -#define STD_COM_FLAGS (0) - -static struct tty_driver *cy_serial_driver; -extern int serial_console; -static struct cyclades_port *serial_console_info = NULL; -static unsigned int serial_console_cflag = 0; -u_char initial_console_speed; - -/* Base address of cd2401 chip on mvme166/7 */ - -#define BASE_ADDR (0xfff45000) -#define pcc2chip ((volatile u_char *)0xfff42000) -#define PccSCCMICR 0x1d -#define PccSCCTICR 0x1e -#define PccSCCRICR 0x1f -#define PccTPIACKR 0x25 -#define PccRPIACKR 0x27 -#define PccIMLR 0x3f - -/* This is the per-port data structure */ -struct cyclades_port cy_port[] = { - /* CARD# */ - {-1}, /* ttyS0 */ - {-1}, /* ttyS1 */ - {-1}, /* ttyS2 */ - {-1}, /* ttyS3 */ -}; - -#define NR_PORTS ARRAY_SIZE(cy_port) - -/* - * This is used to look up the divisor speeds and the timeouts - * We're normally limited to 15 distinct baud rates. The extra - * are accessed via settings in info->flags. - * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - * 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - * HI VHI - */ -static int baud_table[] = { - 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, - 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200, 150000, - 0 -}; - -#if 0 -static char baud_co[] = { /* 25 MHz clock option table */ - /* value => 00 01 02 03 04 */ - /* divide by 8 32 128 512 2048 */ - 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, - 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static char baud_bpr[] = { /* 25 MHz baud rate period table */ - 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3, - 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15 -}; -#endif - -/* I think 166 brd clocks 2401 at 20MHz.... */ - -/* These values are written directly to tcor, and >> 5 for writing to rcor */ -static u_char baud_co[] = { /* 20 MHz clock option table */ - 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x60, 0x60, 0x40, - 0x40, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -/* These values written directly to tbpr/rbpr */ -static u_char baud_bpr[] = { /* 20 MHz baud rate period table */ - 0x00, 0xc0, 0x80, 0x58, 0x6c, 0x40, 0xc0, 0x81, 0x40, 0x81, - 0x57, 0x40, 0x81, 0x40, 0x81, 0x40, 0x2b, 0x20, 0x15, 0x10 -}; - -static u_char baud_cor4[] = { /* receive threshold */ - 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, - 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07 -}; - -static void shutdown(struct cyclades_port *); -static int startup(struct cyclades_port *); -static void cy_throttle(struct tty_struct *); -static void cy_unthrottle(struct tty_struct *); -static void config_setup(struct cyclades_port *); -#ifdef CYCLOM_SHOW_STATUS -static void show_status(int); -#endif - -/* - * I have my own version of udelay(), as it is needed when initialising - * the chip, before the delay loop has been calibrated. Should probably - * reference one of the vmechip2 or pccchip2 counter for an accurate - * delay, but this wild guess will do for now. - */ - -void my_udelay(long us) -{ - u_char x; - volatile u_char *p = &x; - int i; - - while (us--) - for (i = 100; i; i--) - x |= *p; -} - -static inline int serial_paranoia_check(struct cyclades_port *info, char *name, - const char *routine) -{ -#ifdef SERIAL_PARANOIA_CHECK - if (!info) { - printk("Warning: null cyclades_port for (%s) in %s\n", name, - routine); - return 1; - } - - if (info < &cy_port[0] || info >= &cy_port[NR_PORTS]) { - printk("Warning: cyclades_port out of range for (%s) in %s\n", - name, routine); - return 1; - } - - if (info->magic != CYCLADES_MAGIC) { - printk("Warning: bad magic number for serial struct (%s) in " - "%s\n", name, routine); - return 1; - } -#endif - return 0; -} /* serial_paranoia_check */ - -#if 0 -/* The following diagnostic routines allow the driver to spew - information on the screen, even (especially!) during interrupts. - */ -void SP(char *data) -{ - unsigned long flags; - local_irq_save(flags); - printk(KERN_EMERG "%s", data); - local_irq_restore(flags); -} - -char scrn[2]; -void CP(char data) -{ - unsigned long flags; - local_irq_save(flags); - scrn[0] = data; - printk(KERN_EMERG "%c", scrn); - local_irq_restore(flags); -} /* CP */ - -void CP1(int data) -{ - (data < 10) ? CP(data + '0') : CP(data + 'A' - 10); -} /* CP1 */ -void CP2(int data) -{ - CP1((data >> 4) & 0x0f); - CP1(data & 0x0f); -} /* CP2 */ -void CP4(int data) -{ - CP2((data >> 8) & 0xff); - CP2(data & 0xff); -} /* CP4 */ -void CP8(long data) -{ - CP4((data >> 16) & 0xffff); - CP4(data & 0xffff); -} /* CP8 */ -#endif - -/* This routine waits up to 1000 micro-seconds for the previous - command to the Cirrus chip to complete and then issues the - new command. An error is returned if the previous command - didn't finish within the time limit. - */ -u_short write_cy_cmd(volatile u_char * base_addr, u_char cmd) -{ - unsigned long flags; - volatile int i; - - local_irq_save(flags); - /* Check to see that the previous command has completed */ - for (i = 0; i < 100; i++) { - if (base_addr[CyCCR] == 0) { - break; - } - my_udelay(10L); - } - /* if the CCR never cleared, the previous command - didn't finish within the "reasonable time" */ - if (i == 10) { - local_irq_restore(flags); - return (-1); - } - - /* Issue the new command */ - base_addr[CyCCR] = cmd; - local_irq_restore(flags); - return (0); -} /* write_cy_cmd */ - -/* cy_start and cy_stop provide software output flow control as a - function of XON/XOFF, software CTS, and other such stuff. */ - -static void cy_stop(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - int channel; - unsigned long flags; - -#ifdef SERIAL_DEBUG_OTHER - printk("cy_stop %s\n", tty->name); /* */ -#endif - - if (serial_paranoia_check(info, tty->name, "cy_stop")) - return; - - channel = info->line; - - local_irq_save(flags); - base_addr[CyCAR] = (u_char) (channel); /* index channel */ - base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); - local_irq_restore(flags); -} /* cy_stop */ - -static void cy_start(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - int channel; - unsigned long flags; - -#ifdef SERIAL_DEBUG_OTHER - printk("cy_start %s\n", tty->name); /* */ -#endif - - if (serial_paranoia_check(info, tty->name, "cy_start")) - return; - - channel = info->line; - - local_irq_save(flags); - base_addr[CyCAR] = (u_char) (channel); - base_addr[CyIER] |= CyTxMpty; - local_irq_restore(flags); -} /* cy_start */ - -/* The real interrupt service routines are called - whenever the card wants its hand held--chars - received, out buffer empty, modem change, etc. - */ -static irqreturn_t cd2401_rxerr_interrupt(int irq, void *dev_id) -{ - struct tty_struct *tty; - struct cyclades_port *info; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - unsigned char err, rfoc; - int channel; - char data; - - /* determine the channel and change to that context */ - channel = (u_short) (base_addr[CyLICR] >> 2); - info = &cy_port[channel]; - info->last_active = jiffies; - - if ((err = base_addr[CyRISR]) & CyTIMEOUT) { - /* This is a receive timeout interrupt, ignore it */ - base_addr[CyREOIR] = CyNOTRANS; - return IRQ_HANDLED; - } - - /* Read a byte of data if there is any - assume the error - * is associated with this character */ - - if ((rfoc = base_addr[CyRFOC]) != 0) - data = base_addr[CyRDR]; - else - data = 0; - - /* if there is nowhere to put the data, discard it */ - if (info->tty == 0) { - base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; - return IRQ_HANDLED; - } else { /* there is an open port for this data */ - tty = info->tty; - if (err & info->ignore_status_mask) { - base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; - return IRQ_HANDLED; - } - if (tty_buffer_request_room(tty, 1) != 0) { - if (err & info->read_status_mask) { - if (err & CyBREAK) { - tty_insert_flip_char(tty, data, - TTY_BREAK); - if (info->flags & ASYNC_SAK) { - do_SAK(tty); - } - } else if (err & CyFRAME) { - tty_insert_flip_char(tty, data, - TTY_FRAME); - } else if (err & CyPARITY) { - tty_insert_flip_char(tty, data, - TTY_PARITY); - } else if (err & CyOVERRUN) { - tty_insert_flip_char(tty, 0, - TTY_OVERRUN); - /* - If the flip buffer itself is - overflowing, we still lose - the next incoming character. - */ - if (tty_buffer_request_room(tty, 1) != - 0) { - tty_insert_flip_char(tty, data, - TTY_FRAME); - } - /* These two conditions may imply */ - /* a normal read should be done. */ - /* else if(data & CyTIMEOUT) */ - /* else if(data & CySPECHAR) */ - } else { - tty_insert_flip_char(tty, 0, - TTY_NORMAL); - } - } else { - tty_insert_flip_char(tty, data, TTY_NORMAL); - } - } else { - /* there was a software buffer overrun - and nothing could be done about it!!! */ - } - } - tty_schedule_flip(tty); - /* end of service */ - base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; - return IRQ_HANDLED; -} /* cy_rxerr_interrupt */ - -static irqreturn_t cd2401_modem_interrupt(int irq, void *dev_id) -{ - struct cyclades_port *info; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - int channel; - int mdm_change; - int mdm_status; - - /* determine the channel and change to that context */ - channel = (u_short) (base_addr[CyLICR] >> 2); - info = &cy_port[channel]; - info->last_active = jiffies; - - mdm_change = base_addr[CyMISR]; - mdm_status = base_addr[CyMSVR1]; - - if (info->tty == 0) { /* nowhere to put the data, ignore it */ - ; - } else { - if ((mdm_change & CyDCD) - && (info->flags & ASYNC_CHECK_CD)) { - if (mdm_status & CyDCD) { -/* CP('!'); */ - wake_up_interruptible(&info->open_wait); - } else { -/* CP('@'); */ - tty_hangup(info->tty); - wake_up_interruptible(&info->open_wait); - info->flags &= ~ASYNC_NORMAL_ACTIVE; - } - } - if ((mdm_change & CyCTS) - && (info->flags & ASYNC_CTS_FLOW)) { - if (info->tty->stopped) { - if (mdm_status & CyCTS) { - /* !!! cy_start isn't used because... */ - info->tty->stopped = 0; - base_addr[CyIER] |= CyTxMpty; - tty_wakeup(info->tty); - } - } else { - if (!(mdm_status & CyCTS)) { - /* !!! cy_stop isn't used because... */ - info->tty->stopped = 1; - base_addr[CyIER] &= - ~(CyTxMpty | CyTxRdy); - } - } - } - if (mdm_status & CyDSR) { - } - } - base_addr[CyMEOIR] = 0; - return IRQ_HANDLED; -} /* cy_modem_interrupt */ - -static irqreturn_t cd2401_tx_interrupt(int irq, void *dev_id) -{ - struct cyclades_port *info; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - int channel; - int char_count, saved_cnt; - int outch; - - /* determine the channel and change to that context */ - channel = (u_short) (base_addr[CyLICR] >> 2); - - /* validate the port number (as configured and open) */ - if ((channel < 0) || (NR_PORTS <= channel)) { - base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); - base_addr[CyTEOIR] = CyNOTRANS; - return IRQ_HANDLED; - } - info = &cy_port[channel]; - info->last_active = jiffies; - if (info->tty == 0) { - base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); - base_addr[CyTEOIR] = CyNOTRANS; - return IRQ_HANDLED; - } - - /* load the on-chip space available for outbound data */ - saved_cnt = char_count = base_addr[CyTFTC]; - - if (info->x_char) { /* send special char */ - outch = info->x_char; - base_addr[CyTDR] = outch; - char_count--; - info->x_char = 0; - } - - if (info->x_break) { - /* The Cirrus chip requires the "Embedded Transmit - Commands" of start break, delay, and end break - sequences to be sent. The duration of the - break is given in TICs, which runs at HZ - (typically 100) and the PPR runs at 200 Hz, - so the delay is duration * 200/HZ, and thus a - break can run from 1/100 sec to about 5/4 sec. - Need to check these values - RGH 141095. - */ - base_addr[CyTDR] = 0; /* start break */ - base_addr[CyTDR] = 0x81; - base_addr[CyTDR] = 0; /* delay a bit */ - base_addr[CyTDR] = 0x82; - base_addr[CyTDR] = info->x_break * 200 / HZ; - base_addr[CyTDR] = 0; /* terminate break */ - base_addr[CyTDR] = 0x83; - char_count -= 7; - info->x_break = 0; - } - - while (char_count > 0) { - if (!info->xmit_cnt) { - base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); - break; - } - if (info->xmit_buf == 0) { - base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); - break; - } - if (info->tty->stopped || info->tty->hw_stopped) { - base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); - break; - } - /* Because the Embedded Transmit Commands have been - enabled, we must check to see if the escape - character, NULL, is being sent. If it is, we - must ensure that there is room for it to be - doubled in the output stream. Therefore we - no longer advance the pointer when the character - is fetched, but rather wait until after the check - for a NULL output character. (This is necessary - because there may not be room for the two chars - needed to send a NULL. - */ - outch = info->xmit_buf[info->xmit_tail]; - if (outch) { - info->xmit_cnt--; - info->xmit_tail = (info->xmit_tail + 1) - & (PAGE_SIZE - 1); - base_addr[CyTDR] = outch; - char_count--; - } else { - if (char_count > 1) { - info->xmit_cnt--; - info->xmit_tail = (info->xmit_tail + 1) - & (PAGE_SIZE - 1); - base_addr[CyTDR] = outch; - base_addr[CyTDR] = 0; - char_count--; - char_count--; - } else { - break; - } - } - } - - if (info->xmit_cnt < WAKEUP_CHARS) - tty_wakeup(info->tty); - - base_addr[CyTEOIR] = (char_count != saved_cnt) ? 0 : CyNOTRANS; - return IRQ_HANDLED; -} /* cy_tx_interrupt */ - -static irqreturn_t cd2401_rx_interrupt(int irq, void *dev_id) -{ - struct tty_struct *tty; - struct cyclades_port *info; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - int channel; - char data; - int char_count; - int save_cnt; - - /* determine the channel and change to that context */ - channel = (u_short) (base_addr[CyLICR] >> 2); - info = &cy_port[channel]; - info->last_active = jiffies; - save_cnt = char_count = base_addr[CyRFOC]; - - /* if there is nowhere to put the data, discard it */ - if (info->tty == 0) { - while (char_count--) { - data = base_addr[CyRDR]; - } - } else { /* there is an open port for this data */ - tty = info->tty; - /* load # characters available from the chip */ - -#ifdef CYCLOM_ENABLE_MONITORING - ++info->mon.int_count; - info->mon.char_count += char_count; - if (char_count > info->mon.char_max) - info->mon.char_max = char_count; - info->mon.char_last = char_count; -#endif - while (char_count--) { - data = base_addr[CyRDR]; - tty_insert_flip_char(tty, data, TTY_NORMAL); -#ifdef CYCLOM_16Y_HACK - udelay(10L); -#endif - } - tty_schedule_flip(tty); - } - /* end of service */ - base_addr[CyREOIR] = save_cnt ? 0 : CyNOTRANS; - return IRQ_HANDLED; -} /* cy_rx_interrupt */ - -/* This is called whenever a port becomes active; - interrupts are enabled and DTR & RTS are turned on. - */ -static int startup(struct cyclades_port *info) -{ - unsigned long flags; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - int channel; - - if (info->flags & ASYNC_INITIALIZED) { - return 0; - } - - if (!info->type) { - if (info->tty) { - set_bit(TTY_IO_ERROR, &info->tty->flags); - } - return 0; - } - if (!info->xmit_buf) { - info->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); - if (!info->xmit_buf) { - return -ENOMEM; - } - } - - config_setup(info); - - channel = info->line; - -#ifdef SERIAL_DEBUG_OPEN - printk("startup channel %d\n", channel); -#endif - - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; - write_cy_cmd(base_addr, CyENB_RCVR | CyENB_XMTR); - - base_addr[CyCAR] = (u_char) channel; /* !!! Is this needed? */ - base_addr[CyMSVR1] = CyRTS; -/* CP('S');CP('1'); */ - base_addr[CyMSVR2] = CyDTR; - -#ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: raising DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], - base_addr[CyMSVR2]); -#endif - - base_addr[CyIER] |= CyRxData; - info->flags |= ASYNC_INITIALIZED; - - if (info->tty) { - clear_bit(TTY_IO_ERROR, &info->tty->flags); - } - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - - local_irq_restore(flags); - -#ifdef SERIAL_DEBUG_OPEN - printk(" done\n"); -#endif - return 0; -} /* startup */ - -void start_xmit(struct cyclades_port *info) -{ - unsigned long flags; - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - - channel = info->line; - local_irq_save(flags); - base_addr[CyCAR] = channel; - base_addr[CyIER] |= CyTxMpty; - local_irq_restore(flags); -} /* start_xmit */ - -/* - * This routine shuts down a serial port; interrupts are disabled, - * and DTR is dropped if the hangup on close termio flag is on. - */ -static void shutdown(struct cyclades_port *info) -{ - unsigned long flags; - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - - if (!(info->flags & ASYNC_INITIALIZED)) { -/* CP('$'); */ - return; - } - - channel = info->line; - -#ifdef SERIAL_DEBUG_OPEN - printk("shutdown channel %d\n", channel); -#endif - - /* !!! REALLY MUST WAIT FOR LAST CHARACTER TO BE - SENT BEFORE DROPPING THE LINE !!! (Perhaps - set some flag that is read when XMTY happens.) - Other choices are to delay some fixed interval - or schedule some later processing. - */ - local_irq_save(flags); - if (info->xmit_buf) { - free_page((unsigned long)info->xmit_buf); - info->xmit_buf = NULL; - } - - base_addr[CyCAR] = (u_char) channel; - if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { - base_addr[CyMSVR1] = 0; -/* CP('C');CP('1'); */ - base_addr[CyMSVR2] = 0; -#ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: dropping DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], - base_addr[CyMSVR2]); -#endif - } - write_cy_cmd(base_addr, CyDIS_RCVR); - /* it may be appropriate to clear _XMIT at - some later date (after testing)!!! */ - - if (info->tty) { - set_bit(TTY_IO_ERROR, &info->tty->flags); - } - info->flags &= ~ASYNC_INITIALIZED; - local_irq_restore(flags); - -#ifdef SERIAL_DEBUG_OPEN - printk(" done\n"); -#endif -} /* shutdown */ - -/* - * This routine finds or computes the various line characteristics. - */ -static void config_setup(struct cyclades_port *info) -{ - unsigned long flags; - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - unsigned cflag; - int i; - unsigned char ti, need_init_chan = 0; - - if (!info->tty || !info->tty->termios) { - return; - } - if (info->line == -1) { - return; - } - cflag = info->tty->termios->c_cflag; - - /* baud rate */ - i = cflag & CBAUD; -#ifdef CBAUDEX -/* Starting with kernel 1.1.65, there is direct support for - higher baud rates. The following code supports those - changes. The conditional aspect allows this driver to be - used for earlier as well as later kernel versions. (The - mapping is slightly different from serial.c because there - is still the possibility of supporting 75 kbit/sec with - the Cyclades board.) - */ - if (i & CBAUDEX) { - if (i == B57600) - i = 16; - else if (i == B115200) - i = 18; -#ifdef B78600 - else if (i == B78600) - i = 17; -#endif - else - info->tty->termios->c_cflag &= ~CBAUDEX; - } -#endif - if (i == 15) { - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - i += 1; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - i += 3; - } - /* Don't ever change the speed of the console port. It will - * run at the speed specified in bootinfo, or at 19.2K */ - /* Actually, it should run at whatever speed 166Bug was using */ - /* Note info->timeout isn't used at present */ - if (info != serial_console_info) { - info->tbpr = baud_bpr[i]; /* Tx BPR */ - info->tco = baud_co[i]; /* Tx CO */ - info->rbpr = baud_bpr[i]; /* Rx BPR */ - info->rco = baud_co[i] >> 5; /* Rx CO */ - if (baud_table[i] == 134) { - info->timeout = - (info->xmit_fifo_size * HZ * 30 / 269) + 2; - /* get it right for 134.5 baud */ - } else if (baud_table[i]) { - info->timeout = - (info->xmit_fifo_size * HZ * 15 / baud_table[i]) + - 2; - /* this needs to be propagated into the card info */ - } else { - info->timeout = 0; - } - } - /* By tradition (is it a standard?) a baud rate of zero - implies the line should be/has been closed. A bit - later in this routine such a test is performed. */ - - /* byte size and parity */ - info->cor7 = 0; - info->cor6 = 0; - info->cor5 = 0; - info->cor4 = (info->default_threshold ? info->default_threshold : baud_cor4[i]); /* receive threshold */ - /* Following two lines added 101295, RGH. */ - /* It is obviously wrong to access CyCORx, and not info->corx here, - * try and remember to fix it later! */ - channel = info->line; - base_addr[CyCAR] = (u_char) channel; - if (C_CLOCAL(info->tty)) { - if (base_addr[CyIER] & CyMdmCh) - base_addr[CyIER] &= ~CyMdmCh; /* without modem intr */ - /* ignore 1->0 modem transitions */ - if (base_addr[CyCOR4] & (CyDSR | CyCTS | CyDCD)) - base_addr[CyCOR4] &= ~(CyDSR | CyCTS | CyDCD); - /* ignore 0->1 modem transitions */ - if (base_addr[CyCOR5] & (CyDSR | CyCTS | CyDCD)) - base_addr[CyCOR5] &= ~(CyDSR | CyCTS | CyDCD); - } else { - if ((base_addr[CyIER] & CyMdmCh) != CyMdmCh) - base_addr[CyIER] |= CyMdmCh; /* with modem intr */ - /* act on 1->0 modem transitions */ - if ((base_addr[CyCOR4] & (CyDSR | CyCTS | CyDCD)) != - (CyDSR | CyCTS | CyDCD)) - base_addr[CyCOR4] |= CyDSR | CyCTS | CyDCD; - /* act on 0->1 modem transitions */ - if ((base_addr[CyCOR5] & (CyDSR | CyCTS | CyDCD)) != - (CyDSR | CyCTS | CyDCD)) - base_addr[CyCOR5] |= CyDSR | CyCTS | CyDCD; - } - info->cor3 = (cflag & CSTOPB) ? Cy_2_STOP : Cy_1_STOP; - info->cor2 = CyETC; - switch (cflag & CSIZE) { - case CS5: - info->cor1 = Cy_5_BITS; - break; - case CS6: - info->cor1 = Cy_6_BITS; - break; - case CS7: - info->cor1 = Cy_7_BITS; - break; - case CS8: - info->cor1 = Cy_8_BITS; - break; - } - if (cflag & PARENB) { - if (cflag & PARODD) { - info->cor1 |= CyPARITY_O; - } else { - info->cor1 |= CyPARITY_E; - } - } else { - info->cor1 |= CyPARITY_NONE; - } - - /* CTS flow control flag */ -#if 0 - /* Don't complcate matters for now! RGH 141095 */ - if (cflag & CRTSCTS) { - info->flags |= ASYNC_CTS_FLOW; - info->cor2 |= CyCtsAE; - } else { - info->flags &= ~ASYNC_CTS_FLOW; - info->cor2 &= ~CyCtsAE; - } -#endif - if (cflag & CLOCAL) - info->flags &= ~ASYNC_CHECK_CD; - else - info->flags |= ASYNC_CHECK_CD; - - /*********************************************** - The hardware option, CyRtsAO, presents RTS when - the chip has characters to send. Since most modems - use RTS as reverse (inbound) flow control, this - option is not used. If inbound flow control is - necessary, DTR can be programmed to provide the - appropriate signals for use with a non-standard - cable. Contact Marcio Saito for details. - ***********************************************/ - - channel = info->line; - - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; - - /* CyCMR set once only in mvme167_init_serial() */ - if (base_addr[CyLICR] != channel << 2) - base_addr[CyLICR] = channel << 2; - if (base_addr[CyLIVR] != 0x5c) - base_addr[CyLIVR] = 0x5c; - - /* tx and rx baud rate */ - - if (base_addr[CyCOR1] != info->cor1) - need_init_chan = 1; - if (base_addr[CyTCOR] != info->tco) - base_addr[CyTCOR] = info->tco; - if (base_addr[CyTBPR] != info->tbpr) - base_addr[CyTBPR] = info->tbpr; - if (base_addr[CyRCOR] != info->rco) - base_addr[CyRCOR] = info->rco; - if (base_addr[CyRBPR] != info->rbpr) - base_addr[CyRBPR] = info->rbpr; - - /* set line characteristics according configuration */ - - if (base_addr[CySCHR1] != START_CHAR(info->tty)) - base_addr[CySCHR1] = START_CHAR(info->tty); - if (base_addr[CySCHR2] != STOP_CHAR(info->tty)) - base_addr[CySCHR2] = STOP_CHAR(info->tty); - if (base_addr[CySCRL] != START_CHAR(info->tty)) - base_addr[CySCRL] = START_CHAR(info->tty); - if (base_addr[CySCRH] != START_CHAR(info->tty)) - base_addr[CySCRH] = START_CHAR(info->tty); - if (base_addr[CyCOR1] != info->cor1) - base_addr[CyCOR1] = info->cor1; - if (base_addr[CyCOR2] != info->cor2) - base_addr[CyCOR2] = info->cor2; - if (base_addr[CyCOR3] != info->cor3) - base_addr[CyCOR3] = info->cor3; - if (base_addr[CyCOR4] != info->cor4) - base_addr[CyCOR4] = info->cor4; - if (base_addr[CyCOR5] != info->cor5) - base_addr[CyCOR5] = info->cor5; - if (base_addr[CyCOR6] != info->cor6) - base_addr[CyCOR6] = info->cor6; - if (base_addr[CyCOR7] != info->cor7) - base_addr[CyCOR7] = info->cor7; - - if (need_init_chan) - write_cy_cmd(base_addr, CyINIT_CHAN); - - base_addr[CyCAR] = (u_char) channel; /* !!! Is this needed? */ - - /* 2ms default rx timeout */ - ti = info->default_timeout ? info->default_timeout : 0x02; - if (base_addr[CyRTPRL] != ti) - base_addr[CyRTPRL] = ti; - if (base_addr[CyRTPRH] != 0) - base_addr[CyRTPRH] = 0; - - /* Set up RTS here also ????? RGH 141095 */ - if (i == 0) { /* baud rate is zero, turn off line */ - if ((base_addr[CyMSVR2] & CyDTR) == CyDTR) - base_addr[CyMSVR2] = 0; -#ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: dropping DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], - base_addr[CyMSVR2]); -#endif - } else { - if ((base_addr[CyMSVR2] & CyDTR) != CyDTR) - base_addr[CyMSVR2] = CyDTR; -#ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: raising DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], - base_addr[CyMSVR2]); -#endif - } - - if (info->tty) { - clear_bit(TTY_IO_ERROR, &info->tty->flags); - } - - local_irq_restore(flags); - -} /* config_setup */ - -static int cy_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct cyclades_port *info = tty->driver_data; - unsigned long flags; - -#ifdef SERIAL_DEBUG_IO - printk("cy_put_char %s(0x%02x)\n", tty->name, ch); -#endif - - if (serial_paranoia_check(info, tty->name, "cy_put_char")) - return 0; - - if (!info->xmit_buf) - return 0; - - local_irq_save(flags); - if (info->xmit_cnt >= PAGE_SIZE - 1) { - local_irq_restore(flags); - return 0; - } - - info->xmit_buf[info->xmit_head++] = ch; - info->xmit_head &= PAGE_SIZE - 1; - info->xmit_cnt++; - local_irq_restore(flags); - return 1; -} /* cy_put_char */ - -static void cy_flush_chars(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - unsigned long flags; - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - -#ifdef SERIAL_DEBUG_IO - printk("cy_flush_chars %s\n", tty->name); /* */ -#endif - - if (serial_paranoia_check(info, tty->name, "cy_flush_chars")) - return; - - if (info->xmit_cnt <= 0 || tty->stopped - || tty->hw_stopped || !info->xmit_buf) - return; - - channel = info->line; - - local_irq_save(flags); - base_addr[CyCAR] = channel; - base_addr[CyIER] |= CyTxMpty; - local_irq_restore(flags); -} /* cy_flush_chars */ - -/* This routine gets called when tty_write has put something into - the write_queue. If the port is not already transmitting stuff, - start it off by enabling interrupts. The interrupt service - routine will then ensure that the characters are sent. If the - port is already active, there is no need to kick it. - */ -static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) -{ - struct cyclades_port *info = tty->driver_data; - unsigned long flags; - int c, total = 0; - -#ifdef SERIAL_DEBUG_IO - printk("cy_write %s\n", tty->name); /* */ -#endif - - if (serial_paranoia_check(info, tty->name, "cy_write")) { - return 0; - } - - if (!info->xmit_buf) { - return 0; - } - - while (1) { - local_irq_save(flags); - c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - if (c <= 0) { - local_irq_restore(flags); - break; - } - - memcpy(info->xmit_buf + info->xmit_head, buf, c); - info->xmit_head = - (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1); - info->xmit_cnt += c; - local_irq_restore(flags); - - buf += c; - count -= c; - total += c; - } - - if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { - start_xmit(info); - } - return total; -} /* cy_write */ - -static int cy_write_room(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - int ret; - -#ifdef SERIAL_DEBUG_IO - printk("cy_write_room %s\n", tty->name); /* */ -#endif - - if (serial_paranoia_check(info, tty->name, "cy_write_room")) - return 0; - ret = PAGE_SIZE - info->xmit_cnt - 1; - if (ret < 0) - ret = 0; - return ret; -} /* cy_write_room */ - -static int cy_chars_in_buffer(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - -#ifdef SERIAL_DEBUG_IO - printk("cy_chars_in_buffer %s %d\n", tty->name, info->xmit_cnt); /* */ -#endif - - if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer")) - return 0; - - return info->xmit_cnt; -} /* cy_chars_in_buffer */ - -static void cy_flush_buffer(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - unsigned long flags; - -#ifdef SERIAL_DEBUG_IO - printk("cy_flush_buffer %s\n", tty->name); /* */ -#endif - - if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) - return; - local_irq_save(flags); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - local_irq_restore(flags); - tty_wakeup(tty); -} /* cy_flush_buffer */ - -/* This routine is called by the upper-layer tty layer to signal - that incoming characters should be throttled or that the - throttle should be released. - */ -static void cy_throttle(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - unsigned long flags; - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("throttle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); - printk("cy_throttle %s\n", tty->name); -#endif - - if (serial_paranoia_check(info, tty->name, "cy_nthrottle")) { - return; - } - - if (I_IXOFF(tty)) { - info->x_char = STOP_CHAR(tty); - /* Should use the "Send Special Character" feature!!! */ - } - - channel = info->line; - - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; - base_addr[CyMSVR1] = 0; - local_irq_restore(flags); -} /* cy_throttle */ - -static void cy_unthrottle(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - unsigned long flags; - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("throttle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); - printk("cy_unthrottle %s\n", tty->name); -#endif - - if (serial_paranoia_check(info, tty->name, "cy_nthrottle")) { - return; - } - - if (I_IXOFF(tty)) { - info->x_char = START_CHAR(tty); - /* Should use the "Send Special Character" feature!!! */ - } - - channel = info->line; - - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; - base_addr[CyMSVR1] = CyRTS; - local_irq_restore(flags); -} /* cy_unthrottle */ - -static int -get_serial_info(struct cyclades_port *info, - struct serial_struct __user * retinfo) -{ - struct serial_struct tmp; - -/* CP('g'); */ - if (!retinfo) - return -EFAULT; - memset(&tmp, 0, sizeof(tmp)); - tmp.type = info->type; - tmp.line = info->line; - tmp.port = info->line; - tmp.irq = 0; - tmp.flags = info->flags; - tmp.baud_base = 0; /*!!! */ - tmp.close_delay = info->close_delay; - tmp.custom_divisor = 0; /*!!! */ - tmp.hub6 = 0; /*!!! */ - return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; -} /* get_serial_info */ - -static int -set_serial_info(struct cyclades_port *info, - struct serial_struct __user * new_info) -{ - struct serial_struct new_serial; - struct cyclades_port old_info; - -/* CP('s'); */ - if (!new_info) - return -EFAULT; - if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) - return -EFAULT; - old_info = *info; - - if (!capable(CAP_SYS_ADMIN)) { - if ((new_serial.close_delay != info->close_delay) || - ((new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) != - (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK))) - return -EPERM; - info->flags = ((info->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - goto check_and_exit; - } - - /* - * OK, past this point, all the error checking has been done. - * At this point, we start making changes..... - */ - - info->flags = ((info->flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS)); - info->close_delay = new_serial.close_delay; - -check_and_exit: - if (info->flags & ASYNC_INITIALIZED) { - config_setup(info); - return 0; - } - return startup(info); -} /* set_serial_info */ - -static int cy_tiocmget(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - int channel; - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - unsigned long flags; - unsigned char status; - - channel = info->line; - - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; - status = base_addr[CyMSVR1] | base_addr[CyMSVR2]; - local_irq_restore(flags); - - return ((status & CyRTS) ? TIOCM_RTS : 0) - | ((status & CyDTR) ? TIOCM_DTR : 0) - | ((status & CyDCD) ? TIOCM_CAR : 0) - | ((status & CyDSR) ? TIOCM_DSR : 0) - | ((status & CyCTS) ? TIOCM_CTS : 0); -} /* cy_tiocmget */ - -static int -cy_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) -{ - struct cyclades_port *info = tty->driver_data; - int channel; - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - unsigned long flags; - - channel = info->line; - - if (set & TIOCM_RTS) { - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; - base_addr[CyMSVR1] = CyRTS; - local_irq_restore(flags); - } - if (set & TIOCM_DTR) { - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; -/* CP('S');CP('2'); */ - base_addr[CyMSVR2] = CyDTR; -#ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: raising DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], - base_addr[CyMSVR2]); -#endif - local_irq_restore(flags); - } - - if (clear & TIOCM_RTS) { - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; - base_addr[CyMSVR1] = 0; - local_irq_restore(flags); - } - if (clear & TIOCM_DTR) { - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; -/* CP('C');CP('2'); */ - base_addr[CyMSVR2] = 0; -#ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: dropping DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], - base_addr[CyMSVR2]); -#endif - local_irq_restore(flags); - } - - return 0; -} /* set_modem_info */ - -static void send_break(struct cyclades_port *info, int duration) -{ /* Let the transmit ISR take care of this (since it - requires stuffing characters into the output stream). - */ - info->x_break = duration; - if (!info->xmit_cnt) { - start_xmit(info); - } -} /* send_break */ - -static int -get_mon_info(struct cyclades_port *info, struct cyclades_monitor __user * mon) -{ - - if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor))) - return -EFAULT; - info->mon.int_count = 0; - info->mon.char_count = 0; - info->mon.char_max = 0; - info->mon.char_last = 0; - return 0; -} - -static int set_threshold(struct cyclades_port *info, unsigned long __user * arg) -{ - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - unsigned long value; - int channel; - - if (get_user(value, arg)) - return -EFAULT; - - channel = info->line; - info->cor4 &= ~CyREC_FIFO; - info->cor4 |= value & CyREC_FIFO; - base_addr[CyCOR4] = info->cor4; - return 0; -} - -static int -get_threshold(struct cyclades_port *info, unsigned long __user * value) -{ - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - unsigned long tmp; - - channel = info->line; - - tmp = base_addr[CyCOR4] & CyREC_FIFO; - return put_user(tmp, value); -} - -static int -set_default_threshold(struct cyclades_port *info, unsigned long __user * arg) -{ - unsigned long value; - - if (get_user(value, arg)) - return -EFAULT; - - info->default_threshold = value & 0x0f; - return 0; -} - -static int -get_default_threshold(struct cyclades_port *info, unsigned long __user * value) -{ - return put_user(info->default_threshold, value); -} - -static int set_timeout(struct cyclades_port *info, unsigned long __user * arg) -{ - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - unsigned long value; - - if (get_user(value, arg)) - return -EFAULT; - - channel = info->line; - - base_addr[CyRTPRL] = value & 0xff; - base_addr[CyRTPRH] = (value >> 8) & 0xff; - return 0; -} - -static int get_timeout(struct cyclades_port *info, unsigned long __user * value) -{ - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - unsigned long tmp; - - channel = info->line; - - tmp = base_addr[CyRTPRL]; - return put_user(tmp, value); -} - -static int set_default_timeout(struct cyclades_port *info, unsigned long value) -{ - info->default_timeout = value & 0xff; - return 0; -} - -static int -get_default_timeout(struct cyclades_port *info, unsigned long __user * value) -{ - return put_user(info->default_timeout, value); -} - -static int -cy_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct cyclades_port *info = tty->driver_data; - int ret_val = 0; - void __user *argp = (void __user *)arg; - -#ifdef SERIAL_DEBUG_OTHER - printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */ -#endif - - tty_lock(); - - switch (cmd) { - case CYGETMON: - ret_val = get_mon_info(info, argp); - break; - case CYGETTHRESH: - ret_val = get_threshold(info, argp); - break; - case CYSETTHRESH: - ret_val = set_threshold(info, argp); - break; - case CYGETDEFTHRESH: - ret_val = get_default_threshold(info, argp); - break; - case CYSETDEFTHRESH: - ret_val = set_default_threshold(info, argp); - break; - case CYGETTIMEOUT: - ret_val = get_timeout(info, argp); - break; - case CYSETTIMEOUT: - ret_val = set_timeout(info, argp); - break; - case CYGETDEFTIMEOUT: - ret_val = get_default_timeout(info, argp); - break; - case CYSETDEFTIMEOUT: - ret_val = set_default_timeout(info, (unsigned long)arg); - break; - case TCSBRK: /* SVID version: non-zero arg --> no break */ - ret_val = tty_check_change(tty); - if (ret_val) - break; - tty_wait_until_sent(tty, 0); - if (!arg) - send_break(info, HZ / 4); /* 1/4 second */ - break; - case TCSBRKP: /* support for POSIX tcsendbreak() */ - ret_val = tty_check_change(tty); - if (ret_val) - break; - tty_wait_until_sent(tty, 0); - send_break(info, arg ? arg * (HZ / 10) : HZ / 4); - break; - -/* The following commands are incompletely implemented!!! */ - case TIOCGSERIAL: - ret_val = get_serial_info(info, argp); - break; - case TIOCSSERIAL: - ret_val = set_serial_info(info, argp); - break; - default: - ret_val = -ENOIOCTLCMD; - } - tty_unlock(); - -#ifdef SERIAL_DEBUG_OTHER - printk("cy_ioctl done\n"); -#endif - - return ret_val; -} /* cy_ioctl */ - -static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) -{ - struct cyclades_port *info = tty->driver_data; - -#ifdef SERIAL_DEBUG_OTHER - printk("cy_set_termios %s\n", tty->name); -#endif - - if (tty->termios->c_cflag == old_termios->c_cflag) - return; - config_setup(info); - - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->stopped = 0; - cy_start(tty); - } -#ifdef tytso_patch_94Nov25_1726 - if (!(old_termios->c_cflag & CLOCAL) && - (tty->termios->c_cflag & CLOCAL)) - wake_up_interruptible(&info->open_wait); -#endif -} /* cy_set_termios */ - -static void cy_close(struct tty_struct *tty, struct file *filp) -{ - struct cyclades_port *info = tty->driver_data; - -/* CP('C'); */ -#ifdef SERIAL_DEBUG_OTHER - printk("cy_close %s\n", tty->name); -#endif - - if (!info || serial_paranoia_check(info, tty->name, "cy_close")) { - return; - } -#ifdef SERIAL_DEBUG_OPEN - printk("cy_close %s, count = %d\n", tty->name, info->count); -#endif - - if ((tty->count == 1) && (info->count != 1)) { - /* - * Uh, oh. tty->count is 1, which means that the tty - * structure will be freed. Info->count should always - * be one in these conditions. If it's greater than - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ - printk("cy_close: bad serial port count; tty->count is 1, " - "info->count is %d\n", info->count); - info->count = 1; - } -#ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: decrementing count to %d\n", __LINE__, - info->count - 1); -#endif - if (--info->count < 0) { - printk("cy_close: bad serial port count for ttys%d: %d\n", - info->line, info->count); -#ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: setting count to 0\n", __LINE__); -#endif - info->count = 0; - } - if (info->count) - return; - info->flags |= ASYNC_CLOSING; - if (info->flags & ASYNC_INITIALIZED) - tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ - shutdown(info); - cy_flush_buffer(tty); - tty_ldisc_flush(tty); - info->tty = NULL; - if (info->blocked_open) { - if (info->close_delay) { - msleep_interruptible(jiffies_to_msecs - (info->close_delay)); - } - wake_up_interruptible(&info->open_wait); - } - info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); - wake_up_interruptible(&info->close_wait); - -#ifdef SERIAL_DEBUG_OTHER - printk("cy_close done\n"); -#endif -} /* cy_close */ - -/* - * cy_hangup() --- called by tty_hangup() when a hangup is signaled. - */ -void cy_hangup(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - -#ifdef SERIAL_DEBUG_OTHER - printk("cy_hangup %s\n", tty->name); /* */ -#endif - - if (serial_paranoia_check(info, tty->name, "cy_hangup")) - return; - - shutdown(info); -#if 0 - info->event = 0; - info->count = 0; -#ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: setting count to 0\n", __LINE__); -#endif - info->tty = 0; -#endif - info->flags &= ~ASYNC_NORMAL_ACTIVE; - wake_up_interruptible(&info->open_wait); -} /* cy_hangup */ - -/* - * ------------------------------------------------------------ - * cy_open() and friends - * ------------------------------------------------------------ - */ - -static int -block_til_ready(struct tty_struct *tty, struct file *filp, - struct cyclades_port *info) -{ - DECLARE_WAITQUEUE(wait, current); - unsigned long flags; - int channel; - int retval; - volatile u_char *base_addr = (u_char *) BASE_ADDR; - - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (info->flags & ASYNC_CLOSING) { - interruptible_sleep_on(&info->close_wait); - if (info->flags & ASYNC_HUP_NOTIFY) { - return -EAGAIN; - } else { - return -ERESTARTSYS; - } - } - - /* - * If non-blocking mode is set, then make the check up front - * and then exit. - */ - if (filp->f_flags & O_NONBLOCK) { - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, info->count is dropped by one, so that - * cy_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; - add_wait_queue(&info->open_wait, &wait); -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready before block: %s, count = %d\n", - tty->name, info->count); - /**/ -#endif - info->count--; -#ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count); -#endif - info->blocked_open++; - - channel = info->line; - - while (1) { - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; - base_addr[CyMSVR1] = CyRTS; -/* CP('S');CP('4'); */ - base_addr[CyMSVR2] = CyDTR; -#ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: raising DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], - base_addr[CyMSVR2]); -#endif - local_irq_restore(flags); - set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) - || !(info->flags & ASYNC_INITIALIZED)) { - if (info->flags & ASYNC_HUP_NOTIFY) { - retval = -EAGAIN; - } else { - retval = -ERESTARTSYS; - } - break; - } - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; -/* CP('L');CP1(1 && C_CLOCAL(tty)); CP1(1 && (base_addr[CyMSVR1] & CyDCD) ); */ - if (!(info->flags & ASYNC_CLOSING) - && (C_CLOCAL(tty) - || (base_addr[CyMSVR1] & CyDCD))) { - local_irq_restore(flags); - break; - } - local_irq_restore(flags); - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready blocking: %s, count = %d\n", - tty->name, info->count); - /**/ -#endif - tty_unlock(); - schedule(); - tty_lock(); - } - __set_current_state(TASK_RUNNING); - remove_wait_queue(&info->open_wait, &wait); - if (!tty_hung_up_p(filp)) { - info->count++; -#ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: incrementing count to %d\n", __LINE__, - info->count); -#endif - } - info->blocked_open--; -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready after blocking: %s, count = %d\n", - tty->name, info->count); - /**/ -#endif - if (retval) - return retval; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; -} /* block_til_ready */ - -/* - * This routine is called whenever a serial port is opened. It - * performs the serial-specific initialization for the tty structure. - */ -int cy_open(struct tty_struct *tty, struct file *filp) -{ - struct cyclades_port *info; - int retval, line; - -/* CP('O'); */ - line = tty->index; - if ((line < 0) || (NR_PORTS <= line)) { - return -ENODEV; - } - info = &cy_port[line]; - if (info->line < 0) { - return -ENODEV; - } -#ifdef SERIAL_DEBUG_OTHER - printk("cy_open %s\n", tty->name); /* */ -#endif - if (serial_paranoia_check(info, tty->name, "cy_open")) { - return -ENODEV; - } -#ifdef SERIAL_DEBUG_OPEN - printk("cy_open %s, count = %d\n", tty->name, info->count); - /**/ -#endif - info->count++; -#ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count); -#endif - tty->driver_data = info; - info->tty = tty; - - /* - * Start up serial port - */ - retval = startup(info); - if (retval) { - return retval; - } - - retval = block_til_ready(tty, filp, info); - if (retval) { -#ifdef SERIAL_DEBUG_OPEN - printk("cy_open returning after block_til_ready with %d\n", - retval); -#endif - return retval; - } -#ifdef SERIAL_DEBUG_OPEN - printk("cy_open done\n"); - /**/ -#endif - return 0; -} /* cy_open */ - -/* - * --------------------------------------------------------------------- - * serial167_init() and friends - * - * serial167_init() is called at boot-time to initialize the serial driver. - * --------------------------------------------------------------------- - */ - -/* - * This routine prints out the appropriate serial driver version - * number, and identifies which options were configured into this - * driver. - */ -static void show_version(void) -{ - printk("MVME166/167 cd2401 driver\n"); -} /* show_version */ - -/* initialize chips on card -- return number of valid - chips (which is number of ports/4) */ - -/* - * This initialises the hardware to a reasonable state. It should - * probe the chip first so as to copy 166-Bug setup as a default for - * port 0. It initialises CMR to CyASYNC; that is never done again, so - * as to limit the number of CyINIT_CHAN commands in normal running. - * - * ... I wonder what I should do if this fails ... - */ - -void mvme167_serial_console_setup(int cflag) -{ - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int ch; - u_char spd; - u_char rcor, rbpr, badspeed = 0; - unsigned long flags; - - local_irq_save(flags); - - /* - * First probe channel zero of the chip, to see what speed has - * been selected. - */ - - base_addr[CyCAR] = 0; - - rcor = base_addr[CyRCOR] << 5; - rbpr = base_addr[CyRBPR]; - - for (spd = 0; spd < sizeof(baud_bpr); spd++) - if (rbpr == baud_bpr[spd] && rcor == baud_co[spd]) - break; - if (spd >= sizeof(baud_bpr)) { - spd = 14; /* 19200 */ - badspeed = 1; /* Failed to identify speed */ - } - initial_console_speed = spd; - - /* OK, we have chosen a speed, now reset and reinitialise */ - - my_udelay(20000L); /* Allow time for any active o/p to complete */ - if (base_addr[CyCCR] != 0x00) { - local_irq_restore(flags); - /* printk(" chip is never idle (CCR != 0)\n"); */ - return; - } - - base_addr[CyCCR] = CyCHIP_RESET; /* Reset the chip */ - my_udelay(1000L); - - if (base_addr[CyGFRCR] == 0x00) { - local_irq_restore(flags); - /* printk(" chip is not responding (GFRCR stayed 0)\n"); */ - return; - } - - /* - * System clock is 20Mhz, divided by 2048, so divide by 10 for a 1.0ms - * tick - */ - - base_addr[CyTPR] = 10; - - base_addr[CyPILR1] = 0x01; /* Interrupt level for modem change */ - base_addr[CyPILR2] = 0x02; /* Interrupt level for tx ints */ - base_addr[CyPILR3] = 0x03; /* Interrupt level for rx ints */ - - /* - * Attempt to set up all channels to something reasonable, and - * bang out a INIT_CHAN command. We should then be able to limit - * the amount of fiddling we have to do in normal running. - */ - - for (ch = 3; ch >= 0; ch--) { - base_addr[CyCAR] = (u_char) ch; - base_addr[CyIER] = 0; - base_addr[CyCMR] = CyASYNC; - base_addr[CyLICR] = (u_char) ch << 2; - base_addr[CyLIVR] = 0x5c; - base_addr[CyTCOR] = baud_co[spd]; - base_addr[CyTBPR] = baud_bpr[spd]; - base_addr[CyRCOR] = baud_co[spd] >> 5; - base_addr[CyRBPR] = baud_bpr[spd]; - base_addr[CySCHR1] = 'Q' & 0x1f; - base_addr[CySCHR2] = 'X' & 0x1f; - base_addr[CySCRL] = 0; - base_addr[CySCRH] = 0; - base_addr[CyCOR1] = Cy_8_BITS | CyPARITY_NONE; - base_addr[CyCOR2] = 0; - base_addr[CyCOR3] = Cy_1_STOP; - base_addr[CyCOR4] = baud_cor4[spd]; - base_addr[CyCOR5] = 0; - base_addr[CyCOR6] = 0; - base_addr[CyCOR7] = 0; - base_addr[CyRTPRL] = 2; - base_addr[CyRTPRH] = 0; - base_addr[CyMSVR1] = 0; - base_addr[CyMSVR2] = 0; - write_cy_cmd(base_addr, CyINIT_CHAN | CyDIS_RCVR | CyDIS_XMTR); - } - - /* - * Now do specials for channel zero.... - */ - - base_addr[CyMSVR1] = CyRTS; - base_addr[CyMSVR2] = CyDTR; - base_addr[CyIER] = CyRxData; - write_cy_cmd(base_addr, CyENB_RCVR | CyENB_XMTR); - - local_irq_restore(flags); - - my_udelay(20000L); /* Let it all settle down */ - - printk("CD2401 initialised, chip is rev 0x%02x\n", base_addr[CyGFRCR]); - if (badspeed) - printk - (" WARNING: Failed to identify line speed, rcor=%02x,rbpr=%02x\n", - rcor >> 5, rbpr); -} /* serial_console_init */ - -static const struct tty_operations cy_ops = { - .open = cy_open, - .close = cy_close, - .write = cy_write, - .put_char = cy_put_char, - .flush_chars = cy_flush_chars, - .write_room = cy_write_room, - .chars_in_buffer = cy_chars_in_buffer, - .flush_buffer = cy_flush_buffer, - .ioctl = cy_ioctl, - .throttle = cy_throttle, - .unthrottle = cy_unthrottle, - .set_termios = cy_set_termios, - .stop = cy_stop, - .start = cy_start, - .hangup = cy_hangup, - .tiocmget = cy_tiocmget, - .tiocmset = cy_tiocmset, -}; - -/* The serial driver boot-time initialization code! - Hardware I/O ports are mapped to character special devices on a - first found, first allocated manner. That is, this code searches - for Cyclom cards in the system. As each is found, it is probed - to discover how many chips (and thus how many ports) are present. - These ports are mapped to the tty ports 64 and upward in monotonic - fashion. If an 8-port card is replaced with a 16-port card, the - port mapping on a following card will shift. - - This approach is different from what is used in the other serial - device driver because the Cyclom is more properly a multiplexer, - not just an aggregation of serial ports on one card. - - If there are more cards with more ports than have been statically - allocated above, a warning is printed and the extra ports are ignored. - */ -static int __init serial167_init(void) -{ - struct cyclades_port *info; - int ret = 0; - int good_ports = 0; - int port_num = 0; - int index; - int DefSpeed; -#ifdef notyet - struct sigaction sa; -#endif - - if (!(mvme16x_config & MVME16x_CONFIG_GOT_CD2401)) - return 0; - - cy_serial_driver = alloc_tty_driver(NR_PORTS); - if (!cy_serial_driver) - return -ENOMEM; - -#if 0 - scrn[1] = '\0'; -#endif - - show_version(); - - /* Has "console=0,9600n8" been used in bootinfo to change speed? */ - if (serial_console_cflag) - DefSpeed = serial_console_cflag & 0017; - else { - DefSpeed = initial_console_speed; - serial_console_info = &cy_port[0]; - serial_console_cflag = DefSpeed | CS8; -#if 0 - serial_console = 64; /*callout_driver.minor_start */ -#endif - } - - /* Initialize the tty_driver structure */ - - cy_serial_driver->owner = THIS_MODULE; - cy_serial_driver->name = "ttyS"; - cy_serial_driver->major = TTY_MAJOR; - cy_serial_driver->minor_start = 64; - cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - cy_serial_driver->subtype = SERIAL_TYPE_NORMAL; - cy_serial_driver->init_termios = tty_std_termios; - cy_serial_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - cy_serial_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(cy_serial_driver, &cy_ops); - - ret = tty_register_driver(cy_serial_driver); - if (ret) { - printk(KERN_ERR "Couldn't register MVME166/7 serial driver\n"); - put_tty_driver(cy_serial_driver); - return ret; - } - - port_num = 0; - info = cy_port; - for (index = 0; index < 1; index++) { - - good_ports = 4; - - if (port_num < NR_PORTS) { - while (good_ports-- && port_num < NR_PORTS) { - /*** initialize port ***/ - info->magic = CYCLADES_MAGIC; - info->type = PORT_CIRRUS; - info->card = index; - info->line = port_num; - info->flags = STD_COM_FLAGS; - info->tty = NULL; - info->xmit_fifo_size = 12; - info->cor1 = CyPARITY_NONE | Cy_8_BITS; - info->cor2 = CyETC; - info->cor3 = Cy_1_STOP; - info->cor4 = 0x08; /* _very_ small receive threshold */ - info->cor5 = 0; - info->cor6 = 0; - info->cor7 = 0; - info->tbpr = baud_bpr[DefSpeed]; /* Tx BPR */ - info->tco = baud_co[DefSpeed]; /* Tx CO */ - info->rbpr = baud_bpr[DefSpeed]; /* Rx BPR */ - info->rco = baud_co[DefSpeed] >> 5; /* Rx CO */ - info->close_delay = 0; - info->x_char = 0; - info->count = 0; -#ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: setting count to 0\n", - __LINE__); -#endif - info->blocked_open = 0; - info->default_threshold = 0; - info->default_timeout = 0; - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - /* info->session */ - /* info->pgrp */ -/*** !!!!!!!! this may expose new bugs !!!!!!!!! *********/ - info->read_status_mask = - CyTIMEOUT | CySPECHAR | CyBREAK | CyPARITY | - CyFRAME | CyOVERRUN; - /* info->timeout */ - - printk("ttyS%d ", info->line); - port_num++; - info++; - if (!(port_num & 7)) { - printk("\n "); - } - } - } - printk("\n"); - } - while (port_num < NR_PORTS) { - info->line = -1; - port_num++; - info++; - } - - ret = request_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt, 0, - "cd2401_errors", cd2401_rxerr_interrupt); - if (ret) { - printk(KERN_ERR "Could't get cd2401_errors IRQ"); - goto cleanup_serial_driver; - } - - ret = request_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt, 0, - "cd2401_modem", cd2401_modem_interrupt); - if (ret) { - printk(KERN_ERR "Could't get cd2401_modem IRQ"); - goto cleanup_irq_cd2401_errors; - } - - ret = request_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt, 0, - "cd2401_txints", cd2401_tx_interrupt); - if (ret) { - printk(KERN_ERR "Could't get cd2401_txints IRQ"); - goto cleanup_irq_cd2401_modem; - } - - ret = request_irq(MVME167_IRQ_SER_RX, cd2401_rx_interrupt, 0, - "cd2401_rxints", cd2401_rx_interrupt); - if (ret) { - printk(KERN_ERR "Could't get cd2401_rxints IRQ"); - goto cleanup_irq_cd2401_txints; - } - - /* Now we have registered the interrupt handlers, allow the interrupts */ - - pcc2chip[PccSCCMICR] = 0x15; /* Serial ints are level 5 */ - pcc2chip[PccSCCTICR] = 0x15; - pcc2chip[PccSCCRICR] = 0x15; - - pcc2chip[PccIMLR] = 3; /* Allow PCC2 ints above 3!? */ - - return 0; -cleanup_irq_cd2401_txints: - free_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt); -cleanup_irq_cd2401_modem: - free_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt); -cleanup_irq_cd2401_errors: - free_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt); -cleanup_serial_driver: - if (tty_unregister_driver(cy_serial_driver)) - printk(KERN_ERR - "Couldn't unregister MVME166/7 serial driver\n"); - put_tty_driver(cy_serial_driver); - return ret; -} /* serial167_init */ - -module_init(serial167_init); - -#ifdef CYCLOM_SHOW_STATUS -static void show_status(int line_num) -{ - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - struct cyclades_port *info; - unsigned long flags; - - info = &cy_port[line_num]; - channel = info->line; - printk(" channel %d\n", channel); - /**/ printk(" cy_port\n"); - printk(" card line flags = %d %d %x\n", - info->card, info->line, info->flags); - printk - (" *tty read_status_mask timeout xmit_fifo_size = %lx %x %x %x\n", - (long)info->tty, info->read_status_mask, info->timeout, - info->xmit_fifo_size); - printk(" cor1,cor2,cor3,cor4,cor5,cor6,cor7 = %x %x %x %x %x %x %x\n", - info->cor1, info->cor2, info->cor3, info->cor4, info->cor5, - info->cor6, info->cor7); - printk(" tbpr,tco,rbpr,rco = %d %d %d %d\n", info->tbpr, info->tco, - info->rbpr, info->rco); - printk(" close_delay event count = %d %d %d\n", info->close_delay, - info->event, info->count); - printk(" x_char blocked_open = %x %x\n", info->x_char, - info->blocked_open); - printk(" open_wait = %lx %lx %lx\n", (long)info->open_wait); - - local_irq_save(flags); - -/* Global Registers */ - - printk(" CyGFRCR %x\n", base_addr[CyGFRCR]); - printk(" CyCAR %x\n", base_addr[CyCAR]); - printk(" CyRISR %x\n", base_addr[CyRISR]); - printk(" CyTISR %x\n", base_addr[CyTISR]); - printk(" CyMISR %x\n", base_addr[CyMISR]); - printk(" CyRIR %x\n", base_addr[CyRIR]); - printk(" CyTIR %x\n", base_addr[CyTIR]); - printk(" CyMIR %x\n", base_addr[CyMIR]); - printk(" CyTPR %x\n", base_addr[CyTPR]); - - base_addr[CyCAR] = (u_char) channel; - -/* Virtual Registers */ - -#if 0 - printk(" CyRIVR %x\n", base_addr[CyRIVR]); - printk(" CyTIVR %x\n", base_addr[CyTIVR]); - printk(" CyMIVR %x\n", base_addr[CyMIVR]); - printk(" CyMISR %x\n", base_addr[CyMISR]); -#endif - -/* Channel Registers */ - - printk(" CyCCR %x\n", base_addr[CyCCR]); - printk(" CyIER %x\n", base_addr[CyIER]); - printk(" CyCOR1 %x\n", base_addr[CyCOR1]); - printk(" CyCOR2 %x\n", base_addr[CyCOR2]); - printk(" CyCOR3 %x\n", base_addr[CyCOR3]); - printk(" CyCOR4 %x\n", base_addr[CyCOR4]); - printk(" CyCOR5 %x\n", base_addr[CyCOR5]); -#if 0 - printk(" CyCCSR %x\n", base_addr[CyCCSR]); - printk(" CyRDCR %x\n", base_addr[CyRDCR]); -#endif - printk(" CySCHR1 %x\n", base_addr[CySCHR1]); - printk(" CySCHR2 %x\n", base_addr[CySCHR2]); -#if 0 - printk(" CySCHR3 %x\n", base_addr[CySCHR3]); - printk(" CySCHR4 %x\n", base_addr[CySCHR4]); - printk(" CySCRL %x\n", base_addr[CySCRL]); - printk(" CySCRH %x\n", base_addr[CySCRH]); - printk(" CyLNC %x\n", base_addr[CyLNC]); - printk(" CyMCOR1 %x\n", base_addr[CyMCOR1]); - printk(" CyMCOR2 %x\n", base_addr[CyMCOR2]); -#endif - printk(" CyRTPRL %x\n", base_addr[CyRTPRL]); - printk(" CyRTPRH %x\n", base_addr[CyRTPRH]); - printk(" CyMSVR1 %x\n", base_addr[CyMSVR1]); - printk(" CyMSVR2 %x\n", base_addr[CyMSVR2]); - printk(" CyRBPR %x\n", base_addr[CyRBPR]); - printk(" CyRCOR %x\n", base_addr[CyRCOR]); - printk(" CyTBPR %x\n", base_addr[CyTBPR]); - printk(" CyTCOR %x\n", base_addr[CyTCOR]); - - local_irq_restore(flags); -} /* show_status */ -#endif - -#if 0 -/* Dummy routine in mvme16x/config.c for now */ - -/* Serial console setup. Called from linux/init/main.c */ - -void console_setup(char *str, int *ints) -{ - char *s; - int baud, bits, parity; - int cflag = 0; - - /* Sanity check. */ - if (ints[0] > 3 || ints[1] > 3) - return; - - /* Get baud, bits and parity */ - baud = 2400; - bits = 8; - parity = 'n'; - if (ints[2]) - baud = ints[2]; - if ((s = strchr(str, ','))) { - do { - s++; - } while (*s >= '0' && *s <= '9'); - if (*s) - parity = *s++; - if (*s) - bits = *s - '0'; - } - - /* Now construct a cflag setting. */ - switch (baud) { - case 1200: - cflag |= B1200; - break; - case 9600: - cflag |= B9600; - break; - case 19200: - cflag |= B19200; - break; - case 38400: - cflag |= B38400; - break; - case 2400: - default: - cflag |= B2400; - break; - } - switch (bits) { - case 7: - cflag |= CS7; - break; - default: - case 8: - cflag |= CS8; - break; - } - switch (parity) { - case 'o': - case 'O': - cflag |= PARODD; - break; - case 'e': - case 'E': - cflag |= PARENB; - break; - } - - serial_console_info = &cy_port[ints[1]]; - serial_console_cflag = cflag; - serial_console = ints[1] + 64; /*callout_driver.minor_start */ -} -#endif - -/* - * The following is probably out of date for 2.1.x serial console stuff. - * - * The console is registered early on from arch/m68k/kernel/setup.c, and - * it therefore relies on the chip being setup correctly by 166-Bug. This - * seems reasonable, as the serial port has been used to invoke the system - * boot. It also means that this function must not rely on any data - * initialisation performed by serial167_init() etc. - * - * Of course, once the console has been registered, we had better ensure - * that serial167_init() doesn't leave the chip non-functional. - * - * The console must be locked when we get here. - */ - -void serial167_console_write(struct console *co, const char *str, - unsigned count) -{ - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - unsigned long flags; - volatile u_char sink; - u_char ier; - int port; - u_char do_lf = 0; - int i = 0; - - local_irq_save(flags); - - /* Ensure transmitter is enabled! */ - - port = 0; - base_addr[CyCAR] = (u_char) port; - while (base_addr[CyCCR]) - ; - base_addr[CyCCR] = CyENB_XMTR; - - ier = base_addr[CyIER]; - base_addr[CyIER] = CyTxMpty; - - while (1) { - if (pcc2chip[PccSCCTICR] & 0x20) { - /* We have a Tx int. Acknowledge it */ - sink = pcc2chip[PccTPIACKR]; - if ((base_addr[CyLICR] >> 2) == port) { - if (i == count) { - /* Last char of string is now output */ - base_addr[CyTEOIR] = CyNOTRANS; - break; - } - if (do_lf) { - base_addr[CyTDR] = '\n'; - str++; - i++; - do_lf = 0; - } else if (*str == '\n') { - base_addr[CyTDR] = '\r'; - do_lf = 1; - } else { - base_addr[CyTDR] = *str++; - i++; - } - base_addr[CyTEOIR] = 0; - } else - base_addr[CyTEOIR] = CyNOTRANS; - } - } - - base_addr[CyIER] = ier; - - local_irq_restore(flags); -} - -static struct tty_driver *serial167_console_device(struct console *c, - int *index) -{ - *index = c->index; - return cy_serial_driver; -} - -static struct console sercons = { - .name = "ttyS", - .write = serial167_console_write, - .device = serial167_console_device, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -static int __init serial167_console_init(void) -{ - if (vme_brdtype == VME_TYPE_MVME166 || - vme_brdtype == VME_TYPE_MVME167 || - vme_brdtype == VME_TYPE_MVME177) { - mvme167_serial_console_setup(0); - register_console(&sercons); - } - return 0; -} - -console_initcall(serial167_console_init); - -MODULE_LICENSE("GPL"); diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c deleted file mode 100644 index 47e5753f732a..000000000000 --- a/drivers/char/specialix.c +++ /dev/null @@ -1,2368 +0,0 @@ -/* - * specialix.c -- specialix IO8+ multiport serial driver. - * - * Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl) - * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) - * - * Specialix pays for the development and support of this driver. - * Please DO contact io8-linux@specialix.co.uk if you require - * support. But please read the documentation (specialix.txt) - * first. - * - * This driver was developped in the BitWizard linux device - * driver service. If you require a linux device driver for your - * product, please contact devices@BitWizard.nl for a quote. - * - * This code is firmly based on the riscom/8 serial driver, - * written by Dmitry Gorodchanin. The specialix IO8+ card - * programming information was obtained from the CL-CD1865 Data - * Book, and Specialix document number 6200059: IO8+ Hardware - * Functional Specification. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, - * USA. - * - * Revision history: - * - * Revision 1.0: April 1st 1997. - * Initial release for alpha testing. - * Revision 1.1: April 14th 1997. - * Incorporated Richard Hudsons suggestions, - * removed some debugging printk's. - * Revision 1.2: April 15th 1997. - * Ported to 2.1.x kernels. - * Revision 1.3: April 17th 1997 - * Backported to 2.0. (Compatibility macros). - * Revision 1.4: April 18th 1997 - * Fixed DTR/RTS bug that caused the card to indicate - * "don't send data" to a modem after the password prompt. - * Fixed bug for premature (fake) interrupts. - * Revision 1.5: April 19th 1997 - * fixed a minor typo in the header file, cleanup a little. - * performance warnings are now MAXed at once per minute. - * Revision 1.6: May 23 1997 - * Changed the specialix=... format to include interrupt. - * Revision 1.7: May 27 1997 - * Made many more debug printk's a compile time option. - * Revision 1.8: Jul 1 1997 - * port to linux-2.1.43 kernel. - * Revision 1.9: Oct 9 1998 - * Added stuff for the IO8+/PCI version. - * Revision 1.10: Oct 22 1999 / Jan 21 2000. - * Added stuff for setserial. - * Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr) - * - */ - -#define VERSION "1.11" - - -/* - * There is a bunch of documentation about the card, jumpers, config - * settings, restrictions, cables, device names and numbers in - * Documentation/serial/specialix.txt - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "specialix_io8.h" -#include "cd1865.h" - - -/* - This driver can spew a whole lot of debugging output at you. If you - need maximum performance, you should disable the DEBUG define. To - aid in debugging in the field, I'm leaving the compile-time debug - features enabled, and disable them "runtime". That allows me to - instruct people with problems to enable debugging without requiring - them to recompile... -*/ -#define DEBUG - -static int sx_debug; -static int sx_rxfifo = SPECIALIX_RXFIFO; -static int sx_rtscts; - -#ifdef DEBUG -#define dprintk(f, str...) if (sx_debug & f) printk(str) -#else -#define dprintk(f, str...) /* nothing */ -#endif - -#define SX_DEBUG_FLOW 0x0001 -#define SX_DEBUG_DATA 0x0002 -#define SX_DEBUG_PROBE 0x0004 -#define SX_DEBUG_CHAN 0x0008 -#define SX_DEBUG_INIT 0x0010 -#define SX_DEBUG_RX 0x0020 -#define SX_DEBUG_TX 0x0040 -#define SX_DEBUG_IRQ 0x0080 -#define SX_DEBUG_OPEN 0x0100 -#define SX_DEBUG_TERMIOS 0x0200 -#define SX_DEBUG_SIGNALS 0x0400 -#define SX_DEBUG_FIFO 0x0800 - - -#define func_enter() dprintk(SX_DEBUG_FLOW, "io8: enter %s\n", __func__) -#define func_exit() dprintk(SX_DEBUG_FLOW, "io8: exit %s\n", __func__) - - -/* Configurable options: */ - -/* Am I paranoid or not ? ;-) */ -#define SPECIALIX_PARANOIA_CHECK - -/* - * The following defines are mostly for testing purposes. But if you need - * some nice reporting in your syslog, you can define them also. - */ -#undef SX_REPORT_FIFO -#undef SX_REPORT_OVERRUN - - - - -#define SPECIALIX_LEGAL_FLAGS \ - (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \ - ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \ - ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP) - -static struct tty_driver *specialix_driver; - -static struct specialix_board sx_board[SX_NBOARD] = { - { 0, SX_IOBASE1, 9, }, - { 0, SX_IOBASE2, 11, }, - { 0, SX_IOBASE3, 12, }, - { 0, SX_IOBASE4, 15, }, -}; - -static struct specialix_port sx_port[SX_NBOARD * SX_NPORT]; - - -static int sx_paranoia_check(struct specialix_port const *port, - char *name, const char *routine) -{ -#ifdef SPECIALIX_PARANOIA_CHECK - static const char *badmagic = KERN_ERR - "sx: Warning: bad specialix port magic number for device %s in %s\n"; - static const char *badinfo = KERN_ERR - "sx: Warning: null specialix port for device %s in %s\n"; - - if (!port) { - printk(badinfo, name, routine); - return 1; - } - if (port->magic != SPECIALIX_MAGIC) { - printk(badmagic, name, routine); - return 1; - } -#endif - return 0; -} - - -/* - * - * Service functions for specialix IO8+ driver. - * - */ - -/* Get board number from pointer */ -static inline int board_No(struct specialix_board *bp) -{ - return bp - sx_board; -} - - -/* Get port number from pointer */ -static inline int port_No(struct specialix_port const *port) -{ - return SX_PORT(port - sx_port); -} - - -/* Get pointer to board from pointer to port */ -static inline struct specialix_board *port_Board( - struct specialix_port const *port) -{ - return &sx_board[SX_BOARD(port - sx_port)]; -} - - -/* Input Byte from CL CD186x register */ -static inline unsigned char sx_in(struct specialix_board *bp, - unsigned short reg) -{ - bp->reg = reg | 0x80; - outb(reg | 0x80, bp->base + SX_ADDR_REG); - return inb(bp->base + SX_DATA_REG); -} - - -/* Output Byte to CL CD186x register */ -static inline void sx_out(struct specialix_board *bp, unsigned short reg, - unsigned char val) -{ - bp->reg = reg | 0x80; - outb(reg | 0x80, bp->base + SX_ADDR_REG); - outb(val, bp->base + SX_DATA_REG); -} - - -/* Input Byte from CL CD186x register */ -static inline unsigned char sx_in_off(struct specialix_board *bp, - unsigned short reg) -{ - bp->reg = reg; - outb(reg, bp->base + SX_ADDR_REG); - return inb(bp->base + SX_DATA_REG); -} - - -/* Output Byte to CL CD186x register */ -static inline void sx_out_off(struct specialix_board *bp, - unsigned short reg, unsigned char val) -{ - bp->reg = reg; - outb(reg, bp->base + SX_ADDR_REG); - outb(val, bp->base + SX_DATA_REG); -} - - -/* Wait for Channel Command Register ready */ -static void sx_wait_CCR(struct specialix_board *bp) -{ - unsigned long delay, flags; - unsigned char ccr; - - for (delay = SX_CCR_TIMEOUT; delay; delay--) { - spin_lock_irqsave(&bp->lock, flags); - ccr = sx_in(bp, CD186x_CCR); - spin_unlock_irqrestore(&bp->lock, flags); - if (!ccr) - return; - udelay(1); - } - - printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp)); -} - - -/* Wait for Channel Command Register ready */ -static void sx_wait_CCR_off(struct specialix_board *bp) -{ - unsigned long delay; - unsigned char crr; - unsigned long flags; - - for (delay = SX_CCR_TIMEOUT; delay; delay--) { - spin_lock_irqsave(&bp->lock, flags); - crr = sx_in_off(bp, CD186x_CCR); - spin_unlock_irqrestore(&bp->lock, flags); - if (!crr) - return; - udelay(1); - } - - printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp)); -} - - -/* - * specialix IO8+ IO range functions. - */ - -static int sx_request_io_range(struct specialix_board *bp) -{ - return request_region(bp->base, - bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE, - "specialix IO8+") == NULL; -} - - -static void sx_release_io_range(struct specialix_board *bp) -{ - release_region(bp->base, bp->flags & SX_BOARD_IS_PCI ? - SX_PCI_IO_SPACE : SX_IO_SPACE); -} - - -/* Set the IRQ using the RTS lines that run to the PAL on the board.... */ -static int sx_set_irq(struct specialix_board *bp) -{ - int virq; - int i; - unsigned long flags; - - if (bp->flags & SX_BOARD_IS_PCI) - return 1; - switch (bp->irq) { - /* In the same order as in the docs... */ - case 15: - virq = 0; - break; - case 12: - virq = 1; - break; - case 11: - virq = 2; - break; - case 9: - virq = 3; - break; - default:printk(KERN_ERR - "Speclialix: cannot set irq to %d.\n", bp->irq); - return 0; - } - spin_lock_irqsave(&bp->lock, flags); - for (i = 0; i < 2; i++) { - sx_out(bp, CD186x_CAR, i); - sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0); - } - spin_unlock_irqrestore(&bp->lock, flags); - return 1; -} - - -/* Reset and setup CD186x chip */ -static int sx_init_CD186x(struct specialix_board *bp) -{ - unsigned long flags; - int scaler; - int rv = 1; - - func_enter(); - sx_wait_CCR_off(bp); /* Wait for CCR ready */ - spin_lock_irqsave(&bp->lock, flags); - sx_out_off(bp, CD186x_CCR, CCR_HARDRESET); /* Reset CD186x chip */ - spin_unlock_irqrestore(&bp->lock, flags); - msleep(50); /* Delay 0.05 sec */ - spin_lock_irqsave(&bp->lock, flags); - sx_out_off(bp, CD186x_GIVR, SX_ID); /* Set ID for this chip */ - sx_out_off(bp, CD186x_GICR, 0); /* Clear all bits */ - sx_out_off(bp, CD186x_PILR1, SX_ACK_MINT); /* Prio for modem intr */ - sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT); /* Prio for transmitter intr */ - sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */ - /* Set RegAckEn */ - sx_out_off(bp, CD186x_SRCR, sx_in(bp, CD186x_SRCR) | SRCR_REGACKEN); - - /* Setting up prescaler. We need 4 ticks per 1 ms */ - scaler = SX_OSCFREQ/SPECIALIX_TPS; - - sx_out_off(bp, CD186x_PPRH, scaler >> 8); - sx_out_off(bp, CD186x_PPRL, scaler & 0xff); - spin_unlock_irqrestore(&bp->lock, flags); - - if (!sx_set_irq(bp)) { - /* Figure out how to pass this along... */ - printk(KERN_ERR "Cannot set irq to %d.\n", bp->irq); - rv = 0; - } - - func_exit(); - return rv; -} - - -static int read_cross_byte(struct specialix_board *bp, int reg, int bit) -{ - int i; - int t; - unsigned long flags; - - spin_lock_irqsave(&bp->lock, flags); - for (i = 0, t = 0; i < 8; i++) { - sx_out_off(bp, CD186x_CAR, i); - if (sx_in_off(bp, reg) & bit) - t |= 1 << i; - } - spin_unlock_irqrestore(&bp->lock, flags); - - return t; -} - - -/* Main probing routine, also sets irq. */ -static int sx_probe(struct specialix_board *bp) -{ - unsigned char val1, val2; - int rev; - int chip; - - func_enter(); - - if (sx_request_io_range(bp)) { - func_exit(); - return 1; - } - - /* Are the I/O ports here ? */ - sx_out_off(bp, CD186x_PPRL, 0x5a); - udelay(1); - val1 = sx_in_off(bp, CD186x_PPRL); - - sx_out_off(bp, CD186x_PPRL, 0xa5); - udelay(1); - val2 = sx_in_off(bp, CD186x_PPRL); - - - if (val1 != 0x5a || val2 != 0xa5) { - printk(KERN_INFO - "sx%d: specialix IO8+ Board at 0x%03x not found.\n", - board_No(bp), bp->base); - sx_release_io_range(bp); - func_exit(); - return 1; - } - - /* Check the DSR lines that Specialix uses as board - identification */ - val1 = read_cross_byte(bp, CD186x_MSVR, MSVR_DSR); - val2 = read_cross_byte(bp, CD186x_MSVR, MSVR_RTS); - dprintk(SX_DEBUG_INIT, - "sx%d: DSR lines are: %02x, rts lines are: %02x\n", - board_No(bp), val1, val2); - - /* They managed to switch the bit order between the docs and - the IO8+ card. The new PCI card now conforms to old docs. - They changed the PCI docs to reflect the situation on the - old card. */ - val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2; - if (val1 != val2) { - printk(KERN_INFO - "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n", - board_No(bp), val2, bp->base, val1); - sx_release_io_range(bp); - func_exit(); - return 1; - } - - - /* Reset CD186x again */ - if (!sx_init_CD186x(bp)) { - sx_release_io_range(bp); - func_exit(); - return 1; - } - - sx_request_io_range(bp); - bp->flags |= SX_BOARD_PRESENT; - - /* Chip revcode pkgtype - GFRCR SRCR bit 7 - CD180 rev B 0x81 0 - CD180 rev C 0x82 0 - CD1864 rev A 0x82 1 - CD1865 rev A 0x83 1 -- Do not use!!! Does not work. - CD1865 rev B 0x84 1 - -- Thanks to Gwen Wang, Cirrus Logic. - */ - - switch (sx_in_off(bp, CD186x_GFRCR)) { - case 0x82: - chip = 1864; - rev = 'A'; - break; - case 0x83: - chip = 1865; - rev = 'A'; - break; - case 0x84: - chip = 1865; - rev = 'B'; - break; - case 0x85: - chip = 1865; - rev = 'C'; - break; /* Does not exist at this time */ - default: - chip = -1; - rev = 'x'; - } - - dprintk(SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR)); - - printk(KERN_INFO - "sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n", - board_No(bp), bp->base, bp->irq, chip, rev); - - func_exit(); - return 0; -} - -/* - * - * Interrupt processing routines. - * */ - -static struct specialix_port *sx_get_port(struct specialix_board *bp, - unsigned char const *what) -{ - unsigned char channel; - struct specialix_port *port = NULL; - - channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF; - dprintk(SX_DEBUG_CHAN, "channel: %d\n", channel); - if (channel < CD186x_NCH) { - port = &sx_port[board_No(bp) * SX_NPORT + channel]; - dprintk(SX_DEBUG_CHAN, "port: %d %p flags: 0x%lx\n", - board_No(bp) * SX_NPORT + channel, port, - port->port.flags & ASYNC_INITIALIZED); - - if (port->port.flags & ASYNC_INITIALIZED) { - dprintk(SX_DEBUG_CHAN, "port: %d %p\n", channel, port); - func_exit(); - return port; - } - } - printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n", - board_No(bp), what, channel); - return NULL; -} - - -static void sx_receive_exc(struct specialix_board *bp) -{ - struct specialix_port *port; - struct tty_struct *tty; - unsigned char status; - unsigned char ch, flag; - - func_enter(); - - port = sx_get_port(bp, "Receive"); - if (!port) { - dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n"); - func_exit(); - return; - } - tty = port->port.tty; - - status = sx_in(bp, CD186x_RCSR); - - dprintk(SX_DEBUG_RX, "status: 0x%x\n", status); - if (status & RCSR_OE) { - port->overrun++; - dprintk(SX_DEBUG_FIFO, - "sx%d: port %d: Overrun. Total %ld overruns.\n", - board_No(bp), port_No(port), port->overrun); - } - status &= port->mark_mask; - - /* This flip buffer check needs to be below the reading of the - status register to reset the chip's IRQ.... */ - if (tty_buffer_request_room(tty, 1) == 0) { - dprintk(SX_DEBUG_FIFO, - "sx%d: port %d: Working around flip buffer overflow.\n", - board_No(bp), port_No(port)); - func_exit(); - return; - } - - ch = sx_in(bp, CD186x_RDR); - if (!status) { - func_exit(); - return; - } - if (status & RCSR_TOUT) { - printk(KERN_INFO - "sx%d: port %d: Receiver timeout. Hardware problems ?\n", - board_No(bp), port_No(port)); - func_exit(); - return; - - } else if (status & RCSR_BREAK) { - dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n", - board_No(bp), port_No(port)); - flag = TTY_BREAK; - if (port->port.flags & ASYNC_SAK) - do_SAK(tty); - - } else if (status & RCSR_PE) - flag = TTY_PARITY; - - else if (status & RCSR_FE) - flag = TTY_FRAME; - - else if (status & RCSR_OE) - flag = TTY_OVERRUN; - - else - flag = TTY_NORMAL; - - if (tty_insert_flip_char(tty, ch, flag)) - tty_flip_buffer_push(tty); - func_exit(); -} - - -static void sx_receive(struct specialix_board *bp) -{ - struct specialix_port *port; - struct tty_struct *tty; - unsigned char count; - - func_enter(); - - port = sx_get_port(bp, "Receive"); - if (port == NULL) { - dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n"); - func_exit(); - return; - } - tty = port->port.tty; - - count = sx_in(bp, CD186x_RDCR); - dprintk(SX_DEBUG_RX, "port: %p: count: %d\n", port, count); - port->hits[count > 8 ? 9 : count]++; - - while (count--) - tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL); - tty_flip_buffer_push(tty); - func_exit(); -} - - -static void sx_transmit(struct specialix_board *bp) -{ - struct specialix_port *port; - struct tty_struct *tty; - unsigned char count; - - func_enter(); - port = sx_get_port(bp, "Transmit"); - if (port == NULL) { - func_exit(); - return; - } - dprintk(SX_DEBUG_TX, "port: %p\n", port); - tty = port->port.tty; - - if (port->IER & IER_TXEMPTY) { - /* FIFO drained */ - sx_out(bp, CD186x_CAR, port_No(port)); - port->IER &= ~IER_TXEMPTY; - sx_out(bp, CD186x_IER, port->IER); - func_exit(); - return; - } - - if ((port->xmit_cnt <= 0 && !port->break_length) - || tty->stopped || tty->hw_stopped) { - sx_out(bp, CD186x_CAR, port_No(port)); - port->IER &= ~IER_TXRDY; - sx_out(bp, CD186x_IER, port->IER); - func_exit(); - return; - } - - if (port->break_length) { - if (port->break_length > 0) { - if (port->COR2 & COR2_ETC) { - sx_out(bp, CD186x_TDR, CD186x_C_ESC); - sx_out(bp, CD186x_TDR, CD186x_C_SBRK); - port->COR2 &= ~COR2_ETC; - } - count = min_t(int, port->break_length, 0xff); - sx_out(bp, CD186x_TDR, CD186x_C_ESC); - sx_out(bp, CD186x_TDR, CD186x_C_DELAY); - sx_out(bp, CD186x_TDR, count); - port->break_length -= count; - if (port->break_length == 0) - port->break_length--; - } else { - sx_out(bp, CD186x_TDR, CD186x_C_ESC); - sx_out(bp, CD186x_TDR, CD186x_C_EBRK); - sx_out(bp, CD186x_COR2, port->COR2); - sx_wait_CCR(bp); - sx_out(bp, CD186x_CCR, CCR_CORCHG2); - port->break_length = 0; - } - - func_exit(); - return; - } - - count = CD186x_NFIFO; - do { - sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]); - port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1); - if (--port->xmit_cnt <= 0) - break; - } while (--count > 0); - - if (port->xmit_cnt <= 0) { - sx_out(bp, CD186x_CAR, port_No(port)); - port->IER &= ~IER_TXRDY; - sx_out(bp, CD186x_IER, port->IER); - } - if (port->xmit_cnt <= port->wakeup_chars) - tty_wakeup(tty); - - func_exit(); -} - - -static void sx_check_modem(struct specialix_board *bp) -{ - struct specialix_port *port; - struct tty_struct *tty; - unsigned char mcr; - int msvr_cd; - - dprintk(SX_DEBUG_SIGNALS, "Modem intr. "); - port = sx_get_port(bp, "Modem"); - if (port == NULL) - return; - - tty = port->port.tty; - - mcr = sx_in(bp, CD186x_MCR); - - if ((mcr & MCR_CDCHG)) { - dprintk(SX_DEBUG_SIGNALS, "CD just changed... "); - msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD; - if (msvr_cd) { - dprintk(SX_DEBUG_SIGNALS, "Waking up guys in open.\n"); - wake_up_interruptible(&port->port.open_wait); - } else { - dprintk(SX_DEBUG_SIGNALS, "Sending HUP.\n"); - tty_hangup(tty); - } - } - -#ifdef SPECIALIX_BRAIN_DAMAGED_CTS - if (mcr & MCR_CTSCHG) { - if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) { - tty->hw_stopped = 0; - port->IER |= IER_TXRDY; - if (port->xmit_cnt <= port->wakeup_chars) - tty_wakeup(tty); - } else { - tty->hw_stopped = 1; - port->IER &= ~IER_TXRDY; - } - sx_out(bp, CD186x_IER, port->IER); - } - if (mcr & MCR_DSSXHG) { - if (sx_in(bp, CD186x_MSVR) & MSVR_DSR) { - tty->hw_stopped = 0; - port->IER |= IER_TXRDY; - if (port->xmit_cnt <= port->wakeup_chars) - tty_wakeup(tty); - } else { - tty->hw_stopped = 1; - port->IER &= ~IER_TXRDY; - } - sx_out(bp, CD186x_IER, port->IER); - } -#endif /* SPECIALIX_BRAIN_DAMAGED_CTS */ - - /* Clear change bits */ - sx_out(bp, CD186x_MCR, 0); -} - - -/* The main interrupt processing routine */ -static irqreturn_t sx_interrupt(int dummy, void *dev_id) -{ - unsigned char status; - unsigned char ack; - struct specialix_board *bp = dev_id; - unsigned long loop = 0; - int saved_reg; - unsigned long flags; - - func_enter(); - - spin_lock_irqsave(&bp->lock, flags); - - dprintk(SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __func__, - port_No(sx_get_port(bp, "INT")), - SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1); - if (!(bp->flags & SX_BOARD_ACTIVE)) { - dprintk(SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", - bp->irq); - spin_unlock_irqrestore(&bp->lock, flags); - func_exit(); - return IRQ_NONE; - } - - saved_reg = bp->reg; - - while (++loop < 16) { - status = sx_in(bp, CD186x_SRSR) & - (SRSR_RREQint | SRSR_TREQint | SRSR_MREQint); - if (status == 0) - break; - if (status & SRSR_RREQint) { - ack = sx_in(bp, CD186x_RRAR); - - if (ack == (SX_ID | GIVR_IT_RCV)) - sx_receive(bp); - else if (ack == (SX_ID | GIVR_IT_REXC)) - sx_receive_exc(bp); - else - printk(KERN_ERR - "sx%d: status: 0x%x Bad receive ack 0x%02x.\n", - board_No(bp), status, ack); - - } else if (status & SRSR_TREQint) { - ack = sx_in(bp, CD186x_TRAR); - - if (ack == (SX_ID | GIVR_IT_TX)) - sx_transmit(bp); - else - printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n", - board_No(bp), status, ack, - port_No(sx_get_port(bp, "Int"))); - } else if (status & SRSR_MREQint) { - ack = sx_in(bp, CD186x_MRAR); - - if (ack == (SX_ID | GIVR_IT_MODEM)) - sx_check_modem(bp); - else - printk(KERN_ERR - "sx%d: status: 0x%x Bad modem ack 0x%02x.\n", - board_No(bp), status, ack); - - } - - sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */ - } - bp->reg = saved_reg; - outb(bp->reg, bp->base + SX_ADDR_REG); - spin_unlock_irqrestore(&bp->lock, flags); - func_exit(); - return IRQ_HANDLED; -} - - -/* - * Routines for open & close processing. - */ - -static void turn_ints_off(struct specialix_board *bp) -{ - unsigned long flags; - - func_enter(); - spin_lock_irqsave(&bp->lock, flags); - (void) sx_in_off(bp, 0); /* Turn off interrupts. */ - spin_unlock_irqrestore(&bp->lock, flags); - - func_exit(); -} - -static void turn_ints_on(struct specialix_board *bp) -{ - unsigned long flags; - - func_enter(); - - spin_lock_irqsave(&bp->lock, flags); - (void) sx_in(bp, 0); /* Turn ON interrupts. */ - spin_unlock_irqrestore(&bp->lock, flags); - - func_exit(); -} - - -/* Called with disabled interrupts */ -static int sx_setup_board(struct specialix_board *bp) -{ - int error; - - if (bp->flags & SX_BOARD_ACTIVE) - return 0; - - if (bp->flags & SX_BOARD_IS_PCI) - error = request_irq(bp->irq, sx_interrupt, - IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp); - else - error = request_irq(bp->irq, sx_interrupt, - IRQF_DISABLED, "specialix IO8+", bp); - - if (error) - return error; - - turn_ints_on(bp); - bp->flags |= SX_BOARD_ACTIVE; - - return 0; -} - - -/* Called with disabled interrupts */ -static void sx_shutdown_board(struct specialix_board *bp) -{ - func_enter(); - - if (!(bp->flags & SX_BOARD_ACTIVE)) { - func_exit(); - return; - } - - bp->flags &= ~SX_BOARD_ACTIVE; - - dprintk(SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n", - bp->irq, board_No(bp)); - free_irq(bp->irq, bp); - turn_ints_off(bp); - func_exit(); -} - -static unsigned int sx_crtscts(struct tty_struct *tty) -{ - if (sx_rtscts) - return C_CRTSCTS(tty); - return 1; -} - -/* - * Setting up port characteristics. - * Must be called with disabled interrupts - */ -static void sx_change_speed(struct specialix_board *bp, - struct specialix_port *port) -{ - struct tty_struct *tty; - unsigned long baud; - long tmp; - unsigned char cor1 = 0, cor3 = 0; - unsigned char mcor1 = 0, mcor2 = 0; - static unsigned long again; - unsigned long flags; - - func_enter(); - - tty = port->port.tty; - if (!tty || !tty->termios) { - func_exit(); - return; - } - - port->IER = 0; - port->COR2 = 0; - /* Select port on the board */ - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CAR, port_No(port)); - - /* The Specialix board doens't implement the RTS lines. - They are used to set the IRQ level. Don't touch them. */ - if (sx_crtscts(tty)) - port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS); - else - port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS); - spin_unlock_irqrestore(&bp->lock, flags); - dprintk(SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR); - baud = tty_get_baud_rate(tty); - - if (baud == 38400) { - if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - baud = 57600; - if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - baud = 115200; - } - - if (!baud) { - /* Drop DTR & exit */ - dprintk(SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n"); - if (!sx_crtscts(tty)) { - port->MSVR &= ~MSVR_DTR; - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_MSVR, port->MSVR); - spin_unlock_irqrestore(&bp->lock, flags); - } else - dprintk(SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n"); - return; - } else { - /* Set DTR on */ - if (!sx_crtscts(tty)) - port->MSVR |= MSVR_DTR; - } - - /* - * Now we must calculate some speed depended things - */ - - /* Set baud rate for port */ - tmp = port->custom_divisor ; - if (tmp) - printk(KERN_INFO - "sx%d: Using custom baud rate divisor %ld. \n" - "This is an untested option, please be careful.\n", - port_No(port), tmp); - else - tmp = (((SX_OSCFREQ + baud/2) / baud + CD186x_TPC/2) / - CD186x_TPC); - - if (tmp < 0x10 && time_before(again, jiffies)) { - again = jiffies + HZ * 60; - /* Page 48 of version 2.0 of the CL-CD1865 databook */ - if (tmp >= 12) { - printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n" - "Performance degradation is possible.\n" - "Read specialix.txt for more info.\n", - port_No(port), tmp); - } else { - printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n" - "Warning: overstressing Cirrus chip. This might not work.\n" - "Read specialix.txt for more info.\n", port_No(port), tmp); - } - } - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff); - sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff); - sx_out(bp, CD186x_RBPRL, tmp & 0xff); - sx_out(bp, CD186x_TBPRL, tmp & 0xff); - spin_unlock_irqrestore(&bp->lock, flags); - if (port->custom_divisor) - baud = (SX_OSCFREQ + port->custom_divisor/2) / - port->custom_divisor; - baud = (baud + 5) / 10; /* Estimated CPS */ - - /* Two timer ticks seems enough to wakeup something like SLIP driver */ - tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO; - port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ? - SERIAL_XMIT_SIZE - 1 : tmp); - - /* Receiver timeout will be transmission time for 1.5 chars */ - tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud; - tmp = (tmp > 0xff) ? 0xff : tmp; - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_RTPR, tmp); - spin_unlock_irqrestore(&bp->lock, flags); - switch (C_CSIZE(tty)) { - case CS5: - cor1 |= COR1_5BITS; - break; - case CS6: - cor1 |= COR1_6BITS; - break; - case CS7: - cor1 |= COR1_7BITS; - break; - case CS8: - cor1 |= COR1_8BITS; - break; - } - - if (C_CSTOPB(tty)) - cor1 |= COR1_2SB; - - cor1 |= COR1_IGNORE; - if (C_PARENB(tty)) { - cor1 |= COR1_NORMPAR; - if (C_PARODD(tty)) - cor1 |= COR1_ODDP; - if (I_INPCK(tty)) - cor1 &= ~COR1_IGNORE; - } - /* Set marking of some errors */ - port->mark_mask = RCSR_OE | RCSR_TOUT; - if (I_INPCK(tty)) - port->mark_mask |= RCSR_FE | RCSR_PE; - if (I_BRKINT(tty) || I_PARMRK(tty)) - port->mark_mask |= RCSR_BREAK; - if (I_IGNPAR(tty)) - port->mark_mask &= ~(RCSR_FE | RCSR_PE); - if (I_IGNBRK(tty)) { - port->mark_mask &= ~RCSR_BREAK; - if (I_IGNPAR(tty)) - /* Real raw mode. Ignore all */ - port->mark_mask &= ~RCSR_OE; - } - /* Enable Hardware Flow Control */ - if (C_CRTSCTS(tty)) { -#ifdef SPECIALIX_BRAIN_DAMAGED_CTS - port->IER |= IER_DSR | IER_CTS; - mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD; - mcor2 |= MCOR2_DSROD | MCOR2_CTSOD; - spin_lock_irqsave(&bp->lock, flags); - tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & - (MSVR_CTS|MSVR_DSR)); - spin_unlock_irqrestore(&bp->lock, flags); -#else - port->COR2 |= COR2_CTSAE; -#endif - } - /* Enable Software Flow Control. FIXME: I'm not sure about this */ - /* Some people reported that it works, but I still doubt it */ - if (I_IXON(tty)) { - port->COR2 |= COR2_TXIBE; - cor3 |= (COR3_FCT | COR3_SCDE); - if (I_IXANY(tty)) - port->COR2 |= COR2_IXM; - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_SCHR1, START_CHAR(tty)); - sx_out(bp, CD186x_SCHR2, STOP_CHAR(tty)); - sx_out(bp, CD186x_SCHR3, START_CHAR(tty)); - sx_out(bp, CD186x_SCHR4, STOP_CHAR(tty)); - spin_unlock_irqrestore(&bp->lock, flags); - } - if (!C_CLOCAL(tty)) { - /* Enable CD check */ - port->IER |= IER_CD; - mcor1 |= MCOR1_CDZD; - mcor2 |= MCOR2_CDOD; - } - - if (C_CREAD(tty)) - /* Enable receiver */ - port->IER |= IER_RXD; - - /* Set input FIFO size (1-8 bytes) */ - cor3 |= sx_rxfifo; - /* Setting up CD186x channel registers */ - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_COR1, cor1); - sx_out(bp, CD186x_COR2, port->COR2); - sx_out(bp, CD186x_COR3, cor3); - spin_unlock_irqrestore(&bp->lock, flags); - /* Make CD186x know about registers change */ - sx_wait_CCR(bp); - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3); - /* Setting up modem option registers */ - dprintk(SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n", - mcor1, mcor2); - sx_out(bp, CD186x_MCOR1, mcor1); - sx_out(bp, CD186x_MCOR2, mcor2); - spin_unlock_irqrestore(&bp->lock, flags); - /* Enable CD186x transmitter & receiver */ - sx_wait_CCR(bp); - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN); - /* Enable interrupts */ - sx_out(bp, CD186x_IER, port->IER); - /* And finally set the modem lines... */ - sx_out(bp, CD186x_MSVR, port->MSVR); - spin_unlock_irqrestore(&bp->lock, flags); - - func_exit(); -} - - -/* Must be called with interrupts enabled */ -static int sx_setup_port(struct specialix_board *bp, - struct specialix_port *port) -{ - unsigned long flags; - - func_enter(); - - if (port->port.flags & ASYNC_INITIALIZED) { - func_exit(); - return 0; - } - - if (!port->xmit_buf) { - /* We may sleep in get_zeroed_page() */ - unsigned long tmp; - - tmp = get_zeroed_page(GFP_KERNEL); - if (tmp == 0L) { - func_exit(); - return -ENOMEM; - } - - if (port->xmit_buf) { - free_page(tmp); - func_exit(); - return -ERESTARTSYS; - } - port->xmit_buf = (unsigned char *) tmp; - } - - spin_lock_irqsave(&port->lock, flags); - - if (port->port.tty) - clear_bit(TTY_IO_ERROR, &port->port.tty->flags); - - port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; - sx_change_speed(bp, port); - port->port.flags |= ASYNC_INITIALIZED; - - spin_unlock_irqrestore(&port->lock, flags); - - - func_exit(); - return 0; -} - - -/* Must be called with interrupts disabled */ -static void sx_shutdown_port(struct specialix_board *bp, - struct specialix_port *port) -{ - struct tty_struct *tty; - int i; - unsigned long flags; - - func_enter(); - - if (!(port->port.flags & ASYNC_INITIALIZED)) { - func_exit(); - return; - } - - if (sx_debug & SX_DEBUG_FIFO) { - dprintk(SX_DEBUG_FIFO, - "sx%d: port %d: %ld overruns, FIFO hits [ ", - board_No(bp), port_No(port), port->overrun); - for (i = 0; i < 10; i++) - dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]); - dprintk(SX_DEBUG_FIFO, "].\n"); - } - - if (port->xmit_buf) { - free_page((unsigned long) port->xmit_buf); - port->xmit_buf = NULL; - } - - /* Select port */ - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CAR, port_No(port)); - - tty = port->port.tty; - if (tty == NULL || C_HUPCL(tty)) { - /* Drop DTR */ - sx_out(bp, CD186x_MSVDTR, 0); - } - spin_unlock_irqrestore(&bp->lock, flags); - /* Reset port */ - sx_wait_CCR(bp); - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CCR, CCR_SOFTRESET); - /* Disable all interrupts from this port */ - port->IER = 0; - sx_out(bp, CD186x_IER, port->IER); - spin_unlock_irqrestore(&bp->lock, flags); - if (tty) - set_bit(TTY_IO_ERROR, &tty->flags); - port->port.flags &= ~ASYNC_INITIALIZED; - - if (!bp->count) - sx_shutdown_board(bp); - func_exit(); -} - - -static int block_til_ready(struct tty_struct *tty, struct file *filp, - struct specialix_port *port) -{ - DECLARE_WAITQUEUE(wait, current); - struct specialix_board *bp = port_Board(port); - int retval; - int do_clocal = 0; - int CD; - unsigned long flags; - - func_enter(); - - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) { - interruptible_sleep_on(&port->port.close_wait); - if (port->port.flags & ASYNC_HUP_NOTIFY) { - func_exit(); - return -EAGAIN; - } else { - func_exit(); - return -ERESTARTSYS; - } - } - - /* - * If non-blocking mode is set, or the port is not enabled, - * then make the check up front and then exit. - */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR))) { - port->port.flags |= ASYNC_NORMAL_ACTIVE; - func_exit(); - return 0; - } - - if (C_CLOCAL(tty)) - do_clocal = 1; - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, info->count is dropped by one, so that - * rs_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; - add_wait_queue(&port->port.open_wait, &wait); - spin_lock_irqsave(&port->lock, flags); - if (!tty_hung_up_p(filp)) - port->port.count--; - spin_unlock_irqrestore(&port->lock, flags); - port->port.blocked_open++; - while (1) { - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CAR, port_No(port)); - CD = sx_in(bp, CD186x_MSVR) & MSVR_CD; - if (sx_crtscts(tty)) { - /* Activate RTS */ - port->MSVR |= MSVR_DTR; /* WTF? */ - sx_out(bp, CD186x_MSVR, port->MSVR); - } else { - /* Activate DTR */ - port->MSVR |= MSVR_DTR; - sx_out(bp, CD186x_MSVR, port->MSVR); - } - spin_unlock_irqrestore(&bp->lock, flags); - set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !(port->port.flags & ASYNC_INITIALIZED)) { - if (port->port.flags & ASYNC_HUP_NOTIFY) - retval = -EAGAIN; - else - retval = -ERESTARTSYS; - break; - } - if (!(port->port.flags & ASYNC_CLOSING) && - (do_clocal || CD)) - break; - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } - tty_unlock(); - schedule(); - tty_lock(); - } - - set_current_state(TASK_RUNNING); - remove_wait_queue(&port->port.open_wait, &wait); - spin_lock_irqsave(&port->lock, flags); - if (!tty_hung_up_p(filp)) - port->port.count++; - port->port.blocked_open--; - spin_unlock_irqrestore(&port->lock, flags); - if (retval) { - func_exit(); - return retval; - } - - port->port.flags |= ASYNC_NORMAL_ACTIVE; - func_exit(); - return 0; -} - - -static int sx_open(struct tty_struct *tty, struct file *filp) -{ - int board; - int error; - struct specialix_port *port; - struct specialix_board *bp; - int i; - unsigned long flags; - - func_enter(); - - board = SX_BOARD(tty->index); - - if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) { - func_exit(); - return -ENODEV; - } - - bp = &sx_board[board]; - port = sx_port + board * SX_NPORT + SX_PORT(tty->index); - port->overrun = 0; - for (i = 0; i < 10; i++) - port->hits[i] = 0; - - dprintk(SX_DEBUG_OPEN, - "Board = %d, bp = %p, port = %p, portno = %d.\n", - board, bp, port, SX_PORT(tty->index)); - - if (sx_paranoia_check(port, tty->name, "sx_open")) { - func_enter(); - return -ENODEV; - } - - error = sx_setup_board(bp); - if (error) { - func_exit(); - return error; - } - - spin_lock_irqsave(&bp->lock, flags); - port->port.count++; - bp->count++; - tty->driver_data = port; - port->port.tty = tty; - spin_unlock_irqrestore(&bp->lock, flags); - - error = sx_setup_port(bp, port); - if (error) { - func_enter(); - return error; - } - - error = block_til_ready(tty, filp, port); - if (error) { - func_enter(); - return error; - } - - func_exit(); - return 0; -} - -static void sx_flush_buffer(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - unsigned long flags; - struct specialix_board *bp; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) { - func_exit(); - return; - } - - bp = port_Board(port); - spin_lock_irqsave(&port->lock, flags); - port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; - spin_unlock_irqrestore(&port->lock, flags); - tty_wakeup(tty); - - func_exit(); -} - -static void sx_close(struct tty_struct *tty, struct file *filp) -{ - struct specialix_port *port = tty->driver_data; - struct specialix_board *bp; - unsigned long flags; - unsigned long timeout; - - func_enter(); - if (!port || sx_paranoia_check(port, tty->name, "close")) { - func_exit(); - return; - } - spin_lock_irqsave(&port->lock, flags); - - if (tty_hung_up_p(filp)) { - spin_unlock_irqrestore(&port->lock, flags); - func_exit(); - return; - } - - bp = port_Board(port); - if (tty->count == 1 && port->port.count != 1) { - printk(KERN_ERR "sx%d: sx_close: bad port count;" - " tty->count is 1, port count is %d\n", - board_No(bp), port->port.count); - port->port.count = 1; - } - - if (port->port.count > 1) { - port->port.count--; - bp->count--; - - spin_unlock_irqrestore(&port->lock, flags); - - func_exit(); - return; - } - port->port.flags |= ASYNC_CLOSING; - /* - * Now we wait for the transmit buffer to clear; and we notify - * the line discipline to only process XON/XOFF characters. - */ - tty->closing = 1; - spin_unlock_irqrestore(&port->lock, flags); - dprintk(SX_DEBUG_OPEN, "Closing\n"); - if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) - tty_wait_until_sent(tty, port->port.closing_wait); - /* - * At this point we stop accepting input. To do this, we - * disable the receive line status interrupts, and tell the - * interrupt driver to stop checking the data ready bit in the - * line status register. - */ - dprintk(SX_DEBUG_OPEN, "Closed\n"); - port->IER &= ~IER_RXD; - if (port->port.flags & ASYNC_INITIALIZED) { - port->IER &= ~IER_TXRDY; - port->IER |= IER_TXEMPTY; - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CAR, port_No(port)); - sx_out(bp, CD186x_IER, port->IER); - spin_unlock_irqrestore(&bp->lock, flags); - /* - * Before we drop DTR, make sure the UART transmitter - * has completely drained; this is especially - * important if there is a transmit FIFO! - */ - timeout = jiffies+HZ; - while (port->IER & IER_TXEMPTY) { - set_current_state(TASK_INTERRUPTIBLE); - msleep_interruptible(jiffies_to_msecs(port->timeout)); - if (time_after(jiffies, timeout)) { - printk(KERN_INFO "Timeout waiting for close\n"); - break; - } - } - - } - - if (--bp->count < 0) { - printk(KERN_ERR - "sx%d: sx_shutdown_port: bad board count: %d port: %d\n", - board_No(bp), bp->count, tty->index); - bp->count = 0; - } - if (--port->port.count < 0) { - printk(KERN_ERR - "sx%d: sx_close: bad port count for tty%d: %d\n", - board_No(bp), port_No(port), port->port.count); - port->port.count = 0; - } - - sx_shutdown_port(bp, port); - sx_flush_buffer(tty); - tty_ldisc_flush(tty); - spin_lock_irqsave(&port->lock, flags); - tty->closing = 0; - port->port.tty = NULL; - spin_unlock_irqrestore(&port->lock, flags); - if (port->port.blocked_open) { - if (port->port.close_delay) - msleep_interruptible( - jiffies_to_msecs(port->port.close_delay)); - wake_up_interruptible(&port->port.open_wait); - } - port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); - wake_up_interruptible(&port->port.close_wait); - - func_exit(); -} - - -static int sx_write(struct tty_struct *tty, - const unsigned char *buf, int count) -{ - struct specialix_port *port = tty->driver_data; - struct specialix_board *bp; - int c, total = 0; - unsigned long flags; - - func_enter(); - if (sx_paranoia_check(port, tty->name, "sx_write")) { - func_exit(); - return 0; - } - - bp = port_Board(port); - - if (!port->xmit_buf) { - func_exit(); - return 0; - } - - while (1) { - spin_lock_irqsave(&port->lock, flags); - c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, - SERIAL_XMIT_SIZE - port->xmit_head)); - if (c <= 0) { - spin_unlock_irqrestore(&port->lock, flags); - break; - } - memcpy(port->xmit_buf + port->xmit_head, buf, c); - port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); - port->xmit_cnt += c; - spin_unlock_irqrestore(&port->lock, flags); - - buf += c; - count -= c; - total += c; - } - - spin_lock_irqsave(&bp->lock, flags); - if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped && - !(port->IER & IER_TXRDY)) { - port->IER |= IER_TXRDY; - sx_out(bp, CD186x_CAR, port_No(port)); - sx_out(bp, CD186x_IER, port->IER); - } - spin_unlock_irqrestore(&bp->lock, flags); - func_exit(); - - return total; -} - - -static int sx_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct specialix_port *port = tty->driver_data; - unsigned long flags; - struct specialix_board *bp; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_put_char")) { - func_exit(); - return 0; - } - dprintk(SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf); - if (!port->xmit_buf) { - func_exit(); - return 0; - } - bp = port_Board(port); - spin_lock_irqsave(&port->lock, flags); - - dprintk(SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n", - port->xmit_cnt, port->xmit_buf); - if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1 || !port->xmit_buf) { - spin_unlock_irqrestore(&port->lock, flags); - dprintk(SX_DEBUG_TX, "Exit size\n"); - func_exit(); - return 0; - } - dprintk(SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf); - port->xmit_buf[port->xmit_head++] = ch; - port->xmit_head &= SERIAL_XMIT_SIZE - 1; - port->xmit_cnt++; - spin_unlock_irqrestore(&port->lock, flags); - - func_exit(); - return 1; -} - - -static void sx_flush_chars(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - unsigned long flags; - struct specialix_board *bp = port_Board(port); - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_flush_chars")) { - func_exit(); - return; - } - if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || - !port->xmit_buf) { - func_exit(); - return; - } - spin_lock_irqsave(&bp->lock, flags); - port->IER |= IER_TXRDY; - sx_out(port_Board(port), CD186x_CAR, port_No(port)); - sx_out(port_Board(port), CD186x_IER, port->IER); - spin_unlock_irqrestore(&bp->lock, flags); - - func_exit(); -} - - -static int sx_write_room(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - int ret; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_write_room")) { - func_exit(); - return 0; - } - - ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1; - if (ret < 0) - ret = 0; - - func_exit(); - return ret; -} - - -static int sx_chars_in_buffer(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) { - func_exit(); - return 0; - } - func_exit(); - return port->xmit_cnt; -} - -static int sx_tiocmget(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - struct specialix_board *bp; - unsigned char status; - unsigned int result; - unsigned long flags; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, __func__)) { - func_exit(); - return -ENODEV; - } - - bp = port_Board(port); - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CAR, port_No(port)); - status = sx_in(bp, CD186x_MSVR); - spin_unlock_irqrestore(&bp->lock, flags); - dprintk(SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n", - port_No(port), status, sx_in(bp, CD186x_CAR)); - dprintk(SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port); - if (sx_crtscts(port->port.tty)) { - result = TIOCM_DTR | TIOCM_DSR - | ((status & MSVR_DTR) ? TIOCM_RTS : 0) - | ((status & MSVR_CD) ? TIOCM_CAR : 0) - | ((status & MSVR_CTS) ? TIOCM_CTS : 0); - } else { - result = TIOCM_RTS | TIOCM_DSR - | ((status & MSVR_DTR) ? TIOCM_DTR : 0) - | ((status & MSVR_CD) ? TIOCM_CAR : 0) - | ((status & MSVR_CTS) ? TIOCM_CTS : 0); - } - - func_exit(); - - return result; -} - - -static int sx_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct specialix_port *port = tty->driver_data; - unsigned long flags; - struct specialix_board *bp; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, __func__)) { - func_exit(); - return -ENODEV; - } - - bp = port_Board(port); - - spin_lock_irqsave(&port->lock, flags); - if (sx_crtscts(port->port.tty)) { - if (set & TIOCM_RTS) - port->MSVR |= MSVR_DTR; - } else { - if (set & TIOCM_DTR) - port->MSVR |= MSVR_DTR; - } - if (sx_crtscts(port->port.tty)) { - if (clear & TIOCM_RTS) - port->MSVR &= ~MSVR_DTR; - } else { - if (clear & TIOCM_DTR) - port->MSVR &= ~MSVR_DTR; - } - spin_lock(&bp->lock); - sx_out(bp, CD186x_CAR, port_No(port)); - sx_out(bp, CD186x_MSVR, port->MSVR); - spin_unlock(&bp->lock); - spin_unlock_irqrestore(&port->lock, flags); - func_exit(); - return 0; -} - - -static int sx_send_break(struct tty_struct *tty, int length) -{ - struct specialix_port *port = tty->driver_data; - struct specialix_board *bp = port_Board(port); - unsigned long flags; - - func_enter(); - if (length == 0 || length == -1) - return -EOPNOTSUPP; - - spin_lock_irqsave(&port->lock, flags); - port->break_length = SPECIALIX_TPS / HZ * length; - port->COR2 |= COR2_ETC; - port->IER |= IER_TXRDY; - spin_lock(&bp->lock); - sx_out(bp, CD186x_CAR, port_No(port)); - sx_out(bp, CD186x_COR2, port->COR2); - sx_out(bp, CD186x_IER, port->IER); - spin_unlock(&bp->lock); - spin_unlock_irqrestore(&port->lock, flags); - sx_wait_CCR(bp); - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CCR, CCR_CORCHG2); - spin_unlock_irqrestore(&bp->lock, flags); - sx_wait_CCR(bp); - - func_exit(); - return 0; -} - - -static int sx_set_serial_info(struct specialix_port *port, - struct serial_struct __user *newinfo) -{ - struct serial_struct tmp; - struct specialix_board *bp = port_Board(port); - int change_speed; - - func_enter(); - - if (copy_from_user(&tmp, newinfo, sizeof(tmp))) { - func_enter(); - return -EFAULT; - } - - mutex_lock(&port->port.mutex); - change_speed = ((port->port.flags & ASYNC_SPD_MASK) != - (tmp.flags & ASYNC_SPD_MASK)); - change_speed |= (tmp.custom_divisor != port->custom_divisor); - - if (!capable(CAP_SYS_ADMIN)) { - if ((tmp.close_delay != port->port.close_delay) || - (tmp.closing_wait != port->port.closing_wait) || - ((tmp.flags & ~ASYNC_USR_MASK) != - (port->port.flags & ~ASYNC_USR_MASK))) { - func_exit(); - mutex_unlock(&port->port.mutex); - return -EPERM; - } - port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | - (tmp.flags & ASYNC_USR_MASK)); - port->custom_divisor = tmp.custom_divisor; - } else { - port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) | - (tmp.flags & ASYNC_FLAGS)); - port->port.close_delay = tmp.close_delay; - port->port.closing_wait = tmp.closing_wait; - port->custom_divisor = tmp.custom_divisor; - } - if (change_speed) - sx_change_speed(bp, port); - - func_exit(); - mutex_unlock(&port->port.mutex); - return 0; -} - - -static int sx_get_serial_info(struct specialix_port *port, - struct serial_struct __user *retinfo) -{ - struct serial_struct tmp; - struct specialix_board *bp = port_Board(port); - - func_enter(); - - memset(&tmp, 0, sizeof(tmp)); - mutex_lock(&port->port.mutex); - tmp.type = PORT_CIRRUS; - tmp.line = port - sx_port; - tmp.port = bp->base; - tmp.irq = bp->irq; - tmp.flags = port->port.flags; - tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC; - tmp.close_delay = port->port.close_delay * HZ/100; - tmp.closing_wait = port->port.closing_wait * HZ/100; - tmp.custom_divisor = port->custom_divisor; - tmp.xmit_fifo_size = CD186x_NFIFO; - mutex_unlock(&port->port.mutex); - if (copy_to_user(retinfo, &tmp, sizeof(tmp))) { - func_exit(); - return -EFAULT; - } - - func_exit(); - return 0; -} - - -static int sx_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct specialix_port *port = tty->driver_data; - void __user *argp = (void __user *)arg; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_ioctl")) { - func_exit(); - return -ENODEV; - } - - switch (cmd) { - case TIOCGSERIAL: - func_exit(); - return sx_get_serial_info(port, argp); - case TIOCSSERIAL: - func_exit(); - return sx_set_serial_info(port, argp); - default: - func_exit(); - return -ENOIOCTLCMD; - } - func_exit(); - return 0; -} - - -static void sx_throttle(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - struct specialix_board *bp; - unsigned long flags; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_throttle")) { - func_exit(); - return; - } - - bp = port_Board(port); - - /* Use DTR instead of RTS ! */ - if (sx_crtscts(tty)) - port->MSVR &= ~MSVR_DTR; - else { - /* Auch!!! I think the system shouldn't call this then. */ - /* Or maybe we're supposed (allowed?) to do our side of hw - handshake anyway, even when hardware handshake is off. - When you see this in your logs, please report.... */ - printk(KERN_ERR - "sx%d: Need to throttle, but can't (hardware hs is off)\n", - port_No(port)); - } - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CAR, port_No(port)); - spin_unlock_irqrestore(&bp->lock, flags); - if (I_IXOFF(tty)) { - sx_wait_CCR(bp); - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CCR, CCR_SSCH2); - spin_unlock_irqrestore(&bp->lock, flags); - sx_wait_CCR(bp); - } - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_MSVR, port->MSVR); - spin_unlock_irqrestore(&bp->lock, flags); - - func_exit(); -} - - -static void sx_unthrottle(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - struct specialix_board *bp; - unsigned long flags; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) { - func_exit(); - return; - } - - bp = port_Board(port); - - spin_lock_irqsave(&port->lock, flags); - /* XXXX Use DTR INSTEAD???? */ - if (sx_crtscts(tty)) - port->MSVR |= MSVR_DTR; - /* Else clause: see remark in "sx_throttle"... */ - spin_lock(&bp->lock); - sx_out(bp, CD186x_CAR, port_No(port)); - spin_unlock(&bp->lock); - if (I_IXOFF(tty)) { - spin_unlock_irqrestore(&port->lock, flags); - sx_wait_CCR(bp); - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CCR, CCR_SSCH1); - spin_unlock_irqrestore(&bp->lock, flags); - sx_wait_CCR(bp); - spin_lock_irqsave(&port->lock, flags); - } - spin_lock(&bp->lock); - sx_out(bp, CD186x_MSVR, port->MSVR); - spin_unlock(&bp->lock); - spin_unlock_irqrestore(&port->lock, flags); - - func_exit(); -} - - -static void sx_stop(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - struct specialix_board *bp; - unsigned long flags; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_stop")) { - func_exit(); - return; - } - - bp = port_Board(port); - - spin_lock_irqsave(&port->lock, flags); - port->IER &= ~IER_TXRDY; - spin_lock(&bp->lock); - sx_out(bp, CD186x_CAR, port_No(port)); - sx_out(bp, CD186x_IER, port->IER); - spin_unlock(&bp->lock); - spin_unlock_irqrestore(&port->lock, flags); - - func_exit(); -} - - -static void sx_start(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - struct specialix_board *bp; - unsigned long flags; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_start")) { - func_exit(); - return; - } - - bp = port_Board(port); - - spin_lock_irqsave(&port->lock, flags); - if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { - port->IER |= IER_TXRDY; - spin_lock(&bp->lock); - sx_out(bp, CD186x_CAR, port_No(port)); - sx_out(bp, CD186x_IER, port->IER); - spin_unlock(&bp->lock); - } - spin_unlock_irqrestore(&port->lock, flags); - - func_exit(); -} - -static void sx_hangup(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - struct specialix_board *bp; - unsigned long flags; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_hangup")) { - func_exit(); - return; - } - - bp = port_Board(port); - - sx_shutdown_port(bp, port); - spin_lock_irqsave(&port->lock, flags); - bp->count -= port->port.count; - if (bp->count < 0) { - printk(KERN_ERR - "sx%d: sx_hangup: bad board count: %d port: %d\n", - board_No(bp), bp->count, tty->index); - bp->count = 0; - } - port->port.count = 0; - port->port.flags &= ~ASYNC_NORMAL_ACTIVE; - port->port.tty = NULL; - spin_unlock_irqrestore(&port->lock, flags); - wake_up_interruptible(&port->port.open_wait); - - func_exit(); -} - - -static void sx_set_termios(struct tty_struct *tty, - struct ktermios *old_termios) -{ - struct specialix_port *port = tty->driver_data; - unsigned long flags; - struct specialix_board *bp; - - if (sx_paranoia_check(port, tty->name, "sx_set_termios")) - return; - - bp = port_Board(port); - spin_lock_irqsave(&port->lock, flags); - sx_change_speed(port_Board(port), port); - spin_unlock_irqrestore(&port->lock, flags); - - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - sx_start(tty); - } -} - -static const struct tty_operations sx_ops = { - .open = sx_open, - .close = sx_close, - .write = sx_write, - .put_char = sx_put_char, - .flush_chars = sx_flush_chars, - .write_room = sx_write_room, - .chars_in_buffer = sx_chars_in_buffer, - .flush_buffer = sx_flush_buffer, - .ioctl = sx_ioctl, - .throttle = sx_throttle, - .unthrottle = sx_unthrottle, - .set_termios = sx_set_termios, - .stop = sx_stop, - .start = sx_start, - .hangup = sx_hangup, - .tiocmget = sx_tiocmget, - .tiocmset = sx_tiocmset, - .break_ctl = sx_send_break, -}; - -static int sx_init_drivers(void) -{ - int error; - int i; - - func_enter(); - - specialix_driver = alloc_tty_driver(SX_NBOARD * SX_NPORT); - if (!specialix_driver) { - printk(KERN_ERR "sx: Couldn't allocate tty_driver.\n"); - func_exit(); - return 1; - } - - specialix_driver->owner = THIS_MODULE; - specialix_driver->name = "ttyW"; - specialix_driver->major = SPECIALIX_NORMAL_MAJOR; - specialix_driver->type = TTY_DRIVER_TYPE_SERIAL; - specialix_driver->subtype = SERIAL_TYPE_NORMAL; - specialix_driver->init_termios = tty_std_termios; - specialix_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - specialix_driver->init_termios.c_ispeed = 9600; - specialix_driver->init_termios.c_ospeed = 9600; - specialix_driver->flags = TTY_DRIVER_REAL_RAW | - TTY_DRIVER_HARDWARE_BREAK; - tty_set_operations(specialix_driver, &sx_ops); - - error = tty_register_driver(specialix_driver); - if (error) { - put_tty_driver(specialix_driver); - printk(KERN_ERR - "sx: Couldn't register specialix IO8+ driver, error = %d\n", - error); - func_exit(); - return 1; - } - memset(sx_port, 0, sizeof(sx_port)); - for (i = 0; i < SX_NPORT * SX_NBOARD; i++) { - sx_port[i].magic = SPECIALIX_MAGIC; - tty_port_init(&sx_port[i].port); - spin_lock_init(&sx_port[i].lock); - } - - func_exit(); - return 0; -} - -static void sx_release_drivers(void) -{ - func_enter(); - - tty_unregister_driver(specialix_driver); - put_tty_driver(specialix_driver); - func_exit(); -} - -/* - * This routine must be called by kernel at boot time - */ -static int __init specialix_init(void) -{ - int i; - int found = 0; - - func_enter(); - - printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n"); - printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n"); - if (sx_rtscts) - printk(KERN_INFO - "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n"); - else - printk(KERN_INFO "sx: DTR/RTS pin is always RTS.\n"); - - for (i = 0; i < SX_NBOARD; i++) - spin_lock_init(&sx_board[i].lock); - - if (sx_init_drivers()) { - func_exit(); - return -EIO; - } - - for (i = 0; i < SX_NBOARD; i++) - if (sx_board[i].base && !sx_probe(&sx_board[i])) - found++; - -#ifdef CONFIG_PCI - { - struct pci_dev *pdev = NULL; - - i = 0; - while (i < SX_NBOARD) { - if (sx_board[i].flags & SX_BOARD_PRESENT) { - i++; - continue; - } - pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX, - PCI_DEVICE_ID_SPECIALIX_IO8, pdev); - if (!pdev) - break; - - if (pci_enable_device(pdev)) - continue; - - sx_board[i].irq = pdev->irq; - - sx_board[i].base = pci_resource_start(pdev, 2); - - sx_board[i].flags |= SX_BOARD_IS_PCI; - if (!sx_probe(&sx_board[i])) - found++; - } - /* May exit pci_get sequence early with lots of boards */ - if (pdev != NULL) - pci_dev_put(pdev); - } -#endif - - if (!found) { - sx_release_drivers(); - printk(KERN_INFO "sx: No specialix IO8+ boards detected.\n"); - func_exit(); - return -EIO; - } - - func_exit(); - return 0; -} - -static int iobase[SX_NBOARD] = {0,}; -static int irq[SX_NBOARD] = {0,}; - -module_param_array(iobase, int, NULL, 0); -module_param_array(irq, int, NULL, 0); -module_param(sx_debug, int, 0); -module_param(sx_rtscts, int, 0); -module_param(sx_rxfifo, int, 0); - -/* - * You can setup up to 4 boards. - * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter. - * You should specify the IRQs too in that case "irq=....,...". - * - * More than 4 boards in one computer is not possible, as the card can - * only use 4 different interrupts. - * - */ -static int __init specialix_init_module(void) -{ - int i; - - func_enter(); - - if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) { - for (i = 0; i < SX_NBOARD; i++) { - sx_board[i].base = iobase[i]; - sx_board[i].irq = irq[i]; - sx_board[i].count = 0; - } - } - - func_exit(); - - return specialix_init(); -} - -static void __exit specialix_exit_module(void) -{ - int i; - - func_enter(); - - sx_release_drivers(); - for (i = 0; i < SX_NBOARD; i++) - if (sx_board[i].flags & SX_BOARD_PRESENT) - sx_release_io_range(&sx_board[i]); - func_exit(); -} - -static struct pci_device_id specialx_pci_tbl[] __devinitdata __used = { - { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_IO8) }, - { } -}; -MODULE_DEVICE_TABLE(pci, specialx_pci_tbl); - -module_init(specialix_init_module); -module_exit(specialix_exit_module); - -MODULE_LICENSE("GPL"); -MODULE_ALIAS_CHARDEV_MAJOR(SPECIALIX_NORMAL_MAJOR); diff --git a/drivers/char/specialix_io8.h b/drivers/char/specialix_io8.h deleted file mode 100644 index c63005274d9b..000000000000 --- a/drivers/char/specialix_io8.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * linux/drivers/char/specialix_io8.h -- - * Specialix IO8+ multiport serial driver. - * - * Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl) - * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) - * - * - * Specialix pays for the development and support of this driver. - * Please DO contact io8-linux@specialix.co.uk if you require - * support. - * - * This driver was developped in the BitWizard linux device - * driver service. If you require a linux device driver for your - * product, please contact devices@BitWizard.nl for a quote. - * - * This code is firmly based on the riscom/8 serial driver, - * written by Dmitry Gorodchanin. The specialix IO8+ card - * programming information was obtained from the CL-CD1865 Data - * Book, and Specialix document number 6200059: IO8+ Hardware - * Functional Specification. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, - * USA. - * */ - -#ifndef __LINUX_SPECIALIX_H -#define __LINUX_SPECIALIX_H - -#include - -#ifdef __KERNEL__ - -/* You can have max 4 ISA cards in one PC, and I recommend not much -more than a few PCI versions of the card. */ - -#define SX_NBOARD 8 - -/* NOTE: Specialix decoder recognizes 4 addresses, but only two are used.... */ -#define SX_IO_SPACE 4 -/* The PCI version decodes 8 addresses, but still only 2 are used. */ -#define SX_PCI_IO_SPACE 8 - -/* eight ports per board. */ -#define SX_NPORT 8 -#define SX_BOARD(line) ((line) / SX_NPORT) -#define SX_PORT(line) ((line) & (SX_NPORT - 1)) - - -#define SX_DATA_REG 0 /* Base+0 : Data register */ -#define SX_ADDR_REG 1 /* base+1 : Address register. */ - -#define MHz *1000000 /* I'm ashamed of myself. */ - -/* On-board oscillator frequency */ -#define SX_OSCFREQ (25 MHz/2) -/* There is a 25MHz crystal on the board, but the chip is in /2 mode */ - - -/* Ticks per sec. Used for setting receiver timeout and break length */ -#define SPECIALIX_TPS 4000 - -/* Yeah, after heavy testing I decided it must be 6. - * Sure, You can change it if needed. - */ -#define SPECIALIX_RXFIFO 6 /* Max. receiver FIFO size (1-8) */ - -#define SPECIALIX_MAGIC 0x0907 - -#define SX_CCR_TIMEOUT 10000 /* CCR timeout. You may need to wait upto - 10 milliseconds before the internal - processor is available again after - you give it a command */ - -#define SX_IOBASE1 0x100 -#define SX_IOBASE2 0x180 -#define SX_IOBASE3 0x250 -#define SX_IOBASE4 0x260 - -struct specialix_board { - unsigned long flags; - unsigned short base; - unsigned char irq; - //signed char count; - int count; - unsigned char DTR; - int reg; - spinlock_t lock; -}; - -#define SX_BOARD_PRESENT 0x00000001 -#define SX_BOARD_ACTIVE 0x00000002 -#define SX_BOARD_IS_PCI 0x00000004 - - -struct specialix_port { - int magic; - struct tty_port port; - int baud_base; - int flags; - int timeout; - unsigned char * xmit_buf; - int custom_divisor; - int xmit_head; - int xmit_tail; - int xmit_cnt; - short wakeup_chars; - short break_length; - unsigned char mark_mask; - unsigned char IER; - unsigned char MSVR; - unsigned char COR2; - unsigned long overrun; - unsigned long hits[10]; - spinlock_t lock; -}; - -#endif /* __KERNEL__ */ -#endif /* __LINUX_SPECIALIX_H */ - - - - - - - - - diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c deleted file mode 100644 index 4fff5cd3b163..000000000000 --- a/drivers/char/stallion.c +++ /dev/null @@ -1,4651 +0,0 @@ -/*****************************************************************************/ - -/* - * stallion.c -- stallion multiport serial driver. - * - * Copyright (C) 1996-1999 Stallion Technologies - * Copyright (C) 1994-1996 Greg Ungerer. - * - * This code is loosely based on the Linux serial driver, written by - * Linus Torvalds, Theodore T'so and others. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/*****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -/*****************************************************************************/ - -/* - * Define different board types. Use the standard Stallion "assigned" - * board numbers. Boards supported in this driver are abbreviated as - * EIO = EasyIO and ECH = EasyConnection 8/32. - */ -#define BRD_EASYIO 20 -#define BRD_ECH 21 -#define BRD_ECHMC 22 -#define BRD_ECHPCI 26 -#define BRD_ECH64PCI 27 -#define BRD_EASYIOPCI 28 - -struct stlconf { - unsigned int brdtype; - int ioaddr1; - int ioaddr2; - unsigned long memaddr; - int irq; - int irqtype; -}; - -static unsigned int stl_nrbrds; - -/*****************************************************************************/ - -/* - * Define some important driver characteristics. Device major numbers - * allocated as per Linux Device Registry. - */ -#ifndef STL_SIOMEMMAJOR -#define STL_SIOMEMMAJOR 28 -#endif -#ifndef STL_SERIALMAJOR -#define STL_SERIALMAJOR 24 -#endif -#ifndef STL_CALLOUTMAJOR -#define STL_CALLOUTMAJOR 25 -#endif - -/* - * Set the TX buffer size. Bigger is better, but we don't want - * to chew too much memory with buffers! - */ -#define STL_TXBUFLOW 512 -#define STL_TXBUFSIZE 4096 - -/*****************************************************************************/ - -/* - * Define our local driver identity first. Set up stuff to deal with - * all the local structures required by a serial tty driver. - */ -static char *stl_drvtitle = "Stallion Multiport Serial Driver"; -static char *stl_drvname = "stallion"; -static char *stl_drvversion = "5.6.0"; - -static struct tty_driver *stl_serial; - -/* - * Define a local default termios struct. All ports will be created - * with this termios initially. Basically all it defines is a raw port - * at 9600, 8 data bits, 1 stop bit. - */ -static struct ktermios stl_deftermios = { - .c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL), - .c_cc = INIT_C_CC, - .c_ispeed = 9600, - .c_ospeed = 9600, -}; - -/* - * Define global place to put buffer overflow characters. - */ -static char stl_unwanted[SC26198_RXFIFOSIZE]; - -/*****************************************************************************/ - -static DEFINE_MUTEX(stl_brdslock); -static struct stlbrd *stl_brds[STL_MAXBRDS]; - -static const struct tty_port_operations stl_port_ops; - -/* - * Per board state flags. Used with the state field of the board struct. - * Not really much here! - */ -#define BRD_FOUND 0x1 -#define STL_PROBED 0x2 - - -/* - * Define the port structure istate flags. These set of flags are - * modified at interrupt time - so setting and reseting them needs - * to be atomic. Use the bit clear/setting routines for this. - */ -#define ASYI_TXBUSY 1 -#define ASYI_TXLOW 2 -#define ASYI_TXFLOWED 3 - -/* - * Define an array of board names as printable strings. Handy for - * referencing boards when printing trace and stuff. - */ -static char *stl_brdnames[] = { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "EasyIO", - "EC8/32-AT", - "EC8/32-MC", - NULL, - NULL, - NULL, - "EC8/32-PCI", - "EC8/64-PCI", - "EasyIO-PCI", -}; - -/*****************************************************************************/ - -/* - * Define some string labels for arguments passed from the module - * load line. These allow for easy board definitions, and easy - * modification of the io, memory and irq resoucres. - */ -static unsigned int stl_nargs; -static char *board0[4]; -static char *board1[4]; -static char *board2[4]; -static char *board3[4]; - -static char **stl_brdsp[] = { - (char **) &board0, - (char **) &board1, - (char **) &board2, - (char **) &board3 -}; - -/* - * Define a set of common board names, and types. This is used to - * parse any module arguments. - */ - -static struct { - char *name; - int type; -} stl_brdstr[] = { - { "easyio", BRD_EASYIO }, - { "eio", BRD_EASYIO }, - { "20", BRD_EASYIO }, - { "ec8/32", BRD_ECH }, - { "ec8/32-at", BRD_ECH }, - { "ec8/32-isa", BRD_ECH }, - { "ech", BRD_ECH }, - { "echat", BRD_ECH }, - { "21", BRD_ECH }, - { "ec8/32-mc", BRD_ECHMC }, - { "ec8/32-mca", BRD_ECHMC }, - { "echmc", BRD_ECHMC }, - { "echmca", BRD_ECHMC }, - { "22", BRD_ECHMC }, - { "ec8/32-pc", BRD_ECHPCI }, - { "ec8/32-pci", BRD_ECHPCI }, - { "26", BRD_ECHPCI }, - { "ec8/64-pc", BRD_ECH64PCI }, - { "ec8/64-pci", BRD_ECH64PCI }, - { "ech-pci", BRD_ECH64PCI }, - { "echpci", BRD_ECH64PCI }, - { "echpc", BRD_ECH64PCI }, - { "27", BRD_ECH64PCI }, - { "easyio-pc", BRD_EASYIOPCI }, - { "easyio-pci", BRD_EASYIOPCI }, - { "eio-pci", BRD_EASYIOPCI }, - { "eiopci", BRD_EASYIOPCI }, - { "28", BRD_EASYIOPCI }, -}; - -/* - * Define the module agruments. - */ - -module_param_array(board0, charp, &stl_nargs, 0); -MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,ioaddr2][,irq]]"); -module_param_array(board1, charp, &stl_nargs, 0); -MODULE_PARM_DESC(board1, "Board 1 config -> name[,ioaddr[,ioaddr2][,irq]]"); -module_param_array(board2, charp, &stl_nargs, 0); -MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,ioaddr2][,irq]]"); -module_param_array(board3, charp, &stl_nargs, 0); -MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,ioaddr2][,irq]]"); - -/*****************************************************************************/ - -/* - * Hardware ID bits for the EasyIO and ECH boards. These defines apply - * to the directly accessible io ports of these boards (not the uarts - - * they are in cd1400.h and sc26198.h). - */ -#define EIO_8PORTRS 0x04 -#define EIO_4PORTRS 0x05 -#define EIO_8PORTDI 0x00 -#define EIO_8PORTM 0x06 -#define EIO_MK3 0x03 -#define EIO_IDBITMASK 0x07 - -#define EIO_BRDMASK 0xf0 -#define ID_BRD4 0x10 -#define ID_BRD8 0x20 -#define ID_BRD16 0x30 - -#define EIO_INTRPEND 0x08 -#define EIO_INTEDGE 0x00 -#define EIO_INTLEVEL 0x08 -#define EIO_0WS 0x10 - -#define ECH_ID 0xa0 -#define ECH_IDBITMASK 0xe0 -#define ECH_BRDENABLE 0x08 -#define ECH_BRDDISABLE 0x00 -#define ECH_INTENABLE 0x01 -#define ECH_INTDISABLE 0x00 -#define ECH_INTLEVEL 0x02 -#define ECH_INTEDGE 0x00 -#define ECH_INTRPEND 0x01 -#define ECH_BRDRESET 0x01 - -#define ECHMC_INTENABLE 0x01 -#define ECHMC_BRDRESET 0x02 - -#define ECH_PNLSTATUS 2 -#define ECH_PNL16PORT 0x20 -#define ECH_PNLIDMASK 0x07 -#define ECH_PNLXPID 0x40 -#define ECH_PNLINTRPEND 0x80 - -#define ECH_ADDR2MASK 0x1e0 - -/* - * Define the vector mapping bits for the programmable interrupt board - * hardware. These bits encode the interrupt for the board to use - it - * is software selectable (except the EIO-8M). - */ -static unsigned char stl_vecmap[] = { - 0xff, 0xff, 0xff, 0x04, 0x06, 0x05, 0xff, 0x07, - 0xff, 0xff, 0x00, 0x02, 0x01, 0xff, 0xff, 0x03 -}; - -/* - * Lock ordering is that you may not take stallion_lock holding - * brd_lock. - */ - -static spinlock_t brd_lock; /* Guard the board mapping */ -static spinlock_t stallion_lock; /* Guard the tty driver */ - -/* - * Set up enable and disable macros for the ECH boards. They require - * the secondary io address space to be activated and deactivated. - * This way all ECH boards can share their secondary io region. - * If this is an ECH-PCI board then also need to set the page pointer - * to point to the correct page. - */ -#define BRDENABLE(brdnr,pagenr) \ - if (stl_brds[(brdnr)]->brdtype == BRD_ECH) \ - outb((stl_brds[(brdnr)]->ioctrlval | ECH_BRDENABLE), \ - stl_brds[(brdnr)]->ioctrl); \ - else if (stl_brds[(brdnr)]->brdtype == BRD_ECHPCI) \ - outb((pagenr), stl_brds[(brdnr)]->ioctrl); - -#define BRDDISABLE(brdnr) \ - if (stl_brds[(brdnr)]->brdtype == BRD_ECH) \ - outb((stl_brds[(brdnr)]->ioctrlval | ECH_BRDDISABLE), \ - stl_brds[(brdnr)]->ioctrl); - -#define STL_CD1400MAXBAUD 230400 -#define STL_SC26198MAXBAUD 460800 - -#define STL_BAUDBASE 115200 -#define STL_CLOSEDELAY (5 * HZ / 10) - -/*****************************************************************************/ - -/* - * Define the Stallion PCI vendor and device IDs. - */ -#ifndef PCI_VENDOR_ID_STALLION -#define PCI_VENDOR_ID_STALLION 0x124d -#endif -#ifndef PCI_DEVICE_ID_ECHPCI832 -#define PCI_DEVICE_ID_ECHPCI832 0x0000 -#endif -#ifndef PCI_DEVICE_ID_ECHPCI864 -#define PCI_DEVICE_ID_ECHPCI864 0x0002 -#endif -#ifndef PCI_DEVICE_ID_EIOPCI -#define PCI_DEVICE_ID_EIOPCI 0x0003 -#endif - -/* - * Define structure to hold all Stallion PCI boards. - */ - -static struct pci_device_id stl_pcibrds[] = { - { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI864), - .driver_data = BRD_ECH64PCI }, - { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_EIOPCI), - .driver_data = BRD_EASYIOPCI }, - { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI832), - .driver_data = BRD_ECHPCI }, - { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410), - .driver_data = BRD_ECHPCI }, - { } -}; -MODULE_DEVICE_TABLE(pci, stl_pcibrds); - -/*****************************************************************************/ - -/* - * Define macros to extract a brd/port number from a minor number. - */ -#define MINOR2BRD(min) (((min) & 0xc0) >> 6) -#define MINOR2PORT(min) ((min) & 0x3f) - -/* - * Define a baud rate table that converts termios baud rate selector - * into the actual baud rate value. All baud rate calculations are - * based on the actual baud rate required. - */ -static unsigned int stl_baudrates[] = { - 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, - 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600 -}; - -/*****************************************************************************/ - -/* - * Declare all those functions in this driver! - */ - -static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg); -static int stl_brdinit(struct stlbrd *brdp); -static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp); -static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp); - -/* - * CD1400 uart specific handling functions. - */ -static void stl_cd1400setreg(struct stlport *portp, int regnr, int value); -static int stl_cd1400getreg(struct stlport *portp, int regnr); -static int stl_cd1400updatereg(struct stlport *portp, int regnr, int value); -static int stl_cd1400panelinit(struct stlbrd *brdp, struct stlpanel *panelp); -static void stl_cd1400portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp); -static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp); -static int stl_cd1400getsignals(struct stlport *portp); -static void stl_cd1400setsignals(struct stlport *portp, int dtr, int rts); -static void stl_cd1400ccrwait(struct stlport *portp); -static void stl_cd1400enablerxtx(struct stlport *portp, int rx, int tx); -static void stl_cd1400startrxtx(struct stlport *portp, int rx, int tx); -static void stl_cd1400disableintrs(struct stlport *portp); -static void stl_cd1400sendbreak(struct stlport *portp, int len); -static void stl_cd1400flowctrl(struct stlport *portp, int state); -static void stl_cd1400sendflow(struct stlport *portp, int state); -static void stl_cd1400flush(struct stlport *portp); -static int stl_cd1400datastate(struct stlport *portp); -static void stl_cd1400eiointr(struct stlpanel *panelp, unsigned int iobase); -static void stl_cd1400echintr(struct stlpanel *panelp, unsigned int iobase); -static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr); -static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr); -static void stl_cd1400mdmisr(struct stlpanel *panelp, int ioaddr); - -static inline int stl_cd1400breakisr(struct stlport *portp, int ioaddr); - -/* - * SC26198 uart specific handling functions. - */ -static void stl_sc26198setreg(struct stlport *portp, int regnr, int value); -static int stl_sc26198getreg(struct stlport *portp, int regnr); -static int stl_sc26198updatereg(struct stlport *portp, int regnr, int value); -static int stl_sc26198getglobreg(struct stlport *portp, int regnr); -static int stl_sc26198panelinit(struct stlbrd *brdp, struct stlpanel *panelp); -static void stl_sc26198portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp); -static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp); -static int stl_sc26198getsignals(struct stlport *portp); -static void stl_sc26198setsignals(struct stlport *portp, int dtr, int rts); -static void stl_sc26198enablerxtx(struct stlport *portp, int rx, int tx); -static void stl_sc26198startrxtx(struct stlport *portp, int rx, int tx); -static void stl_sc26198disableintrs(struct stlport *portp); -static void stl_sc26198sendbreak(struct stlport *portp, int len); -static void stl_sc26198flowctrl(struct stlport *portp, int state); -static void stl_sc26198sendflow(struct stlport *portp, int state); -static void stl_sc26198flush(struct stlport *portp); -static int stl_sc26198datastate(struct stlport *portp); -static void stl_sc26198wait(struct stlport *portp); -static void stl_sc26198txunflow(struct stlport *portp, struct tty_struct *tty); -static void stl_sc26198intr(struct stlpanel *panelp, unsigned int iobase); -static void stl_sc26198txisr(struct stlport *port); -static void stl_sc26198rxisr(struct stlport *port, unsigned int iack); -static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char ch); -static void stl_sc26198rxbadchars(struct stlport *portp); -static void stl_sc26198otherisr(struct stlport *port, unsigned int iack); - -/*****************************************************************************/ - -/* - * Generic UART support structure. - */ -typedef struct uart { - int (*panelinit)(struct stlbrd *brdp, struct stlpanel *panelp); - void (*portinit)(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp); - void (*setport)(struct stlport *portp, struct ktermios *tiosp); - int (*getsignals)(struct stlport *portp); - void (*setsignals)(struct stlport *portp, int dtr, int rts); - void (*enablerxtx)(struct stlport *portp, int rx, int tx); - void (*startrxtx)(struct stlport *portp, int rx, int tx); - void (*disableintrs)(struct stlport *portp); - void (*sendbreak)(struct stlport *portp, int len); - void (*flowctrl)(struct stlport *portp, int state); - void (*sendflow)(struct stlport *portp, int state); - void (*flush)(struct stlport *portp); - int (*datastate)(struct stlport *portp); - void (*intr)(struct stlpanel *panelp, unsigned int iobase); -} uart_t; - -/* - * Define some macros to make calling these functions nice and clean. - */ -#define stl_panelinit (* ((uart_t *) panelp->uartp)->panelinit) -#define stl_portinit (* ((uart_t *) portp->uartp)->portinit) -#define stl_setport (* ((uart_t *) portp->uartp)->setport) -#define stl_getsignals (* ((uart_t *) portp->uartp)->getsignals) -#define stl_setsignals (* ((uart_t *) portp->uartp)->setsignals) -#define stl_enablerxtx (* ((uart_t *) portp->uartp)->enablerxtx) -#define stl_startrxtx (* ((uart_t *) portp->uartp)->startrxtx) -#define stl_disableintrs (* ((uart_t *) portp->uartp)->disableintrs) -#define stl_sendbreak (* ((uart_t *) portp->uartp)->sendbreak) -#define stl_flowctrl (* ((uart_t *) portp->uartp)->flowctrl) -#define stl_sendflow (* ((uart_t *) portp->uartp)->sendflow) -#define stl_flush (* ((uart_t *) portp->uartp)->flush) -#define stl_datastate (* ((uart_t *) portp->uartp)->datastate) - -/*****************************************************************************/ - -/* - * CD1400 UART specific data initialization. - */ -static uart_t stl_cd1400uart = { - stl_cd1400panelinit, - stl_cd1400portinit, - stl_cd1400setport, - stl_cd1400getsignals, - stl_cd1400setsignals, - stl_cd1400enablerxtx, - stl_cd1400startrxtx, - stl_cd1400disableintrs, - stl_cd1400sendbreak, - stl_cd1400flowctrl, - stl_cd1400sendflow, - stl_cd1400flush, - stl_cd1400datastate, - stl_cd1400eiointr -}; - -/* - * Define the offsets within the register bank of a cd1400 based panel. - * These io address offsets are common to the EasyIO board as well. - */ -#define EREG_ADDR 0 -#define EREG_DATA 4 -#define EREG_RXACK 5 -#define EREG_TXACK 6 -#define EREG_MDACK 7 - -#define EREG_BANKSIZE 8 - -#define CD1400_CLK 25000000 -#define CD1400_CLK8M 20000000 - -/* - * Define the cd1400 baud rate clocks. These are used when calculating - * what clock and divisor to use for the required baud rate. Also - * define the maximum baud rate allowed, and the default base baud. - */ -static int stl_cd1400clkdivs[] = { - CD1400_CLK0, CD1400_CLK1, CD1400_CLK2, CD1400_CLK3, CD1400_CLK4 -}; - -/*****************************************************************************/ - -/* - * SC26198 UART specific data initization. - */ -static uart_t stl_sc26198uart = { - stl_sc26198panelinit, - stl_sc26198portinit, - stl_sc26198setport, - stl_sc26198getsignals, - stl_sc26198setsignals, - stl_sc26198enablerxtx, - stl_sc26198startrxtx, - stl_sc26198disableintrs, - stl_sc26198sendbreak, - stl_sc26198flowctrl, - stl_sc26198sendflow, - stl_sc26198flush, - stl_sc26198datastate, - stl_sc26198intr -}; - -/* - * Define the offsets within the register bank of a sc26198 based panel. - */ -#define XP_DATA 0 -#define XP_ADDR 1 -#define XP_MODID 2 -#define XP_STATUS 2 -#define XP_IACK 3 - -#define XP_BANKSIZE 4 - -/* - * Define the sc26198 baud rate table. Offsets within the table - * represent the actual baud rate selector of sc26198 registers. - */ -static unsigned int sc26198_baudtable[] = { - 50, 75, 150, 200, 300, 450, 600, 900, 1200, 1800, 2400, 3600, - 4800, 7200, 9600, 14400, 19200, 28800, 38400, 57600, 115200, - 230400, 460800, 921600 -}; - -#define SC26198_NRBAUDS ARRAY_SIZE(sc26198_baudtable) - -/*****************************************************************************/ - -/* - * Define the driver info for a user level control device. Used mainly - * to get at port stats - only not using the port device itself. - */ -static const struct file_operations stl_fsiomem = { - .owner = THIS_MODULE, - .unlocked_ioctl = stl_memioctl, - .llseek = noop_llseek, -}; - -static struct class *stallion_class; - -static void stl_cd_change(struct stlport *portp) -{ - unsigned int oldsigs = portp->sigs; - struct tty_struct *tty = tty_port_tty_get(&portp->port); - - if (!tty) - return; - - portp->sigs = stl_getsignals(portp); - - if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0)) - wake_up_interruptible(&portp->port.open_wait); - - if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) - if (portp->port.flags & ASYNC_CHECK_CD) - tty_hangup(tty); - tty_kref_put(tty); -} - -/* - * Check for any arguments passed in on the module load command line. - */ - -/*****************************************************************************/ - -/* - * Parse the supplied argument string, into the board conf struct. - */ - -static int __init stl_parsebrd(struct stlconf *confp, char **argp) -{ - char *sp; - unsigned int i; - - pr_debug("stl_parsebrd(confp=%p,argp=%p)\n", confp, argp); - - if ((argp[0] == NULL) || (*argp[0] == 0)) - return 0; - - for (sp = argp[0], i = 0; (*sp != 0) && (i < 25); sp++, i++) - *sp = tolower(*sp); - - for (i = 0; i < ARRAY_SIZE(stl_brdstr); i++) - if (strcmp(stl_brdstr[i].name, argp[0]) == 0) - break; - - if (i == ARRAY_SIZE(stl_brdstr)) { - printk("STALLION: unknown board name, %s?\n", argp[0]); - return 0; - } - - confp->brdtype = stl_brdstr[i].type; - - i = 1; - if ((argp[i] != NULL) && (*argp[i] != 0)) - confp->ioaddr1 = simple_strtoul(argp[i], NULL, 0); - i++; - if (confp->brdtype == BRD_ECH) { - if ((argp[i] != NULL) && (*argp[i] != 0)) - confp->ioaddr2 = simple_strtoul(argp[i], NULL, 0); - i++; - } - if ((argp[i] != NULL) && (*argp[i] != 0)) - confp->irq = simple_strtoul(argp[i], NULL, 0); - return 1; -} - -/*****************************************************************************/ - -/* - * Allocate a new board structure. Fill out the basic info in it. - */ - -static struct stlbrd *stl_allocbrd(void) -{ - struct stlbrd *brdp; - - brdp = kzalloc(sizeof(struct stlbrd), GFP_KERNEL); - if (!brdp) { - printk("STALLION: failed to allocate memory (size=%Zd)\n", - sizeof(struct stlbrd)); - return NULL; - } - - brdp->magic = STL_BOARDMAGIC; - return brdp; -} - -/*****************************************************************************/ - -static int stl_activate(struct tty_port *port, struct tty_struct *tty) -{ - struct stlport *portp = container_of(port, struct stlport, port); - if (!portp->tx.buf) { - portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); - if (!portp->tx.buf) - return -ENOMEM; - portp->tx.head = portp->tx.buf; - portp->tx.tail = portp->tx.buf; - } - stl_setport(portp, tty->termios); - portp->sigs = stl_getsignals(portp); - stl_setsignals(portp, 1, 1); - stl_enablerxtx(portp, 1, 1); - stl_startrxtx(portp, 1, 0); - return 0; -} - -static int stl_open(struct tty_struct *tty, struct file *filp) -{ - struct stlport *portp; - struct stlbrd *brdp; - unsigned int minordev, brdnr, panelnr; - int portnr; - - pr_debug("stl_open(tty=%p,filp=%p): device=%s\n", tty, filp, tty->name); - - minordev = tty->index; - brdnr = MINOR2BRD(minordev); - if (brdnr >= stl_nrbrds) - return -ENODEV; - brdp = stl_brds[brdnr]; - if (brdp == NULL) - return -ENODEV; - - minordev = MINOR2PORT(minordev); - for (portnr = -1, panelnr = 0; panelnr < STL_MAXPANELS; panelnr++) { - if (brdp->panels[panelnr] == NULL) - break; - if (minordev < brdp->panels[panelnr]->nrports) { - portnr = minordev; - break; - } - minordev -= brdp->panels[panelnr]->nrports; - } - if (portnr < 0) - return -ENODEV; - - portp = brdp->panels[panelnr]->ports[portnr]; - if (portp == NULL) - return -ENODEV; - - tty->driver_data = portp; - return tty_port_open(&portp->port, tty, filp); - -} - -/*****************************************************************************/ - -static int stl_carrier_raised(struct tty_port *port) -{ - struct stlport *portp = container_of(port, struct stlport, port); - return (portp->sigs & TIOCM_CD) ? 1 : 0; -} - -static void stl_dtr_rts(struct tty_port *port, int on) -{ - struct stlport *portp = container_of(port, struct stlport, port); - /* Takes brd_lock internally */ - stl_setsignals(portp, on, on); -} - -/*****************************************************************************/ - -static void stl_flushbuffer(struct tty_struct *tty) -{ - struct stlport *portp; - - pr_debug("stl_flushbuffer(tty=%p)\n", tty); - - portp = tty->driver_data; - if (portp == NULL) - return; - - stl_flush(portp); - tty_wakeup(tty); -} - -/*****************************************************************************/ - -static void stl_waituntilsent(struct tty_struct *tty, int timeout) -{ - struct stlport *portp; - unsigned long tend; - - pr_debug("stl_waituntilsent(tty=%p,timeout=%d)\n", tty, timeout); - - portp = tty->driver_data; - if (portp == NULL) - return; - - if (timeout == 0) - timeout = HZ; - tend = jiffies + timeout; - - while (stl_datastate(portp)) { - if (signal_pending(current)) - break; - msleep_interruptible(20); - if (time_after_eq(jiffies, tend)) - break; - } -} - -/*****************************************************************************/ - -static void stl_shutdown(struct tty_port *port) -{ - struct stlport *portp = container_of(port, struct stlport, port); - stl_disableintrs(portp); - stl_enablerxtx(portp, 0, 0); - stl_flush(portp); - portp->istate = 0; - if (portp->tx.buf != NULL) { - kfree(portp->tx.buf); - portp->tx.buf = NULL; - portp->tx.head = NULL; - portp->tx.tail = NULL; - } -} - -static void stl_close(struct tty_struct *tty, struct file *filp) -{ - struct stlport*portp; - pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp); - - portp = tty->driver_data; - if(portp == NULL) - return; - tty_port_close(&portp->port, tty, filp); -} - -/*****************************************************************************/ - -/* - * Write routine. Take data and stuff it in to the TX ring queue. - * If transmit interrupts are not running then start them. - */ - -static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count) -{ - struct stlport *portp; - unsigned int len, stlen; - unsigned char *chbuf; - char *head, *tail; - - pr_debug("stl_write(tty=%p,buf=%p,count=%d)\n", tty, buf, count); - - portp = tty->driver_data; - if (portp == NULL) - return 0; - if (portp->tx.buf == NULL) - return 0; - -/* - * If copying direct from user space we must cater for page faults, - * causing us to "sleep" here for a while. To handle this copy in all - * the data we need now, into a local buffer. Then when we got it all - * copy it into the TX buffer. - */ - chbuf = (unsigned char *) buf; - - head = portp->tx.head; - tail = portp->tx.tail; - if (head >= tail) { - len = STL_TXBUFSIZE - (head - tail) - 1; - stlen = STL_TXBUFSIZE - (head - portp->tx.buf); - } else { - len = tail - head - 1; - stlen = len; - } - - len = min(len, (unsigned int)count); - count = 0; - while (len > 0) { - stlen = min(len, stlen); - memcpy(head, chbuf, stlen); - len -= stlen; - chbuf += stlen; - count += stlen; - head += stlen; - if (head >= (portp->tx.buf + STL_TXBUFSIZE)) { - head = portp->tx.buf; - stlen = tail - head; - } - } - portp->tx.head = head; - - clear_bit(ASYI_TXLOW, &portp->istate); - stl_startrxtx(portp, -1, 1); - - return count; -} - -/*****************************************************************************/ - -static int stl_putchar(struct tty_struct *tty, unsigned char ch) -{ - struct stlport *portp; - unsigned int len; - char *head, *tail; - - pr_debug("stl_putchar(tty=%p,ch=%x)\n", tty, ch); - - portp = tty->driver_data; - if (portp == NULL) - return -EINVAL; - if (portp->tx.buf == NULL) - return -EINVAL; - - head = portp->tx.head; - tail = portp->tx.tail; - - len = (head >= tail) ? (STL_TXBUFSIZE - (head - tail)) : (tail - head); - len--; - - if (len > 0) { - *head++ = ch; - if (head >= (portp->tx.buf + STL_TXBUFSIZE)) - head = portp->tx.buf; - } - portp->tx.head = head; - return 0; -} - -/*****************************************************************************/ - -/* - * If there are any characters in the buffer then make sure that TX - * interrupts are on and get'em out. Normally used after the putchar - * routine has been called. - */ - -static void stl_flushchars(struct tty_struct *tty) -{ - struct stlport *portp; - - pr_debug("stl_flushchars(tty=%p)\n", tty); - - portp = tty->driver_data; - if (portp == NULL) - return; - if (portp->tx.buf == NULL) - return; - - stl_startrxtx(portp, -1, 1); -} - -/*****************************************************************************/ - -static int stl_writeroom(struct tty_struct *tty) -{ - struct stlport *portp; - char *head, *tail; - - pr_debug("stl_writeroom(tty=%p)\n", tty); - - portp = tty->driver_data; - if (portp == NULL) - return 0; - if (portp->tx.buf == NULL) - return 0; - - head = portp->tx.head; - tail = portp->tx.tail; - return (head >= tail) ? (STL_TXBUFSIZE - (head - tail) - 1) : (tail - head - 1); -} - -/*****************************************************************************/ - -/* - * Return number of chars in the TX buffer. Normally we would just - * calculate the number of chars in the buffer and return that, but if - * the buffer is empty and TX interrupts are still on then we return - * that the buffer still has 1 char in it. This way whoever called us - * will not think that ALL chars have drained - since the UART still - * must have some chars in it (we are busy after all). - */ - -static int stl_charsinbuffer(struct tty_struct *tty) -{ - struct stlport *portp; - unsigned int size; - char *head, *tail; - - pr_debug("stl_charsinbuffer(tty=%p)\n", tty); - - portp = tty->driver_data; - if (portp == NULL) - return 0; - if (portp->tx.buf == NULL) - return 0; - - head = portp->tx.head; - tail = portp->tx.tail; - size = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head)); - if ((size == 0) && test_bit(ASYI_TXBUSY, &portp->istate)) - size = 1; - return size; -} - -/*****************************************************************************/ - -/* - * Generate the serial struct info. - */ - -static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp) -{ - struct serial_struct sio; - struct stlbrd *brdp; - - pr_debug("stl_getserial(portp=%p,sp=%p)\n", portp, sp); - - memset(&sio, 0, sizeof(struct serial_struct)); - - mutex_lock(&portp->port.mutex); - sio.line = portp->portnr; - sio.port = portp->ioaddr; - sio.flags = portp->port.flags; - sio.baud_base = portp->baud_base; - sio.close_delay = portp->close_delay; - sio.closing_wait = portp->closing_wait; - sio.custom_divisor = portp->custom_divisor; - sio.hub6 = 0; - if (portp->uartp == &stl_cd1400uart) { - sio.type = PORT_CIRRUS; - sio.xmit_fifo_size = CD1400_TXFIFOSIZE; - } else { - sio.type = PORT_UNKNOWN; - sio.xmit_fifo_size = SC26198_TXFIFOSIZE; - } - - brdp = stl_brds[portp->brdnr]; - if (brdp != NULL) - sio.irq = brdp->irq; - mutex_unlock(&portp->port.mutex); - - return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? -EFAULT : 0; -} - -/*****************************************************************************/ - -/* - * Set port according to the serial struct info. - * At this point we do not do any auto-configure stuff, so we will - * just quietly ignore any requests to change irq, etc. - */ - -static int stl_setserial(struct tty_struct *tty, struct serial_struct __user *sp) -{ - struct stlport * portp = tty->driver_data; - struct serial_struct sio; - - pr_debug("stl_setserial(portp=%p,sp=%p)\n", portp, sp); - - if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) - return -EFAULT; - mutex_lock(&portp->port.mutex); - if (!capable(CAP_SYS_ADMIN)) { - if ((sio.baud_base != portp->baud_base) || - (sio.close_delay != portp->close_delay) || - ((sio.flags & ~ASYNC_USR_MASK) != - (portp->port.flags & ~ASYNC_USR_MASK))) { - mutex_unlock(&portp->port.mutex); - return -EPERM; - } - } - - portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) | - (sio.flags & ASYNC_USR_MASK); - portp->baud_base = sio.baud_base; - portp->close_delay = sio.close_delay; - portp->closing_wait = sio.closing_wait; - portp->custom_divisor = sio.custom_divisor; - mutex_unlock(&portp->port.mutex); - stl_setport(portp, tty->termios); - return 0; -} - -/*****************************************************************************/ - -static int stl_tiocmget(struct tty_struct *tty) -{ - struct stlport *portp; - - portp = tty->driver_data; - if (portp == NULL) - return -ENODEV; - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - - return stl_getsignals(portp); -} - -static int stl_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct stlport *portp; - int rts = -1, dtr = -1; - - portp = tty->driver_data; - if (portp == NULL) - return -ENODEV; - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - - if (set & TIOCM_RTS) - rts = 1; - if (set & TIOCM_DTR) - dtr = 1; - if (clear & TIOCM_RTS) - rts = 0; - if (clear & TIOCM_DTR) - dtr = 0; - - stl_setsignals(portp, dtr, rts); - return 0; -} - -static int stl_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) -{ - struct stlport *portp; - int rc; - void __user *argp = (void __user *)arg; - - pr_debug("stl_ioctl(tty=%p,cmd=%x,arg=%lx)\n", tty, cmd, arg); - - portp = tty->driver_data; - if (portp == NULL) - return -ENODEV; - - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - - rc = 0; - - switch (cmd) { - case TIOCGSERIAL: - rc = stl_getserial(portp, argp); - break; - case TIOCSSERIAL: - rc = stl_setserial(tty, argp); - break; - case COM_GETPORTSTATS: - rc = stl_getportstats(tty, portp, argp); - break; - case COM_CLRPORTSTATS: - rc = stl_clrportstats(portp, argp); - break; - case TIOCSERCONFIG: - case TIOCSERGWILD: - case TIOCSERSWILD: - case TIOCSERGETLSR: - case TIOCSERGSTRUCT: - case TIOCSERGETMULTI: - case TIOCSERSETMULTI: - default: - rc = -ENOIOCTLCMD; - break; - } - return rc; -} - -/*****************************************************************************/ - -/* - * Start the transmitter again. Just turn TX interrupts back on. - */ - -static void stl_start(struct tty_struct *tty) -{ - struct stlport *portp; - - pr_debug("stl_start(tty=%p)\n", tty); - - portp = tty->driver_data; - if (portp == NULL) - return; - stl_startrxtx(portp, -1, 1); -} - -/*****************************************************************************/ - -static void stl_settermios(struct tty_struct *tty, struct ktermios *old) -{ - struct stlport *portp; - struct ktermios *tiosp; - - pr_debug("stl_settermios(tty=%p,old=%p)\n", tty, old); - - portp = tty->driver_data; - if (portp == NULL) - return; - - tiosp = tty->termios; - if ((tiosp->c_cflag == old->c_cflag) && - (tiosp->c_iflag == old->c_iflag)) - return; - - stl_setport(portp, tiosp); - stl_setsignals(portp, ((tiosp->c_cflag & (CBAUD & ~CBAUDEX)) ? 1 : 0), - -1); - if ((old->c_cflag & CRTSCTS) && ((tiosp->c_cflag & CRTSCTS) == 0)) { - tty->hw_stopped = 0; - stl_start(tty); - } - if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL)) - wake_up_interruptible(&portp->port.open_wait); -} - -/*****************************************************************************/ - -/* - * Attempt to flow control who ever is sending us data. Based on termios - * settings use software or/and hardware flow control. - */ - -static void stl_throttle(struct tty_struct *tty) -{ - struct stlport *portp; - - pr_debug("stl_throttle(tty=%p)\n", tty); - - portp = tty->driver_data; - if (portp == NULL) - return; - stl_flowctrl(portp, 0); -} - -/*****************************************************************************/ - -/* - * Unflow control the device sending us data... - */ - -static void stl_unthrottle(struct tty_struct *tty) -{ - struct stlport *portp; - - pr_debug("stl_unthrottle(tty=%p)\n", tty); - - portp = tty->driver_data; - if (portp == NULL) - return; - stl_flowctrl(portp, 1); -} - -/*****************************************************************************/ - -/* - * Stop the transmitter. Basically to do this we will just turn TX - * interrupts off. - */ - -static void stl_stop(struct tty_struct *tty) -{ - struct stlport *portp; - - pr_debug("stl_stop(tty=%p)\n", tty); - - portp = tty->driver_data; - if (portp == NULL) - return; - stl_startrxtx(portp, -1, 0); -} - -/*****************************************************************************/ - -/* - * Hangup this port. This is pretty much like closing the port, only - * a little more brutal. No waiting for data to drain. Shutdown the - * port and maybe drop signals. - */ - -static void stl_hangup(struct tty_struct *tty) -{ - struct stlport *portp = tty->driver_data; - pr_debug("stl_hangup(tty=%p)\n", tty); - - if (portp == NULL) - return; - tty_port_hangup(&portp->port); -} - -/*****************************************************************************/ - -static int stl_breakctl(struct tty_struct *tty, int state) -{ - struct stlport *portp; - - pr_debug("stl_breakctl(tty=%p,state=%d)\n", tty, state); - - portp = tty->driver_data; - if (portp == NULL) - return -EINVAL; - - stl_sendbreak(portp, ((state == -1) ? 1 : 2)); - return 0; -} - -/*****************************************************************************/ - -static void stl_sendxchar(struct tty_struct *tty, char ch) -{ - struct stlport *portp; - - pr_debug("stl_sendxchar(tty=%p,ch=%x)\n", tty, ch); - - portp = tty->driver_data; - if (portp == NULL) - return; - - if (ch == STOP_CHAR(tty)) - stl_sendflow(portp, 0); - else if (ch == START_CHAR(tty)) - stl_sendflow(portp, 1); - else - stl_putchar(tty, ch); -} - -static void stl_portinfo(struct seq_file *m, struct stlport *portp, int portnr) -{ - int sigs; - char sep; - - seq_printf(m, "%d: uart:%s tx:%d rx:%d", - portnr, (portp->hwid == 1) ? "SC26198" : "CD1400", - (int) portp->stats.txtotal, (int) portp->stats.rxtotal); - - if (portp->stats.rxframing) - seq_printf(m, " fe:%d", (int) portp->stats.rxframing); - if (portp->stats.rxparity) - seq_printf(m, " pe:%d", (int) portp->stats.rxparity); - if (portp->stats.rxbreaks) - seq_printf(m, " brk:%d", (int) portp->stats.rxbreaks); - if (portp->stats.rxoverrun) - seq_printf(m, " oe:%d", (int) portp->stats.rxoverrun); - - sigs = stl_getsignals(portp); - sep = ' '; - if (sigs & TIOCM_RTS) { - seq_printf(m, "%c%s", sep, "RTS"); - sep = '|'; - } - if (sigs & TIOCM_CTS) { - seq_printf(m, "%c%s", sep, "CTS"); - sep = '|'; - } - if (sigs & TIOCM_DTR) { - seq_printf(m, "%c%s", sep, "DTR"); - sep = '|'; - } - if (sigs & TIOCM_CD) { - seq_printf(m, "%c%s", sep, "DCD"); - sep = '|'; - } - if (sigs & TIOCM_DSR) { - seq_printf(m, "%c%s", sep, "DSR"); - sep = '|'; - } - seq_putc(m, '\n'); -} - -/*****************************************************************************/ - -/* - * Port info, read from the /proc file system. - */ - -static int stl_proc_show(struct seq_file *m, void *v) -{ - struct stlbrd *brdp; - struct stlpanel *panelp; - struct stlport *portp; - unsigned int brdnr, panelnr, portnr; - int totalport; - - totalport = 0; - - seq_printf(m, "%s: version %s\n", stl_drvtitle, stl_drvversion); - -/* - * We scan through for each board, panel and port. The offset is - * calculated on the fly, and irrelevant ports are skipped. - */ - for (brdnr = 0; brdnr < stl_nrbrds; brdnr++) { - brdp = stl_brds[brdnr]; - if (brdp == NULL) - continue; - if (brdp->state == 0) - continue; - - totalport = brdnr * STL_MAXPORTS; - for (panelnr = 0; panelnr < brdp->nrpanels; panelnr++) { - panelp = brdp->panels[panelnr]; - if (panelp == NULL) - continue; - - for (portnr = 0; portnr < panelp->nrports; portnr++, - totalport++) { - portp = panelp->ports[portnr]; - if (portp == NULL) - continue; - stl_portinfo(m, portp, totalport); - } - } - } - return 0; -} - -static int stl_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, stl_proc_show, NULL); -} - -static const struct file_operations stl_proc_fops = { - .owner = THIS_MODULE, - .open = stl_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/*****************************************************************************/ - -/* - * All board interrupts are vectored through here first. This code then - * calls off to the approrpriate board interrupt handlers. - */ - -static irqreturn_t stl_intr(int irq, void *dev_id) -{ - struct stlbrd *brdp = dev_id; - - pr_debug("stl_intr(brdp=%p,irq=%d)\n", brdp, brdp->irq); - - return IRQ_RETVAL((* brdp->isr)(brdp)); -} - -/*****************************************************************************/ - -/* - * Interrupt service routine for EasyIO board types. - */ - -static int stl_eiointr(struct stlbrd *brdp) -{ - struct stlpanel *panelp; - unsigned int iobase; - int handled = 0; - - spin_lock(&brd_lock); - panelp = brdp->panels[0]; - iobase = panelp->iobase; - while (inb(brdp->iostatus) & EIO_INTRPEND) { - handled = 1; - (* panelp->isr)(panelp, iobase); - } - spin_unlock(&brd_lock); - return handled; -} - -/*****************************************************************************/ - -/* - * Interrupt service routine for ECH-AT board types. - */ - -static int stl_echatintr(struct stlbrd *brdp) -{ - struct stlpanel *panelp; - unsigned int ioaddr, bnknr; - int handled = 0; - - outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl); - - while (inb(brdp->iostatus) & ECH_INTRPEND) { - handled = 1; - for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) { - ioaddr = brdp->bnkstataddr[bnknr]; - if (inb(ioaddr) & ECH_PNLINTRPEND) { - panelp = brdp->bnk2panel[bnknr]; - (* panelp->isr)(panelp, (ioaddr & 0xfffc)); - } - } - } - - outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl); - - return handled; -} - -/*****************************************************************************/ - -/* - * Interrupt service routine for ECH-MCA board types. - */ - -static int stl_echmcaintr(struct stlbrd *brdp) -{ - struct stlpanel *panelp; - unsigned int ioaddr, bnknr; - int handled = 0; - - while (inb(brdp->iostatus) & ECH_INTRPEND) { - handled = 1; - for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) { - ioaddr = brdp->bnkstataddr[bnknr]; - if (inb(ioaddr) & ECH_PNLINTRPEND) { - panelp = brdp->bnk2panel[bnknr]; - (* panelp->isr)(panelp, (ioaddr & 0xfffc)); - } - } - } - return handled; -} - -/*****************************************************************************/ - -/* - * Interrupt service routine for ECH-PCI board types. - */ - -static int stl_echpciintr(struct stlbrd *brdp) -{ - struct stlpanel *panelp; - unsigned int ioaddr, bnknr, recheck; - int handled = 0; - - while (1) { - recheck = 0; - for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) { - outb(brdp->bnkpageaddr[bnknr], brdp->ioctrl); - ioaddr = brdp->bnkstataddr[bnknr]; - if (inb(ioaddr) & ECH_PNLINTRPEND) { - panelp = brdp->bnk2panel[bnknr]; - (* panelp->isr)(panelp, (ioaddr & 0xfffc)); - recheck++; - handled = 1; - } - } - if (! recheck) - break; - } - return handled; -} - -/*****************************************************************************/ - -/* - * Interrupt service routine for ECH-8/64-PCI board types. - */ - -static int stl_echpci64intr(struct stlbrd *brdp) -{ - struct stlpanel *panelp; - unsigned int ioaddr, bnknr; - int handled = 0; - - while (inb(brdp->ioctrl) & 0x1) { - handled = 1; - for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) { - ioaddr = brdp->bnkstataddr[bnknr]; - if (inb(ioaddr) & ECH_PNLINTRPEND) { - panelp = brdp->bnk2panel[bnknr]; - (* panelp->isr)(panelp, (ioaddr & 0xfffc)); - } - } - } - - return handled; -} - -/*****************************************************************************/ - -/* - * Initialize all the ports on a panel. - */ - -static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *panelp) -{ - struct stlport *portp; - unsigned int i; - int chipmask; - - pr_debug("stl_initports(brdp=%p,panelp=%p)\n", brdp, panelp); - - chipmask = stl_panelinit(brdp, panelp); - -/* - * All UART's are initialized (if found!). Now go through and setup - * each ports data structures. - */ - for (i = 0; i < panelp->nrports; i++) { - portp = kzalloc(sizeof(struct stlport), GFP_KERNEL); - if (!portp) { - printk("STALLION: failed to allocate memory " - "(size=%Zd)\n", sizeof(struct stlport)); - break; - } - tty_port_init(&portp->port); - portp->port.ops = &stl_port_ops; - portp->magic = STL_PORTMAGIC; - portp->portnr = i; - portp->brdnr = panelp->brdnr; - portp->panelnr = panelp->panelnr; - portp->uartp = panelp->uartp; - portp->clk = brdp->clk; - portp->baud_base = STL_BAUDBASE; - portp->close_delay = STL_CLOSEDELAY; - portp->closing_wait = 30 * HZ; - init_waitqueue_head(&portp->port.open_wait); - init_waitqueue_head(&portp->port.close_wait); - portp->stats.brd = portp->brdnr; - portp->stats.panel = portp->panelnr; - portp->stats.port = portp->portnr; - panelp->ports[i] = portp; - stl_portinit(brdp, panelp, portp); - } - - return 0; -} - -static void stl_cleanup_panels(struct stlbrd *brdp) -{ - struct stlpanel *panelp; - struct stlport *portp; - unsigned int j, k; - struct tty_struct *tty; - - for (j = 0; j < STL_MAXPANELS; j++) { - panelp = brdp->panels[j]; - if (panelp == NULL) - continue; - for (k = 0; k < STL_PORTSPERPANEL; k++) { - portp = panelp->ports[k]; - if (portp == NULL) - continue; - tty = tty_port_tty_get(&portp->port); - if (tty != NULL) { - stl_hangup(tty); - tty_kref_put(tty); - } - kfree(portp->tx.buf); - kfree(portp); - } - kfree(panelp); - } -} - -/*****************************************************************************/ - -/* - * Try to find and initialize an EasyIO board. - */ - -static int __devinit stl_initeio(struct stlbrd *brdp) -{ - struct stlpanel *panelp; - unsigned int status; - char *name; - int retval; - - pr_debug("stl_initeio(brdp=%p)\n", brdp); - - brdp->ioctrl = brdp->ioaddr1 + 1; - brdp->iostatus = brdp->ioaddr1 + 2; - - status = inb(brdp->iostatus); - if ((status & EIO_IDBITMASK) == EIO_MK3) - brdp->ioctrl++; - -/* - * Handle board specific stuff now. The real difference is PCI - * or not PCI. - */ - if (brdp->brdtype == BRD_EASYIOPCI) { - brdp->iosize1 = 0x80; - brdp->iosize2 = 0x80; - name = "serial(EIO-PCI)"; - outb(0x41, (brdp->ioaddr2 + 0x4c)); - } else { - brdp->iosize1 = 8; - name = "serial(EIO)"; - if ((brdp->irq < 0) || (brdp->irq > 15) || - (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) { - printk("STALLION: invalid irq=%d for brd=%d\n", - brdp->irq, brdp->brdnr); - retval = -EINVAL; - goto err; - } - outb((stl_vecmap[brdp->irq] | EIO_0WS | - ((brdp->irqtype) ? EIO_INTLEVEL : EIO_INTEDGE)), - brdp->ioctrl); - } - - retval = -EBUSY; - if (!request_region(brdp->ioaddr1, brdp->iosize1, name)) { - printk(KERN_WARNING "STALLION: Warning, board %d I/O address " - "%x conflicts with another device\n", brdp->brdnr, - brdp->ioaddr1); - goto err; - } - - if (brdp->iosize2 > 0) - if (!request_region(brdp->ioaddr2, brdp->iosize2, name)) { - printk(KERN_WARNING "STALLION: Warning, board %d I/O " - "address %x conflicts with another device\n", - brdp->brdnr, brdp->ioaddr2); - printk(KERN_WARNING "STALLION: Warning, also " - "releasing board %d I/O address %x \n", - brdp->brdnr, brdp->ioaddr1); - goto err_rel1; - } - -/* - * Everything looks OK, so let's go ahead and probe for the hardware. - */ - brdp->clk = CD1400_CLK; - brdp->isr = stl_eiointr; - - retval = -ENODEV; - switch (status & EIO_IDBITMASK) { - case EIO_8PORTM: - brdp->clk = CD1400_CLK8M; - /* fall thru */ - case EIO_8PORTRS: - case EIO_8PORTDI: - brdp->nrports = 8; - break; - case EIO_4PORTRS: - brdp->nrports = 4; - break; - case EIO_MK3: - switch (status & EIO_BRDMASK) { - case ID_BRD4: - brdp->nrports = 4; - break; - case ID_BRD8: - brdp->nrports = 8; - break; - case ID_BRD16: - brdp->nrports = 16; - break; - default: - goto err_rel2; - } - break; - default: - goto err_rel2; - } - -/* - * We have verified that the board is actually present, so now we - * can complete the setup. - */ - - panelp = kzalloc(sizeof(struct stlpanel), GFP_KERNEL); - if (!panelp) { - printk(KERN_WARNING "STALLION: failed to allocate memory " - "(size=%Zd)\n", sizeof(struct stlpanel)); - retval = -ENOMEM; - goto err_rel2; - } - - panelp->magic = STL_PANELMAGIC; - panelp->brdnr = brdp->brdnr; - panelp->panelnr = 0; - panelp->nrports = brdp->nrports; - panelp->iobase = brdp->ioaddr1; - panelp->hwid = status; - if ((status & EIO_IDBITMASK) == EIO_MK3) { - panelp->uartp = &stl_sc26198uart; - panelp->isr = stl_sc26198intr; - } else { - panelp->uartp = &stl_cd1400uart; - panelp->isr = stl_cd1400eiointr; - } - - brdp->panels[0] = panelp; - brdp->nrpanels = 1; - brdp->state |= BRD_FOUND; - brdp->hwid = status; - if (request_irq(brdp->irq, stl_intr, IRQF_SHARED, name, brdp) != 0) { - printk("STALLION: failed to register interrupt " - "routine for %s irq=%d\n", name, brdp->irq); - retval = -ENODEV; - goto err_fr; - } - - return 0; -err_fr: - stl_cleanup_panels(brdp); -err_rel2: - if (brdp->iosize2 > 0) - release_region(brdp->ioaddr2, brdp->iosize2); -err_rel1: - release_region(brdp->ioaddr1, brdp->iosize1); -err: - return retval; -} - -/*****************************************************************************/ - -/* - * Try to find an ECH board and initialize it. This code is capable of - * dealing with all types of ECH board. - */ - -static int __devinit stl_initech(struct stlbrd *brdp) -{ - struct stlpanel *panelp; - unsigned int status, nxtid, ioaddr, conflict, panelnr, banknr, i; - int retval; - char *name; - - pr_debug("stl_initech(brdp=%p)\n", brdp); - - status = 0; - conflict = 0; - -/* - * Set up the initial board register contents for boards. This varies a - * bit between the different board types. So we need to handle each - * separately. Also do a check that the supplied IRQ is good. - */ - switch (brdp->brdtype) { - - case BRD_ECH: - brdp->isr = stl_echatintr; - brdp->ioctrl = brdp->ioaddr1 + 1; - brdp->iostatus = brdp->ioaddr1 + 1; - status = inb(brdp->iostatus); - if ((status & ECH_IDBITMASK) != ECH_ID) { - retval = -ENODEV; - goto err; - } - if ((brdp->irq < 0) || (brdp->irq > 15) || - (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) { - printk("STALLION: invalid irq=%d for brd=%d\n", - brdp->irq, brdp->brdnr); - retval = -EINVAL; - goto err; - } - status = ((brdp->ioaddr2 & ECH_ADDR2MASK) >> 1); - status |= (stl_vecmap[brdp->irq] << 1); - outb((status | ECH_BRDRESET), brdp->ioaddr1); - brdp->ioctrlval = ECH_INTENABLE | - ((brdp->irqtype) ? ECH_INTLEVEL : ECH_INTEDGE); - for (i = 0; i < 10; i++) - outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl); - brdp->iosize1 = 2; - brdp->iosize2 = 32; - name = "serial(EC8/32)"; - outb(status, brdp->ioaddr1); - break; - - case BRD_ECHMC: - brdp->isr = stl_echmcaintr; - brdp->ioctrl = brdp->ioaddr1 + 0x20; - brdp->iostatus = brdp->ioctrl; - status = inb(brdp->iostatus); - if ((status & ECH_IDBITMASK) != ECH_ID) { - retval = -ENODEV; - goto err; - } - if ((brdp->irq < 0) || (brdp->irq > 15) || - (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) { - printk("STALLION: invalid irq=%d for brd=%d\n", - brdp->irq, brdp->brdnr); - retval = -EINVAL; - goto err; - } - outb(ECHMC_BRDRESET, brdp->ioctrl); - outb(ECHMC_INTENABLE, brdp->ioctrl); - brdp->iosize1 = 64; - name = "serial(EC8/32-MC)"; - break; - - case BRD_ECHPCI: - brdp->isr = stl_echpciintr; - brdp->ioctrl = brdp->ioaddr1 + 2; - brdp->iosize1 = 4; - brdp->iosize2 = 8; - name = "serial(EC8/32-PCI)"; - break; - - case BRD_ECH64PCI: - brdp->isr = stl_echpci64intr; - brdp->ioctrl = brdp->ioaddr2 + 0x40; - outb(0x43, (brdp->ioaddr1 + 0x4c)); - brdp->iosize1 = 0x80; - brdp->iosize2 = 0x80; - name = "serial(EC8/64-PCI)"; - break; - - default: - printk("STALLION: unknown board type=%d\n", brdp->brdtype); - retval = -EINVAL; - goto err; - } - -/* - * Check boards for possible IO address conflicts and return fail status - * if an IO conflict found. - */ - retval = -EBUSY; - if (!request_region(brdp->ioaddr1, brdp->iosize1, name)) { - printk(KERN_WARNING "STALLION: Warning, board %d I/O address " - "%x conflicts with another device\n", brdp->brdnr, - brdp->ioaddr1); - goto err; - } - - if (brdp->iosize2 > 0) - if (!request_region(brdp->ioaddr2, brdp->iosize2, name)) { - printk(KERN_WARNING "STALLION: Warning, board %d I/O " - "address %x conflicts with another device\n", - brdp->brdnr, brdp->ioaddr2); - printk(KERN_WARNING "STALLION: Warning, also " - "releasing board %d I/O address %x \n", - brdp->brdnr, brdp->ioaddr1); - goto err_rel1; - } - -/* - * Scan through the secondary io address space looking for panels. - * As we find'em allocate and initialize panel structures for each. - */ - brdp->clk = CD1400_CLK; - brdp->hwid = status; - - ioaddr = brdp->ioaddr2; - banknr = 0; - panelnr = 0; - nxtid = 0; - - for (i = 0; i < STL_MAXPANELS; i++) { - if (brdp->brdtype == BRD_ECHPCI) { - outb(nxtid, brdp->ioctrl); - ioaddr = brdp->ioaddr2; - } - status = inb(ioaddr + ECH_PNLSTATUS); - if ((status & ECH_PNLIDMASK) != nxtid) - break; - panelp = kzalloc(sizeof(struct stlpanel), GFP_KERNEL); - if (!panelp) { - printk("STALLION: failed to allocate memory " - "(size=%Zd)\n", sizeof(struct stlpanel)); - retval = -ENOMEM; - goto err_fr; - } - panelp->magic = STL_PANELMAGIC; - panelp->brdnr = brdp->brdnr; - panelp->panelnr = panelnr; - panelp->iobase = ioaddr; - panelp->pagenr = nxtid; - panelp->hwid = status; - brdp->bnk2panel[banknr] = panelp; - brdp->bnkpageaddr[banknr] = nxtid; - brdp->bnkstataddr[banknr++] = ioaddr + ECH_PNLSTATUS; - - if (status & ECH_PNLXPID) { - panelp->uartp = &stl_sc26198uart; - panelp->isr = stl_sc26198intr; - if (status & ECH_PNL16PORT) { - panelp->nrports = 16; - brdp->bnk2panel[banknr] = panelp; - brdp->bnkpageaddr[banknr] = nxtid; - brdp->bnkstataddr[banknr++] = ioaddr + 4 + - ECH_PNLSTATUS; - } else - panelp->nrports = 8; - } else { - panelp->uartp = &stl_cd1400uart; - panelp->isr = stl_cd1400echintr; - if (status & ECH_PNL16PORT) { - panelp->nrports = 16; - panelp->ackmask = 0x80; - if (brdp->brdtype != BRD_ECHPCI) - ioaddr += EREG_BANKSIZE; - brdp->bnk2panel[banknr] = panelp; - brdp->bnkpageaddr[banknr] = ++nxtid; - brdp->bnkstataddr[banknr++] = ioaddr + - ECH_PNLSTATUS; - } else { - panelp->nrports = 8; - panelp->ackmask = 0xc0; - } - } - - nxtid++; - ioaddr += EREG_BANKSIZE; - brdp->nrports += panelp->nrports; - brdp->panels[panelnr++] = panelp; - if ((brdp->brdtype != BRD_ECHPCI) && - (ioaddr >= (brdp->ioaddr2 + brdp->iosize2))) { - retval = -EINVAL; - goto err_fr; - } - } - - brdp->nrpanels = panelnr; - brdp->nrbnks = banknr; - if (brdp->brdtype == BRD_ECH) - outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl); - - brdp->state |= BRD_FOUND; - if (request_irq(brdp->irq, stl_intr, IRQF_SHARED, name, brdp) != 0) { - printk("STALLION: failed to register interrupt " - "routine for %s irq=%d\n", name, brdp->irq); - retval = -ENODEV; - goto err_fr; - } - - return 0; -err_fr: - stl_cleanup_panels(brdp); - if (brdp->iosize2 > 0) - release_region(brdp->ioaddr2, brdp->iosize2); -err_rel1: - release_region(brdp->ioaddr1, brdp->iosize1); -err: - return retval; -} - -/*****************************************************************************/ - -/* - * Initialize and configure the specified board. - * Scan through all the boards in the configuration and see what we - * can find. Handle EIO and the ECH boards a little differently here - * since the initial search and setup is very different. - */ - -static int __devinit stl_brdinit(struct stlbrd *brdp) -{ - int i, retval; - - pr_debug("stl_brdinit(brdp=%p)\n", brdp); - - switch (brdp->brdtype) { - case BRD_EASYIO: - case BRD_EASYIOPCI: - retval = stl_initeio(brdp); - if (retval) - goto err; - break; - case BRD_ECH: - case BRD_ECHMC: - case BRD_ECHPCI: - case BRD_ECH64PCI: - retval = stl_initech(brdp); - if (retval) - goto err; - break; - default: - printk("STALLION: board=%d is unknown board type=%d\n", - brdp->brdnr, brdp->brdtype); - retval = -ENODEV; - goto err; - } - - if ((brdp->state & BRD_FOUND) == 0) { - printk("STALLION: %s board not found, board=%d io=%x irq=%d\n", - stl_brdnames[brdp->brdtype], brdp->brdnr, - brdp->ioaddr1, brdp->irq); - goto err_free; - } - - for (i = 0; i < STL_MAXPANELS; i++) - if (brdp->panels[i] != NULL) - stl_initports(brdp, brdp->panels[i]); - - printk("STALLION: %s found, board=%d io=%x irq=%d " - "nrpanels=%d nrports=%d\n", stl_brdnames[brdp->brdtype], - brdp->brdnr, brdp->ioaddr1, brdp->irq, brdp->nrpanels, - brdp->nrports); - - return 0; -err_free: - free_irq(brdp->irq, brdp); - - stl_cleanup_panels(brdp); - - release_region(brdp->ioaddr1, brdp->iosize1); - if (brdp->iosize2 > 0) - release_region(brdp->ioaddr2, brdp->iosize2); -err: - return retval; -} - -/*****************************************************************************/ - -/* - * Find the next available board number that is free. - */ - -static int __devinit stl_getbrdnr(void) -{ - unsigned int i; - - for (i = 0; i < STL_MAXBRDS; i++) - if (stl_brds[i] == NULL) { - if (i >= stl_nrbrds) - stl_nrbrds = i + 1; - return i; - } - - return -1; -} - -/*****************************************************************************/ -/* - * We have a Stallion board. Allocate a board structure and - * initialize it. Read its IO and IRQ resources from PCI - * configuration space. - */ - -static int __devinit stl_pciprobe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct stlbrd *brdp; - unsigned int i, brdtype = ent->driver_data; - int brdnr, retval = -ENODEV; - - if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) - goto err; - - retval = pci_enable_device(pdev); - if (retval) - goto err; - brdp = stl_allocbrd(); - if (brdp == NULL) { - retval = -ENOMEM; - goto err; - } - mutex_lock(&stl_brdslock); - brdnr = stl_getbrdnr(); - if (brdnr < 0) { - dev_err(&pdev->dev, "too many boards found, " - "maximum supported %d\n", STL_MAXBRDS); - mutex_unlock(&stl_brdslock); - retval = -ENODEV; - goto err_fr; - } - brdp->brdnr = (unsigned int)brdnr; - stl_brds[brdp->brdnr] = brdp; - mutex_unlock(&stl_brdslock); - - brdp->brdtype = brdtype; - brdp->state |= STL_PROBED; - -/* - * We have all resources from the board, so let's setup the actual - * board structure now. - */ - switch (brdtype) { - case BRD_ECHPCI: - brdp->ioaddr2 = pci_resource_start(pdev, 0); - brdp->ioaddr1 = pci_resource_start(pdev, 1); - break; - case BRD_ECH64PCI: - brdp->ioaddr2 = pci_resource_start(pdev, 2); - brdp->ioaddr1 = pci_resource_start(pdev, 1); - break; - case BRD_EASYIOPCI: - brdp->ioaddr1 = pci_resource_start(pdev, 2); - brdp->ioaddr2 = pci_resource_start(pdev, 1); - break; - default: - dev_err(&pdev->dev, "unknown PCI board type=%u\n", brdtype); - break; - } - - brdp->irq = pdev->irq; - retval = stl_brdinit(brdp); - if (retval) - goto err_null; - - pci_set_drvdata(pdev, brdp); - - for (i = 0; i < brdp->nrports; i++) - tty_register_device(stl_serial, - brdp->brdnr * STL_MAXPORTS + i, &pdev->dev); - - return 0; -err_null: - stl_brds[brdp->brdnr] = NULL; -err_fr: - kfree(brdp); -err: - return retval; -} - -static void __devexit stl_pciremove(struct pci_dev *pdev) -{ - struct stlbrd *brdp = pci_get_drvdata(pdev); - unsigned int i; - - free_irq(brdp->irq, brdp); - - stl_cleanup_panels(brdp); - - release_region(brdp->ioaddr1, brdp->iosize1); - if (brdp->iosize2 > 0) - release_region(brdp->ioaddr2, brdp->iosize2); - - for (i = 0; i < brdp->nrports; i++) - tty_unregister_device(stl_serial, - brdp->brdnr * STL_MAXPORTS + i); - - stl_brds[brdp->brdnr] = NULL; - kfree(brdp); -} - -static struct pci_driver stl_pcidriver = { - .name = "stallion", - .id_table = stl_pcibrds, - .probe = stl_pciprobe, - .remove = __devexit_p(stl_pciremove) -}; - -/*****************************************************************************/ - -/* - * Return the board stats structure to user app. - */ - -static int stl_getbrdstats(combrd_t __user *bp) -{ - combrd_t stl_brdstats; - struct stlbrd *brdp; - struct stlpanel *panelp; - unsigned int i; - - if (copy_from_user(&stl_brdstats, bp, sizeof(combrd_t))) - return -EFAULT; - if (stl_brdstats.brd >= STL_MAXBRDS) - return -ENODEV; - brdp = stl_brds[stl_brdstats.brd]; - if (brdp == NULL) - return -ENODEV; - - memset(&stl_brdstats, 0, sizeof(combrd_t)); - stl_brdstats.brd = brdp->brdnr; - stl_brdstats.type = brdp->brdtype; - stl_brdstats.hwid = brdp->hwid; - stl_brdstats.state = brdp->state; - stl_brdstats.ioaddr = brdp->ioaddr1; - stl_brdstats.ioaddr2 = brdp->ioaddr2; - stl_brdstats.irq = brdp->irq; - stl_brdstats.nrpanels = brdp->nrpanels; - stl_brdstats.nrports = brdp->nrports; - for (i = 0; i < brdp->nrpanels; i++) { - panelp = brdp->panels[i]; - stl_brdstats.panels[i].panel = i; - stl_brdstats.panels[i].hwid = panelp->hwid; - stl_brdstats.panels[i].nrports = panelp->nrports; - } - - return copy_to_user(bp, &stl_brdstats, sizeof(combrd_t)) ? -EFAULT : 0; -} - -/*****************************************************************************/ - -/* - * Resolve the referenced port number into a port struct pointer. - */ - -static struct stlport *stl_getport(int brdnr, int panelnr, int portnr) -{ - struct stlbrd *brdp; - struct stlpanel *panelp; - - if (brdnr < 0 || brdnr >= STL_MAXBRDS) - return NULL; - brdp = stl_brds[brdnr]; - if (brdp == NULL) - return NULL; - if (panelnr < 0 || (unsigned int)panelnr >= brdp->nrpanels) - return NULL; - panelp = brdp->panels[panelnr]; - if (panelp == NULL) - return NULL; - if (portnr < 0 || (unsigned int)portnr >= panelp->nrports) - return NULL; - return panelp->ports[portnr]; -} - -/*****************************************************************************/ - -/* - * Return the port stats structure to user app. A NULL port struct - * pointer passed in means that we need to find out from the app - * what port to get stats for (used through board control device). - */ - -static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp) -{ - comstats_t stl_comstats; - unsigned char *head, *tail; - unsigned long flags; - - if (!portp) { - if (copy_from_user(&stl_comstats, cp, sizeof(comstats_t))) - return -EFAULT; - portp = stl_getport(stl_comstats.brd, stl_comstats.panel, - stl_comstats.port); - if (portp == NULL) - return -ENODEV; - } - - mutex_lock(&portp->port.mutex); - portp->stats.state = portp->istate; - portp->stats.flags = portp->port.flags; - portp->stats.hwid = portp->hwid; - - portp->stats.ttystate = 0; - portp->stats.cflags = 0; - portp->stats.iflags = 0; - portp->stats.oflags = 0; - portp->stats.lflags = 0; - portp->stats.rxbuffered = 0; - - spin_lock_irqsave(&stallion_lock, flags); - if (tty != NULL && portp->port.tty == tty) { - portp->stats.ttystate = tty->flags; - /* No longer available as a statistic */ - portp->stats.rxbuffered = 1; /*tty->flip.count; */ - if (tty->termios != NULL) { - portp->stats.cflags = tty->termios->c_cflag; - portp->stats.iflags = tty->termios->c_iflag; - portp->stats.oflags = tty->termios->c_oflag; - portp->stats.lflags = tty->termios->c_lflag; - } - } - spin_unlock_irqrestore(&stallion_lock, flags); - - head = portp->tx.head; - tail = portp->tx.tail; - portp->stats.txbuffered = (head >= tail) ? (head - tail) : - (STL_TXBUFSIZE - (tail - head)); - - portp->stats.signals = (unsigned long) stl_getsignals(portp); - mutex_unlock(&portp->port.mutex); - - return copy_to_user(cp, &portp->stats, - sizeof(comstats_t)) ? -EFAULT : 0; -} - -/*****************************************************************************/ - -/* - * Clear the port stats structure. We also return it zeroed out... - */ - -static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp) -{ - comstats_t stl_comstats; - - if (!portp) { - if (copy_from_user(&stl_comstats, cp, sizeof(comstats_t))) - return -EFAULT; - portp = stl_getport(stl_comstats.brd, stl_comstats.panel, - stl_comstats.port); - if (portp == NULL) - return -ENODEV; - } - - mutex_lock(&portp->port.mutex); - memset(&portp->stats, 0, sizeof(comstats_t)); - portp->stats.brd = portp->brdnr; - portp->stats.panel = portp->panelnr; - portp->stats.port = portp->portnr; - mutex_unlock(&portp->port.mutex); - return copy_to_user(cp, &portp->stats, - sizeof(comstats_t)) ? -EFAULT : 0; -} - -/*****************************************************************************/ - -/* - * Return the entire driver ports structure to a user app. - */ - -static int stl_getportstruct(struct stlport __user *arg) -{ - struct stlport stl_dummyport; - struct stlport *portp; - - if (copy_from_user(&stl_dummyport, arg, sizeof(struct stlport))) - return -EFAULT; - portp = stl_getport(stl_dummyport.brdnr, stl_dummyport.panelnr, - stl_dummyport.portnr); - if (!portp) - return -ENODEV; - return copy_to_user(arg, portp, sizeof(struct stlport)) ? -EFAULT : 0; -} - -/*****************************************************************************/ - -/* - * Return the entire driver board structure to a user app. - */ - -static int stl_getbrdstruct(struct stlbrd __user *arg) -{ - struct stlbrd stl_dummybrd; - struct stlbrd *brdp; - - if (copy_from_user(&stl_dummybrd, arg, sizeof(struct stlbrd))) - return -EFAULT; - if (stl_dummybrd.brdnr >= STL_MAXBRDS) - return -ENODEV; - brdp = stl_brds[stl_dummybrd.brdnr]; - if (!brdp) - return -ENODEV; - return copy_to_user(arg, brdp, sizeof(struct stlbrd)) ? -EFAULT : 0; -} - -/*****************************************************************************/ - -/* - * The "staliomem" device is also required to do some special operations - * on the board and/or ports. In this driver it is mostly used for stats - * collection. - */ - -static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) -{ - int brdnr, rc; - void __user *argp = (void __user *)arg; - - pr_debug("stl_memioctl(fp=%p,cmd=%x,arg=%lx)\n", fp, cmd,arg); - - brdnr = iminor(fp->f_dentry->d_inode); - if (brdnr >= STL_MAXBRDS) - return -ENODEV; - rc = 0; - - switch (cmd) { - case COM_GETPORTSTATS: - rc = stl_getportstats(NULL, NULL, argp); - break; - case COM_CLRPORTSTATS: - rc = stl_clrportstats(NULL, argp); - break; - case COM_GETBRDSTATS: - rc = stl_getbrdstats(argp); - break; - case COM_READPORT: - rc = stl_getportstruct(argp); - break; - case COM_READBOARD: - rc = stl_getbrdstruct(argp); - break; - default: - rc = -ENOIOCTLCMD; - break; - } - return rc; -} - -static const struct tty_operations stl_ops = { - .open = stl_open, - .close = stl_close, - .write = stl_write, - .put_char = stl_putchar, - .flush_chars = stl_flushchars, - .write_room = stl_writeroom, - .chars_in_buffer = stl_charsinbuffer, - .ioctl = stl_ioctl, - .set_termios = stl_settermios, - .throttle = stl_throttle, - .unthrottle = stl_unthrottle, - .stop = stl_stop, - .start = stl_start, - .hangup = stl_hangup, - .flush_buffer = stl_flushbuffer, - .break_ctl = stl_breakctl, - .wait_until_sent = stl_waituntilsent, - .send_xchar = stl_sendxchar, - .tiocmget = stl_tiocmget, - .tiocmset = stl_tiocmset, - .proc_fops = &stl_proc_fops, -}; - -static const struct tty_port_operations stl_port_ops = { - .carrier_raised = stl_carrier_raised, - .dtr_rts = stl_dtr_rts, - .activate = stl_activate, - .shutdown = stl_shutdown, -}; - -/*****************************************************************************/ -/* CD1400 HARDWARE FUNCTIONS */ -/*****************************************************************************/ - -/* - * These functions get/set/update the registers of the cd1400 UARTs. - * Access to the cd1400 registers is via an address/data io port pair. - * (Maybe should make this inline...) - */ - -static int stl_cd1400getreg(struct stlport *portp, int regnr) -{ - outb((regnr + portp->uartaddr), portp->ioaddr); - return inb(portp->ioaddr + EREG_DATA); -} - -static void stl_cd1400setreg(struct stlport *portp, int regnr, int value) -{ - outb(regnr + portp->uartaddr, portp->ioaddr); - outb(value, portp->ioaddr + EREG_DATA); -} - -static int stl_cd1400updatereg(struct stlport *portp, int regnr, int value) -{ - outb(regnr + portp->uartaddr, portp->ioaddr); - if (inb(portp->ioaddr + EREG_DATA) != value) { - outb(value, portp->ioaddr + EREG_DATA); - return 1; - } - return 0; -} - -/*****************************************************************************/ - -/* - * Inbitialize the UARTs in a panel. We don't care what sort of board - * these ports are on - since the port io registers are almost - * identical when dealing with ports. - */ - -static int stl_cd1400panelinit(struct stlbrd *brdp, struct stlpanel *panelp) -{ - unsigned int gfrcr; - int chipmask, i, j; - int nrchips, uartaddr, ioaddr; - unsigned long flags; - - pr_debug("stl_panelinit(brdp=%p,panelp=%p)\n", brdp, panelp); - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(panelp->brdnr, panelp->pagenr); - -/* - * Check that each chip is present and started up OK. - */ - chipmask = 0; - nrchips = panelp->nrports / CD1400_PORTS; - for (i = 0; i < nrchips; i++) { - if (brdp->brdtype == BRD_ECHPCI) { - outb((panelp->pagenr + (i >> 1)), brdp->ioctrl); - ioaddr = panelp->iobase; - } else - ioaddr = panelp->iobase + (EREG_BANKSIZE * (i >> 1)); - uartaddr = (i & 0x01) ? 0x080 : 0; - outb((GFRCR + uartaddr), ioaddr); - outb(0, (ioaddr + EREG_DATA)); - outb((CCR + uartaddr), ioaddr); - outb(CCR_RESETFULL, (ioaddr + EREG_DATA)); - outb(CCR_RESETFULL, (ioaddr + EREG_DATA)); - outb((GFRCR + uartaddr), ioaddr); - for (j = 0; j < CCR_MAXWAIT; j++) - if ((gfrcr = inb(ioaddr + EREG_DATA)) != 0) - break; - - if ((j >= CCR_MAXWAIT) || (gfrcr < 0x40) || (gfrcr > 0x60)) { - printk("STALLION: cd1400 not responding, " - "brd=%d panel=%d chip=%d\n", - panelp->brdnr, panelp->panelnr, i); - continue; - } - chipmask |= (0x1 << i); - outb((PPR + uartaddr), ioaddr); - outb(PPR_SCALAR, (ioaddr + EREG_DATA)); - } - - BRDDISABLE(panelp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); - return chipmask; -} - -/*****************************************************************************/ - -/* - * Initialize hardware specific port registers. - */ - -static void stl_cd1400portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp) -{ - unsigned long flags; - pr_debug("stl_cd1400portinit(brdp=%p,panelp=%p,portp=%p)\n", brdp, - panelp, portp); - - if ((brdp == NULL) || (panelp == NULL) || - (portp == NULL)) - return; - - spin_lock_irqsave(&brd_lock, flags); - portp->ioaddr = panelp->iobase + (((brdp->brdtype == BRD_ECHPCI) || - (portp->portnr < 8)) ? 0 : EREG_BANKSIZE); - portp->uartaddr = (portp->portnr & 0x04) << 5; - portp->pagenr = panelp->pagenr + (portp->portnr >> 3); - - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - stl_cd1400setreg(portp, LIVR, (portp->portnr << 3)); - portp->hwid = stl_cd1400getreg(portp, GFRCR); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Wait for the command register to be ready. We will poll this, - * since it won't usually take too long to be ready. - */ - -static void stl_cd1400ccrwait(struct stlport *portp) -{ - int i; - - for (i = 0; i < CCR_MAXWAIT; i++) - if (stl_cd1400getreg(portp, CCR) == 0) - return; - - printk("STALLION: cd1400 not responding, port=%d panel=%d brd=%d\n", - portp->portnr, portp->panelnr, portp->brdnr); -} - -/*****************************************************************************/ - -/* - * Set up the cd1400 registers for a port based on the termios port - * settings. - */ - -static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp) -{ - struct stlbrd *brdp; - unsigned long flags; - unsigned int clkdiv, baudrate; - unsigned char cor1, cor2, cor3; - unsigned char cor4, cor5, ccr; - unsigned char srer, sreron, sreroff; - unsigned char mcor1, mcor2, rtpr; - unsigned char clk, div; - - cor1 = 0; - cor2 = 0; - cor3 = 0; - cor4 = 0; - cor5 = 0; - ccr = 0; - rtpr = 0; - clk = 0; - div = 0; - mcor1 = 0; - mcor2 = 0; - sreron = 0; - sreroff = 0; - - brdp = stl_brds[portp->brdnr]; - if (brdp == NULL) - return; - -/* - * Set up the RX char ignore mask with those RX error types we - * can ignore. We can get the cd1400 to help us out a little here, - * it will ignore parity errors and breaks for us. - */ - portp->rxignoremsk = 0; - if (tiosp->c_iflag & IGNPAR) { - portp->rxignoremsk |= (ST_PARITY | ST_FRAMING | ST_OVERRUN); - cor1 |= COR1_PARIGNORE; - } - if (tiosp->c_iflag & IGNBRK) { - portp->rxignoremsk |= ST_BREAK; - cor4 |= COR4_IGNBRK; - } - - portp->rxmarkmsk = ST_OVERRUN; - if (tiosp->c_iflag & (INPCK | PARMRK)) - portp->rxmarkmsk |= (ST_PARITY | ST_FRAMING); - if (tiosp->c_iflag & BRKINT) - portp->rxmarkmsk |= ST_BREAK; - -/* - * Go through the char size, parity and stop bits and set all the - * option register appropriately. - */ - switch (tiosp->c_cflag & CSIZE) { - case CS5: - cor1 |= COR1_CHL5; - break; - case CS6: - cor1 |= COR1_CHL6; - break; - case CS7: - cor1 |= COR1_CHL7; - break; - default: - cor1 |= COR1_CHL8; - break; - } - - if (tiosp->c_cflag & CSTOPB) - cor1 |= COR1_STOP2; - else - cor1 |= COR1_STOP1; - - if (tiosp->c_cflag & PARENB) { - if (tiosp->c_cflag & PARODD) - cor1 |= (COR1_PARENB | COR1_PARODD); - else - cor1 |= (COR1_PARENB | COR1_PAREVEN); - } else { - cor1 |= COR1_PARNONE; - } - -/* - * Set the RX FIFO threshold at 6 chars. This gives a bit of breathing - * space for hardware flow control and the like. This should be set to - * VMIN. Also here we will set the RX data timeout to 10ms - this should - * really be based on VTIME. - */ - cor3 |= FIFO_RXTHRESHOLD; - rtpr = 2; - -/* - * Calculate the baud rate timers. For now we will just assume that - * the input and output baud are the same. Could have used a baud - * table here, but this way we can generate virtually any baud rate - * we like! - */ - baudrate = tiosp->c_cflag & CBAUD; - if (baudrate & CBAUDEX) { - baudrate &= ~CBAUDEX; - if ((baudrate < 1) || (baudrate > 4)) - tiosp->c_cflag &= ~CBAUDEX; - else - baudrate += 15; - } - baudrate = stl_baudrates[baudrate]; - if ((tiosp->c_cflag & CBAUD) == B38400) { - if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - baudrate = 57600; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - baudrate = 115200; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - baudrate = 230400; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - baudrate = 460800; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) - baudrate = (portp->baud_base / portp->custom_divisor); - } - if (baudrate > STL_CD1400MAXBAUD) - baudrate = STL_CD1400MAXBAUD; - - if (baudrate > 0) { - for (clk = 0; clk < CD1400_NUMCLKS; clk++) { - clkdiv = (portp->clk / stl_cd1400clkdivs[clk]) / baudrate; - if (clkdiv < 0x100) - break; - } - div = (unsigned char) clkdiv; - } - -/* - * Check what form of modem signaling is required and set it up. - */ - if ((tiosp->c_cflag & CLOCAL) == 0) { - mcor1 |= MCOR1_DCD; - mcor2 |= MCOR2_DCD; - sreron |= SRER_MODEM; - portp->port.flags |= ASYNC_CHECK_CD; - } else - portp->port.flags &= ~ASYNC_CHECK_CD; - -/* - * Setup cd1400 enhanced modes if we can. In particular we want to - * handle as much of the flow control as possible automatically. As - * well as saving a few CPU cycles it will also greatly improve flow - * control reliability. - */ - if (tiosp->c_iflag & IXON) { - cor2 |= COR2_TXIBE; - cor3 |= COR3_SCD12; - if (tiosp->c_iflag & IXANY) - cor2 |= COR2_IXM; - } - - if (tiosp->c_cflag & CRTSCTS) { - cor2 |= COR2_CTSAE; - mcor1 |= FIFO_RTSTHRESHOLD; - } - -/* - * All cd1400 register values calculated so go through and set - * them all up. - */ - - pr_debug("SETPORT: portnr=%d panelnr=%d brdnr=%d\n", - portp->portnr, portp->panelnr, portp->brdnr); - pr_debug(" cor1=%x cor2=%x cor3=%x cor4=%x cor5=%x\n", - cor1, cor2, cor3, cor4, cor5); - pr_debug(" mcor1=%x mcor2=%x rtpr=%x sreron=%x sreroff=%x\n", - mcor1, mcor2, rtpr, sreron, sreroff); - pr_debug(" tcor=%x tbpr=%x rcor=%x rbpr=%x\n", clk, div, clk, div); - pr_debug(" schr1=%x schr2=%x schr3=%x schr4=%x\n", - tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP], - tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x3)); - srer = stl_cd1400getreg(portp, SRER); - stl_cd1400setreg(portp, SRER, 0); - if (stl_cd1400updatereg(portp, COR1, cor1)) - ccr = 1; - if (stl_cd1400updatereg(portp, COR2, cor2)) - ccr = 1; - if (stl_cd1400updatereg(portp, COR3, cor3)) - ccr = 1; - if (ccr) { - stl_cd1400ccrwait(portp); - stl_cd1400setreg(portp, CCR, CCR_CORCHANGE); - } - stl_cd1400setreg(portp, COR4, cor4); - stl_cd1400setreg(portp, COR5, cor5); - stl_cd1400setreg(portp, MCOR1, mcor1); - stl_cd1400setreg(portp, MCOR2, mcor2); - if (baudrate > 0) { - stl_cd1400setreg(portp, TCOR, clk); - stl_cd1400setreg(portp, TBPR, div); - stl_cd1400setreg(portp, RCOR, clk); - stl_cd1400setreg(portp, RBPR, div); - } - stl_cd1400setreg(portp, SCHR1, tiosp->c_cc[VSTART]); - stl_cd1400setreg(portp, SCHR2, tiosp->c_cc[VSTOP]); - stl_cd1400setreg(portp, SCHR3, tiosp->c_cc[VSTART]); - stl_cd1400setreg(portp, SCHR4, tiosp->c_cc[VSTOP]); - stl_cd1400setreg(portp, RTPR, rtpr); - mcor1 = stl_cd1400getreg(portp, MSVR1); - if (mcor1 & MSVR1_DCD) - portp->sigs |= TIOCM_CD; - else - portp->sigs &= ~TIOCM_CD; - stl_cd1400setreg(portp, SRER, ((srer & ~sreroff) | sreron)); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Set the state of the DTR and RTS signals. - */ - -static void stl_cd1400setsignals(struct stlport *portp, int dtr, int rts) -{ - unsigned char msvr1, msvr2; - unsigned long flags; - - pr_debug("stl_cd1400setsignals(portp=%p,dtr=%d,rts=%d)\n", - portp, dtr, rts); - - msvr1 = 0; - msvr2 = 0; - if (dtr > 0) - msvr1 = MSVR1_DTR; - if (rts > 0) - msvr2 = MSVR2_RTS; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - if (rts >= 0) - stl_cd1400setreg(portp, MSVR2, msvr2); - if (dtr >= 0) - stl_cd1400setreg(portp, MSVR1, msvr1); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Return the state of the signals. - */ - -static int stl_cd1400getsignals(struct stlport *portp) -{ - unsigned char msvr1, msvr2; - unsigned long flags; - int sigs; - - pr_debug("stl_cd1400getsignals(portp=%p)\n", portp); - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - msvr1 = stl_cd1400getreg(portp, MSVR1); - msvr2 = stl_cd1400getreg(portp, MSVR2); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); - - sigs = 0; - sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0; - sigs |= (msvr1 & MSVR1_CTS) ? TIOCM_CTS : 0; - sigs |= (msvr1 & MSVR1_DTR) ? TIOCM_DTR : 0; - sigs |= (msvr2 & MSVR2_RTS) ? TIOCM_RTS : 0; -#if 0 - sigs |= (msvr1 & MSVR1_RI) ? TIOCM_RI : 0; - sigs |= (msvr1 & MSVR1_DSR) ? TIOCM_DSR : 0; -#else - sigs |= TIOCM_DSR; -#endif - return sigs; -} - -/*****************************************************************************/ - -/* - * Enable/Disable the Transmitter and/or Receiver. - */ - -static void stl_cd1400enablerxtx(struct stlport *portp, int rx, int tx) -{ - unsigned char ccr; - unsigned long flags; - - pr_debug("stl_cd1400enablerxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx); - - ccr = 0; - - if (tx == 0) - ccr |= CCR_TXDISABLE; - else if (tx > 0) - ccr |= CCR_TXENABLE; - if (rx == 0) - ccr |= CCR_RXDISABLE; - else if (rx > 0) - ccr |= CCR_RXENABLE; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - stl_cd1400ccrwait(portp); - stl_cd1400setreg(portp, CCR, ccr); - stl_cd1400ccrwait(portp); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Start/stop the Transmitter and/or Receiver. - */ - -static void stl_cd1400startrxtx(struct stlport *portp, int rx, int tx) -{ - unsigned char sreron, sreroff; - unsigned long flags; - - pr_debug("stl_cd1400startrxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx); - - sreron = 0; - sreroff = 0; - if (tx == 0) - sreroff |= (SRER_TXDATA | SRER_TXEMPTY); - else if (tx == 1) - sreron |= SRER_TXDATA; - else if (tx >= 2) - sreron |= SRER_TXEMPTY; - if (rx == 0) - sreroff |= SRER_RXDATA; - else if (rx > 0) - sreron |= SRER_RXDATA; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - stl_cd1400setreg(portp, SRER, - ((stl_cd1400getreg(portp, SRER) & ~sreroff) | sreron)); - BRDDISABLE(portp->brdnr); - if (tx > 0) - set_bit(ASYI_TXBUSY, &portp->istate); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Disable all interrupts from this port. - */ - -static void stl_cd1400disableintrs(struct stlport *portp) -{ - unsigned long flags; - - pr_debug("stl_cd1400disableintrs(portp=%p)\n", portp); - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - stl_cd1400setreg(portp, SRER, 0); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -static void stl_cd1400sendbreak(struct stlport *portp, int len) -{ - unsigned long flags; - - pr_debug("stl_cd1400sendbreak(portp=%p,len=%d)\n", portp, len); - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - stl_cd1400setreg(portp, SRER, - ((stl_cd1400getreg(portp, SRER) & ~SRER_TXDATA) | - SRER_TXEMPTY)); - BRDDISABLE(portp->brdnr); - portp->brklen = len; - if (len == 1) - portp->stats.txbreaks++; - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Take flow control actions... - */ - -static void stl_cd1400flowctrl(struct stlport *portp, int state) -{ - struct tty_struct *tty; - unsigned long flags; - - pr_debug("stl_cd1400flowctrl(portp=%p,state=%x)\n", portp, state); - - if (portp == NULL) - return; - tty = tty_port_tty_get(&portp->port); - if (tty == NULL) - return; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - - if (state) { - if (tty->termios->c_iflag & IXOFF) { - stl_cd1400ccrwait(portp); - stl_cd1400setreg(portp, CCR, CCR_SENDSCHR1); - portp->stats.rxxon++; - stl_cd1400ccrwait(portp); - } -/* - * Question: should we return RTS to what it was before? It may - * have been set by an ioctl... Suppose not, since if you have - * hardware flow control set then it is pretty silly to go and - * set the RTS line by hand. - */ - if (tty->termios->c_cflag & CRTSCTS) { - stl_cd1400setreg(portp, MCOR1, - (stl_cd1400getreg(portp, MCOR1) | - FIFO_RTSTHRESHOLD)); - stl_cd1400setreg(portp, MSVR2, MSVR2_RTS); - portp->stats.rxrtson++; - } - } else { - if (tty->termios->c_iflag & IXOFF) { - stl_cd1400ccrwait(portp); - stl_cd1400setreg(portp, CCR, CCR_SENDSCHR2); - portp->stats.rxxoff++; - stl_cd1400ccrwait(portp); - } - if (tty->termios->c_cflag & CRTSCTS) { - stl_cd1400setreg(portp, MCOR1, - (stl_cd1400getreg(portp, MCOR1) & 0xf0)); - stl_cd1400setreg(portp, MSVR2, 0); - portp->stats.rxrtsoff++; - } - } - - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); - tty_kref_put(tty); -} - -/*****************************************************************************/ - -/* - * Send a flow control character... - */ - -static void stl_cd1400sendflow(struct stlport *portp, int state) -{ - struct tty_struct *tty; - unsigned long flags; - - pr_debug("stl_cd1400sendflow(portp=%p,state=%x)\n", portp, state); - - if (portp == NULL) - return; - tty = tty_port_tty_get(&portp->port); - if (tty == NULL) - return; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - if (state) { - stl_cd1400ccrwait(portp); - stl_cd1400setreg(portp, CCR, CCR_SENDSCHR1); - portp->stats.rxxon++; - stl_cd1400ccrwait(portp); - } else { - stl_cd1400ccrwait(portp); - stl_cd1400setreg(portp, CCR, CCR_SENDSCHR2); - portp->stats.rxxoff++; - stl_cd1400ccrwait(portp); - } - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); - tty_kref_put(tty); -} - -/*****************************************************************************/ - -static void stl_cd1400flush(struct stlport *portp) -{ - unsigned long flags; - - pr_debug("stl_cd1400flush(portp=%p)\n", portp); - - if (portp == NULL) - return; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - stl_cd1400ccrwait(portp); - stl_cd1400setreg(portp, CCR, CCR_TXFLUSHFIFO); - stl_cd1400ccrwait(portp); - portp->tx.tail = portp->tx.head; - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Return the current state of data flow on this port. This is only - * really interesting when determining if data has fully completed - * transmission or not... This is easy for the cd1400, it accurately - * maintains the busy port flag. - */ - -static int stl_cd1400datastate(struct stlport *portp) -{ - pr_debug("stl_cd1400datastate(portp=%p)\n", portp); - - if (portp == NULL) - return 0; - - return test_bit(ASYI_TXBUSY, &portp->istate) ? 1 : 0; -} - -/*****************************************************************************/ - -/* - * Interrupt service routine for cd1400 EasyIO boards. - */ - -static void stl_cd1400eiointr(struct stlpanel *panelp, unsigned int iobase) -{ - unsigned char svrtype; - - pr_debug("stl_cd1400eiointr(panelp=%p,iobase=%x)\n", panelp, iobase); - - spin_lock(&brd_lock); - outb(SVRR, iobase); - svrtype = inb(iobase + EREG_DATA); - if (panelp->nrports > 4) { - outb((SVRR + 0x80), iobase); - svrtype |= inb(iobase + EREG_DATA); - } - - if (svrtype & SVRR_RX) - stl_cd1400rxisr(panelp, iobase); - else if (svrtype & SVRR_TX) - stl_cd1400txisr(panelp, iobase); - else if (svrtype & SVRR_MDM) - stl_cd1400mdmisr(panelp, iobase); - - spin_unlock(&brd_lock); -} - -/*****************************************************************************/ - -/* - * Interrupt service routine for cd1400 panels. - */ - -static void stl_cd1400echintr(struct stlpanel *panelp, unsigned int iobase) -{ - unsigned char svrtype; - - pr_debug("stl_cd1400echintr(panelp=%p,iobase=%x)\n", panelp, iobase); - - outb(SVRR, iobase); - svrtype = inb(iobase + EREG_DATA); - outb((SVRR + 0x80), iobase); - svrtype |= inb(iobase + EREG_DATA); - if (svrtype & SVRR_RX) - stl_cd1400rxisr(panelp, iobase); - else if (svrtype & SVRR_TX) - stl_cd1400txisr(panelp, iobase); - else if (svrtype & SVRR_MDM) - stl_cd1400mdmisr(panelp, iobase); -} - - -/*****************************************************************************/ - -/* - * Unfortunately we need to handle breaks in the TX data stream, since - * this is the only way to generate them on the cd1400. - */ - -static int stl_cd1400breakisr(struct stlport *portp, int ioaddr) -{ - if (portp->brklen == 1) { - outb((COR2 + portp->uartaddr), ioaddr); - outb((inb(ioaddr + EREG_DATA) | COR2_ETC), - (ioaddr + EREG_DATA)); - outb((TDR + portp->uartaddr), ioaddr); - outb(ETC_CMD, (ioaddr + EREG_DATA)); - outb(ETC_STARTBREAK, (ioaddr + EREG_DATA)); - outb((SRER + portp->uartaddr), ioaddr); - outb((inb(ioaddr + EREG_DATA) & ~(SRER_TXDATA | SRER_TXEMPTY)), - (ioaddr + EREG_DATA)); - return 1; - } else if (portp->brklen > 1) { - outb((TDR + portp->uartaddr), ioaddr); - outb(ETC_CMD, (ioaddr + EREG_DATA)); - outb(ETC_STOPBREAK, (ioaddr + EREG_DATA)); - portp->brklen = -1; - return 1; - } else { - outb((COR2 + portp->uartaddr), ioaddr); - outb((inb(ioaddr + EREG_DATA) & ~COR2_ETC), - (ioaddr + EREG_DATA)); - portp->brklen = 0; - } - return 0; -} - -/*****************************************************************************/ - -/* - * Transmit interrupt handler. This has gotta be fast! Handling TX - * chars is pretty simple, stuff as many as possible from the TX buffer - * into the cd1400 FIFO. Must also handle TX breaks here, since they - * are embedded as commands in the data stream. Oh no, had to use a goto! - * This could be optimized more, will do when I get time... - * In practice it is possible that interrupts are enabled but that the - * port has been hung up. Need to handle not having any TX buffer here, - * this is done by using the side effect that head and tail will also - * be NULL if the buffer has been freed. - */ - -static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr) -{ - struct stlport *portp; - int len, stlen; - char *head, *tail; - unsigned char ioack, srer; - struct tty_struct *tty; - - pr_debug("stl_cd1400txisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr); - - ioack = inb(ioaddr + EREG_TXACK); - if (((ioack & panelp->ackmask) != 0) || - ((ioack & ACK_TYPMASK) != ACK_TYPTX)) { - printk("STALLION: bad TX interrupt ack value=%x\n", ioack); - return; - } - portp = panelp->ports[(ioack >> 3)]; - -/* - * Unfortunately we need to handle breaks in the data stream, since - * this is the only way to generate them on the cd1400. Do it now if - * a break is to be sent. - */ - if (portp->brklen != 0) - if (stl_cd1400breakisr(portp, ioaddr)) - goto stl_txalldone; - - head = portp->tx.head; - tail = portp->tx.tail; - len = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head)); - if ((len == 0) || ((len < STL_TXBUFLOW) && - (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { - set_bit(ASYI_TXLOW, &portp->istate); - tty = tty_port_tty_get(&portp->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } - } - - if (len == 0) { - outb((SRER + portp->uartaddr), ioaddr); - srer = inb(ioaddr + EREG_DATA); - if (srer & SRER_TXDATA) { - srer = (srer & ~SRER_TXDATA) | SRER_TXEMPTY; - } else { - srer &= ~(SRER_TXDATA | SRER_TXEMPTY); - clear_bit(ASYI_TXBUSY, &portp->istate); - } - outb(srer, (ioaddr + EREG_DATA)); - } else { - len = min(len, CD1400_TXFIFOSIZE); - portp->stats.txtotal += len; - stlen = min_t(unsigned int, len, - (portp->tx.buf + STL_TXBUFSIZE) - tail); - outb((TDR + portp->uartaddr), ioaddr); - outsb((ioaddr + EREG_DATA), tail, stlen); - len -= stlen; - tail += stlen; - if (tail >= (portp->tx.buf + STL_TXBUFSIZE)) - tail = portp->tx.buf; - if (len > 0) { - outsb((ioaddr + EREG_DATA), tail, len); - tail += len; - } - portp->tx.tail = tail; - } - -stl_txalldone: - outb((EOSRR + portp->uartaddr), ioaddr); - outb(0, (ioaddr + EREG_DATA)); -} - -/*****************************************************************************/ - -/* - * Receive character interrupt handler. Determine if we have good chars - * or bad chars and then process appropriately. Good chars are easy - * just shove the lot into the RX buffer and set all status byte to 0. - * If a bad RX char then process as required. This routine needs to be - * fast! In practice it is possible that we get an interrupt on a port - * that is closed. This can happen on hangups - since they completely - * shutdown a port not in user context. Need to handle this case. - */ - -static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr) -{ - struct stlport *portp; - struct tty_struct *tty; - unsigned int ioack, len, buflen; - unsigned char status; - char ch; - - pr_debug("stl_cd1400rxisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr); - - ioack = inb(ioaddr + EREG_RXACK); - if ((ioack & panelp->ackmask) != 0) { - printk("STALLION: bad RX interrupt ack value=%x\n", ioack); - return; - } - portp = panelp->ports[(ioack >> 3)]; - tty = tty_port_tty_get(&portp->port); - - if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) { - outb((RDCR + portp->uartaddr), ioaddr); - len = inb(ioaddr + EREG_DATA); - if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) { - len = min_t(unsigned int, len, sizeof(stl_unwanted)); - outb((RDSR + portp->uartaddr), ioaddr); - insb((ioaddr + EREG_DATA), &stl_unwanted[0], len); - portp->stats.rxlost += len; - portp->stats.rxtotal += len; - } else { - len = min(len, buflen); - if (len > 0) { - unsigned char *ptr; - outb((RDSR + portp->uartaddr), ioaddr); - tty_prepare_flip_string(tty, &ptr, len); - insb((ioaddr + EREG_DATA), ptr, len); - tty_schedule_flip(tty); - portp->stats.rxtotal += len; - } - } - } else if ((ioack & ACK_TYPMASK) == ACK_TYPRXBAD) { - outb((RDSR + portp->uartaddr), ioaddr); - status = inb(ioaddr + EREG_DATA); - ch = inb(ioaddr + EREG_DATA); - if (status & ST_PARITY) - portp->stats.rxparity++; - if (status & ST_FRAMING) - portp->stats.rxframing++; - if (status & ST_OVERRUN) - portp->stats.rxoverrun++; - if (status & ST_BREAK) - portp->stats.rxbreaks++; - if (status & ST_SCHARMASK) { - if ((status & ST_SCHARMASK) == ST_SCHAR1) - portp->stats.txxon++; - if ((status & ST_SCHARMASK) == ST_SCHAR2) - portp->stats.txxoff++; - goto stl_rxalldone; - } - if (tty != NULL && (portp->rxignoremsk & status) == 0) { - if (portp->rxmarkmsk & status) { - if (status & ST_BREAK) { - status = TTY_BREAK; - if (portp->port.flags & ASYNC_SAK) { - do_SAK(tty); - BRDENABLE(portp->brdnr, portp->pagenr); - } - } else if (status & ST_PARITY) - status = TTY_PARITY; - else if (status & ST_FRAMING) - status = TTY_FRAME; - else if(status & ST_OVERRUN) - status = TTY_OVERRUN; - else - status = 0; - } else - status = 0; - tty_insert_flip_char(tty, ch, status); - tty_schedule_flip(tty); - } - } else { - printk("STALLION: bad RX interrupt ack value=%x\n", ioack); - tty_kref_put(tty); - return; - } - -stl_rxalldone: - tty_kref_put(tty); - outb((EOSRR + portp->uartaddr), ioaddr); - outb(0, (ioaddr + EREG_DATA)); -} - -/*****************************************************************************/ - -/* - * Modem interrupt handler. The is called when the modem signal line - * (DCD) has changed state. Leave most of the work to the off-level - * processing routine. - */ - -static void stl_cd1400mdmisr(struct stlpanel *panelp, int ioaddr) -{ - struct stlport *portp; - unsigned int ioack; - unsigned char misr; - - pr_debug("stl_cd1400mdmisr(panelp=%p)\n", panelp); - - ioack = inb(ioaddr + EREG_MDACK); - if (((ioack & panelp->ackmask) != 0) || - ((ioack & ACK_TYPMASK) != ACK_TYPMDM)) { - printk("STALLION: bad MODEM interrupt ack value=%x\n", ioack); - return; - } - portp = panelp->ports[(ioack >> 3)]; - - outb((MISR + portp->uartaddr), ioaddr); - misr = inb(ioaddr + EREG_DATA); - if (misr & MISR_DCD) { - stl_cd_change(portp); - portp->stats.modem++; - } - - outb((EOSRR + portp->uartaddr), ioaddr); - outb(0, (ioaddr + EREG_DATA)); -} - -/*****************************************************************************/ -/* SC26198 HARDWARE FUNCTIONS */ -/*****************************************************************************/ - -/* - * These functions get/set/update the registers of the sc26198 UARTs. - * Access to the sc26198 registers is via an address/data io port pair. - * (Maybe should make this inline...) - */ - -static int stl_sc26198getreg(struct stlport *portp, int regnr) -{ - outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR)); - return inb(portp->ioaddr + XP_DATA); -} - -static void stl_sc26198setreg(struct stlport *portp, int regnr, int value) -{ - outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR)); - outb(value, (portp->ioaddr + XP_DATA)); -} - -static int stl_sc26198updatereg(struct stlport *portp, int regnr, int value) -{ - outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR)); - if (inb(portp->ioaddr + XP_DATA) != value) { - outb(value, (portp->ioaddr + XP_DATA)); - return 1; - } - return 0; -} - -/*****************************************************************************/ - -/* - * Functions to get and set the sc26198 global registers. - */ - -static int stl_sc26198getglobreg(struct stlport *portp, int regnr) -{ - outb(regnr, (portp->ioaddr + XP_ADDR)); - return inb(portp->ioaddr + XP_DATA); -} - -#if 0 -static void stl_sc26198setglobreg(struct stlport *portp, int regnr, int value) -{ - outb(regnr, (portp->ioaddr + XP_ADDR)); - outb(value, (portp->ioaddr + XP_DATA)); -} -#endif - -/*****************************************************************************/ - -/* - * Inbitialize the UARTs in a panel. We don't care what sort of board - * these ports are on - since the port io registers are almost - * identical when dealing with ports. - */ - -static int stl_sc26198panelinit(struct stlbrd *brdp, struct stlpanel *panelp) -{ - int chipmask, i; - int nrchips, ioaddr; - - pr_debug("stl_sc26198panelinit(brdp=%p,panelp=%p)\n", brdp, panelp); - - BRDENABLE(panelp->brdnr, panelp->pagenr); - -/* - * Check that each chip is present and started up OK. - */ - chipmask = 0; - nrchips = (panelp->nrports + 4) / SC26198_PORTS; - if (brdp->brdtype == BRD_ECHPCI) - outb(panelp->pagenr, brdp->ioctrl); - - for (i = 0; i < nrchips; i++) { - ioaddr = panelp->iobase + (i * 4); - outb(SCCR, (ioaddr + XP_ADDR)); - outb(CR_RESETALL, (ioaddr + XP_DATA)); - outb(TSTR, (ioaddr + XP_ADDR)); - if (inb(ioaddr + XP_DATA) != 0) { - printk("STALLION: sc26198 not responding, " - "brd=%d panel=%d chip=%d\n", - panelp->brdnr, panelp->panelnr, i); - continue; - } - chipmask |= (0x1 << i); - outb(GCCR, (ioaddr + XP_ADDR)); - outb(GCCR_IVRTYPCHANACK, (ioaddr + XP_DATA)); - outb(WDTRCR, (ioaddr + XP_ADDR)); - outb(0xff, (ioaddr + XP_DATA)); - } - - BRDDISABLE(panelp->brdnr); - return chipmask; -} - -/*****************************************************************************/ - -/* - * Initialize hardware specific port registers. - */ - -static void stl_sc26198portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp) -{ - pr_debug("stl_sc26198portinit(brdp=%p,panelp=%p,portp=%p)\n", brdp, - panelp, portp); - - if ((brdp == NULL) || (panelp == NULL) || - (portp == NULL)) - return; - - portp->ioaddr = panelp->iobase + ((portp->portnr < 8) ? 0 : 4); - portp->uartaddr = (portp->portnr & 0x07) << 4; - portp->pagenr = panelp->pagenr; - portp->hwid = 0x1; - - BRDENABLE(portp->brdnr, portp->pagenr); - stl_sc26198setreg(portp, IOPCR, IOPCR_SETSIGS); - BRDDISABLE(portp->brdnr); -} - -/*****************************************************************************/ - -/* - * Set up the sc26198 registers for a port based on the termios port - * settings. - */ - -static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp) -{ - struct stlbrd *brdp; - unsigned long flags; - unsigned int baudrate; - unsigned char mr0, mr1, mr2, clk; - unsigned char imron, imroff, iopr, ipr; - - mr0 = 0; - mr1 = 0; - mr2 = 0; - clk = 0; - iopr = 0; - imron = 0; - imroff = 0; - - brdp = stl_brds[portp->brdnr]; - if (brdp == NULL) - return; - -/* - * Set up the RX char ignore mask with those RX error types we - * can ignore. - */ - portp->rxignoremsk = 0; - if (tiosp->c_iflag & IGNPAR) - portp->rxignoremsk |= (SR_RXPARITY | SR_RXFRAMING | - SR_RXOVERRUN); - if (tiosp->c_iflag & IGNBRK) - portp->rxignoremsk |= SR_RXBREAK; - - portp->rxmarkmsk = SR_RXOVERRUN; - if (tiosp->c_iflag & (INPCK | PARMRK)) - portp->rxmarkmsk |= (SR_RXPARITY | SR_RXFRAMING); - if (tiosp->c_iflag & BRKINT) - portp->rxmarkmsk |= SR_RXBREAK; - -/* - * Go through the char size, parity and stop bits and set all the - * option register appropriately. - */ - switch (tiosp->c_cflag & CSIZE) { - case CS5: - mr1 |= MR1_CS5; - break; - case CS6: - mr1 |= MR1_CS6; - break; - case CS7: - mr1 |= MR1_CS7; - break; - default: - mr1 |= MR1_CS8; - break; - } - - if (tiosp->c_cflag & CSTOPB) - mr2 |= MR2_STOP2; - else - mr2 |= MR2_STOP1; - - if (tiosp->c_cflag & PARENB) { - if (tiosp->c_cflag & PARODD) - mr1 |= (MR1_PARENB | MR1_PARODD); - else - mr1 |= (MR1_PARENB | MR1_PAREVEN); - } else - mr1 |= MR1_PARNONE; - - mr1 |= MR1_ERRBLOCK; - -/* - * Set the RX FIFO threshold at 8 chars. This gives a bit of breathing - * space for hardware flow control and the like. This should be set to - * VMIN. - */ - mr2 |= MR2_RXFIFOHALF; - -/* - * Calculate the baud rate timers. For now we will just assume that - * the input and output baud are the same. The sc26198 has a fixed - * baud rate table, so only discrete baud rates possible. - */ - baudrate = tiosp->c_cflag & CBAUD; - if (baudrate & CBAUDEX) { - baudrate &= ~CBAUDEX; - if ((baudrate < 1) || (baudrate > 4)) - tiosp->c_cflag &= ~CBAUDEX; - else - baudrate += 15; - } - baudrate = stl_baudrates[baudrate]; - if ((tiosp->c_cflag & CBAUD) == B38400) { - if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - baudrate = 57600; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - baudrate = 115200; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - baudrate = 230400; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - baudrate = 460800; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) - baudrate = (portp->baud_base / portp->custom_divisor); - } - if (baudrate > STL_SC26198MAXBAUD) - baudrate = STL_SC26198MAXBAUD; - - if (baudrate > 0) - for (clk = 0; clk < SC26198_NRBAUDS; clk++) - if (baudrate <= sc26198_baudtable[clk]) - break; - -/* - * Check what form of modem signaling is required and set it up. - */ - if (tiosp->c_cflag & CLOCAL) { - portp->port.flags &= ~ASYNC_CHECK_CD; - } else { - iopr |= IOPR_DCDCOS; - imron |= IR_IOPORT; - portp->port.flags |= ASYNC_CHECK_CD; - } - -/* - * Setup sc26198 enhanced modes if we can. In particular we want to - * handle as much of the flow control as possible automatically. As - * well as saving a few CPU cycles it will also greatly improve flow - * control reliability. - */ - if (tiosp->c_iflag & IXON) { - mr0 |= MR0_SWFTX | MR0_SWFT; - imron |= IR_XONXOFF; - } else - imroff |= IR_XONXOFF; - - if (tiosp->c_iflag & IXOFF) - mr0 |= MR0_SWFRX; - - if (tiosp->c_cflag & CRTSCTS) { - mr2 |= MR2_AUTOCTS; - mr1 |= MR1_AUTORTS; - } - -/* - * All sc26198 register values calculated so go through and set - * them all up. - */ - - pr_debug("SETPORT: portnr=%d panelnr=%d brdnr=%d\n", - portp->portnr, portp->panelnr, portp->brdnr); - pr_debug(" mr0=%x mr1=%x mr2=%x clk=%x\n", mr0, mr1, mr2, clk); - pr_debug(" iopr=%x imron=%x imroff=%x\n", iopr, imron, imroff); - pr_debug(" schr1=%x schr2=%x schr3=%x schr4=%x\n", - tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP], - tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_sc26198setreg(portp, IMR, 0); - stl_sc26198updatereg(portp, MR0, mr0); - stl_sc26198updatereg(portp, MR1, mr1); - stl_sc26198setreg(portp, SCCR, CR_RXERRBLOCK); - stl_sc26198updatereg(portp, MR2, mr2); - stl_sc26198updatereg(portp, IOPIOR, - ((stl_sc26198getreg(portp, IOPIOR) & ~IPR_CHANGEMASK) | iopr)); - - if (baudrate > 0) { - stl_sc26198setreg(portp, TXCSR, clk); - stl_sc26198setreg(portp, RXCSR, clk); - } - - stl_sc26198setreg(portp, XONCR, tiosp->c_cc[VSTART]); - stl_sc26198setreg(portp, XOFFCR, tiosp->c_cc[VSTOP]); - - ipr = stl_sc26198getreg(portp, IPR); - if (ipr & IPR_DCD) - portp->sigs &= ~TIOCM_CD; - else - portp->sigs |= TIOCM_CD; - - portp->imr = (portp->imr & ~imroff) | imron; - stl_sc26198setreg(portp, IMR, portp->imr); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Set the state of the DTR and RTS signals. - */ - -static void stl_sc26198setsignals(struct stlport *portp, int dtr, int rts) -{ - unsigned char iopioron, iopioroff; - unsigned long flags; - - pr_debug("stl_sc26198setsignals(portp=%p,dtr=%d,rts=%d)\n", portp, - dtr, rts); - - iopioron = 0; - iopioroff = 0; - if (dtr == 0) - iopioroff |= IPR_DTR; - else if (dtr > 0) - iopioron |= IPR_DTR; - if (rts == 0) - iopioroff |= IPR_RTS; - else if (rts > 0) - iopioron |= IPR_RTS; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_sc26198setreg(portp, IOPIOR, - ((stl_sc26198getreg(portp, IOPIOR) & ~iopioroff) | iopioron)); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Return the state of the signals. - */ - -static int stl_sc26198getsignals(struct stlport *portp) -{ - unsigned char ipr; - unsigned long flags; - int sigs; - - pr_debug("stl_sc26198getsignals(portp=%p)\n", portp); - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - ipr = stl_sc26198getreg(portp, IPR); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); - - sigs = 0; - sigs |= (ipr & IPR_DCD) ? 0 : TIOCM_CD; - sigs |= (ipr & IPR_CTS) ? 0 : TIOCM_CTS; - sigs |= (ipr & IPR_DTR) ? 0: TIOCM_DTR; - sigs |= (ipr & IPR_RTS) ? 0: TIOCM_RTS; - sigs |= TIOCM_DSR; - return sigs; -} - -/*****************************************************************************/ - -/* - * Enable/Disable the Transmitter and/or Receiver. - */ - -static void stl_sc26198enablerxtx(struct stlport *portp, int rx, int tx) -{ - unsigned char ccr; - unsigned long flags; - - pr_debug("stl_sc26198enablerxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx,tx); - - ccr = portp->crenable; - if (tx == 0) - ccr &= ~CR_TXENABLE; - else if (tx > 0) - ccr |= CR_TXENABLE; - if (rx == 0) - ccr &= ~CR_RXENABLE; - else if (rx > 0) - ccr |= CR_RXENABLE; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_sc26198setreg(portp, SCCR, ccr); - BRDDISABLE(portp->brdnr); - portp->crenable = ccr; - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Start/stop the Transmitter and/or Receiver. - */ - -static void stl_sc26198startrxtx(struct stlport *portp, int rx, int tx) -{ - unsigned char imr; - unsigned long flags; - - pr_debug("stl_sc26198startrxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx); - - imr = portp->imr; - if (tx == 0) - imr &= ~IR_TXRDY; - else if (tx == 1) - imr |= IR_TXRDY; - if (rx == 0) - imr &= ~(IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG); - else if (rx > 0) - imr |= IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_sc26198setreg(portp, IMR, imr); - BRDDISABLE(portp->brdnr); - portp->imr = imr; - if (tx > 0) - set_bit(ASYI_TXBUSY, &portp->istate); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Disable all interrupts from this port. - */ - -static void stl_sc26198disableintrs(struct stlport *portp) -{ - unsigned long flags; - - pr_debug("stl_sc26198disableintrs(portp=%p)\n", portp); - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - portp->imr = 0; - stl_sc26198setreg(portp, IMR, 0); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -static void stl_sc26198sendbreak(struct stlport *portp, int len) -{ - unsigned long flags; - - pr_debug("stl_sc26198sendbreak(portp=%p,len=%d)\n", portp, len); - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - if (len == 1) { - stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK); - portp->stats.txbreaks++; - } else - stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK); - - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Take flow control actions... - */ - -static void stl_sc26198flowctrl(struct stlport *portp, int state) -{ - struct tty_struct *tty; - unsigned long flags; - unsigned char mr0; - - pr_debug("stl_sc26198flowctrl(portp=%p,state=%x)\n", portp, state); - - if (portp == NULL) - return; - tty = tty_port_tty_get(&portp->port); - if (tty == NULL) - return; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - - if (state) { - if (tty->termios->c_iflag & IXOFF) { - mr0 = stl_sc26198getreg(portp, MR0); - stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX)); - stl_sc26198setreg(portp, SCCR, CR_TXSENDXON); - mr0 |= MR0_SWFRX; - portp->stats.rxxon++; - stl_sc26198wait(portp); - stl_sc26198setreg(portp, MR0, mr0); - } -/* - * Question: should we return RTS to what it was before? It may - * have been set by an ioctl... Suppose not, since if you have - * hardware flow control set then it is pretty silly to go and - * set the RTS line by hand. - */ - if (tty->termios->c_cflag & CRTSCTS) { - stl_sc26198setreg(portp, MR1, - (stl_sc26198getreg(portp, MR1) | MR1_AUTORTS)); - stl_sc26198setreg(portp, IOPIOR, - (stl_sc26198getreg(portp, IOPIOR) | IOPR_RTS)); - portp->stats.rxrtson++; - } - } else { - if (tty->termios->c_iflag & IXOFF) { - mr0 = stl_sc26198getreg(portp, MR0); - stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX)); - stl_sc26198setreg(portp, SCCR, CR_TXSENDXOFF); - mr0 &= ~MR0_SWFRX; - portp->stats.rxxoff++; - stl_sc26198wait(portp); - stl_sc26198setreg(portp, MR0, mr0); - } - if (tty->termios->c_cflag & CRTSCTS) { - stl_sc26198setreg(portp, MR1, - (stl_sc26198getreg(portp, MR1) & ~MR1_AUTORTS)); - stl_sc26198setreg(portp, IOPIOR, - (stl_sc26198getreg(portp, IOPIOR) & ~IOPR_RTS)); - portp->stats.rxrtsoff++; - } - } - - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); - tty_kref_put(tty); -} - -/*****************************************************************************/ - -/* - * Send a flow control character. - */ - -static void stl_sc26198sendflow(struct stlport *portp, int state) -{ - struct tty_struct *tty; - unsigned long flags; - unsigned char mr0; - - pr_debug("stl_sc26198sendflow(portp=%p,state=%x)\n", portp, state); - - if (portp == NULL) - return; - tty = tty_port_tty_get(&portp->port); - if (tty == NULL) - return; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - if (state) { - mr0 = stl_sc26198getreg(portp, MR0); - stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX)); - stl_sc26198setreg(portp, SCCR, CR_TXSENDXON); - mr0 |= MR0_SWFRX; - portp->stats.rxxon++; - stl_sc26198wait(portp); - stl_sc26198setreg(portp, MR0, mr0); - } else { - mr0 = stl_sc26198getreg(portp, MR0); - stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX)); - stl_sc26198setreg(portp, SCCR, CR_TXSENDXOFF); - mr0 &= ~MR0_SWFRX; - portp->stats.rxxoff++; - stl_sc26198wait(portp); - stl_sc26198setreg(portp, MR0, mr0); - } - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); - tty_kref_put(tty); -} - -/*****************************************************************************/ - -static void stl_sc26198flush(struct stlport *portp) -{ - unsigned long flags; - - pr_debug("stl_sc26198flush(portp=%p)\n", portp); - - if (portp == NULL) - return; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_sc26198setreg(portp, SCCR, CR_TXRESET); - stl_sc26198setreg(portp, SCCR, portp->crenable); - BRDDISABLE(portp->brdnr); - portp->tx.tail = portp->tx.head; - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Return the current state of data flow on this port. This is only - * really interesting when determining if data has fully completed - * transmission or not... The sc26198 interrupt scheme cannot - * determine when all data has actually drained, so we need to - * check the port statusy register to be sure. - */ - -static int stl_sc26198datastate(struct stlport *portp) -{ - unsigned long flags; - unsigned char sr; - - pr_debug("stl_sc26198datastate(portp=%p)\n", portp); - - if (portp == NULL) - return 0; - if (test_bit(ASYI_TXBUSY, &portp->istate)) - return 1; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - sr = stl_sc26198getreg(portp, SR); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); - - return (sr & SR_TXEMPTY) ? 0 : 1; -} - -/*****************************************************************************/ - -/* - * Delay for a small amount of time, to give the sc26198 a chance - * to process a command... - */ - -static void stl_sc26198wait(struct stlport *portp) -{ - int i; - - pr_debug("stl_sc26198wait(portp=%p)\n", portp); - - if (portp == NULL) - return; - - for (i = 0; i < 20; i++) - stl_sc26198getglobreg(portp, TSTR); -} - -/*****************************************************************************/ - -/* - * If we are TX flow controlled and in IXANY mode then we may - * need to unflow control here. We gotta do this because of the - * automatic flow control modes of the sc26198. - */ - -static void stl_sc26198txunflow(struct stlport *portp, struct tty_struct *tty) -{ - unsigned char mr0; - - mr0 = stl_sc26198getreg(portp, MR0); - stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX)); - stl_sc26198setreg(portp, SCCR, CR_HOSTXON); - stl_sc26198wait(portp); - stl_sc26198setreg(portp, MR0, mr0); - clear_bit(ASYI_TXFLOWED, &portp->istate); -} - -/*****************************************************************************/ - -/* - * Interrupt service routine for sc26198 panels. - */ - -static void stl_sc26198intr(struct stlpanel *panelp, unsigned int iobase) -{ - struct stlport *portp; - unsigned int iack; - - spin_lock(&brd_lock); - -/* - * Work around bug in sc26198 chip... Cannot have A6 address - * line of UART high, else iack will be returned as 0. - */ - outb(0, (iobase + 1)); - - iack = inb(iobase + XP_IACK); - portp = panelp->ports[(iack & IVR_CHANMASK) + ((iobase & 0x4) << 1)]; - - if (iack & IVR_RXDATA) - stl_sc26198rxisr(portp, iack); - else if (iack & IVR_TXDATA) - stl_sc26198txisr(portp); - else - stl_sc26198otherisr(portp, iack); - - spin_unlock(&brd_lock); -} - -/*****************************************************************************/ - -/* - * Transmit interrupt handler. This has gotta be fast! Handling TX - * chars is pretty simple, stuff as many as possible from the TX buffer - * into the sc26198 FIFO. - * In practice it is possible that interrupts are enabled but that the - * port has been hung up. Need to handle not having any TX buffer here, - * this is done by using the side effect that head and tail will also - * be NULL if the buffer has been freed. - */ - -static void stl_sc26198txisr(struct stlport *portp) -{ - struct tty_struct *tty; - unsigned int ioaddr; - unsigned char mr0; - int len, stlen; - char *head, *tail; - - pr_debug("stl_sc26198txisr(portp=%p)\n", portp); - - ioaddr = portp->ioaddr; - head = portp->tx.head; - tail = portp->tx.tail; - len = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head)); - if ((len == 0) || ((len < STL_TXBUFLOW) && - (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { - set_bit(ASYI_TXLOW, &portp->istate); - tty = tty_port_tty_get(&portp->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } - } - - if (len == 0) { - outb((MR0 | portp->uartaddr), (ioaddr + XP_ADDR)); - mr0 = inb(ioaddr + XP_DATA); - if ((mr0 & MR0_TXMASK) == MR0_TXEMPTY) { - portp->imr &= ~IR_TXRDY; - outb((IMR | portp->uartaddr), (ioaddr + XP_ADDR)); - outb(portp->imr, (ioaddr + XP_DATA)); - clear_bit(ASYI_TXBUSY, &portp->istate); - } else { - mr0 |= ((mr0 & ~MR0_TXMASK) | MR0_TXEMPTY); - outb(mr0, (ioaddr + XP_DATA)); - } - } else { - len = min(len, SC26198_TXFIFOSIZE); - portp->stats.txtotal += len; - stlen = min_t(unsigned int, len, - (portp->tx.buf + STL_TXBUFSIZE) - tail); - outb(GTXFIFO, (ioaddr + XP_ADDR)); - outsb((ioaddr + XP_DATA), tail, stlen); - len -= stlen; - tail += stlen; - if (tail >= (portp->tx.buf + STL_TXBUFSIZE)) - tail = portp->tx.buf; - if (len > 0) { - outsb((ioaddr + XP_DATA), tail, len); - tail += len; - } - portp->tx.tail = tail; - } -} - -/*****************************************************************************/ - -/* - * Receive character interrupt handler. Determine if we have good chars - * or bad chars and then process appropriately. Good chars are easy - * just shove the lot into the RX buffer and set all status byte to 0. - * If a bad RX char then process as required. This routine needs to be - * fast! In practice it is possible that we get an interrupt on a port - * that is closed. This can happen on hangups - since they completely - * shutdown a port not in user context. Need to handle this case. - */ - -static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack) -{ - struct tty_struct *tty; - unsigned int len, buflen, ioaddr; - - pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack); - - tty = tty_port_tty_get(&portp->port); - ioaddr = portp->ioaddr; - outb(GIBCR, (ioaddr + XP_ADDR)); - len = inb(ioaddr + XP_DATA) + 1; - - if ((iack & IVR_TYPEMASK) == IVR_RXDATA) { - if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) { - len = min_t(unsigned int, len, sizeof(stl_unwanted)); - outb(GRXFIFO, (ioaddr + XP_ADDR)); - insb((ioaddr + XP_DATA), &stl_unwanted[0], len); - portp->stats.rxlost += len; - portp->stats.rxtotal += len; - } else { - len = min(len, buflen); - if (len > 0) { - unsigned char *ptr; - outb(GRXFIFO, (ioaddr + XP_ADDR)); - tty_prepare_flip_string(tty, &ptr, len); - insb((ioaddr + XP_DATA), ptr, len); - tty_schedule_flip(tty); - portp->stats.rxtotal += len; - } - } - } else { - stl_sc26198rxbadchars(portp); - } - -/* - * If we are TX flow controlled and in IXANY mode then we may need - * to unflow control here. We gotta do this because of the automatic - * flow control modes of the sc26198. - */ - if (test_bit(ASYI_TXFLOWED, &portp->istate)) { - if ((tty != NULL) && - (tty->termios != NULL) && - (tty->termios->c_iflag & IXANY)) { - stl_sc26198txunflow(portp, tty); - } - } - tty_kref_put(tty); -} - -/*****************************************************************************/ - -/* - * Process an RX bad character. - */ - -static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char ch) -{ - struct tty_struct *tty; - unsigned int ioaddr; - - tty = tty_port_tty_get(&portp->port); - ioaddr = portp->ioaddr; - - if (status & SR_RXPARITY) - portp->stats.rxparity++; - if (status & SR_RXFRAMING) - portp->stats.rxframing++; - if (status & SR_RXOVERRUN) - portp->stats.rxoverrun++; - if (status & SR_RXBREAK) - portp->stats.rxbreaks++; - - if ((tty != NULL) && - ((portp->rxignoremsk & status) == 0)) { - if (portp->rxmarkmsk & status) { - if (status & SR_RXBREAK) { - status = TTY_BREAK; - if (portp->port.flags & ASYNC_SAK) { - do_SAK(tty); - BRDENABLE(portp->brdnr, portp->pagenr); - } - } else if (status & SR_RXPARITY) - status = TTY_PARITY; - else if (status & SR_RXFRAMING) - status = TTY_FRAME; - else if(status & SR_RXOVERRUN) - status = TTY_OVERRUN; - else - status = 0; - } else - status = 0; - - tty_insert_flip_char(tty, ch, status); - tty_schedule_flip(tty); - - if (status == 0) - portp->stats.rxtotal++; - } - tty_kref_put(tty); -} - -/*****************************************************************************/ - -/* - * Process all characters in the RX FIFO of the UART. Check all char - * status bytes as well, and process as required. We need to check - * all bytes in the FIFO, in case some more enter the FIFO while we - * are here. To get the exact character error type we need to switch - * into CHAR error mode (that is why we need to make sure we empty - * the FIFO). - */ - -static void stl_sc26198rxbadchars(struct stlport *portp) -{ - unsigned char status, mr1; - char ch; - -/* - * To get the precise error type for each character we must switch - * back into CHAR error mode. - */ - mr1 = stl_sc26198getreg(portp, MR1); - stl_sc26198setreg(portp, MR1, (mr1 & ~MR1_ERRBLOCK)); - - while ((status = stl_sc26198getreg(portp, SR)) & SR_RXRDY) { - stl_sc26198setreg(portp, SCCR, CR_CLEARRXERR); - ch = stl_sc26198getreg(portp, RXFIFO); - stl_sc26198rxbadch(portp, status, ch); - } - -/* - * To get correct interrupt class we must switch back into BLOCK - * error mode. - */ - stl_sc26198setreg(portp, MR1, mr1); -} - -/*****************************************************************************/ - -/* - * Other interrupt handler. This includes modem signals, flow - * control actions, etc. Most stuff is left to off-level interrupt - * processing time. - */ - -static void stl_sc26198otherisr(struct stlport *portp, unsigned int iack) -{ - unsigned char cir, ipr, xisr; - - pr_debug("stl_sc26198otherisr(portp=%p,iack=%x)\n", portp, iack); - - cir = stl_sc26198getglobreg(portp, CIR); - - switch (cir & CIR_SUBTYPEMASK) { - case CIR_SUBCOS: - ipr = stl_sc26198getreg(portp, IPR); - if (ipr & IPR_DCDCHANGE) { - stl_cd_change(portp); - portp->stats.modem++; - } - break; - case CIR_SUBXONXOFF: - xisr = stl_sc26198getreg(portp, XISR); - if (xisr & XISR_RXXONGOT) { - set_bit(ASYI_TXFLOWED, &portp->istate); - portp->stats.txxoff++; - } - if (xisr & XISR_RXXOFFGOT) { - clear_bit(ASYI_TXFLOWED, &portp->istate); - portp->stats.txxon++; - } - break; - case CIR_SUBBREAK: - stl_sc26198setreg(portp, SCCR, CR_BREAKRESET); - stl_sc26198rxbadchars(portp); - break; - default: - break; - } -} - -static void stl_free_isabrds(void) -{ - struct stlbrd *brdp; - unsigned int i; - - for (i = 0; i < stl_nrbrds; i++) { - if ((brdp = stl_brds[i]) == NULL || (brdp->state & STL_PROBED)) - continue; - - free_irq(brdp->irq, brdp); - - stl_cleanup_panels(brdp); - - release_region(brdp->ioaddr1, brdp->iosize1); - if (brdp->iosize2 > 0) - release_region(brdp->ioaddr2, brdp->iosize2); - - kfree(brdp); - stl_brds[i] = NULL; - } -} - -/* - * Loadable module initialization stuff. - */ -static int __init stallion_module_init(void) -{ - struct stlbrd *brdp; - struct stlconf conf; - unsigned int i, j; - int retval; - - printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion); - - spin_lock_init(&stallion_lock); - spin_lock_init(&brd_lock); - - stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); - if (!stl_serial) { - retval = -ENOMEM; - goto err; - } - - stl_serial->owner = THIS_MODULE; - stl_serial->driver_name = stl_drvname; - stl_serial->name = "ttyE"; - stl_serial->major = STL_SERIALMAJOR; - stl_serial->minor_start = 0; - stl_serial->type = TTY_DRIVER_TYPE_SERIAL; - stl_serial->subtype = SERIAL_TYPE_NORMAL; - stl_serial->init_termios = stl_deftermios; - stl_serial->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; - tty_set_operations(stl_serial, &stl_ops); - - retval = tty_register_driver(stl_serial); - if (retval) { - printk("STALLION: failed to register serial driver\n"); - goto err_frtty; - } - -/* - * Find any dynamically supported boards. That is via module load - * line options. - */ - for (i = stl_nrbrds; i < stl_nargs; i++) { - memset(&conf, 0, sizeof(conf)); - if (stl_parsebrd(&conf, stl_brdsp[i]) == 0) - continue; - if ((brdp = stl_allocbrd()) == NULL) - continue; - brdp->brdnr = i; - brdp->brdtype = conf.brdtype; - brdp->ioaddr1 = conf.ioaddr1; - brdp->ioaddr2 = conf.ioaddr2; - brdp->irq = conf.irq; - brdp->irqtype = conf.irqtype; - stl_brds[brdp->brdnr] = brdp; - if (stl_brdinit(brdp)) { - stl_brds[brdp->brdnr] = NULL; - kfree(brdp); - } else { - for (j = 0; j < brdp->nrports; j++) - tty_register_device(stl_serial, - brdp->brdnr * STL_MAXPORTS + j, NULL); - stl_nrbrds = i + 1; - } - } - - /* this has to be _after_ isa finding because of locking */ - retval = pci_register_driver(&stl_pcidriver); - if (retval && stl_nrbrds == 0) { - printk(KERN_ERR "STALLION: can't register pci driver\n"); - goto err_unrtty; - } - -/* - * Set up a character driver for per board stuff. This is mainly used - * to do stats ioctls on the ports. - */ - if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem)) - printk("STALLION: failed to register serial board device\n"); - - stallion_class = class_create(THIS_MODULE, "staliomem"); - if (IS_ERR(stallion_class)) - printk("STALLION: failed to create class\n"); - for (i = 0; i < 4; i++) - device_create(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i), - NULL, "staliomem%d", i); - - return 0; -err_unrtty: - tty_unregister_driver(stl_serial); -err_frtty: - put_tty_driver(stl_serial); -err: - return retval; -} - -static void __exit stallion_module_exit(void) -{ - struct stlbrd *brdp; - unsigned int i, j; - - pr_debug("cleanup_module()\n"); - - printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle, - stl_drvversion); - -/* - * Free up all allocated resources used by the ports. This includes - * memory and interrupts. As part of this process we will also do - * a hangup on every open port - to try to flush out any processes - * hanging onto ports. - */ - for (i = 0; i < stl_nrbrds; i++) { - if ((brdp = stl_brds[i]) == NULL || (brdp->state & STL_PROBED)) - continue; - for (j = 0; j < brdp->nrports; j++) - tty_unregister_device(stl_serial, - brdp->brdnr * STL_MAXPORTS + j); - } - - for (i = 0; i < 4; i++) - device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i)); - unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"); - class_destroy(stallion_class); - - pci_unregister_driver(&stl_pcidriver); - - stl_free_isabrds(); - - tty_unregister_driver(stl_serial); - put_tty_driver(stl_serial); -} - -module_init(stallion_module_init); -module_exit(stallion_module_exit); - -MODULE_AUTHOR("Greg Ungerer"); -MODULE_DESCRIPTION("Stallion Multiport Serial Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 5c8fcfc42c3e..fb1fc4e5a8cb 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -41,6 +41,8 @@ config STAGING_EXCLUDE_BUILD if !STAGING_EXCLUDE_BUILD +source "drivers/staging/tty/Kconfig" + source "drivers/staging/et131x/Kconfig" source "drivers/staging/slicoss/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index d53886317826..f498e345a01d 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -3,6 +3,7 @@ # fix for build system bug... obj-$(CONFIG_STAGING) += staging.o +obj-y += tty/ obj-$(CONFIG_ET131X) += et131x/ obj-$(CONFIG_SLICOSS) += slicoss/ obj-$(CONFIG_VIDEO_GO7007) += go7007/ diff --git a/drivers/staging/tty/Kconfig b/drivers/staging/tty/Kconfig new file mode 100644 index 000000000000..77103a07abbd --- /dev/null +++ b/drivers/staging/tty/Kconfig @@ -0,0 +1,87 @@ +config STALLION + tristate "Stallion EasyIO or EC8/32 support" + depends on STALDRV && (ISA || EISA || PCI) + help + If you have an EasyIO or EasyConnection 8/32 multiport Stallion + card, then this is for you; say Y. Make sure to read + . + + To compile this driver as a module, choose M here: the + module will be called stallion. + +config ISTALLION + tristate "Stallion EC8/64, ONboard, Brumby support" + depends on STALDRV && (ISA || EISA || PCI) + help + If you have an EasyConnection 8/64, ONboard, Brumby or Stallion + serial multiport card, say Y here. Make sure to read + . + + To compile this driver as a module, choose M here: the + module will be called istallion. + +config DIGIEPCA + tristate "Digiboard Intelligent Async Support" + depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) + ---help--- + This is a driver for Digi International's Xx, Xeve, and Xem series + of cards which provide multiple serial ports. You would need + something like this to connect more than two modems to your Linux + box, for instance in order to become a dial-in server. This driver + supports the original PC (ISA) boards as well as PCI, and EISA. If + you have a card like this, say Y here and read the file + . + + To compile this driver as a module, choose M here: the + module will be called epca. + +config RISCOM8 + tristate "SDL RISCom/8 card support" + depends on SERIAL_NONSTANDARD + help + This is a driver for the SDL Communications RISCom/8 multiport card, + which gives you many serial ports. You would need something like + this to connect more than two modems to your Linux box, for instance + in order to become a dial-in server. If you have a card like that, + say Y here and read the file . + + Also it's possible to say M here and compile this driver as kernel + loadable module; the module will be called riscom8. + +config SPECIALIX + tristate "Specialix IO8+ card support" + depends on SERIAL_NONSTANDARD + help + This is a driver for the Specialix IO8+ multiport card (both the + ISA and the PCI version) which gives you many serial ports. You + would need something like this to connect more than two modems to + your Linux box, for instance in order to become a dial-in server. + + If you have a card like that, say Y here and read the file + . Also it's possible to say + M here and compile this driver as kernel loadable module which will be + called specialix. + +config COMPUTONE + tristate "Computone IntelliPort Plus serial support" + depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) + ---help--- + This driver supports the entire family of Intelliport II/Plus + controllers with the exception of the MicroChannel controllers and + products previous to the Intelliport II. These are multiport cards, + which give you many serial ports. You would need something like this + to connect more than two modems to your Linux box, for instance in + order to become a dial-in server. If you have a card like that, say + Y here and read . + + To compile this driver as module, choose M here: the + module will be called ip2. + +config SERIAL167 + bool "CD2401 support for MVME166/7 serial ports" + depends on MVME16x + help + This is the driver for the serial ports on the Motorola MVME166, + 167, and 172 boards. Everyone using one of these boards should say + Y here. + diff --git a/drivers/staging/tty/Makefile b/drivers/staging/tty/Makefile new file mode 100644 index 000000000000..ac57c105611b --- /dev/null +++ b/drivers/staging/tty/Makefile @@ -0,0 +1,7 @@ +obj-$(CONFIG_STALLION) += stallion.o +obj-$(CONFIG_ISTALLION) += istallion.o +obj-$(CONFIG_DIGIEPCA) += epca.o +obj-$(CONFIG_SERIAL167) += serial167.o +obj-$(CONFIG_SPECIALIX) += specialix.o +obj-$(CONFIG_RISCOM8) += riscom8.o +obj-$(CONFIG_COMPUTONE) += ip2/ diff --git a/drivers/staging/tty/TODO b/drivers/staging/tty/TODO new file mode 100644 index 000000000000..88756453ac6c --- /dev/null +++ b/drivers/staging/tty/TODO @@ -0,0 +1,6 @@ +These are a few tty/serial drivers that either do not build, +or work if they do build, or if they seem to work, are for obsolete +hardware, or are full of unfixable races and no one uses them anymore. + +If no one steps up to adopt any of these drivers, they will be removed +in the 2.6.41 release. diff --git a/drivers/staging/tty/epca.c b/drivers/staging/tty/epca.c new file mode 100644 index 000000000000..7ad3638967ae --- /dev/null +++ b/drivers/staging/tty/epca.c @@ -0,0 +1,2784 @@ +/* + Copyright (C) 1996 Digi International. + + For technical support please email digiLinux@dgii.com or + call Digi tech support at (612) 912-3456 + + ** This driver is no longer supported by Digi ** + + Much of this design and code came from epca.c which was + copyright (C) 1994, 1995 Troy De Jongh, and subsquently + modified by David Nugent, Christoph Lameter, Mike McLagan. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* See README.epca for change history --DAT*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "digiPCI.h" + + +#include "digi1.h" +#include "digiFep1.h" +#include "epca.h" +#include "epcaconfig.h" + +#define VERSION "1.3.0.1-LK2.6" + +/* This major needs to be submitted to Linux to join the majors list */ +#define DIGIINFOMAJOR 35 /* For Digi specific ioctl */ + + +#define MAXCARDS 7 +#define epcaassert(x, msg) if (!(x)) epca_error(__LINE__, msg) + +#define PFX "epca: " + +static int nbdevs, num_cards, liloconfig; +static int digi_poller_inhibited = 1 ; + +static int setup_error_code; +static int invalid_lilo_config; + +/* + * The ISA boards do window flipping into the same spaces so its only sane with + * a single lock. It's still pretty efficient. This lock guards the hardware + * and the tty_port lock guards the kernel side stuff like use counts. Take + * this lock inside the port lock if you must take both. + */ +static DEFINE_SPINLOCK(epca_lock); + +/* MAXBOARDS is typically 12, but ISA and EISA cards are restricted + to 7 below. */ +static struct board_info boards[MAXBOARDS]; + +static struct tty_driver *pc_driver; +static struct tty_driver *pc_info; + +/* ------------------ Begin Digi specific structures -------------------- */ + +/* + * digi_channels represents an array of structures that keep track of each + * channel of the Digi product. Information such as transmit and receive + * pointers, termio data, and signal definitions (DTR, CTS, etc ...) are stored + * here. This structure is NOT used to overlay the cards physical channel + * structure. + */ +static struct channel digi_channels[MAX_ALLOC]; + +/* + * card_ptr is an array used to hold the address of the first channel structure + * of each card. This array will hold the addresses of various channels located + * in digi_channels. + */ +static struct channel *card_ptr[MAXCARDS]; + +static struct timer_list epca_timer; + +/* + * Begin generic memory functions. These functions will be alias (point at) + * more specific functions dependent on the board being configured. + */ +static void memwinon(struct board_info *b, unsigned int win); +static void memwinoff(struct board_info *b, unsigned int win); +static void globalwinon(struct channel *ch); +static void rxwinon(struct channel *ch); +static void txwinon(struct channel *ch); +static void memoff(struct channel *ch); +static void assertgwinon(struct channel *ch); +static void assertmemoff(struct channel *ch); + +/* ---- Begin more 'specific' memory functions for cx_like products --- */ + +static void pcxem_memwinon(struct board_info *b, unsigned int win); +static void pcxem_memwinoff(struct board_info *b, unsigned int win); +static void pcxem_globalwinon(struct channel *ch); +static void pcxem_rxwinon(struct channel *ch); +static void pcxem_txwinon(struct channel *ch); +static void pcxem_memoff(struct channel *ch); + +/* ------ Begin more 'specific' memory functions for the pcxe ------- */ + +static void pcxe_memwinon(struct board_info *b, unsigned int win); +static void pcxe_memwinoff(struct board_info *b, unsigned int win); +static void pcxe_globalwinon(struct channel *ch); +static void pcxe_rxwinon(struct channel *ch); +static void pcxe_txwinon(struct channel *ch); +static void pcxe_memoff(struct channel *ch); + +/* ---- Begin more 'specific' memory functions for the pc64xe and pcxi ---- */ +/* Note : pc64xe and pcxi share the same windowing routines */ + +static void pcxi_memwinon(struct board_info *b, unsigned int win); +static void pcxi_memwinoff(struct board_info *b, unsigned int win); +static void pcxi_globalwinon(struct channel *ch); +static void pcxi_rxwinon(struct channel *ch); +static void pcxi_txwinon(struct channel *ch); +static void pcxi_memoff(struct channel *ch); + +/* - Begin 'specific' do nothing memory functions needed for some cards - */ + +static void dummy_memwinon(struct board_info *b, unsigned int win); +static void dummy_memwinoff(struct board_info *b, unsigned int win); +static void dummy_globalwinon(struct channel *ch); +static void dummy_rxwinon(struct channel *ch); +static void dummy_txwinon(struct channel *ch); +static void dummy_memoff(struct channel *ch); +static void dummy_assertgwinon(struct channel *ch); +static void dummy_assertmemoff(struct channel *ch); + +static struct channel *verifyChannel(struct tty_struct *); +static void pc_sched_event(struct channel *, int); +static void epca_error(int, char *); +static void pc_close(struct tty_struct *, struct file *); +static void shutdown(struct channel *, struct tty_struct *tty); +static void pc_hangup(struct tty_struct *); +static int pc_write_room(struct tty_struct *); +static int pc_chars_in_buffer(struct tty_struct *); +static void pc_flush_buffer(struct tty_struct *); +static void pc_flush_chars(struct tty_struct *); +static int pc_open(struct tty_struct *, struct file *); +static void post_fep_init(unsigned int crd); +static void epcapoll(unsigned long); +static void doevent(int); +static void fepcmd(struct channel *, int, int, int, int, int); +static unsigned termios2digi_h(struct channel *ch, unsigned); +static unsigned termios2digi_i(struct channel *ch, unsigned); +static unsigned termios2digi_c(struct channel *ch, unsigned); +static void epcaparam(struct tty_struct *, struct channel *); +static void receive_data(struct channel *, struct tty_struct *tty); +static int pc_ioctl(struct tty_struct *, + unsigned int, unsigned long); +static int info_ioctl(struct tty_struct *, + unsigned int, unsigned long); +static void pc_set_termios(struct tty_struct *, struct ktermios *); +static void do_softint(struct work_struct *work); +static void pc_stop(struct tty_struct *); +static void pc_start(struct tty_struct *); +static void pc_throttle(struct tty_struct *tty); +static void pc_unthrottle(struct tty_struct *tty); +static int pc_send_break(struct tty_struct *tty, int msec); +static void setup_empty_event(struct tty_struct *tty, struct channel *ch); + +static int pc_write(struct tty_struct *, const unsigned char *, int); +static int pc_init(void); +static int init_PCI(void); + +/* + * Table of functions for each board to handle memory. Mantaining parallelism + * is a *very* good idea here. The idea is for the runtime code to blindly call + * these functions, not knowing/caring about the underlying hardware. This + * stuff should contain no conditionals; if more functionality is needed a + * different entry should be established. These calls are the interface calls + * and are the only functions that should be accessed. Anyone caught making + * direct calls deserves what they get. + */ +static void memwinon(struct board_info *b, unsigned int win) +{ + b->memwinon(b, win); +} + +static void memwinoff(struct board_info *b, unsigned int win) +{ + b->memwinoff(b, win); +} + +static void globalwinon(struct channel *ch) +{ + ch->board->globalwinon(ch); +} + +static void rxwinon(struct channel *ch) +{ + ch->board->rxwinon(ch); +} + +static void txwinon(struct channel *ch) +{ + ch->board->txwinon(ch); +} + +static void memoff(struct channel *ch) +{ + ch->board->memoff(ch); +} +static void assertgwinon(struct channel *ch) +{ + ch->board->assertgwinon(ch); +} + +static void assertmemoff(struct channel *ch) +{ + ch->board->assertmemoff(ch); +} + +/* PCXEM windowing is the same as that used in the PCXR and CX series cards. */ +static void pcxem_memwinon(struct board_info *b, unsigned int win) +{ + outb_p(FEPWIN | win, b->port + 1); +} + +static void pcxem_memwinoff(struct board_info *b, unsigned int win) +{ + outb_p(0, b->port + 1); +} + +static void pcxem_globalwinon(struct channel *ch) +{ + outb_p(FEPWIN, (int)ch->board->port + 1); +} + +static void pcxem_rxwinon(struct channel *ch) +{ + outb_p(ch->rxwin, (int)ch->board->port + 1); +} + +static void pcxem_txwinon(struct channel *ch) +{ + outb_p(ch->txwin, (int)ch->board->port + 1); +} + +static void pcxem_memoff(struct channel *ch) +{ + outb_p(0, (int)ch->board->port + 1); +} + +/* ----------------- Begin pcxe memory window stuff ------------------ */ +static void pcxe_memwinon(struct board_info *b, unsigned int win) +{ + outb_p(FEPWIN | win, b->port + 1); +} + +static void pcxe_memwinoff(struct board_info *b, unsigned int win) +{ + outb_p(inb(b->port) & ~FEPMEM, b->port + 1); + outb_p(0, b->port + 1); +} + +static void pcxe_globalwinon(struct channel *ch) +{ + outb_p(FEPWIN, (int)ch->board->port + 1); +} + +static void pcxe_rxwinon(struct channel *ch) +{ + outb_p(ch->rxwin, (int)ch->board->port + 1); +} + +static void pcxe_txwinon(struct channel *ch) +{ + outb_p(ch->txwin, (int)ch->board->port + 1); +} + +static void pcxe_memoff(struct channel *ch) +{ + outb_p(0, (int)ch->board->port); + outb_p(0, (int)ch->board->port + 1); +} + +/* ------------- Begin pc64xe and pcxi memory window stuff -------------- */ +static void pcxi_memwinon(struct board_info *b, unsigned int win) +{ + outb_p(inb(b->port) | FEPMEM, b->port); +} + +static void pcxi_memwinoff(struct board_info *b, unsigned int win) +{ + outb_p(inb(b->port) & ~FEPMEM, b->port); +} + +static void pcxi_globalwinon(struct channel *ch) +{ + outb_p(FEPMEM, ch->board->port); +} + +static void pcxi_rxwinon(struct channel *ch) +{ + outb_p(FEPMEM, ch->board->port); +} + +static void pcxi_txwinon(struct channel *ch) +{ + outb_p(FEPMEM, ch->board->port); +} + +static void pcxi_memoff(struct channel *ch) +{ + outb_p(0, ch->board->port); +} + +static void pcxi_assertgwinon(struct channel *ch) +{ + epcaassert(inb(ch->board->port) & FEPMEM, "Global memory off"); +} + +static void pcxi_assertmemoff(struct channel *ch) +{ + epcaassert(!(inb(ch->board->port) & FEPMEM), "Memory on"); +} + +/* + * Not all of the cards need specific memory windowing routines. Some cards + * (Such as PCI) needs no windowing routines at all. We provide these do + * nothing routines so that the same code base can be used. The driver will + * ALWAYS call a windowing routine if it thinks it needs to; regardless of the + * card. However, dependent on the card the routine may or may not do anything. + */ +static void dummy_memwinon(struct board_info *b, unsigned int win) +{ +} + +static void dummy_memwinoff(struct board_info *b, unsigned int win) +{ +} + +static void dummy_globalwinon(struct channel *ch) +{ +} + +static void dummy_rxwinon(struct channel *ch) +{ +} + +static void dummy_txwinon(struct channel *ch) +{ +} + +static void dummy_memoff(struct channel *ch) +{ +} + +static void dummy_assertgwinon(struct channel *ch) +{ +} + +static void dummy_assertmemoff(struct channel *ch) +{ +} + +static struct channel *verifyChannel(struct tty_struct *tty) +{ + /* + * This routine basically provides a sanity check. It insures that the + * channel returned is within the proper range of addresses as well as + * properly initialized. If some bogus info gets passed in + * through tty->driver_data this should catch it. + */ + if (tty) { + struct channel *ch = tty->driver_data; + if (ch >= &digi_channels[0] && ch < &digi_channels[nbdevs]) { + if (ch->magic == EPCA_MAGIC) + return ch; + } + } + return NULL; +} + +static void pc_sched_event(struct channel *ch, int event) +{ + /* + * We call this to schedule interrupt processing on some event. The + * kernel sees our request and calls the related routine in OUR driver. + */ + ch->event |= 1 << event; + schedule_work(&ch->tqueue); +} + +static void epca_error(int line, char *msg) +{ + printk(KERN_ERR "epca_error (Digi): line = %d %s\n", line, msg); +} + +static void pc_close(struct tty_struct *tty, struct file *filp) +{ + struct channel *ch; + struct tty_port *port; + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ + ch = verifyChannel(tty); + if (ch == NULL) + return; + port = &ch->port; + + if (tty_port_close_start(port, tty, filp) == 0) + return; + + pc_flush_buffer(tty); + shutdown(ch, tty); + + tty_port_close_end(port, tty); + ch->event = 0; /* FIXME: review ch->event locking */ + tty_port_tty_set(port, NULL); +} + +static void shutdown(struct channel *ch, struct tty_struct *tty) +{ + unsigned long flags; + struct board_chan __iomem *bc; + struct tty_port *port = &ch->port; + + if (!(port->flags & ASYNC_INITIALIZED)) + return; + + spin_lock_irqsave(&epca_lock, flags); + + globalwinon(ch); + bc = ch->brdchan; + + /* + * In order for an event to be generated on the receipt of data the + * idata flag must be set. Since we are shutting down, this is not + * necessary clear this flag. + */ + if (bc) + writeb(0, &bc->idata); + + /* If we're a modem control device and HUPCL is on, drop RTS & DTR. */ + if (tty->termios->c_cflag & HUPCL) { + ch->omodem &= ~(ch->m_rts | ch->m_dtr); + fepcmd(ch, SETMODEM, 0, ch->m_dtr | ch->m_rts, 10, 1); + } + memoff(ch); + + /* + * The channel has officialy been closed. The next time it is opened it + * will have to reinitialized. Set a flag to indicate this. + */ + /* Prevent future Digi programmed interrupts from coming active */ + port->flags &= ~ASYNC_INITIALIZED; + spin_unlock_irqrestore(&epca_lock, flags); +} + +static void pc_hangup(struct tty_struct *tty) +{ + struct channel *ch; + + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ + ch = verifyChannel(tty); + if (ch != NULL) { + pc_flush_buffer(tty); + tty_ldisc_flush(tty); + shutdown(ch, tty); + + ch->event = 0; /* FIXME: review locking of ch->event */ + tty_port_hangup(&ch->port); + } +} + +static int pc_write(struct tty_struct *tty, + const unsigned char *buf, int bytesAvailable) +{ + unsigned int head, tail; + int dataLen; + int size; + int amountCopied; + struct channel *ch; + unsigned long flags; + int remain; + struct board_chan __iomem *bc; + + /* + * pc_write is primarily called directly by the kernel routine + * tty_write (Though it can also be called by put_char) found in + * tty_io.c. pc_write is passed a line discipline buffer where the data + * to be written out is stored. The line discipline implementation + * itself is done at the kernel level and is not brought into the + * driver. + */ + + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ + ch = verifyChannel(tty); + if (ch == NULL) + return 0; + + /* Make a pointer to the channel data structure found on the board. */ + bc = ch->brdchan; + size = ch->txbufsize; + amountCopied = 0; + + spin_lock_irqsave(&epca_lock, flags); + globalwinon(ch); + + head = readw(&bc->tin) & (size - 1); + tail = readw(&bc->tout); + + if (tail != readw(&bc->tout)) + tail = readw(&bc->tout); + tail &= (size - 1); + + if (head >= tail) { + /* head has not wrapped */ + /* + * remain (much like dataLen above) represents the total amount + * of space available on the card for data. Here dataLen + * represents the space existing between the head pointer and + * the end of buffer. This is important because a memcpy cannot + * be told to automatically wrap around when it hits the buffer + * end. + */ + dataLen = size - head; + remain = size - (head - tail) - 1; + } else { + /* head has wrapped around */ + remain = tail - head - 1; + dataLen = remain; + } + /* + * Check the space on the card. If we have more data than space; reduce + * the amount of data to fit the space. + */ + bytesAvailable = min(remain, bytesAvailable); + txwinon(ch); + while (bytesAvailable > 0) { + /* there is data to copy onto card */ + + /* + * If head is not wrapped, the below will make sure the first + * data copy fills to the end of card buffer. + */ + dataLen = min(bytesAvailable, dataLen); + memcpy_toio(ch->txptr + head, buf, dataLen); + buf += dataLen; + head += dataLen; + amountCopied += dataLen; + bytesAvailable -= dataLen; + + if (head >= size) { + head = 0; + dataLen = tail; + } + } + ch->statusflags |= TXBUSY; + globalwinon(ch); + writew(head, &bc->tin); + + if ((ch->statusflags & LOWWAIT) == 0) { + ch->statusflags |= LOWWAIT; + writeb(1, &bc->ilow); + } + memoff(ch); + spin_unlock_irqrestore(&epca_lock, flags); + return amountCopied; +} + +static int pc_write_room(struct tty_struct *tty) +{ + int remain = 0; + struct channel *ch; + unsigned long flags; + unsigned int head, tail; + struct board_chan __iomem *bc; + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ + ch = verifyChannel(tty); + if (ch != NULL) { + spin_lock_irqsave(&epca_lock, flags); + globalwinon(ch); + + bc = ch->brdchan; + head = readw(&bc->tin) & (ch->txbufsize - 1); + tail = readw(&bc->tout); + + if (tail != readw(&bc->tout)) + tail = readw(&bc->tout); + /* Wrap tail if necessary */ + tail &= (ch->txbufsize - 1); + remain = tail - head - 1; + if (remain < 0) + remain += ch->txbufsize; + + if (remain && (ch->statusflags & LOWWAIT) == 0) { + ch->statusflags |= LOWWAIT; + writeb(1, &bc->ilow); + } + memoff(ch); + spin_unlock_irqrestore(&epca_lock, flags); + } + /* Return how much room is left on card */ + return remain; +} + +static int pc_chars_in_buffer(struct tty_struct *tty) +{ + int chars; + unsigned int ctail, head, tail; + int remain; + unsigned long flags; + struct channel *ch; + struct board_chan __iomem *bc; + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ + ch = verifyChannel(tty); + if (ch == NULL) + return 0; + + spin_lock_irqsave(&epca_lock, flags); + globalwinon(ch); + + bc = ch->brdchan; + tail = readw(&bc->tout); + head = readw(&bc->tin); + ctail = readw(&ch->mailbox->cout); + + if (tail == head && readw(&ch->mailbox->cin) == ctail && + readb(&bc->tbusy) == 0) + chars = 0; + else { /* Begin if some space on the card has been used */ + head = readw(&bc->tin) & (ch->txbufsize - 1); + tail &= (ch->txbufsize - 1); + /* + * The logic here is basically opposite of the above + * pc_write_room here we are finding the amount of bytes in the + * buffer filled. Not the amount of bytes empty. + */ + remain = tail - head - 1; + if (remain < 0) + remain += ch->txbufsize; + chars = (int)(ch->txbufsize - remain); + /* + * Make it possible to wakeup anything waiting for output in + * tty_ioctl.c, etc. + * + * If not already set. Setup an event to indicate when the + * transmit buffer empties. + */ + if (!(ch->statusflags & EMPTYWAIT)) + setup_empty_event(tty, ch); + } /* End if some space on the card has been used */ + memoff(ch); + spin_unlock_irqrestore(&epca_lock, flags); + /* Return number of characters residing on card. */ + return chars; +} + +static void pc_flush_buffer(struct tty_struct *tty) +{ + unsigned int tail; + unsigned long flags; + struct channel *ch; + struct board_chan __iomem *bc; + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ + ch = verifyChannel(tty); + if (ch == NULL) + return; + + spin_lock_irqsave(&epca_lock, flags); + globalwinon(ch); + bc = ch->brdchan; + tail = readw(&bc->tout); + /* Have FEP move tout pointer; effectively flushing transmit buffer */ + fepcmd(ch, STOUT, (unsigned) tail, 0, 0, 0); + memoff(ch); + spin_unlock_irqrestore(&epca_lock, flags); + tty_wakeup(tty); +} + +static void pc_flush_chars(struct tty_struct *tty) +{ + struct channel *ch; + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ + ch = verifyChannel(tty); + if (ch != NULL) { + unsigned long flags; + spin_lock_irqsave(&epca_lock, flags); + /* + * If not already set and the transmitter is busy setup an + * event to indicate when the transmit empties. + */ + if ((ch->statusflags & TXBUSY) && + !(ch->statusflags & EMPTYWAIT)) + setup_empty_event(tty, ch); + spin_unlock_irqrestore(&epca_lock, flags); + } +} + +static int epca_carrier_raised(struct tty_port *port) +{ + struct channel *ch = container_of(port, struct channel, port); + if (ch->imodem & ch->dcd) + return 1; + return 0; +} + +static void epca_dtr_rts(struct tty_port *port, int onoff) +{ +} + +static int pc_open(struct tty_struct *tty, struct file *filp) +{ + struct channel *ch; + struct tty_port *port; + unsigned long flags; + int line, retval, boardnum; + struct board_chan __iomem *bc; + unsigned int head; + + line = tty->index; + if (line < 0 || line >= nbdevs) + return -ENODEV; + + ch = &digi_channels[line]; + port = &ch->port; + boardnum = ch->boardnum; + + /* Check status of board configured in system. */ + + /* + * I check to see if the epca_setup routine detected a user error. It + * might be better to put this in pc_init, but for the moment it goes + * here. + */ + if (invalid_lilo_config) { + if (setup_error_code & INVALID_BOARD_TYPE) + printk(KERN_ERR "epca: pc_open: Invalid board type specified in kernel options.\n"); + if (setup_error_code & INVALID_NUM_PORTS) + printk(KERN_ERR "epca: pc_open: Invalid number of ports specified in kernel options.\n"); + if (setup_error_code & INVALID_MEM_BASE) + printk(KERN_ERR "epca: pc_open: Invalid board memory address specified in kernel options.\n"); + if (setup_error_code & INVALID_PORT_BASE) + printk(KERN_ERR "epca; pc_open: Invalid board port address specified in kernel options.\n"); + if (setup_error_code & INVALID_BOARD_STATUS) + printk(KERN_ERR "epca: pc_open: Invalid board status specified in kernel options.\n"); + if (setup_error_code & INVALID_ALTPIN) + printk(KERN_ERR "epca: pc_open: Invalid board altpin specified in kernel options;\n"); + tty->driver_data = NULL; /* Mark this device as 'down' */ + return -ENODEV; + } + if (boardnum >= num_cards || boards[boardnum].status == DISABLED) { + tty->driver_data = NULL; /* Mark this device as 'down' */ + return(-ENODEV); + } + + bc = ch->brdchan; + if (bc == NULL) { + tty->driver_data = NULL; + return -ENODEV; + } + + spin_lock_irqsave(&port->lock, flags); + /* + * Every time a channel is opened, increment a counter. This is + * necessary because we do not wish to flush and shutdown the channel + * until the last app holding the channel open, closes it. + */ + port->count++; + /* + * Set a kernel structures pointer to our local channel structure. This + * way we can get to it when passed only a tty struct. + */ + tty->driver_data = ch; + port->tty = tty; + /* + * If this is the first time the channel has been opened, initialize + * the tty->termios struct otherwise let pc_close handle it. + */ + spin_lock(&epca_lock); + globalwinon(ch); + ch->statusflags = 0; + + /* Save boards current modem status */ + ch->imodem = readb(&bc->mstat); + + /* + * Set receive head and tail ptrs to each other. This indicates no data + * available to read. + */ + head = readw(&bc->rin); + writew(head, &bc->rout); + + /* Set the channels associated tty structure */ + + /* + * The below routine generally sets up parity, baud, flow control + * issues, etc.... It effect both control flags and input flags. + */ + epcaparam(tty, ch); + memoff(ch); + spin_unlock(&epca_lock); + port->flags |= ASYNC_INITIALIZED; + spin_unlock_irqrestore(&port->lock, flags); + + retval = tty_port_block_til_ready(port, tty, filp); + if (retval) + return retval; + /* + * Set this again in case a hangup set it to zero while this open() was + * waiting for the line... + */ + spin_lock_irqsave(&port->lock, flags); + port->tty = tty; + spin_lock(&epca_lock); + globalwinon(ch); + /* Enable Digi Data events */ + writeb(1, &bc->idata); + memoff(ch); + spin_unlock(&epca_lock); + spin_unlock_irqrestore(&port->lock, flags); + return 0; +} + +static int __init epca_module_init(void) +{ + return pc_init(); +} +module_init(epca_module_init); + +static struct pci_driver epca_driver; + +static void __exit epca_module_exit(void) +{ + int count, crd; + struct board_info *bd; + struct channel *ch; + + del_timer_sync(&epca_timer); + + if (tty_unregister_driver(pc_driver) || + tty_unregister_driver(pc_info)) { + printk(KERN_WARNING "epca: cleanup_module failed to un-register tty driver\n"); + return; + } + put_tty_driver(pc_driver); + put_tty_driver(pc_info); + + for (crd = 0; crd < num_cards; crd++) { + bd = &boards[crd]; + if (!bd) { /* sanity check */ + printk(KERN_ERR " - Digi : cleanup_module failed\n"); + return; + } + ch = card_ptr[crd]; + for (count = 0; count < bd->numports; count++, ch++) { + struct tty_struct *tty = tty_port_tty_get(&ch->port); + if (tty) { + tty_hangup(tty); + tty_kref_put(tty); + } + } + } + pci_unregister_driver(&epca_driver); +} +module_exit(epca_module_exit); + +static const struct tty_operations pc_ops = { + .open = pc_open, + .close = pc_close, + .write = pc_write, + .write_room = pc_write_room, + .flush_buffer = pc_flush_buffer, + .chars_in_buffer = pc_chars_in_buffer, + .flush_chars = pc_flush_chars, + .ioctl = pc_ioctl, + .set_termios = pc_set_termios, + .stop = pc_stop, + .start = pc_start, + .throttle = pc_throttle, + .unthrottle = pc_unthrottle, + .hangup = pc_hangup, + .break_ctl = pc_send_break +}; + +static const struct tty_port_operations epca_port_ops = { + .carrier_raised = epca_carrier_raised, + .dtr_rts = epca_dtr_rts, +}; + +static int info_open(struct tty_struct *tty, struct file *filp) +{ + return 0; +} + +static const struct tty_operations info_ops = { + .open = info_open, + .ioctl = info_ioctl, +}; + +static int __init pc_init(void) +{ + int crd; + struct board_info *bd; + unsigned char board_id = 0; + int err = -ENOMEM; + + int pci_boards_found, pci_count; + + pci_count = 0; + + pc_driver = alloc_tty_driver(MAX_ALLOC); + if (!pc_driver) + goto out1; + + pc_info = alloc_tty_driver(MAX_ALLOC); + if (!pc_info) + goto out2; + + /* + * If epca_setup has not been ran by LILO set num_cards to defaults; + * copy board structure defined by digiConfig into drivers board + * structure. Note : If LILO has ran epca_setup then epca_setup will + * handle defining num_cards as well as copying the data into the board + * structure. + */ + if (!liloconfig) { + /* driver has been configured via. epcaconfig */ + nbdevs = NBDEVS; + num_cards = NUMCARDS; + memcpy(&boards, &static_boards, + sizeof(struct board_info) * NUMCARDS); + } + + /* + * Note : If lilo was used to configure the driver and the ignore + * epcaconfig option was choosen (digiepca=2) then nbdevs and num_cards + * will equal 0 at this point. This is okay; PCI cards will still be + * picked up if detected. + */ + + /* + * Set up interrupt, we will worry about memory allocation in + * post_fep_init. + */ + printk(KERN_INFO "DIGI epca driver version %s loaded.\n", VERSION); + + /* + * NOTE : This code assumes that the number of ports found in the + * boards array is correct. This could be wrong if the card in question + * is PCI (And therefore has no ports entry in the boards structure.) + * The rest of the information will be valid for PCI because the + * beginning of pc_init scans for PCI and determines i/o and base + * memory addresses. I am not sure if it is possible to read the number + * of ports supported by the card prior to it being booted (Since that + * is the state it is in when pc_init is run). Because it is not + * possible to query the number of supported ports until after the card + * has booted; we are required to calculate the card_ptrs as the card + * is initialized (Inside post_fep_init). The negative thing about this + * approach is that digiDload's call to GET_INFO will have a bad port + * value. (Since this is called prior to post_fep_init.) + */ + pci_boards_found = 0; + if (num_cards < MAXBOARDS) + pci_boards_found += init_PCI(); + num_cards += pci_boards_found; + + pc_driver->owner = THIS_MODULE; + pc_driver->name = "ttyD"; + pc_driver->major = DIGI_MAJOR; + pc_driver->minor_start = 0; + pc_driver->type = TTY_DRIVER_TYPE_SERIAL; + pc_driver->subtype = SERIAL_TYPE_NORMAL; + pc_driver->init_termios = tty_std_termios; + pc_driver->init_termios.c_iflag = 0; + pc_driver->init_termios.c_oflag = 0; + pc_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; + pc_driver->init_termios.c_lflag = 0; + pc_driver->init_termios.c_ispeed = 9600; + pc_driver->init_termios.c_ospeed = 9600; + pc_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_HARDWARE_BREAK; + tty_set_operations(pc_driver, &pc_ops); + + pc_info->owner = THIS_MODULE; + pc_info->name = "digi_ctl"; + pc_info->major = DIGIINFOMAJOR; + pc_info->minor_start = 0; + pc_info->type = TTY_DRIVER_TYPE_SERIAL; + pc_info->subtype = SERIAL_TYPE_INFO; + pc_info->init_termios = tty_std_termios; + pc_info->init_termios.c_iflag = 0; + pc_info->init_termios.c_oflag = 0; + pc_info->init_termios.c_lflag = 0; + pc_info->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL; + pc_info->init_termios.c_ispeed = 9600; + pc_info->init_termios.c_ospeed = 9600; + pc_info->flags = TTY_DRIVER_REAL_RAW; + tty_set_operations(pc_info, &info_ops); + + + for (crd = 0; crd < num_cards; crd++) { + /* + * This is where the appropriate memory handlers for the + * hardware is set. Everything at runtime blindly jumps through + * these vectors. + */ + + /* defined in epcaconfig.h */ + bd = &boards[crd]; + + switch (bd->type) { + case PCXEM: + case EISAXEM: + bd->memwinon = pcxem_memwinon; + bd->memwinoff = pcxem_memwinoff; + bd->globalwinon = pcxem_globalwinon; + bd->txwinon = pcxem_txwinon; + bd->rxwinon = pcxem_rxwinon; + bd->memoff = pcxem_memoff; + bd->assertgwinon = dummy_assertgwinon; + bd->assertmemoff = dummy_assertmemoff; + break; + + case PCIXEM: + case PCIXRJ: + case PCIXR: + bd->memwinon = dummy_memwinon; + bd->memwinoff = dummy_memwinoff; + bd->globalwinon = dummy_globalwinon; + bd->txwinon = dummy_txwinon; + bd->rxwinon = dummy_rxwinon; + bd->memoff = dummy_memoff; + bd->assertgwinon = dummy_assertgwinon; + bd->assertmemoff = dummy_assertmemoff; + break; + + case PCXE: + case PCXEVE: + bd->memwinon = pcxe_memwinon; + bd->memwinoff = pcxe_memwinoff; + bd->globalwinon = pcxe_globalwinon; + bd->txwinon = pcxe_txwinon; + bd->rxwinon = pcxe_rxwinon; + bd->memoff = pcxe_memoff; + bd->assertgwinon = dummy_assertgwinon; + bd->assertmemoff = dummy_assertmemoff; + break; + + case PCXI: + case PC64XE: + bd->memwinon = pcxi_memwinon; + bd->memwinoff = pcxi_memwinoff; + bd->globalwinon = pcxi_globalwinon; + bd->txwinon = pcxi_txwinon; + bd->rxwinon = pcxi_rxwinon; + bd->memoff = pcxi_memoff; + bd->assertgwinon = pcxi_assertgwinon; + bd->assertmemoff = pcxi_assertmemoff; + break; + + default: + break; + } + + /* + * Some cards need a memory segment to be defined for use in + * transmit and receive windowing operations. These boards are + * listed in the below switch. In the case of the XI the amount + * of memory on the board is variable so the memory_seg is also + * variable. This code determines what they segment should be. + */ + switch (bd->type) { + case PCXE: + case PCXEVE: + case PC64XE: + bd->memory_seg = 0xf000; + break; + + case PCXI: + board_id = inb((int)bd->port); + if ((board_id & 0x1) == 0x1) { + /* it's an XI card */ + /* Is it a 64K board */ + if ((board_id & 0x30) == 0) + bd->memory_seg = 0xf000; + + /* Is it a 128K board */ + if ((board_id & 0x30) == 0x10) + bd->memory_seg = 0xe000; + + /* Is is a 256K board */ + if ((board_id & 0x30) == 0x20) + bd->memory_seg = 0xc000; + + /* Is it a 512K board */ + if ((board_id & 0x30) == 0x30) + bd->memory_seg = 0x8000; + } else + printk(KERN_ERR "epca: Board at 0x%x doesn't appear to be an XI\n", (int)bd->port); + break; + } + } + + err = tty_register_driver(pc_driver); + if (err) { + printk(KERN_ERR "Couldn't register Digi PC/ driver"); + goto out3; + } + + err = tty_register_driver(pc_info); + if (err) { + printk(KERN_ERR "Couldn't register Digi PC/ info "); + goto out4; + } + + /* Start up the poller to check for events on all enabled boards */ + init_timer(&epca_timer); + epca_timer.function = epcapoll; + mod_timer(&epca_timer, jiffies + HZ/25); + return 0; + +out4: + tty_unregister_driver(pc_driver); +out3: + put_tty_driver(pc_info); +out2: + put_tty_driver(pc_driver); +out1: + return err; +} + +static void post_fep_init(unsigned int crd) +{ + int i; + void __iomem *memaddr; + struct global_data __iomem *gd; + struct board_info *bd; + struct board_chan __iomem *bc; + struct channel *ch; + int shrinkmem = 0, lowwater; + + /* + * This call is made by the user via. the ioctl call DIGI_INIT. It is + * responsible for setting up all the card specific stuff. + */ + bd = &boards[crd]; + + /* + * If this is a PCI board, get the port info. Remember PCI cards do not + * have entries into the epcaconfig.h file, so we can't get the number + * of ports from it. Unfortunetly, this means that anyone doing a + * DIGI_GETINFO before the board has booted will get an invalid number + * of ports returned (It should return 0). Calls to DIGI_GETINFO after + * DIGI_INIT has been called will return the proper values. + */ + if (bd->type >= PCIXEM) { /* Begin get PCI number of ports */ + /* + * Below we use XEMPORTS as a memory offset regardless of which + * PCI card it is. This is because all of the supported PCI + * cards have the same memory offset for the channel data. This + * will have to be changed if we ever develop a PCI/XE card. + * NOTE : The FEP manual states that the port offset is 0xC22 + * as opposed to 0xC02. This is only true for PC/XE, and PC/XI + * cards; not for the XEM, or CX series. On the PCI cards the + * number of ports is determined by reading a ID PROM located + * in the box attached to the card. The card can then determine + * the index the id to determine the number of ports available. + * (FYI - The id should be located at 0x1ac (And may use up to + * 4 bytes if the box in question is a XEM or CX)). + */ + /* PCI cards are already remapped at this point ISA are not */ + bd->numports = readw(bd->re_map_membase + XEMPORTS); + epcaassert(bd->numports <= 64, "PCI returned a invalid number of ports"); + nbdevs += (bd->numports); + } else { + /* Fix up the mappings for ISA/EISA etc */ + /* FIXME: 64K - can we be smarter ? */ + bd->re_map_membase = ioremap_nocache(bd->membase, 0x10000); + } + + if (crd != 0) + card_ptr[crd] = card_ptr[crd-1] + boards[crd-1].numports; + else + card_ptr[crd] = &digi_channels[crd]; /* <- For card 0 only */ + + ch = card_ptr[crd]; + epcaassert(ch <= &digi_channels[nbdevs - 1], "ch out of range"); + + memaddr = bd->re_map_membase; + + /* + * The below assignment will set bc to point at the BEGINING of the + * cards channel structures. For 1 card there will be between 8 and 64 + * of these structures. + */ + bc = memaddr + CHANSTRUCT; + + /* + * The below assignment will set gd to point at the BEGINING of global + * memory address 0xc00. The first data in that global memory actually + * starts at address 0xc1a. The command in pointer begins at 0xd10. + */ + gd = memaddr + GLOBAL; + + /* + * XEPORTS (address 0xc22) points at the number of channels the card + * supports. (For 64XE, XI, XEM, and XR use 0xc02) + */ + if ((bd->type == PCXEVE || bd->type == PCXE) && + (readw(memaddr + XEPORTS) < 3)) + shrinkmem = 1; + if (bd->type < PCIXEM) + if (!request_region((int)bd->port, 4, board_desc[bd->type])) + return; + memwinon(bd, 0); + + /* + * Remember ch is the main drivers channels structure, while bc is the + * cards channel structure. + */ + for (i = 0; i < bd->numports; i++, ch++, bc++) { + unsigned long flags; + u16 tseg, rseg; + + tty_port_init(&ch->port); + ch->port.ops = &epca_port_ops; + ch->brdchan = bc; + ch->mailbox = gd; + INIT_WORK(&ch->tqueue, do_softint); + ch->board = &boards[crd]; + + spin_lock_irqsave(&epca_lock, flags); + switch (bd->type) { + /* + * Since some of the boards use different bitmaps for + * their control signals we cannot hard code these + * values and retain portability. We virtualize this + * data here. + */ + case EISAXEM: + case PCXEM: + case PCIXEM: + case PCIXRJ: + case PCIXR: + ch->m_rts = 0x02; + ch->m_dcd = 0x80; + ch->m_dsr = 0x20; + ch->m_cts = 0x10; + ch->m_ri = 0x40; + ch->m_dtr = 0x01; + break; + + case PCXE: + case PCXEVE: + case PCXI: + case PC64XE: + ch->m_rts = 0x02; + ch->m_dcd = 0x08; + ch->m_dsr = 0x10; + ch->m_cts = 0x20; + ch->m_ri = 0x40; + ch->m_dtr = 0x80; + break; + } + + if (boards[crd].altpin) { + ch->dsr = ch->m_dcd; + ch->dcd = ch->m_dsr; + ch->digiext.digi_flags |= DIGI_ALTPIN; + } else { + ch->dcd = ch->m_dcd; + ch->dsr = ch->m_dsr; + } + + ch->boardnum = crd; + ch->channelnum = i; + ch->magic = EPCA_MAGIC; + tty_port_tty_set(&ch->port, NULL); + + if (shrinkmem) { + fepcmd(ch, SETBUFFER, 32, 0, 0, 0); + shrinkmem = 0; + } + + tseg = readw(&bc->tseg); + rseg = readw(&bc->rseg); + + switch (bd->type) { + case PCIXEM: + case PCIXRJ: + case PCIXR: + /* Cover all the 2MEG cards */ + ch->txptr = memaddr + ((tseg << 4) & 0x1fffff); + ch->rxptr = memaddr + ((rseg << 4) & 0x1fffff); + ch->txwin = FEPWIN | (tseg >> 11); + ch->rxwin = FEPWIN | (rseg >> 11); + break; + + case PCXEM: + case EISAXEM: + /* Cover all the 32K windowed cards */ + /* Mask equal to window size - 1 */ + ch->txptr = memaddr + ((tseg << 4) & 0x7fff); + ch->rxptr = memaddr + ((rseg << 4) & 0x7fff); + ch->txwin = FEPWIN | (tseg >> 11); + ch->rxwin = FEPWIN | (rseg >> 11); + break; + + case PCXEVE: + case PCXE: + ch->txptr = memaddr + (((tseg - bd->memory_seg) << 4) + & 0x1fff); + ch->txwin = FEPWIN | ((tseg - bd->memory_seg) >> 9); + ch->rxptr = memaddr + (((rseg - bd->memory_seg) << 4) + & 0x1fff); + ch->rxwin = FEPWIN | ((rseg - bd->memory_seg) >> 9); + break; + + case PCXI: + case PC64XE: + ch->txptr = memaddr + ((tseg - bd->memory_seg) << 4); + ch->rxptr = memaddr + ((rseg - bd->memory_seg) << 4); + ch->txwin = ch->rxwin = 0; + break; + } + + ch->txbufhead = 0; + ch->txbufsize = readw(&bc->tmax) + 1; + + ch->rxbufhead = 0; + ch->rxbufsize = readw(&bc->rmax) + 1; + + lowwater = ch->txbufsize >= 2000 ? 1024 : (ch->txbufsize / 2); + + /* Set transmitter low water mark */ + fepcmd(ch, STXLWATER, lowwater, 0, 10, 0); + + /* Set receiver low water mark */ + fepcmd(ch, SRXLWATER, (ch->rxbufsize / 4), 0, 10, 0); + + /* Set receiver high water mark */ + fepcmd(ch, SRXHWATER, (3 * ch->rxbufsize / 4), 0, 10, 0); + + writew(100, &bc->edelay); + writeb(1, &bc->idata); + + ch->startc = readb(&bc->startc); + ch->stopc = readb(&bc->stopc); + ch->startca = readb(&bc->startca); + ch->stopca = readb(&bc->stopca); + + ch->fepcflag = 0; + ch->fepiflag = 0; + ch->fepoflag = 0; + ch->fepstartc = 0; + ch->fepstopc = 0; + ch->fepstartca = 0; + ch->fepstopca = 0; + + ch->port.close_delay = 50; + + spin_unlock_irqrestore(&epca_lock, flags); + } + + printk(KERN_INFO + "Digi PC/Xx Driver V%s: %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n", + VERSION, board_desc[bd->type], (long)bd->port, + (long)bd->membase, bd->numports); + memwinoff(bd, 0); +} + +static void epcapoll(unsigned long ignored) +{ + unsigned long flags; + int crd; + unsigned int head, tail; + struct channel *ch; + struct board_info *bd; + + /* + * This routine is called upon every timer interrupt. Even though the + * Digi series cards are capable of generating interrupts this method + * of non-looping polling is more efficient. This routine checks for + * card generated events (Such as receive data, are transmit buffer + * empty) and acts on those events. + */ + for (crd = 0; crd < num_cards; crd++) { + bd = &boards[crd]; + ch = card_ptr[crd]; + + if ((bd->status == DISABLED) || digi_poller_inhibited) + continue; + + /* + * assertmemoff is not needed here; indeed it is an empty + * subroutine. It is being kept because future boards may need + * this as well as some legacy boards. + */ + spin_lock_irqsave(&epca_lock, flags); + + assertmemoff(ch); + + globalwinon(ch); + + /* + * In this case head and tail actually refer to the event queue + * not the transmit or receive queue. + */ + head = readw(&ch->mailbox->ein); + tail = readw(&ch->mailbox->eout); + + /* If head isn't equal to tail we have an event */ + if (head != tail) + doevent(crd); + memoff(ch); + + spin_unlock_irqrestore(&epca_lock, flags); + } /* End for each card */ + mod_timer(&epca_timer, jiffies + (HZ / 25)); +} + +static void doevent(int crd) +{ + void __iomem *eventbuf; + struct channel *ch, *chan0; + static struct tty_struct *tty; + struct board_info *bd; + struct board_chan __iomem *bc; + unsigned int tail, head; + int event, channel; + int mstat, lstat; + + /* + * This subroutine is called by epcapoll when an event is detected + * in the event queue. This routine responds to those events. + */ + bd = &boards[crd]; + + chan0 = card_ptr[crd]; + epcaassert(chan0 <= &digi_channels[nbdevs - 1], "ch out of range"); + assertgwinon(chan0); + while ((tail = readw(&chan0->mailbox->eout)) != + (head = readw(&chan0->mailbox->ein))) { + /* Begin while something in event queue */ + assertgwinon(chan0); + eventbuf = bd->re_map_membase + tail + ISTART; + /* Get the channel the event occurred on */ + channel = readb(eventbuf); + /* Get the actual event code that occurred */ + event = readb(eventbuf + 1); + /* + * The two assignments below get the current modem status + * (mstat) and the previous modem status (lstat). These are + * useful becuase an event could signal a change in modem + * signals itself. + */ + mstat = readb(eventbuf + 2); + lstat = readb(eventbuf + 3); + + ch = chan0 + channel; + if ((unsigned)channel >= bd->numports || !ch) { + if (channel >= bd->numports) + ch = chan0; + bc = ch->brdchan; + goto next; + } + + bc = ch->brdchan; + if (bc == NULL) + goto next; + + tty = tty_port_tty_get(&ch->port); + if (event & DATA_IND) { /* Begin DATA_IND */ + receive_data(ch, tty); + assertgwinon(ch); + } /* End DATA_IND */ + /* else *//* Fix for DCD transition missed bug */ + if (event & MODEMCHG_IND) { + /* A modem signal change has been indicated */ + ch->imodem = mstat; + if (test_bit(ASYNCB_CHECK_CD, &ch->port.flags)) { + /* We are now receiving dcd */ + if (mstat & ch->dcd) + wake_up_interruptible(&ch->port.open_wait); + else /* No dcd; hangup */ + pc_sched_event(ch, EPCA_EVENT_HANGUP); + } + } + if (tty) { + if (event & BREAK_IND) { + /* A break has been indicated */ + tty_insert_flip_char(tty, 0, TTY_BREAK); + tty_schedule_flip(tty); + } else if (event & LOWTX_IND) { + if (ch->statusflags & LOWWAIT) { + ch->statusflags &= ~LOWWAIT; + tty_wakeup(tty); + } + } else if (event & EMPTYTX_IND) { + /* This event is generated by + setup_empty_event */ + ch->statusflags &= ~TXBUSY; + if (ch->statusflags & EMPTYWAIT) { + ch->statusflags &= ~EMPTYWAIT; + tty_wakeup(tty); + } + } + tty_kref_put(tty); + } +next: + globalwinon(ch); + BUG_ON(!bc); + writew(1, &bc->idata); + writew((tail + 4) & (IMAX - ISTART - 4), &chan0->mailbox->eout); + globalwinon(chan0); + } /* End while something in event queue */ +} + +static void fepcmd(struct channel *ch, int cmd, int word_or_byte, + int byte2, int ncmds, int bytecmd) +{ + unchar __iomem *memaddr; + unsigned int head, cmdTail, cmdStart, cmdMax; + long count; + int n; + + /* This is the routine in which commands may be passed to the card. */ + + if (ch->board->status == DISABLED) + return; + assertgwinon(ch); + /* Remember head (As well as max) is just an offset not a base addr */ + head = readw(&ch->mailbox->cin); + /* cmdStart is a base address */ + cmdStart = readw(&ch->mailbox->cstart); + /* + * We do the addition below because we do not want a max pointer + * relative to cmdStart. We want a max pointer that points at the + * physical end of the command queue. + */ + cmdMax = (cmdStart + 4 + readw(&ch->mailbox->cmax)); + memaddr = ch->board->re_map_membase; + + if (head >= (cmdMax - cmdStart) || (head & 03)) { + printk(KERN_ERR "line %d: Out of range, cmd = %x, head = %x\n", + __LINE__, cmd, head); + printk(KERN_ERR "line %d: Out of range, cmdMax = %x, cmdStart = %x\n", + __LINE__, cmdMax, cmdStart); + return; + } + if (bytecmd) { + writeb(cmd, memaddr + head + cmdStart + 0); + writeb(ch->channelnum, memaddr + head + cmdStart + 1); + /* Below word_or_byte is bits to set */ + writeb(word_or_byte, memaddr + head + cmdStart + 2); + /* Below byte2 is bits to reset */ + writeb(byte2, memaddr + head + cmdStart + 3); + } else { + writeb(cmd, memaddr + head + cmdStart + 0); + writeb(ch->channelnum, memaddr + head + cmdStart + 1); + writeb(word_or_byte, memaddr + head + cmdStart + 2); + } + head = (head + 4) & (cmdMax - cmdStart - 4); + writew(head, &ch->mailbox->cin); + count = FEPTIMEOUT; + + for (;;) { + count--; + if (count == 0) { + printk(KERN_ERR " - Fep not responding in fepcmd()\n"); + return; + } + head = readw(&ch->mailbox->cin); + cmdTail = readw(&ch->mailbox->cout); + n = (head - cmdTail) & (cmdMax - cmdStart - 4); + /* + * Basically this will break when the FEP acknowledges the + * command by incrementing cmdTail (Making it equal to head). + */ + if (n <= ncmds * (sizeof(short) * 4)) + break; + } +} + +/* + * Digi products use fields in their channels structures that are very similar + * to the c_cflag and c_iflag fields typically found in UNIX termios + * structures. The below three routines allow mappings between these hardware + * "flags" and their respective Linux flags. + */ +static unsigned termios2digi_h(struct channel *ch, unsigned cflag) +{ + unsigned res = 0; + + if (cflag & CRTSCTS) { + ch->digiext.digi_flags |= (RTSPACE | CTSPACE); + res |= ((ch->m_cts) | (ch->m_rts)); + } + + if (ch->digiext.digi_flags & RTSPACE) + res |= ch->m_rts; + + if (ch->digiext.digi_flags & DTRPACE) + res |= ch->m_dtr; + + if (ch->digiext.digi_flags & CTSPACE) + res |= ch->m_cts; + + if (ch->digiext.digi_flags & DSRPACE) + res |= ch->dsr; + + if (ch->digiext.digi_flags & DCDPACE) + res |= ch->dcd; + + if (res & (ch->m_rts)) + ch->digiext.digi_flags |= RTSPACE; + + if (res & (ch->m_cts)) + ch->digiext.digi_flags |= CTSPACE; + + return res; +} + +static unsigned termios2digi_i(struct channel *ch, unsigned iflag) +{ + unsigned res = iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK | + INPCK | ISTRIP | IXON | IXANY | IXOFF); + if (ch->digiext.digi_flags & DIGI_AIXON) + res |= IAIXON; + return res; +} + +static unsigned termios2digi_c(struct channel *ch, unsigned cflag) +{ + unsigned res = 0; + if (cflag & CBAUDEX) { + ch->digiext.digi_flags |= DIGI_FAST; + /* + * HUPCL bit is used by FEP to indicate fast baud table is to + * be used. + */ + res |= FEP_HUPCL; + } else + ch->digiext.digi_flags &= ~DIGI_FAST; + /* + * CBAUD has bit position 0x1000 set these days to indicate Linux + * baud rate remap. Digi hardware can't handle the bit assignment. + * (We use a different bit assignment for high speed.). Clear this + * bit out. + */ + res |= cflag & ((CBAUD ^ CBAUDEX) | PARODD | PARENB | CSTOPB | CSIZE); + /* + * This gets a little confusing. The Digi cards have their own + * representation of c_cflags controlling baud rate. For the most part + * this is identical to the Linux implementation. However; Digi + * supports one rate (76800) that Linux doesn't. This means that the + * c_cflag entry that would normally mean 76800 for Digi actually means + * 115200 under Linux. Without the below mapping, a stty 115200 would + * only drive the board at 76800. Since the rate 230400 is also found + * after 76800, the same problem afflicts us when we choose a rate of + * 230400. Without the below modificiation stty 230400 would actually + * give us 115200. + * + * There are two additional differences. The Linux value for CLOCAL + * (0x800; 0004000) has no meaning to the Digi hardware. Also in later + * releases of Linux; the CBAUD define has CBAUDEX (0x1000; 0010000) + * ored into it (CBAUD = 0x100f as opposed to 0xf). CBAUDEX should be + * checked for a screened out prior to termios2digi_c returning. Since + * CLOCAL isn't used by the board this can be ignored as long as the + * returned value is used only by Digi hardware. + */ + if (cflag & CBAUDEX) { + /* + * The below code is trying to guarantee that only baud rates + * 115200 and 230400 are remapped. We use exclusive or because + * the various baud rates share common bit positions and + * therefore can't be tested for easily. + */ + if ((!((cflag & 0x7) ^ (B115200 & ~CBAUDEX))) || + (!((cflag & 0x7) ^ (B230400 & ~CBAUDEX)))) + res += 1; + } + return res; +} + +/* Caller must hold the locks */ +static void epcaparam(struct tty_struct *tty, struct channel *ch) +{ + unsigned int cmdHead; + struct ktermios *ts; + struct board_chan __iomem *bc; + unsigned mval, hflow, cflag, iflag; + + bc = ch->brdchan; + epcaassert(bc != NULL, "bc out of range"); + + assertgwinon(ch); + ts = tty->termios; + if ((ts->c_cflag & CBAUD) == 0) { /* Begin CBAUD detected */ + cmdHead = readw(&bc->rin); + writew(cmdHead, &bc->rout); + cmdHead = readw(&bc->tin); + /* Changing baud in mid-stream transmission can be wonderful */ + /* + * Flush current transmit buffer by setting cmdTail pointer + * (tout) to cmdHead pointer (tin). Hopefully the transmit + * buffer is empty. + */ + fepcmd(ch, STOUT, (unsigned) cmdHead, 0, 0, 0); + mval = 0; + } else { /* Begin CBAUD not detected */ + /* + * c_cflags have changed but that change had nothing to do with + * BAUD. Propagate the change to the card. + */ + cflag = termios2digi_c(ch, ts->c_cflag); + if (cflag != ch->fepcflag) { + ch->fepcflag = cflag; + /* Set baud rate, char size, stop bits, parity */ + fepcmd(ch, SETCTRLFLAGS, (unsigned) cflag, 0, 0, 0); + } + /* + * If the user has not forced CLOCAL and if the device is not a + * CALLOUT device (Which is always CLOCAL) we set flags such + * that the driver will wait on carrier detect. + */ + if (ts->c_cflag & CLOCAL) + clear_bit(ASYNCB_CHECK_CD, &ch->port.flags); + else + set_bit(ASYNCB_CHECK_CD, &ch->port.flags); + mval = ch->m_dtr | ch->m_rts; + } /* End CBAUD not detected */ + iflag = termios2digi_i(ch, ts->c_iflag); + /* Check input mode flags */ + if (iflag != ch->fepiflag) { + ch->fepiflag = iflag; + /* + * Command sets channels iflag structure on the board. Such + * things as input soft flow control, handling of parity + * errors, and break handling are all set here. + * + * break handling, parity handling, input stripping, + * flow control chars + */ + fepcmd(ch, SETIFLAGS, (unsigned int) ch->fepiflag, 0, 0, 0); + } + /* + * Set the board mint value for this channel. This will cause hardware + * events to be generated each time the DCD signal (Described in mint) + * changes. + */ + writeb(ch->dcd, &bc->mint); + if ((ts->c_cflag & CLOCAL) || (ch->digiext.digi_flags & DIGI_FORCEDCD)) + if (ch->digiext.digi_flags & DIGI_FORCEDCD) + writeb(0, &bc->mint); + ch->imodem = readb(&bc->mstat); + hflow = termios2digi_h(ch, ts->c_cflag); + if (hflow != ch->hflow) { + ch->hflow = hflow; + /* + * Hard flow control has been selected but the board is not + * using it. Activate hard flow control now. + */ + fepcmd(ch, SETHFLOW, hflow, 0xff, 0, 1); + } + mval ^= ch->modemfake & (mval ^ ch->modem); + + if (ch->omodem ^ mval) { + ch->omodem = mval; + /* + * The below command sets the DTR and RTS mstat structure. If + * hard flow control is NOT active these changes will drive the + * output of the actual DTR and RTS lines. If hard flow control + * is active, the changes will be saved in the mstat structure + * and only asserted when hard flow control is turned off. + */ + + /* First reset DTR & RTS; then set them */ + fepcmd(ch, SETMODEM, 0, ((ch->m_dtr)|(ch->m_rts)), 0, 1); + fepcmd(ch, SETMODEM, mval, 0, 0, 1); + } + if (ch->startc != ch->fepstartc || ch->stopc != ch->fepstopc) { + ch->fepstartc = ch->startc; + ch->fepstopc = ch->stopc; + /* + * The XON / XOFF characters have changed; propagate these + * changes to the card. + */ + fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1); + } + if (ch->startca != ch->fepstartca || ch->stopca != ch->fepstopca) { + ch->fepstartca = ch->startca; + ch->fepstopca = ch->stopca; + /* + * Similar to the above, this time the auxilarly XON / XOFF + * characters have changed; propagate these changes to the card. + */ + fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1); + } +} + +/* Caller holds lock */ +static void receive_data(struct channel *ch, struct tty_struct *tty) +{ + unchar *rptr; + struct ktermios *ts = NULL; + struct board_chan __iomem *bc; + int dataToRead, wrapgap, bytesAvailable; + unsigned int tail, head; + unsigned int wrapmask; + + /* + * This routine is called by doint when a receive data event has taken + * place. + */ + globalwinon(ch); + if (ch->statusflags & RXSTOPPED) + return; + if (tty) + ts = tty->termios; + bc = ch->brdchan; + BUG_ON(!bc); + wrapmask = ch->rxbufsize - 1; + + /* + * Get the head and tail pointers to the receiver queue. Wrap the head + * pointer if it has reached the end of the buffer. + */ + head = readw(&bc->rin); + head &= wrapmask; + tail = readw(&bc->rout) & wrapmask; + + bytesAvailable = (head - tail) & wrapmask; + if (bytesAvailable == 0) + return; + + /* If CREAD bit is off or device not open, set TX tail to head */ + if (!tty || !ts || !(ts->c_cflag & CREAD)) { + writew(head, &bc->rout); + return; + } + + if (tty_buffer_request_room(tty, bytesAvailable + 1) == 0) + return; + + if (readb(&bc->orun)) { + writeb(0, &bc->orun); + printk(KERN_WARNING "epca; overrun! DigiBoard device %s\n", + tty->name); + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + } + rxwinon(ch); + while (bytesAvailable > 0) { + /* Begin while there is data on the card */ + wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail; + /* + * Even if head has wrapped around only report the amount of + * data to be equal to the size - tail. Remember memcpy can't + * automaticly wrap around the receive buffer. + */ + dataToRead = (wrapgap < bytesAvailable) ? wrapgap + : bytesAvailable; + /* Make sure we don't overflow the buffer */ + dataToRead = tty_prepare_flip_string(tty, &rptr, dataToRead); + if (dataToRead == 0) + break; + /* + * Move data read from our card into the line disciplines + * buffer for translation if necessary. + */ + memcpy_fromio(rptr, ch->rxptr + tail, dataToRead); + tail = (tail + dataToRead) & wrapmask; + bytesAvailable -= dataToRead; + } /* End while there is data on the card */ + globalwinon(ch); + writew(tail, &bc->rout); + /* Must be called with global data */ + tty_schedule_flip(tty); +} + +static int info_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + switch (cmd) { + case DIGI_GETINFO: + { + struct digi_info di; + int brd; + + if (get_user(brd, (unsigned int __user *)arg)) + return -EFAULT; + if (brd < 0 || brd >= num_cards || num_cards == 0) + return -ENODEV; + + memset(&di, 0, sizeof(di)); + + di.board = brd; + di.status = boards[brd].status; + di.type = boards[brd].type ; + di.numports = boards[brd].numports ; + /* Legacy fixups - just move along nothing to see */ + di.port = (unsigned char *)boards[brd].port ; + di.membase = (unsigned char *)boards[brd].membase ; + + if (copy_to_user((void __user *)arg, &di, sizeof(di))) + return -EFAULT; + break; + + } + + case DIGI_POLLER: + { + int brd = arg & 0xff000000 >> 16; + unsigned char state = arg & 0xff; + + if (brd < 0 || brd >= num_cards) { + printk(KERN_ERR "epca: DIGI POLLER : brd not valid!\n"); + return -ENODEV; + } + digi_poller_inhibited = state; + break; + } + + case DIGI_INIT: + { + /* + * This call is made by the apps to complete the + * initialization of the board(s). This routine is + * responsible for setting the card to its initial + * state and setting the drivers control fields to the + * sutianle settings for the card in question. + */ + int crd; + for (crd = 0; crd < num_cards; crd++) + post_fep_init(crd); + break; + } + default: + return -ENOTTY; + } + return 0; +} + +static int pc_tiocmget(struct tty_struct *tty) +{ + struct channel *ch = tty->driver_data; + struct board_chan __iomem *bc; + unsigned int mstat, mflag = 0; + unsigned long flags; + + if (ch) + bc = ch->brdchan; + else + return -EINVAL; + + spin_lock_irqsave(&epca_lock, flags); + globalwinon(ch); + mstat = readb(&bc->mstat); + memoff(ch); + spin_unlock_irqrestore(&epca_lock, flags); + + if (mstat & ch->m_dtr) + mflag |= TIOCM_DTR; + if (mstat & ch->m_rts) + mflag |= TIOCM_RTS; + if (mstat & ch->m_cts) + mflag |= TIOCM_CTS; + if (mstat & ch->dsr) + mflag |= TIOCM_DSR; + if (mstat & ch->m_ri) + mflag |= TIOCM_RI; + if (mstat & ch->dcd) + mflag |= TIOCM_CD; + return mflag; +} + +static int pc_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + struct channel *ch = tty->driver_data; + unsigned long flags; + + if (!ch) + return -EINVAL; + + spin_lock_irqsave(&epca_lock, flags); + /* + * I think this modemfake stuff is broken. It doesn't correctly reflect + * the behaviour desired by the TIOCM* ioctls. Therefore this is + * probably broken. + */ + if (set & TIOCM_RTS) { + ch->modemfake |= ch->m_rts; + ch->modem |= ch->m_rts; + } + if (set & TIOCM_DTR) { + ch->modemfake |= ch->m_dtr; + ch->modem |= ch->m_dtr; + } + if (clear & TIOCM_RTS) { + ch->modemfake |= ch->m_rts; + ch->modem &= ~ch->m_rts; + } + if (clear & TIOCM_DTR) { + ch->modemfake |= ch->m_dtr; + ch->modem &= ~ch->m_dtr; + } + globalwinon(ch); + /* + * The below routine generally sets up parity, baud, flow control + * issues, etc.... It effect both control flags and input flags. + */ + epcaparam(tty, ch); + memoff(ch); + spin_unlock_irqrestore(&epca_lock, flags); + return 0; +} + +static int pc_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + digiflow_t dflow; + unsigned long flags; + unsigned int mflag, mstat; + unsigned char startc, stopc; + struct board_chan __iomem *bc; + struct channel *ch = tty->driver_data; + void __user *argp = (void __user *)arg; + + if (ch) + bc = ch->brdchan; + else + return -EINVAL; + switch (cmd) { + case TIOCMODG: + mflag = pc_tiocmget(tty); + if (put_user(mflag, (unsigned long __user *)argp)) + return -EFAULT; + break; + case TIOCMODS: + if (get_user(mstat, (unsigned __user *)argp)) + return -EFAULT; + return pc_tiocmset(tty, mstat, ~mstat); + case TIOCSDTR: + spin_lock_irqsave(&epca_lock, flags); + ch->omodem |= ch->m_dtr; + globalwinon(ch); + fepcmd(ch, SETMODEM, ch->m_dtr, 0, 10, 1); + memoff(ch); + spin_unlock_irqrestore(&epca_lock, flags); + break; + + case TIOCCDTR: + spin_lock_irqsave(&epca_lock, flags); + ch->omodem &= ~ch->m_dtr; + globalwinon(ch); + fepcmd(ch, SETMODEM, 0, ch->m_dtr, 10, 1); + memoff(ch); + spin_unlock_irqrestore(&epca_lock, flags); + break; + case DIGI_GETA: + if (copy_to_user(argp, &ch->digiext, sizeof(digi_t))) + return -EFAULT; + break; + case DIGI_SETAW: + case DIGI_SETAF: + if (cmd == DIGI_SETAW) { + /* Setup an event to indicate when the transmit + buffer empties */ + spin_lock_irqsave(&epca_lock, flags); + setup_empty_event(tty, ch); + spin_unlock_irqrestore(&epca_lock, flags); + tty_wait_until_sent(tty, 0); + } else { + /* ldisc lock already held in ioctl */ + if (tty->ldisc->ops->flush_buffer) + tty->ldisc->ops->flush_buffer(tty); + } + /* Fall Thru */ + case DIGI_SETA: + if (copy_from_user(&ch->digiext, argp, sizeof(digi_t))) + return -EFAULT; + + if (ch->digiext.digi_flags & DIGI_ALTPIN) { + ch->dcd = ch->m_dsr; + ch->dsr = ch->m_dcd; + } else { + ch->dcd = ch->m_dcd; + ch->dsr = ch->m_dsr; + } + + spin_lock_irqsave(&epca_lock, flags); + globalwinon(ch); + + /* + * The below routine generally sets up parity, baud, flow + * control issues, etc.... It effect both control flags and + * input flags. + */ + epcaparam(tty, ch); + memoff(ch); + spin_unlock_irqrestore(&epca_lock, flags); + break; + + case DIGI_GETFLOW: + case DIGI_GETAFLOW: + spin_lock_irqsave(&epca_lock, flags); + globalwinon(ch); + if (cmd == DIGI_GETFLOW) { + dflow.startc = readb(&bc->startc); + dflow.stopc = readb(&bc->stopc); + } else { + dflow.startc = readb(&bc->startca); + dflow.stopc = readb(&bc->stopca); + } + memoff(ch); + spin_unlock_irqrestore(&epca_lock, flags); + + if (copy_to_user(argp, &dflow, sizeof(dflow))) + return -EFAULT; + break; + + case DIGI_SETAFLOW: + case DIGI_SETFLOW: + if (cmd == DIGI_SETFLOW) { + startc = ch->startc; + stopc = ch->stopc; + } else { + startc = ch->startca; + stopc = ch->stopca; + } + + if (copy_from_user(&dflow, argp, sizeof(dflow))) + return -EFAULT; + + if (dflow.startc != startc || dflow.stopc != stopc) { + /* Begin if setflow toggled */ + spin_lock_irqsave(&epca_lock, flags); + globalwinon(ch); + + if (cmd == DIGI_SETFLOW) { + ch->fepstartc = ch->startc = dflow.startc; + ch->fepstopc = ch->stopc = dflow.stopc; + fepcmd(ch, SONOFFC, ch->fepstartc, + ch->fepstopc, 0, 1); + } else { + ch->fepstartca = ch->startca = dflow.startc; + ch->fepstopca = ch->stopca = dflow.stopc; + fepcmd(ch, SAUXONOFFC, ch->fepstartca, + ch->fepstopca, 0, 1); + } + + if (ch->statusflags & TXSTOPPED) + pc_start(tty); + + memoff(ch); + spin_unlock_irqrestore(&epca_lock, flags); + } /* End if setflow toggled */ + break; + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static void pc_set_termios(struct tty_struct *tty, struct ktermios *old_termios) +{ + struct channel *ch; + unsigned long flags; + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ + ch = verifyChannel(tty); + + if (ch != NULL) { /* Begin if channel valid */ + spin_lock_irqsave(&epca_lock, flags); + globalwinon(ch); + epcaparam(tty, ch); + memoff(ch); + spin_unlock_irqrestore(&epca_lock, flags); + + if ((old_termios->c_cflag & CRTSCTS) && + ((tty->termios->c_cflag & CRTSCTS) == 0)) + tty->hw_stopped = 0; + + if (!(old_termios->c_cflag & CLOCAL) && + (tty->termios->c_cflag & CLOCAL)) + wake_up_interruptible(&ch->port.open_wait); + + } /* End if channel valid */ +} + +static void do_softint(struct work_struct *work) +{ + struct channel *ch = container_of(work, struct channel, tqueue); + /* Called in response to a modem change event */ + if (ch && ch->magic == EPCA_MAGIC) { + struct tty_struct *tty = tty_port_tty_get(&ch->port); + + if (tty && tty->driver_data) { + if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) { + tty_hangup(tty); + wake_up_interruptible(&ch->port.open_wait); + clear_bit(ASYNCB_NORMAL_ACTIVE, + &ch->port.flags); + } + } + tty_kref_put(tty); + } +} + +/* + * pc_stop and pc_start provide software flow control to the routine and the + * pc_ioctl routine. + */ +static void pc_stop(struct tty_struct *tty) +{ + struct channel *ch; + unsigned long flags; + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ + ch = verifyChannel(tty); + if (ch != NULL) { + spin_lock_irqsave(&epca_lock, flags); + if ((ch->statusflags & TXSTOPPED) == 0) { + /* Begin if transmit stop requested */ + globalwinon(ch); + /* STOP transmitting now !! */ + fepcmd(ch, PAUSETX, 0, 0, 0, 0); + ch->statusflags |= TXSTOPPED; + memoff(ch); + } /* End if transmit stop requested */ + spin_unlock_irqrestore(&epca_lock, flags); + } +} + +static void pc_start(struct tty_struct *tty) +{ + struct channel *ch; + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ + ch = verifyChannel(tty); + if (ch != NULL) { + unsigned long flags; + spin_lock_irqsave(&epca_lock, flags); + /* Just in case output was resumed because of a change + in Digi-flow */ + if (ch->statusflags & TXSTOPPED) { + /* Begin transmit resume requested */ + struct board_chan __iomem *bc; + globalwinon(ch); + bc = ch->brdchan; + if (ch->statusflags & LOWWAIT) + writeb(1, &bc->ilow); + /* Okay, you can start transmitting again... */ + fepcmd(ch, RESUMETX, 0, 0, 0, 0); + ch->statusflags &= ~TXSTOPPED; + memoff(ch); + } /* End transmit resume requested */ + spin_unlock_irqrestore(&epca_lock, flags); + } +} + +/* + * The below routines pc_throttle and pc_unthrottle are used to slow (And + * resume) the receipt of data into the kernels receive buffers. The exact + * occurrence of this depends on the size of the kernels receive buffer and + * what the 'watermarks' are set to for that buffer. See the n_ttys.c file for + * more details. + */ +static void pc_throttle(struct tty_struct *tty) +{ + struct channel *ch; + unsigned long flags; + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ + ch = verifyChannel(tty); + if (ch != NULL) { + spin_lock_irqsave(&epca_lock, flags); + if ((ch->statusflags & RXSTOPPED) == 0) { + globalwinon(ch); + fepcmd(ch, PAUSERX, 0, 0, 0, 0); + ch->statusflags |= RXSTOPPED; + memoff(ch); + } + spin_unlock_irqrestore(&epca_lock, flags); + } +} + +static void pc_unthrottle(struct tty_struct *tty) +{ + struct channel *ch; + unsigned long flags; + /* + * verifyChannel returns the channel from the tty struct if it is + * valid. This serves as a sanity check. + */ + ch = verifyChannel(tty); + if (ch != NULL) { + /* Just in case output was resumed because of a change + in Digi-flow */ + spin_lock_irqsave(&epca_lock, flags); + if (ch->statusflags & RXSTOPPED) { + globalwinon(ch); + fepcmd(ch, RESUMERX, 0, 0, 0, 0); + ch->statusflags &= ~RXSTOPPED; + memoff(ch); + } + spin_unlock_irqrestore(&epca_lock, flags); + } +} + +static int pc_send_break(struct tty_struct *tty, int msec) +{ + struct channel *ch = tty->driver_data; + unsigned long flags; + + if (msec == -1) + msec = 0xFFFF; + else if (msec > 0xFFFE) + msec = 0xFFFE; + else if (msec < 1) + msec = 1; + + spin_lock_irqsave(&epca_lock, flags); + globalwinon(ch); + /* + * Maybe I should send an infinite break here, schedule() for msec + * amount of time, and then stop the break. This way, the user can't + * screw up the FEP by causing digi_send_break() to be called (i.e. via + * an ioctl()) more than once in msec amount of time. + * Try this for now... + */ + fepcmd(ch, SENDBREAK, msec, 0, 10, 0); + memoff(ch); + spin_unlock_irqrestore(&epca_lock, flags); + return 0; +} + +/* Caller MUST hold the lock */ +static void setup_empty_event(struct tty_struct *tty, struct channel *ch) +{ + struct board_chan __iomem *bc = ch->brdchan; + + globalwinon(ch); + ch->statusflags |= EMPTYWAIT; + /* + * When set the iempty flag request a event to be generated when the + * transmit buffer is empty (If there is no BREAK in progress). + */ + writeb(1, &bc->iempty); + memoff(ch); +} + +#ifndef MODULE +static void __init epca_setup(char *str, int *ints) +{ + struct board_info board; + int index, loop, last; + char *temp, *t2; + unsigned len; + + /* + * If this routine looks a little strange it is because it is only + * called if a LILO append command is given to boot the kernel with + * parameters. In this way, we can provide the user a method of + * changing his board configuration without rebuilding the kernel. + */ + if (!liloconfig) + liloconfig = 1; + + memset(&board, 0, sizeof(board)); + + /* Assume the data is int first, later we can change it */ + /* I think that array position 0 of ints holds the number of args */ + for (last = 0, index = 1; index <= ints[0]; index++) + switch (index) { /* Begin parse switch */ + case 1: + board.status = ints[index]; + /* + * We check for 2 (As opposed to 1; because 2 is a flag + * instructing the driver to ignore epcaconfig.) For + * this reason we check for 2. + */ + if (board.status == 2) { + /* Begin ignore epcaconfig as well as lilo cmd line */ + nbdevs = 0; + num_cards = 0; + return; + } /* End ignore epcaconfig as well as lilo cmd line */ + + if (board.status > 2) { + printk(KERN_ERR "epca_setup: Invalid board status 0x%x\n", + board.status); + invalid_lilo_config = 1; + setup_error_code |= INVALID_BOARD_STATUS; + return; + } + last = index; + break; + case 2: + board.type = ints[index]; + if (board.type >= PCIXEM) { + printk(KERN_ERR "epca_setup: Invalid board type 0x%x\n", board.type); + invalid_lilo_config = 1; + setup_error_code |= INVALID_BOARD_TYPE; + return; + } + last = index; + break; + case 3: + board.altpin = ints[index]; + if (board.altpin > 1) { + printk(KERN_ERR "epca_setup: Invalid board altpin 0x%x\n", board.altpin); + invalid_lilo_config = 1; + setup_error_code |= INVALID_ALTPIN; + return; + } + last = index; + break; + + case 4: + board.numports = ints[index]; + if (board.numports < 2 || board.numports > 256) { + printk(KERN_ERR "epca_setup: Invalid board numports 0x%x\n", board.numports); + invalid_lilo_config = 1; + setup_error_code |= INVALID_NUM_PORTS; + return; + } + nbdevs += board.numports; + last = index; + break; + + case 5: + board.port = ints[index]; + if (ints[index] <= 0) { + printk(KERN_ERR "epca_setup: Invalid io port 0x%x\n", (unsigned int)board.port); + invalid_lilo_config = 1; + setup_error_code |= INVALID_PORT_BASE; + return; + } + last = index; + break; + + case 6: + board.membase = ints[index]; + if (ints[index] <= 0) { + printk(KERN_ERR "epca_setup: Invalid memory base 0x%x\n", + (unsigned int)board.membase); + invalid_lilo_config = 1; + setup_error_code |= INVALID_MEM_BASE; + return; + } + last = index; + break; + + default: + printk(KERN_ERR " - epca_setup: Too many integer parms\n"); + return; + + } /* End parse switch */ + + while (str && *str) { /* Begin while there is a string arg */ + /* find the next comma or terminator */ + temp = str; + /* While string is not null, and a comma hasn't been found */ + while (*temp && (*temp != ',')) + temp++; + if (!*temp) + temp = NULL; + else + *temp++ = 0; + /* Set index to the number of args + 1 */ + index = last + 1; + + switch (index) { + case 1: + len = strlen(str); + if (strncmp("Disable", str, len) == 0) + board.status = 0; + else if (strncmp("Enable", str, len) == 0) + board.status = 1; + else { + printk(KERN_ERR "epca_setup: Invalid status %s\n", str); + invalid_lilo_config = 1; + setup_error_code |= INVALID_BOARD_STATUS; + return; + } + last = index; + break; + + case 2: + for (loop = 0; loop < EPCA_NUM_TYPES; loop++) + if (strcmp(board_desc[loop], str) == 0) + break; + /* + * If the index incremented above refers to a + * legitamate board type set it here. + */ + if (index < EPCA_NUM_TYPES) + board.type = loop; + else { + printk(KERN_ERR "epca_setup: Invalid board type: %s\n", str); + invalid_lilo_config = 1; + setup_error_code |= INVALID_BOARD_TYPE; + return; + } + last = index; + break; + + case 3: + len = strlen(str); + if (strncmp("Disable", str, len) == 0) + board.altpin = 0; + else if (strncmp("Enable", str, len) == 0) + board.altpin = 1; + else { + printk(KERN_ERR "epca_setup: Invalid altpin %s\n", str); + invalid_lilo_config = 1; + setup_error_code |= INVALID_ALTPIN; + return; + } + last = index; + break; + + case 4: + t2 = str; + while (isdigit(*t2)) + t2++; + + if (*t2) { + printk(KERN_ERR "epca_setup: Invalid port count %s\n", str); + invalid_lilo_config = 1; + setup_error_code |= INVALID_NUM_PORTS; + return; + } + + /* + * There is not a man page for simple_strtoul but the + * code can be found in vsprintf.c. The first argument + * is the string to translate (To an unsigned long + * obviously), the second argument can be the address + * of any character variable or a NULL. If a variable + * is given, the end pointer of the string will be + * stored in that variable; if a NULL is given the end + * pointer will not be returned. The last argument is + * the base to use. If a 0 is indicated, the routine + * will attempt to determine the proper base by looking + * at the values prefix (A '0' for octal, a 'x' for + * hex, etc ... If a value is given it will use that + * value as the base. + */ + board.numports = simple_strtoul(str, NULL, 0); + nbdevs += board.numports; + last = index; + break; + + case 5: + t2 = str; + while (isxdigit(*t2)) + t2++; + + if (*t2) { + printk(KERN_ERR "epca_setup: Invalid i/o address %s\n", str); + invalid_lilo_config = 1; + setup_error_code |= INVALID_PORT_BASE; + return; + } + + board.port = simple_strtoul(str, NULL, 16); + last = index; + break; + + case 6: + t2 = str; + while (isxdigit(*t2)) + t2++; + + if (*t2) { + printk(KERN_ERR "epca_setup: Invalid memory base %s\n", str); + invalid_lilo_config = 1; + setup_error_code |= INVALID_MEM_BASE; + return; + } + board.membase = simple_strtoul(str, NULL, 16); + last = index; + break; + default: + printk(KERN_ERR "epca: Too many string parms\n"); + return; + } + str = temp; + } /* End while there is a string arg */ + + if (last < 6) { + printk(KERN_ERR "epca: Insufficient parms specified\n"); + return; + } + + /* I should REALLY validate the stuff here */ + /* Copies our local copy of board into boards */ + memcpy((void *)&boards[num_cards], (void *)&board, sizeof(board)); + /* Does this get called once per lilo arg are what ? */ + printk(KERN_INFO "PC/Xx: Added board %i, %s %i ports at 0x%4.4X base 0x%6.6X\n", + num_cards, board_desc[board.type], + board.numports, (int)board.port, (unsigned int) board.membase); + num_cards++; +} + +static int __init epca_real_setup(char *str) +{ + int ints[11]; + + epca_setup(get_options(str, 11, ints), ints); + return 1; +} + +__setup("digiepca", epca_real_setup); +#endif + +enum epic_board_types { + brd_xr = 0, + brd_xem, + brd_cx, + brd_xrj, +}; + +/* indexed directly by epic_board_types enum */ +static struct { + unsigned char board_type; + unsigned bar_idx; /* PCI base address region */ +} epca_info_tbl[] = { + { PCIXR, 0, }, + { PCIXEM, 0, }, + { PCICX, 0, }, + { PCIXRJ, 2, }, +}; + +static int __devinit epca_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + static int board_num = -1; + int board_idx, info_idx = ent->driver_data; + unsigned long addr; + + if (pci_enable_device(pdev)) + return -EIO; + + board_num++; + board_idx = board_num + num_cards; + if (board_idx >= MAXBOARDS) + goto err_out; + + addr = pci_resource_start(pdev, epca_info_tbl[info_idx].bar_idx); + if (!addr) { + printk(KERN_ERR PFX "PCI region #%d not available (size 0)\n", + epca_info_tbl[info_idx].bar_idx); + goto err_out; + } + + boards[board_idx].status = ENABLED; + boards[board_idx].type = epca_info_tbl[info_idx].board_type; + boards[board_idx].numports = 0x0; + boards[board_idx].port = addr + PCI_IO_OFFSET; + boards[board_idx].membase = addr; + + if (!request_mem_region(addr + PCI_IO_OFFSET, 0x200000, "epca")) { + printk(KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n", + 0x200000, addr + PCI_IO_OFFSET); + goto err_out; + } + + boards[board_idx].re_map_port = ioremap_nocache(addr + PCI_IO_OFFSET, + 0x200000); + if (!boards[board_idx].re_map_port) { + printk(KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n", + 0x200000, addr + PCI_IO_OFFSET); + goto err_out_free_pciio; + } + + if (!request_mem_region(addr, 0x200000, "epca")) { + printk(KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n", + 0x200000, addr); + goto err_out_free_iounmap; + } + + boards[board_idx].re_map_membase = ioremap_nocache(addr, 0x200000); + if (!boards[board_idx].re_map_membase) { + printk(KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n", + 0x200000, addr + PCI_IO_OFFSET); + goto err_out_free_memregion; + } + + /* + * I don't know what the below does, but the hardware guys say its + * required on everything except PLX (In this case XRJ). + */ + if (info_idx != brd_xrj) { + pci_write_config_byte(pdev, 0x40, 0); + pci_write_config_byte(pdev, 0x46, 0); + } + + return 0; + +err_out_free_memregion: + release_mem_region(addr, 0x200000); +err_out_free_iounmap: + iounmap(boards[board_idx].re_map_port); +err_out_free_pciio: + release_mem_region(addr + PCI_IO_OFFSET, 0x200000); +err_out: + return -ENODEV; +} + + +static struct pci_device_id epca_pci_tbl[] = { + { PCI_VENDOR_DIGI, PCI_DEVICE_XR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xr }, + { PCI_VENDOR_DIGI, PCI_DEVICE_XEM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xem }, + { PCI_VENDOR_DIGI, PCI_DEVICE_CX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_cx }, + { PCI_VENDOR_DIGI, PCI_DEVICE_XRJ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xrj }, + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, epca_pci_tbl); + +static int __init init_PCI(void) +{ + memset(&epca_driver, 0, sizeof(epca_driver)); + epca_driver.name = "epca"; + epca_driver.id_table = epca_pci_tbl; + epca_driver.probe = epca_init_one; + + return pci_register_driver(&epca_driver); +} + +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/tty/epca.h b/drivers/staging/tty/epca.h new file mode 100644 index 000000000000..d414bf2dbf7c --- /dev/null +++ b/drivers/staging/tty/epca.h @@ -0,0 +1,158 @@ +#define XEMPORTS 0xC02 +#define XEPORTS 0xC22 + +#define MAX_ALLOC 0x100 + +#define MAXBOARDS 12 +#define FEPCODESEG 0x0200L +#define FEPCODE 0x2000L +#define BIOSCODE 0xf800L + +#define MISCGLOBAL 0x0C00L +#define NPORT 0x0C22L +#define MBOX 0x0C40L +#define PORTBASE 0x0C90L + +/* Begin code defines used for epca_setup */ + +#define INVALID_BOARD_TYPE 0x1 +#define INVALID_NUM_PORTS 0x2 +#define INVALID_MEM_BASE 0x4 +#define INVALID_PORT_BASE 0x8 +#define INVALID_BOARD_STATUS 0x10 +#define INVALID_ALTPIN 0x20 + +/* End code defines used for epca_setup */ + + +#define FEPCLR 0x00 +#define FEPMEM 0x02 +#define FEPRST 0x04 +#define FEPINT 0x08 +#define FEPMASK 0x0e +#define FEPWIN 0x80 + +#define PCXE 0 +#define PCXEVE 1 +#define PCXEM 2 +#define EISAXEM 3 +#define PC64XE 4 +#define PCXI 5 +#define PCIXEM 7 +#define PCICX 8 +#define PCIXR 9 +#define PCIXRJ 10 +#define EPCA_NUM_TYPES 6 + + +static char *board_desc[] = +{ + "PC/Xe", + "PC/Xeve", + "PC/Xem", + "EISA/Xem", + "PC/64Xe", + "PC/Xi", + "unknown", + "PCI/Xem", + "PCI/CX", + "PCI/Xr", + "PCI/Xrj", +}; + +#define STARTC 021 +#define STOPC 023 +#define IAIXON 0x2000 + + +#define TXSTOPPED 0x1 +#define LOWWAIT 0x2 +#define EMPTYWAIT 0x4 +#define RXSTOPPED 0x8 +#define TXBUSY 0x10 + +#define DISABLED 0 +#define ENABLED 1 +#define OFF 0 +#define ON 1 + +#define FEPTIMEOUT 200000 +#define SERIAL_TYPE_INFO 3 +#define EPCA_EVENT_HANGUP 1 +#define EPCA_MAGIC 0x5c6df104L + +struct channel +{ + long magic; + struct tty_port port; + unsigned char boardnum; + unsigned char channelnum; + unsigned char omodem; /* FEP output modem status */ + unsigned char imodem; /* FEP input modem status */ + unsigned char modemfake; /* Modem values to be forced */ + unsigned char modem; /* Force values */ + unsigned char hflow; + unsigned char dsr; + unsigned char dcd; + unsigned char m_rts ; /* The bits used in whatever FEP */ + unsigned char m_dcd ; /* is indiginous to this board to */ + unsigned char m_dsr ; /* represent each of the physical */ + unsigned char m_cts ; /* handshake lines */ + unsigned char m_ri ; + unsigned char m_dtr ; + unsigned char stopc; + unsigned char startc; + unsigned char stopca; + unsigned char startca; + unsigned char fepstopc; + unsigned char fepstartc; + unsigned char fepstopca; + unsigned char fepstartca; + unsigned char txwin; + unsigned char rxwin; + unsigned short fepiflag; + unsigned short fepcflag; + unsigned short fepoflag; + unsigned short txbufhead; + unsigned short txbufsize; + unsigned short rxbufhead; + unsigned short rxbufsize; + int close_delay; + unsigned long event; + uint dev; + unsigned long statusflags; + unsigned long c_iflag; + unsigned long c_cflag; + unsigned long c_lflag; + unsigned long c_oflag; + unsigned char __iomem *txptr; + unsigned char __iomem *rxptr; + struct board_info *board; + struct board_chan __iomem *brdchan; + struct digi_struct digiext; + struct work_struct tqueue; + struct global_data __iomem *mailbox; +}; + +struct board_info +{ + unsigned char status; + unsigned char type; + unsigned char altpin; + unsigned short numports; + unsigned long port; + unsigned long membase; + void __iomem *re_map_port; + void __iomem *re_map_membase; + unsigned long memory_seg; + void ( * memwinon ) (struct board_info *, unsigned int) ; + void ( * memwinoff ) (struct board_info *, unsigned int) ; + void ( * globalwinon ) (struct channel *) ; + void ( * txwinon ) (struct channel *) ; + void ( * rxwinon ) (struct channel *) ; + void ( * memoff ) (struct channel *) ; + void ( * assertgwinon ) (struct channel *) ; + void ( * assertmemoff ) (struct channel *) ; + unsigned char poller_inhibited ; +}; + diff --git a/drivers/staging/tty/epcaconfig.h b/drivers/staging/tty/epcaconfig.h new file mode 100644 index 000000000000..55dec067078e --- /dev/null +++ b/drivers/staging/tty/epcaconfig.h @@ -0,0 +1,7 @@ +#define NUMCARDS 0 +#define NBDEVS 0 + +struct board_info static_boards[NUMCARDS]={ +}; + +/* DO NOT HAND EDIT THIS FILE! */ diff --git a/drivers/staging/tty/ip2/Makefile b/drivers/staging/tty/ip2/Makefile new file mode 100644 index 000000000000..7b78e0dfc5b0 --- /dev/null +++ b/drivers/staging/tty/ip2/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for the Computone IntelliPort Plus Driver +# + +obj-$(CONFIG_COMPUTONE) += ip2.o + +ip2-y := ip2main.o + diff --git a/drivers/staging/tty/ip2/i2cmd.c b/drivers/staging/tty/ip2/i2cmd.c new file mode 100644 index 000000000000..e7af647800b6 --- /dev/null +++ b/drivers/staging/tty/ip2/i2cmd.c @@ -0,0 +1,210 @@ +/******************************************************************************* +* +* (c) 1998 by Computone Corporation +* +******************************************************************************** +* +* +* PACKAGE: Linux tty Device Driver for IntelliPort family of multiport +* serial I/O controllers. +* +* DESCRIPTION: Definition table for In-line and Bypass commands. Applicable +* only when the standard loadware is active. (This is included +* source code, not a separate compilation module.) +* +*******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Revision History: +// +// 10 October 1991 MAG First Draft +// 7 November 1991 MAG Reflects additional commands. +// 24 February 1992 MAG Additional commands for 1.4.x loadware +// 11 March 1992 MAG Additional commands +// 30 March 1992 MAG Additional command: CMD_DSS_NOW +// 18 May 1992 MAG Discovered commands 39 & 40 must be at the end of a +// packet: affects implementation. +//------------------------------------------------------------------------------ + +//************ +//* Includes * +//************ + +#include "i2cmd.h" /* To get some bit-defines */ + +//------------------------------------------------------------------------------ +// Here is the table of global arrays which represent each type of command +// supported in the IntelliPort standard loadware. See also i2cmd.h +// for a more complete explanation of what is going on. +//------------------------------------------------------------------------------ + +// Here are the various globals: note that the names are not used except through +// the macros defined in i2cmd.h. Also note that although they are character +// arrays here (for extendability) they are cast to structure pointers in the +// i2cmd.h macros. See i2cmd.h for flags definitions. + +// Length Flags Command +static UCHAR ct02[] = { 1, BTH, 0x02 }; // DTR UP +static UCHAR ct03[] = { 1, BTH, 0x03 }; // DTR DN +static UCHAR ct04[] = { 1, BTH, 0x04 }; // RTS UP +static UCHAR ct05[] = { 1, BTH, 0x05 }; // RTS DN +static UCHAR ct06[] = { 1, BYP, 0x06 }; // START FL +static UCHAR ct07[] = { 2, BTH, 0x07,0 }; // BAUD +static UCHAR ct08[] = { 2, BTH, 0x08,0 }; // BITS +static UCHAR ct09[] = { 2, BTH, 0x09,0 }; // STOP +static UCHAR ct10[] = { 2, BTH, 0x0A,0 }; // PARITY +static UCHAR ct11[] = { 2, BTH, 0x0B,0 }; // XON +static UCHAR ct12[] = { 2, BTH, 0x0C,0 }; // XOFF +static UCHAR ct13[] = { 1, BTH, 0x0D }; // STOP FL +static UCHAR ct14[] = { 1, BYP|VIP, 0x0E }; // ACK HOTK +//static UCHAR ct15[]={ 2, BTH|VIP, 0x0F,0 }; // IRQ SET +static UCHAR ct16[] = { 2, INL, 0x10,0 }; // IXONOPTS +static UCHAR ct17[] = { 2, INL, 0x11,0 }; // OXONOPTS +static UCHAR ct18[] = { 1, INL, 0x12 }; // CTSENAB +static UCHAR ct19[] = { 1, BTH, 0x13 }; // CTSDSAB +static UCHAR ct20[] = { 1, INL, 0x14 }; // DCDENAB +static UCHAR ct21[] = { 1, BTH, 0x15 }; // DCDDSAB +static UCHAR ct22[] = { 1, BTH, 0x16 }; // DSRENAB +static UCHAR ct23[] = { 1, BTH, 0x17 }; // DSRDSAB +static UCHAR ct24[] = { 1, BTH, 0x18 }; // RIENAB +static UCHAR ct25[] = { 1, BTH, 0x19 }; // RIDSAB +static UCHAR ct26[] = { 2, BTH, 0x1A,0 }; // BRKENAB +static UCHAR ct27[] = { 1, BTH, 0x1B }; // BRKDSAB +//static UCHAR ct28[]={ 2, BTH, 0x1C,0 }; // MAXBLOKSIZE +//static UCHAR ct29[]={ 2, 0, 0x1D,0 }; // reserved +static UCHAR ct30[] = { 1, INL, 0x1E }; // CTSFLOWENAB +static UCHAR ct31[] = { 1, INL, 0x1F }; // CTSFLOWDSAB +static UCHAR ct32[] = { 1, INL, 0x20 }; // RTSFLOWENAB +static UCHAR ct33[] = { 1, INL, 0x21 }; // RTSFLOWDSAB +static UCHAR ct34[] = { 2, BTH, 0x22,0 }; // ISTRIPMODE +static UCHAR ct35[] = { 2, BTH|END, 0x23,0 }; // SENDBREAK +static UCHAR ct36[] = { 2, BTH, 0x24,0 }; // SETERRMODE +//static UCHAR ct36a[]={ 3, INL, 0x24,0,0 }; // SET_REPLACE + +// The following is listed for completeness, but should never be sent directly +// by user-level code. It is sent only by library routines in response to data +// movement. +//static UCHAR ct37[]={ 5, BYP|VIP, 0x25,0,0,0,0 }; // FLOW PACKET + +// Back to normal +//static UCHAR ct38[] = {11, BTH|VAR, 0x26,0,0,0,0,0,0,0,0,0,0 }; // DEF KEY SEQ +//static UCHAR ct39[]={ 3, BTH|END, 0x27,0,0 }; // OPOSTON +//static UCHAR ct40[]={ 1, BTH|END, 0x28 }; // OPOSTOFF +static UCHAR ct41[] = { 1, BYP, 0x29 }; // RESUME +//static UCHAR ct42[]={ 2, BTH, 0x2A,0 }; // TXBAUD +//static UCHAR ct43[]={ 2, BTH, 0x2B,0 }; // RXBAUD +//static UCHAR ct44[]={ 2, BTH, 0x2C,0 }; // MS PING +//static UCHAR ct45[]={ 1, BTH, 0x2D }; // HOTENAB +//static UCHAR ct46[]={ 1, BTH, 0x2E }; // HOTDSAB +//static UCHAR ct47[]={ 7, BTH, 0x2F,0,0,0,0,0,0 }; // UNIX FLAGS +//static UCHAR ct48[]={ 1, BTH, 0x30 }; // DSRFLOWENAB +//static UCHAR ct49[]={ 1, BTH, 0x31 }; // DSRFLOWDSAB +//static UCHAR ct50[]={ 1, BTH, 0x32 }; // DTRFLOWENAB +//static UCHAR ct51[]={ 1, BTH, 0x33 }; // DTRFLOWDSAB +//static UCHAR ct52[]={ 1, BTH, 0x34 }; // BAUDTABRESET +//static UCHAR ct53[] = { 3, BTH, 0x35,0,0 }; // BAUDREMAP +static UCHAR ct54[] = { 3, BTH, 0x36,0,0 }; // CUSTOMBAUD1 +static UCHAR ct55[] = { 3, BTH, 0x37,0,0 }; // CUSTOMBAUD2 +static UCHAR ct56[] = { 2, BTH|END, 0x38,0 }; // PAUSE +static UCHAR ct57[] = { 1, BYP, 0x39 }; // SUSPEND +static UCHAR ct58[] = { 1, BYP, 0x3A }; // UNSUSPEND +static UCHAR ct59[] = { 2, BTH, 0x3B,0 }; // PARITYCHK +static UCHAR ct60[] = { 1, INL|VIP, 0x3C }; // BOOKMARKREQ +//static UCHAR ct61[]={ 2, BTH, 0x3D,0 }; // INTERNALLOOP +//static UCHAR ct62[]={ 2, BTH, 0x3E,0 }; // HOTKTIMEOUT +static UCHAR ct63[] = { 2, INL, 0x3F,0 }; // SETTXON +static UCHAR ct64[] = { 2, INL, 0x40,0 }; // SETTXOFF +//static UCHAR ct65[]={ 2, BTH, 0x41,0 }; // SETAUTORTS +//static UCHAR ct66[]={ 2, BTH, 0x42,0 }; // SETHIGHWAT +//static UCHAR ct67[]={ 2, BYP, 0x43,0 }; // STARTSELFL +//static UCHAR ct68[]={ 2, INL, 0x44,0 }; // ENDSELFL +//static UCHAR ct69[]={ 1, BYP, 0x45 }; // HWFLOW_OFF +//static UCHAR ct70[]={ 1, BTH, 0x46 }; // ODSRFL_ENAB +//static UCHAR ct71[]={ 1, BTH, 0x47 }; // ODSRFL_DSAB +//static UCHAR ct72[]={ 1, BTH, 0x48 }; // ODCDFL_ENAB +//static UCHAR ct73[]={ 1, BTH, 0x49 }; // ODCDFL_DSAB +//static UCHAR ct74[]={ 2, BTH, 0x4A,0 }; // LOADLEVEL +//static UCHAR ct75[]={ 2, BTH, 0x4B,0 }; // STATDATA +//static UCHAR ct76[]={ 1, BYP, 0x4C }; // BREAK_ON +//static UCHAR ct77[]={ 1, BYP, 0x4D }; // BREAK_OFF +//static UCHAR ct78[]={ 1, BYP, 0x4E }; // GETFC +static UCHAR ct79[] = { 2, BYP, 0x4F,0 }; // XMIT_NOW +//static UCHAR ct80[]={ 4, BTH, 0x50,0,0,0 }; // DIVISOR_LATCH +//static UCHAR ct81[]={ 1, BYP, 0x51 }; // GET_STATUS +//static UCHAR ct82[]={ 1, BYP, 0x52 }; // GET_TXCNT +//static UCHAR ct83[]={ 1, BYP, 0x53 }; // GET_RXCNT +//static UCHAR ct84[]={ 1, BYP, 0x54 }; // GET_BOXIDS +//static UCHAR ct85[]={10, BYP, 0x55,0,0,0,0,0,0,0,0,0 }; // ENAB_MULT +//static UCHAR ct86[]={ 2, BTH, 0x56,0 }; // RCV_ENABLE +static UCHAR ct87[] = { 1, BYP, 0x57 }; // HW_TEST +//static UCHAR ct88[]={ 3, BTH, 0x58,0,0 }; // RCV_THRESHOLD +//static UCHAR ct90[]={ 3, BYP, 0x5A,0,0 }; // Set SILO +//static UCHAR ct91[]={ 2, BYP, 0x5B,0 }; // timed break + +// Some composite commands as well +//static UCHAR cc01[]={ 2, BTH, 0x02,0x04 }; // DTR & RTS UP +//static UCHAR cc02[]={ 2, BTH, 0x03,0x05 }; // DTR & RTS DN + +//******** +//* Code * +//******** + +//****************************************************************************** +// Function: i2cmdUnixFlags(iflag, cflag, lflag) +// Parameters: Unix tty flags +// +// Returns: Pointer to command structure +// +// Description: +// +// This routine sets the parameters of command 47 and returns a pointer to the +// appropriate structure. +//****************************************************************************** +#if 0 +cmdSyntaxPtr +i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag) +{ + cmdSyntaxPtr pCM = (cmdSyntaxPtr) ct47; + + pCM->cmd[1] = (unsigned char) iflag; + pCM->cmd[2] = (unsigned char) (iflag >> 8); + pCM->cmd[3] = (unsigned char) cflag; + pCM->cmd[4] = (unsigned char) (cflag >> 8); + pCM->cmd[5] = (unsigned char) lflag; + pCM->cmd[6] = (unsigned char) (lflag >> 8); + return pCM; +} +#endif /* 0 */ + +//****************************************************************************** +// Function: i2cmdBaudDef(which, rate) +// Parameters: ? +// +// Returns: Pointer to command structure +// +// Description: +// +// This routine sets the parameters of commands 54 or 55 (according to the +// argument which), and returns a pointer to the appropriate structure. +//****************************************************************************** +static cmdSyntaxPtr +i2cmdBaudDef(int which, unsigned short rate) +{ + cmdSyntaxPtr pCM; + + switch(which) + { + case 1: + pCM = (cmdSyntaxPtr) ct54; + break; + default: + case 2: + pCM = (cmdSyntaxPtr) ct55; + break; + } + pCM->cmd[1] = (unsigned char) rate; + pCM->cmd[2] = (unsigned char) (rate >> 8); + return pCM; +} + diff --git a/drivers/staging/tty/ip2/i2cmd.h b/drivers/staging/tty/ip2/i2cmd.h new file mode 100644 index 000000000000..29277ec6b8ed --- /dev/null +++ b/drivers/staging/tty/ip2/i2cmd.h @@ -0,0 +1,630 @@ +/******************************************************************************* +* +* (c) 1999 by Computone Corporation +* +******************************************************************************** +* +* +* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport +* serial I/O controllers. +* +* DESCRIPTION: Definitions and support for In-line and Bypass commands. +* Applicable only when the standard loadware is active. +* +*******************************************************************************/ +//------------------------------------------------------------------------------ +// Revision History: +// +// 10 October 1991 MAG First Draft +// 7 November 1991 MAG Reflects some new commands +// 20 February 1992 MAG CMD_HOTACK corrected: no argument. +// 24 February 1992 MAG Support added for new commands for 1.4.x loadware. +// 11 March 1992 MAG Additional commands. +// 16 March 1992 MAG Additional commands. +// 30 March 1992 MAG Additional command: CMD_DSS_NOW +// 18 May 1992 MAG Changed CMD_OPOST +// +//------------------------------------------------------------------------------ +#ifndef I2CMD_H // To prevent multiple includes +#define I2CMD_H 1 + +#include "ip2types.h" + +// This module is designed to provide a uniform method of sending commands to +// the board through command packets. The difficulty is, some commands take +// parameters, others do not. Furthermore, it is often useful to send several +// commands to the same channel as part of the same packet. (See also i2pack.h.) +// +// This module is designed so that the caller should not be responsible for +// remembering the exact syntax of each command, or at least so that the +// compiler could check things somewhat. I'll explain as we go... +// +// First, a structure which can embody the syntax of each type of command. +// +typedef struct _cmdSyntax +{ + UCHAR length; // Number of bytes in the command + UCHAR flags; // Information about the command (see below) + + // The command and its parameters, which may be of arbitrary length. Don't + // worry yet how the parameters will be initialized; macros later take care + // of it. Also, don't worry about the arbitrary length issue; this structure + // is never used to allocate space (see i2cmd.c). + UCHAR cmd[2]; +} cmdSyntax, *cmdSyntaxPtr; + +// Bit assignments for flags + +#define INL 1 // Set if suitable for inline commands +#define BYP 2 // Set if suitable for bypass commands +#define BTH (INL|BYP) // suitable for either! +#define END 4 // Set if this must be the last command in a block +#define VIP 8 // Set if this command is special in some way and really + // should only be sent from the library-level and not + // directly from user-level +#define VAR 0x10 // This command is of variable length! + +// Declarations for the global arrays used to bear the commands and their +// arguments. +// +// Note: Since these are globals and the arguments might change, it is important +// that the library routine COPY these into buffers from whence they would be +// sent, rather than merely storing the pointers. In multi-threaded +// environments, important that the copy should obtain before any context switch +// is allowed. Also, for parameterized commands, DO NOT ISSUE THE SAME COMMAND +// MORE THAN ONCE WITH THE SAME PARAMETERS in the same call. +// +static UCHAR ct02[]; +static UCHAR ct03[]; +static UCHAR ct04[]; +static UCHAR ct05[]; +static UCHAR ct06[]; +static UCHAR ct07[]; +static UCHAR ct08[]; +static UCHAR ct09[]; +static UCHAR ct10[]; +static UCHAR ct11[]; +static UCHAR ct12[]; +static UCHAR ct13[]; +static UCHAR ct14[]; +static UCHAR ct15[]; +static UCHAR ct16[]; +static UCHAR ct17[]; +static UCHAR ct18[]; +static UCHAR ct19[]; +static UCHAR ct20[]; +static UCHAR ct21[]; +static UCHAR ct22[]; +static UCHAR ct23[]; +static UCHAR ct24[]; +static UCHAR ct25[]; +static UCHAR ct26[]; +static UCHAR ct27[]; +static UCHAR ct28[]; +static UCHAR ct29[]; +static UCHAR ct30[]; +static UCHAR ct31[]; +static UCHAR ct32[]; +static UCHAR ct33[]; +static UCHAR ct34[]; +static UCHAR ct35[]; +static UCHAR ct36[]; +static UCHAR ct36a[]; +static UCHAR ct41[]; +static UCHAR ct42[]; +static UCHAR ct43[]; +static UCHAR ct44[]; +static UCHAR ct45[]; +static UCHAR ct46[]; +static UCHAR ct48[]; +static UCHAR ct49[]; +static UCHAR ct50[]; +static UCHAR ct51[]; +static UCHAR ct52[]; +static UCHAR ct56[]; +static UCHAR ct57[]; +static UCHAR ct58[]; +static UCHAR ct59[]; +static UCHAR ct60[]; +static UCHAR ct61[]; +static UCHAR ct62[]; +static UCHAR ct63[]; +static UCHAR ct64[]; +static UCHAR ct65[]; +static UCHAR ct66[]; +static UCHAR ct67[]; +static UCHAR ct68[]; +static UCHAR ct69[]; +static UCHAR ct70[]; +static UCHAR ct71[]; +static UCHAR ct72[]; +static UCHAR ct73[]; +static UCHAR ct74[]; +static UCHAR ct75[]; +static UCHAR ct76[]; +static UCHAR ct77[]; +static UCHAR ct78[]; +static UCHAR ct79[]; +static UCHAR ct80[]; +static UCHAR ct81[]; +static UCHAR ct82[]; +static UCHAR ct83[]; +static UCHAR ct84[]; +static UCHAR ct85[]; +static UCHAR ct86[]; +static UCHAR ct87[]; +static UCHAR ct88[]; +static UCHAR ct89[]; +static UCHAR ct90[]; +static UCHAR ct91[]; +static UCHAR cc01[]; +static UCHAR cc02[]; + +// Now, refer to i2cmd.c, and see the character arrays defined there. They are +// cast here to cmdSyntaxPtr. +// +// There are library functions for issuing bypass or inline commands. These +// functions take one or more arguments of the type cmdSyntaxPtr. The routine +// then can figure out how long each command is supposed to be and easily add it +// to the list. +// +// For ease of use, we define manifests which return pointers to appropriate +// cmdSyntaxPtr things. But some commands also take arguments. If a single +// argument is used, we define a macro which performs the single assignment and +// (through the expedient of a comma expression) references the appropriate +// pointer. For commands requiring several arguments, we actually define a +// function to perform the assignments. + +#define CMD_DTRUP (cmdSyntaxPtr)(ct02) // Raise DTR +#define CMD_DTRDN (cmdSyntaxPtr)(ct03) // Lower DTR +#define CMD_RTSUP (cmdSyntaxPtr)(ct04) // Raise RTS +#define CMD_RTSDN (cmdSyntaxPtr)(ct05) // Lower RTS +#define CMD_STARTFL (cmdSyntaxPtr)(ct06) // Start Flushing Data + +#define CMD_DTRRTS_UP (cmdSyntaxPtr)(cc01) // Raise DTR and RTS +#define CMD_DTRRTS_DN (cmdSyntaxPtr)(cc02) // Lower DTR and RTS + +// Set Baud Rate for transmit and receive +#define CMD_SETBAUD(arg) \ + (((cmdSyntaxPtr)(ct07))->cmd[1] = (arg),(cmdSyntaxPtr)(ct07)) + +#define CBR_50 1 +#define CBR_75 2 +#define CBR_110 3 +#define CBR_134 4 +#define CBR_150 5 +#define CBR_200 6 +#define CBR_300 7 +#define CBR_600 8 +#define CBR_1200 9 +#define CBR_1800 10 +#define CBR_2400 11 +#define CBR_4800 12 +#define CBR_9600 13 +#define CBR_19200 14 +#define CBR_38400 15 +#define CBR_2000 16 +#define CBR_3600 17 +#define CBR_7200 18 +#define CBR_56000 19 +#define CBR_57600 20 +#define CBR_64000 21 +#define CBR_76800 22 +#define CBR_115200 23 +#define CBR_C1 24 // Custom baud rate 1 +#define CBR_C2 25 // Custom baud rate 2 +#define CBR_153600 26 +#define CBR_230400 27 +#define CBR_307200 28 +#define CBR_460800 29 +#define CBR_921600 30 + +// Set Character size +// +#define CMD_SETBITS(arg) \ + (((cmdSyntaxPtr)(ct08))->cmd[1] = (arg),(cmdSyntaxPtr)(ct08)) + +#define CSZ_5 0 +#define CSZ_6 1 +#define CSZ_7 2 +#define CSZ_8 3 + +// Set number of stop bits +// +#define CMD_SETSTOP(arg) \ + (((cmdSyntaxPtr)(ct09))->cmd[1] = (arg),(cmdSyntaxPtr)(ct09)) + +#define CST_1 0 +#define CST_15 1 // 1.5 stop bits +#define CST_2 2 + +// Set parity option +// +#define CMD_SETPAR(arg) \ + (((cmdSyntaxPtr)(ct10))->cmd[1] = (arg),(cmdSyntaxPtr)(ct10)) + +#define CSP_NP 0 // no parity +#define CSP_OD 1 // odd parity +#define CSP_EV 2 // Even parity +#define CSP_SP 3 // Space parity +#define CSP_MK 4 // Mark parity + +// Define xon char for transmitter flow control +// +#define CMD_DEF_IXON(arg) \ + (((cmdSyntaxPtr)(ct11))->cmd[1] = (arg),(cmdSyntaxPtr)(ct11)) + +// Define xoff char for transmitter flow control +// +#define CMD_DEF_IXOFF(arg) \ + (((cmdSyntaxPtr)(ct12))->cmd[1] = (arg),(cmdSyntaxPtr)(ct12)) + +#define CMD_STOPFL (cmdSyntaxPtr)(ct13) // Stop Flushing data + +// Acknowledge receipt of hotkey signal +// +#define CMD_HOTACK (cmdSyntaxPtr)(ct14) + +// Define irq level to use. Should actually be sent by library-level code, not +// directly from user... +// +#define CMDVALUE_IRQ 15 // For library use at initialization. Until this command + // is sent, board processing doesn't really start. +#define CMD_SET_IRQ(arg) \ + (((cmdSyntaxPtr)(ct15))->cmd[1] = (arg),(cmdSyntaxPtr)(ct15)) + +#define CIR_POLL 0 // No IRQ - Poll +#define CIR_3 3 // IRQ 3 +#define CIR_4 4 // IRQ 4 +#define CIR_5 5 // IRQ 5 +#define CIR_7 7 // IRQ 7 +#define CIR_10 10 // IRQ 10 +#define CIR_11 11 // IRQ 11 +#define CIR_12 12 // IRQ 12 +#define CIR_15 15 // IRQ 15 + +// Select transmit flow xon/xoff options +// +#define CMD_IXON_OPT(arg) \ + (((cmdSyntaxPtr)(ct16))->cmd[1] = (arg),(cmdSyntaxPtr)(ct16)) + +#define CIX_NONE 0 // Incoming Xon/Xoff characters not special +#define CIX_XON 1 // Xoff disable, Xon enable +#define CIX_XANY 2 // Xoff disable, any key enable + +// Select receive flow xon/xoff options +// +#define CMD_OXON_OPT(arg) \ + (((cmdSyntaxPtr)(ct17))->cmd[1] = (arg),(cmdSyntaxPtr)(ct17)) + +#define COX_NONE 0 // Don't send Xon/Xoff +#define COX_XON 1 // Send xon/xoff to start/stop incoming data + + +#define CMD_CTS_REP (cmdSyntaxPtr)(ct18) // Enable CTS reporting +#define CMD_CTS_NREP (cmdSyntaxPtr)(ct19) // Disable CTS reporting + +#define CMD_DCD_REP (cmdSyntaxPtr)(ct20) // Enable DCD reporting +#define CMD_DCD_NREP (cmdSyntaxPtr)(ct21) // Disable DCD reporting + +#define CMD_DSR_REP (cmdSyntaxPtr)(ct22) // Enable DSR reporting +#define CMD_DSR_NREP (cmdSyntaxPtr)(ct23) // Disable DSR reporting + +#define CMD_RI_REP (cmdSyntaxPtr)(ct24) // Enable RI reporting +#define CMD_RI_NREP (cmdSyntaxPtr)(ct25) // Disable RI reporting + +// Enable break reporting and select style +// +#define CMD_BRK_REP(arg) \ + (((cmdSyntaxPtr)(ct26))->cmd[1] = (arg),(cmdSyntaxPtr)(ct26)) + +#define CBK_STAT 0x00 // Report breaks as a status (exception,irq) +#define CBK_NULL 0x01 // Report breaks as a good null +#define CBK_STAT_SEQ 0x02 // Report breaks as a status AND as in-band character + // sequence FFh, 01h, 10h +#define CBK_SEQ 0x03 // Report breaks as the in-band + //sequence FFh, 01h, 10h ONLY. +#define CBK_FLSH 0x04 // if this bit set also flush input data +#define CBK_POSIX 0x08 // if this bit set report as FF,0,0 sequence +#define CBK_SINGLE 0x10 // if this bit set with CBK_SEQ or CBK_STAT_SEQ + //then reports single null instead of triple + +#define CMD_BRK_NREP (cmdSyntaxPtr)(ct27) // Disable break reporting + +// Specify maximum block size for received data +// +#define CMD_MAX_BLOCK(arg) \ + (((cmdSyntaxPtr)(ct28))->cmd[1] = (arg),(cmdSyntaxPtr)(ct28)) + +// -- COMMAND 29 is reserved -- + +#define CMD_CTSFL_ENAB (cmdSyntaxPtr)(ct30) // Enable CTS flow control +#define CMD_CTSFL_DSAB (cmdSyntaxPtr)(ct31) // Disable CTS flow control +#define CMD_RTSFL_ENAB (cmdSyntaxPtr)(ct32) // Enable RTS flow control +#define CMD_RTSFL_DSAB (cmdSyntaxPtr)(ct33) // Disable RTS flow control + +// Specify istrip option +// +#define CMD_ISTRIP_OPT(arg) \ + (((cmdSyntaxPtr)(ct34))->cmd[1] = (arg),(cmdSyntaxPtr)(ct34)) + +#define CIS_NOSTRIP 0 // Strip characters to character size +#define CIS_STRIP 1 // Strip any 8-bit characters to 7 bits + +// Send a break of arg milliseconds +// +#define CMD_SEND_BRK(arg) \ + (((cmdSyntaxPtr)(ct35))->cmd[1] = (arg),(cmdSyntaxPtr)(ct35)) + +// Set error reporting mode +// +#define CMD_SET_ERROR(arg) \ + (((cmdSyntaxPtr)(ct36))->cmd[1] = (arg),(cmdSyntaxPtr)(ct36)) + +#define CSE_ESTAT 0 // Report error in a status packet +#define CSE_NOREP 1 // Treat character as though it were good +#define CSE_DROP 2 // Discard the character +#define CSE_NULL 3 // Replace with a null +#define CSE_MARK 4 // Replace with a 3-character sequence (as Unix) + +#define CSE_REPLACE 0x8 // Replace the errored character with the + // replacement character defined here + +#define CSE_STAT_REPLACE 0x18 // Replace the errored character with the + // replacement character defined here AND + // report the error as a status packet (as in + // CSE_ESTAT). + + +// COMMAND 37, to send flow control packets, is handled only by low-level +// library code in response to data movement and shouldn't ever be sent by the +// user code. See i2pack.h and the body of i2lib.c for details. + +// Enable on-board post-processing, using options given in oflag argument. +// Formerly, this command was automatically preceded by a CMD_OPOST_OFF command +// because the loadware does not permit sending back-to-back CMD_OPOST_ON +// commands without an intervening CMD_OPOST_OFF. BUT, WE LEARN 18 MAY 92, that +// CMD_OPOST_ON and CMD_OPOST_OFF must each be at the end of a packet (or in a +// solo packet). This means the caller must specify separately CMD_OPOST_OFF, +// CMD_OPOST_ON(parm) when he calls i2QueueCommands(). That function will ensure +// each gets a separate packet. Extra CMD_OPOST_OFF's are always ok. +// +#define CMD_OPOST_ON(oflag) \ + (*(USHORT *)(((cmdSyntaxPtr)(ct39))->cmd[1]) = (oflag), \ + (cmdSyntaxPtr)(ct39)) + +#define CMD_OPOST_OFF (cmdSyntaxPtr)(ct40) // Disable on-board post-proc + +#define CMD_RESUME (cmdSyntaxPtr)(ct41) // Resume: behave as though an XON + // were received; + +// Set Transmit baud rate (see command 7 for arguments) +// +#define CMD_SETBAUD_TX(arg) \ + (((cmdSyntaxPtr)(ct42))->cmd[1] = (arg),(cmdSyntaxPtr)(ct42)) + +// Set Receive baud rate (see command 7 for arguments) +// +#define CMD_SETBAUD_RX(arg) \ + (((cmdSyntaxPtr)(ct43))->cmd[1] = (arg),(cmdSyntaxPtr)(ct43)) + +// Request interrupt from board each arg milliseconds. Interrupt will specify +// "received data", even though there may be no data present. If arg == 0, +// disables any such interrupts. +// +#define CMD_PING_REQ(arg) \ + (((cmdSyntaxPtr)(ct44))->cmd[1] = (arg),(cmdSyntaxPtr)(ct44)) + +#define CMD_HOT_ENAB (cmdSyntaxPtr)(ct45) // Enable Hot-key checking +#define CMD_HOT_DSAB (cmdSyntaxPtr)(ct46) // Disable Hot-key checking + +#if 0 +// COMMAND 47: Send Protocol info via Unix flags: +// iflag = Unix tty t_iflag +// cflag = Unix tty t_cflag +// lflag = Unix tty t_lflag +// See System V Unix/Xenix documentation for the meanings of the bit fields +// within these flags +// +#define CMD_UNIX_FLAGS(iflag,cflag,lflag) i2cmdUnixFlags(iflag,cflag,lflag) +#endif /* 0 */ + +#define CMD_DSRFL_ENAB (cmdSyntaxPtr)(ct48) // Enable DSR receiver ctrl +#define CMD_DSRFL_DSAB (cmdSyntaxPtr)(ct49) // Disable DSR receiver ctrl +#define CMD_DTRFL_ENAB (cmdSyntaxPtr)(ct50) // Enable DTR flow control +#define CMD_DTRFL_DSAB (cmdSyntaxPtr)(ct51) // Disable DTR flow control +#define CMD_BAUD_RESET (cmdSyntaxPtr)(ct52) // Reset baudrate table + +// COMMAND 54: Define custom rate #1 +// rate = (short) 1/10 of the desired baud rate +// +#define CMD_BAUD_DEF1(rate) i2cmdBaudDef(1,rate) + +// COMMAND 55: Define custom rate #2 +// rate = (short) 1/10 of the desired baud rate +// +#define CMD_BAUD_DEF2(rate) i2cmdBaudDef(2,rate) + +// Pause arg hundredths of seconds. (Note, this is NOT milliseconds.) +// +#define CMD_PAUSE(arg) \ + (((cmdSyntaxPtr)(ct56))->cmd[1] = (arg),(cmdSyntaxPtr)(ct56)) + +#define CMD_SUSPEND (cmdSyntaxPtr)(ct57) // Suspend output +#define CMD_UNSUSPEND (cmdSyntaxPtr)(ct58) // Un-Suspend output + +// Set parity-checking options +// +#define CMD_PARCHK(arg) \ + (((cmdSyntaxPtr)(ct59))->cmd[1] = (arg),(cmdSyntaxPtr)(ct59)) + +#define CPK_ENAB 0 // Enable parity checking on input +#define CPK_DSAB 1 // Disable parity checking on input + +#define CMD_BMARK_REQ (cmdSyntaxPtr)(ct60) // Bookmark request + + +// Enable/Disable internal loopback mode +// +#define CMD_INLOOP(arg) \ + (((cmdSyntaxPtr)(ct61))->cmd[1] = (arg),(cmdSyntaxPtr)(ct61)) + +#define CIN_DISABLE 0 // Normal operation (default) +#define CIN_ENABLE 1 // Internal (local) loopback +#define CIN_REMOTE 2 // Remote loopback + +// Specify timeout for hotkeys: Delay will be (arg x 10) milliseconds, arg == 0 +// --> no timeout: wait forever. +// +#define CMD_HOT_TIME(arg) \ + (((cmdSyntaxPtr)(ct62))->cmd[1] = (arg),(cmdSyntaxPtr)(ct62)) + + +// Define (outgoing) xon for receive flow control +// +#define CMD_DEF_OXON(arg) \ + (((cmdSyntaxPtr)(ct63))->cmd[1] = (arg),(cmdSyntaxPtr)(ct63)) + +// Define (outgoing) xoff for receiver flow control +// +#define CMD_DEF_OXOFF(arg) \ + (((cmdSyntaxPtr)(ct64))->cmd[1] = (arg),(cmdSyntaxPtr)(ct64)) + +// Enable/Disable RTS on transmit (1/2 duplex-style) +// +#define CMD_RTS_XMIT(arg) \ + (((cmdSyntaxPtr)(ct65))->cmd[1] = (arg),(cmdSyntaxPtr)(ct65)) + +#define CHD_DISABLE 0 +#define CHD_ENABLE 1 + +// Set high-water-mark level (debugging use only) +// +#define CMD_SETHIGHWAT(arg) \ + (((cmdSyntaxPtr)(ct66))->cmd[1] = (arg),(cmdSyntaxPtr)(ct66)) + +// Start flushing tagged data (tag = 0-14) +// +#define CMD_START_SELFL(tag) \ + (((cmdSyntaxPtr)(ct67))->cmd[1] = (tag),(cmdSyntaxPtr)(ct67)) + +// End flushing tagged data (tag = 0-14) +// +#define CMD_END_SELFL(tag) \ + (((cmdSyntaxPtr)(ct68))->cmd[1] = (tag),(cmdSyntaxPtr)(ct68)) + +#define CMD_HWFLOW_OFF (cmdSyntaxPtr)(ct69) // Disable HW TX flow control +#define CMD_ODSRFL_ENAB (cmdSyntaxPtr)(ct70) // Enable DSR output f/c +#define CMD_ODSRFL_DSAB (cmdSyntaxPtr)(ct71) // Disable DSR output f/c +#define CMD_ODCDFL_ENAB (cmdSyntaxPtr)(ct72) // Enable DCD output f/c +#define CMD_ODCDFL_DSAB (cmdSyntaxPtr)(ct73) // Disable DCD output f/c + +// Set transmit interrupt load level. Count should be an even value 2-12 +// +#define CMD_LOADLEVEL(count) \ + (((cmdSyntaxPtr)(ct74))->cmd[1] = (count),(cmdSyntaxPtr)(ct74)) + +// If reporting DSS changes, map to character sequence FFh, 2, MSR +// +#define CMD_STATDATA(arg) \ + (((cmdSyntaxPtr)(ct75))->cmd[1] = (arg),(cmdSyntaxPtr)(ct75)) + +#define CSTD_DISABLE// Report DSS changes as status packets only (default) +#define CSTD_ENABLE // Report DSS changes as in-band data sequence as well as + // by status packet. + +#define CMD_BREAK_ON (cmdSyntaxPtr)(ct76)// Set break and stop xmit +#define CMD_BREAK_OFF (cmdSyntaxPtr)(ct77)// End break and restart xmit +#define CMD_GETFC (cmdSyntaxPtr)(ct78)// Request for flow control packet + // from board. + +// Transmit this character immediately +// +#define CMD_XMIT_NOW(ch) \ + (((cmdSyntaxPtr)(ct79))->cmd[1] = (ch),(cmdSyntaxPtr)(ct79)) + +// Set baud rate via "divisor latch" +// +#define CMD_DIVISOR_LATCH(which,value) \ + (((cmdSyntaxPtr)(ct80))->cmd[1] = (which), \ + *(USHORT *)(((cmdSyntaxPtr)(ct80))->cmd[2]) = (value), \ + (cmdSyntaxPtr)(ct80)) + +#define CDL_RX 1 // Set receiver rate +#define CDL_TX 2 // Set transmit rate + // (CDL_TX | CDL_RX) Set both rates + +// Request for special diagnostic status pkt from the board. +// +#define CMD_GET_STATUS (cmdSyntaxPtr)(ct81) + +// Request time-stamped transmit character count packet. +// +#define CMD_GET_TXCNT (cmdSyntaxPtr)(ct82) + +// Request time-stamped receive character count packet. +// +#define CMD_GET_RXCNT (cmdSyntaxPtr)(ct83) + +// Request for box/board I.D. packet. +#define CMD_GET_BOXIDS (cmdSyntaxPtr)(ct84) + +// Enable or disable multiple channels according to bit-mapped ushorts box 1-4 +// +#define CMD_ENAB_MULT(enable, box1, box2, box3, box4) \ + (((cmdSytaxPtr)(ct85))->cmd[1] = (enable), \ + *(USHORT *)(((cmdSyntaxPtr)(ct85))->cmd[2]) = (box1), \ + *(USHORT *)(((cmdSyntaxPtr)(ct85))->cmd[4]) = (box2), \ + *(USHORT *)(((cmdSyntaxPtr)(ct85))->cmd[6]) = (box3), \ + *(USHORT *)(((cmdSyntaxPtr)(ct85))->cmd[8]) = (box4), \ + (cmdSyntaxPtr)(ct85)) + +#define CEM_DISABLE 0 +#define CEM_ENABLE 1 + +// Enable or disable receiver or receiver interrupts (default both enabled) +// +#define CMD_RCV_ENABLE(ch) \ + (((cmdSyntaxPtr)(ct86))->cmd[1] = (ch),(cmdSyntaxPtr)(ct86)) + +#define CRE_OFF 0 // Disable the receiver +#define CRE_ON 1 // Enable the receiver +#define CRE_INTOFF 2 // Disable receiver interrupts (to loadware) +#define CRE_INTON 3 // Enable receiver interrupts (to loadware) + +// Starts up a hardware test process, which runs transparently, and sends a +// STAT_HWFAIL packet in case a hardware failure is detected. +// +#define CMD_HW_TEST (cmdSyntaxPtr)(ct87) + +// Change receiver threshold and timeout value: +// Defaults: timeout = 20mS +// threshold count = 8 when DTRflow not in use, +// threshold count = 5 when DTRflow in use. +// +#define CMD_RCV_THRESHOLD(count,ms) \ + (((cmdSyntaxPtr)(ct88))->cmd[1] = (count), \ + ((cmdSyntaxPtr)(ct88))->cmd[2] = (ms), \ + (cmdSyntaxPtr)(ct88)) + +// Makes the loadware report DSS signals for this channel immediately. +// +#define CMD_DSS_NOW (cmdSyntaxPtr)(ct89) + +// Set the receive silo parameters +// timeout is ms idle wait until delivery (~VTIME) +// threshold is max characters cause interrupt (~VMIN) +// +#define CMD_SET_SILO(timeout,threshold) \ + (((cmdSyntaxPtr)(ct90))->cmd[1] = (timeout), \ + ((cmdSyntaxPtr)(ct90))->cmd[2] = (threshold), \ + (cmdSyntaxPtr)(ct90)) + +// Set timed break in decisecond (1/10s) +// +#define CMD_LBREAK(ds) \ + (((cmdSyntaxPtr)(ct91))->cmd[1] = (ds),(cmdSyntaxPtr)(ct66)) + + + +#endif // I2CMD_H diff --git a/drivers/staging/tty/ip2/i2ellis.c b/drivers/staging/tty/ip2/i2ellis.c new file mode 100644 index 000000000000..29db44de399f --- /dev/null +++ b/drivers/staging/tty/ip2/i2ellis.c @@ -0,0 +1,1403 @@ +/******************************************************************************* +* +* (c) 1998 by Computone Corporation +* +******************************************************************************** +* +* +* PACKAGE: Linux tty Device Driver for IntelliPort family of multiport +* serial I/O controllers. +* +* DESCRIPTION: Low-level interface code for the device driver +* (This is included source code, not a separate compilation +* module.) +* +*******************************************************************************/ +//--------------------------------------------- +// Function declarations private to this module +//--------------------------------------------- +// Functions called only indirectly through i2eBordStr entries. + +static int iiWriteBuf16(i2eBordStrPtr, unsigned char *, int); +static int iiWriteBuf8(i2eBordStrPtr, unsigned char *, int); +static int iiReadBuf16(i2eBordStrPtr, unsigned char *, int); +static int iiReadBuf8(i2eBordStrPtr, unsigned char *, int); + +static unsigned short iiReadWord16(i2eBordStrPtr); +static unsigned short iiReadWord8(i2eBordStrPtr); +static void iiWriteWord16(i2eBordStrPtr, unsigned short); +static void iiWriteWord8(i2eBordStrPtr, unsigned short); + +static int iiWaitForTxEmptyII(i2eBordStrPtr, int); +static int iiWaitForTxEmptyIIEX(i2eBordStrPtr, int); +static int iiTxMailEmptyII(i2eBordStrPtr); +static int iiTxMailEmptyIIEX(i2eBordStrPtr); +static int iiTrySendMailII(i2eBordStrPtr, unsigned char); +static int iiTrySendMailIIEX(i2eBordStrPtr, unsigned char); + +static unsigned short iiGetMailII(i2eBordStrPtr); +static unsigned short iiGetMailIIEX(i2eBordStrPtr); + +static void iiEnableMailIrqII(i2eBordStrPtr); +static void iiEnableMailIrqIIEX(i2eBordStrPtr); +static void iiWriteMaskII(i2eBordStrPtr, unsigned char); +static void iiWriteMaskIIEX(i2eBordStrPtr, unsigned char); + +static void ii2Nop(void); + +//*************** +//* Static Data * +//*************** + +static int ii2Safe; // Safe I/O address for delay routine + +static int iiDelayed; // Set when the iiResetDelay function is + // called. Cleared when ANY board is reset. +static DEFINE_RWLOCK(Dl_spinlock); + +//******** +//* Code * +//******** + +//======================================================= +// Initialization Routines +// +// iiSetAddress +// iiReset +// iiResetDelay +// iiInitialize +//======================================================= + +//****************************************************************************** +// Function: iiSetAddress(pB, address, delay) +// Parameters: pB - pointer to the board structure +// address - the purported I/O address of the board +// delay - pointer to the 1-ms delay function to use +// in this and any future operations to this board +// +// Returns: True if everything appears copacetic. +// False if there is any error: the pB->i2eError field has the error +// +// Description: +// +// This routine (roughly) checks for address validity, sets the i2eValid OK and +// sets the state to II_STATE_COLD which means that we haven't even sent a reset +// yet. +// +//****************************************************************************** +static int +iiSetAddress( i2eBordStrPtr pB, int address, delayFunc_t delay ) +{ + // Should any failure occur before init is finished... + pB->i2eValid = I2E_INCOMPLETE; + + // Cannot check upper limit except extremely: Might be microchannel + // Address must be on an 8-byte boundary + + if ((unsigned int)address <= 0x100 + || (unsigned int)address >= 0xfff8 + || (address & 0x7) + ) + { + I2_COMPLETE(pB, I2EE_BADADDR); + } + + // Initialize accelerators + pB->i2eBase = address; + pB->i2eData = address + FIFO_DATA; + pB->i2eStatus = address + FIFO_STATUS; + pB->i2ePointer = address + FIFO_PTR; + pB->i2eXMail = address + FIFO_MAIL; + pB->i2eXMask = address + FIFO_MASK; + + // Initialize i/o address for ii2DelayIO + ii2Safe = address + FIFO_NOP; + + // Initialize the delay routine + pB->i2eDelay = ((delay != (delayFunc_t)NULL) ? delay : (delayFunc_t)ii2Nop); + + pB->i2eValid = I2E_MAGIC; + pB->i2eState = II_STATE_COLD; + + I2_COMPLETE(pB, I2EE_GOOD); +} + +//****************************************************************************** +// Function: iiReset(pB) +// Parameters: pB - pointer to the board structure +// +// Returns: True if everything appears copacetic. +// False if there is any error: the pB->i2eError field has the error +// +// Description: +// +// Attempts to reset the board (see also i2hw.h). Normally, we would use this to +// reset a board immediately after iiSetAddress(), but it is valid to reset a +// board from any state, say, in order to change or re-load loadware. (Under +// such circumstances, no reason to re-run iiSetAddress(), which is why it is a +// separate routine and not included in this routine. +// +//****************************************************************************** +static int +iiReset(i2eBordStrPtr pB) +{ + // Magic number should be set, else even the address is suspect + if (pB->i2eValid != I2E_MAGIC) + { + I2_COMPLETE(pB, I2EE_BADMAGIC); + } + + outb(0, pB->i2eBase + FIFO_RESET); /* Any data will do */ + iiDelay(pB, 50); // Pause between resets + outb(0, pB->i2eBase + FIFO_RESET); /* Second reset */ + + // We must wait before even attempting to read anything from the FIFO: the + // board's P.O.S.T may actually attempt to read and write its end of the + // FIFO in order to check flags, loop back (where supported), etc. On + // completion of this testing it would reset the FIFO, and on completion + // of all // P.O.S.T., write the message. We must not mistake data which + // might have been sent for testing as part of the reset message. To + // better utilize time, say, when resetting several boards, we allow the + // delay to be performed externally; in this way the caller can reset + // several boards, delay a single time, then call the initialization + // routine for all. + + pB->i2eState = II_STATE_RESET; + + iiDelayed = 0; // i.e., the delay routine hasn't been called since the most + // recent reset. + + // Ensure anything which would have been of use to standard loadware is + // blanked out, since board has now forgotten everything!. + + pB->i2eUsingIrq = I2_IRQ_UNDEFINED; /* to not use an interrupt so far */ + pB->i2eWaitingForEmptyFifo = 0; + pB->i2eOutMailWaiting = 0; + pB->i2eChannelPtr = NULL; + pB->i2eChannelCnt = 0; + + pB->i2eLeadoffWord[0] = 0; + pB->i2eFifoInInts = 0; + pB->i2eFifoOutInts = 0; + pB->i2eFatalTrap = NULL; + pB->i2eFatal = 0; + + I2_COMPLETE(pB, I2EE_GOOD); +} + +//****************************************************************************** +// Function: iiResetDelay(pB) +// Parameters: pB - pointer to the board structure +// +// Returns: True if everything appears copacetic. +// False if there is any error: the pB->i2eError field has the error +// +// Description: +// +// Using the delay defined in board structure, waits two seconds (for board to +// reset). +// +//****************************************************************************** +static int +iiResetDelay(i2eBordStrPtr pB) +{ + if (pB->i2eValid != I2E_MAGIC) { + I2_COMPLETE(pB, I2EE_BADMAGIC); + } + if (pB->i2eState != II_STATE_RESET) { + I2_COMPLETE(pB, I2EE_BADSTATE); + } + iiDelay(pB,2000); /* Now we wait for two seconds. */ + iiDelayed = 1; /* Delay has been called: ok to initialize */ + I2_COMPLETE(pB, I2EE_GOOD); +} + +//****************************************************************************** +// Function: iiInitialize(pB) +// Parameters: pB - pointer to the board structure +// +// Returns: True if everything appears copacetic. +// False if there is any error: the pB->i2eError field has the error +// +// Description: +// +// Attempts to read the Power-on reset message. Initializes any remaining fields +// in the pB structure. +// +// This should be called as the third step of a process beginning with +// iiReset(), then iiResetDelay(). This routine checks to see that the structure +// is "valid" and in the reset state, also confirms that the delay routine has +// been called since the latest reset (to any board! overly strong!). +// +//****************************************************************************** +static int +iiInitialize(i2eBordStrPtr pB) +{ + int itemp; + unsigned char c; + unsigned short utemp; + unsigned int ilimit; + + if (pB->i2eValid != I2E_MAGIC) + { + I2_COMPLETE(pB, I2EE_BADMAGIC); + } + + if (pB->i2eState != II_STATE_RESET || !iiDelayed) + { + I2_COMPLETE(pB, I2EE_BADSTATE); + } + + // In case there is a failure short of our completely reading the power-up + // message. + pB->i2eValid = I2E_INCOMPLETE; + + + // Now attempt to read the message. + + for (itemp = 0; itemp < sizeof(porStr); itemp++) + { + // We expect the entire message is ready. + if (!I2_HAS_INPUT(pB)) { + pB->i2ePomSize = itemp; + I2_COMPLETE(pB, I2EE_PORM_SHORT); + } + + pB->i2ePom.c[itemp] = c = inb(pB->i2eData); + + // We check the magic numbers as soon as they are supposed to be read + // (rather than after) to minimize effect of reading something we + // already suspect can't be "us". + if ( (itemp == POR_1_INDEX && c != POR_MAGIC_1) || + (itemp == POR_2_INDEX && c != POR_MAGIC_2)) + { + pB->i2ePomSize = itemp+1; + I2_COMPLETE(pB, I2EE_BADMAGIC); + } + } + + pB->i2ePomSize = itemp; + + // Ensure that this was all the data... + if (I2_HAS_INPUT(pB)) + I2_COMPLETE(pB, I2EE_PORM_LONG); + + // For now, we'll fail to initialize if P.O.S.T reports bad chip mapper: + // Implying we will not be able to download any code either: That's ok: the + // condition is pretty explicit. + if (pB->i2ePom.e.porDiag1 & POR_BAD_MAPPER) + { + I2_COMPLETE(pB, I2EE_POSTERR); + } + + // Determine anything which must be done differently depending on the family + // of boards! + switch (pB->i2ePom.e.porID & POR_ID_FAMILY) + { + case POR_ID_FII: // IntelliPort-II + + pB->i2eFifoStyle = FIFO_II; + pB->i2eFifoSize = 512; // 512 bytes, always + pB->i2eDataWidth16 = false; + + pB->i2eMaxIrq = 15; // Because board cannot tell us it is in an 8-bit + // slot, we do allow it to be done (documentation!) + + pB->i2eGoodMap[1] = + pB->i2eGoodMap[2] = + pB->i2eGoodMap[3] = + pB->i2eChannelMap[1] = + pB->i2eChannelMap[2] = + pB->i2eChannelMap[3] = 0; + + switch (pB->i2ePom.e.porID & POR_ID_SIZE) + { + case POR_ID_II_4: + pB->i2eGoodMap[0] = + pB->i2eChannelMap[0] = 0x0f; // four-port + + // Since porPorts1 is based on the Hardware ID register, the numbers + // should always be consistent for IntelliPort-II. Ditto below... + if (pB->i2ePom.e.porPorts1 != 4) + { + I2_COMPLETE(pB, I2EE_INCONSIST); + } + break; + + case POR_ID_II_8: + case POR_ID_II_8R: + pB->i2eGoodMap[0] = + pB->i2eChannelMap[0] = 0xff; // Eight port + if (pB->i2ePom.e.porPorts1 != 8) + { + I2_COMPLETE(pB, I2EE_INCONSIST); + } + break; + + case POR_ID_II_6: + pB->i2eGoodMap[0] = + pB->i2eChannelMap[0] = 0x3f; // Six Port + if (pB->i2ePom.e.porPorts1 != 6) + { + I2_COMPLETE(pB, I2EE_INCONSIST); + } + break; + } + + // Fix up the "good channel list based on any errors reported. + if (pB->i2ePom.e.porDiag1 & POR_BAD_UART1) + { + pB->i2eGoodMap[0] &= ~0x0f; + } + + if (pB->i2ePom.e.porDiag1 & POR_BAD_UART2) + { + pB->i2eGoodMap[0] &= ~0xf0; + } + + break; // POR_ID_FII case + + case POR_ID_FIIEX: // IntelliPort-IIEX + + pB->i2eFifoStyle = FIFO_IIEX; + + itemp = pB->i2ePom.e.porFifoSize; + + // Implicit assumption that fifo would not grow beyond 32k, + // nor would ever be less than 256. + + if (itemp < 8 || itemp > 15) + { + I2_COMPLETE(pB, I2EE_INCONSIST); + } + pB->i2eFifoSize = (1 << itemp); + + // These are based on what P.O.S.T thinks should be there, based on + // box ID registers + ilimit = pB->i2ePom.e.porNumBoxes; + if (ilimit > ABS_MAX_BOXES) + { + ilimit = ABS_MAX_BOXES; + } + + // For as many boxes as EXIST, gives the type of box. + // Added 8/6/93: check for the ISA-4 (asic) which looks like an + // expandable but for whom "8 or 16?" is not the right question. + + utemp = pB->i2ePom.e.porFlags; + if (utemp & POR_CEX4) + { + pB->i2eChannelMap[0] = 0x000f; + } else { + utemp &= POR_BOXES; + for (itemp = 0; itemp < ilimit; itemp++) + { + pB->i2eChannelMap[itemp] = + ((utemp & POR_BOX_16) ? 0xffff : 0x00ff); + utemp >>= 1; + } + } + + // These are based on what P.O.S.T actually found. + + utemp = (pB->i2ePom.e.porPorts2 << 8) + pB->i2ePom.e.porPorts1; + + for (itemp = 0; itemp < ilimit; itemp++) + { + pB->i2eGoodMap[itemp] = 0; + if (utemp & 1) pB->i2eGoodMap[itemp] |= 0x000f; + if (utemp & 2) pB->i2eGoodMap[itemp] |= 0x00f0; + if (utemp & 4) pB->i2eGoodMap[itemp] |= 0x0f00; + if (utemp & 8) pB->i2eGoodMap[itemp] |= 0xf000; + utemp >>= 4; + } + + // Now determine whether we should transfer in 8 or 16-bit mode. + switch (pB->i2ePom.e.porBus & (POR_BUS_SLOT16 | POR_BUS_DIP16) ) + { + case POR_BUS_SLOT16 | POR_BUS_DIP16: + pB->i2eDataWidth16 = true; + pB->i2eMaxIrq = 15; + break; + + case POR_BUS_SLOT16: + pB->i2eDataWidth16 = false; + pB->i2eMaxIrq = 15; + break; + + case 0: + case POR_BUS_DIP16: // In an 8-bit slot, DIP switch don't care. + default: + pB->i2eDataWidth16 = false; + pB->i2eMaxIrq = 7; + break; + } + break; // POR_ID_FIIEX case + + default: // Unknown type of board + I2_COMPLETE(pB, I2EE_BAD_FAMILY); + break; + } // End the switch based on family + + // Temporarily, claim there is no room in the outbound fifo. + // We will maintain this whenever we check for an empty outbound FIFO. + pB->i2eFifoRemains = 0; + + // Now, based on the bus type, should we expect to be able to re-configure + // interrupts (say, for testing purposes). + switch (pB->i2ePom.e.porBus & POR_BUS_TYPE) + { + case POR_BUS_T_ISA: + case POR_BUS_T_UNK: // If the type of bus is undeclared, assume ok. + case POR_BUS_T_MCA: + case POR_BUS_T_EISA: + break; + default: + I2_COMPLETE(pB, I2EE_BADBUS); + } + + if (pB->i2eDataWidth16) + { + pB->i2eWriteBuf = iiWriteBuf16; + pB->i2eReadBuf = iiReadBuf16; + pB->i2eWriteWord = iiWriteWord16; + pB->i2eReadWord = iiReadWord16; + } else { + pB->i2eWriteBuf = iiWriteBuf8; + pB->i2eReadBuf = iiReadBuf8; + pB->i2eWriteWord = iiWriteWord8; + pB->i2eReadWord = iiReadWord8; + } + + switch(pB->i2eFifoStyle) + { + case FIFO_II: + pB->i2eWaitForTxEmpty = iiWaitForTxEmptyII; + pB->i2eTxMailEmpty = iiTxMailEmptyII; + pB->i2eTrySendMail = iiTrySendMailII; + pB->i2eGetMail = iiGetMailII; + pB->i2eEnableMailIrq = iiEnableMailIrqII; + pB->i2eWriteMask = iiWriteMaskII; + + break; + + case FIFO_IIEX: + pB->i2eWaitForTxEmpty = iiWaitForTxEmptyIIEX; + pB->i2eTxMailEmpty = iiTxMailEmptyIIEX; + pB->i2eTrySendMail = iiTrySendMailIIEX; + pB->i2eGetMail = iiGetMailIIEX; + pB->i2eEnableMailIrq = iiEnableMailIrqIIEX; + pB->i2eWriteMask = iiWriteMaskIIEX; + + break; + + default: + I2_COMPLETE(pB, I2EE_INCONSIST); + } + + // Initialize state information. + pB->i2eState = II_STATE_READY; // Ready to load loadware. + + // Some Final cleanup: + // For some boards, the bootstrap firmware may perform some sort of test + // resulting in a stray character pending in the incoming mailbox. If one is + // there, it should be read and discarded, especially since for the standard + // firmware, it's the mailbox that interrupts the host. + + pB->i2eStartMail = iiGetMail(pB); + + // Throw it away and clear the mailbox structure element + pB->i2eStartMail = NO_MAIL_HERE; + + // Everything is ok now, return with good status/ + + pB->i2eValid = I2E_MAGIC; + I2_COMPLETE(pB, I2EE_GOOD); +} + +//****************************************************************************** +// Function: ii2DelayTimer(mseconds) +// Parameters: mseconds - number of milliseconds to delay +// +// Returns: Nothing +// +// Description: +// +// This routine delays for approximately mseconds milliseconds and is intended +// to be called indirectly through i2Delay field in i2eBordStr. It uses the +// Linux timer_list mechanism. +// +// The Linux timers use a unit called "jiffies" which are 10mS in the Intel +// architecture. This function rounds the delay period up to the next "jiffy". +// In the Alpha architecture the "jiffy" is 1mS, but this driver is not intended +// for Alpha platforms at this time. +// +//****************************************************************************** +static void +ii2DelayTimer(unsigned int mseconds) +{ + msleep_interruptible(mseconds); +} + +#if 0 +//static void ii2DelayIO(unsigned int); +//****************************************************************************** +// !!! Not Used, this is DOS crap, some of you young folks may be interested in +// in how things were done in the stone age of caculating machines !!! +// Function: ii2DelayIO(mseconds) +// Parameters: mseconds - number of milliseconds to delay +// +// Returns: Nothing +// +// Description: +// +// This routine delays for approximately mseconds milliseconds and is intended +// to be called indirectly through i2Delay field in i2eBordStr. It is intended +// for use where a clock-based function is impossible: for example, DOS drivers. +// +// This function uses the IN instruction to place bounds on the timing and +// assumes that ii2Safe has been set. This is because I/O instructions are not +// subject to caching and will therefore take a certain minimum time. To ensure +// the delay is at least long enough on fast machines, it is based on some +// fastest-case calculations. On slower machines this may cause VERY long +// delays. (3 x fastest case). In the fastest case, everything is cached except +// the I/O instruction itself. +// +// Timing calculations: +// The fastest bus speed for I/O operations is likely to be 10 MHz. The I/O +// operation in question is a byte operation to an odd address. For 8-bit +// operations, the architecture generally enforces two wait states. At 10 MHz, a +// single cycle time is 100nS. A read operation at two wait states takes 6 +// cycles for a total time of 600nS. Therefore approximately 1666 iterations +// would be required to generate a single millisecond delay. The worst +// (reasonable) case would be an 8MHz system with no cacheing. In this case, the +// I/O instruction would take 125nS x 6 cyles = 750 nS. More importantly, code +// fetch of other instructions in the loop would take time (zero wait states, +// however) and would be hard to estimate. This is minimized by using in-line +// assembler for the in inner loop of IN instructions. This consists of just a +// few bytes. So we'll guess about four code fetches per loop. Each code fetch +// should take four cycles, so we have 125nS * 8 = 1000nS. Worst case then is +// that what should have taken 1 mS takes instead 1666 * (1750) = 2.9 mS. +// +// So much for theoretical timings: results using 1666 value on some actual +// machines: +// IBM 286 6MHz 3.15 mS +// Zenith 386 33MHz 2.45 mS +// (brandX) 386 33MHz 1.90 mS (has cache) +// (brandY) 486 33MHz 2.35 mS +// NCR 486 ?? 1.65 mS (microchannel) +// +// For most machines, it is probably safe to scale this number back (remember, +// for robust operation use an actual timed delay if possible), so we are using +// a value of 1190. This yields 1.17 mS for the fastest machine in our sample, +// 1.75 mS for typical 386 machines, and 2.25 mS the absolute slowest machine. +// +// 1/29/93: +// The above timings are too slow. Actual cycle times might be faster. ISA cycle +// times could approach 500 nS, and ... +// The IBM model 77 being microchannel has no wait states for 8-bit reads and +// seems to be accessing the I/O at 440 nS per access (from start of one to +// start of next). This would imply we need 1000/.440 = 2272 iterations to +// guarantee we are fast enough. In actual testing, we see that 2 * 1190 are in +// fact enough. For diagnostics, we keep the level at 1190, but developers note +// this needs tuning. +// +// Safe assumption: 2270 i/o reads = 1 millisecond +// +//****************************************************************************** + + +static int ii2DelValue = 1190; // See timing calculations below + // 1666 for fastest theoretical machine + // 1190 safe for most fast 386 machines + // 1000 for fastest machine tested here + // 540 (sic) for AT286/6Mhz +static void +ii2DelayIO(unsigned int mseconds) +{ + if (!ii2Safe) + return; /* Do nothing if this variable uninitialized */ + + while(mseconds--) { + int i = ii2DelValue; + while ( i-- ) { + inb(ii2Safe); + } + } +} +#endif + +//****************************************************************************** +// Function: ii2Nop() +// Parameters: None +// +// Returns: Nothing +// +// Description: +// +// iiInitialize will set i2eDelay to this if the delay parameter is NULL. This +// saves checking for a NULL pointer at every call. +//****************************************************************************** +static void +ii2Nop(void) +{ + return; // no mystery here +} + +//======================================================= +// Routines which are available in 8/16-bit versions, or +// in different fifo styles. These are ALL called +// indirectly through the board structure. +//======================================================= + +//****************************************************************************** +// Function: iiWriteBuf16(pB, address, count) +// Parameters: pB - pointer to board structure +// address - address of data to write +// count - number of data bytes to write +// +// Returns: True if everything appears copacetic. +// False if there is any error: the pB->i2eError field has the error +// +// Description: +// +// Writes 'count' bytes from 'address' to the data fifo specified by the board +// structure pointer pB. Should count happen to be odd, an extra pad byte is +// sent (identity unknown...). Uses 16-bit (word) operations. Is called +// indirectly through pB->i2eWriteBuf. +// +//****************************************************************************** +static int +iiWriteBuf16(i2eBordStrPtr pB, unsigned char *address, int count) +{ + // Rudimentary sanity checking here. + if (pB->i2eValid != I2E_MAGIC) + I2_COMPLETE(pB, I2EE_INVALID); + + I2_OUTSW(pB->i2eData, address, count); + + I2_COMPLETE(pB, I2EE_GOOD); +} + +//****************************************************************************** +// Function: iiWriteBuf8(pB, address, count) +// Parameters: pB - pointer to board structure +// address - address of data to write +// count - number of data bytes to write +// +// Returns: True if everything appears copacetic. +// False if there is any error: the pB->i2eError field has the error +// +// Description: +// +// Writes 'count' bytes from 'address' to the data fifo specified by the board +// structure pointer pB. Should count happen to be odd, an extra pad byte is +// sent (identity unknown...). This is to be consistent with the 16-bit version. +// Uses 8-bit (byte) operations. Is called indirectly through pB->i2eWriteBuf. +// +//****************************************************************************** +static int +iiWriteBuf8(i2eBordStrPtr pB, unsigned char *address, int count) +{ + /* Rudimentary sanity checking here */ + if (pB->i2eValid != I2E_MAGIC) + I2_COMPLETE(pB, I2EE_INVALID); + + I2_OUTSB(pB->i2eData, address, count); + + I2_COMPLETE(pB, I2EE_GOOD); +} + +//****************************************************************************** +// Function: iiReadBuf16(pB, address, count) +// Parameters: pB - pointer to board structure +// address - address to put data read +// count - number of data bytes to read +// +// Returns: True if everything appears copacetic. +// False if there is any error: the pB->i2eError field has the error +// +// Description: +// +// Reads 'count' bytes into 'address' from the data fifo specified by the board +// structure pointer pB. Should count happen to be odd, an extra pad byte is +// received (identity unknown...). Uses 16-bit (word) operations. Is called +// indirectly through pB->i2eReadBuf. +// +//****************************************************************************** +static int +iiReadBuf16(i2eBordStrPtr pB, unsigned char *address, int count) +{ + // Rudimentary sanity checking here. + if (pB->i2eValid != I2E_MAGIC) + I2_COMPLETE(pB, I2EE_INVALID); + + I2_INSW(pB->i2eData, address, count); + + I2_COMPLETE(pB, I2EE_GOOD); +} + +//****************************************************************************** +// Function: iiReadBuf8(pB, address, count) +// Parameters: pB - pointer to board structure +// address - address to put data read +// count - number of data bytes to read +// +// Returns: True if everything appears copacetic. +// False if there is any error: the pB->i2eError field has the error +// +// Description: +// +// Reads 'count' bytes into 'address' from the data fifo specified by the board +// structure pointer pB. Should count happen to be odd, an extra pad byte is +// received (identity unknown...). This to match the 16-bit behaviour. Uses +// 8-bit (byte) operations. Is called indirectly through pB->i2eReadBuf. +// +//****************************************************************************** +static int +iiReadBuf8(i2eBordStrPtr pB, unsigned char *address, int count) +{ + // Rudimentary sanity checking here. + if (pB->i2eValid != I2E_MAGIC) + I2_COMPLETE(pB, I2EE_INVALID); + + I2_INSB(pB->i2eData, address, count); + + I2_COMPLETE(pB, I2EE_GOOD); +} + +//****************************************************************************** +// Function: iiReadWord16(pB) +// Parameters: pB - pointer to board structure +// +// Returns: True if everything appears copacetic. +// False if there is any error: the pB->i2eError field has the error +// +// Description: +// +// Returns the word read from the data fifo specified by the board-structure +// pointer pB. Uses a 16-bit operation. Is called indirectly through +// pB->i2eReadWord. +// +//****************************************************************************** +static unsigned short +iiReadWord16(i2eBordStrPtr pB) +{ + return inw(pB->i2eData); +} + +//****************************************************************************** +// Function: iiReadWord8(pB) +// Parameters: pB - pointer to board structure +// +// Returns: True if everything appears copacetic. +// False if there is any error: the pB->i2eError field has the error +// +// Description: +// +// Returns the word read from the data fifo specified by the board-structure +// pointer pB. Uses two 8-bit operations. Bytes are assumed to be LSB first. Is +// called indirectly through pB->i2eReadWord. +// +//****************************************************************************** +static unsigned short +iiReadWord8(i2eBordStrPtr pB) +{ + unsigned short urs; + + urs = inb(pB->i2eData); + + return (inb(pB->i2eData) << 8) | urs; +} + +//****************************************************************************** +// Function: iiWriteWord16(pB, value) +// Parameters: pB - pointer to board structure +// value - data to write +// +// Returns: True if everything appears copacetic. +// False if there is any error: the pB->i2eError field has the error +// +// Description: +// +// Writes the word 'value' to the data fifo specified by the board-structure +// pointer pB. Uses 16-bit operation. Is called indirectly through +// pB->i2eWriteWord. +// +//****************************************************************************** +static void +iiWriteWord16(i2eBordStrPtr pB, unsigned short value) +{ + outw((int)value, pB->i2eData); +} + +//****************************************************************************** +// Function: iiWriteWord8(pB, value) +// Parameters: pB - pointer to board structure +// value - data to write +// +// Returns: True if everything appears copacetic. +// False if there is any error: the pB->i2eError field has the error +// +// Description: +// +// Writes the word 'value' to the data fifo specified by the board-structure +// pointer pB. Uses two 8-bit operations (writes LSB first). Is called +// indirectly through pB->i2eWriteWord. +// +//****************************************************************************** +static void +iiWriteWord8(i2eBordStrPtr pB, unsigned short value) +{ + outb((char)value, pB->i2eData); + outb((char)(value >> 8), pB->i2eData); +} + +//****************************************************************************** +// Function: iiWaitForTxEmptyII(pB, mSdelay) +// Parameters: pB - pointer to board structure +// mSdelay - period to wait before returning +// +// Returns: True if the FIFO is empty. +// False if it not empty in the required time: the pB->i2eError +// field has the error. +// +// Description: +// +// Waits up to "mSdelay" milliseconds for the outgoing FIFO to become empty; if +// not empty by the required time, returns false and error in pB->i2eError, +// otherwise returns true. +// +// mSdelay == 0 is taken to mean must be empty on the first test. +// +// This version operates on IntelliPort-II - style FIFO's +// +// Note this routine is organized so that if status is ok there is no delay at +// all called either before or after the test. Is called indirectly through +// pB->i2eWaitForTxEmpty. +// +//****************************************************************************** +static int +iiWaitForTxEmptyII(i2eBordStrPtr pB, int mSdelay) +{ + unsigned long flags; + int itemp; + + for (;;) + { + // This routine hinges on being able to see the "other" status register + // (as seen by the local processor). His incoming fifo is our outgoing + // FIFO. + // + // By the nature of this routine, you would be using this as part of a + // larger atomic context: i.e., you would use this routine to ensure the + // fifo empty, then act on this information. Between these two halves, + // you will generally not want to service interrupts or in any way + // disrupt the assumptions implicit in the larger context. + // + // Even worse, however, this routine "shifts" the status register to + // point to the local status register which is not the usual situation. + // Therefore for extra safety, we force the critical section to be + // completely atomic, and pick up after ourselves before allowing any + // interrupts of any kind. + + + write_lock_irqsave(&Dl_spinlock, flags); + outb(SEL_COMMAND, pB->i2ePointer); + outb(SEL_CMD_SH, pB->i2ePointer); + + itemp = inb(pB->i2eStatus); + + outb(SEL_COMMAND, pB->i2ePointer); + outb(SEL_CMD_UNSH, pB->i2ePointer); + + if (itemp & ST_IN_EMPTY) + { + I2_UPDATE_FIFO_ROOM(pB); + write_unlock_irqrestore(&Dl_spinlock, flags); + I2_COMPLETE(pB, I2EE_GOOD); + } + + write_unlock_irqrestore(&Dl_spinlock, flags); + + if (mSdelay-- == 0) + break; + + iiDelay(pB, 1); /* 1 mS granularity on checking condition */ + } + I2_COMPLETE(pB, I2EE_TXE_TIME); +} + +//****************************************************************************** +// Function: iiWaitForTxEmptyIIEX(pB, mSdelay) +// Parameters: pB - pointer to board structure +// mSdelay - period to wait before returning +// +// Returns: True if the FIFO is empty. +// False if it not empty in the required time: the pB->i2eError +// field has the error. +// +// Description: +// +// Waits up to "mSdelay" milliseconds for the outgoing FIFO to become empty; if +// not empty by the required time, returns false and error in pB->i2eError, +// otherwise returns true. +// +// mSdelay == 0 is taken to mean must be empty on the first test. +// +// This version operates on IntelliPort-IIEX - style FIFO's +// +// Note this routine is organized so that if status is ok there is no delay at +// all called either before or after the test. Is called indirectly through +// pB->i2eWaitForTxEmpty. +// +//****************************************************************************** +static int +iiWaitForTxEmptyIIEX(i2eBordStrPtr pB, int mSdelay) +{ + unsigned long flags; + + for (;;) + { + // By the nature of this routine, you would be using this as part of a + // larger atomic context: i.e., you would use this routine to ensure the + // fifo empty, then act on this information. Between these two halves, + // you will generally not want to service interrupts or in any way + // disrupt the assumptions implicit in the larger context. + + write_lock_irqsave(&Dl_spinlock, flags); + + if (inb(pB->i2eStatus) & STE_OUT_MT) { + I2_UPDATE_FIFO_ROOM(pB); + write_unlock_irqrestore(&Dl_spinlock, flags); + I2_COMPLETE(pB, I2EE_GOOD); + } + write_unlock_irqrestore(&Dl_spinlock, flags); + + if (mSdelay-- == 0) + break; + + iiDelay(pB, 1); // 1 mS granularity on checking condition + } + I2_COMPLETE(pB, I2EE_TXE_TIME); +} + +//****************************************************************************** +// Function: iiTxMailEmptyII(pB) +// Parameters: pB - pointer to board structure +// +// Returns: True if the transmit mailbox is empty. +// False if it not empty. +// +// Description: +// +// Returns true or false according to whether the transmit mailbox is empty (and +// therefore able to accept more mail) +// +// This version operates on IntelliPort-II - style FIFO's +// +//****************************************************************************** +static int +iiTxMailEmptyII(i2eBordStrPtr pB) +{ + int port = pB->i2ePointer; + outb(SEL_OUTMAIL, port); + return inb(port) == 0; +} + +//****************************************************************************** +// Function: iiTxMailEmptyIIEX(pB) +// Parameters: pB - pointer to board structure +// +// Returns: True if the transmit mailbox is empty. +// False if it not empty. +// +// Description: +// +// Returns true or false according to whether the transmit mailbox is empty (and +// therefore able to accept more mail) +// +// This version operates on IntelliPort-IIEX - style FIFO's +// +//****************************************************************************** +static int +iiTxMailEmptyIIEX(i2eBordStrPtr pB) +{ + return !(inb(pB->i2eStatus) & STE_OUT_MAIL); +} + +//****************************************************************************** +// Function: iiTrySendMailII(pB,mail) +// Parameters: pB - pointer to board structure +// mail - value to write to mailbox +// +// Returns: True if the transmit mailbox is empty, and mail is sent. +// False if it not empty. +// +// Description: +// +// If outgoing mailbox is empty, sends mail and returns true. If outgoing +// mailbox is not empty, returns false. +// +// This version operates on IntelliPort-II - style FIFO's +// +//****************************************************************************** +static int +iiTrySendMailII(i2eBordStrPtr pB, unsigned char mail) +{ + int port = pB->i2ePointer; + + outb(SEL_OUTMAIL, port); + if (inb(port) == 0) { + outb(SEL_OUTMAIL, port); + outb(mail, port); + return 1; + } + return 0; +} + +//****************************************************************************** +// Function: iiTrySendMailIIEX(pB,mail) +// Parameters: pB - pointer to board structure +// mail - value to write to mailbox +// +// Returns: True if the transmit mailbox is empty, and mail is sent. +// False if it not empty. +// +// Description: +// +// If outgoing mailbox is empty, sends mail and returns true. If outgoing +// mailbox is not empty, returns false. +// +// This version operates on IntelliPort-IIEX - style FIFO's +// +//****************************************************************************** +static int +iiTrySendMailIIEX(i2eBordStrPtr pB, unsigned char mail) +{ + if (inb(pB->i2eStatus) & STE_OUT_MAIL) + return 0; + outb(mail, pB->i2eXMail); + return 1; +} + +//****************************************************************************** +// Function: iiGetMailII(pB,mail) +// Parameters: pB - pointer to board structure +// +// Returns: Mailbox data or NO_MAIL_HERE. +// +// Description: +// +// If no mail available, returns NO_MAIL_HERE otherwise returns the data from +// the mailbox, which is guaranteed != NO_MAIL_HERE. +// +// This version operates on IntelliPort-II - style FIFO's +// +//****************************************************************************** +static unsigned short +iiGetMailII(i2eBordStrPtr pB) +{ + if (I2_HAS_MAIL(pB)) { + outb(SEL_INMAIL, pB->i2ePointer); + return inb(pB->i2ePointer); + } else { + return NO_MAIL_HERE; + } +} + +//****************************************************************************** +// Function: iiGetMailIIEX(pB,mail) +// Parameters: pB - pointer to board structure +// +// Returns: Mailbox data or NO_MAIL_HERE. +// +// Description: +// +// If no mail available, returns NO_MAIL_HERE otherwise returns the data from +// the mailbox, which is guaranteed != NO_MAIL_HERE. +// +// This version operates on IntelliPort-IIEX - style FIFO's +// +//****************************************************************************** +static unsigned short +iiGetMailIIEX(i2eBordStrPtr pB) +{ + if (I2_HAS_MAIL(pB)) + return inb(pB->i2eXMail); + else + return NO_MAIL_HERE; +} + +//****************************************************************************** +// Function: iiEnableMailIrqII(pB) +// Parameters: pB - pointer to board structure +// +// Returns: Nothing +// +// Description: +// +// Enables board to interrupt host (only) by writing to host's in-bound mailbox. +// +// This version operates on IntelliPort-II - style FIFO's +// +//****************************************************************************** +static void +iiEnableMailIrqII(i2eBordStrPtr pB) +{ + outb(SEL_MASK, pB->i2ePointer); + outb(ST_IN_MAIL, pB->i2ePointer); +} + +//****************************************************************************** +// Function: iiEnableMailIrqIIEX(pB) +// Parameters: pB - pointer to board structure +// +// Returns: Nothing +// +// Description: +// +// Enables board to interrupt host (only) by writing to host's in-bound mailbox. +// +// This version operates on IntelliPort-IIEX - style FIFO's +// +//****************************************************************************** +static void +iiEnableMailIrqIIEX(i2eBordStrPtr pB) +{ + outb(MX_IN_MAIL, pB->i2eXMask); +} + +//****************************************************************************** +// Function: iiWriteMaskII(pB) +// Parameters: pB - pointer to board structure +// +// Returns: Nothing +// +// Description: +// +// Writes arbitrary value to the mask register. +// +// This version operates on IntelliPort-II - style FIFO's +// +//****************************************************************************** +static void +iiWriteMaskII(i2eBordStrPtr pB, unsigned char value) +{ + outb(SEL_MASK, pB->i2ePointer); + outb(value, pB->i2ePointer); +} + +//****************************************************************************** +// Function: iiWriteMaskIIEX(pB) +// Parameters: pB - pointer to board structure +// +// Returns: Nothing +// +// Description: +// +// Writes arbitrary value to the mask register. +// +// This version operates on IntelliPort-IIEX - style FIFO's +// +//****************************************************************************** +static void +iiWriteMaskIIEX(i2eBordStrPtr pB, unsigned char value) +{ + outb(value, pB->i2eXMask); +} + +//****************************************************************************** +// Function: iiDownloadBlock(pB, pSource, isStandard) +// Parameters: pB - pointer to board structure +// pSource - loadware block to download +// isStandard - True if "standard" loadware, else false. +// +// Returns: Success or Failure +// +// Description: +// +// Downloads a single block (at pSource)to the board referenced by pB. Caller +// sets isStandard to true/false according to whether the "standard" loadware is +// what's being loaded. The normal process, then, is to perform an iiInitialize +// to the board, then perform some number of iiDownloadBlocks using the returned +// state to determine when download is complete. +// +// Possible return values: (see I2ELLIS.H) +// II_DOWN_BADVALID +// II_DOWN_BADFILE +// II_DOWN_CONTINUING +// II_DOWN_GOOD +// II_DOWN_BAD +// II_DOWN_BADSTATE +// II_DOWN_TIMEOUT +// +// Uses the i2eState and i2eToLoad fields (initialized at iiInitialize) to +// determine whether this is the first block, whether to check for magic +// numbers, how many blocks there are to go... +// +//****************************************************************************** +static int +iiDownloadBlock ( i2eBordStrPtr pB, loadHdrStrPtr pSource, int isStandard) +{ + int itemp; + int loadedFirst; + + if (pB->i2eValid != I2E_MAGIC) return II_DOWN_BADVALID; + + switch(pB->i2eState) + { + case II_STATE_READY: + + // Loading the first block after reset. Must check the magic number of the + // loadfile, store the number of blocks we expect to load. + if (pSource->e.loadMagic != MAGIC_LOADFILE) + { + return II_DOWN_BADFILE; + } + + // Next we store the total number of blocks to load, including this one. + pB->i2eToLoad = 1 + pSource->e.loadBlocksMore; + + // Set the state, store the version numbers. ('Cause this may have come + // from a file - we might want to report these versions and revisions in + // case of an error! + pB->i2eState = II_STATE_LOADING; + pB->i2eLVersion = pSource->e.loadVersion; + pB->i2eLRevision = pSource->e.loadRevision; + pB->i2eLSub = pSource->e.loadSubRevision; + + // The time and date of compilation is also available but don't bother + // storing it for normal purposes. + loadedFirst = 1; + break; + + case II_STATE_LOADING: + loadedFirst = 0; + break; + + default: + return II_DOWN_BADSTATE; + } + + // Now we must be in the II_STATE_LOADING state, and we assume i2eToLoad + // must be positive still, because otherwise we would have cleaned up last + // time and set the state to II_STATE_LOADED. + if (!iiWaitForTxEmpty(pB, MAX_DLOAD_READ_TIME)) { + return II_DOWN_TIMEOUT; + } + + if (!iiWriteBuf(pB, pSource->c, LOADWARE_BLOCK_SIZE)) { + return II_DOWN_BADVALID; + } + + // If we just loaded the first block, wait for the fifo to empty an extra + // long time to allow for any special startup code in the firmware, like + // sending status messages to the LCD's. + + if (loadedFirst) { + if (!iiWaitForTxEmpty(pB, MAX_DLOAD_START_TIME)) { + return II_DOWN_TIMEOUT; + } + } + + // Determine whether this was our last block! + if (--(pB->i2eToLoad)) { + return II_DOWN_CONTINUING; // more to come... + } + + // It WAS our last block: Clean up operations... + // ...Wait for last buffer to drain from the board... + if (!iiWaitForTxEmpty(pB, MAX_DLOAD_READ_TIME)) { + return II_DOWN_TIMEOUT; + } + // If there were only a single block written, this would come back + // immediately and be harmless, though not strictly necessary. + itemp = MAX_DLOAD_ACK_TIME/10; + while (--itemp) { + if (I2_HAS_INPUT(pB)) { + switch (inb(pB->i2eData)) { + case LOADWARE_OK: + pB->i2eState = + isStandard ? II_STATE_STDLOADED :II_STATE_LOADED; + + // Some revisions of the bootstrap firmware (e.g. ISA-8 1.0.2) + // will, // if there is a debug port attached, require some + // time to send information to the debug port now. It will do + // this before // executing any of the code we just downloaded. + // It may take up to 700 milliseconds. + if (pB->i2ePom.e.porDiag2 & POR_DEBUG_PORT) { + iiDelay(pB, 700); + } + + return II_DOWN_GOOD; + + case LOADWARE_BAD: + default: + return II_DOWN_BAD; + } + } + + iiDelay(pB, 10); // 10 mS granularity on checking condition + } + + // Drop-through --> timed out waiting for firmware confirmation + + pB->i2eState = II_STATE_BADLOAD; + return II_DOWN_TIMEOUT; +} + +//****************************************************************************** +// Function: iiDownloadAll(pB, pSource, isStandard, size) +// Parameters: pB - pointer to board structure +// pSource - loadware block to download +// isStandard - True if "standard" loadware, else false. +// size - size of data to download (in bytes) +// +// Returns: Success or Failure +// +// Description: +// +// Given a pointer to a board structure, a pointer to the beginning of some +// loadware, whether it is considered the "standard loadware", and the size of +// the array in bytes loads the entire array to the board as loadware. +// +// Assumes the board has been freshly reset and the power-up reset message read. +// (i.e., in II_STATE_READY). Complains if state is bad, or if there seems to be +// too much or too little data to load, or if iiDownloadBlock complains. +//****************************************************************************** +static int +iiDownloadAll(i2eBordStrPtr pB, loadHdrStrPtr pSource, int isStandard, int size) +{ + int status; + + // We know (from context) board should be ready for the first block of + // download. Complain if not. + if (pB->i2eState != II_STATE_READY) return II_DOWN_BADSTATE; + + while (size > 0) { + size -= LOADWARE_BLOCK_SIZE; // How much data should there be left to + // load after the following operation ? + + // Note we just bump pSource by "one", because its size is actually that + // of an entire block, same as LOADWARE_BLOCK_SIZE. + status = iiDownloadBlock(pB, pSource++, isStandard); + + switch(status) + { + case II_DOWN_GOOD: + return ( (size > 0) ? II_DOWN_OVER : II_DOWN_GOOD); + + case II_DOWN_CONTINUING: + break; + + default: + return status; + } + } + + // We shouldn't drop out: it means "while" caught us with nothing left to + // download, yet the previous DownloadBlock did not return complete. Ergo, + // not enough data to match the size byte in the header. + return II_DOWN_UNDER; +} diff --git a/drivers/staging/tty/ip2/i2ellis.h b/drivers/staging/tty/ip2/i2ellis.h new file mode 100644 index 000000000000..fb6df2456018 --- /dev/null +++ b/drivers/staging/tty/ip2/i2ellis.h @@ -0,0 +1,566 @@ +/******************************************************************************* +* +* (c) 1999 by Computone Corporation +* +******************************************************************************** +* +* +* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport +* serial I/O controllers. +* +* DESCRIPTION: Mainline code for the device driver +* +*******************************************************************************/ +//------------------------------------------------------------------------------ +// i2ellis.h +// +// IntelliPort-II and IntelliPort-IIEX +// +// Extremely +// Low +// Level +// Interface +// Services +// +// Structure Definitions and declarations for "ELLIS" service routines found in +// i2ellis.c +// +// These routines are based on properties of the IntelliPort-II and -IIEX +// hardware and bootstrap firmware, and are not sensitive to particular +// conventions of any particular loadware. +// +// Unlike i2hw.h, which provides IRONCLAD hardware definitions, the material +// here and in i2ellis.c is intended to provice a useful, but not required, +// layer of insulation from the hardware specifics. +//------------------------------------------------------------------------------ +#ifndef I2ELLIS_H /* To prevent multiple includes */ +#define I2ELLIS_H 1 +//------------------------------------------------ +// Revision History: +// +// 30 September 1991 MAG First Draft Started +// 12 October 1991 ...continued... +// +// 20 December 1996 AKM Linux version +//------------------------------------------------- + +//---------------------- +// Mandatory Includes: +//---------------------- +#include "ip2types.h" +#include "i2hw.h" // The hardware definitions + +//------------------------------------------ +// STAT_BOXIDS packets +//------------------------------------------ +#define MAX_BOX 4 + +typedef struct _bidStat +{ + unsigned char bid_value[MAX_BOX]; +} bidStat, *bidStatPtr; + +// This packet is sent in response to a CMD_GET_BOXIDS bypass command. For -IIEX +// boards, reports the hardware-specific "asynchronous resource register" on +// each expansion box. Boxes not present report 0xff. For -II boards, the first +// element contains 0x80 for 8-port, 0x40 for 4-port boards. + +// Box IDs aka ARR or Async Resource Register (more than you want to know) +// 7 6 5 4 3 2 1 0 +// F F N N L S S S +// ============================= +// F F - Product Family Designator +// =====+++++++++++++++++++++++++++++++ +// 0 0 - Intelliport II EX / ISA-8 +// 1 0 - IntelliServer +// 0 1 - SAC - Port Device (Intelliport III ??? ) +// =====+++++++++++++++++++++++++++++++++++++++ +// N N - Number of Ports +// 0 0 - 8 (eight) +// 0 1 - 4 (four) +// 1 0 - 12 (twelve) +// 1 1 - 16 (sixteen) +// =++++++++++++++++++++++++++++++++++ +// L - LCD Display Module Present +// 0 - No +// 1 - LCD module present +// =========+++++++++++++++++++++++++++++++++++++ +// S S S - Async Signals Supported Designator +// 0 0 0 - 8dss, Mod DCE DB25 Female +// 0 0 1 - 6dss, RJ-45 +// 0 1 0 - RS-232/422 dss, DB25 Female +// 0 1 1 - RS-232/422 dss, separate 232/422 DB25 Female +// 1 0 0 - 6dss, 921.6 I/F with ST654's +// 1 0 1 - RS-423/232 8dss, RJ-45 10Pin +// 1 1 0 - 6dss, Mod DCE DB25 Female +// 1 1 1 - NO BOX PRESENT + +#define FF(c) ((c & 0xC0) >> 6) +#define NN(c) ((c & 0x30) >> 4) +#define L(c) ((c & 0x08) >> 3) +#define SSS(c) (c & 0x07) + +#define BID_HAS_654(x) (SSS(x) == 0x04) +#define BID_NO_BOX 0xff /* no box */ +#define BID_8PORT 0x80 /* IP2-8 port */ +#define BID_4PORT 0x81 /* IP2-4 port */ +#define BID_EXP_MASK 0x30 /* IP2-EX */ +#define BID_EXP_8PORT 0x00 /* 8, */ +#define BID_EXP_4PORT 0x10 /* 4, */ +#define BID_EXP_UNDEF 0x20 /* UNDEF, */ +#define BID_EXP_16PORT 0x30 /* 16, */ +#define BID_LCD_CTRL 0x08 /* LCD Controller */ +#define BID_LCD_NONE 0x00 /* - no controller present */ +#define BID_LCD_PRES 0x08 /* - controller present */ +#define BID_CON_MASK 0x07 /* - connector pinouts */ +#define BID_CON_DB25 0x00 /* - DB-25 F */ +#define BID_CON_RJ45 0x01 /* - rj45 */ + +//------------------------------------------------------------------------------ +// i2eBordStr +// +// This structure contains all the information the ELLIS routines require in +// dealing with a particular board. +//------------------------------------------------------------------------------ +// There are some queues here which are guaranteed to never contain the entry +// for a single channel twice. So they must be slightly larger to allow +// unambiguous full/empty management +// +#define CH_QUEUE_SIZE ABS_MOST_PORTS+2 + +typedef struct _i2eBordStr +{ + porStr i2ePom; // Structure containing the power-on message. + + unsigned short i2ePomSize; + // The number of bytes actually read if + // different from sizeof i2ePom, indicates + // there is an error! + + unsigned short i2eStartMail; + // Contains whatever inbound mailbox data + // present at startup. NO_MAIL_HERE indicates + // nothing was present. No special + // significance as of this writing, but may be + // useful for diagnostic reasons. + + unsigned short i2eValid; + // Indicates validity of the structure; if + // i2eValid == I2E_MAGIC, then we can trust + // the other fields. Some (especially + // initialization) functions are good about + // checking for validity. Many functions do + // not, it being assumed that the larger + // context assures we are using a valid + // i2eBordStrPtr. + + unsigned short i2eError; + // Used for returning an error condition from + // several functions which use i2eBordStrPtr + // as an argument. + + // Accelerators to characterize separate features of a board, derived from a + // number of sources. + + unsigned short i2eFifoSize; + // Always, the size of the FIFO. For + // IntelliPort-II, always the same, for -IIEX + // taken from the Power-On reset message. + + volatile + unsigned short i2eFifoRemains; + // Used during normal operation to indicate a + // lower bound on the amount of data which + // might be in the outbound fifo. + + unsigned char i2eFifoStyle; + // Accelerator which tells which style (-II or + // -IIEX) FIFO we are using. + + unsigned char i2eDataWidth16; + // Accelerator which tells whether we should + // do 8 or 16-bit data transfers. + + unsigned char i2eMaxIrq; + // The highest allowable IRQ, based on the + // slot size. + + // Accelerators for various addresses on the board + int i2eBase; // I/O Address of the Board + int i2eData; // From here data transfers happen + int i2eStatus; // From here status reads happen + int i2ePointer; // (IntelliPort-II: pointer/commands) + int i2eXMail; // (IntelliPOrt-IIEX: mailboxes + int i2eXMask; // (IntelliPort-IIEX: mask write + + //------------------------------------------------------- + // Information presented in a common format across boards + // For each box, bit map of the channels present. Box closest to + // the host is box 0. LSB is channel 0. IntelliPort-II (non-expandable) + // is taken to be box 0. These are derived from product i.d. registers. + + unsigned short i2eChannelMap[ABS_MAX_BOXES]; + + // Same as above, except each is derived from firmware attempting to detect + // the uart presence (by reading a valid GFRCR register). If bits are set in + // i2eChannelMap and not in i2eGoodMap, there is a potential problem. + + unsigned short i2eGoodMap[ABS_MAX_BOXES]; + + // --------------------------- + // For indirect function calls + + // Routine to cause an N-millisecond delay: Patched by the ii2Initialize + // function. + + void (*i2eDelay)(unsigned int); + + // Routine to write N bytes to the board through the FIFO. Returns true if + // all copacetic, otherwise returns false and error is in i2eError field. + // IF COUNT IS ODD, ROUNDS UP TO THE NEXT EVEN NUMBER. + + int (*i2eWriteBuf)(struct _i2eBordStr *, unsigned char *, int); + + // Routine to read N bytes from the board through the FIFO. Returns true if + // copacetic, otherwise returns false and error in i2eError. + // IF COUNT IS ODD, ROUNDS UP TO THE NEXT EVEN NUMBER. + + int (*i2eReadBuf)(struct _i2eBordStr *, unsigned char *, int); + + // Returns a word from FIFO. Will use 2 byte operations if needed. + + unsigned short (*i2eReadWord)(struct _i2eBordStr *); + + // Writes a word to FIFO. Will use 2 byte operations if needed. + + void (*i2eWriteWord)(struct _i2eBordStr *, unsigned short); + + // Waits specified time for the Transmit FIFO to go empty. Returns true if + // ok, otherwise returns false and error in i2eError. + + int (*i2eWaitForTxEmpty)(struct _i2eBordStr *, int); + + // Returns true or false according to whether the outgoing mailbox is empty. + + int (*i2eTxMailEmpty)(struct _i2eBordStr *); + + // Checks whether outgoing mailbox is empty. If so, sends mail and returns + // true. Otherwise returns false. + + int (*i2eTrySendMail)(struct _i2eBordStr *, unsigned char); + + // If no mail available, returns NO_MAIL_HERE, else returns the value in the + // mailbox (guaranteed can't be NO_MAIL_HERE). + + unsigned short (*i2eGetMail)(struct _i2eBordStr *); + + // Enables the board to interrupt the host when it writes to the mailbox. + // Irqs will not occur, however, until the loadware separately enables + // interrupt generation to the host. The standard loadware does this in + // response to a command packet sent by the host. (Also, disables + // any other potential interrupt sources from the board -- other than the + // inbound mailbox). + + void (*i2eEnableMailIrq)(struct _i2eBordStr *); + + // Writes an arbitrary value to the mask register. + + void (*i2eWriteMask)(struct _i2eBordStr *, unsigned char); + + + // State information + + // During downloading, indicates the number of blocks remaining to download + // to the board. + + short i2eToLoad; + + // State of board (see manifests below) (e.g., whether in reset condition, + // whether standard loadware is installed, etc. + + unsigned char i2eState; + + // These three fields are only valid when there is loadware running on the + // board. (i2eState == II_STATE_LOADED or i2eState == II_STATE_STDLOADED ) + + unsigned char i2eLVersion; // Loadware version + unsigned char i2eLRevision; // Loadware revision + unsigned char i2eLSub; // Loadware subrevision + + // Flags which only have meaning in the context of the standard loadware. + // Somewhat violates the layering concept, but there is so little additional + // needed at the board level (while much additional at the channel level), + // that this beats maintaining two different per-board structures. + + // Indicates which IRQ the board has been initialized (from software) to use + // For MicroChannel boards, any value different from IRQ_UNDEFINED means + // that the software command has been sent to enable interrupts (or specify + // they are disabled). Special value: IRQ_UNDEFINED indicates that the + // software command to select the interrupt has not yet been sent, therefore + // (since the standard loadware insists that it be sent before any other + // packets are sent) no other packets should be sent yet. + + unsigned short i2eUsingIrq; + + // This is set when we hit the MB_OUT_STUFFED mailbox, which prevents us + // putting more in the mailbox until an appropriate mailbox message is + // received. + + unsigned char i2eWaitingForEmptyFifo; + + // Any mailbox bits waiting to be sent to the board are OR'ed in here. + + unsigned char i2eOutMailWaiting; + + // The head of any incoming packet is read into here, is then examined and + // we dispatch accordingly. + + unsigned short i2eLeadoffWord[1]; + + // Running counter of interrupts where the mailbox indicated incoming data. + + unsigned short i2eFifoInInts; + + // Running counter of interrupts where the mailbox indicated outgoing data + // had been stripped. + + unsigned short i2eFifoOutInts; + + // If not void, gives the address of a routine to call if fatal board error + // is found (only applies to standard l/w). + + void (*i2eFatalTrap)(struct _i2eBordStr *); + + // Will point to an array of some sort of channel structures (whose format + // is unknown at this level, being a function of what loadware is + // installed and the code configuration (max sizes of buffers, etc.)). + + void *i2eChannelPtr; + + // Set indicates that the board has gone fatal. + + unsigned short i2eFatal; + + // The number of elements pointed to by i2eChannelPtr. + + unsigned short i2eChannelCnt; + + // Ring-buffers of channel structures whose channels have particular needs. + + rwlock_t Fbuf_spinlock; + volatile + unsigned short i2Fbuf_strip; // Strip index + volatile + unsigned short i2Fbuf_stuff; // Stuff index + void *i2Fbuf[CH_QUEUE_SIZE]; // An array of channel pointers + // of channels who need to send + // flow control packets. + rwlock_t Dbuf_spinlock; + volatile + unsigned short i2Dbuf_strip; // Strip index + volatile + unsigned short i2Dbuf_stuff; // Stuff index + void *i2Dbuf[CH_QUEUE_SIZE]; // An array of channel pointers + // of channels who need to send + // data or in-line command packets. + rwlock_t Bbuf_spinlock; + volatile + unsigned short i2Bbuf_strip; // Strip index + volatile + unsigned short i2Bbuf_stuff; // Stuff index + void *i2Bbuf[CH_QUEUE_SIZE]; // An array of channel pointers + // of channels who need to send + // bypass command packets. + + /* + * A set of flags to indicate that certain events have occurred on at least + * one of the ports on this board. We use this to decide whether to spin + * through the channels looking for breaks, etc. + */ + int got_input; + int status_change; + bidStat channelBtypes; + + /* + * Debugging counters, etc. + */ + unsigned long debugFlowQueued; + unsigned long debugInlineQueued; + unsigned long debugDataQueued; + unsigned long debugBypassQueued; + unsigned long debugFlowCount; + unsigned long debugInlineCount; + unsigned long debugBypassCount; + + rwlock_t read_fifo_spinlock; + rwlock_t write_fifo_spinlock; + +// For queuing interrupt bottom half handlers. /\/\|=mhw=|\/\/ + struct work_struct tqueue_interrupt; + + struct timer_list SendPendingTimer; // Used by iiSendPending + unsigned int SendPendingRetry; +} i2eBordStr, *i2eBordStrPtr; + +//------------------------------------------------------------------- +// Macro Definitions for the indirect calls defined in the i2eBordStr +//------------------------------------------------------------------- +// +#define iiDelay(a,b) (*(a)->i2eDelay)(b) +#define iiWriteBuf(a,b,c) (*(a)->i2eWriteBuf)(a,b,c) +#define iiReadBuf(a,b,c) (*(a)->i2eReadBuf)(a,b,c) + +#define iiWriteWord(a,b) (*(a)->i2eWriteWord)(a,b) +#define iiReadWord(a) (*(a)->i2eReadWord)(a) + +#define iiWaitForTxEmpty(a,b) (*(a)->i2eWaitForTxEmpty)(a,b) + +#define iiTxMailEmpty(a) (*(a)->i2eTxMailEmpty)(a) +#define iiTrySendMail(a,b) (*(a)->i2eTrySendMail)(a,b) + +#define iiGetMail(a) (*(a)->i2eGetMail)(a) +#define iiEnableMailIrq(a) (*(a)->i2eEnableMailIrq)(a) +#define iiDisableMailIrq(a) (*(a)->i2eWriteMask)(a,0) +#define iiWriteMask(a,b) (*(a)->i2eWriteMask)(a,b) + +//------------------------------------------- +// Manifests for i2eBordStr: +//------------------------------------------- + +typedef void (*delayFunc_t)(unsigned int); + +// i2eValid +// +#define I2E_MAGIC 0x4251 // Structure is valid. +#define I2E_INCOMPLETE 0x1122 // Structure failed during init. + + +// i2eError +// +#define I2EE_GOOD 0 // Operation successful +#define I2EE_BADADDR 1 // Address out of range +#define I2EE_BADSTATE 2 // Attempt to perform a function when the board + // structure was in the incorrect state +#define I2EE_BADMAGIC 3 // Bad magic number from Power On test (i2ePomSize + // reflects what was read +#define I2EE_PORM_SHORT 4 // Power On message too short +#define I2EE_PORM_LONG 5 // Power On message too long +#define I2EE_BAD_FAMILY 6 // Un-supported board family type +#define I2EE_INCONSIST 7 // Firmware reports something impossible, + // e.g. unexpected number of ports... Almost no + // excuse other than bad FIFO... +#define I2EE_POSTERR 8 // Power-On self test reported a bad error +#define I2EE_BADBUS 9 // Unknown Bus type declared in message +#define I2EE_TXE_TIME 10 // Timed out waiting for TX Fifo to empty +#define I2EE_INVALID 11 // i2eValid field does not indicate a valid and + // complete board structure (for functions which + // require this be so.) +#define I2EE_BAD_PORT 12 // Discrepancy between channels actually found and + // what the product is supposed to have. Check + // i2eGoodMap vs i2eChannelMap for details. +#define I2EE_BAD_IRQ 13 // Someone specified an unsupported IRQ +#define I2EE_NOCHANNELS 14 // No channel structures have been defined (for + // functions requiring this). + +// i2eFifoStyle +// +#define FIFO_II 0 /* IntelliPort-II style: see also i2hw.h */ +#define FIFO_IIEX 1 /* IntelliPort-IIEX style */ + +// i2eGetMail +// +#define NO_MAIL_HERE 0x1111 // Since mail is unsigned char, cannot possibly + // promote to 0x1111. +// i2eState +// +#define II_STATE_COLD 0 // Addresses have been defined, but board not even + // reset yet. +#define II_STATE_RESET 1 // Board,if it exists, has just been reset +#define II_STATE_READY 2 // Board ready for its first block +#define II_STATE_LOADING 3 // Board continuing load +#define II_STATE_LOADED 4 // Board has finished load: status ok +#define II_STATE_BADLOAD 5 // Board has finished load: failed! +#define II_STATE_STDLOADED 6 // Board has finished load: standard firmware + +// i2eUsingIrq +// +#define I2_IRQ_UNDEFINED 0x1352 /* No valid irq (or polling = 0) can + * ever promote to this! */ +//------------------------------------------ +// Handy Macros for i2ellis.c and others +// Note these are common to -II and -IIEX +//------------------------------------------ + +// Given a pointer to the board structure, does the input FIFO have any data or +// not? +// +#define I2_HAS_INPUT(pB) !(inb(pB->i2eStatus) & ST_IN_EMPTY) + +// Given a pointer to the board structure, is there anything in the incoming +// mailbox? +// +#define I2_HAS_MAIL(pB) (inb(pB->i2eStatus) & ST_IN_MAIL) + +#define I2_UPDATE_FIFO_ROOM(pB) ((pB)->i2eFifoRemains = (pB)->i2eFifoSize) + +//------------------------------------------ +// Function Declarations for i2ellis.c +//------------------------------------------ +// +// Functions called directly +// +// Initialization of a board & structure is in four (five!) parts: +// +// 1) iiSetAddress() - Define the board address & delay function for a board. +// 2) iiReset() - Reset the board (provided it exists) +// -- Note you may do this to several boards -- +// 3) iiResetDelay() - Delay for 2 seconds (once for all boards) +// 4) iiInitialize() - Attempt to read Power-up message; further initialize +// accelerators +// +// Then you may use iiDownloadAll() or iiDownloadFile() (in i2file.c) to write +// loadware. To change loadware, you must begin again with step 2, resetting +// the board again (step 1 not needed). + +static int iiSetAddress(i2eBordStrPtr, int, delayFunc_t ); +static int iiReset(i2eBordStrPtr); +static int iiResetDelay(i2eBordStrPtr); +static int iiInitialize(i2eBordStrPtr); + +// Routine to validate that all channels expected are there. +// +extern int iiValidateChannels(i2eBordStrPtr); + +// Routine used to download a block of loadware. +// +static int iiDownloadBlock(i2eBordStrPtr, loadHdrStrPtr, int); + +// Return values given by iiDownloadBlock, iiDownloadAll, iiDownloadFile: +// +#define II_DOWN_BADVALID 0 // board structure is invalid +#define II_DOWN_CONTINUING 1 // So far, so good, firmware expects more +#define II_DOWN_GOOD 2 // Download complete, CRC good +#define II_DOWN_BAD 3 // Download complete, but CRC bad +#define II_DOWN_BADFILE 4 // Bad magic number in loadware file +#define II_DOWN_BADSTATE 5 // Board is in an inappropriate state for + // downloading loadware. (see i2eState) +#define II_DOWN_TIMEOUT 6 // Timeout waiting for firmware +#define II_DOWN_OVER 7 // Too much data +#define II_DOWN_UNDER 8 // Not enough data +#define II_DOWN_NOFILE 9 // Loadware file not found + +// Routine to download an entire loadware module: Return values are a subset of +// iiDownloadBlock's, excluding, of course, II_DOWN_CONTINUING +// +static int iiDownloadAll(i2eBordStrPtr, loadHdrStrPtr, int, int); + +// Many functions defined here return True if good, False otherwise, with an +// error code in i2eError field. Here is a handy macro for setting the error +// code and returning. +// +#define I2_COMPLETE(pB,code) do { \ + pB->i2eError = code; \ + return (code == I2EE_GOOD);\ + } while (0) + +#endif // I2ELLIS_H diff --git a/drivers/staging/tty/ip2/i2hw.h b/drivers/staging/tty/ip2/i2hw.h new file mode 100644 index 000000000000..c0ba6c05f0cd --- /dev/null +++ b/drivers/staging/tty/ip2/i2hw.h @@ -0,0 +1,652 @@ +/******************************************************************************* +* +* (c) 1999 by Computone Corporation +* +******************************************************************************** +* +* +* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport +* serial I/O controllers. +* +* DESCRIPTION: Definitions limited to properties of the hardware or the +* bootstrap firmware. As such, they are applicable regardless of +* operating system or loadware (standard or diagnostic). +* +*******************************************************************************/ +#ifndef I2HW_H +#define I2HW_H 1 +//------------------------------------------------------------------------------ +// Revision History: +// +// 23 September 1991 MAG First Draft Started...through... +// 11 October 1991 ... Continuing development... +// 6 August 1993 Added support for ISA-4 (asic) which is architected +// as an ISA-CEX with a single 4-port box. +// +// 20 December 1996 AKM Version for Linux +// +//------------------------------------------------------------------------------ +/*------------------------------------------------------------------------------ + +HARDWARE DESCRIPTION: + +Introduction: + +The IntelliPort-II and IntelliPort-IIEX products occupy a block of eight (8) +addresses in the host's I/O space. + +Some addresses are used to transfer data to/from the board, some to transfer +so-called "mailbox" messages, and some to read bit-mapped status information. +While all the products in the line are functionally similar, some use a 16-bit +data path to transfer data while others use an 8-bit path. Also, the use of +command /status/mailbox registers differs slightly between the II and IIEX +branches of the family. + +The host determines what type of board it is dealing with by reading a string of +sixteen characters from the board. These characters are always placed in the +fifo by the board's local processor whenever the board is reset (either from +power-on or under software control) and are known as the "Power-on Reset +Message." In order that this message can be read from either type of board, the +hardware registers used in reading this message are the same. Once this message +has been read by the host, then it has the information required to operate. + +General Differences between boards: + +The greatest structural difference is between the -II and -IIEX families of +product. The -II boards use the Am4701 dual 512x8 bidirectional fifo to support +the data path, mailbox registers, and status registers. This chip contains some +features which are not used in the IntelliPort-II products; a description of +these is omitted here. Because of these many features, it contains many +registers, too many to access directly within a small address space. They are +accessed by first writing a value to a "pointer" register. This value selects +the register to be accessed. The next read or write to that address accesses +the selected register rather than the pointer register. + +The -IIEX boards use a proprietary design similar to the Am4701 in function. But +because of a simpler, more streamlined design it doesn't require so many +registers. This means they can be accessed directly in single operations rather +than through a pointer register. + +Besides these differences, there are differences in whether 8-bit or 16-bit +transfers are used to move data to the board. + +The -II boards are capable only of 8-bit data transfers, while the -IIEX boards +may be configured for either 8-bit or 16-bit data transfers. If the on-board DIP +switch #8 is ON, and the card has been installed in a 16-bit slot, 16-bit +transfers are supported (and will be expected by the standard loadware). The +on-board firmware can determine the position of the switch, and whether the +board is installed in a 16-bit slot; it supplies this information to the host as +part of the power-up reset message. + +The configuration switch (#8) and slot selection do not directly configure the +hardware. It is up to the on-board loadware and host-based drivers to act +according to the selected options. That is, loadware and drivers could be +written to perform 8-bit transfers regardless of the state of the DIP switch or +slot (and in a diagnostic environment might well do so). Likewise, 16-bit +transfers could be performed as long as the card is in a 16-bit slot. + +Note the slot selection and DIP switch selection are provided separately: a +board running in 8-bit mode in a 16-bit slot has a greater range of possible +interrupts to choose from; information of potential use to the host. + +All 8-bit data transfers are done in the same way, regardless of whether on a +-II board or a -IIEX board. + +The host must consider two things then: 1) whether a -II or -IIEX product is +being used, and 2) whether an 8-bit or 16-bit data path is used. + +A further difference is that -II boards always have a 512-byte fifo operating in +each direction. -IIEX boards may use fifos of varying size; this size is +reported as part of the power-up message. + +I/O Map Of IntelliPort-II and IntelliPort-IIEX boards: +(Relative to the chosen base address) + +Addr R/W IntelliPort-II IntelliPort-IIEX +---- --- -------------- ---------------- +0 R/W Data Port (byte) Data Port (byte or word) +1 R/W (Not used) (MSB of word-wide data written to Data Port) +2 R Status Register Status Register +2 W Pointer Register Interrupt Mask Register +3 R/W (Not used) Mailbox Registers (6 bits: 11111100) +4,5 -- Reserved for future products +6 -- Reserved for future products +7 R Guaranteed to have no effect +7 W Hardware reset of board. + + +Rules: +All data transfers are performed using the even i/o address. If byte-wide data +transfers are being used, do INB/OUTB operations on the data port. If word-wide +transfers are used, do INW/OUTW operations. In some circumstances (such as +reading the power-up message) you will do INB from the data port, but in this +case the MSB of each word read is lost. When accessing all other unreserved +registers, use byte operations only. +------------------------------------------------------------------------------*/ + +//------------------------------------------------ +// Mandatory Includes: +//------------------------------------------------ +// +#include "ip2types.h" + +//------------------------------------------------------------------------- +// Manifests for the I/O map: +//------------------------------------------------------------------------- +// R/W: Data port (byte) for IntelliPort-II, +// R/W: Data port (byte or word) for IntelliPort-IIEX +// Incoming or outgoing data passes through a FIFO, the status of which is +// available in some of the bits in FIFO_STATUS. This (bidirectional) FIFO is +// the primary means of transferring data, commands, flow-control, and status +// information between the host and board. +// +#define FIFO_DATA 0 + +// Another way of passing information between the board and the host is +// through "mailboxes". Unlike a FIFO, a mailbox holds only a single byte of +// data. Writing data to the mailbox causes a status bit to be set, and +// potentially interrupting the intended receiver. The sender has some way to +// determine whether the data has been read yet; as soon as it has, it may send +// more. The mailboxes are handled differently on -II and -IIEX products, as +// suggested below. +//------------------------------------------------------------------------------ +// Read: Status Register for IntelliPort-II or -IIEX +// The presence of any bit set here will cause an interrupt to the host, +// provided the corresponding bit has been unmasked in the interrupt mask +// register. Furthermore, interrupts to the host are disabled globally until the +// loadware selects the irq line to use. With the exception of STN_MR, the bits +// remain set so long as the associated condition is true. +// +#define FIFO_STATUS 2 + +// Bit map of status bits which are identical for -II and -IIEX +// +#define ST_OUT_FULL 0x40 // Outbound FIFO full +#define ST_IN_EMPTY 0x20 // Inbound FIFO empty +#define ST_IN_MAIL 0x04 // Inbound Mailbox full + +// The following exists only on the Intelliport-IIEX, and indicates that the +// board has not read the last outgoing mailbox data yet. In the IntelliPort-II, +// the outgoing mailbox may be read back: a zero indicates the board has read +// the data. +// +#define STE_OUT_MAIL 0x80 // Outbound mailbox full (!) + +// The following bits are defined differently for -II and -IIEX boards. Code +// which relies on these bits will need to be functionally different for the two +// types of boards and should be generally avoided because of the additional +// complexity this creates: + +// Bit map of status bits only on -II + +// Fifo has been RESET (cleared when the status register is read). Note that +// this condition cannot be masked and would always interrupt the host, except +// that the hardware reset also disables interrupts globally from the board +// until re-enabled by loadware. This could also arise from the +// Am4701-supported command to reset the chip, but this command is generally not +// used here. +// +#define STN_MR 0x80 + +// See the AMD Am4701 data sheet for details on the following four bits. They +// are not presently used by Computone drivers. +// +#define STN_OUT_AF 0x10 // Outbound FIFO almost full (programmable) +#define STN_IN_AE 0x08 // Inbound FIFO almost empty (programmable) +#define STN_BD 0x02 // Inbound byte detected +#define STN_PE 0x01 // Parity/Framing condition detected + +// Bit-map of status bits only on -IIEX +// +#define STE_OUT_HF 0x10 // Outbound FIFO half full +#define STE_IN_HF 0x08 // Inbound FIFO half full +#define STE_IN_FULL 0x02 // Inbound FIFO full +#define STE_OUT_MT 0x01 // Outbound FIFO empty + +//------------------------------------------------------------------------------ + +// Intelliport-II -- Write Only: the pointer register. +// Values are written to this register to select the Am4701 internal register to +// be accessed on the next operation. +// +#define FIFO_PTR 0x02 + +// Values for the pointer register +// +#define SEL_COMMAND 0x1 // Selects the Am4701 command register + +// Some possible commands: +// +#define SEL_CMD_MR 0x80 // Am4701 command to reset the chip +#define SEL_CMD_SH 0x40 // Am4701 command to map the "other" port into the + // status register. +#define SEL_CMD_UNSH 0 // Am4701 command to "unshift": port maps into its + // own status register. +#define SEL_MASK 0x2 // Selects the Am4701 interrupt mask register. The + // interrupt mask register is bit-mapped to match + // the status register (FIFO_STATUS) except for + // STN_MR. (See above.) +#define SEL_BYTE_DET 0x3 // Selects the Am4701 byte-detect register. (Not + // normally used except in diagnostics.) +#define SEL_OUTMAIL 0x4 // Selects the outbound mailbox (R/W). Reading back + // a value of zero indicates that the mailbox has + // been read by the board and is available for more + // data./ Writing to the mailbox optionally + // interrupts the board, depending on the loadware's + // setting of its interrupt mask register. +#define SEL_AEAF 0x5 // Selects AE/AF threshold register. +#define SEL_INMAIL 0x6 // Selects the inbound mailbox (Read) + +//------------------------------------------------------------------------------ +// IntelliPort-IIEX -- Write Only: interrupt mask (and misc flags) register: +// Unlike IntelliPort-II, bit assignments do NOT match those of the status +// register. +// +#define FIFO_MASK 0x2 + +// Mailbox readback select: +// If set, reads to FIFO_MAIL will read the OUTBOUND mailbox (host to board). If +// clear (default on reset) reads to FIFO_MAIL will read the INBOUND mailbox. +// This is the normal situation. The clearing of a mailbox is determined on +// -IIEX boards by waiting for the STE_OUT_MAIL bit to clear. Readback +// capability is provided for diagnostic purposes only. +// +#define MX_OUTMAIL_RSEL 0x80 + +#define MX_IN_MAIL 0x40 // Enables interrupts when incoming mailbox goes + // full (ST_IN_MAIL set). +#define MX_IN_FULL 0x20 // Enables interrupts when incoming FIFO goes full + // (STE_IN_FULL). +#define MX_IN_MT 0x08 // Enables interrupts when incoming FIFO goes empty + // (ST_IN_MT). +#define MX_OUT_FULL 0x04 // Enables interrupts when outgoing FIFO goes full + // (ST_OUT_FULL). +#define MX_OUT_MT 0x01 // Enables interrupts when outgoing FIFO goes empty + // (STE_OUT_MT). + +// Any remaining bits are reserved, and should be written to ZERO for +// compatibility with future Computone products. + +//------------------------------------------------------------------------------ +// IntelliPort-IIEX: -- These are only 6-bit mailboxes !!! -- 11111100 (low two +// bits always read back 0). +// Read: One of the mailboxes, usually Inbound. +// Inbound Mailbox (MX_OUTMAIL_RSEL = 0) +// Outbound Mailbox (MX_OUTMAIL_RSEL = 1) +// Write: Outbound Mailbox +// For the IntelliPort-II boards, the outbound mailbox is read back to determine +// whether the board has read the data (0 --> data has been read). For the +// IntelliPort-IIEX, this is done by reading a status register. To determine +// whether mailbox is available for more outbound data, use the STE_OUT_MAIL bit +// in FIFO_STATUS. Moreover, although the Outbound Mailbox can be read back by +// setting MX_OUTMAIL_RSEL, it is NOT cleared when the board reads it, as is the +// case with the -II boards. For this reason, FIFO_MAIL is normally used to read +// the inbound FIFO, and MX_OUTMAIL_RSEL kept clear. (See above for +// MX_OUTMAIL_RSEL description.) +// +#define FIFO_MAIL 0x3 + +//------------------------------------------------------------------------------ +// WRITE ONLY: Resets the board. (Data doesn't matter). +// +#define FIFO_RESET 0x7 + +//------------------------------------------------------------------------------ +// READ ONLY: Will have no effect. (Data is undefined.) +// Actually, there will be an effect, in that the operation is sure to generate +// a bus cycle: viz., an I/O byte Read. This fact can be used to enforce short +// delays when no comparable time constant is available. +// +#define FIFO_NOP 0x7 + +//------------------------------------------------------------------------------ +// RESET & POWER-ON RESET MESSAGE +/*------------------------------------------------------------------------------ +RESET: + +The IntelliPort-II and -IIEX boards are reset in three ways: Power-up, channel +reset, and via a write to the reset register described above. For products using +the ISA bus, these three sources of reset are equvalent. For MCA and EISA buses, +the Power-up and channel reset sources cause additional hardware initialization +which should only occur at system startup time. + +The third type of reset, called a "command reset", is done by writing any data +to the FIFO_RESET address described above. This resets the on-board processor, +FIFO, UARTS, and associated hardware. + +This passes control of the board to the bootstrap firmware, which performs a +Power-On Self Test and which detects its current configuration. For example, +-IIEX products determine the size of FIFO which has been installed, and the +number and type of expansion boxes attached. + +This and other information is then written to the FIFO in a 16-byte data block +to be read by the host. This block is guaranteed to be present within two (2) +seconds of having received the command reset. The firmware is now ready to +receive loadware from the host. + +It is good practice to perform a command reset to the board explicitly as part +of your software initialization. This allows your code to properly restart from +a soft boot. (Many systems do not issue channel reset on soft boot). + +Because of a hardware reset problem on some of the Cirrus Logic 1400's which are +used on the product, it is recommended that you reset the board twice, separated +by an approximately 50 milliseconds delay. (VERY approximately: probably ok to +be off by a factor of five. The important point is that the first command reset +in fact generates a reset pulse on the board. This pulse is guaranteed to last +less than 10 milliseconds. The additional delay ensures the 1400 has had the +chance to respond sufficiently to the first reset. Why not a longer delay? Much +more than 50 milliseconds gets to be noticable, but the board would still work. + +Once all 16 bytes of the Power-on Reset Message have been read, the bootstrap +firmware is ready to receive loadware. + +Note on Power-on Reset Message format: +The various fields have been designed with future expansion in view. +Combinations of bitfields and values have been defined which define products +which may not currently exist. This has been done to allow drivers to anticipate +the possible introduction of products in a systematic fashion. This is not +intended to suggest that each potential product is actually under consideration. +------------------------------------------------------------------------------*/ + +//---------------------------------------- +// Format of Power-on Reset Message +//---------------------------------------- + +typedef union _porStr // "por" stands for Power On Reset +{ + unsigned char c[16]; // array used when considering the message as a + // string of undifferentiated characters + + struct // Elements used when considering values + { + // The first two bytes out of the FIFO are two magic numbers. These are + // intended to establish that there is indeed a member of the + // IntelliPort-II(EX) family present. The remaining bytes may be + // expected // to be valid. When reading the Power-on Reset message, + // if the magic numbers do not match it is probably best to stop + // reading immediately. You are certainly not reading our board (unless + // hardware is faulty), and may in fact be reading some other piece of + // hardware. + + unsigned char porMagic1; // magic number: first byte == POR_MAGIC_1 + unsigned char porMagic2; // magic number: second byte == POR_MAGIC_2 + + // The Version, Revision, and Subrevision are stored as absolute numbers + // and would normally be displayed in the format V.R.S (e.g. 1.0.2) + + unsigned char porVersion; // Bootstrap firmware version number + unsigned char porRevision; // Bootstrap firmware revision number + unsigned char porSubRev; // Bootstrap firmware sub-revision number + + unsigned char porID; // Product ID: Bit-mapped according to + // conventions described below. Among other + // things, this allows us to distinguish + // IntelliPort-II boards from IntelliPort-IIEX + // boards. + + unsigned char porBus; // IntelliPort-II: Unused + // IntelliPort-IIEX: Bus Information: + // Bit-mapped below + + unsigned char porMemory; // On-board DRAM size: in 32k blocks + + // porPorts1 (and porPorts2) are used to determine the ports which are + // available to the board. For non-expandable product, a single number + // is sufficient. For expandable product, the board may be connected + // to as many as four boxes. Each box may be (so far) either a 16-port + // or an 8-port size. Whenever an 8-port box is used, the remaining 8 + // ports leave gaps between existing channels. For that reason, + // expandable products must report a MAP of available channels. Since + // each UART supports four ports, we represent each UART found by a + // single bit. Using two bytes to supply the mapping information we + // report the presense or absense of up to 16 UARTS, or 64 ports in + // steps of 4 ports. For -IIEX products, the ports are numbered + // starting at the box closest to the controller in the "chain". + + // Interpreted Differently for IntelliPort-II and -IIEX. + // -II: Number of ports (Derived actually from product ID). See + // Diag1&2 to indicate if uart was actually detected. + // -IIEX: Bit-map of UARTS found, LSB (see below for MSB of this). This + // bitmap is based on detecting the uarts themselves; + // see porFlags for information from the box i.d's. + unsigned char porPorts1; + + unsigned char porDiag1; // Results of on-board P.O.S.T, 1st byte + unsigned char porDiag2; // Results of on-board P.O.S.T, 2nd byte + unsigned char porSpeed; // Speed of local CPU: given as MHz x10 + // e.g., 16.0 MHz CPU is reported as 160 + unsigned char porFlags; // Misc information (see manifests below) + // Bit-mapped: CPU type, UART's present + + unsigned char porPorts2; // -II: Undefined + // -IIEX: Bit-map of UARTS found, MSB (see + // above for LSB) + + // IntelliPort-II: undefined + // IntelliPort-IIEX: 1 << porFifoSize gives the size, in bytes, of the + // host interface FIFO, in each direction. When running the -IIEX in + // 8-bit mode, fifo capacity is halved. The bootstrap firmware will + // have already accounted for this fact in generating this number. + unsigned char porFifoSize; + + // IntelliPort-II: undefined + // IntelliPort-IIEX: The number of boxes connected. (Presently 1-4) + unsigned char porNumBoxes; + } e; +} porStr, *porStrPtr; + +//-------------------------- +// Values for porStr fields +//-------------------------- + +//--------------------- +// porMagic1, porMagic2 +//---------------------- +// +#define POR_MAGIC_1 0x96 // The only valid value for porMagic1 +#define POR_MAGIC_2 0x35 // The only valid value for porMagic2 +#define POR_1_INDEX 0 // Byte position of POR_MAGIC_1 +#define POR_2_INDEX 1 // Ditto for POR_MAGIC_2 + +//---------------------- +// porID +//---------------------- +// +#define POR_ID_FAMILY 0xc0 // These bits indicate the general family of + // product. +#define POR_ID_FII 0x00 // Family is "IntelliPort-II" +#define POR_ID_FIIEX 0x40 // Family is "IntelliPort-IIEX" + +// These bits are reserved, presently zero. May be used at a later date to +// convey other product information. +// +#define POR_ID_RESERVED 0x3c + +#define POR_ID_SIZE 0x03 // Remaining bits indicate number of ports & + // Connector information. +#define POR_ID_II_8 0x00 // For IntelliPort-II, indicates 8-port using + // standard brick. +#define POR_ID_II_8R 0x01 // For IntelliPort-II, indicates 8-port using + // RJ11's (no CTS) +#define POR_ID_II_6 0x02 // For IntelliPort-II, indicates 6-port using + // RJ45's +#define POR_ID_II_4 0x03 // For IntelliPort-II, indicates 4-port using + // 4xRJ45 connectors +#define POR_ID_EX 0x00 // For IntelliPort-IIEX, indicates standard + // expandable controller (other values reserved) + +//---------------------- +// porBus +//---------------------- + +// IntelliPort-IIEX only: Board is installed in a 16-bit slot +// +#define POR_BUS_SLOT16 0x20 + +// IntelliPort-IIEX only: DIP switch #8 is on, selecting 16-bit host interface +// operation. +// +#define POR_BUS_DIP16 0x10 + +// Bits 0-2 indicate type of bus: This information is stored in the bootstrap +// loadware, different loadware being used on different products for different +// buses. For most situations, the drivers do not need this information; but it +// is handy in a diagnostic environment. For example, on microchannel boards, +// you would not want to try to test several interrupts, only the one for which +// you were configured. +// +#define POR_BUS_TYPE 0x07 + +// Unknown: this product doesn't know what bus it is running in. (e.g. if same +// bootstrap firmware were wanted for two different buses.) +// +#define POR_BUS_T_UNK 0 + +// Note: existing firmware for ISA-8 and MC-8 currently report the POR_BUS_T_UNK +// state, since the same bootstrap firmware is used for each. + +#define POR_BUS_T_MCA 1 // MCA BUS */ +#define POR_BUS_T_EISA 2 // EISA BUS */ +#define POR_BUS_T_ISA 3 // ISA BUS */ + +// Values 4-7 Reserved + +// Remaining bits are reserved + +//---------------------- +// porDiag1 +//---------------------- + +#define POR_BAD_MAPPER 0x80 // HW failure on P.O.S.T: Chip mapper failed + +// These two bits valid only for the IntelliPort-II +// +#define POR_BAD_UART1 0x01 // First 1400 bad +#define POR_BAD_UART2 0x02 // Second 1400 bad + +//---------------------- +// porDiag2 +//---------------------- + +#define POR_DEBUG_PORT 0x80 // debug port was detected by the P.O.S.T +#define POR_DIAG_OK 0x00 // Indicates passage: Failure codes not yet + // available. + // Other bits undefined. +//---------------------- +// porFlags +//---------------------- + +#define POR_CPU 0x03 // These bits indicate supposed CPU type +#define POR_CPU_8 0x01 // Board uses an 80188 (no such thing yet) +#define POR_CPU_6 0x02 // Board uses an 80186 (all existing products) +#define POR_CEX4 0x04 // If set, this is an ISA-CEX/4: An ISA-4 (asic) + // which is architected like an ISA-CEX connected + // to a (hitherto impossible) 4-port box. +#define POR_BOXES 0xf0 // Valid for IntelliPort-IIEX only: Map of Box + // sizes based on box I.D. +#define POR_BOX_16 0x10 // Set indicates 16-port, clear 8-port + +//------------------------------------- +// LOADWARE and DOWNLOADING CODE +//------------------------------------- + +/* +Loadware may be sent to the board in two ways: +1) It may be read from a (binary image) data file block by block as each block + is sent to the board. This is only possible when the initialization is + performed by code which can access your file system. This is most suitable + for diagnostics and appications which use the interface library directly. + +2) It may be hard-coded into your source by including a .h file (typically + supplied by Computone), which declares a data array and initializes every + element. This achieves the same result as if an entire loadware file had + been read into the array. + + This requires more data space in your program, but access to the file system + is not required. This method is more suited to driver code, which typically + is running at a level too low to access the file system directly. + +At present, loadware can only be generated at Computone. + +All Loadware begins with a header area which has a particular format. This +includes a magic number which identifies the file as being (purportedly) +loadware, CRC (for the loader), and version information. +*/ + + +//----------------------------------------------------------------------------- +// Format of loadware block +// +// This is defined as a union so we can pass a pointer to one of these items +// and (if it is the first block) pick out the version information, etc. +// +// Otherwise, to deal with this as a simple character array +//------------------------------------------------------------------------------ + +#define LOADWARE_BLOCK_SIZE 512 // Number of bytes in each block of loadware + +typedef union _loadHdrStr +{ + unsigned char c[LOADWARE_BLOCK_SIZE]; // Valid for every block + + struct // These fields are valid for only the first block of loadware. + { + unsigned char loadMagic; // Magic number: see below + unsigned char loadBlocksMore; // How many more blocks? + unsigned char loadCRC[2]; // Two CRC bytes: used by loader + unsigned char loadVersion; // Version number + unsigned char loadRevision; // Revision number + unsigned char loadSubRevision; // Sub-revision number + unsigned char loadSpares[9]; // Presently unused + unsigned char loadDates[32]; // Null-terminated string which can give + // date and time of compilation + } e; +} loadHdrStr, *loadHdrStrPtr; + +//------------------------------------ +// Defines for downloading code: +//------------------------------------ + +// The loadMagic field in the first block of the loadfile must be this, else the +// file is not valid. +// +#define MAGIC_LOADFILE 0x3c + +// How do we know the load was successful? On completion of the load, the +// bootstrap firmware returns a code to indicate whether it thought the download +// was valid and intends to execute it. These are the only possible valid codes: +// +#define LOADWARE_OK 0xc3 // Download was ok +#define LOADWARE_BAD 0x5a // Download was bad (CRC error) + +// Constants applicable to writing blocks of loadware: +// The first block of loadware might take 600 mS to load, in extreme cases. +// (Expandable board: worst case for sending startup messages to the LCD's). +// The 600mS figure is not really a calculation, but a conservative +// guess/guarantee. Usually this will be within 100 mS, like subsequent blocks. +// +#define MAX_DLOAD_START_TIME 1000 // 1000 mS +#define MAX_DLOAD_READ_TIME 100 // 100 mS + +// Firmware should respond with status (see above) within this long of host +// having sent the final block. +// +#define MAX_DLOAD_ACK_TIME 100 // 100 mS, again! + +//------------------------------------------------------ +// MAXIMUM NUMBER OF PORTS PER BOARD: +// This is fixed for now (with the expandable), but may +// be expanding according to even newer products. +//------------------------------------------------------ +// +#define ABS_MAX_BOXES 4 // Absolute most boxes per board +#define ABS_BIGGEST_BOX 16 // Absolute the most ports per box +#define ABS_MOST_PORTS (ABS_MAX_BOXES * ABS_BIGGEST_BOX) + +#define I2_OUTSW(port, addr, count) outsw((port), (addr), (((count)+1)/2)) +#define I2_OUTSB(port, addr, count) outsb((port), (addr), (((count)+1))&-2) +#define I2_INSW(port, addr, count) insw((port), (addr), (((count)+1)/2)) +#define I2_INSB(port, addr, count) insb((port), (addr), (((count)+1))&-2) + +#endif // I2HW_H + diff --git a/drivers/staging/tty/ip2/i2lib.c b/drivers/staging/tty/ip2/i2lib.c new file mode 100644 index 000000000000..0d10b89218ed --- /dev/null +++ b/drivers/staging/tty/ip2/i2lib.c @@ -0,0 +1,2214 @@ +/******************************************************************************* +* +* (c) 1999 by Computone Corporation +* +******************************************************************************** +* +* +* PACKAGE: Linux tty Device Driver for IntelliPort family of multiport +* serial I/O controllers. +* +* DESCRIPTION: High-level interface code for the device driver. Uses the +* Extremely Low Level Interface Support (i2ellis.c). Provides an +* interface to the standard loadware, to support drivers or +* application code. (This is included source code, not a separate +* compilation module.) +* +*******************************************************************************/ +//------------------------------------------------------------------------------ +// Note on Strategy: +// Once the board has been initialized, it will interrupt us when: +// 1) It has something in the fifo for us to read (incoming data, flow control +// packets, or whatever). +// 2) It has stripped whatever we have sent last time in the FIFO (and +// consequently is ready for more). +// +// Note also that the buffer sizes declared in i2lib.h are VERY SMALL. This +// worsens performance considerably, but is done so that a great many channels +// might use only a little memory. +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Revision History: +// +// 0.00 - 4/16/91 --- First Draft +// 0.01 - 4/29/91 --- 1st beta release +// 0.02 - 6/14/91 --- Changes to allow small model compilation +// 0.03 - 6/17/91 MAG Break reporting protected from interrupts routines with +// in-line asm added for moving data to/from ring buffers, +// replacing a variety of methods used previously. +// 0.04 - 6/21/91 MAG Initial flow-control packets not queued until +// i2_enable_interrupts time. Former versions would enqueue +// them at i2_init_channel time, before we knew how many +// channels were supposed to exist! +// 0.05 - 10/12/91 MAG Major changes: works through the ellis.c routines now; +// supports new 16-bit protocol and expandable boards. +// - 10/24/91 MAG Most changes in place and stable. +// 0.06 - 2/20/92 MAG Format of CMD_HOTACK corrected: the command takes no +// argument. +// 0.07 -- 3/11/92 MAG Support added to store special packet types at interrupt +// level (mostly responses to specific commands.) +// 0.08 -- 3/30/92 MAG Support added for STAT_MODEM packet +// 0.09 -- 6/24/93 MAG i2Link... needed to update number of boards BEFORE +// turning on the interrupt. +// 0.10 -- 6/25/93 MAG To avoid gruesome death from a bad board, we sanity check +// some incoming. +// +// 1.1 - 12/25/96 AKM Linux version. +// - 10/09/98 DMC Revised Linux version. +//------------------------------------------------------------------------------ + +//************ +//* Includes * +//************ + +#include +#include "i2lib.h" + + +//*********************** +//* Function Prototypes * +//*********************** +static void i2QueueNeeds(i2eBordStrPtr, i2ChanStrPtr, int); +static i2ChanStrPtr i2DeQueueNeeds(i2eBordStrPtr, int ); +static void i2StripFifo(i2eBordStrPtr); +static void i2StuffFifoBypass(i2eBordStrPtr); +static void i2StuffFifoFlow(i2eBordStrPtr); +static void i2StuffFifoInline(i2eBordStrPtr); +static int i2RetryFlushOutput(i2ChanStrPtr); + +// Not a documented part of the library routines (careful...) but the Diagnostic +// i2diag.c finds them useful to help the throughput in certain limited +// single-threaded operations. +static void iiSendPendingMail(i2eBordStrPtr); +static void serviceOutgoingFifo(i2eBordStrPtr); + +// Functions defined in ip2.c as part of interrupt handling +static void do_input(struct work_struct *); +static void do_status(struct work_struct *); + +//*************** +//* Debug Data * +//*************** +#ifdef DEBUG_FIFO + +unsigned char DBGBuf[0x4000]; +unsigned short I = 0; + +static void +WriteDBGBuf(char *s, unsigned char *src, unsigned short n ) +{ + char *p = src; + + // XXX: We need a spin lock here if we ever use this again + + while (*s) { // copy label + DBGBuf[I] = *s++; + I = I++ & 0x3fff; + } + while (n--) { // copy data + DBGBuf[I] = *p++; + I = I++ & 0x3fff; + } +} + +static void +fatality(i2eBordStrPtr pB ) +{ + int i; + + for (i=0;i= ' ' && DBGBuf[i] <= '~') { + printk(" %c ",DBGBuf[i]); + } else { + printk(" . "); + } + } + printk("\n"); + printk("Last index %x\n",I); +} +#endif /* DEBUG_FIFO */ + +//******** +//* Code * +//******** + +static inline int +i2Validate ( i2ChanStrPtr pCh ) +{ + //ip2trace(pCh->port_index, ITRC_VERIFY,ITRC_ENTER,2,pCh->validity, + // (CHANNEL_MAGIC | CHANNEL_SUPPORT)); + return ((pCh->validity & (CHANNEL_MAGIC_BITS | CHANNEL_SUPPORT)) + == (CHANNEL_MAGIC | CHANNEL_SUPPORT)); +} + +static void iiSendPendingMail_t(unsigned long data) +{ + i2eBordStrPtr pB = (i2eBordStrPtr)data; + + iiSendPendingMail(pB); +} + +//****************************************************************************** +// Function: iiSendPendingMail(pB) +// Parameters: Pointer to a board structure +// Returns: Nothing +// +// Description: +// If any outgoing mail bits are set and there is outgoing mailbox is empty, +// send the mail and clear the bits. +//****************************************************************************** +static void +iiSendPendingMail(i2eBordStrPtr pB) +{ + if (pB->i2eOutMailWaiting && (!pB->i2eWaitingForEmptyFifo) ) + { + if (iiTrySendMail(pB, pB->i2eOutMailWaiting)) + { + /* If we were already waiting for fifo to empty, + * or just sent MB_OUT_STUFFED, then we are + * still waiting for it to empty, until we should + * receive an MB_IN_STRIPPED from the board. + */ + pB->i2eWaitingForEmptyFifo |= + (pB->i2eOutMailWaiting & MB_OUT_STUFFED); + pB->i2eOutMailWaiting = 0; + pB->SendPendingRetry = 0; + } else { +/* The only time we hit this area is when "iiTrySendMail" has + failed. That only occurs when the outbound mailbox is + still busy with the last message. We take a short breather + to let the board catch up with itself and then try again. + 16 Retries is the limit - then we got a borked board. + /\/\|=mhw=|\/\/ */ + + if( ++pB->SendPendingRetry < 16 ) { + setup_timer(&pB->SendPendingTimer, + iiSendPendingMail_t, (unsigned long)pB); + mod_timer(&pB->SendPendingTimer, jiffies + 1); + } else { + printk( KERN_ERR "IP2: iiSendPendingMail unable to queue outbound mail\n" ); + } + } + } +} + +//****************************************************************************** +// Function: i2InitChannels(pB, nChannels, pCh) +// Parameters: Pointer to Ellis Board structure +// Number of channels to initialize +// Pointer to first element in an array of channel structures +// Returns: Success or failure +// +// Description: +// +// This function patches pointers, back-pointers, and initializes all the +// elements in the channel structure array. +// +// This should be run after the board structure is initialized, through having +// loaded the standard loadware (otherwise it complains). +// +// In any case, it must be done before any serious work begins initializing the +// irq's or sending commands... +// +//****************************************************************************** +static int +i2InitChannels ( i2eBordStrPtr pB, int nChannels, i2ChanStrPtr pCh) +{ + int index, stuffIndex; + i2ChanStrPtr *ppCh; + + if (pB->i2eValid != I2E_MAGIC) { + I2_COMPLETE(pB, I2EE_BADMAGIC); + } + if (pB->i2eState != II_STATE_STDLOADED) { + I2_COMPLETE(pB, I2EE_BADSTATE); + } + + rwlock_init(&pB->read_fifo_spinlock); + rwlock_init(&pB->write_fifo_spinlock); + rwlock_init(&pB->Dbuf_spinlock); + rwlock_init(&pB->Bbuf_spinlock); + rwlock_init(&pB->Fbuf_spinlock); + + // NO LOCK needed yet - this is init + + pB->i2eChannelPtr = pCh; + pB->i2eChannelCnt = nChannels; + + pB->i2Fbuf_strip = pB->i2Fbuf_stuff = 0; + pB->i2Dbuf_strip = pB->i2Dbuf_stuff = 0; + pB->i2Bbuf_strip = pB->i2Bbuf_stuff = 0; + + pB->SendPendingRetry = 0; + + memset ( pCh, 0, sizeof (i2ChanStr) * nChannels ); + + for (index = stuffIndex = 0, ppCh = (i2ChanStrPtr *)(pB->i2Fbuf); + nChannels && index < ABS_MOST_PORTS; + index++) + { + if ( !(pB->i2eChannelMap[index >> 4] & (1 << (index & 0xf)) ) ) { + continue; + } + rwlock_init(&pCh->Ibuf_spinlock); + rwlock_init(&pCh->Obuf_spinlock); + rwlock_init(&pCh->Cbuf_spinlock); + rwlock_init(&pCh->Pbuf_spinlock); + // NO LOCK needed yet - this is init + // Set up validity flag according to support level + if (pB->i2eGoodMap[index >> 4] & (1 << (index & 0xf)) ) { + pCh->validity = CHANNEL_MAGIC | CHANNEL_SUPPORT; + } else { + pCh->validity = CHANNEL_MAGIC; + } + pCh->pMyBord = pB; /* Back-pointer */ + + // Prepare an outgoing flow-control packet to send as soon as the chance + // occurs. + if ( pCh->validity & CHANNEL_SUPPORT ) { + pCh->infl.hd.i2sChannel = index; + pCh->infl.hd.i2sCount = 5; + pCh->infl.hd.i2sType = PTYPE_BYPASS; + pCh->infl.fcmd = 37; + pCh->infl.asof = 0; + pCh->infl.room = IBUF_SIZE - 1; + + pCh->whenSendFlow = (IBUF_SIZE/5)*4; // when 80% full + + // The following is similar to calling i2QueueNeeds, except that this + // is done in longhand, since we are setting up initial conditions on + // many channels at once. + pCh->channelNeeds = NEED_FLOW; // Since starting from scratch + pCh->sinceLastFlow = 0; // No bytes received since last flow + // control packet was queued + stuffIndex++; + *ppCh++ = pCh; // List this channel as needing + // initial flow control packet sent + } + + // Don't allow anything to be sent until the status packets come in from + // the board. + + pCh->outfl.asof = 0; + pCh->outfl.room = 0; + + // Initialize all the ring buffers + + pCh->Ibuf_stuff = pCh->Ibuf_strip = 0; + pCh->Obuf_stuff = pCh->Obuf_strip = 0; + pCh->Cbuf_stuff = pCh->Cbuf_strip = 0; + + memset( &pCh->icount, 0, sizeof (struct async_icount) ); + pCh->hotKeyIn = HOT_CLEAR; + pCh->channelOptions = 0; + pCh->bookMarks = 0; + init_waitqueue_head(&pCh->pBookmarkWait); + + init_waitqueue_head(&pCh->open_wait); + init_waitqueue_head(&pCh->close_wait); + init_waitqueue_head(&pCh->delta_msr_wait); + + // Set base and divisor so default custom rate is 9600 + pCh->BaudBase = 921600; // MAX for ST654, changed after we get + pCh->BaudDivisor = 96; // the boxids (UART types) later + + pCh->dataSetIn = 0; + pCh->dataSetOut = 0; + + pCh->wopen = 0; + pCh->throttled = 0; + + pCh->speed = CBR_9600; + + pCh->flags = 0; + + pCh->ClosingDelay = 5*HZ/10; + pCh->ClosingWaitTime = 30*HZ; + + // Initialize task queue objects + INIT_WORK(&pCh->tqueue_input, do_input); + INIT_WORK(&pCh->tqueue_status, do_status); + +#ifdef IP2DEBUG_TRACE + pCh->trace = ip2trace; +#endif + + ++pCh; + --nChannels; + } + // No need to check for wrap here; this is initialization. + pB->i2Fbuf_stuff = stuffIndex; + I2_COMPLETE(pB, I2EE_GOOD); + +} + +//****************************************************************************** +// Function: i2DeQueueNeeds(pB, type) +// Parameters: Pointer to a board structure +// type bit map: may include NEED_INLINE, NEED_BYPASS, or NEED_FLOW +// Returns: +// Pointer to a channel structure +// +// Description: Returns pointer struct of next channel that needs service of +// the type specified. Otherwise returns a NULL reference. +// +//****************************************************************************** +static i2ChanStrPtr +i2DeQueueNeeds(i2eBordStrPtr pB, int type) +{ + unsigned short queueIndex; + unsigned long flags; + + i2ChanStrPtr pCh = NULL; + + switch(type) { + + case NEED_INLINE: + + write_lock_irqsave(&pB->Dbuf_spinlock, flags); + if ( pB->i2Dbuf_stuff != pB->i2Dbuf_strip) + { + queueIndex = pB->i2Dbuf_strip; + pCh = pB->i2Dbuf[queueIndex]; + queueIndex++; + if (queueIndex >= CH_QUEUE_SIZE) { + queueIndex = 0; + } + pB->i2Dbuf_strip = queueIndex; + pCh->channelNeeds &= ~NEED_INLINE; + } + write_unlock_irqrestore(&pB->Dbuf_spinlock, flags); + break; + + case NEED_BYPASS: + + write_lock_irqsave(&pB->Bbuf_spinlock, flags); + if (pB->i2Bbuf_stuff != pB->i2Bbuf_strip) + { + queueIndex = pB->i2Bbuf_strip; + pCh = pB->i2Bbuf[queueIndex]; + queueIndex++; + if (queueIndex >= CH_QUEUE_SIZE) { + queueIndex = 0; + } + pB->i2Bbuf_strip = queueIndex; + pCh->channelNeeds &= ~NEED_BYPASS; + } + write_unlock_irqrestore(&pB->Bbuf_spinlock, flags); + break; + + case NEED_FLOW: + + write_lock_irqsave(&pB->Fbuf_spinlock, flags); + if (pB->i2Fbuf_stuff != pB->i2Fbuf_strip) + { + queueIndex = pB->i2Fbuf_strip; + pCh = pB->i2Fbuf[queueIndex]; + queueIndex++; + if (queueIndex >= CH_QUEUE_SIZE) { + queueIndex = 0; + } + pB->i2Fbuf_strip = queueIndex; + pCh->channelNeeds &= ~NEED_FLOW; + } + write_unlock_irqrestore(&pB->Fbuf_spinlock, flags); + break; + default: + printk(KERN_ERR "i2DeQueueNeeds called with bad type:%x\n",type); + break; + } + return pCh; +} + +//****************************************************************************** +// Function: i2QueueNeeds(pB, pCh, type) +// Parameters: Pointer to a board structure +// Pointer to a channel structure +// type bit map: may include NEED_INLINE, NEED_BYPASS, or NEED_FLOW +// Returns: Nothing +// +// Description: +// For each type of need selected, if the given channel is not already in the +// queue, adds it, and sets the flag indicating it is in the queue. +//****************************************************************************** +static void +i2QueueNeeds(i2eBordStrPtr pB, i2ChanStrPtr pCh, int type) +{ + unsigned short queueIndex; + unsigned long flags; + + // We turn off all the interrupts during this brief process, since the + // interrupt-level code might want to put things on the queue as well. + + switch (type) { + + case NEED_INLINE: + + write_lock_irqsave(&pB->Dbuf_spinlock, flags); + if ( !(pCh->channelNeeds & NEED_INLINE) ) + { + pCh->channelNeeds |= NEED_INLINE; + queueIndex = pB->i2Dbuf_stuff; + pB->i2Dbuf[queueIndex++] = pCh; + if (queueIndex >= CH_QUEUE_SIZE) + queueIndex = 0; + pB->i2Dbuf_stuff = queueIndex; + } + write_unlock_irqrestore(&pB->Dbuf_spinlock, flags); + break; + + case NEED_BYPASS: + + write_lock_irqsave(&pB->Bbuf_spinlock, flags); + if ((type & NEED_BYPASS) && !(pCh->channelNeeds & NEED_BYPASS)) + { + pCh->channelNeeds |= NEED_BYPASS; + queueIndex = pB->i2Bbuf_stuff; + pB->i2Bbuf[queueIndex++] = pCh; + if (queueIndex >= CH_QUEUE_SIZE) + queueIndex = 0; + pB->i2Bbuf_stuff = queueIndex; + } + write_unlock_irqrestore(&pB->Bbuf_spinlock, flags); + break; + + case NEED_FLOW: + + write_lock_irqsave(&pB->Fbuf_spinlock, flags); + if ((type & NEED_FLOW) && !(pCh->channelNeeds & NEED_FLOW)) + { + pCh->channelNeeds |= NEED_FLOW; + queueIndex = pB->i2Fbuf_stuff; + pB->i2Fbuf[queueIndex++] = pCh; + if (queueIndex >= CH_QUEUE_SIZE) + queueIndex = 0; + pB->i2Fbuf_stuff = queueIndex; + } + write_unlock_irqrestore(&pB->Fbuf_spinlock, flags); + break; + + case NEED_CREDIT: + pCh->channelNeeds |= NEED_CREDIT; + break; + default: + printk(KERN_ERR "i2QueueNeeds called with bad type:%x\n",type); + break; + } + return; +} + +//****************************************************************************** +// Function: i2QueueCommands(type, pCh, timeout, nCommands, pCs,...) +// Parameters: type - PTYPE_BYPASS or PTYPE_INLINE +// pointer to the channel structure +// maximum period to wait +// number of commands (n) +// n commands +// Returns: Number of commands sent, or -1 for error +// +// get board lock before calling +// +// Description: +// Queues up some commands to be sent to a channel. To send possibly several +// bypass or inline commands to the given channel. The timeout parameter +// indicates how many HUNDREDTHS OF SECONDS to wait until there is room: +// 0 = return immediately if no room, -ive = wait forever, +ive = number of +// 1/100 seconds to wait. Return values: +// -1 Some kind of nasty error: bad channel structure or invalid arguments. +// 0 No room to send all the commands +// (+) Number of commands sent +//****************************************************************************** +static int +i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands, + cmdSyntaxPtr pCs0,...) +{ + int totalsize = 0; + int blocksize; + int lastended; + cmdSyntaxPtr *ppCs; + cmdSyntaxPtr pCs; + int count; + int flag; + i2eBordStrPtr pB; + + unsigned short maxBlock; + unsigned short maxBuff; + short bufroom; + unsigned short stuffIndex; + unsigned char *pBuf; + unsigned char *pInsert; + unsigned char *pDest, *pSource; + unsigned short channel; + int cnt; + unsigned long flags = 0; + rwlock_t *lock_var_p = NULL; + + // Make sure the channel exists, otherwise do nothing + if ( !i2Validate ( pCh ) ) { + return -1; + } + + ip2trace (CHANN, ITRC_QUEUE, ITRC_ENTER, 0 ); + + pB = pCh->pMyBord; + + // Board must also exist, and THE INTERRUPT COMMAND ALREADY SENT + if (pB->i2eValid != I2E_MAGIC || pB->i2eUsingIrq == I2_IRQ_UNDEFINED) + return -2; + // If the board has gone fatal, return bad, and also hit the trap routine if + // it exists. + if (pB->i2eFatal) { + if ( pB->i2eFatalTrap ) { + (*(pB)->i2eFatalTrap)(pB); + } + return -3; + } + // Set up some variables, Which buffers are we using? How big are they? + switch(type) + { + case PTYPE_INLINE: + flag = INL; + maxBlock = MAX_OBUF_BLOCK; + maxBuff = OBUF_SIZE; + pBuf = pCh->Obuf; + break; + case PTYPE_BYPASS: + flag = BYP; + maxBlock = MAX_CBUF_BLOCK; + maxBuff = CBUF_SIZE; + pBuf = pCh->Cbuf; + break; + default: + return -4; + } + // Determine the total size required for all the commands + totalsize = blocksize = sizeof(i2CmdHeader); + lastended = 0; + ppCs = &pCs0; + for ( count = nCommands; count; count--, ppCs++) + { + pCs = *ppCs; + cnt = pCs->length; + // Will a new block be needed for this one? + // Two possible reasons: too + // big or previous command has to be at the end of a packet. + if ((blocksize + cnt > maxBlock) || lastended) { + blocksize = sizeof(i2CmdHeader); + totalsize += sizeof(i2CmdHeader); + } + totalsize += cnt; + blocksize += cnt; + + // If this command had to end a block, then we will make sure to + // account for it should there be any more blocks. + lastended = pCs->flags & END; + } + for (;;) { + // Make sure any pending flush commands go out before we add more data. + if ( !( pCh->flush_flags && i2RetryFlushOutput( pCh ) ) ) { + // How much room (this time through) ? + switch(type) { + case PTYPE_INLINE: + lock_var_p = &pCh->Obuf_spinlock; + write_lock_irqsave(lock_var_p, flags); + stuffIndex = pCh->Obuf_stuff; + bufroom = pCh->Obuf_strip - stuffIndex; + break; + case PTYPE_BYPASS: + lock_var_p = &pCh->Cbuf_spinlock; + write_lock_irqsave(lock_var_p, flags); + stuffIndex = pCh->Cbuf_stuff; + bufroom = pCh->Cbuf_strip - stuffIndex; + break; + default: + return -5; + } + if (--bufroom < 0) { + bufroom += maxBuff; + } + + ip2trace (CHANN, ITRC_QUEUE, 2, 1, bufroom ); + + // Check for overflow + if (totalsize <= bufroom) { + // Normal Expected path - We still hold LOCK + break; /* from for()- Enough room: goto proceed */ + } + ip2trace(CHANN, ITRC_QUEUE, 3, 1, totalsize); + write_unlock_irqrestore(lock_var_p, flags); + } else + ip2trace(CHANN, ITRC_QUEUE, 3, 1, totalsize); + + /* Prepare to wait for buffers to empty */ + serviceOutgoingFifo(pB); // Dump what we got + + if (timeout == 0) { + return 0; // Tired of waiting + } + if (timeout > 0) + timeout--; // So negative values == forever + + if (!in_interrupt()) { + schedule_timeout_interruptible(1); // short nap + } else { + // we cannot sched/sleep in interrupt silly + return 0; + } + if (signal_pending(current)) { + return 0; // Wake up! Time to die!!! + } + + ip2trace (CHANN, ITRC_QUEUE, 4, 0 ); + + } // end of for(;;) + + // At this point we have room and the lock - stick them in. + channel = pCh->infl.hd.i2sChannel; + pInsert = &pBuf[stuffIndex]; // Pointer to start of packet + pDest = CMD_OF(pInsert); // Pointer to start of command + + // When we start counting, the block is the size of the header + for (blocksize = sizeof(i2CmdHeader), count = nCommands, + lastended = 0, ppCs = &pCs0; + count; + count--, ppCs++) + { + pCs = *ppCs; // Points to command protocol structure + + // If this is a bookmark request command, post the fact that a bookmark + // request is pending. NOTE THIS TRICK ONLY WORKS BECAUSE CMD_BMARK_REQ + // has no parameters! The more general solution would be to reference + // pCs->cmd[0]. + if (pCs == CMD_BMARK_REQ) { + pCh->bookMarks++; + + ip2trace (CHANN, ITRC_DRAIN, 30, 1, pCh->bookMarks ); + + } + cnt = pCs->length; + + // If this command would put us over the maximum block size or + // if the last command had to be at the end of a block, we end + // the existing block here and start a new one. + if ((blocksize + cnt > maxBlock) || lastended) { + + ip2trace (CHANN, ITRC_QUEUE, 5, 0 ); + + PTYPE_OF(pInsert) = type; + CHANNEL_OF(pInsert) = channel; + // count here does not include the header + CMD_COUNT_OF(pInsert) = blocksize - sizeof(i2CmdHeader); + stuffIndex += blocksize; + if(stuffIndex >= maxBuff) { + stuffIndex = 0; + pInsert = pBuf; + } + pInsert = &pBuf[stuffIndex]; // Pointer to start of next pkt + pDest = CMD_OF(pInsert); + blocksize = sizeof(i2CmdHeader); + } + // Now we know there is room for this one in the current block + + blocksize += cnt; // Total bytes in this command + pSource = pCs->cmd; // Copy the command into the buffer + while (cnt--) { + *pDest++ = *pSource++; + } + // If this command had to end a block, then we will make sure to account + // for it should there be any more blocks. + lastended = pCs->flags & END; + } // end for + // Clean up the final block by writing header, etc + + PTYPE_OF(pInsert) = type; + CHANNEL_OF(pInsert) = channel; + // count here does not include the header + CMD_COUNT_OF(pInsert) = blocksize - sizeof(i2CmdHeader); + stuffIndex += blocksize; + if(stuffIndex >= maxBuff) { + stuffIndex = 0; + pInsert = pBuf; + } + // Updates the index, and post the need for service. When adding these to + // the queue of channels, we turn off the interrupt while doing so, + // because at interrupt level we might want to push a channel back to the + // end of the queue. + switch(type) + { + case PTYPE_INLINE: + pCh->Obuf_stuff = stuffIndex; // Store buffer pointer + write_unlock_irqrestore(&pCh->Obuf_spinlock, flags); + + pB->debugInlineQueued++; + // Add the channel pointer to list of channels needing service (first + // come...), if it's not already there. + i2QueueNeeds(pB, pCh, NEED_INLINE); + break; + + case PTYPE_BYPASS: + pCh->Cbuf_stuff = stuffIndex; // Store buffer pointer + write_unlock_irqrestore(&pCh->Cbuf_spinlock, flags); + + pB->debugBypassQueued++; + // Add the channel pointer to list of channels needing service (first + // come...), if it's not already there. + i2QueueNeeds(pB, pCh, NEED_BYPASS); + break; + } + + ip2trace (CHANN, ITRC_QUEUE, ITRC_RETURN, 1, nCommands ); + + return nCommands; // Good status: number of commands sent +} + +//****************************************************************************** +// Function: i2GetStatus(pCh,resetBits) +// Parameters: Pointer to a channel structure +// Bit map of status bits to clear +// Returns: Bit map of current status bits +// +// Description: +// Returns the state of data set signals, and whether a break has been received, +// (see i2lib.h for bit-mapped result). resetBits is a bit-map of any status +// bits to be cleared: I2_BRK, I2_PAR, I2_FRA, I2_OVR,... These are cleared +// AFTER the condition is passed. If pCh does not point to a valid channel, +// returns -1 (which would be impossible otherwise. +//****************************************************************************** +static int +i2GetStatus(i2ChanStrPtr pCh, int resetBits) +{ + unsigned short status; + i2eBordStrPtr pB; + + ip2trace (CHANN, ITRC_STATUS, ITRC_ENTER, 2, pCh->dataSetIn, resetBits ); + + // Make sure the channel exists, otherwise do nothing */ + if ( !i2Validate ( pCh ) ) + return -1; + + pB = pCh->pMyBord; + + status = pCh->dataSetIn; + + // Clear any specified error bits: but note that only actual error bits can + // be cleared, regardless of the value passed. + if (resetBits) + { + pCh->dataSetIn &= ~(resetBits & (I2_BRK | I2_PAR | I2_FRA | I2_OVR)); + pCh->dataSetIn &= ~(I2_DDCD | I2_DCTS | I2_DDSR | I2_DRI); + } + + ip2trace (CHANN, ITRC_STATUS, ITRC_RETURN, 1, pCh->dataSetIn ); + + return status; +} + +//****************************************************************************** +// Function: i2Input(pChpDest,count) +// Parameters: Pointer to a channel structure +// Pointer to data buffer +// Number of bytes to read +// Returns: Number of bytes read, or -1 for error +// +// Description: +// Strips data from the input buffer and writes it to pDest. If there is a +// collosal blunder, (invalid structure pointers or the like), returns -1. +// Otherwise, returns the number of bytes read. +//****************************************************************************** +static int +i2Input(i2ChanStrPtr pCh) +{ + int amountToMove; + unsigned short stripIndex; + int count; + unsigned long flags = 0; + + ip2trace (CHANN, ITRC_INPUT, ITRC_ENTER, 0); + + // Ensure channel structure seems real + if ( !i2Validate( pCh ) ) { + count = -1; + goto i2Input_exit; + } + write_lock_irqsave(&pCh->Ibuf_spinlock, flags); + + // initialize some accelerators and private copies + stripIndex = pCh->Ibuf_strip; + + count = pCh->Ibuf_stuff - stripIndex; + + // If buffer is empty or requested data count was 0, (trivial case) return + // without any further thought. + if ( count == 0 ) { + write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); + goto i2Input_exit; + } + // Adjust for buffer wrap + if ( count < 0 ) { + count += IBUF_SIZE; + } + // Don't give more than can be taken by the line discipline + amountToMove = pCh->pTTY->receive_room; + if (count > amountToMove) { + count = amountToMove; + } + // How much could we copy without a wrap? + amountToMove = IBUF_SIZE - stripIndex; + + if (amountToMove > count) { + amountToMove = count; + } + // Move the first block + pCh->pTTY->ldisc->ops->receive_buf( pCh->pTTY, + &(pCh->Ibuf[stripIndex]), NULL, amountToMove ); + // If we needed to wrap, do the second data move + if (count > amountToMove) { + pCh->pTTY->ldisc->ops->receive_buf( pCh->pTTY, + pCh->Ibuf, NULL, count - amountToMove ); + } + // Bump and wrap the stripIndex all at once by the amount of data read. This + // method is good regardless of whether the data was in one or two pieces. + stripIndex += count; + if (stripIndex >= IBUF_SIZE) { + stripIndex -= IBUF_SIZE; + } + pCh->Ibuf_strip = stripIndex; + + // Update our flow control information and possibly queue ourselves to send + // it, depending on how much data has been stripped since the last time a + // packet was sent. + pCh->infl.asof += count; + + if ((pCh->sinceLastFlow += count) >= pCh->whenSendFlow) { + pCh->sinceLastFlow -= pCh->whenSendFlow; + write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); + i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW); + } else { + write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); + } + +i2Input_exit: + + ip2trace (CHANN, ITRC_INPUT, ITRC_RETURN, 1, count); + + return count; +} + +//****************************************************************************** +// Function: i2InputFlush(pCh) +// Parameters: Pointer to a channel structure +// Returns: Number of bytes stripped, or -1 for error +// +// Description: +// Strips any data from the input buffer. If there is a collosal blunder, +// (invalid structure pointers or the like), returns -1. Otherwise, returns the +// number of bytes stripped. +//****************************************************************************** +static int +i2InputFlush(i2ChanStrPtr pCh) +{ + int count; + unsigned long flags; + + // Ensure channel structure seems real + if ( !i2Validate ( pCh ) ) + return -1; + + ip2trace (CHANN, ITRC_INPUT, 10, 0); + + write_lock_irqsave(&pCh->Ibuf_spinlock, flags); + count = pCh->Ibuf_stuff - pCh->Ibuf_strip; + + // Adjust for buffer wrap + if (count < 0) { + count += IBUF_SIZE; + } + + // Expedient way to zero out the buffer + pCh->Ibuf_strip = pCh->Ibuf_stuff; + + + // Update our flow control information and possibly queue ourselves to send + // it, depending on how much data has been stripped since the last time a + // packet was sent. + + pCh->infl.asof += count; + + if ( (pCh->sinceLastFlow += count) >= pCh->whenSendFlow ) + { + pCh->sinceLastFlow -= pCh->whenSendFlow; + write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); + i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW); + } else { + write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); + } + + ip2trace (CHANN, ITRC_INPUT, 19, 1, count); + + return count; +} + +//****************************************************************************** +// Function: i2InputAvailable(pCh) +// Parameters: Pointer to a channel structure +// Returns: Number of bytes available, or -1 for error +// +// Description: +// If there is a collosal blunder, (invalid structure pointers or the like), +// returns -1. Otherwise, returns the number of bytes stripped. Otherwise, +// returns the number of bytes available in the buffer. +//****************************************************************************** +#if 0 +static int +i2InputAvailable(i2ChanStrPtr pCh) +{ + int count; + + // Ensure channel structure seems real + if ( !i2Validate ( pCh ) ) return -1; + + + // initialize some accelerators and private copies + read_lock_irqsave(&pCh->Ibuf_spinlock, flags); + count = pCh->Ibuf_stuff - pCh->Ibuf_strip; + read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); + + // Adjust for buffer wrap + if (count < 0) + { + count += IBUF_SIZE; + } + + return count; +} +#endif + +//****************************************************************************** +// Function: i2Output(pCh, pSource, count) +// Parameters: Pointer to channel structure +// Pointer to source data +// Number of bytes to send +// Returns: Number of bytes sent, or -1 for error +// +// Description: +// Queues the data at pSource to be sent as data packets to the board. If there +// is a collosal blunder, (invalid structure pointers or the like), returns -1. +// Otherwise, returns the number of bytes written. What if there is not enough +// room for all the data? If pCh->channelOptions & CO_NBLOCK_WRITE is set, then +// we transfer as many characters as we can now, then return. If this bit is +// clear (default), routine will spin along until all the data is buffered. +// Should this occur, the 1-ms delay routine is called while waiting to avoid +// applications that one cannot break out of. +//****************************************************************************** +static int +i2Output(i2ChanStrPtr pCh, const char *pSource, int count) +{ + i2eBordStrPtr pB; + unsigned char *pInsert; + int amountToMove; + int countOriginal = count; + unsigned short channel; + unsigned short stuffIndex; + unsigned long flags; + + int bailout = 10; + + ip2trace (CHANN, ITRC_OUTPUT, ITRC_ENTER, 2, count, 0 ); + + // Ensure channel structure seems real + if ( !i2Validate ( pCh ) ) + return -1; + + // initialize some accelerators and private copies + pB = pCh->pMyBord; + channel = pCh->infl.hd.i2sChannel; + + // If the board has gone fatal, return bad, and also hit the trap routine if + // it exists. + if (pB->i2eFatal) { + if (pB->i2eFatalTrap) { + (*(pB)->i2eFatalTrap)(pB); + } + return -1; + } + // Proceed as though we would do everything + while ( count > 0 ) { + + // How much room in output buffer is there? + read_lock_irqsave(&pCh->Obuf_spinlock, flags); + amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1; + read_unlock_irqrestore(&pCh->Obuf_spinlock, flags); + if (amountToMove < 0) { + amountToMove += OBUF_SIZE; + } + // Subtract off the headers size and see how much room there is for real + // data. If this is negative, we will discover later. + amountToMove -= sizeof (i2DataHeader); + + // Don't move more (now) than can go in a single packet + if ( amountToMove > (int)(MAX_OBUF_BLOCK - sizeof(i2DataHeader)) ) { + amountToMove = MAX_OBUF_BLOCK - sizeof(i2DataHeader); + } + // Don't move more than the count we were given + if (amountToMove > count) { + amountToMove = count; + } + // Now we know how much we must move: NB because the ring buffers have + // an overflow area at the end, we needn't worry about wrapping in the + // middle of a packet. + +// Small WINDOW here with no LOCK but I can't call Flush with LOCK +// We would be flushing (or ending flush) anyway + + ip2trace (CHANN, ITRC_OUTPUT, 10, 1, amountToMove ); + + if ( !(pCh->flush_flags && i2RetryFlushOutput(pCh) ) + && amountToMove > 0 ) + { + write_lock_irqsave(&pCh->Obuf_spinlock, flags); + stuffIndex = pCh->Obuf_stuff; + + // Had room to move some data: don't know whether the block size, + // buffer space, or what was the limiting factor... + pInsert = &(pCh->Obuf[stuffIndex]); + + // Set up the header + CHANNEL_OF(pInsert) = channel; + PTYPE_OF(pInsert) = PTYPE_DATA; + TAG_OF(pInsert) = 0; + ID_OF(pInsert) = ID_ORDINARY_DATA; + DATA_COUNT_OF(pInsert) = amountToMove; + + // Move the data + memcpy( (char*)(DATA_OF(pInsert)), pSource, amountToMove ); + // Adjust pointers and indices + pSource += amountToMove; + pCh->Obuf_char_count += amountToMove; + stuffIndex += amountToMove + sizeof(i2DataHeader); + count -= amountToMove; + + if (stuffIndex >= OBUF_SIZE) { + stuffIndex = 0; + } + pCh->Obuf_stuff = stuffIndex; + + write_unlock_irqrestore(&pCh->Obuf_spinlock, flags); + + ip2trace (CHANN, ITRC_OUTPUT, 13, 1, stuffIndex ); + + } else { + + // Cannot move data + // becuz we need to stuff a flush + // or amount to move is <= 0 + + ip2trace(CHANN, ITRC_OUTPUT, 14, 3, + amountToMove, pB->i2eFifoRemains, + pB->i2eWaitingForEmptyFifo ); + + // Put this channel back on queue + // this ultimatly gets more data or wakes write output + i2QueueNeeds(pB, pCh, NEED_INLINE); + + if ( pB->i2eWaitingForEmptyFifo ) { + + ip2trace (CHANN, ITRC_OUTPUT, 16, 0 ); + + // or schedule + if (!in_interrupt()) { + + ip2trace (CHANN, ITRC_OUTPUT, 61, 0 ); + + schedule_timeout_interruptible(2); + if (signal_pending(current)) { + break; + } + continue; + } else { + + ip2trace (CHANN, ITRC_OUTPUT, 62, 0 ); + + // let interrupt in = WAS restore_flags() + // We hold no lock nor is irq off anymore??? + + break; + } + break; // from while(count) + } + else if ( pB->i2eFifoRemains < 32 && !pB->i2eTxMailEmpty ( pB ) ) + { + ip2trace (CHANN, ITRC_OUTPUT, 19, 2, + pB->i2eFifoRemains, + pB->i2eTxMailEmpty ); + + break; // from while(count) + } else if ( pCh->channelNeeds & NEED_CREDIT ) { + + ip2trace (CHANN, ITRC_OUTPUT, 22, 0 ); + + break; // from while(count) + } else if ( --bailout) { + + // Try to throw more things (maybe not us) in the fifo if we're + // not already waiting for it. + + ip2trace (CHANN, ITRC_OUTPUT, 20, 0 ); + + serviceOutgoingFifo(pB); + //break; CONTINUE; + } else { + ip2trace (CHANN, ITRC_OUTPUT, 21, 3, + pB->i2eFifoRemains, + pB->i2eOutMailWaiting, + pB->i2eWaitingForEmptyFifo ); + + break; // from while(count) + } + } + } // End of while(count) + + i2QueueNeeds(pB, pCh, NEED_INLINE); + + // We drop through either when the count expires, or when there is some + // count left, but there was a non-blocking write. + if (countOriginal > count) { + + ip2trace (CHANN, ITRC_OUTPUT, 17, 2, countOriginal, count ); + + serviceOutgoingFifo( pB ); + } + + ip2trace (CHANN, ITRC_OUTPUT, ITRC_RETURN, 2, countOriginal, count ); + + return countOriginal - count; +} + +//****************************************************************************** +// Function: i2FlushOutput(pCh) +// Parameters: Pointer to a channel structure +// Returns: Nothing +// +// Description: +// Sends bypass command to start flushing (waiting possibly forever until there +// is room), then sends inline command to stop flushing output, (again waiting +// possibly forever). +//****************************************************************************** +static inline void +i2FlushOutput(i2ChanStrPtr pCh) +{ + + ip2trace (CHANN, ITRC_FLUSH, 1, 1, pCh->flush_flags ); + + if (pCh->flush_flags) + return; + + if ( 1 != i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_STARTFL) ) { + pCh->flush_flags = STARTFL_FLAG; // Failed - flag for later + + ip2trace (CHANN, ITRC_FLUSH, 2, 0 ); + + } else if ( 1 != i2QueueCommands(PTYPE_INLINE, pCh, 0, 1, CMD_STOPFL) ) { + pCh->flush_flags = STOPFL_FLAG; // Failed - flag for later + + ip2trace (CHANN, ITRC_FLUSH, 3, 0 ); + } +} + +static int +i2RetryFlushOutput(i2ChanStrPtr pCh) +{ + int old_flags = pCh->flush_flags; + + ip2trace (CHANN, ITRC_FLUSH, 14, 1, old_flags ); + + pCh->flush_flags = 0; // Clear flag so we can avoid recursion + // and queue the commands + + if ( old_flags & STARTFL_FLAG ) { + if ( 1 == i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_STARTFL) ) { + old_flags = STOPFL_FLAG; //Success - send stop flush + } else { + old_flags = STARTFL_FLAG; //Failure - Flag for retry later + } + + ip2trace (CHANN, ITRC_FLUSH, 15, 1, old_flags ); + + } + if ( old_flags & STOPFL_FLAG ) { + if (1 == i2QueueCommands(PTYPE_INLINE, pCh, 0, 1, CMD_STOPFL)) { + old_flags = 0; // Success - clear flags + } + + ip2trace (CHANN, ITRC_FLUSH, 16, 1, old_flags ); + } + pCh->flush_flags = old_flags; + + ip2trace (CHANN, ITRC_FLUSH, 17, 1, old_flags ); + + return old_flags; +} + +//****************************************************************************** +// Function: i2DrainOutput(pCh,timeout) +// Parameters: Pointer to a channel structure +// Maximum period to wait +// Returns: ? +// +// Description: +// Uses the bookmark request command to ask the board to send a bookmark back as +// soon as all the data is completely sent. +//****************************************************************************** +static void +i2DrainWakeup(unsigned long d) +{ + i2ChanStrPtr pCh = (i2ChanStrPtr)d; + + ip2trace (CHANN, ITRC_DRAIN, 10, 1, pCh->BookmarkTimer.expires ); + + pCh->BookmarkTimer.expires = 0; + wake_up_interruptible( &pCh->pBookmarkWait ); +} + +static void +i2DrainOutput(i2ChanStrPtr pCh, int timeout) +{ + wait_queue_t wait; + i2eBordStrPtr pB; + + ip2trace (CHANN, ITRC_DRAIN, ITRC_ENTER, 1, pCh->BookmarkTimer.expires); + + pB = pCh->pMyBord; + // If the board has gone fatal, return bad, + // and also hit the trap routine if it exists. + if (pB->i2eFatal) { + if (pB->i2eFatalTrap) { + (*(pB)->i2eFatalTrap)(pB); + } + return; + } + if ((timeout > 0) && (pCh->BookmarkTimer.expires == 0 )) { + // One per customer (channel) + setup_timer(&pCh->BookmarkTimer, i2DrainWakeup, + (unsigned long)pCh); + + ip2trace (CHANN, ITRC_DRAIN, 1, 1, pCh->BookmarkTimer.expires ); + + mod_timer(&pCh->BookmarkTimer, jiffies + timeout); + } + + i2QueueCommands( PTYPE_INLINE, pCh, -1, 1, CMD_BMARK_REQ ); + + init_waitqueue_entry(&wait, current); + add_wait_queue(&(pCh->pBookmarkWait), &wait); + set_current_state( TASK_INTERRUPTIBLE ); + + serviceOutgoingFifo( pB ); + + schedule(); // Now we take our interruptible sleep on + + // Clean up the queue + set_current_state( TASK_RUNNING ); + remove_wait_queue(&(pCh->pBookmarkWait), &wait); + + // if expires == 0 then timer poped, then do not need to del_timer + if ((timeout > 0) && pCh->BookmarkTimer.expires && + time_before(jiffies, pCh->BookmarkTimer.expires)) { + del_timer( &(pCh->BookmarkTimer) ); + pCh->BookmarkTimer.expires = 0; + + ip2trace (CHANN, ITRC_DRAIN, 3, 1, pCh->BookmarkTimer.expires ); + + } + ip2trace (CHANN, ITRC_DRAIN, ITRC_RETURN, 1, pCh->BookmarkTimer.expires ); + return; +} + +//****************************************************************************** +// Function: i2OutputFree(pCh) +// Parameters: Pointer to a channel structure +// Returns: Space in output buffer +// +// Description: +// Returns -1 if very gross error. Otherwise returns the amount of bytes still +// free in the output buffer. +//****************************************************************************** +static int +i2OutputFree(i2ChanStrPtr pCh) +{ + int amountToMove; + unsigned long flags; + + // Ensure channel structure seems real + if ( !i2Validate ( pCh ) ) { + return -1; + } + read_lock_irqsave(&pCh->Obuf_spinlock, flags); + amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1; + read_unlock_irqrestore(&pCh->Obuf_spinlock, flags); + + if (amountToMove < 0) { + amountToMove += OBUF_SIZE; + } + // If this is negative, we will discover later + amountToMove -= sizeof(i2DataHeader); + + return (amountToMove < 0) ? 0 : amountToMove; +} +static void + +ip2_owake( PTTY tp) +{ + i2ChanStrPtr pCh; + + if (tp == NULL) return; + + pCh = tp->driver_data; + + ip2trace (CHANN, ITRC_SICMD, 10, 2, tp->flags, + (1 << TTY_DO_WRITE_WAKEUP) ); + + tty_wakeup(tp); +} + +static inline void +set_baud_params(i2eBordStrPtr pB) +{ + int i,j; + i2ChanStrPtr *pCh; + + pCh = (i2ChanStrPtr *) pB->i2eChannelPtr; + + for (i = 0; i < ABS_MAX_BOXES; i++) { + if (pB->channelBtypes.bid_value[i]) { + if (BID_HAS_654(pB->channelBtypes.bid_value[i])) { + for (j = 0; j < ABS_BIGGEST_BOX; j++) { + if (pCh[i*16+j] == NULL) + break; + (pCh[i*16+j])->BaudBase = 921600; // MAX for ST654 + (pCh[i*16+j])->BaudDivisor = 96; + } + } else { // has cirrus cd1400 + for (j = 0; j < ABS_BIGGEST_BOX; j++) { + if (pCh[i*16+j] == NULL) + break; + (pCh[i*16+j])->BaudBase = 115200; // MAX for CD1400 + (pCh[i*16+j])->BaudDivisor = 12; + } + } + } + } +} + +//****************************************************************************** +// Function: i2StripFifo(pB) +// Parameters: Pointer to a board structure +// Returns: ? +// +// Description: +// Strips all the available data from the incoming FIFO, identifies the type of +// packet, and either buffers the data or does what needs to be done. +// +// Note there is no overflow checking here: if the board sends more data than it +// ought to, we will not detect it here, but blindly overflow... +//****************************************************************************** + +// A buffer for reading in blocks for unknown channels +static unsigned char junkBuffer[IBUF_SIZE]; + +// A buffer to read in a status packet. Because of the size of the count field +// for these things, the maximum packet size must be less than MAX_CMD_PACK_SIZE +static unsigned char cmdBuffer[MAX_CMD_PACK_SIZE + 4]; + +// This table changes the bit order from MSR order given by STAT_MODEM packet to +// status bits used in our library. +static char xlatDss[16] = { +0 | 0 | 0 | 0 , +0 | 0 | 0 | I2_CTS , +0 | 0 | I2_DSR | 0 , +0 | 0 | I2_DSR | I2_CTS , +0 | I2_RI | 0 | 0 , +0 | I2_RI | 0 | I2_CTS , +0 | I2_RI | I2_DSR | 0 , +0 | I2_RI | I2_DSR | I2_CTS , +I2_DCD | 0 | 0 | 0 , +I2_DCD | 0 | 0 | I2_CTS , +I2_DCD | 0 | I2_DSR | 0 , +I2_DCD | 0 | I2_DSR | I2_CTS , +I2_DCD | I2_RI | 0 | 0 , +I2_DCD | I2_RI | 0 | I2_CTS , +I2_DCD | I2_RI | I2_DSR | 0 , +I2_DCD | I2_RI | I2_DSR | I2_CTS }; + +static inline void +i2StripFifo(i2eBordStrPtr pB) +{ + i2ChanStrPtr pCh; + int channel; + int count; + unsigned short stuffIndex; + int amountToRead; + unsigned char *pc, *pcLimit; + unsigned char uc; + unsigned char dss_change; + unsigned long bflags,cflags; + +// ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_ENTER, 0 ); + + while (I2_HAS_INPUT(pB)) { +// ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 2, 0 ); + + // Process packet from fifo a one atomic unit + write_lock_irqsave(&pB->read_fifo_spinlock, bflags); + + // The first word (or two bytes) will have channel number and type of + // packet, possibly other information + pB->i2eLeadoffWord[0] = iiReadWord(pB); + + switch(PTYPE_OF(pB->i2eLeadoffWord)) + { + case PTYPE_DATA: + pB->got_input = 1; + +// ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 3, 0 ); + + channel = CHANNEL_OF(pB->i2eLeadoffWord); /* Store channel */ + count = iiReadWord(pB); /* Count is in the next word */ + +// NEW: Check the count for sanity! Should the hardware fail, our death +// is more pleasant. While an oversize channel is acceptable (just more +// than the driver supports), an over-length count clearly means we are +// sick! + if ( ((unsigned int)count) > IBUF_SIZE ) { + pB->i2eFatal = 2; + write_unlock_irqrestore(&pB->read_fifo_spinlock, + bflags); + return; /* Bail out ASAP */ + } + // Channel is illegally big ? + if ((channel >= pB->i2eChannelCnt) || + (NULL==(pCh = ((i2ChanStrPtr*)pB->i2eChannelPtr)[channel]))) + { + iiReadBuf(pB, junkBuffer, count); + write_unlock_irqrestore(&pB->read_fifo_spinlock, + bflags); + break; /* From switch: ready for next packet */ + } + + // Channel should be valid, then + + // If this is a hot-key, merely post its receipt for now. These are + // always supposed to be 1-byte packets, so we won't even check the + // count. Also we will post an acknowledgement to the board so that + // more data can be forthcoming. Note that we are not trying to use + // these sequences in this driver, merely to robustly ignore them. + if(ID_OF(pB->i2eLeadoffWord) == ID_HOT_KEY) + { + pCh->hotKeyIn = iiReadWord(pB) & 0xff; + write_unlock_irqrestore(&pB->read_fifo_spinlock, + bflags); + i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_HOTACK); + break; /* From the switch: ready for next packet */ + } + + // Normal data! We crudely assume there is room for the data in our + // buffer because the board wouldn't have exceeded his credit limit. + write_lock_irqsave(&pCh->Ibuf_spinlock, cflags); + // We have 2 locks now + stuffIndex = pCh->Ibuf_stuff; + amountToRead = IBUF_SIZE - stuffIndex; + if (amountToRead > count) + amountToRead = count; + + // stuffIndex would have been already adjusted so there would + // always be room for at least one, and count is always at least + // one. + + iiReadBuf(pB, &(pCh->Ibuf[stuffIndex]), amountToRead); + pCh->icount.rx += amountToRead; + + // Update the stuffIndex by the amount of data moved. Note we could + // never ask for more data than would just fit. However, we might + // have read in one more byte than we wanted because the read + // rounds up to even bytes. If this byte is on the end of the + // packet, and is padding, we ignore it. If the byte is part of + // the actual data, we need to move it. + + stuffIndex += amountToRead; + + if (stuffIndex >= IBUF_SIZE) { + if ((amountToRead & 1) && (count > amountToRead)) { + pCh->Ibuf[0] = pCh->Ibuf[IBUF_SIZE]; + amountToRead++; + stuffIndex = 1; + } else { + stuffIndex = 0; + } + } + + // If there is anything left over, read it as well + if (count > amountToRead) { + amountToRead = count - amountToRead; + iiReadBuf(pB, &(pCh->Ibuf[stuffIndex]), amountToRead); + pCh->icount.rx += amountToRead; + stuffIndex += amountToRead; + } + + // Update stuff index + pCh->Ibuf_stuff = stuffIndex; + write_unlock_irqrestore(&pCh->Ibuf_spinlock, cflags); + write_unlock_irqrestore(&pB->read_fifo_spinlock, + bflags); + +#ifdef USE_IQ + schedule_work(&pCh->tqueue_input); +#else + do_input(&pCh->tqueue_input); +#endif + + // Note we do not need to maintain any flow-control credits at this + // time: if we were to increment .asof and decrement .room, there + // would be no net effect. Instead, when we strip data, we will + // increment .asof and leave .room unchanged. + + break; // From switch: ready for next packet + + case PTYPE_STATUS: + ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 4, 0 ); + + count = CMD_COUNT_OF(pB->i2eLeadoffWord); + + iiReadBuf(pB, cmdBuffer, count); + // We can release early with buffer grab + write_unlock_irqrestore(&pB->read_fifo_spinlock, + bflags); + + pc = cmdBuffer; + pcLimit = &(cmdBuffer[count]); + + while (pc < pcLimit) { + channel = *pc++; + + ip2trace (channel, ITRC_SFIFO, 7, 2, channel, *pc ); + + /* check for valid channel */ + if (channel < pB->i2eChannelCnt + && + (pCh = (((i2ChanStrPtr*)pB->i2eChannelPtr)[channel])) != NULL + ) + { + dss_change = 0; + + switch (uc = *pc++) + { + /* Breaks and modem signals are easy: just update status */ + case STAT_CTS_UP: + if ( !(pCh->dataSetIn & I2_CTS) ) + { + pCh->dataSetIn |= I2_DCTS; + pCh->icount.cts++; + dss_change = 1; + } + pCh->dataSetIn |= I2_CTS; + break; + + case STAT_CTS_DN: + if ( pCh->dataSetIn & I2_CTS ) + { + pCh->dataSetIn |= I2_DCTS; + pCh->icount.cts++; + dss_change = 1; + } + pCh->dataSetIn &= ~I2_CTS; + break; + + case STAT_DCD_UP: + ip2trace (channel, ITRC_MODEM, 1, 1, pCh->dataSetIn ); + + if ( !(pCh->dataSetIn & I2_DCD) ) + { + ip2trace (CHANN, ITRC_MODEM, 2, 0 ); + pCh->dataSetIn |= I2_DDCD; + pCh->icount.dcd++; + dss_change = 1; + } + pCh->dataSetIn |= I2_DCD; + + ip2trace (channel, ITRC_MODEM, 3, 1, pCh->dataSetIn ); + break; + + case STAT_DCD_DN: + ip2trace (channel, ITRC_MODEM, 4, 1, pCh->dataSetIn ); + if ( pCh->dataSetIn & I2_DCD ) + { + ip2trace (channel, ITRC_MODEM, 5, 0 ); + pCh->dataSetIn |= I2_DDCD; + pCh->icount.dcd++; + dss_change = 1; + } + pCh->dataSetIn &= ~I2_DCD; + + ip2trace (channel, ITRC_MODEM, 6, 1, pCh->dataSetIn ); + break; + + case STAT_DSR_UP: + if ( !(pCh->dataSetIn & I2_DSR) ) + { + pCh->dataSetIn |= I2_DDSR; + pCh->icount.dsr++; + dss_change = 1; + } + pCh->dataSetIn |= I2_DSR; + break; + + case STAT_DSR_DN: + if ( pCh->dataSetIn & I2_DSR ) + { + pCh->dataSetIn |= I2_DDSR; + pCh->icount.dsr++; + dss_change = 1; + } + pCh->dataSetIn &= ~I2_DSR; + break; + + case STAT_RI_UP: + if ( !(pCh->dataSetIn & I2_RI) ) + { + pCh->dataSetIn |= I2_DRI; + pCh->icount.rng++; + dss_change = 1; + } + pCh->dataSetIn |= I2_RI ; + break; + + case STAT_RI_DN: + // to be compat with serial.c + //if ( pCh->dataSetIn & I2_RI ) + //{ + // pCh->dataSetIn |= I2_DRI; + // pCh->icount.rng++; + // dss_change = 1; + //} + pCh->dataSetIn &= ~I2_RI ; + break; + + case STAT_BRK_DET: + pCh->dataSetIn |= I2_BRK; + pCh->icount.brk++; + dss_change = 1; + break; + + // Bookmarks? one less request we're waiting for + case STAT_BMARK: + pCh->bookMarks--; + if (pCh->bookMarks <= 0 ) { + pCh->bookMarks = 0; + wake_up_interruptible( &pCh->pBookmarkWait ); + + ip2trace (channel, ITRC_DRAIN, 20, 1, pCh->BookmarkTimer.expires ); + } + break; + + // Flow control packets? Update the new credits, and if + // someone was waiting for output, queue him up again. + case STAT_FLOW: + pCh->outfl.room = + ((flowStatPtr)pc)->room - + (pCh->outfl.asof - ((flowStatPtr)pc)->asof); + + ip2trace (channel, ITRC_STFLW, 1, 1, pCh->outfl.room ); + + if (pCh->channelNeeds & NEED_CREDIT) + { + ip2trace (channel, ITRC_STFLW, 2, 1, pCh->channelNeeds); + + pCh->channelNeeds &= ~NEED_CREDIT; + i2QueueNeeds(pB, pCh, NEED_INLINE); + if ( pCh->pTTY ) + ip2_owake(pCh->pTTY); + } + + ip2trace (channel, ITRC_STFLW, 3, 1, pCh->channelNeeds); + + pc += sizeof(flowStat); + break; + + /* Special packets: */ + /* Just copy the information into the channel structure */ + + case STAT_STATUS: + + pCh->channelStatus = *((debugStatPtr)pc); + pc += sizeof(debugStat); + break; + + case STAT_TXCNT: + + pCh->channelTcount = *((cntStatPtr)pc); + pc += sizeof(cntStat); + break; + + case STAT_RXCNT: + + pCh->channelRcount = *((cntStatPtr)pc); + pc += sizeof(cntStat); + break; + + case STAT_BOXIDS: + pB->channelBtypes = *((bidStatPtr)pc); + pc += sizeof(bidStat); + set_baud_params(pB); + break; + + case STAT_HWFAIL: + i2QueueCommands (PTYPE_INLINE, pCh, 0, 1, CMD_HW_TEST); + pCh->channelFail = *((failStatPtr)pc); + pc += sizeof(failStat); + break; + + /* No explicit match? then + * Might be an error packet... + */ + default: + switch (uc & STAT_MOD_ERROR) + { + case STAT_ERROR: + if (uc & STAT_E_PARITY) { + pCh->dataSetIn |= I2_PAR; + pCh->icount.parity++; + } + if (uc & STAT_E_FRAMING){ + pCh->dataSetIn |= I2_FRA; + pCh->icount.frame++; + } + if (uc & STAT_E_OVERRUN){ + pCh->dataSetIn |= I2_OVR; + pCh->icount.overrun++; + } + break; + + case STAT_MODEM: + // the answer to DSS_NOW request (not change) + pCh->dataSetIn = (pCh->dataSetIn + & ~(I2_RI | I2_CTS | I2_DCD | I2_DSR) ) + | xlatDss[uc & 0xf]; + wake_up_interruptible ( &pCh->dss_now_wait ); + default: + break; + } + } /* End of switch on status type */ + if (dss_change) { +#ifdef USE_IQ + schedule_work(&pCh->tqueue_status); +#else + do_status(&pCh->tqueue_status); +#endif + } + } + else /* Or else, channel is invalid */ + { + // Even though the channel is invalid, we must test the + // status to see how much additional data it has (to be + // skipped) + switch (*pc++) + { + case STAT_FLOW: + pc += 4; /* Skip the data */ + break; + + default: + break; + } + } + } // End of while (there is still some status packet left) + break; + + default: // Neither packet? should be impossible + ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 5, 1, + PTYPE_OF(pB->i2eLeadoffWord) ); + write_unlock_irqrestore(&pB->read_fifo_spinlock, + bflags); + + break; + } // End of switch on type of packets + } /*while(board I2_HAS_INPUT)*/ + + ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_RETURN, 0 ); + + // Send acknowledgement to the board even if there was no data! + pB->i2eOutMailWaiting |= MB_IN_STRIPPED; + return; +} + +//****************************************************************************** +// Function: i2Write2Fifo(pB,address,count) +// Parameters: Pointer to a board structure, source address, byte count +// Returns: bytes written +// +// Description: +// Writes count bytes to board io address(implied) from source +// Adjusts count, leaves reserve for next time around bypass cmds +//****************************************************************************** +static int +i2Write2Fifo(i2eBordStrPtr pB, unsigned char *source, int count,int reserve) +{ + int rc = 0; + unsigned long flags; + write_lock_irqsave(&pB->write_fifo_spinlock, flags); + if (!pB->i2eWaitingForEmptyFifo) { + if (pB->i2eFifoRemains > (count+reserve)) { + pB->i2eFifoRemains -= count; + iiWriteBuf(pB, source, count); + pB->i2eOutMailWaiting |= MB_OUT_STUFFED; + rc = count; + } + } + write_unlock_irqrestore(&pB->write_fifo_spinlock, flags); + return rc; +} +//****************************************************************************** +// Function: i2StuffFifoBypass(pB) +// Parameters: Pointer to a board structure +// Returns: Nothing +// +// Description: +// Stuffs as many bypass commands into the fifo as possible. This is simpler +// than stuffing data or inline commands to fifo, since we do not have +// flow-control to deal with. +//****************************************************************************** +static inline void +i2StuffFifoBypass(i2eBordStrPtr pB) +{ + i2ChanStrPtr pCh; + unsigned char *pRemove; + unsigned short stripIndex; + unsigned short packetSize; + unsigned short paddedSize; + unsigned short notClogged = 1; + unsigned long flags; + + int bailout = 1000; + + // Continue processing so long as there are entries, or there is room in the + // fifo. Each entry represents a channel with something to do. + while ( --bailout && notClogged && + (NULL != (pCh = i2DeQueueNeeds(pB,NEED_BYPASS)))) + { + write_lock_irqsave(&pCh->Cbuf_spinlock, flags); + stripIndex = pCh->Cbuf_strip; + + // as long as there are packets for this channel... + + while (stripIndex != pCh->Cbuf_stuff) { + pRemove = &(pCh->Cbuf[stripIndex]); + packetSize = CMD_COUNT_OF(pRemove) + sizeof(i2CmdHeader); + paddedSize = roundup(packetSize, 2); + + if (paddedSize > 0) { + if ( 0 == i2Write2Fifo(pB, pRemove, paddedSize,0)) { + notClogged = 0; /* fifo full */ + i2QueueNeeds(pB, pCh, NEED_BYPASS); // Put back on queue + break; // Break from the channel + } + } +#ifdef DEBUG_FIFO +WriteDBGBuf("BYPS", pRemove, paddedSize); +#endif /* DEBUG_FIFO */ + pB->debugBypassCount++; + + pRemove += packetSize; + stripIndex += packetSize; + if (stripIndex >= CBUF_SIZE) { + stripIndex = 0; + pRemove = pCh->Cbuf; + } + } + // Done with this channel. Move to next, removing this one from + // the queue of channels if we cleaned it out (i.e., didn't get clogged. + pCh->Cbuf_strip = stripIndex; + write_unlock_irqrestore(&pCh->Cbuf_spinlock, flags); + } // Either clogged or finished all the work + +#ifdef IP2DEBUG_TRACE + if ( !bailout ) { + ip2trace (ITRC_NO_PORT, ITRC_ERROR, 1, 0 ); + } +#endif +} + +//****************************************************************************** +// Function: i2StuffFifoFlow(pB) +// Parameters: Pointer to a board structure +// Returns: Nothing +// +// Description: +// Stuffs as many flow control packets into the fifo as possible. This is easier +// even than doing normal bypass commands, because there is always at most one +// packet, already assembled, for each channel. +//****************************************************************************** +static inline void +i2StuffFifoFlow(i2eBordStrPtr pB) +{ + i2ChanStrPtr pCh; + unsigned short paddedSize = roundup(sizeof(flowIn), 2); + + ip2trace (ITRC_NO_PORT, ITRC_SFLOW, ITRC_ENTER, 2, + pB->i2eFifoRemains, paddedSize ); + + // Continue processing so long as there are entries, or there is room in the + // fifo. Each entry represents a channel with something to do. + while ( (NULL != (pCh = i2DeQueueNeeds(pB,NEED_FLOW)))) { + pB->debugFlowCount++; + + // NO Chan LOCK needed ??? + if ( 0 == i2Write2Fifo(pB,(unsigned char *)&(pCh->infl),paddedSize,0)) { + break; + } +#ifdef DEBUG_FIFO + WriteDBGBuf("FLOW",(unsigned char *) &(pCh->infl), paddedSize); +#endif /* DEBUG_FIFO */ + + } // Either clogged or finished all the work + + ip2trace (ITRC_NO_PORT, ITRC_SFLOW, ITRC_RETURN, 0 ); +} + +//****************************************************************************** +// Function: i2StuffFifoInline(pB) +// Parameters: Pointer to a board structure +// Returns: Nothing +// +// Description: +// Stuffs as much data and inline commands into the fifo as possible. This is +// the most complex fifo-stuffing operation, since there if now the channel +// flow-control issue to deal with. +//****************************************************************************** +static inline void +i2StuffFifoInline(i2eBordStrPtr pB) +{ + i2ChanStrPtr pCh; + unsigned char *pRemove; + unsigned short stripIndex; + unsigned short packetSize; + unsigned short paddedSize; + unsigned short notClogged = 1; + unsigned short flowsize; + unsigned long flags; + + int bailout = 1000; + int bailout2; + + ip2trace (ITRC_NO_PORT, ITRC_SICMD, ITRC_ENTER, 3, pB->i2eFifoRemains, + pB->i2Dbuf_strip, pB->i2Dbuf_stuff ); + + // Continue processing so long as there are entries, or there is room in the + // fifo. Each entry represents a channel with something to do. + while ( --bailout && notClogged && + (NULL != (pCh = i2DeQueueNeeds(pB,NEED_INLINE))) ) + { + write_lock_irqsave(&pCh->Obuf_spinlock, flags); + stripIndex = pCh->Obuf_strip; + + ip2trace (CHANN, ITRC_SICMD, 3, 2, stripIndex, pCh->Obuf_stuff ); + + // as long as there are packets for this channel... + bailout2 = 1000; + while ( --bailout2 && stripIndex != pCh->Obuf_stuff) { + pRemove = &(pCh->Obuf[stripIndex]); + + // Must determine whether this be a data or command packet to + // calculate correctly the header size and the amount of + // flow-control credit this type of packet will use. + if (PTYPE_OF(pRemove) == PTYPE_DATA) { + flowsize = DATA_COUNT_OF(pRemove); + packetSize = flowsize + sizeof(i2DataHeader); + } else { + flowsize = CMD_COUNT_OF(pRemove); + packetSize = flowsize + sizeof(i2CmdHeader); + } + flowsize = CREDIT_USAGE(flowsize); + paddedSize = roundup(packetSize, 2); + + ip2trace (CHANN, ITRC_SICMD, 4, 2, pB->i2eFifoRemains, paddedSize ); + + // If we don't have enough credits from the board to send the data, + // flag the channel that we are waiting for flow control credit, and + // break out. This will clean up this channel and remove us from the + // queue of hot things to do. + + ip2trace (CHANN, ITRC_SICMD, 5, 2, pCh->outfl.room, flowsize ); + + if (pCh->outfl.room <= flowsize) { + // Do Not have the credits to send this packet. + i2QueueNeeds(pB, pCh, NEED_CREDIT); + notClogged = 0; + break; // So to do next channel + } + if ( (paddedSize > 0) + && ( 0 == i2Write2Fifo(pB, pRemove, paddedSize, 128))) { + // Do Not have room in fifo to send this packet. + notClogged = 0; + i2QueueNeeds(pB, pCh, NEED_INLINE); + break; // Break from the channel + } +#ifdef DEBUG_FIFO +WriteDBGBuf("DATA", pRemove, paddedSize); +#endif /* DEBUG_FIFO */ + pB->debugInlineCount++; + + pCh->icount.tx += flowsize; + // Update current credits + pCh->outfl.room -= flowsize; + pCh->outfl.asof += flowsize; + if (PTYPE_OF(pRemove) == PTYPE_DATA) { + pCh->Obuf_char_count -= DATA_COUNT_OF(pRemove); + } + pRemove += packetSize; + stripIndex += packetSize; + + ip2trace (CHANN, ITRC_SICMD, 6, 2, stripIndex, pCh->Obuf_strip); + + if (stripIndex >= OBUF_SIZE) { + stripIndex = 0; + pRemove = pCh->Obuf; + + ip2trace (CHANN, ITRC_SICMD, 7, 1, stripIndex ); + + } + } /* while */ + if ( !bailout2 ) { + ip2trace (CHANN, ITRC_ERROR, 3, 0 ); + } + // Done with this channel. Move to next, removing this one from the + // queue of channels if we cleaned it out (i.e., didn't get clogged. + pCh->Obuf_strip = stripIndex; + write_unlock_irqrestore(&pCh->Obuf_spinlock, flags); + if ( notClogged ) + { + + ip2trace (CHANN, ITRC_SICMD, 8, 0 ); + + if ( pCh->pTTY ) { + ip2_owake(pCh->pTTY); + } + } + } // Either clogged or finished all the work + + if ( !bailout ) { + ip2trace (ITRC_NO_PORT, ITRC_ERROR, 4, 0 ); + } + + ip2trace (ITRC_NO_PORT, ITRC_SICMD, ITRC_RETURN, 1,pB->i2Dbuf_strip); +} + +//****************************************************************************** +// Function: serviceOutgoingFifo(pB) +// Parameters: Pointer to a board structure +// Returns: Nothing +// +// Description: +// Helper routine to put data in the outgoing fifo, if we aren't already waiting +// for something to be there. If the fifo has only room for a very little data, +// go head and hit the board with a mailbox hit immediately. Otherwise, it will +// have to happen later in the interrupt processing. Since this routine may be +// called both at interrupt and foreground time, we must turn off interrupts +// during the entire process. +//****************************************************************************** +static void +serviceOutgoingFifo(i2eBordStrPtr pB) +{ + // If we aren't currently waiting for the board to empty our fifo, service + // everything that is pending, in priority order (especially, Bypass before + // Inline). + if ( ! pB->i2eWaitingForEmptyFifo ) + { + i2StuffFifoFlow(pB); + i2StuffFifoBypass(pB); + i2StuffFifoInline(pB); + + iiSendPendingMail(pB); + } +} + +//****************************************************************************** +// Function: i2ServiceBoard(pB) +// Parameters: Pointer to a board structure +// Returns: Nothing +// +// Description: +// Normally this is called from interrupt level, but there is deliberately +// nothing in here specific to being called from interrupt level. All the +// hardware-specific, interrupt-specific things happen at the outer levels. +// +// For example, a timer interrupt could drive this routine for some sort of +// polled operation. The only requirement is that the programmer deal with any +// atomiticity/concurrency issues that result. +// +// This routine responds to the board's having sent mailbox information to the +// host (which would normally cause an interrupt). This routine reads the +// incoming mailbox. If there is no data in it, this board did not create the +// interrupt and/or has nothing to be done to it. (Except, if we have been +// waiting to write mailbox data to it, we may do so. +// +// Based on the value in the mailbox, we may take various actions. +// +// No checking here of pB validity: after all, it shouldn't have been called by +// the handler unless pB were on the list. +//****************************************************************************** +static inline int +i2ServiceBoard ( i2eBordStrPtr pB ) +{ + unsigned inmail; + unsigned long flags; + + + /* This should be atomic because of the way we are called... */ + if (NO_MAIL_HERE == ( inmail = pB->i2eStartMail ) ) { + inmail = iiGetMail(pB); + } + pB->i2eStartMail = NO_MAIL_HERE; + + ip2trace (ITRC_NO_PORT, ITRC_INTR, 2, 1, inmail ); + + if (inmail != NO_MAIL_HERE) { + // If the board has gone fatal, nothing to do but hit a bit that will + // alert foreground tasks to protest! + if ( inmail & MB_FATAL_ERROR ) { + pB->i2eFatal = 1; + goto exit_i2ServiceBoard; + } + + /* Assuming no fatal condition, we proceed to do work */ + if ( inmail & MB_IN_STUFFED ) { + pB->i2eFifoInInts++; + i2StripFifo(pB); /* There might be incoming packets */ + } + + if (inmail & MB_OUT_STRIPPED) { + pB->i2eFifoOutInts++; + write_lock_irqsave(&pB->write_fifo_spinlock, flags); + pB->i2eFifoRemains = pB->i2eFifoSize; + pB->i2eWaitingForEmptyFifo = 0; + write_unlock_irqrestore(&pB->write_fifo_spinlock, + flags); + + ip2trace (ITRC_NO_PORT, ITRC_INTR, 30, 1, pB->i2eFifoRemains ); + + } + serviceOutgoingFifo(pB); + } + + ip2trace (ITRC_NO_PORT, ITRC_INTR, 8, 0 ); + +exit_i2ServiceBoard: + + return 0; +} diff --git a/drivers/staging/tty/ip2/i2lib.h b/drivers/staging/tty/ip2/i2lib.h new file mode 100644 index 000000000000..e559e9bac06d --- /dev/null +++ b/drivers/staging/tty/ip2/i2lib.h @@ -0,0 +1,351 @@ +/******************************************************************************* +* +* (c) 1998 by Computone Corporation +* +******************************************************************************** +* +* +* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport +* serial I/O controllers. +* +* DESCRIPTION: Header file for high level library functions +* +*******************************************************************************/ +#ifndef I2LIB_H +#define I2LIB_H 1 +//------------------------------------------------------------------------------ +// I2LIB.H +// +// IntelliPort-II and IntelliPort-IIEX +// +// Defines, structure definitions, and external declarations for i2lib.c +//------------------------------------------------------------------------------ +//-------------------------------------- +// Mandatory Includes: +//-------------------------------------- +#include "ip2types.h" +#include "i2ellis.h" +#include "i2pack.h" +#include "i2cmd.h" +#include + +//------------------------------------------------------------------------------ +// i2ChanStr -- Channel Structure: +// Used to track per-channel information for the library routines using standard +// loadware. Note also, a pointer to an array of these structures is patched +// into the i2eBordStr (see i2ellis.h) +//------------------------------------------------------------------------------ +// +// If we make some limits on the maximum block sizes, we can avoid dealing with +// buffer wrap. The wrapping of the buffer is based on where the start of the +// packet is. Then there is always room for the packet contiguously. +// +// Maximum total length of an outgoing data or in-line command block. The limit +// of 36 on data is quite arbitrary and based more on DOS memory limitations +// than the board interface. However, for commands, the maximum packet length is +// MAX_CMD_PACK_SIZE, because the field size for the count is only a few bits +// (see I2PACK.H) in such packets. For data packets, the count field size is not +// the limiting factor. As of this writing, MAX_OBUF_BLOCK < MAX_CMD_PACK_SIZE, +// but be careful if wanting to modify either. +// +#define MAX_OBUF_BLOCK 36 + +// Another note on maximum block sizes: we are buffering packets here. Data is +// put into the buffer (if there is room) regardless of the credits from the +// board. The board sends new credits whenever it has removed from his buffers a +// number of characters equal to 80% of total buffer size. (Of course, the total +// buffer size is what is reported when the very first set of flow control +// status packets are received from the board. Therefore, to be robust, you must +// always fill the board to at least 80% of the current credit limit, else you +// might not give it enough to trigger a new report. These conditions are +// obtained here so long as the maximum output block size is less than 20% the +// size of the board's output buffers. This is true at present by "coincidence" +// or "infernal knowledge": the board's output buffers are at least 700 bytes +// long (20% = 140 bytes, at least). The 80% figure is "official", so the safest +// strategy might be to trap the first flow control report and guarantee that +// the effective maxObufBlock is the minimum of MAX_OBUF_BLOCK and 20% of first +// reported buffer credit. +// +#define MAX_CBUF_BLOCK 6 // Maximum total length of a bypass command block + +#define IBUF_SIZE 512 // character capacity of input buffer per channel +#define OBUF_SIZE 1024// character capacity of output buffer per channel +#define CBUF_SIZE 10 // character capacity of output bypass buffer + +typedef struct _i2ChanStr +{ + // First, back-pointers so that given a pointer to this structure, you can + // determine the correct board and channel number to reference, (say, when + // issuing commands, etc. (Note, channel number is in infl.hd.i2sChannel.) + + int port_index; // Index of port in channel structure array attached + // to board structure. + PTTY pTTY; // Pointer to tty structure for port (OS specific) + USHORT validity; // Indicates whether the given channel has been + // initialized, really exists (or is a missing + // channel, e.g. channel 9 on an 8-port box.) + + i2eBordStrPtr pMyBord; // Back-pointer to this channel's board structure + + int wopen; // waiting fer carrier + + int throttled; // Set if upper layer can take no data + + int flags; // Defined in tty.h + + PWAITQ open_wait; // Pointer for OS sleep function. + PWAITQ close_wait; // Pointer for OS sleep function. + PWAITQ delta_msr_wait;// Pointer for OS sleep function. + PWAITQ dss_now_wait; // Pointer for OS sleep function. + + struct timer_list BookmarkTimer; // Used by i2DrainOutput + wait_queue_head_t pBookmarkWait; // Used by i2DrainOutput + + int BaudBase; + int BaudDivisor; + + USHORT ClosingDelay; + USHORT ClosingWaitTime; + + volatile + flowIn infl; // This structure is initialized as a completely + // formed flow-control command packet, and as such + // has the channel number, also the capacity and + // "as-of" data needed continuously. + + USHORT sinceLastFlow; // Counts the number of characters read from input + // buffers, since the last time flow control info + // was sent. + + USHORT whenSendFlow; // Determines when new flow control is to be sent to + // the board. Note unlike earlier manifestations of + // the driver, these packets can be sent from + // in-place. + + USHORT channelNeeds; // Bit map of important things which must be done + // for this channel. (See bits below ) + + volatile + flowStat outfl; // Same type of structure is used to hold current + // flow control information used to control our + // output. "asof" is kept updated as data is sent, + // and "room" never goes to zero. + + // The incoming ring buffer + // Unlike the outgoing buffers, this holds raw data, not packets. The two + // extra bytes are used to hold the byte-padding when there is room for an + // odd number of bytes before we must wrap. + // + UCHAR Ibuf[IBUF_SIZE + 2]; + volatile + USHORT Ibuf_stuff; // Stuffing index + volatile + USHORT Ibuf_strip; // Stripping index + + // The outgoing ring-buffer: Holds Data and command packets. N.B., even + // though these are in the channel structure, the channel is also written + // here, the easier to send it to the fifo when ready. HOWEVER, individual + // packets here are NOT padded to even length: the routines for writing + // blocks to the fifo will pad to even byte counts. + // + UCHAR Obuf[OBUF_SIZE+MAX_OBUF_BLOCK+4]; + volatile + USHORT Obuf_stuff; // Stuffing index + volatile + USHORT Obuf_strip; // Stripping index + int Obuf_char_count; + + // The outgoing bypass-command buffer. Unlike earlier manifestations, the + // flow control packets are sent directly from the structures. As above, the + // channel number is included in the packet, but they are NOT padded to even + // size. + // + UCHAR Cbuf[CBUF_SIZE+MAX_CBUF_BLOCK+2]; + volatile + USHORT Cbuf_stuff; // Stuffing index + volatile + USHORT Cbuf_strip; // Stripping index + + // The temporary buffer for the Linux tty driver PutChar entry. + // + UCHAR Pbuf[MAX_OBUF_BLOCK - sizeof (i2DataHeader)]; + volatile + USHORT Pbuf_stuff; // Stuffing index + + // The state of incoming data-set signals + // + USHORT dataSetIn; // Bit-mapped according to below. Also indicates + // whether a break has been detected since last + // inquiry. + + // The state of outcoming data-set signals (as far as we can tell!) + // + USHORT dataSetOut; // Bit-mapped according to below. + + // Most recent hot-key identifier detected + // + USHORT hotKeyIn; // Hot key as sent by the board, HOT_CLEAR indicates + // no hot key detected since last examined. + + // Counter of outstanding requests for bookmarks + // + short bookMarks; // Number of outstanding bookmark requests, (+ive + // whenever a bookmark request if queued up, -ive + // whenever a bookmark is received). + + // Misc options + // + USHORT channelOptions; // See below + + // To store various incoming special packets + // + debugStat channelStatus; + cntStat channelRcount; + cntStat channelTcount; + failStat channelFail; + + // To store the last values for line characteristics we sent to the board. + // + int speed; + + int flush_flags; + + void (*trace)(unsigned short,unsigned char,unsigned char,unsigned long,...); + + /* + * Kernel counters for the 4 input interrupts + */ + struct async_icount icount; + + /* + * Task queues for processing input packets from the board. + */ + struct work_struct tqueue_input; + struct work_struct tqueue_status; + struct work_struct tqueue_hangup; + + rwlock_t Ibuf_spinlock; + rwlock_t Obuf_spinlock; + rwlock_t Cbuf_spinlock; + rwlock_t Pbuf_spinlock; + +} i2ChanStr, *i2ChanStrPtr; + +//--------------------------------------------------- +// Manifests and bit-maps for elements in i2ChanStr +//--------------------------------------------------- +// +// flush flags +// +#define STARTFL_FLAG 1 +#define STOPFL_FLAG 2 + +// validity +// +#define CHANNEL_MAGIC_BITS 0xff00 +#define CHANNEL_MAGIC 0x5300 // (validity & CHANNEL_MAGIC_BITS) == + // CHANNEL_MAGIC --> structure good + +#define CHANNEL_SUPPORT 0x0001 // Indicates channel is supported, exists, + // and passed P.O.S.T. + +// channelNeeds +// +#define NEED_FLOW 1 // Indicates flow control has been queued +#define NEED_INLINE 2 // Indicates inline commands or data queued +#define NEED_BYPASS 4 // Indicates bypass commands queued +#define NEED_CREDIT 8 // Indicates would be sending except has not sufficient + // credit. The data is still in the channel structure, + // but the channel is not enqueued in the board + // structure again until there is a credit received from + // the board. + +// dataSetIn (Also the bits for i2GetStatus return value) +// +#define I2_DCD 1 +#define I2_CTS 2 +#define I2_DSR 4 +#define I2_RI 8 + +// dataSetOut (Also the bits for i2GetStatus return value) +// +#define I2_DTR 1 +#define I2_RTS 2 + +// i2GetStatus() can optionally clear these bits +// +#define I2_BRK 0x10 // A break was detected +#define I2_PAR 0x20 // A parity error was received +#define I2_FRA 0x40 // A framing error was received +#define I2_OVR 0x80 // An overrun error was received + +// i2GetStatus() automatically clears these bits */ +// +#define I2_DDCD 0x100 // DCD changed from its former value +#define I2_DCTS 0x200 // CTS changed from its former value +#define I2_DDSR 0x400 // DSR changed from its former value +#define I2_DRI 0x800 // RI changed from its former value + +// hotKeyIn +// +#define HOT_CLEAR 0x1322 // Indicates that no hot-key has been detected + +// channelOptions +// +#define CO_NBLOCK_WRITE 1 // Writes don't block waiting for buffer. (Default + // is, they do wait.) + +// fcmodes +// +#define I2_OUTFLOW_CTS 0x0001 +#define I2_INFLOW_RTS 0x0002 +#define I2_INFLOW_DSR 0x0004 +#define I2_INFLOW_DTR 0x0008 +#define I2_OUTFLOW_DSR 0x0010 +#define I2_OUTFLOW_DTR 0x0020 +#define I2_OUTFLOW_XON 0x0040 +#define I2_OUTFLOW_XANY 0x0080 +#define I2_INFLOW_XON 0x0100 + +#define I2_CRTSCTS (I2_OUTFLOW_CTS|I2_INFLOW_RTS) +#define I2_IXANY_MODE (I2_OUTFLOW_XON|I2_OUTFLOW_XANY) + +//------------------------------------------- +// Macros used from user level like functions +//------------------------------------------- + +// Macros to set and clear channel options +// +#define i2SetOption(pCh, option) pCh->channelOptions |= option +#define i2ClrOption(pCh, option) pCh->channelOptions &= ~option + +// Macro to set fatal-error trap +// +#define i2SetFatalTrap(pB, routine) pB->i2eFatalTrap = routine + +//-------------------------------------------- +// Declarations and prototypes for i2lib.c +//-------------------------------------------- +// +static int i2InitChannels(i2eBordStrPtr, int, i2ChanStrPtr); +static int i2QueueCommands(int, i2ChanStrPtr, int, int, cmdSyntaxPtr,...); +static int i2GetStatus(i2ChanStrPtr, int); +static int i2Input(i2ChanStrPtr); +static int i2InputFlush(i2ChanStrPtr); +static int i2Output(i2ChanStrPtr, const char *, int); +static int i2OutputFree(i2ChanStrPtr); +static int i2ServiceBoard(i2eBordStrPtr); +static void i2DrainOutput(i2ChanStrPtr, int); + +#ifdef IP2DEBUG_TRACE +void ip2trace(unsigned short,unsigned char,unsigned char,unsigned long,...); +#else +#define ip2trace(a,b,c,d...) do {} while (0) +#endif + +// Argument to i2QueueCommands +// +#define C_IN_LINE 1 +#define C_BYPASS 0 + +#endif // I2LIB_H diff --git a/drivers/staging/tty/ip2/i2pack.h b/drivers/staging/tty/ip2/i2pack.h new file mode 100644 index 000000000000..00342a677c90 --- /dev/null +++ b/drivers/staging/tty/ip2/i2pack.h @@ -0,0 +1,364 @@ +/******************************************************************************* +* +* (c) 1998 by Computone Corporation +* +******************************************************************************** +* +* +* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport +* serial I/O controllers. +* +* DESCRIPTION: Definitions of the packets used to transfer data and commands +* Host <--> Board. Information provided here is only applicable +* when the standard loadware is active. +* +*******************************************************************************/ +#ifndef I2PACK_H +#define I2PACK_H 1 + +//----------------------------------------------- +// Revision History: +// +// 10 October 1991 MAG First draft +// 24 February 1992 MAG Additions for 1.4.x loadware +// 11 March 1992 MAG New status packets +// +//----------------------------------------------- + +//------------------------------------------------------------------------------ +// Packet Formats: +// +// Information passes between the host and board through the FIFO in packets. +// These have headers which indicate the type of packet. Because the fifo data +// path may be 16-bits wide, the protocol is constrained such that each packet +// is always padded to an even byte count. (The lower-level interface routines +// -- i2ellis.c -- are designed to do this). +// +// The sender (be it host or board) must place some number of complete packets +// in the fifo, then place a message in the mailbox that packets are available. +// Placing such a message interrupts the "receiver" (be it board or host), who +// reads the mailbox message and determines that there are incoming packets +// ready. Since there are no partial packets, and the length of a packet is +// given in the header, the remainder of the packet can be read without checking +// for FIFO empty condition. The process is repeated, packet by packet, until +// the incoming FIFO is empty. Then the receiver uses the outbound mailbox to +// signal the board that it has read the data. Only then can the sender place +// additional data in the fifo. +//------------------------------------------------------------------------------ +// +//------------------------------------------------ +// Definition of Packet Header Area +//------------------------------------------------ +// +// Caution: these only define header areas. In actual use the data runs off +// beyond the end of these structures. +// +// Since these structures are based on sequences of bytes which go to the board, +// there cannot be ANY padding between the elements. +#pragma pack(1) + +//---------------------------- +// DATA PACKETS +//---------------------------- + +typedef struct _i2DataHeader +{ + unsigned char i2sChannel; /* The channel number: 0-255 */ + + // -- Bitfields are allocated LSB first -- + + // For incoming data, indicates whether this is an ordinary packet or a + // special one (e.g., hot key hit). + unsigned i2sId : 2 __attribute__ ((__packed__)); + + // For tagging data packets. There are flush commands which flush only data + // packets bearing a particular tag. (used in implementing IntelliView and + // IntelliPrint). THE TAG VALUE 0xf is RESERVED and must not be used (it has + // meaning internally to the loadware). + unsigned i2sTag : 4; + + // These two bits determine the type of packet sent/received. + unsigned i2sType : 2; + + // The count of data to follow: does not include the possible additional + // padding byte. MAXIMUM COUNT: 4094. The top four bits must be 0. + unsigned short i2sCount; + +} i2DataHeader, *i2DataHeaderPtr; + +// Structure is immediately followed by the data, proper. + +//---------------------------- +// NON-DATA PACKETS +//---------------------------- + +typedef struct _i2CmdHeader +{ + unsigned char i2sChannel; // The channel number: 0-255 (Except where noted + // - see below + + // Number of bytes of commands, status or whatever to follow + unsigned i2sCount : 6; + + // These two bits determine the type of packet sent/received. + unsigned i2sType : 2; + +} i2CmdHeader, *i2CmdHeaderPtr; + +// Structure is immediately followed by the applicable data. + +//--------------------------------------- +// Flow Control Packets (Outbound) +//--------------------------------------- + +// One type of outbound command packet is so important that the entire structure +// is explicitly defined here. That is the flow-control packet. This is never +// sent by user-level code (as would be the commands to raise/lower DTR, for +// example). These are only sent by the library routines in response to reading +// incoming data into the buffers. +// +// The parameters inside the command block are maintained in place, then the +// block is sent at the appropriate time. + +typedef struct _flowIn +{ + i2CmdHeader hd; // Channel #, count, type (see above) + unsigned char fcmd; // The flow control command (37) + unsigned short asof; // As of byte number "asof" (LSB first!) I have room + // for "room" bytes + unsigned short room; +} flowIn, *flowInPtr; + +//---------------------------------------- +// (Incoming) Status Packets +//---------------------------------------- + +// Incoming packets which are non-data packets are status packets. In this case, +// the channel number in the header is unimportant. What follows are one or more +// sub-packets, the first word of which consists of the channel (first or low +// byte) and the status indicator (second or high byte), followed by possibly +// more data. + +#define STAT_CTS_UP 0 /* CTS raised (no other bytes) */ +#define STAT_CTS_DN 1 /* CTS dropped (no other bytes) */ +#define STAT_DCD_UP 2 /* DCD raised (no other bytes) */ +#define STAT_DCD_DN 3 /* DCD dropped (no other bytes) */ +#define STAT_DSR_UP 4 /* DSR raised (no other bytes) */ +#define STAT_DSR_DN 5 /* DSR dropped (no other bytes) */ +#define STAT_RI_UP 6 /* RI raised (no other bytes) */ +#define STAT_RI_DN 7 /* RI dropped (no other bytes) */ +#define STAT_BRK_DET 8 /* BRK detect (no other bytes) */ +#define STAT_FLOW 9 /* Flow control(-- more: see below */ +#define STAT_BMARK 10 /* Bookmark (no other bytes) + * Bookmark is sent as a response to + * a command 60: request for bookmark + */ +#define STAT_STATUS 11 /* Special packet: see below */ +#define STAT_TXCNT 12 /* Special packet: see below */ +#define STAT_RXCNT 13 /* Special packet: see below */ +#define STAT_BOXIDS 14 /* Special packet: see below */ +#define STAT_HWFAIL 15 /* Special packet: see below */ + +#define STAT_MOD_ERROR 0xc0 +#define STAT_MODEM 0xc0/* If status & STAT_MOD_ERROR: + * == STAT_MODEM, then this is a modem + * status packet, given in response to a + * CMD_DSS_NOW command. + * The low nibble has each data signal: + */ +#define STAT_MOD_DCD 0x8 +#define STAT_MOD_RI 0x4 +#define STAT_MOD_DSR 0x2 +#define STAT_MOD_CTS 0x1 + +#define STAT_ERROR 0x80/* If status & STAT_MOD_ERROR + * == STAT_ERROR, then + * sort of error on the channel. + * The remaining seven bits indicate + * what sort of error it is. + */ +/* The low three bits indicate parity, framing, or overrun errors */ + +#define STAT_E_PARITY 4 /* Parity error */ +#define STAT_E_FRAMING 2 /* Framing error */ +#define STAT_E_OVERRUN 1 /* (uxart) overrun error */ + +//--------------------------------------- +// STAT_FLOW packets +//--------------------------------------- + +typedef struct _flowStat +{ + unsigned short asof; + unsigned short room; +}flowStat, *flowStatPtr; + +// flowStat packets are received from the board to regulate the flow of outgoing +// data. A local copy of this structure is also kept to track the amount of +// credits used and credits remaining. "room" is the amount of space in the +// board's buffers, "as of" having received a certain byte number. When sending +// data to the fifo, you must calculate how much buffer space your packet will +// use. Add this to the current "asof" and subtract it from the current "room". +// +// The calculation for the board's buffer is given by CREDIT_USAGE, where size +// is the un-rounded count of either data characters or command characters. +// (Which is to say, the count rounded up, plus two). + +#define CREDIT_USAGE(size) (((size) + 3) & ~1) + +//--------------------------------------- +// STAT_STATUS packets +//--------------------------------------- + +typedef struct _debugStat +{ + unsigned char d_ccsr; + unsigned char d_txinh; + unsigned char d_stat1; + unsigned char d_stat2; +} debugStat, *debugStatPtr; + +// debugStat packets are sent to the host in response to a CMD_GET_STATUS +// command. Each byte is bit-mapped as described below: + +#define D_CCSR_XON 2 /* Has received XON, ready to transmit */ +#define D_CCSR_XOFF 4 /* Has received XOFF, not transmitting */ +#define D_CCSR_TXENAB 8 /* Transmitter is enabled */ +#define D_CCSR_RXENAB 0x80 /* Receiver is enabled */ + +#define D_TXINH_BREAK 1 /* We are sending a break */ +#define D_TXINH_EMPTY 2 /* No data to send */ +#define D_TXINH_SUSP 4 /* Output suspended via command 57 */ +#define D_TXINH_CMD 8 /* We are processing an in-line command */ +#define D_TXINH_LCD 0x10 /* LCD diagnostics are running */ +#define D_TXINH_PAUSE 0x20 /* We are processing a PAUSE command */ +#define D_TXINH_DCD 0x40 /* DCD is low, preventing transmission */ +#define D_TXINH_DSR 0x80 /* DSR is low, preventing transmission */ + +#define D_STAT1_TXEN 1 /* Transmit INTERRUPTS enabled */ +#define D_STAT1_RXEN 2 /* Receiver INTERRUPTS enabled */ +#define D_STAT1_MDEN 4 /* Modem (data set sigs) interrupts enabled */ +#define D_STAT1_RLM 8 /* Remote loopback mode selected */ +#define D_STAT1_LLM 0x10 /* Local internal loopback mode selected */ +#define D_STAT1_CTS 0x20 /* CTS is low, preventing transmission */ +#define D_STAT1_DTR 0x40 /* DTR is low, to stop remote transmission */ +#define D_STAT1_RTS 0x80 /* RTS is low, to stop remote transmission */ + +#define D_STAT2_TXMT 1 /* Transmit buffers are all empty */ +#define D_STAT2_RXMT 2 /* Receive buffers are all empty */ +#define D_STAT2_RXINH 4 /* Loadware has tried to inhibit remote + * transmission: dropped DTR, sent XOFF, + * whatever... + */ +#define D_STAT2_RXFLO 8 /* Loadware can send no more data to host + * until it receives a flow-control packet + */ +//----------------------------------------- +// STAT_TXCNT and STAT_RXCNT packets +//---------------------------------------- + +typedef struct _cntStat +{ + unsigned short cs_time; // (Assumes host is little-endian!) + unsigned short cs_count; +} cntStat, *cntStatPtr; + +// These packets are sent in response to a CMD_GET_RXCNT or a CMD_GET_TXCNT +// bypass command. cs_time is a running 1 Millisecond counter which acts as a +// time stamp. cs_count is a running counter of data sent or received from the +// uxarts. (Not including data added by the chip itself, as with CRLF +// processing). +//------------------------------------------ +// STAT_HWFAIL packets +//------------------------------------------ + +typedef struct _failStat +{ + unsigned char fs_written; + unsigned char fs_read; + unsigned short fs_address; +} failStat, *failStatPtr; + +// This packet is sent whenever the on-board diagnostic process detects an +// error. At startup, this process is dormant. The host can wake it up by +// issuing the bypass command CMD_HW_TEST. The process runs at low priority and +// performs continuous hardware verification; writing data to certain on-board +// registers, reading it back, and comparing. If it detects an error, this +// packet is sent to the host, and the process goes dormant again until the host +// sends another CMD_HW_TEST. It then continues with the next register to be +// tested. + +//------------------------------------------------------------------------------ +// Macros to deal with the headers more easily! Note that these are defined so +// they may be used as "left" as well as "right" expressions. +//------------------------------------------------------------------------------ + +// Given a pointer to the packet, reference the channel number +// +#define CHANNEL_OF(pP) ((i2DataHeaderPtr)(pP))->i2sChannel + +// Given a pointer to the packet, reference the Packet type +// +#define PTYPE_OF(pP) ((i2DataHeaderPtr)(pP))->i2sType + +// The possible types of packets +// +#define PTYPE_DATA 0 /* Host <--> Board */ +#define PTYPE_BYPASS 1 /* Host ---> Board */ +#define PTYPE_INLINE 2 /* Host ---> Board */ +#define PTYPE_STATUS 2 /* Host <--- Board */ + +// Given a pointer to a Data packet, reference the Tag +// +#define TAG_OF(pP) ((i2DataHeaderPtr)(pP))->i2sTag + +// Given a pointer to a Data packet, reference the data i.d. +// +#define ID_OF(pP) ((i2DataHeaderPtr)(pP))->i2sId + +// The possible types of ID's +// +#define ID_ORDINARY_DATA 0 +#define ID_HOT_KEY 1 + +// Given a pointer to a Data packet, reference the count +// +#define DATA_COUNT_OF(pP) ((i2DataHeaderPtr)(pP))->i2sCount + +// Given a pointer to a Data packet, reference the beginning of data +// +#define DATA_OF(pP) &((unsigned char *)(pP))[4] // 4 = size of header + +// Given a pointer to a Non-Data packet, reference the count +// +#define CMD_COUNT_OF(pP) ((i2CmdHeaderPtr)(pP))->i2sCount + +#define MAX_CMD_PACK_SIZE 62 // Maximum size of such a count + +// Given a pointer to a Non-Data packet, reference the beginning of data +// +#define CMD_OF(pP) &((unsigned char *)(pP))[2] // 2 = size of header + +//-------------------------------- +// MailBox Bits: +//-------------------------------- + +//-------------------------- +// Outgoing (host to board) +//-------------------------- +// +#define MB_OUT_STUFFED 0x80 // Host has placed output in fifo +#define MB_IN_STRIPPED 0x40 // Host has read in all input from fifo + +//-------------------------- +// Incoming (board to host) +//-------------------------- +// +#define MB_IN_STUFFED 0x80 // Board has placed input in fifo +#define MB_OUT_STRIPPED 0x40 // Board has read all output from fifo +#define MB_FATAL_ERROR 0x20 // Board has encountered a fatal error + +#pragma pack() // Reset padding to command-line default + +#endif // I2PACK_H + diff --git a/drivers/staging/tty/ip2/ip2.h b/drivers/staging/tty/ip2/ip2.h new file mode 100644 index 000000000000..936ccc533949 --- /dev/null +++ b/drivers/staging/tty/ip2/ip2.h @@ -0,0 +1,107 @@ +/******************************************************************************* +* +* (c) 1998 by Computone Corporation +* +******************************************************************************** +* +* +* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport +* serial I/O controllers. +* +* DESCRIPTION: Driver constants for configuration and tuning +* +* NOTES: +* +*******************************************************************************/ +#ifndef IP2_H +#define IP2_H + +#include "ip2types.h" +#include "i2cmd.h" + +/*************/ +/* Constants */ +/*************/ + +/* Device major numbers - since version 2.0.26. */ +#define IP2_TTY_MAJOR 71 +#define IP2_CALLOUT_MAJOR 72 +#define IP2_IPL_MAJOR 73 + +/* Board configuration array. + * This array defines the hardware irq and address for up to IP2_MAX_BOARDS + * (4 supported per ip2_types.h) ISA board addresses and irqs MUST be specified, + * PCI and EISA boards are probed for and automagicly configed + * iff the addresses are set to 1 and 2 respectivily. + * 0x0100 - 0x03f0 == ISA + * 1 == PCI + * 2 == EISA + * 0 == (skip this board) + * This array defines the hardware addresses for them. Special + * addresses are EISA and PCI which go sniffing for boards. + + * In a multiboard system the position in the array determines which port + * devices are assigned to each board: + * board 0 is assigned ttyF0.. to ttyF63, + * board 1 is assigned ttyF64 to ttyF127, + * board 2 is assigned ttyF128 to ttyF191, + * board 3 is assigned ttyF192 to ttyF255. + * + * In PCI and EISA bus systems each range is mapped to card in + * monotonically increasing slot number order, ISA position is as specified + * here. + + * If the irqs are ALL set to 0,0,0,0 all boards operate in + * polled mode. For interrupt operation ISA boards require that the IRQ be + * specified, while PCI and EISA boards any nonzero entry + * will enable interrupts using the BIOS configured irq for the board. + * An invalid irq entry will default to polled mode for that card and print + * console warning. + + * When the driver is loaded as a module these setting can be overridden on the + * modprobe command line or on an option line in /etc/modprobe.conf. + * If the driver is built-in the configuration must be + * set here for ISA cards and address set to 1 and 2 for PCI and EISA. + * + * Here is an example that shows most if not all possibe combinations: + + *static ip2config_t ip2config = + *{ + * {11,1,0,0}, // irqs + * { // Addresses + * 0x0308, // Board 0, ttyF0 - ttyF63// ISA card at io=0x308, irq=11 + * 0x0001, // Board 1, ttyF64 - ttyF127//PCI card configured by BIOS + * 0x0000, // Board 2, ttyF128 - ttyF191// Slot skipped + * 0x0002 // Board 3, ttyF192 - ttyF255//EISA card configured by BIOS + * // but polled not irq driven + * } + *}; + */ + + /* this structure is zeroed out because the suggested method is to configure + * the driver as a module, set up the parameters with an options line in + * /etc/modprobe.conf and load with modprobe or kmod, the kernel + * module loader + */ + + /* This structure is NOW always initialized when the driver is initialized. + * Compiled in defaults MUST be added to the io and irq arrays in + * ip2.c. Those values are configurable from insmod parameters in the + * case of modules or from command line parameters (ip2=io,irq) when + * compiled in. + */ + +static ip2config_t ip2config = +{ + {0,0,0,0}, // irqs + { // Addresses + /* Do NOT set compile time defaults HERE! Use the arrays in + ip2.c! These WILL be overwritten! =mhw= */ + 0x0000, // Board 0, ttyF0 - ttyF63 + 0x0000, // Board 1, ttyF64 - ttyF127 + 0x0000, // Board 2, ttyF128 - ttyF191 + 0x0000 // Board 3, ttyF192 - ttyF255 + } +}; + +#endif diff --git a/drivers/staging/tty/ip2/ip2ioctl.h b/drivers/staging/tty/ip2/ip2ioctl.h new file mode 100644 index 000000000000..aa0a9da85e05 --- /dev/null +++ b/drivers/staging/tty/ip2/ip2ioctl.h @@ -0,0 +1,35 @@ +/******************************************************************************* +* +* (c) 1998 by Computone Corporation +* +******************************************************************************** +* +* +* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport +* serial I/O controllers. +* +* DESCRIPTION: Driver constants for configuration and tuning +* +* NOTES: +* +*******************************************************************************/ + +#ifndef IP2IOCTL_H +#define IP2IOCTL_H + +//************* +//* Constants * +//************* + +// High baud rates (if not defined elsewhere. +#ifndef B153600 +# define B153600 0010005 +#endif +#ifndef B307200 +# define B307200 0010006 +#endif +#ifndef B921600 +# define B921600 0010007 +#endif + +#endif diff --git a/drivers/staging/tty/ip2/ip2main.c b/drivers/staging/tty/ip2/ip2main.c new file mode 100644 index 000000000000..ea7a8fb08283 --- /dev/null +++ b/drivers/staging/tty/ip2/ip2main.c @@ -0,0 +1,3234 @@ +/* +* +* (c) 1999 by Computone Corporation +* +******************************************************************************** +* +* PACKAGE: Linux tty Device Driver for IntelliPort family of multiport +* serial I/O controllers. +* +* DESCRIPTION: Mainline code for the device driver +* +*******************************************************************************/ +// ToDo: +// +// Fix the immediate DSS_NOW problem. +// Work over the channel stats return logic in ip2_ipl_ioctl so they +// make sense for all 256 possible channels and so the user space +// utilities will compile and work properly. +// +// Done: +// +// 1.2.14 /\/\|=mhw=|\/\/ +// Added bounds checking to ip2_ipl_ioctl to avoid potential terroristic acts. +// Changed the definition of ip2trace to be more consistent with kernel style +// Thanks to Andreas Dilger for these updates +// +// 1.2.13 /\/\|=mhw=|\/\/ +// DEVFS: Renamed ttf/{n} to tts/F{n} and cuf/{n} to cua/F{n} to conform +// to agreed devfs serial device naming convention. +// +// 1.2.12 /\/\|=mhw=|\/\/ +// Cleaned up some remove queue cut and paste errors +// +// 1.2.11 /\/\|=mhw=|\/\/ +// Clean up potential NULL pointer dereferences +// Clean up devfs registration +// Add kernel command line parsing for io and irq +// Compile defaults for io and irq are now set in ip2.c not ip2.h! +// Reworked poll_only hack for explicit parameter setting +// You must now EXPLICITLY set poll_only = 1 or set all irqs to 0 +// Merged ip2_loadmain and old_ip2_init +// Converted all instances of interruptible_sleep_on into queue calls +// Most of these had no race conditions but better to clean up now +// +// 1.2.10 /\/\|=mhw=|\/\/ +// Fixed the bottom half interrupt handler and enabled USE_IQI +// to split the interrupt handler into a formal top-half / bottom-half +// Fixed timing window on high speed processors that queued messages to +// the outbound mail fifo faster than the board could handle. +// +// 1.2.9 +// Four box EX was barfing on >128k kmalloc, made structure smaller by +// reducing output buffer size +// +// 1.2.8 +// Device file system support (MHW) +// +// 1.2.7 +// Fixed +// Reload of ip2 without unloading ip2main hangs system on cat of /proc/modules +// +// 1.2.6 +//Fixes DCD problems +// DCD was not reported when CLOCAL was set on call to TIOCMGET +// +//Enhancements: +// TIOCMGET requests and waits for status return +// No DSS interrupts enabled except for DCD when needed +// +// For internal use only +// +//#define IP2DEBUG_INIT +//#define IP2DEBUG_OPEN +//#define IP2DEBUG_WRITE +//#define IP2DEBUG_READ +//#define IP2DEBUG_IOCTL +//#define IP2DEBUG_IPL + +//#define IP2DEBUG_TRACE +//#define DEBUG_FIFO + +/************/ +/* Includes */ +/************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include "ip2types.h" +#include "ip2trace.h" +#include "ip2ioctl.h" +#include "ip2.h" +#include "i2ellis.h" +#include "i2lib.h" + +/***************** + * /proc/ip2mem * + *****************/ + +#include +#include + +static DEFINE_MUTEX(ip2_mutex); +static const struct file_operations ip2mem_proc_fops; +static const struct file_operations ip2_proc_fops; + +/********************/ +/* Type Definitions */ +/********************/ + +/*************/ +/* Constants */ +/*************/ + +/* String constants to identify ourselves */ +static const char pcName[] = "Computone IntelliPort Plus multiport driver"; +static const char pcVersion[] = "1.2.14"; + +/* String constants for port names */ +static const char pcDriver_name[] = "ip2"; +static const char pcIpl[] = "ip2ipl"; + +/***********************/ +/* Function Prototypes */ +/***********************/ + +/* Global module entry functions */ + +/* Private (static) functions */ +static int ip2_open(PTTY, struct file *); +static void ip2_close(PTTY, struct file *); +static int ip2_write(PTTY, const unsigned char *, int); +static int ip2_putchar(PTTY, unsigned char); +static void ip2_flush_chars(PTTY); +static int ip2_write_room(PTTY); +static int ip2_chars_in_buf(PTTY); +static void ip2_flush_buffer(PTTY); +static int ip2_ioctl(PTTY, UINT, ULONG); +static void ip2_set_termios(PTTY, struct ktermios *); +static void ip2_set_line_discipline(PTTY); +static void ip2_throttle(PTTY); +static void ip2_unthrottle(PTTY); +static void ip2_stop(PTTY); +static void ip2_start(PTTY); +static void ip2_hangup(PTTY); +static int ip2_tiocmget(struct tty_struct *tty); +static int ip2_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear); +static int ip2_get_icount(struct tty_struct *tty, + struct serial_icounter_struct *icount); + +static void set_irq(int, int); +static void ip2_interrupt_bh(struct work_struct *work); +static irqreturn_t ip2_interrupt(int irq, void *dev_id); +static void ip2_poll(unsigned long arg); +static inline void service_all_boards(void); +static void do_input(struct work_struct *); +static void do_status(struct work_struct *); + +static void ip2_wait_until_sent(PTTY,int); + +static void set_params (i2ChanStrPtr, struct ktermios *); +static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *); +static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *); + +static ssize_t ip2_ipl_read(struct file *, char __user *, size_t, loff_t *); +static ssize_t ip2_ipl_write(struct file *, const char __user *, size_t, loff_t *); +static long ip2_ipl_ioctl(struct file *, UINT, ULONG); +static int ip2_ipl_open(struct inode *, struct file *); + +static int DumpTraceBuffer(char __user *, int); +static int DumpFifoBuffer( char __user *, int); + +static void ip2_init_board(int, const struct firmware *); +static unsigned short find_eisa_board(int); +static int ip2_setup(char *str); + +/***************/ +/* Static Data */ +/***************/ + +static struct tty_driver *ip2_tty_driver; + +/* Here, then is a table of board pointers which the interrupt routine should + * scan through to determine who it must service. + */ +static unsigned short i2nBoards; // Number of boards here + +static i2eBordStrPtr i2BoardPtrTable[IP2_MAX_BOARDS]; + +static i2ChanStrPtr DevTable[IP2_MAX_PORTS]; +//DevTableMem just used to save addresses for kfree +static void *DevTableMem[IP2_MAX_BOARDS]; + +/* This is the driver descriptor for the ip2ipl device, which is used to + * download the loadware to the boards. + */ +static const struct file_operations ip2_ipl = { + .owner = THIS_MODULE, + .read = ip2_ipl_read, + .write = ip2_ipl_write, + .unlocked_ioctl = ip2_ipl_ioctl, + .open = ip2_ipl_open, + .llseek = noop_llseek, +}; + +static unsigned long irq_counter; +static unsigned long bh_counter; + +// Use immediate queue to service interrupts +#define USE_IQI +//#define USE_IQ // PCI&2.2 needs work + +/* The timer_list entry for our poll routine. If interrupt operation is not + * selected, the board is serviced periodically to see if anything needs doing. + */ +#define POLL_TIMEOUT (jiffies + 1) +static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0); + +#ifdef IP2DEBUG_TRACE +/* Trace (debug) buffer data */ +#define TRACEMAX 1000 +static unsigned long tracebuf[TRACEMAX]; +static int tracestuff; +static int tracestrip; +static int tracewrap; +#endif + +/**********/ +/* Macros */ +/**********/ + +#ifdef IP2DEBUG_OPEN +#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] ttyc=%d, modc=%x -> %s\n", \ + tty->name,(pCh->flags), \ + tty->count,/*GET_USE_COUNT(module)*/0,s) +#else +#define DBG_CNT(s) +#endif + +/********/ +/* Code */ +/********/ + +#include "i2ellis.c" /* Extremely low-level interface services */ +#include "i2cmd.c" /* Standard loadware command definitions */ +#include "i2lib.c" /* High level interface services */ + +/* Configuration area for modprobe */ + +MODULE_AUTHOR("Doug McNash"); +MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); +MODULE_LICENSE("GPL"); + +#define MAX_CMD_STR 50 + +static int poll_only; +static char cmd[MAX_CMD_STR]; + +static int Eisa_irq; +static int Eisa_slot; + +static int iindx; +static char rirqs[IP2_MAX_BOARDS]; +static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0}; + +/* Note: Add compiled in defaults to these arrays, not to the structure + in ip2.h any longer. That structure WILL get overridden + by these values, or command line values, or insmod values!!! =mhw= +*/ +static int io[IP2_MAX_BOARDS]; +static int irq[IP2_MAX_BOARDS] = { -1, -1, -1, -1 }; + +MODULE_AUTHOR("Doug McNash"); +MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); +module_param_array(irq, int, NULL, 0); +MODULE_PARM_DESC(irq, "Interrupts for IntelliPort Cards"); +module_param_array(io, int, NULL, 0); +MODULE_PARM_DESC(io, "I/O ports for IntelliPort Cards"); +module_param(poll_only, bool, 0); +MODULE_PARM_DESC(poll_only, "Do not use card interrupts"); +module_param_string(ip2, cmd, MAX_CMD_STR, 0); +MODULE_PARM_DESC(ip2, "Contains module parameter passed with 'ip2='"); + +/* for sysfs class support */ +static struct class *ip2_class; + +/* Some functions to keep track of what irqs we have */ + +static int __init is_valid_irq(int irq) +{ + int *i = Valid_Irqs; + + while (*i != 0 && *i != irq) + i++; + + return *i; +} + +static void __init mark_requested_irq(char irq) +{ + rirqs[iindx++] = irq; +} + +static int __exit clear_requested_irq(char irq) +{ + int i; + for (i = 0; i < IP2_MAX_BOARDS; ++i) { + if (rirqs[i] == irq) { + rirqs[i] = 0; + return 1; + } + } + return 0; +} + +static int have_requested_irq(char irq) +{ + /* array init to zeros so 0 irq will not be requested as a side + * effect */ + int i; + for (i = 0; i < IP2_MAX_BOARDS; ++i) + if (rirqs[i] == irq) + return 1; + return 0; +} + +/******************************************************************************/ +/* Function: cleanup_module() */ +/* Parameters: None */ +/* Returns: Nothing */ +/* */ +/* Description: */ +/* This is a required entry point for an installable module. It has to return */ +/* the device and the driver to a passive state. It should not be necessary */ +/* to reset the board fully, especially as the loadware is downloaded */ +/* externally rather than in the driver. We just want to disable the board */ +/* and clear the loadware to a reset state. To allow this there has to be a */ +/* way to detect whether the board has the loadware running at init time to */ +/* handle subsequent installations of the driver. All memory allocated by the */ +/* driver should be returned since it may be unloaded from memory. */ +/******************************************************************************/ +static void __exit ip2_cleanup_module(void) +{ + int err; + int i; + + del_timer_sync(&PollTimer); + + /* Reset the boards we have. */ + for (i = 0; i < IP2_MAX_BOARDS; i++) + if (i2BoardPtrTable[i]) + iiReset(i2BoardPtrTable[i]); + + /* The following is done at most once, if any boards were installed. */ + for (i = 0; i < IP2_MAX_BOARDS; i++) { + if (i2BoardPtrTable[i]) { + iiResetDelay(i2BoardPtrTable[i]); + /* free io addresses and Tibet */ + release_region(ip2config.addr[i], 8); + device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i)); + device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, + 4 * i + 1)); + } + /* Disable and remove interrupt handler. */ + if (ip2config.irq[i] > 0 && + have_requested_irq(ip2config.irq[i])) { + free_irq(ip2config.irq[i], (void *)&pcName); + clear_requested_irq(ip2config.irq[i]); + } + } + class_destroy(ip2_class); + err = tty_unregister_driver(ip2_tty_driver); + if (err) + printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", + err); + put_tty_driver(ip2_tty_driver); + unregister_chrdev(IP2_IPL_MAJOR, pcIpl); + remove_proc_entry("ip2mem", NULL); + + /* free memory */ + for (i = 0; i < IP2_MAX_BOARDS; i++) { + void *pB; +#ifdef CONFIG_PCI + if (ip2config.type[i] == PCI && ip2config.pci_dev[i]) { + pci_disable_device(ip2config.pci_dev[i]); + pci_dev_put(ip2config.pci_dev[i]); + ip2config.pci_dev[i] = NULL; + } +#endif + pB = i2BoardPtrTable[i]; + if (pB != NULL) { + kfree(pB); + i2BoardPtrTable[i] = NULL; + } + if (DevTableMem[i] != NULL) { + kfree(DevTableMem[i]); + DevTableMem[i] = NULL; + } + } +} +module_exit(ip2_cleanup_module); + +static const struct tty_operations ip2_ops = { + .open = ip2_open, + .close = ip2_close, + .write = ip2_write, + .put_char = ip2_putchar, + .flush_chars = ip2_flush_chars, + .write_room = ip2_write_room, + .chars_in_buffer = ip2_chars_in_buf, + .flush_buffer = ip2_flush_buffer, + .ioctl = ip2_ioctl, + .throttle = ip2_throttle, + .unthrottle = ip2_unthrottle, + .set_termios = ip2_set_termios, + .set_ldisc = ip2_set_line_discipline, + .stop = ip2_stop, + .start = ip2_start, + .hangup = ip2_hangup, + .tiocmget = ip2_tiocmget, + .tiocmset = ip2_tiocmset, + .get_icount = ip2_get_icount, + .proc_fops = &ip2_proc_fops, +}; + +/******************************************************************************/ +/* Function: ip2_loadmain() */ +/* Parameters: irq, io from command line of insmod et. al. */ +/* pointer to fip firmware and firmware size for boards */ +/* Returns: Success (0) */ +/* */ +/* Description: */ +/* This was the required entry point for all drivers (now in ip2.c) */ +/* It performs all */ +/* initialisation of the devices and driver structures, and registers itself */ +/* with the relevant kernel modules. */ +/******************************************************************************/ +/* IRQF_DISABLED - if set blocks all interrupts else only this line */ +/* IRQF_SHARED - for shared irq PCI or maybe EISA only */ +/* SA_RANDOM - can be source for cert. random number generators */ +#define IP2_SA_FLAGS 0 + + +static const struct firmware *ip2_request_firmware(void) +{ + struct platform_device *pdev; + const struct firmware *fw; + + pdev = platform_device_register_simple("ip2", 0, NULL, 0); + if (IS_ERR(pdev)) { + printk(KERN_ERR "Failed to register platform device for ip2\n"); + return NULL; + } + if (request_firmware(&fw, "intelliport2.bin", &pdev->dev)) { + printk(KERN_ERR "Failed to load firmware 'intelliport2.bin'\n"); + fw = NULL; + } + platform_device_unregister(pdev); + return fw; +} + +/****************************************************************************** + * ip2_setup: + * str: kernel command line string + * + * Can't autoprobe the boards so user must specify configuration on + * kernel command line. Sane people build it modular but the others + * come here. + * + * Alternating pairs of io,irq for up to 4 boards. + * ip2=io0,irq0,io1,irq1,io2,irq2,io3,irq3 + * + * io=0 => No board + * io=1 => PCI + * io=2 => EISA + * else => ISA I/O address + * + * irq=0 or invalid for ISA will revert to polling mode + * + * Any value = -1, do not overwrite compiled in value. + * + ******************************************************************************/ +static int __init ip2_setup(char *str) +{ + int j, ints[10]; /* 4 boards, 2 parameters + 2 */ + unsigned int i; + + str = get_options(str, ARRAY_SIZE(ints), ints); + + for (i = 0, j = 1; i < 4; i++) { + if (j > ints[0]) + break; + if (ints[j] >= 0) + io[i] = ints[j]; + j++; + if (j > ints[0]) + break; + if (ints[j] >= 0) + irq[i] = ints[j]; + j++; + } + return 1; +} +__setup("ip2=", ip2_setup); + +static int __init ip2_loadmain(void) +{ + int i, j, box; + int err = 0; + i2eBordStrPtr pB = NULL; + int rc = -1; + const struct firmware *fw = NULL; + char *str; + + str = cmd; + + if (poll_only) { + /* Hard lock the interrupts to zero */ + irq[0] = irq[1] = irq[2] = irq[3] = poll_only = 0; + } + + /* Check module parameter with 'ip2=' has been passed or not */ + if (!poll_only && (!strncmp(str, "ip2=", 4))) + ip2_setup(str); + + ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0); + + /* process command line arguments to modprobe or + insmod i.e. iop & irqp */ + /* irqp and iop should ALWAYS be specified now... But we check + them individually just to be sure, anyways... */ + for (i = 0; i < IP2_MAX_BOARDS; ++i) { + ip2config.addr[i] = io[i]; + if (irq[i] >= 0) + ip2config.irq[i] = irq[i]; + else + ip2config.irq[i] = 0; + /* This is a little bit of a hack. If poll_only=1 on command + line back in ip2.c OR all IRQs on all specified boards are + explicitly set to 0, then drop to poll only mode and override + PCI or EISA interrupts. This superceeds the old hack of + triggering if all interrupts were zero (like da default). + Still a hack but less prone to random acts of terrorism. + + What we really should do, now that the IRQ default is set + to -1, is to use 0 as a hard coded, do not probe. + + /\/\|=mhw=|\/\/ + */ + poll_only |= irq[i]; + } + poll_only = !poll_only; + + /* Announce our presence */ + printk(KERN_INFO "%s version %s\n", pcName, pcVersion); + + ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS); + if (!ip2_tty_driver) + return -ENOMEM; + + /* Initialise all the boards we can find (up to the maximum). */ + for (i = 0; i < IP2_MAX_BOARDS; ++i) { + switch (ip2config.addr[i]) { + case 0: /* skip this slot even if card is present */ + break; + default: /* ISA */ + /* ISA address must be specified */ + if (ip2config.addr[i] < 0x100 || + ip2config.addr[i] > 0x3f8) { + printk(KERN_ERR "IP2: Bad ISA board %d " + "address %x\n", i, + ip2config.addr[i]); + ip2config.addr[i] = 0; + break; + } + ip2config.type[i] = ISA; + + /* Check for valid irq argument, set for polling if + * invalid */ + if (ip2config.irq[i] && + !is_valid_irq(ip2config.irq[i])) { + printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n", + ip2config.irq[i]); + /* 0 is polling and is valid in that sense */ + ip2config.irq[i] = 0; + } + break; + case PCI: +#ifdef CONFIG_PCI + { + struct pci_dev *pdev = NULL; + u32 addr; + int status; + + pdev = pci_get_device(PCI_VENDOR_ID_COMPUTONE, + PCI_DEVICE_ID_COMPUTONE_IP2EX, pdev); + if (pdev == NULL) { + ip2config.addr[i] = 0; + printk(KERN_ERR "IP2: PCI board %d not " + "found\n", i); + break; + } + + if (pci_enable_device(pdev)) { + dev_err(&pdev->dev, "can't enable device\n"); + goto out; + } + ip2config.type[i] = PCI; + ip2config.pci_dev[i] = pci_dev_get(pdev); + status = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_1, + &addr); + if (addr & 1) + ip2config.addr[i] = (USHORT)(addr & 0xfffe); + else + dev_err(&pdev->dev, "I/O address error\n"); + + ip2config.irq[i] = pdev->irq; +out: + pci_dev_put(pdev); + } +#else + printk(KERN_ERR "IP2: PCI card specified but PCI " + "support not enabled.\n"); + printk(KERN_ERR "IP2: Recompile kernel with CONFIG_PCI " + "defined!\n"); +#endif /* CONFIG_PCI */ + break; + case EISA: + ip2config.addr[i] = find_eisa_board(Eisa_slot + 1); + if (ip2config.addr[i] != 0) { + /* Eisa_irq set as side effect, boo */ + ip2config.type[i] = EISA; + } + ip2config.irq[i] = Eisa_irq; + break; + } /* switch */ + } /* for */ + + for (i = 0; i < IP2_MAX_BOARDS; ++i) { + if (ip2config.addr[i]) { + pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL); + if (pB) { + i2BoardPtrTable[i] = pB; + iiSetAddress(pB, ip2config.addr[i], + ii2DelayTimer); + iiReset(pB); + } else + printk(KERN_ERR "IP2: board memory allocation " + "error\n"); + } + } + for (i = 0; i < IP2_MAX_BOARDS; ++i) { + pB = i2BoardPtrTable[i]; + if (pB != NULL) { + iiResetDelay(pB); + break; + } + } + for (i = 0; i < IP2_MAX_BOARDS; ++i) { + /* We don't want to request the firmware unless we have at + least one board */ + if (i2BoardPtrTable[i] != NULL) { + if (!fw) + fw = ip2_request_firmware(); + if (!fw) + break; + ip2_init_board(i, fw); + } + } + if (fw) + release_firmware(fw); + + ip2trace(ITRC_NO_PORT, ITRC_INIT, 2, 0); + + ip2_tty_driver->owner = THIS_MODULE; + ip2_tty_driver->name = "ttyF"; + ip2_tty_driver->driver_name = pcDriver_name; + ip2_tty_driver->major = IP2_TTY_MAJOR; + ip2_tty_driver->minor_start = 0; + ip2_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; + ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL; + ip2_tty_driver->init_termios = tty_std_termios; + ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; + ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV; + tty_set_operations(ip2_tty_driver, &ip2_ops); + + ip2trace(ITRC_NO_PORT, ITRC_INIT, 3, 0); + + err = tty_register_driver(ip2_tty_driver); + if (err) { + printk(KERN_ERR "IP2: failed to register tty driver\n"); + put_tty_driver(ip2_tty_driver); + return err; /* leaking resources */ + } + + err = register_chrdev(IP2_IPL_MAJOR, pcIpl, &ip2_ipl); + if (err) { + printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", + err); + } else { + /* create the sysfs class */ + ip2_class = class_create(THIS_MODULE, "ip2"); + if (IS_ERR(ip2_class)) { + err = PTR_ERR(ip2_class); + goto out_chrdev; + } + } + /* Register the read_procmem thing */ + if (!proc_create("ip2mem",0,NULL,&ip2mem_proc_fops)) { + printk(KERN_ERR "IP2: failed to register read_procmem\n"); + return -EIO; /* leaking resources */ + } + + ip2trace(ITRC_NO_PORT, ITRC_INIT, 4, 0); + /* Register the interrupt handler or poll handler, depending upon the + * specified interrupt. + */ + + for (i = 0; i < IP2_MAX_BOARDS; ++i) { + if (ip2config.addr[i] == 0) + continue; + + pB = i2BoardPtrTable[i]; + if (pB != NULL) { + device_create(ip2_class, NULL, + MKDEV(IP2_IPL_MAJOR, 4 * i), + NULL, "ipl%d", i); + device_create(ip2_class, NULL, + MKDEV(IP2_IPL_MAJOR, 4 * i + 1), + NULL, "stat%d", i); + + for (box = 0; box < ABS_MAX_BOXES; box++) + for (j = 0; j < ABS_BIGGEST_BOX; j++) + if (pB->i2eChannelMap[box] & (1 << j)) + tty_register_device( + ip2_tty_driver, + j + ABS_BIGGEST_BOX * + (box+i*ABS_MAX_BOXES), + NULL); + } + + if (poll_only) { + /* Poll only forces driver to only use polling and + to ignore the probed PCI or EISA interrupts. */ + ip2config.irq[i] = CIR_POLL; + } + if (ip2config.irq[i] == CIR_POLL) { +retry: + if (!timer_pending(&PollTimer)) { + mod_timer(&PollTimer, POLL_TIMEOUT); + printk(KERN_INFO "IP2: polling\n"); + } + } else { + if (have_requested_irq(ip2config.irq[i])) + continue; + rc = request_irq(ip2config.irq[i], ip2_interrupt, + IP2_SA_FLAGS | + (ip2config.type[i] == PCI ? IRQF_SHARED : 0), + pcName, i2BoardPtrTable[i]); + if (rc) { + printk(KERN_ERR "IP2: request_irq failed: " + "error %d\n", rc); + ip2config.irq[i] = CIR_POLL; + printk(KERN_INFO "IP2: Polling %ld/sec.\n", + (POLL_TIMEOUT - jiffies)); + goto retry; + } + mark_requested_irq(ip2config.irq[i]); + /* Initialise the interrupt handler bottom half + * (aka slih). */ + } + } + + for (i = 0; i < IP2_MAX_BOARDS; ++i) { + if (i2BoardPtrTable[i]) { + /* set and enable board interrupt */ + set_irq(i, ip2config.irq[i]); + } + } + + ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0); + + return 0; + +out_chrdev: + unregister_chrdev(IP2_IPL_MAJOR, "ip2"); + /* unregister and put tty here */ + return err; +} +module_init(ip2_loadmain); + +/******************************************************************************/ +/* Function: ip2_init_board() */ +/* Parameters: Index of board in configuration structure */ +/* Returns: Success (0) */ +/* */ +/* Description: */ +/* This function initializes the specified board. The loadware is copied to */ +/* the board, the channel structures are initialized, and the board details */ +/* are reported on the console. */ +/******************************************************************************/ +static void +ip2_init_board(int boardnum, const struct firmware *fw) +{ + int i; + int nports = 0, nboxes = 0; + i2ChanStrPtr pCh; + i2eBordStrPtr pB = i2BoardPtrTable[boardnum]; + + if ( !iiInitialize ( pB ) ) { + printk ( KERN_ERR "IP2: Failed to initialize board at 0x%x, error %d\n", + pB->i2eBase, pB->i2eError ); + goto err_initialize; + } + printk(KERN_INFO "IP2: Board %d: addr=0x%x irq=%d\n", boardnum + 1, + ip2config.addr[boardnum], ip2config.irq[boardnum] ); + + if (!request_region( ip2config.addr[boardnum], 8, pcName )) { + printk(KERN_ERR "IP2: bad addr=0x%x\n", ip2config.addr[boardnum]); + goto err_initialize; + } + + if ( iiDownloadAll ( pB, (loadHdrStrPtr)fw->data, 1, fw->size ) + != II_DOWN_GOOD ) { + printk ( KERN_ERR "IP2: failed to download loadware\n" ); + goto err_release_region; + } else { + printk ( KERN_INFO "IP2: fv=%d.%d.%d lv=%d.%d.%d\n", + pB->i2ePom.e.porVersion, + pB->i2ePom.e.porRevision, + pB->i2ePom.e.porSubRev, pB->i2eLVersion, + pB->i2eLRevision, pB->i2eLSub ); + } + + switch ( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) { + + default: + printk( KERN_ERR "IP2: Unknown board type, ID = %x\n", + pB->i2ePom.e.porID ); + nports = 0; + goto err_release_region; + break; + + case POR_ID_II_4: /* IntelliPort-II, ISA-4 (4xRJ45) */ + printk ( KERN_INFO "IP2: ISA-4\n" ); + nports = 4; + break; + + case POR_ID_II_8: /* IntelliPort-II, 8-port using standard brick. */ + printk ( KERN_INFO "IP2: ISA-8 std\n" ); + nports = 8; + break; + + case POR_ID_II_8R: /* IntelliPort-II, 8-port using RJ11's (no CTS) */ + printk ( KERN_INFO "IP2: ISA-8 RJ11\n" ); + nports = 8; + break; + + case POR_ID_FIIEX: /* IntelliPort IIEX */ + { + int portnum = IP2_PORTS_PER_BOARD * boardnum; + int box; + + for( box = 0; box < ABS_MAX_BOXES; ++box ) { + if ( pB->i2eChannelMap[box] != 0 ) { + ++nboxes; + } + for( i = 0; i < ABS_BIGGEST_BOX; ++i ) { + if ( pB->i2eChannelMap[box] & 1<< i ) { + ++nports; + } + } + } + DevTableMem[boardnum] = pCh = + kmalloc( sizeof(i2ChanStr) * nports, GFP_KERNEL ); + if ( !pCh ) { + printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n"); + goto err_release_region; + } + if ( !i2InitChannels( pB, nports, pCh ) ) { + printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError); + kfree ( pCh ); + goto err_release_region; + } + pB->i2eChannelPtr = &DevTable[portnum]; + pB->i2eChannelCnt = ABS_MOST_PORTS; + + for( box = 0; box < ABS_MAX_BOXES; ++box, portnum += ABS_BIGGEST_BOX ) { + for( i = 0; i < ABS_BIGGEST_BOX; ++i ) { + if ( pB->i2eChannelMap[box] & (1 << i) ) { + DevTable[portnum + i] = pCh; + pCh->port_index = portnum + i; + pCh++; + } + } + } + printk(KERN_INFO "IP2: EX box=%d ports=%d %d bit\n", + nboxes, nports, pB->i2eDataWidth16 ? 16 : 8 ); + } + goto ex_exit; + } + DevTableMem[boardnum] = pCh = + kmalloc ( sizeof (i2ChanStr) * nports, GFP_KERNEL ); + if ( !pCh ) { + printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n"); + goto err_release_region; + } + pB->i2eChannelPtr = pCh; + pB->i2eChannelCnt = nports; + if ( !i2InitChannels( pB, nports, pCh ) ) { + printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError); + kfree ( pCh ); + goto err_release_region; + } + pB->i2eChannelPtr = &DevTable[IP2_PORTS_PER_BOARD * boardnum]; + + for( i = 0; i < pB->i2eChannelCnt; ++i ) { + DevTable[IP2_PORTS_PER_BOARD * boardnum + i] = pCh; + pCh->port_index = (IP2_PORTS_PER_BOARD * boardnum) + i; + pCh++; + } +ex_exit: + INIT_WORK(&pB->tqueue_interrupt, ip2_interrupt_bh); + return; + +err_release_region: + release_region(ip2config.addr[boardnum], 8); +err_initialize: + kfree ( pB ); + i2BoardPtrTable[boardnum] = NULL; + return; +} + +/******************************************************************************/ +/* Function: find_eisa_board ( int start_slot ) */ +/* Parameters: First slot to check */ +/* Returns: Address of EISA IntelliPort II controller */ +/* */ +/* Description: */ +/* This function searches for an EISA IntelliPort controller, starting */ +/* from the specified slot number. If the motherboard is not identified as an */ +/* EISA motherboard, or no valid board ID is selected it returns 0. Otherwise */ +/* it returns the base address of the controller. */ +/******************************************************************************/ +static unsigned short +find_eisa_board( int start_slot ) +{ + int i, j; + unsigned int idm = 0; + unsigned int idp = 0; + unsigned int base = 0; + unsigned int value; + int setup_address; + int setup_irq; + int ismine = 0; + + /* + * First a check for an EISA motherboard, which we do by comparing the + * EISA ID registers for the system board and the first couple of slots. + * No slot ID should match the system board ID, but on an ISA or PCI + * machine the odds are that an empty bus will return similar values for + * each slot. + */ + i = 0x0c80; + value = (inb(i) << 24) + (inb(i+1) << 16) + (inb(i+2) << 8) + inb(i+3); + for( i = 0x1c80; i <= 0x4c80; i += 0x1000 ) { + j = (inb(i)<<24)+(inb(i+1)<<16)+(inb(i+2)<<8)+inb(i+3); + if ( value == j ) + return 0; + } + + /* + * OK, so we are inclined to believe that this is an EISA machine. Find + * an IntelliPort controller. + */ + for( i = start_slot; i < 16; i++ ) { + base = i << 12; + idm = (inb(base + 0xc80) << 8) | (inb(base + 0xc81) & 0xff); + idp = (inb(base + 0xc82) << 8) | (inb(base + 0xc83) & 0xff); + ismine = 0; + if ( idm == 0x0e8e ) { + if ( idp == 0x0281 || idp == 0x0218 ) { + ismine = 1; + } else if ( idp == 0x0282 || idp == 0x0283 ) { + ismine = 3; /* Can do edge-trigger */ + } + if ( ismine ) { + Eisa_slot = i; + break; + } + } + } + if ( !ismine ) + return 0; + + /* It's some sort of EISA card, but at what address is it configured? */ + + setup_address = base + 0xc88; + value = inb(base + 0xc86); + setup_irq = (value & 8) ? Valid_Irqs[value & 7] : 0; + + if ( (ismine & 2) && !(value & 0x10) ) { + ismine = 1; /* Could be edging, but not */ + } + + if ( Eisa_irq == 0 ) { + Eisa_irq = setup_irq; + } else if ( Eisa_irq != setup_irq ) { + printk ( KERN_ERR "IP2: EISA irq mismatch between EISA controllers\n" ); + } + +#ifdef IP2DEBUG_INIT +printk(KERN_DEBUG "Computone EISA board in slot %d, I.D. 0x%x%x, Address 0x%x", + base >> 12, idm, idp, setup_address); + if ( Eisa_irq ) { + printk(KERN_DEBUG ", Interrupt %d %s\n", + setup_irq, (ismine & 2) ? "(edge)" : "(level)"); + } else { + printk(KERN_DEBUG ", (polled)\n"); + } +#endif + return setup_address; +} + +/******************************************************************************/ +/* Function: set_irq() */ +/* Parameters: index to board in board table */ +/* IRQ to use */ +/* Returns: Success (0) */ +/* */ +/* Description: */ +/******************************************************************************/ +static void +set_irq( int boardnum, int boardIrq ) +{ + unsigned char tempCommand[16]; + i2eBordStrPtr pB = i2BoardPtrTable[boardnum]; + unsigned long flags; + + /* + * Notify the boards they may generate interrupts. This is done by + * sending an in-line command to channel 0 on each board. This is why + * the channels have to be defined already. For each board, if the + * interrupt has never been defined, we must do so NOW, directly, since + * board will not send flow control or even give an interrupt until this + * is done. If polling we must send 0 as the interrupt parameter. + */ + + // We will get an interrupt here at the end of this function + + iiDisableMailIrq(pB); + + /* We build up the entire packet header. */ + CHANNEL_OF(tempCommand) = 0; + PTYPE_OF(tempCommand) = PTYPE_INLINE; + CMD_COUNT_OF(tempCommand) = 2; + (CMD_OF(tempCommand))[0] = CMDVALUE_IRQ; + (CMD_OF(tempCommand))[1] = boardIrq; + /* + * Write to FIFO; don't bother to adjust fifo capacity for this, since + * board will respond almost immediately after SendMail hit. + */ + write_lock_irqsave(&pB->write_fifo_spinlock, flags); + iiWriteBuf(pB, tempCommand, 4); + write_unlock_irqrestore(&pB->write_fifo_spinlock, flags); + pB->i2eUsingIrq = boardIrq; + pB->i2eOutMailWaiting |= MB_OUT_STUFFED; + + /* Need to update number of boards before you enable mailbox int */ + ++i2nBoards; + + CHANNEL_OF(tempCommand) = 0; + PTYPE_OF(tempCommand) = PTYPE_BYPASS; + CMD_COUNT_OF(tempCommand) = 6; + (CMD_OF(tempCommand))[0] = 88; // SILO + (CMD_OF(tempCommand))[1] = 64; // chars + (CMD_OF(tempCommand))[2] = 32; // ms + + (CMD_OF(tempCommand))[3] = 28; // MAX_BLOCK + (CMD_OF(tempCommand))[4] = 64; // chars + + (CMD_OF(tempCommand))[5] = 87; // HW_TEST + write_lock_irqsave(&pB->write_fifo_spinlock, flags); + iiWriteBuf(pB, tempCommand, 8); + write_unlock_irqrestore(&pB->write_fifo_spinlock, flags); + + CHANNEL_OF(tempCommand) = 0; + PTYPE_OF(tempCommand) = PTYPE_BYPASS; + CMD_COUNT_OF(tempCommand) = 1; + (CMD_OF(tempCommand))[0] = 84; /* get BOX_IDS */ + iiWriteBuf(pB, tempCommand, 3); + +#ifdef XXX + // enable heartbeat for test porpoises + CHANNEL_OF(tempCommand) = 0; + PTYPE_OF(tempCommand) = PTYPE_BYPASS; + CMD_COUNT_OF(tempCommand) = 2; + (CMD_OF(tempCommand))[0] = 44; /* get ping */ + (CMD_OF(tempCommand))[1] = 200; /* 200 ms */ + write_lock_irqsave(&pB->write_fifo_spinlock, flags); + iiWriteBuf(pB, tempCommand, 4); + write_unlock_irqrestore(&pB->write_fifo_spinlock, flags); +#endif + + iiEnableMailIrq(pB); + iiSendPendingMail(pB); +} + +/******************************************************************************/ +/* Interrupt Handler Section */ +/******************************************************************************/ + +static inline void +service_all_boards(void) +{ + int i; + i2eBordStrPtr pB; + + /* Service every board on the list */ + for( i = 0; i < IP2_MAX_BOARDS; ++i ) { + pB = i2BoardPtrTable[i]; + if ( pB ) { + i2ServiceBoard( pB ); + } + } +} + + +/******************************************************************************/ +/* Function: ip2_interrupt_bh(work) */ +/* Parameters: work - pointer to the board structure */ +/* Returns: Nothing */ +/* */ +/* Description: */ +/* Service the board in a bottom half interrupt handler and then */ +/* reenable the board's interrupts if it has an IRQ number */ +/* */ +/******************************************************************************/ +static void +ip2_interrupt_bh(struct work_struct *work) +{ + i2eBordStrPtr pB = container_of(work, i2eBordStr, tqueue_interrupt); +// pB better well be set or we have a problem! We can only get +// here from the IMMEDIATE queue. Here, we process the boards. +// Checking pB doesn't cost much and it saves us from the sanity checkers. + + bh_counter++; + + if ( pB ) { + i2ServiceBoard( pB ); + if( pB->i2eUsingIrq ) { +// Re-enable his interrupts + iiEnableMailIrq(pB); + } + } +} + + +/******************************************************************************/ +/* Function: ip2_interrupt(int irq, void *dev_id) */ +/* Parameters: irq - interrupt number */ +/* pointer to optional device ID structure */ +/* Returns: Nothing */ +/* */ +/* Description: */ +/* */ +/* Our task here is simply to identify each board which needs servicing. */ +/* If we are queuing then, queue it to be serviced, and disable its irq */ +/* mask otherwise process the board directly. */ +/* */ +/* We could queue by IRQ but that just complicates things on both ends */ +/* with very little gain in performance (how many instructions does */ +/* it take to iterate on the immediate queue). */ +/* */ +/* */ +/******************************************************************************/ +static void +ip2_irq_work(i2eBordStrPtr pB) +{ +#ifdef USE_IQI + if (NO_MAIL_HERE != ( pB->i2eStartMail = iiGetMail(pB))) { +// Disable his interrupt (will be enabled when serviced) +// This is mostly to protect from reentrancy. + iiDisableMailIrq(pB); + +// Park the board on the immediate queue for processing. + schedule_work(&pB->tqueue_interrupt); + +// Make sure the immediate queue is flagged to fire. + } +#else + +// We are using immediate servicing here. This sucks and can +// cause all sorts of havoc with ppp and others. The failsafe +// check on iiSendPendingMail could also throw a hairball. + + i2ServiceBoard( pB ); + +#endif /* USE_IQI */ +} + +static void +ip2_polled_interrupt(void) +{ + int i; + i2eBordStrPtr pB; + + ip2trace(ITRC_NO_PORT, ITRC_INTR, 99, 1, 0); + + /* Service just the boards on the list using this irq */ + for( i = 0; i < i2nBoards; ++i ) { + pB = i2BoardPtrTable[i]; + +// Only process those boards which match our IRQ. +// IRQ = 0 for polled boards, we won't poll "IRQ" boards + + if (pB && pB->i2eUsingIrq == 0) + ip2_irq_work(pB); + } + + ++irq_counter; + + ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); +} + +static irqreturn_t +ip2_interrupt(int irq, void *dev_id) +{ + i2eBordStrPtr pB = dev_id; + + ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, pB->i2eUsingIrq ); + + ip2_irq_work(pB); + + ++irq_counter; + + ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); + return IRQ_HANDLED; +} + +/******************************************************************************/ +/* Function: ip2_poll(unsigned long arg) */ +/* Parameters: ? */ +/* Returns: Nothing */ +/* */ +/* Description: */ +/* This function calls the library routine i2ServiceBoard for each board in */ +/* the board table. This is used instead of the interrupt routine when polled */ +/* mode is specified. */ +/******************************************************************************/ +static void +ip2_poll(unsigned long arg) +{ + ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 ); + + // Just polled boards, IRQ = 0 will hit all non-interrupt boards. + // It will NOT poll boards handled by hard interrupts. + // The issue of queued BH interrupts is handled in ip2_interrupt(). + ip2_polled_interrupt(); + + mod_timer(&PollTimer, POLL_TIMEOUT); + + ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); +} + +static void do_input(struct work_struct *work) +{ + i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_input); + unsigned long flags; + + ip2trace(CHANN, ITRC_INPUT, 21, 0 ); + + // Data input + if ( pCh->pTTY != NULL ) { + read_lock_irqsave(&pCh->Ibuf_spinlock, flags); + if (!pCh->throttled && (pCh->Ibuf_stuff != pCh->Ibuf_strip)) { + read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); + i2Input( pCh ); + } else + read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); + } else { + ip2trace(CHANN, ITRC_INPUT, 22, 0 ); + + i2InputFlush( pCh ); + } +} + +// code duplicated from n_tty (ldisc) +static inline void isig(int sig, struct tty_struct *tty, int flush) +{ + /* FIXME: This is completely bogus */ + if (tty->pgrp) + kill_pgrp(tty->pgrp, sig, 1); + if (flush || !L_NOFLSH(tty)) { + if ( tty->ldisc->ops->flush_buffer ) + tty->ldisc->ops->flush_buffer(tty); + i2InputFlush( tty->driver_data ); + } +} + +static void do_status(struct work_struct *work) +{ + i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_status); + int status; + + status = i2GetStatus( pCh, (I2_BRK|I2_PAR|I2_FRA|I2_OVR) ); + + ip2trace (CHANN, ITRC_STATUS, 21, 1, status ); + + if (pCh->pTTY && (status & (I2_BRK|I2_PAR|I2_FRA|I2_OVR)) ) { + if ( (status & I2_BRK) ) { + // code duplicated from n_tty (ldisc) + if (I_IGNBRK(pCh->pTTY)) + goto skip_this; + if (I_BRKINT(pCh->pTTY)) { + isig(SIGINT, pCh->pTTY, 1); + goto skip_this; + } + wake_up_interruptible(&pCh->pTTY->read_wait); + } +#ifdef NEVER_HAPPENS_AS_SETUP_XXX + // and can't work because we don't know the_char + // as the_char is reported on a separate path + // The intelligent board does this stuff as setup + { + char brkf = TTY_NORMAL; + unsigned char brkc = '\0'; + unsigned char tmp; + if ( (status & I2_BRK) ) { + brkf = TTY_BREAK; + brkc = '\0'; + } + else if (status & I2_PAR) { + brkf = TTY_PARITY; + brkc = the_char; + } else if (status & I2_FRA) { + brkf = TTY_FRAME; + brkc = the_char; + } else if (status & I2_OVR) { + brkf = TTY_OVERRUN; + brkc = the_char; + } + tmp = pCh->pTTY->real_raw; + pCh->pTTY->real_raw = 0; + pCh->pTTY->ldisc->ops.receive_buf( pCh->pTTY, &brkc, &brkf, 1 ); + pCh->pTTY->real_raw = tmp; + } +#endif /* NEVER_HAPPENS_AS_SETUP_XXX */ + } +skip_this: + + if ( status & (I2_DDCD | I2_DDSR | I2_DCTS | I2_DRI) ) { + wake_up_interruptible(&pCh->delta_msr_wait); + + if ( (pCh->flags & ASYNC_CHECK_CD) && (status & I2_DDCD) ) { + if ( status & I2_DCD ) { + if ( pCh->wopen ) { + wake_up_interruptible ( &pCh->open_wait ); + } + } else { + if (pCh->pTTY && (!(pCh->pTTY->termios->c_cflag & CLOCAL)) ) { + tty_hangup( pCh->pTTY ); + } + } + } + } + + ip2trace (CHANN, ITRC_STATUS, 26, 0 ); +} + +/******************************************************************************/ +/* Device Open/Close/Ioctl Entry Point Section */ +/******************************************************************************/ + +/******************************************************************************/ +/* Function: open_sanity_check() */ +/* Parameters: Pointer to tty structure */ +/* Pointer to file structure */ +/* Returns: Success or failure */ +/* */ +/* Description: */ +/* Verifies the structure magic numbers and cross links. */ +/******************************************************************************/ +#ifdef IP2DEBUG_OPEN +static void +open_sanity_check( i2ChanStrPtr pCh, i2eBordStrPtr pBrd ) +{ + if ( pBrd->i2eValid != I2E_MAGIC ) { + printk(KERN_ERR "IP2: invalid board structure\n" ); + } else if ( pBrd != pCh->pMyBord ) { + printk(KERN_ERR "IP2: board structure pointer mismatch (%p)\n", + pCh->pMyBord ); + } else if ( pBrd->i2eChannelCnt < pCh->port_index ) { + printk(KERN_ERR "IP2: bad device index (%d)\n", pCh->port_index ); + } else if (&((i2ChanStrPtr)pBrd->i2eChannelPtr)[pCh->port_index] != pCh) { + } else { + printk(KERN_INFO "IP2: all pointers check out!\n" ); + } +} +#endif + + +/******************************************************************************/ +/* Function: ip2_open() */ +/* Parameters: Pointer to tty structure */ +/* Pointer to file structure */ +/* Returns: Success or failure */ +/* */ +/* Description: (MANDATORY) */ +/* A successful device open has to run a gauntlet of checks before it */ +/* completes. After some sanity checking and pointer setup, the function */ +/* blocks until all conditions are satisfied. It then initialises the port to */ +/* the default characteristics and returns. */ +/******************************************************************************/ +static int +ip2_open( PTTY tty, struct file *pFile ) +{ + wait_queue_t wait; + int rc = 0; + int do_clocal = 0; + i2ChanStrPtr pCh = DevTable[tty->index]; + + ip2trace (tty->index, ITRC_OPEN, ITRC_ENTER, 0 ); + + if ( pCh == NULL ) { + return -ENODEV; + } + /* Setup pointer links in device and tty structures */ + pCh->pTTY = tty; + tty->driver_data = pCh; + +#ifdef IP2DEBUG_OPEN + printk(KERN_DEBUG \ + "IP2:open(tty=%p,pFile=%p):dev=%s,ch=%d,idx=%d\n", + tty, pFile, tty->name, pCh->infl.hd.i2sChannel, pCh->port_index); + open_sanity_check ( pCh, pCh->pMyBord ); +#endif + + i2QueueCommands(PTYPE_INLINE, pCh, 100, 3, CMD_DTRUP,CMD_RTSUP,CMD_DCD_REP); + pCh->dataSetOut |= (I2_DTR | I2_RTS); + serviceOutgoingFifo( pCh->pMyBord ); + + /* Block here until the port is ready (per serial and istallion) */ + /* + * 1. If the port is in the middle of closing wait for the completion + * and then return the appropriate error. + */ + init_waitqueue_entry(&wait, current); + add_wait_queue(&pCh->close_wait, &wait); + set_current_state( TASK_INTERRUPTIBLE ); + + if ( tty_hung_up_p(pFile) || ( pCh->flags & ASYNC_CLOSING )) { + if ( pCh->flags & ASYNC_CLOSING ) { + tty_unlock(); + schedule(); + tty_lock(); + } + if ( tty_hung_up_p(pFile) ) { + set_current_state( TASK_RUNNING ); + remove_wait_queue(&pCh->close_wait, &wait); + return( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS; + } + } + set_current_state( TASK_RUNNING ); + remove_wait_queue(&pCh->close_wait, &wait); + + /* + * 3. Handle a non-blocking open of a normal port. + */ + if ( (pFile->f_flags & O_NONBLOCK) || (tty->flags & (1<flags |= ASYNC_NORMAL_ACTIVE; + goto noblock; + } + /* + * 4. Now loop waiting for the port to be free and carrier present + * (if required). + */ + if ( tty->termios->c_cflag & CLOCAL ) + do_clocal = 1; + +#ifdef IP2DEBUG_OPEN + printk(KERN_DEBUG "OpenBlock: do_clocal = %d\n", do_clocal); +#endif + + ++pCh->wopen; + + init_waitqueue_entry(&wait, current); + add_wait_queue(&pCh->open_wait, &wait); + + for(;;) { + i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP); + pCh->dataSetOut |= (I2_DTR | I2_RTS); + set_current_state( TASK_INTERRUPTIBLE ); + serviceOutgoingFifo( pCh->pMyBord ); + if ( tty_hung_up_p(pFile) ) { + set_current_state( TASK_RUNNING ); + remove_wait_queue(&pCh->open_wait, &wait); + return ( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EBUSY : -ERESTARTSYS; + } + if (!(pCh->flags & ASYNC_CLOSING) && + (do_clocal || (pCh->dataSetIn & I2_DCD) )) { + rc = 0; + break; + } + +#ifdef IP2DEBUG_OPEN + printk(KERN_DEBUG "ASYNC_CLOSING = %s\n", + (pCh->flags & ASYNC_CLOSING)?"True":"False"); + printk(KERN_DEBUG "OpenBlock: waiting for CD or signal\n"); +#endif + ip2trace (CHANN, ITRC_OPEN, 3, 2, 0, + (pCh->flags & ASYNC_CLOSING) ); + /* check for signal */ + if (signal_pending(current)) { + rc = (( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS); + break; + } + tty_unlock(); + schedule(); + tty_lock(); + } + set_current_state( TASK_RUNNING ); + remove_wait_queue(&pCh->open_wait, &wait); + + --pCh->wopen; //why count? + + ip2trace (CHANN, ITRC_OPEN, 4, 0 ); + + if (rc != 0 ) { + return rc; + } + pCh->flags |= ASYNC_NORMAL_ACTIVE; + +noblock: + + /* first open - Assign termios structure to port */ + if ( tty->count == 1 ) { + i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB); + /* Now we must send the termios settings to the loadware */ + set_params( pCh, NULL ); + } + + /* + * Now set any i2lib options. These may go away if the i2lib code ends + * up rolled into the mainline. + */ + pCh->channelOptions |= CO_NBLOCK_WRITE; + +#ifdef IP2DEBUG_OPEN + printk (KERN_DEBUG "IP2: open completed\n" ); +#endif + serviceOutgoingFifo( pCh->pMyBord ); + + ip2trace (CHANN, ITRC_OPEN, ITRC_RETURN, 0 ); + + return 0; +} + +/******************************************************************************/ +/* Function: ip2_close() */ +/* Parameters: Pointer to tty structure */ +/* Pointer to file structure */ +/* Returns: Nothing */ +/* */ +/* Description: */ +/* */ +/* */ +/******************************************************************************/ +static void +ip2_close( PTTY tty, struct file *pFile ) +{ + i2ChanStrPtr pCh = tty->driver_data; + + if ( !pCh ) { + return; + } + + ip2trace (CHANN, ITRC_CLOSE, ITRC_ENTER, 0 ); + +#ifdef IP2DEBUG_OPEN + printk(KERN_DEBUG "IP2:close %s:\n",tty->name); +#endif + + if ( tty_hung_up_p ( pFile ) ) { + + ip2trace (CHANN, ITRC_CLOSE, 2, 1, 2 ); + + return; + } + if ( tty->count > 1 ) { /* not the last close */ + + ip2trace (CHANN, ITRC_CLOSE, 2, 1, 3 ); + + return; + } + pCh->flags |= ASYNC_CLOSING; // last close actually + + tty->closing = 1; + + if (pCh->ClosingWaitTime != ASYNC_CLOSING_WAIT_NONE) { + /* + * Before we drop DTR, make sure the transmitter has completely drained. + * This uses an timeout, after which the close + * completes. + */ + ip2_wait_until_sent(tty, pCh->ClosingWaitTime ); + } + /* + * At this point we stop accepting input. Here we flush the channel + * input buffer which will allow the board to send up more data. Any + * additional input is tossed at interrupt/poll time. + */ + i2InputFlush( pCh ); + + /* disable DSS reporting */ + i2QueueCommands(PTYPE_INLINE, pCh, 100, 4, + CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP); + if (tty->termios->c_cflag & HUPCL) { + i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN); + pCh->dataSetOut &= ~(I2_DTR | I2_RTS); + i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25)); + } + + serviceOutgoingFifo ( pCh->pMyBord ); + + tty_ldisc_flush(tty); + tty_driver_flush_buffer(tty); + tty->closing = 0; + + pCh->pTTY = NULL; + + if (pCh->wopen) { + if (pCh->ClosingDelay) { + msleep_interruptible(jiffies_to_msecs(pCh->ClosingDelay)); + } + wake_up_interruptible(&pCh->open_wait); + } + + pCh->flags &=~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); + wake_up_interruptible(&pCh->close_wait); + +#ifdef IP2DEBUG_OPEN + DBG_CNT("ip2_close: after wakeups--"); +#endif + + + ip2trace (CHANN, ITRC_CLOSE, ITRC_RETURN, 1, 1 ); + + return; +} + +/******************************************************************************/ +/* Function: ip2_hangup() */ +/* Parameters: Pointer to tty structure */ +/* Returns: Nothing */ +/* */ +/* Description: */ +/* */ +/* */ +/******************************************************************************/ +static void +ip2_hangup ( PTTY tty ) +{ + i2ChanStrPtr pCh = tty->driver_data; + + if( !pCh ) { + return; + } + + ip2trace (CHANN, ITRC_HANGUP, ITRC_ENTER, 0 ); + + ip2_flush_buffer(tty); + + /* disable DSS reporting */ + + i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_DCD_NREP); + i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB); + if ( (tty->termios->c_cflag & HUPCL) ) { + i2QueueCommands(PTYPE_BYPASS, pCh, 0, 2, CMD_RTSDN, CMD_DTRDN); + pCh->dataSetOut &= ~(I2_DTR | I2_RTS); + i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25)); + } + i2QueueCommands(PTYPE_INLINE, pCh, 1, 3, + CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP); + serviceOutgoingFifo ( pCh->pMyBord ); + + wake_up_interruptible ( &pCh->delta_msr_wait ); + + pCh->flags &= ~ASYNC_NORMAL_ACTIVE; + pCh->pTTY = NULL; + wake_up_interruptible ( &pCh->open_wait ); + + ip2trace (CHANN, ITRC_HANGUP, ITRC_RETURN, 0 ); +} + +/******************************************************************************/ +/******************************************************************************/ +/* Device Output Section */ +/******************************************************************************/ +/******************************************************************************/ + +/******************************************************************************/ +/* Function: ip2_write() */ +/* Parameters: Pointer to tty structure */ +/* Flag denoting data is in user (1) or kernel (0) space */ +/* Pointer to data */ +/* Number of bytes to write */ +/* Returns: Number of bytes actually written */ +/* */ +/* Description: (MANDATORY) */ +/* */ +/* */ +/******************************************************************************/ +static int +ip2_write( PTTY tty, const unsigned char *pData, int count) +{ + i2ChanStrPtr pCh = tty->driver_data; + int bytesSent = 0; + unsigned long flags; + + ip2trace (CHANN, ITRC_WRITE, ITRC_ENTER, 2, count, -1 ); + + /* Flush out any buffered data left over from ip2_putchar() calls. */ + ip2_flush_chars( tty ); + + /* This is the actual move bit. Make sure it does what we need!!!!! */ + write_lock_irqsave(&pCh->Pbuf_spinlock, flags); + bytesSent = i2Output( pCh, pData, count); + write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); + + ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent ); + + return bytesSent > 0 ? bytesSent : 0; +} + +/******************************************************************************/ +/* Function: ip2_putchar() */ +/* Parameters: Pointer to tty structure */ +/* Character to write */ +/* Returns: Nothing */ +/* */ +/* Description: */ +/* */ +/* */ +/******************************************************************************/ +static int +ip2_putchar( PTTY tty, unsigned char ch ) +{ + i2ChanStrPtr pCh = tty->driver_data; + unsigned long flags; + +// ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch ); + + write_lock_irqsave(&pCh->Pbuf_spinlock, flags); + pCh->Pbuf[pCh->Pbuf_stuff++] = ch; + if ( pCh->Pbuf_stuff == sizeof pCh->Pbuf ) { + write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); + ip2_flush_chars( tty ); + } else + write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); + return 1; + +// ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch ); +} + +/******************************************************************************/ +/* Function: ip2_flush_chars() */ +/* Parameters: Pointer to tty structure */ +/* Returns: Nothing */ +/* */ +/* Description: */ +/* */ +/******************************************************************************/ +static void +ip2_flush_chars( PTTY tty ) +{ + int strip; + i2ChanStrPtr pCh = tty->driver_data; + unsigned long flags; + + write_lock_irqsave(&pCh->Pbuf_spinlock, flags); + if ( pCh->Pbuf_stuff ) { + +// ip2trace (CHANN, ITRC_PUTC, 10, 1, strip ); + + // + // We may need to restart i2Output if it does not fullfill this request + // + strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff); + if ( strip != pCh->Pbuf_stuff ) { + memmove( pCh->Pbuf, &pCh->Pbuf[strip], pCh->Pbuf_stuff - strip ); + } + pCh->Pbuf_stuff -= strip; + } + write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); +} + +/******************************************************************************/ +/* Function: ip2_write_room() */ +/* Parameters: Pointer to tty structure */ +/* Returns: Number of bytes that the driver can accept */ +/* */ +/* Description: */ +/* */ +/******************************************************************************/ +static int +ip2_write_room ( PTTY tty ) +{ + int bytesFree; + i2ChanStrPtr pCh = tty->driver_data; + unsigned long flags; + + read_lock_irqsave(&pCh->Pbuf_spinlock, flags); + bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff; + read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); + + ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree ); + + return ((bytesFree > 0) ? bytesFree : 0); +} + +/******************************************************************************/ +/* Function: ip2_chars_in_buf() */ +/* Parameters: Pointer to tty structure */ +/* Returns: Number of bytes queued for transmission */ +/* */ +/* Description: */ +/* */ +/* */ +/******************************************************************************/ +static int +ip2_chars_in_buf ( PTTY tty ) +{ + i2ChanStrPtr pCh = tty->driver_data; + int rc; + unsigned long flags; + + ip2trace (CHANN, ITRC_WRITE, 12, 1, pCh->Obuf_char_count + pCh->Pbuf_stuff ); + +#ifdef IP2DEBUG_WRITE + printk (KERN_DEBUG "IP2: chars in buffer = %d (%d,%d)\n", + pCh->Obuf_char_count + pCh->Pbuf_stuff, + pCh->Obuf_char_count, pCh->Pbuf_stuff ); +#endif + read_lock_irqsave(&pCh->Obuf_spinlock, flags); + rc = pCh->Obuf_char_count; + read_unlock_irqrestore(&pCh->Obuf_spinlock, flags); + read_lock_irqsave(&pCh->Pbuf_spinlock, flags); + rc += pCh->Pbuf_stuff; + read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); + return rc; +} + +/******************************************************************************/ +/* Function: ip2_flush_buffer() */ +/* Parameters: Pointer to tty structure */ +/* Returns: Nothing */ +/* */ +/* Description: */ +/* */ +/* */ +/******************************************************************************/ +static void +ip2_flush_buffer( PTTY tty ) +{ + i2ChanStrPtr pCh = tty->driver_data; + unsigned long flags; + + ip2trace (CHANN, ITRC_FLUSH, ITRC_ENTER, 0 ); + +#ifdef IP2DEBUG_WRITE + printk (KERN_DEBUG "IP2: flush buffer\n" ); +#endif + write_lock_irqsave(&pCh->Pbuf_spinlock, flags); + pCh->Pbuf_stuff = 0; + write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); + i2FlushOutput( pCh ); + ip2_owake(tty); + + ip2trace (CHANN, ITRC_FLUSH, ITRC_RETURN, 0 ); + +} + +/******************************************************************************/ +/* Function: ip2_wait_until_sent() */ +/* Parameters: Pointer to tty structure */ +/* Timeout for wait. */ +/* Returns: Nothing */ +/* */ +/* Description: */ +/* This function is used in place of the normal tty_wait_until_sent, which */ +/* only waits for the driver buffers to be empty (or rather, those buffers */ +/* reported by chars_in_buffer) which doesn't work for IP2 due to the */ +/* indeterminate number of bytes buffered on the board. */ +/******************************************************************************/ +static void +ip2_wait_until_sent ( PTTY tty, int timeout ) +{ + int i = jiffies; + i2ChanStrPtr pCh = tty->driver_data; + + tty_wait_until_sent(tty, timeout ); + if ( (i = timeout - (jiffies -i)) > 0) + i2DrainOutput( pCh, i ); +} + +/******************************************************************************/ +/******************************************************************************/ +/* Device Input Section */ +/******************************************************************************/ +/******************************************************************************/ + +/******************************************************************************/ +/* Function: ip2_throttle() */ +/* Parameters: Pointer to tty structure */ +/* Returns: Nothing */ +/* */ +/* Description: */ +/* */ +/* */ +/******************************************************************************/ +static void +ip2_throttle ( PTTY tty ) +{ + i2ChanStrPtr pCh = tty->driver_data; + +#ifdef IP2DEBUG_READ + printk (KERN_DEBUG "IP2: throttle\n" ); +#endif + /* + * Signal the poll/interrupt handlers not to forward incoming data to + * the line discipline. This will cause the buffers to fill up in the + * library and thus cause the library routines to send the flow control + * stuff. + */ + pCh->throttled = 1; +} + +/******************************************************************************/ +/* Function: ip2_unthrottle() */ +/* Parameters: Pointer to tty structure */ +/* Returns: Nothing */ +/* */ +/* Description: */ +/* */ +/* */ +/******************************************************************************/ +static void +ip2_unthrottle ( PTTY tty ) +{ + i2ChanStrPtr pCh = tty->driver_data; + unsigned long flags; + +#ifdef IP2DEBUG_READ + printk (KERN_DEBUG "IP2: unthrottle\n" ); +#endif + + /* Pass incoming data up to the line discipline again. */ + pCh->throttled = 0; + i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME); + serviceOutgoingFifo( pCh->pMyBord ); + read_lock_irqsave(&pCh->Ibuf_spinlock, flags); + if ( pCh->Ibuf_stuff != pCh->Ibuf_strip ) { + read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); +#ifdef IP2DEBUG_READ + printk (KERN_DEBUG "i2Input called from unthrottle\n" ); +#endif + i2Input( pCh ); + } else + read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); +} + +static void +ip2_start ( PTTY tty ) +{ + i2ChanStrPtr pCh = DevTable[tty->index]; + + i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME); + i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_UNSUSPEND); + i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_RESUME); +#ifdef IP2DEBUG_WRITE + printk (KERN_DEBUG "IP2: start tx\n" ); +#endif +} + +static void +ip2_stop ( PTTY tty ) +{ + i2ChanStrPtr pCh = DevTable[tty->index]; + + i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_SUSPEND); +#ifdef IP2DEBUG_WRITE + printk (KERN_DEBUG "IP2: stop tx\n" ); +#endif +} + +/******************************************************************************/ +/* Device Ioctl Section */ +/******************************************************************************/ + +static int ip2_tiocmget(struct tty_struct *tty) +{ + i2ChanStrPtr pCh = DevTable[tty->index]; +#ifdef ENABLE_DSSNOW + wait_queue_t wait; +#endif + + if (pCh == NULL) + return -ENODEV; + +/* + FIXME - the following code is causing a NULL pointer dereference in + 2.3.51 in an interrupt handler. It's suppose to prompt the board + to return the DSS signal status immediately. Why doesn't it do + the same thing in 2.2.14? +*/ + +/* This thing is still busted in the 1.2.12 driver on 2.4.x + and even hoses the serial console so the oops can be trapped. + /\/\|=mhw=|\/\/ */ + +#ifdef ENABLE_DSSNOW + i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DSS_NOW); + + init_waitqueue_entry(&wait, current); + add_wait_queue(&pCh->dss_now_wait, &wait); + set_current_state( TASK_INTERRUPTIBLE ); + + serviceOutgoingFifo( pCh->pMyBord ); + + schedule(); + + set_current_state( TASK_RUNNING ); + remove_wait_queue(&pCh->dss_now_wait, &wait); + + if (signal_pending(current)) { + return -EINTR; + } +#endif + return ((pCh->dataSetOut & I2_RTS) ? TIOCM_RTS : 0) + | ((pCh->dataSetOut & I2_DTR) ? TIOCM_DTR : 0) + | ((pCh->dataSetIn & I2_DCD) ? TIOCM_CAR : 0) + | ((pCh->dataSetIn & I2_RI) ? TIOCM_RNG : 0) + | ((pCh->dataSetIn & I2_DSR) ? TIOCM_DSR : 0) + | ((pCh->dataSetIn & I2_CTS) ? TIOCM_CTS : 0); +} + +static int ip2_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + i2ChanStrPtr pCh = DevTable[tty->index]; + + if (pCh == NULL) + return -ENODEV; + + if (set & TIOCM_RTS) { + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSUP); + pCh->dataSetOut |= I2_RTS; + } + if (set & TIOCM_DTR) { + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRUP); + pCh->dataSetOut |= I2_DTR; + } + + if (clear & TIOCM_RTS) { + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSDN); + pCh->dataSetOut &= ~I2_RTS; + } + if (clear & TIOCM_DTR) { + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRDN); + pCh->dataSetOut &= ~I2_DTR; + } + serviceOutgoingFifo( pCh->pMyBord ); + return 0; +} + +/******************************************************************************/ +/* Function: ip2_ioctl() */ +/* Parameters: Pointer to tty structure */ +/* Pointer to file structure */ +/* Command */ +/* Argument */ +/* Returns: Success or failure */ +/* */ +/* Description: */ +/* */ +/* */ +/******************************************************************************/ +static int +ip2_ioctl ( PTTY tty, UINT cmd, ULONG arg ) +{ + wait_queue_t wait; + i2ChanStrPtr pCh = DevTable[tty->index]; + i2eBordStrPtr pB; + struct async_icount cprev, cnow; /* kernel counter temps */ + int rc = 0; + unsigned long flags; + void __user *argp = (void __user *)arg; + + if ( pCh == NULL ) + return -ENODEV; + + pB = pCh->pMyBord; + + ip2trace (CHANN, ITRC_IOCTL, ITRC_ENTER, 2, cmd, arg ); + +#ifdef IP2DEBUG_IOCTL + printk(KERN_DEBUG "IP2: ioctl cmd (%x), arg (%lx)\n", cmd, arg ); +#endif + + switch(cmd) { + case TIOCGSERIAL: + + ip2trace (CHANN, ITRC_IOCTL, 2, 1, rc ); + + rc = get_serial_info(pCh, argp); + if (rc) + return rc; + break; + + case TIOCSSERIAL: + + ip2trace (CHANN, ITRC_IOCTL, 3, 1, rc ); + + rc = set_serial_info(pCh, argp); + if (rc) + return rc; + break; + + case TCXONC: + rc = tty_check_change(tty); + if (rc) + return rc; + switch (arg) { + case TCOOFF: + //return -ENOIOCTLCMD; + break; + case TCOON: + //return -ENOIOCTLCMD; + break; + case TCIOFF: + if (STOP_CHAR(tty) != __DISABLED_CHAR) { + i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1, + CMD_XMIT_NOW(STOP_CHAR(tty))); + } + break; + case TCION: + if (START_CHAR(tty) != __DISABLED_CHAR) { + i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1, + CMD_XMIT_NOW(START_CHAR(tty))); + } + break; + default: + return -EINVAL; + } + return 0; + + case TCSBRK: /* SVID version: non-zero arg --> no break */ + rc = tty_check_change(tty); + + ip2trace (CHANN, ITRC_IOCTL, 4, 1, rc ); + + if (!rc) { + ip2_wait_until_sent(tty,0); + if (!arg) { + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SEND_BRK(250)); + serviceOutgoingFifo( pCh->pMyBord ); + } + } + break; + + case TCSBRKP: /* support for POSIX tcsendbreak() */ + rc = tty_check_change(tty); + + ip2trace (CHANN, ITRC_IOCTL, 5, 1, rc ); + + if (!rc) { + ip2_wait_until_sent(tty,0); + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, + CMD_SEND_BRK(arg ? arg*100 : 250)); + serviceOutgoingFifo ( pCh->pMyBord ); + } + break; + + case TIOCGSOFTCAR: + + ip2trace (CHANN, ITRC_IOCTL, 6, 1, rc ); + + rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp); + if (rc) + return rc; + break; + + case TIOCSSOFTCAR: + + ip2trace (CHANN, ITRC_IOCTL, 7, 1, rc ); + + rc = get_user(arg,(unsigned long __user *) argp); + if (rc) + return rc; + tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) + | (arg ? CLOCAL : 0)); + + break; + + /* + * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - mask + * passed in arg for lines of interest (use |'ed TIOCM_RNG/DSR/CD/CTS + * for masking). Caller should use TIOCGICOUNT to see which one it was + */ + case TIOCMIWAIT: + write_lock_irqsave(&pB->read_fifo_spinlock, flags); + cprev = pCh->icount; /* note the counters on entry */ + write_unlock_irqrestore(&pB->read_fifo_spinlock, flags); + i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4, + CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP); + init_waitqueue_entry(&wait, current); + add_wait_queue(&pCh->delta_msr_wait, &wait); + set_current_state( TASK_INTERRUPTIBLE ); + + serviceOutgoingFifo( pCh->pMyBord ); + for(;;) { + ip2trace (CHANN, ITRC_IOCTL, 10, 0 ); + + schedule(); + + ip2trace (CHANN, ITRC_IOCTL, 11, 0 ); + + /* see if a signal did it */ + if (signal_pending(current)) { + rc = -ERESTARTSYS; + break; + } + write_lock_irqsave(&pB->read_fifo_spinlock, flags); + cnow = pCh->icount; /* atomic copy */ + write_unlock_irqrestore(&pB->read_fifo_spinlock, flags); + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && + cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { + rc = -EIO; /* no change => rc */ + break; + } + if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || + ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || + ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || + ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { + rc = 0; + break; + } + cprev = cnow; + } + set_current_state( TASK_RUNNING ); + remove_wait_queue(&pCh->delta_msr_wait, &wait); + + i2QueueCommands(PTYPE_BYPASS, pCh, 100, 3, + CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP); + if ( ! (pCh->flags & ASYNC_CHECK_CD)) { + i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DCD_NREP); + } + serviceOutgoingFifo( pCh->pMyBord ); + return rc; + break; + + /* + * The rest are not supported by this driver. By returning -ENOIOCTLCMD they + * will be passed to the line discipline for it to handle. + */ + case TIOCSERCONFIG: + case TIOCSERGWILD: + case TIOCSERGETLSR: + case TIOCSERSWILD: + case TIOCSERGSTRUCT: + case TIOCSERGETMULTI: + case TIOCSERSETMULTI: + + default: + ip2trace (CHANN, ITRC_IOCTL, 12, 0 ); + + rc = -ENOIOCTLCMD; + break; + } + + ip2trace (CHANN, ITRC_IOCTL, ITRC_RETURN, 0 ); + + return rc; +} + +static int ip2_get_icount(struct tty_struct *tty, + struct serial_icounter_struct *icount) +{ + i2ChanStrPtr pCh = DevTable[tty->index]; + i2eBordStrPtr pB; + struct async_icount cnow; /* kernel counter temp */ + unsigned long flags; + + if ( pCh == NULL ) + return -ENODEV; + + pB = pCh->pMyBord; + + /* + * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) + * Return: write counters to the user passed counter struct + * NB: both 1->0 and 0->1 transitions are counted except for RI where + * only 0->1 is counted. The controller is quite capable of counting + * both, but this done to preserve compatibility with the standard + * serial driver. + */ + + write_lock_irqsave(&pB->read_fifo_spinlock, flags); + cnow = pCh->icount; + write_unlock_irqrestore(&pB->read_fifo_spinlock, flags); + + icount->cts = cnow.cts; + icount->dsr = cnow.dsr; + icount->rng = cnow.rng; + icount->dcd = cnow.dcd; + icount->rx = cnow.rx; + icount->tx = cnow.tx; + icount->frame = cnow.frame; + icount->overrun = cnow.overrun; + icount->parity = cnow.parity; + icount->brk = cnow.brk; + icount->buf_overrun = cnow.buf_overrun; + return 0; +} + +/******************************************************************************/ +/* Function: GetSerialInfo() */ +/* Parameters: Pointer to channel structure */ +/* Pointer to old termios structure */ +/* Returns: Nothing */ +/* */ +/* Description: */ +/* This is to support the setserial command, and requires processing of the */ +/* standard Linux serial structure. */ +/******************************************************************************/ +static int +get_serial_info ( i2ChanStrPtr pCh, struct serial_struct __user *retinfo ) +{ + struct serial_struct tmp; + + memset ( &tmp, 0, sizeof(tmp) ); + tmp.type = pCh->pMyBord->channelBtypes.bid_value[(pCh->port_index & (IP2_PORTS_PER_BOARD-1))/16]; + if (BID_HAS_654(tmp.type)) { + tmp.type = PORT_16650; + } else { + tmp.type = PORT_CIRRUS; + } + tmp.line = pCh->port_index; + tmp.port = pCh->pMyBord->i2eBase; + tmp.irq = ip2config.irq[pCh->port_index/64]; + tmp.flags = pCh->flags; + tmp.baud_base = pCh->BaudBase; + tmp.close_delay = pCh->ClosingDelay; + tmp.closing_wait = pCh->ClosingWaitTime; + tmp.custom_divisor = pCh->BaudDivisor; + return copy_to_user(retinfo,&tmp,sizeof(*retinfo)); +} + +/******************************************************************************/ +/* Function: SetSerialInfo() */ +/* Parameters: Pointer to channel structure */ +/* Pointer to old termios structure */ +/* Returns: Nothing */ +/* */ +/* Description: */ +/* This function provides support for setserial, which uses the TIOCSSERIAL */ +/* ioctl. Not all setserial parameters are relevant. If the user attempts to */ +/* change the IRQ, address or type of the port the ioctl fails. */ +/******************************************************************************/ +static int +set_serial_info( i2ChanStrPtr pCh, struct serial_struct __user *new_info ) +{ + struct serial_struct ns; + int old_flags, old_baud_divisor; + + if (copy_from_user(&ns, new_info, sizeof (ns))) + return -EFAULT; + + /* + * We don't allow setserial to change IRQ, board address, type or baud + * base. Also line nunber as such is meaningless but we use it for our + * array index so it is fixed also. + */ + if ( (ns.irq != ip2config.irq[pCh->port_index]) + || ((int) ns.port != ((int) (pCh->pMyBord->i2eBase))) + || (ns.baud_base != pCh->BaudBase) + || (ns.line != pCh->port_index) ) { + return -EINVAL; + } + + old_flags = pCh->flags; + old_baud_divisor = pCh->BaudDivisor; + + if ( !capable(CAP_SYS_ADMIN) ) { + if ( ( ns.close_delay != pCh->ClosingDelay ) || + ( (ns.flags & ~ASYNC_USR_MASK) != + (pCh->flags & ~ASYNC_USR_MASK) ) ) { + return -EPERM; + } + + pCh->flags = (pCh->flags & ~ASYNC_USR_MASK) | + (ns.flags & ASYNC_USR_MASK); + pCh->BaudDivisor = ns.custom_divisor; + } else { + pCh->flags = (pCh->flags & ~ASYNC_FLAGS) | + (ns.flags & ASYNC_FLAGS); + pCh->BaudDivisor = ns.custom_divisor; + pCh->ClosingDelay = ns.close_delay * HZ/100; + pCh->ClosingWaitTime = ns.closing_wait * HZ/100; + } + + if ( ( (old_flags & ASYNC_SPD_MASK) != (pCh->flags & ASYNC_SPD_MASK) ) + || (old_baud_divisor != pCh->BaudDivisor) ) { + // Invalidate speed and reset parameters + set_params( pCh, NULL ); + } + + return 0; +} + +/******************************************************************************/ +/* Function: ip2_set_termios() */ +/* Parameters: Pointer to tty structure */ +/* Pointer to old termios structure */ +/* Returns: Nothing */ +/* */ +/* Description: */ +/* */ +/* */ +/******************************************************************************/ +static void +ip2_set_termios( PTTY tty, struct ktermios *old_termios ) +{ + i2ChanStrPtr pCh = (i2ChanStrPtr)tty->driver_data; + +#ifdef IP2DEBUG_IOCTL + printk (KERN_DEBUG "IP2: set termios %p\n", old_termios ); +#endif + + set_params( pCh, old_termios ); +} + +/******************************************************************************/ +/* Function: ip2_set_line_discipline() */ +/* Parameters: Pointer to tty structure */ +/* Returns: Nothing */ +/* */ +/* Description: Does nothing */ +/* */ +/* */ +/******************************************************************************/ +static void +ip2_set_line_discipline ( PTTY tty ) +{ +#ifdef IP2DEBUG_IOCTL + printk (KERN_DEBUG "IP2: set line discipline\n" ); +#endif + + ip2trace (((i2ChanStrPtr)tty->driver_data)->port_index, ITRC_IOCTL, 16, 0 ); + +} + +/******************************************************************************/ +/* Function: SetLine Characteristics() */ +/* Parameters: Pointer to channel structure */ +/* Returns: Nothing */ +/* */ +/* Description: */ +/* This routine is called to update the channel structure with the new line */ +/* characteristics, and send the appropriate commands to the board when they */ +/* change. */ +/******************************************************************************/ +static void +set_params( i2ChanStrPtr pCh, struct ktermios *o_tios ) +{ + tcflag_t cflag, iflag, lflag; + char stop_char, start_char; + struct ktermios dummy; + + lflag = pCh->pTTY->termios->c_lflag; + cflag = pCh->pTTY->termios->c_cflag; + iflag = pCh->pTTY->termios->c_iflag; + + if (o_tios == NULL) { + dummy.c_lflag = ~lflag; + dummy.c_cflag = ~cflag; + dummy.c_iflag = ~iflag; + o_tios = &dummy; + } + + { + switch ( cflag & CBAUD ) { + case B0: + i2QueueCommands( PTYPE_BYPASS, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN); + pCh->dataSetOut &= ~(I2_DTR | I2_RTS); + i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25)); + pCh->pTTY->termios->c_cflag |= (CBAUD & o_tios->c_cflag); + goto service_it; + break; + case B38400: + /* + * This is the speed that is overloaded with all the other high + * speeds, depending upon the flag settings. + */ + if ( ( pCh->flags & ASYNC_SPD_MASK ) == ASYNC_SPD_HI ) { + pCh->speed = CBR_57600; + } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI ) { + pCh->speed = CBR_115200; + } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST ) { + pCh->speed = CBR_C1; + } else { + pCh->speed = CBR_38400; + } + break; + case B50: pCh->speed = CBR_50; break; + case B75: pCh->speed = CBR_75; break; + case B110: pCh->speed = CBR_110; break; + case B134: pCh->speed = CBR_134; break; + case B150: pCh->speed = CBR_150; break; + case B200: pCh->speed = CBR_200; break; + case B300: pCh->speed = CBR_300; break; + case B600: pCh->speed = CBR_600; break; + case B1200: pCh->speed = CBR_1200; break; + case B1800: pCh->speed = CBR_1800; break; + case B2400: pCh->speed = CBR_2400; break; + case B4800: pCh->speed = CBR_4800; break; + case B9600: pCh->speed = CBR_9600; break; + case B19200: pCh->speed = CBR_19200; break; + case B57600: pCh->speed = CBR_57600; break; + case B115200: pCh->speed = CBR_115200; break; + case B153600: pCh->speed = CBR_153600; break; + case B230400: pCh->speed = CBR_230400; break; + case B307200: pCh->speed = CBR_307200; break; + case B460800: pCh->speed = CBR_460800; break; + case B921600: pCh->speed = CBR_921600; break; + default: pCh->speed = CBR_9600; break; + } + if ( pCh->speed == CBR_C1 ) { + // Process the custom speed parameters. + int bps = pCh->BaudBase / pCh->BaudDivisor; + if ( bps == 921600 ) { + pCh->speed = CBR_921600; + } else { + bps = bps/10; + i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_BAUD_DEF1(bps) ); + } + } + i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_SETBAUD(pCh->speed)); + + i2QueueCommands ( PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP); + pCh->dataSetOut |= (I2_DTR | I2_RTS); + } + if ( (CSTOPB & cflag) ^ (CSTOPB & o_tios->c_cflag)) + { + i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, + CMD_SETSTOP( ( cflag & CSTOPB ) ? CST_2 : CST_1)); + } + if (((PARENB|PARODD) & cflag) ^ ((PARENB|PARODD) & o_tios->c_cflag)) + { + i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, + CMD_SETPAR( + (cflag & PARENB ? (cflag & PARODD ? CSP_OD : CSP_EV) : CSP_NP) + ) + ); + } + /* byte size and parity */ + if ( (CSIZE & cflag)^(CSIZE & o_tios->c_cflag)) + { + int datasize; + switch ( cflag & CSIZE ) { + case CS5: datasize = CSZ_5; break; + case CS6: datasize = CSZ_6; break; + case CS7: datasize = CSZ_7; break; + case CS8: datasize = CSZ_8; break; + default: datasize = CSZ_5; break; /* as per serial.c */ + } + i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, CMD_SETBITS(datasize) ); + } + /* Process CTS flow control flag setting */ + if ( (cflag & CRTSCTS) ) { + i2QueueCommands(PTYPE_INLINE, pCh, 100, + 2, CMD_CTSFL_ENAB, CMD_RTSFL_ENAB); + } else { + i2QueueCommands(PTYPE_INLINE, pCh, 100, + 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB); + } + // + // Process XON/XOFF flow control flags settings + // + stop_char = STOP_CHAR(pCh->pTTY); + start_char = START_CHAR(pCh->pTTY); + + //////////// can't be \000 + if (stop_char == __DISABLED_CHAR ) + { + stop_char = ~__DISABLED_CHAR; + } + if (start_char == __DISABLED_CHAR ) + { + start_char = ~__DISABLED_CHAR; + } + ///////////////////////////////// + + if ( o_tios->c_cc[VSTART] != start_char ) + { + i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXON(start_char)); + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXON(start_char)); + } + if ( o_tios->c_cc[VSTOP] != stop_char ) + { + i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXOFF(stop_char)); + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXOFF(stop_char)); + } + if (stop_char == __DISABLED_CHAR ) + { + stop_char = ~__DISABLED_CHAR; //TEST123 + goto no_xoff; + } + if ((iflag & (IXOFF))^(o_tios->c_iflag & (IXOFF))) + { + if ( iflag & IXOFF ) { // Enable XOFF output flow control + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_XON)); + } else { // Disable XOFF output flow control +no_xoff: + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_NONE)); + } + } + if (start_char == __DISABLED_CHAR ) + { + goto no_xon; + } + if ((iflag & (IXON|IXANY)) ^ (o_tios->c_iflag & (IXON|IXANY))) + { + if ( iflag & IXON ) { + if ( iflag & IXANY ) { // Enable XON/XANY output flow control + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XANY)); + } else { // Enable XON output flow control + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XON)); + } + } else { // Disable XON output flow control +no_xon: + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_NONE)); + } + } + if ( (iflag & ISTRIP) ^ ( o_tios->c_iflag & (ISTRIP)) ) + { + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, + CMD_ISTRIP_OPT((iflag & ISTRIP ? 1 : 0))); + } + if ( (iflag & INPCK) ^ ( o_tios->c_iflag & (INPCK)) ) + { + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, + CMD_PARCHK((iflag & INPCK) ? CPK_ENAB : CPK_DSAB)); + } + + if ( (iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) + ^ ( o_tios->c_iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) ) + { + char brkrpt = 0; + char parrpt = 0; + + if ( iflag & IGNBRK ) { /* Ignore breaks altogether */ + /* Ignore breaks altogether */ + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_NREP); + } else { + if ( iflag & BRKINT ) { + if ( iflag & PARMRK ) { + brkrpt = 0x0a; // exception an inline triple + } else { + brkrpt = 0x1a; // exception and NULL + } + brkrpt |= 0x04; // flush input + } else { + if ( iflag & PARMRK ) { + brkrpt = 0x0b; //POSIX triple \0377 \0 \0 + } else { + brkrpt = 0x01; // Null only + } + } + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_REP(brkrpt)); + } + + if (iflag & IGNPAR) { + parrpt = 0x20; + /* would be 2 for not cirrus bug */ + /* would be 0x20 cept for cirrus bug */ + } else { + if ( iflag & PARMRK ) { + /* + * Replace error characters with 3-byte sequence (\0377,\0,char) + */ + parrpt = 0x04 ; + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_ISTRIP_OPT((char)0)); + } else { + parrpt = 0x03; + } + } + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SET_ERROR(parrpt)); + } + if (cflag & CLOCAL) { + // Status reporting fails for DCD if this is off + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_NREP); + pCh->flags &= ~ASYNC_CHECK_CD; + } else { + i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_REP); + pCh->flags |= ASYNC_CHECK_CD; + } + +service_it: + i2DrainOutput( pCh, 100 ); +} + +/******************************************************************************/ +/* IPL Device Section */ +/******************************************************************************/ + +/******************************************************************************/ +/* Function: ip2_ipl_read() */ +/* Parameters: Pointer to device inode */ +/* Pointer to file structure */ +/* Pointer to data */ +/* Number of bytes to read */ +/* Returns: Success or failure */ +/* */ +/* Description: Ugly */ +/* */ +/* */ +/******************************************************************************/ + +static +ssize_t +ip2_ipl_read(struct file *pFile, char __user *pData, size_t count, loff_t *off ) +{ + unsigned int minor = iminor(pFile->f_path.dentry->d_inode); + int rc = 0; + +#ifdef IP2DEBUG_IPL + printk (KERN_DEBUG "IP2IPL: read %p, %d bytes\n", pData, count ); +#endif + + switch( minor ) { + case 0: // IPL device + rc = -EINVAL; + break; + case 1: // Status dump + rc = -EINVAL; + break; + case 2: // Ping device + rc = -EINVAL; + break; + case 3: // Trace device + rc = DumpTraceBuffer ( pData, count ); + break; + case 4: // Trace device + rc = DumpFifoBuffer ( pData, count ); + break; + default: + rc = -ENODEV; + break; + } + return rc; +} + +static int +DumpFifoBuffer ( char __user *pData, int count ) +{ +#ifdef DEBUG_FIFO + int rc; + rc = copy_to_user(pData, DBGBuf, count); + + printk(KERN_DEBUG "Last index %d\n", I ); + + return count; +#endif /* DEBUG_FIFO */ + return 0; +} + +static int +DumpTraceBuffer ( char __user *pData, int count ) +{ +#ifdef IP2DEBUG_TRACE + int rc; + int dumpcount; + int chunk; + int *pIndex = (int __user *)pData; + + if ( count < (sizeof(int) * 6) ) { + return -EIO; + } + rc = put_user(tracewrap, pIndex ); + rc = put_user(TRACEMAX, ++pIndex ); + rc = put_user(tracestrip, ++pIndex ); + rc = put_user(tracestuff, ++pIndex ); + pData += sizeof(int) * 6; + count -= sizeof(int) * 6; + + dumpcount = tracestuff - tracestrip; + if ( dumpcount < 0 ) { + dumpcount += TRACEMAX; + } + if ( dumpcount > count ) { + dumpcount = count; + } + chunk = TRACEMAX - tracestrip; + if ( dumpcount > chunk ) { + rc = copy_to_user(pData, &tracebuf[tracestrip], + chunk * sizeof(tracebuf[0]) ); + pData += chunk * sizeof(tracebuf[0]); + tracestrip = 0; + chunk = dumpcount - chunk; + } else { + chunk = dumpcount; + } + rc = copy_to_user(pData, &tracebuf[tracestrip], + chunk * sizeof(tracebuf[0]) ); + tracestrip += chunk; + tracewrap = 0; + + rc = put_user(tracestrip, ++pIndex ); + rc = put_user(tracestuff, ++pIndex ); + + return dumpcount; +#else + return 0; +#endif +} + +/******************************************************************************/ +/* Function: ip2_ipl_write() */ +/* Parameters: */ +/* Pointer to file structure */ +/* Pointer to data */ +/* Number of bytes to write */ +/* Returns: Success or failure */ +/* */ +/* Description: */ +/* */ +/* */ +/******************************************************************************/ +static ssize_t +ip2_ipl_write(struct file *pFile, const char __user *pData, size_t count, loff_t *off) +{ +#ifdef IP2DEBUG_IPL + printk (KERN_DEBUG "IP2IPL: write %p, %d bytes\n", pData, count ); +#endif + return 0; +} + +/******************************************************************************/ +/* Function: ip2_ipl_ioctl() */ +/* Parameters: Pointer to device inode */ +/* Pointer to file structure */ +/* Command */ +/* Argument */ +/* Returns: Success or failure */ +/* */ +/* Description: */ +/* */ +/* */ +/******************************************************************************/ +static long +ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg ) +{ + unsigned int iplminor = iminor(pFile->f_path.dentry->d_inode); + int rc = 0; + void __user *argp = (void __user *)arg; + ULONG __user *pIndex = argp; + i2eBordStrPtr pB = i2BoardPtrTable[iplminor / 4]; + i2ChanStrPtr pCh; + +#ifdef IP2DEBUG_IPL + printk (KERN_DEBUG "IP2IPL: ioctl cmd %d, arg %ld\n", cmd, arg ); +#endif + + mutex_lock(&ip2_mutex); + + switch ( iplminor ) { + case 0: // IPL device + rc = -EINVAL; + break; + case 1: // Status dump + case 5: + case 9: + case 13: + switch ( cmd ) { + case 64: /* Driver - ip2stat */ + rc = put_user(-1, pIndex++ ); + rc = put_user(irq_counter, pIndex++ ); + rc = put_user(bh_counter, pIndex++ ); + break; + + case 65: /* Board - ip2stat */ + if ( pB ) { + rc = copy_to_user(argp, pB, sizeof(i2eBordStr)); + rc = put_user(inb(pB->i2eStatus), + (ULONG __user *)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) ); + } else { + rc = -ENODEV; + } + break; + + default: + if (cmd < IP2_MAX_PORTS) { + pCh = DevTable[cmd]; + if ( pCh ) + { + rc = copy_to_user(argp, pCh, sizeof(i2ChanStr)); + if (rc) + rc = -EFAULT; + } else { + rc = -ENODEV; + } + } else { + rc = -EINVAL; + } + } + break; + + case 2: // Ping device + rc = -EINVAL; + break; + case 3: // Trace device + /* + * akpm: This used to write a whole bunch of function addresses + * to userspace, which generated lots of put_user() warnings. + * I killed it all. Just return "success" and don't do + * anything. + */ + if (cmd == 1) + rc = 0; + else + rc = -EINVAL; + break; + + default: + rc = -ENODEV; + break; + } + mutex_unlock(&ip2_mutex); + return rc; +} + +/******************************************************************************/ +/* Function: ip2_ipl_open() */ +/* Parameters: Pointer to device inode */ +/* Pointer to file structure */ +/* Returns: Success or failure */ +/* */ +/* Description: */ +/* */ +/* */ +/******************************************************************************/ +static int +ip2_ipl_open( struct inode *pInode, struct file *pFile ) +{ + +#ifdef IP2DEBUG_IPL + printk (KERN_DEBUG "IP2IPL: open\n" ); +#endif + return 0; +} + +static int +proc_ip2mem_show(struct seq_file *m, void *v) +{ + i2eBordStrPtr pB; + i2ChanStrPtr pCh; + PTTY tty; + int i; + +#define FMTLINE "%3d: 0x%08x 0x%08x 0%011o 0%011o\n" +#define FMTLIN2 " 0x%04x 0x%04x tx flow 0x%x\n" +#define FMTLIN3 " 0x%04x 0x%04x rc flow\n" + + seq_printf(m,"\n"); + + for( i = 0; i < IP2_MAX_BOARDS; ++i ) { + pB = i2BoardPtrTable[i]; + if ( pB ) { + seq_printf(m,"board %d:\n",i); + seq_printf(m,"\tFifo rem: %d mty: %x outM %x\n", + pB->i2eFifoRemains,pB->i2eWaitingForEmptyFifo,pB->i2eOutMailWaiting); + } + } + + seq_printf(m,"#: tty flags, port flags, cflags, iflags\n"); + for (i=0; i < IP2_MAX_PORTS; i++) { + pCh = DevTable[i]; + if (pCh) { + tty = pCh->pTTY; + if (tty && tty->count) { + seq_printf(m,FMTLINE,i,(int)tty->flags,pCh->flags, + tty->termios->c_cflag,tty->termios->c_iflag); + + seq_printf(m,FMTLIN2, + pCh->outfl.asof,pCh->outfl.room,pCh->channelNeeds); + seq_printf(m,FMTLIN3,pCh->infl.asof,pCh->infl.room); + } + } + } + return 0; +} + +static int proc_ip2mem_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_ip2mem_show, NULL); +} + +static const struct file_operations ip2mem_proc_fops = { + .owner = THIS_MODULE, + .open = proc_ip2mem_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* + * This is the handler for /proc/tty/driver/ip2 + * + * This stretch of code has been largely plagerized from at least three + * different sources including ip2mkdev.c and a couple of other drivers. + * The bugs are all mine. :-) =mhw= + */ +static int ip2_proc_show(struct seq_file *m, void *v) +{ + int i, j, box; + int boxes = 0; + int ports = 0; + int tports = 0; + i2eBordStrPtr pB; + char *sep; + + seq_printf(m, "ip2info: 1.0 driver: %s\n", pcVersion); + seq_printf(m, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n", + IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR, + IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX); + + for( i = 0; i < IP2_MAX_BOARDS; ++i ) { + /* This need to be reset for a board by board count... */ + boxes = 0; + pB = i2BoardPtrTable[i]; + if( pB ) { + switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) + { + case POR_ID_FIIEX: + seq_printf(m, "Board %d: EX ports=", i); + sep = ""; + for( box = 0; box < ABS_MAX_BOXES; ++box ) + { + ports = 0; + + if( pB->i2eChannelMap[box] != 0 ) ++boxes; + for( j = 0; j < ABS_BIGGEST_BOX; ++j ) + { + if( pB->i2eChannelMap[box] & 1<< j ) { + ++ports; + } + } + seq_printf(m, "%s%d", sep, ports); + sep = ","; + tports += ports; + } + seq_printf(m, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8); + break; + + case POR_ID_II_4: + seq_printf(m, "Board %d: ISA-4 ports=4 boxes=1", i); + tports = ports = 4; + break; + + case POR_ID_II_8: + seq_printf(m, "Board %d: ISA-8-std ports=8 boxes=1", i); + tports = ports = 8; + break; + + case POR_ID_II_8R: + seq_printf(m, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i); + tports = ports = 8; + break; + + default: + seq_printf(m, "Board %d: unknown", i); + /* Don't try and probe for minor numbers */ + tports = ports = 0; + } + + } else { + /* Don't try and probe for minor numbers */ + seq_printf(m, "Board %d: vacant", i); + tports = ports = 0; + } + + if( tports ) { + seq_puts(m, " minors="); + sep = ""; + for ( box = 0; box < ABS_MAX_BOXES; ++box ) + { + for ( j = 0; j < ABS_BIGGEST_BOX; ++j ) + { + if ( pB->i2eChannelMap[box] & (1 << j) ) + { + seq_printf(m, "%s%d", sep, + j + ABS_BIGGEST_BOX * + (box+i*ABS_MAX_BOXES)); + sep = ","; + } + } + } + } + seq_putc(m, '\n'); + } + return 0; + } + +static int ip2_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, ip2_proc_show, NULL); +} + +static const struct file_operations ip2_proc_fops = { + .owner = THIS_MODULE, + .open = ip2_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/******************************************************************************/ +/* Function: ip2trace() */ +/* Parameters: Value to add to trace buffer */ +/* Returns: Nothing */ +/* */ +/* Description: */ +/* */ +/* */ +/******************************************************************************/ +#ifdef IP2DEBUG_TRACE +void +ip2trace (unsigned short pn, unsigned char cat, unsigned char label, unsigned long codes, ...) +{ + long flags; + unsigned long *pCode = &codes; + union ip2breadcrumb bc; + i2ChanStrPtr pCh; + + + tracebuf[tracestuff++] = jiffies; + if ( tracestuff == TRACEMAX ) { + tracestuff = 0; + } + if ( tracestuff == tracestrip ) { + if ( ++tracestrip == TRACEMAX ) { + tracestrip = 0; + } + ++tracewrap; + } + + bc.hdr.port = 0xff & pn; + bc.hdr.cat = cat; + bc.hdr.codes = (unsigned char)( codes & 0xff ); + bc.hdr.label = label; + tracebuf[tracestuff++] = bc.value; + + for (;;) { + if ( tracestuff == TRACEMAX ) { + tracestuff = 0; + } + if ( tracestuff == tracestrip ) { + if ( ++tracestrip == TRACEMAX ) { + tracestrip = 0; + } + ++tracewrap; + } + + if ( !codes-- ) + break; + + tracebuf[tracestuff++] = *++pCode; + } +} +#endif + + +MODULE_LICENSE("GPL"); + +static struct pci_device_id ip2main_pci_tbl[] __devinitdata __used = { + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_IP2EX) }, + { } +}; + +MODULE_DEVICE_TABLE(pci, ip2main_pci_tbl); + +MODULE_FIRMWARE("intelliport2.bin"); diff --git a/drivers/staging/tty/ip2/ip2trace.h b/drivers/staging/tty/ip2/ip2trace.h new file mode 100644 index 000000000000..da20435dc8a6 --- /dev/null +++ b/drivers/staging/tty/ip2/ip2trace.h @@ -0,0 +1,42 @@ + +// +union ip2breadcrumb +{ + struct { + unsigned char port, cat, codes, label; + } __attribute__ ((packed)) hdr; + unsigned long value; +}; + +#define ITRC_NO_PORT 0xFF +#define CHANN (pCh->port_index) + +#define ITRC_ERROR '!' +#define ITRC_INIT 'A' +#define ITRC_OPEN 'B' +#define ITRC_CLOSE 'C' +#define ITRC_DRAIN 'D' +#define ITRC_IOCTL 'E' +#define ITRC_FLUSH 'F' +#define ITRC_STATUS 'G' +#define ITRC_HANGUP 'H' +#define ITRC_INTR 'I' +#define ITRC_SFLOW 'J' +#define ITRC_SBCMD 'K' +#define ITRC_SICMD 'L' +#define ITRC_MODEM 'M' +#define ITRC_INPUT 'N' +#define ITRC_OUTPUT 'O' +#define ITRC_PUTC 'P' +#define ITRC_QUEUE 'Q' +#define ITRC_STFLW 'R' +#define ITRC_SFIFO 'S' +#define ITRC_VERIFY 'V' +#define ITRC_WRITE 'W' + +#define ITRC_ENTER 0x00 +#define ITRC_RETURN 0xFF + +#define ITRC_QUEUE_ROOM 2 +#define ITRC_QUEUE_CMD 6 + diff --git a/drivers/staging/tty/ip2/ip2types.h b/drivers/staging/tty/ip2/ip2types.h new file mode 100644 index 000000000000..9d67b260b2f6 --- /dev/null +++ b/drivers/staging/tty/ip2/ip2types.h @@ -0,0 +1,57 @@ +/******************************************************************************* +* +* (c) 1998 by Computone Corporation +* +******************************************************************************** +* +* +* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport +* serial I/O controllers. +* +* DESCRIPTION: Driver constants and type definitions. +* +* NOTES: +* +*******************************************************************************/ +#ifndef IP2TYPES_H +#define IP2TYPES_H + +//************* +//* Constants * +//************* + +// Define some limits for this driver. Ports per board is a hardware limitation +// that will not change. Current hardware limits this to 64 ports per board. +// Boards per driver is a self-imposed limit. +// +#define IP2_MAX_BOARDS 4 +#define IP2_PORTS_PER_BOARD ABS_MOST_PORTS +#define IP2_MAX_PORTS (IP2_MAX_BOARDS*IP2_PORTS_PER_BOARD) + +#define ISA 0 +#define PCI 1 +#define EISA 2 + +//******************** +//* Type Definitions * +//******************** + +typedef struct tty_struct * PTTY; +typedef wait_queue_head_t PWAITQ; + +typedef unsigned char UCHAR; +typedef unsigned int UINT; +typedef unsigned short USHORT; +typedef unsigned long ULONG; + +typedef struct +{ + short irq[IP2_MAX_BOARDS]; + unsigned short addr[IP2_MAX_BOARDS]; + int type[IP2_MAX_BOARDS]; +#ifdef CONFIG_PCI + struct pci_dev *pci_dev[IP2_MAX_BOARDS]; +#endif +} ip2config_t; + +#endif diff --git a/drivers/staging/tty/istallion.c b/drivers/staging/tty/istallion.c new file mode 100644 index 000000000000..0b266272cccd --- /dev/null +++ b/drivers/staging/tty/istallion.c @@ -0,0 +1,4507 @@ +/*****************************************************************************/ + +/* + * istallion.c -- stallion intelligent multiport serial driver. + * + * Copyright (C) 1996-1999 Stallion Technologies + * Copyright (C) 1994-1996 Greg Ungerer. + * + * This code is loosely based on the Linux serial driver, written by + * Linus Torvalds, Theodore T'so and others. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +/*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +/*****************************************************************************/ + +/* + * Define different board types. Not all of the following board types + * are supported by this driver. But I will use the standard "assigned" + * board numbers. Currently supported boards are abbreviated as: + * ECP = EasyConnection 8/64, ONB = ONboard, BBY = Brumby and + * STAL = Stallion. + */ +#define BRD_UNKNOWN 0 +#define BRD_STALLION 1 +#define BRD_BRUMBY4 2 +#define BRD_ONBOARD2 3 +#define BRD_ONBOARD 4 +#define BRD_ONBOARDE 7 +#define BRD_ECP 23 +#define BRD_ECPE 24 +#define BRD_ECPMC 25 +#define BRD_ECPPCI 29 + +#define BRD_BRUMBY BRD_BRUMBY4 + +/* + * Define a configuration structure to hold the board configuration. + * Need to set this up in the code (for now) with the boards that are + * to be configured into the system. This is what needs to be modified + * when adding/removing/modifying boards. Each line entry in the + * stli_brdconf[] array is a board. Each line contains io/irq/memory + * ranges for that board (as well as what type of board it is). + * Some examples: + * { BRD_ECP, 0x2a0, 0, 0xcc000, 0, 0 }, + * This line will configure an EasyConnection 8/64 at io address 2a0, + * and shared memory address of cc000. Multiple EasyConnection 8/64 + * boards can share the same shared memory address space. No interrupt + * is required for this board type. + * Another example: + * { BRD_ECPE, 0x5000, 0, 0x80000000, 0, 0 }, + * This line will configure an EasyConnection 8/64 EISA in slot 5 and + * shared memory address of 0x80000000 (2 GByte). Multiple + * EasyConnection 8/64 EISA boards can share the same shared memory + * address space. No interrupt is required for this board type. + * Another example: + * { BRD_ONBOARD, 0x240, 0, 0xd0000, 0, 0 }, + * This line will configure an ONboard (ISA type) at io address 240, + * and shared memory address of d0000. Multiple ONboards can share + * the same shared memory address space. No interrupt required. + * Another example: + * { BRD_BRUMBY4, 0x360, 0, 0xc8000, 0, 0 }, + * This line will configure a Brumby board (any number of ports!) at + * io address 360 and shared memory address of c8000. All Brumby boards + * configured into a system must have their own separate io and memory + * addresses. No interrupt is required. + * Another example: + * { BRD_STALLION, 0x330, 0, 0xd0000, 0, 0 }, + * This line will configure an original Stallion board at io address 330 + * and shared memory address d0000 (this would only be valid for a "V4.0" + * or Rev.O Stallion board). All Stallion boards configured into the + * system must have their own separate io and memory addresses. No + * interrupt is required. + */ + +struct stlconf { + int brdtype; + int ioaddr1; + int ioaddr2; + unsigned long memaddr; + int irq; + int irqtype; +}; + +static unsigned int stli_nrbrds; + +/* stli_lock must NOT be taken holding brd_lock */ +static spinlock_t stli_lock; /* TTY logic lock */ +static spinlock_t brd_lock; /* Board logic lock */ + +/* + * There is some experimental EISA board detection code in this driver. + * By default it is disabled, but for those that want to try it out, + * then set the define below to be 1. + */ +#define STLI_EISAPROBE 0 + +/*****************************************************************************/ + +/* + * Define some important driver characteristics. Device major numbers + * allocated as per Linux Device Registry. + */ +#ifndef STL_SIOMEMMAJOR +#define STL_SIOMEMMAJOR 28 +#endif +#ifndef STL_SERIALMAJOR +#define STL_SERIALMAJOR 24 +#endif +#ifndef STL_CALLOUTMAJOR +#define STL_CALLOUTMAJOR 25 +#endif + +/*****************************************************************************/ + +/* + * Define our local driver identity first. Set up stuff to deal with + * all the local structures required by a serial tty driver. + */ +static char *stli_drvtitle = "Stallion Intelligent Multiport Serial Driver"; +static char *stli_drvname = "istallion"; +static char *stli_drvversion = "5.6.0"; +static char *stli_serialname = "ttyE"; + +static struct tty_driver *stli_serial; +static const struct tty_port_operations stli_port_ops; + +#define STLI_TXBUFSIZE 4096 + +/* + * Use a fast local buffer for cooked characters. Typically a whole + * bunch of cooked characters come in for a port, 1 at a time. So we + * save those up into a local buffer, then write out the whole lot + * with a large memcpy. Just use 1 buffer for all ports, since its + * use it is only need for short periods of time by each port. + */ +static char *stli_txcookbuf; +static int stli_txcooksize; +static int stli_txcookrealsize; +static struct tty_struct *stli_txcooktty; + +/* + * Define a local default termios struct. All ports will be created + * with this termios initially. Basically all it defines is a raw port + * at 9600 baud, 8 data bits, no parity, 1 stop bit. + */ +static struct ktermios stli_deftermios = { + .c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL), + .c_cc = INIT_C_CC, + .c_ispeed = 9600, + .c_ospeed = 9600, +}; + +/* + * Define global stats structures. Not used often, and can be + * re-used for each stats call. + */ +static comstats_t stli_comstats; +static combrd_t stli_brdstats; +static struct asystats stli_cdkstats; + +/*****************************************************************************/ + +static DEFINE_MUTEX(stli_brdslock); +static struct stlibrd *stli_brds[STL_MAXBRDS]; + +static int stli_shared; + +/* + * Per board state flags. Used with the state field of the board struct. + * Not really much here... All we need to do is keep track of whether + * the board has been detected, and whether it is actually running a slave + * or not. + */ +#define BST_FOUND 0 +#define BST_STARTED 1 +#define BST_PROBED 2 + +/* + * Define the set of port state flags. These are marked for internal + * state purposes only, usually to do with the state of communications + * with the slave. Most of them need to be updated atomically, so always + * use the bit setting operations (unless protected by cli/sti). + */ +#define ST_OPENING 2 +#define ST_CLOSING 3 +#define ST_CMDING 4 +#define ST_TXBUSY 5 +#define ST_RXING 6 +#define ST_DOFLUSHRX 7 +#define ST_DOFLUSHTX 8 +#define ST_DOSIGS 9 +#define ST_RXSTOP 10 +#define ST_GETSIGS 11 + +/* + * Define an array of board names as printable strings. Handy for + * referencing boards when printing trace and stuff. + */ +static char *stli_brdnames[] = { + "Unknown", + "Stallion", + "Brumby", + "ONboard-MC", + "ONboard", + "Brumby", + "Brumby", + "ONboard-EI", + NULL, + "ONboard", + "ONboard-MC", + "ONboard-MC", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "EasyIO", + "EC8/32-AT", + "EC8/32-MC", + "EC8/64-AT", + "EC8/64-EI", + "EC8/64-MC", + "EC8/32-PCI", + "EC8/64-PCI", + "EasyIO-PCI", + "EC/RA-PCI", +}; + +/*****************************************************************************/ + +/* + * Define some string labels for arguments passed from the module + * load line. These allow for easy board definitions, and easy + * modification of the io, memory and irq resoucres. + */ + +static char *board0[8]; +static char *board1[8]; +static char *board2[8]; +static char *board3[8]; + +static char **stli_brdsp[] = { + (char **) &board0, + (char **) &board1, + (char **) &board2, + (char **) &board3 +}; + +/* + * Define a set of common board names, and types. This is used to + * parse any module arguments. + */ + +static struct stlibrdtype { + char *name; + int type; +} stli_brdstr[] = { + { "stallion", BRD_STALLION }, + { "1", BRD_STALLION }, + { "brumby", BRD_BRUMBY }, + { "brumby4", BRD_BRUMBY }, + { "brumby/4", BRD_BRUMBY }, + { "brumby-4", BRD_BRUMBY }, + { "brumby8", BRD_BRUMBY }, + { "brumby/8", BRD_BRUMBY }, + { "brumby-8", BRD_BRUMBY }, + { "brumby16", BRD_BRUMBY }, + { "brumby/16", BRD_BRUMBY }, + { "brumby-16", BRD_BRUMBY }, + { "2", BRD_BRUMBY }, + { "onboard2", BRD_ONBOARD2 }, + { "onboard-2", BRD_ONBOARD2 }, + { "onboard/2", BRD_ONBOARD2 }, + { "onboard-mc", BRD_ONBOARD2 }, + { "onboard/mc", BRD_ONBOARD2 }, + { "onboard-mca", BRD_ONBOARD2 }, + { "onboard/mca", BRD_ONBOARD2 }, + { "3", BRD_ONBOARD2 }, + { "onboard", BRD_ONBOARD }, + { "onboardat", BRD_ONBOARD }, + { "4", BRD_ONBOARD }, + { "onboarde", BRD_ONBOARDE }, + { "onboard-e", BRD_ONBOARDE }, + { "onboard/e", BRD_ONBOARDE }, + { "onboard-ei", BRD_ONBOARDE }, + { "onboard/ei", BRD_ONBOARDE }, + { "7", BRD_ONBOARDE }, + { "ecp", BRD_ECP }, + { "ecpat", BRD_ECP }, + { "ec8/64", BRD_ECP }, + { "ec8/64-at", BRD_ECP }, + { "ec8/64-isa", BRD_ECP }, + { "23", BRD_ECP }, + { "ecpe", BRD_ECPE }, + { "ecpei", BRD_ECPE }, + { "ec8/64-e", BRD_ECPE }, + { "ec8/64-ei", BRD_ECPE }, + { "24", BRD_ECPE }, + { "ecpmc", BRD_ECPMC }, + { "ec8/64-mc", BRD_ECPMC }, + { "ec8/64-mca", BRD_ECPMC }, + { "25", BRD_ECPMC }, + { "ecppci", BRD_ECPPCI }, + { "ec/ra", BRD_ECPPCI }, + { "ec/ra-pc", BRD_ECPPCI }, + { "ec/ra-pci", BRD_ECPPCI }, + { "29", BRD_ECPPCI }, +}; + +/* + * Define the module agruments. + */ +MODULE_AUTHOR("Greg Ungerer"); +MODULE_DESCRIPTION("Stallion Intelligent Multiport Serial Driver"); +MODULE_LICENSE("GPL"); + + +module_param_array(board0, charp, NULL, 0); +MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,memaddr]"); +module_param_array(board1, charp, NULL, 0); +MODULE_PARM_DESC(board1, "Board 1 config -> name[,ioaddr[,memaddr]"); +module_param_array(board2, charp, NULL, 0); +MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,memaddr]"); +module_param_array(board3, charp, NULL, 0); +MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,memaddr]"); + +#if STLI_EISAPROBE != 0 +/* + * Set up a default memory address table for EISA board probing. + * The default addresses are all bellow 1Mbyte, which has to be the + * case anyway. They should be safe, since we only read values from + * them, and interrupts are disabled while we do it. If the higher + * memory support is compiled in then we also try probing around + * the 1Gb, 2Gb and 3Gb areas as well... + */ +static unsigned long stli_eisamemprobeaddrs[] = { + 0xc0000, 0xd0000, 0xe0000, 0xf0000, + 0x80000000, 0x80010000, 0x80020000, 0x80030000, + 0x40000000, 0x40010000, 0x40020000, 0x40030000, + 0xc0000000, 0xc0010000, 0xc0020000, 0xc0030000, + 0xff000000, 0xff010000, 0xff020000, 0xff030000, +}; + +static int stli_eisamempsize = ARRAY_SIZE(stli_eisamemprobeaddrs); +#endif + +/* + * Define the Stallion PCI vendor and device IDs. + */ +#ifndef PCI_DEVICE_ID_ECRA +#define PCI_DEVICE_ID_ECRA 0x0004 +#endif + +static struct pci_device_id istallion_pci_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA), }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, istallion_pci_tbl); + +static struct pci_driver stli_pcidriver; + +/*****************************************************************************/ + +/* + * Hardware configuration info for ECP boards. These defines apply + * to the directly accessible io ports of the ECP. There is a set of + * defines for each ECP board type, ISA, EISA, MCA and PCI. + */ +#define ECP_IOSIZE 4 + +#define ECP_MEMSIZE (128 * 1024) +#define ECP_PCIMEMSIZE (256 * 1024) + +#define ECP_ATPAGESIZE (4 * 1024) +#define ECP_MCPAGESIZE (4 * 1024) +#define ECP_EIPAGESIZE (64 * 1024) +#define ECP_PCIPAGESIZE (64 * 1024) + +#define STL_EISAID 0x8c4e + +/* + * Important defines for the ISA class of ECP board. + */ +#define ECP_ATIREG 0 +#define ECP_ATCONFR 1 +#define ECP_ATMEMAR 2 +#define ECP_ATMEMPR 3 +#define ECP_ATSTOP 0x1 +#define ECP_ATINTENAB 0x10 +#define ECP_ATENABLE 0x20 +#define ECP_ATDISABLE 0x00 +#define ECP_ATADDRMASK 0x3f000 +#define ECP_ATADDRSHFT 12 + +/* + * Important defines for the EISA class of ECP board. + */ +#define ECP_EIIREG 0 +#define ECP_EIMEMARL 1 +#define ECP_EICONFR 2 +#define ECP_EIMEMARH 3 +#define ECP_EIENABLE 0x1 +#define ECP_EIDISABLE 0x0 +#define ECP_EISTOP 0x4 +#define ECP_EIEDGE 0x00 +#define ECP_EILEVEL 0x80 +#define ECP_EIADDRMASKL 0x00ff0000 +#define ECP_EIADDRSHFTL 16 +#define ECP_EIADDRMASKH 0xff000000 +#define ECP_EIADDRSHFTH 24 +#define ECP_EIBRDENAB 0xc84 + +#define ECP_EISAID 0x4 + +/* + * Important defines for the Micro-channel class of ECP board. + * (It has a lot in common with the ISA boards.) + */ +#define ECP_MCIREG 0 +#define ECP_MCCONFR 1 +#define ECP_MCSTOP 0x20 +#define ECP_MCENABLE 0x80 +#define ECP_MCDISABLE 0x00 + +/* + * Important defines for the PCI class of ECP board. + * (It has a lot in common with the other ECP boards.) + */ +#define ECP_PCIIREG 0 +#define ECP_PCICONFR 1 +#define ECP_PCISTOP 0x01 + +/* + * Hardware configuration info for ONboard and Brumby boards. These + * defines apply to the directly accessible io ports of these boards. + */ +#define ONB_IOSIZE 16 +#define ONB_MEMSIZE (64 * 1024) +#define ONB_ATPAGESIZE (64 * 1024) +#define ONB_MCPAGESIZE (64 * 1024) +#define ONB_EIMEMSIZE (128 * 1024) +#define ONB_EIPAGESIZE (64 * 1024) + +/* + * Important defines for the ISA class of ONboard board. + */ +#define ONB_ATIREG 0 +#define ONB_ATMEMAR 1 +#define ONB_ATCONFR 2 +#define ONB_ATSTOP 0x4 +#define ONB_ATENABLE 0x01 +#define ONB_ATDISABLE 0x00 +#define ONB_ATADDRMASK 0xff0000 +#define ONB_ATADDRSHFT 16 + +#define ONB_MEMENABLO 0 +#define ONB_MEMENABHI 0x02 + +/* + * Important defines for the EISA class of ONboard board. + */ +#define ONB_EIIREG 0 +#define ONB_EIMEMARL 1 +#define ONB_EICONFR 2 +#define ONB_EIMEMARH 3 +#define ONB_EIENABLE 0x1 +#define ONB_EIDISABLE 0x0 +#define ONB_EISTOP 0x4 +#define ONB_EIEDGE 0x00 +#define ONB_EILEVEL 0x80 +#define ONB_EIADDRMASKL 0x00ff0000 +#define ONB_EIADDRSHFTL 16 +#define ONB_EIADDRMASKH 0xff000000 +#define ONB_EIADDRSHFTH 24 +#define ONB_EIBRDENAB 0xc84 + +#define ONB_EISAID 0x1 + +/* + * Important defines for the Brumby boards. They are pretty simple, + * there is not much that is programmably configurable. + */ +#define BBY_IOSIZE 16 +#define BBY_MEMSIZE (64 * 1024) +#define BBY_PAGESIZE (16 * 1024) + +#define BBY_ATIREG 0 +#define BBY_ATCONFR 1 +#define BBY_ATSTOP 0x4 + +/* + * Important defines for the Stallion boards. They are pretty simple, + * there is not much that is programmably configurable. + */ +#define STAL_IOSIZE 16 +#define STAL_MEMSIZE (64 * 1024) +#define STAL_PAGESIZE (64 * 1024) + +/* + * Define the set of status register values for EasyConnection panels. + * The signature will return with the status value for each panel. From + * this we can determine what is attached to the board - before we have + * actually down loaded any code to it. + */ +#define ECH_PNLSTATUS 2 +#define ECH_PNL16PORT 0x20 +#define ECH_PNLIDMASK 0x07 +#define ECH_PNLXPID 0x40 +#define ECH_PNLINTRPEND 0x80 + +/* + * Define some macros to do things to the board. Even those these boards + * are somewhat related there is often significantly different ways of + * doing some operation on it (like enable, paging, reset, etc). So each + * board class has a set of functions which do the commonly required + * operations. The macros below basically just call these functions, + * generally checking for a NULL function - which means that the board + * needs nothing done to it to achieve this operation! + */ +#define EBRDINIT(brdp) \ + if (brdp->init != NULL) \ + (* brdp->init)(brdp) + +#define EBRDENABLE(brdp) \ + if (brdp->enable != NULL) \ + (* brdp->enable)(brdp); + +#define EBRDDISABLE(brdp) \ + if (brdp->disable != NULL) \ + (* brdp->disable)(brdp); + +#define EBRDINTR(brdp) \ + if (brdp->intr != NULL) \ + (* brdp->intr)(brdp); + +#define EBRDRESET(brdp) \ + if (brdp->reset != NULL) \ + (* brdp->reset)(brdp); + +#define EBRDGETMEMPTR(brdp,offset) \ + (* brdp->getmemptr)(brdp, offset, __LINE__) + +/* + * Define the maximal baud rate, and the default baud base for ports. + */ +#define STL_MAXBAUD 460800 +#define STL_BAUDBASE 115200 +#define STL_CLOSEDELAY (5 * HZ / 10) + +/*****************************************************************************/ + +/* + * Define macros to extract a brd or port number from a minor number. + */ +#define MINOR2BRD(min) (((min) & 0xc0) >> 6) +#define MINOR2PORT(min) ((min) & 0x3f) + +/*****************************************************************************/ + +/* + * Prototype all functions in this driver! + */ + +static int stli_parsebrd(struct stlconf *confp, char **argp); +static int stli_open(struct tty_struct *tty, struct file *filp); +static void stli_close(struct tty_struct *tty, struct file *filp); +static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count); +static int stli_putchar(struct tty_struct *tty, unsigned char ch); +static void stli_flushchars(struct tty_struct *tty); +static int stli_writeroom(struct tty_struct *tty); +static int stli_charsinbuffer(struct tty_struct *tty); +static int stli_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); +static void stli_settermios(struct tty_struct *tty, struct ktermios *old); +static void stli_throttle(struct tty_struct *tty); +static void stli_unthrottle(struct tty_struct *tty); +static void stli_stop(struct tty_struct *tty); +static void stli_start(struct tty_struct *tty); +static void stli_flushbuffer(struct tty_struct *tty); +static int stli_breakctl(struct tty_struct *tty, int state); +static void stli_waituntilsent(struct tty_struct *tty, int timeout); +static void stli_sendxchar(struct tty_struct *tty, char ch); +static void stli_hangup(struct tty_struct *tty); + +static int stli_brdinit(struct stlibrd *brdp); +static int stli_startbrd(struct stlibrd *brdp); +static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp); +static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp); +static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg); +static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp); +static void stli_poll(unsigned long arg); +static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp); +static int stli_initopen(struct tty_struct *tty, struct stlibrd *brdp, struct stliport *portp); +static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); +static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); +static int stli_setport(struct tty_struct *tty); +static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); +static void stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); +static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); +static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp); +static void stli_mkasyport(struct tty_struct *tty, struct stliport *portp, asyport_t *pp, struct ktermios *tiosp); +static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts); +static long stli_mktiocm(unsigned long sigvalue); +static void stli_read(struct stlibrd *brdp, struct stliport *portp); +static int stli_getserial(struct stliport *portp, struct serial_struct __user *sp); +static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *sp); +static int stli_getbrdstats(combrd_t __user *bp); +static int stli_getportstats(struct tty_struct *tty, struct stliport *portp, comstats_t __user *cp); +static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp); +static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp); +static int stli_getportstruct(struct stliport __user *arg); +static int stli_getbrdstruct(struct stlibrd __user *arg); +static struct stlibrd *stli_allocbrd(void); + +static void stli_ecpinit(struct stlibrd *brdp); +static void stli_ecpenable(struct stlibrd *brdp); +static void stli_ecpdisable(struct stlibrd *brdp); +static void __iomem *stli_ecpgetmemptr(struct stlibrd *brdp, unsigned long offset, int line); +static void stli_ecpreset(struct stlibrd *brdp); +static void stli_ecpintr(struct stlibrd *brdp); +static void stli_ecpeiinit(struct stlibrd *brdp); +static void stli_ecpeienable(struct stlibrd *brdp); +static void stli_ecpeidisable(struct stlibrd *brdp); +static void __iomem *stli_ecpeigetmemptr(struct stlibrd *brdp, unsigned long offset, int line); +static void stli_ecpeireset(struct stlibrd *brdp); +static void stli_ecpmcenable(struct stlibrd *brdp); +static void stli_ecpmcdisable(struct stlibrd *brdp); +static void __iomem *stli_ecpmcgetmemptr(struct stlibrd *brdp, unsigned long offset, int line); +static void stli_ecpmcreset(struct stlibrd *brdp); +static void stli_ecppciinit(struct stlibrd *brdp); +static void __iomem *stli_ecppcigetmemptr(struct stlibrd *brdp, unsigned long offset, int line); +static void stli_ecppcireset(struct stlibrd *brdp); + +static void stli_onbinit(struct stlibrd *brdp); +static void stli_onbenable(struct stlibrd *brdp); +static void stli_onbdisable(struct stlibrd *brdp); +static void __iomem *stli_onbgetmemptr(struct stlibrd *brdp, unsigned long offset, int line); +static void stli_onbreset(struct stlibrd *brdp); +static void stli_onbeinit(struct stlibrd *brdp); +static void stli_onbeenable(struct stlibrd *brdp); +static void stli_onbedisable(struct stlibrd *brdp); +static void __iomem *stli_onbegetmemptr(struct stlibrd *brdp, unsigned long offset, int line); +static void stli_onbereset(struct stlibrd *brdp); +static void stli_bbyinit(struct stlibrd *brdp); +static void __iomem *stli_bbygetmemptr(struct stlibrd *brdp, unsigned long offset, int line); +static void stli_bbyreset(struct stlibrd *brdp); +static void stli_stalinit(struct stlibrd *brdp); +static void __iomem *stli_stalgetmemptr(struct stlibrd *brdp, unsigned long offset, int line); +static void stli_stalreset(struct stlibrd *brdp); + +static struct stliport *stli_getport(unsigned int brdnr, unsigned int panelnr, unsigned int portnr); + +static int stli_initecp(struct stlibrd *brdp); +static int stli_initonb(struct stlibrd *brdp); +#if STLI_EISAPROBE != 0 +static int stli_eisamemprobe(struct stlibrd *brdp); +#endif +static int stli_initports(struct stlibrd *brdp); + +/*****************************************************************************/ + +/* + * Define the driver info for a user level shared memory device. This + * device will work sort of like the /dev/kmem device - except that it + * will give access to the shared memory on the Stallion intelligent + * board. This is also a very useful debugging tool. + */ +static const struct file_operations stli_fsiomem = { + .owner = THIS_MODULE, + .read = stli_memread, + .write = stli_memwrite, + .unlocked_ioctl = stli_memioctl, + .llseek = default_llseek, +}; + +/*****************************************************************************/ + +/* + * Define a timer_list entry for our poll routine. The slave board + * is polled every so often to see if anything needs doing. This is + * much cheaper on host cpu than using interrupts. It turns out to + * not increase character latency by much either... + */ +static DEFINE_TIMER(stli_timerlist, stli_poll, 0, 0); + +static int stli_timeron; + +/* + * Define the calculation for the timeout routine. + */ +#define STLI_TIMEOUT (jiffies + 1) + +/*****************************************************************************/ + +static struct class *istallion_class; + +static void stli_cleanup_ports(struct stlibrd *brdp) +{ + struct stliport *portp; + unsigned int j; + struct tty_struct *tty; + + for (j = 0; j < STL_MAXPORTS; j++) { + portp = brdp->ports[j]; + if (portp != NULL) { + tty = tty_port_tty_get(&portp->port); + if (tty != NULL) { + tty_hangup(tty); + tty_kref_put(tty); + } + kfree(portp); + } + } +} + +/*****************************************************************************/ + +/* + * Parse the supplied argument string, into the board conf struct. + */ + +static int stli_parsebrd(struct stlconf *confp, char **argp) +{ + unsigned int i; + char *sp; + + if (argp[0] == NULL || *argp[0] == 0) + return 0; + + for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++) + *sp = tolower(*sp); + + for (i = 0; i < ARRAY_SIZE(stli_brdstr); i++) { + if (strcmp(stli_brdstr[i].name, argp[0]) == 0) + break; + } + if (i == ARRAY_SIZE(stli_brdstr)) { + printk(KERN_WARNING "istallion: unknown board name, %s?\n", argp[0]); + return 0; + } + + confp->brdtype = stli_brdstr[i].type; + if (argp[1] != NULL && *argp[1] != 0) + confp->ioaddr1 = simple_strtoul(argp[1], NULL, 0); + if (argp[2] != NULL && *argp[2] != 0) + confp->memaddr = simple_strtoul(argp[2], NULL, 0); + return(1); +} + +/*****************************************************************************/ + +/* + * On the first open of the device setup the port hardware, and + * initialize the per port data structure. Since initializing the port + * requires several commands to the board we will need to wait for any + * other open that is already initializing the port. + * + * Locking: protected by the port mutex. + */ + +static int stli_activate(struct tty_port *port, struct tty_struct *tty) +{ + struct stliport *portp = container_of(port, struct stliport, port); + struct stlibrd *brdp = stli_brds[portp->brdnr]; + int rc; + + if ((rc = stli_initopen(tty, brdp, portp)) >= 0) + clear_bit(TTY_IO_ERROR, &tty->flags); + wake_up_interruptible(&portp->raw_wait); + return rc; +} + +static int stli_open(struct tty_struct *tty, struct file *filp) +{ + struct stlibrd *brdp; + struct stliport *portp; + unsigned int minordev, brdnr, portnr; + + minordev = tty->index; + brdnr = MINOR2BRD(minordev); + if (brdnr >= stli_nrbrds) + return -ENODEV; + brdp = stli_brds[brdnr]; + if (brdp == NULL) + return -ENODEV; + if (!test_bit(BST_STARTED, &brdp->state)) + return -ENODEV; + portnr = MINOR2PORT(minordev); + if (portnr > brdp->nrports) + return -ENODEV; + + portp = brdp->ports[portnr]; + if (portp == NULL) + return -ENODEV; + if (portp->devnr < 1) + return -ENODEV; + + tty->driver_data = portp; + return tty_port_open(&portp->port, tty, filp); +} + + +/*****************************************************************************/ + +static void stli_shutdown(struct tty_port *port) +{ + struct stlibrd *brdp; + unsigned long ftype; + unsigned long flags; + struct stliport *portp = container_of(port, struct stliport, port); + + if (portp->brdnr >= stli_nrbrds) + return; + brdp = stli_brds[portp->brdnr]; + if (brdp == NULL) + return; + + /* + * May want to wait for data to drain before closing. The BUSY + * flag keeps track of whether we are still transmitting or not. + * It is updated by messages from the slave - indicating when all + * chars really have drained. + */ + + if (!test_bit(ST_CLOSING, &portp->state)) + stli_rawclose(brdp, portp, 0, 0); + + spin_lock_irqsave(&stli_lock, flags); + clear_bit(ST_TXBUSY, &portp->state); + clear_bit(ST_RXSTOP, &portp->state); + spin_unlock_irqrestore(&stli_lock, flags); + + ftype = FLUSHTX | FLUSHRX; + stli_cmdwait(brdp, portp, A_FLUSH, &ftype, sizeof(u32), 0); +} + +static void stli_close(struct tty_struct *tty, struct file *filp) +{ + struct stliport *portp = tty->driver_data; + unsigned long flags; + if (portp == NULL) + return; + spin_lock_irqsave(&stli_lock, flags); + /* Flush any internal buffering out first */ + if (tty == stli_txcooktty) + stli_flushchars(tty); + spin_unlock_irqrestore(&stli_lock, flags); + tty_port_close(&portp->port, tty, filp); +} + +/*****************************************************************************/ + +/* + * Carry out first open operations on a port. This involves a number of + * commands to be sent to the slave. We need to open the port, set the + * notification events, set the initial port settings, get and set the + * initial signal values. We sleep and wait in between each one. But + * this still all happens pretty quickly. + */ + +static int stli_initopen(struct tty_struct *tty, + struct stlibrd *brdp, struct stliport *portp) +{ + asynotify_t nt; + asyport_t aport; + int rc; + + if ((rc = stli_rawopen(brdp, portp, 0, 1)) < 0) + return rc; + + memset(&nt, 0, sizeof(asynotify_t)); + nt.data = (DT_TXLOW | DT_TXEMPTY | DT_RXBUSY | DT_RXBREAK); + nt.signal = SG_DCD; + if ((rc = stli_cmdwait(brdp, portp, A_SETNOTIFY, &nt, + sizeof(asynotify_t), 0)) < 0) + return rc; + + stli_mkasyport(tty, portp, &aport, tty->termios); + if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport, + sizeof(asyport_t), 0)) < 0) + return rc; + + set_bit(ST_GETSIGS, &portp->state); + if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig, + sizeof(asysigs_t), 1)) < 0) + return rc; + if (test_and_clear_bit(ST_GETSIGS, &portp->state)) + portp->sigs = stli_mktiocm(portp->asig.sigvalue); + stli_mkasysigs(&portp->asig, 1, 1); + if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, + sizeof(asysigs_t), 0)) < 0) + return rc; + + return 0; +} + +/*****************************************************************************/ + +/* + * Send an open message to the slave. This will sleep waiting for the + * acknowledgement, so must have user context. We need to co-ordinate + * with close events here, since we don't want open and close events + * to overlap. + */ + +static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait) +{ + cdkhdr_t __iomem *hdrp; + cdkctrl_t __iomem *cp; + unsigned char __iomem *bits; + unsigned long flags; + int rc; + +/* + * Send a message to the slave to open this port. + */ + +/* + * Slave is already closing this port. This can happen if a hangup + * occurs on this port. So we must wait until it is complete. The + * order of opens and closes may not be preserved across shared + * memory, so we must wait until it is complete. + */ + wait_event_interruptible_tty(portp->raw_wait, + !test_bit(ST_CLOSING, &portp->state)); + if (signal_pending(current)) { + return -ERESTARTSYS; + } + +/* + * Everything is ready now, so write the open message into shared + * memory. Once the message is in set the service bits to say that + * this port wants service. + */ + spin_lock_irqsave(&brd_lock, flags); + EBRDENABLE(brdp); + cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; + writel(arg, &cp->openarg); + writeb(1, &cp->open); + hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + + portp->portidx; + writeb(readb(bits) | portp->portbit, bits); + EBRDDISABLE(brdp); + + if (wait == 0) { + spin_unlock_irqrestore(&brd_lock, flags); + return 0; + } + +/* + * Slave is in action, so now we must wait for the open acknowledgment + * to come back. + */ + rc = 0; + set_bit(ST_OPENING, &portp->state); + spin_unlock_irqrestore(&brd_lock, flags); + + wait_event_interruptible_tty(portp->raw_wait, + !test_bit(ST_OPENING, &portp->state)); + if (signal_pending(current)) + rc = -ERESTARTSYS; + + if ((rc == 0) && (portp->rc != 0)) + rc = -EIO; + return rc; +} + +/*****************************************************************************/ + +/* + * Send a close message to the slave. Normally this will sleep waiting + * for the acknowledgement, but if wait parameter is 0 it will not. If + * wait is true then must have user context (to sleep). + */ + +static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait) +{ + cdkhdr_t __iomem *hdrp; + cdkctrl_t __iomem *cp; + unsigned char __iomem *bits; + unsigned long flags; + int rc; + +/* + * Slave is already closing this port. This can happen if a hangup + * occurs on this port. + */ + if (wait) { + wait_event_interruptible_tty(portp->raw_wait, + !test_bit(ST_CLOSING, &portp->state)); + if (signal_pending(current)) { + return -ERESTARTSYS; + } + } + +/* + * Write the close command into shared memory. + */ + spin_lock_irqsave(&brd_lock, flags); + EBRDENABLE(brdp); + cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; + writel(arg, &cp->closearg); + writeb(1, &cp->close); + hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + + portp->portidx; + writeb(readb(bits) |portp->portbit, bits); + EBRDDISABLE(brdp); + + set_bit(ST_CLOSING, &portp->state); + spin_unlock_irqrestore(&brd_lock, flags); + + if (wait == 0) + return 0; + +/* + * Slave is in action, so now we must wait for the open acknowledgment + * to come back. + */ + rc = 0; + wait_event_interruptible_tty(portp->raw_wait, + !test_bit(ST_CLOSING, &portp->state)); + if (signal_pending(current)) + rc = -ERESTARTSYS; + + if ((rc == 0) && (portp->rc != 0)) + rc = -EIO; + return rc; +} + +/*****************************************************************************/ + +/* + * Send a command to the slave and wait for the response. This must + * have user context (it sleeps). This routine is generic in that it + * can send any type of command. Its purpose is to wait for that command + * to complete (as opposed to initiating the command then returning). + */ + +static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback) +{ + /* + * no need for wait_event_tty because clearing ST_CMDING cannot block + * on BTM + */ + wait_event_interruptible(portp->raw_wait, + !test_bit(ST_CMDING, &portp->state)); + if (signal_pending(current)) + return -ERESTARTSYS; + + stli_sendcmd(brdp, portp, cmd, arg, size, copyback); + + wait_event_interruptible(portp->raw_wait, + !test_bit(ST_CMDING, &portp->state)); + if (signal_pending(current)) + return -ERESTARTSYS; + + if (portp->rc != 0) + return -EIO; + return 0; +} + +/*****************************************************************************/ + +/* + * Send the termios settings for this port to the slave. This sleeps + * waiting for the command to complete - so must have user context. + */ + +static int stli_setport(struct tty_struct *tty) +{ + struct stliport *portp = tty->driver_data; + struct stlibrd *brdp; + asyport_t aport; + + if (portp == NULL) + return -ENODEV; + if (portp->brdnr >= stli_nrbrds) + return -ENODEV; + brdp = stli_brds[portp->brdnr]; + if (brdp == NULL) + return -ENODEV; + + stli_mkasyport(tty, portp, &aport, tty->termios); + return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)); +} + +/*****************************************************************************/ + +static int stli_carrier_raised(struct tty_port *port) +{ + struct stliport *portp = container_of(port, struct stliport, port); + return (portp->sigs & TIOCM_CD) ? 1 : 0; +} + +static void stli_dtr_rts(struct tty_port *port, int on) +{ + struct stliport *portp = container_of(port, struct stliport, port); + struct stlibrd *brdp = stli_brds[portp->brdnr]; + stli_mkasysigs(&portp->asig, on, on); + if (stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, + sizeof(asysigs_t), 0) < 0) + printk(KERN_WARNING "istallion: dtr set failed.\n"); +} + + +/*****************************************************************************/ + +/* + * Write routine. Take the data and put it in the shared memory ring + * queue. If port is not already sending chars then need to mark the + * service bits for this port. + */ + +static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count) +{ + cdkasy_t __iomem *ap; + cdkhdr_t __iomem *hdrp; + unsigned char __iomem *bits; + unsigned char __iomem *shbuf; + unsigned char *chbuf; + struct stliport *portp; + struct stlibrd *brdp; + unsigned int len, stlen, head, tail, size; + unsigned long flags; + + if (tty == stli_txcooktty) + stli_flushchars(tty); + portp = tty->driver_data; + if (portp == NULL) + return 0; + if (portp->brdnr >= stli_nrbrds) + return 0; + brdp = stli_brds[portp->brdnr]; + if (brdp == NULL) + return 0; + chbuf = (unsigned char *) buf; + +/* + * All data is now local, shove as much as possible into shared memory. + */ + spin_lock_irqsave(&brd_lock, flags); + EBRDENABLE(brdp); + ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); + head = (unsigned int) readw(&ap->txq.head); + tail = (unsigned int) readw(&ap->txq.tail); + if (tail != ((unsigned int) readw(&ap->txq.tail))) + tail = (unsigned int) readw(&ap->txq.tail); + size = portp->txsize; + if (head >= tail) { + len = size - (head - tail) - 1; + stlen = size - head; + } else { + len = tail - head - 1; + stlen = len; + } + + len = min(len, (unsigned int)count); + count = 0; + shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->txoffset); + + while (len > 0) { + stlen = min(len, stlen); + memcpy_toio(shbuf + head, chbuf, stlen); + chbuf += stlen; + len -= stlen; + count += stlen; + head += stlen; + if (head >= size) { + head = 0; + stlen = tail; + } + } + + ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); + writew(head, &ap->txq.head); + if (test_bit(ST_TXBUSY, &portp->state)) { + if (readl(&ap->changed.data) & DT_TXEMPTY) + writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data); + } + hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + + portp->portidx; + writeb(readb(bits) | portp->portbit, bits); + set_bit(ST_TXBUSY, &portp->state); + EBRDDISABLE(brdp); + spin_unlock_irqrestore(&brd_lock, flags); + + return(count); +} + +/*****************************************************************************/ + +/* + * Output a single character. We put it into a temporary local buffer + * (for speed) then write out that buffer when the flushchars routine + * is called. There is a safety catch here so that if some other port + * writes chars before the current buffer has been, then we write them + * first them do the new ports. + */ + +static int stli_putchar(struct tty_struct *tty, unsigned char ch) +{ + if (tty != stli_txcooktty) { + if (stli_txcooktty != NULL) + stli_flushchars(stli_txcooktty); + stli_txcooktty = tty; + } + + stli_txcookbuf[stli_txcooksize++] = ch; + return 0; +} + +/*****************************************************************************/ + +/* + * Transfer characters from the local TX cooking buffer to the board. + * We sort of ignore the tty that gets passed in here. We rely on the + * info stored with the TX cook buffer to tell us which port to flush + * the data on. In any case we clean out the TX cook buffer, for re-use + * by someone else. + */ + +static void stli_flushchars(struct tty_struct *tty) +{ + cdkhdr_t __iomem *hdrp; + unsigned char __iomem *bits; + cdkasy_t __iomem *ap; + struct tty_struct *cooktty; + struct stliport *portp; + struct stlibrd *brdp; + unsigned int len, stlen, head, tail, size, count, cooksize; + unsigned char *buf; + unsigned char __iomem *shbuf; + unsigned long flags; + + cooksize = stli_txcooksize; + cooktty = stli_txcooktty; + stli_txcooksize = 0; + stli_txcookrealsize = 0; + stli_txcooktty = NULL; + + if (cooktty == NULL) + return; + if (tty != cooktty) + tty = cooktty; + if (cooksize == 0) + return; + + portp = tty->driver_data; + if (portp == NULL) + return; + if (portp->brdnr >= stli_nrbrds) + return; + brdp = stli_brds[portp->brdnr]; + if (brdp == NULL) + return; + + spin_lock_irqsave(&brd_lock, flags); + EBRDENABLE(brdp); + + ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); + head = (unsigned int) readw(&ap->txq.head); + tail = (unsigned int) readw(&ap->txq.tail); + if (tail != ((unsigned int) readw(&ap->txq.tail))) + tail = (unsigned int) readw(&ap->txq.tail); + size = portp->txsize; + if (head >= tail) { + len = size - (head - tail) - 1; + stlen = size - head; + } else { + len = tail - head - 1; + stlen = len; + } + + len = min(len, cooksize); + count = 0; + shbuf = EBRDGETMEMPTR(brdp, portp->txoffset); + buf = stli_txcookbuf; + + while (len > 0) { + stlen = min(len, stlen); + memcpy_toio(shbuf + head, buf, stlen); + buf += stlen; + len -= stlen; + count += stlen; + head += stlen; + if (head >= size) { + head = 0; + stlen = tail; + } + } + + ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); + writew(head, &ap->txq.head); + + if (test_bit(ST_TXBUSY, &portp->state)) { + if (readl(&ap->changed.data) & DT_TXEMPTY) + writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data); + } + hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + + portp->portidx; + writeb(readb(bits) | portp->portbit, bits); + set_bit(ST_TXBUSY, &portp->state); + + EBRDDISABLE(brdp); + spin_unlock_irqrestore(&brd_lock, flags); +} + +/*****************************************************************************/ + +static int stli_writeroom(struct tty_struct *tty) +{ + cdkasyrq_t __iomem *rp; + struct stliport *portp; + struct stlibrd *brdp; + unsigned int head, tail, len; + unsigned long flags; + + if (tty == stli_txcooktty) { + if (stli_txcookrealsize != 0) { + len = stli_txcookrealsize - stli_txcooksize; + return len; + } + } + + portp = tty->driver_data; + if (portp == NULL) + return 0; + if (portp->brdnr >= stli_nrbrds) + return 0; + brdp = stli_brds[portp->brdnr]; + if (brdp == NULL) + return 0; + + spin_lock_irqsave(&brd_lock, flags); + EBRDENABLE(brdp); + rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq; + head = (unsigned int) readw(&rp->head); + tail = (unsigned int) readw(&rp->tail); + if (tail != ((unsigned int) readw(&rp->tail))) + tail = (unsigned int) readw(&rp->tail); + len = (head >= tail) ? (portp->txsize - (head - tail)) : (tail - head); + len--; + EBRDDISABLE(brdp); + spin_unlock_irqrestore(&brd_lock, flags); + + if (tty == stli_txcooktty) { + stli_txcookrealsize = len; + len -= stli_txcooksize; + } + return len; +} + +/*****************************************************************************/ + +/* + * Return the number of characters in the transmit buffer. Normally we + * will return the number of chars in the shared memory ring queue. + * We need to kludge around the case where the shared memory buffer is + * empty but not all characters have drained yet, for this case just + * return that there is 1 character in the buffer! + */ + +static int stli_charsinbuffer(struct tty_struct *tty) +{ + cdkasyrq_t __iomem *rp; + struct stliport *portp; + struct stlibrd *brdp; + unsigned int head, tail, len; + unsigned long flags; + + if (tty == stli_txcooktty) + stli_flushchars(tty); + portp = tty->driver_data; + if (portp == NULL) + return 0; + if (portp->brdnr >= stli_nrbrds) + return 0; + brdp = stli_brds[portp->brdnr]; + if (brdp == NULL) + return 0; + + spin_lock_irqsave(&brd_lock, flags); + EBRDENABLE(brdp); + rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq; + head = (unsigned int) readw(&rp->head); + tail = (unsigned int) readw(&rp->tail); + if (tail != ((unsigned int) readw(&rp->tail))) + tail = (unsigned int) readw(&rp->tail); + len = (head >= tail) ? (head - tail) : (portp->txsize - (tail - head)); + if ((len == 0) && test_bit(ST_TXBUSY, &portp->state)) + len = 1; + EBRDDISABLE(brdp); + spin_unlock_irqrestore(&brd_lock, flags); + + return len; +} + +/*****************************************************************************/ + +/* + * Generate the serial struct info. + */ + +static int stli_getserial(struct stliport *portp, struct serial_struct __user *sp) +{ + struct serial_struct sio; + struct stlibrd *brdp; + + memset(&sio, 0, sizeof(struct serial_struct)); + sio.type = PORT_UNKNOWN; + sio.line = portp->portnr; + sio.irq = 0; + sio.flags = portp->port.flags; + sio.baud_base = portp->baud_base; + sio.close_delay = portp->port.close_delay; + sio.closing_wait = portp->closing_wait; + sio.custom_divisor = portp->custom_divisor; + sio.xmit_fifo_size = 0; + sio.hub6 = 0; + + brdp = stli_brds[portp->brdnr]; + if (brdp != NULL) + sio.port = brdp->iobase; + + return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? + -EFAULT : 0; +} + +/*****************************************************************************/ + +/* + * Set port according to the serial struct info. + * At this point we do not do any auto-configure stuff, so we will + * just quietly ignore any requests to change irq, etc. + */ + +static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *sp) +{ + struct serial_struct sio; + int rc; + struct stliport *portp = tty->driver_data; + + if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) + return -EFAULT; + if (!capable(CAP_SYS_ADMIN)) { + if ((sio.baud_base != portp->baud_base) || + (sio.close_delay != portp->port.close_delay) || + ((sio.flags & ~ASYNC_USR_MASK) != + (portp->port.flags & ~ASYNC_USR_MASK))) + return -EPERM; + } + + portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) | + (sio.flags & ASYNC_USR_MASK); + portp->baud_base = sio.baud_base; + portp->port.close_delay = sio.close_delay; + portp->closing_wait = sio.closing_wait; + portp->custom_divisor = sio.custom_divisor; + + if ((rc = stli_setport(tty)) < 0) + return rc; + return 0; +} + +/*****************************************************************************/ + +static int stli_tiocmget(struct tty_struct *tty) +{ + struct stliport *portp = tty->driver_data; + struct stlibrd *brdp; + int rc; + + if (portp == NULL) + return -ENODEV; + if (portp->brdnr >= stli_nrbrds) + return 0; + brdp = stli_brds[portp->brdnr]; + if (brdp == NULL) + return 0; + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + + if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, + &portp->asig, sizeof(asysigs_t), 1)) < 0) + return rc; + + return stli_mktiocm(portp->asig.sigvalue); +} + +static int stli_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + struct stliport *portp = tty->driver_data; + struct stlibrd *brdp; + int rts = -1, dtr = -1; + + if (portp == NULL) + return -ENODEV; + if (portp->brdnr >= stli_nrbrds) + return 0; + brdp = stli_brds[portp->brdnr]; + if (brdp == NULL) + return 0; + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + + if (set & TIOCM_RTS) + rts = 1; + if (set & TIOCM_DTR) + dtr = 1; + if (clear & TIOCM_RTS) + rts = 0; + if (clear & TIOCM_DTR) + dtr = 0; + + stli_mkasysigs(&portp->asig, dtr, rts); + + return stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, + sizeof(asysigs_t), 0); +} + +static int stli_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) +{ + struct stliport *portp; + struct stlibrd *brdp; + int rc; + void __user *argp = (void __user *)arg; + + portp = tty->driver_data; + if (portp == NULL) + return -ENODEV; + if (portp->brdnr >= stli_nrbrds) + return 0; + brdp = stli_brds[portp->brdnr]; + if (brdp == NULL) + return 0; + + if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && + (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) { + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + } + + rc = 0; + + switch (cmd) { + case TIOCGSERIAL: + rc = stli_getserial(portp, argp); + break; + case TIOCSSERIAL: + rc = stli_setserial(tty, argp); + break; + case STL_GETPFLAG: + rc = put_user(portp->pflag, (unsigned __user *)argp); + break; + case STL_SETPFLAG: + if ((rc = get_user(portp->pflag, (unsigned __user *)argp)) == 0) + stli_setport(tty); + break; + case COM_GETPORTSTATS: + rc = stli_getportstats(tty, portp, argp); + break; + case COM_CLRPORTSTATS: + rc = stli_clrportstats(portp, argp); + break; + case TIOCSERCONFIG: + case TIOCSERGWILD: + case TIOCSERSWILD: + case TIOCSERGETLSR: + case TIOCSERGSTRUCT: + case TIOCSERGETMULTI: + case TIOCSERSETMULTI: + default: + rc = -ENOIOCTLCMD; + break; + } + + return rc; +} + +/*****************************************************************************/ + +/* + * This routine assumes that we have user context and can sleep. + * Looks like it is true for the current ttys implementation..!! + */ + +static void stli_settermios(struct tty_struct *tty, struct ktermios *old) +{ + struct stliport *portp; + struct stlibrd *brdp; + struct ktermios *tiosp; + asyport_t aport; + + portp = tty->driver_data; + if (portp == NULL) + return; + if (portp->brdnr >= stli_nrbrds) + return; + brdp = stli_brds[portp->brdnr]; + if (brdp == NULL) + return; + + tiosp = tty->termios; + + stli_mkasyport(tty, portp, &aport, tiosp); + stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0); + stli_mkasysigs(&portp->asig, ((tiosp->c_cflag & CBAUD) ? 1 : 0), -1); + stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, + sizeof(asysigs_t), 0); + if ((old->c_cflag & CRTSCTS) && ((tiosp->c_cflag & CRTSCTS) == 0)) + tty->hw_stopped = 0; + if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL)) + wake_up_interruptible(&portp->port.open_wait); +} + +/*****************************************************************************/ + +/* + * Attempt to flow control who ever is sending us data. We won't really + * do any flow control action here. We can't directly, and even if we + * wanted to we would have to send a command to the slave. The slave + * knows how to flow control, and will do so when its buffers reach its + * internal high water marks. So what we will do is set a local state + * bit that will stop us sending any RX data up from the poll routine + * (which is the place where RX data from the slave is handled). + */ + +static void stli_throttle(struct tty_struct *tty) +{ + struct stliport *portp = tty->driver_data; + if (portp == NULL) + return; + set_bit(ST_RXSTOP, &portp->state); +} + +/*****************************************************************************/ + +/* + * Unflow control the device sending us data... That means that all + * we have to do is clear the RXSTOP state bit. The next poll call + * will then be able to pass the RX data back up. + */ + +static void stli_unthrottle(struct tty_struct *tty) +{ + struct stliport *portp = tty->driver_data; + if (portp == NULL) + return; + clear_bit(ST_RXSTOP, &portp->state); +} + +/*****************************************************************************/ + +/* + * Stop the transmitter. + */ + +static void stli_stop(struct tty_struct *tty) +{ +} + +/*****************************************************************************/ + +/* + * Start the transmitter again. + */ + +static void stli_start(struct tty_struct *tty) +{ +} + +/*****************************************************************************/ + + +/* + * Hangup this port. This is pretty much like closing the port, only + * a little more brutal. No waiting for data to drain. Shutdown the + * port and maybe drop signals. This is rather tricky really. We want + * to close the port as well. + */ + +static void stli_hangup(struct tty_struct *tty) +{ + struct stliport *portp = tty->driver_data; + tty_port_hangup(&portp->port); +} + +/*****************************************************************************/ + +/* + * Flush characters from the lower buffer. We may not have user context + * so we cannot sleep waiting for it to complete. Also we need to check + * if there is chars for this port in the TX cook buffer, and flush them + * as well. + */ + +static void stli_flushbuffer(struct tty_struct *tty) +{ + struct stliport *portp; + struct stlibrd *brdp; + unsigned long ftype, flags; + + portp = tty->driver_data; + if (portp == NULL) + return; + if (portp->brdnr >= stli_nrbrds) + return; + brdp = stli_brds[portp->brdnr]; + if (brdp == NULL) + return; + + spin_lock_irqsave(&brd_lock, flags); + if (tty == stli_txcooktty) { + stli_txcooktty = NULL; + stli_txcooksize = 0; + stli_txcookrealsize = 0; + } + if (test_bit(ST_CMDING, &portp->state)) { + set_bit(ST_DOFLUSHTX, &portp->state); + } else { + ftype = FLUSHTX; + if (test_bit(ST_DOFLUSHRX, &portp->state)) { + ftype |= FLUSHRX; + clear_bit(ST_DOFLUSHRX, &portp->state); + } + __stli_sendcmd(brdp, portp, A_FLUSH, &ftype, sizeof(u32), 0); + } + spin_unlock_irqrestore(&brd_lock, flags); + tty_wakeup(tty); +} + +/*****************************************************************************/ + +static int stli_breakctl(struct tty_struct *tty, int state) +{ + struct stlibrd *brdp; + struct stliport *portp; + long arg; + + portp = tty->driver_data; + if (portp == NULL) + return -EINVAL; + if (portp->brdnr >= stli_nrbrds) + return -EINVAL; + brdp = stli_brds[portp->brdnr]; + if (brdp == NULL) + return -EINVAL; + + arg = (state == -1) ? BREAKON : BREAKOFF; + stli_cmdwait(brdp, portp, A_BREAK, &arg, sizeof(long), 0); + return 0; +} + +/*****************************************************************************/ + +static void stli_waituntilsent(struct tty_struct *tty, int timeout) +{ + struct stliport *portp; + unsigned long tend; + + portp = tty->driver_data; + if (portp == NULL) + return; + + if (timeout == 0) + timeout = HZ; + tend = jiffies + timeout; + + while (test_bit(ST_TXBUSY, &portp->state)) { + if (signal_pending(current)) + break; + msleep_interruptible(20); + if (time_after_eq(jiffies, tend)) + break; + } +} + +/*****************************************************************************/ + +static void stli_sendxchar(struct tty_struct *tty, char ch) +{ + struct stlibrd *brdp; + struct stliport *portp; + asyctrl_t actrl; + + portp = tty->driver_data; + if (portp == NULL) + return; + if (portp->brdnr >= stli_nrbrds) + return; + brdp = stli_brds[portp->brdnr]; + if (brdp == NULL) + return; + + memset(&actrl, 0, sizeof(asyctrl_t)); + if (ch == STOP_CHAR(tty)) { + actrl.rxctrl = CT_STOPFLOW; + } else if (ch == START_CHAR(tty)) { + actrl.rxctrl = CT_STARTFLOW; + } else { + actrl.txctrl = CT_SENDCHR; + actrl.tximdch = ch; + } + stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0); +} + +static void stli_portinfo(struct seq_file *m, struct stlibrd *brdp, struct stliport *portp, int portnr) +{ + char *uart; + int rc; + + rc = stli_portcmdstats(NULL, portp); + + uart = "UNKNOWN"; + if (test_bit(BST_STARTED, &brdp->state)) { + switch (stli_comstats.hwid) { + case 0: uart = "2681"; break; + case 1: uart = "SC26198"; break; + default:uart = "CD1400"; break; + } + } + seq_printf(m, "%d: uart:%s ", portnr, uart); + + if (test_bit(BST_STARTED, &brdp->state) && rc >= 0) { + char sep; + + seq_printf(m, "tx:%d rx:%d", (int) stli_comstats.txtotal, + (int) stli_comstats.rxtotal); + + if (stli_comstats.rxframing) + seq_printf(m, " fe:%d", + (int) stli_comstats.rxframing); + if (stli_comstats.rxparity) + seq_printf(m, " pe:%d", + (int) stli_comstats.rxparity); + if (stli_comstats.rxbreaks) + seq_printf(m, " brk:%d", + (int) stli_comstats.rxbreaks); + if (stli_comstats.rxoverrun) + seq_printf(m, " oe:%d", + (int) stli_comstats.rxoverrun); + + sep = ' '; + if (stli_comstats.signals & TIOCM_RTS) { + seq_printf(m, "%c%s", sep, "RTS"); + sep = '|'; + } + if (stli_comstats.signals & TIOCM_CTS) { + seq_printf(m, "%c%s", sep, "CTS"); + sep = '|'; + } + if (stli_comstats.signals & TIOCM_DTR) { + seq_printf(m, "%c%s", sep, "DTR"); + sep = '|'; + } + if (stli_comstats.signals & TIOCM_CD) { + seq_printf(m, "%c%s", sep, "DCD"); + sep = '|'; + } + if (stli_comstats.signals & TIOCM_DSR) { + seq_printf(m, "%c%s", sep, "DSR"); + sep = '|'; + } + } + seq_putc(m, '\n'); +} + +/*****************************************************************************/ + +/* + * Port info, read from the /proc file system. + */ + +static int stli_proc_show(struct seq_file *m, void *v) +{ + struct stlibrd *brdp; + struct stliport *portp; + unsigned int brdnr, portnr, totalport; + + totalport = 0; + + seq_printf(m, "%s: version %s\n", stli_drvtitle, stli_drvversion); + +/* + * We scan through for each board, panel and port. The offset is + * calculated on the fly, and irrelevant ports are skipped. + */ + for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) { + brdp = stli_brds[brdnr]; + if (brdp == NULL) + continue; + if (brdp->state == 0) + continue; + + totalport = brdnr * STL_MAXPORTS; + for (portnr = 0; (portnr < brdp->nrports); portnr++, + totalport++) { + portp = brdp->ports[portnr]; + if (portp == NULL) + continue; + stli_portinfo(m, brdp, portp, totalport); + } + } + return 0; +} + +static int stli_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, stli_proc_show, NULL); +} + +static const struct file_operations stli_proc_fops = { + .owner = THIS_MODULE, + .open = stli_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/*****************************************************************************/ + +/* + * Generic send command routine. This will send a message to the slave, + * of the specified type with the specified argument. Must be very + * careful of data that will be copied out from shared memory - + * containing command results. The command completion is all done from + * a poll routine that does not have user context. Therefore you cannot + * copy back directly into user space, or to the kernel stack of a + * process. This routine does not sleep, so can be called from anywhere. + * + * The caller must hold the brd_lock (see also stli_sendcmd the usual + * entry point) + */ + +static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback) +{ + cdkhdr_t __iomem *hdrp; + cdkctrl_t __iomem *cp; + unsigned char __iomem *bits; + + if (test_bit(ST_CMDING, &portp->state)) { + printk(KERN_ERR "istallion: command already busy, cmd=%x!\n", + (int) cmd); + return; + } + + EBRDENABLE(brdp); + cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; + if (size > 0) { + memcpy_toio((void __iomem *) &(cp->args[0]), arg, size); + if (copyback) { + portp->argp = arg; + portp->argsize = size; + } + } + writel(0, &cp->status); + writel(cmd, &cp->cmd); + hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + + portp->portidx; + writeb(readb(bits) | portp->portbit, bits); + set_bit(ST_CMDING, &portp->state); + EBRDDISABLE(brdp); +} + +static void stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback) +{ + unsigned long flags; + + spin_lock_irqsave(&brd_lock, flags); + __stli_sendcmd(brdp, portp, cmd, arg, size, copyback); + spin_unlock_irqrestore(&brd_lock, flags); +} + +/*****************************************************************************/ + +/* + * Read data from shared memory. This assumes that the shared memory + * is enabled and that interrupts are off. Basically we just empty out + * the shared memory buffer into the tty buffer. Must be careful to + * handle the case where we fill up the tty buffer, but still have + * more chars to unload. + */ + +static void stli_read(struct stlibrd *brdp, struct stliport *portp) +{ + cdkasyrq_t __iomem *rp; + char __iomem *shbuf; + struct tty_struct *tty; + unsigned int head, tail, size; + unsigned int len, stlen; + + if (test_bit(ST_RXSTOP, &portp->state)) + return; + tty = tty_port_tty_get(&portp->port); + if (tty == NULL) + return; + + rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq; + head = (unsigned int) readw(&rp->head); + if (head != ((unsigned int) readw(&rp->head))) + head = (unsigned int) readw(&rp->head); + tail = (unsigned int) readw(&rp->tail); + size = portp->rxsize; + if (head >= tail) { + len = head - tail; + stlen = len; + } else { + len = size - (tail - head); + stlen = size - tail; + } + + len = tty_buffer_request_room(tty, len); + + shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->rxoffset); + + while (len > 0) { + unsigned char *cptr; + + stlen = min(len, stlen); + tty_prepare_flip_string(tty, &cptr, stlen); + memcpy_fromio(cptr, shbuf + tail, stlen); + len -= stlen; + tail += stlen; + if (tail >= size) { + tail = 0; + stlen = head; + } + } + rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq; + writew(tail, &rp->tail); + + if (head != tail) + set_bit(ST_RXING, &portp->state); + + tty_schedule_flip(tty); + tty_kref_put(tty); +} + +/*****************************************************************************/ + +/* + * Set up and carry out any delayed commands. There is only a small set + * of slave commands that can be done "off-level". So it is not too + * difficult to deal with them here. + */ + +static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp) +{ + int cmd; + + if (test_bit(ST_DOSIGS, &portp->state)) { + if (test_bit(ST_DOFLUSHTX, &portp->state) && + test_bit(ST_DOFLUSHRX, &portp->state)) + cmd = A_SETSIGNALSF; + else if (test_bit(ST_DOFLUSHTX, &portp->state)) + cmd = A_SETSIGNALSFTX; + else if (test_bit(ST_DOFLUSHRX, &portp->state)) + cmd = A_SETSIGNALSFRX; + else + cmd = A_SETSIGNALS; + clear_bit(ST_DOFLUSHTX, &portp->state); + clear_bit(ST_DOFLUSHRX, &portp->state); + clear_bit(ST_DOSIGS, &portp->state); + memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &portp->asig, + sizeof(asysigs_t)); + writel(0, &cp->status); + writel(cmd, &cp->cmd); + set_bit(ST_CMDING, &portp->state); + } else if (test_bit(ST_DOFLUSHTX, &portp->state) || + test_bit(ST_DOFLUSHRX, &portp->state)) { + cmd = ((test_bit(ST_DOFLUSHTX, &portp->state)) ? FLUSHTX : 0); + cmd |= ((test_bit(ST_DOFLUSHRX, &portp->state)) ? FLUSHRX : 0); + clear_bit(ST_DOFLUSHTX, &portp->state); + clear_bit(ST_DOFLUSHRX, &portp->state); + memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &cmd, sizeof(int)); + writel(0, &cp->status); + writel(A_FLUSH, &cp->cmd); + set_bit(ST_CMDING, &portp->state); + } +} + +/*****************************************************************************/ + +/* + * Host command service checking. This handles commands or messages + * coming from the slave to the host. Must have board shared memory + * enabled and interrupts off when called. Notice that by servicing the + * read data last we don't need to change the shared memory pointer + * during processing (which is a slow IO operation). + * Return value indicates if this port is still awaiting actions from + * the slave (like open, command, or even TX data being sent). If 0 + * then port is still busy, otherwise no longer busy. + */ + +static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp) +{ + cdkasy_t __iomem *ap; + cdkctrl_t __iomem *cp; + struct tty_struct *tty; + asynotify_t nt; + unsigned long oldsigs; + int rc, donerx; + + ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); + cp = &ap->ctrl; + +/* + * Check if we are waiting for an open completion message. + */ + if (test_bit(ST_OPENING, &portp->state)) { + rc = readl(&cp->openarg); + if (readb(&cp->open) == 0 && rc != 0) { + if (rc > 0) + rc--; + writel(0, &cp->openarg); + portp->rc = rc; + clear_bit(ST_OPENING, &portp->state); + wake_up_interruptible(&portp->raw_wait); + } + } + +/* + * Check if we are waiting for a close completion message. + */ + if (test_bit(ST_CLOSING, &portp->state)) { + rc = (int) readl(&cp->closearg); + if (readb(&cp->close) == 0 && rc != 0) { + if (rc > 0) + rc--; + writel(0, &cp->closearg); + portp->rc = rc; + clear_bit(ST_CLOSING, &portp->state); + wake_up_interruptible(&portp->raw_wait); + } + } + +/* + * Check if we are waiting for a command completion message. We may + * need to copy out the command results associated with this command. + */ + if (test_bit(ST_CMDING, &portp->state)) { + rc = readl(&cp->status); + if (readl(&cp->cmd) == 0 && rc != 0) { + if (rc > 0) + rc--; + if (portp->argp != NULL) { + memcpy_fromio(portp->argp, (void __iomem *) &(cp->args[0]), + portp->argsize); + portp->argp = NULL; + } + writel(0, &cp->status); + portp->rc = rc; + clear_bit(ST_CMDING, &portp->state); + stli_dodelaycmd(portp, cp); + wake_up_interruptible(&portp->raw_wait); + } + } + +/* + * Check for any notification messages ready. This includes lots of + * different types of events - RX chars ready, RX break received, + * TX data low or empty in the slave, modem signals changed state. + */ + donerx = 0; + + if (ap->notify) { + nt = ap->changed; + ap->notify = 0; + tty = tty_port_tty_get(&portp->port); + + if (nt.signal & SG_DCD) { + oldsigs = portp->sigs; + portp->sigs = stli_mktiocm(nt.sigvalue); + clear_bit(ST_GETSIGS, &portp->state); + if ((portp->sigs & TIOCM_CD) && + ((oldsigs & TIOCM_CD) == 0)) + wake_up_interruptible(&portp->port.open_wait); + if ((oldsigs & TIOCM_CD) && + ((portp->sigs & TIOCM_CD) == 0)) { + if (portp->port.flags & ASYNC_CHECK_CD) { + if (tty) + tty_hangup(tty); + } + } + } + + if (nt.data & DT_TXEMPTY) + clear_bit(ST_TXBUSY, &portp->state); + if (nt.data & (DT_TXEMPTY | DT_TXLOW)) { + if (tty != NULL) { + tty_wakeup(tty); + EBRDENABLE(brdp); + } + } + + if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) { + if (tty != NULL) { + tty_insert_flip_char(tty, 0, TTY_BREAK); + if (portp->port.flags & ASYNC_SAK) { + do_SAK(tty); + EBRDENABLE(brdp); + } + tty_schedule_flip(tty); + } + } + tty_kref_put(tty); + + if (nt.data & DT_RXBUSY) { + donerx++; + stli_read(brdp, portp); + } + } + +/* + * It might seem odd that we are checking for more RX chars here. + * But, we need to handle the case where the tty buffer was previously + * filled, but we had more characters to pass up. The slave will not + * send any more RX notify messages until the RX buffer has been emptied. + * But it will leave the service bits on (since the buffer is not empty). + * So from here we can try to process more RX chars. + */ + if ((!donerx) && test_bit(ST_RXING, &portp->state)) { + clear_bit(ST_RXING, &portp->state); + stli_read(brdp, portp); + } + + return((test_bit(ST_OPENING, &portp->state) || + test_bit(ST_CLOSING, &portp->state) || + test_bit(ST_CMDING, &portp->state) || + test_bit(ST_TXBUSY, &portp->state) || + test_bit(ST_RXING, &portp->state)) ? 0 : 1); +} + +/*****************************************************************************/ + +/* + * Service all ports on a particular board. Assumes that the boards + * shared memory is enabled, and that the page pointer is pointed + * at the cdk header structure. + */ + +static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp) +{ + struct stliport *portp; + unsigned char hostbits[(STL_MAXCHANS / 8) + 1]; + unsigned char slavebits[(STL_MAXCHANS / 8) + 1]; + unsigned char __iomem *slavep; + int bitpos, bitat, bitsize; + int channr, nrdevs, slavebitchange; + + bitsize = brdp->bitsize; + nrdevs = brdp->nrdevs; + +/* + * Check if slave wants any service. Basically we try to do as + * little work as possible here. There are 2 levels of service + * bits. So if there is nothing to do we bail early. We check + * 8 service bits at a time in the inner loop, so we can bypass + * the lot if none of them want service. + */ + memcpy_fromio(&hostbits[0], (((unsigned char __iomem *) hdrp) + brdp->hostoffset), + bitsize); + + memset(&slavebits[0], 0, bitsize); + slavebitchange = 0; + + for (bitpos = 0; (bitpos < bitsize); bitpos++) { + if (hostbits[bitpos] == 0) + continue; + channr = bitpos * 8; + for (bitat = 0x1; (channr < nrdevs); channr++, bitat <<= 1) { + if (hostbits[bitpos] & bitat) { + portp = brdp->ports[(channr - 1)]; + if (stli_hostcmd(brdp, portp)) { + slavebitchange++; + slavebits[bitpos] |= bitat; + } + } + } + } + +/* + * If any of the ports are no longer busy then update them in the + * slave request bits. We need to do this after, since a host port + * service may initiate more slave requests. + */ + if (slavebitchange) { + hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + slavep = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset; + for (bitpos = 0; (bitpos < bitsize); bitpos++) { + if (readb(slavebits + bitpos)) + writeb(readb(slavep + bitpos) & ~slavebits[bitpos], slavebits + bitpos); + } + } +} + +/*****************************************************************************/ + +/* + * Driver poll routine. This routine polls the boards in use and passes + * messages back up to host when necessary. This is actually very + * CPU efficient, since we will always have the kernel poll clock, it + * adds only a few cycles when idle (since board service can be + * determined very easily), but when loaded generates no interrupts + * (with their expensive associated context change). + */ + +static void stli_poll(unsigned long arg) +{ + cdkhdr_t __iomem *hdrp; + struct stlibrd *brdp; + unsigned int brdnr; + + mod_timer(&stli_timerlist, STLI_TIMEOUT); + +/* + * Check each board and do any servicing required. + */ + for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) { + brdp = stli_brds[brdnr]; + if (brdp == NULL) + continue; + if (!test_bit(BST_STARTED, &brdp->state)) + continue; + + spin_lock(&brd_lock); + EBRDENABLE(brdp); + hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + if (readb(&hdrp->hostreq)) + stli_brdpoll(brdp, hdrp); + EBRDDISABLE(brdp); + spin_unlock(&brd_lock); + } +} + +/*****************************************************************************/ + +/* + * Translate the termios settings into the port setting structure of + * the slave. + */ + +static void stli_mkasyport(struct tty_struct *tty, struct stliport *portp, + asyport_t *pp, struct ktermios *tiosp) +{ + memset(pp, 0, sizeof(asyport_t)); + +/* + * Start of by setting the baud, char size, parity and stop bit info. + */ + pp->baudout = tty_get_baud_rate(tty); + if ((tiosp->c_cflag & CBAUD) == B38400) { + if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + pp->baudout = 57600; + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + pp->baudout = 115200; + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + pp->baudout = 230400; + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + pp->baudout = 460800; + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) + pp->baudout = (portp->baud_base / portp->custom_divisor); + } + if (pp->baudout > STL_MAXBAUD) + pp->baudout = STL_MAXBAUD; + pp->baudin = pp->baudout; + + switch (tiosp->c_cflag & CSIZE) { + case CS5: + pp->csize = 5; + break; + case CS6: + pp->csize = 6; + break; + case CS7: + pp->csize = 7; + break; + default: + pp->csize = 8; + break; + } + + if (tiosp->c_cflag & CSTOPB) + pp->stopbs = PT_STOP2; + else + pp->stopbs = PT_STOP1; + + if (tiosp->c_cflag & PARENB) { + if (tiosp->c_cflag & PARODD) + pp->parity = PT_ODDPARITY; + else + pp->parity = PT_EVENPARITY; + } else { + pp->parity = PT_NOPARITY; + } + +/* + * Set up any flow control options enabled. + */ + if (tiosp->c_iflag & IXON) { + pp->flow |= F_IXON; + if (tiosp->c_iflag & IXANY) + pp->flow |= F_IXANY; + } + if (tiosp->c_cflag & CRTSCTS) + pp->flow |= (F_RTSFLOW | F_CTSFLOW); + + pp->startin = tiosp->c_cc[VSTART]; + pp->stopin = tiosp->c_cc[VSTOP]; + pp->startout = tiosp->c_cc[VSTART]; + pp->stopout = tiosp->c_cc[VSTOP]; + +/* + * Set up the RX char marking mask with those RX error types we must + * catch. We can get the slave to help us out a little here, it will + * ignore parity errors and breaks for us, and mark parity errors in + * the data stream. + */ + if (tiosp->c_iflag & IGNPAR) + pp->iflag |= FI_IGNRXERRS; + if (tiosp->c_iflag & IGNBRK) + pp->iflag |= FI_IGNBREAK; + + portp->rxmarkmsk = 0; + if (tiosp->c_iflag & (INPCK | PARMRK)) + pp->iflag |= FI_1MARKRXERRS; + if (tiosp->c_iflag & BRKINT) + portp->rxmarkmsk |= BRKINT; + +/* + * Set up clocal processing as required. + */ + if (tiosp->c_cflag & CLOCAL) + portp->port.flags &= ~ASYNC_CHECK_CD; + else + portp->port.flags |= ASYNC_CHECK_CD; + +/* + * Transfer any persistent flags into the asyport structure. + */ + pp->pflag = (portp->pflag & 0xffff); + pp->vmin = (portp->pflag & P_RXIMIN) ? 1 : 0; + pp->vtime = (portp->pflag & P_RXITIME) ? 1 : 0; + pp->cc[1] = (portp->pflag & P_RXTHOLD) ? 1 : 0; +} + +/*****************************************************************************/ + +/* + * Construct a slave signals structure for setting the DTR and RTS + * signals as specified. + */ + +static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts) +{ + memset(sp, 0, sizeof(asysigs_t)); + if (dtr >= 0) { + sp->signal |= SG_DTR; + sp->sigvalue |= ((dtr > 0) ? SG_DTR : 0); + } + if (rts >= 0) { + sp->signal |= SG_RTS; + sp->sigvalue |= ((rts > 0) ? SG_RTS : 0); + } +} + +/*****************************************************************************/ + +/* + * Convert the signals returned from the slave into a local TIOCM type + * signals value. We keep them locally in TIOCM format. + */ + +static long stli_mktiocm(unsigned long sigvalue) +{ + long tiocm = 0; + tiocm |= ((sigvalue & SG_DCD) ? TIOCM_CD : 0); + tiocm |= ((sigvalue & SG_CTS) ? TIOCM_CTS : 0); + tiocm |= ((sigvalue & SG_RI) ? TIOCM_RI : 0); + tiocm |= ((sigvalue & SG_DSR) ? TIOCM_DSR : 0); + tiocm |= ((sigvalue & SG_DTR) ? TIOCM_DTR : 0); + tiocm |= ((sigvalue & SG_RTS) ? TIOCM_RTS : 0); + return(tiocm); +} + +/*****************************************************************************/ + +/* + * All panels and ports actually attached have been worked out. All + * we need to do here is set up the appropriate per port data structures. + */ + +static int stli_initports(struct stlibrd *brdp) +{ + struct stliport *portp; + unsigned int i, panelnr, panelport; + + for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) { + portp = kzalloc(sizeof(struct stliport), GFP_KERNEL); + if (!portp) { + printk(KERN_WARNING "istallion: failed to allocate port structure\n"); + continue; + } + tty_port_init(&portp->port); + portp->port.ops = &stli_port_ops; + portp->magic = STLI_PORTMAGIC; + portp->portnr = i; + portp->brdnr = brdp->brdnr; + portp->panelnr = panelnr; + portp->baud_base = STL_BAUDBASE; + portp->port.close_delay = STL_CLOSEDELAY; + portp->closing_wait = 30 * HZ; + init_waitqueue_head(&portp->port.open_wait); + init_waitqueue_head(&portp->port.close_wait); + init_waitqueue_head(&portp->raw_wait); + panelport++; + if (panelport >= brdp->panels[panelnr]) { + panelport = 0; + panelnr++; + } + brdp->ports[i] = portp; + } + + return 0; +} + +/*****************************************************************************/ + +/* + * All the following routines are board specific hardware operations. + */ + +static void stli_ecpinit(struct stlibrd *brdp) +{ + unsigned long memconf; + + outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR)); + udelay(10); + outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); + udelay(100); + + memconf = (brdp->memaddr & ECP_ATADDRMASK) >> ECP_ATADDRSHFT; + outb(memconf, (brdp->iobase + ECP_ATMEMAR)); +} + +/*****************************************************************************/ + +static void stli_ecpenable(struct stlibrd *brdp) +{ + outb(ECP_ATENABLE, (brdp->iobase + ECP_ATCONFR)); +} + +/*****************************************************************************/ + +static void stli_ecpdisable(struct stlibrd *brdp) +{ + outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); +} + +/*****************************************************************************/ + +static void __iomem *stli_ecpgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) +{ + void __iomem *ptr; + unsigned char val; + + if (offset > brdp->memsize) { + printk(KERN_ERR "istallion: shared memory pointer=%x out of " + "range at line=%d(%d), brd=%d\n", + (int) offset, line, __LINE__, brdp->brdnr); + ptr = NULL; + val = 0; + } else { + ptr = brdp->membase + (offset % ECP_ATPAGESIZE); + val = (unsigned char) (offset / ECP_ATPAGESIZE); + } + outb(val, (brdp->iobase + ECP_ATMEMPR)); + return(ptr); +} + +/*****************************************************************************/ + +static void stli_ecpreset(struct stlibrd *brdp) +{ + outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR)); + udelay(10); + outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); + udelay(500); +} + +/*****************************************************************************/ + +static void stli_ecpintr(struct stlibrd *brdp) +{ + outb(0x1, brdp->iobase); +} + +/*****************************************************************************/ + +/* + * The following set of functions act on ECP EISA boards. + */ + +static void stli_ecpeiinit(struct stlibrd *brdp) +{ + unsigned long memconf; + + outb(0x1, (brdp->iobase + ECP_EIBRDENAB)); + outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR)); + udelay(10); + outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR)); + udelay(500); + + memconf = (brdp->memaddr & ECP_EIADDRMASKL) >> ECP_EIADDRSHFTL; + outb(memconf, (brdp->iobase + ECP_EIMEMARL)); + memconf = (brdp->memaddr & ECP_EIADDRMASKH) >> ECP_EIADDRSHFTH; + outb(memconf, (brdp->iobase + ECP_EIMEMARH)); +} + +/*****************************************************************************/ + +static void stli_ecpeienable(struct stlibrd *brdp) +{ + outb(ECP_EIENABLE, (brdp->iobase + ECP_EICONFR)); +} + +/*****************************************************************************/ + +static void stli_ecpeidisable(struct stlibrd *brdp) +{ + outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR)); +} + +/*****************************************************************************/ + +static void __iomem *stli_ecpeigetmemptr(struct stlibrd *brdp, unsigned long offset, int line) +{ + void __iomem *ptr; + unsigned char val; + + if (offset > brdp->memsize) { + printk(KERN_ERR "istallion: shared memory pointer=%x out of " + "range at line=%d(%d), brd=%d\n", + (int) offset, line, __LINE__, brdp->brdnr); + ptr = NULL; + val = 0; + } else { + ptr = brdp->membase + (offset % ECP_EIPAGESIZE); + if (offset < ECP_EIPAGESIZE) + val = ECP_EIENABLE; + else + val = ECP_EIENABLE | 0x40; + } + outb(val, (brdp->iobase + ECP_EICONFR)); + return(ptr); +} + +/*****************************************************************************/ + +static void stli_ecpeireset(struct stlibrd *brdp) +{ + outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR)); + udelay(10); + outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR)); + udelay(500); +} + +/*****************************************************************************/ + +/* + * The following set of functions act on ECP MCA boards. + */ + +static void stli_ecpmcenable(struct stlibrd *brdp) +{ + outb(ECP_MCENABLE, (brdp->iobase + ECP_MCCONFR)); +} + +/*****************************************************************************/ + +static void stli_ecpmcdisable(struct stlibrd *brdp) +{ + outb(ECP_MCDISABLE, (brdp->iobase + ECP_MCCONFR)); +} + +/*****************************************************************************/ + +static void __iomem *stli_ecpmcgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) +{ + void __iomem *ptr; + unsigned char val; + + if (offset > brdp->memsize) { + printk(KERN_ERR "istallion: shared memory pointer=%x out of " + "range at line=%d(%d), brd=%d\n", + (int) offset, line, __LINE__, brdp->brdnr); + ptr = NULL; + val = 0; + } else { + ptr = brdp->membase + (offset % ECP_MCPAGESIZE); + val = ((unsigned char) (offset / ECP_MCPAGESIZE)) | ECP_MCENABLE; + } + outb(val, (brdp->iobase + ECP_MCCONFR)); + return(ptr); +} + +/*****************************************************************************/ + +static void stli_ecpmcreset(struct stlibrd *brdp) +{ + outb(ECP_MCSTOP, (brdp->iobase + ECP_MCCONFR)); + udelay(10); + outb(ECP_MCDISABLE, (brdp->iobase + ECP_MCCONFR)); + udelay(500); +} + +/*****************************************************************************/ + +/* + * The following set of functions act on ECP PCI boards. + */ + +static void stli_ecppciinit(struct stlibrd *brdp) +{ + outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR)); + udelay(10); + outb(0, (brdp->iobase + ECP_PCICONFR)); + udelay(500); +} + +/*****************************************************************************/ + +static void __iomem *stli_ecppcigetmemptr(struct stlibrd *brdp, unsigned long offset, int line) +{ + void __iomem *ptr; + unsigned char val; + + if (offset > brdp->memsize) { + printk(KERN_ERR "istallion: shared memory pointer=%x out of " + "range at line=%d(%d), board=%d\n", + (int) offset, line, __LINE__, brdp->brdnr); + ptr = NULL; + val = 0; + } else { + ptr = brdp->membase + (offset % ECP_PCIPAGESIZE); + val = (offset / ECP_PCIPAGESIZE) << 1; + } + outb(val, (brdp->iobase + ECP_PCICONFR)); + return(ptr); +} + +/*****************************************************************************/ + +static void stli_ecppcireset(struct stlibrd *brdp) +{ + outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR)); + udelay(10); + outb(0, (brdp->iobase + ECP_PCICONFR)); + udelay(500); +} + +/*****************************************************************************/ + +/* + * The following routines act on ONboards. + */ + +static void stli_onbinit(struct stlibrd *brdp) +{ + unsigned long memconf; + + outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR)); + udelay(10); + outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR)); + mdelay(1000); + + memconf = (brdp->memaddr & ONB_ATADDRMASK) >> ONB_ATADDRSHFT; + outb(memconf, (brdp->iobase + ONB_ATMEMAR)); + outb(0x1, brdp->iobase); + mdelay(1); +} + +/*****************************************************************************/ + +static void stli_onbenable(struct stlibrd *brdp) +{ + outb((brdp->enabval | ONB_ATENABLE), (brdp->iobase + ONB_ATCONFR)); +} + +/*****************************************************************************/ + +static void stli_onbdisable(struct stlibrd *brdp) +{ + outb((brdp->enabval | ONB_ATDISABLE), (brdp->iobase + ONB_ATCONFR)); +} + +/*****************************************************************************/ + +static void __iomem *stli_onbgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) +{ + void __iomem *ptr; + + if (offset > brdp->memsize) { + printk(KERN_ERR "istallion: shared memory pointer=%x out of " + "range at line=%d(%d), brd=%d\n", + (int) offset, line, __LINE__, brdp->brdnr); + ptr = NULL; + } else { + ptr = brdp->membase + (offset % ONB_ATPAGESIZE); + } + return(ptr); +} + +/*****************************************************************************/ + +static void stli_onbreset(struct stlibrd *brdp) +{ + outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR)); + udelay(10); + outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR)); + mdelay(1000); +} + +/*****************************************************************************/ + +/* + * The following routines act on ONboard EISA. + */ + +static void stli_onbeinit(struct stlibrd *brdp) +{ + unsigned long memconf; + + outb(0x1, (brdp->iobase + ONB_EIBRDENAB)); + outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); + udelay(10); + outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); + mdelay(1000); + + memconf = (brdp->memaddr & ONB_EIADDRMASKL) >> ONB_EIADDRSHFTL; + outb(memconf, (brdp->iobase + ONB_EIMEMARL)); + memconf = (brdp->memaddr & ONB_EIADDRMASKH) >> ONB_EIADDRSHFTH; + outb(memconf, (brdp->iobase + ONB_EIMEMARH)); + outb(0x1, brdp->iobase); + mdelay(1); +} + +/*****************************************************************************/ + +static void stli_onbeenable(struct stlibrd *brdp) +{ + outb(ONB_EIENABLE, (brdp->iobase + ONB_EICONFR)); +} + +/*****************************************************************************/ + +static void stli_onbedisable(struct stlibrd *brdp) +{ + outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); +} + +/*****************************************************************************/ + +static void __iomem *stli_onbegetmemptr(struct stlibrd *brdp, unsigned long offset, int line) +{ + void __iomem *ptr; + unsigned char val; + + if (offset > brdp->memsize) { + printk(KERN_ERR "istallion: shared memory pointer=%x out of " + "range at line=%d(%d), brd=%d\n", + (int) offset, line, __LINE__, brdp->brdnr); + ptr = NULL; + val = 0; + } else { + ptr = brdp->membase + (offset % ONB_EIPAGESIZE); + if (offset < ONB_EIPAGESIZE) + val = ONB_EIENABLE; + else + val = ONB_EIENABLE | 0x40; + } + outb(val, (brdp->iobase + ONB_EICONFR)); + return(ptr); +} + +/*****************************************************************************/ + +static void stli_onbereset(struct stlibrd *brdp) +{ + outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); + udelay(10); + outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); + mdelay(1000); +} + +/*****************************************************************************/ + +/* + * The following routines act on Brumby boards. + */ + +static void stli_bbyinit(struct stlibrd *brdp) +{ + outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); + udelay(10); + outb(0, (brdp->iobase + BBY_ATCONFR)); + mdelay(1000); + outb(0x1, brdp->iobase); + mdelay(1); +} + +/*****************************************************************************/ + +static void __iomem *stli_bbygetmemptr(struct stlibrd *brdp, unsigned long offset, int line) +{ + void __iomem *ptr; + unsigned char val; + + BUG_ON(offset > brdp->memsize); + + ptr = brdp->membase + (offset % BBY_PAGESIZE); + val = (unsigned char) (offset / BBY_PAGESIZE); + outb(val, (brdp->iobase + BBY_ATCONFR)); + return(ptr); +} + +/*****************************************************************************/ + +static void stli_bbyreset(struct stlibrd *brdp) +{ + outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); + udelay(10); + outb(0, (brdp->iobase + BBY_ATCONFR)); + mdelay(1000); +} + +/*****************************************************************************/ + +/* + * The following routines act on original old Stallion boards. + */ + +static void stli_stalinit(struct stlibrd *brdp) +{ + outb(0x1, brdp->iobase); + mdelay(1000); +} + +/*****************************************************************************/ + +static void __iomem *stli_stalgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) +{ + BUG_ON(offset > brdp->memsize); + return brdp->membase + (offset % STAL_PAGESIZE); +} + +/*****************************************************************************/ + +static void stli_stalreset(struct stlibrd *brdp) +{ + u32 __iomem *vecp; + + vecp = (u32 __iomem *) (brdp->membase + 0x30); + writel(0xffff0000, vecp); + outb(0, brdp->iobase); + mdelay(1000); +} + +/*****************************************************************************/ + +/* + * Try to find an ECP board and initialize it. This handles only ECP + * board types. + */ + +static int stli_initecp(struct stlibrd *brdp) +{ + cdkecpsig_t sig; + cdkecpsig_t __iomem *sigsp; + unsigned int status, nxtid; + char *name; + int retval, panelnr, nrports; + + if ((brdp->iobase == 0) || (brdp->memaddr == 0)) { + retval = -ENODEV; + goto err; + } + + brdp->iosize = ECP_IOSIZE; + + if (!request_region(brdp->iobase, brdp->iosize, "istallion")) { + retval = -EIO; + goto err; + } + +/* + * Based on the specific board type setup the common vars to access + * and enable shared memory. Set all board specific information now + * as well. + */ + switch (brdp->brdtype) { + case BRD_ECP: + brdp->memsize = ECP_MEMSIZE; + brdp->pagesize = ECP_ATPAGESIZE; + brdp->init = stli_ecpinit; + brdp->enable = stli_ecpenable; + brdp->reenable = stli_ecpenable; + brdp->disable = stli_ecpdisable; + brdp->getmemptr = stli_ecpgetmemptr; + brdp->intr = stli_ecpintr; + brdp->reset = stli_ecpreset; + name = "serial(EC8/64)"; + break; + + case BRD_ECPE: + brdp->memsize = ECP_MEMSIZE; + brdp->pagesize = ECP_EIPAGESIZE; + brdp->init = stli_ecpeiinit; + brdp->enable = stli_ecpeienable; + brdp->reenable = stli_ecpeienable; + brdp->disable = stli_ecpeidisable; + brdp->getmemptr = stli_ecpeigetmemptr; + brdp->intr = stli_ecpintr; + brdp->reset = stli_ecpeireset; + name = "serial(EC8/64-EI)"; + break; + + case BRD_ECPMC: + brdp->memsize = ECP_MEMSIZE; + brdp->pagesize = ECP_MCPAGESIZE; + brdp->init = NULL; + brdp->enable = stli_ecpmcenable; + brdp->reenable = stli_ecpmcenable; + brdp->disable = stli_ecpmcdisable; + brdp->getmemptr = stli_ecpmcgetmemptr; + brdp->intr = stli_ecpintr; + brdp->reset = stli_ecpmcreset; + name = "serial(EC8/64-MCA)"; + break; + + case BRD_ECPPCI: + brdp->memsize = ECP_PCIMEMSIZE; + brdp->pagesize = ECP_PCIPAGESIZE; + brdp->init = stli_ecppciinit; + brdp->enable = NULL; + brdp->reenable = NULL; + brdp->disable = NULL; + brdp->getmemptr = stli_ecppcigetmemptr; + brdp->intr = stli_ecpintr; + brdp->reset = stli_ecppcireset; + name = "serial(EC/RA-PCI)"; + break; + + default: + retval = -EINVAL; + goto err_reg; + } + +/* + * The per-board operations structure is all set up, so now let's go + * and get the board operational. Firstly initialize board configuration + * registers. Set the memory mapping info so we can get at the boards + * shared memory. + */ + EBRDINIT(brdp); + + brdp->membase = ioremap_nocache(brdp->memaddr, brdp->memsize); + if (brdp->membase == NULL) { + retval = -ENOMEM; + goto err_reg; + } + +/* + * Now that all specific code is set up, enable the shared memory and + * look for the a signature area that will tell us exactly what board + * this is, and what it is connected to it. + */ + EBRDENABLE(brdp); + sigsp = (cdkecpsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR); + memcpy_fromio(&sig, sigsp, sizeof(cdkecpsig_t)); + EBRDDISABLE(brdp); + + if (sig.magic != cpu_to_le32(ECP_MAGIC)) { + retval = -ENODEV; + goto err_unmap; + } + +/* + * Scan through the signature looking at the panels connected to the + * board. Calculate the total number of ports as we go. + */ + for (panelnr = 0, nxtid = 0; (panelnr < STL_MAXPANELS); panelnr++) { + status = sig.panelid[nxtid]; + if ((status & ECH_PNLIDMASK) != nxtid) + break; + + brdp->panelids[panelnr] = status; + nrports = (status & ECH_PNL16PORT) ? 16 : 8; + if ((nrports == 16) && ((status & ECH_PNLXPID) == 0)) + nxtid++; + brdp->panels[panelnr] = nrports; + brdp->nrports += nrports; + nxtid++; + brdp->nrpanels++; + } + + + set_bit(BST_FOUND, &brdp->state); + return 0; +err_unmap: + iounmap(brdp->membase); + brdp->membase = NULL; +err_reg: + release_region(brdp->iobase, brdp->iosize); +err: + return retval; +} + +/*****************************************************************************/ + +/* + * Try to find an ONboard, Brumby or Stallion board and initialize it. + * This handles only these board types. + */ + +static int stli_initonb(struct stlibrd *brdp) +{ + cdkonbsig_t sig; + cdkonbsig_t __iomem *sigsp; + char *name; + int i, retval; + +/* + * Do a basic sanity check on the IO and memory addresses. + */ + if (brdp->iobase == 0 || brdp->memaddr == 0) { + retval = -ENODEV; + goto err; + } + + brdp->iosize = ONB_IOSIZE; + + if (!request_region(brdp->iobase, brdp->iosize, "istallion")) { + retval = -EIO; + goto err; + } + +/* + * Based on the specific board type setup the common vars to access + * and enable shared memory. Set all board specific information now + * as well. + */ + switch (brdp->brdtype) { + case BRD_ONBOARD: + case BRD_ONBOARD2: + brdp->memsize = ONB_MEMSIZE; + brdp->pagesize = ONB_ATPAGESIZE; + brdp->init = stli_onbinit; + brdp->enable = stli_onbenable; + brdp->reenable = stli_onbenable; + brdp->disable = stli_onbdisable; + brdp->getmemptr = stli_onbgetmemptr; + brdp->intr = stli_ecpintr; + brdp->reset = stli_onbreset; + if (brdp->memaddr > 0x100000) + brdp->enabval = ONB_MEMENABHI; + else + brdp->enabval = ONB_MEMENABLO; + name = "serial(ONBoard)"; + break; + + case BRD_ONBOARDE: + brdp->memsize = ONB_EIMEMSIZE; + brdp->pagesize = ONB_EIPAGESIZE; + brdp->init = stli_onbeinit; + brdp->enable = stli_onbeenable; + brdp->reenable = stli_onbeenable; + brdp->disable = stli_onbedisable; + brdp->getmemptr = stli_onbegetmemptr; + brdp->intr = stli_ecpintr; + brdp->reset = stli_onbereset; + name = "serial(ONBoard/E)"; + break; + + case BRD_BRUMBY4: + brdp->memsize = BBY_MEMSIZE; + brdp->pagesize = BBY_PAGESIZE; + brdp->init = stli_bbyinit; + brdp->enable = NULL; + brdp->reenable = NULL; + brdp->disable = NULL; + brdp->getmemptr = stli_bbygetmemptr; + brdp->intr = stli_ecpintr; + brdp->reset = stli_bbyreset; + name = "serial(Brumby)"; + break; + + case BRD_STALLION: + brdp->memsize = STAL_MEMSIZE; + brdp->pagesize = STAL_PAGESIZE; + brdp->init = stli_stalinit; + brdp->enable = NULL; + brdp->reenable = NULL; + brdp->disable = NULL; + brdp->getmemptr = stli_stalgetmemptr; + brdp->intr = stli_ecpintr; + brdp->reset = stli_stalreset; + name = "serial(Stallion)"; + break; + + default: + retval = -EINVAL; + goto err_reg; + } + +/* + * The per-board operations structure is all set up, so now let's go + * and get the board operational. Firstly initialize board configuration + * registers. Set the memory mapping info so we can get at the boards + * shared memory. + */ + EBRDINIT(brdp); + + brdp->membase = ioremap_nocache(brdp->memaddr, brdp->memsize); + if (brdp->membase == NULL) { + retval = -ENOMEM; + goto err_reg; + } + +/* + * Now that all specific code is set up, enable the shared memory and + * look for the a signature area that will tell us exactly what board + * this is, and how many ports. + */ + EBRDENABLE(brdp); + sigsp = (cdkonbsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR); + memcpy_fromio(&sig, sigsp, sizeof(cdkonbsig_t)); + EBRDDISABLE(brdp); + + if (sig.magic0 != cpu_to_le16(ONB_MAGIC0) || + sig.magic1 != cpu_to_le16(ONB_MAGIC1) || + sig.magic2 != cpu_to_le16(ONB_MAGIC2) || + sig.magic3 != cpu_to_le16(ONB_MAGIC3)) { + retval = -ENODEV; + goto err_unmap; + } + +/* + * Scan through the signature alive mask and calculate how many ports + * there are on this board. + */ + brdp->nrpanels = 1; + if (sig.amask1) { + brdp->nrports = 32; + } else { + for (i = 0; (i < 16); i++) { + if (((sig.amask0 << i) & 0x8000) == 0) + break; + } + brdp->nrports = i; + } + brdp->panels[0] = brdp->nrports; + + + set_bit(BST_FOUND, &brdp->state); + return 0; +err_unmap: + iounmap(brdp->membase); + brdp->membase = NULL; +err_reg: + release_region(brdp->iobase, brdp->iosize); +err: + return retval; +} + +/*****************************************************************************/ + +/* + * Start up a running board. This routine is only called after the + * code has been down loaded to the board and is operational. It will + * read in the memory map, and get the show on the road... + */ + +static int stli_startbrd(struct stlibrd *brdp) +{ + cdkhdr_t __iomem *hdrp; + cdkmem_t __iomem *memp; + cdkasy_t __iomem *ap; + unsigned long flags; + unsigned int portnr, nrdevs, i; + struct stliport *portp; + int rc = 0; + u32 memoff; + + spin_lock_irqsave(&brd_lock, flags); + EBRDENABLE(brdp); + hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + nrdevs = hdrp->nrdevs; + +#if 0 + printk("%s(%d): CDK version %d.%d.%d --> " + "nrdevs=%d memp=%x hostp=%x slavep=%x\n", + __FILE__, __LINE__, readb(&hdrp->ver_release), readb(&hdrp->ver_modification), + readb(&hdrp->ver_fix), nrdevs, (int) readl(&hdrp->memp), readl(&hdrp->hostp), + readl(&hdrp->slavep)); +#endif + + if (nrdevs < (brdp->nrports + 1)) { + printk(KERN_ERR "istallion: slave failed to allocate memory for " + "all devices, devices=%d\n", nrdevs); + brdp->nrports = nrdevs - 1; + } + brdp->nrdevs = nrdevs; + brdp->hostoffset = hdrp->hostp - CDK_CDKADDR; + brdp->slaveoffset = hdrp->slavep - CDK_CDKADDR; + brdp->bitsize = (nrdevs + 7) / 8; + memoff = readl(&hdrp->memp); + if (memoff > brdp->memsize) { + printk(KERN_ERR "istallion: corrupted shared memory region?\n"); + rc = -EIO; + goto stli_donestartup; + } + memp = (cdkmem_t __iomem *) EBRDGETMEMPTR(brdp, memoff); + if (readw(&memp->dtype) != TYP_ASYNCTRL) { + printk(KERN_ERR "istallion: no slave control device found\n"); + goto stli_donestartup; + } + memp++; + +/* + * Cycle through memory allocation of each port. We are guaranteed to + * have all ports inside the first page of slave window, so no need to + * change pages while reading memory map. + */ + for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++, memp++) { + if (readw(&memp->dtype) != TYP_ASYNC) + break; + portp = brdp->ports[portnr]; + if (portp == NULL) + break; + portp->devnr = i; + portp->addr = readl(&memp->offset); + portp->reqbit = (unsigned char) (0x1 << (i * 8 / nrdevs)); + portp->portidx = (unsigned char) (i / 8); + portp->portbit = (unsigned char) (0x1 << (i % 8)); + } + + writeb(0xff, &hdrp->slavereq); + +/* + * For each port setup a local copy of the RX and TX buffer offsets + * and sizes. We do this separate from the above, because we need to + * move the shared memory page... + */ + for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++) { + portp = brdp->ports[portnr]; + if (portp == NULL) + break; + if (portp->addr == 0) + break; + ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); + if (ap != NULL) { + portp->rxsize = readw(&ap->rxq.size); + portp->txsize = readw(&ap->txq.size); + portp->rxoffset = readl(&ap->rxq.offset); + portp->txoffset = readl(&ap->txq.offset); + } + } + +stli_donestartup: + EBRDDISABLE(brdp); + spin_unlock_irqrestore(&brd_lock, flags); + + if (rc == 0) + set_bit(BST_STARTED, &brdp->state); + + if (! stli_timeron) { + stli_timeron++; + mod_timer(&stli_timerlist, STLI_TIMEOUT); + } + + return rc; +} + +/*****************************************************************************/ + +/* + * Probe and initialize the specified board. + */ + +static int __devinit stli_brdinit(struct stlibrd *brdp) +{ + int retval; + + switch (brdp->brdtype) { + case BRD_ECP: + case BRD_ECPE: + case BRD_ECPMC: + case BRD_ECPPCI: + retval = stli_initecp(brdp); + break; + case BRD_ONBOARD: + case BRD_ONBOARDE: + case BRD_ONBOARD2: + case BRD_BRUMBY4: + case BRD_STALLION: + retval = stli_initonb(brdp); + break; + default: + printk(KERN_ERR "istallion: board=%d is unknown board " + "type=%d\n", brdp->brdnr, brdp->brdtype); + retval = -ENODEV; + } + + if (retval) + return retval; + + stli_initports(brdp); + printk(KERN_INFO "istallion: %s found, board=%d io=%x mem=%x " + "nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype], + brdp->brdnr, brdp->iobase, (int) brdp->memaddr, + brdp->nrpanels, brdp->nrports); + return 0; +} + +#if STLI_EISAPROBE != 0 +/*****************************************************************************/ + +/* + * Probe around trying to find where the EISA boards shared memory + * might be. This is a bit if hack, but it is the best we can do. + */ + +static int stli_eisamemprobe(struct stlibrd *brdp) +{ + cdkecpsig_t ecpsig, __iomem *ecpsigp; + cdkonbsig_t onbsig, __iomem *onbsigp; + int i, foundit; + +/* + * First up we reset the board, to get it into a known state. There + * is only 2 board types here we need to worry about. Don;t use the + * standard board init routine here, it programs up the shared + * memory address, and we don't know it yet... + */ + if (brdp->brdtype == BRD_ECPE) { + outb(0x1, (brdp->iobase + ECP_EIBRDENAB)); + outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR)); + udelay(10); + outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR)); + udelay(500); + stli_ecpeienable(brdp); + } else if (brdp->brdtype == BRD_ONBOARDE) { + outb(0x1, (brdp->iobase + ONB_EIBRDENAB)); + outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); + udelay(10); + outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); + mdelay(100); + outb(0x1, brdp->iobase); + mdelay(1); + stli_onbeenable(brdp); + } else { + return -ENODEV; + } + + foundit = 0; + brdp->memsize = ECP_MEMSIZE; + +/* + * Board shared memory is enabled, so now we have a poke around and + * see if we can find it. + */ + for (i = 0; (i < stli_eisamempsize); i++) { + brdp->memaddr = stli_eisamemprobeaddrs[i]; + brdp->membase = ioremap_nocache(brdp->memaddr, brdp->memsize); + if (brdp->membase == NULL) + continue; + + if (brdp->brdtype == BRD_ECPE) { + ecpsigp = stli_ecpeigetmemptr(brdp, + CDK_SIGADDR, __LINE__); + memcpy_fromio(&ecpsig, ecpsigp, sizeof(cdkecpsig_t)); + if (ecpsig.magic == cpu_to_le32(ECP_MAGIC)) + foundit = 1; + } else { + onbsigp = (cdkonbsig_t __iomem *) stli_onbegetmemptr(brdp, + CDK_SIGADDR, __LINE__); + memcpy_fromio(&onbsig, onbsigp, sizeof(cdkonbsig_t)); + if ((onbsig.magic0 == cpu_to_le16(ONB_MAGIC0)) && + (onbsig.magic1 == cpu_to_le16(ONB_MAGIC1)) && + (onbsig.magic2 == cpu_to_le16(ONB_MAGIC2)) && + (onbsig.magic3 == cpu_to_le16(ONB_MAGIC3))) + foundit = 1; + } + + iounmap(brdp->membase); + if (foundit) + break; + } + +/* + * Regardless of whether we found the shared memory or not we must + * disable the region. After that return success or failure. + */ + if (brdp->brdtype == BRD_ECPE) + stli_ecpeidisable(brdp); + else + stli_onbedisable(brdp); + + if (! foundit) { + brdp->memaddr = 0; + brdp->membase = NULL; + printk(KERN_ERR "istallion: failed to probe shared memory " + "region for %s in EISA slot=%d\n", + stli_brdnames[brdp->brdtype], (brdp->iobase >> 12)); + return -ENODEV; + } + return 0; +} +#endif + +static int stli_getbrdnr(void) +{ + unsigned int i; + + for (i = 0; i < STL_MAXBRDS; i++) { + if (!stli_brds[i]) { + if (i >= stli_nrbrds) + stli_nrbrds = i + 1; + return i; + } + } + return -1; +} + +#if STLI_EISAPROBE != 0 +/*****************************************************************************/ + +/* + * Probe around and try to find any EISA boards in system. The biggest + * problem here is finding out what memory address is associated with + * an EISA board after it is found. The registers of the ECPE and + * ONboardE are not readable - so we can't read them from there. We + * don't have access to the EISA CMOS (or EISA BIOS) so we don't + * actually have any way to find out the real value. The best we can + * do is go probing around in the usual places hoping we can find it. + */ + +static int __init stli_findeisabrds(void) +{ + struct stlibrd *brdp; + unsigned int iobase, eid, i; + int brdnr, found = 0; + +/* + * Firstly check if this is an EISA system. If this is not an EISA system then + * don't bother going any further! + */ + if (EISA_bus) + return 0; + +/* + * Looks like an EISA system, so go searching for EISA boards. + */ + for (iobase = 0x1000; (iobase <= 0xc000); iobase += 0x1000) { + outb(0xff, (iobase + 0xc80)); + eid = inb(iobase + 0xc80); + eid |= inb(iobase + 0xc81) << 8; + if (eid != STL_EISAID) + continue; + +/* + * We have found a board. Need to check if this board was + * statically configured already (just in case!). + */ + for (i = 0; (i < STL_MAXBRDS); i++) { + brdp = stli_brds[i]; + if (brdp == NULL) + continue; + if (brdp->iobase == iobase) + break; + } + if (i < STL_MAXBRDS) + continue; + +/* + * We have found a Stallion board and it is not configured already. + * Allocate a board structure and initialize it. + */ + if ((brdp = stli_allocbrd()) == NULL) + return found ? : -ENOMEM; + brdnr = stli_getbrdnr(); + if (brdnr < 0) + return found ? : -ENOMEM; + brdp->brdnr = (unsigned int)brdnr; + eid = inb(iobase + 0xc82); + if (eid == ECP_EISAID) + brdp->brdtype = BRD_ECPE; + else if (eid == ONB_EISAID) + brdp->brdtype = BRD_ONBOARDE; + else + brdp->brdtype = BRD_UNKNOWN; + brdp->iobase = iobase; + outb(0x1, (iobase + 0xc84)); + if (stli_eisamemprobe(brdp)) + outb(0, (iobase + 0xc84)); + if (stli_brdinit(brdp) < 0) { + kfree(brdp); + continue; + } + + stli_brds[brdp->brdnr] = brdp; + found++; + + for (i = 0; i < brdp->nrports; i++) + tty_register_device(stli_serial, + brdp->brdnr * STL_MAXPORTS + i, NULL); + } + + return found; +} +#else +static inline int stli_findeisabrds(void) { return 0; } +#endif + +/*****************************************************************************/ + +/* + * Find the next available board number that is free. + */ + +/*****************************************************************************/ + +/* + * We have a Stallion board. Allocate a board structure and + * initialize it. Read its IO and MEMORY resources from PCI + * configuration space. + */ + +static int __devinit stli_pciprobe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct stlibrd *brdp; + unsigned int i; + int brdnr, retval = -EIO; + + retval = pci_enable_device(pdev); + if (retval) + goto err; + brdp = stli_allocbrd(); + if (brdp == NULL) { + retval = -ENOMEM; + goto err; + } + mutex_lock(&stli_brdslock); + brdnr = stli_getbrdnr(); + if (brdnr < 0) { + printk(KERN_INFO "istallion: too many boards found, " + "maximum supported %d\n", STL_MAXBRDS); + mutex_unlock(&stli_brdslock); + retval = -EIO; + goto err_fr; + } + brdp->brdnr = (unsigned int)brdnr; + stli_brds[brdp->brdnr] = brdp; + mutex_unlock(&stli_brdslock); + brdp->brdtype = BRD_ECPPCI; +/* + * We have all resources from the board, so lets setup the actual + * board structure now. + */ + brdp->iobase = pci_resource_start(pdev, 3); + brdp->memaddr = pci_resource_start(pdev, 2); + retval = stli_brdinit(brdp); + if (retval) + goto err_null; + + set_bit(BST_PROBED, &brdp->state); + pci_set_drvdata(pdev, brdp); + + EBRDENABLE(brdp); + brdp->enable = NULL; + brdp->disable = NULL; + + for (i = 0; i < brdp->nrports; i++) + tty_register_device(stli_serial, brdp->brdnr * STL_MAXPORTS + i, + &pdev->dev); + + return 0; +err_null: + stli_brds[brdp->brdnr] = NULL; +err_fr: + kfree(brdp); +err: + return retval; +} + +static void __devexit stli_pciremove(struct pci_dev *pdev) +{ + struct stlibrd *brdp = pci_get_drvdata(pdev); + + stli_cleanup_ports(brdp); + + iounmap(brdp->membase); + if (brdp->iosize > 0) + release_region(brdp->iobase, brdp->iosize); + + stli_brds[brdp->brdnr] = NULL; + kfree(brdp); +} + +static struct pci_driver stli_pcidriver = { + .name = "istallion", + .id_table = istallion_pci_tbl, + .probe = stli_pciprobe, + .remove = __devexit_p(stli_pciremove) +}; +/*****************************************************************************/ + +/* + * Allocate a new board structure. Fill out the basic info in it. + */ + +static struct stlibrd *stli_allocbrd(void) +{ + struct stlibrd *brdp; + + brdp = kzalloc(sizeof(struct stlibrd), GFP_KERNEL); + if (!brdp) { + printk(KERN_ERR "istallion: failed to allocate memory " + "(size=%Zd)\n", sizeof(struct stlibrd)); + return NULL; + } + brdp->magic = STLI_BOARDMAGIC; + return brdp; +} + +/*****************************************************************************/ + +/* + * Scan through all the boards in the configuration and see what we + * can find. + */ + +static int __init stli_initbrds(void) +{ + struct stlibrd *brdp, *nxtbrdp; + struct stlconf conf; + unsigned int i, j, found = 0; + int retval; + + for (stli_nrbrds = 0; stli_nrbrds < ARRAY_SIZE(stli_brdsp); + stli_nrbrds++) { + memset(&conf, 0, sizeof(conf)); + if (stli_parsebrd(&conf, stli_brdsp[stli_nrbrds]) == 0) + continue; + if ((brdp = stli_allocbrd()) == NULL) + continue; + brdp->brdnr = stli_nrbrds; + brdp->brdtype = conf.brdtype; + brdp->iobase = conf.ioaddr1; + brdp->memaddr = conf.memaddr; + if (stli_brdinit(brdp) < 0) { + kfree(brdp); + continue; + } + stli_brds[brdp->brdnr] = brdp; + found++; + + for (i = 0; i < brdp->nrports; i++) + tty_register_device(stli_serial, + brdp->brdnr * STL_MAXPORTS + i, NULL); + } + + retval = stli_findeisabrds(); + if (retval > 0) + found += retval; + +/* + * All found boards are initialized. Now for a little optimization, if + * no boards are sharing the "shared memory" regions then we can just + * leave them all enabled. This is in fact the usual case. + */ + stli_shared = 0; + if (stli_nrbrds > 1) { + for (i = 0; (i < stli_nrbrds); i++) { + brdp = stli_brds[i]; + if (brdp == NULL) + continue; + for (j = i + 1; (j < stli_nrbrds); j++) { + nxtbrdp = stli_brds[j]; + if (nxtbrdp == NULL) + continue; + if ((brdp->membase >= nxtbrdp->membase) && + (brdp->membase <= (nxtbrdp->membase + + nxtbrdp->memsize - 1))) { + stli_shared++; + break; + } + } + } + } + + if (stli_shared == 0) { + for (i = 0; (i < stli_nrbrds); i++) { + brdp = stli_brds[i]; + if (brdp == NULL) + continue; + if (test_bit(BST_FOUND, &brdp->state)) { + EBRDENABLE(brdp); + brdp->enable = NULL; + brdp->disable = NULL; + } + } + } + + retval = pci_register_driver(&stli_pcidriver); + if (retval && found == 0) { + printk(KERN_ERR "Neither isa nor eisa cards found nor pci " + "driver can be registered!\n"); + goto err; + } + + return 0; +err: + return retval; +} + +/*****************************************************************************/ + +/* + * Code to handle an "staliomem" read operation. This device is the + * contents of the board shared memory. It is used for down loading + * the slave image (and debugging :-) + */ + +static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp) +{ + unsigned long flags; + void __iomem *memptr; + struct stlibrd *brdp; + unsigned int brdnr; + int size, n; + void *p; + loff_t off = *offp; + + brdnr = iminor(fp->f_path.dentry->d_inode); + if (brdnr >= stli_nrbrds) + return -ENODEV; + brdp = stli_brds[brdnr]; + if (brdp == NULL) + return -ENODEV; + if (brdp->state == 0) + return -ENODEV; + if (off >= brdp->memsize || off + count < off) + return 0; + + size = min(count, (size_t)(brdp->memsize - off)); + + /* + * Copy the data a page at a time + */ + + p = (void *)__get_free_page(GFP_KERNEL); + if(p == NULL) + return -ENOMEM; + + while (size > 0) { + spin_lock_irqsave(&brd_lock, flags); + EBRDENABLE(brdp); + memptr = EBRDGETMEMPTR(brdp, off); + n = min(size, (int)(brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); + n = min(n, (int)PAGE_SIZE); + memcpy_fromio(p, memptr, n); + EBRDDISABLE(brdp); + spin_unlock_irqrestore(&brd_lock, flags); + if (copy_to_user(buf, p, n)) { + count = -EFAULT; + goto out; + } + off += n; + buf += n; + size -= n; + } +out: + *offp = off; + free_page((unsigned long)p); + return count; +} + +/*****************************************************************************/ + +/* + * Code to handle an "staliomem" write operation. This device is the + * contents of the board shared memory. It is used for down loading + * the slave image (and debugging :-) + * + * FIXME: copy under lock + */ + +static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp) +{ + unsigned long flags; + void __iomem *memptr; + struct stlibrd *brdp; + char __user *chbuf; + unsigned int brdnr; + int size, n; + void *p; + loff_t off = *offp; + + brdnr = iminor(fp->f_path.dentry->d_inode); + + if (brdnr >= stli_nrbrds) + return -ENODEV; + brdp = stli_brds[brdnr]; + if (brdp == NULL) + return -ENODEV; + if (brdp->state == 0) + return -ENODEV; + if (off >= brdp->memsize || off + count < off) + return 0; + + chbuf = (char __user *) buf; + size = min(count, (size_t)(brdp->memsize - off)); + + /* + * Copy the data a page at a time + */ + + p = (void *)__get_free_page(GFP_KERNEL); + if(p == NULL) + return -ENOMEM; + + while (size > 0) { + n = min(size, (int)(brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); + n = min(n, (int)PAGE_SIZE); + if (copy_from_user(p, chbuf, n)) { + if (count == 0) + count = -EFAULT; + goto out; + } + spin_lock_irqsave(&brd_lock, flags); + EBRDENABLE(brdp); + memptr = EBRDGETMEMPTR(brdp, off); + memcpy_toio(memptr, p, n); + EBRDDISABLE(brdp); + spin_unlock_irqrestore(&brd_lock, flags); + off += n; + chbuf += n; + size -= n; + } +out: + free_page((unsigned long) p); + *offp = off; + return count; +} + +/*****************************************************************************/ + +/* + * Return the board stats structure to user app. + */ + +static int stli_getbrdstats(combrd_t __user *bp) +{ + struct stlibrd *brdp; + unsigned int i; + + if (copy_from_user(&stli_brdstats, bp, sizeof(combrd_t))) + return -EFAULT; + if (stli_brdstats.brd >= STL_MAXBRDS) + return -ENODEV; + brdp = stli_brds[stli_brdstats.brd]; + if (brdp == NULL) + return -ENODEV; + + memset(&stli_brdstats, 0, sizeof(combrd_t)); + + stli_brdstats.brd = brdp->brdnr; + stli_brdstats.type = brdp->brdtype; + stli_brdstats.hwid = 0; + stli_brdstats.state = brdp->state; + stli_brdstats.ioaddr = brdp->iobase; + stli_brdstats.memaddr = brdp->memaddr; + stli_brdstats.nrpanels = brdp->nrpanels; + stli_brdstats.nrports = brdp->nrports; + for (i = 0; (i < brdp->nrpanels); i++) { + stli_brdstats.panels[i].panel = i; + stli_brdstats.panels[i].hwid = brdp->panelids[i]; + stli_brdstats.panels[i].nrports = brdp->panels[i]; + } + + if (copy_to_user(bp, &stli_brdstats, sizeof(combrd_t))) + return -EFAULT; + return 0; +} + +/*****************************************************************************/ + +/* + * Resolve the referenced port number into a port struct pointer. + */ + +static struct stliport *stli_getport(unsigned int brdnr, unsigned int panelnr, + unsigned int portnr) +{ + struct stlibrd *brdp; + unsigned int i; + + if (brdnr >= STL_MAXBRDS) + return NULL; + brdp = stli_brds[brdnr]; + if (brdp == NULL) + return NULL; + for (i = 0; (i < panelnr); i++) + portnr += brdp->panels[i]; + if (portnr >= brdp->nrports) + return NULL; + return brdp->ports[portnr]; +} + +/*****************************************************************************/ + +/* + * Return the port stats structure to user app. A NULL port struct + * pointer passed in means that we need to find out from the app + * what port to get stats for (used through board control device). + */ + +static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp) +{ + unsigned long flags; + struct stlibrd *brdp; + int rc; + + memset(&stli_comstats, 0, sizeof(comstats_t)); + + if (portp == NULL) + return -ENODEV; + brdp = stli_brds[portp->brdnr]; + if (brdp == NULL) + return -ENODEV; + + mutex_lock(&portp->port.mutex); + if (test_bit(BST_STARTED, &brdp->state)) { + if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS, + &stli_cdkstats, sizeof(asystats_t), 1)) < 0) { + mutex_unlock(&portp->port.mutex); + return rc; + } + } else { + memset(&stli_cdkstats, 0, sizeof(asystats_t)); + } + + stli_comstats.brd = portp->brdnr; + stli_comstats.panel = portp->panelnr; + stli_comstats.port = portp->portnr; + stli_comstats.state = portp->state; + stli_comstats.flags = portp->port.flags; + + spin_lock_irqsave(&brd_lock, flags); + if (tty != NULL) { + if (portp->port.tty == tty) { + stli_comstats.ttystate = tty->flags; + stli_comstats.rxbuffered = -1; + if (tty->termios != NULL) { + stli_comstats.cflags = tty->termios->c_cflag; + stli_comstats.iflags = tty->termios->c_iflag; + stli_comstats.oflags = tty->termios->c_oflag; + stli_comstats.lflags = tty->termios->c_lflag; + } + } + } + spin_unlock_irqrestore(&brd_lock, flags); + + stli_comstats.txtotal = stli_cdkstats.txchars; + stli_comstats.rxtotal = stli_cdkstats.rxchars + stli_cdkstats.ringover; + stli_comstats.txbuffered = stli_cdkstats.txringq; + stli_comstats.rxbuffered += stli_cdkstats.rxringq; + stli_comstats.rxoverrun = stli_cdkstats.overruns; + stli_comstats.rxparity = stli_cdkstats.parity; + stli_comstats.rxframing = stli_cdkstats.framing; + stli_comstats.rxlost = stli_cdkstats.ringover; + stli_comstats.rxbreaks = stli_cdkstats.rxbreaks; + stli_comstats.txbreaks = stli_cdkstats.txbreaks; + stli_comstats.txxon = stli_cdkstats.txstart; + stli_comstats.txxoff = stli_cdkstats.txstop; + stli_comstats.rxxon = stli_cdkstats.rxstart; + stli_comstats.rxxoff = stli_cdkstats.rxstop; + stli_comstats.rxrtsoff = stli_cdkstats.rtscnt / 2; + stli_comstats.rxrtson = stli_cdkstats.rtscnt - stli_comstats.rxrtsoff; + stli_comstats.modem = stli_cdkstats.dcdcnt; + stli_comstats.hwid = stli_cdkstats.hwid; + stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals); + mutex_unlock(&portp->port.mutex); + + return 0; +} + +/*****************************************************************************/ + +/* + * Return the port stats structure to user app. A NULL port struct + * pointer passed in means that we need to find out from the app + * what port to get stats for (used through board control device). + */ + +static int stli_getportstats(struct tty_struct *tty, struct stliport *portp, + comstats_t __user *cp) +{ + struct stlibrd *brdp; + int rc; + + if (!portp) { + if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t))) + return -EFAULT; + portp = stli_getport(stli_comstats.brd, stli_comstats.panel, + stli_comstats.port); + if (!portp) + return -ENODEV; + } + + brdp = stli_brds[portp->brdnr]; + if (!brdp) + return -ENODEV; + + if ((rc = stli_portcmdstats(tty, portp)) < 0) + return rc; + + return copy_to_user(cp, &stli_comstats, sizeof(comstats_t)) ? + -EFAULT : 0; +} + +/*****************************************************************************/ + +/* + * Clear the port stats structure. We also return it zeroed out... + */ + +static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp) +{ + struct stlibrd *brdp; + int rc; + + if (!portp) { + if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t))) + return -EFAULT; + portp = stli_getport(stli_comstats.brd, stli_comstats.panel, + stli_comstats.port); + if (!portp) + return -ENODEV; + } + + brdp = stli_brds[portp->brdnr]; + if (!brdp) + return -ENODEV; + + mutex_lock(&portp->port.mutex); + + if (test_bit(BST_STARTED, &brdp->state)) { + if ((rc = stli_cmdwait(brdp, portp, A_CLEARSTATS, NULL, 0, 0)) < 0) { + mutex_unlock(&portp->port.mutex); + return rc; + } + } + + memset(&stli_comstats, 0, sizeof(comstats_t)); + stli_comstats.brd = portp->brdnr; + stli_comstats.panel = portp->panelnr; + stli_comstats.port = portp->portnr; + mutex_unlock(&portp->port.mutex); + + if (copy_to_user(cp, &stli_comstats, sizeof(comstats_t))) + return -EFAULT; + return 0; +} + +/*****************************************************************************/ + +/* + * Return the entire driver ports structure to a user app. + */ + +static int stli_getportstruct(struct stliport __user *arg) +{ + struct stliport stli_dummyport; + struct stliport *portp; + + if (copy_from_user(&stli_dummyport, arg, sizeof(struct stliport))) + return -EFAULT; + portp = stli_getport(stli_dummyport.brdnr, stli_dummyport.panelnr, + stli_dummyport.portnr); + if (!portp) + return -ENODEV; + if (copy_to_user(arg, portp, sizeof(struct stliport))) + return -EFAULT; + return 0; +} + +/*****************************************************************************/ + +/* + * Return the entire driver board structure to a user app. + */ + +static int stli_getbrdstruct(struct stlibrd __user *arg) +{ + struct stlibrd stli_dummybrd; + struct stlibrd *brdp; + + if (copy_from_user(&stli_dummybrd, arg, sizeof(struct stlibrd))) + return -EFAULT; + if (stli_dummybrd.brdnr >= STL_MAXBRDS) + return -ENODEV; + brdp = stli_brds[stli_dummybrd.brdnr]; + if (!brdp) + return -ENODEV; + if (copy_to_user(arg, brdp, sizeof(struct stlibrd))) + return -EFAULT; + return 0; +} + +/*****************************************************************************/ + +/* + * The "staliomem" device is also required to do some special operations on + * the board. We need to be able to send an interrupt to the board, + * reset it, and start/stop it. + */ + +static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) +{ + struct stlibrd *brdp; + int brdnr, rc, done; + void __user *argp = (void __user *)arg; + +/* + * First up handle the board independent ioctls. + */ + done = 0; + rc = 0; + + switch (cmd) { + case COM_GETPORTSTATS: + rc = stli_getportstats(NULL, NULL, argp); + done++; + break; + case COM_CLRPORTSTATS: + rc = stli_clrportstats(NULL, argp); + done++; + break; + case COM_GETBRDSTATS: + rc = stli_getbrdstats(argp); + done++; + break; + case COM_READPORT: + rc = stli_getportstruct(argp); + done++; + break; + case COM_READBOARD: + rc = stli_getbrdstruct(argp); + done++; + break; + } + if (done) + return rc; + +/* + * Now handle the board specific ioctls. These all depend on the + * minor number of the device they were called from. + */ + brdnr = iminor(fp->f_dentry->d_inode); + if (brdnr >= STL_MAXBRDS) + return -ENODEV; + brdp = stli_brds[brdnr]; + if (!brdp) + return -ENODEV; + if (brdp->state == 0) + return -ENODEV; + + switch (cmd) { + case STL_BINTR: + EBRDINTR(brdp); + break; + case STL_BSTART: + rc = stli_startbrd(brdp); + break; + case STL_BSTOP: + clear_bit(BST_STARTED, &brdp->state); + break; + case STL_BRESET: + clear_bit(BST_STARTED, &brdp->state); + EBRDRESET(brdp); + if (stli_shared == 0) { + if (brdp->reenable != NULL) + (* brdp->reenable)(brdp); + } + break; + default: + rc = -ENOIOCTLCMD; + break; + } + return rc; +} + +static const struct tty_operations stli_ops = { + .open = stli_open, + .close = stli_close, + .write = stli_write, + .put_char = stli_putchar, + .flush_chars = stli_flushchars, + .write_room = stli_writeroom, + .chars_in_buffer = stli_charsinbuffer, + .ioctl = stli_ioctl, + .set_termios = stli_settermios, + .throttle = stli_throttle, + .unthrottle = stli_unthrottle, + .stop = stli_stop, + .start = stli_start, + .hangup = stli_hangup, + .flush_buffer = stli_flushbuffer, + .break_ctl = stli_breakctl, + .wait_until_sent = stli_waituntilsent, + .send_xchar = stli_sendxchar, + .tiocmget = stli_tiocmget, + .tiocmset = stli_tiocmset, + .proc_fops = &stli_proc_fops, +}; + +static const struct tty_port_operations stli_port_ops = { + .carrier_raised = stli_carrier_raised, + .dtr_rts = stli_dtr_rts, + .activate = stli_activate, + .shutdown = stli_shutdown, +}; + +/*****************************************************************************/ +/* + * Loadable module initialization stuff. + */ + +static void istallion_cleanup_isa(void) +{ + struct stlibrd *brdp; + unsigned int j; + + for (j = 0; (j < stli_nrbrds); j++) { + if ((brdp = stli_brds[j]) == NULL || + test_bit(BST_PROBED, &brdp->state)) + continue; + + stli_cleanup_ports(brdp); + + iounmap(brdp->membase); + if (brdp->iosize > 0) + release_region(brdp->iobase, brdp->iosize); + kfree(brdp); + stli_brds[j] = NULL; + } +} + +static int __init istallion_module_init(void) +{ + unsigned int i; + int retval; + + printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion); + + spin_lock_init(&stli_lock); + spin_lock_init(&brd_lock); + + stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); + if (!stli_txcookbuf) { + printk(KERN_ERR "istallion: failed to allocate memory " + "(size=%d)\n", STLI_TXBUFSIZE); + retval = -ENOMEM; + goto err; + } + + stli_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); + if (!stli_serial) { + retval = -ENOMEM; + goto err_free; + } + + stli_serial->owner = THIS_MODULE; + stli_serial->driver_name = stli_drvname; + stli_serial->name = stli_serialname; + stli_serial->major = STL_SERIALMAJOR; + stli_serial->minor_start = 0; + stli_serial->type = TTY_DRIVER_TYPE_SERIAL; + stli_serial->subtype = SERIAL_TYPE_NORMAL; + stli_serial->init_termios = stli_deftermios; + stli_serial->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + tty_set_operations(stli_serial, &stli_ops); + + retval = tty_register_driver(stli_serial); + if (retval) { + printk(KERN_ERR "istallion: failed to register serial driver\n"); + goto err_ttyput; + } + + retval = stli_initbrds(); + if (retval) + goto err_ttyunr; + +/* + * Set up a character driver for the shared memory region. We need this + * to down load the slave code image. Also it is a useful debugging tool. + */ + retval = register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stli_fsiomem); + if (retval) { + printk(KERN_ERR "istallion: failed to register serial memory " + "device\n"); + goto err_deinit; + } + + istallion_class = class_create(THIS_MODULE, "staliomem"); + for (i = 0; i < 4; i++) + device_create(istallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i), + NULL, "staliomem%d", i); + + return 0; +err_deinit: + pci_unregister_driver(&stli_pcidriver); + istallion_cleanup_isa(); +err_ttyunr: + tty_unregister_driver(stli_serial); +err_ttyput: + put_tty_driver(stli_serial); +err_free: + kfree(stli_txcookbuf); +err: + return retval; +} + +/*****************************************************************************/ + +static void __exit istallion_module_exit(void) +{ + unsigned int j; + + printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle, + stli_drvversion); + + if (stli_timeron) { + stli_timeron = 0; + del_timer_sync(&stli_timerlist); + } + + unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"); + + for (j = 0; j < 4; j++) + device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, j)); + class_destroy(istallion_class); + + pci_unregister_driver(&stli_pcidriver); + istallion_cleanup_isa(); + + tty_unregister_driver(stli_serial); + put_tty_driver(stli_serial); + + kfree(stli_txcookbuf); +} + +module_init(istallion_module_init); +module_exit(istallion_module_exit); diff --git a/drivers/staging/tty/riscom8.c b/drivers/staging/tty/riscom8.c new file mode 100644 index 000000000000..602643a40b4b --- /dev/null +++ b/drivers/staging/tty/riscom8.c @@ -0,0 +1,1560 @@ +/* + * linux/drivers/char/riscom.c -- RISCom/8 multiport serial driver. + * + * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) + * + * This code is loosely based on the Linux serial driver, written by + * Linus Torvalds, Theodore T'so and others. The RISCom/8 card + * programming info was obtained from various drivers for other OSes + * (FreeBSD, ISC, etc), but no source code from those drivers were + * directly included in this driver. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Revision 1.1 + * + * ChangeLog: + * Arnaldo Carvalho de Melo - 27-Jun-2001 + * - get rid of check_region and several cleanups + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "riscom8.h" +#include "riscom8_reg.h" + +/* Am I paranoid or not ? ;-) */ +#define RISCOM_PARANOIA_CHECK + +/* + * Crazy InteliCom/8 boards sometimes have swapped CTS & DSR signals. + * You can slightly speed up things by #undefing the following option, + * if you are REALLY sure that your board is correct one. + */ + +#define RISCOM_BRAIN_DAMAGED_CTS + +/* + * The following defines are mostly for testing purposes. But if you need + * some nice reporting in your syslog, you can define them also. + */ +#undef RC_REPORT_FIFO +#undef RC_REPORT_OVERRUN + + +#define RISCOM_LEGAL_FLAGS \ + (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \ + ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \ + ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP) + +static struct tty_driver *riscom_driver; + +static DEFINE_SPINLOCK(riscom_lock); + +static struct riscom_board rc_board[RC_NBOARD] = { + { + .base = RC_IOBASE1, + }, + { + .base = RC_IOBASE2, + }, + { + .base = RC_IOBASE3, + }, + { + .base = RC_IOBASE4, + }, +}; + +static struct riscom_port rc_port[RC_NBOARD * RC_NPORT]; + +/* RISCom/8 I/O ports addresses (without address translation) */ +static unsigned short rc_ioport[] = { +#if 1 + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c, +#else + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c, 0x10, + 0x11, 0x12, 0x18, 0x28, 0x31, 0x32, 0x39, 0x3a, 0x40, 0x41, 0x61, 0x62, + 0x63, 0x64, 0x6b, 0x70, 0x71, 0x78, 0x7a, 0x7b, 0x7f, 0x100, 0x101 +#endif +}; +#define RC_NIOPORT ARRAY_SIZE(rc_ioport) + + +static int rc_paranoia_check(struct riscom_port const *port, + char *name, const char *routine) +{ +#ifdef RISCOM_PARANOIA_CHECK + static const char badmagic[] = KERN_INFO + "rc: Warning: bad riscom port magic number for device %s in %s\n"; + static const char badinfo[] = KERN_INFO + "rc: Warning: null riscom port for device %s in %s\n"; + + if (!port) { + printk(badinfo, name, routine); + return 1; + } + if (port->magic != RISCOM8_MAGIC) { + printk(badmagic, name, routine); + return 1; + } +#endif + return 0; +} + +/* + * + * Service functions for RISCom/8 driver. + * + */ + +/* Get board number from pointer */ +static inline int board_No(struct riscom_board const *bp) +{ + return bp - rc_board; +} + +/* Get port number from pointer */ +static inline int port_No(struct riscom_port const *port) +{ + return RC_PORT(port - rc_port); +} + +/* Get pointer to board from pointer to port */ +static inline struct riscom_board *port_Board(struct riscom_port const *port) +{ + return &rc_board[RC_BOARD(port - rc_port)]; +} + +/* Input Byte from CL CD180 register */ +static inline unsigned char rc_in(struct riscom_board const *bp, + unsigned short reg) +{ + return inb(bp->base + RC_TO_ISA(reg)); +} + +/* Output Byte to CL CD180 register */ +static inline void rc_out(struct riscom_board const *bp, unsigned short reg, + unsigned char val) +{ + outb(val, bp->base + RC_TO_ISA(reg)); +} + +/* Wait for Channel Command Register ready */ +static void rc_wait_CCR(struct riscom_board const *bp) +{ + unsigned long delay; + + /* FIXME: need something more descriptive then 100000 :) */ + for (delay = 100000; delay; delay--) + if (!rc_in(bp, CD180_CCR)) + return; + + printk(KERN_INFO "rc%d: Timeout waiting for CCR.\n", board_No(bp)); +} + +/* + * RISCom/8 probe functions. + */ + +static int rc_request_io_range(struct riscom_board * const bp) +{ + int i; + + for (i = 0; i < RC_NIOPORT; i++) + if (!request_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1, + "RISCom/8")) { + goto out_release; + } + return 0; +out_release: + printk(KERN_INFO "rc%d: Skipping probe at 0x%03x. IO address in use.\n", + board_No(bp), bp->base); + while (--i >= 0) + release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1); + return 1; +} + +static void rc_release_io_range(struct riscom_board * const bp) +{ + int i; + + for (i = 0; i < RC_NIOPORT; i++) + release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1); +} + +/* Reset and setup CD180 chip */ +static void __init rc_init_CD180(struct riscom_board const *bp) +{ + unsigned long flags; + + spin_lock_irqsave(&riscom_lock, flags); + + rc_out(bp, RC_CTOUT, 0); /* Clear timeout */ + rc_wait_CCR(bp); /* Wait for CCR ready */ + rc_out(bp, CD180_CCR, CCR_HARDRESET); /* Reset CD180 chip */ + spin_unlock_irqrestore(&riscom_lock, flags); + msleep(50); /* Delay 0.05 sec */ + spin_lock_irqsave(&riscom_lock, flags); + rc_out(bp, CD180_GIVR, RC_ID); /* Set ID for this chip */ + rc_out(bp, CD180_GICR, 0); /* Clear all bits */ + rc_out(bp, CD180_PILR1, RC_ACK_MINT); /* Prio for modem intr */ + rc_out(bp, CD180_PILR2, RC_ACK_TINT); /* Prio for tx intr */ + rc_out(bp, CD180_PILR3, RC_ACK_RINT); /* Prio for rx intr */ + + /* Setting up prescaler. We need 4 ticks per 1 ms */ + rc_out(bp, CD180_PPRH, (RC_OSCFREQ/(1000000/RISCOM_TPS)) >> 8); + rc_out(bp, CD180_PPRL, (RC_OSCFREQ/(1000000/RISCOM_TPS)) & 0xff); + + spin_unlock_irqrestore(&riscom_lock, flags); +} + +/* Main probing routine, also sets irq. */ +static int __init rc_probe(struct riscom_board *bp) +{ + unsigned char val1, val2; + int irqs = 0; + int retries; + + bp->irq = 0; + + if (rc_request_io_range(bp)) + return 1; + + /* Are the I/O ports here ? */ + rc_out(bp, CD180_PPRL, 0x5a); + outb(0xff, 0x80); + val1 = rc_in(bp, CD180_PPRL); + rc_out(bp, CD180_PPRL, 0xa5); + outb(0x00, 0x80); + val2 = rc_in(bp, CD180_PPRL); + + if ((val1 != 0x5a) || (val2 != 0xa5)) { + printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not found.\n", + board_No(bp), bp->base); + goto out_release; + } + + /* It's time to find IRQ for this board */ + for (retries = 0; retries < 5 && irqs <= 0; retries++) { + irqs = probe_irq_on(); + rc_init_CD180(bp); /* Reset CD180 chip */ + rc_out(bp, CD180_CAR, 2); /* Select port 2 */ + rc_wait_CCR(bp); + rc_out(bp, CD180_CCR, CCR_TXEN); /* Enable transmitter */ + rc_out(bp, CD180_IER, IER_TXRDY);/* Enable tx empty intr */ + msleep(50); + irqs = probe_irq_off(irqs); + val1 = rc_in(bp, RC_BSR); /* Get Board Status reg */ + val2 = rc_in(bp, RC_ACK_TINT); /* ACK interrupt */ + rc_init_CD180(bp); /* Reset CD180 again */ + + if ((val1 & RC_BSR_TINT) || (val2 != (RC_ID | GIVR_IT_TX))) { + printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not " + "found.\n", board_No(bp), bp->base); + goto out_release; + } + } + + if (irqs <= 0) { + printk(KERN_ERR "rc%d: Can't find IRQ for RISCom/8 board " + "at 0x%03x.\n", board_No(bp), bp->base); + goto out_release; + } + bp->irq = irqs; + bp->flags |= RC_BOARD_PRESENT; + + printk(KERN_INFO "rc%d: RISCom/8 Rev. %c board detected at " + "0x%03x, IRQ %d.\n", + board_No(bp), + (rc_in(bp, CD180_GFRCR) & 0x0f) + 'A', /* Board revision */ + bp->base, bp->irq); + + return 0; +out_release: + rc_release_io_range(bp); + return 1; +} + +/* + * + * Interrupt processing routines. + * + */ + +static struct riscom_port *rc_get_port(struct riscom_board const *bp, + unsigned char const *what) +{ + unsigned char channel; + struct riscom_port *port; + + channel = rc_in(bp, CD180_GICR) >> GICR_CHAN_OFF; + if (channel < CD180_NCH) { + port = &rc_port[board_No(bp) * RC_NPORT + channel]; + if (port->port.flags & ASYNC_INITIALIZED) + return port; + } + printk(KERN_ERR "rc%d: %s interrupt from invalid port %d\n", + board_No(bp), what, channel); + return NULL; +} + +static void rc_receive_exc(struct riscom_board const *bp) +{ + struct riscom_port *port; + struct tty_struct *tty; + unsigned char status; + unsigned char ch, flag; + + port = rc_get_port(bp, "Receive"); + if (port == NULL) + return; + + tty = tty_port_tty_get(&port->port); + +#ifdef RC_REPORT_OVERRUN + status = rc_in(bp, CD180_RCSR); + if (status & RCSR_OE) + port->overrun++; + status &= port->mark_mask; +#else + status = rc_in(bp, CD180_RCSR) & port->mark_mask; +#endif + ch = rc_in(bp, CD180_RDR); + if (!status) + goto out; + if (status & RCSR_TOUT) { + printk(KERN_WARNING "rc%d: port %d: Receiver timeout. " + "Hardware problems ?\n", + board_No(bp), port_No(port)); + goto out; + + } else if (status & RCSR_BREAK) { + printk(KERN_INFO "rc%d: port %d: Handling break...\n", + board_No(bp), port_No(port)); + flag = TTY_BREAK; + if (tty && (port->port.flags & ASYNC_SAK)) + do_SAK(tty); + + } else if (status & RCSR_PE) + flag = TTY_PARITY; + + else if (status & RCSR_FE) + flag = TTY_FRAME; + + else if (status & RCSR_OE) + flag = TTY_OVERRUN; + else + flag = TTY_NORMAL; + + if (tty) { + tty_insert_flip_char(tty, ch, flag); + tty_flip_buffer_push(tty); + } +out: + tty_kref_put(tty); +} + +static void rc_receive(struct riscom_board const *bp) +{ + struct riscom_port *port; + struct tty_struct *tty; + unsigned char count; + + port = rc_get_port(bp, "Receive"); + if (port == NULL) + return; + + tty = tty_port_tty_get(&port->port); + + count = rc_in(bp, CD180_RDCR); + +#ifdef RC_REPORT_FIFO + port->hits[count > 8 ? 9 : count]++; +#endif + + while (count--) { + u8 ch = rc_in(bp, CD180_RDR); + if (tty) + tty_insert_flip_char(tty, ch, TTY_NORMAL); + } + if (tty) { + tty_flip_buffer_push(tty); + tty_kref_put(tty); + } +} + +static void rc_transmit(struct riscom_board const *bp) +{ + struct riscom_port *port; + struct tty_struct *tty; + unsigned char count; + + port = rc_get_port(bp, "Transmit"); + if (port == NULL) + return; + + tty = tty_port_tty_get(&port->port); + + if (port->IER & IER_TXEMPTY) { + /* FIFO drained */ + rc_out(bp, CD180_CAR, port_No(port)); + port->IER &= ~IER_TXEMPTY; + rc_out(bp, CD180_IER, port->IER); + goto out; + } + + if ((port->xmit_cnt <= 0 && !port->break_length) + || (tty && (tty->stopped || tty->hw_stopped))) { + rc_out(bp, CD180_CAR, port_No(port)); + port->IER &= ~IER_TXRDY; + rc_out(bp, CD180_IER, port->IER); + goto out; + } + + if (port->break_length) { + if (port->break_length > 0) { + if (port->COR2 & COR2_ETC) { + rc_out(bp, CD180_TDR, CD180_C_ESC); + rc_out(bp, CD180_TDR, CD180_C_SBRK); + port->COR2 &= ~COR2_ETC; + } + count = min_t(int, port->break_length, 0xff); + rc_out(bp, CD180_TDR, CD180_C_ESC); + rc_out(bp, CD180_TDR, CD180_C_DELAY); + rc_out(bp, CD180_TDR, count); + port->break_length -= count; + if (port->break_length == 0) + port->break_length--; + } else { + rc_out(bp, CD180_TDR, CD180_C_ESC); + rc_out(bp, CD180_TDR, CD180_C_EBRK); + rc_out(bp, CD180_COR2, port->COR2); + rc_wait_CCR(bp); + rc_out(bp, CD180_CCR, CCR_CORCHG2); + port->break_length = 0; + } + goto out; + } + + count = CD180_NFIFO; + do { + rc_out(bp, CD180_TDR, port->port.xmit_buf[port->xmit_tail++]); + port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1); + if (--port->xmit_cnt <= 0) + break; + } while (--count > 0); + + if (port->xmit_cnt <= 0) { + rc_out(bp, CD180_CAR, port_No(port)); + port->IER &= ~IER_TXRDY; + rc_out(bp, CD180_IER, port->IER); + } + if (tty && port->xmit_cnt <= port->wakeup_chars) + tty_wakeup(tty); +out: + tty_kref_put(tty); +} + +static void rc_check_modem(struct riscom_board const *bp) +{ + struct riscom_port *port; + struct tty_struct *tty; + unsigned char mcr; + + port = rc_get_port(bp, "Modem"); + if (port == NULL) + return; + + tty = tty_port_tty_get(&port->port); + + mcr = rc_in(bp, CD180_MCR); + if (mcr & MCR_CDCHG) { + if (rc_in(bp, CD180_MSVR) & MSVR_CD) + wake_up_interruptible(&port->port.open_wait); + else if (tty) + tty_hangup(tty); + } + +#ifdef RISCOM_BRAIN_DAMAGED_CTS + if (mcr & MCR_CTSCHG) { + if (rc_in(bp, CD180_MSVR) & MSVR_CTS) { + port->IER |= IER_TXRDY; + if (tty) { + tty->hw_stopped = 0; + if (port->xmit_cnt <= port->wakeup_chars) + tty_wakeup(tty); + } + } else { + if (tty) + tty->hw_stopped = 1; + port->IER &= ~IER_TXRDY; + } + rc_out(bp, CD180_IER, port->IER); + } + if (mcr & MCR_DSRCHG) { + if (rc_in(bp, CD180_MSVR) & MSVR_DSR) { + port->IER |= IER_TXRDY; + if (tty) { + tty->hw_stopped = 0; + if (port->xmit_cnt <= port->wakeup_chars) + tty_wakeup(tty); + } + } else { + if (tty) + tty->hw_stopped = 1; + port->IER &= ~IER_TXRDY; + } + rc_out(bp, CD180_IER, port->IER); + } +#endif /* RISCOM_BRAIN_DAMAGED_CTS */ + + /* Clear change bits */ + rc_out(bp, CD180_MCR, 0); + tty_kref_put(tty); +} + +/* The main interrupt processing routine */ +static irqreturn_t rc_interrupt(int dummy, void *dev_id) +{ + unsigned char status; + unsigned char ack; + struct riscom_board *bp = dev_id; + unsigned long loop = 0; + int handled = 0; + + if (!(bp->flags & RC_BOARD_ACTIVE)) + return IRQ_NONE; + + while ((++loop < 16) && ((status = ~(rc_in(bp, RC_BSR))) & + (RC_BSR_TOUT | RC_BSR_TINT | + RC_BSR_MINT | RC_BSR_RINT))) { + handled = 1; + if (status & RC_BSR_TOUT) + printk(KERN_WARNING "rc%d: Got timeout. Hardware " + "error?\n", board_No(bp)); + else if (status & RC_BSR_RINT) { + ack = rc_in(bp, RC_ACK_RINT); + if (ack == (RC_ID | GIVR_IT_RCV)) + rc_receive(bp); + else if (ack == (RC_ID | GIVR_IT_REXC)) + rc_receive_exc(bp); + else + printk(KERN_WARNING "rc%d: Bad receive ack " + "0x%02x.\n", + board_No(bp), ack); + } else if (status & RC_BSR_TINT) { + ack = rc_in(bp, RC_ACK_TINT); + if (ack == (RC_ID | GIVR_IT_TX)) + rc_transmit(bp); + else + printk(KERN_WARNING "rc%d: Bad transmit ack " + "0x%02x.\n", + board_No(bp), ack); + } else /* if (status & RC_BSR_MINT) */ { + ack = rc_in(bp, RC_ACK_MINT); + if (ack == (RC_ID | GIVR_IT_MODEM)) + rc_check_modem(bp); + else + printk(KERN_WARNING "rc%d: Bad modem ack " + "0x%02x.\n", + board_No(bp), ack); + } + rc_out(bp, CD180_EOIR, 0); /* Mark end of interrupt */ + rc_out(bp, RC_CTOUT, 0); /* Clear timeout flag */ + } + return IRQ_RETVAL(handled); +} + +/* + * Routines for open & close processing. + */ + +/* Called with disabled interrupts */ +static int rc_setup_board(struct riscom_board *bp) +{ + int error; + + if (bp->flags & RC_BOARD_ACTIVE) + return 0; + + error = request_irq(bp->irq, rc_interrupt, IRQF_DISABLED, + "RISCom/8", bp); + if (error) + return error; + + rc_out(bp, RC_CTOUT, 0); /* Just in case */ + bp->DTR = ~0; + rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */ + + bp->flags |= RC_BOARD_ACTIVE; + + return 0; +} + +/* Called with disabled interrupts */ +static void rc_shutdown_board(struct riscom_board *bp) +{ + if (!(bp->flags & RC_BOARD_ACTIVE)) + return; + + bp->flags &= ~RC_BOARD_ACTIVE; + + free_irq(bp->irq, NULL); + + bp->DTR = ~0; + rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */ + +} + +/* + * Setting up port characteristics. + * Must be called with disabled interrupts + */ +static void rc_change_speed(struct tty_struct *tty, struct riscom_board *bp, + struct riscom_port *port) +{ + unsigned long baud; + long tmp; + unsigned char cor1 = 0, cor3 = 0; + unsigned char mcor1 = 0, mcor2 = 0; + + port->IER = 0; + port->COR2 = 0; + port->MSVR = MSVR_RTS; + + baud = tty_get_baud_rate(tty); + + /* Select port on the board */ + rc_out(bp, CD180_CAR, port_No(port)); + + if (!baud) { + /* Drop DTR & exit */ + bp->DTR |= (1u << port_No(port)); + rc_out(bp, RC_DTR, bp->DTR); + return; + } else { + /* Set DTR on */ + bp->DTR &= ~(1u << port_No(port)); + rc_out(bp, RC_DTR, bp->DTR); + } + + /* + * Now we must calculate some speed depended things + */ + + /* Set baud rate for port */ + tmp = (((RC_OSCFREQ + baud/2) / baud + + CD180_TPC/2) / CD180_TPC); + + rc_out(bp, CD180_RBPRH, (tmp >> 8) & 0xff); + rc_out(bp, CD180_TBPRH, (tmp >> 8) & 0xff); + rc_out(bp, CD180_RBPRL, tmp & 0xff); + rc_out(bp, CD180_TBPRL, tmp & 0xff); + + baud = (baud + 5) / 10; /* Estimated CPS */ + + /* Two timer ticks seems enough to wakeup something like SLIP driver */ + tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO; + port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ? + SERIAL_XMIT_SIZE - 1 : tmp); + + /* Receiver timeout will be transmission time for 1.5 chars */ + tmp = (RISCOM_TPS + RISCOM_TPS/2 + baud/2) / baud; + tmp = (tmp > 0xff) ? 0xff : tmp; + rc_out(bp, CD180_RTPR, tmp); + + switch (C_CSIZE(tty)) { + case CS5: + cor1 |= COR1_5BITS; + break; + case CS6: + cor1 |= COR1_6BITS; + break; + case CS7: + cor1 |= COR1_7BITS; + break; + case CS8: + cor1 |= COR1_8BITS; + break; + } + if (C_CSTOPB(tty)) + cor1 |= COR1_2SB; + + cor1 |= COR1_IGNORE; + if (C_PARENB(tty)) { + cor1 |= COR1_NORMPAR; + if (C_PARODD(tty)) + cor1 |= COR1_ODDP; + if (I_INPCK(tty)) + cor1 &= ~COR1_IGNORE; + } + /* Set marking of some errors */ + port->mark_mask = RCSR_OE | RCSR_TOUT; + if (I_INPCK(tty)) + port->mark_mask |= RCSR_FE | RCSR_PE; + if (I_BRKINT(tty) || I_PARMRK(tty)) + port->mark_mask |= RCSR_BREAK; + if (I_IGNPAR(tty)) + port->mark_mask &= ~(RCSR_FE | RCSR_PE); + if (I_IGNBRK(tty)) { + port->mark_mask &= ~RCSR_BREAK; + if (I_IGNPAR(tty)) + /* Real raw mode. Ignore all */ + port->mark_mask &= ~RCSR_OE; + } + /* Enable Hardware Flow Control */ + if (C_CRTSCTS(tty)) { +#ifdef RISCOM_BRAIN_DAMAGED_CTS + port->IER |= IER_DSR | IER_CTS; + mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD; + mcor2 |= MCOR2_DSROD | MCOR2_CTSOD; + tty->hw_stopped = !(rc_in(bp, CD180_MSVR) & + (MSVR_CTS|MSVR_DSR)); +#else + port->COR2 |= COR2_CTSAE; +#endif + } + /* Enable Software Flow Control. FIXME: I'm not sure about this */ + /* Some people reported that it works, but I still doubt */ + if (I_IXON(tty)) { + port->COR2 |= COR2_TXIBE; + cor3 |= (COR3_FCT | COR3_SCDE); + if (I_IXANY(tty)) + port->COR2 |= COR2_IXM; + rc_out(bp, CD180_SCHR1, START_CHAR(tty)); + rc_out(bp, CD180_SCHR2, STOP_CHAR(tty)); + rc_out(bp, CD180_SCHR3, START_CHAR(tty)); + rc_out(bp, CD180_SCHR4, STOP_CHAR(tty)); + } + if (!C_CLOCAL(tty)) { + /* Enable CD check */ + port->IER |= IER_CD; + mcor1 |= MCOR1_CDZD; + mcor2 |= MCOR2_CDOD; + } + + if (C_CREAD(tty)) + /* Enable receiver */ + port->IER |= IER_RXD; + + /* Set input FIFO size (1-8 bytes) */ + cor3 |= RISCOM_RXFIFO; + /* Setting up CD180 channel registers */ + rc_out(bp, CD180_COR1, cor1); + rc_out(bp, CD180_COR2, port->COR2); + rc_out(bp, CD180_COR3, cor3); + /* Make CD180 know about registers change */ + rc_wait_CCR(bp); + rc_out(bp, CD180_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3); + /* Setting up modem option registers */ + rc_out(bp, CD180_MCOR1, mcor1); + rc_out(bp, CD180_MCOR2, mcor2); + /* Enable CD180 transmitter & receiver */ + rc_wait_CCR(bp); + rc_out(bp, CD180_CCR, CCR_TXEN | CCR_RXEN); + /* Enable interrupts */ + rc_out(bp, CD180_IER, port->IER); + /* And finally set RTS on */ + rc_out(bp, CD180_MSVR, port->MSVR); +} + +/* Must be called with interrupts enabled */ +static int rc_activate_port(struct tty_port *port, struct tty_struct *tty) +{ + struct riscom_port *rp = container_of(port, struct riscom_port, port); + struct riscom_board *bp = port_Board(rp); + unsigned long flags; + + if (tty_port_alloc_xmit_buf(port) < 0) + return -ENOMEM; + + spin_lock_irqsave(&riscom_lock, flags); + + clear_bit(TTY_IO_ERROR, &tty->flags); + bp->count++; + rp->xmit_cnt = rp->xmit_head = rp->xmit_tail = 0; + rc_change_speed(tty, bp, rp); + spin_unlock_irqrestore(&riscom_lock, flags); + return 0; +} + +/* Must be called with interrupts disabled */ +static void rc_shutdown_port(struct tty_struct *tty, + struct riscom_board *bp, struct riscom_port *port) +{ +#ifdef RC_REPORT_OVERRUN + printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n", + board_No(bp), port_No(port), port->overrun); +#endif +#ifdef RC_REPORT_FIFO + { + int i; + + printk(KERN_INFO "rc%d: port %d: FIFO hits [ ", + board_No(bp), port_No(port)); + for (i = 0; i < 10; i++) + printk("%ld ", port->hits[i]); + printk("].\n"); + } +#endif + tty_port_free_xmit_buf(&port->port); + + /* Select port */ + rc_out(bp, CD180_CAR, port_No(port)); + /* Reset port */ + rc_wait_CCR(bp); + rc_out(bp, CD180_CCR, CCR_SOFTRESET); + /* Disable all interrupts from this port */ + port->IER = 0; + rc_out(bp, CD180_IER, port->IER); + + set_bit(TTY_IO_ERROR, &tty->flags); + + if (--bp->count < 0) { + printk(KERN_INFO "rc%d: rc_shutdown_port: " + "bad board count: %d\n", + board_No(bp), bp->count); + bp->count = 0; + } + /* + * If this is the last opened port on the board + * shutdown whole board + */ + if (!bp->count) + rc_shutdown_board(bp); +} + +static int carrier_raised(struct tty_port *port) +{ + struct riscom_port *p = container_of(port, struct riscom_port, port); + struct riscom_board *bp = port_Board(p); + unsigned long flags; + int CD; + + spin_lock_irqsave(&riscom_lock, flags); + rc_out(bp, CD180_CAR, port_No(p)); + CD = rc_in(bp, CD180_MSVR) & MSVR_CD; + rc_out(bp, CD180_MSVR, MSVR_RTS); + bp->DTR &= ~(1u << port_No(p)); + rc_out(bp, RC_DTR, bp->DTR); + spin_unlock_irqrestore(&riscom_lock, flags); + return CD; +} + +static void dtr_rts(struct tty_port *port, int onoff) +{ + struct riscom_port *p = container_of(port, struct riscom_port, port); + struct riscom_board *bp = port_Board(p); + unsigned long flags; + + spin_lock_irqsave(&riscom_lock, flags); + bp->DTR &= ~(1u << port_No(p)); + if (onoff == 0) + bp->DTR |= (1u << port_No(p)); + rc_out(bp, RC_DTR, bp->DTR); + spin_unlock_irqrestore(&riscom_lock, flags); +} + +static int rc_open(struct tty_struct *tty, struct file *filp) +{ + int board; + int error; + struct riscom_port *port; + struct riscom_board *bp; + + board = RC_BOARD(tty->index); + if (board >= RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT)) + return -ENODEV; + + bp = &rc_board[board]; + port = rc_port + board * RC_NPORT + RC_PORT(tty->index); + if (rc_paranoia_check(port, tty->name, "rc_open")) + return -ENODEV; + + error = rc_setup_board(bp); + if (error) + return error; + + tty->driver_data = port; + return tty_port_open(&port->port, tty, filp); +} + +static void rc_flush_buffer(struct tty_struct *tty) +{ + struct riscom_port *port = tty->driver_data; + unsigned long flags; + + if (rc_paranoia_check(port, tty->name, "rc_flush_buffer")) + return; + + spin_lock_irqsave(&riscom_lock, flags); + port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; + spin_unlock_irqrestore(&riscom_lock, flags); + + tty_wakeup(tty); +} + +static void rc_close_port(struct tty_port *port) +{ + unsigned long flags; + struct riscom_port *rp = container_of(port, struct riscom_port, port); + struct riscom_board *bp = port_Board(rp); + unsigned long timeout; + + /* + * At this point we stop accepting input. To do this, we + * disable the receive line status interrupts, and tell the + * interrupt driver to stop checking the data ready bit in the + * line status register. + */ + + spin_lock_irqsave(&riscom_lock, flags); + rp->IER &= ~IER_RXD; + + rp->IER &= ~IER_TXRDY; + rp->IER |= IER_TXEMPTY; + rc_out(bp, CD180_CAR, port_No(rp)); + rc_out(bp, CD180_IER, rp->IER); + /* + * Before we drop DTR, make sure the UART transmitter + * has completely drained; this is especially + * important if there is a transmit FIFO! + */ + timeout = jiffies + HZ; + while (rp->IER & IER_TXEMPTY) { + spin_unlock_irqrestore(&riscom_lock, flags); + msleep_interruptible(jiffies_to_msecs(rp->timeout)); + spin_lock_irqsave(&riscom_lock, flags); + if (time_after(jiffies, timeout)) + break; + } + rc_shutdown_port(port->tty, bp, rp); + spin_unlock_irqrestore(&riscom_lock, flags); +} + +static void rc_close(struct tty_struct *tty, struct file *filp) +{ + struct riscom_port *port = tty->driver_data; + + if (!port || rc_paranoia_check(port, tty->name, "close")) + return; + tty_port_close(&port->port, tty, filp); +} + +static int rc_write(struct tty_struct *tty, + const unsigned char *buf, int count) +{ + struct riscom_port *port = tty->driver_data; + struct riscom_board *bp; + int c, total = 0; + unsigned long flags; + + if (rc_paranoia_check(port, tty->name, "rc_write")) + return 0; + + bp = port_Board(port); + + while (1) { + spin_lock_irqsave(&riscom_lock, flags); + + c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, + SERIAL_XMIT_SIZE - port->xmit_head)); + if (c <= 0) + break; /* lock continues to be held */ + + memcpy(port->port.xmit_buf + port->xmit_head, buf, c); + port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); + port->xmit_cnt += c; + + spin_unlock_irqrestore(&riscom_lock, flags); + + buf += c; + count -= c; + total += c; + } + + if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped && + !(port->IER & IER_TXRDY)) { + port->IER |= IER_TXRDY; + rc_out(bp, CD180_CAR, port_No(port)); + rc_out(bp, CD180_IER, port->IER); + } + + spin_unlock_irqrestore(&riscom_lock, flags); + + return total; +} + +static int rc_put_char(struct tty_struct *tty, unsigned char ch) +{ + struct riscom_port *port = tty->driver_data; + unsigned long flags; + int ret = 0; + + if (rc_paranoia_check(port, tty->name, "rc_put_char")) + return 0; + + spin_lock_irqsave(&riscom_lock, flags); + + if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) + goto out; + + port->port.xmit_buf[port->xmit_head++] = ch; + port->xmit_head &= SERIAL_XMIT_SIZE - 1; + port->xmit_cnt++; + ret = 1; + +out: + spin_unlock_irqrestore(&riscom_lock, flags); + return ret; +} + +static void rc_flush_chars(struct tty_struct *tty) +{ + struct riscom_port *port = tty->driver_data; + unsigned long flags; + + if (rc_paranoia_check(port, tty->name, "rc_flush_chars")) + return; + + if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped) + return; + + spin_lock_irqsave(&riscom_lock, flags); + + port->IER |= IER_TXRDY; + rc_out(port_Board(port), CD180_CAR, port_No(port)); + rc_out(port_Board(port), CD180_IER, port->IER); + + spin_unlock_irqrestore(&riscom_lock, flags); +} + +static int rc_write_room(struct tty_struct *tty) +{ + struct riscom_port *port = tty->driver_data; + int ret; + + if (rc_paranoia_check(port, tty->name, "rc_write_room")) + return 0; + + ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1; + if (ret < 0) + ret = 0; + return ret; +} + +static int rc_chars_in_buffer(struct tty_struct *tty) +{ + struct riscom_port *port = tty->driver_data; + + if (rc_paranoia_check(port, tty->name, "rc_chars_in_buffer")) + return 0; + + return port->xmit_cnt; +} + +static int rc_tiocmget(struct tty_struct *tty) +{ + struct riscom_port *port = tty->driver_data; + struct riscom_board *bp; + unsigned char status; + unsigned int result; + unsigned long flags; + + if (rc_paranoia_check(port, tty->name, __func__)) + return -ENODEV; + + bp = port_Board(port); + + spin_lock_irqsave(&riscom_lock, flags); + + rc_out(bp, CD180_CAR, port_No(port)); + status = rc_in(bp, CD180_MSVR); + result = rc_in(bp, RC_RI) & (1u << port_No(port)) ? 0 : TIOCM_RNG; + + spin_unlock_irqrestore(&riscom_lock, flags); + + result |= ((status & MSVR_RTS) ? TIOCM_RTS : 0) + | ((status & MSVR_DTR) ? TIOCM_DTR : 0) + | ((status & MSVR_CD) ? TIOCM_CAR : 0) + | ((status & MSVR_DSR) ? TIOCM_DSR : 0) + | ((status & MSVR_CTS) ? TIOCM_CTS : 0); + return result; +} + +static int rc_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + struct riscom_port *port = tty->driver_data; + unsigned long flags; + struct riscom_board *bp; + + if (rc_paranoia_check(port, tty->name, __func__)) + return -ENODEV; + + bp = port_Board(port); + + spin_lock_irqsave(&riscom_lock, flags); + + if (set & TIOCM_RTS) + port->MSVR |= MSVR_RTS; + if (set & TIOCM_DTR) + bp->DTR &= ~(1u << port_No(port)); + + if (clear & TIOCM_RTS) + port->MSVR &= ~MSVR_RTS; + if (clear & TIOCM_DTR) + bp->DTR |= (1u << port_No(port)); + + rc_out(bp, CD180_CAR, port_No(port)); + rc_out(bp, CD180_MSVR, port->MSVR); + rc_out(bp, RC_DTR, bp->DTR); + + spin_unlock_irqrestore(&riscom_lock, flags); + + return 0; +} + +static int rc_send_break(struct tty_struct *tty, int length) +{ + struct riscom_port *port = tty->driver_data; + struct riscom_board *bp = port_Board(port); + unsigned long flags; + + if (length == 0 || length == -1) + return -EOPNOTSUPP; + + spin_lock_irqsave(&riscom_lock, flags); + + port->break_length = RISCOM_TPS / HZ * length; + port->COR2 |= COR2_ETC; + port->IER |= IER_TXRDY; + rc_out(bp, CD180_CAR, port_No(port)); + rc_out(bp, CD180_COR2, port->COR2); + rc_out(bp, CD180_IER, port->IER); + rc_wait_CCR(bp); + rc_out(bp, CD180_CCR, CCR_CORCHG2); + rc_wait_CCR(bp); + + spin_unlock_irqrestore(&riscom_lock, flags); + return 0; +} + +static int rc_set_serial_info(struct tty_struct *tty, struct riscom_port *port, + struct serial_struct __user *newinfo) +{ + struct serial_struct tmp; + struct riscom_board *bp = port_Board(port); + int change_speed; + + if (copy_from_user(&tmp, newinfo, sizeof(tmp))) + return -EFAULT; + + mutex_lock(&port->port.mutex); + change_speed = ((port->port.flags & ASYNC_SPD_MASK) != + (tmp.flags & ASYNC_SPD_MASK)); + + if (!capable(CAP_SYS_ADMIN)) { + if ((tmp.close_delay != port->port.close_delay) || + (tmp.closing_wait != port->port.closing_wait) || + ((tmp.flags & ~ASYNC_USR_MASK) != + (port->port.flags & ~ASYNC_USR_MASK))) { + mutex_unlock(&port->port.mutex); + return -EPERM; + } + port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | + (tmp.flags & ASYNC_USR_MASK)); + } else { + port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) | + (tmp.flags & ASYNC_FLAGS)); + port->port.close_delay = tmp.close_delay; + port->port.closing_wait = tmp.closing_wait; + } + if (change_speed) { + unsigned long flags; + + spin_lock_irqsave(&riscom_lock, flags); + rc_change_speed(tty, bp, port); + spin_unlock_irqrestore(&riscom_lock, flags); + } + mutex_unlock(&port->port.mutex); + return 0; +} + +static int rc_get_serial_info(struct riscom_port *port, + struct serial_struct __user *retinfo) +{ + struct serial_struct tmp; + struct riscom_board *bp = port_Board(port); + + memset(&tmp, 0, sizeof(tmp)); + tmp.type = PORT_CIRRUS; + tmp.line = port - rc_port; + + mutex_lock(&port->port.mutex); + tmp.port = bp->base; + tmp.irq = bp->irq; + tmp.flags = port->port.flags; + tmp.baud_base = (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC; + tmp.close_delay = port->port.close_delay * HZ/100; + tmp.closing_wait = port->port.closing_wait * HZ/100; + mutex_unlock(&port->port.mutex); + tmp.xmit_fifo_size = CD180_NFIFO; + return copy_to_user(retinfo, &tmp, sizeof(tmp)) ? -EFAULT : 0; +} + +static int rc_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + struct riscom_port *port = tty->driver_data; + void __user *argp = (void __user *)arg; + int retval; + + if (rc_paranoia_check(port, tty->name, "rc_ioctl")) + return -ENODEV; + + switch (cmd) { + case TIOCGSERIAL: + retval = rc_get_serial_info(port, argp); + break; + case TIOCSSERIAL: + retval = rc_set_serial_info(tty, port, argp); + break; + default: + retval = -ENOIOCTLCMD; + } + return retval; +} + +static void rc_throttle(struct tty_struct *tty) +{ + struct riscom_port *port = tty->driver_data; + struct riscom_board *bp; + unsigned long flags; + + if (rc_paranoia_check(port, tty->name, "rc_throttle")) + return; + bp = port_Board(port); + + spin_lock_irqsave(&riscom_lock, flags); + port->MSVR &= ~MSVR_RTS; + rc_out(bp, CD180_CAR, port_No(port)); + if (I_IXOFF(tty)) { + rc_wait_CCR(bp); + rc_out(bp, CD180_CCR, CCR_SSCH2); + rc_wait_CCR(bp); + } + rc_out(bp, CD180_MSVR, port->MSVR); + spin_unlock_irqrestore(&riscom_lock, flags); +} + +static void rc_unthrottle(struct tty_struct *tty) +{ + struct riscom_port *port = tty->driver_data; + struct riscom_board *bp; + unsigned long flags; + + if (rc_paranoia_check(port, tty->name, "rc_unthrottle")) + return; + bp = port_Board(port); + + spin_lock_irqsave(&riscom_lock, flags); + port->MSVR |= MSVR_RTS; + rc_out(bp, CD180_CAR, port_No(port)); + if (I_IXOFF(tty)) { + rc_wait_CCR(bp); + rc_out(bp, CD180_CCR, CCR_SSCH1); + rc_wait_CCR(bp); + } + rc_out(bp, CD180_MSVR, port->MSVR); + spin_unlock_irqrestore(&riscom_lock, flags); +} + +static void rc_stop(struct tty_struct *tty) +{ + struct riscom_port *port = tty->driver_data; + struct riscom_board *bp; + unsigned long flags; + + if (rc_paranoia_check(port, tty->name, "rc_stop")) + return; + + bp = port_Board(port); + + spin_lock_irqsave(&riscom_lock, flags); + port->IER &= ~IER_TXRDY; + rc_out(bp, CD180_CAR, port_No(port)); + rc_out(bp, CD180_IER, port->IER); + spin_unlock_irqrestore(&riscom_lock, flags); +} + +static void rc_start(struct tty_struct *tty) +{ + struct riscom_port *port = tty->driver_data; + struct riscom_board *bp; + unsigned long flags; + + if (rc_paranoia_check(port, tty->name, "rc_start")) + return; + + bp = port_Board(port); + + spin_lock_irqsave(&riscom_lock, flags); + + if (port->xmit_cnt && port->port.xmit_buf && !(port->IER & IER_TXRDY)) { + port->IER |= IER_TXRDY; + rc_out(bp, CD180_CAR, port_No(port)); + rc_out(bp, CD180_IER, port->IER); + } + spin_unlock_irqrestore(&riscom_lock, flags); +} + +static void rc_hangup(struct tty_struct *tty) +{ + struct riscom_port *port = tty->driver_data; + + if (rc_paranoia_check(port, tty->name, "rc_hangup")) + return; + + tty_port_hangup(&port->port); +} + +static void rc_set_termios(struct tty_struct *tty, + struct ktermios *old_termios) +{ + struct riscom_port *port = tty->driver_data; + unsigned long flags; + + if (rc_paranoia_check(port, tty->name, "rc_set_termios")) + return; + + spin_lock_irqsave(&riscom_lock, flags); + rc_change_speed(tty, port_Board(port), port); + spin_unlock_irqrestore(&riscom_lock, flags); + + if ((old_termios->c_cflag & CRTSCTS) && + !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + rc_start(tty); + } +} + +static const struct tty_operations riscom_ops = { + .open = rc_open, + .close = rc_close, + .write = rc_write, + .put_char = rc_put_char, + .flush_chars = rc_flush_chars, + .write_room = rc_write_room, + .chars_in_buffer = rc_chars_in_buffer, + .flush_buffer = rc_flush_buffer, + .ioctl = rc_ioctl, + .throttle = rc_throttle, + .unthrottle = rc_unthrottle, + .set_termios = rc_set_termios, + .stop = rc_stop, + .start = rc_start, + .hangup = rc_hangup, + .tiocmget = rc_tiocmget, + .tiocmset = rc_tiocmset, + .break_ctl = rc_send_break, +}; + +static const struct tty_port_operations riscom_port_ops = { + .carrier_raised = carrier_raised, + .dtr_rts = dtr_rts, + .shutdown = rc_close_port, + .activate = rc_activate_port, +}; + + +static int __init rc_init_drivers(void) +{ + int error; + int i; + + riscom_driver = alloc_tty_driver(RC_NBOARD * RC_NPORT); + if (!riscom_driver) + return -ENOMEM; + + riscom_driver->owner = THIS_MODULE; + riscom_driver->name = "ttyL"; + riscom_driver->major = RISCOM8_NORMAL_MAJOR; + riscom_driver->type = TTY_DRIVER_TYPE_SERIAL; + riscom_driver->subtype = SERIAL_TYPE_NORMAL; + riscom_driver->init_termios = tty_std_termios; + riscom_driver->init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + riscom_driver->init_termios.c_ispeed = 9600; + riscom_driver->init_termios.c_ospeed = 9600; + riscom_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_HARDWARE_BREAK; + tty_set_operations(riscom_driver, &riscom_ops); + error = tty_register_driver(riscom_driver); + if (error != 0) { + put_tty_driver(riscom_driver); + printk(KERN_ERR "rc: Couldn't register RISCom/8 driver, " + "error = %d\n", error); + return 1; + } + memset(rc_port, 0, sizeof(rc_port)); + for (i = 0; i < RC_NPORT * RC_NBOARD; i++) { + tty_port_init(&rc_port[i].port); + rc_port[i].port.ops = &riscom_port_ops; + rc_port[i].magic = RISCOM8_MAGIC; + } + return 0; +} + +static void rc_release_drivers(void) +{ + tty_unregister_driver(riscom_driver); + put_tty_driver(riscom_driver); +} + +#ifndef MODULE +/* + * Called at boot time. + * + * You can specify IO base for up to RC_NBOARD cards, + * using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt. + * Note that there will be no probing at default + * addresses in this case. + * + */ +static int __init riscom8_setup(char *str) +{ + int ints[RC_NBOARD]; + int i; + + str = get_options(str, ARRAY_SIZE(ints), ints); + + for (i = 0; i < RC_NBOARD; i++) { + if (i < ints[0]) + rc_board[i].base = ints[i+1]; + else + rc_board[i].base = 0; + } + return 1; +} + +__setup("riscom8=", riscom8_setup); +#endif + +static char banner[] __initdata = + KERN_INFO "rc: SDL RISCom/8 card driver v1.1, (c) D.Gorodchanin " + "1994-1996.\n"; +static char no_boards_msg[] __initdata = + KERN_INFO "rc: No RISCom/8 boards detected.\n"; + +/* + * This routine must be called by kernel at boot time + */ +static int __init riscom8_init(void) +{ + int i; + int found = 0; + + printk(banner); + + if (rc_init_drivers()) + return -EIO; + + for (i = 0; i < RC_NBOARD; i++) + if (rc_board[i].base && !rc_probe(&rc_board[i])) + found++; + if (!found) { + rc_release_drivers(); + printk(no_boards_msg); + return -EIO; + } + return 0; +} + +#ifdef MODULE +static int iobase; +static int iobase1; +static int iobase2; +static int iobase3; +module_param(iobase, int, 0); +module_param(iobase1, int, 0); +module_param(iobase2, int, 0); +module_param(iobase3, int, 0); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS_CHARDEV_MAJOR(RISCOM8_NORMAL_MAJOR); +#endif /* MODULE */ + +/* + * You can setup up to 4 boards (current value of RC_NBOARD) + * by specifying "iobase=0xXXX iobase1=0xXXX ..." as insmod parameter. + * + */ +static int __init riscom8_init_module(void) +{ +#ifdef MODULE + int i; + + if (iobase || iobase1 || iobase2 || iobase3) { + for (i = 0; i < RC_NBOARD; i++) + rc_board[i].base = 0; + } + + if (iobase) + rc_board[0].base = iobase; + if (iobase1) + rc_board[1].base = iobase1; + if (iobase2) + rc_board[2].base = iobase2; + if (iobase3) + rc_board[3].base = iobase3; +#endif /* MODULE */ + + return riscom8_init(); +} + +static void __exit riscom8_exit_module(void) +{ + int i; + + rc_release_drivers(); + for (i = 0; i < RC_NBOARD; i++) + if (rc_board[i].flags & RC_BOARD_PRESENT) + rc_release_io_range(&rc_board[i]); + +} + +module_init(riscom8_init_module); +module_exit(riscom8_exit_module); diff --git a/drivers/staging/tty/riscom8.h b/drivers/staging/tty/riscom8.h new file mode 100644 index 000000000000..c9876b3f9714 --- /dev/null +++ b/drivers/staging/tty/riscom8.h @@ -0,0 +1,91 @@ +/* + * linux/drivers/char/riscom8.h -- RISCom/8 multiport serial driver. + * + * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) + * + * This code is loosely based on the Linux serial driver, written by + * Linus Torvalds, Theodore T'so and others. The RISCom/8 card + * programming info was obtained from various drivers for other OSes + * (FreeBSD, ISC, etc), but no source code from those drivers were + * directly included in this driver. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __LINUX_RISCOM8_H +#define __LINUX_RISCOM8_H + +#include + +#ifdef __KERNEL__ + +#define RC_NBOARD 4 +/* NOTE: RISCom decoder recognizes 16 addresses... */ +#define RC_NPORT 8 +#define RC_BOARD(line) (((line) >> 3) & 0x07) +#define RC_PORT(line) ((line) & (RC_NPORT - 1)) + +/* Ticks per sec. Used for setting receiver timeout and break length */ +#define RISCOM_TPS 4000 + +/* Yeah, after heavy testing I decided it must be 6. + * Sure, You can change it if needed. + */ +#define RISCOM_RXFIFO 6 /* Max. receiver FIFO size (1-8) */ + +#define RISCOM8_MAGIC 0x0907 + +#define RC_IOBASE1 0x220 +#define RC_IOBASE2 0x240 +#define RC_IOBASE3 0x250 +#define RC_IOBASE4 0x260 + +struct riscom_board { + unsigned long flags; + unsigned short base; + unsigned char irq; + signed char count; + unsigned char DTR; +}; + +#define RC_BOARD_PRESENT 0x00000001 +#define RC_BOARD_ACTIVE 0x00000002 + +struct riscom_port { + int magic; + struct tty_port port; + int baud_base; + int timeout; + int custom_divisor; + int xmit_head; + int xmit_tail; + int xmit_cnt; + short wakeup_chars; + short break_length; + unsigned char mark_mask; + unsigned char IER; + unsigned char MSVR; + unsigned char COR2; +#ifdef RC_REPORT_OVERRUN + unsigned long overrun; +#endif +#ifdef RC_REPORT_FIFO + unsigned long hits[10]; +#endif +}; + +#endif /* __KERNEL__ */ +#endif /* __LINUX_RISCOM8_H */ diff --git a/drivers/staging/tty/riscom8_reg.h b/drivers/staging/tty/riscom8_reg.h new file mode 100644 index 000000000000..a32475ed0d18 --- /dev/null +++ b/drivers/staging/tty/riscom8_reg.h @@ -0,0 +1,254 @@ +/* + * linux/drivers/char/riscom8_reg.h -- RISCom/8 multiport serial driver. + */ + +/* + * Definitions for RISCom/8 Async Mux card by SDL Communications, Inc. + */ + +/* + * Address mapping between Cirrus Logic CD180 chip internal registers + * and ISA port addresses: + * + * CL-CD180 A6 A5 A4 A3 A2 A1 A0 + * ISA A15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0 + */ +#define RC_TO_ISA(r) ((((r)&0x07)<<1) | (((r)&~0x07)<<7)) + + +/* RISCom/8 On-Board Registers (assuming address translation) */ + +#define RC_RI 0x100 /* Ring Indicator Register (R/O) */ +#define RC_DTR 0x100 /* DTR Register (W/O) */ +#define RC_BSR 0x101 /* Board Status Register (R/O) */ +#define RC_CTOUT 0x101 /* Clear Timeout (W/O) */ + + +/* Board Status Register */ + +#define RC_BSR_TOUT 0x08 /* Hardware Timeout */ +#define RC_BSR_RINT 0x04 /* Receiver Interrupt */ +#define RC_BSR_TINT 0x02 /* Transmitter Interrupt */ +#define RC_BSR_MINT 0x01 /* Modem Ctl Interrupt */ + + +/* On-board oscillator frequency (in Hz) */ +#define RC_OSCFREQ 9830400 + +/* Values of choice for Interrupt ACKs */ +#define RC_ACK_MINT 0x81 /* goes to PILR1 */ +#define RC_ACK_RINT 0x82 /* goes to PILR3 */ +#define RC_ACK_TINT 0x84 /* goes to PILR2 */ + +/* Chip ID (sorry, only one chip now) */ +#define RC_ID 0x10 + +/* Definitions for Cirrus Logic CL-CD180 8-port async mux chip */ + +#define CD180_NCH 8 /* Total number of channels */ +#define CD180_TPC 16 /* Ticks per character */ +#define CD180_NFIFO 8 /* TX FIFO size */ + + +/* Global registers */ + +#define CD180_GIVR 0x40 /* Global Interrupt Vector Register */ +#define CD180_GICR 0x41 /* Global Interrupting Channel Register */ +#define CD180_PILR1 0x61 /* Priority Interrupt Level Register 1 */ +#define CD180_PILR2 0x62 /* Priority Interrupt Level Register 2 */ +#define CD180_PILR3 0x63 /* Priority Interrupt Level Register 3 */ +#define CD180_CAR 0x64 /* Channel Access Register */ +#define CD180_GFRCR 0x6b /* Global Firmware Revision Code Register */ +#define CD180_PPRH 0x70 /* Prescaler Period Register High */ +#define CD180_PPRL 0x71 /* Prescaler Period Register Low */ +#define CD180_RDR 0x78 /* Receiver Data Register */ +#define CD180_RCSR 0x7a /* Receiver Character Status Register */ +#define CD180_TDR 0x7b /* Transmit Data Register */ +#define CD180_EOIR 0x7f /* End of Interrupt Register */ + + +/* Channel Registers */ + +#define CD180_CCR 0x01 /* Channel Command Register */ +#define CD180_IER 0x02 /* Interrupt Enable Register */ +#define CD180_COR1 0x03 /* Channel Option Register 1 */ +#define CD180_COR2 0x04 /* Channel Option Register 2 */ +#define CD180_COR3 0x05 /* Channel Option Register 3 */ +#define CD180_CCSR 0x06 /* Channel Control Status Register */ +#define CD180_RDCR 0x07 /* Receive Data Count Register */ +#define CD180_SCHR1 0x09 /* Special Character Register 1 */ +#define CD180_SCHR2 0x0a /* Special Character Register 2 */ +#define CD180_SCHR3 0x0b /* Special Character Register 3 */ +#define CD180_SCHR4 0x0c /* Special Character Register 4 */ +#define CD180_MCOR1 0x10 /* Modem Change Option 1 Register */ +#define CD180_MCOR2 0x11 /* Modem Change Option 2 Register */ +#define CD180_MCR 0x12 /* Modem Change Register */ +#define CD180_RTPR 0x18 /* Receive Timeout Period Register */ +#define CD180_MSVR 0x28 /* Modem Signal Value Register */ +#define CD180_RBPRH 0x31 /* Receive Baud Rate Period Register High */ +#define CD180_RBPRL 0x32 /* Receive Baud Rate Period Register Low */ +#define CD180_TBPRH 0x39 /* Transmit Baud Rate Period Register High */ +#define CD180_TBPRL 0x3a /* Transmit Baud Rate Period Register Low */ + + +/* Global Interrupt Vector Register (R/W) */ + +#define GIVR_ITMASK 0x07 /* Interrupt type mask */ +#define GIVR_IT_MODEM 0x01 /* Modem Signal Change Interrupt */ +#define GIVR_IT_TX 0x02 /* Transmit Data Interrupt */ +#define GIVR_IT_RCV 0x03 /* Receive Good Data Interrupt */ +#define GIVR_IT_REXC 0x07 /* Receive Exception Interrupt */ + + +/* Global Interrupt Channel Register (R/W) */ + +#define GICR_CHAN 0x1c /* Channel Number Mask */ +#define GICR_CHAN_OFF 2 /* Channel Number Offset */ + + +/* Channel Address Register (R/W) */ + +#define CAR_CHAN 0x07 /* Channel Number Mask */ +#define CAR_A7 0x08 /* A7 Address Extension (unused) */ + + +/* Receive Character Status Register (R/O) */ + +#define RCSR_TOUT 0x80 /* Rx Timeout */ +#define RCSR_SCDET 0x70 /* Special Character Detected Mask */ +#define RCSR_NO_SC 0x00 /* No Special Characters Detected */ +#define RCSR_SC_1 0x10 /* Special Char 1 (or 1 & 3) Detected */ +#define RCSR_SC_2 0x20 /* Special Char 2 (or 2 & 4) Detected */ +#define RCSR_SC_3 0x30 /* Special Char 3 Detected */ +#define RCSR_SC_4 0x40 /* Special Char 4 Detected */ +#define RCSR_BREAK 0x08 /* Break has been detected */ +#define RCSR_PE 0x04 /* Parity Error */ +#define RCSR_FE 0x02 /* Frame Error */ +#define RCSR_OE 0x01 /* Overrun Error */ + + +/* Channel Command Register (R/W) (commands in groups can be OR-ed) */ + +#define CCR_HARDRESET 0x81 /* Reset the chip */ + +#define CCR_SOFTRESET 0x80 /* Soft Channel Reset */ + +#define CCR_CORCHG1 0x42 /* Channel Option Register 1 Changed */ +#define CCR_CORCHG2 0x44 /* Channel Option Register 2 Changed */ +#define CCR_CORCHG3 0x48 /* Channel Option Register 3 Changed */ + +#define CCR_SSCH1 0x21 /* Send Special Character 1 */ + +#define CCR_SSCH2 0x22 /* Send Special Character 2 */ + +#define CCR_SSCH3 0x23 /* Send Special Character 3 */ + +#define CCR_SSCH4 0x24 /* Send Special Character 4 */ + +#define CCR_TXEN 0x18 /* Enable Transmitter */ +#define CCR_RXEN 0x12 /* Enable Receiver */ + +#define CCR_TXDIS 0x14 /* Disable Transmitter */ +#define CCR_RXDIS 0x11 /* Disable Receiver */ + + +/* Interrupt Enable Register (R/W) */ + +#define IER_DSR 0x80 /* Enable interrupt on DSR change */ +#define IER_CD 0x40 /* Enable interrupt on CD change */ +#define IER_CTS 0x20 /* Enable interrupt on CTS change */ +#define IER_RXD 0x10 /* Enable interrupt on Receive Data */ +#define IER_RXSC 0x08 /* Enable interrupt on Receive Spec. Char */ +#define IER_TXRDY 0x04 /* Enable interrupt on TX FIFO empty */ +#define IER_TXEMPTY 0x02 /* Enable interrupt on TX completely empty */ +#define IER_RET 0x01 /* Enable interrupt on RX Exc. Timeout */ + + +/* Channel Option Register 1 (R/W) */ + +#define COR1_ODDP 0x80 /* Odd Parity */ +#define COR1_PARMODE 0x60 /* Parity Mode mask */ +#define COR1_NOPAR 0x00 /* No Parity */ +#define COR1_FORCEPAR 0x20 /* Force Parity */ +#define COR1_NORMPAR 0x40 /* Normal Parity */ +#define COR1_IGNORE 0x10 /* Ignore Parity on RX */ +#define COR1_STOPBITS 0x0c /* Number of Stop Bits */ +#define COR1_1SB 0x00 /* 1 Stop Bit */ +#define COR1_15SB 0x04 /* 1.5 Stop Bits */ +#define COR1_2SB 0x08 /* 2 Stop Bits */ +#define COR1_CHARLEN 0x03 /* Character Length */ +#define COR1_5BITS 0x00 /* 5 bits */ +#define COR1_6BITS 0x01 /* 6 bits */ +#define COR1_7BITS 0x02 /* 7 bits */ +#define COR1_8BITS 0x03 /* 8 bits */ + + +/* Channel Option Register 2 (R/W) */ + +#define COR2_IXM 0x80 /* Implied XON mode */ +#define COR2_TXIBE 0x40 /* Enable In-Band (XON/XOFF) Flow Control */ +#define COR2_ETC 0x20 /* Embedded Tx Commands Enable */ +#define COR2_LLM 0x10 /* Local Loopback Mode */ +#define COR2_RLM 0x08 /* Remote Loopback Mode */ +#define COR2_RTSAO 0x04 /* RTS Automatic Output Enable */ +#define COR2_CTSAE 0x02 /* CTS Automatic Enable */ +#define COR2_DSRAE 0x01 /* DSR Automatic Enable */ + + +/* Channel Option Register 3 (R/W) */ + +#define COR3_XONCH 0x80 /* XON is a pair of characters (1 & 3) */ +#define COR3_XOFFCH 0x40 /* XOFF is a pair of characters (2 & 4) */ +#define COR3_FCT 0x20 /* Flow-Control Transparency Mode */ +#define COR3_SCDE 0x10 /* Special Character Detection Enable */ +#define COR3_RXTH 0x0f /* RX FIFO Threshold value (1-8) */ + + +/* Channel Control Status Register (R/O) */ + +#define CCSR_RXEN 0x80 /* Receiver Enabled */ +#define CCSR_RXFLOFF 0x40 /* Receive Flow Off (XOFF was sent) */ +#define CCSR_RXFLON 0x20 /* Receive Flow On (XON was sent) */ +#define CCSR_TXEN 0x08 /* Transmitter Enabled */ +#define CCSR_TXFLOFF 0x04 /* Transmit Flow Off (got XOFF) */ +#define CCSR_TXFLON 0x02 /* Transmit Flow On (got XON) */ + + +/* Modem Change Option Register 1 (R/W) */ + +#define MCOR1_DSRZD 0x80 /* Detect 0->1 transition of DSR */ +#define MCOR1_CDZD 0x40 /* Detect 0->1 transition of CD */ +#define MCOR1_CTSZD 0x20 /* Detect 0->1 transition of CTS */ +#define MCOR1_DTRTH 0x0f /* Auto DTR flow control Threshold (1-8) */ +#define MCOR1_NODTRFC 0x0 /* Automatic DTR flow control disabled */ + + +/* Modem Change Option Register 2 (R/W) */ + +#define MCOR2_DSROD 0x80 /* Detect 1->0 transition of DSR */ +#define MCOR2_CDOD 0x40 /* Detect 1->0 transition of CD */ +#define MCOR2_CTSOD 0x20 /* Detect 1->0 transition of CTS */ + + +/* Modem Change Register (R/W) */ + +#define MCR_DSRCHG 0x80 /* DSR Changed */ +#define MCR_CDCHG 0x40 /* CD Changed */ +#define MCR_CTSCHG 0x20 /* CTS Changed */ + + +/* Modem Signal Value Register (R/W) */ + +#define MSVR_DSR 0x80 /* Current state of DSR input */ +#define MSVR_CD 0x40 /* Current state of CD input */ +#define MSVR_CTS 0x20 /* Current state of CTS input */ +#define MSVR_DTR 0x02 /* Current state of DTR output */ +#define MSVR_RTS 0x01 /* Current state of RTS output */ + + +/* Escape characters */ + +#define CD180_C_ESC 0x00 /* Escape character */ +#define CD180_C_SBRK 0x81 /* Start sending BREAK */ +#define CD180_C_DELAY 0x82 /* Delay output */ +#define CD180_C_EBRK 0x83 /* Stop sending BREAK */ diff --git a/drivers/staging/tty/serial167.c b/drivers/staging/tty/serial167.c new file mode 100644 index 000000000000..674af6933978 --- /dev/null +++ b/drivers/staging/tty/serial167.c @@ -0,0 +1,2489 @@ +/* + * linux/drivers/char/serial167.c + * + * Driver for MVME166/7 board serial ports, which are via a CD2401. + * Based very much on cyclades.c. + * + * MVME166/7 work by Richard Hirst [richard@sleepie.demon.co.uk] + * + * ============================================================== + * + * static char rcsid[] = + * "$Revision: 1.36.1.4 $$Date: 1995/03/29 06:14:14 $"; + * + * linux/kernel/cyclades.c + * + * Maintained by Marcio Saito (cyclades@netcom.com) and + * Randolph Bentson (bentson@grieg.seaslug.org) + * + * Much of the design and some of the code came from serial.c + * which was copyright (C) 1991, 1992 Linus Torvalds. It was + * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92, + * and then fixed as suggested by Michael K. Johnson 12/12/92. + * + * This version does not support shared irq's. + * + * $Log: cyclades.c,v $ + * Revision 1.36.1.4 1995/03/29 06:14:14 bentson + * disambiguate between Cyclom-16Y and Cyclom-32Ye; + * + * Changes: + * + * 200 lines of changes record removed - RGH 11-10-95, starting work on + * converting this to drive serial ports on mvme166 (cd2401). + * + * Arnaldo Carvalho de Melo - 2000/08/25 + * - get rid of verify_area + * - use get_user to access memory from userspace in set_threshold, + * set_default_threshold and set_timeout + * - don't use the panic function in serial167_init + * - do resource release on failure on serial167_init + * - include missing restore_flags in mvme167_serial_console_setup + * + * Kars de Jong - 2004/09/06 + * - replace bottom half handler with task queue handler + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#define SERIAL_PARANOIA_CHECK +#undef SERIAL_DEBUG_OPEN +#undef SERIAL_DEBUG_THROTTLE +#undef SERIAL_DEBUG_OTHER +#undef SERIAL_DEBUG_IO +#undef SERIAL_DEBUG_COUNT +#undef SERIAL_DEBUG_DTR +#undef CYCLOM_16Y_HACK +#define CYCLOM_ENABLE_MONITORING + +#define WAKEUP_CHARS 256 + +#define STD_COM_FLAGS (0) + +static struct tty_driver *cy_serial_driver; +extern int serial_console; +static struct cyclades_port *serial_console_info = NULL; +static unsigned int serial_console_cflag = 0; +u_char initial_console_speed; + +/* Base address of cd2401 chip on mvme166/7 */ + +#define BASE_ADDR (0xfff45000) +#define pcc2chip ((volatile u_char *)0xfff42000) +#define PccSCCMICR 0x1d +#define PccSCCTICR 0x1e +#define PccSCCRICR 0x1f +#define PccTPIACKR 0x25 +#define PccRPIACKR 0x27 +#define PccIMLR 0x3f + +/* This is the per-port data structure */ +struct cyclades_port cy_port[] = { + /* CARD# */ + {-1}, /* ttyS0 */ + {-1}, /* ttyS1 */ + {-1}, /* ttyS2 */ + {-1}, /* ttyS3 */ +}; + +#define NR_PORTS ARRAY_SIZE(cy_port) + +/* + * This is used to look up the divisor speeds and the timeouts + * We're normally limited to 15 distinct baud rates. The extra + * are accessed via settings in info->flags. + * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + * 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + * HI VHI + */ +static int baud_table[] = { + 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, + 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200, 150000, + 0 +}; + +#if 0 +static char baud_co[] = { /* 25 MHz clock option table */ + /* value => 00 01 02 03 04 */ + /* divide by 8 32 128 512 2048 */ + 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, + 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static char baud_bpr[] = { /* 25 MHz baud rate period table */ + 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3, + 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15 +}; +#endif + +/* I think 166 brd clocks 2401 at 20MHz.... */ + +/* These values are written directly to tcor, and >> 5 for writing to rcor */ +static u_char baud_co[] = { /* 20 MHz clock option table */ + 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x60, 0x60, 0x40, + 0x40, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* These values written directly to tbpr/rbpr */ +static u_char baud_bpr[] = { /* 20 MHz baud rate period table */ + 0x00, 0xc0, 0x80, 0x58, 0x6c, 0x40, 0xc0, 0x81, 0x40, 0x81, + 0x57, 0x40, 0x81, 0x40, 0x81, 0x40, 0x2b, 0x20, 0x15, 0x10 +}; + +static u_char baud_cor4[] = { /* receive threshold */ + 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, + 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07 +}; + +static void shutdown(struct cyclades_port *); +static int startup(struct cyclades_port *); +static void cy_throttle(struct tty_struct *); +static void cy_unthrottle(struct tty_struct *); +static void config_setup(struct cyclades_port *); +#ifdef CYCLOM_SHOW_STATUS +static void show_status(int); +#endif + +/* + * I have my own version of udelay(), as it is needed when initialising + * the chip, before the delay loop has been calibrated. Should probably + * reference one of the vmechip2 or pccchip2 counter for an accurate + * delay, but this wild guess will do for now. + */ + +void my_udelay(long us) +{ + u_char x; + volatile u_char *p = &x; + int i; + + while (us--) + for (i = 100; i; i--) + x |= *p; +} + +static inline int serial_paranoia_check(struct cyclades_port *info, char *name, + const char *routine) +{ +#ifdef SERIAL_PARANOIA_CHECK + if (!info) { + printk("Warning: null cyclades_port for (%s) in %s\n", name, + routine); + return 1; + } + + if (info < &cy_port[0] || info >= &cy_port[NR_PORTS]) { + printk("Warning: cyclades_port out of range for (%s) in %s\n", + name, routine); + return 1; + } + + if (info->magic != CYCLADES_MAGIC) { + printk("Warning: bad magic number for serial struct (%s) in " + "%s\n", name, routine); + return 1; + } +#endif + return 0; +} /* serial_paranoia_check */ + +#if 0 +/* The following diagnostic routines allow the driver to spew + information on the screen, even (especially!) during interrupts. + */ +void SP(char *data) +{ + unsigned long flags; + local_irq_save(flags); + printk(KERN_EMERG "%s", data); + local_irq_restore(flags); +} + +char scrn[2]; +void CP(char data) +{ + unsigned long flags; + local_irq_save(flags); + scrn[0] = data; + printk(KERN_EMERG "%c", scrn); + local_irq_restore(flags); +} /* CP */ + +void CP1(int data) +{ + (data < 10) ? CP(data + '0') : CP(data + 'A' - 10); +} /* CP1 */ +void CP2(int data) +{ + CP1((data >> 4) & 0x0f); + CP1(data & 0x0f); +} /* CP2 */ +void CP4(int data) +{ + CP2((data >> 8) & 0xff); + CP2(data & 0xff); +} /* CP4 */ +void CP8(long data) +{ + CP4((data >> 16) & 0xffff); + CP4(data & 0xffff); +} /* CP8 */ +#endif + +/* This routine waits up to 1000 micro-seconds for the previous + command to the Cirrus chip to complete and then issues the + new command. An error is returned if the previous command + didn't finish within the time limit. + */ +u_short write_cy_cmd(volatile u_char * base_addr, u_char cmd) +{ + unsigned long flags; + volatile int i; + + local_irq_save(flags); + /* Check to see that the previous command has completed */ + for (i = 0; i < 100; i++) { + if (base_addr[CyCCR] == 0) { + break; + } + my_udelay(10L); + } + /* if the CCR never cleared, the previous command + didn't finish within the "reasonable time" */ + if (i == 10) { + local_irq_restore(flags); + return (-1); + } + + /* Issue the new command */ + base_addr[CyCCR] = cmd; + local_irq_restore(flags); + return (0); +} /* write_cy_cmd */ + +/* cy_start and cy_stop provide software output flow control as a + function of XON/XOFF, software CTS, and other such stuff. */ + +static void cy_stop(struct tty_struct *tty) +{ + struct cyclades_port *info = tty->driver_data; + volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; + int channel; + unsigned long flags; + +#ifdef SERIAL_DEBUG_OTHER + printk("cy_stop %s\n", tty->name); /* */ +#endif + + if (serial_paranoia_check(info, tty->name, "cy_stop")) + return; + + channel = info->line; + + local_irq_save(flags); + base_addr[CyCAR] = (u_char) (channel); /* index channel */ + base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); + local_irq_restore(flags); +} /* cy_stop */ + +static void cy_start(struct tty_struct *tty) +{ + struct cyclades_port *info = tty->driver_data; + volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; + int channel; + unsigned long flags; + +#ifdef SERIAL_DEBUG_OTHER + printk("cy_start %s\n", tty->name); /* */ +#endif + + if (serial_paranoia_check(info, tty->name, "cy_start")) + return; + + channel = info->line; + + local_irq_save(flags); + base_addr[CyCAR] = (u_char) (channel); + base_addr[CyIER] |= CyTxMpty; + local_irq_restore(flags); +} /* cy_start */ + +/* The real interrupt service routines are called + whenever the card wants its hand held--chars + received, out buffer empty, modem change, etc. + */ +static irqreturn_t cd2401_rxerr_interrupt(int irq, void *dev_id) +{ + struct tty_struct *tty; + struct cyclades_port *info; + volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; + unsigned char err, rfoc; + int channel; + char data; + + /* determine the channel and change to that context */ + channel = (u_short) (base_addr[CyLICR] >> 2); + info = &cy_port[channel]; + info->last_active = jiffies; + + if ((err = base_addr[CyRISR]) & CyTIMEOUT) { + /* This is a receive timeout interrupt, ignore it */ + base_addr[CyREOIR] = CyNOTRANS; + return IRQ_HANDLED; + } + + /* Read a byte of data if there is any - assume the error + * is associated with this character */ + + if ((rfoc = base_addr[CyRFOC]) != 0) + data = base_addr[CyRDR]; + else + data = 0; + + /* if there is nowhere to put the data, discard it */ + if (info->tty == 0) { + base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; + return IRQ_HANDLED; + } else { /* there is an open port for this data */ + tty = info->tty; + if (err & info->ignore_status_mask) { + base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; + return IRQ_HANDLED; + } + if (tty_buffer_request_room(tty, 1) != 0) { + if (err & info->read_status_mask) { + if (err & CyBREAK) { + tty_insert_flip_char(tty, data, + TTY_BREAK); + if (info->flags & ASYNC_SAK) { + do_SAK(tty); + } + } else if (err & CyFRAME) { + tty_insert_flip_char(tty, data, + TTY_FRAME); + } else if (err & CyPARITY) { + tty_insert_flip_char(tty, data, + TTY_PARITY); + } else if (err & CyOVERRUN) { + tty_insert_flip_char(tty, 0, + TTY_OVERRUN); + /* + If the flip buffer itself is + overflowing, we still lose + the next incoming character. + */ + if (tty_buffer_request_room(tty, 1) != + 0) { + tty_insert_flip_char(tty, data, + TTY_FRAME); + } + /* These two conditions may imply */ + /* a normal read should be done. */ + /* else if(data & CyTIMEOUT) */ + /* else if(data & CySPECHAR) */ + } else { + tty_insert_flip_char(tty, 0, + TTY_NORMAL); + } + } else { + tty_insert_flip_char(tty, data, TTY_NORMAL); + } + } else { + /* there was a software buffer overrun + and nothing could be done about it!!! */ + } + } + tty_schedule_flip(tty); + /* end of service */ + base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; + return IRQ_HANDLED; +} /* cy_rxerr_interrupt */ + +static irqreturn_t cd2401_modem_interrupt(int irq, void *dev_id) +{ + struct cyclades_port *info; + volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; + int channel; + int mdm_change; + int mdm_status; + + /* determine the channel and change to that context */ + channel = (u_short) (base_addr[CyLICR] >> 2); + info = &cy_port[channel]; + info->last_active = jiffies; + + mdm_change = base_addr[CyMISR]; + mdm_status = base_addr[CyMSVR1]; + + if (info->tty == 0) { /* nowhere to put the data, ignore it */ + ; + } else { + if ((mdm_change & CyDCD) + && (info->flags & ASYNC_CHECK_CD)) { + if (mdm_status & CyDCD) { +/* CP('!'); */ + wake_up_interruptible(&info->open_wait); + } else { +/* CP('@'); */ + tty_hangup(info->tty); + wake_up_interruptible(&info->open_wait); + info->flags &= ~ASYNC_NORMAL_ACTIVE; + } + } + if ((mdm_change & CyCTS) + && (info->flags & ASYNC_CTS_FLOW)) { + if (info->tty->stopped) { + if (mdm_status & CyCTS) { + /* !!! cy_start isn't used because... */ + info->tty->stopped = 0; + base_addr[CyIER] |= CyTxMpty; + tty_wakeup(info->tty); + } + } else { + if (!(mdm_status & CyCTS)) { + /* !!! cy_stop isn't used because... */ + info->tty->stopped = 1; + base_addr[CyIER] &= + ~(CyTxMpty | CyTxRdy); + } + } + } + if (mdm_status & CyDSR) { + } + } + base_addr[CyMEOIR] = 0; + return IRQ_HANDLED; +} /* cy_modem_interrupt */ + +static irqreturn_t cd2401_tx_interrupt(int irq, void *dev_id) +{ + struct cyclades_port *info; + volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; + int channel; + int char_count, saved_cnt; + int outch; + + /* determine the channel and change to that context */ + channel = (u_short) (base_addr[CyLICR] >> 2); + + /* validate the port number (as configured and open) */ + if ((channel < 0) || (NR_PORTS <= channel)) { + base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); + base_addr[CyTEOIR] = CyNOTRANS; + return IRQ_HANDLED; + } + info = &cy_port[channel]; + info->last_active = jiffies; + if (info->tty == 0) { + base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); + base_addr[CyTEOIR] = CyNOTRANS; + return IRQ_HANDLED; + } + + /* load the on-chip space available for outbound data */ + saved_cnt = char_count = base_addr[CyTFTC]; + + if (info->x_char) { /* send special char */ + outch = info->x_char; + base_addr[CyTDR] = outch; + char_count--; + info->x_char = 0; + } + + if (info->x_break) { + /* The Cirrus chip requires the "Embedded Transmit + Commands" of start break, delay, and end break + sequences to be sent. The duration of the + break is given in TICs, which runs at HZ + (typically 100) and the PPR runs at 200 Hz, + so the delay is duration * 200/HZ, and thus a + break can run from 1/100 sec to about 5/4 sec. + Need to check these values - RGH 141095. + */ + base_addr[CyTDR] = 0; /* start break */ + base_addr[CyTDR] = 0x81; + base_addr[CyTDR] = 0; /* delay a bit */ + base_addr[CyTDR] = 0x82; + base_addr[CyTDR] = info->x_break * 200 / HZ; + base_addr[CyTDR] = 0; /* terminate break */ + base_addr[CyTDR] = 0x83; + char_count -= 7; + info->x_break = 0; + } + + while (char_count > 0) { + if (!info->xmit_cnt) { + base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); + break; + } + if (info->xmit_buf == 0) { + base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); + break; + } + if (info->tty->stopped || info->tty->hw_stopped) { + base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); + break; + } + /* Because the Embedded Transmit Commands have been + enabled, we must check to see if the escape + character, NULL, is being sent. If it is, we + must ensure that there is room for it to be + doubled in the output stream. Therefore we + no longer advance the pointer when the character + is fetched, but rather wait until after the check + for a NULL output character. (This is necessary + because there may not be room for the two chars + needed to send a NULL. + */ + outch = info->xmit_buf[info->xmit_tail]; + if (outch) { + info->xmit_cnt--; + info->xmit_tail = (info->xmit_tail + 1) + & (PAGE_SIZE - 1); + base_addr[CyTDR] = outch; + char_count--; + } else { + if (char_count > 1) { + info->xmit_cnt--; + info->xmit_tail = (info->xmit_tail + 1) + & (PAGE_SIZE - 1); + base_addr[CyTDR] = outch; + base_addr[CyTDR] = 0; + char_count--; + char_count--; + } else { + break; + } + } + } + + if (info->xmit_cnt < WAKEUP_CHARS) + tty_wakeup(info->tty); + + base_addr[CyTEOIR] = (char_count != saved_cnt) ? 0 : CyNOTRANS; + return IRQ_HANDLED; +} /* cy_tx_interrupt */ + +static irqreturn_t cd2401_rx_interrupt(int irq, void *dev_id) +{ + struct tty_struct *tty; + struct cyclades_port *info; + volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; + int channel; + char data; + int char_count; + int save_cnt; + + /* determine the channel and change to that context */ + channel = (u_short) (base_addr[CyLICR] >> 2); + info = &cy_port[channel]; + info->last_active = jiffies; + save_cnt = char_count = base_addr[CyRFOC]; + + /* if there is nowhere to put the data, discard it */ + if (info->tty == 0) { + while (char_count--) { + data = base_addr[CyRDR]; + } + } else { /* there is an open port for this data */ + tty = info->tty; + /* load # characters available from the chip */ + +#ifdef CYCLOM_ENABLE_MONITORING + ++info->mon.int_count; + info->mon.char_count += char_count; + if (char_count > info->mon.char_max) + info->mon.char_max = char_count; + info->mon.char_last = char_count; +#endif + while (char_count--) { + data = base_addr[CyRDR]; + tty_insert_flip_char(tty, data, TTY_NORMAL); +#ifdef CYCLOM_16Y_HACK + udelay(10L); +#endif + } + tty_schedule_flip(tty); + } + /* end of service */ + base_addr[CyREOIR] = save_cnt ? 0 : CyNOTRANS; + return IRQ_HANDLED; +} /* cy_rx_interrupt */ + +/* This is called whenever a port becomes active; + interrupts are enabled and DTR & RTS are turned on. + */ +static int startup(struct cyclades_port *info) +{ + unsigned long flags; + volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; + int channel; + + if (info->flags & ASYNC_INITIALIZED) { + return 0; + } + + if (!info->type) { + if (info->tty) { + set_bit(TTY_IO_ERROR, &info->tty->flags); + } + return 0; + } + if (!info->xmit_buf) { + info->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); + if (!info->xmit_buf) { + return -ENOMEM; + } + } + + config_setup(info); + + channel = info->line; + +#ifdef SERIAL_DEBUG_OPEN + printk("startup channel %d\n", channel); +#endif + + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; + write_cy_cmd(base_addr, CyENB_RCVR | CyENB_XMTR); + + base_addr[CyCAR] = (u_char) channel; /* !!! Is this needed? */ + base_addr[CyMSVR1] = CyRTS; +/* CP('S');CP('1'); */ + base_addr[CyMSVR2] = CyDTR; + +#ifdef SERIAL_DEBUG_DTR + printk("cyc: %d: raising DTR\n", __LINE__); + printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], + base_addr[CyMSVR2]); +#endif + + base_addr[CyIER] |= CyRxData; + info->flags |= ASYNC_INITIALIZED; + + if (info->tty) { + clear_bit(TTY_IO_ERROR, &info->tty->flags); + } + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + + local_irq_restore(flags); + +#ifdef SERIAL_DEBUG_OPEN + printk(" done\n"); +#endif + return 0; +} /* startup */ + +void start_xmit(struct cyclades_port *info) +{ + unsigned long flags; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; + + channel = info->line; + local_irq_save(flags); + base_addr[CyCAR] = channel; + base_addr[CyIER] |= CyTxMpty; + local_irq_restore(flags); +} /* start_xmit */ + +/* + * This routine shuts down a serial port; interrupts are disabled, + * and DTR is dropped if the hangup on close termio flag is on. + */ +static void shutdown(struct cyclades_port *info) +{ + unsigned long flags; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; + + if (!(info->flags & ASYNC_INITIALIZED)) { +/* CP('$'); */ + return; + } + + channel = info->line; + +#ifdef SERIAL_DEBUG_OPEN + printk("shutdown channel %d\n", channel); +#endif + + /* !!! REALLY MUST WAIT FOR LAST CHARACTER TO BE + SENT BEFORE DROPPING THE LINE !!! (Perhaps + set some flag that is read when XMTY happens.) + Other choices are to delay some fixed interval + or schedule some later processing. + */ + local_irq_save(flags); + if (info->xmit_buf) { + free_page((unsigned long)info->xmit_buf); + info->xmit_buf = NULL; + } + + base_addr[CyCAR] = (u_char) channel; + if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { + base_addr[CyMSVR1] = 0; +/* CP('C');CP('1'); */ + base_addr[CyMSVR2] = 0; +#ifdef SERIAL_DEBUG_DTR + printk("cyc: %d: dropping DTR\n", __LINE__); + printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], + base_addr[CyMSVR2]); +#endif + } + write_cy_cmd(base_addr, CyDIS_RCVR); + /* it may be appropriate to clear _XMIT at + some later date (after testing)!!! */ + + if (info->tty) { + set_bit(TTY_IO_ERROR, &info->tty->flags); + } + info->flags &= ~ASYNC_INITIALIZED; + local_irq_restore(flags); + +#ifdef SERIAL_DEBUG_OPEN + printk(" done\n"); +#endif +} /* shutdown */ + +/* + * This routine finds or computes the various line characteristics. + */ +static void config_setup(struct cyclades_port *info) +{ + unsigned long flags; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; + unsigned cflag; + int i; + unsigned char ti, need_init_chan = 0; + + if (!info->tty || !info->tty->termios) { + return; + } + if (info->line == -1) { + return; + } + cflag = info->tty->termios->c_cflag; + + /* baud rate */ + i = cflag & CBAUD; +#ifdef CBAUDEX +/* Starting with kernel 1.1.65, there is direct support for + higher baud rates. The following code supports those + changes. The conditional aspect allows this driver to be + used for earlier as well as later kernel versions. (The + mapping is slightly different from serial.c because there + is still the possibility of supporting 75 kbit/sec with + the Cyclades board.) + */ + if (i & CBAUDEX) { + if (i == B57600) + i = 16; + else if (i == B115200) + i = 18; +#ifdef B78600 + else if (i == B78600) + i = 17; +#endif + else + info->tty->termios->c_cflag &= ~CBAUDEX; + } +#endif + if (i == 15) { + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + i += 1; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + i += 3; + } + /* Don't ever change the speed of the console port. It will + * run at the speed specified in bootinfo, or at 19.2K */ + /* Actually, it should run at whatever speed 166Bug was using */ + /* Note info->timeout isn't used at present */ + if (info != serial_console_info) { + info->tbpr = baud_bpr[i]; /* Tx BPR */ + info->tco = baud_co[i]; /* Tx CO */ + info->rbpr = baud_bpr[i]; /* Rx BPR */ + info->rco = baud_co[i] >> 5; /* Rx CO */ + if (baud_table[i] == 134) { + info->timeout = + (info->xmit_fifo_size * HZ * 30 / 269) + 2; + /* get it right for 134.5 baud */ + } else if (baud_table[i]) { + info->timeout = + (info->xmit_fifo_size * HZ * 15 / baud_table[i]) + + 2; + /* this needs to be propagated into the card info */ + } else { + info->timeout = 0; + } + } + /* By tradition (is it a standard?) a baud rate of zero + implies the line should be/has been closed. A bit + later in this routine such a test is performed. */ + + /* byte size and parity */ + info->cor7 = 0; + info->cor6 = 0; + info->cor5 = 0; + info->cor4 = (info->default_threshold ? info->default_threshold : baud_cor4[i]); /* receive threshold */ + /* Following two lines added 101295, RGH. */ + /* It is obviously wrong to access CyCORx, and not info->corx here, + * try and remember to fix it later! */ + channel = info->line; + base_addr[CyCAR] = (u_char) channel; + if (C_CLOCAL(info->tty)) { + if (base_addr[CyIER] & CyMdmCh) + base_addr[CyIER] &= ~CyMdmCh; /* without modem intr */ + /* ignore 1->0 modem transitions */ + if (base_addr[CyCOR4] & (CyDSR | CyCTS | CyDCD)) + base_addr[CyCOR4] &= ~(CyDSR | CyCTS | CyDCD); + /* ignore 0->1 modem transitions */ + if (base_addr[CyCOR5] & (CyDSR | CyCTS | CyDCD)) + base_addr[CyCOR5] &= ~(CyDSR | CyCTS | CyDCD); + } else { + if ((base_addr[CyIER] & CyMdmCh) != CyMdmCh) + base_addr[CyIER] |= CyMdmCh; /* with modem intr */ + /* act on 1->0 modem transitions */ + if ((base_addr[CyCOR4] & (CyDSR | CyCTS | CyDCD)) != + (CyDSR | CyCTS | CyDCD)) + base_addr[CyCOR4] |= CyDSR | CyCTS | CyDCD; + /* act on 0->1 modem transitions */ + if ((base_addr[CyCOR5] & (CyDSR | CyCTS | CyDCD)) != + (CyDSR | CyCTS | CyDCD)) + base_addr[CyCOR5] |= CyDSR | CyCTS | CyDCD; + } + info->cor3 = (cflag & CSTOPB) ? Cy_2_STOP : Cy_1_STOP; + info->cor2 = CyETC; + switch (cflag & CSIZE) { + case CS5: + info->cor1 = Cy_5_BITS; + break; + case CS6: + info->cor1 = Cy_6_BITS; + break; + case CS7: + info->cor1 = Cy_7_BITS; + break; + case CS8: + info->cor1 = Cy_8_BITS; + break; + } + if (cflag & PARENB) { + if (cflag & PARODD) { + info->cor1 |= CyPARITY_O; + } else { + info->cor1 |= CyPARITY_E; + } + } else { + info->cor1 |= CyPARITY_NONE; + } + + /* CTS flow control flag */ +#if 0 + /* Don't complcate matters for now! RGH 141095 */ + if (cflag & CRTSCTS) { + info->flags |= ASYNC_CTS_FLOW; + info->cor2 |= CyCtsAE; + } else { + info->flags &= ~ASYNC_CTS_FLOW; + info->cor2 &= ~CyCtsAE; + } +#endif + if (cflag & CLOCAL) + info->flags &= ~ASYNC_CHECK_CD; + else + info->flags |= ASYNC_CHECK_CD; + + /*********************************************** + The hardware option, CyRtsAO, presents RTS when + the chip has characters to send. Since most modems + use RTS as reverse (inbound) flow control, this + option is not used. If inbound flow control is + necessary, DTR can be programmed to provide the + appropriate signals for use with a non-standard + cable. Contact Marcio Saito for details. + ***********************************************/ + + channel = info->line; + + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; + + /* CyCMR set once only in mvme167_init_serial() */ + if (base_addr[CyLICR] != channel << 2) + base_addr[CyLICR] = channel << 2; + if (base_addr[CyLIVR] != 0x5c) + base_addr[CyLIVR] = 0x5c; + + /* tx and rx baud rate */ + + if (base_addr[CyCOR1] != info->cor1) + need_init_chan = 1; + if (base_addr[CyTCOR] != info->tco) + base_addr[CyTCOR] = info->tco; + if (base_addr[CyTBPR] != info->tbpr) + base_addr[CyTBPR] = info->tbpr; + if (base_addr[CyRCOR] != info->rco) + base_addr[CyRCOR] = info->rco; + if (base_addr[CyRBPR] != info->rbpr) + base_addr[CyRBPR] = info->rbpr; + + /* set line characteristics according configuration */ + + if (base_addr[CySCHR1] != START_CHAR(info->tty)) + base_addr[CySCHR1] = START_CHAR(info->tty); + if (base_addr[CySCHR2] != STOP_CHAR(info->tty)) + base_addr[CySCHR2] = STOP_CHAR(info->tty); + if (base_addr[CySCRL] != START_CHAR(info->tty)) + base_addr[CySCRL] = START_CHAR(info->tty); + if (base_addr[CySCRH] != START_CHAR(info->tty)) + base_addr[CySCRH] = START_CHAR(info->tty); + if (base_addr[CyCOR1] != info->cor1) + base_addr[CyCOR1] = info->cor1; + if (base_addr[CyCOR2] != info->cor2) + base_addr[CyCOR2] = info->cor2; + if (base_addr[CyCOR3] != info->cor3) + base_addr[CyCOR3] = info->cor3; + if (base_addr[CyCOR4] != info->cor4) + base_addr[CyCOR4] = info->cor4; + if (base_addr[CyCOR5] != info->cor5) + base_addr[CyCOR5] = info->cor5; + if (base_addr[CyCOR6] != info->cor6) + base_addr[CyCOR6] = info->cor6; + if (base_addr[CyCOR7] != info->cor7) + base_addr[CyCOR7] = info->cor7; + + if (need_init_chan) + write_cy_cmd(base_addr, CyINIT_CHAN); + + base_addr[CyCAR] = (u_char) channel; /* !!! Is this needed? */ + + /* 2ms default rx timeout */ + ti = info->default_timeout ? info->default_timeout : 0x02; + if (base_addr[CyRTPRL] != ti) + base_addr[CyRTPRL] = ti; + if (base_addr[CyRTPRH] != 0) + base_addr[CyRTPRH] = 0; + + /* Set up RTS here also ????? RGH 141095 */ + if (i == 0) { /* baud rate is zero, turn off line */ + if ((base_addr[CyMSVR2] & CyDTR) == CyDTR) + base_addr[CyMSVR2] = 0; +#ifdef SERIAL_DEBUG_DTR + printk("cyc: %d: dropping DTR\n", __LINE__); + printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], + base_addr[CyMSVR2]); +#endif + } else { + if ((base_addr[CyMSVR2] & CyDTR) != CyDTR) + base_addr[CyMSVR2] = CyDTR; +#ifdef SERIAL_DEBUG_DTR + printk("cyc: %d: raising DTR\n", __LINE__); + printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], + base_addr[CyMSVR2]); +#endif + } + + if (info->tty) { + clear_bit(TTY_IO_ERROR, &info->tty->flags); + } + + local_irq_restore(flags); + +} /* config_setup */ + +static int cy_put_char(struct tty_struct *tty, unsigned char ch) +{ + struct cyclades_port *info = tty->driver_data; + unsigned long flags; + +#ifdef SERIAL_DEBUG_IO + printk("cy_put_char %s(0x%02x)\n", tty->name, ch); +#endif + + if (serial_paranoia_check(info, tty->name, "cy_put_char")) + return 0; + + if (!info->xmit_buf) + return 0; + + local_irq_save(flags); + if (info->xmit_cnt >= PAGE_SIZE - 1) { + local_irq_restore(flags); + return 0; + } + + info->xmit_buf[info->xmit_head++] = ch; + info->xmit_head &= PAGE_SIZE - 1; + info->xmit_cnt++; + local_irq_restore(flags); + return 1; +} /* cy_put_char */ + +static void cy_flush_chars(struct tty_struct *tty) +{ + struct cyclades_port *info = tty->driver_data; + unsigned long flags; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; + +#ifdef SERIAL_DEBUG_IO + printk("cy_flush_chars %s\n", tty->name); /* */ +#endif + + if (serial_paranoia_check(info, tty->name, "cy_flush_chars")) + return; + + if (info->xmit_cnt <= 0 || tty->stopped + || tty->hw_stopped || !info->xmit_buf) + return; + + channel = info->line; + + local_irq_save(flags); + base_addr[CyCAR] = channel; + base_addr[CyIER] |= CyTxMpty; + local_irq_restore(flags); +} /* cy_flush_chars */ + +/* This routine gets called when tty_write has put something into + the write_queue. If the port is not already transmitting stuff, + start it off by enabling interrupts. The interrupt service + routine will then ensure that the characters are sent. If the + port is already active, there is no need to kick it. + */ +static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) +{ + struct cyclades_port *info = tty->driver_data; + unsigned long flags; + int c, total = 0; + +#ifdef SERIAL_DEBUG_IO + printk("cy_write %s\n", tty->name); /* */ +#endif + + if (serial_paranoia_check(info, tty->name, "cy_write")) { + return 0; + } + + if (!info->xmit_buf) { + return 0; + } + + while (1) { + local_irq_save(flags); + c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + if (c <= 0) { + local_irq_restore(flags); + break; + } + + memcpy(info->xmit_buf + info->xmit_head, buf, c); + info->xmit_head = + (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1); + info->xmit_cnt += c; + local_irq_restore(flags); + + buf += c; + count -= c; + total += c; + } + + if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { + start_xmit(info); + } + return total; +} /* cy_write */ + +static int cy_write_room(struct tty_struct *tty) +{ + struct cyclades_port *info = tty->driver_data; + int ret; + +#ifdef SERIAL_DEBUG_IO + printk("cy_write_room %s\n", tty->name); /* */ +#endif + + if (serial_paranoia_check(info, tty->name, "cy_write_room")) + return 0; + ret = PAGE_SIZE - info->xmit_cnt - 1; + if (ret < 0) + ret = 0; + return ret; +} /* cy_write_room */ + +static int cy_chars_in_buffer(struct tty_struct *tty) +{ + struct cyclades_port *info = tty->driver_data; + +#ifdef SERIAL_DEBUG_IO + printk("cy_chars_in_buffer %s %d\n", tty->name, info->xmit_cnt); /* */ +#endif + + if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer")) + return 0; + + return info->xmit_cnt; +} /* cy_chars_in_buffer */ + +static void cy_flush_buffer(struct tty_struct *tty) +{ + struct cyclades_port *info = tty->driver_data; + unsigned long flags; + +#ifdef SERIAL_DEBUG_IO + printk("cy_flush_buffer %s\n", tty->name); /* */ +#endif + + if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) + return; + local_irq_save(flags); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + local_irq_restore(flags); + tty_wakeup(tty); +} /* cy_flush_buffer */ + +/* This routine is called by the upper-layer tty layer to signal + that incoming characters should be throttled or that the + throttle should be released. + */ +static void cy_throttle(struct tty_struct *tty) +{ + struct cyclades_port *info = tty->driver_data; + unsigned long flags; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; + +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + printk("throttle %s: %d....\n", tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); + printk("cy_throttle %s\n", tty->name); +#endif + + if (serial_paranoia_check(info, tty->name, "cy_nthrottle")) { + return; + } + + if (I_IXOFF(tty)) { + info->x_char = STOP_CHAR(tty); + /* Should use the "Send Special Character" feature!!! */ + } + + channel = info->line; + + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; + base_addr[CyMSVR1] = 0; + local_irq_restore(flags); +} /* cy_throttle */ + +static void cy_unthrottle(struct tty_struct *tty) +{ + struct cyclades_port *info = tty->driver_data; + unsigned long flags; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; + +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + printk("throttle %s: %d....\n", tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); + printk("cy_unthrottle %s\n", tty->name); +#endif + + if (serial_paranoia_check(info, tty->name, "cy_nthrottle")) { + return; + } + + if (I_IXOFF(tty)) { + info->x_char = START_CHAR(tty); + /* Should use the "Send Special Character" feature!!! */ + } + + channel = info->line; + + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; + base_addr[CyMSVR1] = CyRTS; + local_irq_restore(flags); +} /* cy_unthrottle */ + +static int +get_serial_info(struct cyclades_port *info, + struct serial_struct __user * retinfo) +{ + struct serial_struct tmp; + +/* CP('g'); */ + if (!retinfo) + return -EFAULT; + memset(&tmp, 0, sizeof(tmp)); + tmp.type = info->type; + tmp.line = info->line; + tmp.port = info->line; + tmp.irq = 0; + tmp.flags = info->flags; + tmp.baud_base = 0; /*!!! */ + tmp.close_delay = info->close_delay; + tmp.custom_divisor = 0; /*!!! */ + tmp.hub6 = 0; /*!!! */ + return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; +} /* get_serial_info */ + +static int +set_serial_info(struct cyclades_port *info, + struct serial_struct __user * new_info) +{ + struct serial_struct new_serial; + struct cyclades_port old_info; + +/* CP('s'); */ + if (!new_info) + return -EFAULT; + if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) + return -EFAULT; + old_info = *info; + + if (!capable(CAP_SYS_ADMIN)) { + if ((new_serial.close_delay != info->close_delay) || + ((new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) != + (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK))) + return -EPERM; + info->flags = ((info->flags & ~ASYNC_USR_MASK) | + (new_serial.flags & ASYNC_USR_MASK)); + goto check_and_exit; + } + + /* + * OK, past this point, all the error checking has been done. + * At this point, we start making changes..... + */ + + info->flags = ((info->flags & ~ASYNC_FLAGS) | + (new_serial.flags & ASYNC_FLAGS)); + info->close_delay = new_serial.close_delay; + +check_and_exit: + if (info->flags & ASYNC_INITIALIZED) { + config_setup(info); + return 0; + } + return startup(info); +} /* set_serial_info */ + +static int cy_tiocmget(struct tty_struct *tty) +{ + struct cyclades_port *info = tty->driver_data; + int channel; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + unsigned long flags; + unsigned char status; + + channel = info->line; + + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; + status = base_addr[CyMSVR1] | base_addr[CyMSVR2]; + local_irq_restore(flags); + + return ((status & CyRTS) ? TIOCM_RTS : 0) + | ((status & CyDTR) ? TIOCM_DTR : 0) + | ((status & CyDCD) ? TIOCM_CAR : 0) + | ((status & CyDSR) ? TIOCM_DSR : 0) + | ((status & CyCTS) ? TIOCM_CTS : 0); +} /* cy_tiocmget */ + +static int +cy_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) +{ + struct cyclades_port *info = tty->driver_data; + int channel; + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + unsigned long flags; + + channel = info->line; + + if (set & TIOCM_RTS) { + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; + base_addr[CyMSVR1] = CyRTS; + local_irq_restore(flags); + } + if (set & TIOCM_DTR) { + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; +/* CP('S');CP('2'); */ + base_addr[CyMSVR2] = CyDTR; +#ifdef SERIAL_DEBUG_DTR + printk("cyc: %d: raising DTR\n", __LINE__); + printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], + base_addr[CyMSVR2]); +#endif + local_irq_restore(flags); + } + + if (clear & TIOCM_RTS) { + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; + base_addr[CyMSVR1] = 0; + local_irq_restore(flags); + } + if (clear & TIOCM_DTR) { + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; +/* CP('C');CP('2'); */ + base_addr[CyMSVR2] = 0; +#ifdef SERIAL_DEBUG_DTR + printk("cyc: %d: dropping DTR\n", __LINE__); + printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], + base_addr[CyMSVR2]); +#endif + local_irq_restore(flags); + } + + return 0; +} /* set_modem_info */ + +static void send_break(struct cyclades_port *info, int duration) +{ /* Let the transmit ISR take care of this (since it + requires stuffing characters into the output stream). + */ + info->x_break = duration; + if (!info->xmit_cnt) { + start_xmit(info); + } +} /* send_break */ + +static int +get_mon_info(struct cyclades_port *info, struct cyclades_monitor __user * mon) +{ + + if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor))) + return -EFAULT; + info->mon.int_count = 0; + info->mon.char_count = 0; + info->mon.char_max = 0; + info->mon.char_last = 0; + return 0; +} + +static int set_threshold(struct cyclades_port *info, unsigned long __user * arg) +{ + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + unsigned long value; + int channel; + + if (get_user(value, arg)) + return -EFAULT; + + channel = info->line; + info->cor4 &= ~CyREC_FIFO; + info->cor4 |= value & CyREC_FIFO; + base_addr[CyCOR4] = info->cor4; + return 0; +} + +static int +get_threshold(struct cyclades_port *info, unsigned long __user * value) +{ + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; + unsigned long tmp; + + channel = info->line; + + tmp = base_addr[CyCOR4] & CyREC_FIFO; + return put_user(tmp, value); +} + +static int +set_default_threshold(struct cyclades_port *info, unsigned long __user * arg) +{ + unsigned long value; + + if (get_user(value, arg)) + return -EFAULT; + + info->default_threshold = value & 0x0f; + return 0; +} + +static int +get_default_threshold(struct cyclades_port *info, unsigned long __user * value) +{ + return put_user(info->default_threshold, value); +} + +static int set_timeout(struct cyclades_port *info, unsigned long __user * arg) +{ + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; + unsigned long value; + + if (get_user(value, arg)) + return -EFAULT; + + channel = info->line; + + base_addr[CyRTPRL] = value & 0xff; + base_addr[CyRTPRH] = (value >> 8) & 0xff; + return 0; +} + +static int get_timeout(struct cyclades_port *info, unsigned long __user * value) +{ + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; + unsigned long tmp; + + channel = info->line; + + tmp = base_addr[CyRTPRL]; + return put_user(tmp, value); +} + +static int set_default_timeout(struct cyclades_port *info, unsigned long value) +{ + info->default_timeout = value & 0xff; + return 0; +} + +static int +get_default_timeout(struct cyclades_port *info, unsigned long __user * value) +{ + return put_user(info->default_timeout, value); +} + +static int +cy_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + struct cyclades_port *info = tty->driver_data; + int ret_val = 0; + void __user *argp = (void __user *)arg; + +#ifdef SERIAL_DEBUG_OTHER + printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */ +#endif + + tty_lock(); + + switch (cmd) { + case CYGETMON: + ret_val = get_mon_info(info, argp); + break; + case CYGETTHRESH: + ret_val = get_threshold(info, argp); + break; + case CYSETTHRESH: + ret_val = set_threshold(info, argp); + break; + case CYGETDEFTHRESH: + ret_val = get_default_threshold(info, argp); + break; + case CYSETDEFTHRESH: + ret_val = set_default_threshold(info, argp); + break; + case CYGETTIMEOUT: + ret_val = get_timeout(info, argp); + break; + case CYSETTIMEOUT: + ret_val = set_timeout(info, argp); + break; + case CYGETDEFTIMEOUT: + ret_val = get_default_timeout(info, argp); + break; + case CYSETDEFTIMEOUT: + ret_val = set_default_timeout(info, (unsigned long)arg); + break; + case TCSBRK: /* SVID version: non-zero arg --> no break */ + ret_val = tty_check_change(tty); + if (ret_val) + break; + tty_wait_until_sent(tty, 0); + if (!arg) + send_break(info, HZ / 4); /* 1/4 second */ + break; + case TCSBRKP: /* support for POSIX tcsendbreak() */ + ret_val = tty_check_change(tty); + if (ret_val) + break; + tty_wait_until_sent(tty, 0); + send_break(info, arg ? arg * (HZ / 10) : HZ / 4); + break; + +/* The following commands are incompletely implemented!!! */ + case TIOCGSERIAL: + ret_val = get_serial_info(info, argp); + break; + case TIOCSSERIAL: + ret_val = set_serial_info(info, argp); + break; + default: + ret_val = -ENOIOCTLCMD; + } + tty_unlock(); + +#ifdef SERIAL_DEBUG_OTHER + printk("cy_ioctl done\n"); +#endif + + return ret_val; +} /* cy_ioctl */ + +static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) +{ + struct cyclades_port *info = tty->driver_data; + +#ifdef SERIAL_DEBUG_OTHER + printk("cy_set_termios %s\n", tty->name); +#endif + + if (tty->termios->c_cflag == old_termios->c_cflag) + return; + config_setup(info); + + if ((old_termios->c_cflag & CRTSCTS) && + !(tty->termios->c_cflag & CRTSCTS)) { + tty->stopped = 0; + cy_start(tty); + } +#ifdef tytso_patch_94Nov25_1726 + if (!(old_termios->c_cflag & CLOCAL) && + (tty->termios->c_cflag & CLOCAL)) + wake_up_interruptible(&info->open_wait); +#endif +} /* cy_set_termios */ + +static void cy_close(struct tty_struct *tty, struct file *filp) +{ + struct cyclades_port *info = tty->driver_data; + +/* CP('C'); */ +#ifdef SERIAL_DEBUG_OTHER + printk("cy_close %s\n", tty->name); +#endif + + if (!info || serial_paranoia_check(info, tty->name, "cy_close")) { + return; + } +#ifdef SERIAL_DEBUG_OPEN + printk("cy_close %s, count = %d\n", tty->name, info->count); +#endif + + if ((tty->count == 1) && (info->count != 1)) { + /* + * Uh, oh. tty->count is 1, which means that the tty + * structure will be freed. Info->count should always + * be one in these conditions. If it's greater than + * one, we've got real problems, since it means the + * serial port won't be shutdown. + */ + printk("cy_close: bad serial port count; tty->count is 1, " + "info->count is %d\n", info->count); + info->count = 1; + } +#ifdef SERIAL_DEBUG_COUNT + printk("cyc: %d: decrementing count to %d\n", __LINE__, + info->count - 1); +#endif + if (--info->count < 0) { + printk("cy_close: bad serial port count for ttys%d: %d\n", + info->line, info->count); +#ifdef SERIAL_DEBUG_COUNT + printk("cyc: %d: setting count to 0\n", __LINE__); +#endif + info->count = 0; + } + if (info->count) + return; + info->flags |= ASYNC_CLOSING; + if (info->flags & ASYNC_INITIALIZED) + tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ + shutdown(info); + cy_flush_buffer(tty); + tty_ldisc_flush(tty); + info->tty = NULL; + if (info->blocked_open) { + if (info->close_delay) { + msleep_interruptible(jiffies_to_msecs + (info->close_delay)); + } + wake_up_interruptible(&info->open_wait); + } + info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); + wake_up_interruptible(&info->close_wait); + +#ifdef SERIAL_DEBUG_OTHER + printk("cy_close done\n"); +#endif +} /* cy_close */ + +/* + * cy_hangup() --- called by tty_hangup() when a hangup is signaled. + */ +void cy_hangup(struct tty_struct *tty) +{ + struct cyclades_port *info = tty->driver_data; + +#ifdef SERIAL_DEBUG_OTHER + printk("cy_hangup %s\n", tty->name); /* */ +#endif + + if (serial_paranoia_check(info, tty->name, "cy_hangup")) + return; + + shutdown(info); +#if 0 + info->event = 0; + info->count = 0; +#ifdef SERIAL_DEBUG_COUNT + printk("cyc: %d: setting count to 0\n", __LINE__); +#endif + info->tty = 0; +#endif + info->flags &= ~ASYNC_NORMAL_ACTIVE; + wake_up_interruptible(&info->open_wait); +} /* cy_hangup */ + +/* + * ------------------------------------------------------------ + * cy_open() and friends + * ------------------------------------------------------------ + */ + +static int +block_til_ready(struct tty_struct *tty, struct file *filp, + struct cyclades_port *info) +{ + DECLARE_WAITQUEUE(wait, current); + unsigned long flags; + int channel; + int retval; + volatile u_char *base_addr = (u_char *) BASE_ADDR; + + /* + * If the device is in the middle of being closed, then block + * until it's done, and then try again. + */ + if (info->flags & ASYNC_CLOSING) { + interruptible_sleep_on(&info->close_wait); + if (info->flags & ASYNC_HUP_NOTIFY) { + return -EAGAIN; + } else { + return -ERESTARTSYS; + } + } + + /* + * If non-blocking mode is set, then make the check up front + * and then exit. + */ + if (filp->f_flags & O_NONBLOCK) { + info->flags |= ASYNC_NORMAL_ACTIVE; + return 0; + } + + /* + * Block waiting for the carrier detect and the line to become + * free (i.e., not in use by the callout). While we are in + * this loop, info->count is dropped by one, so that + * cy_close() knows when to free things. We restore it upon + * exit, either normal or abnormal. + */ + retval = 0; + add_wait_queue(&info->open_wait, &wait); +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready before block: %s, count = %d\n", + tty->name, info->count); + /**/ +#endif + info->count--; +#ifdef SERIAL_DEBUG_COUNT + printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count); +#endif + info->blocked_open++; + + channel = info->line; + + while (1) { + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; + base_addr[CyMSVR1] = CyRTS; +/* CP('S');CP('4'); */ + base_addr[CyMSVR2] = CyDTR; +#ifdef SERIAL_DEBUG_DTR + printk("cyc: %d: raising DTR\n", __LINE__); + printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], + base_addr[CyMSVR2]); +#endif + local_irq_restore(flags); + set_current_state(TASK_INTERRUPTIBLE); + if (tty_hung_up_p(filp) + || !(info->flags & ASYNC_INITIALIZED)) { + if (info->flags & ASYNC_HUP_NOTIFY) { + retval = -EAGAIN; + } else { + retval = -ERESTARTSYS; + } + break; + } + local_irq_save(flags); + base_addr[CyCAR] = (u_char) channel; +/* CP('L');CP1(1 && C_CLOCAL(tty)); CP1(1 && (base_addr[CyMSVR1] & CyDCD) ); */ + if (!(info->flags & ASYNC_CLOSING) + && (C_CLOCAL(tty) + || (base_addr[CyMSVR1] & CyDCD))) { + local_irq_restore(flags); + break; + } + local_irq_restore(flags); + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready blocking: %s, count = %d\n", + tty->name, info->count); + /**/ +#endif + tty_unlock(); + schedule(); + tty_lock(); + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&info->open_wait, &wait); + if (!tty_hung_up_p(filp)) { + info->count++; +#ifdef SERIAL_DEBUG_COUNT + printk("cyc: %d: incrementing count to %d\n", __LINE__, + info->count); +#endif + } + info->blocked_open--; +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready after blocking: %s, count = %d\n", + tty->name, info->count); + /**/ +#endif + if (retval) + return retval; + info->flags |= ASYNC_NORMAL_ACTIVE; + return 0; +} /* block_til_ready */ + +/* + * This routine is called whenever a serial port is opened. It + * performs the serial-specific initialization for the tty structure. + */ +int cy_open(struct tty_struct *tty, struct file *filp) +{ + struct cyclades_port *info; + int retval, line; + +/* CP('O'); */ + line = tty->index; + if ((line < 0) || (NR_PORTS <= line)) { + return -ENODEV; + } + info = &cy_port[line]; + if (info->line < 0) { + return -ENODEV; + } +#ifdef SERIAL_DEBUG_OTHER + printk("cy_open %s\n", tty->name); /* */ +#endif + if (serial_paranoia_check(info, tty->name, "cy_open")) { + return -ENODEV; + } +#ifdef SERIAL_DEBUG_OPEN + printk("cy_open %s, count = %d\n", tty->name, info->count); + /**/ +#endif + info->count++; +#ifdef SERIAL_DEBUG_COUNT + printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count); +#endif + tty->driver_data = info; + info->tty = tty; + + /* + * Start up serial port + */ + retval = startup(info); + if (retval) { + return retval; + } + + retval = block_til_ready(tty, filp, info); + if (retval) { +#ifdef SERIAL_DEBUG_OPEN + printk("cy_open returning after block_til_ready with %d\n", + retval); +#endif + return retval; + } +#ifdef SERIAL_DEBUG_OPEN + printk("cy_open done\n"); + /**/ +#endif + return 0; +} /* cy_open */ + +/* + * --------------------------------------------------------------------- + * serial167_init() and friends + * + * serial167_init() is called at boot-time to initialize the serial driver. + * --------------------------------------------------------------------- + */ + +/* + * This routine prints out the appropriate serial driver version + * number, and identifies which options were configured into this + * driver. + */ +static void show_version(void) +{ + printk("MVME166/167 cd2401 driver\n"); +} /* show_version */ + +/* initialize chips on card -- return number of valid + chips (which is number of ports/4) */ + +/* + * This initialises the hardware to a reasonable state. It should + * probe the chip first so as to copy 166-Bug setup as a default for + * port 0. It initialises CMR to CyASYNC; that is never done again, so + * as to limit the number of CyINIT_CHAN commands in normal running. + * + * ... I wonder what I should do if this fails ... + */ + +void mvme167_serial_console_setup(int cflag) +{ + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int ch; + u_char spd; + u_char rcor, rbpr, badspeed = 0; + unsigned long flags; + + local_irq_save(flags); + + /* + * First probe channel zero of the chip, to see what speed has + * been selected. + */ + + base_addr[CyCAR] = 0; + + rcor = base_addr[CyRCOR] << 5; + rbpr = base_addr[CyRBPR]; + + for (spd = 0; spd < sizeof(baud_bpr); spd++) + if (rbpr == baud_bpr[spd] && rcor == baud_co[spd]) + break; + if (spd >= sizeof(baud_bpr)) { + spd = 14; /* 19200 */ + badspeed = 1; /* Failed to identify speed */ + } + initial_console_speed = spd; + + /* OK, we have chosen a speed, now reset and reinitialise */ + + my_udelay(20000L); /* Allow time for any active o/p to complete */ + if (base_addr[CyCCR] != 0x00) { + local_irq_restore(flags); + /* printk(" chip is never idle (CCR != 0)\n"); */ + return; + } + + base_addr[CyCCR] = CyCHIP_RESET; /* Reset the chip */ + my_udelay(1000L); + + if (base_addr[CyGFRCR] == 0x00) { + local_irq_restore(flags); + /* printk(" chip is not responding (GFRCR stayed 0)\n"); */ + return; + } + + /* + * System clock is 20Mhz, divided by 2048, so divide by 10 for a 1.0ms + * tick + */ + + base_addr[CyTPR] = 10; + + base_addr[CyPILR1] = 0x01; /* Interrupt level for modem change */ + base_addr[CyPILR2] = 0x02; /* Interrupt level for tx ints */ + base_addr[CyPILR3] = 0x03; /* Interrupt level for rx ints */ + + /* + * Attempt to set up all channels to something reasonable, and + * bang out a INIT_CHAN command. We should then be able to limit + * the amount of fiddling we have to do in normal running. + */ + + for (ch = 3; ch >= 0; ch--) { + base_addr[CyCAR] = (u_char) ch; + base_addr[CyIER] = 0; + base_addr[CyCMR] = CyASYNC; + base_addr[CyLICR] = (u_char) ch << 2; + base_addr[CyLIVR] = 0x5c; + base_addr[CyTCOR] = baud_co[spd]; + base_addr[CyTBPR] = baud_bpr[spd]; + base_addr[CyRCOR] = baud_co[spd] >> 5; + base_addr[CyRBPR] = baud_bpr[spd]; + base_addr[CySCHR1] = 'Q' & 0x1f; + base_addr[CySCHR2] = 'X' & 0x1f; + base_addr[CySCRL] = 0; + base_addr[CySCRH] = 0; + base_addr[CyCOR1] = Cy_8_BITS | CyPARITY_NONE; + base_addr[CyCOR2] = 0; + base_addr[CyCOR3] = Cy_1_STOP; + base_addr[CyCOR4] = baud_cor4[spd]; + base_addr[CyCOR5] = 0; + base_addr[CyCOR6] = 0; + base_addr[CyCOR7] = 0; + base_addr[CyRTPRL] = 2; + base_addr[CyRTPRH] = 0; + base_addr[CyMSVR1] = 0; + base_addr[CyMSVR2] = 0; + write_cy_cmd(base_addr, CyINIT_CHAN | CyDIS_RCVR | CyDIS_XMTR); + } + + /* + * Now do specials for channel zero.... + */ + + base_addr[CyMSVR1] = CyRTS; + base_addr[CyMSVR2] = CyDTR; + base_addr[CyIER] = CyRxData; + write_cy_cmd(base_addr, CyENB_RCVR | CyENB_XMTR); + + local_irq_restore(flags); + + my_udelay(20000L); /* Let it all settle down */ + + printk("CD2401 initialised, chip is rev 0x%02x\n", base_addr[CyGFRCR]); + if (badspeed) + printk + (" WARNING: Failed to identify line speed, rcor=%02x,rbpr=%02x\n", + rcor >> 5, rbpr); +} /* serial_console_init */ + +static const struct tty_operations cy_ops = { + .open = cy_open, + .close = cy_close, + .write = cy_write, + .put_char = cy_put_char, + .flush_chars = cy_flush_chars, + .write_room = cy_write_room, + .chars_in_buffer = cy_chars_in_buffer, + .flush_buffer = cy_flush_buffer, + .ioctl = cy_ioctl, + .throttle = cy_throttle, + .unthrottle = cy_unthrottle, + .set_termios = cy_set_termios, + .stop = cy_stop, + .start = cy_start, + .hangup = cy_hangup, + .tiocmget = cy_tiocmget, + .tiocmset = cy_tiocmset, +}; + +/* The serial driver boot-time initialization code! + Hardware I/O ports are mapped to character special devices on a + first found, first allocated manner. That is, this code searches + for Cyclom cards in the system. As each is found, it is probed + to discover how many chips (and thus how many ports) are present. + These ports are mapped to the tty ports 64 and upward in monotonic + fashion. If an 8-port card is replaced with a 16-port card, the + port mapping on a following card will shift. + + This approach is different from what is used in the other serial + device driver because the Cyclom is more properly a multiplexer, + not just an aggregation of serial ports on one card. + + If there are more cards with more ports than have been statically + allocated above, a warning is printed and the extra ports are ignored. + */ +static int __init serial167_init(void) +{ + struct cyclades_port *info; + int ret = 0; + int good_ports = 0; + int port_num = 0; + int index; + int DefSpeed; +#ifdef notyet + struct sigaction sa; +#endif + + if (!(mvme16x_config & MVME16x_CONFIG_GOT_CD2401)) + return 0; + + cy_serial_driver = alloc_tty_driver(NR_PORTS); + if (!cy_serial_driver) + return -ENOMEM; + +#if 0 + scrn[1] = '\0'; +#endif + + show_version(); + + /* Has "console=0,9600n8" been used in bootinfo to change speed? */ + if (serial_console_cflag) + DefSpeed = serial_console_cflag & 0017; + else { + DefSpeed = initial_console_speed; + serial_console_info = &cy_port[0]; + serial_console_cflag = DefSpeed | CS8; +#if 0 + serial_console = 64; /*callout_driver.minor_start */ +#endif + } + + /* Initialize the tty_driver structure */ + + cy_serial_driver->owner = THIS_MODULE; + cy_serial_driver->name = "ttyS"; + cy_serial_driver->major = TTY_MAJOR; + cy_serial_driver->minor_start = 64; + cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL; + cy_serial_driver->subtype = SERIAL_TYPE_NORMAL; + cy_serial_driver->init_termios = tty_std_termios; + cy_serial_driver->init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + cy_serial_driver->flags = TTY_DRIVER_REAL_RAW; + tty_set_operations(cy_serial_driver, &cy_ops); + + ret = tty_register_driver(cy_serial_driver); + if (ret) { + printk(KERN_ERR "Couldn't register MVME166/7 serial driver\n"); + put_tty_driver(cy_serial_driver); + return ret; + } + + port_num = 0; + info = cy_port; + for (index = 0; index < 1; index++) { + + good_ports = 4; + + if (port_num < NR_PORTS) { + while (good_ports-- && port_num < NR_PORTS) { + /*** initialize port ***/ + info->magic = CYCLADES_MAGIC; + info->type = PORT_CIRRUS; + info->card = index; + info->line = port_num; + info->flags = STD_COM_FLAGS; + info->tty = NULL; + info->xmit_fifo_size = 12; + info->cor1 = CyPARITY_NONE | Cy_8_BITS; + info->cor2 = CyETC; + info->cor3 = Cy_1_STOP; + info->cor4 = 0x08; /* _very_ small receive threshold */ + info->cor5 = 0; + info->cor6 = 0; + info->cor7 = 0; + info->tbpr = baud_bpr[DefSpeed]; /* Tx BPR */ + info->tco = baud_co[DefSpeed]; /* Tx CO */ + info->rbpr = baud_bpr[DefSpeed]; /* Rx BPR */ + info->rco = baud_co[DefSpeed] >> 5; /* Rx CO */ + info->close_delay = 0; + info->x_char = 0; + info->count = 0; +#ifdef SERIAL_DEBUG_COUNT + printk("cyc: %d: setting count to 0\n", + __LINE__); +#endif + info->blocked_open = 0; + info->default_threshold = 0; + info->default_timeout = 0; + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + /* info->session */ + /* info->pgrp */ +/*** !!!!!!!! this may expose new bugs !!!!!!!!! *********/ + info->read_status_mask = + CyTIMEOUT | CySPECHAR | CyBREAK | CyPARITY | + CyFRAME | CyOVERRUN; + /* info->timeout */ + + printk("ttyS%d ", info->line); + port_num++; + info++; + if (!(port_num & 7)) { + printk("\n "); + } + } + } + printk("\n"); + } + while (port_num < NR_PORTS) { + info->line = -1; + port_num++; + info++; + } + + ret = request_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt, 0, + "cd2401_errors", cd2401_rxerr_interrupt); + if (ret) { + printk(KERN_ERR "Could't get cd2401_errors IRQ"); + goto cleanup_serial_driver; + } + + ret = request_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt, 0, + "cd2401_modem", cd2401_modem_interrupt); + if (ret) { + printk(KERN_ERR "Could't get cd2401_modem IRQ"); + goto cleanup_irq_cd2401_errors; + } + + ret = request_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt, 0, + "cd2401_txints", cd2401_tx_interrupt); + if (ret) { + printk(KERN_ERR "Could't get cd2401_txints IRQ"); + goto cleanup_irq_cd2401_modem; + } + + ret = request_irq(MVME167_IRQ_SER_RX, cd2401_rx_interrupt, 0, + "cd2401_rxints", cd2401_rx_interrupt); + if (ret) { + printk(KERN_ERR "Could't get cd2401_rxints IRQ"); + goto cleanup_irq_cd2401_txints; + } + + /* Now we have registered the interrupt handlers, allow the interrupts */ + + pcc2chip[PccSCCMICR] = 0x15; /* Serial ints are level 5 */ + pcc2chip[PccSCCTICR] = 0x15; + pcc2chip[PccSCCRICR] = 0x15; + + pcc2chip[PccIMLR] = 3; /* Allow PCC2 ints above 3!? */ + + return 0; +cleanup_irq_cd2401_txints: + free_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt); +cleanup_irq_cd2401_modem: + free_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt); +cleanup_irq_cd2401_errors: + free_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt); +cleanup_serial_driver: + if (tty_unregister_driver(cy_serial_driver)) + printk(KERN_ERR + "Couldn't unregister MVME166/7 serial driver\n"); + put_tty_driver(cy_serial_driver); + return ret; +} /* serial167_init */ + +module_init(serial167_init); + +#ifdef CYCLOM_SHOW_STATUS +static void show_status(int line_num) +{ + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + int channel; + struct cyclades_port *info; + unsigned long flags; + + info = &cy_port[line_num]; + channel = info->line; + printk(" channel %d\n", channel); + /**/ printk(" cy_port\n"); + printk(" card line flags = %d %d %x\n", + info->card, info->line, info->flags); + printk + (" *tty read_status_mask timeout xmit_fifo_size = %lx %x %x %x\n", + (long)info->tty, info->read_status_mask, info->timeout, + info->xmit_fifo_size); + printk(" cor1,cor2,cor3,cor4,cor5,cor6,cor7 = %x %x %x %x %x %x %x\n", + info->cor1, info->cor2, info->cor3, info->cor4, info->cor5, + info->cor6, info->cor7); + printk(" tbpr,tco,rbpr,rco = %d %d %d %d\n", info->tbpr, info->tco, + info->rbpr, info->rco); + printk(" close_delay event count = %d %d %d\n", info->close_delay, + info->event, info->count); + printk(" x_char blocked_open = %x %x\n", info->x_char, + info->blocked_open); + printk(" open_wait = %lx %lx %lx\n", (long)info->open_wait); + + local_irq_save(flags); + +/* Global Registers */ + + printk(" CyGFRCR %x\n", base_addr[CyGFRCR]); + printk(" CyCAR %x\n", base_addr[CyCAR]); + printk(" CyRISR %x\n", base_addr[CyRISR]); + printk(" CyTISR %x\n", base_addr[CyTISR]); + printk(" CyMISR %x\n", base_addr[CyMISR]); + printk(" CyRIR %x\n", base_addr[CyRIR]); + printk(" CyTIR %x\n", base_addr[CyTIR]); + printk(" CyMIR %x\n", base_addr[CyMIR]); + printk(" CyTPR %x\n", base_addr[CyTPR]); + + base_addr[CyCAR] = (u_char) channel; + +/* Virtual Registers */ + +#if 0 + printk(" CyRIVR %x\n", base_addr[CyRIVR]); + printk(" CyTIVR %x\n", base_addr[CyTIVR]); + printk(" CyMIVR %x\n", base_addr[CyMIVR]); + printk(" CyMISR %x\n", base_addr[CyMISR]); +#endif + +/* Channel Registers */ + + printk(" CyCCR %x\n", base_addr[CyCCR]); + printk(" CyIER %x\n", base_addr[CyIER]); + printk(" CyCOR1 %x\n", base_addr[CyCOR1]); + printk(" CyCOR2 %x\n", base_addr[CyCOR2]); + printk(" CyCOR3 %x\n", base_addr[CyCOR3]); + printk(" CyCOR4 %x\n", base_addr[CyCOR4]); + printk(" CyCOR5 %x\n", base_addr[CyCOR5]); +#if 0 + printk(" CyCCSR %x\n", base_addr[CyCCSR]); + printk(" CyRDCR %x\n", base_addr[CyRDCR]); +#endif + printk(" CySCHR1 %x\n", base_addr[CySCHR1]); + printk(" CySCHR2 %x\n", base_addr[CySCHR2]); +#if 0 + printk(" CySCHR3 %x\n", base_addr[CySCHR3]); + printk(" CySCHR4 %x\n", base_addr[CySCHR4]); + printk(" CySCRL %x\n", base_addr[CySCRL]); + printk(" CySCRH %x\n", base_addr[CySCRH]); + printk(" CyLNC %x\n", base_addr[CyLNC]); + printk(" CyMCOR1 %x\n", base_addr[CyMCOR1]); + printk(" CyMCOR2 %x\n", base_addr[CyMCOR2]); +#endif + printk(" CyRTPRL %x\n", base_addr[CyRTPRL]); + printk(" CyRTPRH %x\n", base_addr[CyRTPRH]); + printk(" CyMSVR1 %x\n", base_addr[CyMSVR1]); + printk(" CyMSVR2 %x\n", base_addr[CyMSVR2]); + printk(" CyRBPR %x\n", base_addr[CyRBPR]); + printk(" CyRCOR %x\n", base_addr[CyRCOR]); + printk(" CyTBPR %x\n", base_addr[CyTBPR]); + printk(" CyTCOR %x\n", base_addr[CyTCOR]); + + local_irq_restore(flags); +} /* show_status */ +#endif + +#if 0 +/* Dummy routine in mvme16x/config.c for now */ + +/* Serial console setup. Called from linux/init/main.c */ + +void console_setup(char *str, int *ints) +{ + char *s; + int baud, bits, parity; + int cflag = 0; + + /* Sanity check. */ + if (ints[0] > 3 || ints[1] > 3) + return; + + /* Get baud, bits and parity */ + baud = 2400; + bits = 8; + parity = 'n'; + if (ints[2]) + baud = ints[2]; + if ((s = strchr(str, ','))) { + do { + s++; + } while (*s >= '0' && *s <= '9'); + if (*s) + parity = *s++; + if (*s) + bits = *s - '0'; + } + + /* Now construct a cflag setting. */ + switch (baud) { + case 1200: + cflag |= B1200; + break; + case 9600: + cflag |= B9600; + break; + case 19200: + cflag |= B19200; + break; + case 38400: + cflag |= B38400; + break; + case 2400: + default: + cflag |= B2400; + break; + } + switch (bits) { + case 7: + cflag |= CS7; + break; + default: + case 8: + cflag |= CS8; + break; + } + switch (parity) { + case 'o': + case 'O': + cflag |= PARODD; + break; + case 'e': + case 'E': + cflag |= PARENB; + break; + } + + serial_console_info = &cy_port[ints[1]]; + serial_console_cflag = cflag; + serial_console = ints[1] + 64; /*callout_driver.minor_start */ +} +#endif + +/* + * The following is probably out of date for 2.1.x serial console stuff. + * + * The console is registered early on from arch/m68k/kernel/setup.c, and + * it therefore relies on the chip being setup correctly by 166-Bug. This + * seems reasonable, as the serial port has been used to invoke the system + * boot. It also means that this function must not rely on any data + * initialisation performed by serial167_init() etc. + * + * Of course, once the console has been registered, we had better ensure + * that serial167_init() doesn't leave the chip non-functional. + * + * The console must be locked when we get here. + */ + +void serial167_console_write(struct console *co, const char *str, + unsigned count) +{ + volatile unsigned char *base_addr = (u_char *) BASE_ADDR; + unsigned long flags; + volatile u_char sink; + u_char ier; + int port; + u_char do_lf = 0; + int i = 0; + + local_irq_save(flags); + + /* Ensure transmitter is enabled! */ + + port = 0; + base_addr[CyCAR] = (u_char) port; + while (base_addr[CyCCR]) + ; + base_addr[CyCCR] = CyENB_XMTR; + + ier = base_addr[CyIER]; + base_addr[CyIER] = CyTxMpty; + + while (1) { + if (pcc2chip[PccSCCTICR] & 0x20) { + /* We have a Tx int. Acknowledge it */ + sink = pcc2chip[PccTPIACKR]; + if ((base_addr[CyLICR] >> 2) == port) { + if (i == count) { + /* Last char of string is now output */ + base_addr[CyTEOIR] = CyNOTRANS; + break; + } + if (do_lf) { + base_addr[CyTDR] = '\n'; + str++; + i++; + do_lf = 0; + } else if (*str == '\n') { + base_addr[CyTDR] = '\r'; + do_lf = 1; + } else { + base_addr[CyTDR] = *str++; + i++; + } + base_addr[CyTEOIR] = 0; + } else + base_addr[CyTEOIR] = CyNOTRANS; + } + } + + base_addr[CyIER] = ier; + + local_irq_restore(flags); +} + +static struct tty_driver *serial167_console_device(struct console *c, + int *index) +{ + *index = c->index; + return cy_serial_driver; +} + +static struct console sercons = { + .name = "ttyS", + .write = serial167_console_write, + .device = serial167_console_device, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +static int __init serial167_console_init(void) +{ + if (vme_brdtype == VME_TYPE_MVME166 || + vme_brdtype == VME_TYPE_MVME167 || + vme_brdtype == VME_TYPE_MVME177) { + mvme167_serial_console_setup(0); + register_console(&sercons); + } + return 0; +} + +console_initcall(serial167_console_init); + +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/tty/specialix.c b/drivers/staging/tty/specialix.c new file mode 100644 index 000000000000..47e5753f732a --- /dev/null +++ b/drivers/staging/tty/specialix.c @@ -0,0 +1,2368 @@ +/* + * specialix.c -- specialix IO8+ multiport serial driver. + * + * Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl) + * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) + * + * Specialix pays for the development and support of this driver. + * Please DO contact io8-linux@specialix.co.uk if you require + * support. But please read the documentation (specialix.txt) + * first. + * + * This driver was developped in the BitWizard linux device + * driver service. If you require a linux device driver for your + * product, please contact devices@BitWizard.nl for a quote. + * + * This code is firmly based on the riscom/8 serial driver, + * written by Dmitry Gorodchanin. The specialix IO8+ card + * programming information was obtained from the CL-CD1865 Data + * Book, and Specialix document number 6200059: IO8+ Hardware + * Functional Specification. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, + * USA. + * + * Revision history: + * + * Revision 1.0: April 1st 1997. + * Initial release for alpha testing. + * Revision 1.1: April 14th 1997. + * Incorporated Richard Hudsons suggestions, + * removed some debugging printk's. + * Revision 1.2: April 15th 1997. + * Ported to 2.1.x kernels. + * Revision 1.3: April 17th 1997 + * Backported to 2.0. (Compatibility macros). + * Revision 1.4: April 18th 1997 + * Fixed DTR/RTS bug that caused the card to indicate + * "don't send data" to a modem after the password prompt. + * Fixed bug for premature (fake) interrupts. + * Revision 1.5: April 19th 1997 + * fixed a minor typo in the header file, cleanup a little. + * performance warnings are now MAXed at once per minute. + * Revision 1.6: May 23 1997 + * Changed the specialix=... format to include interrupt. + * Revision 1.7: May 27 1997 + * Made many more debug printk's a compile time option. + * Revision 1.8: Jul 1 1997 + * port to linux-2.1.43 kernel. + * Revision 1.9: Oct 9 1998 + * Added stuff for the IO8+/PCI version. + * Revision 1.10: Oct 22 1999 / Jan 21 2000. + * Added stuff for setserial. + * Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr) + * + */ + +#define VERSION "1.11" + + +/* + * There is a bunch of documentation about the card, jumpers, config + * settings, restrictions, cables, device names and numbers in + * Documentation/serial/specialix.txt + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "specialix_io8.h" +#include "cd1865.h" + + +/* + This driver can spew a whole lot of debugging output at you. If you + need maximum performance, you should disable the DEBUG define. To + aid in debugging in the field, I'm leaving the compile-time debug + features enabled, and disable them "runtime". That allows me to + instruct people with problems to enable debugging without requiring + them to recompile... +*/ +#define DEBUG + +static int sx_debug; +static int sx_rxfifo = SPECIALIX_RXFIFO; +static int sx_rtscts; + +#ifdef DEBUG +#define dprintk(f, str...) if (sx_debug & f) printk(str) +#else +#define dprintk(f, str...) /* nothing */ +#endif + +#define SX_DEBUG_FLOW 0x0001 +#define SX_DEBUG_DATA 0x0002 +#define SX_DEBUG_PROBE 0x0004 +#define SX_DEBUG_CHAN 0x0008 +#define SX_DEBUG_INIT 0x0010 +#define SX_DEBUG_RX 0x0020 +#define SX_DEBUG_TX 0x0040 +#define SX_DEBUG_IRQ 0x0080 +#define SX_DEBUG_OPEN 0x0100 +#define SX_DEBUG_TERMIOS 0x0200 +#define SX_DEBUG_SIGNALS 0x0400 +#define SX_DEBUG_FIFO 0x0800 + + +#define func_enter() dprintk(SX_DEBUG_FLOW, "io8: enter %s\n", __func__) +#define func_exit() dprintk(SX_DEBUG_FLOW, "io8: exit %s\n", __func__) + + +/* Configurable options: */ + +/* Am I paranoid or not ? ;-) */ +#define SPECIALIX_PARANOIA_CHECK + +/* + * The following defines are mostly for testing purposes. But if you need + * some nice reporting in your syslog, you can define them also. + */ +#undef SX_REPORT_FIFO +#undef SX_REPORT_OVERRUN + + + + +#define SPECIALIX_LEGAL_FLAGS \ + (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \ + ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \ + ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP) + +static struct tty_driver *specialix_driver; + +static struct specialix_board sx_board[SX_NBOARD] = { + { 0, SX_IOBASE1, 9, }, + { 0, SX_IOBASE2, 11, }, + { 0, SX_IOBASE3, 12, }, + { 0, SX_IOBASE4, 15, }, +}; + +static struct specialix_port sx_port[SX_NBOARD * SX_NPORT]; + + +static int sx_paranoia_check(struct specialix_port const *port, + char *name, const char *routine) +{ +#ifdef SPECIALIX_PARANOIA_CHECK + static const char *badmagic = KERN_ERR + "sx: Warning: bad specialix port magic number for device %s in %s\n"; + static const char *badinfo = KERN_ERR + "sx: Warning: null specialix port for device %s in %s\n"; + + if (!port) { + printk(badinfo, name, routine); + return 1; + } + if (port->magic != SPECIALIX_MAGIC) { + printk(badmagic, name, routine); + return 1; + } +#endif + return 0; +} + + +/* + * + * Service functions for specialix IO8+ driver. + * + */ + +/* Get board number from pointer */ +static inline int board_No(struct specialix_board *bp) +{ + return bp - sx_board; +} + + +/* Get port number from pointer */ +static inline int port_No(struct specialix_port const *port) +{ + return SX_PORT(port - sx_port); +} + + +/* Get pointer to board from pointer to port */ +static inline struct specialix_board *port_Board( + struct specialix_port const *port) +{ + return &sx_board[SX_BOARD(port - sx_port)]; +} + + +/* Input Byte from CL CD186x register */ +static inline unsigned char sx_in(struct specialix_board *bp, + unsigned short reg) +{ + bp->reg = reg | 0x80; + outb(reg | 0x80, bp->base + SX_ADDR_REG); + return inb(bp->base + SX_DATA_REG); +} + + +/* Output Byte to CL CD186x register */ +static inline void sx_out(struct specialix_board *bp, unsigned short reg, + unsigned char val) +{ + bp->reg = reg | 0x80; + outb(reg | 0x80, bp->base + SX_ADDR_REG); + outb(val, bp->base + SX_DATA_REG); +} + + +/* Input Byte from CL CD186x register */ +static inline unsigned char sx_in_off(struct specialix_board *bp, + unsigned short reg) +{ + bp->reg = reg; + outb(reg, bp->base + SX_ADDR_REG); + return inb(bp->base + SX_DATA_REG); +} + + +/* Output Byte to CL CD186x register */ +static inline void sx_out_off(struct specialix_board *bp, + unsigned short reg, unsigned char val) +{ + bp->reg = reg; + outb(reg, bp->base + SX_ADDR_REG); + outb(val, bp->base + SX_DATA_REG); +} + + +/* Wait for Channel Command Register ready */ +static void sx_wait_CCR(struct specialix_board *bp) +{ + unsigned long delay, flags; + unsigned char ccr; + + for (delay = SX_CCR_TIMEOUT; delay; delay--) { + spin_lock_irqsave(&bp->lock, flags); + ccr = sx_in(bp, CD186x_CCR); + spin_unlock_irqrestore(&bp->lock, flags); + if (!ccr) + return; + udelay(1); + } + + printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp)); +} + + +/* Wait for Channel Command Register ready */ +static void sx_wait_CCR_off(struct specialix_board *bp) +{ + unsigned long delay; + unsigned char crr; + unsigned long flags; + + for (delay = SX_CCR_TIMEOUT; delay; delay--) { + spin_lock_irqsave(&bp->lock, flags); + crr = sx_in_off(bp, CD186x_CCR); + spin_unlock_irqrestore(&bp->lock, flags); + if (!crr) + return; + udelay(1); + } + + printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp)); +} + + +/* + * specialix IO8+ IO range functions. + */ + +static int sx_request_io_range(struct specialix_board *bp) +{ + return request_region(bp->base, + bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE, + "specialix IO8+") == NULL; +} + + +static void sx_release_io_range(struct specialix_board *bp) +{ + release_region(bp->base, bp->flags & SX_BOARD_IS_PCI ? + SX_PCI_IO_SPACE : SX_IO_SPACE); +} + + +/* Set the IRQ using the RTS lines that run to the PAL on the board.... */ +static int sx_set_irq(struct specialix_board *bp) +{ + int virq; + int i; + unsigned long flags; + + if (bp->flags & SX_BOARD_IS_PCI) + return 1; + switch (bp->irq) { + /* In the same order as in the docs... */ + case 15: + virq = 0; + break; + case 12: + virq = 1; + break; + case 11: + virq = 2; + break; + case 9: + virq = 3; + break; + default:printk(KERN_ERR + "Speclialix: cannot set irq to %d.\n", bp->irq); + return 0; + } + spin_lock_irqsave(&bp->lock, flags); + for (i = 0; i < 2; i++) { + sx_out(bp, CD186x_CAR, i); + sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0); + } + spin_unlock_irqrestore(&bp->lock, flags); + return 1; +} + + +/* Reset and setup CD186x chip */ +static int sx_init_CD186x(struct specialix_board *bp) +{ + unsigned long flags; + int scaler; + int rv = 1; + + func_enter(); + sx_wait_CCR_off(bp); /* Wait for CCR ready */ + spin_lock_irqsave(&bp->lock, flags); + sx_out_off(bp, CD186x_CCR, CCR_HARDRESET); /* Reset CD186x chip */ + spin_unlock_irqrestore(&bp->lock, flags); + msleep(50); /* Delay 0.05 sec */ + spin_lock_irqsave(&bp->lock, flags); + sx_out_off(bp, CD186x_GIVR, SX_ID); /* Set ID for this chip */ + sx_out_off(bp, CD186x_GICR, 0); /* Clear all bits */ + sx_out_off(bp, CD186x_PILR1, SX_ACK_MINT); /* Prio for modem intr */ + sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT); /* Prio for transmitter intr */ + sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */ + /* Set RegAckEn */ + sx_out_off(bp, CD186x_SRCR, sx_in(bp, CD186x_SRCR) | SRCR_REGACKEN); + + /* Setting up prescaler. We need 4 ticks per 1 ms */ + scaler = SX_OSCFREQ/SPECIALIX_TPS; + + sx_out_off(bp, CD186x_PPRH, scaler >> 8); + sx_out_off(bp, CD186x_PPRL, scaler & 0xff); + spin_unlock_irqrestore(&bp->lock, flags); + + if (!sx_set_irq(bp)) { + /* Figure out how to pass this along... */ + printk(KERN_ERR "Cannot set irq to %d.\n", bp->irq); + rv = 0; + } + + func_exit(); + return rv; +} + + +static int read_cross_byte(struct specialix_board *bp, int reg, int bit) +{ + int i; + int t; + unsigned long flags; + + spin_lock_irqsave(&bp->lock, flags); + for (i = 0, t = 0; i < 8; i++) { + sx_out_off(bp, CD186x_CAR, i); + if (sx_in_off(bp, reg) & bit) + t |= 1 << i; + } + spin_unlock_irqrestore(&bp->lock, flags); + + return t; +} + + +/* Main probing routine, also sets irq. */ +static int sx_probe(struct specialix_board *bp) +{ + unsigned char val1, val2; + int rev; + int chip; + + func_enter(); + + if (sx_request_io_range(bp)) { + func_exit(); + return 1; + } + + /* Are the I/O ports here ? */ + sx_out_off(bp, CD186x_PPRL, 0x5a); + udelay(1); + val1 = sx_in_off(bp, CD186x_PPRL); + + sx_out_off(bp, CD186x_PPRL, 0xa5); + udelay(1); + val2 = sx_in_off(bp, CD186x_PPRL); + + + if (val1 != 0x5a || val2 != 0xa5) { + printk(KERN_INFO + "sx%d: specialix IO8+ Board at 0x%03x not found.\n", + board_No(bp), bp->base); + sx_release_io_range(bp); + func_exit(); + return 1; + } + + /* Check the DSR lines that Specialix uses as board + identification */ + val1 = read_cross_byte(bp, CD186x_MSVR, MSVR_DSR); + val2 = read_cross_byte(bp, CD186x_MSVR, MSVR_RTS); + dprintk(SX_DEBUG_INIT, + "sx%d: DSR lines are: %02x, rts lines are: %02x\n", + board_No(bp), val1, val2); + + /* They managed to switch the bit order between the docs and + the IO8+ card. The new PCI card now conforms to old docs. + They changed the PCI docs to reflect the situation on the + old card. */ + val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2; + if (val1 != val2) { + printk(KERN_INFO + "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n", + board_No(bp), val2, bp->base, val1); + sx_release_io_range(bp); + func_exit(); + return 1; + } + + + /* Reset CD186x again */ + if (!sx_init_CD186x(bp)) { + sx_release_io_range(bp); + func_exit(); + return 1; + } + + sx_request_io_range(bp); + bp->flags |= SX_BOARD_PRESENT; + + /* Chip revcode pkgtype + GFRCR SRCR bit 7 + CD180 rev B 0x81 0 + CD180 rev C 0x82 0 + CD1864 rev A 0x82 1 + CD1865 rev A 0x83 1 -- Do not use!!! Does not work. + CD1865 rev B 0x84 1 + -- Thanks to Gwen Wang, Cirrus Logic. + */ + + switch (sx_in_off(bp, CD186x_GFRCR)) { + case 0x82: + chip = 1864; + rev = 'A'; + break; + case 0x83: + chip = 1865; + rev = 'A'; + break; + case 0x84: + chip = 1865; + rev = 'B'; + break; + case 0x85: + chip = 1865; + rev = 'C'; + break; /* Does not exist at this time */ + default: + chip = -1; + rev = 'x'; + } + + dprintk(SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR)); + + printk(KERN_INFO + "sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n", + board_No(bp), bp->base, bp->irq, chip, rev); + + func_exit(); + return 0; +} + +/* + * + * Interrupt processing routines. + * */ + +static struct specialix_port *sx_get_port(struct specialix_board *bp, + unsigned char const *what) +{ + unsigned char channel; + struct specialix_port *port = NULL; + + channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF; + dprintk(SX_DEBUG_CHAN, "channel: %d\n", channel); + if (channel < CD186x_NCH) { + port = &sx_port[board_No(bp) * SX_NPORT + channel]; + dprintk(SX_DEBUG_CHAN, "port: %d %p flags: 0x%lx\n", + board_No(bp) * SX_NPORT + channel, port, + port->port.flags & ASYNC_INITIALIZED); + + if (port->port.flags & ASYNC_INITIALIZED) { + dprintk(SX_DEBUG_CHAN, "port: %d %p\n", channel, port); + func_exit(); + return port; + } + } + printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n", + board_No(bp), what, channel); + return NULL; +} + + +static void sx_receive_exc(struct specialix_board *bp) +{ + struct specialix_port *port; + struct tty_struct *tty; + unsigned char status; + unsigned char ch, flag; + + func_enter(); + + port = sx_get_port(bp, "Receive"); + if (!port) { + dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n"); + func_exit(); + return; + } + tty = port->port.tty; + + status = sx_in(bp, CD186x_RCSR); + + dprintk(SX_DEBUG_RX, "status: 0x%x\n", status); + if (status & RCSR_OE) { + port->overrun++; + dprintk(SX_DEBUG_FIFO, + "sx%d: port %d: Overrun. Total %ld overruns.\n", + board_No(bp), port_No(port), port->overrun); + } + status &= port->mark_mask; + + /* This flip buffer check needs to be below the reading of the + status register to reset the chip's IRQ.... */ + if (tty_buffer_request_room(tty, 1) == 0) { + dprintk(SX_DEBUG_FIFO, + "sx%d: port %d: Working around flip buffer overflow.\n", + board_No(bp), port_No(port)); + func_exit(); + return; + } + + ch = sx_in(bp, CD186x_RDR); + if (!status) { + func_exit(); + return; + } + if (status & RCSR_TOUT) { + printk(KERN_INFO + "sx%d: port %d: Receiver timeout. Hardware problems ?\n", + board_No(bp), port_No(port)); + func_exit(); + return; + + } else if (status & RCSR_BREAK) { + dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n", + board_No(bp), port_No(port)); + flag = TTY_BREAK; + if (port->port.flags & ASYNC_SAK) + do_SAK(tty); + + } else if (status & RCSR_PE) + flag = TTY_PARITY; + + else if (status & RCSR_FE) + flag = TTY_FRAME; + + else if (status & RCSR_OE) + flag = TTY_OVERRUN; + + else + flag = TTY_NORMAL; + + if (tty_insert_flip_char(tty, ch, flag)) + tty_flip_buffer_push(tty); + func_exit(); +} + + +static void sx_receive(struct specialix_board *bp) +{ + struct specialix_port *port; + struct tty_struct *tty; + unsigned char count; + + func_enter(); + + port = sx_get_port(bp, "Receive"); + if (port == NULL) { + dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n"); + func_exit(); + return; + } + tty = port->port.tty; + + count = sx_in(bp, CD186x_RDCR); + dprintk(SX_DEBUG_RX, "port: %p: count: %d\n", port, count); + port->hits[count > 8 ? 9 : count]++; + + while (count--) + tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL); + tty_flip_buffer_push(tty); + func_exit(); +} + + +static void sx_transmit(struct specialix_board *bp) +{ + struct specialix_port *port; + struct tty_struct *tty; + unsigned char count; + + func_enter(); + port = sx_get_port(bp, "Transmit"); + if (port == NULL) { + func_exit(); + return; + } + dprintk(SX_DEBUG_TX, "port: %p\n", port); + tty = port->port.tty; + + if (port->IER & IER_TXEMPTY) { + /* FIFO drained */ + sx_out(bp, CD186x_CAR, port_No(port)); + port->IER &= ~IER_TXEMPTY; + sx_out(bp, CD186x_IER, port->IER); + func_exit(); + return; + } + + if ((port->xmit_cnt <= 0 && !port->break_length) + || tty->stopped || tty->hw_stopped) { + sx_out(bp, CD186x_CAR, port_No(port)); + port->IER &= ~IER_TXRDY; + sx_out(bp, CD186x_IER, port->IER); + func_exit(); + return; + } + + if (port->break_length) { + if (port->break_length > 0) { + if (port->COR2 & COR2_ETC) { + sx_out(bp, CD186x_TDR, CD186x_C_ESC); + sx_out(bp, CD186x_TDR, CD186x_C_SBRK); + port->COR2 &= ~COR2_ETC; + } + count = min_t(int, port->break_length, 0xff); + sx_out(bp, CD186x_TDR, CD186x_C_ESC); + sx_out(bp, CD186x_TDR, CD186x_C_DELAY); + sx_out(bp, CD186x_TDR, count); + port->break_length -= count; + if (port->break_length == 0) + port->break_length--; + } else { + sx_out(bp, CD186x_TDR, CD186x_C_ESC); + sx_out(bp, CD186x_TDR, CD186x_C_EBRK); + sx_out(bp, CD186x_COR2, port->COR2); + sx_wait_CCR(bp); + sx_out(bp, CD186x_CCR, CCR_CORCHG2); + port->break_length = 0; + } + + func_exit(); + return; + } + + count = CD186x_NFIFO; + do { + sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]); + port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1); + if (--port->xmit_cnt <= 0) + break; + } while (--count > 0); + + if (port->xmit_cnt <= 0) { + sx_out(bp, CD186x_CAR, port_No(port)); + port->IER &= ~IER_TXRDY; + sx_out(bp, CD186x_IER, port->IER); + } + if (port->xmit_cnt <= port->wakeup_chars) + tty_wakeup(tty); + + func_exit(); +} + + +static void sx_check_modem(struct specialix_board *bp) +{ + struct specialix_port *port; + struct tty_struct *tty; + unsigned char mcr; + int msvr_cd; + + dprintk(SX_DEBUG_SIGNALS, "Modem intr. "); + port = sx_get_port(bp, "Modem"); + if (port == NULL) + return; + + tty = port->port.tty; + + mcr = sx_in(bp, CD186x_MCR); + + if ((mcr & MCR_CDCHG)) { + dprintk(SX_DEBUG_SIGNALS, "CD just changed... "); + msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD; + if (msvr_cd) { + dprintk(SX_DEBUG_SIGNALS, "Waking up guys in open.\n"); + wake_up_interruptible(&port->port.open_wait); + } else { + dprintk(SX_DEBUG_SIGNALS, "Sending HUP.\n"); + tty_hangup(tty); + } + } + +#ifdef SPECIALIX_BRAIN_DAMAGED_CTS + if (mcr & MCR_CTSCHG) { + if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) { + tty->hw_stopped = 0; + port->IER |= IER_TXRDY; + if (port->xmit_cnt <= port->wakeup_chars) + tty_wakeup(tty); + } else { + tty->hw_stopped = 1; + port->IER &= ~IER_TXRDY; + } + sx_out(bp, CD186x_IER, port->IER); + } + if (mcr & MCR_DSSXHG) { + if (sx_in(bp, CD186x_MSVR) & MSVR_DSR) { + tty->hw_stopped = 0; + port->IER |= IER_TXRDY; + if (port->xmit_cnt <= port->wakeup_chars) + tty_wakeup(tty); + } else { + tty->hw_stopped = 1; + port->IER &= ~IER_TXRDY; + } + sx_out(bp, CD186x_IER, port->IER); + } +#endif /* SPECIALIX_BRAIN_DAMAGED_CTS */ + + /* Clear change bits */ + sx_out(bp, CD186x_MCR, 0); +} + + +/* The main interrupt processing routine */ +static irqreturn_t sx_interrupt(int dummy, void *dev_id) +{ + unsigned char status; + unsigned char ack; + struct specialix_board *bp = dev_id; + unsigned long loop = 0; + int saved_reg; + unsigned long flags; + + func_enter(); + + spin_lock_irqsave(&bp->lock, flags); + + dprintk(SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __func__, + port_No(sx_get_port(bp, "INT")), + SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1); + if (!(bp->flags & SX_BOARD_ACTIVE)) { + dprintk(SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", + bp->irq); + spin_unlock_irqrestore(&bp->lock, flags); + func_exit(); + return IRQ_NONE; + } + + saved_reg = bp->reg; + + while (++loop < 16) { + status = sx_in(bp, CD186x_SRSR) & + (SRSR_RREQint | SRSR_TREQint | SRSR_MREQint); + if (status == 0) + break; + if (status & SRSR_RREQint) { + ack = sx_in(bp, CD186x_RRAR); + + if (ack == (SX_ID | GIVR_IT_RCV)) + sx_receive(bp); + else if (ack == (SX_ID | GIVR_IT_REXC)) + sx_receive_exc(bp); + else + printk(KERN_ERR + "sx%d: status: 0x%x Bad receive ack 0x%02x.\n", + board_No(bp), status, ack); + + } else if (status & SRSR_TREQint) { + ack = sx_in(bp, CD186x_TRAR); + + if (ack == (SX_ID | GIVR_IT_TX)) + sx_transmit(bp); + else + printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n", + board_No(bp), status, ack, + port_No(sx_get_port(bp, "Int"))); + } else if (status & SRSR_MREQint) { + ack = sx_in(bp, CD186x_MRAR); + + if (ack == (SX_ID | GIVR_IT_MODEM)) + sx_check_modem(bp); + else + printk(KERN_ERR + "sx%d: status: 0x%x Bad modem ack 0x%02x.\n", + board_No(bp), status, ack); + + } + + sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */ + } + bp->reg = saved_reg; + outb(bp->reg, bp->base + SX_ADDR_REG); + spin_unlock_irqrestore(&bp->lock, flags); + func_exit(); + return IRQ_HANDLED; +} + + +/* + * Routines for open & close processing. + */ + +static void turn_ints_off(struct specialix_board *bp) +{ + unsigned long flags; + + func_enter(); + spin_lock_irqsave(&bp->lock, flags); + (void) sx_in_off(bp, 0); /* Turn off interrupts. */ + spin_unlock_irqrestore(&bp->lock, flags); + + func_exit(); +} + +static void turn_ints_on(struct specialix_board *bp) +{ + unsigned long flags; + + func_enter(); + + spin_lock_irqsave(&bp->lock, flags); + (void) sx_in(bp, 0); /* Turn ON interrupts. */ + spin_unlock_irqrestore(&bp->lock, flags); + + func_exit(); +} + + +/* Called with disabled interrupts */ +static int sx_setup_board(struct specialix_board *bp) +{ + int error; + + if (bp->flags & SX_BOARD_ACTIVE) + return 0; + + if (bp->flags & SX_BOARD_IS_PCI) + error = request_irq(bp->irq, sx_interrupt, + IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp); + else + error = request_irq(bp->irq, sx_interrupt, + IRQF_DISABLED, "specialix IO8+", bp); + + if (error) + return error; + + turn_ints_on(bp); + bp->flags |= SX_BOARD_ACTIVE; + + return 0; +} + + +/* Called with disabled interrupts */ +static void sx_shutdown_board(struct specialix_board *bp) +{ + func_enter(); + + if (!(bp->flags & SX_BOARD_ACTIVE)) { + func_exit(); + return; + } + + bp->flags &= ~SX_BOARD_ACTIVE; + + dprintk(SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n", + bp->irq, board_No(bp)); + free_irq(bp->irq, bp); + turn_ints_off(bp); + func_exit(); +} + +static unsigned int sx_crtscts(struct tty_struct *tty) +{ + if (sx_rtscts) + return C_CRTSCTS(tty); + return 1; +} + +/* + * Setting up port characteristics. + * Must be called with disabled interrupts + */ +static void sx_change_speed(struct specialix_board *bp, + struct specialix_port *port) +{ + struct tty_struct *tty; + unsigned long baud; + long tmp; + unsigned char cor1 = 0, cor3 = 0; + unsigned char mcor1 = 0, mcor2 = 0; + static unsigned long again; + unsigned long flags; + + func_enter(); + + tty = port->port.tty; + if (!tty || !tty->termios) { + func_exit(); + return; + } + + port->IER = 0; + port->COR2 = 0; + /* Select port on the board */ + spin_lock_irqsave(&bp->lock, flags); + sx_out(bp, CD186x_CAR, port_No(port)); + + /* The Specialix board doens't implement the RTS lines. + They are used to set the IRQ level. Don't touch them. */ + if (sx_crtscts(tty)) + port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS); + else + port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS); + spin_unlock_irqrestore(&bp->lock, flags); + dprintk(SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR); + baud = tty_get_baud_rate(tty); + + if (baud == 38400) { + if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + baud = 57600; + if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + baud = 115200; + } + + if (!baud) { + /* Drop DTR & exit */ + dprintk(SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n"); + if (!sx_crtscts(tty)) { + port->MSVR &= ~MSVR_DTR; + spin_lock_irqsave(&bp->lock, flags); + sx_out(bp, CD186x_MSVR, port->MSVR); + spin_unlock_irqrestore(&bp->lock, flags); + } else + dprintk(SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n"); + return; + } else { + /* Set DTR on */ + if (!sx_crtscts(tty)) + port->MSVR |= MSVR_DTR; + } + + /* + * Now we must calculate some speed depended things + */ + + /* Set baud rate for port */ + tmp = port->custom_divisor ; + if (tmp) + printk(KERN_INFO + "sx%d: Using custom baud rate divisor %ld. \n" + "This is an untested option, please be careful.\n", + port_No(port), tmp); + else + tmp = (((SX_OSCFREQ + baud/2) / baud + CD186x_TPC/2) / + CD186x_TPC); + + if (tmp < 0x10 && time_before(again, jiffies)) { + again = jiffies + HZ * 60; + /* Page 48 of version 2.0 of the CL-CD1865 databook */ + if (tmp >= 12) { + printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n" + "Performance degradation is possible.\n" + "Read specialix.txt for more info.\n", + port_No(port), tmp); + } else { + printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n" + "Warning: overstressing Cirrus chip. This might not work.\n" + "Read specialix.txt for more info.\n", port_No(port), tmp); + } + } + spin_lock_irqsave(&bp->lock, flags); + sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff); + sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff); + sx_out(bp, CD186x_RBPRL, tmp & 0xff); + sx_out(bp, CD186x_TBPRL, tmp & 0xff); + spin_unlock_irqrestore(&bp->lock, flags); + if (port->custom_divisor) + baud = (SX_OSCFREQ + port->custom_divisor/2) / + port->custom_divisor; + baud = (baud + 5) / 10; /* Estimated CPS */ + + /* Two timer ticks seems enough to wakeup something like SLIP driver */ + tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO; + port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ? + SERIAL_XMIT_SIZE - 1 : tmp); + + /* Receiver timeout will be transmission time for 1.5 chars */ + tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud; + tmp = (tmp > 0xff) ? 0xff : tmp; + spin_lock_irqsave(&bp->lock, flags); + sx_out(bp, CD186x_RTPR, tmp); + spin_unlock_irqrestore(&bp->lock, flags); + switch (C_CSIZE(tty)) { + case CS5: + cor1 |= COR1_5BITS; + break; + case CS6: + cor1 |= COR1_6BITS; + break; + case CS7: + cor1 |= COR1_7BITS; + break; + case CS8: + cor1 |= COR1_8BITS; + break; + } + + if (C_CSTOPB(tty)) + cor1 |= COR1_2SB; + + cor1 |= COR1_IGNORE; + if (C_PARENB(tty)) { + cor1 |= COR1_NORMPAR; + if (C_PARODD(tty)) + cor1 |= COR1_ODDP; + if (I_INPCK(tty)) + cor1 &= ~COR1_IGNORE; + } + /* Set marking of some errors */ + port->mark_mask = RCSR_OE | RCSR_TOUT; + if (I_INPCK(tty)) + port->mark_mask |= RCSR_FE | RCSR_PE; + if (I_BRKINT(tty) || I_PARMRK(tty)) + port->mark_mask |= RCSR_BREAK; + if (I_IGNPAR(tty)) + port->mark_mask &= ~(RCSR_FE | RCSR_PE); + if (I_IGNBRK(tty)) { + port->mark_mask &= ~RCSR_BREAK; + if (I_IGNPAR(tty)) + /* Real raw mode. Ignore all */ + port->mark_mask &= ~RCSR_OE; + } + /* Enable Hardware Flow Control */ + if (C_CRTSCTS(tty)) { +#ifdef SPECIALIX_BRAIN_DAMAGED_CTS + port->IER |= IER_DSR | IER_CTS; + mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD; + mcor2 |= MCOR2_DSROD | MCOR2_CTSOD; + spin_lock_irqsave(&bp->lock, flags); + tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & + (MSVR_CTS|MSVR_DSR)); + spin_unlock_irqrestore(&bp->lock, flags); +#else + port->COR2 |= COR2_CTSAE; +#endif + } + /* Enable Software Flow Control. FIXME: I'm not sure about this */ + /* Some people reported that it works, but I still doubt it */ + if (I_IXON(tty)) { + port->COR2 |= COR2_TXIBE; + cor3 |= (COR3_FCT | COR3_SCDE); + if (I_IXANY(tty)) + port->COR2 |= COR2_IXM; + spin_lock_irqsave(&bp->lock, flags); + sx_out(bp, CD186x_SCHR1, START_CHAR(tty)); + sx_out(bp, CD186x_SCHR2, STOP_CHAR(tty)); + sx_out(bp, CD186x_SCHR3, START_CHAR(tty)); + sx_out(bp, CD186x_SCHR4, STOP_CHAR(tty)); + spin_unlock_irqrestore(&bp->lock, flags); + } + if (!C_CLOCAL(tty)) { + /* Enable CD check */ + port->IER |= IER_CD; + mcor1 |= MCOR1_CDZD; + mcor2 |= MCOR2_CDOD; + } + + if (C_CREAD(tty)) + /* Enable receiver */ + port->IER |= IER_RXD; + + /* Set input FIFO size (1-8 bytes) */ + cor3 |= sx_rxfifo; + /* Setting up CD186x channel registers */ + spin_lock_irqsave(&bp->lock, flags); + sx_out(bp, CD186x_COR1, cor1); + sx_out(bp, CD186x_COR2, port->COR2); + sx_out(bp, CD186x_COR3, cor3); + spin_unlock_irqrestore(&bp->lock, flags); + /* Make CD186x know about registers change */ + sx_wait_CCR(bp); + spin_lock_irqsave(&bp->lock, flags); + sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3); + /* Setting up modem option registers */ + dprintk(SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n", + mcor1, mcor2); + sx_out(bp, CD186x_MCOR1, mcor1); + sx_out(bp, CD186x_MCOR2, mcor2); + spin_unlock_irqrestore(&bp->lock, flags); + /* Enable CD186x transmitter & receiver */ + sx_wait_CCR(bp); + spin_lock_irqsave(&bp->lock, flags); + sx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN); + /* Enable interrupts */ + sx_out(bp, CD186x_IER, port->IER); + /* And finally set the modem lines... */ + sx_out(bp, CD186x_MSVR, port->MSVR); + spin_unlock_irqrestore(&bp->lock, flags); + + func_exit(); +} + + +/* Must be called with interrupts enabled */ +static int sx_setup_port(struct specialix_board *bp, + struct specialix_port *port) +{ + unsigned long flags; + + func_enter(); + + if (port->port.flags & ASYNC_INITIALIZED) { + func_exit(); + return 0; + } + + if (!port->xmit_buf) { + /* We may sleep in get_zeroed_page() */ + unsigned long tmp; + + tmp = get_zeroed_page(GFP_KERNEL); + if (tmp == 0L) { + func_exit(); + return -ENOMEM; + } + + if (port->xmit_buf) { + free_page(tmp); + func_exit(); + return -ERESTARTSYS; + } + port->xmit_buf = (unsigned char *) tmp; + } + + spin_lock_irqsave(&port->lock, flags); + + if (port->port.tty) + clear_bit(TTY_IO_ERROR, &port->port.tty->flags); + + port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; + sx_change_speed(bp, port); + port->port.flags |= ASYNC_INITIALIZED; + + spin_unlock_irqrestore(&port->lock, flags); + + + func_exit(); + return 0; +} + + +/* Must be called with interrupts disabled */ +static void sx_shutdown_port(struct specialix_board *bp, + struct specialix_port *port) +{ + struct tty_struct *tty; + int i; + unsigned long flags; + + func_enter(); + + if (!(port->port.flags & ASYNC_INITIALIZED)) { + func_exit(); + return; + } + + if (sx_debug & SX_DEBUG_FIFO) { + dprintk(SX_DEBUG_FIFO, + "sx%d: port %d: %ld overruns, FIFO hits [ ", + board_No(bp), port_No(port), port->overrun); + for (i = 0; i < 10; i++) + dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]); + dprintk(SX_DEBUG_FIFO, "].\n"); + } + + if (port->xmit_buf) { + free_page((unsigned long) port->xmit_buf); + port->xmit_buf = NULL; + } + + /* Select port */ + spin_lock_irqsave(&bp->lock, flags); + sx_out(bp, CD186x_CAR, port_No(port)); + + tty = port->port.tty; + if (tty == NULL || C_HUPCL(tty)) { + /* Drop DTR */ + sx_out(bp, CD186x_MSVDTR, 0); + } + spin_unlock_irqrestore(&bp->lock, flags); + /* Reset port */ + sx_wait_CCR(bp); + spin_lock_irqsave(&bp->lock, flags); + sx_out(bp, CD186x_CCR, CCR_SOFTRESET); + /* Disable all interrupts from this port */ + port->IER = 0; + sx_out(bp, CD186x_IER, port->IER); + spin_unlock_irqrestore(&bp->lock, flags); + if (tty) + set_bit(TTY_IO_ERROR, &tty->flags); + port->port.flags &= ~ASYNC_INITIALIZED; + + if (!bp->count) + sx_shutdown_board(bp); + func_exit(); +} + + +static int block_til_ready(struct tty_struct *tty, struct file *filp, + struct specialix_port *port) +{ + DECLARE_WAITQUEUE(wait, current); + struct specialix_board *bp = port_Board(port); + int retval; + int do_clocal = 0; + int CD; + unsigned long flags; + + func_enter(); + + /* + * If the device is in the middle of being closed, then block + * until it's done, and then try again. + */ + if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) { + interruptible_sleep_on(&port->port.close_wait); + if (port->port.flags & ASYNC_HUP_NOTIFY) { + func_exit(); + return -EAGAIN; + } else { + func_exit(); + return -ERESTARTSYS; + } + } + + /* + * If non-blocking mode is set, or the port is not enabled, + * then make the check up front and then exit. + */ + if ((filp->f_flags & O_NONBLOCK) || + (tty->flags & (1 << TTY_IO_ERROR))) { + port->port.flags |= ASYNC_NORMAL_ACTIVE; + func_exit(); + return 0; + } + + if (C_CLOCAL(tty)) + do_clocal = 1; + + /* + * Block waiting for the carrier detect and the line to become + * free (i.e., not in use by the callout). While we are in + * this loop, info->count is dropped by one, so that + * rs_close() knows when to free things. We restore it upon + * exit, either normal or abnormal. + */ + retval = 0; + add_wait_queue(&port->port.open_wait, &wait); + spin_lock_irqsave(&port->lock, flags); + if (!tty_hung_up_p(filp)) + port->port.count--; + spin_unlock_irqrestore(&port->lock, flags); + port->port.blocked_open++; + while (1) { + spin_lock_irqsave(&bp->lock, flags); + sx_out(bp, CD186x_CAR, port_No(port)); + CD = sx_in(bp, CD186x_MSVR) & MSVR_CD; + if (sx_crtscts(tty)) { + /* Activate RTS */ + port->MSVR |= MSVR_DTR; /* WTF? */ + sx_out(bp, CD186x_MSVR, port->MSVR); + } else { + /* Activate DTR */ + port->MSVR |= MSVR_DTR; + sx_out(bp, CD186x_MSVR, port->MSVR); + } + spin_unlock_irqrestore(&bp->lock, flags); + set_current_state(TASK_INTERRUPTIBLE); + if (tty_hung_up_p(filp) || + !(port->port.flags & ASYNC_INITIALIZED)) { + if (port->port.flags & ASYNC_HUP_NOTIFY) + retval = -EAGAIN; + else + retval = -ERESTARTSYS; + break; + } + if (!(port->port.flags & ASYNC_CLOSING) && + (do_clocal || CD)) + break; + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } + tty_unlock(); + schedule(); + tty_lock(); + } + + set_current_state(TASK_RUNNING); + remove_wait_queue(&port->port.open_wait, &wait); + spin_lock_irqsave(&port->lock, flags); + if (!tty_hung_up_p(filp)) + port->port.count++; + port->port.blocked_open--; + spin_unlock_irqrestore(&port->lock, flags); + if (retval) { + func_exit(); + return retval; + } + + port->port.flags |= ASYNC_NORMAL_ACTIVE; + func_exit(); + return 0; +} + + +static int sx_open(struct tty_struct *tty, struct file *filp) +{ + int board; + int error; + struct specialix_port *port; + struct specialix_board *bp; + int i; + unsigned long flags; + + func_enter(); + + board = SX_BOARD(tty->index); + + if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) { + func_exit(); + return -ENODEV; + } + + bp = &sx_board[board]; + port = sx_port + board * SX_NPORT + SX_PORT(tty->index); + port->overrun = 0; + for (i = 0; i < 10; i++) + port->hits[i] = 0; + + dprintk(SX_DEBUG_OPEN, + "Board = %d, bp = %p, port = %p, portno = %d.\n", + board, bp, port, SX_PORT(tty->index)); + + if (sx_paranoia_check(port, tty->name, "sx_open")) { + func_enter(); + return -ENODEV; + } + + error = sx_setup_board(bp); + if (error) { + func_exit(); + return error; + } + + spin_lock_irqsave(&bp->lock, flags); + port->port.count++; + bp->count++; + tty->driver_data = port; + port->port.tty = tty; + spin_unlock_irqrestore(&bp->lock, flags); + + error = sx_setup_port(bp, port); + if (error) { + func_enter(); + return error; + } + + error = block_til_ready(tty, filp, port); + if (error) { + func_enter(); + return error; + } + + func_exit(); + return 0; +} + +static void sx_flush_buffer(struct tty_struct *tty) +{ + struct specialix_port *port = tty->driver_data; + unsigned long flags; + struct specialix_board *bp; + + func_enter(); + + if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) { + func_exit(); + return; + } + + bp = port_Board(port); + spin_lock_irqsave(&port->lock, flags); + port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; + spin_unlock_irqrestore(&port->lock, flags); + tty_wakeup(tty); + + func_exit(); +} + +static void sx_close(struct tty_struct *tty, struct file *filp) +{ + struct specialix_port *port = tty->driver_data; + struct specialix_board *bp; + unsigned long flags; + unsigned long timeout; + + func_enter(); + if (!port || sx_paranoia_check(port, tty->name, "close")) { + func_exit(); + return; + } + spin_lock_irqsave(&port->lock, flags); + + if (tty_hung_up_p(filp)) { + spin_unlock_irqrestore(&port->lock, flags); + func_exit(); + return; + } + + bp = port_Board(port); + if (tty->count == 1 && port->port.count != 1) { + printk(KERN_ERR "sx%d: sx_close: bad port count;" + " tty->count is 1, port count is %d\n", + board_No(bp), port->port.count); + port->port.count = 1; + } + + if (port->port.count > 1) { + port->port.count--; + bp->count--; + + spin_unlock_irqrestore(&port->lock, flags); + + func_exit(); + return; + } + port->port.flags |= ASYNC_CLOSING; + /* + * Now we wait for the transmit buffer to clear; and we notify + * the line discipline to only process XON/XOFF characters. + */ + tty->closing = 1; + spin_unlock_irqrestore(&port->lock, flags); + dprintk(SX_DEBUG_OPEN, "Closing\n"); + if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) + tty_wait_until_sent(tty, port->port.closing_wait); + /* + * At this point we stop accepting input. To do this, we + * disable the receive line status interrupts, and tell the + * interrupt driver to stop checking the data ready bit in the + * line status register. + */ + dprintk(SX_DEBUG_OPEN, "Closed\n"); + port->IER &= ~IER_RXD; + if (port->port.flags & ASYNC_INITIALIZED) { + port->IER &= ~IER_TXRDY; + port->IER |= IER_TXEMPTY; + spin_lock_irqsave(&bp->lock, flags); + sx_out(bp, CD186x_CAR, port_No(port)); + sx_out(bp, CD186x_IER, port->IER); + spin_unlock_irqrestore(&bp->lock, flags); + /* + * Before we drop DTR, make sure the UART transmitter + * has completely drained; this is especially + * important if there is a transmit FIFO! + */ + timeout = jiffies+HZ; + while (port->IER & IER_TXEMPTY) { + set_current_state(TASK_INTERRUPTIBLE); + msleep_interruptible(jiffies_to_msecs(port->timeout)); + if (time_after(jiffies, timeout)) { + printk(KERN_INFO "Timeout waiting for close\n"); + break; + } + } + + } + + if (--bp->count < 0) { + printk(KERN_ERR + "sx%d: sx_shutdown_port: bad board count: %d port: %d\n", + board_No(bp), bp->count, tty->index); + bp->count = 0; + } + if (--port->port.count < 0) { + printk(KERN_ERR + "sx%d: sx_close: bad port count for tty%d: %d\n", + board_No(bp), port_No(port), port->port.count); + port->port.count = 0; + } + + sx_shutdown_port(bp, port); + sx_flush_buffer(tty); + tty_ldisc_flush(tty); + spin_lock_irqsave(&port->lock, flags); + tty->closing = 0; + port->port.tty = NULL; + spin_unlock_irqrestore(&port->lock, flags); + if (port->port.blocked_open) { + if (port->port.close_delay) + msleep_interruptible( + jiffies_to_msecs(port->port.close_delay)); + wake_up_interruptible(&port->port.open_wait); + } + port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); + wake_up_interruptible(&port->port.close_wait); + + func_exit(); +} + + +static int sx_write(struct tty_struct *tty, + const unsigned char *buf, int count) +{ + struct specialix_port *port = tty->driver_data; + struct specialix_board *bp; + int c, total = 0; + unsigned long flags; + + func_enter(); + if (sx_paranoia_check(port, tty->name, "sx_write")) { + func_exit(); + return 0; + } + + bp = port_Board(port); + + if (!port->xmit_buf) { + func_exit(); + return 0; + } + + while (1) { + spin_lock_irqsave(&port->lock, flags); + c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, + SERIAL_XMIT_SIZE - port->xmit_head)); + if (c <= 0) { + spin_unlock_irqrestore(&port->lock, flags); + break; + } + memcpy(port->xmit_buf + port->xmit_head, buf, c); + port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); + port->xmit_cnt += c; + spin_unlock_irqrestore(&port->lock, flags); + + buf += c; + count -= c; + total += c; + } + + spin_lock_irqsave(&bp->lock, flags); + if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped && + !(port->IER & IER_TXRDY)) { + port->IER |= IER_TXRDY; + sx_out(bp, CD186x_CAR, port_No(port)); + sx_out(bp, CD186x_IER, port->IER); + } + spin_unlock_irqrestore(&bp->lock, flags); + func_exit(); + + return total; +} + + +static int sx_put_char(struct tty_struct *tty, unsigned char ch) +{ + struct specialix_port *port = tty->driver_data; + unsigned long flags; + struct specialix_board *bp; + + func_enter(); + + if (sx_paranoia_check(port, tty->name, "sx_put_char")) { + func_exit(); + return 0; + } + dprintk(SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf); + if (!port->xmit_buf) { + func_exit(); + return 0; + } + bp = port_Board(port); + spin_lock_irqsave(&port->lock, flags); + + dprintk(SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n", + port->xmit_cnt, port->xmit_buf); + if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1 || !port->xmit_buf) { + spin_unlock_irqrestore(&port->lock, flags); + dprintk(SX_DEBUG_TX, "Exit size\n"); + func_exit(); + return 0; + } + dprintk(SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf); + port->xmit_buf[port->xmit_head++] = ch; + port->xmit_head &= SERIAL_XMIT_SIZE - 1; + port->xmit_cnt++; + spin_unlock_irqrestore(&port->lock, flags); + + func_exit(); + return 1; +} + + +static void sx_flush_chars(struct tty_struct *tty) +{ + struct specialix_port *port = tty->driver_data; + unsigned long flags; + struct specialix_board *bp = port_Board(port); + + func_enter(); + + if (sx_paranoia_check(port, tty->name, "sx_flush_chars")) { + func_exit(); + return; + } + if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || + !port->xmit_buf) { + func_exit(); + return; + } + spin_lock_irqsave(&bp->lock, flags); + port->IER |= IER_TXRDY; + sx_out(port_Board(port), CD186x_CAR, port_No(port)); + sx_out(port_Board(port), CD186x_IER, port->IER); + spin_unlock_irqrestore(&bp->lock, flags); + + func_exit(); +} + + +static int sx_write_room(struct tty_struct *tty) +{ + struct specialix_port *port = tty->driver_data; + int ret; + + func_enter(); + + if (sx_paranoia_check(port, tty->name, "sx_write_room")) { + func_exit(); + return 0; + } + + ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1; + if (ret < 0) + ret = 0; + + func_exit(); + return ret; +} + + +static int sx_chars_in_buffer(struct tty_struct *tty) +{ + struct specialix_port *port = tty->driver_data; + + func_enter(); + + if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) { + func_exit(); + return 0; + } + func_exit(); + return port->xmit_cnt; +} + +static int sx_tiocmget(struct tty_struct *tty) +{ + struct specialix_port *port = tty->driver_data; + struct specialix_board *bp; + unsigned char status; + unsigned int result; + unsigned long flags; + + func_enter(); + + if (sx_paranoia_check(port, tty->name, __func__)) { + func_exit(); + return -ENODEV; + } + + bp = port_Board(port); + spin_lock_irqsave(&bp->lock, flags); + sx_out(bp, CD186x_CAR, port_No(port)); + status = sx_in(bp, CD186x_MSVR); + spin_unlock_irqrestore(&bp->lock, flags); + dprintk(SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n", + port_No(port), status, sx_in(bp, CD186x_CAR)); + dprintk(SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port); + if (sx_crtscts(port->port.tty)) { + result = TIOCM_DTR | TIOCM_DSR + | ((status & MSVR_DTR) ? TIOCM_RTS : 0) + | ((status & MSVR_CD) ? TIOCM_CAR : 0) + | ((status & MSVR_CTS) ? TIOCM_CTS : 0); + } else { + result = TIOCM_RTS | TIOCM_DSR + | ((status & MSVR_DTR) ? TIOCM_DTR : 0) + | ((status & MSVR_CD) ? TIOCM_CAR : 0) + | ((status & MSVR_CTS) ? TIOCM_CTS : 0); + } + + func_exit(); + + return result; +} + + +static int sx_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + struct specialix_port *port = tty->driver_data; + unsigned long flags; + struct specialix_board *bp; + + func_enter(); + + if (sx_paranoia_check(port, tty->name, __func__)) { + func_exit(); + return -ENODEV; + } + + bp = port_Board(port); + + spin_lock_irqsave(&port->lock, flags); + if (sx_crtscts(port->port.tty)) { + if (set & TIOCM_RTS) + port->MSVR |= MSVR_DTR; + } else { + if (set & TIOCM_DTR) + port->MSVR |= MSVR_DTR; + } + if (sx_crtscts(port->port.tty)) { + if (clear & TIOCM_RTS) + port->MSVR &= ~MSVR_DTR; + } else { + if (clear & TIOCM_DTR) + port->MSVR &= ~MSVR_DTR; + } + spin_lock(&bp->lock); + sx_out(bp, CD186x_CAR, port_No(port)); + sx_out(bp, CD186x_MSVR, port->MSVR); + spin_unlock(&bp->lock); + spin_unlock_irqrestore(&port->lock, flags); + func_exit(); + return 0; +} + + +static int sx_send_break(struct tty_struct *tty, int length) +{ + struct specialix_port *port = tty->driver_data; + struct specialix_board *bp = port_Board(port); + unsigned long flags; + + func_enter(); + if (length == 0 || length == -1) + return -EOPNOTSUPP; + + spin_lock_irqsave(&port->lock, flags); + port->break_length = SPECIALIX_TPS / HZ * length; + port->COR2 |= COR2_ETC; + port->IER |= IER_TXRDY; + spin_lock(&bp->lock); + sx_out(bp, CD186x_CAR, port_No(port)); + sx_out(bp, CD186x_COR2, port->COR2); + sx_out(bp, CD186x_IER, port->IER); + spin_unlock(&bp->lock); + spin_unlock_irqrestore(&port->lock, flags); + sx_wait_CCR(bp); + spin_lock_irqsave(&bp->lock, flags); + sx_out(bp, CD186x_CCR, CCR_CORCHG2); + spin_unlock_irqrestore(&bp->lock, flags); + sx_wait_CCR(bp); + + func_exit(); + return 0; +} + + +static int sx_set_serial_info(struct specialix_port *port, + struct serial_struct __user *newinfo) +{ + struct serial_struct tmp; + struct specialix_board *bp = port_Board(port); + int change_speed; + + func_enter(); + + if (copy_from_user(&tmp, newinfo, sizeof(tmp))) { + func_enter(); + return -EFAULT; + } + + mutex_lock(&port->port.mutex); + change_speed = ((port->port.flags & ASYNC_SPD_MASK) != + (tmp.flags & ASYNC_SPD_MASK)); + change_speed |= (tmp.custom_divisor != port->custom_divisor); + + if (!capable(CAP_SYS_ADMIN)) { + if ((tmp.close_delay != port->port.close_delay) || + (tmp.closing_wait != port->port.closing_wait) || + ((tmp.flags & ~ASYNC_USR_MASK) != + (port->port.flags & ~ASYNC_USR_MASK))) { + func_exit(); + mutex_unlock(&port->port.mutex); + return -EPERM; + } + port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | + (tmp.flags & ASYNC_USR_MASK)); + port->custom_divisor = tmp.custom_divisor; + } else { + port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) | + (tmp.flags & ASYNC_FLAGS)); + port->port.close_delay = tmp.close_delay; + port->port.closing_wait = tmp.closing_wait; + port->custom_divisor = tmp.custom_divisor; + } + if (change_speed) + sx_change_speed(bp, port); + + func_exit(); + mutex_unlock(&port->port.mutex); + return 0; +} + + +static int sx_get_serial_info(struct specialix_port *port, + struct serial_struct __user *retinfo) +{ + struct serial_struct tmp; + struct specialix_board *bp = port_Board(port); + + func_enter(); + + memset(&tmp, 0, sizeof(tmp)); + mutex_lock(&port->port.mutex); + tmp.type = PORT_CIRRUS; + tmp.line = port - sx_port; + tmp.port = bp->base; + tmp.irq = bp->irq; + tmp.flags = port->port.flags; + tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC; + tmp.close_delay = port->port.close_delay * HZ/100; + tmp.closing_wait = port->port.closing_wait * HZ/100; + tmp.custom_divisor = port->custom_divisor; + tmp.xmit_fifo_size = CD186x_NFIFO; + mutex_unlock(&port->port.mutex); + if (copy_to_user(retinfo, &tmp, sizeof(tmp))) { + func_exit(); + return -EFAULT; + } + + func_exit(); + return 0; +} + + +static int sx_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + struct specialix_port *port = tty->driver_data; + void __user *argp = (void __user *)arg; + + func_enter(); + + if (sx_paranoia_check(port, tty->name, "sx_ioctl")) { + func_exit(); + return -ENODEV; + } + + switch (cmd) { + case TIOCGSERIAL: + func_exit(); + return sx_get_serial_info(port, argp); + case TIOCSSERIAL: + func_exit(); + return sx_set_serial_info(port, argp); + default: + func_exit(); + return -ENOIOCTLCMD; + } + func_exit(); + return 0; +} + + +static void sx_throttle(struct tty_struct *tty) +{ + struct specialix_port *port = tty->driver_data; + struct specialix_board *bp; + unsigned long flags; + + func_enter(); + + if (sx_paranoia_check(port, tty->name, "sx_throttle")) { + func_exit(); + return; + } + + bp = port_Board(port); + + /* Use DTR instead of RTS ! */ + if (sx_crtscts(tty)) + port->MSVR &= ~MSVR_DTR; + else { + /* Auch!!! I think the system shouldn't call this then. */ + /* Or maybe we're supposed (allowed?) to do our side of hw + handshake anyway, even when hardware handshake is off. + When you see this in your logs, please report.... */ + printk(KERN_ERR + "sx%d: Need to throttle, but can't (hardware hs is off)\n", + port_No(port)); + } + spin_lock_irqsave(&bp->lock, flags); + sx_out(bp, CD186x_CAR, port_No(port)); + spin_unlock_irqrestore(&bp->lock, flags); + if (I_IXOFF(tty)) { + sx_wait_CCR(bp); + spin_lock_irqsave(&bp->lock, flags); + sx_out(bp, CD186x_CCR, CCR_SSCH2); + spin_unlock_irqrestore(&bp->lock, flags); + sx_wait_CCR(bp); + } + spin_lock_irqsave(&bp->lock, flags); + sx_out(bp, CD186x_MSVR, port->MSVR); + spin_unlock_irqrestore(&bp->lock, flags); + + func_exit(); +} + + +static void sx_unthrottle(struct tty_struct *tty) +{ + struct specialix_port *port = tty->driver_data; + struct specialix_board *bp; + unsigned long flags; + + func_enter(); + + if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) { + func_exit(); + return; + } + + bp = port_Board(port); + + spin_lock_irqsave(&port->lock, flags); + /* XXXX Use DTR INSTEAD???? */ + if (sx_crtscts(tty)) + port->MSVR |= MSVR_DTR; + /* Else clause: see remark in "sx_throttle"... */ + spin_lock(&bp->lock); + sx_out(bp, CD186x_CAR, port_No(port)); + spin_unlock(&bp->lock); + if (I_IXOFF(tty)) { + spin_unlock_irqrestore(&port->lock, flags); + sx_wait_CCR(bp); + spin_lock_irqsave(&bp->lock, flags); + sx_out(bp, CD186x_CCR, CCR_SSCH1); + spin_unlock_irqrestore(&bp->lock, flags); + sx_wait_CCR(bp); + spin_lock_irqsave(&port->lock, flags); + } + spin_lock(&bp->lock); + sx_out(bp, CD186x_MSVR, port->MSVR); + spin_unlock(&bp->lock); + spin_unlock_irqrestore(&port->lock, flags); + + func_exit(); +} + + +static void sx_stop(struct tty_struct *tty) +{ + struct specialix_port *port = tty->driver_data; + struct specialix_board *bp; + unsigned long flags; + + func_enter(); + + if (sx_paranoia_check(port, tty->name, "sx_stop")) { + func_exit(); + return; + } + + bp = port_Board(port); + + spin_lock_irqsave(&port->lock, flags); + port->IER &= ~IER_TXRDY; + spin_lock(&bp->lock); + sx_out(bp, CD186x_CAR, port_No(port)); + sx_out(bp, CD186x_IER, port->IER); + spin_unlock(&bp->lock); + spin_unlock_irqrestore(&port->lock, flags); + + func_exit(); +} + + +static void sx_start(struct tty_struct *tty) +{ + struct specialix_port *port = tty->driver_data; + struct specialix_board *bp; + unsigned long flags; + + func_enter(); + + if (sx_paranoia_check(port, tty->name, "sx_start")) { + func_exit(); + return; + } + + bp = port_Board(port); + + spin_lock_irqsave(&port->lock, flags); + if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { + port->IER |= IER_TXRDY; + spin_lock(&bp->lock); + sx_out(bp, CD186x_CAR, port_No(port)); + sx_out(bp, CD186x_IER, port->IER); + spin_unlock(&bp->lock); + } + spin_unlock_irqrestore(&port->lock, flags); + + func_exit(); +} + +static void sx_hangup(struct tty_struct *tty) +{ + struct specialix_port *port = tty->driver_data; + struct specialix_board *bp; + unsigned long flags; + + func_enter(); + + if (sx_paranoia_check(port, tty->name, "sx_hangup")) { + func_exit(); + return; + } + + bp = port_Board(port); + + sx_shutdown_port(bp, port); + spin_lock_irqsave(&port->lock, flags); + bp->count -= port->port.count; + if (bp->count < 0) { + printk(KERN_ERR + "sx%d: sx_hangup: bad board count: %d port: %d\n", + board_No(bp), bp->count, tty->index); + bp->count = 0; + } + port->port.count = 0; + port->port.flags &= ~ASYNC_NORMAL_ACTIVE; + port->port.tty = NULL; + spin_unlock_irqrestore(&port->lock, flags); + wake_up_interruptible(&port->port.open_wait); + + func_exit(); +} + + +static void sx_set_termios(struct tty_struct *tty, + struct ktermios *old_termios) +{ + struct specialix_port *port = tty->driver_data; + unsigned long flags; + struct specialix_board *bp; + + if (sx_paranoia_check(port, tty->name, "sx_set_termios")) + return; + + bp = port_Board(port); + spin_lock_irqsave(&port->lock, flags); + sx_change_speed(port_Board(port), port); + spin_unlock_irqrestore(&port->lock, flags); + + if ((old_termios->c_cflag & CRTSCTS) && + !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + sx_start(tty); + } +} + +static const struct tty_operations sx_ops = { + .open = sx_open, + .close = sx_close, + .write = sx_write, + .put_char = sx_put_char, + .flush_chars = sx_flush_chars, + .write_room = sx_write_room, + .chars_in_buffer = sx_chars_in_buffer, + .flush_buffer = sx_flush_buffer, + .ioctl = sx_ioctl, + .throttle = sx_throttle, + .unthrottle = sx_unthrottle, + .set_termios = sx_set_termios, + .stop = sx_stop, + .start = sx_start, + .hangup = sx_hangup, + .tiocmget = sx_tiocmget, + .tiocmset = sx_tiocmset, + .break_ctl = sx_send_break, +}; + +static int sx_init_drivers(void) +{ + int error; + int i; + + func_enter(); + + specialix_driver = alloc_tty_driver(SX_NBOARD * SX_NPORT); + if (!specialix_driver) { + printk(KERN_ERR "sx: Couldn't allocate tty_driver.\n"); + func_exit(); + return 1; + } + + specialix_driver->owner = THIS_MODULE; + specialix_driver->name = "ttyW"; + specialix_driver->major = SPECIALIX_NORMAL_MAJOR; + specialix_driver->type = TTY_DRIVER_TYPE_SERIAL; + specialix_driver->subtype = SERIAL_TYPE_NORMAL; + specialix_driver->init_termios = tty_std_termios; + specialix_driver->init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + specialix_driver->init_termios.c_ispeed = 9600; + specialix_driver->init_termios.c_ospeed = 9600; + specialix_driver->flags = TTY_DRIVER_REAL_RAW | + TTY_DRIVER_HARDWARE_BREAK; + tty_set_operations(specialix_driver, &sx_ops); + + error = tty_register_driver(specialix_driver); + if (error) { + put_tty_driver(specialix_driver); + printk(KERN_ERR + "sx: Couldn't register specialix IO8+ driver, error = %d\n", + error); + func_exit(); + return 1; + } + memset(sx_port, 0, sizeof(sx_port)); + for (i = 0; i < SX_NPORT * SX_NBOARD; i++) { + sx_port[i].magic = SPECIALIX_MAGIC; + tty_port_init(&sx_port[i].port); + spin_lock_init(&sx_port[i].lock); + } + + func_exit(); + return 0; +} + +static void sx_release_drivers(void) +{ + func_enter(); + + tty_unregister_driver(specialix_driver); + put_tty_driver(specialix_driver); + func_exit(); +} + +/* + * This routine must be called by kernel at boot time + */ +static int __init specialix_init(void) +{ + int i; + int found = 0; + + func_enter(); + + printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n"); + printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n"); + if (sx_rtscts) + printk(KERN_INFO + "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n"); + else + printk(KERN_INFO "sx: DTR/RTS pin is always RTS.\n"); + + for (i = 0; i < SX_NBOARD; i++) + spin_lock_init(&sx_board[i].lock); + + if (sx_init_drivers()) { + func_exit(); + return -EIO; + } + + for (i = 0; i < SX_NBOARD; i++) + if (sx_board[i].base && !sx_probe(&sx_board[i])) + found++; + +#ifdef CONFIG_PCI + { + struct pci_dev *pdev = NULL; + + i = 0; + while (i < SX_NBOARD) { + if (sx_board[i].flags & SX_BOARD_PRESENT) { + i++; + continue; + } + pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX, + PCI_DEVICE_ID_SPECIALIX_IO8, pdev); + if (!pdev) + break; + + if (pci_enable_device(pdev)) + continue; + + sx_board[i].irq = pdev->irq; + + sx_board[i].base = pci_resource_start(pdev, 2); + + sx_board[i].flags |= SX_BOARD_IS_PCI; + if (!sx_probe(&sx_board[i])) + found++; + } + /* May exit pci_get sequence early with lots of boards */ + if (pdev != NULL) + pci_dev_put(pdev); + } +#endif + + if (!found) { + sx_release_drivers(); + printk(KERN_INFO "sx: No specialix IO8+ boards detected.\n"); + func_exit(); + return -EIO; + } + + func_exit(); + return 0; +} + +static int iobase[SX_NBOARD] = {0,}; +static int irq[SX_NBOARD] = {0,}; + +module_param_array(iobase, int, NULL, 0); +module_param_array(irq, int, NULL, 0); +module_param(sx_debug, int, 0); +module_param(sx_rtscts, int, 0); +module_param(sx_rxfifo, int, 0); + +/* + * You can setup up to 4 boards. + * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter. + * You should specify the IRQs too in that case "irq=....,...". + * + * More than 4 boards in one computer is not possible, as the card can + * only use 4 different interrupts. + * + */ +static int __init specialix_init_module(void) +{ + int i; + + func_enter(); + + if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) { + for (i = 0; i < SX_NBOARD; i++) { + sx_board[i].base = iobase[i]; + sx_board[i].irq = irq[i]; + sx_board[i].count = 0; + } + } + + func_exit(); + + return specialix_init(); +} + +static void __exit specialix_exit_module(void) +{ + int i; + + func_enter(); + + sx_release_drivers(); + for (i = 0; i < SX_NBOARD; i++) + if (sx_board[i].flags & SX_BOARD_PRESENT) + sx_release_io_range(&sx_board[i]); + func_exit(); +} + +static struct pci_device_id specialx_pci_tbl[] __devinitdata __used = { + { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_IO8) }, + { } +}; +MODULE_DEVICE_TABLE(pci, specialx_pci_tbl); + +module_init(specialix_init_module); +module_exit(specialix_exit_module); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS_CHARDEV_MAJOR(SPECIALIX_NORMAL_MAJOR); diff --git a/drivers/staging/tty/specialix_io8.h b/drivers/staging/tty/specialix_io8.h new file mode 100644 index 000000000000..c63005274d9b --- /dev/null +++ b/drivers/staging/tty/specialix_io8.h @@ -0,0 +1,140 @@ +/* + * linux/drivers/char/specialix_io8.h -- + * Specialix IO8+ multiport serial driver. + * + * Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl) + * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) + * + * + * Specialix pays for the development and support of this driver. + * Please DO contact io8-linux@specialix.co.uk if you require + * support. + * + * This driver was developped in the BitWizard linux device + * driver service. If you require a linux device driver for your + * product, please contact devices@BitWizard.nl for a quote. + * + * This code is firmly based on the riscom/8 serial driver, + * written by Dmitry Gorodchanin. The specialix IO8+ card + * programming information was obtained from the CL-CD1865 Data + * Book, and Specialix document number 6200059: IO8+ Hardware + * Functional Specification. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, + * USA. + * */ + +#ifndef __LINUX_SPECIALIX_H +#define __LINUX_SPECIALIX_H + +#include + +#ifdef __KERNEL__ + +/* You can have max 4 ISA cards in one PC, and I recommend not much +more than a few PCI versions of the card. */ + +#define SX_NBOARD 8 + +/* NOTE: Specialix decoder recognizes 4 addresses, but only two are used.... */ +#define SX_IO_SPACE 4 +/* The PCI version decodes 8 addresses, but still only 2 are used. */ +#define SX_PCI_IO_SPACE 8 + +/* eight ports per board. */ +#define SX_NPORT 8 +#define SX_BOARD(line) ((line) / SX_NPORT) +#define SX_PORT(line) ((line) & (SX_NPORT - 1)) + + +#define SX_DATA_REG 0 /* Base+0 : Data register */ +#define SX_ADDR_REG 1 /* base+1 : Address register. */ + +#define MHz *1000000 /* I'm ashamed of myself. */ + +/* On-board oscillator frequency */ +#define SX_OSCFREQ (25 MHz/2) +/* There is a 25MHz crystal on the board, but the chip is in /2 mode */ + + +/* Ticks per sec. Used for setting receiver timeout and break length */ +#define SPECIALIX_TPS 4000 + +/* Yeah, after heavy testing I decided it must be 6. + * Sure, You can change it if needed. + */ +#define SPECIALIX_RXFIFO 6 /* Max. receiver FIFO size (1-8) */ + +#define SPECIALIX_MAGIC 0x0907 + +#define SX_CCR_TIMEOUT 10000 /* CCR timeout. You may need to wait upto + 10 milliseconds before the internal + processor is available again after + you give it a command */ + +#define SX_IOBASE1 0x100 +#define SX_IOBASE2 0x180 +#define SX_IOBASE3 0x250 +#define SX_IOBASE4 0x260 + +struct specialix_board { + unsigned long flags; + unsigned short base; + unsigned char irq; + //signed char count; + int count; + unsigned char DTR; + int reg; + spinlock_t lock; +}; + +#define SX_BOARD_PRESENT 0x00000001 +#define SX_BOARD_ACTIVE 0x00000002 +#define SX_BOARD_IS_PCI 0x00000004 + + +struct specialix_port { + int magic; + struct tty_port port; + int baud_base; + int flags; + int timeout; + unsigned char * xmit_buf; + int custom_divisor; + int xmit_head; + int xmit_tail; + int xmit_cnt; + short wakeup_chars; + short break_length; + unsigned char mark_mask; + unsigned char IER; + unsigned char MSVR; + unsigned char COR2; + unsigned long overrun; + unsigned long hits[10]; + spinlock_t lock; +}; + +#endif /* __KERNEL__ */ +#endif /* __LINUX_SPECIALIX_H */ + + + + + + + + + diff --git a/drivers/staging/tty/stallion.c b/drivers/staging/tty/stallion.c new file mode 100644 index 000000000000..4fff5cd3b163 --- /dev/null +++ b/drivers/staging/tty/stallion.c @@ -0,0 +1,4651 @@ +/*****************************************************************************/ + +/* + * stallion.c -- stallion multiport serial driver. + * + * Copyright (C) 1996-1999 Stallion Technologies + * Copyright (C) 1994-1996 Greg Ungerer. + * + * This code is loosely based on the Linux serial driver, written by + * Linus Torvalds, Theodore T'so and others. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +/*****************************************************************************/ + +/* + * Define different board types. Use the standard Stallion "assigned" + * board numbers. Boards supported in this driver are abbreviated as + * EIO = EasyIO and ECH = EasyConnection 8/32. + */ +#define BRD_EASYIO 20 +#define BRD_ECH 21 +#define BRD_ECHMC 22 +#define BRD_ECHPCI 26 +#define BRD_ECH64PCI 27 +#define BRD_EASYIOPCI 28 + +struct stlconf { + unsigned int brdtype; + int ioaddr1; + int ioaddr2; + unsigned long memaddr; + int irq; + int irqtype; +}; + +static unsigned int stl_nrbrds; + +/*****************************************************************************/ + +/* + * Define some important driver characteristics. Device major numbers + * allocated as per Linux Device Registry. + */ +#ifndef STL_SIOMEMMAJOR +#define STL_SIOMEMMAJOR 28 +#endif +#ifndef STL_SERIALMAJOR +#define STL_SERIALMAJOR 24 +#endif +#ifndef STL_CALLOUTMAJOR +#define STL_CALLOUTMAJOR 25 +#endif + +/* + * Set the TX buffer size. Bigger is better, but we don't want + * to chew too much memory with buffers! + */ +#define STL_TXBUFLOW 512 +#define STL_TXBUFSIZE 4096 + +/*****************************************************************************/ + +/* + * Define our local driver identity first. Set up stuff to deal with + * all the local structures required by a serial tty driver. + */ +static char *stl_drvtitle = "Stallion Multiport Serial Driver"; +static char *stl_drvname = "stallion"; +static char *stl_drvversion = "5.6.0"; + +static struct tty_driver *stl_serial; + +/* + * Define a local default termios struct. All ports will be created + * with this termios initially. Basically all it defines is a raw port + * at 9600, 8 data bits, 1 stop bit. + */ +static struct ktermios stl_deftermios = { + .c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL), + .c_cc = INIT_C_CC, + .c_ispeed = 9600, + .c_ospeed = 9600, +}; + +/* + * Define global place to put buffer overflow characters. + */ +static char stl_unwanted[SC26198_RXFIFOSIZE]; + +/*****************************************************************************/ + +static DEFINE_MUTEX(stl_brdslock); +static struct stlbrd *stl_brds[STL_MAXBRDS]; + +static const struct tty_port_operations stl_port_ops; + +/* + * Per board state flags. Used with the state field of the board struct. + * Not really much here! + */ +#define BRD_FOUND 0x1 +#define STL_PROBED 0x2 + + +/* + * Define the port structure istate flags. These set of flags are + * modified at interrupt time - so setting and reseting them needs + * to be atomic. Use the bit clear/setting routines for this. + */ +#define ASYI_TXBUSY 1 +#define ASYI_TXLOW 2 +#define ASYI_TXFLOWED 3 + +/* + * Define an array of board names as printable strings. Handy for + * referencing boards when printing trace and stuff. + */ +static char *stl_brdnames[] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "EasyIO", + "EC8/32-AT", + "EC8/32-MC", + NULL, + NULL, + NULL, + "EC8/32-PCI", + "EC8/64-PCI", + "EasyIO-PCI", +}; + +/*****************************************************************************/ + +/* + * Define some string labels for arguments passed from the module + * load line. These allow for easy board definitions, and easy + * modification of the io, memory and irq resoucres. + */ +static unsigned int stl_nargs; +static char *board0[4]; +static char *board1[4]; +static char *board2[4]; +static char *board3[4]; + +static char **stl_brdsp[] = { + (char **) &board0, + (char **) &board1, + (char **) &board2, + (char **) &board3 +}; + +/* + * Define a set of common board names, and types. This is used to + * parse any module arguments. + */ + +static struct { + char *name; + int type; +} stl_brdstr[] = { + { "easyio", BRD_EASYIO }, + { "eio", BRD_EASYIO }, + { "20", BRD_EASYIO }, + { "ec8/32", BRD_ECH }, + { "ec8/32-at", BRD_ECH }, + { "ec8/32-isa", BRD_ECH }, + { "ech", BRD_ECH }, + { "echat", BRD_ECH }, + { "21", BRD_ECH }, + { "ec8/32-mc", BRD_ECHMC }, + { "ec8/32-mca", BRD_ECHMC }, + { "echmc", BRD_ECHMC }, + { "echmca", BRD_ECHMC }, + { "22", BRD_ECHMC }, + { "ec8/32-pc", BRD_ECHPCI }, + { "ec8/32-pci", BRD_ECHPCI }, + { "26", BRD_ECHPCI }, + { "ec8/64-pc", BRD_ECH64PCI }, + { "ec8/64-pci", BRD_ECH64PCI }, + { "ech-pci", BRD_ECH64PCI }, + { "echpci", BRD_ECH64PCI }, + { "echpc", BRD_ECH64PCI }, + { "27", BRD_ECH64PCI }, + { "easyio-pc", BRD_EASYIOPCI }, + { "easyio-pci", BRD_EASYIOPCI }, + { "eio-pci", BRD_EASYIOPCI }, + { "eiopci", BRD_EASYIOPCI }, + { "28", BRD_EASYIOPCI }, +}; + +/* + * Define the module agruments. + */ + +module_param_array(board0, charp, &stl_nargs, 0); +MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,ioaddr2][,irq]]"); +module_param_array(board1, charp, &stl_nargs, 0); +MODULE_PARM_DESC(board1, "Board 1 config -> name[,ioaddr[,ioaddr2][,irq]]"); +module_param_array(board2, charp, &stl_nargs, 0); +MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,ioaddr2][,irq]]"); +module_param_array(board3, charp, &stl_nargs, 0); +MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,ioaddr2][,irq]]"); + +/*****************************************************************************/ + +/* + * Hardware ID bits for the EasyIO and ECH boards. These defines apply + * to the directly accessible io ports of these boards (not the uarts - + * they are in cd1400.h and sc26198.h). + */ +#define EIO_8PORTRS 0x04 +#define EIO_4PORTRS 0x05 +#define EIO_8PORTDI 0x00 +#define EIO_8PORTM 0x06 +#define EIO_MK3 0x03 +#define EIO_IDBITMASK 0x07 + +#define EIO_BRDMASK 0xf0 +#define ID_BRD4 0x10 +#define ID_BRD8 0x20 +#define ID_BRD16 0x30 + +#define EIO_INTRPEND 0x08 +#define EIO_INTEDGE 0x00 +#define EIO_INTLEVEL 0x08 +#define EIO_0WS 0x10 + +#define ECH_ID 0xa0 +#define ECH_IDBITMASK 0xe0 +#define ECH_BRDENABLE 0x08 +#define ECH_BRDDISABLE 0x00 +#define ECH_INTENABLE 0x01 +#define ECH_INTDISABLE 0x00 +#define ECH_INTLEVEL 0x02 +#define ECH_INTEDGE 0x00 +#define ECH_INTRPEND 0x01 +#define ECH_BRDRESET 0x01 + +#define ECHMC_INTENABLE 0x01 +#define ECHMC_BRDRESET 0x02 + +#define ECH_PNLSTATUS 2 +#define ECH_PNL16PORT 0x20 +#define ECH_PNLIDMASK 0x07 +#define ECH_PNLXPID 0x40 +#define ECH_PNLINTRPEND 0x80 + +#define ECH_ADDR2MASK 0x1e0 + +/* + * Define the vector mapping bits for the programmable interrupt board + * hardware. These bits encode the interrupt for the board to use - it + * is software selectable (except the EIO-8M). + */ +static unsigned char stl_vecmap[] = { + 0xff, 0xff, 0xff, 0x04, 0x06, 0x05, 0xff, 0x07, + 0xff, 0xff, 0x00, 0x02, 0x01, 0xff, 0xff, 0x03 +}; + +/* + * Lock ordering is that you may not take stallion_lock holding + * brd_lock. + */ + +static spinlock_t brd_lock; /* Guard the board mapping */ +static spinlock_t stallion_lock; /* Guard the tty driver */ + +/* + * Set up enable and disable macros for the ECH boards. They require + * the secondary io address space to be activated and deactivated. + * This way all ECH boards can share their secondary io region. + * If this is an ECH-PCI board then also need to set the page pointer + * to point to the correct page. + */ +#define BRDENABLE(brdnr,pagenr) \ + if (stl_brds[(brdnr)]->brdtype == BRD_ECH) \ + outb((stl_brds[(brdnr)]->ioctrlval | ECH_BRDENABLE), \ + stl_brds[(brdnr)]->ioctrl); \ + else if (stl_brds[(brdnr)]->brdtype == BRD_ECHPCI) \ + outb((pagenr), stl_brds[(brdnr)]->ioctrl); + +#define BRDDISABLE(brdnr) \ + if (stl_brds[(brdnr)]->brdtype == BRD_ECH) \ + outb((stl_brds[(brdnr)]->ioctrlval | ECH_BRDDISABLE), \ + stl_brds[(brdnr)]->ioctrl); + +#define STL_CD1400MAXBAUD 230400 +#define STL_SC26198MAXBAUD 460800 + +#define STL_BAUDBASE 115200 +#define STL_CLOSEDELAY (5 * HZ / 10) + +/*****************************************************************************/ + +/* + * Define the Stallion PCI vendor and device IDs. + */ +#ifndef PCI_VENDOR_ID_STALLION +#define PCI_VENDOR_ID_STALLION 0x124d +#endif +#ifndef PCI_DEVICE_ID_ECHPCI832 +#define PCI_DEVICE_ID_ECHPCI832 0x0000 +#endif +#ifndef PCI_DEVICE_ID_ECHPCI864 +#define PCI_DEVICE_ID_ECHPCI864 0x0002 +#endif +#ifndef PCI_DEVICE_ID_EIOPCI +#define PCI_DEVICE_ID_EIOPCI 0x0003 +#endif + +/* + * Define structure to hold all Stallion PCI boards. + */ + +static struct pci_device_id stl_pcibrds[] = { + { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI864), + .driver_data = BRD_ECH64PCI }, + { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_EIOPCI), + .driver_data = BRD_EASYIOPCI }, + { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI832), + .driver_data = BRD_ECHPCI }, + { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410), + .driver_data = BRD_ECHPCI }, + { } +}; +MODULE_DEVICE_TABLE(pci, stl_pcibrds); + +/*****************************************************************************/ + +/* + * Define macros to extract a brd/port number from a minor number. + */ +#define MINOR2BRD(min) (((min) & 0xc0) >> 6) +#define MINOR2PORT(min) ((min) & 0x3f) + +/* + * Define a baud rate table that converts termios baud rate selector + * into the actual baud rate value. All baud rate calculations are + * based on the actual baud rate required. + */ +static unsigned int stl_baudrates[] = { + 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, + 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600 +}; + +/*****************************************************************************/ + +/* + * Declare all those functions in this driver! + */ + +static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg); +static int stl_brdinit(struct stlbrd *brdp); +static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp); +static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp); + +/* + * CD1400 uart specific handling functions. + */ +static void stl_cd1400setreg(struct stlport *portp, int regnr, int value); +static int stl_cd1400getreg(struct stlport *portp, int regnr); +static int stl_cd1400updatereg(struct stlport *portp, int regnr, int value); +static int stl_cd1400panelinit(struct stlbrd *brdp, struct stlpanel *panelp); +static void stl_cd1400portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp); +static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp); +static int stl_cd1400getsignals(struct stlport *portp); +static void stl_cd1400setsignals(struct stlport *portp, int dtr, int rts); +static void stl_cd1400ccrwait(struct stlport *portp); +static void stl_cd1400enablerxtx(struct stlport *portp, int rx, int tx); +static void stl_cd1400startrxtx(struct stlport *portp, int rx, int tx); +static void stl_cd1400disableintrs(struct stlport *portp); +static void stl_cd1400sendbreak(struct stlport *portp, int len); +static void stl_cd1400flowctrl(struct stlport *portp, int state); +static void stl_cd1400sendflow(struct stlport *portp, int state); +static void stl_cd1400flush(struct stlport *portp); +static int stl_cd1400datastate(struct stlport *portp); +static void stl_cd1400eiointr(struct stlpanel *panelp, unsigned int iobase); +static void stl_cd1400echintr(struct stlpanel *panelp, unsigned int iobase); +static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr); +static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr); +static void stl_cd1400mdmisr(struct stlpanel *panelp, int ioaddr); + +static inline int stl_cd1400breakisr(struct stlport *portp, int ioaddr); + +/* + * SC26198 uart specific handling functions. + */ +static void stl_sc26198setreg(struct stlport *portp, int regnr, int value); +static int stl_sc26198getreg(struct stlport *portp, int regnr); +static int stl_sc26198updatereg(struct stlport *portp, int regnr, int value); +static int stl_sc26198getglobreg(struct stlport *portp, int regnr); +static int stl_sc26198panelinit(struct stlbrd *brdp, struct stlpanel *panelp); +static void stl_sc26198portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp); +static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp); +static int stl_sc26198getsignals(struct stlport *portp); +static void stl_sc26198setsignals(struct stlport *portp, int dtr, int rts); +static void stl_sc26198enablerxtx(struct stlport *portp, int rx, int tx); +static void stl_sc26198startrxtx(struct stlport *portp, int rx, int tx); +static void stl_sc26198disableintrs(struct stlport *portp); +static void stl_sc26198sendbreak(struct stlport *portp, int len); +static void stl_sc26198flowctrl(struct stlport *portp, int state); +static void stl_sc26198sendflow(struct stlport *portp, int state); +static void stl_sc26198flush(struct stlport *portp); +static int stl_sc26198datastate(struct stlport *portp); +static void stl_sc26198wait(struct stlport *portp); +static void stl_sc26198txunflow(struct stlport *portp, struct tty_struct *tty); +static void stl_sc26198intr(struct stlpanel *panelp, unsigned int iobase); +static void stl_sc26198txisr(struct stlport *port); +static void stl_sc26198rxisr(struct stlport *port, unsigned int iack); +static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char ch); +static void stl_sc26198rxbadchars(struct stlport *portp); +static void stl_sc26198otherisr(struct stlport *port, unsigned int iack); + +/*****************************************************************************/ + +/* + * Generic UART support structure. + */ +typedef struct uart { + int (*panelinit)(struct stlbrd *brdp, struct stlpanel *panelp); + void (*portinit)(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp); + void (*setport)(struct stlport *portp, struct ktermios *tiosp); + int (*getsignals)(struct stlport *portp); + void (*setsignals)(struct stlport *portp, int dtr, int rts); + void (*enablerxtx)(struct stlport *portp, int rx, int tx); + void (*startrxtx)(struct stlport *portp, int rx, int tx); + void (*disableintrs)(struct stlport *portp); + void (*sendbreak)(struct stlport *portp, int len); + void (*flowctrl)(struct stlport *portp, int state); + void (*sendflow)(struct stlport *portp, int state); + void (*flush)(struct stlport *portp); + int (*datastate)(struct stlport *portp); + void (*intr)(struct stlpanel *panelp, unsigned int iobase); +} uart_t; + +/* + * Define some macros to make calling these functions nice and clean. + */ +#define stl_panelinit (* ((uart_t *) panelp->uartp)->panelinit) +#define stl_portinit (* ((uart_t *) portp->uartp)->portinit) +#define stl_setport (* ((uart_t *) portp->uartp)->setport) +#define stl_getsignals (* ((uart_t *) portp->uartp)->getsignals) +#define stl_setsignals (* ((uart_t *) portp->uartp)->setsignals) +#define stl_enablerxtx (* ((uart_t *) portp->uartp)->enablerxtx) +#define stl_startrxtx (* ((uart_t *) portp->uartp)->startrxtx) +#define stl_disableintrs (* ((uart_t *) portp->uartp)->disableintrs) +#define stl_sendbreak (* ((uart_t *) portp->uartp)->sendbreak) +#define stl_flowctrl (* ((uart_t *) portp->uartp)->flowctrl) +#define stl_sendflow (* ((uart_t *) portp->uartp)->sendflow) +#define stl_flush (* ((uart_t *) portp->uartp)->flush) +#define stl_datastate (* ((uart_t *) portp->uartp)->datastate) + +/*****************************************************************************/ + +/* + * CD1400 UART specific data initialization. + */ +static uart_t stl_cd1400uart = { + stl_cd1400panelinit, + stl_cd1400portinit, + stl_cd1400setport, + stl_cd1400getsignals, + stl_cd1400setsignals, + stl_cd1400enablerxtx, + stl_cd1400startrxtx, + stl_cd1400disableintrs, + stl_cd1400sendbreak, + stl_cd1400flowctrl, + stl_cd1400sendflow, + stl_cd1400flush, + stl_cd1400datastate, + stl_cd1400eiointr +}; + +/* + * Define the offsets within the register bank of a cd1400 based panel. + * These io address offsets are common to the EasyIO board as well. + */ +#define EREG_ADDR 0 +#define EREG_DATA 4 +#define EREG_RXACK 5 +#define EREG_TXACK 6 +#define EREG_MDACK 7 + +#define EREG_BANKSIZE 8 + +#define CD1400_CLK 25000000 +#define CD1400_CLK8M 20000000 + +/* + * Define the cd1400 baud rate clocks. These are used when calculating + * what clock and divisor to use for the required baud rate. Also + * define the maximum baud rate allowed, and the default base baud. + */ +static int stl_cd1400clkdivs[] = { + CD1400_CLK0, CD1400_CLK1, CD1400_CLK2, CD1400_CLK3, CD1400_CLK4 +}; + +/*****************************************************************************/ + +/* + * SC26198 UART specific data initization. + */ +static uart_t stl_sc26198uart = { + stl_sc26198panelinit, + stl_sc26198portinit, + stl_sc26198setport, + stl_sc26198getsignals, + stl_sc26198setsignals, + stl_sc26198enablerxtx, + stl_sc26198startrxtx, + stl_sc26198disableintrs, + stl_sc26198sendbreak, + stl_sc26198flowctrl, + stl_sc26198sendflow, + stl_sc26198flush, + stl_sc26198datastate, + stl_sc26198intr +}; + +/* + * Define the offsets within the register bank of a sc26198 based panel. + */ +#define XP_DATA 0 +#define XP_ADDR 1 +#define XP_MODID 2 +#define XP_STATUS 2 +#define XP_IACK 3 + +#define XP_BANKSIZE 4 + +/* + * Define the sc26198 baud rate table. Offsets within the table + * represent the actual baud rate selector of sc26198 registers. + */ +static unsigned int sc26198_baudtable[] = { + 50, 75, 150, 200, 300, 450, 600, 900, 1200, 1800, 2400, 3600, + 4800, 7200, 9600, 14400, 19200, 28800, 38400, 57600, 115200, + 230400, 460800, 921600 +}; + +#define SC26198_NRBAUDS ARRAY_SIZE(sc26198_baudtable) + +/*****************************************************************************/ + +/* + * Define the driver info for a user level control device. Used mainly + * to get at port stats - only not using the port device itself. + */ +static const struct file_operations stl_fsiomem = { + .owner = THIS_MODULE, + .unlocked_ioctl = stl_memioctl, + .llseek = noop_llseek, +}; + +static struct class *stallion_class; + +static void stl_cd_change(struct stlport *portp) +{ + unsigned int oldsigs = portp->sigs; + struct tty_struct *tty = tty_port_tty_get(&portp->port); + + if (!tty) + return; + + portp->sigs = stl_getsignals(portp); + + if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0)) + wake_up_interruptible(&portp->port.open_wait); + + if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) + if (portp->port.flags & ASYNC_CHECK_CD) + tty_hangup(tty); + tty_kref_put(tty); +} + +/* + * Check for any arguments passed in on the module load command line. + */ + +/*****************************************************************************/ + +/* + * Parse the supplied argument string, into the board conf struct. + */ + +static int __init stl_parsebrd(struct stlconf *confp, char **argp) +{ + char *sp; + unsigned int i; + + pr_debug("stl_parsebrd(confp=%p,argp=%p)\n", confp, argp); + + if ((argp[0] == NULL) || (*argp[0] == 0)) + return 0; + + for (sp = argp[0], i = 0; (*sp != 0) && (i < 25); sp++, i++) + *sp = tolower(*sp); + + for (i = 0; i < ARRAY_SIZE(stl_brdstr); i++) + if (strcmp(stl_brdstr[i].name, argp[0]) == 0) + break; + + if (i == ARRAY_SIZE(stl_brdstr)) { + printk("STALLION: unknown board name, %s?\n", argp[0]); + return 0; + } + + confp->brdtype = stl_brdstr[i].type; + + i = 1; + if ((argp[i] != NULL) && (*argp[i] != 0)) + confp->ioaddr1 = simple_strtoul(argp[i], NULL, 0); + i++; + if (confp->brdtype == BRD_ECH) { + if ((argp[i] != NULL) && (*argp[i] != 0)) + confp->ioaddr2 = simple_strtoul(argp[i], NULL, 0); + i++; + } + if ((argp[i] != NULL) && (*argp[i] != 0)) + confp->irq = simple_strtoul(argp[i], NULL, 0); + return 1; +} + +/*****************************************************************************/ + +/* + * Allocate a new board structure. Fill out the basic info in it. + */ + +static struct stlbrd *stl_allocbrd(void) +{ + struct stlbrd *brdp; + + brdp = kzalloc(sizeof(struct stlbrd), GFP_KERNEL); + if (!brdp) { + printk("STALLION: failed to allocate memory (size=%Zd)\n", + sizeof(struct stlbrd)); + return NULL; + } + + brdp->magic = STL_BOARDMAGIC; + return brdp; +} + +/*****************************************************************************/ + +static int stl_activate(struct tty_port *port, struct tty_struct *tty) +{ + struct stlport *portp = container_of(port, struct stlport, port); + if (!portp->tx.buf) { + portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); + if (!portp->tx.buf) + return -ENOMEM; + portp->tx.head = portp->tx.buf; + portp->tx.tail = portp->tx.buf; + } + stl_setport(portp, tty->termios); + portp->sigs = stl_getsignals(portp); + stl_setsignals(portp, 1, 1); + stl_enablerxtx(portp, 1, 1); + stl_startrxtx(portp, 1, 0); + return 0; +} + +static int stl_open(struct tty_struct *tty, struct file *filp) +{ + struct stlport *portp; + struct stlbrd *brdp; + unsigned int minordev, brdnr, panelnr; + int portnr; + + pr_debug("stl_open(tty=%p,filp=%p): device=%s\n", tty, filp, tty->name); + + minordev = tty->index; + brdnr = MINOR2BRD(minordev); + if (brdnr >= stl_nrbrds) + return -ENODEV; + brdp = stl_brds[brdnr]; + if (brdp == NULL) + return -ENODEV; + + minordev = MINOR2PORT(minordev); + for (portnr = -1, panelnr = 0; panelnr < STL_MAXPANELS; panelnr++) { + if (brdp->panels[panelnr] == NULL) + break; + if (minordev < brdp->panels[panelnr]->nrports) { + portnr = minordev; + break; + } + minordev -= brdp->panels[panelnr]->nrports; + } + if (portnr < 0) + return -ENODEV; + + portp = brdp->panels[panelnr]->ports[portnr]; + if (portp == NULL) + return -ENODEV; + + tty->driver_data = portp; + return tty_port_open(&portp->port, tty, filp); + +} + +/*****************************************************************************/ + +static int stl_carrier_raised(struct tty_port *port) +{ + struct stlport *portp = container_of(port, struct stlport, port); + return (portp->sigs & TIOCM_CD) ? 1 : 0; +} + +static void stl_dtr_rts(struct tty_port *port, int on) +{ + struct stlport *portp = container_of(port, struct stlport, port); + /* Takes brd_lock internally */ + stl_setsignals(portp, on, on); +} + +/*****************************************************************************/ + +static void stl_flushbuffer(struct tty_struct *tty) +{ + struct stlport *portp; + + pr_debug("stl_flushbuffer(tty=%p)\n", tty); + + portp = tty->driver_data; + if (portp == NULL) + return; + + stl_flush(portp); + tty_wakeup(tty); +} + +/*****************************************************************************/ + +static void stl_waituntilsent(struct tty_struct *tty, int timeout) +{ + struct stlport *portp; + unsigned long tend; + + pr_debug("stl_waituntilsent(tty=%p,timeout=%d)\n", tty, timeout); + + portp = tty->driver_data; + if (portp == NULL) + return; + + if (timeout == 0) + timeout = HZ; + tend = jiffies + timeout; + + while (stl_datastate(portp)) { + if (signal_pending(current)) + break; + msleep_interruptible(20); + if (time_after_eq(jiffies, tend)) + break; + } +} + +/*****************************************************************************/ + +static void stl_shutdown(struct tty_port *port) +{ + struct stlport *portp = container_of(port, struct stlport, port); + stl_disableintrs(portp); + stl_enablerxtx(portp, 0, 0); + stl_flush(portp); + portp->istate = 0; + if (portp->tx.buf != NULL) { + kfree(portp->tx.buf); + portp->tx.buf = NULL; + portp->tx.head = NULL; + portp->tx.tail = NULL; + } +} + +static void stl_close(struct tty_struct *tty, struct file *filp) +{ + struct stlport*portp; + pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp); + + portp = tty->driver_data; + if(portp == NULL) + return; + tty_port_close(&portp->port, tty, filp); +} + +/*****************************************************************************/ + +/* + * Write routine. Take data and stuff it in to the TX ring queue. + * If transmit interrupts are not running then start them. + */ + +static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count) +{ + struct stlport *portp; + unsigned int len, stlen; + unsigned char *chbuf; + char *head, *tail; + + pr_debug("stl_write(tty=%p,buf=%p,count=%d)\n", tty, buf, count); + + portp = tty->driver_data; + if (portp == NULL) + return 0; + if (portp->tx.buf == NULL) + return 0; + +/* + * If copying direct from user space we must cater for page faults, + * causing us to "sleep" here for a while. To handle this copy in all + * the data we need now, into a local buffer. Then when we got it all + * copy it into the TX buffer. + */ + chbuf = (unsigned char *) buf; + + head = portp->tx.head; + tail = portp->tx.tail; + if (head >= tail) { + len = STL_TXBUFSIZE - (head - tail) - 1; + stlen = STL_TXBUFSIZE - (head - portp->tx.buf); + } else { + len = tail - head - 1; + stlen = len; + } + + len = min(len, (unsigned int)count); + count = 0; + while (len > 0) { + stlen = min(len, stlen); + memcpy(head, chbuf, stlen); + len -= stlen; + chbuf += stlen; + count += stlen; + head += stlen; + if (head >= (portp->tx.buf + STL_TXBUFSIZE)) { + head = portp->tx.buf; + stlen = tail - head; + } + } + portp->tx.head = head; + + clear_bit(ASYI_TXLOW, &portp->istate); + stl_startrxtx(portp, -1, 1); + + return count; +} + +/*****************************************************************************/ + +static int stl_putchar(struct tty_struct *tty, unsigned char ch) +{ + struct stlport *portp; + unsigned int len; + char *head, *tail; + + pr_debug("stl_putchar(tty=%p,ch=%x)\n", tty, ch); + + portp = tty->driver_data; + if (portp == NULL) + return -EINVAL; + if (portp->tx.buf == NULL) + return -EINVAL; + + head = portp->tx.head; + tail = portp->tx.tail; + + len = (head >= tail) ? (STL_TXBUFSIZE - (head - tail)) : (tail - head); + len--; + + if (len > 0) { + *head++ = ch; + if (head >= (portp->tx.buf + STL_TXBUFSIZE)) + head = portp->tx.buf; + } + portp->tx.head = head; + return 0; +} + +/*****************************************************************************/ + +/* + * If there are any characters in the buffer then make sure that TX + * interrupts are on and get'em out. Normally used after the putchar + * routine has been called. + */ + +static void stl_flushchars(struct tty_struct *tty) +{ + struct stlport *portp; + + pr_debug("stl_flushchars(tty=%p)\n", tty); + + portp = tty->driver_data; + if (portp == NULL) + return; + if (portp->tx.buf == NULL) + return; + + stl_startrxtx(portp, -1, 1); +} + +/*****************************************************************************/ + +static int stl_writeroom(struct tty_struct *tty) +{ + struct stlport *portp; + char *head, *tail; + + pr_debug("stl_writeroom(tty=%p)\n", tty); + + portp = tty->driver_data; + if (portp == NULL) + return 0; + if (portp->tx.buf == NULL) + return 0; + + head = portp->tx.head; + tail = portp->tx.tail; + return (head >= tail) ? (STL_TXBUFSIZE - (head - tail) - 1) : (tail - head - 1); +} + +/*****************************************************************************/ + +/* + * Return number of chars in the TX buffer. Normally we would just + * calculate the number of chars in the buffer and return that, but if + * the buffer is empty and TX interrupts are still on then we return + * that the buffer still has 1 char in it. This way whoever called us + * will not think that ALL chars have drained - since the UART still + * must have some chars in it (we are busy after all). + */ + +static int stl_charsinbuffer(struct tty_struct *tty) +{ + struct stlport *portp; + unsigned int size; + char *head, *tail; + + pr_debug("stl_charsinbuffer(tty=%p)\n", tty); + + portp = tty->driver_data; + if (portp == NULL) + return 0; + if (portp->tx.buf == NULL) + return 0; + + head = portp->tx.head; + tail = portp->tx.tail; + size = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head)); + if ((size == 0) && test_bit(ASYI_TXBUSY, &portp->istate)) + size = 1; + return size; +} + +/*****************************************************************************/ + +/* + * Generate the serial struct info. + */ + +static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp) +{ + struct serial_struct sio; + struct stlbrd *brdp; + + pr_debug("stl_getserial(portp=%p,sp=%p)\n", portp, sp); + + memset(&sio, 0, sizeof(struct serial_struct)); + + mutex_lock(&portp->port.mutex); + sio.line = portp->portnr; + sio.port = portp->ioaddr; + sio.flags = portp->port.flags; + sio.baud_base = portp->baud_base; + sio.close_delay = portp->close_delay; + sio.closing_wait = portp->closing_wait; + sio.custom_divisor = portp->custom_divisor; + sio.hub6 = 0; + if (portp->uartp == &stl_cd1400uart) { + sio.type = PORT_CIRRUS; + sio.xmit_fifo_size = CD1400_TXFIFOSIZE; + } else { + sio.type = PORT_UNKNOWN; + sio.xmit_fifo_size = SC26198_TXFIFOSIZE; + } + + brdp = stl_brds[portp->brdnr]; + if (brdp != NULL) + sio.irq = brdp->irq; + mutex_unlock(&portp->port.mutex); + + return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? -EFAULT : 0; +} + +/*****************************************************************************/ + +/* + * Set port according to the serial struct info. + * At this point we do not do any auto-configure stuff, so we will + * just quietly ignore any requests to change irq, etc. + */ + +static int stl_setserial(struct tty_struct *tty, struct serial_struct __user *sp) +{ + struct stlport * portp = tty->driver_data; + struct serial_struct sio; + + pr_debug("stl_setserial(portp=%p,sp=%p)\n", portp, sp); + + if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) + return -EFAULT; + mutex_lock(&portp->port.mutex); + if (!capable(CAP_SYS_ADMIN)) { + if ((sio.baud_base != portp->baud_base) || + (sio.close_delay != portp->close_delay) || + ((sio.flags & ~ASYNC_USR_MASK) != + (portp->port.flags & ~ASYNC_USR_MASK))) { + mutex_unlock(&portp->port.mutex); + return -EPERM; + } + } + + portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) | + (sio.flags & ASYNC_USR_MASK); + portp->baud_base = sio.baud_base; + portp->close_delay = sio.close_delay; + portp->closing_wait = sio.closing_wait; + portp->custom_divisor = sio.custom_divisor; + mutex_unlock(&portp->port.mutex); + stl_setport(portp, tty->termios); + return 0; +} + +/*****************************************************************************/ + +static int stl_tiocmget(struct tty_struct *tty) +{ + struct stlport *portp; + + portp = tty->driver_data; + if (portp == NULL) + return -ENODEV; + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + + return stl_getsignals(portp); +} + +static int stl_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + struct stlport *portp; + int rts = -1, dtr = -1; + + portp = tty->driver_data; + if (portp == NULL) + return -ENODEV; + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + + if (set & TIOCM_RTS) + rts = 1; + if (set & TIOCM_DTR) + dtr = 1; + if (clear & TIOCM_RTS) + rts = 0; + if (clear & TIOCM_DTR) + dtr = 0; + + stl_setsignals(portp, dtr, rts); + return 0; +} + +static int stl_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) +{ + struct stlport *portp; + int rc; + void __user *argp = (void __user *)arg; + + pr_debug("stl_ioctl(tty=%p,cmd=%x,arg=%lx)\n", tty, cmd, arg); + + portp = tty->driver_data; + if (portp == NULL) + return -ENODEV; + + if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && + (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + + rc = 0; + + switch (cmd) { + case TIOCGSERIAL: + rc = stl_getserial(portp, argp); + break; + case TIOCSSERIAL: + rc = stl_setserial(tty, argp); + break; + case COM_GETPORTSTATS: + rc = stl_getportstats(tty, portp, argp); + break; + case COM_CLRPORTSTATS: + rc = stl_clrportstats(portp, argp); + break; + case TIOCSERCONFIG: + case TIOCSERGWILD: + case TIOCSERSWILD: + case TIOCSERGETLSR: + case TIOCSERGSTRUCT: + case TIOCSERGETMULTI: + case TIOCSERSETMULTI: + default: + rc = -ENOIOCTLCMD; + break; + } + return rc; +} + +/*****************************************************************************/ + +/* + * Start the transmitter again. Just turn TX interrupts back on. + */ + +static void stl_start(struct tty_struct *tty) +{ + struct stlport *portp; + + pr_debug("stl_start(tty=%p)\n", tty); + + portp = tty->driver_data; + if (portp == NULL) + return; + stl_startrxtx(portp, -1, 1); +} + +/*****************************************************************************/ + +static void stl_settermios(struct tty_struct *tty, struct ktermios *old) +{ + struct stlport *portp; + struct ktermios *tiosp; + + pr_debug("stl_settermios(tty=%p,old=%p)\n", tty, old); + + portp = tty->driver_data; + if (portp == NULL) + return; + + tiosp = tty->termios; + if ((tiosp->c_cflag == old->c_cflag) && + (tiosp->c_iflag == old->c_iflag)) + return; + + stl_setport(portp, tiosp); + stl_setsignals(portp, ((tiosp->c_cflag & (CBAUD & ~CBAUDEX)) ? 1 : 0), + -1); + if ((old->c_cflag & CRTSCTS) && ((tiosp->c_cflag & CRTSCTS) == 0)) { + tty->hw_stopped = 0; + stl_start(tty); + } + if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL)) + wake_up_interruptible(&portp->port.open_wait); +} + +/*****************************************************************************/ + +/* + * Attempt to flow control who ever is sending us data. Based on termios + * settings use software or/and hardware flow control. + */ + +static void stl_throttle(struct tty_struct *tty) +{ + struct stlport *portp; + + pr_debug("stl_throttle(tty=%p)\n", tty); + + portp = tty->driver_data; + if (portp == NULL) + return; + stl_flowctrl(portp, 0); +} + +/*****************************************************************************/ + +/* + * Unflow control the device sending us data... + */ + +static void stl_unthrottle(struct tty_struct *tty) +{ + struct stlport *portp; + + pr_debug("stl_unthrottle(tty=%p)\n", tty); + + portp = tty->driver_data; + if (portp == NULL) + return; + stl_flowctrl(portp, 1); +} + +/*****************************************************************************/ + +/* + * Stop the transmitter. Basically to do this we will just turn TX + * interrupts off. + */ + +static void stl_stop(struct tty_struct *tty) +{ + struct stlport *portp; + + pr_debug("stl_stop(tty=%p)\n", tty); + + portp = tty->driver_data; + if (portp == NULL) + return; + stl_startrxtx(portp, -1, 0); +} + +/*****************************************************************************/ + +/* + * Hangup this port. This is pretty much like closing the port, only + * a little more brutal. No waiting for data to drain. Shutdown the + * port and maybe drop signals. + */ + +static void stl_hangup(struct tty_struct *tty) +{ + struct stlport *portp = tty->driver_data; + pr_debug("stl_hangup(tty=%p)\n", tty); + + if (portp == NULL) + return; + tty_port_hangup(&portp->port); +} + +/*****************************************************************************/ + +static int stl_breakctl(struct tty_struct *tty, int state) +{ + struct stlport *portp; + + pr_debug("stl_breakctl(tty=%p,state=%d)\n", tty, state); + + portp = tty->driver_data; + if (portp == NULL) + return -EINVAL; + + stl_sendbreak(portp, ((state == -1) ? 1 : 2)); + return 0; +} + +/*****************************************************************************/ + +static void stl_sendxchar(struct tty_struct *tty, char ch) +{ + struct stlport *portp; + + pr_debug("stl_sendxchar(tty=%p,ch=%x)\n", tty, ch); + + portp = tty->driver_data; + if (portp == NULL) + return; + + if (ch == STOP_CHAR(tty)) + stl_sendflow(portp, 0); + else if (ch == START_CHAR(tty)) + stl_sendflow(portp, 1); + else + stl_putchar(tty, ch); +} + +static void stl_portinfo(struct seq_file *m, struct stlport *portp, int portnr) +{ + int sigs; + char sep; + + seq_printf(m, "%d: uart:%s tx:%d rx:%d", + portnr, (portp->hwid == 1) ? "SC26198" : "CD1400", + (int) portp->stats.txtotal, (int) portp->stats.rxtotal); + + if (portp->stats.rxframing) + seq_printf(m, " fe:%d", (int) portp->stats.rxframing); + if (portp->stats.rxparity) + seq_printf(m, " pe:%d", (int) portp->stats.rxparity); + if (portp->stats.rxbreaks) + seq_printf(m, " brk:%d", (int) portp->stats.rxbreaks); + if (portp->stats.rxoverrun) + seq_printf(m, " oe:%d", (int) portp->stats.rxoverrun); + + sigs = stl_getsignals(portp); + sep = ' '; + if (sigs & TIOCM_RTS) { + seq_printf(m, "%c%s", sep, "RTS"); + sep = '|'; + } + if (sigs & TIOCM_CTS) { + seq_printf(m, "%c%s", sep, "CTS"); + sep = '|'; + } + if (sigs & TIOCM_DTR) { + seq_printf(m, "%c%s", sep, "DTR"); + sep = '|'; + } + if (sigs & TIOCM_CD) { + seq_printf(m, "%c%s", sep, "DCD"); + sep = '|'; + } + if (sigs & TIOCM_DSR) { + seq_printf(m, "%c%s", sep, "DSR"); + sep = '|'; + } + seq_putc(m, '\n'); +} + +/*****************************************************************************/ + +/* + * Port info, read from the /proc file system. + */ + +static int stl_proc_show(struct seq_file *m, void *v) +{ + struct stlbrd *brdp; + struct stlpanel *panelp; + struct stlport *portp; + unsigned int brdnr, panelnr, portnr; + int totalport; + + totalport = 0; + + seq_printf(m, "%s: version %s\n", stl_drvtitle, stl_drvversion); + +/* + * We scan through for each board, panel and port. The offset is + * calculated on the fly, and irrelevant ports are skipped. + */ + for (brdnr = 0; brdnr < stl_nrbrds; brdnr++) { + brdp = stl_brds[brdnr]; + if (brdp == NULL) + continue; + if (brdp->state == 0) + continue; + + totalport = brdnr * STL_MAXPORTS; + for (panelnr = 0; panelnr < brdp->nrpanels; panelnr++) { + panelp = brdp->panels[panelnr]; + if (panelp == NULL) + continue; + + for (portnr = 0; portnr < panelp->nrports; portnr++, + totalport++) { + portp = panelp->ports[portnr]; + if (portp == NULL) + continue; + stl_portinfo(m, portp, totalport); + } + } + } + return 0; +} + +static int stl_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, stl_proc_show, NULL); +} + +static const struct file_operations stl_proc_fops = { + .owner = THIS_MODULE, + .open = stl_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/*****************************************************************************/ + +/* + * All board interrupts are vectored through here first. This code then + * calls off to the approrpriate board interrupt handlers. + */ + +static irqreturn_t stl_intr(int irq, void *dev_id) +{ + struct stlbrd *brdp = dev_id; + + pr_debug("stl_intr(brdp=%p,irq=%d)\n", brdp, brdp->irq); + + return IRQ_RETVAL((* brdp->isr)(brdp)); +} + +/*****************************************************************************/ + +/* + * Interrupt service routine for EasyIO board types. + */ + +static int stl_eiointr(struct stlbrd *brdp) +{ + struct stlpanel *panelp; + unsigned int iobase; + int handled = 0; + + spin_lock(&brd_lock); + panelp = brdp->panels[0]; + iobase = panelp->iobase; + while (inb(brdp->iostatus) & EIO_INTRPEND) { + handled = 1; + (* panelp->isr)(panelp, iobase); + } + spin_unlock(&brd_lock); + return handled; +} + +/*****************************************************************************/ + +/* + * Interrupt service routine for ECH-AT board types. + */ + +static int stl_echatintr(struct stlbrd *brdp) +{ + struct stlpanel *panelp; + unsigned int ioaddr, bnknr; + int handled = 0; + + outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl); + + while (inb(brdp->iostatus) & ECH_INTRPEND) { + handled = 1; + for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) { + ioaddr = brdp->bnkstataddr[bnknr]; + if (inb(ioaddr) & ECH_PNLINTRPEND) { + panelp = brdp->bnk2panel[bnknr]; + (* panelp->isr)(panelp, (ioaddr & 0xfffc)); + } + } + } + + outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl); + + return handled; +} + +/*****************************************************************************/ + +/* + * Interrupt service routine for ECH-MCA board types. + */ + +static int stl_echmcaintr(struct stlbrd *brdp) +{ + struct stlpanel *panelp; + unsigned int ioaddr, bnknr; + int handled = 0; + + while (inb(brdp->iostatus) & ECH_INTRPEND) { + handled = 1; + for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) { + ioaddr = brdp->bnkstataddr[bnknr]; + if (inb(ioaddr) & ECH_PNLINTRPEND) { + panelp = brdp->bnk2panel[bnknr]; + (* panelp->isr)(panelp, (ioaddr & 0xfffc)); + } + } + } + return handled; +} + +/*****************************************************************************/ + +/* + * Interrupt service routine for ECH-PCI board types. + */ + +static int stl_echpciintr(struct stlbrd *brdp) +{ + struct stlpanel *panelp; + unsigned int ioaddr, bnknr, recheck; + int handled = 0; + + while (1) { + recheck = 0; + for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) { + outb(brdp->bnkpageaddr[bnknr], brdp->ioctrl); + ioaddr = brdp->bnkstataddr[bnknr]; + if (inb(ioaddr) & ECH_PNLINTRPEND) { + panelp = brdp->bnk2panel[bnknr]; + (* panelp->isr)(panelp, (ioaddr & 0xfffc)); + recheck++; + handled = 1; + } + } + if (! recheck) + break; + } + return handled; +} + +/*****************************************************************************/ + +/* + * Interrupt service routine for ECH-8/64-PCI board types. + */ + +static int stl_echpci64intr(struct stlbrd *brdp) +{ + struct stlpanel *panelp; + unsigned int ioaddr, bnknr; + int handled = 0; + + while (inb(brdp->ioctrl) & 0x1) { + handled = 1; + for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) { + ioaddr = brdp->bnkstataddr[bnknr]; + if (inb(ioaddr) & ECH_PNLINTRPEND) { + panelp = brdp->bnk2panel[bnknr]; + (* panelp->isr)(panelp, (ioaddr & 0xfffc)); + } + } + } + + return handled; +} + +/*****************************************************************************/ + +/* + * Initialize all the ports on a panel. + */ + +static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *panelp) +{ + struct stlport *portp; + unsigned int i; + int chipmask; + + pr_debug("stl_initports(brdp=%p,panelp=%p)\n", brdp, panelp); + + chipmask = stl_panelinit(brdp, panelp); + +/* + * All UART's are initialized (if found!). Now go through and setup + * each ports data structures. + */ + for (i = 0; i < panelp->nrports; i++) { + portp = kzalloc(sizeof(struct stlport), GFP_KERNEL); + if (!portp) { + printk("STALLION: failed to allocate memory " + "(size=%Zd)\n", sizeof(struct stlport)); + break; + } + tty_port_init(&portp->port); + portp->port.ops = &stl_port_ops; + portp->magic = STL_PORTMAGIC; + portp->portnr = i; + portp->brdnr = panelp->brdnr; + portp->panelnr = panelp->panelnr; + portp->uartp = panelp->uartp; + portp->clk = brdp->clk; + portp->baud_base = STL_BAUDBASE; + portp->close_delay = STL_CLOSEDELAY; + portp->closing_wait = 30 * HZ; + init_waitqueue_head(&portp->port.open_wait); + init_waitqueue_head(&portp->port.close_wait); + portp->stats.brd = portp->brdnr; + portp->stats.panel = portp->panelnr; + portp->stats.port = portp->portnr; + panelp->ports[i] = portp; + stl_portinit(brdp, panelp, portp); + } + + return 0; +} + +static void stl_cleanup_panels(struct stlbrd *brdp) +{ + struct stlpanel *panelp; + struct stlport *portp; + unsigned int j, k; + struct tty_struct *tty; + + for (j = 0; j < STL_MAXPANELS; j++) { + panelp = brdp->panels[j]; + if (panelp == NULL) + continue; + for (k = 0; k < STL_PORTSPERPANEL; k++) { + portp = panelp->ports[k]; + if (portp == NULL) + continue; + tty = tty_port_tty_get(&portp->port); + if (tty != NULL) { + stl_hangup(tty); + tty_kref_put(tty); + } + kfree(portp->tx.buf); + kfree(portp); + } + kfree(panelp); + } +} + +/*****************************************************************************/ + +/* + * Try to find and initialize an EasyIO board. + */ + +static int __devinit stl_initeio(struct stlbrd *brdp) +{ + struct stlpanel *panelp; + unsigned int status; + char *name; + int retval; + + pr_debug("stl_initeio(brdp=%p)\n", brdp); + + brdp->ioctrl = brdp->ioaddr1 + 1; + brdp->iostatus = brdp->ioaddr1 + 2; + + status = inb(brdp->iostatus); + if ((status & EIO_IDBITMASK) == EIO_MK3) + brdp->ioctrl++; + +/* + * Handle board specific stuff now. The real difference is PCI + * or not PCI. + */ + if (brdp->brdtype == BRD_EASYIOPCI) { + brdp->iosize1 = 0x80; + brdp->iosize2 = 0x80; + name = "serial(EIO-PCI)"; + outb(0x41, (brdp->ioaddr2 + 0x4c)); + } else { + brdp->iosize1 = 8; + name = "serial(EIO)"; + if ((brdp->irq < 0) || (brdp->irq > 15) || + (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) { + printk("STALLION: invalid irq=%d for brd=%d\n", + brdp->irq, brdp->brdnr); + retval = -EINVAL; + goto err; + } + outb((stl_vecmap[brdp->irq] | EIO_0WS | + ((brdp->irqtype) ? EIO_INTLEVEL : EIO_INTEDGE)), + brdp->ioctrl); + } + + retval = -EBUSY; + if (!request_region(brdp->ioaddr1, brdp->iosize1, name)) { + printk(KERN_WARNING "STALLION: Warning, board %d I/O address " + "%x conflicts with another device\n", brdp->brdnr, + brdp->ioaddr1); + goto err; + } + + if (brdp->iosize2 > 0) + if (!request_region(brdp->ioaddr2, brdp->iosize2, name)) { + printk(KERN_WARNING "STALLION: Warning, board %d I/O " + "address %x conflicts with another device\n", + brdp->brdnr, brdp->ioaddr2); + printk(KERN_WARNING "STALLION: Warning, also " + "releasing board %d I/O address %x \n", + brdp->brdnr, brdp->ioaddr1); + goto err_rel1; + } + +/* + * Everything looks OK, so let's go ahead and probe for the hardware. + */ + brdp->clk = CD1400_CLK; + brdp->isr = stl_eiointr; + + retval = -ENODEV; + switch (status & EIO_IDBITMASK) { + case EIO_8PORTM: + brdp->clk = CD1400_CLK8M; + /* fall thru */ + case EIO_8PORTRS: + case EIO_8PORTDI: + brdp->nrports = 8; + break; + case EIO_4PORTRS: + brdp->nrports = 4; + break; + case EIO_MK3: + switch (status & EIO_BRDMASK) { + case ID_BRD4: + brdp->nrports = 4; + break; + case ID_BRD8: + brdp->nrports = 8; + break; + case ID_BRD16: + brdp->nrports = 16; + break; + default: + goto err_rel2; + } + break; + default: + goto err_rel2; + } + +/* + * We have verified that the board is actually present, so now we + * can complete the setup. + */ + + panelp = kzalloc(sizeof(struct stlpanel), GFP_KERNEL); + if (!panelp) { + printk(KERN_WARNING "STALLION: failed to allocate memory " + "(size=%Zd)\n", sizeof(struct stlpanel)); + retval = -ENOMEM; + goto err_rel2; + } + + panelp->magic = STL_PANELMAGIC; + panelp->brdnr = brdp->brdnr; + panelp->panelnr = 0; + panelp->nrports = brdp->nrports; + panelp->iobase = brdp->ioaddr1; + panelp->hwid = status; + if ((status & EIO_IDBITMASK) == EIO_MK3) { + panelp->uartp = &stl_sc26198uart; + panelp->isr = stl_sc26198intr; + } else { + panelp->uartp = &stl_cd1400uart; + panelp->isr = stl_cd1400eiointr; + } + + brdp->panels[0] = panelp; + brdp->nrpanels = 1; + brdp->state |= BRD_FOUND; + brdp->hwid = status; + if (request_irq(brdp->irq, stl_intr, IRQF_SHARED, name, brdp) != 0) { + printk("STALLION: failed to register interrupt " + "routine for %s irq=%d\n", name, brdp->irq); + retval = -ENODEV; + goto err_fr; + } + + return 0; +err_fr: + stl_cleanup_panels(brdp); +err_rel2: + if (brdp->iosize2 > 0) + release_region(brdp->ioaddr2, brdp->iosize2); +err_rel1: + release_region(brdp->ioaddr1, brdp->iosize1); +err: + return retval; +} + +/*****************************************************************************/ + +/* + * Try to find an ECH board and initialize it. This code is capable of + * dealing with all types of ECH board. + */ + +static int __devinit stl_initech(struct stlbrd *brdp) +{ + struct stlpanel *panelp; + unsigned int status, nxtid, ioaddr, conflict, panelnr, banknr, i; + int retval; + char *name; + + pr_debug("stl_initech(brdp=%p)\n", brdp); + + status = 0; + conflict = 0; + +/* + * Set up the initial board register contents for boards. This varies a + * bit between the different board types. So we need to handle each + * separately. Also do a check that the supplied IRQ is good. + */ + switch (brdp->brdtype) { + + case BRD_ECH: + brdp->isr = stl_echatintr; + brdp->ioctrl = brdp->ioaddr1 + 1; + brdp->iostatus = brdp->ioaddr1 + 1; + status = inb(brdp->iostatus); + if ((status & ECH_IDBITMASK) != ECH_ID) { + retval = -ENODEV; + goto err; + } + if ((brdp->irq < 0) || (brdp->irq > 15) || + (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) { + printk("STALLION: invalid irq=%d for brd=%d\n", + brdp->irq, brdp->brdnr); + retval = -EINVAL; + goto err; + } + status = ((brdp->ioaddr2 & ECH_ADDR2MASK) >> 1); + status |= (stl_vecmap[brdp->irq] << 1); + outb((status | ECH_BRDRESET), brdp->ioaddr1); + brdp->ioctrlval = ECH_INTENABLE | + ((brdp->irqtype) ? ECH_INTLEVEL : ECH_INTEDGE); + for (i = 0; i < 10; i++) + outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl); + brdp->iosize1 = 2; + brdp->iosize2 = 32; + name = "serial(EC8/32)"; + outb(status, brdp->ioaddr1); + break; + + case BRD_ECHMC: + brdp->isr = stl_echmcaintr; + brdp->ioctrl = brdp->ioaddr1 + 0x20; + brdp->iostatus = brdp->ioctrl; + status = inb(brdp->iostatus); + if ((status & ECH_IDBITMASK) != ECH_ID) { + retval = -ENODEV; + goto err; + } + if ((brdp->irq < 0) || (brdp->irq > 15) || + (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) { + printk("STALLION: invalid irq=%d for brd=%d\n", + brdp->irq, brdp->brdnr); + retval = -EINVAL; + goto err; + } + outb(ECHMC_BRDRESET, brdp->ioctrl); + outb(ECHMC_INTENABLE, brdp->ioctrl); + brdp->iosize1 = 64; + name = "serial(EC8/32-MC)"; + break; + + case BRD_ECHPCI: + brdp->isr = stl_echpciintr; + brdp->ioctrl = brdp->ioaddr1 + 2; + brdp->iosize1 = 4; + brdp->iosize2 = 8; + name = "serial(EC8/32-PCI)"; + break; + + case BRD_ECH64PCI: + brdp->isr = stl_echpci64intr; + brdp->ioctrl = brdp->ioaddr2 + 0x40; + outb(0x43, (brdp->ioaddr1 + 0x4c)); + brdp->iosize1 = 0x80; + brdp->iosize2 = 0x80; + name = "serial(EC8/64-PCI)"; + break; + + default: + printk("STALLION: unknown board type=%d\n", brdp->brdtype); + retval = -EINVAL; + goto err; + } + +/* + * Check boards for possible IO address conflicts and return fail status + * if an IO conflict found. + */ + retval = -EBUSY; + if (!request_region(brdp->ioaddr1, brdp->iosize1, name)) { + printk(KERN_WARNING "STALLION: Warning, board %d I/O address " + "%x conflicts with another device\n", brdp->brdnr, + brdp->ioaddr1); + goto err; + } + + if (brdp->iosize2 > 0) + if (!request_region(brdp->ioaddr2, brdp->iosize2, name)) { + printk(KERN_WARNING "STALLION: Warning, board %d I/O " + "address %x conflicts with another device\n", + brdp->brdnr, brdp->ioaddr2); + printk(KERN_WARNING "STALLION: Warning, also " + "releasing board %d I/O address %x \n", + brdp->brdnr, brdp->ioaddr1); + goto err_rel1; + } + +/* + * Scan through the secondary io address space looking for panels. + * As we find'em allocate and initialize panel structures for each. + */ + brdp->clk = CD1400_CLK; + brdp->hwid = status; + + ioaddr = brdp->ioaddr2; + banknr = 0; + panelnr = 0; + nxtid = 0; + + for (i = 0; i < STL_MAXPANELS; i++) { + if (brdp->brdtype == BRD_ECHPCI) { + outb(nxtid, brdp->ioctrl); + ioaddr = brdp->ioaddr2; + } + status = inb(ioaddr + ECH_PNLSTATUS); + if ((status & ECH_PNLIDMASK) != nxtid) + break; + panelp = kzalloc(sizeof(struct stlpanel), GFP_KERNEL); + if (!panelp) { + printk("STALLION: failed to allocate memory " + "(size=%Zd)\n", sizeof(struct stlpanel)); + retval = -ENOMEM; + goto err_fr; + } + panelp->magic = STL_PANELMAGIC; + panelp->brdnr = brdp->brdnr; + panelp->panelnr = panelnr; + panelp->iobase = ioaddr; + panelp->pagenr = nxtid; + panelp->hwid = status; + brdp->bnk2panel[banknr] = panelp; + brdp->bnkpageaddr[banknr] = nxtid; + brdp->bnkstataddr[banknr++] = ioaddr + ECH_PNLSTATUS; + + if (status & ECH_PNLXPID) { + panelp->uartp = &stl_sc26198uart; + panelp->isr = stl_sc26198intr; + if (status & ECH_PNL16PORT) { + panelp->nrports = 16; + brdp->bnk2panel[banknr] = panelp; + brdp->bnkpageaddr[banknr] = nxtid; + brdp->bnkstataddr[banknr++] = ioaddr + 4 + + ECH_PNLSTATUS; + } else + panelp->nrports = 8; + } else { + panelp->uartp = &stl_cd1400uart; + panelp->isr = stl_cd1400echintr; + if (status & ECH_PNL16PORT) { + panelp->nrports = 16; + panelp->ackmask = 0x80; + if (brdp->brdtype != BRD_ECHPCI) + ioaddr += EREG_BANKSIZE; + brdp->bnk2panel[banknr] = panelp; + brdp->bnkpageaddr[banknr] = ++nxtid; + brdp->bnkstataddr[banknr++] = ioaddr + + ECH_PNLSTATUS; + } else { + panelp->nrports = 8; + panelp->ackmask = 0xc0; + } + } + + nxtid++; + ioaddr += EREG_BANKSIZE; + brdp->nrports += panelp->nrports; + brdp->panels[panelnr++] = panelp; + if ((brdp->brdtype != BRD_ECHPCI) && + (ioaddr >= (brdp->ioaddr2 + brdp->iosize2))) { + retval = -EINVAL; + goto err_fr; + } + } + + brdp->nrpanels = panelnr; + brdp->nrbnks = banknr; + if (brdp->brdtype == BRD_ECH) + outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl); + + brdp->state |= BRD_FOUND; + if (request_irq(brdp->irq, stl_intr, IRQF_SHARED, name, brdp) != 0) { + printk("STALLION: failed to register interrupt " + "routine for %s irq=%d\n", name, brdp->irq); + retval = -ENODEV; + goto err_fr; + } + + return 0; +err_fr: + stl_cleanup_panels(brdp); + if (brdp->iosize2 > 0) + release_region(brdp->ioaddr2, brdp->iosize2); +err_rel1: + release_region(brdp->ioaddr1, brdp->iosize1); +err: + return retval; +} + +/*****************************************************************************/ + +/* + * Initialize and configure the specified board. + * Scan through all the boards in the configuration and see what we + * can find. Handle EIO and the ECH boards a little differently here + * since the initial search and setup is very different. + */ + +static int __devinit stl_brdinit(struct stlbrd *brdp) +{ + int i, retval; + + pr_debug("stl_brdinit(brdp=%p)\n", brdp); + + switch (brdp->brdtype) { + case BRD_EASYIO: + case BRD_EASYIOPCI: + retval = stl_initeio(brdp); + if (retval) + goto err; + break; + case BRD_ECH: + case BRD_ECHMC: + case BRD_ECHPCI: + case BRD_ECH64PCI: + retval = stl_initech(brdp); + if (retval) + goto err; + break; + default: + printk("STALLION: board=%d is unknown board type=%d\n", + brdp->brdnr, brdp->brdtype); + retval = -ENODEV; + goto err; + } + + if ((brdp->state & BRD_FOUND) == 0) { + printk("STALLION: %s board not found, board=%d io=%x irq=%d\n", + stl_brdnames[brdp->brdtype], brdp->brdnr, + brdp->ioaddr1, brdp->irq); + goto err_free; + } + + for (i = 0; i < STL_MAXPANELS; i++) + if (brdp->panels[i] != NULL) + stl_initports(brdp, brdp->panels[i]); + + printk("STALLION: %s found, board=%d io=%x irq=%d " + "nrpanels=%d nrports=%d\n", stl_brdnames[brdp->brdtype], + brdp->brdnr, brdp->ioaddr1, brdp->irq, brdp->nrpanels, + brdp->nrports); + + return 0; +err_free: + free_irq(brdp->irq, brdp); + + stl_cleanup_panels(brdp); + + release_region(brdp->ioaddr1, brdp->iosize1); + if (brdp->iosize2 > 0) + release_region(brdp->ioaddr2, brdp->iosize2); +err: + return retval; +} + +/*****************************************************************************/ + +/* + * Find the next available board number that is free. + */ + +static int __devinit stl_getbrdnr(void) +{ + unsigned int i; + + for (i = 0; i < STL_MAXBRDS; i++) + if (stl_brds[i] == NULL) { + if (i >= stl_nrbrds) + stl_nrbrds = i + 1; + return i; + } + + return -1; +} + +/*****************************************************************************/ +/* + * We have a Stallion board. Allocate a board structure and + * initialize it. Read its IO and IRQ resources from PCI + * configuration space. + */ + +static int __devinit stl_pciprobe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct stlbrd *brdp; + unsigned int i, brdtype = ent->driver_data; + int brdnr, retval = -ENODEV; + + if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) + goto err; + + retval = pci_enable_device(pdev); + if (retval) + goto err; + brdp = stl_allocbrd(); + if (brdp == NULL) { + retval = -ENOMEM; + goto err; + } + mutex_lock(&stl_brdslock); + brdnr = stl_getbrdnr(); + if (brdnr < 0) { + dev_err(&pdev->dev, "too many boards found, " + "maximum supported %d\n", STL_MAXBRDS); + mutex_unlock(&stl_brdslock); + retval = -ENODEV; + goto err_fr; + } + brdp->brdnr = (unsigned int)brdnr; + stl_brds[brdp->brdnr] = brdp; + mutex_unlock(&stl_brdslock); + + brdp->brdtype = brdtype; + brdp->state |= STL_PROBED; + +/* + * We have all resources from the board, so let's setup the actual + * board structure now. + */ + switch (brdtype) { + case BRD_ECHPCI: + brdp->ioaddr2 = pci_resource_start(pdev, 0); + brdp->ioaddr1 = pci_resource_start(pdev, 1); + break; + case BRD_ECH64PCI: + brdp->ioaddr2 = pci_resource_start(pdev, 2); + brdp->ioaddr1 = pci_resource_start(pdev, 1); + break; + case BRD_EASYIOPCI: + brdp->ioaddr1 = pci_resource_start(pdev, 2); + brdp->ioaddr2 = pci_resource_start(pdev, 1); + break; + default: + dev_err(&pdev->dev, "unknown PCI board type=%u\n", brdtype); + break; + } + + brdp->irq = pdev->irq; + retval = stl_brdinit(brdp); + if (retval) + goto err_null; + + pci_set_drvdata(pdev, brdp); + + for (i = 0; i < brdp->nrports; i++) + tty_register_device(stl_serial, + brdp->brdnr * STL_MAXPORTS + i, &pdev->dev); + + return 0; +err_null: + stl_brds[brdp->brdnr] = NULL; +err_fr: + kfree(brdp); +err: + return retval; +} + +static void __devexit stl_pciremove(struct pci_dev *pdev) +{ + struct stlbrd *brdp = pci_get_drvdata(pdev); + unsigned int i; + + free_irq(brdp->irq, brdp); + + stl_cleanup_panels(brdp); + + release_region(brdp->ioaddr1, brdp->iosize1); + if (brdp->iosize2 > 0) + release_region(brdp->ioaddr2, brdp->iosize2); + + for (i = 0; i < brdp->nrports; i++) + tty_unregister_device(stl_serial, + brdp->brdnr * STL_MAXPORTS + i); + + stl_brds[brdp->brdnr] = NULL; + kfree(brdp); +} + +static struct pci_driver stl_pcidriver = { + .name = "stallion", + .id_table = stl_pcibrds, + .probe = stl_pciprobe, + .remove = __devexit_p(stl_pciremove) +}; + +/*****************************************************************************/ + +/* + * Return the board stats structure to user app. + */ + +static int stl_getbrdstats(combrd_t __user *bp) +{ + combrd_t stl_brdstats; + struct stlbrd *brdp; + struct stlpanel *panelp; + unsigned int i; + + if (copy_from_user(&stl_brdstats, bp, sizeof(combrd_t))) + return -EFAULT; + if (stl_brdstats.brd >= STL_MAXBRDS) + return -ENODEV; + brdp = stl_brds[stl_brdstats.brd]; + if (brdp == NULL) + return -ENODEV; + + memset(&stl_brdstats, 0, sizeof(combrd_t)); + stl_brdstats.brd = brdp->brdnr; + stl_brdstats.type = brdp->brdtype; + stl_brdstats.hwid = brdp->hwid; + stl_brdstats.state = brdp->state; + stl_brdstats.ioaddr = brdp->ioaddr1; + stl_brdstats.ioaddr2 = brdp->ioaddr2; + stl_brdstats.irq = brdp->irq; + stl_brdstats.nrpanels = brdp->nrpanels; + stl_brdstats.nrports = brdp->nrports; + for (i = 0; i < brdp->nrpanels; i++) { + panelp = brdp->panels[i]; + stl_brdstats.panels[i].panel = i; + stl_brdstats.panels[i].hwid = panelp->hwid; + stl_brdstats.panels[i].nrports = panelp->nrports; + } + + return copy_to_user(bp, &stl_brdstats, sizeof(combrd_t)) ? -EFAULT : 0; +} + +/*****************************************************************************/ + +/* + * Resolve the referenced port number into a port struct pointer. + */ + +static struct stlport *stl_getport(int brdnr, int panelnr, int portnr) +{ + struct stlbrd *brdp; + struct stlpanel *panelp; + + if (brdnr < 0 || brdnr >= STL_MAXBRDS) + return NULL; + brdp = stl_brds[brdnr]; + if (brdp == NULL) + return NULL; + if (panelnr < 0 || (unsigned int)panelnr >= brdp->nrpanels) + return NULL; + panelp = brdp->panels[panelnr]; + if (panelp == NULL) + return NULL; + if (portnr < 0 || (unsigned int)portnr >= panelp->nrports) + return NULL; + return panelp->ports[portnr]; +} + +/*****************************************************************************/ + +/* + * Return the port stats structure to user app. A NULL port struct + * pointer passed in means that we need to find out from the app + * what port to get stats for (used through board control device). + */ + +static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp) +{ + comstats_t stl_comstats; + unsigned char *head, *tail; + unsigned long flags; + + if (!portp) { + if (copy_from_user(&stl_comstats, cp, sizeof(comstats_t))) + return -EFAULT; + portp = stl_getport(stl_comstats.brd, stl_comstats.panel, + stl_comstats.port); + if (portp == NULL) + return -ENODEV; + } + + mutex_lock(&portp->port.mutex); + portp->stats.state = portp->istate; + portp->stats.flags = portp->port.flags; + portp->stats.hwid = portp->hwid; + + portp->stats.ttystate = 0; + portp->stats.cflags = 0; + portp->stats.iflags = 0; + portp->stats.oflags = 0; + portp->stats.lflags = 0; + portp->stats.rxbuffered = 0; + + spin_lock_irqsave(&stallion_lock, flags); + if (tty != NULL && portp->port.tty == tty) { + portp->stats.ttystate = tty->flags; + /* No longer available as a statistic */ + portp->stats.rxbuffered = 1; /*tty->flip.count; */ + if (tty->termios != NULL) { + portp->stats.cflags = tty->termios->c_cflag; + portp->stats.iflags = tty->termios->c_iflag; + portp->stats.oflags = tty->termios->c_oflag; + portp->stats.lflags = tty->termios->c_lflag; + } + } + spin_unlock_irqrestore(&stallion_lock, flags); + + head = portp->tx.head; + tail = portp->tx.tail; + portp->stats.txbuffered = (head >= tail) ? (head - tail) : + (STL_TXBUFSIZE - (tail - head)); + + portp->stats.signals = (unsigned long) stl_getsignals(portp); + mutex_unlock(&portp->port.mutex); + + return copy_to_user(cp, &portp->stats, + sizeof(comstats_t)) ? -EFAULT : 0; +} + +/*****************************************************************************/ + +/* + * Clear the port stats structure. We also return it zeroed out... + */ + +static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp) +{ + comstats_t stl_comstats; + + if (!portp) { + if (copy_from_user(&stl_comstats, cp, sizeof(comstats_t))) + return -EFAULT; + portp = stl_getport(stl_comstats.brd, stl_comstats.panel, + stl_comstats.port); + if (portp == NULL) + return -ENODEV; + } + + mutex_lock(&portp->port.mutex); + memset(&portp->stats, 0, sizeof(comstats_t)); + portp->stats.brd = portp->brdnr; + portp->stats.panel = portp->panelnr; + portp->stats.port = portp->portnr; + mutex_unlock(&portp->port.mutex); + return copy_to_user(cp, &portp->stats, + sizeof(comstats_t)) ? -EFAULT : 0; +} + +/*****************************************************************************/ + +/* + * Return the entire driver ports structure to a user app. + */ + +static int stl_getportstruct(struct stlport __user *arg) +{ + struct stlport stl_dummyport; + struct stlport *portp; + + if (copy_from_user(&stl_dummyport, arg, sizeof(struct stlport))) + return -EFAULT; + portp = stl_getport(stl_dummyport.brdnr, stl_dummyport.panelnr, + stl_dummyport.portnr); + if (!portp) + return -ENODEV; + return copy_to_user(arg, portp, sizeof(struct stlport)) ? -EFAULT : 0; +} + +/*****************************************************************************/ + +/* + * Return the entire driver board structure to a user app. + */ + +static int stl_getbrdstruct(struct stlbrd __user *arg) +{ + struct stlbrd stl_dummybrd; + struct stlbrd *brdp; + + if (copy_from_user(&stl_dummybrd, arg, sizeof(struct stlbrd))) + return -EFAULT; + if (stl_dummybrd.brdnr >= STL_MAXBRDS) + return -ENODEV; + brdp = stl_brds[stl_dummybrd.brdnr]; + if (!brdp) + return -ENODEV; + return copy_to_user(arg, brdp, sizeof(struct stlbrd)) ? -EFAULT : 0; +} + +/*****************************************************************************/ + +/* + * The "staliomem" device is also required to do some special operations + * on the board and/or ports. In this driver it is mostly used for stats + * collection. + */ + +static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) +{ + int brdnr, rc; + void __user *argp = (void __user *)arg; + + pr_debug("stl_memioctl(fp=%p,cmd=%x,arg=%lx)\n", fp, cmd,arg); + + brdnr = iminor(fp->f_dentry->d_inode); + if (brdnr >= STL_MAXBRDS) + return -ENODEV; + rc = 0; + + switch (cmd) { + case COM_GETPORTSTATS: + rc = stl_getportstats(NULL, NULL, argp); + break; + case COM_CLRPORTSTATS: + rc = stl_clrportstats(NULL, argp); + break; + case COM_GETBRDSTATS: + rc = stl_getbrdstats(argp); + break; + case COM_READPORT: + rc = stl_getportstruct(argp); + break; + case COM_READBOARD: + rc = stl_getbrdstruct(argp); + break; + default: + rc = -ENOIOCTLCMD; + break; + } + return rc; +} + +static const struct tty_operations stl_ops = { + .open = stl_open, + .close = stl_close, + .write = stl_write, + .put_char = stl_putchar, + .flush_chars = stl_flushchars, + .write_room = stl_writeroom, + .chars_in_buffer = stl_charsinbuffer, + .ioctl = stl_ioctl, + .set_termios = stl_settermios, + .throttle = stl_throttle, + .unthrottle = stl_unthrottle, + .stop = stl_stop, + .start = stl_start, + .hangup = stl_hangup, + .flush_buffer = stl_flushbuffer, + .break_ctl = stl_breakctl, + .wait_until_sent = stl_waituntilsent, + .send_xchar = stl_sendxchar, + .tiocmget = stl_tiocmget, + .tiocmset = stl_tiocmset, + .proc_fops = &stl_proc_fops, +}; + +static const struct tty_port_operations stl_port_ops = { + .carrier_raised = stl_carrier_raised, + .dtr_rts = stl_dtr_rts, + .activate = stl_activate, + .shutdown = stl_shutdown, +}; + +/*****************************************************************************/ +/* CD1400 HARDWARE FUNCTIONS */ +/*****************************************************************************/ + +/* + * These functions get/set/update the registers of the cd1400 UARTs. + * Access to the cd1400 registers is via an address/data io port pair. + * (Maybe should make this inline...) + */ + +static int stl_cd1400getreg(struct stlport *portp, int regnr) +{ + outb((regnr + portp->uartaddr), portp->ioaddr); + return inb(portp->ioaddr + EREG_DATA); +} + +static void stl_cd1400setreg(struct stlport *portp, int regnr, int value) +{ + outb(regnr + portp->uartaddr, portp->ioaddr); + outb(value, portp->ioaddr + EREG_DATA); +} + +static int stl_cd1400updatereg(struct stlport *portp, int regnr, int value) +{ + outb(regnr + portp->uartaddr, portp->ioaddr); + if (inb(portp->ioaddr + EREG_DATA) != value) { + outb(value, portp->ioaddr + EREG_DATA); + return 1; + } + return 0; +} + +/*****************************************************************************/ + +/* + * Inbitialize the UARTs in a panel. We don't care what sort of board + * these ports are on - since the port io registers are almost + * identical when dealing with ports. + */ + +static int stl_cd1400panelinit(struct stlbrd *brdp, struct stlpanel *panelp) +{ + unsigned int gfrcr; + int chipmask, i, j; + int nrchips, uartaddr, ioaddr; + unsigned long flags; + + pr_debug("stl_panelinit(brdp=%p,panelp=%p)\n", brdp, panelp); + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(panelp->brdnr, panelp->pagenr); + +/* + * Check that each chip is present and started up OK. + */ + chipmask = 0; + nrchips = panelp->nrports / CD1400_PORTS; + for (i = 0; i < nrchips; i++) { + if (brdp->brdtype == BRD_ECHPCI) { + outb((panelp->pagenr + (i >> 1)), brdp->ioctrl); + ioaddr = panelp->iobase; + } else + ioaddr = panelp->iobase + (EREG_BANKSIZE * (i >> 1)); + uartaddr = (i & 0x01) ? 0x080 : 0; + outb((GFRCR + uartaddr), ioaddr); + outb(0, (ioaddr + EREG_DATA)); + outb((CCR + uartaddr), ioaddr); + outb(CCR_RESETFULL, (ioaddr + EREG_DATA)); + outb(CCR_RESETFULL, (ioaddr + EREG_DATA)); + outb((GFRCR + uartaddr), ioaddr); + for (j = 0; j < CCR_MAXWAIT; j++) + if ((gfrcr = inb(ioaddr + EREG_DATA)) != 0) + break; + + if ((j >= CCR_MAXWAIT) || (gfrcr < 0x40) || (gfrcr > 0x60)) { + printk("STALLION: cd1400 not responding, " + "brd=%d panel=%d chip=%d\n", + panelp->brdnr, panelp->panelnr, i); + continue; + } + chipmask |= (0x1 << i); + outb((PPR + uartaddr), ioaddr); + outb(PPR_SCALAR, (ioaddr + EREG_DATA)); + } + + BRDDISABLE(panelp->brdnr); + spin_unlock_irqrestore(&brd_lock, flags); + return chipmask; +} + +/*****************************************************************************/ + +/* + * Initialize hardware specific port registers. + */ + +static void stl_cd1400portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp) +{ + unsigned long flags; + pr_debug("stl_cd1400portinit(brdp=%p,panelp=%p,portp=%p)\n", brdp, + panelp, portp); + + if ((brdp == NULL) || (panelp == NULL) || + (portp == NULL)) + return; + + spin_lock_irqsave(&brd_lock, flags); + portp->ioaddr = panelp->iobase + (((brdp->brdtype == BRD_ECHPCI) || + (portp->portnr < 8)) ? 0 : EREG_BANKSIZE); + portp->uartaddr = (portp->portnr & 0x04) << 5; + portp->pagenr = panelp->pagenr + (portp->portnr >> 3); + + BRDENABLE(portp->brdnr, portp->pagenr); + stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); + stl_cd1400setreg(portp, LIVR, (portp->portnr << 3)); + portp->hwid = stl_cd1400getreg(portp, GFRCR); + BRDDISABLE(portp->brdnr); + spin_unlock_irqrestore(&brd_lock, flags); +} + +/*****************************************************************************/ + +/* + * Wait for the command register to be ready. We will poll this, + * since it won't usually take too long to be ready. + */ + +static void stl_cd1400ccrwait(struct stlport *portp) +{ + int i; + + for (i = 0; i < CCR_MAXWAIT; i++) + if (stl_cd1400getreg(portp, CCR) == 0) + return; + + printk("STALLION: cd1400 not responding, port=%d panel=%d brd=%d\n", + portp->portnr, portp->panelnr, portp->brdnr); +} + +/*****************************************************************************/ + +/* + * Set up the cd1400 registers for a port based on the termios port + * settings. + */ + +static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp) +{ + struct stlbrd *brdp; + unsigned long flags; + unsigned int clkdiv, baudrate; + unsigned char cor1, cor2, cor3; + unsigned char cor4, cor5, ccr; + unsigned char srer, sreron, sreroff; + unsigned char mcor1, mcor2, rtpr; + unsigned char clk, div; + + cor1 = 0; + cor2 = 0; + cor3 = 0; + cor4 = 0; + cor5 = 0; + ccr = 0; + rtpr = 0; + clk = 0; + div = 0; + mcor1 = 0; + mcor2 = 0; + sreron = 0; + sreroff = 0; + + brdp = stl_brds[portp->brdnr]; + if (brdp == NULL) + return; + +/* + * Set up the RX char ignore mask with those RX error types we + * can ignore. We can get the cd1400 to help us out a little here, + * it will ignore parity errors and breaks for us. + */ + portp->rxignoremsk = 0; + if (tiosp->c_iflag & IGNPAR) { + portp->rxignoremsk |= (ST_PARITY | ST_FRAMING | ST_OVERRUN); + cor1 |= COR1_PARIGNORE; + } + if (tiosp->c_iflag & IGNBRK) { + portp->rxignoremsk |= ST_BREAK; + cor4 |= COR4_IGNBRK; + } + + portp->rxmarkmsk = ST_OVERRUN; + if (tiosp->c_iflag & (INPCK | PARMRK)) + portp->rxmarkmsk |= (ST_PARITY | ST_FRAMING); + if (tiosp->c_iflag & BRKINT) + portp->rxmarkmsk |= ST_BREAK; + +/* + * Go through the char size, parity and stop bits and set all the + * option register appropriately. + */ + switch (tiosp->c_cflag & CSIZE) { + case CS5: + cor1 |= COR1_CHL5; + break; + case CS6: + cor1 |= COR1_CHL6; + break; + case CS7: + cor1 |= COR1_CHL7; + break; + default: + cor1 |= COR1_CHL8; + break; + } + + if (tiosp->c_cflag & CSTOPB) + cor1 |= COR1_STOP2; + else + cor1 |= COR1_STOP1; + + if (tiosp->c_cflag & PARENB) { + if (tiosp->c_cflag & PARODD) + cor1 |= (COR1_PARENB | COR1_PARODD); + else + cor1 |= (COR1_PARENB | COR1_PAREVEN); + } else { + cor1 |= COR1_PARNONE; + } + +/* + * Set the RX FIFO threshold at 6 chars. This gives a bit of breathing + * space for hardware flow control and the like. This should be set to + * VMIN. Also here we will set the RX data timeout to 10ms - this should + * really be based on VTIME. + */ + cor3 |= FIFO_RXTHRESHOLD; + rtpr = 2; + +/* + * Calculate the baud rate timers. For now we will just assume that + * the input and output baud are the same. Could have used a baud + * table here, but this way we can generate virtually any baud rate + * we like! + */ + baudrate = tiosp->c_cflag & CBAUD; + if (baudrate & CBAUDEX) { + baudrate &= ~CBAUDEX; + if ((baudrate < 1) || (baudrate > 4)) + tiosp->c_cflag &= ~CBAUDEX; + else + baudrate += 15; + } + baudrate = stl_baudrates[baudrate]; + if ((tiosp->c_cflag & CBAUD) == B38400) { + if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + baudrate = 57600; + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + baudrate = 115200; + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + baudrate = 230400; + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + baudrate = 460800; + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) + baudrate = (portp->baud_base / portp->custom_divisor); + } + if (baudrate > STL_CD1400MAXBAUD) + baudrate = STL_CD1400MAXBAUD; + + if (baudrate > 0) { + for (clk = 0; clk < CD1400_NUMCLKS; clk++) { + clkdiv = (portp->clk / stl_cd1400clkdivs[clk]) / baudrate; + if (clkdiv < 0x100) + break; + } + div = (unsigned char) clkdiv; + } + +/* + * Check what form of modem signaling is required and set it up. + */ + if ((tiosp->c_cflag & CLOCAL) == 0) { + mcor1 |= MCOR1_DCD; + mcor2 |= MCOR2_DCD; + sreron |= SRER_MODEM; + portp->port.flags |= ASYNC_CHECK_CD; + } else + portp->port.flags &= ~ASYNC_CHECK_CD; + +/* + * Setup cd1400 enhanced modes if we can. In particular we want to + * handle as much of the flow control as possible automatically. As + * well as saving a few CPU cycles it will also greatly improve flow + * control reliability. + */ + if (tiosp->c_iflag & IXON) { + cor2 |= COR2_TXIBE; + cor3 |= COR3_SCD12; + if (tiosp->c_iflag & IXANY) + cor2 |= COR2_IXM; + } + + if (tiosp->c_cflag & CRTSCTS) { + cor2 |= COR2_CTSAE; + mcor1 |= FIFO_RTSTHRESHOLD; + } + +/* + * All cd1400 register values calculated so go through and set + * them all up. + */ + + pr_debug("SETPORT: portnr=%d panelnr=%d brdnr=%d\n", + portp->portnr, portp->panelnr, portp->brdnr); + pr_debug(" cor1=%x cor2=%x cor3=%x cor4=%x cor5=%x\n", + cor1, cor2, cor3, cor4, cor5); + pr_debug(" mcor1=%x mcor2=%x rtpr=%x sreron=%x sreroff=%x\n", + mcor1, mcor2, rtpr, sreron, sreroff); + pr_debug(" tcor=%x tbpr=%x rcor=%x rbpr=%x\n", clk, div, clk, div); + pr_debug(" schr1=%x schr2=%x schr3=%x schr4=%x\n", + tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP], + tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + stl_cd1400setreg(portp, CAR, (portp->portnr & 0x3)); + srer = stl_cd1400getreg(portp, SRER); + stl_cd1400setreg(portp, SRER, 0); + if (stl_cd1400updatereg(portp, COR1, cor1)) + ccr = 1; + if (stl_cd1400updatereg(portp, COR2, cor2)) + ccr = 1; + if (stl_cd1400updatereg(portp, COR3, cor3)) + ccr = 1; + if (ccr) { + stl_cd1400ccrwait(portp); + stl_cd1400setreg(portp, CCR, CCR_CORCHANGE); + } + stl_cd1400setreg(portp, COR4, cor4); + stl_cd1400setreg(portp, COR5, cor5); + stl_cd1400setreg(portp, MCOR1, mcor1); + stl_cd1400setreg(portp, MCOR2, mcor2); + if (baudrate > 0) { + stl_cd1400setreg(portp, TCOR, clk); + stl_cd1400setreg(portp, TBPR, div); + stl_cd1400setreg(portp, RCOR, clk); + stl_cd1400setreg(portp, RBPR, div); + } + stl_cd1400setreg(portp, SCHR1, tiosp->c_cc[VSTART]); + stl_cd1400setreg(portp, SCHR2, tiosp->c_cc[VSTOP]); + stl_cd1400setreg(portp, SCHR3, tiosp->c_cc[VSTART]); + stl_cd1400setreg(portp, SCHR4, tiosp->c_cc[VSTOP]); + stl_cd1400setreg(portp, RTPR, rtpr); + mcor1 = stl_cd1400getreg(portp, MSVR1); + if (mcor1 & MSVR1_DCD) + portp->sigs |= TIOCM_CD; + else + portp->sigs &= ~TIOCM_CD; + stl_cd1400setreg(portp, SRER, ((srer & ~sreroff) | sreron)); + BRDDISABLE(portp->brdnr); + spin_unlock_irqrestore(&brd_lock, flags); +} + +/*****************************************************************************/ + +/* + * Set the state of the DTR and RTS signals. + */ + +static void stl_cd1400setsignals(struct stlport *portp, int dtr, int rts) +{ + unsigned char msvr1, msvr2; + unsigned long flags; + + pr_debug("stl_cd1400setsignals(portp=%p,dtr=%d,rts=%d)\n", + portp, dtr, rts); + + msvr1 = 0; + msvr2 = 0; + if (dtr > 0) + msvr1 = MSVR1_DTR; + if (rts > 0) + msvr2 = MSVR2_RTS; + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); + if (rts >= 0) + stl_cd1400setreg(portp, MSVR2, msvr2); + if (dtr >= 0) + stl_cd1400setreg(portp, MSVR1, msvr1); + BRDDISABLE(portp->brdnr); + spin_unlock_irqrestore(&brd_lock, flags); +} + +/*****************************************************************************/ + +/* + * Return the state of the signals. + */ + +static int stl_cd1400getsignals(struct stlport *portp) +{ + unsigned char msvr1, msvr2; + unsigned long flags; + int sigs; + + pr_debug("stl_cd1400getsignals(portp=%p)\n", portp); + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); + msvr1 = stl_cd1400getreg(portp, MSVR1); + msvr2 = stl_cd1400getreg(portp, MSVR2); + BRDDISABLE(portp->brdnr); + spin_unlock_irqrestore(&brd_lock, flags); + + sigs = 0; + sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0; + sigs |= (msvr1 & MSVR1_CTS) ? TIOCM_CTS : 0; + sigs |= (msvr1 & MSVR1_DTR) ? TIOCM_DTR : 0; + sigs |= (msvr2 & MSVR2_RTS) ? TIOCM_RTS : 0; +#if 0 + sigs |= (msvr1 & MSVR1_RI) ? TIOCM_RI : 0; + sigs |= (msvr1 & MSVR1_DSR) ? TIOCM_DSR : 0; +#else + sigs |= TIOCM_DSR; +#endif + return sigs; +} + +/*****************************************************************************/ + +/* + * Enable/Disable the Transmitter and/or Receiver. + */ + +static void stl_cd1400enablerxtx(struct stlport *portp, int rx, int tx) +{ + unsigned char ccr; + unsigned long flags; + + pr_debug("stl_cd1400enablerxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx); + + ccr = 0; + + if (tx == 0) + ccr |= CCR_TXDISABLE; + else if (tx > 0) + ccr |= CCR_TXENABLE; + if (rx == 0) + ccr |= CCR_RXDISABLE; + else if (rx > 0) + ccr |= CCR_RXENABLE; + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); + stl_cd1400ccrwait(portp); + stl_cd1400setreg(portp, CCR, ccr); + stl_cd1400ccrwait(portp); + BRDDISABLE(portp->brdnr); + spin_unlock_irqrestore(&brd_lock, flags); +} + +/*****************************************************************************/ + +/* + * Start/stop the Transmitter and/or Receiver. + */ + +static void stl_cd1400startrxtx(struct stlport *portp, int rx, int tx) +{ + unsigned char sreron, sreroff; + unsigned long flags; + + pr_debug("stl_cd1400startrxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx); + + sreron = 0; + sreroff = 0; + if (tx == 0) + sreroff |= (SRER_TXDATA | SRER_TXEMPTY); + else if (tx == 1) + sreron |= SRER_TXDATA; + else if (tx >= 2) + sreron |= SRER_TXEMPTY; + if (rx == 0) + sreroff |= SRER_RXDATA; + else if (rx > 0) + sreron |= SRER_RXDATA; + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); + stl_cd1400setreg(portp, SRER, + ((stl_cd1400getreg(portp, SRER) & ~sreroff) | sreron)); + BRDDISABLE(portp->brdnr); + if (tx > 0) + set_bit(ASYI_TXBUSY, &portp->istate); + spin_unlock_irqrestore(&brd_lock, flags); +} + +/*****************************************************************************/ + +/* + * Disable all interrupts from this port. + */ + +static void stl_cd1400disableintrs(struct stlport *portp) +{ + unsigned long flags; + + pr_debug("stl_cd1400disableintrs(portp=%p)\n", portp); + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); + stl_cd1400setreg(portp, SRER, 0); + BRDDISABLE(portp->brdnr); + spin_unlock_irqrestore(&brd_lock, flags); +} + +/*****************************************************************************/ + +static void stl_cd1400sendbreak(struct stlport *portp, int len) +{ + unsigned long flags; + + pr_debug("stl_cd1400sendbreak(portp=%p,len=%d)\n", portp, len); + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); + stl_cd1400setreg(portp, SRER, + ((stl_cd1400getreg(portp, SRER) & ~SRER_TXDATA) | + SRER_TXEMPTY)); + BRDDISABLE(portp->brdnr); + portp->brklen = len; + if (len == 1) + portp->stats.txbreaks++; + spin_unlock_irqrestore(&brd_lock, flags); +} + +/*****************************************************************************/ + +/* + * Take flow control actions... + */ + +static void stl_cd1400flowctrl(struct stlport *portp, int state) +{ + struct tty_struct *tty; + unsigned long flags; + + pr_debug("stl_cd1400flowctrl(portp=%p,state=%x)\n", portp, state); + + if (portp == NULL) + return; + tty = tty_port_tty_get(&portp->port); + if (tty == NULL) + return; + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); + + if (state) { + if (tty->termios->c_iflag & IXOFF) { + stl_cd1400ccrwait(portp); + stl_cd1400setreg(portp, CCR, CCR_SENDSCHR1); + portp->stats.rxxon++; + stl_cd1400ccrwait(portp); + } +/* + * Question: should we return RTS to what it was before? It may + * have been set by an ioctl... Suppose not, since if you have + * hardware flow control set then it is pretty silly to go and + * set the RTS line by hand. + */ + if (tty->termios->c_cflag & CRTSCTS) { + stl_cd1400setreg(portp, MCOR1, + (stl_cd1400getreg(portp, MCOR1) | + FIFO_RTSTHRESHOLD)); + stl_cd1400setreg(portp, MSVR2, MSVR2_RTS); + portp->stats.rxrtson++; + } + } else { + if (tty->termios->c_iflag & IXOFF) { + stl_cd1400ccrwait(portp); + stl_cd1400setreg(portp, CCR, CCR_SENDSCHR2); + portp->stats.rxxoff++; + stl_cd1400ccrwait(portp); + } + if (tty->termios->c_cflag & CRTSCTS) { + stl_cd1400setreg(portp, MCOR1, + (stl_cd1400getreg(portp, MCOR1) & 0xf0)); + stl_cd1400setreg(portp, MSVR2, 0); + portp->stats.rxrtsoff++; + } + } + + BRDDISABLE(portp->brdnr); + spin_unlock_irqrestore(&brd_lock, flags); + tty_kref_put(tty); +} + +/*****************************************************************************/ + +/* + * Send a flow control character... + */ + +static void stl_cd1400sendflow(struct stlport *portp, int state) +{ + struct tty_struct *tty; + unsigned long flags; + + pr_debug("stl_cd1400sendflow(portp=%p,state=%x)\n", portp, state); + + if (portp == NULL) + return; + tty = tty_port_tty_get(&portp->port); + if (tty == NULL) + return; + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); + if (state) { + stl_cd1400ccrwait(portp); + stl_cd1400setreg(portp, CCR, CCR_SENDSCHR1); + portp->stats.rxxon++; + stl_cd1400ccrwait(portp); + } else { + stl_cd1400ccrwait(portp); + stl_cd1400setreg(portp, CCR, CCR_SENDSCHR2); + portp->stats.rxxoff++; + stl_cd1400ccrwait(portp); + } + BRDDISABLE(portp->brdnr); + spin_unlock_irqrestore(&brd_lock, flags); + tty_kref_put(tty); +} + +/*****************************************************************************/ + +static void stl_cd1400flush(struct stlport *portp) +{ + unsigned long flags; + + pr_debug("stl_cd1400flush(portp=%p)\n", portp); + + if (portp == NULL) + return; + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); + stl_cd1400ccrwait(portp); + stl_cd1400setreg(portp, CCR, CCR_TXFLUSHFIFO); + stl_cd1400ccrwait(portp); + portp->tx.tail = portp->tx.head; + BRDDISABLE(portp->brdnr); + spin_unlock_irqrestore(&brd_lock, flags); +} + +/*****************************************************************************/ + +/* + * Return the current state of data flow on this port. This is only + * really interesting when determining if data has fully completed + * transmission or not... This is easy for the cd1400, it accurately + * maintains the busy port flag. + */ + +static int stl_cd1400datastate(struct stlport *portp) +{ + pr_debug("stl_cd1400datastate(portp=%p)\n", portp); + + if (portp == NULL) + return 0; + + return test_bit(ASYI_TXBUSY, &portp->istate) ? 1 : 0; +} + +/*****************************************************************************/ + +/* + * Interrupt service routine for cd1400 EasyIO boards. + */ + +static void stl_cd1400eiointr(struct stlpanel *panelp, unsigned int iobase) +{ + unsigned char svrtype; + + pr_debug("stl_cd1400eiointr(panelp=%p,iobase=%x)\n", panelp, iobase); + + spin_lock(&brd_lock); + outb(SVRR, iobase); + svrtype = inb(iobase + EREG_DATA); + if (panelp->nrports > 4) { + outb((SVRR + 0x80), iobase); + svrtype |= inb(iobase + EREG_DATA); + } + + if (svrtype & SVRR_RX) + stl_cd1400rxisr(panelp, iobase); + else if (svrtype & SVRR_TX) + stl_cd1400txisr(panelp, iobase); + else if (svrtype & SVRR_MDM) + stl_cd1400mdmisr(panelp, iobase); + + spin_unlock(&brd_lock); +} + +/*****************************************************************************/ + +/* + * Interrupt service routine for cd1400 panels. + */ + +static void stl_cd1400echintr(struct stlpanel *panelp, unsigned int iobase) +{ + unsigned char svrtype; + + pr_debug("stl_cd1400echintr(panelp=%p,iobase=%x)\n", panelp, iobase); + + outb(SVRR, iobase); + svrtype = inb(iobase + EREG_DATA); + outb((SVRR + 0x80), iobase); + svrtype |= inb(iobase + EREG_DATA); + if (svrtype & SVRR_RX) + stl_cd1400rxisr(panelp, iobase); + else if (svrtype & SVRR_TX) + stl_cd1400txisr(panelp, iobase); + else if (svrtype & SVRR_MDM) + stl_cd1400mdmisr(panelp, iobase); +} + + +/*****************************************************************************/ + +/* + * Unfortunately we need to handle breaks in the TX data stream, since + * this is the only way to generate them on the cd1400. + */ + +static int stl_cd1400breakisr(struct stlport *portp, int ioaddr) +{ + if (portp->brklen == 1) { + outb((COR2 + portp->uartaddr), ioaddr); + outb((inb(ioaddr + EREG_DATA) | COR2_ETC), + (ioaddr + EREG_DATA)); + outb((TDR + portp->uartaddr), ioaddr); + outb(ETC_CMD, (ioaddr + EREG_DATA)); + outb(ETC_STARTBREAK, (ioaddr + EREG_DATA)); + outb((SRER + portp->uartaddr), ioaddr); + outb((inb(ioaddr + EREG_DATA) & ~(SRER_TXDATA | SRER_TXEMPTY)), + (ioaddr + EREG_DATA)); + return 1; + } else if (portp->brklen > 1) { + outb((TDR + portp->uartaddr), ioaddr); + outb(ETC_CMD, (ioaddr + EREG_DATA)); + outb(ETC_STOPBREAK, (ioaddr + EREG_DATA)); + portp->brklen = -1; + return 1; + } else { + outb((COR2 + portp->uartaddr), ioaddr); + outb((inb(ioaddr + EREG_DATA) & ~COR2_ETC), + (ioaddr + EREG_DATA)); + portp->brklen = 0; + } + return 0; +} + +/*****************************************************************************/ + +/* + * Transmit interrupt handler. This has gotta be fast! Handling TX + * chars is pretty simple, stuff as many as possible from the TX buffer + * into the cd1400 FIFO. Must also handle TX breaks here, since they + * are embedded as commands in the data stream. Oh no, had to use a goto! + * This could be optimized more, will do when I get time... + * In practice it is possible that interrupts are enabled but that the + * port has been hung up. Need to handle not having any TX buffer here, + * this is done by using the side effect that head and tail will also + * be NULL if the buffer has been freed. + */ + +static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr) +{ + struct stlport *portp; + int len, stlen; + char *head, *tail; + unsigned char ioack, srer; + struct tty_struct *tty; + + pr_debug("stl_cd1400txisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr); + + ioack = inb(ioaddr + EREG_TXACK); + if (((ioack & panelp->ackmask) != 0) || + ((ioack & ACK_TYPMASK) != ACK_TYPTX)) { + printk("STALLION: bad TX interrupt ack value=%x\n", ioack); + return; + } + portp = panelp->ports[(ioack >> 3)]; + +/* + * Unfortunately we need to handle breaks in the data stream, since + * this is the only way to generate them on the cd1400. Do it now if + * a break is to be sent. + */ + if (portp->brklen != 0) + if (stl_cd1400breakisr(portp, ioaddr)) + goto stl_txalldone; + + head = portp->tx.head; + tail = portp->tx.tail; + len = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head)); + if ((len == 0) || ((len < STL_TXBUFLOW) && + (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { + set_bit(ASYI_TXLOW, &portp->istate); + tty = tty_port_tty_get(&portp->port); + if (tty) { + tty_wakeup(tty); + tty_kref_put(tty); + } + } + + if (len == 0) { + outb((SRER + portp->uartaddr), ioaddr); + srer = inb(ioaddr + EREG_DATA); + if (srer & SRER_TXDATA) { + srer = (srer & ~SRER_TXDATA) | SRER_TXEMPTY; + } else { + srer &= ~(SRER_TXDATA | SRER_TXEMPTY); + clear_bit(ASYI_TXBUSY, &portp->istate); + } + outb(srer, (ioaddr + EREG_DATA)); + } else { + len = min(len, CD1400_TXFIFOSIZE); + portp->stats.txtotal += len; + stlen = min_t(unsigned int, len, + (portp->tx.buf + STL_TXBUFSIZE) - tail); + outb((TDR + portp->uartaddr), ioaddr); + outsb((ioaddr + EREG_DATA), tail, stlen); + len -= stlen; + tail += stlen; + if (tail >= (portp->tx.buf + STL_TXBUFSIZE)) + tail = portp->tx.buf; + if (len > 0) { + outsb((ioaddr + EREG_DATA), tail, len); + tail += len; + } + portp->tx.tail = tail; + } + +stl_txalldone: + outb((EOSRR + portp->uartaddr), ioaddr); + outb(0, (ioaddr + EREG_DATA)); +} + +/*****************************************************************************/ + +/* + * Receive character interrupt handler. Determine if we have good chars + * or bad chars and then process appropriately. Good chars are easy + * just shove the lot into the RX buffer and set all status byte to 0. + * If a bad RX char then process as required. This routine needs to be + * fast! In practice it is possible that we get an interrupt on a port + * that is closed. This can happen on hangups - since they completely + * shutdown a port not in user context. Need to handle this case. + */ + +static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr) +{ + struct stlport *portp; + struct tty_struct *tty; + unsigned int ioack, len, buflen; + unsigned char status; + char ch; + + pr_debug("stl_cd1400rxisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr); + + ioack = inb(ioaddr + EREG_RXACK); + if ((ioack & panelp->ackmask) != 0) { + printk("STALLION: bad RX interrupt ack value=%x\n", ioack); + return; + } + portp = panelp->ports[(ioack >> 3)]; + tty = tty_port_tty_get(&portp->port); + + if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) { + outb((RDCR + portp->uartaddr), ioaddr); + len = inb(ioaddr + EREG_DATA); + if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) { + len = min_t(unsigned int, len, sizeof(stl_unwanted)); + outb((RDSR + portp->uartaddr), ioaddr); + insb((ioaddr + EREG_DATA), &stl_unwanted[0], len); + portp->stats.rxlost += len; + portp->stats.rxtotal += len; + } else { + len = min(len, buflen); + if (len > 0) { + unsigned char *ptr; + outb((RDSR + portp->uartaddr), ioaddr); + tty_prepare_flip_string(tty, &ptr, len); + insb((ioaddr + EREG_DATA), ptr, len); + tty_schedule_flip(tty); + portp->stats.rxtotal += len; + } + } + } else if ((ioack & ACK_TYPMASK) == ACK_TYPRXBAD) { + outb((RDSR + portp->uartaddr), ioaddr); + status = inb(ioaddr + EREG_DATA); + ch = inb(ioaddr + EREG_DATA); + if (status & ST_PARITY) + portp->stats.rxparity++; + if (status & ST_FRAMING) + portp->stats.rxframing++; + if (status & ST_OVERRUN) + portp->stats.rxoverrun++; + if (status & ST_BREAK) + portp->stats.rxbreaks++; + if (status & ST_SCHARMASK) { + if ((status & ST_SCHARMASK) == ST_SCHAR1) + portp->stats.txxon++; + if ((status & ST_SCHARMASK) == ST_SCHAR2) + portp->stats.txxoff++; + goto stl_rxalldone; + } + if (tty != NULL && (portp->rxignoremsk & status) == 0) { + if (portp->rxmarkmsk & status) { + if (status & ST_BREAK) { + status = TTY_BREAK; + if (portp->port.flags & ASYNC_SAK) { + do_SAK(tty); + BRDENABLE(portp->brdnr, portp->pagenr); + } + } else if (status & ST_PARITY) + status = TTY_PARITY; + else if (status & ST_FRAMING) + status = TTY_FRAME; + else if(status & ST_OVERRUN) + status = TTY_OVERRUN; + else + status = 0; + } else + status = 0; + tty_insert_flip_char(tty, ch, status); + tty_schedule_flip(tty); + } + } else { + printk("STALLION: bad RX interrupt ack value=%x\n", ioack); + tty_kref_put(tty); + return; + } + +stl_rxalldone: + tty_kref_put(tty); + outb((EOSRR + portp->uartaddr), ioaddr); + outb(0, (ioaddr + EREG_DATA)); +} + +/*****************************************************************************/ + +/* + * Modem interrupt handler. The is called when the modem signal line + * (DCD) has changed state. Leave most of the work to the off-level + * processing routine. + */ + +static void stl_cd1400mdmisr(struct stlpanel *panelp, int ioaddr) +{ + struct stlport *portp; + unsigned int ioack; + unsigned char misr; + + pr_debug("stl_cd1400mdmisr(panelp=%p)\n", panelp); + + ioack = inb(ioaddr + EREG_MDACK); + if (((ioack & panelp->ackmask) != 0) || + ((ioack & ACK_TYPMASK) != ACK_TYPMDM)) { + printk("STALLION: bad MODEM interrupt ack value=%x\n", ioack); + return; + } + portp = panelp->ports[(ioack >> 3)]; + + outb((MISR + portp->uartaddr), ioaddr); + misr = inb(ioaddr + EREG_DATA); + if (misr & MISR_DCD) { + stl_cd_change(portp); + portp->stats.modem++; + } + + outb((EOSRR + portp->uartaddr), ioaddr); + outb(0, (ioaddr + EREG_DATA)); +} + +/*****************************************************************************/ +/* SC26198 HARDWARE FUNCTIONS */ +/*****************************************************************************/ + +/* + * These functions get/set/update the registers of the sc26198 UARTs. + * Access to the sc26198 registers is via an address/data io port pair. + * (Maybe should make this inline...) + */ + +static int stl_sc26198getreg(struct stlport *portp, int regnr) +{ + outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR)); + return inb(portp->ioaddr + XP_DATA); +} + +static void stl_sc26198setreg(struct stlport *portp, int regnr, int value) +{ + outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR)); + outb(value, (portp->ioaddr + XP_DATA)); +} + +static int stl_sc26198updatereg(struct stlport *portp, int regnr, int value) +{ + outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR)); + if (inb(portp->ioaddr + XP_DATA) != value) { + outb(value, (portp->ioaddr + XP_DATA)); + return 1; + } + return 0; +} + +/*****************************************************************************/ + +/* + * Functions to get and set the sc26198 global registers. + */ + +static int stl_sc26198getglobreg(struct stlport *portp, int regnr) +{ + outb(regnr, (portp->ioaddr + XP_ADDR)); + return inb(portp->ioaddr + XP_DATA); +} + +#if 0 +static void stl_sc26198setglobreg(struct stlport *portp, int regnr, int value) +{ + outb(regnr, (portp->ioaddr + XP_ADDR)); + outb(value, (portp->ioaddr + XP_DATA)); +} +#endif + +/*****************************************************************************/ + +/* + * Inbitialize the UARTs in a panel. We don't care what sort of board + * these ports are on - since the port io registers are almost + * identical when dealing with ports. + */ + +static int stl_sc26198panelinit(struct stlbrd *brdp, struct stlpanel *panelp) +{ + int chipmask, i; + int nrchips, ioaddr; + + pr_debug("stl_sc26198panelinit(brdp=%p,panelp=%p)\n", brdp, panelp); + + BRDENABLE(panelp->brdnr, panelp->pagenr); + +/* + * Check that each chip is present and started up OK. + */ + chipmask = 0; + nrchips = (panelp->nrports + 4) / SC26198_PORTS; + if (brdp->brdtype == BRD_ECHPCI) + outb(panelp->pagenr, brdp->ioctrl); + + for (i = 0; i < nrchips; i++) { + ioaddr = panelp->iobase + (i * 4); + outb(SCCR, (ioaddr + XP_ADDR)); + outb(CR_RESETALL, (ioaddr + XP_DATA)); + outb(TSTR, (ioaddr + XP_ADDR)); + if (inb(ioaddr + XP_DATA) != 0) { + printk("STALLION: sc26198 not responding, " + "brd=%d panel=%d chip=%d\n", + panelp->brdnr, panelp->panelnr, i); + continue; + } + chipmask |= (0x1 << i); + outb(GCCR, (ioaddr + XP_ADDR)); + outb(GCCR_IVRTYPCHANACK, (ioaddr + XP_DATA)); + outb(WDTRCR, (ioaddr + XP_ADDR)); + outb(0xff, (ioaddr + XP_DATA)); + } + + BRDDISABLE(panelp->brdnr); + return chipmask; +} + +/*****************************************************************************/ + +/* + * Initialize hardware specific port registers. + */ + +static void stl_sc26198portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp) +{ + pr_debug("stl_sc26198portinit(brdp=%p,panelp=%p,portp=%p)\n", brdp, + panelp, portp); + + if ((brdp == NULL) || (panelp == NULL) || + (portp == NULL)) + return; + + portp->ioaddr = panelp->iobase + ((portp->portnr < 8) ? 0 : 4); + portp->uartaddr = (portp->portnr & 0x07) << 4; + portp->pagenr = panelp->pagenr; + portp->hwid = 0x1; + + BRDENABLE(portp->brdnr, portp->pagenr); + stl_sc26198setreg(portp, IOPCR, IOPCR_SETSIGS); + BRDDISABLE(portp->brdnr); +} + +/*****************************************************************************/ + +/* + * Set up the sc26198 registers for a port based on the termios port + * settings. + */ + +static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp) +{ + struct stlbrd *brdp; + unsigned long flags; + unsigned int baudrate; + unsigned char mr0, mr1, mr2, clk; + unsigned char imron, imroff, iopr, ipr; + + mr0 = 0; + mr1 = 0; + mr2 = 0; + clk = 0; + iopr = 0; + imron = 0; + imroff = 0; + + brdp = stl_brds[portp->brdnr]; + if (brdp == NULL) + return; + +/* + * Set up the RX char ignore mask with those RX error types we + * can ignore. + */ + portp->rxignoremsk = 0; + if (tiosp->c_iflag & IGNPAR) + portp->rxignoremsk |= (SR_RXPARITY | SR_RXFRAMING | + SR_RXOVERRUN); + if (tiosp->c_iflag & IGNBRK) + portp->rxignoremsk |= SR_RXBREAK; + + portp->rxmarkmsk = SR_RXOVERRUN; + if (tiosp->c_iflag & (INPCK | PARMRK)) + portp->rxmarkmsk |= (SR_RXPARITY | SR_RXFRAMING); + if (tiosp->c_iflag & BRKINT) + portp->rxmarkmsk |= SR_RXBREAK; + +/* + * Go through the char size, parity and stop bits and set all the + * option register appropriately. + */ + switch (tiosp->c_cflag & CSIZE) { + case CS5: + mr1 |= MR1_CS5; + break; + case CS6: + mr1 |= MR1_CS6; + break; + case CS7: + mr1 |= MR1_CS7; + break; + default: + mr1 |= MR1_CS8; + break; + } + + if (tiosp->c_cflag & CSTOPB) + mr2 |= MR2_STOP2; + else + mr2 |= MR2_STOP1; + + if (tiosp->c_cflag & PARENB) { + if (tiosp->c_cflag & PARODD) + mr1 |= (MR1_PARENB | MR1_PARODD); + else + mr1 |= (MR1_PARENB | MR1_PAREVEN); + } else + mr1 |= MR1_PARNONE; + + mr1 |= MR1_ERRBLOCK; + +/* + * Set the RX FIFO threshold at 8 chars. This gives a bit of breathing + * space for hardware flow control and the like. This should be set to + * VMIN. + */ + mr2 |= MR2_RXFIFOHALF; + +/* + * Calculate the baud rate timers. For now we will just assume that + * the input and output baud are the same. The sc26198 has a fixed + * baud rate table, so only discrete baud rates possible. + */ + baudrate = tiosp->c_cflag & CBAUD; + if (baudrate & CBAUDEX) { + baudrate &= ~CBAUDEX; + if ((baudrate < 1) || (baudrate > 4)) + tiosp->c_cflag &= ~CBAUDEX; + else + baudrate += 15; + } + baudrate = stl_baudrates[baudrate]; + if ((tiosp->c_cflag & CBAUD) == B38400) { + if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + baudrate = 57600; + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + baudrate = 115200; + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + baudrate = 230400; + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + baudrate = 460800; + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) + baudrate = (portp->baud_base / portp->custom_divisor); + } + if (baudrate > STL_SC26198MAXBAUD) + baudrate = STL_SC26198MAXBAUD; + + if (baudrate > 0) + for (clk = 0; clk < SC26198_NRBAUDS; clk++) + if (baudrate <= sc26198_baudtable[clk]) + break; + +/* + * Check what form of modem signaling is required and set it up. + */ + if (tiosp->c_cflag & CLOCAL) { + portp->port.flags &= ~ASYNC_CHECK_CD; + } else { + iopr |= IOPR_DCDCOS; + imron |= IR_IOPORT; + portp->port.flags |= ASYNC_CHECK_CD; + } + +/* + * Setup sc26198 enhanced modes if we can. In particular we want to + * handle as much of the flow control as possible automatically. As + * well as saving a few CPU cycles it will also greatly improve flow + * control reliability. + */ + if (tiosp->c_iflag & IXON) { + mr0 |= MR0_SWFTX | MR0_SWFT; + imron |= IR_XONXOFF; + } else + imroff |= IR_XONXOFF; + + if (tiosp->c_iflag & IXOFF) + mr0 |= MR0_SWFRX; + + if (tiosp->c_cflag & CRTSCTS) { + mr2 |= MR2_AUTOCTS; + mr1 |= MR1_AUTORTS; + } + +/* + * All sc26198 register values calculated so go through and set + * them all up. + */ + + pr_debug("SETPORT: portnr=%d panelnr=%d brdnr=%d\n", + portp->portnr, portp->panelnr, portp->brdnr); + pr_debug(" mr0=%x mr1=%x mr2=%x clk=%x\n", mr0, mr1, mr2, clk); + pr_debug(" iopr=%x imron=%x imroff=%x\n", iopr, imron, imroff); + pr_debug(" schr1=%x schr2=%x schr3=%x schr4=%x\n", + tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP], + tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + stl_sc26198setreg(portp, IMR, 0); + stl_sc26198updatereg(portp, MR0, mr0); + stl_sc26198updatereg(portp, MR1, mr1); + stl_sc26198setreg(portp, SCCR, CR_RXERRBLOCK); + stl_sc26198updatereg(portp, MR2, mr2); + stl_sc26198updatereg(portp, IOPIOR, + ((stl_sc26198getreg(portp, IOPIOR) & ~IPR_CHANGEMASK) | iopr)); + + if (baudrate > 0) { + stl_sc26198setreg(portp, TXCSR, clk); + stl_sc26198setreg(portp, RXCSR, clk); + } + + stl_sc26198setreg(portp, XONCR, tiosp->c_cc[VSTART]); + stl_sc26198setreg(portp, XOFFCR, tiosp->c_cc[VSTOP]); + + ipr = stl_sc26198getreg(portp, IPR); + if (ipr & IPR_DCD) + portp->sigs &= ~TIOCM_CD; + else + portp->sigs |= TIOCM_CD; + + portp->imr = (portp->imr & ~imroff) | imron; + stl_sc26198setreg(portp, IMR, portp->imr); + BRDDISABLE(portp->brdnr); + spin_unlock_irqrestore(&brd_lock, flags); +} + +/*****************************************************************************/ + +/* + * Set the state of the DTR and RTS signals. + */ + +static void stl_sc26198setsignals(struct stlport *portp, int dtr, int rts) +{ + unsigned char iopioron, iopioroff; + unsigned long flags; + + pr_debug("stl_sc26198setsignals(portp=%p,dtr=%d,rts=%d)\n", portp, + dtr, rts); + + iopioron = 0; + iopioroff = 0; + if (dtr == 0) + iopioroff |= IPR_DTR; + else if (dtr > 0) + iopioron |= IPR_DTR; + if (rts == 0) + iopioroff |= IPR_RTS; + else if (rts > 0) + iopioron |= IPR_RTS; + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + stl_sc26198setreg(portp, IOPIOR, + ((stl_sc26198getreg(portp, IOPIOR) & ~iopioroff) | iopioron)); + BRDDISABLE(portp->brdnr); + spin_unlock_irqrestore(&brd_lock, flags); +} + +/*****************************************************************************/ + +/* + * Return the state of the signals. + */ + +static int stl_sc26198getsignals(struct stlport *portp) +{ + unsigned char ipr; + unsigned long flags; + int sigs; + + pr_debug("stl_sc26198getsignals(portp=%p)\n", portp); + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + ipr = stl_sc26198getreg(portp, IPR); + BRDDISABLE(portp->brdnr); + spin_unlock_irqrestore(&brd_lock, flags); + + sigs = 0; + sigs |= (ipr & IPR_DCD) ? 0 : TIOCM_CD; + sigs |= (ipr & IPR_CTS) ? 0 : TIOCM_CTS; + sigs |= (ipr & IPR_DTR) ? 0: TIOCM_DTR; + sigs |= (ipr & IPR_RTS) ? 0: TIOCM_RTS; + sigs |= TIOCM_DSR; + return sigs; +} + +/*****************************************************************************/ + +/* + * Enable/Disable the Transmitter and/or Receiver. + */ + +static void stl_sc26198enablerxtx(struct stlport *portp, int rx, int tx) +{ + unsigned char ccr; + unsigned long flags; + + pr_debug("stl_sc26198enablerxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx,tx); + + ccr = portp->crenable; + if (tx == 0) + ccr &= ~CR_TXENABLE; + else if (tx > 0) + ccr |= CR_TXENABLE; + if (rx == 0) + ccr &= ~CR_RXENABLE; + else if (rx > 0) + ccr |= CR_RXENABLE; + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + stl_sc26198setreg(portp, SCCR, ccr); + BRDDISABLE(portp->brdnr); + portp->crenable = ccr; + spin_unlock_irqrestore(&brd_lock, flags); +} + +/*****************************************************************************/ + +/* + * Start/stop the Transmitter and/or Receiver. + */ + +static void stl_sc26198startrxtx(struct stlport *portp, int rx, int tx) +{ + unsigned char imr; + unsigned long flags; + + pr_debug("stl_sc26198startrxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx); + + imr = portp->imr; + if (tx == 0) + imr &= ~IR_TXRDY; + else if (tx == 1) + imr |= IR_TXRDY; + if (rx == 0) + imr &= ~(IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG); + else if (rx > 0) + imr |= IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG; + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + stl_sc26198setreg(portp, IMR, imr); + BRDDISABLE(portp->brdnr); + portp->imr = imr; + if (tx > 0) + set_bit(ASYI_TXBUSY, &portp->istate); + spin_unlock_irqrestore(&brd_lock, flags); +} + +/*****************************************************************************/ + +/* + * Disable all interrupts from this port. + */ + +static void stl_sc26198disableintrs(struct stlport *portp) +{ + unsigned long flags; + + pr_debug("stl_sc26198disableintrs(portp=%p)\n", portp); + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + portp->imr = 0; + stl_sc26198setreg(portp, IMR, 0); + BRDDISABLE(portp->brdnr); + spin_unlock_irqrestore(&brd_lock, flags); +} + +/*****************************************************************************/ + +static void stl_sc26198sendbreak(struct stlport *portp, int len) +{ + unsigned long flags; + + pr_debug("stl_sc26198sendbreak(portp=%p,len=%d)\n", portp, len); + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + if (len == 1) { + stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK); + portp->stats.txbreaks++; + } else + stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK); + + BRDDISABLE(portp->brdnr); + spin_unlock_irqrestore(&brd_lock, flags); +} + +/*****************************************************************************/ + +/* + * Take flow control actions... + */ + +static void stl_sc26198flowctrl(struct stlport *portp, int state) +{ + struct tty_struct *tty; + unsigned long flags; + unsigned char mr0; + + pr_debug("stl_sc26198flowctrl(portp=%p,state=%x)\n", portp, state); + + if (portp == NULL) + return; + tty = tty_port_tty_get(&portp->port); + if (tty == NULL) + return; + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + + if (state) { + if (tty->termios->c_iflag & IXOFF) { + mr0 = stl_sc26198getreg(portp, MR0); + stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX)); + stl_sc26198setreg(portp, SCCR, CR_TXSENDXON); + mr0 |= MR0_SWFRX; + portp->stats.rxxon++; + stl_sc26198wait(portp); + stl_sc26198setreg(portp, MR0, mr0); + } +/* + * Question: should we return RTS to what it was before? It may + * have been set by an ioctl... Suppose not, since if you have + * hardware flow control set then it is pretty silly to go and + * set the RTS line by hand. + */ + if (tty->termios->c_cflag & CRTSCTS) { + stl_sc26198setreg(portp, MR1, + (stl_sc26198getreg(portp, MR1) | MR1_AUTORTS)); + stl_sc26198setreg(portp, IOPIOR, + (stl_sc26198getreg(portp, IOPIOR) | IOPR_RTS)); + portp->stats.rxrtson++; + } + } else { + if (tty->termios->c_iflag & IXOFF) { + mr0 = stl_sc26198getreg(portp, MR0); + stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX)); + stl_sc26198setreg(portp, SCCR, CR_TXSENDXOFF); + mr0 &= ~MR0_SWFRX; + portp->stats.rxxoff++; + stl_sc26198wait(portp); + stl_sc26198setreg(portp, MR0, mr0); + } + if (tty->termios->c_cflag & CRTSCTS) { + stl_sc26198setreg(portp, MR1, + (stl_sc26198getreg(portp, MR1) & ~MR1_AUTORTS)); + stl_sc26198setreg(portp, IOPIOR, + (stl_sc26198getreg(portp, IOPIOR) & ~IOPR_RTS)); + portp->stats.rxrtsoff++; + } + } + + BRDDISABLE(portp->brdnr); + spin_unlock_irqrestore(&brd_lock, flags); + tty_kref_put(tty); +} + +/*****************************************************************************/ + +/* + * Send a flow control character. + */ + +static void stl_sc26198sendflow(struct stlport *portp, int state) +{ + struct tty_struct *tty; + unsigned long flags; + unsigned char mr0; + + pr_debug("stl_sc26198sendflow(portp=%p,state=%x)\n", portp, state); + + if (portp == NULL) + return; + tty = tty_port_tty_get(&portp->port); + if (tty == NULL) + return; + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + if (state) { + mr0 = stl_sc26198getreg(portp, MR0); + stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX)); + stl_sc26198setreg(portp, SCCR, CR_TXSENDXON); + mr0 |= MR0_SWFRX; + portp->stats.rxxon++; + stl_sc26198wait(portp); + stl_sc26198setreg(portp, MR0, mr0); + } else { + mr0 = stl_sc26198getreg(portp, MR0); + stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX)); + stl_sc26198setreg(portp, SCCR, CR_TXSENDXOFF); + mr0 &= ~MR0_SWFRX; + portp->stats.rxxoff++; + stl_sc26198wait(portp); + stl_sc26198setreg(portp, MR0, mr0); + } + BRDDISABLE(portp->brdnr); + spin_unlock_irqrestore(&brd_lock, flags); + tty_kref_put(tty); +} + +/*****************************************************************************/ + +static void stl_sc26198flush(struct stlport *portp) +{ + unsigned long flags; + + pr_debug("stl_sc26198flush(portp=%p)\n", portp); + + if (portp == NULL) + return; + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + stl_sc26198setreg(portp, SCCR, CR_TXRESET); + stl_sc26198setreg(portp, SCCR, portp->crenable); + BRDDISABLE(portp->brdnr); + portp->tx.tail = portp->tx.head; + spin_unlock_irqrestore(&brd_lock, flags); +} + +/*****************************************************************************/ + +/* + * Return the current state of data flow on this port. This is only + * really interesting when determining if data has fully completed + * transmission or not... The sc26198 interrupt scheme cannot + * determine when all data has actually drained, so we need to + * check the port statusy register to be sure. + */ + +static int stl_sc26198datastate(struct stlport *portp) +{ + unsigned long flags; + unsigned char sr; + + pr_debug("stl_sc26198datastate(portp=%p)\n", portp); + + if (portp == NULL) + return 0; + if (test_bit(ASYI_TXBUSY, &portp->istate)) + return 1; + + spin_lock_irqsave(&brd_lock, flags); + BRDENABLE(portp->brdnr, portp->pagenr); + sr = stl_sc26198getreg(portp, SR); + BRDDISABLE(portp->brdnr); + spin_unlock_irqrestore(&brd_lock, flags); + + return (sr & SR_TXEMPTY) ? 0 : 1; +} + +/*****************************************************************************/ + +/* + * Delay for a small amount of time, to give the sc26198 a chance + * to process a command... + */ + +static void stl_sc26198wait(struct stlport *portp) +{ + int i; + + pr_debug("stl_sc26198wait(portp=%p)\n", portp); + + if (portp == NULL) + return; + + for (i = 0; i < 20; i++) + stl_sc26198getglobreg(portp, TSTR); +} + +/*****************************************************************************/ + +/* + * If we are TX flow controlled and in IXANY mode then we may + * need to unflow control here. We gotta do this because of the + * automatic flow control modes of the sc26198. + */ + +static void stl_sc26198txunflow(struct stlport *portp, struct tty_struct *tty) +{ + unsigned char mr0; + + mr0 = stl_sc26198getreg(portp, MR0); + stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX)); + stl_sc26198setreg(portp, SCCR, CR_HOSTXON); + stl_sc26198wait(portp); + stl_sc26198setreg(portp, MR0, mr0); + clear_bit(ASYI_TXFLOWED, &portp->istate); +} + +/*****************************************************************************/ + +/* + * Interrupt service routine for sc26198 panels. + */ + +static void stl_sc26198intr(struct stlpanel *panelp, unsigned int iobase) +{ + struct stlport *portp; + unsigned int iack; + + spin_lock(&brd_lock); + +/* + * Work around bug in sc26198 chip... Cannot have A6 address + * line of UART high, else iack will be returned as 0. + */ + outb(0, (iobase + 1)); + + iack = inb(iobase + XP_IACK); + portp = panelp->ports[(iack & IVR_CHANMASK) + ((iobase & 0x4) << 1)]; + + if (iack & IVR_RXDATA) + stl_sc26198rxisr(portp, iack); + else if (iack & IVR_TXDATA) + stl_sc26198txisr(portp); + else + stl_sc26198otherisr(portp, iack); + + spin_unlock(&brd_lock); +} + +/*****************************************************************************/ + +/* + * Transmit interrupt handler. This has gotta be fast! Handling TX + * chars is pretty simple, stuff as many as possible from the TX buffer + * into the sc26198 FIFO. + * In practice it is possible that interrupts are enabled but that the + * port has been hung up. Need to handle not having any TX buffer here, + * this is done by using the side effect that head and tail will also + * be NULL if the buffer has been freed. + */ + +static void stl_sc26198txisr(struct stlport *portp) +{ + struct tty_struct *tty; + unsigned int ioaddr; + unsigned char mr0; + int len, stlen; + char *head, *tail; + + pr_debug("stl_sc26198txisr(portp=%p)\n", portp); + + ioaddr = portp->ioaddr; + head = portp->tx.head; + tail = portp->tx.tail; + len = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head)); + if ((len == 0) || ((len < STL_TXBUFLOW) && + (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { + set_bit(ASYI_TXLOW, &portp->istate); + tty = tty_port_tty_get(&portp->port); + if (tty) { + tty_wakeup(tty); + tty_kref_put(tty); + } + } + + if (len == 0) { + outb((MR0 | portp->uartaddr), (ioaddr + XP_ADDR)); + mr0 = inb(ioaddr + XP_DATA); + if ((mr0 & MR0_TXMASK) == MR0_TXEMPTY) { + portp->imr &= ~IR_TXRDY; + outb((IMR | portp->uartaddr), (ioaddr + XP_ADDR)); + outb(portp->imr, (ioaddr + XP_DATA)); + clear_bit(ASYI_TXBUSY, &portp->istate); + } else { + mr0 |= ((mr0 & ~MR0_TXMASK) | MR0_TXEMPTY); + outb(mr0, (ioaddr + XP_DATA)); + } + } else { + len = min(len, SC26198_TXFIFOSIZE); + portp->stats.txtotal += len; + stlen = min_t(unsigned int, len, + (portp->tx.buf + STL_TXBUFSIZE) - tail); + outb(GTXFIFO, (ioaddr + XP_ADDR)); + outsb((ioaddr + XP_DATA), tail, stlen); + len -= stlen; + tail += stlen; + if (tail >= (portp->tx.buf + STL_TXBUFSIZE)) + tail = portp->tx.buf; + if (len > 0) { + outsb((ioaddr + XP_DATA), tail, len); + tail += len; + } + portp->tx.tail = tail; + } +} + +/*****************************************************************************/ + +/* + * Receive character interrupt handler. Determine if we have good chars + * or bad chars and then process appropriately. Good chars are easy + * just shove the lot into the RX buffer and set all status byte to 0. + * If a bad RX char then process as required. This routine needs to be + * fast! In practice it is possible that we get an interrupt on a port + * that is closed. This can happen on hangups - since they completely + * shutdown a port not in user context. Need to handle this case. + */ + +static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack) +{ + struct tty_struct *tty; + unsigned int len, buflen, ioaddr; + + pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack); + + tty = tty_port_tty_get(&portp->port); + ioaddr = portp->ioaddr; + outb(GIBCR, (ioaddr + XP_ADDR)); + len = inb(ioaddr + XP_DATA) + 1; + + if ((iack & IVR_TYPEMASK) == IVR_RXDATA) { + if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) { + len = min_t(unsigned int, len, sizeof(stl_unwanted)); + outb(GRXFIFO, (ioaddr + XP_ADDR)); + insb((ioaddr + XP_DATA), &stl_unwanted[0], len); + portp->stats.rxlost += len; + portp->stats.rxtotal += len; + } else { + len = min(len, buflen); + if (len > 0) { + unsigned char *ptr; + outb(GRXFIFO, (ioaddr + XP_ADDR)); + tty_prepare_flip_string(tty, &ptr, len); + insb((ioaddr + XP_DATA), ptr, len); + tty_schedule_flip(tty); + portp->stats.rxtotal += len; + } + } + } else { + stl_sc26198rxbadchars(portp); + } + +/* + * If we are TX flow controlled and in IXANY mode then we may need + * to unflow control here. We gotta do this because of the automatic + * flow control modes of the sc26198. + */ + if (test_bit(ASYI_TXFLOWED, &portp->istate)) { + if ((tty != NULL) && + (tty->termios != NULL) && + (tty->termios->c_iflag & IXANY)) { + stl_sc26198txunflow(portp, tty); + } + } + tty_kref_put(tty); +} + +/*****************************************************************************/ + +/* + * Process an RX bad character. + */ + +static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char ch) +{ + struct tty_struct *tty; + unsigned int ioaddr; + + tty = tty_port_tty_get(&portp->port); + ioaddr = portp->ioaddr; + + if (status & SR_RXPARITY) + portp->stats.rxparity++; + if (status & SR_RXFRAMING) + portp->stats.rxframing++; + if (status & SR_RXOVERRUN) + portp->stats.rxoverrun++; + if (status & SR_RXBREAK) + portp->stats.rxbreaks++; + + if ((tty != NULL) && + ((portp->rxignoremsk & status) == 0)) { + if (portp->rxmarkmsk & status) { + if (status & SR_RXBREAK) { + status = TTY_BREAK; + if (portp->port.flags & ASYNC_SAK) { + do_SAK(tty); + BRDENABLE(portp->brdnr, portp->pagenr); + } + } else if (status & SR_RXPARITY) + status = TTY_PARITY; + else if (status & SR_RXFRAMING) + status = TTY_FRAME; + else if(status & SR_RXOVERRUN) + status = TTY_OVERRUN; + else + status = 0; + } else + status = 0; + + tty_insert_flip_char(tty, ch, status); + tty_schedule_flip(tty); + + if (status == 0) + portp->stats.rxtotal++; + } + tty_kref_put(tty); +} + +/*****************************************************************************/ + +/* + * Process all characters in the RX FIFO of the UART. Check all char + * status bytes as well, and process as required. We need to check + * all bytes in the FIFO, in case some more enter the FIFO while we + * are here. To get the exact character error type we need to switch + * into CHAR error mode (that is why we need to make sure we empty + * the FIFO). + */ + +static void stl_sc26198rxbadchars(struct stlport *portp) +{ + unsigned char status, mr1; + char ch; + +/* + * To get the precise error type for each character we must switch + * back into CHAR error mode. + */ + mr1 = stl_sc26198getreg(portp, MR1); + stl_sc26198setreg(portp, MR1, (mr1 & ~MR1_ERRBLOCK)); + + while ((status = stl_sc26198getreg(portp, SR)) & SR_RXRDY) { + stl_sc26198setreg(portp, SCCR, CR_CLEARRXERR); + ch = stl_sc26198getreg(portp, RXFIFO); + stl_sc26198rxbadch(portp, status, ch); + } + +/* + * To get correct interrupt class we must switch back into BLOCK + * error mode. + */ + stl_sc26198setreg(portp, MR1, mr1); +} + +/*****************************************************************************/ + +/* + * Other interrupt handler. This includes modem signals, flow + * control actions, etc. Most stuff is left to off-level interrupt + * processing time. + */ + +static void stl_sc26198otherisr(struct stlport *portp, unsigned int iack) +{ + unsigned char cir, ipr, xisr; + + pr_debug("stl_sc26198otherisr(portp=%p,iack=%x)\n", portp, iack); + + cir = stl_sc26198getglobreg(portp, CIR); + + switch (cir & CIR_SUBTYPEMASK) { + case CIR_SUBCOS: + ipr = stl_sc26198getreg(portp, IPR); + if (ipr & IPR_DCDCHANGE) { + stl_cd_change(portp); + portp->stats.modem++; + } + break; + case CIR_SUBXONXOFF: + xisr = stl_sc26198getreg(portp, XISR); + if (xisr & XISR_RXXONGOT) { + set_bit(ASYI_TXFLOWED, &portp->istate); + portp->stats.txxoff++; + } + if (xisr & XISR_RXXOFFGOT) { + clear_bit(ASYI_TXFLOWED, &portp->istate); + portp->stats.txxon++; + } + break; + case CIR_SUBBREAK: + stl_sc26198setreg(portp, SCCR, CR_BREAKRESET); + stl_sc26198rxbadchars(portp); + break; + default: + break; + } +} + +static void stl_free_isabrds(void) +{ + struct stlbrd *brdp; + unsigned int i; + + for (i = 0; i < stl_nrbrds; i++) { + if ((brdp = stl_brds[i]) == NULL || (brdp->state & STL_PROBED)) + continue; + + free_irq(brdp->irq, brdp); + + stl_cleanup_panels(brdp); + + release_region(brdp->ioaddr1, brdp->iosize1); + if (brdp->iosize2 > 0) + release_region(brdp->ioaddr2, brdp->iosize2); + + kfree(brdp); + stl_brds[i] = NULL; + } +} + +/* + * Loadable module initialization stuff. + */ +static int __init stallion_module_init(void) +{ + struct stlbrd *brdp; + struct stlconf conf; + unsigned int i, j; + int retval; + + printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion); + + spin_lock_init(&stallion_lock); + spin_lock_init(&brd_lock); + + stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); + if (!stl_serial) { + retval = -ENOMEM; + goto err; + } + + stl_serial->owner = THIS_MODULE; + stl_serial->driver_name = stl_drvname; + stl_serial->name = "ttyE"; + stl_serial->major = STL_SERIALMAJOR; + stl_serial->minor_start = 0; + stl_serial->type = TTY_DRIVER_TYPE_SERIAL; + stl_serial->subtype = SERIAL_TYPE_NORMAL; + stl_serial->init_termios = stl_deftermios; + stl_serial->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + tty_set_operations(stl_serial, &stl_ops); + + retval = tty_register_driver(stl_serial); + if (retval) { + printk("STALLION: failed to register serial driver\n"); + goto err_frtty; + } + +/* + * Find any dynamically supported boards. That is via module load + * line options. + */ + for (i = stl_nrbrds; i < stl_nargs; i++) { + memset(&conf, 0, sizeof(conf)); + if (stl_parsebrd(&conf, stl_brdsp[i]) == 0) + continue; + if ((brdp = stl_allocbrd()) == NULL) + continue; + brdp->brdnr = i; + brdp->brdtype = conf.brdtype; + brdp->ioaddr1 = conf.ioaddr1; + brdp->ioaddr2 = conf.ioaddr2; + brdp->irq = conf.irq; + brdp->irqtype = conf.irqtype; + stl_brds[brdp->brdnr] = brdp; + if (stl_brdinit(brdp)) { + stl_brds[brdp->brdnr] = NULL; + kfree(brdp); + } else { + for (j = 0; j < brdp->nrports; j++) + tty_register_device(stl_serial, + brdp->brdnr * STL_MAXPORTS + j, NULL); + stl_nrbrds = i + 1; + } + } + + /* this has to be _after_ isa finding because of locking */ + retval = pci_register_driver(&stl_pcidriver); + if (retval && stl_nrbrds == 0) { + printk(KERN_ERR "STALLION: can't register pci driver\n"); + goto err_unrtty; + } + +/* + * Set up a character driver for per board stuff. This is mainly used + * to do stats ioctls on the ports. + */ + if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem)) + printk("STALLION: failed to register serial board device\n"); + + stallion_class = class_create(THIS_MODULE, "staliomem"); + if (IS_ERR(stallion_class)) + printk("STALLION: failed to create class\n"); + for (i = 0; i < 4; i++) + device_create(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i), + NULL, "staliomem%d", i); + + return 0; +err_unrtty: + tty_unregister_driver(stl_serial); +err_frtty: + put_tty_driver(stl_serial); +err: + return retval; +} + +static void __exit stallion_module_exit(void) +{ + struct stlbrd *brdp; + unsigned int i, j; + + pr_debug("cleanup_module()\n"); + + printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle, + stl_drvversion); + +/* + * Free up all allocated resources used by the ports. This includes + * memory and interrupts. As part of this process we will also do + * a hangup on every open port - to try to flush out any processes + * hanging onto ports. + */ + for (i = 0; i < stl_nrbrds; i++) { + if ((brdp = stl_brds[i]) == NULL || (brdp->state & STL_PROBED)) + continue; + for (j = 0; j < brdp->nrports; j++) + tty_unregister_device(stl_serial, + brdp->brdnr * STL_MAXPORTS + j); + } + + for (i = 0; i < 4; i++) + device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i)); + unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"); + class_destroy(stallion_class); + + pci_unregister_driver(&stl_pcidriver); + + stl_free_isabrds(); + + tty_unregister_driver(stl_serial); + put_tty_driver(stl_serial); +} + +module_init(stallion_module_init); +module_exit(stallion_module_exit); + +MODULE_AUTHOR("Greg Ungerer"); +MODULE_DESCRIPTION("Stallion Multiport Serial Driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 4c37705877e74c02c968735c2eee0f84914cf557 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 22 Feb 2011 17:09:33 -0800 Subject: tty: move obsolete and broken generic_serial drivers to drivers/staging/generic_serial/ As planned by Arnd Bergmann, this moves the following drivers to the drivers/staging/generic_serial directory where they will be removed after 2.6.41 if no one steps up to claim them. generic_serial rio ser_a2232 sx vme_scc Cc: Arnd Bergmann Cc: Alan Cox Cc: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/char/Kconfig | 44 - drivers/char/Makefile | 6 - drivers/char/generic_serial.c | 844 ------ drivers/char/rio/Makefile | 12 - drivers/char/rio/board.h | 132 - drivers/char/rio/cirrus.h | 210 -- drivers/char/rio/cmdblk.h | 53 - drivers/char/rio/cmdpkt.h | 177 -- drivers/char/rio/daemon.h | 307 --- drivers/char/rio/errors.h | 98 - drivers/char/rio/func.h | 143 - drivers/char/rio/host.h | 123 - drivers/char/rio/link.h | 96 - drivers/char/rio/linux_compat.h | 77 - drivers/char/rio/map.h | 98 - drivers/char/rio/param.h | 55 - drivers/char/rio/parmmap.h | 81 - drivers/char/rio/pci.h | 72 - drivers/char/rio/phb.h | 142 - drivers/char/rio/pkt.h | 77 - drivers/char/rio/port.h | 179 -- drivers/char/rio/protsts.h | 110 - drivers/char/rio/rio.h | 208 -- drivers/char/rio/rio_linux.c | 1204 --------- drivers/char/rio/rio_linux.h | 197 -- drivers/char/rio/rioboard.h | 275 -- drivers/char/rio/rioboot.c | 1113 -------- drivers/char/rio/riocmd.c | 939 ------- drivers/char/rio/rioctrl.c | 1504 ----------- drivers/char/rio/riodrvr.h | 138 - drivers/char/rio/rioinfo.h | 92 - drivers/char/rio/rioinit.c | 421 --- drivers/char/rio/riointr.c | 645 ----- drivers/char/rio/rioioctl.h | 57 - drivers/char/rio/rioparam.c | 663 ----- drivers/char/rio/rioroute.c | 1039 -------- drivers/char/rio/riospace.h | 154 -- drivers/char/rio/riotable.c | 941 ------- drivers/char/rio/riotty.c | 654 ----- drivers/char/rio/route.h | 101 - drivers/char/rio/rup.h | 69 - drivers/char/rio/unixrup.h | 51 - drivers/char/ser_a2232.c | 831 ------ drivers/char/ser_a2232.h | 202 -- drivers/char/ser_a2232fw.ax | 529 ---- drivers/char/ser_a2232fw.h | 306 --- drivers/char/sx.c | 2894 --------------------- drivers/char/sx.h | 201 -- drivers/char/sxboards.h | 206 -- drivers/char/sxwindow.h | 393 --- drivers/char/vme_scc.c | 1145 -------- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/generic_serial/Kconfig | 45 + drivers/staging/generic_serial/Makefile | 6 + drivers/staging/generic_serial/TODO | 6 + drivers/staging/generic_serial/generic_serial.c | 844 ++++++ drivers/staging/generic_serial/rio/Makefile | 12 + drivers/staging/generic_serial/rio/board.h | 132 + drivers/staging/generic_serial/rio/cirrus.h | 210 ++ drivers/staging/generic_serial/rio/cmdblk.h | 53 + drivers/staging/generic_serial/rio/cmdpkt.h | 177 ++ drivers/staging/generic_serial/rio/daemon.h | 307 +++ drivers/staging/generic_serial/rio/errors.h | 98 + drivers/staging/generic_serial/rio/func.h | 143 + drivers/staging/generic_serial/rio/host.h | 123 + drivers/staging/generic_serial/rio/link.h | 96 + drivers/staging/generic_serial/rio/linux_compat.h | 77 + drivers/staging/generic_serial/rio/map.h | 98 + drivers/staging/generic_serial/rio/param.h | 55 + drivers/staging/generic_serial/rio/parmmap.h | 81 + drivers/staging/generic_serial/rio/pci.h | 72 + drivers/staging/generic_serial/rio/phb.h | 142 + drivers/staging/generic_serial/rio/pkt.h | 77 + drivers/staging/generic_serial/rio/port.h | 179 ++ drivers/staging/generic_serial/rio/protsts.h | 110 + drivers/staging/generic_serial/rio/rio.h | 208 ++ drivers/staging/generic_serial/rio/rio_linux.c | 1204 +++++++++ drivers/staging/generic_serial/rio/rio_linux.h | 197 ++ drivers/staging/generic_serial/rio/rioboard.h | 275 ++ drivers/staging/generic_serial/rio/rioboot.c | 1113 ++++++++ drivers/staging/generic_serial/rio/riocmd.c | 939 +++++++ drivers/staging/generic_serial/rio/rioctrl.c | 1504 +++++++++++ drivers/staging/generic_serial/rio/riodrvr.h | 138 + drivers/staging/generic_serial/rio/rioinfo.h | 92 + drivers/staging/generic_serial/rio/rioinit.c | 421 +++ drivers/staging/generic_serial/rio/riointr.c | 645 +++++ drivers/staging/generic_serial/rio/rioioctl.h | 57 + drivers/staging/generic_serial/rio/rioparam.c | 663 +++++ drivers/staging/generic_serial/rio/rioroute.c | 1039 ++++++++ drivers/staging/generic_serial/rio/riospace.h | 154 ++ drivers/staging/generic_serial/rio/riotable.c | 941 +++++++ drivers/staging/generic_serial/rio/riotty.c | 654 +++++ drivers/staging/generic_serial/rio/route.h | 101 + drivers/staging/generic_serial/rio/rup.h | 69 + drivers/staging/generic_serial/rio/unixrup.h | 51 + drivers/staging/generic_serial/ser_a2232.c | 831 ++++++ drivers/staging/generic_serial/ser_a2232.h | 202 ++ drivers/staging/generic_serial/ser_a2232fw.ax | 529 ++++ drivers/staging/generic_serial/ser_a2232fw.h | 306 +++ drivers/staging/generic_serial/sx.c | 2894 +++++++++++++++++++++ drivers/staging/generic_serial/sx.h | 201 ++ drivers/staging/generic_serial/sxboards.h | 206 ++ drivers/staging/generic_serial/sxwindow.h | 393 +++ drivers/staging/generic_serial/vme_scc.c | 1145 ++++++++ 105 files changed, 20318 insertions(+), 20308 deletions(-) delete mode 100644 drivers/char/generic_serial.c delete mode 100644 drivers/char/rio/Makefile delete mode 100644 drivers/char/rio/board.h delete mode 100644 drivers/char/rio/cirrus.h delete mode 100644 drivers/char/rio/cmdblk.h delete mode 100644 drivers/char/rio/cmdpkt.h delete mode 100644 drivers/char/rio/daemon.h delete mode 100644 drivers/char/rio/errors.h delete mode 100644 drivers/char/rio/func.h delete mode 100644 drivers/char/rio/host.h delete mode 100644 drivers/char/rio/link.h delete mode 100644 drivers/char/rio/linux_compat.h delete mode 100644 drivers/char/rio/map.h delete mode 100644 drivers/char/rio/param.h delete mode 100644 drivers/char/rio/parmmap.h delete mode 100644 drivers/char/rio/pci.h delete mode 100644 drivers/char/rio/phb.h delete mode 100644 drivers/char/rio/pkt.h delete mode 100644 drivers/char/rio/port.h delete mode 100644 drivers/char/rio/protsts.h delete mode 100644 drivers/char/rio/rio.h delete mode 100644 drivers/char/rio/rio_linux.c delete mode 100644 drivers/char/rio/rio_linux.h delete mode 100644 drivers/char/rio/rioboard.h delete mode 100644 drivers/char/rio/rioboot.c delete mode 100644 drivers/char/rio/riocmd.c delete mode 100644 drivers/char/rio/rioctrl.c delete mode 100644 drivers/char/rio/riodrvr.h delete mode 100644 drivers/char/rio/rioinfo.h delete mode 100644 drivers/char/rio/rioinit.c delete mode 100644 drivers/char/rio/riointr.c delete mode 100644 drivers/char/rio/rioioctl.h delete mode 100644 drivers/char/rio/rioparam.c delete mode 100644 drivers/char/rio/rioroute.c delete mode 100644 drivers/char/rio/riospace.h delete mode 100644 drivers/char/rio/riotable.c delete mode 100644 drivers/char/rio/riotty.c delete mode 100644 drivers/char/rio/route.h delete mode 100644 drivers/char/rio/rup.h delete mode 100644 drivers/char/rio/unixrup.h delete mode 100644 drivers/char/ser_a2232.c delete mode 100644 drivers/char/ser_a2232.h delete mode 100644 drivers/char/ser_a2232fw.ax delete mode 100644 drivers/char/ser_a2232fw.h delete mode 100644 drivers/char/sx.c delete mode 100644 drivers/char/sx.h delete mode 100644 drivers/char/sxboards.h delete mode 100644 drivers/char/sxwindow.h delete mode 100644 drivers/char/vme_scc.c create mode 100644 drivers/staging/generic_serial/Kconfig create mode 100644 drivers/staging/generic_serial/Makefile create mode 100644 drivers/staging/generic_serial/TODO create mode 100644 drivers/staging/generic_serial/generic_serial.c create mode 100644 drivers/staging/generic_serial/rio/Makefile create mode 100644 drivers/staging/generic_serial/rio/board.h create mode 100644 drivers/staging/generic_serial/rio/cirrus.h create mode 100644 drivers/staging/generic_serial/rio/cmdblk.h create mode 100644 drivers/staging/generic_serial/rio/cmdpkt.h create mode 100644 drivers/staging/generic_serial/rio/daemon.h create mode 100644 drivers/staging/generic_serial/rio/errors.h create mode 100644 drivers/staging/generic_serial/rio/func.h create mode 100644 drivers/staging/generic_serial/rio/host.h create mode 100644 drivers/staging/generic_serial/rio/link.h create mode 100644 drivers/staging/generic_serial/rio/linux_compat.h create mode 100644 drivers/staging/generic_serial/rio/map.h create mode 100644 drivers/staging/generic_serial/rio/param.h create mode 100644 drivers/staging/generic_serial/rio/parmmap.h create mode 100644 drivers/staging/generic_serial/rio/pci.h create mode 100644 drivers/staging/generic_serial/rio/phb.h create mode 100644 drivers/staging/generic_serial/rio/pkt.h create mode 100644 drivers/staging/generic_serial/rio/port.h create mode 100644 drivers/staging/generic_serial/rio/protsts.h create mode 100644 drivers/staging/generic_serial/rio/rio.h create mode 100644 drivers/staging/generic_serial/rio/rio_linux.c create mode 100644 drivers/staging/generic_serial/rio/rio_linux.h create mode 100644 drivers/staging/generic_serial/rio/rioboard.h create mode 100644 drivers/staging/generic_serial/rio/rioboot.c create mode 100644 drivers/staging/generic_serial/rio/riocmd.c create mode 100644 drivers/staging/generic_serial/rio/rioctrl.c create mode 100644 drivers/staging/generic_serial/rio/riodrvr.h create mode 100644 drivers/staging/generic_serial/rio/rioinfo.h create mode 100644 drivers/staging/generic_serial/rio/rioinit.c create mode 100644 drivers/staging/generic_serial/rio/riointr.c create mode 100644 drivers/staging/generic_serial/rio/rioioctl.h create mode 100644 drivers/staging/generic_serial/rio/rioparam.c create mode 100644 drivers/staging/generic_serial/rio/rioroute.c create mode 100644 drivers/staging/generic_serial/rio/riospace.h create mode 100644 drivers/staging/generic_serial/rio/riotable.c create mode 100644 drivers/staging/generic_serial/rio/riotty.c create mode 100644 drivers/staging/generic_serial/rio/route.h create mode 100644 drivers/staging/generic_serial/rio/rup.h create mode 100644 drivers/staging/generic_serial/rio/unixrup.h create mode 100644 drivers/staging/generic_serial/ser_a2232.c create mode 100644 drivers/staging/generic_serial/ser_a2232.h create mode 100644 drivers/staging/generic_serial/ser_a2232fw.ax create mode 100644 drivers/staging/generic_serial/ser_a2232fw.h create mode 100644 drivers/staging/generic_serial/sx.c create mode 100644 drivers/staging/generic_serial/sx.h create mode 100644 drivers/staging/generic_serial/sxboards.h create mode 100644 drivers/staging/generic_serial/sxwindow.h create mode 100644 drivers/staging/generic_serial/vme_scc.c (limited to 'drivers') diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 7b8cf0295f6c..04f8b2d083c6 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -15,34 +15,6 @@ config DEVKMEM kind of kernel debugging operations. When in doubt, say "N". -config SX - tristate "Specialix SX (and SI) card support" - depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) && BROKEN - help - This is a driver for the SX and SI multiport serial cards. - Please read the file for details. - - This driver can only be built as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called sx. If you want to do that, say M here. - -config RIO - tristate "Specialix RIO system support" - depends on SERIAL_NONSTANDARD && BROKEN - help - This is a driver for the Specialix RIO, a smart serial card which - drives an outboard box that can support up to 128 ports. Product - information is at . - There are both ISA and PCI versions. - -config RIO_OLDPCI - bool "Support really old RIO/PCI cards" - depends on RIO - help - Older RIO PCI cards need some initialization-time configuration to - determine the IRQ and some control addresses. If you have a RIO and - this doesn't seem to work, try setting this to Y. - config STALDRV bool "Stallion multiport serial support" depends on SERIAL_NONSTANDARD @@ -55,22 +27,6 @@ config STALDRV in this case. If you have never heard about all this, it's safe to say N. -config A2232 - tristate "Commodore A2232 serial support (EXPERIMENTAL)" - depends on EXPERIMENTAL && ZORRO && BROKEN - ---help--- - This option supports the 2232 7-port serial card shipped with the - Amiga 2000 and other Zorro-bus machines, dating from 1989. At - a max of 19,200 bps, the ports are served by a 6551 ACIA UART chip - each, plus a 8520 CIA, and a master 6502 CPU and buffer as well. The - ports were connected with 8 pin DIN connectors on the card bracket, - for which 8 pin to DB25 adapters were supplied. The card also had - jumpers internally to toggle various pinning configurations. - - This driver can be built as a module; but then "generic_serial" - will also be built as a module. This has to be loaded before - "ser_a2232". If you want to do this, answer M here. - config SGI_SNSC bool "SGI Altix system controller communication support" depends on (IA64_SGI_SN2 || IA64_GENERIC) diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 48bb8acbea49..3ca1f627be8a 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -5,13 +5,7 @@ obj-y += mem.o random.o obj-$(CONFIG_TTY_PRINTK) += ttyprintk.o obj-y += misc.o -obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o -obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o -obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o -obj-$(CONFIG_A2232) += ser_a2232.o generic_serial.o obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o -obj-$(CONFIG_SX) += sx.o generic_serial.o -obj-$(CONFIG_RIO) += rio/ generic_serial.o obj-$(CONFIG_RAW_DRIVER) += raw.o obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o obj-$(CONFIG_MSPEC) += mspec.o diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c deleted file mode 100644 index 5954ee1dc953..000000000000 --- a/drivers/char/generic_serial.c +++ /dev/null @@ -1,844 +0,0 @@ -/* - * generic_serial.c - * - * Copyright (C) 1998/1999 R.E.Wolff@BitWizard.nl - * - * written for the SX serial driver. - * Contains the code that should be shared over all the serial drivers. - * - * Credit for the idea to do it this way might go to Alan Cox. - * - * - * Version 0.1 -- December, 1998. Initial version. - * Version 0.2 -- March, 1999. Some more routines. Bugfixes. Etc. - * Version 0.5 -- August, 1999. Some more fixes. Reformat for Linus. - * - * BitWizard is actively maintaining this file. We sometimes find - * that someone submitted changes to this file. We really appreciate - * your help, but please submit changes through us. We're doing our - * best to be responsive. -- REW - * */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG - -static int gs_debug; - -#ifdef DEBUG -#define gs_dprintk(f, str...) if (gs_debug & f) printk (str) -#else -#define gs_dprintk(f, str...) /* nothing */ -#endif - -#define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter %s\n", __func__) -#define func_exit() gs_dprintk (GS_DEBUG_FLOW, "gs: exit %s\n", __func__) - -#define RS_EVENT_WRITE_WAKEUP 1 - -module_param(gs_debug, int, 0644); - - -int gs_put_char(struct tty_struct * tty, unsigned char ch) -{ - struct gs_port *port; - - func_enter (); - - port = tty->driver_data; - - if (!port) return 0; - - if (! (port->port.flags & ASYNC_INITIALIZED)) return 0; - - /* Take a lock on the serial tranmit buffer! */ - mutex_lock(& port->port_write_mutex); - - if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { - /* Sorry, buffer is full, drop character. Update statistics???? -- REW */ - mutex_unlock(&port->port_write_mutex); - return 0; - } - - port->xmit_buf[port->xmit_head++] = ch; - port->xmit_head &= SERIAL_XMIT_SIZE - 1; - port->xmit_cnt++; /* Characters in buffer */ - - mutex_unlock(&port->port_write_mutex); - func_exit (); - return 1; -} - - -/* -> Problems to take into account are: -> -1- Interrupts that empty part of the buffer. -> -2- page faults on the access to userspace. -> -3- Other processes that are also trying to do a "write". -*/ - -int gs_write(struct tty_struct * tty, - const unsigned char *buf, int count) -{ - struct gs_port *port; - int c, total = 0; - int t; - - func_enter (); - - port = tty->driver_data; - - if (!port) return 0; - - if (! (port->port.flags & ASYNC_INITIALIZED)) - return 0; - - /* get exclusive "write" access to this port (problem 3) */ - /* This is not a spinlock because we can have a disk access (page - fault) in copy_from_user */ - mutex_lock(& port->port_write_mutex); - - while (1) { - - c = count; - - /* This is safe because we "OWN" the "head". Noone else can - change the "head": we own the port_write_mutex. */ - /* Don't overrun the end of the buffer */ - t = SERIAL_XMIT_SIZE - port->xmit_head; - if (t < c) c = t; - - /* This is safe because the xmit_cnt can only decrease. This - would increase "t", so we might copy too little chars. */ - /* Don't copy past the "head" of the buffer */ - t = SERIAL_XMIT_SIZE - 1 - port->xmit_cnt; - if (t < c) c = t; - - /* Can't copy more? break out! */ - if (c <= 0) break; - - memcpy (port->xmit_buf + port->xmit_head, buf, c); - - port -> xmit_cnt += c; - port -> xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE -1); - buf += c; - count -= c; - total += c; - } - mutex_unlock(& port->port_write_mutex); - - gs_dprintk (GS_DEBUG_WRITE, "write: interrupts are %s\n", - (port->port.flags & GS_TX_INTEN)?"enabled": "disabled"); - - if (port->xmit_cnt && - !tty->stopped && - !tty->hw_stopped && - !(port->port.flags & GS_TX_INTEN)) { - port->port.flags |= GS_TX_INTEN; - port->rd->enable_tx_interrupts (port); - } - func_exit (); - return total; -} - - - -int gs_write_room(struct tty_struct * tty) -{ - struct gs_port *port = tty->driver_data; - int ret; - - func_enter (); - ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1; - if (ret < 0) - ret = 0; - func_exit (); - return ret; -} - - -int gs_chars_in_buffer(struct tty_struct *tty) -{ - struct gs_port *port = tty->driver_data; - func_enter (); - - func_exit (); - return port->xmit_cnt; -} - - -static int gs_real_chars_in_buffer(struct tty_struct *tty) -{ - struct gs_port *port; - func_enter (); - - port = tty->driver_data; - - if (!port->rd) return 0; - if (!port->rd->chars_in_buffer) return 0; - - func_exit (); - return port->xmit_cnt + port->rd->chars_in_buffer (port); -} - - -static int gs_wait_tx_flushed (void * ptr, unsigned long timeout) -{ - struct gs_port *port = ptr; - unsigned long end_jiffies; - int jiffies_to_transmit, charsleft = 0, rv = 0; - int rcib; - - func_enter(); - - gs_dprintk (GS_DEBUG_FLUSH, "port=%p.\n", port); - if (port) { - gs_dprintk (GS_DEBUG_FLUSH, "xmit_cnt=%x, xmit_buf=%p, tty=%p.\n", - port->xmit_cnt, port->xmit_buf, port->port.tty); - } - - if (!port || port->xmit_cnt < 0 || !port->xmit_buf) { - gs_dprintk (GS_DEBUG_FLUSH, "ERROR: !port, !port->xmit_buf or prot->xmit_cnt < 0.\n"); - func_exit(); - return -EINVAL; /* This is an error which we don't know how to handle. */ - } - - rcib = gs_real_chars_in_buffer(port->port.tty); - - if(rcib <= 0) { - gs_dprintk (GS_DEBUG_FLUSH, "nothing to wait for.\n"); - func_exit(); - return rv; - } - /* stop trying: now + twice the time it would normally take + seconds */ - if (timeout == 0) timeout = MAX_SCHEDULE_TIMEOUT; - end_jiffies = jiffies; - if (timeout != MAX_SCHEDULE_TIMEOUT) - end_jiffies += port->baud?(2 * rcib * 10 * HZ / port->baud):0; - end_jiffies += timeout; - - gs_dprintk (GS_DEBUG_FLUSH, "now=%lx, end=%lx (%ld).\n", - jiffies, end_jiffies, end_jiffies-jiffies); - - /* the expression is actually jiffies < end_jiffies, but that won't - work around the wraparound. Tricky eh? */ - while ((charsleft = gs_real_chars_in_buffer (port->port.tty)) && - time_after (end_jiffies, jiffies)) { - /* Units check: - chars * (bits/char) * (jiffies /sec) / (bits/sec) = jiffies! - check! */ - - charsleft += 16; /* Allow 16 chars more to be transmitted ... */ - jiffies_to_transmit = port->baud?(1 + charsleft * 10 * HZ / port->baud):0; - /* ^^^ Round up.... */ - if (jiffies_to_transmit <= 0) jiffies_to_transmit = 1; - - gs_dprintk (GS_DEBUG_FLUSH, "Expect to finish in %d jiffies " - "(%d chars).\n", jiffies_to_transmit, charsleft); - - msleep_interruptible(jiffies_to_msecs(jiffies_to_transmit)); - if (signal_pending (current)) { - gs_dprintk (GS_DEBUG_FLUSH, "Signal pending. Bombing out: "); - rv = -EINTR; - break; - } - } - - gs_dprintk (GS_DEBUG_FLUSH, "charsleft = %d.\n", charsleft); - set_current_state (TASK_RUNNING); - - func_exit(); - return rv; -} - - - -void gs_flush_buffer(struct tty_struct *tty) -{ - struct gs_port *port; - unsigned long flags; - - func_enter (); - - port = tty->driver_data; - - if (!port) return; - - /* XXX Would the write semaphore do? */ - spin_lock_irqsave (&port->driver_lock, flags); - port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; - spin_unlock_irqrestore (&port->driver_lock, flags); - - tty_wakeup(tty); - func_exit (); -} - - -void gs_flush_chars(struct tty_struct * tty) -{ - struct gs_port *port; - - func_enter (); - - port = tty->driver_data; - - if (!port) return; - - if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || - !port->xmit_buf) { - func_exit (); - return; - } - - /* Beats me -- REW */ - port->port.flags |= GS_TX_INTEN; - port->rd->enable_tx_interrupts (port); - func_exit (); -} - - -void gs_stop(struct tty_struct * tty) -{ - struct gs_port *port; - - func_enter (); - - port = tty->driver_data; - - if (!port) return; - - if (port->xmit_cnt && - port->xmit_buf && - (port->port.flags & GS_TX_INTEN) ) { - port->port.flags &= ~GS_TX_INTEN; - port->rd->disable_tx_interrupts (port); - } - func_exit (); -} - - -void gs_start(struct tty_struct * tty) -{ - struct gs_port *port; - - port = tty->driver_data; - - if (!port) return; - - if (port->xmit_cnt && - port->xmit_buf && - !(port->port.flags & GS_TX_INTEN) ) { - port->port.flags |= GS_TX_INTEN; - port->rd->enable_tx_interrupts (port); - } - func_exit (); -} - - -static void gs_shutdown_port (struct gs_port *port) -{ - unsigned long flags; - - func_enter(); - - if (!port) return; - - if (!(port->port.flags & ASYNC_INITIALIZED)) - return; - - spin_lock_irqsave(&port->driver_lock, flags); - - if (port->xmit_buf) { - free_page((unsigned long) port->xmit_buf); - port->xmit_buf = NULL; - } - - if (port->port.tty) - set_bit(TTY_IO_ERROR, &port->port.tty->flags); - - port->rd->shutdown_port (port); - - port->port.flags &= ~ASYNC_INITIALIZED; - spin_unlock_irqrestore(&port->driver_lock, flags); - - func_exit(); -} - - -void gs_hangup(struct tty_struct *tty) -{ - struct gs_port *port; - unsigned long flags; - - func_enter (); - - port = tty->driver_data; - tty = port->port.tty; - if (!tty) - return; - - gs_shutdown_port (port); - spin_lock_irqsave(&port->port.lock, flags); - port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|GS_ACTIVE); - port->port.tty = NULL; - port->port.count = 0; - spin_unlock_irqrestore(&port->port.lock, flags); - - wake_up_interruptible(&port->port.open_wait); - func_exit (); -} - - -int gs_block_til_ready(void *port_, struct file * filp) -{ - struct gs_port *gp = port_; - struct tty_port *port = &gp->port; - DECLARE_WAITQUEUE(wait, current); - int retval; - int do_clocal = 0; - int CD; - struct tty_struct *tty; - unsigned long flags; - - func_enter (); - - if (!port) return 0; - - tty = port->tty; - - gs_dprintk (GS_DEBUG_BTR, "Entering gs_block_till_ready.\n"); - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { - interruptible_sleep_on(&port->close_wait); - if (port->flags & ASYNC_HUP_NOTIFY) - return -EAGAIN; - else - return -ERESTARTSYS; - } - - gs_dprintk (GS_DEBUG_BTR, "after hung up\n"); - - /* - * If non-blocking mode is set, or the port is not enabled, - * then make the check up front and then exit. - */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR))) { - port->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - gs_dprintk (GS_DEBUG_BTR, "after nonblock\n"); - - if (C_CLOCAL(tty)) - do_clocal = 1; - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, port->count is dropped by one, so that - * rs_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; - - add_wait_queue(&port->open_wait, &wait); - - gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n"); - spin_lock_irqsave(&port->lock, flags); - if (!tty_hung_up_p(filp)) { - port->count--; - } - port->blocked_open++; - spin_unlock_irqrestore(&port->lock, flags); - while (1) { - CD = tty_port_carrier_raised(port); - gs_dprintk (GS_DEBUG_BTR, "CD is now %d.\n", CD); - set_current_state (TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !(port->flags & ASYNC_INITIALIZED)) { - if (port->flags & ASYNC_HUP_NOTIFY) - retval = -EAGAIN; - else - retval = -ERESTARTSYS; - break; - } - if (!(port->flags & ASYNC_CLOSING) && - (do_clocal || CD)) - break; - gs_dprintk (GS_DEBUG_BTR, "signal_pending is now: %d (%lx)\n", - (int)signal_pending (current), *(long*)(¤t->blocked)); - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } - schedule(); - } - gs_dprintk (GS_DEBUG_BTR, "Got out of the loop. (%d)\n", - port->blocked_open); - set_current_state (TASK_RUNNING); - remove_wait_queue(&port->open_wait, &wait); - - spin_lock_irqsave(&port->lock, flags); - if (!tty_hung_up_p(filp)) { - port->count++; - } - port->blocked_open--; - if (retval == 0) - port->flags |= ASYNC_NORMAL_ACTIVE; - spin_unlock_irqrestore(&port->lock, flags); - func_exit (); - return retval; -} - - -void gs_close(struct tty_struct * tty, struct file * filp) -{ - unsigned long flags; - struct gs_port *port; - - func_enter (); - - port = tty->driver_data; - - if (!port) return; - - if (!port->port.tty) { - /* This seems to happen when this is called from vhangup. */ - gs_dprintk (GS_DEBUG_CLOSE, "gs: Odd: port->port.tty is NULL\n"); - port->port.tty = tty; - } - - spin_lock_irqsave(&port->port.lock, flags); - - if (tty_hung_up_p(filp)) { - spin_unlock_irqrestore(&port->port.lock, flags); - if (port->rd->hungup) - port->rd->hungup (port); - func_exit (); - return; - } - - if ((tty->count == 1) && (port->port.count != 1)) { - printk(KERN_ERR "gs: gs_close port %p: bad port count;" - " tty->count is 1, port count is %d\n", port, port->port.count); - port->port.count = 1; - } - if (--port->port.count < 0) { - printk(KERN_ERR "gs: gs_close port %p: bad port count: %d\n", port, port->port.count); - port->port.count = 0; - } - - if (port->port.count) { - gs_dprintk(GS_DEBUG_CLOSE, "gs_close port %p: count: %d\n", port, port->port.count); - spin_unlock_irqrestore(&port->port.lock, flags); - func_exit (); - return; - } - port->port.flags |= ASYNC_CLOSING; - - /* - * Now we wait for the transmit buffer to clear; and we notify - * the line discipline to only process XON/XOFF characters. - */ - tty->closing = 1; - /* if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) - tty_wait_until_sent(tty, port->closing_wait); */ - - /* - * At this point we stop accepting input. To do this, we - * disable the receive line status interrupts, and tell the - * interrupt driver to stop checking the data ready bit in the - * line status register. - */ - - spin_lock_irqsave(&port->driver_lock, flags); - port->rd->disable_rx_interrupts (port); - spin_unlock_irqrestore(&port->driver_lock, flags); - spin_unlock_irqrestore(&port->port.lock, flags); - - /* close has no way of returning "EINTR", so discard return value */ - if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) - gs_wait_tx_flushed (port, port->closing_wait); - - port->port.flags &= ~GS_ACTIVE; - - gs_flush_buffer(tty); - - tty_ldisc_flush(tty); - tty->closing = 0; - - spin_lock_irqsave(&port->driver_lock, flags); - port->event = 0; - port->rd->close (port); - port->rd->shutdown_port (port); - spin_unlock_irqrestore(&port->driver_lock, flags); - - spin_lock_irqsave(&port->port.lock, flags); - port->port.tty = NULL; - - if (port->port.blocked_open) { - if (port->close_delay) { - spin_unlock_irqrestore(&port->port.lock, flags); - msleep_interruptible(jiffies_to_msecs(port->close_delay)); - spin_lock_irqsave(&port->port.lock, flags); - } - wake_up_interruptible(&port->port.open_wait); - } - port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING | ASYNC_INITIALIZED); - spin_unlock_irqrestore(&port->port.lock, flags); - wake_up_interruptible(&port->port.close_wait); - - func_exit (); -} - - -void gs_set_termios (struct tty_struct * tty, - struct ktermios * old_termios) -{ - struct gs_port *port; - int baudrate, tmp, rv; - struct ktermios *tiosp; - - func_enter(); - - port = tty->driver_data; - - if (!port) return; - if (!port->port.tty) { - /* This seems to happen when this is called after gs_close. */ - gs_dprintk (GS_DEBUG_TERMIOS, "gs: Odd: port->port.tty is NULL\n"); - port->port.tty = tty; - } - - - tiosp = tty->termios; - - if (gs_debug & GS_DEBUG_TERMIOS) { - gs_dprintk (GS_DEBUG_TERMIOS, "termios structure (%p):\n", tiosp); - } - - if(old_termios && (gs_debug & GS_DEBUG_TERMIOS)) { - if(tiosp->c_iflag != old_termios->c_iflag) printk("c_iflag changed\n"); - if(tiosp->c_oflag != old_termios->c_oflag) printk("c_oflag changed\n"); - if(tiosp->c_cflag != old_termios->c_cflag) printk("c_cflag changed\n"); - if(tiosp->c_lflag != old_termios->c_lflag) printk("c_lflag changed\n"); - if(tiosp->c_line != old_termios->c_line) printk("c_line changed\n"); - if(!memcmp(tiosp->c_cc, old_termios->c_cc, NCC)) printk("c_cc changed\n"); - } - - baudrate = tty_get_baud_rate(tty); - - if ((tiosp->c_cflag & CBAUD) == B38400) { - if ( (port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - baudrate = 57600; - else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - baudrate = 115200; - else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - baudrate = 230400; - else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - baudrate = 460800; - else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) - baudrate = (port->baud_base / port->custom_divisor); - } - - /* I recommend using THIS instead of the mess in termios (and - duplicating the above code). Next we should create a clean - interface towards this variable. If your card supports arbitrary - baud rates, (e.g. CD1400 or 16550 based cards) then everything - will be very easy..... */ - port->baud = baudrate; - - /* Two timer ticks seems enough to wakeup something like SLIP driver */ - /* Baudrate/10 is cps. Divide by HZ to get chars per tick. */ - tmp = (baudrate / 10 / HZ) * 2; - - if (tmp < 0) tmp = 0; - if (tmp >= SERIAL_XMIT_SIZE) tmp = SERIAL_XMIT_SIZE-1; - - port->wakeup_chars = tmp; - - /* We should really wait for the characters to be all sent before - changing the settings. -- CAL */ - rv = gs_wait_tx_flushed (port, MAX_SCHEDULE_TIMEOUT); - if (rv < 0) return /* rv */; - - rv = port->rd->set_real_termios(port); - if (rv < 0) return /* rv */; - - if ((!old_termios || - (old_termios->c_cflag & CRTSCTS)) && - !( tiosp->c_cflag & CRTSCTS)) { - tty->stopped = 0; - gs_start(tty); - } - -#ifdef tytso_patch_94Nov25_1726 - /* This "makes sense", Why is it commented out? */ - - if (!(old_termios->c_cflag & CLOCAL) && - (tty->termios->c_cflag & CLOCAL)) - wake_up_interruptible(&port->gs.open_wait); -#endif - - func_exit(); - return /* 0 */; -} - - - -/* Must be called with interrupts enabled */ -int gs_init_port(struct gs_port *port) -{ - unsigned long flags; - - func_enter (); - - if (port->port.flags & ASYNC_INITIALIZED) { - func_exit (); - return 0; - } - if (!port->xmit_buf) { - /* We may sleep in get_zeroed_page() */ - unsigned long tmp; - - tmp = get_zeroed_page(GFP_KERNEL); - spin_lock_irqsave (&port->driver_lock, flags); - if (port->xmit_buf) - free_page (tmp); - else - port->xmit_buf = (unsigned char *) tmp; - spin_unlock_irqrestore(&port->driver_lock, flags); - if (!port->xmit_buf) { - func_exit (); - return -ENOMEM; - } - } - - spin_lock_irqsave (&port->driver_lock, flags); - if (port->port.tty) - clear_bit(TTY_IO_ERROR, &port->port.tty->flags); - mutex_init(&port->port_write_mutex); - port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; - spin_unlock_irqrestore(&port->driver_lock, flags); - gs_set_termios(port->port.tty, NULL); - spin_lock_irqsave (&port->driver_lock, flags); - port->port.flags |= ASYNC_INITIALIZED; - port->port.flags &= ~GS_TX_INTEN; - - spin_unlock_irqrestore(&port->driver_lock, flags); - func_exit (); - return 0; -} - - -int gs_setserial(struct gs_port *port, struct serial_struct __user *sp) -{ - struct serial_struct sio; - - if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) - return(-EFAULT); - - if (!capable(CAP_SYS_ADMIN)) { - if ((sio.baud_base != port->baud_base) || - (sio.close_delay != port->close_delay) || - ((sio.flags & ~ASYNC_USR_MASK) != - (port->port.flags & ~ASYNC_USR_MASK))) - return(-EPERM); - } - - port->port.flags = (port->port.flags & ~ASYNC_USR_MASK) | - (sio.flags & ASYNC_USR_MASK); - - port->baud_base = sio.baud_base; - port->close_delay = sio.close_delay; - port->closing_wait = sio.closing_wait; - port->custom_divisor = sio.custom_divisor; - - gs_set_termios (port->port.tty, NULL); - - return 0; -} - - -/*****************************************************************************/ - -/* - * Generate the serial struct info. - */ - -int gs_getserial(struct gs_port *port, struct serial_struct __user *sp) -{ - struct serial_struct sio; - - memset(&sio, 0, sizeof(struct serial_struct)); - sio.flags = port->port.flags; - sio.baud_base = port->baud_base; - sio.close_delay = port->close_delay; - sio.closing_wait = port->closing_wait; - sio.custom_divisor = port->custom_divisor; - sio.hub6 = 0; - - /* If you want you can override these. */ - sio.type = PORT_UNKNOWN; - sio.xmit_fifo_size = -1; - sio.line = -1; - sio.port = -1; - sio.irq = -1; - - if (port->rd->getserial) - port->rd->getserial (port, &sio); - - if (copy_to_user(sp, &sio, sizeof(struct serial_struct))) - return -EFAULT; - return 0; - -} - - -void gs_got_break(struct gs_port *port) -{ - func_enter (); - - tty_insert_flip_char(port->port.tty, 0, TTY_BREAK); - tty_schedule_flip(port->port.tty); - if (port->port.flags & ASYNC_SAK) { - do_SAK (port->port.tty); - } - - func_exit (); -} - - -EXPORT_SYMBOL(gs_put_char); -EXPORT_SYMBOL(gs_write); -EXPORT_SYMBOL(gs_write_room); -EXPORT_SYMBOL(gs_chars_in_buffer); -EXPORT_SYMBOL(gs_flush_buffer); -EXPORT_SYMBOL(gs_flush_chars); -EXPORT_SYMBOL(gs_stop); -EXPORT_SYMBOL(gs_start); -EXPORT_SYMBOL(gs_hangup); -EXPORT_SYMBOL(gs_block_til_ready); -EXPORT_SYMBOL(gs_close); -EXPORT_SYMBOL(gs_set_termios); -EXPORT_SYMBOL(gs_init_port); -EXPORT_SYMBOL(gs_setserial); -EXPORT_SYMBOL(gs_getserial); -EXPORT_SYMBOL(gs_got_break); - -MODULE_LICENSE("GPL"); diff --git a/drivers/char/rio/Makefile b/drivers/char/rio/Makefile deleted file mode 100644 index 1661875883fb..000000000000 --- a/drivers/char/rio/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# Makefile for the linux rio-subsystem. -# -# (C) R.E.Wolff@BitWizard.nl -# -# This file is GPL. See other files for the full Blurb. I'm lazy today. -# - -obj-$(CONFIG_RIO) += rio.o - -rio-y := rio_linux.o rioinit.o rioboot.o riocmd.o rioctrl.o riointr.o \ - rioparam.o rioroute.o riotable.o riotty.o diff --git a/drivers/char/rio/board.h b/drivers/char/rio/board.h deleted file mode 100644 index bdea633a9076..000000000000 --- a/drivers/char/rio/board.h +++ /dev/null @@ -1,132 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : board.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:07 -** Retrieved : 11/6/98 11:34:20 -** -** ident @(#)board.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_board_h__ -#define __rio_board_h__ - -/* -** board.h contains the definitions for the *hardware* of the host cards. -** It describes the memory overlay for the dual port RAM area. -*/ - -#define DP_SRAM1_SIZE 0x7C00 -#define DP_SRAM2_SIZE 0x0200 -#define DP_SRAM3_SIZE 0x7000 -#define DP_SCRATCH_SIZE 0x1000 -#define DP_PARMMAP_ADDR 0x01FE /* offset into SRAM2 */ -#define DP_STARTUP_ADDR 0x01F8 /* offset into SRAM2 */ - -/* -** The shape of the Host Control area, at offset 0x7C00, Write Only -*/ -struct s_Ctrl { - u8 DpCtl; /* 7C00 */ - u8 Dp_Unused2_[127]; - u8 DpIntSet; /* 7C80 */ - u8 Dp_Unused3_[127]; - u8 DpTpuReset; /* 7D00 */ - u8 Dp_Unused4_[127]; - u8 DpIntReset; /* 7D80 */ - u8 Dp_Unused5_[127]; -}; - -/* -** The PROM data area on the host (0x7C00), Read Only -*/ -struct s_Prom { - u16 DpSlxCode[2]; - u16 DpRev; - u16 Dp_Unused6_; - u16 DpUniq[4]; - u16 DpJahre; - u16 DpWoche; - u16 DpHwFeature[5]; - u16 DpOemId; - u16 DpSiggy[16]; -}; - -/* -** Union of the Ctrl and Prom areas -*/ -union u_CtrlProm { /* This is the control/PROM area (0x7C00) */ - struct s_Ctrl DpCtrl; - struct s_Prom DpProm; -}; - -/* -** The top end of memory! -*/ -struct s_ParmMapS { /* Area containing Parm Map Pointer */ - u8 Dp_Unused8_[DP_PARMMAP_ADDR]; - u16 DpParmMapAd; -}; - -struct s_StartUpS { - u8 Dp_Unused9_[DP_STARTUP_ADDR]; - u8 Dp_LongJump[0x4]; - u8 Dp_Unused10_[2]; - u8 Dp_ShortJump[0x2]; -}; - -union u_Sram2ParmMap { /* This is the top of memory (0x7E00-0x7FFF) */ - u8 DpSramMem[DP_SRAM2_SIZE]; - struct s_ParmMapS DpParmMapS; - struct s_StartUpS DpStartUpS; -}; - -/* -** This is the DP RAM overlay. -*/ -struct DpRam { - u8 DpSram1[DP_SRAM1_SIZE]; /* 0000 - 7BFF */ - union u_CtrlProm DpCtrlProm; /* 7C00 - 7DFF */ - union u_Sram2ParmMap DpSram2ParmMap; /* 7E00 - 7FFF */ - u8 DpScratch[DP_SCRATCH_SIZE]; /* 8000 - 8FFF */ - u8 DpSram3[DP_SRAM3_SIZE]; /* 9000 - FFFF */ -}; - -#define DpControl DpCtrlProm.DpCtrl.DpCtl -#define DpSetInt DpCtrlProm.DpCtrl.DpIntSet -#define DpResetTpu DpCtrlProm.DpCtrl.DpTpuReset -#define DpResetInt DpCtrlProm.DpCtrl.DpIntReset - -#define DpSlx DpCtrlProm.DpProm.DpSlxCode -#define DpRevision DpCtrlProm.DpProm.DpRev -#define DpUnique DpCtrlProm.DpProm.DpUniq -#define DpYear DpCtrlProm.DpProm.DpJahre -#define DpWeek DpCtrlProm.DpProm.DpWoche -#define DpSignature DpCtrlProm.DpProm.DpSiggy - -#define DpParmMapR DpSram2ParmMap.DpParmMapS.DpParmMapAd -#define DpSram2 DpSram2ParmMap.DpSramMem - -#endif diff --git a/drivers/char/rio/cirrus.h b/drivers/char/rio/cirrus.h deleted file mode 100644 index 5ab51679caa2..000000000000 --- a/drivers/char/rio/cirrus.h +++ /dev/null @@ -1,210 +0,0 @@ -/**************************************************************************** - ******* ******* - ******* CIRRUS.H ******* - ******* ******* - **************************************************************************** - - Author : Jeremy Rolls - Date : 3 Aug 1990 - - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - Version : 0.01 - - - Mods - ---------------------------------------------------------------------------- - Date By Description - ---------------------------------------------------------------------------- - - ***************************************************************************/ - -#ifndef _cirrus_h -#define _cirrus_h 1 - -/* Bit fields for particular registers shared with driver */ - -/* COR1 - driver and RTA */ -#define RIOC_COR1_ODD 0x80 /* Odd parity */ -#define RIOC_COR1_EVEN 0x00 /* Even parity */ -#define RIOC_COR1_NOP 0x00 /* No parity */ -#define RIOC_COR1_FORCE 0x20 /* Force parity */ -#define RIOC_COR1_NORMAL 0x40 /* With parity */ -#define RIOC_COR1_1STOP 0x00 /* 1 stop bit */ -#define RIOC_COR1_15STOP 0x04 /* 1.5 stop bits */ -#define RIOC_COR1_2STOP 0x08 /* 2 stop bits */ -#define RIOC_COR1_5BITS 0x00 /* 5 data bits */ -#define RIOC_COR1_6BITS 0x01 /* 6 data bits */ -#define RIOC_COR1_7BITS 0x02 /* 7 data bits */ -#define RIOC_COR1_8BITS 0x03 /* 8 data bits */ - -#define RIOC_COR1_HOST 0xef /* Safe host bits */ - -/* RTA only */ -#define RIOC_COR1_CINPCK 0x00 /* Check parity of received characters */ -#define RIOC_COR1_CNINPCK 0x10 /* Don't check parity */ - -/* COR2 bits for both RTA and driver use */ -#define RIOC_COR2_IXANY 0x80 /* IXANY - any character is XON */ -#define RIOC_COR2_IXON 0x40 /* IXON - enable tx soft flowcontrol */ -#define RIOC_COR2_RTSFLOW 0x02 /* Enable tx hardware flow control */ - -/* Additional driver bits */ -#define RIOC_COR2_HUPCL 0x20 /* Hang up on close */ -#define RIOC_COR2_CTSFLOW 0x04 /* Enable rx hardware flow control */ -#define RIOC_COR2_IXOFF 0x01 /* Enable rx software flow control */ -#define RIOC_COR2_DTRFLOW 0x08 /* Enable tx hardware flow control */ - -/* RTA use only */ -#define RIOC_COR2_ETC 0x20 /* Embedded transmit options */ -#define RIOC_COR2_LOCAL 0x10 /* Local loopback mode */ -#define RIOC_COR2_REMOTE 0x08 /* Remote loopback mode */ -#define RIOC_COR2_HOST 0xc2 /* Safe host bits */ - -/* COR3 - RTA use only */ -#define RIOC_COR3_SCDRNG 0x80 /* Enable special char detect for range */ -#define RIOC_COR3_SCD34 0x40 /* Special character detect for SCHR's 3 + 4 */ -#define RIOC_COR3_FCT 0x20 /* Flow control transparency */ -#define RIOC_COR3_SCD12 0x10 /* Special character detect for SCHR's 1 + 2 */ -#define RIOC_COR3_FIFO12 0x0c /* 12 chars for receive FIFO threshold */ -#define RIOC_COR3_FIFO10 0x0a /* 10 chars for receive FIFO threshold */ -#define RIOC_COR3_FIFO8 0x08 /* 8 chars for receive FIFO threshold */ -#define RIOC_COR3_FIFO6 0x06 /* 6 chars for receive FIFO threshold */ - -#define RIOC_COR3_THRESHOLD RIOC_COR3_FIFO8 /* MUST BE LESS THAN MCOR_THRESHOLD */ - -#define RIOC_COR3_DEFAULT (RIOC_COR3_FCT | RIOC_COR3_THRESHOLD) - /* Default bits for COR3 */ - -/* COR4 driver and RTA use */ -#define RIOC_COR4_IGNCR 0x80 /* Throw away CR's on input */ -#define RIOC_COR4_ICRNL 0x40 /* Map CR -> NL on input */ -#define RIOC_COR4_INLCR 0x20 /* Map NL -> CR on input */ -#define RIOC_COR4_IGNBRK 0x10 /* Ignore Break */ -#define RIOC_COR4_NBRKINT 0x08 /* No interrupt on break (-BRKINT) */ -#define RIOC_COR4_RAISEMOD 0x01 /* Raise modem output lines on non-zero baud */ - - -/* COR4 driver only */ -#define RIOC_COR4_IGNPAR 0x04 /* IGNPAR (ignore characters with errors) */ -#define RIOC_COR4_PARMRK 0x02 /* PARMRK */ - -#define RIOC_COR4_HOST 0xf8 /* Safe host bits */ - -/* COR4 RTA only */ -#define RIOC_COR4_CIGNPAR 0x02 /* Thrown away bad characters */ -#define RIOC_COR4_CPARMRK 0x04 /* PARMRK characters */ -#define RIOC_COR4_CNPARMRK 0x03 /* Don't PARMRK */ - -/* COR5 driver and RTA use */ -#define RIOC_COR5_ISTRIP 0x80 /* Strip input chars to 7 bits */ -#define RIOC_COR5_LNE 0x40 /* Enable LNEXT processing */ -#define RIOC_COR5_CMOE 0x20 /* Match good and errored characters */ -#define RIOC_COR5_ONLCR 0x02 /* NL -> CR NL on output */ -#define RIOC_COR5_OCRNL 0x01 /* CR -> NL on output */ - -/* -** Spare bits - these are not used in the CIRRUS registers, so we use -** them to set various other features. -*/ -/* -** tstop and tbusy indication -*/ -#define RIOC_COR5_TSTATE_ON 0x08 /* Turn on monitoring of tbusy and tstop */ -#define RIOC_COR5_TSTATE_OFF 0x04 /* Turn off monitoring of tbusy and tstop */ -/* -** TAB3 -*/ -#define RIOC_COR5_TAB3 0x10 /* TAB3 mode */ - -#define RIOC_COR5_HOST 0xc3 /* Safe host bits */ - -/* CCSR */ -#define RIOC_CCSR_TXFLOFF 0x04 /* Tx is xoffed */ - -/* MSVR1 */ -/* NB. DTR / CD swapped from Cirrus spec as the pins are also reversed on the - RTA. This is because otherwise DCD would get lost on the 1 parallel / 3 - serial option. -*/ -#define RIOC_MSVR1_CD 0x80 /* CD (DSR on Cirrus) */ -#define RIOC_MSVR1_RTS 0x40 /* RTS (CTS on Cirrus) */ -#define RIOC_MSVR1_RI 0x20 /* RI */ -#define RIOC_MSVR1_DTR 0x10 /* DTR (CD on Cirrus) */ -#define RIOC_MSVR1_CTS 0x01 /* CTS output pin (RTS on Cirrus) */ -/* Next two used to indicate state of tbusy and tstop to driver */ -#define RIOC_MSVR1_TSTOP 0x08 /* Set if port flow controlled */ -#define RIOC_MSVR1_TEMPTY 0x04 /* Set if port tx buffer empty */ - -#define RIOC_MSVR1_HOST 0xf3 /* The bits the host wants */ - -/* Defines for the subscripts of a CONFIG packet */ -#define RIOC_CONFIG_COR1 1 /* Option register 1 */ -#define RIOC_CONFIG_COR2 2 /* Option register 2 */ -#define RIOC_CONFIG_COR4 3 /* Option register 4 */ -#define RIOC_CONFIG_COR5 4 /* Option register 5 */ -#define RIOC_CONFIG_TXXON 5 /* Tx XON character */ -#define RIOC_CONFIG_TXXOFF 6 /* Tx XOFF character */ -#define RIOC_CONFIG_RXXON 7 /* Rx XON character */ -#define RIOC_CONFIG_RXXOFF 8 /* Rx XOFF character */ -#define RIOC_CONFIG_LNEXT 9 /* LNEXT character */ -#define RIOC_CONFIG_TXBAUD 10 /* Tx baud rate */ -#define RIOC_CONFIG_RXBAUD 11 /* Rx baud rate */ - -#define RIOC_PRE_EMPTIVE 0x80 /* Pre-emptive bit in command field */ - -/* Packet types going from Host to remote - with the exception of OPEN, MOPEN, - CONFIG, SBREAK and MEMDUMP the remaining bytes of the data array will not - be used -*/ -#define RIOC_OPEN 0x00 /* Open a port */ -#define RIOC_CONFIG 0x01 /* Configure a port */ -#define RIOC_MOPEN 0x02 /* Modem open (block for DCD) */ -#define RIOC_CLOSE 0x03 /* Close a port */ -#define RIOC_WFLUSH (0x04 | RIOC_PRE_EMPTIVE) /* Write flush */ -#define RIOC_RFLUSH (0x05 | RIOC_PRE_EMPTIVE) /* Read flush */ -#define RIOC_RESUME (0x06 | RIOC_PRE_EMPTIVE) /* Resume if xoffed */ -#define RIOC_SBREAK 0x07 /* Start break */ -#define RIOC_EBREAK 0x08 /* End break */ -#define RIOC_SUSPEND (0x09 | RIOC_PRE_EMPTIVE) /* Susp op (behave as tho xoffed) */ -#define RIOC_FCLOSE (0x0a | RIOC_PRE_EMPTIVE) /* Force close */ -#define RIOC_XPRINT 0x0b /* Xprint packet */ -#define RIOC_MBIS (0x0c | RIOC_PRE_EMPTIVE) /* Set modem lines */ -#define RIOC_MBIC (0x0d | RIOC_PRE_EMPTIVE) /* Clear modem lines */ -#define RIOC_MSET (0x0e | RIOC_PRE_EMPTIVE) /* Set modem lines */ -#define RIOC_PCLOSE 0x0f /* Pseudo close - Leaves rx/tx enabled */ -#define RIOC_MGET (0x10 | RIOC_PRE_EMPTIVE) /* Force update of modem status */ -#define RIOC_MEMDUMP (0x11 | RIOC_PRE_EMPTIVE) /* Send back mem from addr supplied */ -#define RIOC_READ_REGISTER (0x12 | RIOC_PRE_EMPTIVE) /* Read CD1400 register (debug) */ - -/* "Command" packets going from remote to host COMPLETE and MODEM_STATUS - use data[4] / data[3] to indicate current state and modem status respectively -*/ - -#define RIOC_COMPLETE (0x20 | RIOC_PRE_EMPTIVE) - /* Command complete */ -#define RIOC_BREAK_RECEIVED (0x21 | RIOC_PRE_EMPTIVE) - /* Break received */ -#define RIOC_MODEM_STATUS (0x22 | RIOC_PRE_EMPTIVE) - /* Change in modem status */ - -/* "Command" packet that could go either way - handshake wake-up */ -#define RIOC_HANDSHAKE (0x23 | RIOC_PRE_EMPTIVE) - /* Wake-up to HOST / RTA */ - -#endif diff --git a/drivers/char/rio/cmdblk.h b/drivers/char/rio/cmdblk.h deleted file mode 100644 index 9ed4f861675a..000000000000 --- a/drivers/char/rio/cmdblk.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : cmdblk.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:09 -** Retrieved : 11/6/98 11:34:20 -** -** ident @(#)cmdblk.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_cmdblk_h__ -#define __rio_cmdblk_h__ - -/* -** the structure of a command block, used to queue commands destined for -** a rup. -*/ - -struct CmdBlk { - struct CmdBlk *NextP; /* Pointer to next command block */ - struct PKT Packet; /* A packet, to copy to the rup */ - /* The func to call to check if OK */ - int (*PreFuncP) (unsigned long, struct CmdBlk *); - int PreArg; /* The arg for the func */ - /* The func to call when completed */ - int (*PostFuncP) (unsigned long, struct CmdBlk *); - int PostArg; /* The arg for the func */ -}; - -#define NUM_RIO_CMD_BLKS (3 * (MAX_RUP * 4 + LINKS_PER_UNIT * 4)) -#endif diff --git a/drivers/char/rio/cmdpkt.h b/drivers/char/rio/cmdpkt.h deleted file mode 100644 index c1e7a2798070..000000000000 --- a/drivers/char/rio/cmdpkt.h +++ /dev/null @@ -1,177 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : cmdpkt.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:09 -** Retrieved : 11/6/98 11:34:20 -** -** ident @(#)cmdpkt.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ -#ifndef __rio_cmdpkt_h__ -#define __rio_cmdpkt_h__ - -/* -** overlays for the data area of a packet. Used in both directions -** (to build a packet to send, and to interpret a packet that arrives) -** and is very inconvenient for MIPS, so they appear as two separate -** structures - those used for modifying/reading packets on the card -** and those for modifying/reading packets in real memory, which have an _M -** suffix. -*/ - -#define RTA_BOOT_DATA_SIZE (PKT_MAX_DATA_LEN-2) - -/* -** The boot information packet looks like this: -** This structure overlays a PktCmd->CmdData structure, and so starts -** at Data[2] in the actual pkt! -*/ -struct BootSequence { - u16 NumPackets; - u16 LoadBase; - u16 CodeSize; -}; - -#define BOOT_SEQUENCE_LEN 8 - -struct SamTop { - u8 Unit; - u8 Link; -}; - -struct CmdHdr { - u8 PcCommand; - union { - u8 PcPhbNum; - u8 PcLinkNum; - u8 PcIDNum; - } U0; -}; - - -struct PktCmd { - union { - struct { - struct CmdHdr CmdHdr; - struct BootSequence PcBootSequence; - } S1; - struct { - u16 PcSequence; - u8 PcBootData[RTA_BOOT_DATA_SIZE]; - } S2; - struct { - u16 __crud__; - u8 PcUniqNum[4]; /* this is really a uint. */ - u8 PcModuleTypes; /* what modules are fitted */ - } S3; - struct { - struct CmdHdr CmdHdr; - u8 __undefined__; - u8 PcModemStatus; - u8 PcPortStatus; - u8 PcSubCommand; /* commands like mem or register dump */ - u16 PcSubAddr; /* Address for command */ - u8 PcSubData[64]; /* Date area for command */ - } S4; - struct { - struct CmdHdr CmdHdr; - u8 PcCommandText[1]; - u8 __crud__[20]; - u8 PcIDNum2; /* It had to go somewhere! */ - } S5; - struct { - struct CmdHdr CmdHdr; - struct SamTop Topology[LINKS_PER_UNIT]; - } S6; - } U1; -}; - -struct PktCmd_M { - union { - struct { - struct { - u8 PcCommand; - union { - u8 PcPhbNum; - u8 PcLinkNum; - u8 PcIDNum; - } U0; - } CmdHdr; - struct { - u16 NumPackets; - u16 LoadBase; - u16 CodeSize; - } PcBootSequence; - } S1; - struct { - u16 PcSequence; - u8 PcBootData[RTA_BOOT_DATA_SIZE]; - } S2; - struct { - u16 __crud__; - u8 PcUniqNum[4]; /* this is really a uint. */ - u8 PcModuleTypes; /* what modules are fitted */ - } S3; - struct { - u16 __cmd_hdr__; - u8 __undefined__; - u8 PcModemStatus; - u8 PcPortStatus; - u8 PcSubCommand; - u16 PcSubAddr; - u8 PcSubData[64]; - } S4; - struct { - u16 __cmd_hdr__; - u8 PcCommandText[1]; - u8 __crud__[20]; - u8 PcIDNum2; /* Tacked on end */ - } S5; - struct { - u16 __cmd_hdr__; - struct Top Topology[LINKS_PER_UNIT]; - } S6; - } U1; -}; - -#define Command U1.S1.CmdHdr.PcCommand -#define PhbNum U1.S1.CmdHdr.U0.PcPhbNum -#define IDNum U1.S1.CmdHdr.U0.PcIDNum -#define IDNum2 U1.S5.PcIDNum2 -#define LinkNum U1.S1.CmdHdr.U0.PcLinkNum -#define Sequence U1.S2.PcSequence -#define BootData U1.S2.PcBootData -#define BootSequence U1.S1.PcBootSequence -#define UniqNum U1.S3.PcUniqNum -#define ModemStatus U1.S4.PcModemStatus -#define PortStatus U1.S4.PcPortStatus -#define SubCommand U1.S4.PcSubCommand -#define SubAddr U1.S4.PcSubAddr -#define SubData U1.S4.PcSubData -#define CommandText U1.S5.PcCommandText -#define RouteTopology U1.S6.Topology -#define ModuleTypes U1.S3.PcModuleTypes - -#endif diff --git a/drivers/char/rio/daemon.h b/drivers/char/rio/daemon.h deleted file mode 100644 index 4af90323fd00..000000000000 --- a/drivers/char/rio/daemon.h +++ /dev/null @@ -1,307 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : daemon.h -** SID : 1.3 -** Last Modified : 11/6/98 11:34:09 -** Retrieved : 11/6/98 11:34:21 -** -** ident @(#)daemon.h 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_daemon_h__ -#define __rio_daemon_h__ - - -/* -** structures used on /dev/rio -*/ - -struct Error { - unsigned int Error; - unsigned int Entry; - unsigned int Other; -}; - -struct DownLoad { - char __user *DataP; - unsigned int Count; - unsigned int ProductCode; -}; - -/* -** A few constants.... -*/ -#ifndef MAX_VERSION_LEN -#define MAX_VERSION_LEN 256 -#endif - -#ifndef MAX_XP_CTRL_LEN -#define MAX_XP_CTRL_LEN 16 /* ALSO IN PORT.H */ -#endif - -struct PortSetup { - unsigned int From; /* Set/Clear XP & IXANY Control from this port.... */ - unsigned int To; /* .... to this port */ - unsigned int XpCps; /* at this speed */ - char XpOn[MAX_XP_CTRL_LEN]; /* this is the start string */ - char XpOff[MAX_XP_CTRL_LEN]; /* this is the stop string */ - u8 IxAny; /* enable/disable IXANY */ - u8 IxOn; /* enable/disable IXON */ - u8 Lock; /* lock port params */ - u8 Store; /* store params across closes */ - u8 Drain; /* close only when drained */ -}; - -struct LpbReq { - unsigned int Host; - unsigned int Link; - struct LPB __user *LpbP; -}; - -struct RupReq { - unsigned int HostNum; - unsigned int RupNum; - struct RUP __user *RupP; -}; - -struct PortReq { - unsigned int SysPort; - struct Port __user *PortP; -}; - -struct StreamInfo { - unsigned int SysPort; - int RQueue; - int WQueue; -}; - -struct HostReq { - unsigned int HostNum; - struct Host __user *HostP; -}; - -struct HostDpRam { - unsigned int HostNum; - struct DpRam __user *DpRamP; -}; - -struct DebugCtrl { - unsigned int SysPort; - unsigned int Debug; - unsigned int Wait; -}; - -struct MapInfo { - unsigned int FirstPort; /* 8 ports, starting from this (tty) number */ - unsigned int RtaUnique; /* reside on this RTA (unique number) */ -}; - -struct MapIn { - unsigned int NumEntries; /* How many port sets are we mapping? */ - struct MapInfo *MapInfoP; /* Pointer to (user space) info */ -}; - -struct SendPack { - unsigned int PortNum; - unsigned char Len; - unsigned char Data[PKT_MAX_DATA_LEN]; -}; - -struct SpecialRupCmd { - struct PKT Packet; - unsigned short Host; - unsigned short RupNum; -}; - -struct IdentifyRta { - unsigned long RtaUnique; - u8 ID; -}; - -struct KillNeighbour { - unsigned long UniqueNum; - u8 Link; -}; - -struct rioVersion { - char version[MAX_VERSION_LEN]; - char relid[MAX_VERSION_LEN]; - int buildLevel; - char buildDate[MAX_VERSION_LEN]; -}; - - -/* -** RIOC commands are for the daemon type operations -** -** 09.12.1998 ARG - ESIL 0776 part fix -** Definition for 'RIOC' also appears in rioioctl.h, so we'd better do a -** #ifndef here first. -** rioioctl.h also now has #define 'RIO_QUICK_CHECK' as this ioctl is now -** allowed to be used by customers. -*/ -#ifndef RIOC -#define RIOC ('R'<<8)|('i'<<16)|('o'<<24) -#endif - -/* -** Boot stuff -*/ -#define RIO_GET_TABLE (RIOC | 100) -#define RIO_PUT_TABLE (RIOC | 101) -#define RIO_ASSIGN_RTA (RIOC | 102) -#define RIO_DELETE_RTA (RIOC | 103) -#define RIO_HOST_FOAD (RIOC | 104) -#define RIO_QUICK_CHECK (RIOC | 105) -#define RIO_SIGNALS_ON (RIOC | 106) -#define RIO_SIGNALS_OFF (RIOC | 107) -#define RIO_CHANGE_NAME (RIOC | 108) -#define RIO_DOWNLOAD (RIOC | 109) -#define RIO_GET_LOG (RIOC | 110) -#define RIO_SETUP_PORTS (RIOC | 111) -#define RIO_ALL_MODEM (RIOC | 112) - -/* -** card state, debug stuff -*/ -#define RIO_NUM_HOSTS (RIOC | 120) -#define RIO_HOST_LPB (RIOC | 121) -#define RIO_HOST_RUP (RIOC | 122) -#define RIO_HOST_PORT (RIOC | 123) -#define RIO_PARMS (RIOC | 124) -#define RIO_HOST_REQ (RIOC | 125) -#define RIO_READ_CONFIG (RIOC | 126) -#define RIO_SET_CONFIG (RIOC | 127) -#define RIO_VERSID (RIOC | 128) -#define RIO_FLAGS (RIOC | 129) -#define RIO_SETDEBUG (RIOC | 130) -#define RIO_GETDEBUG (RIOC | 131) -#define RIO_READ_LEVELS (RIOC | 132) -#define RIO_SET_FAST_BUS (RIOC | 133) -#define RIO_SET_SLOW_BUS (RIOC | 134) -#define RIO_SET_BYTE_MODE (RIOC | 135) -#define RIO_SET_WORD_MODE (RIOC | 136) -#define RIO_STREAM_INFO (RIOC | 137) -#define RIO_START_POLLER (RIOC | 138) -#define RIO_STOP_POLLER (RIOC | 139) -#define RIO_LAST_ERROR (RIOC | 140) -#define RIO_TICK (RIOC | 141) -#define RIO_TOCK (RIOC | 241) /* I did this on purpose, you know. */ -#define RIO_SEND_PACKET (RIOC | 142) -#define RIO_SET_BUSY (RIOC | 143) -#define SPECIAL_RUP_CMD (RIOC | 144) -#define RIO_FOAD_RTA (RIOC | 145) -#define RIO_ZOMBIE_RTA (RIOC | 146) -#define RIO_IDENTIFY_RTA (RIOC | 147) -#define RIO_KILL_NEIGHBOUR (RIOC | 148) -#define RIO_DEBUG_MEM (RIOC | 149) -/* -** 150 - 167 used..... See below -*/ -#define RIO_GET_PORT_SETUP (RIOC | 168) -#define RIO_RESUME (RIOC | 169) -#define RIO_MESG (RIOC | 170) -#define RIO_NO_MESG (RIOC | 171) -#define RIO_WHAT_MESG (RIOC | 172) -#define RIO_HOST_DPRAM (RIOC | 173) -#define RIO_MAP_B50_TO_50 (RIOC | 174) -#define RIO_MAP_B50_TO_57600 (RIOC | 175) -#define RIO_MAP_B110_TO_110 (RIOC | 176) -#define RIO_MAP_B110_TO_115200 (RIOC | 177) -#define RIO_GET_PORT_PARAMS (RIOC | 178) -#define RIO_SET_PORT_PARAMS (RIOC | 179) -#define RIO_GET_PORT_TTY (RIOC | 180) -#define RIO_SET_PORT_TTY (RIOC | 181) -#define RIO_SYSLOG_ONLY (RIOC | 182) -#define RIO_SYSLOG_CONS (RIOC | 183) -#define RIO_CONS_ONLY (RIOC | 184) -#define RIO_BLOCK_OPENS (RIOC | 185) - -/* -** 02.03.1999 ARG - ESIL 0820 fix : -** RIOBootMode is no longer use by the driver, so these ioctls -** are now obsolete : -** -#define RIO_GET_BOOT_MODE (RIOC | 186) -#define RIO_SET_BOOT_MODE (RIOC | 187) -** -*/ - -#define RIO_MEM_DUMP (RIOC | 189) -#define RIO_READ_REGISTER (RIOC | 190) -#define RIO_GET_MODTYPE (RIOC | 191) -#define RIO_SET_TIMER (RIOC | 192) -#define RIO_READ_CHECK (RIOC | 196) -#define RIO_WAITING_FOR_RESTART (RIOC | 197) -#define RIO_BIND_RTA (RIOC | 198) -#define RIO_GET_BINDINGS (RIOC | 199) -#define RIO_PUT_BINDINGS (RIOC | 200) - -#define RIO_MAKE_DEV (RIOC | 201) -#define RIO_MINOR (RIOC | 202) - -#define RIO_IDENTIFY_DRIVER (RIOC | 203) -#define RIO_DISPLAY_HOST_CFG (RIOC | 204) - - -/* -** MAKE_DEV / MINOR stuff -*/ -#define RIO_DEV_DIRECT 0x0000 -#define RIO_DEV_MODEM 0x0200 -#define RIO_DEV_XPRINT 0x0400 -#define RIO_DEV_MASK 0x0600 - -/* -** port management, xprint stuff -*/ -#define rIOCN(N) (RIOC|(N)) -#define rIOCR(N,T) (RIOC|(N)) -#define rIOCW(N,T) (RIOC|(N)) - -#define RIO_GET_XP_ON rIOCR(150,char[16]) /* start xprint string */ -#define RIO_SET_XP_ON rIOCW(151,char[16]) -#define RIO_GET_XP_OFF rIOCR(152,char[16]) /* finish xprint string */ -#define RIO_SET_XP_OFF rIOCW(153,char[16]) -#define RIO_GET_XP_CPS rIOCR(154,int) /* xprint CPS */ -#define RIO_SET_XP_CPS rIOCW(155,int) -#define RIO_GET_IXANY rIOCR(156,int) /* ixany allowed? */ -#define RIO_SET_IXANY rIOCW(157,int) -#define RIO_SET_IXANY_ON rIOCN(158) /* allow ixany */ -#define RIO_SET_IXANY_OFF rIOCN(159) /* disallow ixany */ -#define RIO_GET_MODEM rIOCR(160,int) /* port is modem/direct line? */ -#define RIO_SET_MODEM rIOCW(161,int) -#define RIO_SET_MODEM_ON rIOCN(162) /* port is a modem */ -#define RIO_SET_MODEM_OFF rIOCN(163) /* port is direct */ -#define RIO_GET_IXON rIOCR(164,int) /* ixon allowed? */ -#define RIO_SET_IXON rIOCW(165,int) -#define RIO_SET_IXON_ON rIOCN(166) /* allow ixon */ -#define RIO_SET_IXON_OFF rIOCN(167) /* disallow ixon */ - -#define RIO_GET_SIVIEW ((('s')<<8) | 106) /* backwards compatible with SI */ - -#define RIO_IOCTL_UNKNOWN -2 - -#endif diff --git a/drivers/char/rio/errors.h b/drivers/char/rio/errors.h deleted file mode 100644 index bdb05234090a..000000000000 --- a/drivers/char/rio/errors.h +++ /dev/null @@ -1,98 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : errors.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:10 -** Retrieved : 11/6/98 11:34:21 -** -** ident @(#)errors.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_errors_h__ -#define __rio_errors_h__ - -/* -** error codes -*/ - -#define NOTHING_WRONG_AT_ALL 0 -#define BAD_CHARACTER_IN_NAME 1 -#define TABLE_ENTRY_ISNT_PROPERLY_NULL 2 -#define UNKNOWN_HOST_NUMBER 3 -#define ZERO_RTA_ID 4 -#define BAD_RTA_ID 5 -#define DUPLICATED_RTA_ID 6 -#define DUPLICATE_UNIQUE_NUMBER 7 -#define BAD_TTY_NUMBER 8 -#define TTY_NUMBER_IN_USE 9 -#define NAME_USED_TWICE 10 -#define HOST_ID_NOT_ZERO 11 -#define BOOT_IN_PROGRESS 12 -#define COPYIN_FAILED 13 -#define HOST_FILE_TOO_LARGE 14 -#define COPYOUT_FAILED 15 -#define NOT_SUPER_USER 16 -#define RIO_ALREADY_POLLING 17 - -#define ID_NUMBER_OUT_OF_RANGE 18 -#define PORT_NUMBER_OUT_OF_RANGE 19 -#define HOST_NUMBER_OUT_OF_RANGE 20 -#define RUP_NUMBER_OUT_OF_RANGE 21 -#define TTY_NUMBER_OUT_OF_RANGE 22 -#define LINK_NUMBER_OUT_OF_RANGE 23 - -#define HOST_NOT_RUNNING 24 -#define IOCTL_COMMAND_UNKNOWN 25 -#define RIO_SYSTEM_HALTED 26 -#define WAIT_FOR_DRAIN_BROKEN 27 -#define PORT_NOT_MAPPED_INTO_SYSTEM 28 -#define EXCLUSIVE_USE_SET 29 -#define WAIT_FOR_NOT_CLOSING_BROKEN 30 -#define WAIT_FOR_PORT_TO_OPEN_BROKEN 31 -#define WAIT_FOR_CARRIER_BROKEN 32 -#define WAIT_FOR_NOT_IN_USE_BROKEN 33 -#define WAIT_FOR_CAN_ADD_COMMAND_BROKEN 34 -#define WAIT_FOR_ADD_COMMAND_BROKEN 35 -#define WAIT_FOR_NOT_PARAM_BROKEN 36 -#define WAIT_FOR_RETRY_BROKEN 37 -#define HOST_HAS_ALREADY_BEEN_BOOTED 38 -#define UNIT_IS_IN_USE 39 -#define COULDNT_FIND_ENTRY 40 -#define RTA_UNIQUE_NUMBER_ZERO 41 -#define CLOSE_COMMAND_FAILED 42 -#define WAIT_FOR_CLOSE_BROKEN 43 -#define CPS_VALUE_OUT_OF_RANGE 44 -#define ID_ALREADY_IN_USE 45 -#define SIGNALS_ALREADY_SET 46 -#define NOT_RECEIVING_PROCESS 47 -#define RTA_NUMBER_WRONG 48 -#define NO_SUCH_PRODUCT 49 -#define HOST_SYSPORT_BAD 50 -#define ID_NOT_TENTATIVE 51 -#define XPRINT_CPS_OUT_OF_RANGE 52 -#define NOT_ENOUGH_CORE_FOR_PCI_COPY 53 - - -#endif /* __rio_errors_h__ */ diff --git a/drivers/char/rio/func.h b/drivers/char/rio/func.h deleted file mode 100644 index 078d44f85e45..000000000000 --- a/drivers/char/rio/func.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : func.h -** SID : 1.3 -** Last Modified : 11/6/98 11:34:10 -** Retrieved : 11/6/98 11:34:21 -** -** ident @(#)func.h 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __func_h_def -#define __func_h_def - -#include - -/* rioboot.c */ -int RIOBootCodeRTA(struct rio_info *, struct DownLoad *); -int RIOBootCodeHOST(struct rio_info *, struct DownLoad *); -int RIOBootCodeUNKNOWN(struct rio_info *, struct DownLoad *); -void msec_timeout(struct Host *); -int RIOBootRup(struct rio_info *, unsigned int, struct Host *, struct PKT __iomem *); -int RIOBootOk(struct rio_info *, struct Host *, unsigned long); -int RIORtaBound(struct rio_info *, unsigned int); -void rio_fill_host_slot(int, int, unsigned int, struct Host *); - -/* riocmd.c */ -int RIOFoadRta(struct Host *, struct Map *); -int RIOZombieRta(struct Host *, struct Map *); -int RIOCommandRta(struct rio_info *, unsigned long, int (*func) (struct Host *, struct Map *)); -int RIOIdentifyRta(struct rio_info *, void __user *); -int RIOKillNeighbour(struct rio_info *, void __user *); -int RIOSuspendBootRta(struct Host *, int, int); -int RIOFoadWakeup(struct rio_info *); -struct CmdBlk *RIOGetCmdBlk(void); -void RIOFreeCmdBlk(struct CmdBlk *); -int RIOQueueCmdBlk(struct Host *, unsigned int, struct CmdBlk *); -void RIOPollHostCommands(struct rio_info *, struct Host *); -int RIOWFlushMark(unsigned long, struct CmdBlk *); -int RIORFlushEnable(unsigned long, struct CmdBlk *); -int RIOUnUse(unsigned long, struct CmdBlk *); - -/* rioctrl.c */ -int riocontrol(struct rio_info *, dev_t, int, unsigned long, int); - -int RIOPreemptiveCmd(struct rio_info *, struct Port *, unsigned char); - -/* rioinit.c */ -void rioinit(struct rio_info *, struct RioHostInfo *); -void RIOInitHosts(struct rio_info *, struct RioHostInfo *); -void RIOISAinit(struct rio_info *, int); -int RIODoAT(struct rio_info *, int, int); -caddr_t RIOCheckForATCard(int); -int RIOAssignAT(struct rio_info *, int, void __iomem *, int); -int RIOBoardTest(unsigned long, void __iomem *, unsigned char, int); -void RIOAllocDataStructs(struct rio_info *); -void RIOSetupDataStructs(struct rio_info *); -int RIODefaultName(struct rio_info *, struct Host *, unsigned int); -struct rioVersion *RIOVersid(void); -void RIOHostReset(unsigned int, struct DpRam __iomem *, unsigned int); - -/* riointr.c */ -void RIOTxEnable(char *); -void RIOServiceHost(struct rio_info *, struct Host *); -int riotproc(struct rio_info *, struct ttystatics *, int, int); - -/* rioparam.c */ -int RIOParam(struct Port *, int, int, int); -int RIODelay(struct Port *PortP, int); -int RIODelay_ni(struct Port *PortP, int); -void ms_timeout(struct Port *); -int can_add_transmit(struct PKT __iomem **, struct Port *); -void add_transmit(struct Port *); -void put_free_end(struct Host *, struct PKT __iomem *); -int can_remove_receive(struct PKT __iomem **, struct Port *); -void remove_receive(struct Port *); - -/* rioroute.c */ -int RIORouteRup(struct rio_info *, unsigned int, struct Host *, struct PKT __iomem *); -void RIOFixPhbs(struct rio_info *, struct Host *, unsigned int); -unsigned int GetUnitType(unsigned int); -int RIOSetChange(struct rio_info *); -int RIOFindFreeID(struct rio_info *, struct Host *, unsigned int *, unsigned int *); - - -/* riotty.c */ - -int riotopen(struct tty_struct *tty, struct file *filp); -int riotclose(void *ptr); -int riotioctl(struct rio_info *, struct tty_struct *, int, caddr_t); -void ttyseth(struct Port *, struct ttystatics *, struct old_sgttyb *sg); - -/* riotable.c */ -int RIONewTable(struct rio_info *); -int RIOApel(struct rio_info *); -int RIODeleteRta(struct rio_info *, struct Map *); -int RIOAssignRta(struct rio_info *, struct Map *); -int RIOReMapPorts(struct rio_info *, struct Host *, struct Map *); -int RIOChangeName(struct rio_info *, struct Map *); - -#if 0 -/* riodrvr.c */ -struct rio_info *rio_install(struct RioHostInfo *); -int rio_uninstall(struct rio_info *); -int rio_open(struct rio_info *, int, struct file *); -int rio_close(struct rio_info *, struct file *); -int rio_read(struct rio_info *, struct file *, char *, int); -int rio_write(struct rio_info *, struct file *f, char *, int); -int rio_ioctl(struct rio_info *, struct file *, int, char *); -int rio_select(struct rio_info *, struct file *f, int, struct sel *); -int rio_intr(char *); -int rio_isr_thread(char *); -struct rio_info *rio_info_store(int cmd, struct rio_info *p); -#endif - -extern void rio_copy_to_card(void *from, void __iomem *to, int len); -extern int rio_minor(struct tty_struct *tty); -extern int rio_ismodem(struct tty_struct *tty); - -extern void rio_start_card_running(struct Host *HostP); - -#endif /* __func_h_def */ diff --git a/drivers/char/rio/host.h b/drivers/char/rio/host.h deleted file mode 100644 index 78f24540c224..000000000000 --- a/drivers/char/rio/host.h +++ /dev/null @@ -1,123 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : host.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:10 -** Retrieved : 11/6/98 11:34:21 -** -** ident @(#)host.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_host_h__ -#define __rio_host_h__ - -/* -** the host structure - one per host card in the system. -*/ - -#define MAX_EXTRA_UNITS 64 - -/* -** Host data structure. This is used for the software equiv. of -** the host. -*/ -struct Host { - struct pci_dev *pdev; - unsigned char Type; /* RIO_EISA, RIO_MCA, ... */ - unsigned char Ivec; /* POLLED or ivec number */ - unsigned char Mode; /* Control stuff */ - unsigned char Slot; /* Slot */ - void __iomem *Caddr; /* KV address of DPRAM */ - struct DpRam __iomem *CardP; /* KV address of DPRAM, with overlay */ - unsigned long PaddrP; /* Phys. address of DPRAM */ - char Name[MAX_NAME_LEN]; /* The name of the host */ - unsigned int UniqueNum; /* host unique number */ - spinlock_t HostLock; /* Lock structure for MPX */ - unsigned int WorkToBeDone; /* set to true each interrupt */ - unsigned int InIntr; /* Being serviced? */ - unsigned int IntSrvDone; /* host's interrupt has been serviced */ - void (*Copy) (void *, void __iomem *, int); /* copy func */ - struct timer_list timer; - /* - ** I M P O R T A N T ! - ** - ** The rest of this data structure is cleared to zero after - ** a RIO_HOST_FOAD command. - */ - - unsigned long Flags; /* Whats going down */ -#define RC_WAITING 0 -#define RC_STARTUP 1 -#define RC_RUNNING 2 -#define RC_STUFFED 3 -#define RC_READY 7 -#define RUN_STATE 7 -/* -** Boot mode applies to the way in which hosts in this system will -** boot RTAs -*/ -#define RC_BOOT_ALL 0x8 /* Boot all RTAs attached */ -#define RC_BOOT_OWN 0x10 /* Only boot RTAs bound to this system */ -#define RC_BOOT_NONE 0x20 /* Don't boot any RTAs (slave mode) */ - - struct Top Topology[LINKS_PER_UNIT]; /* one per link */ - struct Map Mapping[MAX_RUP]; /* Mappings for host */ - struct PHB __iomem *PhbP; /* Pointer to the PHB array */ - unsigned short __iomem *PhbNumP; /* Ptr to Number of PHB's */ - struct LPB __iomem *LinkStrP; /* Link Structure Array */ - struct RUP __iomem *RupP; /* Sixteen real rups here */ - struct PARM_MAP __iomem *ParmMapP; /* points to the parmmap */ - unsigned int ExtraUnits[MAX_EXTRA_UNITS]; /* unknown things */ - unsigned int NumExtraBooted; /* how many of the above */ - /* - ** Twenty logical rups. - ** The first sixteen are the real Rup entries (above), the last four - ** are the link RUPs. - */ - struct UnixRup UnixRups[MAX_RUP + LINKS_PER_UNIT]; - int timeout_id; /* For calling 100 ms delays */ - int timeout_sem; /* For calling 100 ms delays */ - unsigned long locks; /* long req'd for set_bit --RR */ - char ____end_marker____; -}; -#define Control CardP->DpControl -#define SetInt CardP->DpSetInt -#define ResetTpu CardP->DpResetTpu -#define ResetInt CardP->DpResetInt -#define Signature CardP->DpSignature -#define Sram1 CardP->DpSram1 -#define Sram2 CardP->DpSram2 -#define Sram3 CardP->DpSram3 -#define Scratch CardP->DpScratch -#define __ParmMapR CardP->DpParmMapR -#define SLX CardP->DpSlx -#define Revision CardP->DpRevision -#define Unique CardP->DpUnique -#define Year CardP->DpYear -#define Week CardP->DpWeek - -#define RIO_DUMBPARM 0x0860 /* what not to expect */ - -#endif diff --git a/drivers/char/rio/link.h b/drivers/char/rio/link.h deleted file mode 100644 index f3bf11a04d41..000000000000 --- a/drivers/char/rio/link.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** - ******* ******* - ******* L I N K - ******* ******* - **************************************************************************** - - Author : Ian Nandhra / Jeremy Rolls - Date : - - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - Version : 0.01 - - - Mods - ---------------------------------------------------------------------------- - Date By Description - ---------------------------------------------------------------------------- - - ***************************************************************************/ - -#ifndef _link_h -#define _link_h 1 - -/************************************************* - * Define the Link Status stuff - ************************************************/ -/* Boot request stuff */ -#define BOOT_REQUEST ((ushort) 0) /* Request for a boot */ -#define BOOT_ABORT ((ushort) 1) /* Abort a boot */ -#define BOOT_SEQUENCE ((ushort) 2) /* Packet with the number of packets - and load address */ -#define BOOT_COMPLETED ((ushort) 3) /* Boot completed */ - - -struct LPB { - u16 link_number; /* Link Number */ - u16 in_ch; /* Link In Channel */ - u16 out_ch; /* Link Out Channel */ - u8 attached_serial[4]; /* Attached serial number */ - u8 attached_host_serial[4]; - /* Serial number of Host who - booted the other end */ - u16 descheduled; /* Currently Descheduled */ - u16 state; /* Current state */ - u16 send_poll; /* Send a Poll Packet */ - u16 ltt_p; /* Process Descriptor */ - u16 lrt_p; /* Process Descriptor */ - u16 lrt_status; /* Current lrt status */ - u16 ltt_status; /* Current ltt status */ - u16 timeout; /* Timeout value */ - u16 topology; /* Topology bits */ - u16 mon_ltt; - u16 mon_lrt; - u16 WaitNoBoot; /* Secs to hold off booting */ - u16 add_packet_list; /* Add packets to here */ - u16 remove_packet_list; /* Send packets from here */ - - u16 lrt_fail_chan; /* Lrt's failure channel */ - u16 ltt_fail_chan; /* Ltt's failure channel */ - - /* RUP structure for HOST to driver communications */ - struct RUP rup; - struct RUP link_rup; /* RUP for the link (POLL, - topology etc.) */ - u16 attached_link; /* Number of attached link */ - u16 csum_errors; /* csum errors */ - u16 num_disconnects; /* number of disconnects */ - u16 num_sync_rcvd; /* # sync's received */ - u16 num_sync_rqst; /* # sync requests */ - u16 num_tx; /* Num pkts sent */ - u16 num_rx; /* Num pkts received */ - u16 module_attached; /* Module tpyes of attached */ - u16 led_timeout; /* LED timeout */ - u16 first_port; /* First port to service */ - u16 last_port; /* Last port to service */ -}; - -#endif - -/*********** end of file ***********/ diff --git a/drivers/char/rio/linux_compat.h b/drivers/char/rio/linux_compat.h deleted file mode 100644 index 34c0d2899ef1..000000000000 --- a/drivers/char/rio/linux_compat.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * (C) 2000 R.E.Wolff@BitWizard.nl - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - - -#define DEBUG_ALL - -struct ttystatics { - struct termios tm; -}; - -extern int rio_debug; - -#define RIO_DEBUG_INIT 0x000001 -#define RIO_DEBUG_BOOT 0x000002 -#define RIO_DEBUG_CMD 0x000004 -#define RIO_DEBUG_CTRL 0x000008 -#define RIO_DEBUG_INTR 0x000010 -#define RIO_DEBUG_PARAM 0x000020 -#define RIO_DEBUG_ROUTE 0x000040 -#define RIO_DEBUG_TABLE 0x000080 -#define RIO_DEBUG_TTY 0x000100 -#define RIO_DEBUG_FLOW 0x000200 -#define RIO_DEBUG_MODEMSIGNALS 0x000400 -#define RIO_DEBUG_PROBE 0x000800 -#define RIO_DEBUG_CLEANUP 0x001000 -#define RIO_DEBUG_IFLOW 0x002000 -#define RIO_DEBUG_PFE 0x004000 -#define RIO_DEBUG_REC 0x008000 -#define RIO_DEBUG_SPINLOCK 0x010000 -#define RIO_DEBUG_DELAY 0x020000 -#define RIO_DEBUG_MOD_COUNT 0x040000 - - -/* Copied over from riowinif.h . This is ugly. The winif file declares -also much other stuff which is incompatible with the headers from -the older driver. The older driver includes "brates.h" which shadows -the definitions from Linux, and is incompatible... */ - -/* RxBaud and TxBaud definitions... */ -#define RIO_B0 0x00 /* RTS / DTR signals dropped */ -#define RIO_B50 0x01 /* 50 baud */ -#define RIO_B75 0x02 /* 75 baud */ -#define RIO_B110 0x03 /* 110 baud */ -#define RIO_B134 0x04 /* 134.5 baud */ -#define RIO_B150 0x05 /* 150 baud */ -#define RIO_B200 0x06 /* 200 baud */ -#define RIO_B300 0x07 /* 300 baud */ -#define RIO_B600 0x08 /* 600 baud */ -#define RIO_B1200 0x09 /* 1200 baud */ -#define RIO_B1800 0x0A /* 1800 baud */ -#define RIO_B2400 0x0B /* 2400 baud */ -#define RIO_B4800 0x0C /* 4800 baud */ -#define RIO_B9600 0x0D /* 9600 baud */ -#define RIO_B19200 0x0E /* 19200 baud */ -#define RIO_B38400 0x0F /* 38400 baud */ -#define RIO_B56000 0x10 /* 56000 baud */ -#define RIO_B57600 0x11 /* 57600 baud */ -#define RIO_B64000 0x12 /* 64000 baud */ -#define RIO_B115200 0x13 /* 115200 baud */ -#define RIO_B2000 0x14 /* 2000 baud */ diff --git a/drivers/char/rio/map.h b/drivers/char/rio/map.h deleted file mode 100644 index 8366978578c1..000000000000 --- a/drivers/char/rio/map.h +++ /dev/null @@ -1,98 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : map.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:11 -** Retrieved : 11/6/98 11:34:21 -** -** ident @(#)map.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_map_h__ -#define __rio_map_h__ - -/* -** mapping structure passed to and from the config.rio program to -** determine the current topology of the world -*/ - -#define MAX_MAP_ENTRY 17 -#define TOTAL_MAP_ENTRIES (MAX_MAP_ENTRY*RIO_SLOTS) -#define MAX_NAME_LEN 32 - -struct Map { - unsigned int HostUniqueNum; /* Supporting hosts unique number */ - unsigned int RtaUniqueNum; /* Unique number */ - /* - ** The next two IDs must be swapped on big-endian architectures - ** when using a v2.04 /etc/rio/config with a v3.00 driver (when - ** upgrading for example). - */ - unsigned short ID; /* ID used in the subnet */ - unsigned short ID2; /* ID of 2nd block of 8 for 16 port */ - unsigned long Flags; /* Booted, ID Given, Disconnected */ - unsigned long SysPort; /* First tty mapped to this port */ - struct Top Topology[LINKS_PER_UNIT]; /* ID connected to each link */ - char Name[MAX_NAME_LEN]; /* Cute name by which RTA is known */ -}; - -/* -** Flag values: -*/ -#define RTA_BOOTED 0x00000001 -#define RTA_NEWBOOT 0x00000010 -#define MSG_DONE 0x00000020 -#define RTA_INTERCONNECT 0x00000040 -#define RTA16_SECOND_SLOT 0x00000080 -#define BEEN_HERE 0x00000100 -#define SLOT_TENTATIVE 0x40000000 -#define SLOT_IN_USE 0x80000000 - -/* -** HostUniqueNum is the unique number from the host card that this RTA -** is to be connected to. -** RtaUniqueNum is the unique number of the RTA concerned. It will be ZERO -** if the slot in the table is unused. If it is the same as the HostUniqueNum -** then this slot represents a host card. -** Flags contains current boot/route state info -** SysPort is a value in the range 0-504, being the number of the first tty -** on this RTA. Each RTA supports 8 ports. The SysPort value must be modulo 8. -** SysPort 0-127 correspond to /dev/ttyr001 to /dev/ttyr128, with minor -** numbers 0-127. SysPort 128-255 correspond to /dev/ttyr129 to /dev/ttyr256, -** again with minor numbers 0-127, and so on for SysPorts 256-383 and 384-511 -** ID will be in the range 0-16 for a `known' RTA. ID will be 0xFFFF for an -** unused slot/unknown ID etc. -** The Topology array contains the ID of the unit connected to each of the -** four links on this unit. The entry will be 0xFFFF if NOTHING is connected -** to the link, or will be 0xFF00 if an UNKNOWN unit is connected to the link. -** The Name field is a null-terminated string, upto 31 characters, containing -** the 'cute' name that the sysadmin/users know the RTA by. It is permissible -** for this string to contain any character in the range \040 to \176 inclusive. -** In particular, ctrl sequences and DEL (0x7F, \177) are not allowed. The -** special character '%' IS allowable, and needs no special action. -** -*/ - -#endif diff --git a/drivers/char/rio/param.h b/drivers/char/rio/param.h deleted file mode 100644 index 7e9b6283e8aa..000000000000 --- a/drivers/char/rio/param.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : param.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:12 -** Retrieved : 11/6/98 11:34:21 -** -** ident @(#)param.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_param_h__ -#define __rio_param_h__ - -/* -** the param command block, as used in OPEN and PARAM calls. -*/ - -struct phb_param { - u8 Cmd; /* It is very important that these line up */ - u8 Cor1; /* with what is expected at the other end. */ - u8 Cor2; /* to confirm that you've got it right, */ - u8 Cor4; /* check with cirrus/cirrus.h */ - u8 Cor5; - u8 TxXon; /* Transmit X-On character */ - u8 TxXoff; /* Transmit X-Off character */ - u8 RxXon; /* Receive X-On character */ - u8 RxXoff; /* Receive X-Off character */ - u8 LNext; /* Literal-next character */ - u8 TxBaud; /* Transmit baudrate */ - u8 RxBaud; /* Receive baudrate */ -}; - -#endif diff --git a/drivers/char/rio/parmmap.h b/drivers/char/rio/parmmap.h deleted file mode 100644 index acc8fa439df5..000000000000 --- a/drivers/char/rio/parmmap.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** - ******* ******* - ******* H O S T M E M O R Y M A P - ******* ******* - **************************************************************************** - - Author : Ian Nandhra / Jeremy Rolls - Date : - - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - Version : 0.01 - - - Mods - ---------------------------------------------------------------------------- - Date By Description - ---------------------------------------------------------------------------- -6/4/1991 jonb Made changes to accommodate Mips R3230 bus - ***************************************************************************/ - -#ifndef _parmap_h -#define _parmap_h - -typedef struct PARM_MAP PARM_MAP; - -struct PARM_MAP { - u16 phb_ptr; /* Pointer to the PHB array */ - u16 phb_num_ptr; /* Ptr to Number of PHB's */ - u16 free_list; /* Free List pointer */ - u16 free_list_end; /* Free List End pointer */ - u16 q_free_list_ptr; /* Ptr to Q_BUF variable */ - u16 unit_id_ptr; /* Unit Id */ - u16 link_str_ptr; /* Link Structure Array */ - u16 bootloader_1; /* 1st Stage Boot Loader */ - u16 bootloader_2; /* 2nd Stage Boot Loader */ - u16 port_route_map_ptr; /* Port Route Map */ - u16 route_ptr; /* Unit Route Map */ - u16 map_present; /* Route Map present */ - s16 pkt_num; /* Total number of packets */ - s16 q_num; /* Total number of Q packets */ - u16 buffers_per_port; /* Number of buffers per port */ - u16 heap_size; /* Initial size of heap */ - u16 heap_left; /* Current Heap left */ - u16 error; /* Error code */ - u16 tx_max; /* Max number of tx pkts per phb */ - u16 rx_max; /* Max number of rx pkts per phb */ - u16 rx_limit; /* For high / low watermarks */ - s16 links; /* Links to use */ - s16 timer; /* Interrupts per second */ - u16 rups; /* Pointer to the RUPs */ - u16 max_phb; /* Mostly for debugging */ - u16 living; /* Just increments!! */ - u16 init_done; /* Initialisation over */ - u16 booting_link; - u16 idle_count; /* Idle time counter */ - u16 busy_count; /* Busy counter */ - u16 idle_control; /* Control Idle Process */ - u16 tx_intr; /* TX interrupt pending */ - u16 rx_intr; /* RX interrupt pending */ - u16 rup_intr; /* RUP interrupt pending */ -}; - -#endif - -/*********** end of file ***********/ diff --git a/drivers/char/rio/pci.h b/drivers/char/rio/pci.h deleted file mode 100644 index 6032f9135956..000000000000 --- a/drivers/char/rio/pci.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : pci.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:12 -** Retrieved : 11/6/98 11:34:21 -** -** ident @(#)pci.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_pci_h__ -#define __rio_pci_h__ - -/* -** PCI stuff -*/ - -#define PCITpFastClock 0x80 -#define PCITpSlowClock 0x00 -#define PCITpFastLinks 0x40 -#define PCITpSlowLinks 0x00 -#define PCITpIntEnable 0x04 -#define PCITpIntDisable 0x00 -#define PCITpBusEnable 0x02 -#define PCITpBusDisable 0x00 -#define PCITpBootFromRam 0x01 -#define PCITpBootFromLink 0x00 - -#define RIO_PCI_VENDOR 0x11CB -#define RIO_PCI_DEVICE 0x8000 -#define RIO_PCI_BASE_CLASS 0x02 -#define RIO_PCI_SUB_CLASS 0x80 -#define RIO_PCI_PROG_IFACE 0x00 - -#define RIO_PCI_RID 0x0008 -#define RIO_PCI_BADR0 0x0010 -#define RIO_PCI_INTLN 0x003C -#define RIO_PCI_INTPIN 0x003D - -#define RIO_PCI_MEM_SIZE 65536 - -#define RIO_PCI_TURBO_TP 0x80 -#define RIO_PCI_FAST_LINKS 0x40 -#define RIO_PCI_INT_ENABLE 0x04 -#define RIO_PCI_TP_BUS_ENABLE 0x02 -#define RIO_PCI_BOOT_FROM_RAM 0x01 - -#define RIO_PCI_DEFAULT_MODE 0x05 - -#endif /* __rio_pci_h__ */ diff --git a/drivers/char/rio/phb.h b/drivers/char/rio/phb.h deleted file mode 100644 index a4c48ae4e365..000000000000 --- a/drivers/char/rio/phb.h +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************** - ******* ******* - ******* P H B H E A D E R ******* - ******* ******* - **************************************************************************** - - Author : Ian Nandhra, Jeremy Rolls - Date : - - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - Version : 0.01 - - - Mods - ---------------------------------------------------------------------------- - Date By Description - ---------------------------------------------------------------------------- - - ***************************************************************************/ - -#ifndef _phb_h -#define _phb_h 1 - -/************************************************* - * Handshake asserted. Deasserted by the LTT(s) - ************************************************/ -#define PHB_HANDSHAKE_SET ((ushort) 0x001) /* Set by LRT */ - -#define PHB_HANDSHAKE_RESET ((ushort) 0x002) /* Set by ISR / driver */ - -#define PHB_HANDSHAKE_FLAGS (PHB_HANDSHAKE_RESET | PHB_HANDSHAKE_SET) - /* Reset by ltt */ - - -/************************************************* - * Maximum number of PHB's - ************************************************/ -#define MAX_PHB ((ushort) 128) /* range 0-127 */ - -/************************************************* - * Defines for the mode fields - ************************************************/ -#define TXPKT_INCOMPLETE 0x0001 /* Previous tx packet not completed */ -#define TXINTR_ENABLED 0x0002 /* Tx interrupt is enabled */ -#define TX_TAB3 0x0004 /* TAB3 mode */ -#define TX_OCRNL 0x0008 /* OCRNL mode */ -#define TX_ONLCR 0x0010 /* ONLCR mode */ -#define TX_SENDSPACES 0x0020 /* Send n spaces command needs - completing */ -#define TX_SENDNULL 0x0040 /* Escaping NULL needs completing */ -#define TX_SENDLF 0x0080 /* LF -> CR LF needs completing */ -#define TX_PARALLELBUG 0x0100 /* CD1400 LF -> CR LF bug on parallel - port */ -#define TX_HANGOVER (TX_SENDSPACES | TX_SENDLF | TX_SENDNULL) -#define TX_DTRFLOW 0x0200 /* DTR tx flow control */ -#define TX_DTRFLOWED 0x0400 /* DTR is low - don't allow more data - into the FIFO */ -#define TX_DATAINFIFO 0x0800 /* There is data in the FIFO */ -#define TX_BUSY 0x1000 /* Data in FIFO, shift or holding regs */ - -#define RX_SPARE 0x0001 /* SPARE */ -#define RXINTR_ENABLED 0x0002 /* Rx interrupt enabled */ -#define RX_ICRNL 0x0008 /* ICRNL mode */ -#define RX_INLCR 0x0010 /* INLCR mode */ -#define RX_IGNCR 0x0020 /* IGNCR mode */ -#define RX_CTSFLOW 0x0040 /* CTSFLOW enabled */ -#define RX_IXOFF 0x0080 /* IXOFF enabled */ -#define RX_CTSFLOWED 0x0100 /* CTSFLOW and CTS dropped */ -#define RX_IXOFFED 0x0200 /* IXOFF and xoff sent */ -#define RX_BUFFERED 0x0400 /* Try and pass on complete packets */ - -#define PORT_ISOPEN 0x0001 /* Port open? */ -#define PORT_HUPCL 0x0002 /* Hangup on close? */ -#define PORT_MOPENPEND 0x0004 /* Modem open pending */ -#define PORT_ISPARALLEL 0x0008 /* Parallel port */ -#define PORT_BREAK 0x0010 /* Port on break */ -#define PORT_STATUSPEND 0x0020 /* Status packet pending */ -#define PORT_BREAKPEND 0x0040 /* Break packet pending */ -#define PORT_MODEMPEND 0x0080 /* Modem status packet pending */ -#define PORT_PARALLELBUG 0x0100 /* CD1400 LF -> CR LF bug on parallel - port */ -#define PORT_FULLMODEM 0x0200 /* Full modem signals */ -#define PORT_RJ45 0x0400 /* RJ45 connector - no RI signal */ -#define PORT_RESTRICTED 0x0600 /* Restricted connector - no RI / DTR */ - -#define PORT_MODEMBITS 0x0600 /* Mask for modem fields */ - -#define PORT_WCLOSE 0x0800 /* Waiting for close */ -#define PORT_HANDSHAKEFIX 0x1000 /* Port has H/W flow control fix */ -#define PORT_WASPCLOSED 0x2000 /* Port closed with PCLOSE */ -#define DUMPMODE 0x4000 /* Dump RTA mem */ -#define READ_REG 0x8000 /* Read CD1400 register */ - - - -/************************************************************************** - * PHB Structure - * A few words. - * - * Normally Packets are added to the end of the list and removed from - * the start. The pointer tx_add points to a SPACE to put a Packet. - * The pointer tx_remove points to the next Packet to remove - *************************************************************************/ - -struct PHB { - u8 source; - u8 handshake; - u8 status; - u16 timeout; /* Maximum of 1.9 seconds */ - u8 link; /* Send down this link */ - u8 destination; - u16 tx_start; - u16 tx_end; - u16 tx_add; - u16 tx_remove; - - u16 rx_start; - u16 rx_end; - u16 rx_add; - u16 rx_remove; - -}; - -#endif - -/*********** end of file ***********/ diff --git a/drivers/char/rio/pkt.h b/drivers/char/rio/pkt.h deleted file mode 100644 index a9458164f02f..000000000000 --- a/drivers/char/rio/pkt.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** - ******* ******* - ******* P A C K E T H E A D E R F I L E - ******* ******* - **************************************************************************** - - Author : Ian Nandhra / Jeremy Rolls - Date : - - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - Version : 0.01 - - - Mods - ---------------------------------------------------------------------------- - Date By Description - ---------------------------------------------------------------------------- - - ***************************************************************************/ - -#ifndef _pkt_h -#define _pkt_h 1 - -#define PKT_CMD_BIT ((ushort) 0x080) -#define PKT_CMD_DATA ((ushort) 0x080) - -#define PKT_ACK ((ushort) 0x040) - -#define PKT_TGL ((ushort) 0x020) - -#define PKT_LEN_MASK ((ushort) 0x07f) - -#define DATA_WNDW ((ushort) 0x10) -#define PKT_TTL_MASK ((ushort) 0x0f) - -#define PKT_MAX_DATA_LEN 72 - -#define PKT_LENGTH sizeof(struct PKT) -#define SYNC_PKT_LENGTH (PKT_LENGTH + 4) - -#define CONTROL_PKT_LEN_MASK PKT_LEN_MASK -#define CONTROL_PKT_CMD_BIT PKT_CMD_BIT -#define CONTROL_PKT_ACK (PKT_ACK << 8) -#define CONTROL_PKT_TGL (PKT_TGL << 8) -#define CONTROL_PKT_TTL_MASK (PKT_TTL_MASK << 8) -#define CONTROL_DATA_WNDW (DATA_WNDW << 8) - -struct PKT { - u8 dest_unit; /* Destination Unit Id */ - u8 dest_port; /* Destination POrt */ - u8 src_unit; /* Source Unit Id */ - u8 src_port; /* Source POrt */ - u8 len; - u8 control; - u8 data[PKT_MAX_DATA_LEN]; - /* Actual data :-) */ - u16 csum; /* C-SUM */ -}; -#endif - -/*********** end of file ***********/ diff --git a/drivers/char/rio/port.h b/drivers/char/rio/port.h deleted file mode 100644 index 49cf6d15ee54..000000000000 --- a/drivers/char/rio/port.h +++ /dev/null @@ -1,179 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : port.h -** SID : 1.3 -** Last Modified : 11/6/98 11:34:12 -** Retrieved : 11/6/98 11:34:21 -** -** ident @(#)port.h 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_port_h__ -#define __rio_port_h__ - -/* -** Port data structure -*/ -struct Port { - struct gs_port gs; - int PortNum; /* RIO port no., 0-511 */ - struct Host *HostP; - void __iomem *Caddr; - unsigned short HostPort; /* Port number on host card */ - unsigned char RupNum; /* Number of RUP for port */ - unsigned char ID2; /* Second ID of RTA for port */ - unsigned long State; /* FLAGS for open & xopen */ -#define RIO_LOPEN 0x00001 /* Local open */ -#define RIO_MOPEN 0x00002 /* Modem open */ -#define RIO_WOPEN 0x00004 /* Waiting for open */ -#define RIO_CLOSING 0x00008 /* The port is being close */ -#define RIO_XPBUSY 0x00010 /* Transparent printer busy */ -#define RIO_BREAKING 0x00020 /* Break in progress */ -#define RIO_DIRECT 0x00040 /* Doing Direct output */ -#define RIO_EXCLUSIVE 0x00080 /* Stream open for exclusive use */ -#define RIO_NDELAY 0x00100 /* Stream is open FNDELAY */ -#define RIO_CARR_ON 0x00200 /* Stream has carrier present */ -#define RIO_XPWANTR 0x00400 /* Stream wanted by Xprint */ -#define RIO_RBLK 0x00800 /* Stream is read-blocked */ -#define RIO_BUSY 0x01000 /* Stream is BUSY for write */ -#define RIO_TIMEOUT 0x02000 /* Stream timeout in progress */ -#define RIO_TXSTOP 0x04000 /* Stream output is stopped */ -#define RIO_WAITFLUSH 0x08000 /* Stream waiting for flush */ -#define RIO_DYNOROD 0x10000 /* Drain failed */ -#define RIO_DELETED 0x20000 /* RTA has been deleted */ -#define RIO_ISSCANCODE 0x40000 /* This line is in scancode mode */ -#define RIO_USING_EUC 0x100000 /* Using extended Unix chars */ -#define RIO_CAN_COOK 0x200000 /* This line can do cooking */ -#define RIO_TRIAD_MODE 0x400000 /* Enable TRIAD special ops. */ -#define RIO_TRIAD_BLOCK 0x800000 /* Next read will block */ -#define RIO_TRIAD_FUNC 0x1000000 /* Seen a function key coming in */ -#define RIO_THROTTLE_RX 0x2000000 /* RX needs to be throttled. */ - - unsigned long Config; /* FLAGS for NOREAD.... */ -#define RIO_NOREAD 0x0001 /* Are not allowed to read port */ -#define RIO_NOWRITE 0x0002 /* Are not allowed to write port */ -#define RIO_NOXPRINT 0x0004 /* Are not allowed to xprint port */ -#define RIO_NOMASK 0x0007 /* All not allowed things */ -#define RIO_IXANY 0x0008 /* Port is allowed ixany */ -#define RIO_MODEM 0x0010 /* Stream is a modem device */ -#define RIO_IXON 0x0020 /* Port is allowed ixon */ -#define RIO_WAITDRAIN 0x0040 /* Wait for port to completely drain */ -#define RIO_MAP_50_TO_50 0x0080 /* Map 50 baud to 50 baud */ -#define RIO_MAP_110_TO_110 0x0100 /* Map 110 baud to 110 baud */ - -/* -** 15.10.1998 ARG - ESIL 0761 prt fix -** As LynxOS does not appear to support Hardware Flow Control ..... -** Define our own flow control flags in 'Config'. -*/ -#define RIO_CTSFLOW 0x0200 /* RIO's own CTSFLOW flag */ -#define RIO_RTSFLOW 0x0400 /* RIO's own RTSFLOW flag */ - - - struct PHB __iomem *PhbP; /* pointer to PHB for port */ - u16 __iomem *TxAdd; /* Add packets here */ - u16 __iomem *TxStart; /* Start of add array */ - u16 __iomem *TxEnd; /* End of add array */ - u16 __iomem *RxRemove; /* Remove packets here */ - u16 __iomem *RxStart; /* Start of remove array */ - u16 __iomem *RxEnd; /* End of remove array */ - unsigned int RtaUniqueNum; /* Unique number of RTA */ - unsigned short PortState; /* status of port */ - unsigned short ModemState; /* status of modem lines */ - unsigned long ModemLines; /* Modem bits sent to RTA */ - unsigned char CookMode; /* who expands CR/LF? */ - unsigned char ParamSem; /* Prevent write during param */ - unsigned char Mapped; /* if port mapped onto host */ - unsigned char SecondBlock; /* if port belongs to 2nd block - of 16 port RTA */ - unsigned char InUse; /* how many pre-emptive cmds */ - unsigned char Lock; /* if params locked */ - unsigned char Store; /* if params stored across closes */ - unsigned char FirstOpen; /* TRUE if first time port opened */ - unsigned char FlushCmdBodge; /* if doing a (non)flush */ - unsigned char MagicFlags; /* require intr processing */ -#define MAGIC_FLUSH 0x01 /* mirror of WflushFlag */ -#define MAGIC_REBOOT 0x02 /* RTA re-booted, re-open ports */ -#define MORE_OUTPUT_EYGOR 0x04 /* riotproc failed to empty clists */ - unsigned char WflushFlag; /* 1 How many WFLUSHs active */ -/* -** Transparent print stuff -*/ - struct Xprint { -#ifndef MAX_XP_CTRL_LEN -#define MAX_XP_CTRL_LEN 16 /* ALSO IN DAEMON.H */ -#endif - unsigned int XpCps; - char XpOn[MAX_XP_CTRL_LEN]; - char XpOff[MAX_XP_CTRL_LEN]; - unsigned short XpLen; /* strlen(XpOn)+strlen(XpOff) */ - unsigned char XpActive; - unsigned char XpLastTickOk; /* TRUE if we can process */ -#define XP_OPEN 00001 -#define XP_RUNABLE 00002 - struct ttystatics *XttyP; - } Xprint; - unsigned char RxDataStart; - unsigned char Cor2Copy; /* copy of COR2 */ - char *Name; /* points to the Rta's name */ - char *TxRingBuffer; - unsigned short TxBufferIn; /* New data arrives here */ - unsigned short TxBufferOut; /* Intr removes data here */ - unsigned short OldTxBufferOut; /* Indicates if draining */ - int TimeoutId; /* Timeout ID */ - unsigned int Debug; - unsigned char WaitUntilBooted; /* True if open should block */ - unsigned int statsGather; /* True if gathering stats */ - unsigned long txchars; /* Chars transmitted */ - unsigned long rxchars; /* Chars received */ - unsigned long opens; /* port open count */ - unsigned long closes; /* port close count */ - unsigned long ioctls; /* ioctl count */ - unsigned char LastRxTgl; /* Last state of rx toggle bit */ - spinlock_t portSem; /* Lock using this sem */ - int MonitorTstate; /* Monitoring ? */ - int timeout_id; /* For calling 100 ms delays */ - int timeout_sem; /* For calling 100 ms delays */ - int firstOpen; /* First time open ? */ - char *p; /* save the global struc here .. */ -}; - -struct ModuleInfo { - char *Name; - unsigned int Flags[4]; /* one per port on a module */ -}; - -/* -** This struct is required because trying to grab an entire Port structure -** runs into problems with differing struct sizes between driver and config. -*/ -struct PortParams { - unsigned int Port; - unsigned long Config; - unsigned long State; - struct ttystatics *TtyP; -}; - -#endif diff --git a/drivers/char/rio/protsts.h b/drivers/char/rio/protsts.h deleted file mode 100644 index 8ab79401d3ee..000000000000 --- a/drivers/char/rio/protsts.h +++ /dev/null @@ -1,110 +0,0 @@ -/**************************************************************************** - ******* ******* - ******* P R O T O C O L S T A T U S S T R U C T U R E ******* - ******* ******* - **************************************************************************** - - Author : Ian Nandhra / Jeremy Rolls - Date : - - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - Version : 0.01 - - - Mods - ---------------------------------------------------------------------------- - Date By Description - ---------------------------------------------------------------------------- - - ***************************************************************************/ - -#ifndef _protsts_h -#define _protsts_h 1 - -/************************************************* - * ACK bit. Last Packet received OK. Set by - * rxpkt to indicate that the Packet has been - * received OK and that the LTT must set the ACK - * bit in the next outward bound Packet - * and re-set by LTT's after xmit. - * - * Gets shoved into rx_status - ************************************************/ -#define PHB_RX_LAST_PKT_ACKED ((ushort) 0x080) - -/******************************************************* - * The Rx TOGGLE bit. - * Stuffed into rx_status by RXPKT - ******************************************************/ -#define PHB_RX_DATA_WNDW ((ushort) 0x040) - -/******************************************************* - * The Rx TOGGLE bit. Matches the setting in PKT.H - * Stuffed into rx_status - ******************************************************/ -#define PHB_RX_TGL ((ushort) 0x2000) - - -/************************************************* - * This bit is set by the LRT to indicate that - * an ACK (packet) must be returned. - * - * Gets shoved into tx_status - ************************************************/ -#define PHB_TX_SEND_PKT_ACK ((ushort) 0x08) - -/************************************************* - * Set by LTT to indicate that an ACK is required - *************************************************/ -#define PHB_TX_ACK_RQRD ((ushort) 0x01) - - -/******************************************************* - * The Tx TOGGLE bit. - * Stuffed into tx_status by RXPKT from the PKT WndW - * field. Looked by the LTT when the NEXT Packet - * is going to be sent. - ******************************************************/ -#define PHB_TX_DATA_WNDW ((ushort) 0x04) - - -/******************************************************* - * The Tx TOGGLE bit. Matches the setting in PKT.H - * Stuffed into tx_status - ******************************************************/ -#define PHB_TX_TGL ((ushort) 0x02) - -/******************************************************* - * Request intr bit. Set when the queue has gone quiet - * and the PHB has requested an interrupt. - ******************************************************/ -#define PHB_TX_INTR ((ushort) 0x100) - -/******************************************************* - * SET if the PHB cannot send any more data down the - * Link - ******************************************************/ -#define PHB_TX_HANDSHAKE ((ushort) 0x010) - - -#define RUP_SEND_WNDW ((ushort) 0x08) ; - -#endif - -/*********** end of file ***********/ diff --git a/drivers/char/rio/rio.h b/drivers/char/rio/rio.h deleted file mode 100644 index 1bf36223a4e8..000000000000 --- a/drivers/char/rio/rio.h +++ /dev/null @@ -1,208 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 1998 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : rio.h -** SID : 1.3 -** Last Modified : 11/6/98 11:34:13 -** Retrieved : 11/6/98 11:34:22 -** -** ident @(#)rio.h 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_rio_h__ -#define __rio_rio_h__ - -/* -** Maximum numbers of things -*/ -#define RIO_SLOTS 4 /* number of configuration slots */ -#define RIO_HOSTS 4 /* number of hosts that can be found */ -#define PORTS_PER_HOST 128 /* number of ports per host */ -#define LINKS_PER_UNIT 4 /* number of links from a host */ -#define RIO_PORTS (PORTS_PER_HOST * RIO_HOSTS) /* max. no. of ports */ -#define RTAS_PER_HOST (MAX_RUP) /* number of RTAs per host */ -#define PORTS_PER_RTA (PORTS_PER_HOST/RTAS_PER_HOST) /* ports on a rta */ -#define PORTS_PER_MODULE 4 /* number of ports on a plug-in module */ - /* number of modules on an RTA */ -#define MODULES_PER_RTA (PORTS_PER_RTA/PORTS_PER_MODULE) -#define MAX_PRODUCT 16 /* numbr of different product codes */ -#define MAX_MODULE_TYPES 16 /* number of different types of module */ - -#define RIO_CONTROL_DEV 128 /* minor number of host/control device */ -#define RIO_INVALID_MAJOR 0 /* test first host card's major no for validity */ - -/* -** number of RTAs that can be bound to a master -*/ -#define MAX_RTA_BINDINGS (MAX_RUP * RIO_HOSTS) - -/* -** Unit types -*/ -#define PC_RTA16 0x90000000 -#define PC_RTA8 0xe0000000 -#define TYPE_HOST 0 -#define TYPE_RTA8 1 -#define TYPE_RTA16 2 - -/* -** Flag values returned by functions -*/ - -#define RIO_FAIL -1 - -/* -** SysPort value for something that hasn't any ports -*/ -#define NO_PORT 0xFFFFFFFF - -/* -** Unit ID Of all hosts -*/ -#define HOST_ID 0 - -/* -** Break bytes into nybles -*/ -#define LONYBLE(X) ((X) & 0xF) -#define HINYBLE(X) (((X)>>4) & 0xF) - -/* -** Flag values passed into some functions -*/ -#define DONT_SLEEP 0 -#define OK_TO_SLEEP 1 - -#define DONT_PRINT 1 -#define DO_PRINT 0 - -#define PRINT_TO_LOG_CONS 0 -#define PRINT_TO_CONS 1 -#define PRINT_TO_LOG 2 - -/* -** Timeout has trouble with times of less than 3 ticks... -*/ -#define MIN_TIMEOUT 3 - -/* -** Generally useful constants -*/ - -#define HUNDRED_MS ((HZ/10)?(HZ/10):1) -#define ONE_MEG 0x100000 -#define SIXTY_FOUR_K 0x10000 - -#define RIO_AT_MEM_SIZE SIXTY_FOUR_K -#define RIO_EISA_MEM_SIZE SIXTY_FOUR_K -#define RIO_MCA_MEM_SIZE SIXTY_FOUR_K - -#define COOK_WELL 0 -#define COOK_MEDIUM 1 -#define COOK_RAW 2 - -/* -** Pointer manipulation stuff -** RIO_PTR takes hostp->Caddr and the offset into the DP RAM area -** and produces a UNIX caddr_t (pointer) to the object -** RIO_OBJ takes hostp->Caddr and a UNIX pointer to an object and -** returns the offset into the DP RAM area. -*/ -#define RIO_PTR(C,O) (((unsigned char __iomem *)(C))+(0xFFFF&(O))) -#define RIO_OFF(C,O) ((unsigned char __iomem *)(O)-(unsigned char __iomem *)(C)) - -/* -** How to convert from various different device number formats: -** DEV is a dev number, as passed to open, close etc - NOT a minor -** number! -**/ - -#define RIO_MODEM_MASK 0x1FF -#define RIO_MODEM_BIT 0x200 -#define RIO_UNMODEM(DEV) (MINOR(DEV) & RIO_MODEM_MASK) -#define RIO_ISMODEM(DEV) (MINOR(DEV) & RIO_MODEM_BIT) -#define RIO_PORT(DEV,FIRST_MAJ) ( (MAJOR(DEV) - FIRST_MAJ) * PORTS_PER_HOST) \ - + MINOR(DEV) -#define CSUM(pkt_ptr) (((u16 *)(pkt_ptr))[0] + ((u16 *)(pkt_ptr))[1] + \ - ((u16 *)(pkt_ptr))[2] + ((u16 *)(pkt_ptr))[3] + \ - ((u16 *)(pkt_ptr))[4] + ((u16 *)(pkt_ptr))[5] + \ - ((u16 *)(pkt_ptr))[6] + ((u16 *)(pkt_ptr))[7] + \ - ((u16 *)(pkt_ptr))[8] + ((u16 *)(pkt_ptr))[9] ) - -#define RIO_LINK_ENABLE 0x80FF /* FF is a hack, mainly for Mips, to */ - /* prevent a really stupid race condition. */ - -#define NOT_INITIALISED 0 -#define INITIALISED 1 - -#define NOT_POLLING 0 -#define POLLING 1 - -#define NOT_CHANGED 0 -#define CHANGED 1 - -#define NOT_INUSE 0 - -#define DISCONNECT 0 -#define CONNECT 1 - -/* ------ Control Codes ------ */ - -#define CONTROL '^' -#define IFOAD ( CONTROL + 1 ) -#define IDENTIFY ( CONTROL + 2 ) -#define ZOMBIE ( CONTROL + 3 ) -#define UFOAD ( CONTROL + 4 ) -#define IWAIT ( CONTROL + 5 ) - -#define IFOAD_MAGIC 0xF0AD /* of course */ -#define ZOMBIE_MAGIC (~0xDEAD) /* not dead -> zombie */ -#define UFOAD_MAGIC 0xD1E /* kill-your-neighbour */ -#define IWAIT_MAGIC 0xB1DE /* Bide your time */ - -/* ------ Error Codes ------ */ - -#define E_NO_ERROR ((ushort) 0) - -/* ------ Free Lists ------ */ - -struct rio_free_list { - u16 next; - u16 prev; -}; - -/* NULL for card side linked lists */ -#define TPNULL ((ushort)(0x8000)) -/* We can add another packet to a transmit queue if the packet pointer pointed - * to by the TxAdd pointer has PKT_IN_USE clear in its address. */ -#define PKT_IN_USE 0x1 - -/* ------ Topology ------ */ - -struct Top { - u8 Unit; - u8 Link; -}; - -#endif /* __rio_h__ */ diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c deleted file mode 100644 index 5e33293d24e3..000000000000 --- a/drivers/char/rio/rio_linux.c +++ /dev/null @@ -1,1204 +0,0 @@ - -/* rio_linux.c -- Linux driver for the Specialix RIO series cards. - * - * - * (C) 1999 R.E.Wolff@BitWizard.nl - * - * Specialix pays for the development and support of this driver. - * Please DO contact support@specialix.co.uk if you require - * support. But please read the documentation (rio.txt) first. - * - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, - * USA. - * - * */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "linux_compat.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" -#include "cirrus.h" -#include "rioioctl.h" -#include "param.h" -#include "protsts.h" -#include "rioboard.h" - - -#include "rio_linux.h" - -/* I don't think that this driver can handle more than 512 ports on -one machine. Specialix specifies max 4 boards in one machine. I don't -know why. If you want to try anyway you'll have to increase the number -of boards in rio.h. You'll have to allocate more majors if you need -more than 512 ports.... */ - -#ifndef RIO_NORMAL_MAJOR0 -/* This allows overriding on the compiler commandline, or in a "major.h" - include or something like that */ -#define RIO_NORMAL_MAJOR0 154 -#define RIO_NORMAL_MAJOR1 156 -#endif - -#ifndef PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 -#define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000 -#endif - -#ifndef RIO_WINDOW_LEN -#define RIO_WINDOW_LEN 0x10000 -#endif - - -/* Configurable options: - (Don't be too sure that it'll work if you toggle them) */ - -/* Am I paranoid or not ? ;-) */ -#undef RIO_PARANOIA_CHECK - - -/* 20 -> 2000 per second. The card should rate-limit interrupts at 1000 - Hz, but it is user configurable. I don't recommend going above 1000 - Hz. The interrupt ratelimit might trigger if the interrupt is - shared with a very active other device. - undef this if you want to disable the check.... -*/ -#define IRQ_RATE_LIMIT 200 - - -/* These constants are derived from SCO Source */ -static DEFINE_MUTEX(rio_fw_mutex); -static struct Conf - RIOConf = { - /* locator */ "RIO Config here", - /* startuptime */ HZ * 2, - /* how long to wait for card to run */ - /* slowcook */ 0, - /* TRUE -> always use line disc. */ - /* intrpolltime */ 1, - /* The frequency of OUR polls */ - /* breakinterval */ 25, - /* x10 mS XXX: units seem to be 1ms not 10! -- REW */ - /* timer */ 10, - /* mS */ - /* RtaLoadBase */ 0x7000, - /* HostLoadBase */ 0x7C00, - /* XpHz */ 5, - /* number of Xprint hits per second */ - /* XpCps */ 120, - /* Xprint characters per second */ - /* XpOn */ "\033d#", - /* start Xprint for a wyse 60 */ - /* XpOff */ "\024", - /* end Xprint for a wyse 60 */ - /* MaxXpCps */ 2000, - /* highest Xprint speed */ - /* MinXpCps */ 10, - /* slowest Xprint speed */ - /* SpinCmds */ 1, - /* non-zero for mega fast boots */ - /* First Addr */ 0x0A0000, - /* First address to look at */ - /* Last Addr */ 0xFF0000, - /* Last address looked at */ - /* BufferSize */ 1024, - /* Bytes per port of buffering */ - /* LowWater */ 256, - /* how much data left before wakeup */ - /* LineLength */ 80, - /* how wide is the console? */ - /* CmdTimeout */ HZ, - /* how long a close command may take */ -}; - - - - -/* Function prototypes */ - -static void rio_disable_tx_interrupts(void *ptr); -static void rio_enable_tx_interrupts(void *ptr); -static void rio_disable_rx_interrupts(void *ptr); -static void rio_enable_rx_interrupts(void *ptr); -static int rio_carrier_raised(struct tty_port *port); -static void rio_shutdown_port(void *ptr); -static int rio_set_real_termios(void *ptr); -static void rio_hungup(void *ptr); -static void rio_close(void *ptr); -static int rio_chars_in_buffer(void *ptr); -static long rio_fw_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -static int rio_init_drivers(void); - -static void my_hd(void *addr, int len); - -static struct tty_driver *rio_driver, *rio_driver2; - -/* The name "p" is a bit non-descript. But that's what the rio-lynxos -sources use all over the place. */ -struct rio_info *p; - -int rio_debug; - - -/* You can have the driver poll your card. - - Set rio_poll to 1 to poll every timer tick (10ms on Intel). - This is used when the card cannot use an interrupt for some reason. -*/ -static int rio_poll = 1; - - -/* These are the only open spaces in my computer. Yours may have more - or less.... */ -static int rio_probe_addrs[] = { 0xc0000, 0xd0000, 0xe0000 }; - -#define NR_RIO_ADDRS ARRAY_SIZE(rio_probe_addrs) - - -/* Set the mask to all-ones. This alas, only supports 32 interrupts. - Some architectures may need more. -- Changed to LONG to - support up to 64 bits on 64bit architectures. -- REW 20/06/99 */ -static long rio_irqmask = -1; - -MODULE_AUTHOR("Rogier Wolff , Patrick van de Lageweg "); -MODULE_DESCRIPTION("RIO driver"); -MODULE_LICENSE("GPL"); -module_param(rio_poll, int, 0); -module_param(rio_debug, int, 0644); -module_param(rio_irqmask, long, 0); - -static struct real_driver rio_real_driver = { - rio_disable_tx_interrupts, - rio_enable_tx_interrupts, - rio_disable_rx_interrupts, - rio_enable_rx_interrupts, - rio_shutdown_port, - rio_set_real_termios, - rio_chars_in_buffer, - rio_close, - rio_hungup, - NULL -}; - -/* - * Firmware loader driver specific routines - * - */ - -static const struct file_operations rio_fw_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = rio_fw_ioctl, - .llseek = noop_llseek, -}; - -static struct miscdevice rio_fw_device = { - RIOCTL_MISC_MINOR, "rioctl", &rio_fw_fops -}; - - - - - -#ifdef RIO_PARANOIA_CHECK - -/* This doesn't work. Who's paranoid around here? Not me! */ - -static inline int rio_paranoia_check(struct rio_port const *port, char *name, const char *routine) -{ - - static const char *badmagic = KERN_ERR "rio: Warning: bad rio port magic number for device %s in %s\n"; - static const char *badinfo = KERN_ERR "rio: Warning: null rio port for device %s in %s\n"; - - if (!port) { - printk(badinfo, name, routine); - return 1; - } - if (port->magic != RIO_MAGIC) { - printk(badmagic, name, routine); - return 1; - } - - return 0; -} -#else -#define rio_paranoia_check(a,b,c) 0 -#endif - - -#ifdef DEBUG -static void my_hd(void *ad, int len) -{ - int i, j, ch; - unsigned char *addr = ad; - - for (i = 0; i < len; i += 16) { - rio_dprintk(RIO_DEBUG_PARAM, "%08lx ", (unsigned long) addr + i); - for (j = 0; j < 16; j++) { - rio_dprintk(RIO_DEBUG_PARAM, "%02x %s", addr[j + i], (j == 7) ? " " : ""); - } - for (j = 0; j < 16; j++) { - ch = addr[j + i]; - rio_dprintk(RIO_DEBUG_PARAM, "%c", (ch < 0x20) ? '.' : ((ch > 0x7f) ? '.' : ch)); - } - rio_dprintk(RIO_DEBUG_PARAM, "\n"); - } -} -#else -#define my_hd(ad,len) do{/* nothing*/ } while (0) -#endif - - -/* Delay a number of jiffies, allowing a signal to interrupt */ -int RIODelay(struct Port *PortP, int njiffies) -{ - func_enter(); - - rio_dprintk(RIO_DEBUG_DELAY, "delaying %d jiffies\n", njiffies); - msleep_interruptible(jiffies_to_msecs(njiffies)); - func_exit(); - - if (signal_pending(current)) - return RIO_FAIL; - else - return !RIO_FAIL; -} - - -/* Delay a number of jiffies, disallowing a signal to interrupt */ -int RIODelay_ni(struct Port *PortP, int njiffies) -{ - func_enter(); - - rio_dprintk(RIO_DEBUG_DELAY, "delaying %d jiffies (ni)\n", njiffies); - msleep(jiffies_to_msecs(njiffies)); - func_exit(); - return !RIO_FAIL; -} - -void rio_copy_to_card(void *from, void __iomem *to, int len) -{ - rio_copy_toio(to, from, len); -} - -int rio_minor(struct tty_struct *tty) -{ - return tty->index + ((tty->driver == rio_driver) ? 0 : 256); -} - -static int rio_set_real_termios(void *ptr) -{ - return RIOParam((struct Port *) ptr, RIOC_CONFIG, 1, 1); -} - - -static void rio_reset_interrupt(struct Host *HostP) -{ - func_enter(); - - switch (HostP->Type) { - case RIO_AT: - case RIO_MCA: - case RIO_PCI: - writeb(0xFF, &HostP->ResetInt); - } - - func_exit(); -} - - -static irqreturn_t rio_interrupt(int irq, void *ptr) -{ - struct Host *HostP; - func_enter(); - - HostP = ptr; /* &p->RIOHosts[(long)ptr]; */ - rio_dprintk(RIO_DEBUG_IFLOW, "rio: enter rio_interrupt (%d/%d)\n", irq, HostP->Ivec); - - /* AAargh! The order in which to do these things is essential and - not trivial. - - - hardware twiddling goes before "recursive". Otherwise when we - poll the card, and a recursive interrupt happens, we won't - ack the card, so it might keep on interrupting us. (especially - level sensitive interrupt systems like PCI). - - - Rate limit goes before hardware twiddling. Otherwise we won't - catch a card that has gone bonkers. - - - The "initialized" test goes after the hardware twiddling. Otherwise - the card will stick us in the interrupt routine again. - - - The initialized test goes before recursive. - */ - - rio_dprintk(RIO_DEBUG_IFLOW, "rio: We've have noticed the interrupt\n"); - if (HostP->Ivec == irq) { - /* Tell the card we've noticed the interrupt. */ - rio_reset_interrupt(HostP); - } - - if ((HostP->Flags & RUN_STATE) != RC_RUNNING) - return IRQ_HANDLED; - - if (test_and_set_bit(RIO_BOARD_INTR_LOCK, &HostP->locks)) { - printk(KERN_ERR "Recursive interrupt! (host %p/irq%d)\n", ptr, HostP->Ivec); - return IRQ_HANDLED; - } - - RIOServiceHost(p, HostP); - - rio_dprintk(RIO_DEBUG_IFLOW, "riointr() doing host %p type %d\n", ptr, HostP->Type); - - clear_bit(RIO_BOARD_INTR_LOCK, &HostP->locks); - rio_dprintk(RIO_DEBUG_IFLOW, "rio: exit rio_interrupt (%d/%d)\n", irq, HostP->Ivec); - func_exit(); - return IRQ_HANDLED; -} - - -static void rio_pollfunc(unsigned long data) -{ - func_enter(); - - rio_interrupt(0, &p->RIOHosts[data]); - mod_timer(&p->RIOHosts[data].timer, jiffies + rio_poll); - - func_exit(); -} - - -/* ********************************************************************** * - * Here are the routines that actually * - * interface with the generic_serial driver * - * ********************************************************************** */ - -/* Ehhm. I don't know how to fiddle with interrupts on the Specialix - cards. .... Hmm. Ok I figured it out. You don't. -- REW */ - -static void rio_disable_tx_interrupts(void *ptr) -{ - func_enter(); - - /* port->gs.port.flags &= ~GS_TX_INTEN; */ - - func_exit(); -} - - -static void rio_enable_tx_interrupts(void *ptr) -{ - struct Port *PortP = ptr; - /* int hn; */ - - func_enter(); - - /* hn = PortP->HostP - p->RIOHosts; - - rio_dprintk (RIO_DEBUG_TTY, "Pushing host %d\n", hn); - rio_interrupt (-1,(void *) hn, NULL); */ - - RIOTxEnable((char *) PortP); - - /* - * In general we cannot count on "tx empty" interrupts, although - * the interrupt routine seems to be able to tell the difference. - */ - PortP->gs.port.flags &= ~GS_TX_INTEN; - - func_exit(); -} - - -static void rio_disable_rx_interrupts(void *ptr) -{ - func_enter(); - func_exit(); -} - -static void rio_enable_rx_interrupts(void *ptr) -{ - /* struct rio_port *port = ptr; */ - func_enter(); - func_exit(); -} - - -/* Jeez. Isn't this simple? */ -static int rio_carrier_raised(struct tty_port *port) -{ - struct Port *PortP = container_of(port, struct Port, gs.port); - int rv; - - func_enter(); - rv = (PortP->ModemState & RIOC_MSVR1_CD) != 0; - - rio_dprintk(RIO_DEBUG_INIT, "Getting CD status: %d\n", rv); - - func_exit(); - return rv; -} - - -/* Jeez. Isn't this simple? Actually, we can sync with the actual port - by just pushing stuff into the queue going to the port... */ -static int rio_chars_in_buffer(void *ptr) -{ - func_enter(); - - func_exit(); - return 0; -} - - -/* Nothing special here... */ -static void rio_shutdown_port(void *ptr) -{ - struct Port *PortP; - - func_enter(); - - PortP = (struct Port *) ptr; - PortP->gs.port.tty = NULL; - func_exit(); -} - - -/* I haven't the foggiest why the decrement use count has to happen - here. The whole linux serial drivers stuff needs to be redesigned. - My guess is that this is a hack to minimize the impact of a bug - elsewhere. Thinking about it some more. (try it sometime) Try - running minicom on a serial port that is driven by a modularized - driver. Have the modem hangup. Then remove the driver module. Then - exit minicom. I expect an "oops". -- REW */ -static void rio_hungup(void *ptr) -{ - struct Port *PortP; - - func_enter(); - - PortP = (struct Port *) ptr; - PortP->gs.port.tty = NULL; - - func_exit(); -} - - -/* The standard serial_close would become shorter if you'd wrap it like - this. - rs_close (...){save_flags;cli;real_close();dec_use_count;restore_flags;} - */ -static void rio_close(void *ptr) -{ - struct Port *PortP; - - func_enter(); - - PortP = (struct Port *) ptr; - - riotclose(ptr); - - if (PortP->gs.port.count) { - printk(KERN_ERR "WARNING port count:%d\n", PortP->gs.port.count); - PortP->gs.port.count = 0; - } - - PortP->gs.port.tty = NULL; - func_exit(); -} - - - -static long rio_fw_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - int rc = 0; - func_enter(); - - /* The "dev" argument isn't used. */ - mutex_lock(&rio_fw_mutex); - rc = riocontrol(p, 0, cmd, arg, capable(CAP_SYS_ADMIN)); - mutex_unlock(&rio_fw_mutex); - - func_exit(); - return rc; -} - -extern int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg); - -static int rio_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg) -{ - void __user *argp = (void __user *)arg; - int rc; - struct Port *PortP; - int ival; - - func_enter(); - - PortP = (struct Port *) tty->driver_data; - - rc = 0; - switch (cmd) { - case TIOCSSOFTCAR: - if ((rc = get_user(ival, (unsigned __user *) argp)) == 0) { - tty->termios->c_cflag = (tty->termios->c_cflag & ~CLOCAL) | (ival ? CLOCAL : 0); - } - break; - case TIOCGSERIAL: - rc = -EFAULT; - if (access_ok(VERIFY_WRITE, argp, sizeof(struct serial_struct))) - rc = gs_getserial(&PortP->gs, argp); - break; - case TCSBRK: - if (PortP->State & RIO_DELETED) { - rio_dprintk(RIO_DEBUG_TTY, "BREAK on deleted RTA\n"); - rc = -EIO; - } else { - if (RIOShortCommand(p, PortP, RIOC_SBREAK, 2, 250) == - RIO_FAIL) { - rio_dprintk(RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n"); - rc = -EIO; - } - } - break; - case TCSBRKP: - if (PortP->State & RIO_DELETED) { - rio_dprintk(RIO_DEBUG_TTY, "BREAK on deleted RTA\n"); - rc = -EIO; - } else { - int l; - l = arg ? arg * 100 : 250; - if (l > 255) - l = 255; - if (RIOShortCommand(p, PortP, RIOC_SBREAK, 2, - arg ? arg * 100 : 250) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n"); - rc = -EIO; - } - } - break; - case TIOCSSERIAL: - rc = -EFAULT; - if (access_ok(VERIFY_READ, argp, sizeof(struct serial_struct))) - rc = gs_setserial(&PortP->gs, argp); - break; - default: - rc = -ENOIOCTLCMD; - break; - } - func_exit(); - return rc; -} - - -/* The throttle/unthrottle scheme for the Specialix card is different - * from other drivers and deserves some explanation. - * The Specialix hardware takes care of XON/XOFF - * and CTS/RTS flow control itself. This means that all we have to - * do when signalled by the upper tty layer to throttle/unthrottle is - * to make a note of it here. When we come to read characters from the - * rx buffers on the card (rio_receive_chars()) we look to see if the - * upper layer can accept more (as noted here in rio_rx_throt[]). - * If it can't we simply don't remove chars from the cards buffer. - * When the tty layer can accept chars, we again note that here and when - * rio_receive_chars() is called it will remove them from the cards buffer. - * The card will notice that a ports buffer has drained below some low - * water mark and will unflow control the line itself, using whatever - * flow control scheme is in use for that port. -- Simon Allen - */ - -static void rio_throttle(struct tty_struct *tty) -{ - struct Port *port = (struct Port *) tty->driver_data; - - func_enter(); - /* If the port is using any type of input flow - * control then throttle the port. - */ - - if ((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty))) { - port->State |= RIO_THROTTLE_RX; - } - - func_exit(); -} - - -static void rio_unthrottle(struct tty_struct *tty) -{ - struct Port *port = (struct Port *) tty->driver_data; - - func_enter(); - /* Always unthrottle even if flow control is not enabled on - * this port in case we disabled flow control while the port - * was throttled - */ - - port->State &= ~RIO_THROTTLE_RX; - - func_exit(); - return; -} - - - - - -/* ********************************************************************** * - * Here are the initialization routines. * - * ********************************************************************** */ - - -static struct vpd_prom *get_VPD_PROM(struct Host *hp) -{ - static struct vpd_prom vpdp; - char *p; - int i; - - func_enter(); - rio_dprintk(RIO_DEBUG_PROBE, "Going to verify vpd prom at %p.\n", hp->Caddr + RIO_VPD_ROM); - - p = (char *) &vpdp; - for (i = 0; i < sizeof(struct vpd_prom); i++) - *p++ = readb(hp->Caddr + RIO_VPD_ROM + i * 2); - /* read_rio_byte (hp, RIO_VPD_ROM + i*2); */ - - /* Terminate the identifier string. - *** requires one extra byte in struct vpd_prom *** */ - *p++ = 0; - - if (rio_debug & RIO_DEBUG_PROBE) - my_hd((char *) &vpdp, 0x20); - - func_exit(); - - return &vpdp; -} - -static const struct tty_operations rio_ops = { - .open = riotopen, - .close = gs_close, - .write = gs_write, - .put_char = gs_put_char, - .flush_chars = gs_flush_chars, - .write_room = gs_write_room, - .chars_in_buffer = gs_chars_in_buffer, - .flush_buffer = gs_flush_buffer, - .ioctl = rio_ioctl, - .throttle = rio_throttle, - .unthrottle = rio_unthrottle, - .set_termios = gs_set_termios, - .stop = gs_stop, - .start = gs_start, - .hangup = gs_hangup, -}; - -static int rio_init_drivers(void) -{ - int error = -ENOMEM; - - rio_driver = alloc_tty_driver(256); - if (!rio_driver) - goto out; - rio_driver2 = alloc_tty_driver(256); - if (!rio_driver2) - goto out1; - - func_enter(); - - rio_driver->owner = THIS_MODULE; - rio_driver->driver_name = "specialix_rio"; - rio_driver->name = "ttySR"; - rio_driver->major = RIO_NORMAL_MAJOR0; - rio_driver->type = TTY_DRIVER_TYPE_SERIAL; - rio_driver->subtype = SERIAL_TYPE_NORMAL; - rio_driver->init_termios = tty_std_termios; - rio_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - rio_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(rio_driver, &rio_ops); - - rio_driver2->owner = THIS_MODULE; - rio_driver2->driver_name = "specialix_rio"; - rio_driver2->name = "ttySR"; - rio_driver2->major = RIO_NORMAL_MAJOR1; - rio_driver2->type = TTY_DRIVER_TYPE_SERIAL; - rio_driver2->subtype = SERIAL_TYPE_NORMAL; - rio_driver2->init_termios = tty_std_termios; - rio_driver2->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - rio_driver2->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(rio_driver2, &rio_ops); - - rio_dprintk(RIO_DEBUG_INIT, "set_termios = %p\n", gs_set_termios); - - if ((error = tty_register_driver(rio_driver))) - goto out2; - if ((error = tty_register_driver(rio_driver2))) - goto out3; - func_exit(); - return 0; - out3: - tty_unregister_driver(rio_driver); - out2: - put_tty_driver(rio_driver2); - out1: - put_tty_driver(rio_driver); - out: - printk(KERN_ERR "rio: Couldn't register a rio driver, error = %d\n", error); - return 1; -} - -static const struct tty_port_operations rio_port_ops = { - .carrier_raised = rio_carrier_raised, -}; - -static int rio_init_datastructures(void) -{ - int i; - struct Port *port; - func_enter(); - - /* Many drivers statically allocate the maximum number of ports - There is no reason not to allocate them dynamically. Is there? -- REW */ - /* However, the RIO driver allows users to configure their first - RTA as the ports numbered 504-511. We therefore need to allocate - the whole range. :-( -- REW */ - -#define RI_SZ sizeof(struct rio_info) -#define HOST_SZ sizeof(struct Host) -#define PORT_SZ sizeof(struct Port *) -#define TMIO_SZ sizeof(struct termios *) - rio_dprintk(RIO_DEBUG_INIT, "getting : %Zd %Zd %Zd %Zd %Zd bytes\n", RI_SZ, RIO_HOSTS * HOST_SZ, RIO_PORTS * PORT_SZ, RIO_PORTS * TMIO_SZ, RIO_PORTS * TMIO_SZ); - - if (!(p = kzalloc(RI_SZ, GFP_KERNEL))) - goto free0; - if (!(p->RIOHosts = kzalloc(RIO_HOSTS * HOST_SZ, GFP_KERNEL))) - goto free1; - if (!(p->RIOPortp = kzalloc(RIO_PORTS * PORT_SZ, GFP_KERNEL))) - goto free2; - p->RIOConf = RIOConf; - rio_dprintk(RIO_DEBUG_INIT, "Got : %p %p %p\n", p, p->RIOHosts, p->RIOPortp); - -#if 1 - for (i = 0; i < RIO_PORTS; i++) { - port = p->RIOPortp[i] = kzalloc(sizeof(struct Port), GFP_KERNEL); - if (!port) { - goto free6; - } - rio_dprintk(RIO_DEBUG_INIT, "initing port %d (%d)\n", i, port->Mapped); - tty_port_init(&port->gs.port); - port->gs.port.ops = &rio_port_ops; - port->PortNum = i; - port->gs.magic = RIO_MAGIC; - port->gs.close_delay = HZ / 2; - port->gs.closing_wait = 30 * HZ; - port->gs.rd = &rio_real_driver; - spin_lock_init(&port->portSem); - } -#else - /* We could postpone initializing them to when they are configured. */ -#endif - - - - if (rio_debug & RIO_DEBUG_INIT) { - my_hd(&rio_real_driver, sizeof(rio_real_driver)); - } - - - func_exit(); - return 0; - - free6:for (i--; i >= 0; i--) - kfree(p->RIOPortp[i]); -/*free5: - free4: - free3:*/ kfree(p->RIOPortp); - free2:kfree(p->RIOHosts); - free1: - rio_dprintk(RIO_DEBUG_INIT, "Not enough memory! %p %p %p\n", p, p->RIOHosts, p->RIOPortp); - kfree(p); - free0: - return -ENOMEM; -} - -static void __exit rio_release_drivers(void) -{ - func_enter(); - tty_unregister_driver(rio_driver2); - tty_unregister_driver(rio_driver); - put_tty_driver(rio_driver2); - put_tty_driver(rio_driver); - func_exit(); -} - - -#ifdef CONFIG_PCI - /* This was written for SX, but applies to RIO too... - (including bugs....) - - There is another bit besides Bit 17. Turning that bit off - (on boards shipped with the fix in the eeprom) results in a - hang on the next access to the card. - */ - - /******************************************************** - * Setting bit 17 in the CNTRL register of the PLX 9050 * - * chip forces a retry on writes while a read is pending.* - * This is to prevent the card locking up on Intel Xeon * - * multiprocessor systems with the NX chipset. -- NV * - ********************************************************/ - -/* Newer cards are produced with this bit set from the configuration - EEprom. As the bit is read/write for the CPU, we can fix it here, - if we detect that it isn't set correctly. -- REW */ - -static void fix_rio_pci(struct pci_dev *pdev) -{ - unsigned long hwbase; - unsigned char __iomem *rebase; - unsigned int t; - -#define CNTRL_REG_OFFSET 0x50 -#define CNTRL_REG_GOODVALUE 0x18260000 - - hwbase = pci_resource_start(pdev, 0); - rebase = ioremap(hwbase, 0x80); - t = readl(rebase + CNTRL_REG_OFFSET); - if (t != CNTRL_REG_GOODVALUE) { - printk(KERN_DEBUG "rio: performing cntrl reg fix: %08x -> %08x\n", t, CNTRL_REG_GOODVALUE); - writel(CNTRL_REG_GOODVALUE, rebase + CNTRL_REG_OFFSET); - } - iounmap(rebase); -} -#endif - - -static int __init rio_init(void) -{ - int found = 0; - int i; - struct Host *hp; - int retval; - struct vpd_prom *vpdp; - int okboard; - -#ifdef CONFIG_PCI - struct pci_dev *pdev = NULL; - unsigned short tshort; -#endif - - func_enter(); - rio_dprintk(RIO_DEBUG_INIT, "Initing rio module... (rio_debug=%d)\n", rio_debug); - - if (abs((long) (&rio_debug) - rio_debug) < 0x10000) { - printk(KERN_WARNING "rio: rio_debug is an address, instead of a value. " "Assuming -1. Was %x/%p.\n", rio_debug, &rio_debug); - rio_debug = -1; - } - - if (misc_register(&rio_fw_device) < 0) { - printk(KERN_ERR "RIO: Unable to register firmware loader driver.\n"); - return -EIO; - } - - retval = rio_init_datastructures(); - if (retval < 0) { - misc_deregister(&rio_fw_device); - return retval; - } -#ifdef CONFIG_PCI - /* First look for the JET devices: */ - while ((pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, pdev))) { - u32 tint; - - if (pci_enable_device(pdev)) - continue; - - /* Specialix has a whole bunch of cards with - 0x2000 as the device ID. They say its because - the standard requires it. Stupid standard. */ - /* It seems that reading a word doesn't work reliably on 2.0. - Also, reading a non-aligned dword doesn't work. So we read the - whole dword at 0x2c and extract the word at 0x2e (SUBSYSTEM_ID) - ourselves */ - pci_read_config_dword(pdev, 0x2c, &tint); - tshort = (tint >> 16) & 0xffff; - rio_dprintk(RIO_DEBUG_PROBE, "Got a specialix card: %x.\n", tint); - if (tshort != 0x0100) { - rio_dprintk(RIO_DEBUG_PROBE, "But it's not a RIO card (%d)...\n", tshort); - continue; - } - rio_dprintk(RIO_DEBUG_PROBE, "cp1\n"); - - hp = &p->RIOHosts[p->RIONumHosts]; - hp->PaddrP = pci_resource_start(pdev, 2); - hp->Ivec = pdev->irq; - if (((1 << hp->Ivec) & rio_irqmask) == 0) - hp->Ivec = 0; - hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); - hp->CardP = (struct DpRam __iomem *) hp->Caddr; - hp->Type = RIO_PCI; - hp->Copy = rio_copy_to_card; - hp->Mode = RIO_PCI_BOOT_FROM_RAM; - spin_lock_init(&hp->HostLock); - rio_reset_interrupt(hp); - rio_start_card_running(hp); - - rio_dprintk(RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n", (void *) p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr); - if (RIOBoardTest(p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr, RIO_PCI, 0) == 0) { - rio_dprintk(RIO_DEBUG_INIT, "Done RIOBoardTest\n"); - writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt); - p->RIOHosts[p->RIONumHosts].UniqueNum = - ((readb(&p->RIOHosts[p->RIONumHosts].Unique[0]) & 0xFF) << 0) | - ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24); - rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); - - fix_rio_pci(pdev); - - p->RIOHosts[p->RIONumHosts].pdev = pdev; - pci_dev_get(pdev); - - p->RIOLastPCISearch = 0; - p->RIONumHosts++; - found++; - } else { - iounmap(p->RIOHosts[p->RIONumHosts].Caddr); - p->RIOHosts[p->RIONumHosts].Caddr = NULL; - } - } - - /* Then look for the older PCI card.... : */ - - /* These older PCI cards have problems (only byte-mode access is - supported), which makes them a bit awkward to support. - They also have problems sharing interrupts. Be careful. - (The driver now refuses to share interrupts for these - cards. This should be sufficient). - */ - - /* Then look for the older RIO/PCI devices: */ - while ((pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_RIO, pdev))) { - if (pci_enable_device(pdev)) - continue; - -#ifdef CONFIG_RIO_OLDPCI - hp = &p->RIOHosts[p->RIONumHosts]; - hp->PaddrP = pci_resource_start(pdev, 0); - hp->Ivec = pdev->irq; - if (((1 << hp->Ivec) & rio_irqmask) == 0) - hp->Ivec = 0; - hp->Ivec |= 0x8000; /* Mark as non-sharable */ - hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); - hp->CardP = (struct DpRam __iomem *) hp->Caddr; - hp->Type = RIO_PCI; - hp->Copy = rio_copy_to_card; - hp->Mode = RIO_PCI_BOOT_FROM_RAM; - spin_lock_init(&hp->HostLock); - - rio_dprintk(RIO_DEBUG_PROBE, "Ivec: %x\n", hp->Ivec); - rio_dprintk(RIO_DEBUG_PROBE, "Mode: %x\n", hp->Mode); - - rio_reset_interrupt(hp); - rio_start_card_running(hp); - rio_dprintk(RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n", (void *) p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr); - if (RIOBoardTest(p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr, RIO_PCI, 0) == 0) { - writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt); - p->RIOHosts[p->RIONumHosts].UniqueNum = - ((readb(&p->RIOHosts[p->RIONumHosts].Unique[0]) & 0xFF) << 0) | - ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24); - rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); - - p->RIOHosts[p->RIONumHosts].pdev = pdev; - pci_dev_get(pdev); - - p->RIOLastPCISearch = 0; - p->RIONumHosts++; - found++; - } else { - iounmap(p->RIOHosts[p->RIONumHosts].Caddr); - p->RIOHosts[p->RIONumHosts].Caddr = NULL; - } -#else - printk(KERN_ERR "Found an older RIO PCI card, but the driver is not " "compiled to support it.\n"); -#endif - } -#endif /* PCI */ - - /* Now probe for ISA cards... */ - for (i = 0; i < NR_RIO_ADDRS; i++) { - hp = &p->RIOHosts[p->RIONumHosts]; - hp->PaddrP = rio_probe_addrs[i]; - /* There was something about the IRQs of these cards. 'Forget what.--REW */ - hp->Ivec = 0; - hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); - hp->CardP = (struct DpRam __iomem *) hp->Caddr; - hp->Type = RIO_AT; - hp->Copy = rio_copy_to_card; /* AT card PCI???? - PVDL - * -- YES! this is now a normal copy. Only the - * old PCI card uses the special PCI copy. - * Moreover, the ISA card will work with the - * special PCI copy anyway. -- REW */ - hp->Mode = 0; - spin_lock_init(&hp->HostLock); - - vpdp = get_VPD_PROM(hp); - rio_dprintk(RIO_DEBUG_PROBE, "Got VPD ROM\n"); - okboard = 0; - if ((strncmp(vpdp->identifier, RIO_ISA_IDENT, 16) == 0) || (strncmp(vpdp->identifier, RIO_ISA2_IDENT, 16) == 0) || (strncmp(vpdp->identifier, RIO_ISA3_IDENT, 16) == 0)) { - /* Board is present... */ - if (RIOBoardTest(hp->PaddrP, hp->Caddr, RIO_AT, 0) == 0) { - /* ... and feeling fine!!!! */ - rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); - if (RIOAssignAT(p, hp->PaddrP, hp->Caddr, 0)) { - rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, host%d uniqid = %x.\n", p->RIONumHosts, p->RIOHosts[p->RIONumHosts - 1].UniqueNum); - okboard++; - found++; - } - } - - if (!okboard) { - iounmap(hp->Caddr); - hp->Caddr = NULL; - } - } - } - - - for (i = 0; i < p->RIONumHosts; i++) { - hp = &p->RIOHosts[i]; - if (hp->Ivec) { - int mode = IRQF_SHARED; - if (hp->Ivec & 0x8000) { - mode = 0; - hp->Ivec &= 0x7fff; - } - rio_dprintk(RIO_DEBUG_INIT, "Requesting interrupt hp: %p rio_interrupt: %d Mode: %x\n", hp, hp->Ivec, hp->Mode); - retval = request_irq(hp->Ivec, rio_interrupt, mode, "rio", hp); - rio_dprintk(RIO_DEBUG_INIT, "Return value from request_irq: %d\n", retval); - if (retval) { - printk(KERN_ERR "rio: Cannot allocate irq %d.\n", hp->Ivec); - hp->Ivec = 0; - } - rio_dprintk(RIO_DEBUG_INIT, "Got irq %d.\n", hp->Ivec); - if (hp->Ivec != 0) { - rio_dprintk(RIO_DEBUG_INIT, "Enabling interrupts on rio card.\n"); - hp->Mode |= RIO_PCI_INT_ENABLE; - } else - hp->Mode &= ~RIO_PCI_INT_ENABLE; - rio_dprintk(RIO_DEBUG_INIT, "New Mode: %x\n", hp->Mode); - rio_start_card_running(hp); - } - /* Init the timer "always" to make sure that it can safely be - deleted when we unload... */ - - setup_timer(&hp->timer, rio_pollfunc, i); - if (!hp->Ivec) { - rio_dprintk(RIO_DEBUG_INIT, "Starting polling at %dj intervals.\n", rio_poll); - mod_timer(&hp->timer, jiffies + rio_poll); - } - } - - if (found) { - rio_dprintk(RIO_DEBUG_INIT, "rio: total of %d boards detected.\n", found); - rio_init_drivers(); - } else { - /* deregister the misc device we created earlier */ - misc_deregister(&rio_fw_device); - } - - func_exit(); - return found ? 0 : -EIO; -} - - -static void __exit rio_exit(void) -{ - int i; - struct Host *hp; - - func_enter(); - - for (i = 0, hp = p->RIOHosts; i < p->RIONumHosts; i++, hp++) { - RIOHostReset(hp->Type, hp->CardP, hp->Slot); - if (hp->Ivec) { - free_irq(hp->Ivec, hp); - rio_dprintk(RIO_DEBUG_INIT, "freed irq %d.\n", hp->Ivec); - } - /* It is safe/allowed to del_timer a non-active timer */ - del_timer_sync(&hp->timer); - if (hp->Caddr) - iounmap(hp->Caddr); - if (hp->Type == RIO_PCI) - pci_dev_put(hp->pdev); - } - - if (misc_deregister(&rio_fw_device) < 0) { - printk(KERN_INFO "rio: couldn't deregister control-device\n"); - } - - - rio_dprintk(RIO_DEBUG_CLEANUP, "Cleaning up drivers\n"); - - rio_release_drivers(); - - /* Release dynamically allocated memory */ - kfree(p->RIOPortp); - kfree(p->RIOHosts); - kfree(p); - - func_exit(); -} - -module_init(rio_init); -module_exit(rio_exit); diff --git a/drivers/char/rio/rio_linux.h b/drivers/char/rio/rio_linux.h deleted file mode 100644 index 7f26cd7c815e..000000000000 --- a/drivers/char/rio/rio_linux.h +++ /dev/null @@ -1,197 +0,0 @@ - -/* - * rio_linux.h - * - * Copyright (C) 1998,1999,2000 R.E.Wolff@BitWizard.nl - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * RIO serial driver. - * - * Version 1.0 -- July, 1999. - * - */ - -#define RIO_NBOARDS 4 -#define RIO_PORTSPERBOARD 128 -#define RIO_NPORTS (RIO_NBOARDS * RIO_PORTSPERBOARD) - -#define MODEM_SUPPORT - -#ifdef __KERNEL__ - -#define RIO_MAGIC 0x12345678 - - -struct vpd_prom { - unsigned short id; - char hwrev; - char hwass; - int uniqid; - char myear; - char mweek; - char hw_feature[5]; - char oem_id; - char identifier[16]; -}; - - -#define RIO_DEBUG_ALL 0xffffffff - -#define O_OTHER(tty) \ - ((O_OLCUC(tty)) ||\ - (O_ONLCR(tty)) ||\ - (O_OCRNL(tty)) ||\ - (O_ONOCR(tty)) ||\ - (O_ONLRET(tty)) ||\ - (O_OFILL(tty)) ||\ - (O_OFDEL(tty)) ||\ - (O_NLDLY(tty)) ||\ - (O_CRDLY(tty)) ||\ - (O_TABDLY(tty)) ||\ - (O_BSDLY(tty)) ||\ - (O_VTDLY(tty)) ||\ - (O_FFDLY(tty))) - -/* Same for input. */ -#define I_OTHER(tty) \ - ((I_INLCR(tty)) ||\ - (I_IGNCR(tty)) ||\ - (I_ICRNL(tty)) ||\ - (I_IUCLC(tty)) ||\ - (L_ISIG(tty))) - - -#endif /* __KERNEL__ */ - - -#define RIO_BOARD_INTR_LOCK 1 - - -#ifndef RIOCTL_MISC_MINOR -/* Allow others to gather this into "major.h" or something like that */ -#define RIOCTL_MISC_MINOR 169 -#endif - - -/* Allow us to debug "in the field" without requiring clients to - recompile.... */ -#if 1 -#define rio_spin_lock_irqsave(sem, flags) do { \ - rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlockirqsave: %p %s:%d\n", \ - sem, __FILE__, __LINE__);\ - spin_lock_irqsave(sem, flags);\ - } while (0) - -#define rio_spin_unlock_irqrestore(sem, flags) do { \ - rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlockirqrestore: %p %s:%d\n",\ - sem, __FILE__, __LINE__);\ - spin_unlock_irqrestore(sem, flags);\ - } while (0) - -#define rio_spin_lock(sem) do { \ - rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlock: %p %s:%d\n",\ - sem, __FILE__, __LINE__);\ - spin_lock(sem);\ - } while (0) - -#define rio_spin_unlock(sem) do { \ - rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlock: %p %s:%d\n",\ - sem, __FILE__, __LINE__);\ - spin_unlock(sem);\ - } while (0) -#else -#define rio_spin_lock_irqsave(sem, flags) \ - spin_lock_irqsave(sem, flags) - -#define rio_spin_unlock_irqrestore(sem, flags) \ - spin_unlock_irqrestore(sem, flags) - -#define rio_spin_lock(sem) \ - spin_lock(sem) - -#define rio_spin_unlock(sem) \ - spin_unlock(sem) - -#endif - - - -#ifdef CONFIG_RIO_OLDPCI -static inline void __iomem *rio_memcpy_toio(void __iomem *dummy, void __iomem *dest, void *source, int n) -{ - char __iomem *dst = dest; - char *src = source; - - while (n--) { - writeb(*src++, dst++); - (void) readb(dummy); - } - - return dest; -} - -static inline void __iomem *rio_copy_toio(void __iomem *dest, void *source, int n) -{ - char __iomem *dst = dest; - char *src = source; - - while (n--) - writeb(*src++, dst++); - - return dest; -} - - -static inline void *rio_memcpy_fromio(void *dest, void __iomem *source, int n) -{ - char *dst = dest; - char __iomem *src = source; - - while (n--) - *dst++ = readb(src++); - - return dest; -} - -#else -#define rio_memcpy_toio(dummy,dest,source,n) memcpy_toio(dest, source, n) -#define rio_copy_toio memcpy_toio -#define rio_memcpy_fromio memcpy_fromio -#endif - -#define DEBUG 1 - - -/* - This driver can spew a whole lot of debugging output at you. If you - need maximum performance, you should disable the DEBUG define. To - aid in debugging in the field, I'm leaving the compile-time debug - features enabled, and disable them "runtime". That allows me to - instruct people with problems to enable debugging without requiring - them to recompile... -*/ - -#ifdef DEBUG -#define rio_dprintk(f, str...) do { if (rio_debug & f) printk (str);} while (0) -#define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s\n", __func__) -#define func_exit() rio_dprintk (RIO_DEBUG_FLOW, "rio: exit %s\n", __func__) -#define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s (port %d)\n",__func__, port->line) -#else -#define rio_dprintk(f, str...) /* nothing */ -#define func_enter() -#define func_exit() -#define func_enter2() -#endif diff --git a/drivers/char/rio/rioboard.h b/drivers/char/rio/rioboard.h deleted file mode 100644 index 252230043c82..000000000000 --- a/drivers/char/rio/rioboard.h +++ /dev/null @@ -1,275 +0,0 @@ -/************************************************************************/ -/* */ -/* Title : RIO Host Card Hardware Definitions */ -/* */ -/* Author : N.P.Vassallo */ -/* */ -/* Creation : 26th April 1999 */ -/* */ -/* Version : 1.0.0 */ -/* */ -/* Copyright : (c) Specialix International Ltd. 1999 * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * */ -/* Description : Prototypes, structures and definitions */ -/* describing the RIO board hardware */ -/* */ -/************************************************************************/ - -#ifndef _rioboard_h /* If RIOBOARD.H not already defined */ -#define _rioboard_h 1 - -/***************************************************************************** -*********************** *********************** -*********************** Hardware Control Registers *********************** -*********************** *********************** -*****************************************************************************/ - -/* Hardware Registers... */ - -#define RIO_REG_BASE 0x7C00 /* Base of control registers */ - -#define RIO_CONFIG RIO_REG_BASE + 0x0000 /* WRITE: Configuration Register */ -#define RIO_INTSET RIO_REG_BASE + 0x0080 /* WRITE: Interrupt Set */ -#define RIO_RESET RIO_REG_BASE + 0x0100 /* WRITE: Host Reset */ -#define RIO_INTRESET RIO_REG_BASE + 0x0180 /* WRITE: Interrupt Reset */ - -#define RIO_VPD_ROM RIO_REG_BASE + 0x0000 /* READ: Vital Product Data ROM */ -#define RIO_INTSTAT RIO_REG_BASE + 0x0080 /* READ: Interrupt Status (Jet boards only) */ -#define RIO_RESETSTAT RIO_REG_BASE + 0x0100 /* READ: Reset Status (Jet boards only) */ - -/* RIO_VPD_ROM definitions... */ -#define VPD_SLX_ID1 0x00 /* READ: Specialix Identifier #1 */ -#define VPD_SLX_ID2 0x01 /* READ: Specialix Identifier #2 */ -#define VPD_HW_REV 0x02 /* READ: Hardware Revision */ -#define VPD_HW_ASSEM 0x03 /* READ: Hardware Assembly Level */ -#define VPD_UNIQUEID4 0x04 /* READ: Unique Identifier #4 */ -#define VPD_UNIQUEID3 0x05 /* READ: Unique Identifier #3 */ -#define VPD_UNIQUEID2 0x06 /* READ: Unique Identifier #2 */ -#define VPD_UNIQUEID1 0x07 /* READ: Unique Identifier #1 */ -#define VPD_MANU_YEAR 0x08 /* READ: Year Of Manufacture (0 = 1970) */ -#define VPD_MANU_WEEK 0x09 /* READ: Week Of Manufacture (0 = week 1 Jan) */ -#define VPD_HWFEATURE1 0x0A /* READ: Hardware Feature Byte 1 */ -#define VPD_HWFEATURE2 0x0B /* READ: Hardware Feature Byte 2 */ -#define VPD_HWFEATURE3 0x0C /* READ: Hardware Feature Byte 3 */ -#define VPD_HWFEATURE4 0x0D /* READ: Hardware Feature Byte 4 */ -#define VPD_HWFEATURE5 0x0E /* READ: Hardware Feature Byte 5 */ -#define VPD_OEMID 0x0F /* READ: OEM Identifier */ -#define VPD_IDENT 0x10 /* READ: Identifier string (16 bytes) */ -#define VPD_IDENT_LEN 0x10 - -/* VPD ROM Definitions... */ -#define SLX_ID1 0x4D -#define SLX_ID2 0x98 - -#define PRODUCT_ID(a) ((a>>4)&0xF) /* Use to obtain Product ID from VPD_UNIQUEID1 */ - -#define ID_SX_ISA 0x2 -#define ID_RIO_EISA 0x3 -#define ID_SX_PCI 0x5 -#define ID_SX_EISA 0x7 -#define ID_RIO_RTA16 0x9 -#define ID_RIO_ISA 0xA -#define ID_RIO_MCA 0xB -#define ID_RIO_SBUS 0xC -#define ID_RIO_PCI 0xD -#define ID_RIO_RTA8 0xE - -/* Transputer bootstrap definitions... */ - -#define BOOTLOADADDR (0x8000 - 6) -#define BOOTINDICATE (0x8000 - 2) - -/* Firmware load position... */ - -#define FIRMWARELOADADDR 0x7C00 /* Firmware is loaded _before_ this address */ - -/***************************************************************************** -***************************** ***************************** -***************************** RIO (Rev1) ISA ***************************** -***************************** ***************************** -*****************************************************************************/ - -/* Control Register Definitions... */ -#define RIO_ISA_IDENT "JBJGPGGHINSMJPJR" - -#define RIO_ISA_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ -#define RIO_ISA_CFG_BUSENABLE 0x02 /* Enable processor bus */ -#define RIO_ISA_CFG_IRQMASK 0x30 /* Interrupt mask */ -#define RIO_ISA_CFG_IRQ12 0x10 /* Interrupt Level 12 */ -#define RIO_ISA_CFG_IRQ11 0x20 /* Interrupt Level 11 */ -#define RIO_ISA_CFG_IRQ9 0x30 /* Interrupt Level 9 */ -#define RIO_ISA_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ -#define RIO_ISA_CFG_WAITSTATE0 0x80 /* 0 waitstates, else 1 */ - -/***************************************************************************** -***************************** ***************************** -***************************** RIO (Rev2) ISA ***************************** -***************************** ***************************** -*****************************************************************************/ - -/* Control Register Definitions... */ -#define RIO_ISA2_IDENT "JBJGPGGHINSMJPJR" - -#define RIO_ISA2_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ -#define RIO_ISA2_CFG_BUSENABLE 0x02 /* Enable processor bus */ -#define RIO_ISA2_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ -#define RIO_ISA2_CFG_16BIT 0x08 /* 16bit mode, else 8bit */ -#define RIO_ISA2_CFG_IRQMASK 0x30 /* Interrupt mask */ -#define RIO_ISA2_CFG_IRQ15 0x00 /* Interrupt Level 15 */ -#define RIO_ISA2_CFG_IRQ12 0x10 /* Interrupt Level 12 */ -#define RIO_ISA2_CFG_IRQ11 0x20 /* Interrupt Level 11 */ -#define RIO_ISA2_CFG_IRQ9 0x30 /* Interrupt Level 9 */ -#define RIO_ISA2_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ -#define RIO_ISA2_CFG_WAITSTATE0 0x80 /* 0 waitstates, else 1 */ - -/***************************************************************************** -***************************** ****************************** -***************************** RIO (Jet) ISA ****************************** -***************************** ****************************** -*****************************************************************************/ - -/* Control Register Definitions... */ -#define RIO_ISA3_IDENT "JET HOST BY KEV#" - -#define RIO_ISA3_CFG_BUSENABLE 0x02 /* Enable processor bus */ -#define RIO_ISA3_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ -#define RIO_ISA32_CFG_IRQMASK 0xF30 /* Interrupt mask */ -#define RIO_ISA3_CFG_IRQ15 0xF0 /* Interrupt Level 15 */ -#define RIO_ISA3_CFG_IRQ12 0xC0 /* Interrupt Level 12 */ -#define RIO_ISA3_CFG_IRQ11 0xB0 /* Interrupt Level 11 */ -#define RIO_ISA3_CFG_IRQ10 0xA0 /* Interrupt Level 10 */ -#define RIO_ISA3_CFG_IRQ9 0x90 /* Interrupt Level 9 */ - -/***************************************************************************** -********************************* ******************************** -********************************* RIO MCA ******************************** -********************************* ******************************** -*****************************************************************************/ - -/* Control Register Definitions... */ -#define RIO_MCA_IDENT "JBJGPGGHINSMJPJR" - -#define RIO_MCA_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ -#define RIO_MCA_CFG_BUSENABLE 0x02 /* Enable processor bus */ -#define RIO_MCA_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ - -/***************************************************************************** -******************************** ******************************** -******************************** RIO EISA ******************************** -******************************** ******************************** -*****************************************************************************/ - -/* EISA Configuration Space Definitions... */ -#define EISA_PRODUCT_ID1 0xC80 -#define EISA_PRODUCT_ID2 0xC81 -#define EISA_PRODUCT_NUMBER 0xC82 -#define EISA_REVISION_NUMBER 0xC83 -#define EISA_CARD_ENABLE 0xC84 -#define EISA_VPD_UNIQUEID4 0xC88 /* READ: Unique Identifier #4 */ -#define EISA_VPD_UNIQUEID3 0xC8A /* READ: Unique Identifier #3 */ -#define EISA_VPD_UNIQUEID2 0xC90 /* READ: Unique Identifier #2 */ -#define EISA_VPD_UNIQUEID1 0xC92 /* READ: Unique Identifier #1 */ -#define EISA_VPD_MANU_YEAR 0xC98 /* READ: Year Of Manufacture (0 = 1970) */ -#define EISA_VPD_MANU_WEEK 0xC9A /* READ: Week Of Manufacture (0 = week 1 Jan) */ -#define EISA_MEM_ADDR_23_16 0xC00 -#define EISA_MEM_ADDR_31_24 0xC01 -#define EISA_RIO_CONFIG 0xC02 /* WRITE: Configuration Register */ -#define EISA_RIO_INTSET 0xC03 /* WRITE: Interrupt Set */ -#define EISA_RIO_INTRESET 0xC03 /* READ: Interrupt Reset */ - -/* Control Register Definitions... */ -#define RIO_EISA_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ -#define RIO_EISA_CFG_LINK20 0x02 /* 20Mbps link, else 10Mbps */ -#define RIO_EISA_CFG_BUSENABLE 0x04 /* Enable processor bus */ -#define RIO_EISA_CFG_PROCRUN 0x08 /* Processor running, else reset */ -#define RIO_EISA_CFG_IRQMASK 0xF0 /* Interrupt mask */ -#define RIO_EISA_CFG_IRQ15 0xF0 /* Interrupt Level 15 */ -#define RIO_EISA_CFG_IRQ14 0xE0 /* Interrupt Level 14 */ -#define RIO_EISA_CFG_IRQ12 0xC0 /* Interrupt Level 12 */ -#define RIO_EISA_CFG_IRQ11 0xB0 /* Interrupt Level 11 */ -#define RIO_EISA_CFG_IRQ10 0xA0 /* Interrupt Level 10 */ -#define RIO_EISA_CFG_IRQ9 0x90 /* Interrupt Level 9 */ -#define RIO_EISA_CFG_IRQ7 0x70 /* Interrupt Level 7 */ -#define RIO_EISA_CFG_IRQ6 0x60 /* Interrupt Level 6 */ -#define RIO_EISA_CFG_IRQ5 0x50 /* Interrupt Level 5 */ -#define RIO_EISA_CFG_IRQ4 0x40 /* Interrupt Level 4 */ -#define RIO_EISA_CFG_IRQ3 0x30 /* Interrupt Level 3 */ - -/***************************************************************************** -******************************** ******************************** -******************************** RIO SBus ******************************** -******************************** ******************************** -*****************************************************************************/ - -/* Control Register Definitions... */ -#define RIO_SBUS_IDENT "JBPGK#\0\0\0\0\0\0\0\0\0\0" - -#define RIO_SBUS_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ -#define RIO_SBUS_CFG_BUSENABLE 0x02 /* Enable processor bus */ -#define RIO_SBUS_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ -#define RIO_SBUS_CFG_IRQMASK 0x38 /* Interrupt mask */ -#define RIO_SBUS_CFG_IRQNONE 0x00 /* No Interrupt */ -#define RIO_SBUS_CFG_IRQ7 0x38 /* Interrupt Level 7 */ -#define RIO_SBUS_CFG_IRQ6 0x30 /* Interrupt Level 6 */ -#define RIO_SBUS_CFG_IRQ5 0x28 /* Interrupt Level 5 */ -#define RIO_SBUS_CFG_IRQ4 0x20 /* Interrupt Level 4 */ -#define RIO_SBUS_CFG_IRQ3 0x18 /* Interrupt Level 3 */ -#define RIO_SBUS_CFG_IRQ2 0x10 /* Interrupt Level 2 */ -#define RIO_SBUS_CFG_IRQ1 0x08 /* Interrupt Level 1 */ -#define RIO_SBUS_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ -#define RIO_SBUS_CFG_PROC25 0x80 /* 25Mhz processor clock, else 20Mhz */ - -/***************************************************************************** -********************************* ******************************** -********************************* RIO PCI ******************************** -********************************* ******************************** -*****************************************************************************/ - -/* Control Register Definitions... */ -#define RIO_PCI_IDENT "ECDDPGJGJHJRGSK#" - -#define RIO_PCI_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ -#define RIO_PCI_CFG_BUSENABLE 0x02 /* Enable processor bus */ -#define RIO_PCI_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ -#define RIO_PCI_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ -#define RIO_PCI_CFG_PROC25 0x80 /* 25Mhz processor clock, else 20Mhz */ - -/* PCI Definitions... */ -#define SPX_VENDOR_ID 0x11CB /* Assigned by the PCI SIG */ -#define SPX_DEVICE_ID 0x8000 /* RIO bridge boards */ -#define SPX_PLXDEVICE_ID 0x2000 /* PLX bridge boards */ -#define SPX_SUB_VENDOR_ID SPX_VENDOR_ID /* Same as vendor id */ -#define RIO_SUB_SYS_ID 0x0800 /* RIO PCI board */ - -/***************************************************************************** -***************************** ****************************** -***************************** RIO (Jet) PCI ****************************** -***************************** ****************************** -*****************************************************************************/ - -/* Control Register Definitions... */ -#define RIO_PCI2_IDENT "JET HOST BY KEV#" - -#define RIO_PCI2_CFG_BUSENABLE 0x02 /* Enable processor bus */ -#define RIO_PCI2_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ - -/* PCI Definitions... */ -#define RIO2_SUB_SYS_ID 0x0100 /* RIO (Jet) PCI board */ - -#endif /*_rioboard_h */ - -/* End of RIOBOARD.H */ diff --git a/drivers/char/rio/rioboot.c b/drivers/char/rio/rioboot.c deleted file mode 100644 index d956dd316005..000000000000 --- a/drivers/char/rio/rioboot.c +++ /dev/null @@ -1,1113 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : rioboot.c -** SID : 1.3 -** Last Modified : 11/6/98 10:33:36 -** Retrieved : 11/6/98 10:33:48 -** -** ident @(#)rioboot.c 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "linux_compat.h" -#include "rio_linux.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" - -static int RIOBootComplete(struct rio_info *p, struct Host *HostP, unsigned int Rup, struct PktCmd __iomem *PktCmdP); - -static const unsigned char RIOAtVec2Ctrl[] = { - /* 0 */ INTERRUPT_DISABLE, - /* 1 */ INTERRUPT_DISABLE, - /* 2 */ INTERRUPT_DISABLE, - /* 3 */ INTERRUPT_DISABLE, - /* 4 */ INTERRUPT_DISABLE, - /* 5 */ INTERRUPT_DISABLE, - /* 6 */ INTERRUPT_DISABLE, - /* 7 */ INTERRUPT_DISABLE, - /* 8 */ INTERRUPT_DISABLE, - /* 9 */ IRQ_9 | INTERRUPT_ENABLE, - /* 10 */ INTERRUPT_DISABLE, - /* 11 */ IRQ_11 | INTERRUPT_ENABLE, - /* 12 */ IRQ_12 | INTERRUPT_ENABLE, - /* 13 */ INTERRUPT_DISABLE, - /* 14 */ INTERRUPT_DISABLE, - /* 15 */ IRQ_15 | INTERRUPT_ENABLE -}; - -/** - * RIOBootCodeRTA - Load RTA boot code - * @p: RIO to load - * @rbp: Download descriptor - * - * Called when the user process initiates booting of the card firmware. - * Lads the firmware - */ - -int RIOBootCodeRTA(struct rio_info *p, struct DownLoad * rbp) -{ - int offset; - - func_enter(); - - rio_dprintk(RIO_DEBUG_BOOT, "Data at user address %p\n", rbp->DataP); - - /* - ** Check that we have set asside enough memory for this - */ - if (rbp->Count > SIXTY_FOUR_K) { - rio_dprintk(RIO_DEBUG_BOOT, "RTA Boot Code Too Large!\n"); - p->RIOError.Error = HOST_FILE_TOO_LARGE; - func_exit(); - return -ENOMEM; - } - - if (p->RIOBooting) { - rio_dprintk(RIO_DEBUG_BOOT, "RTA Boot Code : BUSY BUSY BUSY!\n"); - p->RIOError.Error = BOOT_IN_PROGRESS; - func_exit(); - return -EBUSY; - } - - /* - ** The data we load in must end on a (RTA_BOOT_DATA_SIZE) byte boundary, - ** so calculate how far we have to move the data up the buffer - ** to achieve this. - */ - offset = (RTA_BOOT_DATA_SIZE - (rbp->Count % RTA_BOOT_DATA_SIZE)) % RTA_BOOT_DATA_SIZE; - - /* - ** Be clean, and clear the 'unused' portion of the boot buffer, - ** because it will (eventually) be part of the Rta run time environment - ** and so should be zeroed. - */ - memset(p->RIOBootPackets, 0, offset); - - /* - ** Copy the data from user space into the array - */ - - if (copy_from_user(((u8 *)p->RIOBootPackets) + offset, rbp->DataP, rbp->Count)) { - rio_dprintk(RIO_DEBUG_BOOT, "Bad data copy from user space\n"); - p->RIOError.Error = COPYIN_FAILED; - func_exit(); - return -EFAULT; - } - - /* - ** Make sure that our copy of the size includes that offset we discussed - ** earlier. - */ - p->RIONumBootPkts = (rbp->Count + offset) / RTA_BOOT_DATA_SIZE; - p->RIOBootCount = rbp->Count; - - func_exit(); - return 0; -} - -/** - * rio_start_card_running - host card start - * @HostP: The RIO to kick off - * - * Start a RIO processor unit running. Encapsulates the knowledge - * of the card type. - */ - -void rio_start_card_running(struct Host *HostP) -{ - switch (HostP->Type) { - case RIO_AT: - rio_dprintk(RIO_DEBUG_BOOT, "Start ISA card running\n"); - writeb(BOOT_FROM_RAM | EXTERNAL_BUS_ON | HostP->Mode | RIOAtVec2Ctrl[HostP->Ivec & 0xF], &HostP->Control); - break; - case RIO_PCI: - /* - ** PCI is much the same as MCA. Everything is once again memory - ** mapped, so we are writing to memory registers instead of io - ** ports. - */ - rio_dprintk(RIO_DEBUG_BOOT, "Start PCI card running\n"); - writeb(PCITpBootFromRam | PCITpBusEnable | HostP->Mode, &HostP->Control); - break; - default: - rio_dprintk(RIO_DEBUG_BOOT, "Unknown host type %d\n", HostP->Type); - break; - } - return; -} - -/* -** Load in the host boot code - load it directly onto all halted hosts -** of the correct type. -** -** Put your rubber pants on before messing with this code - even the magic -** numbers have trouble understanding what they are doing here. -*/ - -int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp) -{ - struct Host *HostP; - u8 __iomem *Cad; - PARM_MAP __iomem *ParmMapP; - int RupN; - int PortN; - unsigned int host; - u8 __iomem *StartP; - u8 __iomem *DestP; - int wait_count; - u16 OldParmMap; - u16 offset; /* It is very important that this is a u16 */ - u8 *DownCode = NULL; - unsigned long flags; - - HostP = NULL; /* Assure the compiler we've initialized it */ - - - /* Walk the hosts */ - for (host = 0; host < p->RIONumHosts; host++) { - rio_dprintk(RIO_DEBUG_BOOT, "Attempt to boot host %d\n", host); - HostP = &p->RIOHosts[host]; - - rio_dprintk(RIO_DEBUG_BOOT, "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n", HostP->Type, HostP->Mode, HostP->Ivec); - - /* Don't boot hosts already running */ - if ((HostP->Flags & RUN_STATE) != RC_WAITING) { - rio_dprintk(RIO_DEBUG_BOOT, "%s %d already running\n", "Host", host); - continue; - } - - /* - ** Grab a pointer to the card (ioremapped) - */ - Cad = HostP->Caddr; - - /* - ** We are going to (try) and load in rbp->Count bytes. - ** The last byte will reside at p->RIOConf.HostLoadBase-1; - ** Therefore, we need to start copying at address - ** (caddr+p->RIOConf.HostLoadBase-rbp->Count) - */ - StartP = &Cad[p->RIOConf.HostLoadBase - rbp->Count]; - - rio_dprintk(RIO_DEBUG_BOOT, "kernel virtual address for host is %p\n", Cad); - rio_dprintk(RIO_DEBUG_BOOT, "kernel virtual address for download is %p\n", StartP); - rio_dprintk(RIO_DEBUG_BOOT, "host loadbase is 0x%x\n", p->RIOConf.HostLoadBase); - rio_dprintk(RIO_DEBUG_BOOT, "size of download is 0x%x\n", rbp->Count); - - /* Make sure it fits */ - if (p->RIOConf.HostLoadBase < rbp->Count) { - rio_dprintk(RIO_DEBUG_BOOT, "Bin too large\n"); - p->RIOError.Error = HOST_FILE_TOO_LARGE; - func_exit(); - return -EFBIG; - } - /* - ** Ensure that the host really is stopped. - ** Disable it's external bus & twang its reset line. - */ - RIOHostReset(HostP->Type, HostP->CardP, HostP->Slot); - - /* - ** Copy the data directly from user space to the SRAM. - ** This ain't going to be none too clever if the download - ** code is bigger than this segment. - */ - rio_dprintk(RIO_DEBUG_BOOT, "Copy in code\n"); - - /* Buffer to local memory as we want to use I/O space and - some cards only do 8 or 16 bit I/O */ - - DownCode = vmalloc(rbp->Count); - if (!DownCode) { - p->RIOError.Error = NOT_ENOUGH_CORE_FOR_PCI_COPY; - func_exit(); - return -ENOMEM; - } - if (copy_from_user(DownCode, rbp->DataP, rbp->Count)) { - kfree(DownCode); - p->RIOError.Error = COPYIN_FAILED; - func_exit(); - return -EFAULT; - } - HostP->Copy(DownCode, StartP, rbp->Count); - vfree(DownCode); - - rio_dprintk(RIO_DEBUG_BOOT, "Copy completed\n"); - - /* - ** S T O P ! - ** - ** Upto this point the code has been fairly rational, and possibly - ** even straight forward. What follows is a pile of crud that will - ** magically turn into six bytes of transputer assembler. Normally - ** you would expect an array or something, but, being me, I have - ** chosen [been told] to use a technique whereby the startup code - ** will be correct if we change the loadbase for the code. Which - ** brings us onto another issue - the loadbase is the *end* of the - ** code, not the start. - ** - ** If I were you I wouldn't start from here. - */ - - /* - ** We now need to insert a short boot section into - ** the memory at the end of Sram2. This is normally (de)composed - ** of the last eight bytes of the download code. The - ** download has been assembled/compiled to expect to be - ** loaded from 0x7FFF downwards. We have loaded it - ** at some other address. The startup code goes into the small - ** ram window at Sram2, in the last 8 bytes, which are really - ** at addresses 0x7FF8-0x7FFF. - ** - ** If the loadbase is, say, 0x7C00, then we need to branch to - ** address 0x7BFE to run the host.bin startup code. We assemble - ** this jump manually. - ** - ** The two byte sequence 60 08 is loaded into memory at address - ** 0x7FFE,F. This is a local branch to location 0x7FF8 (60 is nfix 0, - ** which adds '0' to the .O register, complements .O, and then shifts - ** it left by 4 bit positions, 08 is a jump .O+8 instruction. This will - ** add 8 to .O (which was 0xFFF0), and will branch RELATIVE to the new - ** location. Now, the branch starts from the value of .PC (or .IP or - ** whatever the bloody register is called on this chip), and the .PC - ** will be pointing to the location AFTER the branch, in this case - ** .PC == 0x8000, so the branch will be to 0x8000+0xFFF8 = 0x7FF8. - ** - ** A long branch is coded at 0x7FF8. This consists of loading a four - ** byte offset into .O using nfix (as above) and pfix operators. The - ** pfix operates in exactly the same way as the nfix operator, but - ** without the complement operation. The offset, of course, must be - ** relative to the address of the byte AFTER the branch instruction, - ** which will be (urm) 0x7FFC, so, our final destination of the branch - ** (loadbase-2), has to be reached from here. Imagine that the loadbase - ** is 0x7C00 (which it is), then we will need to branch to 0x7BFE (which - ** is the first byte of the initial two byte short local branch of the - ** download code). - ** - ** To code a jump from 0x7FFC (which is where the branch will start - ** from) to 0x7BFE, we will need to branch 0xFC02 bytes (0x7FFC+0xFC02)= - ** 0x7BFE. - ** This will be coded as four bytes: - ** 60 2C 20 02 - ** being nfix .O+0 - ** pfix .O+C - ** pfix .O+0 - ** jump .O+2 - ** - ** The nfix operator is used, so that the startup code will be - ** compatible with the whole Tp family. (lies, damn lies, it'll never - ** work in a month of Sundays). - ** - ** The nfix nyble is the 1s complement of the nyble value you - ** want to load - in this case we wanted 'F' so we nfix loaded '0'. - */ - - - /* - ** Dest points to the top 8 bytes of Sram2. The Tp jumps - ** to 0x7FFE at reset time, and starts executing. This is - ** a short branch to 0x7FF8, where a long branch is coded. - */ - - DestP = &Cad[0x7FF8]; /* <<<---- READ THE ABOVE COMMENTS */ - -#define NFIX(N) (0x60 | (N)) /* .O = (~(.O + N))<<4 */ -#define PFIX(N) (0x20 | (N)) /* .O = (.O + N)<<4 */ -#define JUMP(N) (0x00 | (N)) /* .PC = .PC + .O */ - - /* - ** 0x7FFC is the address of the location following the last byte of - ** the four byte jump instruction. - ** READ THE ABOVE COMMENTS - ** - ** offset is (TO-FROM) % MEMSIZE, but with compound buggering about. - ** Memsize is 64K for this range of Tp, so offset is a short (unsigned, - ** cos I don't understand 2's complement). - */ - offset = (p->RIOConf.HostLoadBase - 2) - 0x7FFC; - - writeb(NFIX(((unsigned short) (~offset) >> (unsigned short) 12) & 0xF), DestP); - writeb(PFIX((offset >> 8) & 0xF), DestP + 1); - writeb(PFIX((offset >> 4) & 0xF), DestP + 2); - writeb(JUMP(offset & 0xF), DestP + 3); - - writeb(NFIX(0), DestP + 6); - writeb(JUMP(8), DestP + 7); - - rio_dprintk(RIO_DEBUG_BOOT, "host loadbase is 0x%x\n", p->RIOConf.HostLoadBase); - rio_dprintk(RIO_DEBUG_BOOT, "startup offset is 0x%x\n", offset); - - /* - ** Flag what is going on - */ - HostP->Flags &= ~RUN_STATE; - HostP->Flags |= RC_STARTUP; - - /* - ** Grab a copy of the current ParmMap pointer, so we - ** can tell when it has changed. - */ - OldParmMap = readw(&HostP->__ParmMapR); - - rio_dprintk(RIO_DEBUG_BOOT, "Original parmmap is 0x%x\n", OldParmMap); - - /* - ** And start it running (I hope). - ** As there is nothing dodgy or obscure about the - ** above code, this is guaranteed to work every time. - */ - rio_dprintk(RIO_DEBUG_BOOT, "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n", HostP->Type, HostP->Mode, HostP->Ivec); - - rio_start_card_running(HostP); - - rio_dprintk(RIO_DEBUG_BOOT, "Set control port\n"); - - /* - ** Now, wait for upto five seconds for the Tp to setup the parmmap - ** pointer: - */ - for (wait_count = 0; (wait_count < p->RIOConf.StartupTime) && (readw(&HostP->__ParmMapR) == OldParmMap); wait_count++) { - rio_dprintk(RIO_DEBUG_BOOT, "Checkout %d, 0x%x\n", wait_count, readw(&HostP->__ParmMapR)); - mdelay(100); - - } - - /* - ** If the parmmap pointer is unchanged, then the host code - ** has crashed & burned in a really spectacular way - */ - if (readw(&HostP->__ParmMapR) == OldParmMap) { - rio_dprintk(RIO_DEBUG_BOOT, "parmmap 0x%x\n", readw(&HostP->__ParmMapR)); - rio_dprintk(RIO_DEBUG_BOOT, "RIO Mesg Run Fail\n"); - HostP->Flags &= ~RUN_STATE; - HostP->Flags |= RC_STUFFED; - RIOHostReset( HostP->Type, HostP->CardP, HostP->Slot ); - continue; - } - - rio_dprintk(RIO_DEBUG_BOOT, "Running 0x%x\n", readw(&HostP->__ParmMapR)); - - /* - ** Well, the board thought it was OK, and setup its parmmap - ** pointer. For the time being, we will pretend that this - ** board is running, and check out what the error flag says. - */ - - /* - ** Grab a 32 bit pointer to the parmmap structure - */ - ParmMapP = (PARM_MAP __iomem *) RIO_PTR(Cad, readw(&HostP->__ParmMapR)); - rio_dprintk(RIO_DEBUG_BOOT, "ParmMapP : %p\n", ParmMapP); - ParmMapP = (PARM_MAP __iomem *)(Cad + readw(&HostP->__ParmMapR)); - rio_dprintk(RIO_DEBUG_BOOT, "ParmMapP : %p\n", ParmMapP); - - /* - ** The links entry should be 0xFFFF; we set it up - ** with a mask to say how many PHBs to use, and - ** which links to use. - */ - if (readw(&ParmMapP->links) != 0xFFFF) { - rio_dprintk(RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name); - rio_dprintk(RIO_DEBUG_BOOT, "Links = 0x%x\n", readw(&ParmMapP->links)); - HostP->Flags &= ~RUN_STATE; - HostP->Flags |= RC_STUFFED; - RIOHostReset( HostP->Type, HostP->CardP, HostP->Slot ); - continue; - } - - writew(RIO_LINK_ENABLE, &ParmMapP->links); - - /* - ** now wait for the card to set all the parmmap->XXX stuff - ** this is a wait of upto two seconds.... - */ - rio_dprintk(RIO_DEBUG_BOOT, "Looking for init_done - %d ticks\n", p->RIOConf.StartupTime); - HostP->timeout_id = 0; - for (wait_count = 0; (wait_count < p->RIOConf.StartupTime) && !readw(&ParmMapP->init_done); wait_count++) { - rio_dprintk(RIO_DEBUG_BOOT, "Waiting for init_done\n"); - mdelay(100); - } - rio_dprintk(RIO_DEBUG_BOOT, "OK! init_done!\n"); - - if (readw(&ParmMapP->error) != E_NO_ERROR || !readw(&ParmMapP->init_done)) { - rio_dprintk(RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name); - rio_dprintk(RIO_DEBUG_BOOT, "Timedout waiting for init_done\n"); - HostP->Flags &= ~RUN_STATE; - HostP->Flags |= RC_STUFFED; - RIOHostReset( HostP->Type, HostP->CardP, HostP->Slot ); - continue; - } - - rio_dprintk(RIO_DEBUG_BOOT, "Got init_done\n"); - - /* - ** It runs! It runs! - */ - rio_dprintk(RIO_DEBUG_BOOT, "Host ID %x Running\n", HostP->UniqueNum); - - /* - ** set the time period between interrupts. - */ - writew(p->RIOConf.Timer, &ParmMapP->timer); - - /* - ** Translate all the 16 bit pointers in the __ParmMapR into - ** 32 bit pointers for the driver in ioremap space. - */ - HostP->ParmMapP = ParmMapP; - HostP->PhbP = (struct PHB __iomem *) RIO_PTR(Cad, readw(&ParmMapP->phb_ptr)); - HostP->RupP = (struct RUP __iomem *) RIO_PTR(Cad, readw(&ParmMapP->rups)); - HostP->PhbNumP = (unsigned short __iomem *) RIO_PTR(Cad, readw(&ParmMapP->phb_num_ptr)); - HostP->LinkStrP = (struct LPB __iomem *) RIO_PTR(Cad, readw(&ParmMapP->link_str_ptr)); - - /* - ** point the UnixRups at the real Rups - */ - for (RupN = 0; RupN < MAX_RUP; RupN++) { - HostP->UnixRups[RupN].RupP = &HostP->RupP[RupN]; - HostP->UnixRups[RupN].Id = RupN + 1; - HostP->UnixRups[RupN].BaseSysPort = NO_PORT; - spin_lock_init(&HostP->UnixRups[RupN].RupLock); - } - - for (RupN = 0; RupN < LINKS_PER_UNIT; RupN++) { - HostP->UnixRups[RupN + MAX_RUP].RupP = &HostP->LinkStrP[RupN].rup; - HostP->UnixRups[RupN + MAX_RUP].Id = 0; - HostP->UnixRups[RupN + MAX_RUP].BaseSysPort = NO_PORT; - spin_lock_init(&HostP->UnixRups[RupN + MAX_RUP].RupLock); - } - - /* - ** point the PortP->Phbs at the real Phbs - */ - for (PortN = p->RIOFirstPortsMapped; PortN < p->RIOLastPortsMapped + PORTS_PER_RTA; PortN++) { - if (p->RIOPortp[PortN]->HostP == HostP) { - struct Port *PortP = p->RIOPortp[PortN]; - struct PHB __iomem *PhbP; - /* int oldspl; */ - - if (!PortP->Mapped) - continue; - - PhbP = &HostP->PhbP[PortP->HostPort]; - rio_spin_lock_irqsave(&PortP->portSem, flags); - - PortP->PhbP = PhbP; - - PortP->TxAdd = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->tx_add)); - PortP->TxStart = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->tx_start)); - PortP->TxEnd = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->tx_end)); - PortP->RxRemove = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->rx_remove)); - PortP->RxStart = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->rx_start)); - PortP->RxEnd = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->rx_end)); - - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - /* - ** point the UnixRup at the base SysPort - */ - if (!(PortN % PORTS_PER_RTA)) - HostP->UnixRups[PortP->RupNum].BaseSysPort = PortN; - } - } - - rio_dprintk(RIO_DEBUG_BOOT, "Set the card running... \n"); - /* - ** last thing - show the world that everything is in place - */ - HostP->Flags &= ~RUN_STATE; - HostP->Flags |= RC_RUNNING; - } - /* - ** MPX always uses a poller. This is actually patched into the system - ** configuration and called directly from each clock tick. - ** - */ - p->RIOPolling = 1; - - p->RIOSystemUp++; - - rio_dprintk(RIO_DEBUG_BOOT, "Done everything %x\n", HostP->Ivec); - func_exit(); - return 0; -} - - - -/** - * RIOBootRup - Boot an RTA - * @p: rio we are working with - * @Rup: Rup number - * @HostP: host object - * @PacketP: packet to use - * - * If we have successfully processed this boot, then - * return 1. If we havent, then return 0. - */ - -int RIOBootRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct PKT __iomem *PacketP) -{ - struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *) PacketP->data; - struct PktCmd_M *PktReplyP; - struct CmdBlk *CmdBlkP; - unsigned int sequence; - - /* - ** If we haven't been told what to boot, we can't boot it. - */ - if (p->RIONumBootPkts == 0) { - rio_dprintk(RIO_DEBUG_BOOT, "No RTA code to download yet\n"); - return 0; - } - - /* - ** Special case of boot completed - if we get one of these then we - ** don't need a command block. For all other cases we do, so handle - ** this first and then get a command block, then handle every other - ** case, relinquishing the command block if disaster strikes! - */ - if ((readb(&PacketP->len) & PKT_CMD_BIT) && (readb(&PktCmdP->Command) == BOOT_COMPLETED)) - return RIOBootComplete(p, HostP, Rup, PktCmdP); - - /* - ** Try to allocate a command block. This is in kernel space - */ - if (!(CmdBlkP = RIOGetCmdBlk())) { - rio_dprintk(RIO_DEBUG_BOOT, "No command blocks to boot RTA! come back later.\n"); - return 0; - } - - /* - ** Fill in the default info on the command block - */ - CmdBlkP->Packet.dest_unit = Rup < (unsigned short) MAX_RUP ? Rup : 0; - CmdBlkP->Packet.dest_port = BOOT_RUP; - CmdBlkP->Packet.src_unit = 0; - CmdBlkP->Packet.src_port = BOOT_RUP; - - CmdBlkP->PreFuncP = CmdBlkP->PostFuncP = NULL; - PktReplyP = (struct PktCmd_M *) CmdBlkP->Packet.data; - - /* - ** process COMMANDS on the boot rup! - */ - if (readb(&PacketP->len) & PKT_CMD_BIT) { - /* - ** We only expect one type of command - a BOOT_REQUEST! - */ - if (readb(&PktCmdP->Command) != BOOT_REQUEST) { - rio_dprintk(RIO_DEBUG_BOOT, "Unexpected command %d on BOOT RUP %d of host %Zd\n", readb(&PktCmdP->Command), Rup, HostP - p->RIOHosts); - RIOFreeCmdBlk(CmdBlkP); - return 1; - } - - /* - ** Build a Boot Sequence command block - ** - ** We no longer need to use "Boot Mode", we'll always allow - ** boot requests - the boot will not complete if the device - ** appears in the bindings table. - ** - ** We'll just (always) set the command field in packet reply - ** to allow an attempted boot sequence : - */ - PktReplyP->Command = BOOT_SEQUENCE; - - PktReplyP->BootSequence.NumPackets = p->RIONumBootPkts; - PktReplyP->BootSequence.LoadBase = p->RIOConf.RtaLoadBase; - PktReplyP->BootSequence.CodeSize = p->RIOBootCount; - - CmdBlkP->Packet.len = BOOT_SEQUENCE_LEN | PKT_CMD_BIT; - - memcpy((void *) &CmdBlkP->Packet.data[BOOT_SEQUENCE_LEN], "BOOT", 4); - - rio_dprintk(RIO_DEBUG_BOOT, "Boot RTA on Host %Zd Rup %d - %d (0x%x) packets to 0x%x\n", HostP - p->RIOHosts, Rup, p->RIONumBootPkts, p->RIONumBootPkts, p->RIOConf.RtaLoadBase); - - /* - ** If this host is in slave mode, send the RTA an invalid boot - ** sequence command block to force it to kill the boot. We wait - ** for half a second before sending this packet to prevent the RTA - ** attempting to boot too often. The master host should then grab - ** the RTA and make it its own. - */ - p->RIOBooting++; - RIOQueueCmdBlk(HostP, Rup, CmdBlkP); - return 1; - } - - /* - ** It is a request for boot data. - */ - sequence = readw(&PktCmdP->Sequence); - - rio_dprintk(RIO_DEBUG_BOOT, "Boot block %d on Host %Zd Rup%d\n", sequence, HostP - p->RIOHosts, Rup); - - if (sequence >= p->RIONumBootPkts) { - rio_dprintk(RIO_DEBUG_BOOT, "Got a request for packet %d, max is %d\n", sequence, p->RIONumBootPkts); - } - - PktReplyP->Sequence = sequence; - memcpy(PktReplyP->BootData, p->RIOBootPackets[p->RIONumBootPkts - sequence - 1], RTA_BOOT_DATA_SIZE); - CmdBlkP->Packet.len = PKT_MAX_DATA_LEN; - RIOQueueCmdBlk(HostP, Rup, CmdBlkP); - return 1; -} - -/** - * RIOBootComplete - RTA boot is done - * @p: RIO we are working with - * @HostP: Host structure - * @Rup: RUP being used - * @PktCmdP: Packet command that was used - * - * This function is called when an RTA been booted. - * If booted by a host, HostP->HostUniqueNum is the booting host. - * If booted by an RTA, HostP->Mapping[Rup].RtaUniqueNum is the booting RTA. - * RtaUniq is the booted RTA. - */ - -static int RIOBootComplete(struct rio_info *p, struct Host *HostP, unsigned int Rup, struct PktCmd __iomem *PktCmdP) -{ - struct Map *MapP = NULL; - struct Map *MapP2 = NULL; - int Flag; - int found; - int host, rta; - int EmptySlot = -1; - int entry, entry2; - char *MyType, *MyName; - unsigned int MyLink; - unsigned short RtaType; - u32 RtaUniq = (readb(&PktCmdP->UniqNum[0])) + (readb(&PktCmdP->UniqNum[1]) << 8) + (readb(&PktCmdP->UniqNum[2]) << 16) + (readb(&PktCmdP->UniqNum[3]) << 24); - - p->RIOBooting = 0; - - rio_dprintk(RIO_DEBUG_BOOT, "RTA Boot completed - BootInProgress now %d\n", p->RIOBooting); - - /* - ** Determine type of unit (16/8 port RTA). - */ - - RtaType = GetUnitType(RtaUniq); - if (Rup >= (unsigned short) MAX_RUP) - rio_dprintk(RIO_DEBUG_BOOT, "RIO: Host %s has booted an RTA(%d) on link %c\n", HostP->Name, 8 * RtaType, readb(&PktCmdP->LinkNum) + 'A'); - else - rio_dprintk(RIO_DEBUG_BOOT, "RIO: RTA %s has booted an RTA(%d) on link %c\n", HostP->Mapping[Rup].Name, 8 * RtaType, readb(&PktCmdP->LinkNum) + 'A'); - - rio_dprintk(RIO_DEBUG_BOOT, "UniqNum is 0x%x\n", RtaUniq); - - if (RtaUniq == 0x00000000 || RtaUniq == 0xffffffff) { - rio_dprintk(RIO_DEBUG_BOOT, "Illegal RTA Uniq Number\n"); - return 1; - } - - /* - ** If this RTA has just booted an RTA which doesn't belong to this - ** system, or the system is in slave mode, do not attempt to create - ** a new table entry for it. - */ - - if (!RIOBootOk(p, HostP, RtaUniq)) { - MyLink = readb(&PktCmdP->LinkNum); - if (Rup < (unsigned short) MAX_RUP) { - /* - ** RtaUniq was clone booted (by this RTA). Instruct this RTA - ** to hold off further attempts to boot on this link for 30 - ** seconds. - */ - if (RIOSuspendBootRta(HostP, HostP->Mapping[Rup].ID, MyLink)) { - rio_dprintk(RIO_DEBUG_BOOT, "RTA failed to suspend booting on link %c\n", 'A' + MyLink); - } - } else - /* - ** RtaUniq was booted by this host. Set the booting link - ** to hold off for 30 seconds to give another unit a - ** chance to boot it. - */ - writew(30, &HostP->LinkStrP[MyLink].WaitNoBoot); - rio_dprintk(RIO_DEBUG_BOOT, "RTA %x not owned - suspend booting down link %c on unit %x\n", RtaUniq, 'A' + MyLink, HostP->Mapping[Rup].RtaUniqueNum); - return 1; - } - - /* - ** Check for a SLOT_IN_USE entry for this RTA attached to the - ** current host card in the driver table. - ** - ** If it exists, make a note that we have booted it. Other parts of - ** the driver are interested in this information at a later date, - ** in particular when the booting RTA asks for an ID for this unit, - ** we must have set the BOOTED flag, and the NEWBOOT flag is used - ** to force an open on any ports that where previously open on this - ** unit. - */ - for (entry = 0; entry < MAX_RUP; entry++) { - unsigned int sysport; - - if ((HostP->Mapping[entry].Flags & SLOT_IN_USE) && (HostP->Mapping[entry].RtaUniqueNum == RtaUniq)) { - HostP->Mapping[entry].Flags |= RTA_BOOTED | RTA_NEWBOOT; - if ((sysport = HostP->Mapping[entry].SysPort) != NO_PORT) { - if (sysport < p->RIOFirstPortsBooted) - p->RIOFirstPortsBooted = sysport; - if (sysport > p->RIOLastPortsBooted) - p->RIOLastPortsBooted = sysport; - /* - ** For a 16 port RTA, check the second bank of 8 ports - */ - if (RtaType == TYPE_RTA16) { - entry2 = HostP->Mapping[entry].ID2 - 1; - HostP->Mapping[entry2].Flags |= RTA_BOOTED | RTA_NEWBOOT; - sysport = HostP->Mapping[entry2].SysPort; - if (sysport < p->RIOFirstPortsBooted) - p->RIOFirstPortsBooted = sysport; - if (sysport > p->RIOLastPortsBooted) - p->RIOLastPortsBooted = sysport; - } - } - if (RtaType == TYPE_RTA16) - rio_dprintk(RIO_DEBUG_BOOT, "RTA will be given IDs %d+%d\n", entry + 1, entry2 + 1); - else - rio_dprintk(RIO_DEBUG_BOOT, "RTA will be given ID %d\n", entry + 1); - return 1; - } - } - - rio_dprintk(RIO_DEBUG_BOOT, "RTA not configured for this host\n"); - - if (Rup >= (unsigned short) MAX_RUP) { - /* - ** It was a host that did the booting - */ - MyType = "Host"; - MyName = HostP->Name; - } else { - /* - ** It was an RTA that did the booting - */ - MyType = "RTA"; - MyName = HostP->Mapping[Rup].Name; - } - MyLink = readb(&PktCmdP->LinkNum); - - /* - ** There is no SLOT_IN_USE entry for this RTA attached to the current - ** host card in the driver table. - ** - ** Check for a SLOT_TENTATIVE entry for this RTA attached to the - ** current host card in the driver table. - ** - ** If we find one, then we re-use that slot. - */ - for (entry = 0; entry < MAX_RUP; entry++) { - if ((HostP->Mapping[entry].Flags & SLOT_TENTATIVE) && (HostP->Mapping[entry].RtaUniqueNum == RtaUniq)) { - if (RtaType == TYPE_RTA16) { - entry2 = HostP->Mapping[entry].ID2 - 1; - if ((HostP->Mapping[entry2].Flags & SLOT_TENTATIVE) && (HostP->Mapping[entry2].RtaUniqueNum == RtaUniq)) - rio_dprintk(RIO_DEBUG_BOOT, "Found previous tentative slots (%d+%d)\n", entry, entry2); - else - continue; - } else - rio_dprintk(RIO_DEBUG_BOOT, "Found previous tentative slot (%d)\n", entry); - if (!p->RIONoMessage) - printk("RTA connected to %s '%s' (%c) not configured.\n", MyType, MyName, MyLink + 'A'); - return 1; - } - } - - /* - ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA - ** attached to the current host card in the driver table. - ** - ** Check if there is a SLOT_IN_USE or SLOT_TENTATIVE entry on another - ** host for this RTA in the driver table. - ** - ** For a SLOT_IN_USE entry on another host, we need to delete the RTA - ** entry from the other host and add it to this host (using some of - ** the functions from table.c which do this). - ** For a SLOT_TENTATIVE entry on another host, we must cope with the - ** following scenario: - ** - ** + Plug 8 port RTA into host A. (This creates SLOT_TENTATIVE entry - ** in table) - ** + Unplug RTA and plug into host B. (We now have 2 SLOT_TENTATIVE - ** entries) - ** + Configure RTA on host B. (This slot now becomes SLOT_IN_USE) - ** + Unplug RTA and plug back into host A. - ** + Configure RTA on host A. We now have the same RTA configured - ** with different ports on two different hosts. - */ - rio_dprintk(RIO_DEBUG_BOOT, "Have we seen RTA %x before?\n", RtaUniq); - found = 0; - Flag = 0; /* Convince the compiler this variable is initialized */ - for (host = 0; !found && (host < p->RIONumHosts); host++) { - for (rta = 0; rta < MAX_RUP; rta++) { - if ((p->RIOHosts[host].Mapping[rta].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) && (p->RIOHosts[host].Mapping[rta].RtaUniqueNum == RtaUniq)) { - Flag = p->RIOHosts[host].Mapping[rta].Flags; - MapP = &p->RIOHosts[host].Mapping[rta]; - if (RtaType == TYPE_RTA16) { - MapP2 = &p->RIOHosts[host].Mapping[MapP->ID2 - 1]; - rio_dprintk(RIO_DEBUG_BOOT, "This RTA is units %d+%d from host %s\n", rta + 1, MapP->ID2, p->RIOHosts[host].Name); - } else - rio_dprintk(RIO_DEBUG_BOOT, "This RTA is unit %d from host %s\n", rta + 1, p->RIOHosts[host].Name); - found = 1; - break; - } - } - } - - /* - ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA - ** attached to the current host card in the driver table. - ** - ** If we have not found a SLOT_IN_USE or SLOT_TENTATIVE entry on - ** another host for this RTA in the driver table... - ** - ** Check for a SLOT_IN_USE entry for this RTA in the config table. - */ - if (!MapP) { - rio_dprintk(RIO_DEBUG_BOOT, "Look for RTA %x in RIOSavedTable\n", RtaUniq); - for (rta = 0; rta < TOTAL_MAP_ENTRIES; rta++) { - rio_dprintk(RIO_DEBUG_BOOT, "Check table entry %d (%x)", rta, p->RIOSavedTable[rta].RtaUniqueNum); - - if ((p->RIOSavedTable[rta].Flags & SLOT_IN_USE) && (p->RIOSavedTable[rta].RtaUniqueNum == RtaUniq)) { - MapP = &p->RIOSavedTable[rta]; - Flag = p->RIOSavedTable[rta].Flags; - if (RtaType == TYPE_RTA16) { - for (entry2 = rta + 1; entry2 < TOTAL_MAP_ENTRIES; entry2++) { - if (p->RIOSavedTable[entry2].RtaUniqueNum == RtaUniq) - break; - } - MapP2 = &p->RIOSavedTable[entry2]; - rio_dprintk(RIO_DEBUG_BOOT, "This RTA is from table entries %d+%d\n", rta, entry2); - } else - rio_dprintk(RIO_DEBUG_BOOT, "This RTA is from table entry %d\n", rta); - break; - } - } - } - - /* - ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA - ** attached to the current host card in the driver table. - ** - ** We may have found a SLOT_IN_USE entry on another host for this - ** RTA in the config table, or a SLOT_IN_USE or SLOT_TENTATIVE entry - ** on another host for this RTA in the driver table. - ** - ** Check the driver table for room to fit this newly discovered RTA. - ** RIOFindFreeID() first looks for free slots and if it does not - ** find any free slots it will then attempt to oust any - ** tentative entry in the table. - */ - EmptySlot = 1; - if (RtaType == TYPE_RTA16) { - if (RIOFindFreeID(p, HostP, &entry, &entry2) == 0) { - RIODefaultName(p, HostP, entry); - rio_fill_host_slot(entry, entry2, RtaUniq, HostP); - EmptySlot = 0; - } - } else { - if (RIOFindFreeID(p, HostP, &entry, NULL) == 0) { - RIODefaultName(p, HostP, entry); - rio_fill_host_slot(entry, 0, RtaUniq, HostP); - EmptySlot = 0; - } - } - - /* - ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA - ** attached to the current host card in the driver table. - ** - ** If we found a SLOT_IN_USE entry on another host for this - ** RTA in the config or driver table, and there are enough free - ** slots in the driver table, then we need to move it over and - ** delete it from the other host. - ** If we found a SLOT_TENTATIVE entry on another host for this - ** RTA in the driver table, just delete the other host entry. - */ - if (EmptySlot == 0) { - if (MapP) { - if (Flag & SLOT_IN_USE) { - rio_dprintk(RIO_DEBUG_BOOT, "This RTA configured on another host - move entry to current host (1)\n"); - HostP->Mapping[entry].SysPort = MapP->SysPort; - memcpy(HostP->Mapping[entry].Name, MapP->Name, MAX_NAME_LEN); - HostP->Mapping[entry].Flags = SLOT_IN_USE | RTA_BOOTED | RTA_NEWBOOT; - RIOReMapPorts(p, HostP, &HostP->Mapping[entry]); - if (HostP->Mapping[entry].SysPort < p->RIOFirstPortsBooted) - p->RIOFirstPortsBooted = HostP->Mapping[entry].SysPort; - if (HostP->Mapping[entry].SysPort > p->RIOLastPortsBooted) - p->RIOLastPortsBooted = HostP->Mapping[entry].SysPort; - rio_dprintk(RIO_DEBUG_BOOT, "SysPort %d, Name %s\n", (int) MapP->SysPort, MapP->Name); - } else { - rio_dprintk(RIO_DEBUG_BOOT, "This RTA has a tentative entry on another host - delete that entry (1)\n"); - HostP->Mapping[entry].Flags = SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT; - } - if (RtaType == TYPE_RTA16) { - if (Flag & SLOT_IN_USE) { - HostP->Mapping[entry2].Flags = SLOT_IN_USE | RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT; - HostP->Mapping[entry2].SysPort = MapP2->SysPort; - /* - ** Map second block of ttys for 16 port RTA - */ - RIOReMapPorts(p, HostP, &HostP->Mapping[entry2]); - if (HostP->Mapping[entry2].SysPort < p->RIOFirstPortsBooted) - p->RIOFirstPortsBooted = HostP->Mapping[entry2].SysPort; - if (HostP->Mapping[entry2].SysPort > p->RIOLastPortsBooted) - p->RIOLastPortsBooted = HostP->Mapping[entry2].SysPort; - rio_dprintk(RIO_DEBUG_BOOT, "SysPort %d, Name %s\n", (int) HostP->Mapping[entry2].SysPort, HostP->Mapping[entry].Name); - } else - HostP->Mapping[entry2].Flags = SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT; - memset(MapP2, 0, sizeof(struct Map)); - } - memset(MapP, 0, sizeof(struct Map)); - if (!p->RIONoMessage) - printk("An orphaned RTA has been adopted by %s '%s' (%c).\n", MyType, MyName, MyLink + 'A'); - } else if (!p->RIONoMessage) - printk("RTA connected to %s '%s' (%c) not configured.\n", MyType, MyName, MyLink + 'A'); - RIOSetChange(p); - return 1; - } - - /* - ** There is no room in the driver table to make an entry for the - ** booted RTA. Keep a note of its Uniq Num in the overflow table, - ** so we can ignore it's ID requests. - */ - if (!p->RIONoMessage) - printk("The RTA connected to %s '%s' (%c) cannot be configured. You cannot configure more than 128 ports to one host card.\n", MyType, MyName, MyLink + 'A'); - for (entry = 0; entry < HostP->NumExtraBooted; entry++) { - if (HostP->ExtraUnits[entry] == RtaUniq) { - /* - ** already got it! - */ - return 1; - } - } - /* - ** If there is room, add the unit to the list of extras - */ - if (HostP->NumExtraBooted < MAX_EXTRA_UNITS) - HostP->ExtraUnits[HostP->NumExtraBooted++] = RtaUniq; - return 1; -} - - -/* -** If the RTA or its host appears in the RIOBindTab[] structure then -** we mustn't boot the RTA and should return 0. -** This operation is slightly different from the other drivers for RIO -** in that this is designed to work with the new utilities -** not config.rio and is FAR SIMPLER. -** We no longer support the RIOBootMode variable. It is all done from the -** "boot/noboot" field in the rio.cf file. -*/ -int RIOBootOk(struct rio_info *p, struct Host *HostP, unsigned long RtaUniq) -{ - int Entry; - unsigned int HostUniq = HostP->UniqueNum; - - /* - ** Search bindings table for RTA or its parent. - ** If it exists, return 0, else 1. - */ - for (Entry = 0; (Entry < MAX_RTA_BINDINGS) && (p->RIOBindTab[Entry] != 0); Entry++) { - if ((p->RIOBindTab[Entry] == HostUniq) || (p->RIOBindTab[Entry] == RtaUniq)) - return 0; - } - return 1; -} - -/* -** Make an empty slot tentative. If this is a 16 port RTA, make both -** slots tentative, and the second one RTA_SECOND_SLOT as well. -*/ - -void rio_fill_host_slot(int entry, int entry2, unsigned int rta_uniq, struct Host *host) -{ - int link; - - rio_dprintk(RIO_DEBUG_BOOT, "rio_fill_host_slot(%d, %d, 0x%x...)\n", entry, entry2, rta_uniq); - - host->Mapping[entry].Flags = (RTA_BOOTED | RTA_NEWBOOT | SLOT_TENTATIVE); - host->Mapping[entry].SysPort = NO_PORT; - host->Mapping[entry].RtaUniqueNum = rta_uniq; - host->Mapping[entry].HostUniqueNum = host->UniqueNum; - host->Mapping[entry].ID = entry + 1; - host->Mapping[entry].ID2 = 0; - if (entry2) { - host->Mapping[entry2].Flags = (RTA_BOOTED | RTA_NEWBOOT | SLOT_TENTATIVE | RTA16_SECOND_SLOT); - host->Mapping[entry2].SysPort = NO_PORT; - host->Mapping[entry2].RtaUniqueNum = rta_uniq; - host->Mapping[entry2].HostUniqueNum = host->UniqueNum; - host->Mapping[entry2].Name[0] = '\0'; - host->Mapping[entry2].ID = entry2 + 1; - host->Mapping[entry2].ID2 = entry + 1; - host->Mapping[entry].ID2 = entry2 + 1; - } - /* - ** Must set these up, so that utilities show - ** topology of 16 port RTAs correctly - */ - for (link = 0; link < LINKS_PER_UNIT; link++) { - host->Mapping[entry].Topology[link].Unit = ROUTE_DISCONNECT; - host->Mapping[entry].Topology[link].Link = NO_LINK; - if (entry2) { - host->Mapping[entry2].Topology[link].Unit = ROUTE_DISCONNECT; - host->Mapping[entry2].Topology[link].Link = NO_LINK; - } - } -} diff --git a/drivers/char/rio/riocmd.c b/drivers/char/rio/riocmd.c deleted file mode 100644 index f121357e5af0..000000000000 --- a/drivers/char/rio/riocmd.c +++ /dev/null @@ -1,939 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** ported from the existing SCO driver source -** - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : riocmd.c -** SID : 1.2 -** Last Modified : 11/6/98 10:33:41 -** Retrieved : 11/6/98 10:33:49 -** -** ident @(#)riocmd.c 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "linux_compat.h" -#include "rio_linux.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" -#include "cirrus.h" - - -static struct IdentifyRta IdRta; -static struct KillNeighbour KillUnit; - -int RIOFoadRta(struct Host *HostP, struct Map *MapP) -{ - struct CmdBlk *CmdBlkP; - - rio_dprintk(RIO_DEBUG_CMD, "FOAD RTA\n"); - - CmdBlkP = RIOGetCmdBlk(); - - if (!CmdBlkP) { - rio_dprintk(RIO_DEBUG_CMD, "FOAD RTA: GetCmdBlk failed\n"); - return -ENXIO; - } - - CmdBlkP->Packet.dest_unit = MapP->ID; - CmdBlkP->Packet.dest_port = BOOT_RUP; - CmdBlkP->Packet.src_unit = 0; - CmdBlkP->Packet.src_port = BOOT_RUP; - CmdBlkP->Packet.len = 0x84; - CmdBlkP->Packet.data[0] = IFOAD; - CmdBlkP->Packet.data[1] = 0; - CmdBlkP->Packet.data[2] = IFOAD_MAGIC & 0xFF; - CmdBlkP->Packet.data[3] = (IFOAD_MAGIC >> 8) & 0xFF; - - if (RIOQueueCmdBlk(HostP, MapP->ID - 1, CmdBlkP) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_CMD, "FOAD RTA: Failed to queue foad command\n"); - return -EIO; - } - return 0; -} - -int RIOZombieRta(struct Host *HostP, struct Map *MapP) -{ - struct CmdBlk *CmdBlkP; - - rio_dprintk(RIO_DEBUG_CMD, "ZOMBIE RTA\n"); - - CmdBlkP = RIOGetCmdBlk(); - - if (!CmdBlkP) { - rio_dprintk(RIO_DEBUG_CMD, "ZOMBIE RTA: GetCmdBlk failed\n"); - return -ENXIO; - } - - CmdBlkP->Packet.dest_unit = MapP->ID; - CmdBlkP->Packet.dest_port = BOOT_RUP; - CmdBlkP->Packet.src_unit = 0; - CmdBlkP->Packet.src_port = BOOT_RUP; - CmdBlkP->Packet.len = 0x84; - CmdBlkP->Packet.data[0] = ZOMBIE; - CmdBlkP->Packet.data[1] = 0; - CmdBlkP->Packet.data[2] = ZOMBIE_MAGIC & 0xFF; - CmdBlkP->Packet.data[3] = (ZOMBIE_MAGIC >> 8) & 0xFF; - - if (RIOQueueCmdBlk(HostP, MapP->ID - 1, CmdBlkP) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_CMD, "ZOMBIE RTA: Failed to queue zombie command\n"); - return -EIO; - } - return 0; -} - -int RIOCommandRta(struct rio_info *p, unsigned long RtaUnique, int (*func) (struct Host * HostP, struct Map * MapP)) -{ - unsigned int Host; - - rio_dprintk(RIO_DEBUG_CMD, "Command RTA 0x%lx func %p\n", RtaUnique, func); - - if (!RtaUnique) - return (0); - - for (Host = 0; Host < p->RIONumHosts; Host++) { - unsigned int Rta; - struct Host *HostP = &p->RIOHosts[Host]; - - for (Rta = 0; Rta < RTAS_PER_HOST; Rta++) { - struct Map *MapP = &HostP->Mapping[Rta]; - - if (MapP->RtaUniqueNum == RtaUnique) { - uint Link; - - /* - ** now, lets just check we have a route to it... - ** IF the routing stuff is working, then one of the - ** topology entries for this unit will have a legit - ** route *somewhere*. We care not where - if its got - ** any connections, we can get to it. - */ - for (Link = 0; Link < LINKS_PER_UNIT; Link++) { - if (MapP->Topology[Link].Unit <= (u8) MAX_RUP) { - /* - ** Its worth trying the operation... - */ - return (*func) (HostP, MapP); - } - } - } - } - } - return -ENXIO; -} - - -int RIOIdentifyRta(struct rio_info *p, void __user * arg) -{ - unsigned int Host; - - if (copy_from_user(&IdRta, arg, sizeof(IdRta))) { - rio_dprintk(RIO_DEBUG_CMD, "RIO_IDENTIFY_RTA copy failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - - for (Host = 0; Host < p->RIONumHosts; Host++) { - unsigned int Rta; - struct Host *HostP = &p->RIOHosts[Host]; - - for (Rta = 0; Rta < RTAS_PER_HOST; Rta++) { - struct Map *MapP = &HostP->Mapping[Rta]; - - if (MapP->RtaUniqueNum == IdRta.RtaUnique) { - uint Link; - /* - ** now, lets just check we have a route to it... - ** IF the routing stuff is working, then one of the - ** topology entries for this unit will have a legit - ** route *somewhere*. We care not where - if its got - ** any connections, we can get to it. - */ - for (Link = 0; Link < LINKS_PER_UNIT; Link++) { - if (MapP->Topology[Link].Unit <= (u8) MAX_RUP) { - /* - ** Its worth trying the operation... - */ - struct CmdBlk *CmdBlkP; - - rio_dprintk(RIO_DEBUG_CMD, "IDENTIFY RTA\n"); - - CmdBlkP = RIOGetCmdBlk(); - - if (!CmdBlkP) { - rio_dprintk(RIO_DEBUG_CMD, "IDENTIFY RTA: GetCmdBlk failed\n"); - return -ENXIO; - } - - CmdBlkP->Packet.dest_unit = MapP->ID; - CmdBlkP->Packet.dest_port = BOOT_RUP; - CmdBlkP->Packet.src_unit = 0; - CmdBlkP->Packet.src_port = BOOT_RUP; - CmdBlkP->Packet.len = 0x84; - CmdBlkP->Packet.data[0] = IDENTIFY; - CmdBlkP->Packet.data[1] = 0; - CmdBlkP->Packet.data[2] = IdRta.ID; - - if (RIOQueueCmdBlk(HostP, MapP->ID - 1, CmdBlkP) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_CMD, "IDENTIFY RTA: Failed to queue command\n"); - return -EIO; - } - return 0; - } - } - } - } - } - return -ENOENT; -} - - -int RIOKillNeighbour(struct rio_info *p, void __user * arg) -{ - uint Host; - uint ID; - struct Host *HostP; - struct CmdBlk *CmdBlkP; - - rio_dprintk(RIO_DEBUG_CMD, "KILL HOST NEIGHBOUR\n"); - - if (copy_from_user(&KillUnit, arg, sizeof(KillUnit))) { - rio_dprintk(RIO_DEBUG_CMD, "RIO_KILL_NEIGHBOUR copy failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - - if (KillUnit.Link > 3) - return -ENXIO; - - CmdBlkP = RIOGetCmdBlk(); - - if (!CmdBlkP) { - rio_dprintk(RIO_DEBUG_CMD, "UFOAD: GetCmdBlk failed\n"); - return -ENXIO; - } - - CmdBlkP->Packet.dest_unit = 0; - CmdBlkP->Packet.src_unit = 0; - CmdBlkP->Packet.dest_port = BOOT_RUP; - CmdBlkP->Packet.src_port = BOOT_RUP; - CmdBlkP->Packet.len = 0x84; - CmdBlkP->Packet.data[0] = UFOAD; - CmdBlkP->Packet.data[1] = KillUnit.Link; - CmdBlkP->Packet.data[2] = UFOAD_MAGIC & 0xFF; - CmdBlkP->Packet.data[3] = (UFOAD_MAGIC >> 8) & 0xFF; - - for (Host = 0; Host < p->RIONumHosts; Host++) { - ID = 0; - HostP = &p->RIOHosts[Host]; - - if (HostP->UniqueNum == KillUnit.UniqueNum) { - if (RIOQueueCmdBlk(HostP, RTAS_PER_HOST + KillUnit.Link, CmdBlkP) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_CMD, "UFOAD: Failed queue command\n"); - return -EIO; - } - return 0; - } - - for (ID = 0; ID < RTAS_PER_HOST; ID++) { - if (HostP->Mapping[ID].RtaUniqueNum == KillUnit.UniqueNum) { - CmdBlkP->Packet.dest_unit = ID + 1; - if (RIOQueueCmdBlk(HostP, ID, CmdBlkP) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_CMD, "UFOAD: Failed queue command\n"); - return -EIO; - } - return 0; - } - } - } - RIOFreeCmdBlk(CmdBlkP); - return -ENXIO; -} - -int RIOSuspendBootRta(struct Host *HostP, int ID, int Link) -{ - struct CmdBlk *CmdBlkP; - - rio_dprintk(RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA ID %d, link %c\n", ID, 'A' + Link); - - CmdBlkP = RIOGetCmdBlk(); - - if (!CmdBlkP) { - rio_dprintk(RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: GetCmdBlk failed\n"); - return -ENXIO; - } - - CmdBlkP->Packet.dest_unit = ID; - CmdBlkP->Packet.dest_port = BOOT_RUP; - CmdBlkP->Packet.src_unit = 0; - CmdBlkP->Packet.src_port = BOOT_RUP; - CmdBlkP->Packet.len = 0x84; - CmdBlkP->Packet.data[0] = IWAIT; - CmdBlkP->Packet.data[1] = Link; - CmdBlkP->Packet.data[2] = IWAIT_MAGIC & 0xFF; - CmdBlkP->Packet.data[3] = (IWAIT_MAGIC >> 8) & 0xFF; - - if (RIOQueueCmdBlk(HostP, ID - 1, CmdBlkP) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: Failed to queue iwait command\n"); - return -EIO; - } - return 0; -} - -int RIOFoadWakeup(struct rio_info *p) -{ - int port; - struct Port *PortP; - unsigned long flags; - - for (port = 0; port < RIO_PORTS; port++) { - PortP = p->RIOPortp[port]; - - rio_spin_lock_irqsave(&PortP->portSem, flags); - PortP->Config = 0; - PortP->State = 0; - PortP->InUse = NOT_INUSE; - PortP->PortState = 0; - PortP->FlushCmdBodge = 0; - PortP->ModemLines = 0; - PortP->ModemState = 0; - PortP->CookMode = 0; - PortP->ParamSem = 0; - PortP->Mapped = 0; - PortP->WflushFlag = 0; - PortP->MagicFlags = 0; - PortP->RxDataStart = 0; - PortP->TxBufferIn = 0; - PortP->TxBufferOut = 0; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - } - return (0); -} - -/* -** Incoming command on the COMMAND_RUP to be processed. -*/ -static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struct PKT __iomem *PacketP) -{ - struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *)PacketP->data; - struct Port *PortP; - struct UnixRup *UnixRupP; - unsigned short SysPort; - unsigned short ReportedModemStatus; - unsigned short rup; - unsigned short subCommand; - unsigned long flags; - - func_enter(); - - /* - ** 16 port RTA note: - ** Command rup packets coming from the RTA will have pkt->data[1] (which - ** translates to PktCmdP->PhbNum) set to the host port number for the - ** particular unit. To access the correct BaseSysPort for a 16 port RTA, - ** we can use PhbNum to get the rup number for the appropriate 8 port - ** block (for the first block, this should be equal to 'Rup'). - */ - rup = readb(&PktCmdP->PhbNum) / (unsigned short) PORTS_PER_RTA; - UnixRupP = &HostP->UnixRups[rup]; - SysPort = UnixRupP->BaseSysPort + (readb(&PktCmdP->PhbNum) % (unsigned short) PORTS_PER_RTA); - rio_dprintk(RIO_DEBUG_CMD, "Command on rup %d, port %d\n", rup, SysPort); - - if (UnixRupP->BaseSysPort == NO_PORT) { - rio_dprintk(RIO_DEBUG_CMD, "OBSCURE ERROR!\n"); - rio_dprintk(RIO_DEBUG_CMD, "Diagnostics follow. Please WRITE THESE DOWN and report them to Specialix Technical Support\n"); - rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: Host number %Zd, name ``%s''\n", HostP - p->RIOHosts, HostP->Name); - rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: Rup number 0x%x\n", rup); - - if (Rup < (unsigned short) MAX_RUP) { - rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: This is the RUP for RTA ``%s''\n", HostP->Mapping[Rup].Name); - } else - rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n", ('A' + Rup - MAX_RUP), HostP->Name); - - rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%x\n", readb(&PacketP->dest_unit), readb(&PacketP->dest_port)); - rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Source 0x%x:0x%x\n", readb(&PacketP->src_unit), readb(&PacketP->src_port)); - rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Length 0x%x (%d)\n", readb(&PacketP->len), readb(&PacketP->len)); - rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Control 0x%x (%d)\n", readb(&PacketP->control), readb(&PacketP->control)); - rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Check 0x%x (%d)\n", readw(&PacketP->csum), readw(&PacketP->csum)); - rio_dprintk(RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, " "Command Code 0x%x\n", readb(&PktCmdP->PhbNum), readb(&PktCmdP->Command)); - return 1; - } - PortP = p->RIOPortp[SysPort]; - rio_spin_lock_irqsave(&PortP->portSem, flags); - switch (readb(&PktCmdP->Command)) { - case RIOC_BREAK_RECEIVED: - rio_dprintk(RIO_DEBUG_CMD, "Received a break!\n"); - /* If the current line disc. is not multi-threading and - the current processor is not the default, reset rup_intr - and return 0 to ensure that the command packet is - not freed. */ - /* Call tmgr HANGUP HERE */ - /* Fix this later when every thing works !!!! RAMRAJ */ - gs_got_break(&PortP->gs); - break; - - case RIOC_COMPLETE: - rio_dprintk(RIO_DEBUG_CMD, "Command complete on phb %d host %Zd\n", readb(&PktCmdP->PhbNum), HostP - p->RIOHosts); - subCommand = 1; - switch (readb(&PktCmdP->SubCommand)) { - case RIOC_MEMDUMP: - rio_dprintk(RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%x\n", readb(&PktCmdP->SubCommand), readw(&PktCmdP->SubAddr)); - break; - case RIOC_READ_REGISTER: - rio_dprintk(RIO_DEBUG_CMD, "Read register (0x%x)\n", readw(&PktCmdP->SubAddr)); - p->CdRegister = (readb(&PktCmdP->ModemStatus) & RIOC_MSVR1_HOST); - break; - default: - subCommand = 0; - break; - } - if (subCommand) - break; - rio_dprintk(RIO_DEBUG_CMD, "New status is 0x%x was 0x%x\n", readb(&PktCmdP->PortStatus), PortP->PortState); - if (PortP->PortState != readb(&PktCmdP->PortStatus)) { - rio_dprintk(RIO_DEBUG_CMD, "Mark status & wakeup\n"); - PortP->PortState = readb(&PktCmdP->PortStatus); - /* What should we do here ... - wakeup( &PortP->PortState ); - */ - } else - rio_dprintk(RIO_DEBUG_CMD, "No change\n"); - - /* FALLTHROUGH */ - case RIOC_MODEM_STATUS: - /* - ** Knock out the tbusy and tstop bits, as these are not relevant - ** to the check for modem status change (they're just there because - ** it's a convenient place to put them!). - */ - ReportedModemStatus = readb(&PktCmdP->ModemStatus); - if ((PortP->ModemState & RIOC_MSVR1_HOST) == - (ReportedModemStatus & RIOC_MSVR1_HOST)) { - rio_dprintk(RIO_DEBUG_CMD, "Modem status unchanged 0x%x\n", PortP->ModemState); - /* - ** Update ModemState just in case tbusy or tstop states have - ** changed. - */ - PortP->ModemState = ReportedModemStatus; - } else { - rio_dprintk(RIO_DEBUG_CMD, "Modem status change from 0x%x to 0x%x\n", PortP->ModemState, ReportedModemStatus); - PortP->ModemState = ReportedModemStatus; -#ifdef MODEM_SUPPORT - if (PortP->Mapped) { - /***********************************************************\ - ************************************************************* - *** *** - *** M O D E M S T A T E C H A N G E *** - *** *** - ************************************************************* - \***********************************************************/ - /* - ** If the device is a modem, then check the modem - ** carrier. - */ - if (PortP->gs.port.tty == NULL) - break; - if (PortP->gs.port.tty->termios == NULL) - break; - - if (!(PortP->gs.port.tty->termios->c_cflag & CLOCAL) && ((PortP->State & (RIO_MOPEN | RIO_WOPEN)))) { - - rio_dprintk(RIO_DEBUG_CMD, "Is there a Carrier?\n"); - /* - ** Is there a carrier? - */ - if (PortP->ModemState & RIOC_MSVR1_CD) { - /* - ** Has carrier just appeared? - */ - if (!(PortP->State & RIO_CARR_ON)) { - rio_dprintk(RIO_DEBUG_CMD, "Carrier just came up.\n"); - PortP->State |= RIO_CARR_ON; - /* - ** wakeup anyone in WOPEN - */ - if (PortP->State & (PORT_ISOPEN | RIO_WOPEN)) - wake_up_interruptible(&PortP->gs.port.open_wait); - } - } else { - /* - ** Has carrier just dropped? - */ - if (PortP->State & RIO_CARR_ON) { - if (PortP->State & (PORT_ISOPEN | RIO_WOPEN | RIO_MOPEN)) - tty_hangup(PortP->gs.port.tty); - PortP->State &= ~RIO_CARR_ON; - rio_dprintk(RIO_DEBUG_CMD, "Carrirer just went down\n"); - } - } - } - } -#endif - } - break; - - default: - rio_dprintk(RIO_DEBUG_CMD, "Unknown command %d on CMD_RUP of host %Zd\n", readb(&PktCmdP->Command), HostP - p->RIOHosts); - break; - } - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - - func_exit(); - - return 1; -} - -/* -** The command mechanism: -** Each rup has a chain of commands associated with it. -** This chain is maintained by routines in this file. -** Periodically we are called and we run a quick check of all the -** active chains to determine if there is a command to be executed, -** and if the rup is ready to accept it. -** -*/ - -/* -** Allocate an empty command block. -*/ -struct CmdBlk *RIOGetCmdBlk(void) -{ - struct CmdBlk *CmdBlkP; - - CmdBlkP = kzalloc(sizeof(struct CmdBlk), GFP_ATOMIC); - return CmdBlkP; -} - -/* -** Return a block to the head of the free list. -*/ -void RIOFreeCmdBlk(struct CmdBlk *CmdBlkP) -{ - kfree(CmdBlkP); -} - -/* -** attach a command block to the list of commands to be performed for -** a given rup. -*/ -int RIOQueueCmdBlk(struct Host *HostP, uint Rup, struct CmdBlk *CmdBlkP) -{ - struct CmdBlk **Base; - struct UnixRup *UnixRupP; - unsigned long flags; - - if (Rup >= (unsigned short) (MAX_RUP + LINKS_PER_UNIT)) { - rio_dprintk(RIO_DEBUG_CMD, "Illegal rup number %d in RIOQueueCmdBlk\n", Rup); - RIOFreeCmdBlk(CmdBlkP); - return RIO_FAIL; - } - - UnixRupP = &HostP->UnixRups[Rup]; - - rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); - - /* - ** If the RUP is currently inactive, then put the request - ** straight on the RUP.... - */ - if ((UnixRupP->CmdsWaitingP == NULL) && (UnixRupP->CmdPendingP == NULL) && (readw(&UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE) && (CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP) (CmdBlkP->PreArg, CmdBlkP) - : 1)) { - rio_dprintk(RIO_DEBUG_CMD, "RUP inactive-placing command straight on. Cmd byte is 0x%x\n", CmdBlkP->Packet.data[0]); - - /* - ** Whammy! blat that pack! - */ - HostP->Copy(&CmdBlkP->Packet, RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->txpkt)), sizeof(struct PKT)); - - /* - ** place command packet on the pending position. - */ - UnixRupP->CmdPendingP = CmdBlkP; - - /* - ** set the command register - */ - writew(TX_PACKET_READY, &UnixRupP->RupP->txcontrol); - - rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); - - return 0; - } - rio_dprintk(RIO_DEBUG_CMD, "RUP active - en-queing\n"); - - if (UnixRupP->CmdsWaitingP != NULL) - rio_dprintk(RIO_DEBUG_CMD, "Rup active - command waiting\n"); - if (UnixRupP->CmdPendingP != NULL) - rio_dprintk(RIO_DEBUG_CMD, "Rup active - command pending\n"); - if (readw(&UnixRupP->RupP->txcontrol) != TX_RUP_INACTIVE) - rio_dprintk(RIO_DEBUG_CMD, "Rup active - command rup not ready\n"); - - Base = &UnixRupP->CmdsWaitingP; - - rio_dprintk(RIO_DEBUG_CMD, "First try to queue cmdblk %p at %p\n", CmdBlkP, Base); - - while (*Base) { - rio_dprintk(RIO_DEBUG_CMD, "Command cmdblk %p here\n", *Base); - Base = &((*Base)->NextP); - rio_dprintk(RIO_DEBUG_CMD, "Now try to queue cmd cmdblk %p at %p\n", CmdBlkP, Base); - } - - rio_dprintk(RIO_DEBUG_CMD, "Will queue cmdblk %p at %p\n", CmdBlkP, Base); - - *Base = CmdBlkP; - - CmdBlkP->NextP = NULL; - - rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); - - return 0; -} - -/* -** Here we go - if there is an empty rup, fill it! -** must be called at splrio() or higher. -*/ -void RIOPollHostCommands(struct rio_info *p, struct Host *HostP) -{ - struct CmdBlk *CmdBlkP; - struct UnixRup *UnixRupP; - struct PKT __iomem *PacketP; - unsigned short Rup; - unsigned long flags; - - - Rup = MAX_RUP + LINKS_PER_UNIT; - - do { /* do this loop for each RUP */ - /* - ** locate the rup we are processing & lock it - */ - UnixRupP = &HostP->UnixRups[--Rup]; - - spin_lock_irqsave(&UnixRupP->RupLock, flags); - - /* - ** First check for incoming commands: - */ - if (readw(&UnixRupP->RupP->rxcontrol) != RX_RUP_INACTIVE) { - int FreeMe; - - PacketP = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->rxpkt)); - - switch (readb(&PacketP->dest_port)) { - case BOOT_RUP: - rio_dprintk(RIO_DEBUG_CMD, "Incoming Boot %s packet '%x'\n", readb(&PacketP->len) & 0x80 ? "Command" : "Data", readb(&PacketP->data[0])); - rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); - FreeMe = RIOBootRup(p, Rup, HostP, PacketP); - rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); - break; - - case COMMAND_RUP: - /* - ** Free the RUP lock as loss of carrier causes a - ** ttyflush which will (eventually) call another - ** routine that uses the RUP lock. - */ - rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); - FreeMe = RIOCommandRup(p, Rup, HostP, PacketP); - if (readb(&PacketP->data[5]) == RIOC_MEMDUMP) { - rio_dprintk(RIO_DEBUG_CMD, "Memdump from 0x%x complete\n", readw(&(PacketP->data[6]))); - rio_memcpy_fromio(p->RIOMemDump, &(PacketP->data[8]), 32); - } - rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); - break; - - case ROUTE_RUP: - rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); - FreeMe = RIORouteRup(p, Rup, HostP, PacketP); - rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); - break; - - default: - rio_dprintk(RIO_DEBUG_CMD, "Unknown RUP %d\n", readb(&PacketP->dest_port)); - FreeMe = 1; - break; - } - - if (FreeMe) { - rio_dprintk(RIO_DEBUG_CMD, "Free processed incoming command packet\n"); - put_free_end(HostP, PacketP); - - writew(RX_RUP_INACTIVE, &UnixRupP->RupP->rxcontrol); - - if (readw(&UnixRupP->RupP->handshake) == PHB_HANDSHAKE_SET) { - rio_dprintk(RIO_DEBUG_CMD, "Handshake rup %d\n", Rup); - writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &UnixRupP->RupP->handshake); - } - } - } - - /* - ** IF a command was running on the port, - ** and it has completed, then tidy it up. - */ - if ((CmdBlkP = UnixRupP->CmdPendingP) && /* ASSIGN! */ - (readw(&UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) { - /* - ** we are idle. - ** there is a command in pending. - ** Therefore, this command has finished. - ** So, wakeup whoever is waiting for it (and tell them - ** what happened). - */ - if (CmdBlkP->Packet.dest_port == BOOT_RUP) - rio_dprintk(RIO_DEBUG_CMD, "Free Boot %s Command Block '%x'\n", CmdBlkP->Packet.len & 0x80 ? "Command" : "Data", CmdBlkP->Packet.data[0]); - - rio_dprintk(RIO_DEBUG_CMD, "Command %p completed\n", CmdBlkP); - - /* - ** Clear the Rup lock to prevent mutual exclusion. - */ - if (CmdBlkP->PostFuncP) { - rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); - (*CmdBlkP->PostFuncP) (CmdBlkP->PostArg, CmdBlkP); - rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); - } - - /* - ** ....clear the pending flag.... - */ - UnixRupP->CmdPendingP = NULL; - - /* - ** ....and return the command block to the freelist. - */ - RIOFreeCmdBlk(CmdBlkP); - } - - /* - ** If there is a command for this rup, and the rup - ** is idle, then process the command - */ - if ((CmdBlkP = UnixRupP->CmdsWaitingP) && /* ASSIGN! */ - (UnixRupP->CmdPendingP == NULL) && (readw(&UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) { - /* - ** if the pre-function is non-zero, call it. - ** If it returns RIO_FAIL then don't - ** send this command yet! - */ - if (!(CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP) (CmdBlkP->PreArg, CmdBlkP) : 1)) { - rio_dprintk(RIO_DEBUG_CMD, "Not ready to start command %p\n", CmdBlkP); - } else { - rio_dprintk(RIO_DEBUG_CMD, "Start new command %p Cmd byte is 0x%x\n", CmdBlkP, CmdBlkP->Packet.data[0]); - /* - ** Whammy! blat that pack! - */ - HostP->Copy(&CmdBlkP->Packet, RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->txpkt)), sizeof(struct PKT)); - - /* - ** remove the command from the rup command queue... - */ - UnixRupP->CmdsWaitingP = CmdBlkP->NextP; - - /* - ** ...and place it on the pending position. - */ - UnixRupP->CmdPendingP = CmdBlkP; - - /* - ** set the command register - */ - writew(TX_PACKET_READY, &UnixRupP->RupP->txcontrol); - - /* - ** the command block will be freed - ** when the command has been processed. - */ - } - } - spin_unlock_irqrestore(&UnixRupP->RupLock, flags); - } while (Rup); -} - -int RIOWFlushMark(unsigned long iPortP, struct CmdBlk *CmdBlkP) -{ - struct Port *PortP = (struct Port *) iPortP; - unsigned long flags; - - rio_spin_lock_irqsave(&PortP->portSem, flags); - PortP->WflushFlag++; - PortP->MagicFlags |= MAGIC_FLUSH; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return RIOUnUse(iPortP, CmdBlkP); -} - -int RIORFlushEnable(unsigned long iPortP, struct CmdBlk *CmdBlkP) -{ - struct Port *PortP = (struct Port *) iPortP; - struct PKT __iomem *PacketP; - unsigned long flags; - - rio_spin_lock_irqsave(&PortP->portSem, flags); - - while (can_remove_receive(&PacketP, PortP)) { - remove_receive(PortP); - put_free_end(PortP->HostP, PacketP); - } - - if (readw(&PortP->PhbP->handshake) == PHB_HANDSHAKE_SET) { - /* - ** MAGIC! (Basically, handshake the RX buffer, so that - ** the RTAs upstream can be re-enabled.) - */ - rio_dprintk(RIO_DEBUG_CMD, "Util: Set RX handshake bit\n"); - writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &PortP->PhbP->handshake); - } - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return RIOUnUse(iPortP, CmdBlkP); -} - -int RIOUnUse(unsigned long iPortP, struct CmdBlk *CmdBlkP) -{ - struct Port *PortP = (struct Port *) iPortP; - unsigned long flags; - - rio_spin_lock_irqsave(&PortP->portSem, flags); - - rio_dprintk(RIO_DEBUG_CMD, "Decrement in use count for port\n"); - - if (PortP->InUse) { - if (--PortP->InUse != NOT_INUSE) { - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return 0; - } - } - /* - ** While PortP->InUse is set (i.e. a preemptive command has been sent to - ** the RTA and is awaiting completion), any transmit data is prevented from - ** being transferred from the write queue into the transmit packets - ** (add_transmit) and no furthur transmit interrupt will be sent for that - ** data. The next interrupt will occur up to 500ms later (RIOIntr is called - ** twice a second as a saftey measure). This was the case when kermit was - ** used to send data into a RIO port. After each packet was sent, TCFLSH - ** was called to flush the read queue preemptively. PortP->InUse was - ** incremented, thereby blocking the 6 byte acknowledgement packet - ** transmitted back. This acknowledgment hung around for 500ms before - ** being sent, thus reducing input performance substantially!. - ** When PortP->InUse becomes NOT_INUSE, we must ensure that any data - ** hanging around in the transmit buffer is sent immediately. - */ - writew(1, &PortP->HostP->ParmMapP->tx_intr); - /* What to do here .. - wakeup( (caddr_t)&(PortP->InUse) ); - */ - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return 0; -} - -/* -** -** How to use this file: -** -** To send a command down a rup, you need to allocate a command block, fill -** in the packet information, fill in the command number, fill in the pre- -** and post- functions and arguments, and then add the command block to the -** queue of command blocks for the port in question. When the port is idle, -** then the pre-function will be called. If this returns RIO_FAIL then the -** command will be re-queued and tried again at a later date (probably in one -** clock tick). If the pre-function returns NOT RIO_FAIL, then the command -** packet will be queued on the RUP, and the txcontrol field set to the -** command number. When the txcontrol field has changed from being the -** command number, then the post-function will be called, with the argument -** specified earlier, a pointer to the command block, and the value of -** txcontrol. -** -** To allocate a command block, call RIOGetCmdBlk(). This returns a pointer -** to the command block structure allocated, or NULL if there aren't any. -** The block will have been zeroed for you. -** -** The structure has the following fields: -** -** struct CmdBlk -** { -** struct CmdBlk *NextP; ** Pointer to next command block ** -** struct PKT Packet; ** A packet, to copy to the rup ** -** int (*PreFuncP)(); ** The func to call to check if OK ** -** int PreArg; ** The arg for the func ** -** int (*PostFuncP)(); ** The func to call when completed ** -** int PostArg; ** The arg for the func ** -** }; -** -** You need to fill in ALL fields EXCEPT NextP, which is used to link the -** blocks together either on the free list or on the Rup list. -** -** Packet is an actual packet structure to be filled in with the packet -** information associated with the command. You need to fill in everything, -** as the command processor doesn't process the command packet in any way. -** -** The PreFuncP is called before the packet is enqueued on the host rup. -** PreFuncP is called as (*PreFuncP)(PreArg, CmdBlkP);. PreFuncP must -** return !RIO_FAIL to have the packet queued on the rup, and RIO_FAIL -** if the packet is NOT to be queued. -** -** The PostFuncP is called when the command has completed. It is called -** as (*PostFuncP)(PostArg, CmdBlkP, txcontrol);. PostFuncP is not expected -** to return a value. PostFuncP does NOT need to free the command block, -** as this happens automatically after PostFuncP returns. -** -** Once the command block has been filled in, it is attached to the correct -** queue by calling RIOQueueCmdBlk( HostP, Rup, CmdBlkP ) where HostP is -** a pointer to the struct Host, Rup is the NUMBER of the rup (NOT a pointer -** to it!), and CmdBlkP is the pointer to the command block allocated using -** RIOGetCmdBlk(). -** -*/ diff --git a/drivers/char/rio/rioctrl.c b/drivers/char/rio/rioctrl.c deleted file mode 100644 index 780506326a73..000000000000 --- a/drivers/char/rio/rioctrl.c +++ /dev/null @@ -1,1504 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : rioctrl.c -** SID : 1.3 -** Last Modified : 11/6/98 10:33:42 -** Retrieved : 11/6/98 10:33:49 -** -** ident @(#)rioctrl.c 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - - -#include "linux_compat.h" -#include "rio_linux.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" -#include "cirrus.h" -#include "rioioctl.h" - - -static struct LpbReq LpbReq; -static struct RupReq RupReq; -static struct PortReq PortReq; -static struct HostReq HostReq; /* oh really? global? and no locking? */ -static struct HostDpRam HostDpRam; -static struct DebugCtrl DebugCtrl; -static struct Map MapEnt; -static struct PortSetup PortSetup; -static struct DownLoad DownLoad; -static struct SendPack SendPack; -/* static struct StreamInfo StreamInfo; */ -/* static char modemtable[RIO_PORTS]; */ -static struct SpecialRupCmd SpecialRupCmd; -static struct PortParams PortParams; -static struct portStats portStats; - -static struct SubCmdStruct { - ushort Host; - ushort Rup; - ushort Port; - ushort Addr; -} SubCmd; - -struct PortTty { - uint port; - struct ttystatics Tty; -}; - -static struct PortTty PortTty; -typedef struct ttystatics TERMIO; - -/* -** This table is used when the config.rio downloads bin code to the -** driver. We index the table using the product code, 0-F, and call -** the function pointed to by the entry, passing the information -** about the boot. -** The RIOBootCodeUNKNOWN entry is there to politely tell the calling -** process to bog off. -*/ -static int - (*RIOBootTable[MAX_PRODUCT]) (struct rio_info *, struct DownLoad *) = { - /* 0 */ RIOBootCodeHOST, - /* Host Card */ - /* 1 */ RIOBootCodeRTA, - /* RTA */ -}; - -#define drv_makedev(maj, min) ((((uint) maj & 0xff) << 8) | ((uint) min & 0xff)) - -static int copy_from_io(void __user *to, void __iomem *from, size_t size) -{ - void *buf = kmalloc(size, GFP_KERNEL); - int res = -ENOMEM; - if (buf) { - rio_memcpy_fromio(buf, from, size); - res = copy_to_user(to, buf, size); - kfree(buf); - } - return res; -} - -int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su) -{ - uint Host; /* leave me unsigned! */ - uint port; /* and me! */ - struct Host *HostP; - ushort loop; - int Entry; - struct Port *PortP; - struct PKT __iomem *PacketP; - int retval = 0; - unsigned long flags; - void __user *argp = (void __user *)arg; - - func_enter(); - - /* Confuse the compiler to think that we've initialized these */ - Host = 0; - PortP = NULL; - - rio_dprintk(RIO_DEBUG_CTRL, "control ioctl cmd: 0x%x arg: %p\n", cmd, argp); - - switch (cmd) { - /* - ** RIO_SET_TIMER - ** - ** Change the value of the host card interrupt timer. - ** If the host card number is -1 then all host cards are changed - ** otherwise just the specified host card will be changed. - */ - case RIO_SET_TIMER: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_TIMER to %ldms\n", arg); - { - int host, value; - host = (arg >> 16) & 0x0000FFFF; - value = arg & 0x0000ffff; - if (host == -1) { - for (host = 0; host < p->RIONumHosts; host++) { - if (p->RIOHosts[host].Flags == RC_RUNNING) { - writew(value, &p->RIOHosts[host].ParmMapP->timer); - } - } - } else if (host >= p->RIONumHosts) { - return -EINVAL; - } else { - if (p->RIOHosts[host].Flags == RC_RUNNING) { - writew(value, &p->RIOHosts[host].ParmMapP->timer); - } - } - } - return 0; - - case RIO_FOAD_RTA: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_FOAD_RTA\n"); - return RIOCommandRta(p, arg, RIOFoadRta); - - case RIO_ZOMBIE_RTA: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_ZOMBIE_RTA\n"); - return RIOCommandRta(p, arg, RIOZombieRta); - - case RIO_IDENTIFY_RTA: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_IDENTIFY_RTA\n"); - return RIOIdentifyRta(p, argp); - - case RIO_KILL_NEIGHBOUR: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_KILL_NEIGHBOUR\n"); - return RIOKillNeighbour(p, argp); - - case SPECIAL_RUP_CMD: - { - struct CmdBlk *CmdBlkP; - - rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD\n"); - if (copy_from_user(&SpecialRupCmd, argp, sizeof(SpecialRupCmd))) { - rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD copy failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - CmdBlkP = RIOGetCmdBlk(); - if (!CmdBlkP) { - rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD GetCmdBlk failed\n"); - return -ENXIO; - } - CmdBlkP->Packet = SpecialRupCmd.Packet; - if (SpecialRupCmd.Host >= p->RIONumHosts) - SpecialRupCmd.Host = 0; - rio_dprintk(RIO_DEBUG_CTRL, "Queue special rup command for host %d rup %d\n", SpecialRupCmd.Host, SpecialRupCmd.RupNum); - if (RIOQueueCmdBlk(&p->RIOHosts[SpecialRupCmd.Host], SpecialRupCmd.RupNum, CmdBlkP) == RIO_FAIL) { - printk(KERN_WARNING "rio: FAILED TO QUEUE SPECIAL RUP COMMAND\n"); - } - return 0; - } - - case RIO_DEBUG_MEM: - return -EPERM; - - case RIO_ALL_MODEM: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_ALL_MODEM\n"); - p->RIOError.Error = IOCTL_COMMAND_UNKNOWN; - return -EINVAL; - - case RIO_GET_TABLE: - /* - ** Read the routing table from the device driver to user space - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_TABLE\n"); - - if ((retval = RIOApel(p)) != 0) - return retval; - - if (copy_to_user(argp, p->RIOConnectTable, TOTAL_MAP_ENTRIES * sizeof(struct Map))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_TABLE copy failed\n"); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - - { - int entry; - rio_dprintk(RIO_DEBUG_CTRL, "*****\nMAP ENTRIES\n"); - for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) { - if ((p->RIOConnectTable[entry].ID == 0) && (p->RIOConnectTable[entry].HostUniqueNum == 0) && (p->RIOConnectTable[entry].RtaUniqueNum == 0)) - continue; - - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.HostUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].HostUniqueNum); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Flags = 0x%x\n", entry, (int) p->RIOConnectTable[entry].Flags); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.SysPort = 0x%x\n", entry, (int) p->RIOConnectTable[entry].SysPort); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[0].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Unit); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[0].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Link); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[1].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Unit); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[1].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Link); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[2].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Unit); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[2].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Link); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[3].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Unit); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[4].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Link); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name); - } - rio_dprintk(RIO_DEBUG_CTRL, "*****\nEND MAP ENTRIES\n"); - } - p->RIOQuickCheck = NOT_CHANGED; /* a table has been gotten */ - return 0; - - case RIO_PUT_TABLE: - /* - ** Write the routing table to the device driver from user space - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE\n"); - - if (!su) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE !Root\n"); - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - if (copy_from_user(&p->RIOConnectTable[0], argp, TOTAL_MAP_ENTRIES * sizeof(struct Map))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE copy failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } -/* -*********************************** - { - int entry; - rio_dprint(RIO_DEBUG_CTRL, ("*****\nMAP ENTRIES\n") ); - for ( entry=0; entryRIOConnectTable[entry].HostUniqueNum ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2 ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Flags = 0x%x\n", entry, p->RIOConnectTable[entry].Flags ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.SysPort = 0x%x\n", entry, p->RIOConnectTable[entry].SysPort ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[0].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[0].Unit ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[0].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[0].Link ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[1].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[1].Unit ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[1].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[1].Link ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[2].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[2].Unit ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[2].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[2].Link ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[3].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[3].Unit ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[4].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[3].Link ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name ) ); - } - rio_dprint(RIO_DEBUG_CTRL, ("*****\nEND MAP ENTRIES\n") ); - } -*********************************** -*/ - return RIONewTable(p); - - case RIO_GET_BINDINGS: - /* - ** Send bindings table, containing unique numbers of RTAs owned - ** by this system to user space - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS\n"); - - if (!su) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS !Root\n"); - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - if (copy_to_user(argp, p->RIOBindTab, (sizeof(ulong) * MAX_RTA_BINDINGS))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS copy failed\n"); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return 0; - - case RIO_PUT_BINDINGS: - /* - ** Receive a bindings table, containing unique numbers of RTAs owned - ** by this system - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS\n"); - - if (!su) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS !Root\n"); - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - if (copy_from_user(&p->RIOBindTab[0], argp, (sizeof(ulong) * MAX_RTA_BINDINGS))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS copy failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - return 0; - - case RIO_BIND_RTA: - { - int EmptySlot = -1; - /* - ** Bind this RTA to host, so that it will be booted by - ** host in 'boot owned RTAs' mode. - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_BIND_RTA\n"); - - if (!su) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_BIND_RTA !Root\n"); - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - for (Entry = 0; Entry < MAX_RTA_BINDINGS; Entry++) { - if ((EmptySlot == -1) && (p->RIOBindTab[Entry] == 0L)) - EmptySlot = Entry; - else if (p->RIOBindTab[Entry] == arg) { - /* - ** Already exists - delete - */ - p->RIOBindTab[Entry] = 0L; - rio_dprintk(RIO_DEBUG_CTRL, "Removing Rta %ld from p->RIOBindTab\n", arg); - return 0; - } - } - /* - ** Dosen't exist - add - */ - if (EmptySlot != -1) { - p->RIOBindTab[EmptySlot] = arg; - rio_dprintk(RIO_DEBUG_CTRL, "Adding Rta %lx to p->RIOBindTab\n", arg); - } else { - rio_dprintk(RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %lx not added\n", arg); - return -ENOMEM; - } - return 0; - } - - case RIO_RESUME: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME\n"); - port = arg; - if ((port < 0) || (port > 511)) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Bad port number %d\n", port); - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - PortP = p->RIOPortp[port]; - if (!PortP->Mapped) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not mapped\n", port); - p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM; - return -EINVAL; - } - if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not open\n", port); - return -EINVAL; - } - - rio_spin_lock_irqsave(&PortP->portSem, flags); - if (RIOPreemptiveCmd(p, (p->RIOPortp[port]), RIOC_RESUME) == - RIO_FAIL) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME failed\n"); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return -EBUSY; - } else { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d resumed\n", port); - PortP->State |= RIO_BUSY; - } - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return retval; - - case RIO_ASSIGN_RTA: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA\n"); - if (!su) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA !Root\n"); - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) { - rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - return RIOAssignRta(p, &MapEnt); - - case RIO_CHANGE_NAME: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_CHANGE_NAME\n"); - if (!su) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_CHANGE_NAME !Root\n"); - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) { - rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - return RIOChangeName(p, &MapEnt); - - case RIO_DELETE_RTA: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_DELETE_RTA\n"); - if (!su) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_DELETE_RTA !Root\n"); - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) { - rio_dprintk(RIO_DEBUG_CTRL, "Copy from data space failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - return RIODeleteRta(p, &MapEnt); - - case RIO_QUICK_CHECK: - if (copy_to_user(argp, &p->RIORtaDisCons, sizeof(unsigned int))) { - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return 0; - - case RIO_LAST_ERROR: - if (copy_to_user(argp, &p->RIOError, sizeof(struct Error))) - return -EFAULT; - return 0; - - case RIO_GET_LOG: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_LOG\n"); - return -EINVAL; - - case RIO_GET_MODTYPE: - if (copy_from_user(&port, argp, sizeof(unsigned int))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - rio_dprintk(RIO_DEBUG_CTRL, "Get module type for port %d\n", port); - if (port < 0 || port > 511) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Bad port number %d\n", port); - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - PortP = (p->RIOPortp[port]); - if (!PortP->Mapped) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Port %d not mapped\n", port); - p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM; - return -EINVAL; - } - /* - ** Return module type of port - */ - port = PortP->HostP->UnixRups[PortP->RupNum].ModTypes; - if (copy_to_user(argp, &port, sizeof(unsigned int))) { - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return (0); - case RIO_BLOCK_OPENS: - rio_dprintk(RIO_DEBUG_CTRL, "Opens block until booted\n"); - for (Entry = 0; Entry < RIO_PORTS; Entry++) { - rio_spin_lock_irqsave(&PortP->portSem, flags); - p->RIOPortp[Entry]->WaitUntilBooted = 1; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - } - return 0; - - case RIO_SETUP_PORTS: - rio_dprintk(RIO_DEBUG_CTRL, "Setup ports\n"); - if (copy_from_user(&PortSetup, argp, sizeof(PortSetup))) { - p->RIOError.Error = COPYIN_FAILED; - rio_dprintk(RIO_DEBUG_CTRL, "EFAULT"); - return -EFAULT; - } - if (PortSetup.From > PortSetup.To || PortSetup.To >= RIO_PORTS) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - rio_dprintk(RIO_DEBUG_CTRL, "ENXIO"); - return -ENXIO; - } - if (PortSetup.XpCps > p->RIOConf.MaxXpCps || PortSetup.XpCps < p->RIOConf.MinXpCps) { - p->RIOError.Error = XPRINT_CPS_OUT_OF_RANGE; - rio_dprintk(RIO_DEBUG_CTRL, "EINVAL"); - return -EINVAL; - } - if (!p->RIOPortp) { - printk(KERN_ERR "rio: No p->RIOPortp array!\n"); - rio_dprintk(RIO_DEBUG_CTRL, "No p->RIOPortp array!\n"); - return -EIO; - } - rio_dprintk(RIO_DEBUG_CTRL, "entering loop (%d %d)!\n", PortSetup.From, PortSetup.To); - for (loop = PortSetup.From; loop <= PortSetup.To; loop++) { - rio_dprintk(RIO_DEBUG_CTRL, "in loop (%d)!\n", loop); - } - rio_dprintk(RIO_DEBUG_CTRL, "after loop (%d)!\n", loop); - rio_dprintk(RIO_DEBUG_CTRL, "Retval:%x\n", retval); - return retval; - - case RIO_GET_PORT_SETUP: - rio_dprintk(RIO_DEBUG_CTRL, "Get port setup\n"); - if (copy_from_user(&PortSetup, argp, sizeof(PortSetup))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (PortSetup.From >= RIO_PORTS) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - - port = PortSetup.To = PortSetup.From; - PortSetup.IxAny = (p->RIOPortp[port]->Config & RIO_IXANY) ? 1 : 0; - PortSetup.IxOn = (p->RIOPortp[port]->Config & RIO_IXON) ? 1 : 0; - PortSetup.Drain = (p->RIOPortp[port]->Config & RIO_WAITDRAIN) ? 1 : 0; - PortSetup.Store = p->RIOPortp[port]->Store; - PortSetup.Lock = p->RIOPortp[port]->Lock; - PortSetup.XpCps = p->RIOPortp[port]->Xprint.XpCps; - memcpy(PortSetup.XpOn, p->RIOPortp[port]->Xprint.XpOn, MAX_XP_CTRL_LEN); - memcpy(PortSetup.XpOff, p->RIOPortp[port]->Xprint.XpOff, MAX_XP_CTRL_LEN); - PortSetup.XpOn[MAX_XP_CTRL_LEN - 1] = '\0'; - PortSetup.XpOff[MAX_XP_CTRL_LEN - 1] = '\0'; - - if (copy_to_user(argp, &PortSetup, sizeof(PortSetup))) { - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return retval; - - case RIO_GET_PORT_PARAMS: - rio_dprintk(RIO_DEBUG_CTRL, "Get port params\n"); - if (copy_from_user(&PortParams, argp, sizeof(struct PortParams))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (PortParams.Port >= RIO_PORTS) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - PortP = (p->RIOPortp[PortParams.Port]); - PortParams.Config = PortP->Config; - PortParams.State = PortP->State; - rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortParams.Port); - - if (copy_to_user(argp, &PortParams, sizeof(struct PortParams))) { - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return retval; - - case RIO_GET_PORT_TTY: - rio_dprintk(RIO_DEBUG_CTRL, "Get port tty\n"); - if (copy_from_user(&PortTty, argp, sizeof(struct PortTty))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (PortTty.port >= RIO_PORTS) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - - rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortTty.port); - PortP = (p->RIOPortp[PortTty.port]); - if (copy_to_user(argp, &PortTty, sizeof(struct PortTty))) { - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return retval; - - case RIO_SET_PORT_TTY: - if (copy_from_user(&PortTty, argp, sizeof(struct PortTty))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - rio_dprintk(RIO_DEBUG_CTRL, "Set port %d tty\n", PortTty.port); - if (PortTty.port >= (ushort) RIO_PORTS) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - PortP = (p->RIOPortp[PortTty.port]); - RIOParam(PortP, RIOC_CONFIG, PortP->State & RIO_MODEM, - OK_TO_SLEEP); - return retval; - - case RIO_SET_PORT_PARAMS: - rio_dprintk(RIO_DEBUG_CTRL, "Set port params\n"); - if (copy_from_user(&PortParams, argp, sizeof(PortParams))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (PortParams.Port >= (ushort) RIO_PORTS) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - PortP = (p->RIOPortp[PortParams.Port]); - rio_spin_lock_irqsave(&PortP->portSem, flags); - PortP->Config = PortParams.Config; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return retval; - - case RIO_GET_PORT_STATS: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_PORT_STATS\n"); - if (copy_from_user(&portStats, argp, sizeof(struct portStats))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (portStats.port < 0 || portStats.port >= RIO_PORTS) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - PortP = (p->RIOPortp[portStats.port]); - portStats.gather = PortP->statsGather; - portStats.txchars = PortP->txchars; - portStats.rxchars = PortP->rxchars; - portStats.opens = PortP->opens; - portStats.closes = PortP->closes; - portStats.ioctls = PortP->ioctls; - if (copy_to_user(argp, &portStats, sizeof(struct portStats))) { - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return retval; - - case RIO_RESET_PORT_STATS: - port = arg; - rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESET_PORT_STATS\n"); - if (port >= RIO_PORTS) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - PortP = (p->RIOPortp[port]); - rio_spin_lock_irqsave(&PortP->portSem, flags); - PortP->txchars = 0; - PortP->rxchars = 0; - PortP->opens = 0; - PortP->closes = 0; - PortP->ioctls = 0; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return retval; - - case RIO_GATHER_PORT_STATS: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GATHER_PORT_STATS\n"); - if (copy_from_user(&portStats, argp, sizeof(struct portStats))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (portStats.port < 0 || portStats.port >= RIO_PORTS) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - PortP = (p->RIOPortp[portStats.port]); - rio_spin_lock_irqsave(&PortP->portSem, flags); - PortP->statsGather = portStats.gather; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return retval; - - case RIO_READ_CONFIG: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_CONFIG\n"); - if (copy_to_user(argp, &p->RIOConf, sizeof(struct Conf))) { - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return retval; - - case RIO_SET_CONFIG: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_CONFIG\n"); - if (!su) { - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - if (copy_from_user(&p->RIOConf, argp, sizeof(struct Conf))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - /* - ** move a few value around - */ - for (Host = 0; Host < p->RIONumHosts; Host++) - if ((p->RIOHosts[Host].Flags & RUN_STATE) == RC_RUNNING) - writew(p->RIOConf.Timer, &p->RIOHosts[Host].ParmMapP->timer); - return retval; - - case RIO_START_POLLER: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_START_POLLER\n"); - return -EINVAL; - - case RIO_STOP_POLLER: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_STOP_POLLER\n"); - if (!su) { - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - p->RIOPolling = NOT_POLLING; - return retval; - - case RIO_SETDEBUG: - case RIO_GETDEBUG: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SETDEBUG/RIO_GETDEBUG\n"); - if (copy_from_user(&DebugCtrl, argp, sizeof(DebugCtrl))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (DebugCtrl.SysPort == NO_PORT) { - if (cmd == RIO_SETDEBUG) { - if (!su) { - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - p->rio_debug = DebugCtrl.Debug; - p->RIODebugWait = DebugCtrl.Wait; - rio_dprintk(RIO_DEBUG_CTRL, "Set global debug to 0x%x set wait to 0x%x\n", p->rio_debug, p->RIODebugWait); - } else { - rio_dprintk(RIO_DEBUG_CTRL, "Get global debug 0x%x wait 0x%x\n", p->rio_debug, p->RIODebugWait); - DebugCtrl.Debug = p->rio_debug; - DebugCtrl.Wait = p->RIODebugWait; - if (copy_to_user(argp, &DebugCtrl, sizeof(DebugCtrl))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", DebugCtrl.SysPort); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - } - } else if (DebugCtrl.SysPort >= RIO_PORTS && DebugCtrl.SysPort != NO_PORT) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", DebugCtrl.SysPort); - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } else if (cmd == RIO_SETDEBUG) { - if (!su) { - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - p->RIOPortp[DebugCtrl.SysPort]->Debug = DebugCtrl.Debug; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SETDEBUG 0x%x\n", p->RIOPortp[DebugCtrl.SysPort]->Debug); - } else { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG 0x%x\n", p->RIOPortp[DebugCtrl.SysPort]->Debug); - DebugCtrl.Debug = p->RIOPortp[DebugCtrl.SysPort]->Debug; - if (copy_to_user(argp, &DebugCtrl, sizeof(DebugCtrl))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG: Bad copy to user space\n"); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - } - return retval; - - case RIO_VERSID: - /* - ** Enquire about the release and version. - ** We return MAX_VERSION_LEN bytes, being a - ** textual null terminated string. - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID\n"); - if (copy_to_user(argp, RIOVersid(), sizeof(struct rioVersion))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID: Bad copy to user space (host=%d)\n", Host); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return retval; - - case RIO_NUM_HOSTS: - /* - ** Enquire as to the number of hosts located - ** at init time. - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS\n"); - if (copy_to_user(argp, &p->RIONumHosts, sizeof(p->RIONumHosts))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS: Bad copy to user space\n"); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return retval; - - case RIO_HOST_FOAD: - /* - ** Kill host. This may not be in the final version... - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD %ld\n", arg); - if (!su) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD: Not super user\n"); - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - p->RIOHalted = 1; - p->RIOSystemUp = 0; - - for (Host = 0; Host < p->RIONumHosts; Host++) { - (void) RIOBoardTest(p->RIOHosts[Host].PaddrP, p->RIOHosts[Host].Caddr, p->RIOHosts[Host].Type, p->RIOHosts[Host].Slot); - memset(&p->RIOHosts[Host].Flags, 0, ((char *) &p->RIOHosts[Host].____end_marker____) - ((char *) &p->RIOHosts[Host].Flags)); - p->RIOHosts[Host].Flags = RC_WAITING; - } - RIOFoadWakeup(p); - p->RIONumBootPkts = 0; - p->RIOBooting = 0; - printk("HEEEEELP!\n"); - - for (loop = 0; loop < RIO_PORTS; loop++) { - spin_lock_init(&p->RIOPortp[loop]->portSem); - p->RIOPortp[loop]->InUse = NOT_INUSE; - } - - p->RIOSystemUp = 0; - return retval; - - case RIO_DOWNLOAD: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD\n"); - if (!su) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Not super user\n"); - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - if (copy_from_user(&DownLoad, argp, sizeof(DownLoad))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Copy in from user space failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - rio_dprintk(RIO_DEBUG_CTRL, "Copied in download code for product code 0x%x\n", DownLoad.ProductCode); - - /* - ** It is important that the product code is an unsigned object! - */ - if (DownLoad.ProductCode >= MAX_PRODUCT) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Bad product code %d passed\n", DownLoad.ProductCode); - p->RIOError.Error = NO_SUCH_PRODUCT; - return -ENXIO; - } - /* - ** do something! - */ - retval = (*(RIOBootTable[DownLoad.ProductCode])) (p, &DownLoad); - /* <-- Panic */ - p->RIOHalted = 0; - /* - ** and go back, content with a job well completed. - */ - return retval; - - case RIO_PARMS: - { - unsigned int host; - - if (copy_from_user(&host, argp, sizeof(host))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - /* - ** Fetch the parmmap - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS\n"); - if (copy_from_io(argp, p->RIOHosts[host].ParmMapP, sizeof(PARM_MAP))) { - p->RIOError.Error = COPYOUT_FAILED; - rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS: Copy out to user space failed\n"); - return -EFAULT; - } - } - return retval; - - case RIO_HOST_REQ: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ\n"); - if (copy_from_user(&HostReq, argp, sizeof(HostReq))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (HostReq.HostNum >= p->RIONumHosts) { - p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Illegal host number %d\n", HostReq.HostNum); - return -ENXIO; - } - rio_dprintk(RIO_DEBUG_CTRL, "Request for host %d\n", HostReq.HostNum); - - if (copy_to_user(HostReq.HostP, &p->RIOHosts[HostReq.HostNum], sizeof(struct Host))) { - p->RIOError.Error = COPYOUT_FAILED; - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Bad copy to user space\n"); - return -EFAULT; - } - return retval; - - case RIO_HOST_DPRAM: - rio_dprintk(RIO_DEBUG_CTRL, "Request for DPRAM\n"); - if (copy_from_user(&HostDpRam, argp, sizeof(HostDpRam))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Copy in from user space failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (HostDpRam.HostNum >= p->RIONumHosts) { - p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Illegal host number %d\n", HostDpRam.HostNum); - return -ENXIO; - } - rio_dprintk(RIO_DEBUG_CTRL, "Request for host %d\n", HostDpRam.HostNum); - - if (p->RIOHosts[HostDpRam.HostNum].Type == RIO_PCI) { - int off; - /* It's hardware like this that really gets on my tits. */ - static unsigned char copy[sizeof(struct DpRam)]; - for (off = 0; off < sizeof(struct DpRam); off++) - copy[off] = readb(p->RIOHosts[HostDpRam.HostNum].Caddr + off); - if (copy_to_user(HostDpRam.DpRamP, copy, sizeof(struct DpRam))) { - p->RIOError.Error = COPYOUT_FAILED; - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n"); - return -EFAULT; - } - } else if (copy_from_io(HostDpRam.DpRamP, p->RIOHosts[HostDpRam.HostNum].Caddr, sizeof(struct DpRam))) { - p->RIOError.Error = COPYOUT_FAILED; - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n"); - return -EFAULT; - } - return retval; - - case RIO_SET_BUSY: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY\n"); - if (arg > 511) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY: Bad port number %ld\n", arg); - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - p->RIOPortp[arg]->State |= RIO_BUSY; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return retval; - - case RIO_HOST_PORT: - /* - ** The daemon want port information - ** (probably for debug reasons) - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT\n"); - if (copy_from_user(&PortReq, argp, sizeof(PortReq))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Copy in from user space failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - - if (PortReq.SysPort >= RIO_PORTS) { /* SysPort is unsigned */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Illegal port number %d\n", PortReq.SysPort); - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - rio_dprintk(RIO_DEBUG_CTRL, "Request for port %d\n", PortReq.SysPort); - if (copy_to_user(PortReq.PortP, p->RIOPortp[PortReq.SysPort], sizeof(struct Port))) { - p->RIOError.Error = COPYOUT_FAILED; - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Bad copy to user space\n"); - return -EFAULT; - } - return retval; - - case RIO_HOST_RUP: - /* - ** The daemon want rup information - ** (probably for debug reasons) - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP\n"); - if (copy_from_user(&RupReq, argp, sizeof(RupReq))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Copy in from user space failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (RupReq.HostNum >= p->RIONumHosts) { /* host is unsigned */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal host number %d\n", RupReq.HostNum); - p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - if (RupReq.RupNum >= MAX_RUP + LINKS_PER_UNIT) { /* eek! */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal rup number %d\n", RupReq.RupNum); - p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - HostP = &p->RIOHosts[RupReq.HostNum]; - - if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Host %d not running\n", RupReq.HostNum); - p->RIOError.Error = HOST_NOT_RUNNING; - return -EIO; - } - rio_dprintk(RIO_DEBUG_CTRL, "Request for rup %d from host %d\n", RupReq.RupNum, RupReq.HostNum); - - if (copy_from_io(RupReq.RupP, HostP->UnixRups[RupReq.RupNum].RupP, sizeof(struct RUP))) { - p->RIOError.Error = COPYOUT_FAILED; - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Bad copy to user space\n"); - return -EFAULT; - } - return retval; - - case RIO_HOST_LPB: - /* - ** The daemon want lpb information - ** (probably for debug reasons) - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB\n"); - if (copy_from_user(&LpbReq, argp, sizeof(LpbReq))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy from user space\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (LpbReq.Host >= p->RIONumHosts) { /* host is unsigned */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal host number %d\n", LpbReq.Host); - p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - if (LpbReq.Link >= LINKS_PER_UNIT) { /* eek! */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal link number %d\n", LpbReq.Link); - p->RIOError.Error = LINK_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - HostP = &p->RIOHosts[LpbReq.Host]; - - if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Host %d not running\n", LpbReq.Host); - p->RIOError.Error = HOST_NOT_RUNNING; - return -EIO; - } - rio_dprintk(RIO_DEBUG_CTRL, "Request for lpb %d from host %d\n", LpbReq.Link, LpbReq.Host); - - if (copy_from_io(LpbReq.LpbP, &HostP->LinkStrP[LpbReq.Link], sizeof(struct LPB))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy to user space\n"); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return retval; - - /* - ** Here 3 IOCTL's that allow us to change the way in which - ** rio logs errors. send them just to syslog or send them - ** to both syslog and console or send them to just the console. - ** - ** See RioStrBuf() in util.c for the other half. - */ - case RIO_SYSLOG_ONLY: - p->RIOPrintLogState = PRINT_TO_LOG; /* Just syslog */ - return 0; - - case RIO_SYSLOG_CONS: - p->RIOPrintLogState = PRINT_TO_LOG_CONS; /* syslog and console */ - return 0; - - case RIO_CONS_ONLY: - p->RIOPrintLogState = PRINT_TO_CONS; /* Just console */ - return 0; - - case RIO_SIGNALS_ON: - if (p->RIOSignalProcess) { - p->RIOError.Error = SIGNALS_ALREADY_SET; - return -EBUSY; - } - /* FIXME: PID tracking */ - p->RIOSignalProcess = current->pid; - p->RIOPrintDisabled = DONT_PRINT; - return retval; - - case RIO_SIGNALS_OFF: - if (p->RIOSignalProcess != current->pid) { - p->RIOError.Error = NOT_RECEIVING_PROCESS; - return -EPERM; - } - rio_dprintk(RIO_DEBUG_CTRL, "Clear signal process to zero\n"); - p->RIOSignalProcess = 0; - return retval; - - case RIO_SET_BYTE_MODE: - for (Host = 0; Host < p->RIONumHosts; Host++) - if (p->RIOHosts[Host].Type == RIO_AT) - p->RIOHosts[Host].Mode &= ~WORD_OPERATION; - return retval; - - case RIO_SET_WORD_MODE: - for (Host = 0; Host < p->RIONumHosts; Host++) - if (p->RIOHosts[Host].Type == RIO_AT) - p->RIOHosts[Host].Mode |= WORD_OPERATION; - return retval; - - case RIO_SET_FAST_BUS: - for (Host = 0; Host < p->RIONumHosts; Host++) - if (p->RIOHosts[Host].Type == RIO_AT) - p->RIOHosts[Host].Mode |= FAST_AT_BUS; - return retval; - - case RIO_SET_SLOW_BUS: - for (Host = 0; Host < p->RIONumHosts; Host++) - if (p->RIOHosts[Host].Type == RIO_AT) - p->RIOHosts[Host].Mode &= ~FAST_AT_BUS; - return retval; - - case RIO_MAP_B50_TO_50: - case RIO_MAP_B50_TO_57600: - case RIO_MAP_B110_TO_110: - case RIO_MAP_B110_TO_115200: - rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping\n"); - port = arg; - if (port < 0 || port > 511) { - rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", port); - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - switch (cmd) { - case RIO_MAP_B50_TO_50: - p->RIOPortp[port]->Config |= RIO_MAP_50_TO_50; - break; - case RIO_MAP_B50_TO_57600: - p->RIOPortp[port]->Config &= ~RIO_MAP_50_TO_50; - break; - case RIO_MAP_B110_TO_110: - p->RIOPortp[port]->Config |= RIO_MAP_110_TO_110; - break; - case RIO_MAP_B110_TO_115200: - p->RIOPortp[port]->Config &= ~RIO_MAP_110_TO_110; - break; - } - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return retval; - - case RIO_STREAM_INFO: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_STREAM_INFO\n"); - return -EINVAL; - - case RIO_SEND_PACKET: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET\n"); - if (copy_from_user(&SendPack, argp, sizeof(SendPack))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET: Bad copy from user space\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (SendPack.PortNum >= 128) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - - PortP = p->RIOPortp[SendPack.PortNum]; - rio_spin_lock_irqsave(&PortP->portSem, flags); - - if (!can_add_transmit(&PacketP, PortP)) { - p->RIOError.Error = UNIT_IS_IN_USE; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return -ENOSPC; - } - - for (loop = 0; loop < (ushort) (SendPack.Len & 127); loop++) - writeb(SendPack.Data[loop], &PacketP->data[loop]); - - writeb(SendPack.Len, &PacketP->len); - - add_transmit(PortP); - /* - ** Count characters transmitted for port statistics reporting - */ - if (PortP->statsGather) - PortP->txchars += (SendPack.Len & 127); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return retval; - - case RIO_NO_MESG: - if (su) - p->RIONoMessage = 1; - return su ? 0 : -EPERM; - - case RIO_MESG: - if (su) - p->RIONoMessage = 0; - return su ? 0 : -EPERM; - - case RIO_WHAT_MESG: - if (copy_to_user(argp, &p->RIONoMessage, sizeof(p->RIONoMessage))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_WHAT_MESG: Bad copy to user space\n"); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return 0; - - case RIO_MEM_DUMP: - if (copy_from_user(&SubCmd, argp, sizeof(struct SubCmdStruct))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP host %d rup %d addr %x\n", SubCmd.Host, SubCmd.Rup, SubCmd.Addr); - - if (SubCmd.Rup >= MAX_RUP + LINKS_PER_UNIT) { - p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - - if (SubCmd.Host >= p->RIONumHosts) { - p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - - port = p->RIOHosts[SubCmd.Host].UnixRups[SubCmd.Rup].BaseSysPort; - - PortP = p->RIOPortp[port]; - - rio_spin_lock_irqsave(&PortP->portSem, flags); - - if (RIOPreemptiveCmd(p, PortP, RIOC_MEMDUMP) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP failed\n"); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return -EBUSY; - } else - PortP->State |= RIO_BUSY; - - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - if (copy_to_user(argp, p->RIOMemDump, MEMDUMP_SIZE)) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP copy failed\n"); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return 0; - - case RIO_TICK: - if (arg >= p->RIONumHosts) - return -EINVAL; - rio_dprintk(RIO_DEBUG_CTRL, "Set interrupt for host %ld\n", arg); - writeb(0xFF, &p->RIOHosts[arg].SetInt); - return 0; - - case RIO_TOCK: - if (arg >= p->RIONumHosts) - return -EINVAL; - rio_dprintk(RIO_DEBUG_CTRL, "Clear interrupt for host %ld\n", arg); - writeb(0xFF, &p->RIOHosts[arg].ResetInt); - return 0; - - case RIO_READ_CHECK: - /* Check reads for pkts with data[0] the same */ - p->RIOReadCheck = !p->RIOReadCheck; - if (copy_to_user(argp, &p->RIOReadCheck, sizeof(unsigned int))) { - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return 0; - - case RIO_READ_REGISTER: - if (copy_from_user(&SubCmd, argp, sizeof(struct SubCmdStruct))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER host %d rup %d port %d reg %x\n", SubCmd.Host, SubCmd.Rup, SubCmd.Port, SubCmd.Addr); - - if (SubCmd.Port > 511) { - rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", SubCmd.Port); - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - - if (SubCmd.Rup >= MAX_RUP + LINKS_PER_UNIT) { - p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - - if (SubCmd.Host >= p->RIONumHosts) { - p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - - port = p->RIOHosts[SubCmd.Host].UnixRups[SubCmd.Rup].BaseSysPort + SubCmd.Port; - PortP = p->RIOPortp[port]; - - rio_spin_lock_irqsave(&PortP->portSem, flags); - - if (RIOPreemptiveCmd(p, PortP, RIOC_READ_REGISTER) == - RIO_FAIL) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER failed\n"); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return -EBUSY; - } else - PortP->State |= RIO_BUSY; - - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - if (copy_to_user(argp, &p->CdRegister, sizeof(unsigned int))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER copy failed\n"); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return 0; - /* - ** rio_make_dev: given port number (0-511) ORed with port type - ** (RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT) return dev_t - ** value to pass to mknod to create the correct device node. - */ - case RIO_MAKE_DEV: - { - unsigned int port = arg & RIO_MODEM_MASK; - unsigned int ret; - - switch (arg & RIO_DEV_MASK) { - case RIO_DEV_DIRECT: - ret = drv_makedev(MAJOR(dev), port); - rio_dprintk(RIO_DEBUG_CTRL, "Makedev direct 0x%x is 0x%x\n", port, ret); - return ret; - case RIO_DEV_MODEM: - ret = drv_makedev(MAJOR(dev), (port | RIO_MODEM_BIT)); - rio_dprintk(RIO_DEBUG_CTRL, "Makedev modem 0x%x is 0x%x\n", port, ret); - return ret; - case RIO_DEV_XPRINT: - ret = drv_makedev(MAJOR(dev), port); - rio_dprintk(RIO_DEBUG_CTRL, "Makedev printer 0x%x is 0x%x\n", port, ret); - return ret; - } - rio_dprintk(RIO_DEBUG_CTRL, "MAKE Device is called\n"); - return -EINVAL; - } - /* - ** rio_minor: given a dev_t from a stat() call, return - ** the port number (0-511) ORed with the port type - ** ( RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT ) - */ - case RIO_MINOR: - { - dev_t dv; - int mino; - unsigned long ret; - - dv = (dev_t) (arg); - mino = RIO_UNMODEM(dv); - - if (RIO_ISMODEM(dv)) { - rio_dprintk(RIO_DEBUG_CTRL, "Minor for device 0x%x: modem %d\n", dv, mino); - ret = mino | RIO_DEV_MODEM; - } else { - rio_dprintk(RIO_DEBUG_CTRL, "Minor for device 0x%x: direct %d\n", dv, mino); - ret = mino | RIO_DEV_DIRECT; - } - return ret; - } - } - rio_dprintk(RIO_DEBUG_CTRL, "INVALID DAEMON IOCTL 0x%x\n", cmd); - p->RIOError.Error = IOCTL_COMMAND_UNKNOWN; - - func_exit(); - return -EINVAL; -} - -/* -** Pre-emptive commands go on RUPs and are only one byte long. -*/ -int RIOPreemptiveCmd(struct rio_info *p, struct Port *PortP, u8 Cmd) -{ - struct CmdBlk *CmdBlkP; - struct PktCmd_M *PktCmdP; - int Ret; - ushort rup; - int port; - - if (PortP->State & RIO_DELETED) { - rio_dprintk(RIO_DEBUG_CTRL, "Preemptive command to deleted RTA ignored\n"); - return RIO_FAIL; - } - - if ((PortP->InUse == (typeof(PortP->InUse))-1) || - !(CmdBlkP = RIOGetCmdBlk())) { - rio_dprintk(RIO_DEBUG_CTRL, "Cannot allocate command block " - "for command %d on port %d\n", Cmd, PortP->PortNum); - return RIO_FAIL; - } - - rio_dprintk(RIO_DEBUG_CTRL, "Command blk %p - InUse now %d\n", - CmdBlkP, PortP->InUse); - - PktCmdP = (struct PktCmd_M *)&CmdBlkP->Packet.data[0]; - - CmdBlkP->Packet.src_unit = 0; - if (PortP->SecondBlock) - rup = PortP->ID2; - else - rup = PortP->RupNum; - CmdBlkP->Packet.dest_unit = rup; - CmdBlkP->Packet.src_port = COMMAND_RUP; - CmdBlkP->Packet.dest_port = COMMAND_RUP; - CmdBlkP->Packet.len = PKT_CMD_BIT | 2; - CmdBlkP->PostFuncP = RIOUnUse; - CmdBlkP->PostArg = (unsigned long) PortP; - PktCmdP->Command = Cmd; - port = PortP->HostPort % (ushort) PORTS_PER_RTA; - /* - ** Index ports 8-15 for 2nd block of 16 port RTA. - */ - if (PortP->SecondBlock) - port += (ushort) PORTS_PER_RTA; - PktCmdP->PhbNum = port; - - switch (Cmd) { - case RIOC_MEMDUMP: - rio_dprintk(RIO_DEBUG_CTRL, "Queue MEMDUMP command blk %p " - "(addr 0x%x)\n", CmdBlkP, (int) SubCmd.Addr); - PktCmdP->SubCommand = RIOC_MEMDUMP; - PktCmdP->SubAddr = SubCmd.Addr; - break; - case RIOC_FCLOSE: - rio_dprintk(RIO_DEBUG_CTRL, "Queue FCLOSE command blk %p\n", - CmdBlkP); - break; - case RIOC_READ_REGISTER: - rio_dprintk(RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) " - "command blk %p\n", (int) SubCmd.Addr, CmdBlkP); - PktCmdP->SubCommand = RIOC_READ_REGISTER; - PktCmdP->SubAddr = SubCmd.Addr; - break; - case RIOC_RESUME: - rio_dprintk(RIO_DEBUG_CTRL, "Queue RESUME command blk %p\n", - CmdBlkP); - break; - case RIOC_RFLUSH: - rio_dprintk(RIO_DEBUG_CTRL, "Queue RFLUSH command blk %p\n", - CmdBlkP); - CmdBlkP->PostFuncP = RIORFlushEnable; - break; - case RIOC_SUSPEND: - rio_dprintk(RIO_DEBUG_CTRL, "Queue SUSPEND command blk %p\n", - CmdBlkP); - break; - - case RIOC_MGET: - rio_dprintk(RIO_DEBUG_CTRL, "Queue MGET command blk %p\n", - CmdBlkP); - break; - - case RIOC_MSET: - case RIOC_MBIC: - case RIOC_MBIS: - CmdBlkP->Packet.data[4] = (char) PortP->ModemLines; - rio_dprintk(RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command " - "blk %p\n", CmdBlkP); - break; - - case RIOC_WFLUSH: - /* - ** If we have queued up the maximum number of Write flushes - ** allowed then we should not bother sending any more to the - ** RTA. - */ - if (PortP->WflushFlag == (typeof(PortP->WflushFlag))-1) { - rio_dprintk(RIO_DEBUG_CTRL, "Trashed WFLUSH, " - "WflushFlag about to wrap!"); - RIOFreeCmdBlk(CmdBlkP); - return (RIO_FAIL); - } else { - rio_dprintk(RIO_DEBUG_CTRL, "Queue WFLUSH command " - "blk %p\n", CmdBlkP); - CmdBlkP->PostFuncP = RIOWFlushMark; - } - break; - } - - PortP->InUse++; - - Ret = RIOQueueCmdBlk(PortP->HostP, rup, CmdBlkP); - - return Ret; -} diff --git a/drivers/char/rio/riodrvr.h b/drivers/char/rio/riodrvr.h deleted file mode 100644 index 0907e711b355..000000000000 --- a/drivers/char/rio/riodrvr.h +++ /dev/null @@ -1,138 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : riodrvr.h -** SID : 1.3 -** Last Modified : 11/6/98 09:22:46 -** Retrieved : 11/6/98 09:22:46 -** -** ident @(#)riodrvr.h 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __riodrvr_h -#define __riodrvr_h - -#include /* for HZ */ - -#define MEMDUMP_SIZE 32 -#define MOD_DISABLE (RIO_NOREAD|RIO_NOWRITE|RIO_NOXPRINT) - - -struct rio_info { - int mode; /* Intr or polled, word/byte */ - spinlock_t RIOIntrSem; /* Interrupt thread sem */ - int current_chan; /* current channel */ - int RIOFailed; /* Not initialised ? */ - int RIOInstallAttempts; /* no. of rio-install() calls */ - int RIOLastPCISearch; /* status of last search */ - int RIONumHosts; /* Number of RIO Hosts */ - struct Host *RIOHosts; /* RIO Host values */ - struct Port **RIOPortp; /* RIO port values */ -/* -** 02.03.1999 ARG - ESIL 0820 fix -** We no longer use RIOBootMode -** - int RIOBootMode; * RIO boot mode * -** -*/ - int RIOPrintDisabled; /* RIO printing disabled ? */ - int RIOPrintLogState; /* RIO printing state ? */ - int RIOPolling; /* Polling ? */ -/* -** 09.12.1998 ARG - ESIL 0776 part fix -** The 'RIO_QUICK_CHECK' ioctl was using RIOHalted. -** The fix for this ESIL introduces another member (RIORtaDisCons) here to be -** updated in RIOConCon() - to keep track of RTA connections/disconnections. -** 'RIO_QUICK_CHECK' now returns the value of RIORtaDisCons. -*/ - int RIOHalted; /* halted ? */ - int RIORtaDisCons; /* RTA connections/disconnections */ - unsigned int RIOReadCheck; /* Rio read check */ - unsigned int RIONoMessage; /* To display message or not */ - unsigned int RIONumBootPkts; /* how many packets for an RTA */ - unsigned int RIOBootCount; /* size of RTA code */ - unsigned int RIOBooting; /* count of outstanding boots */ - unsigned int RIOSystemUp; /* Booted ?? */ - unsigned int RIOCounting; /* for counting interrupts */ - unsigned int RIOIntCount; /* # of intr since last check */ - unsigned int RIOTxCount; /* number of xmit intrs */ - unsigned int RIORxCount; /* number of rx intrs */ - unsigned int RIORupCount; /* number of rup intrs */ - int RIXTimer; - int RIOBufferSize; /* Buffersize */ - int RIOBufferMask; /* Buffersize */ - - int RIOFirstMajor; /* First host card's major no */ - - unsigned int RIOLastPortsMapped; /* highest port number known */ - unsigned int RIOFirstPortsMapped; /* lowest port number known */ - - unsigned int RIOLastPortsBooted; /* highest port number running */ - unsigned int RIOFirstPortsBooted; /* lowest port number running */ - - unsigned int RIOLastPortsOpened; /* highest port number running */ - unsigned int RIOFirstPortsOpened; /* lowest port number running */ - - /* Flag to say that the topology information has been changed. */ - unsigned int RIOQuickCheck; - unsigned int CdRegister; /* ??? */ - int RIOSignalProcess; /* Signalling process */ - int rio_debug; /* To debug ... */ - int RIODebugWait; /* For what ??? */ - int tpri; /* Thread prio */ - int tid; /* Thread id */ - unsigned int _RIO_Polled; /* Counter for polling */ - unsigned int _RIO_Interrupted; /* Counter for interrupt */ - int intr_tid; /* iointset return value */ - int TxEnSem; /* TxEnable Semaphore */ - - - struct Error RIOError; /* to Identify what went wrong */ - struct Conf RIOConf; /* Configuration ??? */ - struct ttystatics channel[RIO_PORTS]; /* channel information */ - char RIOBootPackets[1 + (SIXTY_FOUR_K / RTA_BOOT_DATA_SIZE)] - [RTA_BOOT_DATA_SIZE]; - struct Map RIOConnectTable[TOTAL_MAP_ENTRIES]; - struct Map RIOSavedTable[TOTAL_MAP_ENTRIES]; - - /* RTA to host binding table for master/slave operation */ - unsigned long RIOBindTab[MAX_RTA_BINDINGS]; - /* RTA memory dump variable */ - unsigned char RIOMemDump[MEMDUMP_SIZE]; - struct ModuleInfo RIOModuleTypes[MAX_MODULE_TYPES]; - -}; - - -#ifdef linux -#define debug(x) printk x -#else -#define debug(x) kkprintf x -#endif - - - -#define RIO_RESET_INT 0x7d80 - -#endif /* __riodrvr.h */ diff --git a/drivers/char/rio/rioinfo.h b/drivers/char/rio/rioinfo.h deleted file mode 100644 index 42ff1e79d96f..000000000000 --- a/drivers/char/rio/rioinfo.h +++ /dev/null @@ -1,92 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : rioinfo.h -** SID : 1.2 -** Last Modified : 11/6/98 14:07:49 -** Retrieved : 11/6/98 14:07:50 -** -** ident @(#)rioinfo.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rioinfo_h -#define __rioinfo_h - -/* -** Host card data structure -*/ -struct RioHostInfo { - long location; /* RIO Card Base I/O address */ - long vector; /* RIO Card IRQ vector */ - int bus; /* ISA/EISA/MCA/PCI */ - int mode; /* pointer to host mode - INTERRUPT / POLLED */ - struct old_sgttyb - *Sg; /* pointer to default term characteristics */ -}; - - -/* Mode in rio device info */ -#define INTERRUPTED_MODE 0x01 /* Interrupt is generated */ -#define POLLED_MODE 0x02 /* No interrupt */ -#define AUTO_MODE 0x03 /* Auto mode */ - -#define WORD_ACCESS_MODE 0x10 /* Word Access Mode */ -#define BYTE_ACCESS_MODE 0x20 /* Byte Access Mode */ - - -/* Bus type that RIO supports */ -#define ISA_BUS 0x01 /* The card is ISA */ -#define EISA_BUS 0x02 /* The card is EISA */ -#define MCA_BUS 0x04 /* The card is MCA */ -#define PCI_BUS 0x08 /* The card is PCI */ - -/* -** 11.11.1998 ARG - ESIL ???? part fix -** Moved definition for 'CHAN' here from rioinfo.c (it is now -** called 'DEF_TERM_CHARACTERISTICS'). -*/ - -#define DEF_TERM_CHARACTERISTICS \ -{ \ - B19200, B19200, /* input and output speed */ \ - 'H' - '@', /* erase char */ \ - -1, /* 2nd erase char */ \ - 'U' - '@', /* kill char */ \ - ECHO | CRMOD, /* mode */ \ - 'C' - '@', /* interrupt character */ \ - '\\' - '@', /* quit char */ \ - 'Q' - '@', /* start char */ \ - 'S' - '@', /* stop char */ \ - 'D' - '@', /* EOF */ \ - -1, /* brk */ \ - (LCRTBS | LCRTERA | LCRTKIL | LCTLECH), /* local mode word */ \ - 'Z' - '@', /* process stop */ \ - 'Y' - '@', /* delayed stop */ \ - 'R' - '@', /* reprint line */ \ - 'O' - '@', /* flush output */ \ - 'W' - '@', /* word erase */ \ - 'V' - '@' /* literal next char */ \ -} - -#endif /* __rioinfo_h */ diff --git a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c deleted file mode 100644 index 24a282bb89d4..000000000000 --- a/drivers/char/rio/rioinit.c +++ /dev/null @@ -1,421 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : rioinit.c -** SID : 1.3 -** Last Modified : 11/6/98 10:33:43 -** Retrieved : 11/6/98 10:33:49 -** -** ident @(#)rioinit.c 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - - -#include "linux_compat.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" -#include "cirrus.h" -#include "rioioctl.h" -#include "rio_linux.h" - -int RIOPCIinit(struct rio_info *p, int Mode); - -static int RIOScrub(int, u8 __iomem *, int); - - -/** -** RIOAssignAT : -** -** Fill out the fields in the p->RIOHosts structure now we know we know -** we have a board present. -** -** bits < 0 indicates 8 bit operation requested, -** bits > 0 indicates 16 bit operation. -*/ - -int RIOAssignAT(struct rio_info *p, int Base, void __iomem *virtAddr, int mode) -{ - int bits; - struct DpRam __iomem *cardp = (struct DpRam __iomem *)virtAddr; - - if ((Base < ONE_MEG) || (mode & BYTE_ACCESS_MODE)) - bits = BYTE_OPERATION; - else - bits = WORD_OPERATION; - - /* - ** Board has passed its scrub test. Fill in all the - ** transient stuff. - */ - p->RIOHosts[p->RIONumHosts].Caddr = virtAddr; - p->RIOHosts[p->RIONumHosts].CardP = virtAddr; - - /* - ** Revision 01 AT host cards don't support WORD operations, - */ - if (readb(&cardp->DpRevision) == 01) - bits = BYTE_OPERATION; - - p->RIOHosts[p->RIONumHosts].Type = RIO_AT; - p->RIOHosts[p->RIONumHosts].Copy = rio_copy_to_card; - /* set this later */ - p->RIOHosts[p->RIONumHosts].Slot = -1; - p->RIOHosts[p->RIONumHosts].Mode = SLOW_LINKS | SLOW_AT_BUS | bits; - writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | p->RIOHosts[p->RIONumHosts].Mode | INTERRUPT_DISABLE , - &p->RIOHosts[p->RIONumHosts].Control); - writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt); - writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | p->RIOHosts[p->RIONumHosts].Mode | INTERRUPT_DISABLE, - &p->RIOHosts[p->RIONumHosts].Control); - writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt); - p->RIOHosts[p->RIONumHosts].UniqueNum = - ((readb(&p->RIOHosts[p->RIONumHosts].Unique[0])&0xFF)<<0)| - ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1])&0xFF)<<8)| - ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2])&0xFF)<<16)| - ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3])&0xFF)<<24); - rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Uniquenum 0x%x\n",p->RIOHosts[p->RIONumHosts].UniqueNum); - - p->RIONumHosts++; - rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Tests Passed at 0x%x\n", Base); - return(1); -} - -static u8 val[] = { -#ifdef VERY_LONG_TEST - 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, - 0xa5, 0xff, 0x5a, 0x00, 0xff, 0xc9, 0x36, -#endif - 0xff, 0x00, 0x00 }; - -#define TEST_END sizeof(val) - -/* -** RAM test a board. -** Nothing too complicated, just enough to check it out. -*/ -int RIOBoardTest(unsigned long paddr, void __iomem *caddr, unsigned char type, int slot) -{ - struct DpRam __iomem *DpRam = caddr; - void __iomem *ram[4]; - int size[4]; - int op, bank; - int nbanks; - - rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Reset host type=%d, DpRam=%p, slot=%d\n", - type, DpRam, slot); - - RIOHostReset(type, DpRam, slot); - - /* - ** Scrub the memory. This comes in several banks: - ** DPsram1 - 7000h bytes - ** DPsram2 - 200h bytes - ** DPsram3 - 7000h bytes - ** scratch - 1000h bytes - */ - - rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Setup ram/size arrays\n"); - - size[0] = DP_SRAM1_SIZE; - size[1] = DP_SRAM2_SIZE; - size[2] = DP_SRAM3_SIZE; - size[3] = DP_SCRATCH_SIZE; - - ram[0] = DpRam->DpSram1; - ram[1] = DpRam->DpSram2; - ram[2] = DpRam->DpSram3; - nbanks = (type == RIO_PCI) ? 3 : 4; - if (nbanks == 4) - ram[3] = DpRam->DpScratch; - - - if (nbanks == 3) { - rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Memory: %p(0x%x), %p(0x%x), %p(0x%x)\n", - ram[0], size[0], ram[1], size[1], ram[2], size[2]); - } else { - rio_dprintk (RIO_DEBUG_INIT, "RIO-init: %p(0x%x), %p(0x%x), %p(0x%x), %p(0x%x)\n", - ram[0], size[0], ram[1], size[1], ram[2], size[2], ram[3], size[3]); - } - - /* - ** This scrub operation will test for crosstalk between - ** banks. TEST_END is a magic number, and relates to the offset - ** within the 'val' array used by Scrub. - */ - for (op=0; opMapping[UnitId].Name, "UNKNOWN RTA X-XX", 17); - HostP->Mapping[UnitId].Name[12]='1'+(HostP-p->RIOHosts); - if ((UnitId+1) > 9) { - HostP->Mapping[UnitId].Name[14]='0'+((UnitId+1)/10); - HostP->Mapping[UnitId].Name[15]='0'+((UnitId+1)%10); - } - else { - HostP->Mapping[UnitId].Name[14]='1'+UnitId; - HostP->Mapping[UnitId].Name[15]=0; - } - return 0; -} - -#define RIO_RELEASE "Linux" -#define RELEASE_ID "1.0" - -static struct rioVersion stVersion; - -struct rioVersion *RIOVersid(void) -{ - strlcpy(stVersion.version, "RIO driver for linux V1.0", - sizeof(stVersion.version)); - strlcpy(stVersion.buildDate, __DATE__, - sizeof(stVersion.buildDate)); - - return &stVersion; -} - -void RIOHostReset(unsigned int Type, struct DpRam __iomem *DpRamP, unsigned int Slot) -{ - /* - ** Reset the Tpu - */ - rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: type 0x%x", Type); - switch ( Type ) { - case RIO_AT: - rio_dprintk (RIO_DEBUG_INIT, " (RIO_AT)\n"); - writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | INTERRUPT_DISABLE | BYTE_OPERATION | - SLOW_LINKS | SLOW_AT_BUS, &DpRamP->DpControl); - writeb(0xFF, &DpRamP->DpResetTpu); - udelay(3); - rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: Don't know if it worked. Try reset again\n"); - writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | INTERRUPT_DISABLE | - BYTE_OPERATION | SLOW_LINKS | SLOW_AT_BUS, &DpRamP->DpControl); - writeb(0xFF, &DpRamP->DpResetTpu); - udelay(3); - break; - case RIO_PCI: - rio_dprintk (RIO_DEBUG_INIT, " (RIO_PCI)\n"); - writeb(RIO_PCI_BOOT_FROM_RAM, &DpRamP->DpControl); - writeb(0xFF, &DpRamP->DpResetInt); - writeb(0xFF, &DpRamP->DpResetTpu); - udelay(100); - break; - default: - rio_dprintk (RIO_DEBUG_INIT, " (UNKNOWN)\n"); - break; - } - return; -} diff --git a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c deleted file mode 100644 index 2e71aecae206..000000000000 --- a/drivers/char/rio/riointr.c +++ /dev/null @@ -1,645 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : riointr.c -** SID : 1.2 -** Last Modified : 11/6/98 10:33:44 -** Retrieved : 11/6/98 10:33:49 -** -** ident @(#)riointr.c 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include - -#include "linux_compat.h" -#include "rio_linux.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" -#include "cirrus.h" -#include "rioioctl.h" - - -static void RIOReceive(struct rio_info *, struct Port *); - - -static char *firstchars(char *p, int nch) -{ - static char buf[2][128]; - static int t = 0; - t = !t; - memcpy(buf[t], p, nch); - buf[t][nch] = 0; - return buf[t]; -} - - -#define INCR( P, I ) ((P) = (((P)+(I)) & p->RIOBufferMask)) -/* Enable and start the transmission of packets */ -void RIOTxEnable(char *en) -{ - struct Port *PortP; - struct rio_info *p; - struct tty_struct *tty; - int c; - struct PKT __iomem *PacketP; - unsigned long flags; - - PortP = (struct Port *) en; - p = (struct rio_info *) PortP->p; - tty = PortP->gs.port.tty; - - - rio_dprintk(RIO_DEBUG_INTR, "tx port %d: %d chars queued.\n", PortP->PortNum, PortP->gs.xmit_cnt); - - if (!PortP->gs.xmit_cnt) - return; - - - /* This routine is an order of magnitude simpler than the specialix - version. One of the disadvantages is that this version will send - an incomplete packet (usually 64 bytes instead of 72) once for - every 4k worth of data. Let's just say that this won't influence - performance significantly..... */ - - rio_spin_lock_irqsave(&PortP->portSem, flags); - - while (can_add_transmit(&PacketP, PortP)) { - c = PortP->gs.xmit_cnt; - if (c > PKT_MAX_DATA_LEN) - c = PKT_MAX_DATA_LEN; - - /* Don't copy past the end of the source buffer */ - if (c > SERIAL_XMIT_SIZE - PortP->gs.xmit_tail) - c = SERIAL_XMIT_SIZE - PortP->gs.xmit_tail; - - { - int t; - t = (c > 10) ? 10 : c; - - rio_dprintk(RIO_DEBUG_INTR, "rio: tx port %d: copying %d chars: %s - %s\n", PortP->PortNum, c, firstchars(PortP->gs.xmit_buf + PortP->gs.xmit_tail, t), firstchars(PortP->gs.xmit_buf + PortP->gs.xmit_tail + c - t, t)); - } - /* If for one reason or another, we can't copy more data, - we're done! */ - if (c == 0) - break; - - rio_memcpy_toio(PortP->HostP->Caddr, PacketP->data, PortP->gs.xmit_buf + PortP->gs.xmit_tail, c); - /* udelay (1); */ - - writeb(c, &(PacketP->len)); - if (!(PortP->State & RIO_DELETED)) { - add_transmit(PortP); - /* - ** Count chars tx'd for port statistics reporting - */ - if (PortP->statsGather) - PortP->txchars += c; - } - PortP->gs.xmit_tail = (PortP->gs.xmit_tail + c) & (SERIAL_XMIT_SIZE - 1); - PortP->gs.xmit_cnt -= c; - } - - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - - if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2 * PKT_MAX_DATA_LEN)) - tty_wakeup(PortP->gs.port.tty); - -} - - -/* -** RIO Host Service routine. Does all the work traditionally associated with an -** interrupt. -*/ -static int RupIntr; -static int RxIntr; -static int TxIntr; - -void RIOServiceHost(struct rio_info *p, struct Host *HostP) -{ - rio_spin_lock(&HostP->HostLock); - if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { - static int t = 0; - rio_spin_unlock(&HostP->HostLock); - if ((t++ % 200) == 0) - rio_dprintk(RIO_DEBUG_INTR, "Interrupt but host not running. flags=%x.\n", (int) HostP->Flags); - return; - } - rio_spin_unlock(&HostP->HostLock); - - if (readw(&HostP->ParmMapP->rup_intr)) { - writew(0, &HostP->ParmMapP->rup_intr); - p->RIORupCount++; - RupIntr++; - rio_dprintk(RIO_DEBUG_INTR, "rio: RUP interrupt on host %Zd\n", HostP - p->RIOHosts); - RIOPollHostCommands(p, HostP); - } - - if (readw(&HostP->ParmMapP->rx_intr)) { - int port; - - writew(0, &HostP->ParmMapP->rx_intr); - p->RIORxCount++; - RxIntr++; - - rio_dprintk(RIO_DEBUG_INTR, "rio: RX interrupt on host %Zd\n", HostP - p->RIOHosts); - /* - ** Loop through every port. If the port is mapped into - ** the system ( i.e. has /dev/ttyXXXX associated ) then it is - ** worth checking. If the port isn't open, grab any packets - ** hanging on its receive queue and stuff them on the free - ** list; check for commands on the way. - */ - for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) { - struct Port *PortP = p->RIOPortp[port]; - struct tty_struct *ttyP; - struct PKT __iomem *PacketP; - - /* - ** not mapped in - most of the RIOPortp[] information - ** has not been set up! - ** Optimise: ports come in bundles of eight. - */ - if (!PortP->Mapped) { - port += 7; - continue; /* with the next port */ - } - - /* - ** If the host board isn't THIS host board, check the next one. - ** optimise: ports come in bundles of eight. - */ - if (PortP->HostP != HostP) { - port += 7; - continue; - } - - /* - ** Let us see - is the port open? If not, then don't service it. - */ - if (!(PortP->PortState & PORT_ISOPEN)) { - continue; - } - - /* - ** find corresponding tty structure. The process of mapping - ** the ports puts these here. - */ - ttyP = PortP->gs.port.tty; - - /* - ** Lock the port before we begin working on it. - */ - rio_spin_lock(&PortP->portSem); - - /* - ** Process received data if there is any. - */ - if (can_remove_receive(&PacketP, PortP)) - RIOReceive(p, PortP); - - /* - ** If there is no data left to be read from the port, and - ** it's handshake bit is set, then we must clear the handshake, - ** so that that downstream RTA is re-enabled. - */ - if (!can_remove_receive(&PacketP, PortP) && (readw(&PortP->PhbP->handshake) == PHB_HANDSHAKE_SET)) { - /* - ** MAGIC! ( Basically, handshake the RX buffer, so that - ** the RTAs upstream can be re-enabled. ) - */ - rio_dprintk(RIO_DEBUG_INTR, "Set RX handshake bit\n"); - writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &PortP->PhbP->handshake); - } - rio_spin_unlock(&PortP->portSem); - } - } - - if (readw(&HostP->ParmMapP->tx_intr)) { - int port; - - writew(0, &HostP->ParmMapP->tx_intr); - - p->RIOTxCount++; - TxIntr++; - rio_dprintk(RIO_DEBUG_INTR, "rio: TX interrupt on host %Zd\n", HostP - p->RIOHosts); - - /* - ** Loop through every port. - ** If the port is mapped into the system ( i.e. has /dev/ttyXXXX - ** associated ) then it is worth checking. - */ - for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) { - struct Port *PortP = p->RIOPortp[port]; - struct tty_struct *ttyP; - struct PKT __iomem *PacketP; - - /* - ** not mapped in - most of the RIOPortp[] information - ** has not been set up! - */ - if (!PortP->Mapped) { - port += 7; - continue; /* with the next port */ - } - - /* - ** If the host board isn't running, then its data structures - ** are no use to us - continue quietly. - */ - if (PortP->HostP != HostP) { - port += 7; - continue; /* with the next port */ - } - - /* - ** Let us see - is the port open? If not, then don't service it. - */ - if (!(PortP->PortState & PORT_ISOPEN)) { - continue; - } - - rio_dprintk(RIO_DEBUG_INTR, "rio: Looking into port %d.\n", port); - /* - ** Lock the port before we begin working on it. - */ - rio_spin_lock(&PortP->portSem); - - /* - ** If we can't add anything to the transmit queue, then - ** we need do none of this processing. - */ - if (!can_add_transmit(&PacketP, PortP)) { - rio_dprintk(RIO_DEBUG_INTR, "Can't add to port, so skipping.\n"); - rio_spin_unlock(&PortP->portSem); - continue; - } - - /* - ** find corresponding tty structure. The process of mapping - ** the ports puts these here. - */ - ttyP = PortP->gs.port.tty; - /* If ttyP is NULL, the port is getting closed. Forget about it. */ - if (!ttyP) { - rio_dprintk(RIO_DEBUG_INTR, "no tty, so skipping.\n"); - rio_spin_unlock(&PortP->portSem); - continue; - } - /* - ** If there is more room available we start up the transmit - ** data process again. This can be direct I/O, if the cookmode - ** is set to COOK_RAW or COOK_MEDIUM, or will be a call to the - ** riotproc( T_OUTPUT ) if we are in COOK_WELL mode, to fetch - ** characters via the line discipline. We must always call - ** the line discipline, - ** so that user input characters can be echoed correctly. - ** - ** ++++ Update +++++ - ** With the advent of double buffering, we now see if - ** TxBufferOut-In is non-zero. If so, then we copy a packet - ** to the output place, and set it going. If this empties - ** the buffer, then we must issue a wakeup( ) on OUT. - ** If it frees space in the buffer then we must issue - ** a wakeup( ) on IN. - ** - ** ++++ Extra! Extra! If PortP->WflushFlag is set, then we - ** have to send a WFLUSH command down the PHB, to mark the - ** end point of a WFLUSH. We also need to clear out any - ** data from the double buffer! ( note that WflushFlag is a - ** *count* of the number of WFLUSH commands outstanding! ) - ** - ** ++++ And there's more! - ** If an RTA is powered off, then on again, and rebooted, - ** whilst it has ports open, then we need to re-open the ports. - ** ( reasonable enough ). We can't do this when we spot the - ** re-boot, in interrupt time, because the queue is probably - ** full. So, when we come in here, we need to test if any - ** ports are in this condition, and re-open the port before - ** we try to send any more data to it. Now, the re-booted - ** RTA will be discarding packets from the PHB until it - ** receives this open packet, but don't worry tooo much - ** about that. The one thing that is interesting is the - ** combination of this effect and the WFLUSH effect! - */ - /* For now don't handle RTA reboots. -- REW. - Reenabled. Otherwise RTA reboots didn't work. Duh. -- REW */ - if (PortP->MagicFlags) { - if (PortP->MagicFlags & MAGIC_REBOOT) { - /* - ** well, the RTA has been rebooted, and there is room - ** on its queue to add the open packet that is required. - ** - ** The messy part of this line is trying to decide if - ** we need to call the Param function as a tty or as - ** a modem. - ** DONT USE CLOCAL AS A TEST FOR THIS! - ** - ** If we can't param the port, then move on to the - ** next port. - */ - PortP->InUse = NOT_INUSE; - - rio_spin_unlock(&PortP->portSem); - if (RIOParam(PortP, RIOC_OPEN, ((PortP->Cor2Copy & (RIOC_COR2_RTSFLOW | RIOC_COR2_CTSFLOW)) == (RIOC_COR2_RTSFLOW | RIOC_COR2_CTSFLOW)) ? 1 : 0, DONT_SLEEP) == RIO_FAIL) - continue; /* with next port */ - rio_spin_lock(&PortP->portSem); - PortP->MagicFlags &= ~MAGIC_REBOOT; - } - - /* - ** As mentioned above, this is a tacky hack to cope - ** with WFLUSH - */ - if (PortP->WflushFlag) { - rio_dprintk(RIO_DEBUG_INTR, "Want to WFLUSH mark this port\n"); - - if (PortP->InUse) - rio_dprintk(RIO_DEBUG_INTR, "FAILS - PORT IS IN USE\n"); - } - - while (PortP->WflushFlag && can_add_transmit(&PacketP, PortP) && (PortP->InUse == NOT_INUSE)) { - int p; - struct PktCmd __iomem *PktCmdP; - - rio_dprintk(RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n"); - /* - ** make it look just like a WFLUSH command - */ - PktCmdP = (struct PktCmd __iomem *) &PacketP->data[0]; - - writeb(RIOC_WFLUSH, &PktCmdP->Command); - - p = PortP->HostPort % (u16) PORTS_PER_RTA; - - /* - ** If second block of ports for 16 port RTA, add 8 - ** to index 8-15. - */ - if (PortP->SecondBlock) - p += PORTS_PER_RTA; - - writeb(p, &PktCmdP->PhbNum); - - /* - ** to make debuggery easier - */ - writeb('W', &PacketP->data[2]); - writeb('F', &PacketP->data[3]); - writeb('L', &PacketP->data[4]); - writeb('U', &PacketP->data[5]); - writeb('S', &PacketP->data[6]); - writeb('H', &PacketP->data[7]); - writeb(' ', &PacketP->data[8]); - writeb('0' + PortP->WflushFlag, &PacketP->data[9]); - writeb(' ', &PacketP->data[10]); - writeb(' ', &PacketP->data[11]); - writeb('\0', &PacketP->data[12]); - - /* - ** its two bytes long! - */ - writeb(PKT_CMD_BIT | 2, &PacketP->len); - - /* - ** queue it! - */ - if (!(PortP->State & RIO_DELETED)) { - add_transmit(PortP); - /* - ** Count chars tx'd for port statistics reporting - */ - if (PortP->statsGather) - PortP->txchars += 2; - } - - if (--(PortP->WflushFlag) == 0) { - PortP->MagicFlags &= ~MAGIC_FLUSH; - } - - rio_dprintk(RIO_DEBUG_INTR, "Wflush count now stands at %d\n", PortP->WflushFlag); - } - if (PortP->MagicFlags & MORE_OUTPUT_EYGOR) { - if (PortP->MagicFlags & MAGIC_FLUSH) { - PortP->MagicFlags |= MORE_OUTPUT_EYGOR; - } else { - if (!can_add_transmit(&PacketP, PortP)) { - rio_spin_unlock(&PortP->portSem); - continue; - } - rio_spin_unlock(&PortP->portSem); - RIOTxEnable((char *) PortP); - rio_spin_lock(&PortP->portSem); - PortP->MagicFlags &= ~MORE_OUTPUT_EYGOR; - } - } - } - - - /* - ** If we can't add anything to the transmit queue, then - ** we need do none of the remaining processing. - */ - if (!can_add_transmit(&PacketP, PortP)) { - rio_spin_unlock(&PortP->portSem); - continue; - } - - rio_spin_unlock(&PortP->portSem); - RIOTxEnable((char *) PortP); - } - } -} - -/* -** Routine for handling received data for tty drivers -*/ -static void RIOReceive(struct rio_info *p, struct Port *PortP) -{ - struct tty_struct *TtyP; - unsigned short transCount; - struct PKT __iomem *PacketP; - register unsigned int DataCnt; - unsigned char __iomem *ptr; - unsigned char *buf; - int copied = 0; - - static int intCount, RxIntCnt; - - /* - ** The receive data process is to remove packets from the - ** PHB until there aren't any more or the current cblock - ** is full. When this occurs, there will be some left over - ** data in the packet, that we must do something with. - ** As we haven't unhooked the packet from the read list - ** yet, we can just leave the packet there, having first - ** made a note of how far we got. This means that we need - ** a pointer per port saying where we start taking the - ** data from - this will normally be zero, but when we - ** run out of space it will be set to the offset of the - ** next byte to copy from the packet data area. The packet - ** length field is decremented by the number of bytes that - ** we successfully removed from the packet. When this reaches - ** zero, we reset the offset pointer to be zero, and free - ** the packet from the front of the queue. - */ - - intCount++; - - TtyP = PortP->gs.port.tty; - if (!TtyP) { - rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: tty is null. \n"); - return; - } - - if (PortP->State & RIO_THROTTLE_RX) { - rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: Throttled. Can't handle more input.\n"); - return; - } - - if (PortP->State & RIO_DELETED) { - while (can_remove_receive(&PacketP, PortP)) { - remove_receive(PortP); - put_free_end(PortP->HostP, PacketP); - } - } else { - /* - ** loop, just so long as: - ** i ) there's some data ( i.e. can_remove_receive ) - ** ii ) we haven't been blocked - ** iii ) there's somewhere to put the data - ** iv ) we haven't outstayed our welcome - */ - transCount = 1; - while (can_remove_receive(&PacketP, PortP) - && transCount) { - RxIntCnt++; - - /* - ** check that it is not a command! - */ - if (readb(&PacketP->len) & PKT_CMD_BIT) { - rio_dprintk(RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n"); - /* rio_dprint(RIO_DEBUG_INTR, (" sysport = %d\n", p->RIOPortp->PortNum)); */ - rio_dprintk(RIO_DEBUG_INTR, " dest_unit = %d\n", readb(&PacketP->dest_unit)); - rio_dprintk(RIO_DEBUG_INTR, " dest_port = %d\n", readb(&PacketP->dest_port)); - rio_dprintk(RIO_DEBUG_INTR, " src_unit = %d\n", readb(&PacketP->src_unit)); - rio_dprintk(RIO_DEBUG_INTR, " src_port = %d\n", readb(&PacketP->src_port)); - rio_dprintk(RIO_DEBUG_INTR, " len = %d\n", readb(&PacketP->len)); - rio_dprintk(RIO_DEBUG_INTR, " control = %d\n", readb(&PacketP->control)); - rio_dprintk(RIO_DEBUG_INTR, " csum = %d\n", readw(&PacketP->csum)); - rio_dprintk(RIO_DEBUG_INTR, " data bytes: "); - for (DataCnt = 0; DataCnt < PKT_MAX_DATA_LEN; DataCnt++) - rio_dprintk(RIO_DEBUG_INTR, "%d\n", readb(&PacketP->data[DataCnt])); - remove_receive(PortP); - put_free_end(PortP->HostP, PacketP); - continue; /* with next packet */ - } - - /* - ** How many characters can we move 'upstream' ? - ** - ** Determine the minimum of the amount of data - ** available and the amount of space in which to - ** put it. - ** - ** 1. Get the packet length by masking 'len' - ** for only the length bits. - ** 2. Available space is [buffer size] - [space used] - ** - ** Transfer count is the minimum of packet length - ** and available space. - */ - - transCount = tty_buffer_request_room(TtyP, readb(&PacketP->len) & PKT_LEN_MASK); - rio_dprintk(RIO_DEBUG_REC, "port %d: Copy %d bytes\n", PortP->PortNum, transCount); - /* - ** To use the following 'kkprintfs' for debugging - change the '#undef' - ** to '#define', (this is the only place ___DEBUG_IT___ occurs in the - ** driver). - */ - ptr = (unsigned char __iomem *) PacketP->data + PortP->RxDataStart; - - tty_prepare_flip_string(TtyP, &buf, transCount); - rio_memcpy_fromio(buf, ptr, transCount); - PortP->RxDataStart += transCount; - writeb(readb(&PacketP->len)-transCount, &PacketP->len); - copied += transCount; - - - - if (readb(&PacketP->len) == 0) { - /* - ** If we have emptied the packet, then we can - ** free it, and reset the start pointer for - ** the next packet. - */ - remove_receive(PortP); - put_free_end(PortP->HostP, PacketP); - PortP->RxDataStart = 0; - } - } - } - if (copied) { - rio_dprintk(RIO_DEBUG_REC, "port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum, copied); - tty_flip_buffer_push(TtyP); - } - - return; -} - diff --git a/drivers/char/rio/rioioctl.h b/drivers/char/rio/rioioctl.h deleted file mode 100644 index e8af5b30519e..000000000000 --- a/drivers/char/rio/rioioctl.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : rioioctl.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:13 -** Retrieved : 11/6/98 11:34:22 -** -** ident @(#)rioioctl.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rioioctl_h__ -#define __rioioctl_h__ - -/* -** RIO device driver - user ioctls and associated structures. -*/ - -struct portStats { - int port; - int gather; - unsigned long txchars; - unsigned long rxchars; - unsigned long opens; - unsigned long closes; - unsigned long ioctls; -}; - -#define RIOC ('R'<<8)|('i'<<16)|('o'<<24) - -#define RIO_QUICK_CHECK (RIOC | 105) -#define RIO_GATHER_PORT_STATS (RIOC | 193) -#define RIO_RESET_PORT_STATS (RIOC | 194) -#define RIO_GET_PORT_STATS (RIOC | 195) - -#endif /* __rioioctl_h__ */ diff --git a/drivers/char/rio/rioparam.c b/drivers/char/rio/rioparam.c deleted file mode 100644 index 6415f3f32a72..000000000000 --- a/drivers/char/rio/rioparam.c +++ /dev/null @@ -1,663 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : rioparam.c -** SID : 1.3 -** Last Modified : 11/6/98 10:33:45 -** Retrieved : 11/6/98 10:33:50 -** -** ident @(#)rioparam.c 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - - -#include "linux_compat.h" -#include "rio_linux.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" -#include "cirrus.h" -#include "rioioctl.h" -#include "param.h" - - - -/* -** The Scam, based on email from jeremyr@bugs.specialix.co.uk.... -** -** To send a command on a particular port, you put a packet with the -** command bit set onto the port. The command bit is in the len field, -** and gets ORed in with the actual byte count. -** -** When you send a packet with the command bit set the first -** data byte (data[0]) is interpreted as the command to execute. -** It also governs what data structure overlay should accompany the packet. -** Commands are defined in cirrus/cirrus.h -** -** If you want the command to pre-emt data already on the queue for the -** port, set the pre-emptive bit in conjunction with the command bit. -** It is not defined what will happen if you set the preemptive bit -** on a packet that is NOT a command. -** -** Pre-emptive commands should be queued at the head of the queue using -** add_start(), whereas normal commands and data are enqueued using -** add_end(). -** -** Most commands do not use the remaining bytes in the data array. The -** exceptions are OPEN MOPEN and CONFIG. (NB. As with the SI CONFIG and -** OPEN are currently analogous). With these three commands the following -** 11 data bytes are all used to pass config information such as baud rate etc. -** The fields are also defined in cirrus.h. Some contain straightforward -** information such as the transmit XON character. Two contain the transmit and -** receive baud rates respectively. For most baud rates there is a direct -** mapping between the rates defined in and the byte in the -** packet. There are additional (non UNIX-standard) rates defined in -** /u/dos/rio/cirrus/h/brates.h. -** -** The rest of the data fields contain approximations to the Cirrus registers -** that are used to program number of bits etc. Each registers bit fields is -** defined in cirrus.h. -** -** NB. Only use those bits that are defined as being driver specific -** or common to the RTA and the driver. -** -** All commands going from RTA->Host will be dealt with by the Host code - you -** will never see them. As with the SI there will be three fields to look out -** for in each phb (not yet defined - needs defining a.s.a.p). -** -** modem_status - current state of handshake pins. -** -** port_status - current port status - equivalent to hi_stat for SI, indicates -** if port is IDLE_OPEN, IDLE_CLOSED etc. -** -** break_status - bit X set if break has been received. -** -** Happy hacking. -** -*/ - -/* -** RIOParam is used to open or configure a port. You pass it a PortP, -** which will have a tty struct attached to it. You also pass a command, -** either OPEN or CONFIG. The port's setup is taken from the t_ fields -** of the tty struct inside the PortP, and the port is either opened -** or re-configured. You must also tell RIOParam if the device is a modem -** device or not (i.e. top bit of minor number set or clear - take special -** care when deciding on this!). -** RIOParam neither flushes nor waits for drain, and is NOT preemptive. -** -** RIOParam assumes it will be called at splrio(), and also assumes -** that CookMode is set correctly in the port structure. -** -** NB. for MPX -** tty lock must NOT have been previously acquired. -*/ -int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag) -{ - struct tty_struct *TtyP; - int retval; - struct phb_param __iomem *phb_param_ptr; - struct PKT __iomem *PacketP; - int res; - u8 Cor1 = 0, Cor2 = 0, Cor4 = 0, Cor5 = 0; - u8 TxXon = 0, TxXoff = 0, RxXon = 0, RxXoff = 0; - u8 LNext = 0, TxBaud = 0, RxBaud = 0; - int retries = 0xff; - unsigned long flags; - - func_enter(); - - TtyP = PortP->gs.port.tty; - - rio_dprintk(RIO_DEBUG_PARAM, "RIOParam: Port:%d cmd:%d Modem:%d SleepFlag:%d Mapped: %d, tty=%p\n", PortP->PortNum, cmd, Modem, SleepFlag, PortP->Mapped, TtyP); - - if (!TtyP) { - rio_dprintk(RIO_DEBUG_PARAM, "Can't call rioparam with null tty.\n"); - - func_exit(); - - return RIO_FAIL; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - - if (cmd == RIOC_OPEN) { - /* - ** If the port is set to store or lock the parameters, and it is - ** paramed with OPEN, we want to restore the saved port termio, but - ** only if StoredTermio has been saved, i.e. NOT 1st open after reboot. - */ - } - - /* - ** wait for space - */ - while (!(res = can_add_transmit(&PacketP, PortP)) || (PortP->InUse != NOT_INUSE)) { - if (retries-- <= 0) { - break; - } - if (PortP->InUse != NOT_INUSE) { - rio_dprintk(RIO_DEBUG_PARAM, "Port IN_USE for pre-emptive command\n"); - } - - if (!res) { - rio_dprintk(RIO_DEBUG_PARAM, "Port has no space on transmit queue\n"); - } - - if (SleepFlag != OK_TO_SLEEP) { - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - func_exit(); - - return RIO_FAIL; - } - - rio_dprintk(RIO_DEBUG_PARAM, "wait for can_add_transmit\n"); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - retval = RIODelay(PortP, HUNDRED_MS); - rio_spin_lock_irqsave(&PortP->portSem, flags); - if (retval == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_PARAM, "wait for can_add_transmit broken by signal\n"); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - func_exit(); - return -EINTR; - } - if (PortP->State & RIO_DELETED) { - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - func_exit(); - return 0; - } - } - - if (!res) { - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - func_exit(); - - return RIO_FAIL; - } - - rio_dprintk(RIO_DEBUG_PARAM, "can_add_transmit() returns %x\n", res); - rio_dprintk(RIO_DEBUG_PARAM, "Packet is %p\n", PacketP); - - phb_param_ptr = (struct phb_param __iomem *) PacketP->data; - - - switch (TtyP->termios->c_cflag & CSIZE) { - case CS5: - { - rio_dprintk(RIO_DEBUG_PARAM, "5 bit data\n"); - Cor1 |= RIOC_COR1_5BITS; - break; - } - case CS6: - { - rio_dprintk(RIO_DEBUG_PARAM, "6 bit data\n"); - Cor1 |= RIOC_COR1_6BITS; - break; - } - case CS7: - { - rio_dprintk(RIO_DEBUG_PARAM, "7 bit data\n"); - Cor1 |= RIOC_COR1_7BITS; - break; - } - case CS8: - { - rio_dprintk(RIO_DEBUG_PARAM, "8 bit data\n"); - Cor1 |= RIOC_COR1_8BITS; - break; - } - } - - if (TtyP->termios->c_cflag & CSTOPB) { - rio_dprintk(RIO_DEBUG_PARAM, "2 stop bits\n"); - Cor1 |= RIOC_COR1_2STOP; - } else { - rio_dprintk(RIO_DEBUG_PARAM, "1 stop bit\n"); - Cor1 |= RIOC_COR1_1STOP; - } - - if (TtyP->termios->c_cflag & PARENB) { - rio_dprintk(RIO_DEBUG_PARAM, "Enable parity\n"); - Cor1 |= RIOC_COR1_NORMAL; - } else { - rio_dprintk(RIO_DEBUG_PARAM, "Disable parity\n"); - Cor1 |= RIOC_COR1_NOP; - } - if (TtyP->termios->c_cflag & PARODD) { - rio_dprintk(RIO_DEBUG_PARAM, "Odd parity\n"); - Cor1 |= RIOC_COR1_ODD; - } else { - rio_dprintk(RIO_DEBUG_PARAM, "Even parity\n"); - Cor1 |= RIOC_COR1_EVEN; - } - - /* - ** COR 2 - */ - if (TtyP->termios->c_iflag & IXON) { - rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop output control\n"); - Cor2 |= RIOC_COR2_IXON; - } else { - if (PortP->Config & RIO_IXON) { - rio_dprintk(RIO_DEBUG_PARAM, "Force enable start/stop output control\n"); - Cor2 |= RIOC_COR2_IXON; - } else - rio_dprintk(RIO_DEBUG_PARAM, "IXON has been disabled.\n"); - } - - if (TtyP->termios->c_iflag & IXANY) { - if (PortP->Config & RIO_IXANY) { - rio_dprintk(RIO_DEBUG_PARAM, "Enable any key to restart output\n"); - Cor2 |= RIOC_COR2_IXANY; - } else - rio_dprintk(RIO_DEBUG_PARAM, "IXANY has been disabled due to sanity reasons.\n"); - } - - if (TtyP->termios->c_iflag & IXOFF) { - rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop input control 2\n"); - Cor2 |= RIOC_COR2_IXOFF; - } - - if (TtyP->termios->c_cflag & HUPCL) { - rio_dprintk(RIO_DEBUG_PARAM, "Hangup on last close\n"); - Cor2 |= RIOC_COR2_HUPCL; - } - - if (C_CRTSCTS(TtyP)) { - rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control enabled\n"); - Cor2 |= RIOC_COR2_CTSFLOW; - Cor2 |= RIOC_COR2_RTSFLOW; - } else { - rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control disabled\n"); - Cor2 &= ~RIOC_COR2_CTSFLOW; - Cor2 &= ~RIOC_COR2_RTSFLOW; - } - - - if (TtyP->termios->c_cflag & CLOCAL) { - rio_dprintk(RIO_DEBUG_PARAM, "Local line\n"); - } else { - rio_dprintk(RIO_DEBUG_PARAM, "Possible Modem line\n"); - } - - /* - ** COR 4 (there is no COR 3) - */ - if (TtyP->termios->c_iflag & IGNBRK) { - rio_dprintk(RIO_DEBUG_PARAM, "Ignore break condition\n"); - Cor4 |= RIOC_COR4_IGNBRK; - } - if (!(TtyP->termios->c_iflag & BRKINT)) { - rio_dprintk(RIO_DEBUG_PARAM, "Break generates NULL condition\n"); - Cor4 |= RIOC_COR4_NBRKINT; - } else { - rio_dprintk(RIO_DEBUG_PARAM, "Interrupt on break condition\n"); - } - - if (TtyP->termios->c_iflag & INLCR) { - rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage return on input\n"); - Cor4 |= RIOC_COR4_INLCR; - } - - if (TtyP->termios->c_iflag & IGNCR) { - rio_dprintk(RIO_DEBUG_PARAM, "Ignore carriage return on input\n"); - Cor4 |= RIOC_COR4_IGNCR; - } - - if (TtyP->termios->c_iflag & ICRNL) { - rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on input\n"); - Cor4 |= RIOC_COR4_ICRNL; - } - if (TtyP->termios->c_iflag & IGNPAR) { - rio_dprintk(RIO_DEBUG_PARAM, "Ignore characters with parity errors\n"); - Cor4 |= RIOC_COR4_IGNPAR; - } - if (TtyP->termios->c_iflag & PARMRK) { - rio_dprintk(RIO_DEBUG_PARAM, "Mark parity errors\n"); - Cor4 |= RIOC_COR4_PARMRK; - } - - /* - ** Set the RAISEMOD flag to ensure that the modem lines are raised - ** on reception of a config packet. - ** The download code handles the zero baud condition. - */ - Cor4 |= RIOC_COR4_RAISEMOD; - - /* - ** COR 5 - */ - - Cor5 = RIOC_COR5_CMOE; - - /* - ** Set to monitor tbusy/tstop (or not). - */ - - if (PortP->MonitorTstate) - Cor5 |= RIOC_COR5_TSTATE_ON; - else - Cor5 |= RIOC_COR5_TSTATE_OFF; - - /* - ** Could set LNE here if you wanted LNext processing. SVR4 will use it. - */ - if (TtyP->termios->c_iflag & ISTRIP) { - rio_dprintk(RIO_DEBUG_PARAM, "Strip input characters\n"); - if (!(PortP->State & RIO_TRIAD_MODE)) { - Cor5 |= RIOC_COR5_ISTRIP; - } - } - - if (TtyP->termios->c_oflag & ONLCR) { - rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage-return, newline on output\n"); - if (PortP->CookMode == COOK_MEDIUM) - Cor5 |= RIOC_COR5_ONLCR; - } - if (TtyP->termios->c_oflag & OCRNL) { - rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on output\n"); - if (PortP->CookMode == COOK_MEDIUM) - Cor5 |= RIOC_COR5_OCRNL; - } - if ((TtyP->termios->c_oflag & TABDLY) == TAB3) { - rio_dprintk(RIO_DEBUG_PARAM, "Tab delay 3 set\n"); - if (PortP->CookMode == COOK_MEDIUM) - Cor5 |= RIOC_COR5_TAB3; - } - - /* - ** Flow control bytes. - */ - TxXon = TtyP->termios->c_cc[VSTART]; - TxXoff = TtyP->termios->c_cc[VSTOP]; - RxXon = TtyP->termios->c_cc[VSTART]; - RxXoff = TtyP->termios->c_cc[VSTOP]; - /* - ** LNEXT byte - */ - LNext = 0; - - /* - ** Baud rate bytes - */ - rio_dprintk(RIO_DEBUG_PARAM, "Mapping of rx/tx baud %x (%x)\n", TtyP->termios->c_cflag, CBAUD); - - switch (TtyP->termios->c_cflag & CBAUD) { -#define e(b) case B ## b : RxBaud = TxBaud = RIO_B ## b ;break - e(50); - e(75); - e(110); - e(134); - e(150); - e(200); - e(300); - e(600); - e(1200); - e(1800); - e(2400); - e(4800); - e(9600); - e(19200); - e(38400); - e(57600); - e(115200); /* e(230400);e(460800); e(921600); */ - } - - rio_dprintk(RIO_DEBUG_PARAM, "tx baud 0x%x, rx baud 0x%x\n", TxBaud, RxBaud); - - - /* - ** Leftovers - */ - if (TtyP->termios->c_cflag & CREAD) - rio_dprintk(RIO_DEBUG_PARAM, "Enable receiver\n"); -#ifdef RCV1EN - if (TtyP->termios->c_cflag & RCV1EN) - rio_dprintk(RIO_DEBUG_PARAM, "RCV1EN (?)\n"); -#endif -#ifdef XMT1EN - if (TtyP->termios->c_cflag & XMT1EN) - rio_dprintk(RIO_DEBUG_PARAM, "XMT1EN (?)\n"); -#endif - if (TtyP->termios->c_lflag & ISIG) - rio_dprintk(RIO_DEBUG_PARAM, "Input character signal generating enabled\n"); - if (TtyP->termios->c_lflag & ICANON) - rio_dprintk(RIO_DEBUG_PARAM, "Canonical input: erase and kill enabled\n"); - if (TtyP->termios->c_lflag & XCASE) - rio_dprintk(RIO_DEBUG_PARAM, "Canonical upper/lower presentation\n"); - if (TtyP->termios->c_lflag & ECHO) - rio_dprintk(RIO_DEBUG_PARAM, "Enable input echo\n"); - if (TtyP->termios->c_lflag & ECHOE) - rio_dprintk(RIO_DEBUG_PARAM, "Enable echo erase\n"); - if (TtyP->termios->c_lflag & ECHOK) - rio_dprintk(RIO_DEBUG_PARAM, "Enable echo kill\n"); - if (TtyP->termios->c_lflag & ECHONL) - rio_dprintk(RIO_DEBUG_PARAM, "Enable echo newline\n"); - if (TtyP->termios->c_lflag & NOFLSH) - rio_dprintk(RIO_DEBUG_PARAM, "Disable flush after interrupt or quit\n"); -#ifdef TOSTOP - if (TtyP->termios->c_lflag & TOSTOP) - rio_dprintk(RIO_DEBUG_PARAM, "Send SIGTTOU for background output\n"); -#endif -#ifdef XCLUDE - if (TtyP->termios->c_lflag & XCLUDE) - rio_dprintk(RIO_DEBUG_PARAM, "Exclusive use of this line\n"); -#endif - if (TtyP->termios->c_iflag & IUCLC) - rio_dprintk(RIO_DEBUG_PARAM, "Map uppercase to lowercase on input\n"); - if (TtyP->termios->c_oflag & OPOST) - rio_dprintk(RIO_DEBUG_PARAM, "Enable output post-processing\n"); - if (TtyP->termios->c_oflag & OLCUC) - rio_dprintk(RIO_DEBUG_PARAM, "Map lowercase to uppercase on output\n"); - if (TtyP->termios->c_oflag & ONOCR) - rio_dprintk(RIO_DEBUG_PARAM, "No carriage return output at column 0\n"); - if (TtyP->termios->c_oflag & ONLRET) - rio_dprintk(RIO_DEBUG_PARAM, "Newline performs carriage return function\n"); - if (TtyP->termios->c_oflag & OFILL) - rio_dprintk(RIO_DEBUG_PARAM, "Use fill characters for delay\n"); - if (TtyP->termios->c_oflag & OFDEL) - rio_dprintk(RIO_DEBUG_PARAM, "Fill character is DEL\n"); - if (TtyP->termios->c_oflag & NLDLY) - rio_dprintk(RIO_DEBUG_PARAM, "Newline delay set\n"); - if (TtyP->termios->c_oflag & CRDLY) - rio_dprintk(RIO_DEBUG_PARAM, "Carriage return delay set\n"); - if (TtyP->termios->c_oflag & TABDLY) - rio_dprintk(RIO_DEBUG_PARAM, "Tab delay set\n"); - /* - ** These things are kind of useful in a later life! - */ - PortP->Cor2Copy = Cor2; - - if (PortP->State & RIO_DELETED) { - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - func_exit(); - - return RIO_FAIL; - } - - /* - ** Actually write the info into the packet to be sent - */ - writeb(cmd, &phb_param_ptr->Cmd); - writeb(Cor1, &phb_param_ptr->Cor1); - writeb(Cor2, &phb_param_ptr->Cor2); - writeb(Cor4, &phb_param_ptr->Cor4); - writeb(Cor5, &phb_param_ptr->Cor5); - writeb(TxXon, &phb_param_ptr->TxXon); - writeb(RxXon, &phb_param_ptr->RxXon); - writeb(TxXoff, &phb_param_ptr->TxXoff); - writeb(RxXoff, &phb_param_ptr->RxXoff); - writeb(LNext, &phb_param_ptr->LNext); - writeb(TxBaud, &phb_param_ptr->TxBaud); - writeb(RxBaud, &phb_param_ptr->RxBaud); - - /* - ** Set the length/command field - */ - writeb(12 | PKT_CMD_BIT, &PacketP->len); - - /* - ** The packet is formed - now, whack it off - ** to its final destination: - */ - add_transmit(PortP); - /* - ** Count characters transmitted for port statistics reporting - */ - if (PortP->statsGather) - PortP->txchars += 12; - - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - - rio_dprintk(RIO_DEBUG_PARAM, "add_transmit returned.\n"); - /* - ** job done. - */ - func_exit(); - - return 0; -} - - -/* -** We can add another packet to a transmit queue if the packet pointer pointed -** to by the TxAdd pointer has PKT_IN_USE clear in its address. -*/ -int can_add_transmit(struct PKT __iomem **PktP, struct Port *PortP) -{ - struct PKT __iomem *tp; - - *PktP = tp = (struct PKT __iomem *) RIO_PTR(PortP->Caddr, readw(PortP->TxAdd)); - - return !((unsigned long) tp & PKT_IN_USE); -} - -/* -** To add a packet to the queue, you set the PKT_IN_USE bit in the address, -** and then move the TxAdd pointer along one position to point to the next -** packet pointer. You must wrap the pointer from the end back to the start. -*/ -void add_transmit(struct Port *PortP) -{ - if (readw(PortP->TxAdd) & PKT_IN_USE) { - rio_dprintk(RIO_DEBUG_PARAM, "add_transmit: Packet has been stolen!"); - } - writew(readw(PortP->TxAdd) | PKT_IN_USE, PortP->TxAdd); - PortP->TxAdd = (PortP->TxAdd == PortP->TxEnd) ? PortP->TxStart : PortP->TxAdd + 1; - writew(RIO_OFF(PortP->Caddr, PortP->TxAdd), &PortP->PhbP->tx_add); -} - -/**************************************** - * Put a packet onto the end of the - * free list - ****************************************/ -void put_free_end(struct Host *HostP, struct PKT __iomem *PktP) -{ - struct rio_free_list __iomem *tmp_pointer; - unsigned short old_end, new_end; - unsigned long flags; - - rio_spin_lock_irqsave(&HostP->HostLock, flags); - - /************************************************* - * Put a packet back onto the back of the free list - * - ************************************************/ - - rio_dprintk(RIO_DEBUG_PFE, "put_free_end(PktP=%p)\n", PktP); - - if ((old_end = readw(&HostP->ParmMapP->free_list_end)) != TPNULL) { - new_end = RIO_OFF(HostP->Caddr, PktP); - tmp_pointer = (struct rio_free_list __iomem *) RIO_PTR(HostP->Caddr, old_end); - writew(new_end, &tmp_pointer->next); - writew(old_end, &((struct rio_free_list __iomem *) PktP)->prev); - writew(TPNULL, &((struct rio_free_list __iomem *) PktP)->next); - writew(new_end, &HostP->ParmMapP->free_list_end); - } else { /* First packet on the free list this should never happen! */ - rio_dprintk(RIO_DEBUG_PFE, "put_free_end(): This should never happen\n"); - writew(RIO_OFF(HostP->Caddr, PktP), &HostP->ParmMapP->free_list_end); - tmp_pointer = (struct rio_free_list __iomem *) PktP; - writew(TPNULL, &tmp_pointer->prev); - writew(TPNULL, &tmp_pointer->next); - } - rio_dprintk(RIO_DEBUG_CMD, "Before unlock: %p\n", &HostP->HostLock); - rio_spin_unlock_irqrestore(&HostP->HostLock, flags); -} - -/* -** can_remove_receive(PktP,P) returns non-zero if PKT_IN_USE is set -** for the next packet on the queue. It will also set PktP to point to the -** relevant packet, [having cleared the PKT_IN_USE bit]. If PKT_IN_USE is clear, -** then can_remove_receive() returns 0. -*/ -int can_remove_receive(struct PKT __iomem **PktP, struct Port *PortP) -{ - if (readw(PortP->RxRemove) & PKT_IN_USE) { - *PktP = (struct PKT __iomem *) RIO_PTR(PortP->Caddr, readw(PortP->RxRemove) & ~PKT_IN_USE); - return 1; - } - return 0; -} - -/* -** To remove a packet from the receive queue you clear its PKT_IN_USE bit, -** and then bump the pointers. Once the pointers get to the end, they must -** be wrapped back to the start. -*/ -void remove_receive(struct Port *PortP) -{ - writew(readw(PortP->RxRemove) & ~PKT_IN_USE, PortP->RxRemove); - PortP->RxRemove = (PortP->RxRemove == PortP->RxEnd) ? PortP->RxStart : PortP->RxRemove + 1; - writew(RIO_OFF(PortP->Caddr, PortP->RxRemove), &PortP->PhbP->rx_remove); -} diff --git a/drivers/char/rio/rioroute.c b/drivers/char/rio/rioroute.c deleted file mode 100644 index f9b936ac3394..000000000000 --- a/drivers/char/rio/rioroute.c +++ /dev/null @@ -1,1039 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : rioroute.c -** SID : 1.3 -** Last Modified : 11/6/98 10:33:46 -** Retrieved : 11/6/98 10:33:50 -** -** ident @(#)rioroute.c 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - - -#include "linux_compat.h" -#include "rio_linux.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" -#include "cirrus.h" -#include "rioioctl.h" -#include "param.h" - -static int RIOCheckIsolated(struct rio_info *, struct Host *, unsigned int); -static int RIOIsolate(struct rio_info *, struct Host *, unsigned int); -static int RIOCheck(struct Host *, unsigned int); -static void RIOConCon(struct rio_info *, struct Host *, unsigned int, unsigned int, unsigned int, unsigned int, int); - - -/* -** Incoming on the ROUTE_RUP -** I wrote this while I was tired. Forgive me. -*/ -int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct PKT __iomem * PacketP) -{ - struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *) PacketP->data; - struct PktCmd_M *PktReplyP; - struct CmdBlk *CmdBlkP; - struct Port *PortP; - struct Map *MapP; - struct Top *TopP; - int ThisLink, ThisLinkMin, ThisLinkMax; - int port; - int Mod, Mod1, Mod2; - unsigned short RtaType; - unsigned int RtaUniq; - unsigned int ThisUnit, ThisUnit2; /* 2 ids to accommodate 16 port RTA */ - unsigned int OldUnit, NewUnit, OldLink, NewLink; - char *MyType, *MyName; - int Lies; - unsigned long flags; - - /* - ** Is this unit telling us it's current link topology? - */ - if (readb(&PktCmdP->Command) == ROUTE_TOPOLOGY) { - MapP = HostP->Mapping; - - /* - ** The packet can be sent either by the host or by an RTA. - ** If it comes from the host, then we need to fill in the - ** Topology array in the host structure. If it came in - ** from an RTA then we need to fill in the Mapping structure's - ** Topology array for the unit. - */ - if (Rup >= (unsigned short) MAX_RUP) { - ThisUnit = HOST_ID; - TopP = HostP->Topology; - MyType = "Host"; - MyName = HostP->Name; - ThisLinkMin = ThisLinkMax = Rup - MAX_RUP; - } else { - ThisUnit = Rup + 1; - TopP = HostP->Mapping[Rup].Topology; - MyType = "RTA"; - MyName = HostP->Mapping[Rup].Name; - ThisLinkMin = 0; - ThisLinkMax = LINKS_PER_UNIT - 1; - } - - /* - ** Lies will not be tolerated. - ** If any pair of links claim to be connected to the same - ** place, then ignore this packet completely. - */ - Lies = 0; - for (ThisLink = ThisLinkMin + 1; ThisLink <= ThisLinkMax; ThisLink++) { - /* - ** it won't lie about network interconnect, total disconnects - ** and no-IDs. (or at least, it doesn't *matter* if it does) - */ - if (readb(&PktCmdP->RouteTopology[ThisLink].Unit) > (unsigned short) MAX_RUP) - continue; - - for (NewLink = ThisLinkMin; NewLink < ThisLink; NewLink++) { - if ((readb(&PktCmdP->RouteTopology[ThisLink].Unit) == readb(&PktCmdP->RouteTopology[NewLink].Unit)) && (readb(&PktCmdP->RouteTopology[ThisLink].Link) == readb(&PktCmdP->RouteTopology[NewLink].Link))) { - Lies++; - } - } - } - - if (Lies) { - rio_dprintk(RIO_DEBUG_ROUTE, "LIES! DAMN LIES! %d LIES!\n", Lies); - rio_dprintk(RIO_DEBUG_ROUTE, "%d:%c %d:%c %d:%c %d:%c\n", - readb(&PktCmdP->RouteTopology[0].Unit), - 'A' + readb(&PktCmdP->RouteTopology[0].Link), - readb(&PktCmdP->RouteTopology[1].Unit), - 'A' + readb(&PktCmdP->RouteTopology[1].Link), readb(&PktCmdP->RouteTopology[2].Unit), 'A' + readb(&PktCmdP->RouteTopology[2].Link), readb(&PktCmdP->RouteTopology[3].Unit), 'A' + readb(&PktCmdP->RouteTopology[3].Link)); - return 1; - } - - /* - ** now, process each link. - */ - for (ThisLink = ThisLinkMin; ThisLink <= ThisLinkMax; ThisLink++) { - /* - ** this is what it was connected to - */ - OldUnit = TopP[ThisLink].Unit; - OldLink = TopP[ThisLink].Link; - - /* - ** this is what it is now connected to - */ - NewUnit = readb(&PktCmdP->RouteTopology[ThisLink].Unit); - NewLink = readb(&PktCmdP->RouteTopology[ThisLink].Link); - - if (OldUnit != NewUnit || OldLink != NewLink) { - /* - ** something has changed! - */ - - if (NewUnit > MAX_RUP && NewUnit != ROUTE_DISCONNECT && NewUnit != ROUTE_NO_ID && NewUnit != ROUTE_INTERCONNECT) { - rio_dprintk(RIO_DEBUG_ROUTE, "I have a link from %s %s to unit %d:%d - I don't like it.\n", MyType, MyName, NewUnit, NewLink); - } else { - /* - ** put the new values in - */ - TopP[ThisLink].Unit = NewUnit; - TopP[ThisLink].Link = NewLink; - - RIOSetChange(p); - - if (OldUnit <= MAX_RUP) { - /* - ** If something has become bust, then re-enable them messages - */ - if (!p->RIONoMessage) - RIOConCon(p, HostP, ThisUnit, ThisLink, OldUnit, OldLink, DISCONNECT); - } - - if ((NewUnit <= MAX_RUP) && !p->RIONoMessage) - RIOConCon(p, HostP, ThisUnit, ThisLink, NewUnit, NewLink, CONNECT); - - if (NewUnit == ROUTE_NO_ID) - rio_dprintk(RIO_DEBUG_ROUTE, "%s %s (%c) is connected to an unconfigured unit.\n", MyType, MyName, 'A' + ThisLink); - - if (NewUnit == ROUTE_INTERCONNECT) { - if (!p->RIONoMessage) - printk(KERN_DEBUG "rio: %s '%s' (%c) is connected to another network.\n", MyType, MyName, 'A' + ThisLink); - } - - /* - ** perform an update for 'the other end', so that these messages - ** only appears once. Only disconnect the other end if it is pointing - ** at us! - */ - if (OldUnit == HOST_ID) { - if (HostP->Topology[OldLink].Unit == ThisUnit && HostP->Topology[OldLink].Link == ThisLink) { - rio_dprintk(RIO_DEBUG_ROUTE, "SETTING HOST (%c) TO DISCONNECTED!\n", OldLink + 'A'); - HostP->Topology[OldLink].Unit = ROUTE_DISCONNECT; - HostP->Topology[OldLink].Link = NO_LINK; - } else { - rio_dprintk(RIO_DEBUG_ROUTE, "HOST(%c) WAS NOT CONNECTED TO %s (%c)!\n", OldLink + 'A', HostP->Mapping[ThisUnit - 1].Name, ThisLink + 'A'); - } - } else if (OldUnit <= MAX_RUP) { - if (HostP->Mapping[OldUnit - 1].Topology[OldLink].Unit == ThisUnit && HostP->Mapping[OldUnit - 1].Topology[OldLink].Link == ThisLink) { - rio_dprintk(RIO_DEBUG_ROUTE, "SETTING RTA %s (%c) TO DISCONNECTED!\n", HostP->Mapping[OldUnit - 1].Name, OldLink + 'A'); - HostP->Mapping[OldUnit - 1].Topology[OldLink].Unit = ROUTE_DISCONNECT; - HostP->Mapping[OldUnit - 1].Topology[OldLink].Link = NO_LINK; - } else { - rio_dprintk(RIO_DEBUG_ROUTE, "RTA %s (%c) WAS NOT CONNECTED TO %s (%c)\n", HostP->Mapping[OldUnit - 1].Name, OldLink + 'A', HostP->Mapping[ThisUnit - 1].Name, ThisLink + 'A'); - } - } - if (NewUnit == HOST_ID) { - rio_dprintk(RIO_DEBUG_ROUTE, "MARKING HOST (%c) CONNECTED TO %s (%c)\n", NewLink + 'A', MyName, ThisLink + 'A'); - HostP->Topology[NewLink].Unit = ThisUnit; - HostP->Topology[NewLink].Link = ThisLink; - } else if (NewUnit <= MAX_RUP) { - rio_dprintk(RIO_DEBUG_ROUTE, "MARKING RTA %s (%c) CONNECTED TO %s (%c)\n", HostP->Mapping[NewUnit - 1].Name, NewLink + 'A', MyName, ThisLink + 'A'); - HostP->Mapping[NewUnit - 1].Topology[NewLink].Unit = ThisUnit; - HostP->Mapping[NewUnit - 1].Topology[NewLink].Link = ThisLink; - } - } - RIOSetChange(p); - RIOCheckIsolated(p, HostP, OldUnit); - } - } - return 1; - } - - /* - ** The only other command we recognise is a route_request command - */ - if (readb(&PktCmdP->Command) != ROUTE_REQUEST) { - rio_dprintk(RIO_DEBUG_ROUTE, "Unknown command %d received on rup %d host %p ROUTE_RUP\n", readb(&PktCmdP->Command), Rup, HostP); - return 1; - } - - RtaUniq = (readb(&PktCmdP->UniqNum[0])) + (readb(&PktCmdP->UniqNum[1]) << 8) + (readb(&PktCmdP->UniqNum[2]) << 16) + (readb(&PktCmdP->UniqNum[3]) << 24); - - /* - ** Determine if 8 or 16 port RTA - */ - RtaType = GetUnitType(RtaUniq); - - rio_dprintk(RIO_DEBUG_ROUTE, "Received a request for an ID for serial number %x\n", RtaUniq); - - Mod = readb(&PktCmdP->ModuleTypes); - Mod1 = LONYBLE(Mod); - if (RtaType == TYPE_RTA16) { - /* - ** Only one ident is set for a 16 port RTA. To make compatible - ** with 8 port, set 2nd ident in Mod2 to the same as Mod1. - */ - Mod2 = Mod1; - rio_dprintk(RIO_DEBUG_ROUTE, "Backplane type is %s (all ports)\n", p->RIOModuleTypes[Mod1].Name); - } else { - Mod2 = HINYBLE(Mod); - rio_dprintk(RIO_DEBUG_ROUTE, "Module types are %s (ports 0-3) and %s (ports 4-7)\n", p->RIOModuleTypes[Mod1].Name, p->RIOModuleTypes[Mod2].Name); - } - - /* - ** try to unhook a command block from the command free list. - */ - if (!(CmdBlkP = RIOGetCmdBlk())) { - rio_dprintk(RIO_DEBUG_ROUTE, "No command blocks to route RTA! come back later.\n"); - return 0; - } - - /* - ** Fill in the default info on the command block - */ - CmdBlkP->Packet.dest_unit = Rup; - CmdBlkP->Packet.dest_port = ROUTE_RUP; - CmdBlkP->Packet.src_unit = HOST_ID; - CmdBlkP->Packet.src_port = ROUTE_RUP; - CmdBlkP->Packet.len = PKT_CMD_BIT | 1; - CmdBlkP->PreFuncP = CmdBlkP->PostFuncP = NULL; - PktReplyP = (struct PktCmd_M *) CmdBlkP->Packet.data; - - if (!RIOBootOk(p, HostP, RtaUniq)) { - rio_dprintk(RIO_DEBUG_ROUTE, "RTA %x tried to get an ID, but does not belong - FOAD it!\n", RtaUniq); - PktReplyP->Command = ROUTE_FOAD; - memcpy(PktReplyP->CommandText, "RT_FOAD", 7); - RIOQueueCmdBlk(HostP, Rup, CmdBlkP); - return 1; - } - - /* - ** Check to see if the RTA is configured for this host - */ - for (ThisUnit = 0; ThisUnit < MAX_RUP; ThisUnit++) { - rio_dprintk(RIO_DEBUG_ROUTE, "Entry %d Flags=%s %s UniqueNum=0x%x\n", - ThisUnit, HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE ? "Slot-In-Use" : "Not In Use", HostP->Mapping[ThisUnit].Flags & SLOT_TENTATIVE ? "Slot-Tentative" : "Not Tentative", HostP->Mapping[ThisUnit].RtaUniqueNum); - - /* - ** We have an entry for it. - */ - if ((HostP->Mapping[ThisUnit].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) && (HostP->Mapping[ThisUnit].RtaUniqueNum == RtaUniq)) { - if (RtaType == TYPE_RTA16) { - ThisUnit2 = HostP->Mapping[ThisUnit].ID2 - 1; - rio_dprintk(RIO_DEBUG_ROUTE, "Found unit 0x%x at slots %d+%d\n", RtaUniq, ThisUnit, ThisUnit2); - } else - rio_dprintk(RIO_DEBUG_ROUTE, "Found unit 0x%x at slot %d\n", RtaUniq, ThisUnit); - /* - ** If we have no knowledge of booting it, then the host has - ** been re-booted, and so we must kill the RTA, so that it - ** will be booted again (potentially with new bins) - ** and it will then re-ask for an ID, which we will service. - */ - if ((HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE) && !(HostP->Mapping[ThisUnit].Flags & RTA_BOOTED)) { - if (!(HostP->Mapping[ThisUnit].Flags & MSG_DONE)) { - if (!p->RIONoMessage) - printk(KERN_DEBUG "rio: RTA '%s' is being updated.\n", HostP->Mapping[ThisUnit].Name); - HostP->Mapping[ThisUnit].Flags |= MSG_DONE; - } - PktReplyP->Command = ROUTE_FOAD; - memcpy(PktReplyP->CommandText, "RT_FOAD", 7); - RIOQueueCmdBlk(HostP, Rup, CmdBlkP); - return 1; - } - - /* - ** Send the ID (entry) to this RTA. The ID number is implicit as - ** the offset into the table. It is worth noting at this stage - ** that offset zero in the table contains the entries for the - ** RTA with ID 1!!!! - */ - PktReplyP->Command = ROUTE_ALLOCATE; - PktReplyP->IDNum = ThisUnit + 1; - if (RtaType == TYPE_RTA16) { - if (HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE) - /* - ** Adjust the phb and tx pkt dest_units for 2nd block of 8 - ** only if the RTA has ports associated (SLOT_IN_USE) - */ - RIOFixPhbs(p, HostP, ThisUnit2); - PktReplyP->IDNum2 = ThisUnit2 + 1; - rio_dprintk(RIO_DEBUG_ROUTE, "RTA '%s' has been allocated IDs %d+%d\n", HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum, PktReplyP->IDNum2); - } else { - PktReplyP->IDNum2 = ROUTE_NO_ID; - rio_dprintk(RIO_DEBUG_ROUTE, "RTA '%s' has been allocated ID %d\n", HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum); - } - memcpy(PktReplyP->CommandText, "RT_ALLOCAT", 10); - - RIOQueueCmdBlk(HostP, Rup, CmdBlkP); - - /* - ** If this is a freshly booted RTA, then we need to re-open - ** the ports, if any where open, so that data may once more - ** flow around the system! - */ - if ((HostP->Mapping[ThisUnit].Flags & RTA_NEWBOOT) && (HostP->Mapping[ThisUnit].SysPort != NO_PORT)) { - /* - ** look at the ports associated with this beast and - ** see if any where open. If they was, then re-open - ** them, using the info from the tty flags. - */ - for (port = 0; port < PORTS_PER_RTA; port++) { - PortP = p->RIOPortp[port + HostP->Mapping[ThisUnit].SysPort]; - if (PortP->State & (RIO_MOPEN | RIO_LOPEN)) { - rio_dprintk(RIO_DEBUG_ROUTE, "Re-opened this port\n"); - rio_spin_lock_irqsave(&PortP->portSem, flags); - PortP->MagicFlags |= MAGIC_REBOOT; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - } - } - if (RtaType == TYPE_RTA16) { - for (port = 0; port < PORTS_PER_RTA; port++) { - PortP = p->RIOPortp[port + HostP->Mapping[ThisUnit2].SysPort]; - if (PortP->State & (RIO_MOPEN | RIO_LOPEN)) { - rio_dprintk(RIO_DEBUG_ROUTE, "Re-opened this port\n"); - rio_spin_lock_irqsave(&PortP->portSem, flags); - PortP->MagicFlags |= MAGIC_REBOOT; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - } - } - } - } - - /* - ** keep a copy of the module types! - */ - HostP->UnixRups[ThisUnit].ModTypes = Mod; - if (RtaType == TYPE_RTA16) - HostP->UnixRups[ThisUnit2].ModTypes = Mod; - - /* - ** If either of the modules on this unit is read-only or write-only - ** or none-xprint, then we need to transfer that info over to the - ** relevant ports. - */ - if (HostP->Mapping[ThisUnit].SysPort != NO_PORT) { - for (port = 0; port < PORTS_PER_MODULE; port++) { - p->RIOPortp[port + HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK; - p->RIOPortp[port + HostP->Mapping[ThisUnit].SysPort]->Config |= p->RIOModuleTypes[Mod1].Flags[port]; - p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK; - p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port]; - } - if (RtaType == TYPE_RTA16) { - for (port = 0; port < PORTS_PER_MODULE; port++) { - p->RIOPortp[port + HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK; - p->RIOPortp[port + HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod1].Flags[port]; - p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK; - p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port]; - } - } - } - - /* - ** Job done, get on with the interrupts! - */ - return 1; - } - } - /* - ** There is no table entry for this RTA at all. - ** - ** Lets check to see if we actually booted this unit - if not, - ** then we reset it and it will go round the loop of being booted - ** we can then worry about trying to fit it into the table. - */ - for (ThisUnit = 0; ThisUnit < HostP->NumExtraBooted; ThisUnit++) - if (HostP->ExtraUnits[ThisUnit] == RtaUniq) - break; - if (ThisUnit == HostP->NumExtraBooted && ThisUnit != MAX_EXTRA_UNITS) { - /* - ** if the unit wasn't in the table, and the table wasn't full, then - ** we reset the unit, because we didn't boot it. - ** However, if the table is full, it could be that we did boot - ** this unit, and so we won't reboot it, because it isn't really - ** all that disasterous to keep the old bins in most cases. This - ** is a rather tacky feature, but we are on the edge of reallity - ** here, because the implication is that someone has connected - ** 16+MAX_EXTRA_UNITS onto one host. - */ - static int UnknownMesgDone = 0; - - if (!UnknownMesgDone) { - if (!p->RIONoMessage) - printk(KERN_DEBUG "rio: One or more unknown RTAs are being updated.\n"); - UnknownMesgDone = 1; - } - - PktReplyP->Command = ROUTE_FOAD; - memcpy(PktReplyP->CommandText, "RT_FOAD", 7); - } else { - /* - ** we did boot it (as an extra), and there may now be a table - ** slot free (because of a delete), so we will try to make - ** a tentative entry for it, so that the configurator can see it - ** and fill in the details for us. - */ - if (RtaType == TYPE_RTA16) { - if (RIOFindFreeID(p, HostP, &ThisUnit, &ThisUnit2) == 0) { - RIODefaultName(p, HostP, ThisUnit); - rio_fill_host_slot(ThisUnit, ThisUnit2, RtaUniq, HostP); - } - } else { - if (RIOFindFreeID(p, HostP, &ThisUnit, NULL) == 0) { - RIODefaultName(p, HostP, ThisUnit); - rio_fill_host_slot(ThisUnit, 0, RtaUniq, HostP); - } - } - PktReplyP->Command = ROUTE_USED; - memcpy(PktReplyP->CommandText, "RT_USED", 7); - } - RIOQueueCmdBlk(HostP, Rup, CmdBlkP); - return 1; -} - - -void RIOFixPhbs(struct rio_info *p, struct Host *HostP, unsigned int unit) -{ - unsigned short link, port; - struct Port *PortP; - unsigned long flags; - int PortN = HostP->Mapping[unit].SysPort; - - rio_dprintk(RIO_DEBUG_ROUTE, "RIOFixPhbs unit %d sysport %d\n", unit, PortN); - - if (PortN != -1) { - unsigned short dest_unit = HostP->Mapping[unit].ID2; - - /* - ** Get the link number used for the 1st 8 phbs on this unit. - */ - PortP = p->RIOPortp[HostP->Mapping[dest_unit - 1].SysPort]; - - link = readw(&PortP->PhbP->link); - - for (port = 0; port < PORTS_PER_RTA; port++, PortN++) { - unsigned short dest_port = port + 8; - u16 __iomem *TxPktP; - struct PKT __iomem *Pkt; - - PortP = p->RIOPortp[PortN]; - - rio_spin_lock_irqsave(&PortP->portSem, flags); - /* - ** If RTA is not powered on, the tx packets will be - ** unset, so go no further. - */ - if (!PortP->TxStart) { - rio_dprintk(RIO_DEBUG_ROUTE, "Tx pkts not set up yet\n"); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - break; - } - - /* - ** For the second slot of a 16 port RTA, the driver needs to - ** sort out the phb to port mappings. The dest_unit for this - ** group of 8 phbs is set to the dest_unit of the accompanying - ** 8 port block. The dest_port of the second unit is set to - ** be in the range 8-15 (i.e. 8 is added). Thus, for a 16 port - ** RTA with IDs 5 and 6, traffic bound for port 6 of unit 6 - ** (being the second map ID) will be sent to dest_unit 5, port - ** 14. When this RTA is deleted, dest_unit for ID 6 will be - ** restored, and the dest_port will be reduced by 8. - ** Transmit packets also have a destination field which needs - ** adjusting in the same manner. - ** Note that the unit/port bytes in 'dest' are swapped. - ** We also need to adjust the phb and rup link numbers for the - ** second block of 8 ttys. - */ - for (TxPktP = PortP->TxStart; TxPktP <= PortP->TxEnd; TxPktP++) { - /* - ** *TxPktP is the pointer to the transmit packet on the host - ** card. This needs to be translated into a 32 bit pointer - ** so it can be accessed from the driver. - */ - Pkt = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(TxPktP)); - - /* - ** If the packet is used, reset it. - */ - Pkt = (struct PKT __iomem *) ((unsigned long) Pkt & ~PKT_IN_USE); - writeb(dest_unit, &Pkt->dest_unit); - writeb(dest_port, &Pkt->dest_port); - } - rio_dprintk(RIO_DEBUG_ROUTE, "phb dest: Old %x:%x New %x:%x\n", readw(&PortP->PhbP->destination) & 0xff, (readw(&PortP->PhbP->destination) >> 8) & 0xff, dest_unit, dest_port); - writew(dest_unit + (dest_port << 8), &PortP->PhbP->destination); - writew(link, &PortP->PhbP->link); - - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - } - /* - ** Now make sure the range of ports to be serviced includes - ** the 2nd 8 on this 16 port RTA. - */ - if (link > 3) - return; - if (((unit * 8) + 7) > readw(&HostP->LinkStrP[link].last_port)) { - rio_dprintk(RIO_DEBUG_ROUTE, "last port on host link %d: %d\n", link, (unit * 8) + 7); - writew((unit * 8) + 7, &HostP->LinkStrP[link].last_port); - } - } -} - -/* -** Check to see if the new disconnection has isolated this unit. -** If it has, then invalidate all its link information, and tell -** the world about it. This is done to ensure that the configurator -** only gets up-to-date information about what is going on. -*/ -static int RIOCheckIsolated(struct rio_info *p, struct Host *HostP, unsigned int UnitId) -{ - unsigned long flags; - rio_spin_lock_irqsave(&HostP->HostLock, flags); - - if (RIOCheck(HostP, UnitId)) { - rio_dprintk(RIO_DEBUG_ROUTE, "Unit %d is NOT isolated\n", UnitId); - rio_spin_unlock_irqrestore(&HostP->HostLock, flags); - return (0); - } - - RIOIsolate(p, HostP, UnitId); - RIOSetChange(p); - rio_spin_unlock_irqrestore(&HostP->HostLock, flags); - return 1; -} - -/* -** Invalidate all the link interconnectivity of this unit, and of -** all the units attached to it. This will mean that the entire -** subnet will re-introduce itself. -*/ -static int RIOIsolate(struct rio_info *p, struct Host *HostP, unsigned int UnitId) -{ - unsigned int link, unit; - - UnitId--; /* this trick relies on the Unit Id being UNSIGNED! */ - - if (UnitId >= MAX_RUP) /* dontcha just lurv unsigned maths! */ - return (0); - - if (HostP->Mapping[UnitId].Flags & BEEN_HERE) - return (0); - - HostP->Mapping[UnitId].Flags |= BEEN_HERE; - - if (p->RIOPrintDisabled == DO_PRINT) - rio_dprintk(RIO_DEBUG_ROUTE, "RIOMesgIsolated %s", HostP->Mapping[UnitId].Name); - - for (link = 0; link < LINKS_PER_UNIT; link++) { - unit = HostP->Mapping[UnitId].Topology[link].Unit; - HostP->Mapping[UnitId].Topology[link].Unit = ROUTE_DISCONNECT; - HostP->Mapping[UnitId].Topology[link].Link = NO_LINK; - RIOIsolate(p, HostP, unit); - } - HostP->Mapping[UnitId].Flags &= ~BEEN_HERE; - return 1; -} - -static int RIOCheck(struct Host *HostP, unsigned int UnitId) -{ - unsigned char link; - -/* rio_dprint(RIO_DEBUG_ROUTE, ("Check to see if unit %d has a route to the host\n",UnitId)); */ - rio_dprintk(RIO_DEBUG_ROUTE, "RIOCheck : UnitID = %d\n", UnitId); - - if (UnitId == HOST_ID) { - /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is NOT isolated - it IS the host!\n", UnitId)); */ - return 1; - } - - UnitId--; - - if (UnitId >= MAX_RUP) { - /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d - ignored.\n", UnitId)); */ - return 0; - } - - for (link = 0; link < LINKS_PER_UNIT; link++) { - if (HostP->Mapping[UnitId].Topology[link].Unit == HOST_ID) { - /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is connected directly to host via link (%c).\n", - UnitId, 'A'+link)); */ - return 1; - } - } - - if (HostP->Mapping[UnitId].Flags & BEEN_HERE) { - /* rio_dprint(RIO_DEBUG_ROUTE, ("Been to Unit %d before - ignoring\n", UnitId)); */ - return 0; - } - - HostP->Mapping[UnitId].Flags |= BEEN_HERE; - - for (link = 0; link < LINKS_PER_UNIT; link++) { - /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d check link (%c)\n", UnitId,'A'+link)); */ - if (RIOCheck(HostP, HostP->Mapping[UnitId].Topology[link].Unit)) { - /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is connected to something that knows the host via link (%c)\n", UnitId,link+'A')); */ - HostP->Mapping[UnitId].Flags &= ~BEEN_HERE; - return 1; - } - } - - HostP->Mapping[UnitId].Flags &= ~BEEN_HERE; - - /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d DOESNT KNOW THE HOST!\n", UnitId)); */ - - return 0; -} - -/* -** Returns the type of unit (host, 16/8 port RTA) -*/ - -unsigned int GetUnitType(unsigned int Uniq) -{ - switch ((Uniq >> 28) & 0xf) { - case RIO_AT: - case RIO_MCA: - case RIO_EISA: - case RIO_PCI: - rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: Host\n"); - return (TYPE_HOST); - case RIO_RTA_16: - rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: 16 port RTA\n"); - return (TYPE_RTA16); - case RIO_RTA: - rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: 8 port RTA\n"); - return (TYPE_RTA8); - default: - rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: Unrecognised\n"); - return (99); - } -} - -int RIOSetChange(struct rio_info *p) -{ - if (p->RIOQuickCheck != NOT_CHANGED) - return (0); - p->RIOQuickCheck = CHANGED; - if (p->RIOSignalProcess) { - rio_dprintk(RIO_DEBUG_ROUTE, "Send SIG-HUP"); - /* - psignal( RIOSignalProcess, SIGHUP ); - */ - } - return (0); -} - -static void RIOConCon(struct rio_info *p, - struct Host *HostP, - unsigned int FromId, - unsigned int FromLink, - unsigned int ToId, - unsigned int ToLink, - int Change) -{ - char *FromName; - char *FromType; - char *ToName; - char *ToType; - unsigned int tp; - -/* -** 15.10.1998 ARG - ESIL 0759 -** (Part) fix for port being trashed when opened whilst RTA "disconnected" -** -** What's this doing in here anyway ? -** It was causing the port to be 'unmapped' if opened whilst RTA "disconnected" -** -** 09.12.1998 ARG - ESIL 0776 - part fix -** Okay, We've found out what this was all about now ! -** Someone had botched this to use RIOHalted to indicated the number of RTAs -** 'disconnected'. The value in RIOHalted was then being used in the -** 'RIO_QUICK_CHECK' ioctl. A none zero value indicating that a least one RTA -** is 'disconnected'. The change was put in to satisfy a customer's needs. -** Having taken this bit of code out 'RIO_QUICK_CHECK' now no longer works for -** the customer. -** - if (Change == CONNECT) { - if (p->RIOHalted) p->RIOHalted --; - } - else { - p->RIOHalted ++; - } -** -** So - we need to implement it slightly differently - a new member of the -** rio_info struct - RIORtaDisCons (RIO RTA connections) keeps track of RTA -** connections and disconnections. -*/ - if (Change == CONNECT) { - if (p->RIORtaDisCons) - p->RIORtaDisCons--; - } else { - p->RIORtaDisCons++; - } - - if (p->RIOPrintDisabled == DONT_PRINT) - return; - - if (FromId > ToId) { - tp = FromId; - FromId = ToId; - ToId = tp; - tp = FromLink; - FromLink = ToLink; - ToLink = tp; - } - - FromName = FromId ? HostP->Mapping[FromId - 1].Name : HostP->Name; - FromType = FromId ? "RTA" : "HOST"; - ToName = ToId ? HostP->Mapping[ToId - 1].Name : HostP->Name; - ToType = ToId ? "RTA" : "HOST"; - - rio_dprintk(RIO_DEBUG_ROUTE, "Link between %s '%s' (%c) and %s '%s' (%c) %s.\n", FromType, FromName, 'A' + FromLink, ToType, ToName, 'A' + ToLink, (Change == CONNECT) ? "established" : "disconnected"); - printk(KERN_DEBUG "rio: Link between %s '%s' (%c) and %s '%s' (%c) %s.\n", FromType, FromName, 'A' + FromLink, ToType, ToName, 'A' + ToLink, (Change == CONNECT) ? "established" : "disconnected"); -} - -/* -** RIORemoveFromSavedTable : -** -** Delete and RTA entry from the saved table given to us -** by the configuration program. -*/ -static int RIORemoveFromSavedTable(struct rio_info *p, struct Map *pMap) -{ - int entry; - - /* - ** We loop for all entries even after finding an entry and - ** zeroing it because we may have two entries to delete if - ** it's a 16 port RTA. - */ - for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) { - if (p->RIOSavedTable[entry].RtaUniqueNum == pMap->RtaUniqueNum) { - memset(&p->RIOSavedTable[entry], 0, sizeof(struct Map)); - } - } - return 0; -} - - -/* -** RIOCheckDisconnected : -** -** Scan the unit links to and return zero if the unit is completely -** disconnected. -*/ -static int RIOFreeDisconnected(struct rio_info *p, struct Host *HostP, int unit) -{ - int link; - - - rio_dprintk(RIO_DEBUG_ROUTE, "RIOFreeDisconnect unit %d\n", unit); - /* - ** If the slot is tentative and does not belong to the - ** second half of a 16 port RTA then scan to see if - ** is disconnected. - */ - for (link = 0; link < LINKS_PER_UNIT; link++) { - if (HostP->Mapping[unit].Topology[link].Unit != ROUTE_DISCONNECT) - break; - } - - /* - ** If not all links are disconnected then we can forget about it. - */ - if (link < LINKS_PER_UNIT) - return 1; - -#ifdef NEED_TO_FIX_THIS - /* Ok so all the links are disconnected. But we may have only just - ** made this slot tentative and not yet received a topology update. - ** Lets check how long ago we made it tentative. - */ - rio_dprintk(RIO_DEBUG_ROUTE, "Just about to check LBOLT on entry %d\n", unit); - if (drv_getparm(LBOLT, (ulong_t *) & current_time)) - rio_dprintk(RIO_DEBUG_ROUTE, "drv_getparm(LBOLT,....) Failed.\n"); - - elapse_time = current_time - TentTime[unit]; - rio_dprintk(RIO_DEBUG_ROUTE, "elapse %d = current %d - tent %d (%d usec)\n", elapse_time, current_time, TentTime[unit], drv_hztousec(elapse_time)); - if (drv_hztousec(elapse_time) < WAIT_TO_FINISH) { - rio_dprintk(RIO_DEBUG_ROUTE, "Skipping slot %d, not timed out yet %d\n", unit, drv_hztousec(elapse_time)); - return 1; - } -#endif - - /* - ** We have found an usable slot. - ** If it is half of a 16 port RTA then delete the other half. - */ - if (HostP->Mapping[unit].ID2 != 0) { - int nOther = (HostP->Mapping[unit].ID2) - 1; - - rio_dprintk(RIO_DEBUG_ROUTE, "RioFreedis second slot %d.\n", nOther); - memset(&HostP->Mapping[nOther], 0, sizeof(struct Map)); - } - RIORemoveFromSavedTable(p, &HostP->Mapping[unit]); - - return 0; -} - - -/* -** RIOFindFreeID : -** -** This function scans the given host table for either one -** or two free unit ID's. -*/ - -int RIOFindFreeID(struct rio_info *p, struct Host *HostP, unsigned int * pID1, unsigned int * pID2) -{ - int unit, tempID; - - /* - ** Initialise the ID's to MAX_RUP. - ** We do this to make the loop for setting the ID's as simple as - ** possible. - */ - *pID1 = MAX_RUP; - if (pID2 != NULL) - *pID2 = MAX_RUP; - - /* - ** Scan all entries of the host mapping table for free slots. - ** We scan for free slots first and then if that is not successful - ** we start all over again looking for tentative slots we can re-use. - */ - for (unit = 0; unit < MAX_RUP; unit++) { - rio_dprintk(RIO_DEBUG_ROUTE, "Scanning unit %d\n", unit); - /* - ** If the flags are zero then the slot is empty. - */ - if (HostP->Mapping[unit].Flags == 0) { - rio_dprintk(RIO_DEBUG_ROUTE, " This slot is empty.\n"); - /* - ** If we haven't allocated the first ID then do it now. - */ - if (*pID1 == MAX_RUP) { - rio_dprintk(RIO_DEBUG_ROUTE, "Make tentative entry for first unit %d\n", unit); - *pID1 = unit; - - /* - ** If the second ID is not needed then we can return - ** now. - */ - if (pID2 == NULL) - return 0; - } else { - /* - ** Allocate the second slot and return. - */ - rio_dprintk(RIO_DEBUG_ROUTE, "Make tentative entry for second unit %d\n", unit); - *pID2 = unit; - return 0; - } - } - } - - /* - ** If we manage to come out of the free slot loop then we - ** need to start all over again looking for tentative slots - ** that we can re-use. - */ - rio_dprintk(RIO_DEBUG_ROUTE, "Starting to scan for tentative slots\n"); - for (unit = 0; unit < MAX_RUP; unit++) { - if (((HostP->Mapping[unit].Flags & SLOT_TENTATIVE) || (HostP->Mapping[unit].Flags == 0)) && !(HostP->Mapping[unit].Flags & RTA16_SECOND_SLOT)) { - rio_dprintk(RIO_DEBUG_ROUTE, " Slot %d looks promising.\n", unit); - - if (unit == *pID1) { - rio_dprintk(RIO_DEBUG_ROUTE, " No it isn't, its the 1st half\n"); - continue; - } - - /* - ** Slot is Tentative or Empty, but not a tentative second - ** slot of a 16 porter. - ** Attempt to free up this slot (and its parnter if - ** it is a 16 port slot. The second slot will become - ** empty after a call to RIOFreeDisconnected so thats why - ** we look for empty slots above as well). - */ - if (HostP->Mapping[unit].Flags != 0) - if (RIOFreeDisconnected(p, HostP, unit) != 0) - continue; - /* - ** If we haven't allocated the first ID then do it now. - */ - if (*pID1 == MAX_RUP) { - rio_dprintk(RIO_DEBUG_ROUTE, "Grab tentative entry for first unit %d\n", unit); - *pID1 = unit; - - /* - ** Clear out this slot now that we intend to use it. - */ - memset(&HostP->Mapping[unit], 0, sizeof(struct Map)); - - /* - ** If the second ID is not needed then we can return - ** now. - */ - if (pID2 == NULL) - return 0; - } else { - /* - ** Allocate the second slot and return. - */ - rio_dprintk(RIO_DEBUG_ROUTE, "Grab tentative/empty entry for second unit %d\n", unit); - *pID2 = unit; - - /* - ** Clear out this slot now that we intend to use it. - */ - memset(&HostP->Mapping[unit], 0, sizeof(struct Map)); - - /* At this point under the right(wrong?) conditions - ** we may have a first unit ID being higher than the - ** second unit ID. This is a bad idea if we are about - ** to fill the slots with a 16 port RTA. - ** Better check and swap them over. - */ - - if (*pID1 > *pID2) { - rio_dprintk(RIO_DEBUG_ROUTE, "Swapping IDS %d %d\n", *pID1, *pID2); - tempID = *pID1; - *pID1 = *pID2; - *pID2 = tempID; - } - return 0; - } - } - } - - /* - ** If we manage to get to the end of the second loop then we - ** can give up and return a failure. - */ - return 1; -} - - -/* -** The link switch scenario. -** -** Rta Wun (A) is connected to Tuw (A). -** The tables are all up to date, and the system is OK. -** -** If Wun (A) is now moved to Wun (B) before Wun (A) can -** become disconnected, then the follow happens: -** -** Tuw (A) spots the change of unit:link at the other end -** of its link and Tuw sends a topology packet reflecting -** the change: Tuw (A) now disconnected from Wun (A), and -** this is closely followed by a packet indicating that -** Tuw (A) is now connected to Wun (B). -** -** Wun (B) will spot that it has now become connected, and -** Wun will send a topology packet, which indicates that -** both Wun (A) and Wun (B) is connected to Tuw (A). -** -** Eventually Wun (A) realises that it is now disconnected -** and Wun will send out a topology packet indicating that -** Wun (A) is now disconnected. -*/ diff --git a/drivers/char/rio/riospace.h b/drivers/char/rio/riospace.h deleted file mode 100644 index ffb31d4332b9..000000000000 --- a/drivers/char/rio/riospace.h +++ /dev/null @@ -1,154 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : riospace.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:13 -** Retrieved : 11/6/98 11:34:22 -** -** ident @(#)riospace.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_riospace_h__ -#define __rio_riospace_h__ - -#define RIO_LOCATOR_LEN 16 -#define MAX_RIO_BOARDS 4 - -/* -** DONT change this file. At all. Unless you can rebuild the entire -** device driver, which you probably can't, then the rest of the -** driver won't see any changes you make here. So don't make any. -** In particular, it won't be able to see changes to RIO_SLOTS -*/ - -struct Conf { - char Locator[24]; - unsigned int StartupTime; - unsigned int SlowCook; - unsigned int IntrPollTime; - unsigned int BreakInterval; - unsigned int Timer; - unsigned int RtaLoadBase; - unsigned int HostLoadBase; - unsigned int XpHz; - unsigned int XpCps; - char *XpOn; - char *XpOff; - unsigned int MaxXpCps; - unsigned int MinXpCps; - unsigned int SpinCmds; - unsigned int FirstAddr; - unsigned int LastAddr; - unsigned int BufferSize; - unsigned int LowWater; - unsigned int LineLength; - unsigned int CmdTime; -}; - -/* -** Board types - these MUST correspond to product codes! -*/ -#define RIO_EMPTY 0x0 -#define RIO_EISA 0x3 -#define RIO_RTA_16 0x9 -#define RIO_AT 0xA -#define RIO_MCA 0xB -#define RIO_PCI 0xD -#define RIO_RTA 0xE - -/* -** Board data structure. This is used for configuration info -*/ -struct Brd { - unsigned char Type; /* RIO_EISA, RIO_MCA, RIO_AT, RIO_EMPTY... */ - unsigned char Ivec; /* POLLED or ivec number */ - unsigned char Mode; /* Control stuff, see below */ -}; - -struct Board { - char Locator[RIO_LOCATOR_LEN]; - int NumSlots; - struct Brd Boards[MAX_RIO_BOARDS]; -}; - -#define BOOT_FROM_LINK 0x00 -#define BOOT_FROM_RAM 0x01 -#define EXTERNAL_BUS_OFF 0x00 -#define EXTERNAL_BUS_ON 0x02 -#define INTERRUPT_DISABLE 0x00 -#define INTERRUPT_ENABLE 0x04 -#define BYTE_OPERATION 0x00 -#define WORD_OPERATION 0x08 -#define POLLED INTERRUPT_DISABLE -#define IRQ_15 (0x00 | INTERRUPT_ENABLE) -#define IRQ_12 (0x10 | INTERRUPT_ENABLE) -#define IRQ_11 (0x20 | INTERRUPT_ENABLE) -#define IRQ_9 (0x30 | INTERRUPT_ENABLE) -#define SLOW_LINKS 0x00 -#define FAST_LINKS 0x40 -#define SLOW_AT_BUS 0x00 -#define FAST_AT_BUS 0x80 -#define SLOW_PCI_TP 0x00 -#define FAST_PCI_TP 0x80 -/* -** Debug levels -*/ -#define DBG_NONE 0x00000000 - -#define DBG_INIT 0x00000001 -#define DBG_OPEN 0x00000002 -#define DBG_CLOSE 0x00000004 -#define DBG_IOCTL 0x00000008 - -#define DBG_READ 0x00000010 -#define DBG_WRITE 0x00000020 -#define DBG_INTR 0x00000040 -#define DBG_PROC 0x00000080 - -#define DBG_PARAM 0x00000100 -#define DBG_CMD 0x00000200 -#define DBG_XPRINT 0x00000400 -#define DBG_POLL 0x00000800 - -#define DBG_DAEMON 0x00001000 -#define DBG_FAIL 0x00002000 -#define DBG_MODEM 0x00004000 -#define DBG_LIST 0x00008000 - -#define DBG_ROUTE 0x00010000 -#define DBG_UTIL 0x00020000 -#define DBG_BOOT 0x00040000 -#define DBG_BUFFER 0x00080000 - -#define DBG_MON 0x00100000 -#define DBG_SPECIAL 0x00200000 -#define DBG_VPIX 0x00400000 -#define DBG_FLUSH 0x00800000 - -#define DBG_QENABLE 0x01000000 - -#define DBG_ALWAYS 0x80000000 - -#endif /* __rio_riospace_h__ */ diff --git a/drivers/char/rio/riotable.c b/drivers/char/rio/riotable.c deleted file mode 100644 index 3d15802dc0f3..000000000000 --- a/drivers/char/rio/riotable.c +++ /dev/null @@ -1,941 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : riotable.c -** SID : 1.2 -** Last Modified : 11/6/98 10:33:47 -** Retrieved : 11/6/98 10:33:50 -** -** ident @(#)riotable.c 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include - - -#include "linux_compat.h" -#include "rio_linux.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" -#include "cirrus.h" -#include "rioioctl.h" -#include "param.h" -#include "protsts.h" - -/* -** A configuration table has been loaded. It is now up to us -** to sort it out and use the information contained therein. -*/ -int RIONewTable(struct rio_info *p) -{ - int Host, Host1, Host2, NameIsUnique, Entry, SubEnt; - struct Map *MapP; - struct Map *HostMapP; - struct Host *HostP; - - char *cptr; - - /* - ** We have been sent a new table to install. We need to break - ** it down into little bits and spread it around a bit to see - ** what we have got. - */ - /* - ** Things to check: - ** (things marked 'xx' aren't checked any more!) - ** (1) That there are no booted Hosts/RTAs out there. - ** (2) That the names are properly formed - ** (3) That blank entries really are. - ** xx (4) That hosts mentioned in the table actually exist. xx - ** (5) That the IDs are unique (per host). - ** (6) That host IDs are zero - ** (7) That port numbers are valid - ** (8) That port numbers aren't duplicated - ** (9) That names aren't duplicated - ** xx (10) That hosts that actually exist are mentioned in the table. xx - */ - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(1)\n"); - if (p->RIOSystemUp) { /* (1) */ - p->RIOError.Error = HOST_HAS_ALREADY_BEEN_BOOTED; - return -EBUSY; - } - - p->RIOError.Error = NOTHING_WRONG_AT_ALL; - p->RIOError.Entry = -1; - p->RIOError.Other = -1; - - for (Entry = 0; Entry < TOTAL_MAP_ENTRIES; Entry++) { - MapP = &p->RIOConnectTable[Entry]; - if ((MapP->Flags & RTA16_SECOND_SLOT) == 0) { - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(2)\n"); - cptr = MapP->Name; /* (2) */ - cptr[MAX_NAME_LEN - 1] = '\0'; - if (cptr[0] == '\0') { - memcpy(MapP->Name, MapP->RtaUniqueNum ? "RTA NN" : "HOST NN", 8); - MapP->Name[5] = '0' + Entry / 10; - MapP->Name[6] = '0' + Entry % 10; - } - while (*cptr) { - if (*cptr < ' ' || *cptr > '~') { - p->RIOError.Error = BAD_CHARACTER_IN_NAME; - p->RIOError.Entry = Entry; - return -ENXIO; - } - cptr++; - } - } - - /* - ** If the entry saved was a tentative entry then just forget - ** about it. - */ - if (MapP->Flags & SLOT_TENTATIVE) { - MapP->HostUniqueNum = 0; - MapP->RtaUniqueNum = 0; - continue; - } - - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(3)\n"); - if (!MapP->RtaUniqueNum && !MapP->HostUniqueNum) { /* (3) */ - if (MapP->ID || MapP->SysPort || MapP->Flags) { - rio_dprintk(RIO_DEBUG_TABLE, "%s pretending to be empty but isn't\n", MapP->Name); - p->RIOError.Error = TABLE_ENTRY_ISNT_PROPERLY_NULL; - p->RIOError.Entry = Entry; - return -ENXIO; - } - rio_dprintk(RIO_DEBUG_TABLE, "!RIO: Daemon: test (3) passes\n"); - continue; - } - - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(4)\n"); - for (Host = 0; Host < p->RIONumHosts; Host++) { /* (4) */ - if (p->RIOHosts[Host].UniqueNum == MapP->HostUniqueNum) { - HostP = &p->RIOHosts[Host]; - /* - ** having done the lookup, we don't really want to do - ** it again, so hang the host number in a safe place - */ - MapP->Topology[0].Unit = Host; - break; - } - } - - if (Host >= p->RIONumHosts) { - rio_dprintk(RIO_DEBUG_TABLE, "RTA %s has unknown host unique number 0x%x\n", MapP->Name, MapP->HostUniqueNum); - MapP->HostUniqueNum = 0; - /* MapP->RtaUniqueNum = 0; */ - /* MapP->ID = 0; */ - /* MapP->Flags = 0; */ - /* MapP->SysPort = 0; */ - /* MapP->Name[0] = 0; */ - continue; - } - - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(5)\n"); - if (MapP->RtaUniqueNum) { /* (5) */ - if (!MapP->ID) { - rio_dprintk(RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an ID of zero!\n", MapP->Name); - p->RIOError.Error = ZERO_RTA_ID; - p->RIOError.Entry = Entry; - return -ENXIO; - } - if (MapP->ID > MAX_RUP) { - rio_dprintk(RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an invalid ID %d\n", MapP->Name, MapP->ID); - p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE; - p->RIOError.Entry = Entry; - return -ENXIO; - } - for (SubEnt = 0; SubEnt < Entry; SubEnt++) { - if (MapP->HostUniqueNum == p->RIOConnectTable[SubEnt].HostUniqueNum && MapP->ID == p->RIOConnectTable[SubEnt].ID) { - rio_dprintk(RIO_DEBUG_TABLE, "Dupl. ID number allocated to RTA %s and RTA %s\n", MapP->Name, p->RIOConnectTable[SubEnt].Name); - p->RIOError.Error = DUPLICATED_RTA_ID; - p->RIOError.Entry = Entry; - p->RIOError.Other = SubEnt; - return -ENXIO; - } - /* - ** If the RtaUniqueNum is the same, it may be looking at both - ** entries for a 16 port RTA, so check the ids - */ - if ((MapP->RtaUniqueNum == p->RIOConnectTable[SubEnt].RtaUniqueNum) - && (MapP->ID2 != p->RIOConnectTable[SubEnt].ID)) { - rio_dprintk(RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n", MapP->Name); - rio_dprintk(RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n", p->RIOConnectTable[SubEnt].Name); - p->RIOError.Error = DUPLICATE_UNIQUE_NUMBER; - p->RIOError.Entry = Entry; - p->RIOError.Other = SubEnt; - return -ENXIO; - } - } - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(7a)\n"); - /* (7a) */ - if ((MapP->SysPort != NO_PORT) && (MapP->SysPort % PORTS_PER_RTA)) { - rio_dprintk(RIO_DEBUG_TABLE, "TTY Port number %d-RTA %s is not a multiple of %d!\n", (int) MapP->SysPort, MapP->Name, PORTS_PER_RTA); - p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE; - p->RIOError.Entry = Entry; - return -ENXIO; - } - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(7b)\n"); - /* (7b) */ - if ((MapP->SysPort != NO_PORT) && (MapP->SysPort >= RIO_PORTS)) { - rio_dprintk(RIO_DEBUG_TABLE, "TTY Port number %d for RTA %s is too big\n", (int) MapP->SysPort, MapP->Name); - p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE; - p->RIOError.Entry = Entry; - return -ENXIO; - } - for (SubEnt = 0; SubEnt < Entry; SubEnt++) { - if (p->RIOConnectTable[SubEnt].Flags & RTA16_SECOND_SLOT) - continue; - if (p->RIOConnectTable[SubEnt].RtaUniqueNum) { - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(8)\n"); - /* (8) */ - if ((MapP->SysPort != NO_PORT) && (MapP->SysPort == p->RIOConnectTable[SubEnt].SysPort)) { - rio_dprintk(RIO_DEBUG_TABLE, "RTA %s:same TTY port # as RTA %s (%d)\n", MapP->Name, p->RIOConnectTable[SubEnt].Name, (int) MapP->SysPort); - p->RIOError.Error = TTY_NUMBER_IN_USE; - p->RIOError.Entry = Entry; - p->RIOError.Other = SubEnt; - return -ENXIO; - } - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(9)\n"); - if (strcmp(MapP->Name, p->RIOConnectTable[SubEnt].Name) == 0 && !(MapP->Flags & RTA16_SECOND_SLOT)) { /* (9) */ - rio_dprintk(RIO_DEBUG_TABLE, "RTA name %s used twice\n", MapP->Name); - p->RIOError.Error = NAME_USED_TWICE; - p->RIOError.Entry = Entry; - p->RIOError.Other = SubEnt; - return -ENXIO; - } - } - } - } else { /* (6) */ - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(6)\n"); - if (MapP->ID) { - rio_dprintk(RIO_DEBUG_TABLE, "RIO:HOST %s has been allocated ID that isn't zero!\n", MapP->Name); - p->RIOError.Error = HOST_ID_NOT_ZERO; - p->RIOError.Entry = Entry; - return -ENXIO; - } - if (MapP->SysPort != NO_PORT) { - rio_dprintk(RIO_DEBUG_TABLE, "RIO: HOST %s has been allocated port numbers!\n", MapP->Name); - p->RIOError.Error = HOST_SYSPORT_BAD; - p->RIOError.Entry = Entry; - return -ENXIO; - } - } - } - - /* - ** wow! if we get here then it's a goody! - */ - - /* - ** Zero the (old) entries for each host... - */ - for (Host = 0; Host < RIO_HOSTS; Host++) { - for (Entry = 0; Entry < MAX_RUP; Entry++) { - memset(&p->RIOHosts[Host].Mapping[Entry], 0, sizeof(struct Map)); - } - memset(&p->RIOHosts[Host].Name[0], 0, sizeof(p->RIOHosts[Host].Name)); - } - - /* - ** Copy in the new table entries - */ - for (Entry = 0; Entry < TOTAL_MAP_ENTRIES; Entry++) { - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: Copy table for Host entry %d\n", Entry); - MapP = &p->RIOConnectTable[Entry]; - - /* - ** Now, if it is an empty slot ignore it! - */ - if (MapP->HostUniqueNum == 0) - continue; - - /* - ** we saved the host number earlier, so grab it back - */ - HostP = &p->RIOHosts[MapP->Topology[0].Unit]; - - /* - ** If it is a host, then we only need to fill in the name field. - */ - if (MapP->ID == 0) { - rio_dprintk(RIO_DEBUG_TABLE, "Host entry found. Name %s\n", MapP->Name); - memcpy(HostP->Name, MapP->Name, MAX_NAME_LEN); - continue; - } - - /* - ** Its an RTA entry, so fill in the host mapping entries for it - ** and the port mapping entries. Notice that entry zero is for - ** ID one. - */ - HostMapP = &HostP->Mapping[MapP->ID - 1]; - - if (MapP->Flags & SLOT_IN_USE) { - rio_dprintk(RIO_DEBUG_TABLE, "Rta entry found. Name %s\n", MapP->Name); - /* - ** structure assign, then sort out the bits we shouldn't have done - */ - *HostMapP = *MapP; - - HostMapP->Flags = SLOT_IN_USE; - if (MapP->Flags & RTA16_SECOND_SLOT) - HostMapP->Flags |= RTA16_SECOND_SLOT; - - RIOReMapPorts(p, HostP, HostMapP); - } else { - rio_dprintk(RIO_DEBUG_TABLE, "TENTATIVE Rta entry found. Name %s\n", MapP->Name); - } - } - - for (Entry = 0; Entry < TOTAL_MAP_ENTRIES; Entry++) { - p->RIOSavedTable[Entry] = p->RIOConnectTable[Entry]; - } - - for (Host = 0; Host < p->RIONumHosts; Host++) { - for (SubEnt = 0; SubEnt < LINKS_PER_UNIT; SubEnt++) { - p->RIOHosts[Host].Topology[SubEnt].Unit = ROUTE_DISCONNECT; - p->RIOHosts[Host].Topology[SubEnt].Link = NO_LINK; - } - for (Entry = 0; Entry < MAX_RUP; Entry++) { - for (SubEnt = 0; SubEnt < LINKS_PER_UNIT; SubEnt++) { - p->RIOHosts[Host].Mapping[Entry].Topology[SubEnt].Unit = ROUTE_DISCONNECT; - p->RIOHosts[Host].Mapping[Entry].Topology[SubEnt].Link = NO_LINK; - } - } - if (!p->RIOHosts[Host].Name[0]) { - memcpy(p->RIOHosts[Host].Name, "HOST 1", 7); - p->RIOHosts[Host].Name[5] += Host; - } - /* - ** Check that default name assigned is unique. - */ - Host1 = Host; - NameIsUnique = 0; - while (!NameIsUnique) { - NameIsUnique = 1; - for (Host2 = 0; Host2 < p->RIONumHosts; Host2++) { - if (Host2 == Host) - continue; - if (strcmp(p->RIOHosts[Host].Name, p->RIOHosts[Host2].Name) - == 0) { - NameIsUnique = 0; - Host1++; - if (Host1 >= p->RIONumHosts) - Host1 = 0; - p->RIOHosts[Host].Name[5] = '1' + Host1; - } - } - } - /* - ** Rename host if name already used. - */ - if (Host1 != Host) { - rio_dprintk(RIO_DEBUG_TABLE, "Default name %s already used\n", p->RIOHosts[Host].Name); - memcpy(p->RIOHosts[Host].Name, "HOST 1", 7); - p->RIOHosts[Host].Name[5] += Host1; - } - rio_dprintk(RIO_DEBUG_TABLE, "Assigning default name %s\n", p->RIOHosts[Host].Name); - } - return 0; -} - -/* -** User process needs the config table - build it from first -** principles. -** -* FIXME: SMP locking -*/ -int RIOApel(struct rio_info *p) -{ - int Host; - int link; - int Rup; - int Next = 0; - struct Map *MapP; - struct Host *HostP; - unsigned long flags; - - rio_dprintk(RIO_DEBUG_TABLE, "Generating a table to return to config.rio\n"); - - memset(&p->RIOConnectTable[0], 0, sizeof(struct Map) * TOTAL_MAP_ENTRIES); - - for (Host = 0; Host < RIO_HOSTS; Host++) { - rio_dprintk(RIO_DEBUG_TABLE, "Processing host %d\n", Host); - HostP = &p->RIOHosts[Host]; - rio_spin_lock_irqsave(&HostP->HostLock, flags); - - MapP = &p->RIOConnectTable[Next++]; - MapP->HostUniqueNum = HostP->UniqueNum; - if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { - rio_spin_unlock_irqrestore(&HostP->HostLock, flags); - continue; - } - MapP->RtaUniqueNum = 0; - MapP->ID = 0; - MapP->Flags = SLOT_IN_USE; - MapP->SysPort = NO_PORT; - for (link = 0; link < LINKS_PER_UNIT; link++) - MapP->Topology[link] = HostP->Topology[link]; - memcpy(MapP->Name, HostP->Name, MAX_NAME_LEN); - for (Rup = 0; Rup < MAX_RUP; Rup++) { - if (HostP->Mapping[Rup].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) { - p->RIOConnectTable[Next] = HostP->Mapping[Rup]; - if (HostP->Mapping[Rup].Flags & SLOT_IN_USE) - p->RIOConnectTable[Next].Flags |= SLOT_IN_USE; - if (HostP->Mapping[Rup].Flags & SLOT_TENTATIVE) - p->RIOConnectTable[Next].Flags |= SLOT_TENTATIVE; - if (HostP->Mapping[Rup].Flags & RTA16_SECOND_SLOT) - p->RIOConnectTable[Next].Flags |= RTA16_SECOND_SLOT; - Next++; - } - } - rio_spin_unlock_irqrestore(&HostP->HostLock, flags); - } - return 0; -} - -/* -** config.rio has taken a dislike to one of the gross maps entries. -** if the entry is suitably inactive, then we can gob on it and remove -** it from the table. -*/ -int RIODeleteRta(struct rio_info *p, struct Map *MapP) -{ - int host, entry, port, link; - int SysPort; - struct Host *HostP; - struct Map *HostMapP; - struct Port *PortP; - int work_done = 0; - unsigned long lock_flags, sem_flags; - - rio_dprintk(RIO_DEBUG_TABLE, "Delete entry on host %x, rta %x\n", MapP->HostUniqueNum, MapP->RtaUniqueNum); - - for (host = 0; host < p->RIONumHosts; host++) { - HostP = &p->RIOHosts[host]; - - rio_spin_lock_irqsave(&HostP->HostLock, lock_flags); - - if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { - rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags); - continue; - } - - for (entry = 0; entry < MAX_RUP; entry++) { - if (MapP->RtaUniqueNum == HostP->Mapping[entry].RtaUniqueNum) { - HostMapP = &HostP->Mapping[entry]; - rio_dprintk(RIO_DEBUG_TABLE, "Found entry offset %d on host %s\n", entry, HostP->Name); - - /* - ** Check all four links of the unit are disconnected - */ - for (link = 0; link < LINKS_PER_UNIT; link++) { - if (HostMapP->Topology[link].Unit != ROUTE_DISCONNECT) { - rio_dprintk(RIO_DEBUG_TABLE, "Entry is in use and cannot be deleted!\n"); - p->RIOError.Error = UNIT_IS_IN_USE; - rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags); - return -EBUSY; - } - } - /* - ** Slot has been allocated, BUT not booted/routed/ - ** connected/selected or anything else-ed - */ - SysPort = HostMapP->SysPort; - - if (SysPort != NO_PORT) { - for (port = SysPort; port < SysPort + PORTS_PER_RTA; port++) { - PortP = p->RIOPortp[port]; - rio_dprintk(RIO_DEBUG_TABLE, "Unmap port\n"); - - rio_spin_lock_irqsave(&PortP->portSem, sem_flags); - - PortP->Mapped = 0; - - if (PortP->State & (RIO_MOPEN | RIO_LOPEN)) { - - rio_dprintk(RIO_DEBUG_TABLE, "Gob on port\n"); - PortP->TxBufferIn = PortP->TxBufferOut = 0; - /* What should I do - wakeup( &PortP->TxBufferIn ); - wakeup( &PortP->TxBufferOut); - */ - PortP->InUse = NOT_INUSE; - /* What should I do - wakeup( &PortP->InUse ); - signal(PortP->TtyP->t_pgrp,SIGKILL); - ttyflush(PortP->TtyP,(FREAD|FWRITE)); - */ - PortP->State |= RIO_CLOSING | RIO_DELETED; - } - - /* - ** For the second slot of a 16 port RTA, the - ** driver needs to reset the changes made to - ** the phb to port mappings in RIORouteRup. - */ - if (PortP->SecondBlock) { - u16 dest_unit = HostMapP->ID; - u16 dest_port = port - SysPort; - u16 __iomem *TxPktP; - struct PKT __iomem *Pkt; - - for (TxPktP = PortP->TxStart; TxPktP <= PortP->TxEnd; TxPktP++) { - /* - ** *TxPktP is the pointer to the - ** transmit packet on the host card. - ** This needs to be translated into - ** a 32 bit pointer so it can be - ** accessed from the driver. - */ - Pkt = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(&*TxPktP)); - rio_dprintk(RIO_DEBUG_TABLE, "Tx packet (%x) destination: Old %x:%x New %x:%x\n", readw(TxPktP), readb(&Pkt->dest_unit), readb(&Pkt->dest_port), dest_unit, dest_port); - writew(dest_unit, &Pkt->dest_unit); - writew(dest_port, &Pkt->dest_port); - } - rio_dprintk(RIO_DEBUG_TABLE, "Port %d phb destination: Old %x:%x New %x:%x\n", port, readb(&PortP->PhbP->destination) & 0xff, (readb(&PortP->PhbP->destination) >> 8) & 0xff, dest_unit, dest_port); - writew(dest_unit + (dest_port << 8), &PortP->PhbP->destination); - } - rio_spin_unlock_irqrestore(&PortP->portSem, sem_flags); - } - } - rio_dprintk(RIO_DEBUG_TABLE, "Entry nulled.\n"); - memset(HostMapP, 0, sizeof(struct Map)); - work_done++; - } - } - rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags); - } - - /* XXXXX lock me up */ - for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) { - if (p->RIOSavedTable[entry].RtaUniqueNum == MapP->RtaUniqueNum) { - memset(&p->RIOSavedTable[entry], 0, sizeof(struct Map)); - work_done++; - } - if (p->RIOConnectTable[entry].RtaUniqueNum == MapP->RtaUniqueNum) { - memset(&p->RIOConnectTable[entry], 0, sizeof(struct Map)); - work_done++; - } - } - if (work_done) - return 0; - - rio_dprintk(RIO_DEBUG_TABLE, "Couldn't find entry to be deleted\n"); - p->RIOError.Error = COULDNT_FIND_ENTRY; - return -ENXIO; -} - -int RIOAssignRta(struct rio_info *p, struct Map *MapP) -{ - int host; - struct Map *HostMapP; - char *sptr; - int link; - - - rio_dprintk(RIO_DEBUG_TABLE, "Assign entry on host %x, rta %x, ID %d, Sysport %d\n", MapP->HostUniqueNum, MapP->RtaUniqueNum, MapP->ID, (int) MapP->SysPort); - - if ((MapP->ID != (u16) - 1) && ((int) MapP->ID < (int) 1 || (int) MapP->ID > MAX_RUP)) { - rio_dprintk(RIO_DEBUG_TABLE, "Bad ID in map entry!\n"); - p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - if (MapP->RtaUniqueNum == 0) { - rio_dprintk(RIO_DEBUG_TABLE, "Rta Unique number zero!\n"); - p->RIOError.Error = RTA_UNIQUE_NUMBER_ZERO; - return -EINVAL; - } - if ((MapP->SysPort != NO_PORT) && (MapP->SysPort % PORTS_PER_RTA)) { - rio_dprintk(RIO_DEBUG_TABLE, "Port %d not multiple of %d!\n", (int) MapP->SysPort, PORTS_PER_RTA); - p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - if ((MapP->SysPort != NO_PORT) && (MapP->SysPort >= RIO_PORTS)) { - rio_dprintk(RIO_DEBUG_TABLE, "Port %d not valid!\n", (int) MapP->SysPort); - p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - - /* - ** Copy the name across to the map entry. - */ - MapP->Name[MAX_NAME_LEN - 1] = '\0'; - sptr = MapP->Name; - while (*sptr) { - if (*sptr < ' ' || *sptr > '~') { - rio_dprintk(RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n"); - p->RIOError.Error = BAD_CHARACTER_IN_NAME; - return -EINVAL; - } - sptr++; - } - - for (host = 0; host < p->RIONumHosts; host++) { - if (MapP->HostUniqueNum == p->RIOHosts[host].UniqueNum) { - if ((p->RIOHosts[host].Flags & RUN_STATE) != RC_RUNNING) { - p->RIOError.Error = HOST_NOT_RUNNING; - return -ENXIO; - } - - /* - ** Now we have a host we need to allocate an ID - ** if the entry does not already have one. - */ - if (MapP->ID == (u16) - 1) { - int nNewID; - - rio_dprintk(RIO_DEBUG_TABLE, "Attempting to get a new ID for rta \"%s\"\n", MapP->Name); - /* - ** The idea here is to allow RTA's to be assigned - ** before they actually appear on the network. - ** This allows the addition of RTA's without having - ** to plug them in. - ** What we do is: - ** - Find a free ID and allocate it to the RTA. - ** - If this map entry is the second half of a - ** 16 port entry then find the other half and - ** make sure the 2 cross reference each other. - */ - if (RIOFindFreeID(p, &p->RIOHosts[host], &nNewID, NULL) != 0) { - p->RIOError.Error = COULDNT_FIND_ENTRY; - return -EBUSY; - } - MapP->ID = (u16) nNewID + 1; - rio_dprintk(RIO_DEBUG_TABLE, "Allocated ID %d for this new RTA.\n", MapP->ID); - HostMapP = &p->RIOHosts[host].Mapping[nNewID]; - HostMapP->RtaUniqueNum = MapP->RtaUniqueNum; - HostMapP->HostUniqueNum = MapP->HostUniqueNum; - HostMapP->ID = MapP->ID; - for (link = 0; link < LINKS_PER_UNIT; link++) { - HostMapP->Topology[link].Unit = ROUTE_DISCONNECT; - HostMapP->Topology[link].Link = NO_LINK; - } - if (MapP->Flags & RTA16_SECOND_SLOT) { - int unit; - - for (unit = 0; unit < MAX_RUP; unit++) - if (p->RIOHosts[host].Mapping[unit].RtaUniqueNum == MapP->RtaUniqueNum) - break; - if (unit == MAX_RUP) { - p->RIOError.Error = COULDNT_FIND_ENTRY; - return -EBUSY; - } - HostMapP->Flags |= RTA16_SECOND_SLOT; - HostMapP->ID2 = MapP->ID2 = p->RIOHosts[host].Mapping[unit].ID; - p->RIOHosts[host].Mapping[unit].ID2 = MapP->ID; - rio_dprintk(RIO_DEBUG_TABLE, "Cross referenced id %d to ID %d.\n", MapP->ID, p->RIOHosts[host].Mapping[unit].ID); - } - } - - HostMapP = &p->RIOHosts[host].Mapping[MapP->ID - 1]; - - if (HostMapP->Flags & SLOT_IN_USE) { - rio_dprintk(RIO_DEBUG_TABLE, "Map table slot for ID %d is already in use.\n", MapP->ID); - p->RIOError.Error = ID_ALREADY_IN_USE; - return -EBUSY; - } - - /* - ** Assign the sys ports and the name, and mark the slot as - ** being in use. - */ - HostMapP->SysPort = MapP->SysPort; - if ((MapP->Flags & RTA16_SECOND_SLOT) == 0) - memcpy(HostMapP->Name, MapP->Name, MAX_NAME_LEN); - HostMapP->Flags = SLOT_IN_USE | RTA_BOOTED; -#ifdef NEED_TO_FIX - RIO_SV_BROADCAST(p->RIOHosts[host].svFlags[MapP->ID - 1]); -#endif - if (MapP->Flags & RTA16_SECOND_SLOT) - HostMapP->Flags |= RTA16_SECOND_SLOT; - - RIOReMapPorts(p, &p->RIOHosts[host], HostMapP); - /* - ** Adjust 2nd block of 8 phbs - */ - if (MapP->Flags & RTA16_SECOND_SLOT) - RIOFixPhbs(p, &p->RIOHosts[host], HostMapP->ID - 1); - - if (HostMapP->SysPort != NO_PORT) { - if (HostMapP->SysPort < p->RIOFirstPortsBooted) - p->RIOFirstPortsBooted = HostMapP->SysPort; - if (HostMapP->SysPort > p->RIOLastPortsBooted) - p->RIOLastPortsBooted = HostMapP->SysPort; - } - if (MapP->Flags & RTA16_SECOND_SLOT) - rio_dprintk(RIO_DEBUG_TABLE, "Second map of RTA %s added to configuration\n", p->RIOHosts[host].Mapping[MapP->ID2 - 1].Name); - else - rio_dprintk(RIO_DEBUG_TABLE, "RTA %s added to configuration\n", MapP->Name); - return 0; - } - } - p->RIOError.Error = UNKNOWN_HOST_NUMBER; - rio_dprintk(RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum); - return -ENXIO; -} - - -int RIOReMapPorts(struct rio_info *p, struct Host *HostP, struct Map *HostMapP) -{ - struct Port *PortP; - unsigned int SubEnt; - unsigned int HostPort; - unsigned int SysPort; - u16 RtaType; - unsigned long flags; - - rio_dprintk(RIO_DEBUG_TABLE, "Mapping sysport %d to id %d\n", (int) HostMapP->SysPort, HostMapP->ID); - - /* - ** We need to tell the UnixRups which sysport the rup corresponds to - */ - HostP->UnixRups[HostMapP->ID - 1].BaseSysPort = HostMapP->SysPort; - - if (HostMapP->SysPort == NO_PORT) - return (0); - - RtaType = GetUnitType(HostMapP->RtaUniqueNum); - rio_dprintk(RIO_DEBUG_TABLE, "Mapping sysport %d-%d\n", (int) HostMapP->SysPort, (int) HostMapP->SysPort + PORTS_PER_RTA - 1); - - /* - ** now map each of its eight ports - */ - for (SubEnt = 0; SubEnt < PORTS_PER_RTA; SubEnt++) { - rio_dprintk(RIO_DEBUG_TABLE, "subent = %d, HostMapP->SysPort = %d\n", SubEnt, (int) HostMapP->SysPort); - SysPort = HostMapP->SysPort + SubEnt; /* portnumber within system */ - /* portnumber on host */ - - HostPort = (HostMapP->ID - 1) * PORTS_PER_RTA + SubEnt; - - rio_dprintk(RIO_DEBUG_TABLE, "c1 p = %p, p->rioPortp = %p\n", p, p->RIOPortp); - PortP = p->RIOPortp[SysPort]; - rio_dprintk(RIO_DEBUG_TABLE, "Map port\n"); - - /* - ** Point at all the real neat data structures - */ - rio_spin_lock_irqsave(&PortP->portSem, flags); - PortP->HostP = HostP; - PortP->Caddr = HostP->Caddr; - - /* - ** The PhbP cannot be filled in yet - ** unless the host has been booted - */ - if ((HostP->Flags & RUN_STATE) == RC_RUNNING) { - struct PHB __iomem *PhbP = PortP->PhbP = &HostP->PhbP[HostPort]; - PortP->TxAdd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_add)); - PortP->TxStart = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_start)); - PortP->TxEnd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_end)); - PortP->RxRemove = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_remove)); - PortP->RxStart = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_start)); - PortP->RxEnd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_end)); - } else - PortP->PhbP = NULL; - - /* - ** port related flags - */ - PortP->HostPort = HostPort; - /* - ** For each part of a 16 port RTA, RupNum is ID - 1. - */ - PortP->RupNum = HostMapP->ID - 1; - if (HostMapP->Flags & RTA16_SECOND_SLOT) { - PortP->ID2 = HostMapP->ID2 - 1; - PortP->SecondBlock = 1; - } else { - PortP->ID2 = 0; - PortP->SecondBlock = 0; - } - PortP->RtaUniqueNum = HostMapP->RtaUniqueNum; - - /* - ** If the port was already mapped then thats all we need to do. - */ - if (PortP->Mapped) { - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - continue; - } else - HostMapP->Flags &= ~RTA_NEWBOOT; - - PortP->State = 0; - PortP->Config = 0; - /* - ** Check out the module type - if it is special (read only etc.) - ** then we need to set flags in the PortP->Config. - ** Note: For 16 port RTA, all ports are of the same type. - */ - if (RtaType == TYPE_RTA16) { - PortP->Config |= p->RIOModuleTypes[HostP->UnixRups[HostMapP->ID - 1].ModTypes].Flags[SubEnt % PORTS_PER_MODULE]; - } else { - if (SubEnt < PORTS_PER_MODULE) - PortP->Config |= p->RIOModuleTypes[LONYBLE(HostP->UnixRups[HostMapP->ID - 1].ModTypes)].Flags[SubEnt % PORTS_PER_MODULE]; - else - PortP->Config |= p->RIOModuleTypes[HINYBLE(HostP->UnixRups[HostMapP->ID - 1].ModTypes)].Flags[SubEnt % PORTS_PER_MODULE]; - } - - /* - ** more port related flags - */ - PortP->PortState = 0; - PortP->ModemLines = 0; - PortP->ModemState = 0; - PortP->CookMode = COOK_WELL; - PortP->ParamSem = 0; - PortP->FlushCmdBodge = 0; - PortP->WflushFlag = 0; - PortP->MagicFlags = 0; - PortP->Lock = 0; - PortP->Store = 0; - PortP->FirstOpen = 1; - - /* - ** Buffers 'n things - */ - PortP->RxDataStart = 0; - PortP->Cor2Copy = 0; - PortP->Name = &HostMapP->Name[0]; - PortP->statsGather = 0; - PortP->txchars = 0; - PortP->rxchars = 0; - PortP->opens = 0; - PortP->closes = 0; - PortP->ioctls = 0; - if (PortP->TxRingBuffer) - memset(PortP->TxRingBuffer, 0, p->RIOBufferSize); - else if (p->RIOBufferSize) { - PortP->TxRingBuffer = kzalloc(p->RIOBufferSize, GFP_KERNEL); - } - PortP->TxBufferOut = 0; - PortP->TxBufferIn = 0; - PortP->Debug = 0; - /* - ** LastRxTgl stores the state of the rx toggle bit for this - ** port, to be compared with the state of the next pkt received. - ** If the same, we have received the same rx pkt from the RTA - ** twice. Initialise to a value not equal to PHB_RX_TGL or 0. - */ - PortP->LastRxTgl = ~(u8) PHB_RX_TGL; - - /* - ** and mark the port as usable - */ - PortP->Mapped = 1; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - } - if (HostMapP->SysPort < p->RIOFirstPortsMapped) - p->RIOFirstPortsMapped = HostMapP->SysPort; - if (HostMapP->SysPort > p->RIOLastPortsMapped) - p->RIOLastPortsMapped = HostMapP->SysPort; - - return 0; -} - -int RIOChangeName(struct rio_info *p, struct Map *MapP) -{ - int host; - struct Map *HostMapP; - char *sptr; - - rio_dprintk(RIO_DEBUG_TABLE, "Change name entry on host %x, rta %x, ID %d, Sysport %d\n", MapP->HostUniqueNum, MapP->RtaUniqueNum, MapP->ID, (int) MapP->SysPort); - - if (MapP->ID > MAX_RUP) { - rio_dprintk(RIO_DEBUG_TABLE, "Bad ID in map entry!\n"); - p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - - MapP->Name[MAX_NAME_LEN - 1] = '\0'; - sptr = MapP->Name; - - while (*sptr) { - if (*sptr < ' ' || *sptr > '~') { - rio_dprintk(RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n"); - p->RIOError.Error = BAD_CHARACTER_IN_NAME; - return -EINVAL; - } - sptr++; - } - - for (host = 0; host < p->RIONumHosts; host++) { - if (MapP->HostUniqueNum == p->RIOHosts[host].UniqueNum) { - if ((p->RIOHosts[host].Flags & RUN_STATE) != RC_RUNNING) { - p->RIOError.Error = HOST_NOT_RUNNING; - return -ENXIO; - } - if (MapP->ID == 0) { - memcpy(p->RIOHosts[host].Name, MapP->Name, MAX_NAME_LEN); - return 0; - } - - HostMapP = &p->RIOHosts[host].Mapping[MapP->ID - 1]; - - if (HostMapP->RtaUniqueNum != MapP->RtaUniqueNum) { - p->RIOError.Error = RTA_NUMBER_WRONG; - return -ENXIO; - } - memcpy(HostMapP->Name, MapP->Name, MAX_NAME_LEN); - return 0; - } - } - p->RIOError.Error = UNKNOWN_HOST_NUMBER; - rio_dprintk(RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum); - return -ENXIO; -} diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c deleted file mode 100644 index 8a90393faf3c..000000000000 --- a/drivers/char/rio/riotty.c +++ /dev/null @@ -1,654 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : riotty.c -** SID : 1.3 -** Last Modified : 11/6/98 10:33:47 -** Retrieved : 11/6/98 10:33:50 -** -** ident @(#)riotty.c 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#define __EXPLICIT_DEF_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include - - -#include "linux_compat.h" -#include "rio_linux.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" -#include "cirrus.h" -#include "rioioctl.h" -#include "param.h" - -static void RIOClearUp(struct Port *PortP); - -/* Below belongs in func.h */ -int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg); - - -extern struct rio_info *p; - - -int riotopen(struct tty_struct *tty, struct file *filp) -{ - unsigned int SysPort; - int repeat_this = 250; - struct Port *PortP; /* pointer to the port structure */ - unsigned long flags; - int retval = 0; - - func_enter(); - - /* Make sure driver_data is NULL in case the rio isn't booted jet. Else gs_close - is going to oops. - */ - tty->driver_data = NULL; - - SysPort = rio_minor(tty); - - if (p->RIOFailed) { - rio_dprintk(RIO_DEBUG_TTY, "System initialisation failed\n"); - func_exit(); - return -ENXIO; - } - - rio_dprintk(RIO_DEBUG_TTY, "port open SysPort %d (mapped:%d)\n", SysPort, p->RIOPortp[SysPort]->Mapped); - - /* - ** Validate that we have received a legitimate request. - ** Currently, just check that we are opening a port on - ** a host card that actually exists, and that the port - ** has been mapped onto a host. - */ - if (SysPort >= RIO_PORTS) { /* out of range ? */ - rio_dprintk(RIO_DEBUG_TTY, "Illegal port number %d\n", SysPort); - func_exit(); - return -ENXIO; - } - - /* - ** Grab pointer to the port stucture - */ - PortP = p->RIOPortp[SysPort]; /* Get control struc */ - rio_dprintk(RIO_DEBUG_TTY, "PortP: %p\n", PortP); - if (!PortP->Mapped) { /* we aren't mapped yet! */ - /* - ** The system doesn't know which RTA this port - ** corresponds to. - */ - rio_dprintk(RIO_DEBUG_TTY, "port not mapped into system\n"); - func_exit(); - return -ENXIO; - } - - tty->driver_data = PortP; - - PortP->gs.port.tty = tty; - PortP->gs.port.count++; - - rio_dprintk(RIO_DEBUG_TTY, "%d bytes in tx buffer\n", PortP->gs.xmit_cnt); - - retval = gs_init_port(&PortP->gs); - if (retval) { - PortP->gs.port.count--; - return -ENXIO; - } - /* - ** If the host hasn't been booted yet, then - ** fail - */ - if ((PortP->HostP->Flags & RUN_STATE) != RC_RUNNING) { - rio_dprintk(RIO_DEBUG_TTY, "Host not running\n"); - func_exit(); - return -ENXIO; - } - - /* - ** If the RTA has not booted yet and the user has choosen to block - ** until the RTA is present then we must spin here waiting for - ** the RTA to boot. - */ - /* I find the above code a bit hairy. I find the below code - easier to read and shorter. Now, if it works too that would - be great... -- REW - */ - rio_dprintk(RIO_DEBUG_TTY, "Checking if RTA has booted... \n"); - while (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) { - if (!PortP->WaitUntilBooted) { - rio_dprintk(RIO_DEBUG_TTY, "RTA never booted\n"); - func_exit(); - return -ENXIO; - } - - /* Under Linux you'd normally use a wait instead of this - busy-waiting. I'll stick with the old implementation for - now. --REW - */ - if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_TTY, "RTA_wait_for_boot: EINTR in delay \n"); - func_exit(); - return -EINTR; - } - if (repeat_this-- <= 0) { - rio_dprintk(RIO_DEBUG_TTY, "Waiting for RTA to boot timeout\n"); - func_exit(); - return -EIO; - } - } - rio_dprintk(RIO_DEBUG_TTY, "RTA has been booted\n"); - rio_spin_lock_irqsave(&PortP->portSem, flags); - if (p->RIOHalted) { - goto bombout; - } - - /* - ** If the port is in the final throws of being closed, - ** we should wait here (politely), waiting - ** for it to finish, so that it doesn't close us! - */ - while ((PortP->State & RIO_CLOSING) && !p->RIOHalted) { - rio_dprintk(RIO_DEBUG_TTY, "Waiting for RIO_CLOSING to go away\n"); - if (repeat_this-- <= 0) { - rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n"); - RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); - retval = -EINTR; - goto bombout; - } - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { - rio_spin_lock_irqsave(&PortP->portSem, flags); - retval = -EINTR; - goto bombout; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - } - - if (!PortP->Mapped) { - rio_dprintk(RIO_DEBUG_TTY, "Port unmapped while closing!\n"); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - retval = -ENXIO; - func_exit(); - return retval; - } - - if (p->RIOHalted) { - goto bombout; - } - -/* -** 15.10.1998 ARG - ESIL 0761 part fix -** RIO has it's own CTSFLOW and RTSFLOW flags in 'Config' in the port structure, -** we need to make sure that the flags are clear when the port is opened. -*/ - /* Uh? Suppose I turn these on and then another process opens - the port again? The flags get cleared! Not good. -- REW */ - if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) { - PortP->Config &= ~(RIO_CTSFLOW | RIO_RTSFLOW); - } - - if (!(PortP->firstOpen)) { /* First time ? */ - rio_dprintk(RIO_DEBUG_TTY, "First open for this port\n"); - - - PortP->firstOpen++; - PortP->CookMode = 0; /* XXX RIOCookMode(tp); */ - PortP->InUse = NOT_INUSE; - - /* Tentative fix for bug PR27. Didn't work. */ - /* PortP->gs.xmit_cnt = 0; */ - - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - - /* Someone explain to me why this delay/config is - here. If I read the docs correctly the "open" - command piggybacks the parameters immediately. - -- REW */ - RIOParam(PortP, RIOC_OPEN, 1, OK_TO_SLEEP); /* Open the port */ - rio_spin_lock_irqsave(&PortP->portSem, flags); - - /* - ** wait for the port to be not closed. - */ - while (!(PortP->PortState & PORT_ISOPEN) && !p->RIOHalted) { - rio_dprintk(RIO_DEBUG_TTY, "Waiting for PORT_ISOPEN-currently %x\n", PortP->PortState); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_TTY, "Waiting for open to finish broken by signal\n"); - RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); - func_exit(); - return -EINTR; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - } - - if (p->RIOHalted) { - retval = -EIO; - bombout: - /* RIOClearUp( PortP ); */ - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return retval; - } - rio_dprintk(RIO_DEBUG_TTY, "PORT_ISOPEN found\n"); - } - rio_dprintk(RIO_DEBUG_TTY, "Modem - test for carrier\n"); - /* - ** ACTION - ** insert test for carrier here. -- ??? - ** I already see that test here. What's the deal? -- REW - */ - if ((PortP->gs.port.tty->termios->c_cflag & CLOCAL) || - (PortP->ModemState & RIOC_MSVR1_CD)) { - rio_dprintk(RIO_DEBUG_TTY, "open(%d) Modem carr on\n", SysPort); - /* - tp->tm.c_state |= CARR_ON; - wakeup((caddr_t) &tp->tm.c_canq); - */ - PortP->State |= RIO_CARR_ON; - wake_up_interruptible(&PortP->gs.port.open_wait); - } else { /* no carrier - wait for DCD */ - /* - while (!(PortP->gs.port.tty->termios->c_state & CARR_ON) && - !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted ) - */ - while (!(PortP->State & RIO_CARR_ON) && !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted) { - rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr on\n", SysPort); - /* - PortP->gs.port.tty->termios->c_state |= WOPEN; - */ - PortP->State |= RIO_WOPEN; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { - rio_spin_lock_irqsave(&PortP->portSem, flags); - /* - ** ACTION: verify that this is a good thing - ** to do here. -- ??? - ** I think it's OK. -- REW - */ - rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr broken by signal\n", SysPort); - RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); - /* - tp->tm.c_state &= ~WOPEN; - */ - PortP->State &= ~RIO_WOPEN; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - func_exit(); - return -EINTR; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - } - PortP->State &= ~RIO_WOPEN; - } - if (p->RIOHalted) - goto bombout; - rio_dprintk(RIO_DEBUG_TTY, "Setting RIO_MOPEN\n"); - PortP->State |= RIO_MOPEN; - - if (p->RIOHalted) - goto bombout; - - rio_dprintk(RIO_DEBUG_TTY, "high level open done\n"); - - /* - ** Count opens for port statistics reporting - */ - if (PortP->statsGather) - PortP->opens++; - - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - rio_dprintk(RIO_DEBUG_TTY, "Returning from open\n"); - func_exit(); - return 0; -} - -/* -** RIOClose the port. -** The operating system thinks that this is last close for the device. -** As there are two interfaces to the port (Modem and tty), we need to -** check that both are closed before we close the device. -*/ -int riotclose(void *ptr) -{ - struct Port *PortP = ptr; /* pointer to the port structure */ - int deleted = 0; - int try = -1; /* Disable the timeouts by setting them to -1 */ - int repeat_this = -1; /* Congrats to those having 15 years of - uptime! (You get to break the driver.) */ - unsigned long end_time; - struct tty_struct *tty; - unsigned long flags; - int rv = 0; - - rio_dprintk(RIO_DEBUG_TTY, "port close SysPort %d\n", PortP->PortNum); - - /* PortP = p->RIOPortp[SysPort]; */ - rio_dprintk(RIO_DEBUG_TTY, "Port is at address %p\n", PortP); - /* tp = PortP->TtyP; *//* Get tty */ - tty = PortP->gs.port.tty; - rio_dprintk(RIO_DEBUG_TTY, "TTY is at address %p\n", tty); - - if (PortP->gs.closing_wait) - end_time = jiffies + PortP->gs.closing_wait; - else - end_time = jiffies + MAX_SCHEDULE_TIMEOUT; - - rio_spin_lock_irqsave(&PortP->portSem, flags); - - /* - ** Setting this flag will make any process trying to open - ** this port block until we are complete closing it. - */ - PortP->State |= RIO_CLOSING; - - if ((PortP->State & RIO_DELETED)) { - rio_dprintk(RIO_DEBUG_TTY, "Close on deleted RTA\n"); - deleted = 1; - } - - if (p->RIOHalted) { - RIOClearUp(PortP); - rv = -EIO; - goto close_end; - } - - rio_dprintk(RIO_DEBUG_TTY, "Clear bits\n"); - /* - ** clear the open bits for this device - */ - PortP->State &= ~RIO_MOPEN; - PortP->State &= ~RIO_CARR_ON; - PortP->ModemState &= ~RIOC_MSVR1_CD; - /* - ** If the device was open as both a Modem and a tty line - ** then we need to wimp out here, as the port has not really - ** been finally closed (gee, whizz!) The test here uses the - ** bit for the OTHER mode of operation, to see if THAT is - ** still active! - */ - if ((PortP->State & (RIO_LOPEN | RIO_MOPEN))) { - /* - ** The port is still open for the other task - - ** return, pretending that we are still active. - */ - rio_dprintk(RIO_DEBUG_TTY, "Channel %d still open !\n", PortP->PortNum); - PortP->State &= ~RIO_CLOSING; - if (PortP->firstOpen) - PortP->firstOpen--; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return -EIO; - } - - rio_dprintk(RIO_DEBUG_TTY, "Closing down - everything must go!\n"); - - PortP->State &= ~RIO_DYNOROD; - - /* - ** This is where we wait for the port - ** to drain down before closing. Bye-bye.... - ** (We never meant to do this) - */ - rio_dprintk(RIO_DEBUG_TTY, "Timeout 1 starts\n"); - - if (!deleted) - while ((PortP->InUse != NOT_INUSE) && !p->RIOHalted && (PortP->TxBufferIn != PortP->TxBufferOut)) { - if (repeat_this-- <= 0) { - rv = -EINTR; - rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n"); - RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); - goto close_end; - } - rio_dprintk(RIO_DEBUG_TTY, "Calling timeout to flush in closing\n"); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - if (RIODelay_ni(PortP, HUNDRED_MS * 10) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_TTY, "RTA EINTR in delay \n"); - rv = -EINTR; - rio_spin_lock_irqsave(&PortP->portSem, flags); - goto close_end; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - } - - PortP->TxBufferIn = PortP->TxBufferOut = 0; - repeat_this = 0xff; - - PortP->InUse = 0; - if ((PortP->State & (RIO_LOPEN | RIO_MOPEN))) { - /* - ** The port has been re-opened for the other task - - ** return, pretending that we are still active. - */ - rio_dprintk(RIO_DEBUG_TTY, "Channel %d re-open!\n", PortP->PortNum); - PortP->State &= ~RIO_CLOSING; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - if (PortP->firstOpen) - PortP->firstOpen--; - return -EIO; - } - - if (p->RIOHalted) { - RIOClearUp(PortP); - goto close_end; - } - - /* Can't call RIOShortCommand with the port locked. */ - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - - if (RIOShortCommand(p, PortP, RIOC_CLOSE, 1, 0) == RIO_FAIL) { - RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); - rio_spin_lock_irqsave(&PortP->portSem, flags); - goto close_end; - } - - if (!deleted) - while (try && (PortP->PortState & PORT_ISOPEN)) { - try--; - if (time_after(jiffies, end_time)) { - rio_dprintk(RIO_DEBUG_TTY, "Run out of tries - force the bugger shut!\n"); - RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); - break; - } - rio_dprintk(RIO_DEBUG_TTY, "Close: PortState:ISOPEN is %d\n", PortP->PortState & PORT_ISOPEN); - - if (p->RIOHalted) { - RIOClearUp(PortP); - rio_spin_lock_irqsave(&PortP->portSem, flags); - goto close_end; - } - if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_TTY, "RTA EINTR in delay \n"); - RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); - break; - } - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - rio_dprintk(RIO_DEBUG_TTY, "Close: try was %d on completion\n", try); - - /* RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); */ - -/* -** 15.10.1998 ARG - ESIL 0761 part fix -** RIO has it's own CTSFLOW and RTSFLOW flags in 'Config' in the port structure,** we need to make sure that the flags are clear when the port is opened. -*/ - PortP->Config &= ~(RIO_CTSFLOW | RIO_RTSFLOW); - - /* - ** Count opens for port statistics reporting - */ - if (PortP->statsGather) - PortP->closes++; - -close_end: - /* XXX: Why would a "DELETED" flag be reset here? I'd have - thought that a "deleted" flag means that the port was - permanently gone, but here we can make it reappear by it - being in close during the "deletion". - */ - PortP->State &= ~(RIO_CLOSING | RIO_DELETED); - if (PortP->firstOpen) - PortP->firstOpen--; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - rio_dprintk(RIO_DEBUG_TTY, "Return from close\n"); - return rv; -} - - - -static void RIOClearUp(struct Port *PortP) -{ - rio_dprintk(RIO_DEBUG_TTY, "RIOHalted set\n"); - PortP->Config = 0; /* Direct semaphore */ - PortP->PortState = 0; - PortP->firstOpen = 0; - PortP->FlushCmdBodge = 0; - PortP->ModemState = PortP->CookMode = 0; - PortP->Mapped = 0; - PortP->WflushFlag = 0; - PortP->MagicFlags = 0; - PortP->RxDataStart = 0; - PortP->TxBufferIn = 0; - PortP->TxBufferOut = 0; -} - -/* -** Put a command onto a port. -** The PortPointer, command, length and arg are passed. -** The len is the length *inclusive* of the command byte, -** and so for a command that takes no data, len==1. -** The arg is a single byte, and is only used if len==2. -** Other values of len aren't allowed, and will cause -** a panic. -*/ -int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg) -{ - struct PKT __iomem *PacketP; - int retries = 20; /* at 10 per second -> 2 seconds */ - unsigned long flags; - - rio_dprintk(RIO_DEBUG_TTY, "entering shortcommand.\n"); - - if (PortP->State & RIO_DELETED) { - rio_dprintk(RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n"); - return RIO_FAIL; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - - /* - ** If the port is in use for pre-emptive command, then wait for it to - ** be free again. - */ - while ((PortP->InUse != NOT_INUSE) && !p->RIOHalted) { - rio_dprintk(RIO_DEBUG_TTY, "Waiting for not in use (%d)\n", retries); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - if (retries-- <= 0) { - return RIO_FAIL; - } - if (RIODelay_ni(PortP, HUNDRED_MS) == RIO_FAIL) { - return RIO_FAIL; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - } - if (PortP->State & RIO_DELETED) { - rio_dprintk(RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n"); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return RIO_FAIL; - } - - while (!can_add_transmit(&PacketP, PortP) && !p->RIOHalted) { - rio_dprintk(RIO_DEBUG_TTY, "Waiting to add short command to queue (%d)\n", retries); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - if (retries-- <= 0) { - rio_dprintk(RIO_DEBUG_TTY, "out of tries. Failing\n"); - return RIO_FAIL; - } - if (RIODelay_ni(PortP, HUNDRED_MS) == RIO_FAIL) { - return RIO_FAIL; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - } - - if (p->RIOHalted) { - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return RIO_FAIL; - } - - /* - ** set the command byte and the argument byte - */ - writeb(command, &PacketP->data[0]); - - if (len == 2) - writeb(arg, &PacketP->data[1]); - - /* - ** set the length of the packet and set the command bit. - */ - writeb(PKT_CMD_BIT | len, &PacketP->len); - - add_transmit(PortP); - /* - ** Count characters transmitted for port statistics reporting - */ - if (PortP->statsGather) - PortP->txchars += len; - - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return p->RIOHalted ? RIO_FAIL : ~RIO_FAIL; -} - - diff --git a/drivers/char/rio/route.h b/drivers/char/rio/route.h deleted file mode 100644 index 46e963771c30..000000000000 --- a/drivers/char/rio/route.h +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** - ******* ******* - ******* R O U T E H E A D E R - ******* ******* - **************************************************************************** - - Author : Ian Nandhra / Jeremy Rolls - Date : - - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - Version : 0.01 - - - Mods - ---------------------------------------------------------------------------- - Date By Description - ---------------------------------------------------------------------------- - - ***************************************************************************/ - -#ifndef _route_h -#define _route_h - -#define MAX_LINKS 4 -#define MAX_NODES 17 /* Maximum nodes in a subnet */ -#define NODE_BYTES ((MAX_NODES / 8) + 1) /* Number of bytes needed for - 1 bit per node */ -#define ROUTE_DATA_SIZE (NODE_BYTES + 2) /* Number of bytes for complete - info about cost etc. */ -#define ROUTES_PER_PACKET ((PKT_MAX_DATA_LEN -2)/ ROUTE_DATA_SIZE) - /* Number of nodes we can squeeze - into one packet */ -#define MAX_TOPOLOGY_PACKETS (MAX_NODES / ROUTES_PER_PACKET + 1) -/************************************************ - * Define the types of command for the ROUTE RUP. - ************************************************/ -#define ROUTE_REQUEST 0 /* Request an ID */ -#define ROUTE_FOAD 1 /* Kill the RTA */ -#define ROUTE_ALREADY 2 /* ID given already */ -#define ROUTE_USED 3 /* All ID's used */ -#define ROUTE_ALLOCATE 4 /* Here it is */ -#define ROUTE_REQ_TOP 5 /* I bet you didn't expect.... - the Topological Inquisition */ -#define ROUTE_TOPOLOGY 6 /* Topology request answered FD */ -/******************************************************************* - * Define the Route Map Structure - * - * The route map gives a pointer to a Link Structure to use. - * This allows Disconnected Links to be checked quickly - ******************************************************************/ -typedef struct COST_ROUTE COST_ROUTE; -struct COST_ROUTE { - unsigned char cost; /* Cost down this link */ - unsigned char route[NODE_BYTES]; /* Nodes through this route */ -}; - -typedef struct ROUTE_STR ROUTE_STR; -struct ROUTE_STR { - COST_ROUTE cost_route[MAX_LINKS]; - /* cost / route for this link */ - ushort favoured; /* favoured link */ -}; - - -#define NO_LINK (short) 5 /* Link unattached */ -#define ROUTE_NO_ID (short) 100 /* No Id */ -#define ROUTE_DISCONNECT (ushort) 0xff /* Not connected */ -#define ROUTE_INTERCONNECT (ushort) 0x40 /* Sub-net interconnect */ - - -#define SYNC_RUP (ushort) 255 -#define COMMAND_RUP (ushort) 254 -#define ERROR_RUP (ushort) 253 -#define POLL_RUP (ushort) 252 -#define BOOT_RUP (ushort) 251 -#define ROUTE_RUP (ushort) 250 -#define STATUS_RUP (ushort) 249 -#define POWER_RUP (ushort) 248 - -#define HIGHEST_RUP (ushort) 255 /* Set to Top one */ -#define LOWEST_RUP (ushort) 248 /* Set to bottom one */ - -#endif - -/*********** end of file ***********/ diff --git a/drivers/char/rio/rup.h b/drivers/char/rio/rup.h deleted file mode 100644 index 4ae90cb207a9..000000000000 --- a/drivers/char/rio/rup.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** - ******* ******* - ******* R U P S T R U C T U R E - ******* ******* - **************************************************************************** - - Author : Ian Nandhra - Date : - - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - Version : 0.01 - - - Mods - ---------------------------------------------------------------------------- - Date By Description - ---------------------------------------------------------------------------- - - ***************************************************************************/ - -#ifndef _rup_h -#define _rup_h 1 - -#define MAX_RUP ((short) 16) -#define PKTS_PER_RUP ((short) 2) /* They are always used in pairs */ - -/************************************************* - * Define all the packet request stuff - ************************************************/ -#define TX_RUP_INACTIVE 0 /* Nothing to transmit */ -#define TX_PACKET_READY 1 /* Transmit packet ready */ -#define TX_LOCK_RUP 2 /* Transmit side locked */ - -#define RX_RUP_INACTIVE 0 /* Nothing received */ -#define RX_PACKET_READY 1 /* Packet received */ - -#define RUP_NO_OWNER 0xff /* RUP not owned by any process */ - -struct RUP { - u16 txpkt; /* Outgoing packet */ - u16 rxpkt; /* Incoming packet */ - u16 link; /* Which link to send down? */ - u8 rup_dest_unit[2]; /* Destination unit */ - u16 handshake; /* For handshaking */ - u16 timeout; /* Timeout */ - u16 status; /* Status */ - u16 txcontrol; /* Transmit control */ - u16 rxcontrol; /* Receive control */ -}; - -#endif - -/*********** end of file ***********/ diff --git a/drivers/char/rio/unixrup.h b/drivers/char/rio/unixrup.h deleted file mode 100644 index 7abf0cba0f2c..000000000000 --- a/drivers/char/rio/unixrup.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -** Module : unixrup.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:20 -** Retrieved : 11/6/98 11:34:22 -** -** ident @(#)unixrup.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_unixrup_h__ -#define __rio_unixrup_h__ - -/* -** UnixRup data structure. This contains pointers to actual RUPs on the -** host card, and all the command/boot control stuff. -*/ -struct UnixRup { - struct CmdBlk *CmdsWaitingP; /* Commands waiting to be done */ - struct CmdBlk *CmdPendingP; /* The command currently being sent */ - struct RUP __iomem *RupP; /* the Rup to send it to */ - unsigned int Id; /* Id number */ - unsigned int BaseSysPort; /* SysPort of first tty on this RTA */ - unsigned int ModTypes; /* Modules on this RTA */ - spinlock_t RupLock; /* Lock structure for MPX */ - /* struct lockb RupLock; *//* Lock structure for MPX */ -}; - -#endif /* __rio_unixrup_h__ */ diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c deleted file mode 100644 index 3f47c2ead8e5..000000000000 --- a/drivers/char/ser_a2232.c +++ /dev/null @@ -1,831 +0,0 @@ -/* drivers/char/ser_a2232.c */ - -/* $Id: ser_a2232.c,v 0.4 2000/01/25 12:00:00 ehaase Exp $ */ - -/* Linux serial driver for the Amiga A2232 board */ - -/* This driver is MAINTAINED. Before applying any changes, please contact - * the author. - */ - -/* Copyright (c) 2000-2001 Enver Haase - * alias The A2232 driver project - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -/***************************** Documentation ************************/ -/* - * This driver is in EXPERIMENTAL state. That means I could not find - * someone with five A2232 boards with 35 ports running at 19200 bps - * at the same time and test the machine's behaviour. - * However, I know that you can performance-tweak this driver (see - * the source code). - * One thing to consider is the time this driver consumes during the - * Amiga's vertical blank interrupt. Everything that is to be done - * _IS DONE_ when entering the vertical blank interrupt handler of - * this driver. - * However, it would be more sane to only do the job for only ONE card - * instead of ALL cards at a time; or, more generally, to handle only - * SOME ports instead of ALL ports at a time. - * However, as long as no-one runs into problems I guess I shouldn't - * change the driver as it runs fine for me :) . - * - * Version history of this file: - * 0.4 Resolved licensing issues. - * 0.3 Inclusion in the Linux/m68k tree, small fixes. - * 0.2 Added documentation, minor typo fixes. - * 0.1 Initial release. - * - * TO DO: - * - Handle incoming BREAK events. I guess "Stevens: Advanced - * Programming in the UNIX(R) Environment" is a good reference - * on what is to be done. - * - When installing as a module, don't simply 'printk' text, but - * send it to the TTY used by the user. - * - * THANKS TO: - * - Jukka Marin (65EC02 code). - * - The other NetBSD developers on whose A2232 driver I had a - * pretty close look. However, I didn't copy any code so it - * is okay to put my code under the GPL and include it into - * Linux. - */ -/***************************** End of Documentation *****************/ - -/***************************** Defines ******************************/ -/* - * Enables experimental 115200 (normal) 230400 (turbo) baud rate. - * The A2232 specification states it can only operate at speeds up to - * 19200 bits per second, and I was not able to send a file via - * "sz"/"rz" and a null-modem cable from one A2232 port to another - * at 115200 bits per second. - * However, this might work for you. - */ -#undef A2232_SPEEDHACK -/* - * Default is not to use RTS/CTS so you could be talked to death. - */ -#define A2232_SUPPRESS_RTSCTS_WARNING -/************************* End of Defines ***************************/ - -/***************************** Includes *****************************/ -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include "ser_a2232.h" -#include "ser_a2232fw.h" -/************************* End of Includes **************************/ - -/***************************** Prototypes ***************************/ -/* The interrupt service routine */ -static irqreturn_t a2232_vbl_inter(int irq, void *data); -/* Initialize the port structures */ -static void a2232_init_portstructs(void); -/* Initialize and register TTY drivers. */ -/* returns 0 IFF successful */ -static int a2232_init_drivers(void); - -/* BEGIN GENERIC_SERIAL PROTOTYPES */ -static void a2232_disable_tx_interrupts(void *ptr); -static void a2232_enable_tx_interrupts(void *ptr); -static void a2232_disable_rx_interrupts(void *ptr); -static void a2232_enable_rx_interrupts(void *ptr); -static int a2232_carrier_raised(struct tty_port *port); -static void a2232_shutdown_port(void *ptr); -static int a2232_set_real_termios(void *ptr); -static int a2232_chars_in_buffer(void *ptr); -static void a2232_close(void *ptr); -static void a2232_hungup(void *ptr); -/* static void a2232_getserial (void *ptr, struct serial_struct *sp); */ -/* END GENERIC_SERIAL PROTOTYPES */ - -/* Functions that the TTY driver struct expects */ -static int a2232_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); -static void a2232_throttle(struct tty_struct *tty); -static void a2232_unthrottle(struct tty_struct *tty); -static int a2232_open(struct tty_struct * tty, struct file * filp); -/************************* End of Prototypes ************************/ - -/***************************** Global variables *********************/ -/*--------------------------------------------------------------------------- - * Interface from generic_serial.c back here - *--------------------------------------------------------------------------*/ -static struct real_driver a2232_real_driver = { - a2232_disable_tx_interrupts, - a2232_enable_tx_interrupts, - a2232_disable_rx_interrupts, - a2232_enable_rx_interrupts, - a2232_shutdown_port, - a2232_set_real_termios, - a2232_chars_in_buffer, - a2232_close, - a2232_hungup, - NULL /* a2232_getserial */ -}; - -static void *a2232_driver_ID = &a2232_driver_ID; // Some memory address WE own. - -/* Ports structs */ -static struct a2232_port a2232_ports[MAX_A2232_BOARDS*NUMLINES]; - -/* TTY driver structs */ -static struct tty_driver *a2232_driver; - -/* nr of cards completely (all ports) and correctly configured */ -static int nr_a2232; - -/* zorro_dev structs for the A2232's */ -static struct zorro_dev *zd_a2232[MAX_A2232_BOARDS]; -/***************************** End of Global variables **************/ - -/* Helper functions */ - -static inline volatile struct a2232memory *a2232mem(unsigned int board) -{ - return (volatile struct a2232memory *)ZTWO_VADDR(zd_a2232[board]->resource.start); -} - -static inline volatile struct a2232status *a2232stat(unsigned int board, - unsigned int portonboard) -{ - volatile struct a2232memory *mem = a2232mem(board); - return &(mem->Status[portonboard]); -} - -static inline void a2232_receive_char(struct a2232_port *port, int ch, int err) -{ -/* Mostly stolen from other drivers. - Maybe one could implement a more efficient version by not only - transferring one character at a time. -*/ - struct tty_struct *tty = port->gs.port.tty; - -#if 0 - switch(err) { - case TTY_BREAK: - break; - case TTY_PARITY: - break; - case TTY_OVERRUN: - break; - case TTY_FRAME: - break; - } -#endif - - tty_insert_flip_char(tty, ch, err); - tty_flip_buffer_push(tty); -} - -/***************************** Functions ****************************/ -/*** BEGIN OF REAL_DRIVER FUNCTIONS ***/ - -static void a2232_disable_tx_interrupts(void *ptr) -{ - struct a2232_port *port; - volatile struct a2232status *stat; - unsigned long flags; - - port = ptr; - stat = a2232stat(port->which_a2232, port->which_port_on_a2232); - stat->OutDisable = -1; - - /* Does this here really have to be? */ - local_irq_save(flags); - port->gs.port.flags &= ~GS_TX_INTEN; - local_irq_restore(flags); -} - -static void a2232_enable_tx_interrupts(void *ptr) -{ - struct a2232_port *port; - volatile struct a2232status *stat; - unsigned long flags; - - port = ptr; - stat = a2232stat(port->which_a2232, port->which_port_on_a2232); - stat->OutDisable = 0; - - /* Does this here really have to be? */ - local_irq_save(flags); - port->gs.port.flags |= GS_TX_INTEN; - local_irq_restore(flags); -} - -static void a2232_disable_rx_interrupts(void *ptr) -{ - struct a2232_port *port; - port = ptr; - port->disable_rx = -1; -} - -static void a2232_enable_rx_interrupts(void *ptr) -{ - struct a2232_port *port; - port = ptr; - port->disable_rx = 0; -} - -static int a2232_carrier_raised(struct tty_port *port) -{ - struct a2232_port *ap = container_of(port, struct a2232_port, gs.port); - return ap->cd_status; -} - -static void a2232_shutdown_port(void *ptr) -{ - struct a2232_port *port; - volatile struct a2232status *stat; - unsigned long flags; - - port = ptr; - stat = a2232stat(port->which_a2232, port->which_port_on_a2232); - - local_irq_save(flags); - - port->gs.port.flags &= ~GS_ACTIVE; - - if (port->gs.port.tty && port->gs.port.tty->termios->c_cflag & HUPCL) { - /* Set DTR and RTS to Low, flush output. - The NetBSD driver "msc.c" does it this way. */ - stat->Command = ( (stat->Command & ~A2232CMD_CMask) | - A2232CMD_Close ); - stat->OutFlush = -1; - stat->Setup = -1; - } - - local_irq_restore(flags); - - /* After analyzing control flow, I think a2232_shutdown_port - is actually the last call from the system when at application - level someone issues a "echo Hello >>/dev/ttyY0". - Therefore I think the MOD_DEC_USE_COUNT should be here and - not in "a2232_close()". See the comment in "sx.c", too. - If you run into problems, compile this driver into the - kernel instead of compiling it as a module. */ -} - -static int a2232_set_real_termios(void *ptr) -{ - unsigned int cflag, baud, chsize, stopb, parity, softflow; - int rate; - int a2232_param, a2232_cmd; - unsigned long flags; - unsigned int i; - struct a2232_port *port = ptr; - volatile struct a2232status *status; - volatile struct a2232memory *mem; - - if (!port->gs.port.tty || !port->gs.port.tty->termios) return 0; - - status = a2232stat(port->which_a2232, port->which_port_on_a2232); - mem = a2232mem(port->which_a2232); - - a2232_param = a2232_cmd = 0; - - // get baud rate - baud = port->gs.baud; - if (baud == 0) { - /* speed == 0 -> drop DTR, do nothing else */ - local_irq_save(flags); - // Clear DTR (and RTS... mhhh). - status->Command = ( (status->Command & ~A2232CMD_CMask) | - A2232CMD_Close ); - status->OutFlush = -1; - status->Setup = -1; - - local_irq_restore(flags); - return 0; - } - - rate = A2232_BAUD_TABLE_NOAVAIL; - for (i=0; i < A2232_BAUD_TABLE_NUM_RATES * 3; i += 3){ - if (a2232_baud_table[i] == baud){ - if (mem->Common.Crystal == A2232_TURBO) rate = a2232_baud_table[i+2]; - else rate = a2232_baud_table[i+1]; - } - } - if (rate == A2232_BAUD_TABLE_NOAVAIL){ - printk("a2232: Board %d Port %d unsupported baud rate: %d baud. Using another.\n",port->which_a2232,port->which_port_on_a2232,baud); - // This is useful for both (turbo or normal) Crystal versions. - rate = A2232PARAM_B9600; - } - a2232_param |= rate; - - cflag = port->gs.port.tty->termios->c_cflag; - - // get character size - chsize = cflag & CSIZE; - switch (chsize){ - case CS8: a2232_param |= A2232PARAM_8Bit; break; - case CS7: a2232_param |= A2232PARAM_7Bit; break; - case CS6: a2232_param |= A2232PARAM_6Bit; break; - case CS5: a2232_param |= A2232PARAM_5Bit; break; - default: printk("a2232: Board %d Port %d unsupported character size: %d. Using 8 data bits.\n", - port->which_a2232,port->which_port_on_a2232,chsize); - a2232_param |= A2232PARAM_8Bit; break; - } - - // get number of stop bits - stopb = cflag & CSTOPB; - if (stopb){ // two stop bits instead of one - printk("a2232: Board %d Port %d 2 stop bits unsupported. Using 1 stop bit.\n", - port->which_a2232,port->which_port_on_a2232); - } - - // Warn if RTS/CTS not wanted - if (!(cflag & CRTSCTS)){ -#ifndef A2232_SUPPRESS_RTSCTS_WARNING - printk("a2232: Board %d Port %d cannot switch off firmware-implemented RTS/CTS hardware flow control.\n", - port->which_a2232,port->which_port_on_a2232); -#endif - } - - /* I think this is correct. - However, IXOFF means _input_ flow control and I wonder - if one should care about IXON _output_ flow control, - too. If this makes problems, one should turn the A2232 - firmware XON/XOFF "SoftFlow" flow control off and use - the conventional way of inserting START/STOP characters - by hand in throttle()/unthrottle(). - */ - softflow = !!( port->gs.port.tty->termios->c_iflag & IXOFF ); - - // get Parity (Enabled/Disabled? If Enabled, Odd or Even?) - parity = cflag & (PARENB | PARODD); - if (parity & PARENB){ - if (parity & PARODD){ - a2232_cmd |= A2232CMD_OddParity; - } - else{ - a2232_cmd |= A2232CMD_EvenParity; - } - } - else a2232_cmd |= A2232CMD_NoParity; - - - /* Hmm. Maybe an own a2232_port structure - member would be cleaner? */ - if (cflag & CLOCAL) - port->gs.port.flags &= ~ASYNC_CHECK_CD; - else - port->gs.port.flags |= ASYNC_CHECK_CD; - - - /* Now we have all parameters and can go to set them: */ - local_irq_save(flags); - - status->Param = a2232_param | A2232PARAM_RcvBaud; - status->Command = a2232_cmd | A2232CMD_Open | A2232CMD_Enable; - status->SoftFlow = softflow; - status->OutDisable = 0; - status->Setup = -1; - - local_irq_restore(flags); - return 0; -} - -static int a2232_chars_in_buffer(void *ptr) -{ - struct a2232_port *port; - volatile struct a2232status *status; - unsigned char ret; /* we need modulo-256 arithmetics */ - port = ptr; - status = a2232stat(port->which_a2232, port->which_port_on_a2232); -#if A2232_IOBUFLEN != 256 -#error "Re-Implement a2232_chars_in_buffer()!" -#endif - ret = (status->OutHead - status->OutTail); - return ret; -} - -static void a2232_close(void *ptr) -{ - a2232_disable_tx_interrupts(ptr); - a2232_disable_rx_interrupts(ptr); - /* see the comment in a2232_shutdown_port above. */ -} - -static void a2232_hungup(void *ptr) -{ - a2232_close(ptr); -} -/*** END OF REAL_DRIVER FUNCTIONS ***/ - -/*** BEGIN FUNCTIONS EXPECTED BY TTY DRIVER STRUCTS ***/ -static int a2232_ioctl( struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - return -ENOIOCTLCMD; -} - -static void a2232_throttle(struct tty_struct *tty) -{ -/* Throttle: System cannot take another chars: Drop RTS or - send the STOP char or whatever. - The A2232 firmware does RTS/CTS anyway, and XON/XOFF - if switched on. So the only thing we can do at this - layer here is not taking any characters out of the - A2232 buffer any more. */ - struct a2232_port *port = tty->driver_data; - port->throttle_input = -1; -} - -static void a2232_unthrottle(struct tty_struct *tty) -{ -/* Unthrottle: dual to "throttle()" above. */ - struct a2232_port *port = tty->driver_data; - port->throttle_input = 0; -} - -static int a2232_open(struct tty_struct * tty, struct file * filp) -{ -/* More or less stolen from other drivers. */ - int line; - int retval; - struct a2232_port *port; - - line = tty->index; - port = &a2232_ports[line]; - - tty->driver_data = port; - port->gs.port.tty = tty; - port->gs.port.count++; - retval = gs_init_port(&port->gs); - if (retval) { - port->gs.port.count--; - return retval; - } - port->gs.port.flags |= GS_ACTIVE; - retval = gs_block_til_ready(port, filp); - - if (retval) { - port->gs.port.count--; - return retval; - } - - a2232_enable_rx_interrupts(port); - - return 0; -} -/*** END OF FUNCTIONS EXPECTED BY TTY DRIVER STRUCTS ***/ - -static irqreturn_t a2232_vbl_inter(int irq, void *data) -{ -#if A2232_IOBUFLEN != 256 -#error "Re-Implement a2232_vbl_inter()!" -#endif - -struct a2232_port *port; -volatile struct a2232memory *mem; -volatile struct a2232status *status; -unsigned char newhead; -unsigned char bufpos; /* Must be unsigned char. We need the modulo-256 arithmetics */ -unsigned char ncd, ocd, ccd; /* names consistent with the NetBSD driver */ -volatile u_char *ibuf, *cbuf, *obuf; -int ch, err, n, p; - for (n = 0; n < nr_a2232; n++){ /* for every completely initialized A2232 board */ - mem = a2232mem(n); - for (p = 0; p < NUMLINES; p++){ /* for every port on this board */ - err = 0; - port = &a2232_ports[n*NUMLINES+p]; - if ( port->gs.port.flags & GS_ACTIVE ){ /* if the port is used */ - - status = a2232stat(n,p); - - if (!port->disable_rx && !port->throttle_input){ /* If input is not disabled */ - newhead = status->InHead; /* 65EC02 write pointer */ - bufpos = status->InTail; - - /* check for input for this port */ - if (newhead != bufpos) { - /* buffer for input chars/events */ - ibuf = mem->InBuf[p]; - - /* data types of bytes in ibuf */ - cbuf = mem->InCtl[p]; - - /* do for all chars */ - while (bufpos != newhead) { - /* which type of input data? */ - switch (cbuf[bufpos]) { - /* switch on input event (CD, BREAK, etc.) */ - case A2232INCTL_EVENT: - switch (ibuf[bufpos++]) { - case A2232EVENT_Break: - /* TODO: Handle BREAK signal */ - break; - /* A2232EVENT_CarrierOn and A2232EVENT_CarrierOff are - handled in a separate queue and should not occur here. */ - case A2232EVENT_Sync: - printk("A2232: 65EC02 software sent SYNC event, don't know what to do. Ignoring."); - break; - default: - printk("A2232: 65EC02 software broken, unknown event type %d occurred.\n",ibuf[bufpos-1]); - } /* event type switch */ - break; - case A2232INCTL_CHAR: - /* Receive incoming char */ - a2232_receive_char(port, ibuf[bufpos], err); - bufpos++; - break; - default: - printk("A2232: 65EC02 software broken, unknown data type %d occurred.\n",cbuf[bufpos]); - bufpos++; - } /* switch on input data type */ - } /* while there's something in the buffer */ - - status->InTail = bufpos; /* tell 65EC02 what we've read */ - - } /* if there was something in the buffer */ - } /* If input is not disabled */ - - /* Now check if there's something to output */ - obuf = mem->OutBuf[p]; - bufpos = status->OutHead; - while ( (port->gs.xmit_cnt > 0) && - (!port->gs.port.tty->stopped) && - (!port->gs.port.tty->hw_stopped) ){ /* While there are chars to transmit */ - if (((bufpos+1) & A2232_IOBUFLENMASK) != status->OutTail) { /* If the A2232 buffer is not full */ - ch = port->gs.xmit_buf[port->gs.xmit_tail]; /* get the next char to transmit */ - port->gs.xmit_tail = (port->gs.xmit_tail+1) & (SERIAL_XMIT_SIZE-1); /* modulo-addition for the gs.xmit_buf ring-buffer */ - obuf[bufpos++] = ch; /* put it into the A2232 buffer */ - port->gs.xmit_cnt--; - } - else{ /* If A2232 the buffer is full */ - break; /* simply stop filling it. */ - } - } - status->OutHead = bufpos; - - /* WakeUp if output buffer runs low */ - if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.port.tty) { - tty_wakeup(port->gs.port.tty); - } - } // if the port is used - } // for every port on the board - - /* Now check the CD message queue */ - newhead = mem->Common.CDHead; - bufpos = mem->Common.CDTail; - if (newhead != bufpos){ /* There are CD events in queue */ - ocd = mem->Common.CDStatus; /* get old status bits */ - while (newhead != bufpos){ /* read all events */ - ncd = mem->CDBuf[bufpos++]; /* get one event */ - ccd = ncd ^ ocd; /* mask of changed lines */ - ocd = ncd; /* save new status bits */ - for(p=0; p < NUMLINES; p++){ /* for all ports */ - if (ccd & 1){ /* this one changed */ - - struct a2232_port *port = &a2232_ports[n*7+p]; - port->cd_status = !(ncd & 1); /* ncd&1 <=> CD is now off */ - - if (!(port->gs.port.flags & ASYNC_CHECK_CD)) - ; /* Don't report DCD changes */ - else if (port->cd_status) { // if DCD on: DCD went UP! - - /* Are we blocking in open?*/ - wake_up_interruptible(&port->gs.port.open_wait); - } - else { // if DCD off: DCD went DOWN! - if (port->gs.port.tty) - tty_hangup (port->gs.port.tty); - } - - } // if CD changed for this port - ccd >>= 1; - ncd >>= 1; /* Shift bits for next line */ - } // for every port - } // while CD events in queue - mem->Common.CDStatus = ocd; /* save new status */ - mem->Common.CDTail = bufpos; /* remove events */ - } // if events in CD queue - - } // for every completely initialized A2232 board - return IRQ_HANDLED; -} - -static const struct tty_port_operations a2232_port_ops = { - .carrier_raised = a2232_carrier_raised, -}; - -static void a2232_init_portstructs(void) -{ - struct a2232_port *port; - int i; - - for (i = 0; i < MAX_A2232_BOARDS*NUMLINES; i++) { - port = a2232_ports + i; - tty_port_init(&port->gs.port); - port->gs.port.ops = &a2232_port_ops; - port->which_a2232 = i/NUMLINES; - port->which_port_on_a2232 = i%NUMLINES; - port->disable_rx = port->throttle_input = port->cd_status = 0; - port->gs.magic = A2232_MAGIC; - port->gs.close_delay = HZ/2; - port->gs.closing_wait = 30 * HZ; - port->gs.rd = &a2232_real_driver; - } -} - -static const struct tty_operations a2232_ops = { - .open = a2232_open, - .close = gs_close, - .write = gs_write, - .put_char = gs_put_char, - .flush_chars = gs_flush_chars, - .write_room = gs_write_room, - .chars_in_buffer = gs_chars_in_buffer, - .flush_buffer = gs_flush_buffer, - .ioctl = a2232_ioctl, - .throttle = a2232_throttle, - .unthrottle = a2232_unthrottle, - .set_termios = gs_set_termios, - .stop = gs_stop, - .start = gs_start, - .hangup = gs_hangup, -}; - -static int a2232_init_drivers(void) -{ - int error; - - a2232_driver = alloc_tty_driver(NUMLINES * nr_a2232); - if (!a2232_driver) - return -ENOMEM; - a2232_driver->owner = THIS_MODULE; - a2232_driver->driver_name = "commodore_a2232"; - a2232_driver->name = "ttyY"; - a2232_driver->major = A2232_NORMAL_MAJOR; - a2232_driver->type = TTY_DRIVER_TYPE_SERIAL; - a2232_driver->subtype = SERIAL_TYPE_NORMAL; - a2232_driver->init_termios = tty_std_termios; - a2232_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - a2232_driver->init_termios.c_ispeed = 9600; - a2232_driver->init_termios.c_ospeed = 9600; - a2232_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(a2232_driver, &a2232_ops); - if ((error = tty_register_driver(a2232_driver))) { - printk(KERN_ERR "A2232: Couldn't register A2232 driver, error = %d\n", - error); - put_tty_driver(a2232_driver); - return 1; - } - return 0; -} - -static int __init a2232board_init(void) -{ - struct zorro_dev *z; - - unsigned int boardaddr; - int bcount; - short start; - u_char *from; - volatile u_char *to; - volatile struct a2232memory *mem; - int error, i; - -#ifdef CONFIG_SMP - return -ENODEV; /* This driver is not SMP aware. Is there an SMP ZorroII-bus-machine? */ -#endif - - if (!MACH_IS_AMIGA){ - return -ENODEV; - } - - printk("Commodore A2232 driver initializing.\n"); /* Say that we're alive. */ - - z = NULL; - nr_a2232 = 0; - while ( (z = zorro_find_device(ZORRO_WILDCARD, z)) ){ - if ( (z->id != ZORRO_PROD_CBM_A2232_PROTOTYPE) && - (z->id != ZORRO_PROD_CBM_A2232) ){ - continue; // The board found was no A2232 - } - if (!zorro_request_device(z,"A2232 driver")) - continue; - - printk("Commodore A2232 found (#%d).\n",nr_a2232); - - zd_a2232[nr_a2232] = z; - - boardaddr = ZTWO_VADDR( z->resource.start ); - printk("Board is located at address 0x%x, size is 0x%x.\n", boardaddr, (unsigned int) ((z->resource.end+1) - (z->resource.start))); - - mem = (volatile struct a2232memory *) boardaddr; - - (void) mem->Enable6502Reset; /* copy the code across to the board */ - to = (u_char *)mem; from = a2232_65EC02code; bcount = sizeof(a2232_65EC02code) - 2; - start = *(short *)from; - from += sizeof(start); - to += start; - while(bcount--) *to++ = *from++; - printk("65EC02 software uploaded to the A2232 memory.\n"); - - mem->Common.Crystal = A2232_UNKNOWN; /* use automatic speed check */ - - /* start 6502 running */ - (void) mem->ResetBoard; - printk("A2232's 65EC02 CPU up and running.\n"); - - /* wait until speed detector has finished */ - for (bcount = 0; bcount < 2000; bcount++) { - udelay(1000); - if (mem->Common.Crystal) - break; - } - printk((mem->Common.Crystal?"A2232 oscillator crystal detected by 65EC02 software: ":"65EC02 software could not determine A2232 oscillator crystal: ")); - switch (mem->Common.Crystal){ - case A2232_UNKNOWN: - printk("Unknown crystal.\n"); - break; - case A2232_NORMAL: - printk ("Normal crystal.\n"); - break; - case A2232_TURBO: - printk ("Turbo crystal.\n"); - break; - default: - printk ("0x%x. Huh?\n",mem->Common.Crystal); - } - - nr_a2232++; - - } - - printk("Total: %d A2232 boards initialized.\n", nr_a2232); /* Some status report if no card was found */ - - a2232_init_portstructs(); - - /* - a2232_init_drivers also registers the drivers. Must be here because all boards - have to be detected first. - */ - if (a2232_init_drivers()) return -ENODEV; // maybe we should use a different -Exxx? - - error = request_irq(IRQ_AMIGA_VERTB, a2232_vbl_inter, 0, - "A2232 serial VBL", a2232_driver_ID); - if (error) { - for (i = 0; i < nr_a2232; i++) - zorro_release_device(zd_a2232[i]); - tty_unregister_driver(a2232_driver); - put_tty_driver(a2232_driver); - } - return error; -} - -static void __exit a2232board_exit(void) -{ - int i; - - for (i = 0; i < nr_a2232; i++) { - zorro_release_device(zd_a2232[i]); - } - - tty_unregister_driver(a2232_driver); - put_tty_driver(a2232_driver); - free_irq(IRQ_AMIGA_VERTB, a2232_driver_ID); -} - -module_init(a2232board_init); -module_exit(a2232board_exit); - -MODULE_AUTHOR("Enver Haase"); -MODULE_DESCRIPTION("Amiga A2232 multi-serial board driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/char/ser_a2232.h b/drivers/char/ser_a2232.h deleted file mode 100644 index bc09eb9e118b..000000000000 --- a/drivers/char/ser_a2232.h +++ /dev/null @@ -1,202 +0,0 @@ -/* drivers/char/ser_a2232.h */ - -/* $Id: ser_a2232.h,v 0.4 2000/01/25 12:00:00 ehaase Exp $ */ - -/* Linux serial driver for the Amiga A2232 board */ - -/* This driver is MAINTAINED. Before applying any changes, please contact - * the author. - */ - -/* Copyright (c) 2000-2001 Enver Haase - * alias The A2232 driver project - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _SER_A2232_H_ -#define _SER_A2232_H_ - -/* - How many boards are to be supported at maximum; - "up to five A2232 Multiport Serial Cards may be installed in a - single Amiga 2000" states the A2232 User's Guide. If you have - more slots available, you might want to change the value below. -*/ -#define MAX_A2232_BOARDS 5 - -#ifndef A2232_NORMAL_MAJOR -/* This allows overriding on the compiler commandline, or in a "major.h" - include or something like that */ -#define A2232_NORMAL_MAJOR 224 /* /dev/ttyY* */ -#define A2232_CALLOUT_MAJOR 225 /* /dev/cuy* */ -#endif - -/* Some magic is always good - Who knows :) */ -#define A2232_MAGIC 0x000a2232 - -/* A2232 port structure to keep track of the - status of every single line used */ -struct a2232_port{ - struct gs_port gs; - unsigned int which_a2232; - unsigned int which_port_on_a2232; - short disable_rx; - short throttle_input; - short cd_status; -}; - -#define NUMLINES 7 /* number of lines per board */ -#define A2232_IOBUFLEN 256 /* number of bytes per buffer */ -#define A2232_IOBUFLENMASK 0xff /* mask for maximum number of bytes */ - - -#define A2232_UNKNOWN 0 /* crystal not known */ -#define A2232_NORMAL 1 /* normal A2232 (1.8432 MHz oscillator) */ -#define A2232_TURBO 2 /* turbo A2232 (3.6864 MHz oscillator) */ - - -struct a2232common { - char Crystal; /* normal (1) or turbo (2) board? */ - u_char Pad_a; - u_char TimerH; /* timer value after speed check */ - u_char TimerL; - u_char CDHead; /* head pointer for CD message queue */ - u_char CDTail; /* tail pointer for CD message queue */ - u_char CDStatus; - u_char Pad_b; -}; - -struct a2232status { - u_char InHead; /* input queue head */ - u_char InTail; /* input queue tail */ - u_char OutDisable; /* disables output */ - u_char OutHead; /* output queue head */ - u_char OutTail; /* output queue tail */ - u_char OutCtrl; /* soft flow control character to send */ - u_char OutFlush; /* flushes output buffer */ - u_char Setup; /* causes reconfiguration */ - u_char Param; /* parameter byte - see A2232PARAM */ - u_char Command; /* command byte - see A2232CMD */ - u_char SoftFlow; /* enables xon/xoff flow control */ - /* private 65EC02 fields: */ - u_char XonOff; /* stores XON/XOFF enable/disable */ -}; - -#define A2232_MEMPAD1 \ - (0x0200 - NUMLINES * sizeof(struct a2232status) - \ - sizeof(struct a2232common)) -#define A2232_MEMPAD2 (0x2000 - NUMLINES * A2232_IOBUFLEN - A2232_IOBUFLEN) - -struct a2232memory { - struct a2232status Status[NUMLINES]; /* 0x0000-0x006f status areas */ - struct a2232common Common; /* 0x0070-0x0077 common flags */ - u_char Dummy1[A2232_MEMPAD1]; /* 0x00XX-0x01ff */ - u_char OutBuf[NUMLINES][A2232_IOBUFLEN];/* 0x0200-0x08ff output bufs */ - u_char InBuf[NUMLINES][A2232_IOBUFLEN]; /* 0x0900-0x0fff input bufs */ - u_char InCtl[NUMLINES][A2232_IOBUFLEN]; /* 0x1000-0x16ff control data */ - u_char CDBuf[A2232_IOBUFLEN]; /* 0x1700-0x17ff CD event buffer */ - u_char Dummy2[A2232_MEMPAD2]; /* 0x1800-0x2fff */ - u_char Code[0x1000]; /* 0x3000-0x3fff code area */ - u_short InterruptAck; /* 0x4000 intr ack */ - u_char Dummy3[0x3ffe]; /* 0x4002-0x7fff */ - u_short Enable6502Reset; /* 0x8000 Stop board, */ - /* 6502 RESET line held low */ - u_char Dummy4[0x3ffe]; /* 0x8002-0xbfff */ - u_short ResetBoard; /* 0xc000 reset board & run, */ - /* 6502 RESET line held high */ -}; - -#undef A2232_MEMPAD1 -#undef A2232_MEMPAD2 - -#define A2232INCTL_CHAR 0 /* corresponding byte in InBuf is a character */ -#define A2232INCTL_EVENT 1 /* corresponding byte in InBuf is an event */ - -#define A2232EVENT_Break 1 /* break set */ -#define A2232EVENT_CarrierOn 2 /* carrier raised */ -#define A2232EVENT_CarrierOff 3 /* carrier dropped */ -#define A2232EVENT_Sync 4 /* don't know, defined in 2232.ax */ - -#define A2232CMD_Enable 0x1 /* enable/DTR bit */ -#define A2232CMD_Close 0x2 /* close the device */ -#define A2232CMD_Open 0xb /* open the device */ -#define A2232CMD_CMask 0xf /* command mask */ -#define A2232CMD_RTSOff 0x0 /* turn off RTS */ -#define A2232CMD_RTSOn 0x8 /* turn on RTS */ -#define A2232CMD_Break 0xd /* transmit a break */ -#define A2232CMD_RTSMask 0xc /* mask for RTS stuff */ -#define A2232CMD_NoParity 0x00 /* don't use parity */ -#define A2232CMD_OddParity 0x20 /* odd parity */ -#define A2232CMD_EvenParity 0x60 /* even parity */ -#define A2232CMD_ParityMask 0xe0 /* parity mask */ - -#define A2232PARAM_B115200 0x0 /* baud rates */ -#define A2232PARAM_B50 0x1 -#define A2232PARAM_B75 0x2 -#define A2232PARAM_B110 0x3 -#define A2232PARAM_B134 0x4 -#define A2232PARAM_B150 0x5 -#define A2232PARAM_B300 0x6 -#define A2232PARAM_B600 0x7 -#define A2232PARAM_B1200 0x8 -#define A2232PARAM_B1800 0x9 -#define A2232PARAM_B2400 0xa -#define A2232PARAM_B3600 0xb -#define A2232PARAM_B4800 0xc -#define A2232PARAM_B7200 0xd -#define A2232PARAM_B9600 0xe -#define A2232PARAM_B19200 0xf -#define A2232PARAM_BaudMask 0xf /* baud rate mask */ -#define A2232PARAM_RcvBaud 0x10 /* enable receive baud rate */ -#define A2232PARAM_8Bit 0x00 /* numbers of bits */ -#define A2232PARAM_7Bit 0x20 -#define A2232PARAM_6Bit 0x40 -#define A2232PARAM_5Bit 0x60 -#define A2232PARAM_BitMask 0x60 /* numbers of bits mask */ - - -/* Standard speeds tables, -1 means unavailable, -2 means 0 baud: switch off line */ -#define A2232_BAUD_TABLE_NOAVAIL -1 -#define A2232_BAUD_TABLE_NUM_RATES (18) -static int a2232_baud_table[A2232_BAUD_TABLE_NUM_RATES*3] = { - //Baud //Normal //Turbo - 50, A2232PARAM_B50, A2232_BAUD_TABLE_NOAVAIL, - 75, A2232PARAM_B75, A2232_BAUD_TABLE_NOAVAIL, - 110, A2232PARAM_B110, A2232_BAUD_TABLE_NOAVAIL, - 134, A2232PARAM_B134, A2232_BAUD_TABLE_NOAVAIL, - 150, A2232PARAM_B150, A2232PARAM_B75, - 200, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL, - 300, A2232PARAM_B300, A2232PARAM_B150, - 600, A2232PARAM_B600, A2232PARAM_B300, - 1200, A2232PARAM_B1200, A2232PARAM_B600, - 1800, A2232PARAM_B1800, A2232_BAUD_TABLE_NOAVAIL, - 2400, A2232PARAM_B2400, A2232PARAM_B1200, - 4800, A2232PARAM_B4800, A2232PARAM_B2400, - 9600, A2232PARAM_B9600, A2232PARAM_B4800, - 19200, A2232PARAM_B19200, A2232PARAM_B9600, - 38400, A2232_BAUD_TABLE_NOAVAIL, A2232PARAM_B19200, - 57600, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL, -#ifdef A2232_SPEEDHACK - 115200, A2232PARAM_B115200, A2232_BAUD_TABLE_NOAVAIL, - 230400, A2232_BAUD_TABLE_NOAVAIL, A2232PARAM_B115200 -#else - 115200, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL, - 230400, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL -#endif -}; -#endif diff --git a/drivers/char/ser_a2232fw.ax b/drivers/char/ser_a2232fw.ax deleted file mode 100644 index 736438032768..000000000000 --- a/drivers/char/ser_a2232fw.ax +++ /dev/null @@ -1,529 +0,0 @@ -;.lib "axm" -; -;begin -;title "A2232 serial board driver" -; -;set modules "2232" -;set executable "2232.bin" -; -;;;;set nolink -; -;set temporary directory "t:" -; -;set assembly options "-m6502 -l60:t:list" -;set link options "bin"; loadadr" -;;;bin2c 2232.bin msc6502.h msc6502code -;end -; -; -; ### Commodore A2232 serial board driver for NetBSD by JM v1.3 ### -; -; - Created 950501 by JM - -; -; -; Serial board driver software. -; -; -% Copyright (c) 1995 Jukka Marin . -% All rights reserved. -% -% Redistribution and use in source and binary forms, with or without -% modification, are permitted provided that the following conditions -% are met: -% 1. Redistributions of source code must retain the above copyright -% notice, and the entire permission notice in its entirety, -% including the disclaimer of warranties. -% 2. Redistributions in binary form must reproduce the above copyright -% notice, this list of conditions and the following disclaimer in the -% documentation and/or other materials provided with the distribution. -% 3. The name of the author may not be used to endorse or promote -% products derived from this software without specific prior -% written permission. -% -% ALTERNATIVELY, this product may be distributed under the terms of -% the GNU General Public License, in which case the provisions of the -% GPL are required INSTEAD OF the above restrictions. (This clause is -% necessary due to a potential bad interaction between the GPL and -% the restrictions contained in a BSD-style copyright.) -% -% THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED -% WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -% OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -% DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, -% INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -% (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -% SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -% HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -% STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -% OF THE POSSIBILITY OF SUCH DAMAGE. -; -; -; Bugs: -; -; - Can't send a break yet -; -; -; -; Edited: -; -; - 950501 by JM -> v0.1 - Created this file. -; - 951029 by JM -> v1.3 - Carrier Detect events now queued in a separate -; queue. -; -; - - -CODE equ $3800 ; start address for program code - - -CTL_CHAR equ $00 ; byte in ibuf is a character -CTL_EVENT equ $01 ; byte in ibuf is an event - -EVENT_BREAK equ $01 -EVENT_CDON equ $02 -EVENT_CDOFF equ $03 -EVENT_SYNC equ $04 - -XON equ $11 -XOFF equ $13 - - -VARBASE macro *starting_address ; was VARINIT -_varbase set \1 - endm - -VARDEF macro *name space_needs -\1 equ _varbase -_varbase set _varbase+\2 - endm - - -stz macro * address - db $64,\1 - endm - -stzax macro * address - db $9e,<\1,>\1 - endm - - -biti macro * immediate value - db $89,\1 - endm - -smb0 macro * address - db $87,\1 - endm -smb1 macro * address - db $97,\1 - endm -smb2 macro * address - db $a7,\1 - endm -smb3 macro * address - db $b7,\1 - endm -smb4 macro * address - db $c7,\1 - endm -smb5 macro * address - db $d7,\1 - endm -smb6 macro * address - db $e7,\1 - endm -smb7 macro * address - db $f7,\1 - endm - - - -;-----------------------------------------------------------------------; -; ; -; stuff common for all ports, non-critical (run once / loop) ; -; ; -DO_SLOW macro * port_number ; - .local ; ; - lda CIA+C_PA ; check all CD inputs ; - cmp CommonCDo ; changed from previous accptd? ; - beq =over ; nope, do nothing else here ; - ; ; - cmp CommonCDb ; bouncing? ; - beq =nobounce ; nope -> ; - ; ; - sta CommonCDb ; save current state ; - lda #64 ; reinitialize counter ; - sta CommonCDc ; ; - jmp =over ; skip CD save ; - ; ; -=nobounce dec CommonCDc ; no, decrement bounce counter ; - bpl =over ; not done yet, so skip CD save ; - ; ; -=saveCD ldx CDHead ; get write index ; - sta cdbuf,x ; save status in buffer ; - inx ; ; - cpx CDTail ; buffer full? ; - .if ne ; no: preserve status: ; - stx CDHead ; update index in RAM ; - sta CommonCDo ; save state for the next check ; - .end ; ; -=over .end local ; - endm ; - ; -;-----------------------------------------------------------------------; - - -; port specific stuff (no data transfer) - -DO_PORT macro * port_number - .local ; ; - lda SetUp\1 ; reconfiguration request? ; - .if ne ; yes: ; - lda SoftFlow\1 ; get XON/XOFF flag ; - sta XonOff\1 ; save it ; - lda Param\1 ; get parameter ; - ora #%00010000 ; use baud generator for Rx ; - sta ACIA\1+A_CTRL ; store in control register ; - stz OutDisable\1 ; enable transmit output ; - stz SetUp\1 ; no reconfiguration no more ; - .end ; ; - ; ; - lda InHead\1 ; get write index ; - sbc InTail\1 ; buffer full soon? ; - cmp #200 ; 200 chars or more in buffer? ; - lda Command\1 ; get Command reg value ; - and #%11110011 ; turn RTS OFF by default ; - .if cc ; still room in buffer: ; - ora #%00001000 ; turn RTS ON ; - .end ; ; - sta ACIA\1+A_CMD ; set/clear RTS ; - ; ; - lda OutFlush\1 ; request to flush output buffer; - .if ne ; yessh! ; - lda OutHead\1 ; get head ; - sta OutTail\1 ; save as tail ; - stz OutDisable\1 ; enable transmit output ; - stz OutFlush\1 ; clear request ; - .end - .end local - endm - - -DO_DATA macro * port number - .local - lda ACIA\1+A_SR ; read ACIA status register ; - biti [1<<3] ; something received? ; - .if ne ; yes: ; - biti [1<<1] ; framing error? ; - .if ne ; yes: ; - lda ACIA\1+A_DATA ; read received character ; - bne =SEND ; not break -> ignore it ; - ldx InHead\1 ; get write pointer ; - lda #CTL_EVENT ; get type of byte ; - sta ictl\1,x ; save it in InCtl buffer ; - lda #EVENT_BREAK ; event code ; - sta ibuf\1,x ; save it as well ; - inx ; ; - cpx InTail\1 ; still room in buffer? ; - .if ne ; absolutely: ; - stx InHead\1 ; update index in memory ; - .end ; ; - jmp =SEND ; go check if anything to send ; - .end ; ; - ; normal char received: ; - ldx InHead\1 ; get write index ; - lda ACIA\1+A_DATA ; read received character ; - sta ibuf\1,x ; save char in buffer ; - stzax ictl\1 ; set type to CTL_CHAR ; - inx ; ; - cpx InTail\1 ; buffer full? ; - .if ne ; no: preserve character: ; - stx InHead\1 ; update index in RAM ; - .end ; ; - and #$7f ; mask off parity if any ; - cmp #XOFF ; XOFF from remote host? ; - .if eq ; yes: ; - lda XonOff\1 ; if XON/XOFF handshaking.. ; - sta OutDisable\1 ; ..disable transmitter ; - .end ; ; - .end ; ; - ; ; - ; BUFFER FULL CHECK WAS HERE ; - ; ; -=SEND lda ACIA\1+A_SR ; transmit register empty? ; - and #[1<<4] ; ; - .if ne ; yes: ; - ldx OutCtrl\1 ; sending out XON/XOFF? ; - .if ne ; yes: ; - lda CIA+C_PB ; check CTS signal ; - and #[1<<\1] ; (for this port only) ; - bne =DONE ; not allowed to send -> done ; - stx ACIA\1+A_DATA ; transmit control char ; - stz OutCtrl\1 ; clear flag ; - jmp =DONE ; and we're done ; - .end ; ; - ; ; - ldx OutTail\1 ; anything to transmit? ; - cpx OutHead\1 ; ; - .if ne ; yes: ; - lda OutDisable\1 ; allowed to transmit? ; - .if eq ; yes: ; - lda CIA+C_PB ; check CTS signal ; - and #[1<<\1] ; (for this port only) ; - bne =DONE ; not allowed to send -> done ; - lda obuf\1,x ; get a char from buffer ; - sta ACIA\1+A_DATA ; send it away ; - inc OutTail\1 ; update read index ; - .end ; ; - .end ; ; - .end ; ; -=DONE .end local - endm - - - -PORTVAR macro * port number - VARDEF InHead\1 1 - VARDEF InTail\1 1 - VARDEF OutDisable\1 1 - VARDEF OutHead\1 1 - VARDEF OutTail\1 1 - VARDEF OutCtrl\1 1 - VARDEF OutFlush\1 1 - VARDEF SetUp\1 1 - VARDEF Param\1 1 - VARDEF Command\1 1 - VARDEF SoftFlow\1 1 - ; private: - VARDEF XonOff\1 1 - endm - - - VARBASE 0 ; start variables at address $0000 - PORTVAR 0 ; define variables for port 0 - PORTVAR 1 ; define variables for port 1 - PORTVAR 2 ; define variables for port 2 - PORTVAR 3 ; define variables for port 3 - PORTVAR 4 ; define variables for port 4 - PORTVAR 5 ; define variables for port 5 - PORTVAR 6 ; define variables for port 6 - - - - VARDEF Crystal 1 ; 0 = unknown, 1 = normal, 2 = turbo - VARDEF Pad_a 1 - VARDEF TimerH 1 - VARDEF TimerL 1 - VARDEF CDHead 1 - VARDEF CDTail 1 - VARDEF CDStatus 1 - VARDEF Pad_b 1 - - VARDEF CommonCDo 1 ; for carrier detect optimization - VARDEF CommonCDc 1 ; for carrier detect debouncing - VARDEF CommonCDb 1 ; for carrier detect debouncing - - - VARBASE $0200 - VARDEF obuf0 256 ; output data (characters only) - VARDEF obuf1 256 - VARDEF obuf2 256 - VARDEF obuf3 256 - VARDEF obuf4 256 - VARDEF obuf5 256 - VARDEF obuf6 256 - - VARDEF ibuf0 256 ; input data (characters, events etc - see ictl) - VARDEF ibuf1 256 - VARDEF ibuf2 256 - VARDEF ibuf3 256 - VARDEF ibuf4 256 - VARDEF ibuf5 256 - VARDEF ibuf6 256 - - VARDEF ictl0 256 ; input control information (type of data in ibuf) - VARDEF ictl1 256 - VARDEF ictl2 256 - VARDEF ictl3 256 - VARDEF ictl4 256 - VARDEF ictl5 256 - VARDEF ictl6 256 - - VARDEF cdbuf 256 ; CD event queue - - -ACIA0 equ $4400 -ACIA1 equ $4c00 -ACIA2 equ $5400 -ACIA3 equ $5c00 -ACIA4 equ $6400 -ACIA5 equ $6c00 -ACIA6 equ $7400 - -A_DATA equ $00 -A_SR equ $02 -A_CMD equ $04 -A_CTRL equ $06 -; 00 write transmit data read received data -; 02 reset ACIA read status register -; 04 write command register read command register -; 06 write control register read control register - -CIA equ $7c00 ; 8520 CIA -C_PA equ $00 ; port A data register -C_PB equ $02 ; port B data register -C_DDRA equ $04 ; data direction register for port A -C_DDRB equ $06 ; data direction register for port B -C_TAL equ $08 ; timer A -C_TAH equ $0a -C_TBL equ $0c ; timer B -C_TBH equ $0e -C_TODL equ $10 ; TOD LSB -C_TODM equ $12 ; TOD middle byte -C_TODH equ $14 ; TOD MSB -C_DATA equ $18 ; serial data register -C_INTCTRL equ $1a ; interrupt control register -C_CTRLA equ $1c ; control register A -C_CTRLB equ $1e ; control register B - - - - - - section main,code,CODE-2 - - db >CODE,. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/* This is the 65EC02 code by Jukka Marin that is executed by - the A2232's 65EC02 processor (base address: 0x3800) - Source file: ser_a2232fw.ax - Version: 1.3 (951029) - Known Bugs: Cannot send a break yet -*/ -static unsigned char a2232_65EC02code[] = { - 0x38, 0x00, 0xA2, 0xFF, 0x9A, 0xD8, 0xA2, 0x00, - 0xA9, 0x00, 0xA0, 0x54, 0x95, 0x00, 0xE8, 0x88, - 0xD0, 0xFA, 0x64, 0x5C, 0x64, 0x5E, 0x64, 0x58, - 0x64, 0x59, 0xA9, 0x00, 0x85, 0x55, 0xA9, 0xAA, - 0xC9, 0x64, 0x90, 0x02, 0xE6, 0x55, 0xA5, 0x54, - 0xF0, 0x03, 0x4C, 0x92, 0x38, 0xA9, 0x98, 0x8D, - 0x06, 0x44, 0xA9, 0x0B, 0x8D, 0x04, 0x44, 0xAD, - 0x02, 0x44, 0xA9, 0x80, 0x8D, 0x1A, 0x7C, 0xA9, - 0xFF, 0x8D, 0x08, 0x7C, 0x8D, 0x0A, 0x7C, 0xA2, - 0x00, 0x8E, 0x00, 0x44, 0xEA, 0xEA, 0xAD, 0x02, - 0x44, 0xEA, 0xEA, 0x8E, 0x00, 0x44, 0xAD, 0x02, - 0x44, 0x29, 0x10, 0xF0, 0xF9, 0xA9, 0x11, 0x8E, - 0x00, 0x44, 0x8D, 0x1C, 0x7C, 0xAD, 0x02, 0x44, - 0x29, 0x10, 0xF0, 0xF9, 0x8E, 0x1C, 0x7C, 0xAD, - 0x08, 0x7C, 0x85, 0x57, 0xAD, 0x0A, 0x7C, 0x85, - 0x56, 0xC9, 0xD0, 0x90, 0x05, 0xA9, 0x02, 0x4C, - 0x82, 0x38, 0xA9, 0x01, 0x85, 0x54, 0xA9, 0x00, - 0x8D, 0x02, 0x44, 0x8D, 0x06, 0x44, 0x8D, 0x04, - 0x44, 0x4C, 0x92, 0x38, 0xAD, 0x00, 0x7C, 0xC5, - 0x5C, 0xF0, 0x1F, 0xC5, 0x5E, 0xF0, 0x09, 0x85, - 0x5E, 0xA9, 0x40, 0x85, 0x5D, 0x4C, 0xB8, 0x38, - 0xC6, 0x5D, 0x10, 0x0E, 0xA6, 0x58, 0x9D, 0x00, - 0x17, 0xE8, 0xE4, 0x59, 0xF0, 0x04, 0x86, 0x58, - 0x85, 0x5C, 0x20, 0x23, 0x3A, 0xA5, 0x07, 0xF0, - 0x0F, 0xA5, 0x0A, 0x85, 0x0B, 0xA5, 0x08, 0x09, - 0x10, 0x8D, 0x06, 0x44, 0x64, 0x02, 0x64, 0x07, - 0xA5, 0x00, 0xE5, 0x01, 0xC9, 0xC8, 0xA5, 0x09, - 0x29, 0xF3, 0xB0, 0x02, 0x09, 0x08, 0x8D, 0x04, - 0x44, 0xA5, 0x06, 0xF0, 0x08, 0xA5, 0x03, 0x85, - 0x04, 0x64, 0x02, 0x64, 0x06, 0x20, 0x23, 0x3A, - 0xA5, 0x13, 0xF0, 0x0F, 0xA5, 0x16, 0x85, 0x17, - 0xA5, 0x14, 0x09, 0x10, 0x8D, 0x06, 0x4C, 0x64, - 0x0E, 0x64, 0x13, 0xA5, 0x0C, 0xE5, 0x0D, 0xC9, - 0xC8, 0xA5, 0x15, 0x29, 0xF3, 0xB0, 0x02, 0x09, - 0x08, 0x8D, 0x04, 0x4C, 0xA5, 0x12, 0xF0, 0x08, - 0xA5, 0x0F, 0x85, 0x10, 0x64, 0x0E, 0x64, 0x12, - 0x20, 0x23, 0x3A, 0xA5, 0x1F, 0xF0, 0x0F, 0xA5, - 0x22, 0x85, 0x23, 0xA5, 0x20, 0x09, 0x10, 0x8D, - 0x06, 0x54, 0x64, 0x1A, 0x64, 0x1F, 0xA5, 0x18, - 0xE5, 0x19, 0xC9, 0xC8, 0xA5, 0x21, 0x29, 0xF3, - 0xB0, 0x02, 0x09, 0x08, 0x8D, 0x04, 0x54, 0xA5, - 0x1E, 0xF0, 0x08, 0xA5, 0x1B, 0x85, 0x1C, 0x64, - 0x1A, 0x64, 0x1E, 0x20, 0x23, 0x3A, 0xA5, 0x2B, - 0xF0, 0x0F, 0xA5, 0x2E, 0x85, 0x2F, 0xA5, 0x2C, - 0x09, 0x10, 0x8D, 0x06, 0x5C, 0x64, 0x26, 0x64, - 0x2B, 0xA5, 0x24, 0xE5, 0x25, 0xC9, 0xC8, 0xA5, - 0x2D, 0x29, 0xF3, 0xB0, 0x02, 0x09, 0x08, 0x8D, - 0x04, 0x5C, 0xA5, 0x2A, 0xF0, 0x08, 0xA5, 0x27, - 0x85, 0x28, 0x64, 0x26, 0x64, 0x2A, 0x20, 0x23, - 0x3A, 0xA5, 0x37, 0xF0, 0x0F, 0xA5, 0x3A, 0x85, - 0x3B, 0xA5, 0x38, 0x09, 0x10, 0x8D, 0x06, 0x64, - 0x64, 0x32, 0x64, 0x37, 0xA5, 0x30, 0xE5, 0x31, - 0xC9, 0xC8, 0xA5, 0x39, 0x29, 0xF3, 0xB0, 0x02, - 0x09, 0x08, 0x8D, 0x04, 0x64, 0xA5, 0x36, 0xF0, - 0x08, 0xA5, 0x33, 0x85, 0x34, 0x64, 0x32, 0x64, - 0x36, 0x20, 0x23, 0x3A, 0xA5, 0x43, 0xF0, 0x0F, - 0xA5, 0x46, 0x85, 0x47, 0xA5, 0x44, 0x09, 0x10, - 0x8D, 0x06, 0x6C, 0x64, 0x3E, 0x64, 0x43, 0xA5, - 0x3C, 0xE5, 0x3D, 0xC9, 0xC8, 0xA5, 0x45, 0x29, - 0xF3, 0xB0, 0x02, 0x09, 0x08, 0x8D, 0x04, 0x6C, - 0xA5, 0x42, 0xF0, 0x08, 0xA5, 0x3F, 0x85, 0x40, - 0x64, 0x3E, 0x64, 0x42, 0x20, 0x23, 0x3A, 0xA5, - 0x4F, 0xF0, 0x0F, 0xA5, 0x52, 0x85, 0x53, 0xA5, - 0x50, 0x09, 0x10, 0x8D, 0x06, 0x74, 0x64, 0x4A, - 0x64, 0x4F, 0xA5, 0x48, 0xE5, 0x49, 0xC9, 0xC8, - 0xA5, 0x51, 0x29, 0xF3, 0xB0, 0x02, 0x09, 0x08, - 0x8D, 0x04, 0x74, 0xA5, 0x4E, 0xF0, 0x08, 0xA5, - 0x4B, 0x85, 0x4C, 0x64, 0x4A, 0x64, 0x4E, 0x20, - 0x23, 0x3A, 0x4C, 0x92, 0x38, 0xAD, 0x02, 0x44, - 0x89, 0x08, 0xF0, 0x3B, 0x89, 0x02, 0xF0, 0x1B, - 0xAD, 0x00, 0x44, 0xD0, 0x32, 0xA6, 0x00, 0xA9, - 0x01, 0x9D, 0x00, 0x10, 0xA9, 0x01, 0x9D, 0x00, - 0x09, 0xE8, 0xE4, 0x01, 0xF0, 0x02, 0x86, 0x00, - 0x4C, 0x65, 0x3A, 0xA6, 0x00, 0xAD, 0x00, 0x44, - 0x9D, 0x00, 0x09, 0x9E, 0x00, 0x10, 0xE8, 0xE4, - 0x01, 0xF0, 0x02, 0x86, 0x00, 0x29, 0x7F, 0xC9, - 0x13, 0xD0, 0x04, 0xA5, 0x0B, 0x85, 0x02, 0xAD, - 0x02, 0x44, 0x29, 0x10, 0xF0, 0x2C, 0xA6, 0x05, - 0xF0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x01, 0xD0, - 0x21, 0x8E, 0x00, 0x44, 0x64, 0x05, 0x4C, 0x98, - 0x3A, 0xA6, 0x04, 0xE4, 0x03, 0xF0, 0x13, 0xA5, - 0x02, 0xD0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x01, - 0xD0, 0x08, 0xBD, 0x00, 0x02, 0x8D, 0x00, 0x44, - 0xE6, 0x04, 0xAD, 0x02, 0x4C, 0x89, 0x08, 0xF0, - 0x3B, 0x89, 0x02, 0xF0, 0x1B, 0xAD, 0x00, 0x4C, - 0xD0, 0x32, 0xA6, 0x0C, 0xA9, 0x01, 0x9D, 0x00, - 0x11, 0xA9, 0x01, 0x9D, 0x00, 0x0A, 0xE8, 0xE4, - 0x0D, 0xF0, 0x02, 0x86, 0x0C, 0x4C, 0xDA, 0x3A, - 0xA6, 0x0C, 0xAD, 0x00, 0x4C, 0x9D, 0x00, 0x0A, - 0x9E, 0x00, 0x11, 0xE8, 0xE4, 0x0D, 0xF0, 0x02, - 0x86, 0x0C, 0x29, 0x7F, 0xC9, 0x13, 0xD0, 0x04, - 0xA5, 0x17, 0x85, 0x0E, 0xAD, 0x02, 0x4C, 0x29, - 0x10, 0xF0, 0x2C, 0xA6, 0x11, 0xF0, 0x0F, 0xAD, - 0x02, 0x7C, 0x29, 0x02, 0xD0, 0x21, 0x8E, 0x00, - 0x4C, 0x64, 0x11, 0x4C, 0x0D, 0x3B, 0xA6, 0x10, - 0xE4, 0x0F, 0xF0, 0x13, 0xA5, 0x0E, 0xD0, 0x0F, - 0xAD, 0x02, 0x7C, 0x29, 0x02, 0xD0, 0x08, 0xBD, - 0x00, 0x03, 0x8D, 0x00, 0x4C, 0xE6, 0x10, 0xAD, - 0x02, 0x54, 0x89, 0x08, 0xF0, 0x3B, 0x89, 0x02, - 0xF0, 0x1B, 0xAD, 0x00, 0x54, 0xD0, 0x32, 0xA6, - 0x18, 0xA9, 0x01, 0x9D, 0x00, 0x12, 0xA9, 0x01, - 0x9D, 0x00, 0x0B, 0xE8, 0xE4, 0x19, 0xF0, 0x02, - 0x86, 0x18, 0x4C, 0x4F, 0x3B, 0xA6, 0x18, 0xAD, - 0x00, 0x54, 0x9D, 0x00, 0x0B, 0x9E, 0x00, 0x12, - 0xE8, 0xE4, 0x19, 0xF0, 0x02, 0x86, 0x18, 0x29, - 0x7F, 0xC9, 0x13, 0xD0, 0x04, 0xA5, 0x23, 0x85, - 0x1A, 0xAD, 0x02, 0x54, 0x29, 0x10, 0xF0, 0x2C, - 0xA6, 0x1D, 0xF0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, - 0x04, 0xD0, 0x21, 0x8E, 0x00, 0x54, 0x64, 0x1D, - 0x4C, 0x82, 0x3B, 0xA6, 0x1C, 0xE4, 0x1B, 0xF0, - 0x13, 0xA5, 0x1A, 0xD0, 0x0F, 0xAD, 0x02, 0x7C, - 0x29, 0x04, 0xD0, 0x08, 0xBD, 0x00, 0x04, 0x8D, - 0x00, 0x54, 0xE6, 0x1C, 0xAD, 0x02, 0x5C, 0x89, - 0x08, 0xF0, 0x3B, 0x89, 0x02, 0xF0, 0x1B, 0xAD, - 0x00, 0x5C, 0xD0, 0x32, 0xA6, 0x24, 0xA9, 0x01, - 0x9D, 0x00, 0x13, 0xA9, 0x01, 0x9D, 0x00, 0x0C, - 0xE8, 0xE4, 0x25, 0xF0, 0x02, 0x86, 0x24, 0x4C, - 0xC4, 0x3B, 0xA6, 0x24, 0xAD, 0x00, 0x5C, 0x9D, - 0x00, 0x0C, 0x9E, 0x00, 0x13, 0xE8, 0xE4, 0x25, - 0xF0, 0x02, 0x86, 0x24, 0x29, 0x7F, 0xC9, 0x13, - 0xD0, 0x04, 0xA5, 0x2F, 0x85, 0x26, 0xAD, 0x02, - 0x5C, 0x29, 0x10, 0xF0, 0x2C, 0xA6, 0x29, 0xF0, - 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x08, 0xD0, 0x21, - 0x8E, 0x00, 0x5C, 0x64, 0x29, 0x4C, 0xF7, 0x3B, - 0xA6, 0x28, 0xE4, 0x27, 0xF0, 0x13, 0xA5, 0x26, - 0xD0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x08, 0xD0, - 0x08, 0xBD, 0x00, 0x05, 0x8D, 0x00, 0x5C, 0xE6, - 0x28, 0xAD, 0x02, 0x64, 0x89, 0x08, 0xF0, 0x3B, - 0x89, 0x02, 0xF0, 0x1B, 0xAD, 0x00, 0x64, 0xD0, - 0x32, 0xA6, 0x30, 0xA9, 0x01, 0x9D, 0x00, 0x14, - 0xA9, 0x01, 0x9D, 0x00, 0x0D, 0xE8, 0xE4, 0x31, - 0xF0, 0x02, 0x86, 0x30, 0x4C, 0x39, 0x3C, 0xA6, - 0x30, 0xAD, 0x00, 0x64, 0x9D, 0x00, 0x0D, 0x9E, - 0x00, 0x14, 0xE8, 0xE4, 0x31, 0xF0, 0x02, 0x86, - 0x30, 0x29, 0x7F, 0xC9, 0x13, 0xD0, 0x04, 0xA5, - 0x3B, 0x85, 0x32, 0xAD, 0x02, 0x64, 0x29, 0x10, - 0xF0, 0x2C, 0xA6, 0x35, 0xF0, 0x0F, 0xAD, 0x02, - 0x7C, 0x29, 0x10, 0xD0, 0x21, 0x8E, 0x00, 0x64, - 0x64, 0x35, 0x4C, 0x6C, 0x3C, 0xA6, 0x34, 0xE4, - 0x33, 0xF0, 0x13, 0xA5, 0x32, 0xD0, 0x0F, 0xAD, - 0x02, 0x7C, 0x29, 0x10, 0xD0, 0x08, 0xBD, 0x00, - 0x06, 0x8D, 0x00, 0x64, 0xE6, 0x34, 0xAD, 0x02, - 0x6C, 0x89, 0x08, 0xF0, 0x3B, 0x89, 0x02, 0xF0, - 0x1B, 0xAD, 0x00, 0x6C, 0xD0, 0x32, 0xA6, 0x3C, - 0xA9, 0x01, 0x9D, 0x00, 0x15, 0xA9, 0x01, 0x9D, - 0x00, 0x0E, 0xE8, 0xE4, 0x3D, 0xF0, 0x02, 0x86, - 0x3C, 0x4C, 0xAE, 0x3C, 0xA6, 0x3C, 0xAD, 0x00, - 0x6C, 0x9D, 0x00, 0x0E, 0x9E, 0x00, 0x15, 0xE8, - 0xE4, 0x3D, 0xF0, 0x02, 0x86, 0x3C, 0x29, 0x7F, - 0xC9, 0x13, 0xD0, 0x04, 0xA5, 0x47, 0x85, 0x3E, - 0xAD, 0x02, 0x6C, 0x29, 0x10, 0xF0, 0x2C, 0xA6, - 0x41, 0xF0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x20, - 0xD0, 0x21, 0x8E, 0x00, 0x6C, 0x64, 0x41, 0x4C, - 0xE1, 0x3C, 0xA6, 0x40, 0xE4, 0x3F, 0xF0, 0x13, - 0xA5, 0x3E, 0xD0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, - 0x20, 0xD0, 0x08, 0xBD, 0x00, 0x07, 0x8D, 0x00, - 0x6C, 0xE6, 0x40, 0xAD, 0x02, 0x74, 0x89, 0x08, - 0xF0, 0x3B, 0x89, 0x02, 0xF0, 0x1B, 0xAD, 0x00, - 0x74, 0xD0, 0x32, 0xA6, 0x48, 0xA9, 0x01, 0x9D, - 0x00, 0x16, 0xA9, 0x01, 0x9D, 0x00, 0x0F, 0xE8, - 0xE4, 0x49, 0xF0, 0x02, 0x86, 0x48, 0x4C, 0x23, - 0x3D, 0xA6, 0x48, 0xAD, 0x00, 0x74, 0x9D, 0x00, - 0x0F, 0x9E, 0x00, 0x16, 0xE8, 0xE4, 0x49, 0xF0, - 0x02, 0x86, 0x48, 0x29, 0x7F, 0xC9, 0x13, 0xD0, - 0x04, 0xA5, 0x53, 0x85, 0x4A, 0xAD, 0x02, 0x74, - 0x29, 0x10, 0xF0, 0x2C, 0xA6, 0x4D, 0xF0, 0x0F, - 0xAD, 0x02, 0x7C, 0x29, 0x40, 0xD0, 0x21, 0x8E, - 0x00, 0x74, 0x64, 0x4D, 0x4C, 0x56, 0x3D, 0xA6, - 0x4C, 0xE4, 0x4B, 0xF0, 0x13, 0xA5, 0x4A, 0xD0, - 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x40, 0xD0, 0x08, - 0xBD, 0x00, 0x08, 0x8D, 0x00, 0x74, 0xE6, 0x4C, - 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0xD0, 0x00, 0x38, - 0xCE, 0xC0, -}; diff --git a/drivers/char/sx.c b/drivers/char/sx.c deleted file mode 100644 index 1291462bcddb..000000000000 --- a/drivers/char/sx.c +++ /dev/null @@ -1,2894 +0,0 @@ -/* sx.c -- driver for the Specialix SX series cards. - * - * This driver will also support the older SI, and XIO cards. - * - * - * (C) 1998 - 2004 R.E.Wolff@BitWizard.nl - * - * Simon Allen (simonallen@cix.compulink.co.uk) wrote a previous - * version of this driver. Some fragments may have been copied. (none - * yet :-) - * - * Specialix pays for the development and support of this driver. - * Please DO contact support@specialix.co.uk if you require - * support. But please read the documentation (sx.txt) first. - * - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, - * USA. - * - * Revision history: - * Revision 1.33 2000/03/09 10:00:00 pvdl,wolff - * - Fixed module and port counting - * - Fixed signal handling - * - Fixed an Ooops - * - * Revision 1.32 2000/03/07 09:00:00 wolff,pvdl - * - Fixed some sx_dprintk typos - * - added detection for an invalid board/module configuration - * - * Revision 1.31 2000/03/06 12:00:00 wolff,pvdl - * - Added support for EISA - * - * Revision 1.30 2000/01/21 17:43:06 wolff - * - Added support for SX+ - * - * Revision 1.26 1999/08/05 15:22:14 wolff - * - Port to 2.3.x - * - Reformatted to Linus' liking. - * - * Revision 1.25 1999/07/30 14:24:08 wolff - * Had accidentally left "gs_debug" set to "-1" instead of "off" (=0). - * - * Revision 1.24 1999/07/28 09:41:52 wolff - * - I noticed the remark about use-count straying in sx.txt. I checked - * sx_open, and found a few places where that could happen. I hope it's - * fixed now. - * - * Revision 1.23 1999/07/28 08:56:06 wolff - * - Fixed crash when sx_firmware run twice. - * - Added sx_slowpoll as a module parameter (I guess nobody really wanted - * to change it from the default... ) - * - Fixed a stupid editing problem I introduced in 1.22. - * - Fixed dropping characters on a termios change. - * - * Revision 1.22 1999/07/26 21:01:43 wolff - * Russell Brown noticed that I had overlooked 4 out of six modem control - * signals in sx_getsignals. Ooops. - * - * Revision 1.21 1999/07/23 09:11:33 wolff - * I forgot to free dynamically allocated memory when the driver is unloaded. - * - * Revision 1.20 1999/07/20 06:25:26 wolff - * The "closing wait" wasn't honoured. Thanks to James Griffiths for - * reporting this. - * - * Revision 1.19 1999/07/11 08:59:59 wolff - * Fixed an oops in close, when an open was pending. Changed the memtest - * a bit. Should also test the board in word-mode, however my card fails the - * memtest then. I still have to figure out what is wrong... - * - * Revision 1.18 1999/06/10 09:38:42 wolff - * Changed the format of the firmware revision from %04x to %x.%02x . - * - * Revision 1.17 1999/06/04 09:44:35 wolff - * fixed problem: reference to pci stuff when config_pci was off... - * Thanks to Jorge Novo for noticing this. - * - * Revision 1.16 1999/06/02 08:30:15 wolff - * added/removed the workaround for the DCD bug in the Firmware. - * A bit more debugging code to locate that... - * - * Revision 1.15 1999/06/01 11:35:30 wolff - * when DCD is left low (floating?), on TA's the firmware first tells us - * that DCD is high, but after a short while suddenly comes to the - * conclusion that it is low. All this would be fine, if it weren't that - * Unix requires us to send a "hangup" signal in that case. This usually - * all happens BEFORE the program has had a chance to ioctl the device - * into clocal mode.. - * - * Revision 1.14 1999/05/25 11:18:59 wolff - * Added PCI-fix. - * Added checks for return code of sx_sendcommand. - * Don't issue "reconfig" if port isn't open yet. (bit us on TA modules...) - * - * Revision 1.13 1999/04/29 15:18:01 wolff - * Fixed an "oops" that showed on SuSE 6.0 systems. - * Activate DTR again after stty 0. - * - * Revision 1.12 1999/04/29 07:49:52 wolff - * Improved "stty 0" handling a bit. (used to change baud to 9600 assuming - * the connection would be dropped anyway. That is not always the case, - * and confuses people). - * Told the card to always monitor the modem signals. - * Added support for dynamic gs_debug adjustments. - * Now tells the rest of the system the number of ports. - * - * Revision 1.11 1999/04/24 11:11:30 wolff - * Fixed two stupid typos in the memory test. - * - * Revision 1.10 1999/04/24 10:53:39 wolff - * Added some of Christian's suggestions. - * Fixed an HW_COOK_IN bug (ISIG was not in I_OTHER. We used to trust the - * card to send the signal to the process.....) - * - * Revision 1.9 1999/04/23 07:26:38 wolff - * Included Christian Lademann's 2.0 compile-warning fixes and interrupt - * assignment redesign. - * Cleanup of some other stuff. - * - * Revision 1.8 1999/04/16 13:05:30 wolff - * fixed a DCD change unnoticed bug. - * - * Revision 1.7 1999/04/14 22:19:51 wolff - * Fixed typo that showed up in 2.0.x builds (get_user instead of Get_user!) - * - * Revision 1.6 1999/04/13 18:40:20 wolff - * changed misc-minor to 161, as assigned by HPA. - * - * Revision 1.5 1999/04/13 15:12:25 wolff - * Fixed use-count leak when "hangup" occurred. - * Added workaround for a stupid-PCIBIOS bug. - * - * - * Revision 1.4 1999/04/01 22:47:40 wolff - * Fixed < 1M linux-2.0 problem. - * (vremap isn't compatible with ioremap in that case) - * - * Revision 1.3 1999/03/31 13:45:45 wolff - * Firmware loading is now done through a separate IOCTL. - * - * Revision 1.2 1999/03/28 12:22:29 wolff - * rcs cleanup - * - * Revision 1.1 1999/03/28 12:10:34 wolff - * Readying for release on 2.0.x (sorry David, 1.01 becomes 1.1 for RCS). - * - * Revision 0.12 1999/03/28 09:20:10 wolff - * Fixed problem in 0.11, continueing cleanup. - * - * Revision 0.11 1999/03/28 08:46:44 wolff - * cleanup. Not good. - * - * Revision 0.10 1999/03/28 08:09:43 wolff - * Fixed loosing characters on close. - * - * Revision 0.9 1999/03/21 22:52:01 wolff - * Ported back to 2.2.... (minor things) - * - * Revision 0.8 1999/03/21 22:40:33 wolff - * Port to 2.0 - * - * Revision 0.7 1999/03/21 19:06:34 wolff - * Fixed hangup processing. - * - * Revision 0.6 1999/02/05 08:45:14 wolff - * fixed real_raw problems. Inclusion into kernel imminent. - * - * Revision 0.5 1998/12/21 23:51:06 wolff - * Snatched a nasty bug: sx_transmit_chars was getting re-entered, and it - * shouldn't have. THATs why I want to have transmit interrupts even when - * the buffer is empty. - * - * Revision 0.4 1998/12/17 09:34:46 wolff - * PPP works. ioctl works. Basically works! - * - * Revision 0.3 1998/12/15 13:05:18 wolff - * It works! Wow! Gotta start implementing IOCTL and stuff.... - * - * Revision 0.2 1998/12/01 08:33:53 wolff - * moved over to 2.1.130 - * - * Revision 0.1 1998/11/03 21:23:51 wolff - * Initial revision. Detects SX card. - * - * */ - -#define SX_VERSION 1.33 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* The 3.0.0 version of sxboards/sxwindow.h uses BYTE and WORD.... */ -#define BYTE u8 -#define WORD u16 - -/* .... but the 3.0.4 version uses _u8 and _u16. */ -#define _u8 u8 -#define _u16 u16 - -#include "sxboards.h" -#include "sxwindow.h" - -#include -#include "sx.h" - -/* I don't think that this driver can handle more than 256 ports on - one machine. You'll have to increase the number of boards in sx.h - if you want more than 4 boards. */ - -#ifndef PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 -#define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000 -#endif - -/* Configurable options: - (Don't be too sure that it'll work if you toggle them) */ - -/* Am I paranoid or not ? ;-) */ -#undef SX_PARANOIA_CHECK - -/* 20 -> 2000 per second. The card should rate-limit interrupts at 100 - Hz, but it is user configurable. I don't recommend going above 1000 - Hz. The interrupt ratelimit might trigger if the interrupt is - shared with a very active other device. */ -#define IRQ_RATE_LIMIT 20 - -/* Sharing interrupts is possible now. If the other device wants more - than 2000 interrupts per second, we'd gracefully decline further - interrupts. That's not what we want. On the other hand, if the - other device interrupts 2000 times a second, don't use the SX - interrupt. Use polling. */ -#undef IRQ_RATE_LIMIT - -#if 0 -/* Not implemented */ -/* - * The following defines are mostly for testing purposes. But if you need - * some nice reporting in your syslog, you can define them also. - */ -#define SX_REPORT_FIFO -#define SX_REPORT_OVERRUN -#endif - -/* Function prototypes */ -static void sx_disable_tx_interrupts(void *ptr); -static void sx_enable_tx_interrupts(void *ptr); -static void sx_disable_rx_interrupts(void *ptr); -static void sx_enable_rx_interrupts(void *ptr); -static int sx_carrier_raised(struct tty_port *port); -static void sx_shutdown_port(void *ptr); -static int sx_set_real_termios(void *ptr); -static void sx_close(void *ptr); -static int sx_chars_in_buffer(void *ptr); -static int sx_init_board(struct sx_board *board); -static int sx_init_portstructs(int nboards, int nports); -static long sx_fw_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg); -static int sx_init_drivers(void); - -static struct tty_driver *sx_driver; - -static DEFINE_MUTEX(sx_boards_lock); -static struct sx_board boards[SX_NBOARDS]; -static struct sx_port *sx_ports; -static int sx_initialized; -static int sx_nports; -static int sx_debug; - -/* You can have the driver poll your card. - - Set sx_poll to 1 to poll every timer tick (10ms on Intel). - This is used when the card cannot use an interrupt for some reason. - - - set sx_slowpoll to 100 to do an extra poll once a second (on Intel). If - the driver misses an interrupt (report this if it DOES happen to you!) - everything will continue to work.... - */ -static int sx_poll = 1; -static int sx_slowpoll; - -/* The card limits the number of interrupts per second. - At 115k2 "100" should be sufficient. - If you're using higher baudrates, you can increase this... - */ - -static int sx_maxints = 100; - -#ifdef CONFIG_ISA - -/* These are the only open spaces in my computer. Yours may have more - or less.... -- REW - duh: Card at 0xa0000 is possible on HP Netserver?? -- pvdl -*/ -static int sx_probe_addrs[] = { - 0xc0000, 0xd0000, 0xe0000, - 0xc8000, 0xd8000, 0xe8000 -}; -static int si_probe_addrs[] = { - 0xc0000, 0xd0000, 0xe0000, - 0xc8000, 0xd8000, 0xe8000, 0xa0000 -}; -static int si1_probe_addrs[] = { - 0xd0000 -}; - -#define NR_SX_ADDRS ARRAY_SIZE(sx_probe_addrs) -#define NR_SI_ADDRS ARRAY_SIZE(si_probe_addrs) -#define NR_SI1_ADDRS ARRAY_SIZE(si1_probe_addrs) - -module_param_array(sx_probe_addrs, int, NULL, 0); -module_param_array(si_probe_addrs, int, NULL, 0); -#endif - -/* Set the mask to all-ones. This alas, only supports 32 interrupts. - Some architectures may need more. */ -static int sx_irqmask = -1; - -module_param(sx_poll, int, 0); -module_param(sx_slowpoll, int, 0); -module_param(sx_maxints, int, 0); -module_param(sx_debug, int, 0); -module_param(sx_irqmask, int, 0); - -MODULE_LICENSE("GPL"); - -static struct real_driver sx_real_driver = { - sx_disable_tx_interrupts, - sx_enable_tx_interrupts, - sx_disable_rx_interrupts, - sx_enable_rx_interrupts, - sx_shutdown_port, - sx_set_real_termios, - sx_chars_in_buffer, - sx_close, -}; - -/* - This driver can spew a whole lot of debugging output at you. If you - need maximum performance, you should disable the DEBUG define. To - aid in debugging in the field, I'm leaving the compile-time debug - features enabled, and disable them "runtime". That allows me to - instruct people with problems to enable debugging without requiring - them to recompile... -*/ -#define DEBUG - -#ifdef DEBUG -#define sx_dprintk(f, str...) if (sx_debug & f) printk (str) -#else -#define sx_dprintk(f, str...) /* nothing */ -#endif - -#define func_enter() sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s\n",__func__) -#define func_exit() sx_dprintk(SX_DEBUG_FLOW, "sx: exit %s\n",__func__) - -#define func_enter2() sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s (port %d)\n", \ - __func__, port->line) - -/* - * Firmware loader driver specific routines - * - */ - -static const struct file_operations sx_fw_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = sx_fw_ioctl, - .llseek = noop_llseek, -}; - -static struct miscdevice sx_fw_device = { - SXCTL_MISC_MINOR, "sxctl", &sx_fw_fops -}; - -#ifdef SX_PARANOIA_CHECK - -/* This doesn't work. Who's paranoid around here? Not me! */ - -static inline int sx_paranoia_check(struct sx_port const *port, - char *name, const char *routine) -{ - static const char *badmagic = KERN_ERR "sx: Warning: bad sx port magic " - "number for device %s in %s\n"; - static const char *badinfo = KERN_ERR "sx: Warning: null sx port for " - "device %s in %s\n"; - - if (!port) { - printk(badinfo, name, routine); - return 1; - } - if (port->magic != SX_MAGIC) { - printk(badmagic, name, routine); - return 1; - } - - return 0; -} -#else -#define sx_paranoia_check(a,b,c) 0 -#endif - -/* The timeouts. First try 30 times as fast as possible. Then give - the card some time to breathe between accesses. (Otherwise the - processor on the card might not be able to access its OWN bus... */ - -#define TIMEOUT_1 30 -#define TIMEOUT_2 1000000 - -#ifdef DEBUG -static void my_hd_io(void __iomem *p, int len) -{ - int i, j, ch; - unsigned char __iomem *addr = p; - - for (i = 0; i < len; i += 16) { - printk("%p ", addr + i); - for (j = 0; j < 16; j++) { - printk("%02x %s", readb(addr + j + i), - (j == 7) ? " " : ""); - } - for (j = 0; j < 16; j++) { - ch = readb(addr + j + i); - printk("%c", (ch < 0x20) ? '.' : - ((ch > 0x7f) ? '.' : ch)); - } - printk("\n"); - } -} -static void my_hd(void *p, int len) -{ - int i, j, ch; - unsigned char *addr = p; - - for (i = 0; i < len; i += 16) { - printk("%p ", addr + i); - for (j = 0; j < 16; j++) { - printk("%02x %s", addr[j + i], (j == 7) ? " " : ""); - } - for (j = 0; j < 16; j++) { - ch = addr[j + i]; - printk("%c", (ch < 0x20) ? '.' : - ((ch > 0x7f) ? '.' : ch)); - } - printk("\n"); - } -} -#endif - -/* This needs redoing for Alpha -- REW -- Done. */ - -static inline void write_sx_byte(struct sx_board *board, int offset, u8 byte) -{ - writeb(byte, board->base + offset); -} - -static inline u8 read_sx_byte(struct sx_board *board, int offset) -{ - return readb(board->base + offset); -} - -static inline void write_sx_word(struct sx_board *board, int offset, u16 word) -{ - writew(word, board->base + offset); -} - -static inline u16 read_sx_word(struct sx_board *board, int offset) -{ - return readw(board->base + offset); -} - -static int sx_busy_wait_eq(struct sx_board *board, - int offset, int mask, int correctval) -{ - int i; - - func_enter(); - - for (i = 0; i < TIMEOUT_1; i++) - if ((read_sx_byte(board, offset) & mask) == correctval) { - func_exit(); - return 1; - } - - for (i = 0; i < TIMEOUT_2; i++) { - if ((read_sx_byte(board, offset) & mask) == correctval) { - func_exit(); - return 1; - } - udelay(1); - } - - func_exit(); - return 0; -} - -static int sx_busy_wait_neq(struct sx_board *board, - int offset, int mask, int badval) -{ - int i; - - func_enter(); - - for (i = 0; i < TIMEOUT_1; i++) - if ((read_sx_byte(board, offset) & mask) != badval) { - func_exit(); - return 1; - } - - for (i = 0; i < TIMEOUT_2; i++) { - if ((read_sx_byte(board, offset) & mask) != badval) { - func_exit(); - return 1; - } - udelay(1); - } - - func_exit(); - return 0; -} - -/* 5.6.4 of 6210028 r2.3 */ -static int sx_reset(struct sx_board *board) -{ - func_enter(); - - if (IS_SX_BOARD(board)) { - - write_sx_byte(board, SX_CONFIG, 0); - write_sx_byte(board, SX_RESET, 1); /* Value doesn't matter */ - - if (!sx_busy_wait_eq(board, SX_RESET_STATUS, 1, 0)) { - printk(KERN_INFO "sx: Card doesn't respond to " - "reset...\n"); - return 0; - } - } else if (IS_EISA_BOARD(board)) { - outb(board->irq << 4, board->eisa_base + 0xc02); - } else if (IS_SI1_BOARD(board)) { - write_sx_byte(board, SI1_ISA_RESET, 0); /*value doesn't matter*/ - } else { - /* Gory details of the SI/ISA board */ - write_sx_byte(board, SI2_ISA_RESET, SI2_ISA_RESET_SET); - write_sx_byte(board, SI2_ISA_IRQ11, SI2_ISA_IRQ11_CLEAR); - write_sx_byte(board, SI2_ISA_IRQ12, SI2_ISA_IRQ12_CLEAR); - write_sx_byte(board, SI2_ISA_IRQ15, SI2_ISA_IRQ15_CLEAR); - write_sx_byte(board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_CLEAR); - write_sx_byte(board, SI2_ISA_IRQSET, SI2_ISA_IRQSET_CLEAR); - } - - func_exit(); - return 1; -} - -/* This doesn't work on machines where "NULL" isn't 0 */ -/* If you have one of those, someone will need to write - the equivalent of this, which will amount to about 3 lines. I don't - want to complicate this right now. -- REW - (See, I do write comments every now and then :-) */ -#define OFFSETOF(strct, elem) ((long)&(((struct strct *)NULL)->elem)) - -#define CHAN_OFFSET(port,elem) (port->ch_base + OFFSETOF (_SXCHANNEL, elem)) -#define MODU_OFFSET(board,addr,elem) (addr + OFFSETOF (_SXMODULE, elem)) -#define BRD_OFFSET(board,elem) (OFFSETOF (_SXCARD, elem)) - -#define sx_write_channel_byte(port, elem, val) \ - write_sx_byte (port->board, CHAN_OFFSET (port, elem), val) - -#define sx_read_channel_byte(port, elem) \ - read_sx_byte (port->board, CHAN_OFFSET (port, elem)) - -#define sx_write_channel_word(port, elem, val) \ - write_sx_word (port->board, CHAN_OFFSET (port, elem), val) - -#define sx_read_channel_word(port, elem) \ - read_sx_word (port->board, CHAN_OFFSET (port, elem)) - -#define sx_write_module_byte(board, addr, elem, val) \ - write_sx_byte (board, MODU_OFFSET (board, addr, elem), val) - -#define sx_read_module_byte(board, addr, elem) \ - read_sx_byte (board, MODU_OFFSET (board, addr, elem)) - -#define sx_write_module_word(board, addr, elem, val) \ - write_sx_word (board, MODU_OFFSET (board, addr, elem), val) - -#define sx_read_module_word(board, addr, elem) \ - read_sx_word (board, MODU_OFFSET (board, addr, elem)) - -#define sx_write_board_byte(board, elem, val) \ - write_sx_byte (board, BRD_OFFSET (board, elem), val) - -#define sx_read_board_byte(board, elem) \ - read_sx_byte (board, BRD_OFFSET (board, elem)) - -#define sx_write_board_word(board, elem, val) \ - write_sx_word (board, BRD_OFFSET (board, elem), val) - -#define sx_read_board_word(board, elem) \ - read_sx_word (board, BRD_OFFSET (board, elem)) - -static int sx_start_board(struct sx_board *board) -{ - if (IS_SX_BOARD(board)) { - write_sx_byte(board, SX_CONFIG, SX_CONF_BUSEN); - } else if (IS_EISA_BOARD(board)) { - write_sx_byte(board, SI2_EISA_OFF, SI2_EISA_VAL); - outb((board->irq << 4) | 4, board->eisa_base + 0xc02); - } else if (IS_SI1_BOARD(board)) { - write_sx_byte(board, SI1_ISA_RESET_CLEAR, 0); - write_sx_byte(board, SI1_ISA_INTCL, 0); - } else { - /* Don't bug me about the clear_set. - I haven't the foggiest idea what it's about -- REW */ - write_sx_byte(board, SI2_ISA_RESET, SI2_ISA_RESET_CLEAR); - write_sx_byte(board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET); - } - return 1; -} - -#define SX_IRQ_REG_VAL(board) \ - ((board->flags & SX_ISA_BOARD) ? (board->irq << 4) : 0) - -/* Note. The SX register is write-only. Therefore, we have to enable the - bus too. This is a no-op, if you don't mess with this driver... */ -static int sx_start_interrupts(struct sx_board *board) -{ - - /* Don't call this with board->irq == 0 */ - - if (IS_SX_BOARD(board)) { - write_sx_byte(board, SX_CONFIG, SX_IRQ_REG_VAL(board) | - SX_CONF_BUSEN | SX_CONF_HOSTIRQ); - } else if (IS_EISA_BOARD(board)) { - inb(board->eisa_base + 0xc03); - } else if (IS_SI1_BOARD(board)) { - write_sx_byte(board, SI1_ISA_INTCL, 0); - write_sx_byte(board, SI1_ISA_INTCL_CLEAR, 0); - } else { - switch (board->irq) { - case 11: - write_sx_byte(board, SI2_ISA_IRQ11, SI2_ISA_IRQ11_SET); - break; - case 12: - write_sx_byte(board, SI2_ISA_IRQ12, SI2_ISA_IRQ12_SET); - break; - case 15: - write_sx_byte(board, SI2_ISA_IRQ15, SI2_ISA_IRQ15_SET); - break; - default: - printk(KERN_INFO "sx: SI/XIO card doesn't support " - "interrupt %d.\n", board->irq); - return 0; - } - write_sx_byte(board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET); - } - - return 1; -} - -static int sx_send_command(struct sx_port *port, - int command, int mask, int newstat) -{ - func_enter2(); - write_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat), command); - func_exit(); - return sx_busy_wait_eq(port->board, CHAN_OFFSET(port, hi_hstat), mask, - newstat); -} - -static char *mod_type_s(int module_type) -{ - switch (module_type) { - case TA4: - return "TA4"; - case TA8: - return "TA8"; - case TA4_ASIC: - return "TA4_ASIC"; - case TA8_ASIC: - return "TA8_ASIC"; - case MTA_CD1400: - return "MTA_CD1400"; - case SXDC: - return "SXDC"; - default: - return "Unknown/invalid"; - } -} - -static char *pan_type_s(int pan_type) -{ - switch (pan_type) { - case MOD_RS232DB25: - return "MOD_RS232DB25"; - case MOD_RS232RJ45: - return "MOD_RS232RJ45"; - case MOD_RS422DB25: - return "MOD_RS422DB25"; - case MOD_PARALLEL: - return "MOD_PARALLEL"; - case MOD_2_RS232DB25: - return "MOD_2_RS232DB25"; - case MOD_2_RS232RJ45: - return "MOD_2_RS232RJ45"; - case MOD_2_RS422DB25: - return "MOD_2_RS422DB25"; - case MOD_RS232DB25MALE: - return "MOD_RS232DB25MALE"; - case MOD_2_PARALLEL: - return "MOD_2_PARALLEL"; - case MOD_BLANK: - return "empty"; - default: - return "invalid"; - } -} - -static int mod_compat_type(int module_type) -{ - return module_type >> 4; -} - -static void sx_reconfigure_port(struct sx_port *port) -{ - if (sx_read_channel_byte(port, hi_hstat) == HS_IDLE_OPEN) { - if (sx_send_command(port, HS_CONFIG, -1, HS_IDLE_OPEN) != 1) { - printk(KERN_WARNING "sx: Sent reconfigure command, but " - "card didn't react.\n"); - } - } else { - sx_dprintk(SX_DEBUG_TERMIOS, "sx: Not sending reconfigure: " - "port isn't open (%02x).\n", - sx_read_channel_byte(port, hi_hstat)); - } -} - -static void sx_setsignals(struct sx_port *port, int dtr, int rts) -{ - int t; - func_enter2(); - - t = sx_read_channel_byte(port, hi_op); - if (dtr >= 0) - t = dtr ? (t | OP_DTR) : (t & ~OP_DTR); - if (rts >= 0) - t = rts ? (t | OP_RTS) : (t & ~OP_RTS); - sx_write_channel_byte(port, hi_op, t); - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "setsignals: %d/%d\n", dtr, rts); - - func_exit(); -} - -static int sx_getsignals(struct sx_port *port) -{ - int i_stat, o_stat; - - o_stat = sx_read_channel_byte(port, hi_op); - i_stat = sx_read_channel_byte(port, hi_ip); - - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "getsignals: %d/%d (%d/%d) " - "%02x/%02x\n", - (o_stat & OP_DTR) != 0, (o_stat & OP_RTS) != 0, - port->c_dcd, tty_port_carrier_raised(&port->gs.port), - sx_read_channel_byte(port, hi_ip), - sx_read_channel_byte(port, hi_state)); - - return (((o_stat & OP_DTR) ? TIOCM_DTR : 0) | - ((o_stat & OP_RTS) ? TIOCM_RTS : 0) | - ((i_stat & IP_CTS) ? TIOCM_CTS : 0) | - ((i_stat & IP_DCD) ? TIOCM_CAR : 0) | - ((i_stat & IP_DSR) ? TIOCM_DSR : 0) | - ((i_stat & IP_RI) ? TIOCM_RNG : 0)); -} - -static void sx_set_baud(struct sx_port *port) -{ - int t; - - if (port->board->ta_type == MOD_SXDC) { - switch (port->gs.baud) { - /* Save some typing work... */ -#define e(x) case x: t = BAUD_ ## x; break - e(50); - e(75); - e(110); - e(150); - e(200); - e(300); - e(600); - e(1200); - e(1800); - e(2000); - e(2400); - e(4800); - e(7200); - e(9600); - e(14400); - e(19200); - e(28800); - e(38400); - e(56000); - e(57600); - e(64000); - e(76800); - e(115200); - e(128000); - e(150000); - e(230400); - e(256000); - e(460800); - e(921600); - case 134: - t = BAUD_134_5; - break; - case 0: - t = -1; - break; - default: - /* Can I return "invalid"? */ - t = BAUD_9600; - printk(KERN_INFO "sx: unsupported baud rate: %d.\n", - port->gs.baud); - break; - } -#undef e - if (t > 0) { -/* The baud rate is not set to 0, so we're enabeling DTR... -- REW */ - sx_setsignals(port, 1, -1); - /* XXX This is not TA & MTA compatible */ - sx_write_channel_byte(port, hi_csr, 0xff); - - sx_write_channel_byte(port, hi_txbaud, t); - sx_write_channel_byte(port, hi_rxbaud, t); - } else { - sx_setsignals(port, 0, -1); - } - } else { - switch (port->gs.baud) { -#define e(x) case x: t = CSR_ ## x; break - e(75); - e(150); - e(300); - e(600); - e(1200); - e(2400); - e(4800); - e(1800); - e(9600); - e(19200); - e(57600); - e(38400); -/* TA supports 110, but not 115200, MTA supports 115200, but not 110 */ - case 110: - if (port->board->ta_type == MOD_TA) { - t = CSR_110; - break; - } else { - t = CSR_9600; - printk(KERN_INFO "sx: Unsupported baud rate: " - "%d.\n", port->gs.baud); - break; - } - case 115200: - if (port->board->ta_type == MOD_TA) { - t = CSR_9600; - printk(KERN_INFO "sx: Unsupported baud rate: " - "%d.\n", port->gs.baud); - break; - } else { - t = CSR_110; - break; - } - case 0: - t = -1; - break; - default: - t = CSR_9600; - printk(KERN_INFO "sx: Unsupported baud rate: %d.\n", - port->gs.baud); - break; - } -#undef e - if (t >= 0) { - sx_setsignals(port, 1, -1); - sx_write_channel_byte(port, hi_csr, t * 0x11); - } else { - sx_setsignals(port, 0, -1); - } - } -} - -/* Simon Allen's version of this routine was 225 lines long. 85 is a lot - better. -- REW */ - -static int sx_set_real_termios(void *ptr) -{ - struct sx_port *port = ptr; - - func_enter2(); - - if (!port->gs.port.tty) - return 0; - - /* What is this doing here? -- REW - Ha! figured it out. It is to allow you to get DTR active again - if you've dropped it with stty 0. Moved to set_baud, where it - belongs (next to the drop dtr if baud == 0) -- REW */ - /* sx_setsignals (port, 1, -1); */ - - sx_set_baud(port); - -#define CFLAG port->gs.port.tty->termios->c_cflag - sx_write_channel_byte(port, hi_mr1, - (C_PARENB(port->gs.port.tty) ? MR1_WITH : MR1_NONE) | - (C_PARODD(port->gs.port.tty) ? MR1_ODD : MR1_EVEN) | - (C_CRTSCTS(port->gs.port.tty) ? MR1_RTS_RXFLOW : 0) | - (((CFLAG & CSIZE) == CS8) ? MR1_8_BITS : 0) | - (((CFLAG & CSIZE) == CS7) ? MR1_7_BITS : 0) | - (((CFLAG & CSIZE) == CS6) ? MR1_6_BITS : 0) | - (((CFLAG & CSIZE) == CS5) ? MR1_5_BITS : 0)); - - sx_write_channel_byte(port, hi_mr2, - (C_CRTSCTS(port->gs.port.tty) ? MR2_CTS_TXFLOW : 0) | - (C_CSTOPB(port->gs.port.tty) ? MR2_2_STOP : - MR2_1_STOP)); - - switch (CFLAG & CSIZE) { - case CS8: - sx_write_channel_byte(port, hi_mask, 0xff); - break; - case CS7: - sx_write_channel_byte(port, hi_mask, 0x7f); - break; - case CS6: - sx_write_channel_byte(port, hi_mask, 0x3f); - break; - case CS5: - sx_write_channel_byte(port, hi_mask, 0x1f); - break; - default: - printk(KERN_INFO "sx: Invalid wordsize: %u\n", - (unsigned int)CFLAG & CSIZE); - break; - } - - sx_write_channel_byte(port, hi_prtcl, - (I_IXON(port->gs.port.tty) ? SP_TXEN : 0) | - (I_IXOFF(port->gs.port.tty) ? SP_RXEN : 0) | - (I_IXANY(port->gs.port.tty) ? SP_TANY : 0) | SP_DCEN); - - sx_write_channel_byte(port, hi_break, - (I_IGNBRK(port->gs.port.tty) ? BR_IGN : 0 | - I_BRKINT(port->gs.port.tty) ? BR_INT : 0)); - - sx_write_channel_byte(port, hi_txon, START_CHAR(port->gs.port.tty)); - sx_write_channel_byte(port, hi_rxon, START_CHAR(port->gs.port.tty)); - sx_write_channel_byte(port, hi_txoff, STOP_CHAR(port->gs.port.tty)); - sx_write_channel_byte(port, hi_rxoff, STOP_CHAR(port->gs.port.tty)); - - sx_reconfigure_port(port); - - /* Tell line discipline whether we will do input cooking */ - if (I_OTHER(port->gs.port.tty)) { - clear_bit(TTY_HW_COOK_IN, &port->gs.port.tty->flags); - } else { - set_bit(TTY_HW_COOK_IN, &port->gs.port.tty->flags); - } - sx_dprintk(SX_DEBUG_TERMIOS, "iflags: %x(%d) ", - (unsigned int)port->gs.port.tty->termios->c_iflag, - I_OTHER(port->gs.port.tty)); - -/* Tell line discipline whether we will do output cooking. - * If OPOST is set and no other output flags are set then we can do output - * processing. Even if only *one* other flag in the O_OTHER group is set - * we do cooking in software. - */ - if (O_OPOST(port->gs.port.tty) && !O_OTHER(port->gs.port.tty)) { - set_bit(TTY_HW_COOK_OUT, &port->gs.port.tty->flags); - } else { - clear_bit(TTY_HW_COOK_OUT, &port->gs.port.tty->flags); - } - sx_dprintk(SX_DEBUG_TERMIOS, "oflags: %x(%d)\n", - (unsigned int)port->gs.port.tty->termios->c_oflag, - O_OTHER(port->gs.port.tty)); - /* port->c_dcd = sx_get_CD (port); */ - func_exit(); - return 0; -} - -/* ********************************************************************** * - * the interrupt related routines * - * ********************************************************************** */ - -/* Note: - Other drivers use the macro "MIN" to calculate how much to copy. - This has the disadvantage that it will evaluate parts twice. That's - expensive when it's IO (and the compiler cannot optimize those away!). - Moreover, I'm not sure that you're race-free. - - I assign a value, and then only allow the value to decrease. This - is always safe. This makes the code a few lines longer, and you - know I'm dead against that, but I think it is required in this - case. */ - -static void sx_transmit_chars(struct sx_port *port) -{ - int c; - int tx_ip; - int txroom; - - func_enter2(); - sx_dprintk(SX_DEBUG_TRANSMIT, "Port %p: transmit %d chars\n", - port, port->gs.xmit_cnt); - - if (test_and_set_bit(SX_PORT_TRANSMIT_LOCK, &port->locks)) { - return; - } - - while (1) { - c = port->gs.xmit_cnt; - - sx_dprintk(SX_DEBUG_TRANSMIT, "Copying %d ", c); - tx_ip = sx_read_channel_byte(port, hi_txipos); - - /* Took me 5 minutes to deduce this formula. - Luckily it is literally in the manual in section 6.5.4.3.5 */ - txroom = (sx_read_channel_byte(port, hi_txopos) - tx_ip - 1) & - 0xff; - - /* Don't copy more bytes than there is room for in the buffer */ - if (c > txroom) - c = txroom; - sx_dprintk(SX_DEBUG_TRANSMIT, " %d(%d) ", c, txroom); - - /* Don't copy past the end of the hardware transmit buffer */ - if (c > 0x100 - tx_ip) - c = 0x100 - tx_ip; - - sx_dprintk(SX_DEBUG_TRANSMIT, " %d(%d) ", c, 0x100 - tx_ip); - - /* Don't copy pas the end of the source buffer */ - if (c > SERIAL_XMIT_SIZE - port->gs.xmit_tail) - c = SERIAL_XMIT_SIZE - port->gs.xmit_tail; - - sx_dprintk(SX_DEBUG_TRANSMIT, " %d(%ld) \n", - c, SERIAL_XMIT_SIZE - port->gs.xmit_tail); - - /* If for one reason or another, we can't copy more data, we're - done! */ - if (c == 0) - break; - - memcpy_toio(port->board->base + CHAN_OFFSET(port, hi_txbuf) + - tx_ip, port->gs.xmit_buf + port->gs.xmit_tail, c); - - /* Update the pointer in the card */ - sx_write_channel_byte(port, hi_txipos, (tx_ip + c) & 0xff); - - /* Update the kernel buffer end */ - port->gs.xmit_tail = (port->gs.xmit_tail + c) & - (SERIAL_XMIT_SIZE - 1); - - /* This one last. (this is essential) - It would allow others to start putting more data into the - buffer! */ - port->gs.xmit_cnt -= c; - } - - if (port->gs.xmit_cnt == 0) { - sx_disable_tx_interrupts(port); - } - - if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.port.tty) { - tty_wakeup(port->gs.port.tty); - sx_dprintk(SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n", - port->gs.wakeup_chars); - } - - clear_bit(SX_PORT_TRANSMIT_LOCK, &port->locks); - func_exit(); -} - -/* Note the symmetry between receiving chars and transmitting them! - Note: The kernel should have implemented both a receive buffer and - a transmit buffer. */ - -/* Inlined: Called only once. Remove the inline when you add another call */ -static inline void sx_receive_chars(struct sx_port *port) -{ - int c; - int rx_op; - struct tty_struct *tty; - int copied = 0; - unsigned char *rp; - - func_enter2(); - tty = port->gs.port.tty; - while (1) { - rx_op = sx_read_channel_byte(port, hi_rxopos); - c = (sx_read_channel_byte(port, hi_rxipos) - rx_op) & 0xff; - - sx_dprintk(SX_DEBUG_RECEIVE, "rxop=%d, c = %d.\n", rx_op, c); - - /* Don't copy past the end of the hardware receive buffer */ - if (rx_op + c > 0x100) - c = 0x100 - rx_op; - - sx_dprintk(SX_DEBUG_RECEIVE, "c = %d.\n", c); - - /* Don't copy more bytes than there is room for in the buffer */ - - c = tty_prepare_flip_string(tty, &rp, c); - - sx_dprintk(SX_DEBUG_RECEIVE, "c = %d.\n", c); - - /* If for one reason or another, we can't copy more data, we're done! */ - if (c == 0) - break; - - sx_dprintk(SX_DEBUG_RECEIVE, "Copying over %d chars. First is " - "%d at %lx\n", c, read_sx_byte(port->board, - CHAN_OFFSET(port, hi_rxbuf) + rx_op), - CHAN_OFFSET(port, hi_rxbuf)); - memcpy_fromio(rp, port->board->base + - CHAN_OFFSET(port, hi_rxbuf) + rx_op, c); - - /* This one last. ( Not essential.) - It allows the card to start putting more data into the - buffer! - Update the pointer in the card */ - sx_write_channel_byte(port, hi_rxopos, (rx_op + c) & 0xff); - - copied += c; - } - if (copied) { - struct timeval tv; - - do_gettimeofday(&tv); - sx_dprintk(SX_DEBUG_RECEIVE, "pushing flipq port %d (%3d " - "chars): %d.%06d (%d/%d)\n", port->line, - copied, (int)(tv.tv_sec % 60), (int)tv.tv_usec, - tty->raw, tty->real_raw); - - /* Tell the rest of the system the news. Great news. New - characters! */ - tty_flip_buffer_push(tty); - /* tty_schedule_flip (tty); */ - } - - func_exit(); -} - -/* Inlined: it is called only once. Remove the inline if you add another - call */ -static inline void sx_check_modem_signals(struct sx_port *port) -{ - int hi_state; - int c_dcd; - - hi_state = sx_read_channel_byte(port, hi_state); - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "Checking modem signals (%d/%d)\n", - port->c_dcd, tty_port_carrier_raised(&port->gs.port)); - - if (hi_state & ST_BREAK) { - hi_state &= ~ST_BREAK; - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "got a break.\n"); - sx_write_channel_byte(port, hi_state, hi_state); - gs_got_break(&port->gs); - } - if (hi_state & ST_DCD) { - hi_state &= ~ST_DCD; - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "got a DCD change.\n"); - sx_write_channel_byte(port, hi_state, hi_state); - c_dcd = tty_port_carrier_raised(&port->gs.port); - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD is now %d\n", c_dcd); - if (c_dcd != port->c_dcd) { - port->c_dcd = c_dcd; - if (tty_port_carrier_raised(&port->gs.port)) { - /* DCD went UP */ - if ((sx_read_channel_byte(port, hi_hstat) != - HS_IDLE_CLOSED) && - !(port->gs.port.tty->termios-> - c_cflag & CLOCAL)) { - /* Are we blocking in open? */ - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " - "active, unblocking open\n"); - wake_up_interruptible(&port->gs.port. - open_wait); - } else { - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " - "raised. Ignoring.\n"); - } - } else { - /* DCD went down! */ - if (!(port->gs.port.tty->termios->c_cflag & CLOCAL)){ - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " - "dropped. hanging up....\n"); - tty_hangup(port->gs.port.tty); - } else { - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " - "dropped. ignoring.\n"); - } - } - } else { - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "Hmmm. card told us " - "DCD changed, but it didn't.\n"); - } - } -} - -/* This is what an interrupt routine should look like. - * Small, elegant, clear. - */ - -static irqreturn_t sx_interrupt(int irq, void *ptr) -{ - struct sx_board *board = ptr; - struct sx_port *port; - int i; - - func_enter(); - sx_dprintk(SX_DEBUG_FLOW, "sx: enter sx_interrupt (%d/%d)\n", irq, - board->irq); - - /* AAargh! The order in which to do these things is essential and - not trivial. - - - Rate limit goes before "recursive". Otherwise a series of - recursive calls will hang the machine in the interrupt routine. - - - hardware twiddling goes before "recursive". Otherwise when we - poll the card, and a recursive interrupt happens, we won't - ack the card, so it might keep on interrupting us. (especially - level sensitive interrupt systems like PCI). - - - Rate limit goes before hardware twiddling. Otherwise we won't - catch a card that has gone bonkers. - - - The "initialized" test goes after the hardware twiddling. Otherwise - the card will stick us in the interrupt routine again. - - - The initialized test goes before recursive. - */ - -#ifdef IRQ_RATE_LIMIT - /* Aaargh! I'm ashamed. This costs more lines-of-code than the - actual interrupt routine!. (Well, used to when I wrote that - comment) */ - { - static int lastjif; - static int nintr = 0; - - if (lastjif == jiffies) { - if (++nintr > IRQ_RATE_LIMIT) { - free_irq(board->irq, board); - printk(KERN_ERR "sx: Too many interrupts. " - "Turning off interrupt %d.\n", - board->irq); - } - } else { - lastjif = jiffies; - nintr = 0; - } - } -#endif - - if (board->irq == irq) { - /* Tell the card we've noticed the interrupt. */ - - sx_write_board_word(board, cc_int_pending, 0); - if (IS_SX_BOARD(board)) { - write_sx_byte(board, SX_RESET_IRQ, 1); - } else if (IS_EISA_BOARD(board)) { - inb(board->eisa_base + 0xc03); - write_sx_word(board, 8, 0); - } else { - write_sx_byte(board, SI2_ISA_INTCLEAR, - SI2_ISA_INTCLEAR_CLEAR); - write_sx_byte(board, SI2_ISA_INTCLEAR, - SI2_ISA_INTCLEAR_SET); - } - } - - if (!sx_initialized) - return IRQ_HANDLED; - if (!(board->flags & SX_BOARD_INITIALIZED)) - return IRQ_HANDLED; - - if (test_and_set_bit(SX_BOARD_INTR_LOCK, &board->locks)) { - printk(KERN_ERR "Recursive interrupt! (%d)\n", board->irq); - return IRQ_HANDLED; - } - - for (i = 0; i < board->nports; i++) { - port = &board->ports[i]; - if (port->gs.port.flags & GS_ACTIVE) { - if (sx_read_channel_byte(port, hi_state)) { - sx_dprintk(SX_DEBUG_INTERRUPTS, "Port %d: " - "modem signal change?... \n",i); - sx_check_modem_signals(port); - } - if (port->gs.xmit_cnt) { - sx_transmit_chars(port); - } - if (!(port->gs.port.flags & SX_RX_THROTTLE)) { - sx_receive_chars(port); - } - } - } - - clear_bit(SX_BOARD_INTR_LOCK, &board->locks); - - sx_dprintk(SX_DEBUG_FLOW, "sx: exit sx_interrupt (%d/%d)\n", irq, - board->irq); - func_exit(); - return IRQ_HANDLED; -} - -static void sx_pollfunc(unsigned long data) -{ - struct sx_board *board = (struct sx_board *)data; - - func_enter(); - - sx_interrupt(0, board); - - mod_timer(&board->timer, jiffies + sx_poll); - func_exit(); -} - -/* ********************************************************************** * - * Here are the routines that actually * - * interface with the generic_serial driver * - * ********************************************************************** */ - -/* Ehhm. I don't know how to fiddle with interrupts on the SX card. --REW */ -/* Hmm. Ok I figured it out. You don't. */ - -static void sx_disable_tx_interrupts(void *ptr) -{ - struct sx_port *port = ptr; - func_enter2(); - - port->gs.port.flags &= ~GS_TX_INTEN; - - func_exit(); -} - -static void sx_enable_tx_interrupts(void *ptr) -{ - struct sx_port *port = ptr; - int data_in_buffer; - func_enter2(); - - /* First transmit the characters that we're supposed to */ - sx_transmit_chars(port); - - /* The sx card will never interrupt us if we don't fill the buffer - past 25%. So we keep considering interrupts off if that's the case. */ - data_in_buffer = (sx_read_channel_byte(port, hi_txipos) - - sx_read_channel_byte(port, hi_txopos)) & 0xff; - - /* XXX Must be "HIGH_WATER" for SI card according to doc. */ - if (data_in_buffer < LOW_WATER) - port->gs.port.flags &= ~GS_TX_INTEN; - - func_exit(); -} - -static void sx_disable_rx_interrupts(void *ptr) -{ - /* struct sx_port *port = ptr; */ - func_enter(); - - func_exit(); -} - -static void sx_enable_rx_interrupts(void *ptr) -{ - /* struct sx_port *port = ptr; */ - func_enter(); - - func_exit(); -} - -/* Jeez. Isn't this simple? */ -static int sx_carrier_raised(struct tty_port *port) -{ - struct sx_port *sp = container_of(port, struct sx_port, gs.port); - return ((sx_read_channel_byte(sp, hi_ip) & IP_DCD) != 0); -} - -/* Jeez. Isn't this simple? */ -static int sx_chars_in_buffer(void *ptr) -{ - struct sx_port *port = ptr; - func_enter2(); - - func_exit(); - return ((sx_read_channel_byte(port, hi_txipos) - - sx_read_channel_byte(port, hi_txopos)) & 0xff); -} - -static void sx_shutdown_port(void *ptr) -{ - struct sx_port *port = ptr; - - func_enter(); - - port->gs.port.flags &= ~GS_ACTIVE; - if (port->gs.port.tty && (port->gs.port.tty->termios->c_cflag & HUPCL)) { - sx_setsignals(port, 0, 0); - sx_reconfigure_port(port); - } - - func_exit(); -} - -/* ********************************************************************** * - * Here are the routines that actually * - * interface with the rest of the system * - * ********************************************************************** */ - -static int sx_open(struct tty_struct *tty, struct file *filp) -{ - struct sx_port *port; - int retval, line; - unsigned long flags; - - func_enter(); - - if (!sx_initialized) { - return -EIO; - } - - line = tty->index; - sx_dprintk(SX_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p, " - "np=%d)\n", task_pid_nr(current), line, tty, - current->signal->tty, sx_nports); - - if ((line < 0) || (line >= SX_NPORTS) || (line >= sx_nports)) - return -ENODEV; - - port = &sx_ports[line]; - port->c_dcd = 0; /* Make sure that the first interrupt doesn't detect a - 1 -> 0 transition. */ - - sx_dprintk(SX_DEBUG_OPEN, "port = %p c_dcd = %d\n", port, port->c_dcd); - - spin_lock_irqsave(&port->gs.driver_lock, flags); - - tty->driver_data = port; - port->gs.port.tty = tty; - port->gs.port.count++; - spin_unlock_irqrestore(&port->gs.driver_lock, flags); - - sx_dprintk(SX_DEBUG_OPEN, "starting port\n"); - - /* - * Start up serial port - */ - retval = gs_init_port(&port->gs); - sx_dprintk(SX_DEBUG_OPEN, "done gs_init\n"); - if (retval) { - port->gs.port.count--; - return retval; - } - - port->gs.port.flags |= GS_ACTIVE; - if (port->gs.port.count <= 1) - sx_setsignals(port, 1, 1); - -#if 0 - if (sx_debug & SX_DEBUG_OPEN) - my_hd(port, sizeof(*port)); -#else - if (sx_debug & SX_DEBUG_OPEN) - my_hd_io(port->board->base + port->ch_base, sizeof(*port)); -#endif - - if (port->gs.port.count <= 1) { - if (sx_send_command(port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) { - printk(KERN_ERR "sx: Card didn't respond to LOPEN " - "command.\n"); - spin_lock_irqsave(&port->gs.driver_lock, flags); - port->gs.port.count--; - spin_unlock_irqrestore(&port->gs.driver_lock, flags); - return -EIO; - } - } - - retval = gs_block_til_ready(port, filp); - sx_dprintk(SX_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n", - retval, port->gs.port.count); - - if (retval) { -/* - * Don't lower gs.port.count here because sx_close() will be called later - */ - - return retval; - } - /* tty->low_latency = 1; */ - - port->c_dcd = sx_carrier_raised(&port->gs.port); - sx_dprintk(SX_DEBUG_OPEN, "at open: cd=%d\n", port->c_dcd); - - func_exit(); - return 0; - -} - -static void sx_close(void *ptr) -{ - struct sx_port *port = ptr; - /* Give the port 5 seconds to close down. */ - int to = 5 * HZ; - - func_enter(); - - sx_setsignals(port, 0, 0); - sx_reconfigure_port(port); - sx_send_command(port, HS_CLOSE, 0, 0); - - while (to-- && (sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED)) - if (msleep_interruptible(10)) - break; - if (sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED) { - if (sx_send_command(port, HS_FORCE_CLOSED, -1, HS_IDLE_CLOSED) - != 1) { - printk(KERN_ERR "sx: sent the force_close command, but " - "card didn't react\n"); - } else - sx_dprintk(SX_DEBUG_CLOSE, "sent the force_close " - "command.\n"); - } - - sx_dprintk(SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n", - 5 * HZ - to - 1, port->gs.port.count); - - if (port->gs.port.count) { - sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", - port->gs.port.count); - /*printk("%s SETTING port count to zero: %p count: %d\n", - __func__, port, port->gs.port.count); - port->gs.port.count = 0;*/ - } - - func_exit(); -} - -/* This is relatively thorough. But then again it is only 20 lines. */ -#define MARCHUP for (i = min; i < max; i++) -#define MARCHDOWN for (i = max - 1; i >= min; i--) -#define W0 write_sx_byte(board, i, 0x55) -#define W1 write_sx_byte(board, i, 0xaa) -#define R0 if (read_sx_byte(board, i) != 0x55) return 1 -#define R1 if (read_sx_byte(board, i) != 0xaa) return 1 - -/* This memtest takes a human-noticable time. You normally only do it - once a boot, so I guess that it is worth it. */ -static int do_memtest(struct sx_board *board, int min, int max) -{ - int i; - - /* This is a marchb. Theoretically, marchb catches much more than - simpler tests. In practise, the longer test just catches more - intermittent errors. -- REW - (For the theory behind memory testing see: - Testing Semiconductor Memories by A.J. van de Goor.) */ - MARCHUP { - W0; - } - MARCHUP { - R0; - W1; - R1; - W0; - R0; - W1; - } - MARCHUP { - R1; - W0; - W1; - } - MARCHDOWN { - R1; - W0; - W1; - W0; - } - MARCHDOWN { - R0; - W1; - W0; - } - - return 0; -} - -#undef MARCHUP -#undef MARCHDOWN -#undef W0 -#undef W1 -#undef R0 -#undef R1 - -#define MARCHUP for (i = min; i < max; i += 2) -#define MARCHDOWN for (i = max - 1; i >= min; i -= 2) -#define W0 write_sx_word(board, i, 0x55aa) -#define W1 write_sx_word(board, i, 0xaa55) -#define R0 if (read_sx_word(board, i) != 0x55aa) return 1 -#define R1 if (read_sx_word(board, i) != 0xaa55) return 1 - -#if 0 -/* This memtest takes a human-noticable time. You normally only do it - once a boot, so I guess that it is worth it. */ -static int do_memtest_w(struct sx_board *board, int min, int max) -{ - int i; - - MARCHUP { - W0; - } - MARCHUP { - R0; - W1; - R1; - W0; - R0; - W1; - } - MARCHUP { - R1; - W0; - W1; - } - MARCHDOWN { - R1; - W0; - W1; - W0; - } - MARCHDOWN { - R0; - W1; - W0; - } - - return 0; -} -#endif - -static long sx_fw_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) -{ - long rc = 0; - int __user *descr = (int __user *)arg; - int i; - static struct sx_board *board = NULL; - int nbytes, offset; - unsigned long data; - char *tmp; - - func_enter(); - - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - - tty_lock(); - - sx_dprintk(SX_DEBUG_FIRMWARE, "IOCTL %x: %lx\n", cmd, arg); - - if (!board) - board = &boards[0]; - if (board->flags & SX_BOARD_PRESENT) { - sx_dprintk(SX_DEBUG_FIRMWARE, "Board present! (%x)\n", - board->flags); - } else { - sx_dprintk(SX_DEBUG_FIRMWARE, "Board not present! (%x) all:", - board->flags); - for (i = 0; i < SX_NBOARDS; i++) - sx_dprintk(SX_DEBUG_FIRMWARE, "<%x> ", boards[i].flags); - sx_dprintk(SX_DEBUG_FIRMWARE, "\n"); - rc = -EIO; - goto out; - } - - switch (cmd) { - case SXIO_SET_BOARD: - sx_dprintk(SX_DEBUG_FIRMWARE, "set board to %ld\n", arg); - rc = -EIO; - if (arg >= SX_NBOARDS) - break; - sx_dprintk(SX_DEBUG_FIRMWARE, "not out of range\n"); - if (!(boards[arg].flags & SX_BOARD_PRESENT)) - break; - sx_dprintk(SX_DEBUG_FIRMWARE, ".. and present!\n"); - board = &boards[arg]; - rc = 0; - /* FIXME: And this does ... nothing?? */ - break; - case SXIO_GET_TYPE: - rc = -ENOENT; /* If we manage to miss one, return error. */ - if (IS_SX_BOARD(board)) - rc = SX_TYPE_SX; - if (IS_CF_BOARD(board)) - rc = SX_TYPE_CF; - if (IS_SI_BOARD(board)) - rc = SX_TYPE_SI; - if (IS_SI1_BOARD(board)) - rc = SX_TYPE_SI; - if (IS_EISA_BOARD(board)) - rc = SX_TYPE_SI; - sx_dprintk(SX_DEBUG_FIRMWARE, "returning type= %ld\n", rc); - break; - case SXIO_DO_RAMTEST: - if (sx_initialized) { /* Already initialized: better not ramtest the board. */ - rc = -EPERM; - break; - } - if (IS_SX_BOARD(board)) { - rc = do_memtest(board, 0, 0x7000); - if (!rc) - rc = do_memtest(board, 0, 0x7000); - /*if (!rc) rc = do_memtest_w (board, 0, 0x7000); */ - } else { - rc = do_memtest(board, 0, 0x7ff8); - /* if (!rc) rc = do_memtest_w (board, 0, 0x7ff8); */ - } - sx_dprintk(SX_DEBUG_FIRMWARE, - "returning memtest result= %ld\n", rc); - break; - case SXIO_DOWNLOAD: - if (sx_initialized) {/* Already initialized */ - rc = -EEXIST; - break; - } - if (!sx_reset(board)) { - rc = -EIO; - break; - } - sx_dprintk(SX_DEBUG_INIT, "reset the board...\n"); - - tmp = kmalloc(SX_CHUNK_SIZE, GFP_USER); - if (!tmp) { - rc = -ENOMEM; - break; - } - /* FIXME: check returns */ - get_user(nbytes, descr++); - get_user(offset, descr++); - get_user(data, descr++); - while (nbytes && data) { - for (i = 0; i < nbytes; i += SX_CHUNK_SIZE) { - if (copy_from_user(tmp, (char __user *)data + i, - (i + SX_CHUNK_SIZE > nbytes) ? - nbytes - i : SX_CHUNK_SIZE)) { - kfree(tmp); - rc = -EFAULT; - goto out; - } - memcpy_toio(board->base2 + offset + i, tmp, - (i + SX_CHUNK_SIZE > nbytes) ? - nbytes - i : SX_CHUNK_SIZE); - } - - get_user(nbytes, descr++); - get_user(offset, descr++); - get_user(data, descr++); - } - kfree(tmp); - sx_nports += sx_init_board(board); - rc = sx_nports; - break; - case SXIO_INIT: - if (sx_initialized) { /* Already initialized */ - rc = -EEXIST; - break; - } - /* This is not allowed until all boards are initialized... */ - for (i = 0; i < SX_NBOARDS; i++) { - if ((boards[i].flags & SX_BOARD_PRESENT) && - !(boards[i].flags & SX_BOARD_INITIALIZED)) { - rc = -EIO; - break; - } - } - for (i = 0; i < SX_NBOARDS; i++) - if (!(boards[i].flags & SX_BOARD_PRESENT)) - break; - - sx_dprintk(SX_DEBUG_FIRMWARE, "initing portstructs, %d boards, " - "%d channels, first board: %d ports\n", - i, sx_nports, boards[0].nports); - rc = sx_init_portstructs(i, sx_nports); - sx_init_drivers(); - if (rc >= 0) - sx_initialized++; - break; - case SXIO_SETDEBUG: - sx_debug = arg; - break; - case SXIO_GETDEBUG: - rc = sx_debug; - break; - case SXIO_GETGSDEBUG: - case SXIO_SETGSDEBUG: - rc = -EINVAL; - break; - case SXIO_GETNPORTS: - rc = sx_nports; - break; - default: - rc = -ENOTTY; - break; - } -out: - tty_unlock(); - func_exit(); - return rc; -} - -static int sx_break(struct tty_struct *tty, int flag) -{ - struct sx_port *port = tty->driver_data; - int rv; - - func_enter(); - tty_lock(); - - if (flag) - rv = sx_send_command(port, HS_START, -1, HS_IDLE_BREAK); - else - rv = sx_send_command(port, HS_STOP, -1, HS_IDLE_OPEN); - if (rv != 1) - printk(KERN_ERR "sx: couldn't send break (%x).\n", - read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat))); - tty_unlock(); - func_exit(); - return 0; -} - -static int sx_tiocmget(struct tty_struct *tty) -{ - struct sx_port *port = tty->driver_data; - return sx_getsignals(port); -} - -static int sx_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct sx_port *port = tty->driver_data; - int rts = -1, dtr = -1; - - if (set & TIOCM_RTS) - rts = 1; - if (set & TIOCM_DTR) - dtr = 1; - if (clear & TIOCM_RTS) - rts = 0; - if (clear & TIOCM_DTR) - dtr = 0; - - sx_setsignals(port, dtr, rts); - sx_reconfigure_port(port); - return 0; -} - -static int sx_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - int rc; - struct sx_port *port = tty->driver_data; - void __user *argp = (void __user *)arg; - - /* func_enter2(); */ - - rc = 0; - tty_lock(); - switch (cmd) { - case TIOCGSERIAL: - rc = gs_getserial(&port->gs, argp); - break; - case TIOCSSERIAL: - rc = gs_setserial(&port->gs, argp); - break; - default: - rc = -ENOIOCTLCMD; - break; - } - tty_unlock(); - - /* func_exit(); */ - return rc; -} - -/* The throttle/unthrottle scheme for the Specialix card is different - * from other drivers and deserves some explanation. - * The Specialix hardware takes care of XON/XOFF - * and CTS/RTS flow control itself. This means that all we have to - * do when signalled by the upper tty layer to throttle/unthrottle is - * to make a note of it here. When we come to read characters from the - * rx buffers on the card (sx_receive_chars()) we look to see if the - * upper layer can accept more (as noted here in sx_rx_throt[]). - * If it can't we simply don't remove chars from the cards buffer. - * When the tty layer can accept chars, we again note that here and when - * sx_receive_chars() is called it will remove them from the cards buffer. - * The card will notice that a ports buffer has drained below some low - * water mark and will unflow control the line itself, using whatever - * flow control scheme is in use for that port. -- Simon Allen - */ - -static void sx_throttle(struct tty_struct *tty) -{ - struct sx_port *port = tty->driver_data; - - func_enter2(); - /* If the port is using any type of input flow - * control then throttle the port. - */ - if ((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty))) { - port->gs.port.flags |= SX_RX_THROTTLE; - } - func_exit(); -} - -static void sx_unthrottle(struct tty_struct *tty) -{ - struct sx_port *port = tty->driver_data; - - func_enter2(); - /* Always unthrottle even if flow control is not enabled on - * this port in case we disabled flow control while the port - * was throttled - */ - port->gs.port.flags &= ~SX_RX_THROTTLE; - func_exit(); - return; -} - -/* ********************************************************************** * - * Here are the initialization routines. * - * ********************************************************************** */ - -static int sx_init_board(struct sx_board *board) -{ - int addr; - int chans; - int type; - - func_enter(); - - /* This is preceded by downloading the download code. */ - - board->flags |= SX_BOARD_INITIALIZED; - - if (read_sx_byte(board, 0)) - /* CF boards may need this. */ - write_sx_byte(board, 0, 0); - - /* This resets the processor again, to make sure it didn't do any - foolish things while we were downloading the image */ - if (!sx_reset(board)) - return 0; - - sx_start_board(board); - udelay(10); - if (!sx_busy_wait_neq(board, 0, 0xff, 0)) { - printk(KERN_ERR "sx: Ooops. Board won't initialize.\n"); - return 0; - } - - /* Ok. So now the processor on the card is running. It gathered - some info for us... */ - sx_dprintk(SX_DEBUG_INIT, "The sxcard structure:\n"); - if (sx_debug & SX_DEBUG_INIT) - my_hd_io(board->base, 0x10); - sx_dprintk(SX_DEBUG_INIT, "the first sx_module structure:\n"); - if (sx_debug & SX_DEBUG_INIT) - my_hd_io(board->base + 0x80, 0x30); - - sx_dprintk(SX_DEBUG_INIT, "init_status: %x, %dk memory, firmware " - "V%x.%02x,\n", - read_sx_byte(board, 0), read_sx_byte(board, 1), - read_sx_byte(board, 5), read_sx_byte(board, 4)); - - if (read_sx_byte(board, 0) == 0xff) { - printk(KERN_INFO "sx: No modules found. Sorry.\n"); - board->nports = 0; - return 0; - } - - chans = 0; - - if (IS_SX_BOARD(board)) { - sx_write_board_word(board, cc_int_count, sx_maxints); - } else { - if (sx_maxints) - sx_write_board_word(board, cc_int_count, - SI_PROCESSOR_CLOCK / 8 / sx_maxints); - } - - /* grab the first module type... */ - /* board->ta_type = mod_compat_type (read_sx_byte (board, 0x80 + 0x08)); */ - board->ta_type = mod_compat_type(sx_read_module_byte(board, 0x80, - mc_chip)); - - /* XXX byteorder */ - for (addr = 0x80; addr != 0; addr = read_sx_word(board, addr) & 0x7fff){ - type = sx_read_module_byte(board, addr, mc_chip); - sx_dprintk(SX_DEBUG_INIT, "Module at %x: %d channels\n", - addr, read_sx_byte(board, addr + 2)); - - chans += sx_read_module_byte(board, addr, mc_type); - - sx_dprintk(SX_DEBUG_INIT, "module is an %s, which has %s/%s " - "panels\n", - mod_type_s(type), - pan_type_s(sx_read_module_byte(board, addr, - mc_mods) & 0xf), - pan_type_s(sx_read_module_byte(board, addr, - mc_mods) >> 4)); - - sx_dprintk(SX_DEBUG_INIT, "CD1400 versions: %x/%x, ASIC " - "version: %x\n", - sx_read_module_byte(board, addr, mc_rev1), - sx_read_module_byte(board, addr, mc_rev2), - sx_read_module_byte(board, addr, mc_mtaasic_rev)); - - /* The following combinations are illegal: It should theoretically - work, but timing problems make the bus HANG. */ - - if (mod_compat_type(type) != board->ta_type) { - printk(KERN_ERR "sx: This is an invalid " - "configuration.\nDon't mix TA/MTA/SXDC on the " - "same hostadapter.\n"); - chans = 0; - break; - } - if ((IS_EISA_BOARD(board) || - IS_SI_BOARD(board)) && - (mod_compat_type(type) == 4)) { - printk(KERN_ERR "sx: This is an invalid " - "configuration.\nDon't use SXDCs on an SI/XIO " - "adapter.\n"); - chans = 0; - break; - } -#if 0 /* Problem fixed: firmware 3.05 */ - if (IS_SX_BOARD(board) && (type == TA8)) { - /* There are some issues with the firmware and the DCD/RTS - lines. It might work if you tie them together or something. - It might also work if you get a newer sx_firmware. Therefore - this is just a warning. */ - printk(KERN_WARNING - "sx: The SX host doesn't work too well " - "with the TA8 adapters.\nSpecialix is working on it.\n"); - } -#endif - } - - if (chans) { - if (board->irq > 0) { - /* fixed irq, probably PCI */ - if (sx_irqmask & (1 << board->irq)) { /* may we use this irq? */ - if (request_irq(board->irq, sx_interrupt, - IRQF_SHARED | IRQF_DISABLED, - "sx", board)) { - printk(KERN_ERR "sx: Cannot allocate " - "irq %d.\n", board->irq); - board->irq = 0; - } - } else - board->irq = 0; - } else if (board->irq < 0 && sx_irqmask) { - /* auto-allocate irq */ - int irqnr; - int irqmask = sx_irqmask & (IS_SX_BOARD(board) ? - SX_ISA_IRQ_MASK : SI2_ISA_IRQ_MASK); - for (irqnr = 15; irqnr > 0; irqnr--) - if (irqmask & (1 << irqnr)) - if (!request_irq(irqnr, sx_interrupt, - IRQF_SHARED | IRQF_DISABLED, - "sx", board)) - break; - if (!irqnr) - printk(KERN_ERR "sx: Cannot allocate IRQ.\n"); - board->irq = irqnr; - } else - board->irq = 0; - - if (board->irq) { - /* Found a valid interrupt, start up interrupts! */ - sx_dprintk(SX_DEBUG_INIT, "Using irq %d.\n", - board->irq); - sx_start_interrupts(board); - board->poll = sx_slowpoll; - board->flags |= SX_IRQ_ALLOCATED; - } else { - /* no irq: setup board for polled operation */ - board->poll = sx_poll; - sx_dprintk(SX_DEBUG_INIT, "Using poll-interval %d.\n", - board->poll); - } - - /* The timer should be initialized anyway: That way we can - safely del_timer it when the module is unloaded. */ - setup_timer(&board->timer, sx_pollfunc, (unsigned long)board); - - if (board->poll) - mod_timer(&board->timer, jiffies + board->poll); - } else { - board->irq = 0; - } - - board->nports = chans; - sx_dprintk(SX_DEBUG_INIT, "returning %d ports.", board->nports); - - func_exit(); - return chans; -} - -static void __devinit printheader(void) -{ - static int header_printed; - - if (!header_printed) { - printk(KERN_INFO "Specialix SX driver " - "(C) 1998/1999 R.E.Wolff@BitWizard.nl\n"); - printk(KERN_INFO "sx: version " __stringify(SX_VERSION) "\n"); - header_printed = 1; - } -} - -static int __devinit probe_sx(struct sx_board *board) -{ - struct vpd_prom vpdp; - char *p; - int i; - - func_enter(); - - if (!IS_CF_BOARD(board)) { - sx_dprintk(SX_DEBUG_PROBE, "Going to verify vpd prom at %p.\n", - board->base + SX_VPD_ROM); - - if (sx_debug & SX_DEBUG_PROBE) - my_hd_io(board->base + SX_VPD_ROM, 0x40); - - p = (char *)&vpdp; - for (i = 0; i < sizeof(struct vpd_prom); i++) - *p++ = read_sx_byte(board, SX_VPD_ROM + i * 2); - - if (sx_debug & SX_DEBUG_PROBE) - my_hd(&vpdp, 0x20); - - sx_dprintk(SX_DEBUG_PROBE, "checking identifier...\n"); - - if (strncmp(vpdp.identifier, SX_VPD_IDENT_STRING, 16) != 0) { - sx_dprintk(SX_DEBUG_PROBE, "Got non-SX identifier: " - "'%s'\n", vpdp.identifier); - return 0; - } - } - - printheader(); - - if (!IS_CF_BOARD(board)) { - printk(KERN_DEBUG "sx: Found an SX board at %lx\n", - board->hw_base); - printk(KERN_DEBUG "sx: hw_rev: %d, assembly level: %d, " - "uniq ID:%08x, ", - vpdp.hwrev, vpdp.hwass, vpdp.uniqid); - printk("Manufactured: %d/%d\n", 1970 + vpdp.myear, vpdp.mweek); - - if ((((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) != - SX_PCI_UNIQUEID1) && (((vpdp.uniqid >> 24) & - SX_UNIQUEID_MASK) != SX_ISA_UNIQUEID1)) { - /* This might be a bit harsh. This was the primary - reason the SX/ISA card didn't work at first... */ - printk(KERN_ERR "sx: Hmm. Not an SX/PCI or SX/ISA " - "card. Sorry: giving up.\n"); - return (0); - } - - if (((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) == - SX_ISA_UNIQUEID1) { - if (((unsigned long)board->hw_base) & 0x8000) { - printk(KERN_WARNING "sx: Warning: There may be " - "hardware problems with the card at " - "%lx.\n", board->hw_base); - printk(KERN_WARNING "sx: Read sx.txt for more " - "info.\n"); - } - } - } - - board->nports = -1; - - /* This resets the processor, and keeps it off the bus. */ - if (!sx_reset(board)) - return 0; - sx_dprintk(SX_DEBUG_INIT, "reset the board...\n"); - - func_exit(); - return 1; -} - -#if defined(CONFIG_ISA) || defined(CONFIG_EISA) - -/* Specialix probes for this card at 32k increments from 640k to 16M. - I consider machines with less than 16M unlikely nowadays, so I'm - not probing above 1Mb. Also, 0xa0000, 0xb0000, are taken by the VGA - card. 0xe0000 and 0xf0000 are taken by the BIOS. That only leaves - 0xc0000, 0xc8000, 0xd0000 and 0xd8000 . */ - -static int __devinit probe_si(struct sx_board *board) -{ - int i; - - func_enter(); - sx_dprintk(SX_DEBUG_PROBE, "Going to verify SI signature hw %lx at " - "%p.\n", board->hw_base, board->base + SI2_ISA_ID_BASE); - - if (sx_debug & SX_DEBUG_PROBE) - my_hd_io(board->base + SI2_ISA_ID_BASE, 0x8); - - if (!IS_EISA_BOARD(board)) { - if (IS_SI1_BOARD(board)) { - for (i = 0; i < 8; i++) { - write_sx_byte(board, SI2_ISA_ID_BASE + 7 - i,i); - } - } - for (i = 0; i < 8; i++) { - if ((read_sx_byte(board, SI2_ISA_ID_BASE + 7 - i) & 7) - != i) { - func_exit(); - return 0; - } - } - } - - /* Now we're pretty much convinced that there is an SI board here, - but to prevent trouble, we'd better double check that we don't - have an SI1 board when we're probing for an SI2 board.... */ - - write_sx_byte(board, SI2_ISA_ID_BASE, 0x10); - if (IS_SI1_BOARD(board)) { - /* This should be an SI1 board, which has this - location writable... */ - if (read_sx_byte(board, SI2_ISA_ID_BASE) != 0x10) { - func_exit(); - return 0; - } - } else { - /* This should be an SI2 board, which has the bottom - 3 bits non-writable... */ - if (read_sx_byte(board, SI2_ISA_ID_BASE) == 0x10) { - func_exit(); - return 0; - } - } - - /* Now we're pretty much convinced that there is an SI board here, - but to prevent trouble, we'd better double check that we don't - have an SI1 board when we're probing for an SI2 board.... */ - - write_sx_byte(board, SI2_ISA_ID_BASE, 0x10); - if (IS_SI1_BOARD(board)) { - /* This should be an SI1 board, which has this - location writable... */ - if (read_sx_byte(board, SI2_ISA_ID_BASE) != 0x10) { - func_exit(); - return 0; - } - } else { - /* This should be an SI2 board, which has the bottom - 3 bits non-writable... */ - if (read_sx_byte(board, SI2_ISA_ID_BASE) == 0x10) { - func_exit(); - return 0; - } - } - - printheader(); - - printk(KERN_DEBUG "sx: Found an SI board at %lx\n", board->hw_base); - /* Compared to the SX boards, it is a complete guess as to what - this card is up to... */ - - board->nports = -1; - - /* This resets the processor, and keeps it off the bus. */ - if (!sx_reset(board)) - return 0; - sx_dprintk(SX_DEBUG_INIT, "reset the board...\n"); - - func_exit(); - return 1; -} -#endif - -static const struct tty_operations sx_ops = { - .break_ctl = sx_break, - .open = sx_open, - .close = gs_close, - .write = gs_write, - .put_char = gs_put_char, - .flush_chars = gs_flush_chars, - .write_room = gs_write_room, - .chars_in_buffer = gs_chars_in_buffer, - .flush_buffer = gs_flush_buffer, - .ioctl = sx_ioctl, - .throttle = sx_throttle, - .unthrottle = sx_unthrottle, - .set_termios = gs_set_termios, - .stop = gs_stop, - .start = gs_start, - .hangup = gs_hangup, - .tiocmget = sx_tiocmget, - .tiocmset = sx_tiocmset, -}; - -static const struct tty_port_operations sx_port_ops = { - .carrier_raised = sx_carrier_raised, -}; - -static int sx_init_drivers(void) -{ - int error; - - func_enter(); - - sx_driver = alloc_tty_driver(sx_nports); - if (!sx_driver) - return 1; - sx_driver->owner = THIS_MODULE; - sx_driver->driver_name = "specialix_sx"; - sx_driver->name = "ttyX"; - sx_driver->major = SX_NORMAL_MAJOR; - sx_driver->type = TTY_DRIVER_TYPE_SERIAL; - sx_driver->subtype = SERIAL_TYPE_NORMAL; - sx_driver->init_termios = tty_std_termios; - sx_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - sx_driver->init_termios.c_ispeed = 9600; - sx_driver->init_termios.c_ospeed = 9600; - sx_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(sx_driver, &sx_ops); - - if ((error = tty_register_driver(sx_driver))) { - put_tty_driver(sx_driver); - printk(KERN_ERR "sx: Couldn't register sx driver, error = %d\n", - error); - return 1; - } - func_exit(); - return 0; -} - -static int sx_init_portstructs(int nboards, int nports) -{ - struct sx_board *board; - struct sx_port *port; - int i, j; - int addr, chans; - int portno; - - func_enter(); - - /* Many drivers statically allocate the maximum number of ports - There is no reason not to allocate them dynamically. - Is there? -- REW */ - sx_ports = kcalloc(nports, sizeof(struct sx_port), GFP_KERNEL); - if (!sx_ports) - return -ENOMEM; - - port = sx_ports; - for (i = 0; i < nboards; i++) { - board = &boards[i]; - board->ports = port; - for (j = 0; j < boards[i].nports; j++) { - sx_dprintk(SX_DEBUG_INIT, "initing port %d\n", j); - tty_port_init(&port->gs.port); - port->gs.port.ops = &sx_port_ops; - port->gs.magic = SX_MAGIC; - port->gs.close_delay = HZ / 2; - port->gs.closing_wait = 30 * HZ; - port->board = board; - port->gs.rd = &sx_real_driver; -#ifdef NEW_WRITE_LOCKING - port->gs.port_write_mutex = MUTEX; -#endif - spin_lock_init(&port->gs.driver_lock); - /* - * Initializing wait queue - */ - port++; - } - } - - port = sx_ports; - portno = 0; - for (i = 0; i < nboards; i++) { - board = &boards[i]; - board->port_base = portno; - /* Possibly the configuration was rejected. */ - sx_dprintk(SX_DEBUG_PROBE, "Board has %d channels\n", - board->nports); - if (board->nports <= 0) - continue; - /* XXX byteorder ?? */ - for (addr = 0x80; addr != 0; - addr = read_sx_word(board, addr) & 0x7fff) { - chans = sx_read_module_byte(board, addr, mc_type); - sx_dprintk(SX_DEBUG_PROBE, "Module at %x: %d " - "channels\n", addr, chans); - sx_dprintk(SX_DEBUG_PROBE, "Port at"); - for (j = 0; j < chans; j++) { - /* The "sx-way" is the way it SHOULD be done. - That way in the future, the firmware may for - example pack the structures a bit more - efficient. Neil tells me it isn't going to - happen anytime soon though. */ - if (IS_SX_BOARD(board)) - port->ch_base = sx_read_module_word( - board, addr + j * 2, - mc_chan_pointer); - else - port->ch_base = addr + 0x100 + 0x300 *j; - - sx_dprintk(SX_DEBUG_PROBE, " %x", - port->ch_base); - port->line = portno++; - port++; - } - sx_dprintk(SX_DEBUG_PROBE, "\n"); - } - /* This has to be done earlier. */ - /* board->flags |= SX_BOARD_INITIALIZED; */ - } - - func_exit(); - return 0; -} - -static unsigned int sx_find_free_board(void) -{ - unsigned int i; - - for (i = 0; i < SX_NBOARDS; i++) - if (!(boards[i].flags & SX_BOARD_PRESENT)) - break; - - return i; -} - -static void __exit sx_release_drivers(void) -{ - func_enter(); - tty_unregister_driver(sx_driver); - put_tty_driver(sx_driver); - func_exit(); -} - -static void __devexit sx_remove_card(struct sx_board *board, - struct pci_dev *pdev) -{ - if (board->flags & SX_BOARD_INITIALIZED) { - /* The board should stop messing with us. (actually I mean the - interrupt) */ - sx_reset(board); - if ((board->irq) && (board->flags & SX_IRQ_ALLOCATED)) - free_irq(board->irq, board); - - /* It is safe/allowed to del_timer a non-active timer */ - del_timer(&board->timer); - if (pdev) { -#ifdef CONFIG_PCI - iounmap(board->base2); - pci_release_region(pdev, IS_CF_BOARD(board) ? 3 : 2); -#endif - } else { - iounmap(board->base); - release_region(board->hw_base, board->hw_len); - } - - board->flags &= ~(SX_BOARD_INITIALIZED | SX_BOARD_PRESENT); - } -} - -#ifdef CONFIG_EISA - -static int __devinit sx_eisa_probe(struct device *dev) -{ - struct eisa_device *edev = to_eisa_device(dev); - struct sx_board *board; - unsigned long eisa_slot = edev->base_addr; - unsigned int i; - int retval = -EIO; - - mutex_lock(&sx_boards_lock); - i = sx_find_free_board(); - if (i == SX_NBOARDS) { - mutex_unlock(&sx_boards_lock); - goto err; - } - board = &boards[i]; - board->flags |= SX_BOARD_PRESENT; - mutex_unlock(&sx_boards_lock); - - dev_info(dev, "XIO : Signature found in EISA slot %lu, " - "Product %d Rev %d (REPORT THIS TO LKLM)\n", - eisa_slot >> 12, - inb(eisa_slot + EISA_VENDOR_ID_OFFSET + 2), - inb(eisa_slot + EISA_VENDOR_ID_OFFSET + 3)); - - board->eisa_base = eisa_slot; - board->flags &= ~SX_BOARD_TYPE; - board->flags |= SI_EISA_BOARD; - - board->hw_base = ((inb(eisa_slot + 0xc01) << 8) + - inb(eisa_slot + 0xc00)) << 16; - board->hw_len = SI2_EISA_WINDOW_LEN; - if (!request_region(board->hw_base, board->hw_len, "sx")) { - dev_err(dev, "can't request region\n"); - goto err_flag; - } - board->base2 = - board->base = ioremap_nocache(board->hw_base, SI2_EISA_WINDOW_LEN); - if (!board->base) { - dev_err(dev, "can't remap memory\n"); - goto err_reg; - } - - sx_dprintk(SX_DEBUG_PROBE, "IO hw_base address: %lx\n", board->hw_base); - sx_dprintk(SX_DEBUG_PROBE, "base: %p\n", board->base); - board->irq = inb(eisa_slot + 0xc02) >> 4; - sx_dprintk(SX_DEBUG_PROBE, "IRQ: %d\n", board->irq); - - if (!probe_si(board)) - goto err_unmap; - - dev_set_drvdata(dev, board); - - return 0; -err_unmap: - iounmap(board->base); -err_reg: - release_region(board->hw_base, board->hw_len); -err_flag: - board->flags &= ~SX_BOARD_PRESENT; -err: - return retval; -} - -static int __devexit sx_eisa_remove(struct device *dev) -{ - struct sx_board *board = dev_get_drvdata(dev); - - sx_remove_card(board, NULL); - - return 0; -} - -static struct eisa_device_id sx_eisa_tbl[] = { - { "SLX" }, - { "" } -}; - -MODULE_DEVICE_TABLE(eisa, sx_eisa_tbl); - -static struct eisa_driver sx_eisadriver = { - .id_table = sx_eisa_tbl, - .driver = { - .name = "sx", - .probe = sx_eisa_probe, - .remove = __devexit_p(sx_eisa_remove), - } -}; - -#endif - -#ifdef CONFIG_PCI - /******************************************************** - * Setting bit 17 in the CNTRL register of the PLX 9050 * - * chip forces a retry on writes while a read is pending.* - * This is to prevent the card locking up on Intel Xeon * - * multiprocessor systems with the NX chipset. -- NV * - ********************************************************/ - -/* Newer cards are produced with this bit set from the configuration - EEprom. As the bit is read/write for the CPU, we can fix it here, - if we detect that it isn't set correctly. -- REW */ - -static void __devinit fix_sx_pci(struct pci_dev *pdev, struct sx_board *board) -{ - unsigned int hwbase; - void __iomem *rebase; - unsigned int t; - -#define CNTRL_REG_OFFSET 0x50 -#define CNTRL_REG_GOODVALUE 0x18260000 - - pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase); - hwbase &= PCI_BASE_ADDRESS_MEM_MASK; - rebase = ioremap_nocache(hwbase, 0x80); - t = readl(rebase + CNTRL_REG_OFFSET); - if (t != CNTRL_REG_GOODVALUE) { - printk(KERN_DEBUG "sx: performing cntrl reg fix: %08x -> " - "%08x\n", t, CNTRL_REG_GOODVALUE); - writel(CNTRL_REG_GOODVALUE, rebase + CNTRL_REG_OFFSET); - } - iounmap(rebase); -} -#endif - -static int __devinit sx_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ -#ifdef CONFIG_PCI - struct sx_board *board; - unsigned int i, reg; - int retval = -EIO; - - mutex_lock(&sx_boards_lock); - i = sx_find_free_board(); - if (i == SX_NBOARDS) { - mutex_unlock(&sx_boards_lock); - goto err; - } - board = &boards[i]; - board->flags |= SX_BOARD_PRESENT; - mutex_unlock(&sx_boards_lock); - - retval = pci_enable_device(pdev); - if (retval) - goto err_flag; - - board->flags &= ~SX_BOARD_TYPE; - board->flags |= (pdev->subsystem_vendor == 0x200) ? SX_PCI_BOARD : - SX_CFPCI_BOARD; - - /* CF boards use base address 3.... */ - reg = IS_CF_BOARD(board) ? 3 : 2; - retval = pci_request_region(pdev, reg, "sx"); - if (retval) { - dev_err(&pdev->dev, "can't request region\n"); - goto err_flag; - } - board->hw_base = pci_resource_start(pdev, reg); - board->base2 = - board->base = ioremap_nocache(board->hw_base, WINDOW_LEN(board)); - if (!board->base) { - dev_err(&pdev->dev, "ioremap failed\n"); - goto err_reg; - } - - /* Most of the stuff on the CF board is offset by 0x18000 .... */ - if (IS_CF_BOARD(board)) - board->base += 0x18000; - - board->irq = pdev->irq; - - dev_info(&pdev->dev, "Got a specialix card: %p(%d) %x.\n", board->base, - board->irq, board->flags); - - if (!probe_sx(board)) { - retval = -EIO; - goto err_unmap; - } - - fix_sx_pci(pdev, board); - - pci_set_drvdata(pdev, board); - - return 0; -err_unmap: - iounmap(board->base2); -err_reg: - pci_release_region(pdev, reg); -err_flag: - board->flags &= ~SX_BOARD_PRESENT; -err: - return retval; -#else - return -ENODEV; -#endif -} - -static void __devexit sx_pci_remove(struct pci_dev *pdev) -{ - struct sx_board *board = pci_get_drvdata(pdev); - - sx_remove_card(board, pdev); -} - -/* Specialix has a whole bunch of cards with 0x2000 as the device ID. They say - its because the standard requires it. So check for SUBVENDOR_ID. */ -static struct pci_device_id sx_pci_tbl[] = { - { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, - .subvendor = PCI_ANY_ID, .subdevice = 0x0200 }, - { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, - .subvendor = PCI_ANY_ID, .subdevice = 0x0300 }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, sx_pci_tbl); - -static struct pci_driver sx_pcidriver = { - .name = "sx", - .id_table = sx_pci_tbl, - .probe = sx_pci_probe, - .remove = __devexit_p(sx_pci_remove) -}; - -static int __init sx_init(void) -{ -#ifdef CONFIG_EISA - int retval1; -#endif -#ifdef CONFIG_ISA - struct sx_board *board; - unsigned int i; -#endif - unsigned int found = 0; - int retval; - - func_enter(); - sx_dprintk(SX_DEBUG_INIT, "Initing sx module... (sx_debug=%d)\n", - sx_debug); - if (abs((long)(&sx_debug) - sx_debug) < 0x10000) { - printk(KERN_WARNING "sx: sx_debug is an address, instead of a " - "value. Assuming -1.\n(%p)\n", &sx_debug); - sx_debug = -1; - } - - if (misc_register(&sx_fw_device) < 0) { - printk(KERN_ERR "SX: Unable to register firmware loader " - "driver.\n"); - return -EIO; - } -#ifdef CONFIG_ISA - for (i = 0; i < NR_SX_ADDRS; i++) { - board = &boards[found]; - board->hw_base = sx_probe_addrs[i]; - board->hw_len = SX_WINDOW_LEN; - if (!request_region(board->hw_base, board->hw_len, "sx")) - continue; - board->base2 = - board->base = ioremap_nocache(board->hw_base, board->hw_len); - if (!board->base) - goto err_sx_reg; - board->flags &= ~SX_BOARD_TYPE; - board->flags |= SX_ISA_BOARD; - board->irq = sx_irqmask ? -1 : 0; - - if (probe_sx(board)) { - board->flags |= SX_BOARD_PRESENT; - found++; - } else { - iounmap(board->base); -err_sx_reg: - release_region(board->hw_base, board->hw_len); - } - } - - for (i = 0; i < NR_SI_ADDRS; i++) { - board = &boards[found]; - board->hw_base = si_probe_addrs[i]; - board->hw_len = SI2_ISA_WINDOW_LEN; - if (!request_region(board->hw_base, board->hw_len, "sx")) - continue; - board->base2 = - board->base = ioremap_nocache(board->hw_base, board->hw_len); - if (!board->base) - goto err_si_reg; - board->flags &= ~SX_BOARD_TYPE; - board->flags |= SI_ISA_BOARD; - board->irq = sx_irqmask ? -1 : 0; - - if (probe_si(board)) { - board->flags |= SX_BOARD_PRESENT; - found++; - } else { - iounmap(board->base); -err_si_reg: - release_region(board->hw_base, board->hw_len); - } - } - for (i = 0; i < NR_SI1_ADDRS; i++) { - board = &boards[found]; - board->hw_base = si1_probe_addrs[i]; - board->hw_len = SI1_ISA_WINDOW_LEN; - if (!request_region(board->hw_base, board->hw_len, "sx")) - continue; - board->base2 = - board->base = ioremap_nocache(board->hw_base, board->hw_len); - if (!board->base) - goto err_si1_reg; - board->flags &= ~SX_BOARD_TYPE; - board->flags |= SI1_ISA_BOARD; - board->irq = sx_irqmask ? -1 : 0; - - if (probe_si(board)) { - board->flags |= SX_BOARD_PRESENT; - found++; - } else { - iounmap(board->base); -err_si1_reg: - release_region(board->hw_base, board->hw_len); - } - } -#endif -#ifdef CONFIG_EISA - retval1 = eisa_driver_register(&sx_eisadriver); -#endif - retval = pci_register_driver(&sx_pcidriver); - - if (found) { - printk(KERN_INFO "sx: total of %d boards detected.\n", found); - retval = 0; - } else if (retval) { -#ifdef CONFIG_EISA - retval = retval1; - if (retval1) -#endif - misc_deregister(&sx_fw_device); - } - - func_exit(); - return retval; -} - -static void __exit sx_exit(void) -{ - int i; - - func_enter(); -#ifdef CONFIG_EISA - eisa_driver_unregister(&sx_eisadriver); -#endif - pci_unregister_driver(&sx_pcidriver); - - for (i = 0; i < SX_NBOARDS; i++) - sx_remove_card(&boards[i], NULL); - - if (misc_deregister(&sx_fw_device) < 0) { - printk(KERN_INFO "sx: couldn't deregister firmware loader " - "device\n"); - } - sx_dprintk(SX_DEBUG_CLEANUP, "Cleaning up drivers (%d)\n", - sx_initialized); - if (sx_initialized) - sx_release_drivers(); - - kfree(sx_ports); - func_exit(); -} - -module_init(sx_init); -module_exit(sx_exit); diff --git a/drivers/char/sx.h b/drivers/char/sx.h deleted file mode 100644 index 87c2defdead7..000000000000 --- a/drivers/char/sx.h +++ /dev/null @@ -1,201 +0,0 @@ - -/* - * sx.h - * - * Copyright (C) 1998/1999 R.E.Wolff@BitWizard.nl - * - * SX serial driver. - * -- Supports SI, XIO and SX host cards. - * -- Supports TAs, MTAs and SXDCs. - * - * Version 1.3 -- March, 1999. - * - */ - -#define SX_NBOARDS 4 -#define SX_PORTSPERBOARD 32 -#define SX_NPORTS (SX_NBOARDS * SX_PORTSPERBOARD) - -#ifdef __KERNEL__ - -#define SX_MAGIC 0x12345678 - -struct sx_port { - struct gs_port gs; - struct wait_queue *shutdown_wait; - int ch_base; - int c_dcd; - struct sx_board *board; - int line; - unsigned long locks; -}; - -struct sx_board { - int magic; - void __iomem *base; - void __iomem *base2; - unsigned long hw_base; - resource_size_t hw_len; - int eisa_base; - int port_base; /* Number of the first port */ - struct sx_port *ports; - int nports; - int flags; - int irq; - int poll; - int ta_type; - struct timer_list timer; - unsigned long locks; -}; - -struct vpd_prom { - unsigned short id; - char hwrev; - char hwass; - int uniqid; - char myear; - char mweek; - char hw_feature[5]; - char oem_id; - char identifier[16]; -}; - -#ifndef MOD_RS232DB25MALE -#define MOD_RS232DB25MALE 0x0a -#endif - -#define SI_ISA_BOARD 0x00000001 -#define SX_ISA_BOARD 0x00000002 -#define SX_PCI_BOARD 0x00000004 -#define SX_CFPCI_BOARD 0x00000008 -#define SX_CFISA_BOARD 0x00000010 -#define SI_EISA_BOARD 0x00000020 -#define SI1_ISA_BOARD 0x00000040 - -#define SX_BOARD_PRESENT 0x00001000 -#define SX_BOARD_INITIALIZED 0x00002000 -#define SX_IRQ_ALLOCATED 0x00004000 - -#define SX_BOARD_TYPE 0x000000ff - -#define IS_SX_BOARD(board) (board->flags & (SX_PCI_BOARD | SX_CFPCI_BOARD | \ - SX_ISA_BOARD | SX_CFISA_BOARD)) - -#define IS_SI_BOARD(board) (board->flags & SI_ISA_BOARD) -#define IS_SI1_BOARD(board) (board->flags & SI1_ISA_BOARD) - -#define IS_EISA_BOARD(board) (board->flags & SI_EISA_BOARD) - -#define IS_CF_BOARD(board) (board->flags & (SX_CFISA_BOARD | SX_CFPCI_BOARD)) - -/* The SI processor clock is required to calculate the cc_int_count register - value for the SI cards. */ -#define SI_PROCESSOR_CLOCK 25000000 - - -/* port flags */ -/* Make sure these don't clash with gs flags or async flags */ -#define SX_RX_THROTTLE 0x0000001 - - - -#define SX_PORT_TRANSMIT_LOCK 0 -#define SX_BOARD_INTR_LOCK 0 - - - -/* Debug flags. Add these together to get more debug info. */ - -#define SX_DEBUG_OPEN 0x00000001 -#define SX_DEBUG_SETTING 0x00000002 -#define SX_DEBUG_FLOW 0x00000004 -#define SX_DEBUG_MODEMSIGNALS 0x00000008 -#define SX_DEBUG_TERMIOS 0x00000010 -#define SX_DEBUG_TRANSMIT 0x00000020 -#define SX_DEBUG_RECEIVE 0x00000040 -#define SX_DEBUG_INTERRUPTS 0x00000080 -#define SX_DEBUG_PROBE 0x00000100 -#define SX_DEBUG_INIT 0x00000200 -#define SX_DEBUG_CLEANUP 0x00000400 -#define SX_DEBUG_CLOSE 0x00000800 -#define SX_DEBUG_FIRMWARE 0x00001000 -#define SX_DEBUG_MEMTEST 0x00002000 - -#define SX_DEBUG_ALL 0xffffffff - - -#define O_OTHER(tty) \ - ((O_OLCUC(tty)) ||\ - (O_ONLCR(tty)) ||\ - (O_OCRNL(tty)) ||\ - (O_ONOCR(tty)) ||\ - (O_ONLRET(tty)) ||\ - (O_OFILL(tty)) ||\ - (O_OFDEL(tty)) ||\ - (O_NLDLY(tty)) ||\ - (O_CRDLY(tty)) ||\ - (O_TABDLY(tty)) ||\ - (O_BSDLY(tty)) ||\ - (O_VTDLY(tty)) ||\ - (O_FFDLY(tty))) - -/* Same for input. */ -#define I_OTHER(tty) \ - ((I_INLCR(tty)) ||\ - (I_IGNCR(tty)) ||\ - (I_ICRNL(tty)) ||\ - (I_IUCLC(tty)) ||\ - (L_ISIG(tty))) - -#define MOD_TA ( TA>>4) -#define MOD_MTA (MTA_CD1400>>4) -#define MOD_SXDC ( SXDC>>4) - - -/* We copy the download code over to the card in chunks of ... bytes */ -#define SX_CHUNK_SIZE 128 - -#endif /* __KERNEL__ */ - - - -/* Specialix document 6210046-11 page 3 */ -#define SPX(X) (('S'<<24) | ('P' << 16) | (X)) - -/* Specialix-Linux specific IOCTLS. */ -#define SPXL(X) (SPX(('L' << 8) | (X))) - - -#define SXIO_SET_BOARD SPXL(0x01) -#define SXIO_GET_TYPE SPXL(0x02) -#define SXIO_DOWNLOAD SPXL(0x03) -#define SXIO_INIT SPXL(0x04) -#define SXIO_SETDEBUG SPXL(0x05) -#define SXIO_GETDEBUG SPXL(0x06) -#define SXIO_DO_RAMTEST SPXL(0x07) -#define SXIO_SETGSDEBUG SPXL(0x08) -#define SXIO_GETGSDEBUG SPXL(0x09) -#define SXIO_GETNPORTS SPXL(0x0a) - - -#ifndef SXCTL_MISC_MINOR -/* Allow others to gather this into "major.h" or something like that */ -#define SXCTL_MISC_MINOR 167 -#endif - -#ifndef SX_NORMAL_MAJOR -/* This allows overriding on the compiler commandline, or in a "major.h" - include or something like that */ -#define SX_NORMAL_MAJOR 32 -#define SX_CALLOUT_MAJOR 33 -#endif - - -#define SX_TYPE_SX 0x01 -#define SX_TYPE_SI 0x02 -#define SX_TYPE_CF 0x03 - - -#define WINDOW_LEN(board) (IS_CF_BOARD(board)?0x20000:SX_WINDOW_LEN) -/* Need a #define for ^^^^^^^ !!! */ - diff --git a/drivers/char/sxboards.h b/drivers/char/sxboards.h deleted file mode 100644 index 427927dc7dbf..000000000000 --- a/drivers/char/sxboards.h +++ /dev/null @@ -1,206 +0,0 @@ -/************************************************************************/ -/* */ -/* Title : SX/SI/XIO Board Hardware Definitions */ -/* */ -/* Author : N.P.Vassallo */ -/* */ -/* Creation : 16th March 1998 */ -/* */ -/* Version : 3.0.0 */ -/* */ -/* Copyright : (c) Specialix International Ltd. 1998 */ -/* */ -/* Description : Prototypes, structures and definitions */ -/* describing the SX/SI/XIO board hardware */ -/* */ -/************************************************************************/ - -/* History... - -3.0.0 16/03/98 NPV Creation. - -*/ - -#ifndef _sxboards_h /* If SXBOARDS.H not already defined */ -#define _sxboards_h 1 - -/***************************************************************************** -******************************* ****************************** -******************************* Board Types ****************************** -******************************* ****************************** -*****************************************************************************/ - -/* BUS types... */ -#define BUS_ISA 0 -#define BUS_MCA 1 -#define BUS_EISA 2 -#define BUS_PCI 3 - -/* Board phases... */ -#define SI1_Z280 1 -#define SI2_Z280 2 -#define SI3_T225 3 - -/* Board types... */ -#define CARD_TYPE(bus,phase) (bus<<4|phase) -#define CARD_BUS(type) ((type>>4)&0xF) -#define CARD_PHASE(type) (type&0xF) - -#define TYPE_SI1_ISA CARD_TYPE(BUS_ISA,SI1_Z280) -#define TYPE_SI2_ISA CARD_TYPE(BUS_ISA,SI2_Z280) -#define TYPE_SI2_EISA CARD_TYPE(BUS_EISA,SI2_Z280) -#define TYPE_SI2_PCI CARD_TYPE(BUS_PCI,SI2_Z280) - -#define TYPE_SX_ISA CARD_TYPE(BUS_ISA,SI3_T225) -#define TYPE_SX_PCI CARD_TYPE(BUS_PCI,SI3_T225) -/***************************************************************************** -****************************** ****************************** -****************************** Phase 1 Z280 ****************************** -****************************** ****************************** -*****************************************************************************/ - -/* ISA board details... */ -#define SI1_ISA_WINDOW_LEN 0x10000 /* 64 Kbyte shared memory window */ -//#define SI1_ISA_MEMORY_LEN 0x8000 /* Usable memory - unused define*/ -//#define SI1_ISA_ADDR_LOW 0x0A0000 /* Lowest address = 640 Kbyte */ -//#define SI1_ISA_ADDR_HIGH 0xFF8000 /* Highest address = 16Mbyte - 32Kbyte */ -//#define SI2_ISA_ADDR_STEP SI2_ISA_WINDOW_LEN/* ISA board address step */ -//#define SI2_ISA_IRQ_MASK 0x9800 /* IRQs 15,12,11 */ - -/* ISA board, register definitions... */ -//#define SI2_ISA_ID_BASE 0x7FF8 /* READ: Board ID string */ -#define SI1_ISA_RESET 0x8000 /* WRITE: Host Reset */ -#define SI1_ISA_RESET_CLEAR 0xc000 /* WRITE: Host Reset clear*/ -#define SI1_ISA_WAIT 0x9000 /* WRITE: Host wait */ -#define SI1_ISA_WAIT_CLEAR 0xd000 /* WRITE: Host wait clear */ -#define SI1_ISA_INTCL 0xa000 /* WRITE: Host Reset */ -#define SI1_ISA_INTCL_CLEAR 0xe000 /* WRITE: Host Reset */ - - -/***************************************************************************** -****************************** ****************************** -****************************** Phase 2 Z280 ****************************** -****************************** ****************************** -*****************************************************************************/ - -/* ISA board details... */ -#define SI2_ISA_WINDOW_LEN 0x8000 /* 32 Kbyte shared memory window */ -#define SI2_ISA_MEMORY_LEN 0x7FF8 /* Usable memory */ -#define SI2_ISA_ADDR_LOW 0x0A0000 /* Lowest address = 640 Kbyte */ -#define SI2_ISA_ADDR_HIGH 0xFF8000 /* Highest address = 16Mbyte - 32Kbyte */ -#define SI2_ISA_ADDR_STEP SI2_ISA_WINDOW_LEN/* ISA board address step */ -#define SI2_ISA_IRQ_MASK 0x9800 /* IRQs 15,12,11 */ - -/* ISA board, register definitions... */ -#define SI2_ISA_ID_BASE 0x7FF8 /* READ: Board ID string */ -#define SI2_ISA_RESET SI2_ISA_ID_BASE /* WRITE: Host Reset */ -#define SI2_ISA_IRQ11 (SI2_ISA_ID_BASE+1) /* WRITE: Set IRQ11 */ -#define SI2_ISA_IRQ12 (SI2_ISA_ID_BASE+2) /* WRITE: Set IRQ12 */ -#define SI2_ISA_IRQ15 (SI2_ISA_ID_BASE+3) /* WRITE: Set IRQ15 */ -#define SI2_ISA_IRQSET (SI2_ISA_ID_BASE+4) /* WRITE: Set Host Interrupt */ -#define SI2_ISA_INTCLEAR (SI2_ISA_ID_BASE+5) /* WRITE: Enable Host Interrupt */ - -#define SI2_ISA_IRQ11_SET 0x10 -#define SI2_ISA_IRQ11_CLEAR 0x00 -#define SI2_ISA_IRQ12_SET 0x10 -#define SI2_ISA_IRQ12_CLEAR 0x00 -#define SI2_ISA_IRQ15_SET 0x10 -#define SI2_ISA_IRQ15_CLEAR 0x00 -#define SI2_ISA_INTCLEAR_SET 0x10 -#define SI2_ISA_INTCLEAR_CLEAR 0x00 -#define SI2_ISA_IRQSET_CLEAR 0x10 -#define SI2_ISA_IRQSET_SET 0x00 -#define SI2_ISA_RESET_SET 0x00 -#define SI2_ISA_RESET_CLEAR 0x10 - -/* PCI board details... */ -#define SI2_PCI_WINDOW_LEN 0x100000 /* 1 Mbyte memory window */ - -/* PCI board register definitions... */ -#define SI2_PCI_SET_IRQ 0x40001 /* Set Host Interrupt */ -#define SI2_PCI_RESET 0xC0001 /* Host Reset */ - -/***************************************************************************** -****************************** ****************************** -****************************** Phase 3 T225 ****************************** -****************************** ****************************** -*****************************************************************************/ - -/* General board details... */ -#define SX_WINDOW_LEN 64*1024 /* 64 Kbyte memory window */ - -/* ISA board details... */ -#define SX_ISA_ADDR_LOW 0x0A0000 /* Lowest address = 640 Kbyte */ -#define SX_ISA_ADDR_HIGH 0xFF8000 /* Highest address = 16Mbyte - 32Kbyte */ -#define SX_ISA_ADDR_STEP SX_WINDOW_LEN /* ISA board address step */ -#define SX_ISA_IRQ_MASK 0x9E00 /* IRQs 15,12,11,10,9 */ - -/* Hardware register definitions... */ -#define SX_EVENT_STATUS 0x7800 /* READ: T225 Event Status */ -#define SX_EVENT_STROBE 0x7800 /* WRITE: T225 Event Strobe */ -#define SX_EVENT_ENABLE 0x7880 /* WRITE: T225 Event Enable */ -#define SX_VPD_ROM 0x7C00 /* READ: Vital Product Data ROM */ -#define SX_CONFIG 0x7C00 /* WRITE: Host Configuration Register */ -#define SX_IRQ_STATUS 0x7C80 /* READ: Host Interrupt Status */ -#define SX_SET_IRQ 0x7C80 /* WRITE: Set Host Interrupt */ -#define SX_RESET_STATUS 0x7D00 /* READ: Host Reset Status */ -#define SX_RESET 0x7D00 /* WRITE: Host Reset */ -#define SX_RESET_IRQ 0x7D80 /* WRITE: Reset Host Interrupt */ - -/* SX_VPD_ROM definitions... */ -#define SX_VPD_SLX_ID1 0x00 -#define SX_VPD_SLX_ID2 0x01 -#define SX_VPD_HW_REV 0x02 -#define SX_VPD_HW_ASSEM 0x03 -#define SX_VPD_UNIQUEID4 0x04 -#define SX_VPD_UNIQUEID3 0x05 -#define SX_VPD_UNIQUEID2 0x06 -#define SX_VPD_UNIQUEID1 0x07 -#define SX_VPD_MANU_YEAR 0x08 -#define SX_VPD_MANU_WEEK 0x09 -#define SX_VPD_IDENT 0x10 -#define SX_VPD_IDENT_STRING "JET HOST BY KEV#" - -/* SX unique identifiers... */ -#define SX_UNIQUEID_MASK 0xF0 -#define SX_ISA_UNIQUEID1 0x20 -#define SX_PCI_UNIQUEID1 0x50 - -/* SX_CONFIG definitions... */ -#define SX_CONF_BUSEN 0x02 /* Enable T225 memory and I/O */ -#define SX_CONF_HOSTIRQ 0x04 /* Enable board to host interrupt */ - -/* SX bootstrap... */ -#define SX_BOOTSTRAP "\x28\x20\x21\x02\x60\x0a" -#define SX_BOOTSTRAP_SIZE 6 -#define SX_BOOTSTRAP_ADDR (0x8000-SX_BOOTSTRAP_SIZE) - -/***************************************************************************** -********************************** ********************************** -********************************** EISA ********************************** -********************************** ********************************** -*****************************************************************************/ - -#define SI2_EISA_OFF 0x42 -#define SI2_EISA_VAL 0x01 -#define SI2_EISA_WINDOW_LEN 0x10000 - -/***************************************************************************** -*********************************** ********************************** -*********************************** PCI ********************************** -*********************************** ********************************** -*****************************************************************************/ - -/* General definitions... */ - -#define SPX_VENDOR_ID 0x11CB /* Assigned by the PCI SIG */ -#define SPX_DEVICE_ID 0x4000 /* SI/XIO boards */ -#define SPX_PLXDEVICE_ID 0x2000 /* SX boards */ - -#define SPX_SUB_VENDOR_ID SPX_VENDOR_ID /* Same as vendor id */ -#define SI2_SUB_SYS_ID 0x400 /* Phase 2 (Z280) board */ -#define SX_SUB_SYS_ID 0x200 /* Phase 3 (t225) board */ - -#endif /*_sxboards_h */ - -/* End of SXBOARDS.H */ diff --git a/drivers/char/sxwindow.h b/drivers/char/sxwindow.h deleted file mode 100644 index cf01b662aefc..000000000000 --- a/drivers/char/sxwindow.h +++ /dev/null @@ -1,393 +0,0 @@ -/************************************************************************/ -/* */ -/* Title : SX Shared Memory Window Structure */ -/* */ -/* Author : N.P.Vassallo */ -/* */ -/* Creation : 16th March 1998 */ -/* */ -/* Version : 3.0.0 */ -/* */ -/* Copyright : (c) Specialix International Ltd. 1998 */ -/* */ -/* Description : Prototypes, structures and definitions */ -/* describing the SX/SI/XIO cards shared */ -/* memory window structure: */ -/* SXCARD */ -/* SXMODULE */ -/* SXCHANNEL */ -/* */ -/************************************************************************/ - -/* History... - -3.0.0 16/03/98 NPV Creation. (based on STRUCT.H) - -*/ - -#ifndef _sxwindow_h /* If SXWINDOW.H not already defined */ -#define _sxwindow_h 1 - -/***************************************************************************** -*************************** *************************** -*************************** Common Definitions *************************** -*************************** *************************** -*****************************************************************************/ - -typedef struct _SXCARD *PSXCARD; /* SXCARD structure pointer */ -typedef struct _SXMODULE *PMOD; /* SXMODULE structure pointer */ -typedef struct _SXCHANNEL *PCHAN; /* SXCHANNEL structure pointer */ - -/***************************************************************************** -********************************* ********************************* -********************************* SXCARD ********************************* -********************************* ********************************* -*****************************************************************************/ - -typedef struct _SXCARD -{ - BYTE cc_init_status; /* 0x00 Initialisation status */ - BYTE cc_mem_size; /* 0x01 Size of memory on card */ - WORD cc_int_count; /* 0x02 Interrupt count */ - WORD cc_revision; /* 0x04 Download code revision */ - BYTE cc_isr_count; /* 0x06 Count when ISR is run */ - BYTE cc_main_count; /* 0x07 Count when main loop is run */ - WORD cc_int_pending; /* 0x08 Interrupt pending */ - WORD cc_poll_count; /* 0x0A Count when poll is run */ - BYTE cc_int_set_count; /* 0x0C Count when host interrupt is set */ - BYTE cc_rfu[0x80 - 0x0D]; /* 0x0D Pad structure to 128 bytes (0x80) */ - -} SXCARD; - -/* SXCARD.cc_init_status definitions... */ -#define ADAPTERS_FOUND (BYTE)0x01 -#define NO_ADAPTERS_FOUND (BYTE)0xFF - -/* SXCARD.cc_mem_size definitions... */ -#define SX_MEMORY_SIZE (BYTE)0x40 - -/* SXCARD.cc_int_count definitions... */ -#define INT_COUNT_DEFAULT 100 /* Hz */ - -/***************************************************************************** -******************************** ******************************** -******************************** SXMODULE ******************************** -******************************** ******************************** -*****************************************************************************/ - -#define TOP_POINTER(a) ((a)|0x8000) /* Sets top bit of word */ -#define UNTOP_POINTER(a) ((a)&~0x8000) /* Clears top bit of word */ - -typedef struct _SXMODULE -{ - WORD mc_next; /* 0x00 Next module "pointer" (ORed with 0x8000) */ - BYTE mc_type; /* 0x02 Type of TA in terms of number of channels */ - BYTE mc_mod_no; /* 0x03 Module number on SI bus cable (0 closest to card) */ - BYTE mc_dtr; /* 0x04 Private DTR copy (TA only) */ - BYTE mc_rfu1; /* 0x05 Reserved */ - WORD mc_uart; /* 0x06 UART base address for this module */ - BYTE mc_chip; /* 0x08 Chip type / number of ports */ - BYTE mc_current_uart; /* 0x09 Current uart selected for this module */ -#ifdef DOWNLOAD - PCHAN mc_chan_pointer[8]; /* 0x0A Pointer to each channel structure */ -#else - WORD mc_chan_pointer[8]; /* 0x0A Define as WORD if not compiling into download */ -#endif - WORD mc_rfu2; /* 0x1A Reserved */ - BYTE mc_opens1; /* 0x1C Number of open ports on first four ports on MTA/SXDC */ - BYTE mc_opens2; /* 0x1D Number of open ports on second four ports on MTA/SXDC */ - BYTE mc_mods; /* 0x1E Types of connector module attached to MTA/SXDC */ - BYTE mc_rev1; /* 0x1F Revision of first CD1400 on MTA/SXDC */ - BYTE mc_rev2; /* 0x20 Revision of second CD1400 on MTA/SXDC */ - BYTE mc_mtaasic_rev; /* 0x21 Revision of MTA ASIC 1..4 -> A, B, C, D */ - BYTE mc_rfu3[0x100 - 0x22]; /* 0x22 Pad structure to 256 bytes (0x100) */ - -} SXMODULE; - -/* SXMODULE.mc_type definitions... */ -#define FOUR_PORTS (BYTE)4 -#define EIGHT_PORTS (BYTE)8 - -/* SXMODULE.mc_chip definitions... */ -#define CHIP_MASK 0xF0 -#define TA (BYTE)0 -#define TA4 (TA | FOUR_PORTS) -#define TA8 (TA | EIGHT_PORTS) -#define TA4_ASIC (BYTE)0x0A -#define TA8_ASIC (BYTE)0x0B -#define MTA_CD1400 (BYTE)0x28 -#define SXDC (BYTE)0x48 - -/* SXMODULE.mc_mods definitions... */ -#define MOD_RS232DB25 0x00 /* RS232 DB25 (socket/plug) */ -#define MOD_RS232RJ45 0x01 /* RS232 RJ45 (shielded/opto-isolated) */ -#define MOD_RESERVED_2 0x02 /* Reserved (RS485) */ -#define MOD_RS422DB25 0x03 /* RS422 DB25 Socket */ -#define MOD_RESERVED_4 0x04 /* Reserved */ -#define MOD_PARALLEL 0x05 /* Parallel */ -#define MOD_RESERVED_6 0x06 /* Reserved (RS423) */ -#define MOD_RESERVED_7 0x07 /* Reserved */ -#define MOD_2_RS232DB25 0x08 /* Rev 2.0 RS232 DB25 (socket/plug) */ -#define MOD_2_RS232RJ45 0x09 /* Rev 2.0 RS232 RJ45 */ -#define MOD_RESERVED_A 0x0A /* Rev 2.0 Reserved */ -#define MOD_2_RS422DB25 0x0B /* Rev 2.0 RS422 DB25 */ -#define MOD_RESERVED_C 0x0C /* Rev 2.0 Reserved */ -#define MOD_2_PARALLEL 0x0D /* Rev 2.0 Parallel */ -#define MOD_RESERVED_E 0x0E /* Rev 2.0 Reserved */ -#define MOD_BLANK 0x0F /* Blank Panel */ - -/***************************************************************************** -******************************** ******************************* -******************************** SXCHANNEL ******************************* -******************************** ******************************* -*****************************************************************************/ - -#define TX_BUFF_OFFSET 0x60 /* Transmit buffer offset in channel structure */ -#define BUFF_POINTER(a) (((a)+TX_BUFF_OFFSET)|0x8000) -#define UNBUFF_POINTER(a) (jet_channel*)(((a)&~0x8000)-TX_BUFF_OFFSET) -#define BUFFER_SIZE 256 -#define HIGH_WATER ((BUFFER_SIZE / 4) * 3) -#define LOW_WATER (BUFFER_SIZE / 4) - -typedef struct _SXCHANNEL -{ - WORD next_item; /* 0x00 Offset from window base of next channels hi_txbuf (ORred with 0x8000) */ - WORD addr_uart; /* 0x02 INTERNAL pointer to uart address. Includes FASTPATH bit */ - WORD module; /* 0x04 Offset from window base of parent SXMODULE structure */ - BYTE type; /* 0x06 Chip type / number of ports (copy of mc_chip) */ - BYTE chan_number; /* 0x07 Channel number on the TA/MTA/SXDC */ - WORD xc_status; /* 0x08 Flow control and I/O status */ - BYTE hi_rxipos; /* 0x0A Receive buffer input index */ - BYTE hi_rxopos; /* 0x0B Receive buffer output index */ - BYTE hi_txopos; /* 0x0C Transmit buffer output index */ - BYTE hi_txipos; /* 0x0D Transmit buffer input index */ - BYTE hi_hstat; /* 0x0E Command register */ - BYTE dtr_bit; /* 0x0F INTERNAL DTR control byte (TA only) */ - BYTE txon; /* 0x10 INTERNAL copy of hi_txon */ - BYTE txoff; /* 0x11 INTERNAL copy of hi_txoff */ - BYTE rxon; /* 0x12 INTERNAL copy of hi_rxon */ - BYTE rxoff; /* 0x13 INTERNAL copy of hi_rxoff */ - BYTE hi_mr1; /* 0x14 Mode Register 1 (databits,parity,RTS rx flow)*/ - BYTE hi_mr2; /* 0x15 Mode Register 2 (stopbits,local,CTS tx flow)*/ - BYTE hi_csr; /* 0x16 Clock Select Register (baud rate) */ - BYTE hi_op; /* 0x17 Modem Output Signal */ - BYTE hi_ip; /* 0x18 Modem Input Signal */ - BYTE hi_state; /* 0x19 Channel status */ - BYTE hi_prtcl; /* 0x1A Channel protocol (flow control) */ - BYTE hi_txon; /* 0x1B Transmit XON character */ - BYTE hi_txoff; /* 0x1C Transmit XOFF character */ - BYTE hi_rxon; /* 0x1D Receive XON character */ - BYTE hi_rxoff; /* 0x1E Receive XOFF character */ - BYTE close_prev; /* 0x1F INTERNAL channel previously closed flag */ - BYTE hi_break; /* 0x20 Break and error control */ - BYTE break_state; /* 0x21 INTERNAL copy of hi_break */ - BYTE hi_mask; /* 0x22 Mask for received data */ - BYTE mask; /* 0x23 INTERNAL copy of hi_mask */ - BYTE mod_type; /* 0x24 MTA/SXDC hardware module type */ - BYTE ccr_state; /* 0x25 INTERNAL MTA/SXDC state of CCR register */ - BYTE ip_mask; /* 0x26 Input handshake mask */ - BYTE hi_parallel; /* 0x27 Parallel port flag */ - BYTE par_error; /* 0x28 Error code for parallel loopback test */ - BYTE any_sent; /* 0x29 INTERNAL data sent flag */ - BYTE asic_txfifo_size; /* 0x2A INTERNAL SXDC transmit FIFO size */ - BYTE rfu1[2]; /* 0x2B Reserved */ - BYTE csr; /* 0x2D INTERNAL copy of hi_csr */ -#ifdef DOWNLOAD - PCHAN nextp; /* 0x2E Offset from window base of next channel structure */ -#else - WORD nextp; /* 0x2E Define as WORD if not compiling into download */ -#endif - BYTE prtcl; /* 0x30 INTERNAL copy of hi_prtcl */ - BYTE mr1; /* 0x31 INTERNAL copy of hi_mr1 */ - BYTE mr2; /* 0x32 INTERNAL copy of hi_mr2 */ - BYTE hi_txbaud; /* 0x33 Extended transmit baud rate (SXDC only if((hi_csr&0x0F)==0x0F) */ - BYTE hi_rxbaud; /* 0x34 Extended receive baud rate (SXDC only if((hi_csr&0xF0)==0xF0) */ - BYTE txbreak_state; /* 0x35 INTERNAL MTA/SXDC transmit break state */ - BYTE txbaud; /* 0x36 INTERNAL copy of hi_txbaud */ - BYTE rxbaud; /* 0x37 INTERNAL copy of hi_rxbaud */ - WORD err_framing; /* 0x38 Count of receive framing errors */ - WORD err_parity; /* 0x3A Count of receive parity errors */ - WORD err_overrun; /* 0x3C Count of receive overrun errors */ - WORD err_overflow; /* 0x3E Count of receive buffer overflow errors */ - BYTE rfu2[TX_BUFF_OFFSET - 0x40]; /* 0x40 Reserved until hi_txbuf */ - BYTE hi_txbuf[BUFFER_SIZE]; /* 0x060 Transmit buffer */ - BYTE hi_rxbuf[BUFFER_SIZE]; /* 0x160 Receive buffer */ - BYTE rfu3[0x300 - 0x260]; /* 0x260 Reserved until 768 bytes (0x300) */ - -} SXCHANNEL; - -/* SXCHANNEL.addr_uart definitions... */ -#define FASTPATH 0x1000 /* Set to indicate fast rx/tx processing (TA only) */ - -/* SXCHANNEL.xc_status definitions... */ -#define X_TANY 0x0001 /* XON is any character (TA only) */ -#define X_TION 0x0001 /* Tx interrupts on (MTA only) */ -#define X_TXEN 0x0002 /* Tx XON/XOFF enabled (TA only) */ -#define X_RTSEN 0x0002 /* RTS FLOW enabled (MTA only) */ -#define X_TXRC 0x0004 /* XOFF received (TA only) */ -#define X_RTSLOW 0x0004 /* RTS dropped (MTA only) */ -#define X_RXEN 0x0008 /* Rx XON/XOFF enabled */ -#define X_ANYXO 0x0010 /* XOFF pending/sent or RTS dropped */ -#define X_RXSE 0x0020 /* Rx XOFF sent */ -#define X_NPEND 0x0040 /* Rx XON pending or XOFF pending */ -#define X_FPEND 0x0080 /* Rx XOFF pending */ -#define C_CRSE 0x0100 /* Carriage return sent (TA only) */ -#define C_TEMR 0x0100 /* Tx empty requested (MTA only) */ -#define C_TEMA 0x0200 /* Tx empty acked (MTA only) */ -#define C_ANYP 0x0200 /* Any protocol bar tx XON/XOFF (TA only) */ -#define C_EN 0x0400 /* Cooking enabled (on MTA means port is also || */ -#define C_HIGH 0x0800 /* Buffer previously hit high water */ -#define C_CTSEN 0x1000 /* CTS automatic flow-control enabled */ -#define C_DCDEN 0x2000 /* DCD/DTR checking enabled */ -#define C_BREAK 0x4000 /* Break detected */ -#define C_RTSEN 0x8000 /* RTS automatic flow control enabled (MTA only) */ -#define C_PARITY 0x8000 /* Parity checking enabled (TA only) */ - -/* SXCHANNEL.hi_hstat definitions... */ -#define HS_IDLE_OPEN 0x00 /* Channel open state */ -#define HS_LOPEN 0x02 /* Local open command (no modem monitoring) */ -#define HS_MOPEN 0x04 /* Modem open command (wait for DCD signal) */ -#define HS_IDLE_MPEND 0x06 /* Waiting for DCD signal state */ -#define HS_CONFIG 0x08 /* Configuration command */ -#define HS_CLOSE 0x0A /* Close command */ -#define HS_START 0x0C /* Start transmit break command */ -#define HS_STOP 0x0E /* Stop transmit break command */ -#define HS_IDLE_CLOSED 0x10 /* Closed channel state */ -#define HS_IDLE_BREAK 0x12 /* Transmit break state */ -#define HS_FORCE_CLOSED 0x14 /* Force close command */ -#define HS_RESUME 0x16 /* Clear pending XOFF command */ -#define HS_WFLUSH 0x18 /* Flush transmit buffer command */ -#define HS_RFLUSH 0x1A /* Flush receive buffer command */ -#define HS_SUSPEND 0x1C /* Suspend output command (like XOFF received) */ -#define PARALLEL 0x1E /* Parallel port loopback test command (Diagnostics Only) */ -#define ENABLE_RX_INTS 0x20 /* Enable receive interrupts command (Diagnostics Only) */ -#define ENABLE_TX_INTS 0x22 /* Enable transmit interrupts command (Diagnostics Only) */ -#define ENABLE_MDM_INTS 0x24 /* Enable modem interrupts command (Diagnostics Only) */ -#define DISABLE_INTS 0x26 /* Disable interrupts command (Diagnostics Only) */ - -/* SXCHANNEL.hi_mr1 definitions... */ -#define MR1_BITS 0x03 /* Data bits mask */ -#define MR1_5_BITS 0x00 /* 5 data bits */ -#define MR1_6_BITS 0x01 /* 6 data bits */ -#define MR1_7_BITS 0x02 /* 7 data bits */ -#define MR1_8_BITS 0x03 /* 8 data bits */ -#define MR1_PARITY 0x1C /* Parity mask */ -#define MR1_ODD 0x04 /* Odd parity */ -#define MR1_EVEN 0x00 /* Even parity */ -#define MR1_WITH 0x00 /* Parity enabled */ -#define MR1_FORCE 0x08 /* Force parity */ -#define MR1_NONE 0x10 /* No parity */ -#define MR1_NOPARITY MR1_NONE /* No parity */ -#define MR1_ODDPARITY (MR1_WITH|MR1_ODD) /* Odd parity */ -#define MR1_EVENPARITY (MR1_WITH|MR1_EVEN) /* Even parity */ -#define MR1_MARKPARITY (MR1_FORCE|MR1_ODD) /* Mark parity */ -#define MR1_SPACEPARITY (MR1_FORCE|MR1_EVEN) /* Space parity */ -#define MR1_RTS_RXFLOW 0x80 /* RTS receive flow control */ - -/* SXCHANNEL.hi_mr2 definitions... */ -#define MR2_STOP 0x0F /* Stop bits mask */ -#define MR2_1_STOP 0x07 /* 1 stop bit */ -#define MR2_2_STOP 0x0F /* 2 stop bits */ -#define MR2_CTS_TXFLOW 0x10 /* CTS transmit flow control */ -#define MR2_RTS_TOGGLE 0x20 /* RTS toggle on transmit */ -#define MR2_NORMAL 0x00 /* Normal mode */ -#define MR2_AUTO 0x40 /* Auto-echo mode (TA only) */ -#define MR2_LOCAL 0x80 /* Local echo mode */ -#define MR2_REMOTE 0xC0 /* Remote echo mode (TA only) */ - -/* SXCHANNEL.hi_csr definitions... */ -#define CSR_75 0x0 /* 75 baud */ -#define CSR_110 0x1 /* 110 baud (TA), 115200 (MTA/SXDC) */ -#define CSR_38400 0x2 /* 38400 baud */ -#define CSR_150 0x3 /* 150 baud */ -#define CSR_300 0x4 /* 300 baud */ -#define CSR_600 0x5 /* 600 baud */ -#define CSR_1200 0x6 /* 1200 baud */ -#define CSR_2000 0x7 /* 2000 baud */ -#define CSR_2400 0x8 /* 2400 baud */ -#define CSR_4800 0x9 /* 4800 baud */ -#define CSR_1800 0xA /* 1800 baud */ -#define CSR_9600 0xB /* 9600 baud */ -#define CSR_19200 0xC /* 19200 baud */ -#define CSR_57600 0xD /* 57600 baud */ -#define CSR_EXTBAUD 0xF /* Extended baud rate (hi_txbaud/hi_rxbaud) */ - -/* SXCHANNEL.hi_op definitions... */ -#define OP_RTS 0x01 /* RTS modem output signal */ -#define OP_DTR 0x02 /* DTR modem output signal */ - -/* SXCHANNEL.hi_ip definitions... */ -#define IP_CTS 0x02 /* CTS modem input signal */ -#define IP_DCD 0x04 /* DCD modem input signal */ -#define IP_DSR 0x20 /* DTR modem input signal */ -#define IP_RI 0x40 /* RI modem input signal */ - -/* SXCHANNEL.hi_state definitions... */ -#define ST_BREAK 0x01 /* Break received (clear with config) */ -#define ST_DCD 0x02 /* DCD signal changed state */ - -/* SXCHANNEL.hi_prtcl definitions... */ -#define SP_TANY 0x01 /* Transmit XON/XANY (if SP_TXEN enabled) */ -#define SP_TXEN 0x02 /* Transmit XON/XOFF flow control */ -#define SP_CEN 0x04 /* Cooking enabled */ -#define SP_RXEN 0x08 /* Rx XON/XOFF enabled */ -#define SP_DCEN 0x20 /* DCD / DTR check */ -#define SP_DTR_RXFLOW 0x40 /* DTR receive flow control */ -#define SP_PAEN 0x80 /* Parity checking enabled */ - -/* SXCHANNEL.hi_break definitions... */ -#define BR_IGN 0x01 /* Ignore any received breaks */ -#define BR_INT 0x02 /* Interrupt on received break */ -#define BR_PARMRK 0x04 /* Enable parmrk parity error processing */ -#define BR_PARIGN 0x08 /* Ignore chars with parity errors */ -#define BR_ERRINT 0x80 /* Treat parity/framing/overrun errors as exceptions */ - -/* SXCHANNEL.par_error definitions.. */ -#define DIAG_IRQ_RX 0x01 /* Indicate serial receive interrupt (diags only) */ -#define DIAG_IRQ_TX 0x02 /* Indicate serial transmit interrupt (diags only) */ -#define DIAG_IRQ_MD 0x04 /* Indicate serial modem interrupt (diags only) */ - -/* SXCHANNEL.hi_txbaud/hi_rxbaud definitions... (SXDC only) */ -#define BAUD_75 0x00 /* 75 baud */ -#define BAUD_115200 0x01 /* 115200 baud */ -#define BAUD_38400 0x02 /* 38400 baud */ -#define BAUD_150 0x03 /* 150 baud */ -#define BAUD_300 0x04 /* 300 baud */ -#define BAUD_600 0x05 /* 600 baud */ -#define BAUD_1200 0x06 /* 1200 baud */ -#define BAUD_2000 0x07 /* 2000 baud */ -#define BAUD_2400 0x08 /* 2400 baud */ -#define BAUD_4800 0x09 /* 4800 baud */ -#define BAUD_1800 0x0A /* 1800 baud */ -#define BAUD_9600 0x0B /* 9600 baud */ -#define BAUD_19200 0x0C /* 19200 baud */ -#define BAUD_57600 0x0D /* 57600 baud */ -#define BAUD_230400 0x0E /* 230400 baud */ -#define BAUD_460800 0x0F /* 460800 baud */ -#define BAUD_921600 0x10 /* 921600 baud */ -#define BAUD_50 0x11 /* 50 baud */ -#define BAUD_110 0x12 /* 110 baud */ -#define BAUD_134_5 0x13 /* 134.5 baud */ -#define BAUD_200 0x14 /* 200 baud */ -#define BAUD_7200 0x15 /* 7200 baud */ -#define BAUD_56000 0x16 /* 56000 baud */ -#define BAUD_64000 0x17 /* 64000 baud */ -#define BAUD_76800 0x18 /* 76800 baud */ -#define BAUD_128000 0x19 /* 128000 baud */ -#define BAUD_150000 0x1A /* 150000 baud */ -#define BAUD_14400 0x1B /* 14400 baud */ -#define BAUD_256000 0x1C /* 256000 baud */ -#define BAUD_28800 0x1D /* 28800 baud */ - -/* SXCHANNEL.txbreak_state definiions... */ -#define TXBREAK_OFF 0 /* Not sending break */ -#define TXBREAK_START 1 /* Begin sending break */ -#define TXBREAK_START1 2 /* Begin sending break, part 1 */ -#define TXBREAK_ON 3 /* Sending break */ -#define TXBREAK_STOP 4 /* Stop sending break */ -#define TXBREAK_STOP1 5 /* Stop sending break, part 1 */ - -#endif /* _sxwindow_h */ - -/* End of SXWINDOW.H */ - diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c deleted file mode 100644 index 96838640f575..000000000000 --- a/drivers/char/vme_scc.c +++ /dev/null @@ -1,1145 +0,0 @@ -/* - * drivers/char/vme_scc.c: MVME147, MVME162, BVME6000 SCC serial ports - * implementation. - * Copyright 1999 Richard Hirst - * - * Based on atari_SCC.c which was - * Copyright 1994-95 Roman Hodek - * Partially based on PC-Linux serial.c by Linus Torvalds and Theodore Ts'o - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_MVME147_SCC -#include -#endif -#ifdef CONFIG_MVME162_SCC -#include -#endif -#ifdef CONFIG_BVME6000_SCC -#include -#endif - -#include -#include "scc.h" - - -#define CHANNEL_A 0 -#define CHANNEL_B 1 - -#define SCC_MINOR_BASE 64 - -/* Shadows for all SCC write registers */ -static unsigned char scc_shadow[2][16]; - -/* Location to access for SCC register access delay */ -static volatile unsigned char *scc_del = NULL; - -/* To keep track of STATUS_REG state for detection of Ext/Status int source */ -static unsigned char scc_last_status_reg[2]; - -/***************************** Prototypes *****************************/ - -/* Function prototypes */ -static void scc_disable_tx_interrupts(void * ptr); -static void scc_enable_tx_interrupts(void * ptr); -static void scc_disable_rx_interrupts(void * ptr); -static void scc_enable_rx_interrupts(void * ptr); -static int scc_carrier_raised(struct tty_port *port); -static void scc_shutdown_port(void * ptr); -static int scc_set_real_termios(void *ptr); -static void scc_hungup(void *ptr); -static void scc_close(void *ptr); -static int scc_chars_in_buffer(void * ptr); -static int scc_open(struct tty_struct * tty, struct file * filp); -static int scc_ioctl(struct tty_struct * tty, - unsigned int cmd, unsigned long arg); -static void scc_throttle(struct tty_struct *tty); -static void scc_unthrottle(struct tty_struct *tty); -static irqreturn_t scc_tx_int(int irq, void *data); -static irqreturn_t scc_rx_int(int irq, void *data); -static irqreturn_t scc_stat_int(int irq, void *data); -static irqreturn_t scc_spcond_int(int irq, void *data); -static void scc_setsignals(struct scc_port *port, int dtr, int rts); -static int scc_break_ctl(struct tty_struct *tty, int break_state); - -static struct tty_driver *scc_driver; - -static struct scc_port scc_ports[2]; - -/*--------------------------------------------------------------------------- - * Interface from generic_serial.c back here - *--------------------------------------------------------------------------*/ - -static struct real_driver scc_real_driver = { - scc_disable_tx_interrupts, - scc_enable_tx_interrupts, - scc_disable_rx_interrupts, - scc_enable_rx_interrupts, - scc_shutdown_port, - scc_set_real_termios, - scc_chars_in_buffer, - scc_close, - scc_hungup, - NULL -}; - - -static const struct tty_operations scc_ops = { - .open = scc_open, - .close = gs_close, - .write = gs_write, - .put_char = gs_put_char, - .flush_chars = gs_flush_chars, - .write_room = gs_write_room, - .chars_in_buffer = gs_chars_in_buffer, - .flush_buffer = gs_flush_buffer, - .ioctl = scc_ioctl, - .throttle = scc_throttle, - .unthrottle = scc_unthrottle, - .set_termios = gs_set_termios, - .stop = gs_stop, - .start = gs_start, - .hangup = gs_hangup, - .break_ctl = scc_break_ctl, -}; - -static const struct tty_port_operations scc_port_ops = { - .carrier_raised = scc_carrier_raised, -}; - -/*---------------------------------------------------------------------------- - * vme_scc_init() and support functions - *---------------------------------------------------------------------------*/ - -static int __init scc_init_drivers(void) -{ - int error; - - scc_driver = alloc_tty_driver(2); - if (!scc_driver) - return -ENOMEM; - scc_driver->owner = THIS_MODULE; - scc_driver->driver_name = "scc"; - scc_driver->name = "ttyS"; - scc_driver->major = TTY_MAJOR; - scc_driver->minor_start = SCC_MINOR_BASE; - scc_driver->type = TTY_DRIVER_TYPE_SERIAL; - scc_driver->subtype = SERIAL_TYPE_NORMAL; - scc_driver->init_termios = tty_std_termios; - scc_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - scc_driver->init_termios.c_ispeed = 9600; - scc_driver->init_termios.c_ospeed = 9600; - scc_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(scc_driver, &scc_ops); - - if ((error = tty_register_driver(scc_driver))) { - printk(KERN_ERR "scc: Couldn't register scc driver, error = %d\n", - error); - put_tty_driver(scc_driver); - return 1; - } - - return 0; -} - - -/* ports[] array is indexed by line no (i.e. [0] for ttyS0, [1] for ttyS1). - */ - -static void __init scc_init_portstructs(void) -{ - struct scc_port *port; - int i; - - for (i = 0; i < 2; i++) { - port = scc_ports + i; - tty_port_init(&port->gs.port); - port->gs.port.ops = &scc_port_ops; - port->gs.magic = SCC_MAGIC; - port->gs.close_delay = HZ/2; - port->gs.closing_wait = 30 * HZ; - port->gs.rd = &scc_real_driver; -#ifdef NEW_WRITE_LOCKING - port->gs.port_write_mutex = MUTEX; -#endif - init_waitqueue_head(&port->gs.port.open_wait); - init_waitqueue_head(&port->gs.port.close_wait); - } -} - - -#ifdef CONFIG_MVME147_SCC -static int __init mvme147_scc_init(void) -{ - struct scc_port *port; - int error; - - printk(KERN_INFO "SCC: MVME147 Serial Driver\n"); - /* Init channel A */ - port = &scc_ports[0]; - port->channel = CHANNEL_A; - port->ctrlp = (volatile unsigned char *)M147_SCC_A_ADDR; - port->datap = port->ctrlp + 1; - port->port_a = &scc_ports[0]; - port->port_b = &scc_ports[1]; - error = request_irq(MVME147_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED, - "SCC-A TX", port); - if (error) - goto fail; - error = request_irq(MVME147_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED, - "SCC-A status", port); - if (error) - goto fail_free_a_tx; - error = request_irq(MVME147_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED, - "SCC-A RX", port); - if (error) - goto fail_free_a_stat; - error = request_irq(MVME147_IRQ_SCCA_SPCOND, scc_spcond_int, - IRQF_DISABLED, "SCC-A special cond", port); - if (error) - goto fail_free_a_rx; - - { - SCC_ACCESS_INIT(port); - - /* disable interrupts for this channel */ - SCCwrite(INT_AND_DMA_REG, 0); - /* Set the interrupt vector */ - SCCwrite(INT_VECTOR_REG, MVME147_IRQ_SCC_BASE); - /* Interrupt parameters: vector includes status, status low */ - SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT); - SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB); - } - - /* Init channel B */ - port = &scc_ports[1]; - port->channel = CHANNEL_B; - port->ctrlp = (volatile unsigned char *)M147_SCC_B_ADDR; - port->datap = port->ctrlp + 1; - port->port_a = &scc_ports[0]; - port->port_b = &scc_ports[1]; - error = request_irq(MVME147_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED, - "SCC-B TX", port); - if (error) - goto fail_free_a_spcond; - error = request_irq(MVME147_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED, - "SCC-B status", port); - if (error) - goto fail_free_b_tx; - error = request_irq(MVME147_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED, - "SCC-B RX", port); - if (error) - goto fail_free_b_stat; - error = request_irq(MVME147_IRQ_SCCB_SPCOND, scc_spcond_int, - IRQF_DISABLED, "SCC-B special cond", port); - if (error) - goto fail_free_b_rx; - - { - SCC_ACCESS_INIT(port); - - /* disable interrupts for this channel */ - SCCwrite(INT_AND_DMA_REG, 0); - } - - /* Ensure interrupts are enabled in the PCC chip */ - m147_pcc->serial_cntrl=PCC_LEVEL_SERIAL|PCC_INT_ENAB; - - /* Initialise the tty driver structures and register */ - scc_init_portstructs(); - scc_init_drivers(); - - return 0; - -fail_free_b_rx: - free_irq(MVME147_IRQ_SCCB_RX, port); -fail_free_b_stat: - free_irq(MVME147_IRQ_SCCB_STAT, port); -fail_free_b_tx: - free_irq(MVME147_IRQ_SCCB_TX, port); -fail_free_a_spcond: - free_irq(MVME147_IRQ_SCCA_SPCOND, port); -fail_free_a_rx: - free_irq(MVME147_IRQ_SCCA_RX, port); -fail_free_a_stat: - free_irq(MVME147_IRQ_SCCA_STAT, port); -fail_free_a_tx: - free_irq(MVME147_IRQ_SCCA_TX, port); -fail: - return error; -} -#endif - - -#ifdef CONFIG_MVME162_SCC -static int __init mvme162_scc_init(void) -{ - struct scc_port *port; - int error; - - if (!(mvme16x_config & MVME16x_CONFIG_GOT_SCCA)) - return (-ENODEV); - - printk(KERN_INFO "SCC: MVME162 Serial Driver\n"); - /* Init channel A */ - port = &scc_ports[0]; - port->channel = CHANNEL_A; - port->ctrlp = (volatile unsigned char *)MVME_SCC_A_ADDR; - port->datap = port->ctrlp + 2; - port->port_a = &scc_ports[0]; - port->port_b = &scc_ports[1]; - error = request_irq(MVME162_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED, - "SCC-A TX", port); - if (error) - goto fail; - error = request_irq(MVME162_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED, - "SCC-A status", port); - if (error) - goto fail_free_a_tx; - error = request_irq(MVME162_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED, - "SCC-A RX", port); - if (error) - goto fail_free_a_stat; - error = request_irq(MVME162_IRQ_SCCA_SPCOND, scc_spcond_int, - IRQF_DISABLED, "SCC-A special cond", port); - if (error) - goto fail_free_a_rx; - - { - SCC_ACCESS_INIT(port); - - /* disable interrupts for this channel */ - SCCwrite(INT_AND_DMA_REG, 0); - /* Set the interrupt vector */ - SCCwrite(INT_VECTOR_REG, MVME162_IRQ_SCC_BASE); - /* Interrupt parameters: vector includes status, status low */ - SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT); - SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB); - } - - /* Init channel B */ - port = &scc_ports[1]; - port->channel = CHANNEL_B; - port->ctrlp = (volatile unsigned char *)MVME_SCC_B_ADDR; - port->datap = port->ctrlp + 2; - port->port_a = &scc_ports[0]; - port->port_b = &scc_ports[1]; - error = request_irq(MVME162_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED, - "SCC-B TX", port); - if (error) - goto fail_free_a_spcond; - error = request_irq(MVME162_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED, - "SCC-B status", port); - if (error) - goto fail_free_b_tx; - error = request_irq(MVME162_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED, - "SCC-B RX", port); - if (error) - goto fail_free_b_stat; - error = request_irq(MVME162_IRQ_SCCB_SPCOND, scc_spcond_int, - IRQF_DISABLED, "SCC-B special cond", port); - if (error) - goto fail_free_b_rx; - - { - SCC_ACCESS_INIT(port); /* Either channel will do */ - - /* disable interrupts for this channel */ - SCCwrite(INT_AND_DMA_REG, 0); - } - - /* Ensure interrupts are enabled in the MC2 chip */ - *(volatile char *)0xfff4201d = 0x14; - - /* Initialise the tty driver structures and register */ - scc_init_portstructs(); - scc_init_drivers(); - - return 0; - -fail_free_b_rx: - free_irq(MVME162_IRQ_SCCB_RX, port); -fail_free_b_stat: - free_irq(MVME162_IRQ_SCCB_STAT, port); -fail_free_b_tx: - free_irq(MVME162_IRQ_SCCB_TX, port); -fail_free_a_spcond: - free_irq(MVME162_IRQ_SCCA_SPCOND, port); -fail_free_a_rx: - free_irq(MVME162_IRQ_SCCA_RX, port); -fail_free_a_stat: - free_irq(MVME162_IRQ_SCCA_STAT, port); -fail_free_a_tx: - free_irq(MVME162_IRQ_SCCA_TX, port); -fail: - return error; -} -#endif - - -#ifdef CONFIG_BVME6000_SCC -static int __init bvme6000_scc_init(void) -{ - struct scc_port *port; - int error; - - printk(KERN_INFO "SCC: BVME6000 Serial Driver\n"); - /* Init channel A */ - port = &scc_ports[0]; - port->channel = CHANNEL_A; - port->ctrlp = (volatile unsigned char *)BVME_SCC_A_ADDR; - port->datap = port->ctrlp + 4; - port->port_a = &scc_ports[0]; - port->port_b = &scc_ports[1]; - error = request_irq(BVME_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED, - "SCC-A TX", port); - if (error) - goto fail; - error = request_irq(BVME_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED, - "SCC-A status", port); - if (error) - goto fail_free_a_tx; - error = request_irq(BVME_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED, - "SCC-A RX", port); - if (error) - goto fail_free_a_stat; - error = request_irq(BVME_IRQ_SCCA_SPCOND, scc_spcond_int, - IRQF_DISABLED, "SCC-A special cond", port); - if (error) - goto fail_free_a_rx; - - { - SCC_ACCESS_INIT(port); - - /* disable interrupts for this channel */ - SCCwrite(INT_AND_DMA_REG, 0); - /* Set the interrupt vector */ - SCCwrite(INT_VECTOR_REG, BVME_IRQ_SCC_BASE); - /* Interrupt parameters: vector includes status, status low */ - SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT); - SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB); - } - - /* Init channel B */ - port = &scc_ports[1]; - port->channel = CHANNEL_B; - port->ctrlp = (volatile unsigned char *)BVME_SCC_B_ADDR; - port->datap = port->ctrlp + 4; - port->port_a = &scc_ports[0]; - port->port_b = &scc_ports[1]; - error = request_irq(BVME_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED, - "SCC-B TX", port); - if (error) - goto fail_free_a_spcond; - error = request_irq(BVME_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED, - "SCC-B status", port); - if (error) - goto fail_free_b_tx; - error = request_irq(BVME_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED, - "SCC-B RX", port); - if (error) - goto fail_free_b_stat; - error = request_irq(BVME_IRQ_SCCB_SPCOND, scc_spcond_int, - IRQF_DISABLED, "SCC-B special cond", port); - if (error) - goto fail_free_b_rx; - - { - SCC_ACCESS_INIT(port); /* Either channel will do */ - - /* disable interrupts for this channel */ - SCCwrite(INT_AND_DMA_REG, 0); - } - - /* Initialise the tty driver structures and register */ - scc_init_portstructs(); - scc_init_drivers(); - - return 0; - -fail: - free_irq(BVME_IRQ_SCCA_STAT, port); -fail_free_a_tx: - free_irq(BVME_IRQ_SCCA_RX, port); -fail_free_a_stat: - free_irq(BVME_IRQ_SCCA_SPCOND, port); -fail_free_a_rx: - free_irq(BVME_IRQ_SCCB_TX, port); -fail_free_a_spcond: - free_irq(BVME_IRQ_SCCB_STAT, port); -fail_free_b_tx: - free_irq(BVME_IRQ_SCCB_RX, port); -fail_free_b_stat: - free_irq(BVME_IRQ_SCCB_SPCOND, port); -fail_free_b_rx: - return error; -} -#endif - - -static int __init vme_scc_init(void) -{ - int res = -ENODEV; - -#ifdef CONFIG_MVME147_SCC - if (MACH_IS_MVME147) - res = mvme147_scc_init(); -#endif -#ifdef CONFIG_MVME162_SCC - if (MACH_IS_MVME16x) - res = mvme162_scc_init(); -#endif -#ifdef CONFIG_BVME6000_SCC - if (MACH_IS_BVME6000) - res = bvme6000_scc_init(); -#endif - return res; -} - -module_init(vme_scc_init); - - -/*--------------------------------------------------------------------------- - * Interrupt handlers - *--------------------------------------------------------------------------*/ - -static irqreturn_t scc_rx_int(int irq, void *data) -{ - unsigned char ch; - struct scc_port *port = data; - struct tty_struct *tty = port->gs.port.tty; - SCC_ACCESS_INIT(port); - - ch = SCCread_NB(RX_DATA_REG); - if (!tty) { - printk(KERN_WARNING "scc_rx_int with NULL tty!\n"); - SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); - return IRQ_HANDLED; - } - tty_insert_flip_char(tty, ch, 0); - - /* Check if another character is already ready; in that case, the - * spcond_int() function must be used, because this character may have an - * error condition that isn't signalled by the interrupt vector used! - */ - if (SCCread(INT_PENDING_REG) & - (port->channel == CHANNEL_A ? IPR_A_RX : IPR_B_RX)) { - scc_spcond_int (irq, data); - return IRQ_HANDLED; - } - - SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); - - tty_flip_buffer_push(tty); - return IRQ_HANDLED; -} - - -static irqreturn_t scc_spcond_int(int irq, void *data) -{ - struct scc_port *port = data; - struct tty_struct *tty = port->gs.port.tty; - unsigned char stat, ch, err; - int int_pending_mask = port->channel == CHANNEL_A ? - IPR_A_RX : IPR_B_RX; - SCC_ACCESS_INIT(port); - - if (!tty) { - printk(KERN_WARNING "scc_spcond_int with NULL tty!\n"); - SCCwrite(COMMAND_REG, CR_ERROR_RESET); - SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); - return IRQ_HANDLED; - } - do { - stat = SCCread(SPCOND_STATUS_REG); - ch = SCCread_NB(RX_DATA_REG); - - if (stat & SCSR_RX_OVERRUN) - err = TTY_OVERRUN; - else if (stat & SCSR_PARITY_ERR) - err = TTY_PARITY; - else if (stat & SCSR_CRC_FRAME_ERR) - err = TTY_FRAME; - else - err = 0; - - tty_insert_flip_char(tty, ch, err); - - /* ++TeSche: *All* errors have to be cleared manually, - * else the condition persists for the next chars - */ - if (err) - SCCwrite(COMMAND_REG, CR_ERROR_RESET); - - } while(SCCread(INT_PENDING_REG) & int_pending_mask); - - SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); - - tty_flip_buffer_push(tty); - return IRQ_HANDLED; -} - - -static irqreturn_t scc_tx_int(int irq, void *data) -{ - struct scc_port *port = data; - SCC_ACCESS_INIT(port); - - if (!port->gs.port.tty) { - printk(KERN_WARNING "scc_tx_int with NULL tty!\n"); - SCCmod (INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0); - SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET); - SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); - return IRQ_HANDLED; - } - while ((SCCread_NB(STATUS_REG) & SR_TX_BUF_EMPTY)) { - if (port->x_char) { - SCCwrite(TX_DATA_REG, port->x_char); - port->x_char = 0; - } - else if ((port->gs.xmit_cnt <= 0) || - port->gs.port.tty->stopped || - port->gs.port.tty->hw_stopped) - break; - else { - SCCwrite(TX_DATA_REG, port->gs.xmit_buf[port->gs.xmit_tail++]); - port->gs.xmit_tail = port->gs.xmit_tail & (SERIAL_XMIT_SIZE-1); - if (--port->gs.xmit_cnt <= 0) - break; - } - } - if ((port->gs.xmit_cnt <= 0) || port->gs.port.tty->stopped || - port->gs.port.tty->hw_stopped) { - /* disable tx interrupts */ - SCCmod (INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0); - SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET); /* disable tx_int on next tx underrun? */ - port->gs.port.flags &= ~GS_TX_INTEN; - } - if (port->gs.port.tty && port->gs.xmit_cnt <= port->gs.wakeup_chars) - tty_wakeup(port->gs.port.tty); - - SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); - return IRQ_HANDLED; -} - - -static irqreturn_t scc_stat_int(int irq, void *data) -{ - struct scc_port *port = data; - unsigned channel = port->channel; - unsigned char last_sr, sr, changed; - SCC_ACCESS_INIT(port); - - last_sr = scc_last_status_reg[channel]; - sr = scc_last_status_reg[channel] = SCCread_NB(STATUS_REG); - changed = last_sr ^ sr; - - if (changed & SR_DCD) { - port->c_dcd = !!(sr & SR_DCD); - if (!(port->gs.port.flags & ASYNC_CHECK_CD)) - ; /* Don't report DCD changes */ - else if (port->c_dcd) { - wake_up_interruptible(&port->gs.port.open_wait); - } - else { - if (port->gs.port.tty) - tty_hangup (port->gs.port.tty); - } - } - SCCwrite(COMMAND_REG, CR_EXTSTAT_RESET); - SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); - return IRQ_HANDLED; -} - - -/*--------------------------------------------------------------------------- - * generic_serial.c callback funtions - *--------------------------------------------------------------------------*/ - -static void scc_disable_tx_interrupts(void *ptr) -{ - struct scc_port *port = ptr; - unsigned long flags; - SCC_ACCESS_INIT(port); - - local_irq_save(flags); - SCCmod(INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0); - port->gs.port.flags &= ~GS_TX_INTEN; - local_irq_restore(flags); -} - - -static void scc_enable_tx_interrupts(void *ptr) -{ - struct scc_port *port = ptr; - unsigned long flags; - SCC_ACCESS_INIT(port); - - local_irq_save(flags); - SCCmod(INT_AND_DMA_REG, 0xff, IDR_TX_INT_ENAB); - /* restart the transmitter */ - scc_tx_int (0, port); - local_irq_restore(flags); -} - - -static void scc_disable_rx_interrupts(void *ptr) -{ - struct scc_port *port = ptr; - unsigned long flags; - SCC_ACCESS_INIT(port); - - local_irq_save(flags); - SCCmod(INT_AND_DMA_REG, - ~(IDR_RX_INT_MASK|IDR_PARERR_AS_SPCOND|IDR_EXTSTAT_INT_ENAB), 0); - local_irq_restore(flags); -} - - -static void scc_enable_rx_interrupts(void *ptr) -{ - struct scc_port *port = ptr; - unsigned long flags; - SCC_ACCESS_INIT(port); - - local_irq_save(flags); - SCCmod(INT_AND_DMA_REG, 0xff, - IDR_EXTSTAT_INT_ENAB|IDR_PARERR_AS_SPCOND|IDR_RX_INT_ALL); - local_irq_restore(flags); -} - - -static int scc_carrier_raised(struct tty_port *port) -{ - struct scc_port *sc = container_of(port, struct scc_port, gs.port); - unsigned channel = sc->channel; - - return !!(scc_last_status_reg[channel] & SR_DCD); -} - - -static void scc_shutdown_port(void *ptr) -{ - struct scc_port *port = ptr; - - port->gs.port.flags &= ~ GS_ACTIVE; - if (port->gs.port.tty && (port->gs.port.tty->termios->c_cflag & HUPCL)) { - scc_setsignals (port, 0, 0); - } -} - - -static int scc_set_real_termios (void *ptr) -{ - /* the SCC has char sizes 5,7,6,8 in that order! */ - static int chsize_map[4] = { 0, 2, 1, 3 }; - unsigned cflag, baud, chsize, channel, brgval = 0; - unsigned long flags; - struct scc_port *port = ptr; - SCC_ACCESS_INIT(port); - - if (!port->gs.port.tty || !port->gs.port.tty->termios) return 0; - - channel = port->channel; - - if (channel == CHANNEL_A) - return 0; /* Settings controlled by boot PROM */ - - cflag = port->gs.port.tty->termios->c_cflag; - baud = port->gs.baud; - chsize = (cflag & CSIZE) >> 4; - - if (baud == 0) { - /* speed == 0 -> drop DTR */ - local_irq_save(flags); - SCCmod(TX_CTRL_REG, ~TCR_DTR, 0); - local_irq_restore(flags); - return 0; - } - else if ((MACH_IS_MVME16x && (baud < 50 || baud > 38400)) || - (MACH_IS_MVME147 && (baud < 50 || baud > 19200)) || - (MACH_IS_BVME6000 &&(baud < 50 || baud > 76800))) { - printk(KERN_NOTICE "SCC: Bad speed requested, %d\n", baud); - return 0; - } - - if (cflag & CLOCAL) - port->gs.port.flags &= ~ASYNC_CHECK_CD; - else - port->gs.port.flags |= ASYNC_CHECK_CD; - -#ifdef CONFIG_MVME147_SCC - if (MACH_IS_MVME147) - brgval = (M147_SCC_PCLK + baud/2) / (16 * 2 * baud) - 2; -#endif -#ifdef CONFIG_MVME162_SCC - if (MACH_IS_MVME16x) - brgval = (MVME_SCC_PCLK + baud/2) / (16 * 2 * baud) - 2; -#endif -#ifdef CONFIG_BVME6000_SCC - if (MACH_IS_BVME6000) - brgval = (BVME_SCC_RTxC + baud/2) / (16 * 2 * baud) - 2; -#endif - /* Now we have all parameters and can go to set them: */ - local_irq_save(flags); - - /* receiver's character size and auto-enables */ - SCCmod(RX_CTRL_REG, ~(RCR_CHSIZE_MASK|RCR_AUTO_ENAB_MODE), - (chsize_map[chsize] << 6) | - ((cflag & CRTSCTS) ? RCR_AUTO_ENAB_MODE : 0)); - /* parity and stop bits (both, Tx and Rx), clock mode never changes */ - SCCmod (AUX1_CTRL_REG, - ~(A1CR_PARITY_MASK | A1CR_MODE_MASK), - ((cflag & PARENB - ? (cflag & PARODD ? A1CR_PARITY_ODD : A1CR_PARITY_EVEN) - : A1CR_PARITY_NONE) - | (cflag & CSTOPB ? A1CR_MODE_ASYNC_2 : A1CR_MODE_ASYNC_1))); - /* sender's character size, set DTR for valid baud rate */ - SCCmod(TX_CTRL_REG, ~TCR_CHSIZE_MASK, chsize_map[chsize] << 5 | TCR_DTR); - /* clock sources never change */ - /* disable BRG before changing the value */ - SCCmod(DPLL_CTRL_REG, ~DCR_BRG_ENAB, 0); - /* BRG value */ - SCCwrite(TIMER_LOW_REG, brgval & 0xff); - SCCwrite(TIMER_HIGH_REG, (brgval >> 8) & 0xff); - /* BRG enable, and clock source never changes */ - SCCmod(DPLL_CTRL_REG, 0xff, DCR_BRG_ENAB); - - local_irq_restore(flags); - - return 0; -} - - -static int scc_chars_in_buffer (void *ptr) -{ - struct scc_port *port = ptr; - SCC_ACCESS_INIT(port); - - return (SCCread (SPCOND_STATUS_REG) & SCSR_ALL_SENT) ? 0 : 1; -} - - -/* Comment taken from sx.c (2.4.0): - I haven't the foggiest why the decrement use count has to happen - here. The whole linux serial drivers stuff needs to be redesigned. - My guess is that this is a hack to minimize the impact of a bug - elsewhere. Thinking about it some more. (try it sometime) Try - running minicom on a serial port that is driven by a modularized - driver. Have the modem hangup. Then remove the driver module. Then - exit minicom. I expect an "oops". -- REW */ - -static void scc_hungup(void *ptr) -{ - scc_disable_tx_interrupts(ptr); - scc_disable_rx_interrupts(ptr); -} - - -static void scc_close(void *ptr) -{ - scc_disable_tx_interrupts(ptr); - scc_disable_rx_interrupts(ptr); -} - - -/*--------------------------------------------------------------------------- - * Internal support functions - *--------------------------------------------------------------------------*/ - -static void scc_setsignals(struct scc_port *port, int dtr, int rts) -{ - unsigned long flags; - unsigned char t; - SCC_ACCESS_INIT(port); - - local_irq_save(flags); - t = SCCread(TX_CTRL_REG); - if (dtr >= 0) t = dtr? (t | TCR_DTR): (t & ~TCR_DTR); - if (rts >= 0) t = rts? (t | TCR_RTS): (t & ~TCR_RTS); - SCCwrite(TX_CTRL_REG, t); - local_irq_restore(flags); -} - - -static void scc_send_xchar(struct tty_struct *tty, char ch) -{ - struct scc_port *port = tty->driver_data; - - port->x_char = ch; - if (ch) - scc_enable_tx_interrupts(port); -} - - -/*--------------------------------------------------------------------------- - * Driver entrypoints referenced from above - *--------------------------------------------------------------------------*/ - -static int scc_open (struct tty_struct * tty, struct file * filp) -{ - int line = tty->index; - int retval; - struct scc_port *port = &scc_ports[line]; - int i, channel = port->channel; - unsigned long flags; - SCC_ACCESS_INIT(port); -#if defined(CONFIG_MVME162_SCC) || defined(CONFIG_MVME147_SCC) - static const struct { - unsigned reg, val; - } mvme_init_tab[] = { - /* Values for MVME162 and MVME147 */ - /* no parity, 1 stop bit, async, 1:16 */ - { AUX1_CTRL_REG, A1CR_PARITY_NONE|A1CR_MODE_ASYNC_1|A1CR_CLKMODE_x16 }, - /* parity error is special cond, ints disabled, no DMA */ - { INT_AND_DMA_REG, IDR_PARERR_AS_SPCOND | IDR_RX_INT_DISAB }, - /* Rx 8 bits/char, no auto enable, Rx off */ - { RX_CTRL_REG, RCR_CHSIZE_8 }, - /* DTR off, Tx 8 bits/char, RTS off, Tx off */ - { TX_CTRL_REG, TCR_CHSIZE_8 }, - /* special features off */ - { AUX2_CTRL_REG, 0 }, - { CLK_CTRL_REG, CCR_RXCLK_BRG | CCR_TXCLK_BRG }, - { DPLL_CTRL_REG, DCR_BRG_ENAB | DCR_BRG_USE_PCLK }, - /* Start Rx */ - { RX_CTRL_REG, RCR_RX_ENAB | RCR_CHSIZE_8 }, - /* Start Tx */ - { TX_CTRL_REG, TCR_TX_ENAB | TCR_RTS | TCR_DTR | TCR_CHSIZE_8 }, - /* Ext/Stat ints: DCD only */ - { INT_CTRL_REG, ICR_ENAB_DCD_INT }, - /* Reset Ext/Stat ints */ - { COMMAND_REG, CR_EXTSTAT_RESET }, - /* ...again */ - { COMMAND_REG, CR_EXTSTAT_RESET }, - }; -#endif -#if defined(CONFIG_BVME6000_SCC) - static const struct { - unsigned reg, val; - } bvme_init_tab[] = { - /* Values for BVME6000 */ - /* no parity, 1 stop bit, async, 1:16 */ - { AUX1_CTRL_REG, A1CR_PARITY_NONE|A1CR_MODE_ASYNC_1|A1CR_CLKMODE_x16 }, - /* parity error is special cond, ints disabled, no DMA */ - { INT_AND_DMA_REG, IDR_PARERR_AS_SPCOND | IDR_RX_INT_DISAB }, - /* Rx 8 bits/char, no auto enable, Rx off */ - { RX_CTRL_REG, RCR_CHSIZE_8 }, - /* DTR off, Tx 8 bits/char, RTS off, Tx off */ - { TX_CTRL_REG, TCR_CHSIZE_8 }, - /* special features off */ - { AUX2_CTRL_REG, 0 }, - { CLK_CTRL_REG, CCR_RTxC_XTAL | CCR_RXCLK_BRG | CCR_TXCLK_BRG }, - { DPLL_CTRL_REG, DCR_BRG_ENAB }, - /* Start Rx */ - { RX_CTRL_REG, RCR_RX_ENAB | RCR_CHSIZE_8 }, - /* Start Tx */ - { TX_CTRL_REG, TCR_TX_ENAB | TCR_RTS | TCR_DTR | TCR_CHSIZE_8 }, - /* Ext/Stat ints: DCD only */ - { INT_CTRL_REG, ICR_ENAB_DCD_INT }, - /* Reset Ext/Stat ints */ - { COMMAND_REG, CR_EXTSTAT_RESET }, - /* ...again */ - { COMMAND_REG, CR_EXTSTAT_RESET }, - }; -#endif - if (!(port->gs.port.flags & ASYNC_INITIALIZED)) { - local_irq_save(flags); -#if defined(CONFIG_MVME147_SCC) || defined(CONFIG_MVME162_SCC) - if (MACH_IS_MVME147 || MACH_IS_MVME16x) { - for (i = 0; i < ARRAY_SIZE(mvme_init_tab); ++i) - SCCwrite(mvme_init_tab[i].reg, mvme_init_tab[i].val); - } -#endif -#if defined(CONFIG_BVME6000_SCC) - if (MACH_IS_BVME6000) { - for (i = 0; i < ARRAY_SIZE(bvme_init_tab); ++i) - SCCwrite(bvme_init_tab[i].reg, bvme_init_tab[i].val); - } -#endif - - /* remember status register for detection of DCD and CTS changes */ - scc_last_status_reg[channel] = SCCread(STATUS_REG); - - port->c_dcd = 0; /* Prevent initial 1->0 interrupt */ - scc_setsignals (port, 1,1); - local_irq_restore(flags); - } - - tty->driver_data = port; - port->gs.port.tty = tty; - port->gs.port.count++; - retval = gs_init_port(&port->gs); - if (retval) { - port->gs.port.count--; - return retval; - } - port->gs.port.flags |= GS_ACTIVE; - retval = gs_block_til_ready(port, filp); - - if (retval) { - port->gs.port.count--; - return retval; - } - - port->c_dcd = tty_port_carrier_raised(&port->gs.port); - - scc_enable_rx_interrupts(port); - - return 0; -} - - -static void scc_throttle (struct tty_struct * tty) -{ - struct scc_port *port = tty->driver_data; - unsigned long flags; - SCC_ACCESS_INIT(port); - - if (tty->termios->c_cflag & CRTSCTS) { - local_irq_save(flags); - SCCmod(TX_CTRL_REG, ~TCR_RTS, 0); - local_irq_restore(flags); - } - if (I_IXOFF(tty)) - scc_send_xchar(tty, STOP_CHAR(tty)); -} - - -static void scc_unthrottle (struct tty_struct * tty) -{ - struct scc_port *port = tty->driver_data; - unsigned long flags; - SCC_ACCESS_INIT(port); - - if (tty->termios->c_cflag & CRTSCTS) { - local_irq_save(flags); - SCCmod(TX_CTRL_REG, 0xff, TCR_RTS); - local_irq_restore(flags); - } - if (I_IXOFF(tty)) - scc_send_xchar(tty, START_CHAR(tty)); -} - - -static int scc_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - return -ENOIOCTLCMD; -} - - -static int scc_break_ctl(struct tty_struct *tty, int break_state) -{ - struct scc_port *port = tty->driver_data; - unsigned long flags; - SCC_ACCESS_INIT(port); - - local_irq_save(flags); - SCCmod(TX_CTRL_REG, ~TCR_SEND_BREAK, - break_state ? TCR_SEND_BREAK : 0); - local_irq_restore(flags); - return 0; -} - - -/*--------------------------------------------------------------------------- - * Serial console stuff... - *--------------------------------------------------------------------------*/ - -#define scc_delay() do { __asm__ __volatile__ (" nop; nop"); } while (0) - -static void scc_ch_write (char ch) -{ - volatile char *p = NULL; - -#ifdef CONFIG_MVME147_SCC - if (MACH_IS_MVME147) - p = (volatile char *)M147_SCC_A_ADDR; -#endif -#ifdef CONFIG_MVME162_SCC - if (MACH_IS_MVME16x) - p = (volatile char *)MVME_SCC_A_ADDR; -#endif -#ifdef CONFIG_BVME6000_SCC - if (MACH_IS_BVME6000) - p = (volatile char *)BVME_SCC_A_ADDR; -#endif - - do { - scc_delay(); - } - while (!(*p & 4)); - scc_delay(); - *p = 8; - scc_delay(); - *p = ch; -} - -/* The console must be locked when we get here. */ - -static void scc_console_write (struct console *co, const char *str, unsigned count) -{ - unsigned long flags; - - local_irq_save(flags); - - while (count--) - { - if (*str == '\n') - scc_ch_write ('\r'); - scc_ch_write (*str++); - } - local_irq_restore(flags); -} - -static struct tty_driver *scc_console_device(struct console *c, int *index) -{ - *index = c->index; - return scc_driver; -} - -static struct console sercons = { - .name = "ttyS", - .write = scc_console_write, - .device = scc_console_device, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - - -static int __init vme_scc_console_init(void) -{ - if (vme_brdtype == VME_TYPE_MVME147 || - vme_brdtype == VME_TYPE_MVME162 || - vme_brdtype == VME_TYPE_MVME172 || - vme_brdtype == VME_TYPE_BVME4000 || - vme_brdtype == VME_TYPE_BVME6000) - register_console(&sercons); - return 0; -} -console_initcall(vme_scc_console_init); diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index fb1fc4e5a8cb..58e4a8e15a0e 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -43,6 +43,8 @@ if !STAGING_EXCLUDE_BUILD source "drivers/staging/tty/Kconfig" +source "drivers/staging/generic_serial/Kconfig" + source "drivers/staging/et131x/Kconfig" source "drivers/staging/slicoss/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index f498e345a01d..ff7372d25c91 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_STAGING) += staging.o obj-y += tty/ +obj-y += generic_serial/ obj-$(CONFIG_ET131X) += et131x/ obj-$(CONFIG_SLICOSS) += slicoss/ obj-$(CONFIG_VIDEO_GO7007) += go7007/ diff --git a/drivers/staging/generic_serial/Kconfig b/drivers/staging/generic_serial/Kconfig new file mode 100644 index 000000000000..795daea37750 --- /dev/null +++ b/drivers/staging/generic_serial/Kconfig @@ -0,0 +1,45 @@ +config A2232 + tristate "Commodore A2232 serial support (EXPERIMENTAL)" + depends on EXPERIMENTAL && ZORRO && BROKEN + ---help--- + This option supports the 2232 7-port serial card shipped with the + Amiga 2000 and other Zorro-bus machines, dating from 1989. At + a max of 19,200 bps, the ports are served by a 6551 ACIA UART chip + each, plus a 8520 CIA, and a master 6502 CPU and buffer as well. The + ports were connected with 8 pin DIN connectors on the card bracket, + for which 8 pin to DB25 adapters were supplied. The card also had + jumpers internally to toggle various pinning configurations. + + This driver can be built as a module; but then "generic_serial" + will also be built as a module. This has to be loaded before + "ser_a2232". If you want to do this, answer M here. + +config SX + tristate "Specialix SX (and SI) card support" + depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) && BROKEN + help + This is a driver for the SX and SI multiport serial cards. + Please read the file for details. + + This driver can only be built as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called sx. If you want to do that, say M here. + +config RIO + tristate "Specialix RIO system support" + depends on SERIAL_NONSTANDARD && BROKEN + help + This is a driver for the Specialix RIO, a smart serial card which + drives an outboard box that can support up to 128 ports. Product + information is at . + There are both ISA and PCI versions. + +config RIO_OLDPCI + bool "Support really old RIO/PCI cards" + depends on RIO + help + Older RIO PCI cards need some initialization-time configuration to + determine the IRQ and some control addresses. If you have a RIO and + this doesn't seem to work, try setting this to Y. + + diff --git a/drivers/staging/generic_serial/Makefile b/drivers/staging/generic_serial/Makefile new file mode 100644 index 000000000000..ffc90c8b013c --- /dev/null +++ b/drivers/staging/generic_serial/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o +obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o +obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o +obj-$(CONFIG_A2232) += ser_a2232.o generic_serial.o +obj-$(CONFIG_SX) += sx.o generic_serial.o +obj-$(CONFIG_RIO) += rio/ generic_serial.o diff --git a/drivers/staging/generic_serial/TODO b/drivers/staging/generic_serial/TODO new file mode 100644 index 000000000000..88756453ac6c --- /dev/null +++ b/drivers/staging/generic_serial/TODO @@ -0,0 +1,6 @@ +These are a few tty/serial drivers that either do not build, +or work if they do build, or if they seem to work, are for obsolete +hardware, or are full of unfixable races and no one uses them anymore. + +If no one steps up to adopt any of these drivers, they will be removed +in the 2.6.41 release. diff --git a/drivers/staging/generic_serial/generic_serial.c b/drivers/staging/generic_serial/generic_serial.c new file mode 100644 index 000000000000..5954ee1dc953 --- /dev/null +++ b/drivers/staging/generic_serial/generic_serial.c @@ -0,0 +1,844 @@ +/* + * generic_serial.c + * + * Copyright (C) 1998/1999 R.E.Wolff@BitWizard.nl + * + * written for the SX serial driver. + * Contains the code that should be shared over all the serial drivers. + * + * Credit for the idea to do it this way might go to Alan Cox. + * + * + * Version 0.1 -- December, 1998. Initial version. + * Version 0.2 -- March, 1999. Some more routines. Bugfixes. Etc. + * Version 0.5 -- August, 1999. Some more fixes. Reformat for Linus. + * + * BitWizard is actively maintaining this file. We sometimes find + * that someone submitted changes to this file. We really appreciate + * your help, but please submit changes through us. We're doing our + * best to be responsive. -- REW + * */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG + +static int gs_debug; + +#ifdef DEBUG +#define gs_dprintk(f, str...) if (gs_debug & f) printk (str) +#else +#define gs_dprintk(f, str...) /* nothing */ +#endif + +#define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter %s\n", __func__) +#define func_exit() gs_dprintk (GS_DEBUG_FLOW, "gs: exit %s\n", __func__) + +#define RS_EVENT_WRITE_WAKEUP 1 + +module_param(gs_debug, int, 0644); + + +int gs_put_char(struct tty_struct * tty, unsigned char ch) +{ + struct gs_port *port; + + func_enter (); + + port = tty->driver_data; + + if (!port) return 0; + + if (! (port->port.flags & ASYNC_INITIALIZED)) return 0; + + /* Take a lock on the serial tranmit buffer! */ + mutex_lock(& port->port_write_mutex); + + if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { + /* Sorry, buffer is full, drop character. Update statistics???? -- REW */ + mutex_unlock(&port->port_write_mutex); + return 0; + } + + port->xmit_buf[port->xmit_head++] = ch; + port->xmit_head &= SERIAL_XMIT_SIZE - 1; + port->xmit_cnt++; /* Characters in buffer */ + + mutex_unlock(&port->port_write_mutex); + func_exit (); + return 1; +} + + +/* +> Problems to take into account are: +> -1- Interrupts that empty part of the buffer. +> -2- page faults on the access to userspace. +> -3- Other processes that are also trying to do a "write". +*/ + +int gs_write(struct tty_struct * tty, + const unsigned char *buf, int count) +{ + struct gs_port *port; + int c, total = 0; + int t; + + func_enter (); + + port = tty->driver_data; + + if (!port) return 0; + + if (! (port->port.flags & ASYNC_INITIALIZED)) + return 0; + + /* get exclusive "write" access to this port (problem 3) */ + /* This is not a spinlock because we can have a disk access (page + fault) in copy_from_user */ + mutex_lock(& port->port_write_mutex); + + while (1) { + + c = count; + + /* This is safe because we "OWN" the "head". Noone else can + change the "head": we own the port_write_mutex. */ + /* Don't overrun the end of the buffer */ + t = SERIAL_XMIT_SIZE - port->xmit_head; + if (t < c) c = t; + + /* This is safe because the xmit_cnt can only decrease. This + would increase "t", so we might copy too little chars. */ + /* Don't copy past the "head" of the buffer */ + t = SERIAL_XMIT_SIZE - 1 - port->xmit_cnt; + if (t < c) c = t; + + /* Can't copy more? break out! */ + if (c <= 0) break; + + memcpy (port->xmit_buf + port->xmit_head, buf, c); + + port -> xmit_cnt += c; + port -> xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE -1); + buf += c; + count -= c; + total += c; + } + mutex_unlock(& port->port_write_mutex); + + gs_dprintk (GS_DEBUG_WRITE, "write: interrupts are %s\n", + (port->port.flags & GS_TX_INTEN)?"enabled": "disabled"); + + if (port->xmit_cnt && + !tty->stopped && + !tty->hw_stopped && + !(port->port.flags & GS_TX_INTEN)) { + port->port.flags |= GS_TX_INTEN; + port->rd->enable_tx_interrupts (port); + } + func_exit (); + return total; +} + + + +int gs_write_room(struct tty_struct * tty) +{ + struct gs_port *port = tty->driver_data; + int ret; + + func_enter (); + ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1; + if (ret < 0) + ret = 0; + func_exit (); + return ret; +} + + +int gs_chars_in_buffer(struct tty_struct *tty) +{ + struct gs_port *port = tty->driver_data; + func_enter (); + + func_exit (); + return port->xmit_cnt; +} + + +static int gs_real_chars_in_buffer(struct tty_struct *tty) +{ + struct gs_port *port; + func_enter (); + + port = tty->driver_data; + + if (!port->rd) return 0; + if (!port->rd->chars_in_buffer) return 0; + + func_exit (); + return port->xmit_cnt + port->rd->chars_in_buffer (port); +} + + +static int gs_wait_tx_flushed (void * ptr, unsigned long timeout) +{ + struct gs_port *port = ptr; + unsigned long end_jiffies; + int jiffies_to_transmit, charsleft = 0, rv = 0; + int rcib; + + func_enter(); + + gs_dprintk (GS_DEBUG_FLUSH, "port=%p.\n", port); + if (port) { + gs_dprintk (GS_DEBUG_FLUSH, "xmit_cnt=%x, xmit_buf=%p, tty=%p.\n", + port->xmit_cnt, port->xmit_buf, port->port.tty); + } + + if (!port || port->xmit_cnt < 0 || !port->xmit_buf) { + gs_dprintk (GS_DEBUG_FLUSH, "ERROR: !port, !port->xmit_buf or prot->xmit_cnt < 0.\n"); + func_exit(); + return -EINVAL; /* This is an error which we don't know how to handle. */ + } + + rcib = gs_real_chars_in_buffer(port->port.tty); + + if(rcib <= 0) { + gs_dprintk (GS_DEBUG_FLUSH, "nothing to wait for.\n"); + func_exit(); + return rv; + } + /* stop trying: now + twice the time it would normally take + seconds */ + if (timeout == 0) timeout = MAX_SCHEDULE_TIMEOUT; + end_jiffies = jiffies; + if (timeout != MAX_SCHEDULE_TIMEOUT) + end_jiffies += port->baud?(2 * rcib * 10 * HZ / port->baud):0; + end_jiffies += timeout; + + gs_dprintk (GS_DEBUG_FLUSH, "now=%lx, end=%lx (%ld).\n", + jiffies, end_jiffies, end_jiffies-jiffies); + + /* the expression is actually jiffies < end_jiffies, but that won't + work around the wraparound. Tricky eh? */ + while ((charsleft = gs_real_chars_in_buffer (port->port.tty)) && + time_after (end_jiffies, jiffies)) { + /* Units check: + chars * (bits/char) * (jiffies /sec) / (bits/sec) = jiffies! + check! */ + + charsleft += 16; /* Allow 16 chars more to be transmitted ... */ + jiffies_to_transmit = port->baud?(1 + charsleft * 10 * HZ / port->baud):0; + /* ^^^ Round up.... */ + if (jiffies_to_transmit <= 0) jiffies_to_transmit = 1; + + gs_dprintk (GS_DEBUG_FLUSH, "Expect to finish in %d jiffies " + "(%d chars).\n", jiffies_to_transmit, charsleft); + + msleep_interruptible(jiffies_to_msecs(jiffies_to_transmit)); + if (signal_pending (current)) { + gs_dprintk (GS_DEBUG_FLUSH, "Signal pending. Bombing out: "); + rv = -EINTR; + break; + } + } + + gs_dprintk (GS_DEBUG_FLUSH, "charsleft = %d.\n", charsleft); + set_current_state (TASK_RUNNING); + + func_exit(); + return rv; +} + + + +void gs_flush_buffer(struct tty_struct *tty) +{ + struct gs_port *port; + unsigned long flags; + + func_enter (); + + port = tty->driver_data; + + if (!port) return; + + /* XXX Would the write semaphore do? */ + spin_lock_irqsave (&port->driver_lock, flags); + port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; + spin_unlock_irqrestore (&port->driver_lock, flags); + + tty_wakeup(tty); + func_exit (); +} + + +void gs_flush_chars(struct tty_struct * tty) +{ + struct gs_port *port; + + func_enter (); + + port = tty->driver_data; + + if (!port) return; + + if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || + !port->xmit_buf) { + func_exit (); + return; + } + + /* Beats me -- REW */ + port->port.flags |= GS_TX_INTEN; + port->rd->enable_tx_interrupts (port); + func_exit (); +} + + +void gs_stop(struct tty_struct * tty) +{ + struct gs_port *port; + + func_enter (); + + port = tty->driver_data; + + if (!port) return; + + if (port->xmit_cnt && + port->xmit_buf && + (port->port.flags & GS_TX_INTEN) ) { + port->port.flags &= ~GS_TX_INTEN; + port->rd->disable_tx_interrupts (port); + } + func_exit (); +} + + +void gs_start(struct tty_struct * tty) +{ + struct gs_port *port; + + port = tty->driver_data; + + if (!port) return; + + if (port->xmit_cnt && + port->xmit_buf && + !(port->port.flags & GS_TX_INTEN) ) { + port->port.flags |= GS_TX_INTEN; + port->rd->enable_tx_interrupts (port); + } + func_exit (); +} + + +static void gs_shutdown_port (struct gs_port *port) +{ + unsigned long flags; + + func_enter(); + + if (!port) return; + + if (!(port->port.flags & ASYNC_INITIALIZED)) + return; + + spin_lock_irqsave(&port->driver_lock, flags); + + if (port->xmit_buf) { + free_page((unsigned long) port->xmit_buf); + port->xmit_buf = NULL; + } + + if (port->port.tty) + set_bit(TTY_IO_ERROR, &port->port.tty->flags); + + port->rd->shutdown_port (port); + + port->port.flags &= ~ASYNC_INITIALIZED; + spin_unlock_irqrestore(&port->driver_lock, flags); + + func_exit(); +} + + +void gs_hangup(struct tty_struct *tty) +{ + struct gs_port *port; + unsigned long flags; + + func_enter (); + + port = tty->driver_data; + tty = port->port.tty; + if (!tty) + return; + + gs_shutdown_port (port); + spin_lock_irqsave(&port->port.lock, flags); + port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|GS_ACTIVE); + port->port.tty = NULL; + port->port.count = 0; + spin_unlock_irqrestore(&port->port.lock, flags); + + wake_up_interruptible(&port->port.open_wait); + func_exit (); +} + + +int gs_block_til_ready(void *port_, struct file * filp) +{ + struct gs_port *gp = port_; + struct tty_port *port = &gp->port; + DECLARE_WAITQUEUE(wait, current); + int retval; + int do_clocal = 0; + int CD; + struct tty_struct *tty; + unsigned long flags; + + func_enter (); + + if (!port) return 0; + + tty = port->tty; + + gs_dprintk (GS_DEBUG_BTR, "Entering gs_block_till_ready.\n"); + /* + * If the device is in the middle of being closed, then block + * until it's done, and then try again. + */ + if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { + interruptible_sleep_on(&port->close_wait); + if (port->flags & ASYNC_HUP_NOTIFY) + return -EAGAIN; + else + return -ERESTARTSYS; + } + + gs_dprintk (GS_DEBUG_BTR, "after hung up\n"); + + /* + * If non-blocking mode is set, or the port is not enabled, + * then make the check up front and then exit. + */ + if ((filp->f_flags & O_NONBLOCK) || + (tty->flags & (1 << TTY_IO_ERROR))) { + port->flags |= ASYNC_NORMAL_ACTIVE; + return 0; + } + + gs_dprintk (GS_DEBUG_BTR, "after nonblock\n"); + + if (C_CLOCAL(tty)) + do_clocal = 1; + + /* + * Block waiting for the carrier detect and the line to become + * free (i.e., not in use by the callout). While we are in + * this loop, port->count is dropped by one, so that + * rs_close() knows when to free things. We restore it upon + * exit, either normal or abnormal. + */ + retval = 0; + + add_wait_queue(&port->open_wait, &wait); + + gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n"); + spin_lock_irqsave(&port->lock, flags); + if (!tty_hung_up_p(filp)) { + port->count--; + } + port->blocked_open++; + spin_unlock_irqrestore(&port->lock, flags); + while (1) { + CD = tty_port_carrier_raised(port); + gs_dprintk (GS_DEBUG_BTR, "CD is now %d.\n", CD); + set_current_state (TASK_INTERRUPTIBLE); + if (tty_hung_up_p(filp) || + !(port->flags & ASYNC_INITIALIZED)) { + if (port->flags & ASYNC_HUP_NOTIFY) + retval = -EAGAIN; + else + retval = -ERESTARTSYS; + break; + } + if (!(port->flags & ASYNC_CLOSING) && + (do_clocal || CD)) + break; + gs_dprintk (GS_DEBUG_BTR, "signal_pending is now: %d (%lx)\n", + (int)signal_pending (current), *(long*)(¤t->blocked)); + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } + schedule(); + } + gs_dprintk (GS_DEBUG_BTR, "Got out of the loop. (%d)\n", + port->blocked_open); + set_current_state (TASK_RUNNING); + remove_wait_queue(&port->open_wait, &wait); + + spin_lock_irqsave(&port->lock, flags); + if (!tty_hung_up_p(filp)) { + port->count++; + } + port->blocked_open--; + if (retval == 0) + port->flags |= ASYNC_NORMAL_ACTIVE; + spin_unlock_irqrestore(&port->lock, flags); + func_exit (); + return retval; +} + + +void gs_close(struct tty_struct * tty, struct file * filp) +{ + unsigned long flags; + struct gs_port *port; + + func_enter (); + + port = tty->driver_data; + + if (!port) return; + + if (!port->port.tty) { + /* This seems to happen when this is called from vhangup. */ + gs_dprintk (GS_DEBUG_CLOSE, "gs: Odd: port->port.tty is NULL\n"); + port->port.tty = tty; + } + + spin_lock_irqsave(&port->port.lock, flags); + + if (tty_hung_up_p(filp)) { + spin_unlock_irqrestore(&port->port.lock, flags); + if (port->rd->hungup) + port->rd->hungup (port); + func_exit (); + return; + } + + if ((tty->count == 1) && (port->port.count != 1)) { + printk(KERN_ERR "gs: gs_close port %p: bad port count;" + " tty->count is 1, port count is %d\n", port, port->port.count); + port->port.count = 1; + } + if (--port->port.count < 0) { + printk(KERN_ERR "gs: gs_close port %p: bad port count: %d\n", port, port->port.count); + port->port.count = 0; + } + + if (port->port.count) { + gs_dprintk(GS_DEBUG_CLOSE, "gs_close port %p: count: %d\n", port, port->port.count); + spin_unlock_irqrestore(&port->port.lock, flags); + func_exit (); + return; + } + port->port.flags |= ASYNC_CLOSING; + + /* + * Now we wait for the transmit buffer to clear; and we notify + * the line discipline to only process XON/XOFF characters. + */ + tty->closing = 1; + /* if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) + tty_wait_until_sent(tty, port->closing_wait); */ + + /* + * At this point we stop accepting input. To do this, we + * disable the receive line status interrupts, and tell the + * interrupt driver to stop checking the data ready bit in the + * line status register. + */ + + spin_lock_irqsave(&port->driver_lock, flags); + port->rd->disable_rx_interrupts (port); + spin_unlock_irqrestore(&port->driver_lock, flags); + spin_unlock_irqrestore(&port->port.lock, flags); + + /* close has no way of returning "EINTR", so discard return value */ + if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) + gs_wait_tx_flushed (port, port->closing_wait); + + port->port.flags &= ~GS_ACTIVE; + + gs_flush_buffer(tty); + + tty_ldisc_flush(tty); + tty->closing = 0; + + spin_lock_irqsave(&port->driver_lock, flags); + port->event = 0; + port->rd->close (port); + port->rd->shutdown_port (port); + spin_unlock_irqrestore(&port->driver_lock, flags); + + spin_lock_irqsave(&port->port.lock, flags); + port->port.tty = NULL; + + if (port->port.blocked_open) { + if (port->close_delay) { + spin_unlock_irqrestore(&port->port.lock, flags); + msleep_interruptible(jiffies_to_msecs(port->close_delay)); + spin_lock_irqsave(&port->port.lock, flags); + } + wake_up_interruptible(&port->port.open_wait); + } + port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING | ASYNC_INITIALIZED); + spin_unlock_irqrestore(&port->port.lock, flags); + wake_up_interruptible(&port->port.close_wait); + + func_exit (); +} + + +void gs_set_termios (struct tty_struct * tty, + struct ktermios * old_termios) +{ + struct gs_port *port; + int baudrate, tmp, rv; + struct ktermios *tiosp; + + func_enter(); + + port = tty->driver_data; + + if (!port) return; + if (!port->port.tty) { + /* This seems to happen when this is called after gs_close. */ + gs_dprintk (GS_DEBUG_TERMIOS, "gs: Odd: port->port.tty is NULL\n"); + port->port.tty = tty; + } + + + tiosp = tty->termios; + + if (gs_debug & GS_DEBUG_TERMIOS) { + gs_dprintk (GS_DEBUG_TERMIOS, "termios structure (%p):\n", tiosp); + } + + if(old_termios && (gs_debug & GS_DEBUG_TERMIOS)) { + if(tiosp->c_iflag != old_termios->c_iflag) printk("c_iflag changed\n"); + if(tiosp->c_oflag != old_termios->c_oflag) printk("c_oflag changed\n"); + if(tiosp->c_cflag != old_termios->c_cflag) printk("c_cflag changed\n"); + if(tiosp->c_lflag != old_termios->c_lflag) printk("c_lflag changed\n"); + if(tiosp->c_line != old_termios->c_line) printk("c_line changed\n"); + if(!memcmp(tiosp->c_cc, old_termios->c_cc, NCC)) printk("c_cc changed\n"); + } + + baudrate = tty_get_baud_rate(tty); + + if ((tiosp->c_cflag & CBAUD) == B38400) { + if ( (port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + baudrate = 57600; + else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + baudrate = 115200; + else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + baudrate = 230400; + else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + baudrate = 460800; + else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) + baudrate = (port->baud_base / port->custom_divisor); + } + + /* I recommend using THIS instead of the mess in termios (and + duplicating the above code). Next we should create a clean + interface towards this variable. If your card supports arbitrary + baud rates, (e.g. CD1400 or 16550 based cards) then everything + will be very easy..... */ + port->baud = baudrate; + + /* Two timer ticks seems enough to wakeup something like SLIP driver */ + /* Baudrate/10 is cps. Divide by HZ to get chars per tick. */ + tmp = (baudrate / 10 / HZ) * 2; + + if (tmp < 0) tmp = 0; + if (tmp >= SERIAL_XMIT_SIZE) tmp = SERIAL_XMIT_SIZE-1; + + port->wakeup_chars = tmp; + + /* We should really wait for the characters to be all sent before + changing the settings. -- CAL */ + rv = gs_wait_tx_flushed (port, MAX_SCHEDULE_TIMEOUT); + if (rv < 0) return /* rv */; + + rv = port->rd->set_real_termios(port); + if (rv < 0) return /* rv */; + + if ((!old_termios || + (old_termios->c_cflag & CRTSCTS)) && + !( tiosp->c_cflag & CRTSCTS)) { + tty->stopped = 0; + gs_start(tty); + } + +#ifdef tytso_patch_94Nov25_1726 + /* This "makes sense", Why is it commented out? */ + + if (!(old_termios->c_cflag & CLOCAL) && + (tty->termios->c_cflag & CLOCAL)) + wake_up_interruptible(&port->gs.open_wait); +#endif + + func_exit(); + return /* 0 */; +} + + + +/* Must be called with interrupts enabled */ +int gs_init_port(struct gs_port *port) +{ + unsigned long flags; + + func_enter (); + + if (port->port.flags & ASYNC_INITIALIZED) { + func_exit (); + return 0; + } + if (!port->xmit_buf) { + /* We may sleep in get_zeroed_page() */ + unsigned long tmp; + + tmp = get_zeroed_page(GFP_KERNEL); + spin_lock_irqsave (&port->driver_lock, flags); + if (port->xmit_buf) + free_page (tmp); + else + port->xmit_buf = (unsigned char *) tmp; + spin_unlock_irqrestore(&port->driver_lock, flags); + if (!port->xmit_buf) { + func_exit (); + return -ENOMEM; + } + } + + spin_lock_irqsave (&port->driver_lock, flags); + if (port->port.tty) + clear_bit(TTY_IO_ERROR, &port->port.tty->flags); + mutex_init(&port->port_write_mutex); + port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; + spin_unlock_irqrestore(&port->driver_lock, flags); + gs_set_termios(port->port.tty, NULL); + spin_lock_irqsave (&port->driver_lock, flags); + port->port.flags |= ASYNC_INITIALIZED; + port->port.flags &= ~GS_TX_INTEN; + + spin_unlock_irqrestore(&port->driver_lock, flags); + func_exit (); + return 0; +} + + +int gs_setserial(struct gs_port *port, struct serial_struct __user *sp) +{ + struct serial_struct sio; + + if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) + return(-EFAULT); + + if (!capable(CAP_SYS_ADMIN)) { + if ((sio.baud_base != port->baud_base) || + (sio.close_delay != port->close_delay) || + ((sio.flags & ~ASYNC_USR_MASK) != + (port->port.flags & ~ASYNC_USR_MASK))) + return(-EPERM); + } + + port->port.flags = (port->port.flags & ~ASYNC_USR_MASK) | + (sio.flags & ASYNC_USR_MASK); + + port->baud_base = sio.baud_base; + port->close_delay = sio.close_delay; + port->closing_wait = sio.closing_wait; + port->custom_divisor = sio.custom_divisor; + + gs_set_termios (port->port.tty, NULL); + + return 0; +} + + +/*****************************************************************************/ + +/* + * Generate the serial struct info. + */ + +int gs_getserial(struct gs_port *port, struct serial_struct __user *sp) +{ + struct serial_struct sio; + + memset(&sio, 0, sizeof(struct serial_struct)); + sio.flags = port->port.flags; + sio.baud_base = port->baud_base; + sio.close_delay = port->close_delay; + sio.closing_wait = port->closing_wait; + sio.custom_divisor = port->custom_divisor; + sio.hub6 = 0; + + /* If you want you can override these. */ + sio.type = PORT_UNKNOWN; + sio.xmit_fifo_size = -1; + sio.line = -1; + sio.port = -1; + sio.irq = -1; + + if (port->rd->getserial) + port->rd->getserial (port, &sio); + + if (copy_to_user(sp, &sio, sizeof(struct serial_struct))) + return -EFAULT; + return 0; + +} + + +void gs_got_break(struct gs_port *port) +{ + func_enter (); + + tty_insert_flip_char(port->port.tty, 0, TTY_BREAK); + tty_schedule_flip(port->port.tty); + if (port->port.flags & ASYNC_SAK) { + do_SAK (port->port.tty); + } + + func_exit (); +} + + +EXPORT_SYMBOL(gs_put_char); +EXPORT_SYMBOL(gs_write); +EXPORT_SYMBOL(gs_write_room); +EXPORT_SYMBOL(gs_chars_in_buffer); +EXPORT_SYMBOL(gs_flush_buffer); +EXPORT_SYMBOL(gs_flush_chars); +EXPORT_SYMBOL(gs_stop); +EXPORT_SYMBOL(gs_start); +EXPORT_SYMBOL(gs_hangup); +EXPORT_SYMBOL(gs_block_til_ready); +EXPORT_SYMBOL(gs_close); +EXPORT_SYMBOL(gs_set_termios); +EXPORT_SYMBOL(gs_init_port); +EXPORT_SYMBOL(gs_setserial); +EXPORT_SYMBOL(gs_getserial); +EXPORT_SYMBOL(gs_got_break); + +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/generic_serial/rio/Makefile b/drivers/staging/generic_serial/rio/Makefile new file mode 100644 index 000000000000..1661875883fb --- /dev/null +++ b/drivers/staging/generic_serial/rio/Makefile @@ -0,0 +1,12 @@ +# +# Makefile for the linux rio-subsystem. +# +# (C) R.E.Wolff@BitWizard.nl +# +# This file is GPL. See other files for the full Blurb. I'm lazy today. +# + +obj-$(CONFIG_RIO) += rio.o + +rio-y := rio_linux.o rioinit.o rioboot.o riocmd.o rioctrl.o riointr.o \ + rioparam.o rioroute.o riotable.o riotty.o diff --git a/drivers/staging/generic_serial/rio/board.h b/drivers/staging/generic_serial/rio/board.h new file mode 100644 index 000000000000..bdea633a9076 --- /dev/null +++ b/drivers/staging/generic_serial/rio/board.h @@ -0,0 +1,132 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : board.h +** SID : 1.2 +** Last Modified : 11/6/98 11:34:07 +** Retrieved : 11/6/98 11:34:20 +** +** ident @(#)board.h 1.2 +** +** ----------------------------------------------------------------------------- +*/ + +#ifndef __rio_board_h__ +#define __rio_board_h__ + +/* +** board.h contains the definitions for the *hardware* of the host cards. +** It describes the memory overlay for the dual port RAM area. +*/ + +#define DP_SRAM1_SIZE 0x7C00 +#define DP_SRAM2_SIZE 0x0200 +#define DP_SRAM3_SIZE 0x7000 +#define DP_SCRATCH_SIZE 0x1000 +#define DP_PARMMAP_ADDR 0x01FE /* offset into SRAM2 */ +#define DP_STARTUP_ADDR 0x01F8 /* offset into SRAM2 */ + +/* +** The shape of the Host Control area, at offset 0x7C00, Write Only +*/ +struct s_Ctrl { + u8 DpCtl; /* 7C00 */ + u8 Dp_Unused2_[127]; + u8 DpIntSet; /* 7C80 */ + u8 Dp_Unused3_[127]; + u8 DpTpuReset; /* 7D00 */ + u8 Dp_Unused4_[127]; + u8 DpIntReset; /* 7D80 */ + u8 Dp_Unused5_[127]; +}; + +/* +** The PROM data area on the host (0x7C00), Read Only +*/ +struct s_Prom { + u16 DpSlxCode[2]; + u16 DpRev; + u16 Dp_Unused6_; + u16 DpUniq[4]; + u16 DpJahre; + u16 DpWoche; + u16 DpHwFeature[5]; + u16 DpOemId; + u16 DpSiggy[16]; +}; + +/* +** Union of the Ctrl and Prom areas +*/ +union u_CtrlProm { /* This is the control/PROM area (0x7C00) */ + struct s_Ctrl DpCtrl; + struct s_Prom DpProm; +}; + +/* +** The top end of memory! +*/ +struct s_ParmMapS { /* Area containing Parm Map Pointer */ + u8 Dp_Unused8_[DP_PARMMAP_ADDR]; + u16 DpParmMapAd; +}; + +struct s_StartUpS { + u8 Dp_Unused9_[DP_STARTUP_ADDR]; + u8 Dp_LongJump[0x4]; + u8 Dp_Unused10_[2]; + u8 Dp_ShortJump[0x2]; +}; + +union u_Sram2ParmMap { /* This is the top of memory (0x7E00-0x7FFF) */ + u8 DpSramMem[DP_SRAM2_SIZE]; + struct s_ParmMapS DpParmMapS; + struct s_StartUpS DpStartUpS; +}; + +/* +** This is the DP RAM overlay. +*/ +struct DpRam { + u8 DpSram1[DP_SRAM1_SIZE]; /* 0000 - 7BFF */ + union u_CtrlProm DpCtrlProm; /* 7C00 - 7DFF */ + union u_Sram2ParmMap DpSram2ParmMap; /* 7E00 - 7FFF */ + u8 DpScratch[DP_SCRATCH_SIZE]; /* 8000 - 8FFF */ + u8 DpSram3[DP_SRAM3_SIZE]; /* 9000 - FFFF */ +}; + +#define DpControl DpCtrlProm.DpCtrl.DpCtl +#define DpSetInt DpCtrlProm.DpCtrl.DpIntSet +#define DpResetTpu DpCtrlProm.DpCtrl.DpTpuReset +#define DpResetInt DpCtrlProm.DpCtrl.DpIntReset + +#define DpSlx DpCtrlProm.DpProm.DpSlxCode +#define DpRevision DpCtrlProm.DpProm.DpRev +#define DpUnique DpCtrlProm.DpProm.DpUniq +#define DpYear DpCtrlProm.DpProm.DpJahre +#define DpWeek DpCtrlProm.DpProm.DpWoche +#define DpSignature DpCtrlProm.DpProm.DpSiggy + +#define DpParmMapR DpSram2ParmMap.DpParmMapS.DpParmMapAd +#define DpSram2 DpSram2ParmMap.DpSramMem + +#endif diff --git a/drivers/staging/generic_serial/rio/cirrus.h b/drivers/staging/generic_serial/rio/cirrus.h new file mode 100644 index 000000000000..5ab51679caa2 --- /dev/null +++ b/drivers/staging/generic_serial/rio/cirrus.h @@ -0,0 +1,210 @@ +/**************************************************************************** + ******* ******* + ******* CIRRUS.H ******* + ******* ******* + **************************************************************************** + + Author : Jeremy Rolls + Date : 3 Aug 1990 + + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Version : 0.01 + + + Mods + ---------------------------------------------------------------------------- + Date By Description + ---------------------------------------------------------------------------- + + ***************************************************************************/ + +#ifndef _cirrus_h +#define _cirrus_h 1 + +/* Bit fields for particular registers shared with driver */ + +/* COR1 - driver and RTA */ +#define RIOC_COR1_ODD 0x80 /* Odd parity */ +#define RIOC_COR1_EVEN 0x00 /* Even parity */ +#define RIOC_COR1_NOP 0x00 /* No parity */ +#define RIOC_COR1_FORCE 0x20 /* Force parity */ +#define RIOC_COR1_NORMAL 0x40 /* With parity */ +#define RIOC_COR1_1STOP 0x00 /* 1 stop bit */ +#define RIOC_COR1_15STOP 0x04 /* 1.5 stop bits */ +#define RIOC_COR1_2STOP 0x08 /* 2 stop bits */ +#define RIOC_COR1_5BITS 0x00 /* 5 data bits */ +#define RIOC_COR1_6BITS 0x01 /* 6 data bits */ +#define RIOC_COR1_7BITS 0x02 /* 7 data bits */ +#define RIOC_COR1_8BITS 0x03 /* 8 data bits */ + +#define RIOC_COR1_HOST 0xef /* Safe host bits */ + +/* RTA only */ +#define RIOC_COR1_CINPCK 0x00 /* Check parity of received characters */ +#define RIOC_COR1_CNINPCK 0x10 /* Don't check parity */ + +/* COR2 bits for both RTA and driver use */ +#define RIOC_COR2_IXANY 0x80 /* IXANY - any character is XON */ +#define RIOC_COR2_IXON 0x40 /* IXON - enable tx soft flowcontrol */ +#define RIOC_COR2_RTSFLOW 0x02 /* Enable tx hardware flow control */ + +/* Additional driver bits */ +#define RIOC_COR2_HUPCL 0x20 /* Hang up on close */ +#define RIOC_COR2_CTSFLOW 0x04 /* Enable rx hardware flow control */ +#define RIOC_COR2_IXOFF 0x01 /* Enable rx software flow control */ +#define RIOC_COR2_DTRFLOW 0x08 /* Enable tx hardware flow control */ + +/* RTA use only */ +#define RIOC_COR2_ETC 0x20 /* Embedded transmit options */ +#define RIOC_COR2_LOCAL 0x10 /* Local loopback mode */ +#define RIOC_COR2_REMOTE 0x08 /* Remote loopback mode */ +#define RIOC_COR2_HOST 0xc2 /* Safe host bits */ + +/* COR3 - RTA use only */ +#define RIOC_COR3_SCDRNG 0x80 /* Enable special char detect for range */ +#define RIOC_COR3_SCD34 0x40 /* Special character detect for SCHR's 3 + 4 */ +#define RIOC_COR3_FCT 0x20 /* Flow control transparency */ +#define RIOC_COR3_SCD12 0x10 /* Special character detect for SCHR's 1 + 2 */ +#define RIOC_COR3_FIFO12 0x0c /* 12 chars for receive FIFO threshold */ +#define RIOC_COR3_FIFO10 0x0a /* 10 chars for receive FIFO threshold */ +#define RIOC_COR3_FIFO8 0x08 /* 8 chars for receive FIFO threshold */ +#define RIOC_COR3_FIFO6 0x06 /* 6 chars for receive FIFO threshold */ + +#define RIOC_COR3_THRESHOLD RIOC_COR3_FIFO8 /* MUST BE LESS THAN MCOR_THRESHOLD */ + +#define RIOC_COR3_DEFAULT (RIOC_COR3_FCT | RIOC_COR3_THRESHOLD) + /* Default bits for COR3 */ + +/* COR4 driver and RTA use */ +#define RIOC_COR4_IGNCR 0x80 /* Throw away CR's on input */ +#define RIOC_COR4_ICRNL 0x40 /* Map CR -> NL on input */ +#define RIOC_COR4_INLCR 0x20 /* Map NL -> CR on input */ +#define RIOC_COR4_IGNBRK 0x10 /* Ignore Break */ +#define RIOC_COR4_NBRKINT 0x08 /* No interrupt on break (-BRKINT) */ +#define RIOC_COR4_RAISEMOD 0x01 /* Raise modem output lines on non-zero baud */ + + +/* COR4 driver only */ +#define RIOC_COR4_IGNPAR 0x04 /* IGNPAR (ignore characters with errors) */ +#define RIOC_COR4_PARMRK 0x02 /* PARMRK */ + +#define RIOC_COR4_HOST 0xf8 /* Safe host bits */ + +/* COR4 RTA only */ +#define RIOC_COR4_CIGNPAR 0x02 /* Thrown away bad characters */ +#define RIOC_COR4_CPARMRK 0x04 /* PARMRK characters */ +#define RIOC_COR4_CNPARMRK 0x03 /* Don't PARMRK */ + +/* COR5 driver and RTA use */ +#define RIOC_COR5_ISTRIP 0x80 /* Strip input chars to 7 bits */ +#define RIOC_COR5_LNE 0x40 /* Enable LNEXT processing */ +#define RIOC_COR5_CMOE 0x20 /* Match good and errored characters */ +#define RIOC_COR5_ONLCR 0x02 /* NL -> CR NL on output */ +#define RIOC_COR5_OCRNL 0x01 /* CR -> NL on output */ + +/* +** Spare bits - these are not used in the CIRRUS registers, so we use +** them to set various other features. +*/ +/* +** tstop and tbusy indication +*/ +#define RIOC_COR5_TSTATE_ON 0x08 /* Turn on monitoring of tbusy and tstop */ +#define RIOC_COR5_TSTATE_OFF 0x04 /* Turn off monitoring of tbusy and tstop */ +/* +** TAB3 +*/ +#define RIOC_COR5_TAB3 0x10 /* TAB3 mode */ + +#define RIOC_COR5_HOST 0xc3 /* Safe host bits */ + +/* CCSR */ +#define RIOC_CCSR_TXFLOFF 0x04 /* Tx is xoffed */ + +/* MSVR1 */ +/* NB. DTR / CD swapped from Cirrus spec as the pins are also reversed on the + RTA. This is because otherwise DCD would get lost on the 1 parallel / 3 + serial option. +*/ +#define RIOC_MSVR1_CD 0x80 /* CD (DSR on Cirrus) */ +#define RIOC_MSVR1_RTS 0x40 /* RTS (CTS on Cirrus) */ +#define RIOC_MSVR1_RI 0x20 /* RI */ +#define RIOC_MSVR1_DTR 0x10 /* DTR (CD on Cirrus) */ +#define RIOC_MSVR1_CTS 0x01 /* CTS output pin (RTS on Cirrus) */ +/* Next two used to indicate state of tbusy and tstop to driver */ +#define RIOC_MSVR1_TSTOP 0x08 /* Set if port flow controlled */ +#define RIOC_MSVR1_TEMPTY 0x04 /* Set if port tx buffer empty */ + +#define RIOC_MSVR1_HOST 0xf3 /* The bits the host wants */ + +/* Defines for the subscripts of a CONFIG packet */ +#define RIOC_CONFIG_COR1 1 /* Option register 1 */ +#define RIOC_CONFIG_COR2 2 /* Option register 2 */ +#define RIOC_CONFIG_COR4 3 /* Option register 4 */ +#define RIOC_CONFIG_COR5 4 /* Option register 5 */ +#define RIOC_CONFIG_TXXON 5 /* Tx XON character */ +#define RIOC_CONFIG_TXXOFF 6 /* Tx XOFF character */ +#define RIOC_CONFIG_RXXON 7 /* Rx XON character */ +#define RIOC_CONFIG_RXXOFF 8 /* Rx XOFF character */ +#define RIOC_CONFIG_LNEXT 9 /* LNEXT character */ +#define RIOC_CONFIG_TXBAUD 10 /* Tx baud rate */ +#define RIOC_CONFIG_RXBAUD 11 /* Rx baud rate */ + +#define RIOC_PRE_EMPTIVE 0x80 /* Pre-emptive bit in command field */ + +/* Packet types going from Host to remote - with the exception of OPEN, MOPEN, + CONFIG, SBREAK and MEMDUMP the remaining bytes of the data array will not + be used +*/ +#define RIOC_OPEN 0x00 /* Open a port */ +#define RIOC_CONFIG 0x01 /* Configure a port */ +#define RIOC_MOPEN 0x02 /* Modem open (block for DCD) */ +#define RIOC_CLOSE 0x03 /* Close a port */ +#define RIOC_WFLUSH (0x04 | RIOC_PRE_EMPTIVE) /* Write flush */ +#define RIOC_RFLUSH (0x05 | RIOC_PRE_EMPTIVE) /* Read flush */ +#define RIOC_RESUME (0x06 | RIOC_PRE_EMPTIVE) /* Resume if xoffed */ +#define RIOC_SBREAK 0x07 /* Start break */ +#define RIOC_EBREAK 0x08 /* End break */ +#define RIOC_SUSPEND (0x09 | RIOC_PRE_EMPTIVE) /* Susp op (behave as tho xoffed) */ +#define RIOC_FCLOSE (0x0a | RIOC_PRE_EMPTIVE) /* Force close */ +#define RIOC_XPRINT 0x0b /* Xprint packet */ +#define RIOC_MBIS (0x0c | RIOC_PRE_EMPTIVE) /* Set modem lines */ +#define RIOC_MBIC (0x0d | RIOC_PRE_EMPTIVE) /* Clear modem lines */ +#define RIOC_MSET (0x0e | RIOC_PRE_EMPTIVE) /* Set modem lines */ +#define RIOC_PCLOSE 0x0f /* Pseudo close - Leaves rx/tx enabled */ +#define RIOC_MGET (0x10 | RIOC_PRE_EMPTIVE) /* Force update of modem status */ +#define RIOC_MEMDUMP (0x11 | RIOC_PRE_EMPTIVE) /* Send back mem from addr supplied */ +#define RIOC_READ_REGISTER (0x12 | RIOC_PRE_EMPTIVE) /* Read CD1400 register (debug) */ + +/* "Command" packets going from remote to host COMPLETE and MODEM_STATUS + use data[4] / data[3] to indicate current state and modem status respectively +*/ + +#define RIOC_COMPLETE (0x20 | RIOC_PRE_EMPTIVE) + /* Command complete */ +#define RIOC_BREAK_RECEIVED (0x21 | RIOC_PRE_EMPTIVE) + /* Break received */ +#define RIOC_MODEM_STATUS (0x22 | RIOC_PRE_EMPTIVE) + /* Change in modem status */ + +/* "Command" packet that could go either way - handshake wake-up */ +#define RIOC_HANDSHAKE (0x23 | RIOC_PRE_EMPTIVE) + /* Wake-up to HOST / RTA */ + +#endif diff --git a/drivers/staging/generic_serial/rio/cmdblk.h b/drivers/staging/generic_serial/rio/cmdblk.h new file mode 100644 index 000000000000..9ed4f861675a --- /dev/null +++ b/drivers/staging/generic_serial/rio/cmdblk.h @@ -0,0 +1,53 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : cmdblk.h +** SID : 1.2 +** Last Modified : 11/6/98 11:34:09 +** Retrieved : 11/6/98 11:34:20 +** +** ident @(#)cmdblk.h 1.2 +** +** ----------------------------------------------------------------------------- +*/ + +#ifndef __rio_cmdblk_h__ +#define __rio_cmdblk_h__ + +/* +** the structure of a command block, used to queue commands destined for +** a rup. +*/ + +struct CmdBlk { + struct CmdBlk *NextP; /* Pointer to next command block */ + struct PKT Packet; /* A packet, to copy to the rup */ + /* The func to call to check if OK */ + int (*PreFuncP) (unsigned long, struct CmdBlk *); + int PreArg; /* The arg for the func */ + /* The func to call when completed */ + int (*PostFuncP) (unsigned long, struct CmdBlk *); + int PostArg; /* The arg for the func */ +}; + +#define NUM_RIO_CMD_BLKS (3 * (MAX_RUP * 4 + LINKS_PER_UNIT * 4)) +#endif diff --git a/drivers/staging/generic_serial/rio/cmdpkt.h b/drivers/staging/generic_serial/rio/cmdpkt.h new file mode 100644 index 000000000000..c1e7a2798070 --- /dev/null +++ b/drivers/staging/generic_serial/rio/cmdpkt.h @@ -0,0 +1,177 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : cmdpkt.h +** SID : 1.2 +** Last Modified : 11/6/98 11:34:09 +** Retrieved : 11/6/98 11:34:20 +** +** ident @(#)cmdpkt.h 1.2 +** +** ----------------------------------------------------------------------------- +*/ +#ifndef __rio_cmdpkt_h__ +#define __rio_cmdpkt_h__ + +/* +** overlays for the data area of a packet. Used in both directions +** (to build a packet to send, and to interpret a packet that arrives) +** and is very inconvenient for MIPS, so they appear as two separate +** structures - those used for modifying/reading packets on the card +** and those for modifying/reading packets in real memory, which have an _M +** suffix. +*/ + +#define RTA_BOOT_DATA_SIZE (PKT_MAX_DATA_LEN-2) + +/* +** The boot information packet looks like this: +** This structure overlays a PktCmd->CmdData structure, and so starts +** at Data[2] in the actual pkt! +*/ +struct BootSequence { + u16 NumPackets; + u16 LoadBase; + u16 CodeSize; +}; + +#define BOOT_SEQUENCE_LEN 8 + +struct SamTop { + u8 Unit; + u8 Link; +}; + +struct CmdHdr { + u8 PcCommand; + union { + u8 PcPhbNum; + u8 PcLinkNum; + u8 PcIDNum; + } U0; +}; + + +struct PktCmd { + union { + struct { + struct CmdHdr CmdHdr; + struct BootSequence PcBootSequence; + } S1; + struct { + u16 PcSequence; + u8 PcBootData[RTA_BOOT_DATA_SIZE]; + } S2; + struct { + u16 __crud__; + u8 PcUniqNum[4]; /* this is really a uint. */ + u8 PcModuleTypes; /* what modules are fitted */ + } S3; + struct { + struct CmdHdr CmdHdr; + u8 __undefined__; + u8 PcModemStatus; + u8 PcPortStatus; + u8 PcSubCommand; /* commands like mem or register dump */ + u16 PcSubAddr; /* Address for command */ + u8 PcSubData[64]; /* Date area for command */ + } S4; + struct { + struct CmdHdr CmdHdr; + u8 PcCommandText[1]; + u8 __crud__[20]; + u8 PcIDNum2; /* It had to go somewhere! */ + } S5; + struct { + struct CmdHdr CmdHdr; + struct SamTop Topology[LINKS_PER_UNIT]; + } S6; + } U1; +}; + +struct PktCmd_M { + union { + struct { + struct { + u8 PcCommand; + union { + u8 PcPhbNum; + u8 PcLinkNum; + u8 PcIDNum; + } U0; + } CmdHdr; + struct { + u16 NumPackets; + u16 LoadBase; + u16 CodeSize; + } PcBootSequence; + } S1; + struct { + u16 PcSequence; + u8 PcBootData[RTA_BOOT_DATA_SIZE]; + } S2; + struct { + u16 __crud__; + u8 PcUniqNum[4]; /* this is really a uint. */ + u8 PcModuleTypes; /* what modules are fitted */ + } S3; + struct { + u16 __cmd_hdr__; + u8 __undefined__; + u8 PcModemStatus; + u8 PcPortStatus; + u8 PcSubCommand; + u16 PcSubAddr; + u8 PcSubData[64]; + } S4; + struct { + u16 __cmd_hdr__; + u8 PcCommandText[1]; + u8 __crud__[20]; + u8 PcIDNum2; /* Tacked on end */ + } S5; + struct { + u16 __cmd_hdr__; + struct Top Topology[LINKS_PER_UNIT]; + } S6; + } U1; +}; + +#define Command U1.S1.CmdHdr.PcCommand +#define PhbNum U1.S1.CmdHdr.U0.PcPhbNum +#define IDNum U1.S1.CmdHdr.U0.PcIDNum +#define IDNum2 U1.S5.PcIDNum2 +#define LinkNum U1.S1.CmdHdr.U0.PcLinkNum +#define Sequence U1.S2.PcSequence +#define BootData U1.S2.PcBootData +#define BootSequence U1.S1.PcBootSequence +#define UniqNum U1.S3.PcUniqNum +#define ModemStatus U1.S4.PcModemStatus +#define PortStatus U1.S4.PcPortStatus +#define SubCommand U1.S4.PcSubCommand +#define SubAddr U1.S4.PcSubAddr +#define SubData U1.S4.PcSubData +#define CommandText U1.S5.PcCommandText +#define RouteTopology U1.S6.Topology +#define ModuleTypes U1.S3.PcModuleTypes + +#endif diff --git a/drivers/staging/generic_serial/rio/daemon.h b/drivers/staging/generic_serial/rio/daemon.h new file mode 100644 index 000000000000..4af90323fd00 --- /dev/null +++ b/drivers/staging/generic_serial/rio/daemon.h @@ -0,0 +1,307 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : daemon.h +** SID : 1.3 +** Last Modified : 11/6/98 11:34:09 +** Retrieved : 11/6/98 11:34:21 +** +** ident @(#)daemon.h 1.3 +** +** ----------------------------------------------------------------------------- +*/ + +#ifndef __rio_daemon_h__ +#define __rio_daemon_h__ + + +/* +** structures used on /dev/rio +*/ + +struct Error { + unsigned int Error; + unsigned int Entry; + unsigned int Other; +}; + +struct DownLoad { + char __user *DataP; + unsigned int Count; + unsigned int ProductCode; +}; + +/* +** A few constants.... +*/ +#ifndef MAX_VERSION_LEN +#define MAX_VERSION_LEN 256 +#endif + +#ifndef MAX_XP_CTRL_LEN +#define MAX_XP_CTRL_LEN 16 /* ALSO IN PORT.H */ +#endif + +struct PortSetup { + unsigned int From; /* Set/Clear XP & IXANY Control from this port.... */ + unsigned int To; /* .... to this port */ + unsigned int XpCps; /* at this speed */ + char XpOn[MAX_XP_CTRL_LEN]; /* this is the start string */ + char XpOff[MAX_XP_CTRL_LEN]; /* this is the stop string */ + u8 IxAny; /* enable/disable IXANY */ + u8 IxOn; /* enable/disable IXON */ + u8 Lock; /* lock port params */ + u8 Store; /* store params across closes */ + u8 Drain; /* close only when drained */ +}; + +struct LpbReq { + unsigned int Host; + unsigned int Link; + struct LPB __user *LpbP; +}; + +struct RupReq { + unsigned int HostNum; + unsigned int RupNum; + struct RUP __user *RupP; +}; + +struct PortReq { + unsigned int SysPort; + struct Port __user *PortP; +}; + +struct StreamInfo { + unsigned int SysPort; + int RQueue; + int WQueue; +}; + +struct HostReq { + unsigned int HostNum; + struct Host __user *HostP; +}; + +struct HostDpRam { + unsigned int HostNum; + struct DpRam __user *DpRamP; +}; + +struct DebugCtrl { + unsigned int SysPort; + unsigned int Debug; + unsigned int Wait; +}; + +struct MapInfo { + unsigned int FirstPort; /* 8 ports, starting from this (tty) number */ + unsigned int RtaUnique; /* reside on this RTA (unique number) */ +}; + +struct MapIn { + unsigned int NumEntries; /* How many port sets are we mapping? */ + struct MapInfo *MapInfoP; /* Pointer to (user space) info */ +}; + +struct SendPack { + unsigned int PortNum; + unsigned char Len; + unsigned char Data[PKT_MAX_DATA_LEN]; +}; + +struct SpecialRupCmd { + struct PKT Packet; + unsigned short Host; + unsigned short RupNum; +}; + +struct IdentifyRta { + unsigned long RtaUnique; + u8 ID; +}; + +struct KillNeighbour { + unsigned long UniqueNum; + u8 Link; +}; + +struct rioVersion { + char version[MAX_VERSION_LEN]; + char relid[MAX_VERSION_LEN]; + int buildLevel; + char buildDate[MAX_VERSION_LEN]; +}; + + +/* +** RIOC commands are for the daemon type operations +** +** 09.12.1998 ARG - ESIL 0776 part fix +** Definition for 'RIOC' also appears in rioioctl.h, so we'd better do a +** #ifndef here first. +** rioioctl.h also now has #define 'RIO_QUICK_CHECK' as this ioctl is now +** allowed to be used by customers. +*/ +#ifndef RIOC +#define RIOC ('R'<<8)|('i'<<16)|('o'<<24) +#endif + +/* +** Boot stuff +*/ +#define RIO_GET_TABLE (RIOC | 100) +#define RIO_PUT_TABLE (RIOC | 101) +#define RIO_ASSIGN_RTA (RIOC | 102) +#define RIO_DELETE_RTA (RIOC | 103) +#define RIO_HOST_FOAD (RIOC | 104) +#define RIO_QUICK_CHECK (RIOC | 105) +#define RIO_SIGNALS_ON (RIOC | 106) +#define RIO_SIGNALS_OFF (RIOC | 107) +#define RIO_CHANGE_NAME (RIOC | 108) +#define RIO_DOWNLOAD (RIOC | 109) +#define RIO_GET_LOG (RIOC | 110) +#define RIO_SETUP_PORTS (RIOC | 111) +#define RIO_ALL_MODEM (RIOC | 112) + +/* +** card state, debug stuff +*/ +#define RIO_NUM_HOSTS (RIOC | 120) +#define RIO_HOST_LPB (RIOC | 121) +#define RIO_HOST_RUP (RIOC | 122) +#define RIO_HOST_PORT (RIOC | 123) +#define RIO_PARMS (RIOC | 124) +#define RIO_HOST_REQ (RIOC | 125) +#define RIO_READ_CONFIG (RIOC | 126) +#define RIO_SET_CONFIG (RIOC | 127) +#define RIO_VERSID (RIOC | 128) +#define RIO_FLAGS (RIOC | 129) +#define RIO_SETDEBUG (RIOC | 130) +#define RIO_GETDEBUG (RIOC | 131) +#define RIO_READ_LEVELS (RIOC | 132) +#define RIO_SET_FAST_BUS (RIOC | 133) +#define RIO_SET_SLOW_BUS (RIOC | 134) +#define RIO_SET_BYTE_MODE (RIOC | 135) +#define RIO_SET_WORD_MODE (RIOC | 136) +#define RIO_STREAM_INFO (RIOC | 137) +#define RIO_START_POLLER (RIOC | 138) +#define RIO_STOP_POLLER (RIOC | 139) +#define RIO_LAST_ERROR (RIOC | 140) +#define RIO_TICK (RIOC | 141) +#define RIO_TOCK (RIOC | 241) /* I did this on purpose, you know. */ +#define RIO_SEND_PACKET (RIOC | 142) +#define RIO_SET_BUSY (RIOC | 143) +#define SPECIAL_RUP_CMD (RIOC | 144) +#define RIO_FOAD_RTA (RIOC | 145) +#define RIO_ZOMBIE_RTA (RIOC | 146) +#define RIO_IDENTIFY_RTA (RIOC | 147) +#define RIO_KILL_NEIGHBOUR (RIOC | 148) +#define RIO_DEBUG_MEM (RIOC | 149) +/* +** 150 - 167 used..... See below +*/ +#define RIO_GET_PORT_SETUP (RIOC | 168) +#define RIO_RESUME (RIOC | 169) +#define RIO_MESG (RIOC | 170) +#define RIO_NO_MESG (RIOC | 171) +#define RIO_WHAT_MESG (RIOC | 172) +#define RIO_HOST_DPRAM (RIOC | 173) +#define RIO_MAP_B50_TO_50 (RIOC | 174) +#define RIO_MAP_B50_TO_57600 (RIOC | 175) +#define RIO_MAP_B110_TO_110 (RIOC | 176) +#define RIO_MAP_B110_TO_115200 (RIOC | 177) +#define RIO_GET_PORT_PARAMS (RIOC | 178) +#define RIO_SET_PORT_PARAMS (RIOC | 179) +#define RIO_GET_PORT_TTY (RIOC | 180) +#define RIO_SET_PORT_TTY (RIOC | 181) +#define RIO_SYSLOG_ONLY (RIOC | 182) +#define RIO_SYSLOG_CONS (RIOC | 183) +#define RIO_CONS_ONLY (RIOC | 184) +#define RIO_BLOCK_OPENS (RIOC | 185) + +/* +** 02.03.1999 ARG - ESIL 0820 fix : +** RIOBootMode is no longer use by the driver, so these ioctls +** are now obsolete : +** +#define RIO_GET_BOOT_MODE (RIOC | 186) +#define RIO_SET_BOOT_MODE (RIOC | 187) +** +*/ + +#define RIO_MEM_DUMP (RIOC | 189) +#define RIO_READ_REGISTER (RIOC | 190) +#define RIO_GET_MODTYPE (RIOC | 191) +#define RIO_SET_TIMER (RIOC | 192) +#define RIO_READ_CHECK (RIOC | 196) +#define RIO_WAITING_FOR_RESTART (RIOC | 197) +#define RIO_BIND_RTA (RIOC | 198) +#define RIO_GET_BINDINGS (RIOC | 199) +#define RIO_PUT_BINDINGS (RIOC | 200) + +#define RIO_MAKE_DEV (RIOC | 201) +#define RIO_MINOR (RIOC | 202) + +#define RIO_IDENTIFY_DRIVER (RIOC | 203) +#define RIO_DISPLAY_HOST_CFG (RIOC | 204) + + +/* +** MAKE_DEV / MINOR stuff +*/ +#define RIO_DEV_DIRECT 0x0000 +#define RIO_DEV_MODEM 0x0200 +#define RIO_DEV_XPRINT 0x0400 +#define RIO_DEV_MASK 0x0600 + +/* +** port management, xprint stuff +*/ +#define rIOCN(N) (RIOC|(N)) +#define rIOCR(N,T) (RIOC|(N)) +#define rIOCW(N,T) (RIOC|(N)) + +#define RIO_GET_XP_ON rIOCR(150,char[16]) /* start xprint string */ +#define RIO_SET_XP_ON rIOCW(151,char[16]) +#define RIO_GET_XP_OFF rIOCR(152,char[16]) /* finish xprint string */ +#define RIO_SET_XP_OFF rIOCW(153,char[16]) +#define RIO_GET_XP_CPS rIOCR(154,int) /* xprint CPS */ +#define RIO_SET_XP_CPS rIOCW(155,int) +#define RIO_GET_IXANY rIOCR(156,int) /* ixany allowed? */ +#define RIO_SET_IXANY rIOCW(157,int) +#define RIO_SET_IXANY_ON rIOCN(158) /* allow ixany */ +#define RIO_SET_IXANY_OFF rIOCN(159) /* disallow ixany */ +#define RIO_GET_MODEM rIOCR(160,int) /* port is modem/direct line? */ +#define RIO_SET_MODEM rIOCW(161,int) +#define RIO_SET_MODEM_ON rIOCN(162) /* port is a modem */ +#define RIO_SET_MODEM_OFF rIOCN(163) /* port is direct */ +#define RIO_GET_IXON rIOCR(164,int) /* ixon allowed? */ +#define RIO_SET_IXON rIOCW(165,int) +#define RIO_SET_IXON_ON rIOCN(166) /* allow ixon */ +#define RIO_SET_IXON_OFF rIOCN(167) /* disallow ixon */ + +#define RIO_GET_SIVIEW ((('s')<<8) | 106) /* backwards compatible with SI */ + +#define RIO_IOCTL_UNKNOWN -2 + +#endif diff --git a/drivers/staging/generic_serial/rio/errors.h b/drivers/staging/generic_serial/rio/errors.h new file mode 100644 index 000000000000..bdb05234090a --- /dev/null +++ b/drivers/staging/generic_serial/rio/errors.h @@ -0,0 +1,98 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : errors.h +** SID : 1.2 +** Last Modified : 11/6/98 11:34:10 +** Retrieved : 11/6/98 11:34:21 +** +** ident @(#)errors.h 1.2 +** +** ----------------------------------------------------------------------------- +*/ + +#ifndef __rio_errors_h__ +#define __rio_errors_h__ + +/* +** error codes +*/ + +#define NOTHING_WRONG_AT_ALL 0 +#define BAD_CHARACTER_IN_NAME 1 +#define TABLE_ENTRY_ISNT_PROPERLY_NULL 2 +#define UNKNOWN_HOST_NUMBER 3 +#define ZERO_RTA_ID 4 +#define BAD_RTA_ID 5 +#define DUPLICATED_RTA_ID 6 +#define DUPLICATE_UNIQUE_NUMBER 7 +#define BAD_TTY_NUMBER 8 +#define TTY_NUMBER_IN_USE 9 +#define NAME_USED_TWICE 10 +#define HOST_ID_NOT_ZERO 11 +#define BOOT_IN_PROGRESS 12 +#define COPYIN_FAILED 13 +#define HOST_FILE_TOO_LARGE 14 +#define COPYOUT_FAILED 15 +#define NOT_SUPER_USER 16 +#define RIO_ALREADY_POLLING 17 + +#define ID_NUMBER_OUT_OF_RANGE 18 +#define PORT_NUMBER_OUT_OF_RANGE 19 +#define HOST_NUMBER_OUT_OF_RANGE 20 +#define RUP_NUMBER_OUT_OF_RANGE 21 +#define TTY_NUMBER_OUT_OF_RANGE 22 +#define LINK_NUMBER_OUT_OF_RANGE 23 + +#define HOST_NOT_RUNNING 24 +#define IOCTL_COMMAND_UNKNOWN 25 +#define RIO_SYSTEM_HALTED 26 +#define WAIT_FOR_DRAIN_BROKEN 27 +#define PORT_NOT_MAPPED_INTO_SYSTEM 28 +#define EXCLUSIVE_USE_SET 29 +#define WAIT_FOR_NOT_CLOSING_BROKEN 30 +#define WAIT_FOR_PORT_TO_OPEN_BROKEN 31 +#define WAIT_FOR_CARRIER_BROKEN 32 +#define WAIT_FOR_NOT_IN_USE_BROKEN 33 +#define WAIT_FOR_CAN_ADD_COMMAND_BROKEN 34 +#define WAIT_FOR_ADD_COMMAND_BROKEN 35 +#define WAIT_FOR_NOT_PARAM_BROKEN 36 +#define WAIT_FOR_RETRY_BROKEN 37 +#define HOST_HAS_ALREADY_BEEN_BOOTED 38 +#define UNIT_IS_IN_USE 39 +#define COULDNT_FIND_ENTRY 40 +#define RTA_UNIQUE_NUMBER_ZERO 41 +#define CLOSE_COMMAND_FAILED 42 +#define WAIT_FOR_CLOSE_BROKEN 43 +#define CPS_VALUE_OUT_OF_RANGE 44 +#define ID_ALREADY_IN_USE 45 +#define SIGNALS_ALREADY_SET 46 +#define NOT_RECEIVING_PROCESS 47 +#define RTA_NUMBER_WRONG 48 +#define NO_SUCH_PRODUCT 49 +#define HOST_SYSPORT_BAD 50 +#define ID_NOT_TENTATIVE 51 +#define XPRINT_CPS_OUT_OF_RANGE 52 +#define NOT_ENOUGH_CORE_FOR_PCI_COPY 53 + + +#endif /* __rio_errors_h__ */ diff --git a/drivers/staging/generic_serial/rio/func.h b/drivers/staging/generic_serial/rio/func.h new file mode 100644 index 000000000000..078d44f85e45 --- /dev/null +++ b/drivers/staging/generic_serial/rio/func.h @@ -0,0 +1,143 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : func.h +** SID : 1.3 +** Last Modified : 11/6/98 11:34:10 +** Retrieved : 11/6/98 11:34:21 +** +** ident @(#)func.h 1.3 +** +** ----------------------------------------------------------------------------- +*/ + +#ifndef __func_h_def +#define __func_h_def + +#include + +/* rioboot.c */ +int RIOBootCodeRTA(struct rio_info *, struct DownLoad *); +int RIOBootCodeHOST(struct rio_info *, struct DownLoad *); +int RIOBootCodeUNKNOWN(struct rio_info *, struct DownLoad *); +void msec_timeout(struct Host *); +int RIOBootRup(struct rio_info *, unsigned int, struct Host *, struct PKT __iomem *); +int RIOBootOk(struct rio_info *, struct Host *, unsigned long); +int RIORtaBound(struct rio_info *, unsigned int); +void rio_fill_host_slot(int, int, unsigned int, struct Host *); + +/* riocmd.c */ +int RIOFoadRta(struct Host *, struct Map *); +int RIOZombieRta(struct Host *, struct Map *); +int RIOCommandRta(struct rio_info *, unsigned long, int (*func) (struct Host *, struct Map *)); +int RIOIdentifyRta(struct rio_info *, void __user *); +int RIOKillNeighbour(struct rio_info *, void __user *); +int RIOSuspendBootRta(struct Host *, int, int); +int RIOFoadWakeup(struct rio_info *); +struct CmdBlk *RIOGetCmdBlk(void); +void RIOFreeCmdBlk(struct CmdBlk *); +int RIOQueueCmdBlk(struct Host *, unsigned int, struct CmdBlk *); +void RIOPollHostCommands(struct rio_info *, struct Host *); +int RIOWFlushMark(unsigned long, struct CmdBlk *); +int RIORFlushEnable(unsigned long, struct CmdBlk *); +int RIOUnUse(unsigned long, struct CmdBlk *); + +/* rioctrl.c */ +int riocontrol(struct rio_info *, dev_t, int, unsigned long, int); + +int RIOPreemptiveCmd(struct rio_info *, struct Port *, unsigned char); + +/* rioinit.c */ +void rioinit(struct rio_info *, struct RioHostInfo *); +void RIOInitHosts(struct rio_info *, struct RioHostInfo *); +void RIOISAinit(struct rio_info *, int); +int RIODoAT(struct rio_info *, int, int); +caddr_t RIOCheckForATCard(int); +int RIOAssignAT(struct rio_info *, int, void __iomem *, int); +int RIOBoardTest(unsigned long, void __iomem *, unsigned char, int); +void RIOAllocDataStructs(struct rio_info *); +void RIOSetupDataStructs(struct rio_info *); +int RIODefaultName(struct rio_info *, struct Host *, unsigned int); +struct rioVersion *RIOVersid(void); +void RIOHostReset(unsigned int, struct DpRam __iomem *, unsigned int); + +/* riointr.c */ +void RIOTxEnable(char *); +void RIOServiceHost(struct rio_info *, struct Host *); +int riotproc(struct rio_info *, struct ttystatics *, int, int); + +/* rioparam.c */ +int RIOParam(struct Port *, int, int, int); +int RIODelay(struct Port *PortP, int); +int RIODelay_ni(struct Port *PortP, int); +void ms_timeout(struct Port *); +int can_add_transmit(struct PKT __iomem **, struct Port *); +void add_transmit(struct Port *); +void put_free_end(struct Host *, struct PKT __iomem *); +int can_remove_receive(struct PKT __iomem **, struct Port *); +void remove_receive(struct Port *); + +/* rioroute.c */ +int RIORouteRup(struct rio_info *, unsigned int, struct Host *, struct PKT __iomem *); +void RIOFixPhbs(struct rio_info *, struct Host *, unsigned int); +unsigned int GetUnitType(unsigned int); +int RIOSetChange(struct rio_info *); +int RIOFindFreeID(struct rio_info *, struct Host *, unsigned int *, unsigned int *); + + +/* riotty.c */ + +int riotopen(struct tty_struct *tty, struct file *filp); +int riotclose(void *ptr); +int riotioctl(struct rio_info *, struct tty_struct *, int, caddr_t); +void ttyseth(struct Port *, struct ttystatics *, struct old_sgttyb *sg); + +/* riotable.c */ +int RIONewTable(struct rio_info *); +int RIOApel(struct rio_info *); +int RIODeleteRta(struct rio_info *, struct Map *); +int RIOAssignRta(struct rio_info *, struct Map *); +int RIOReMapPorts(struct rio_info *, struct Host *, struct Map *); +int RIOChangeName(struct rio_info *, struct Map *); + +#if 0 +/* riodrvr.c */ +struct rio_info *rio_install(struct RioHostInfo *); +int rio_uninstall(struct rio_info *); +int rio_open(struct rio_info *, int, struct file *); +int rio_close(struct rio_info *, struct file *); +int rio_read(struct rio_info *, struct file *, char *, int); +int rio_write(struct rio_info *, struct file *f, char *, int); +int rio_ioctl(struct rio_info *, struct file *, int, char *); +int rio_select(struct rio_info *, struct file *f, int, struct sel *); +int rio_intr(char *); +int rio_isr_thread(char *); +struct rio_info *rio_info_store(int cmd, struct rio_info *p); +#endif + +extern void rio_copy_to_card(void *from, void __iomem *to, int len); +extern int rio_minor(struct tty_struct *tty); +extern int rio_ismodem(struct tty_struct *tty); + +extern void rio_start_card_running(struct Host *HostP); + +#endif /* __func_h_def */ diff --git a/drivers/staging/generic_serial/rio/host.h b/drivers/staging/generic_serial/rio/host.h new file mode 100644 index 000000000000..78f24540c224 --- /dev/null +++ b/drivers/staging/generic_serial/rio/host.h @@ -0,0 +1,123 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : host.h +** SID : 1.2 +** Last Modified : 11/6/98 11:34:10 +** Retrieved : 11/6/98 11:34:21 +** +** ident @(#)host.h 1.2 +** +** ----------------------------------------------------------------------------- +*/ + +#ifndef __rio_host_h__ +#define __rio_host_h__ + +/* +** the host structure - one per host card in the system. +*/ + +#define MAX_EXTRA_UNITS 64 + +/* +** Host data structure. This is used for the software equiv. of +** the host. +*/ +struct Host { + struct pci_dev *pdev; + unsigned char Type; /* RIO_EISA, RIO_MCA, ... */ + unsigned char Ivec; /* POLLED or ivec number */ + unsigned char Mode; /* Control stuff */ + unsigned char Slot; /* Slot */ + void __iomem *Caddr; /* KV address of DPRAM */ + struct DpRam __iomem *CardP; /* KV address of DPRAM, with overlay */ + unsigned long PaddrP; /* Phys. address of DPRAM */ + char Name[MAX_NAME_LEN]; /* The name of the host */ + unsigned int UniqueNum; /* host unique number */ + spinlock_t HostLock; /* Lock structure for MPX */ + unsigned int WorkToBeDone; /* set to true each interrupt */ + unsigned int InIntr; /* Being serviced? */ + unsigned int IntSrvDone; /* host's interrupt has been serviced */ + void (*Copy) (void *, void __iomem *, int); /* copy func */ + struct timer_list timer; + /* + ** I M P O R T A N T ! + ** + ** The rest of this data structure is cleared to zero after + ** a RIO_HOST_FOAD command. + */ + + unsigned long Flags; /* Whats going down */ +#define RC_WAITING 0 +#define RC_STARTUP 1 +#define RC_RUNNING 2 +#define RC_STUFFED 3 +#define RC_READY 7 +#define RUN_STATE 7 +/* +** Boot mode applies to the way in which hosts in this system will +** boot RTAs +*/ +#define RC_BOOT_ALL 0x8 /* Boot all RTAs attached */ +#define RC_BOOT_OWN 0x10 /* Only boot RTAs bound to this system */ +#define RC_BOOT_NONE 0x20 /* Don't boot any RTAs (slave mode) */ + + struct Top Topology[LINKS_PER_UNIT]; /* one per link */ + struct Map Mapping[MAX_RUP]; /* Mappings for host */ + struct PHB __iomem *PhbP; /* Pointer to the PHB array */ + unsigned short __iomem *PhbNumP; /* Ptr to Number of PHB's */ + struct LPB __iomem *LinkStrP; /* Link Structure Array */ + struct RUP __iomem *RupP; /* Sixteen real rups here */ + struct PARM_MAP __iomem *ParmMapP; /* points to the parmmap */ + unsigned int ExtraUnits[MAX_EXTRA_UNITS]; /* unknown things */ + unsigned int NumExtraBooted; /* how many of the above */ + /* + ** Twenty logical rups. + ** The first sixteen are the real Rup entries (above), the last four + ** are the link RUPs. + */ + struct UnixRup UnixRups[MAX_RUP + LINKS_PER_UNIT]; + int timeout_id; /* For calling 100 ms delays */ + int timeout_sem; /* For calling 100 ms delays */ + unsigned long locks; /* long req'd for set_bit --RR */ + char ____end_marker____; +}; +#define Control CardP->DpControl +#define SetInt CardP->DpSetInt +#define ResetTpu CardP->DpResetTpu +#define ResetInt CardP->DpResetInt +#define Signature CardP->DpSignature +#define Sram1 CardP->DpSram1 +#define Sram2 CardP->DpSram2 +#define Sram3 CardP->DpSram3 +#define Scratch CardP->DpScratch +#define __ParmMapR CardP->DpParmMapR +#define SLX CardP->DpSlx +#define Revision CardP->DpRevision +#define Unique CardP->DpUnique +#define Year CardP->DpYear +#define Week CardP->DpWeek + +#define RIO_DUMBPARM 0x0860 /* what not to expect */ + +#endif diff --git a/drivers/staging/generic_serial/rio/link.h b/drivers/staging/generic_serial/rio/link.h new file mode 100644 index 000000000000..f3bf11a04d41 --- /dev/null +++ b/drivers/staging/generic_serial/rio/link.h @@ -0,0 +1,96 @@ +/**************************************************************************** + ******* ******* + ******* L I N K + ******* ******* + **************************************************************************** + + Author : Ian Nandhra / Jeremy Rolls + Date : + + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Version : 0.01 + + + Mods + ---------------------------------------------------------------------------- + Date By Description + ---------------------------------------------------------------------------- + + ***************************************************************************/ + +#ifndef _link_h +#define _link_h 1 + +/************************************************* + * Define the Link Status stuff + ************************************************/ +/* Boot request stuff */ +#define BOOT_REQUEST ((ushort) 0) /* Request for a boot */ +#define BOOT_ABORT ((ushort) 1) /* Abort a boot */ +#define BOOT_SEQUENCE ((ushort) 2) /* Packet with the number of packets + and load address */ +#define BOOT_COMPLETED ((ushort) 3) /* Boot completed */ + + +struct LPB { + u16 link_number; /* Link Number */ + u16 in_ch; /* Link In Channel */ + u16 out_ch; /* Link Out Channel */ + u8 attached_serial[4]; /* Attached serial number */ + u8 attached_host_serial[4]; + /* Serial number of Host who + booted the other end */ + u16 descheduled; /* Currently Descheduled */ + u16 state; /* Current state */ + u16 send_poll; /* Send a Poll Packet */ + u16 ltt_p; /* Process Descriptor */ + u16 lrt_p; /* Process Descriptor */ + u16 lrt_status; /* Current lrt status */ + u16 ltt_status; /* Current ltt status */ + u16 timeout; /* Timeout value */ + u16 topology; /* Topology bits */ + u16 mon_ltt; + u16 mon_lrt; + u16 WaitNoBoot; /* Secs to hold off booting */ + u16 add_packet_list; /* Add packets to here */ + u16 remove_packet_list; /* Send packets from here */ + + u16 lrt_fail_chan; /* Lrt's failure channel */ + u16 ltt_fail_chan; /* Ltt's failure channel */ + + /* RUP structure for HOST to driver communications */ + struct RUP rup; + struct RUP link_rup; /* RUP for the link (POLL, + topology etc.) */ + u16 attached_link; /* Number of attached link */ + u16 csum_errors; /* csum errors */ + u16 num_disconnects; /* number of disconnects */ + u16 num_sync_rcvd; /* # sync's received */ + u16 num_sync_rqst; /* # sync requests */ + u16 num_tx; /* Num pkts sent */ + u16 num_rx; /* Num pkts received */ + u16 module_attached; /* Module tpyes of attached */ + u16 led_timeout; /* LED timeout */ + u16 first_port; /* First port to service */ + u16 last_port; /* Last port to service */ +}; + +#endif + +/*********** end of file ***********/ diff --git a/drivers/staging/generic_serial/rio/linux_compat.h b/drivers/staging/generic_serial/rio/linux_compat.h new file mode 100644 index 000000000000..34c0d2899ef1 --- /dev/null +++ b/drivers/staging/generic_serial/rio/linux_compat.h @@ -0,0 +1,77 @@ +/* + * (C) 2000 R.E.Wolff@BitWizard.nl + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + + +#define DEBUG_ALL + +struct ttystatics { + struct termios tm; +}; + +extern int rio_debug; + +#define RIO_DEBUG_INIT 0x000001 +#define RIO_DEBUG_BOOT 0x000002 +#define RIO_DEBUG_CMD 0x000004 +#define RIO_DEBUG_CTRL 0x000008 +#define RIO_DEBUG_INTR 0x000010 +#define RIO_DEBUG_PARAM 0x000020 +#define RIO_DEBUG_ROUTE 0x000040 +#define RIO_DEBUG_TABLE 0x000080 +#define RIO_DEBUG_TTY 0x000100 +#define RIO_DEBUG_FLOW 0x000200 +#define RIO_DEBUG_MODEMSIGNALS 0x000400 +#define RIO_DEBUG_PROBE 0x000800 +#define RIO_DEBUG_CLEANUP 0x001000 +#define RIO_DEBUG_IFLOW 0x002000 +#define RIO_DEBUG_PFE 0x004000 +#define RIO_DEBUG_REC 0x008000 +#define RIO_DEBUG_SPINLOCK 0x010000 +#define RIO_DEBUG_DELAY 0x020000 +#define RIO_DEBUG_MOD_COUNT 0x040000 + + +/* Copied over from riowinif.h . This is ugly. The winif file declares +also much other stuff which is incompatible with the headers from +the older driver. The older driver includes "brates.h" which shadows +the definitions from Linux, and is incompatible... */ + +/* RxBaud and TxBaud definitions... */ +#define RIO_B0 0x00 /* RTS / DTR signals dropped */ +#define RIO_B50 0x01 /* 50 baud */ +#define RIO_B75 0x02 /* 75 baud */ +#define RIO_B110 0x03 /* 110 baud */ +#define RIO_B134 0x04 /* 134.5 baud */ +#define RIO_B150 0x05 /* 150 baud */ +#define RIO_B200 0x06 /* 200 baud */ +#define RIO_B300 0x07 /* 300 baud */ +#define RIO_B600 0x08 /* 600 baud */ +#define RIO_B1200 0x09 /* 1200 baud */ +#define RIO_B1800 0x0A /* 1800 baud */ +#define RIO_B2400 0x0B /* 2400 baud */ +#define RIO_B4800 0x0C /* 4800 baud */ +#define RIO_B9600 0x0D /* 9600 baud */ +#define RIO_B19200 0x0E /* 19200 baud */ +#define RIO_B38400 0x0F /* 38400 baud */ +#define RIO_B56000 0x10 /* 56000 baud */ +#define RIO_B57600 0x11 /* 57600 baud */ +#define RIO_B64000 0x12 /* 64000 baud */ +#define RIO_B115200 0x13 /* 115200 baud */ +#define RIO_B2000 0x14 /* 2000 baud */ diff --git a/drivers/staging/generic_serial/rio/map.h b/drivers/staging/generic_serial/rio/map.h new file mode 100644 index 000000000000..8366978578c1 --- /dev/null +++ b/drivers/staging/generic_serial/rio/map.h @@ -0,0 +1,98 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : map.h +** SID : 1.2 +** Last Modified : 11/6/98 11:34:11 +** Retrieved : 11/6/98 11:34:21 +** +** ident @(#)map.h 1.2 +** +** ----------------------------------------------------------------------------- +*/ + +#ifndef __rio_map_h__ +#define __rio_map_h__ + +/* +** mapping structure passed to and from the config.rio program to +** determine the current topology of the world +*/ + +#define MAX_MAP_ENTRY 17 +#define TOTAL_MAP_ENTRIES (MAX_MAP_ENTRY*RIO_SLOTS) +#define MAX_NAME_LEN 32 + +struct Map { + unsigned int HostUniqueNum; /* Supporting hosts unique number */ + unsigned int RtaUniqueNum; /* Unique number */ + /* + ** The next two IDs must be swapped on big-endian architectures + ** when using a v2.04 /etc/rio/config with a v3.00 driver (when + ** upgrading for example). + */ + unsigned short ID; /* ID used in the subnet */ + unsigned short ID2; /* ID of 2nd block of 8 for 16 port */ + unsigned long Flags; /* Booted, ID Given, Disconnected */ + unsigned long SysPort; /* First tty mapped to this port */ + struct Top Topology[LINKS_PER_UNIT]; /* ID connected to each link */ + char Name[MAX_NAME_LEN]; /* Cute name by which RTA is known */ +}; + +/* +** Flag values: +*/ +#define RTA_BOOTED 0x00000001 +#define RTA_NEWBOOT 0x00000010 +#define MSG_DONE 0x00000020 +#define RTA_INTERCONNECT 0x00000040 +#define RTA16_SECOND_SLOT 0x00000080 +#define BEEN_HERE 0x00000100 +#define SLOT_TENTATIVE 0x40000000 +#define SLOT_IN_USE 0x80000000 + +/* +** HostUniqueNum is the unique number from the host card that this RTA +** is to be connected to. +** RtaUniqueNum is the unique number of the RTA concerned. It will be ZERO +** if the slot in the table is unused. If it is the same as the HostUniqueNum +** then this slot represents a host card. +** Flags contains current boot/route state info +** SysPort is a value in the range 0-504, being the number of the first tty +** on this RTA. Each RTA supports 8 ports. The SysPort value must be modulo 8. +** SysPort 0-127 correspond to /dev/ttyr001 to /dev/ttyr128, with minor +** numbers 0-127. SysPort 128-255 correspond to /dev/ttyr129 to /dev/ttyr256, +** again with minor numbers 0-127, and so on for SysPorts 256-383 and 384-511 +** ID will be in the range 0-16 for a `known' RTA. ID will be 0xFFFF for an +** unused slot/unknown ID etc. +** The Topology array contains the ID of the unit connected to each of the +** four links on this unit. The entry will be 0xFFFF if NOTHING is connected +** to the link, or will be 0xFF00 if an UNKNOWN unit is connected to the link. +** The Name field is a null-terminated string, upto 31 characters, containing +** the 'cute' name that the sysadmin/users know the RTA by. It is permissible +** for this string to contain any character in the range \040 to \176 inclusive. +** In particular, ctrl sequences and DEL (0x7F, \177) are not allowed. The +** special character '%' IS allowable, and needs no special action. +** +*/ + +#endif diff --git a/drivers/staging/generic_serial/rio/param.h b/drivers/staging/generic_serial/rio/param.h new file mode 100644 index 000000000000..7e9b6283e8aa --- /dev/null +++ b/drivers/staging/generic_serial/rio/param.h @@ -0,0 +1,55 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : param.h +** SID : 1.2 +** Last Modified : 11/6/98 11:34:12 +** Retrieved : 11/6/98 11:34:21 +** +** ident @(#)param.h 1.2 +** +** ----------------------------------------------------------------------------- +*/ + +#ifndef __rio_param_h__ +#define __rio_param_h__ + +/* +** the param command block, as used in OPEN and PARAM calls. +*/ + +struct phb_param { + u8 Cmd; /* It is very important that these line up */ + u8 Cor1; /* with what is expected at the other end. */ + u8 Cor2; /* to confirm that you've got it right, */ + u8 Cor4; /* check with cirrus/cirrus.h */ + u8 Cor5; + u8 TxXon; /* Transmit X-On character */ + u8 TxXoff; /* Transmit X-Off character */ + u8 RxXon; /* Receive X-On character */ + u8 RxXoff; /* Receive X-Off character */ + u8 LNext; /* Literal-next character */ + u8 TxBaud; /* Transmit baudrate */ + u8 RxBaud; /* Receive baudrate */ +}; + +#endif diff --git a/drivers/staging/generic_serial/rio/parmmap.h b/drivers/staging/generic_serial/rio/parmmap.h new file mode 100644 index 000000000000..acc8fa439df5 --- /dev/null +++ b/drivers/staging/generic_serial/rio/parmmap.h @@ -0,0 +1,81 @@ +/**************************************************************************** + ******* ******* + ******* H O S T M E M O R Y M A P + ******* ******* + **************************************************************************** + + Author : Ian Nandhra / Jeremy Rolls + Date : + + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Version : 0.01 + + + Mods + ---------------------------------------------------------------------------- + Date By Description + ---------------------------------------------------------------------------- +6/4/1991 jonb Made changes to accommodate Mips R3230 bus + ***************************************************************************/ + +#ifndef _parmap_h +#define _parmap_h + +typedef struct PARM_MAP PARM_MAP; + +struct PARM_MAP { + u16 phb_ptr; /* Pointer to the PHB array */ + u16 phb_num_ptr; /* Ptr to Number of PHB's */ + u16 free_list; /* Free List pointer */ + u16 free_list_end; /* Free List End pointer */ + u16 q_free_list_ptr; /* Ptr to Q_BUF variable */ + u16 unit_id_ptr; /* Unit Id */ + u16 link_str_ptr; /* Link Structure Array */ + u16 bootloader_1; /* 1st Stage Boot Loader */ + u16 bootloader_2; /* 2nd Stage Boot Loader */ + u16 port_route_map_ptr; /* Port Route Map */ + u16 route_ptr; /* Unit Route Map */ + u16 map_present; /* Route Map present */ + s16 pkt_num; /* Total number of packets */ + s16 q_num; /* Total number of Q packets */ + u16 buffers_per_port; /* Number of buffers per port */ + u16 heap_size; /* Initial size of heap */ + u16 heap_left; /* Current Heap left */ + u16 error; /* Error code */ + u16 tx_max; /* Max number of tx pkts per phb */ + u16 rx_max; /* Max number of rx pkts per phb */ + u16 rx_limit; /* For high / low watermarks */ + s16 links; /* Links to use */ + s16 timer; /* Interrupts per second */ + u16 rups; /* Pointer to the RUPs */ + u16 max_phb; /* Mostly for debugging */ + u16 living; /* Just increments!! */ + u16 init_done; /* Initialisation over */ + u16 booting_link; + u16 idle_count; /* Idle time counter */ + u16 busy_count; /* Busy counter */ + u16 idle_control; /* Control Idle Process */ + u16 tx_intr; /* TX interrupt pending */ + u16 rx_intr; /* RX interrupt pending */ + u16 rup_intr; /* RUP interrupt pending */ +}; + +#endif + +/*********** end of file ***********/ diff --git a/drivers/staging/generic_serial/rio/pci.h b/drivers/staging/generic_serial/rio/pci.h new file mode 100644 index 000000000000..6032f9135956 --- /dev/null +++ b/drivers/staging/generic_serial/rio/pci.h @@ -0,0 +1,72 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : pci.h +** SID : 1.2 +** Last Modified : 11/6/98 11:34:12 +** Retrieved : 11/6/98 11:34:21 +** +** ident @(#)pci.h 1.2 +** +** ----------------------------------------------------------------------------- +*/ + +#ifndef __rio_pci_h__ +#define __rio_pci_h__ + +/* +** PCI stuff +*/ + +#define PCITpFastClock 0x80 +#define PCITpSlowClock 0x00 +#define PCITpFastLinks 0x40 +#define PCITpSlowLinks 0x00 +#define PCITpIntEnable 0x04 +#define PCITpIntDisable 0x00 +#define PCITpBusEnable 0x02 +#define PCITpBusDisable 0x00 +#define PCITpBootFromRam 0x01 +#define PCITpBootFromLink 0x00 + +#define RIO_PCI_VENDOR 0x11CB +#define RIO_PCI_DEVICE 0x8000 +#define RIO_PCI_BASE_CLASS 0x02 +#define RIO_PCI_SUB_CLASS 0x80 +#define RIO_PCI_PROG_IFACE 0x00 + +#define RIO_PCI_RID 0x0008 +#define RIO_PCI_BADR0 0x0010 +#define RIO_PCI_INTLN 0x003C +#define RIO_PCI_INTPIN 0x003D + +#define RIO_PCI_MEM_SIZE 65536 + +#define RIO_PCI_TURBO_TP 0x80 +#define RIO_PCI_FAST_LINKS 0x40 +#define RIO_PCI_INT_ENABLE 0x04 +#define RIO_PCI_TP_BUS_ENABLE 0x02 +#define RIO_PCI_BOOT_FROM_RAM 0x01 + +#define RIO_PCI_DEFAULT_MODE 0x05 + +#endif /* __rio_pci_h__ */ diff --git a/drivers/staging/generic_serial/rio/phb.h b/drivers/staging/generic_serial/rio/phb.h new file mode 100644 index 000000000000..a4c48ae4e365 --- /dev/null +++ b/drivers/staging/generic_serial/rio/phb.h @@ -0,0 +1,142 @@ +/**************************************************************************** + ******* ******* + ******* P H B H E A D E R ******* + ******* ******* + **************************************************************************** + + Author : Ian Nandhra, Jeremy Rolls + Date : + + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Version : 0.01 + + + Mods + ---------------------------------------------------------------------------- + Date By Description + ---------------------------------------------------------------------------- + + ***************************************************************************/ + +#ifndef _phb_h +#define _phb_h 1 + +/************************************************* + * Handshake asserted. Deasserted by the LTT(s) + ************************************************/ +#define PHB_HANDSHAKE_SET ((ushort) 0x001) /* Set by LRT */ + +#define PHB_HANDSHAKE_RESET ((ushort) 0x002) /* Set by ISR / driver */ + +#define PHB_HANDSHAKE_FLAGS (PHB_HANDSHAKE_RESET | PHB_HANDSHAKE_SET) + /* Reset by ltt */ + + +/************************************************* + * Maximum number of PHB's + ************************************************/ +#define MAX_PHB ((ushort) 128) /* range 0-127 */ + +/************************************************* + * Defines for the mode fields + ************************************************/ +#define TXPKT_INCOMPLETE 0x0001 /* Previous tx packet not completed */ +#define TXINTR_ENABLED 0x0002 /* Tx interrupt is enabled */ +#define TX_TAB3 0x0004 /* TAB3 mode */ +#define TX_OCRNL 0x0008 /* OCRNL mode */ +#define TX_ONLCR 0x0010 /* ONLCR mode */ +#define TX_SENDSPACES 0x0020 /* Send n spaces command needs + completing */ +#define TX_SENDNULL 0x0040 /* Escaping NULL needs completing */ +#define TX_SENDLF 0x0080 /* LF -> CR LF needs completing */ +#define TX_PARALLELBUG 0x0100 /* CD1400 LF -> CR LF bug on parallel + port */ +#define TX_HANGOVER (TX_SENDSPACES | TX_SENDLF | TX_SENDNULL) +#define TX_DTRFLOW 0x0200 /* DTR tx flow control */ +#define TX_DTRFLOWED 0x0400 /* DTR is low - don't allow more data + into the FIFO */ +#define TX_DATAINFIFO 0x0800 /* There is data in the FIFO */ +#define TX_BUSY 0x1000 /* Data in FIFO, shift or holding regs */ + +#define RX_SPARE 0x0001 /* SPARE */ +#define RXINTR_ENABLED 0x0002 /* Rx interrupt enabled */ +#define RX_ICRNL 0x0008 /* ICRNL mode */ +#define RX_INLCR 0x0010 /* INLCR mode */ +#define RX_IGNCR 0x0020 /* IGNCR mode */ +#define RX_CTSFLOW 0x0040 /* CTSFLOW enabled */ +#define RX_IXOFF 0x0080 /* IXOFF enabled */ +#define RX_CTSFLOWED 0x0100 /* CTSFLOW and CTS dropped */ +#define RX_IXOFFED 0x0200 /* IXOFF and xoff sent */ +#define RX_BUFFERED 0x0400 /* Try and pass on complete packets */ + +#define PORT_ISOPEN 0x0001 /* Port open? */ +#define PORT_HUPCL 0x0002 /* Hangup on close? */ +#define PORT_MOPENPEND 0x0004 /* Modem open pending */ +#define PORT_ISPARALLEL 0x0008 /* Parallel port */ +#define PORT_BREAK 0x0010 /* Port on break */ +#define PORT_STATUSPEND 0x0020 /* Status packet pending */ +#define PORT_BREAKPEND 0x0040 /* Break packet pending */ +#define PORT_MODEMPEND 0x0080 /* Modem status packet pending */ +#define PORT_PARALLELBUG 0x0100 /* CD1400 LF -> CR LF bug on parallel + port */ +#define PORT_FULLMODEM 0x0200 /* Full modem signals */ +#define PORT_RJ45 0x0400 /* RJ45 connector - no RI signal */ +#define PORT_RESTRICTED 0x0600 /* Restricted connector - no RI / DTR */ + +#define PORT_MODEMBITS 0x0600 /* Mask for modem fields */ + +#define PORT_WCLOSE 0x0800 /* Waiting for close */ +#define PORT_HANDSHAKEFIX 0x1000 /* Port has H/W flow control fix */ +#define PORT_WASPCLOSED 0x2000 /* Port closed with PCLOSE */ +#define DUMPMODE 0x4000 /* Dump RTA mem */ +#define READ_REG 0x8000 /* Read CD1400 register */ + + + +/************************************************************************** + * PHB Structure + * A few words. + * + * Normally Packets are added to the end of the list and removed from + * the start. The pointer tx_add points to a SPACE to put a Packet. + * The pointer tx_remove points to the next Packet to remove + *************************************************************************/ + +struct PHB { + u8 source; + u8 handshake; + u8 status; + u16 timeout; /* Maximum of 1.9 seconds */ + u8 link; /* Send down this link */ + u8 destination; + u16 tx_start; + u16 tx_end; + u16 tx_add; + u16 tx_remove; + + u16 rx_start; + u16 rx_end; + u16 rx_add; + u16 rx_remove; + +}; + +#endif + +/*********** end of file ***********/ diff --git a/drivers/staging/generic_serial/rio/pkt.h b/drivers/staging/generic_serial/rio/pkt.h new file mode 100644 index 000000000000..a9458164f02f --- /dev/null +++ b/drivers/staging/generic_serial/rio/pkt.h @@ -0,0 +1,77 @@ +/**************************************************************************** + ******* ******* + ******* P A C K E T H E A D E R F I L E + ******* ******* + **************************************************************************** + + Author : Ian Nandhra / Jeremy Rolls + Date : + + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Version : 0.01 + + + Mods + ---------------------------------------------------------------------------- + Date By Description + ---------------------------------------------------------------------------- + + ***************************************************************************/ + +#ifndef _pkt_h +#define _pkt_h 1 + +#define PKT_CMD_BIT ((ushort) 0x080) +#define PKT_CMD_DATA ((ushort) 0x080) + +#define PKT_ACK ((ushort) 0x040) + +#define PKT_TGL ((ushort) 0x020) + +#define PKT_LEN_MASK ((ushort) 0x07f) + +#define DATA_WNDW ((ushort) 0x10) +#define PKT_TTL_MASK ((ushort) 0x0f) + +#define PKT_MAX_DATA_LEN 72 + +#define PKT_LENGTH sizeof(struct PKT) +#define SYNC_PKT_LENGTH (PKT_LENGTH + 4) + +#define CONTROL_PKT_LEN_MASK PKT_LEN_MASK +#define CONTROL_PKT_CMD_BIT PKT_CMD_BIT +#define CONTROL_PKT_ACK (PKT_ACK << 8) +#define CONTROL_PKT_TGL (PKT_TGL << 8) +#define CONTROL_PKT_TTL_MASK (PKT_TTL_MASK << 8) +#define CONTROL_DATA_WNDW (DATA_WNDW << 8) + +struct PKT { + u8 dest_unit; /* Destination Unit Id */ + u8 dest_port; /* Destination POrt */ + u8 src_unit; /* Source Unit Id */ + u8 src_port; /* Source POrt */ + u8 len; + u8 control; + u8 data[PKT_MAX_DATA_LEN]; + /* Actual data :-) */ + u16 csum; /* C-SUM */ +}; +#endif + +/*********** end of file ***********/ diff --git a/drivers/staging/generic_serial/rio/port.h b/drivers/staging/generic_serial/rio/port.h new file mode 100644 index 000000000000..49cf6d15ee54 --- /dev/null +++ b/drivers/staging/generic_serial/rio/port.h @@ -0,0 +1,179 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : port.h +** SID : 1.3 +** Last Modified : 11/6/98 11:34:12 +** Retrieved : 11/6/98 11:34:21 +** +** ident @(#)port.h 1.3 +** +** ----------------------------------------------------------------------------- +*/ + +#ifndef __rio_port_h__ +#define __rio_port_h__ + +/* +** Port data structure +*/ +struct Port { + struct gs_port gs; + int PortNum; /* RIO port no., 0-511 */ + struct Host *HostP; + void __iomem *Caddr; + unsigned short HostPort; /* Port number on host card */ + unsigned char RupNum; /* Number of RUP for port */ + unsigned char ID2; /* Second ID of RTA for port */ + unsigned long State; /* FLAGS for open & xopen */ +#define RIO_LOPEN 0x00001 /* Local open */ +#define RIO_MOPEN 0x00002 /* Modem open */ +#define RIO_WOPEN 0x00004 /* Waiting for open */ +#define RIO_CLOSING 0x00008 /* The port is being close */ +#define RIO_XPBUSY 0x00010 /* Transparent printer busy */ +#define RIO_BREAKING 0x00020 /* Break in progress */ +#define RIO_DIRECT 0x00040 /* Doing Direct output */ +#define RIO_EXCLUSIVE 0x00080 /* Stream open for exclusive use */ +#define RIO_NDELAY 0x00100 /* Stream is open FNDELAY */ +#define RIO_CARR_ON 0x00200 /* Stream has carrier present */ +#define RIO_XPWANTR 0x00400 /* Stream wanted by Xprint */ +#define RIO_RBLK 0x00800 /* Stream is read-blocked */ +#define RIO_BUSY 0x01000 /* Stream is BUSY for write */ +#define RIO_TIMEOUT 0x02000 /* Stream timeout in progress */ +#define RIO_TXSTOP 0x04000 /* Stream output is stopped */ +#define RIO_WAITFLUSH 0x08000 /* Stream waiting for flush */ +#define RIO_DYNOROD 0x10000 /* Drain failed */ +#define RIO_DELETED 0x20000 /* RTA has been deleted */ +#define RIO_ISSCANCODE 0x40000 /* This line is in scancode mode */ +#define RIO_USING_EUC 0x100000 /* Using extended Unix chars */ +#define RIO_CAN_COOK 0x200000 /* This line can do cooking */ +#define RIO_TRIAD_MODE 0x400000 /* Enable TRIAD special ops. */ +#define RIO_TRIAD_BLOCK 0x800000 /* Next read will block */ +#define RIO_TRIAD_FUNC 0x1000000 /* Seen a function key coming in */ +#define RIO_THROTTLE_RX 0x2000000 /* RX needs to be throttled. */ + + unsigned long Config; /* FLAGS for NOREAD.... */ +#define RIO_NOREAD 0x0001 /* Are not allowed to read port */ +#define RIO_NOWRITE 0x0002 /* Are not allowed to write port */ +#define RIO_NOXPRINT 0x0004 /* Are not allowed to xprint port */ +#define RIO_NOMASK 0x0007 /* All not allowed things */ +#define RIO_IXANY 0x0008 /* Port is allowed ixany */ +#define RIO_MODEM 0x0010 /* Stream is a modem device */ +#define RIO_IXON 0x0020 /* Port is allowed ixon */ +#define RIO_WAITDRAIN 0x0040 /* Wait for port to completely drain */ +#define RIO_MAP_50_TO_50 0x0080 /* Map 50 baud to 50 baud */ +#define RIO_MAP_110_TO_110 0x0100 /* Map 110 baud to 110 baud */ + +/* +** 15.10.1998 ARG - ESIL 0761 prt fix +** As LynxOS does not appear to support Hardware Flow Control ..... +** Define our own flow control flags in 'Config'. +*/ +#define RIO_CTSFLOW 0x0200 /* RIO's own CTSFLOW flag */ +#define RIO_RTSFLOW 0x0400 /* RIO's own RTSFLOW flag */ + + + struct PHB __iomem *PhbP; /* pointer to PHB for port */ + u16 __iomem *TxAdd; /* Add packets here */ + u16 __iomem *TxStart; /* Start of add array */ + u16 __iomem *TxEnd; /* End of add array */ + u16 __iomem *RxRemove; /* Remove packets here */ + u16 __iomem *RxStart; /* Start of remove array */ + u16 __iomem *RxEnd; /* End of remove array */ + unsigned int RtaUniqueNum; /* Unique number of RTA */ + unsigned short PortState; /* status of port */ + unsigned short ModemState; /* status of modem lines */ + unsigned long ModemLines; /* Modem bits sent to RTA */ + unsigned char CookMode; /* who expands CR/LF? */ + unsigned char ParamSem; /* Prevent write during param */ + unsigned char Mapped; /* if port mapped onto host */ + unsigned char SecondBlock; /* if port belongs to 2nd block + of 16 port RTA */ + unsigned char InUse; /* how many pre-emptive cmds */ + unsigned char Lock; /* if params locked */ + unsigned char Store; /* if params stored across closes */ + unsigned char FirstOpen; /* TRUE if first time port opened */ + unsigned char FlushCmdBodge; /* if doing a (non)flush */ + unsigned char MagicFlags; /* require intr processing */ +#define MAGIC_FLUSH 0x01 /* mirror of WflushFlag */ +#define MAGIC_REBOOT 0x02 /* RTA re-booted, re-open ports */ +#define MORE_OUTPUT_EYGOR 0x04 /* riotproc failed to empty clists */ + unsigned char WflushFlag; /* 1 How many WFLUSHs active */ +/* +** Transparent print stuff +*/ + struct Xprint { +#ifndef MAX_XP_CTRL_LEN +#define MAX_XP_CTRL_LEN 16 /* ALSO IN DAEMON.H */ +#endif + unsigned int XpCps; + char XpOn[MAX_XP_CTRL_LEN]; + char XpOff[MAX_XP_CTRL_LEN]; + unsigned short XpLen; /* strlen(XpOn)+strlen(XpOff) */ + unsigned char XpActive; + unsigned char XpLastTickOk; /* TRUE if we can process */ +#define XP_OPEN 00001 +#define XP_RUNABLE 00002 + struct ttystatics *XttyP; + } Xprint; + unsigned char RxDataStart; + unsigned char Cor2Copy; /* copy of COR2 */ + char *Name; /* points to the Rta's name */ + char *TxRingBuffer; + unsigned short TxBufferIn; /* New data arrives here */ + unsigned short TxBufferOut; /* Intr removes data here */ + unsigned short OldTxBufferOut; /* Indicates if draining */ + int TimeoutId; /* Timeout ID */ + unsigned int Debug; + unsigned char WaitUntilBooted; /* True if open should block */ + unsigned int statsGather; /* True if gathering stats */ + unsigned long txchars; /* Chars transmitted */ + unsigned long rxchars; /* Chars received */ + unsigned long opens; /* port open count */ + unsigned long closes; /* port close count */ + unsigned long ioctls; /* ioctl count */ + unsigned char LastRxTgl; /* Last state of rx toggle bit */ + spinlock_t portSem; /* Lock using this sem */ + int MonitorTstate; /* Monitoring ? */ + int timeout_id; /* For calling 100 ms delays */ + int timeout_sem; /* For calling 100 ms delays */ + int firstOpen; /* First time open ? */ + char *p; /* save the global struc here .. */ +}; + +struct ModuleInfo { + char *Name; + unsigned int Flags[4]; /* one per port on a module */ +}; + +/* +** This struct is required because trying to grab an entire Port structure +** runs into problems with differing struct sizes between driver and config. +*/ +struct PortParams { + unsigned int Port; + unsigned long Config; + unsigned long State; + struct ttystatics *TtyP; +}; + +#endif diff --git a/drivers/staging/generic_serial/rio/protsts.h b/drivers/staging/generic_serial/rio/protsts.h new file mode 100644 index 000000000000..8ab79401d3ee --- /dev/null +++ b/drivers/staging/generic_serial/rio/protsts.h @@ -0,0 +1,110 @@ +/**************************************************************************** + ******* ******* + ******* P R O T O C O L S T A T U S S T R U C T U R E ******* + ******* ******* + **************************************************************************** + + Author : Ian Nandhra / Jeremy Rolls + Date : + + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Version : 0.01 + + + Mods + ---------------------------------------------------------------------------- + Date By Description + ---------------------------------------------------------------------------- + + ***************************************************************************/ + +#ifndef _protsts_h +#define _protsts_h 1 + +/************************************************* + * ACK bit. Last Packet received OK. Set by + * rxpkt to indicate that the Packet has been + * received OK and that the LTT must set the ACK + * bit in the next outward bound Packet + * and re-set by LTT's after xmit. + * + * Gets shoved into rx_status + ************************************************/ +#define PHB_RX_LAST_PKT_ACKED ((ushort) 0x080) + +/******************************************************* + * The Rx TOGGLE bit. + * Stuffed into rx_status by RXPKT + ******************************************************/ +#define PHB_RX_DATA_WNDW ((ushort) 0x040) + +/******************************************************* + * The Rx TOGGLE bit. Matches the setting in PKT.H + * Stuffed into rx_status + ******************************************************/ +#define PHB_RX_TGL ((ushort) 0x2000) + + +/************************************************* + * This bit is set by the LRT to indicate that + * an ACK (packet) must be returned. + * + * Gets shoved into tx_status + ************************************************/ +#define PHB_TX_SEND_PKT_ACK ((ushort) 0x08) + +/************************************************* + * Set by LTT to indicate that an ACK is required + *************************************************/ +#define PHB_TX_ACK_RQRD ((ushort) 0x01) + + +/******************************************************* + * The Tx TOGGLE bit. + * Stuffed into tx_status by RXPKT from the PKT WndW + * field. Looked by the LTT when the NEXT Packet + * is going to be sent. + ******************************************************/ +#define PHB_TX_DATA_WNDW ((ushort) 0x04) + + +/******************************************************* + * The Tx TOGGLE bit. Matches the setting in PKT.H + * Stuffed into tx_status + ******************************************************/ +#define PHB_TX_TGL ((ushort) 0x02) + +/******************************************************* + * Request intr bit. Set when the queue has gone quiet + * and the PHB has requested an interrupt. + ******************************************************/ +#define PHB_TX_INTR ((ushort) 0x100) + +/******************************************************* + * SET if the PHB cannot send any more data down the + * Link + ******************************************************/ +#define PHB_TX_HANDSHAKE ((ushort) 0x010) + + +#define RUP_SEND_WNDW ((ushort) 0x08) ; + +#endif + +/*********** end of file ***********/ diff --git a/drivers/staging/generic_serial/rio/rio.h b/drivers/staging/generic_serial/rio/rio.h new file mode 100644 index 000000000000..1bf36223a4e8 --- /dev/null +++ b/drivers/staging/generic_serial/rio/rio.h @@ -0,0 +1,208 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 1998 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : rio.h +** SID : 1.3 +** Last Modified : 11/6/98 11:34:13 +** Retrieved : 11/6/98 11:34:22 +** +** ident @(#)rio.h 1.3 +** +** ----------------------------------------------------------------------------- +*/ + +#ifndef __rio_rio_h__ +#define __rio_rio_h__ + +/* +** Maximum numbers of things +*/ +#define RIO_SLOTS 4 /* number of configuration slots */ +#define RIO_HOSTS 4 /* number of hosts that can be found */ +#define PORTS_PER_HOST 128 /* number of ports per host */ +#define LINKS_PER_UNIT 4 /* number of links from a host */ +#define RIO_PORTS (PORTS_PER_HOST * RIO_HOSTS) /* max. no. of ports */ +#define RTAS_PER_HOST (MAX_RUP) /* number of RTAs per host */ +#define PORTS_PER_RTA (PORTS_PER_HOST/RTAS_PER_HOST) /* ports on a rta */ +#define PORTS_PER_MODULE 4 /* number of ports on a plug-in module */ + /* number of modules on an RTA */ +#define MODULES_PER_RTA (PORTS_PER_RTA/PORTS_PER_MODULE) +#define MAX_PRODUCT 16 /* numbr of different product codes */ +#define MAX_MODULE_TYPES 16 /* number of different types of module */ + +#define RIO_CONTROL_DEV 128 /* minor number of host/control device */ +#define RIO_INVALID_MAJOR 0 /* test first host card's major no for validity */ + +/* +** number of RTAs that can be bound to a master +*/ +#define MAX_RTA_BINDINGS (MAX_RUP * RIO_HOSTS) + +/* +** Unit types +*/ +#define PC_RTA16 0x90000000 +#define PC_RTA8 0xe0000000 +#define TYPE_HOST 0 +#define TYPE_RTA8 1 +#define TYPE_RTA16 2 + +/* +** Flag values returned by functions +*/ + +#define RIO_FAIL -1 + +/* +** SysPort value for something that hasn't any ports +*/ +#define NO_PORT 0xFFFFFFFF + +/* +** Unit ID Of all hosts +*/ +#define HOST_ID 0 + +/* +** Break bytes into nybles +*/ +#define LONYBLE(X) ((X) & 0xF) +#define HINYBLE(X) (((X)>>4) & 0xF) + +/* +** Flag values passed into some functions +*/ +#define DONT_SLEEP 0 +#define OK_TO_SLEEP 1 + +#define DONT_PRINT 1 +#define DO_PRINT 0 + +#define PRINT_TO_LOG_CONS 0 +#define PRINT_TO_CONS 1 +#define PRINT_TO_LOG 2 + +/* +** Timeout has trouble with times of less than 3 ticks... +*/ +#define MIN_TIMEOUT 3 + +/* +** Generally useful constants +*/ + +#define HUNDRED_MS ((HZ/10)?(HZ/10):1) +#define ONE_MEG 0x100000 +#define SIXTY_FOUR_K 0x10000 + +#define RIO_AT_MEM_SIZE SIXTY_FOUR_K +#define RIO_EISA_MEM_SIZE SIXTY_FOUR_K +#define RIO_MCA_MEM_SIZE SIXTY_FOUR_K + +#define COOK_WELL 0 +#define COOK_MEDIUM 1 +#define COOK_RAW 2 + +/* +** Pointer manipulation stuff +** RIO_PTR takes hostp->Caddr and the offset into the DP RAM area +** and produces a UNIX caddr_t (pointer) to the object +** RIO_OBJ takes hostp->Caddr and a UNIX pointer to an object and +** returns the offset into the DP RAM area. +*/ +#define RIO_PTR(C,O) (((unsigned char __iomem *)(C))+(0xFFFF&(O))) +#define RIO_OFF(C,O) ((unsigned char __iomem *)(O)-(unsigned char __iomem *)(C)) + +/* +** How to convert from various different device number formats: +** DEV is a dev number, as passed to open, close etc - NOT a minor +** number! +**/ + +#define RIO_MODEM_MASK 0x1FF +#define RIO_MODEM_BIT 0x200 +#define RIO_UNMODEM(DEV) (MINOR(DEV) & RIO_MODEM_MASK) +#define RIO_ISMODEM(DEV) (MINOR(DEV) & RIO_MODEM_BIT) +#define RIO_PORT(DEV,FIRST_MAJ) ( (MAJOR(DEV) - FIRST_MAJ) * PORTS_PER_HOST) \ + + MINOR(DEV) +#define CSUM(pkt_ptr) (((u16 *)(pkt_ptr))[0] + ((u16 *)(pkt_ptr))[1] + \ + ((u16 *)(pkt_ptr))[2] + ((u16 *)(pkt_ptr))[3] + \ + ((u16 *)(pkt_ptr))[4] + ((u16 *)(pkt_ptr))[5] + \ + ((u16 *)(pkt_ptr))[6] + ((u16 *)(pkt_ptr))[7] + \ + ((u16 *)(pkt_ptr))[8] + ((u16 *)(pkt_ptr))[9] ) + +#define RIO_LINK_ENABLE 0x80FF /* FF is a hack, mainly for Mips, to */ + /* prevent a really stupid race condition. */ + +#define NOT_INITIALISED 0 +#define INITIALISED 1 + +#define NOT_POLLING 0 +#define POLLING 1 + +#define NOT_CHANGED 0 +#define CHANGED 1 + +#define NOT_INUSE 0 + +#define DISCONNECT 0 +#define CONNECT 1 + +/* ------ Control Codes ------ */ + +#define CONTROL '^' +#define IFOAD ( CONTROL + 1 ) +#define IDENTIFY ( CONTROL + 2 ) +#define ZOMBIE ( CONTROL + 3 ) +#define UFOAD ( CONTROL + 4 ) +#define IWAIT ( CONTROL + 5 ) + +#define IFOAD_MAGIC 0xF0AD /* of course */ +#define ZOMBIE_MAGIC (~0xDEAD) /* not dead -> zombie */ +#define UFOAD_MAGIC 0xD1E /* kill-your-neighbour */ +#define IWAIT_MAGIC 0xB1DE /* Bide your time */ + +/* ------ Error Codes ------ */ + +#define E_NO_ERROR ((ushort) 0) + +/* ------ Free Lists ------ */ + +struct rio_free_list { + u16 next; + u16 prev; +}; + +/* NULL for card side linked lists */ +#define TPNULL ((ushort)(0x8000)) +/* We can add another packet to a transmit queue if the packet pointer pointed + * to by the TxAdd pointer has PKT_IN_USE clear in its address. */ +#define PKT_IN_USE 0x1 + +/* ------ Topology ------ */ + +struct Top { + u8 Unit; + u8 Link; +}; + +#endif /* __rio_h__ */ diff --git a/drivers/staging/generic_serial/rio/rio_linux.c b/drivers/staging/generic_serial/rio/rio_linux.c new file mode 100644 index 000000000000..5e33293d24e3 --- /dev/null +++ b/drivers/staging/generic_serial/rio/rio_linux.c @@ -0,0 +1,1204 @@ + +/* rio_linux.c -- Linux driver for the Specialix RIO series cards. + * + * + * (C) 1999 R.E.Wolff@BitWizard.nl + * + * Specialix pays for the development and support of this driver. + * Please DO contact support@specialix.co.uk if you require + * support. But please read the documentation (rio.txt) first. + * + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, + * USA. + * + * */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "linux_compat.h" +#include "pkt.h" +#include "daemon.h" +#include "rio.h" +#include "riospace.h" +#include "cmdpkt.h" +#include "map.h" +#include "rup.h" +#include "port.h" +#include "riodrvr.h" +#include "rioinfo.h" +#include "func.h" +#include "errors.h" +#include "pci.h" + +#include "parmmap.h" +#include "unixrup.h" +#include "board.h" +#include "host.h" +#include "phb.h" +#include "link.h" +#include "cmdblk.h" +#include "route.h" +#include "cirrus.h" +#include "rioioctl.h" +#include "param.h" +#include "protsts.h" +#include "rioboard.h" + + +#include "rio_linux.h" + +/* I don't think that this driver can handle more than 512 ports on +one machine. Specialix specifies max 4 boards in one machine. I don't +know why. If you want to try anyway you'll have to increase the number +of boards in rio.h. You'll have to allocate more majors if you need +more than 512 ports.... */ + +#ifndef RIO_NORMAL_MAJOR0 +/* This allows overriding on the compiler commandline, or in a "major.h" + include or something like that */ +#define RIO_NORMAL_MAJOR0 154 +#define RIO_NORMAL_MAJOR1 156 +#endif + +#ifndef PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 +#define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000 +#endif + +#ifndef RIO_WINDOW_LEN +#define RIO_WINDOW_LEN 0x10000 +#endif + + +/* Configurable options: + (Don't be too sure that it'll work if you toggle them) */ + +/* Am I paranoid or not ? ;-) */ +#undef RIO_PARANOIA_CHECK + + +/* 20 -> 2000 per second. The card should rate-limit interrupts at 1000 + Hz, but it is user configurable. I don't recommend going above 1000 + Hz. The interrupt ratelimit might trigger if the interrupt is + shared with a very active other device. + undef this if you want to disable the check.... +*/ +#define IRQ_RATE_LIMIT 200 + + +/* These constants are derived from SCO Source */ +static DEFINE_MUTEX(rio_fw_mutex); +static struct Conf + RIOConf = { + /* locator */ "RIO Config here", + /* startuptime */ HZ * 2, + /* how long to wait for card to run */ + /* slowcook */ 0, + /* TRUE -> always use line disc. */ + /* intrpolltime */ 1, + /* The frequency of OUR polls */ + /* breakinterval */ 25, + /* x10 mS XXX: units seem to be 1ms not 10! -- REW */ + /* timer */ 10, + /* mS */ + /* RtaLoadBase */ 0x7000, + /* HostLoadBase */ 0x7C00, + /* XpHz */ 5, + /* number of Xprint hits per second */ + /* XpCps */ 120, + /* Xprint characters per second */ + /* XpOn */ "\033d#", + /* start Xprint for a wyse 60 */ + /* XpOff */ "\024", + /* end Xprint for a wyse 60 */ + /* MaxXpCps */ 2000, + /* highest Xprint speed */ + /* MinXpCps */ 10, + /* slowest Xprint speed */ + /* SpinCmds */ 1, + /* non-zero for mega fast boots */ + /* First Addr */ 0x0A0000, + /* First address to look at */ + /* Last Addr */ 0xFF0000, + /* Last address looked at */ + /* BufferSize */ 1024, + /* Bytes per port of buffering */ + /* LowWater */ 256, + /* how much data left before wakeup */ + /* LineLength */ 80, + /* how wide is the console? */ + /* CmdTimeout */ HZ, + /* how long a close command may take */ +}; + + + + +/* Function prototypes */ + +static void rio_disable_tx_interrupts(void *ptr); +static void rio_enable_tx_interrupts(void *ptr); +static void rio_disable_rx_interrupts(void *ptr); +static void rio_enable_rx_interrupts(void *ptr); +static int rio_carrier_raised(struct tty_port *port); +static void rio_shutdown_port(void *ptr); +static int rio_set_real_termios(void *ptr); +static void rio_hungup(void *ptr); +static void rio_close(void *ptr); +static int rio_chars_in_buffer(void *ptr); +static long rio_fw_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +static int rio_init_drivers(void); + +static void my_hd(void *addr, int len); + +static struct tty_driver *rio_driver, *rio_driver2; + +/* The name "p" is a bit non-descript. But that's what the rio-lynxos +sources use all over the place. */ +struct rio_info *p; + +int rio_debug; + + +/* You can have the driver poll your card. + - Set rio_poll to 1 to poll every timer tick (10ms on Intel). + This is used when the card cannot use an interrupt for some reason. +*/ +static int rio_poll = 1; + + +/* These are the only open spaces in my computer. Yours may have more + or less.... */ +static int rio_probe_addrs[] = { 0xc0000, 0xd0000, 0xe0000 }; + +#define NR_RIO_ADDRS ARRAY_SIZE(rio_probe_addrs) + + +/* Set the mask to all-ones. This alas, only supports 32 interrupts. + Some architectures may need more. -- Changed to LONG to + support up to 64 bits on 64bit architectures. -- REW 20/06/99 */ +static long rio_irqmask = -1; + +MODULE_AUTHOR("Rogier Wolff , Patrick van de Lageweg "); +MODULE_DESCRIPTION("RIO driver"); +MODULE_LICENSE("GPL"); +module_param(rio_poll, int, 0); +module_param(rio_debug, int, 0644); +module_param(rio_irqmask, long, 0); + +static struct real_driver rio_real_driver = { + rio_disable_tx_interrupts, + rio_enable_tx_interrupts, + rio_disable_rx_interrupts, + rio_enable_rx_interrupts, + rio_shutdown_port, + rio_set_real_termios, + rio_chars_in_buffer, + rio_close, + rio_hungup, + NULL +}; + +/* + * Firmware loader driver specific routines + * + */ + +static const struct file_operations rio_fw_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = rio_fw_ioctl, + .llseek = noop_llseek, +}; + +static struct miscdevice rio_fw_device = { + RIOCTL_MISC_MINOR, "rioctl", &rio_fw_fops +}; + + + + + +#ifdef RIO_PARANOIA_CHECK + +/* This doesn't work. Who's paranoid around here? Not me! */ + +static inline int rio_paranoia_check(struct rio_port const *port, char *name, const char *routine) +{ + + static const char *badmagic = KERN_ERR "rio: Warning: bad rio port magic number for device %s in %s\n"; + static const char *badinfo = KERN_ERR "rio: Warning: null rio port for device %s in %s\n"; + + if (!port) { + printk(badinfo, name, routine); + return 1; + } + if (port->magic != RIO_MAGIC) { + printk(badmagic, name, routine); + return 1; + } + + return 0; +} +#else +#define rio_paranoia_check(a,b,c) 0 +#endif + + +#ifdef DEBUG +static void my_hd(void *ad, int len) +{ + int i, j, ch; + unsigned char *addr = ad; + + for (i = 0; i < len; i += 16) { + rio_dprintk(RIO_DEBUG_PARAM, "%08lx ", (unsigned long) addr + i); + for (j = 0; j < 16; j++) { + rio_dprintk(RIO_DEBUG_PARAM, "%02x %s", addr[j + i], (j == 7) ? " " : ""); + } + for (j = 0; j < 16; j++) { + ch = addr[j + i]; + rio_dprintk(RIO_DEBUG_PARAM, "%c", (ch < 0x20) ? '.' : ((ch > 0x7f) ? '.' : ch)); + } + rio_dprintk(RIO_DEBUG_PARAM, "\n"); + } +} +#else +#define my_hd(ad,len) do{/* nothing*/ } while (0) +#endif + + +/* Delay a number of jiffies, allowing a signal to interrupt */ +int RIODelay(struct Port *PortP, int njiffies) +{ + func_enter(); + + rio_dprintk(RIO_DEBUG_DELAY, "delaying %d jiffies\n", njiffies); + msleep_interruptible(jiffies_to_msecs(njiffies)); + func_exit(); + + if (signal_pending(current)) + return RIO_FAIL; + else + return !RIO_FAIL; +} + + +/* Delay a number of jiffies, disallowing a signal to interrupt */ +int RIODelay_ni(struct Port *PortP, int njiffies) +{ + func_enter(); + + rio_dprintk(RIO_DEBUG_DELAY, "delaying %d jiffies (ni)\n", njiffies); + msleep(jiffies_to_msecs(njiffies)); + func_exit(); + return !RIO_FAIL; +} + +void rio_copy_to_card(void *from, void __iomem *to, int len) +{ + rio_copy_toio(to, from, len); +} + +int rio_minor(struct tty_struct *tty) +{ + return tty->index + ((tty->driver == rio_driver) ? 0 : 256); +} + +static int rio_set_real_termios(void *ptr) +{ + return RIOParam((struct Port *) ptr, RIOC_CONFIG, 1, 1); +} + + +static void rio_reset_interrupt(struct Host *HostP) +{ + func_enter(); + + switch (HostP->Type) { + case RIO_AT: + case RIO_MCA: + case RIO_PCI: + writeb(0xFF, &HostP->ResetInt); + } + + func_exit(); +} + + +static irqreturn_t rio_interrupt(int irq, void *ptr) +{ + struct Host *HostP; + func_enter(); + + HostP = ptr; /* &p->RIOHosts[(long)ptr]; */ + rio_dprintk(RIO_DEBUG_IFLOW, "rio: enter rio_interrupt (%d/%d)\n", irq, HostP->Ivec); + + /* AAargh! The order in which to do these things is essential and + not trivial. + + - hardware twiddling goes before "recursive". Otherwise when we + poll the card, and a recursive interrupt happens, we won't + ack the card, so it might keep on interrupting us. (especially + level sensitive interrupt systems like PCI). + + - Rate limit goes before hardware twiddling. Otherwise we won't + catch a card that has gone bonkers. + + - The "initialized" test goes after the hardware twiddling. Otherwise + the card will stick us in the interrupt routine again. + + - The initialized test goes before recursive. + */ + + rio_dprintk(RIO_DEBUG_IFLOW, "rio: We've have noticed the interrupt\n"); + if (HostP->Ivec == irq) { + /* Tell the card we've noticed the interrupt. */ + rio_reset_interrupt(HostP); + } + + if ((HostP->Flags & RUN_STATE) != RC_RUNNING) + return IRQ_HANDLED; + + if (test_and_set_bit(RIO_BOARD_INTR_LOCK, &HostP->locks)) { + printk(KERN_ERR "Recursive interrupt! (host %p/irq%d)\n", ptr, HostP->Ivec); + return IRQ_HANDLED; + } + + RIOServiceHost(p, HostP); + + rio_dprintk(RIO_DEBUG_IFLOW, "riointr() doing host %p type %d\n", ptr, HostP->Type); + + clear_bit(RIO_BOARD_INTR_LOCK, &HostP->locks); + rio_dprintk(RIO_DEBUG_IFLOW, "rio: exit rio_interrupt (%d/%d)\n", irq, HostP->Ivec); + func_exit(); + return IRQ_HANDLED; +} + + +static void rio_pollfunc(unsigned long data) +{ + func_enter(); + + rio_interrupt(0, &p->RIOHosts[data]); + mod_timer(&p->RIOHosts[data].timer, jiffies + rio_poll); + + func_exit(); +} + + +/* ********************************************************************** * + * Here are the routines that actually * + * interface with the generic_serial driver * + * ********************************************************************** */ + +/* Ehhm. I don't know how to fiddle with interrupts on the Specialix + cards. .... Hmm. Ok I figured it out. You don't. -- REW */ + +static void rio_disable_tx_interrupts(void *ptr) +{ + func_enter(); + + /* port->gs.port.flags &= ~GS_TX_INTEN; */ + + func_exit(); +} + + +static void rio_enable_tx_interrupts(void *ptr) +{ + struct Port *PortP = ptr; + /* int hn; */ + + func_enter(); + + /* hn = PortP->HostP - p->RIOHosts; + + rio_dprintk (RIO_DEBUG_TTY, "Pushing host %d\n", hn); + rio_interrupt (-1,(void *) hn, NULL); */ + + RIOTxEnable((char *) PortP); + + /* + * In general we cannot count on "tx empty" interrupts, although + * the interrupt routine seems to be able to tell the difference. + */ + PortP->gs.port.flags &= ~GS_TX_INTEN; + + func_exit(); +} + + +static void rio_disable_rx_interrupts(void *ptr) +{ + func_enter(); + func_exit(); +} + +static void rio_enable_rx_interrupts(void *ptr) +{ + /* struct rio_port *port = ptr; */ + func_enter(); + func_exit(); +} + + +/* Jeez. Isn't this simple? */ +static int rio_carrier_raised(struct tty_port *port) +{ + struct Port *PortP = container_of(port, struct Port, gs.port); + int rv; + + func_enter(); + rv = (PortP->ModemState & RIOC_MSVR1_CD) != 0; + + rio_dprintk(RIO_DEBUG_INIT, "Getting CD status: %d\n", rv); + + func_exit(); + return rv; +} + + +/* Jeez. Isn't this simple? Actually, we can sync with the actual port + by just pushing stuff into the queue going to the port... */ +static int rio_chars_in_buffer(void *ptr) +{ + func_enter(); + + func_exit(); + return 0; +} + + +/* Nothing special here... */ +static void rio_shutdown_port(void *ptr) +{ + struct Port *PortP; + + func_enter(); + + PortP = (struct Port *) ptr; + PortP->gs.port.tty = NULL; + func_exit(); +} + + +/* I haven't the foggiest why the decrement use count has to happen + here. The whole linux serial drivers stuff needs to be redesigned. + My guess is that this is a hack to minimize the impact of a bug + elsewhere. Thinking about it some more. (try it sometime) Try + running minicom on a serial port that is driven by a modularized + driver. Have the modem hangup. Then remove the driver module. Then + exit minicom. I expect an "oops". -- REW */ +static void rio_hungup(void *ptr) +{ + struct Port *PortP; + + func_enter(); + + PortP = (struct Port *) ptr; + PortP->gs.port.tty = NULL; + + func_exit(); +} + + +/* The standard serial_close would become shorter if you'd wrap it like + this. + rs_close (...){save_flags;cli;real_close();dec_use_count;restore_flags;} + */ +static void rio_close(void *ptr) +{ + struct Port *PortP; + + func_enter(); + + PortP = (struct Port *) ptr; + + riotclose(ptr); + + if (PortP->gs.port.count) { + printk(KERN_ERR "WARNING port count:%d\n", PortP->gs.port.count); + PortP->gs.port.count = 0; + } + + PortP->gs.port.tty = NULL; + func_exit(); +} + + + +static long rio_fw_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int rc = 0; + func_enter(); + + /* The "dev" argument isn't used. */ + mutex_lock(&rio_fw_mutex); + rc = riocontrol(p, 0, cmd, arg, capable(CAP_SYS_ADMIN)); + mutex_unlock(&rio_fw_mutex); + + func_exit(); + return rc; +} + +extern int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg); + +static int rio_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg) +{ + void __user *argp = (void __user *)arg; + int rc; + struct Port *PortP; + int ival; + + func_enter(); + + PortP = (struct Port *) tty->driver_data; + + rc = 0; + switch (cmd) { + case TIOCSSOFTCAR: + if ((rc = get_user(ival, (unsigned __user *) argp)) == 0) { + tty->termios->c_cflag = (tty->termios->c_cflag & ~CLOCAL) | (ival ? CLOCAL : 0); + } + break; + case TIOCGSERIAL: + rc = -EFAULT; + if (access_ok(VERIFY_WRITE, argp, sizeof(struct serial_struct))) + rc = gs_getserial(&PortP->gs, argp); + break; + case TCSBRK: + if (PortP->State & RIO_DELETED) { + rio_dprintk(RIO_DEBUG_TTY, "BREAK on deleted RTA\n"); + rc = -EIO; + } else { + if (RIOShortCommand(p, PortP, RIOC_SBREAK, 2, 250) == + RIO_FAIL) { + rio_dprintk(RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n"); + rc = -EIO; + } + } + break; + case TCSBRKP: + if (PortP->State & RIO_DELETED) { + rio_dprintk(RIO_DEBUG_TTY, "BREAK on deleted RTA\n"); + rc = -EIO; + } else { + int l; + l = arg ? arg * 100 : 250; + if (l > 255) + l = 255; + if (RIOShortCommand(p, PortP, RIOC_SBREAK, 2, + arg ? arg * 100 : 250) == RIO_FAIL) { + rio_dprintk(RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n"); + rc = -EIO; + } + } + break; + case TIOCSSERIAL: + rc = -EFAULT; + if (access_ok(VERIFY_READ, argp, sizeof(struct serial_struct))) + rc = gs_setserial(&PortP->gs, argp); + break; + default: + rc = -ENOIOCTLCMD; + break; + } + func_exit(); + return rc; +} + + +/* The throttle/unthrottle scheme for the Specialix card is different + * from other drivers and deserves some explanation. + * The Specialix hardware takes care of XON/XOFF + * and CTS/RTS flow control itself. This means that all we have to + * do when signalled by the upper tty layer to throttle/unthrottle is + * to make a note of it here. When we come to read characters from the + * rx buffers on the card (rio_receive_chars()) we look to see if the + * upper layer can accept more (as noted here in rio_rx_throt[]). + * If it can't we simply don't remove chars from the cards buffer. + * When the tty layer can accept chars, we again note that here and when + * rio_receive_chars() is called it will remove them from the cards buffer. + * The card will notice that a ports buffer has drained below some low + * water mark and will unflow control the line itself, using whatever + * flow control scheme is in use for that port. -- Simon Allen + */ + +static void rio_throttle(struct tty_struct *tty) +{ + struct Port *port = (struct Port *) tty->driver_data; + + func_enter(); + /* If the port is using any type of input flow + * control then throttle the port. + */ + + if ((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty))) { + port->State |= RIO_THROTTLE_RX; + } + + func_exit(); +} + + +static void rio_unthrottle(struct tty_struct *tty) +{ + struct Port *port = (struct Port *) tty->driver_data; + + func_enter(); + /* Always unthrottle even if flow control is not enabled on + * this port in case we disabled flow control while the port + * was throttled + */ + + port->State &= ~RIO_THROTTLE_RX; + + func_exit(); + return; +} + + + + + +/* ********************************************************************** * + * Here are the initialization routines. * + * ********************************************************************** */ + + +static struct vpd_prom *get_VPD_PROM(struct Host *hp) +{ + static struct vpd_prom vpdp; + char *p; + int i; + + func_enter(); + rio_dprintk(RIO_DEBUG_PROBE, "Going to verify vpd prom at %p.\n", hp->Caddr + RIO_VPD_ROM); + + p = (char *) &vpdp; + for (i = 0; i < sizeof(struct vpd_prom); i++) + *p++ = readb(hp->Caddr + RIO_VPD_ROM + i * 2); + /* read_rio_byte (hp, RIO_VPD_ROM + i*2); */ + + /* Terminate the identifier string. + *** requires one extra byte in struct vpd_prom *** */ + *p++ = 0; + + if (rio_debug & RIO_DEBUG_PROBE) + my_hd((char *) &vpdp, 0x20); + + func_exit(); + + return &vpdp; +} + +static const struct tty_operations rio_ops = { + .open = riotopen, + .close = gs_close, + .write = gs_write, + .put_char = gs_put_char, + .flush_chars = gs_flush_chars, + .write_room = gs_write_room, + .chars_in_buffer = gs_chars_in_buffer, + .flush_buffer = gs_flush_buffer, + .ioctl = rio_ioctl, + .throttle = rio_throttle, + .unthrottle = rio_unthrottle, + .set_termios = gs_set_termios, + .stop = gs_stop, + .start = gs_start, + .hangup = gs_hangup, +}; + +static int rio_init_drivers(void) +{ + int error = -ENOMEM; + + rio_driver = alloc_tty_driver(256); + if (!rio_driver) + goto out; + rio_driver2 = alloc_tty_driver(256); + if (!rio_driver2) + goto out1; + + func_enter(); + + rio_driver->owner = THIS_MODULE; + rio_driver->driver_name = "specialix_rio"; + rio_driver->name = "ttySR"; + rio_driver->major = RIO_NORMAL_MAJOR0; + rio_driver->type = TTY_DRIVER_TYPE_SERIAL; + rio_driver->subtype = SERIAL_TYPE_NORMAL; + rio_driver->init_termios = tty_std_termios; + rio_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + rio_driver->flags = TTY_DRIVER_REAL_RAW; + tty_set_operations(rio_driver, &rio_ops); + + rio_driver2->owner = THIS_MODULE; + rio_driver2->driver_name = "specialix_rio"; + rio_driver2->name = "ttySR"; + rio_driver2->major = RIO_NORMAL_MAJOR1; + rio_driver2->type = TTY_DRIVER_TYPE_SERIAL; + rio_driver2->subtype = SERIAL_TYPE_NORMAL; + rio_driver2->init_termios = tty_std_termios; + rio_driver2->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + rio_driver2->flags = TTY_DRIVER_REAL_RAW; + tty_set_operations(rio_driver2, &rio_ops); + + rio_dprintk(RIO_DEBUG_INIT, "set_termios = %p\n", gs_set_termios); + + if ((error = tty_register_driver(rio_driver))) + goto out2; + if ((error = tty_register_driver(rio_driver2))) + goto out3; + func_exit(); + return 0; + out3: + tty_unregister_driver(rio_driver); + out2: + put_tty_driver(rio_driver2); + out1: + put_tty_driver(rio_driver); + out: + printk(KERN_ERR "rio: Couldn't register a rio driver, error = %d\n", error); + return 1; +} + +static const struct tty_port_operations rio_port_ops = { + .carrier_raised = rio_carrier_raised, +}; + +static int rio_init_datastructures(void) +{ + int i; + struct Port *port; + func_enter(); + + /* Many drivers statically allocate the maximum number of ports + There is no reason not to allocate them dynamically. Is there? -- REW */ + /* However, the RIO driver allows users to configure their first + RTA as the ports numbered 504-511. We therefore need to allocate + the whole range. :-( -- REW */ + +#define RI_SZ sizeof(struct rio_info) +#define HOST_SZ sizeof(struct Host) +#define PORT_SZ sizeof(struct Port *) +#define TMIO_SZ sizeof(struct termios *) + rio_dprintk(RIO_DEBUG_INIT, "getting : %Zd %Zd %Zd %Zd %Zd bytes\n", RI_SZ, RIO_HOSTS * HOST_SZ, RIO_PORTS * PORT_SZ, RIO_PORTS * TMIO_SZ, RIO_PORTS * TMIO_SZ); + + if (!(p = kzalloc(RI_SZ, GFP_KERNEL))) + goto free0; + if (!(p->RIOHosts = kzalloc(RIO_HOSTS * HOST_SZ, GFP_KERNEL))) + goto free1; + if (!(p->RIOPortp = kzalloc(RIO_PORTS * PORT_SZ, GFP_KERNEL))) + goto free2; + p->RIOConf = RIOConf; + rio_dprintk(RIO_DEBUG_INIT, "Got : %p %p %p\n", p, p->RIOHosts, p->RIOPortp); + +#if 1 + for (i = 0; i < RIO_PORTS; i++) { + port = p->RIOPortp[i] = kzalloc(sizeof(struct Port), GFP_KERNEL); + if (!port) { + goto free6; + } + rio_dprintk(RIO_DEBUG_INIT, "initing port %d (%d)\n", i, port->Mapped); + tty_port_init(&port->gs.port); + port->gs.port.ops = &rio_port_ops; + port->PortNum = i; + port->gs.magic = RIO_MAGIC; + port->gs.close_delay = HZ / 2; + port->gs.closing_wait = 30 * HZ; + port->gs.rd = &rio_real_driver; + spin_lock_init(&port->portSem); + } +#else + /* We could postpone initializing them to when they are configured. */ +#endif + + + + if (rio_debug & RIO_DEBUG_INIT) { + my_hd(&rio_real_driver, sizeof(rio_real_driver)); + } + + + func_exit(); + return 0; + + free6:for (i--; i >= 0; i--) + kfree(p->RIOPortp[i]); +/*free5: + free4: + free3:*/ kfree(p->RIOPortp); + free2:kfree(p->RIOHosts); + free1: + rio_dprintk(RIO_DEBUG_INIT, "Not enough memory! %p %p %p\n", p, p->RIOHosts, p->RIOPortp); + kfree(p); + free0: + return -ENOMEM; +} + +static void __exit rio_release_drivers(void) +{ + func_enter(); + tty_unregister_driver(rio_driver2); + tty_unregister_driver(rio_driver); + put_tty_driver(rio_driver2); + put_tty_driver(rio_driver); + func_exit(); +} + + +#ifdef CONFIG_PCI + /* This was written for SX, but applies to RIO too... + (including bugs....) + + There is another bit besides Bit 17. Turning that bit off + (on boards shipped with the fix in the eeprom) results in a + hang on the next access to the card. + */ + + /******************************************************** + * Setting bit 17 in the CNTRL register of the PLX 9050 * + * chip forces a retry on writes while a read is pending.* + * This is to prevent the card locking up on Intel Xeon * + * multiprocessor systems with the NX chipset. -- NV * + ********************************************************/ + +/* Newer cards are produced with this bit set from the configuration + EEprom. As the bit is read/write for the CPU, we can fix it here, + if we detect that it isn't set correctly. -- REW */ + +static void fix_rio_pci(struct pci_dev *pdev) +{ + unsigned long hwbase; + unsigned char __iomem *rebase; + unsigned int t; + +#define CNTRL_REG_OFFSET 0x50 +#define CNTRL_REG_GOODVALUE 0x18260000 + + hwbase = pci_resource_start(pdev, 0); + rebase = ioremap(hwbase, 0x80); + t = readl(rebase + CNTRL_REG_OFFSET); + if (t != CNTRL_REG_GOODVALUE) { + printk(KERN_DEBUG "rio: performing cntrl reg fix: %08x -> %08x\n", t, CNTRL_REG_GOODVALUE); + writel(CNTRL_REG_GOODVALUE, rebase + CNTRL_REG_OFFSET); + } + iounmap(rebase); +} +#endif + + +static int __init rio_init(void) +{ + int found = 0; + int i; + struct Host *hp; + int retval; + struct vpd_prom *vpdp; + int okboard; + +#ifdef CONFIG_PCI + struct pci_dev *pdev = NULL; + unsigned short tshort; +#endif + + func_enter(); + rio_dprintk(RIO_DEBUG_INIT, "Initing rio module... (rio_debug=%d)\n", rio_debug); + + if (abs((long) (&rio_debug) - rio_debug) < 0x10000) { + printk(KERN_WARNING "rio: rio_debug is an address, instead of a value. " "Assuming -1. Was %x/%p.\n", rio_debug, &rio_debug); + rio_debug = -1; + } + + if (misc_register(&rio_fw_device) < 0) { + printk(KERN_ERR "RIO: Unable to register firmware loader driver.\n"); + return -EIO; + } + + retval = rio_init_datastructures(); + if (retval < 0) { + misc_deregister(&rio_fw_device); + return retval; + } +#ifdef CONFIG_PCI + /* First look for the JET devices: */ + while ((pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, pdev))) { + u32 tint; + + if (pci_enable_device(pdev)) + continue; + + /* Specialix has a whole bunch of cards with + 0x2000 as the device ID. They say its because + the standard requires it. Stupid standard. */ + /* It seems that reading a word doesn't work reliably on 2.0. + Also, reading a non-aligned dword doesn't work. So we read the + whole dword at 0x2c and extract the word at 0x2e (SUBSYSTEM_ID) + ourselves */ + pci_read_config_dword(pdev, 0x2c, &tint); + tshort = (tint >> 16) & 0xffff; + rio_dprintk(RIO_DEBUG_PROBE, "Got a specialix card: %x.\n", tint); + if (tshort != 0x0100) { + rio_dprintk(RIO_DEBUG_PROBE, "But it's not a RIO card (%d)...\n", tshort); + continue; + } + rio_dprintk(RIO_DEBUG_PROBE, "cp1\n"); + + hp = &p->RIOHosts[p->RIONumHosts]; + hp->PaddrP = pci_resource_start(pdev, 2); + hp->Ivec = pdev->irq; + if (((1 << hp->Ivec) & rio_irqmask) == 0) + hp->Ivec = 0; + hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); + hp->CardP = (struct DpRam __iomem *) hp->Caddr; + hp->Type = RIO_PCI; + hp->Copy = rio_copy_to_card; + hp->Mode = RIO_PCI_BOOT_FROM_RAM; + spin_lock_init(&hp->HostLock); + rio_reset_interrupt(hp); + rio_start_card_running(hp); + + rio_dprintk(RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n", (void *) p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr); + if (RIOBoardTest(p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr, RIO_PCI, 0) == 0) { + rio_dprintk(RIO_DEBUG_INIT, "Done RIOBoardTest\n"); + writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt); + p->RIOHosts[p->RIONumHosts].UniqueNum = + ((readb(&p->RIOHosts[p->RIONumHosts].Unique[0]) & 0xFF) << 0) | + ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24); + rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); + + fix_rio_pci(pdev); + + p->RIOHosts[p->RIONumHosts].pdev = pdev; + pci_dev_get(pdev); + + p->RIOLastPCISearch = 0; + p->RIONumHosts++; + found++; + } else { + iounmap(p->RIOHosts[p->RIONumHosts].Caddr); + p->RIOHosts[p->RIONumHosts].Caddr = NULL; + } + } + + /* Then look for the older PCI card.... : */ + + /* These older PCI cards have problems (only byte-mode access is + supported), which makes them a bit awkward to support. + They also have problems sharing interrupts. Be careful. + (The driver now refuses to share interrupts for these + cards. This should be sufficient). + */ + + /* Then look for the older RIO/PCI devices: */ + while ((pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_RIO, pdev))) { + if (pci_enable_device(pdev)) + continue; + +#ifdef CONFIG_RIO_OLDPCI + hp = &p->RIOHosts[p->RIONumHosts]; + hp->PaddrP = pci_resource_start(pdev, 0); + hp->Ivec = pdev->irq; + if (((1 << hp->Ivec) & rio_irqmask) == 0) + hp->Ivec = 0; + hp->Ivec |= 0x8000; /* Mark as non-sharable */ + hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); + hp->CardP = (struct DpRam __iomem *) hp->Caddr; + hp->Type = RIO_PCI; + hp->Copy = rio_copy_to_card; + hp->Mode = RIO_PCI_BOOT_FROM_RAM; + spin_lock_init(&hp->HostLock); + + rio_dprintk(RIO_DEBUG_PROBE, "Ivec: %x\n", hp->Ivec); + rio_dprintk(RIO_DEBUG_PROBE, "Mode: %x\n", hp->Mode); + + rio_reset_interrupt(hp); + rio_start_card_running(hp); + rio_dprintk(RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n", (void *) p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr); + if (RIOBoardTest(p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr, RIO_PCI, 0) == 0) { + writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt); + p->RIOHosts[p->RIONumHosts].UniqueNum = + ((readb(&p->RIOHosts[p->RIONumHosts].Unique[0]) & 0xFF) << 0) | + ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24); + rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); + + p->RIOHosts[p->RIONumHosts].pdev = pdev; + pci_dev_get(pdev); + + p->RIOLastPCISearch = 0; + p->RIONumHosts++; + found++; + } else { + iounmap(p->RIOHosts[p->RIONumHosts].Caddr); + p->RIOHosts[p->RIONumHosts].Caddr = NULL; + } +#else + printk(KERN_ERR "Found an older RIO PCI card, but the driver is not " "compiled to support it.\n"); +#endif + } +#endif /* PCI */ + + /* Now probe for ISA cards... */ + for (i = 0; i < NR_RIO_ADDRS; i++) { + hp = &p->RIOHosts[p->RIONumHosts]; + hp->PaddrP = rio_probe_addrs[i]; + /* There was something about the IRQs of these cards. 'Forget what.--REW */ + hp->Ivec = 0; + hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); + hp->CardP = (struct DpRam __iomem *) hp->Caddr; + hp->Type = RIO_AT; + hp->Copy = rio_copy_to_card; /* AT card PCI???? - PVDL + * -- YES! this is now a normal copy. Only the + * old PCI card uses the special PCI copy. + * Moreover, the ISA card will work with the + * special PCI copy anyway. -- REW */ + hp->Mode = 0; + spin_lock_init(&hp->HostLock); + + vpdp = get_VPD_PROM(hp); + rio_dprintk(RIO_DEBUG_PROBE, "Got VPD ROM\n"); + okboard = 0; + if ((strncmp(vpdp->identifier, RIO_ISA_IDENT, 16) == 0) || (strncmp(vpdp->identifier, RIO_ISA2_IDENT, 16) == 0) || (strncmp(vpdp->identifier, RIO_ISA3_IDENT, 16) == 0)) { + /* Board is present... */ + if (RIOBoardTest(hp->PaddrP, hp->Caddr, RIO_AT, 0) == 0) { + /* ... and feeling fine!!!! */ + rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); + if (RIOAssignAT(p, hp->PaddrP, hp->Caddr, 0)) { + rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, host%d uniqid = %x.\n", p->RIONumHosts, p->RIOHosts[p->RIONumHosts - 1].UniqueNum); + okboard++; + found++; + } + } + + if (!okboard) { + iounmap(hp->Caddr); + hp->Caddr = NULL; + } + } + } + + + for (i = 0; i < p->RIONumHosts; i++) { + hp = &p->RIOHosts[i]; + if (hp->Ivec) { + int mode = IRQF_SHARED; + if (hp->Ivec & 0x8000) { + mode = 0; + hp->Ivec &= 0x7fff; + } + rio_dprintk(RIO_DEBUG_INIT, "Requesting interrupt hp: %p rio_interrupt: %d Mode: %x\n", hp, hp->Ivec, hp->Mode); + retval = request_irq(hp->Ivec, rio_interrupt, mode, "rio", hp); + rio_dprintk(RIO_DEBUG_INIT, "Return value from request_irq: %d\n", retval); + if (retval) { + printk(KERN_ERR "rio: Cannot allocate irq %d.\n", hp->Ivec); + hp->Ivec = 0; + } + rio_dprintk(RIO_DEBUG_INIT, "Got irq %d.\n", hp->Ivec); + if (hp->Ivec != 0) { + rio_dprintk(RIO_DEBUG_INIT, "Enabling interrupts on rio card.\n"); + hp->Mode |= RIO_PCI_INT_ENABLE; + } else + hp->Mode &= ~RIO_PCI_INT_ENABLE; + rio_dprintk(RIO_DEBUG_INIT, "New Mode: %x\n", hp->Mode); + rio_start_card_running(hp); + } + /* Init the timer "always" to make sure that it can safely be + deleted when we unload... */ + + setup_timer(&hp->timer, rio_pollfunc, i); + if (!hp->Ivec) { + rio_dprintk(RIO_DEBUG_INIT, "Starting polling at %dj intervals.\n", rio_poll); + mod_timer(&hp->timer, jiffies + rio_poll); + } + } + + if (found) { + rio_dprintk(RIO_DEBUG_INIT, "rio: total of %d boards detected.\n", found); + rio_init_drivers(); + } else { + /* deregister the misc device we created earlier */ + misc_deregister(&rio_fw_device); + } + + func_exit(); + return found ? 0 : -EIO; +} + + +static void __exit rio_exit(void) +{ + int i; + struct Host *hp; + + func_enter(); + + for (i = 0, hp = p->RIOHosts; i < p->RIONumHosts; i++, hp++) { + RIOHostReset(hp->Type, hp->CardP, hp->Slot); + if (hp->Ivec) { + free_irq(hp->Ivec, hp); + rio_dprintk(RIO_DEBUG_INIT, "freed irq %d.\n", hp->Ivec); + } + /* It is safe/allowed to del_timer a non-active timer */ + del_timer_sync(&hp->timer); + if (hp->Caddr) + iounmap(hp->Caddr); + if (hp->Type == RIO_PCI) + pci_dev_put(hp->pdev); + } + + if (misc_deregister(&rio_fw_device) < 0) { + printk(KERN_INFO "rio: couldn't deregister control-device\n"); + } + + + rio_dprintk(RIO_DEBUG_CLEANUP, "Cleaning up drivers\n"); + + rio_release_drivers(); + + /* Release dynamically allocated memory */ + kfree(p->RIOPortp); + kfree(p->RIOHosts); + kfree(p); + + func_exit(); +} + +module_init(rio_init); +module_exit(rio_exit); diff --git a/drivers/staging/generic_serial/rio/rio_linux.h b/drivers/staging/generic_serial/rio/rio_linux.h new file mode 100644 index 000000000000..7f26cd7c815e --- /dev/null +++ b/drivers/staging/generic_serial/rio/rio_linux.h @@ -0,0 +1,197 @@ + +/* + * rio_linux.h + * + * Copyright (C) 1998,1999,2000 R.E.Wolff@BitWizard.nl + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * RIO serial driver. + * + * Version 1.0 -- July, 1999. + * + */ + +#define RIO_NBOARDS 4 +#define RIO_PORTSPERBOARD 128 +#define RIO_NPORTS (RIO_NBOARDS * RIO_PORTSPERBOARD) + +#define MODEM_SUPPORT + +#ifdef __KERNEL__ + +#define RIO_MAGIC 0x12345678 + + +struct vpd_prom { + unsigned short id; + char hwrev; + char hwass; + int uniqid; + char myear; + char mweek; + char hw_feature[5]; + char oem_id; + char identifier[16]; +}; + + +#define RIO_DEBUG_ALL 0xffffffff + +#define O_OTHER(tty) \ + ((O_OLCUC(tty)) ||\ + (O_ONLCR(tty)) ||\ + (O_OCRNL(tty)) ||\ + (O_ONOCR(tty)) ||\ + (O_ONLRET(tty)) ||\ + (O_OFILL(tty)) ||\ + (O_OFDEL(tty)) ||\ + (O_NLDLY(tty)) ||\ + (O_CRDLY(tty)) ||\ + (O_TABDLY(tty)) ||\ + (O_BSDLY(tty)) ||\ + (O_VTDLY(tty)) ||\ + (O_FFDLY(tty))) + +/* Same for input. */ +#define I_OTHER(tty) \ + ((I_INLCR(tty)) ||\ + (I_IGNCR(tty)) ||\ + (I_ICRNL(tty)) ||\ + (I_IUCLC(tty)) ||\ + (L_ISIG(tty))) + + +#endif /* __KERNEL__ */ + + +#define RIO_BOARD_INTR_LOCK 1 + + +#ifndef RIOCTL_MISC_MINOR +/* Allow others to gather this into "major.h" or something like that */ +#define RIOCTL_MISC_MINOR 169 +#endif + + +/* Allow us to debug "in the field" without requiring clients to + recompile.... */ +#if 1 +#define rio_spin_lock_irqsave(sem, flags) do { \ + rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlockirqsave: %p %s:%d\n", \ + sem, __FILE__, __LINE__);\ + spin_lock_irqsave(sem, flags);\ + } while (0) + +#define rio_spin_unlock_irqrestore(sem, flags) do { \ + rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlockirqrestore: %p %s:%d\n",\ + sem, __FILE__, __LINE__);\ + spin_unlock_irqrestore(sem, flags);\ + } while (0) + +#define rio_spin_lock(sem) do { \ + rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlock: %p %s:%d\n",\ + sem, __FILE__, __LINE__);\ + spin_lock(sem);\ + } while (0) + +#define rio_spin_unlock(sem) do { \ + rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlock: %p %s:%d\n",\ + sem, __FILE__, __LINE__);\ + spin_unlock(sem);\ + } while (0) +#else +#define rio_spin_lock_irqsave(sem, flags) \ + spin_lock_irqsave(sem, flags) + +#define rio_spin_unlock_irqrestore(sem, flags) \ + spin_unlock_irqrestore(sem, flags) + +#define rio_spin_lock(sem) \ + spin_lock(sem) + +#define rio_spin_unlock(sem) \ + spin_unlock(sem) + +#endif + + + +#ifdef CONFIG_RIO_OLDPCI +static inline void __iomem *rio_memcpy_toio(void __iomem *dummy, void __iomem *dest, void *source, int n) +{ + char __iomem *dst = dest; + char *src = source; + + while (n--) { + writeb(*src++, dst++); + (void) readb(dummy); + } + + return dest; +} + +static inline void __iomem *rio_copy_toio(void __iomem *dest, void *source, int n) +{ + char __iomem *dst = dest; + char *src = source; + + while (n--) + writeb(*src++, dst++); + + return dest; +} + + +static inline void *rio_memcpy_fromio(void *dest, void __iomem *source, int n) +{ + char *dst = dest; + char __iomem *src = source; + + while (n--) + *dst++ = readb(src++); + + return dest; +} + +#else +#define rio_memcpy_toio(dummy,dest,source,n) memcpy_toio(dest, source, n) +#define rio_copy_toio memcpy_toio +#define rio_memcpy_fromio memcpy_fromio +#endif + +#define DEBUG 1 + + +/* + This driver can spew a whole lot of debugging output at you. If you + need maximum performance, you should disable the DEBUG define. To + aid in debugging in the field, I'm leaving the compile-time debug + features enabled, and disable them "runtime". That allows me to + instruct people with problems to enable debugging without requiring + them to recompile... +*/ + +#ifdef DEBUG +#define rio_dprintk(f, str...) do { if (rio_debug & f) printk (str);} while (0) +#define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s\n", __func__) +#define func_exit() rio_dprintk (RIO_DEBUG_FLOW, "rio: exit %s\n", __func__) +#define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s (port %d)\n",__func__, port->line) +#else +#define rio_dprintk(f, str...) /* nothing */ +#define func_enter() +#define func_exit() +#define func_enter2() +#endif diff --git a/drivers/staging/generic_serial/rio/rioboard.h b/drivers/staging/generic_serial/rio/rioboard.h new file mode 100644 index 000000000000..252230043c82 --- /dev/null +++ b/drivers/staging/generic_serial/rio/rioboard.h @@ -0,0 +1,275 @@ +/************************************************************************/ +/* */ +/* Title : RIO Host Card Hardware Definitions */ +/* */ +/* Author : N.P.Vassallo */ +/* */ +/* Creation : 26th April 1999 */ +/* */ +/* Version : 1.0.0 */ +/* */ +/* Copyright : (c) Specialix International Ltd. 1999 * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * */ +/* Description : Prototypes, structures and definitions */ +/* describing the RIO board hardware */ +/* */ +/************************************************************************/ + +#ifndef _rioboard_h /* If RIOBOARD.H not already defined */ +#define _rioboard_h 1 + +/***************************************************************************** +*********************** *********************** +*********************** Hardware Control Registers *********************** +*********************** *********************** +*****************************************************************************/ + +/* Hardware Registers... */ + +#define RIO_REG_BASE 0x7C00 /* Base of control registers */ + +#define RIO_CONFIG RIO_REG_BASE + 0x0000 /* WRITE: Configuration Register */ +#define RIO_INTSET RIO_REG_BASE + 0x0080 /* WRITE: Interrupt Set */ +#define RIO_RESET RIO_REG_BASE + 0x0100 /* WRITE: Host Reset */ +#define RIO_INTRESET RIO_REG_BASE + 0x0180 /* WRITE: Interrupt Reset */ + +#define RIO_VPD_ROM RIO_REG_BASE + 0x0000 /* READ: Vital Product Data ROM */ +#define RIO_INTSTAT RIO_REG_BASE + 0x0080 /* READ: Interrupt Status (Jet boards only) */ +#define RIO_RESETSTAT RIO_REG_BASE + 0x0100 /* READ: Reset Status (Jet boards only) */ + +/* RIO_VPD_ROM definitions... */ +#define VPD_SLX_ID1 0x00 /* READ: Specialix Identifier #1 */ +#define VPD_SLX_ID2 0x01 /* READ: Specialix Identifier #2 */ +#define VPD_HW_REV 0x02 /* READ: Hardware Revision */ +#define VPD_HW_ASSEM 0x03 /* READ: Hardware Assembly Level */ +#define VPD_UNIQUEID4 0x04 /* READ: Unique Identifier #4 */ +#define VPD_UNIQUEID3 0x05 /* READ: Unique Identifier #3 */ +#define VPD_UNIQUEID2 0x06 /* READ: Unique Identifier #2 */ +#define VPD_UNIQUEID1 0x07 /* READ: Unique Identifier #1 */ +#define VPD_MANU_YEAR 0x08 /* READ: Year Of Manufacture (0 = 1970) */ +#define VPD_MANU_WEEK 0x09 /* READ: Week Of Manufacture (0 = week 1 Jan) */ +#define VPD_HWFEATURE1 0x0A /* READ: Hardware Feature Byte 1 */ +#define VPD_HWFEATURE2 0x0B /* READ: Hardware Feature Byte 2 */ +#define VPD_HWFEATURE3 0x0C /* READ: Hardware Feature Byte 3 */ +#define VPD_HWFEATURE4 0x0D /* READ: Hardware Feature Byte 4 */ +#define VPD_HWFEATURE5 0x0E /* READ: Hardware Feature Byte 5 */ +#define VPD_OEMID 0x0F /* READ: OEM Identifier */ +#define VPD_IDENT 0x10 /* READ: Identifier string (16 bytes) */ +#define VPD_IDENT_LEN 0x10 + +/* VPD ROM Definitions... */ +#define SLX_ID1 0x4D +#define SLX_ID2 0x98 + +#define PRODUCT_ID(a) ((a>>4)&0xF) /* Use to obtain Product ID from VPD_UNIQUEID1 */ + +#define ID_SX_ISA 0x2 +#define ID_RIO_EISA 0x3 +#define ID_SX_PCI 0x5 +#define ID_SX_EISA 0x7 +#define ID_RIO_RTA16 0x9 +#define ID_RIO_ISA 0xA +#define ID_RIO_MCA 0xB +#define ID_RIO_SBUS 0xC +#define ID_RIO_PCI 0xD +#define ID_RIO_RTA8 0xE + +/* Transputer bootstrap definitions... */ + +#define BOOTLOADADDR (0x8000 - 6) +#define BOOTINDICATE (0x8000 - 2) + +/* Firmware load position... */ + +#define FIRMWARELOADADDR 0x7C00 /* Firmware is loaded _before_ this address */ + +/***************************************************************************** +***************************** ***************************** +***************************** RIO (Rev1) ISA ***************************** +***************************** ***************************** +*****************************************************************************/ + +/* Control Register Definitions... */ +#define RIO_ISA_IDENT "JBJGPGGHINSMJPJR" + +#define RIO_ISA_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ +#define RIO_ISA_CFG_BUSENABLE 0x02 /* Enable processor bus */ +#define RIO_ISA_CFG_IRQMASK 0x30 /* Interrupt mask */ +#define RIO_ISA_CFG_IRQ12 0x10 /* Interrupt Level 12 */ +#define RIO_ISA_CFG_IRQ11 0x20 /* Interrupt Level 11 */ +#define RIO_ISA_CFG_IRQ9 0x30 /* Interrupt Level 9 */ +#define RIO_ISA_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ +#define RIO_ISA_CFG_WAITSTATE0 0x80 /* 0 waitstates, else 1 */ + +/***************************************************************************** +***************************** ***************************** +***************************** RIO (Rev2) ISA ***************************** +***************************** ***************************** +*****************************************************************************/ + +/* Control Register Definitions... */ +#define RIO_ISA2_IDENT "JBJGPGGHINSMJPJR" + +#define RIO_ISA2_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ +#define RIO_ISA2_CFG_BUSENABLE 0x02 /* Enable processor bus */ +#define RIO_ISA2_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ +#define RIO_ISA2_CFG_16BIT 0x08 /* 16bit mode, else 8bit */ +#define RIO_ISA2_CFG_IRQMASK 0x30 /* Interrupt mask */ +#define RIO_ISA2_CFG_IRQ15 0x00 /* Interrupt Level 15 */ +#define RIO_ISA2_CFG_IRQ12 0x10 /* Interrupt Level 12 */ +#define RIO_ISA2_CFG_IRQ11 0x20 /* Interrupt Level 11 */ +#define RIO_ISA2_CFG_IRQ9 0x30 /* Interrupt Level 9 */ +#define RIO_ISA2_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ +#define RIO_ISA2_CFG_WAITSTATE0 0x80 /* 0 waitstates, else 1 */ + +/***************************************************************************** +***************************** ****************************** +***************************** RIO (Jet) ISA ****************************** +***************************** ****************************** +*****************************************************************************/ + +/* Control Register Definitions... */ +#define RIO_ISA3_IDENT "JET HOST BY KEV#" + +#define RIO_ISA3_CFG_BUSENABLE 0x02 /* Enable processor bus */ +#define RIO_ISA3_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ +#define RIO_ISA32_CFG_IRQMASK 0xF30 /* Interrupt mask */ +#define RIO_ISA3_CFG_IRQ15 0xF0 /* Interrupt Level 15 */ +#define RIO_ISA3_CFG_IRQ12 0xC0 /* Interrupt Level 12 */ +#define RIO_ISA3_CFG_IRQ11 0xB0 /* Interrupt Level 11 */ +#define RIO_ISA3_CFG_IRQ10 0xA0 /* Interrupt Level 10 */ +#define RIO_ISA3_CFG_IRQ9 0x90 /* Interrupt Level 9 */ + +/***************************************************************************** +********************************* ******************************** +********************************* RIO MCA ******************************** +********************************* ******************************** +*****************************************************************************/ + +/* Control Register Definitions... */ +#define RIO_MCA_IDENT "JBJGPGGHINSMJPJR" + +#define RIO_MCA_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ +#define RIO_MCA_CFG_BUSENABLE 0x02 /* Enable processor bus */ +#define RIO_MCA_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ + +/***************************************************************************** +******************************** ******************************** +******************************** RIO EISA ******************************** +******************************** ******************************** +*****************************************************************************/ + +/* EISA Configuration Space Definitions... */ +#define EISA_PRODUCT_ID1 0xC80 +#define EISA_PRODUCT_ID2 0xC81 +#define EISA_PRODUCT_NUMBER 0xC82 +#define EISA_REVISION_NUMBER 0xC83 +#define EISA_CARD_ENABLE 0xC84 +#define EISA_VPD_UNIQUEID4 0xC88 /* READ: Unique Identifier #4 */ +#define EISA_VPD_UNIQUEID3 0xC8A /* READ: Unique Identifier #3 */ +#define EISA_VPD_UNIQUEID2 0xC90 /* READ: Unique Identifier #2 */ +#define EISA_VPD_UNIQUEID1 0xC92 /* READ: Unique Identifier #1 */ +#define EISA_VPD_MANU_YEAR 0xC98 /* READ: Year Of Manufacture (0 = 1970) */ +#define EISA_VPD_MANU_WEEK 0xC9A /* READ: Week Of Manufacture (0 = week 1 Jan) */ +#define EISA_MEM_ADDR_23_16 0xC00 +#define EISA_MEM_ADDR_31_24 0xC01 +#define EISA_RIO_CONFIG 0xC02 /* WRITE: Configuration Register */ +#define EISA_RIO_INTSET 0xC03 /* WRITE: Interrupt Set */ +#define EISA_RIO_INTRESET 0xC03 /* READ: Interrupt Reset */ + +/* Control Register Definitions... */ +#define RIO_EISA_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ +#define RIO_EISA_CFG_LINK20 0x02 /* 20Mbps link, else 10Mbps */ +#define RIO_EISA_CFG_BUSENABLE 0x04 /* Enable processor bus */ +#define RIO_EISA_CFG_PROCRUN 0x08 /* Processor running, else reset */ +#define RIO_EISA_CFG_IRQMASK 0xF0 /* Interrupt mask */ +#define RIO_EISA_CFG_IRQ15 0xF0 /* Interrupt Level 15 */ +#define RIO_EISA_CFG_IRQ14 0xE0 /* Interrupt Level 14 */ +#define RIO_EISA_CFG_IRQ12 0xC0 /* Interrupt Level 12 */ +#define RIO_EISA_CFG_IRQ11 0xB0 /* Interrupt Level 11 */ +#define RIO_EISA_CFG_IRQ10 0xA0 /* Interrupt Level 10 */ +#define RIO_EISA_CFG_IRQ9 0x90 /* Interrupt Level 9 */ +#define RIO_EISA_CFG_IRQ7 0x70 /* Interrupt Level 7 */ +#define RIO_EISA_CFG_IRQ6 0x60 /* Interrupt Level 6 */ +#define RIO_EISA_CFG_IRQ5 0x50 /* Interrupt Level 5 */ +#define RIO_EISA_CFG_IRQ4 0x40 /* Interrupt Level 4 */ +#define RIO_EISA_CFG_IRQ3 0x30 /* Interrupt Level 3 */ + +/***************************************************************************** +******************************** ******************************** +******************************** RIO SBus ******************************** +******************************** ******************************** +*****************************************************************************/ + +/* Control Register Definitions... */ +#define RIO_SBUS_IDENT "JBPGK#\0\0\0\0\0\0\0\0\0\0" + +#define RIO_SBUS_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ +#define RIO_SBUS_CFG_BUSENABLE 0x02 /* Enable processor bus */ +#define RIO_SBUS_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ +#define RIO_SBUS_CFG_IRQMASK 0x38 /* Interrupt mask */ +#define RIO_SBUS_CFG_IRQNONE 0x00 /* No Interrupt */ +#define RIO_SBUS_CFG_IRQ7 0x38 /* Interrupt Level 7 */ +#define RIO_SBUS_CFG_IRQ6 0x30 /* Interrupt Level 6 */ +#define RIO_SBUS_CFG_IRQ5 0x28 /* Interrupt Level 5 */ +#define RIO_SBUS_CFG_IRQ4 0x20 /* Interrupt Level 4 */ +#define RIO_SBUS_CFG_IRQ3 0x18 /* Interrupt Level 3 */ +#define RIO_SBUS_CFG_IRQ2 0x10 /* Interrupt Level 2 */ +#define RIO_SBUS_CFG_IRQ1 0x08 /* Interrupt Level 1 */ +#define RIO_SBUS_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ +#define RIO_SBUS_CFG_PROC25 0x80 /* 25Mhz processor clock, else 20Mhz */ + +/***************************************************************************** +********************************* ******************************** +********************************* RIO PCI ******************************** +********************************* ******************************** +*****************************************************************************/ + +/* Control Register Definitions... */ +#define RIO_PCI_IDENT "ECDDPGJGJHJRGSK#" + +#define RIO_PCI_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ +#define RIO_PCI_CFG_BUSENABLE 0x02 /* Enable processor bus */ +#define RIO_PCI_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ +#define RIO_PCI_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ +#define RIO_PCI_CFG_PROC25 0x80 /* 25Mhz processor clock, else 20Mhz */ + +/* PCI Definitions... */ +#define SPX_VENDOR_ID 0x11CB /* Assigned by the PCI SIG */ +#define SPX_DEVICE_ID 0x8000 /* RIO bridge boards */ +#define SPX_PLXDEVICE_ID 0x2000 /* PLX bridge boards */ +#define SPX_SUB_VENDOR_ID SPX_VENDOR_ID /* Same as vendor id */ +#define RIO_SUB_SYS_ID 0x0800 /* RIO PCI board */ + +/***************************************************************************** +***************************** ****************************** +***************************** RIO (Jet) PCI ****************************** +***************************** ****************************** +*****************************************************************************/ + +/* Control Register Definitions... */ +#define RIO_PCI2_IDENT "JET HOST BY KEV#" + +#define RIO_PCI2_CFG_BUSENABLE 0x02 /* Enable processor bus */ +#define RIO_PCI2_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ + +/* PCI Definitions... */ +#define RIO2_SUB_SYS_ID 0x0100 /* RIO (Jet) PCI board */ + +#endif /*_rioboard_h */ + +/* End of RIOBOARD.H */ diff --git a/drivers/staging/generic_serial/rio/rioboot.c b/drivers/staging/generic_serial/rio/rioboot.c new file mode 100644 index 000000000000..d956dd316005 --- /dev/null +++ b/drivers/staging/generic_serial/rio/rioboot.c @@ -0,0 +1,1113 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : rioboot.c +** SID : 1.3 +** Last Modified : 11/6/98 10:33:36 +** Retrieved : 11/6/98 10:33:48 +** +** ident @(#)rioboot.c 1.3 +** +** ----------------------------------------------------------------------------- +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "linux_compat.h" +#include "rio_linux.h" +#include "pkt.h" +#include "daemon.h" +#include "rio.h" +#include "riospace.h" +#include "cmdpkt.h" +#include "map.h" +#include "rup.h" +#include "port.h" +#include "riodrvr.h" +#include "rioinfo.h" +#include "func.h" +#include "errors.h" +#include "pci.h" + +#include "parmmap.h" +#include "unixrup.h" +#include "board.h" +#include "host.h" +#include "phb.h" +#include "link.h" +#include "cmdblk.h" +#include "route.h" + +static int RIOBootComplete(struct rio_info *p, struct Host *HostP, unsigned int Rup, struct PktCmd __iomem *PktCmdP); + +static const unsigned char RIOAtVec2Ctrl[] = { + /* 0 */ INTERRUPT_DISABLE, + /* 1 */ INTERRUPT_DISABLE, + /* 2 */ INTERRUPT_DISABLE, + /* 3 */ INTERRUPT_DISABLE, + /* 4 */ INTERRUPT_DISABLE, + /* 5 */ INTERRUPT_DISABLE, + /* 6 */ INTERRUPT_DISABLE, + /* 7 */ INTERRUPT_DISABLE, + /* 8 */ INTERRUPT_DISABLE, + /* 9 */ IRQ_9 | INTERRUPT_ENABLE, + /* 10 */ INTERRUPT_DISABLE, + /* 11 */ IRQ_11 | INTERRUPT_ENABLE, + /* 12 */ IRQ_12 | INTERRUPT_ENABLE, + /* 13 */ INTERRUPT_DISABLE, + /* 14 */ INTERRUPT_DISABLE, + /* 15 */ IRQ_15 | INTERRUPT_ENABLE +}; + +/** + * RIOBootCodeRTA - Load RTA boot code + * @p: RIO to load + * @rbp: Download descriptor + * + * Called when the user process initiates booting of the card firmware. + * Lads the firmware + */ + +int RIOBootCodeRTA(struct rio_info *p, struct DownLoad * rbp) +{ + int offset; + + func_enter(); + + rio_dprintk(RIO_DEBUG_BOOT, "Data at user address %p\n", rbp->DataP); + + /* + ** Check that we have set asside enough memory for this + */ + if (rbp->Count > SIXTY_FOUR_K) { + rio_dprintk(RIO_DEBUG_BOOT, "RTA Boot Code Too Large!\n"); + p->RIOError.Error = HOST_FILE_TOO_LARGE; + func_exit(); + return -ENOMEM; + } + + if (p->RIOBooting) { + rio_dprintk(RIO_DEBUG_BOOT, "RTA Boot Code : BUSY BUSY BUSY!\n"); + p->RIOError.Error = BOOT_IN_PROGRESS; + func_exit(); + return -EBUSY; + } + + /* + ** The data we load in must end on a (RTA_BOOT_DATA_SIZE) byte boundary, + ** so calculate how far we have to move the data up the buffer + ** to achieve this. + */ + offset = (RTA_BOOT_DATA_SIZE - (rbp->Count % RTA_BOOT_DATA_SIZE)) % RTA_BOOT_DATA_SIZE; + + /* + ** Be clean, and clear the 'unused' portion of the boot buffer, + ** because it will (eventually) be part of the Rta run time environment + ** and so should be zeroed. + */ + memset(p->RIOBootPackets, 0, offset); + + /* + ** Copy the data from user space into the array + */ + + if (copy_from_user(((u8 *)p->RIOBootPackets) + offset, rbp->DataP, rbp->Count)) { + rio_dprintk(RIO_DEBUG_BOOT, "Bad data copy from user space\n"); + p->RIOError.Error = COPYIN_FAILED; + func_exit(); + return -EFAULT; + } + + /* + ** Make sure that our copy of the size includes that offset we discussed + ** earlier. + */ + p->RIONumBootPkts = (rbp->Count + offset) / RTA_BOOT_DATA_SIZE; + p->RIOBootCount = rbp->Count; + + func_exit(); + return 0; +} + +/** + * rio_start_card_running - host card start + * @HostP: The RIO to kick off + * + * Start a RIO processor unit running. Encapsulates the knowledge + * of the card type. + */ + +void rio_start_card_running(struct Host *HostP) +{ + switch (HostP->Type) { + case RIO_AT: + rio_dprintk(RIO_DEBUG_BOOT, "Start ISA card running\n"); + writeb(BOOT_FROM_RAM | EXTERNAL_BUS_ON | HostP->Mode | RIOAtVec2Ctrl[HostP->Ivec & 0xF], &HostP->Control); + break; + case RIO_PCI: + /* + ** PCI is much the same as MCA. Everything is once again memory + ** mapped, so we are writing to memory registers instead of io + ** ports. + */ + rio_dprintk(RIO_DEBUG_BOOT, "Start PCI card running\n"); + writeb(PCITpBootFromRam | PCITpBusEnable | HostP->Mode, &HostP->Control); + break; + default: + rio_dprintk(RIO_DEBUG_BOOT, "Unknown host type %d\n", HostP->Type); + break; + } + return; +} + +/* +** Load in the host boot code - load it directly onto all halted hosts +** of the correct type. +** +** Put your rubber pants on before messing with this code - even the magic +** numbers have trouble understanding what they are doing here. +*/ + +int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp) +{ + struct Host *HostP; + u8 __iomem *Cad; + PARM_MAP __iomem *ParmMapP; + int RupN; + int PortN; + unsigned int host; + u8 __iomem *StartP; + u8 __iomem *DestP; + int wait_count; + u16 OldParmMap; + u16 offset; /* It is very important that this is a u16 */ + u8 *DownCode = NULL; + unsigned long flags; + + HostP = NULL; /* Assure the compiler we've initialized it */ + + + /* Walk the hosts */ + for (host = 0; host < p->RIONumHosts; host++) { + rio_dprintk(RIO_DEBUG_BOOT, "Attempt to boot host %d\n", host); + HostP = &p->RIOHosts[host]; + + rio_dprintk(RIO_DEBUG_BOOT, "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n", HostP->Type, HostP->Mode, HostP->Ivec); + + /* Don't boot hosts already running */ + if ((HostP->Flags & RUN_STATE) != RC_WAITING) { + rio_dprintk(RIO_DEBUG_BOOT, "%s %d already running\n", "Host", host); + continue; + } + + /* + ** Grab a pointer to the card (ioremapped) + */ + Cad = HostP->Caddr; + + /* + ** We are going to (try) and load in rbp->Count bytes. + ** The last byte will reside at p->RIOConf.HostLoadBase-1; + ** Therefore, we need to start copying at address + ** (caddr+p->RIOConf.HostLoadBase-rbp->Count) + */ + StartP = &Cad[p->RIOConf.HostLoadBase - rbp->Count]; + + rio_dprintk(RIO_DEBUG_BOOT, "kernel virtual address for host is %p\n", Cad); + rio_dprintk(RIO_DEBUG_BOOT, "kernel virtual address for download is %p\n", StartP); + rio_dprintk(RIO_DEBUG_BOOT, "host loadbase is 0x%x\n", p->RIOConf.HostLoadBase); + rio_dprintk(RIO_DEBUG_BOOT, "size of download is 0x%x\n", rbp->Count); + + /* Make sure it fits */ + if (p->RIOConf.HostLoadBase < rbp->Count) { + rio_dprintk(RIO_DEBUG_BOOT, "Bin too large\n"); + p->RIOError.Error = HOST_FILE_TOO_LARGE; + func_exit(); + return -EFBIG; + } + /* + ** Ensure that the host really is stopped. + ** Disable it's external bus & twang its reset line. + */ + RIOHostReset(HostP->Type, HostP->CardP, HostP->Slot); + + /* + ** Copy the data directly from user space to the SRAM. + ** This ain't going to be none too clever if the download + ** code is bigger than this segment. + */ + rio_dprintk(RIO_DEBUG_BOOT, "Copy in code\n"); + + /* Buffer to local memory as we want to use I/O space and + some cards only do 8 or 16 bit I/O */ + + DownCode = vmalloc(rbp->Count); + if (!DownCode) { + p->RIOError.Error = NOT_ENOUGH_CORE_FOR_PCI_COPY; + func_exit(); + return -ENOMEM; + } + if (copy_from_user(DownCode, rbp->DataP, rbp->Count)) { + kfree(DownCode); + p->RIOError.Error = COPYIN_FAILED; + func_exit(); + return -EFAULT; + } + HostP->Copy(DownCode, StartP, rbp->Count); + vfree(DownCode); + + rio_dprintk(RIO_DEBUG_BOOT, "Copy completed\n"); + + /* + ** S T O P ! + ** + ** Upto this point the code has been fairly rational, and possibly + ** even straight forward. What follows is a pile of crud that will + ** magically turn into six bytes of transputer assembler. Normally + ** you would expect an array or something, but, being me, I have + ** chosen [been told] to use a technique whereby the startup code + ** will be correct if we change the loadbase for the code. Which + ** brings us onto another issue - the loadbase is the *end* of the + ** code, not the start. + ** + ** If I were you I wouldn't start from here. + */ + + /* + ** We now need to insert a short boot section into + ** the memory at the end of Sram2. This is normally (de)composed + ** of the last eight bytes of the download code. The + ** download has been assembled/compiled to expect to be + ** loaded from 0x7FFF downwards. We have loaded it + ** at some other address. The startup code goes into the small + ** ram window at Sram2, in the last 8 bytes, which are really + ** at addresses 0x7FF8-0x7FFF. + ** + ** If the loadbase is, say, 0x7C00, then we need to branch to + ** address 0x7BFE to run the host.bin startup code. We assemble + ** this jump manually. + ** + ** The two byte sequence 60 08 is loaded into memory at address + ** 0x7FFE,F. This is a local branch to location 0x7FF8 (60 is nfix 0, + ** which adds '0' to the .O register, complements .O, and then shifts + ** it left by 4 bit positions, 08 is a jump .O+8 instruction. This will + ** add 8 to .O (which was 0xFFF0), and will branch RELATIVE to the new + ** location. Now, the branch starts from the value of .PC (or .IP or + ** whatever the bloody register is called on this chip), and the .PC + ** will be pointing to the location AFTER the branch, in this case + ** .PC == 0x8000, so the branch will be to 0x8000+0xFFF8 = 0x7FF8. + ** + ** A long branch is coded at 0x7FF8. This consists of loading a four + ** byte offset into .O using nfix (as above) and pfix operators. The + ** pfix operates in exactly the same way as the nfix operator, but + ** without the complement operation. The offset, of course, must be + ** relative to the address of the byte AFTER the branch instruction, + ** which will be (urm) 0x7FFC, so, our final destination of the branch + ** (loadbase-2), has to be reached from here. Imagine that the loadbase + ** is 0x7C00 (which it is), then we will need to branch to 0x7BFE (which + ** is the first byte of the initial two byte short local branch of the + ** download code). + ** + ** To code a jump from 0x7FFC (which is where the branch will start + ** from) to 0x7BFE, we will need to branch 0xFC02 bytes (0x7FFC+0xFC02)= + ** 0x7BFE. + ** This will be coded as four bytes: + ** 60 2C 20 02 + ** being nfix .O+0 + ** pfix .O+C + ** pfix .O+0 + ** jump .O+2 + ** + ** The nfix operator is used, so that the startup code will be + ** compatible with the whole Tp family. (lies, damn lies, it'll never + ** work in a month of Sundays). + ** + ** The nfix nyble is the 1s complement of the nyble value you + ** want to load - in this case we wanted 'F' so we nfix loaded '0'. + */ + + + /* + ** Dest points to the top 8 bytes of Sram2. The Tp jumps + ** to 0x7FFE at reset time, and starts executing. This is + ** a short branch to 0x7FF8, where a long branch is coded. + */ + + DestP = &Cad[0x7FF8]; /* <<<---- READ THE ABOVE COMMENTS */ + +#define NFIX(N) (0x60 | (N)) /* .O = (~(.O + N))<<4 */ +#define PFIX(N) (0x20 | (N)) /* .O = (.O + N)<<4 */ +#define JUMP(N) (0x00 | (N)) /* .PC = .PC + .O */ + + /* + ** 0x7FFC is the address of the location following the last byte of + ** the four byte jump instruction. + ** READ THE ABOVE COMMENTS + ** + ** offset is (TO-FROM) % MEMSIZE, but with compound buggering about. + ** Memsize is 64K for this range of Tp, so offset is a short (unsigned, + ** cos I don't understand 2's complement). + */ + offset = (p->RIOConf.HostLoadBase - 2) - 0x7FFC; + + writeb(NFIX(((unsigned short) (~offset) >> (unsigned short) 12) & 0xF), DestP); + writeb(PFIX((offset >> 8) & 0xF), DestP + 1); + writeb(PFIX((offset >> 4) & 0xF), DestP + 2); + writeb(JUMP(offset & 0xF), DestP + 3); + + writeb(NFIX(0), DestP + 6); + writeb(JUMP(8), DestP + 7); + + rio_dprintk(RIO_DEBUG_BOOT, "host loadbase is 0x%x\n", p->RIOConf.HostLoadBase); + rio_dprintk(RIO_DEBUG_BOOT, "startup offset is 0x%x\n", offset); + + /* + ** Flag what is going on + */ + HostP->Flags &= ~RUN_STATE; + HostP->Flags |= RC_STARTUP; + + /* + ** Grab a copy of the current ParmMap pointer, so we + ** can tell when it has changed. + */ + OldParmMap = readw(&HostP->__ParmMapR); + + rio_dprintk(RIO_DEBUG_BOOT, "Original parmmap is 0x%x\n", OldParmMap); + + /* + ** And start it running (I hope). + ** As there is nothing dodgy or obscure about the + ** above code, this is guaranteed to work every time. + */ + rio_dprintk(RIO_DEBUG_BOOT, "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n", HostP->Type, HostP->Mode, HostP->Ivec); + + rio_start_card_running(HostP); + + rio_dprintk(RIO_DEBUG_BOOT, "Set control port\n"); + + /* + ** Now, wait for upto five seconds for the Tp to setup the parmmap + ** pointer: + */ + for (wait_count = 0; (wait_count < p->RIOConf.StartupTime) && (readw(&HostP->__ParmMapR) == OldParmMap); wait_count++) { + rio_dprintk(RIO_DEBUG_BOOT, "Checkout %d, 0x%x\n", wait_count, readw(&HostP->__ParmMapR)); + mdelay(100); + + } + + /* + ** If the parmmap pointer is unchanged, then the host code + ** has crashed & burned in a really spectacular way + */ + if (readw(&HostP->__ParmMapR) == OldParmMap) { + rio_dprintk(RIO_DEBUG_BOOT, "parmmap 0x%x\n", readw(&HostP->__ParmMapR)); + rio_dprintk(RIO_DEBUG_BOOT, "RIO Mesg Run Fail\n"); + HostP->Flags &= ~RUN_STATE; + HostP->Flags |= RC_STUFFED; + RIOHostReset( HostP->Type, HostP->CardP, HostP->Slot ); + continue; + } + + rio_dprintk(RIO_DEBUG_BOOT, "Running 0x%x\n", readw(&HostP->__ParmMapR)); + + /* + ** Well, the board thought it was OK, and setup its parmmap + ** pointer. For the time being, we will pretend that this + ** board is running, and check out what the error flag says. + */ + + /* + ** Grab a 32 bit pointer to the parmmap structure + */ + ParmMapP = (PARM_MAP __iomem *) RIO_PTR(Cad, readw(&HostP->__ParmMapR)); + rio_dprintk(RIO_DEBUG_BOOT, "ParmMapP : %p\n", ParmMapP); + ParmMapP = (PARM_MAP __iomem *)(Cad + readw(&HostP->__ParmMapR)); + rio_dprintk(RIO_DEBUG_BOOT, "ParmMapP : %p\n", ParmMapP); + + /* + ** The links entry should be 0xFFFF; we set it up + ** with a mask to say how many PHBs to use, and + ** which links to use. + */ + if (readw(&ParmMapP->links) != 0xFFFF) { + rio_dprintk(RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name); + rio_dprintk(RIO_DEBUG_BOOT, "Links = 0x%x\n", readw(&ParmMapP->links)); + HostP->Flags &= ~RUN_STATE; + HostP->Flags |= RC_STUFFED; + RIOHostReset( HostP->Type, HostP->CardP, HostP->Slot ); + continue; + } + + writew(RIO_LINK_ENABLE, &ParmMapP->links); + + /* + ** now wait for the card to set all the parmmap->XXX stuff + ** this is a wait of upto two seconds.... + */ + rio_dprintk(RIO_DEBUG_BOOT, "Looking for init_done - %d ticks\n", p->RIOConf.StartupTime); + HostP->timeout_id = 0; + for (wait_count = 0; (wait_count < p->RIOConf.StartupTime) && !readw(&ParmMapP->init_done); wait_count++) { + rio_dprintk(RIO_DEBUG_BOOT, "Waiting for init_done\n"); + mdelay(100); + } + rio_dprintk(RIO_DEBUG_BOOT, "OK! init_done!\n"); + + if (readw(&ParmMapP->error) != E_NO_ERROR || !readw(&ParmMapP->init_done)) { + rio_dprintk(RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name); + rio_dprintk(RIO_DEBUG_BOOT, "Timedout waiting for init_done\n"); + HostP->Flags &= ~RUN_STATE; + HostP->Flags |= RC_STUFFED; + RIOHostReset( HostP->Type, HostP->CardP, HostP->Slot ); + continue; + } + + rio_dprintk(RIO_DEBUG_BOOT, "Got init_done\n"); + + /* + ** It runs! It runs! + */ + rio_dprintk(RIO_DEBUG_BOOT, "Host ID %x Running\n", HostP->UniqueNum); + + /* + ** set the time period between interrupts. + */ + writew(p->RIOConf.Timer, &ParmMapP->timer); + + /* + ** Translate all the 16 bit pointers in the __ParmMapR into + ** 32 bit pointers for the driver in ioremap space. + */ + HostP->ParmMapP = ParmMapP; + HostP->PhbP = (struct PHB __iomem *) RIO_PTR(Cad, readw(&ParmMapP->phb_ptr)); + HostP->RupP = (struct RUP __iomem *) RIO_PTR(Cad, readw(&ParmMapP->rups)); + HostP->PhbNumP = (unsigned short __iomem *) RIO_PTR(Cad, readw(&ParmMapP->phb_num_ptr)); + HostP->LinkStrP = (struct LPB __iomem *) RIO_PTR(Cad, readw(&ParmMapP->link_str_ptr)); + + /* + ** point the UnixRups at the real Rups + */ + for (RupN = 0; RupN < MAX_RUP; RupN++) { + HostP->UnixRups[RupN].RupP = &HostP->RupP[RupN]; + HostP->UnixRups[RupN].Id = RupN + 1; + HostP->UnixRups[RupN].BaseSysPort = NO_PORT; + spin_lock_init(&HostP->UnixRups[RupN].RupLock); + } + + for (RupN = 0; RupN < LINKS_PER_UNIT; RupN++) { + HostP->UnixRups[RupN + MAX_RUP].RupP = &HostP->LinkStrP[RupN].rup; + HostP->UnixRups[RupN + MAX_RUP].Id = 0; + HostP->UnixRups[RupN + MAX_RUP].BaseSysPort = NO_PORT; + spin_lock_init(&HostP->UnixRups[RupN + MAX_RUP].RupLock); + } + + /* + ** point the PortP->Phbs at the real Phbs + */ + for (PortN = p->RIOFirstPortsMapped; PortN < p->RIOLastPortsMapped + PORTS_PER_RTA; PortN++) { + if (p->RIOPortp[PortN]->HostP == HostP) { + struct Port *PortP = p->RIOPortp[PortN]; + struct PHB __iomem *PhbP; + /* int oldspl; */ + + if (!PortP->Mapped) + continue; + + PhbP = &HostP->PhbP[PortP->HostPort]; + rio_spin_lock_irqsave(&PortP->portSem, flags); + + PortP->PhbP = PhbP; + + PortP->TxAdd = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->tx_add)); + PortP->TxStart = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->tx_start)); + PortP->TxEnd = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->tx_end)); + PortP->RxRemove = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->rx_remove)); + PortP->RxStart = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->rx_start)); + PortP->RxEnd = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->rx_end)); + + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + /* + ** point the UnixRup at the base SysPort + */ + if (!(PortN % PORTS_PER_RTA)) + HostP->UnixRups[PortP->RupNum].BaseSysPort = PortN; + } + } + + rio_dprintk(RIO_DEBUG_BOOT, "Set the card running... \n"); + /* + ** last thing - show the world that everything is in place + */ + HostP->Flags &= ~RUN_STATE; + HostP->Flags |= RC_RUNNING; + } + /* + ** MPX always uses a poller. This is actually patched into the system + ** configuration and called directly from each clock tick. + ** + */ + p->RIOPolling = 1; + + p->RIOSystemUp++; + + rio_dprintk(RIO_DEBUG_BOOT, "Done everything %x\n", HostP->Ivec); + func_exit(); + return 0; +} + + + +/** + * RIOBootRup - Boot an RTA + * @p: rio we are working with + * @Rup: Rup number + * @HostP: host object + * @PacketP: packet to use + * + * If we have successfully processed this boot, then + * return 1. If we havent, then return 0. + */ + +int RIOBootRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct PKT __iomem *PacketP) +{ + struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *) PacketP->data; + struct PktCmd_M *PktReplyP; + struct CmdBlk *CmdBlkP; + unsigned int sequence; + + /* + ** If we haven't been told what to boot, we can't boot it. + */ + if (p->RIONumBootPkts == 0) { + rio_dprintk(RIO_DEBUG_BOOT, "No RTA code to download yet\n"); + return 0; + } + + /* + ** Special case of boot completed - if we get one of these then we + ** don't need a command block. For all other cases we do, so handle + ** this first and then get a command block, then handle every other + ** case, relinquishing the command block if disaster strikes! + */ + if ((readb(&PacketP->len) & PKT_CMD_BIT) && (readb(&PktCmdP->Command) == BOOT_COMPLETED)) + return RIOBootComplete(p, HostP, Rup, PktCmdP); + + /* + ** Try to allocate a command block. This is in kernel space + */ + if (!(CmdBlkP = RIOGetCmdBlk())) { + rio_dprintk(RIO_DEBUG_BOOT, "No command blocks to boot RTA! come back later.\n"); + return 0; + } + + /* + ** Fill in the default info on the command block + */ + CmdBlkP->Packet.dest_unit = Rup < (unsigned short) MAX_RUP ? Rup : 0; + CmdBlkP->Packet.dest_port = BOOT_RUP; + CmdBlkP->Packet.src_unit = 0; + CmdBlkP->Packet.src_port = BOOT_RUP; + + CmdBlkP->PreFuncP = CmdBlkP->PostFuncP = NULL; + PktReplyP = (struct PktCmd_M *) CmdBlkP->Packet.data; + + /* + ** process COMMANDS on the boot rup! + */ + if (readb(&PacketP->len) & PKT_CMD_BIT) { + /* + ** We only expect one type of command - a BOOT_REQUEST! + */ + if (readb(&PktCmdP->Command) != BOOT_REQUEST) { + rio_dprintk(RIO_DEBUG_BOOT, "Unexpected command %d on BOOT RUP %d of host %Zd\n", readb(&PktCmdP->Command), Rup, HostP - p->RIOHosts); + RIOFreeCmdBlk(CmdBlkP); + return 1; + } + + /* + ** Build a Boot Sequence command block + ** + ** We no longer need to use "Boot Mode", we'll always allow + ** boot requests - the boot will not complete if the device + ** appears in the bindings table. + ** + ** We'll just (always) set the command field in packet reply + ** to allow an attempted boot sequence : + */ + PktReplyP->Command = BOOT_SEQUENCE; + + PktReplyP->BootSequence.NumPackets = p->RIONumBootPkts; + PktReplyP->BootSequence.LoadBase = p->RIOConf.RtaLoadBase; + PktReplyP->BootSequence.CodeSize = p->RIOBootCount; + + CmdBlkP->Packet.len = BOOT_SEQUENCE_LEN | PKT_CMD_BIT; + + memcpy((void *) &CmdBlkP->Packet.data[BOOT_SEQUENCE_LEN], "BOOT", 4); + + rio_dprintk(RIO_DEBUG_BOOT, "Boot RTA on Host %Zd Rup %d - %d (0x%x) packets to 0x%x\n", HostP - p->RIOHosts, Rup, p->RIONumBootPkts, p->RIONumBootPkts, p->RIOConf.RtaLoadBase); + + /* + ** If this host is in slave mode, send the RTA an invalid boot + ** sequence command block to force it to kill the boot. We wait + ** for half a second before sending this packet to prevent the RTA + ** attempting to boot too often. The master host should then grab + ** the RTA and make it its own. + */ + p->RIOBooting++; + RIOQueueCmdBlk(HostP, Rup, CmdBlkP); + return 1; + } + + /* + ** It is a request for boot data. + */ + sequence = readw(&PktCmdP->Sequence); + + rio_dprintk(RIO_DEBUG_BOOT, "Boot block %d on Host %Zd Rup%d\n", sequence, HostP - p->RIOHosts, Rup); + + if (sequence >= p->RIONumBootPkts) { + rio_dprintk(RIO_DEBUG_BOOT, "Got a request for packet %d, max is %d\n", sequence, p->RIONumBootPkts); + } + + PktReplyP->Sequence = sequence; + memcpy(PktReplyP->BootData, p->RIOBootPackets[p->RIONumBootPkts - sequence - 1], RTA_BOOT_DATA_SIZE); + CmdBlkP->Packet.len = PKT_MAX_DATA_LEN; + RIOQueueCmdBlk(HostP, Rup, CmdBlkP); + return 1; +} + +/** + * RIOBootComplete - RTA boot is done + * @p: RIO we are working with + * @HostP: Host structure + * @Rup: RUP being used + * @PktCmdP: Packet command that was used + * + * This function is called when an RTA been booted. + * If booted by a host, HostP->HostUniqueNum is the booting host. + * If booted by an RTA, HostP->Mapping[Rup].RtaUniqueNum is the booting RTA. + * RtaUniq is the booted RTA. + */ + +static int RIOBootComplete(struct rio_info *p, struct Host *HostP, unsigned int Rup, struct PktCmd __iomem *PktCmdP) +{ + struct Map *MapP = NULL; + struct Map *MapP2 = NULL; + int Flag; + int found; + int host, rta; + int EmptySlot = -1; + int entry, entry2; + char *MyType, *MyName; + unsigned int MyLink; + unsigned short RtaType; + u32 RtaUniq = (readb(&PktCmdP->UniqNum[0])) + (readb(&PktCmdP->UniqNum[1]) << 8) + (readb(&PktCmdP->UniqNum[2]) << 16) + (readb(&PktCmdP->UniqNum[3]) << 24); + + p->RIOBooting = 0; + + rio_dprintk(RIO_DEBUG_BOOT, "RTA Boot completed - BootInProgress now %d\n", p->RIOBooting); + + /* + ** Determine type of unit (16/8 port RTA). + */ + + RtaType = GetUnitType(RtaUniq); + if (Rup >= (unsigned short) MAX_RUP) + rio_dprintk(RIO_DEBUG_BOOT, "RIO: Host %s has booted an RTA(%d) on link %c\n", HostP->Name, 8 * RtaType, readb(&PktCmdP->LinkNum) + 'A'); + else + rio_dprintk(RIO_DEBUG_BOOT, "RIO: RTA %s has booted an RTA(%d) on link %c\n", HostP->Mapping[Rup].Name, 8 * RtaType, readb(&PktCmdP->LinkNum) + 'A'); + + rio_dprintk(RIO_DEBUG_BOOT, "UniqNum is 0x%x\n", RtaUniq); + + if (RtaUniq == 0x00000000 || RtaUniq == 0xffffffff) { + rio_dprintk(RIO_DEBUG_BOOT, "Illegal RTA Uniq Number\n"); + return 1; + } + + /* + ** If this RTA has just booted an RTA which doesn't belong to this + ** system, or the system is in slave mode, do not attempt to create + ** a new table entry for it. + */ + + if (!RIOBootOk(p, HostP, RtaUniq)) { + MyLink = readb(&PktCmdP->LinkNum); + if (Rup < (unsigned short) MAX_RUP) { + /* + ** RtaUniq was clone booted (by this RTA). Instruct this RTA + ** to hold off further attempts to boot on this link for 30 + ** seconds. + */ + if (RIOSuspendBootRta(HostP, HostP->Mapping[Rup].ID, MyLink)) { + rio_dprintk(RIO_DEBUG_BOOT, "RTA failed to suspend booting on link %c\n", 'A' + MyLink); + } + } else + /* + ** RtaUniq was booted by this host. Set the booting link + ** to hold off for 30 seconds to give another unit a + ** chance to boot it. + */ + writew(30, &HostP->LinkStrP[MyLink].WaitNoBoot); + rio_dprintk(RIO_DEBUG_BOOT, "RTA %x not owned - suspend booting down link %c on unit %x\n", RtaUniq, 'A' + MyLink, HostP->Mapping[Rup].RtaUniqueNum); + return 1; + } + + /* + ** Check for a SLOT_IN_USE entry for this RTA attached to the + ** current host card in the driver table. + ** + ** If it exists, make a note that we have booted it. Other parts of + ** the driver are interested in this information at a later date, + ** in particular when the booting RTA asks for an ID for this unit, + ** we must have set the BOOTED flag, and the NEWBOOT flag is used + ** to force an open on any ports that where previously open on this + ** unit. + */ + for (entry = 0; entry < MAX_RUP; entry++) { + unsigned int sysport; + + if ((HostP->Mapping[entry].Flags & SLOT_IN_USE) && (HostP->Mapping[entry].RtaUniqueNum == RtaUniq)) { + HostP->Mapping[entry].Flags |= RTA_BOOTED | RTA_NEWBOOT; + if ((sysport = HostP->Mapping[entry].SysPort) != NO_PORT) { + if (sysport < p->RIOFirstPortsBooted) + p->RIOFirstPortsBooted = sysport; + if (sysport > p->RIOLastPortsBooted) + p->RIOLastPortsBooted = sysport; + /* + ** For a 16 port RTA, check the second bank of 8 ports + */ + if (RtaType == TYPE_RTA16) { + entry2 = HostP->Mapping[entry].ID2 - 1; + HostP->Mapping[entry2].Flags |= RTA_BOOTED | RTA_NEWBOOT; + sysport = HostP->Mapping[entry2].SysPort; + if (sysport < p->RIOFirstPortsBooted) + p->RIOFirstPortsBooted = sysport; + if (sysport > p->RIOLastPortsBooted) + p->RIOLastPortsBooted = sysport; + } + } + if (RtaType == TYPE_RTA16) + rio_dprintk(RIO_DEBUG_BOOT, "RTA will be given IDs %d+%d\n", entry + 1, entry2 + 1); + else + rio_dprintk(RIO_DEBUG_BOOT, "RTA will be given ID %d\n", entry + 1); + return 1; + } + } + + rio_dprintk(RIO_DEBUG_BOOT, "RTA not configured for this host\n"); + + if (Rup >= (unsigned short) MAX_RUP) { + /* + ** It was a host that did the booting + */ + MyType = "Host"; + MyName = HostP->Name; + } else { + /* + ** It was an RTA that did the booting + */ + MyType = "RTA"; + MyName = HostP->Mapping[Rup].Name; + } + MyLink = readb(&PktCmdP->LinkNum); + + /* + ** There is no SLOT_IN_USE entry for this RTA attached to the current + ** host card in the driver table. + ** + ** Check for a SLOT_TENTATIVE entry for this RTA attached to the + ** current host card in the driver table. + ** + ** If we find one, then we re-use that slot. + */ + for (entry = 0; entry < MAX_RUP; entry++) { + if ((HostP->Mapping[entry].Flags & SLOT_TENTATIVE) && (HostP->Mapping[entry].RtaUniqueNum == RtaUniq)) { + if (RtaType == TYPE_RTA16) { + entry2 = HostP->Mapping[entry].ID2 - 1; + if ((HostP->Mapping[entry2].Flags & SLOT_TENTATIVE) && (HostP->Mapping[entry2].RtaUniqueNum == RtaUniq)) + rio_dprintk(RIO_DEBUG_BOOT, "Found previous tentative slots (%d+%d)\n", entry, entry2); + else + continue; + } else + rio_dprintk(RIO_DEBUG_BOOT, "Found previous tentative slot (%d)\n", entry); + if (!p->RIONoMessage) + printk("RTA connected to %s '%s' (%c) not configured.\n", MyType, MyName, MyLink + 'A'); + return 1; + } + } + + /* + ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA + ** attached to the current host card in the driver table. + ** + ** Check if there is a SLOT_IN_USE or SLOT_TENTATIVE entry on another + ** host for this RTA in the driver table. + ** + ** For a SLOT_IN_USE entry on another host, we need to delete the RTA + ** entry from the other host and add it to this host (using some of + ** the functions from table.c which do this). + ** For a SLOT_TENTATIVE entry on another host, we must cope with the + ** following scenario: + ** + ** + Plug 8 port RTA into host A. (This creates SLOT_TENTATIVE entry + ** in table) + ** + Unplug RTA and plug into host B. (We now have 2 SLOT_TENTATIVE + ** entries) + ** + Configure RTA on host B. (This slot now becomes SLOT_IN_USE) + ** + Unplug RTA and plug back into host A. + ** + Configure RTA on host A. We now have the same RTA configured + ** with different ports on two different hosts. + */ + rio_dprintk(RIO_DEBUG_BOOT, "Have we seen RTA %x before?\n", RtaUniq); + found = 0; + Flag = 0; /* Convince the compiler this variable is initialized */ + for (host = 0; !found && (host < p->RIONumHosts); host++) { + for (rta = 0; rta < MAX_RUP; rta++) { + if ((p->RIOHosts[host].Mapping[rta].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) && (p->RIOHosts[host].Mapping[rta].RtaUniqueNum == RtaUniq)) { + Flag = p->RIOHosts[host].Mapping[rta].Flags; + MapP = &p->RIOHosts[host].Mapping[rta]; + if (RtaType == TYPE_RTA16) { + MapP2 = &p->RIOHosts[host].Mapping[MapP->ID2 - 1]; + rio_dprintk(RIO_DEBUG_BOOT, "This RTA is units %d+%d from host %s\n", rta + 1, MapP->ID2, p->RIOHosts[host].Name); + } else + rio_dprintk(RIO_DEBUG_BOOT, "This RTA is unit %d from host %s\n", rta + 1, p->RIOHosts[host].Name); + found = 1; + break; + } + } + } + + /* + ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA + ** attached to the current host card in the driver table. + ** + ** If we have not found a SLOT_IN_USE or SLOT_TENTATIVE entry on + ** another host for this RTA in the driver table... + ** + ** Check for a SLOT_IN_USE entry for this RTA in the config table. + */ + if (!MapP) { + rio_dprintk(RIO_DEBUG_BOOT, "Look for RTA %x in RIOSavedTable\n", RtaUniq); + for (rta = 0; rta < TOTAL_MAP_ENTRIES; rta++) { + rio_dprintk(RIO_DEBUG_BOOT, "Check table entry %d (%x)", rta, p->RIOSavedTable[rta].RtaUniqueNum); + + if ((p->RIOSavedTable[rta].Flags & SLOT_IN_USE) && (p->RIOSavedTable[rta].RtaUniqueNum == RtaUniq)) { + MapP = &p->RIOSavedTable[rta]; + Flag = p->RIOSavedTable[rta].Flags; + if (RtaType == TYPE_RTA16) { + for (entry2 = rta + 1; entry2 < TOTAL_MAP_ENTRIES; entry2++) { + if (p->RIOSavedTable[entry2].RtaUniqueNum == RtaUniq) + break; + } + MapP2 = &p->RIOSavedTable[entry2]; + rio_dprintk(RIO_DEBUG_BOOT, "This RTA is from table entries %d+%d\n", rta, entry2); + } else + rio_dprintk(RIO_DEBUG_BOOT, "This RTA is from table entry %d\n", rta); + break; + } + } + } + + /* + ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA + ** attached to the current host card in the driver table. + ** + ** We may have found a SLOT_IN_USE entry on another host for this + ** RTA in the config table, or a SLOT_IN_USE or SLOT_TENTATIVE entry + ** on another host for this RTA in the driver table. + ** + ** Check the driver table for room to fit this newly discovered RTA. + ** RIOFindFreeID() first looks for free slots and if it does not + ** find any free slots it will then attempt to oust any + ** tentative entry in the table. + */ + EmptySlot = 1; + if (RtaType == TYPE_RTA16) { + if (RIOFindFreeID(p, HostP, &entry, &entry2) == 0) { + RIODefaultName(p, HostP, entry); + rio_fill_host_slot(entry, entry2, RtaUniq, HostP); + EmptySlot = 0; + } + } else { + if (RIOFindFreeID(p, HostP, &entry, NULL) == 0) { + RIODefaultName(p, HostP, entry); + rio_fill_host_slot(entry, 0, RtaUniq, HostP); + EmptySlot = 0; + } + } + + /* + ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA + ** attached to the current host card in the driver table. + ** + ** If we found a SLOT_IN_USE entry on another host for this + ** RTA in the config or driver table, and there are enough free + ** slots in the driver table, then we need to move it over and + ** delete it from the other host. + ** If we found a SLOT_TENTATIVE entry on another host for this + ** RTA in the driver table, just delete the other host entry. + */ + if (EmptySlot == 0) { + if (MapP) { + if (Flag & SLOT_IN_USE) { + rio_dprintk(RIO_DEBUG_BOOT, "This RTA configured on another host - move entry to current host (1)\n"); + HostP->Mapping[entry].SysPort = MapP->SysPort; + memcpy(HostP->Mapping[entry].Name, MapP->Name, MAX_NAME_LEN); + HostP->Mapping[entry].Flags = SLOT_IN_USE | RTA_BOOTED | RTA_NEWBOOT; + RIOReMapPorts(p, HostP, &HostP->Mapping[entry]); + if (HostP->Mapping[entry].SysPort < p->RIOFirstPortsBooted) + p->RIOFirstPortsBooted = HostP->Mapping[entry].SysPort; + if (HostP->Mapping[entry].SysPort > p->RIOLastPortsBooted) + p->RIOLastPortsBooted = HostP->Mapping[entry].SysPort; + rio_dprintk(RIO_DEBUG_BOOT, "SysPort %d, Name %s\n", (int) MapP->SysPort, MapP->Name); + } else { + rio_dprintk(RIO_DEBUG_BOOT, "This RTA has a tentative entry on another host - delete that entry (1)\n"); + HostP->Mapping[entry].Flags = SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT; + } + if (RtaType == TYPE_RTA16) { + if (Flag & SLOT_IN_USE) { + HostP->Mapping[entry2].Flags = SLOT_IN_USE | RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT; + HostP->Mapping[entry2].SysPort = MapP2->SysPort; + /* + ** Map second block of ttys for 16 port RTA + */ + RIOReMapPorts(p, HostP, &HostP->Mapping[entry2]); + if (HostP->Mapping[entry2].SysPort < p->RIOFirstPortsBooted) + p->RIOFirstPortsBooted = HostP->Mapping[entry2].SysPort; + if (HostP->Mapping[entry2].SysPort > p->RIOLastPortsBooted) + p->RIOLastPortsBooted = HostP->Mapping[entry2].SysPort; + rio_dprintk(RIO_DEBUG_BOOT, "SysPort %d, Name %s\n", (int) HostP->Mapping[entry2].SysPort, HostP->Mapping[entry].Name); + } else + HostP->Mapping[entry2].Flags = SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT; + memset(MapP2, 0, sizeof(struct Map)); + } + memset(MapP, 0, sizeof(struct Map)); + if (!p->RIONoMessage) + printk("An orphaned RTA has been adopted by %s '%s' (%c).\n", MyType, MyName, MyLink + 'A'); + } else if (!p->RIONoMessage) + printk("RTA connected to %s '%s' (%c) not configured.\n", MyType, MyName, MyLink + 'A'); + RIOSetChange(p); + return 1; + } + + /* + ** There is no room in the driver table to make an entry for the + ** booted RTA. Keep a note of its Uniq Num in the overflow table, + ** so we can ignore it's ID requests. + */ + if (!p->RIONoMessage) + printk("The RTA connected to %s '%s' (%c) cannot be configured. You cannot configure more than 128 ports to one host card.\n", MyType, MyName, MyLink + 'A'); + for (entry = 0; entry < HostP->NumExtraBooted; entry++) { + if (HostP->ExtraUnits[entry] == RtaUniq) { + /* + ** already got it! + */ + return 1; + } + } + /* + ** If there is room, add the unit to the list of extras + */ + if (HostP->NumExtraBooted < MAX_EXTRA_UNITS) + HostP->ExtraUnits[HostP->NumExtraBooted++] = RtaUniq; + return 1; +} + + +/* +** If the RTA or its host appears in the RIOBindTab[] structure then +** we mustn't boot the RTA and should return 0. +** This operation is slightly different from the other drivers for RIO +** in that this is designed to work with the new utilities +** not config.rio and is FAR SIMPLER. +** We no longer support the RIOBootMode variable. It is all done from the +** "boot/noboot" field in the rio.cf file. +*/ +int RIOBootOk(struct rio_info *p, struct Host *HostP, unsigned long RtaUniq) +{ + int Entry; + unsigned int HostUniq = HostP->UniqueNum; + + /* + ** Search bindings table for RTA or its parent. + ** If it exists, return 0, else 1. + */ + for (Entry = 0; (Entry < MAX_RTA_BINDINGS) && (p->RIOBindTab[Entry] != 0); Entry++) { + if ((p->RIOBindTab[Entry] == HostUniq) || (p->RIOBindTab[Entry] == RtaUniq)) + return 0; + } + return 1; +} + +/* +** Make an empty slot tentative. If this is a 16 port RTA, make both +** slots tentative, and the second one RTA_SECOND_SLOT as well. +*/ + +void rio_fill_host_slot(int entry, int entry2, unsigned int rta_uniq, struct Host *host) +{ + int link; + + rio_dprintk(RIO_DEBUG_BOOT, "rio_fill_host_slot(%d, %d, 0x%x...)\n", entry, entry2, rta_uniq); + + host->Mapping[entry].Flags = (RTA_BOOTED | RTA_NEWBOOT | SLOT_TENTATIVE); + host->Mapping[entry].SysPort = NO_PORT; + host->Mapping[entry].RtaUniqueNum = rta_uniq; + host->Mapping[entry].HostUniqueNum = host->UniqueNum; + host->Mapping[entry].ID = entry + 1; + host->Mapping[entry].ID2 = 0; + if (entry2) { + host->Mapping[entry2].Flags = (RTA_BOOTED | RTA_NEWBOOT | SLOT_TENTATIVE | RTA16_SECOND_SLOT); + host->Mapping[entry2].SysPort = NO_PORT; + host->Mapping[entry2].RtaUniqueNum = rta_uniq; + host->Mapping[entry2].HostUniqueNum = host->UniqueNum; + host->Mapping[entry2].Name[0] = '\0'; + host->Mapping[entry2].ID = entry2 + 1; + host->Mapping[entry2].ID2 = entry + 1; + host->Mapping[entry].ID2 = entry2 + 1; + } + /* + ** Must set these up, so that utilities show + ** topology of 16 port RTAs correctly + */ + for (link = 0; link < LINKS_PER_UNIT; link++) { + host->Mapping[entry].Topology[link].Unit = ROUTE_DISCONNECT; + host->Mapping[entry].Topology[link].Link = NO_LINK; + if (entry2) { + host->Mapping[entry2].Topology[link].Unit = ROUTE_DISCONNECT; + host->Mapping[entry2].Topology[link].Link = NO_LINK; + } + } +} diff --git a/drivers/staging/generic_serial/rio/riocmd.c b/drivers/staging/generic_serial/rio/riocmd.c new file mode 100644 index 000000000000..f121357e5af0 --- /dev/null +++ b/drivers/staging/generic_serial/rio/riocmd.c @@ -0,0 +1,939 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** ported from the existing SCO driver source +** + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : riocmd.c +** SID : 1.2 +** Last Modified : 11/6/98 10:33:41 +** Retrieved : 11/6/98 10:33:49 +** +** ident @(#)riocmd.c 1.2 +** +** ----------------------------------------------------------------------------- +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "linux_compat.h" +#include "rio_linux.h" +#include "pkt.h" +#include "daemon.h" +#include "rio.h" +#include "riospace.h" +#include "cmdpkt.h" +#include "map.h" +#include "rup.h" +#include "port.h" +#include "riodrvr.h" +#include "rioinfo.h" +#include "func.h" +#include "errors.h" +#include "pci.h" + +#include "parmmap.h" +#include "unixrup.h" +#include "board.h" +#include "host.h" +#include "phb.h" +#include "link.h" +#include "cmdblk.h" +#include "route.h" +#include "cirrus.h" + + +static struct IdentifyRta IdRta; +static struct KillNeighbour KillUnit; + +int RIOFoadRta(struct Host *HostP, struct Map *MapP) +{ + struct CmdBlk *CmdBlkP; + + rio_dprintk(RIO_DEBUG_CMD, "FOAD RTA\n"); + + CmdBlkP = RIOGetCmdBlk(); + + if (!CmdBlkP) { + rio_dprintk(RIO_DEBUG_CMD, "FOAD RTA: GetCmdBlk failed\n"); + return -ENXIO; + } + + CmdBlkP->Packet.dest_unit = MapP->ID; + CmdBlkP->Packet.dest_port = BOOT_RUP; + CmdBlkP->Packet.src_unit = 0; + CmdBlkP->Packet.src_port = BOOT_RUP; + CmdBlkP->Packet.len = 0x84; + CmdBlkP->Packet.data[0] = IFOAD; + CmdBlkP->Packet.data[1] = 0; + CmdBlkP->Packet.data[2] = IFOAD_MAGIC & 0xFF; + CmdBlkP->Packet.data[3] = (IFOAD_MAGIC >> 8) & 0xFF; + + if (RIOQueueCmdBlk(HostP, MapP->ID - 1, CmdBlkP) == RIO_FAIL) { + rio_dprintk(RIO_DEBUG_CMD, "FOAD RTA: Failed to queue foad command\n"); + return -EIO; + } + return 0; +} + +int RIOZombieRta(struct Host *HostP, struct Map *MapP) +{ + struct CmdBlk *CmdBlkP; + + rio_dprintk(RIO_DEBUG_CMD, "ZOMBIE RTA\n"); + + CmdBlkP = RIOGetCmdBlk(); + + if (!CmdBlkP) { + rio_dprintk(RIO_DEBUG_CMD, "ZOMBIE RTA: GetCmdBlk failed\n"); + return -ENXIO; + } + + CmdBlkP->Packet.dest_unit = MapP->ID; + CmdBlkP->Packet.dest_port = BOOT_RUP; + CmdBlkP->Packet.src_unit = 0; + CmdBlkP->Packet.src_port = BOOT_RUP; + CmdBlkP->Packet.len = 0x84; + CmdBlkP->Packet.data[0] = ZOMBIE; + CmdBlkP->Packet.data[1] = 0; + CmdBlkP->Packet.data[2] = ZOMBIE_MAGIC & 0xFF; + CmdBlkP->Packet.data[3] = (ZOMBIE_MAGIC >> 8) & 0xFF; + + if (RIOQueueCmdBlk(HostP, MapP->ID - 1, CmdBlkP) == RIO_FAIL) { + rio_dprintk(RIO_DEBUG_CMD, "ZOMBIE RTA: Failed to queue zombie command\n"); + return -EIO; + } + return 0; +} + +int RIOCommandRta(struct rio_info *p, unsigned long RtaUnique, int (*func) (struct Host * HostP, struct Map * MapP)) +{ + unsigned int Host; + + rio_dprintk(RIO_DEBUG_CMD, "Command RTA 0x%lx func %p\n", RtaUnique, func); + + if (!RtaUnique) + return (0); + + for (Host = 0; Host < p->RIONumHosts; Host++) { + unsigned int Rta; + struct Host *HostP = &p->RIOHosts[Host]; + + for (Rta = 0; Rta < RTAS_PER_HOST; Rta++) { + struct Map *MapP = &HostP->Mapping[Rta]; + + if (MapP->RtaUniqueNum == RtaUnique) { + uint Link; + + /* + ** now, lets just check we have a route to it... + ** IF the routing stuff is working, then one of the + ** topology entries for this unit will have a legit + ** route *somewhere*. We care not where - if its got + ** any connections, we can get to it. + */ + for (Link = 0; Link < LINKS_PER_UNIT; Link++) { + if (MapP->Topology[Link].Unit <= (u8) MAX_RUP) { + /* + ** Its worth trying the operation... + */ + return (*func) (HostP, MapP); + } + } + } + } + } + return -ENXIO; +} + + +int RIOIdentifyRta(struct rio_info *p, void __user * arg) +{ + unsigned int Host; + + if (copy_from_user(&IdRta, arg, sizeof(IdRta))) { + rio_dprintk(RIO_DEBUG_CMD, "RIO_IDENTIFY_RTA copy failed\n"); + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + + for (Host = 0; Host < p->RIONumHosts; Host++) { + unsigned int Rta; + struct Host *HostP = &p->RIOHosts[Host]; + + for (Rta = 0; Rta < RTAS_PER_HOST; Rta++) { + struct Map *MapP = &HostP->Mapping[Rta]; + + if (MapP->RtaUniqueNum == IdRta.RtaUnique) { + uint Link; + /* + ** now, lets just check we have a route to it... + ** IF the routing stuff is working, then one of the + ** topology entries for this unit will have a legit + ** route *somewhere*. We care not where - if its got + ** any connections, we can get to it. + */ + for (Link = 0; Link < LINKS_PER_UNIT; Link++) { + if (MapP->Topology[Link].Unit <= (u8) MAX_RUP) { + /* + ** Its worth trying the operation... + */ + struct CmdBlk *CmdBlkP; + + rio_dprintk(RIO_DEBUG_CMD, "IDENTIFY RTA\n"); + + CmdBlkP = RIOGetCmdBlk(); + + if (!CmdBlkP) { + rio_dprintk(RIO_DEBUG_CMD, "IDENTIFY RTA: GetCmdBlk failed\n"); + return -ENXIO; + } + + CmdBlkP->Packet.dest_unit = MapP->ID; + CmdBlkP->Packet.dest_port = BOOT_RUP; + CmdBlkP->Packet.src_unit = 0; + CmdBlkP->Packet.src_port = BOOT_RUP; + CmdBlkP->Packet.len = 0x84; + CmdBlkP->Packet.data[0] = IDENTIFY; + CmdBlkP->Packet.data[1] = 0; + CmdBlkP->Packet.data[2] = IdRta.ID; + + if (RIOQueueCmdBlk(HostP, MapP->ID - 1, CmdBlkP) == RIO_FAIL) { + rio_dprintk(RIO_DEBUG_CMD, "IDENTIFY RTA: Failed to queue command\n"); + return -EIO; + } + return 0; + } + } + } + } + } + return -ENOENT; +} + + +int RIOKillNeighbour(struct rio_info *p, void __user * arg) +{ + uint Host; + uint ID; + struct Host *HostP; + struct CmdBlk *CmdBlkP; + + rio_dprintk(RIO_DEBUG_CMD, "KILL HOST NEIGHBOUR\n"); + + if (copy_from_user(&KillUnit, arg, sizeof(KillUnit))) { + rio_dprintk(RIO_DEBUG_CMD, "RIO_KILL_NEIGHBOUR copy failed\n"); + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + + if (KillUnit.Link > 3) + return -ENXIO; + + CmdBlkP = RIOGetCmdBlk(); + + if (!CmdBlkP) { + rio_dprintk(RIO_DEBUG_CMD, "UFOAD: GetCmdBlk failed\n"); + return -ENXIO; + } + + CmdBlkP->Packet.dest_unit = 0; + CmdBlkP->Packet.src_unit = 0; + CmdBlkP->Packet.dest_port = BOOT_RUP; + CmdBlkP->Packet.src_port = BOOT_RUP; + CmdBlkP->Packet.len = 0x84; + CmdBlkP->Packet.data[0] = UFOAD; + CmdBlkP->Packet.data[1] = KillUnit.Link; + CmdBlkP->Packet.data[2] = UFOAD_MAGIC & 0xFF; + CmdBlkP->Packet.data[3] = (UFOAD_MAGIC >> 8) & 0xFF; + + for (Host = 0; Host < p->RIONumHosts; Host++) { + ID = 0; + HostP = &p->RIOHosts[Host]; + + if (HostP->UniqueNum == KillUnit.UniqueNum) { + if (RIOQueueCmdBlk(HostP, RTAS_PER_HOST + KillUnit.Link, CmdBlkP) == RIO_FAIL) { + rio_dprintk(RIO_DEBUG_CMD, "UFOAD: Failed queue command\n"); + return -EIO; + } + return 0; + } + + for (ID = 0; ID < RTAS_PER_HOST; ID++) { + if (HostP->Mapping[ID].RtaUniqueNum == KillUnit.UniqueNum) { + CmdBlkP->Packet.dest_unit = ID + 1; + if (RIOQueueCmdBlk(HostP, ID, CmdBlkP) == RIO_FAIL) { + rio_dprintk(RIO_DEBUG_CMD, "UFOAD: Failed queue command\n"); + return -EIO; + } + return 0; + } + } + } + RIOFreeCmdBlk(CmdBlkP); + return -ENXIO; +} + +int RIOSuspendBootRta(struct Host *HostP, int ID, int Link) +{ + struct CmdBlk *CmdBlkP; + + rio_dprintk(RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA ID %d, link %c\n", ID, 'A' + Link); + + CmdBlkP = RIOGetCmdBlk(); + + if (!CmdBlkP) { + rio_dprintk(RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: GetCmdBlk failed\n"); + return -ENXIO; + } + + CmdBlkP->Packet.dest_unit = ID; + CmdBlkP->Packet.dest_port = BOOT_RUP; + CmdBlkP->Packet.src_unit = 0; + CmdBlkP->Packet.src_port = BOOT_RUP; + CmdBlkP->Packet.len = 0x84; + CmdBlkP->Packet.data[0] = IWAIT; + CmdBlkP->Packet.data[1] = Link; + CmdBlkP->Packet.data[2] = IWAIT_MAGIC & 0xFF; + CmdBlkP->Packet.data[3] = (IWAIT_MAGIC >> 8) & 0xFF; + + if (RIOQueueCmdBlk(HostP, ID - 1, CmdBlkP) == RIO_FAIL) { + rio_dprintk(RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: Failed to queue iwait command\n"); + return -EIO; + } + return 0; +} + +int RIOFoadWakeup(struct rio_info *p) +{ + int port; + struct Port *PortP; + unsigned long flags; + + for (port = 0; port < RIO_PORTS; port++) { + PortP = p->RIOPortp[port]; + + rio_spin_lock_irqsave(&PortP->portSem, flags); + PortP->Config = 0; + PortP->State = 0; + PortP->InUse = NOT_INUSE; + PortP->PortState = 0; + PortP->FlushCmdBodge = 0; + PortP->ModemLines = 0; + PortP->ModemState = 0; + PortP->CookMode = 0; + PortP->ParamSem = 0; + PortP->Mapped = 0; + PortP->WflushFlag = 0; + PortP->MagicFlags = 0; + PortP->RxDataStart = 0; + PortP->TxBufferIn = 0; + PortP->TxBufferOut = 0; + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + } + return (0); +} + +/* +** Incoming command on the COMMAND_RUP to be processed. +*/ +static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struct PKT __iomem *PacketP) +{ + struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *)PacketP->data; + struct Port *PortP; + struct UnixRup *UnixRupP; + unsigned short SysPort; + unsigned short ReportedModemStatus; + unsigned short rup; + unsigned short subCommand; + unsigned long flags; + + func_enter(); + + /* + ** 16 port RTA note: + ** Command rup packets coming from the RTA will have pkt->data[1] (which + ** translates to PktCmdP->PhbNum) set to the host port number for the + ** particular unit. To access the correct BaseSysPort for a 16 port RTA, + ** we can use PhbNum to get the rup number for the appropriate 8 port + ** block (for the first block, this should be equal to 'Rup'). + */ + rup = readb(&PktCmdP->PhbNum) / (unsigned short) PORTS_PER_RTA; + UnixRupP = &HostP->UnixRups[rup]; + SysPort = UnixRupP->BaseSysPort + (readb(&PktCmdP->PhbNum) % (unsigned short) PORTS_PER_RTA); + rio_dprintk(RIO_DEBUG_CMD, "Command on rup %d, port %d\n", rup, SysPort); + + if (UnixRupP->BaseSysPort == NO_PORT) { + rio_dprintk(RIO_DEBUG_CMD, "OBSCURE ERROR!\n"); + rio_dprintk(RIO_DEBUG_CMD, "Diagnostics follow. Please WRITE THESE DOWN and report them to Specialix Technical Support\n"); + rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: Host number %Zd, name ``%s''\n", HostP - p->RIOHosts, HostP->Name); + rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: Rup number 0x%x\n", rup); + + if (Rup < (unsigned short) MAX_RUP) { + rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: This is the RUP for RTA ``%s''\n", HostP->Mapping[Rup].Name); + } else + rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n", ('A' + Rup - MAX_RUP), HostP->Name); + + rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%x\n", readb(&PacketP->dest_unit), readb(&PacketP->dest_port)); + rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Source 0x%x:0x%x\n", readb(&PacketP->src_unit), readb(&PacketP->src_port)); + rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Length 0x%x (%d)\n", readb(&PacketP->len), readb(&PacketP->len)); + rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Control 0x%x (%d)\n", readb(&PacketP->control), readb(&PacketP->control)); + rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Check 0x%x (%d)\n", readw(&PacketP->csum), readw(&PacketP->csum)); + rio_dprintk(RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, " "Command Code 0x%x\n", readb(&PktCmdP->PhbNum), readb(&PktCmdP->Command)); + return 1; + } + PortP = p->RIOPortp[SysPort]; + rio_spin_lock_irqsave(&PortP->portSem, flags); + switch (readb(&PktCmdP->Command)) { + case RIOC_BREAK_RECEIVED: + rio_dprintk(RIO_DEBUG_CMD, "Received a break!\n"); + /* If the current line disc. is not multi-threading and + the current processor is not the default, reset rup_intr + and return 0 to ensure that the command packet is + not freed. */ + /* Call tmgr HANGUP HERE */ + /* Fix this later when every thing works !!!! RAMRAJ */ + gs_got_break(&PortP->gs); + break; + + case RIOC_COMPLETE: + rio_dprintk(RIO_DEBUG_CMD, "Command complete on phb %d host %Zd\n", readb(&PktCmdP->PhbNum), HostP - p->RIOHosts); + subCommand = 1; + switch (readb(&PktCmdP->SubCommand)) { + case RIOC_MEMDUMP: + rio_dprintk(RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%x\n", readb(&PktCmdP->SubCommand), readw(&PktCmdP->SubAddr)); + break; + case RIOC_READ_REGISTER: + rio_dprintk(RIO_DEBUG_CMD, "Read register (0x%x)\n", readw(&PktCmdP->SubAddr)); + p->CdRegister = (readb(&PktCmdP->ModemStatus) & RIOC_MSVR1_HOST); + break; + default: + subCommand = 0; + break; + } + if (subCommand) + break; + rio_dprintk(RIO_DEBUG_CMD, "New status is 0x%x was 0x%x\n", readb(&PktCmdP->PortStatus), PortP->PortState); + if (PortP->PortState != readb(&PktCmdP->PortStatus)) { + rio_dprintk(RIO_DEBUG_CMD, "Mark status & wakeup\n"); + PortP->PortState = readb(&PktCmdP->PortStatus); + /* What should we do here ... + wakeup( &PortP->PortState ); + */ + } else + rio_dprintk(RIO_DEBUG_CMD, "No change\n"); + + /* FALLTHROUGH */ + case RIOC_MODEM_STATUS: + /* + ** Knock out the tbusy and tstop bits, as these are not relevant + ** to the check for modem status change (they're just there because + ** it's a convenient place to put them!). + */ + ReportedModemStatus = readb(&PktCmdP->ModemStatus); + if ((PortP->ModemState & RIOC_MSVR1_HOST) == + (ReportedModemStatus & RIOC_MSVR1_HOST)) { + rio_dprintk(RIO_DEBUG_CMD, "Modem status unchanged 0x%x\n", PortP->ModemState); + /* + ** Update ModemState just in case tbusy or tstop states have + ** changed. + */ + PortP->ModemState = ReportedModemStatus; + } else { + rio_dprintk(RIO_DEBUG_CMD, "Modem status change from 0x%x to 0x%x\n", PortP->ModemState, ReportedModemStatus); + PortP->ModemState = ReportedModemStatus; +#ifdef MODEM_SUPPORT + if (PortP->Mapped) { + /***********************************************************\ + ************************************************************* + *** *** + *** M O D E M S T A T E C H A N G E *** + *** *** + ************************************************************* + \***********************************************************/ + /* + ** If the device is a modem, then check the modem + ** carrier. + */ + if (PortP->gs.port.tty == NULL) + break; + if (PortP->gs.port.tty->termios == NULL) + break; + + if (!(PortP->gs.port.tty->termios->c_cflag & CLOCAL) && ((PortP->State & (RIO_MOPEN | RIO_WOPEN)))) { + + rio_dprintk(RIO_DEBUG_CMD, "Is there a Carrier?\n"); + /* + ** Is there a carrier? + */ + if (PortP->ModemState & RIOC_MSVR1_CD) { + /* + ** Has carrier just appeared? + */ + if (!(PortP->State & RIO_CARR_ON)) { + rio_dprintk(RIO_DEBUG_CMD, "Carrier just came up.\n"); + PortP->State |= RIO_CARR_ON; + /* + ** wakeup anyone in WOPEN + */ + if (PortP->State & (PORT_ISOPEN | RIO_WOPEN)) + wake_up_interruptible(&PortP->gs.port.open_wait); + } + } else { + /* + ** Has carrier just dropped? + */ + if (PortP->State & RIO_CARR_ON) { + if (PortP->State & (PORT_ISOPEN | RIO_WOPEN | RIO_MOPEN)) + tty_hangup(PortP->gs.port.tty); + PortP->State &= ~RIO_CARR_ON; + rio_dprintk(RIO_DEBUG_CMD, "Carrirer just went down\n"); + } + } + } + } +#endif + } + break; + + default: + rio_dprintk(RIO_DEBUG_CMD, "Unknown command %d on CMD_RUP of host %Zd\n", readb(&PktCmdP->Command), HostP - p->RIOHosts); + break; + } + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + + func_exit(); + + return 1; +} + +/* +** The command mechanism: +** Each rup has a chain of commands associated with it. +** This chain is maintained by routines in this file. +** Periodically we are called and we run a quick check of all the +** active chains to determine if there is a command to be executed, +** and if the rup is ready to accept it. +** +*/ + +/* +** Allocate an empty command block. +*/ +struct CmdBlk *RIOGetCmdBlk(void) +{ + struct CmdBlk *CmdBlkP; + + CmdBlkP = kzalloc(sizeof(struct CmdBlk), GFP_ATOMIC); + return CmdBlkP; +} + +/* +** Return a block to the head of the free list. +*/ +void RIOFreeCmdBlk(struct CmdBlk *CmdBlkP) +{ + kfree(CmdBlkP); +} + +/* +** attach a command block to the list of commands to be performed for +** a given rup. +*/ +int RIOQueueCmdBlk(struct Host *HostP, uint Rup, struct CmdBlk *CmdBlkP) +{ + struct CmdBlk **Base; + struct UnixRup *UnixRupP; + unsigned long flags; + + if (Rup >= (unsigned short) (MAX_RUP + LINKS_PER_UNIT)) { + rio_dprintk(RIO_DEBUG_CMD, "Illegal rup number %d in RIOQueueCmdBlk\n", Rup); + RIOFreeCmdBlk(CmdBlkP); + return RIO_FAIL; + } + + UnixRupP = &HostP->UnixRups[Rup]; + + rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); + + /* + ** If the RUP is currently inactive, then put the request + ** straight on the RUP.... + */ + if ((UnixRupP->CmdsWaitingP == NULL) && (UnixRupP->CmdPendingP == NULL) && (readw(&UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE) && (CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP) (CmdBlkP->PreArg, CmdBlkP) + : 1)) { + rio_dprintk(RIO_DEBUG_CMD, "RUP inactive-placing command straight on. Cmd byte is 0x%x\n", CmdBlkP->Packet.data[0]); + + /* + ** Whammy! blat that pack! + */ + HostP->Copy(&CmdBlkP->Packet, RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->txpkt)), sizeof(struct PKT)); + + /* + ** place command packet on the pending position. + */ + UnixRupP->CmdPendingP = CmdBlkP; + + /* + ** set the command register + */ + writew(TX_PACKET_READY, &UnixRupP->RupP->txcontrol); + + rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); + + return 0; + } + rio_dprintk(RIO_DEBUG_CMD, "RUP active - en-queing\n"); + + if (UnixRupP->CmdsWaitingP != NULL) + rio_dprintk(RIO_DEBUG_CMD, "Rup active - command waiting\n"); + if (UnixRupP->CmdPendingP != NULL) + rio_dprintk(RIO_DEBUG_CMD, "Rup active - command pending\n"); + if (readw(&UnixRupP->RupP->txcontrol) != TX_RUP_INACTIVE) + rio_dprintk(RIO_DEBUG_CMD, "Rup active - command rup not ready\n"); + + Base = &UnixRupP->CmdsWaitingP; + + rio_dprintk(RIO_DEBUG_CMD, "First try to queue cmdblk %p at %p\n", CmdBlkP, Base); + + while (*Base) { + rio_dprintk(RIO_DEBUG_CMD, "Command cmdblk %p here\n", *Base); + Base = &((*Base)->NextP); + rio_dprintk(RIO_DEBUG_CMD, "Now try to queue cmd cmdblk %p at %p\n", CmdBlkP, Base); + } + + rio_dprintk(RIO_DEBUG_CMD, "Will queue cmdblk %p at %p\n", CmdBlkP, Base); + + *Base = CmdBlkP; + + CmdBlkP->NextP = NULL; + + rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); + + return 0; +} + +/* +** Here we go - if there is an empty rup, fill it! +** must be called at splrio() or higher. +*/ +void RIOPollHostCommands(struct rio_info *p, struct Host *HostP) +{ + struct CmdBlk *CmdBlkP; + struct UnixRup *UnixRupP; + struct PKT __iomem *PacketP; + unsigned short Rup; + unsigned long flags; + + + Rup = MAX_RUP + LINKS_PER_UNIT; + + do { /* do this loop for each RUP */ + /* + ** locate the rup we are processing & lock it + */ + UnixRupP = &HostP->UnixRups[--Rup]; + + spin_lock_irqsave(&UnixRupP->RupLock, flags); + + /* + ** First check for incoming commands: + */ + if (readw(&UnixRupP->RupP->rxcontrol) != RX_RUP_INACTIVE) { + int FreeMe; + + PacketP = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->rxpkt)); + + switch (readb(&PacketP->dest_port)) { + case BOOT_RUP: + rio_dprintk(RIO_DEBUG_CMD, "Incoming Boot %s packet '%x'\n", readb(&PacketP->len) & 0x80 ? "Command" : "Data", readb(&PacketP->data[0])); + rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); + FreeMe = RIOBootRup(p, Rup, HostP, PacketP); + rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); + break; + + case COMMAND_RUP: + /* + ** Free the RUP lock as loss of carrier causes a + ** ttyflush which will (eventually) call another + ** routine that uses the RUP lock. + */ + rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); + FreeMe = RIOCommandRup(p, Rup, HostP, PacketP); + if (readb(&PacketP->data[5]) == RIOC_MEMDUMP) { + rio_dprintk(RIO_DEBUG_CMD, "Memdump from 0x%x complete\n", readw(&(PacketP->data[6]))); + rio_memcpy_fromio(p->RIOMemDump, &(PacketP->data[8]), 32); + } + rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); + break; + + case ROUTE_RUP: + rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); + FreeMe = RIORouteRup(p, Rup, HostP, PacketP); + rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); + break; + + default: + rio_dprintk(RIO_DEBUG_CMD, "Unknown RUP %d\n", readb(&PacketP->dest_port)); + FreeMe = 1; + break; + } + + if (FreeMe) { + rio_dprintk(RIO_DEBUG_CMD, "Free processed incoming command packet\n"); + put_free_end(HostP, PacketP); + + writew(RX_RUP_INACTIVE, &UnixRupP->RupP->rxcontrol); + + if (readw(&UnixRupP->RupP->handshake) == PHB_HANDSHAKE_SET) { + rio_dprintk(RIO_DEBUG_CMD, "Handshake rup %d\n", Rup); + writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &UnixRupP->RupP->handshake); + } + } + } + + /* + ** IF a command was running on the port, + ** and it has completed, then tidy it up. + */ + if ((CmdBlkP = UnixRupP->CmdPendingP) && /* ASSIGN! */ + (readw(&UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) { + /* + ** we are idle. + ** there is a command in pending. + ** Therefore, this command has finished. + ** So, wakeup whoever is waiting for it (and tell them + ** what happened). + */ + if (CmdBlkP->Packet.dest_port == BOOT_RUP) + rio_dprintk(RIO_DEBUG_CMD, "Free Boot %s Command Block '%x'\n", CmdBlkP->Packet.len & 0x80 ? "Command" : "Data", CmdBlkP->Packet.data[0]); + + rio_dprintk(RIO_DEBUG_CMD, "Command %p completed\n", CmdBlkP); + + /* + ** Clear the Rup lock to prevent mutual exclusion. + */ + if (CmdBlkP->PostFuncP) { + rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); + (*CmdBlkP->PostFuncP) (CmdBlkP->PostArg, CmdBlkP); + rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); + } + + /* + ** ....clear the pending flag.... + */ + UnixRupP->CmdPendingP = NULL; + + /* + ** ....and return the command block to the freelist. + */ + RIOFreeCmdBlk(CmdBlkP); + } + + /* + ** If there is a command for this rup, and the rup + ** is idle, then process the command + */ + if ((CmdBlkP = UnixRupP->CmdsWaitingP) && /* ASSIGN! */ + (UnixRupP->CmdPendingP == NULL) && (readw(&UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) { + /* + ** if the pre-function is non-zero, call it. + ** If it returns RIO_FAIL then don't + ** send this command yet! + */ + if (!(CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP) (CmdBlkP->PreArg, CmdBlkP) : 1)) { + rio_dprintk(RIO_DEBUG_CMD, "Not ready to start command %p\n", CmdBlkP); + } else { + rio_dprintk(RIO_DEBUG_CMD, "Start new command %p Cmd byte is 0x%x\n", CmdBlkP, CmdBlkP->Packet.data[0]); + /* + ** Whammy! blat that pack! + */ + HostP->Copy(&CmdBlkP->Packet, RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->txpkt)), sizeof(struct PKT)); + + /* + ** remove the command from the rup command queue... + */ + UnixRupP->CmdsWaitingP = CmdBlkP->NextP; + + /* + ** ...and place it on the pending position. + */ + UnixRupP->CmdPendingP = CmdBlkP; + + /* + ** set the command register + */ + writew(TX_PACKET_READY, &UnixRupP->RupP->txcontrol); + + /* + ** the command block will be freed + ** when the command has been processed. + */ + } + } + spin_unlock_irqrestore(&UnixRupP->RupLock, flags); + } while (Rup); +} + +int RIOWFlushMark(unsigned long iPortP, struct CmdBlk *CmdBlkP) +{ + struct Port *PortP = (struct Port *) iPortP; + unsigned long flags; + + rio_spin_lock_irqsave(&PortP->portSem, flags); + PortP->WflushFlag++; + PortP->MagicFlags |= MAGIC_FLUSH; + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return RIOUnUse(iPortP, CmdBlkP); +} + +int RIORFlushEnable(unsigned long iPortP, struct CmdBlk *CmdBlkP) +{ + struct Port *PortP = (struct Port *) iPortP; + struct PKT __iomem *PacketP; + unsigned long flags; + + rio_spin_lock_irqsave(&PortP->portSem, flags); + + while (can_remove_receive(&PacketP, PortP)) { + remove_receive(PortP); + put_free_end(PortP->HostP, PacketP); + } + + if (readw(&PortP->PhbP->handshake) == PHB_HANDSHAKE_SET) { + /* + ** MAGIC! (Basically, handshake the RX buffer, so that + ** the RTAs upstream can be re-enabled.) + */ + rio_dprintk(RIO_DEBUG_CMD, "Util: Set RX handshake bit\n"); + writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &PortP->PhbP->handshake); + } + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return RIOUnUse(iPortP, CmdBlkP); +} + +int RIOUnUse(unsigned long iPortP, struct CmdBlk *CmdBlkP) +{ + struct Port *PortP = (struct Port *) iPortP; + unsigned long flags; + + rio_spin_lock_irqsave(&PortP->portSem, flags); + + rio_dprintk(RIO_DEBUG_CMD, "Decrement in use count for port\n"); + + if (PortP->InUse) { + if (--PortP->InUse != NOT_INUSE) { + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return 0; + } + } + /* + ** While PortP->InUse is set (i.e. a preemptive command has been sent to + ** the RTA and is awaiting completion), any transmit data is prevented from + ** being transferred from the write queue into the transmit packets + ** (add_transmit) and no furthur transmit interrupt will be sent for that + ** data. The next interrupt will occur up to 500ms later (RIOIntr is called + ** twice a second as a saftey measure). This was the case when kermit was + ** used to send data into a RIO port. After each packet was sent, TCFLSH + ** was called to flush the read queue preemptively. PortP->InUse was + ** incremented, thereby blocking the 6 byte acknowledgement packet + ** transmitted back. This acknowledgment hung around for 500ms before + ** being sent, thus reducing input performance substantially!. + ** When PortP->InUse becomes NOT_INUSE, we must ensure that any data + ** hanging around in the transmit buffer is sent immediately. + */ + writew(1, &PortP->HostP->ParmMapP->tx_intr); + /* What to do here .. + wakeup( (caddr_t)&(PortP->InUse) ); + */ + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return 0; +} + +/* +** +** How to use this file: +** +** To send a command down a rup, you need to allocate a command block, fill +** in the packet information, fill in the command number, fill in the pre- +** and post- functions and arguments, and then add the command block to the +** queue of command blocks for the port in question. When the port is idle, +** then the pre-function will be called. If this returns RIO_FAIL then the +** command will be re-queued and tried again at a later date (probably in one +** clock tick). If the pre-function returns NOT RIO_FAIL, then the command +** packet will be queued on the RUP, and the txcontrol field set to the +** command number. When the txcontrol field has changed from being the +** command number, then the post-function will be called, with the argument +** specified earlier, a pointer to the command block, and the value of +** txcontrol. +** +** To allocate a command block, call RIOGetCmdBlk(). This returns a pointer +** to the command block structure allocated, or NULL if there aren't any. +** The block will have been zeroed for you. +** +** The structure has the following fields: +** +** struct CmdBlk +** { +** struct CmdBlk *NextP; ** Pointer to next command block ** +** struct PKT Packet; ** A packet, to copy to the rup ** +** int (*PreFuncP)(); ** The func to call to check if OK ** +** int PreArg; ** The arg for the func ** +** int (*PostFuncP)(); ** The func to call when completed ** +** int PostArg; ** The arg for the func ** +** }; +** +** You need to fill in ALL fields EXCEPT NextP, which is used to link the +** blocks together either on the free list or on the Rup list. +** +** Packet is an actual packet structure to be filled in with the packet +** information associated with the command. You need to fill in everything, +** as the command processor doesn't process the command packet in any way. +** +** The PreFuncP is called before the packet is enqueued on the host rup. +** PreFuncP is called as (*PreFuncP)(PreArg, CmdBlkP);. PreFuncP must +** return !RIO_FAIL to have the packet queued on the rup, and RIO_FAIL +** if the packet is NOT to be queued. +** +** The PostFuncP is called when the command has completed. It is called +** as (*PostFuncP)(PostArg, CmdBlkP, txcontrol);. PostFuncP is not expected +** to return a value. PostFuncP does NOT need to free the command block, +** as this happens automatically after PostFuncP returns. +** +** Once the command block has been filled in, it is attached to the correct +** queue by calling RIOQueueCmdBlk( HostP, Rup, CmdBlkP ) where HostP is +** a pointer to the struct Host, Rup is the NUMBER of the rup (NOT a pointer +** to it!), and CmdBlkP is the pointer to the command block allocated using +** RIOGetCmdBlk(). +** +*/ diff --git a/drivers/staging/generic_serial/rio/rioctrl.c b/drivers/staging/generic_serial/rio/rioctrl.c new file mode 100644 index 000000000000..780506326a73 --- /dev/null +++ b/drivers/staging/generic_serial/rio/rioctrl.c @@ -0,0 +1,1504 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : rioctrl.c +** SID : 1.3 +** Last Modified : 11/6/98 10:33:42 +** Retrieved : 11/6/98 10:33:49 +** +** ident @(#)rioctrl.c 1.3 +** +** ----------------------------------------------------------------------------- +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + + +#include "linux_compat.h" +#include "rio_linux.h" +#include "pkt.h" +#include "daemon.h" +#include "rio.h" +#include "riospace.h" +#include "cmdpkt.h" +#include "map.h" +#include "rup.h" +#include "port.h" +#include "riodrvr.h" +#include "rioinfo.h" +#include "func.h" +#include "errors.h" +#include "pci.h" + +#include "parmmap.h" +#include "unixrup.h" +#include "board.h" +#include "host.h" +#include "phb.h" +#include "link.h" +#include "cmdblk.h" +#include "route.h" +#include "cirrus.h" +#include "rioioctl.h" + + +static struct LpbReq LpbReq; +static struct RupReq RupReq; +static struct PortReq PortReq; +static struct HostReq HostReq; /* oh really? global? and no locking? */ +static struct HostDpRam HostDpRam; +static struct DebugCtrl DebugCtrl; +static struct Map MapEnt; +static struct PortSetup PortSetup; +static struct DownLoad DownLoad; +static struct SendPack SendPack; +/* static struct StreamInfo StreamInfo; */ +/* static char modemtable[RIO_PORTS]; */ +static struct SpecialRupCmd SpecialRupCmd; +static struct PortParams PortParams; +static struct portStats portStats; + +static struct SubCmdStruct { + ushort Host; + ushort Rup; + ushort Port; + ushort Addr; +} SubCmd; + +struct PortTty { + uint port; + struct ttystatics Tty; +}; + +static struct PortTty PortTty; +typedef struct ttystatics TERMIO; + +/* +** This table is used when the config.rio downloads bin code to the +** driver. We index the table using the product code, 0-F, and call +** the function pointed to by the entry, passing the information +** about the boot. +** The RIOBootCodeUNKNOWN entry is there to politely tell the calling +** process to bog off. +*/ +static int + (*RIOBootTable[MAX_PRODUCT]) (struct rio_info *, struct DownLoad *) = { + /* 0 */ RIOBootCodeHOST, + /* Host Card */ + /* 1 */ RIOBootCodeRTA, + /* RTA */ +}; + +#define drv_makedev(maj, min) ((((uint) maj & 0xff) << 8) | ((uint) min & 0xff)) + +static int copy_from_io(void __user *to, void __iomem *from, size_t size) +{ + void *buf = kmalloc(size, GFP_KERNEL); + int res = -ENOMEM; + if (buf) { + rio_memcpy_fromio(buf, from, size); + res = copy_to_user(to, buf, size); + kfree(buf); + } + return res; +} + +int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su) +{ + uint Host; /* leave me unsigned! */ + uint port; /* and me! */ + struct Host *HostP; + ushort loop; + int Entry; + struct Port *PortP; + struct PKT __iomem *PacketP; + int retval = 0; + unsigned long flags; + void __user *argp = (void __user *)arg; + + func_enter(); + + /* Confuse the compiler to think that we've initialized these */ + Host = 0; + PortP = NULL; + + rio_dprintk(RIO_DEBUG_CTRL, "control ioctl cmd: 0x%x arg: %p\n", cmd, argp); + + switch (cmd) { + /* + ** RIO_SET_TIMER + ** + ** Change the value of the host card interrupt timer. + ** If the host card number is -1 then all host cards are changed + ** otherwise just the specified host card will be changed. + */ + case RIO_SET_TIMER: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_TIMER to %ldms\n", arg); + { + int host, value; + host = (arg >> 16) & 0x0000FFFF; + value = arg & 0x0000ffff; + if (host == -1) { + for (host = 0; host < p->RIONumHosts; host++) { + if (p->RIOHosts[host].Flags == RC_RUNNING) { + writew(value, &p->RIOHosts[host].ParmMapP->timer); + } + } + } else if (host >= p->RIONumHosts) { + return -EINVAL; + } else { + if (p->RIOHosts[host].Flags == RC_RUNNING) { + writew(value, &p->RIOHosts[host].ParmMapP->timer); + } + } + } + return 0; + + case RIO_FOAD_RTA: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_FOAD_RTA\n"); + return RIOCommandRta(p, arg, RIOFoadRta); + + case RIO_ZOMBIE_RTA: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_ZOMBIE_RTA\n"); + return RIOCommandRta(p, arg, RIOZombieRta); + + case RIO_IDENTIFY_RTA: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_IDENTIFY_RTA\n"); + return RIOIdentifyRta(p, argp); + + case RIO_KILL_NEIGHBOUR: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_KILL_NEIGHBOUR\n"); + return RIOKillNeighbour(p, argp); + + case SPECIAL_RUP_CMD: + { + struct CmdBlk *CmdBlkP; + + rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD\n"); + if (copy_from_user(&SpecialRupCmd, argp, sizeof(SpecialRupCmd))) { + rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD copy failed\n"); + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + CmdBlkP = RIOGetCmdBlk(); + if (!CmdBlkP) { + rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD GetCmdBlk failed\n"); + return -ENXIO; + } + CmdBlkP->Packet = SpecialRupCmd.Packet; + if (SpecialRupCmd.Host >= p->RIONumHosts) + SpecialRupCmd.Host = 0; + rio_dprintk(RIO_DEBUG_CTRL, "Queue special rup command for host %d rup %d\n", SpecialRupCmd.Host, SpecialRupCmd.RupNum); + if (RIOQueueCmdBlk(&p->RIOHosts[SpecialRupCmd.Host], SpecialRupCmd.RupNum, CmdBlkP) == RIO_FAIL) { + printk(KERN_WARNING "rio: FAILED TO QUEUE SPECIAL RUP COMMAND\n"); + } + return 0; + } + + case RIO_DEBUG_MEM: + return -EPERM; + + case RIO_ALL_MODEM: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_ALL_MODEM\n"); + p->RIOError.Error = IOCTL_COMMAND_UNKNOWN; + return -EINVAL; + + case RIO_GET_TABLE: + /* + ** Read the routing table from the device driver to user space + */ + rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_TABLE\n"); + + if ((retval = RIOApel(p)) != 0) + return retval; + + if (copy_to_user(argp, p->RIOConnectTable, TOTAL_MAP_ENTRIES * sizeof(struct Map))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_TABLE copy failed\n"); + p->RIOError.Error = COPYOUT_FAILED; + return -EFAULT; + } + + { + int entry; + rio_dprintk(RIO_DEBUG_CTRL, "*****\nMAP ENTRIES\n"); + for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) { + if ((p->RIOConnectTable[entry].ID == 0) && (p->RIOConnectTable[entry].HostUniqueNum == 0) && (p->RIOConnectTable[entry].RtaUniqueNum == 0)) + continue; + + rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.HostUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].HostUniqueNum); + rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum); + rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID); + rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2); + rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Flags = 0x%x\n", entry, (int) p->RIOConnectTable[entry].Flags); + rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.SysPort = 0x%x\n", entry, (int) p->RIOConnectTable[entry].SysPort); + rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[0].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Unit); + rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[0].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Link); + rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[1].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Unit); + rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[1].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Link); + rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[2].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Unit); + rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[2].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Link); + rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[3].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Unit); + rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[4].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Link); + rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name); + } + rio_dprintk(RIO_DEBUG_CTRL, "*****\nEND MAP ENTRIES\n"); + } + p->RIOQuickCheck = NOT_CHANGED; /* a table has been gotten */ + return 0; + + case RIO_PUT_TABLE: + /* + ** Write the routing table to the device driver from user space + */ + rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE\n"); + + if (!su) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE !Root\n"); + p->RIOError.Error = NOT_SUPER_USER; + return -EPERM; + } + if (copy_from_user(&p->RIOConnectTable[0], argp, TOTAL_MAP_ENTRIES * sizeof(struct Map))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE copy failed\n"); + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } +/* +*********************************** + { + int entry; + rio_dprint(RIO_DEBUG_CTRL, ("*****\nMAP ENTRIES\n") ); + for ( entry=0; entryRIOConnectTable[entry].HostUniqueNum ) ); + rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum ) ); + rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID ) ); + rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2 ) ); + rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Flags = 0x%x\n", entry, p->RIOConnectTable[entry].Flags ) ); + rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.SysPort = 0x%x\n", entry, p->RIOConnectTable[entry].SysPort ) ); + rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[0].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[0].Unit ) ); + rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[0].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[0].Link ) ); + rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[1].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[1].Unit ) ); + rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[1].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[1].Link ) ); + rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[2].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[2].Unit ) ); + rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[2].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[2].Link ) ); + rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[3].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[3].Unit ) ); + rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[4].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[3].Link ) ); + rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name ) ); + } + rio_dprint(RIO_DEBUG_CTRL, ("*****\nEND MAP ENTRIES\n") ); + } +*********************************** +*/ + return RIONewTable(p); + + case RIO_GET_BINDINGS: + /* + ** Send bindings table, containing unique numbers of RTAs owned + ** by this system to user space + */ + rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS\n"); + + if (!su) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS !Root\n"); + p->RIOError.Error = NOT_SUPER_USER; + return -EPERM; + } + if (copy_to_user(argp, p->RIOBindTab, (sizeof(ulong) * MAX_RTA_BINDINGS))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS copy failed\n"); + p->RIOError.Error = COPYOUT_FAILED; + return -EFAULT; + } + return 0; + + case RIO_PUT_BINDINGS: + /* + ** Receive a bindings table, containing unique numbers of RTAs owned + ** by this system + */ + rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS\n"); + + if (!su) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS !Root\n"); + p->RIOError.Error = NOT_SUPER_USER; + return -EPERM; + } + if (copy_from_user(&p->RIOBindTab[0], argp, (sizeof(ulong) * MAX_RTA_BINDINGS))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS copy failed\n"); + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + return 0; + + case RIO_BIND_RTA: + { + int EmptySlot = -1; + /* + ** Bind this RTA to host, so that it will be booted by + ** host in 'boot owned RTAs' mode. + */ + rio_dprintk(RIO_DEBUG_CTRL, "RIO_BIND_RTA\n"); + + if (!su) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_BIND_RTA !Root\n"); + p->RIOError.Error = NOT_SUPER_USER; + return -EPERM; + } + for (Entry = 0; Entry < MAX_RTA_BINDINGS; Entry++) { + if ((EmptySlot == -1) && (p->RIOBindTab[Entry] == 0L)) + EmptySlot = Entry; + else if (p->RIOBindTab[Entry] == arg) { + /* + ** Already exists - delete + */ + p->RIOBindTab[Entry] = 0L; + rio_dprintk(RIO_DEBUG_CTRL, "Removing Rta %ld from p->RIOBindTab\n", arg); + return 0; + } + } + /* + ** Dosen't exist - add + */ + if (EmptySlot != -1) { + p->RIOBindTab[EmptySlot] = arg; + rio_dprintk(RIO_DEBUG_CTRL, "Adding Rta %lx to p->RIOBindTab\n", arg); + } else { + rio_dprintk(RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %lx not added\n", arg); + return -ENOMEM; + } + return 0; + } + + case RIO_RESUME: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME\n"); + port = arg; + if ((port < 0) || (port > 511)) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Bad port number %d\n", port); + p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; + return -EINVAL; + } + PortP = p->RIOPortp[port]; + if (!PortP->Mapped) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not mapped\n", port); + p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM; + return -EINVAL; + } + if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not open\n", port); + return -EINVAL; + } + + rio_spin_lock_irqsave(&PortP->portSem, flags); + if (RIOPreemptiveCmd(p, (p->RIOPortp[port]), RIOC_RESUME) == + RIO_FAIL) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME failed\n"); + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return -EBUSY; + } else { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d resumed\n", port); + PortP->State |= RIO_BUSY; + } + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return retval; + + case RIO_ASSIGN_RTA: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA\n"); + if (!su) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA !Root\n"); + p->RIOError.Error = NOT_SUPER_USER; + return -EPERM; + } + if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) { + rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n"); + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + return RIOAssignRta(p, &MapEnt); + + case RIO_CHANGE_NAME: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_CHANGE_NAME\n"); + if (!su) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_CHANGE_NAME !Root\n"); + p->RIOError.Error = NOT_SUPER_USER; + return -EPERM; + } + if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) { + rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n"); + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + return RIOChangeName(p, &MapEnt); + + case RIO_DELETE_RTA: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_DELETE_RTA\n"); + if (!su) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_DELETE_RTA !Root\n"); + p->RIOError.Error = NOT_SUPER_USER; + return -EPERM; + } + if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) { + rio_dprintk(RIO_DEBUG_CTRL, "Copy from data space failed\n"); + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + return RIODeleteRta(p, &MapEnt); + + case RIO_QUICK_CHECK: + if (copy_to_user(argp, &p->RIORtaDisCons, sizeof(unsigned int))) { + p->RIOError.Error = COPYOUT_FAILED; + return -EFAULT; + } + return 0; + + case RIO_LAST_ERROR: + if (copy_to_user(argp, &p->RIOError, sizeof(struct Error))) + return -EFAULT; + return 0; + + case RIO_GET_LOG: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_LOG\n"); + return -EINVAL; + + case RIO_GET_MODTYPE: + if (copy_from_user(&port, argp, sizeof(unsigned int))) { + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + rio_dprintk(RIO_DEBUG_CTRL, "Get module type for port %d\n", port); + if (port < 0 || port > 511) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Bad port number %d\n", port); + p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; + return -EINVAL; + } + PortP = (p->RIOPortp[port]); + if (!PortP->Mapped) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Port %d not mapped\n", port); + p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM; + return -EINVAL; + } + /* + ** Return module type of port + */ + port = PortP->HostP->UnixRups[PortP->RupNum].ModTypes; + if (copy_to_user(argp, &port, sizeof(unsigned int))) { + p->RIOError.Error = COPYOUT_FAILED; + return -EFAULT; + } + return (0); + case RIO_BLOCK_OPENS: + rio_dprintk(RIO_DEBUG_CTRL, "Opens block until booted\n"); + for (Entry = 0; Entry < RIO_PORTS; Entry++) { + rio_spin_lock_irqsave(&PortP->portSem, flags); + p->RIOPortp[Entry]->WaitUntilBooted = 1; + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + } + return 0; + + case RIO_SETUP_PORTS: + rio_dprintk(RIO_DEBUG_CTRL, "Setup ports\n"); + if (copy_from_user(&PortSetup, argp, sizeof(PortSetup))) { + p->RIOError.Error = COPYIN_FAILED; + rio_dprintk(RIO_DEBUG_CTRL, "EFAULT"); + return -EFAULT; + } + if (PortSetup.From > PortSetup.To || PortSetup.To >= RIO_PORTS) { + p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; + rio_dprintk(RIO_DEBUG_CTRL, "ENXIO"); + return -ENXIO; + } + if (PortSetup.XpCps > p->RIOConf.MaxXpCps || PortSetup.XpCps < p->RIOConf.MinXpCps) { + p->RIOError.Error = XPRINT_CPS_OUT_OF_RANGE; + rio_dprintk(RIO_DEBUG_CTRL, "EINVAL"); + return -EINVAL; + } + if (!p->RIOPortp) { + printk(KERN_ERR "rio: No p->RIOPortp array!\n"); + rio_dprintk(RIO_DEBUG_CTRL, "No p->RIOPortp array!\n"); + return -EIO; + } + rio_dprintk(RIO_DEBUG_CTRL, "entering loop (%d %d)!\n", PortSetup.From, PortSetup.To); + for (loop = PortSetup.From; loop <= PortSetup.To; loop++) { + rio_dprintk(RIO_DEBUG_CTRL, "in loop (%d)!\n", loop); + } + rio_dprintk(RIO_DEBUG_CTRL, "after loop (%d)!\n", loop); + rio_dprintk(RIO_DEBUG_CTRL, "Retval:%x\n", retval); + return retval; + + case RIO_GET_PORT_SETUP: + rio_dprintk(RIO_DEBUG_CTRL, "Get port setup\n"); + if (copy_from_user(&PortSetup, argp, sizeof(PortSetup))) { + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + if (PortSetup.From >= RIO_PORTS) { + p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; + return -ENXIO; + } + + port = PortSetup.To = PortSetup.From; + PortSetup.IxAny = (p->RIOPortp[port]->Config & RIO_IXANY) ? 1 : 0; + PortSetup.IxOn = (p->RIOPortp[port]->Config & RIO_IXON) ? 1 : 0; + PortSetup.Drain = (p->RIOPortp[port]->Config & RIO_WAITDRAIN) ? 1 : 0; + PortSetup.Store = p->RIOPortp[port]->Store; + PortSetup.Lock = p->RIOPortp[port]->Lock; + PortSetup.XpCps = p->RIOPortp[port]->Xprint.XpCps; + memcpy(PortSetup.XpOn, p->RIOPortp[port]->Xprint.XpOn, MAX_XP_CTRL_LEN); + memcpy(PortSetup.XpOff, p->RIOPortp[port]->Xprint.XpOff, MAX_XP_CTRL_LEN); + PortSetup.XpOn[MAX_XP_CTRL_LEN - 1] = '\0'; + PortSetup.XpOff[MAX_XP_CTRL_LEN - 1] = '\0'; + + if (copy_to_user(argp, &PortSetup, sizeof(PortSetup))) { + p->RIOError.Error = COPYOUT_FAILED; + return -EFAULT; + } + return retval; + + case RIO_GET_PORT_PARAMS: + rio_dprintk(RIO_DEBUG_CTRL, "Get port params\n"); + if (copy_from_user(&PortParams, argp, sizeof(struct PortParams))) { + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + if (PortParams.Port >= RIO_PORTS) { + p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; + return -ENXIO; + } + PortP = (p->RIOPortp[PortParams.Port]); + PortParams.Config = PortP->Config; + PortParams.State = PortP->State; + rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortParams.Port); + + if (copy_to_user(argp, &PortParams, sizeof(struct PortParams))) { + p->RIOError.Error = COPYOUT_FAILED; + return -EFAULT; + } + return retval; + + case RIO_GET_PORT_TTY: + rio_dprintk(RIO_DEBUG_CTRL, "Get port tty\n"); + if (copy_from_user(&PortTty, argp, sizeof(struct PortTty))) { + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + if (PortTty.port >= RIO_PORTS) { + p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; + return -ENXIO; + } + + rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortTty.port); + PortP = (p->RIOPortp[PortTty.port]); + if (copy_to_user(argp, &PortTty, sizeof(struct PortTty))) { + p->RIOError.Error = COPYOUT_FAILED; + return -EFAULT; + } + return retval; + + case RIO_SET_PORT_TTY: + if (copy_from_user(&PortTty, argp, sizeof(struct PortTty))) { + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + rio_dprintk(RIO_DEBUG_CTRL, "Set port %d tty\n", PortTty.port); + if (PortTty.port >= (ushort) RIO_PORTS) { + p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; + return -ENXIO; + } + PortP = (p->RIOPortp[PortTty.port]); + RIOParam(PortP, RIOC_CONFIG, PortP->State & RIO_MODEM, + OK_TO_SLEEP); + return retval; + + case RIO_SET_PORT_PARAMS: + rio_dprintk(RIO_DEBUG_CTRL, "Set port params\n"); + if (copy_from_user(&PortParams, argp, sizeof(PortParams))) { + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + if (PortParams.Port >= (ushort) RIO_PORTS) { + p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; + return -ENXIO; + } + PortP = (p->RIOPortp[PortParams.Port]); + rio_spin_lock_irqsave(&PortP->portSem, flags); + PortP->Config = PortParams.Config; + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return retval; + + case RIO_GET_PORT_STATS: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_PORT_STATS\n"); + if (copy_from_user(&portStats, argp, sizeof(struct portStats))) { + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + if (portStats.port < 0 || portStats.port >= RIO_PORTS) { + p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; + return -ENXIO; + } + PortP = (p->RIOPortp[portStats.port]); + portStats.gather = PortP->statsGather; + portStats.txchars = PortP->txchars; + portStats.rxchars = PortP->rxchars; + portStats.opens = PortP->opens; + portStats.closes = PortP->closes; + portStats.ioctls = PortP->ioctls; + if (copy_to_user(argp, &portStats, sizeof(struct portStats))) { + p->RIOError.Error = COPYOUT_FAILED; + return -EFAULT; + } + return retval; + + case RIO_RESET_PORT_STATS: + port = arg; + rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESET_PORT_STATS\n"); + if (port >= RIO_PORTS) { + p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; + return -ENXIO; + } + PortP = (p->RIOPortp[port]); + rio_spin_lock_irqsave(&PortP->portSem, flags); + PortP->txchars = 0; + PortP->rxchars = 0; + PortP->opens = 0; + PortP->closes = 0; + PortP->ioctls = 0; + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return retval; + + case RIO_GATHER_PORT_STATS: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_GATHER_PORT_STATS\n"); + if (copy_from_user(&portStats, argp, sizeof(struct portStats))) { + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + if (portStats.port < 0 || portStats.port >= RIO_PORTS) { + p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; + return -ENXIO; + } + PortP = (p->RIOPortp[portStats.port]); + rio_spin_lock_irqsave(&PortP->portSem, flags); + PortP->statsGather = portStats.gather; + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return retval; + + case RIO_READ_CONFIG: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_CONFIG\n"); + if (copy_to_user(argp, &p->RIOConf, sizeof(struct Conf))) { + p->RIOError.Error = COPYOUT_FAILED; + return -EFAULT; + } + return retval; + + case RIO_SET_CONFIG: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_CONFIG\n"); + if (!su) { + p->RIOError.Error = NOT_SUPER_USER; + return -EPERM; + } + if (copy_from_user(&p->RIOConf, argp, sizeof(struct Conf))) { + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + /* + ** move a few value around + */ + for (Host = 0; Host < p->RIONumHosts; Host++) + if ((p->RIOHosts[Host].Flags & RUN_STATE) == RC_RUNNING) + writew(p->RIOConf.Timer, &p->RIOHosts[Host].ParmMapP->timer); + return retval; + + case RIO_START_POLLER: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_START_POLLER\n"); + return -EINVAL; + + case RIO_STOP_POLLER: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_STOP_POLLER\n"); + if (!su) { + p->RIOError.Error = NOT_SUPER_USER; + return -EPERM; + } + p->RIOPolling = NOT_POLLING; + return retval; + + case RIO_SETDEBUG: + case RIO_GETDEBUG: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_SETDEBUG/RIO_GETDEBUG\n"); + if (copy_from_user(&DebugCtrl, argp, sizeof(DebugCtrl))) { + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + if (DebugCtrl.SysPort == NO_PORT) { + if (cmd == RIO_SETDEBUG) { + if (!su) { + p->RIOError.Error = NOT_SUPER_USER; + return -EPERM; + } + p->rio_debug = DebugCtrl.Debug; + p->RIODebugWait = DebugCtrl.Wait; + rio_dprintk(RIO_DEBUG_CTRL, "Set global debug to 0x%x set wait to 0x%x\n", p->rio_debug, p->RIODebugWait); + } else { + rio_dprintk(RIO_DEBUG_CTRL, "Get global debug 0x%x wait 0x%x\n", p->rio_debug, p->RIODebugWait); + DebugCtrl.Debug = p->rio_debug; + DebugCtrl.Wait = p->RIODebugWait; + if (copy_to_user(argp, &DebugCtrl, sizeof(DebugCtrl))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", DebugCtrl.SysPort); + p->RIOError.Error = COPYOUT_FAILED; + return -EFAULT; + } + } + } else if (DebugCtrl.SysPort >= RIO_PORTS && DebugCtrl.SysPort != NO_PORT) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", DebugCtrl.SysPort); + p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; + return -ENXIO; + } else if (cmd == RIO_SETDEBUG) { + if (!su) { + p->RIOError.Error = NOT_SUPER_USER; + return -EPERM; + } + rio_spin_lock_irqsave(&PortP->portSem, flags); + p->RIOPortp[DebugCtrl.SysPort]->Debug = DebugCtrl.Debug; + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + rio_dprintk(RIO_DEBUG_CTRL, "RIO_SETDEBUG 0x%x\n", p->RIOPortp[DebugCtrl.SysPort]->Debug); + } else { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG 0x%x\n", p->RIOPortp[DebugCtrl.SysPort]->Debug); + DebugCtrl.Debug = p->RIOPortp[DebugCtrl.SysPort]->Debug; + if (copy_to_user(argp, &DebugCtrl, sizeof(DebugCtrl))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG: Bad copy to user space\n"); + p->RIOError.Error = COPYOUT_FAILED; + return -EFAULT; + } + } + return retval; + + case RIO_VERSID: + /* + ** Enquire about the release and version. + ** We return MAX_VERSION_LEN bytes, being a + ** textual null terminated string. + */ + rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID\n"); + if (copy_to_user(argp, RIOVersid(), sizeof(struct rioVersion))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID: Bad copy to user space (host=%d)\n", Host); + p->RIOError.Error = COPYOUT_FAILED; + return -EFAULT; + } + return retval; + + case RIO_NUM_HOSTS: + /* + ** Enquire as to the number of hosts located + ** at init time. + */ + rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS\n"); + if (copy_to_user(argp, &p->RIONumHosts, sizeof(p->RIONumHosts))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS: Bad copy to user space\n"); + p->RIOError.Error = COPYOUT_FAILED; + return -EFAULT; + } + return retval; + + case RIO_HOST_FOAD: + /* + ** Kill host. This may not be in the final version... + */ + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD %ld\n", arg); + if (!su) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD: Not super user\n"); + p->RIOError.Error = NOT_SUPER_USER; + return -EPERM; + } + p->RIOHalted = 1; + p->RIOSystemUp = 0; + + for (Host = 0; Host < p->RIONumHosts; Host++) { + (void) RIOBoardTest(p->RIOHosts[Host].PaddrP, p->RIOHosts[Host].Caddr, p->RIOHosts[Host].Type, p->RIOHosts[Host].Slot); + memset(&p->RIOHosts[Host].Flags, 0, ((char *) &p->RIOHosts[Host].____end_marker____) - ((char *) &p->RIOHosts[Host].Flags)); + p->RIOHosts[Host].Flags = RC_WAITING; + } + RIOFoadWakeup(p); + p->RIONumBootPkts = 0; + p->RIOBooting = 0; + printk("HEEEEELP!\n"); + + for (loop = 0; loop < RIO_PORTS; loop++) { + spin_lock_init(&p->RIOPortp[loop]->portSem); + p->RIOPortp[loop]->InUse = NOT_INUSE; + } + + p->RIOSystemUp = 0; + return retval; + + case RIO_DOWNLOAD: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD\n"); + if (!su) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Not super user\n"); + p->RIOError.Error = NOT_SUPER_USER; + return -EPERM; + } + if (copy_from_user(&DownLoad, argp, sizeof(DownLoad))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Copy in from user space failed\n"); + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + rio_dprintk(RIO_DEBUG_CTRL, "Copied in download code for product code 0x%x\n", DownLoad.ProductCode); + + /* + ** It is important that the product code is an unsigned object! + */ + if (DownLoad.ProductCode >= MAX_PRODUCT) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Bad product code %d passed\n", DownLoad.ProductCode); + p->RIOError.Error = NO_SUCH_PRODUCT; + return -ENXIO; + } + /* + ** do something! + */ + retval = (*(RIOBootTable[DownLoad.ProductCode])) (p, &DownLoad); + /* <-- Panic */ + p->RIOHalted = 0; + /* + ** and go back, content with a job well completed. + */ + return retval; + + case RIO_PARMS: + { + unsigned int host; + + if (copy_from_user(&host, argp, sizeof(host))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n"); + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + /* + ** Fetch the parmmap + */ + rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS\n"); + if (copy_from_io(argp, p->RIOHosts[host].ParmMapP, sizeof(PARM_MAP))) { + p->RIOError.Error = COPYOUT_FAILED; + rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS: Copy out to user space failed\n"); + return -EFAULT; + } + } + return retval; + + case RIO_HOST_REQ: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ\n"); + if (copy_from_user(&HostReq, argp, sizeof(HostReq))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n"); + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + if (HostReq.HostNum >= p->RIONumHosts) { + p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Illegal host number %d\n", HostReq.HostNum); + return -ENXIO; + } + rio_dprintk(RIO_DEBUG_CTRL, "Request for host %d\n", HostReq.HostNum); + + if (copy_to_user(HostReq.HostP, &p->RIOHosts[HostReq.HostNum], sizeof(struct Host))) { + p->RIOError.Error = COPYOUT_FAILED; + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Bad copy to user space\n"); + return -EFAULT; + } + return retval; + + case RIO_HOST_DPRAM: + rio_dprintk(RIO_DEBUG_CTRL, "Request for DPRAM\n"); + if (copy_from_user(&HostDpRam, argp, sizeof(HostDpRam))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Copy in from user space failed\n"); + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + if (HostDpRam.HostNum >= p->RIONumHosts) { + p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Illegal host number %d\n", HostDpRam.HostNum); + return -ENXIO; + } + rio_dprintk(RIO_DEBUG_CTRL, "Request for host %d\n", HostDpRam.HostNum); + + if (p->RIOHosts[HostDpRam.HostNum].Type == RIO_PCI) { + int off; + /* It's hardware like this that really gets on my tits. */ + static unsigned char copy[sizeof(struct DpRam)]; + for (off = 0; off < sizeof(struct DpRam); off++) + copy[off] = readb(p->RIOHosts[HostDpRam.HostNum].Caddr + off); + if (copy_to_user(HostDpRam.DpRamP, copy, sizeof(struct DpRam))) { + p->RIOError.Error = COPYOUT_FAILED; + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n"); + return -EFAULT; + } + } else if (copy_from_io(HostDpRam.DpRamP, p->RIOHosts[HostDpRam.HostNum].Caddr, sizeof(struct DpRam))) { + p->RIOError.Error = COPYOUT_FAILED; + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n"); + return -EFAULT; + } + return retval; + + case RIO_SET_BUSY: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY\n"); + if (arg > 511) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY: Bad port number %ld\n", arg); + p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; + return -EINVAL; + } + rio_spin_lock_irqsave(&PortP->portSem, flags); + p->RIOPortp[arg]->State |= RIO_BUSY; + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return retval; + + case RIO_HOST_PORT: + /* + ** The daemon want port information + ** (probably for debug reasons) + */ + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT\n"); + if (copy_from_user(&PortReq, argp, sizeof(PortReq))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Copy in from user space failed\n"); + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + + if (PortReq.SysPort >= RIO_PORTS) { /* SysPort is unsigned */ + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Illegal port number %d\n", PortReq.SysPort); + p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; + return -ENXIO; + } + rio_dprintk(RIO_DEBUG_CTRL, "Request for port %d\n", PortReq.SysPort); + if (copy_to_user(PortReq.PortP, p->RIOPortp[PortReq.SysPort], sizeof(struct Port))) { + p->RIOError.Error = COPYOUT_FAILED; + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Bad copy to user space\n"); + return -EFAULT; + } + return retval; + + case RIO_HOST_RUP: + /* + ** The daemon want rup information + ** (probably for debug reasons) + */ + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP\n"); + if (copy_from_user(&RupReq, argp, sizeof(RupReq))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Copy in from user space failed\n"); + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + if (RupReq.HostNum >= p->RIONumHosts) { /* host is unsigned */ + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal host number %d\n", RupReq.HostNum); + p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; + return -ENXIO; + } + if (RupReq.RupNum >= MAX_RUP + LINKS_PER_UNIT) { /* eek! */ + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal rup number %d\n", RupReq.RupNum); + p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; + return -EINVAL; + } + HostP = &p->RIOHosts[RupReq.HostNum]; + + if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Host %d not running\n", RupReq.HostNum); + p->RIOError.Error = HOST_NOT_RUNNING; + return -EIO; + } + rio_dprintk(RIO_DEBUG_CTRL, "Request for rup %d from host %d\n", RupReq.RupNum, RupReq.HostNum); + + if (copy_from_io(RupReq.RupP, HostP->UnixRups[RupReq.RupNum].RupP, sizeof(struct RUP))) { + p->RIOError.Error = COPYOUT_FAILED; + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Bad copy to user space\n"); + return -EFAULT; + } + return retval; + + case RIO_HOST_LPB: + /* + ** The daemon want lpb information + ** (probably for debug reasons) + */ + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB\n"); + if (copy_from_user(&LpbReq, argp, sizeof(LpbReq))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy from user space\n"); + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + if (LpbReq.Host >= p->RIONumHosts) { /* host is unsigned */ + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal host number %d\n", LpbReq.Host); + p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; + return -ENXIO; + } + if (LpbReq.Link >= LINKS_PER_UNIT) { /* eek! */ + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal link number %d\n", LpbReq.Link); + p->RIOError.Error = LINK_NUMBER_OUT_OF_RANGE; + return -EINVAL; + } + HostP = &p->RIOHosts[LpbReq.Host]; + + if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Host %d not running\n", LpbReq.Host); + p->RIOError.Error = HOST_NOT_RUNNING; + return -EIO; + } + rio_dprintk(RIO_DEBUG_CTRL, "Request for lpb %d from host %d\n", LpbReq.Link, LpbReq.Host); + + if (copy_from_io(LpbReq.LpbP, &HostP->LinkStrP[LpbReq.Link], sizeof(struct LPB))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy to user space\n"); + p->RIOError.Error = COPYOUT_FAILED; + return -EFAULT; + } + return retval; + + /* + ** Here 3 IOCTL's that allow us to change the way in which + ** rio logs errors. send them just to syslog or send them + ** to both syslog and console or send them to just the console. + ** + ** See RioStrBuf() in util.c for the other half. + */ + case RIO_SYSLOG_ONLY: + p->RIOPrintLogState = PRINT_TO_LOG; /* Just syslog */ + return 0; + + case RIO_SYSLOG_CONS: + p->RIOPrintLogState = PRINT_TO_LOG_CONS; /* syslog and console */ + return 0; + + case RIO_CONS_ONLY: + p->RIOPrintLogState = PRINT_TO_CONS; /* Just console */ + return 0; + + case RIO_SIGNALS_ON: + if (p->RIOSignalProcess) { + p->RIOError.Error = SIGNALS_ALREADY_SET; + return -EBUSY; + } + /* FIXME: PID tracking */ + p->RIOSignalProcess = current->pid; + p->RIOPrintDisabled = DONT_PRINT; + return retval; + + case RIO_SIGNALS_OFF: + if (p->RIOSignalProcess != current->pid) { + p->RIOError.Error = NOT_RECEIVING_PROCESS; + return -EPERM; + } + rio_dprintk(RIO_DEBUG_CTRL, "Clear signal process to zero\n"); + p->RIOSignalProcess = 0; + return retval; + + case RIO_SET_BYTE_MODE: + for (Host = 0; Host < p->RIONumHosts; Host++) + if (p->RIOHosts[Host].Type == RIO_AT) + p->RIOHosts[Host].Mode &= ~WORD_OPERATION; + return retval; + + case RIO_SET_WORD_MODE: + for (Host = 0; Host < p->RIONumHosts; Host++) + if (p->RIOHosts[Host].Type == RIO_AT) + p->RIOHosts[Host].Mode |= WORD_OPERATION; + return retval; + + case RIO_SET_FAST_BUS: + for (Host = 0; Host < p->RIONumHosts; Host++) + if (p->RIOHosts[Host].Type == RIO_AT) + p->RIOHosts[Host].Mode |= FAST_AT_BUS; + return retval; + + case RIO_SET_SLOW_BUS: + for (Host = 0; Host < p->RIONumHosts; Host++) + if (p->RIOHosts[Host].Type == RIO_AT) + p->RIOHosts[Host].Mode &= ~FAST_AT_BUS; + return retval; + + case RIO_MAP_B50_TO_50: + case RIO_MAP_B50_TO_57600: + case RIO_MAP_B110_TO_110: + case RIO_MAP_B110_TO_115200: + rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping\n"); + port = arg; + if (port < 0 || port > 511) { + rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", port); + p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; + return -EINVAL; + } + rio_spin_lock_irqsave(&PortP->portSem, flags); + switch (cmd) { + case RIO_MAP_B50_TO_50: + p->RIOPortp[port]->Config |= RIO_MAP_50_TO_50; + break; + case RIO_MAP_B50_TO_57600: + p->RIOPortp[port]->Config &= ~RIO_MAP_50_TO_50; + break; + case RIO_MAP_B110_TO_110: + p->RIOPortp[port]->Config |= RIO_MAP_110_TO_110; + break; + case RIO_MAP_B110_TO_115200: + p->RIOPortp[port]->Config &= ~RIO_MAP_110_TO_110; + break; + } + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return retval; + + case RIO_STREAM_INFO: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_STREAM_INFO\n"); + return -EINVAL; + + case RIO_SEND_PACKET: + rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET\n"); + if (copy_from_user(&SendPack, argp, sizeof(SendPack))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET: Bad copy from user space\n"); + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + if (SendPack.PortNum >= 128) { + p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; + return -ENXIO; + } + + PortP = p->RIOPortp[SendPack.PortNum]; + rio_spin_lock_irqsave(&PortP->portSem, flags); + + if (!can_add_transmit(&PacketP, PortP)) { + p->RIOError.Error = UNIT_IS_IN_USE; + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return -ENOSPC; + } + + for (loop = 0; loop < (ushort) (SendPack.Len & 127); loop++) + writeb(SendPack.Data[loop], &PacketP->data[loop]); + + writeb(SendPack.Len, &PacketP->len); + + add_transmit(PortP); + /* + ** Count characters transmitted for port statistics reporting + */ + if (PortP->statsGather) + PortP->txchars += (SendPack.Len & 127); + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return retval; + + case RIO_NO_MESG: + if (su) + p->RIONoMessage = 1; + return su ? 0 : -EPERM; + + case RIO_MESG: + if (su) + p->RIONoMessage = 0; + return su ? 0 : -EPERM; + + case RIO_WHAT_MESG: + if (copy_to_user(argp, &p->RIONoMessage, sizeof(p->RIONoMessage))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_WHAT_MESG: Bad copy to user space\n"); + p->RIOError.Error = COPYOUT_FAILED; + return -EFAULT; + } + return 0; + + case RIO_MEM_DUMP: + if (copy_from_user(&SubCmd, argp, sizeof(struct SubCmdStruct))) { + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP host %d rup %d addr %x\n", SubCmd.Host, SubCmd.Rup, SubCmd.Addr); + + if (SubCmd.Rup >= MAX_RUP + LINKS_PER_UNIT) { + p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; + return -EINVAL; + } + + if (SubCmd.Host >= p->RIONumHosts) { + p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; + return -EINVAL; + } + + port = p->RIOHosts[SubCmd.Host].UnixRups[SubCmd.Rup].BaseSysPort; + + PortP = p->RIOPortp[port]; + + rio_spin_lock_irqsave(&PortP->portSem, flags); + + if (RIOPreemptiveCmd(p, PortP, RIOC_MEMDUMP) == RIO_FAIL) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP failed\n"); + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return -EBUSY; + } else + PortP->State |= RIO_BUSY; + + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + if (copy_to_user(argp, p->RIOMemDump, MEMDUMP_SIZE)) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP copy failed\n"); + p->RIOError.Error = COPYOUT_FAILED; + return -EFAULT; + } + return 0; + + case RIO_TICK: + if (arg >= p->RIONumHosts) + return -EINVAL; + rio_dprintk(RIO_DEBUG_CTRL, "Set interrupt for host %ld\n", arg); + writeb(0xFF, &p->RIOHosts[arg].SetInt); + return 0; + + case RIO_TOCK: + if (arg >= p->RIONumHosts) + return -EINVAL; + rio_dprintk(RIO_DEBUG_CTRL, "Clear interrupt for host %ld\n", arg); + writeb(0xFF, &p->RIOHosts[arg].ResetInt); + return 0; + + case RIO_READ_CHECK: + /* Check reads for pkts with data[0] the same */ + p->RIOReadCheck = !p->RIOReadCheck; + if (copy_to_user(argp, &p->RIOReadCheck, sizeof(unsigned int))) { + p->RIOError.Error = COPYOUT_FAILED; + return -EFAULT; + } + return 0; + + case RIO_READ_REGISTER: + if (copy_from_user(&SubCmd, argp, sizeof(struct SubCmdStruct))) { + p->RIOError.Error = COPYIN_FAILED; + return -EFAULT; + } + rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER host %d rup %d port %d reg %x\n", SubCmd.Host, SubCmd.Rup, SubCmd.Port, SubCmd.Addr); + + if (SubCmd.Port > 511) { + rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", SubCmd.Port); + p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; + return -EINVAL; + } + + if (SubCmd.Rup >= MAX_RUP + LINKS_PER_UNIT) { + p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; + return -EINVAL; + } + + if (SubCmd.Host >= p->RIONumHosts) { + p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; + return -EINVAL; + } + + port = p->RIOHosts[SubCmd.Host].UnixRups[SubCmd.Rup].BaseSysPort + SubCmd.Port; + PortP = p->RIOPortp[port]; + + rio_spin_lock_irqsave(&PortP->portSem, flags); + + if (RIOPreemptiveCmd(p, PortP, RIOC_READ_REGISTER) == + RIO_FAIL) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER failed\n"); + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return -EBUSY; + } else + PortP->State |= RIO_BUSY; + + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + if (copy_to_user(argp, &p->CdRegister, sizeof(unsigned int))) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER copy failed\n"); + p->RIOError.Error = COPYOUT_FAILED; + return -EFAULT; + } + return 0; + /* + ** rio_make_dev: given port number (0-511) ORed with port type + ** (RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT) return dev_t + ** value to pass to mknod to create the correct device node. + */ + case RIO_MAKE_DEV: + { + unsigned int port = arg & RIO_MODEM_MASK; + unsigned int ret; + + switch (arg & RIO_DEV_MASK) { + case RIO_DEV_DIRECT: + ret = drv_makedev(MAJOR(dev), port); + rio_dprintk(RIO_DEBUG_CTRL, "Makedev direct 0x%x is 0x%x\n", port, ret); + return ret; + case RIO_DEV_MODEM: + ret = drv_makedev(MAJOR(dev), (port | RIO_MODEM_BIT)); + rio_dprintk(RIO_DEBUG_CTRL, "Makedev modem 0x%x is 0x%x\n", port, ret); + return ret; + case RIO_DEV_XPRINT: + ret = drv_makedev(MAJOR(dev), port); + rio_dprintk(RIO_DEBUG_CTRL, "Makedev printer 0x%x is 0x%x\n", port, ret); + return ret; + } + rio_dprintk(RIO_DEBUG_CTRL, "MAKE Device is called\n"); + return -EINVAL; + } + /* + ** rio_minor: given a dev_t from a stat() call, return + ** the port number (0-511) ORed with the port type + ** ( RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT ) + */ + case RIO_MINOR: + { + dev_t dv; + int mino; + unsigned long ret; + + dv = (dev_t) (arg); + mino = RIO_UNMODEM(dv); + + if (RIO_ISMODEM(dv)) { + rio_dprintk(RIO_DEBUG_CTRL, "Minor for device 0x%x: modem %d\n", dv, mino); + ret = mino | RIO_DEV_MODEM; + } else { + rio_dprintk(RIO_DEBUG_CTRL, "Minor for device 0x%x: direct %d\n", dv, mino); + ret = mino | RIO_DEV_DIRECT; + } + return ret; + } + } + rio_dprintk(RIO_DEBUG_CTRL, "INVALID DAEMON IOCTL 0x%x\n", cmd); + p->RIOError.Error = IOCTL_COMMAND_UNKNOWN; + + func_exit(); + return -EINVAL; +} + +/* +** Pre-emptive commands go on RUPs and are only one byte long. +*/ +int RIOPreemptiveCmd(struct rio_info *p, struct Port *PortP, u8 Cmd) +{ + struct CmdBlk *CmdBlkP; + struct PktCmd_M *PktCmdP; + int Ret; + ushort rup; + int port; + + if (PortP->State & RIO_DELETED) { + rio_dprintk(RIO_DEBUG_CTRL, "Preemptive command to deleted RTA ignored\n"); + return RIO_FAIL; + } + + if ((PortP->InUse == (typeof(PortP->InUse))-1) || + !(CmdBlkP = RIOGetCmdBlk())) { + rio_dprintk(RIO_DEBUG_CTRL, "Cannot allocate command block " + "for command %d on port %d\n", Cmd, PortP->PortNum); + return RIO_FAIL; + } + + rio_dprintk(RIO_DEBUG_CTRL, "Command blk %p - InUse now %d\n", + CmdBlkP, PortP->InUse); + + PktCmdP = (struct PktCmd_M *)&CmdBlkP->Packet.data[0]; + + CmdBlkP->Packet.src_unit = 0; + if (PortP->SecondBlock) + rup = PortP->ID2; + else + rup = PortP->RupNum; + CmdBlkP->Packet.dest_unit = rup; + CmdBlkP->Packet.src_port = COMMAND_RUP; + CmdBlkP->Packet.dest_port = COMMAND_RUP; + CmdBlkP->Packet.len = PKT_CMD_BIT | 2; + CmdBlkP->PostFuncP = RIOUnUse; + CmdBlkP->PostArg = (unsigned long) PortP; + PktCmdP->Command = Cmd; + port = PortP->HostPort % (ushort) PORTS_PER_RTA; + /* + ** Index ports 8-15 for 2nd block of 16 port RTA. + */ + if (PortP->SecondBlock) + port += (ushort) PORTS_PER_RTA; + PktCmdP->PhbNum = port; + + switch (Cmd) { + case RIOC_MEMDUMP: + rio_dprintk(RIO_DEBUG_CTRL, "Queue MEMDUMP command blk %p " + "(addr 0x%x)\n", CmdBlkP, (int) SubCmd.Addr); + PktCmdP->SubCommand = RIOC_MEMDUMP; + PktCmdP->SubAddr = SubCmd.Addr; + break; + case RIOC_FCLOSE: + rio_dprintk(RIO_DEBUG_CTRL, "Queue FCLOSE command blk %p\n", + CmdBlkP); + break; + case RIOC_READ_REGISTER: + rio_dprintk(RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) " + "command blk %p\n", (int) SubCmd.Addr, CmdBlkP); + PktCmdP->SubCommand = RIOC_READ_REGISTER; + PktCmdP->SubAddr = SubCmd.Addr; + break; + case RIOC_RESUME: + rio_dprintk(RIO_DEBUG_CTRL, "Queue RESUME command blk %p\n", + CmdBlkP); + break; + case RIOC_RFLUSH: + rio_dprintk(RIO_DEBUG_CTRL, "Queue RFLUSH command blk %p\n", + CmdBlkP); + CmdBlkP->PostFuncP = RIORFlushEnable; + break; + case RIOC_SUSPEND: + rio_dprintk(RIO_DEBUG_CTRL, "Queue SUSPEND command blk %p\n", + CmdBlkP); + break; + + case RIOC_MGET: + rio_dprintk(RIO_DEBUG_CTRL, "Queue MGET command blk %p\n", + CmdBlkP); + break; + + case RIOC_MSET: + case RIOC_MBIC: + case RIOC_MBIS: + CmdBlkP->Packet.data[4] = (char) PortP->ModemLines; + rio_dprintk(RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command " + "blk %p\n", CmdBlkP); + break; + + case RIOC_WFLUSH: + /* + ** If we have queued up the maximum number of Write flushes + ** allowed then we should not bother sending any more to the + ** RTA. + */ + if (PortP->WflushFlag == (typeof(PortP->WflushFlag))-1) { + rio_dprintk(RIO_DEBUG_CTRL, "Trashed WFLUSH, " + "WflushFlag about to wrap!"); + RIOFreeCmdBlk(CmdBlkP); + return (RIO_FAIL); + } else { + rio_dprintk(RIO_DEBUG_CTRL, "Queue WFLUSH command " + "blk %p\n", CmdBlkP); + CmdBlkP->PostFuncP = RIOWFlushMark; + } + break; + } + + PortP->InUse++; + + Ret = RIOQueueCmdBlk(PortP->HostP, rup, CmdBlkP); + + return Ret; +} diff --git a/drivers/staging/generic_serial/rio/riodrvr.h b/drivers/staging/generic_serial/rio/riodrvr.h new file mode 100644 index 000000000000..0907e711b355 --- /dev/null +++ b/drivers/staging/generic_serial/rio/riodrvr.h @@ -0,0 +1,138 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : riodrvr.h +** SID : 1.3 +** Last Modified : 11/6/98 09:22:46 +** Retrieved : 11/6/98 09:22:46 +** +** ident @(#)riodrvr.h 1.3 +** +** ----------------------------------------------------------------------------- +*/ + +#ifndef __riodrvr_h +#define __riodrvr_h + +#include /* for HZ */ + +#define MEMDUMP_SIZE 32 +#define MOD_DISABLE (RIO_NOREAD|RIO_NOWRITE|RIO_NOXPRINT) + + +struct rio_info { + int mode; /* Intr or polled, word/byte */ + spinlock_t RIOIntrSem; /* Interrupt thread sem */ + int current_chan; /* current channel */ + int RIOFailed; /* Not initialised ? */ + int RIOInstallAttempts; /* no. of rio-install() calls */ + int RIOLastPCISearch; /* status of last search */ + int RIONumHosts; /* Number of RIO Hosts */ + struct Host *RIOHosts; /* RIO Host values */ + struct Port **RIOPortp; /* RIO port values */ +/* +** 02.03.1999 ARG - ESIL 0820 fix +** We no longer use RIOBootMode +** + int RIOBootMode; * RIO boot mode * +** +*/ + int RIOPrintDisabled; /* RIO printing disabled ? */ + int RIOPrintLogState; /* RIO printing state ? */ + int RIOPolling; /* Polling ? */ +/* +** 09.12.1998 ARG - ESIL 0776 part fix +** The 'RIO_QUICK_CHECK' ioctl was using RIOHalted. +** The fix for this ESIL introduces another member (RIORtaDisCons) here to be +** updated in RIOConCon() - to keep track of RTA connections/disconnections. +** 'RIO_QUICK_CHECK' now returns the value of RIORtaDisCons. +*/ + int RIOHalted; /* halted ? */ + int RIORtaDisCons; /* RTA connections/disconnections */ + unsigned int RIOReadCheck; /* Rio read check */ + unsigned int RIONoMessage; /* To display message or not */ + unsigned int RIONumBootPkts; /* how many packets for an RTA */ + unsigned int RIOBootCount; /* size of RTA code */ + unsigned int RIOBooting; /* count of outstanding boots */ + unsigned int RIOSystemUp; /* Booted ?? */ + unsigned int RIOCounting; /* for counting interrupts */ + unsigned int RIOIntCount; /* # of intr since last check */ + unsigned int RIOTxCount; /* number of xmit intrs */ + unsigned int RIORxCount; /* number of rx intrs */ + unsigned int RIORupCount; /* number of rup intrs */ + int RIXTimer; + int RIOBufferSize; /* Buffersize */ + int RIOBufferMask; /* Buffersize */ + + int RIOFirstMajor; /* First host card's major no */ + + unsigned int RIOLastPortsMapped; /* highest port number known */ + unsigned int RIOFirstPortsMapped; /* lowest port number known */ + + unsigned int RIOLastPortsBooted; /* highest port number running */ + unsigned int RIOFirstPortsBooted; /* lowest port number running */ + + unsigned int RIOLastPortsOpened; /* highest port number running */ + unsigned int RIOFirstPortsOpened; /* lowest port number running */ + + /* Flag to say that the topology information has been changed. */ + unsigned int RIOQuickCheck; + unsigned int CdRegister; /* ??? */ + int RIOSignalProcess; /* Signalling process */ + int rio_debug; /* To debug ... */ + int RIODebugWait; /* For what ??? */ + int tpri; /* Thread prio */ + int tid; /* Thread id */ + unsigned int _RIO_Polled; /* Counter for polling */ + unsigned int _RIO_Interrupted; /* Counter for interrupt */ + int intr_tid; /* iointset return value */ + int TxEnSem; /* TxEnable Semaphore */ + + + struct Error RIOError; /* to Identify what went wrong */ + struct Conf RIOConf; /* Configuration ??? */ + struct ttystatics channel[RIO_PORTS]; /* channel information */ + char RIOBootPackets[1 + (SIXTY_FOUR_K / RTA_BOOT_DATA_SIZE)] + [RTA_BOOT_DATA_SIZE]; + struct Map RIOConnectTable[TOTAL_MAP_ENTRIES]; + struct Map RIOSavedTable[TOTAL_MAP_ENTRIES]; + + /* RTA to host binding table for master/slave operation */ + unsigned long RIOBindTab[MAX_RTA_BINDINGS]; + /* RTA memory dump variable */ + unsigned char RIOMemDump[MEMDUMP_SIZE]; + struct ModuleInfo RIOModuleTypes[MAX_MODULE_TYPES]; + +}; + + +#ifdef linux +#define debug(x) printk x +#else +#define debug(x) kkprintf x +#endif + + + +#define RIO_RESET_INT 0x7d80 + +#endif /* __riodrvr.h */ diff --git a/drivers/staging/generic_serial/rio/rioinfo.h b/drivers/staging/generic_serial/rio/rioinfo.h new file mode 100644 index 000000000000..42ff1e79d96f --- /dev/null +++ b/drivers/staging/generic_serial/rio/rioinfo.h @@ -0,0 +1,92 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : rioinfo.h +** SID : 1.2 +** Last Modified : 11/6/98 14:07:49 +** Retrieved : 11/6/98 14:07:50 +** +** ident @(#)rioinfo.h 1.2 +** +** ----------------------------------------------------------------------------- +*/ + +#ifndef __rioinfo_h +#define __rioinfo_h + +/* +** Host card data structure +*/ +struct RioHostInfo { + long location; /* RIO Card Base I/O address */ + long vector; /* RIO Card IRQ vector */ + int bus; /* ISA/EISA/MCA/PCI */ + int mode; /* pointer to host mode - INTERRUPT / POLLED */ + struct old_sgttyb + *Sg; /* pointer to default term characteristics */ +}; + + +/* Mode in rio device info */ +#define INTERRUPTED_MODE 0x01 /* Interrupt is generated */ +#define POLLED_MODE 0x02 /* No interrupt */ +#define AUTO_MODE 0x03 /* Auto mode */ + +#define WORD_ACCESS_MODE 0x10 /* Word Access Mode */ +#define BYTE_ACCESS_MODE 0x20 /* Byte Access Mode */ + + +/* Bus type that RIO supports */ +#define ISA_BUS 0x01 /* The card is ISA */ +#define EISA_BUS 0x02 /* The card is EISA */ +#define MCA_BUS 0x04 /* The card is MCA */ +#define PCI_BUS 0x08 /* The card is PCI */ + +/* +** 11.11.1998 ARG - ESIL ???? part fix +** Moved definition for 'CHAN' here from rioinfo.c (it is now +** called 'DEF_TERM_CHARACTERISTICS'). +*/ + +#define DEF_TERM_CHARACTERISTICS \ +{ \ + B19200, B19200, /* input and output speed */ \ + 'H' - '@', /* erase char */ \ + -1, /* 2nd erase char */ \ + 'U' - '@', /* kill char */ \ + ECHO | CRMOD, /* mode */ \ + 'C' - '@', /* interrupt character */ \ + '\\' - '@', /* quit char */ \ + 'Q' - '@', /* start char */ \ + 'S' - '@', /* stop char */ \ + 'D' - '@', /* EOF */ \ + -1, /* brk */ \ + (LCRTBS | LCRTERA | LCRTKIL | LCTLECH), /* local mode word */ \ + 'Z' - '@', /* process stop */ \ + 'Y' - '@', /* delayed stop */ \ + 'R' - '@', /* reprint line */ \ + 'O' - '@', /* flush output */ \ + 'W' - '@', /* word erase */ \ + 'V' - '@' /* literal next char */ \ +} + +#endif /* __rioinfo_h */ diff --git a/drivers/staging/generic_serial/rio/rioinit.c b/drivers/staging/generic_serial/rio/rioinit.c new file mode 100644 index 000000000000..24a282bb89d4 --- /dev/null +++ b/drivers/staging/generic_serial/rio/rioinit.c @@ -0,0 +1,421 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : rioinit.c +** SID : 1.3 +** Last Modified : 11/6/98 10:33:43 +** Retrieved : 11/6/98 10:33:49 +** +** ident @(#)rioinit.c 1.3 +** +** ----------------------------------------------------------------------------- +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + + +#include "linux_compat.h" +#include "pkt.h" +#include "daemon.h" +#include "rio.h" +#include "riospace.h" +#include "cmdpkt.h" +#include "map.h" +#include "rup.h" +#include "port.h" +#include "riodrvr.h" +#include "rioinfo.h" +#include "func.h" +#include "errors.h" +#include "pci.h" + +#include "parmmap.h" +#include "unixrup.h" +#include "board.h" +#include "host.h" +#include "phb.h" +#include "link.h" +#include "cmdblk.h" +#include "route.h" +#include "cirrus.h" +#include "rioioctl.h" +#include "rio_linux.h" + +int RIOPCIinit(struct rio_info *p, int Mode); + +static int RIOScrub(int, u8 __iomem *, int); + + +/** +** RIOAssignAT : +** +** Fill out the fields in the p->RIOHosts structure now we know we know +** we have a board present. +** +** bits < 0 indicates 8 bit operation requested, +** bits > 0 indicates 16 bit operation. +*/ + +int RIOAssignAT(struct rio_info *p, int Base, void __iomem *virtAddr, int mode) +{ + int bits; + struct DpRam __iomem *cardp = (struct DpRam __iomem *)virtAddr; + + if ((Base < ONE_MEG) || (mode & BYTE_ACCESS_MODE)) + bits = BYTE_OPERATION; + else + bits = WORD_OPERATION; + + /* + ** Board has passed its scrub test. Fill in all the + ** transient stuff. + */ + p->RIOHosts[p->RIONumHosts].Caddr = virtAddr; + p->RIOHosts[p->RIONumHosts].CardP = virtAddr; + + /* + ** Revision 01 AT host cards don't support WORD operations, + */ + if (readb(&cardp->DpRevision) == 01) + bits = BYTE_OPERATION; + + p->RIOHosts[p->RIONumHosts].Type = RIO_AT; + p->RIOHosts[p->RIONumHosts].Copy = rio_copy_to_card; + /* set this later */ + p->RIOHosts[p->RIONumHosts].Slot = -1; + p->RIOHosts[p->RIONumHosts].Mode = SLOW_LINKS | SLOW_AT_BUS | bits; + writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | p->RIOHosts[p->RIONumHosts].Mode | INTERRUPT_DISABLE , + &p->RIOHosts[p->RIONumHosts].Control); + writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt); + writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | p->RIOHosts[p->RIONumHosts].Mode | INTERRUPT_DISABLE, + &p->RIOHosts[p->RIONumHosts].Control); + writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt); + p->RIOHosts[p->RIONumHosts].UniqueNum = + ((readb(&p->RIOHosts[p->RIONumHosts].Unique[0])&0xFF)<<0)| + ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1])&0xFF)<<8)| + ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2])&0xFF)<<16)| + ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3])&0xFF)<<24); + rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Uniquenum 0x%x\n",p->RIOHosts[p->RIONumHosts].UniqueNum); + + p->RIONumHosts++; + rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Tests Passed at 0x%x\n", Base); + return(1); +} + +static u8 val[] = { +#ifdef VERY_LONG_TEST + 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, + 0xa5, 0xff, 0x5a, 0x00, 0xff, 0xc9, 0x36, +#endif + 0xff, 0x00, 0x00 }; + +#define TEST_END sizeof(val) + +/* +** RAM test a board. +** Nothing too complicated, just enough to check it out. +*/ +int RIOBoardTest(unsigned long paddr, void __iomem *caddr, unsigned char type, int slot) +{ + struct DpRam __iomem *DpRam = caddr; + void __iomem *ram[4]; + int size[4]; + int op, bank; + int nbanks; + + rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Reset host type=%d, DpRam=%p, slot=%d\n", + type, DpRam, slot); + + RIOHostReset(type, DpRam, slot); + + /* + ** Scrub the memory. This comes in several banks: + ** DPsram1 - 7000h bytes + ** DPsram2 - 200h bytes + ** DPsram3 - 7000h bytes + ** scratch - 1000h bytes + */ + + rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Setup ram/size arrays\n"); + + size[0] = DP_SRAM1_SIZE; + size[1] = DP_SRAM2_SIZE; + size[2] = DP_SRAM3_SIZE; + size[3] = DP_SCRATCH_SIZE; + + ram[0] = DpRam->DpSram1; + ram[1] = DpRam->DpSram2; + ram[2] = DpRam->DpSram3; + nbanks = (type == RIO_PCI) ? 3 : 4; + if (nbanks == 4) + ram[3] = DpRam->DpScratch; + + + if (nbanks == 3) { + rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Memory: %p(0x%x), %p(0x%x), %p(0x%x)\n", + ram[0], size[0], ram[1], size[1], ram[2], size[2]); + } else { + rio_dprintk (RIO_DEBUG_INIT, "RIO-init: %p(0x%x), %p(0x%x), %p(0x%x), %p(0x%x)\n", + ram[0], size[0], ram[1], size[1], ram[2], size[2], ram[3], size[3]); + } + + /* + ** This scrub operation will test for crosstalk between + ** banks. TEST_END is a magic number, and relates to the offset + ** within the 'val' array used by Scrub. + */ + for (op=0; opMapping[UnitId].Name, "UNKNOWN RTA X-XX", 17); + HostP->Mapping[UnitId].Name[12]='1'+(HostP-p->RIOHosts); + if ((UnitId+1) > 9) { + HostP->Mapping[UnitId].Name[14]='0'+((UnitId+1)/10); + HostP->Mapping[UnitId].Name[15]='0'+((UnitId+1)%10); + } + else { + HostP->Mapping[UnitId].Name[14]='1'+UnitId; + HostP->Mapping[UnitId].Name[15]=0; + } + return 0; +} + +#define RIO_RELEASE "Linux" +#define RELEASE_ID "1.0" + +static struct rioVersion stVersion; + +struct rioVersion *RIOVersid(void) +{ + strlcpy(stVersion.version, "RIO driver for linux V1.0", + sizeof(stVersion.version)); + strlcpy(stVersion.buildDate, __DATE__, + sizeof(stVersion.buildDate)); + + return &stVersion; +} + +void RIOHostReset(unsigned int Type, struct DpRam __iomem *DpRamP, unsigned int Slot) +{ + /* + ** Reset the Tpu + */ + rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: type 0x%x", Type); + switch ( Type ) { + case RIO_AT: + rio_dprintk (RIO_DEBUG_INIT, " (RIO_AT)\n"); + writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | INTERRUPT_DISABLE | BYTE_OPERATION | + SLOW_LINKS | SLOW_AT_BUS, &DpRamP->DpControl); + writeb(0xFF, &DpRamP->DpResetTpu); + udelay(3); + rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: Don't know if it worked. Try reset again\n"); + writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | INTERRUPT_DISABLE | + BYTE_OPERATION | SLOW_LINKS | SLOW_AT_BUS, &DpRamP->DpControl); + writeb(0xFF, &DpRamP->DpResetTpu); + udelay(3); + break; + case RIO_PCI: + rio_dprintk (RIO_DEBUG_INIT, " (RIO_PCI)\n"); + writeb(RIO_PCI_BOOT_FROM_RAM, &DpRamP->DpControl); + writeb(0xFF, &DpRamP->DpResetInt); + writeb(0xFF, &DpRamP->DpResetTpu); + udelay(100); + break; + default: + rio_dprintk (RIO_DEBUG_INIT, " (UNKNOWN)\n"); + break; + } + return; +} diff --git a/drivers/staging/generic_serial/rio/riointr.c b/drivers/staging/generic_serial/rio/riointr.c new file mode 100644 index 000000000000..2e71aecae206 --- /dev/null +++ b/drivers/staging/generic_serial/rio/riointr.c @@ -0,0 +1,645 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : riointr.c +** SID : 1.2 +** Last Modified : 11/6/98 10:33:44 +** Retrieved : 11/6/98 10:33:49 +** +** ident @(#)riointr.c 1.2 +** +** ----------------------------------------------------------------------------- +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include "linux_compat.h" +#include "rio_linux.h" +#include "pkt.h" +#include "daemon.h" +#include "rio.h" +#include "riospace.h" +#include "cmdpkt.h" +#include "map.h" +#include "rup.h" +#include "port.h" +#include "riodrvr.h" +#include "rioinfo.h" +#include "func.h" +#include "errors.h" +#include "pci.h" + +#include "parmmap.h" +#include "unixrup.h" +#include "board.h" +#include "host.h" +#include "phb.h" +#include "link.h" +#include "cmdblk.h" +#include "route.h" +#include "cirrus.h" +#include "rioioctl.h" + + +static void RIOReceive(struct rio_info *, struct Port *); + + +static char *firstchars(char *p, int nch) +{ + static char buf[2][128]; + static int t = 0; + t = !t; + memcpy(buf[t], p, nch); + buf[t][nch] = 0; + return buf[t]; +} + + +#define INCR( P, I ) ((P) = (((P)+(I)) & p->RIOBufferMask)) +/* Enable and start the transmission of packets */ +void RIOTxEnable(char *en) +{ + struct Port *PortP; + struct rio_info *p; + struct tty_struct *tty; + int c; + struct PKT __iomem *PacketP; + unsigned long flags; + + PortP = (struct Port *) en; + p = (struct rio_info *) PortP->p; + tty = PortP->gs.port.tty; + + + rio_dprintk(RIO_DEBUG_INTR, "tx port %d: %d chars queued.\n", PortP->PortNum, PortP->gs.xmit_cnt); + + if (!PortP->gs.xmit_cnt) + return; + + + /* This routine is an order of magnitude simpler than the specialix + version. One of the disadvantages is that this version will send + an incomplete packet (usually 64 bytes instead of 72) once for + every 4k worth of data. Let's just say that this won't influence + performance significantly..... */ + + rio_spin_lock_irqsave(&PortP->portSem, flags); + + while (can_add_transmit(&PacketP, PortP)) { + c = PortP->gs.xmit_cnt; + if (c > PKT_MAX_DATA_LEN) + c = PKT_MAX_DATA_LEN; + + /* Don't copy past the end of the source buffer */ + if (c > SERIAL_XMIT_SIZE - PortP->gs.xmit_tail) + c = SERIAL_XMIT_SIZE - PortP->gs.xmit_tail; + + { + int t; + t = (c > 10) ? 10 : c; + + rio_dprintk(RIO_DEBUG_INTR, "rio: tx port %d: copying %d chars: %s - %s\n", PortP->PortNum, c, firstchars(PortP->gs.xmit_buf + PortP->gs.xmit_tail, t), firstchars(PortP->gs.xmit_buf + PortP->gs.xmit_tail + c - t, t)); + } + /* If for one reason or another, we can't copy more data, + we're done! */ + if (c == 0) + break; + + rio_memcpy_toio(PortP->HostP->Caddr, PacketP->data, PortP->gs.xmit_buf + PortP->gs.xmit_tail, c); + /* udelay (1); */ + + writeb(c, &(PacketP->len)); + if (!(PortP->State & RIO_DELETED)) { + add_transmit(PortP); + /* + ** Count chars tx'd for port statistics reporting + */ + if (PortP->statsGather) + PortP->txchars += c; + } + PortP->gs.xmit_tail = (PortP->gs.xmit_tail + c) & (SERIAL_XMIT_SIZE - 1); + PortP->gs.xmit_cnt -= c; + } + + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + + if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2 * PKT_MAX_DATA_LEN)) + tty_wakeup(PortP->gs.port.tty); + +} + + +/* +** RIO Host Service routine. Does all the work traditionally associated with an +** interrupt. +*/ +static int RupIntr; +static int RxIntr; +static int TxIntr; + +void RIOServiceHost(struct rio_info *p, struct Host *HostP) +{ + rio_spin_lock(&HostP->HostLock); + if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { + static int t = 0; + rio_spin_unlock(&HostP->HostLock); + if ((t++ % 200) == 0) + rio_dprintk(RIO_DEBUG_INTR, "Interrupt but host not running. flags=%x.\n", (int) HostP->Flags); + return; + } + rio_spin_unlock(&HostP->HostLock); + + if (readw(&HostP->ParmMapP->rup_intr)) { + writew(0, &HostP->ParmMapP->rup_intr); + p->RIORupCount++; + RupIntr++; + rio_dprintk(RIO_DEBUG_INTR, "rio: RUP interrupt on host %Zd\n", HostP - p->RIOHosts); + RIOPollHostCommands(p, HostP); + } + + if (readw(&HostP->ParmMapP->rx_intr)) { + int port; + + writew(0, &HostP->ParmMapP->rx_intr); + p->RIORxCount++; + RxIntr++; + + rio_dprintk(RIO_DEBUG_INTR, "rio: RX interrupt on host %Zd\n", HostP - p->RIOHosts); + /* + ** Loop through every port. If the port is mapped into + ** the system ( i.e. has /dev/ttyXXXX associated ) then it is + ** worth checking. If the port isn't open, grab any packets + ** hanging on its receive queue and stuff them on the free + ** list; check for commands on the way. + */ + for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) { + struct Port *PortP = p->RIOPortp[port]; + struct tty_struct *ttyP; + struct PKT __iomem *PacketP; + + /* + ** not mapped in - most of the RIOPortp[] information + ** has not been set up! + ** Optimise: ports come in bundles of eight. + */ + if (!PortP->Mapped) { + port += 7; + continue; /* with the next port */ + } + + /* + ** If the host board isn't THIS host board, check the next one. + ** optimise: ports come in bundles of eight. + */ + if (PortP->HostP != HostP) { + port += 7; + continue; + } + + /* + ** Let us see - is the port open? If not, then don't service it. + */ + if (!(PortP->PortState & PORT_ISOPEN)) { + continue; + } + + /* + ** find corresponding tty structure. The process of mapping + ** the ports puts these here. + */ + ttyP = PortP->gs.port.tty; + + /* + ** Lock the port before we begin working on it. + */ + rio_spin_lock(&PortP->portSem); + + /* + ** Process received data if there is any. + */ + if (can_remove_receive(&PacketP, PortP)) + RIOReceive(p, PortP); + + /* + ** If there is no data left to be read from the port, and + ** it's handshake bit is set, then we must clear the handshake, + ** so that that downstream RTA is re-enabled. + */ + if (!can_remove_receive(&PacketP, PortP) && (readw(&PortP->PhbP->handshake) == PHB_HANDSHAKE_SET)) { + /* + ** MAGIC! ( Basically, handshake the RX buffer, so that + ** the RTAs upstream can be re-enabled. ) + */ + rio_dprintk(RIO_DEBUG_INTR, "Set RX handshake bit\n"); + writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &PortP->PhbP->handshake); + } + rio_spin_unlock(&PortP->portSem); + } + } + + if (readw(&HostP->ParmMapP->tx_intr)) { + int port; + + writew(0, &HostP->ParmMapP->tx_intr); + + p->RIOTxCount++; + TxIntr++; + rio_dprintk(RIO_DEBUG_INTR, "rio: TX interrupt on host %Zd\n", HostP - p->RIOHosts); + + /* + ** Loop through every port. + ** If the port is mapped into the system ( i.e. has /dev/ttyXXXX + ** associated ) then it is worth checking. + */ + for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) { + struct Port *PortP = p->RIOPortp[port]; + struct tty_struct *ttyP; + struct PKT __iomem *PacketP; + + /* + ** not mapped in - most of the RIOPortp[] information + ** has not been set up! + */ + if (!PortP->Mapped) { + port += 7; + continue; /* with the next port */ + } + + /* + ** If the host board isn't running, then its data structures + ** are no use to us - continue quietly. + */ + if (PortP->HostP != HostP) { + port += 7; + continue; /* with the next port */ + } + + /* + ** Let us see - is the port open? If not, then don't service it. + */ + if (!(PortP->PortState & PORT_ISOPEN)) { + continue; + } + + rio_dprintk(RIO_DEBUG_INTR, "rio: Looking into port %d.\n", port); + /* + ** Lock the port before we begin working on it. + */ + rio_spin_lock(&PortP->portSem); + + /* + ** If we can't add anything to the transmit queue, then + ** we need do none of this processing. + */ + if (!can_add_transmit(&PacketP, PortP)) { + rio_dprintk(RIO_DEBUG_INTR, "Can't add to port, so skipping.\n"); + rio_spin_unlock(&PortP->portSem); + continue; + } + + /* + ** find corresponding tty structure. The process of mapping + ** the ports puts these here. + */ + ttyP = PortP->gs.port.tty; + /* If ttyP is NULL, the port is getting closed. Forget about it. */ + if (!ttyP) { + rio_dprintk(RIO_DEBUG_INTR, "no tty, so skipping.\n"); + rio_spin_unlock(&PortP->portSem); + continue; + } + /* + ** If there is more room available we start up the transmit + ** data process again. This can be direct I/O, if the cookmode + ** is set to COOK_RAW or COOK_MEDIUM, or will be a call to the + ** riotproc( T_OUTPUT ) if we are in COOK_WELL mode, to fetch + ** characters via the line discipline. We must always call + ** the line discipline, + ** so that user input characters can be echoed correctly. + ** + ** ++++ Update +++++ + ** With the advent of double buffering, we now see if + ** TxBufferOut-In is non-zero. If so, then we copy a packet + ** to the output place, and set it going. If this empties + ** the buffer, then we must issue a wakeup( ) on OUT. + ** If it frees space in the buffer then we must issue + ** a wakeup( ) on IN. + ** + ** ++++ Extra! Extra! If PortP->WflushFlag is set, then we + ** have to send a WFLUSH command down the PHB, to mark the + ** end point of a WFLUSH. We also need to clear out any + ** data from the double buffer! ( note that WflushFlag is a + ** *count* of the number of WFLUSH commands outstanding! ) + ** + ** ++++ And there's more! + ** If an RTA is powered off, then on again, and rebooted, + ** whilst it has ports open, then we need to re-open the ports. + ** ( reasonable enough ). We can't do this when we spot the + ** re-boot, in interrupt time, because the queue is probably + ** full. So, when we come in here, we need to test if any + ** ports are in this condition, and re-open the port before + ** we try to send any more data to it. Now, the re-booted + ** RTA will be discarding packets from the PHB until it + ** receives this open packet, but don't worry tooo much + ** about that. The one thing that is interesting is the + ** combination of this effect and the WFLUSH effect! + */ + /* For now don't handle RTA reboots. -- REW. + Reenabled. Otherwise RTA reboots didn't work. Duh. -- REW */ + if (PortP->MagicFlags) { + if (PortP->MagicFlags & MAGIC_REBOOT) { + /* + ** well, the RTA has been rebooted, and there is room + ** on its queue to add the open packet that is required. + ** + ** The messy part of this line is trying to decide if + ** we need to call the Param function as a tty or as + ** a modem. + ** DONT USE CLOCAL AS A TEST FOR THIS! + ** + ** If we can't param the port, then move on to the + ** next port. + */ + PortP->InUse = NOT_INUSE; + + rio_spin_unlock(&PortP->portSem); + if (RIOParam(PortP, RIOC_OPEN, ((PortP->Cor2Copy & (RIOC_COR2_RTSFLOW | RIOC_COR2_CTSFLOW)) == (RIOC_COR2_RTSFLOW | RIOC_COR2_CTSFLOW)) ? 1 : 0, DONT_SLEEP) == RIO_FAIL) + continue; /* with next port */ + rio_spin_lock(&PortP->portSem); + PortP->MagicFlags &= ~MAGIC_REBOOT; + } + + /* + ** As mentioned above, this is a tacky hack to cope + ** with WFLUSH + */ + if (PortP->WflushFlag) { + rio_dprintk(RIO_DEBUG_INTR, "Want to WFLUSH mark this port\n"); + + if (PortP->InUse) + rio_dprintk(RIO_DEBUG_INTR, "FAILS - PORT IS IN USE\n"); + } + + while (PortP->WflushFlag && can_add_transmit(&PacketP, PortP) && (PortP->InUse == NOT_INUSE)) { + int p; + struct PktCmd __iomem *PktCmdP; + + rio_dprintk(RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n"); + /* + ** make it look just like a WFLUSH command + */ + PktCmdP = (struct PktCmd __iomem *) &PacketP->data[0]; + + writeb(RIOC_WFLUSH, &PktCmdP->Command); + + p = PortP->HostPort % (u16) PORTS_PER_RTA; + + /* + ** If second block of ports for 16 port RTA, add 8 + ** to index 8-15. + */ + if (PortP->SecondBlock) + p += PORTS_PER_RTA; + + writeb(p, &PktCmdP->PhbNum); + + /* + ** to make debuggery easier + */ + writeb('W', &PacketP->data[2]); + writeb('F', &PacketP->data[3]); + writeb('L', &PacketP->data[4]); + writeb('U', &PacketP->data[5]); + writeb('S', &PacketP->data[6]); + writeb('H', &PacketP->data[7]); + writeb(' ', &PacketP->data[8]); + writeb('0' + PortP->WflushFlag, &PacketP->data[9]); + writeb(' ', &PacketP->data[10]); + writeb(' ', &PacketP->data[11]); + writeb('\0', &PacketP->data[12]); + + /* + ** its two bytes long! + */ + writeb(PKT_CMD_BIT | 2, &PacketP->len); + + /* + ** queue it! + */ + if (!(PortP->State & RIO_DELETED)) { + add_transmit(PortP); + /* + ** Count chars tx'd for port statistics reporting + */ + if (PortP->statsGather) + PortP->txchars += 2; + } + + if (--(PortP->WflushFlag) == 0) { + PortP->MagicFlags &= ~MAGIC_FLUSH; + } + + rio_dprintk(RIO_DEBUG_INTR, "Wflush count now stands at %d\n", PortP->WflushFlag); + } + if (PortP->MagicFlags & MORE_OUTPUT_EYGOR) { + if (PortP->MagicFlags & MAGIC_FLUSH) { + PortP->MagicFlags |= MORE_OUTPUT_EYGOR; + } else { + if (!can_add_transmit(&PacketP, PortP)) { + rio_spin_unlock(&PortP->portSem); + continue; + } + rio_spin_unlock(&PortP->portSem); + RIOTxEnable((char *) PortP); + rio_spin_lock(&PortP->portSem); + PortP->MagicFlags &= ~MORE_OUTPUT_EYGOR; + } + } + } + + + /* + ** If we can't add anything to the transmit queue, then + ** we need do none of the remaining processing. + */ + if (!can_add_transmit(&PacketP, PortP)) { + rio_spin_unlock(&PortP->portSem); + continue; + } + + rio_spin_unlock(&PortP->portSem); + RIOTxEnable((char *) PortP); + } + } +} + +/* +** Routine for handling received data for tty drivers +*/ +static void RIOReceive(struct rio_info *p, struct Port *PortP) +{ + struct tty_struct *TtyP; + unsigned short transCount; + struct PKT __iomem *PacketP; + register unsigned int DataCnt; + unsigned char __iomem *ptr; + unsigned char *buf; + int copied = 0; + + static int intCount, RxIntCnt; + + /* + ** The receive data process is to remove packets from the + ** PHB until there aren't any more or the current cblock + ** is full. When this occurs, there will be some left over + ** data in the packet, that we must do something with. + ** As we haven't unhooked the packet from the read list + ** yet, we can just leave the packet there, having first + ** made a note of how far we got. This means that we need + ** a pointer per port saying where we start taking the + ** data from - this will normally be zero, but when we + ** run out of space it will be set to the offset of the + ** next byte to copy from the packet data area. The packet + ** length field is decremented by the number of bytes that + ** we successfully removed from the packet. When this reaches + ** zero, we reset the offset pointer to be zero, and free + ** the packet from the front of the queue. + */ + + intCount++; + + TtyP = PortP->gs.port.tty; + if (!TtyP) { + rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: tty is null. \n"); + return; + } + + if (PortP->State & RIO_THROTTLE_RX) { + rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: Throttled. Can't handle more input.\n"); + return; + } + + if (PortP->State & RIO_DELETED) { + while (can_remove_receive(&PacketP, PortP)) { + remove_receive(PortP); + put_free_end(PortP->HostP, PacketP); + } + } else { + /* + ** loop, just so long as: + ** i ) there's some data ( i.e. can_remove_receive ) + ** ii ) we haven't been blocked + ** iii ) there's somewhere to put the data + ** iv ) we haven't outstayed our welcome + */ + transCount = 1; + while (can_remove_receive(&PacketP, PortP) + && transCount) { + RxIntCnt++; + + /* + ** check that it is not a command! + */ + if (readb(&PacketP->len) & PKT_CMD_BIT) { + rio_dprintk(RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n"); + /* rio_dprint(RIO_DEBUG_INTR, (" sysport = %d\n", p->RIOPortp->PortNum)); */ + rio_dprintk(RIO_DEBUG_INTR, " dest_unit = %d\n", readb(&PacketP->dest_unit)); + rio_dprintk(RIO_DEBUG_INTR, " dest_port = %d\n", readb(&PacketP->dest_port)); + rio_dprintk(RIO_DEBUG_INTR, " src_unit = %d\n", readb(&PacketP->src_unit)); + rio_dprintk(RIO_DEBUG_INTR, " src_port = %d\n", readb(&PacketP->src_port)); + rio_dprintk(RIO_DEBUG_INTR, " len = %d\n", readb(&PacketP->len)); + rio_dprintk(RIO_DEBUG_INTR, " control = %d\n", readb(&PacketP->control)); + rio_dprintk(RIO_DEBUG_INTR, " csum = %d\n", readw(&PacketP->csum)); + rio_dprintk(RIO_DEBUG_INTR, " data bytes: "); + for (DataCnt = 0; DataCnt < PKT_MAX_DATA_LEN; DataCnt++) + rio_dprintk(RIO_DEBUG_INTR, "%d\n", readb(&PacketP->data[DataCnt])); + remove_receive(PortP); + put_free_end(PortP->HostP, PacketP); + continue; /* with next packet */ + } + + /* + ** How many characters can we move 'upstream' ? + ** + ** Determine the minimum of the amount of data + ** available and the amount of space in which to + ** put it. + ** + ** 1. Get the packet length by masking 'len' + ** for only the length bits. + ** 2. Available space is [buffer size] - [space used] + ** + ** Transfer count is the minimum of packet length + ** and available space. + */ + + transCount = tty_buffer_request_room(TtyP, readb(&PacketP->len) & PKT_LEN_MASK); + rio_dprintk(RIO_DEBUG_REC, "port %d: Copy %d bytes\n", PortP->PortNum, transCount); + /* + ** To use the following 'kkprintfs' for debugging - change the '#undef' + ** to '#define', (this is the only place ___DEBUG_IT___ occurs in the + ** driver). + */ + ptr = (unsigned char __iomem *) PacketP->data + PortP->RxDataStart; + + tty_prepare_flip_string(TtyP, &buf, transCount); + rio_memcpy_fromio(buf, ptr, transCount); + PortP->RxDataStart += transCount; + writeb(readb(&PacketP->len)-transCount, &PacketP->len); + copied += transCount; + + + + if (readb(&PacketP->len) == 0) { + /* + ** If we have emptied the packet, then we can + ** free it, and reset the start pointer for + ** the next packet. + */ + remove_receive(PortP); + put_free_end(PortP->HostP, PacketP); + PortP->RxDataStart = 0; + } + } + } + if (copied) { + rio_dprintk(RIO_DEBUG_REC, "port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum, copied); + tty_flip_buffer_push(TtyP); + } + + return; +} + diff --git a/drivers/staging/generic_serial/rio/rioioctl.h b/drivers/staging/generic_serial/rio/rioioctl.h new file mode 100644 index 000000000000..e8af5b30519e --- /dev/null +++ b/drivers/staging/generic_serial/rio/rioioctl.h @@ -0,0 +1,57 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : rioioctl.h +** SID : 1.2 +** Last Modified : 11/6/98 11:34:13 +** Retrieved : 11/6/98 11:34:22 +** +** ident @(#)rioioctl.h 1.2 +** +** ----------------------------------------------------------------------------- +*/ + +#ifndef __rioioctl_h__ +#define __rioioctl_h__ + +/* +** RIO device driver - user ioctls and associated structures. +*/ + +struct portStats { + int port; + int gather; + unsigned long txchars; + unsigned long rxchars; + unsigned long opens; + unsigned long closes; + unsigned long ioctls; +}; + +#define RIOC ('R'<<8)|('i'<<16)|('o'<<24) + +#define RIO_QUICK_CHECK (RIOC | 105) +#define RIO_GATHER_PORT_STATS (RIOC | 193) +#define RIO_RESET_PORT_STATS (RIOC | 194) +#define RIO_GET_PORT_STATS (RIOC | 195) + +#endif /* __rioioctl_h__ */ diff --git a/drivers/staging/generic_serial/rio/rioparam.c b/drivers/staging/generic_serial/rio/rioparam.c new file mode 100644 index 000000000000..6415f3f32a72 --- /dev/null +++ b/drivers/staging/generic_serial/rio/rioparam.c @@ -0,0 +1,663 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : rioparam.c +** SID : 1.3 +** Last Modified : 11/6/98 10:33:45 +** Retrieved : 11/6/98 10:33:50 +** +** ident @(#)rioparam.c 1.3 +** +** ----------------------------------------------------------------------------- +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + + +#include "linux_compat.h" +#include "rio_linux.h" +#include "pkt.h" +#include "daemon.h" +#include "rio.h" +#include "riospace.h" +#include "cmdpkt.h" +#include "map.h" +#include "rup.h" +#include "port.h" +#include "riodrvr.h" +#include "rioinfo.h" +#include "func.h" +#include "errors.h" +#include "pci.h" + +#include "parmmap.h" +#include "unixrup.h" +#include "board.h" +#include "host.h" +#include "phb.h" +#include "link.h" +#include "cmdblk.h" +#include "route.h" +#include "cirrus.h" +#include "rioioctl.h" +#include "param.h" + + + +/* +** The Scam, based on email from jeremyr@bugs.specialix.co.uk.... +** +** To send a command on a particular port, you put a packet with the +** command bit set onto the port. The command bit is in the len field, +** and gets ORed in with the actual byte count. +** +** When you send a packet with the command bit set the first +** data byte (data[0]) is interpreted as the command to execute. +** It also governs what data structure overlay should accompany the packet. +** Commands are defined in cirrus/cirrus.h +** +** If you want the command to pre-emt data already on the queue for the +** port, set the pre-emptive bit in conjunction with the command bit. +** It is not defined what will happen if you set the preemptive bit +** on a packet that is NOT a command. +** +** Pre-emptive commands should be queued at the head of the queue using +** add_start(), whereas normal commands and data are enqueued using +** add_end(). +** +** Most commands do not use the remaining bytes in the data array. The +** exceptions are OPEN MOPEN and CONFIG. (NB. As with the SI CONFIG and +** OPEN are currently analogous). With these three commands the following +** 11 data bytes are all used to pass config information such as baud rate etc. +** The fields are also defined in cirrus.h. Some contain straightforward +** information such as the transmit XON character. Two contain the transmit and +** receive baud rates respectively. For most baud rates there is a direct +** mapping between the rates defined in and the byte in the +** packet. There are additional (non UNIX-standard) rates defined in +** /u/dos/rio/cirrus/h/brates.h. +** +** The rest of the data fields contain approximations to the Cirrus registers +** that are used to program number of bits etc. Each registers bit fields is +** defined in cirrus.h. +** +** NB. Only use those bits that are defined as being driver specific +** or common to the RTA and the driver. +** +** All commands going from RTA->Host will be dealt with by the Host code - you +** will never see them. As with the SI there will be three fields to look out +** for in each phb (not yet defined - needs defining a.s.a.p). +** +** modem_status - current state of handshake pins. +** +** port_status - current port status - equivalent to hi_stat for SI, indicates +** if port is IDLE_OPEN, IDLE_CLOSED etc. +** +** break_status - bit X set if break has been received. +** +** Happy hacking. +** +*/ + +/* +** RIOParam is used to open or configure a port. You pass it a PortP, +** which will have a tty struct attached to it. You also pass a command, +** either OPEN or CONFIG. The port's setup is taken from the t_ fields +** of the tty struct inside the PortP, and the port is either opened +** or re-configured. You must also tell RIOParam if the device is a modem +** device or not (i.e. top bit of minor number set or clear - take special +** care when deciding on this!). +** RIOParam neither flushes nor waits for drain, and is NOT preemptive. +** +** RIOParam assumes it will be called at splrio(), and also assumes +** that CookMode is set correctly in the port structure. +** +** NB. for MPX +** tty lock must NOT have been previously acquired. +*/ +int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag) +{ + struct tty_struct *TtyP; + int retval; + struct phb_param __iomem *phb_param_ptr; + struct PKT __iomem *PacketP; + int res; + u8 Cor1 = 0, Cor2 = 0, Cor4 = 0, Cor5 = 0; + u8 TxXon = 0, TxXoff = 0, RxXon = 0, RxXoff = 0; + u8 LNext = 0, TxBaud = 0, RxBaud = 0; + int retries = 0xff; + unsigned long flags; + + func_enter(); + + TtyP = PortP->gs.port.tty; + + rio_dprintk(RIO_DEBUG_PARAM, "RIOParam: Port:%d cmd:%d Modem:%d SleepFlag:%d Mapped: %d, tty=%p\n", PortP->PortNum, cmd, Modem, SleepFlag, PortP->Mapped, TtyP); + + if (!TtyP) { + rio_dprintk(RIO_DEBUG_PARAM, "Can't call rioparam with null tty.\n"); + + func_exit(); + + return RIO_FAIL; + } + rio_spin_lock_irqsave(&PortP->portSem, flags); + + if (cmd == RIOC_OPEN) { + /* + ** If the port is set to store or lock the parameters, and it is + ** paramed with OPEN, we want to restore the saved port termio, but + ** only if StoredTermio has been saved, i.e. NOT 1st open after reboot. + */ + } + + /* + ** wait for space + */ + while (!(res = can_add_transmit(&PacketP, PortP)) || (PortP->InUse != NOT_INUSE)) { + if (retries-- <= 0) { + break; + } + if (PortP->InUse != NOT_INUSE) { + rio_dprintk(RIO_DEBUG_PARAM, "Port IN_USE for pre-emptive command\n"); + } + + if (!res) { + rio_dprintk(RIO_DEBUG_PARAM, "Port has no space on transmit queue\n"); + } + + if (SleepFlag != OK_TO_SLEEP) { + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + func_exit(); + + return RIO_FAIL; + } + + rio_dprintk(RIO_DEBUG_PARAM, "wait for can_add_transmit\n"); + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + retval = RIODelay(PortP, HUNDRED_MS); + rio_spin_lock_irqsave(&PortP->portSem, flags); + if (retval == RIO_FAIL) { + rio_dprintk(RIO_DEBUG_PARAM, "wait for can_add_transmit broken by signal\n"); + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + func_exit(); + return -EINTR; + } + if (PortP->State & RIO_DELETED) { + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + func_exit(); + return 0; + } + } + + if (!res) { + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + func_exit(); + + return RIO_FAIL; + } + + rio_dprintk(RIO_DEBUG_PARAM, "can_add_transmit() returns %x\n", res); + rio_dprintk(RIO_DEBUG_PARAM, "Packet is %p\n", PacketP); + + phb_param_ptr = (struct phb_param __iomem *) PacketP->data; + + + switch (TtyP->termios->c_cflag & CSIZE) { + case CS5: + { + rio_dprintk(RIO_DEBUG_PARAM, "5 bit data\n"); + Cor1 |= RIOC_COR1_5BITS; + break; + } + case CS6: + { + rio_dprintk(RIO_DEBUG_PARAM, "6 bit data\n"); + Cor1 |= RIOC_COR1_6BITS; + break; + } + case CS7: + { + rio_dprintk(RIO_DEBUG_PARAM, "7 bit data\n"); + Cor1 |= RIOC_COR1_7BITS; + break; + } + case CS8: + { + rio_dprintk(RIO_DEBUG_PARAM, "8 bit data\n"); + Cor1 |= RIOC_COR1_8BITS; + break; + } + } + + if (TtyP->termios->c_cflag & CSTOPB) { + rio_dprintk(RIO_DEBUG_PARAM, "2 stop bits\n"); + Cor1 |= RIOC_COR1_2STOP; + } else { + rio_dprintk(RIO_DEBUG_PARAM, "1 stop bit\n"); + Cor1 |= RIOC_COR1_1STOP; + } + + if (TtyP->termios->c_cflag & PARENB) { + rio_dprintk(RIO_DEBUG_PARAM, "Enable parity\n"); + Cor1 |= RIOC_COR1_NORMAL; + } else { + rio_dprintk(RIO_DEBUG_PARAM, "Disable parity\n"); + Cor1 |= RIOC_COR1_NOP; + } + if (TtyP->termios->c_cflag & PARODD) { + rio_dprintk(RIO_DEBUG_PARAM, "Odd parity\n"); + Cor1 |= RIOC_COR1_ODD; + } else { + rio_dprintk(RIO_DEBUG_PARAM, "Even parity\n"); + Cor1 |= RIOC_COR1_EVEN; + } + + /* + ** COR 2 + */ + if (TtyP->termios->c_iflag & IXON) { + rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop output control\n"); + Cor2 |= RIOC_COR2_IXON; + } else { + if (PortP->Config & RIO_IXON) { + rio_dprintk(RIO_DEBUG_PARAM, "Force enable start/stop output control\n"); + Cor2 |= RIOC_COR2_IXON; + } else + rio_dprintk(RIO_DEBUG_PARAM, "IXON has been disabled.\n"); + } + + if (TtyP->termios->c_iflag & IXANY) { + if (PortP->Config & RIO_IXANY) { + rio_dprintk(RIO_DEBUG_PARAM, "Enable any key to restart output\n"); + Cor2 |= RIOC_COR2_IXANY; + } else + rio_dprintk(RIO_DEBUG_PARAM, "IXANY has been disabled due to sanity reasons.\n"); + } + + if (TtyP->termios->c_iflag & IXOFF) { + rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop input control 2\n"); + Cor2 |= RIOC_COR2_IXOFF; + } + + if (TtyP->termios->c_cflag & HUPCL) { + rio_dprintk(RIO_DEBUG_PARAM, "Hangup on last close\n"); + Cor2 |= RIOC_COR2_HUPCL; + } + + if (C_CRTSCTS(TtyP)) { + rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control enabled\n"); + Cor2 |= RIOC_COR2_CTSFLOW; + Cor2 |= RIOC_COR2_RTSFLOW; + } else { + rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control disabled\n"); + Cor2 &= ~RIOC_COR2_CTSFLOW; + Cor2 &= ~RIOC_COR2_RTSFLOW; + } + + + if (TtyP->termios->c_cflag & CLOCAL) { + rio_dprintk(RIO_DEBUG_PARAM, "Local line\n"); + } else { + rio_dprintk(RIO_DEBUG_PARAM, "Possible Modem line\n"); + } + + /* + ** COR 4 (there is no COR 3) + */ + if (TtyP->termios->c_iflag & IGNBRK) { + rio_dprintk(RIO_DEBUG_PARAM, "Ignore break condition\n"); + Cor4 |= RIOC_COR4_IGNBRK; + } + if (!(TtyP->termios->c_iflag & BRKINT)) { + rio_dprintk(RIO_DEBUG_PARAM, "Break generates NULL condition\n"); + Cor4 |= RIOC_COR4_NBRKINT; + } else { + rio_dprintk(RIO_DEBUG_PARAM, "Interrupt on break condition\n"); + } + + if (TtyP->termios->c_iflag & INLCR) { + rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage return on input\n"); + Cor4 |= RIOC_COR4_INLCR; + } + + if (TtyP->termios->c_iflag & IGNCR) { + rio_dprintk(RIO_DEBUG_PARAM, "Ignore carriage return on input\n"); + Cor4 |= RIOC_COR4_IGNCR; + } + + if (TtyP->termios->c_iflag & ICRNL) { + rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on input\n"); + Cor4 |= RIOC_COR4_ICRNL; + } + if (TtyP->termios->c_iflag & IGNPAR) { + rio_dprintk(RIO_DEBUG_PARAM, "Ignore characters with parity errors\n"); + Cor4 |= RIOC_COR4_IGNPAR; + } + if (TtyP->termios->c_iflag & PARMRK) { + rio_dprintk(RIO_DEBUG_PARAM, "Mark parity errors\n"); + Cor4 |= RIOC_COR4_PARMRK; + } + + /* + ** Set the RAISEMOD flag to ensure that the modem lines are raised + ** on reception of a config packet. + ** The download code handles the zero baud condition. + */ + Cor4 |= RIOC_COR4_RAISEMOD; + + /* + ** COR 5 + */ + + Cor5 = RIOC_COR5_CMOE; + + /* + ** Set to monitor tbusy/tstop (or not). + */ + + if (PortP->MonitorTstate) + Cor5 |= RIOC_COR5_TSTATE_ON; + else + Cor5 |= RIOC_COR5_TSTATE_OFF; + + /* + ** Could set LNE here if you wanted LNext processing. SVR4 will use it. + */ + if (TtyP->termios->c_iflag & ISTRIP) { + rio_dprintk(RIO_DEBUG_PARAM, "Strip input characters\n"); + if (!(PortP->State & RIO_TRIAD_MODE)) { + Cor5 |= RIOC_COR5_ISTRIP; + } + } + + if (TtyP->termios->c_oflag & ONLCR) { + rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage-return, newline on output\n"); + if (PortP->CookMode == COOK_MEDIUM) + Cor5 |= RIOC_COR5_ONLCR; + } + if (TtyP->termios->c_oflag & OCRNL) { + rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on output\n"); + if (PortP->CookMode == COOK_MEDIUM) + Cor5 |= RIOC_COR5_OCRNL; + } + if ((TtyP->termios->c_oflag & TABDLY) == TAB3) { + rio_dprintk(RIO_DEBUG_PARAM, "Tab delay 3 set\n"); + if (PortP->CookMode == COOK_MEDIUM) + Cor5 |= RIOC_COR5_TAB3; + } + + /* + ** Flow control bytes. + */ + TxXon = TtyP->termios->c_cc[VSTART]; + TxXoff = TtyP->termios->c_cc[VSTOP]; + RxXon = TtyP->termios->c_cc[VSTART]; + RxXoff = TtyP->termios->c_cc[VSTOP]; + /* + ** LNEXT byte + */ + LNext = 0; + + /* + ** Baud rate bytes + */ + rio_dprintk(RIO_DEBUG_PARAM, "Mapping of rx/tx baud %x (%x)\n", TtyP->termios->c_cflag, CBAUD); + + switch (TtyP->termios->c_cflag & CBAUD) { +#define e(b) case B ## b : RxBaud = TxBaud = RIO_B ## b ;break + e(50); + e(75); + e(110); + e(134); + e(150); + e(200); + e(300); + e(600); + e(1200); + e(1800); + e(2400); + e(4800); + e(9600); + e(19200); + e(38400); + e(57600); + e(115200); /* e(230400);e(460800); e(921600); */ + } + + rio_dprintk(RIO_DEBUG_PARAM, "tx baud 0x%x, rx baud 0x%x\n", TxBaud, RxBaud); + + + /* + ** Leftovers + */ + if (TtyP->termios->c_cflag & CREAD) + rio_dprintk(RIO_DEBUG_PARAM, "Enable receiver\n"); +#ifdef RCV1EN + if (TtyP->termios->c_cflag & RCV1EN) + rio_dprintk(RIO_DEBUG_PARAM, "RCV1EN (?)\n"); +#endif +#ifdef XMT1EN + if (TtyP->termios->c_cflag & XMT1EN) + rio_dprintk(RIO_DEBUG_PARAM, "XMT1EN (?)\n"); +#endif + if (TtyP->termios->c_lflag & ISIG) + rio_dprintk(RIO_DEBUG_PARAM, "Input character signal generating enabled\n"); + if (TtyP->termios->c_lflag & ICANON) + rio_dprintk(RIO_DEBUG_PARAM, "Canonical input: erase and kill enabled\n"); + if (TtyP->termios->c_lflag & XCASE) + rio_dprintk(RIO_DEBUG_PARAM, "Canonical upper/lower presentation\n"); + if (TtyP->termios->c_lflag & ECHO) + rio_dprintk(RIO_DEBUG_PARAM, "Enable input echo\n"); + if (TtyP->termios->c_lflag & ECHOE) + rio_dprintk(RIO_DEBUG_PARAM, "Enable echo erase\n"); + if (TtyP->termios->c_lflag & ECHOK) + rio_dprintk(RIO_DEBUG_PARAM, "Enable echo kill\n"); + if (TtyP->termios->c_lflag & ECHONL) + rio_dprintk(RIO_DEBUG_PARAM, "Enable echo newline\n"); + if (TtyP->termios->c_lflag & NOFLSH) + rio_dprintk(RIO_DEBUG_PARAM, "Disable flush after interrupt or quit\n"); +#ifdef TOSTOP + if (TtyP->termios->c_lflag & TOSTOP) + rio_dprintk(RIO_DEBUG_PARAM, "Send SIGTTOU for background output\n"); +#endif +#ifdef XCLUDE + if (TtyP->termios->c_lflag & XCLUDE) + rio_dprintk(RIO_DEBUG_PARAM, "Exclusive use of this line\n"); +#endif + if (TtyP->termios->c_iflag & IUCLC) + rio_dprintk(RIO_DEBUG_PARAM, "Map uppercase to lowercase on input\n"); + if (TtyP->termios->c_oflag & OPOST) + rio_dprintk(RIO_DEBUG_PARAM, "Enable output post-processing\n"); + if (TtyP->termios->c_oflag & OLCUC) + rio_dprintk(RIO_DEBUG_PARAM, "Map lowercase to uppercase on output\n"); + if (TtyP->termios->c_oflag & ONOCR) + rio_dprintk(RIO_DEBUG_PARAM, "No carriage return output at column 0\n"); + if (TtyP->termios->c_oflag & ONLRET) + rio_dprintk(RIO_DEBUG_PARAM, "Newline performs carriage return function\n"); + if (TtyP->termios->c_oflag & OFILL) + rio_dprintk(RIO_DEBUG_PARAM, "Use fill characters for delay\n"); + if (TtyP->termios->c_oflag & OFDEL) + rio_dprintk(RIO_DEBUG_PARAM, "Fill character is DEL\n"); + if (TtyP->termios->c_oflag & NLDLY) + rio_dprintk(RIO_DEBUG_PARAM, "Newline delay set\n"); + if (TtyP->termios->c_oflag & CRDLY) + rio_dprintk(RIO_DEBUG_PARAM, "Carriage return delay set\n"); + if (TtyP->termios->c_oflag & TABDLY) + rio_dprintk(RIO_DEBUG_PARAM, "Tab delay set\n"); + /* + ** These things are kind of useful in a later life! + */ + PortP->Cor2Copy = Cor2; + + if (PortP->State & RIO_DELETED) { + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + func_exit(); + + return RIO_FAIL; + } + + /* + ** Actually write the info into the packet to be sent + */ + writeb(cmd, &phb_param_ptr->Cmd); + writeb(Cor1, &phb_param_ptr->Cor1); + writeb(Cor2, &phb_param_ptr->Cor2); + writeb(Cor4, &phb_param_ptr->Cor4); + writeb(Cor5, &phb_param_ptr->Cor5); + writeb(TxXon, &phb_param_ptr->TxXon); + writeb(RxXon, &phb_param_ptr->RxXon); + writeb(TxXoff, &phb_param_ptr->TxXoff); + writeb(RxXoff, &phb_param_ptr->RxXoff); + writeb(LNext, &phb_param_ptr->LNext); + writeb(TxBaud, &phb_param_ptr->TxBaud); + writeb(RxBaud, &phb_param_ptr->RxBaud); + + /* + ** Set the length/command field + */ + writeb(12 | PKT_CMD_BIT, &PacketP->len); + + /* + ** The packet is formed - now, whack it off + ** to its final destination: + */ + add_transmit(PortP); + /* + ** Count characters transmitted for port statistics reporting + */ + if (PortP->statsGather) + PortP->txchars += 12; + + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + + rio_dprintk(RIO_DEBUG_PARAM, "add_transmit returned.\n"); + /* + ** job done. + */ + func_exit(); + + return 0; +} + + +/* +** We can add another packet to a transmit queue if the packet pointer pointed +** to by the TxAdd pointer has PKT_IN_USE clear in its address. +*/ +int can_add_transmit(struct PKT __iomem **PktP, struct Port *PortP) +{ + struct PKT __iomem *tp; + + *PktP = tp = (struct PKT __iomem *) RIO_PTR(PortP->Caddr, readw(PortP->TxAdd)); + + return !((unsigned long) tp & PKT_IN_USE); +} + +/* +** To add a packet to the queue, you set the PKT_IN_USE bit in the address, +** and then move the TxAdd pointer along one position to point to the next +** packet pointer. You must wrap the pointer from the end back to the start. +*/ +void add_transmit(struct Port *PortP) +{ + if (readw(PortP->TxAdd) & PKT_IN_USE) { + rio_dprintk(RIO_DEBUG_PARAM, "add_transmit: Packet has been stolen!"); + } + writew(readw(PortP->TxAdd) | PKT_IN_USE, PortP->TxAdd); + PortP->TxAdd = (PortP->TxAdd == PortP->TxEnd) ? PortP->TxStart : PortP->TxAdd + 1; + writew(RIO_OFF(PortP->Caddr, PortP->TxAdd), &PortP->PhbP->tx_add); +} + +/**************************************** + * Put a packet onto the end of the + * free list + ****************************************/ +void put_free_end(struct Host *HostP, struct PKT __iomem *PktP) +{ + struct rio_free_list __iomem *tmp_pointer; + unsigned short old_end, new_end; + unsigned long flags; + + rio_spin_lock_irqsave(&HostP->HostLock, flags); + + /************************************************* + * Put a packet back onto the back of the free list + * + ************************************************/ + + rio_dprintk(RIO_DEBUG_PFE, "put_free_end(PktP=%p)\n", PktP); + + if ((old_end = readw(&HostP->ParmMapP->free_list_end)) != TPNULL) { + new_end = RIO_OFF(HostP->Caddr, PktP); + tmp_pointer = (struct rio_free_list __iomem *) RIO_PTR(HostP->Caddr, old_end); + writew(new_end, &tmp_pointer->next); + writew(old_end, &((struct rio_free_list __iomem *) PktP)->prev); + writew(TPNULL, &((struct rio_free_list __iomem *) PktP)->next); + writew(new_end, &HostP->ParmMapP->free_list_end); + } else { /* First packet on the free list this should never happen! */ + rio_dprintk(RIO_DEBUG_PFE, "put_free_end(): This should never happen\n"); + writew(RIO_OFF(HostP->Caddr, PktP), &HostP->ParmMapP->free_list_end); + tmp_pointer = (struct rio_free_list __iomem *) PktP; + writew(TPNULL, &tmp_pointer->prev); + writew(TPNULL, &tmp_pointer->next); + } + rio_dprintk(RIO_DEBUG_CMD, "Before unlock: %p\n", &HostP->HostLock); + rio_spin_unlock_irqrestore(&HostP->HostLock, flags); +} + +/* +** can_remove_receive(PktP,P) returns non-zero if PKT_IN_USE is set +** for the next packet on the queue. It will also set PktP to point to the +** relevant packet, [having cleared the PKT_IN_USE bit]. If PKT_IN_USE is clear, +** then can_remove_receive() returns 0. +*/ +int can_remove_receive(struct PKT __iomem **PktP, struct Port *PortP) +{ + if (readw(PortP->RxRemove) & PKT_IN_USE) { + *PktP = (struct PKT __iomem *) RIO_PTR(PortP->Caddr, readw(PortP->RxRemove) & ~PKT_IN_USE); + return 1; + } + return 0; +} + +/* +** To remove a packet from the receive queue you clear its PKT_IN_USE bit, +** and then bump the pointers. Once the pointers get to the end, they must +** be wrapped back to the start. +*/ +void remove_receive(struct Port *PortP) +{ + writew(readw(PortP->RxRemove) & ~PKT_IN_USE, PortP->RxRemove); + PortP->RxRemove = (PortP->RxRemove == PortP->RxEnd) ? PortP->RxStart : PortP->RxRemove + 1; + writew(RIO_OFF(PortP->Caddr, PortP->RxRemove), &PortP->PhbP->rx_remove); +} diff --git a/drivers/staging/generic_serial/rio/rioroute.c b/drivers/staging/generic_serial/rio/rioroute.c new file mode 100644 index 000000000000..f9b936ac3394 --- /dev/null +++ b/drivers/staging/generic_serial/rio/rioroute.c @@ -0,0 +1,1039 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : rioroute.c +** SID : 1.3 +** Last Modified : 11/6/98 10:33:46 +** Retrieved : 11/6/98 10:33:50 +** +** ident @(#)rioroute.c 1.3 +** +** ----------------------------------------------------------------------------- +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + + +#include "linux_compat.h" +#include "rio_linux.h" +#include "pkt.h" +#include "daemon.h" +#include "rio.h" +#include "riospace.h" +#include "cmdpkt.h" +#include "map.h" +#include "rup.h" +#include "port.h" +#include "riodrvr.h" +#include "rioinfo.h" +#include "func.h" +#include "errors.h" +#include "pci.h" + +#include "parmmap.h" +#include "unixrup.h" +#include "board.h" +#include "host.h" +#include "phb.h" +#include "link.h" +#include "cmdblk.h" +#include "route.h" +#include "cirrus.h" +#include "rioioctl.h" +#include "param.h" + +static int RIOCheckIsolated(struct rio_info *, struct Host *, unsigned int); +static int RIOIsolate(struct rio_info *, struct Host *, unsigned int); +static int RIOCheck(struct Host *, unsigned int); +static void RIOConCon(struct rio_info *, struct Host *, unsigned int, unsigned int, unsigned int, unsigned int, int); + + +/* +** Incoming on the ROUTE_RUP +** I wrote this while I was tired. Forgive me. +*/ +int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct PKT __iomem * PacketP) +{ + struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *) PacketP->data; + struct PktCmd_M *PktReplyP; + struct CmdBlk *CmdBlkP; + struct Port *PortP; + struct Map *MapP; + struct Top *TopP; + int ThisLink, ThisLinkMin, ThisLinkMax; + int port; + int Mod, Mod1, Mod2; + unsigned short RtaType; + unsigned int RtaUniq; + unsigned int ThisUnit, ThisUnit2; /* 2 ids to accommodate 16 port RTA */ + unsigned int OldUnit, NewUnit, OldLink, NewLink; + char *MyType, *MyName; + int Lies; + unsigned long flags; + + /* + ** Is this unit telling us it's current link topology? + */ + if (readb(&PktCmdP->Command) == ROUTE_TOPOLOGY) { + MapP = HostP->Mapping; + + /* + ** The packet can be sent either by the host or by an RTA. + ** If it comes from the host, then we need to fill in the + ** Topology array in the host structure. If it came in + ** from an RTA then we need to fill in the Mapping structure's + ** Topology array for the unit. + */ + if (Rup >= (unsigned short) MAX_RUP) { + ThisUnit = HOST_ID; + TopP = HostP->Topology; + MyType = "Host"; + MyName = HostP->Name; + ThisLinkMin = ThisLinkMax = Rup - MAX_RUP; + } else { + ThisUnit = Rup + 1; + TopP = HostP->Mapping[Rup].Topology; + MyType = "RTA"; + MyName = HostP->Mapping[Rup].Name; + ThisLinkMin = 0; + ThisLinkMax = LINKS_PER_UNIT - 1; + } + + /* + ** Lies will not be tolerated. + ** If any pair of links claim to be connected to the same + ** place, then ignore this packet completely. + */ + Lies = 0; + for (ThisLink = ThisLinkMin + 1; ThisLink <= ThisLinkMax; ThisLink++) { + /* + ** it won't lie about network interconnect, total disconnects + ** and no-IDs. (or at least, it doesn't *matter* if it does) + */ + if (readb(&PktCmdP->RouteTopology[ThisLink].Unit) > (unsigned short) MAX_RUP) + continue; + + for (NewLink = ThisLinkMin; NewLink < ThisLink; NewLink++) { + if ((readb(&PktCmdP->RouteTopology[ThisLink].Unit) == readb(&PktCmdP->RouteTopology[NewLink].Unit)) && (readb(&PktCmdP->RouteTopology[ThisLink].Link) == readb(&PktCmdP->RouteTopology[NewLink].Link))) { + Lies++; + } + } + } + + if (Lies) { + rio_dprintk(RIO_DEBUG_ROUTE, "LIES! DAMN LIES! %d LIES!\n", Lies); + rio_dprintk(RIO_DEBUG_ROUTE, "%d:%c %d:%c %d:%c %d:%c\n", + readb(&PktCmdP->RouteTopology[0].Unit), + 'A' + readb(&PktCmdP->RouteTopology[0].Link), + readb(&PktCmdP->RouteTopology[1].Unit), + 'A' + readb(&PktCmdP->RouteTopology[1].Link), readb(&PktCmdP->RouteTopology[2].Unit), 'A' + readb(&PktCmdP->RouteTopology[2].Link), readb(&PktCmdP->RouteTopology[3].Unit), 'A' + readb(&PktCmdP->RouteTopology[3].Link)); + return 1; + } + + /* + ** now, process each link. + */ + for (ThisLink = ThisLinkMin; ThisLink <= ThisLinkMax; ThisLink++) { + /* + ** this is what it was connected to + */ + OldUnit = TopP[ThisLink].Unit; + OldLink = TopP[ThisLink].Link; + + /* + ** this is what it is now connected to + */ + NewUnit = readb(&PktCmdP->RouteTopology[ThisLink].Unit); + NewLink = readb(&PktCmdP->RouteTopology[ThisLink].Link); + + if (OldUnit != NewUnit || OldLink != NewLink) { + /* + ** something has changed! + */ + + if (NewUnit > MAX_RUP && NewUnit != ROUTE_DISCONNECT && NewUnit != ROUTE_NO_ID && NewUnit != ROUTE_INTERCONNECT) { + rio_dprintk(RIO_DEBUG_ROUTE, "I have a link from %s %s to unit %d:%d - I don't like it.\n", MyType, MyName, NewUnit, NewLink); + } else { + /* + ** put the new values in + */ + TopP[ThisLink].Unit = NewUnit; + TopP[ThisLink].Link = NewLink; + + RIOSetChange(p); + + if (OldUnit <= MAX_RUP) { + /* + ** If something has become bust, then re-enable them messages + */ + if (!p->RIONoMessage) + RIOConCon(p, HostP, ThisUnit, ThisLink, OldUnit, OldLink, DISCONNECT); + } + + if ((NewUnit <= MAX_RUP) && !p->RIONoMessage) + RIOConCon(p, HostP, ThisUnit, ThisLink, NewUnit, NewLink, CONNECT); + + if (NewUnit == ROUTE_NO_ID) + rio_dprintk(RIO_DEBUG_ROUTE, "%s %s (%c) is connected to an unconfigured unit.\n", MyType, MyName, 'A' + ThisLink); + + if (NewUnit == ROUTE_INTERCONNECT) { + if (!p->RIONoMessage) + printk(KERN_DEBUG "rio: %s '%s' (%c) is connected to another network.\n", MyType, MyName, 'A' + ThisLink); + } + + /* + ** perform an update for 'the other end', so that these messages + ** only appears once. Only disconnect the other end if it is pointing + ** at us! + */ + if (OldUnit == HOST_ID) { + if (HostP->Topology[OldLink].Unit == ThisUnit && HostP->Topology[OldLink].Link == ThisLink) { + rio_dprintk(RIO_DEBUG_ROUTE, "SETTING HOST (%c) TO DISCONNECTED!\n", OldLink + 'A'); + HostP->Topology[OldLink].Unit = ROUTE_DISCONNECT; + HostP->Topology[OldLink].Link = NO_LINK; + } else { + rio_dprintk(RIO_DEBUG_ROUTE, "HOST(%c) WAS NOT CONNECTED TO %s (%c)!\n", OldLink + 'A', HostP->Mapping[ThisUnit - 1].Name, ThisLink + 'A'); + } + } else if (OldUnit <= MAX_RUP) { + if (HostP->Mapping[OldUnit - 1].Topology[OldLink].Unit == ThisUnit && HostP->Mapping[OldUnit - 1].Topology[OldLink].Link == ThisLink) { + rio_dprintk(RIO_DEBUG_ROUTE, "SETTING RTA %s (%c) TO DISCONNECTED!\n", HostP->Mapping[OldUnit - 1].Name, OldLink + 'A'); + HostP->Mapping[OldUnit - 1].Topology[OldLink].Unit = ROUTE_DISCONNECT; + HostP->Mapping[OldUnit - 1].Topology[OldLink].Link = NO_LINK; + } else { + rio_dprintk(RIO_DEBUG_ROUTE, "RTA %s (%c) WAS NOT CONNECTED TO %s (%c)\n", HostP->Mapping[OldUnit - 1].Name, OldLink + 'A', HostP->Mapping[ThisUnit - 1].Name, ThisLink + 'A'); + } + } + if (NewUnit == HOST_ID) { + rio_dprintk(RIO_DEBUG_ROUTE, "MARKING HOST (%c) CONNECTED TO %s (%c)\n", NewLink + 'A', MyName, ThisLink + 'A'); + HostP->Topology[NewLink].Unit = ThisUnit; + HostP->Topology[NewLink].Link = ThisLink; + } else if (NewUnit <= MAX_RUP) { + rio_dprintk(RIO_DEBUG_ROUTE, "MARKING RTA %s (%c) CONNECTED TO %s (%c)\n", HostP->Mapping[NewUnit - 1].Name, NewLink + 'A', MyName, ThisLink + 'A'); + HostP->Mapping[NewUnit - 1].Topology[NewLink].Unit = ThisUnit; + HostP->Mapping[NewUnit - 1].Topology[NewLink].Link = ThisLink; + } + } + RIOSetChange(p); + RIOCheckIsolated(p, HostP, OldUnit); + } + } + return 1; + } + + /* + ** The only other command we recognise is a route_request command + */ + if (readb(&PktCmdP->Command) != ROUTE_REQUEST) { + rio_dprintk(RIO_DEBUG_ROUTE, "Unknown command %d received on rup %d host %p ROUTE_RUP\n", readb(&PktCmdP->Command), Rup, HostP); + return 1; + } + + RtaUniq = (readb(&PktCmdP->UniqNum[0])) + (readb(&PktCmdP->UniqNum[1]) << 8) + (readb(&PktCmdP->UniqNum[2]) << 16) + (readb(&PktCmdP->UniqNum[3]) << 24); + + /* + ** Determine if 8 or 16 port RTA + */ + RtaType = GetUnitType(RtaUniq); + + rio_dprintk(RIO_DEBUG_ROUTE, "Received a request for an ID for serial number %x\n", RtaUniq); + + Mod = readb(&PktCmdP->ModuleTypes); + Mod1 = LONYBLE(Mod); + if (RtaType == TYPE_RTA16) { + /* + ** Only one ident is set for a 16 port RTA. To make compatible + ** with 8 port, set 2nd ident in Mod2 to the same as Mod1. + */ + Mod2 = Mod1; + rio_dprintk(RIO_DEBUG_ROUTE, "Backplane type is %s (all ports)\n", p->RIOModuleTypes[Mod1].Name); + } else { + Mod2 = HINYBLE(Mod); + rio_dprintk(RIO_DEBUG_ROUTE, "Module types are %s (ports 0-3) and %s (ports 4-7)\n", p->RIOModuleTypes[Mod1].Name, p->RIOModuleTypes[Mod2].Name); + } + + /* + ** try to unhook a command block from the command free list. + */ + if (!(CmdBlkP = RIOGetCmdBlk())) { + rio_dprintk(RIO_DEBUG_ROUTE, "No command blocks to route RTA! come back later.\n"); + return 0; + } + + /* + ** Fill in the default info on the command block + */ + CmdBlkP->Packet.dest_unit = Rup; + CmdBlkP->Packet.dest_port = ROUTE_RUP; + CmdBlkP->Packet.src_unit = HOST_ID; + CmdBlkP->Packet.src_port = ROUTE_RUP; + CmdBlkP->Packet.len = PKT_CMD_BIT | 1; + CmdBlkP->PreFuncP = CmdBlkP->PostFuncP = NULL; + PktReplyP = (struct PktCmd_M *) CmdBlkP->Packet.data; + + if (!RIOBootOk(p, HostP, RtaUniq)) { + rio_dprintk(RIO_DEBUG_ROUTE, "RTA %x tried to get an ID, but does not belong - FOAD it!\n", RtaUniq); + PktReplyP->Command = ROUTE_FOAD; + memcpy(PktReplyP->CommandText, "RT_FOAD", 7); + RIOQueueCmdBlk(HostP, Rup, CmdBlkP); + return 1; + } + + /* + ** Check to see if the RTA is configured for this host + */ + for (ThisUnit = 0; ThisUnit < MAX_RUP; ThisUnit++) { + rio_dprintk(RIO_DEBUG_ROUTE, "Entry %d Flags=%s %s UniqueNum=0x%x\n", + ThisUnit, HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE ? "Slot-In-Use" : "Not In Use", HostP->Mapping[ThisUnit].Flags & SLOT_TENTATIVE ? "Slot-Tentative" : "Not Tentative", HostP->Mapping[ThisUnit].RtaUniqueNum); + + /* + ** We have an entry for it. + */ + if ((HostP->Mapping[ThisUnit].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) && (HostP->Mapping[ThisUnit].RtaUniqueNum == RtaUniq)) { + if (RtaType == TYPE_RTA16) { + ThisUnit2 = HostP->Mapping[ThisUnit].ID2 - 1; + rio_dprintk(RIO_DEBUG_ROUTE, "Found unit 0x%x at slots %d+%d\n", RtaUniq, ThisUnit, ThisUnit2); + } else + rio_dprintk(RIO_DEBUG_ROUTE, "Found unit 0x%x at slot %d\n", RtaUniq, ThisUnit); + /* + ** If we have no knowledge of booting it, then the host has + ** been re-booted, and so we must kill the RTA, so that it + ** will be booted again (potentially with new bins) + ** and it will then re-ask for an ID, which we will service. + */ + if ((HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE) && !(HostP->Mapping[ThisUnit].Flags & RTA_BOOTED)) { + if (!(HostP->Mapping[ThisUnit].Flags & MSG_DONE)) { + if (!p->RIONoMessage) + printk(KERN_DEBUG "rio: RTA '%s' is being updated.\n", HostP->Mapping[ThisUnit].Name); + HostP->Mapping[ThisUnit].Flags |= MSG_DONE; + } + PktReplyP->Command = ROUTE_FOAD; + memcpy(PktReplyP->CommandText, "RT_FOAD", 7); + RIOQueueCmdBlk(HostP, Rup, CmdBlkP); + return 1; + } + + /* + ** Send the ID (entry) to this RTA. The ID number is implicit as + ** the offset into the table. It is worth noting at this stage + ** that offset zero in the table contains the entries for the + ** RTA with ID 1!!!! + */ + PktReplyP->Command = ROUTE_ALLOCATE; + PktReplyP->IDNum = ThisUnit + 1; + if (RtaType == TYPE_RTA16) { + if (HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE) + /* + ** Adjust the phb and tx pkt dest_units for 2nd block of 8 + ** only if the RTA has ports associated (SLOT_IN_USE) + */ + RIOFixPhbs(p, HostP, ThisUnit2); + PktReplyP->IDNum2 = ThisUnit2 + 1; + rio_dprintk(RIO_DEBUG_ROUTE, "RTA '%s' has been allocated IDs %d+%d\n", HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum, PktReplyP->IDNum2); + } else { + PktReplyP->IDNum2 = ROUTE_NO_ID; + rio_dprintk(RIO_DEBUG_ROUTE, "RTA '%s' has been allocated ID %d\n", HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum); + } + memcpy(PktReplyP->CommandText, "RT_ALLOCAT", 10); + + RIOQueueCmdBlk(HostP, Rup, CmdBlkP); + + /* + ** If this is a freshly booted RTA, then we need to re-open + ** the ports, if any where open, so that data may once more + ** flow around the system! + */ + if ((HostP->Mapping[ThisUnit].Flags & RTA_NEWBOOT) && (HostP->Mapping[ThisUnit].SysPort != NO_PORT)) { + /* + ** look at the ports associated with this beast and + ** see if any where open. If they was, then re-open + ** them, using the info from the tty flags. + */ + for (port = 0; port < PORTS_PER_RTA; port++) { + PortP = p->RIOPortp[port + HostP->Mapping[ThisUnit].SysPort]; + if (PortP->State & (RIO_MOPEN | RIO_LOPEN)) { + rio_dprintk(RIO_DEBUG_ROUTE, "Re-opened this port\n"); + rio_spin_lock_irqsave(&PortP->portSem, flags); + PortP->MagicFlags |= MAGIC_REBOOT; + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + } + } + if (RtaType == TYPE_RTA16) { + for (port = 0; port < PORTS_PER_RTA; port++) { + PortP = p->RIOPortp[port + HostP->Mapping[ThisUnit2].SysPort]; + if (PortP->State & (RIO_MOPEN | RIO_LOPEN)) { + rio_dprintk(RIO_DEBUG_ROUTE, "Re-opened this port\n"); + rio_spin_lock_irqsave(&PortP->portSem, flags); + PortP->MagicFlags |= MAGIC_REBOOT; + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + } + } + } + } + + /* + ** keep a copy of the module types! + */ + HostP->UnixRups[ThisUnit].ModTypes = Mod; + if (RtaType == TYPE_RTA16) + HostP->UnixRups[ThisUnit2].ModTypes = Mod; + + /* + ** If either of the modules on this unit is read-only or write-only + ** or none-xprint, then we need to transfer that info over to the + ** relevant ports. + */ + if (HostP->Mapping[ThisUnit].SysPort != NO_PORT) { + for (port = 0; port < PORTS_PER_MODULE; port++) { + p->RIOPortp[port + HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK; + p->RIOPortp[port + HostP->Mapping[ThisUnit].SysPort]->Config |= p->RIOModuleTypes[Mod1].Flags[port]; + p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK; + p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port]; + } + if (RtaType == TYPE_RTA16) { + for (port = 0; port < PORTS_PER_MODULE; port++) { + p->RIOPortp[port + HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK; + p->RIOPortp[port + HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod1].Flags[port]; + p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK; + p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port]; + } + } + } + + /* + ** Job done, get on with the interrupts! + */ + return 1; + } + } + /* + ** There is no table entry for this RTA at all. + ** + ** Lets check to see if we actually booted this unit - if not, + ** then we reset it and it will go round the loop of being booted + ** we can then worry about trying to fit it into the table. + */ + for (ThisUnit = 0; ThisUnit < HostP->NumExtraBooted; ThisUnit++) + if (HostP->ExtraUnits[ThisUnit] == RtaUniq) + break; + if (ThisUnit == HostP->NumExtraBooted && ThisUnit != MAX_EXTRA_UNITS) { + /* + ** if the unit wasn't in the table, and the table wasn't full, then + ** we reset the unit, because we didn't boot it. + ** However, if the table is full, it could be that we did boot + ** this unit, and so we won't reboot it, because it isn't really + ** all that disasterous to keep the old bins in most cases. This + ** is a rather tacky feature, but we are on the edge of reallity + ** here, because the implication is that someone has connected + ** 16+MAX_EXTRA_UNITS onto one host. + */ + static int UnknownMesgDone = 0; + + if (!UnknownMesgDone) { + if (!p->RIONoMessage) + printk(KERN_DEBUG "rio: One or more unknown RTAs are being updated.\n"); + UnknownMesgDone = 1; + } + + PktReplyP->Command = ROUTE_FOAD; + memcpy(PktReplyP->CommandText, "RT_FOAD", 7); + } else { + /* + ** we did boot it (as an extra), and there may now be a table + ** slot free (because of a delete), so we will try to make + ** a tentative entry for it, so that the configurator can see it + ** and fill in the details for us. + */ + if (RtaType == TYPE_RTA16) { + if (RIOFindFreeID(p, HostP, &ThisUnit, &ThisUnit2) == 0) { + RIODefaultName(p, HostP, ThisUnit); + rio_fill_host_slot(ThisUnit, ThisUnit2, RtaUniq, HostP); + } + } else { + if (RIOFindFreeID(p, HostP, &ThisUnit, NULL) == 0) { + RIODefaultName(p, HostP, ThisUnit); + rio_fill_host_slot(ThisUnit, 0, RtaUniq, HostP); + } + } + PktReplyP->Command = ROUTE_USED; + memcpy(PktReplyP->CommandText, "RT_USED", 7); + } + RIOQueueCmdBlk(HostP, Rup, CmdBlkP); + return 1; +} + + +void RIOFixPhbs(struct rio_info *p, struct Host *HostP, unsigned int unit) +{ + unsigned short link, port; + struct Port *PortP; + unsigned long flags; + int PortN = HostP->Mapping[unit].SysPort; + + rio_dprintk(RIO_DEBUG_ROUTE, "RIOFixPhbs unit %d sysport %d\n", unit, PortN); + + if (PortN != -1) { + unsigned short dest_unit = HostP->Mapping[unit].ID2; + + /* + ** Get the link number used for the 1st 8 phbs on this unit. + */ + PortP = p->RIOPortp[HostP->Mapping[dest_unit - 1].SysPort]; + + link = readw(&PortP->PhbP->link); + + for (port = 0; port < PORTS_PER_RTA; port++, PortN++) { + unsigned short dest_port = port + 8; + u16 __iomem *TxPktP; + struct PKT __iomem *Pkt; + + PortP = p->RIOPortp[PortN]; + + rio_spin_lock_irqsave(&PortP->portSem, flags); + /* + ** If RTA is not powered on, the tx packets will be + ** unset, so go no further. + */ + if (!PortP->TxStart) { + rio_dprintk(RIO_DEBUG_ROUTE, "Tx pkts not set up yet\n"); + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + break; + } + + /* + ** For the second slot of a 16 port RTA, the driver needs to + ** sort out the phb to port mappings. The dest_unit for this + ** group of 8 phbs is set to the dest_unit of the accompanying + ** 8 port block. The dest_port of the second unit is set to + ** be in the range 8-15 (i.e. 8 is added). Thus, for a 16 port + ** RTA with IDs 5 and 6, traffic bound for port 6 of unit 6 + ** (being the second map ID) will be sent to dest_unit 5, port + ** 14. When this RTA is deleted, dest_unit for ID 6 will be + ** restored, and the dest_port will be reduced by 8. + ** Transmit packets also have a destination field which needs + ** adjusting in the same manner. + ** Note that the unit/port bytes in 'dest' are swapped. + ** We also need to adjust the phb and rup link numbers for the + ** second block of 8 ttys. + */ + for (TxPktP = PortP->TxStart; TxPktP <= PortP->TxEnd; TxPktP++) { + /* + ** *TxPktP is the pointer to the transmit packet on the host + ** card. This needs to be translated into a 32 bit pointer + ** so it can be accessed from the driver. + */ + Pkt = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(TxPktP)); + + /* + ** If the packet is used, reset it. + */ + Pkt = (struct PKT __iomem *) ((unsigned long) Pkt & ~PKT_IN_USE); + writeb(dest_unit, &Pkt->dest_unit); + writeb(dest_port, &Pkt->dest_port); + } + rio_dprintk(RIO_DEBUG_ROUTE, "phb dest: Old %x:%x New %x:%x\n", readw(&PortP->PhbP->destination) & 0xff, (readw(&PortP->PhbP->destination) >> 8) & 0xff, dest_unit, dest_port); + writew(dest_unit + (dest_port << 8), &PortP->PhbP->destination); + writew(link, &PortP->PhbP->link); + + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + } + /* + ** Now make sure the range of ports to be serviced includes + ** the 2nd 8 on this 16 port RTA. + */ + if (link > 3) + return; + if (((unit * 8) + 7) > readw(&HostP->LinkStrP[link].last_port)) { + rio_dprintk(RIO_DEBUG_ROUTE, "last port on host link %d: %d\n", link, (unit * 8) + 7); + writew((unit * 8) + 7, &HostP->LinkStrP[link].last_port); + } + } +} + +/* +** Check to see if the new disconnection has isolated this unit. +** If it has, then invalidate all its link information, and tell +** the world about it. This is done to ensure that the configurator +** only gets up-to-date information about what is going on. +*/ +static int RIOCheckIsolated(struct rio_info *p, struct Host *HostP, unsigned int UnitId) +{ + unsigned long flags; + rio_spin_lock_irqsave(&HostP->HostLock, flags); + + if (RIOCheck(HostP, UnitId)) { + rio_dprintk(RIO_DEBUG_ROUTE, "Unit %d is NOT isolated\n", UnitId); + rio_spin_unlock_irqrestore(&HostP->HostLock, flags); + return (0); + } + + RIOIsolate(p, HostP, UnitId); + RIOSetChange(p); + rio_spin_unlock_irqrestore(&HostP->HostLock, flags); + return 1; +} + +/* +** Invalidate all the link interconnectivity of this unit, and of +** all the units attached to it. This will mean that the entire +** subnet will re-introduce itself. +*/ +static int RIOIsolate(struct rio_info *p, struct Host *HostP, unsigned int UnitId) +{ + unsigned int link, unit; + + UnitId--; /* this trick relies on the Unit Id being UNSIGNED! */ + + if (UnitId >= MAX_RUP) /* dontcha just lurv unsigned maths! */ + return (0); + + if (HostP->Mapping[UnitId].Flags & BEEN_HERE) + return (0); + + HostP->Mapping[UnitId].Flags |= BEEN_HERE; + + if (p->RIOPrintDisabled == DO_PRINT) + rio_dprintk(RIO_DEBUG_ROUTE, "RIOMesgIsolated %s", HostP->Mapping[UnitId].Name); + + for (link = 0; link < LINKS_PER_UNIT; link++) { + unit = HostP->Mapping[UnitId].Topology[link].Unit; + HostP->Mapping[UnitId].Topology[link].Unit = ROUTE_DISCONNECT; + HostP->Mapping[UnitId].Topology[link].Link = NO_LINK; + RIOIsolate(p, HostP, unit); + } + HostP->Mapping[UnitId].Flags &= ~BEEN_HERE; + return 1; +} + +static int RIOCheck(struct Host *HostP, unsigned int UnitId) +{ + unsigned char link; + +/* rio_dprint(RIO_DEBUG_ROUTE, ("Check to see if unit %d has a route to the host\n",UnitId)); */ + rio_dprintk(RIO_DEBUG_ROUTE, "RIOCheck : UnitID = %d\n", UnitId); + + if (UnitId == HOST_ID) { + /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is NOT isolated - it IS the host!\n", UnitId)); */ + return 1; + } + + UnitId--; + + if (UnitId >= MAX_RUP) { + /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d - ignored.\n", UnitId)); */ + return 0; + } + + for (link = 0; link < LINKS_PER_UNIT; link++) { + if (HostP->Mapping[UnitId].Topology[link].Unit == HOST_ID) { + /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is connected directly to host via link (%c).\n", + UnitId, 'A'+link)); */ + return 1; + } + } + + if (HostP->Mapping[UnitId].Flags & BEEN_HERE) { + /* rio_dprint(RIO_DEBUG_ROUTE, ("Been to Unit %d before - ignoring\n", UnitId)); */ + return 0; + } + + HostP->Mapping[UnitId].Flags |= BEEN_HERE; + + for (link = 0; link < LINKS_PER_UNIT; link++) { + /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d check link (%c)\n", UnitId,'A'+link)); */ + if (RIOCheck(HostP, HostP->Mapping[UnitId].Topology[link].Unit)) { + /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is connected to something that knows the host via link (%c)\n", UnitId,link+'A')); */ + HostP->Mapping[UnitId].Flags &= ~BEEN_HERE; + return 1; + } + } + + HostP->Mapping[UnitId].Flags &= ~BEEN_HERE; + + /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d DOESNT KNOW THE HOST!\n", UnitId)); */ + + return 0; +} + +/* +** Returns the type of unit (host, 16/8 port RTA) +*/ + +unsigned int GetUnitType(unsigned int Uniq) +{ + switch ((Uniq >> 28) & 0xf) { + case RIO_AT: + case RIO_MCA: + case RIO_EISA: + case RIO_PCI: + rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: Host\n"); + return (TYPE_HOST); + case RIO_RTA_16: + rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: 16 port RTA\n"); + return (TYPE_RTA16); + case RIO_RTA: + rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: 8 port RTA\n"); + return (TYPE_RTA8); + default: + rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: Unrecognised\n"); + return (99); + } +} + +int RIOSetChange(struct rio_info *p) +{ + if (p->RIOQuickCheck != NOT_CHANGED) + return (0); + p->RIOQuickCheck = CHANGED; + if (p->RIOSignalProcess) { + rio_dprintk(RIO_DEBUG_ROUTE, "Send SIG-HUP"); + /* + psignal( RIOSignalProcess, SIGHUP ); + */ + } + return (0); +} + +static void RIOConCon(struct rio_info *p, + struct Host *HostP, + unsigned int FromId, + unsigned int FromLink, + unsigned int ToId, + unsigned int ToLink, + int Change) +{ + char *FromName; + char *FromType; + char *ToName; + char *ToType; + unsigned int tp; + +/* +** 15.10.1998 ARG - ESIL 0759 +** (Part) fix for port being trashed when opened whilst RTA "disconnected" +** +** What's this doing in here anyway ? +** It was causing the port to be 'unmapped' if opened whilst RTA "disconnected" +** +** 09.12.1998 ARG - ESIL 0776 - part fix +** Okay, We've found out what this was all about now ! +** Someone had botched this to use RIOHalted to indicated the number of RTAs +** 'disconnected'. The value in RIOHalted was then being used in the +** 'RIO_QUICK_CHECK' ioctl. A none zero value indicating that a least one RTA +** is 'disconnected'. The change was put in to satisfy a customer's needs. +** Having taken this bit of code out 'RIO_QUICK_CHECK' now no longer works for +** the customer. +** + if (Change == CONNECT) { + if (p->RIOHalted) p->RIOHalted --; + } + else { + p->RIOHalted ++; + } +** +** So - we need to implement it slightly differently - a new member of the +** rio_info struct - RIORtaDisCons (RIO RTA connections) keeps track of RTA +** connections and disconnections. +*/ + if (Change == CONNECT) { + if (p->RIORtaDisCons) + p->RIORtaDisCons--; + } else { + p->RIORtaDisCons++; + } + + if (p->RIOPrintDisabled == DONT_PRINT) + return; + + if (FromId > ToId) { + tp = FromId; + FromId = ToId; + ToId = tp; + tp = FromLink; + FromLink = ToLink; + ToLink = tp; + } + + FromName = FromId ? HostP->Mapping[FromId - 1].Name : HostP->Name; + FromType = FromId ? "RTA" : "HOST"; + ToName = ToId ? HostP->Mapping[ToId - 1].Name : HostP->Name; + ToType = ToId ? "RTA" : "HOST"; + + rio_dprintk(RIO_DEBUG_ROUTE, "Link between %s '%s' (%c) and %s '%s' (%c) %s.\n", FromType, FromName, 'A' + FromLink, ToType, ToName, 'A' + ToLink, (Change == CONNECT) ? "established" : "disconnected"); + printk(KERN_DEBUG "rio: Link between %s '%s' (%c) and %s '%s' (%c) %s.\n", FromType, FromName, 'A' + FromLink, ToType, ToName, 'A' + ToLink, (Change == CONNECT) ? "established" : "disconnected"); +} + +/* +** RIORemoveFromSavedTable : +** +** Delete and RTA entry from the saved table given to us +** by the configuration program. +*/ +static int RIORemoveFromSavedTable(struct rio_info *p, struct Map *pMap) +{ + int entry; + + /* + ** We loop for all entries even after finding an entry and + ** zeroing it because we may have two entries to delete if + ** it's a 16 port RTA. + */ + for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) { + if (p->RIOSavedTable[entry].RtaUniqueNum == pMap->RtaUniqueNum) { + memset(&p->RIOSavedTable[entry], 0, sizeof(struct Map)); + } + } + return 0; +} + + +/* +** RIOCheckDisconnected : +** +** Scan the unit links to and return zero if the unit is completely +** disconnected. +*/ +static int RIOFreeDisconnected(struct rio_info *p, struct Host *HostP, int unit) +{ + int link; + + + rio_dprintk(RIO_DEBUG_ROUTE, "RIOFreeDisconnect unit %d\n", unit); + /* + ** If the slot is tentative and does not belong to the + ** second half of a 16 port RTA then scan to see if + ** is disconnected. + */ + for (link = 0; link < LINKS_PER_UNIT; link++) { + if (HostP->Mapping[unit].Topology[link].Unit != ROUTE_DISCONNECT) + break; + } + + /* + ** If not all links are disconnected then we can forget about it. + */ + if (link < LINKS_PER_UNIT) + return 1; + +#ifdef NEED_TO_FIX_THIS + /* Ok so all the links are disconnected. But we may have only just + ** made this slot tentative and not yet received a topology update. + ** Lets check how long ago we made it tentative. + */ + rio_dprintk(RIO_DEBUG_ROUTE, "Just about to check LBOLT on entry %d\n", unit); + if (drv_getparm(LBOLT, (ulong_t *) & current_time)) + rio_dprintk(RIO_DEBUG_ROUTE, "drv_getparm(LBOLT,....) Failed.\n"); + + elapse_time = current_time - TentTime[unit]; + rio_dprintk(RIO_DEBUG_ROUTE, "elapse %d = current %d - tent %d (%d usec)\n", elapse_time, current_time, TentTime[unit], drv_hztousec(elapse_time)); + if (drv_hztousec(elapse_time) < WAIT_TO_FINISH) { + rio_dprintk(RIO_DEBUG_ROUTE, "Skipping slot %d, not timed out yet %d\n", unit, drv_hztousec(elapse_time)); + return 1; + } +#endif + + /* + ** We have found an usable slot. + ** If it is half of a 16 port RTA then delete the other half. + */ + if (HostP->Mapping[unit].ID2 != 0) { + int nOther = (HostP->Mapping[unit].ID2) - 1; + + rio_dprintk(RIO_DEBUG_ROUTE, "RioFreedis second slot %d.\n", nOther); + memset(&HostP->Mapping[nOther], 0, sizeof(struct Map)); + } + RIORemoveFromSavedTable(p, &HostP->Mapping[unit]); + + return 0; +} + + +/* +** RIOFindFreeID : +** +** This function scans the given host table for either one +** or two free unit ID's. +*/ + +int RIOFindFreeID(struct rio_info *p, struct Host *HostP, unsigned int * pID1, unsigned int * pID2) +{ + int unit, tempID; + + /* + ** Initialise the ID's to MAX_RUP. + ** We do this to make the loop for setting the ID's as simple as + ** possible. + */ + *pID1 = MAX_RUP; + if (pID2 != NULL) + *pID2 = MAX_RUP; + + /* + ** Scan all entries of the host mapping table for free slots. + ** We scan for free slots first and then if that is not successful + ** we start all over again looking for tentative slots we can re-use. + */ + for (unit = 0; unit < MAX_RUP; unit++) { + rio_dprintk(RIO_DEBUG_ROUTE, "Scanning unit %d\n", unit); + /* + ** If the flags are zero then the slot is empty. + */ + if (HostP->Mapping[unit].Flags == 0) { + rio_dprintk(RIO_DEBUG_ROUTE, " This slot is empty.\n"); + /* + ** If we haven't allocated the first ID then do it now. + */ + if (*pID1 == MAX_RUP) { + rio_dprintk(RIO_DEBUG_ROUTE, "Make tentative entry for first unit %d\n", unit); + *pID1 = unit; + + /* + ** If the second ID is not needed then we can return + ** now. + */ + if (pID2 == NULL) + return 0; + } else { + /* + ** Allocate the second slot and return. + */ + rio_dprintk(RIO_DEBUG_ROUTE, "Make tentative entry for second unit %d\n", unit); + *pID2 = unit; + return 0; + } + } + } + + /* + ** If we manage to come out of the free slot loop then we + ** need to start all over again looking for tentative slots + ** that we can re-use. + */ + rio_dprintk(RIO_DEBUG_ROUTE, "Starting to scan for tentative slots\n"); + for (unit = 0; unit < MAX_RUP; unit++) { + if (((HostP->Mapping[unit].Flags & SLOT_TENTATIVE) || (HostP->Mapping[unit].Flags == 0)) && !(HostP->Mapping[unit].Flags & RTA16_SECOND_SLOT)) { + rio_dprintk(RIO_DEBUG_ROUTE, " Slot %d looks promising.\n", unit); + + if (unit == *pID1) { + rio_dprintk(RIO_DEBUG_ROUTE, " No it isn't, its the 1st half\n"); + continue; + } + + /* + ** Slot is Tentative or Empty, but not a tentative second + ** slot of a 16 porter. + ** Attempt to free up this slot (and its parnter if + ** it is a 16 port slot. The second slot will become + ** empty after a call to RIOFreeDisconnected so thats why + ** we look for empty slots above as well). + */ + if (HostP->Mapping[unit].Flags != 0) + if (RIOFreeDisconnected(p, HostP, unit) != 0) + continue; + /* + ** If we haven't allocated the first ID then do it now. + */ + if (*pID1 == MAX_RUP) { + rio_dprintk(RIO_DEBUG_ROUTE, "Grab tentative entry for first unit %d\n", unit); + *pID1 = unit; + + /* + ** Clear out this slot now that we intend to use it. + */ + memset(&HostP->Mapping[unit], 0, sizeof(struct Map)); + + /* + ** If the second ID is not needed then we can return + ** now. + */ + if (pID2 == NULL) + return 0; + } else { + /* + ** Allocate the second slot and return. + */ + rio_dprintk(RIO_DEBUG_ROUTE, "Grab tentative/empty entry for second unit %d\n", unit); + *pID2 = unit; + + /* + ** Clear out this slot now that we intend to use it. + */ + memset(&HostP->Mapping[unit], 0, sizeof(struct Map)); + + /* At this point under the right(wrong?) conditions + ** we may have a first unit ID being higher than the + ** second unit ID. This is a bad idea if we are about + ** to fill the slots with a 16 port RTA. + ** Better check and swap them over. + */ + + if (*pID1 > *pID2) { + rio_dprintk(RIO_DEBUG_ROUTE, "Swapping IDS %d %d\n", *pID1, *pID2); + tempID = *pID1; + *pID1 = *pID2; + *pID2 = tempID; + } + return 0; + } + } + } + + /* + ** If we manage to get to the end of the second loop then we + ** can give up and return a failure. + */ + return 1; +} + + +/* +** The link switch scenario. +** +** Rta Wun (A) is connected to Tuw (A). +** The tables are all up to date, and the system is OK. +** +** If Wun (A) is now moved to Wun (B) before Wun (A) can +** become disconnected, then the follow happens: +** +** Tuw (A) spots the change of unit:link at the other end +** of its link and Tuw sends a topology packet reflecting +** the change: Tuw (A) now disconnected from Wun (A), and +** this is closely followed by a packet indicating that +** Tuw (A) is now connected to Wun (B). +** +** Wun (B) will spot that it has now become connected, and +** Wun will send a topology packet, which indicates that +** both Wun (A) and Wun (B) is connected to Tuw (A). +** +** Eventually Wun (A) realises that it is now disconnected +** and Wun will send out a topology packet indicating that +** Wun (A) is now disconnected. +*/ diff --git a/drivers/staging/generic_serial/rio/riospace.h b/drivers/staging/generic_serial/rio/riospace.h new file mode 100644 index 000000000000..ffb31d4332b9 --- /dev/null +++ b/drivers/staging/generic_serial/rio/riospace.h @@ -0,0 +1,154 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : riospace.h +** SID : 1.2 +** Last Modified : 11/6/98 11:34:13 +** Retrieved : 11/6/98 11:34:22 +** +** ident @(#)riospace.h 1.2 +** +** ----------------------------------------------------------------------------- +*/ + +#ifndef __rio_riospace_h__ +#define __rio_riospace_h__ + +#define RIO_LOCATOR_LEN 16 +#define MAX_RIO_BOARDS 4 + +/* +** DONT change this file. At all. Unless you can rebuild the entire +** device driver, which you probably can't, then the rest of the +** driver won't see any changes you make here. So don't make any. +** In particular, it won't be able to see changes to RIO_SLOTS +*/ + +struct Conf { + char Locator[24]; + unsigned int StartupTime; + unsigned int SlowCook; + unsigned int IntrPollTime; + unsigned int BreakInterval; + unsigned int Timer; + unsigned int RtaLoadBase; + unsigned int HostLoadBase; + unsigned int XpHz; + unsigned int XpCps; + char *XpOn; + char *XpOff; + unsigned int MaxXpCps; + unsigned int MinXpCps; + unsigned int SpinCmds; + unsigned int FirstAddr; + unsigned int LastAddr; + unsigned int BufferSize; + unsigned int LowWater; + unsigned int LineLength; + unsigned int CmdTime; +}; + +/* +** Board types - these MUST correspond to product codes! +*/ +#define RIO_EMPTY 0x0 +#define RIO_EISA 0x3 +#define RIO_RTA_16 0x9 +#define RIO_AT 0xA +#define RIO_MCA 0xB +#define RIO_PCI 0xD +#define RIO_RTA 0xE + +/* +** Board data structure. This is used for configuration info +*/ +struct Brd { + unsigned char Type; /* RIO_EISA, RIO_MCA, RIO_AT, RIO_EMPTY... */ + unsigned char Ivec; /* POLLED or ivec number */ + unsigned char Mode; /* Control stuff, see below */ +}; + +struct Board { + char Locator[RIO_LOCATOR_LEN]; + int NumSlots; + struct Brd Boards[MAX_RIO_BOARDS]; +}; + +#define BOOT_FROM_LINK 0x00 +#define BOOT_FROM_RAM 0x01 +#define EXTERNAL_BUS_OFF 0x00 +#define EXTERNAL_BUS_ON 0x02 +#define INTERRUPT_DISABLE 0x00 +#define INTERRUPT_ENABLE 0x04 +#define BYTE_OPERATION 0x00 +#define WORD_OPERATION 0x08 +#define POLLED INTERRUPT_DISABLE +#define IRQ_15 (0x00 | INTERRUPT_ENABLE) +#define IRQ_12 (0x10 | INTERRUPT_ENABLE) +#define IRQ_11 (0x20 | INTERRUPT_ENABLE) +#define IRQ_9 (0x30 | INTERRUPT_ENABLE) +#define SLOW_LINKS 0x00 +#define FAST_LINKS 0x40 +#define SLOW_AT_BUS 0x00 +#define FAST_AT_BUS 0x80 +#define SLOW_PCI_TP 0x00 +#define FAST_PCI_TP 0x80 +/* +** Debug levels +*/ +#define DBG_NONE 0x00000000 + +#define DBG_INIT 0x00000001 +#define DBG_OPEN 0x00000002 +#define DBG_CLOSE 0x00000004 +#define DBG_IOCTL 0x00000008 + +#define DBG_READ 0x00000010 +#define DBG_WRITE 0x00000020 +#define DBG_INTR 0x00000040 +#define DBG_PROC 0x00000080 + +#define DBG_PARAM 0x00000100 +#define DBG_CMD 0x00000200 +#define DBG_XPRINT 0x00000400 +#define DBG_POLL 0x00000800 + +#define DBG_DAEMON 0x00001000 +#define DBG_FAIL 0x00002000 +#define DBG_MODEM 0x00004000 +#define DBG_LIST 0x00008000 + +#define DBG_ROUTE 0x00010000 +#define DBG_UTIL 0x00020000 +#define DBG_BOOT 0x00040000 +#define DBG_BUFFER 0x00080000 + +#define DBG_MON 0x00100000 +#define DBG_SPECIAL 0x00200000 +#define DBG_VPIX 0x00400000 +#define DBG_FLUSH 0x00800000 + +#define DBG_QENABLE 0x01000000 + +#define DBG_ALWAYS 0x80000000 + +#endif /* __rio_riospace_h__ */ diff --git a/drivers/staging/generic_serial/rio/riotable.c b/drivers/staging/generic_serial/rio/riotable.c new file mode 100644 index 000000000000..3d15802dc0f3 --- /dev/null +++ b/drivers/staging/generic_serial/rio/riotable.c @@ -0,0 +1,941 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : riotable.c +** SID : 1.2 +** Last Modified : 11/6/98 10:33:47 +** Retrieved : 11/6/98 10:33:50 +** +** ident @(#)riotable.c 1.2 +** +** ----------------------------------------------------------------------------- +*/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include + + +#include "linux_compat.h" +#include "rio_linux.h" +#include "pkt.h" +#include "daemon.h" +#include "rio.h" +#include "riospace.h" +#include "cmdpkt.h" +#include "map.h" +#include "rup.h" +#include "port.h" +#include "riodrvr.h" +#include "rioinfo.h" +#include "func.h" +#include "errors.h" +#include "pci.h" + +#include "parmmap.h" +#include "unixrup.h" +#include "board.h" +#include "host.h" +#include "phb.h" +#include "link.h" +#include "cmdblk.h" +#include "route.h" +#include "cirrus.h" +#include "rioioctl.h" +#include "param.h" +#include "protsts.h" + +/* +** A configuration table has been loaded. It is now up to us +** to sort it out and use the information contained therein. +*/ +int RIONewTable(struct rio_info *p) +{ + int Host, Host1, Host2, NameIsUnique, Entry, SubEnt; + struct Map *MapP; + struct Map *HostMapP; + struct Host *HostP; + + char *cptr; + + /* + ** We have been sent a new table to install. We need to break + ** it down into little bits and spread it around a bit to see + ** what we have got. + */ + /* + ** Things to check: + ** (things marked 'xx' aren't checked any more!) + ** (1) That there are no booted Hosts/RTAs out there. + ** (2) That the names are properly formed + ** (3) That blank entries really are. + ** xx (4) That hosts mentioned in the table actually exist. xx + ** (5) That the IDs are unique (per host). + ** (6) That host IDs are zero + ** (7) That port numbers are valid + ** (8) That port numbers aren't duplicated + ** (9) That names aren't duplicated + ** xx (10) That hosts that actually exist are mentioned in the table. xx + */ + rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(1)\n"); + if (p->RIOSystemUp) { /* (1) */ + p->RIOError.Error = HOST_HAS_ALREADY_BEEN_BOOTED; + return -EBUSY; + } + + p->RIOError.Error = NOTHING_WRONG_AT_ALL; + p->RIOError.Entry = -1; + p->RIOError.Other = -1; + + for (Entry = 0; Entry < TOTAL_MAP_ENTRIES; Entry++) { + MapP = &p->RIOConnectTable[Entry]; + if ((MapP->Flags & RTA16_SECOND_SLOT) == 0) { + rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(2)\n"); + cptr = MapP->Name; /* (2) */ + cptr[MAX_NAME_LEN - 1] = '\0'; + if (cptr[0] == '\0') { + memcpy(MapP->Name, MapP->RtaUniqueNum ? "RTA NN" : "HOST NN", 8); + MapP->Name[5] = '0' + Entry / 10; + MapP->Name[6] = '0' + Entry % 10; + } + while (*cptr) { + if (*cptr < ' ' || *cptr > '~') { + p->RIOError.Error = BAD_CHARACTER_IN_NAME; + p->RIOError.Entry = Entry; + return -ENXIO; + } + cptr++; + } + } + + /* + ** If the entry saved was a tentative entry then just forget + ** about it. + */ + if (MapP->Flags & SLOT_TENTATIVE) { + MapP->HostUniqueNum = 0; + MapP->RtaUniqueNum = 0; + continue; + } + + rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(3)\n"); + if (!MapP->RtaUniqueNum && !MapP->HostUniqueNum) { /* (3) */ + if (MapP->ID || MapP->SysPort || MapP->Flags) { + rio_dprintk(RIO_DEBUG_TABLE, "%s pretending to be empty but isn't\n", MapP->Name); + p->RIOError.Error = TABLE_ENTRY_ISNT_PROPERLY_NULL; + p->RIOError.Entry = Entry; + return -ENXIO; + } + rio_dprintk(RIO_DEBUG_TABLE, "!RIO: Daemon: test (3) passes\n"); + continue; + } + + rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(4)\n"); + for (Host = 0; Host < p->RIONumHosts; Host++) { /* (4) */ + if (p->RIOHosts[Host].UniqueNum == MapP->HostUniqueNum) { + HostP = &p->RIOHosts[Host]; + /* + ** having done the lookup, we don't really want to do + ** it again, so hang the host number in a safe place + */ + MapP->Topology[0].Unit = Host; + break; + } + } + + if (Host >= p->RIONumHosts) { + rio_dprintk(RIO_DEBUG_TABLE, "RTA %s has unknown host unique number 0x%x\n", MapP->Name, MapP->HostUniqueNum); + MapP->HostUniqueNum = 0; + /* MapP->RtaUniqueNum = 0; */ + /* MapP->ID = 0; */ + /* MapP->Flags = 0; */ + /* MapP->SysPort = 0; */ + /* MapP->Name[0] = 0; */ + continue; + } + + rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(5)\n"); + if (MapP->RtaUniqueNum) { /* (5) */ + if (!MapP->ID) { + rio_dprintk(RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an ID of zero!\n", MapP->Name); + p->RIOError.Error = ZERO_RTA_ID; + p->RIOError.Entry = Entry; + return -ENXIO; + } + if (MapP->ID > MAX_RUP) { + rio_dprintk(RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an invalid ID %d\n", MapP->Name, MapP->ID); + p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE; + p->RIOError.Entry = Entry; + return -ENXIO; + } + for (SubEnt = 0; SubEnt < Entry; SubEnt++) { + if (MapP->HostUniqueNum == p->RIOConnectTable[SubEnt].HostUniqueNum && MapP->ID == p->RIOConnectTable[SubEnt].ID) { + rio_dprintk(RIO_DEBUG_TABLE, "Dupl. ID number allocated to RTA %s and RTA %s\n", MapP->Name, p->RIOConnectTable[SubEnt].Name); + p->RIOError.Error = DUPLICATED_RTA_ID; + p->RIOError.Entry = Entry; + p->RIOError.Other = SubEnt; + return -ENXIO; + } + /* + ** If the RtaUniqueNum is the same, it may be looking at both + ** entries for a 16 port RTA, so check the ids + */ + if ((MapP->RtaUniqueNum == p->RIOConnectTable[SubEnt].RtaUniqueNum) + && (MapP->ID2 != p->RIOConnectTable[SubEnt].ID)) { + rio_dprintk(RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n", MapP->Name); + rio_dprintk(RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n", p->RIOConnectTable[SubEnt].Name); + p->RIOError.Error = DUPLICATE_UNIQUE_NUMBER; + p->RIOError.Entry = Entry; + p->RIOError.Other = SubEnt; + return -ENXIO; + } + } + rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(7a)\n"); + /* (7a) */ + if ((MapP->SysPort != NO_PORT) && (MapP->SysPort % PORTS_PER_RTA)) { + rio_dprintk(RIO_DEBUG_TABLE, "TTY Port number %d-RTA %s is not a multiple of %d!\n", (int) MapP->SysPort, MapP->Name, PORTS_PER_RTA); + p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE; + p->RIOError.Entry = Entry; + return -ENXIO; + } + rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(7b)\n"); + /* (7b) */ + if ((MapP->SysPort != NO_PORT) && (MapP->SysPort >= RIO_PORTS)) { + rio_dprintk(RIO_DEBUG_TABLE, "TTY Port number %d for RTA %s is too big\n", (int) MapP->SysPort, MapP->Name); + p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE; + p->RIOError.Entry = Entry; + return -ENXIO; + } + for (SubEnt = 0; SubEnt < Entry; SubEnt++) { + if (p->RIOConnectTable[SubEnt].Flags & RTA16_SECOND_SLOT) + continue; + if (p->RIOConnectTable[SubEnt].RtaUniqueNum) { + rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(8)\n"); + /* (8) */ + if ((MapP->SysPort != NO_PORT) && (MapP->SysPort == p->RIOConnectTable[SubEnt].SysPort)) { + rio_dprintk(RIO_DEBUG_TABLE, "RTA %s:same TTY port # as RTA %s (%d)\n", MapP->Name, p->RIOConnectTable[SubEnt].Name, (int) MapP->SysPort); + p->RIOError.Error = TTY_NUMBER_IN_USE; + p->RIOError.Entry = Entry; + p->RIOError.Other = SubEnt; + return -ENXIO; + } + rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(9)\n"); + if (strcmp(MapP->Name, p->RIOConnectTable[SubEnt].Name) == 0 && !(MapP->Flags & RTA16_SECOND_SLOT)) { /* (9) */ + rio_dprintk(RIO_DEBUG_TABLE, "RTA name %s used twice\n", MapP->Name); + p->RIOError.Error = NAME_USED_TWICE; + p->RIOError.Entry = Entry; + p->RIOError.Other = SubEnt; + return -ENXIO; + } + } + } + } else { /* (6) */ + rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(6)\n"); + if (MapP->ID) { + rio_dprintk(RIO_DEBUG_TABLE, "RIO:HOST %s has been allocated ID that isn't zero!\n", MapP->Name); + p->RIOError.Error = HOST_ID_NOT_ZERO; + p->RIOError.Entry = Entry; + return -ENXIO; + } + if (MapP->SysPort != NO_PORT) { + rio_dprintk(RIO_DEBUG_TABLE, "RIO: HOST %s has been allocated port numbers!\n", MapP->Name); + p->RIOError.Error = HOST_SYSPORT_BAD; + p->RIOError.Entry = Entry; + return -ENXIO; + } + } + } + + /* + ** wow! if we get here then it's a goody! + */ + + /* + ** Zero the (old) entries for each host... + */ + for (Host = 0; Host < RIO_HOSTS; Host++) { + for (Entry = 0; Entry < MAX_RUP; Entry++) { + memset(&p->RIOHosts[Host].Mapping[Entry], 0, sizeof(struct Map)); + } + memset(&p->RIOHosts[Host].Name[0], 0, sizeof(p->RIOHosts[Host].Name)); + } + + /* + ** Copy in the new table entries + */ + for (Entry = 0; Entry < TOTAL_MAP_ENTRIES; Entry++) { + rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: Copy table for Host entry %d\n", Entry); + MapP = &p->RIOConnectTable[Entry]; + + /* + ** Now, if it is an empty slot ignore it! + */ + if (MapP->HostUniqueNum == 0) + continue; + + /* + ** we saved the host number earlier, so grab it back + */ + HostP = &p->RIOHosts[MapP->Topology[0].Unit]; + + /* + ** If it is a host, then we only need to fill in the name field. + */ + if (MapP->ID == 0) { + rio_dprintk(RIO_DEBUG_TABLE, "Host entry found. Name %s\n", MapP->Name); + memcpy(HostP->Name, MapP->Name, MAX_NAME_LEN); + continue; + } + + /* + ** Its an RTA entry, so fill in the host mapping entries for it + ** and the port mapping entries. Notice that entry zero is for + ** ID one. + */ + HostMapP = &HostP->Mapping[MapP->ID - 1]; + + if (MapP->Flags & SLOT_IN_USE) { + rio_dprintk(RIO_DEBUG_TABLE, "Rta entry found. Name %s\n", MapP->Name); + /* + ** structure assign, then sort out the bits we shouldn't have done + */ + *HostMapP = *MapP; + + HostMapP->Flags = SLOT_IN_USE; + if (MapP->Flags & RTA16_SECOND_SLOT) + HostMapP->Flags |= RTA16_SECOND_SLOT; + + RIOReMapPorts(p, HostP, HostMapP); + } else { + rio_dprintk(RIO_DEBUG_TABLE, "TENTATIVE Rta entry found. Name %s\n", MapP->Name); + } + } + + for (Entry = 0; Entry < TOTAL_MAP_ENTRIES; Entry++) { + p->RIOSavedTable[Entry] = p->RIOConnectTable[Entry]; + } + + for (Host = 0; Host < p->RIONumHosts; Host++) { + for (SubEnt = 0; SubEnt < LINKS_PER_UNIT; SubEnt++) { + p->RIOHosts[Host].Topology[SubEnt].Unit = ROUTE_DISCONNECT; + p->RIOHosts[Host].Topology[SubEnt].Link = NO_LINK; + } + for (Entry = 0; Entry < MAX_RUP; Entry++) { + for (SubEnt = 0; SubEnt < LINKS_PER_UNIT; SubEnt++) { + p->RIOHosts[Host].Mapping[Entry].Topology[SubEnt].Unit = ROUTE_DISCONNECT; + p->RIOHosts[Host].Mapping[Entry].Topology[SubEnt].Link = NO_LINK; + } + } + if (!p->RIOHosts[Host].Name[0]) { + memcpy(p->RIOHosts[Host].Name, "HOST 1", 7); + p->RIOHosts[Host].Name[5] += Host; + } + /* + ** Check that default name assigned is unique. + */ + Host1 = Host; + NameIsUnique = 0; + while (!NameIsUnique) { + NameIsUnique = 1; + for (Host2 = 0; Host2 < p->RIONumHosts; Host2++) { + if (Host2 == Host) + continue; + if (strcmp(p->RIOHosts[Host].Name, p->RIOHosts[Host2].Name) + == 0) { + NameIsUnique = 0; + Host1++; + if (Host1 >= p->RIONumHosts) + Host1 = 0; + p->RIOHosts[Host].Name[5] = '1' + Host1; + } + } + } + /* + ** Rename host if name already used. + */ + if (Host1 != Host) { + rio_dprintk(RIO_DEBUG_TABLE, "Default name %s already used\n", p->RIOHosts[Host].Name); + memcpy(p->RIOHosts[Host].Name, "HOST 1", 7); + p->RIOHosts[Host].Name[5] += Host1; + } + rio_dprintk(RIO_DEBUG_TABLE, "Assigning default name %s\n", p->RIOHosts[Host].Name); + } + return 0; +} + +/* +** User process needs the config table - build it from first +** principles. +** +* FIXME: SMP locking +*/ +int RIOApel(struct rio_info *p) +{ + int Host; + int link; + int Rup; + int Next = 0; + struct Map *MapP; + struct Host *HostP; + unsigned long flags; + + rio_dprintk(RIO_DEBUG_TABLE, "Generating a table to return to config.rio\n"); + + memset(&p->RIOConnectTable[0], 0, sizeof(struct Map) * TOTAL_MAP_ENTRIES); + + for (Host = 0; Host < RIO_HOSTS; Host++) { + rio_dprintk(RIO_DEBUG_TABLE, "Processing host %d\n", Host); + HostP = &p->RIOHosts[Host]; + rio_spin_lock_irqsave(&HostP->HostLock, flags); + + MapP = &p->RIOConnectTable[Next++]; + MapP->HostUniqueNum = HostP->UniqueNum; + if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { + rio_spin_unlock_irqrestore(&HostP->HostLock, flags); + continue; + } + MapP->RtaUniqueNum = 0; + MapP->ID = 0; + MapP->Flags = SLOT_IN_USE; + MapP->SysPort = NO_PORT; + for (link = 0; link < LINKS_PER_UNIT; link++) + MapP->Topology[link] = HostP->Topology[link]; + memcpy(MapP->Name, HostP->Name, MAX_NAME_LEN); + for (Rup = 0; Rup < MAX_RUP; Rup++) { + if (HostP->Mapping[Rup].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) { + p->RIOConnectTable[Next] = HostP->Mapping[Rup]; + if (HostP->Mapping[Rup].Flags & SLOT_IN_USE) + p->RIOConnectTable[Next].Flags |= SLOT_IN_USE; + if (HostP->Mapping[Rup].Flags & SLOT_TENTATIVE) + p->RIOConnectTable[Next].Flags |= SLOT_TENTATIVE; + if (HostP->Mapping[Rup].Flags & RTA16_SECOND_SLOT) + p->RIOConnectTable[Next].Flags |= RTA16_SECOND_SLOT; + Next++; + } + } + rio_spin_unlock_irqrestore(&HostP->HostLock, flags); + } + return 0; +} + +/* +** config.rio has taken a dislike to one of the gross maps entries. +** if the entry is suitably inactive, then we can gob on it and remove +** it from the table. +*/ +int RIODeleteRta(struct rio_info *p, struct Map *MapP) +{ + int host, entry, port, link; + int SysPort; + struct Host *HostP; + struct Map *HostMapP; + struct Port *PortP; + int work_done = 0; + unsigned long lock_flags, sem_flags; + + rio_dprintk(RIO_DEBUG_TABLE, "Delete entry on host %x, rta %x\n", MapP->HostUniqueNum, MapP->RtaUniqueNum); + + for (host = 0; host < p->RIONumHosts; host++) { + HostP = &p->RIOHosts[host]; + + rio_spin_lock_irqsave(&HostP->HostLock, lock_flags); + + if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { + rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags); + continue; + } + + for (entry = 0; entry < MAX_RUP; entry++) { + if (MapP->RtaUniqueNum == HostP->Mapping[entry].RtaUniqueNum) { + HostMapP = &HostP->Mapping[entry]; + rio_dprintk(RIO_DEBUG_TABLE, "Found entry offset %d on host %s\n", entry, HostP->Name); + + /* + ** Check all four links of the unit are disconnected + */ + for (link = 0; link < LINKS_PER_UNIT; link++) { + if (HostMapP->Topology[link].Unit != ROUTE_DISCONNECT) { + rio_dprintk(RIO_DEBUG_TABLE, "Entry is in use and cannot be deleted!\n"); + p->RIOError.Error = UNIT_IS_IN_USE; + rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags); + return -EBUSY; + } + } + /* + ** Slot has been allocated, BUT not booted/routed/ + ** connected/selected or anything else-ed + */ + SysPort = HostMapP->SysPort; + + if (SysPort != NO_PORT) { + for (port = SysPort; port < SysPort + PORTS_PER_RTA; port++) { + PortP = p->RIOPortp[port]; + rio_dprintk(RIO_DEBUG_TABLE, "Unmap port\n"); + + rio_spin_lock_irqsave(&PortP->portSem, sem_flags); + + PortP->Mapped = 0; + + if (PortP->State & (RIO_MOPEN | RIO_LOPEN)) { + + rio_dprintk(RIO_DEBUG_TABLE, "Gob on port\n"); + PortP->TxBufferIn = PortP->TxBufferOut = 0; + /* What should I do + wakeup( &PortP->TxBufferIn ); + wakeup( &PortP->TxBufferOut); + */ + PortP->InUse = NOT_INUSE; + /* What should I do + wakeup( &PortP->InUse ); + signal(PortP->TtyP->t_pgrp,SIGKILL); + ttyflush(PortP->TtyP,(FREAD|FWRITE)); + */ + PortP->State |= RIO_CLOSING | RIO_DELETED; + } + + /* + ** For the second slot of a 16 port RTA, the + ** driver needs to reset the changes made to + ** the phb to port mappings in RIORouteRup. + */ + if (PortP->SecondBlock) { + u16 dest_unit = HostMapP->ID; + u16 dest_port = port - SysPort; + u16 __iomem *TxPktP; + struct PKT __iomem *Pkt; + + for (TxPktP = PortP->TxStart; TxPktP <= PortP->TxEnd; TxPktP++) { + /* + ** *TxPktP is the pointer to the + ** transmit packet on the host card. + ** This needs to be translated into + ** a 32 bit pointer so it can be + ** accessed from the driver. + */ + Pkt = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(&*TxPktP)); + rio_dprintk(RIO_DEBUG_TABLE, "Tx packet (%x) destination: Old %x:%x New %x:%x\n", readw(TxPktP), readb(&Pkt->dest_unit), readb(&Pkt->dest_port), dest_unit, dest_port); + writew(dest_unit, &Pkt->dest_unit); + writew(dest_port, &Pkt->dest_port); + } + rio_dprintk(RIO_DEBUG_TABLE, "Port %d phb destination: Old %x:%x New %x:%x\n", port, readb(&PortP->PhbP->destination) & 0xff, (readb(&PortP->PhbP->destination) >> 8) & 0xff, dest_unit, dest_port); + writew(dest_unit + (dest_port << 8), &PortP->PhbP->destination); + } + rio_spin_unlock_irqrestore(&PortP->portSem, sem_flags); + } + } + rio_dprintk(RIO_DEBUG_TABLE, "Entry nulled.\n"); + memset(HostMapP, 0, sizeof(struct Map)); + work_done++; + } + } + rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags); + } + + /* XXXXX lock me up */ + for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) { + if (p->RIOSavedTable[entry].RtaUniqueNum == MapP->RtaUniqueNum) { + memset(&p->RIOSavedTable[entry], 0, sizeof(struct Map)); + work_done++; + } + if (p->RIOConnectTable[entry].RtaUniqueNum == MapP->RtaUniqueNum) { + memset(&p->RIOConnectTable[entry], 0, sizeof(struct Map)); + work_done++; + } + } + if (work_done) + return 0; + + rio_dprintk(RIO_DEBUG_TABLE, "Couldn't find entry to be deleted\n"); + p->RIOError.Error = COULDNT_FIND_ENTRY; + return -ENXIO; +} + +int RIOAssignRta(struct rio_info *p, struct Map *MapP) +{ + int host; + struct Map *HostMapP; + char *sptr; + int link; + + + rio_dprintk(RIO_DEBUG_TABLE, "Assign entry on host %x, rta %x, ID %d, Sysport %d\n", MapP->HostUniqueNum, MapP->RtaUniqueNum, MapP->ID, (int) MapP->SysPort); + + if ((MapP->ID != (u16) - 1) && ((int) MapP->ID < (int) 1 || (int) MapP->ID > MAX_RUP)) { + rio_dprintk(RIO_DEBUG_TABLE, "Bad ID in map entry!\n"); + p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE; + return -EINVAL; + } + if (MapP->RtaUniqueNum == 0) { + rio_dprintk(RIO_DEBUG_TABLE, "Rta Unique number zero!\n"); + p->RIOError.Error = RTA_UNIQUE_NUMBER_ZERO; + return -EINVAL; + } + if ((MapP->SysPort != NO_PORT) && (MapP->SysPort % PORTS_PER_RTA)) { + rio_dprintk(RIO_DEBUG_TABLE, "Port %d not multiple of %d!\n", (int) MapP->SysPort, PORTS_PER_RTA); + p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE; + return -EINVAL; + } + if ((MapP->SysPort != NO_PORT) && (MapP->SysPort >= RIO_PORTS)) { + rio_dprintk(RIO_DEBUG_TABLE, "Port %d not valid!\n", (int) MapP->SysPort); + p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE; + return -EINVAL; + } + + /* + ** Copy the name across to the map entry. + */ + MapP->Name[MAX_NAME_LEN - 1] = '\0'; + sptr = MapP->Name; + while (*sptr) { + if (*sptr < ' ' || *sptr > '~') { + rio_dprintk(RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n"); + p->RIOError.Error = BAD_CHARACTER_IN_NAME; + return -EINVAL; + } + sptr++; + } + + for (host = 0; host < p->RIONumHosts; host++) { + if (MapP->HostUniqueNum == p->RIOHosts[host].UniqueNum) { + if ((p->RIOHosts[host].Flags & RUN_STATE) != RC_RUNNING) { + p->RIOError.Error = HOST_NOT_RUNNING; + return -ENXIO; + } + + /* + ** Now we have a host we need to allocate an ID + ** if the entry does not already have one. + */ + if (MapP->ID == (u16) - 1) { + int nNewID; + + rio_dprintk(RIO_DEBUG_TABLE, "Attempting to get a new ID for rta \"%s\"\n", MapP->Name); + /* + ** The idea here is to allow RTA's to be assigned + ** before they actually appear on the network. + ** This allows the addition of RTA's without having + ** to plug them in. + ** What we do is: + ** - Find a free ID and allocate it to the RTA. + ** - If this map entry is the second half of a + ** 16 port entry then find the other half and + ** make sure the 2 cross reference each other. + */ + if (RIOFindFreeID(p, &p->RIOHosts[host], &nNewID, NULL) != 0) { + p->RIOError.Error = COULDNT_FIND_ENTRY; + return -EBUSY; + } + MapP->ID = (u16) nNewID + 1; + rio_dprintk(RIO_DEBUG_TABLE, "Allocated ID %d for this new RTA.\n", MapP->ID); + HostMapP = &p->RIOHosts[host].Mapping[nNewID]; + HostMapP->RtaUniqueNum = MapP->RtaUniqueNum; + HostMapP->HostUniqueNum = MapP->HostUniqueNum; + HostMapP->ID = MapP->ID; + for (link = 0; link < LINKS_PER_UNIT; link++) { + HostMapP->Topology[link].Unit = ROUTE_DISCONNECT; + HostMapP->Topology[link].Link = NO_LINK; + } + if (MapP->Flags & RTA16_SECOND_SLOT) { + int unit; + + for (unit = 0; unit < MAX_RUP; unit++) + if (p->RIOHosts[host].Mapping[unit].RtaUniqueNum == MapP->RtaUniqueNum) + break; + if (unit == MAX_RUP) { + p->RIOError.Error = COULDNT_FIND_ENTRY; + return -EBUSY; + } + HostMapP->Flags |= RTA16_SECOND_SLOT; + HostMapP->ID2 = MapP->ID2 = p->RIOHosts[host].Mapping[unit].ID; + p->RIOHosts[host].Mapping[unit].ID2 = MapP->ID; + rio_dprintk(RIO_DEBUG_TABLE, "Cross referenced id %d to ID %d.\n", MapP->ID, p->RIOHosts[host].Mapping[unit].ID); + } + } + + HostMapP = &p->RIOHosts[host].Mapping[MapP->ID - 1]; + + if (HostMapP->Flags & SLOT_IN_USE) { + rio_dprintk(RIO_DEBUG_TABLE, "Map table slot for ID %d is already in use.\n", MapP->ID); + p->RIOError.Error = ID_ALREADY_IN_USE; + return -EBUSY; + } + + /* + ** Assign the sys ports and the name, and mark the slot as + ** being in use. + */ + HostMapP->SysPort = MapP->SysPort; + if ((MapP->Flags & RTA16_SECOND_SLOT) == 0) + memcpy(HostMapP->Name, MapP->Name, MAX_NAME_LEN); + HostMapP->Flags = SLOT_IN_USE | RTA_BOOTED; +#ifdef NEED_TO_FIX + RIO_SV_BROADCAST(p->RIOHosts[host].svFlags[MapP->ID - 1]); +#endif + if (MapP->Flags & RTA16_SECOND_SLOT) + HostMapP->Flags |= RTA16_SECOND_SLOT; + + RIOReMapPorts(p, &p->RIOHosts[host], HostMapP); + /* + ** Adjust 2nd block of 8 phbs + */ + if (MapP->Flags & RTA16_SECOND_SLOT) + RIOFixPhbs(p, &p->RIOHosts[host], HostMapP->ID - 1); + + if (HostMapP->SysPort != NO_PORT) { + if (HostMapP->SysPort < p->RIOFirstPortsBooted) + p->RIOFirstPortsBooted = HostMapP->SysPort; + if (HostMapP->SysPort > p->RIOLastPortsBooted) + p->RIOLastPortsBooted = HostMapP->SysPort; + } + if (MapP->Flags & RTA16_SECOND_SLOT) + rio_dprintk(RIO_DEBUG_TABLE, "Second map of RTA %s added to configuration\n", p->RIOHosts[host].Mapping[MapP->ID2 - 1].Name); + else + rio_dprintk(RIO_DEBUG_TABLE, "RTA %s added to configuration\n", MapP->Name); + return 0; + } + } + p->RIOError.Error = UNKNOWN_HOST_NUMBER; + rio_dprintk(RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum); + return -ENXIO; +} + + +int RIOReMapPorts(struct rio_info *p, struct Host *HostP, struct Map *HostMapP) +{ + struct Port *PortP; + unsigned int SubEnt; + unsigned int HostPort; + unsigned int SysPort; + u16 RtaType; + unsigned long flags; + + rio_dprintk(RIO_DEBUG_TABLE, "Mapping sysport %d to id %d\n", (int) HostMapP->SysPort, HostMapP->ID); + + /* + ** We need to tell the UnixRups which sysport the rup corresponds to + */ + HostP->UnixRups[HostMapP->ID - 1].BaseSysPort = HostMapP->SysPort; + + if (HostMapP->SysPort == NO_PORT) + return (0); + + RtaType = GetUnitType(HostMapP->RtaUniqueNum); + rio_dprintk(RIO_DEBUG_TABLE, "Mapping sysport %d-%d\n", (int) HostMapP->SysPort, (int) HostMapP->SysPort + PORTS_PER_RTA - 1); + + /* + ** now map each of its eight ports + */ + for (SubEnt = 0; SubEnt < PORTS_PER_RTA; SubEnt++) { + rio_dprintk(RIO_DEBUG_TABLE, "subent = %d, HostMapP->SysPort = %d\n", SubEnt, (int) HostMapP->SysPort); + SysPort = HostMapP->SysPort + SubEnt; /* portnumber within system */ + /* portnumber on host */ + + HostPort = (HostMapP->ID - 1) * PORTS_PER_RTA + SubEnt; + + rio_dprintk(RIO_DEBUG_TABLE, "c1 p = %p, p->rioPortp = %p\n", p, p->RIOPortp); + PortP = p->RIOPortp[SysPort]; + rio_dprintk(RIO_DEBUG_TABLE, "Map port\n"); + + /* + ** Point at all the real neat data structures + */ + rio_spin_lock_irqsave(&PortP->portSem, flags); + PortP->HostP = HostP; + PortP->Caddr = HostP->Caddr; + + /* + ** The PhbP cannot be filled in yet + ** unless the host has been booted + */ + if ((HostP->Flags & RUN_STATE) == RC_RUNNING) { + struct PHB __iomem *PhbP = PortP->PhbP = &HostP->PhbP[HostPort]; + PortP->TxAdd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_add)); + PortP->TxStart = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_start)); + PortP->TxEnd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_end)); + PortP->RxRemove = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_remove)); + PortP->RxStart = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_start)); + PortP->RxEnd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_end)); + } else + PortP->PhbP = NULL; + + /* + ** port related flags + */ + PortP->HostPort = HostPort; + /* + ** For each part of a 16 port RTA, RupNum is ID - 1. + */ + PortP->RupNum = HostMapP->ID - 1; + if (HostMapP->Flags & RTA16_SECOND_SLOT) { + PortP->ID2 = HostMapP->ID2 - 1; + PortP->SecondBlock = 1; + } else { + PortP->ID2 = 0; + PortP->SecondBlock = 0; + } + PortP->RtaUniqueNum = HostMapP->RtaUniqueNum; + + /* + ** If the port was already mapped then thats all we need to do. + */ + if (PortP->Mapped) { + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + continue; + } else + HostMapP->Flags &= ~RTA_NEWBOOT; + + PortP->State = 0; + PortP->Config = 0; + /* + ** Check out the module type - if it is special (read only etc.) + ** then we need to set flags in the PortP->Config. + ** Note: For 16 port RTA, all ports are of the same type. + */ + if (RtaType == TYPE_RTA16) { + PortP->Config |= p->RIOModuleTypes[HostP->UnixRups[HostMapP->ID - 1].ModTypes].Flags[SubEnt % PORTS_PER_MODULE]; + } else { + if (SubEnt < PORTS_PER_MODULE) + PortP->Config |= p->RIOModuleTypes[LONYBLE(HostP->UnixRups[HostMapP->ID - 1].ModTypes)].Flags[SubEnt % PORTS_PER_MODULE]; + else + PortP->Config |= p->RIOModuleTypes[HINYBLE(HostP->UnixRups[HostMapP->ID - 1].ModTypes)].Flags[SubEnt % PORTS_PER_MODULE]; + } + + /* + ** more port related flags + */ + PortP->PortState = 0; + PortP->ModemLines = 0; + PortP->ModemState = 0; + PortP->CookMode = COOK_WELL; + PortP->ParamSem = 0; + PortP->FlushCmdBodge = 0; + PortP->WflushFlag = 0; + PortP->MagicFlags = 0; + PortP->Lock = 0; + PortP->Store = 0; + PortP->FirstOpen = 1; + + /* + ** Buffers 'n things + */ + PortP->RxDataStart = 0; + PortP->Cor2Copy = 0; + PortP->Name = &HostMapP->Name[0]; + PortP->statsGather = 0; + PortP->txchars = 0; + PortP->rxchars = 0; + PortP->opens = 0; + PortP->closes = 0; + PortP->ioctls = 0; + if (PortP->TxRingBuffer) + memset(PortP->TxRingBuffer, 0, p->RIOBufferSize); + else if (p->RIOBufferSize) { + PortP->TxRingBuffer = kzalloc(p->RIOBufferSize, GFP_KERNEL); + } + PortP->TxBufferOut = 0; + PortP->TxBufferIn = 0; + PortP->Debug = 0; + /* + ** LastRxTgl stores the state of the rx toggle bit for this + ** port, to be compared with the state of the next pkt received. + ** If the same, we have received the same rx pkt from the RTA + ** twice. Initialise to a value not equal to PHB_RX_TGL or 0. + */ + PortP->LastRxTgl = ~(u8) PHB_RX_TGL; + + /* + ** and mark the port as usable + */ + PortP->Mapped = 1; + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + } + if (HostMapP->SysPort < p->RIOFirstPortsMapped) + p->RIOFirstPortsMapped = HostMapP->SysPort; + if (HostMapP->SysPort > p->RIOLastPortsMapped) + p->RIOLastPortsMapped = HostMapP->SysPort; + + return 0; +} + +int RIOChangeName(struct rio_info *p, struct Map *MapP) +{ + int host; + struct Map *HostMapP; + char *sptr; + + rio_dprintk(RIO_DEBUG_TABLE, "Change name entry on host %x, rta %x, ID %d, Sysport %d\n", MapP->HostUniqueNum, MapP->RtaUniqueNum, MapP->ID, (int) MapP->SysPort); + + if (MapP->ID > MAX_RUP) { + rio_dprintk(RIO_DEBUG_TABLE, "Bad ID in map entry!\n"); + p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE; + return -EINVAL; + } + + MapP->Name[MAX_NAME_LEN - 1] = '\0'; + sptr = MapP->Name; + + while (*sptr) { + if (*sptr < ' ' || *sptr > '~') { + rio_dprintk(RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n"); + p->RIOError.Error = BAD_CHARACTER_IN_NAME; + return -EINVAL; + } + sptr++; + } + + for (host = 0; host < p->RIONumHosts; host++) { + if (MapP->HostUniqueNum == p->RIOHosts[host].UniqueNum) { + if ((p->RIOHosts[host].Flags & RUN_STATE) != RC_RUNNING) { + p->RIOError.Error = HOST_NOT_RUNNING; + return -ENXIO; + } + if (MapP->ID == 0) { + memcpy(p->RIOHosts[host].Name, MapP->Name, MAX_NAME_LEN); + return 0; + } + + HostMapP = &p->RIOHosts[host].Mapping[MapP->ID - 1]; + + if (HostMapP->RtaUniqueNum != MapP->RtaUniqueNum) { + p->RIOError.Error = RTA_NUMBER_WRONG; + return -ENXIO; + } + memcpy(HostMapP->Name, MapP->Name, MAX_NAME_LEN); + return 0; + } + } + p->RIOError.Error = UNKNOWN_HOST_NUMBER; + rio_dprintk(RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum); + return -ENXIO; +} diff --git a/drivers/staging/generic_serial/rio/riotty.c b/drivers/staging/generic_serial/rio/riotty.c new file mode 100644 index 000000000000..8a90393faf3c --- /dev/null +++ b/drivers/staging/generic_serial/rio/riotty.c @@ -0,0 +1,654 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : riotty.c +** SID : 1.3 +** Last Modified : 11/6/98 10:33:47 +** Retrieved : 11/6/98 10:33:50 +** +** ident @(#)riotty.c 1.3 +** +** ----------------------------------------------------------------------------- +*/ + +#define __EXPLICIT_DEF_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + + +#include "linux_compat.h" +#include "rio_linux.h" +#include "pkt.h" +#include "daemon.h" +#include "rio.h" +#include "riospace.h" +#include "cmdpkt.h" +#include "map.h" +#include "rup.h" +#include "port.h" +#include "riodrvr.h" +#include "rioinfo.h" +#include "func.h" +#include "errors.h" +#include "pci.h" + +#include "parmmap.h" +#include "unixrup.h" +#include "board.h" +#include "host.h" +#include "phb.h" +#include "link.h" +#include "cmdblk.h" +#include "route.h" +#include "cirrus.h" +#include "rioioctl.h" +#include "param.h" + +static void RIOClearUp(struct Port *PortP); + +/* Below belongs in func.h */ +int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg); + + +extern struct rio_info *p; + + +int riotopen(struct tty_struct *tty, struct file *filp) +{ + unsigned int SysPort; + int repeat_this = 250; + struct Port *PortP; /* pointer to the port structure */ + unsigned long flags; + int retval = 0; + + func_enter(); + + /* Make sure driver_data is NULL in case the rio isn't booted jet. Else gs_close + is going to oops. + */ + tty->driver_data = NULL; + + SysPort = rio_minor(tty); + + if (p->RIOFailed) { + rio_dprintk(RIO_DEBUG_TTY, "System initialisation failed\n"); + func_exit(); + return -ENXIO; + } + + rio_dprintk(RIO_DEBUG_TTY, "port open SysPort %d (mapped:%d)\n", SysPort, p->RIOPortp[SysPort]->Mapped); + + /* + ** Validate that we have received a legitimate request. + ** Currently, just check that we are opening a port on + ** a host card that actually exists, and that the port + ** has been mapped onto a host. + */ + if (SysPort >= RIO_PORTS) { /* out of range ? */ + rio_dprintk(RIO_DEBUG_TTY, "Illegal port number %d\n", SysPort); + func_exit(); + return -ENXIO; + } + + /* + ** Grab pointer to the port stucture + */ + PortP = p->RIOPortp[SysPort]; /* Get control struc */ + rio_dprintk(RIO_DEBUG_TTY, "PortP: %p\n", PortP); + if (!PortP->Mapped) { /* we aren't mapped yet! */ + /* + ** The system doesn't know which RTA this port + ** corresponds to. + */ + rio_dprintk(RIO_DEBUG_TTY, "port not mapped into system\n"); + func_exit(); + return -ENXIO; + } + + tty->driver_data = PortP; + + PortP->gs.port.tty = tty; + PortP->gs.port.count++; + + rio_dprintk(RIO_DEBUG_TTY, "%d bytes in tx buffer\n", PortP->gs.xmit_cnt); + + retval = gs_init_port(&PortP->gs); + if (retval) { + PortP->gs.port.count--; + return -ENXIO; + } + /* + ** If the host hasn't been booted yet, then + ** fail + */ + if ((PortP->HostP->Flags & RUN_STATE) != RC_RUNNING) { + rio_dprintk(RIO_DEBUG_TTY, "Host not running\n"); + func_exit(); + return -ENXIO; + } + + /* + ** If the RTA has not booted yet and the user has choosen to block + ** until the RTA is present then we must spin here waiting for + ** the RTA to boot. + */ + /* I find the above code a bit hairy. I find the below code + easier to read and shorter. Now, if it works too that would + be great... -- REW + */ + rio_dprintk(RIO_DEBUG_TTY, "Checking if RTA has booted... \n"); + while (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) { + if (!PortP->WaitUntilBooted) { + rio_dprintk(RIO_DEBUG_TTY, "RTA never booted\n"); + func_exit(); + return -ENXIO; + } + + /* Under Linux you'd normally use a wait instead of this + busy-waiting. I'll stick with the old implementation for + now. --REW + */ + if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { + rio_dprintk(RIO_DEBUG_TTY, "RTA_wait_for_boot: EINTR in delay \n"); + func_exit(); + return -EINTR; + } + if (repeat_this-- <= 0) { + rio_dprintk(RIO_DEBUG_TTY, "Waiting for RTA to boot timeout\n"); + func_exit(); + return -EIO; + } + } + rio_dprintk(RIO_DEBUG_TTY, "RTA has been booted\n"); + rio_spin_lock_irqsave(&PortP->portSem, flags); + if (p->RIOHalted) { + goto bombout; + } + + /* + ** If the port is in the final throws of being closed, + ** we should wait here (politely), waiting + ** for it to finish, so that it doesn't close us! + */ + while ((PortP->State & RIO_CLOSING) && !p->RIOHalted) { + rio_dprintk(RIO_DEBUG_TTY, "Waiting for RIO_CLOSING to go away\n"); + if (repeat_this-- <= 0) { + rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n"); + RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); + retval = -EINTR; + goto bombout; + } + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { + rio_spin_lock_irqsave(&PortP->portSem, flags); + retval = -EINTR; + goto bombout; + } + rio_spin_lock_irqsave(&PortP->portSem, flags); + } + + if (!PortP->Mapped) { + rio_dprintk(RIO_DEBUG_TTY, "Port unmapped while closing!\n"); + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + retval = -ENXIO; + func_exit(); + return retval; + } + + if (p->RIOHalted) { + goto bombout; + } + +/* +** 15.10.1998 ARG - ESIL 0761 part fix +** RIO has it's own CTSFLOW and RTSFLOW flags in 'Config' in the port structure, +** we need to make sure that the flags are clear when the port is opened. +*/ + /* Uh? Suppose I turn these on and then another process opens + the port again? The flags get cleared! Not good. -- REW */ + if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) { + PortP->Config &= ~(RIO_CTSFLOW | RIO_RTSFLOW); + } + + if (!(PortP->firstOpen)) { /* First time ? */ + rio_dprintk(RIO_DEBUG_TTY, "First open for this port\n"); + + + PortP->firstOpen++; + PortP->CookMode = 0; /* XXX RIOCookMode(tp); */ + PortP->InUse = NOT_INUSE; + + /* Tentative fix for bug PR27. Didn't work. */ + /* PortP->gs.xmit_cnt = 0; */ + + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + + /* Someone explain to me why this delay/config is + here. If I read the docs correctly the "open" + command piggybacks the parameters immediately. + -- REW */ + RIOParam(PortP, RIOC_OPEN, 1, OK_TO_SLEEP); /* Open the port */ + rio_spin_lock_irqsave(&PortP->portSem, flags); + + /* + ** wait for the port to be not closed. + */ + while (!(PortP->PortState & PORT_ISOPEN) && !p->RIOHalted) { + rio_dprintk(RIO_DEBUG_TTY, "Waiting for PORT_ISOPEN-currently %x\n", PortP->PortState); + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { + rio_dprintk(RIO_DEBUG_TTY, "Waiting for open to finish broken by signal\n"); + RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); + func_exit(); + return -EINTR; + } + rio_spin_lock_irqsave(&PortP->portSem, flags); + } + + if (p->RIOHalted) { + retval = -EIO; + bombout: + /* RIOClearUp( PortP ); */ + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return retval; + } + rio_dprintk(RIO_DEBUG_TTY, "PORT_ISOPEN found\n"); + } + rio_dprintk(RIO_DEBUG_TTY, "Modem - test for carrier\n"); + /* + ** ACTION + ** insert test for carrier here. -- ??? + ** I already see that test here. What's the deal? -- REW + */ + if ((PortP->gs.port.tty->termios->c_cflag & CLOCAL) || + (PortP->ModemState & RIOC_MSVR1_CD)) { + rio_dprintk(RIO_DEBUG_TTY, "open(%d) Modem carr on\n", SysPort); + /* + tp->tm.c_state |= CARR_ON; + wakeup((caddr_t) &tp->tm.c_canq); + */ + PortP->State |= RIO_CARR_ON; + wake_up_interruptible(&PortP->gs.port.open_wait); + } else { /* no carrier - wait for DCD */ + /* + while (!(PortP->gs.port.tty->termios->c_state & CARR_ON) && + !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted ) + */ + while (!(PortP->State & RIO_CARR_ON) && !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted) { + rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr on\n", SysPort); + /* + PortP->gs.port.tty->termios->c_state |= WOPEN; + */ + PortP->State |= RIO_WOPEN; + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { + rio_spin_lock_irqsave(&PortP->portSem, flags); + /* + ** ACTION: verify that this is a good thing + ** to do here. -- ??? + ** I think it's OK. -- REW + */ + rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr broken by signal\n", SysPort); + RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); + /* + tp->tm.c_state &= ~WOPEN; + */ + PortP->State &= ~RIO_WOPEN; + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + func_exit(); + return -EINTR; + } + rio_spin_lock_irqsave(&PortP->portSem, flags); + } + PortP->State &= ~RIO_WOPEN; + } + if (p->RIOHalted) + goto bombout; + rio_dprintk(RIO_DEBUG_TTY, "Setting RIO_MOPEN\n"); + PortP->State |= RIO_MOPEN; + + if (p->RIOHalted) + goto bombout; + + rio_dprintk(RIO_DEBUG_TTY, "high level open done\n"); + + /* + ** Count opens for port statistics reporting + */ + if (PortP->statsGather) + PortP->opens++; + + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + rio_dprintk(RIO_DEBUG_TTY, "Returning from open\n"); + func_exit(); + return 0; +} + +/* +** RIOClose the port. +** The operating system thinks that this is last close for the device. +** As there are two interfaces to the port (Modem and tty), we need to +** check that both are closed before we close the device. +*/ +int riotclose(void *ptr) +{ + struct Port *PortP = ptr; /* pointer to the port structure */ + int deleted = 0; + int try = -1; /* Disable the timeouts by setting them to -1 */ + int repeat_this = -1; /* Congrats to those having 15 years of + uptime! (You get to break the driver.) */ + unsigned long end_time; + struct tty_struct *tty; + unsigned long flags; + int rv = 0; + + rio_dprintk(RIO_DEBUG_TTY, "port close SysPort %d\n", PortP->PortNum); + + /* PortP = p->RIOPortp[SysPort]; */ + rio_dprintk(RIO_DEBUG_TTY, "Port is at address %p\n", PortP); + /* tp = PortP->TtyP; *//* Get tty */ + tty = PortP->gs.port.tty; + rio_dprintk(RIO_DEBUG_TTY, "TTY is at address %p\n", tty); + + if (PortP->gs.closing_wait) + end_time = jiffies + PortP->gs.closing_wait; + else + end_time = jiffies + MAX_SCHEDULE_TIMEOUT; + + rio_spin_lock_irqsave(&PortP->portSem, flags); + + /* + ** Setting this flag will make any process trying to open + ** this port block until we are complete closing it. + */ + PortP->State |= RIO_CLOSING; + + if ((PortP->State & RIO_DELETED)) { + rio_dprintk(RIO_DEBUG_TTY, "Close on deleted RTA\n"); + deleted = 1; + } + + if (p->RIOHalted) { + RIOClearUp(PortP); + rv = -EIO; + goto close_end; + } + + rio_dprintk(RIO_DEBUG_TTY, "Clear bits\n"); + /* + ** clear the open bits for this device + */ + PortP->State &= ~RIO_MOPEN; + PortP->State &= ~RIO_CARR_ON; + PortP->ModemState &= ~RIOC_MSVR1_CD; + /* + ** If the device was open as both a Modem and a tty line + ** then we need to wimp out here, as the port has not really + ** been finally closed (gee, whizz!) The test here uses the + ** bit for the OTHER mode of operation, to see if THAT is + ** still active! + */ + if ((PortP->State & (RIO_LOPEN | RIO_MOPEN))) { + /* + ** The port is still open for the other task - + ** return, pretending that we are still active. + */ + rio_dprintk(RIO_DEBUG_TTY, "Channel %d still open !\n", PortP->PortNum); + PortP->State &= ~RIO_CLOSING; + if (PortP->firstOpen) + PortP->firstOpen--; + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return -EIO; + } + + rio_dprintk(RIO_DEBUG_TTY, "Closing down - everything must go!\n"); + + PortP->State &= ~RIO_DYNOROD; + + /* + ** This is where we wait for the port + ** to drain down before closing. Bye-bye.... + ** (We never meant to do this) + */ + rio_dprintk(RIO_DEBUG_TTY, "Timeout 1 starts\n"); + + if (!deleted) + while ((PortP->InUse != NOT_INUSE) && !p->RIOHalted && (PortP->TxBufferIn != PortP->TxBufferOut)) { + if (repeat_this-- <= 0) { + rv = -EINTR; + rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n"); + RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); + goto close_end; + } + rio_dprintk(RIO_DEBUG_TTY, "Calling timeout to flush in closing\n"); + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + if (RIODelay_ni(PortP, HUNDRED_MS * 10) == RIO_FAIL) { + rio_dprintk(RIO_DEBUG_TTY, "RTA EINTR in delay \n"); + rv = -EINTR; + rio_spin_lock_irqsave(&PortP->portSem, flags); + goto close_end; + } + rio_spin_lock_irqsave(&PortP->portSem, flags); + } + + PortP->TxBufferIn = PortP->TxBufferOut = 0; + repeat_this = 0xff; + + PortP->InUse = 0; + if ((PortP->State & (RIO_LOPEN | RIO_MOPEN))) { + /* + ** The port has been re-opened for the other task - + ** return, pretending that we are still active. + */ + rio_dprintk(RIO_DEBUG_TTY, "Channel %d re-open!\n", PortP->PortNum); + PortP->State &= ~RIO_CLOSING; + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + if (PortP->firstOpen) + PortP->firstOpen--; + return -EIO; + } + + if (p->RIOHalted) { + RIOClearUp(PortP); + goto close_end; + } + + /* Can't call RIOShortCommand with the port locked. */ + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + + if (RIOShortCommand(p, PortP, RIOC_CLOSE, 1, 0) == RIO_FAIL) { + RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); + rio_spin_lock_irqsave(&PortP->portSem, flags); + goto close_end; + } + + if (!deleted) + while (try && (PortP->PortState & PORT_ISOPEN)) { + try--; + if (time_after(jiffies, end_time)) { + rio_dprintk(RIO_DEBUG_TTY, "Run out of tries - force the bugger shut!\n"); + RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); + break; + } + rio_dprintk(RIO_DEBUG_TTY, "Close: PortState:ISOPEN is %d\n", PortP->PortState & PORT_ISOPEN); + + if (p->RIOHalted) { + RIOClearUp(PortP); + rio_spin_lock_irqsave(&PortP->portSem, flags); + goto close_end; + } + if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { + rio_dprintk(RIO_DEBUG_TTY, "RTA EINTR in delay \n"); + RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); + break; + } + } + rio_spin_lock_irqsave(&PortP->portSem, flags); + rio_dprintk(RIO_DEBUG_TTY, "Close: try was %d on completion\n", try); + + /* RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); */ + +/* +** 15.10.1998 ARG - ESIL 0761 part fix +** RIO has it's own CTSFLOW and RTSFLOW flags in 'Config' in the port structure,** we need to make sure that the flags are clear when the port is opened. +*/ + PortP->Config &= ~(RIO_CTSFLOW | RIO_RTSFLOW); + + /* + ** Count opens for port statistics reporting + */ + if (PortP->statsGather) + PortP->closes++; + +close_end: + /* XXX: Why would a "DELETED" flag be reset here? I'd have + thought that a "deleted" flag means that the port was + permanently gone, but here we can make it reappear by it + being in close during the "deletion". + */ + PortP->State &= ~(RIO_CLOSING | RIO_DELETED); + if (PortP->firstOpen) + PortP->firstOpen--; + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + rio_dprintk(RIO_DEBUG_TTY, "Return from close\n"); + return rv; +} + + + +static void RIOClearUp(struct Port *PortP) +{ + rio_dprintk(RIO_DEBUG_TTY, "RIOHalted set\n"); + PortP->Config = 0; /* Direct semaphore */ + PortP->PortState = 0; + PortP->firstOpen = 0; + PortP->FlushCmdBodge = 0; + PortP->ModemState = PortP->CookMode = 0; + PortP->Mapped = 0; + PortP->WflushFlag = 0; + PortP->MagicFlags = 0; + PortP->RxDataStart = 0; + PortP->TxBufferIn = 0; + PortP->TxBufferOut = 0; +} + +/* +** Put a command onto a port. +** The PortPointer, command, length and arg are passed. +** The len is the length *inclusive* of the command byte, +** and so for a command that takes no data, len==1. +** The arg is a single byte, and is only used if len==2. +** Other values of len aren't allowed, and will cause +** a panic. +*/ +int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg) +{ + struct PKT __iomem *PacketP; + int retries = 20; /* at 10 per second -> 2 seconds */ + unsigned long flags; + + rio_dprintk(RIO_DEBUG_TTY, "entering shortcommand.\n"); + + if (PortP->State & RIO_DELETED) { + rio_dprintk(RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n"); + return RIO_FAIL; + } + rio_spin_lock_irqsave(&PortP->portSem, flags); + + /* + ** If the port is in use for pre-emptive command, then wait for it to + ** be free again. + */ + while ((PortP->InUse != NOT_INUSE) && !p->RIOHalted) { + rio_dprintk(RIO_DEBUG_TTY, "Waiting for not in use (%d)\n", retries); + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + if (retries-- <= 0) { + return RIO_FAIL; + } + if (RIODelay_ni(PortP, HUNDRED_MS) == RIO_FAIL) { + return RIO_FAIL; + } + rio_spin_lock_irqsave(&PortP->portSem, flags); + } + if (PortP->State & RIO_DELETED) { + rio_dprintk(RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n"); + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return RIO_FAIL; + } + + while (!can_add_transmit(&PacketP, PortP) && !p->RIOHalted) { + rio_dprintk(RIO_DEBUG_TTY, "Waiting to add short command to queue (%d)\n", retries); + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + if (retries-- <= 0) { + rio_dprintk(RIO_DEBUG_TTY, "out of tries. Failing\n"); + return RIO_FAIL; + } + if (RIODelay_ni(PortP, HUNDRED_MS) == RIO_FAIL) { + return RIO_FAIL; + } + rio_spin_lock_irqsave(&PortP->portSem, flags); + } + + if (p->RIOHalted) { + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return RIO_FAIL; + } + + /* + ** set the command byte and the argument byte + */ + writeb(command, &PacketP->data[0]); + + if (len == 2) + writeb(arg, &PacketP->data[1]); + + /* + ** set the length of the packet and set the command bit. + */ + writeb(PKT_CMD_BIT | len, &PacketP->len); + + add_transmit(PortP); + /* + ** Count characters transmitted for port statistics reporting + */ + if (PortP->statsGather) + PortP->txchars += len; + + rio_spin_unlock_irqrestore(&PortP->portSem, flags); + return p->RIOHalted ? RIO_FAIL : ~RIO_FAIL; +} + + diff --git a/drivers/staging/generic_serial/rio/route.h b/drivers/staging/generic_serial/rio/route.h new file mode 100644 index 000000000000..46e963771c30 --- /dev/null +++ b/drivers/staging/generic_serial/rio/route.h @@ -0,0 +1,101 @@ +/**************************************************************************** + ******* ******* + ******* R O U T E H E A D E R + ******* ******* + **************************************************************************** + + Author : Ian Nandhra / Jeremy Rolls + Date : + + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Version : 0.01 + + + Mods + ---------------------------------------------------------------------------- + Date By Description + ---------------------------------------------------------------------------- + + ***************************************************************************/ + +#ifndef _route_h +#define _route_h + +#define MAX_LINKS 4 +#define MAX_NODES 17 /* Maximum nodes in a subnet */ +#define NODE_BYTES ((MAX_NODES / 8) + 1) /* Number of bytes needed for + 1 bit per node */ +#define ROUTE_DATA_SIZE (NODE_BYTES + 2) /* Number of bytes for complete + info about cost etc. */ +#define ROUTES_PER_PACKET ((PKT_MAX_DATA_LEN -2)/ ROUTE_DATA_SIZE) + /* Number of nodes we can squeeze + into one packet */ +#define MAX_TOPOLOGY_PACKETS (MAX_NODES / ROUTES_PER_PACKET + 1) +/************************************************ + * Define the types of command for the ROUTE RUP. + ************************************************/ +#define ROUTE_REQUEST 0 /* Request an ID */ +#define ROUTE_FOAD 1 /* Kill the RTA */ +#define ROUTE_ALREADY 2 /* ID given already */ +#define ROUTE_USED 3 /* All ID's used */ +#define ROUTE_ALLOCATE 4 /* Here it is */ +#define ROUTE_REQ_TOP 5 /* I bet you didn't expect.... + the Topological Inquisition */ +#define ROUTE_TOPOLOGY 6 /* Topology request answered FD */ +/******************************************************************* + * Define the Route Map Structure + * + * The route map gives a pointer to a Link Structure to use. + * This allows Disconnected Links to be checked quickly + ******************************************************************/ +typedef struct COST_ROUTE COST_ROUTE; +struct COST_ROUTE { + unsigned char cost; /* Cost down this link */ + unsigned char route[NODE_BYTES]; /* Nodes through this route */ +}; + +typedef struct ROUTE_STR ROUTE_STR; +struct ROUTE_STR { + COST_ROUTE cost_route[MAX_LINKS]; + /* cost / route for this link */ + ushort favoured; /* favoured link */ +}; + + +#define NO_LINK (short) 5 /* Link unattached */ +#define ROUTE_NO_ID (short) 100 /* No Id */ +#define ROUTE_DISCONNECT (ushort) 0xff /* Not connected */ +#define ROUTE_INTERCONNECT (ushort) 0x40 /* Sub-net interconnect */ + + +#define SYNC_RUP (ushort) 255 +#define COMMAND_RUP (ushort) 254 +#define ERROR_RUP (ushort) 253 +#define POLL_RUP (ushort) 252 +#define BOOT_RUP (ushort) 251 +#define ROUTE_RUP (ushort) 250 +#define STATUS_RUP (ushort) 249 +#define POWER_RUP (ushort) 248 + +#define HIGHEST_RUP (ushort) 255 /* Set to Top one */ +#define LOWEST_RUP (ushort) 248 /* Set to bottom one */ + +#endif + +/*********** end of file ***********/ diff --git a/drivers/staging/generic_serial/rio/rup.h b/drivers/staging/generic_serial/rio/rup.h new file mode 100644 index 000000000000..4ae90cb207a9 --- /dev/null +++ b/drivers/staging/generic_serial/rio/rup.h @@ -0,0 +1,69 @@ +/**************************************************************************** + ******* ******* + ******* R U P S T R U C T U R E + ******* ******* + **************************************************************************** + + Author : Ian Nandhra + Date : + + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Version : 0.01 + + + Mods + ---------------------------------------------------------------------------- + Date By Description + ---------------------------------------------------------------------------- + + ***************************************************************************/ + +#ifndef _rup_h +#define _rup_h 1 + +#define MAX_RUP ((short) 16) +#define PKTS_PER_RUP ((short) 2) /* They are always used in pairs */ + +/************************************************* + * Define all the packet request stuff + ************************************************/ +#define TX_RUP_INACTIVE 0 /* Nothing to transmit */ +#define TX_PACKET_READY 1 /* Transmit packet ready */ +#define TX_LOCK_RUP 2 /* Transmit side locked */ + +#define RX_RUP_INACTIVE 0 /* Nothing received */ +#define RX_PACKET_READY 1 /* Packet received */ + +#define RUP_NO_OWNER 0xff /* RUP not owned by any process */ + +struct RUP { + u16 txpkt; /* Outgoing packet */ + u16 rxpkt; /* Incoming packet */ + u16 link; /* Which link to send down? */ + u8 rup_dest_unit[2]; /* Destination unit */ + u16 handshake; /* For handshaking */ + u16 timeout; /* Timeout */ + u16 status; /* Status */ + u16 txcontrol; /* Transmit control */ + u16 rxcontrol; /* Receive control */ +}; + +#endif + +/*********** end of file ***********/ diff --git a/drivers/staging/generic_serial/rio/unixrup.h b/drivers/staging/generic_serial/rio/unixrup.h new file mode 100644 index 000000000000..7abf0cba0f2c --- /dev/null +++ b/drivers/staging/generic_serial/rio/unixrup.h @@ -0,0 +1,51 @@ +/* +** ----------------------------------------------------------------------------- +** +** Perle Specialix driver for Linux +** Ported from existing RIO Driver for SCO sources. + * + * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Module : unixrup.h +** SID : 1.2 +** Last Modified : 11/6/98 11:34:20 +** Retrieved : 11/6/98 11:34:22 +** +** ident @(#)unixrup.h 1.2 +** +** ----------------------------------------------------------------------------- +*/ + +#ifndef __rio_unixrup_h__ +#define __rio_unixrup_h__ + +/* +** UnixRup data structure. This contains pointers to actual RUPs on the +** host card, and all the command/boot control stuff. +*/ +struct UnixRup { + struct CmdBlk *CmdsWaitingP; /* Commands waiting to be done */ + struct CmdBlk *CmdPendingP; /* The command currently being sent */ + struct RUP __iomem *RupP; /* the Rup to send it to */ + unsigned int Id; /* Id number */ + unsigned int BaseSysPort; /* SysPort of first tty on this RTA */ + unsigned int ModTypes; /* Modules on this RTA */ + spinlock_t RupLock; /* Lock structure for MPX */ + /* struct lockb RupLock; *//* Lock structure for MPX */ +}; + +#endif /* __rio_unixrup_h__ */ diff --git a/drivers/staging/generic_serial/ser_a2232.c b/drivers/staging/generic_serial/ser_a2232.c new file mode 100644 index 000000000000..3f47c2ead8e5 --- /dev/null +++ b/drivers/staging/generic_serial/ser_a2232.c @@ -0,0 +1,831 @@ +/* drivers/char/ser_a2232.c */ + +/* $Id: ser_a2232.c,v 0.4 2000/01/25 12:00:00 ehaase Exp $ */ + +/* Linux serial driver for the Amiga A2232 board */ + +/* This driver is MAINTAINED. Before applying any changes, please contact + * the author. + */ + +/* Copyright (c) 2000-2001 Enver Haase + * alias The A2232 driver project + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +/***************************** Documentation ************************/ +/* + * This driver is in EXPERIMENTAL state. That means I could not find + * someone with five A2232 boards with 35 ports running at 19200 bps + * at the same time and test the machine's behaviour. + * However, I know that you can performance-tweak this driver (see + * the source code). + * One thing to consider is the time this driver consumes during the + * Amiga's vertical blank interrupt. Everything that is to be done + * _IS DONE_ when entering the vertical blank interrupt handler of + * this driver. + * However, it would be more sane to only do the job for only ONE card + * instead of ALL cards at a time; or, more generally, to handle only + * SOME ports instead of ALL ports at a time. + * However, as long as no-one runs into problems I guess I shouldn't + * change the driver as it runs fine for me :) . + * + * Version history of this file: + * 0.4 Resolved licensing issues. + * 0.3 Inclusion in the Linux/m68k tree, small fixes. + * 0.2 Added documentation, minor typo fixes. + * 0.1 Initial release. + * + * TO DO: + * - Handle incoming BREAK events. I guess "Stevens: Advanced + * Programming in the UNIX(R) Environment" is a good reference + * on what is to be done. + * - When installing as a module, don't simply 'printk' text, but + * send it to the TTY used by the user. + * + * THANKS TO: + * - Jukka Marin (65EC02 code). + * - The other NetBSD developers on whose A2232 driver I had a + * pretty close look. However, I didn't copy any code so it + * is okay to put my code under the GPL and include it into + * Linux. + */ +/***************************** End of Documentation *****************/ + +/***************************** Defines ******************************/ +/* + * Enables experimental 115200 (normal) 230400 (turbo) baud rate. + * The A2232 specification states it can only operate at speeds up to + * 19200 bits per second, and I was not able to send a file via + * "sz"/"rz" and a null-modem cable from one A2232 port to another + * at 115200 bits per second. + * However, this might work for you. + */ +#undef A2232_SPEEDHACK +/* + * Default is not to use RTS/CTS so you could be talked to death. + */ +#define A2232_SUPPRESS_RTSCTS_WARNING +/************************* End of Defines ***************************/ + +/***************************** Includes *****************************/ +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "ser_a2232.h" +#include "ser_a2232fw.h" +/************************* End of Includes **************************/ + +/***************************** Prototypes ***************************/ +/* The interrupt service routine */ +static irqreturn_t a2232_vbl_inter(int irq, void *data); +/* Initialize the port structures */ +static void a2232_init_portstructs(void); +/* Initialize and register TTY drivers. */ +/* returns 0 IFF successful */ +static int a2232_init_drivers(void); + +/* BEGIN GENERIC_SERIAL PROTOTYPES */ +static void a2232_disable_tx_interrupts(void *ptr); +static void a2232_enable_tx_interrupts(void *ptr); +static void a2232_disable_rx_interrupts(void *ptr); +static void a2232_enable_rx_interrupts(void *ptr); +static int a2232_carrier_raised(struct tty_port *port); +static void a2232_shutdown_port(void *ptr); +static int a2232_set_real_termios(void *ptr); +static int a2232_chars_in_buffer(void *ptr); +static void a2232_close(void *ptr); +static void a2232_hungup(void *ptr); +/* static void a2232_getserial (void *ptr, struct serial_struct *sp); */ +/* END GENERIC_SERIAL PROTOTYPES */ + +/* Functions that the TTY driver struct expects */ +static int a2232_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg); +static void a2232_throttle(struct tty_struct *tty); +static void a2232_unthrottle(struct tty_struct *tty); +static int a2232_open(struct tty_struct * tty, struct file * filp); +/************************* End of Prototypes ************************/ + +/***************************** Global variables *********************/ +/*--------------------------------------------------------------------------- + * Interface from generic_serial.c back here + *--------------------------------------------------------------------------*/ +static struct real_driver a2232_real_driver = { + a2232_disable_tx_interrupts, + a2232_enable_tx_interrupts, + a2232_disable_rx_interrupts, + a2232_enable_rx_interrupts, + a2232_shutdown_port, + a2232_set_real_termios, + a2232_chars_in_buffer, + a2232_close, + a2232_hungup, + NULL /* a2232_getserial */ +}; + +static void *a2232_driver_ID = &a2232_driver_ID; // Some memory address WE own. + +/* Ports structs */ +static struct a2232_port a2232_ports[MAX_A2232_BOARDS*NUMLINES]; + +/* TTY driver structs */ +static struct tty_driver *a2232_driver; + +/* nr of cards completely (all ports) and correctly configured */ +static int nr_a2232; + +/* zorro_dev structs for the A2232's */ +static struct zorro_dev *zd_a2232[MAX_A2232_BOARDS]; +/***************************** End of Global variables **************/ + +/* Helper functions */ + +static inline volatile struct a2232memory *a2232mem(unsigned int board) +{ + return (volatile struct a2232memory *)ZTWO_VADDR(zd_a2232[board]->resource.start); +} + +static inline volatile struct a2232status *a2232stat(unsigned int board, + unsigned int portonboard) +{ + volatile struct a2232memory *mem = a2232mem(board); + return &(mem->Status[portonboard]); +} + +static inline void a2232_receive_char(struct a2232_port *port, int ch, int err) +{ +/* Mostly stolen from other drivers. + Maybe one could implement a more efficient version by not only + transferring one character at a time. +*/ + struct tty_struct *tty = port->gs.port.tty; + +#if 0 + switch(err) { + case TTY_BREAK: + break; + case TTY_PARITY: + break; + case TTY_OVERRUN: + break; + case TTY_FRAME: + break; + } +#endif + + tty_insert_flip_char(tty, ch, err); + tty_flip_buffer_push(tty); +} + +/***************************** Functions ****************************/ +/*** BEGIN OF REAL_DRIVER FUNCTIONS ***/ + +static void a2232_disable_tx_interrupts(void *ptr) +{ + struct a2232_port *port; + volatile struct a2232status *stat; + unsigned long flags; + + port = ptr; + stat = a2232stat(port->which_a2232, port->which_port_on_a2232); + stat->OutDisable = -1; + + /* Does this here really have to be? */ + local_irq_save(flags); + port->gs.port.flags &= ~GS_TX_INTEN; + local_irq_restore(flags); +} + +static void a2232_enable_tx_interrupts(void *ptr) +{ + struct a2232_port *port; + volatile struct a2232status *stat; + unsigned long flags; + + port = ptr; + stat = a2232stat(port->which_a2232, port->which_port_on_a2232); + stat->OutDisable = 0; + + /* Does this here really have to be? */ + local_irq_save(flags); + port->gs.port.flags |= GS_TX_INTEN; + local_irq_restore(flags); +} + +static void a2232_disable_rx_interrupts(void *ptr) +{ + struct a2232_port *port; + port = ptr; + port->disable_rx = -1; +} + +static void a2232_enable_rx_interrupts(void *ptr) +{ + struct a2232_port *port; + port = ptr; + port->disable_rx = 0; +} + +static int a2232_carrier_raised(struct tty_port *port) +{ + struct a2232_port *ap = container_of(port, struct a2232_port, gs.port); + return ap->cd_status; +} + +static void a2232_shutdown_port(void *ptr) +{ + struct a2232_port *port; + volatile struct a2232status *stat; + unsigned long flags; + + port = ptr; + stat = a2232stat(port->which_a2232, port->which_port_on_a2232); + + local_irq_save(flags); + + port->gs.port.flags &= ~GS_ACTIVE; + + if (port->gs.port.tty && port->gs.port.tty->termios->c_cflag & HUPCL) { + /* Set DTR and RTS to Low, flush output. + The NetBSD driver "msc.c" does it this way. */ + stat->Command = ( (stat->Command & ~A2232CMD_CMask) | + A2232CMD_Close ); + stat->OutFlush = -1; + stat->Setup = -1; + } + + local_irq_restore(flags); + + /* After analyzing control flow, I think a2232_shutdown_port + is actually the last call from the system when at application + level someone issues a "echo Hello >>/dev/ttyY0". + Therefore I think the MOD_DEC_USE_COUNT should be here and + not in "a2232_close()". See the comment in "sx.c", too. + If you run into problems, compile this driver into the + kernel instead of compiling it as a module. */ +} + +static int a2232_set_real_termios(void *ptr) +{ + unsigned int cflag, baud, chsize, stopb, parity, softflow; + int rate; + int a2232_param, a2232_cmd; + unsigned long flags; + unsigned int i; + struct a2232_port *port = ptr; + volatile struct a2232status *status; + volatile struct a2232memory *mem; + + if (!port->gs.port.tty || !port->gs.port.tty->termios) return 0; + + status = a2232stat(port->which_a2232, port->which_port_on_a2232); + mem = a2232mem(port->which_a2232); + + a2232_param = a2232_cmd = 0; + + // get baud rate + baud = port->gs.baud; + if (baud == 0) { + /* speed == 0 -> drop DTR, do nothing else */ + local_irq_save(flags); + // Clear DTR (and RTS... mhhh). + status->Command = ( (status->Command & ~A2232CMD_CMask) | + A2232CMD_Close ); + status->OutFlush = -1; + status->Setup = -1; + + local_irq_restore(flags); + return 0; + } + + rate = A2232_BAUD_TABLE_NOAVAIL; + for (i=0; i < A2232_BAUD_TABLE_NUM_RATES * 3; i += 3){ + if (a2232_baud_table[i] == baud){ + if (mem->Common.Crystal == A2232_TURBO) rate = a2232_baud_table[i+2]; + else rate = a2232_baud_table[i+1]; + } + } + if (rate == A2232_BAUD_TABLE_NOAVAIL){ + printk("a2232: Board %d Port %d unsupported baud rate: %d baud. Using another.\n",port->which_a2232,port->which_port_on_a2232,baud); + // This is useful for both (turbo or normal) Crystal versions. + rate = A2232PARAM_B9600; + } + a2232_param |= rate; + + cflag = port->gs.port.tty->termios->c_cflag; + + // get character size + chsize = cflag & CSIZE; + switch (chsize){ + case CS8: a2232_param |= A2232PARAM_8Bit; break; + case CS7: a2232_param |= A2232PARAM_7Bit; break; + case CS6: a2232_param |= A2232PARAM_6Bit; break; + case CS5: a2232_param |= A2232PARAM_5Bit; break; + default: printk("a2232: Board %d Port %d unsupported character size: %d. Using 8 data bits.\n", + port->which_a2232,port->which_port_on_a2232,chsize); + a2232_param |= A2232PARAM_8Bit; break; + } + + // get number of stop bits + stopb = cflag & CSTOPB; + if (stopb){ // two stop bits instead of one + printk("a2232: Board %d Port %d 2 stop bits unsupported. Using 1 stop bit.\n", + port->which_a2232,port->which_port_on_a2232); + } + + // Warn if RTS/CTS not wanted + if (!(cflag & CRTSCTS)){ +#ifndef A2232_SUPPRESS_RTSCTS_WARNING + printk("a2232: Board %d Port %d cannot switch off firmware-implemented RTS/CTS hardware flow control.\n", + port->which_a2232,port->which_port_on_a2232); +#endif + } + + /* I think this is correct. + However, IXOFF means _input_ flow control and I wonder + if one should care about IXON _output_ flow control, + too. If this makes problems, one should turn the A2232 + firmware XON/XOFF "SoftFlow" flow control off and use + the conventional way of inserting START/STOP characters + by hand in throttle()/unthrottle(). + */ + softflow = !!( port->gs.port.tty->termios->c_iflag & IXOFF ); + + // get Parity (Enabled/Disabled? If Enabled, Odd or Even?) + parity = cflag & (PARENB | PARODD); + if (parity & PARENB){ + if (parity & PARODD){ + a2232_cmd |= A2232CMD_OddParity; + } + else{ + a2232_cmd |= A2232CMD_EvenParity; + } + } + else a2232_cmd |= A2232CMD_NoParity; + + + /* Hmm. Maybe an own a2232_port structure + member would be cleaner? */ + if (cflag & CLOCAL) + port->gs.port.flags &= ~ASYNC_CHECK_CD; + else + port->gs.port.flags |= ASYNC_CHECK_CD; + + + /* Now we have all parameters and can go to set them: */ + local_irq_save(flags); + + status->Param = a2232_param | A2232PARAM_RcvBaud; + status->Command = a2232_cmd | A2232CMD_Open | A2232CMD_Enable; + status->SoftFlow = softflow; + status->OutDisable = 0; + status->Setup = -1; + + local_irq_restore(flags); + return 0; +} + +static int a2232_chars_in_buffer(void *ptr) +{ + struct a2232_port *port; + volatile struct a2232status *status; + unsigned char ret; /* we need modulo-256 arithmetics */ + port = ptr; + status = a2232stat(port->which_a2232, port->which_port_on_a2232); +#if A2232_IOBUFLEN != 256 +#error "Re-Implement a2232_chars_in_buffer()!" +#endif + ret = (status->OutHead - status->OutTail); + return ret; +} + +static void a2232_close(void *ptr) +{ + a2232_disable_tx_interrupts(ptr); + a2232_disable_rx_interrupts(ptr); + /* see the comment in a2232_shutdown_port above. */ +} + +static void a2232_hungup(void *ptr) +{ + a2232_close(ptr); +} +/*** END OF REAL_DRIVER FUNCTIONS ***/ + +/*** BEGIN FUNCTIONS EXPECTED BY TTY DRIVER STRUCTS ***/ +static int a2232_ioctl( struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + return -ENOIOCTLCMD; +} + +static void a2232_throttle(struct tty_struct *tty) +{ +/* Throttle: System cannot take another chars: Drop RTS or + send the STOP char or whatever. + The A2232 firmware does RTS/CTS anyway, and XON/XOFF + if switched on. So the only thing we can do at this + layer here is not taking any characters out of the + A2232 buffer any more. */ + struct a2232_port *port = tty->driver_data; + port->throttle_input = -1; +} + +static void a2232_unthrottle(struct tty_struct *tty) +{ +/* Unthrottle: dual to "throttle()" above. */ + struct a2232_port *port = tty->driver_data; + port->throttle_input = 0; +} + +static int a2232_open(struct tty_struct * tty, struct file * filp) +{ +/* More or less stolen from other drivers. */ + int line; + int retval; + struct a2232_port *port; + + line = tty->index; + port = &a2232_ports[line]; + + tty->driver_data = port; + port->gs.port.tty = tty; + port->gs.port.count++; + retval = gs_init_port(&port->gs); + if (retval) { + port->gs.port.count--; + return retval; + } + port->gs.port.flags |= GS_ACTIVE; + retval = gs_block_til_ready(port, filp); + + if (retval) { + port->gs.port.count--; + return retval; + } + + a2232_enable_rx_interrupts(port); + + return 0; +} +/*** END OF FUNCTIONS EXPECTED BY TTY DRIVER STRUCTS ***/ + +static irqreturn_t a2232_vbl_inter(int irq, void *data) +{ +#if A2232_IOBUFLEN != 256 +#error "Re-Implement a2232_vbl_inter()!" +#endif + +struct a2232_port *port; +volatile struct a2232memory *mem; +volatile struct a2232status *status; +unsigned char newhead; +unsigned char bufpos; /* Must be unsigned char. We need the modulo-256 arithmetics */ +unsigned char ncd, ocd, ccd; /* names consistent with the NetBSD driver */ +volatile u_char *ibuf, *cbuf, *obuf; +int ch, err, n, p; + for (n = 0; n < nr_a2232; n++){ /* for every completely initialized A2232 board */ + mem = a2232mem(n); + for (p = 0; p < NUMLINES; p++){ /* for every port on this board */ + err = 0; + port = &a2232_ports[n*NUMLINES+p]; + if ( port->gs.port.flags & GS_ACTIVE ){ /* if the port is used */ + + status = a2232stat(n,p); + + if (!port->disable_rx && !port->throttle_input){ /* If input is not disabled */ + newhead = status->InHead; /* 65EC02 write pointer */ + bufpos = status->InTail; + + /* check for input for this port */ + if (newhead != bufpos) { + /* buffer for input chars/events */ + ibuf = mem->InBuf[p]; + + /* data types of bytes in ibuf */ + cbuf = mem->InCtl[p]; + + /* do for all chars */ + while (bufpos != newhead) { + /* which type of input data? */ + switch (cbuf[bufpos]) { + /* switch on input event (CD, BREAK, etc.) */ + case A2232INCTL_EVENT: + switch (ibuf[bufpos++]) { + case A2232EVENT_Break: + /* TODO: Handle BREAK signal */ + break; + /* A2232EVENT_CarrierOn and A2232EVENT_CarrierOff are + handled in a separate queue and should not occur here. */ + case A2232EVENT_Sync: + printk("A2232: 65EC02 software sent SYNC event, don't know what to do. Ignoring."); + break; + default: + printk("A2232: 65EC02 software broken, unknown event type %d occurred.\n",ibuf[bufpos-1]); + } /* event type switch */ + break; + case A2232INCTL_CHAR: + /* Receive incoming char */ + a2232_receive_char(port, ibuf[bufpos], err); + bufpos++; + break; + default: + printk("A2232: 65EC02 software broken, unknown data type %d occurred.\n",cbuf[bufpos]); + bufpos++; + } /* switch on input data type */ + } /* while there's something in the buffer */ + + status->InTail = bufpos; /* tell 65EC02 what we've read */ + + } /* if there was something in the buffer */ + } /* If input is not disabled */ + + /* Now check if there's something to output */ + obuf = mem->OutBuf[p]; + bufpos = status->OutHead; + while ( (port->gs.xmit_cnt > 0) && + (!port->gs.port.tty->stopped) && + (!port->gs.port.tty->hw_stopped) ){ /* While there are chars to transmit */ + if (((bufpos+1) & A2232_IOBUFLENMASK) != status->OutTail) { /* If the A2232 buffer is not full */ + ch = port->gs.xmit_buf[port->gs.xmit_tail]; /* get the next char to transmit */ + port->gs.xmit_tail = (port->gs.xmit_tail+1) & (SERIAL_XMIT_SIZE-1); /* modulo-addition for the gs.xmit_buf ring-buffer */ + obuf[bufpos++] = ch; /* put it into the A2232 buffer */ + port->gs.xmit_cnt--; + } + else{ /* If A2232 the buffer is full */ + break; /* simply stop filling it. */ + } + } + status->OutHead = bufpos; + + /* WakeUp if output buffer runs low */ + if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.port.tty) { + tty_wakeup(port->gs.port.tty); + } + } // if the port is used + } // for every port on the board + + /* Now check the CD message queue */ + newhead = mem->Common.CDHead; + bufpos = mem->Common.CDTail; + if (newhead != bufpos){ /* There are CD events in queue */ + ocd = mem->Common.CDStatus; /* get old status bits */ + while (newhead != bufpos){ /* read all events */ + ncd = mem->CDBuf[bufpos++]; /* get one event */ + ccd = ncd ^ ocd; /* mask of changed lines */ + ocd = ncd; /* save new status bits */ + for(p=0; p < NUMLINES; p++){ /* for all ports */ + if (ccd & 1){ /* this one changed */ + + struct a2232_port *port = &a2232_ports[n*7+p]; + port->cd_status = !(ncd & 1); /* ncd&1 <=> CD is now off */ + + if (!(port->gs.port.flags & ASYNC_CHECK_CD)) + ; /* Don't report DCD changes */ + else if (port->cd_status) { // if DCD on: DCD went UP! + + /* Are we blocking in open?*/ + wake_up_interruptible(&port->gs.port.open_wait); + } + else { // if DCD off: DCD went DOWN! + if (port->gs.port.tty) + tty_hangup (port->gs.port.tty); + } + + } // if CD changed for this port + ccd >>= 1; + ncd >>= 1; /* Shift bits for next line */ + } // for every port + } // while CD events in queue + mem->Common.CDStatus = ocd; /* save new status */ + mem->Common.CDTail = bufpos; /* remove events */ + } // if events in CD queue + + } // for every completely initialized A2232 board + return IRQ_HANDLED; +} + +static const struct tty_port_operations a2232_port_ops = { + .carrier_raised = a2232_carrier_raised, +}; + +static void a2232_init_portstructs(void) +{ + struct a2232_port *port; + int i; + + for (i = 0; i < MAX_A2232_BOARDS*NUMLINES; i++) { + port = a2232_ports + i; + tty_port_init(&port->gs.port); + port->gs.port.ops = &a2232_port_ops; + port->which_a2232 = i/NUMLINES; + port->which_port_on_a2232 = i%NUMLINES; + port->disable_rx = port->throttle_input = port->cd_status = 0; + port->gs.magic = A2232_MAGIC; + port->gs.close_delay = HZ/2; + port->gs.closing_wait = 30 * HZ; + port->gs.rd = &a2232_real_driver; + } +} + +static const struct tty_operations a2232_ops = { + .open = a2232_open, + .close = gs_close, + .write = gs_write, + .put_char = gs_put_char, + .flush_chars = gs_flush_chars, + .write_room = gs_write_room, + .chars_in_buffer = gs_chars_in_buffer, + .flush_buffer = gs_flush_buffer, + .ioctl = a2232_ioctl, + .throttle = a2232_throttle, + .unthrottle = a2232_unthrottle, + .set_termios = gs_set_termios, + .stop = gs_stop, + .start = gs_start, + .hangup = gs_hangup, +}; + +static int a2232_init_drivers(void) +{ + int error; + + a2232_driver = alloc_tty_driver(NUMLINES * nr_a2232); + if (!a2232_driver) + return -ENOMEM; + a2232_driver->owner = THIS_MODULE; + a2232_driver->driver_name = "commodore_a2232"; + a2232_driver->name = "ttyY"; + a2232_driver->major = A2232_NORMAL_MAJOR; + a2232_driver->type = TTY_DRIVER_TYPE_SERIAL; + a2232_driver->subtype = SERIAL_TYPE_NORMAL; + a2232_driver->init_termios = tty_std_termios; + a2232_driver->init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + a2232_driver->init_termios.c_ispeed = 9600; + a2232_driver->init_termios.c_ospeed = 9600; + a2232_driver->flags = TTY_DRIVER_REAL_RAW; + tty_set_operations(a2232_driver, &a2232_ops); + if ((error = tty_register_driver(a2232_driver))) { + printk(KERN_ERR "A2232: Couldn't register A2232 driver, error = %d\n", + error); + put_tty_driver(a2232_driver); + return 1; + } + return 0; +} + +static int __init a2232board_init(void) +{ + struct zorro_dev *z; + + unsigned int boardaddr; + int bcount; + short start; + u_char *from; + volatile u_char *to; + volatile struct a2232memory *mem; + int error, i; + +#ifdef CONFIG_SMP + return -ENODEV; /* This driver is not SMP aware. Is there an SMP ZorroII-bus-machine? */ +#endif + + if (!MACH_IS_AMIGA){ + return -ENODEV; + } + + printk("Commodore A2232 driver initializing.\n"); /* Say that we're alive. */ + + z = NULL; + nr_a2232 = 0; + while ( (z = zorro_find_device(ZORRO_WILDCARD, z)) ){ + if ( (z->id != ZORRO_PROD_CBM_A2232_PROTOTYPE) && + (z->id != ZORRO_PROD_CBM_A2232) ){ + continue; // The board found was no A2232 + } + if (!zorro_request_device(z,"A2232 driver")) + continue; + + printk("Commodore A2232 found (#%d).\n",nr_a2232); + + zd_a2232[nr_a2232] = z; + + boardaddr = ZTWO_VADDR( z->resource.start ); + printk("Board is located at address 0x%x, size is 0x%x.\n", boardaddr, (unsigned int) ((z->resource.end+1) - (z->resource.start))); + + mem = (volatile struct a2232memory *) boardaddr; + + (void) mem->Enable6502Reset; /* copy the code across to the board */ + to = (u_char *)mem; from = a2232_65EC02code; bcount = sizeof(a2232_65EC02code) - 2; + start = *(short *)from; + from += sizeof(start); + to += start; + while(bcount--) *to++ = *from++; + printk("65EC02 software uploaded to the A2232 memory.\n"); + + mem->Common.Crystal = A2232_UNKNOWN; /* use automatic speed check */ + + /* start 6502 running */ + (void) mem->ResetBoard; + printk("A2232's 65EC02 CPU up and running.\n"); + + /* wait until speed detector has finished */ + for (bcount = 0; bcount < 2000; bcount++) { + udelay(1000); + if (mem->Common.Crystal) + break; + } + printk((mem->Common.Crystal?"A2232 oscillator crystal detected by 65EC02 software: ":"65EC02 software could not determine A2232 oscillator crystal: ")); + switch (mem->Common.Crystal){ + case A2232_UNKNOWN: + printk("Unknown crystal.\n"); + break; + case A2232_NORMAL: + printk ("Normal crystal.\n"); + break; + case A2232_TURBO: + printk ("Turbo crystal.\n"); + break; + default: + printk ("0x%x. Huh?\n",mem->Common.Crystal); + } + + nr_a2232++; + + } + + printk("Total: %d A2232 boards initialized.\n", nr_a2232); /* Some status report if no card was found */ + + a2232_init_portstructs(); + + /* + a2232_init_drivers also registers the drivers. Must be here because all boards + have to be detected first. + */ + if (a2232_init_drivers()) return -ENODEV; // maybe we should use a different -Exxx? + + error = request_irq(IRQ_AMIGA_VERTB, a2232_vbl_inter, 0, + "A2232 serial VBL", a2232_driver_ID); + if (error) { + for (i = 0; i < nr_a2232; i++) + zorro_release_device(zd_a2232[i]); + tty_unregister_driver(a2232_driver); + put_tty_driver(a2232_driver); + } + return error; +} + +static void __exit a2232board_exit(void) +{ + int i; + + for (i = 0; i < nr_a2232; i++) { + zorro_release_device(zd_a2232[i]); + } + + tty_unregister_driver(a2232_driver); + put_tty_driver(a2232_driver); + free_irq(IRQ_AMIGA_VERTB, a2232_driver_ID); +} + +module_init(a2232board_init); +module_exit(a2232board_exit); + +MODULE_AUTHOR("Enver Haase"); +MODULE_DESCRIPTION("Amiga A2232 multi-serial board driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/generic_serial/ser_a2232.h b/drivers/staging/generic_serial/ser_a2232.h new file mode 100644 index 000000000000..bc09eb9e118b --- /dev/null +++ b/drivers/staging/generic_serial/ser_a2232.h @@ -0,0 +1,202 @@ +/* drivers/char/ser_a2232.h */ + +/* $Id: ser_a2232.h,v 0.4 2000/01/25 12:00:00 ehaase Exp $ */ + +/* Linux serial driver for the Amiga A2232 board */ + +/* This driver is MAINTAINED. Before applying any changes, please contact + * the author. + */ + +/* Copyright (c) 2000-2001 Enver Haase + * alias The A2232 driver project + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef _SER_A2232_H_ +#define _SER_A2232_H_ + +/* + How many boards are to be supported at maximum; + "up to five A2232 Multiport Serial Cards may be installed in a + single Amiga 2000" states the A2232 User's Guide. If you have + more slots available, you might want to change the value below. +*/ +#define MAX_A2232_BOARDS 5 + +#ifndef A2232_NORMAL_MAJOR +/* This allows overriding on the compiler commandline, or in a "major.h" + include or something like that */ +#define A2232_NORMAL_MAJOR 224 /* /dev/ttyY* */ +#define A2232_CALLOUT_MAJOR 225 /* /dev/cuy* */ +#endif + +/* Some magic is always good - Who knows :) */ +#define A2232_MAGIC 0x000a2232 + +/* A2232 port structure to keep track of the + status of every single line used */ +struct a2232_port{ + struct gs_port gs; + unsigned int which_a2232; + unsigned int which_port_on_a2232; + short disable_rx; + short throttle_input; + short cd_status; +}; + +#define NUMLINES 7 /* number of lines per board */ +#define A2232_IOBUFLEN 256 /* number of bytes per buffer */ +#define A2232_IOBUFLENMASK 0xff /* mask for maximum number of bytes */ + + +#define A2232_UNKNOWN 0 /* crystal not known */ +#define A2232_NORMAL 1 /* normal A2232 (1.8432 MHz oscillator) */ +#define A2232_TURBO 2 /* turbo A2232 (3.6864 MHz oscillator) */ + + +struct a2232common { + char Crystal; /* normal (1) or turbo (2) board? */ + u_char Pad_a; + u_char TimerH; /* timer value after speed check */ + u_char TimerL; + u_char CDHead; /* head pointer for CD message queue */ + u_char CDTail; /* tail pointer for CD message queue */ + u_char CDStatus; + u_char Pad_b; +}; + +struct a2232status { + u_char InHead; /* input queue head */ + u_char InTail; /* input queue tail */ + u_char OutDisable; /* disables output */ + u_char OutHead; /* output queue head */ + u_char OutTail; /* output queue tail */ + u_char OutCtrl; /* soft flow control character to send */ + u_char OutFlush; /* flushes output buffer */ + u_char Setup; /* causes reconfiguration */ + u_char Param; /* parameter byte - see A2232PARAM */ + u_char Command; /* command byte - see A2232CMD */ + u_char SoftFlow; /* enables xon/xoff flow control */ + /* private 65EC02 fields: */ + u_char XonOff; /* stores XON/XOFF enable/disable */ +}; + +#define A2232_MEMPAD1 \ + (0x0200 - NUMLINES * sizeof(struct a2232status) - \ + sizeof(struct a2232common)) +#define A2232_MEMPAD2 (0x2000 - NUMLINES * A2232_IOBUFLEN - A2232_IOBUFLEN) + +struct a2232memory { + struct a2232status Status[NUMLINES]; /* 0x0000-0x006f status areas */ + struct a2232common Common; /* 0x0070-0x0077 common flags */ + u_char Dummy1[A2232_MEMPAD1]; /* 0x00XX-0x01ff */ + u_char OutBuf[NUMLINES][A2232_IOBUFLEN];/* 0x0200-0x08ff output bufs */ + u_char InBuf[NUMLINES][A2232_IOBUFLEN]; /* 0x0900-0x0fff input bufs */ + u_char InCtl[NUMLINES][A2232_IOBUFLEN]; /* 0x1000-0x16ff control data */ + u_char CDBuf[A2232_IOBUFLEN]; /* 0x1700-0x17ff CD event buffer */ + u_char Dummy2[A2232_MEMPAD2]; /* 0x1800-0x2fff */ + u_char Code[0x1000]; /* 0x3000-0x3fff code area */ + u_short InterruptAck; /* 0x4000 intr ack */ + u_char Dummy3[0x3ffe]; /* 0x4002-0x7fff */ + u_short Enable6502Reset; /* 0x8000 Stop board, */ + /* 6502 RESET line held low */ + u_char Dummy4[0x3ffe]; /* 0x8002-0xbfff */ + u_short ResetBoard; /* 0xc000 reset board & run, */ + /* 6502 RESET line held high */ +}; + +#undef A2232_MEMPAD1 +#undef A2232_MEMPAD2 + +#define A2232INCTL_CHAR 0 /* corresponding byte in InBuf is a character */ +#define A2232INCTL_EVENT 1 /* corresponding byte in InBuf is an event */ + +#define A2232EVENT_Break 1 /* break set */ +#define A2232EVENT_CarrierOn 2 /* carrier raised */ +#define A2232EVENT_CarrierOff 3 /* carrier dropped */ +#define A2232EVENT_Sync 4 /* don't know, defined in 2232.ax */ + +#define A2232CMD_Enable 0x1 /* enable/DTR bit */ +#define A2232CMD_Close 0x2 /* close the device */ +#define A2232CMD_Open 0xb /* open the device */ +#define A2232CMD_CMask 0xf /* command mask */ +#define A2232CMD_RTSOff 0x0 /* turn off RTS */ +#define A2232CMD_RTSOn 0x8 /* turn on RTS */ +#define A2232CMD_Break 0xd /* transmit a break */ +#define A2232CMD_RTSMask 0xc /* mask for RTS stuff */ +#define A2232CMD_NoParity 0x00 /* don't use parity */ +#define A2232CMD_OddParity 0x20 /* odd parity */ +#define A2232CMD_EvenParity 0x60 /* even parity */ +#define A2232CMD_ParityMask 0xe0 /* parity mask */ + +#define A2232PARAM_B115200 0x0 /* baud rates */ +#define A2232PARAM_B50 0x1 +#define A2232PARAM_B75 0x2 +#define A2232PARAM_B110 0x3 +#define A2232PARAM_B134 0x4 +#define A2232PARAM_B150 0x5 +#define A2232PARAM_B300 0x6 +#define A2232PARAM_B600 0x7 +#define A2232PARAM_B1200 0x8 +#define A2232PARAM_B1800 0x9 +#define A2232PARAM_B2400 0xa +#define A2232PARAM_B3600 0xb +#define A2232PARAM_B4800 0xc +#define A2232PARAM_B7200 0xd +#define A2232PARAM_B9600 0xe +#define A2232PARAM_B19200 0xf +#define A2232PARAM_BaudMask 0xf /* baud rate mask */ +#define A2232PARAM_RcvBaud 0x10 /* enable receive baud rate */ +#define A2232PARAM_8Bit 0x00 /* numbers of bits */ +#define A2232PARAM_7Bit 0x20 +#define A2232PARAM_6Bit 0x40 +#define A2232PARAM_5Bit 0x60 +#define A2232PARAM_BitMask 0x60 /* numbers of bits mask */ + + +/* Standard speeds tables, -1 means unavailable, -2 means 0 baud: switch off line */ +#define A2232_BAUD_TABLE_NOAVAIL -1 +#define A2232_BAUD_TABLE_NUM_RATES (18) +static int a2232_baud_table[A2232_BAUD_TABLE_NUM_RATES*3] = { + //Baud //Normal //Turbo + 50, A2232PARAM_B50, A2232_BAUD_TABLE_NOAVAIL, + 75, A2232PARAM_B75, A2232_BAUD_TABLE_NOAVAIL, + 110, A2232PARAM_B110, A2232_BAUD_TABLE_NOAVAIL, + 134, A2232PARAM_B134, A2232_BAUD_TABLE_NOAVAIL, + 150, A2232PARAM_B150, A2232PARAM_B75, + 200, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL, + 300, A2232PARAM_B300, A2232PARAM_B150, + 600, A2232PARAM_B600, A2232PARAM_B300, + 1200, A2232PARAM_B1200, A2232PARAM_B600, + 1800, A2232PARAM_B1800, A2232_BAUD_TABLE_NOAVAIL, + 2400, A2232PARAM_B2400, A2232PARAM_B1200, + 4800, A2232PARAM_B4800, A2232PARAM_B2400, + 9600, A2232PARAM_B9600, A2232PARAM_B4800, + 19200, A2232PARAM_B19200, A2232PARAM_B9600, + 38400, A2232_BAUD_TABLE_NOAVAIL, A2232PARAM_B19200, + 57600, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL, +#ifdef A2232_SPEEDHACK + 115200, A2232PARAM_B115200, A2232_BAUD_TABLE_NOAVAIL, + 230400, A2232_BAUD_TABLE_NOAVAIL, A2232PARAM_B115200 +#else + 115200, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL, + 230400, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL +#endif +}; +#endif diff --git a/drivers/staging/generic_serial/ser_a2232fw.ax b/drivers/staging/generic_serial/ser_a2232fw.ax new file mode 100644 index 000000000000..736438032768 --- /dev/null +++ b/drivers/staging/generic_serial/ser_a2232fw.ax @@ -0,0 +1,529 @@ +;.lib "axm" +; +;begin +;title "A2232 serial board driver" +; +;set modules "2232" +;set executable "2232.bin" +; +;;;;set nolink +; +;set temporary directory "t:" +; +;set assembly options "-m6502 -l60:t:list" +;set link options "bin"; loadadr" +;;;bin2c 2232.bin msc6502.h msc6502code +;end +; +; +; ### Commodore A2232 serial board driver for NetBSD by JM v1.3 ### +; +; - Created 950501 by JM - +; +; +; Serial board driver software. +; +; +% Copyright (c) 1995 Jukka Marin . +% All rights reserved. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions +% are met: +% 1. Redistributions of source code must retain the above copyright +% notice, and the entire permission notice in its entirety, +% including the disclaimer of warranties. +% 2. Redistributions in binary form must reproduce the above copyright +% notice, this list of conditions and the following disclaimer in the +% documentation and/or other materials provided with the distribution. +% 3. The name of the author may not be used to endorse or promote +% products derived from this software without specific prior +% written permission. +% +% ALTERNATIVELY, this product may be distributed under the terms of +% the GNU General Public License, in which case the provisions of the +% GPL are required INSTEAD OF the above restrictions. (This clause is +% necessary due to a potential bad interaction between the GPL and +% the restrictions contained in a BSD-style copyright.) +% +% THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED +% WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +% OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +% DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +% INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +% (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +% SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +% HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +% STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +% OF THE POSSIBILITY OF SUCH DAMAGE. +; +; +; Bugs: +; +; - Can't send a break yet +; +; +; +; Edited: +; +; - 950501 by JM -> v0.1 - Created this file. +; - 951029 by JM -> v1.3 - Carrier Detect events now queued in a separate +; queue. +; +; + + +CODE equ $3800 ; start address for program code + + +CTL_CHAR equ $00 ; byte in ibuf is a character +CTL_EVENT equ $01 ; byte in ibuf is an event + +EVENT_BREAK equ $01 +EVENT_CDON equ $02 +EVENT_CDOFF equ $03 +EVENT_SYNC equ $04 + +XON equ $11 +XOFF equ $13 + + +VARBASE macro *starting_address ; was VARINIT +_varbase set \1 + endm + +VARDEF macro *name space_needs +\1 equ _varbase +_varbase set _varbase+\2 + endm + + +stz macro * address + db $64,\1 + endm + +stzax macro * address + db $9e,<\1,>\1 + endm + + +biti macro * immediate value + db $89,\1 + endm + +smb0 macro * address + db $87,\1 + endm +smb1 macro * address + db $97,\1 + endm +smb2 macro * address + db $a7,\1 + endm +smb3 macro * address + db $b7,\1 + endm +smb4 macro * address + db $c7,\1 + endm +smb5 macro * address + db $d7,\1 + endm +smb6 macro * address + db $e7,\1 + endm +smb7 macro * address + db $f7,\1 + endm + + + +;-----------------------------------------------------------------------; +; ; +; stuff common for all ports, non-critical (run once / loop) ; +; ; +DO_SLOW macro * port_number ; + .local ; ; + lda CIA+C_PA ; check all CD inputs ; + cmp CommonCDo ; changed from previous accptd? ; + beq =over ; nope, do nothing else here ; + ; ; + cmp CommonCDb ; bouncing? ; + beq =nobounce ; nope -> ; + ; ; + sta CommonCDb ; save current state ; + lda #64 ; reinitialize counter ; + sta CommonCDc ; ; + jmp =over ; skip CD save ; + ; ; +=nobounce dec CommonCDc ; no, decrement bounce counter ; + bpl =over ; not done yet, so skip CD save ; + ; ; +=saveCD ldx CDHead ; get write index ; + sta cdbuf,x ; save status in buffer ; + inx ; ; + cpx CDTail ; buffer full? ; + .if ne ; no: preserve status: ; + stx CDHead ; update index in RAM ; + sta CommonCDo ; save state for the next check ; + .end ; ; +=over .end local ; + endm ; + ; +;-----------------------------------------------------------------------; + + +; port specific stuff (no data transfer) + +DO_PORT macro * port_number + .local ; ; + lda SetUp\1 ; reconfiguration request? ; + .if ne ; yes: ; + lda SoftFlow\1 ; get XON/XOFF flag ; + sta XonOff\1 ; save it ; + lda Param\1 ; get parameter ; + ora #%00010000 ; use baud generator for Rx ; + sta ACIA\1+A_CTRL ; store in control register ; + stz OutDisable\1 ; enable transmit output ; + stz SetUp\1 ; no reconfiguration no more ; + .end ; ; + ; ; + lda InHead\1 ; get write index ; + sbc InTail\1 ; buffer full soon? ; + cmp #200 ; 200 chars or more in buffer? ; + lda Command\1 ; get Command reg value ; + and #%11110011 ; turn RTS OFF by default ; + .if cc ; still room in buffer: ; + ora #%00001000 ; turn RTS ON ; + .end ; ; + sta ACIA\1+A_CMD ; set/clear RTS ; + ; ; + lda OutFlush\1 ; request to flush output buffer; + .if ne ; yessh! ; + lda OutHead\1 ; get head ; + sta OutTail\1 ; save as tail ; + stz OutDisable\1 ; enable transmit output ; + stz OutFlush\1 ; clear request ; + .end + .end local + endm + + +DO_DATA macro * port number + .local + lda ACIA\1+A_SR ; read ACIA status register ; + biti [1<<3] ; something received? ; + .if ne ; yes: ; + biti [1<<1] ; framing error? ; + .if ne ; yes: ; + lda ACIA\1+A_DATA ; read received character ; + bne =SEND ; not break -> ignore it ; + ldx InHead\1 ; get write pointer ; + lda #CTL_EVENT ; get type of byte ; + sta ictl\1,x ; save it in InCtl buffer ; + lda #EVENT_BREAK ; event code ; + sta ibuf\1,x ; save it as well ; + inx ; ; + cpx InTail\1 ; still room in buffer? ; + .if ne ; absolutely: ; + stx InHead\1 ; update index in memory ; + .end ; ; + jmp =SEND ; go check if anything to send ; + .end ; ; + ; normal char received: ; + ldx InHead\1 ; get write index ; + lda ACIA\1+A_DATA ; read received character ; + sta ibuf\1,x ; save char in buffer ; + stzax ictl\1 ; set type to CTL_CHAR ; + inx ; ; + cpx InTail\1 ; buffer full? ; + .if ne ; no: preserve character: ; + stx InHead\1 ; update index in RAM ; + .end ; ; + and #$7f ; mask off parity if any ; + cmp #XOFF ; XOFF from remote host? ; + .if eq ; yes: ; + lda XonOff\1 ; if XON/XOFF handshaking.. ; + sta OutDisable\1 ; ..disable transmitter ; + .end ; ; + .end ; ; + ; ; + ; BUFFER FULL CHECK WAS HERE ; + ; ; +=SEND lda ACIA\1+A_SR ; transmit register empty? ; + and #[1<<4] ; ; + .if ne ; yes: ; + ldx OutCtrl\1 ; sending out XON/XOFF? ; + .if ne ; yes: ; + lda CIA+C_PB ; check CTS signal ; + and #[1<<\1] ; (for this port only) ; + bne =DONE ; not allowed to send -> done ; + stx ACIA\1+A_DATA ; transmit control char ; + stz OutCtrl\1 ; clear flag ; + jmp =DONE ; and we're done ; + .end ; ; + ; ; + ldx OutTail\1 ; anything to transmit? ; + cpx OutHead\1 ; ; + .if ne ; yes: ; + lda OutDisable\1 ; allowed to transmit? ; + .if eq ; yes: ; + lda CIA+C_PB ; check CTS signal ; + and #[1<<\1] ; (for this port only) ; + bne =DONE ; not allowed to send -> done ; + lda obuf\1,x ; get a char from buffer ; + sta ACIA\1+A_DATA ; send it away ; + inc OutTail\1 ; update read index ; + .end ; ; + .end ; ; + .end ; ; +=DONE .end local + endm + + + +PORTVAR macro * port number + VARDEF InHead\1 1 + VARDEF InTail\1 1 + VARDEF OutDisable\1 1 + VARDEF OutHead\1 1 + VARDEF OutTail\1 1 + VARDEF OutCtrl\1 1 + VARDEF OutFlush\1 1 + VARDEF SetUp\1 1 + VARDEF Param\1 1 + VARDEF Command\1 1 + VARDEF SoftFlow\1 1 + ; private: + VARDEF XonOff\1 1 + endm + + + VARBASE 0 ; start variables at address $0000 + PORTVAR 0 ; define variables for port 0 + PORTVAR 1 ; define variables for port 1 + PORTVAR 2 ; define variables for port 2 + PORTVAR 3 ; define variables for port 3 + PORTVAR 4 ; define variables for port 4 + PORTVAR 5 ; define variables for port 5 + PORTVAR 6 ; define variables for port 6 + + + + VARDEF Crystal 1 ; 0 = unknown, 1 = normal, 2 = turbo + VARDEF Pad_a 1 + VARDEF TimerH 1 + VARDEF TimerL 1 + VARDEF CDHead 1 + VARDEF CDTail 1 + VARDEF CDStatus 1 + VARDEF Pad_b 1 + + VARDEF CommonCDo 1 ; for carrier detect optimization + VARDEF CommonCDc 1 ; for carrier detect debouncing + VARDEF CommonCDb 1 ; for carrier detect debouncing + + + VARBASE $0200 + VARDEF obuf0 256 ; output data (characters only) + VARDEF obuf1 256 + VARDEF obuf2 256 + VARDEF obuf3 256 + VARDEF obuf4 256 + VARDEF obuf5 256 + VARDEF obuf6 256 + + VARDEF ibuf0 256 ; input data (characters, events etc - see ictl) + VARDEF ibuf1 256 + VARDEF ibuf2 256 + VARDEF ibuf3 256 + VARDEF ibuf4 256 + VARDEF ibuf5 256 + VARDEF ibuf6 256 + + VARDEF ictl0 256 ; input control information (type of data in ibuf) + VARDEF ictl1 256 + VARDEF ictl2 256 + VARDEF ictl3 256 + VARDEF ictl4 256 + VARDEF ictl5 256 + VARDEF ictl6 256 + + VARDEF cdbuf 256 ; CD event queue + + +ACIA0 equ $4400 +ACIA1 equ $4c00 +ACIA2 equ $5400 +ACIA3 equ $5c00 +ACIA4 equ $6400 +ACIA5 equ $6c00 +ACIA6 equ $7400 + +A_DATA equ $00 +A_SR equ $02 +A_CMD equ $04 +A_CTRL equ $06 +; 00 write transmit data read received data +; 02 reset ACIA read status register +; 04 write command register read command register +; 06 write control register read control register + +CIA equ $7c00 ; 8520 CIA +C_PA equ $00 ; port A data register +C_PB equ $02 ; port B data register +C_DDRA equ $04 ; data direction register for port A +C_DDRB equ $06 ; data direction register for port B +C_TAL equ $08 ; timer A +C_TAH equ $0a +C_TBL equ $0c ; timer B +C_TBH equ $0e +C_TODL equ $10 ; TOD LSB +C_TODM equ $12 ; TOD middle byte +C_TODH equ $14 ; TOD MSB +C_DATA equ $18 ; serial data register +C_INTCTRL equ $1a ; interrupt control register +C_CTRLA equ $1c ; control register A +C_CTRLB equ $1e ; control register B + + + + + + section main,code,CODE-2 + + db >CODE,. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* This is the 65EC02 code by Jukka Marin that is executed by + the A2232's 65EC02 processor (base address: 0x3800) + Source file: ser_a2232fw.ax + Version: 1.3 (951029) + Known Bugs: Cannot send a break yet +*/ +static unsigned char a2232_65EC02code[] = { + 0x38, 0x00, 0xA2, 0xFF, 0x9A, 0xD8, 0xA2, 0x00, + 0xA9, 0x00, 0xA0, 0x54, 0x95, 0x00, 0xE8, 0x88, + 0xD0, 0xFA, 0x64, 0x5C, 0x64, 0x5E, 0x64, 0x58, + 0x64, 0x59, 0xA9, 0x00, 0x85, 0x55, 0xA9, 0xAA, + 0xC9, 0x64, 0x90, 0x02, 0xE6, 0x55, 0xA5, 0x54, + 0xF0, 0x03, 0x4C, 0x92, 0x38, 0xA9, 0x98, 0x8D, + 0x06, 0x44, 0xA9, 0x0B, 0x8D, 0x04, 0x44, 0xAD, + 0x02, 0x44, 0xA9, 0x80, 0x8D, 0x1A, 0x7C, 0xA9, + 0xFF, 0x8D, 0x08, 0x7C, 0x8D, 0x0A, 0x7C, 0xA2, + 0x00, 0x8E, 0x00, 0x44, 0xEA, 0xEA, 0xAD, 0x02, + 0x44, 0xEA, 0xEA, 0x8E, 0x00, 0x44, 0xAD, 0x02, + 0x44, 0x29, 0x10, 0xF0, 0xF9, 0xA9, 0x11, 0x8E, + 0x00, 0x44, 0x8D, 0x1C, 0x7C, 0xAD, 0x02, 0x44, + 0x29, 0x10, 0xF0, 0xF9, 0x8E, 0x1C, 0x7C, 0xAD, + 0x08, 0x7C, 0x85, 0x57, 0xAD, 0x0A, 0x7C, 0x85, + 0x56, 0xC9, 0xD0, 0x90, 0x05, 0xA9, 0x02, 0x4C, + 0x82, 0x38, 0xA9, 0x01, 0x85, 0x54, 0xA9, 0x00, + 0x8D, 0x02, 0x44, 0x8D, 0x06, 0x44, 0x8D, 0x04, + 0x44, 0x4C, 0x92, 0x38, 0xAD, 0x00, 0x7C, 0xC5, + 0x5C, 0xF0, 0x1F, 0xC5, 0x5E, 0xF0, 0x09, 0x85, + 0x5E, 0xA9, 0x40, 0x85, 0x5D, 0x4C, 0xB8, 0x38, + 0xC6, 0x5D, 0x10, 0x0E, 0xA6, 0x58, 0x9D, 0x00, + 0x17, 0xE8, 0xE4, 0x59, 0xF0, 0x04, 0x86, 0x58, + 0x85, 0x5C, 0x20, 0x23, 0x3A, 0xA5, 0x07, 0xF0, + 0x0F, 0xA5, 0x0A, 0x85, 0x0B, 0xA5, 0x08, 0x09, + 0x10, 0x8D, 0x06, 0x44, 0x64, 0x02, 0x64, 0x07, + 0xA5, 0x00, 0xE5, 0x01, 0xC9, 0xC8, 0xA5, 0x09, + 0x29, 0xF3, 0xB0, 0x02, 0x09, 0x08, 0x8D, 0x04, + 0x44, 0xA5, 0x06, 0xF0, 0x08, 0xA5, 0x03, 0x85, + 0x04, 0x64, 0x02, 0x64, 0x06, 0x20, 0x23, 0x3A, + 0xA5, 0x13, 0xF0, 0x0F, 0xA5, 0x16, 0x85, 0x17, + 0xA5, 0x14, 0x09, 0x10, 0x8D, 0x06, 0x4C, 0x64, + 0x0E, 0x64, 0x13, 0xA5, 0x0C, 0xE5, 0x0D, 0xC9, + 0xC8, 0xA5, 0x15, 0x29, 0xF3, 0xB0, 0x02, 0x09, + 0x08, 0x8D, 0x04, 0x4C, 0xA5, 0x12, 0xF0, 0x08, + 0xA5, 0x0F, 0x85, 0x10, 0x64, 0x0E, 0x64, 0x12, + 0x20, 0x23, 0x3A, 0xA5, 0x1F, 0xF0, 0x0F, 0xA5, + 0x22, 0x85, 0x23, 0xA5, 0x20, 0x09, 0x10, 0x8D, + 0x06, 0x54, 0x64, 0x1A, 0x64, 0x1F, 0xA5, 0x18, + 0xE5, 0x19, 0xC9, 0xC8, 0xA5, 0x21, 0x29, 0xF3, + 0xB0, 0x02, 0x09, 0x08, 0x8D, 0x04, 0x54, 0xA5, + 0x1E, 0xF0, 0x08, 0xA5, 0x1B, 0x85, 0x1C, 0x64, + 0x1A, 0x64, 0x1E, 0x20, 0x23, 0x3A, 0xA5, 0x2B, + 0xF0, 0x0F, 0xA5, 0x2E, 0x85, 0x2F, 0xA5, 0x2C, + 0x09, 0x10, 0x8D, 0x06, 0x5C, 0x64, 0x26, 0x64, + 0x2B, 0xA5, 0x24, 0xE5, 0x25, 0xC9, 0xC8, 0xA5, + 0x2D, 0x29, 0xF3, 0xB0, 0x02, 0x09, 0x08, 0x8D, + 0x04, 0x5C, 0xA5, 0x2A, 0xF0, 0x08, 0xA5, 0x27, + 0x85, 0x28, 0x64, 0x26, 0x64, 0x2A, 0x20, 0x23, + 0x3A, 0xA5, 0x37, 0xF0, 0x0F, 0xA5, 0x3A, 0x85, + 0x3B, 0xA5, 0x38, 0x09, 0x10, 0x8D, 0x06, 0x64, + 0x64, 0x32, 0x64, 0x37, 0xA5, 0x30, 0xE5, 0x31, + 0xC9, 0xC8, 0xA5, 0x39, 0x29, 0xF3, 0xB0, 0x02, + 0x09, 0x08, 0x8D, 0x04, 0x64, 0xA5, 0x36, 0xF0, + 0x08, 0xA5, 0x33, 0x85, 0x34, 0x64, 0x32, 0x64, + 0x36, 0x20, 0x23, 0x3A, 0xA5, 0x43, 0xF0, 0x0F, + 0xA5, 0x46, 0x85, 0x47, 0xA5, 0x44, 0x09, 0x10, + 0x8D, 0x06, 0x6C, 0x64, 0x3E, 0x64, 0x43, 0xA5, + 0x3C, 0xE5, 0x3D, 0xC9, 0xC8, 0xA5, 0x45, 0x29, + 0xF3, 0xB0, 0x02, 0x09, 0x08, 0x8D, 0x04, 0x6C, + 0xA5, 0x42, 0xF0, 0x08, 0xA5, 0x3F, 0x85, 0x40, + 0x64, 0x3E, 0x64, 0x42, 0x20, 0x23, 0x3A, 0xA5, + 0x4F, 0xF0, 0x0F, 0xA5, 0x52, 0x85, 0x53, 0xA5, + 0x50, 0x09, 0x10, 0x8D, 0x06, 0x74, 0x64, 0x4A, + 0x64, 0x4F, 0xA5, 0x48, 0xE5, 0x49, 0xC9, 0xC8, + 0xA5, 0x51, 0x29, 0xF3, 0xB0, 0x02, 0x09, 0x08, + 0x8D, 0x04, 0x74, 0xA5, 0x4E, 0xF0, 0x08, 0xA5, + 0x4B, 0x85, 0x4C, 0x64, 0x4A, 0x64, 0x4E, 0x20, + 0x23, 0x3A, 0x4C, 0x92, 0x38, 0xAD, 0x02, 0x44, + 0x89, 0x08, 0xF0, 0x3B, 0x89, 0x02, 0xF0, 0x1B, + 0xAD, 0x00, 0x44, 0xD0, 0x32, 0xA6, 0x00, 0xA9, + 0x01, 0x9D, 0x00, 0x10, 0xA9, 0x01, 0x9D, 0x00, + 0x09, 0xE8, 0xE4, 0x01, 0xF0, 0x02, 0x86, 0x00, + 0x4C, 0x65, 0x3A, 0xA6, 0x00, 0xAD, 0x00, 0x44, + 0x9D, 0x00, 0x09, 0x9E, 0x00, 0x10, 0xE8, 0xE4, + 0x01, 0xF0, 0x02, 0x86, 0x00, 0x29, 0x7F, 0xC9, + 0x13, 0xD0, 0x04, 0xA5, 0x0B, 0x85, 0x02, 0xAD, + 0x02, 0x44, 0x29, 0x10, 0xF0, 0x2C, 0xA6, 0x05, + 0xF0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x01, 0xD0, + 0x21, 0x8E, 0x00, 0x44, 0x64, 0x05, 0x4C, 0x98, + 0x3A, 0xA6, 0x04, 0xE4, 0x03, 0xF0, 0x13, 0xA5, + 0x02, 0xD0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x01, + 0xD0, 0x08, 0xBD, 0x00, 0x02, 0x8D, 0x00, 0x44, + 0xE6, 0x04, 0xAD, 0x02, 0x4C, 0x89, 0x08, 0xF0, + 0x3B, 0x89, 0x02, 0xF0, 0x1B, 0xAD, 0x00, 0x4C, + 0xD0, 0x32, 0xA6, 0x0C, 0xA9, 0x01, 0x9D, 0x00, + 0x11, 0xA9, 0x01, 0x9D, 0x00, 0x0A, 0xE8, 0xE4, + 0x0D, 0xF0, 0x02, 0x86, 0x0C, 0x4C, 0xDA, 0x3A, + 0xA6, 0x0C, 0xAD, 0x00, 0x4C, 0x9D, 0x00, 0x0A, + 0x9E, 0x00, 0x11, 0xE8, 0xE4, 0x0D, 0xF0, 0x02, + 0x86, 0x0C, 0x29, 0x7F, 0xC9, 0x13, 0xD0, 0x04, + 0xA5, 0x17, 0x85, 0x0E, 0xAD, 0x02, 0x4C, 0x29, + 0x10, 0xF0, 0x2C, 0xA6, 0x11, 0xF0, 0x0F, 0xAD, + 0x02, 0x7C, 0x29, 0x02, 0xD0, 0x21, 0x8E, 0x00, + 0x4C, 0x64, 0x11, 0x4C, 0x0D, 0x3B, 0xA6, 0x10, + 0xE4, 0x0F, 0xF0, 0x13, 0xA5, 0x0E, 0xD0, 0x0F, + 0xAD, 0x02, 0x7C, 0x29, 0x02, 0xD0, 0x08, 0xBD, + 0x00, 0x03, 0x8D, 0x00, 0x4C, 0xE6, 0x10, 0xAD, + 0x02, 0x54, 0x89, 0x08, 0xF0, 0x3B, 0x89, 0x02, + 0xF0, 0x1B, 0xAD, 0x00, 0x54, 0xD0, 0x32, 0xA6, + 0x18, 0xA9, 0x01, 0x9D, 0x00, 0x12, 0xA9, 0x01, + 0x9D, 0x00, 0x0B, 0xE8, 0xE4, 0x19, 0xF0, 0x02, + 0x86, 0x18, 0x4C, 0x4F, 0x3B, 0xA6, 0x18, 0xAD, + 0x00, 0x54, 0x9D, 0x00, 0x0B, 0x9E, 0x00, 0x12, + 0xE8, 0xE4, 0x19, 0xF0, 0x02, 0x86, 0x18, 0x29, + 0x7F, 0xC9, 0x13, 0xD0, 0x04, 0xA5, 0x23, 0x85, + 0x1A, 0xAD, 0x02, 0x54, 0x29, 0x10, 0xF0, 0x2C, + 0xA6, 0x1D, 0xF0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, + 0x04, 0xD0, 0x21, 0x8E, 0x00, 0x54, 0x64, 0x1D, + 0x4C, 0x82, 0x3B, 0xA6, 0x1C, 0xE4, 0x1B, 0xF0, + 0x13, 0xA5, 0x1A, 0xD0, 0x0F, 0xAD, 0x02, 0x7C, + 0x29, 0x04, 0xD0, 0x08, 0xBD, 0x00, 0x04, 0x8D, + 0x00, 0x54, 0xE6, 0x1C, 0xAD, 0x02, 0x5C, 0x89, + 0x08, 0xF0, 0x3B, 0x89, 0x02, 0xF0, 0x1B, 0xAD, + 0x00, 0x5C, 0xD0, 0x32, 0xA6, 0x24, 0xA9, 0x01, + 0x9D, 0x00, 0x13, 0xA9, 0x01, 0x9D, 0x00, 0x0C, + 0xE8, 0xE4, 0x25, 0xF0, 0x02, 0x86, 0x24, 0x4C, + 0xC4, 0x3B, 0xA6, 0x24, 0xAD, 0x00, 0x5C, 0x9D, + 0x00, 0x0C, 0x9E, 0x00, 0x13, 0xE8, 0xE4, 0x25, + 0xF0, 0x02, 0x86, 0x24, 0x29, 0x7F, 0xC9, 0x13, + 0xD0, 0x04, 0xA5, 0x2F, 0x85, 0x26, 0xAD, 0x02, + 0x5C, 0x29, 0x10, 0xF0, 0x2C, 0xA6, 0x29, 0xF0, + 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x08, 0xD0, 0x21, + 0x8E, 0x00, 0x5C, 0x64, 0x29, 0x4C, 0xF7, 0x3B, + 0xA6, 0x28, 0xE4, 0x27, 0xF0, 0x13, 0xA5, 0x26, + 0xD0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x08, 0xD0, + 0x08, 0xBD, 0x00, 0x05, 0x8D, 0x00, 0x5C, 0xE6, + 0x28, 0xAD, 0x02, 0x64, 0x89, 0x08, 0xF0, 0x3B, + 0x89, 0x02, 0xF0, 0x1B, 0xAD, 0x00, 0x64, 0xD0, + 0x32, 0xA6, 0x30, 0xA9, 0x01, 0x9D, 0x00, 0x14, + 0xA9, 0x01, 0x9D, 0x00, 0x0D, 0xE8, 0xE4, 0x31, + 0xF0, 0x02, 0x86, 0x30, 0x4C, 0x39, 0x3C, 0xA6, + 0x30, 0xAD, 0x00, 0x64, 0x9D, 0x00, 0x0D, 0x9E, + 0x00, 0x14, 0xE8, 0xE4, 0x31, 0xF0, 0x02, 0x86, + 0x30, 0x29, 0x7F, 0xC9, 0x13, 0xD0, 0x04, 0xA5, + 0x3B, 0x85, 0x32, 0xAD, 0x02, 0x64, 0x29, 0x10, + 0xF0, 0x2C, 0xA6, 0x35, 0xF0, 0x0F, 0xAD, 0x02, + 0x7C, 0x29, 0x10, 0xD0, 0x21, 0x8E, 0x00, 0x64, + 0x64, 0x35, 0x4C, 0x6C, 0x3C, 0xA6, 0x34, 0xE4, + 0x33, 0xF0, 0x13, 0xA5, 0x32, 0xD0, 0x0F, 0xAD, + 0x02, 0x7C, 0x29, 0x10, 0xD0, 0x08, 0xBD, 0x00, + 0x06, 0x8D, 0x00, 0x64, 0xE6, 0x34, 0xAD, 0x02, + 0x6C, 0x89, 0x08, 0xF0, 0x3B, 0x89, 0x02, 0xF0, + 0x1B, 0xAD, 0x00, 0x6C, 0xD0, 0x32, 0xA6, 0x3C, + 0xA9, 0x01, 0x9D, 0x00, 0x15, 0xA9, 0x01, 0x9D, + 0x00, 0x0E, 0xE8, 0xE4, 0x3D, 0xF0, 0x02, 0x86, + 0x3C, 0x4C, 0xAE, 0x3C, 0xA6, 0x3C, 0xAD, 0x00, + 0x6C, 0x9D, 0x00, 0x0E, 0x9E, 0x00, 0x15, 0xE8, + 0xE4, 0x3D, 0xF0, 0x02, 0x86, 0x3C, 0x29, 0x7F, + 0xC9, 0x13, 0xD0, 0x04, 0xA5, 0x47, 0x85, 0x3E, + 0xAD, 0x02, 0x6C, 0x29, 0x10, 0xF0, 0x2C, 0xA6, + 0x41, 0xF0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x20, + 0xD0, 0x21, 0x8E, 0x00, 0x6C, 0x64, 0x41, 0x4C, + 0xE1, 0x3C, 0xA6, 0x40, 0xE4, 0x3F, 0xF0, 0x13, + 0xA5, 0x3E, 0xD0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, + 0x20, 0xD0, 0x08, 0xBD, 0x00, 0x07, 0x8D, 0x00, + 0x6C, 0xE6, 0x40, 0xAD, 0x02, 0x74, 0x89, 0x08, + 0xF0, 0x3B, 0x89, 0x02, 0xF0, 0x1B, 0xAD, 0x00, + 0x74, 0xD0, 0x32, 0xA6, 0x48, 0xA9, 0x01, 0x9D, + 0x00, 0x16, 0xA9, 0x01, 0x9D, 0x00, 0x0F, 0xE8, + 0xE4, 0x49, 0xF0, 0x02, 0x86, 0x48, 0x4C, 0x23, + 0x3D, 0xA6, 0x48, 0xAD, 0x00, 0x74, 0x9D, 0x00, + 0x0F, 0x9E, 0x00, 0x16, 0xE8, 0xE4, 0x49, 0xF0, + 0x02, 0x86, 0x48, 0x29, 0x7F, 0xC9, 0x13, 0xD0, + 0x04, 0xA5, 0x53, 0x85, 0x4A, 0xAD, 0x02, 0x74, + 0x29, 0x10, 0xF0, 0x2C, 0xA6, 0x4D, 0xF0, 0x0F, + 0xAD, 0x02, 0x7C, 0x29, 0x40, 0xD0, 0x21, 0x8E, + 0x00, 0x74, 0x64, 0x4D, 0x4C, 0x56, 0x3D, 0xA6, + 0x4C, 0xE4, 0x4B, 0xF0, 0x13, 0xA5, 0x4A, 0xD0, + 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x40, 0xD0, 0x08, + 0xBD, 0x00, 0x08, 0x8D, 0x00, 0x74, 0xE6, 0x4C, + 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0xD0, 0x00, 0x38, + 0xCE, 0xC0, +}; diff --git a/drivers/staging/generic_serial/sx.c b/drivers/staging/generic_serial/sx.c new file mode 100644 index 000000000000..1291462bcddb --- /dev/null +++ b/drivers/staging/generic_serial/sx.c @@ -0,0 +1,2894 @@ +/* sx.c -- driver for the Specialix SX series cards. + * + * This driver will also support the older SI, and XIO cards. + * + * + * (C) 1998 - 2004 R.E.Wolff@BitWizard.nl + * + * Simon Allen (simonallen@cix.compulink.co.uk) wrote a previous + * version of this driver. Some fragments may have been copied. (none + * yet :-) + * + * Specialix pays for the development and support of this driver. + * Please DO contact support@specialix.co.uk if you require + * support. But please read the documentation (sx.txt) first. + * + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, + * USA. + * + * Revision history: + * Revision 1.33 2000/03/09 10:00:00 pvdl,wolff + * - Fixed module and port counting + * - Fixed signal handling + * - Fixed an Ooops + * + * Revision 1.32 2000/03/07 09:00:00 wolff,pvdl + * - Fixed some sx_dprintk typos + * - added detection for an invalid board/module configuration + * + * Revision 1.31 2000/03/06 12:00:00 wolff,pvdl + * - Added support for EISA + * + * Revision 1.30 2000/01/21 17:43:06 wolff + * - Added support for SX+ + * + * Revision 1.26 1999/08/05 15:22:14 wolff + * - Port to 2.3.x + * - Reformatted to Linus' liking. + * + * Revision 1.25 1999/07/30 14:24:08 wolff + * Had accidentally left "gs_debug" set to "-1" instead of "off" (=0). + * + * Revision 1.24 1999/07/28 09:41:52 wolff + * - I noticed the remark about use-count straying in sx.txt. I checked + * sx_open, and found a few places where that could happen. I hope it's + * fixed now. + * + * Revision 1.23 1999/07/28 08:56:06 wolff + * - Fixed crash when sx_firmware run twice. + * - Added sx_slowpoll as a module parameter (I guess nobody really wanted + * to change it from the default... ) + * - Fixed a stupid editing problem I introduced in 1.22. + * - Fixed dropping characters on a termios change. + * + * Revision 1.22 1999/07/26 21:01:43 wolff + * Russell Brown noticed that I had overlooked 4 out of six modem control + * signals in sx_getsignals. Ooops. + * + * Revision 1.21 1999/07/23 09:11:33 wolff + * I forgot to free dynamically allocated memory when the driver is unloaded. + * + * Revision 1.20 1999/07/20 06:25:26 wolff + * The "closing wait" wasn't honoured. Thanks to James Griffiths for + * reporting this. + * + * Revision 1.19 1999/07/11 08:59:59 wolff + * Fixed an oops in close, when an open was pending. Changed the memtest + * a bit. Should also test the board in word-mode, however my card fails the + * memtest then. I still have to figure out what is wrong... + * + * Revision 1.18 1999/06/10 09:38:42 wolff + * Changed the format of the firmware revision from %04x to %x.%02x . + * + * Revision 1.17 1999/06/04 09:44:35 wolff + * fixed problem: reference to pci stuff when config_pci was off... + * Thanks to Jorge Novo for noticing this. + * + * Revision 1.16 1999/06/02 08:30:15 wolff + * added/removed the workaround for the DCD bug in the Firmware. + * A bit more debugging code to locate that... + * + * Revision 1.15 1999/06/01 11:35:30 wolff + * when DCD is left low (floating?), on TA's the firmware first tells us + * that DCD is high, but after a short while suddenly comes to the + * conclusion that it is low. All this would be fine, if it weren't that + * Unix requires us to send a "hangup" signal in that case. This usually + * all happens BEFORE the program has had a chance to ioctl the device + * into clocal mode.. + * + * Revision 1.14 1999/05/25 11:18:59 wolff + * Added PCI-fix. + * Added checks for return code of sx_sendcommand. + * Don't issue "reconfig" if port isn't open yet. (bit us on TA modules...) + * + * Revision 1.13 1999/04/29 15:18:01 wolff + * Fixed an "oops" that showed on SuSE 6.0 systems. + * Activate DTR again after stty 0. + * + * Revision 1.12 1999/04/29 07:49:52 wolff + * Improved "stty 0" handling a bit. (used to change baud to 9600 assuming + * the connection would be dropped anyway. That is not always the case, + * and confuses people). + * Told the card to always monitor the modem signals. + * Added support for dynamic gs_debug adjustments. + * Now tells the rest of the system the number of ports. + * + * Revision 1.11 1999/04/24 11:11:30 wolff + * Fixed two stupid typos in the memory test. + * + * Revision 1.10 1999/04/24 10:53:39 wolff + * Added some of Christian's suggestions. + * Fixed an HW_COOK_IN bug (ISIG was not in I_OTHER. We used to trust the + * card to send the signal to the process.....) + * + * Revision 1.9 1999/04/23 07:26:38 wolff + * Included Christian Lademann's 2.0 compile-warning fixes and interrupt + * assignment redesign. + * Cleanup of some other stuff. + * + * Revision 1.8 1999/04/16 13:05:30 wolff + * fixed a DCD change unnoticed bug. + * + * Revision 1.7 1999/04/14 22:19:51 wolff + * Fixed typo that showed up in 2.0.x builds (get_user instead of Get_user!) + * + * Revision 1.6 1999/04/13 18:40:20 wolff + * changed misc-minor to 161, as assigned by HPA. + * + * Revision 1.5 1999/04/13 15:12:25 wolff + * Fixed use-count leak when "hangup" occurred. + * Added workaround for a stupid-PCIBIOS bug. + * + * + * Revision 1.4 1999/04/01 22:47:40 wolff + * Fixed < 1M linux-2.0 problem. + * (vremap isn't compatible with ioremap in that case) + * + * Revision 1.3 1999/03/31 13:45:45 wolff + * Firmware loading is now done through a separate IOCTL. + * + * Revision 1.2 1999/03/28 12:22:29 wolff + * rcs cleanup + * + * Revision 1.1 1999/03/28 12:10:34 wolff + * Readying for release on 2.0.x (sorry David, 1.01 becomes 1.1 for RCS). + * + * Revision 0.12 1999/03/28 09:20:10 wolff + * Fixed problem in 0.11, continueing cleanup. + * + * Revision 0.11 1999/03/28 08:46:44 wolff + * cleanup. Not good. + * + * Revision 0.10 1999/03/28 08:09:43 wolff + * Fixed loosing characters on close. + * + * Revision 0.9 1999/03/21 22:52:01 wolff + * Ported back to 2.2.... (minor things) + * + * Revision 0.8 1999/03/21 22:40:33 wolff + * Port to 2.0 + * + * Revision 0.7 1999/03/21 19:06:34 wolff + * Fixed hangup processing. + * + * Revision 0.6 1999/02/05 08:45:14 wolff + * fixed real_raw problems. Inclusion into kernel imminent. + * + * Revision 0.5 1998/12/21 23:51:06 wolff + * Snatched a nasty bug: sx_transmit_chars was getting re-entered, and it + * shouldn't have. THATs why I want to have transmit interrupts even when + * the buffer is empty. + * + * Revision 0.4 1998/12/17 09:34:46 wolff + * PPP works. ioctl works. Basically works! + * + * Revision 0.3 1998/12/15 13:05:18 wolff + * It works! Wow! Gotta start implementing IOCTL and stuff.... + * + * Revision 0.2 1998/12/01 08:33:53 wolff + * moved over to 2.1.130 + * + * Revision 0.1 1998/11/03 21:23:51 wolff + * Initial revision. Detects SX card. + * + * */ + +#define SX_VERSION 1.33 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* The 3.0.0 version of sxboards/sxwindow.h uses BYTE and WORD.... */ +#define BYTE u8 +#define WORD u16 + +/* .... but the 3.0.4 version uses _u8 and _u16. */ +#define _u8 u8 +#define _u16 u16 + +#include "sxboards.h" +#include "sxwindow.h" + +#include +#include "sx.h" + +/* I don't think that this driver can handle more than 256 ports on + one machine. You'll have to increase the number of boards in sx.h + if you want more than 4 boards. */ + +#ifndef PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 +#define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000 +#endif + +/* Configurable options: + (Don't be too sure that it'll work if you toggle them) */ + +/* Am I paranoid or not ? ;-) */ +#undef SX_PARANOIA_CHECK + +/* 20 -> 2000 per second. The card should rate-limit interrupts at 100 + Hz, but it is user configurable. I don't recommend going above 1000 + Hz. The interrupt ratelimit might trigger if the interrupt is + shared with a very active other device. */ +#define IRQ_RATE_LIMIT 20 + +/* Sharing interrupts is possible now. If the other device wants more + than 2000 interrupts per second, we'd gracefully decline further + interrupts. That's not what we want. On the other hand, if the + other device interrupts 2000 times a second, don't use the SX + interrupt. Use polling. */ +#undef IRQ_RATE_LIMIT + +#if 0 +/* Not implemented */ +/* + * The following defines are mostly for testing purposes. But if you need + * some nice reporting in your syslog, you can define them also. + */ +#define SX_REPORT_FIFO +#define SX_REPORT_OVERRUN +#endif + +/* Function prototypes */ +static void sx_disable_tx_interrupts(void *ptr); +static void sx_enable_tx_interrupts(void *ptr); +static void sx_disable_rx_interrupts(void *ptr); +static void sx_enable_rx_interrupts(void *ptr); +static int sx_carrier_raised(struct tty_port *port); +static void sx_shutdown_port(void *ptr); +static int sx_set_real_termios(void *ptr); +static void sx_close(void *ptr); +static int sx_chars_in_buffer(void *ptr); +static int sx_init_board(struct sx_board *board); +static int sx_init_portstructs(int nboards, int nports); +static long sx_fw_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg); +static int sx_init_drivers(void); + +static struct tty_driver *sx_driver; + +static DEFINE_MUTEX(sx_boards_lock); +static struct sx_board boards[SX_NBOARDS]; +static struct sx_port *sx_ports; +static int sx_initialized; +static int sx_nports; +static int sx_debug; + +/* You can have the driver poll your card. + - Set sx_poll to 1 to poll every timer tick (10ms on Intel). + This is used when the card cannot use an interrupt for some reason. + + - set sx_slowpoll to 100 to do an extra poll once a second (on Intel). If + the driver misses an interrupt (report this if it DOES happen to you!) + everything will continue to work.... + */ +static int sx_poll = 1; +static int sx_slowpoll; + +/* The card limits the number of interrupts per second. + At 115k2 "100" should be sufficient. + If you're using higher baudrates, you can increase this... + */ + +static int sx_maxints = 100; + +#ifdef CONFIG_ISA + +/* These are the only open spaces in my computer. Yours may have more + or less.... -- REW + duh: Card at 0xa0000 is possible on HP Netserver?? -- pvdl +*/ +static int sx_probe_addrs[] = { + 0xc0000, 0xd0000, 0xe0000, + 0xc8000, 0xd8000, 0xe8000 +}; +static int si_probe_addrs[] = { + 0xc0000, 0xd0000, 0xe0000, + 0xc8000, 0xd8000, 0xe8000, 0xa0000 +}; +static int si1_probe_addrs[] = { + 0xd0000 +}; + +#define NR_SX_ADDRS ARRAY_SIZE(sx_probe_addrs) +#define NR_SI_ADDRS ARRAY_SIZE(si_probe_addrs) +#define NR_SI1_ADDRS ARRAY_SIZE(si1_probe_addrs) + +module_param_array(sx_probe_addrs, int, NULL, 0); +module_param_array(si_probe_addrs, int, NULL, 0); +#endif + +/* Set the mask to all-ones. This alas, only supports 32 interrupts. + Some architectures may need more. */ +static int sx_irqmask = -1; + +module_param(sx_poll, int, 0); +module_param(sx_slowpoll, int, 0); +module_param(sx_maxints, int, 0); +module_param(sx_debug, int, 0); +module_param(sx_irqmask, int, 0); + +MODULE_LICENSE("GPL"); + +static struct real_driver sx_real_driver = { + sx_disable_tx_interrupts, + sx_enable_tx_interrupts, + sx_disable_rx_interrupts, + sx_enable_rx_interrupts, + sx_shutdown_port, + sx_set_real_termios, + sx_chars_in_buffer, + sx_close, +}; + +/* + This driver can spew a whole lot of debugging output at you. If you + need maximum performance, you should disable the DEBUG define. To + aid in debugging in the field, I'm leaving the compile-time debug + features enabled, and disable them "runtime". That allows me to + instruct people with problems to enable debugging without requiring + them to recompile... +*/ +#define DEBUG + +#ifdef DEBUG +#define sx_dprintk(f, str...) if (sx_debug & f) printk (str) +#else +#define sx_dprintk(f, str...) /* nothing */ +#endif + +#define func_enter() sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s\n",__func__) +#define func_exit() sx_dprintk(SX_DEBUG_FLOW, "sx: exit %s\n",__func__) + +#define func_enter2() sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s (port %d)\n", \ + __func__, port->line) + +/* + * Firmware loader driver specific routines + * + */ + +static const struct file_operations sx_fw_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = sx_fw_ioctl, + .llseek = noop_llseek, +}; + +static struct miscdevice sx_fw_device = { + SXCTL_MISC_MINOR, "sxctl", &sx_fw_fops +}; + +#ifdef SX_PARANOIA_CHECK + +/* This doesn't work. Who's paranoid around here? Not me! */ + +static inline int sx_paranoia_check(struct sx_port const *port, + char *name, const char *routine) +{ + static const char *badmagic = KERN_ERR "sx: Warning: bad sx port magic " + "number for device %s in %s\n"; + static const char *badinfo = KERN_ERR "sx: Warning: null sx port for " + "device %s in %s\n"; + + if (!port) { + printk(badinfo, name, routine); + return 1; + } + if (port->magic != SX_MAGIC) { + printk(badmagic, name, routine); + return 1; + } + + return 0; +} +#else +#define sx_paranoia_check(a,b,c) 0 +#endif + +/* The timeouts. First try 30 times as fast as possible. Then give + the card some time to breathe between accesses. (Otherwise the + processor on the card might not be able to access its OWN bus... */ + +#define TIMEOUT_1 30 +#define TIMEOUT_2 1000000 + +#ifdef DEBUG +static void my_hd_io(void __iomem *p, int len) +{ + int i, j, ch; + unsigned char __iomem *addr = p; + + for (i = 0; i < len; i += 16) { + printk("%p ", addr + i); + for (j = 0; j < 16; j++) { + printk("%02x %s", readb(addr + j + i), + (j == 7) ? " " : ""); + } + for (j = 0; j < 16; j++) { + ch = readb(addr + j + i); + printk("%c", (ch < 0x20) ? '.' : + ((ch > 0x7f) ? '.' : ch)); + } + printk("\n"); + } +} +static void my_hd(void *p, int len) +{ + int i, j, ch; + unsigned char *addr = p; + + for (i = 0; i < len; i += 16) { + printk("%p ", addr + i); + for (j = 0; j < 16; j++) { + printk("%02x %s", addr[j + i], (j == 7) ? " " : ""); + } + for (j = 0; j < 16; j++) { + ch = addr[j + i]; + printk("%c", (ch < 0x20) ? '.' : + ((ch > 0x7f) ? '.' : ch)); + } + printk("\n"); + } +} +#endif + +/* This needs redoing for Alpha -- REW -- Done. */ + +static inline void write_sx_byte(struct sx_board *board, int offset, u8 byte) +{ + writeb(byte, board->base + offset); +} + +static inline u8 read_sx_byte(struct sx_board *board, int offset) +{ + return readb(board->base + offset); +} + +static inline void write_sx_word(struct sx_board *board, int offset, u16 word) +{ + writew(word, board->base + offset); +} + +static inline u16 read_sx_word(struct sx_board *board, int offset) +{ + return readw(board->base + offset); +} + +static int sx_busy_wait_eq(struct sx_board *board, + int offset, int mask, int correctval) +{ + int i; + + func_enter(); + + for (i = 0; i < TIMEOUT_1; i++) + if ((read_sx_byte(board, offset) & mask) == correctval) { + func_exit(); + return 1; + } + + for (i = 0; i < TIMEOUT_2; i++) { + if ((read_sx_byte(board, offset) & mask) == correctval) { + func_exit(); + return 1; + } + udelay(1); + } + + func_exit(); + return 0; +} + +static int sx_busy_wait_neq(struct sx_board *board, + int offset, int mask, int badval) +{ + int i; + + func_enter(); + + for (i = 0; i < TIMEOUT_1; i++) + if ((read_sx_byte(board, offset) & mask) != badval) { + func_exit(); + return 1; + } + + for (i = 0; i < TIMEOUT_2; i++) { + if ((read_sx_byte(board, offset) & mask) != badval) { + func_exit(); + return 1; + } + udelay(1); + } + + func_exit(); + return 0; +} + +/* 5.6.4 of 6210028 r2.3 */ +static int sx_reset(struct sx_board *board) +{ + func_enter(); + + if (IS_SX_BOARD(board)) { + + write_sx_byte(board, SX_CONFIG, 0); + write_sx_byte(board, SX_RESET, 1); /* Value doesn't matter */ + + if (!sx_busy_wait_eq(board, SX_RESET_STATUS, 1, 0)) { + printk(KERN_INFO "sx: Card doesn't respond to " + "reset...\n"); + return 0; + } + } else if (IS_EISA_BOARD(board)) { + outb(board->irq << 4, board->eisa_base + 0xc02); + } else if (IS_SI1_BOARD(board)) { + write_sx_byte(board, SI1_ISA_RESET, 0); /*value doesn't matter*/ + } else { + /* Gory details of the SI/ISA board */ + write_sx_byte(board, SI2_ISA_RESET, SI2_ISA_RESET_SET); + write_sx_byte(board, SI2_ISA_IRQ11, SI2_ISA_IRQ11_CLEAR); + write_sx_byte(board, SI2_ISA_IRQ12, SI2_ISA_IRQ12_CLEAR); + write_sx_byte(board, SI2_ISA_IRQ15, SI2_ISA_IRQ15_CLEAR); + write_sx_byte(board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_CLEAR); + write_sx_byte(board, SI2_ISA_IRQSET, SI2_ISA_IRQSET_CLEAR); + } + + func_exit(); + return 1; +} + +/* This doesn't work on machines where "NULL" isn't 0 */ +/* If you have one of those, someone will need to write + the equivalent of this, which will amount to about 3 lines. I don't + want to complicate this right now. -- REW + (See, I do write comments every now and then :-) */ +#define OFFSETOF(strct, elem) ((long)&(((struct strct *)NULL)->elem)) + +#define CHAN_OFFSET(port,elem) (port->ch_base + OFFSETOF (_SXCHANNEL, elem)) +#define MODU_OFFSET(board,addr,elem) (addr + OFFSETOF (_SXMODULE, elem)) +#define BRD_OFFSET(board,elem) (OFFSETOF (_SXCARD, elem)) + +#define sx_write_channel_byte(port, elem, val) \ + write_sx_byte (port->board, CHAN_OFFSET (port, elem), val) + +#define sx_read_channel_byte(port, elem) \ + read_sx_byte (port->board, CHAN_OFFSET (port, elem)) + +#define sx_write_channel_word(port, elem, val) \ + write_sx_word (port->board, CHAN_OFFSET (port, elem), val) + +#define sx_read_channel_word(port, elem) \ + read_sx_word (port->board, CHAN_OFFSET (port, elem)) + +#define sx_write_module_byte(board, addr, elem, val) \ + write_sx_byte (board, MODU_OFFSET (board, addr, elem), val) + +#define sx_read_module_byte(board, addr, elem) \ + read_sx_byte (board, MODU_OFFSET (board, addr, elem)) + +#define sx_write_module_word(board, addr, elem, val) \ + write_sx_word (board, MODU_OFFSET (board, addr, elem), val) + +#define sx_read_module_word(board, addr, elem) \ + read_sx_word (board, MODU_OFFSET (board, addr, elem)) + +#define sx_write_board_byte(board, elem, val) \ + write_sx_byte (board, BRD_OFFSET (board, elem), val) + +#define sx_read_board_byte(board, elem) \ + read_sx_byte (board, BRD_OFFSET (board, elem)) + +#define sx_write_board_word(board, elem, val) \ + write_sx_word (board, BRD_OFFSET (board, elem), val) + +#define sx_read_board_word(board, elem) \ + read_sx_word (board, BRD_OFFSET (board, elem)) + +static int sx_start_board(struct sx_board *board) +{ + if (IS_SX_BOARD(board)) { + write_sx_byte(board, SX_CONFIG, SX_CONF_BUSEN); + } else if (IS_EISA_BOARD(board)) { + write_sx_byte(board, SI2_EISA_OFF, SI2_EISA_VAL); + outb((board->irq << 4) | 4, board->eisa_base + 0xc02); + } else if (IS_SI1_BOARD(board)) { + write_sx_byte(board, SI1_ISA_RESET_CLEAR, 0); + write_sx_byte(board, SI1_ISA_INTCL, 0); + } else { + /* Don't bug me about the clear_set. + I haven't the foggiest idea what it's about -- REW */ + write_sx_byte(board, SI2_ISA_RESET, SI2_ISA_RESET_CLEAR); + write_sx_byte(board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET); + } + return 1; +} + +#define SX_IRQ_REG_VAL(board) \ + ((board->flags & SX_ISA_BOARD) ? (board->irq << 4) : 0) + +/* Note. The SX register is write-only. Therefore, we have to enable the + bus too. This is a no-op, if you don't mess with this driver... */ +static int sx_start_interrupts(struct sx_board *board) +{ + + /* Don't call this with board->irq == 0 */ + + if (IS_SX_BOARD(board)) { + write_sx_byte(board, SX_CONFIG, SX_IRQ_REG_VAL(board) | + SX_CONF_BUSEN | SX_CONF_HOSTIRQ); + } else if (IS_EISA_BOARD(board)) { + inb(board->eisa_base + 0xc03); + } else if (IS_SI1_BOARD(board)) { + write_sx_byte(board, SI1_ISA_INTCL, 0); + write_sx_byte(board, SI1_ISA_INTCL_CLEAR, 0); + } else { + switch (board->irq) { + case 11: + write_sx_byte(board, SI2_ISA_IRQ11, SI2_ISA_IRQ11_SET); + break; + case 12: + write_sx_byte(board, SI2_ISA_IRQ12, SI2_ISA_IRQ12_SET); + break; + case 15: + write_sx_byte(board, SI2_ISA_IRQ15, SI2_ISA_IRQ15_SET); + break; + default: + printk(KERN_INFO "sx: SI/XIO card doesn't support " + "interrupt %d.\n", board->irq); + return 0; + } + write_sx_byte(board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET); + } + + return 1; +} + +static int sx_send_command(struct sx_port *port, + int command, int mask, int newstat) +{ + func_enter2(); + write_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat), command); + func_exit(); + return sx_busy_wait_eq(port->board, CHAN_OFFSET(port, hi_hstat), mask, + newstat); +} + +static char *mod_type_s(int module_type) +{ + switch (module_type) { + case TA4: + return "TA4"; + case TA8: + return "TA8"; + case TA4_ASIC: + return "TA4_ASIC"; + case TA8_ASIC: + return "TA8_ASIC"; + case MTA_CD1400: + return "MTA_CD1400"; + case SXDC: + return "SXDC"; + default: + return "Unknown/invalid"; + } +} + +static char *pan_type_s(int pan_type) +{ + switch (pan_type) { + case MOD_RS232DB25: + return "MOD_RS232DB25"; + case MOD_RS232RJ45: + return "MOD_RS232RJ45"; + case MOD_RS422DB25: + return "MOD_RS422DB25"; + case MOD_PARALLEL: + return "MOD_PARALLEL"; + case MOD_2_RS232DB25: + return "MOD_2_RS232DB25"; + case MOD_2_RS232RJ45: + return "MOD_2_RS232RJ45"; + case MOD_2_RS422DB25: + return "MOD_2_RS422DB25"; + case MOD_RS232DB25MALE: + return "MOD_RS232DB25MALE"; + case MOD_2_PARALLEL: + return "MOD_2_PARALLEL"; + case MOD_BLANK: + return "empty"; + default: + return "invalid"; + } +} + +static int mod_compat_type(int module_type) +{ + return module_type >> 4; +} + +static void sx_reconfigure_port(struct sx_port *port) +{ + if (sx_read_channel_byte(port, hi_hstat) == HS_IDLE_OPEN) { + if (sx_send_command(port, HS_CONFIG, -1, HS_IDLE_OPEN) != 1) { + printk(KERN_WARNING "sx: Sent reconfigure command, but " + "card didn't react.\n"); + } + } else { + sx_dprintk(SX_DEBUG_TERMIOS, "sx: Not sending reconfigure: " + "port isn't open (%02x).\n", + sx_read_channel_byte(port, hi_hstat)); + } +} + +static void sx_setsignals(struct sx_port *port, int dtr, int rts) +{ + int t; + func_enter2(); + + t = sx_read_channel_byte(port, hi_op); + if (dtr >= 0) + t = dtr ? (t | OP_DTR) : (t & ~OP_DTR); + if (rts >= 0) + t = rts ? (t | OP_RTS) : (t & ~OP_RTS); + sx_write_channel_byte(port, hi_op, t); + sx_dprintk(SX_DEBUG_MODEMSIGNALS, "setsignals: %d/%d\n", dtr, rts); + + func_exit(); +} + +static int sx_getsignals(struct sx_port *port) +{ + int i_stat, o_stat; + + o_stat = sx_read_channel_byte(port, hi_op); + i_stat = sx_read_channel_byte(port, hi_ip); + + sx_dprintk(SX_DEBUG_MODEMSIGNALS, "getsignals: %d/%d (%d/%d) " + "%02x/%02x\n", + (o_stat & OP_DTR) != 0, (o_stat & OP_RTS) != 0, + port->c_dcd, tty_port_carrier_raised(&port->gs.port), + sx_read_channel_byte(port, hi_ip), + sx_read_channel_byte(port, hi_state)); + + return (((o_stat & OP_DTR) ? TIOCM_DTR : 0) | + ((o_stat & OP_RTS) ? TIOCM_RTS : 0) | + ((i_stat & IP_CTS) ? TIOCM_CTS : 0) | + ((i_stat & IP_DCD) ? TIOCM_CAR : 0) | + ((i_stat & IP_DSR) ? TIOCM_DSR : 0) | + ((i_stat & IP_RI) ? TIOCM_RNG : 0)); +} + +static void sx_set_baud(struct sx_port *port) +{ + int t; + + if (port->board->ta_type == MOD_SXDC) { + switch (port->gs.baud) { + /* Save some typing work... */ +#define e(x) case x: t = BAUD_ ## x; break + e(50); + e(75); + e(110); + e(150); + e(200); + e(300); + e(600); + e(1200); + e(1800); + e(2000); + e(2400); + e(4800); + e(7200); + e(9600); + e(14400); + e(19200); + e(28800); + e(38400); + e(56000); + e(57600); + e(64000); + e(76800); + e(115200); + e(128000); + e(150000); + e(230400); + e(256000); + e(460800); + e(921600); + case 134: + t = BAUD_134_5; + break; + case 0: + t = -1; + break; + default: + /* Can I return "invalid"? */ + t = BAUD_9600; + printk(KERN_INFO "sx: unsupported baud rate: %d.\n", + port->gs.baud); + break; + } +#undef e + if (t > 0) { +/* The baud rate is not set to 0, so we're enabeling DTR... -- REW */ + sx_setsignals(port, 1, -1); + /* XXX This is not TA & MTA compatible */ + sx_write_channel_byte(port, hi_csr, 0xff); + + sx_write_channel_byte(port, hi_txbaud, t); + sx_write_channel_byte(port, hi_rxbaud, t); + } else { + sx_setsignals(port, 0, -1); + } + } else { + switch (port->gs.baud) { +#define e(x) case x: t = CSR_ ## x; break + e(75); + e(150); + e(300); + e(600); + e(1200); + e(2400); + e(4800); + e(1800); + e(9600); + e(19200); + e(57600); + e(38400); +/* TA supports 110, but not 115200, MTA supports 115200, but not 110 */ + case 110: + if (port->board->ta_type == MOD_TA) { + t = CSR_110; + break; + } else { + t = CSR_9600; + printk(KERN_INFO "sx: Unsupported baud rate: " + "%d.\n", port->gs.baud); + break; + } + case 115200: + if (port->board->ta_type == MOD_TA) { + t = CSR_9600; + printk(KERN_INFO "sx: Unsupported baud rate: " + "%d.\n", port->gs.baud); + break; + } else { + t = CSR_110; + break; + } + case 0: + t = -1; + break; + default: + t = CSR_9600; + printk(KERN_INFO "sx: Unsupported baud rate: %d.\n", + port->gs.baud); + break; + } +#undef e + if (t >= 0) { + sx_setsignals(port, 1, -1); + sx_write_channel_byte(port, hi_csr, t * 0x11); + } else { + sx_setsignals(port, 0, -1); + } + } +} + +/* Simon Allen's version of this routine was 225 lines long. 85 is a lot + better. -- REW */ + +static int sx_set_real_termios(void *ptr) +{ + struct sx_port *port = ptr; + + func_enter2(); + + if (!port->gs.port.tty) + return 0; + + /* What is this doing here? -- REW + Ha! figured it out. It is to allow you to get DTR active again + if you've dropped it with stty 0. Moved to set_baud, where it + belongs (next to the drop dtr if baud == 0) -- REW */ + /* sx_setsignals (port, 1, -1); */ + + sx_set_baud(port); + +#define CFLAG port->gs.port.tty->termios->c_cflag + sx_write_channel_byte(port, hi_mr1, + (C_PARENB(port->gs.port.tty) ? MR1_WITH : MR1_NONE) | + (C_PARODD(port->gs.port.tty) ? MR1_ODD : MR1_EVEN) | + (C_CRTSCTS(port->gs.port.tty) ? MR1_RTS_RXFLOW : 0) | + (((CFLAG & CSIZE) == CS8) ? MR1_8_BITS : 0) | + (((CFLAG & CSIZE) == CS7) ? MR1_7_BITS : 0) | + (((CFLAG & CSIZE) == CS6) ? MR1_6_BITS : 0) | + (((CFLAG & CSIZE) == CS5) ? MR1_5_BITS : 0)); + + sx_write_channel_byte(port, hi_mr2, + (C_CRTSCTS(port->gs.port.tty) ? MR2_CTS_TXFLOW : 0) | + (C_CSTOPB(port->gs.port.tty) ? MR2_2_STOP : + MR2_1_STOP)); + + switch (CFLAG & CSIZE) { + case CS8: + sx_write_channel_byte(port, hi_mask, 0xff); + break; + case CS7: + sx_write_channel_byte(port, hi_mask, 0x7f); + break; + case CS6: + sx_write_channel_byte(port, hi_mask, 0x3f); + break; + case CS5: + sx_write_channel_byte(port, hi_mask, 0x1f); + break; + default: + printk(KERN_INFO "sx: Invalid wordsize: %u\n", + (unsigned int)CFLAG & CSIZE); + break; + } + + sx_write_channel_byte(port, hi_prtcl, + (I_IXON(port->gs.port.tty) ? SP_TXEN : 0) | + (I_IXOFF(port->gs.port.tty) ? SP_RXEN : 0) | + (I_IXANY(port->gs.port.tty) ? SP_TANY : 0) | SP_DCEN); + + sx_write_channel_byte(port, hi_break, + (I_IGNBRK(port->gs.port.tty) ? BR_IGN : 0 | + I_BRKINT(port->gs.port.tty) ? BR_INT : 0)); + + sx_write_channel_byte(port, hi_txon, START_CHAR(port->gs.port.tty)); + sx_write_channel_byte(port, hi_rxon, START_CHAR(port->gs.port.tty)); + sx_write_channel_byte(port, hi_txoff, STOP_CHAR(port->gs.port.tty)); + sx_write_channel_byte(port, hi_rxoff, STOP_CHAR(port->gs.port.tty)); + + sx_reconfigure_port(port); + + /* Tell line discipline whether we will do input cooking */ + if (I_OTHER(port->gs.port.tty)) { + clear_bit(TTY_HW_COOK_IN, &port->gs.port.tty->flags); + } else { + set_bit(TTY_HW_COOK_IN, &port->gs.port.tty->flags); + } + sx_dprintk(SX_DEBUG_TERMIOS, "iflags: %x(%d) ", + (unsigned int)port->gs.port.tty->termios->c_iflag, + I_OTHER(port->gs.port.tty)); + +/* Tell line discipline whether we will do output cooking. + * If OPOST is set and no other output flags are set then we can do output + * processing. Even if only *one* other flag in the O_OTHER group is set + * we do cooking in software. + */ + if (O_OPOST(port->gs.port.tty) && !O_OTHER(port->gs.port.tty)) { + set_bit(TTY_HW_COOK_OUT, &port->gs.port.tty->flags); + } else { + clear_bit(TTY_HW_COOK_OUT, &port->gs.port.tty->flags); + } + sx_dprintk(SX_DEBUG_TERMIOS, "oflags: %x(%d)\n", + (unsigned int)port->gs.port.tty->termios->c_oflag, + O_OTHER(port->gs.port.tty)); + /* port->c_dcd = sx_get_CD (port); */ + func_exit(); + return 0; +} + +/* ********************************************************************** * + * the interrupt related routines * + * ********************************************************************** */ + +/* Note: + Other drivers use the macro "MIN" to calculate how much to copy. + This has the disadvantage that it will evaluate parts twice. That's + expensive when it's IO (and the compiler cannot optimize those away!). + Moreover, I'm not sure that you're race-free. + + I assign a value, and then only allow the value to decrease. This + is always safe. This makes the code a few lines longer, and you + know I'm dead against that, but I think it is required in this + case. */ + +static void sx_transmit_chars(struct sx_port *port) +{ + int c; + int tx_ip; + int txroom; + + func_enter2(); + sx_dprintk(SX_DEBUG_TRANSMIT, "Port %p: transmit %d chars\n", + port, port->gs.xmit_cnt); + + if (test_and_set_bit(SX_PORT_TRANSMIT_LOCK, &port->locks)) { + return; + } + + while (1) { + c = port->gs.xmit_cnt; + + sx_dprintk(SX_DEBUG_TRANSMIT, "Copying %d ", c); + tx_ip = sx_read_channel_byte(port, hi_txipos); + + /* Took me 5 minutes to deduce this formula. + Luckily it is literally in the manual in section 6.5.4.3.5 */ + txroom = (sx_read_channel_byte(port, hi_txopos) - tx_ip - 1) & + 0xff; + + /* Don't copy more bytes than there is room for in the buffer */ + if (c > txroom) + c = txroom; + sx_dprintk(SX_DEBUG_TRANSMIT, " %d(%d) ", c, txroom); + + /* Don't copy past the end of the hardware transmit buffer */ + if (c > 0x100 - tx_ip) + c = 0x100 - tx_ip; + + sx_dprintk(SX_DEBUG_TRANSMIT, " %d(%d) ", c, 0x100 - tx_ip); + + /* Don't copy pas the end of the source buffer */ + if (c > SERIAL_XMIT_SIZE - port->gs.xmit_tail) + c = SERIAL_XMIT_SIZE - port->gs.xmit_tail; + + sx_dprintk(SX_DEBUG_TRANSMIT, " %d(%ld) \n", + c, SERIAL_XMIT_SIZE - port->gs.xmit_tail); + + /* If for one reason or another, we can't copy more data, we're + done! */ + if (c == 0) + break; + + memcpy_toio(port->board->base + CHAN_OFFSET(port, hi_txbuf) + + tx_ip, port->gs.xmit_buf + port->gs.xmit_tail, c); + + /* Update the pointer in the card */ + sx_write_channel_byte(port, hi_txipos, (tx_ip + c) & 0xff); + + /* Update the kernel buffer end */ + port->gs.xmit_tail = (port->gs.xmit_tail + c) & + (SERIAL_XMIT_SIZE - 1); + + /* This one last. (this is essential) + It would allow others to start putting more data into the + buffer! */ + port->gs.xmit_cnt -= c; + } + + if (port->gs.xmit_cnt == 0) { + sx_disable_tx_interrupts(port); + } + + if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.port.tty) { + tty_wakeup(port->gs.port.tty); + sx_dprintk(SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n", + port->gs.wakeup_chars); + } + + clear_bit(SX_PORT_TRANSMIT_LOCK, &port->locks); + func_exit(); +} + +/* Note the symmetry between receiving chars and transmitting them! + Note: The kernel should have implemented both a receive buffer and + a transmit buffer. */ + +/* Inlined: Called only once. Remove the inline when you add another call */ +static inline void sx_receive_chars(struct sx_port *port) +{ + int c; + int rx_op; + struct tty_struct *tty; + int copied = 0; + unsigned char *rp; + + func_enter2(); + tty = port->gs.port.tty; + while (1) { + rx_op = sx_read_channel_byte(port, hi_rxopos); + c = (sx_read_channel_byte(port, hi_rxipos) - rx_op) & 0xff; + + sx_dprintk(SX_DEBUG_RECEIVE, "rxop=%d, c = %d.\n", rx_op, c); + + /* Don't copy past the end of the hardware receive buffer */ + if (rx_op + c > 0x100) + c = 0x100 - rx_op; + + sx_dprintk(SX_DEBUG_RECEIVE, "c = %d.\n", c); + + /* Don't copy more bytes than there is room for in the buffer */ + + c = tty_prepare_flip_string(tty, &rp, c); + + sx_dprintk(SX_DEBUG_RECEIVE, "c = %d.\n", c); + + /* If for one reason or another, we can't copy more data, we're done! */ + if (c == 0) + break; + + sx_dprintk(SX_DEBUG_RECEIVE, "Copying over %d chars. First is " + "%d at %lx\n", c, read_sx_byte(port->board, + CHAN_OFFSET(port, hi_rxbuf) + rx_op), + CHAN_OFFSET(port, hi_rxbuf)); + memcpy_fromio(rp, port->board->base + + CHAN_OFFSET(port, hi_rxbuf) + rx_op, c); + + /* This one last. ( Not essential.) + It allows the card to start putting more data into the + buffer! + Update the pointer in the card */ + sx_write_channel_byte(port, hi_rxopos, (rx_op + c) & 0xff); + + copied += c; + } + if (copied) { + struct timeval tv; + + do_gettimeofday(&tv); + sx_dprintk(SX_DEBUG_RECEIVE, "pushing flipq port %d (%3d " + "chars): %d.%06d (%d/%d)\n", port->line, + copied, (int)(tv.tv_sec % 60), (int)tv.tv_usec, + tty->raw, tty->real_raw); + + /* Tell the rest of the system the news. Great news. New + characters! */ + tty_flip_buffer_push(tty); + /* tty_schedule_flip (tty); */ + } + + func_exit(); +} + +/* Inlined: it is called only once. Remove the inline if you add another + call */ +static inline void sx_check_modem_signals(struct sx_port *port) +{ + int hi_state; + int c_dcd; + + hi_state = sx_read_channel_byte(port, hi_state); + sx_dprintk(SX_DEBUG_MODEMSIGNALS, "Checking modem signals (%d/%d)\n", + port->c_dcd, tty_port_carrier_raised(&port->gs.port)); + + if (hi_state & ST_BREAK) { + hi_state &= ~ST_BREAK; + sx_dprintk(SX_DEBUG_MODEMSIGNALS, "got a break.\n"); + sx_write_channel_byte(port, hi_state, hi_state); + gs_got_break(&port->gs); + } + if (hi_state & ST_DCD) { + hi_state &= ~ST_DCD; + sx_dprintk(SX_DEBUG_MODEMSIGNALS, "got a DCD change.\n"); + sx_write_channel_byte(port, hi_state, hi_state); + c_dcd = tty_port_carrier_raised(&port->gs.port); + sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD is now %d\n", c_dcd); + if (c_dcd != port->c_dcd) { + port->c_dcd = c_dcd; + if (tty_port_carrier_raised(&port->gs.port)) { + /* DCD went UP */ + if ((sx_read_channel_byte(port, hi_hstat) != + HS_IDLE_CLOSED) && + !(port->gs.port.tty->termios-> + c_cflag & CLOCAL)) { + /* Are we blocking in open? */ + sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " + "active, unblocking open\n"); + wake_up_interruptible(&port->gs.port. + open_wait); + } else { + sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " + "raised. Ignoring.\n"); + } + } else { + /* DCD went down! */ + if (!(port->gs.port.tty->termios->c_cflag & CLOCAL)){ + sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " + "dropped. hanging up....\n"); + tty_hangup(port->gs.port.tty); + } else { + sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " + "dropped. ignoring.\n"); + } + } + } else { + sx_dprintk(SX_DEBUG_MODEMSIGNALS, "Hmmm. card told us " + "DCD changed, but it didn't.\n"); + } + } +} + +/* This is what an interrupt routine should look like. + * Small, elegant, clear. + */ + +static irqreturn_t sx_interrupt(int irq, void *ptr) +{ + struct sx_board *board = ptr; + struct sx_port *port; + int i; + + func_enter(); + sx_dprintk(SX_DEBUG_FLOW, "sx: enter sx_interrupt (%d/%d)\n", irq, + board->irq); + + /* AAargh! The order in which to do these things is essential and + not trivial. + + - Rate limit goes before "recursive". Otherwise a series of + recursive calls will hang the machine in the interrupt routine. + + - hardware twiddling goes before "recursive". Otherwise when we + poll the card, and a recursive interrupt happens, we won't + ack the card, so it might keep on interrupting us. (especially + level sensitive interrupt systems like PCI). + + - Rate limit goes before hardware twiddling. Otherwise we won't + catch a card that has gone bonkers. + + - The "initialized" test goes after the hardware twiddling. Otherwise + the card will stick us in the interrupt routine again. + + - The initialized test goes before recursive. + */ + +#ifdef IRQ_RATE_LIMIT + /* Aaargh! I'm ashamed. This costs more lines-of-code than the + actual interrupt routine!. (Well, used to when I wrote that + comment) */ + { + static int lastjif; + static int nintr = 0; + + if (lastjif == jiffies) { + if (++nintr > IRQ_RATE_LIMIT) { + free_irq(board->irq, board); + printk(KERN_ERR "sx: Too many interrupts. " + "Turning off interrupt %d.\n", + board->irq); + } + } else { + lastjif = jiffies; + nintr = 0; + } + } +#endif + + if (board->irq == irq) { + /* Tell the card we've noticed the interrupt. */ + + sx_write_board_word(board, cc_int_pending, 0); + if (IS_SX_BOARD(board)) { + write_sx_byte(board, SX_RESET_IRQ, 1); + } else if (IS_EISA_BOARD(board)) { + inb(board->eisa_base + 0xc03); + write_sx_word(board, 8, 0); + } else { + write_sx_byte(board, SI2_ISA_INTCLEAR, + SI2_ISA_INTCLEAR_CLEAR); + write_sx_byte(board, SI2_ISA_INTCLEAR, + SI2_ISA_INTCLEAR_SET); + } + } + + if (!sx_initialized) + return IRQ_HANDLED; + if (!(board->flags & SX_BOARD_INITIALIZED)) + return IRQ_HANDLED; + + if (test_and_set_bit(SX_BOARD_INTR_LOCK, &board->locks)) { + printk(KERN_ERR "Recursive interrupt! (%d)\n", board->irq); + return IRQ_HANDLED; + } + + for (i = 0; i < board->nports; i++) { + port = &board->ports[i]; + if (port->gs.port.flags & GS_ACTIVE) { + if (sx_read_channel_byte(port, hi_state)) { + sx_dprintk(SX_DEBUG_INTERRUPTS, "Port %d: " + "modem signal change?... \n",i); + sx_check_modem_signals(port); + } + if (port->gs.xmit_cnt) { + sx_transmit_chars(port); + } + if (!(port->gs.port.flags & SX_RX_THROTTLE)) { + sx_receive_chars(port); + } + } + } + + clear_bit(SX_BOARD_INTR_LOCK, &board->locks); + + sx_dprintk(SX_DEBUG_FLOW, "sx: exit sx_interrupt (%d/%d)\n", irq, + board->irq); + func_exit(); + return IRQ_HANDLED; +} + +static void sx_pollfunc(unsigned long data) +{ + struct sx_board *board = (struct sx_board *)data; + + func_enter(); + + sx_interrupt(0, board); + + mod_timer(&board->timer, jiffies + sx_poll); + func_exit(); +} + +/* ********************************************************************** * + * Here are the routines that actually * + * interface with the generic_serial driver * + * ********************************************************************** */ + +/* Ehhm. I don't know how to fiddle with interrupts on the SX card. --REW */ +/* Hmm. Ok I figured it out. You don't. */ + +static void sx_disable_tx_interrupts(void *ptr) +{ + struct sx_port *port = ptr; + func_enter2(); + + port->gs.port.flags &= ~GS_TX_INTEN; + + func_exit(); +} + +static void sx_enable_tx_interrupts(void *ptr) +{ + struct sx_port *port = ptr; + int data_in_buffer; + func_enter2(); + + /* First transmit the characters that we're supposed to */ + sx_transmit_chars(port); + + /* The sx card will never interrupt us if we don't fill the buffer + past 25%. So we keep considering interrupts off if that's the case. */ + data_in_buffer = (sx_read_channel_byte(port, hi_txipos) - + sx_read_channel_byte(port, hi_txopos)) & 0xff; + + /* XXX Must be "HIGH_WATER" for SI card according to doc. */ + if (data_in_buffer < LOW_WATER) + port->gs.port.flags &= ~GS_TX_INTEN; + + func_exit(); +} + +static void sx_disable_rx_interrupts(void *ptr) +{ + /* struct sx_port *port = ptr; */ + func_enter(); + + func_exit(); +} + +static void sx_enable_rx_interrupts(void *ptr) +{ + /* struct sx_port *port = ptr; */ + func_enter(); + + func_exit(); +} + +/* Jeez. Isn't this simple? */ +static int sx_carrier_raised(struct tty_port *port) +{ + struct sx_port *sp = container_of(port, struct sx_port, gs.port); + return ((sx_read_channel_byte(sp, hi_ip) & IP_DCD) != 0); +} + +/* Jeez. Isn't this simple? */ +static int sx_chars_in_buffer(void *ptr) +{ + struct sx_port *port = ptr; + func_enter2(); + + func_exit(); + return ((sx_read_channel_byte(port, hi_txipos) - + sx_read_channel_byte(port, hi_txopos)) & 0xff); +} + +static void sx_shutdown_port(void *ptr) +{ + struct sx_port *port = ptr; + + func_enter(); + + port->gs.port.flags &= ~GS_ACTIVE; + if (port->gs.port.tty && (port->gs.port.tty->termios->c_cflag & HUPCL)) { + sx_setsignals(port, 0, 0); + sx_reconfigure_port(port); + } + + func_exit(); +} + +/* ********************************************************************** * + * Here are the routines that actually * + * interface with the rest of the system * + * ********************************************************************** */ + +static int sx_open(struct tty_struct *tty, struct file *filp) +{ + struct sx_port *port; + int retval, line; + unsigned long flags; + + func_enter(); + + if (!sx_initialized) { + return -EIO; + } + + line = tty->index; + sx_dprintk(SX_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p, " + "np=%d)\n", task_pid_nr(current), line, tty, + current->signal->tty, sx_nports); + + if ((line < 0) || (line >= SX_NPORTS) || (line >= sx_nports)) + return -ENODEV; + + port = &sx_ports[line]; + port->c_dcd = 0; /* Make sure that the first interrupt doesn't detect a + 1 -> 0 transition. */ + + sx_dprintk(SX_DEBUG_OPEN, "port = %p c_dcd = %d\n", port, port->c_dcd); + + spin_lock_irqsave(&port->gs.driver_lock, flags); + + tty->driver_data = port; + port->gs.port.tty = tty; + port->gs.port.count++; + spin_unlock_irqrestore(&port->gs.driver_lock, flags); + + sx_dprintk(SX_DEBUG_OPEN, "starting port\n"); + + /* + * Start up serial port + */ + retval = gs_init_port(&port->gs); + sx_dprintk(SX_DEBUG_OPEN, "done gs_init\n"); + if (retval) { + port->gs.port.count--; + return retval; + } + + port->gs.port.flags |= GS_ACTIVE; + if (port->gs.port.count <= 1) + sx_setsignals(port, 1, 1); + +#if 0 + if (sx_debug & SX_DEBUG_OPEN) + my_hd(port, sizeof(*port)); +#else + if (sx_debug & SX_DEBUG_OPEN) + my_hd_io(port->board->base + port->ch_base, sizeof(*port)); +#endif + + if (port->gs.port.count <= 1) { + if (sx_send_command(port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) { + printk(KERN_ERR "sx: Card didn't respond to LOPEN " + "command.\n"); + spin_lock_irqsave(&port->gs.driver_lock, flags); + port->gs.port.count--; + spin_unlock_irqrestore(&port->gs.driver_lock, flags); + return -EIO; + } + } + + retval = gs_block_til_ready(port, filp); + sx_dprintk(SX_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n", + retval, port->gs.port.count); + + if (retval) { +/* + * Don't lower gs.port.count here because sx_close() will be called later + */ + + return retval; + } + /* tty->low_latency = 1; */ + + port->c_dcd = sx_carrier_raised(&port->gs.port); + sx_dprintk(SX_DEBUG_OPEN, "at open: cd=%d\n", port->c_dcd); + + func_exit(); + return 0; + +} + +static void sx_close(void *ptr) +{ + struct sx_port *port = ptr; + /* Give the port 5 seconds to close down. */ + int to = 5 * HZ; + + func_enter(); + + sx_setsignals(port, 0, 0); + sx_reconfigure_port(port); + sx_send_command(port, HS_CLOSE, 0, 0); + + while (to-- && (sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED)) + if (msleep_interruptible(10)) + break; + if (sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED) { + if (sx_send_command(port, HS_FORCE_CLOSED, -1, HS_IDLE_CLOSED) + != 1) { + printk(KERN_ERR "sx: sent the force_close command, but " + "card didn't react\n"); + } else + sx_dprintk(SX_DEBUG_CLOSE, "sent the force_close " + "command.\n"); + } + + sx_dprintk(SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n", + 5 * HZ - to - 1, port->gs.port.count); + + if (port->gs.port.count) { + sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", + port->gs.port.count); + /*printk("%s SETTING port count to zero: %p count: %d\n", + __func__, port, port->gs.port.count); + port->gs.port.count = 0;*/ + } + + func_exit(); +} + +/* This is relatively thorough. But then again it is only 20 lines. */ +#define MARCHUP for (i = min; i < max; i++) +#define MARCHDOWN for (i = max - 1; i >= min; i--) +#define W0 write_sx_byte(board, i, 0x55) +#define W1 write_sx_byte(board, i, 0xaa) +#define R0 if (read_sx_byte(board, i) != 0x55) return 1 +#define R1 if (read_sx_byte(board, i) != 0xaa) return 1 + +/* This memtest takes a human-noticable time. You normally only do it + once a boot, so I guess that it is worth it. */ +static int do_memtest(struct sx_board *board, int min, int max) +{ + int i; + + /* This is a marchb. Theoretically, marchb catches much more than + simpler tests. In practise, the longer test just catches more + intermittent errors. -- REW + (For the theory behind memory testing see: + Testing Semiconductor Memories by A.J. van de Goor.) */ + MARCHUP { + W0; + } + MARCHUP { + R0; + W1; + R1; + W0; + R0; + W1; + } + MARCHUP { + R1; + W0; + W1; + } + MARCHDOWN { + R1; + W0; + W1; + W0; + } + MARCHDOWN { + R0; + W1; + W0; + } + + return 0; +} + +#undef MARCHUP +#undef MARCHDOWN +#undef W0 +#undef W1 +#undef R0 +#undef R1 + +#define MARCHUP for (i = min; i < max; i += 2) +#define MARCHDOWN for (i = max - 1; i >= min; i -= 2) +#define W0 write_sx_word(board, i, 0x55aa) +#define W1 write_sx_word(board, i, 0xaa55) +#define R0 if (read_sx_word(board, i) != 0x55aa) return 1 +#define R1 if (read_sx_word(board, i) != 0xaa55) return 1 + +#if 0 +/* This memtest takes a human-noticable time. You normally only do it + once a boot, so I guess that it is worth it. */ +static int do_memtest_w(struct sx_board *board, int min, int max) +{ + int i; + + MARCHUP { + W0; + } + MARCHUP { + R0; + W1; + R1; + W0; + R0; + W1; + } + MARCHUP { + R1; + W0; + W1; + } + MARCHDOWN { + R1; + W0; + W1; + W0; + } + MARCHDOWN { + R0; + W1; + W0; + } + + return 0; +} +#endif + +static long sx_fw_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + long rc = 0; + int __user *descr = (int __user *)arg; + int i; + static struct sx_board *board = NULL; + int nbytes, offset; + unsigned long data; + char *tmp; + + func_enter(); + + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + + tty_lock(); + + sx_dprintk(SX_DEBUG_FIRMWARE, "IOCTL %x: %lx\n", cmd, arg); + + if (!board) + board = &boards[0]; + if (board->flags & SX_BOARD_PRESENT) { + sx_dprintk(SX_DEBUG_FIRMWARE, "Board present! (%x)\n", + board->flags); + } else { + sx_dprintk(SX_DEBUG_FIRMWARE, "Board not present! (%x) all:", + board->flags); + for (i = 0; i < SX_NBOARDS; i++) + sx_dprintk(SX_DEBUG_FIRMWARE, "<%x> ", boards[i].flags); + sx_dprintk(SX_DEBUG_FIRMWARE, "\n"); + rc = -EIO; + goto out; + } + + switch (cmd) { + case SXIO_SET_BOARD: + sx_dprintk(SX_DEBUG_FIRMWARE, "set board to %ld\n", arg); + rc = -EIO; + if (arg >= SX_NBOARDS) + break; + sx_dprintk(SX_DEBUG_FIRMWARE, "not out of range\n"); + if (!(boards[arg].flags & SX_BOARD_PRESENT)) + break; + sx_dprintk(SX_DEBUG_FIRMWARE, ".. and present!\n"); + board = &boards[arg]; + rc = 0; + /* FIXME: And this does ... nothing?? */ + break; + case SXIO_GET_TYPE: + rc = -ENOENT; /* If we manage to miss one, return error. */ + if (IS_SX_BOARD(board)) + rc = SX_TYPE_SX; + if (IS_CF_BOARD(board)) + rc = SX_TYPE_CF; + if (IS_SI_BOARD(board)) + rc = SX_TYPE_SI; + if (IS_SI1_BOARD(board)) + rc = SX_TYPE_SI; + if (IS_EISA_BOARD(board)) + rc = SX_TYPE_SI; + sx_dprintk(SX_DEBUG_FIRMWARE, "returning type= %ld\n", rc); + break; + case SXIO_DO_RAMTEST: + if (sx_initialized) { /* Already initialized: better not ramtest the board. */ + rc = -EPERM; + break; + } + if (IS_SX_BOARD(board)) { + rc = do_memtest(board, 0, 0x7000); + if (!rc) + rc = do_memtest(board, 0, 0x7000); + /*if (!rc) rc = do_memtest_w (board, 0, 0x7000); */ + } else { + rc = do_memtest(board, 0, 0x7ff8); + /* if (!rc) rc = do_memtest_w (board, 0, 0x7ff8); */ + } + sx_dprintk(SX_DEBUG_FIRMWARE, + "returning memtest result= %ld\n", rc); + break; + case SXIO_DOWNLOAD: + if (sx_initialized) {/* Already initialized */ + rc = -EEXIST; + break; + } + if (!sx_reset(board)) { + rc = -EIO; + break; + } + sx_dprintk(SX_DEBUG_INIT, "reset the board...\n"); + + tmp = kmalloc(SX_CHUNK_SIZE, GFP_USER); + if (!tmp) { + rc = -ENOMEM; + break; + } + /* FIXME: check returns */ + get_user(nbytes, descr++); + get_user(offset, descr++); + get_user(data, descr++); + while (nbytes && data) { + for (i = 0; i < nbytes; i += SX_CHUNK_SIZE) { + if (copy_from_user(tmp, (char __user *)data + i, + (i + SX_CHUNK_SIZE > nbytes) ? + nbytes - i : SX_CHUNK_SIZE)) { + kfree(tmp); + rc = -EFAULT; + goto out; + } + memcpy_toio(board->base2 + offset + i, tmp, + (i + SX_CHUNK_SIZE > nbytes) ? + nbytes - i : SX_CHUNK_SIZE); + } + + get_user(nbytes, descr++); + get_user(offset, descr++); + get_user(data, descr++); + } + kfree(tmp); + sx_nports += sx_init_board(board); + rc = sx_nports; + break; + case SXIO_INIT: + if (sx_initialized) { /* Already initialized */ + rc = -EEXIST; + break; + } + /* This is not allowed until all boards are initialized... */ + for (i = 0; i < SX_NBOARDS; i++) { + if ((boards[i].flags & SX_BOARD_PRESENT) && + !(boards[i].flags & SX_BOARD_INITIALIZED)) { + rc = -EIO; + break; + } + } + for (i = 0; i < SX_NBOARDS; i++) + if (!(boards[i].flags & SX_BOARD_PRESENT)) + break; + + sx_dprintk(SX_DEBUG_FIRMWARE, "initing portstructs, %d boards, " + "%d channels, first board: %d ports\n", + i, sx_nports, boards[0].nports); + rc = sx_init_portstructs(i, sx_nports); + sx_init_drivers(); + if (rc >= 0) + sx_initialized++; + break; + case SXIO_SETDEBUG: + sx_debug = arg; + break; + case SXIO_GETDEBUG: + rc = sx_debug; + break; + case SXIO_GETGSDEBUG: + case SXIO_SETGSDEBUG: + rc = -EINVAL; + break; + case SXIO_GETNPORTS: + rc = sx_nports; + break; + default: + rc = -ENOTTY; + break; + } +out: + tty_unlock(); + func_exit(); + return rc; +} + +static int sx_break(struct tty_struct *tty, int flag) +{ + struct sx_port *port = tty->driver_data; + int rv; + + func_enter(); + tty_lock(); + + if (flag) + rv = sx_send_command(port, HS_START, -1, HS_IDLE_BREAK); + else + rv = sx_send_command(port, HS_STOP, -1, HS_IDLE_OPEN); + if (rv != 1) + printk(KERN_ERR "sx: couldn't send break (%x).\n", + read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat))); + tty_unlock(); + func_exit(); + return 0; +} + +static int sx_tiocmget(struct tty_struct *tty) +{ + struct sx_port *port = tty->driver_data; + return sx_getsignals(port); +} + +static int sx_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + struct sx_port *port = tty->driver_data; + int rts = -1, dtr = -1; + + if (set & TIOCM_RTS) + rts = 1; + if (set & TIOCM_DTR) + dtr = 1; + if (clear & TIOCM_RTS) + rts = 0; + if (clear & TIOCM_DTR) + dtr = 0; + + sx_setsignals(port, dtr, rts); + sx_reconfigure_port(port); + return 0; +} + +static int sx_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + int rc; + struct sx_port *port = tty->driver_data; + void __user *argp = (void __user *)arg; + + /* func_enter2(); */ + + rc = 0; + tty_lock(); + switch (cmd) { + case TIOCGSERIAL: + rc = gs_getserial(&port->gs, argp); + break; + case TIOCSSERIAL: + rc = gs_setserial(&port->gs, argp); + break; + default: + rc = -ENOIOCTLCMD; + break; + } + tty_unlock(); + + /* func_exit(); */ + return rc; +} + +/* The throttle/unthrottle scheme for the Specialix card is different + * from other drivers and deserves some explanation. + * The Specialix hardware takes care of XON/XOFF + * and CTS/RTS flow control itself. This means that all we have to + * do when signalled by the upper tty layer to throttle/unthrottle is + * to make a note of it here. When we come to read characters from the + * rx buffers on the card (sx_receive_chars()) we look to see if the + * upper layer can accept more (as noted here in sx_rx_throt[]). + * If it can't we simply don't remove chars from the cards buffer. + * When the tty layer can accept chars, we again note that here and when + * sx_receive_chars() is called it will remove them from the cards buffer. + * The card will notice that a ports buffer has drained below some low + * water mark and will unflow control the line itself, using whatever + * flow control scheme is in use for that port. -- Simon Allen + */ + +static void sx_throttle(struct tty_struct *tty) +{ + struct sx_port *port = tty->driver_data; + + func_enter2(); + /* If the port is using any type of input flow + * control then throttle the port. + */ + if ((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty))) { + port->gs.port.flags |= SX_RX_THROTTLE; + } + func_exit(); +} + +static void sx_unthrottle(struct tty_struct *tty) +{ + struct sx_port *port = tty->driver_data; + + func_enter2(); + /* Always unthrottle even if flow control is not enabled on + * this port in case we disabled flow control while the port + * was throttled + */ + port->gs.port.flags &= ~SX_RX_THROTTLE; + func_exit(); + return; +} + +/* ********************************************************************** * + * Here are the initialization routines. * + * ********************************************************************** */ + +static int sx_init_board(struct sx_board *board) +{ + int addr; + int chans; + int type; + + func_enter(); + + /* This is preceded by downloading the download code. */ + + board->flags |= SX_BOARD_INITIALIZED; + + if (read_sx_byte(board, 0)) + /* CF boards may need this. */ + write_sx_byte(board, 0, 0); + + /* This resets the processor again, to make sure it didn't do any + foolish things while we were downloading the image */ + if (!sx_reset(board)) + return 0; + + sx_start_board(board); + udelay(10); + if (!sx_busy_wait_neq(board, 0, 0xff, 0)) { + printk(KERN_ERR "sx: Ooops. Board won't initialize.\n"); + return 0; + } + + /* Ok. So now the processor on the card is running. It gathered + some info for us... */ + sx_dprintk(SX_DEBUG_INIT, "The sxcard structure:\n"); + if (sx_debug & SX_DEBUG_INIT) + my_hd_io(board->base, 0x10); + sx_dprintk(SX_DEBUG_INIT, "the first sx_module structure:\n"); + if (sx_debug & SX_DEBUG_INIT) + my_hd_io(board->base + 0x80, 0x30); + + sx_dprintk(SX_DEBUG_INIT, "init_status: %x, %dk memory, firmware " + "V%x.%02x,\n", + read_sx_byte(board, 0), read_sx_byte(board, 1), + read_sx_byte(board, 5), read_sx_byte(board, 4)); + + if (read_sx_byte(board, 0) == 0xff) { + printk(KERN_INFO "sx: No modules found. Sorry.\n"); + board->nports = 0; + return 0; + } + + chans = 0; + + if (IS_SX_BOARD(board)) { + sx_write_board_word(board, cc_int_count, sx_maxints); + } else { + if (sx_maxints) + sx_write_board_word(board, cc_int_count, + SI_PROCESSOR_CLOCK / 8 / sx_maxints); + } + + /* grab the first module type... */ + /* board->ta_type = mod_compat_type (read_sx_byte (board, 0x80 + 0x08)); */ + board->ta_type = mod_compat_type(sx_read_module_byte(board, 0x80, + mc_chip)); + + /* XXX byteorder */ + for (addr = 0x80; addr != 0; addr = read_sx_word(board, addr) & 0x7fff){ + type = sx_read_module_byte(board, addr, mc_chip); + sx_dprintk(SX_DEBUG_INIT, "Module at %x: %d channels\n", + addr, read_sx_byte(board, addr + 2)); + + chans += sx_read_module_byte(board, addr, mc_type); + + sx_dprintk(SX_DEBUG_INIT, "module is an %s, which has %s/%s " + "panels\n", + mod_type_s(type), + pan_type_s(sx_read_module_byte(board, addr, + mc_mods) & 0xf), + pan_type_s(sx_read_module_byte(board, addr, + mc_mods) >> 4)); + + sx_dprintk(SX_DEBUG_INIT, "CD1400 versions: %x/%x, ASIC " + "version: %x\n", + sx_read_module_byte(board, addr, mc_rev1), + sx_read_module_byte(board, addr, mc_rev2), + sx_read_module_byte(board, addr, mc_mtaasic_rev)); + + /* The following combinations are illegal: It should theoretically + work, but timing problems make the bus HANG. */ + + if (mod_compat_type(type) != board->ta_type) { + printk(KERN_ERR "sx: This is an invalid " + "configuration.\nDon't mix TA/MTA/SXDC on the " + "same hostadapter.\n"); + chans = 0; + break; + } + if ((IS_EISA_BOARD(board) || + IS_SI_BOARD(board)) && + (mod_compat_type(type) == 4)) { + printk(KERN_ERR "sx: This is an invalid " + "configuration.\nDon't use SXDCs on an SI/XIO " + "adapter.\n"); + chans = 0; + break; + } +#if 0 /* Problem fixed: firmware 3.05 */ + if (IS_SX_BOARD(board) && (type == TA8)) { + /* There are some issues with the firmware and the DCD/RTS + lines. It might work if you tie them together or something. + It might also work if you get a newer sx_firmware. Therefore + this is just a warning. */ + printk(KERN_WARNING + "sx: The SX host doesn't work too well " + "with the TA8 adapters.\nSpecialix is working on it.\n"); + } +#endif + } + + if (chans) { + if (board->irq > 0) { + /* fixed irq, probably PCI */ + if (sx_irqmask & (1 << board->irq)) { /* may we use this irq? */ + if (request_irq(board->irq, sx_interrupt, + IRQF_SHARED | IRQF_DISABLED, + "sx", board)) { + printk(KERN_ERR "sx: Cannot allocate " + "irq %d.\n", board->irq); + board->irq = 0; + } + } else + board->irq = 0; + } else if (board->irq < 0 && sx_irqmask) { + /* auto-allocate irq */ + int irqnr; + int irqmask = sx_irqmask & (IS_SX_BOARD(board) ? + SX_ISA_IRQ_MASK : SI2_ISA_IRQ_MASK); + for (irqnr = 15; irqnr > 0; irqnr--) + if (irqmask & (1 << irqnr)) + if (!request_irq(irqnr, sx_interrupt, + IRQF_SHARED | IRQF_DISABLED, + "sx", board)) + break; + if (!irqnr) + printk(KERN_ERR "sx: Cannot allocate IRQ.\n"); + board->irq = irqnr; + } else + board->irq = 0; + + if (board->irq) { + /* Found a valid interrupt, start up interrupts! */ + sx_dprintk(SX_DEBUG_INIT, "Using irq %d.\n", + board->irq); + sx_start_interrupts(board); + board->poll = sx_slowpoll; + board->flags |= SX_IRQ_ALLOCATED; + } else { + /* no irq: setup board for polled operation */ + board->poll = sx_poll; + sx_dprintk(SX_DEBUG_INIT, "Using poll-interval %d.\n", + board->poll); + } + + /* The timer should be initialized anyway: That way we can + safely del_timer it when the module is unloaded. */ + setup_timer(&board->timer, sx_pollfunc, (unsigned long)board); + + if (board->poll) + mod_timer(&board->timer, jiffies + board->poll); + } else { + board->irq = 0; + } + + board->nports = chans; + sx_dprintk(SX_DEBUG_INIT, "returning %d ports.", board->nports); + + func_exit(); + return chans; +} + +static void __devinit printheader(void) +{ + static int header_printed; + + if (!header_printed) { + printk(KERN_INFO "Specialix SX driver " + "(C) 1998/1999 R.E.Wolff@BitWizard.nl\n"); + printk(KERN_INFO "sx: version " __stringify(SX_VERSION) "\n"); + header_printed = 1; + } +} + +static int __devinit probe_sx(struct sx_board *board) +{ + struct vpd_prom vpdp; + char *p; + int i; + + func_enter(); + + if (!IS_CF_BOARD(board)) { + sx_dprintk(SX_DEBUG_PROBE, "Going to verify vpd prom at %p.\n", + board->base + SX_VPD_ROM); + + if (sx_debug & SX_DEBUG_PROBE) + my_hd_io(board->base + SX_VPD_ROM, 0x40); + + p = (char *)&vpdp; + for (i = 0; i < sizeof(struct vpd_prom); i++) + *p++ = read_sx_byte(board, SX_VPD_ROM + i * 2); + + if (sx_debug & SX_DEBUG_PROBE) + my_hd(&vpdp, 0x20); + + sx_dprintk(SX_DEBUG_PROBE, "checking identifier...\n"); + + if (strncmp(vpdp.identifier, SX_VPD_IDENT_STRING, 16) != 0) { + sx_dprintk(SX_DEBUG_PROBE, "Got non-SX identifier: " + "'%s'\n", vpdp.identifier); + return 0; + } + } + + printheader(); + + if (!IS_CF_BOARD(board)) { + printk(KERN_DEBUG "sx: Found an SX board at %lx\n", + board->hw_base); + printk(KERN_DEBUG "sx: hw_rev: %d, assembly level: %d, " + "uniq ID:%08x, ", + vpdp.hwrev, vpdp.hwass, vpdp.uniqid); + printk("Manufactured: %d/%d\n", 1970 + vpdp.myear, vpdp.mweek); + + if ((((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) != + SX_PCI_UNIQUEID1) && (((vpdp.uniqid >> 24) & + SX_UNIQUEID_MASK) != SX_ISA_UNIQUEID1)) { + /* This might be a bit harsh. This was the primary + reason the SX/ISA card didn't work at first... */ + printk(KERN_ERR "sx: Hmm. Not an SX/PCI or SX/ISA " + "card. Sorry: giving up.\n"); + return (0); + } + + if (((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) == + SX_ISA_UNIQUEID1) { + if (((unsigned long)board->hw_base) & 0x8000) { + printk(KERN_WARNING "sx: Warning: There may be " + "hardware problems with the card at " + "%lx.\n", board->hw_base); + printk(KERN_WARNING "sx: Read sx.txt for more " + "info.\n"); + } + } + } + + board->nports = -1; + + /* This resets the processor, and keeps it off the bus. */ + if (!sx_reset(board)) + return 0; + sx_dprintk(SX_DEBUG_INIT, "reset the board...\n"); + + func_exit(); + return 1; +} + +#if defined(CONFIG_ISA) || defined(CONFIG_EISA) + +/* Specialix probes for this card at 32k increments from 640k to 16M. + I consider machines with less than 16M unlikely nowadays, so I'm + not probing above 1Mb. Also, 0xa0000, 0xb0000, are taken by the VGA + card. 0xe0000 and 0xf0000 are taken by the BIOS. That only leaves + 0xc0000, 0xc8000, 0xd0000 and 0xd8000 . */ + +static int __devinit probe_si(struct sx_board *board) +{ + int i; + + func_enter(); + sx_dprintk(SX_DEBUG_PROBE, "Going to verify SI signature hw %lx at " + "%p.\n", board->hw_base, board->base + SI2_ISA_ID_BASE); + + if (sx_debug & SX_DEBUG_PROBE) + my_hd_io(board->base + SI2_ISA_ID_BASE, 0x8); + + if (!IS_EISA_BOARD(board)) { + if (IS_SI1_BOARD(board)) { + for (i = 0; i < 8; i++) { + write_sx_byte(board, SI2_ISA_ID_BASE + 7 - i,i); + } + } + for (i = 0; i < 8; i++) { + if ((read_sx_byte(board, SI2_ISA_ID_BASE + 7 - i) & 7) + != i) { + func_exit(); + return 0; + } + } + } + + /* Now we're pretty much convinced that there is an SI board here, + but to prevent trouble, we'd better double check that we don't + have an SI1 board when we're probing for an SI2 board.... */ + + write_sx_byte(board, SI2_ISA_ID_BASE, 0x10); + if (IS_SI1_BOARD(board)) { + /* This should be an SI1 board, which has this + location writable... */ + if (read_sx_byte(board, SI2_ISA_ID_BASE) != 0x10) { + func_exit(); + return 0; + } + } else { + /* This should be an SI2 board, which has the bottom + 3 bits non-writable... */ + if (read_sx_byte(board, SI2_ISA_ID_BASE) == 0x10) { + func_exit(); + return 0; + } + } + + /* Now we're pretty much convinced that there is an SI board here, + but to prevent trouble, we'd better double check that we don't + have an SI1 board when we're probing for an SI2 board.... */ + + write_sx_byte(board, SI2_ISA_ID_BASE, 0x10); + if (IS_SI1_BOARD(board)) { + /* This should be an SI1 board, which has this + location writable... */ + if (read_sx_byte(board, SI2_ISA_ID_BASE) != 0x10) { + func_exit(); + return 0; + } + } else { + /* This should be an SI2 board, which has the bottom + 3 bits non-writable... */ + if (read_sx_byte(board, SI2_ISA_ID_BASE) == 0x10) { + func_exit(); + return 0; + } + } + + printheader(); + + printk(KERN_DEBUG "sx: Found an SI board at %lx\n", board->hw_base); + /* Compared to the SX boards, it is a complete guess as to what + this card is up to... */ + + board->nports = -1; + + /* This resets the processor, and keeps it off the bus. */ + if (!sx_reset(board)) + return 0; + sx_dprintk(SX_DEBUG_INIT, "reset the board...\n"); + + func_exit(); + return 1; +} +#endif + +static const struct tty_operations sx_ops = { + .break_ctl = sx_break, + .open = sx_open, + .close = gs_close, + .write = gs_write, + .put_char = gs_put_char, + .flush_chars = gs_flush_chars, + .write_room = gs_write_room, + .chars_in_buffer = gs_chars_in_buffer, + .flush_buffer = gs_flush_buffer, + .ioctl = sx_ioctl, + .throttle = sx_throttle, + .unthrottle = sx_unthrottle, + .set_termios = gs_set_termios, + .stop = gs_stop, + .start = gs_start, + .hangup = gs_hangup, + .tiocmget = sx_tiocmget, + .tiocmset = sx_tiocmset, +}; + +static const struct tty_port_operations sx_port_ops = { + .carrier_raised = sx_carrier_raised, +}; + +static int sx_init_drivers(void) +{ + int error; + + func_enter(); + + sx_driver = alloc_tty_driver(sx_nports); + if (!sx_driver) + return 1; + sx_driver->owner = THIS_MODULE; + sx_driver->driver_name = "specialix_sx"; + sx_driver->name = "ttyX"; + sx_driver->major = SX_NORMAL_MAJOR; + sx_driver->type = TTY_DRIVER_TYPE_SERIAL; + sx_driver->subtype = SERIAL_TYPE_NORMAL; + sx_driver->init_termios = tty_std_termios; + sx_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + sx_driver->init_termios.c_ispeed = 9600; + sx_driver->init_termios.c_ospeed = 9600; + sx_driver->flags = TTY_DRIVER_REAL_RAW; + tty_set_operations(sx_driver, &sx_ops); + + if ((error = tty_register_driver(sx_driver))) { + put_tty_driver(sx_driver); + printk(KERN_ERR "sx: Couldn't register sx driver, error = %d\n", + error); + return 1; + } + func_exit(); + return 0; +} + +static int sx_init_portstructs(int nboards, int nports) +{ + struct sx_board *board; + struct sx_port *port; + int i, j; + int addr, chans; + int portno; + + func_enter(); + + /* Many drivers statically allocate the maximum number of ports + There is no reason not to allocate them dynamically. + Is there? -- REW */ + sx_ports = kcalloc(nports, sizeof(struct sx_port), GFP_KERNEL); + if (!sx_ports) + return -ENOMEM; + + port = sx_ports; + for (i = 0; i < nboards; i++) { + board = &boards[i]; + board->ports = port; + for (j = 0; j < boards[i].nports; j++) { + sx_dprintk(SX_DEBUG_INIT, "initing port %d\n", j); + tty_port_init(&port->gs.port); + port->gs.port.ops = &sx_port_ops; + port->gs.magic = SX_MAGIC; + port->gs.close_delay = HZ / 2; + port->gs.closing_wait = 30 * HZ; + port->board = board; + port->gs.rd = &sx_real_driver; +#ifdef NEW_WRITE_LOCKING + port->gs.port_write_mutex = MUTEX; +#endif + spin_lock_init(&port->gs.driver_lock); + /* + * Initializing wait queue + */ + port++; + } + } + + port = sx_ports; + portno = 0; + for (i = 0; i < nboards; i++) { + board = &boards[i]; + board->port_base = portno; + /* Possibly the configuration was rejected. */ + sx_dprintk(SX_DEBUG_PROBE, "Board has %d channels\n", + board->nports); + if (board->nports <= 0) + continue; + /* XXX byteorder ?? */ + for (addr = 0x80; addr != 0; + addr = read_sx_word(board, addr) & 0x7fff) { + chans = sx_read_module_byte(board, addr, mc_type); + sx_dprintk(SX_DEBUG_PROBE, "Module at %x: %d " + "channels\n", addr, chans); + sx_dprintk(SX_DEBUG_PROBE, "Port at"); + for (j = 0; j < chans; j++) { + /* The "sx-way" is the way it SHOULD be done. + That way in the future, the firmware may for + example pack the structures a bit more + efficient. Neil tells me it isn't going to + happen anytime soon though. */ + if (IS_SX_BOARD(board)) + port->ch_base = sx_read_module_word( + board, addr + j * 2, + mc_chan_pointer); + else + port->ch_base = addr + 0x100 + 0x300 *j; + + sx_dprintk(SX_DEBUG_PROBE, " %x", + port->ch_base); + port->line = portno++; + port++; + } + sx_dprintk(SX_DEBUG_PROBE, "\n"); + } + /* This has to be done earlier. */ + /* board->flags |= SX_BOARD_INITIALIZED; */ + } + + func_exit(); + return 0; +} + +static unsigned int sx_find_free_board(void) +{ + unsigned int i; + + for (i = 0; i < SX_NBOARDS; i++) + if (!(boards[i].flags & SX_BOARD_PRESENT)) + break; + + return i; +} + +static void __exit sx_release_drivers(void) +{ + func_enter(); + tty_unregister_driver(sx_driver); + put_tty_driver(sx_driver); + func_exit(); +} + +static void __devexit sx_remove_card(struct sx_board *board, + struct pci_dev *pdev) +{ + if (board->flags & SX_BOARD_INITIALIZED) { + /* The board should stop messing with us. (actually I mean the + interrupt) */ + sx_reset(board); + if ((board->irq) && (board->flags & SX_IRQ_ALLOCATED)) + free_irq(board->irq, board); + + /* It is safe/allowed to del_timer a non-active timer */ + del_timer(&board->timer); + if (pdev) { +#ifdef CONFIG_PCI + iounmap(board->base2); + pci_release_region(pdev, IS_CF_BOARD(board) ? 3 : 2); +#endif + } else { + iounmap(board->base); + release_region(board->hw_base, board->hw_len); + } + + board->flags &= ~(SX_BOARD_INITIALIZED | SX_BOARD_PRESENT); + } +} + +#ifdef CONFIG_EISA + +static int __devinit sx_eisa_probe(struct device *dev) +{ + struct eisa_device *edev = to_eisa_device(dev); + struct sx_board *board; + unsigned long eisa_slot = edev->base_addr; + unsigned int i; + int retval = -EIO; + + mutex_lock(&sx_boards_lock); + i = sx_find_free_board(); + if (i == SX_NBOARDS) { + mutex_unlock(&sx_boards_lock); + goto err; + } + board = &boards[i]; + board->flags |= SX_BOARD_PRESENT; + mutex_unlock(&sx_boards_lock); + + dev_info(dev, "XIO : Signature found in EISA slot %lu, " + "Product %d Rev %d (REPORT THIS TO LKLM)\n", + eisa_slot >> 12, + inb(eisa_slot + EISA_VENDOR_ID_OFFSET + 2), + inb(eisa_slot + EISA_VENDOR_ID_OFFSET + 3)); + + board->eisa_base = eisa_slot; + board->flags &= ~SX_BOARD_TYPE; + board->flags |= SI_EISA_BOARD; + + board->hw_base = ((inb(eisa_slot + 0xc01) << 8) + + inb(eisa_slot + 0xc00)) << 16; + board->hw_len = SI2_EISA_WINDOW_LEN; + if (!request_region(board->hw_base, board->hw_len, "sx")) { + dev_err(dev, "can't request region\n"); + goto err_flag; + } + board->base2 = + board->base = ioremap_nocache(board->hw_base, SI2_EISA_WINDOW_LEN); + if (!board->base) { + dev_err(dev, "can't remap memory\n"); + goto err_reg; + } + + sx_dprintk(SX_DEBUG_PROBE, "IO hw_base address: %lx\n", board->hw_base); + sx_dprintk(SX_DEBUG_PROBE, "base: %p\n", board->base); + board->irq = inb(eisa_slot + 0xc02) >> 4; + sx_dprintk(SX_DEBUG_PROBE, "IRQ: %d\n", board->irq); + + if (!probe_si(board)) + goto err_unmap; + + dev_set_drvdata(dev, board); + + return 0; +err_unmap: + iounmap(board->base); +err_reg: + release_region(board->hw_base, board->hw_len); +err_flag: + board->flags &= ~SX_BOARD_PRESENT; +err: + return retval; +} + +static int __devexit sx_eisa_remove(struct device *dev) +{ + struct sx_board *board = dev_get_drvdata(dev); + + sx_remove_card(board, NULL); + + return 0; +} + +static struct eisa_device_id sx_eisa_tbl[] = { + { "SLX" }, + { "" } +}; + +MODULE_DEVICE_TABLE(eisa, sx_eisa_tbl); + +static struct eisa_driver sx_eisadriver = { + .id_table = sx_eisa_tbl, + .driver = { + .name = "sx", + .probe = sx_eisa_probe, + .remove = __devexit_p(sx_eisa_remove), + } +}; + +#endif + +#ifdef CONFIG_PCI + /******************************************************** + * Setting bit 17 in the CNTRL register of the PLX 9050 * + * chip forces a retry on writes while a read is pending.* + * This is to prevent the card locking up on Intel Xeon * + * multiprocessor systems with the NX chipset. -- NV * + ********************************************************/ + +/* Newer cards are produced with this bit set from the configuration + EEprom. As the bit is read/write for the CPU, we can fix it here, + if we detect that it isn't set correctly. -- REW */ + +static void __devinit fix_sx_pci(struct pci_dev *pdev, struct sx_board *board) +{ + unsigned int hwbase; + void __iomem *rebase; + unsigned int t; + +#define CNTRL_REG_OFFSET 0x50 +#define CNTRL_REG_GOODVALUE 0x18260000 + + pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase); + hwbase &= PCI_BASE_ADDRESS_MEM_MASK; + rebase = ioremap_nocache(hwbase, 0x80); + t = readl(rebase + CNTRL_REG_OFFSET); + if (t != CNTRL_REG_GOODVALUE) { + printk(KERN_DEBUG "sx: performing cntrl reg fix: %08x -> " + "%08x\n", t, CNTRL_REG_GOODVALUE); + writel(CNTRL_REG_GOODVALUE, rebase + CNTRL_REG_OFFSET); + } + iounmap(rebase); +} +#endif + +static int __devinit sx_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ +#ifdef CONFIG_PCI + struct sx_board *board; + unsigned int i, reg; + int retval = -EIO; + + mutex_lock(&sx_boards_lock); + i = sx_find_free_board(); + if (i == SX_NBOARDS) { + mutex_unlock(&sx_boards_lock); + goto err; + } + board = &boards[i]; + board->flags |= SX_BOARD_PRESENT; + mutex_unlock(&sx_boards_lock); + + retval = pci_enable_device(pdev); + if (retval) + goto err_flag; + + board->flags &= ~SX_BOARD_TYPE; + board->flags |= (pdev->subsystem_vendor == 0x200) ? SX_PCI_BOARD : + SX_CFPCI_BOARD; + + /* CF boards use base address 3.... */ + reg = IS_CF_BOARD(board) ? 3 : 2; + retval = pci_request_region(pdev, reg, "sx"); + if (retval) { + dev_err(&pdev->dev, "can't request region\n"); + goto err_flag; + } + board->hw_base = pci_resource_start(pdev, reg); + board->base2 = + board->base = ioremap_nocache(board->hw_base, WINDOW_LEN(board)); + if (!board->base) { + dev_err(&pdev->dev, "ioremap failed\n"); + goto err_reg; + } + + /* Most of the stuff on the CF board is offset by 0x18000 .... */ + if (IS_CF_BOARD(board)) + board->base += 0x18000; + + board->irq = pdev->irq; + + dev_info(&pdev->dev, "Got a specialix card: %p(%d) %x.\n", board->base, + board->irq, board->flags); + + if (!probe_sx(board)) { + retval = -EIO; + goto err_unmap; + } + + fix_sx_pci(pdev, board); + + pci_set_drvdata(pdev, board); + + return 0; +err_unmap: + iounmap(board->base2); +err_reg: + pci_release_region(pdev, reg); +err_flag: + board->flags &= ~SX_BOARD_PRESENT; +err: + return retval; +#else + return -ENODEV; +#endif +} + +static void __devexit sx_pci_remove(struct pci_dev *pdev) +{ + struct sx_board *board = pci_get_drvdata(pdev); + + sx_remove_card(board, pdev); +} + +/* Specialix has a whole bunch of cards with 0x2000 as the device ID. They say + its because the standard requires it. So check for SUBVENDOR_ID. */ +static struct pci_device_id sx_pci_tbl[] = { + { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, + .subvendor = PCI_ANY_ID, .subdevice = 0x0200 }, + { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, + .subvendor = PCI_ANY_ID, .subdevice = 0x0300 }, + { 0 } +}; + +MODULE_DEVICE_TABLE(pci, sx_pci_tbl); + +static struct pci_driver sx_pcidriver = { + .name = "sx", + .id_table = sx_pci_tbl, + .probe = sx_pci_probe, + .remove = __devexit_p(sx_pci_remove) +}; + +static int __init sx_init(void) +{ +#ifdef CONFIG_EISA + int retval1; +#endif +#ifdef CONFIG_ISA + struct sx_board *board; + unsigned int i; +#endif + unsigned int found = 0; + int retval; + + func_enter(); + sx_dprintk(SX_DEBUG_INIT, "Initing sx module... (sx_debug=%d)\n", + sx_debug); + if (abs((long)(&sx_debug) - sx_debug) < 0x10000) { + printk(KERN_WARNING "sx: sx_debug is an address, instead of a " + "value. Assuming -1.\n(%p)\n", &sx_debug); + sx_debug = -1; + } + + if (misc_register(&sx_fw_device) < 0) { + printk(KERN_ERR "SX: Unable to register firmware loader " + "driver.\n"); + return -EIO; + } +#ifdef CONFIG_ISA + for (i = 0; i < NR_SX_ADDRS; i++) { + board = &boards[found]; + board->hw_base = sx_probe_addrs[i]; + board->hw_len = SX_WINDOW_LEN; + if (!request_region(board->hw_base, board->hw_len, "sx")) + continue; + board->base2 = + board->base = ioremap_nocache(board->hw_base, board->hw_len); + if (!board->base) + goto err_sx_reg; + board->flags &= ~SX_BOARD_TYPE; + board->flags |= SX_ISA_BOARD; + board->irq = sx_irqmask ? -1 : 0; + + if (probe_sx(board)) { + board->flags |= SX_BOARD_PRESENT; + found++; + } else { + iounmap(board->base); +err_sx_reg: + release_region(board->hw_base, board->hw_len); + } + } + + for (i = 0; i < NR_SI_ADDRS; i++) { + board = &boards[found]; + board->hw_base = si_probe_addrs[i]; + board->hw_len = SI2_ISA_WINDOW_LEN; + if (!request_region(board->hw_base, board->hw_len, "sx")) + continue; + board->base2 = + board->base = ioremap_nocache(board->hw_base, board->hw_len); + if (!board->base) + goto err_si_reg; + board->flags &= ~SX_BOARD_TYPE; + board->flags |= SI_ISA_BOARD; + board->irq = sx_irqmask ? -1 : 0; + + if (probe_si(board)) { + board->flags |= SX_BOARD_PRESENT; + found++; + } else { + iounmap(board->base); +err_si_reg: + release_region(board->hw_base, board->hw_len); + } + } + for (i = 0; i < NR_SI1_ADDRS; i++) { + board = &boards[found]; + board->hw_base = si1_probe_addrs[i]; + board->hw_len = SI1_ISA_WINDOW_LEN; + if (!request_region(board->hw_base, board->hw_len, "sx")) + continue; + board->base2 = + board->base = ioremap_nocache(board->hw_base, board->hw_len); + if (!board->base) + goto err_si1_reg; + board->flags &= ~SX_BOARD_TYPE; + board->flags |= SI1_ISA_BOARD; + board->irq = sx_irqmask ? -1 : 0; + + if (probe_si(board)) { + board->flags |= SX_BOARD_PRESENT; + found++; + } else { + iounmap(board->base); +err_si1_reg: + release_region(board->hw_base, board->hw_len); + } + } +#endif +#ifdef CONFIG_EISA + retval1 = eisa_driver_register(&sx_eisadriver); +#endif + retval = pci_register_driver(&sx_pcidriver); + + if (found) { + printk(KERN_INFO "sx: total of %d boards detected.\n", found); + retval = 0; + } else if (retval) { +#ifdef CONFIG_EISA + retval = retval1; + if (retval1) +#endif + misc_deregister(&sx_fw_device); + } + + func_exit(); + return retval; +} + +static void __exit sx_exit(void) +{ + int i; + + func_enter(); +#ifdef CONFIG_EISA + eisa_driver_unregister(&sx_eisadriver); +#endif + pci_unregister_driver(&sx_pcidriver); + + for (i = 0; i < SX_NBOARDS; i++) + sx_remove_card(&boards[i], NULL); + + if (misc_deregister(&sx_fw_device) < 0) { + printk(KERN_INFO "sx: couldn't deregister firmware loader " + "device\n"); + } + sx_dprintk(SX_DEBUG_CLEANUP, "Cleaning up drivers (%d)\n", + sx_initialized); + if (sx_initialized) + sx_release_drivers(); + + kfree(sx_ports); + func_exit(); +} + +module_init(sx_init); +module_exit(sx_exit); diff --git a/drivers/staging/generic_serial/sx.h b/drivers/staging/generic_serial/sx.h new file mode 100644 index 000000000000..87c2defdead7 --- /dev/null +++ b/drivers/staging/generic_serial/sx.h @@ -0,0 +1,201 @@ + +/* + * sx.h + * + * Copyright (C) 1998/1999 R.E.Wolff@BitWizard.nl + * + * SX serial driver. + * -- Supports SI, XIO and SX host cards. + * -- Supports TAs, MTAs and SXDCs. + * + * Version 1.3 -- March, 1999. + * + */ + +#define SX_NBOARDS 4 +#define SX_PORTSPERBOARD 32 +#define SX_NPORTS (SX_NBOARDS * SX_PORTSPERBOARD) + +#ifdef __KERNEL__ + +#define SX_MAGIC 0x12345678 + +struct sx_port { + struct gs_port gs; + struct wait_queue *shutdown_wait; + int ch_base; + int c_dcd; + struct sx_board *board; + int line; + unsigned long locks; +}; + +struct sx_board { + int magic; + void __iomem *base; + void __iomem *base2; + unsigned long hw_base; + resource_size_t hw_len; + int eisa_base; + int port_base; /* Number of the first port */ + struct sx_port *ports; + int nports; + int flags; + int irq; + int poll; + int ta_type; + struct timer_list timer; + unsigned long locks; +}; + +struct vpd_prom { + unsigned short id; + char hwrev; + char hwass; + int uniqid; + char myear; + char mweek; + char hw_feature[5]; + char oem_id; + char identifier[16]; +}; + +#ifndef MOD_RS232DB25MALE +#define MOD_RS232DB25MALE 0x0a +#endif + +#define SI_ISA_BOARD 0x00000001 +#define SX_ISA_BOARD 0x00000002 +#define SX_PCI_BOARD 0x00000004 +#define SX_CFPCI_BOARD 0x00000008 +#define SX_CFISA_BOARD 0x00000010 +#define SI_EISA_BOARD 0x00000020 +#define SI1_ISA_BOARD 0x00000040 + +#define SX_BOARD_PRESENT 0x00001000 +#define SX_BOARD_INITIALIZED 0x00002000 +#define SX_IRQ_ALLOCATED 0x00004000 + +#define SX_BOARD_TYPE 0x000000ff + +#define IS_SX_BOARD(board) (board->flags & (SX_PCI_BOARD | SX_CFPCI_BOARD | \ + SX_ISA_BOARD | SX_CFISA_BOARD)) + +#define IS_SI_BOARD(board) (board->flags & SI_ISA_BOARD) +#define IS_SI1_BOARD(board) (board->flags & SI1_ISA_BOARD) + +#define IS_EISA_BOARD(board) (board->flags & SI_EISA_BOARD) + +#define IS_CF_BOARD(board) (board->flags & (SX_CFISA_BOARD | SX_CFPCI_BOARD)) + +/* The SI processor clock is required to calculate the cc_int_count register + value for the SI cards. */ +#define SI_PROCESSOR_CLOCK 25000000 + + +/* port flags */ +/* Make sure these don't clash with gs flags or async flags */ +#define SX_RX_THROTTLE 0x0000001 + + + +#define SX_PORT_TRANSMIT_LOCK 0 +#define SX_BOARD_INTR_LOCK 0 + + + +/* Debug flags. Add these together to get more debug info. */ + +#define SX_DEBUG_OPEN 0x00000001 +#define SX_DEBUG_SETTING 0x00000002 +#define SX_DEBUG_FLOW 0x00000004 +#define SX_DEBUG_MODEMSIGNALS 0x00000008 +#define SX_DEBUG_TERMIOS 0x00000010 +#define SX_DEBUG_TRANSMIT 0x00000020 +#define SX_DEBUG_RECEIVE 0x00000040 +#define SX_DEBUG_INTERRUPTS 0x00000080 +#define SX_DEBUG_PROBE 0x00000100 +#define SX_DEBUG_INIT 0x00000200 +#define SX_DEBUG_CLEANUP 0x00000400 +#define SX_DEBUG_CLOSE 0x00000800 +#define SX_DEBUG_FIRMWARE 0x00001000 +#define SX_DEBUG_MEMTEST 0x00002000 + +#define SX_DEBUG_ALL 0xffffffff + + +#define O_OTHER(tty) \ + ((O_OLCUC(tty)) ||\ + (O_ONLCR(tty)) ||\ + (O_OCRNL(tty)) ||\ + (O_ONOCR(tty)) ||\ + (O_ONLRET(tty)) ||\ + (O_OFILL(tty)) ||\ + (O_OFDEL(tty)) ||\ + (O_NLDLY(tty)) ||\ + (O_CRDLY(tty)) ||\ + (O_TABDLY(tty)) ||\ + (O_BSDLY(tty)) ||\ + (O_VTDLY(tty)) ||\ + (O_FFDLY(tty))) + +/* Same for input. */ +#define I_OTHER(tty) \ + ((I_INLCR(tty)) ||\ + (I_IGNCR(tty)) ||\ + (I_ICRNL(tty)) ||\ + (I_IUCLC(tty)) ||\ + (L_ISIG(tty))) + +#define MOD_TA ( TA>>4) +#define MOD_MTA (MTA_CD1400>>4) +#define MOD_SXDC ( SXDC>>4) + + +/* We copy the download code over to the card in chunks of ... bytes */ +#define SX_CHUNK_SIZE 128 + +#endif /* __KERNEL__ */ + + + +/* Specialix document 6210046-11 page 3 */ +#define SPX(X) (('S'<<24) | ('P' << 16) | (X)) + +/* Specialix-Linux specific IOCTLS. */ +#define SPXL(X) (SPX(('L' << 8) | (X))) + + +#define SXIO_SET_BOARD SPXL(0x01) +#define SXIO_GET_TYPE SPXL(0x02) +#define SXIO_DOWNLOAD SPXL(0x03) +#define SXIO_INIT SPXL(0x04) +#define SXIO_SETDEBUG SPXL(0x05) +#define SXIO_GETDEBUG SPXL(0x06) +#define SXIO_DO_RAMTEST SPXL(0x07) +#define SXIO_SETGSDEBUG SPXL(0x08) +#define SXIO_GETGSDEBUG SPXL(0x09) +#define SXIO_GETNPORTS SPXL(0x0a) + + +#ifndef SXCTL_MISC_MINOR +/* Allow others to gather this into "major.h" or something like that */ +#define SXCTL_MISC_MINOR 167 +#endif + +#ifndef SX_NORMAL_MAJOR +/* This allows overriding on the compiler commandline, or in a "major.h" + include or something like that */ +#define SX_NORMAL_MAJOR 32 +#define SX_CALLOUT_MAJOR 33 +#endif + + +#define SX_TYPE_SX 0x01 +#define SX_TYPE_SI 0x02 +#define SX_TYPE_CF 0x03 + + +#define WINDOW_LEN(board) (IS_CF_BOARD(board)?0x20000:SX_WINDOW_LEN) +/* Need a #define for ^^^^^^^ !!! */ + diff --git a/drivers/staging/generic_serial/sxboards.h b/drivers/staging/generic_serial/sxboards.h new file mode 100644 index 000000000000..427927dc7dbf --- /dev/null +++ b/drivers/staging/generic_serial/sxboards.h @@ -0,0 +1,206 @@ +/************************************************************************/ +/* */ +/* Title : SX/SI/XIO Board Hardware Definitions */ +/* */ +/* Author : N.P.Vassallo */ +/* */ +/* Creation : 16th March 1998 */ +/* */ +/* Version : 3.0.0 */ +/* */ +/* Copyright : (c) Specialix International Ltd. 1998 */ +/* */ +/* Description : Prototypes, structures and definitions */ +/* describing the SX/SI/XIO board hardware */ +/* */ +/************************************************************************/ + +/* History... + +3.0.0 16/03/98 NPV Creation. + +*/ + +#ifndef _sxboards_h /* If SXBOARDS.H not already defined */ +#define _sxboards_h 1 + +/***************************************************************************** +******************************* ****************************** +******************************* Board Types ****************************** +******************************* ****************************** +*****************************************************************************/ + +/* BUS types... */ +#define BUS_ISA 0 +#define BUS_MCA 1 +#define BUS_EISA 2 +#define BUS_PCI 3 + +/* Board phases... */ +#define SI1_Z280 1 +#define SI2_Z280 2 +#define SI3_T225 3 + +/* Board types... */ +#define CARD_TYPE(bus,phase) (bus<<4|phase) +#define CARD_BUS(type) ((type>>4)&0xF) +#define CARD_PHASE(type) (type&0xF) + +#define TYPE_SI1_ISA CARD_TYPE(BUS_ISA,SI1_Z280) +#define TYPE_SI2_ISA CARD_TYPE(BUS_ISA,SI2_Z280) +#define TYPE_SI2_EISA CARD_TYPE(BUS_EISA,SI2_Z280) +#define TYPE_SI2_PCI CARD_TYPE(BUS_PCI,SI2_Z280) + +#define TYPE_SX_ISA CARD_TYPE(BUS_ISA,SI3_T225) +#define TYPE_SX_PCI CARD_TYPE(BUS_PCI,SI3_T225) +/***************************************************************************** +****************************** ****************************** +****************************** Phase 1 Z280 ****************************** +****************************** ****************************** +*****************************************************************************/ + +/* ISA board details... */ +#define SI1_ISA_WINDOW_LEN 0x10000 /* 64 Kbyte shared memory window */ +//#define SI1_ISA_MEMORY_LEN 0x8000 /* Usable memory - unused define*/ +//#define SI1_ISA_ADDR_LOW 0x0A0000 /* Lowest address = 640 Kbyte */ +//#define SI1_ISA_ADDR_HIGH 0xFF8000 /* Highest address = 16Mbyte - 32Kbyte */ +//#define SI2_ISA_ADDR_STEP SI2_ISA_WINDOW_LEN/* ISA board address step */ +//#define SI2_ISA_IRQ_MASK 0x9800 /* IRQs 15,12,11 */ + +/* ISA board, register definitions... */ +//#define SI2_ISA_ID_BASE 0x7FF8 /* READ: Board ID string */ +#define SI1_ISA_RESET 0x8000 /* WRITE: Host Reset */ +#define SI1_ISA_RESET_CLEAR 0xc000 /* WRITE: Host Reset clear*/ +#define SI1_ISA_WAIT 0x9000 /* WRITE: Host wait */ +#define SI1_ISA_WAIT_CLEAR 0xd000 /* WRITE: Host wait clear */ +#define SI1_ISA_INTCL 0xa000 /* WRITE: Host Reset */ +#define SI1_ISA_INTCL_CLEAR 0xe000 /* WRITE: Host Reset */ + + +/***************************************************************************** +****************************** ****************************** +****************************** Phase 2 Z280 ****************************** +****************************** ****************************** +*****************************************************************************/ + +/* ISA board details... */ +#define SI2_ISA_WINDOW_LEN 0x8000 /* 32 Kbyte shared memory window */ +#define SI2_ISA_MEMORY_LEN 0x7FF8 /* Usable memory */ +#define SI2_ISA_ADDR_LOW 0x0A0000 /* Lowest address = 640 Kbyte */ +#define SI2_ISA_ADDR_HIGH 0xFF8000 /* Highest address = 16Mbyte - 32Kbyte */ +#define SI2_ISA_ADDR_STEP SI2_ISA_WINDOW_LEN/* ISA board address step */ +#define SI2_ISA_IRQ_MASK 0x9800 /* IRQs 15,12,11 */ + +/* ISA board, register definitions... */ +#define SI2_ISA_ID_BASE 0x7FF8 /* READ: Board ID string */ +#define SI2_ISA_RESET SI2_ISA_ID_BASE /* WRITE: Host Reset */ +#define SI2_ISA_IRQ11 (SI2_ISA_ID_BASE+1) /* WRITE: Set IRQ11 */ +#define SI2_ISA_IRQ12 (SI2_ISA_ID_BASE+2) /* WRITE: Set IRQ12 */ +#define SI2_ISA_IRQ15 (SI2_ISA_ID_BASE+3) /* WRITE: Set IRQ15 */ +#define SI2_ISA_IRQSET (SI2_ISA_ID_BASE+4) /* WRITE: Set Host Interrupt */ +#define SI2_ISA_INTCLEAR (SI2_ISA_ID_BASE+5) /* WRITE: Enable Host Interrupt */ + +#define SI2_ISA_IRQ11_SET 0x10 +#define SI2_ISA_IRQ11_CLEAR 0x00 +#define SI2_ISA_IRQ12_SET 0x10 +#define SI2_ISA_IRQ12_CLEAR 0x00 +#define SI2_ISA_IRQ15_SET 0x10 +#define SI2_ISA_IRQ15_CLEAR 0x00 +#define SI2_ISA_INTCLEAR_SET 0x10 +#define SI2_ISA_INTCLEAR_CLEAR 0x00 +#define SI2_ISA_IRQSET_CLEAR 0x10 +#define SI2_ISA_IRQSET_SET 0x00 +#define SI2_ISA_RESET_SET 0x00 +#define SI2_ISA_RESET_CLEAR 0x10 + +/* PCI board details... */ +#define SI2_PCI_WINDOW_LEN 0x100000 /* 1 Mbyte memory window */ + +/* PCI board register definitions... */ +#define SI2_PCI_SET_IRQ 0x40001 /* Set Host Interrupt */ +#define SI2_PCI_RESET 0xC0001 /* Host Reset */ + +/***************************************************************************** +****************************** ****************************** +****************************** Phase 3 T225 ****************************** +****************************** ****************************** +*****************************************************************************/ + +/* General board details... */ +#define SX_WINDOW_LEN 64*1024 /* 64 Kbyte memory window */ + +/* ISA board details... */ +#define SX_ISA_ADDR_LOW 0x0A0000 /* Lowest address = 640 Kbyte */ +#define SX_ISA_ADDR_HIGH 0xFF8000 /* Highest address = 16Mbyte - 32Kbyte */ +#define SX_ISA_ADDR_STEP SX_WINDOW_LEN /* ISA board address step */ +#define SX_ISA_IRQ_MASK 0x9E00 /* IRQs 15,12,11,10,9 */ + +/* Hardware register definitions... */ +#define SX_EVENT_STATUS 0x7800 /* READ: T225 Event Status */ +#define SX_EVENT_STROBE 0x7800 /* WRITE: T225 Event Strobe */ +#define SX_EVENT_ENABLE 0x7880 /* WRITE: T225 Event Enable */ +#define SX_VPD_ROM 0x7C00 /* READ: Vital Product Data ROM */ +#define SX_CONFIG 0x7C00 /* WRITE: Host Configuration Register */ +#define SX_IRQ_STATUS 0x7C80 /* READ: Host Interrupt Status */ +#define SX_SET_IRQ 0x7C80 /* WRITE: Set Host Interrupt */ +#define SX_RESET_STATUS 0x7D00 /* READ: Host Reset Status */ +#define SX_RESET 0x7D00 /* WRITE: Host Reset */ +#define SX_RESET_IRQ 0x7D80 /* WRITE: Reset Host Interrupt */ + +/* SX_VPD_ROM definitions... */ +#define SX_VPD_SLX_ID1 0x00 +#define SX_VPD_SLX_ID2 0x01 +#define SX_VPD_HW_REV 0x02 +#define SX_VPD_HW_ASSEM 0x03 +#define SX_VPD_UNIQUEID4 0x04 +#define SX_VPD_UNIQUEID3 0x05 +#define SX_VPD_UNIQUEID2 0x06 +#define SX_VPD_UNIQUEID1 0x07 +#define SX_VPD_MANU_YEAR 0x08 +#define SX_VPD_MANU_WEEK 0x09 +#define SX_VPD_IDENT 0x10 +#define SX_VPD_IDENT_STRING "JET HOST BY KEV#" + +/* SX unique identifiers... */ +#define SX_UNIQUEID_MASK 0xF0 +#define SX_ISA_UNIQUEID1 0x20 +#define SX_PCI_UNIQUEID1 0x50 + +/* SX_CONFIG definitions... */ +#define SX_CONF_BUSEN 0x02 /* Enable T225 memory and I/O */ +#define SX_CONF_HOSTIRQ 0x04 /* Enable board to host interrupt */ + +/* SX bootstrap... */ +#define SX_BOOTSTRAP "\x28\x20\x21\x02\x60\x0a" +#define SX_BOOTSTRAP_SIZE 6 +#define SX_BOOTSTRAP_ADDR (0x8000-SX_BOOTSTRAP_SIZE) + +/***************************************************************************** +********************************** ********************************** +********************************** EISA ********************************** +********************************** ********************************** +*****************************************************************************/ + +#define SI2_EISA_OFF 0x42 +#define SI2_EISA_VAL 0x01 +#define SI2_EISA_WINDOW_LEN 0x10000 + +/***************************************************************************** +*********************************** ********************************** +*********************************** PCI ********************************** +*********************************** ********************************** +*****************************************************************************/ + +/* General definitions... */ + +#define SPX_VENDOR_ID 0x11CB /* Assigned by the PCI SIG */ +#define SPX_DEVICE_ID 0x4000 /* SI/XIO boards */ +#define SPX_PLXDEVICE_ID 0x2000 /* SX boards */ + +#define SPX_SUB_VENDOR_ID SPX_VENDOR_ID /* Same as vendor id */ +#define SI2_SUB_SYS_ID 0x400 /* Phase 2 (Z280) board */ +#define SX_SUB_SYS_ID 0x200 /* Phase 3 (t225) board */ + +#endif /*_sxboards_h */ + +/* End of SXBOARDS.H */ diff --git a/drivers/staging/generic_serial/sxwindow.h b/drivers/staging/generic_serial/sxwindow.h new file mode 100644 index 000000000000..cf01b662aefc --- /dev/null +++ b/drivers/staging/generic_serial/sxwindow.h @@ -0,0 +1,393 @@ +/************************************************************************/ +/* */ +/* Title : SX Shared Memory Window Structure */ +/* */ +/* Author : N.P.Vassallo */ +/* */ +/* Creation : 16th March 1998 */ +/* */ +/* Version : 3.0.0 */ +/* */ +/* Copyright : (c) Specialix International Ltd. 1998 */ +/* */ +/* Description : Prototypes, structures and definitions */ +/* describing the SX/SI/XIO cards shared */ +/* memory window structure: */ +/* SXCARD */ +/* SXMODULE */ +/* SXCHANNEL */ +/* */ +/************************************************************************/ + +/* History... + +3.0.0 16/03/98 NPV Creation. (based on STRUCT.H) + +*/ + +#ifndef _sxwindow_h /* If SXWINDOW.H not already defined */ +#define _sxwindow_h 1 + +/***************************************************************************** +*************************** *************************** +*************************** Common Definitions *************************** +*************************** *************************** +*****************************************************************************/ + +typedef struct _SXCARD *PSXCARD; /* SXCARD structure pointer */ +typedef struct _SXMODULE *PMOD; /* SXMODULE structure pointer */ +typedef struct _SXCHANNEL *PCHAN; /* SXCHANNEL structure pointer */ + +/***************************************************************************** +********************************* ********************************* +********************************* SXCARD ********************************* +********************************* ********************************* +*****************************************************************************/ + +typedef struct _SXCARD +{ + BYTE cc_init_status; /* 0x00 Initialisation status */ + BYTE cc_mem_size; /* 0x01 Size of memory on card */ + WORD cc_int_count; /* 0x02 Interrupt count */ + WORD cc_revision; /* 0x04 Download code revision */ + BYTE cc_isr_count; /* 0x06 Count when ISR is run */ + BYTE cc_main_count; /* 0x07 Count when main loop is run */ + WORD cc_int_pending; /* 0x08 Interrupt pending */ + WORD cc_poll_count; /* 0x0A Count when poll is run */ + BYTE cc_int_set_count; /* 0x0C Count when host interrupt is set */ + BYTE cc_rfu[0x80 - 0x0D]; /* 0x0D Pad structure to 128 bytes (0x80) */ + +} SXCARD; + +/* SXCARD.cc_init_status definitions... */ +#define ADAPTERS_FOUND (BYTE)0x01 +#define NO_ADAPTERS_FOUND (BYTE)0xFF + +/* SXCARD.cc_mem_size definitions... */ +#define SX_MEMORY_SIZE (BYTE)0x40 + +/* SXCARD.cc_int_count definitions... */ +#define INT_COUNT_DEFAULT 100 /* Hz */ + +/***************************************************************************** +******************************** ******************************** +******************************** SXMODULE ******************************** +******************************** ******************************** +*****************************************************************************/ + +#define TOP_POINTER(a) ((a)|0x8000) /* Sets top bit of word */ +#define UNTOP_POINTER(a) ((a)&~0x8000) /* Clears top bit of word */ + +typedef struct _SXMODULE +{ + WORD mc_next; /* 0x00 Next module "pointer" (ORed with 0x8000) */ + BYTE mc_type; /* 0x02 Type of TA in terms of number of channels */ + BYTE mc_mod_no; /* 0x03 Module number on SI bus cable (0 closest to card) */ + BYTE mc_dtr; /* 0x04 Private DTR copy (TA only) */ + BYTE mc_rfu1; /* 0x05 Reserved */ + WORD mc_uart; /* 0x06 UART base address for this module */ + BYTE mc_chip; /* 0x08 Chip type / number of ports */ + BYTE mc_current_uart; /* 0x09 Current uart selected for this module */ +#ifdef DOWNLOAD + PCHAN mc_chan_pointer[8]; /* 0x0A Pointer to each channel structure */ +#else + WORD mc_chan_pointer[8]; /* 0x0A Define as WORD if not compiling into download */ +#endif + WORD mc_rfu2; /* 0x1A Reserved */ + BYTE mc_opens1; /* 0x1C Number of open ports on first four ports on MTA/SXDC */ + BYTE mc_opens2; /* 0x1D Number of open ports on second four ports on MTA/SXDC */ + BYTE mc_mods; /* 0x1E Types of connector module attached to MTA/SXDC */ + BYTE mc_rev1; /* 0x1F Revision of first CD1400 on MTA/SXDC */ + BYTE mc_rev2; /* 0x20 Revision of second CD1400 on MTA/SXDC */ + BYTE mc_mtaasic_rev; /* 0x21 Revision of MTA ASIC 1..4 -> A, B, C, D */ + BYTE mc_rfu3[0x100 - 0x22]; /* 0x22 Pad structure to 256 bytes (0x100) */ + +} SXMODULE; + +/* SXMODULE.mc_type definitions... */ +#define FOUR_PORTS (BYTE)4 +#define EIGHT_PORTS (BYTE)8 + +/* SXMODULE.mc_chip definitions... */ +#define CHIP_MASK 0xF0 +#define TA (BYTE)0 +#define TA4 (TA | FOUR_PORTS) +#define TA8 (TA | EIGHT_PORTS) +#define TA4_ASIC (BYTE)0x0A +#define TA8_ASIC (BYTE)0x0B +#define MTA_CD1400 (BYTE)0x28 +#define SXDC (BYTE)0x48 + +/* SXMODULE.mc_mods definitions... */ +#define MOD_RS232DB25 0x00 /* RS232 DB25 (socket/plug) */ +#define MOD_RS232RJ45 0x01 /* RS232 RJ45 (shielded/opto-isolated) */ +#define MOD_RESERVED_2 0x02 /* Reserved (RS485) */ +#define MOD_RS422DB25 0x03 /* RS422 DB25 Socket */ +#define MOD_RESERVED_4 0x04 /* Reserved */ +#define MOD_PARALLEL 0x05 /* Parallel */ +#define MOD_RESERVED_6 0x06 /* Reserved (RS423) */ +#define MOD_RESERVED_7 0x07 /* Reserved */ +#define MOD_2_RS232DB25 0x08 /* Rev 2.0 RS232 DB25 (socket/plug) */ +#define MOD_2_RS232RJ45 0x09 /* Rev 2.0 RS232 RJ45 */ +#define MOD_RESERVED_A 0x0A /* Rev 2.0 Reserved */ +#define MOD_2_RS422DB25 0x0B /* Rev 2.0 RS422 DB25 */ +#define MOD_RESERVED_C 0x0C /* Rev 2.0 Reserved */ +#define MOD_2_PARALLEL 0x0D /* Rev 2.0 Parallel */ +#define MOD_RESERVED_E 0x0E /* Rev 2.0 Reserved */ +#define MOD_BLANK 0x0F /* Blank Panel */ + +/***************************************************************************** +******************************** ******************************* +******************************** SXCHANNEL ******************************* +******************************** ******************************* +*****************************************************************************/ + +#define TX_BUFF_OFFSET 0x60 /* Transmit buffer offset in channel structure */ +#define BUFF_POINTER(a) (((a)+TX_BUFF_OFFSET)|0x8000) +#define UNBUFF_POINTER(a) (jet_channel*)(((a)&~0x8000)-TX_BUFF_OFFSET) +#define BUFFER_SIZE 256 +#define HIGH_WATER ((BUFFER_SIZE / 4) * 3) +#define LOW_WATER (BUFFER_SIZE / 4) + +typedef struct _SXCHANNEL +{ + WORD next_item; /* 0x00 Offset from window base of next channels hi_txbuf (ORred with 0x8000) */ + WORD addr_uart; /* 0x02 INTERNAL pointer to uart address. Includes FASTPATH bit */ + WORD module; /* 0x04 Offset from window base of parent SXMODULE structure */ + BYTE type; /* 0x06 Chip type / number of ports (copy of mc_chip) */ + BYTE chan_number; /* 0x07 Channel number on the TA/MTA/SXDC */ + WORD xc_status; /* 0x08 Flow control and I/O status */ + BYTE hi_rxipos; /* 0x0A Receive buffer input index */ + BYTE hi_rxopos; /* 0x0B Receive buffer output index */ + BYTE hi_txopos; /* 0x0C Transmit buffer output index */ + BYTE hi_txipos; /* 0x0D Transmit buffer input index */ + BYTE hi_hstat; /* 0x0E Command register */ + BYTE dtr_bit; /* 0x0F INTERNAL DTR control byte (TA only) */ + BYTE txon; /* 0x10 INTERNAL copy of hi_txon */ + BYTE txoff; /* 0x11 INTERNAL copy of hi_txoff */ + BYTE rxon; /* 0x12 INTERNAL copy of hi_rxon */ + BYTE rxoff; /* 0x13 INTERNAL copy of hi_rxoff */ + BYTE hi_mr1; /* 0x14 Mode Register 1 (databits,parity,RTS rx flow)*/ + BYTE hi_mr2; /* 0x15 Mode Register 2 (stopbits,local,CTS tx flow)*/ + BYTE hi_csr; /* 0x16 Clock Select Register (baud rate) */ + BYTE hi_op; /* 0x17 Modem Output Signal */ + BYTE hi_ip; /* 0x18 Modem Input Signal */ + BYTE hi_state; /* 0x19 Channel status */ + BYTE hi_prtcl; /* 0x1A Channel protocol (flow control) */ + BYTE hi_txon; /* 0x1B Transmit XON character */ + BYTE hi_txoff; /* 0x1C Transmit XOFF character */ + BYTE hi_rxon; /* 0x1D Receive XON character */ + BYTE hi_rxoff; /* 0x1E Receive XOFF character */ + BYTE close_prev; /* 0x1F INTERNAL channel previously closed flag */ + BYTE hi_break; /* 0x20 Break and error control */ + BYTE break_state; /* 0x21 INTERNAL copy of hi_break */ + BYTE hi_mask; /* 0x22 Mask for received data */ + BYTE mask; /* 0x23 INTERNAL copy of hi_mask */ + BYTE mod_type; /* 0x24 MTA/SXDC hardware module type */ + BYTE ccr_state; /* 0x25 INTERNAL MTA/SXDC state of CCR register */ + BYTE ip_mask; /* 0x26 Input handshake mask */ + BYTE hi_parallel; /* 0x27 Parallel port flag */ + BYTE par_error; /* 0x28 Error code for parallel loopback test */ + BYTE any_sent; /* 0x29 INTERNAL data sent flag */ + BYTE asic_txfifo_size; /* 0x2A INTERNAL SXDC transmit FIFO size */ + BYTE rfu1[2]; /* 0x2B Reserved */ + BYTE csr; /* 0x2D INTERNAL copy of hi_csr */ +#ifdef DOWNLOAD + PCHAN nextp; /* 0x2E Offset from window base of next channel structure */ +#else + WORD nextp; /* 0x2E Define as WORD if not compiling into download */ +#endif + BYTE prtcl; /* 0x30 INTERNAL copy of hi_prtcl */ + BYTE mr1; /* 0x31 INTERNAL copy of hi_mr1 */ + BYTE mr2; /* 0x32 INTERNAL copy of hi_mr2 */ + BYTE hi_txbaud; /* 0x33 Extended transmit baud rate (SXDC only if((hi_csr&0x0F)==0x0F) */ + BYTE hi_rxbaud; /* 0x34 Extended receive baud rate (SXDC only if((hi_csr&0xF0)==0xF0) */ + BYTE txbreak_state; /* 0x35 INTERNAL MTA/SXDC transmit break state */ + BYTE txbaud; /* 0x36 INTERNAL copy of hi_txbaud */ + BYTE rxbaud; /* 0x37 INTERNAL copy of hi_rxbaud */ + WORD err_framing; /* 0x38 Count of receive framing errors */ + WORD err_parity; /* 0x3A Count of receive parity errors */ + WORD err_overrun; /* 0x3C Count of receive overrun errors */ + WORD err_overflow; /* 0x3E Count of receive buffer overflow errors */ + BYTE rfu2[TX_BUFF_OFFSET - 0x40]; /* 0x40 Reserved until hi_txbuf */ + BYTE hi_txbuf[BUFFER_SIZE]; /* 0x060 Transmit buffer */ + BYTE hi_rxbuf[BUFFER_SIZE]; /* 0x160 Receive buffer */ + BYTE rfu3[0x300 - 0x260]; /* 0x260 Reserved until 768 bytes (0x300) */ + +} SXCHANNEL; + +/* SXCHANNEL.addr_uart definitions... */ +#define FASTPATH 0x1000 /* Set to indicate fast rx/tx processing (TA only) */ + +/* SXCHANNEL.xc_status definitions... */ +#define X_TANY 0x0001 /* XON is any character (TA only) */ +#define X_TION 0x0001 /* Tx interrupts on (MTA only) */ +#define X_TXEN 0x0002 /* Tx XON/XOFF enabled (TA only) */ +#define X_RTSEN 0x0002 /* RTS FLOW enabled (MTA only) */ +#define X_TXRC 0x0004 /* XOFF received (TA only) */ +#define X_RTSLOW 0x0004 /* RTS dropped (MTA only) */ +#define X_RXEN 0x0008 /* Rx XON/XOFF enabled */ +#define X_ANYXO 0x0010 /* XOFF pending/sent or RTS dropped */ +#define X_RXSE 0x0020 /* Rx XOFF sent */ +#define X_NPEND 0x0040 /* Rx XON pending or XOFF pending */ +#define X_FPEND 0x0080 /* Rx XOFF pending */ +#define C_CRSE 0x0100 /* Carriage return sent (TA only) */ +#define C_TEMR 0x0100 /* Tx empty requested (MTA only) */ +#define C_TEMA 0x0200 /* Tx empty acked (MTA only) */ +#define C_ANYP 0x0200 /* Any protocol bar tx XON/XOFF (TA only) */ +#define C_EN 0x0400 /* Cooking enabled (on MTA means port is also || */ +#define C_HIGH 0x0800 /* Buffer previously hit high water */ +#define C_CTSEN 0x1000 /* CTS automatic flow-control enabled */ +#define C_DCDEN 0x2000 /* DCD/DTR checking enabled */ +#define C_BREAK 0x4000 /* Break detected */ +#define C_RTSEN 0x8000 /* RTS automatic flow control enabled (MTA only) */ +#define C_PARITY 0x8000 /* Parity checking enabled (TA only) */ + +/* SXCHANNEL.hi_hstat definitions... */ +#define HS_IDLE_OPEN 0x00 /* Channel open state */ +#define HS_LOPEN 0x02 /* Local open command (no modem monitoring) */ +#define HS_MOPEN 0x04 /* Modem open command (wait for DCD signal) */ +#define HS_IDLE_MPEND 0x06 /* Waiting for DCD signal state */ +#define HS_CONFIG 0x08 /* Configuration command */ +#define HS_CLOSE 0x0A /* Close command */ +#define HS_START 0x0C /* Start transmit break command */ +#define HS_STOP 0x0E /* Stop transmit break command */ +#define HS_IDLE_CLOSED 0x10 /* Closed channel state */ +#define HS_IDLE_BREAK 0x12 /* Transmit break state */ +#define HS_FORCE_CLOSED 0x14 /* Force close command */ +#define HS_RESUME 0x16 /* Clear pending XOFF command */ +#define HS_WFLUSH 0x18 /* Flush transmit buffer command */ +#define HS_RFLUSH 0x1A /* Flush receive buffer command */ +#define HS_SUSPEND 0x1C /* Suspend output command (like XOFF received) */ +#define PARALLEL 0x1E /* Parallel port loopback test command (Diagnostics Only) */ +#define ENABLE_RX_INTS 0x20 /* Enable receive interrupts command (Diagnostics Only) */ +#define ENABLE_TX_INTS 0x22 /* Enable transmit interrupts command (Diagnostics Only) */ +#define ENABLE_MDM_INTS 0x24 /* Enable modem interrupts command (Diagnostics Only) */ +#define DISABLE_INTS 0x26 /* Disable interrupts command (Diagnostics Only) */ + +/* SXCHANNEL.hi_mr1 definitions... */ +#define MR1_BITS 0x03 /* Data bits mask */ +#define MR1_5_BITS 0x00 /* 5 data bits */ +#define MR1_6_BITS 0x01 /* 6 data bits */ +#define MR1_7_BITS 0x02 /* 7 data bits */ +#define MR1_8_BITS 0x03 /* 8 data bits */ +#define MR1_PARITY 0x1C /* Parity mask */ +#define MR1_ODD 0x04 /* Odd parity */ +#define MR1_EVEN 0x00 /* Even parity */ +#define MR1_WITH 0x00 /* Parity enabled */ +#define MR1_FORCE 0x08 /* Force parity */ +#define MR1_NONE 0x10 /* No parity */ +#define MR1_NOPARITY MR1_NONE /* No parity */ +#define MR1_ODDPARITY (MR1_WITH|MR1_ODD) /* Odd parity */ +#define MR1_EVENPARITY (MR1_WITH|MR1_EVEN) /* Even parity */ +#define MR1_MARKPARITY (MR1_FORCE|MR1_ODD) /* Mark parity */ +#define MR1_SPACEPARITY (MR1_FORCE|MR1_EVEN) /* Space parity */ +#define MR1_RTS_RXFLOW 0x80 /* RTS receive flow control */ + +/* SXCHANNEL.hi_mr2 definitions... */ +#define MR2_STOP 0x0F /* Stop bits mask */ +#define MR2_1_STOP 0x07 /* 1 stop bit */ +#define MR2_2_STOP 0x0F /* 2 stop bits */ +#define MR2_CTS_TXFLOW 0x10 /* CTS transmit flow control */ +#define MR2_RTS_TOGGLE 0x20 /* RTS toggle on transmit */ +#define MR2_NORMAL 0x00 /* Normal mode */ +#define MR2_AUTO 0x40 /* Auto-echo mode (TA only) */ +#define MR2_LOCAL 0x80 /* Local echo mode */ +#define MR2_REMOTE 0xC0 /* Remote echo mode (TA only) */ + +/* SXCHANNEL.hi_csr definitions... */ +#define CSR_75 0x0 /* 75 baud */ +#define CSR_110 0x1 /* 110 baud (TA), 115200 (MTA/SXDC) */ +#define CSR_38400 0x2 /* 38400 baud */ +#define CSR_150 0x3 /* 150 baud */ +#define CSR_300 0x4 /* 300 baud */ +#define CSR_600 0x5 /* 600 baud */ +#define CSR_1200 0x6 /* 1200 baud */ +#define CSR_2000 0x7 /* 2000 baud */ +#define CSR_2400 0x8 /* 2400 baud */ +#define CSR_4800 0x9 /* 4800 baud */ +#define CSR_1800 0xA /* 1800 baud */ +#define CSR_9600 0xB /* 9600 baud */ +#define CSR_19200 0xC /* 19200 baud */ +#define CSR_57600 0xD /* 57600 baud */ +#define CSR_EXTBAUD 0xF /* Extended baud rate (hi_txbaud/hi_rxbaud) */ + +/* SXCHANNEL.hi_op definitions... */ +#define OP_RTS 0x01 /* RTS modem output signal */ +#define OP_DTR 0x02 /* DTR modem output signal */ + +/* SXCHANNEL.hi_ip definitions... */ +#define IP_CTS 0x02 /* CTS modem input signal */ +#define IP_DCD 0x04 /* DCD modem input signal */ +#define IP_DSR 0x20 /* DTR modem input signal */ +#define IP_RI 0x40 /* RI modem input signal */ + +/* SXCHANNEL.hi_state definitions... */ +#define ST_BREAK 0x01 /* Break received (clear with config) */ +#define ST_DCD 0x02 /* DCD signal changed state */ + +/* SXCHANNEL.hi_prtcl definitions... */ +#define SP_TANY 0x01 /* Transmit XON/XANY (if SP_TXEN enabled) */ +#define SP_TXEN 0x02 /* Transmit XON/XOFF flow control */ +#define SP_CEN 0x04 /* Cooking enabled */ +#define SP_RXEN 0x08 /* Rx XON/XOFF enabled */ +#define SP_DCEN 0x20 /* DCD / DTR check */ +#define SP_DTR_RXFLOW 0x40 /* DTR receive flow control */ +#define SP_PAEN 0x80 /* Parity checking enabled */ + +/* SXCHANNEL.hi_break definitions... */ +#define BR_IGN 0x01 /* Ignore any received breaks */ +#define BR_INT 0x02 /* Interrupt on received break */ +#define BR_PARMRK 0x04 /* Enable parmrk parity error processing */ +#define BR_PARIGN 0x08 /* Ignore chars with parity errors */ +#define BR_ERRINT 0x80 /* Treat parity/framing/overrun errors as exceptions */ + +/* SXCHANNEL.par_error definitions.. */ +#define DIAG_IRQ_RX 0x01 /* Indicate serial receive interrupt (diags only) */ +#define DIAG_IRQ_TX 0x02 /* Indicate serial transmit interrupt (diags only) */ +#define DIAG_IRQ_MD 0x04 /* Indicate serial modem interrupt (diags only) */ + +/* SXCHANNEL.hi_txbaud/hi_rxbaud definitions... (SXDC only) */ +#define BAUD_75 0x00 /* 75 baud */ +#define BAUD_115200 0x01 /* 115200 baud */ +#define BAUD_38400 0x02 /* 38400 baud */ +#define BAUD_150 0x03 /* 150 baud */ +#define BAUD_300 0x04 /* 300 baud */ +#define BAUD_600 0x05 /* 600 baud */ +#define BAUD_1200 0x06 /* 1200 baud */ +#define BAUD_2000 0x07 /* 2000 baud */ +#define BAUD_2400 0x08 /* 2400 baud */ +#define BAUD_4800 0x09 /* 4800 baud */ +#define BAUD_1800 0x0A /* 1800 baud */ +#define BAUD_9600 0x0B /* 9600 baud */ +#define BAUD_19200 0x0C /* 19200 baud */ +#define BAUD_57600 0x0D /* 57600 baud */ +#define BAUD_230400 0x0E /* 230400 baud */ +#define BAUD_460800 0x0F /* 460800 baud */ +#define BAUD_921600 0x10 /* 921600 baud */ +#define BAUD_50 0x11 /* 50 baud */ +#define BAUD_110 0x12 /* 110 baud */ +#define BAUD_134_5 0x13 /* 134.5 baud */ +#define BAUD_200 0x14 /* 200 baud */ +#define BAUD_7200 0x15 /* 7200 baud */ +#define BAUD_56000 0x16 /* 56000 baud */ +#define BAUD_64000 0x17 /* 64000 baud */ +#define BAUD_76800 0x18 /* 76800 baud */ +#define BAUD_128000 0x19 /* 128000 baud */ +#define BAUD_150000 0x1A /* 150000 baud */ +#define BAUD_14400 0x1B /* 14400 baud */ +#define BAUD_256000 0x1C /* 256000 baud */ +#define BAUD_28800 0x1D /* 28800 baud */ + +/* SXCHANNEL.txbreak_state definiions... */ +#define TXBREAK_OFF 0 /* Not sending break */ +#define TXBREAK_START 1 /* Begin sending break */ +#define TXBREAK_START1 2 /* Begin sending break, part 1 */ +#define TXBREAK_ON 3 /* Sending break */ +#define TXBREAK_STOP 4 /* Stop sending break */ +#define TXBREAK_STOP1 5 /* Stop sending break, part 1 */ + +#endif /* _sxwindow_h */ + +/* End of SXWINDOW.H */ + diff --git a/drivers/staging/generic_serial/vme_scc.c b/drivers/staging/generic_serial/vme_scc.c new file mode 100644 index 000000000000..96838640f575 --- /dev/null +++ b/drivers/staging/generic_serial/vme_scc.c @@ -0,0 +1,1145 @@ +/* + * drivers/char/vme_scc.c: MVME147, MVME162, BVME6000 SCC serial ports + * implementation. + * Copyright 1999 Richard Hirst + * + * Based on atari_SCC.c which was + * Copyright 1994-95 Roman Hodek + * Partially based on PC-Linux serial.c by Linus Torvalds and Theodore Ts'o + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_MVME147_SCC +#include +#endif +#ifdef CONFIG_MVME162_SCC +#include +#endif +#ifdef CONFIG_BVME6000_SCC +#include +#endif + +#include +#include "scc.h" + + +#define CHANNEL_A 0 +#define CHANNEL_B 1 + +#define SCC_MINOR_BASE 64 + +/* Shadows for all SCC write registers */ +static unsigned char scc_shadow[2][16]; + +/* Location to access for SCC register access delay */ +static volatile unsigned char *scc_del = NULL; + +/* To keep track of STATUS_REG state for detection of Ext/Status int source */ +static unsigned char scc_last_status_reg[2]; + +/***************************** Prototypes *****************************/ + +/* Function prototypes */ +static void scc_disable_tx_interrupts(void * ptr); +static void scc_enable_tx_interrupts(void * ptr); +static void scc_disable_rx_interrupts(void * ptr); +static void scc_enable_rx_interrupts(void * ptr); +static int scc_carrier_raised(struct tty_port *port); +static void scc_shutdown_port(void * ptr); +static int scc_set_real_termios(void *ptr); +static void scc_hungup(void *ptr); +static void scc_close(void *ptr); +static int scc_chars_in_buffer(void * ptr); +static int scc_open(struct tty_struct * tty, struct file * filp); +static int scc_ioctl(struct tty_struct * tty, + unsigned int cmd, unsigned long arg); +static void scc_throttle(struct tty_struct *tty); +static void scc_unthrottle(struct tty_struct *tty); +static irqreturn_t scc_tx_int(int irq, void *data); +static irqreturn_t scc_rx_int(int irq, void *data); +static irqreturn_t scc_stat_int(int irq, void *data); +static irqreturn_t scc_spcond_int(int irq, void *data); +static void scc_setsignals(struct scc_port *port, int dtr, int rts); +static int scc_break_ctl(struct tty_struct *tty, int break_state); + +static struct tty_driver *scc_driver; + +static struct scc_port scc_ports[2]; + +/*--------------------------------------------------------------------------- + * Interface from generic_serial.c back here + *--------------------------------------------------------------------------*/ + +static struct real_driver scc_real_driver = { + scc_disable_tx_interrupts, + scc_enable_tx_interrupts, + scc_disable_rx_interrupts, + scc_enable_rx_interrupts, + scc_shutdown_port, + scc_set_real_termios, + scc_chars_in_buffer, + scc_close, + scc_hungup, + NULL +}; + + +static const struct tty_operations scc_ops = { + .open = scc_open, + .close = gs_close, + .write = gs_write, + .put_char = gs_put_char, + .flush_chars = gs_flush_chars, + .write_room = gs_write_room, + .chars_in_buffer = gs_chars_in_buffer, + .flush_buffer = gs_flush_buffer, + .ioctl = scc_ioctl, + .throttle = scc_throttle, + .unthrottle = scc_unthrottle, + .set_termios = gs_set_termios, + .stop = gs_stop, + .start = gs_start, + .hangup = gs_hangup, + .break_ctl = scc_break_ctl, +}; + +static const struct tty_port_operations scc_port_ops = { + .carrier_raised = scc_carrier_raised, +}; + +/*---------------------------------------------------------------------------- + * vme_scc_init() and support functions + *---------------------------------------------------------------------------*/ + +static int __init scc_init_drivers(void) +{ + int error; + + scc_driver = alloc_tty_driver(2); + if (!scc_driver) + return -ENOMEM; + scc_driver->owner = THIS_MODULE; + scc_driver->driver_name = "scc"; + scc_driver->name = "ttyS"; + scc_driver->major = TTY_MAJOR; + scc_driver->minor_start = SCC_MINOR_BASE; + scc_driver->type = TTY_DRIVER_TYPE_SERIAL; + scc_driver->subtype = SERIAL_TYPE_NORMAL; + scc_driver->init_termios = tty_std_termios; + scc_driver->init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + scc_driver->init_termios.c_ispeed = 9600; + scc_driver->init_termios.c_ospeed = 9600; + scc_driver->flags = TTY_DRIVER_REAL_RAW; + tty_set_operations(scc_driver, &scc_ops); + + if ((error = tty_register_driver(scc_driver))) { + printk(KERN_ERR "scc: Couldn't register scc driver, error = %d\n", + error); + put_tty_driver(scc_driver); + return 1; + } + + return 0; +} + + +/* ports[] array is indexed by line no (i.e. [0] for ttyS0, [1] for ttyS1). + */ + +static void __init scc_init_portstructs(void) +{ + struct scc_port *port; + int i; + + for (i = 0; i < 2; i++) { + port = scc_ports + i; + tty_port_init(&port->gs.port); + port->gs.port.ops = &scc_port_ops; + port->gs.magic = SCC_MAGIC; + port->gs.close_delay = HZ/2; + port->gs.closing_wait = 30 * HZ; + port->gs.rd = &scc_real_driver; +#ifdef NEW_WRITE_LOCKING + port->gs.port_write_mutex = MUTEX; +#endif + init_waitqueue_head(&port->gs.port.open_wait); + init_waitqueue_head(&port->gs.port.close_wait); + } +} + + +#ifdef CONFIG_MVME147_SCC +static int __init mvme147_scc_init(void) +{ + struct scc_port *port; + int error; + + printk(KERN_INFO "SCC: MVME147 Serial Driver\n"); + /* Init channel A */ + port = &scc_ports[0]; + port->channel = CHANNEL_A; + port->ctrlp = (volatile unsigned char *)M147_SCC_A_ADDR; + port->datap = port->ctrlp + 1; + port->port_a = &scc_ports[0]; + port->port_b = &scc_ports[1]; + error = request_irq(MVME147_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED, + "SCC-A TX", port); + if (error) + goto fail; + error = request_irq(MVME147_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED, + "SCC-A status", port); + if (error) + goto fail_free_a_tx; + error = request_irq(MVME147_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED, + "SCC-A RX", port); + if (error) + goto fail_free_a_stat; + error = request_irq(MVME147_IRQ_SCCA_SPCOND, scc_spcond_int, + IRQF_DISABLED, "SCC-A special cond", port); + if (error) + goto fail_free_a_rx; + + { + SCC_ACCESS_INIT(port); + + /* disable interrupts for this channel */ + SCCwrite(INT_AND_DMA_REG, 0); + /* Set the interrupt vector */ + SCCwrite(INT_VECTOR_REG, MVME147_IRQ_SCC_BASE); + /* Interrupt parameters: vector includes status, status low */ + SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT); + SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB); + } + + /* Init channel B */ + port = &scc_ports[1]; + port->channel = CHANNEL_B; + port->ctrlp = (volatile unsigned char *)M147_SCC_B_ADDR; + port->datap = port->ctrlp + 1; + port->port_a = &scc_ports[0]; + port->port_b = &scc_ports[1]; + error = request_irq(MVME147_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED, + "SCC-B TX", port); + if (error) + goto fail_free_a_spcond; + error = request_irq(MVME147_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED, + "SCC-B status", port); + if (error) + goto fail_free_b_tx; + error = request_irq(MVME147_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED, + "SCC-B RX", port); + if (error) + goto fail_free_b_stat; + error = request_irq(MVME147_IRQ_SCCB_SPCOND, scc_spcond_int, + IRQF_DISABLED, "SCC-B special cond", port); + if (error) + goto fail_free_b_rx; + + { + SCC_ACCESS_INIT(port); + + /* disable interrupts for this channel */ + SCCwrite(INT_AND_DMA_REG, 0); + } + + /* Ensure interrupts are enabled in the PCC chip */ + m147_pcc->serial_cntrl=PCC_LEVEL_SERIAL|PCC_INT_ENAB; + + /* Initialise the tty driver structures and register */ + scc_init_portstructs(); + scc_init_drivers(); + + return 0; + +fail_free_b_rx: + free_irq(MVME147_IRQ_SCCB_RX, port); +fail_free_b_stat: + free_irq(MVME147_IRQ_SCCB_STAT, port); +fail_free_b_tx: + free_irq(MVME147_IRQ_SCCB_TX, port); +fail_free_a_spcond: + free_irq(MVME147_IRQ_SCCA_SPCOND, port); +fail_free_a_rx: + free_irq(MVME147_IRQ_SCCA_RX, port); +fail_free_a_stat: + free_irq(MVME147_IRQ_SCCA_STAT, port); +fail_free_a_tx: + free_irq(MVME147_IRQ_SCCA_TX, port); +fail: + return error; +} +#endif + + +#ifdef CONFIG_MVME162_SCC +static int __init mvme162_scc_init(void) +{ + struct scc_port *port; + int error; + + if (!(mvme16x_config & MVME16x_CONFIG_GOT_SCCA)) + return (-ENODEV); + + printk(KERN_INFO "SCC: MVME162 Serial Driver\n"); + /* Init channel A */ + port = &scc_ports[0]; + port->channel = CHANNEL_A; + port->ctrlp = (volatile unsigned char *)MVME_SCC_A_ADDR; + port->datap = port->ctrlp + 2; + port->port_a = &scc_ports[0]; + port->port_b = &scc_ports[1]; + error = request_irq(MVME162_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED, + "SCC-A TX", port); + if (error) + goto fail; + error = request_irq(MVME162_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED, + "SCC-A status", port); + if (error) + goto fail_free_a_tx; + error = request_irq(MVME162_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED, + "SCC-A RX", port); + if (error) + goto fail_free_a_stat; + error = request_irq(MVME162_IRQ_SCCA_SPCOND, scc_spcond_int, + IRQF_DISABLED, "SCC-A special cond", port); + if (error) + goto fail_free_a_rx; + + { + SCC_ACCESS_INIT(port); + + /* disable interrupts for this channel */ + SCCwrite(INT_AND_DMA_REG, 0); + /* Set the interrupt vector */ + SCCwrite(INT_VECTOR_REG, MVME162_IRQ_SCC_BASE); + /* Interrupt parameters: vector includes status, status low */ + SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT); + SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB); + } + + /* Init channel B */ + port = &scc_ports[1]; + port->channel = CHANNEL_B; + port->ctrlp = (volatile unsigned char *)MVME_SCC_B_ADDR; + port->datap = port->ctrlp + 2; + port->port_a = &scc_ports[0]; + port->port_b = &scc_ports[1]; + error = request_irq(MVME162_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED, + "SCC-B TX", port); + if (error) + goto fail_free_a_spcond; + error = request_irq(MVME162_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED, + "SCC-B status", port); + if (error) + goto fail_free_b_tx; + error = request_irq(MVME162_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED, + "SCC-B RX", port); + if (error) + goto fail_free_b_stat; + error = request_irq(MVME162_IRQ_SCCB_SPCOND, scc_spcond_int, + IRQF_DISABLED, "SCC-B special cond", port); + if (error) + goto fail_free_b_rx; + + { + SCC_ACCESS_INIT(port); /* Either channel will do */ + + /* disable interrupts for this channel */ + SCCwrite(INT_AND_DMA_REG, 0); + } + + /* Ensure interrupts are enabled in the MC2 chip */ + *(volatile char *)0xfff4201d = 0x14; + + /* Initialise the tty driver structures and register */ + scc_init_portstructs(); + scc_init_drivers(); + + return 0; + +fail_free_b_rx: + free_irq(MVME162_IRQ_SCCB_RX, port); +fail_free_b_stat: + free_irq(MVME162_IRQ_SCCB_STAT, port); +fail_free_b_tx: + free_irq(MVME162_IRQ_SCCB_TX, port); +fail_free_a_spcond: + free_irq(MVME162_IRQ_SCCA_SPCOND, port); +fail_free_a_rx: + free_irq(MVME162_IRQ_SCCA_RX, port); +fail_free_a_stat: + free_irq(MVME162_IRQ_SCCA_STAT, port); +fail_free_a_tx: + free_irq(MVME162_IRQ_SCCA_TX, port); +fail: + return error; +} +#endif + + +#ifdef CONFIG_BVME6000_SCC +static int __init bvme6000_scc_init(void) +{ + struct scc_port *port; + int error; + + printk(KERN_INFO "SCC: BVME6000 Serial Driver\n"); + /* Init channel A */ + port = &scc_ports[0]; + port->channel = CHANNEL_A; + port->ctrlp = (volatile unsigned char *)BVME_SCC_A_ADDR; + port->datap = port->ctrlp + 4; + port->port_a = &scc_ports[0]; + port->port_b = &scc_ports[1]; + error = request_irq(BVME_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED, + "SCC-A TX", port); + if (error) + goto fail; + error = request_irq(BVME_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED, + "SCC-A status", port); + if (error) + goto fail_free_a_tx; + error = request_irq(BVME_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED, + "SCC-A RX", port); + if (error) + goto fail_free_a_stat; + error = request_irq(BVME_IRQ_SCCA_SPCOND, scc_spcond_int, + IRQF_DISABLED, "SCC-A special cond", port); + if (error) + goto fail_free_a_rx; + + { + SCC_ACCESS_INIT(port); + + /* disable interrupts for this channel */ + SCCwrite(INT_AND_DMA_REG, 0); + /* Set the interrupt vector */ + SCCwrite(INT_VECTOR_REG, BVME_IRQ_SCC_BASE); + /* Interrupt parameters: vector includes status, status low */ + SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT); + SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB); + } + + /* Init channel B */ + port = &scc_ports[1]; + port->channel = CHANNEL_B; + port->ctrlp = (volatile unsigned char *)BVME_SCC_B_ADDR; + port->datap = port->ctrlp + 4; + port->port_a = &scc_ports[0]; + port->port_b = &scc_ports[1]; + error = request_irq(BVME_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED, + "SCC-B TX", port); + if (error) + goto fail_free_a_spcond; + error = request_irq(BVME_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED, + "SCC-B status", port); + if (error) + goto fail_free_b_tx; + error = request_irq(BVME_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED, + "SCC-B RX", port); + if (error) + goto fail_free_b_stat; + error = request_irq(BVME_IRQ_SCCB_SPCOND, scc_spcond_int, + IRQF_DISABLED, "SCC-B special cond", port); + if (error) + goto fail_free_b_rx; + + { + SCC_ACCESS_INIT(port); /* Either channel will do */ + + /* disable interrupts for this channel */ + SCCwrite(INT_AND_DMA_REG, 0); + } + + /* Initialise the tty driver structures and register */ + scc_init_portstructs(); + scc_init_drivers(); + + return 0; + +fail: + free_irq(BVME_IRQ_SCCA_STAT, port); +fail_free_a_tx: + free_irq(BVME_IRQ_SCCA_RX, port); +fail_free_a_stat: + free_irq(BVME_IRQ_SCCA_SPCOND, port); +fail_free_a_rx: + free_irq(BVME_IRQ_SCCB_TX, port); +fail_free_a_spcond: + free_irq(BVME_IRQ_SCCB_STAT, port); +fail_free_b_tx: + free_irq(BVME_IRQ_SCCB_RX, port); +fail_free_b_stat: + free_irq(BVME_IRQ_SCCB_SPCOND, port); +fail_free_b_rx: + return error; +} +#endif + + +static int __init vme_scc_init(void) +{ + int res = -ENODEV; + +#ifdef CONFIG_MVME147_SCC + if (MACH_IS_MVME147) + res = mvme147_scc_init(); +#endif +#ifdef CONFIG_MVME162_SCC + if (MACH_IS_MVME16x) + res = mvme162_scc_init(); +#endif +#ifdef CONFIG_BVME6000_SCC + if (MACH_IS_BVME6000) + res = bvme6000_scc_init(); +#endif + return res; +} + +module_init(vme_scc_init); + + +/*--------------------------------------------------------------------------- + * Interrupt handlers + *--------------------------------------------------------------------------*/ + +static irqreturn_t scc_rx_int(int irq, void *data) +{ + unsigned char ch; + struct scc_port *port = data; + struct tty_struct *tty = port->gs.port.tty; + SCC_ACCESS_INIT(port); + + ch = SCCread_NB(RX_DATA_REG); + if (!tty) { + printk(KERN_WARNING "scc_rx_int with NULL tty!\n"); + SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); + return IRQ_HANDLED; + } + tty_insert_flip_char(tty, ch, 0); + + /* Check if another character is already ready; in that case, the + * spcond_int() function must be used, because this character may have an + * error condition that isn't signalled by the interrupt vector used! + */ + if (SCCread(INT_PENDING_REG) & + (port->channel == CHANNEL_A ? IPR_A_RX : IPR_B_RX)) { + scc_spcond_int (irq, data); + return IRQ_HANDLED; + } + + SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); + + tty_flip_buffer_push(tty); + return IRQ_HANDLED; +} + + +static irqreturn_t scc_spcond_int(int irq, void *data) +{ + struct scc_port *port = data; + struct tty_struct *tty = port->gs.port.tty; + unsigned char stat, ch, err; + int int_pending_mask = port->channel == CHANNEL_A ? + IPR_A_RX : IPR_B_RX; + SCC_ACCESS_INIT(port); + + if (!tty) { + printk(KERN_WARNING "scc_spcond_int with NULL tty!\n"); + SCCwrite(COMMAND_REG, CR_ERROR_RESET); + SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); + return IRQ_HANDLED; + } + do { + stat = SCCread(SPCOND_STATUS_REG); + ch = SCCread_NB(RX_DATA_REG); + + if (stat & SCSR_RX_OVERRUN) + err = TTY_OVERRUN; + else if (stat & SCSR_PARITY_ERR) + err = TTY_PARITY; + else if (stat & SCSR_CRC_FRAME_ERR) + err = TTY_FRAME; + else + err = 0; + + tty_insert_flip_char(tty, ch, err); + + /* ++TeSche: *All* errors have to be cleared manually, + * else the condition persists for the next chars + */ + if (err) + SCCwrite(COMMAND_REG, CR_ERROR_RESET); + + } while(SCCread(INT_PENDING_REG) & int_pending_mask); + + SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); + + tty_flip_buffer_push(tty); + return IRQ_HANDLED; +} + + +static irqreturn_t scc_tx_int(int irq, void *data) +{ + struct scc_port *port = data; + SCC_ACCESS_INIT(port); + + if (!port->gs.port.tty) { + printk(KERN_WARNING "scc_tx_int with NULL tty!\n"); + SCCmod (INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0); + SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET); + SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); + return IRQ_HANDLED; + } + while ((SCCread_NB(STATUS_REG) & SR_TX_BUF_EMPTY)) { + if (port->x_char) { + SCCwrite(TX_DATA_REG, port->x_char); + port->x_char = 0; + } + else if ((port->gs.xmit_cnt <= 0) || + port->gs.port.tty->stopped || + port->gs.port.tty->hw_stopped) + break; + else { + SCCwrite(TX_DATA_REG, port->gs.xmit_buf[port->gs.xmit_tail++]); + port->gs.xmit_tail = port->gs.xmit_tail & (SERIAL_XMIT_SIZE-1); + if (--port->gs.xmit_cnt <= 0) + break; + } + } + if ((port->gs.xmit_cnt <= 0) || port->gs.port.tty->stopped || + port->gs.port.tty->hw_stopped) { + /* disable tx interrupts */ + SCCmod (INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0); + SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET); /* disable tx_int on next tx underrun? */ + port->gs.port.flags &= ~GS_TX_INTEN; + } + if (port->gs.port.tty && port->gs.xmit_cnt <= port->gs.wakeup_chars) + tty_wakeup(port->gs.port.tty); + + SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); + return IRQ_HANDLED; +} + + +static irqreturn_t scc_stat_int(int irq, void *data) +{ + struct scc_port *port = data; + unsigned channel = port->channel; + unsigned char last_sr, sr, changed; + SCC_ACCESS_INIT(port); + + last_sr = scc_last_status_reg[channel]; + sr = scc_last_status_reg[channel] = SCCread_NB(STATUS_REG); + changed = last_sr ^ sr; + + if (changed & SR_DCD) { + port->c_dcd = !!(sr & SR_DCD); + if (!(port->gs.port.flags & ASYNC_CHECK_CD)) + ; /* Don't report DCD changes */ + else if (port->c_dcd) { + wake_up_interruptible(&port->gs.port.open_wait); + } + else { + if (port->gs.port.tty) + tty_hangup (port->gs.port.tty); + } + } + SCCwrite(COMMAND_REG, CR_EXTSTAT_RESET); + SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); + return IRQ_HANDLED; +} + + +/*--------------------------------------------------------------------------- + * generic_serial.c callback funtions + *--------------------------------------------------------------------------*/ + +static void scc_disable_tx_interrupts(void *ptr) +{ + struct scc_port *port = ptr; + unsigned long flags; + SCC_ACCESS_INIT(port); + + local_irq_save(flags); + SCCmod(INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0); + port->gs.port.flags &= ~GS_TX_INTEN; + local_irq_restore(flags); +} + + +static void scc_enable_tx_interrupts(void *ptr) +{ + struct scc_port *port = ptr; + unsigned long flags; + SCC_ACCESS_INIT(port); + + local_irq_save(flags); + SCCmod(INT_AND_DMA_REG, 0xff, IDR_TX_INT_ENAB); + /* restart the transmitter */ + scc_tx_int (0, port); + local_irq_restore(flags); +} + + +static void scc_disable_rx_interrupts(void *ptr) +{ + struct scc_port *port = ptr; + unsigned long flags; + SCC_ACCESS_INIT(port); + + local_irq_save(flags); + SCCmod(INT_AND_DMA_REG, + ~(IDR_RX_INT_MASK|IDR_PARERR_AS_SPCOND|IDR_EXTSTAT_INT_ENAB), 0); + local_irq_restore(flags); +} + + +static void scc_enable_rx_interrupts(void *ptr) +{ + struct scc_port *port = ptr; + unsigned long flags; + SCC_ACCESS_INIT(port); + + local_irq_save(flags); + SCCmod(INT_AND_DMA_REG, 0xff, + IDR_EXTSTAT_INT_ENAB|IDR_PARERR_AS_SPCOND|IDR_RX_INT_ALL); + local_irq_restore(flags); +} + + +static int scc_carrier_raised(struct tty_port *port) +{ + struct scc_port *sc = container_of(port, struct scc_port, gs.port); + unsigned channel = sc->channel; + + return !!(scc_last_status_reg[channel] & SR_DCD); +} + + +static void scc_shutdown_port(void *ptr) +{ + struct scc_port *port = ptr; + + port->gs.port.flags &= ~ GS_ACTIVE; + if (port->gs.port.tty && (port->gs.port.tty->termios->c_cflag & HUPCL)) { + scc_setsignals (port, 0, 0); + } +} + + +static int scc_set_real_termios (void *ptr) +{ + /* the SCC has char sizes 5,7,6,8 in that order! */ + static int chsize_map[4] = { 0, 2, 1, 3 }; + unsigned cflag, baud, chsize, channel, brgval = 0; + unsigned long flags; + struct scc_port *port = ptr; + SCC_ACCESS_INIT(port); + + if (!port->gs.port.tty || !port->gs.port.tty->termios) return 0; + + channel = port->channel; + + if (channel == CHANNEL_A) + return 0; /* Settings controlled by boot PROM */ + + cflag = port->gs.port.tty->termios->c_cflag; + baud = port->gs.baud; + chsize = (cflag & CSIZE) >> 4; + + if (baud == 0) { + /* speed == 0 -> drop DTR */ + local_irq_save(flags); + SCCmod(TX_CTRL_REG, ~TCR_DTR, 0); + local_irq_restore(flags); + return 0; + } + else if ((MACH_IS_MVME16x && (baud < 50 || baud > 38400)) || + (MACH_IS_MVME147 && (baud < 50 || baud > 19200)) || + (MACH_IS_BVME6000 &&(baud < 50 || baud > 76800))) { + printk(KERN_NOTICE "SCC: Bad speed requested, %d\n", baud); + return 0; + } + + if (cflag & CLOCAL) + port->gs.port.flags &= ~ASYNC_CHECK_CD; + else + port->gs.port.flags |= ASYNC_CHECK_CD; + +#ifdef CONFIG_MVME147_SCC + if (MACH_IS_MVME147) + brgval = (M147_SCC_PCLK + baud/2) / (16 * 2 * baud) - 2; +#endif +#ifdef CONFIG_MVME162_SCC + if (MACH_IS_MVME16x) + brgval = (MVME_SCC_PCLK + baud/2) / (16 * 2 * baud) - 2; +#endif +#ifdef CONFIG_BVME6000_SCC + if (MACH_IS_BVME6000) + brgval = (BVME_SCC_RTxC + baud/2) / (16 * 2 * baud) - 2; +#endif + /* Now we have all parameters and can go to set them: */ + local_irq_save(flags); + + /* receiver's character size and auto-enables */ + SCCmod(RX_CTRL_REG, ~(RCR_CHSIZE_MASK|RCR_AUTO_ENAB_MODE), + (chsize_map[chsize] << 6) | + ((cflag & CRTSCTS) ? RCR_AUTO_ENAB_MODE : 0)); + /* parity and stop bits (both, Tx and Rx), clock mode never changes */ + SCCmod (AUX1_CTRL_REG, + ~(A1CR_PARITY_MASK | A1CR_MODE_MASK), + ((cflag & PARENB + ? (cflag & PARODD ? A1CR_PARITY_ODD : A1CR_PARITY_EVEN) + : A1CR_PARITY_NONE) + | (cflag & CSTOPB ? A1CR_MODE_ASYNC_2 : A1CR_MODE_ASYNC_1))); + /* sender's character size, set DTR for valid baud rate */ + SCCmod(TX_CTRL_REG, ~TCR_CHSIZE_MASK, chsize_map[chsize] << 5 | TCR_DTR); + /* clock sources never change */ + /* disable BRG before changing the value */ + SCCmod(DPLL_CTRL_REG, ~DCR_BRG_ENAB, 0); + /* BRG value */ + SCCwrite(TIMER_LOW_REG, brgval & 0xff); + SCCwrite(TIMER_HIGH_REG, (brgval >> 8) & 0xff); + /* BRG enable, and clock source never changes */ + SCCmod(DPLL_CTRL_REG, 0xff, DCR_BRG_ENAB); + + local_irq_restore(flags); + + return 0; +} + + +static int scc_chars_in_buffer (void *ptr) +{ + struct scc_port *port = ptr; + SCC_ACCESS_INIT(port); + + return (SCCread (SPCOND_STATUS_REG) & SCSR_ALL_SENT) ? 0 : 1; +} + + +/* Comment taken from sx.c (2.4.0): + I haven't the foggiest why the decrement use count has to happen + here. The whole linux serial drivers stuff needs to be redesigned. + My guess is that this is a hack to minimize the impact of a bug + elsewhere. Thinking about it some more. (try it sometime) Try + running minicom on a serial port that is driven by a modularized + driver. Have the modem hangup. Then remove the driver module. Then + exit minicom. I expect an "oops". -- REW */ + +static void scc_hungup(void *ptr) +{ + scc_disable_tx_interrupts(ptr); + scc_disable_rx_interrupts(ptr); +} + + +static void scc_close(void *ptr) +{ + scc_disable_tx_interrupts(ptr); + scc_disable_rx_interrupts(ptr); +} + + +/*--------------------------------------------------------------------------- + * Internal support functions + *--------------------------------------------------------------------------*/ + +static void scc_setsignals(struct scc_port *port, int dtr, int rts) +{ + unsigned long flags; + unsigned char t; + SCC_ACCESS_INIT(port); + + local_irq_save(flags); + t = SCCread(TX_CTRL_REG); + if (dtr >= 0) t = dtr? (t | TCR_DTR): (t & ~TCR_DTR); + if (rts >= 0) t = rts? (t | TCR_RTS): (t & ~TCR_RTS); + SCCwrite(TX_CTRL_REG, t); + local_irq_restore(flags); +} + + +static void scc_send_xchar(struct tty_struct *tty, char ch) +{ + struct scc_port *port = tty->driver_data; + + port->x_char = ch; + if (ch) + scc_enable_tx_interrupts(port); +} + + +/*--------------------------------------------------------------------------- + * Driver entrypoints referenced from above + *--------------------------------------------------------------------------*/ + +static int scc_open (struct tty_struct * tty, struct file * filp) +{ + int line = tty->index; + int retval; + struct scc_port *port = &scc_ports[line]; + int i, channel = port->channel; + unsigned long flags; + SCC_ACCESS_INIT(port); +#if defined(CONFIG_MVME162_SCC) || defined(CONFIG_MVME147_SCC) + static const struct { + unsigned reg, val; + } mvme_init_tab[] = { + /* Values for MVME162 and MVME147 */ + /* no parity, 1 stop bit, async, 1:16 */ + { AUX1_CTRL_REG, A1CR_PARITY_NONE|A1CR_MODE_ASYNC_1|A1CR_CLKMODE_x16 }, + /* parity error is special cond, ints disabled, no DMA */ + { INT_AND_DMA_REG, IDR_PARERR_AS_SPCOND | IDR_RX_INT_DISAB }, + /* Rx 8 bits/char, no auto enable, Rx off */ + { RX_CTRL_REG, RCR_CHSIZE_8 }, + /* DTR off, Tx 8 bits/char, RTS off, Tx off */ + { TX_CTRL_REG, TCR_CHSIZE_8 }, + /* special features off */ + { AUX2_CTRL_REG, 0 }, + { CLK_CTRL_REG, CCR_RXCLK_BRG | CCR_TXCLK_BRG }, + { DPLL_CTRL_REG, DCR_BRG_ENAB | DCR_BRG_USE_PCLK }, + /* Start Rx */ + { RX_CTRL_REG, RCR_RX_ENAB | RCR_CHSIZE_8 }, + /* Start Tx */ + { TX_CTRL_REG, TCR_TX_ENAB | TCR_RTS | TCR_DTR | TCR_CHSIZE_8 }, + /* Ext/Stat ints: DCD only */ + { INT_CTRL_REG, ICR_ENAB_DCD_INT }, + /* Reset Ext/Stat ints */ + { COMMAND_REG, CR_EXTSTAT_RESET }, + /* ...again */ + { COMMAND_REG, CR_EXTSTAT_RESET }, + }; +#endif +#if defined(CONFIG_BVME6000_SCC) + static const struct { + unsigned reg, val; + } bvme_init_tab[] = { + /* Values for BVME6000 */ + /* no parity, 1 stop bit, async, 1:16 */ + { AUX1_CTRL_REG, A1CR_PARITY_NONE|A1CR_MODE_ASYNC_1|A1CR_CLKMODE_x16 }, + /* parity error is special cond, ints disabled, no DMA */ + { INT_AND_DMA_REG, IDR_PARERR_AS_SPCOND | IDR_RX_INT_DISAB }, + /* Rx 8 bits/char, no auto enable, Rx off */ + { RX_CTRL_REG, RCR_CHSIZE_8 }, + /* DTR off, Tx 8 bits/char, RTS off, Tx off */ + { TX_CTRL_REG, TCR_CHSIZE_8 }, + /* special features off */ + { AUX2_CTRL_REG, 0 }, + { CLK_CTRL_REG, CCR_RTxC_XTAL | CCR_RXCLK_BRG | CCR_TXCLK_BRG }, + { DPLL_CTRL_REG, DCR_BRG_ENAB }, + /* Start Rx */ + { RX_CTRL_REG, RCR_RX_ENAB | RCR_CHSIZE_8 }, + /* Start Tx */ + { TX_CTRL_REG, TCR_TX_ENAB | TCR_RTS | TCR_DTR | TCR_CHSIZE_8 }, + /* Ext/Stat ints: DCD only */ + { INT_CTRL_REG, ICR_ENAB_DCD_INT }, + /* Reset Ext/Stat ints */ + { COMMAND_REG, CR_EXTSTAT_RESET }, + /* ...again */ + { COMMAND_REG, CR_EXTSTAT_RESET }, + }; +#endif + if (!(port->gs.port.flags & ASYNC_INITIALIZED)) { + local_irq_save(flags); +#if defined(CONFIG_MVME147_SCC) || defined(CONFIG_MVME162_SCC) + if (MACH_IS_MVME147 || MACH_IS_MVME16x) { + for (i = 0; i < ARRAY_SIZE(mvme_init_tab); ++i) + SCCwrite(mvme_init_tab[i].reg, mvme_init_tab[i].val); + } +#endif +#if defined(CONFIG_BVME6000_SCC) + if (MACH_IS_BVME6000) { + for (i = 0; i < ARRAY_SIZE(bvme_init_tab); ++i) + SCCwrite(bvme_init_tab[i].reg, bvme_init_tab[i].val); + } +#endif + + /* remember status register for detection of DCD and CTS changes */ + scc_last_status_reg[channel] = SCCread(STATUS_REG); + + port->c_dcd = 0; /* Prevent initial 1->0 interrupt */ + scc_setsignals (port, 1,1); + local_irq_restore(flags); + } + + tty->driver_data = port; + port->gs.port.tty = tty; + port->gs.port.count++; + retval = gs_init_port(&port->gs); + if (retval) { + port->gs.port.count--; + return retval; + } + port->gs.port.flags |= GS_ACTIVE; + retval = gs_block_til_ready(port, filp); + + if (retval) { + port->gs.port.count--; + return retval; + } + + port->c_dcd = tty_port_carrier_raised(&port->gs.port); + + scc_enable_rx_interrupts(port); + + return 0; +} + + +static void scc_throttle (struct tty_struct * tty) +{ + struct scc_port *port = tty->driver_data; + unsigned long flags; + SCC_ACCESS_INIT(port); + + if (tty->termios->c_cflag & CRTSCTS) { + local_irq_save(flags); + SCCmod(TX_CTRL_REG, ~TCR_RTS, 0); + local_irq_restore(flags); + } + if (I_IXOFF(tty)) + scc_send_xchar(tty, STOP_CHAR(tty)); +} + + +static void scc_unthrottle (struct tty_struct * tty) +{ + struct scc_port *port = tty->driver_data; + unsigned long flags; + SCC_ACCESS_INIT(port); + + if (tty->termios->c_cflag & CRTSCTS) { + local_irq_save(flags); + SCCmod(TX_CTRL_REG, 0xff, TCR_RTS); + local_irq_restore(flags); + } + if (I_IXOFF(tty)) + scc_send_xchar(tty, START_CHAR(tty)); +} + + +static int scc_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + return -ENOIOCTLCMD; +} + + +static int scc_break_ctl(struct tty_struct *tty, int break_state) +{ + struct scc_port *port = tty->driver_data; + unsigned long flags; + SCC_ACCESS_INIT(port); + + local_irq_save(flags); + SCCmod(TX_CTRL_REG, ~TCR_SEND_BREAK, + break_state ? TCR_SEND_BREAK : 0); + local_irq_restore(flags); + return 0; +} + + +/*--------------------------------------------------------------------------- + * Serial console stuff... + *--------------------------------------------------------------------------*/ + +#define scc_delay() do { __asm__ __volatile__ (" nop; nop"); } while (0) + +static void scc_ch_write (char ch) +{ + volatile char *p = NULL; + +#ifdef CONFIG_MVME147_SCC + if (MACH_IS_MVME147) + p = (volatile char *)M147_SCC_A_ADDR; +#endif +#ifdef CONFIG_MVME162_SCC + if (MACH_IS_MVME16x) + p = (volatile char *)MVME_SCC_A_ADDR; +#endif +#ifdef CONFIG_BVME6000_SCC + if (MACH_IS_BVME6000) + p = (volatile char *)BVME_SCC_A_ADDR; +#endif + + do { + scc_delay(); + } + while (!(*p & 4)); + scc_delay(); + *p = 8; + scc_delay(); + *p = ch; +} + +/* The console must be locked when we get here. */ + +static void scc_console_write (struct console *co, const char *str, unsigned count) +{ + unsigned long flags; + + local_irq_save(flags); + + while (count--) + { + if (*str == '\n') + scc_ch_write ('\r'); + scc_ch_write (*str++); + } + local_irq_restore(flags); +} + +static struct tty_driver *scc_console_device(struct console *c, int *index) +{ + *index = c->index; + return scc_driver; +} + +static struct console sercons = { + .name = "ttyS", + .write = scc_console_write, + .device = scc_console_device, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + + +static int __init vme_scc_console_init(void) +{ + if (vme_brdtype == VME_TYPE_MVME147 || + vme_brdtype == VME_TYPE_MVME162 || + vme_brdtype == VME_TYPE_MVME172 || + vme_brdtype == VME_TYPE_BVME4000 || + vme_brdtype == VME_TYPE_BVME6000) + register_console(&sercons); + return 0; +} +console_initcall(vme_scc_console_init); -- cgit v1.2.3 From 8212a49d1c1e53ad2bc3176b983a2483b48fd989 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 8 Feb 2011 13:55:59 -0800 Subject: USB: xhci: mark local functions as static Functions that are not used outsde of the module they are defined should be marked as static. Signed-off-by: Dmitry Torokhov Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-dbg.c | 4 ++-- drivers/usb/host/xhci-mem.c | 4 ++-- drivers/usb/host/xhci.c | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c index 582937e2132f..0231814a97a5 100644 --- a/drivers/usb/host/xhci-dbg.c +++ b/drivers/usb/host/xhci-dbg.c @@ -450,7 +450,7 @@ char *xhci_get_slot_state(struct xhci_hcd *xhci, } } -void xhci_dbg_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx) +static void xhci_dbg_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx) { /* Fields are 32 bits wide, DMA addresses are in bytes */ int field_size = 32 / 8; @@ -489,7 +489,7 @@ void xhci_dbg_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx) dbg_rsvd64(xhci, (u64 *)slot_ctx, dma); } -void xhci_dbg_ep_ctx(struct xhci_hcd *xhci, +static void xhci_dbg_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int last_ep) { diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index dbb8bcd3919e..a9534396e85b 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -307,7 +307,7 @@ struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, /***************** Streams structures manipulation *************************/ -void xhci_free_stream_ctx(struct xhci_hcd *xhci, +static void xhci_free_stream_ctx(struct xhci_hcd *xhci, unsigned int num_stream_ctxs, struct xhci_stream_ctx *stream_ctx, dma_addr_t dma) { @@ -335,7 +335,7 @@ void xhci_free_stream_ctx(struct xhci_hcd *xhci, * The stream context array must be a power of 2, and can be as small as * 64 bytes or as large as 1MB. */ -struct xhci_stream_ctx *xhci_alloc_stream_ctx(struct xhci_hcd *xhci, +static struct xhci_stream_ctx *xhci_alloc_stream_ctx(struct xhci_hcd *xhci, unsigned int num_stream_ctxs, dma_addr_t *dma, gfp_t mem_flags) { diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 9784880df584..2083fc2179b2 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -109,7 +109,7 @@ int xhci_halt(struct xhci_hcd *xhci) /* * Set the run bit and wait for the host to be running. */ -int xhci_start(struct xhci_hcd *xhci) +static int xhci_start(struct xhci_hcd *xhci) { u32 temp; int ret; @@ -329,7 +329,7 @@ int xhci_init(struct usb_hcd *hcd) #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING -void xhci_event_ring_work(unsigned long arg) +static void xhci_event_ring_work(unsigned long arg) { unsigned long flags; int temp; @@ -857,7 +857,7 @@ unsigned int xhci_last_valid_endpoint(u32 added_ctxs) /* Returns 1 if the arguments are OK; * returns 0 this is a root hub; returns -EINVAL for NULL pointers. */ -int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, +static int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep, int check_ep, bool check_virt_dev, const char *func) { struct xhci_hcd *xhci; @@ -1693,7 +1693,7 @@ static void xhci_setup_input_ctx_for_config_ep(struct xhci_hcd *xhci, xhci_dbg_ctx(xhci, in_ctx, xhci_last_valid_endpoint(add_flags)); } -void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci, +static void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, struct xhci_dequeue_state *deq_state) { -- cgit v1.2.3 From da3564ee027e788a5ff8e520fb2d2b00a78b2464 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Wed, 23 Feb 2011 10:03:12 +0900 Subject: pch_uart: add multi-scatter processing Currently, this driver can handle only single scatterlist. Thus, it can't send data beyond FIFO size. This patch enables this driver can handle multiple scatter list. Signed-off-by: Tomoya MORINAGA Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 117 ++++++++++++++++++++++++++++++++---------- 1 file changed, 89 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 3b2fb93e1fa1..c1386eb255d3 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -226,7 +226,8 @@ struct eg20t_port { struct pch_dma_slave param_rx; struct dma_chan *chan_tx; struct dma_chan *chan_rx; - struct scatterlist sg_tx; + struct scatterlist *sg_tx_p; + int nent; struct scatterlist sg_rx; int tx_dma_use; void *rx_buf_virt; @@ -595,16 +596,20 @@ static void pch_dma_rx_complete(void *arg) struct eg20t_port *priv = arg; struct uart_port *port = &priv->port; struct tty_struct *tty = tty_port_tty_get(&port->state->port); + int count; if (!tty) { pr_debug("%s:tty is busy now", __func__); return; } - if (dma_push_rx(priv, priv->trigger_level)) + dma_sync_sg_for_cpu(port->dev, &priv->sg_rx, 1, DMA_FROM_DEVICE); + count = dma_push_rx(priv, priv->trigger_level); + if (count) tty_flip_buffer_push(tty); - tty_kref_put(tty); + async_tx_ack(priv->desc_rx); + pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT); } static void pch_dma_tx_complete(void *arg) @@ -612,13 +617,21 @@ static void pch_dma_tx_complete(void *arg) struct eg20t_port *priv = arg; struct uart_port *port = &priv->port; struct circ_buf *xmit = &port->state->xmit; + struct scatterlist *sg = priv->sg_tx_p; + int i; - xmit->tail += sg_dma_len(&priv->sg_tx); + for (i = 0; i < priv->nent; i++, sg++) { + xmit->tail += sg_dma_len(sg); + port->icount.tx += sg_dma_len(sg); + } xmit->tail &= UART_XMIT_SIZE - 1; - port->icount.tx += sg_dma_len(&priv->sg_tx); - async_tx_ack(priv->desc_tx); + dma_unmap_sg(port->dev, sg, priv->nent, DMA_TO_DEVICE); priv->tx_dma_use = 0; + priv->nent = 0; + kfree(priv->sg_tx_p); + if (uart_circ_chars_pending(xmit)) + pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_TX_INT); } static int pop_tx(struct eg20t_port *priv, unsigned char *buf, int size) @@ -682,7 +695,7 @@ static int dma_handle_rx(struct eg20t_port *priv) sg_init_table(&priv->sg_rx, 1); /* Initialize SG table */ - sg_dma_len(sg) = priv->fifo_size; + sg_dma_len(sg) = priv->trigger_level; sg_set_page(&priv->sg_rx, virt_to_page(priv->rx_buf_virt), sg_dma_len(sg), (unsigned long)priv->rx_buf_virt & @@ -692,7 +705,8 @@ static int dma_handle_rx(struct eg20t_port *priv) desc = priv->chan_rx->device->device_prep_slave_sg(priv->chan_rx, sg, 1, DMA_FROM_DEVICE, - DMA_PREP_INTERRUPT); + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!desc) return 0; @@ -731,6 +745,9 @@ static unsigned int handle_tx(struct eg20t_port *priv) fifo_size--; } size = min(xmit->head - xmit->tail, fifo_size); + if (size < 0) + size = fifo_size; + tx_size = pop_tx(priv, xmit->buf, size); if (tx_size > 0) { ret = pch_uart_hal_write(priv, xmit->buf, tx_size); @@ -740,8 +757,10 @@ static unsigned int handle_tx(struct eg20t_port *priv) priv->tx_empty = tx_empty; - if (tx_empty) + if (tx_empty) { pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_TX_INT); + uart_write_wakeup(port); + } return PCH_UART_HANDLED_TX_INT; } @@ -750,11 +769,16 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) { struct uart_port *port = &priv->port; struct circ_buf *xmit = &port->state->xmit; - struct scatterlist *sg = &priv->sg_tx; + struct scatterlist *sg; int nent; int fifo_size; int tx_empty; struct dma_async_tx_descriptor *desc; + int num; + int i; + int bytes; + int size; + int rem; if (!priv->start_tx) { pr_info("%s:Tx isn't started. (%lu)\n", __func__, jiffies); @@ -772,37 +796,68 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) fifo_size--; } - pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_TX_INT); + bytes = min((int)CIRC_CNT(xmit->head, xmit->tail, + UART_XMIT_SIZE), CIRC_CNT_TO_END(xmit->head, + xmit->tail, UART_XMIT_SIZE)); + if (!bytes) { + pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_TX_INT); + uart_write_wakeup(port); + return 0; + } + + if (bytes > fifo_size) { + num = bytes / fifo_size + 1; + size = fifo_size; + rem = bytes % fifo_size; + } else { + num = 1; + size = bytes; + rem = bytes; + } priv->tx_dma_use = 1; - sg_init_table(&priv->sg_tx, 1); /* Initialize SG table */ + priv->sg_tx_p = kzalloc(sizeof(struct scatterlist)*num, GFP_ATOMIC); + + sg_init_table(priv->sg_tx_p, num); /* Initialize SG table */ + sg = priv->sg_tx_p; - sg_set_page(&priv->sg_tx, virt_to_page(xmit->buf), - UART_XMIT_SIZE, (int)xmit->buf & ~PAGE_MASK); + for (i = 0; i < num; i++, sg++) { + if (i == (num - 1)) + sg_set_page(sg, virt_to_page(xmit->buf), + rem, fifo_size * i); + else + sg_set_page(sg, virt_to_page(xmit->buf), + size, fifo_size * i); + } - nent = dma_map_sg(port->dev, &priv->sg_tx, 1, DMA_TO_DEVICE); + sg = priv->sg_tx_p; + nent = dma_map_sg(port->dev, sg, num, DMA_TO_DEVICE); if (!nent) { pr_err("%s:dma_map_sg Failed\n", __func__); return 0; } - - sg->offset = xmit->tail & (UART_XMIT_SIZE - 1); - sg_dma_address(sg) = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) + - sg->offset; - sg_dma_len(sg) = min((int)CIRC_CNT(xmit->head, xmit->tail, - UART_XMIT_SIZE), CIRC_CNT_TO_END(xmit->head, - xmit->tail, UART_XMIT_SIZE)); + priv->nent = nent; + + for (i = 0; i < nent; i++, sg++) { + sg->offset = (xmit->tail & (UART_XMIT_SIZE - 1)) + + fifo_size * i; + sg_dma_address(sg) = (sg_dma_address(sg) & + ~(UART_XMIT_SIZE - 1)) + sg->offset; + if (i == (nent - 1)) + sg_dma_len(sg) = rem; + else + sg_dma_len(sg) = size; + } desc = priv->chan_tx->device->device_prep_slave_sg(priv->chan_tx, - sg, nent, DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + priv->sg_tx_p, nent, DMA_TO_DEVICE, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc) { pr_err("%s:device_prep_slave_sg Failed\n", __func__); return 0; } - - dma_sync_sg_for_device(port->dev, sg, 1, DMA_TO_DEVICE); - + dma_sync_sg_for_device(port->dev, priv->sg_tx_p, nent, DMA_TO_DEVICE); priv->desc_tx = desc; desc->callback = pch_dma_tx_complete; desc->callback_param = priv; @@ -857,10 +912,16 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) } break; case PCH_UART_IID_RDR: /* Received Data Ready */ - if (priv->use_dma) + if (priv->use_dma) { + pch_uart_hal_disable_interrupt(priv, + PCH_UART_HAL_RX_INT); ret = dma_handle_rx(priv); - else + if (!ret) + pch_uart_hal_enable_interrupt(priv, + PCH_UART_HAL_RX_INT); + } else { ret = handle_rx(priv); + } break; case PCH_UART_IID_RDR_TO: /* Received Data Ready (FIFO Timeout) */ -- cgit v1.2.3 From 7e4613296576c843643ceb97091d98da1e8caab8 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Wed, 23 Feb 2011 10:03:13 +0900 Subject: pch_uart: add spin_lock_init Currently, spin_lock is not initialized. Thus, add spin_lock_init(). Signed-off-by: Tomoya MORINAGA Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index c1386eb255d3..9e1b8652de7f 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -1370,6 +1370,8 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, priv->port.line = num++; priv->trigger = PCH_UART_HAL_TRIGGER_M; + spin_lock_init(&priv->port.lock); + pci_set_drvdata(pdev, priv); pch_uart_hal_request(pdev, fifosize, base_baud); -- cgit v1.2.3 From 1822076cf324dde1eb9678ae2174dc8b4662417c Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Wed, 23 Feb 2011 10:03:14 +0900 Subject: pch_uart : Reduce memcpy Reduce memcpy for performance improvement. Signed-off-by: Tomoya MORINAGA Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 9e1b8652de7f..0e171b8f0700 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -390,7 +390,7 @@ static u8 pch_uart_hal_get_modem(struct eg20t_port *priv) return get_msr(priv, priv->membase); } -static int pch_uart_hal_write(struct eg20t_port *priv, +static void pch_uart_hal_write(struct eg20t_port *priv, const unsigned char *buf, int tx_size) { int i; @@ -400,7 +400,6 @@ static int pch_uart_hal_write(struct eg20t_port *priv, thr = buf[i++]; iowrite8(thr, priv->membase + PCH_UART_THR); } - return i; } static int pch_uart_hal_read(struct eg20t_port *priv, unsigned char *buf, @@ -634,7 +633,7 @@ static void pch_dma_tx_complete(void *arg) pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_TX_INT); } -static int pop_tx(struct eg20t_port *priv, unsigned char *buf, int size) +static int pop_tx(struct eg20t_port *priv, int size) { int count = 0; struct uart_port *port = &priv->port; @@ -647,7 +646,7 @@ static int pop_tx(struct eg20t_port *priv, unsigned char *buf, int size) int cnt_to_end = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); int sz = min(size - count, cnt_to_end); - memcpy(&buf[count], &xmit->buf[xmit->tail], sz); + pch_uart_hal_write(priv, &xmit->buf[xmit->tail], sz); xmit->tail = (xmit->tail + sz) & (UART_XMIT_SIZE - 1); count += sz; } while (!uart_circ_empty(xmit) && count < size); @@ -723,7 +722,6 @@ static unsigned int handle_tx(struct eg20t_port *priv) { struct uart_port *port = &priv->port; struct circ_buf *xmit = &port->state->xmit; - int ret; int fifo_size; int tx_size; int size; @@ -748,10 +746,9 @@ static unsigned int handle_tx(struct eg20t_port *priv) if (size < 0) size = fifo_size; - tx_size = pop_tx(priv, xmit->buf, size); + tx_size = pop_tx(priv, size); if (tx_size > 0) { - ret = pch_uart_hal_write(priv, xmit->buf, tx_size); - port->icount.tx += ret; + port->icount.tx += tx_size; tx_empty = 0; } -- cgit v1.2.3 From 23877fdc6df3306037d81d2ac71c2d6e26ec08f4 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Wed, 23 Feb 2011 10:03:15 +0900 Subject: pch_uart : Use dev_xxx not pr_xxx For easy to understad which port the message is out, replace pr_xxx with dev_xxx. Signed-off-by: Tomoya MORINAGA Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 77 +++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 0e171b8f0700..68855351c76e 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -282,7 +282,7 @@ static int pch_uart_hal_set_line(struct eg20t_port *priv, int baud, div = DIV_ROUND(priv->base_baud / 16, baud); if (div < 0 || USHRT_MAX <= div) { - pr_err("Invalid Baud(div=0x%x)\n", div); + dev_err(priv->port.dev, "Invalid Baud(div=0x%x)\n", div); return -EINVAL; } @@ -290,17 +290,17 @@ static int pch_uart_hal_set_line(struct eg20t_port *priv, int baud, dlm = ((unsigned int)div >> 8) & 0x00FFU; if (parity & ~(PCH_UART_LCR_PEN | PCH_UART_LCR_EPS | PCH_UART_LCR_SP)) { - pr_err("Invalid parity(0x%x)\n", parity); + dev_err(priv->port.dev, "Invalid parity(0x%x)\n", parity); return -EINVAL; } if (bits & ~PCH_UART_LCR_WLS) { - pr_err("Invalid bits(0x%x)\n", bits); + dev_err(priv->port.dev, "Invalid bits(0x%x)\n", bits); return -EINVAL; } if (stb & ~PCH_UART_LCR_STB) { - pr_err("Invalid STB(0x%x)\n", stb); + dev_err(priv->port.dev, "Invalid STB(0x%x)\n", stb); return -EINVAL; } @@ -308,7 +308,7 @@ static int pch_uart_hal_set_line(struct eg20t_port *priv, int baud, lcr |= bits; lcr |= stb; - pr_debug("%s:baud = %d, div = %04x, lcr = %02x (%lu)\n", + dev_dbg(priv->port.dev, "%s:baud = %d, div = %04x, lcr = %02x (%lu)\n", __func__, baud, div, lcr, jiffies); iowrite8(PCH_UART_LCR_DLAB, priv->membase + UART_LCR); iowrite8(dll, priv->membase + PCH_UART_DLL); @@ -322,7 +322,8 @@ static int pch_uart_hal_fifo_reset(struct eg20t_port *priv, unsigned int flag) { if (flag & ~(PCH_UART_FCR_TFR | PCH_UART_FCR_RFR)) { - pr_err("%s:Invalid flag(0x%x)\n", __func__, flag); + dev_err(priv->port.dev, "%s:Invalid flag(0x%x)\n", + __func__, flag); return -EINVAL; } @@ -341,17 +342,20 @@ static int pch_uart_hal_set_fifo(struct eg20t_port *priv, u8 fcr; if (dmamode & ~PCH_UART_FCR_DMS) { - pr_err("%s:Invalid DMA Mode(0x%x)\n", __func__, dmamode); + dev_err(priv->port.dev, "%s:Invalid DMA Mode(0x%x)\n", + __func__, dmamode); return -EINVAL; } if (fifo_size & ~(PCH_UART_FCR_FIFOE | PCH_UART_FCR_FIFO256)) { - pr_err("%s:Invalid FIFO SIZE(0x%x)\n", __func__, fifo_size); + dev_err(priv->port.dev, "%s:Invalid FIFO SIZE(0x%x)\n", + __func__, fifo_size); return -EINVAL; } if (trigger & ~PCH_UART_FCR_RFTL) { - pr_err("%s:Invalid TRIGGER(0x%x)\n", __func__, trigger); + dev_err(priv->port.dev, "%s:Invalid TRIGGER(0x%x)\n", + __func__, trigger); return -EINVAL; } @@ -455,7 +459,7 @@ static int push_rx(struct eg20t_port *priv, const unsigned char *buf, port = &priv->port; tty = tty_port_tty_get(&port->state->port); if (!tty) { - pr_debug("%s:tty is busy now", __func__); + dev_dbg(priv->port.dev, "%s:tty is busy now", __func__); return -EBUSY; } @@ -472,8 +476,8 @@ static int pop_tx_x(struct eg20t_port *priv, unsigned char *buf) struct uart_port *port = &priv->port; if (port->x_char) { - pr_debug("%s:X character send %02x (%lu)\n", __func__, - port->x_char, jiffies); + dev_dbg(priv->port.dev, "%s:X character send %02x (%lu)\n", + __func__, port->x_char, jiffies); buf[0] = port->x_char; port->x_char = 0; ret = 1; @@ -493,7 +497,7 @@ static int dma_push_rx(struct eg20t_port *priv, int size) port = &priv->port; tty = tty_port_tty_get(&port->state->port); if (!tty) { - pr_debug("%s:tty is busy now", __func__); + dev_dbg(priv->port.dev, "%s:tty is busy now", __func__); return 0; } @@ -567,7 +571,8 @@ static void pch_request_dma(struct uart_port *port) param->tx_reg = port->mapbase + UART_TX; chan = dma_request_channel(mask, filter, param); if (!chan) { - pr_err("%s:dma_request_channel FAILS(Tx)\n", __func__); + dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Tx)\n", + __func__); return; } priv->chan_tx = chan; @@ -579,7 +584,8 @@ static void pch_request_dma(struct uart_port *port) param->rx_reg = port->mapbase + UART_RX; chan = dma_request_channel(mask, filter, param); if (!chan) { - pr_err("%s:dma_request_channel FAILS(Rx)\n", __func__); + dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Rx)\n", + __func__); dma_release_channel(priv->chan_tx); return; } @@ -598,7 +604,7 @@ static void pch_dma_rx_complete(void *arg) int count; if (!tty) { - pr_debug("%s:tty is busy now", __func__); + dev_dbg(priv->port.dev, "%s:tty is busy now", __func__); return; } @@ -652,7 +658,7 @@ static int pop_tx(struct eg20t_port *priv, int size) } while (!uart_circ_empty(xmit) && count < size); pop_tx_end: - pr_debug("%d characters. Remained %d characters. (%lu)\n", + dev_dbg(priv->port.dev, "%d characters. Remained %d characters.(%lu)\n", count, size - count, jiffies); return count; @@ -728,7 +734,8 @@ static unsigned int handle_tx(struct eg20t_port *priv) int tx_empty; if (!priv->start_tx) { - pr_info("%s:Tx isn't started. (%lu)\n", __func__, jiffies); + dev_info(priv->port.dev, "%s:Tx isn't started. (%lu)\n", + __func__, jiffies); pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_TX_INT); priv->tx_empty = 1; return 0; @@ -778,7 +785,8 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) int rem; if (!priv->start_tx) { - pr_info("%s:Tx isn't started. (%lu)\n", __func__, jiffies); + dev_info(priv->port.dev, "%s:Tx isn't started. (%lu)\n", + __func__, jiffies); pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_TX_INT); priv->tx_empty = 1; return 0; @@ -797,6 +805,7 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) UART_XMIT_SIZE), CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE)); if (!bytes) { + dev_dbg(priv->port.dev, "%s 0 bytes return\n", __func__); pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_TX_INT); uart_write_wakeup(port); return 0; @@ -812,6 +821,9 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) rem = bytes; } + dev_dbg(priv->port.dev, "%s num=%d size=%d rem=%d\n", + __func__, num, size, rem); + priv->tx_dma_use = 1; priv->sg_tx_p = kzalloc(sizeof(struct scatterlist)*num, GFP_ATOMIC); @@ -831,7 +843,7 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) sg = priv->sg_tx_p; nent = dma_map_sg(port->dev, sg, num, DMA_TO_DEVICE); if (!nent) { - pr_err("%s:dma_map_sg Failed\n", __func__); + dev_err(priv->port.dev, "%s:dma_map_sg Failed\n", __func__); return 0; } priv->nent = nent; @@ -851,7 +863,8 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) priv->sg_tx_p, nent, DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc) { - pr_err("%s:device_prep_slave_sg Failed\n", __func__); + dev_err(priv->port.dev, "%s:device_prep_slave_sg Failed\n", + __func__); return 0; } dma_sync_sg_for_device(port->dev, priv->sg_tx_p, nent, DMA_TO_DEVICE); @@ -935,7 +948,8 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) ret = PCH_UART_HANDLED_MS_INT; break; default: /* Never junp to this label */ - pr_err("%s:iid=%d (%lu)\n", __func__, iid, jiffies); + dev_err(priv->port.dev, "%s:iid=%d (%lu)\n", __func__, + iid, jiffies); ret = -1; break; } @@ -1024,9 +1038,13 @@ static void pch_uart_start_tx(struct uart_port *port) priv = container_of(port, struct eg20t_port, port); - if (priv->use_dma) - if (priv->tx_dma_use) + if (priv->use_dma) { + if (priv->tx_dma_use) { + dev_dbg(priv->port.dev, "%s : Tx DMA is NOT empty.\n", + __func__); return; + } + } priv->start_tx = 1; pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_TX_INT); @@ -1142,7 +1160,8 @@ static void pch_uart_shutdown(struct uart_port *port) ret = pch_uart_hal_set_fifo(priv, PCH_UART_HAL_DMA_MODE0, PCH_UART_HAL_FIFO_DIS, PCH_UART_HAL_TRIGGER1); if (ret) - pr_err("pch_uart_hal_set_fifo Failed(ret=%d)\n", ret); + dev_err(priv->port.dev, + "pch_uart_hal_set_fifo Failed(ret=%d)\n", ret); if (priv->use_dma_flag) pch_free_dma(port); @@ -1263,17 +1282,19 @@ static int pch_uart_verify_port(struct uart_port *port, priv = container_of(port, struct eg20t_port, port); if (serinfo->flags & UPF_LOW_LATENCY) { - pr_info("PCH UART : Use PIO Mode (without DMA)\n"); + dev_info(priv->port.dev, + "PCH UART : Use PIO Mode (without DMA)\n"); priv->use_dma = 0; serinfo->flags &= ~UPF_LOW_LATENCY; } else { #ifndef CONFIG_PCH_DMA - pr_err("%s : PCH DMA is not Loaded.\n", __func__); + dev_err(priv->port.dev, "%s : PCH DMA is not Loaded.\n", + __func__); return -EOPNOTSUPP; #endif priv->use_dma = 1; priv->use_dma_flag = 1; - pr_info("PCH UART : Use DMA Mode\n"); + dev_info(priv->port.dev, "PCH UART : Use DMA Mode\n"); } return 0; -- cgit v1.2.3 From aac6c0b0fd6458f166651fc102695fb8836a4d95 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Wed, 23 Feb 2011 10:03:16 +0900 Subject: pch_uart: fix uart clock setting issue Currently, uart clock is not set correctly. This patch fixes the issue. Signed-off-by: Tomoya MORINAGA Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 68855351c76e..189886122516 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -1089,7 +1089,12 @@ static int pch_uart_startup(struct uart_port *port) priv = container_of(port, struct eg20t_port, port); priv->tx_empty = 1; - port->uartclk = priv->base_baud; + + if (port->uartclk) + priv->base_baud = port->uartclk; + else + port->uartclk = priv->base_baud; + pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_ALL_INT); ret = pch_uart_hal_set_line(priv, default_baud, PCH_UART_HAL_PARITY_NONE, PCH_UART_HAL_8BIT, -- cgit v1.2.3 From 9af7155bb03675ba2d4d68428a4345e0511ce8dd Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Wed, 23 Feb 2011 10:03:17 +0900 Subject: pch_uart: fix auto flow control miss-setting issue Currently, auto-flow control setting processing is not set correctly. This patch fixes the issue. Signed-off-by: Tomoya MORINAGA Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 189886122516..0c95051fa0a4 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -218,6 +218,7 @@ struct eg20t_port { struct pch_uart_buffer rxbuf; unsigned int dmsr; unsigned int fcr; + unsigned int mcr; unsigned int use_dma; unsigned int use_dma_flag; struct dma_async_tx_descriptor *desc_tx; @@ -1007,7 +1008,6 @@ static unsigned int pch_uart_get_mctrl(struct uart_port *port) static void pch_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) { u32 mcr = 0; - unsigned int dat; struct eg20t_port *priv = container_of(port, struct eg20t_port, port); if (mctrl & TIOCM_DTR) @@ -1017,11 +1017,11 @@ static void pch_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) if (mctrl & TIOCM_LOOP) mcr |= UART_MCR_LOOP; - if (mctrl) { - dat = pch_uart_get_mctrl(port); - dat |= mcr; - iowrite8(dat, priv->membase + UART_MCR); - } + if (priv->mcr & UART_MCR_AFE) + mcr |= UART_MCR_AFE; + + if (mctrl) + iowrite8(mcr, priv->membase + UART_MCR); } static void pch_uart_stop_tx(struct uart_port *port) @@ -1215,6 +1215,13 @@ static void pch_uart_set_termios(struct uart_port *port, } else { parity = PCH_UART_HAL_PARITY_NONE; } + + /* Only UART0 has auto hardware flow function */ + if ((termios->c_cflag & CRTSCTS) && (priv->fifo_size == 256)) + priv->mcr |= UART_MCR_AFE; + else + priv->mcr &= ~UART_MCR_AFE; + termios->c_cflag &= ~CMSPAR; /* Mark/Space parity is not supported */ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); -- cgit v1.2.3 From 60d1031e114a3e96e4420421e34ddc0dcd10cbae Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Wed, 23 Feb 2011 10:03:18 +0900 Subject: pch_uart: fix exclusive access issue Signed-off-by: Tomoya MORINAGA Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 0c95051fa0a4..da0ba0fa2b99 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -636,8 +636,7 @@ static void pch_dma_tx_complete(void *arg) priv->tx_dma_use = 0; priv->nent = 0; kfree(priv->sg_tx_p); - if (uart_circ_chars_pending(xmit)) - pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_TX_INT); + pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_TX_INT); } static int pop_tx(struct eg20t_port *priv, int size) @@ -793,6 +792,14 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) return 0; } + if (priv->tx_dma_use) { + dev_dbg(priv->port.dev, "%s:Tx is not completed. (%lu)\n", + __func__, jiffies); + pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_TX_INT); + priv->tx_empty = 1; + return 0; + } + fifo_size = max(priv->fifo_size, 1); tx_empty = 1; if (pop_tx_x(priv, xmit->buf)) { -- cgit v1.2.3 From fec38d1752c01ad72789bac9f1a128f7e933735d Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Wed, 23 Feb 2011 10:03:19 +0900 Subject: pch_uart: Fix DMA channel miss-setting issue. Signed-off-by: Tomoya MORINAGA Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 59 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index da0ba0fa2b99..a5ce9a5c018d 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -235,6 +235,36 @@ struct eg20t_port { dma_addr_t rx_buf_dma; }; +/** + * struct pch_uart_driver_data - private data structure for UART-DMA + * @port_type: The number of DMA channel + * @line_no: UART port line number (0, 1, 2...) + */ +struct pch_uart_driver_data { + int port_type; + int line_no; +}; + +enum pch_uart_num_t { + pch_et20t_uart0 = 0, + pch_et20t_uart1, + pch_et20t_uart2, + pch_et20t_uart3, + pch_ml7213_uart0, + pch_ml7213_uart1, + pch_ml7213_uart2, +}; + +static struct pch_uart_driver_data drv_dat[] = { + [pch_et20t_uart0] = {PCH_UART_8LINE, 0}, + [pch_et20t_uart1] = {PCH_UART_2LINE, 1}, + [pch_et20t_uart2] = {PCH_UART_2LINE, 2}, + [pch_et20t_uart3] = {PCH_UART_2LINE, 3}, + [pch_ml7213_uart0] = {PCH_UART_8LINE, 0}, + [pch_ml7213_uart1] = {PCH_UART_2LINE, 1}, + [pch_ml7213_uart2] = {PCH_UART_2LINE, 2}, +}; + static unsigned int default_baud = 9600; static const int trigger_level_256[4] = { 1, 64, 128, 224 }; static const int trigger_level_64[4] = { 1, 16, 32, 56 }; @@ -568,7 +598,8 @@ static void pch_request_dma(struct uart_port *port) /* Set Tx DMA */ param = &priv->param_tx; param->dma_dev = &dma_dev->dev; - param->chan_id = priv->port.line; + param->chan_id = priv->port.line * 2; /* Tx = 0, 2, 4, ... */ + param->tx_reg = port->mapbase + UART_TX; chan = dma_request_channel(mask, filter, param); if (!chan) { @@ -581,7 +612,8 @@ static void pch_request_dma(struct uart_port *port) /* Set Rx DMA */ param = &priv->param_rx; param->dma_dev = &dma_dev->dev; - param->chan_id = priv->port.line + 1; /* Rx = Tx + 1 */ + param->chan_id = priv->port.line * 2 + 1; /* Rx = Tx + 1 */ + param->rx_reg = port->mapbase + UART_RX; chan = dma_request_channel(mask, filter, param); if (!chan) { @@ -1358,8 +1390,11 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, unsigned int mapbase; unsigned char *rxbuf; int fifosize, base_baud; - static int num; - int port_type = id->driver_data; + int port_type; + struct pch_uart_driver_data *board; + + board = &drv_dat[id->driver_data]; + port_type = board->port_type; priv = kzalloc(sizeof(struct eg20t_port), GFP_KERNEL); if (priv == NULL) @@ -1404,7 +1439,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, priv->port.ops = &pch_uart_ops; priv->port.flags = UPF_BOOT_AUTOCONF; priv->port.fifosize = fifosize; - priv->port.line = num++; + priv->port.line = board->line_no; priv->trigger = PCH_UART_HAL_TRIGGER_M; spin_lock_init(&priv->port.lock); @@ -1482,19 +1517,19 @@ static int pch_uart_pci_resume(struct pci_dev *pdev) static DEFINE_PCI_DEVICE_TABLE(pch_uart_pci_id) = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8811), - .driver_data = PCH_UART_8LINE}, + .driver_data = pch_et20t_uart0}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8812), - .driver_data = PCH_UART_2LINE}, + .driver_data = pch_et20t_uart1}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8813), - .driver_data = PCH_UART_2LINE}, + .driver_data = pch_et20t_uart2}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8814), - .driver_data = PCH_UART_2LINE}, + .driver_data = pch_et20t_uart3}, {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8027), - .driver_data = PCH_UART_8LINE}, + .driver_data = pch_ml7213_uart0}, {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8028), - .driver_data = PCH_UART_2LINE}, + .driver_data = pch_ml7213_uart1}, {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8029), - .driver_data = PCH_UART_2LINE}, + .driver_data = pch_ml7213_uart2}, {0,}, }; -- cgit v1.2.3 From 49495d44dfa4ba76cf7d1ed8fe84746dd9552255 Mon Sep 17 00:00:00 2001 From: Florian Mickler Date: Mon, 7 Feb 2011 23:29:31 +0100 Subject: amd64-agp: fix crash at second module load The module forgot to sometimes unregister some resources. This fixes Bug #22882. [Patch updated to 2.6.38-rc3 by Randy Dunlap.] Tested-by: Randy Dunlap Signed-off-by: Florian Mickler Signed-off-by: Dave Airlie --- drivers/char/agp/amd64-agp.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 9252e85706ef..780498d76581 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c @@ -773,18 +773,23 @@ int __init agp_amd64_init(void) #else printk(KERN_INFO PFX "You can boot with agp=try_unsupported\n"); #endif + pci_unregister_driver(&agp_amd64_pci_driver); return -ENODEV; } /* First check that we have at least one AMD64 NB */ - if (!pci_dev_present(amd_nb_misc_ids)) + if (!pci_dev_present(amd_nb_misc_ids)) { + pci_unregister_driver(&agp_amd64_pci_driver); return -ENODEV; + } /* Look for any AGP bridge */ agp_amd64_pci_driver.id_table = agp_amd64_pci_promisc_table; err = driver_attach(&agp_amd64_pci_driver.driver); - if (err == 0 && agp_bridges_found == 0) + if (err == 0 && agp_bridges_found == 0) { + pci_unregister_driver(&agp_amd64_pci_driver); err = -ENODEV; + } } return err; } -- cgit v1.2.3 From 02ad2d9080266e6d999c00b78610ef6a45be45ea Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 23 Feb 2011 00:27:06 +0200 Subject: wl12xx: use standard ALIGN() macro Use the standard ALIGN() macro instead of redefining similar macros. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/rx.h | 4 ---- drivers/net/wireless/wl12xx/tx.c | 4 ++-- drivers/net/wireless/wl12xx/tx.h | 2 -- 3 files changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/rx.h b/drivers/net/wireless/wl12xx/rx.h index 4cef8fa3dee1..75fabf836491 100644 --- a/drivers/net/wireless/wl12xx/rx.h +++ b/drivers/net/wireless/wl12xx/rx.h @@ -30,10 +30,6 @@ #define WL1271_RX_MAX_RSSI -30 #define WL1271_RX_MIN_RSSI -95 -#define WL1271_RX_ALIGN_TO 4 -#define WL1271_RX_ALIGN(len) (((len) + WL1271_RX_ALIGN_TO - 1) & \ - ~(WL1271_RX_ALIGN_TO - 1)) - #define SHORT_PREAMBLE_BIT BIT(0) #define OFDM_RATE_BIT BIT(6) #define PBCC_RATE_BIT BIT(7) diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 67a00946e3dd..94ff3faf7dde 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -185,7 +185,7 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, desc->reserved = 0; /* align the length (and store in terms of words) */ - pad = WL1271_TX_ALIGN(skb->len); + pad = ALIGN(skb->len, WL1271_TX_ALIGN_TO); desc->length = cpu_to_le16(pad >> 2); /* calculate number of padding bytes */ @@ -245,7 +245,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, * pad the skb data to make sure its length is aligned. * The number of padding bytes is computed and set in wl1271_tx_fill_hdr */ - total_len = WL1271_TX_ALIGN(skb->len); + total_len = ALIGN(skb->len, WL1271_TX_ALIGN_TO); memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len); memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len); diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h index 05722a560d91..db88f58707a3 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h @@ -53,8 +53,6 @@ #define TX_HW_RESULT_QUEUE_LEN_MASK 0xf #define WL1271_TX_ALIGN_TO 4 -#define WL1271_TX_ALIGN(len) (((len) + WL1271_TX_ALIGN_TO - 1) & \ - ~(WL1271_TX_ALIGN_TO - 1)) #define WL1271_TKIP_IV_SPACE 4 struct wl1271_tx_hw_descr { -- cgit v1.2.3 From 6dc9fb3c78a78982f6418b6cf457140f7afa658d Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 23 Feb 2011 00:27:07 +0200 Subject: wl12xx: always set mac_address when configuring ht caps The mac_address should be set also when ht caps are disabled. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index 33840d95d17d..6d5312990f79 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -1328,10 +1328,9 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl, /* get data from A-MPDU parameters field */ acx->ampdu_max_length = ht_cap->ampdu_factor; acx->ampdu_min_spacing = ht_cap->ampdu_density; - - memcpy(acx->mac_address, mac_address, ETH_ALEN); } + memcpy(acx->mac_address, mac_address, ETH_ALEN); acx->ht_capabilites = cpu_to_le32(ht_capabilites); ret = wl1271_cmd_configure(wl, ACX_PEER_HT_CAP, acx, sizeof(*acx)); -- cgit v1.2.3 From f4d08ddd3e60c79a141be36a5f3a7294c619291d Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 23 Feb 2011 00:22:24 +0200 Subject: wl12xx: fix potential race condition with TX queue watermark Check the conditions for the high/low TX queue watermarks when the spin-lock is taken. This prevents race conditions as tx_queue_count and the flag checked are only modified when the spin-lock is taken. The following race was in mind: - Queues are almost full and wl1271_op_tx() will stop the queues, but it doesn't get the spin-lock yet. - (on another CPU) tx_work_locked() dequeues 15 skbs from this queue and tx_queue_count is updated to reflect this - wl1271_op_tx() does not check tx_queue_count after taking the spin-lock and incorrectly stops the queue. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 13c7102f9864..9bb9ad31c2f5 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -987,6 +987,17 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) spin_lock_irqsave(&wl->wl_lock, flags); wl->tx_queue_count++; + + /* + * The workqueue is slow to process the tx_queue and we need stop + * the queue here, otherwise the queue will get too long. + */ + if (wl->tx_queue_count >= WL1271_TX_QUEUE_HIGH_WATERMARK) { + wl1271_debug(DEBUG_TX, "op_tx: stopping queues"); + ieee80211_stop_queues(wl->hw); + set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); + } + spin_unlock_irqrestore(&wl->wl_lock, flags); /* queue the packet */ @@ -1001,19 +1012,6 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags)) ieee80211_queue_work(wl->hw, &wl->tx_work); - /* - * The workqueue is slow to process the tx_queue and we need stop - * the queue here, otherwise the queue will get too long. - */ - if (wl->tx_queue_count >= WL1271_TX_QUEUE_HIGH_WATERMARK) { - wl1271_debug(DEBUG_TX, "op_tx: stopping queues"); - - spin_lock_irqsave(&wl->wl_lock, flags); - ieee80211_stop_queues(wl->hw); - set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); - spin_unlock_irqrestore(&wl->wl_lock, flags); - } - return NETDEV_TX_OK; } -- cgit v1.2.3 From 99a2775d02a7accf4cc661a65c76fd7b379d1c7a Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 23 Feb 2011 00:22:25 +0200 Subject: wl12xx: AP-mode - fix race condition on sta connection If a sta starts transmitting immediately after authentication, sometimes the FW deauthenticates it. Fix this by marking the sta "in-connection" in FW before sending the autentication response. The "in-connection" entry is automatically removed when connection succeeds or after a timeout. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 25 +++++++++++++++++++++++++ drivers/net/wireless/wl12xx/acx.h | 9 +++++++++ drivers/net/wireless/wl12xx/tx.c | 19 +++++++++++++++++++ 3 files changed, 53 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index 6d5312990f79..3badc6bb7866 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -1541,3 +1541,28 @@ out: kfree(config_ps); return ret; } + +int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr) +{ + struct wl1271_acx_inconnection_sta *acx = NULL; + int ret; + + wl1271_debug(DEBUG_ACX, "acx set inconnaction sta %pM", addr); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) + return -ENOMEM; + + memcpy(acx->addr, addr, ETH_ALEN); + + ret = wl1271_cmd_configure(wl, ACX_UPDATE_INCONNECTION_STA_LIST, + acx, sizeof(*acx)); + if (ret < 0) { + wl1271_warning("acx set inconnaction sta failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; +} diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index 4e301de916bb..dd19b01d807b 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h @@ -1155,6 +1155,13 @@ struct wl1271_acx_config_ps { __le32 null_data_rate; } __packed; +struct wl1271_acx_inconnection_sta { + struct acx_header header; + + u8 addr[ETH_ALEN]; + u8 padding1[2]; +} __packed; + enum { ACX_WAKE_UP_CONDITIONS = 0x0002, ACX_MEM_CFG = 0x0003, @@ -1215,6 +1222,7 @@ enum { ACX_GEN_FW_CMD = 0x0070, ACX_HOST_IF_CFG_BITMAP = 0x0071, ACX_MAX_TX_FAILURE = 0x0072, + ACX_UPDATE_INCONNECTION_STA_LIST = 0x0073, DOT11_RX_MSDU_LIFE_TIME = 0x1004, DOT11_CUR_TX_PWR = 0x100D, DOT11_RX_DOT11_MODE = 0x1012, @@ -1290,5 +1298,6 @@ int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn, int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); int wl1271_acx_max_tx_retry(struct wl1271 *wl); int wl1271_acx_config_ps(struct wl1271 *wl); +int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr); #endif /* __WL1271_ACX_H__ */ diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 94ff3faf7dde..0bb57daac889 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -70,6 +70,22 @@ static void wl1271_free_tx_id(struct wl1271 *wl, int id) } } +static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl, + struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr; + + /* + * add the station to the known list before transmitting the + * authentication response. this way it won't get de-authed by FW + * when transmitting too soon. + */ + hdr = (struct ieee80211_hdr *)(skb->data + + sizeof(struct wl1271_tx_hw_descr)); + if (ieee80211_is_auth(hdr->frame_control)) + wl1271_acx_set_inconnection_sta(wl, hdr->addr1); +} + static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, u32 buf_offset) { @@ -238,6 +254,9 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, if (ret < 0) return ret; + if (wl->bss_type == BSS_TYPE_AP_BSS) + wl1271_tx_ap_update_inconnection_sta(wl, skb); + wl1271_tx_fill_hdr(wl, skb, extra, info); /* -- cgit v1.2.3 From a8c0ddb5ba2889e1e11a033ccbadfc600f236a91 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 23 Feb 2011 00:22:26 +0200 Subject: wl12xx: AP-mode - TX queue per link in AC When operating in AP-mode we require a per link tx-queue. This allows us to implement HW assisted PS mode for links, as well as regulate per-link FW TX blocks consumption. Split each link into ACs to support future QoS for AP-mode. AC queues are emptied in priority and per-link queues are scheduled in a simple round-robin fashion. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 17 ++++- drivers/net/wireless/wl12xx/tx.c | 130 ++++++++++++++++++++++++++++++++--- drivers/net/wireless/wl12xx/tx.h | 3 + drivers/net/wireless/wl12xx/wl12xx.h | 14 ++++ 4 files changed, 151 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 9bb9ad31c2f5..3a4f6069be60 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -984,6 +984,7 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) struct wl1271 *wl = hw->priv; unsigned long flags; int q; + u8 hlid = 0; spin_lock_irqsave(&wl->wl_lock, flags); wl->tx_queue_count++; @@ -1002,7 +1003,13 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) /* queue the packet */ q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); - skb_queue_tail(&wl->tx_queue[q], skb); + if (wl->bss_type == BSS_TYPE_AP_BSS) { + hlid = wl1271_tx_get_hlid(skb); + wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d", hlid, q); + skb_queue_tail(&wl->links[hlid].tx_queue[q], skb); + } else { + skb_queue_tail(&wl->tx_queue[q], skb); + } /* * The chip specific setup must run before the first TX packet - @@ -2643,6 +2650,7 @@ static void wl1271_free_hlid(struct wl1271 *wl, u8 hlid) int id = hlid - WL1271_AP_STA_HLID_START; __clear_bit(id, wl->ap_hlid_map); + wl1271_tx_reset_link_queues(wl, hlid); } static int wl1271_op_sta_add(struct ieee80211_hw *hw, @@ -3270,7 +3278,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void) struct ieee80211_hw *hw; struct platform_device *plat_dev = NULL; struct wl1271 *wl; - int i, ret; + int i, j, ret; unsigned int order; hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); @@ -3298,6 +3306,10 @@ struct ieee80211_hw *wl1271_alloc_hw(void) for (i = 0; i < NUM_TX_QUEUES; i++) skb_queue_head_init(&wl->tx_queue[i]); + for (i = 0; i < NUM_TX_QUEUES; i++) + for (j = 0; j < AP_MAX_LINKS; j++) + skb_queue_head_init(&wl->links[j].tx_queue[i]); + INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work); INIT_WORK(&wl->irq_work, wl1271_irq_work); @@ -3323,6 +3335,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void) wl->bss_type = MAX_BSS_TYPE; wl->set_bss_type = MAX_BSS_TYPE; wl->fw_bss_type = MAX_BSS_TYPE; + wl->last_tx_hlid = 0; memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); for (i = 0; i < ACX_TX_DESCRIPTORS; i++) diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 0bb57daac889..8c769500ec5d 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -86,6 +86,27 @@ static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl, wl1271_acx_set_inconnection_sta(wl, hdr->addr1); } +u8 wl1271_tx_get_hlid(struct sk_buff *skb) +{ + struct ieee80211_tx_info *control = IEEE80211_SKB_CB(skb); + + if (control->control.sta) { + struct wl1271_station *wl_sta; + + wl_sta = (struct wl1271_station *) + control->control.sta->drv_priv; + return wl_sta->hlid; + } else { + struct ieee80211_hdr *hdr; + + hdr = (struct ieee80211_hdr *)skb->data; + if (ieee80211_is_mgmt(hdr->frame_control)) + return WL1271_AP_GLOBAL_HLID; + else + return WL1271_AP_BROADCAST_HLID; + } +} + static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, u32 buf_offset) { @@ -298,7 +319,7 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) return enabled_rates; } -static void handle_tx_low_watermark(struct wl1271 *wl) +void wl1271_handle_tx_low_watermark(struct wl1271 *wl) { unsigned long flags; @@ -312,7 +333,7 @@ static void handle_tx_low_watermark(struct wl1271 *wl) } } -static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) +static struct sk_buff *wl1271_sta_skb_dequeue(struct wl1271 *wl) { struct sk_buff *skb = NULL; unsigned long flags; @@ -338,12 +359,69 @@ out: return skb; } +static struct sk_buff *wl1271_ap_skb_dequeue(struct wl1271 *wl) +{ + struct sk_buff *skb = NULL; + unsigned long flags; + int i, h, start_hlid; + + /* start from the link after the last one */ + start_hlid = (wl->last_tx_hlid + 1) % AP_MAX_LINKS; + + /* dequeue according to AC, round robin on each link */ + for (i = 0; i < AP_MAX_LINKS; i++) { + h = (start_hlid + i) % AP_MAX_LINKS; + + skb = skb_dequeue(&wl->links[h].tx_queue[CONF_TX_AC_VO]); + if (skb) + goto out; + skb = skb_dequeue(&wl->links[h].tx_queue[CONF_TX_AC_VI]); + if (skb) + goto out; + skb = skb_dequeue(&wl->links[h].tx_queue[CONF_TX_AC_BE]); + if (skb) + goto out; + skb = skb_dequeue(&wl->links[h].tx_queue[CONF_TX_AC_BK]); + if (skb) + goto out; + } + +out: + if (skb) { + wl->last_tx_hlid = h; + spin_lock_irqsave(&wl->wl_lock, flags); + wl->tx_queue_count--; + spin_unlock_irqrestore(&wl->wl_lock, flags); + } else { + wl->last_tx_hlid = 0; + } + + return skb; +} + +static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) +{ + if (wl->bss_type == BSS_TYPE_AP_BSS) + return wl1271_ap_skb_dequeue(wl); + + return wl1271_sta_skb_dequeue(wl); +} + static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb) { unsigned long flags; int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); - skb_queue_head(&wl->tx_queue[q], skb); + if (wl->bss_type == BSS_TYPE_AP_BSS) { + u8 hlid = wl1271_tx_get_hlid(skb); + skb_queue_head(&wl->links[hlid].tx_queue[q], skb); + + /* make sure we dequeue the same packet next time */ + wl->last_tx_hlid = (hlid + AP_MAX_LINKS - 1) % AP_MAX_LINKS; + } else { + skb_queue_head(&wl->tx_queue[q], skb); + } + spin_lock_irqsave(&wl->wl_lock, flags); wl->tx_queue_count++; spin_unlock_irqrestore(&wl->wl_lock, flags); @@ -406,7 +484,7 @@ out_ack: if (sent_packets) { /* interrupt the firmware with the new packets */ wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count); - handle_tx_low_watermark(wl); + wl1271_handle_tx_low_watermark(wl); } out: @@ -523,6 +601,27 @@ void wl1271_tx_complete(struct wl1271 *wl) } } +void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid) +{ + struct sk_buff *skb; + int i, total = 0; + unsigned long flags; + + for (i = 0; i < NUM_TX_QUEUES; i++) { + while ((skb = skb_dequeue(&wl->links[hlid].tx_queue[i]))) { + wl1271_debug(DEBUG_TX, "link freeing skb 0x%p", skb); + ieee80211_tx_status(wl->hw, skb); + total++; + } + } + + spin_lock_irqsave(&wl->wl_lock, flags); + wl->tx_queue_count -= total; + spin_unlock_irqrestore(&wl->wl_lock, flags); + + wl1271_handle_tx_low_watermark(wl); +} + /* caller must hold wl->mutex */ void wl1271_tx_reset(struct wl1271 *wl) { @@ -530,19 +629,28 @@ void wl1271_tx_reset(struct wl1271 *wl) struct sk_buff *skb; /* TX failure */ - for (i = 0; i < NUM_TX_QUEUES; i++) { - while ((skb = skb_dequeue(&wl->tx_queue[i]))) { - wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); - ieee80211_tx_status(wl->hw, skb); + if (wl->bss_type == BSS_TYPE_AP_BSS) { + for (i = 0; i < AP_MAX_LINKS; i++) + wl1271_tx_reset_link_queues(wl, i); + + wl->last_tx_hlid = 0; + } else { + for (i = 0; i < NUM_TX_QUEUES; i++) { + while ((skb = skb_dequeue(&wl->tx_queue[i]))) { + wl1271_debug(DEBUG_TX, "freeing skb 0x%p", + skb); + ieee80211_tx_status(wl->hw, skb); + } } } + wl->tx_queue_count = 0; /* * Make sure the driver is at a consistent state, in case this * function is called from a context other than interface removal. */ - handle_tx_low_watermark(wl); + wl1271_handle_tx_low_watermark(wl); for (i = 0; i < ACX_TX_DESCRIPTORS; i++) if (wl->tx_frames[i] != NULL) { @@ -563,8 +671,8 @@ void wl1271_tx_flush(struct wl1271 *wl) while (!time_after(jiffies, timeout)) { mutex_lock(&wl->mutex); - wl1271_debug(DEBUG_TX, "flushing tx buffer: %d", - wl->tx_frames_cnt); + wl1271_debug(DEBUG_TX, "flushing tx buffer: %d %d", + wl->tx_frames_cnt, wl->tx_queue_count); if ((wl->tx_frames_cnt == 0) && (wl->tx_queue_count == 0)) { mutex_unlock(&wl->mutex); return; diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h index db88f58707a3..02f07fa66e82 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h @@ -150,5 +150,8 @@ void wl1271_tx_flush(struct wl1271 *wl); u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set); u32 wl1271_tx_min_rate_get(struct wl1271 *wl); +u8 wl1271_tx_get_hlid(struct sk_buff *skb); +void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid); +void wl1271_handle_tx_low_watermark(struct wl1271 *wl); #endif diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 1d6c94304b1a..9ffac80d3988 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -319,6 +319,11 @@ enum wl12xx_flags { WL1271_FLAG_AP_STARTED }; +struct wl1271_link { + /* AP-mode - TX queue per AC in link */ + struct sk_buff_head tx_queue[NUM_TX_QUEUES]; +}; + struct wl1271 { struct platform_device *plat_dev; struct ieee80211_hw *hw; @@ -498,6 +503,15 @@ struct wl1271 { /* RX BA constraint value */ bool ba_support; u8 ba_rx_bitmap; + + /* + * AP-mode - links indexed by HLID. The global and broadcast links + * are always active. + */ + struct wl1271_link links[AP_MAX_LINKS]; + + /* the hlid of the link where the last transmitted skb came from */ + int last_tx_hlid; }; struct wl1271_station { -- cgit v1.2.3 From 1d36cd892c130a5a781acb282e083b94127f1c50 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 23 Feb 2011 00:22:27 +0200 Subject: wl12xx: report invalid TX rate when returning non-TX-ed skbs Report a TX rate idx of -1 and count 0 when returning untransmitted skbs to mac80211 using ieee80211_tx_status(). Otherwise mac80211 tries to use the returned (essentially garbage) status. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/tx.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 8c769500ec5d..de60b4bc4a72 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -606,10 +606,14 @@ void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid) struct sk_buff *skb; int i, total = 0; unsigned long flags; + struct ieee80211_tx_info *info; for (i = 0; i < NUM_TX_QUEUES; i++) { while ((skb = skb_dequeue(&wl->links[hlid].tx_queue[i]))) { wl1271_debug(DEBUG_TX, "link freeing skb 0x%p", skb); + info = IEEE80211_SKB_CB(skb); + info->status.rates[0].idx = -1; + info->status.rates[0].count = 0; ieee80211_tx_status(wl->hw, skb); total++; } @@ -627,6 +631,7 @@ void wl1271_tx_reset(struct wl1271 *wl) { int i; struct sk_buff *skb; + struct ieee80211_tx_info *info; /* TX failure */ if (wl->bss_type == BSS_TYPE_AP_BSS) { @@ -639,6 +644,9 @@ void wl1271_tx_reset(struct wl1271 *wl) while ((skb = skb_dequeue(&wl->tx_queue[i]))) { wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); + info = IEEE80211_SKB_CB(skb); + info->status.rates[0].idx = -1; + info->status.rates[0].count = 0; ieee80211_tx_status(wl->hw, skb); } } @@ -657,6 +665,9 @@ void wl1271_tx_reset(struct wl1271 *wl) skb = wl->tx_frames[i]; wl1271_free_tx_id(wl, i); wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); + info = IEEE80211_SKB_CB(skb); + info->status.rates[0].idx = -1; + info->status.rates[0].count = 0; ieee80211_tx_status(wl->hw, skb); } } -- cgit v1.2.3 From ba7c082a139178da239a65e6e6cc6bd1c8515d97 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 23 Feb 2011 00:22:28 +0200 Subject: wl12xx: AP-mode - support HW based link PS monitoring When operating in AP mode the wl1271 hardware filters out null-data packets as well as management packets. This makes it impossible for mac80211 to monitor the PS mode by using the PM bit of incoming frames. Disable mac80211 automatic link PS-mode handling by supporting IEEE80211_HW_AP_LINK_PS in HW flags. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 3a4f6069be60..f336e9cbd9e0 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -3226,7 +3226,8 @@ int wl1271_init_ieee80211(struct wl1271 *wl) IEEE80211_HW_HAS_RATE_CONTROL | IEEE80211_HW_CONNECTION_MONITOR | IEEE80211_HW_SUPPORTS_CQM_RSSI | - IEEE80211_HW_REPORTS_TX_ACK_STATUS; + IEEE80211_HW_REPORTS_TX_ACK_STATUS | + IEEE80211_HW_AP_LINK_PS; wl->hw->wiphy->cipher_suites = cipher_suites; wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); -- cgit v1.2.3 From 409622ecc2a3b618b31b1894ed6360fbdca95d62 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 23 Feb 2011 00:22:29 +0200 Subject: wl12xx: AP mode - fix bug in cleanup of wl1271_op_sta_add() Remove an active hlid when chip wakeup fails. In addition rename the involved functions. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index f336e9cbd9e0..92f822043331 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2624,7 +2624,7 @@ static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx, return 0; } -static int wl1271_allocate_hlid(struct wl1271 *wl, +static int wl1271_allocate_sta(struct wl1271 *wl, struct ieee80211_sta *sta, u8 *hlid) { @@ -2645,10 +2645,13 @@ static int wl1271_allocate_hlid(struct wl1271 *wl, return 0; } -static void wl1271_free_hlid(struct wl1271 *wl, u8 hlid) +static void wl1271_free_sta(struct wl1271 *wl, u8 hlid) { int id = hlid - WL1271_AP_STA_HLID_START; + if (WARN_ON(!test_bit(id, wl->ap_hlid_map))) + return; + __clear_bit(id, wl->ap_hlid_map); wl1271_tx_reset_link_queues(wl, hlid); } @@ -2671,13 +2674,13 @@ static int wl1271_op_sta_add(struct ieee80211_hw *hw, wl1271_debug(DEBUG_MAC80211, "mac80211 add sta %d", (int)sta->aid); - ret = wl1271_allocate_hlid(wl, sta, &hlid); + ret = wl1271_allocate_sta(wl, sta, &hlid); if (ret < 0) goto out; ret = wl1271_ps_elp_wakeup(wl, false); if (ret < 0) - goto out; + goto out_free_sta; ret = wl1271_cmd_add_sta(wl, sta, hlid); if (ret < 0) @@ -2686,6 +2689,10 @@ static int wl1271_op_sta_add(struct ieee80211_hw *hw, out_sleep: wl1271_ps_elp_sleep(wl); +out_free_sta: + if (ret < 0) + wl1271_free_sta(wl, hlid); + out: mutex_unlock(&wl->mutex); return ret; @@ -2722,7 +2729,7 @@ static int wl1271_op_sta_remove(struct ieee80211_hw *hw, if (ret < 0) goto out_sleep; - wl1271_free_hlid(wl, wl_sta->hlid); + wl1271_free_sta(wl, wl_sta->hlid); out_sleep: wl1271_ps_elp_sleep(wl); -- cgit v1.2.3 From 09039f42a24084c10e7761ab28ef22932c62a46f Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 23 Feb 2011 00:22:30 +0200 Subject: wl12xx: AP-mode - count free FW TX blocks per link Count the number of FW TX blocks allocated per link. We add blocks to a link counter when allocated for a TX descriptor. We remove blocks according to counters in fw_status indicating the number of freed blocks in FW. These counters are polled after each IRQ. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 11 ++++++++ drivers/net/wireless/wl12xx/ps.c | 2 -- drivers/net/wireless/wl12xx/tx.c | 53 ++++++++++++++++++++---------------- drivers/net/wireless/wl12xx/wl12xx.h | 4 +++ 4 files changed, 44 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 92f822043331..5772a33d79ec 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -574,6 +574,17 @@ static void wl1271_fw_status(struct wl1271 *wl, if (total) clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags); + if (wl->bss_type == BSS_TYPE_AP_BSS) { + for (i = 0; i < AP_MAX_LINKS; i++) { + u8 cnt = status->tx_lnk_free_blks[i] - + wl->links[i].prev_freed_blks; + + wl->links[i].prev_freed_blks = + status->tx_lnk_free_blks[i]; + wl->links[i].allocated_blks -= cnt; + } + } + /* update the host-chipset time offset */ getnstimeofday(&ts); wl->time_offset = (timespec_to_ns(&ts) >> 10) - diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index 2d3086ae6338..b7b3139e00fb 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c @@ -172,5 +172,3 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, return ret; } - - diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index de60b4bc4a72..ea1382bd38f4 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -108,7 +108,7 @@ u8 wl1271_tx_get_hlid(struct sk_buff *skb) } static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, - u32 buf_offset) + u32 buf_offset, u8 hlid) { struct wl1271_tx_hw_descr *desc; u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; @@ -137,6 +137,9 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, wl->tx_blocks_available -= total_blocks; + if (wl->bss_type == BSS_TYPE_AP_BSS) + wl->links[hlid].allocated_blks += total_blocks; + ret = 0; wl1271_debug(DEBUG_TX, @@ -150,7 +153,8 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, } static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, - u32 extra, struct ieee80211_tx_info *control) + u32 extra, struct ieee80211_tx_info *control, + u8 hlid) { struct timespec ts; struct wl1271_tx_hw_descr *desc; @@ -186,7 +190,7 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, desc->tid = ac; if (wl->bss_type != BSS_TYPE_AP_BSS) { - desc->aid = TX_HW_DEFAULT_AID; + desc->aid = hlid; /* if the packets are destined for AP (have a STA entry) send them with AP rate policies, otherwise use default @@ -196,25 +200,17 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, else rate_idx = ACX_TX_BASIC_RATE; } else { - if (control->control.sta) { - struct wl1271_station *wl_sta; - - wl_sta = (struct wl1271_station *) - control->control.sta->drv_priv; - desc->hlid = wl_sta->hlid; + desc->hlid = hlid; + switch (hlid) { + case WL1271_AP_GLOBAL_HLID: + rate_idx = ACX_TX_AP_MODE_MGMT_RATE; + break; + case WL1271_AP_BROADCAST_HLID: + rate_idx = ACX_TX_AP_MODE_BCST_RATE; + break; + default: rate_idx = ac; - } else { - struct ieee80211_hdr *hdr; - - hdr = (struct ieee80211_hdr *) - (skb->data + sizeof(*desc)); - if (ieee80211_is_mgmt(hdr->frame_control)) { - desc->hlid = WL1271_AP_GLOBAL_HLID; - rate_idx = ACX_TX_AP_MODE_MGMT_RATE; - } else { - desc->hlid = WL1271_AP_BROADCAST_HLID; - rate_idx = ACX_TX_AP_MODE_BCST_RATE; - } + break; } } @@ -245,6 +241,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, u32 extra = 0; int ret = 0; u32 total_len; + u8 hlid; if (!skb) return -EINVAL; @@ -271,14 +268,19 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, } } - ret = wl1271_tx_allocate(wl, skb, extra, buf_offset); + if (wl->bss_type == BSS_TYPE_AP_BSS) + hlid = wl1271_tx_get_hlid(skb); + else + hlid = TX_HW_DEFAULT_AID; + + ret = wl1271_tx_allocate(wl, skb, extra, buf_offset, hlid); if (ret < 0) return ret; if (wl->bss_type == BSS_TYPE_AP_BSS) wl1271_tx_ap_update_inconnection_sta(wl, skb); - wl1271_tx_fill_hdr(wl, skb, extra, info); + wl1271_tx_fill_hdr(wl, skb, extra, info, hlid); /* * The length of each packet is stored in terms of words. Thus, we must @@ -635,8 +637,11 @@ void wl1271_tx_reset(struct wl1271 *wl) /* TX failure */ if (wl->bss_type == BSS_TYPE_AP_BSS) { - for (i = 0; i < AP_MAX_LINKS; i++) + for (i = 0; i < AP_MAX_LINKS; i++) { wl1271_tx_reset_link_queues(wl, i); + wl->links[i].allocated_blks = 0; + wl->links[i].prev_freed_blks = 0; + } wl->last_tx_hlid = 0; } else { diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 9ffac80d3988..0e00c5be99d3 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -322,6 +322,10 @@ enum wl12xx_flags { struct wl1271_link { /* AP-mode - TX queue per AC in link */ struct sk_buff_head tx_queue[NUM_TX_QUEUES]; + + /* accounting for allocated / available TX blocks in FW */ + u8 allocated_blks; + u8 prev_freed_blks; }; struct wl1271 { -- cgit v1.2.3 From b622d992c21a85ce590afe2c18977ed28b457e0e Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Wed, 23 Feb 2011 00:22:31 +0200 Subject: wl12xx: AP-mode - management of links in PS-mode Update the PS mode of each link according to a bitmap polled from fw_status. Manually notify mac80211 about PS mode changes in connected stations. mac80211 will only be notified about PS start when the station is in PS and there is a small number of TX blocks from this link ready in HW. This is required for waking up the remote station since the TIM is updated entirely by FW. When a station enters mac80211-PS-mode, we drop all the skbs in the low-level TX queues belonging to this sta with STAT_TX_FILTERED to keep our queues clean. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 73 +++++++++++++++++++++++++++----- drivers/net/wireless/wl12xx/ps.c | 80 ++++++++++++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/ps.h | 2 + drivers/net/wireless/wl12xx/tx.c | 24 ++++++++++- drivers/net/wireless/wl12xx/wl12xx.h | 19 +++++++++ 5 files changed, 186 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 5772a33d79ec..95aa19ae84e5 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -537,6 +537,57 @@ static int wl1271_plt_init(struct wl1271 *wl) return ret; } +static void wl1271_irq_ps_regulate_link(struct wl1271 *wl, u8 hlid, u8 tx_blks) +{ + bool fw_ps; + + /* only regulate station links */ + if (hlid < WL1271_AP_STA_HLID_START) + return; + + fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); + + /* + * Wake up from high level PS if the STA is asleep with too little + * blocks in FW or if the STA is awake. + */ + if (!fw_ps || tx_blks < WL1271_PS_STA_MAX_BLOCKS) + wl1271_ps_link_end(wl, hlid); + + /* Start high-level PS if the STA is asleep with enough blocks in FW */ + else if (fw_ps && tx_blks >= WL1271_PS_STA_MAX_BLOCKS) + wl1271_ps_link_start(wl, hlid, true); +} + +static void wl1271_irq_update_links_status(struct wl1271 *wl, + struct wl1271_fw_ap_status *status) +{ + u32 cur_fw_ps_map; + u8 hlid; + + cur_fw_ps_map = le32_to_cpu(status->link_ps_bitmap); + if (wl->ap_fw_ps_map != cur_fw_ps_map) { + wl1271_debug(DEBUG_PSM, + "link ps prev 0x%x cur 0x%x changed 0x%x", + wl->ap_fw_ps_map, cur_fw_ps_map, + wl->ap_fw_ps_map ^ cur_fw_ps_map); + + wl->ap_fw_ps_map = cur_fw_ps_map; + } + + for (hlid = WL1271_AP_STA_HLID_START; hlid < AP_MAX_LINKS; hlid++) { + u8 cnt = status->tx_lnk_free_blks[hlid] - + wl->links[hlid].prev_freed_blks; + + wl->links[hlid].prev_freed_blks = + status->tx_lnk_free_blks[hlid]; + wl->links[hlid].allocated_blks -= cnt; + + wl1271_irq_ps_regulate_link(wl, hlid, + wl->links[hlid].allocated_blks); + } +} + static void wl1271_fw_status(struct wl1271 *wl, struct wl1271_fw_full_status *full_status) { @@ -574,16 +625,9 @@ static void wl1271_fw_status(struct wl1271 *wl, if (total) clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags); - if (wl->bss_type == BSS_TYPE_AP_BSS) { - for (i = 0; i < AP_MAX_LINKS; i++) { - u8 cnt = status->tx_lnk_free_blks[i] - - wl->links[i].prev_freed_blks; - - wl->links[i].prev_freed_blks = - status->tx_lnk_free_blks[i]; - wl->links[i].allocated_blks -= cnt; - } - } + /* for AP update num of allocated TX blocks per link and ps status */ + if (wl->bss_type == BSS_TYPE_AP_BSS) + wl1271_irq_update_links_status(wl, &full_status->ap); /* update the host-chipset time offset */ getnstimeofday(&ts); @@ -1241,6 +1285,8 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl) wl->filters = 0; wl1271_free_ap_keys(wl); memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map)); + wl->ap_fw_ps_map = 0; + wl->ap_ps_map = 0; for (i = 0; i < NUM_TX_QUEUES; i++) wl->tx_blocks_freed[i] = 0; @@ -2649,10 +2695,10 @@ static int wl1271_allocate_sta(struct wl1271 *wl, } wl_sta = (struct wl1271_station *)sta->drv_priv; - __set_bit(id, wl->ap_hlid_map); wl_sta->hlid = WL1271_AP_STA_HLID_START + id; *hlid = wl_sta->hlid; + memcpy(wl->links[wl_sta->hlid].addr, sta->addr, ETH_ALEN); return 0; } @@ -2664,7 +2710,10 @@ static void wl1271_free_sta(struct wl1271 *wl, u8 hlid) return; __clear_bit(id, wl->ap_hlid_map); + memset(wl->links[hlid].addr, 0, ETH_ALEN); wl1271_tx_reset_link_queues(wl, hlid); + __clear_bit(hlid, &wl->ap_ps_map); + __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); } static int wl1271_op_sta_add(struct ieee80211_hw *hw, @@ -3355,6 +3404,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void) wl->set_bss_type = MAX_BSS_TYPE; wl->fw_bss_type = MAX_BSS_TYPE; wl->last_tx_hlid = 0; + wl->ap_ps_map = 0; + wl->ap_fw_ps_map = 0; memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); for (i = 0; i < ACX_TX_DESCRIPTORS; i++) diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index b7b3139e00fb..5c347b1bd17f 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c @@ -24,6 +24,7 @@ #include "reg.h" #include "ps.h" #include "io.h" +#include "tx.h" #define WL1271_WAKEUP_TIMEOUT 500 @@ -172,3 +173,82 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, return ret; } + +static void wl1271_ps_filter_frames(struct wl1271 *wl, u8 hlid) +{ + int i, filtered = 0; + struct sk_buff *skb; + struct ieee80211_tx_info *info; + unsigned long flags; + + /* filter all frames currently the low level queus for this hlid */ + for (i = 0; i < NUM_TX_QUEUES; i++) { + while ((skb = skb_dequeue(&wl->links[hlid].tx_queue[i]))) { + info = IEEE80211_SKB_CB(skb); + info->flags |= IEEE80211_TX_STAT_TX_FILTERED; + info->status.rates[0].idx = -1; + ieee80211_tx_status(wl->hw, skb); + filtered++; + } + } + + spin_lock_irqsave(&wl->wl_lock, flags); + wl->tx_queue_count -= filtered; + spin_unlock_irqrestore(&wl->wl_lock, flags); + + wl1271_handle_tx_low_watermark(wl); +} + +void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues) +{ + struct ieee80211_sta *sta; + + if (test_bit(hlid, &wl->ap_ps_map)) + return; + + wl1271_debug(DEBUG_PSM, "start mac80211 PSM on hlid %d blks %d " + "clean_queues %d", hlid, wl->links[hlid].allocated_blks, + clean_queues); + + rcu_read_lock(); + sta = ieee80211_find_sta(wl->vif, wl->links[hlid].addr); + if (!sta) { + wl1271_error("could not find sta %pM for starting ps", + wl->links[hlid].addr); + rcu_read_unlock(); + return; + } + + ieee80211_sta_ps_transition_ni(sta, true); + rcu_read_unlock(); + + /* do we want to filter all frames from this link's queues? */ + if (clean_queues) + wl1271_ps_filter_frames(wl, hlid); + + __set_bit(hlid, &wl->ap_ps_map); +} + +void wl1271_ps_link_end(struct wl1271 *wl, u8 hlid) +{ + struct ieee80211_sta *sta; + + if (!test_bit(hlid, &wl->ap_ps_map)) + return; + + wl1271_debug(DEBUG_PSM, "end mac80211 PSM on hlid %d", hlid); + + __clear_bit(hlid, &wl->ap_ps_map); + + rcu_read_lock(); + sta = ieee80211_find_sta(wl->vif, wl->links[hlid].addr); + if (!sta) { + wl1271_error("could not find sta %pM for ending ps", + wl->links[hlid].addr); + goto end; + } + + ieee80211_sta_ps_transition_ni(sta, false); +end: + rcu_read_unlock(); +} diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/wl12xx/ps.h index 8415060f08e5..fc1f4c193593 100644 --- a/drivers/net/wireless/wl12xx/ps.h +++ b/drivers/net/wireless/wl12xx/ps.h @@ -32,5 +32,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, void wl1271_ps_elp_sleep(struct wl1271 *wl); int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake); void wl1271_elp_work(struct work_struct *work); +void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues); +void wl1271_ps_link_end(struct wl1271 *wl, u8 hlid); #endif /* __WL1271_PS_H__ */ diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index ea1382bd38f4..ac60d577319f 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -86,6 +86,26 @@ static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl, wl1271_acx_set_inconnection_sta(wl, hdr->addr1); } +static void wl1271_tx_regulate_link(struct wl1271 *wl, u8 hlid) +{ + bool fw_ps; + u8 tx_blks; + + /* only regulate station links */ + if (hlid < WL1271_AP_STA_HLID_START) + return; + + fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); + tx_blks = wl->links[hlid].allocated_blks; + + /* + * if in FW PS and there is enough data in FW we can put the link + * into high-level PS and clean out its TX queues. + */ + if (fw_ps && tx_blks >= WL1271_PS_STA_MAX_BLOCKS) + wl1271_ps_link_start(wl, hlid, true); +} + u8 wl1271_tx_get_hlid(struct sk_buff *skb) { struct ieee80211_tx_info *control = IEEE80211_SKB_CB(skb); @@ -277,8 +297,10 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, if (ret < 0) return ret; - if (wl->bss_type == BSS_TYPE_AP_BSS) + if (wl->bss_type == BSS_TYPE_AP_BSS) { wl1271_tx_ap_update_inconnection_sta(wl, skb); + wl1271_tx_regulate_link(wl, hlid); + } wl1271_tx_fill_hdr(wl, skb, extra, info, hlid); diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 0e00c5be99d3..338acc9f60b3 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -153,6 +153,17 @@ extern u32 wl12xx_debug_level; #define WL1271_AP_BROADCAST_HLID 1 #define WL1271_AP_STA_HLID_START 2 +/* + * When in AP-mode, we allow (at least) this number of mem-blocks + * to be transmitted to FW for a STA in PS-mode. Only when packets are + * present in the FW buffers it will wake the sleeping STA. We want to put + * enough packets for the driver to transmit all of its buffered data before + * the STA goes to sleep again. But we don't want to take too much mem-blocks + * as it might hurt the throughput of active STAs. + * The number of blocks (18) is enough for 2 large packets. + */ +#define WL1271_PS_STA_MAX_BLOCKS (2 * 9) + #define WL1271_AP_BSS_INDEX 0 #define WL1271_AP_DEF_INACTIV_SEC 300 #define WL1271_AP_DEF_BEACON_EXP 20 @@ -326,6 +337,8 @@ struct wl1271_link { /* accounting for allocated / available TX blocks in FW */ u8 allocated_blks; u8 prev_freed_blks; + + u8 addr[ETH_ALEN]; }; struct wl1271 { @@ -516,6 +529,12 @@ struct wl1271 { /* the hlid of the link where the last transmitted skb came from */ int last_tx_hlid; + + /* AP-mode - a bitmap of links currently in PS mode according to FW */ + u32 ap_fw_ps_map; + + /* AP-mode - a bitmap of links currently in PS mode in mac80211 */ + unsigned long ap_ps_map; }; struct wl1271_station { -- cgit v1.2.3 From 9bb794ae0509f39abad6593793ec86d490bad31b Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 22 Feb 2011 20:15:07 -0800 Subject: Input: synaptics - document 0x0c query Since Synaptics technical writers department is a bit slow releasing updated Synaptics interface guide, let's add some new bits (with their blessing) to the code so that they don't get lost. Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers') diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 25e5d042a72c..7453938bf5ef 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h @@ -51,6 +51,29 @@ #define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20) #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) #define SYN_CAP_PRODUCT_ID(ec) (((ec) & 0xff0000) >> 16) + +/* + * The following describes response for the 0x0c query. + * + * byte mask name meaning + * ---- ---- ------- ------------ + * 1 0x01 adjustable threshold capacitive button sensitivity + * can be adjusted + * 1 0x02 report max query 0x0d gives max coord reported + * 1 0x04 clearpad sensor is ClearPad product + * 1 0x08 advanced gesture not particularly meaningful + * 1 0x10 clickpad bit 0 1-button ClickPad + * 1 0x60 multifinger mode identifies firmware finger counting + * (not reporting!) algorithm. + * Not particularly meaningful + * 1 0x80 covered pad W clipped to 14, 15 == pad mostly covered + * 2 0x01 clickpad bit 1 2-button ClickPad + * 2 0x02 deluxe LED controls touchpad support LED commands + * ala multimedia control bar + * 2 0x04 reduced filtering firmware does less filtering on + * position data, driver should watch + * for noise. + */ #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ #define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */ #define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000) -- cgit v1.2.3 From 1d64b655dc083df5c5ac39945ccbbc6532903bf1 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 23 Feb 2011 08:51:28 -0800 Subject: Input: serio/gameport - use 'long' system workqueue Commit 8ee294cd9def0004887da7f44b80563493b0a097 converted serio subsystem event handling from using a dedicated thread to using common workqueue. Unfortunately, this regressed our boot times, due to the fact that serio jobs take long time to execute. While the new concurrency managed workqueue code manages long-playing works just fine and schedules additional workers as needed, such works wreck havoc among remaining users of flush_scheduled_work(). To solve this problem let's move serio/gameport works from system_wq to system_long_wq which nobody tries to flush. Reported-and-tested-by: Hernando Torque Acked-by: Tejun Heo Signed-off-by: Dmitry Torokhov --- drivers/input/gameport/gameport.c | 2 +- drivers/input/serio/serio.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index dbf741c95835..ce57ede6e981 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -360,7 +360,7 @@ static int gameport_queue_event(void *object, struct module *owner, event->owner = owner; list_add_tail(&event->node, &gameport_event_list); - schedule_work(&gameport_event_work); + queue_work(system_long_wq, &gameport_event_work); out: spin_unlock_irqrestore(&gameport_event_lock, flags); diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 7c38d1fbabf2..ba70058e2be3 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -299,7 +299,7 @@ static int serio_queue_event(void *object, struct module *owner, event->owner = owner; list_add_tail(&event->node, &serio_event_list); - schedule_work(&serio_event_work); + queue_work(system_long_wq, &serio_event_work); out: spin_unlock_irqrestore(&serio_event_lock, flags); -- cgit v1.2.3 From 6fbb47859faa88e7fca458497d9688e928e587e1 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Fri, 18 Feb 2011 15:05:52 -0800 Subject: staging: hv: Remove unnecessary ASSERTs in netvsc_initialize() These fields have been assigned in netvsc_drv_init() before calling netvsc_initialize(), so there is no need to check them. The ASSERTs were already commented out, and this patch removes them. Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/netvsc.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index 8c6d4ae54be2..f21a59db169c 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -188,11 +188,6 @@ int netvsc_initialize(struct hv_driver *drv) drv->name = driver_name; memcpy(&drv->dev_type, &netvsc_device_type, sizeof(struct hv_guid)); - /* Make sure it is set by the caller */ - /* FIXME: These probably should still be tested in some way */ - /* ASSERT(driver->OnReceiveCallback); */ - /* ASSERT(driver->OnLinkStatusChanged); */ - /* Setup the dispatch table */ driver->base.dev_add = netvsc_device_add; driver->base.dev_rm = netvsc_device_remove; -- cgit v1.2.3 From 31acaa50c6c61bfb486dacaa2ec62950a42de233 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Fri, 18 Feb 2011 15:05:53 -0800 Subject: staging: hv: Fix the WARN_ON condition in free_net_device() In a previous commit, 7a09876d, ASSERT was changed to WARN_ON, but the condition wasn't updated. This patch fixed this error. Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/netvsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index f21a59db169c..20b159775e88 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -95,7 +95,7 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device) static void free_net_device(struct netvsc_device *device) { - WARN_ON(atomic_read(&device->refcnt) == 0); + WARN_ON(atomic_read(&device->refcnt) != 0); device->dev->ext = NULL; kfree(device); } -- cgit v1.2.3 From 008536e8458613ce569595e43b0e71afa8b48ae8 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 19 Feb 2011 15:45:29 -0800 Subject: connector: Convert char *name to const char *name Allow more const declarations. Signed-off-by: Joe Perches Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/connector/cn_queue.c | 7 ++++--- drivers/connector/connector.c | 2 +- include/linux/connector.h | 9 ++++++--- 3 files changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c index 81270d221e5a..55653aba6735 100644 --- a/drivers/connector/cn_queue.c +++ b/drivers/connector/cn_queue.c @@ -48,7 +48,7 @@ void cn_queue_wrapper(struct work_struct *work) } static struct cn_callback_entry * -cn_queue_alloc_callback_entry(char *name, struct cb_id *id, +cn_queue_alloc_callback_entry(const char *name, struct cb_id *id, void (*callback)(struct cn_msg *, struct netlink_skb_parms *)) { struct cn_callback_entry *cbq; @@ -78,7 +78,8 @@ int cn_cb_equal(struct cb_id *i1, struct cb_id *i2) return ((i1->idx == i2->idx) && (i1->val == i2->val)); } -int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, +int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name, + struct cb_id *id, void (*callback)(struct cn_msg *, struct netlink_skb_parms *)) { struct cn_callback_entry *cbq, *__cbq; @@ -135,7 +136,7 @@ void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id) } } -struct cn_queue_dev *cn_queue_alloc_dev(char *name, struct sock *nls) +struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *nls) { struct cn_queue_dev *dev; diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index 05117f1ad867..f7554de3be5e 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c @@ -205,7 +205,7 @@ static void cn_rx_skb(struct sk_buff *__skb) * * May sleep. */ -int cn_add_callback(struct cb_id *id, char *name, +int cn_add_callback(struct cb_id *id, const char *name, void (*callback)(struct cn_msg *, struct netlink_skb_parms *)) { int err; diff --git a/include/linux/connector.h b/include/linux/connector.h index 2e9759cdd275..bcafc942e5e4 100644 --- a/include/linux/connector.h +++ b/include/linux/connector.h @@ -129,14 +129,17 @@ struct cn_dev { struct cn_queue_dev *cbdev; }; -int cn_add_callback(struct cb_id *, char *, void (*callback) (struct cn_msg *, struct netlink_skb_parms *)); +int cn_add_callback(struct cb_id *id, const char *name, + void (*callback)(struct cn_msg *, struct netlink_skb_parms *)); void cn_del_callback(struct cb_id *); int cn_netlink_send(struct cn_msg *, u32, gfp_t); -int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(struct cn_msg *, struct netlink_skb_parms *)); +int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name, + struct cb_id *id, + void (*callback)(struct cn_msg *, struct netlink_skb_parms *)); void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id); -struct cn_queue_dev *cn_queue_alloc_dev(char *name, struct sock *); +struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *); void cn_queue_free_dev(struct cn_queue_dev *dev); int cn_cb_equal(struct cb_id *, struct cb_id *); -- cgit v1.2.3 From da62b761769f60e5d476ad882c5ba40fb5d61664 Mon Sep 17 00:00:00 2001 From: Nishant Sarmukadam Date: Thu, 17 Feb 2011 14:45:16 -0800 Subject: mwl8k: fix rf_antenna rx argument for AP When configuring rx antennas using CMD_RF_ANTENNA, the argument input is the number of antennas to be enabled. For AP, we support 3 rx antennas and hence set the field to 3. For tx antennas, value is a bitmap, so 0x7 enables all three. Signed-off-by: Nishant Sarmukadam Signed-off-by: Pradeep Nemavat Signed-off-by: Thomas Pedersen Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index af4f2c64f242..f79da1b1487e 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -3945,9 +3945,13 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed) if (rc) goto out; - rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x7); - if (!rc) - rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_TX, 0x7); + rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x3); + if (rc) + wiphy_warn(hw->wiphy, "failed to set # of RX antennas"); + rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_TX, 0x7); + if (rc) + wiphy_warn(hw->wiphy, "failed to set # of TX antennas"); + } else { rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level); if (rc) -- cgit v1.2.3 From 0bf22c3751d19f9be20205c0e7112723618a4858 Mon Sep 17 00:00:00 2001 From: Nishant Sarmukadam Date: Thu, 17 Feb 2011 14:45:17 -0800 Subject: mwl8k: Tell mac80211 we have rate adaptation in FW All mwl8k parts perform rate control in firmware. Make this known to mac80211 so that it does not launch minstrel. Also, because actual tx rate information is not available from the firmware, invalidate the rate status before returning the skb to mac80211. Signed-off-by: Nishant Sarmukadam Signed-off-by: Thomas Pedersen Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index f79da1b1487e..44355f7dd615 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -1535,6 +1535,13 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) info = IEEE80211_SKB_CB(skb); ieee80211_tx_info_clear_status(info); + + /* Rate control is happening in the firmware. + * Ensure no tx rate is being reported. + */ + info->status.rates[0].idx = -1; + info->status.rates[0].count = 1; + if (MWL8K_TXD_SUCCESS(status)) info->flags |= IEEE80211_TX_STAT_ACK; @@ -4764,7 +4771,7 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) hw->queues = MWL8K_TX_QUEUES; /* Set rssi values to dBm */ - hw->flags |= IEEE80211_HW_SIGNAL_DBM; + hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_HAS_RATE_CONTROL; hw->vif_data_size = sizeof(struct mwl8k_vif); hw->sta_data_size = sizeof(struct mwl8k_sta); -- cgit v1.2.3 From 85c9205c79c794a6eea0c7217db93b4c637f136e Mon Sep 17 00:00:00 2001 From: Nishant Sarmukadam Date: Thu, 17 Feb 2011 14:45:18 -0800 Subject: mwl8k: Invert tx queues for set_hw_spec and set_edca_params mac80211 and mwl8k FW tx queue priorities map inversely to each other. Fix this. Signed-off-by: Pradeep Nemavat Signed-off-by: Lennert Buytenhek Tested-by: Pradeep Nemavat Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 44355f7dd615..03f2584aed12 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -2128,8 +2128,18 @@ static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw) cmd->ps_cookie = cpu_to_le32(priv->cookie_dma); cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma); cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES); - for (i = 0; i < MWL8K_TX_QUEUES; i++) - cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma); + + /* + * Mac80211 stack has Q0 as highest priority and Q3 as lowest in + * that order. Firmware has Q3 as highest priority and Q0 as lowest + * in that order. Map Q3 of mac80211 to Q0 of firmware so that the + * priority is interpreted the right way in firmware. + */ + for (i = 0; i < MWL8K_TX_QUEUES; i++) { + int j = MWL8K_TX_QUEUES - 1 - i; + cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[j].txd_dma); + } + cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT | MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP | MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON); @@ -4331,12 +4341,14 @@ static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue, if (!priv->wmm_enabled) rc = mwl8k_cmd_set_wmm_mode(hw, 1); - if (!rc) - rc = mwl8k_cmd_set_edca_params(hw, queue, + if (!rc) { + int q = MWL8K_TX_QUEUES - 1 - queue; + rc = mwl8k_cmd_set_edca_params(hw, q, params->cw_min, params->cw_max, params->aifs, params->txop); + } mwl8k_fw_unlock(hw); } -- cgit v1.2.3 From 36bcce430657e6fece0e8dd91557f35dbb69ec67 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:47:52 +0530 Subject: ath9k_htc: Handle storage devices Some AR7010 based devices are recognized as storage media. Sending a CD-EJECT command to the device will 'convert' it into a WLAN device. Do this within the driver itself, removing the dependancy on an external program (usb_modeswitch). Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 74 +++++++++++++++++++++++++++++--- drivers/net/wireless/ath/ath9k/reg.h | 1 + 2 files changed, 69 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 5ab3084eb9cb..fde54446973f 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -52,6 +52,9 @@ static struct usb_device_id ath9k_hif_usb_ids[] = { { USB_DEVICE(0x083A, 0xA704), .driver_info = AR9280_USB }, /* SMC Networks */ + { USB_DEVICE(0x0cf3, 0x20ff), + .driver_info = STORAGE_DEVICE }, + { }, }; @@ -934,6 +937,61 @@ static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev) release_firmware(hif_dev->firmware); } +/* + * An exact copy of the function from zd1211rw. + */ +static int send_eject_command(struct usb_interface *interface) +{ + struct usb_device *udev = interface_to_usbdev(interface); + struct usb_host_interface *iface_desc = &interface->altsetting[0]; + struct usb_endpoint_descriptor *endpoint; + unsigned char *cmd; + u8 bulk_out_ep; + int r; + + /* Find bulk out endpoint */ + for (r = 1; r >= 0; r--) { + endpoint = &iface_desc->endpoint[r].desc; + if (usb_endpoint_dir_out(endpoint) && + usb_endpoint_xfer_bulk(endpoint)) { + bulk_out_ep = endpoint->bEndpointAddress; + break; + } + } + if (r == -1) { + dev_err(&udev->dev, + "ath9k_htc: Could not find bulk out endpoint\n"); + return -ENODEV; + } + + cmd = kzalloc(31, GFP_KERNEL); + if (cmd == NULL) + return -ENODEV; + + /* USB bulk command block */ + cmd[0] = 0x55; /* bulk command signature */ + cmd[1] = 0x53; /* bulk command signature */ + cmd[2] = 0x42; /* bulk command signature */ + cmd[3] = 0x43; /* bulk command signature */ + cmd[14] = 6; /* command length */ + + cmd[15] = 0x1b; /* SCSI command: START STOP UNIT */ + cmd[19] = 0x2; /* eject disc */ + + dev_info(&udev->dev, "Ejecting storage device...\n"); + r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, bulk_out_ep), + cmd, 31, NULL, 2000); + kfree(cmd); + if (r) + return r; + + /* At this point, the device disconnects and reconnects with the real + * ID numbers. */ + + usb_set_intfdata(interface, NULL); + return 0; +} + static int ath9k_hif_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) { @@ -941,6 +999,9 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, struct hif_device_usb *hif_dev; int ret = 0; + if (id->driver_info == STORAGE_DEVICE) + return send_eject_command(interface); + hif_dev = kzalloc(sizeof(struct hif_device_usb), GFP_KERNEL); if (!hif_dev) { ret = -ENOMEM; @@ -1027,12 +1088,13 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface) struct hif_device_usb *hif_dev = usb_get_intfdata(interface); bool unplugged = (udev->state == USB_STATE_NOTATTACHED) ? true : false; - if (hif_dev) { - ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged); - ath9k_htc_hw_free(hif_dev->htc_handle); - ath9k_hif_usb_dev_deinit(hif_dev); - usb_set_intfdata(interface, NULL); - } + if (!hif_dev) + return; + + ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged); + ath9k_htc_hw_free(hif_dev->htc_handle); + ath9k_hif_usb_dev_deinit(hif_dev); + usb_set_intfdata(interface, NULL); if (!unplugged && (hif_dev->flags & HIF_USB_START)) ath9k_hif_usb_reboot(udev); diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 64b226a78b2e..8fa8acfde62e 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -878,6 +878,7 @@ enum ath_usb_dev { AR9280_USB = 1, /* AR7010 + AR9280, UB94 */ AR9287_USB = 2, /* AR7010 + AR9287, UB95 */ + STORAGE_DEVICE = 3, }; #define AR_DEVID_7010(_ah) \ -- cgit v1.2.3 From a97b478c92c14255d375ed9ceb7a882083523593 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:48:00 +0530 Subject: ath9k_htc: Allow upto two simultaneous interfaces Multiple interfaces can be configured if a slot is free on the target. Monitor mode also requires a slot. The maximum number of stations that can be handled in the firmware is 8, manage the station slots accordingly. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 7 ++ drivers/net/wireless/ath/ath9k/htc_drv_main.c | 148 ++++++++++++++++++-------- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 29 +++-- 3 files changed, 130 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 0cb504d7b8c4..ab8d1f0cba13 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -204,6 +204,8 @@ struct ath9k_htc_target_stats { __be32 ht_tx_xretries; } __packed; +#define ATH9K_HTC_MAX_VIF 2 + struct ath9k_htc_vif { u8 index; }; @@ -358,6 +360,11 @@ struct ath9k_htc_priv { enum htc_endpoint_id data_vi_ep; enum htc_endpoint_id data_vo_ep; + u8 vif_slot; + u8 mon_vif_idx; + u8 sta_slot; + u8 vif_sta_pos[ATH9K_HTC_MAX_VIF]; + u16 op_flags; u16 curtxpow; u16 txpowlimit; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 50fde0e10595..618670d318c5 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -227,6 +227,13 @@ err: return ret; } +/* + * Monitor mode handling is a tad complicated because the firmware requires + * an interface to be created exclusively, while mac80211 doesn't associate + * an interface with the mode. + * + * So, for now, only one monitor interface can be configured. + */ static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv) { struct ath_common *common = ath9k_hw_common(priv->ah); @@ -236,9 +243,10 @@ static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv) memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); - hvif.index = 0; /* Should do for now */ + hvif.index = priv->mon_vif_idx; WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); priv->nvifs--; + priv->vif_slot &= ~(1 << priv->mon_vif_idx); } static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) @@ -246,51 +254,69 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) struct ath_common *common = ath9k_hw_common(priv->ah); struct ath9k_htc_target_vif hvif; struct ath9k_htc_target_sta tsta; - int ret = 0; + int ret = 0, sta_idx; u8 cmd_rsp; - if (priv->nvifs > 0) - return -ENOBUFS; + if ((priv->nvifs >= ATH9K_HTC_MAX_VIF) || + (priv->nstations >= ATH9K_HTC_MAX_STA)) { + ret = -ENOBUFS; + goto err_vif; + } - if (priv->nstations >= ATH9K_HTC_MAX_STA) - return -ENOBUFS; + sta_idx = ffz(priv->sta_slot); + if ((sta_idx < 0) || (sta_idx > ATH9K_HTC_MAX_STA)) { + ret = -ENOBUFS; + goto err_vif; + } /* * Add an interface. */ - memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); hvif.opmode = cpu_to_be32(HTC_M_MONITOR); - priv->ah->opmode = NL80211_IFTYPE_MONITOR; - hvif.index = priv->nvifs; + hvif.index = ffz(priv->vif_slot); WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif); if (ret) - return ret; + goto err_vif; + + /* + * Assign the monitor interface index as a special case here. + * This is needed when the interface is brought down. + */ + priv->mon_vif_idx = hvif.index; + priv->vif_slot |= (1 << hvif.index); + + /* + * Set the hardware mode to monitor only if there are no + * other interfaces. + */ + if (!priv->nvifs) + priv->ah->opmode = NL80211_IFTYPE_MONITOR; priv->nvifs++; /* * Associate a station with the interface for packet injection. */ - memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta)); memcpy(&tsta.macaddr, common->macaddr, ETH_ALEN); tsta.is_vif_sta = 1; - tsta.sta_index = priv->nstations; + tsta.sta_index = sta_idx; tsta.vif_index = hvif.index; tsta.maxampdu = 0xffff; WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta); if (ret) { ath_err(common, "Unable to add station entry for monitor mode\n"); - goto err_vif; + goto err_sta; } + priv->sta_slot |= (1 << sta_idx); priv->nstations++; /* @@ -301,15 +327,23 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) ath_dbg(common, ATH_DBG_CONFIG, "Failed to update capability in target\n"); + priv->vif_sta_pos[priv->mon_vif_idx] = sta_idx; priv->ah->is_monitoring = true; + ath_dbg(common, ATH_DBG_CONFIG, + "Attached a monitor interface at idx: %d, sta idx: %d\n", + priv->mon_vif_idx, sta_idx); + return 0; -err_vif: +err_sta: /* * Remove the interface from the target. */ __ath9k_htc_remove_monitor_interface(priv); +err_vif: + ath_dbg(common, ATH_DBG_FATAL, "Unable to attach a monitor interface\n"); + return ret; } @@ -321,7 +355,7 @@ static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv) __ath9k_htc_remove_monitor_interface(priv); - sta_idx = 0; /* Only single interface, for now */ + sta_idx = priv->vif_sta_pos[priv->mon_vif_idx]; WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx); if (ret) { @@ -329,9 +363,14 @@ static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv) return ret; } + priv->sta_slot &= ~(1 << sta_idx); priv->nstations--; priv->ah->is_monitoring = false; + ath_dbg(common, ATH_DBG_CONFIG, + "Removed a monitor interface at idx: %d, sta idx: %d\n", + priv->mon_vif_idx, sta_idx); + return 0; } @@ -343,12 +382,16 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, struct ath9k_htc_target_sta tsta; struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv; struct ath9k_htc_sta *ista; - int ret; + int ret, sta_idx; u8 cmd_rsp; if (priv->nstations >= ATH9K_HTC_MAX_STA) return -ENOBUFS; + sta_idx = ffz(priv->sta_slot); + if ((sta_idx < 0) || (sta_idx > ATH9K_HTC_MAX_STA)) + return -ENOBUFS; + memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta)); if (sta) { @@ -358,13 +401,13 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, tsta.associd = common->curaid; tsta.is_vif_sta = 0; tsta.valid = true; - ista->index = priv->nstations; + ista->index = sta_idx; } else { memcpy(&tsta.macaddr, vif->addr, ETH_ALEN); tsta.is_vif_sta = 1; } - tsta.sta_index = priv->nstations; + tsta.sta_index = sta_idx; tsta.vif_index = avp->index; tsta.maxampdu = 0xffff; if (sta && sta->ht_cap.ht_supported) @@ -379,12 +422,21 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, return ret; } - if (sta) + if (sta) { ath_dbg(common, ATH_DBG_CONFIG, "Added a station entry for: %pM (idx: %d)\n", sta->addr, tsta.sta_index); + } else { + ath_dbg(common, ATH_DBG_CONFIG, + "Added a station entry for VIF %d (idx: %d)\n", + avp->index, tsta.sta_index); + } + priv->sta_slot |= (1 << sta_idx); priv->nstations++; + if (!sta) + priv->vif_sta_pos[avp->index] = sta_idx; + return 0; } @@ -393,6 +445,7 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv, struct ieee80211_sta *sta) { struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv; struct ath9k_htc_sta *ista; int ret; u8 cmd_rsp, sta_idx; @@ -401,7 +454,7 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv, ista = (struct ath9k_htc_sta *) sta->drv_priv; sta_idx = ista->index; } else { - sta_idx = 0; + sta_idx = priv->vif_sta_pos[avp->index]; } WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx); @@ -413,12 +466,19 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv, return ret; } - if (sta) + if (sta) { ath_dbg(common, ATH_DBG_CONFIG, "Removed a station entry for: %pM (idx: %d)\n", sta->addr, sta_idx); + } else { + ath_dbg(common, ATH_DBG_CONFIG, + "Removed a station entry for VIF %d (idx: %d)\n", + avp->index, sta_idx); + } + priv->sta_slot &= ~(1 << sta_idx); priv->nstations--; + return 0; } @@ -1049,21 +1109,16 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) mutex_lock(&priv->mutex); - /* Remove monitor interface here */ - if (ah->opmode == NL80211_IFTYPE_MONITOR) { - if (ath9k_htc_remove_monitor_interface(priv)) - ath_err(common, "Unable to remove monitor interface\n"); - else - ath_dbg(common, ATH_DBG_CONFIG, - "Monitor interface removed\n"); - } - if (ah->btcoex_hw.enabled) { ath9k_hw_btcoex_disable(ah); if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) ath_htc_cancel_btcoex_work(priv); } + /* Remove a monitor interface if it's present. */ + if (priv->ah->is_monitoring) + ath9k_htc_remove_monitor_interface(priv); + ath9k_hw_phy_disable(ah); ath9k_hw_disable(ah); ath9k_htc_ps_restore(priv); @@ -1087,8 +1142,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); - /* Only one interface for now */ - if (priv->nvifs > 0) { + if (priv->nvifs >= ATH9K_HTC_MAX_VIF) { ret = -ENOBUFS; goto out; } @@ -1111,13 +1165,8 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, goto out; } - ath_dbg(common, ATH_DBG_CONFIG, - "Attach a VIF of type: %d\n", vif->type); - - priv->ah->opmode = vif->type; - /* Index starts from zero on the target */ - avp->index = hvif.index = priv->nvifs; + avp->index = hvif.index = ffz(priv->vif_slot); hvif.rtsthreshold = cpu_to_be16(2304); WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif); if (ret) @@ -1138,7 +1187,13 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, ath_dbg(common, ATH_DBG_CONFIG, "Failed to update capability in target\n"); + priv->ah->opmode = vif->type; + priv->vif_slot |= (1 << avp->index); priv->vif = vif; + + ath_dbg(common, ATH_DBG_CONFIG, + "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index); + out: ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); @@ -1156,8 +1211,6 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, int ret = 0; u8 cmd_rsp; - ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n"); - mutex_lock(&priv->mutex); ath9k_htc_ps_wakeup(priv); @@ -1166,10 +1219,13 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, hvif.index = avp->index; WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); priv->nvifs--; + priv->vif_slot &= ~(1 << avp->index); ath9k_htc_remove_station(priv, vif, NULL); priv->vif = NULL; + ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface at idx: %d\n", avp->index); + ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); } @@ -1205,13 +1261,11 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) * IEEE80211_CONF_CHANGE_CHANNEL is handled. */ if (changed & IEEE80211_CONF_CHANGE_MONITOR) { - if (conf->flags & IEEE80211_CONF_MONITOR) { - if (ath9k_htc_add_monitor_interface(priv)) - ath_err(common, "Failed to set monitor mode\n"); - else - ath_dbg(common, ATH_DBG_CONFIG, - "HW opmode set to Monitor mode\n"); - } + if ((conf->flags & IEEE80211_CONF_MONITOR) && + !priv->ah->is_monitoring) + ath9k_htc_add_monitor_interface(priv); + else if (priv->ah->is_monitoring) + ath9k_htc_remove_monitor_interface(priv); } if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 7a5ffca21958..d5f0f41b4dec 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -84,7 +84,9 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) struct ieee80211_hdr *hdr; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_sta *sta = tx_info->control.sta; + struct ieee80211_vif *vif = tx_info->control.vif; struct ath9k_htc_sta *ista; + struct ath9k_htc_vif *avp; struct ath9k_htc_tx_ctl tx_ctl; enum htc_endpoint_id epid; u16 qnum; @@ -95,18 +97,31 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) hdr = (struct ieee80211_hdr *) skb->data; fc = hdr->frame_control; - if (tx_info->control.vif && - (struct ath9k_htc_vif *) tx_info->control.vif->drv_priv) - vif_idx = ((struct ath9k_htc_vif *) - tx_info->control.vif->drv_priv)->index; - else - vif_idx = priv->nvifs; + /* + * Find out on which interface this packet has to be + * sent out. + */ + if (vif) { + avp = (struct ath9k_htc_vif *) vif->drv_priv; + vif_idx = avp->index; + } else { + if (!priv->ah->is_monitoring) { + ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, + "VIF is null, but no monitor interface !\n"); + return -EINVAL; + } + vif_idx = priv->mon_vif_idx; + } + + /* + * Find out which station this packet is destined for. + */ if (sta) { ista = (struct ath9k_htc_sta *) sta->drv_priv; sta_idx = ista->index; } else { - sta_idx = 0; + sta_idx = priv->vif_sta_pos[vif_idx]; } memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); -- cgit v1.2.3 From 1057b7503908e351b399caeeca38f9ef5fcc766c Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:48:09 +0530 Subject: ath9k_htc: Unify target capability updating Update capabilites on the target once, when start() is called, there is no need for redundant updating on adding an interface. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 618670d318c5..4ced5cd6ef1c 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -318,15 +318,6 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) priv->sta_slot |= (1 << sta_idx); priv->nstations++; - - /* - * Set chainmask etc. on the target. - */ - ret = ath9k_htc_update_cap_target(priv); - if (ret) - ath_dbg(common, ATH_DBG_CONFIG, - "Failed to update capability in target\n"); - priv->vif_sta_pos[priv->mon_vif_idx] = sta_idx; priv->ah->is_monitoring = true; @@ -1050,6 +1041,11 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) ath9k_host_rx_init(priv); + ret = ath9k_htc_update_cap_target(priv); + if (ret) + ath_dbg(common, ATH_DBG_CONFIG, + "Failed to update capability in target\n"); + priv->op_flags &= ~OP_INVALID; htc_start(priv->htc); @@ -1182,11 +1178,6 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, if (ret) goto out; - ret = ath9k_htc_update_cap_target(priv); - if (ret) - ath_dbg(common, ATH_DBG_CONFIG, - "Failed to update capability in target\n"); - priv->ah->opmode = vif->type; priv->vif_slot |= (1 << avp->index); priv->vif = vif; -- cgit v1.2.3 From ab77c70a15cdff106704a34254341c9a3a11dbc4 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:48:16 +0530 Subject: ath9k_htc: Fix error handling in add_interface Addition of a station might fail - handle this error properly by removing the VAP on the target. Also, bail out immediately if the max. no of interfaces has been reached. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 4ced5cd6ef1c..ebc5dbfb6a1b 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1140,7 +1140,8 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, if (priv->nvifs >= ATH9K_HTC_MAX_VIF) { ret = -ENOBUFS; - goto out; + mutex_unlock(&priv->mutex); + return ret; } ath9k_htc_ps_wakeup(priv); @@ -1168,18 +1169,19 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, if (ret) goto out; - priv->nvifs++; - /* * We need a node in target to tx mgmt frames * before association. */ ret = ath9k_htc_add_station(priv, vif, NULL); - if (ret) + if (ret) { + WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); goto out; + } priv->ah->opmode = vif->type; priv->vif_slot |= (1 << avp->index); + priv->nvifs++; priv->vif = vif; ath_dbg(common, ATH_DBG_CONFIG, -- cgit v1.2.3 From cf04e77286da4e6625f66133fcab5ecda9e24159 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:48:24 +0530 Subject: ath9k_htc: Remove OP_PREAMBLE_SHORT mac80211's BSS info can be used for this. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 13 ++++++------- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 9 --------- 2 files changed, 6 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index ab8d1f0cba13..ed6af32f963e 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -335,13 +335,12 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv); #define OP_SCANNING BIT(1) #define OP_LED_ASSOCIATED BIT(2) #define OP_LED_ON BIT(3) -#define OP_PREAMBLE_SHORT BIT(4) -#define OP_PROTECT_ENABLE BIT(5) -#define OP_ASSOCIATED BIT(6) -#define OP_ENABLE_BEACON BIT(7) -#define OP_LED_DEINIT BIT(8) -#define OP_BT_PRIORITY_DETECTED BIT(9) -#define OP_BT_SCAN BIT(10) +#define OP_PROTECT_ENABLE BIT(4) +#define OP_ASSOCIATED BIT(5) +#define OP_ENABLE_BEACON BIT(6) +#define OP_LED_DEINIT BIT(7) +#define OP_BT_PRIORITY_DETECTED BIT(8) +#define OP_BT_SCAN BIT(9) struct ath9k_htc_priv { struct device *dev; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index ebc5dbfb6a1b..13e9deca6790 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1524,15 +1524,6 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, ath9k_htc_beacon_config(priv, vif); } - if (changed & BSS_CHANGED_ERP_PREAMBLE) { - ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", - bss_conf->use_short_preamble); - if (bss_conf->use_short_preamble) - priv->op_flags |= OP_PREAMBLE_SHORT; - else - priv->op_flags &= ~OP_PREAMBLE_SHORT; - } - if (changed & BSS_CHANGED_ERP_CTS_PROT) { ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n", bss_conf->use_cts_prot); -- cgit v1.2.3 From 9304c82d8f3b40eb31c2d04f5849fbd9802c06ef Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:48:31 +0530 Subject: ath9k_htc: Remove OP_PROTECT_ENABLE CTS protection can be obtained from mac80211 directly. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 11 +++++------ drivers/net/wireless/ath/ath9k/htc_drv_main.c | 10 ---------- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 2 +- 3 files changed, 6 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index ed6af32f963e..4e19e14e8c11 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -335,12 +335,11 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv); #define OP_SCANNING BIT(1) #define OP_LED_ASSOCIATED BIT(2) #define OP_LED_ON BIT(3) -#define OP_PROTECT_ENABLE BIT(4) -#define OP_ASSOCIATED BIT(5) -#define OP_ENABLE_BEACON BIT(6) -#define OP_LED_DEINIT BIT(7) -#define OP_BT_PRIORITY_DETECTED BIT(8) -#define OP_BT_SCAN BIT(9) +#define OP_ASSOCIATED BIT(4) +#define OP_ENABLE_BEACON BIT(5) +#define OP_LED_DEINIT BIT(6) +#define OP_BT_PRIORITY_DETECTED BIT(7) +#define OP_BT_SCAN BIT(8) struct ath9k_htc_priv { struct device *dev; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 13e9deca6790..dbde491f3d9c 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1524,16 +1524,6 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, ath9k_htc_beacon_config(priv, vif); } - if (changed & BSS_CHANGED_ERP_CTS_PROT) { - ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n", - bss_conf->use_cts_prot); - if (bss_conf->use_cts_prot && - hw->conf.channel->band != IEEE80211_BAND_5GHZ) - priv->op_flags |= OP_PROTECT_ENABLE; - else - priv->op_flags &= ~OP_PROTECT_ENABLE; - } - if (changed & BSS_CHANGED_ERP_SLOT) { if (bss_conf->use_short_slot) ah->slottime = 9; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index d5f0f41b4dec..884deebf8e01 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -156,7 +156,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) /* CTS-to-self */ if (!(flags & ATH9K_HTC_TX_RTSCTS) && - (priv->op_flags & OP_PROTECT_ENABLE)) + (vif && vif->bss_conf.use_cts_prot)) flags |= ATH9K_HTC_TX_CTSONLY; tx_hdr.flags = cpu_to_be32(flags); -- cgit v1.2.3 From 7c277349ecbd66e19fad3d949fa6ef6c131a3b62 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:48:39 +0530 Subject: ath9k_htc: Remove OP_ASSOCIATED variable mac80211 stores the association state in ieee80211_bss_conf. Use this and remove the local state, which is incorrect anyway since it is stored globally and not on a per-VIF basis. Restarting ANI and reconfiguration of HW beacon timers when a scan run ends requires more work. This is handled by iterating over the active interfaces. Finally, remove the useless check for associated status in RX processing. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 14 ++++--- drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 19 +++++++++ drivers/net/wireless/ath/ath9k/htc_drv_main.c | 56 +++++++++++++++---------- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 26 ++++++------ 4 files changed, 74 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 4e19e14e8c11..eecb42b24bc5 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -335,11 +335,10 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv); #define OP_SCANNING BIT(1) #define OP_LED_ASSOCIATED BIT(2) #define OP_LED_ON BIT(3) -#define OP_ASSOCIATED BIT(4) -#define OP_ENABLE_BEACON BIT(5) -#define OP_LED_DEINIT BIT(6) -#define OP_BT_PRIORITY_DETECTED BIT(7) -#define OP_BT_SCAN BIT(8) +#define OP_ENABLE_BEACON BIT(4) +#define OP_LED_DEINIT BIT(5) +#define OP_BT_PRIORITY_DETECTED BIT(6) +#define OP_BT_SCAN BIT(7) struct ath9k_htc_priv { struct device *dev; @@ -370,6 +369,8 @@ struct ath9k_htc_priv { u16 nstations; u16 seq_no; u32 bmiss_cnt; + bool rearm_ani; + bool reconfig_beacon; struct ath9k_hw_cal_data caldata; @@ -429,6 +430,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv); void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv); void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif); +void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv); void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending); void ath9k_htc_rxep(void *priv, struct sk_buff *skb, @@ -441,7 +443,7 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv); void ath9k_htc_station_work(struct work_struct *work); void ath9k_htc_aggr_work(struct work_struct *work); -void ath9k_ani_work(struct work_struct *work);; +void ath9k_ani_work(struct work_struct *work); void ath_start_ani(struct ath9k_htc_priv *priv); int ath9k_tx_init(struct ath9k_htc_priv *priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 87cc65a78a3f..133f628dc086 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -283,3 +283,22 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, return; } } + +void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf; + + switch (priv->ah->opmode) { + case NL80211_IFTYPE_STATION: + ath9k_htc_beacon_config_sta(priv, cur_conf); + break; + case NL80211_IFTYPE_ADHOC: + ath9k_htc_beacon_config_adhoc(priv, cur_conf); + break; + default: + ath_dbg(common, ATH_DBG_CONFIG, + "Unsupported beaconing mode\n"); + return; + } +} diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index dbde491f3d9c..5ef076978181 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -105,6 +105,34 @@ void ath9k_ps_work(struct work_struct *work) ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP); } +static void ath9k_htc_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) +{ + struct ath9k_htc_priv *priv = data; + struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + + if (bss_conf->assoc) { + priv->rearm_ani = true; + priv->reconfig_beacon = true; + } +} + +static void ath9k_htc_vif_reconfig(struct ath9k_htc_priv *priv) +{ + priv->rearm_ani = false; + priv->reconfig_beacon = false; + + ieee80211_iterate_active_interfaces_atomic(priv->hw, + ath9k_htc_vif_iter, priv); + if (priv->rearm_ani) + ath_start_ani(priv); + + if (priv->reconfig_beacon) { + ath9k_htc_ps_wakeup(priv); + ath9k_htc_beacon_reconfig(priv); + ath9k_htc_ps_restore(priv); + } +} + void ath9k_htc_reset(struct ath9k_htc_priv *priv) { struct ath_hw *ah = priv->ah; @@ -119,9 +147,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) mutex_lock(&priv->mutex); ath9k_htc_ps_wakeup(priv); - if (priv->op_flags & OP_ASSOCIATED) - cancel_delayed_work_sync(&priv->ath9k_ani_work); - + cancel_delayed_work_sync(&priv->ath9k_ani_work); ieee80211_stop_queues(priv->hw); htc_stop(priv->htc); WMI_CMD(WMI_DISABLE_INTR_CMDID); @@ -148,12 +174,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) WMI_CMD(WMI_ENABLE_INTR_CMDID); htc_start(priv->htc); - - if (priv->op_flags & OP_ASSOCIATED) { - ath9k_htc_beacon_config(priv, priv->vif); - ath_start_ani(priv); - } - + ath9k_htc_vif_reconfig(priv); ieee80211_wake_queues(priv->hw); ath9k_htc_ps_restore(priv); @@ -1491,13 +1512,10 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", bss_conf->assoc); - if (bss_conf->assoc) { - priv->op_flags |= OP_ASSOCIATED; + if (bss_conf->assoc) ath_start_ani(priv); - } else { - priv->op_flags &= ~OP_ASSOCIATED; + else cancel_delayed_work_sync(&priv->ath9k_ani_work); - } } if (changed & BSS_CHANGED_BSSID) { @@ -1622,8 +1640,7 @@ static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw) priv->op_flags |= OP_SCANNING; spin_unlock_bh(&priv->beacon_lock); cancel_work_sync(&priv->ps_work); - if (priv->op_flags & OP_ASSOCIATED) - cancel_delayed_work_sync(&priv->ath9k_ani_work); + cancel_delayed_work_sync(&priv->ath9k_ani_work); mutex_unlock(&priv->mutex); } @@ -1632,14 +1649,11 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw) struct ath9k_htc_priv *priv = hw->priv; mutex_lock(&priv->mutex); - ath9k_htc_ps_wakeup(priv); spin_lock_bh(&priv->beacon_lock); priv->op_flags &= ~OP_SCANNING; spin_unlock_bh(&priv->beacon_lock); - if (priv->op_flags & OP_ASSOCIATED) { - ath9k_htc_beacon_config(priv, priv->vif); - ath_start_ani(priv); - } + ath9k_htc_ps_wakeup(priv); + ath9k_htc_vif_reconfig(priv); ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 884deebf8e01..6ddcf939aff5 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -591,24 +591,22 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, ath9k_process_rate(hw, rx_status, rxbuf->rxstatus.rs_rate, rxbuf->rxstatus.rs_flags); - if (priv->op_flags & OP_ASSOCIATED) { - if (rxbuf->rxstatus.rs_rssi != ATH9K_RSSI_BAD && - !rxbuf->rxstatus.rs_moreaggr) - ATH_RSSI_LPF(priv->rx.last_rssi, - rxbuf->rxstatus.rs_rssi); + if (rxbuf->rxstatus.rs_rssi != ATH9K_RSSI_BAD && + !rxbuf->rxstatus.rs_moreaggr) + ATH_RSSI_LPF(priv->rx.last_rssi, + rxbuf->rxstatus.rs_rssi); - last_rssi = priv->rx.last_rssi; + last_rssi = priv->rx.last_rssi; - if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) - rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi, - ATH_RSSI_EP_MULTIPLIER); + if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) + rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi, + ATH_RSSI_EP_MULTIPLIER); - if (rxbuf->rxstatus.rs_rssi < 0) - rxbuf->rxstatus.rs_rssi = 0; + if (rxbuf->rxstatus.rs_rssi < 0) + rxbuf->rxstatus.rs_rssi = 0; - if (ieee80211_is_beacon(fc)) - priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi; - } + if (ieee80211_is_beacon(fc)) + priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi; rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp); rx_status->band = hw->conf.channel->band; -- cgit v1.2.3 From 585895cdfc683a067d803fead83267cee309ffd0 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:48:46 +0530 Subject: ath9k_htc: Set the BSSID mask for multiple interfaces Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 5 ++++ drivers/net/wireless/ath/ath9k/htc_drv_main.c | 35 +++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index eecb42b24bc5..11d028f2156e 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -210,6 +210,11 @@ struct ath9k_htc_vif { u8 index; }; +struct ath9k_vif_iter_data { + const u8 *hw_macaddr; + u8 mask[ETH_ALEN]; +}; + #define ATH9K_HTC_MAX_STA 8 #define ATH9K_HTC_MAX_TID 8 diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 5ef076978181..9620f4532f02 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -133,6 +133,39 @@ static void ath9k_htc_vif_reconfig(struct ath9k_htc_priv *priv) } } +static void ath9k_htc_bssid_iter(void *data, u8 *mac, struct ieee80211_vif *vif) +{ + struct ath9k_vif_iter_data *iter_data = data; + int i; + + for (i = 0; i < ETH_ALEN; i++) + iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]); +} + +static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_vif_iter_data iter_data; + + /* + * Use the hardware MAC address as reference, the hardware uses it + * together with the BSSID mask when matching addresses. + */ + iter_data.hw_macaddr = common->macaddr; + memset(&iter_data.mask, 0xff, ETH_ALEN); + + if (vif) + ath9k_htc_bssid_iter(&iter_data, vif->addr, vif); + + /* Get list of all active MAC addresses */ + ieee80211_iterate_active_interfaces_atomic(priv->hw, ath9k_htc_bssid_iter, + &iter_data); + + memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); + ath_hw_setbssidmask(common); +} + void ath9k_htc_reset(struct ath9k_htc_priv *priv) { struct ath_hw *ah = priv->ah; @@ -1200,6 +1233,8 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, goto out; } + ath9k_htc_set_bssid_mask(priv, vif); + priv->ah->opmode = vif->type; priv->vif_slot |= (1 << avp->index); priv->nvifs++; -- cgit v1.2.3 From 9a3d025be11a1da625f8a71636b55a3bd3718574 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:48:53 +0530 Subject: ath9k_htc: Make sequence number calculation per-VIF Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 11d028f2156e..97f7ae096f69 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -208,6 +208,7 @@ struct ath9k_htc_target_stats { struct ath9k_htc_vif { u8 index; + u16 seq_no; }; struct ath9k_vif_iter_data { @@ -372,7 +373,6 @@ struct ath9k_htc_priv { u16 txpowlimit; u16 nvifs; u16 nstations; - u16 seq_no; u32 bmiss_cnt; bool rearm_ani; bool reconfig_beacon; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 133f628dc086..bbbdd60bcb3e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -207,9 +207,9 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) beacon->data; - priv->seq_no += 0x10; + avp->seq_no += 0x10; hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); - hdr->seq_ctrl |= cpu_to_le16(priv->seq_no); + hdr->seq_ctrl |= cpu_to_le16(avp->seq_no); } tx_ctl.type = ATH9K_HTC_NORMAL; -- cgit v1.2.3 From 2299423bd0e32ccef78bbf1d4075617e3fd6cfd3 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:49:00 +0530 Subject: ath9k_htc: Use VIF from the packet's control data There is no need to use a locally stored reference. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 6ddcf939aff5..04d824863d97 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -232,6 +232,7 @@ static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, void ath9k_tx_tasklet(unsigned long data) { struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; + struct ieee80211_vif *vif; struct ieee80211_sta *sta; struct ieee80211_hdr *hdr; struct ieee80211_tx_info *tx_info; @@ -243,12 +244,16 @@ void ath9k_tx_tasklet(unsigned long data) hdr = (struct ieee80211_hdr *) skb->data; fc = hdr->frame_control; tx_info = IEEE80211_SKB_CB(skb); + vif = tx_info->control.vif; memset(&tx_info->status, 0, sizeof(tx_info->status)); + if (!vif) + goto send_mac80211; + rcu_read_lock(); - sta = ieee80211_find_sta(priv->vif, hdr->addr1); + sta = ieee80211_find_sta(vif, hdr->addr1); if (!sta) { rcu_read_unlock(); ieee80211_tx_status(priv->hw, skb); @@ -278,6 +283,7 @@ void ath9k_tx_tasklet(unsigned long data) rcu_read_unlock(); + send_mac80211: /* Send status to mac80211 */ ieee80211_tx_status(priv->hw, skb); } -- cgit v1.2.3 From 87df89579a4a3e6c767603acb762115159655745 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:49:08 +0530 Subject: ath9k_htc: Protect ampdu_action with a mutex This is required when issuing commands to the firmware. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 9620f4532f02..04cb243416ae 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1639,6 +1639,8 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, struct ath9k_htc_sta *ista; int ret = 0; + mutex_lock(&priv->mutex); + switch (action) { case IEEE80211_AMPDU_RX_START: break; @@ -1663,6 +1665,8 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n"); } + mutex_unlock(&priv->mutex); + return ret; } -- cgit v1.2.3 From 0df8359a88f40ab3b0d38156a5f41ee856178aa3 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:49:15 +0530 Subject: ath9k_htc: Maintain individual counters for interfaces This is required for allowing only one IBSS interface to be configured. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 28 +++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/htc_drv_main.c | 14 ++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 97f7ae096f69..0088c6e2f629 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -206,6 +206,32 @@ struct ath9k_htc_target_stats { #define ATH9K_HTC_MAX_VIF 2 +#define INC_VIF(_priv, _type) do { \ + switch (_type) { \ + case NL80211_IFTYPE_STATION: \ + _priv->num_sta_vif++; \ + break; \ + case NL80211_IFTYPE_ADHOC: \ + _priv->num_ibss_vif++; \ + break; \ + default: \ + break; \ + } \ + } while (0) + +#define DEC_VIF(_priv, _type) do { \ + switch (_type) { \ + case NL80211_IFTYPE_STATION: \ + _priv->num_sta_vif--; \ + break; \ + case NL80211_IFTYPE_ADHOC: \ + _priv->num_ibss_vif--; \ + break; \ + default: \ + break; \ + } \ + } while (0) + struct ath9k_htc_vif { u8 index; u16 seq_no; @@ -367,6 +393,8 @@ struct ath9k_htc_priv { u8 mon_vif_idx; u8 sta_slot; u8 vif_sta_pos[ATH9K_HTC_MAX_VIF]; + u8 num_ibss_vif; + u8 num_sta_vif; u16 op_flags; u16 curtxpow; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 04cb243416ae..39074fc72d6f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1193,9 +1193,15 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); if (priv->nvifs >= ATH9K_HTC_MAX_VIF) { - ret = -ENOBUFS; mutex_unlock(&priv->mutex); - return ret; + return -ENOBUFS; + } + + if (priv->num_ibss_vif || + (priv->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) { + ath_err(common, "IBSS coexistence with other modes is not allowed\n"); + mutex_unlock(&priv->mutex); + return -ENOBUFS; } ath9k_htc_ps_wakeup(priv); @@ -1240,6 +1246,8 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, priv->nvifs++; priv->vif = vif; + INC_VIF(priv, vif->type); + ath_dbg(common, ATH_DBG_CONFIG, "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index); @@ -1273,6 +1281,8 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, ath9k_htc_remove_station(priv, vif, NULL); priv->vif = NULL; + DEC_VIF(priv, vif->type); + ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface at idx: %d\n", avp->index); ath9k_htc_ps_restore(priv); -- cgit v1.2.3 From da8d9d937b34cf5d82e01420d015d8ee14f76467 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:49:23 +0530 Subject: ath9k_htc: Allow AP interface to be created Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 8 ++++++++ drivers/net/wireless/ath/ath9k/htc_drv_main.c | 11 +++++++++++ 2 files changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 0088c6e2f629..b21942818b13 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -205,6 +205,7 @@ struct ath9k_htc_target_stats { } __packed; #define ATH9K_HTC_MAX_VIF 2 +#define ATH9K_HTC_MAX_BCN_VIF 2 #define INC_VIF(_priv, _type) do { \ switch (_type) { \ @@ -214,6 +215,9 @@ struct ath9k_htc_target_stats { case NL80211_IFTYPE_ADHOC: \ _priv->num_ibss_vif++; \ break; \ + case NL80211_IFTYPE_AP: \ + _priv->num_ap_vif++; \ + break; \ default: \ break; \ } \ @@ -227,6 +231,9 @@ struct ath9k_htc_target_stats { case NL80211_IFTYPE_ADHOC: \ _priv->num_ibss_vif--; \ break; \ + case NL80211_IFTYPE_AP: \ + _priv->num_ap_vif--; \ + break; \ default: \ break; \ } \ @@ -395,6 +402,7 @@ struct ath9k_htc_priv { u8 vif_sta_pos[ATH9K_HTC_MAX_VIF]; u8 num_ibss_vif; u8 num_sta_vif; + u8 num_ap_vif; u16 op_flags; u16 curtxpow; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 39074fc72d6f..51a8c51510e8 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1204,6 +1204,14 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, return -ENOBUFS; } + if (((vif->type == NL80211_IFTYPE_AP) || + (vif->type == NL80211_IFTYPE_ADHOC)) && + ((priv->num_ap_vif + priv->num_ibss_vif) >= ATH9K_HTC_MAX_BCN_VIF)) { + ath_err(common, "Max. number of beaconing interfaces reached\n"); + mutex_unlock(&priv->mutex); + return -ENOBUFS; + } + ath9k_htc_ps_wakeup(priv); memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); memcpy(&hvif.myaddr, vif->addr, ETH_ALEN); @@ -1215,6 +1223,9 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, case NL80211_IFTYPE_ADHOC: hvif.opmode = cpu_to_be32(HTC_M_IBSS); break; + case NL80211_IFTYPE_AP: + hvif.opmode = cpu_to_be32(HTC_M_HOSTAP); + break; default: ath_err(common, "Interface type %d not yet supported\n", vif->type); -- cgit v1.2.3 From ffbe7c83cb4a9d05ff49cdc8e2b02b88ccbae826 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:49:31 +0530 Subject: ath9k_htc: Calculate and set the HW opmode Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 51a8c51510e8..9733580579a9 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -166,6 +166,18 @@ static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv, ath_hw_setbssidmask(common); } +static void ath9k_htc_set_opmode(struct ath9k_htc_priv *priv) +{ + if (priv->num_ibss_vif) + priv->ah->opmode = NL80211_IFTYPE_ADHOC; + else if (priv->num_ap_vif) + priv->ah->opmode = NL80211_IFTYPE_AP; + else + priv->ah->opmode = NL80211_IFTYPE_STATION; + + ath9k_hw_setopmode(priv->ah); +} + void ath9k_htc_reset(struct ath9k_htc_priv *priv) { struct ath_hw *ah = priv->ah; @@ -1252,12 +1264,12 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, ath9k_htc_set_bssid_mask(priv, vif); - priv->ah->opmode = vif->type; priv->vif_slot |= (1 << avp->index); priv->nvifs++; priv->vif = vif; INC_VIF(priv, vif->type); + ath9k_htc_set_opmode(priv); ath_dbg(common, ATH_DBG_CONFIG, "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index); @@ -1293,6 +1305,7 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, priv->vif = NULL; DEC_VIF(priv, vif->type); + ath9k_htc_set_opmode(priv); ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface at idx: %d\n", avp->index); -- cgit v1.2.3 From a236254c35f04a4d47c701ed3ec4a0b5dcb097b0 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:49:38 +0530 Subject: ath9k_htc: Add ANI for AP mode The time granularity for the ANI task is different for AP and station mode. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 9 +++-- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 49 ++++++++++++++++++++------- 3 files changed, 43 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index b21942818b13..5b0a21a14279 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -32,6 +32,7 @@ #include "wmi.h" #define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */ +#define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */ #define ATH_ANI_POLLINTERVAL 100 /* 100 ms */ #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ @@ -378,6 +379,7 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv); #define OP_LED_DEINIT BIT(5) #define OP_BT_PRIORITY_DETECTED BIT(6) #define OP_BT_SCAN BIT(7) +#define OP_ANI_RUNNING BIT(8) struct ath9k_htc_priv { struct device *dev; @@ -429,7 +431,7 @@ struct ath9k_htc_priv { struct ath9k_htc_rx rx; struct tasklet_struct tx_tasklet; struct sk_buff_head tx_queue; - struct delayed_work ath9k_ani_work; + struct delayed_work ani_work; struct work_struct ps_work; struct work_struct fatal_work; @@ -484,8 +486,9 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv); void ath9k_htc_station_work(struct work_struct *work); void ath9k_htc_aggr_work(struct work_struct *work); -void ath9k_ani_work(struct work_struct *work); -void ath_start_ani(struct ath9k_htc_priv *priv); +void ath9k_htc_ani_work(struct work_struct *work); +void ath9k_htc_start_ani(struct ath9k_htc_priv *priv); +void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv); int ath9k_tx_init(struct ath9k_htc_priv *priv); void ath9k_tx_tasklet(unsigned long data); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index a7bc26d1bd66..52c6af2d6341 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -679,7 +679,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, (unsigned long)priv); tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, (unsigned long)priv); - INIT_DELAYED_WORK(&priv->ath9k_ani_work, ath9k_ani_work); + INIT_DELAYED_WORK(&priv->ani_work, ath9k_htc_ani_work); INIT_WORK(&priv->ps_work, ath9k_ps_work); INIT_WORK(&priv->fatal_work, ath9k_fatal_work); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 9733580579a9..f384b358b48d 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -124,7 +124,7 @@ static void ath9k_htc_vif_reconfig(struct ath9k_htc_priv *priv) ieee80211_iterate_active_interfaces_atomic(priv->hw, ath9k_htc_vif_iter, priv); if (priv->rearm_ani) - ath_start_ani(priv); + ath9k_htc_start_ani(priv); if (priv->reconfig_beacon) { ath9k_htc_ps_wakeup(priv); @@ -192,7 +192,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv) mutex_lock(&priv->mutex); ath9k_htc_ps_wakeup(priv); - cancel_delayed_work_sync(&priv->ath9k_ani_work); + ath9k_htc_stop_ani(priv); ieee80211_stop_queues(priv->hw); htc_stop(priv->htc); WMI_CMD(WMI_DISABLE_INTR_CMDID); @@ -917,7 +917,7 @@ void ath9k_htc_debug_remove_root(void) /* ANI */ /*******/ -void ath_start_ani(struct ath9k_htc_priv *priv) +void ath9k_htc_start_ani(struct ath9k_htc_priv *priv) { struct ath_common *common = ath9k_hw_common(priv->ah); unsigned long timestamp = jiffies_to_msecs(jiffies); @@ -926,15 +926,22 @@ void ath_start_ani(struct ath9k_htc_priv *priv) common->ani.shortcal_timer = timestamp; common->ani.checkani_timer = timestamp; - ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work, + priv->op_flags |= OP_ANI_RUNNING; + + ieee80211_queue_delayed_work(common->hw, &priv->ani_work, msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); } -void ath9k_ani_work(struct work_struct *work) +void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv) +{ + cancel_delayed_work_sync(&priv->ani_work); + priv->op_flags &= ~OP_ANI_RUNNING; +} + +void ath9k_htc_ani_work(struct work_struct *work) { struct ath9k_htc_priv *priv = - container_of(work, struct ath9k_htc_priv, - ath9k_ani_work.work); + container_of(work, struct ath9k_htc_priv, ani_work.work); struct ath_hw *ah = priv->ah; struct ath_common *common = ath9k_hw_common(ah); bool longcal = false; @@ -943,7 +950,8 @@ void ath9k_ani_work(struct work_struct *work) unsigned int timestamp = jiffies_to_msecs(jiffies); u32 cal_interval, short_cal_interval; - short_cal_interval = ATH_STA_SHORT_CALINTERVAL; + short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ? + ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL; /* Only calibrate if awake */ if (ah->power_mode != ATH9K_PM_AWAKE) @@ -1012,7 +1020,7 @@ set_timer: if (!common->ani.caldone) cal_interval = min(cal_interval, (u32)short_cal_interval); - ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work, + ieee80211_queue_delayed_work(common->hw, &priv->ani_work, msecs_to_jiffies(cal_interval)); } @@ -1166,7 +1174,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) cancel_work_sync(&priv->fatal_work); cancel_work_sync(&priv->ps_work); cancel_delayed_work_sync(&priv->ath9k_led_blink_work); - cancel_delayed_work_sync(&priv->ath9k_ani_work); + ath9k_htc_stop_ani(priv); ath9k_led_stop_brightness(priv); mutex_lock(&priv->mutex); @@ -1271,6 +1279,10 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, INC_VIF(priv, vif->type); ath9k_htc_set_opmode(priv); + if ((priv->ah->opmode == NL80211_IFTYPE_AP) && + !(priv->op_flags & OP_ANI_RUNNING)) + ath9k_htc_start_ani(priv); + ath_dbg(common, ATH_DBG_CONFIG, "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index); @@ -1307,6 +1319,17 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, DEC_VIF(priv, vif->type); ath9k_htc_set_opmode(priv); + /* + * Stop ANI only if there are no associated station interfaces. + */ + if ((vif->type == NL80211_IFTYPE_AP) && (priv->num_ap_vif == 0)) { + priv->rearm_ani = false; + ieee80211_iterate_active_interfaces_atomic(priv->hw, + ath9k_htc_vif_iter, priv); + if (!priv->rearm_ani) + ath9k_htc_stop_ani(priv); + } + ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface at idx: %d\n", avp->index); ath9k_htc_ps_restore(priv); @@ -1582,9 +1605,9 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, bss_conf->assoc); if (bss_conf->assoc) - ath_start_ani(priv); + ath9k_htc_start_ani(priv); else - cancel_delayed_work_sync(&priv->ath9k_ani_work); + ath9k_htc_stop_ani(priv); } if (changed & BSS_CHANGED_BSSID) { @@ -1713,7 +1736,7 @@ static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw) priv->op_flags |= OP_SCANNING; spin_unlock_bh(&priv->beacon_lock); cancel_work_sync(&priv->ps_work); - cancel_delayed_work_sync(&priv->ath9k_ani_work); + ath9k_htc_stop_ani(priv); mutex_unlock(&priv->mutex); } -- cgit v1.2.3 From a5fae37d118bb633708b2787e53871e38bf3b15e Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:49:53 +0530 Subject: ath9k_htc: Configure beacon timers in AP mode Handle multi-interface situations by checking if AP interfaces are already present. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 3 +- drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 78 ++++++++++++++++++++++++- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 45 +++++++++++--- drivers/net/wireless/ath/ath9k/wmi.c | 4 -- 4 files changed, 115 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 5b0a21a14279..e9c51cae88ab 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -352,10 +352,8 @@ struct ath_led { struct htc_beacon_config { u16 beacon_interval; - u16 listen_interval; u16 dtim_period; u16 bmiss_timeout; - u8 dtim_count; }; struct ath_btcoex { @@ -380,6 +378,7 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv); #define OP_BT_PRIORITY_DETECTED BIT(6) #define OP_BT_SCAN BIT(7) #define OP_ANI_RUNNING BIT(8) +#define OP_TSF_RESET BIT(9) struct ath9k_htc_priv { struct device *dev; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index bbbdd60bcb3e..e897a56695b2 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -138,6 +138,51 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); } +static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, + struct htc_beacon_config *bss_conf) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + enum ath9k_int imask = 0; + u32 nexttbtt, intval, tsftu; + __be32 htc_imask = 0; + int ret; + u8 cmd_rsp; + u64 tsf; + + intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD; + intval /= ATH9K_HTC_MAX_BCN_VIF; + nexttbtt = intval; + + if (priv->op_flags & OP_TSF_RESET) { + intval |= ATH9K_BEACON_RESET_TSF; + priv->op_flags &= ~OP_TSF_RESET; + } else { + /* + * Pull nexttbtt forward to reflect the current TSF. + */ + tsf = ath9k_hw_gettsf64(priv->ah); + tsftu = TSF_TO_TU(tsf >> 32, tsf) + FUDGE; + do { + nexttbtt += intval; + } while (nexttbtt < tsftu); + } + + intval |= ATH9K_BEACON_ENA; + + if (priv->op_flags & OP_ENABLE_BEACON) + imask |= ATH9K_INT_SWBA; + + ath_dbg(common, ATH_DBG_CONFIG, + "AP Beacon config, intval: %d, nexttbtt: %u imask: 0x%x\n", + bss_conf->beacon_interval, nexttbtt, imask); + + WMI_CMD(WMI_DISABLE_INTR_CMDID); + ath9k_hw_beaconinit(priv->ah, nexttbtt, intval); + priv->bmiss_cnt = 0; + htc_imask = cpu_to_be32(imask); + WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); +} + static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, struct htc_beacon_config *bss_conf) { @@ -260,13 +305,36 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf; struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + /* + * Changing the beacon interval when multiple AP interfaces + * are configured will affect beacon transmission of all + * of them. + */ + if ((priv->ah->opmode == NL80211_IFTYPE_AP) && + (priv->num_ap_vif > 1) && + (vif->type == NL80211_IFTYPE_AP) && + (cur_conf->beacon_interval != bss_conf->beacon_int)) { + ath_dbg(common, ATH_DBG_CONFIG, + "Changing beacon interval of multiple AP interfaces !\n"); + return; + } + + /* + * If the HW is operating in AP mode, any new station interfaces that + * are added cannot change the beacon parameters. + */ + if (priv->num_ap_vif && + (vif->type != NL80211_IFTYPE_AP)) { + ath_dbg(common, ATH_DBG_CONFIG, + "HW in AP mode, cannot set STA beacon parameters\n"); + return; + } + cur_conf->beacon_interval = bss_conf->beacon_int; if (cur_conf->beacon_interval == 0) cur_conf->beacon_interval = 100; cur_conf->dtim_period = bss_conf->dtim_period; - cur_conf->listen_interval = 1; - cur_conf->dtim_count = 1; cur_conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval; @@ -277,6 +345,9 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, case NL80211_IFTYPE_ADHOC: ath9k_htc_beacon_config_adhoc(priv, cur_conf); break; + case NL80211_IFTYPE_AP: + ath9k_htc_beacon_config_ap(priv, cur_conf); + break; default: ath_dbg(common, ATH_DBG_CONFIG, "Unsupported beaconing mode\n"); @@ -296,6 +367,9 @@ void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv) case NL80211_IFTYPE_ADHOC: ath9k_htc_beacon_config_adhoc(priv, cur_conf); break; + case NL80211_IFTYPE_AP: + ath9k_htc_beacon_config_ap(priv, cur_conf); + break; default: ath_dbg(common, ATH_DBG_CONFIG, "Unsupported beaconing mode\n"); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index f384b358b48d..7367d6c1c649 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -110,6 +110,9 @@ static void ath9k_htc_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) struct ath9k_htc_priv *priv = data; struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + if ((vif->type == NL80211_IFTYPE_AP) && bss_conf->enable_beacon) + priv->reconfig_beacon = true; + if (bss_conf->assoc) { priv->rearm_ani = true; priv->reconfig_beacon = true; @@ -288,6 +291,11 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, goto err; htc_start(priv->htc); + + if (!(priv->op_flags & OP_SCANNING) && + !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) + ath9k_htc_vif_reconfig(priv); + err: ath9k_htc_ps_restore(priv); return ret; @@ -1620,17 +1628,40 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, common->curbssid, common->curaid); } - if ((changed & BSS_CHANGED_BEACON_INT) || - (changed & BSS_CHANGED_BEACON) || - ((changed & BSS_CHANGED_BEACON_ENABLED) && - bss_conf->enable_beacon)) { + if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) { + ath_dbg(common, ATH_DBG_CONFIG, + "Beacon enabled for BSS: %pM\n", bss_conf->bssid); priv->op_flags |= OP_ENABLE_BEACON; ath9k_htc_beacon_config(priv, vif); } - if ((changed & BSS_CHANGED_BEACON_ENABLED) && - !bss_conf->enable_beacon) { - priv->op_flags &= ~OP_ENABLE_BEACON; + if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) { + /* + * Disable SWBA interrupt only if there are no + * AP/IBSS interfaces. + */ + if ((priv->num_ap_vif <= 1) || priv->num_ibss_vif) { + ath_dbg(common, ATH_DBG_CONFIG, + "Beacon disabled for BSS: %pM\n", + bss_conf->bssid); + priv->op_flags &= ~OP_ENABLE_BEACON; + ath9k_htc_beacon_config(priv, vif); + } + } + + if (changed & BSS_CHANGED_BEACON_INT) { + /* + * Reset the HW TSF for the first AP interface. + */ + if ((priv->ah->opmode == NL80211_IFTYPE_AP) && + (priv->nvifs == 1) && + (priv->num_ap_vif == 1) && + (vif->type == NL80211_IFTYPE_AP)) { + priv->op_flags |= OP_TSF_RESET; + } + ath_dbg(common, ATH_DBG_CONFIG, + "Beacon interval changed for BSS: %pM\n", + bss_conf->bssid); ath9k_htc_beacon_config(priv, vif); } diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index dc862f5e1162..d3d24904f62f 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -123,12 +123,8 @@ void ath9k_deinit_wmi(struct ath9k_htc_priv *priv) void ath9k_swba_tasklet(unsigned long data) { struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; - struct ath_common *common = ath9k_hw_common(priv->ah); - - ath_dbg(common, ATH_DBG_WMI, "SWBA Event received\n"); ath9k_htc_swba(priv, priv->wmi->beacon_pending); - } void ath9k_fatal_work(struct work_struct *work) -- cgit v1.2.3 From 200be651f77f8407086873520436bf55a4468e26 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:50:01 +0530 Subject: ath9k_htc: Fix TBTT calculation for IBSS mode The target beacon transmission time has to be synced with the HW TSF when configuring beacon timers in Adhoc mode. Failing to do this would cause erroneous beacon transmission, for example, on completion of a scan run to check for IBSS merges. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index e897a56695b2..007b99fc50c8 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -188,20 +188,31 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, { struct ath_common *common = ath9k_hw_common(priv->ah); enum ath9k_int imask = 0; - u32 nexttbtt, intval; + u32 nexttbtt, intval, tsftu; __be32 htc_imask = 0; int ret; u8 cmd_rsp; + u64 tsf; intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD; nexttbtt = intval; + + /* + * Pull nexttbtt forward to reflect the current TSF. + */ + tsf = ath9k_hw_gettsf64(priv->ah); + tsftu = TSF_TO_TU(tsf >> 32, tsf) + FUDGE; + do { + nexttbtt += intval; + } while (nexttbtt < tsftu); + intval |= ATH9K_BEACON_ENA; if (priv->op_flags & OP_ENABLE_BEACON) imask |= ATH9K_INT_SWBA; - ath_dbg(common, ATH_DBG_BEACON, - "IBSS Beacon config, intval: %d, imask: 0x%x\n", - bss_conf->beacon_interval, imask); + ath_dbg(common, ATH_DBG_CONFIG, + "IBSS Beacon config, intval: %d, nexttbtt: %u, imask: 0x%x\n", + bss_conf->beacon_interval, nexttbtt, imask); WMI_CMD(WMI_DISABLE_INTR_CMDID); ath9k_hw_beaconinit(priv->ah, nexttbtt, intval); -- cgit v1.2.3 From 88427c65f0f1c98729fd35b458ca402c36ff619d Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:50:15 +0530 Subject: ath9k_htc: Fix host RX initialization There is no need to set the BSSID mask or opmode when initializing RX, they would be set correctly in the HW reset routine. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 04d824863d97..426620a50d5e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -433,20 +433,12 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv) static void ath9k_htc_opmode_init(struct ath9k_htc_priv *priv) { struct ath_hw *ah = priv->ah; - struct ath_common *common = ath9k_hw_common(ah); - u32 rfilt, mfilt[2]; /* configure rx filter */ rfilt = ath9k_htc_calcrxfilter(priv); ath9k_hw_setrxfilter(ah, rfilt); - /* configure bssid mask */ - ath_hw_setbssidmask(common); - - /* configure operational mode */ - ath9k_hw_setopmode(ah); - /* calculate and install multicast filter */ mfilt[0] = mfilt[1] = ~0; ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]); -- cgit v1.2.3 From 4825f54a44fc7280bf02c6d48c83d7a3df864e17 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:50:23 +0530 Subject: ath9k_htc: Fix RX filters Add ATH9K_RX_FILTER_UNCOMP_BA_BAR and ATH9K_RX_FILTER_PSPOLL when mac80211 requires it. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 426620a50d5e..564ac13596f1 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -407,7 +407,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv) */ if (((ah->opmode != NL80211_IFTYPE_AP) && (priv->rxfilter & FIF_PROMISC_IN_BSS)) || - (ah->opmode == NL80211_IFTYPE_MONITOR)) + ah->is_monitoring) rfilt |= ATH9K_RX_FILTER_PROM; if (priv->rxfilter & FIF_CONTROL) @@ -419,8 +419,13 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv) else rfilt |= ATH9K_RX_FILTER_BEACON; - if (conf_is_ht(&priv->hw->conf)) + if (conf_is_ht(&priv->hw->conf)) { rfilt |= ATH9K_RX_FILTER_COMP_BAR; + rfilt |= ATH9K_RX_FILTER_UNCOMP_BA_BAR; + } + + if (priv->rxfilter & FIF_PSPOLL) + rfilt |= ATH9K_RX_FILTER_PSPOLL; return rfilt; -- cgit v1.2.3 From 3e3f1d197f5a432b961fadb35604dba92583945e Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:50:30 +0530 Subject: ath9k_htc: Add debug code to print endpoint mapping Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 52c6af2d6341..fc67c937e172 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -787,6 +787,7 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, struct ath_hw *ah; int error = 0; struct ath_regulatory *reg; + char hw_name[64]; /* Bring up device */ error = ath9k_init_priv(priv, devid, product, drv_info); @@ -827,6 +828,22 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, goto err_world; } + ath_dbg(common, ATH_DBG_CONFIG, + "WMI:%d, BCN:%d, CAB:%d, UAPSD:%d, MGMT:%d, " + "BE:%d, BK:%d, VI:%d, VO:%d\n", + priv->wmi_cmd_ep, + priv->beacon_ep, + priv->cab_ep, + priv->uapsd_ep, + priv->mgmt_ep, + priv->data_be_ep, + priv->data_bk_ep, + priv->data_vi_ep, + priv->data_vo_ep); + + ath9k_hw_name(priv->ah, hw_name, sizeof(hw_name)); + wiphy_info(hw->wiphy, "%s\n", hw_name); + ath9k_init_leds(priv); ath9k_start_rfkill_poll(priv); -- cgit v1.2.3 From 512c044a299f133c8dc86dd5fa6378d745489286 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 21 Feb 2011 07:50:38 +0530 Subject: ath9k_htc: Fix error path in URB allocation ath9k_hif_usb_alloc_urbs() takes care of freeing all the allocated URBs for the various endpoints when an error occurs. Calling ath9k_hif_usb_dealloc_urbs() would cause a panic since the URBs have already been freed. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index fde54446973f..7dc20489f2e2 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -916,13 +916,11 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info) if (ret) { dev_err(&hif_dev->udev->dev, "ath9k_htc: Unable to allocate URBs\n"); - goto err_urb; + goto err_fw_download; } return 0; -err_urb: - ath9k_hif_usb_dealloc_urbs(hif_dev); err_fw_download: release_firmware(hif_dev->firmware); err_fw_req: -- cgit v1.2.3 From 9c1f992c777d350b8c3b3e5c524decc131bcda28 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 21 Feb 2011 19:38:58 +0100 Subject: b43: N-PHY: fix 0x2055 radio workaround condition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index ab81ed8b19d7..00377b687384 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -430,9 +430,9 @@ static void b43_radio_init2055_post(struct b43_wldev *dev) bool workaround = false; if (sprom->revision < 4) - workaround = (binfo->vendor != PCI_VENDOR_ID_BROADCOM || - binfo->type != 0x46D || - binfo->rev < 0x41); + workaround = (binfo->vendor != PCI_VENDOR_ID_BROADCOM && + binfo->type == 0x46D && + binfo->rev >= 0x41); else workaround = !(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS); -- cgit v1.2.3 From 8e60b04479ba94ce82e88804b45438533bef4ef9 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 21 Feb 2011 19:45:34 +0100 Subject: b43: N-PHY: rev1: enable some gain ctl workarounds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 00377b687384..3928d82b097b 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1281,17 +1281,17 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) B43_NPHY_TABLE_DATALO, tmp); } } + } - b43_nphy_set_rf_sequence(dev, 5, - rfseq_events, rfseq_delays, 3); - b43_phy_maskset(dev, B43_NPHY_OVER_DGAIN1, - ~B43_NPHY_OVER_DGAIN_CCKDGECV & 0xFFFF, - 0x5A << B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT); + b43_nphy_set_rf_sequence(dev, 5, + rfseq_events, rfseq_delays, 3); + b43_phy_maskset(dev, B43_NPHY_OVER_DGAIN1, + ~B43_NPHY_OVER_DGAIN_CCKDGECV & 0xFFFF, + 0x5A << B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT); - if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) - b43_phy_maskset(dev, B43_PHY_N(0xC5D), - 0xFF80, 4); - } + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) + b43_phy_maskset(dev, B43_PHY_N(0xC5D), + 0xFF80, 4); } } -- cgit v1.2.3 From 05db8c5729fac2788f45bf327d168f2ea397f6a1 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 21 Feb 2011 19:45:35 +0100 Subject: b43: N-PHY: rev1: restore PHY state after RSSI operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 3928d82b097b..9f5a3c993239 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -2128,7 +2128,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0); save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1); - } else if (dev->phy.rev == 2) { + } else { save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); @@ -2179,7 +2179,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]); b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]); b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]); - } else if (dev->phy.rev == 2) { + } else { b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]); b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]); b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[2]); -- cgit v1.2.3 From 6ebacbb79d2d05978ba50a24d8cbe2a76ff2014c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 23 Feb 2011 15:06:08 +0100 Subject: mac80211: rename RX_FLAG_TSFT The flag isn't very descriptive -- the intention is that the driver provides a TSF timestamp at the beginning of the MPDU -- make that clearer by renaming the flag to RX_FLAG_MACTIME_MPDU. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 2 +- drivers/net/wireless/ath/ath9k/recv.c | 2 +- drivers/net/wireless/b43/xmit.c | 2 +- drivers/net/wireless/b43legacy/xmit.c | 2 +- drivers/net/wireless/iwlegacy/iwl-4965-lib.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +- drivers/net/wireless/p54/txrx.c | 2 +- drivers/net/wireless/rtl818x/rtl8180/dev.c | 2 +- drivers/net/wireless/rtl818x/rtl8187/dev.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 2 +- drivers/net/wireless/wl1251/rx.c | 2 +- drivers/staging/brcm80211/sys/wlc_mac80211.c | 5 ++++- include/net/mac80211.h | 9 +++++---- net/mac80211/ibss.c | 2 +- net/mac80211/rx.c | 4 ++-- 17 files changed, 25 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index dbc45e085434..80d9cf0c4cd2 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1361,7 +1361,7 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb, * right now, so it's not too bad... */ rxs->mactime = ath5k_extend_tsf(sc->ah, rs->rs_tstamp); - rxs->flag |= RX_FLAG_TSFT; + rxs->flag |= RX_FLAG_MACTIME_MPDU; rxs->freq = sc->curchan->center_freq; rxs->band = sc->curchan->band; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 564ac13596f1..4a4f27ba96af 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -616,7 +616,7 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, rx_status->freq = hw->conf.channel->center_freq; rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR; rx_status->antenna = rxbuf->rxstatus.rs_antenna; - rx_status->flag |= RX_FLAG_TSFT; + rx_status->flag |= RX_FLAG_MACTIME_MPDU; return true; diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index daf171d2f610..cb559e345b86 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -983,7 +983,7 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common, rx_status->freq = hw->conf.channel->center_freq; rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi; rx_status->antenna = rx_stats->rs_antenna; - rx_status->flag |= RX_FLAG_TSFT; + rx_status->flag |= RX_FLAG_MACTIME_MPDU; return 0; } diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index e6b0528f3b52..ad605bcdd40e 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c @@ -652,7 +652,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) status.mactime += mactime; if (low_mactime_now <= mactime) status.mactime -= 0x10000; - status.flag |= RX_FLAG_TSFT; + status.flag |= RX_FLAG_MACTIME_MPDU; } chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT; diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index 7d177d97f1f7..3a95541708a6 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c @@ -572,7 +572,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev, status.mactime += mactime; if (low_mactime_now <= mactime) status.mactime -= 0x10000; - status.flag |= RX_FLAG_TSFT; + status.flag |= RX_FLAG_MACTIME_MPDU; } chanid = (chanstat & B43legacy_RX_CHAN_ID) >> diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c index c1a24946715e..bd9618a4269d 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c @@ -639,7 +639,7 @@ void iwl4965_rx_reply_rx(struct iwl_priv *priv, /* TSF isn't reliable. In order to allow smooth user experience, * this W/A doesn't propagate it to the mac80211 */ - /*rx_status.flag |= RX_FLAG_TSFT;*/ + /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/ priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 325ff5c89ee8..0d0572ca7e77 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1173,7 +1173,7 @@ void iwlagn_rx_reply_rx(struct iwl_priv *priv, /* TSF isn't reliable. In order to allow smooth user experience, * this W/A doesn't propagate it to the mac80211 */ - /*rx_status.flag |= RX_FLAG_TSFT;*/ + /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/ priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp); diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index 917d5d948e3c..a408ff333920 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c @@ -367,7 +367,7 @@ static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb) rx_status->mactime = ((u64)priv->tsf_high32) << 32 | tsf32; priv->tsf_low32 = tsf32; - rx_status->flag |= RX_FLAG_TSFT; + rx_status->flag |= RX_FLAG_MACTIME_MPDU; if (hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN)) header_len += hdr->align[0]; diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c index 5851cbc1e957..b85debb4f7b1 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c @@ -146,7 +146,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) rx_status.freq = dev->conf.channel->center_freq; rx_status.band = dev->conf.channel->band; rx_status.mactime = le64_to_cpu(entry->tsft); - rx_status.flag |= RX_FLAG_TSFT; + rx_status.flag |= RX_FLAG_MACTIME_MPDU; if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index 6b82cac37ee3..1f5df12cb156 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c @@ -373,7 +373,7 @@ static void rtl8187_rx_cb(struct urb *urb) rx_status.rate_idx = rate; rx_status.freq = dev->conf.channel->center_freq; rx_status.band = dev->conf.channel->band; - rx_status.flag |= RX_FLAG_TSFT; + rx_status.flag |= RX_FLAG_MACTIME_MPDU; if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 01b95427fee0..8a67372f71fb 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -691,7 +691,7 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, if (GET_RX_DESC_RXHT(pdesc)) rx_status->flag |= RX_FLAG_HT; - rx_status->flag |= RX_FLAG_TSFT; + rx_status->flag |= RX_FLAG_MACTIME_MPDU; if (stats->decrypted) rx_status->flag |= RX_FLAG_DECRYPTED; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 9855c3e0a4b2..659e0ca95c64 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -334,7 +334,7 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw, rx_status->flag |= RX_FLAG_40MHZ; if (GET_RX_DESC_RX_HT(pdesc)) rx_status->flag |= RX_FLAG_HT; - rx_status->flag |= RX_FLAG_TSFT; + rx_status->flag |= RX_FLAG_MACTIME_MPDU; if (stats->decrypted) rx_status->flag |= RX_FLAG_DECRYPTED; rx_status->rate_idx = _rtl92c_rate_mapping(hw, diff --git a/drivers/net/wireless/wl1251/rx.c b/drivers/net/wireless/wl1251/rx.c index b659e15c78df..c1b3b3f03da2 100644 --- a/drivers/net/wireless/wl1251/rx.c +++ b/drivers/net/wireless/wl1251/rx.c @@ -81,7 +81,7 @@ static void wl1251_rx_status(struct wl1251 *wl, status->freq = ieee80211_channel_to_frequency(desc->channel, status->band); - status->flag |= RX_FLAG_TSFT; + status->flag |= RX_FLAG_MACTIME_MPDU; if (desc->flags & RX_DESC_ENCRYPTION_MASK) { status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 1d5d01ac0a9b..f305bf948617 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -6819,11 +6819,14 @@ prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, ratespec_t rspec; unsigned char *plcp; +#if 0 + /* Clearly, this is bogus -- reading the TSF now is wrong */ wlc_read_tsf(wlc, &tsf_l, &tsf_h); /* mactime */ rx_status->mactime = tsf_h; rx_status->mactime <<= 32; rx_status->mactime |= tsf_l; - rx_status->flag |= RX_FLAG_TSFT; + rx_status->flag |= RX_FLAG_MACTIME_MPDU; /* clearly wrong */ +#endif channel = WLC_CHAN_CHANNEL(rxh->RxChan); diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 8fcd1691cfb7..a13c8d8fca5c 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -599,9 +599,10 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) * the frame. * @RX_FLAG_FAILED_PLCP_CRC: Set this flag if the PCLP check failed on * the frame. - * @RX_FLAG_TSFT: The timestamp passed in the RX status (@mactime field) - * is valid. This is useful in monitor mode and necessary for beacon frames - * to enable IBSS merging. + * @RX_FLAG_MACTIME_MPDU: The timestamp passed in the RX status (@mactime + * field) is valid and contains the time the first symbol of the MPDU + * was received. This is useful in monitor mode and for proper IBSS + * merging. * @RX_FLAG_SHORTPRE: Short preamble was used for this frame * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index * @RX_FLAG_40MHZ: HT40 (40 MHz) was used @@ -614,7 +615,7 @@ enum mac80211_rx_flags { RX_FLAG_IV_STRIPPED = 1<<4, RX_FLAG_FAILED_FCS_CRC = 1<<5, RX_FLAG_FAILED_PLCP_CRC = 1<<6, - RX_FLAG_TSFT = 1<<7, + RX_FLAG_MACTIME_MPDU = 1<<7, RX_FLAG_SHORTPRE = 1<<8, RX_FLAG_HT = 1<<9, RX_FLAG_40MHZ = 1<<10, diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index a42aa61269ea..463271f9492e 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -355,7 +355,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, if (memcmp(cbss->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) goto put_bss; - if (rx_status->flag & RX_FLAG_TSFT) { + if (rx_status->flag & RX_FLAG_MACTIME_MPDU) { /* * For correct IBSS merging we need mactime; since mactime is * defined as the time the first data symbol of the frame hits diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index f502634d43af..5b534235d6be 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -77,7 +77,7 @@ ieee80211_rx_radiotap_len(struct ieee80211_local *local, /* always present fields */ len = sizeof(struct ieee80211_radiotap_header) + 9; - if (status->flag & RX_FLAG_TSFT) + if (status->flag & RX_FLAG_MACTIME_MPDU) len += 8; if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) len += 1; @@ -123,7 +123,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, /* the order of the following fields is important */ /* IEEE80211_RADIOTAP_TSFT */ - if (status->flag & RX_FLAG_TSFT) { + if (status->flag & RX_FLAG_MACTIME_MPDU) { put_unaligned_le64(status->mactime, pos); rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT); -- cgit v1.2.3 From 9d17e80de8b86be9a51ed5abe93e51fe22d0beb3 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 20 Feb 2011 11:35:26 +0100 Subject: rtlwifi: Fix build when RTL8192CU is selected, but RTL8192CE is not The wireless Makefile does not build rtlwifi for rtl8192cu unless rtl8192ce is selected. Signed-off-by: Willy Tarreau Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index cd0c7e2aed43..ddd3fb6ba1d3 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -24,7 +24,7 @@ obj-$(CONFIG_B43LEGACY) += b43legacy/ obj-$(CONFIG_ZD1211RW) += zd1211rw/ obj-$(CONFIG_RTL8180) += rtl818x/ obj-$(CONFIG_RTL8187) += rtl818x/ -obj-$(CONFIG_RTL8192CE) += rtlwifi/ +obj-$(CONFIG_RTLWIFI) += rtlwifi/ # 16-bit wireless PCMCIA client drivers obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o -- cgit v1.2.3 From 4c0f13f3e7b8c6cbdaddc04579d05ea2bf1145a8 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 20 Feb 2011 11:35:48 +0100 Subject: rtl8192cu: fix build error (vmalloc/vfree undefined) On the ARM system, a build fails due to missing include. Signed-off-by: Willy Tarreau Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 4e937e0da8e2..62604cbd75e8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -40,7 +40,7 @@ #include "trx.h" #include "led.h" #include "hw.h" - +#include MODULE_AUTHOR("Georgia "); MODULE_AUTHOR("Ziv Huang "); -- cgit v1.2.3 From 892c05c093858086d808aeb366b2e11106dd96c6 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 20 Feb 2011 11:43:07 +0100 Subject: rtlwifi: Let rtlwifi build when PCI is not enabled On systems where PCI does not exist, a build of rtlwifi will fail. Apply the same fix in case there are systems with PCI but not USB. Signed-off-by: Willy Tarreau Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile index c3e83a1da33b..52be12e718ab 100644 --- a/drivers/net/wireless/rtlwifi/Makefile +++ b/drivers/net/wireless/rtlwifi/Makefile @@ -5,12 +5,15 @@ rtlwifi-objs := \ core.o \ debug.o \ efuse.o \ - pci.o \ ps.o \ rc.o \ regd.o \ usb.o +ifeq ($(CONFIG_PCI),y) +rtlwifi-objs += pci.o +endif + obj-$(CONFIG_RTL8192CE) += rtl8192ce/ obj-$(CONFIG_RTL8192CU) += rtl8192cu/ -- cgit v1.2.3 From 8c6113cd03c7e927f5ee5f6ad98e155ef2d27177 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 20 Feb 2011 11:43:36 +0100 Subject: rtlwifi: Eliminate udelay calls with too large values On ARM, compilation of rtlwifi/efuse.c fails with the message: ERROR: "__bad_udelay" [drivers/net/wireless/rtlwifi/rtlwifi.ko] undefined! On inspection, the faulty calls are in routine efuse_reset_loader(), a routine that is never used, and the faulty routine is deleted. Signed-off-by: Willy Tarreau Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/efuse.c | 18 ------------------ drivers/net/wireless/rtlwifi/efuse.h | 3 --- 2 files changed, 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index 62876cd5c41a..4f92cba6810a 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c @@ -1169,21 +1169,3 @@ static u8 efuse_calculate_word_cnts(u8 word_en) return word_cnts; } -void efuse_reset_loader(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u16 tmp_u2b; - - tmp_u2b = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN]); - rtl_write_word(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN], - (tmp_u2b & ~(BIT(12)))); - udelay(10000); - rtl_write_word(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN], - (tmp_u2b | BIT(12))); - udelay(10000); -} - -bool efuse_program_map(struct ieee80211_hw *hw, char *p_filename, u8 tabletype) -{ - return true; -} diff --git a/drivers/net/wireless/rtlwifi/efuse.h b/drivers/net/wireless/rtlwifi/efuse.h index 2d39a4df181b..47774dd4c2a6 100644 --- a/drivers/net/wireless/rtlwifi/efuse.h +++ b/drivers/net/wireless/rtlwifi/efuse.h @@ -117,8 +117,5 @@ extern bool efuse_shadow_update_chk(struct ieee80211_hw *hw); extern void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw); extern void efuse_force_write_vendor_Id(struct ieee80211_hw *hw); extern void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx); -extern bool efuse_program_map(struct ieee80211_hw *hw, - char *p_filename, u8 tabletype); -extern void efuse_reset_loader(struct ieee80211_hw *hw); #endif -- cgit v1.2.3 From 96e0a0797eba35b5420c710b928f19094b2d5c45 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 22 Feb 2011 21:07:42 +0100 Subject: x86: dtb: Add support for PCI devices backed by dtb nodes x86_of_pci_init() does two things: - it provides a generic irq enable and disable function. enable queries the device tree for the interrupt information, calls ->xlate on the irq host and updates the pci->irq information for the device. - it walks through PCI bus(es) in the device tree and adds its children (device) nodes to appropriate pci_dev nodes in kernel. So the dtb node information is available at probe time of the PCI device. Adding a PCI bus based on the information in the device tree is currently not supported. Right now direct access via ioports is used. Signed-off-by: Sebastian Andrzej Siewior Tested-by: Dirk Brandewie Acked-by: Grant Likely Cc: sodaville@linutronix.de Cc: devicetree-discuss@lists.ozlabs.org LKML-Reference: <1298405266-1624-8-git-send-email-bigeasy@linutronix.de> Signed-off-by: Thomas Gleixner --- arch/x86/include/asm/prom.h | 14 ++++++++ arch/x86/kernel/devicetree.c | 83 ++++++++++++++++++++++++++++++++++++++++++++ drivers/of/Kconfig | 2 +- drivers/of/of_pci.c | 1 + 4 files changed, 99 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h index 35ec32b47500..8fcd519a44dc 100644 --- a/arch/x86/include/asm/prom.h +++ b/arch/x86/include/asm/prom.h @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -29,8 +30,21 @@ extern void add_dtb(u64 data); void x86_dtb_find_config(void); void x86_dtb_get_config(unsigned int unused); void add_interrupt_host(struct irq_domain *ih); +void __cpuinit x86_of_pci_init(void); + +static inline struct device_node *pci_device_to_OF_node(struct pci_dev *pdev) +{ + return pdev ? pdev->dev.of_node : NULL; +} + +static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus) +{ + return pci_device_to_OF_node(bus->self); +} + #else static inline void add_dtb(u64 data) { } +static inline void x86_of_pci_init(void) { } #define x86_dtb_find_config x86_init_noop #define x86_dtb_get_config x86_init_uint_noop #define of_ioapic 0 diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index dbb3bda40af9..7b574226e0a8 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c @@ -9,11 +9,15 @@ #include #include #include +#include #include +#include +#include #include #include #include +#include __initdata u64 initial_dtb; char __initdata cmd_line[COMMAND_LINE_SIZE]; @@ -99,6 +103,85 @@ void __init add_dtb(u64 data) initial_dtb = data + offsetof(struct setup_data, data); } +#ifdef CONFIG_PCI +static int x86_of_pci_irq_enable(struct pci_dev *dev) +{ + struct of_irq oirq; + u32 virq; + int ret; + u8 pin; + + ret = pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + if (ret) + return ret; + if (!pin) + return 0; + + ret = of_irq_map_pci(dev, &oirq); + if (ret) + return ret; + + virq = irq_create_of_mapping(oirq.controller, oirq.specifier, + oirq.size); + if (virq == 0) + return -EINVAL; + dev->irq = virq; + return 0; +} + +static void x86_of_pci_irq_disable(struct pci_dev *dev) +{ +} + +void __cpuinit x86_of_pci_init(void) +{ + struct device_node *np; + + pcibios_enable_irq = x86_of_pci_irq_enable; + pcibios_disable_irq = x86_of_pci_irq_disable; + + for_each_node_by_type(np, "pci") { + const void *prop; + struct pci_bus *bus; + unsigned int bus_min; + struct device_node *child; + + prop = of_get_property(np, "bus-range", NULL); + if (!prop) + continue; + bus_min = be32_to_cpup(prop); + + bus = pci_find_bus(0, bus_min); + if (!bus) { + printk(KERN_ERR "Can't find a node for bus %s.\n", + np->full_name); + continue; + } + + if (bus->self) + bus->self->dev.of_node = np; + else + bus->dev.of_node = np; + + for_each_child_of_node(np, child) { + struct pci_dev *dev; + u32 devfn; + + prop = of_get_property(child, "reg", NULL); + if (!prop) + continue; + + devfn = (be32_to_cpup(prop) >> 8) & 0xff; + dev = pci_get_slot(bus, devfn); + if (!dev) + continue; + dev->dev.of_node = child; + pci_dev_put(dev); + } + } +} +#endif + static void __init dtb_setup_hpet(void) { struct device_node *dn; diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index efabbf9dd607..d06a6374ed6c 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -71,7 +71,7 @@ config OF_MDIO config OF_PCI def_tristate PCI - depends on PCI && (PPC || MICROBLAZE) + depends on PCI && (PPC || MICROBLAZE || X86) help OpenFirmware PCI bus accessors diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c index 314535fa32c1..ac1ec54e4fd5 100644 --- a/drivers/of/of_pci.c +++ b/drivers/of/of_pci.c @@ -1,5 +1,6 @@ #include #include +#include #include /** -- cgit v1.2.3 From 3bcbaf6e08d8d82cde781997bd2c56dda87049b5 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 22 Feb 2011 21:07:46 +0100 Subject: rtc: cmos: Add OF bindings This allows to load the OF driver based informations from the device tree. Systems without BIOS may need to perform some initialization. PowerPC creates a PNP device from the OF information and performs this kind of initialization in their private PCI quirk. This looks more generic. This patch also avoids registering the platform RTC driver on X86 if we have a device tree blob. Otherwise we would setup the device based on the hardcoded information in arch/x86 rather than the device tree based one. [ tglx: Changed "int of_have_populated_dt()" to bool as recommended by Grant ] Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Dirk Brandewie Acked-by: Grant Likely Cc: sodaville@linutronix.de Cc: devicetree-discuss@lists.ozlabs.org Cc: rtc-linux@googlegroups.com Cc: Alessandro Zummo LKML-Reference: <1298405266-1624-12-git-send-email-bigeasy@linutronix.de> Signed-off-by: Thomas Gleixner --- Documentation/devicetree/bindings/rtc/rtc-cmos.txt | 28 ++++++++++++++ arch/x86/kernel/rtc.c | 3 ++ drivers/rtc/rtc-cmos.c | 45 ++++++++++++++++++++++ include/linux/of.h | 12 ++++++ 4 files changed, 88 insertions(+) create mode 100644 Documentation/devicetree/bindings/rtc/rtc-cmos.txt (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/rtc/rtc-cmos.txt b/Documentation/devicetree/bindings/rtc/rtc-cmos.txt new file mode 100644 index 000000000000..7382989b3052 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/rtc-cmos.txt @@ -0,0 +1,28 @@ + Motorola mc146818 compatible RTC +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Required properties: + - compatible : "motorola,mc146818" + - reg : should contain registers location and length. + +Optional properties: + - interrupts : should contain interrupt. + - interrupt-parent : interrupt source phandle. + - ctrl-reg : Contains the initial value of the control register also + called "Register B". + - freq-reg : Contains the initial value of the frequency register also + called "Regsiter A". + +"Register A" and "B" are usually initialized by the firmware (BIOS for +instance). If this is not done, it can be performed by the driver. + +ISA Example: + + rtc@70 { + compatible = "motorola,mc146818"; + interrupts = <8 3>; + interrupt-parent = <&ioapic1>; + ctrl-reg = <2>; + freq-reg = <0x26>; + reg = <1 0x70 2>; + }; diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c index 6f39cab052d5..3f2ad2640d85 100644 --- a/arch/x86/kernel/rtc.c +++ b/arch/x86/kernel/rtc.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -236,6 +237,8 @@ static __init int add_rtc_cmos(void) } } #endif + if (of_have_populated_dt()) + return 0; platform_device_register(&rtc_device); dev_info(&rtc_device.dev, diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index c7ff8df347e7..159b95e4b420 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -37,6 +37,8 @@ #include #include #include +#include +#include /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ #include @@ -1123,6 +1125,47 @@ static struct pnp_driver cmos_pnp_driver = { #endif /* CONFIG_PNP */ +#ifdef CONFIG_OF +static const struct of_device_id of_cmos_match[] = { + { + .compatible = "motorola,mc146818", + }, + { }, +}; +MODULE_DEVICE_TABLE(of, of_cmos_match); + +static __init void cmos_of_init(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct rtc_time time; + int ret; + const __be32 *val; + + if (!node) + return; + + val = of_get_property(node, "ctrl-reg", NULL); + if (val) + CMOS_WRITE(be32_to_cpup(val), RTC_CONTROL); + + val = of_get_property(node, "freq-reg", NULL); + if (val) + CMOS_WRITE(be32_to_cpup(val), RTC_FREQ_SELECT); + + get_rtc_time(&time); + ret = rtc_valid_tm(&time); + if (ret) { + struct rtc_time def_time = { + .tm_year = 1, + .tm_mday = 1, + }; + set_rtc_time(&def_time); + } +} +#else +static inline void cmos_of_init(struct platform_device *pdev) {} +#define of_cmos_match NULL +#endif /*----------------------------------------------------------------*/ /* Platform setup should have set up an RTC device, when PNP is @@ -1131,6 +1174,7 @@ static struct pnp_driver cmos_pnp_driver = { static int __init cmos_platform_probe(struct platform_device *pdev) { + cmos_of_init(pdev); cmos_wake_setup(&pdev->dev); return cmos_do_probe(&pdev->dev, platform_get_resource(pdev, IORESOURCE_IO, 0), @@ -1162,6 +1206,7 @@ static struct platform_driver cmos_platform_driver = { #ifdef CONFIG_PM .pm = &cmos_pm_ops, #endif + .of_match_table = of_cmos_match, } }; diff --git a/include/linux/of.h b/include/linux/of.h index d9dd664a6a9c..266db1d0baa9 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -70,6 +70,11 @@ extern struct device_node *allnodes; extern struct device_node *of_chosen; extern rwlock_t devtree_lock; +static inline bool of_have_populated_dt(void) +{ + return allnodes != NULL; +} + static inline bool of_node_is_root(const struct device_node *node) { return node && (node->parent == NULL); @@ -222,5 +227,12 @@ extern void of_attach_node(struct device_node *); extern void of_detach_node(struct device_node *); #endif +#else + +static inline bool of_have_populated_dt(void) +{ + return false; +} + #endif /* CONFIG_OF */ #endif /* _LINUX_OF_H */ -- cgit v1.2.3 From 1472d3a87586eb7529d1d85f7c888055650b7208 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 23 Feb 2011 10:24:58 -0600 Subject: rtlwifi: rtl8192ce: rtl8192cu: Fix multiple def errors for allyesconfig build As noted by Stephan Rothwell, an allyesconfig build fails since rtl8192cu was merged with failures such as: drivers/net/wireless/rtlwifi/rtl8192cu/built-in.o: In function `rtl92c_phy_sw_chnl': (.opd+0xf30): multiple definition of `rtl92c_phy_sw_chnl' drivers/net/wireless/rtlwifi/rtl8192ce/built-in.o:(.opd+0xb70): first defined here drivers/net/wireless/rtlwifi/rtl8192cu/built-in.o: In function `rtl92c_fill_h2c_cmd': (.opd+0x288): multiple definition of `rtl92c_fill_h2c_cmd' drivers/net/wireless/rtlwifi/rtl8192ce/built-in.o:(.opd+0x288): first defined here These are caused because the code shared between rtl8192ce and rtl8192cu is included in both drivers. This has been fixed by creating a new modue that contains the shared code. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/Kconfig | 7 + drivers/net/wireless/rtlwifi/Makefile | 3 + drivers/net/wireless/rtlwifi/rtl8192c/Makefile | 9 + drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 12 +- drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h | 204 ++++++ drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 774 +++++++++++++++++++++ drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h | 98 +++ drivers/net/wireless/rtlwifi/rtl8192c/main.c | 39 ++ drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | 125 ++-- drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h | 246 +++++++ drivers/net/wireless/rtlwifi/rtl8192ce/Makefile | 1 - drivers/net/wireless/rtlwifi/rtl8192ce/dm.c | 7 +- drivers/net/wireless/rtlwifi/rtl8192ce/dm.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/fw.c | 769 -------------------- drivers/net/wireless/rtlwifi/rtl8192ce/fw.h | 98 --- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 5 +- drivers/net/wireless/rtlwifi/rtl8192ce/hw.h | 11 + drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | 31 +- drivers/net/wireless/rtlwifi/rtl8192ce/phy.h | 28 +- drivers/net/wireless/rtlwifi/rtl8192ce/rf.c | 10 +- drivers/net/wireless/rtlwifi/rtl8192ce/rf.h | 5 +- drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 15 +- drivers/net/wireless/rtlwifi/rtl8192ce/sw.h | 12 + drivers/net/wireless/rtlwifi/rtl8192cu/Makefile | 1 - drivers/net/wireless/rtlwifi/rtl8192cu/dm.c | 5 +- drivers/net/wireless/rtlwifi/rtl8192cu/dm.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/fw.c | 30 - drivers/net/wireless/rtlwifi/rtl8192cu/fw.h | 30 - drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 7 +- drivers/net/wireless/rtlwifi/rtl8192cu/hw.h | 9 + drivers/net/wireless/rtlwifi/rtl8192cu/phy.c | 38 +- drivers/net/wireless/rtlwifi/rtl8192cu/phy.h | 4 +- drivers/net/wireless/rtlwifi/rtl8192cu/rf.c | 12 +- drivers/net/wireless/rtlwifi/rtl8192cu/rf.h | 19 +- drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 15 +- drivers/net/wireless/rtlwifi/rtl8192cu/sw.h | 18 + drivers/net/wireless/rtlwifi/wifi.h | 12 + 37 files changed, 1636 insertions(+), 1077 deletions(-) create mode 100644 drivers/net/wireless/rtlwifi/rtl8192c/Makefile create mode 100644 drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h create mode 100644 drivers/net/wireless/rtlwifi/rtl8192c/main.c create mode 100644 drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/fw.c delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192ce/fw.h delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/fw.c delete mode 100644 drivers/net/wireless/rtlwifi/rtl8192cu/fw.h (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig index 86f8d4d64037..ce49e0ce7cad 100644 --- a/drivers/net/wireless/rtlwifi/Kconfig +++ b/drivers/net/wireless/rtlwifi/Kconfig @@ -3,6 +3,7 @@ config RTL8192CE depends on MAC80211 && PCI && EXPERIMENTAL select FW_LOADER select RTLWIFI + select RTL8192C_COMMON ---help--- This is the driver for Realtek RTL8192CE/RTL8188CE 802.11n PCIe wireless network adapters. @@ -14,6 +15,7 @@ config RTL8192CU depends on MAC80211 && USB && EXPERIMENTAL select FW_LOADER select RTLWIFI + select RTL8192C_COMMON ---help--- This is the driver for Realtek RTL8192CU/RTL8188CU 802.11n USB wireless network adapters. @@ -24,3 +26,8 @@ config RTLWIFI tristate depends on RTL8192CE || RTL8192CU default m + +config RTL8192C_COMMON + tristate + depends on RTL8192CE || RTL8192CU + default m diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile index 52be12e718ab..9192fd583413 100644 --- a/drivers/net/wireless/rtlwifi/Makefile +++ b/drivers/net/wireless/rtlwifi/Makefile @@ -10,10 +10,13 @@ rtlwifi-objs := \ regd.o \ usb.o +rtl8192c_common-objs += \ + ifeq ($(CONFIG_PCI),y) rtlwifi-objs += pci.o endif +obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c/ obj-$(CONFIG_RTL8192CE) += rtl8192ce/ obj-$(CONFIG_RTL8192CU) += rtl8192cu/ diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/Makefile b/drivers/net/wireless/rtlwifi/rtl8192c/Makefile new file mode 100644 index 000000000000..aee42d7ae8a2 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192c/Makefile @@ -0,0 +1,9 @@ +rtl8192c-common-objs := \ + main.o \ + dm_common.o \ + fw_common.o \ + phy_common.o + +obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c-common.o + +ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index b4f1e4e6b733..bb023274414c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -27,6 +27,8 @@ * *****************************************************************************/ +#include "dm_common.h" + struct dig_t dm_digtable; static struct ps_t dm_pstable; @@ -517,6 +519,7 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw) dm_digtable.pre_igvalue = dm_digtable.cur_igvalue; } } +EXPORT_SYMBOL(rtl92c_dm_write_dig); static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw) { @@ -554,6 +557,7 @@ void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw) rtlpriv->dm.is_any_nonbepkts = false; rtlpriv->dm.is_cur_rdlstate = false; } +EXPORT_SYMBOL(rtl92c_dm_init_edca_turbo); static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) { @@ -1103,6 +1107,7 @@ void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw) { rtl92c_dm_check_txpower_tracking_thermal_meter(hw); } +EXPORT_SYMBOL(rtl92c_dm_check_txpower_tracking); void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) { @@ -1118,6 +1123,7 @@ void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) rtlpriv->dm.useramask = false; } +EXPORT_SYMBOL(rtl92c_dm_init_rate_adaptive_mask); static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) { @@ -1307,6 +1313,7 @@ void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal) dm_pstable.pre_rfstate = dm_pstable.cur_rfstate; } } +EXPORT_SYMBOL(rtl92c_dm_rf_saving); static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) { @@ -1360,6 +1367,7 @@ void rtl92c_dm_init(struct ieee80211_hw *hw) rtl92c_dm_initialize_txpower_tracking(hw); rtl92c_dm_init_dynamic_bb_powersaving(hw); } +EXPORT_SYMBOL(rtl92c_dm_init); void rtl92c_dm_watchdog(struct ieee80211_hw *hw) { @@ -1380,9 +1388,11 @@ void rtl92c_dm_watchdog(struct ieee80211_hw *hw) rtl92c_dm_dig(hw); rtl92c_dm_false_alarm_counter_statistics(hw); rtl92c_dm_dynamic_bb_powersaving(hw); - rtl92c_dm_dynamic_txpower(hw); + rtlpriv->cfg->ops->dm_dynamic_txpower(hw); rtl92c_dm_check_txpower_tracking(hw); rtl92c_dm_refresh_rate_adaptive_mask(hw); rtl92c_dm_check_edca_turbo(hw); + } } +EXPORT_SYMBOL(rtl92c_dm_watchdog); diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h new file mode 100644 index 000000000000..b9cbb0a3c03f --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h @@ -0,0 +1,204 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92COMMON_DM_H__ +#define __RTL92COMMON_DM_H__ + +#include "../wifi.h" +#include "../rtl8192ce/def.h" +#include "../rtl8192ce/reg.h" +#include "fw_common.h" + +#define HAL_DM_DIG_DISABLE BIT(0) +#define HAL_DM_HIPWR_DISABLE BIT(1) + +#define OFDM_TABLE_LENGTH 37 +#define CCK_TABLE_LENGTH 33 + +#define OFDM_TABLE_SIZE 37 +#define CCK_TABLE_SIZE 33 + +#define BW_AUTO_SWITCH_HIGH_LOW 25 +#define BW_AUTO_SWITCH_LOW_HIGH 30 + +#define DM_DIG_THRESH_HIGH 40 +#define DM_DIG_THRESH_LOW 35 + +#define DM_FALSEALARM_THRESH_LOW 400 +#define DM_FALSEALARM_THRESH_HIGH 1000 + +#define DM_DIG_MAX 0x3e +#define DM_DIG_MIN 0x1e + +#define DM_DIG_FA_UPPER 0x32 +#define DM_DIG_FA_LOWER 0x20 +#define DM_DIG_FA_TH0 0x20 +#define DM_DIG_FA_TH1 0x100 +#define DM_DIG_FA_TH2 0x200 + +#define DM_DIG_BACKOFF_MAX 12 +#define DM_DIG_BACKOFF_MIN -4 +#define DM_DIG_BACKOFF_DEFAULT 10 + +#define RXPATHSELECTION_SS_TH_lOW 30 +#define RXPATHSELECTION_DIFF_TH 18 + +#define DM_RATR_STA_INIT 0 +#define DM_RATR_STA_HIGH 1 +#define DM_RATR_STA_MIDDLE 2 +#define DM_RATR_STA_LOW 3 + +#define CTS2SELF_THVAL 30 +#define REGC38_TH 20 + +#define WAIOTTHVal 25 + +#define TXHIGHPWRLEVEL_NORMAL 0 +#define TXHIGHPWRLEVEL_LEVEL1 1 +#define TXHIGHPWRLEVEL_LEVEL2 2 +#define TXHIGHPWRLEVEL_BT1 3 +#define TXHIGHPWRLEVEL_BT2 4 + +#define DM_TYPE_BYFW 0 +#define DM_TYPE_BYDRIVER 1 + +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 + +struct ps_t { + u8 pre_ccastate; + u8 cur_ccasate; + u8 pre_rfstate; + u8 cur_rfstate; + long rssi_val_min; +}; + +struct dig_t { + u8 dig_enable_flag; + u8 dig_ext_port_stage; + u32 rssi_lowthresh; + u32 rssi_highthresh; + u32 fa_lowthresh; + u32 fa_highthresh; + u8 cursta_connectctate; + u8 presta_connectstate; + u8 curmultista_connectstate; + u8 pre_igvalue; + u8 cur_igvalue; + char backoff_val; + char backoff_val_range_max; + char backoff_val_range_min; + u8 rx_gain_range_max; + u8 rx_gain_range_min; + u8 rssi_val_min; + u8 pre_cck_pd_state; + u8 cur_cck_pd_state; + u8 pre_cck_fa_state; + u8 cur_cck_fa_state; + u8 pre_ccastate; + u8 cur_ccasate; +}; + +struct swat_t { + u8 failure_cnt; + u8 try_flag; + u8 stop_trying; + long pre_rssi; + long trying_threshold; + u8 cur_antenna; + u8 pre_antenna; +}; + +enum tag_dynamic_init_gain_operation_type_definition { + DIG_TYPE_THRESH_HIGH = 0, + DIG_TYPE_THRESH_LOW = 1, + DIG_TYPE_BACKOFF = 2, + DIG_TYPE_RX_GAIN_MIN = 3, + DIG_TYPE_RX_GAIN_MAX = 4, + DIG_TYPE_ENABLE = 5, + DIG_TYPE_DISABLE = 6, + DIG_OP_TYPE_MAX +}; + +enum tag_cck_packet_detection_threshold_type_definition { + CCK_PD_STAGE_LowRssi = 0, + CCK_PD_STAGE_HighRssi = 1, + CCK_FA_STAGE_Low = 2, + CCK_FA_STAGE_High = 3, + CCK_PD_STAGE_MAX = 4, +}; + +enum dm_1r_cca_e { + CCA_1R = 0, + CCA_2R = 1, + CCA_MAX = 2, +}; + +enum dm_rf_e { + RF_SAVE = 0, + RF_NORMAL = 1, + RF_MAX = 2, +}; + +enum dm_sw_ant_switch_e { + ANS_ANTENNA_B = 1, + ANS_ANTENNA_A = 2, + ANS_ANTENNA_MAX = 3, +}; + +enum dm_dig_ext_port_alg_e { + DIG_EXT_PORT_STAGE_0 = 0, + DIG_EXT_PORT_STAGE_1 = 1, + DIG_EXT_PORT_STAGE_2 = 2, + DIG_EXT_PORT_STAGE_3 = 3, + DIG_EXT_PORT_STAGE_MAX = 4, +}; + +enum dm_dig_connect_e { + DIG_STA_DISCONNECT = 0, + DIG_STA_CONNECT = 1, + DIG_STA_BEFORE_CONNECT = 2, + DIG_MULTISTA_DISCONNECT = 3, + DIG_MULTISTA_CONNECT = 4, + DIG_CONNECT_MAX +}; + +extern struct dig_t dm_digtable; +void rtl92c_dm_init(struct ieee80211_hw *hw); +void rtl92c_dm_watchdog(struct ieee80211_hw *hw); +void rtl92c_dm_write_dig(struct ieee80211_hw *hw); +void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw); +void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw); +void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); +void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); +void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); +void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); +void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c new file mode 100644 index 000000000000..5ef91374b230 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -0,0 +1,774 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../rtl8192ce/reg.h" +#include "../rtl8192ce/def.h" +#include "fw_common.h" + +static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) { + u32 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + if (enable) + value32 |= MCUFWDL_EN; + else + value32 &= ~MCUFWDL_EN; + rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); + } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) { + u8 tmp; + if (enable) { + + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, + tmp | 0x04); + + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01); + + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2); + rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7); + } else { + + tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); + rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe); + + rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00); + } + } +} + +static void _rtl92c_fw_block_write(struct ieee80211_hw *hw, + const u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 blockSize = sizeof(u32); + u8 *bufferPtr = (u8 *) buffer; + u32 *pu4BytePtr = (u32 *) buffer; + u32 i, offset, blockCount, remainSize; + + blockCount = size / blockSize; + remainSize = size % blockSize; + + for (i = 0; i < blockCount; i++) { + offset = i * blockSize; + rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset), + *(pu4BytePtr + i)); + } + + if (remainSize) { + offset = blockCount * blockSize; + bufferPtr += offset; + for (i = 0; i < remainSize; i++) { + rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS + + offset + i), *(bufferPtr + i)); + } + } +} + +static void _rtl92c_fw_page_write(struct ieee80211_hw *hw, + u32 page, const u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value8; + u8 u8page = (u8) (page & 0x07); + + value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page; + + rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8); + _rtl92c_fw_block_write(hw, buffer, size); +} + +static void _rtl92c_fill_dummy(u8 *pfwbuf, u32 *pfwlen) +{ + u32 fwlen = *pfwlen; + u8 remain = (u8) (fwlen % 4); + + remain = (remain == 0) ? 0 : (4 - remain); + + while (remain > 0) { + pfwbuf[fwlen] = 0; + fwlen++; + remain--; + } + + *pfwlen = fwlen; +} + +static void _rtl92c_write_fw(struct ieee80211_hw *hw, + enum version_8192c version, u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 *bufferPtr = (u8 *) buffer; + + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size)); + + if (IS_CHIP_VER_B(version)) { + u32 pageNums, remainSize; + u32 page, offset; + + if (IS_HARDWARE_TYPE_8192CE(rtlhal)) + _rtl92c_fill_dummy(bufferPtr, &size); + + pageNums = size / FW_8192C_PAGE_SIZE; + remainSize = size % FW_8192C_PAGE_SIZE; + + if (pageNums > 4) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Page numbers should not greater then 4\n")); + } + + for (page = 0; page < pageNums; page++) { + offset = page * FW_8192C_PAGE_SIZE; + _rtl92c_fw_page_write(hw, page, (bufferPtr + offset), + FW_8192C_PAGE_SIZE); + } + + if (remainSize) { + offset = pageNums * FW_8192C_PAGE_SIZE; + page = pageNums; + _rtl92c_fw_page_write(hw, page, (bufferPtr + offset), + remainSize); + } + } else { + _rtl92c_fw_block_write(hw, buffer, size); + } +} + +static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int err = -EIO; + u32 counter = 0; + u32 value32; + + do { + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) && + (!(value32 & FWDL_ChkSum_rpt))); + + if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("chksum report faill ! REG_MCUFWDL:0x%08x .\n", + value32)); + goto exit; + } + + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32)); + + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + value32 |= MCUFWDL_RDY; + value32 &= ~WINTINI_RDY; + rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); + + counter = 0; + + do { + value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); + if (value32 & WINTINI_RDY) { + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + ("Polling FW ready success!!" + " REG_MCUFWDL:0x%08x .\n", + value32)); + err = 0; + goto exit; + } + + mdelay(FW_8192C_POLLING_DELAY); + + } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT); + + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32)); + +exit: + return err; +} + +int rtl92c_download_fw(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl92c_firmware_header *pfwheader; + u8 *pfwdata; + u32 fwsize; + int err; + enum version_8192c version = rtlhal->version; + const struct firmware *firmware; + + printk(KERN_INFO "rtl8192cu: Loading firmware file %s\n", + rtlpriv->cfg->fw_name); + err = request_firmware(&firmware, rtlpriv->cfg->fw_name, + rtlpriv->io.dev); + if (err) { + printk(KERN_ERR "rtl8192cu: Firmware loading failed\n"); + return 1; + } + + if (firmware->size > 0x4000) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Firmware is too big!\n")); + release_firmware(firmware); + return 1; + } + + memcpy(rtlhal->pfirmware, firmware->data, firmware->size); + fwsize = firmware->size; + release_firmware(firmware); + + pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; + pfwdata = (u8 *) rtlhal->pfirmware; + + if (IS_FW_HEADER_EXIST(pfwheader)) { + RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, + ("Firmware Version(%d), Signature(%#x),Size(%d)\n", + pfwheader->version, pfwheader->signature, + (uint)sizeof(struct rtl92c_firmware_header))); + + pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header); + fwsize = fwsize - sizeof(struct rtl92c_firmware_header); + } + + _rtl92c_enable_fw_download(hw, true); + _rtl92c_write_fw(hw, version, pfwdata, fwsize); + _rtl92c_enable_fw_download(hw, false); + + err = _rtl92c_fw_free_to_go(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Firmware is not ready to run!\n")); + } else { + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + ("Firmware is ready to run!\n")); + } + + return 0; +} +EXPORT_SYMBOL(rtl92c_download_fw); + +static bool _rtl92c_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 val_hmetfr, val_mcutst_1; + bool result = false; + + val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR); + val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum)); + + if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0) + result = true; + return result; +} + +static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, u8 *p_cmdbuffer) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 boxnum; + u16 box_reg, box_extreg; + u8 u1b_tmp; + bool isfw_read = false; + u8 buf_index; + bool bwrite_sucess = false; + u8 wait_h2c_limmit = 100; + u8 wait_writeh2c_limmit = 100; + u8 boxcontent[4], boxextcontent[2]; + u32 h2c_waitcounter = 0; + unsigned long flag; + u8 idx; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n")); + + while (true) { + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + if (rtlhal->h2c_setinprogress) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("H2C set in progress! Wait to set.." + "element_id(%d).\n", element_id)); + + while (rtlhal->h2c_setinprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, + flag); + h2c_waitcounter++; + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Wait 100 us (%d times)...\n", + h2c_waitcounter)); + udelay(100); + + if (h2c_waitcounter > 1000) + return; + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, + flag); + } + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + } else { + rtlhal->h2c_setinprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + break; + } + } + + while (!bwrite_sucess) { + wait_writeh2c_limmit--; + if (wait_writeh2c_limmit == 0) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("Write H2C fail because no trigger " + "for FW INT!\n")); + break; + } + + boxnum = rtlhal->last_hmeboxnum; + switch (boxnum) { + case 0: + box_reg = REG_HMEBOX_0; + box_extreg = REG_HMEBOX_EXT_0; + break; + case 1: + box_reg = REG_HMEBOX_1; + box_extreg = REG_HMEBOX_EXT_1; + break; + case 2: + box_reg = REG_HMEBOX_2; + box_extreg = REG_HMEBOX_EXT_2; + break; + case 3: + box_reg = REG_HMEBOX_3; + box_extreg = REG_HMEBOX_EXT_3; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + + isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum); + while (!isfw_read) { + + wait_h2c_limmit--; + if (wait_h2c_limmit == 0) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Wating too long for FW read " + "clear HMEBox(%d)!\n", boxnum)); + break; + } + + udelay(10); + + isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum); + u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Wating for FW read clear HMEBox(%d)!!! " + "0x1BF = %2x\n", boxnum, u1b_tmp)); + } + + if (!isfw_read) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Write H2C register BOX[%d] fail!!!!! " + "Fw do not read.\n", boxnum)); + break; + } + + memset(boxcontent, 0, sizeof(boxcontent)); + memset(boxextcontent, 0, sizeof(boxextcontent)); + boxcontent[0] = element_id; + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("Write element_id box_reg(%4x) = %2x\n", + box_reg, element_id)); + + switch (cmd_len) { + case 1: + boxcontent[0] &= ~(BIT(7)); + memcpy((u8 *) (boxcontent) + 1, + p_cmdbuffer + buf_index, 1); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 2: + boxcontent[0] &= ~(BIT(7)); + memcpy((u8 *) (boxcontent) + 1, + p_cmdbuffer + buf_index, 2); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 3: + boxcontent[0] &= ~(BIT(7)); + memcpy((u8 *) (boxcontent) + 1, + p_cmdbuffer + buf_index, 3); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 4: + boxcontent[0] |= (BIT(7)); + memcpy((u8 *) (boxextcontent), + p_cmdbuffer + buf_index, 2); + memcpy((u8 *) (boxcontent) + 1, + p_cmdbuffer + buf_index + 2, 2); + + for (idx = 0; idx < 2; idx++) { + rtl_write_byte(rtlpriv, box_extreg + idx, + boxextcontent[idx]); + } + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 5: + boxcontent[0] |= (BIT(7)); + memcpy((u8 *) (boxextcontent), + p_cmdbuffer + buf_index, 2); + memcpy((u8 *) (boxcontent) + 1, + p_cmdbuffer + buf_index + 2, 3); + + for (idx = 0; idx < 2; idx++) { + rtl_write_byte(rtlpriv, box_extreg + idx, + boxextcontent[idx]); + } + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + ("switch case not process\n")); + break; + } + + bwrite_sucess = true; + + rtlhal->last_hmeboxnum = boxnum + 1; + if (rtlhal->last_hmeboxnum == 4) + rtlhal->last_hmeboxnum = 0; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + ("pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum)); + } + + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + rtlhal->h2c_setinprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n")); +} + +void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, u8 *p_cmdbuffer) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 tmp_cmdbuf[2]; + + if (rtlhal->fw_ready == false) { + RT_ASSERT(false, ("return H2C cmd because of Fw " + "download fail!!!\n")); + return; + } + + memset(tmp_cmdbuf, 0, 8); + memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len); + _rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); + + return; +} +EXPORT_SYMBOL(rtl92c_fill_h2c_cmd); + +void rtl92c_firmware_selfreset(struct ieee80211_hw *hw) +{ + u8 u1b_tmp; + u8 delay = 100; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20); + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + + while (u1b_tmp & BIT(2)) { + delay--; + if (delay == 0) { + RT_ASSERT(false, ("8051 reset fail.\n")); + break; + } + udelay(50); + u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); + } +} +EXPORT_SYMBOL(rtl92c_firmware_selfreset); + +void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 u1_h2c_set_pwrmode[3] = {0}; + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode)); + + SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); + SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1); + SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, + ppsc->reg_max_lps_awakeintvl); + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n", + u1_h2c_set_pwrmode, 3); + rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode); + +} +EXPORT_SYMBOL(rtl92c_set_fw_pwrmode_cmd); + +#define BEACON_PG 0 /*->1*/ +#define PSPOLL_PG 2 +#define NULL_PG 3 +#define PROBERSP_PG 4 /*->5*/ + +#define TOTAL_RESERVED_PKT_LEN 768 + +static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { + /* page 0 beacon */ + 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 1 beacon */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 2 ps-poll */ + 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 3 null */ + 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 4 probe_resp */ + 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 5 probe_resp */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct sk_buff *skb = NULL; + + u32 totalpacketlen; + bool rtstatus; + u8 u1RsvdPageLoc[3] = {0}; + bool b_dlok = false; + + u8 *beacon; + u8 *p_pspoll; + u8 *nullfunc; + u8 *p_probersp; + /*--------------------------------------------------------- + (1) beacon + ---------------------------------------------------------*/ + beacon = &reserved_page_packet[BEACON_PG * 128]; + SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); + SET_80211_HDR_ADDRESS3(beacon, mac->bssid); + + /*------------------------------------------------------- + (2) ps-poll + --------------------------------------------------------*/ + p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; + SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); + SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); + SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); + + SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG); + + /*-------------------------------------------------------- + (3) null data + ---------------------------------------------------------*/ + nullfunc = &reserved_page_packet[NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); + SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); + SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG); + + /*--------------------------------------------------------- + (4) probe response + ----------------------------------------------------------*/ + p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; + SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); + SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); + SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG); + + totalpacketlen = TOTAL_RESERVED_PKT_LEN; + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + &reserved_page_packet[0], totalpacketlen); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + u1RsvdPageLoc, 3); + + + skb = dev_alloc_skb(totalpacketlen); + memcpy((u8 *) skb_put(skb, totalpacketlen), + &reserved_page_packet, totalpacketlen); + + rtstatus = rtlpriv->cfg->ops->cmd_send_packet(hw, skb); + + if (rtstatus) + b_dlok = true; + + if (b_dlok) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + ("Set RSVD page location to Fw.\n")); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "H2C_RSVDPAGE:\n", + u1RsvdPageLoc, 3); + rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE, + sizeof(u1RsvdPageLoc), u1RsvdPageLoc); + } else + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + ("Set RSVD page location to Fw FAIL!!!!!!.\n")); +} +EXPORT_SYMBOL(rtl92c_set_fw_rsvdpagepkt); + +void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) +{ + u8 u1_joinbssrpt_parm[1] = {0}; + + SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus); + + rtl92c_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm); +} +EXPORT_SYMBOL(rtl92c_set_fw_joinbss_report_cmd); diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h new file mode 100644 index 000000000000..3db33bd14666 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h @@ -0,0 +1,98 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92C__FW__H__ +#define __RTL92C__FW__H__ + +#define FW_8192C_SIZE 0x3000 +#define FW_8192C_START_ADDRESS 0x1000 +#define FW_8192C_END_ADDRESS 0x3FFF +#define FW_8192C_PAGE_SIZE 4096 +#define FW_8192C_POLLING_DELAY 5 +#define FW_8192C_POLLING_TIMEOUT_COUNT 100 + +#define IS_FW_HEADER_EXIST(_pfwhdr) \ + ((_pfwhdr->signature&0xFFF0) == 0x92C0 ||\ + (_pfwhdr->signature&0xFFF0) == 0x88C0) + +struct rtl92c_firmware_header { + u16 signature; + u8 category; + u8 function; + u16 version; + u8 subversion; + u8 rsvd1; + u8 month; + u8 date; + u8 hour; + u8 minute; + u16 ramcodeSize; + u16 rsvd2; + u32 svnindex; + u32 rsvd3; + u32 rsvd4; + u32 rsvd5; +}; + +enum rtl8192c_h2c_cmd { + H2C_AP_OFFLOAD = 0, + H2C_SETPWRMODE = 1, + H2C_JOINBSSRPT = 2, + H2C_RSVDPAGE = 3, + H2C_RSSI_REPORT = 5, + H2C_RA_MASK = 6, + MAX_H2CCMD +}; + +#define pagenum_128(_len) (u32)(((_len)>>7) + ((_len)&0x7F ? 1 : 0)) + +#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) +#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) +#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) +#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) + +int rtl92c_download_fw(struct ieee80211_hw *hw); +void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *p_cmdbuffer); +void rtl92c_firmware_selfreset(struct ieee80211_hw *hw); +void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); +void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); +void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/main.c b/drivers/net/wireless/rtlwifi/rtl8192c/main.c new file mode 100644 index 000000000000..2f624fc27499 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192c/main.c @@ -0,0 +1,39 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" + + +MODULE_AUTHOR("lizhaoming "); +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Georgia "); +MODULE_AUTHOR("Ziv Huang "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n PCI wireless"); diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index 3728abc4df59..30e3ef8badee 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c @@ -27,44 +27,15 @@ * *****************************************************************************/ +#include "../wifi.h" +#include "../rtl8192ce/reg.h" +#include "../rtl8192ce/def.h" +#include "dm_common.h" +#include "phy_common.h" + /* Define macro to shorten lines */ #define MCS_TXPWR mcs_txpwrlevel_origoffset -static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset); -static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, - u32 data); -static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset); -static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, - u32 data); -static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); -static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); -static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); -static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, - u8 configtype); -static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, - u8 configtype); -static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); -static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, - u32 cmdtableidx, u32 cmdtablesz, - enum swchnlcmd_id cmdid, u32 para1, - u32 para2, u32 msdelay); -static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, - u8 channel, u8 *stage, u8 *step, - u32 *delay); -static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, - long power_indbm); -static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, - enum radio_path rfpath); -static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, - u8 txpwridx); -static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t); - u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -84,6 +55,7 @@ u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) return returnvalue; } +EXPORT_SYMBOL(rtl92c_phy_query_bb_reg); void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, u32 data) @@ -106,24 +78,26 @@ void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," " data(%#x)\n", regaddr, bitmask, data)); - } +EXPORT_SYMBOL(rtl92c_phy_set_bb_reg); -static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, +u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset) { RT_ASSERT(false, ("deprecated!\n")); return 0; } +EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_read); -static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, +void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset, u32 data) { RT_ASSERT(false, ("deprecated!\n")); } +EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_write); -static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, +u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -172,8 +146,9 @@ static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, retvalue)); return retvalue; } +EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read); -static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, +void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset, u32 data) { @@ -195,8 +170,9 @@ static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, rfpath, pphyreg->rf3wire_offset, data_and_addr)); } +EXPORT_SYMBOL(_rtl92c_phy_rf_serial_write); -static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) +u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) { u32 i; @@ -206,6 +182,7 @@ static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) } return i; } +EXPORT_SYMBOL(_rtl92c_phy_calculate_bit_shift); static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) { @@ -222,10 +199,13 @@ static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) } bool rtl92c_phy_rf_config(struct ieee80211_hw *hw) { - return rtl92c_phy_rf6052_config(hw); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + return rtlpriv->cfg->ops->phy_rf6052_config(hw); } +EXPORT_SYMBOL(rtl92c_phy_rf_config); -static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) +bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); @@ -233,7 +213,7 @@ static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) bool rtstatus; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n")); - rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, + rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw, BASEBAND_CONFIG_PHY_REG); if (rtstatus != true) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!")); @@ -245,14 +225,14 @@ static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) } if (rtlefuse->autoload_failflag == false) { rtlphy->pwrgroup_cnt = 0; - rtstatus = _rtl92c_phy_config_bb_with_pgheaderfile(hw, + rtstatus = rtlpriv->cfg->ops->config_bb_with_pgheaderfile(hw, BASEBAND_CONFIG_PHY_REG); } if (rtstatus != true) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!")); return false; } - rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, + rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB); if (rtstatus != true) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n")); @@ -263,13 +243,9 @@ static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) 0x200)); return true; } +EXPORT_SYMBOL(_rtl92c_phy_bb8192c_config_parafile); - -void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw) -{ -} - -static void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, +void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, u32 data) { @@ -404,12 +380,7 @@ static void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, rtlphy->pwrgroup_cnt++; } } - -static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, - enum radio_path rfpath) -{ - return true; -} +EXPORT_SYMBOL(_rtl92c_store_pwrIndex_diffrate_offset); void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) { @@ -443,7 +414,7 @@ void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) ROFDM0_RXDETECTOR3, rtlphy->framesync)); } -static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) +void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); @@ -547,6 +518,7 @@ static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) TRANSCEIVEB_HSPI_READBACK; } +EXPORT_SYMBOL(_rtl92c_phy_init_bb_rf_register_definition); void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) { @@ -615,7 +587,8 @@ static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw, void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) { - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); u8 cckpowerlevel[2], ofdmpowerlevel[2]; if (rtlefuse->txpwr_fromeprom == false) @@ -625,9 +598,11 @@ void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) _rtl92c_ccxpower_index_check(hw, channel, &cckpowerlevel[0], &ofdmpowerlevel[0]); - rtl92c_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); - rtl92c_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel); + rtlpriv->cfg->ops->phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); + rtlpriv->cfg->ops->phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], + channel); } +EXPORT_SYMBOL(rtl92c_phy_set_txpower_level); bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) { @@ -662,10 +637,12 @@ bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); return true; } +EXPORT_SYMBOL(rtl92c_phy_update_txpower_dbm); void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval) { } +EXPORT_SYMBOL(rtl92c_phy_set_beacon_hw_reg); static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, enum wireless_mode wirelessmode, @@ -697,6 +674,7 @@ static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, return txpwridx; } +EXPORT_SYMBOL(_rtl92c_phy_dbm_to_txpwr_Idx); static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, enum wireless_mode wirelessmode, @@ -720,6 +698,7 @@ static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, pwrout_dbm = txpwridx / 2 + offset; return pwrout_dbm; } +EXPORT_SYMBOL(_rtl92c_phy_txpwr_idx_to_dbm); void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) { @@ -749,6 +728,7 @@ void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) } } } +EXPORT_SYMBOL(rtl92c_phy_scan_operation_backup); void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, enum nl80211_channel_type ch_type) @@ -762,7 +742,7 @@ void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, return; rtlphy->set_bwmode_inprogress = true; if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) - rtl92c_phy_set_bw_mode_callback(hw); + rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw); else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("FALSE driver sleep or unload\n")); @@ -770,6 +750,7 @@ void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, rtlphy->current_chan_bw = tmp_bw; } } +EXPORT_SYMBOL(rtl92c_phy_set_bw_mode); void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) { @@ -798,6 +779,7 @@ void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) } while (true); RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); } +EXPORT_SYMBOL(rtl92c_phy_sw_chnl_callback); u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) { @@ -827,6 +809,7 @@ u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) } return 1; } +EXPORT_SYMBOL(rtl92c_phy_sw_chnl); static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel, u8 *stage, u8 *step, @@ -961,6 +944,7 @@ bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath) { return true; } +EXPORT_SYMBOL(rtl8192_phy_check_is_legal_rfpath); static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) { @@ -1901,19 +1885,22 @@ void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery) _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10); } +EXPORT_SYMBOL(rtl92c_phy_iq_calibrate); void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw) { + struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); bool start_conttx = false, singletone = false; if (start_conttx || singletone) return; if (IS_92C_SERIAL(rtlhal->version)) - _rtl92c_phy_lc_calibrate(hw, true); + rtlpriv->cfg->ops->phy_lc_calibrate(hw, true); else - _rtl92c_phy_lc_calibrate(hw, false); + rtlpriv->cfg->ops->phy_lc_calibrate(hw, false); } +EXPORT_SYMBOL(rtl92c_phy_lc_calibrate); void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) { @@ -1928,6 +1915,7 @@ void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) else _rtl92c_phy_ap_calibrate(hw, delta, false); } +EXPORT_SYMBOL(rtl92c_phy_ap_calibrate); void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) { @@ -1938,6 +1926,7 @@ void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) else _rtl92c_phy_set_rfpath_switch(hw, bmain, false); } +EXPORT_SYMBOL(rtl92c_phy_set_rfpath_switch); bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) { @@ -1976,6 +1965,7 @@ bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype)); return true; } +EXPORT_SYMBOL(rtl92c_phy_set_io_cmd); void rtl92c_phy_set_io(struct ieee80211_hw *hw) { @@ -2005,6 +1995,7 @@ void rtl92c_phy_set_io(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<---(%#x)\n", rtlphy->current_io_type)); } +EXPORT_SYMBOL(rtl92c_phy_set_io); void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw) { @@ -2017,8 +2008,9 @@ void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); } +EXPORT_SYMBOL(rtl92ce_phy_set_rf_on); -static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw) +void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw) { u32 u4b_tmp; u8 delay = 5; @@ -2047,3 +2039,4 @@ static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); } +EXPORT_SYMBOL(_rtl92c_phy_set_rf_sleep); diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h new file mode 100644 index 000000000000..148bc019f4bd --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h @@ -0,0 +1,246 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2010 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL92C_PHY_H__ +#define __RTL92C_PHY_H__ + +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#define MAX_DOZE_WAITING_TIMES_9x 64 + +#define RT_CANNOT_IO(hw) false +#define HIGHPOWER_RADIOA_ARRAYLEN 22 + +#define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 1 + +#define APK_BB_REG_NUM 5 +#define APK_AFE_REG_NUM 16 +#define APK_CURVE_REG_NUM 4 +#define PATH_NUM 2 + +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 +#define AntennaDiversityValue 0x80 +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define Reset_Cnt_Limit 3 + +#define IQK_ADDA_REG_NUM 16 +#define IQK_MAC_REG_NUM 4 + +#define RF90_PATH_MAX 2 + +#define CT_OFFSET_MAC_ADDR 0X16 + +#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A +#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60 +#define CT_OFFSET_HT402S_TX_PWR_IDX_DIF 0x66 +#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69 +#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C + +#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F +#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72 + +#define CT_OFFSET_CHANNEL_PLAH 0x75 +#define CT_OFFSET_THERMAL_METER 0x78 +#define CT_OFFSET_RF_OPTION 0x79 +#define CT_OFFSET_VERSION 0x7E +#define CT_OFFSET_CUSTOMER_ID 0x7F + +#define RTL92C_MAX_PATH_NUM 2 +#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255 +enum swchnlcmd_id { + CMDID_END, + CMDID_SET_TXPOWEROWER_LEVEL, + CMDID_BBREGWRITE10, + CMDID_WRITEPORT_ULONG, + CMDID_WRITEPORT_USHORT, + CMDID_WRITEPORT_UCHAR, + CMDID_RF_WRITEREG, +}; + +struct swchnlcmd { + enum swchnlcmd_id cmdid; + u32 para1; + u32 para2; + u32 msdelay; +}; + +enum hw90_block_e { + HW90_BLOCK_MAC = 0, + HW90_BLOCK_PHY0 = 1, + HW90_BLOCK_PHY1 = 2, + HW90_BLOCK_RF = 3, + HW90_BLOCK_MAXIMUM = 4, +}; + +enum baseband_config_type { + BASEBAND_CONFIG_PHY_REG = 0, + BASEBAND_CONFIG_AGC_TAB = 1, +}; + +enum ra_offset_area { + RA_OFFSET_LEGACY_OFDM1, + RA_OFFSET_LEGACY_OFDM2, + RA_OFFSET_HT_OFDM1, + RA_OFFSET_HT_OFDM2, + RA_OFFSET_HT_OFDM3, + RA_OFFSET_HT_OFDM4, + RA_OFFSET_HT_CCK, +}; + +enum antenna_path { + ANTENNA_NONE, + ANTENNA_D, + ANTENNA_C, + ANTENNA_CD, + ANTENNA_B, + ANTENNA_BD, + ANTENNA_BC, + ANTENNA_BCD, + ANTENNA_A, + ANTENNA_AD, + ANTENNA_AC, + ANTENNA_ACD, + ANTENNA_AB, + ANTENNA_ABD, + ANTENNA_ABC, + ANTENNA_ABCD +}; + +struct r_antenna_select_ofdm { + u32 r_tx_antenna:4; + u32 r_ant_l:4; + u32 r_ant_non_ht:4; + u32 r_ant_ht1:4; + u32 r_ant_ht2:4; + u32 r_ant_ht_s1:4; + u32 r_ant_non_ht_s1:4; + u32 ofdm_txsc:2; + u32 reserved:2; +}; + +struct r_antenna_select_cck { + u8 r_cckrx_enable_2:2; + u8 r_cckrx_enable:2; + u8 r_ccktx_enable:4; +}; + +struct efuse_contents { + u8 mac_addr[ETH_ALEN]; + u8 cck_tx_power_idx[6]; + u8 ht40_1s_tx_power_idx[6]; + u8 ht40_2s_tx_power_idx_diff[3]; + u8 ht20_tx_power_idx_diff[3]; + u8 ofdm_tx_power_idx_diff[3]; + u8 ht40_max_power_offset[3]; + u8 ht20_max_power_offset[3]; + u8 channel_plan; + u8 thermal_meter; + u8 rf_option[5]; + u8 version; + u8 oem_id; + u8 regulatory; +}; + +struct tx_power_struct { + u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 legacy_ht_txpowerdiff; + u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; + u8 pwrgroup_cnt; + u32 mcs_original_offset[4][16]; +}; + +extern u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask); +extern void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data); +extern u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask); +extern void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask, u32 data); +extern bool rtl92c_phy_mac_config(struct ieee80211_hw *hw); +extern bool rtl92c_phy_bb_config(struct ieee80211_hw *hw); +extern bool rtl92c_phy_rf_config(struct ieee80211_hw *hw); +extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +extern void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +extern void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, + long *powerlevel); +extern void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +extern bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, + long power_indbm); +extern void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, + u8 operation); +extern void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +extern void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +extern void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw); +extern u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw); +extern void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); +extern void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, + u16 beaconinterval); +void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); +void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); +void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); +bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +extern bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, + u32 rfpath); +extern bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); +void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); +void rtl92c_phy_set_io(struct ieee80211_hw *hw); +void rtl92c_bb_block_on(struct ieee80211_hw *hw); +u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); +static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx); +static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + long power_indbm); +void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); +static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, + u32 cmdtableidx, u32 cmdtablesz, + enum swchnlcmd_id cmdid, u32 para1, + u32 para2, u32 msdelay); +static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, u8 *step, + u32 *delay); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile b/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile index 5c5fdde637cb..c0cb0cfe7d37 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile @@ -1,6 +1,5 @@ rtl8192ce-objs := \ dm.o \ - fw.o \ hw.o \ led.o \ phy.o \ diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c index 888df5e2d2fc..7d76504df4d1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c @@ -33,11 +33,8 @@ #include "def.h" #include "phy.h" #include "dm.h" -#include "fw.h" -#include "../rtl8192c/dm_common.c" - -void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) +void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); @@ -114,5 +111,3 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; } - - diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h index 5911d52a24ac..36302ebae4a3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h @@ -192,6 +192,6 @@ void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw); void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw); void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); -void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw); +void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c deleted file mode 100644 index 11c8bdb4af59..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c +++ /dev/null @@ -1,769 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include -#include "../wifi.h" -#include "../pci.h" -#include "../base.h" -#include "reg.h" -#include "def.h" -#include "fw.h" -#include "table.h" - -static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) { - u32 value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); - if (enable) - value32 |= MCUFWDL_EN; - else - value32 &= ~MCUFWDL_EN; - rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); - } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) { - u8 tmp; - if (enable) { - - tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, - tmp | 0x04); - - tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); - rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01); - - tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2); - rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7); - } else { - - tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); - rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe); - - rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00); - } - } -} - -static void _rtl92c_fw_block_write(struct ieee80211_hw *hw, - const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 blockSize = sizeof(u32); - u8 *bufferPtr = (u8 *) buffer; - u32 *pu4BytePtr = (u32 *) buffer; - u32 i, offset, blockCount, remainSize; - - blockCount = size / blockSize; - remainSize = size % blockSize; - - for (i = 0; i < blockCount; i++) { - offset = i * blockSize; - rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset), - *(pu4BytePtr + i)); - } - - if (remainSize) { - offset = blockCount * blockSize; - bufferPtr += offset; - for (i = 0; i < remainSize; i++) { - rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS + - offset + i), *(bufferPtr + i)); - } - } -} - -static void _rtl92c_fw_page_write(struct ieee80211_hw *hw, - u32 page, const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 value8; - u8 u8page = (u8) (page & 0x07); - - value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page; - - rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8); - _rtl92c_fw_block_write(hw, buffer, size); -} - -static void _rtl92c_fill_dummy(u8 *pfwbuf, u32 *pfwlen) -{ - u32 fwlen = *pfwlen; - u8 remain = (u8) (fwlen % 4); - - remain = (remain == 0) ? 0 : (4 - remain); - - while (remain > 0) { - pfwbuf[fwlen] = 0; - fwlen++; - remain--; - } - - *pfwlen = fwlen; -} - -static void _rtl92c_write_fw(struct ieee80211_hw *hw, - enum version_8192c version, u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 *bufferPtr = (u8 *) buffer; - - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size)); - - if (IS_CHIP_VER_B(version)) { - u32 pageNums, remainSize; - u32 page, offset; - - if (IS_HARDWARE_TYPE_8192CE(rtlhal)) - _rtl92c_fill_dummy(bufferPtr, &size); - - pageNums = size / FW_8192C_PAGE_SIZE; - remainSize = size % FW_8192C_PAGE_SIZE; - - if (pageNums > 4) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Page numbers should not greater then 4\n")); - } - - for (page = 0; page < pageNums; page++) { - offset = page * FW_8192C_PAGE_SIZE; - _rtl92c_fw_page_write(hw, page, (bufferPtr + offset), - FW_8192C_PAGE_SIZE); - } - - if (remainSize) { - offset = pageNums * FW_8192C_PAGE_SIZE; - page = pageNums; - _rtl92c_fw_page_write(hw, page, (bufferPtr + offset), - remainSize); - } - } else { - _rtl92c_fw_block_write(hw, buffer, size); - } -} - -static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - int err = -EIO; - u32 counter = 0; - u32 value32; - - do { - value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); - } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) && - (!(value32 & FWDL_ChkSum_rpt))); - - if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("chksum report faill ! REG_MCUFWDL:0x%08x .\n", - value32)); - goto exit; - } - - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32)); - - value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); - value32 |= MCUFWDL_RDY; - value32 &= ~WINTINI_RDY; - rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); - - counter = 0; - - do { - value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); - if (value32 & WINTINI_RDY) { - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("Polling FW ready success!!" - " REG_MCUFWDL:0x%08x .\n", - value32)); - err = 0; - goto exit; - } - - mdelay(FW_8192C_POLLING_DELAY); - - } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT); - - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32)); - -exit: - return err; -} - -int rtl92c_download_fw(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl92c_firmware_header *pfwheader; - u8 *pfwdata; - u32 fwsize; - int err; - enum version_8192c version = rtlhal->version; - const struct firmware *firmware; - - printk(KERN_INFO "rtl8192cu: Loading firmware file %s\n", - rtlpriv->cfg->fw_name); - err = request_firmware(&firmware, rtlpriv->cfg->fw_name, - rtlpriv->io.dev); - if (err) { - printk(KERN_ERR "rtl8192cu: Firmware loading failed\n"); - return 1; - } - - if (firmware->size > 0x4000) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Firmware is too big!\n")); - release_firmware(firmware); - return 1; - } - - memcpy(rtlhal->pfirmware, firmware->data, firmware->size); - fwsize = firmware->size; - release_firmware(firmware); - - pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; - pfwdata = (u8 *) rtlhal->pfirmware; - - if (IS_FW_HEADER_EXIST(pfwheader)) { - RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Firmware Version(%d), Signature(%#x),Size(%d)\n", - pfwheader->version, pfwheader->signature, - (uint)sizeof(struct rtl92c_firmware_header))); - - pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header); - fwsize = fwsize - sizeof(struct rtl92c_firmware_header); - } - - _rtl92c_enable_fw_download(hw, true); - _rtl92c_write_fw(hw, version, pfwdata, fwsize); - _rtl92c_enable_fw_download(hw, false); - - err = _rtl92c_fw_free_to_go(hw); - if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Firmware is not ready to run!\n")); - } else { - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("Firmware is ready to run!\n")); - } - - return 0; -} - -static bool _rtl92c_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 val_hmetfr, val_mcutst_1; - bool result = false; - - val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR); - val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum)); - - if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0) - result = true; - return result; -} - -static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, - u8 element_id, u32 cmd_len, u8 *p_cmdbuffer) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 boxnum; - u16 box_reg, box_extreg; - u8 u1b_tmp; - bool isfw_read = false; - u8 buf_index; - bool bwrite_sucess = false; - u8 wait_h2c_limmit = 100; - u8 wait_writeh2c_limmit = 100; - u8 boxcontent[4], boxextcontent[2]; - u32 h2c_waitcounter = 0; - unsigned long flag; - u8 idx; - - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n")); - - while (true) { - spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); - if (rtlhal->h2c_setinprogress) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("H2C set in progress! Wait to set.." - "element_id(%d).\n", element_id)); - - while (rtlhal->h2c_setinprogress) { - spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, - flag); - h2c_waitcounter++; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wait 100 us (%d times)...\n", - h2c_waitcounter)); - udelay(100); - - if (h2c_waitcounter > 1000) - return; - spin_lock_irqsave(&rtlpriv->locks.h2c_lock, - flag); - } - spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - } else { - rtlhal->h2c_setinprogress = true; - spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - break; - } - } - - while (!bwrite_sucess) { - wait_writeh2c_limmit--; - if (wait_writeh2c_limmit == 0) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Write H2C fail because no trigger " - "for FW INT!\n")); - break; - } - - boxnum = rtlhal->last_hmeboxnum; - switch (boxnum) { - case 0: - box_reg = REG_HMEBOX_0; - box_extreg = REG_HMEBOX_EXT_0; - break; - case 1: - box_reg = REG_HMEBOX_1; - box_extreg = REG_HMEBOX_EXT_1; - break; - case 2: - box_reg = REG_HMEBOX_2; - box_extreg = REG_HMEBOX_EXT_2; - break; - case 3: - box_reg = REG_HMEBOX_3; - box_extreg = REG_HMEBOX_EXT_3; - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); - break; - } - - isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum); - while (!isfw_read) { - - wait_h2c_limmit--; - if (wait_h2c_limmit == 0) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wating too long for FW read " - "clear HMEBox(%d)!\n", boxnum)); - break; - } - - udelay(10); - - isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum); - u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF); - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wating for FW read clear HMEBox(%d)!!! " - "0x1BF = %2x\n", boxnum, u1b_tmp)); - } - - if (!isfw_read) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Write H2C register BOX[%d] fail!!!!! " - "Fw do not read.\n", boxnum)); - break; - } - - memset(boxcontent, 0, sizeof(boxcontent)); - memset(boxextcontent, 0, sizeof(boxextcontent)); - boxcontent[0] = element_id; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Write element_id box_reg(%4x) = %2x\n", - box_reg, element_id)); - - switch (cmd_len) { - case 1: - boxcontent[0] &= ~(BIT(7)); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer + buf_index, 1); - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - case 2: - boxcontent[0] &= ~(BIT(7)); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer + buf_index, 2); - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - case 3: - boxcontent[0] &= ~(BIT(7)); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer + buf_index, 3); - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - case 4: - boxcontent[0] |= (BIT(7)); - memcpy((u8 *) (boxextcontent), - p_cmdbuffer + buf_index, 2); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer + buf_index + 2, 2); - - for (idx = 0; idx < 2; idx++) { - rtl_write_byte(rtlpriv, box_extreg + idx, - boxextcontent[idx]); - } - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - case 5: - boxcontent[0] |= (BIT(7)); - memcpy((u8 *) (boxextcontent), - p_cmdbuffer + buf_index, 2); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer + buf_index + 2, 3); - - for (idx = 0; idx < 2; idx++) { - rtl_write_byte(rtlpriv, box_extreg + idx, - boxextcontent[idx]); - } - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); - break; - } - - bwrite_sucess = true; - - rtlhal->last_hmeboxnum = boxnum + 1; - if (rtlhal->last_hmeboxnum == 4) - rtlhal->last_hmeboxnum = 0; - - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("pHalData->last_hmeboxnum = %d\n", - rtlhal->last_hmeboxnum)); - } - - spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); - rtlhal->h2c_setinprogress = false; - spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n")); -} - -void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, - u8 element_id, u32 cmd_len, u8 *p_cmdbuffer) -{ - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u32 tmp_cmdbuf[2]; - - if (rtlhal->fw_ready == false) { - RT_ASSERT(false, ("return H2C cmd because of Fw " - "download fail!!!\n")); - return; - } - - memset(tmp_cmdbuf, 0, 8); - memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len); - _rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); - - return; -} - -void rtl92c_firmware_selfreset(struct ieee80211_hw *hw) -{ - u8 u1b_tmp; - u8 delay = 100; - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20); - u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); - - while (u1b_tmp & BIT(2)) { - delay--; - if (delay == 0) { - RT_ASSERT(false, ("8051 reset fail.\n")); - break; - } - udelay(50); - u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); - } -} - -void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 u1_h2c_set_pwrmode[3] = {0}; - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode)); - - SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); - SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1); - SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, - ppsc->reg_max_lps_awakeintvl); - - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n", - u1_h2c_set_pwrmode, 3); - rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode); - -} - -#define BEACON_PG 0 /*->1*/ -#define PSPOLL_PG 2 -#define NULL_PG 3 -#define PROBERSP_PG 4 /*->5*/ - -#define TOTAL_RESERVED_PKT_LEN 768 - -static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { - /* page 0 beacon */ - 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, - 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, - 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, - 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, - 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, - 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, - 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, - 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 1 beacon */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 2 ps-poll */ - 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10, - 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 3 null */ - 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, - 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, - 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 4 probe_resp */ - 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, - 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, - 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, - 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, - 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, - 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, - 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, - 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, - 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, - 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, - 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 5 probe_resp */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct sk_buff *skb = NULL; - - u32 totalpacketlen; - bool rtstatus; - u8 u1RsvdPageLoc[3] = {0}; - bool b_dlok = false; - - u8 *beacon; - u8 *p_pspoll; - u8 *nullfunc; - u8 *p_probersp; - /*--------------------------------------------------------- - (1) beacon - ---------------------------------------------------------*/ - beacon = &reserved_page_packet[BEACON_PG * 128]; - SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); - SET_80211_HDR_ADDRESS3(beacon, mac->bssid); - - /*------------------------------------------------------- - (2) ps-poll - --------------------------------------------------------*/ - p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; - SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); - SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); - SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); - - SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG); - - /*-------------------------------------------------------- - (3) null data - ---------------------------------------------------------*/ - nullfunc = &reserved_page_packet[NULL_PG * 128]; - SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); - SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); - SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); - - SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG); - - /*--------------------------------------------------------- - (4) probe response - ----------------------------------------------------------*/ - p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; - SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); - SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); - SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); - - SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG); - - totalpacketlen = TOTAL_RESERVED_PKT_LEN; - - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, - "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", - &reserved_page_packet[0], totalpacketlen); - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", - u1RsvdPageLoc, 3); - - - skb = dev_alloc_skb(totalpacketlen); - memcpy((u8 *) skb_put(skb, totalpacketlen), - &reserved_page_packet, totalpacketlen); - - rtstatus = rtlpriv->cfg->ops->cmd_send_packet(hw, skb); - - if (rtstatus) - b_dlok = true; - - if (b_dlok) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Set RSVD page location to Fw.\n")); - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "H2C_RSVDPAGE:\n", - u1RsvdPageLoc, 3); - rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE, - sizeof(u1RsvdPageLoc), u1RsvdPageLoc); - } else - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Set RSVD page location to Fw FAIL!!!!!!.\n")); -} - -void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) -{ - u8 u1_joinbssrpt_parm[1] = {0}; - - SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus); - - rtl92c_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm); -} diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/fw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.h deleted file mode 100644 index 3db33bd14666..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/fw.h +++ /dev/null @@ -1,98 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL92C__FW__H__ -#define __RTL92C__FW__H__ - -#define FW_8192C_SIZE 0x3000 -#define FW_8192C_START_ADDRESS 0x1000 -#define FW_8192C_END_ADDRESS 0x3FFF -#define FW_8192C_PAGE_SIZE 4096 -#define FW_8192C_POLLING_DELAY 5 -#define FW_8192C_POLLING_TIMEOUT_COUNT 100 - -#define IS_FW_HEADER_EXIST(_pfwhdr) \ - ((_pfwhdr->signature&0xFFF0) == 0x92C0 ||\ - (_pfwhdr->signature&0xFFF0) == 0x88C0) - -struct rtl92c_firmware_header { - u16 signature; - u8 category; - u8 function; - u16 version; - u8 subversion; - u8 rsvd1; - u8 month; - u8 date; - u8 hour; - u8 minute; - u16 ramcodeSize; - u16 rsvd2; - u32 svnindex; - u32 rsvd3; - u32 rsvd4; - u32 rsvd5; -}; - -enum rtl8192c_h2c_cmd { - H2C_AP_OFFLOAD = 0, - H2C_SETPWRMODE = 1, - H2C_JOINBSSRPT = 2, - H2C_RSVDPAGE = 3, - H2C_RSSI_REPORT = 5, - H2C_RA_MASK = 6, - MAX_H2CCMD -}; - -#define pagenum_128(_len) (u32)(((_len)>>7) + ((_len)&0x7F ? 1 : 0)) - -#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) -#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) -#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) -#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) -#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) -#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) -#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) - -int rtl92c_download_fw(struct ieee80211_hw *hw); -void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, - u32 cmd_len, u8 *p_cmdbuffer); -void rtl92c_firmware_selfreset(struct ieee80211_hw *hw); -void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); -void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); -void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); - -#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 0b910921e606..05477f465a75 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -37,7 +37,6 @@ #include "def.h" #include "phy.h" #include "dm.h" -#include "fw.h" #include "led.h" #include "hw.h" @@ -949,8 +948,8 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) } rtlhal->last_hmeboxnum = 0; - rtl92c_phy_mac_config(hw); - rtl92c_phy_bb_config(hw); + rtl92ce_phy_mac_config(hw); + rtl92ce_phy_bb_config(hw); rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; rtl92c_phy_rf_config(hw); rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h index 305c819c8c78..a3dfdb635168 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h @@ -30,6 +30,8 @@ #ifndef __RTL92CE_HW_H__ #define __RTL92CE_HW_H__ +#define H2C_RA_MASK 6 + void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw); void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw, @@ -53,5 +55,14 @@ void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw); void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, bool is_group, u8 enc_algo, bool is_wepkey, bool clear_all); +bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); +void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); +void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); +void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); +int rtl92c_download_fw(struct ieee80211_hw *hw); +void rtl92c_firmware_selfreset(struct ieee80211_hw *hw); +void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, u8 *p_cmdbuffer); +bool rtl92ce_phy_mac_config(struct ieee80211_hw *hw); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 191106033b3c..d0541e8c6012 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -32,14 +32,13 @@ #include "../ps.h" #include "reg.h" #include "def.h" +#include "hw.h" #include "phy.h" #include "rf.h" #include "dm.h" #include "table.h" -#include "../rtl8192c/phy_common.c" - -u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, +u32 rtl92ce_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, u32 regaddr, u32 bitmask) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -74,7 +73,7 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, return readback_value; } -void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, +void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, u32 regaddr, u32 bitmask, u32 data) { @@ -122,19 +121,19 @@ void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, bitmask, data, rfpath)); } -bool rtl92c_phy_mac_config(struct ieee80211_hw *hw) +bool rtl92ce_phy_mac_config(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); bool is92c = IS_92C_SERIAL(rtlhal->version); - bool rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw); + bool rtstatus = _rtl92ce_phy_config_mac_with_headerfile(hw); if (is92c) rtl_write_byte(rtlpriv, 0x14, 0x71); return rtstatus; } -bool rtl92c_phy_bb_config(struct ieee80211_hw *hw) +bool rtl92ce_phy_bb_config(struct ieee80211_hw *hw) { bool rtstatus = true; struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -160,7 +159,7 @@ bool rtl92c_phy_bb_config(struct ieee80211_hw *hw) return rtstatus; } -static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) +bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); u32 i; @@ -177,7 +176,7 @@ static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) return true; } -static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, +bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, u8 configtype) { int i; @@ -221,7 +220,6 @@ static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, phy_regarray_table[i], phy_regarray_table[i + 1])); } - rtl92c_phy_config_bb_external_pa(hw); } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { for (i = 0; i < agctab_arraylen; i = i + 2) { rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD, @@ -237,7 +235,7 @@ static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, return true; } -static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, +bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, u8 configtype) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -276,7 +274,7 @@ static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, return true; } -bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, +bool rtl92ce_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, enum radio_path rfpath) { @@ -331,7 +329,6 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, udelay(1); } } - _rtl92c_phy_config_rf_external_pa(hw, rfpath); break; case RF90_PATH_B: for (i = 0; i < radiob_arraylen; i = i + 2) { @@ -367,7 +364,7 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, return true; } -void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw) +void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); @@ -435,7 +432,7 @@ void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); } -static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) +void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) { u8 tmpreg; u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; @@ -602,7 +599,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies))); ppsc->last_sleep_jiffies = jiffies; - _rtl92ce_phy_set_rf_sleep(hw); + _rtl92c_phy_set_rf_sleep(hw); break; } default: @@ -617,7 +614,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, return bresult; } -bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, +bool rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, enum rf_pwrstate rfpwr_state) { struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h index 3fc60e434cef..a37267e3fc22 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h @@ -191,11 +191,11 @@ extern void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, extern u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, u32 regaddr, u32 bitmask); -extern void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, +extern void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, u32 regaddr, u32 bitmask, u32 data); extern bool rtl92c_phy_mac_config(struct ieee80211_hw *hw); -extern bool rtl92c_phy_bb_config(struct ieee80211_hw *hw); +bool rtl92ce_phy_bb_config(struct ieee80211_hw *hw); extern bool rtl92c_phy_rf_config(struct ieee80211_hw *hw); extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, enum radio_path rfpath); @@ -223,12 +223,32 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, extern bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath); bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); -extern bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, +bool rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, enum rf_pwrstate rfpwr_state); -void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw); void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); void rtl92c_phy_set_io(struct ieee80211_hw *hw); void rtl92c_bb_block_on(struct ieee80211_hw *hw); +u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset); +u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset); +u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); +void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data); +void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, + u32 data); +void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset, + u32 data); +void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, + u32 data); +bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); +void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); +bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); +void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index ffd8e04c4028..669b1168dbec 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c @@ -61,7 +61,7 @@ void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) } } -void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, +void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, u8 *ppowerlevel) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -410,7 +410,7 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw, } } -void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, +void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, u8 *ppowerlevel, u8 channel) { u32 writeVal[2], powerBase0[2], powerBase1[2]; @@ -430,7 +430,7 @@ void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, } } -bool rtl92c_phy_rf6052_config(struct ieee80211_hw *hw) +bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); @@ -484,11 +484,11 @@ static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw) switch (rfpath) { case RF90_PATH_A: - rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, + rtstatus = rtl92ce_phy_config_rf_with_headerfile(hw, (enum radio_path) rfpath); break; case RF90_PATH_B: - rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, + rtstatus = rtl92ce_phy_config_rf_with_headerfile(hw, (enum radio_path) rfpath); break; case RF90_PATH_C: diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h index d3014f99bb7b..3aa520c1c171 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h @@ -40,5 +40,8 @@ extern void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, u8 *ppowerlevel); extern void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, u8 *ppowerlevel, u8 channel); -extern bool rtl92c_phy_rf6052_config(struct ieee80211_hw *hw); +bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw); +bool rtl92ce_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath); + #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index b4df0b332832..b1cc4d44f534 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -37,6 +37,7 @@ #include "phy.h" #include "dm.h" #include "hw.h" +#include "rf.h" #include "sw.h" #include "trx.h" #include "led.h" @@ -122,7 +123,7 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = { .switch_channel = rtl92c_phy_sw_chnl, .dm_watchdog = rtl92c_dm_watchdog, .scan_operation_backup = rtl92c_phy_scan_operation_backup, - .set_rf_power_state = rtl92c_phy_set_rf_power_state, + .set_rf_power_state = rtl92ce_phy_set_rf_power_state, .led_control = rtl92ce_led_control, .set_desc = rtl92ce_set_desc, .get_desc = rtl92ce_get_desc, @@ -133,9 +134,17 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = { .deinit_sw_leds = rtl92ce_deinit_sw_leds, .get_bbreg = rtl92c_phy_query_bb_reg, .set_bbreg = rtl92c_phy_set_bb_reg, - .get_rfreg = rtl92c_phy_query_rf_reg, - .set_rfreg = rtl92c_phy_set_rf_reg, + .get_rfreg = rtl92ce_phy_query_rf_reg, + .set_rfreg = rtl92ce_phy_set_rf_reg, .cmd_send_packet = _rtl92c_cmd_send_packet, + .phy_rf6052_config = rtl92ce_phy_rf6052_config, + .phy_rf6052_set_cck_txpower = rtl92ce_phy_rf6052_set_cck_txpower, + .phy_rf6052_set_ofdm_txpower = rtl92ce_phy_rf6052_set_ofdm_txpower, + .config_bb_with_headerfile = _rtl92ce_phy_config_bb_with_headerfile, + .config_bb_with_pgheaderfile = _rtl92ce_phy_config_bb_with_pgheaderfile, + .phy_lc_calibrate = _rtl92ce_phy_lc_calibrate, + .phy_set_bw_mode_callback = rtl92ce_phy_set_bw_mode_callback, + .dm_dynamic_txpower = rtl92ce_dm_dynamic_txpower, }; static struct rtl_mod_params rtl92ce_mod_params = { diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h index 0568d6dc83d7..36e657668c1e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h @@ -35,5 +35,17 @@ void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw); void rtl92c_init_var_map(struct ieee80211_hw *hw); bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb); +void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); +bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype); +bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype); +void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t); +u32 rtl92ce_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, u32 bitmask); +void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/Makefile b/drivers/net/wireless/rtlwifi/rtl8192cu/Makefile index 91c65122ca80..ad2de6b839ef 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/Makefile +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/Makefile @@ -1,6 +1,5 @@ rtl8192cu-objs := \ dm.o \ - fw.o \ hw.o \ led.o \ mac.o \ diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c index a4649a2f7e6f..f311baee668d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c @@ -33,11 +33,8 @@ #include "def.h" #include "phy.h" #include "dm.h" -#include "fw.h" -#include "../rtl8192c/dm_common.c" - -void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) +void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h index 5e7fbfc2851b..7f966c666b5a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h @@ -29,4 +29,4 @@ #include "../rtl8192ce/dm.h" -void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw); +void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/fw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/fw.c deleted file mode 100644 index 8e350eea3422..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/fw.c +++ /dev/null @@ -1,30 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../rtl8192ce/fw.c" diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/fw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/fw.h deleted file mode 100644 index a3bbac811d08..000000000000 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/fw.h +++ /dev/null @@ -1,30 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2010 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../rtl8192ce/fw.h" diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index df8fe3b51c9b..9444e76838cf 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -38,7 +38,6 @@ #include "phy.h" #include "mac.h" #include "dm.h" -#include "fw.h" #include "hw.h" #include "trx.h" #include "led.h" @@ -1190,8 +1189,8 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw) } rtlhal->last_hmeboxnum = 0; /* h2c */ _rtl92cu_phy_param_tab_init(hw); - rtl92c_phy_mac_config(hw); - rtl92c_phy_bb_config(hw); + rtl92cu_phy_mac_config(hw); + rtl92cu_phy_bb_config(hw); rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; rtl92c_phy_rf_config(hw); if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && @@ -1203,7 +1202,7 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw) RF_CHNLBW, RFREG_OFFSET_MASK); rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, RF_CHNLBW, RFREG_OFFSET_MASK); - rtl92c_bb_block_on(hw); + rtl92cu_bb_block_on(hw); rtl_cam_reset_all_entry(hw); rtl92cu_enable_hw_security_config(hw); ppsc->rfpwr_state = ERFON; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h index 3c0ea5ea6db5..62af555bb61c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h @@ -30,6 +30,8 @@ #ifndef __RTL92CU_HW_H__ #define __RTL92CU_HW_H__ +#define H2C_RA_MASK 6 + #define LLT_POLLING_LLT_THRESHOLD 20 #define LLT_POLLING_READY_TIMEOUT_COUNT 100 #define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255 @@ -103,5 +105,12 @@ void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw); bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid); void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); u8 _rtl92c_get_chnl_group(u8 chnl); +int rtl92c_download_fw(struct ieee80211_hw *hw); +void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); +void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished); +void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); +void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, + u8 element_id, u32 cmd_len, u8 *p_cmdbuffer); +bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c index dc65ef2bbeac..4e020e654e6b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c @@ -37,9 +37,7 @@ #include "dm.h" #include "table.h" -#include "../rtl8192c/phy_common.c" - -u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, +u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, u32 regaddr, u32 bitmask) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -65,7 +63,7 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, return readback_value; } -void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, +void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, u32 regaddr, u32 bitmask, u32 data) { @@ -104,20 +102,20 @@ void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, regaddr, bitmask, data, rfpath)); } -bool rtl92c_phy_mac_config(struct ieee80211_hw *hw) +bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw) { bool rtstatus; struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); bool is92c = IS_92C_SERIAL(rtlhal->version); - rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw); + rtstatus = _rtl92cu_phy_config_mac_with_headerfile(hw); if (is92c && IS_HARDWARE_TYPE_8192CE(rtlhal)) rtl_write_byte(rtlpriv, 0x14, 0x71); return rtstatus; } -bool rtl92c_phy_bb_config(struct ieee80211_hw *hw) +bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw) { bool rtstatus = true; struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -146,7 +144,7 @@ bool rtl92c_phy_bb_config(struct ieee80211_hw *hw) return rtstatus; } -static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) +bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); @@ -164,7 +162,7 @@ static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) return true; } -static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, +bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, u8 configtype) { int i; @@ -209,7 +207,6 @@ static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, phy_regarray_table[i], phy_regarray_table[i + 1])); } - rtl92c_phy_config_bb_external_pa(hw); } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { for (i = 0; i < agctab_arraylen; i = i + 2) { rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD, @@ -225,7 +222,7 @@ static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, return true; } -static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, +bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, u8 configtype) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -263,7 +260,7 @@ static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, return true; } -bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, +bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, enum radio_path rfpath) { int i; @@ -316,7 +313,6 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, udelay(1); } } - _rtl92c_phy_config_rf_external_pa(hw, rfpath); break; case RF90_PATH_B: for (i = 0; i < radiob_arraylen; i = i + 2) { @@ -352,7 +348,7 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, return true; } -void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw) +void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); @@ -410,12 +406,12 @@ void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw) ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); break; } - rtl92c_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); + rtl92cu_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); rtlphy->set_bwmode_inprogress = false; RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); } -void rtl92c_bb_block_on(struct ieee80211_hw *hw) +void rtl92cu_bb_block_on(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -425,7 +421,7 @@ void rtl92c_bb_block_on(struct ieee80211_hw *hw) mutex_unlock(&rtlpriv->io.bb_mutex); } -static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) +void _rtl92cu_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) { u8 tmpreg; u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; @@ -463,7 +459,7 @@ static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) } } -static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, +bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, enum rf_pwrstate rfpwr_state) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -584,7 +580,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies))); ppsc->last_sleep_jiffies = jiffies; - _rtl92ce_phy_set_rf_sleep(hw); + _rtl92c_phy_set_rf_sleep(hw); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, @@ -598,7 +594,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, return bresult; } -bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, +bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, enum rf_pwrstate rfpwr_state) { struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); @@ -606,6 +602,6 @@ bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, if (rfpwr_state == ppsc->rfpwr_state) return bresult; - bresult = _rtl92ce_phy_set_rf_power_state(hw, rfpwr_state); + bresult = _rtl92cu_phy_set_rf_power_state(hw, rfpwr_state); return bresult; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h index c456c15afbf1..06299559ab68 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h @@ -29,6 +29,8 @@ #include "../rtl8192ce/phy.h" -void rtl92c_bb_block_on(struct ieee80211_hw *hw); +void rtl92cu_bb_block_on(struct ieee80211_hw *hw); bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath); void rtl92c_phy_set_io(struct ieee80211_hw *hw); +bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); +bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c index 9149adcc8fa5..1c79c226f145 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c @@ -36,7 +36,7 @@ static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw); -void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) +void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); @@ -61,7 +61,7 @@ void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) } } -void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, +void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, u8 *ppowerlevel) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -388,7 +388,7 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw, } } -void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, +void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, u8 *ppowerlevel, u8 channel) { u32 writeVal[2], powerBase0[2], powerBase1[2]; @@ -406,7 +406,7 @@ void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, } } -bool rtl92c_phy_rf6052_config(struct ieee80211_hw *hw) +bool rtl92cu_phy_rf6052_config(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); @@ -456,11 +456,11 @@ static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw) udelay(1); switch (rfpath) { case RF90_PATH_A: - rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, + rtstatus = rtl92cu_phy_config_rf_with_headerfile(hw, (enum radio_path) rfpath); break; case RF90_PATH_B: - rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, + rtstatus = rtl92cu_phy_config_rf_with_headerfile(hw, (enum radio_path) rfpath); break; case RF90_PATH_C: diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h index c4ed125ef4dc..86c2728cfa00 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h @@ -27,4 +27,21 @@ * *****************************************************************************/ -#include "../rtl8192ce/rf.h" +#ifndef __RTL92CU_RF_H__ +#define __RTL92CU_RF_H__ + +#define RF6052_MAX_TX_PWR 0x3F +#define RF6052_MAX_REG 0x3F +#define RF6052_MAX_PATH 2 + +extern void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, + u8 bandwidth); +extern void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +extern void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); +bool rtl92cu_phy_rf6052_config(struct ieee80211_hw *hw); +bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath); + +#endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 62604cbd75e8..71244a38d49e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -36,6 +36,7 @@ #include "phy.h" #include "mac.h" #include "dm.h" +#include "rf.h" #include "sw.h" #include "trx.h" #include "led.h" @@ -106,7 +107,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = { .switch_channel = rtl92c_phy_sw_chnl, .dm_watchdog = rtl92c_dm_watchdog, .scan_operation_backup = rtl92c_phy_scan_operation_backup, - .set_rf_power_state = rtl92c_phy_set_rf_power_state, + .set_rf_power_state = rtl92cu_phy_set_rf_power_state, .led_control = rtl92cu_led_control, .enable_hw_sec = rtl92cu_enable_hw_security_config, .set_key = rtl92c_set_key, @@ -114,8 +115,16 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = { .deinit_sw_leds = rtl92cu_deinit_sw_leds, .get_bbreg = rtl92c_phy_query_bb_reg, .set_bbreg = rtl92c_phy_set_bb_reg, - .get_rfreg = rtl92c_phy_query_rf_reg, - .set_rfreg = rtl92c_phy_set_rf_reg, + .get_rfreg = rtl92cu_phy_query_rf_reg, + .set_rfreg = rtl92cu_phy_set_rf_reg, + .phy_rf6052_config = rtl92cu_phy_rf6052_config, + .phy_rf6052_set_cck_txpower = rtl92cu_phy_rf6052_set_cck_txpower, + .phy_rf6052_set_ofdm_txpower = rtl92cu_phy_rf6052_set_ofdm_txpower, + .config_bb_with_headerfile = _rtl92cu_phy_config_bb_with_headerfile, + .config_bb_with_pgheaderfile = _rtl92cu_phy_config_bb_with_pgheaderfile, + .phy_lc_calibrate = _rtl92cu_phy_lc_calibrate, + .phy_set_bw_mode_callback = rtl92cu_phy_set_bw_mode_callback, + .dm_dynamic_txpower = rtl92cu_dm_dynamic_txpower, }; static struct rtl_mod_params rtl92cu_mod_params = { diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h index 3b2c66339554..43b1177924ab 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h @@ -32,4 +32,22 @@ #define EFUSE_MAX_SECTION 16 +void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *powerlevel); +void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); +bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype); +bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, + u8 configtype); +void _rtl92cu_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t); +void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data); +bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); +u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, u32 bitmask); +void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw); + #endif diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 4b90b35f211e..9d0c01a86d0c 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -1383,6 +1383,18 @@ struct rtl_hal_ops { u32 regaddr, u32 bitmask); void (*set_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath, u32 regaddr, u32 bitmask, u32 data); + bool (*phy_rf6052_config) (struct ieee80211_hw *hw); + void (*phy_rf6052_set_cck_txpower) (struct ieee80211_hw *hw, + u8 *powerlevel); + void (*phy_rf6052_set_ofdm_txpower) (struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); + bool (*config_bb_with_headerfile) (struct ieee80211_hw *hw, + u8 configtype); + bool (*config_bb_with_pgheaderfile) (struct ieee80211_hw *hw, + u8 configtype); + void (*phy_lc_calibrate) (struct ieee80211_hw *hw, bool is2t); + void (*phy_set_bw_mode_callback) (struct ieee80211_hw *hw); + void (*dm_dynamic_txpower) (struct ieee80211_hw *hw); }; struct rtl_intf_ops { -- cgit v1.2.3 From 0867b42113ec4eb8646eb361b15cbcfb741ddf5b Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 22 Feb 2011 14:27:58 +0000 Subject: staging: gma500: Intel GMA500 staging driver This is an initial staging driver for the GMA500. It's been stripped out of the PVR drivers and crunched together from various bits of code and different kernels. Currently it's unaccelerated but still pretty snappy even compositing with the frame buffer X server. Lots of work is needed to rework the ttm and bo interfaces from being ripped out and then 2D acceleration wants putting back for framebuffer and somehow eventually via DRM. There is no support for the parts without open source userspace (video accelerators, 3D) as per kernel policy. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 9 +- drivers/staging/gma500/Kconfig | 12 + drivers/staging/gma500/Makefile | 30 + drivers/staging/gma500/TODO | 26 + drivers/staging/gma500/psb_bl.c | 167 +++ drivers/staging/gma500/psb_buffer.c | 450 ++++++ drivers/staging/gma500/psb_drm.h | 696 ++++++++++ drivers/staging/gma500/psb_drv.c | 1677 +++++++++++++++++++++++ drivers/staging/gma500/psb_drv.h | 1139 +++++++++++++++ drivers/staging/gma500/psb_fb.c | 840 ++++++++++++ drivers/staging/gma500/psb_fb.h | 59 + drivers/staging/gma500/psb_fence.c | 122 ++ drivers/staging/gma500/psb_gfx.mod.c | 27 + drivers/staging/gma500/psb_gtt.c | 1034 ++++++++++++++ drivers/staging/gma500/psb_gtt.h | 105 ++ drivers/staging/gma500/psb_intel_bios.c | 301 ++++ drivers/staging/gma500/psb_intel_bios.h | 430 ++++++ drivers/staging/gma500/psb_intel_display.c | 1489 ++++++++++++++++++++ drivers/staging/gma500/psb_intel_display.h | 25 + drivers/staging/gma500/psb_intel_drv.h | 247 ++++ drivers/staging/gma500/psb_intel_i2c.c | 169 +++ drivers/staging/gma500/psb_intel_lvds.c | 889 ++++++++++++ drivers/staging/gma500/psb_intel_modes.c | 77 ++ drivers/staging/gma500/psb_intel_opregion.c | 78 ++ drivers/staging/gma500/psb_intel_reg.h | 1200 ++++++++++++++++ drivers/staging/gma500/psb_intel_sdvo.c | 1298 ++++++++++++++++++ drivers/staging/gma500/psb_intel_sdvo_regs.h | 338 +++++ drivers/staging/gma500/psb_irq.c | 637 +++++++++ drivers/staging/gma500/psb_irq.h | 49 + drivers/staging/gma500/psb_mmu.c | 919 +++++++++++++ drivers/staging/gma500/psb_powermgmt.c | 797 +++++++++++ drivers/staging/gma500/psb_powermgmt.h | 96 ++ drivers/staging/gma500/psb_pvr_glue.c | 73 + drivers/staging/gma500/psb_pvr_glue.h | 25 + drivers/staging/gma500/psb_reg.h | 588 ++++++++ drivers/staging/gma500/psb_reset.c | 90 ++ drivers/staging/gma500/psb_sgx.c | 238 ++++ drivers/staging/gma500/psb_sgx.h | 32 + drivers/staging/gma500/psb_ttm_fence.c | 605 ++++++++ drivers/staging/gma500/psb_ttm_fence_api.h | 272 ++++ drivers/staging/gma500/psb_ttm_fence_driver.h | 302 ++++ drivers/staging/gma500/psb_ttm_fence_user.c | 237 ++++ drivers/staging/gma500/psb_ttm_fence_user.h | 140 ++ drivers/staging/gma500/psb_ttm_glue.c | 349 +++++ drivers/staging/gma500/psb_ttm_placement_user.c | 628 +++++++++ drivers/staging/gma500/psb_ttm_placement_user.h | 252 ++++ drivers/staging/gma500/psb_ttm_userobj_api.h | 85 ++ 48 files changed, 19346 insertions(+), 4 deletions(-) create mode 100644 drivers/staging/gma500/Kconfig create mode 100644 drivers/staging/gma500/Makefile create mode 100644 drivers/staging/gma500/TODO create mode 100644 drivers/staging/gma500/psb_bl.c create mode 100644 drivers/staging/gma500/psb_buffer.c create mode 100644 drivers/staging/gma500/psb_drm.h create mode 100644 drivers/staging/gma500/psb_drv.c create mode 100644 drivers/staging/gma500/psb_drv.h create mode 100644 drivers/staging/gma500/psb_fb.c create mode 100644 drivers/staging/gma500/psb_fb.h create mode 100644 drivers/staging/gma500/psb_fence.c create mode 100644 drivers/staging/gma500/psb_gfx.mod.c create mode 100644 drivers/staging/gma500/psb_gtt.c create mode 100644 drivers/staging/gma500/psb_gtt.h create mode 100644 drivers/staging/gma500/psb_intel_bios.c create mode 100644 drivers/staging/gma500/psb_intel_bios.h create mode 100644 drivers/staging/gma500/psb_intel_display.c create mode 100644 drivers/staging/gma500/psb_intel_display.h create mode 100644 drivers/staging/gma500/psb_intel_drv.h create mode 100644 drivers/staging/gma500/psb_intel_i2c.c create mode 100644 drivers/staging/gma500/psb_intel_lvds.c create mode 100644 drivers/staging/gma500/psb_intel_modes.c create mode 100644 drivers/staging/gma500/psb_intel_opregion.c create mode 100644 drivers/staging/gma500/psb_intel_reg.h create mode 100644 drivers/staging/gma500/psb_intel_sdvo.c create mode 100644 drivers/staging/gma500/psb_intel_sdvo_regs.h create mode 100644 drivers/staging/gma500/psb_irq.c create mode 100644 drivers/staging/gma500/psb_irq.h create mode 100644 drivers/staging/gma500/psb_mmu.c create mode 100644 drivers/staging/gma500/psb_powermgmt.c create mode 100644 drivers/staging/gma500/psb_powermgmt.h create mode 100644 drivers/staging/gma500/psb_pvr_glue.c create mode 100644 drivers/staging/gma500/psb_pvr_glue.h create mode 100644 drivers/staging/gma500/psb_reg.h create mode 100644 drivers/staging/gma500/psb_reset.c create mode 100644 drivers/staging/gma500/psb_sgx.c create mode 100644 drivers/staging/gma500/psb_sgx.h create mode 100644 drivers/staging/gma500/psb_ttm_fence.c create mode 100644 drivers/staging/gma500/psb_ttm_fence_api.h create mode 100644 drivers/staging/gma500/psb_ttm_fence_driver.h create mode 100644 drivers/staging/gma500/psb_ttm_fence_user.c create mode 100644 drivers/staging/gma500/psb_ttm_fence_user.h create mode 100644 drivers/staging/gma500/psb_ttm_glue.c create mode 100644 drivers/staging/gma500/psb_ttm_placement_user.c create mode 100644 drivers/staging/gma500/psb_ttm_placement_user.h create mode 100644 drivers/staging/gma500/psb_ttm_userobj_api.h (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 118bf525b931..4b137a6d9937 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -179,5 +179,7 @@ source "drivers/staging/cptm1217/Kconfig" source "drivers/staging/ste_rmi4/Kconfig" +source "drivers/staging/gma500/Kconfig" + endif # !STAGING_EXCLUDE_BUILD endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 625bae215eda..3519e5703d85 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -61,12 +61,13 @@ obj-$(CONFIG_SOLO6X10) += solo6x10/ obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/ obj-$(CONFIG_ACPI_QUICKSTART) += quickstart/ obj-$(CONFIG_WESTBRIDGE_ASTORIA) += westbridge/astoria/ -obj-$(CONFIG_SBE_2T3E3) += sbe-2t3e3/ +obj-$(CONFIG_SBE_2T3E3) += sbe-2t3e3/ obj-$(CONFIG_ATH6K_LEGACY) += ath6kl/ obj-$(CONFIG_USB_ENESTORAGE) += keucr/ -obj-$(CONFIG_BCM_WIMAX) += bcm/ +obj-$(CONFIG_BCM_WIMAX) += bcm/ obj-$(CONFIG_FT1000) += ft1000/ -obj-$(CONFIG_SND_INTEL_SST) += intel_sst/ -obj-$(CONFIG_SPEAKUP) += speakup/ +obj-$(CONFIG_SND_INTEL_SST) += intel_sst/ +obj-$(CONFIG_SPEAKUP) += speakup/ obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/ obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/ +obj-$(CONFIG_DRM_PSB) += gma500/ diff --git a/drivers/staging/gma500/Kconfig b/drivers/staging/gma500/Kconfig new file mode 100644 index 000000000000..5501eb9b3355 --- /dev/null +++ b/drivers/staging/gma500/Kconfig @@ -0,0 +1,12 @@ +config DRM_PSB + tristate "Intel GMA500 KMS Framebuffer" + depends on DRM && PCI + select FB_CFB_COPYAREA + select FB_CFB_FILLRECT + select FB_CFB_IMAGEBLIT + select DRM_KMS_HELPER + select DRM_TTM + help + Say yes for an experimental KMS framebuffer driver for the + Intel GMA500 ('Poulsbo') graphics support. + diff --git a/drivers/staging/gma500/Makefile b/drivers/staging/gma500/Makefile new file mode 100644 index 000000000000..21381eb4031b --- /dev/null +++ b/drivers/staging/gma500/Makefile @@ -0,0 +1,30 @@ +# +# KMS driver for the GMA500 +# +ccflags-y += -Iinclude/drm + +psb_gfx-y += psb_bl.o \ + psb_drv.o \ + psb_fb.o \ + psb_gtt.o \ + psb_intel_bios.o \ + psb_intel_opregion.o \ + psb_intel_display.o \ + psb_intel_i2c.o \ + psb_intel_lvds.o \ + psb_intel_modes.o \ + psb_intel_sdvo.o \ + psb_reset.o \ + psb_sgx.o \ + psb_pvr_glue.o \ + psb_buffer.o \ + psb_fence.o \ + psb_mmu.o \ + psb_ttm_glue.o \ + psb_ttm_fence.o \ + psb_ttm_fence_user.o \ + psb_ttm_placement_user.o \ + psb_powermgmt.o \ + psb_irq.o + +obj-$(CONFIG_DRM_PSB) += psb_gfx.o diff --git a/drivers/staging/gma500/TODO b/drivers/staging/gma500/TODO new file mode 100644 index 000000000000..f692ce1d2427 --- /dev/null +++ b/drivers/staging/gma500/TODO @@ -0,0 +1,26 @@ +- Test on more platforms +- Clean up the various chunks of unused code +- Sort out the power management side. Not important for Poulsbo but + matters for Moorestown +- Add Moorestown support (single pipe, no BIOS, no stolen memory, + some other differences) +- Sort out the bo and ttm code to support userframe buffers and DRM + interfaces rather than just faking it enough for a framebuffer +- Add 2D acceleration via console and DRM + +As per kernel policy and the in the interest of the safety of various +kittens there is no support or plans to add hooks for the closed user space +stuff. + + +Why bother ? +- Proper display configuration +- Can be made to work on Moorestown where VESA won't +- Works on systems where the VESA BIOS is bust or the tables are broken + without hacks +- 2D acceleration + +Currently tested on ++ Dell Mini 10 100x600 + + diff --git a/drivers/staging/gma500/psb_bl.c b/drivers/staging/gma500/psb_bl.c new file mode 100644 index 000000000000..52edb43c9206 --- /dev/null +++ b/drivers/staging/gma500/psb_bl.c @@ -0,0 +1,167 @@ +/* + * psb backlight using HAL + * + * Copyright (c) 2009, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Authors: Eric Knopp + * + */ + +#include +#include +#include "psb_drv.h" +#include "psb_intel_reg.h" +#include "psb_intel_drv.h" +#include "psb_intel_bios.h" +#include "psb_powermgmt.h" + +#define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF +#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */ +#define BLC_PWM_FREQ_CALC_CONSTANT 32 +#define MHz 1000000 +#define BRIGHTNESS_MIN_LEVEL 1 +#define BRIGHTNESS_MAX_LEVEL 100 +#define BRIGHTNESS_MASK 0xFF +#define BLC_POLARITY_NORMAL 0 +#define BLC_POLARITY_INVERSE 1 +#define BLC_ADJUSTMENT_MAX 100 + +#define PSB_BLC_PWM_PRECISION_FACTOR 10 +#define PSB_BLC_MAX_PWM_REG_FREQ 0xFFFE +#define PSB_BLC_MIN_PWM_REG_FREQ 0x2 + +#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) +#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16) + +static int psb_brightness; +static struct backlight_device *psb_backlight_device; +static u8 blc_brightnesscmd; +static u8 blc_pol; +static u8 blc_type; + +int psb_set_brightness(struct backlight_device *bd) +{ + struct drm_device *dev = bl_get_data(psb_backlight_device); + int level = bd->props.brightness; + + DRM_DEBUG_DRIVER("backlight level set to %d\n", level); + + /* Perform value bounds checking */ + if (level < BRIGHTNESS_MIN_LEVEL) + level = BRIGHTNESS_MIN_LEVEL; + + psb_intel_lvds_set_brightness(dev, level); + psb_brightness = level; + return 0; +} + +int psb_get_brightness(struct backlight_device *bd) +{ + DRM_DEBUG_DRIVER("brightness = 0x%x\n", psb_brightness); + + /* return locally cached var instead of HW read (due to DPST etc.) */ + return psb_brightness; +} + +static const struct backlight_ops psb_ops = { + .get_brightness = psb_get_brightness, + .update_status = psb_set_brightness, +}; + +static int device_backlight_init(struct drm_device *dev) +{ + unsigned long CoreClock; + /* u32 bl_max_freq; */ + /* unsigned long value; */ + u16 bl_max_freq; + uint32_t value; + uint32_t blc_pwm_precision_factor; + struct drm_psb_private *dev_priv = dev->dev_private; + + /* get bl_max_freq and pol from dev_priv*/ + if (!dev_priv->lvds_bl) { + DRM_ERROR("Has no valid LVDS backlight info\n"); + return 1; + } + bl_max_freq = dev_priv->lvds_bl->freq; + blc_pol = dev_priv->lvds_bl->pol; + blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR; + blc_brightnesscmd = dev_priv->lvds_bl->brightnesscmd; + blc_type = dev_priv->lvds_bl->type; + + CoreClock = dev_priv->core_freq; + + value = (CoreClock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT; + value *= blc_pwm_precision_factor; + value /= bl_max_freq; + value /= blc_pwm_precision_factor; + + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_ONLY_IF_ON)) { + /* Check: may be MFLD only */ + if ( + value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ || + value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ) + return 2; + else { + value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR; + REG_WRITE(BLC_PWM_CTL, + (value << PSB_BACKLIGHT_PWM_CTL_SHIFT) | + (value)); + } + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } + return 0; +} + +int psb_backlight_init(struct drm_device *dev) +{ +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + int ret = 0; + + struct backlight_properties props; + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = BRIGHTNESS_MAX_LEVEL; + + psb_backlight_device = backlight_device_register("psb-bl", NULL, + (void *)dev, &psb_ops, &props); + if (IS_ERR(psb_backlight_device)) + return PTR_ERR(psb_backlight_device); + + ret = device_backlight_init(dev); + if (ret < 0) + return ret; + + psb_backlight_device->props.brightness = BRIGHTNESS_MAX_LEVEL; + psb_backlight_device->props.max_brightness = BRIGHTNESS_MAX_LEVEL; + backlight_update_status(psb_backlight_device); +#endif + return 0; +} + +void psb_backlight_exit(void) +{ +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + psb_backlight_device->props.brightness = 0; + backlight_update_status(psb_backlight_device); + backlight_device_unregister(psb_backlight_device); +#endif +} + +struct backlight_device *psb_get_backlight_device(void) +{ + return psb_backlight_device; +} diff --git a/drivers/staging/gma500/psb_buffer.c b/drivers/staging/gma500/psb_buffer.c new file mode 100644 index 000000000000..3077f6a7b7dc --- /dev/null +++ b/drivers/staging/gma500/psb_buffer.c @@ -0,0 +1,450 @@ +/************************************************************************** + * Copyright (c) 2007, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom + */ +#include "ttm/ttm_placement.h" +#include "ttm/ttm_execbuf_util.h" +#include "psb_ttm_fence_api.h" +#include +#include "psb_drv.h" + +#define DRM_MEM_TTM 26 + +struct drm_psb_ttm_backend { + struct ttm_backend base; + struct page **pages; + unsigned int desired_tile_stride; + unsigned int hw_tile_stride; + int mem_type; + unsigned long offset; + unsigned long num_pages; +}; + +/* + * MSVDX/TOPAZ GPU virtual space looks like this + * (We currently use only one MMU context). + * PSB_MEM_MMU_START: from 0x00000000~0xe000000, for generic buffers + * TTM_PL_CI: from 0xe0000000+half GTT space, for camear/video buffer sharing + * TTM_PL_RAR: from TTM_PL_CI+CI size, for RAR/video buffer sharing + * TTM_PL_TT: from TTM_PL_RAR+RAR size, for buffers need to mapping into GTT + */ +static int psb_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, + struct ttm_mem_type_manager *man) +{ + + struct drm_psb_private *dev_priv = + container_of(bdev, struct drm_psb_private, bdev); + struct psb_gtt *pg = dev_priv->pg; + + switch (type) { + case TTM_PL_SYSTEM: + man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; + man->available_caching = TTM_PL_FLAG_CACHED | + TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC; + man->default_caching = TTM_PL_FLAG_CACHED; + break; + case DRM_PSB_MEM_MMU: + man->func = &ttm_bo_manager_func; + man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | + TTM_MEMTYPE_FLAG_CMA; + man->gpu_offset = PSB_MEM_MMU_START; + man->available_caching = TTM_PL_FLAG_CACHED | + TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC; + man->default_caching = TTM_PL_FLAG_WC; + break; + case TTM_PL_CI: + man->func = &ttm_bo_manager_func; + man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | + TTM_MEMTYPE_FLAG_FIXED; + man->gpu_offset = pg->mmu_gatt_start + (pg->ci_start); + man->available_caching = TTM_PL_FLAG_UNCACHED; + man->default_caching = TTM_PL_FLAG_UNCACHED; + break; + case TTM_PL_RAR: /* Unmappable RAR memory */ + man->func = &ttm_bo_manager_func; + man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | + TTM_MEMTYPE_FLAG_FIXED; + man->available_caching = TTM_PL_FLAG_UNCACHED; + man->default_caching = TTM_PL_FLAG_UNCACHED; + man->gpu_offset = pg->mmu_gatt_start + (pg->rar_start); + break; + case TTM_PL_TT: /* Mappable GATT memory */ + man->func = &ttm_bo_manager_func; +#ifdef PSB_WORKING_HOST_MMU_ACCESS + man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; +#else + man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | + TTM_MEMTYPE_FLAG_CMA; +#endif + man->available_caching = TTM_PL_FLAG_CACHED | + TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC; + man->default_caching = TTM_PL_FLAG_WC; + man->gpu_offset = pg->mmu_gatt_start + + (pg->rar_start + dev_priv->rar_region_size); + break; + default: + DRM_ERROR("Unsupported memory type %u\n", (unsigned) type); + return -EINVAL; + } + return 0; +} + + +static void psb_evict_mask(struct ttm_buffer_object *bo, + struct ttm_placement *placement) +{ + static uint32_t cur_placement; + + cur_placement = bo->mem.placement & ~TTM_PL_MASK_MEM; + cur_placement |= TTM_PL_FLAG_SYSTEM; + + placement->fpfn = 0; + placement->lpfn = 0; + placement->num_placement = 1; + placement->placement = &cur_placement; + placement->num_busy_placement = 0; + placement->busy_placement = NULL; + + /* all buffers evicted to system memory */ + /* return cur_placement | TTM_PL_FLAG_SYSTEM; */ +} + +static int psb_invalidate_caches(struct ttm_bo_device *bdev, + uint32_t placement) +{ + return 0; +} + +static int psb_move_blit(struct ttm_buffer_object *bo, + bool evict, bool no_wait, + struct ttm_mem_reg *new_mem) +{ + BUG(); + return 0; +} + +/* + * Flip destination ttm into GATT, + * then blit and subsequently move out again. + */ + +static int psb_move_flip(struct ttm_buffer_object *bo, + bool evict, bool interruptible, bool no_wait, + struct ttm_mem_reg *new_mem) +{ + /*struct ttm_bo_device *bdev = bo->bdev;*/ + struct ttm_mem_reg tmp_mem; + int ret; + struct ttm_placement placement; + uint32_t flags = TTM_PL_FLAG_TT; + + tmp_mem = *new_mem; + tmp_mem.mm_node = NULL; + + placement.fpfn = 0; + placement.lpfn = 0; + placement.num_placement = 1; + placement.placement = &flags; + placement.num_busy_placement = 0; /* FIXME */ + placement.busy_placement = NULL; + + ret = ttm_bo_mem_space(bo, &placement, &tmp_mem, interruptible, + false, no_wait); + if (ret) + return ret; + ret = ttm_tt_bind(bo->ttm, &tmp_mem); + if (ret) + goto out_cleanup; + ret = psb_move_blit(bo, true, no_wait, &tmp_mem); + if (ret) + goto out_cleanup; + + ret = ttm_bo_move_ttm(bo, evict, false, no_wait, new_mem); +out_cleanup: + if (tmp_mem.mm_node) { + drm_mm_put_block(tmp_mem.mm_node); + tmp_mem.mm_node = NULL; + } + return ret; +} + +static int psb_move(struct ttm_buffer_object *bo, + bool evict, bool interruptible, bool no_wait_reserve, + bool no_wait, struct ttm_mem_reg *new_mem) +{ + struct ttm_mem_reg *old_mem = &bo->mem; + + if ((old_mem->mem_type == TTM_PL_RAR) || + (new_mem->mem_type == TTM_PL_RAR)) { + if (old_mem->mm_node) { + spin_lock(&bo->glob->lru_lock); + drm_mm_put_block(old_mem->mm_node); + spin_unlock(&bo->glob->lru_lock); + } + old_mem->mm_node = NULL; + *old_mem = *new_mem; + } else if (old_mem->mem_type == TTM_PL_SYSTEM) { + return ttm_bo_move_memcpy(bo, evict, false, no_wait, new_mem); + } else if (new_mem->mem_type == TTM_PL_SYSTEM) { + int ret = psb_move_flip(bo, evict, interruptible, + no_wait, new_mem); + if (unlikely(ret != 0)) { + if (ret == -ERESTART) + return ret; + else + return ttm_bo_move_memcpy(bo, evict, false, + no_wait, new_mem); + } + } else { + if (psb_move_blit(bo, evict, no_wait, new_mem)) + return ttm_bo_move_memcpy(bo, evict, false, no_wait, + new_mem); + } + return 0; +} + +static int drm_psb_tbe_populate(struct ttm_backend *backend, + unsigned long num_pages, + struct page **pages, + struct page *dummy_read_page, + dma_addr_t *dma_addrs) +{ + struct drm_psb_ttm_backend *psb_be = + container_of(backend, struct drm_psb_ttm_backend, base); + + psb_be->pages = pages; + return 0; +} + +static int drm_psb_tbe_unbind(struct ttm_backend *backend) +{ + struct ttm_bo_device *bdev = backend->bdev; + struct drm_psb_private *dev_priv = + container_of(bdev, struct drm_psb_private, bdev); + struct drm_psb_ttm_backend *psb_be = + container_of(backend, struct drm_psb_ttm_backend, base); + struct psb_mmu_pd *pd = psb_mmu_get_default_pd(dev_priv->mmu); + /* struct ttm_mem_type_manager *man = &bdev->man[psb_be->mem_type]; */ + + if (psb_be->mem_type == TTM_PL_TT) { + uint32_t gatt_p_offset = + (psb_be->offset - dev_priv->pg->mmu_gatt_start) + >> PAGE_SHIFT; + + (void) psb_gtt_remove_pages(dev_priv->pg, gatt_p_offset, + psb_be->num_pages, + psb_be->desired_tile_stride, + psb_be->hw_tile_stride, 0); + } + + psb_mmu_remove_pages(pd, psb_be->offset, + psb_be->num_pages, + psb_be->desired_tile_stride, + psb_be->hw_tile_stride); + + return 0; +} + +static int drm_psb_tbe_bind(struct ttm_backend *backend, + struct ttm_mem_reg *bo_mem) +{ + struct ttm_bo_device *bdev = backend->bdev; + struct drm_psb_private *dev_priv = + container_of(bdev, struct drm_psb_private, bdev); + struct drm_psb_ttm_backend *psb_be = + container_of(backend, struct drm_psb_ttm_backend, base); + struct psb_mmu_pd *pd = psb_mmu_get_default_pd(dev_priv->mmu); + struct ttm_mem_type_manager *man = &bdev->man[bo_mem->mem_type]; + struct drm_mm_node *mm_node = bo_mem->mm_node; + int type; + int ret = 0; + + psb_be->mem_type = bo_mem->mem_type; + psb_be->num_pages = bo_mem->num_pages; + psb_be->desired_tile_stride = 0; + psb_be->hw_tile_stride = 0; + psb_be->offset = (mm_node->start << PAGE_SHIFT) + + man->gpu_offset; + + type = + (bo_mem-> + placement & TTM_PL_FLAG_CACHED) ? PSB_MMU_CACHED_MEMORY : 0; + + if (psb_be->mem_type == TTM_PL_TT) { + uint32_t gatt_p_offset = + (psb_be->offset - dev_priv->pg->mmu_gatt_start) + >> PAGE_SHIFT; + + ret = psb_gtt_insert_pages(dev_priv->pg, psb_be->pages, + gatt_p_offset, + psb_be->num_pages, + psb_be->desired_tile_stride, + psb_be->hw_tile_stride, type); + } + + ret = psb_mmu_insert_pages(pd, psb_be->pages, + psb_be->offset, psb_be->num_pages, + psb_be->desired_tile_stride, + psb_be->hw_tile_stride, type); + if (ret) + goto out_err; + + return 0; +out_err: + drm_psb_tbe_unbind(backend); + return ret; + +} + +static void drm_psb_tbe_clear(struct ttm_backend *backend) +{ + struct drm_psb_ttm_backend *psb_be = + container_of(backend, struct drm_psb_ttm_backend, base); + + psb_be->pages = NULL; + return; +} + +static void drm_psb_tbe_destroy(struct ttm_backend *backend) +{ + struct drm_psb_ttm_backend *psb_be = + container_of(backend, struct drm_psb_ttm_backend, base); + + if (backend) + kfree(psb_be); +} + +static struct ttm_backend_func psb_ttm_backend = { + .populate = drm_psb_tbe_populate, + .clear = drm_psb_tbe_clear, + .bind = drm_psb_tbe_bind, + .unbind = drm_psb_tbe_unbind, + .destroy = drm_psb_tbe_destroy, +}; + +static struct ttm_backend *drm_psb_tbe_init(struct ttm_bo_device *bdev) +{ + struct drm_psb_ttm_backend *psb_be; + + psb_be = kzalloc(sizeof(*psb_be), GFP_KERNEL); + if (!psb_be) + return NULL; + psb_be->pages = NULL; + psb_be->base.func = &psb_ttm_backend; + psb_be->base.bdev = bdev; + return &psb_be->base; +} + +static int psb_ttm_io_mem_reserve(struct ttm_bo_device *bdev, + struct ttm_mem_reg *mem) +{ + struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; + struct drm_psb_private *dev_priv = + container_of(bdev, struct drm_psb_private, bdev); + struct psb_gtt *pg = dev_priv->pg; + struct drm_mm_node *mm_node = mem->mm_node; + + mem->bus.addr = NULL; + mem->bus.offset = 0; + mem->bus.size = mem->num_pages << PAGE_SHIFT; + mem->bus.base = 0; + mem->bus.is_iomem = false; + if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE)) + return -EINVAL; + switch (mem->mem_type) { + case TTM_PL_SYSTEM: + /* system memory */ + return 0; + case TTM_PL_TT: + mem->bus.offset = mm_node->start << PAGE_SHIFT; + mem->bus.base = pg->gatt_start; + mem->bus.is_iomem = false; + /* Don't know whether it is IO_MEM, this flag + used in vm_fault handle */ + break; + case DRM_PSB_MEM_MMU: + mem->bus.offset = mm_node->start << PAGE_SHIFT; + mem->bus.base = 0x00000000; + break; + case TTM_PL_CI: + mem->bus.offset = mm_node->start << PAGE_SHIFT; + mem->bus.base = dev_priv->ci_region_start;; + mem->bus.is_iomem = true; + break; + case TTM_PL_RAR: + mem->bus.offset = mm_node->start << PAGE_SHIFT; + mem->bus.base = dev_priv->rar_region_start;; + mem->bus.is_iomem = true; + break; + default: + return -EINVAL; + } + return 0; +} + +static void psb_ttm_io_mem_free(struct ttm_bo_device *bdev, + struct ttm_mem_reg *mem) +{ +} + +/* + * Use this memory type priority if no eviction is needed. + */ +/* +static uint32_t psb_mem_prios[] = { + TTM_PL_CI, + TTM_PL_RAR, + TTM_PL_TT, + DRM_PSB_MEM_MMU, + TTM_PL_SYSTEM +}; +*/ +/* + * Use this memory type priority if need to evict. + */ +/* +static uint32_t psb_busy_prios[] = { + TTM_PL_TT, + TTM_PL_CI, + TTM_PL_RAR, + DRM_PSB_MEM_MMU, + TTM_PL_SYSTEM +}; +*/ +struct ttm_bo_driver psb_ttm_bo_driver = { +/* + .mem_type_prio = psb_mem_prios, + .mem_busy_prio = psb_busy_prios, + .num_mem_type_prio = ARRAY_SIZE(psb_mem_prios), + .num_mem_busy_prio = ARRAY_SIZE(psb_busy_prios), +*/ + .create_ttm_backend_entry = &drm_psb_tbe_init, + .invalidate_caches = &psb_invalidate_caches, + .init_mem_type = &psb_init_mem_type, + .evict_flags = &psb_evict_mask, + .move = &psb_move, + .verify_access = &psb_verify_access, + .sync_obj_signaled = &ttm_fence_sync_obj_signaled, + .sync_obj_wait = &ttm_fence_sync_obj_wait, + .sync_obj_flush = &ttm_fence_sync_obj_flush, + .sync_obj_unref = &ttm_fence_sync_obj_unref, + .sync_obj_ref = &ttm_fence_sync_obj_ref, + .io_mem_reserve = &psb_ttm_io_mem_reserve, + .io_mem_free = &psb_ttm_io_mem_free +}; diff --git a/drivers/staging/gma500/psb_drm.h b/drivers/staging/gma500/psb_drm.h new file mode 100644 index 000000000000..ef5fcd03b346 --- /dev/null +++ b/drivers/staging/gma500/psb_drm.h @@ -0,0 +1,696 @@ +/************************************************************************** + * Copyright (c) 2007, Intel Corporation. + * All Rights Reserved. + * Copyright (c) 2008, Tungsten Graphics Inc. Cedar Park, TX., USA. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + **************************************************************************/ + +#ifndef _PSB_DRM_H_ +#define _PSB_DRM_H_ + +#if defined(__linux__) && !defined(__KERNEL__) +#include +#include +#include "drm_mode.h" +#endif + +#include "psb_ttm_fence_user.h" +#include "psb_ttm_placement_user.h" + +/* + * Menlow/MRST graphics driver package version + * a.b.c.xxxx + * a - Product Family: 5 - Linux + * b - Major Release Version: 0 - non-Gallium (Unbuntu); + * 1 - Gallium (Moblin2) + * c - Hotfix Release + * xxxx - Graphics internal build # + */ +#define PSB_PACKAGE_VERSION "5.3.0.32L.0036" + +#define DRM_PSB_SAREA_MAJOR 0 +#define DRM_PSB_SAREA_MINOR 2 +#define PSB_FIXED_SHIFT 16 + +#define PSB_NUM_PIPE 3 + +/* + * Public memory types. + */ + +#define DRM_PSB_MEM_MMU TTM_PL_PRIV1 +#define DRM_PSB_FLAG_MEM_MMU TTM_PL_FLAG_PRIV1 + +#define TTM_PL_CI TTM_PL_PRIV0 +#define TTM_PL_FLAG_CI TTM_PL_FLAG_PRIV0 + +#define TTM_PL_RAR TTM_PL_PRIV2 +#define TTM_PL_FLAG_RAR TTM_PL_FLAG_PRIV2 + +typedef int32_t psb_fixed; +typedef uint32_t psb_ufixed; + +static inline int32_t psb_int_to_fixed(int a) +{ + return a * (1 << PSB_FIXED_SHIFT); +} + +static inline uint32_t psb_unsigned_to_ufixed(unsigned int a) +{ + return a << PSB_FIXED_SHIFT; +} + +/*Status of the command sent to the gfx device.*/ +typedef enum { + DRM_CMD_SUCCESS, + DRM_CMD_FAILED, + DRM_CMD_HANG +} drm_cmd_status_t; + +struct drm_psb_scanout { + uint32_t buffer_id; /* DRM buffer object ID */ + uint32_t rotation; /* Rotation as in RR_rotation definitions */ + uint32_t stride; /* Buffer stride in bytes */ + uint32_t depth; /* Buffer depth in bits (NOT) bpp */ + uint32_t width; /* Buffer width in pixels */ + uint32_t height; /* Buffer height in lines */ + int32_t transform[3][3]; /* Buffer composite transform */ + /* (scaling, rot, reflect) */ +}; + +#define DRM_PSB_SAREA_OWNERS 16 +#define DRM_PSB_SAREA_OWNER_2D 0 +#define DRM_PSB_SAREA_OWNER_3D 1 + +#define DRM_PSB_SAREA_SCANOUTS 3 + +struct drm_psb_sarea { + /* Track changes of this data structure */ + + uint32_t major; + uint32_t minor; + + /* Last context to touch part of hw */ + uint32_t ctx_owners[DRM_PSB_SAREA_OWNERS]; + + /* Definition of front- and rotated buffers */ + uint32_t num_scanouts; + struct drm_psb_scanout scanouts[DRM_PSB_SAREA_SCANOUTS]; + + int planeA_x; + int planeA_y; + int planeA_w; + int planeA_h; + int planeB_x; + int planeB_y; + int planeB_w; + int planeB_h; + /* Number of active scanouts */ + uint32_t num_active_scanouts; +}; + +#define PSB_RELOC_MAGIC 0x67676767 +#define PSB_RELOC_SHIFT_MASK 0x0000FFFF +#define PSB_RELOC_SHIFT_SHIFT 0 +#define PSB_RELOC_ALSHIFT_MASK 0xFFFF0000 +#define PSB_RELOC_ALSHIFT_SHIFT 16 + +#define PSB_RELOC_OP_OFFSET 0 /* Offset of the indicated + * buffer + */ + +struct drm_psb_reloc { + uint32_t reloc_op; + uint32_t where; /* offset in destination buffer */ + uint32_t buffer; /* Buffer reloc applies to */ + uint32_t mask; /* Destination format: */ + uint32_t shift; /* Destination format: */ + uint32_t pre_add; /* Destination format: */ + uint32_t background; /* Destination add */ + uint32_t dst_buffer; /* Destination buffer. Index into buffer_list */ + uint32_t arg0; /* Reloc-op dependant */ + uint32_t arg1; +}; + + +#define PSB_GPU_ACCESS_READ (1ULL << 32) +#define PSB_GPU_ACCESS_WRITE (1ULL << 33) +#define PSB_GPU_ACCESS_MASK (PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE) + +#define PSB_BO_FLAG_COMMAND (1ULL << 52) + +#define PSB_ENGINE_2D 0 +#define PSB_ENGINE_VIDEO 1 +#define LNC_ENGINE_ENCODE 5 + +/* + * For this fence class we have a couple of + * fence types. + */ + +#define _PSB_FENCE_EXE_SHIFT 0 +#define _PSB_FENCE_FEEDBACK_SHIFT 4 + +#define _PSB_FENCE_TYPE_EXE (1 << _PSB_FENCE_EXE_SHIFT) +#define _PSB_FENCE_TYPE_FEEDBACK (1 << _PSB_FENCE_FEEDBACK_SHIFT) + +#define PSB_NUM_ENGINES 6 + + +#define PSB_FEEDBACK_OP_VISTEST (1 << 0) + +struct drm_psb_extension_rep { + int32_t exists; + uint32_t driver_ioctl_offset; + uint32_t sarea_offset; + uint32_t major; + uint32_t minor; + uint32_t pl; +}; + +#define DRM_PSB_EXT_NAME_LEN 128 + +union drm_psb_extension_arg { + char extension[DRM_PSB_EXT_NAME_LEN]; + struct drm_psb_extension_rep rep; +}; + +struct psb_validate_req { + uint64_t set_flags; + uint64_t clear_flags; + uint64_t next; + uint64_t presumed_gpu_offset; + uint32_t buffer_handle; + uint32_t presumed_flags; + uint32_t group; + uint32_t pad64; +}; + +struct psb_validate_rep { + uint64_t gpu_offset; + uint32_t placement; + uint32_t fence_type_mask; +}; + +#define PSB_USE_PRESUMED (1 << 0) + +struct psb_validate_arg { + int handled; + int ret; + union { + struct psb_validate_req req; + struct psb_validate_rep rep; + } d; +}; + + +#define DRM_PSB_FENCE_NO_USER (1 << 0) + +struct psb_ttm_fence_rep { + uint32_t handle; + uint32_t fence_class; + uint32_t fence_type; + uint32_t signaled_types; + uint32_t error; +}; + +typedef struct drm_psb_cmdbuf_arg { + uint64_t buffer_list; /* List of buffers to validate */ + uint64_t clip_rects; /* See i915 counterpart */ + uint64_t scene_arg; + uint64_t fence_arg; + + uint32_t ta_flags; + + uint32_t ta_handle; /* TA reg-value pairs */ + uint32_t ta_offset; + uint32_t ta_size; + + uint32_t oom_handle; + uint32_t oom_offset; + uint32_t oom_size; + + uint32_t cmdbuf_handle; /* 2D Command buffer object or, */ + uint32_t cmdbuf_offset; /* rasterizer reg-value pairs */ + uint32_t cmdbuf_size; + + uint32_t reloc_handle; /* Reloc buffer object */ + uint32_t reloc_offset; + uint32_t num_relocs; + + int32_t damage; /* Damage front buffer with cliprects */ + /* Not implemented yet */ + uint32_t fence_flags; + uint32_t engine; + + /* + * Feedback; + */ + + uint32_t feedback_ops; + uint32_t feedback_handle; + uint32_t feedback_offset; + uint32_t feedback_breakpoints; + uint32_t feedback_size; +} drm_psb_cmdbuf_arg_t; + +typedef struct drm_psb_pageflip_arg { + uint32_t flip_offset; + uint32_t stride; +} drm_psb_pageflip_arg_t; + +typedef enum { + LNC_VIDEO_DEVICE_INFO, + LNC_VIDEO_GETPARAM_RAR_INFO, + LNC_VIDEO_GETPARAM_CI_INFO, + LNC_VIDEO_GETPARAM_RAR_HANDLER_OFFSET, + LNC_VIDEO_FRAME_SKIP, + IMG_VIDEO_DECODE_STATUS, + IMG_VIDEO_NEW_CONTEXT, + IMG_VIDEO_RM_CONTEXT, + IMG_VIDEO_MB_ERROR +} lnc_getparam_key_t; + +struct drm_lnc_video_getparam_arg { + lnc_getparam_key_t key; + uint64_t arg; /* argument pointer */ + uint64_t value; /* feed back pointer */ +}; + + +/* + * Feedback components: + */ + +/* + * Vistest component. The number of these in the feedback buffer + * equals the number of vistest breakpoints + 1. + * This is currently the only feedback component. + */ + +struct drm_psb_vistest { + uint32_t vt[8]; +}; + +struct drm_psb_sizes_arg { + uint32_t ta_mem_size; + uint32_t mmu_size; + uint32_t pds_size; + uint32_t rastgeom_size; + uint32_t tt_size; + uint32_t vram_size; +}; + +struct drm_psb_hist_status_arg { + uint32_t buf[32]; +}; + +struct drm_psb_dpst_lut_arg { + uint8_t lut[256]; + int output_id; +}; + +struct mrst_timing_info { + uint16_t pixel_clock; + uint8_t hactive_lo; + uint8_t hblank_lo; + uint8_t hblank_hi:4; + uint8_t hactive_hi:4; + uint8_t vactive_lo; + uint8_t vblank_lo; + uint8_t vblank_hi:4; + uint8_t vactive_hi:4; + uint8_t hsync_offset_lo; + uint8_t hsync_pulse_width_lo; + uint8_t vsync_pulse_width_lo:4; + uint8_t vsync_offset_lo:4; + uint8_t vsync_pulse_width_hi:2; + uint8_t vsync_offset_hi:2; + uint8_t hsync_pulse_width_hi:2; + uint8_t hsync_offset_hi:2; + uint8_t width_mm_lo; + uint8_t height_mm_lo; + uint8_t height_mm_hi:4; + uint8_t width_mm_hi:4; + uint8_t hborder; + uint8_t vborder; + uint8_t unknown0:1; + uint8_t hsync_positive:1; + uint8_t vsync_positive:1; + uint8_t separate_sync:2; + uint8_t stereo:1; + uint8_t unknown6:1; + uint8_t interlaced:1; +} __attribute__((packed)); + +struct gct_r10_timing_info { + uint16_t pixel_clock; + uint32_t hactive_lo:8; + uint32_t hactive_hi:4; + uint32_t hblank_lo:8; + uint32_t hblank_hi:4; + uint32_t hsync_offset_lo:8; + uint16_t hsync_offset_hi:2; + uint16_t hsync_pulse_width_lo:8; + uint16_t hsync_pulse_width_hi:2; + uint16_t hsync_positive:1; + uint16_t rsvd_1:3; + uint8_t vactive_lo:8; + uint16_t vactive_hi:4; + uint16_t vblank_lo:8; + uint16_t vblank_hi:4; + uint16_t vsync_offset_lo:4; + uint16_t vsync_offset_hi:2; + uint16_t vsync_pulse_width_lo:4; + uint16_t vsync_pulse_width_hi:2; + uint16_t vsync_positive:1; + uint16_t rsvd_2:3; +} __attribute__((packed)); + +struct mrst_panel_descriptor_v1{ + uint32_t Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */ + /* 0x61190 if MIPI */ + uint32_t Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/ + uint32_t Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/ + uint32_t Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 dword */ + /* Register 0x61210 */ + struct mrst_timing_info DTD;/*18 bytes, Standard definition */ + uint16_t Panel_Backlight_Inverter_Descriptor;/* 16 bits, as follows */ + /* Bit 0, Frequency, 15 bits,0 - 32767Hz */ + /* Bit 15, Polarity, 1 bit, 0: Normal, 1: Inverted */ + uint16_t Panel_MIPI_Display_Descriptor; + /*16 bits, Defined as follows: */ + /* if MIPI, 0x0000 if LVDS */ + /* Bit 0, Type, 2 bits, */ + /* 0: Type-1, */ + /* 1: Type-2, */ + /* 2: Type-3, */ + /* 3: Type-4 */ + /* Bit 2, Pixel Format, 4 bits */ + /* Bit0: 16bpp (not supported in LNC), */ + /* Bit1: 18bpp loosely packed, */ + /* Bit2: 18bpp packed, */ + /* Bit3: 24bpp */ + /* Bit 6, Reserved, 2 bits, 00b */ + /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */ + /* Bit 14, Reserved, 2 bits, 00b */ +} __attribute__ ((packed)); + +struct mrst_panel_descriptor_v2{ + uint32_t Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */ + /* 0x61190 if MIPI */ + uint32_t Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/ + uint32_t Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/ + uint8_t Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 byte */ + /* Register 0x61210 */ + struct mrst_timing_info DTD;/*18 bytes, Standard definition */ + uint16_t Panel_Backlight_Inverter_Descriptor;/*16 bits, as follows*/ + /*Bit 0, Frequency, 16 bits, 0 - 32767Hz*/ + uint8_t Panel_Initial_Brightness;/* [7:0] 0 - 100% */ + /*Bit 7, Polarity, 1 bit,0: Normal, 1: Inverted*/ + uint16_t Panel_MIPI_Display_Descriptor; + /*16 bits, Defined as follows: */ + /* if MIPI, 0x0000 if LVDS */ + /* Bit 0, Type, 2 bits, */ + /* 0: Type-1, */ + /* 1: Type-2, */ + /* 2: Type-3, */ + /* 3: Type-4 */ + /* Bit 2, Pixel Format, 4 bits */ + /* Bit0: 16bpp (not supported in LNC), */ + /* Bit1: 18bpp loosely packed, */ + /* Bit2: 18bpp packed, */ + /* Bit3: 24bpp */ + /* Bit 6, Reserved, 2 bits, 00b */ + /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */ + /* Bit 14, Reserved, 2 bits, 00b */ +} __attribute__ ((packed)); + +union mrst_panel_rx{ + struct{ + uint16_t NumberOfLanes:2; /*Num of Lanes, 2 bits,0 = 1 lane,*/ + /* 1 = 2 lanes, 2 = 3 lanes, 3 = 4 lanes. */ + uint16_t MaxLaneFreq:3; /* 0: 100MHz, 1: 200MHz, 2: 300MHz, */ + /*3: 400MHz, 4: 500MHz, 5: 600MHz, 6: 700MHz, 7: 800MHz.*/ + uint16_t SupportedVideoTransferMode:2; /*0: Non-burst only */ + /* 1: Burst and non-burst */ + /* 2/3: Reserved */ + uint16_t HSClkBehavior:1; /*0: Continuous, 1: Non-continuous*/ + uint16_t DuoDisplaySupport:1; /*1 bit,0: No, 1: Yes*/ + uint16_t ECC_ChecksumCapabilities:1;/*1 bit,0: No, 1: Yes*/ + uint16_t BidirectionalCommunication:1;/*1 bit,0: No, 1: Yes */ + uint16_t Rsvd:5;/*5 bits,00000b */ + } panelrx; + uint16_t panel_receiver; +} __attribute__ ((packed)); + +struct gct_ioctl_arg{ + uint8_t bpi; /* boot panel index, number of panel used during boot */ + uint8_t pt; /* panel type, 4 bit field, 0=lvds, 1=mipi */ + struct mrst_timing_info DTD; /* timing info for the selected panel */ + uint32_t Panel_Port_Control; + uint32_t PP_On_Sequencing;/*1 dword,Register 0x61208,*/ + uint32_t PP_Off_Sequencing;/*1 dword,Register 0x6120C,*/ + uint32_t PP_Cycle_Delay; + uint16_t Panel_Backlight_Inverter_Descriptor; + uint16_t Panel_MIPI_Display_Descriptor; +} __attribute__ ((packed)); + +struct mrst_vbt{ + char Signature[4]; /*4 bytes,"$GCT" */ + uint8_t Revision; /*1 byte */ + uint8_t Size; /*1 byte */ + uint8_t Checksum; /*1 byte,Calculated*/ + void *mrst_gct; +} __attribute__ ((packed)); + +struct mrst_gct_v1{ /* expect this table to change per customer request*/ + union{ /*8 bits,Defined as follows: */ + struct{ + uint8_t PanelType:4; /*4 bits, Bit field for panels*/ + /* 0 - 3: 0 = LVDS, 1 = MIPI*/ + /*2 bits,Specifies which of the*/ + uint8_t BootPanelIndex:2; + /* 4 panels to use by default*/ + uint8_t BootMIPI_DSI_RxIndex:2;/*Specifies which of*/ + /* the 4 MIPI DSI receivers to use*/ + } PD; + uint8_t PanelDescriptor; + }; + struct mrst_panel_descriptor_v1 panel[4];/*panel descrs,38 bytes each*/ + union mrst_panel_rx panelrx[4]; /* panel receivers*/ +} __attribute__ ((packed)); + +struct mrst_gct_v2{ /* expect this table to change per customer request*/ + union{ /*8 bits,Defined as follows: */ + struct{ + uint8_t PanelType:4; /*4 bits, Bit field for panels*/ + /* 0 - 3: 0 = LVDS, 1 = MIPI*/ + /*2 bits,Specifies which of the*/ + uint8_t BootPanelIndex:2; + /* 4 panels to use by default*/ + uint8_t BootMIPI_DSI_RxIndex:2;/*Specifies which of*/ + /* the 4 MIPI DSI receivers to use*/ + } PD; + uint8_t PanelDescriptor; + }; + struct mrst_panel_descriptor_v2 panel[4];/*panel descrs,38 bytes each*/ + union mrst_panel_rx panelrx[4]; /* panel receivers*/ +} __attribute__ ((packed)); + +#define PSB_DC_CRTC_SAVE 0x01 +#define PSB_DC_CRTC_RESTORE 0x02 +#define PSB_DC_OUTPUT_SAVE 0x04 +#define PSB_DC_OUTPUT_RESTORE 0x08 +#define PSB_DC_CRTC_MASK 0x03 +#define PSB_DC_OUTPUT_MASK 0x0C + +struct drm_psb_dc_state_arg { + uint32_t flags; + uint32_t obj_id; +}; + +struct drm_psb_mode_operation_arg { + uint32_t obj_id; + uint16_t operation; + struct drm_mode_modeinfo mode; + void *data; +}; + +struct drm_psb_stolen_memory_arg { + uint32_t base; + uint32_t size; +}; + +/*Display Register Bits*/ +#define REGRWBITS_PFIT_CONTROLS (1 << 0) +#define REGRWBITS_PFIT_AUTOSCALE_RATIOS (1 << 1) +#define REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS (1 << 2) +#define REGRWBITS_PIPEASRC (1 << 3) +#define REGRWBITS_PIPEBSRC (1 << 4) +#define REGRWBITS_VTOTAL_A (1 << 5) +#define REGRWBITS_VTOTAL_B (1 << 6) +#define REGRWBITS_DSPACNTR (1 << 8) +#define REGRWBITS_DSPBCNTR (1 << 9) +#define REGRWBITS_DSPCCNTR (1 << 10) + +/*Overlay Register Bits*/ +#define OV_REGRWBITS_OVADD (1 << 0) +#define OV_REGRWBITS_OGAM_ALL (1 << 1) + +#define OVC_REGRWBITS_OVADD (1 << 2) +#define OVC_REGRWBITS_OGAM_ALL (1 << 3) + +struct drm_psb_register_rw_arg { + uint32_t b_force_hw_on; + + uint32_t display_read_mask; + uint32_t display_write_mask; + + struct { + uint32_t pfit_controls; + uint32_t pfit_autoscale_ratios; + uint32_t pfit_programmed_scale_ratios; + uint32_t pipeasrc; + uint32_t pipebsrc; + uint32_t vtotal_a; + uint32_t vtotal_b; + } display; + + uint32_t overlay_read_mask; + uint32_t overlay_write_mask; + + struct { + uint32_t OVADD; + uint32_t OGAMC0; + uint32_t OGAMC1; + uint32_t OGAMC2; + uint32_t OGAMC3; + uint32_t OGAMC4; + uint32_t OGAMC5; + uint32_t IEP_ENABLED; + uint32_t IEP_BLE_MINMAX; + uint32_t IEP_BSSCC_CONTROL; + uint32_t b_wait_vblank; + } overlay; + + uint32_t sprite_enable_mask; + uint32_t sprite_disable_mask; + + struct { + uint32_t dspa_control; + uint32_t dspa_key_value; + uint32_t dspa_key_mask; + uint32_t dspc_control; + uint32_t dspc_stride; + uint32_t dspc_position; + uint32_t dspc_linear_offset; + uint32_t dspc_size; + uint32_t dspc_surface; + } sprite; + + uint32_t subpicture_enable_mask; + uint32_t subpicture_disable_mask; +}; + +struct psb_gtt_mapping_arg { + void *hKernelMemInfo; + uint32_t offset_pages; +}; + +struct drm_psb_getpageaddrs_arg { + uint32_t handle; + unsigned long *page_addrs; + unsigned long gtt_offset; +}; + +/* Controlling the kernel modesetting buffers */ + +#define DRM_PSB_KMS_OFF 0x00 +#define DRM_PSB_KMS_ON 0x01 +#define DRM_PSB_VT_LEAVE 0x02 +#define DRM_PSB_VT_ENTER 0x03 +#define DRM_PSB_EXTENSION 0x06 +#define DRM_PSB_SIZES 0x07 +#define DRM_PSB_FUSE_REG 0x08 +#define DRM_PSB_VBT 0x09 +#define DRM_PSB_DC_STATE 0x0A +#define DRM_PSB_ADB 0x0B +#define DRM_PSB_MODE_OPERATION 0x0C +#define DRM_PSB_STOLEN_MEMORY 0x0D +#define DRM_PSB_REGISTER_RW 0x0E +#define DRM_PSB_GTT_MAP 0x0F +#define DRM_PSB_GTT_UNMAP 0x10 +#define DRM_PSB_GETPAGEADDRS 0x11 +/** + * NOTE: Add new commands here, but increment + * the values below and increment their + * corresponding defines where they're + * defined elsewhere. + */ +#define DRM_PVR_RESERVED1 0x12 +#define DRM_PVR_RESERVED2 0x13 +#define DRM_PVR_RESERVED3 0x14 +#define DRM_PVR_RESERVED4 0x15 +#define DRM_PVR_RESERVED5 0x16 + +#define DRM_PSB_HIST_ENABLE 0x17 +#define DRM_PSB_HIST_STATUS 0x18 +#define DRM_PSB_UPDATE_GUARD 0x19 +#define DRM_PSB_INIT_COMM 0x1A +#define DRM_PSB_DPST 0x1B +#define DRM_PSB_GAMMA 0x1C +#define DRM_PSB_DPST_BL 0x1D + +#define DRM_PVR_RESERVED6 0x1E + +#define DRM_PSB_GET_PIPE_FROM_CRTC_ID 0x1F +#define DRM_PSB_DPU_QUERY 0x20 +#define DRM_PSB_DPU_DSR_ON 0x21 +#define DRM_PSB_DPU_DSR_OFF 0x22 + +#define DRM_PSB_DSR_ENABLE 0xfffffffe +#define DRM_PSB_DSR_DISABLE 0xffffffff + +struct psb_drm_dpu_rect { + int x, y; + int width, height; +}; + +struct drm_psb_drv_dsr_off_arg { + int screen; + struct psb_drm_dpu_rect damage_rect; +}; + + +struct drm_psb_dev_info_arg { + uint32_t num_use_attribute_registers; +}; +#define DRM_PSB_DEVINFO 0x01 + +#define PSB_MODE_OPERATION_MODE_VALID 0x01 +#define PSB_MODE_OPERATION_SET_DC_BASE 0x02 + +struct drm_psb_get_pipe_from_crtc_id_arg { + /** ID of CRTC being requested **/ + uint32_t crtc_id; + + /** pipe of requested CRTC **/ + uint32_t pipe; +}; + +#endif diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c new file mode 100644 index 000000000000..2fe09c828a9b --- /dev/null +++ b/drivers/staging/gma500/psb_drv.c @@ -0,0 +1,1677 @@ +/************************************************************************** + * Copyright (c) 2007, Intel Corporation. + * All Rights Reserved. + * Copyright (c) 2008, Tungsten Graphics, Inc. Cedar Park, TX., USA. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + **************************************************************************/ + +#include +#include +#include "psb_drm.h" +#include "psb_drv.h" +#include "psb_fb.h" +#include "psb_reg.h" +#include "psb_intel_reg.h" +#include "psb_intel_bios.h" +#include +#include "psb_powermgmt.h" +#include +#include +#include +#include + +int drm_psb_debug; +static int drm_psb_trap_pagefaults; + +int drm_psb_disable_vsync = 1; +int drm_psb_no_fb; +int drm_psb_force_pipeb; +int drm_idle_check_interval = 5; +int gfxrtdelay = 2 * 1000; + +static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent); + +MODULE_PARM_DESC(debug, "Enable debug output"); +MODULE_PARM_DESC(no_fb, "Disable FBdev"); +MODULE_PARM_DESC(trap_pagefaults, "Error and reset on MMU pagefaults"); +MODULE_PARM_DESC(disable_vsync, "Disable vsync interrupts"); +MODULE_PARM_DESC(force_pipeb, "Forces PIPEB to become primary fb"); +MODULE_PARM_DESC(ta_mem_size, "TA memory size in kiB"); +MODULE_PARM_DESC(ospm, "switch for ospm support"); +MODULE_PARM_DESC(rtpm, "Specifies Runtime PM delay for GFX"); +MODULE_PARM_DESC(hdmi_edid, "EDID info for HDMI monitor"); +module_param_named(debug, drm_psb_debug, int, 0600); +module_param_named(no_fb, drm_psb_no_fb, int, 0600); +module_param_named(trap_pagefaults, drm_psb_trap_pagefaults, int, 0600); +module_param_named(force_pipeb, drm_psb_force_pipeb, int, 0600); +module_param_named(rtpm, gfxrtdelay, int, 0600); + + +static struct pci_device_id pciidlist[] = { + { 0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8108 }, + { 0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8109 }, + { 0, 0, 0} +}; +MODULE_DEVICE_TABLE(pci, pciidlist); + +/* + * Standard IOCTLs. + */ + +#define DRM_IOCTL_PSB_KMS_OFF \ + DRM_IO(DRM_PSB_KMS_OFF + DRM_COMMAND_BASE) +#define DRM_IOCTL_PSB_KMS_ON \ + DRM_IO(DRM_PSB_KMS_ON + DRM_COMMAND_BASE) +#define DRM_IOCTL_PSB_VT_LEAVE \ + DRM_IO(DRM_PSB_VT_LEAVE + DRM_COMMAND_BASE) +#define DRM_IOCTL_PSB_VT_ENTER \ + DRM_IO(DRM_PSB_VT_ENTER + DRM_COMMAND_BASE) +#define DRM_IOCTL_PSB_SIZES \ + DRM_IOR(DRM_PSB_SIZES + DRM_COMMAND_BASE, \ + struct drm_psb_sizes_arg) +#define DRM_IOCTL_PSB_FUSE_REG \ + DRM_IOWR(DRM_PSB_FUSE_REG + DRM_COMMAND_BASE, uint32_t) +#define DRM_IOCTL_PSB_DC_STATE \ + DRM_IOW(DRM_PSB_DC_STATE + DRM_COMMAND_BASE, \ + struct drm_psb_dc_state_arg) +#define DRM_IOCTL_PSB_ADB \ + DRM_IOWR(DRM_PSB_ADB + DRM_COMMAND_BASE, uint32_t) +#define DRM_IOCTL_PSB_MODE_OPERATION \ + DRM_IOWR(DRM_PSB_MODE_OPERATION + DRM_COMMAND_BASE, \ + struct drm_psb_mode_operation_arg) +#define DRM_IOCTL_PSB_STOLEN_MEMORY \ + DRM_IOWR(DRM_PSB_STOLEN_MEMORY + DRM_COMMAND_BASE, \ + struct drm_psb_stolen_memory_arg) +#define DRM_IOCTL_PSB_REGISTER_RW \ + DRM_IOWR(DRM_PSB_REGISTER_RW + DRM_COMMAND_BASE, \ + struct drm_psb_register_rw_arg) +#define DRM_IOCTL_PSB_GTT_MAP \ + DRM_IOWR(DRM_PSB_GTT_MAP + DRM_COMMAND_BASE, \ + struct psb_gtt_mapping_arg) +#define DRM_IOCTL_PSB_GTT_UNMAP \ + DRM_IOW(DRM_PSB_GTT_UNMAP + DRM_COMMAND_BASE, \ + struct psb_gtt_mapping_arg) +#define DRM_IOCTL_PSB_GETPAGEADDRS \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_GETPAGEADDRS,\ + struct drm_psb_getpageaddrs_arg) +#define DRM_IOCTL_PSB_HIST_ENABLE \ + DRM_IOWR(DRM_PSB_HIST_ENABLE + DRM_COMMAND_BASE, \ + uint32_t) +#define DRM_IOCTL_PSB_HIST_STATUS \ + DRM_IOWR(DRM_PSB_HIST_STATUS + DRM_COMMAND_BASE, \ + struct drm_psb_hist_status_arg) +#define DRM_IOCTL_PSB_UPDATE_GUARD \ + DRM_IOWR(DRM_PSB_UPDATE_GUARD + DRM_COMMAND_BASE, \ + uint32_t) +#define DRM_IOCTL_PSB_DPST \ + DRM_IOWR(DRM_PSB_DPST + DRM_COMMAND_BASE, \ + uint32_t) +#define DRM_IOCTL_PSB_GAMMA \ + DRM_IOWR(DRM_PSB_GAMMA + DRM_COMMAND_BASE, \ + struct drm_psb_dpst_lut_arg) +#define DRM_IOCTL_PSB_DPST_BL \ + DRM_IOWR(DRM_PSB_DPST_BL + DRM_COMMAND_BASE, \ + uint32_t) +#define DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID \ + DRM_IOWR(DRM_PSB_GET_PIPE_FROM_CRTC_ID + DRM_COMMAND_BASE, \ + struct drm_psb_get_pipe_from_crtc_id_arg) + +/* + * TTM execbuf extension. + */ +#define DRM_PSB_CMDBUF (DRM_PSB_DPU_DSR_OFF + 1) + +#define DRM_PSB_SCENE_UNREF (DRM_PSB_CMDBUF + 1) +#define DRM_IOCTL_PSB_CMDBUF \ + DRM_IOW(DRM_PSB_CMDBUF + DRM_COMMAND_BASE, \ + struct drm_psb_cmdbuf_arg) +#define DRM_IOCTL_PSB_SCENE_UNREF \ + DRM_IOW(DRM_PSB_SCENE_UNREF + DRM_COMMAND_BASE, \ + struct drm_psb_scene) +#define DRM_IOCTL_PSB_KMS_OFF DRM_IO(DRM_PSB_KMS_OFF + DRM_COMMAND_BASE) +#define DRM_IOCTL_PSB_KMS_ON DRM_IO(DRM_PSB_KMS_ON + DRM_COMMAND_BASE) +/* + * TTM placement user extension. + */ + +#define DRM_PSB_PLACEMENT_OFFSET (DRM_PSB_SCENE_UNREF + 1) + +#define DRM_PSB_TTM_PL_CREATE (TTM_PL_CREATE + DRM_PSB_PLACEMENT_OFFSET) +#define DRM_PSB_TTM_PL_REFERENCE (TTM_PL_REFERENCE + DRM_PSB_PLACEMENT_OFFSET) +#define DRM_PSB_TTM_PL_UNREF (TTM_PL_UNREF + DRM_PSB_PLACEMENT_OFFSET) +#define DRM_PSB_TTM_PL_SYNCCPU (TTM_PL_SYNCCPU + DRM_PSB_PLACEMENT_OFFSET) +#define DRM_PSB_TTM_PL_WAITIDLE (TTM_PL_WAITIDLE + DRM_PSB_PLACEMENT_OFFSET) +#define DRM_PSB_TTM_PL_SETSTATUS (TTM_PL_SETSTATUS + DRM_PSB_PLACEMENT_OFFSET) +#define DRM_PSB_TTM_PL_CREATE_UB (TTM_PL_CREATE_UB + DRM_PSB_PLACEMENT_OFFSET) + +/* + * TTM fence extension. + */ + +#define DRM_PSB_FENCE_OFFSET (DRM_PSB_TTM_PL_CREATE_UB + 1) +#define DRM_PSB_TTM_FENCE_SIGNALED (TTM_FENCE_SIGNALED + DRM_PSB_FENCE_OFFSET) +#define DRM_PSB_TTM_FENCE_FINISH (TTM_FENCE_FINISH + DRM_PSB_FENCE_OFFSET) +#define DRM_PSB_TTM_FENCE_UNREF (TTM_FENCE_UNREF + DRM_PSB_FENCE_OFFSET) + +#define DRM_PSB_FLIP (DRM_PSB_TTM_FENCE_UNREF + 1) /*20*/ +/* PSB video extension */ +#define DRM_LNC_VIDEO_GETPARAM (DRM_PSB_FLIP + 1) + +#define DRM_IOCTL_PSB_TTM_PL_CREATE \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_CREATE,\ + union ttm_pl_create_arg) +#define DRM_IOCTL_PSB_TTM_PL_REFERENCE \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_REFERENCE,\ + union ttm_pl_reference_arg) +#define DRM_IOCTL_PSB_TTM_PL_UNREF \ + DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_UNREF,\ + struct ttm_pl_reference_req) +#define DRM_IOCTL_PSB_TTM_PL_SYNCCPU \ + DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_SYNCCPU,\ + struct ttm_pl_synccpu_arg) +#define DRM_IOCTL_PSB_TTM_PL_WAITIDLE \ + DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_WAITIDLE,\ + struct ttm_pl_waitidle_arg) +#define DRM_IOCTL_PSB_TTM_PL_SETSTATUS \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_SETSTATUS,\ + union ttm_pl_setstatus_arg) +#define DRM_IOCTL_PSB_TTM_PL_CREATE_UB \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_CREATE_UB,\ + union ttm_pl_create_ub_arg) +#define DRM_IOCTL_PSB_TTM_FENCE_SIGNALED \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_FENCE_SIGNALED, \ + union ttm_fence_signaled_arg) +#define DRM_IOCTL_PSB_TTM_FENCE_FINISH \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_FENCE_FINISH, \ + union ttm_fence_finish_arg) +#define DRM_IOCTL_PSB_TTM_FENCE_UNREF \ + DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_FENCE_UNREF, \ + struct ttm_fence_unref_arg) +#define DRM_IOCTL_PSB_FLIP \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_FLIP, \ + struct drm_psb_pageflip_arg) +#define DRM_IOCTL_LNC_VIDEO_GETPARAM \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_LNC_VIDEO_GETPARAM, \ + struct drm_lnc_video_getparam_arg) + +static int psb_vt_leave_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +static int psb_vt_enter_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +static int psb_sizes_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +static int psb_dc_state_ioctl(struct drm_device *dev, void * data, + struct drm_file *file_priv); +static int psb_adb_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +static int psb_mode_operation_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +static int psb_register_rw_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +static int psb_dpst_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +static int psb_gamma_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +#define PSB_IOCTL_DEF(ioctl, func, flags) \ + [DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func} + +static struct drm_ioctl_desc psb_ioctls[] = { + PSB_IOCTL_DEF(DRM_IOCTL_PSB_KMS_OFF, psbfb_kms_off_ioctl, + DRM_ROOT_ONLY), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_KMS_ON, + psbfb_kms_on_ioctl, + DRM_ROOT_ONLY), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_VT_LEAVE, psb_vt_leave_ioctl, + DRM_ROOT_ONLY), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_VT_ENTER, + psb_vt_enter_ioctl, + DRM_ROOT_ONLY), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_SIZES, psb_sizes_ioctl, DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_DC_STATE, psb_dc_state_ioctl, DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_ADB, psb_adb_ioctl, DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_MODE_OPERATION, psb_mode_operation_ioctl, + DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_STOLEN_MEMORY, psb_stolen_memory_ioctl, + DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_REGISTER_RW, psb_register_rw_ioctl, + DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_GTT_MAP, + psb_gtt_map_meminfo_ioctl, + DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_GTT_UNMAP, + psb_gtt_unmap_meminfo_ioctl, + DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_GETPAGEADDRS, + psb_getpageaddrs_ioctl, + DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST, psb_dpst_ioctl, DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_GAMMA, psb_gamma_ioctl, DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST_BL, psb_dpst_bl_ioctl, DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID, + psb_intel_get_pipe_from_crtc_id, 0), + /*to be removed later*/ + /*PSB_IOCTL_DEF(DRM_IOCTL_PSB_SCENE_UNREF, drm_psb_scene_unref_ioctl, + DRM_AUTH),*/ + + PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_CREATE, psb_pl_create_ioctl, + DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_REFERENCE, psb_pl_reference_ioctl, + DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_UNREF, psb_pl_unref_ioctl, + DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_SYNCCPU, psb_pl_synccpu_ioctl, + DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_WAITIDLE, psb_pl_waitidle_ioctl, + DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_SETSTATUS, psb_pl_setstatus_ioctl, + DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_CREATE_UB, psb_pl_ub_create_ioctl, + DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_FENCE_SIGNALED, + psb_fence_signaled_ioctl, DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_FENCE_FINISH, psb_fence_finish_ioctl, + DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_FENCE_UNREF, psb_fence_unref_ioctl, + DRM_AUTH), +}; + +static void psb_set_uopt(struct drm_psb_uopt *uopt) +{ + return; +} + +static void psb_lastclose(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) dev->dev_private; + + return; + + if (!dev->dev_private) + return; + + mutex_lock(&dev_priv->cmdbuf_mutex); + if (dev_priv->context.buffers) { + vfree(dev_priv->context.buffers); + dev_priv->context.buffers = NULL; + } + mutex_unlock(&dev_priv->cmdbuf_mutex); +} + +static void psb_do_takedown(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) dev->dev_private; + struct ttm_bo_device *bdev = &dev_priv->bdev; + + + if (dev_priv->have_mem_mmu) { + ttm_bo_clean_mm(bdev, DRM_PSB_MEM_MMU); + dev_priv->have_mem_mmu = 0; + } + + if (dev_priv->have_tt) { + ttm_bo_clean_mm(bdev, TTM_PL_TT); + dev_priv->have_tt = 0; + } + + if (dev_priv->have_camera) { + ttm_bo_clean_mm(bdev, TTM_PL_CI); + dev_priv->have_camera = 0; + } + if (dev_priv->have_rar) { + ttm_bo_clean_mm(bdev, TTM_PL_RAR); + dev_priv->have_rar = 0; + } + +} + +static void psb_get_core_freq(struct drm_device *dev) +{ + uint32_t clock; + struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); + struct drm_psb_private *dev_priv = dev->dev_private; + + /*pci_write_config_dword(pci_root, 0xD4, 0x00C32004);*/ + /*pci_write_config_dword(pci_root, 0xD0, 0xE0033000);*/ + + pci_write_config_dword(pci_root, 0xD0, 0xD0050300); + pci_read_config_dword(pci_root, 0xD4, &clock); + pci_dev_put(pci_root); + + switch (clock & 0x07) { + case 0: + dev_priv->core_freq = 100; + break; + case 1: + dev_priv->core_freq = 133; + break; + case 2: + dev_priv->core_freq = 150; + break; + case 3: + dev_priv->core_freq = 178; + break; + case 4: + dev_priv->core_freq = 200; + break; + case 5: + case 6: + case 7: + dev_priv->core_freq = 266; + default: + dev_priv->core_freq = 0; + } +} + +#define FB_REG06 0xD0810600 +#define FB_TOPAZ_DISABLE BIT0 +#define FB_MIPI_DISABLE BIT11 +#define FB_REG09 0xD0810900 +#define FB_SKU_MASK (BIT12|BIT13|BIT14) +#define FB_SKU_SHIFT 12 +#define FB_SKU_100 0 +#define FB_SKU_100L 1 +#define FB_SKU_83 2 +#if 1 /* FIXME remove it after PO */ +#define FB_GFX_CLK_DIVIDE_MASK (BIT20|BIT21|BIT22) +#define FB_GFX_CLK_DIVIDE_SHIFT 20 +#define FB_VED_CLK_DIVIDE_MASK (BIT23|BIT24) +#define FB_VED_CLK_DIVIDE_SHIFT 23 +#define FB_VEC_CLK_DIVIDE_MASK (BIT25|BIT26) +#define FB_VEC_CLK_DIVIDE_SHIFT 25 +#endif /* FIXME remove it after PO */ + + +bool mid_get_pci_revID(struct drm_psb_private *dev_priv) +{ + uint32_t platform_rev_id = 0; + struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0)); + + /*get the revison ID, B0:D2:F0;0x08 */ + pci_read_config_dword(pci_gfx_root, 0x08, &platform_rev_id); + dev_priv->platform_rev_id = (uint8_t) platform_rev_id; + pci_dev_put(pci_gfx_root); + PSB_DEBUG_ENTRY("platform_rev_id is %x\n", + dev_priv->platform_rev_id); + + return true; +} + +static int psb_do_init(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) dev->dev_private; + struct ttm_bo_device *bdev = &dev_priv->bdev; + struct psb_gtt *pg = dev_priv->pg; + + uint32_t stolen_gtt; + uint32_t tt_start; + uint32_t tt_pages; + + int ret = -ENOMEM; + + + /* + * Initialize sequence numbers for the different command + * submission mechanisms. + */ + + dev_priv->sequence[PSB_ENGINE_2D] = 0; + dev_priv->sequence[PSB_ENGINE_VIDEO] = 0; + dev_priv->sequence[LNC_ENGINE_ENCODE] = 0; + + if (pg->mmu_gatt_start & 0x0FFFFFFF) { + DRM_ERROR("Gatt must be 256M aligned. This is a bug.\n"); + ret = -EINVAL; + goto out_err; + } + + stolen_gtt = (pg->stolen_size >> PAGE_SHIFT) * 4; + stolen_gtt = (stolen_gtt + PAGE_SIZE - 1) >> PAGE_SHIFT; + stolen_gtt = + (stolen_gtt < pg->gtt_pages) ? stolen_gtt : pg->gtt_pages; + + dev_priv->gatt_free_offset = pg->mmu_gatt_start + + (stolen_gtt << PAGE_SHIFT) * 1024; + + if (1 || drm_debug) { + uint32_t core_id = PSB_RSGX32(PSB_CR_CORE_ID); + uint32_t core_rev = PSB_RSGX32(PSB_CR_CORE_REVISION); + DRM_INFO("SGX core id = 0x%08x\n", core_id); + DRM_INFO("SGX core rev major = 0x%02x, minor = 0x%02x\n", + (core_rev & _PSB_CC_REVISION_MAJOR_MASK) >> + _PSB_CC_REVISION_MAJOR_SHIFT, + (core_rev & _PSB_CC_REVISION_MINOR_MASK) >> + _PSB_CC_REVISION_MINOR_SHIFT); + DRM_INFO + ("SGX core rev maintenance = 0x%02x, designer = 0x%02x\n", + (core_rev & _PSB_CC_REVISION_MAINTENANCE_MASK) >> + _PSB_CC_REVISION_MAINTENANCE_SHIFT, + (core_rev & _PSB_CC_REVISION_DESIGNER_MASK) >> + _PSB_CC_REVISION_DESIGNER_SHIFT); + } + + spin_lock_init(&dev_priv->irqmask_lock); + + tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ? + pg->gatt_pages : PSB_TT_PRIV0_PLIMIT; + tt_start = dev_priv->gatt_free_offset - pg->mmu_gatt_start; + tt_pages -= tt_start >> PAGE_SHIFT; + dev_priv->sizes.ta_mem_size = 0; + + + /* TT region managed by TTM. */ + if (!ttm_bo_init_mm(bdev, TTM_PL_TT, + pg->gatt_pages - + (pg->ci_start >> PAGE_SHIFT) - + ((dev_priv->ci_region_size + dev_priv->rar_region_size) + >> PAGE_SHIFT))) { + + dev_priv->have_tt = 1; + dev_priv->sizes.tt_size = + (tt_pages << PAGE_SHIFT) / (1024 * 1024) / 2; + } + + if (!ttm_bo_init_mm(bdev, + DRM_PSB_MEM_MMU, + PSB_MEM_TT_START >> PAGE_SHIFT)) { + dev_priv->have_mem_mmu = 1; + dev_priv->sizes.mmu_size = + PSB_MEM_TT_START / (1024*1024); + } + + + PSB_DEBUG_INIT("Init MSVDX\n"); + return 0; +out_err: + psb_do_takedown(dev); + return ret; +} + +static int psb_driver_unload(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) dev->dev_private; + + /* Kill vblank etc here */ + + psb_backlight_exit(); /*writes minimum value to backlight HW reg */ + + if (drm_psb_no_fb == 0) + psb_modeset_cleanup(dev); + + if (dev_priv) { + psb_lid_timer_takedown(dev_priv); + + psb_do_takedown(dev); + + + if (dev_priv->pf_pd) { + psb_mmu_free_pagedir(dev_priv->pf_pd); + dev_priv->pf_pd = NULL; + } + if (dev_priv->mmu) { + struct psb_gtt *pg = dev_priv->pg; + + down_read(&pg->sem); + psb_mmu_remove_pfn_sequence( + psb_mmu_get_default_pd + (dev_priv->mmu), + pg->mmu_gatt_start, + pg->vram_stolen_size >> PAGE_SHIFT); + if (pg->ci_stolen_size != 0) + psb_mmu_remove_pfn_sequence( + psb_mmu_get_default_pd + (dev_priv->mmu), + pg->ci_start, + pg->ci_stolen_size >> PAGE_SHIFT); + if (pg->rar_stolen_size != 0) + psb_mmu_remove_pfn_sequence( + psb_mmu_get_default_pd + (dev_priv->mmu), + pg->rar_start, + pg->rar_stolen_size >> PAGE_SHIFT); + up_read(&pg->sem); + psb_mmu_driver_takedown(dev_priv->mmu); + dev_priv->mmu = NULL; + } + psb_gtt_takedown(dev_priv->pg, 1); + if (dev_priv->scratch_page) { + __free_page(dev_priv->scratch_page); + dev_priv->scratch_page = NULL; + } + if (dev_priv->has_bo_device) { + ttm_bo_device_release(&dev_priv->bdev); + dev_priv->has_bo_device = 0; + } + if (dev_priv->has_fence_device) { + ttm_fence_device_release(&dev_priv->fdev); + dev_priv->has_fence_device = 0; + } + if (dev_priv->vdc_reg) { + iounmap(dev_priv->vdc_reg); + dev_priv->vdc_reg = NULL; + } + if (dev_priv->sgx_reg) { + iounmap(dev_priv->sgx_reg); + dev_priv->sgx_reg = NULL; + } + + if (dev_priv->tdev) + ttm_object_device_release(&dev_priv->tdev); + + if (dev_priv->has_global) + psb_ttm_global_release(dev_priv); + + kfree(dev_priv); + dev->dev_private = NULL; + + /*destory VBT data*/ + psb_intel_destory_bios(dev); + } + + ospm_power_uninit(); + + return 0; +} + + +static int psb_driver_load(struct drm_device *dev, unsigned long chipset) +{ + struct drm_psb_private *dev_priv; + struct ttm_bo_device *bdev; + unsigned long resource_start; + struct psb_gtt *pg; + unsigned long irqflags; + int ret = -ENOMEM; + uint32_t tt_pages; + + DRM_INFO("psb - %s\n", PSB_PACKAGE_VERSION); + + DRM_INFO("Run drivers on Poulsbo platform!\n"); + + dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); + if (dev_priv == NULL) + return -ENOMEM; + INIT_LIST_HEAD(&dev_priv->video_ctx); + + dev_priv->num_pipe = 2; + + + dev_priv->dev = dev; + bdev = &dev_priv->bdev; + + ret = psb_ttm_global_init(dev_priv); + if (unlikely(ret != 0)) + goto out_err; + dev_priv->has_global = 1; + + dev_priv->tdev = ttm_object_device_init + (dev_priv->mem_global_ref.object, PSB_OBJECT_HASH_ORDER); + if (unlikely(dev_priv->tdev == NULL)) + goto out_err; + + mutex_init(&dev_priv->temp_mem); + mutex_init(&dev_priv->cmdbuf_mutex); + mutex_init(&dev_priv->reset_mutex); + INIT_LIST_HEAD(&dev_priv->context.validate_list); + INIT_LIST_HEAD(&dev_priv->context.kern_validate_list); + +/* mutex_init(&dev_priv->dsr_mutex); */ + + spin_lock_init(&dev_priv->reloc_lock); + + DRM_INIT_WAITQUEUE(&dev_priv->rel_mapped_queue); + + dev->dev_private = (void *) dev_priv; + dev_priv->chipset = chipset; + psb_set_uopt(&dev_priv->uopt); + + PSB_DEBUG_INIT("Mapping MMIO\n"); + resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE); + + dev_priv->vdc_reg = + ioremap(resource_start + PSB_VDC_OFFSET, PSB_VDC_SIZE); + if (!dev_priv->vdc_reg) + goto out_err; + + dev_priv->sgx_reg = ioremap(resource_start + PSB_SGX_OFFSET, + PSB_SGX_SIZE); + + if (!dev_priv->sgx_reg) + goto out_err; + + psb_get_core_freq(dev); + psb_intel_opregion_init(dev); + psb_intel_init_bios(dev); + + PSB_DEBUG_INIT("Init TTM fence and BO driver\n"); + + /* Init OSPM support */ + ospm_power_init(dev); + + ret = psb_ttm_fence_device_init(&dev_priv->fdev); + if (unlikely(ret != 0)) + goto out_err; + + dev_priv->has_fence_device = 1; + ret = ttm_bo_device_init(bdev, + dev_priv->bo_global_ref.ref.object, + &psb_ttm_bo_driver, + DRM_PSB_FILE_PAGE_OFFSET, false); + if (unlikely(ret != 0)) + goto out_err; + dev_priv->has_bo_device = 1; + ttm_lock_init(&dev_priv->ttm_lock); + + ret = -ENOMEM; + + dev_priv->scratch_page = alloc_page(GFP_DMA32 | __GFP_ZERO); + if (!dev_priv->scratch_page) + goto out_err; + + set_pages_uc(dev_priv->scratch_page, 1); + + dev_priv->pg = psb_gtt_alloc(dev); + if (!dev_priv->pg) + goto out_err; + + ret = psb_gtt_init(dev_priv->pg, 0); + if (ret) + goto out_err; + + ret = psb_gtt_mm_init(dev_priv->pg); + if (ret) + goto out_err; + + dev_priv->mmu = psb_mmu_driver_init((void *)0, + drm_psb_trap_pagefaults, 0, + dev_priv); + if (!dev_priv->mmu) + goto out_err; + + pg = dev_priv->pg; + + tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ? + (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT; + + /* CI/RAR use the lower half of TT. */ + pg->ci_start = (tt_pages / 2) << PAGE_SHIFT; + pg->rar_start = pg->ci_start + pg->ci_stolen_size; + + + /* + * Make MSVDX/TOPAZ MMU aware of the CI stolen memory area. + */ + if (dev_priv->pg->ci_stolen_size != 0) { + down_read(&pg->sem); + ret = psb_mmu_insert_pfn_sequence(psb_mmu_get_default_pd + (dev_priv->mmu), + dev_priv->ci_region_start >> PAGE_SHIFT, + pg->mmu_gatt_start + pg->ci_start, + pg->ci_stolen_size >> PAGE_SHIFT, 0); + up_read(&pg->sem); + if (ret) + goto out_err; + } + + /* + * Make MSVDX/TOPAZ MMU aware of the rar stolen memory area. + */ + if (dev_priv->pg->rar_stolen_size != 0) { + down_read(&pg->sem); + ret = psb_mmu_insert_pfn_sequence( + psb_mmu_get_default_pd(dev_priv->mmu), + dev_priv->rar_region_start >> PAGE_SHIFT, + pg->mmu_gatt_start + pg->rar_start, + pg->rar_stolen_size >> PAGE_SHIFT, 0); + up_read(&pg->sem); + if (ret) + goto out_err; + } + + dev_priv->pf_pd = psb_mmu_alloc_pd(dev_priv->mmu, 1, 0); + if (!dev_priv->pf_pd) + goto out_err; + + psb_mmu_set_pd_context(psb_mmu_get_default_pd(dev_priv->mmu), 0); + psb_mmu_set_pd_context(dev_priv->pf_pd, 1); + + spin_lock_init(&dev_priv->sequence_lock); + + PSB_DEBUG_INIT("Begin to init MSVDX/Topaz\n"); + + ret = psb_do_init(dev); + if (ret) + return ret; + + /** + * Init lid switch timer. + * NOTE: must do this after psb_intel_opregion_init + * and psb_backlight_init + */ + if (dev_priv->lid_state) + psb_lid_timer_init(dev_priv); + + ret = drm_vblank_init(dev, dev_priv->num_pipe); + if (ret) + goto out_err; + + /* + * Install interrupt handlers prior to powering off SGX or else we will + * crash. + */ + dev_priv->vdc_irq_mask = 0; + dev_priv->pipestat[0] = 0; + dev_priv->pipestat[1] = 0; + dev_priv->pipestat[2] = 0; + spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); + PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R); + PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R); + spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); + if (drm_core_check_feature(dev, DRIVER_MODESET)) + drm_irq_install(dev); + + dev->vblank_disable_allowed = 1; + + dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ + + dev->driver->get_vblank_counter = psb_get_vblank_counter; + + if (drm_psb_no_fb == 0) { + psb_modeset_init(dev); + psb_fbdev_init(dev); + drm_kms_helper_poll_init(dev); + } + + ret = psb_backlight_init(dev); + if (ret) + return ret; +#if 0 + /*enable runtime pm at last*/ + pm_runtime_enable(&dev->pdev->dev); + pm_runtime_set_active(&dev->pdev->dev); +#endif + /*Intel drm driver load is done, continue doing pvr load*/ + DRM_DEBUG("Pvr driver load\n"); + +/* if (PVRCore_Init() < 0) + goto out_err; */ +/* if (MRSTLFBInit(dev) < 0) + goto out_err;*/ + return 0; +out_err: + psb_driver_unload(dev); + return ret; +} + +int psb_driver_device_is_agp(struct drm_device *dev) +{ + return 0; +} + + +static int psb_vt_leave_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_psb_private *dev_priv = psb_priv(dev); + struct ttm_bo_device *bdev = &dev_priv->bdev; + struct ttm_mem_type_manager *man; + int ret; + + ret = ttm_vt_lock(&dev_priv->ttm_lock, 1, + psb_fpriv(file_priv)->tfile); + if (unlikely(ret != 0)) + return ret; + + ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_TT); + if (unlikely(ret != 0)) + goto out_unlock; + + man = &bdev->man[TTM_PL_TT]; + +#if 0 /* What to do with this ? */ + if (unlikely(!drm_mm_clean(&man->manager))) + DRM_INFO("Warning: GATT was not clean after VT switch.\n"); +#endif + + ttm_bo_swapout_all(&dev_priv->bdev); + + return 0; +out_unlock: + (void) ttm_vt_unlock(&dev_priv->ttm_lock); + return ret; +} + +static int psb_vt_enter_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_psb_private *dev_priv = psb_priv(dev); + return ttm_vt_unlock(&dev_priv->ttm_lock); +} + +static int psb_sizes_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_psb_private *dev_priv = psb_priv(dev); + struct drm_psb_sizes_arg *arg = + (struct drm_psb_sizes_arg *) data; + + *arg = dev_priv->sizes; + return 0; +} + +static int psb_dc_state_ioctl(struct drm_device *dev, void * data, + struct drm_file *file_priv) +{ + uint32_t flags; + uint32_t obj_id; + struct drm_mode_object *obj; + struct drm_connector *connector; + struct drm_crtc *crtc; + struct drm_psb_dc_state_arg *arg = + (struct drm_psb_dc_state_arg *)data; + + flags = arg->flags; + obj_id = arg->obj_id; + + if (flags & PSB_DC_CRTC_MASK) { + obj = drm_mode_object_find(dev, obj_id, + DRM_MODE_OBJECT_CRTC); + if (!obj) { + DRM_DEBUG("Invalid CRTC object.\n"); + return -EINVAL; + } + + crtc = obj_to_crtc(obj); + + mutex_lock(&dev->mode_config.mutex); + if (drm_helper_crtc_in_use(crtc)) { + if (flags & PSB_DC_CRTC_SAVE) + crtc->funcs->save(crtc); + else + crtc->funcs->restore(crtc); + } + mutex_unlock(&dev->mode_config.mutex); + + return 0; + } else if (flags & PSB_DC_OUTPUT_MASK) { + obj = drm_mode_object_find(dev, obj_id, + DRM_MODE_OBJECT_CONNECTOR); + if (!obj) { + DRM_DEBUG("Invalid connector id.\n"); + return -EINVAL; + } + + connector = obj_to_connector(obj); + if (flags & PSB_DC_OUTPUT_SAVE) + connector->funcs->save(connector); + else + connector->funcs->restore(connector); + + return 0; + } + + DRM_DEBUG("Bad flags 0x%x\n", flags); + return -EINVAL; +} + +static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_psb_private *dev_priv = psb_priv(dev); + uint32_t *arg = data; + struct backlight_device bd; + dev_priv->blc_adj2 = *arg; + +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + bd.props.brightness = psb_get_brightness(&bd); + psb_set_brightness(&bd); +#endif + return 0; +} + +static int psb_adb_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_psb_private *dev_priv = psb_priv(dev); + uint32_t *arg = data; + struct backlight_device bd; + dev_priv->blc_adj1 = *arg; + +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + bd.props.brightness = psb_get_brightness(&bd); + psb_set_brightness(&bd); +#endif + return 0; +} + +/* return the current mode to the dpst module */ +static int psb_dpst_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_psb_private *dev_priv = psb_priv(dev); + uint32_t *arg = data; + uint32_t x; + uint32_t y; + uint32_t reg; + + if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_ONLY_IF_ON)) + return 0; + + reg = PSB_RVDC32(PIPEASRC); + + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + + /* horizontal is the left 16 bits */ + x = reg >> 16; + /* vertical is the right 16 bits */ + y = reg & 0x0000ffff; + + /* the values are the image size minus one */ + x++; + y++; + + *arg = (x << 16) | y; + + return 0; +} +static int psb_gamma_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_psb_dpst_lut_arg *lut_arg = data; + struct drm_mode_object *obj; + struct drm_crtc *crtc; + struct drm_connector *connector; + struct psb_intel_crtc *psb_intel_crtc; + int i = 0; + int32_t obj_id; + + obj_id = lut_arg->output_id; + obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_CONNECTOR); + if (!obj) { + DRM_DEBUG("Invalid Connector object.\n"); + return -EINVAL; + } + + connector = obj_to_connector(obj); + crtc = connector->encoder->crtc; + psb_intel_crtc = to_psb_intel_crtc(crtc); + + for (i = 0; i < 256; i++) + psb_intel_crtc->lut_adj[i] = lut_arg->lut[i]; + + psb_intel_crtc_load_lut(crtc); + + return 0; +} + +static int psb_mode_operation_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + uint32_t obj_id; + uint16_t op; + struct drm_mode_modeinfo *umode; + struct drm_display_mode *mode = NULL; + struct drm_psb_mode_operation_arg *arg; + struct drm_mode_object *obj; + struct drm_connector *connector; + struct drm_framebuffer *drm_fb; + struct psb_framebuffer *psb_fb; + struct drm_connector_helper_funcs *connector_funcs; + int ret = 0; + int resp = MODE_OK; + struct drm_psb_private *dev_priv = psb_priv(dev); + + arg = (struct drm_psb_mode_operation_arg *)data; + obj_id = arg->obj_id; + op = arg->operation; + + switch (op) { + case PSB_MODE_OPERATION_SET_DC_BASE: + obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_FB); + if (!obj) { + DRM_ERROR("Invalid FB id %d\n", obj_id); + return -EINVAL; + } + + drm_fb = obj_to_fb(obj); + psb_fb = to_psb_fb(drm_fb); + + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_ONLY_IF_ON)) { + REG_WRITE(DSPASURF, psb_fb->offset); + REG_READ(DSPASURF); + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } else { + dev_priv->saveDSPASURF = psb_fb->offset; + } + + return 0; + case PSB_MODE_OPERATION_MODE_VALID: + umode = &arg->mode; + + mutex_lock(&dev->mode_config.mutex); + + obj = drm_mode_object_find(dev, obj_id, + DRM_MODE_OBJECT_CONNECTOR); + if (!obj) { + ret = -EINVAL; + goto mode_op_out; + } + + connector = obj_to_connector(obj); + + mode = drm_mode_create(dev); + if (!mode) { + ret = -ENOMEM; + goto mode_op_out; + } + + /* drm_crtc_convert_umode(mode, umode); */ + { + mode->clock = umode->clock; + mode->hdisplay = umode->hdisplay; + mode->hsync_start = umode->hsync_start; + mode->hsync_end = umode->hsync_end; + mode->htotal = umode->htotal; + mode->hskew = umode->hskew; + mode->vdisplay = umode->vdisplay; + mode->vsync_start = umode->vsync_start; + mode->vsync_end = umode->vsync_end; + mode->vtotal = umode->vtotal; + mode->vscan = umode->vscan; + mode->vrefresh = umode->vrefresh; + mode->flags = umode->flags; + mode->type = umode->type; + strncpy(mode->name, umode->name, DRM_DISPLAY_MODE_LEN); + mode->name[DRM_DISPLAY_MODE_LEN-1] = 0; + } + + connector_funcs = (struct drm_connector_helper_funcs *) + connector->helper_private; + + if (connector_funcs->mode_valid) { + resp = connector_funcs->mode_valid(connector, mode); + arg->data = (void *)resp; + } + + /*do some clean up work*/ + if (mode) + drm_mode_destroy(dev, mode); +mode_op_out: + mutex_unlock(&dev->mode_config.mutex); + return ret; + + default: + DRM_DEBUG("Unsupported psb mode operation"); + return -EOPNOTSUPP; + } + + return 0; +} + +static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_psb_private *dev_priv = psb_priv(dev); + struct drm_psb_stolen_memory_arg *arg = data; + + arg->base = dev_priv->pg->stolen_base; + arg->size = dev_priv->pg->vram_stolen_size; + + return 0; +} + +static int psb_register_rw_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_psb_private *dev_priv = psb_priv(dev); + struct drm_psb_register_rw_arg *arg = data; + UHBUsage usage = + arg->b_force_hw_on ? OSPM_UHB_FORCE_POWER_ON : OSPM_UHB_ONLY_IF_ON; + + if (arg->display_write_mask != 0) { + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) { + if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS) + PSB_WVDC32(arg->display.pfit_controls, + PFIT_CONTROL); + if (arg->display_write_mask & + REGRWBITS_PFIT_AUTOSCALE_RATIOS) + PSB_WVDC32(arg->display.pfit_autoscale_ratios, + PFIT_AUTO_RATIOS); + if (arg->display_write_mask & + REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS) + PSB_WVDC32( + arg->display.pfit_programmed_scale_ratios, + PFIT_PGM_RATIOS); + if (arg->display_write_mask & REGRWBITS_PIPEASRC) + PSB_WVDC32(arg->display.pipeasrc, + PIPEASRC); + if (arg->display_write_mask & REGRWBITS_PIPEBSRC) + PSB_WVDC32(arg->display.pipebsrc, + PIPEBSRC); + if (arg->display_write_mask & REGRWBITS_VTOTAL_A) + PSB_WVDC32(arg->display.vtotal_a, + VTOTAL_A); + if (arg->display_write_mask & REGRWBITS_VTOTAL_B) + PSB_WVDC32(arg->display.vtotal_b, + VTOTAL_B); + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } else { + if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS) + dev_priv->savePFIT_CONTROL = + arg->display.pfit_controls; + if (arg->display_write_mask & + REGRWBITS_PFIT_AUTOSCALE_RATIOS) + dev_priv->savePFIT_AUTO_RATIOS = + arg->display.pfit_autoscale_ratios; + if (arg->display_write_mask & + REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS) + dev_priv->savePFIT_PGM_RATIOS = + arg->display.pfit_programmed_scale_ratios; + if (arg->display_write_mask & REGRWBITS_PIPEASRC) + dev_priv->savePIPEASRC = arg->display.pipeasrc; + if (arg->display_write_mask & REGRWBITS_PIPEBSRC) + dev_priv->savePIPEBSRC = arg->display.pipebsrc; + if (arg->display_write_mask & REGRWBITS_VTOTAL_A) + dev_priv->saveVTOTAL_A = arg->display.vtotal_a; + if (arg->display_write_mask & REGRWBITS_VTOTAL_B) + dev_priv->saveVTOTAL_B = arg->display.vtotal_b; + } + } + + if (arg->display_read_mask != 0) { + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) { + if (arg->display_read_mask & + REGRWBITS_PFIT_CONTROLS) + arg->display.pfit_controls = + PSB_RVDC32(PFIT_CONTROL); + if (arg->display_read_mask & + REGRWBITS_PFIT_AUTOSCALE_RATIOS) + arg->display.pfit_autoscale_ratios = + PSB_RVDC32(PFIT_AUTO_RATIOS); + if (arg->display_read_mask & + REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS) + arg->display.pfit_programmed_scale_ratios = + PSB_RVDC32(PFIT_PGM_RATIOS); + if (arg->display_read_mask & REGRWBITS_PIPEASRC) + arg->display.pipeasrc = PSB_RVDC32(PIPEASRC); + if (arg->display_read_mask & REGRWBITS_PIPEBSRC) + arg->display.pipebsrc = PSB_RVDC32(PIPEBSRC); + if (arg->display_read_mask & REGRWBITS_VTOTAL_A) + arg->display.vtotal_a = PSB_RVDC32(VTOTAL_A); + if (arg->display_read_mask & REGRWBITS_VTOTAL_B) + arg->display.vtotal_b = PSB_RVDC32(VTOTAL_B); + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } else { + if (arg->display_read_mask & + REGRWBITS_PFIT_CONTROLS) + arg->display.pfit_controls = + dev_priv->savePFIT_CONTROL; + if (arg->display_read_mask & + REGRWBITS_PFIT_AUTOSCALE_RATIOS) + arg->display.pfit_autoscale_ratios = + dev_priv->savePFIT_AUTO_RATIOS; + if (arg->display_read_mask & + REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS) + arg->display.pfit_programmed_scale_ratios = + dev_priv->savePFIT_PGM_RATIOS; + if (arg->display_read_mask & REGRWBITS_PIPEASRC) + arg->display.pipeasrc = dev_priv->savePIPEASRC; + if (arg->display_read_mask & REGRWBITS_PIPEBSRC) + arg->display.pipebsrc = dev_priv->savePIPEBSRC; + if (arg->display_read_mask & REGRWBITS_VTOTAL_A) + arg->display.vtotal_a = dev_priv->saveVTOTAL_A; + if (arg->display_read_mask & REGRWBITS_VTOTAL_B) + arg->display.vtotal_b = dev_priv->saveVTOTAL_B; + } + } + + if (arg->overlay_write_mask != 0) { + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) { + if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) { + PSB_WVDC32(arg->overlay.OGAMC5, OV_OGAMC5); + PSB_WVDC32(arg->overlay.OGAMC4, OV_OGAMC4); + PSB_WVDC32(arg->overlay.OGAMC3, OV_OGAMC3); + PSB_WVDC32(arg->overlay.OGAMC2, OV_OGAMC2); + PSB_WVDC32(arg->overlay.OGAMC1, OV_OGAMC1); + PSB_WVDC32(arg->overlay.OGAMC0, OV_OGAMC0); + } + if (arg->overlay_write_mask & OVC_REGRWBITS_OGAM_ALL) { + PSB_WVDC32(arg->overlay.OGAMC5, OVC_OGAMC5); + PSB_WVDC32(arg->overlay.OGAMC4, OVC_OGAMC4); + PSB_WVDC32(arg->overlay.OGAMC3, OVC_OGAMC3); + PSB_WVDC32(arg->overlay.OGAMC2, OVC_OGAMC2); + PSB_WVDC32(arg->overlay.OGAMC1, OVC_OGAMC1); + PSB_WVDC32(arg->overlay.OGAMC0, OVC_OGAMC0); + } + + if (arg->overlay_write_mask & OV_REGRWBITS_OVADD) { + PSB_WVDC32(arg->overlay.OVADD, OV_OVADD); + + if (arg->overlay.b_wait_vblank) { + /* Wait for 20ms.*/ + unsigned long vblank_timeout = jiffies + + HZ/50; + uint32_t temp; + while (time_before_eq(jiffies, + vblank_timeout)) { + temp = PSB_RVDC32(OV_DOVASTA); + if ((temp & (0x1 << 31)) != 0) + break; + cpu_relax(); + } + } + } + if (arg->overlay_write_mask & OVC_REGRWBITS_OVADD) { + PSB_WVDC32(arg->overlay.OVADD, OVC_OVADD); + if (arg->overlay.b_wait_vblank) { + /* Wait for 20ms.*/ + unsigned long vblank_timeout = + jiffies + HZ/50; + uint32_t temp; + while (time_before_eq(jiffies, + vblank_timeout)) { + temp = PSB_RVDC32(OVC_DOVCSTA); + if ((temp & (0x1 << 31)) != 0) + break; + cpu_relax(); + } + } + } + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } else { + if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) { + dev_priv->saveOV_OGAMC5 = arg->overlay.OGAMC5; + dev_priv->saveOV_OGAMC4 = arg->overlay.OGAMC4; + dev_priv->saveOV_OGAMC3 = arg->overlay.OGAMC3; + dev_priv->saveOV_OGAMC2 = arg->overlay.OGAMC2; + dev_priv->saveOV_OGAMC1 = arg->overlay.OGAMC1; + dev_priv->saveOV_OGAMC0 = arg->overlay.OGAMC0; + } + if (arg->overlay_write_mask & OVC_REGRWBITS_OGAM_ALL) { + dev_priv->saveOVC_OGAMC5 = arg->overlay.OGAMC5; + dev_priv->saveOVC_OGAMC4 = arg->overlay.OGAMC4; + dev_priv->saveOVC_OGAMC3 = arg->overlay.OGAMC3; + dev_priv->saveOVC_OGAMC2 = arg->overlay.OGAMC2; + dev_priv->saveOVC_OGAMC1 = arg->overlay.OGAMC1; + dev_priv->saveOVC_OGAMC0 = arg->overlay.OGAMC0; + } + if (arg->overlay_write_mask & OV_REGRWBITS_OVADD) + dev_priv->saveOV_OVADD = arg->overlay.OVADD; + if (arg->overlay_write_mask & OVC_REGRWBITS_OVADD) + dev_priv->saveOVC_OVADD = arg->overlay.OVADD; + } + } + + if (arg->overlay_read_mask != 0) { + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) { + if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) { + arg->overlay.OGAMC5 = PSB_RVDC32(OV_OGAMC5); + arg->overlay.OGAMC4 = PSB_RVDC32(OV_OGAMC4); + arg->overlay.OGAMC3 = PSB_RVDC32(OV_OGAMC3); + arg->overlay.OGAMC2 = PSB_RVDC32(OV_OGAMC2); + arg->overlay.OGAMC1 = PSB_RVDC32(OV_OGAMC1); + arg->overlay.OGAMC0 = PSB_RVDC32(OV_OGAMC0); + } + if (arg->overlay_read_mask & OVC_REGRWBITS_OGAM_ALL) { + arg->overlay.OGAMC5 = PSB_RVDC32(OVC_OGAMC5); + arg->overlay.OGAMC4 = PSB_RVDC32(OVC_OGAMC4); + arg->overlay.OGAMC3 = PSB_RVDC32(OVC_OGAMC3); + arg->overlay.OGAMC2 = PSB_RVDC32(OVC_OGAMC2); + arg->overlay.OGAMC1 = PSB_RVDC32(OVC_OGAMC1); + arg->overlay.OGAMC0 = PSB_RVDC32(OVC_OGAMC0); + } + if (arg->overlay_read_mask & OV_REGRWBITS_OVADD) + arg->overlay.OVADD = PSB_RVDC32(OV_OVADD); + if (arg->overlay_read_mask & OVC_REGRWBITS_OVADD) + arg->overlay.OVADD = PSB_RVDC32(OVC_OVADD); + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } else { + if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) { + arg->overlay.OGAMC5 = dev_priv->saveOV_OGAMC5; + arg->overlay.OGAMC4 = dev_priv->saveOV_OGAMC4; + arg->overlay.OGAMC3 = dev_priv->saveOV_OGAMC3; + arg->overlay.OGAMC2 = dev_priv->saveOV_OGAMC2; + arg->overlay.OGAMC1 = dev_priv->saveOV_OGAMC1; + arg->overlay.OGAMC0 = dev_priv->saveOV_OGAMC0; + } + if (arg->overlay_read_mask & OVC_REGRWBITS_OGAM_ALL) { + arg->overlay.OGAMC5 = dev_priv->saveOVC_OGAMC5; + arg->overlay.OGAMC4 = dev_priv->saveOVC_OGAMC4; + arg->overlay.OGAMC3 = dev_priv->saveOVC_OGAMC3; + arg->overlay.OGAMC2 = dev_priv->saveOVC_OGAMC2; + arg->overlay.OGAMC1 = dev_priv->saveOVC_OGAMC1; + arg->overlay.OGAMC0 = dev_priv->saveOVC_OGAMC0; + } + if (arg->overlay_read_mask & OV_REGRWBITS_OVADD) + arg->overlay.OVADD = dev_priv->saveOV_OVADD; + if (arg->overlay_read_mask & OVC_REGRWBITS_OVADD) + arg->overlay.OVADD = dev_priv->saveOVC_OVADD; + } + } + + if (arg->sprite_enable_mask != 0) { + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) { + PSB_WVDC32(0x1F3E, DSPARB); + PSB_WVDC32(arg->sprite.dspa_control + | PSB_RVDC32(DSPACNTR), DSPACNTR); + PSB_WVDC32(arg->sprite.dspa_key_value, DSPAKEYVAL); + PSB_WVDC32(arg->sprite.dspa_key_mask, DSPAKEYMASK); + PSB_WVDC32(PSB_RVDC32(DSPASURF), DSPASURF); + PSB_RVDC32(DSPASURF); + PSB_WVDC32(arg->sprite.dspc_control, DSPCCNTR); + PSB_WVDC32(arg->sprite.dspc_stride, DSPCSTRIDE); + PSB_WVDC32(arg->sprite.dspc_position, DSPCPOS); + PSB_WVDC32(arg->sprite.dspc_linear_offset, DSPCLINOFF); + PSB_WVDC32(arg->sprite.dspc_size, DSPCSIZE); + PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF); + PSB_RVDC32(DSPCSURF); + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } + } + + if (arg->sprite_disable_mask != 0) { + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) { + PSB_WVDC32(0x3F3E, DSPARB); + PSB_WVDC32(0x0, DSPCCNTR); + PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF); + PSB_RVDC32(DSPCSURF); + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } + } + + if (arg->subpicture_enable_mask != 0) { + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) { + uint32_t temp; + if (arg->subpicture_enable_mask & REGRWBITS_DSPACNTR) { + temp = PSB_RVDC32(DSPACNTR); + temp &= ~DISPPLANE_PIXFORMAT_MASK; + temp &= ~DISPPLANE_BOTTOM; + temp |= DISPPLANE_32BPP; + PSB_WVDC32(temp, DSPACNTR); + + temp = PSB_RVDC32(DSPABASE); + PSB_WVDC32(temp, DSPABASE); + PSB_RVDC32(DSPABASE); + temp = PSB_RVDC32(DSPASURF); + PSB_WVDC32(temp, DSPASURF); + PSB_RVDC32(DSPASURF); + } + if (arg->subpicture_enable_mask & REGRWBITS_DSPBCNTR) { + temp = PSB_RVDC32(DSPBCNTR); + temp &= ~DISPPLANE_PIXFORMAT_MASK; + temp &= ~DISPPLANE_BOTTOM; + temp |= DISPPLANE_32BPP; + PSB_WVDC32(temp, DSPBCNTR); + + temp = PSB_RVDC32(DSPBBASE); + PSB_WVDC32(temp, DSPBBASE); + PSB_RVDC32(DSPBBASE); + temp = PSB_RVDC32(DSPBSURF); + PSB_WVDC32(temp, DSPBSURF); + PSB_RVDC32(DSPBSURF); + } + if (arg->subpicture_enable_mask & REGRWBITS_DSPCCNTR) { + temp = PSB_RVDC32(DSPCCNTR); + temp &= ~DISPPLANE_PIXFORMAT_MASK; + temp &= ~DISPPLANE_BOTTOM; + temp |= DISPPLANE_32BPP; + PSB_WVDC32(temp, DSPCCNTR); + + temp = PSB_RVDC32(DSPCBASE); + PSB_WVDC32(temp, DSPCBASE); + PSB_RVDC32(DSPCBASE); + temp = PSB_RVDC32(DSPCSURF); + PSB_WVDC32(temp, DSPCSURF); + PSB_RVDC32(DSPCSURF); + } + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } + } + + if (arg->subpicture_disable_mask != 0) { + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) { + uint32_t temp; + if (arg->subpicture_disable_mask & REGRWBITS_DSPACNTR) { + temp = PSB_RVDC32(DSPACNTR); + temp &= ~DISPPLANE_PIXFORMAT_MASK; + temp |= DISPPLANE_32BPP_NO_ALPHA; + PSB_WVDC32(temp, DSPACNTR); + + temp = PSB_RVDC32(DSPABASE); + PSB_WVDC32(temp, DSPABASE); + PSB_RVDC32(DSPABASE); + temp = PSB_RVDC32(DSPASURF); + PSB_WVDC32(temp, DSPASURF); + PSB_RVDC32(DSPASURF); + } + if (arg->subpicture_disable_mask & REGRWBITS_DSPBCNTR) { + temp = PSB_RVDC32(DSPBCNTR); + temp &= ~DISPPLANE_PIXFORMAT_MASK; + temp |= DISPPLANE_32BPP_NO_ALPHA; + PSB_WVDC32(temp, DSPBCNTR); + + temp = PSB_RVDC32(DSPBBASE); + PSB_WVDC32(temp, DSPBBASE); + PSB_RVDC32(DSPBBASE); + temp = PSB_RVDC32(DSPBSURF); + PSB_WVDC32(temp, DSPBSURF); + PSB_RVDC32(DSPBSURF); + } + if (arg->subpicture_disable_mask & REGRWBITS_DSPCCNTR) { + temp = PSB_RVDC32(DSPCCNTR); + temp &= ~DISPPLANE_PIXFORMAT_MASK; + temp |= DISPPLANE_32BPP_NO_ALPHA; + PSB_WVDC32(temp, DSPCCNTR); + + temp = PSB_RVDC32(DSPCBASE); + PSB_WVDC32(temp, DSPCBASE); + PSB_RVDC32(DSPCBASE); + temp = PSB_RVDC32(DSPCSURF); + PSB_WVDC32(temp, DSPCSURF); + PSB_RVDC32(DSPCSURF); + } + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } + } + + return 0; +} + +/* always available as we are SIGIO'd */ +static unsigned int psb_poll(struct file *filp, + struct poll_table_struct *wait) +{ + return POLLIN | POLLRDNORM; +} + +/* Not sure what we will need yet - in the PVR driver this disappears into + a tangle of abstracted handlers and per process crap */ + +struct psb_priv { + int dummy; +}; + +static int psb_driver_open(struct drm_device *dev, struct drm_file *priv) +{ + struct psb_priv *psb = kzalloc(sizeof(struct psb_priv), GFP_KERNEL); + if (psb == NULL) + return -ENOMEM; + priv->driver_priv = psb; + DRM_DEBUG("\n"); + /*return PVRSRVOpen(dev, priv);*/ + return 0; +} + +static void psb_driver_close(struct drm_device *dev, struct drm_file *priv) +{ + kfree(priv->driver_priv); + priv->driver_priv = NULL; +} + +static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct drm_file *file_priv = filp->private_data; + struct drm_device *dev = file_priv->minor->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + static unsigned int runtime_allowed; + unsigned int nr = DRM_IOCTL_NR(cmd); + + DRM_DEBUG("cmd = %x, nr = %x\n", cmd, nr); + + if (runtime_allowed == 1 && dev_priv->is_lvds_on) { + runtime_allowed++; + pm_runtime_allow(&dev->pdev->dev); + dev_priv->rpm_enabled = 1; + } + /* + * The driver private ioctls and TTM ioctls should be + * thread-safe. + */ + + if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) + && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) { + struct drm_ioctl_desc *ioctl = + &psb_ioctls[nr - DRM_COMMAND_BASE]; + + if (unlikely(ioctl->cmd != cmd)) { + DRM_ERROR( + "Invalid drm cmnd %d ioctl->cmd %x, cmd %x\n", + nr - DRM_COMMAND_BASE, ioctl->cmd, cmd); + return -EINVAL; + } + + return drm_ioctl(filp, cmd, arg); + } + /* + * Not all old drm ioctls are thread-safe. + */ + + return drm_ioctl(filp, cmd, arg); +} + + +/* When a client dies: + * - Check for and clean up flipped page state + */ +void psb_driver_preclose(struct drm_device *dev, struct drm_file *priv) +{ +} + +static void psb_remove(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + drm_put_dev(dev); +} + + +static const struct dev_pm_ops psb_pm_ops = { + .runtime_suspend = psb_runtime_suspend, + .runtime_resume = psb_runtime_resume, + .runtime_idle = psb_runtime_idle, +}; + +static struct drm_driver driver = { + .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | \ + DRIVER_IRQ_VBL | DRIVER_MODESET, + .load = psb_driver_load, + .unload = psb_driver_unload, + + .ioctls = psb_ioctls, + .num_ioctls = DRM_ARRAY_SIZE(psb_ioctls), + .device_is_agp = psb_driver_device_is_agp, + .irq_preinstall = psb_irq_preinstall, + .irq_postinstall = psb_irq_postinstall, + .irq_uninstall = psb_irq_uninstall, + .irq_handler = psb_irq_handler, + .enable_vblank = psb_enable_vblank, + .disable_vblank = psb_disable_vblank, + .get_vblank_counter = psb_get_vblank_counter, + .firstopen = NULL, + .lastclose = psb_lastclose, + .open = psb_driver_open, + .postclose = psb_driver_close, +#if 0 /* ACFIXME */ + .get_map_ofs = drm_core_get_map_ofs, + .get_reg_ofs = drm_core_get_reg_ofs, + .proc_init = psb_proc_init, + .proc_cleanup = psb_proc_cleanup, +#endif + .preclose = psb_driver_preclose, + .fops = { + .owner = THIS_MODULE, + .open = psb_open, + .release = psb_release, + .unlocked_ioctl = psb_unlocked_ioctl, + .mmap = psb_mmap, + .poll = psb_poll, + .fasync = drm_fasync, + .read = drm_read, + }, + .pci_driver = { + .name = DRIVER_NAME, + .id_table = pciidlist, + .resume = ospm_power_resume, + .suspend = ospm_power_suspend, + .probe = psb_probe, + .remove = psb_remove, +#ifdef CONFIG_PM + .driver.pm = &psb_pm_ops, +#endif + }, + .name = DRIVER_NAME, + .desc = DRIVER_DESC, + .date = PSB_DRM_DRIVER_DATE, + .major = PSB_DRM_DRIVER_MAJOR, + .minor = PSB_DRM_DRIVER_MINOR, + .patchlevel = PSB_DRM_DRIVER_PATCHLEVEL +}; + +static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + /* MLD Added this from Inaky's patch */ + if (pci_enable_msi(pdev)) + DRM_ERROR("Enable MSI failed!\n"); + return drm_get_pci_dev(pdev, ent, &driver); +} + +static int __init psb_init(void) +{ + return drm_init(&driver); +} + +static void __exit psb_exit(void) +{ + drm_exit(&driver); +} + +late_initcall(psb_init); +module_exit(psb_exit); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h new file mode 100644 index 000000000000..b75b9d850723 --- /dev/null +++ b/drivers/staging/gma500/psb_drv.h @@ -0,0 +1,1139 @@ +/************************************************************************** + * Copyright (c) 2007-2008, Intel Corporation. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + **************************************************************************/ + +#ifndef _PSB_DRV_H_ +#define _PSB_DRV_H_ + +#include + +#include +#include "drm_global.h" +#include "psb_drm.h" +#include "psb_reg.h" +#include "psb_intel_drv.h" +#include "psb_gtt.h" +#include "psb_powermgmt.h" +#include "ttm/ttm_object.h" +#include "psb_ttm_fence_driver.h" +#include "psb_ttm_userobj_api.h" +#include "ttm/ttm_bo_driver.h" +#include "ttm/ttm_lock.h" + +/*Append new drm mode definition here, align with libdrm definition*/ +#define DRM_MODE_SCALE_NO_SCALE 2 + +extern struct ttm_bo_driver psb_ttm_bo_driver; + +enum { + CHIP_PSB_8108 = 0, + CHIP_PSB_8109 = 1, +}; + +/* + *Hardware bugfixes + */ + +#define DRIVER_NAME "pvrsrvkm" +#define DRIVER_DESC "drm driver for the Intel GMA500" +#define DRIVER_AUTHOR "Intel Corporation" +#define OSPM_PROC_ENTRY "ospm" +#define RTPM_PROC_ENTRY "rtpm" +#define BLC_PROC_ENTRY "mrst_blc" +#define DISPLAY_PROC_ENTRY "display_status" + +#define PSB_DRM_DRIVER_DATE "2009-03-10" +#define PSB_DRM_DRIVER_MAJOR 8 +#define PSB_DRM_DRIVER_MINOR 1 +#define PSB_DRM_DRIVER_PATCHLEVEL 0 + +/* + *TTM driver private offsets. + */ + +#define DRM_PSB_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) + +#define PSB_OBJECT_HASH_ORDER 13 +#define PSB_FILE_OBJECT_HASH_ORDER 12 +#define PSB_BO_HASH_ORDER 12 + +#define PSB_VDC_OFFSET 0x00000000 +#define PSB_VDC_SIZE 0x000080000 +#define MRST_MMIO_SIZE 0x0000C0000 +#define MDFLD_MMIO_SIZE 0x000100000 +#define PSB_SGX_SIZE 0x8000 +#define PSB_SGX_OFFSET 0x00040000 +#define MRST_SGX_OFFSET 0x00080000 +#define PSB_MMIO_RESOURCE 0 +#define PSB_GATT_RESOURCE 2 +#define PSB_GTT_RESOURCE 3 +#define PSB_GMCH_CTRL 0x52 +#define PSB_BSM 0x5C +#define _PSB_GMCH_ENABLED 0x4 +#define PSB_PGETBL_CTL 0x2020 +#define _PSB_PGETBL_ENABLED 0x00000001 +#define PSB_SGX_2D_SLAVE_PORT 0x4000 +#define PSB_TT_PRIV0_LIMIT (256*1024*1024) +#define PSB_TT_PRIV0_PLIMIT (PSB_TT_PRIV0_LIMIT >> PAGE_SHIFT) +#define PSB_NUM_VALIDATE_BUFFERS 2048 + +#define PSB_MEM_MMU_START 0x00000000 +#define PSB_MEM_TT_START 0xE0000000 + +#define PSB_GL3_CACHE_CTL 0x2100 +#define PSB_GL3_CACHE_STAT 0x2108 + +/* + *Flags for external memory type field. + */ + +#define MRST_MSVDX_OFFSET 0x90000 /*MSVDX Base offset */ +#define PSB_MSVDX_OFFSET 0x50000 /*MSVDX Base offset */ +/* MSVDX MMIO region is 0x50000 - 0x57fff ==> 32KB */ +#define PSB_MSVDX_SIZE 0x10000 + +#define LNC_TOPAZ_OFFSET 0xA0000 +#define PNW_TOPAZ_OFFSET 0xC0000 +#define PNW_GL3_OFFSET 0xB0000 +#define LNC_TOPAZ_SIZE 0x10000 +#define PNW_TOPAZ_SIZE 0x30000 /* PNW VXE285 has two cores */ +#define PSB_MMU_CACHED_MEMORY 0x0001 /* Bind to MMU only */ +#define PSB_MMU_RO_MEMORY 0x0002 /* MMU RO memory */ +#define PSB_MMU_WO_MEMORY 0x0004 /* MMU WO memory */ + +/* + *PTE's and PDE's + */ + +#define PSB_PDE_MASK 0x003FFFFF +#define PSB_PDE_SHIFT 22 +#define PSB_PTE_SHIFT 12 + +#define PSB_PTE_VALID 0x0001 /* PTE / PDE valid */ +#define PSB_PTE_WO 0x0002 /* Write only */ +#define PSB_PTE_RO 0x0004 /* Read only */ +#define PSB_PTE_CACHED 0x0008 /* CPU cache coherent */ + +/* + *VDC registers and bits + */ +#define PSB_MSVDX_CLOCKGATING 0x2064 +#define PSB_TOPAZ_CLOCKGATING 0x2068 +#define PSB_HWSTAM 0x2098 +#define PSB_INSTPM 0x20C0 +#define PSB_INT_IDENTITY_R 0x20A4 +#define _MDFLD_PIPEC_EVENT_FLAG (1<<2) +#define _MDFLD_PIPEC_VBLANK_FLAG (1<<3) +#define _PSB_DPST_PIPEB_FLAG (1<<4) +#define _MDFLD_PIPEB_EVENT_FLAG (1<<4) +#define _PSB_VSYNC_PIPEB_FLAG (1<<5) +#define _PSB_DPST_PIPEA_FLAG (1<<6) +#define _PSB_PIPEA_EVENT_FLAG (1<<6) +#define _PSB_VSYNC_PIPEA_FLAG (1<<7) +#define _MDFLD_MIPIA_FLAG (1<<16) +#define _MDFLD_MIPIC_FLAG (1<<17) +#define _PSB_IRQ_SGX_FLAG (1<<18) +#define _PSB_IRQ_MSVDX_FLAG (1<<19) +#define _LNC_IRQ_TOPAZ_FLAG (1<<20) + +/* This flag includes all the display IRQ bits excepts the vblank irqs. */ +#define _MDFLD_DISP_ALL_IRQ_FLAG (_MDFLD_PIPEC_EVENT_FLAG | _MDFLD_PIPEB_EVENT_FLAG | \ + _PSB_PIPEA_EVENT_FLAG | _PSB_VSYNC_PIPEA_FLAG | _MDFLD_MIPIA_FLAG | _MDFLD_MIPIC_FLAG) +#define PSB_INT_IDENTITY_R 0x20A4 +#define PSB_INT_MASK_R 0x20A8 +#define PSB_INT_ENABLE_R 0x20A0 + +#define _PSB_MMU_ER_MASK 0x0001FF00 +#define _PSB_MMU_ER_HOST (1 << 16) +#define GPIOA 0x5010 +#define GPIOB 0x5014 +#define GPIOC 0x5018 +#define GPIOD 0x501c +#define GPIOE 0x5020 +#define GPIOF 0x5024 +#define GPIOG 0x5028 +#define GPIOH 0x502c +#define GPIO_CLOCK_DIR_MASK (1 << 0) +#define GPIO_CLOCK_DIR_IN (0 << 1) +#define GPIO_CLOCK_DIR_OUT (1 << 1) +#define GPIO_CLOCK_VAL_MASK (1 << 2) +#define GPIO_CLOCK_VAL_OUT (1 << 3) +#define GPIO_CLOCK_VAL_IN (1 << 4) +#define GPIO_CLOCK_PULLUP_DISABLE (1 << 5) +#define GPIO_DATA_DIR_MASK (1 << 8) +#define GPIO_DATA_DIR_IN (0 << 9) +#define GPIO_DATA_DIR_OUT (1 << 9) +#define GPIO_DATA_VAL_MASK (1 << 10) +#define GPIO_DATA_VAL_OUT (1 << 11) +#define GPIO_DATA_VAL_IN (1 << 12) +#define GPIO_DATA_PULLUP_DISABLE (1 << 13) + +#define VCLK_DIVISOR_VGA0 0x6000 +#define VCLK_DIVISOR_VGA1 0x6004 +#define VCLK_POST_DIV 0x6010 + +#define PSB_COMM_2D (PSB_ENGINE_2D << 4) +#define PSB_COMM_3D (PSB_ENGINE_3D << 4) +#define PSB_COMM_TA (PSB_ENGINE_TA << 4) +#define PSB_COMM_HP (PSB_ENGINE_HP << 4) +#define PSB_COMM_USER_IRQ (1024 >> 2) +#define PSB_COMM_USER_IRQ_LOST (PSB_COMM_USER_IRQ + 1) +#define PSB_COMM_FW (2048 >> 2) + +#define PSB_UIRQ_VISTEST 1 +#define PSB_UIRQ_OOM_REPLY 2 +#define PSB_UIRQ_FIRE_TA_REPLY 3 +#define PSB_UIRQ_FIRE_RASTER_REPLY 4 + +#define PSB_2D_SIZE (256*1024*1024) +#define PSB_MAX_RELOC_PAGES 1024 + +#define PSB_LOW_REG_OFFS 0x0204 +#define PSB_HIGH_REG_OFFS 0x0600 + +#define PSB_NUM_VBLANKS 2 + + +#define PSB_2D_SIZE (256*1024*1024) +#define PSB_MAX_RELOC_PAGES 1024 + +#define PSB_LOW_REG_OFFS 0x0204 +#define PSB_HIGH_REG_OFFS 0x0600 + +#define PSB_NUM_VBLANKS 2 +#define PSB_WATCHDOG_DELAY (DRM_HZ * 2) +#define PSB_LID_DELAY (DRM_HZ / 10) + +#define MDFLD_PNW_A0 0x00 +#define MDFLD_PNW_B0 0x04 +#define MDFLD_PNW_C0 0x08 + +#define MDFLD_DSR_2D_3D_0 BIT0 +#define MDFLD_DSR_2D_3D_2 BIT1 +#define MDFLD_DSR_CURSOR_0 BIT2 +#define MDFLD_DSR_CURSOR_2 BIT3 +#define MDFLD_DSR_OVERLAY_0 BIT4 +#define MDFLD_DSR_OVERLAY_2 BIT5 +#define MDFLD_DSR_MIPI_CONTROL BIT6 +#define MDFLD_DSR_2D_3D (MDFLD_DSR_2D_3D_0 | MDFLD_DSR_2D_3D_2) + +#define MDFLD_DSR_RR 45 +#define MDFLD_DPU_ENABLE BIT31 +#define MDFLD_DSR_FULLSCREEN BIT30 +#define MDFLD_DSR_DELAY (DRM_HZ / MDFLD_DSR_RR) + +#define PSB_PWR_STATE_ON 1 +#define PSB_PWR_STATE_OFF 2 + +#define PSB_PMPOLICY_NOPM 0 +#define PSB_PMPOLICY_CLOCKGATING 1 +#define PSB_PMPOLICY_POWERDOWN 2 + +#define PSB_PMSTATE_POWERUP 0 +#define PSB_PMSTATE_CLOCKGATED 1 +#define PSB_PMSTATE_POWERDOWN 2 +#define PSB_PCIx_MSI_ADDR_LOC 0x94 +#define PSB_PCIx_MSI_DATA_LOC 0x98 + +#define MDFLD_PLANE_MAX_WIDTH 2048 +#define MDFLD_PLANE_MAX_HEIGHT 2048 + +struct opregion_header; +struct opregion_acpi; +struct opregion_swsci; +struct opregion_asle; + +struct psb_intel_opregion { + struct opregion_header *header; + struct opregion_acpi *acpi; + struct opregion_swsci *swsci; + struct opregion_asle *asle; + int enabled; +}; + +/* + *User options. + */ + +struct drm_psb_uopt { + int pad; /*keep it here in case we use it in future*/ +}; + +/** + *struct psb_context + * + *@buffers: array of pre-allocated validate buffers. + *@used_buffers: number of buffers in @buffers array currently in use. + *@validate_buffer: buffers validated from user-space. + *@kern_validate_buffers : buffers validated from kernel-space. + *@fence_flags : Fence flags to be used for fence creation. + * + *This structure is used during execbuf validation. + */ + +struct psb_context { + struct psb_validate_buffer *buffers; + uint32_t used_buffers; + struct list_head validate_list; + struct list_head kern_validate_list; + uint32_t fence_types; + uint32_t val_seq; +}; + +struct psb_validate_buffer; + +/* Currently defined profiles */ +enum VAProfile { + VAProfileMPEG2Simple = 0, + VAProfileMPEG2Main = 1, + VAProfileMPEG4Simple = 2, + VAProfileMPEG4AdvancedSimple = 3, + VAProfileMPEG4Main = 4, + VAProfileH264Baseline = 5, + VAProfileH264Main = 6, + VAProfileH264High = 7, + VAProfileVC1Simple = 8, + VAProfileVC1Main = 9, + VAProfileVC1Advanced = 10, + VAProfileH263Baseline = 11, + VAProfileJPEGBaseline = 12, + VAProfileH264ConstrainedBaseline = 13 +}; + +/* Currently defined entrypoints */ +enum VAEntrypoint { + VAEntrypointVLD = 1, + VAEntrypointIZZ = 2, + VAEntrypointIDCT = 3, + VAEntrypointMoComp = 4, + VAEntrypointDeblocking = 5, + VAEntrypointEncSlice = 6, /* slice level encode */ + VAEntrypointEncPicture = 7 /* pictuer encode, JPEG, etc */ +}; + + +struct psb_video_ctx { + struct list_head head; + struct file *filp; /* DRM device file pointer */ + int ctx_type; /* profile<<8|entrypoint */ + /* todo: more context specific data for multi-context support */ +}; + +#define MODE_SETTING_IN_CRTC 0x1 +#define MODE_SETTING_IN_ENCODER 0x2 +#define MODE_SETTING_ON_GOING 0x3 +#define MODE_SETTING_IN_DSR 0x4 +#define MODE_SETTING_ENCODER_DONE 0x8 +#define GCT_R10_HEADER_SIZE 16 +#define GCT_R10_DISPLAY_DESC_SIZE 28 + +struct drm_psb_private { + /* + * DSI info. + */ + void * dbi_dsr_info; + void * dsi_configs[2]; + + /* + *TTM Glue. + */ + + struct drm_global_reference mem_global_ref; + struct ttm_bo_global_ref bo_global_ref; + int has_global; + + struct drm_device *dev; + struct ttm_object_device *tdev; + struct ttm_fence_device fdev; + struct ttm_bo_device bdev; + struct ttm_lock ttm_lock; + struct vm_operations_struct *ttm_vm_ops; + int has_fence_device; + int has_bo_device; + + unsigned long chipset; + + struct drm_psb_dev_info_arg dev_info; + struct drm_psb_uopt uopt; + + struct psb_gtt *pg; + + /*GTT Memory manager*/ + struct psb_gtt_mm *gtt_mm; + + struct page *scratch_page; + uint32_t sequence[PSB_NUM_ENGINES]; + uint32_t last_sequence[PSB_NUM_ENGINES]; + uint32_t last_submitted_seq[PSB_NUM_ENGINES]; + + struct psb_mmu_driver *mmu; + struct psb_mmu_pd *pf_pd; + + uint8_t *sgx_reg; + uint8_t *vdc_reg; + uint32_t gatt_free_offset; + + /* IMG video context */ + struct list_head video_ctx; + + + + /* + *Fencing / irq. + */ + + uint32_t vdc_irq_mask; + uint32_t pipestat[PSB_NUM_PIPE]; + bool vblanksEnabledForFlips; + + spinlock_t irqmask_lock; + spinlock_t sequence_lock; + + /* + *Modesetting + */ + struct psb_intel_mode_device mode_dev; + + struct drm_crtc *plane_to_crtc_mapping[PSB_NUM_PIPE]; + struct drm_crtc *pipe_to_crtc_mapping[PSB_NUM_PIPE]; + uint32_t num_pipe; + + /* + * CI share buffer + */ + unsigned int ci_region_start; + unsigned int ci_region_size; + + /* + * RAR share buffer; + */ + unsigned int rar_region_start; + unsigned int rar_region_size; + + /* + *Memory managers + */ + + int have_camera; + int have_rar; + int have_tt; + int have_mem_mmu; + struct mutex temp_mem; + + /* + *Relocation buffer mapping. + */ + + spinlock_t reloc_lock; + unsigned int rel_mapped_pages; + wait_queue_head_t rel_mapped_queue; + + /* + *SAREA + */ + struct drm_psb_sarea *sarea_priv; + + /* + *OSPM info + */ + uint32_t ospm_base; + + /* + * Sizes info + */ + + struct drm_psb_sizes_arg sizes; + + uint32_t fuse_reg_value; + + /* pci revision id for B0:D2:F0 */ + uint8_t platform_rev_id; + + /* + *LVDS info + */ + int backlight_duty_cycle; /* restore backlight to this value */ + bool panel_wants_dither; + struct drm_display_mode *panel_fixed_mode; + struct drm_display_mode *lfp_lvds_vbt_mode; + struct drm_display_mode *sdvo_lvds_vbt_mode; + + struct bdb_lvds_backlight *lvds_bl; /*LVDS backlight info from VBT*/ + struct psb_intel_i2c_chan *lvds_i2c_bus; + + /* Feature bits from the VBIOS*/ + unsigned int int_tv_support:1; + unsigned int lvds_dither:1; + unsigned int lvds_vbt:1; + unsigned int int_crt_support:1; + unsigned int lvds_use_ssc:1; + int lvds_ssc_freq; + bool is_lvds_on; + + unsigned int core_freq; + uint32_t iLVDS_enable; + + /*runtime PM state*/ + int rpm_enabled; + + /* + *Register state + */ + uint32_t saveDSPACNTR; + uint32_t saveDSPBCNTR; + uint32_t savePIPEACONF; + uint32_t savePIPEBCONF; + uint32_t savePIPEASRC; + uint32_t savePIPEBSRC; + uint32_t saveFPA0; + uint32_t saveFPA1; + uint32_t saveDPLL_A; + uint32_t saveDPLL_A_MD; + uint32_t saveHTOTAL_A; + uint32_t saveHBLANK_A; + uint32_t saveHSYNC_A; + uint32_t saveVTOTAL_A; + uint32_t saveVBLANK_A; + uint32_t saveVSYNC_A; + uint32_t saveDSPASTRIDE; + uint32_t saveDSPASIZE; + uint32_t saveDSPAPOS; + uint32_t saveDSPABASE; + uint32_t saveDSPASURF; + uint32_t saveFPB0; + uint32_t saveFPB1; + uint32_t saveDPLL_B; + uint32_t saveDPLL_B_MD; + uint32_t saveHTOTAL_B; + uint32_t saveHBLANK_B; + uint32_t saveHSYNC_B; + uint32_t saveVTOTAL_B; + uint32_t saveVBLANK_B; + uint32_t saveVSYNC_B; + uint32_t saveDSPBSTRIDE; + uint32_t saveDSPBSIZE; + uint32_t saveDSPBPOS; + uint32_t saveDSPBBASE; + uint32_t saveDSPBSURF; + uint32_t saveVCLK_DIVISOR_VGA0; + uint32_t saveVCLK_DIVISOR_VGA1; + uint32_t saveVCLK_POST_DIV; + uint32_t saveVGACNTRL; + uint32_t saveADPA; + uint32_t saveLVDS; + uint32_t saveDVOA; + uint32_t saveDVOB; + uint32_t saveDVOC; + uint32_t savePP_ON; + uint32_t savePP_OFF; + uint32_t savePP_CONTROL; + uint32_t savePP_CYCLE; + uint32_t savePFIT_CONTROL; + uint32_t savePaletteA[256]; + uint32_t savePaletteB[256]; + uint32_t saveBLC_PWM_CTL2; + uint32_t saveBLC_PWM_CTL; + uint32_t saveCLOCKGATING; + uint32_t saveDSPARB; + uint32_t saveDSPATILEOFF; + uint32_t saveDSPBTILEOFF; + uint32_t saveDSPAADDR; + uint32_t saveDSPBADDR; + uint32_t savePFIT_AUTO_RATIOS; + uint32_t savePFIT_PGM_RATIOS; + uint32_t savePP_ON_DELAYS; + uint32_t savePP_OFF_DELAYS; + uint32_t savePP_DIVISOR; + uint32_t saveBSM; + uint32_t saveVBT; + uint32_t saveBCLRPAT_A; + uint32_t saveBCLRPAT_B; + uint32_t saveDSPALINOFF; + uint32_t saveDSPBLINOFF; + uint32_t savePERF_MODE; + uint32_t saveDSPFW1; + uint32_t saveDSPFW2; + uint32_t saveDSPFW3; + uint32_t saveDSPFW4; + uint32_t saveDSPFW5; + uint32_t saveDSPFW6; + uint32_t saveCHICKENBIT; + uint32_t saveDSPACURSOR_CTRL; + uint32_t saveDSPBCURSOR_CTRL; + uint32_t saveDSPACURSOR_BASE; + uint32_t saveDSPBCURSOR_BASE; + uint32_t saveDSPACURSOR_POS; + uint32_t saveDSPBCURSOR_POS; + uint32_t save_palette_a[256]; + uint32_t save_palette_b[256]; + uint32_t saveOV_OVADD; + uint32_t saveOV_OGAMC0; + uint32_t saveOV_OGAMC1; + uint32_t saveOV_OGAMC2; + uint32_t saveOV_OGAMC3; + uint32_t saveOV_OGAMC4; + uint32_t saveOV_OGAMC5; + uint32_t saveOVC_OVADD; + uint32_t saveOVC_OGAMC0; + uint32_t saveOVC_OGAMC1; + uint32_t saveOVC_OGAMC2; + uint32_t saveOVC_OGAMC3; + uint32_t saveOVC_OGAMC4; + uint32_t saveOVC_OGAMC5; + + /* + * extra MDFLD Register state + */ + uint32_t saveHDMIPHYMISCCTL; + uint32_t saveHDMIB_CONTROL; + uint32_t saveDSPCCNTR; + uint32_t savePIPECCONF; + uint32_t savePIPECSRC; + uint32_t saveHTOTAL_C; + uint32_t saveHBLANK_C; + uint32_t saveHSYNC_C; + uint32_t saveVTOTAL_C; + uint32_t saveVBLANK_C; + uint32_t saveVSYNC_C; + uint32_t saveDSPCSTRIDE; + uint32_t saveDSPCSIZE; + uint32_t saveDSPCPOS; + uint32_t saveDSPCSURF; + uint32_t saveDSPCLINOFF; + uint32_t saveDSPCTILEOFF; + uint32_t saveDSPCCURSOR_CTRL; + uint32_t saveDSPCCURSOR_BASE; + uint32_t saveDSPCCURSOR_POS; + uint32_t save_palette_c[256]; + uint32_t saveOV_OVADD_C; + uint32_t saveOV_OGAMC0_C; + uint32_t saveOV_OGAMC1_C; + uint32_t saveOV_OGAMC2_C; + uint32_t saveOV_OGAMC3_C; + uint32_t saveOV_OGAMC4_C; + uint32_t saveOV_OGAMC5_C; + + /* DSI reg save */ + uint32_t saveDEVICE_READY_REG; + uint32_t saveINTR_EN_REG; + uint32_t saveDSI_FUNC_PRG_REG; + uint32_t saveHS_TX_TIMEOUT_REG; + uint32_t saveLP_RX_TIMEOUT_REG; + uint32_t saveTURN_AROUND_TIMEOUT_REG; + uint32_t saveDEVICE_RESET_REG; + uint32_t saveDPI_RESOLUTION_REG; + uint32_t saveHORIZ_SYNC_PAD_COUNT_REG; + uint32_t saveHORIZ_BACK_PORCH_COUNT_REG; + uint32_t saveHORIZ_FRONT_PORCH_COUNT_REG; + uint32_t saveHORIZ_ACTIVE_AREA_COUNT_REG; + uint32_t saveVERT_SYNC_PAD_COUNT_REG; + uint32_t saveVERT_BACK_PORCH_COUNT_REG; + uint32_t saveVERT_FRONT_PORCH_COUNT_REG; + uint32_t saveHIGH_LOW_SWITCH_COUNT_REG; + uint32_t saveINIT_COUNT_REG; + uint32_t saveMAX_RET_PAK_REG; + uint32_t saveVIDEO_FMT_REG; + uint32_t saveEOT_DISABLE_REG; + uint32_t saveLP_BYTECLK_REG; + uint32_t saveHS_LS_DBI_ENABLE_REG; + uint32_t saveTXCLKESC_REG; + uint32_t saveDPHY_PARAM_REG; + uint32_t saveMIPI_CONTROL_REG; + uint32_t saveMIPI; + uint32_t saveMIPI_C; + void (*init_drvIC)(struct drm_device *dev); + void (*dsi_prePowerState)(struct drm_device *dev); + void (*dsi_postPowerState)(struct drm_device *dev); + + /* DPST Register Save */ + uint32_t saveHISTOGRAM_INT_CONTROL_REG; + uint32_t saveHISTOGRAM_LOGIC_CONTROL_REG; + uint32_t savePWM_CONTROL_LOGIC; + + /* MSI reg save */ + + uint32_t msi_addr; + uint32_t msi_data; + + /* + *Scheduling. + */ + + struct mutex reset_mutex; + struct mutex cmdbuf_mutex; + /*uint32_t ta_mem_pages; + struct psb_ta_mem *ta_mem; + int force_ta_mem_load;*/ + atomic_t val_seq; + + /* + *TODO: change this to be per drm-context. + */ + + struct psb_context context; + + /* + * LID-Switch + */ + spinlock_t lid_lock; + struct timer_list lid_timer; + struct psb_intel_opregion opregion; + u32 *lid_state; + u32 lid_last_state; + + /* + *Watchdog + */ + + int timer_available; + + uint32_t apm_reg; + uint16_t apm_base; + + /* + * Used for modifying backlight from + * xrandr -- consider removing and using HAL instead + */ + struct drm_property *backlight_property; + uint32_t blc_adj1; + uint32_t blc_adj2; + + void * fbdev; +}; + + +struct psb_file_data { /* TODO: Audit this, remove the indirection and set + it up properly in open/postclose ACFIXME */ + void *priv; +}; + +struct psb_fpriv { + struct ttm_object_file *tfile; +}; + +struct psb_mmu_driver; + +extern int drm_crtc_probe_output_modes(struct drm_device *dev, int, int); +extern int drm_pick_crtcs(struct drm_device *dev); + +static inline struct psb_fpriv *psb_fpriv(struct drm_file *file_priv) +{ + struct psb_file_data *pvr_file_priv + = (struct psb_file_data *)file_priv->driver_priv; + return (struct psb_fpriv *) pvr_file_priv->priv; +} + +static inline struct drm_psb_private *psb_priv(struct drm_device *dev) +{ + return (struct drm_psb_private *) dev->dev_private; +} + +/* + *TTM glue. psb_ttm_glue.c + */ + +extern int psb_open(struct inode *inode, struct file *filp); +extern int psb_release(struct inode *inode, struct file *filp); +extern int psb_mmap(struct file *filp, struct vm_area_struct *vma); + +extern int psb_fence_signaled_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int psb_verify_access(struct ttm_buffer_object *bo, + struct file *filp); +extern ssize_t psb_ttm_read(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos); +extern ssize_t psb_ttm_write(struct file *filp, const char __user *buf, + size_t count, loff_t *f_pos); +extern int psb_fence_finish_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int psb_fence_unref_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int psb_pl_waitidle_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int psb_pl_setstatus_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int psb_pl_synccpu_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int psb_pl_unref_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int psb_pl_reference_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int psb_pl_create_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int psb_pl_ub_create_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int psb_extension_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int psb_ttm_global_init(struct drm_psb_private *dev_priv); +extern void psb_ttm_global_release(struct drm_psb_private *dev_priv); +extern int psb_getpageaddrs_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +/* + *MMU stuff. + */ + +extern struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers, + int trap_pagefaults, + int invalid_type, + struct drm_psb_private *dev_priv); +extern void psb_mmu_driver_takedown(struct psb_mmu_driver *driver); +extern struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver + *driver); +extern void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd, uint32_t mmu_offset, + uint32_t gtt_start, uint32_t gtt_pages); +extern struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver, + int trap_pagefaults, + int invalid_type); +extern void psb_mmu_free_pagedir(struct psb_mmu_pd *pd); +extern void psb_mmu_flush(struct psb_mmu_driver *driver, int rc_prot); +extern void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd, + unsigned long address, + uint32_t num_pages); +extern int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd, + uint32_t start_pfn, + unsigned long address, + uint32_t num_pages, int type); +extern int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual, + unsigned long *pfn); + +/* + *Enable / disable MMU for different requestors. + */ + + +extern void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context); +extern int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages, + unsigned long address, uint32_t num_pages, + uint32_t desired_tile_stride, + uint32_t hw_tile_stride, int type); +extern void psb_mmu_remove_pages(struct psb_mmu_pd *pd, + unsigned long address, uint32_t num_pages, + uint32_t desired_tile_stride, + uint32_t hw_tile_stride); +/* + *psb_sgx.c + */ + + + +extern int psb_cmdbuf_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int psb_reg_submit(struct drm_psb_private *dev_priv, + uint32_t *regs, unsigned int cmds); + + +extern void psb_fence_or_sync(struct drm_file *file_priv, + uint32_t engine, + uint32_t fence_types, + uint32_t fence_flags, + struct list_head *list, + struct psb_ttm_fence_rep *fence_arg, + struct ttm_fence_object **fence_p); +extern int psb_validate_kernel_buffer(struct psb_context *context, + struct ttm_buffer_object *bo, + uint32_t fence_class, + uint64_t set_flags, + uint64_t clr_flags); + +/* + *psb_irq.c + */ + +extern irqreturn_t psb_irq_handler(DRM_IRQ_ARGS); +extern int psb_irq_enable_dpst(struct drm_device *dev); +extern int psb_irq_disable_dpst(struct drm_device *dev); +extern void psb_irq_preinstall(struct drm_device *dev); +extern int psb_irq_postinstall(struct drm_device *dev); +extern void psb_irq_uninstall(struct drm_device *dev); +extern void psb_irq_preinstall_islands(struct drm_device *dev, int hw_islands); +extern int psb_irq_postinstall_islands(struct drm_device *dev, int hw_islands); +extern void psb_irq_turn_on_dpst(struct drm_device *dev); +extern void psb_irq_turn_off_dpst(struct drm_device *dev); + +extern void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands); +extern int psb_vblank_wait2(struct drm_device *dev,unsigned int *sequence); +extern int psb_vblank_wait(struct drm_device *dev, unsigned int *sequence); +extern int psb_enable_vblank(struct drm_device *dev, int crtc); +extern void psb_disable_vblank(struct drm_device *dev, int crtc); +void +psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask); + +void +psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask); + +extern u32 psb_get_vblank_counter(struct drm_device *dev, int crtc); + +/* + *psb_fence.c + */ + +extern void psb_fence_handler(struct drm_device *dev, uint32_t class); + +extern int psb_fence_emit_sequence(struct ttm_fence_device *fdev, + uint32_t fence_class, + uint32_t flags, uint32_t *sequence, + unsigned long *timeout_jiffies); +extern void psb_fence_error(struct drm_device *dev, + uint32_t class, + uint32_t sequence, uint32_t type, int error); +extern int psb_ttm_fence_device_init(struct ttm_fence_device *fdev); + +/* MSVDX/Topaz stuff */ +extern int psb_remove_videoctx(struct drm_psb_private *dev_priv, struct file *filp); + +extern int lnc_video_frameskip(struct drm_device *dev, + uint64_t user_pointer); +extern int lnc_video_getparam(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +/* + * psb_opregion.c + */ +extern int psb_intel_opregion_init(struct drm_device *dev); + +/* + *psb_fb.c + */ +extern int psbfb_probed(struct drm_device *dev); +extern int psbfb_remove(struct drm_device *dev, + struct drm_framebuffer *fb); +extern int psbfb_kms_off_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int psbfb_kms_on_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern void *psbfb_vdc_reg(struct drm_device* dev); + +/* + *psb_reset.c + */ + +extern void psb_lid_timer_init(struct drm_psb_private *dev_priv); +extern void psb_lid_timer_takedown(struct drm_psb_private *dev_priv); +extern void psb_print_pagefault(struct drm_psb_private *dev_priv); + +/* modesetting */ +extern void psb_modeset_init(struct drm_device *dev); +extern void psb_modeset_cleanup(struct drm_device *dev); +extern int psb_fbdev_init(struct drm_device * dev); + +/* psb_bl.c */ +int psb_backlight_init(struct drm_device *dev); +void psb_backlight_exit(void); +int psb_set_brightness(struct backlight_device *bd); +int psb_get_brightness(struct backlight_device *bd); +struct backlight_device * psb_get_backlight_device(void); + +/* + *Debug print bits setting + */ +#define PSB_D_GENERAL (1 << 0) +#define PSB_D_INIT (1 << 1) +#define PSB_D_IRQ (1 << 2) +#define PSB_D_ENTRY (1 << 3) +/* debug the get H/V BP/FP count */ +#define PSB_D_HV (1 << 4) +#define PSB_D_DBI_BF (1 << 5) +#define PSB_D_PM (1 << 6) +#define PSB_D_RENDER (1 << 7) +#define PSB_D_REG (1 << 8) +#define PSB_D_MSVDX (1 << 9) +#define PSB_D_TOPAZ (1 << 10) + +#ifndef DRM_DEBUG_CODE +/* To enable debug printout, set drm_psb_debug in psb_drv.c + * to any combination of above print flags. + */ +/* #define DRM_DEBUG_CODE 2 */ +#endif + +extern int drm_psb_debug; +extern int drm_psb_no_fb; +extern int drm_psb_disable_vsync; +extern int drm_idle_check_interval; + +#define PSB_DEBUG_GENERAL(_fmt, _arg...) \ + PSB_DEBUG(PSB_D_GENERAL, _fmt, ##_arg) +#define PSB_DEBUG_INIT(_fmt, _arg...) \ + PSB_DEBUG(PSB_D_INIT, _fmt, ##_arg) +#define PSB_DEBUG_IRQ(_fmt, _arg...) \ + PSB_DEBUG(PSB_D_IRQ, _fmt, ##_arg) +#define PSB_DEBUG_ENTRY(_fmt, _arg...) \ + PSB_DEBUG(PSB_D_ENTRY, _fmt, ##_arg) +#define PSB_DEBUG_HV(_fmt, _arg...) \ + PSB_DEBUG(PSB_D_HV, _fmt, ##_arg) +#define PSB_DEBUG_DBI_BF(_fmt, _arg...) \ + PSB_DEBUG(PSB_D_DBI_BF, _fmt, ##_arg) +#define PSB_DEBUG_PM(_fmt, _arg...) \ + PSB_DEBUG(PSB_D_PM, _fmt, ##_arg) +#define PSB_DEBUG_RENDER(_fmt, _arg...) \ + PSB_DEBUG(PSB_D_RENDER, _fmt, ##_arg) +#define PSB_DEBUG_REG(_fmt, _arg...) \ + PSB_DEBUG(PSB_D_REG, _fmt, ##_arg) +#define PSB_DEBUG_MSVDX(_fmt, _arg...) \ + PSB_DEBUG(PSB_D_MSVDX, _fmt, ##_arg) +#define PSB_DEBUG_TOPAZ(_fmt, _arg...) \ + PSB_DEBUG(PSB_D_TOPAZ, _fmt, ##_arg) + +#if DRM_DEBUG_CODE +#define PSB_DEBUG(_flag, _fmt, _arg...) \ + do { \ + if (unlikely((_flag) & drm_psb_debug)) \ + printk(KERN_DEBUG \ + "[psb:0x%02x:%s] " _fmt , _flag, \ + __func__ , ##_arg); \ + } while (0) +#else +#define PSB_DEBUG(_fmt, _arg...) do { } while (0) +#endif + +/* + *Utilities + */ +#define DRM_DRIVER_PRIVATE_T struct drm_psb_private + +static inline u32 MRST_MSG_READ32(uint port, uint offset) +{ + int mcr = (0xD0<<24) | (port << 16) | (offset << 8); + uint32_t ret_val = 0; + struct pci_dev *pci_root = pci_get_bus_and_slot (0, 0); + pci_write_config_dword (pci_root, 0xD0, mcr); + pci_read_config_dword (pci_root, 0xD4, &ret_val); + pci_dev_put(pci_root); + return ret_val; +} +static inline void MRST_MSG_WRITE32(uint port, uint offset, u32 value) +{ + int mcr = (0xE0<<24) | (port << 16) | (offset << 8) | 0xF0; + struct pci_dev *pci_root = pci_get_bus_and_slot (0, 0); + pci_write_config_dword (pci_root, 0xD4, value); + pci_write_config_dword (pci_root, 0xD0, mcr); + pci_dev_put(pci_root); +} +static inline u32 MDFLD_MSG_READ32(uint port, uint offset) +{ + int mcr = (0x10<<24) | (port << 16) | (offset << 8); + uint32_t ret_val = 0; + struct pci_dev *pci_root = pci_get_bus_and_slot (0, 0); + pci_write_config_dword (pci_root, 0xD0, mcr); + pci_read_config_dword (pci_root, 0xD4, &ret_val); + pci_dev_put(pci_root); + return ret_val; +} +static inline void MDFLD_MSG_WRITE32(uint port, uint offset, u32 value) +{ + int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0; + struct pci_dev *pci_root = pci_get_bus_and_slot (0, 0); + pci_write_config_dword (pci_root, 0xD4, value); + pci_write_config_dword (pci_root, 0xD0, mcr); + pci_dev_put(pci_root); +} + +static inline uint32_t REGISTER_READ(struct drm_device *dev, uint32_t reg) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + int reg_val = ioread32(dev_priv->vdc_reg + (reg)); + PSB_DEBUG_REG("reg = 0x%x. reg_val = 0x%x. \n", reg, reg_val); + return reg_val; +} + +#define REG_READ(reg) REGISTER_READ(dev, (reg)) +static inline void REGISTER_WRITE(struct drm_device *dev, uint32_t reg, + uint32_t val) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + if ((reg < 0x70084 || reg >0x70088) && (reg < 0xa000 || reg >0xa3ff)) + PSB_DEBUG_REG("reg = 0x%x, val = 0x%x. \n", reg, val); + + iowrite32((val), dev_priv->vdc_reg + (reg)); +} + +#define REG_WRITE(reg, val) REGISTER_WRITE(dev, (reg), (val)) + +static inline void REGISTER_WRITE16(struct drm_device *dev, + uint32_t reg, uint32_t val) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + + PSB_DEBUG_REG("reg = 0x%x, val = 0x%x. \n", reg, val); + + iowrite16((val), dev_priv->vdc_reg + (reg)); +} + +#define REG_WRITE16(reg, val) REGISTER_WRITE16(dev, (reg), (val)) + +static inline void REGISTER_WRITE8(struct drm_device *dev, + uint32_t reg, uint32_t val) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + + PSB_DEBUG_REG("reg = 0x%x, val = 0x%x. \n", reg, val); + + iowrite8((val), dev_priv->vdc_reg + (reg)); +} + +#define REG_WRITE8(reg, val) REGISTER_WRITE8(dev, (reg), (val)) + +#define PSB_ALIGN_TO(_val, _align) \ + (((_val) + ((_align) - 1)) & ~((_align) - 1)) +#define PSB_WVDC32(_val, _offs) \ + iowrite32(_val, dev_priv->vdc_reg + (_offs)) +#define PSB_RVDC32(_offs) \ + ioread32(dev_priv->vdc_reg + (_offs)) + +/* #define TRAP_SGX_PM_FAULT 1 */ +#ifdef TRAP_SGX_PM_FAULT +#define PSB_RSGX32(_offs) \ +({ \ + if (inl(dev_priv->apm_base + PSB_APM_STS) & 0x3) { \ + printk(KERN_ERR "access sgx when it's off!! (READ) %s, %d\n", \ + __FILE__, __LINE__); \ + mdelay(1000); \ + } \ + ioread32(dev_priv->sgx_reg + (_offs)); \ +}) +#else +#define PSB_RSGX32(_offs) \ + ioread32(dev_priv->sgx_reg + (_offs)) +#endif +#define PSB_WSGX32(_val, _offs) \ + iowrite32(_val, dev_priv->sgx_reg + (_offs)) + +#define MSVDX_REG_DUMP 0 +#if MSVDX_REG_DUMP + +#define PSB_WMSVDX32(_val, _offs) \ + printk("MSVDX: write %08x to reg 0x%08x\n", (unsigned int)(_val), (unsigned int)(_offs));\ + iowrite32(_val, dev_priv->msvdx_reg + (_offs)) +#define PSB_RMSVDX32(_offs) \ + ioread32(dev_priv->msvdx_reg + (_offs)) + +#else + +#define PSB_WMSVDX32(_val, _offs) \ + iowrite32(_val, dev_priv->msvdx_reg + (_offs)) +#define PSB_RMSVDX32(_offs) \ + ioread32(dev_priv->msvdx_reg + (_offs)) + +#endif + +#define PSB_ALPL(_val, _base) \ + (((_val) >> (_base ## _ALIGNSHIFT)) << (_base ## _SHIFT)) +#define PSB_ALPLM(_val, _base) \ + ((((_val) >> (_base ## _ALIGNSHIFT)) << (_base ## _SHIFT)) & (_base ## _MASK)) + +#endif diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c new file mode 100644 index 000000000000..6585e8882243 --- /dev/null +++ b/drivers/staging/gma500/psb_fb.c @@ -0,0 +1,840 @@ +/************************************************************************** + * Copyright (c) 2007, Intel Corporation. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + **************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "psb_drv.h" +#include "psb_intel_reg.h" +#include "psb_intel_drv.h" +#include "psb_ttm_userobj_api.h" +#include "psb_fb.h" +#include "psb_sgx.h" +#include "psb_pvr_glue.h" + +static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb); +static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb, + struct drm_file *file_priv, + unsigned int *handle); + +static const struct drm_framebuffer_funcs psb_fb_funcs = { + .destroy = psb_user_framebuffer_destroy, + .create_handle = psb_user_framebuffer_create_handle, +}; + +#define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16) + +void *psbfb_vdc_reg(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv; + dev_priv = (struct drm_psb_private *) dev->dev_private; + return dev_priv->vdc_reg; +} +/*EXPORT_SYMBOL(psbfb_vdc_reg); */ + +static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, + struct fb_info *info) +{ + struct psb_fbdev *fbdev = info->par; + struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb; + uint32_t v; + + if (!fb) + return -ENOMEM; + + if (regno > 255) + return 1; + + red = CMAP_TOHW(red, info->var.red.length); + blue = CMAP_TOHW(blue, info->var.blue.length); + green = CMAP_TOHW(green, info->var.green.length); + transp = CMAP_TOHW(transp, info->var.transp.length); + + v = (red << info->var.red.offset) | + (green << info->var.green.offset) | + (blue << info->var.blue.offset) | + (transp << info->var.transp.offset); + + if (regno < 16) { + switch (fb->bits_per_pixel) { + case 16: + ((uint32_t *) info->pseudo_palette)[regno] = v; + break; + case 24: + case 32: + ((uint32_t *) info->pseudo_palette)[regno] = v; + break; + } + } + + return 0; +} + +static int psbfb_kms_off(struct drm_device *dev, int suspend) +{ + struct drm_framebuffer *fb = 0; + struct psb_framebuffer *psbfb = to_psb_fb(fb); + DRM_DEBUG("psbfb_kms_off_ioctl\n"); + + mutex_lock(&dev->mode_config.mutex); + list_for_each_entry(fb, &dev->mode_config.fb_list, head) { + struct fb_info *info = psbfb->fbdev; + + if (suspend) { + fb_set_suspend(info, 1); + drm_fb_helper_blank(FB_BLANK_POWERDOWN, info); + } + } + mutex_unlock(&dev->mode_config.mutex); + return 0; +} + +int psbfb_kms_off_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + int ret; + + if (drm_psb_no_fb) + return 0; + console_lock(); + ret = psbfb_kms_off(dev, 0); + console_unlock(); + + return ret; +} + +static int psbfb_kms_on(struct drm_device *dev, int resume) +{ + struct drm_framebuffer *fb = 0; + struct psb_framebuffer *psbfb = to_psb_fb(fb); + + DRM_DEBUG("psbfb_kms_on_ioctl\n"); + + mutex_lock(&dev->mode_config.mutex); + list_for_each_entry(fb, &dev->mode_config.fb_list, head) { + struct fb_info *info = psbfb->fbdev; + + if (resume) { + fb_set_suspend(info, 0); + drm_fb_helper_blank(FB_BLANK_UNBLANK, info); + } + } + mutex_unlock(&dev->mode_config.mutex); + + return 0; +} + +int psbfb_kms_on_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + int ret; + + if (drm_psb_no_fb) + return 0; + console_lock(); + ret = psbfb_kms_on(dev, 0); + console_unlock(); + drm_helper_disable_unused_functions(dev); + return ret; +} + +void psbfb_suspend(struct drm_device *dev) +{ + console_lock(); + psbfb_kms_off(dev, 1); + console_unlock(); +} + +void psbfb_resume(struct drm_device *dev) +{ + console_lock(); + psbfb_kms_on(dev, 1); + console_unlock(); + drm_helper_disable_unused_functions(dev); +} + +static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + int page_num = 0; + int i; + unsigned long address = 0; + int ret; + unsigned long pfn; + struct psb_framebuffer *psbfb = vma->vm_private_data; + struct drm_device *dev = psbfb->base.dev; + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_gtt *pg = dev_priv->pg; + unsigned long phys_addr = (unsigned long)pg->stolen_base;; + + page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; + + address = (unsigned long)vmf->virtual_address; + + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + for (i = 0; i < page_num; i++) { + pfn = (phys_addr >> PAGE_SHIFT); /* phys_to_pfn(phys_addr); */ + + ret = vm_insert_mixed(vma, address, pfn); + if (unlikely((ret == -EBUSY) || (ret != 0 && i > 0))) + break; + else if (unlikely(ret != 0)) { + ret = (ret == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS; + return ret; + } + + address += PAGE_SIZE; + phys_addr += PAGE_SIZE; + } + + return VM_FAULT_NOPAGE; +} + +static void psbfb_vm_open(struct vm_area_struct *vma) +{ + DRM_DEBUG("vm_open\n"); +} + +static void psbfb_vm_close(struct vm_area_struct *vma) +{ + DRM_DEBUG("vm_close\n"); +} + +static struct vm_operations_struct psbfb_vm_ops = { + .fault = psbfb_vm_fault, + .open = psbfb_vm_open, + .close = psbfb_vm_close +}; + +static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma) +{ + struct psb_fbdev *fbdev = info->par; + struct psb_framebuffer *psbfb = fbdev->pfb; + char *fb_screen_base = NULL; + struct drm_device *dev = psbfb->base.dev; + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_gtt *pg = dev_priv->pg; + + if (vma->vm_pgoff != 0) + return -EINVAL; + if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) + return -EINVAL; + + if (!psbfb->addr_space) + psbfb->addr_space = vma->vm_file->f_mapping; + + fb_screen_base = (char *)info->screen_base; + + DRM_DEBUG("vm_pgoff 0x%lx, screen base %p vram_addr %p\n", + vma->vm_pgoff, fb_screen_base, pg->vram_addr); + + /*if using stolen memory, */ + if (fb_screen_base == pg->vram_addr) { + vma->vm_ops = &psbfb_vm_ops; + vma->vm_private_data = (void *)psbfb; + vma->vm_flags |= VM_RESERVED | VM_IO | + VM_MIXEDMAP | VM_DONTEXPAND; + } else { + /*using IMG meminfo, can I use pvrmmap to map it?*/ + + } + + return 0; +} + + +static struct fb_ops psbfb_ops = { + .owner = THIS_MODULE, + .fb_check_var = drm_fb_helper_check_var, + .fb_set_par = drm_fb_helper_set_par, + .fb_blank = drm_fb_helper_blank, + .fb_setcolreg = psbfb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_mmap = psbfb_mmap, +}; + +static struct drm_framebuffer *psb_framebuffer_create + (struct drm_device *dev, struct drm_mode_fb_cmd *r, + void *mm_private) +{ + struct psb_framebuffer *fb; + int ret; + + fb = kzalloc(sizeof(*fb), GFP_KERNEL); + if (!fb) + return NULL; + + ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs); + + if (ret) + goto err; + + drm_helper_mode_fill_fb_struct(&fb->base, r); + + fb->bo = mm_private; + + return &fb->base; + +err: + kfree(fb); + return NULL; +} + +static struct drm_framebuffer *psb_user_framebuffer_create + (struct drm_device *dev, struct drm_file *filp, + struct drm_mode_fb_cmd *r) +{ + struct ttm_buffer_object *bo = NULL; + uint64_t size; + + bo = ttm_buffer_object_lookup(psb_fpriv(filp)->tfile, r->handle); + if (!bo) + return NULL; + + /* JB: TODO not drop, make smarter */ + size = ((uint64_t) bo->num_pages) << PAGE_SHIFT; + if (size < r->width * r->height * 4) + return NULL; + + /* JB: TODO not drop, refcount buffer */ + return psb_framebuffer_create(dev, r, bo); + +#if 0 + struct psb_framebuffer *psbfb; + struct drm_framebuffer *fb; + struct fb_info *info; + void *psKernelMemInfo = NULL; + void * hKernelMemInfo = (void *)r->handle; + struct drm_psb_private *dev_priv + = (struct drm_psb_private *)dev->dev_private; + struct psb_fbdev *fbdev = dev_priv->fbdev; + struct psb_gtt *pg = dev_priv->pg; + int ret; + uint32_t offset; + uint64_t size; + + ret = psb_get_meminfo_by_handle(hKernelMemInfo, &psKernelMemInfo); + if (ret) { + DRM_ERROR("Cannot get meminfo for handle 0x%x\n", + (u32)hKernelMemInfo); + return NULL; + } + + DRM_DEBUG("Got Kernel MemInfo for handle %lx\n", + (u32)hKernelMemInfo); + + /* JB: TODO not drop, make smarter */ + size = psKernelMemInfo->ui32AllocSize; + if (size < r->height * r->pitch) + return NULL; + + /* JB: TODO not drop, refcount buffer */ + /* return psb_framebuffer_create(dev, r, bo); */ + + fb = psb_framebuffer_create(dev, r, (void *)psKernelMemInfo); + if (!fb) { + DRM_ERROR("failed to allocate fb.\n"); + return NULL; + } + + psbfb = to_psb_fb(fb); + psbfb->size = size; + psbfb->hKernelMemInfo = hKernelMemInfo; + + DRM_DEBUG("Mapping to gtt..., KernelMemInfo %p\n", psKernelMemInfo); + + /*if not VRAM, map it into tt aperture*/ + if (psKernelMemInfo->pvLinAddrKM != pg->vram_addr) { + ret = psb_gtt_map_meminfo(dev, hKernelMemInfo, &offset); + if (ret) { + DRM_ERROR("map meminfo for 0x%x failed\n", + (u32)hKernelMemInfo); + return NULL; + } + psbfb->offset = (offset << PAGE_SHIFT); + } else { + psbfb->offset = 0; + } + info = framebuffer_alloc(0, &dev->pdev->dev); + if (!info) + return NULL; + + strcpy(info->fix.id, "psbfb"); + + info->flags = FBINFO_DEFAULT; + info->fbops = &psbfb_ops; + + info->fix.smem_start = dev->mode_config.fb_base; + info->fix.smem_len = size; + + info->screen_base = psKernelMemInfo->pvLinAddrKM; + info->screen_size = size; + + drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); + drm_fb_helper_fill_var(info, &fbdev->psb_fb_helper, + fb->width, fb->height); + + info->fix.mmio_start = pci_resource_start(dev->pdev, 0); + info->fix.mmio_len = pci_resource_len(dev->pdev, 0); + + info->pixmap.size = 64 * 1024; + info->pixmap.buf_align = 8; + info->pixmap.access_align = 32; + info->pixmap.flags = FB_PIXMAP_SYSTEM; + info->pixmap.scan_align = 1; + + psbfb->fbdev = info; + fbdev->pfb = psbfb; + + fbdev->psb_fb_helper.fb = fb; + fbdev->psb_fb_helper.fbdev = info; + MRSTLFBHandleChangeFB(dev, psbfb); + + return fb; +#endif +} + +static int psbfb_create(struct psb_fbdev *fbdev, + struct drm_fb_helper_surface_size *sizes) +{ + struct drm_device *dev = fbdev->psb_fb_helper.dev; + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_gtt *pg = dev_priv->pg; + struct fb_info *info; + struct drm_framebuffer *fb; + struct psb_framebuffer *psbfb; + struct drm_mode_fb_cmd mode_cmd; + struct device *device = &dev->pdev->dev; + + struct ttm_buffer_object *fbo = NULL; + int size, aligned_size; + int ret; + + mode_cmd.width = sizes->surface_width; + mode_cmd.height = sizes->surface_height; + + mode_cmd.bpp = 32; + /* HW requires pitch to be 64 byte aligned */ + mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 1) / 8), 64); + mode_cmd.depth = 24; + + size = mode_cmd.pitch * mode_cmd.height; + aligned_size = ALIGN(size, PAGE_SIZE); + + mutex_lock(&dev->struct_mutex); + fb = psb_framebuffer_create(dev, &mode_cmd, fbo); + if (!fb) { + DRM_ERROR("failed to allocate fb.\n"); + ret = -ENOMEM; + goto out_err0; + } + psbfb = to_psb_fb(fb); + psbfb->size = size; + + info = framebuffer_alloc(sizeof(struct psb_fbdev), device); + if (!info) { + ret = -ENOMEM; + goto out_err1; + } + + info->par = fbdev; + + psbfb->fbdev = info; + + fbdev->psb_fb_helper.fb = fb; + fbdev->psb_fb_helper.fbdev = info; + fbdev->pfb = psbfb; + + strcpy(info->fix.id, "psbfb"); + + info->flags = FBINFO_DEFAULT; + info->fbops = &psbfb_ops; + info->fix.smem_start = dev->mode_config.fb_base; + info->fix.smem_len = size; + info->screen_base = (char *)pg->vram_addr; + info->screen_size = size; + memset(info->screen_base, 0, size); + + drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); + drm_fb_helper_fill_var(info, &fbdev->psb_fb_helper, + sizes->fb_width, sizes->fb_height); + + info->fix.mmio_start = pci_resource_start(dev->pdev, 0); + info->fix.mmio_len = pci_resource_len(dev->pdev, 0); + + info->pixmap.size = 64 * 1024; + info->pixmap.buf_align = 8; + info->pixmap.access_align = 32; + info->pixmap.flags = FB_PIXMAP_SYSTEM; + info->pixmap.scan_align = 1; + + DRM_DEBUG("fb depth is %d\n", fb->depth); + DRM_DEBUG(" pitch is %d\n", fb->pitch); + + printk(KERN_INFO"allocated %dx%d fb\n", + psbfb->base.width, psbfb->base.height); + + mutex_unlock(&dev->struct_mutex); + + return 0; +out_err0: + fb->funcs->destroy(fb); +out_err1: + mutex_unlock(&dev->struct_mutex); + return ret; +} + +static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, + u16 blue, int regno) +{ + DRM_DEBUG("%s\n", __func__); +} + +static void psbfb_gamma_get(struct drm_crtc *crtc, u16 *red, + u16 *green, u16 *blue, int regno) +{ + DRM_DEBUG("%s\n", __func__); +} + +static int psbfb_probe(struct drm_fb_helper *helper, + struct drm_fb_helper_surface_size *sizes) +{ + struct psb_fbdev *psb_fbdev = (struct psb_fbdev *)helper; + int new_fb = 0; + int ret; + + DRM_DEBUG("%s\n", __func__); + + if (!helper->fb) { + ret = psbfb_create(psb_fbdev, sizes); + if (ret) + return ret; + new_fb = 1; + } + return new_fb; +} + +struct drm_fb_helper_funcs psb_fb_helper_funcs = { + .gamma_set = psbfb_gamma_set, + .gamma_get = psbfb_gamma_get, + .fb_probe = psbfb_probe, +}; + +int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev) +{ + struct fb_info *info; + struct psb_framebuffer *psbfb = fbdev->pfb; + + if (fbdev->psb_fb_helper.fbdev) { + info = fbdev->psb_fb_helper.fbdev; + unregister_framebuffer(info); + iounmap(info->screen_base); + framebuffer_release(info); + } + + drm_fb_helper_fini(&fbdev->psb_fb_helper); + + drm_framebuffer_cleanup(&psbfb->base); + + return 0; +} + +int psb_fbdev_init(struct drm_device *dev) +{ + struct psb_fbdev *fbdev; + struct drm_psb_private *dev_priv = dev->dev_private; + int num_crtc; + + fbdev = kzalloc(sizeof(struct psb_fbdev), GFP_KERNEL); + if (!fbdev) { + DRM_ERROR("no memory\n"); + return -ENOMEM; + } + + dev_priv->fbdev = fbdev; + fbdev->psb_fb_helper.funcs = &psb_fb_helper_funcs; + + num_crtc = 2; + + drm_fb_helper_init(dev, &fbdev->psb_fb_helper, num_crtc, + INTELFB_CONN_LIMIT); + + drm_fb_helper_single_add_all_connectors(&fbdev->psb_fb_helper); + drm_fb_helper_initial_config(&fbdev->psb_fb_helper, 32); + return 0; +} + +void psb_fbdev_fini(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + + if (!dev_priv->fbdev) + return; + + psb_fbdev_destroy(dev, dev_priv->fbdev); + kfree(dev_priv->fbdev); + dev_priv->fbdev = NULL; +} + + +static void psbfb_output_poll_changed(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_fbdev *fbdev = (struct psb_fbdev *)dev_priv->fbdev; + drm_fb_helper_hotplug_event(&fbdev->psb_fb_helper); +} + +int psbfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) +{ + struct fb_info *info; + struct psb_framebuffer *psbfb = to_psb_fb(fb); + + if (drm_psb_no_fb) + return 0; + + info = psbfb->fbdev; + psbfb->pvrBO = NULL; + + if (info) + framebuffer_release(info); + return 0; +} +/*EXPORT_SYMBOL(psbfb_remove); */ + +static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb, + struct drm_file *file_priv, + unsigned int *handle) +{ + /* JB: TODO currently we can't go from a bo to a handle with ttm */ + (void) file_priv; + *handle = 0; + return 0; +} + +static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb) +{ + struct drm_device *dev = fb->dev; + struct psb_framebuffer *psbfb = to_psb_fb(fb); + + /*ummap gtt pages*/ + psb_gtt_unmap_meminfo(dev, psbfb->hKernelMemInfo); + if (psbfb->fbdev) + psbfb_remove(dev, fb); + + /* JB: TODO not drop, refcount buffer */ + drm_framebuffer_cleanup(fb); + kfree(fb); +} + +static const struct drm_mode_config_funcs psb_mode_funcs = { + .fb_create = psb_user_framebuffer_create, + .output_poll_changed = psbfb_output_poll_changed, +}; + +static int psb_create_backlight_property(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv + = (struct drm_psb_private *) dev->dev_private; + struct drm_property *backlight; + + if (dev_priv->backlight_property) + return 0; + + backlight = drm_property_create(dev, + DRM_MODE_PROP_RANGE, + "backlight", + 2); + backlight->values[0] = 0; + backlight->values[1] = 100; + + dev_priv->backlight_property = backlight; + + return 0; +} + +static void psb_setup_outputs(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) dev->dev_private; + struct drm_connector *connector; + + PSB_DEBUG_ENTRY("\n"); + + drm_mode_create_scaling_mode_property(dev); + + psb_create_backlight_property(dev); + + psb_intel_lvds_init(dev, &dev_priv->mode_dev); + /* psb_intel_sdvo_init(dev, SDVOB); */ + + list_for_each_entry(connector, &dev->mode_config.connector_list, + head) { + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + struct drm_encoder *encoder = &psb_intel_output->enc; + int crtc_mask = 0, clone_mask = 0; + + /* valid crtcs */ + switch (psb_intel_output->type) { + case INTEL_OUTPUT_SDVO: + crtc_mask = ((1 << 0) | (1 << 1)); + clone_mask = (1 << INTEL_OUTPUT_SDVO); + break; + case INTEL_OUTPUT_LVDS: + PSB_DEBUG_ENTRY("LVDS.\n"); + crtc_mask = (1 << 1); + clone_mask = (1 << INTEL_OUTPUT_LVDS); + break; + case INTEL_OUTPUT_MIPI: + PSB_DEBUG_ENTRY("MIPI.\n"); + crtc_mask = (1 << 0); + clone_mask = (1 << INTEL_OUTPUT_MIPI); + break; + case INTEL_OUTPUT_MIPI2: + PSB_DEBUG_ENTRY("MIPI2.\n"); + crtc_mask = (1 << 2); + clone_mask = (1 << INTEL_OUTPUT_MIPI2); + break; + case INTEL_OUTPUT_HDMI: + PSB_DEBUG_ENTRY("HDMI.\n"); + crtc_mask = (1 << 1); + clone_mask = (1 << INTEL_OUTPUT_HDMI); + break; + } + + encoder->possible_crtcs = crtc_mask; + encoder->possible_clones = + psb_intel_connector_clones(dev, clone_mask); + + } +} + +static void *psb_bo_from_handle(struct drm_device *dev, + struct drm_file *file_priv, + unsigned int handle) +{ + void *psKernelMemInfo = NULL; + void * hKernelMemInfo = (void *)handle; + int ret; + + ret = psb_get_meminfo_by_handle(hKernelMemInfo, &psKernelMemInfo); + if (ret) { + DRM_ERROR("Cannot get meminfo for handle 0x%x\n", + (u32)hKernelMemInfo); + return NULL; + } + + return (void *)psKernelMemInfo; +} + +static size_t psb_bo_size(struct drm_device *dev, void *bof) +{ +#if 0 + void *psKernelMemInfo = (void *)bof; + return (size_t)psKernelMemInfo->ui32AllocSize; +#else + return 0; +#endif +} + +static size_t psb_bo_offset(struct drm_device *dev, void *bof) +{ + struct psb_framebuffer *psbfb + = (struct psb_framebuffer *)bof; + + return (size_t)psbfb->offset; +} + +static int psb_bo_pin_for_scanout(struct drm_device *dev, void *bo) +{ + return 0; +} + +static int psb_bo_unpin_for_scanout(struct drm_device *dev, void *bo) +{ + return 0; +} + +void psb_modeset_init(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) dev->dev_private; + struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; + int i; + + PSB_DEBUG_ENTRY("\n"); + /* Init mm functions */ + mode_dev->bo_from_handle = psb_bo_from_handle; + mode_dev->bo_size = psb_bo_size; + mode_dev->bo_offset = psb_bo_offset; + mode_dev->bo_pin_for_scanout = psb_bo_pin_for_scanout; + mode_dev->bo_unpin_for_scanout = psb_bo_unpin_for_scanout; + + drm_mode_config_init(dev); + + dev->mode_config.min_width = 0; + dev->mode_config.min_height = 0; + + dev->mode_config.funcs = (void *) &psb_mode_funcs; + + /* set memory base */ + /* MRST and PSB should use BAR 2*/ + pci_read_config_dword(dev->pdev, PSB_BSM, (u32 *) + &(dev->mode_config.fb_base)); + + /* num pipes is 2 for PSB but 1 for Mrst */ + for (i = 0; i < dev_priv->num_pipe; i++) + psb_intel_crtc_init(dev, i, mode_dev); + + dev->mode_config.max_width = 2048; + dev->mode_config.max_height = 2048; + + psb_setup_outputs(dev); + + /* setup fbs */ + /* drm_initial_config(dev); */ +} + +void psb_modeset_cleanup(struct drm_device *dev) +{ + mutex_lock(&dev->struct_mutex); + + drm_kms_helper_poll_fini(dev); + psb_fbdev_fini(dev); + + drm_mode_config_cleanup(dev); + + mutex_unlock(&dev->struct_mutex); +} diff --git a/drivers/staging/gma500/psb_fb.h b/drivers/staging/gma500/psb_fb.h new file mode 100644 index 000000000000..d39d84ddab50 --- /dev/null +++ b/drivers/staging/gma500/psb_fb.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2008, Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Authors: + * Eric Anholt + * + */ + +#ifndef _PSB_FB_H_ +#define _PSB_FB_H_ + +#include +#include +#include + +#include "psb_drv.h" + +/*IMG Headers*/ +/*#include "servicesint.h"*/ + +struct psb_framebuffer { + struct drm_framebuffer base; + struct address_space *addr_space; + struct ttm_buffer_object *bo; + struct fb_info * fbdev; + /* struct ttm_bo_kmap_obj kmap; */ + void *pvrBO; /* FIXME: sort this out */ + void * hKernelMemInfo; + uint32_t size; + uint32_t offset; +}; + +struct psb_fbdev { + struct drm_fb_helper psb_fb_helper; + struct psb_framebuffer * pfb; +}; + + +#define to_psb_fb(x) container_of(x, struct psb_framebuffer, base) + + +extern int psb_intel_connector_clones(struct drm_device *dev, int type_mask); + + +#endif + diff --git a/drivers/staging/gma500/psb_fence.c b/drivers/staging/gma500/psb_fence.c new file mode 100644 index 000000000000..a70aa64f2cad --- /dev/null +++ b/drivers/staging/gma500/psb_fence.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2007, Intel Corporation. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * + * Authors: Thomas Hellstrom + */ + +#include +#include "psb_drv.h" + + +static void psb_fence_poll(struct ttm_fence_device *fdev, + uint32_t fence_class, uint32_t waiting_types) +{ + struct drm_psb_private *dev_priv = + container_of(fdev, struct drm_psb_private, fdev); + + + if (unlikely(!dev_priv)) + return; + + if (waiting_types == 0) + return; + + /* DRM_ERROR("Polling fence sequence, got 0x%08x\n", sequence); */ + ttm_fence_handler(fdev, fence_class, 0 /* Sequence */, + _PSB_FENCE_TYPE_EXE, 0); +} + +void psb_fence_error(struct drm_device *dev, + uint32_t fence_class, + uint32_t sequence, uint32_t type, int error) +{ + struct drm_psb_private *dev_priv = psb_priv(dev); + struct ttm_fence_device *fdev = &dev_priv->fdev; + unsigned long irq_flags; + struct ttm_fence_class_manager *fc = + &fdev->fence_class[fence_class]; + + BUG_ON(fence_class >= PSB_NUM_ENGINES); + write_lock_irqsave(&fc->lock, irq_flags); + ttm_fence_handler(fdev, fence_class, sequence, type, error); + write_unlock_irqrestore(&fc->lock, irq_flags); +} + +int psb_fence_emit_sequence(struct ttm_fence_device *fdev, + uint32_t fence_class, + uint32_t flags, uint32_t *sequence, + unsigned long *timeout_jiffies) +{ + struct drm_psb_private *dev_priv = + container_of(fdev, struct drm_psb_private, fdev); + + if (!dev_priv) + return -EINVAL; + + if (fence_class >= PSB_NUM_ENGINES) + return -EINVAL; + + DRM_ERROR("Unexpected fence class\n"); + return -EINVAL; +} + +static void psb_fence_lockup(struct ttm_fence_object *fence, + uint32_t fence_types) +{ + DRM_ERROR("Unsupported fence class\n"); +} + +void psb_fence_handler(struct drm_device *dev, uint32_t fence_class) +{ + struct drm_psb_private *dev_priv = psb_priv(dev); + struct ttm_fence_device *fdev = &dev_priv->fdev; + struct ttm_fence_class_manager *fc = + &fdev->fence_class[fence_class]; + unsigned long irq_flags; + + write_lock_irqsave(&fc->lock, irq_flags); + psb_fence_poll(fdev, fence_class, fc->waiting_types); + write_unlock_irqrestore(&fc->lock, irq_flags); +} + + +static struct ttm_fence_driver psb_ttm_fence_driver = { + .has_irq = NULL, + .emit = psb_fence_emit_sequence, + .flush = NULL, + .poll = psb_fence_poll, + .needed_flush = NULL, + .wait = NULL, + .signaled = NULL, + .lockup = psb_fence_lockup, +}; + +int psb_ttm_fence_device_init(struct ttm_fence_device *fdev) +{ + struct drm_psb_private *dev_priv = + container_of(fdev, struct drm_psb_private, fdev); + struct ttm_fence_class_init fci = {.wrap_diff = (1 << 30), + .flush_diff = (1 << 29), + .sequence_mask = 0xFFFFFFFF + }; + + return ttm_fence_device_init(PSB_NUM_ENGINES, + dev_priv->mem_global_ref.object, + fdev, &fci, 1, + &psb_ttm_fence_driver); +} diff --git a/drivers/staging/gma500/psb_gfx.mod.c b/drivers/staging/gma500/psb_gfx.mod.c new file mode 100644 index 000000000000..1a663ab44400 --- /dev/null +++ b/drivers/staging/gma500/psb_gfx.mod.c @@ -0,0 +1,27 @@ +#include +#include +#include + +MODULE_INFO(vermagic, VERMAGIC_STRING); + +struct module __this_module +__attribute__((section(".gnu.linkonce.this_module"))) = { + .name = KBUILD_MODNAME, + .init = init_module, +#ifdef CONFIG_MODULE_UNLOAD + .exit = cleanup_module, +#endif + .arch = MODULE_ARCH_INIT, +}; + +MODULE_INFO(staging, "Y"); + +static const char __module_depends[] +__used +__attribute__((section(".modinfo"))) = +"depends=ttm,drm,drm_kms_helper,i2c-core,cfbfillrect,cfbimgblt,cfbcopyarea,i2c-algo-bit"; + +MODULE_ALIAS("pci:v00008086d00008108sv*sd*bc*sc*i*"); +MODULE_ALIAS("pci:v00008086d00008109sv*sd*bc*sc*i*"); + +MODULE_INFO(srcversion, "933CCC78041722973001B78"); diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c new file mode 100644 index 000000000000..53c1e1ed3bd2 --- /dev/null +++ b/drivers/staging/gma500/psb_gtt.c @@ -0,0 +1,1034 @@ +/* + * Copyright (c) 2007, Intel Corporation. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Authors: Thomas Hellstrom + */ + +#include +#include "psb_drv.h" +#include "psb_pvr_glue.h" + +static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type) +{ + uint32_t mask = PSB_PTE_VALID; + + if (type & PSB_MMU_CACHED_MEMORY) + mask |= PSB_PTE_CACHED; + if (type & PSB_MMU_RO_MEMORY) + mask |= PSB_PTE_RO; + if (type & PSB_MMU_WO_MEMORY) + mask |= PSB_PTE_WO; + + return (pfn << PAGE_SHIFT) | mask; +} + +struct psb_gtt *psb_gtt_alloc(struct drm_device *dev) +{ + struct psb_gtt *tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); + + if (!tmp) + return NULL; + + init_rwsem(&tmp->sem); + tmp->dev = dev; + + return tmp; +} + +void psb_gtt_takedown(struct psb_gtt *pg, int free) +{ + struct drm_psb_private *dev_priv = pg->dev->dev_private; + + if (!pg) + return; + + if (pg->gtt_map) { + iounmap(pg->gtt_map); + pg->gtt_map = NULL; + } + if (pg->initialized) { + pci_write_config_word(pg->dev->pdev, PSB_GMCH_CTRL, + pg->gmch_ctrl); + PSB_WVDC32(pg->pge_ctl, PSB_PGETBL_CTL); + (void) PSB_RVDC32(PSB_PGETBL_CTL); + } + if (free) + kfree(pg); +} + +int psb_gtt_init(struct psb_gtt *pg, int resume) +{ + struct drm_device *dev = pg->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + unsigned gtt_pages; + unsigned long stolen_size, vram_stolen_size, ci_stolen_size; + unsigned long rar_stolen_size; + unsigned i, num_pages; + unsigned pfn_base; + uint32_t ci_pages, vram_pages; + uint32_t tt_pages; + uint32_t *ttm_gtt_map; + uint32_t dvmt_mode = 0; + + int ret = 0; + uint32_t pte; + + pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &pg->gmch_ctrl); + pci_write_config_word(dev->pdev, PSB_GMCH_CTRL, + pg->gmch_ctrl | _PSB_GMCH_ENABLED); + + pg->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL); + PSB_WVDC32(pg->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL); + (void) PSB_RVDC32(PSB_PGETBL_CTL); + + pg->initialized = 1; + + pg->gtt_phys_start = pg->pge_ctl & PAGE_MASK; + + pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE); + /* fix me: video mmu has hw bug to access 0x0D0000000, + * then make gatt start at 0x0e000,0000 */ + pg->mmu_gatt_start = PSB_MEM_TT_START; + pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE); + gtt_pages = + pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT; + pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE) + >> PAGE_SHIFT; + + pci_read_config_dword(dev->pdev, PSB_BSM, &pg->stolen_base); + vram_stolen_size = pg->gtt_phys_start - pg->stolen_base - PAGE_SIZE; + + /* CI is not included in the stolen size since the TOPAZ MMU bug */ + ci_stolen_size = dev_priv->ci_region_size; + /* Don't add CI & RAR share buffer space + * managed by TTM to stolen_size */ + stolen_size = vram_stolen_size; + + rar_stolen_size = dev_priv->rar_region_size; + + printk(KERN_INFO"GMMADR(region 0) start: 0x%08x (%dM).\n", + pg->gatt_start, pg->gatt_pages/256); + printk(KERN_INFO"GTTADR(region 3) start: 0x%08x (can map %dM RAM), and actual RAM base 0x%08x.\n", + pg->gtt_start, gtt_pages * 4, pg->gtt_phys_start); + printk(KERN_INFO "Stole memory information\n"); + printk(KERN_INFO " base in RAM: 0x%x\n", pg->stolen_base); + printk(KERN_INFO " size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n", + vram_stolen_size/1024); + dvmt_mode = (pg->gmch_ctrl >> 4) & 0x7; + printk(KERN_INFO " the correct size should be: %dM(dvmt mode=%d)\n", + (dvmt_mode == 1) ? 1 : (2 << (dvmt_mode - 1)), dvmt_mode); + + if (ci_stolen_size > 0) + printk(KERN_INFO"CI Stole memory: RAM base = 0x%08x, size = %lu M\n", + dev_priv->ci_region_start, + ci_stolen_size / 1024 / 1024); + if (rar_stolen_size > 0) + printk(KERN_INFO "RAR Stole memory: RAM base = 0x%08x, size = %lu M\n", + dev_priv->rar_region_start, + rar_stolen_size / 1024 / 1024); + + if (resume && (gtt_pages != pg->gtt_pages) && + (stolen_size != pg->stolen_size)) { + DRM_ERROR("GTT resume error.\n"); + ret = -EINVAL; + goto out_err; + } + + pg->gtt_pages = gtt_pages; + pg->stolen_size = stolen_size; + pg->vram_stolen_size = vram_stolen_size; + pg->ci_stolen_size = ci_stolen_size; + pg->rar_stolen_size = rar_stolen_size; + pg->gtt_map = + ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT); + if (!pg->gtt_map) { + DRM_ERROR("Failure to map gtt.\n"); + ret = -ENOMEM; + goto out_err; + } + + pg->vram_addr = ioremap_wc(pg->stolen_base, stolen_size); + if (!pg->vram_addr) { + DRM_ERROR("Failure to map stolen base.\n"); + ret = -ENOMEM; + goto out_err; + } + + DRM_DEBUG("%s: vram kernel virtual address %p\n", pg->vram_addr); + + tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ? + (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT; + + ttm_gtt_map = pg->gtt_map + tt_pages / 2; + + /* + * insert vram stolen pages. + */ + + pfn_base = pg->stolen_base >> PAGE_SHIFT; + vram_pages = num_pages = vram_stolen_size >> PAGE_SHIFT; + printk(KERN_INFO"Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n", + num_pages, pfn_base, 0); + for (i = 0; i < num_pages; ++i) { + pte = psb_gtt_mask_pte(pfn_base + i, 0); + iowrite32(pte, pg->gtt_map + i); + } + + /* + * Init rest of gtt managed by IMG. + */ + pfn_base = page_to_pfn(dev_priv->scratch_page); + pte = psb_gtt_mask_pte(pfn_base, 0); + for (; i < tt_pages / 2 - 1; ++i) + iowrite32(pte, pg->gtt_map + i); + + /* + * insert CI stolen pages + */ + + pfn_base = dev_priv->ci_region_start >> PAGE_SHIFT; + ci_pages = num_pages = ci_stolen_size >> PAGE_SHIFT; + printk(KERN_INFO"Set up %d CI stolen pages starting at 0x%08x, GTT offset %dK\n", + num_pages, pfn_base, (ttm_gtt_map - pg->gtt_map) * 4); + for (i = 0; i < num_pages; ++i) { + pte = psb_gtt_mask_pte(pfn_base + i, 0); + iowrite32(pte, ttm_gtt_map + i); + } + + /* + * insert RAR stolen pages + */ + if (rar_stolen_size != 0) { + pfn_base = dev_priv->rar_region_start >> PAGE_SHIFT; + num_pages = rar_stolen_size >> PAGE_SHIFT; + printk(KERN_INFO"Set up %d RAR stolen pages starting at 0x%08x, GTT offset %dK\n", + num_pages, pfn_base, + (ttm_gtt_map - pg->gtt_map + i) * 4); + for (; i < num_pages + ci_pages; ++i) { + pte = psb_gtt_mask_pte(pfn_base + i - ci_pages, 0); + iowrite32(pte, ttm_gtt_map + i); + } + } + /* + * Init rest of gtt managed by TTM. + */ + + pfn_base = page_to_pfn(dev_priv->scratch_page); + pte = psb_gtt_mask_pte(pfn_base, 0); + PSB_DEBUG_INIT("Initializing the rest of a total " + "of %d gtt pages.\n", pg->gatt_pages); + + for (; i < pg->gatt_pages - tt_pages / 2; ++i) + iowrite32(pte, ttm_gtt_map + i); + (void) ioread32(pg->gtt_map + i - 1); + + return 0; + +out_err: + psb_gtt_takedown(pg, 0); + return ret; +} + +int psb_gtt_insert_pages(struct psb_gtt *pg, struct page **pages, + unsigned offset_pages, unsigned num_pages, + unsigned desired_tile_stride, + unsigned hw_tile_stride, int type) +{ + unsigned rows = 1; + unsigned add; + unsigned row_add; + unsigned i; + unsigned j; + uint32_t *cur_page = NULL; + uint32_t pte; + + if (hw_tile_stride) + rows = num_pages / desired_tile_stride; + else + desired_tile_stride = num_pages; + + add = desired_tile_stride; + row_add = hw_tile_stride; + + down_read(&pg->sem); + for (i = 0; i < rows; ++i) { + cur_page = pg->gtt_map + offset_pages; + for (j = 0; j < desired_tile_stride; ++j) { + pte = + psb_gtt_mask_pte(page_to_pfn(*pages++), type); + iowrite32(pte, cur_page++); + } + offset_pages += add; + } + (void) ioread32(cur_page - 1); + up_read(&pg->sem); + + return 0; +} + +int psb_gtt_insert_phys_addresses(struct psb_gtt *pg, dma_addr_t *pPhysFrames, + unsigned offset_pages, unsigned num_pages, int type) +{ + unsigned j; + uint32_t *cur_page = NULL; + uint32_t pte; + u32 ba; + + down_read(&pg->sem); + cur_page = pg->gtt_map + offset_pages; + for (j = 0; j < num_pages; ++j) { + ba = *pPhysFrames++; + pte = psb_gtt_mask_pte(ba >> PAGE_SHIFT, type); + iowrite32(pte, cur_page++); + } + (void) ioread32(cur_page - 1); + up_read(&pg->sem); + return 0; +} + +int psb_gtt_remove_pages(struct psb_gtt *pg, unsigned offset_pages, + unsigned num_pages, unsigned desired_tile_stride, + unsigned hw_tile_stride, int rc_prot) +{ + struct drm_psb_private *dev_priv = pg->dev->dev_private; + unsigned rows = 1; + unsigned add; + unsigned row_add; + unsigned i; + unsigned j; + uint32_t *cur_page = NULL; + unsigned pfn_base = page_to_pfn(dev_priv->scratch_page); + uint32_t pte = psb_gtt_mask_pte(pfn_base, 0); + + if (hw_tile_stride) + rows = num_pages / desired_tile_stride; + else + desired_tile_stride = num_pages; + + add = desired_tile_stride; + row_add = hw_tile_stride; + + if (rc_prot) + down_read(&pg->sem); + for (i = 0; i < rows; ++i) { + cur_page = pg->gtt_map + offset_pages; + for (j = 0; j < desired_tile_stride; ++j) + iowrite32(pte, cur_page++); + + offset_pages += add; + } + (void) ioread32(cur_page - 1); + if (rc_prot) + up_read(&pg->sem); + + return 0; +} + +int psb_gtt_mm_init(struct psb_gtt *pg) +{ + struct psb_gtt_mm *gtt_mm; + struct drm_psb_private *dev_priv = pg->dev->dev_private; + struct drm_open_hash *ht; + struct drm_mm *mm; + int ret; + uint32_t tt_start; + uint32_t tt_size; + + if (!pg || !pg->initialized) { + DRM_DEBUG("Invalid gtt struct\n"); + return -EINVAL; + } + + gtt_mm = kzalloc(sizeof(struct psb_gtt_mm), GFP_KERNEL); + if (!gtt_mm) + return -ENOMEM; + + spin_lock_init(>t_mm->lock); + + ht = >t_mm->hash; + ret = drm_ht_create(ht, 20); + if (ret) { + DRM_DEBUG("Create hash table failed(%d)\n", ret); + goto err_free; + } + + tt_start = (pg->stolen_size + PAGE_SIZE - 1) >> PAGE_SHIFT; + tt_start = (tt_start < pg->gatt_pages) ? tt_start : pg->gatt_pages; + tt_size = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ? + (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT; + + mm = >t_mm->base; + + /*will use tt_start ~ 128M for IMG TT buffers*/ + ret = drm_mm_init(mm, tt_start, ((tt_size / 2) - tt_start)); + if (ret) { + DRM_DEBUG("drm_mm_int error(%d)\n", ret); + goto err_mm_init; + } + + gtt_mm->count = 0; + + dev_priv->gtt_mm = gtt_mm; + + DRM_INFO("PSB GTT mem manager ready, tt_start %ld, tt_size %ld pages\n", + (unsigned long)tt_start, + (unsigned long)((tt_size / 2) - tt_start)); + return 0; +err_mm_init: + drm_ht_remove(ht); + +err_free: + kfree(gtt_mm); + return ret; +} + +/** + * Delete all hash entries; + */ +void psb_gtt_mm_takedown(void) +{ + return; +} + +static int psb_gtt_mm_get_ht_by_pid_locked(struct psb_gtt_mm *mm, + u32 tgid, + struct psb_gtt_hash_entry **hentry) +{ + struct drm_hash_item *entry; + struct psb_gtt_hash_entry *psb_entry; + int ret; + + ret = drm_ht_find_item(&mm->hash, tgid, &entry); + if (ret) { + DRM_DEBUG("Cannot find entry pid=%ld\n", tgid); + return ret; + } + + psb_entry = container_of(entry, struct psb_gtt_hash_entry, item); + if (!psb_entry) { + DRM_DEBUG("Invalid entry"); + return -EINVAL; + } + + *hentry = psb_entry; + return 0; +} + + +static int psb_gtt_mm_insert_ht_locked(struct psb_gtt_mm *mm, + u32 tgid, + struct psb_gtt_hash_entry *hentry) +{ + struct drm_hash_item *item; + int ret; + + if (!hentry) { + DRM_DEBUG("Invalid parameters\n"); + return -EINVAL; + } + + item = &hentry->item; + item->key = tgid; + + /** + * NOTE: drm_ht_insert_item will perform such a check + ret = psb_gtt_mm_get_ht_by_pid(mm, tgid, &tmp); + if (!ret) { + DRM_DEBUG("Entry already exists for pid %ld\n", tgid); + return -EAGAIN; + } + */ + + /*Insert the given entry*/ + ret = drm_ht_insert_item(&mm->hash, item); + if (ret) { + DRM_DEBUG("Insert failure\n"); + return ret; + } + + mm->count++; + + return 0; +} + +static int psb_gtt_mm_alloc_insert_ht(struct psb_gtt_mm *mm, + u32 tgid, + struct psb_gtt_hash_entry **entry) +{ + struct psb_gtt_hash_entry *hentry; + int ret; + + /*if the hentry for this tgid exists, just get it and return*/ + spin_lock(&mm->lock); + ret = psb_gtt_mm_get_ht_by_pid_locked(mm, tgid, &hentry); + if (!ret) { + DRM_DEBUG("Entry for tgid %ld exist, hentry %p\n", + tgid, hentry); + *entry = hentry; + spin_unlock(&mm->lock); + return 0; + } + spin_unlock(&mm->lock); + + DRM_DEBUG("Entry for tgid %ld doesn't exist, will create it\n", tgid); + + hentry = kzalloc(sizeof(struct psb_gtt_hash_entry), GFP_KERNEL); + if (!hentry) { + DRM_DEBUG("Kmalloc failled\n"); + return -ENOMEM; + } + + ret = drm_ht_create(&hentry->ht, 20); + if (ret) { + DRM_DEBUG("Create hash table failed\n"); + return ret; + } + + spin_lock(&mm->lock); + ret = psb_gtt_mm_insert_ht_locked(mm, tgid, hentry); + spin_unlock(&mm->lock); + + if (!ret) + *entry = hentry; + + return ret; +} + +static struct psb_gtt_hash_entry * +psb_gtt_mm_remove_ht_locked(struct psb_gtt_mm *mm, u32 tgid) +{ + struct psb_gtt_hash_entry *tmp; + int ret; + + ret = psb_gtt_mm_get_ht_by_pid_locked(mm, tgid, &tmp); + if (ret) { + DRM_DEBUG("Cannot find entry pid %ld\n", tgid); + return NULL; + } + + /*remove it from ht*/ + drm_ht_remove_item(&mm->hash, &tmp->item); + + mm->count--; + + return tmp; +} + +static int psb_gtt_mm_remove_free_ht_locked(struct psb_gtt_mm *mm, u32 tgid) +{ + struct psb_gtt_hash_entry *entry; + + entry = psb_gtt_mm_remove_ht_locked(mm, tgid); + + if (!entry) { + DRM_DEBUG("Invalid entry"); + return -EINVAL; + } + + /*delete ht*/ + drm_ht_remove(&entry->ht); + + /*free this entry*/ + kfree(entry); + return 0; +} + +static int +psb_gtt_mm_get_mem_mapping_locked(struct drm_open_hash *ht, + u32 key, + struct psb_gtt_mem_mapping **hentry) +{ + struct drm_hash_item *entry; + struct psb_gtt_mem_mapping *mapping; + int ret; + + ret = drm_ht_find_item(ht, key, &entry); + if (ret) { + DRM_DEBUG("Cannot find key %ld\n", key); + return ret; + } + + mapping = container_of(entry, struct psb_gtt_mem_mapping, item); + if (!mapping) { + DRM_DEBUG("Invalid entry\n"); + return -EINVAL; + } + + *hentry = mapping; + return 0; +} + +static int +psb_gtt_mm_insert_mem_mapping_locked(struct drm_open_hash *ht, + u32 key, + struct psb_gtt_mem_mapping *hentry) +{ + struct drm_hash_item *item; + struct psb_gtt_hash_entry *entry; + int ret; + + if (!hentry) { + DRM_DEBUG("hentry is NULL\n"); + return -EINVAL; + } + + item = &hentry->item; + item->key = key; + + ret = drm_ht_insert_item(ht, item); + if (ret) { + DRM_DEBUG("insert_item failed\n"); + return ret; + } + + entry = container_of(ht, struct psb_gtt_hash_entry, ht); + if (entry) + entry->count++; + + return 0; +} + +static int +psb_gtt_mm_alloc_insert_mem_mapping(struct psb_gtt_mm *mm, + struct drm_open_hash *ht, + u32 key, + struct drm_mm_node *node, + struct psb_gtt_mem_mapping **entry) +{ + struct psb_gtt_mem_mapping *mapping; + int ret; + + if (!node || !ht) { + DRM_DEBUG("parameter error\n"); + return -EINVAL; + } + + /*try to get this mem_map */ + spin_lock(&mm->lock); + ret = psb_gtt_mm_get_mem_mapping_locked(ht, key, &mapping); + if (!ret) { + DRM_DEBUG("mapping entry for key %ld exists, entry %p\n", + key, mapping); + *entry = mapping; + spin_unlock(&mm->lock); + return 0; + } + spin_unlock(&mm->lock); + + DRM_DEBUG("Mapping entry for key %ld doesn't exist, will create it\n", + key); + + mapping = kzalloc(sizeof(struct psb_gtt_mem_mapping), GFP_KERNEL); + if (!mapping) { + DRM_DEBUG("kmalloc failed\n"); + return -ENOMEM; + } + + mapping->node = node; + + spin_lock(&mm->lock); + ret = psb_gtt_mm_insert_mem_mapping_locked(ht, key, mapping); + spin_unlock(&mm->lock); + + if (!ret) + *entry = mapping; + + return ret; +} + +static struct psb_gtt_mem_mapping * +psb_gtt_mm_remove_mem_mapping_locked(struct drm_open_hash *ht, u32 key) +{ + struct psb_gtt_mem_mapping *tmp; + struct psb_gtt_hash_entry *entry; + int ret; + + ret = psb_gtt_mm_get_mem_mapping_locked(ht, key, &tmp); + if (ret) { + DRM_DEBUG("Cannot find key %ld\n", key); + return NULL; + } + + drm_ht_remove_item(ht, &tmp->item); + + entry = container_of(ht, struct psb_gtt_hash_entry, ht); + if (entry) + entry->count--; + + return tmp; +} + +static int psb_gtt_mm_remove_free_mem_mapping_locked(struct drm_open_hash *ht, + u32 key, + struct drm_mm_node **node) +{ + struct psb_gtt_mem_mapping *entry; + + entry = psb_gtt_mm_remove_mem_mapping_locked(ht, key); + if (!entry) { + DRM_DEBUG("entry is NULL\n"); + return -EINVAL; + } + + *node = entry->node; + + kfree(entry); + return 0; +} + +static int psb_gtt_add_node(struct psb_gtt_mm *mm, + u32 tgid, + u32 key, + struct drm_mm_node *node, + struct psb_gtt_mem_mapping **entry) +{ + struct psb_gtt_hash_entry *hentry; + struct psb_gtt_mem_mapping *mapping; + int ret; + + ret = psb_gtt_mm_alloc_insert_ht(mm, tgid, &hentry); + if (ret) { + DRM_DEBUG("alloc_insert failed\n"); + return ret; + } + + ret = psb_gtt_mm_alloc_insert_mem_mapping(mm, + &hentry->ht, + key, + node, + &mapping); + if (ret) { + DRM_DEBUG("mapping alloc_insert failed\n"); + return ret; + } + + *entry = mapping; + + return 0; +} + +static int psb_gtt_remove_node(struct psb_gtt_mm *mm, + u32 tgid, + u32 key, + struct drm_mm_node **node) +{ + struct psb_gtt_hash_entry *hentry; + struct drm_mm_node *tmp; + int ret; + + spin_lock(&mm->lock); + ret = psb_gtt_mm_get_ht_by_pid_locked(mm, tgid, &hentry); + if (ret) { + DRM_DEBUG("Cannot find entry for pid %ld\n", tgid); + spin_unlock(&mm->lock); + return ret; + } + spin_unlock(&mm->lock); + + /*remove mapping entry*/ + spin_lock(&mm->lock); + ret = psb_gtt_mm_remove_free_mem_mapping_locked(&hentry->ht, + key, + &tmp); + if (ret) { + DRM_DEBUG("remove_free failed\n"); + spin_unlock(&mm->lock); + return ret; + } + + *node = tmp; + + /*check the count of mapping entry*/ + if (!hentry->count) { + DRM_DEBUG("count of mapping entry is zero, tgid=%ld\n", tgid); + psb_gtt_mm_remove_free_ht_locked(mm, tgid); + } + + spin_unlock(&mm->lock); + + return 0; +} + +static int psb_gtt_mm_alloc_mem(struct psb_gtt_mm *mm, + uint32_t pages, + uint32_t align, + struct drm_mm_node **node) +{ + struct drm_mm_node *tmp_node; + int ret; + + do { + ret = drm_mm_pre_get(&mm->base); + if (unlikely(ret)) { + DRM_DEBUG("drm_mm_pre_get error\n"); + return ret; + } + + spin_lock(&mm->lock); + tmp_node = drm_mm_search_free(&mm->base, pages, align, 1); + if (unlikely(!tmp_node)) { + DRM_DEBUG("No free node found\n"); + spin_unlock(&mm->lock); + break; + } + + tmp_node = drm_mm_get_block_atomic(tmp_node, pages, align); + spin_unlock(&mm->lock); + } while (!tmp_node); + + if (!tmp_node) { + DRM_DEBUG("Node allocation failed\n"); + return -ENOMEM; + } + + *node = tmp_node; + return 0; +} + +static void psb_gtt_mm_free_mem(struct psb_gtt_mm *mm, struct drm_mm_node *node) +{ + spin_lock(&mm->lock); + drm_mm_put_block(node); + spin_unlock(&mm->lock); +} + +int psb_gtt_map_meminfo(struct drm_device *dev, + void *hKernelMemInfo, + uint32_t *offset) +{ + return -EINVAL; + /* FIXMEAC */ +#if 0 + struct drm_psb_private *dev_priv + = (struct drm_psb_private *)dev->dev_private; + void *psKernelMemInfo; + struct psb_gtt_mm *mm = dev_priv->gtt_mm; + struct psb_gtt *pg = dev_priv->pg; + uint32_t size, pages, offset_pages; + void *kmem; + struct drm_mm_node *node; + struct page **page_list; + struct psb_gtt_mem_mapping *mapping = NULL; + int ret; + + ret = psb_get_meminfo_by_handle(hKernelMemInfo, &psKernelMemInfo); + if (ret) { + DRM_DEBUG("Cannot find kernelMemInfo handle %ld\n", + hKernelMemInfo); + return -EINVAL; + } + + DRM_DEBUG("Got psKernelMemInfo %p for handle %lx\n", + psKernelMemInfo, (u32)hKernelMemInfo); + size = psKernelMemInfo->ui32AllocSize; + kmem = psKernelMemInfo->pvLinAddrKM; + pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; + + DRM_DEBUG("KerMemInfo size %ld, cpuVadr %lx, pages %ld, osMemHdl %lx\n", + size, kmem, pages, psKernelMemInfo->sMemBlk.hOSMemHandle); + + if (!kmem) + DRM_DEBUG("kmem is NULL"); + + /*get pages*/ + ret = psb_get_pages_by_mem_handle(psKernelMemInfo->sMemBlk.hOSMemHandle, + &page_list); + if (ret) { + DRM_DEBUG("get pages error\n"); + return ret; + } + + DRM_DEBUG("get %ld pages\n", pages); + + /*alloc memory in TT apeture*/ + ret = psb_gtt_mm_alloc_mem(mm, pages, 0, &node); + if (ret) { + DRM_DEBUG("alloc TT memory error\n"); + goto failed_pages_alloc; + } + + /*update psb_gtt_mm*/ + ret = psb_gtt_add_node(mm, + task_tgid_nr(current), + (u32)hKernelMemInfo, + node, + &mapping); + if (ret) { + DRM_DEBUG("add_node failed"); + goto failed_add_node; + } + + node = mapping->node; + offset_pages = node->start; + + DRM_DEBUG("get free node for %ld pages, offset %ld pages", + pages, offset_pages); + + /*update gtt*/ + psb_gtt_insert_pages(pg, page_list, + (unsigned)offset_pages, + (unsigned)pages, + 0, + 0, + 0); + + *offset = offset_pages; + return 0; + +failed_add_node: + psb_gtt_mm_free_mem(mm, node); +failed_pages_alloc: + kfree(page_list); + return ret; +#endif +} + +int psb_gtt_unmap_meminfo(struct drm_device *dev, void * hKernelMemInfo) +{ + struct drm_psb_private *dev_priv + = (struct drm_psb_private *)dev->dev_private; + struct psb_gtt_mm *mm = dev_priv->gtt_mm; + struct psb_gtt *pg = dev_priv->pg; + uint32_t pages, offset_pages; + struct drm_mm_node *node; + int ret; + + ret = psb_gtt_remove_node(mm, + task_tgid_nr(current), + (u32)hKernelMemInfo, + &node); + if (ret) { + DRM_DEBUG("remove node failed\n"); + return ret; + } + + /*remove gtt entries*/ + offset_pages = node->start; + pages = node->size; + + psb_gtt_remove_pages(pg, offset_pages, pages, 0, 0, 1); + + + /*free tt node*/ + + psb_gtt_mm_free_mem(mm, node); + return 0; +} + +int psb_gtt_map_meminfo_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct psb_gtt_mapping_arg *arg + = (struct psb_gtt_mapping_arg *)data; + uint32_t *offset_pages = &arg->offset_pages; + + DRM_DEBUG("\n"); + + return psb_gtt_map_meminfo(dev, arg->hKernelMemInfo, offset_pages); +} + +int psb_gtt_unmap_meminfo_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + + struct psb_gtt_mapping_arg *arg + = (struct psb_gtt_mapping_arg *)data; + + DRM_DEBUG("\n"); + + return psb_gtt_unmap_meminfo(dev, arg->hKernelMemInfo); +} + +int psb_gtt_map_pvr_memory(struct drm_device *dev, unsigned int hHandle, + unsigned int ui32TaskId, dma_addr_t *pPages, + unsigned int ui32PagesNum, unsigned int *ui32Offset) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_gtt_mm *mm = dev_priv->gtt_mm; + struct psb_gtt *pg = dev_priv->pg; + uint32_t size, pages, offset_pages; + struct drm_mm_node *node = NULL; + struct psb_gtt_mem_mapping *mapping = NULL; + int ret; + + size = ui32PagesNum * PAGE_SIZE; + pages = 0; + + /*alloc memory in TT apeture*/ + ret = psb_gtt_mm_alloc_mem(mm, ui32PagesNum, 0, &node); + if (ret) { + DRM_DEBUG("alloc TT memory error\n"); + goto failed_pages_alloc; + } + + /*update psb_gtt_mm*/ + ret = psb_gtt_add_node(mm, + (u32)ui32TaskId, + (u32)hHandle, + node, + &mapping); + if (ret) { + DRM_DEBUG("add_node failed"); + goto failed_add_node; + } + + node = mapping->node; + offset_pages = node->start; + + DRM_DEBUG("get free node for %ld pages, offset %ld pages", + pages, offset_pages); + + /*update gtt*/ + psb_gtt_insert_phys_addresses(pg, pPages, (unsigned)offset_pages, + (unsigned)ui32PagesNum, 0); + + *ui32Offset = offset_pages; + return 0; + +failed_add_node: + psb_gtt_mm_free_mem(mm, node); +failed_pages_alloc: + return ret; +} + + +int psb_gtt_unmap_pvr_memory(struct drm_device *dev, unsigned int hHandle, + unsigned int ui32TaskId) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_gtt_mm *mm = dev_priv->gtt_mm; + struct psb_gtt *pg = dev_priv->pg; + uint32_t pages, offset_pages; + struct drm_mm_node *node; + int ret; + + ret = psb_gtt_remove_node(mm, (u32)ui32TaskId, (u32)hHandle, &node); + if (ret) { + printk(KERN_ERR "remove node failed\n"); + return ret; + } + + /*remove gtt entries*/ + offset_pages = node->start; + pages = node->size; + + psb_gtt_remove_pages(pg, offset_pages, pages, 0, 0, 1); + + /*free tt node*/ + psb_gtt_mm_free_mem(mm, node); + return 0; +} diff --git a/drivers/staging/gma500/psb_gtt.h b/drivers/staging/gma500/psb_gtt.h new file mode 100644 index 000000000000..3544b4d92f11 --- /dev/null +++ b/drivers/staging/gma500/psb_gtt.h @@ -0,0 +1,105 @@ +/************************************************************************** + * Copyright (c) 2007-2008, Intel Corporation. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + **************************************************************************/ + +#ifndef _PSB_GTT_H_ +#define _PSB_GTT_H_ + +#include + +/*#include "img_types.h"*/ + +struct psb_gtt { + struct drm_device *dev; + int initialized; + uint32_t gatt_start; + uint32_t mmu_gatt_start; + uint32_t ci_start; + uint32_t rar_start; + uint32_t gtt_start; + uint32_t gtt_phys_start; + unsigned gtt_pages; + unsigned gatt_pages; + uint32_t stolen_base; + void *vram_addr; + uint32_t pge_ctl; + u16 gmch_ctrl; + unsigned long stolen_size; + unsigned long vram_stolen_size; + unsigned long ci_stolen_size; + unsigned long rar_stolen_size; + uint32_t *gtt_map; + struct rw_semaphore sem; +}; + +struct psb_gtt_mm { + struct drm_mm base; + struct drm_open_hash hash; + uint32_t count; + spinlock_t lock; +}; + +struct psb_gtt_hash_entry { + struct drm_open_hash ht; + uint32_t count; + struct drm_hash_item item; +}; + +struct psb_gtt_mem_mapping { + struct drm_mm_node *node; + struct drm_hash_item item; +}; + +/*Exported functions*/ +extern int psb_gtt_init(struct psb_gtt *pg, int resume); +extern int psb_gtt_insert_pages(struct psb_gtt *pg, struct page **pages, + unsigned offset_pages, unsigned num_pages, + unsigned desired_tile_stride, + unsigned hw_tile_stride, int type); +extern int psb_gtt_remove_pages(struct psb_gtt *pg, unsigned offset_pages, + unsigned num_pages, + unsigned desired_tile_stride, + unsigned hw_tile_stride, + int rc_prot); + +extern struct psb_gtt *psb_gtt_alloc(struct drm_device *dev); +extern void psb_gtt_takedown(struct psb_gtt *pg, int free); +extern int psb_gtt_map_meminfo(struct drm_device *dev, + void * hKernelMemInfo, + uint32_t *offset); +extern int psb_gtt_unmap_meminfo(struct drm_device *dev, + void * hKernelMemInfo); +extern int psb_gtt_map_meminfo_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int psb_gtt_unmap_meminfo_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int psb_gtt_mm_init(struct psb_gtt *pg); +extern void psb_gtt_mm_takedown(void); + +extern int psb_gtt_map_pvr_memory(struct drm_device *dev, + unsigned int hHandle, + unsigned int ui32TaskId, + dma_addr_t *pPages, + unsigned int ui32PagesNum, + unsigned int *ui32Offset); + +extern int psb_gtt_unmap_pvr_memory(struct drm_device *dev, + unsigned int hHandle, + unsigned int ui32TaskId); + +#endif diff --git a/drivers/staging/gma500/psb_intel_bios.c b/drivers/staging/gma500/psb_intel_bios.c new file mode 100644 index 000000000000..83d8e9359f2f --- /dev/null +++ b/drivers/staging/gma500/psb_intel_bios.c @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2006 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Authors: + * Eric Anholt + * + */ +#include +#include +#include "psb_drm.h" +#include "psb_drv.h" +#include "psb_intel_drv.h" +#include "psb_intel_reg.h" +#include "psb_intel_bios.h" + + +static void *find_section(struct bdb_header *bdb, int section_id) +{ + u8 *base = (u8 *)bdb; + int index = 0; + u16 total, current_size; + u8 current_id; + + /* skip to first section */ + index += bdb->header_size; + total = bdb->bdb_size; + + /* walk the sections looking for section_id */ + while (index < total) { + current_id = *(base + index); + index++; + current_size = *((u16 *)(base + index)); + index += 2; + if (current_id == section_id) + return base + index; + index += current_size; + } + + return NULL; +} + +static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, + struct lvds_dvo_timing *dvo_timing) +{ + panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) | + dvo_timing->hactive_lo; + panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay + + ((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo); + panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start + + dvo_timing->hsync_pulse_width; + panel_fixed_mode->htotal = panel_fixed_mode->hdisplay + + ((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo); + + panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) | + dvo_timing->vactive_lo; + panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay + + dvo_timing->vsync_off; + panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start + + dvo_timing->vsync_pulse_width; + panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay + + ((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo); + panel_fixed_mode->clock = dvo_timing->clock * 10; + panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; + + /* Some VBTs have bogus h/vtotal values */ + if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) + panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; + if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal) + panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1; + + drm_mode_set_name(panel_fixed_mode); +} + +static void parse_backlight_data(struct drm_psb_private *dev_priv, + struct bdb_header *bdb) +{ + struct bdb_lvds_backlight *vbt_lvds_bl = NULL; + struct bdb_lvds_backlight *lvds_bl; + u8 p_type = 0; + void *bl_start = NULL; + struct bdb_lvds_options *lvds_opts + = find_section(bdb, BDB_LVDS_OPTIONS); + + dev_priv->lvds_bl = NULL; + + if (lvds_opts) { + DRM_DEBUG("lvds_options found at %p\n", lvds_opts); + p_type = lvds_opts->panel_type; + } else { + DRM_DEBUG("no lvds_options\n"); + return; + } + + bl_start = find_section(bdb, BDB_LVDS_BACKLIGHT); + vbt_lvds_bl = (struct bdb_lvds_backlight *)(bl_start + 1) + p_type; + + lvds_bl = kzalloc(sizeof(*vbt_lvds_bl), GFP_KERNEL); + if (!lvds_bl) { + DRM_DEBUG("No memory\n"); + return; + } + + memcpy(lvds_bl, vbt_lvds_bl, sizeof(*vbt_lvds_bl)); + + dev_priv->lvds_bl = lvds_bl; +} + +/* Try to find integrated panel data */ +static void parse_lfp_panel_data(struct drm_psb_private *dev_priv, + struct bdb_header *bdb) +{ + struct bdb_lvds_options *lvds_options; + struct bdb_lvds_lfp_data *lvds_lfp_data; + struct bdb_lvds_lfp_data_entry *entry; + struct lvds_dvo_timing *dvo_timing; + struct drm_display_mode *panel_fixed_mode; + + /* Defaults if we can't find VBT info */ + dev_priv->lvds_dither = 0; + dev_priv->lvds_vbt = 0; + + lvds_options = find_section(bdb, BDB_LVDS_OPTIONS); + if (!lvds_options) + return; + + dev_priv->lvds_dither = lvds_options->pixel_dither; + if (lvds_options->panel_type == 0xff) + return; + + lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA); + if (!lvds_lfp_data) + return; + + dev_priv->lvds_vbt = 1; + + entry = &lvds_lfp_data->data[lvds_options->panel_type]; + dvo_timing = &entry->dvo_timing; + + panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), + GFP_KERNEL); + + fill_detail_timing_data(panel_fixed_mode, dvo_timing); + + dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode; + + DRM_DEBUG("Found panel mode in BIOS VBT tables:\n"); + drm_mode_debug_printmodeline(panel_fixed_mode); + + return; +} + +/* Try to find sdvo panel data */ +static void parse_sdvo_panel_data(struct drm_psb_private *dev_priv, + struct bdb_header *bdb) +{ + struct bdb_sdvo_lvds_options *sdvo_lvds_options; + struct lvds_dvo_timing *dvo_timing; + struct drm_display_mode *panel_fixed_mode; + + dev_priv->sdvo_lvds_vbt_mode = NULL; + + sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS); + if (!sdvo_lvds_options) + return; + + dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS); + if (!dvo_timing) + return; + + panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); + + if (!panel_fixed_mode) + return; + + fill_detail_timing_data(panel_fixed_mode, + dvo_timing + sdvo_lvds_options->panel_type); + + dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode; + + return; +} + +static void parse_general_features(struct drm_psb_private *dev_priv, + struct bdb_header *bdb) +{ + struct bdb_general_features *general; + + /* Set sensible defaults in case we can't find the general block */ + dev_priv->int_tv_support = 1; + dev_priv->int_crt_support = 1; + + general = find_section(bdb, BDB_GENERAL_FEATURES); + if (general) { + dev_priv->int_tv_support = general->int_tv_support; + dev_priv->int_crt_support = general->int_crt_support; + dev_priv->lvds_use_ssc = general->enable_ssc; + + if (dev_priv->lvds_use_ssc) { + dev_priv->lvds_ssc_freq + = general->ssc_freq ? 100 : 96; + } + } +} + +/** + * psb_intel_init_bios - initialize VBIOS settings & find VBT + * @dev: DRM device + * + * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers + * to appropriate values. + * + * VBT existence is a sanity check that is relied on by other i830_bios.c code. + * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may + * feed an updated VBT back through that, compared to what we'll fetch using + * this method of groping around in the BIOS data. + * + * Returns 0 on success, nonzero on failure. + */ +bool psb_intel_init_bios(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct pci_dev *pdev = dev->pdev; + struct vbt_header *vbt = NULL; + struct bdb_header *bdb; + u8 __iomem *bios; + size_t size; + int i; + + bios = pci_map_rom(pdev, &size); + if (!bios) + return -1; + + /* Scour memory looking for the VBT signature */ + for (i = 0; i + 4 < size; i++) { + if (!memcmp(bios + i, "$VBT", 4)) { + vbt = (struct vbt_header *)(bios + i); + break; + } + } + + if (!vbt) { + DRM_ERROR("VBT signature missing\n"); + pci_unmap_rom(pdev, bios); + return -1; + } + + bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); + + /* Grab useful general definitions */ + parse_general_features(dev_priv, bdb); + parse_lfp_panel_data(dev_priv, bdb); + parse_sdvo_panel_data(dev_priv, bdb); + parse_backlight_data(dev_priv, bdb); + + pci_unmap_rom(pdev, bios); + + return 0; +} + +/** + * Destory and free VBT data + */ +void psb_intel_destory_bios(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct drm_display_mode *sdvo_lvds_vbt_mode = + dev_priv->sdvo_lvds_vbt_mode; + struct drm_display_mode *lfp_lvds_vbt_mode = + dev_priv->lfp_lvds_vbt_mode; + struct bdb_lvds_backlight *lvds_bl = + dev_priv->lvds_bl; + + /*free sdvo panel mode*/ + if (sdvo_lvds_vbt_mode) { + dev_priv->sdvo_lvds_vbt_mode = NULL; + kfree(sdvo_lvds_vbt_mode); + } + + if (lfp_lvds_vbt_mode) { + dev_priv->lfp_lvds_vbt_mode = NULL; + kfree(lfp_lvds_vbt_mode); + } + + if (lvds_bl) { + dev_priv->lvds_bl = NULL; + kfree(lvds_bl); + } +} diff --git a/drivers/staging/gma500/psb_intel_bios.h b/drivers/staging/gma500/psb_intel_bios.h new file mode 100644 index 000000000000..dfcae6218308 --- /dev/null +++ b/drivers/staging/gma500/psb_intel_bios.h @@ -0,0 +1,430 @@ +/* + * Copyright (c) 2006 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Authors: + * Eric Anholt + * + */ + +#ifndef _I830_BIOS_H_ +#define _I830_BIOS_H_ + +#include + +struct vbt_header { + u8 signature[20]; /**< Always starts with 'VBT$' */ + u16 version; /**< decimal */ + u16 header_size; /**< in bytes */ + u16 vbt_size; /**< in bytes */ + u8 vbt_checksum; + u8 reserved0; + u32 bdb_offset; /**< from beginning of VBT */ + u32 aim_offset[4]; /**< from beginning of VBT */ +} __attribute__((packed)); + + +struct bdb_header { + u8 signature[16]; /**< Always 'BIOS_DATA_BLOCK' */ + u16 version; /**< decimal */ + u16 header_size; /**< in bytes */ + u16 bdb_size; /**< in bytes */ +}; + +/* strictly speaking, this is a "skip" block, but it has interesting info */ +struct vbios_data { + u8 type; /* 0 == desktop, 1 == mobile */ + u8 relstage; + u8 chipset; + u8 lvds_present:1; + u8 tv_present:1; + u8 rsvd2:6; /* finish byte */ + u8 rsvd3[4]; + u8 signon[155]; + u8 copyright[61]; + u16 code_segment; + u8 dos_boot_mode; + u8 bandwidth_percent; + u8 rsvd4; /* popup memory size */ + u8 resize_pci_bios; + u8 rsvd5; /* is crt already on ddc2 */ +} __attribute__((packed)); + +/* + * There are several types of BIOS data blocks (BDBs), each block has + * an ID and size in the first 3 bytes (ID in first, size in next 2). + * Known types are listed below. + */ +#define BDB_GENERAL_FEATURES 1 +#define BDB_GENERAL_DEFINITIONS 2 +#define BDB_OLD_TOGGLE_LIST 3 +#define BDB_MODE_SUPPORT_LIST 4 +#define BDB_GENERIC_MODE_TABLE 5 +#define BDB_EXT_MMIO_REGS 6 +#define BDB_SWF_IO 7 +#define BDB_SWF_MMIO 8 +#define BDB_DOT_CLOCK_TABLE 9 +#define BDB_MODE_REMOVAL_TABLE 10 +#define BDB_CHILD_DEVICE_TABLE 11 +#define BDB_DRIVER_FEATURES 12 +#define BDB_DRIVER_PERSISTENCE 13 +#define BDB_EXT_TABLE_PTRS 14 +#define BDB_DOT_CLOCK_OVERRIDE 15 +#define BDB_DISPLAY_SELECT 16 +/* 17 rsvd */ +#define BDB_DRIVER_ROTATION 18 +#define BDB_DISPLAY_REMOVE 19 +#define BDB_OEM_CUSTOM 20 +#define BDB_EFP_LIST 21 /* workarounds for VGA hsync/vsync */ +#define BDB_SDVO_LVDS_OPTIONS 22 +#define BDB_SDVO_PANEL_DTDS 23 +#define BDB_SDVO_LVDS_PNP_IDS 24 +#define BDB_SDVO_LVDS_POWER_SEQ 25 +#define BDB_TV_OPTIONS 26 +#define BDB_LVDS_OPTIONS 40 +#define BDB_LVDS_LFP_DATA_PTRS 41 +#define BDB_LVDS_LFP_DATA 42 +#define BDB_LVDS_BACKLIGHT 43 +#define BDB_LVDS_POWER 44 +#define BDB_SKIP 254 /* VBIOS private block, ignore */ + +struct bdb_general_features { + /* bits 1 */ + u8 panel_fitting:2; + u8 flexaim:1; + u8 msg_enable:1; + u8 clear_screen:3; + u8 color_flip:1; + + /* bits 2 */ + u8 download_ext_vbt:1; + u8 enable_ssc:1; + u8 ssc_freq:1; + u8 enable_lfp_on_override:1; + u8 disable_ssc_ddt:1; + u8 rsvd8:3; /* finish byte */ + + /* bits 3 */ + u8 disable_smooth_vision:1; + u8 single_dvi:1; + u8 rsvd9:6; /* finish byte */ + + /* bits 4 */ + u8 legacy_monitor_detect; + + /* bits 5 */ + u8 int_crt_support:1; + u8 int_tv_support:1; + u8 rsvd11:6; /* finish byte */ +} __attribute__((packed)); + +struct bdb_general_definitions { + /* DDC GPIO */ + u8 crt_ddc_gmbus_pin; + + /* DPMS bits */ + u8 dpms_acpi:1; + u8 skip_boot_crt_detect:1; + u8 dpms_aim:1; + u8 rsvd1:5; /* finish byte */ + + /* boot device bits */ + u8 boot_display[2]; + u8 child_dev_size; + + /* device info */ + u8 tv_or_lvds_info[33]; + u8 dev1[33]; + u8 dev2[33]; + u8 dev3[33]; + u8 dev4[33]; + /* may be another device block here on some platforms */ +}; + +struct bdb_lvds_options { + u8 panel_type; + u8 rsvd1; + /* LVDS capabilities, stored in a dword */ + u8 pfit_mode:2; + u8 pfit_text_mode_enhanced:1; + u8 pfit_gfx_mode_enhanced:1; + u8 pfit_ratio_auto:1; + u8 pixel_dither:1; + u8 lvds_edid:1; + u8 rsvd2:1; + u8 rsvd4; +} __attribute__((packed)); + +struct bdb_lvds_backlight { + u8 type:2; + u8 pol:1; + u8 gpio:3; + u8 gmbus:2; + u16 freq; + u8 minbrightness; + u8 i2caddr; + u8 brightnesscmd; + /*FIXME: more...*/ +} __attribute__((packed)); + +/* LFP pointer table contains entries to the struct below */ +struct bdb_lvds_lfp_data_ptr { + u16 fp_timing_offset; /* offsets are from start of bdb */ + u8 fp_table_size; + u16 dvo_timing_offset; + u8 dvo_table_size; + u16 panel_pnp_id_offset; + u8 pnp_table_size; +} __attribute__((packed)); + +struct bdb_lvds_lfp_data_ptrs { + u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */ + struct bdb_lvds_lfp_data_ptr ptr[16]; +} __attribute__((packed)); + +/* LFP data has 3 blocks per entry */ +struct lvds_fp_timing { + u16 x_res; + u16 y_res; + u32 lvds_reg; + u32 lvds_reg_val; + u32 pp_on_reg; + u32 pp_on_reg_val; + u32 pp_off_reg; + u32 pp_off_reg_val; + u32 pp_cycle_reg; + u32 pp_cycle_reg_val; + u32 pfit_reg; + u32 pfit_reg_val; + u16 terminator; +} __attribute__((packed)); + +struct lvds_dvo_timing { + u16 clock; /**< In 10khz */ + u8 hactive_lo; + u8 hblank_lo; + u8 hblank_hi:4; + u8 hactive_hi:4; + u8 vactive_lo; + u8 vblank_lo; + u8 vblank_hi:4; + u8 vactive_hi:4; + u8 hsync_off_lo; + u8 hsync_pulse_width; + u8 vsync_pulse_width:4; + u8 vsync_off:4; + u8 rsvd0:6; + u8 hsync_off_hi:2; + u8 h_image; + u8 v_image; + u8 max_hv; + u8 h_border; + u8 v_border; + u8 rsvd1:3; + u8 digital:2; + u8 vsync_positive:1; + u8 hsync_positive:1; + u8 rsvd2:1; +} __attribute__((packed)); + +struct lvds_pnp_id { + u16 mfg_name; + u16 product_code; + u32 serial; + u8 mfg_week; + u8 mfg_year; +} __attribute__((packed)); + +struct bdb_lvds_lfp_data_entry { + struct lvds_fp_timing fp_timing; + struct lvds_dvo_timing dvo_timing; + struct lvds_pnp_id pnp_id; +} __attribute__((packed)); + +struct bdb_lvds_lfp_data { + struct bdb_lvds_lfp_data_entry data[16]; +} __attribute__((packed)); + +struct aimdb_header { + char signature[16]; + char oem_device[20]; + u16 aimdb_version; + u16 aimdb_header_size; + u16 aimdb_size; +} __attribute__((packed)); + +struct aimdb_block { + u8 aimdb_id; + u16 aimdb_size; +} __attribute__((packed)); + +struct vch_panel_data { + u16 fp_timing_offset; + u8 fp_timing_size; + u16 dvo_timing_offset; + u8 dvo_timing_size; + u16 text_fitting_offset; + u8 text_fitting_size; + u16 graphics_fitting_offset; + u8 graphics_fitting_size; +} __attribute__((packed)); + +struct vch_bdb_22 { + struct aimdb_block aimdb_block; + struct vch_panel_data panels[16]; +} __attribute__((packed)); + +struct bdb_sdvo_lvds_options { + u8 panel_backlight; + u8 h40_set_panel_type; + u8 panel_type; + u8 ssc_clk_freq; + u16 als_low_trip; + u16 als_high_trip; + u8 sclalarcoeff_tab_row_num; + u8 sclalarcoeff_tab_row_size; + u8 coefficient[8]; + u8 panel_misc_bits_1; + u8 panel_misc_bits_2; + u8 panel_misc_bits_3; + u8 panel_misc_bits_4; +} __attribute__((packed)); + + +extern bool psb_intel_init_bios(struct drm_device *dev); +extern void psb_intel_destory_bios(struct drm_device *dev); + +/* + * Driver<->VBIOS interaction occurs through scratch bits in + * GR18 & SWF*. + */ + +/* GR18 bits are set on display switch and hotkey events */ +#define GR18_DRIVER_SWITCH_EN (1<<7) /* 0: VBIOS control, 1: driver control */ +#define GR18_HOTKEY_MASK 0x78 /* See also SWF4 15:0 */ +#define GR18_HK_NONE (0x0<<3) +#define GR18_HK_LFP_STRETCH (0x1<<3) +#define GR18_HK_TOGGLE_DISP (0x2<<3) +#define GR18_HK_DISP_SWITCH (0x4<<3) /* see SWF14 15:0 for what to enable */ +#define GR18_HK_POPUP_DISABLED (0x6<<3) +#define GR18_HK_POPUP_ENABLED (0x7<<3) +#define GR18_HK_PFIT (0x8<<3) +#define GR18_HK_APM_CHANGE (0xa<<3) +#define GR18_HK_MULTIPLE (0xc<<3) +#define GR18_USER_INT_EN (1<<2) +#define GR18_A0000_FLUSH_EN (1<<1) +#define GR18_SMM_EN (1<<0) + +/* Set by driver, cleared by VBIOS */ +#define SWF00_YRES_SHIFT 16 +#define SWF00_XRES_SHIFT 0 +#define SWF00_RES_MASK 0xffff + +/* Set by VBIOS at boot time and driver at runtime */ +#define SWF01_TV2_FORMAT_SHIFT 8 +#define SWF01_TV1_FORMAT_SHIFT 0 +#define SWF01_TV_FORMAT_MASK 0xffff + +#define SWF10_VBIOS_BLC_I2C_EN (1<<29) +#define SWF10_GTT_OVERRIDE_EN (1<<28) +#define SWF10_LFP_DPMS_OVR (1<<27) /* override DPMS on display switch */ +#define SWF10_ACTIVE_TOGGLE_LIST_MASK (7<<24) +#define SWF10_OLD_TOGGLE 0x0 +#define SWF10_TOGGLE_LIST_1 0x1 +#define SWF10_TOGGLE_LIST_2 0x2 +#define SWF10_TOGGLE_LIST_3 0x3 +#define SWF10_TOGGLE_LIST_4 0x4 +#define SWF10_PANNING_EN (1<<23) +#define SWF10_DRIVER_LOADED (1<<22) +#define SWF10_EXTENDED_DESKTOP (1<<21) +#define SWF10_EXCLUSIVE_MODE (1<<20) +#define SWF10_OVERLAY_EN (1<<19) +#define SWF10_PLANEB_HOLDOFF (1<<18) +#define SWF10_PLANEA_HOLDOFF (1<<17) +#define SWF10_VGA_HOLDOFF (1<<16) +#define SWF10_ACTIVE_DISP_MASK 0xffff +#define SWF10_PIPEB_LFP2 (1<<15) +#define SWF10_PIPEB_EFP2 (1<<14) +#define SWF10_PIPEB_TV2 (1<<13) +#define SWF10_PIPEB_CRT2 (1<<12) +#define SWF10_PIPEB_LFP (1<<11) +#define SWF10_PIPEB_EFP (1<<10) +#define SWF10_PIPEB_TV (1<<9) +#define SWF10_PIPEB_CRT (1<<8) +#define SWF10_PIPEA_LFP2 (1<<7) +#define SWF10_PIPEA_EFP2 (1<<6) +#define SWF10_PIPEA_TV2 (1<<5) +#define SWF10_PIPEA_CRT2 (1<<4) +#define SWF10_PIPEA_LFP (1<<3) +#define SWF10_PIPEA_EFP (1<<2) +#define SWF10_PIPEA_TV (1<<1) +#define SWF10_PIPEA_CRT (1<<0) + +#define SWF11_MEMORY_SIZE_SHIFT 16 +#define SWF11_SV_TEST_EN (1<<15) +#define SWF11_IS_AGP (1<<14) +#define SWF11_DISPLAY_HOLDOFF (1<<13) +#define SWF11_DPMS_REDUCED (1<<12) +#define SWF11_IS_VBE_MODE (1<<11) +#define SWF11_PIPEB_ACCESS (1<<10) /* 0 here means pipe a */ +#define SWF11_DPMS_MASK 0x07 +#define SWF11_DPMS_OFF (1<<2) +#define SWF11_DPMS_SUSPEND (1<<1) +#define SWF11_DPMS_STANDBY (1<<0) +#define SWF11_DPMS_ON 0 + +#define SWF14_GFX_PFIT_EN (1<<31) +#define SWF14_TEXT_PFIT_EN (1<<30) +#define SWF14_LID_STATUS_CLOSED (1<<29) /* 0 here means open */ +#define SWF14_POPUP_EN (1<<28) +#define SWF14_DISPLAY_HOLDOFF (1<<27) +#define SWF14_DISP_DETECT_EN (1<<26) +#define SWF14_DOCKING_STATUS_DOCKED (1<<25) /* 0 here means undocked */ +#define SWF14_DRIVER_STATUS (1<<24) +#define SWF14_OS_TYPE_WIN9X (1<<23) +#define SWF14_OS_TYPE_WINNT (1<<22) +/* 21:19 rsvd */ +#define SWF14_PM_TYPE_MASK 0x00070000 +#define SWF14_PM_ACPI_VIDEO (0x4 << 16) +#define SWF14_PM_ACPI (0x3 << 16) +#define SWF14_PM_APM_12 (0x2 << 16) +#define SWF14_PM_APM_11 (0x1 << 16) +#define SWF14_HK_REQUEST_MASK 0x0000ffff /* see GR18 6:3 for event type */ + /* if GR18 indicates a display switch */ +#define SWF14_DS_PIPEB_LFP2_EN (1<<15) +#define SWF14_DS_PIPEB_EFP2_EN (1<<14) +#define SWF14_DS_PIPEB_TV2_EN (1<<13) +#define SWF14_DS_PIPEB_CRT2_EN (1<<12) +#define SWF14_DS_PIPEB_LFP_EN (1<<11) +#define SWF14_DS_PIPEB_EFP_EN (1<<10) +#define SWF14_DS_PIPEB_TV_EN (1<<9) +#define SWF14_DS_PIPEB_CRT_EN (1<<8) +#define SWF14_DS_PIPEA_LFP2_EN (1<<7) +#define SWF14_DS_PIPEA_EFP2_EN (1<<6) +#define SWF14_DS_PIPEA_TV2_EN (1<<5) +#define SWF14_DS_PIPEA_CRT2_EN (1<<4) +#define SWF14_DS_PIPEA_LFP_EN (1<<3) +#define SWF14_DS_PIPEA_EFP_EN (1<<2) +#define SWF14_DS_PIPEA_TV_EN (1<<1) +#define SWF14_DS_PIPEA_CRT_EN (1<<0) + /* if GR18 indicates a panel fitting request */ +#define SWF14_PFIT_EN (1<<0) /* 0 means disable */ + /* if GR18 indicates an APM change request */ +#define SWF14_APM_HIBERNATE 0x4 +#define SWF14_APM_SUSPEND 0x3 +#define SWF14_APM_STANDBY 0x1 +#define SWF14_APM_RESTORE 0x0 + +#endif /* _I830_BIOS_H_ */ diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c new file mode 100644 index 000000000000..80b37f4ca10a --- /dev/null +++ b/drivers/staging/gma500/psb_intel_display.c @@ -0,0 +1,1489 @@ +/* + * Copyright © 2006-2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Authors: + * Eric Anholt + */ + +#include +#include + +#include +#include "psb_fb.h" +#include "psb_drv.h" +#include "psb_intel_drv.h" +#include "psb_intel_reg.h" +#include "psb_intel_display.h" +#include "psb_powermgmt.h" + + +struct psb_intel_clock_t { + /* given values */ + int n; + int m1, m2; + int p1, p2; + /* derived values */ + int dot; + int vco; + int m; + int p; +}; + +struct psb_intel_range_t { + int min, max; +}; + +struct psb_intel_p2_t { + int dot_limit; + int p2_slow, p2_fast; +}; + +#define INTEL_P2_NUM 2 + +struct psb_intel_limit_t { + struct psb_intel_range_t dot, vco, n, m, m1, m2, p, p1; + struct psb_intel_p2_t p2; +}; + +#define I8XX_DOT_MIN 25000 +#define I8XX_DOT_MAX 350000 +#define I8XX_VCO_MIN 930000 +#define I8XX_VCO_MAX 1400000 +#define I8XX_N_MIN 3 +#define I8XX_N_MAX 16 +#define I8XX_M_MIN 96 +#define I8XX_M_MAX 140 +#define I8XX_M1_MIN 18 +#define I8XX_M1_MAX 26 +#define I8XX_M2_MIN 6 +#define I8XX_M2_MAX 16 +#define I8XX_P_MIN 4 +#define I8XX_P_MAX 128 +#define I8XX_P1_MIN 2 +#define I8XX_P1_MAX 33 +#define I8XX_P1_LVDS_MIN 1 +#define I8XX_P1_LVDS_MAX 6 +#define I8XX_P2_SLOW 4 +#define I8XX_P2_FAST 2 +#define I8XX_P2_LVDS_SLOW 14 +#define I8XX_P2_LVDS_FAST 14 /* No fast option */ +#define I8XX_P2_SLOW_LIMIT 165000 + +#define I9XX_DOT_MIN 20000 +#define I9XX_DOT_MAX 400000 +#define I9XX_VCO_MIN 1400000 +#define I9XX_VCO_MAX 2800000 +#define I9XX_N_MIN 3 +#define I9XX_N_MAX 8 +#define I9XX_M_MIN 70 +#define I9XX_M_MAX 120 +#define I9XX_M1_MIN 10 +#define I9XX_M1_MAX 20 +#define I9XX_M2_MIN 5 +#define I9XX_M2_MAX 9 +#define I9XX_P_SDVO_DAC_MIN 5 +#define I9XX_P_SDVO_DAC_MAX 80 +#define I9XX_P_LVDS_MIN 7 +#define I9XX_P_LVDS_MAX 98 +#define I9XX_P1_MIN 1 +#define I9XX_P1_MAX 8 +#define I9XX_P2_SDVO_DAC_SLOW 10 +#define I9XX_P2_SDVO_DAC_FAST 5 +#define I9XX_P2_SDVO_DAC_SLOW_LIMIT 200000 +#define I9XX_P2_LVDS_SLOW 14 +#define I9XX_P2_LVDS_FAST 7 +#define I9XX_P2_LVDS_SLOW_LIMIT 112000 + +#define INTEL_LIMIT_I8XX_DVO_DAC 0 +#define INTEL_LIMIT_I8XX_LVDS 1 +#define INTEL_LIMIT_I9XX_SDVO_DAC 2 +#define INTEL_LIMIT_I9XX_LVDS 3 + +static const struct psb_intel_limit_t psb_intel_limits[] = { + { /* INTEL_LIMIT_I8XX_DVO_DAC */ + .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX}, + .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX}, + .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX}, + .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX}, + .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX}, + .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX}, + .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX}, + .p1 = {.min = I8XX_P1_MIN, .max = I8XX_P1_MAX}, + .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT, + .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST}, + }, + { /* INTEL_LIMIT_I8XX_LVDS */ + .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX}, + .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX}, + .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX}, + .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX}, + .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX}, + .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX}, + .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX}, + .p1 = {.min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX}, + .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT, + .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST}, + }, + { /* INTEL_LIMIT_I9XX_SDVO_DAC */ + .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, + .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX}, + .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX}, + .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX}, + .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX}, + .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX}, + .p = {.min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX}, + .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX}, + .p2 = {.dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, + .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = + I9XX_P2_SDVO_DAC_FAST}, + }, + { /* INTEL_LIMIT_I9XX_LVDS */ + .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, + .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX}, + .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX}, + .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX}, + .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX}, + .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX}, + .p = {.min = I9XX_P_LVDS_MIN, .max = I9XX_P_LVDS_MAX}, + .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX}, + /* The single-channel range is 25-112Mhz, and dual-channel + * is 80-224Mhz. Prefer single channel as much as possible. + */ + .p2 = {.dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, + .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST}, + }, +}; + +static const struct psb_intel_limit_t *psb_intel_limit(struct drm_crtc *crtc) +{ + const struct psb_intel_limit_t *limit; + + if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) + limit = &psb_intel_limits[INTEL_LIMIT_I9XX_LVDS]; + else + limit = &psb_intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; + return limit; +} + +/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ + +static void i8xx_clock(int refclk, struct psb_intel_clock_t *clock) +{ + clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); + clock->p = clock->p1 * clock->p2; + clock->vco = refclk * clock->m / (clock->n + 2); + clock->dot = clock->vco / clock->p; +} + +/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */ + +static void i9xx_clock(int refclk, struct psb_intel_clock_t *clock) +{ + clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); + clock->p = clock->p1 * clock->p2; + clock->vco = refclk * clock->m / (clock->n + 2); + clock->dot = clock->vco / clock->p; +} + +static void psb_intel_clock(struct drm_device *dev, int refclk, + struct psb_intel_clock_t *clock) +{ + return i9xx_clock(refclk, clock); +} + +/** + * Returns whether any output on the specified pipe is of the specified type + */ +bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type) +{ + struct drm_device *dev = crtc->dev; + struct drm_mode_config *mode_config = &dev->mode_config; + struct drm_connector *l_entry; + + list_for_each_entry(l_entry, &mode_config->connector_list, head) { + if (l_entry->encoder && l_entry->encoder->crtc == crtc) { + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(l_entry); + if (psb_intel_output->type == type) + return true; + } + } + return false; +} + +#define INTELPllInvalid(s) { /* ErrorF (s) */; return false; } +/** + * Returns whether the given set of divisors are valid for a given refclk with + * the given connectors. + */ + +static bool psb_intel_PLL_is_valid(struct drm_crtc *crtc, + struct psb_intel_clock_t *clock) +{ + const struct psb_intel_limit_t *limit = psb_intel_limit(crtc); + + if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1) + INTELPllInvalid("p1 out of range\n"); + if (clock->p < limit->p.min || limit->p.max < clock->p) + INTELPllInvalid("p out of range\n"); + if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2) + INTELPllInvalid("m2 out of range\n"); + if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1) + INTELPllInvalid("m1 out of range\n"); + if (clock->m1 <= clock->m2) + INTELPllInvalid("m1 <= m2\n"); + if (clock->m < limit->m.min || limit->m.max < clock->m) + INTELPllInvalid("m out of range\n"); + if (clock->n < limit->n.min || limit->n.max < clock->n) + INTELPllInvalid("n out of range\n"); + if (clock->vco < limit->vco.min || limit->vco.max < clock->vco) + INTELPllInvalid("vco out of range\n"); + /* XXX: We may need to be checking "Dot clock" + * depending on the multiplier, connector, etc., + * rather than just a single range. + */ + if (clock->dot < limit->dot.min || limit->dot.max < clock->dot) + INTELPllInvalid("dot out of range\n"); + + return true; +} + +/** + * Returns a set of divisors for the desired target clock with the given + * refclk, or FALSE. The returned values represent the clock equation: + * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. + */ +static bool psb_intel_find_best_PLL(struct drm_crtc *crtc, int target, + int refclk, + struct psb_intel_clock_t *best_clock) +{ + struct drm_device *dev = crtc->dev; + struct psb_intel_clock_t clock; + const struct psb_intel_limit_t *limit = psb_intel_limit(crtc); + int err = target; + + if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && + (REG_READ(LVDS) & LVDS_PORT_EN) != 0) { + /* + * For LVDS, if the panel is on, just rely on its current + * settings for dual-channel. We haven't figured out how to + * reliably set up different single/dual channel state, if we + * even can. + */ + if ((REG_READ(LVDS) & LVDS_CLKB_POWER_MASK) == + LVDS_CLKB_POWER_UP) + clock.p2 = limit->p2.p2_fast; + else + clock.p2 = limit->p2.p2_slow; + } else { + if (target < limit->p2.dot_limit) + clock.p2 = limit->p2.p2_slow; + else + clock.p2 = limit->p2.p2_fast; + } + + memset(best_clock, 0, sizeof(*best_clock)); + + for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; + clock.m1++) { + for (clock.m2 = limit->m2.min; + clock.m2 < clock.m1 && clock.m2 <= limit->m2.max; + clock.m2++) { + for (clock.n = limit->n.min; + clock.n <= limit->n.max; clock.n++) { + for (clock.p1 = limit->p1.min; + clock.p1 <= limit->p1.max; + clock.p1++) { + int this_err; + + psb_intel_clock(dev, refclk, &clock); + + if (!psb_intel_PLL_is_valid + (crtc, &clock)) + continue; + + this_err = abs(clock.dot - target); + if (this_err < err) { + *best_clock = clock; + err = this_err; + } + } + } + } + } + + return err != target; +} + +void psb_intel_wait_for_vblank(struct drm_device *dev) +{ + /* Wait for 20ms, i.e. one cycle at 50hz. */ + udelay(20000); +} + +int psb_intel_pipe_set_base(struct drm_crtc *crtc, + int x, int y, struct drm_framebuffer *old_fb) +{ + struct drm_device *dev = crtc->dev; + /* struct drm_i915_master_private *master_priv; */ + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); + struct psb_intel_mode_device *mode_dev = psb_intel_crtc->mode_dev; + int pipe = psb_intel_crtc->pipe; + unsigned long Start, Offset; + int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE); + int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); + int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; + u32 dspcntr; + int ret = 0; + + PSB_DEBUG_ENTRY("\n"); + + /* no fb bound */ + if (!crtc->fb) { + DRM_DEBUG("No FB bound\n"); + return 0; + } + + if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_FORCE_POWER_ON)) + return 0; + + Start = mode_dev->bo_offset(dev, psbfb); + Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); + + REG_WRITE(dspstride, crtc->fb->pitch); + + dspcntr = REG_READ(dspcntr_reg); + dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; + + switch (crtc->fb->bits_per_pixel) { + case 8: + dspcntr |= DISPPLANE_8BPP; + break; + case 16: + if (crtc->fb->depth == 15) + dspcntr |= DISPPLANE_15_16BPP; + else + dspcntr |= DISPPLANE_16BPP; + break; + case 24: + case 32: + dspcntr |= DISPPLANE_32BPP_NO_ALPHA; + break; + default: + DRM_ERROR("Unknown color depth\n"); + ret = -EINVAL; + goto psb_intel_pipe_set_base_exit; + } + REG_WRITE(dspcntr_reg, dspcntr); + + DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y); + if (0 /* FIXMEAC - check what PSB needs */) { + REG_WRITE(dspbase, Offset); + REG_READ(dspbase); + REG_WRITE(dspsurf, Start); + REG_READ(dspsurf); + } else { + REG_WRITE(dspbase, Start + Offset); + REG_READ(dspbase); + } + +psb_intel_pipe_set_base_exit: + + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + + return ret; +} + +/** + * Sets the power management mode of the pipe and plane. + * + * This code should probably grow support for turning the cursor off and back + * on appropriately at the same time as we're turning the pipe off/on. + */ +static void psb_intel_crtc_dpms(struct drm_crtc *crtc, int mode) +{ + struct drm_device *dev = crtc->dev; + /* struct drm_i915_master_private *master_priv; */ + /* struct drm_i915_private *dev_priv = dev->dev_private; */ + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int pipe = psb_intel_crtc->pipe; + int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; + int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE; + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; + u32 temp; + bool enabled; + + /* XXX: When our outputs are all unaware of DPMS modes other than off + * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. + */ + switch (mode) { + case DRM_MODE_DPMS_ON: + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + /* Enable the DPLL */ + temp = REG_READ(dpll_reg); + if ((temp & DPLL_VCO_ENABLE) == 0) { + REG_WRITE(dpll_reg, temp); + REG_READ(dpll_reg); + /* Wait for the clocks to stabilize. */ + udelay(150); + REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); + REG_READ(dpll_reg); + /* Wait for the clocks to stabilize. */ + udelay(150); + REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); + REG_READ(dpll_reg); + /* Wait for the clocks to stabilize. */ + udelay(150); + } + + /* Enable the pipe */ + temp = REG_READ(pipeconf_reg); + if ((temp & PIPEACONF_ENABLE) == 0) + REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE); + + /* Enable the plane */ + temp = REG_READ(dspcntr_reg); + if ((temp & DISPLAY_PLANE_ENABLE) == 0) { + REG_WRITE(dspcntr_reg, + temp | DISPLAY_PLANE_ENABLE); + /* Flush the plane changes */ + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); + } + + psb_intel_crtc_load_lut(crtc); + + /* Give the overlay scaler a chance to enable + * if it's on this pipe */ + /* psb_intel_crtc_dpms_video(crtc, true); TODO */ + break; + case DRM_MODE_DPMS_OFF: + /* Give the overlay scaler a chance to disable + * if it's on this pipe */ + /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */ + + /* Disable the VGA plane that we never use */ + REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); + + /* Disable display plane */ + temp = REG_READ(dspcntr_reg); + if ((temp & DISPLAY_PLANE_ENABLE) != 0) { + REG_WRITE(dspcntr_reg, + temp & ~DISPLAY_PLANE_ENABLE); + /* Flush the plane changes */ + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); + REG_READ(dspbase_reg); + } + + /* Next, disable display pipes */ + temp = REG_READ(pipeconf_reg); + if ((temp & PIPEACONF_ENABLE) != 0) { + REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); + REG_READ(pipeconf_reg); + } + + /* Wait for vblank for the disable to take effect. */ + psb_intel_wait_for_vblank(dev); + + temp = REG_READ(dpll_reg); + if ((temp & DPLL_VCO_ENABLE) != 0) { + REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE); + REG_READ(dpll_reg); + } + + /* Wait for the clocks to turn off. */ + udelay(150); + break; + } + + enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF; + + /*Set FIFO Watermarks*/ + REG_WRITE(DSPARB, 0x3F3E); +} + +static void psb_intel_crtc_prepare(struct drm_crtc *crtc) +{ + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); +} + +static void psb_intel_crtc_commit(struct drm_crtc *crtc) +{ + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); +} + +void psb_intel_encoder_prepare(struct drm_encoder *encoder) +{ + struct drm_encoder_helper_funcs *encoder_funcs = + encoder->helper_private; + /* lvds has its own version of prepare see psb_intel_lvds_prepare */ + encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF); +} + +void psb_intel_encoder_commit(struct drm_encoder *encoder) +{ + struct drm_encoder_helper_funcs *encoder_funcs = + encoder->helper_private; + /* lvds has its own version of commit see psb_intel_lvds_commit */ + encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); +} + +static bool psb_intel_crtc_mode_fixup(struct drm_crtc *crtc, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + return true; +} + + +/** + * Return the pipe currently connected to the panel fitter, + * or -1 if the panel fitter is not present or not in use + */ +static int psb_intel_panel_fitter_pipe(struct drm_device *dev) +{ + u32 pfit_control; + + pfit_control = REG_READ(PFIT_CONTROL); + + /* See if the panel fitter is in use */ + if ((pfit_control & PFIT_ENABLE) == 0) + return -1; + /* Must be on PIPE 1 for PSB */ + return 1; +} + +static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, + int x, int y, + struct drm_framebuffer *old_fb) +{ + struct drm_device *dev = crtc->dev; + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int pipe = psb_intel_crtc->pipe; + int fp_reg = (pipe == 0) ? FPA0 : FPB0; + int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; + int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; + int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; + int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; + int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; + int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; + int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; + int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE; + int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; + int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; + int refclk; + struct psb_intel_clock_t clock; + u32 dpll = 0, fp = 0, dspcntr, pipeconf; + bool ok, is_sdvo = false, is_dvo = false; + bool is_crt = false, is_lvds = false, is_tv = false; + struct drm_mode_config *mode_config = &dev->mode_config; + struct drm_connector *connector; + + list_for_each_entry(connector, &mode_config->connector_list, head) { + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + + if (!connector->encoder + || connector->encoder->crtc != crtc) + continue; + + switch (psb_intel_output->type) { + case INTEL_OUTPUT_LVDS: + is_lvds = true; + break; + case INTEL_OUTPUT_SDVO: + is_sdvo = true; + break; + case INTEL_OUTPUT_DVO: + is_dvo = true; + break; + case INTEL_OUTPUT_TVOUT: + is_tv = true; + break; + case INTEL_OUTPUT_ANALOG: + is_crt = true; + break; + } + } + + refclk = 96000; + + ok = psb_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, + &clock); + if (!ok) { + DRM_ERROR("Couldn't find PLL settings for mode!\n"); + return 0; + } + + fp = clock.n << 16 | clock.m1 << 8 | clock.m2; + + dpll = DPLL_VGA_MODE_DIS; + if (is_lvds) { + dpll |= DPLLB_MODE_LVDS; + dpll |= DPLL_DVO_HIGH_SPEED; + } else + dpll |= DPLLB_MODE_DAC_SERIAL; + if (is_sdvo) { + int sdvo_pixel_multiply = + adjusted_mode->clock / mode->clock; + dpll |= DPLL_DVO_HIGH_SPEED; + dpll |= + (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; + } + + /* compute bitmask from p1 value */ + dpll |= (1 << (clock.p1 - 1)) << 16; + switch (clock.p2) { + case 5: + dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5; + break; + case 7: + dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7; + break; + case 10: + dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10; + break; + case 14: + dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14; + break; + } + + if (is_tv) { + /* XXX: just matching BIOS for now */ +/* dpll |= PLL_REF_INPUT_TVCLKINBC; */ + dpll |= 3; + } + dpll |= PLL_REF_INPUT_DREFCLK; + + /* setup pipeconf */ + pipeconf = REG_READ(pipeconf_reg); + + /* Set up the display plane register */ + dspcntr = DISPPLANE_GAMMA_ENABLE; + + if (pipe == 0) + dspcntr |= DISPPLANE_SEL_PIPE_A; + else + dspcntr |= DISPPLANE_SEL_PIPE_B; + + dspcntr |= DISPLAY_PLANE_ENABLE; + pipeconf |= PIPEACONF_ENABLE; + dpll |= DPLL_VCO_ENABLE; + + + /* Disable the panel fitter if it was on our pipe */ + if (psb_intel_panel_fitter_pipe(dev) == pipe) + REG_WRITE(PFIT_CONTROL, 0); + + DRM_DEBUG("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); + drm_mode_debug_printmodeline(mode); + + if (dpll & DPLL_VCO_ENABLE) { + REG_WRITE(fp_reg, fp); + REG_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); + REG_READ(dpll_reg); + udelay(150); + } + + /* The LVDS pin pair needs to be on before the DPLLs are enabled. + * This is an exception to the general rule that mode_set doesn't turn + * things on. + */ + if (is_lvds) { + u32 lvds = REG_READ(LVDS); + + lvds |= + LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | + LVDS_PIPEB_SELECT; + /* Set the B0-B3 data pairs corresponding to + * whether we're going to + * set the DPLLs for dual-channel mode or not. + */ + if (clock.p2 == 7) + lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; + else + lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); + + /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) + * appropriately here, but we need to look more + * thoroughly into how panels behave in the two modes. + */ + + REG_WRITE(LVDS, lvds); + REG_READ(LVDS); + } + + REG_WRITE(fp_reg, fp); + REG_WRITE(dpll_reg, dpll); + REG_READ(dpll_reg); + /* Wait for the clocks to stabilize. */ + udelay(150); + + /* write it again -- the BIOS does, after all */ + REG_WRITE(dpll_reg, dpll); + + REG_READ(dpll_reg); + /* Wait for the clocks to stabilize. */ + udelay(150); + + REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | + ((adjusted_mode->crtc_htotal - 1) << 16)); + REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | + ((adjusted_mode->crtc_hblank_end - 1) << 16)); + REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | + ((adjusted_mode->crtc_hsync_end - 1) << 16)); + REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | + ((adjusted_mode->crtc_vtotal - 1) << 16)); + REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | + ((adjusted_mode->crtc_vblank_end - 1) << 16)); + REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | + ((adjusted_mode->crtc_vsync_end - 1) << 16)); + /* pipesrc and dspsize control the size that is scaled from, + * which should always be the user's requested size. + */ + REG_WRITE(dspsize_reg, + ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); + REG_WRITE(dsppos_reg, 0); + REG_WRITE(pipesrc_reg, + ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); + REG_WRITE(pipeconf_reg, pipeconf); + REG_READ(pipeconf_reg); + + psb_intel_wait_for_vblank(dev); + + REG_WRITE(dspcntr_reg, dspcntr); + + /* Flush the plane changes */ + { + struct drm_crtc_helper_funcs *crtc_funcs = + crtc->helper_private; + crtc_funcs->mode_set_base(crtc, x, y, old_fb); + } + + psb_intel_wait_for_vblank(dev); + + return 0; +} + +/** Loads the palette/gamma unit for the CRTC with the prepared values */ +void psb_intel_crtc_load_lut(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_psb_private *dev_priv = + (struct drm_psb_private *)dev->dev_private; + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int palreg = PALETTE_A; + int i; + + /* The clocks have to be on to load the palette. */ + if (!crtc->enabled) + return; + + switch (psb_intel_crtc->pipe) { + case 0: + break; + case 1: + palreg = PALETTE_B; + break; + case 2: + palreg = PALETTE_C; + break; + default: + DRM_ERROR("Illegal Pipe Number.\n"); + return; + } + + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_ONLY_IF_ON)) { + for (i = 0; i < 256; i++) { + REG_WRITE(palreg + 4 * i, + ((psb_intel_crtc->lut_r[i] + + psb_intel_crtc->lut_adj[i]) << 16) | + ((psb_intel_crtc->lut_g[i] + + psb_intel_crtc->lut_adj[i]) << 8) | + (psb_intel_crtc->lut_b[i] + + psb_intel_crtc->lut_adj[i])); + } + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } else { + for (i = 0; i < 256; i++) { + dev_priv->save_palette_a[i] = + ((psb_intel_crtc->lut_r[i] + + psb_intel_crtc->lut_adj[i]) << 16) | + ((psb_intel_crtc->lut_g[i] + + psb_intel_crtc->lut_adj[i]) << 8) | + (psb_intel_crtc->lut_b[i] + + psb_intel_crtc->lut_adj[i]); + } + + } +} + +/** + * Save HW states of giving crtc + */ +static void psb_intel_crtc_save(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + /* struct drm_psb_private *dev_priv = + (struct drm_psb_private *)dev->dev_private; */ + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state; + int pipeA = (psb_intel_crtc->pipe == 0); + uint32_t paletteReg; + int i; + + DRM_DEBUG("\n"); + + if (!crtc_state) { + DRM_DEBUG("No CRTC state found\n"); + return; + } + + crtc_state->saveDSPCNTR = REG_READ(pipeA ? DSPACNTR : DSPBCNTR); + crtc_state->savePIPECONF = REG_READ(pipeA ? PIPEACONF : PIPEBCONF); + crtc_state->savePIPESRC = REG_READ(pipeA ? PIPEASRC : PIPEBSRC); + crtc_state->saveFP0 = REG_READ(pipeA ? FPA0 : FPB0); + crtc_state->saveFP1 = REG_READ(pipeA ? FPA1 : FPB1); + crtc_state->saveDPLL = REG_READ(pipeA ? DPLL_A : DPLL_B); + crtc_state->saveHTOTAL = REG_READ(pipeA ? HTOTAL_A : HTOTAL_B); + crtc_state->saveHBLANK = REG_READ(pipeA ? HBLANK_A : HBLANK_B); + crtc_state->saveHSYNC = REG_READ(pipeA ? HSYNC_A : HSYNC_B); + crtc_state->saveVTOTAL = REG_READ(pipeA ? VTOTAL_A : VTOTAL_B); + crtc_state->saveVBLANK = REG_READ(pipeA ? VBLANK_A : VBLANK_B); + crtc_state->saveVSYNC = REG_READ(pipeA ? VSYNC_A : VSYNC_B); + crtc_state->saveDSPSTRIDE = REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE); + + /*NOTE: DSPSIZE DSPPOS only for psb*/ + crtc_state->saveDSPSIZE = REG_READ(pipeA ? DSPASIZE : DSPBSIZE); + crtc_state->saveDSPPOS = REG_READ(pipeA ? DSPAPOS : DSPBPOS); + + crtc_state->saveDSPBASE = REG_READ(pipeA ? DSPABASE : DSPBBASE); + + DRM_DEBUG("(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n", + crtc_state->saveDSPCNTR, + crtc_state->savePIPECONF, + crtc_state->savePIPESRC, + crtc_state->saveFP0, + crtc_state->saveFP1, + crtc_state->saveDPLL, + crtc_state->saveHTOTAL, + crtc_state->saveHBLANK, + crtc_state->saveHSYNC, + crtc_state->saveVTOTAL, + crtc_state->saveVBLANK, + crtc_state->saveVSYNC, + crtc_state->saveDSPSTRIDE, + crtc_state->saveDSPSIZE, + crtc_state->saveDSPPOS, + crtc_state->saveDSPBASE + ); + + paletteReg = pipeA ? PALETTE_A : PALETTE_B; + for (i = 0; i < 256; ++i) + crtc_state->savePalette[i] = REG_READ(paletteReg + (i << 2)); +} + +/** + * Restore HW states of giving crtc + */ +static void psb_intel_crtc_restore(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + /* struct drm_psb_private * dev_priv = + (struct drm_psb_private *)dev->dev_private; */ + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state; + /* struct drm_crtc_helper_funcs * crtc_funcs = crtc->helper_private; */ + int pipeA = (psb_intel_crtc->pipe == 0); + uint32_t paletteReg; + int i; + + DRM_DEBUG("\n"); + + if (!crtc_state) { + DRM_DEBUG("No crtc state\n"); + return; + } + + DRM_DEBUG( + "current:(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n", + REG_READ(pipeA ? DSPACNTR : DSPBCNTR), + REG_READ(pipeA ? PIPEACONF : PIPEBCONF), + REG_READ(pipeA ? PIPEASRC : PIPEBSRC), + REG_READ(pipeA ? FPA0 : FPB0), + REG_READ(pipeA ? FPA1 : FPB1), + REG_READ(pipeA ? DPLL_A : DPLL_B), + REG_READ(pipeA ? HTOTAL_A : HTOTAL_B), + REG_READ(pipeA ? HBLANK_A : HBLANK_B), + REG_READ(pipeA ? HSYNC_A : HSYNC_B), + REG_READ(pipeA ? VTOTAL_A : VTOTAL_B), + REG_READ(pipeA ? VBLANK_A : VBLANK_B), + REG_READ(pipeA ? VSYNC_A : VSYNC_B), + REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE), + REG_READ(pipeA ? DSPASIZE : DSPBSIZE), + REG_READ(pipeA ? DSPAPOS : DSPBPOS), + REG_READ(pipeA ? DSPABASE : DSPBBASE) + ); + + DRM_DEBUG( + "saved: (%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n", + crtc_state->saveDSPCNTR, + crtc_state->savePIPECONF, + crtc_state->savePIPESRC, + crtc_state->saveFP0, + crtc_state->saveFP1, + crtc_state->saveDPLL, + crtc_state->saveHTOTAL, + crtc_state->saveHBLANK, + crtc_state->saveHSYNC, + crtc_state->saveVTOTAL, + crtc_state->saveVBLANK, + crtc_state->saveVSYNC, + crtc_state->saveDSPSTRIDE, + crtc_state->saveDSPSIZE, + crtc_state->saveDSPPOS, + crtc_state->saveDSPBASE + ); + + + if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) { + REG_WRITE(pipeA ? DPLL_A : DPLL_B, + crtc_state->saveDPLL & ~DPLL_VCO_ENABLE); + REG_READ(pipeA ? DPLL_A : DPLL_B); + DRM_DEBUG("write dpll: %x\n", + REG_READ(pipeA ? DPLL_A : DPLL_B)); + udelay(150); + } + + REG_WRITE(pipeA ? FPA0 : FPB0, crtc_state->saveFP0); + REG_READ(pipeA ? FPA0 : FPB0); + + REG_WRITE(pipeA ? FPA1 : FPB1, crtc_state->saveFP1); + REG_READ(pipeA ? FPA1 : FPB1); + + REG_WRITE(pipeA ? DPLL_A : DPLL_B, crtc_state->saveDPLL); + REG_READ(pipeA ? DPLL_A : DPLL_B); + udelay(150); + + REG_WRITE(pipeA ? HTOTAL_A : HTOTAL_B, crtc_state->saveHTOTAL); + REG_WRITE(pipeA ? HBLANK_A : HBLANK_B, crtc_state->saveHBLANK); + REG_WRITE(pipeA ? HSYNC_A : HSYNC_B, crtc_state->saveHSYNC); + REG_WRITE(pipeA ? VTOTAL_A : VTOTAL_B, crtc_state->saveVTOTAL); + REG_WRITE(pipeA ? VBLANK_A : VBLANK_B, crtc_state->saveVBLANK); + REG_WRITE(pipeA ? VSYNC_A : VSYNC_B, crtc_state->saveVSYNC); + REG_WRITE(pipeA ? DSPASTRIDE : DSPBSTRIDE, crtc_state->saveDSPSTRIDE); + + REG_WRITE(pipeA ? DSPASIZE : DSPBSIZE, crtc_state->saveDSPSIZE); + REG_WRITE(pipeA ? DSPAPOS : DSPBPOS, crtc_state->saveDSPPOS); + + REG_WRITE(pipeA ? PIPEASRC : PIPEBSRC, crtc_state->savePIPESRC); + REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE); + REG_WRITE(pipeA ? PIPEACONF : PIPEBCONF, crtc_state->savePIPECONF); + + psb_intel_wait_for_vblank(dev); + + REG_WRITE(pipeA ? DSPACNTR : DSPBCNTR, crtc_state->saveDSPCNTR); + REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE); + + psb_intel_wait_for_vblank(dev); + + paletteReg = pipeA ? PALETTE_A : PALETTE_B; + for (i = 0; i < 256; ++i) + REG_WRITE(paletteReg + (i << 2), crtc_state->savePalette[i]); +} + +static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc, + struct drm_file *file_priv, + uint32_t handle, + uint32_t width, uint32_t height) +{ + struct drm_device *dev = crtc->dev; + struct drm_psb_private *dev_priv = + (struct drm_psb_private *)dev->dev_private; + struct psb_gtt *pg = dev_priv->pg; + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + struct psb_intel_mode_device *mode_dev = psb_intel_crtc->mode_dev; + int pipe = psb_intel_crtc->pipe; + uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR; + uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; + uint32_t temp; + size_t addr = 0; + uint32_t page_offset; + size_t size; + void *bo; + int ret; + + DRM_DEBUG("\n"); + + /* if we want to turn of the cursor ignore width and height */ + if (!handle) { + DRM_DEBUG("cursor off\n"); + /* turn off the cursor */ + temp = 0; + temp |= CURSOR_MODE_DISABLE; + + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_ONLY_IF_ON)) { + REG_WRITE(control, temp); + REG_WRITE(base, 0); + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } + + /* unpin the old bo */ + if (psb_intel_crtc->cursor_bo) { + mode_dev->bo_unpin_for_scanout(dev, + psb_intel_crtc-> + cursor_bo); + psb_intel_crtc->cursor_bo = NULL; + } + + return 0; + } + + /* Currently we only support 64x64 cursors */ + if (width != 64 || height != 64) { + DRM_ERROR("we currently only support 64x64 cursors\n"); + return -EINVAL; + } + + bo = mode_dev->bo_from_handle(dev, file_priv, handle); + if (!bo) + return -ENOENT; + + ret = mode_dev->bo_pin_for_scanout(dev, bo); + if (ret) + return ret; + size = mode_dev->bo_size(dev, bo); + if (size < width * height * 4) { + DRM_ERROR("buffer is to small\n"); + return -ENOMEM; + } + + /*insert this bo into gtt*/ + DRM_DEBUG("%s: map meminfo for hw cursor. handle %x\n", + __func__, handle); + + ret = psb_gtt_map_meminfo(dev, (void *)handle, &page_offset); + if (ret) { + DRM_ERROR("Can not map meminfo to GTT. handle 0x%x\n", handle); + return ret; + } + + addr = page_offset << PAGE_SHIFT; + + addr += pg->stolen_base; + + psb_intel_crtc->cursor_addr = addr; + + temp = 0; + /* set the pipe for the cursor */ + temp |= (pipe << 28); + temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; + + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_ONLY_IF_ON)) { + REG_WRITE(control, temp); + REG_WRITE(base, addr); + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } + + /* unpin the old bo */ + if (psb_intel_crtc->cursor_bo && psb_intel_crtc->cursor_bo != bo) { + mode_dev->bo_unpin_for_scanout(dev, psb_intel_crtc->cursor_bo); + psb_intel_crtc->cursor_bo = bo; + } + + return 0; +} + +static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) +{ + struct drm_device *dev = crtc->dev; + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int pipe = psb_intel_crtc->pipe; + uint32_t temp = 0; + uint32_t adder; + + + if (x < 0) { + temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT); + x = -x; + } + if (y < 0) { + temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT); + y = -y; + } + + temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT); + temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); + + adder = psb_intel_crtc->cursor_addr; + + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_ONLY_IF_ON)) { + REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp); + REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder); + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } + return 0; +} + +static void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, + u16 *green, u16 *blue, uint32_t type, uint32_t size) +{ + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int i; + + if (size != 256) + return; + + for (i = 0; i < 256; i++) { + psb_intel_crtc->lut_r[i] = red[i] >> 8; + psb_intel_crtc->lut_g[i] = green[i] >> 8; + psb_intel_crtc->lut_b[i] = blue[i] >> 8; + } + + psb_intel_crtc_load_lut(crtc); +} + +static int psb_crtc_set_config(struct drm_mode_set *set) +{ + int ret; + struct drm_device *dev = set->crtc->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + + if (!dev_priv->rpm_enabled) + return drm_crtc_helper_set_config(set); + + pm_runtime_forbid(&dev->pdev->dev); + ret = drm_crtc_helper_set_config(set); + pm_runtime_allow(&dev->pdev->dev); + return ret; +} + +/* Returns the clock of the currently programmed mode of the given pipe. */ +static int psb_intel_crtc_clock_get(struct drm_device *dev, + struct drm_crtc *crtc) +{ + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int pipe = psb_intel_crtc->pipe; + u32 dpll; + u32 fp; + struct psb_intel_clock_t clock; + bool is_lvds; + struct drm_psb_private *dev_priv = dev->dev_private; + + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_ONLY_IF_ON)) { + dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B); + if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) + fp = REG_READ((pipe == 0) ? FPA0 : FPB0); + else + fp = REG_READ((pipe == 0) ? FPA1 : FPB1); + is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN); + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } else { + dpll = (pipe == 0) ? + dev_priv->saveDPLL_A : dev_priv->saveDPLL_B; + + if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) + fp = (pipe == 0) ? + dev_priv->saveFPA0 : + dev_priv->saveFPB0; + else + fp = (pipe == 0) ? + dev_priv->saveFPA1 : + dev_priv->saveFPB1; + + is_lvds = (pipe == 1) && (dev_priv->saveLVDS & LVDS_PORT_EN); + } + + clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; + clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT; + clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT; + + if (is_lvds) { + clock.p1 = + ffs((dpll & + DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> + DPLL_FPA01_P1_POST_DIV_SHIFT); + clock.p2 = 14; + + if ((dpll & PLL_REF_INPUT_MASK) == + PLLB_REF_INPUT_SPREADSPECTRUMIN) { + /* XXX: might not be 66MHz */ + i8xx_clock(66000, &clock); + } else + i8xx_clock(48000, &clock); + } else { + if (dpll & PLL_P1_DIVIDE_BY_TWO) + clock.p1 = 2; + else { + clock.p1 = + ((dpll & + DPLL_FPA01_P1_POST_DIV_MASK_I830) >> + DPLL_FPA01_P1_POST_DIV_SHIFT) + 2; + } + if (dpll & PLL_P2_DIVIDE_BY_4) + clock.p2 = 4; + else + clock.p2 = 2; + + i8xx_clock(48000, &clock); + } + + /* XXX: It would be nice to validate the clocks, but we can't reuse + * i830PllIsValid() because it relies on the xf86_config connector + * configuration being accurate, which it isn't necessarily. + */ + + return clock.dot; +} + +/** Returns the currently programmed mode of the given pipe. */ +struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev, + struct drm_crtc *crtc) +{ + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int pipe = psb_intel_crtc->pipe; + struct drm_display_mode *mode; + int htot; + int hsync; + int vtot; + int vsync; + struct drm_psb_private *dev_priv = dev->dev_private; + + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_ONLY_IF_ON)) { + htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B); + hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B); + vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B); + vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B); + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } else { + htot = (pipe == 0) ? + dev_priv->saveHTOTAL_A : dev_priv->saveHTOTAL_B; + hsync = (pipe == 0) ? + dev_priv->saveHSYNC_A : dev_priv->saveHSYNC_B; + vtot = (pipe == 0) ? + dev_priv->saveVTOTAL_A : dev_priv->saveVTOTAL_B; + vsync = (pipe == 0) ? + dev_priv->saveVSYNC_A : dev_priv->saveVSYNC_B; + } + + mode = kzalloc(sizeof(*mode), GFP_KERNEL); + if (!mode) + return NULL; + + mode->clock = psb_intel_crtc_clock_get(dev, crtc); + mode->hdisplay = (htot & 0xffff) + 1; + mode->htotal = ((htot & 0xffff0000) >> 16) + 1; + mode->hsync_start = (hsync & 0xffff) + 1; + mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1; + mode->vdisplay = (vtot & 0xffff) + 1; + mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1; + mode->vsync_start = (vsync & 0xffff) + 1; + mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1; + + drm_mode_set_name(mode); + drm_mode_set_crtcinfo(mode, 0); + + return mode; +} + +static void psb_intel_crtc_destroy(struct drm_crtc *crtc) +{ + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + + kfree(psb_intel_crtc->crtc_state); + drm_crtc_cleanup(crtc); + kfree(psb_intel_crtc); +} + +static const struct drm_crtc_helper_funcs psb_intel_helper_funcs = { + .dpms = psb_intel_crtc_dpms, + .mode_fixup = psb_intel_crtc_mode_fixup, + .mode_set = psb_intel_crtc_mode_set, + .mode_set_base = psb_intel_pipe_set_base, + .prepare = psb_intel_crtc_prepare, + .commit = psb_intel_crtc_commit, +}; + +static const struct drm_crtc_helper_funcs mrst_helper_funcs; +static const struct drm_crtc_helper_funcs mdfld_helper_funcs; +const struct drm_crtc_funcs mdfld_intel_crtc_funcs; + +const struct drm_crtc_funcs psb_intel_crtc_funcs = { + .save = psb_intel_crtc_save, + .restore = psb_intel_crtc_restore, + .cursor_set = psb_intel_crtc_cursor_set, + .cursor_move = psb_intel_crtc_cursor_move, + .gamma_set = psb_intel_crtc_gamma_set, + .set_config = psb_crtc_set_config, + .destroy = psb_intel_crtc_destroy, +}; + +void psb_intel_crtc_init(struct drm_device *dev, int pipe, + struct psb_intel_mode_device *mode_dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_intel_crtc *psb_intel_crtc; + int i; + uint16_t *r_base, *g_base, *b_base; + + PSB_DEBUG_ENTRY("\n"); + + /* We allocate a extra array of drm_connector pointers + * for fbdev after the crtc */ + psb_intel_crtc = + kzalloc(sizeof(struct psb_intel_crtc) + + (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)), + GFP_KERNEL); + if (psb_intel_crtc == NULL) + return; + + psb_intel_crtc->crtc_state = + kzalloc(sizeof(struct psb_intel_crtc_state), GFP_KERNEL); + if (!psb_intel_crtc->crtc_state) { + DRM_INFO("Crtc state error: No memory\n"); + kfree(psb_intel_crtc); + return; + } + + drm_crtc_init(dev, &psb_intel_crtc->base, &psb_intel_crtc_funcs); + + drm_mode_crtc_set_gamma_size(&psb_intel_crtc->base, 256); + psb_intel_crtc->pipe = pipe; + psb_intel_crtc->plane = pipe; + + r_base = psb_intel_crtc->base.gamma_store; + g_base = r_base + 256; + b_base = g_base + 256; + for (i = 0; i < 256; i++) { + psb_intel_crtc->lut_r[i] = i; + psb_intel_crtc->lut_g[i] = i; + psb_intel_crtc->lut_b[i] = i; + r_base[i] = i << 8; + g_base[i] = i << 8; + b_base[i] = i << 8; + + psb_intel_crtc->lut_adj[i] = 0; + } + + psb_intel_crtc->mode_dev = mode_dev; + psb_intel_crtc->cursor_addr = 0; + + drm_crtc_helper_add(&psb_intel_crtc->base, + &psb_intel_helper_funcs); + + /* Setup the array of drm_connector pointer array */ + psb_intel_crtc->mode_set.crtc = &psb_intel_crtc->base; + BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) || + dev_priv->plane_to_crtc_mapping[psb_intel_crtc->plane] != NULL); + dev_priv->plane_to_crtc_mapping[psb_intel_crtc->plane] = + &psb_intel_crtc->base; + dev_priv->pipe_to_crtc_mapping[psb_intel_crtc->pipe] = + &psb_intel_crtc->base; + psb_intel_crtc->mode_set.connectors = + (struct drm_connector **) (psb_intel_crtc + 1); + psb_intel_crtc->mode_set.num_connectors = 0; +} + +int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct drm_psb_get_pipe_from_crtc_id_arg *pipe_from_crtc_id = data; + struct drm_mode_object *drmmode_obj; + struct psb_intel_crtc *crtc; + + if (!dev_priv) { + DRM_ERROR("called with no initialization\n"); + return -EINVAL; + } + + drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id, + DRM_MODE_OBJECT_CRTC); + + if (!drmmode_obj) { + DRM_ERROR("no such CRTC id\n"); + return -EINVAL; + } + + crtc = to_psb_intel_crtc(obj_to_crtc(drmmode_obj)); + pipe_from_crtc_id->pipe = crtc->pipe; + + return 0; +} + +struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev, int pipe) +{ + struct drm_crtc *crtc = NULL; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + if (psb_intel_crtc->pipe == pipe) + break; + } + return crtc; +} + +int psb_intel_connector_clones(struct drm_device *dev, int type_mask) +{ + int index_mask = 0; + struct drm_connector *connector; + int entry = 0; + + list_for_each_entry(connector, &dev->mode_config.connector_list, + head) { + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + if (type_mask & (1 << psb_intel_output->type)) + index_mask |= (1 << entry); + entry++; + } + return index_mask; +} + + +void psb_intel_modeset_cleanup(struct drm_device *dev) +{ + drm_mode_config_cleanup(dev); +} + + +/* current intel driver doesn't take advantage of encoders + always give back the encoder for the connector +*/ +struct drm_encoder *psb_intel_best_encoder(struct drm_connector *connector) +{ + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + + return &psb_intel_output->enc; +} + diff --git a/drivers/staging/gma500/psb_intel_display.h b/drivers/staging/gma500/psb_intel_display.h new file mode 100644 index 000000000000..74e3b5e5deaf --- /dev/null +++ b/drivers/staging/gma500/psb_intel_display.h @@ -0,0 +1,25 @@ +/* copyright (c) 2008, Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Authors: + * Eric Anholt + */ + +#ifndef _INTEL_DISPLAY_H_ +#define _INTEL_DISPLAY_H_ + +bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type); + +#endif diff --git a/drivers/staging/gma500/psb_intel_drv.h b/drivers/staging/gma500/psb_intel_drv.h new file mode 100644 index 000000000000..cb0a91b78173 --- /dev/null +++ b/drivers/staging/gma500/psb_intel_drv.h @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2009, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef __INTEL_DRV_H__ +#define __INTEL_DRV_H__ + +#include +#include +#include +#include +#include + +/* + * MOORESTOWN defines + */ +#define DELAY_TIME1 2000 /* 1000 = 1ms */ + +/* + * Display related stuff + */ + +/* store information about an Ixxx DVO */ +/* The i830->i865 use multiple DVOs with multiple i2cs */ +/* the i915, i945 have a single sDVO i2c bus - which is different */ +#define MAX_OUTPUTS 6 +/* maximum connectors per crtcs in the mode set */ +#define INTELFB_CONN_LIMIT 4 + +#define INTEL_I2C_BUS_DVO 1 +#define INTEL_I2C_BUS_SDVO 2 + +/* these are outputs from the chip - integrated only + * external chips are via DVO or SDVO output */ +#define INTEL_OUTPUT_UNUSED 0 +#define INTEL_OUTPUT_ANALOG 1 +#define INTEL_OUTPUT_DVO 2 +#define INTEL_OUTPUT_SDVO 3 +#define INTEL_OUTPUT_LVDS 4 +#define INTEL_OUTPUT_TVOUT 5 +#define INTEL_OUTPUT_HDMI 6 +#define INTEL_OUTPUT_MIPI 7 +#define INTEL_OUTPUT_MIPI2 8 + +#define INTEL_DVO_CHIP_NONE 0 +#define INTEL_DVO_CHIP_LVDS 1 +#define INTEL_DVO_CHIP_TMDS 2 +#define INTEL_DVO_CHIP_TVOUT 4 + +enum mipi_panel_type { + NSC_800X480 = 1, + LGE_480X1024 = 2, + TPO_864X480 = 3 +}; + +/** + * Hold information useally put on the device driver privates here, + * since it needs to be shared across multiple of devices drivers privates. +*/ +struct psb_intel_mode_device { + + /* + * Abstracted memory manager operations + */ + void *(*bo_from_handle) (struct drm_device *dev, + struct drm_file *file_priv, + unsigned int handle); + size_t(*bo_size) (struct drm_device *dev, void *bo); + size_t(*bo_offset) (struct drm_device *dev, void *bo); + int (*bo_pin_for_scanout) (struct drm_device *dev, void *bo); + int (*bo_unpin_for_scanout) (struct drm_device *dev, void *bo); + + /* + * Cursor + */ + int cursor_needs_physical; + + /* + * LVDS info + */ + int backlight_duty_cycle; /* restore backlight to this value */ + bool panel_wants_dither; + struct drm_display_mode *panel_fixed_mode; + struct drm_display_mode *panel_fixed_mode2; + struct drm_display_mode *vbt_mode; /* if any */ + + uint32_t saveBLC_PWM_CTL; +}; + +struct psb_intel_i2c_chan { + /* for getting at dev. private (mmio etc.) */ + struct drm_device *drm_dev; + u32 reg; /* GPIO reg */ + struct i2c_adapter adapter; + struct i2c_algo_bit_data algo; + u8 slave_addr; +}; + +struct psb_intel_output { + struct drm_connector base; + + struct drm_encoder enc; + int type; + + struct psb_intel_i2c_chan *i2c_bus; /* for control functions */ + struct psb_intel_i2c_chan *ddc_bus; /* for DDC only stuff */ + bool load_detect_temp; + void *dev_priv; + + struct psb_intel_mode_device *mode_dev; + +}; + +struct psb_intel_crtc_state { + uint32_t saveDSPCNTR; + uint32_t savePIPECONF; + uint32_t savePIPESRC; + uint32_t saveDPLL; + uint32_t saveFP0; + uint32_t saveFP1; + uint32_t saveHTOTAL; + uint32_t saveHBLANK; + uint32_t saveHSYNC; + uint32_t saveVTOTAL; + uint32_t saveVBLANK; + uint32_t saveVSYNC; + uint32_t saveDSPSTRIDE; + uint32_t saveDSPSIZE; + uint32_t saveDSPPOS; + uint32_t saveDSPBASE; + uint32_t savePalette[256]; +}; + +struct psb_intel_crtc { + struct drm_crtc base; + int pipe; + int plane; + uint32_t cursor_addr; + u8 lut_r[256], lut_g[256], lut_b[256]; + u8 lut_adj[256]; + struct psb_intel_framebuffer *fbdev_fb; + /* a mode_set for fbdev users on this crtc */ + struct drm_mode_set mode_set; + + /* current bo we scanout from */ + void *scanout_bo; + + /* current bo we cursor from */ + void *cursor_bo; + + struct drm_display_mode saved_mode; + struct drm_display_mode saved_adjusted_mode; + + struct psb_intel_mode_device *mode_dev; + + /*crtc mode setting flags*/ + u32 mode_flags; + + /* Saved Crtc HW states */ + struct psb_intel_crtc_state *crtc_state; +}; + +#define to_psb_intel_crtc(x) \ + container_of(x, struct psb_intel_crtc, base) +#define to_psb_intel_output(x) \ + container_of(x, struct psb_intel_output, base) +#define enc_to_psb_intel_output(x) \ + container_of(x, struct psb_intel_output, enc) +#define to_psb_intel_framebuffer(x) \ + container_of(x, struct psb_intel_framebuffer, base) + +struct psb_intel_i2c_chan *psb_intel_i2c_create(struct drm_device *dev, + const u32 reg, const char *name); +void psb_intel_i2c_destroy(struct psb_intel_i2c_chan *chan); +int psb_intel_ddc_get_modes(struct psb_intel_output *psb_intel_output); +extern bool psb_intel_ddc_probe(struct psb_intel_output *psb_intel_output); + +extern void psb_intel_crtc_init(struct drm_device *dev, int pipe, + struct psb_intel_mode_device *mode_dev); +extern void psb_intel_crt_init(struct drm_device *dev); +extern void psb_intel_sdvo_init(struct drm_device *dev, int output_device); +extern void psb_intel_dvo_init(struct drm_device *dev); +extern void psb_intel_tv_init(struct drm_device *dev); +extern void psb_intel_lvds_init(struct drm_device *dev, + struct psb_intel_mode_device *mode_dev); +extern void psb_intel_lvds_set_brightness(struct drm_device *dev, int level); +extern void mrst_lvds_init(struct drm_device *dev, + struct psb_intel_mode_device *mode_dev); +extern void mrst_wait_for_INTR_PKT_SENT(struct drm_device *dev); +extern void mrst_dsi_init(struct drm_device *dev, + struct psb_intel_mode_device *mode_dev); +extern void mid_dsi_init(struct drm_device *dev, + struct psb_intel_mode_device *mode_dev, int dsi_num); + +extern void psb_intel_crtc_load_lut(struct drm_crtc *crtc); +extern void psb_intel_encoder_prepare(struct drm_encoder *encoder); +extern void psb_intel_encoder_commit(struct drm_encoder *encoder); + +extern struct drm_encoder *psb_intel_best_encoder(struct drm_connector + *connector); + +extern struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev, + struct drm_crtc *crtc); +extern void psb_intel_wait_for_vblank(struct drm_device *dev); +extern int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev, + int pipe); +extern struct drm_connector *psb_intel_sdvo_find(struct drm_device *dev, + int sdvoB); +extern int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector); +extern void psb_intel_sdvo_set_hotplug(struct drm_connector *connector, + int enable); +extern int intelfb_probe(struct drm_device *dev); +extern int intelfb_remove(struct drm_device *dev, + struct drm_framebuffer *fb); +extern struct drm_framebuffer *psb_intel_framebuffer_create(struct drm_device + *dev, struct + drm_mode_fb_cmd + *mode_cmd, + void *mm_private); +extern bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); +extern int psb_intel_lvds_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode); +extern int psb_intel_lvds_set_property(struct drm_connector *connector, + struct drm_property *property, + uint64_t value); +extern void psb_intel_lvds_destroy(struct drm_connector *connector); +extern const struct drm_encoder_funcs psb_intel_lvds_enc_funcs; + +#endif /* __INTEL_DRV_H__ */ diff --git a/drivers/staging/gma500/psb_intel_i2c.c b/drivers/staging/gma500/psb_intel_i2c.c new file mode 100644 index 000000000000..e33432df510c --- /dev/null +++ b/drivers/staging/gma500/psb_intel_i2c.c @@ -0,0 +1,169 @@ +/* + * Copyright © 2006-2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Authors: + * Eric Anholt + */ + +#include +#include + +#include "psb_drv.h" +#include "psb_intel_reg.h" + +/* + * Intel GPIO access functions + */ + +#define I2C_RISEFALL_TIME 20 + +static int get_clock(void *data) +{ + struct psb_intel_i2c_chan *chan = data; + struct drm_device *dev = chan->drm_dev; + u32 val; + + val = REG_READ(chan->reg); + return (val & GPIO_CLOCK_VAL_IN) != 0; +} + +static int get_data(void *data) +{ + struct psb_intel_i2c_chan *chan = data; + struct drm_device *dev = chan->drm_dev; + u32 val; + + val = REG_READ(chan->reg); + return (val & GPIO_DATA_VAL_IN) != 0; +} + +static void set_clock(void *data, int state_high) +{ + struct psb_intel_i2c_chan *chan = data; + struct drm_device *dev = chan->drm_dev; + u32 reserved = 0, clock_bits; + + /* On most chips, these bits must be preserved in software. */ + reserved = + REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE | + GPIO_CLOCK_PULLUP_DISABLE); + + if (state_high) + clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK; + else + clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | + GPIO_CLOCK_VAL_MASK; + REG_WRITE(chan->reg, reserved | clock_bits); + udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */ +} + +static void set_data(void *data, int state_high) +{ + struct psb_intel_i2c_chan *chan = data; + struct drm_device *dev = chan->drm_dev; + u32 reserved = 0, data_bits; + + /* On most chips, these bits must be preserved in software. */ + reserved = + REG_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE | + GPIO_CLOCK_PULLUP_DISABLE); + + if (state_high) + data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK; + else + data_bits = + GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | + GPIO_DATA_VAL_MASK; + + REG_WRITE(chan->reg, reserved | data_bits); + udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */ +} + +/** + * psb_intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg + * @dev: DRM device + * @output: driver specific output device + * @reg: GPIO reg to use + * @name: name for this bus + * + * Creates and registers a new i2c bus with the Linux i2c layer, for use + * in output probing and control (e.g. DDC or SDVO control functions). + * + * Possible values for @reg include: + * %GPIOA + * %GPIOB + * %GPIOC + * %GPIOD + * %GPIOE + * %GPIOF + * %GPIOG + * %GPIOH + * see PRM for details on how these different busses are used. + */ +struct psb_intel_i2c_chan *psb_intel_i2c_create(struct drm_device *dev, + const u32 reg, const char *name) +{ + struct psb_intel_i2c_chan *chan; + + chan = kzalloc(sizeof(struct psb_intel_i2c_chan), GFP_KERNEL); + if (!chan) + goto out_free; + + chan->drm_dev = dev; + chan->reg = reg; + snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name); + chan->adapter.owner = THIS_MODULE; + chan->adapter.algo_data = &chan->algo; + chan->adapter.dev.parent = &dev->pdev->dev; + chan->algo.setsda = set_data; + chan->algo.setscl = set_clock; + chan->algo.getsda = get_data; + chan->algo.getscl = get_clock; + chan->algo.udelay = 20; + chan->algo.timeout = usecs_to_jiffies(2200); + chan->algo.data = chan; + + i2c_set_adapdata(&chan->adapter, chan); + + if (i2c_bit_add_bus(&chan->adapter)) + goto out_free; + + /* JJJ: raise SCL and SDA? */ + set_data(chan, 1); + set_clock(chan, 1); + udelay(20); + + return chan; + +out_free: + kfree(chan); + return NULL; +} + +/** + * psb_intel_i2c_destroy - unregister and free i2c bus resources + * @output: channel to free + * + * Unregister the adapter from the i2c layer, then free the structure. + */ +void psb_intel_i2c_destroy(struct psb_intel_i2c_chan *chan) +{ + if (!chan) + return; + + i2c_del_adapter(&chan->adapter); + kfree(chan); +} diff --git a/drivers/staging/gma500/psb_intel_lvds.c b/drivers/staging/gma500/psb_intel_lvds.c new file mode 100644 index 000000000000..d3d210a1026a --- /dev/null +++ b/drivers/staging/gma500/psb_intel_lvds.c @@ -0,0 +1,889 @@ +/* + * Copyright © 2006-2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Authors: + * Eric Anholt + * Dave Airlie + * Jesse Barnes + */ + +#include +/* #include */ +/* #include */ +#include + +#include "psb_intel_bios.h" +#include "psb_drv.h" +#include "psb_intel_drv.h" +#include "psb_intel_reg.h" +#include "psb_powermgmt.h" +#include + +/* MRST defines start */ +uint8_t blc_freq; +uint8_t blc_minbrightness; +uint8_t blc_i2caddr; +uint8_t blc_brightnesscmd; +int lvds_backlight; /* restore backlight to this value */ + +u32 CoreClock; +u32 PWMControlRegFreq; + +/** + * LVDS I2C backlight control macros + */ +#define BRIGHTNESS_MAX_LEVEL 100 +#define BRIGHTNESS_MASK 0xFF +#define BLC_I2C_TYPE 0x01 +#define BLC_PWM_TYPT 0x02 + +#define BLC_POLARITY_NORMAL 0 +#define BLC_POLARITY_INVERSE 1 + +#define PSB_BLC_MAX_PWM_REG_FREQ (0xFFFE) +#define PSB_BLC_MIN_PWM_REG_FREQ (0x2) +#define PSB_BLC_PWM_PRECISION_FACTOR (10) +#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16) +#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) + +struct psb_intel_lvds_priv { + /** + * Saved LVDO output states + */ + uint32_t savePP_ON; + uint32_t savePP_OFF; + uint32_t saveLVDS; + uint32_t savePP_CONTROL; + uint32_t savePP_CYCLE; + uint32_t savePFIT_CONTROL; + uint32_t savePFIT_PGM_RATIOS; + uint32_t saveBLC_PWM_CTL; +}; + +/* MRST defines end */ + +/** + * Returns the maximum level of the backlight duty cycle field. + */ +static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + u32 retVal; + + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_ONLY_IF_ON)) { + retVal = ((REG_READ(BLC_PWM_CTL) & + BACKLIGHT_MODULATION_FREQ_MASK) >> + BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; + + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } else + retVal = ((dev_priv->saveBLC_PWM_CTL & + BACKLIGHT_MODULATION_FREQ_MASK) >> + BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; + + return retVal; +} + +/** + * Set LVDS backlight level by I2C command + */ +static int psb_lvds_i2c_set_brightness(struct drm_device *dev, + unsigned int level) +{ + struct drm_psb_private *dev_priv = + (struct drm_psb_private *)dev->dev_private; + + struct psb_intel_i2c_chan *lvds_i2c_bus = dev_priv->lvds_i2c_bus; + u8 out_buf[2]; + unsigned int blc_i2c_brightness; + + struct i2c_msg msgs[] = { + { + .addr = lvds_i2c_bus->slave_addr, + .flags = 0, + .len = 2, + .buf = out_buf, + } + }; + + blc_i2c_brightness = BRIGHTNESS_MASK & ((unsigned int)level * + BRIGHTNESS_MASK / + BRIGHTNESS_MAX_LEVEL); + + if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE) + blc_i2c_brightness = BRIGHTNESS_MASK - blc_i2c_brightness; + + out_buf[0] = dev_priv->lvds_bl->brightnesscmd; + out_buf[1] = (u8)blc_i2c_brightness; + + if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1) { + DRM_DEBUG("I2C set brightness.(command, value) (%d, %d)\n", + blc_brightnesscmd, + blc_i2c_brightness); + return 0; + } + + DRM_ERROR("I2C transfer error\n"); + return -1; +} + + +static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level) +{ + struct drm_psb_private *dev_priv = + (struct drm_psb_private *)dev->dev_private; + + u32 max_pwm_blc; + u32 blc_pwm_duty_cycle; + + max_pwm_blc = psb_intel_lvds_get_max_backlight(dev); + + /*BLC_PWM_CTL Should be initiated while backlight device init*/ + BUG_ON((max_pwm_blc & PSB_BLC_MAX_PWM_REG_FREQ) == 0); + + blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL; + + if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE) + blc_pwm_duty_cycle = max_pwm_blc - blc_pwm_duty_cycle; + + blc_pwm_duty_cycle &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR; + REG_WRITE(BLC_PWM_CTL, + (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) | + (blc_pwm_duty_cycle)); + + return 0; +} + +/** + * Set LVDS backlight level either by I2C or PWM + */ +void psb_intel_lvds_set_brightness(struct drm_device *dev, int level) +{ + /*u32 blc_pwm_ctl;*/ + struct drm_psb_private *dev_priv = + (struct drm_psb_private *)dev->dev_private; + + DRM_DEBUG("backlight level is %d\n", level); + + if (!dev_priv->lvds_bl) { + DRM_ERROR("NO LVDS Backlight Info\n"); + return; + } + + if (dev_priv->lvds_bl->type == BLC_I2C_TYPE) + psb_lvds_i2c_set_brightness(dev, level); + else + psb_lvds_pwm_set_brightness(dev, level); +} + +/** + * Sets the backlight level. + * + * \param level backlight level, from 0 to psb_intel_lvds_get_max_backlight(). + */ +static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + u32 blc_pwm_ctl; + + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_ONLY_IF_ON)) { + blc_pwm_ctl = + REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; + REG_WRITE(BLC_PWM_CTL, + (blc_pwm_ctl | + (level << BACKLIGHT_DUTY_CYCLE_SHIFT))); + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } else { + blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL & + ~BACKLIGHT_DUTY_CYCLE_MASK; + dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl | + (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); + } +} + +/** + * Sets the power state for the panel. + */ +static void psb_intel_lvds_set_power(struct drm_device *dev, + struct psb_intel_output *output, bool on) +{ + u32 pp_status; + + if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_FORCE_POWER_ON)) + return; + + if (on) { + REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | + POWER_TARGET_ON); + do { + pp_status = REG_READ(PP_STATUS); + } while ((pp_status & PP_ON) == 0); + + psb_intel_lvds_set_backlight(dev, + output-> + mode_dev->backlight_duty_cycle); + } else { + psb_intel_lvds_set_backlight(dev, 0); + + REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & + ~POWER_TARGET_ON); + do { + pp_status = REG_READ(PP_STATUS); + } while (pp_status & PP_ON); + } + + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); +} + +static void psb_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode) +{ + struct drm_device *dev = encoder->dev; + struct psb_intel_output *output = enc_to_psb_intel_output(encoder); + + if (mode == DRM_MODE_DPMS_ON) + psb_intel_lvds_set_power(dev, output, true); + else + psb_intel_lvds_set_power(dev, output, false); + + /* XXX: We never power down the LVDS pairs. */ +} + +static void psb_intel_lvds_save(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct drm_psb_private *dev_priv = + (struct drm_psb_private *)dev->dev_private; + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + struct psb_intel_lvds_priv *lvds_priv = + (struct psb_intel_lvds_priv *)psb_intel_output->dev_priv; + + lvds_priv->savePP_ON = REG_READ(LVDSPP_ON); + lvds_priv->savePP_OFF = REG_READ(LVDSPP_OFF); + lvds_priv->saveLVDS = REG_READ(LVDS); + lvds_priv->savePP_CONTROL = REG_READ(PP_CONTROL); + lvds_priv->savePP_CYCLE = REG_READ(PP_CYCLE); + /*lvds_priv->savePP_DIVISOR = REG_READ(PP_DIVISOR);*/ + lvds_priv->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL); + lvds_priv->savePFIT_CONTROL = REG_READ(PFIT_CONTROL); + lvds_priv->savePFIT_PGM_RATIOS = REG_READ(PFIT_PGM_RATIOS); + + /*TODO: move backlight_duty_cycle to psb_intel_lvds_priv*/ + dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL & + BACKLIGHT_DUTY_CYCLE_MASK); + + /* + * If the light is off at server startup, + * just make it full brightness + */ + if (dev_priv->backlight_duty_cycle == 0) + dev_priv->backlight_duty_cycle = + psb_intel_lvds_get_max_backlight(dev); + + DRM_DEBUG("(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", + lvds_priv->savePP_ON, + lvds_priv->savePP_OFF, + lvds_priv->saveLVDS, + lvds_priv->savePP_CONTROL, + lvds_priv->savePP_CYCLE, + lvds_priv->saveBLC_PWM_CTL); +} + +static void psb_intel_lvds_restore(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + u32 pp_status; + + /*struct drm_psb_private *dev_priv = + (struct drm_psb_private *)dev->dev_private;*/ + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + struct psb_intel_lvds_priv *lvds_priv = + (struct psb_intel_lvds_priv *)psb_intel_output->dev_priv; + + DRM_DEBUG("(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", + lvds_priv->savePP_ON, + lvds_priv->savePP_OFF, + lvds_priv->saveLVDS, + lvds_priv->savePP_CONTROL, + lvds_priv->savePP_CYCLE, + lvds_priv->saveBLC_PWM_CTL); + + REG_WRITE(BLC_PWM_CTL, lvds_priv->saveBLC_PWM_CTL); + REG_WRITE(PFIT_CONTROL, lvds_priv->savePFIT_CONTROL); + REG_WRITE(PFIT_PGM_RATIOS, lvds_priv->savePFIT_PGM_RATIOS); + REG_WRITE(LVDSPP_ON, lvds_priv->savePP_ON); + REG_WRITE(LVDSPP_OFF, lvds_priv->savePP_OFF); + /*REG_WRITE(PP_DIVISOR, lvds_priv->savePP_DIVISOR);*/ + REG_WRITE(PP_CYCLE, lvds_priv->savePP_CYCLE); + REG_WRITE(PP_CONTROL, lvds_priv->savePP_CONTROL); + REG_WRITE(LVDS, lvds_priv->saveLVDS); + + if (lvds_priv->savePP_CONTROL & POWER_TARGET_ON) { + REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | + POWER_TARGET_ON); + do { + pp_status = REG_READ(PP_STATUS); + } while ((pp_status & PP_ON) == 0); + } else { + REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & + ~POWER_TARGET_ON); + do { + pp_status = REG_READ(PP_STATUS); + } while (pp_status & PP_ON); + } +} + +int psb_intel_lvds_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + struct drm_display_mode *fixed_mode = + psb_intel_output->mode_dev->panel_fixed_mode; + + PSB_DEBUG_ENTRY("\n"); + + if (psb_intel_output->type == INTEL_OUTPUT_MIPI2) + fixed_mode = psb_intel_output->mode_dev->panel_fixed_mode2; + + /* just in case */ + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) + return MODE_NO_DBLESCAN; + + /* just in case */ + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + return MODE_NO_INTERLACE; + + if (fixed_mode) { + if (mode->hdisplay > fixed_mode->hdisplay) + return MODE_PANEL; + if (mode->vdisplay > fixed_mode->vdisplay) + return MODE_PANEL; + } + return MODE_OK; +} + +bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct psb_intel_mode_device *mode_dev = + enc_to_psb_intel_output(encoder)->mode_dev; + struct drm_device *dev = encoder->dev; + struct psb_intel_crtc *psb_intel_crtc = + to_psb_intel_crtc(encoder->crtc); + struct drm_encoder *tmp_encoder; + struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode; + struct psb_intel_output *psb_intel_output = + enc_to_psb_intel_output(encoder); + + PSB_DEBUG_ENTRY("type = 0x%x, pipe = %d.\n", + psb_intel_output->type, psb_intel_crtc->pipe); + + if (psb_intel_output->type == INTEL_OUTPUT_MIPI2) + panel_fixed_mode = mode_dev->panel_fixed_mode2; + + /* PSB doesn't appear to be GEN4 */ + if (psb_intel_crtc->pipe == 0) { + printk(KERN_ERR "Can't support LVDS on pipe A\n"); + return false; + } + /* Should never happen!! */ + list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, + head) { + if (tmp_encoder != encoder + && tmp_encoder->crtc == encoder->crtc) { + printk(KERN_ERR "Can't enable LVDS and another " + "encoder on the same pipe\n"); + return false; + } + } + + /* + * If we have timings from the BIOS for the panel, put them in + * to the adjusted mode. The CRTC will be set up for this mode, + * with the panel scaling set up to source from the H/VDisplay + * of the original mode. + */ + if (panel_fixed_mode != NULL) { + adjusted_mode->hdisplay = panel_fixed_mode->hdisplay; + adjusted_mode->hsync_start = panel_fixed_mode->hsync_start; + adjusted_mode->hsync_end = panel_fixed_mode->hsync_end; + adjusted_mode->htotal = panel_fixed_mode->htotal; + adjusted_mode->vdisplay = panel_fixed_mode->vdisplay; + adjusted_mode->vsync_start = panel_fixed_mode->vsync_start; + adjusted_mode->vsync_end = panel_fixed_mode->vsync_end; + adjusted_mode->vtotal = panel_fixed_mode->vtotal; + adjusted_mode->clock = panel_fixed_mode->clock; + drm_mode_set_crtcinfo(adjusted_mode, + CRTC_INTERLACE_HALVE_V); + } + + /* + * XXX: It would be nice to support lower refresh rates on the + * panels to reduce power consumption, and perhaps match the + * user's requested refresh rate. + */ + + return true; +} + +static void psb_intel_lvds_prepare(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + struct psb_intel_output *output = enc_to_psb_intel_output(encoder); + struct psb_intel_mode_device *mode_dev = output->mode_dev; + + PSB_DEBUG_ENTRY("\n"); + + if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_FORCE_POWER_ON)) + return; + + mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL); + mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL & + BACKLIGHT_DUTY_CYCLE_MASK); + + psb_intel_lvds_set_power(dev, output, false); + + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); +} + +static void psb_intel_lvds_commit(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + struct psb_intel_output *output = enc_to_psb_intel_output(encoder); + struct psb_intel_mode_device *mode_dev = output->mode_dev; + + PSB_DEBUG_ENTRY("\n"); + + if (mode_dev->backlight_duty_cycle == 0) + mode_dev->backlight_duty_cycle = + psb_intel_lvds_get_max_backlight(dev); + + psb_intel_lvds_set_power(dev, output, true); +} + +static void psb_intel_lvds_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct psb_intel_mode_device *mode_dev = + enc_to_psb_intel_output(encoder)->mode_dev; + struct drm_device *dev = encoder->dev; + u32 pfit_control; + + /* + * The LVDS pin pair will already have been turned on in the + * psb_intel_crtc_mode_set since it has a large impact on the DPLL + * settings. + */ + + /* + * Enable automatic panel scaling so that non-native modes fill the + * screen. Should be enabled before the pipe is enabled, according to + * register description and PRM. + */ + if (mode->hdisplay != adjusted_mode->hdisplay || + mode->vdisplay != adjusted_mode->vdisplay) + pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE | + HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR | + HORIZ_INTERP_BILINEAR); + else + pfit_control = 0; + + if (mode_dev->panel_wants_dither) + pfit_control |= PANEL_8TO6_DITHER_ENABLE; + + REG_WRITE(PFIT_CONTROL, pfit_control); +} + +/** + * Detect the LVDS connection. + * + * This always returns CONNECTOR_STATUS_CONNECTED. + * This connector should only have + * been set up if the LVDS was actually connected anyway. + */ +static enum drm_connector_status psb_intel_lvds_detect(struct drm_connector + *connector, bool force) +{ + return connector_status_connected; +} + +/** + * Return the list of DDC modes if available, or the BIOS fixed mode otherwise. + */ +static int psb_intel_lvds_get_modes(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + struct psb_intel_mode_device *mode_dev = + psb_intel_output->mode_dev; + int ret = 0; + + ret = psb_intel_ddc_get_modes(psb_intel_output); + + if (ret) + return ret; + + /* Didn't get an EDID, so + * Set wide sync ranges so we get all modes + * handed to valid_mode for checking + */ + connector->display_info.min_vfreq = 0; + connector->display_info.max_vfreq = 200; + connector->display_info.min_hfreq = 0; + connector->display_info.max_hfreq = 200; + + if (mode_dev->panel_fixed_mode != NULL) { + struct drm_display_mode *mode = + drm_mode_duplicate(dev, mode_dev->panel_fixed_mode); + drm_mode_probed_add(connector, mode); + return 1; + } + + return 0; +} + +/** + * psb_intel_lvds_destroy - unregister and free LVDS structures + * @connector: connector to free + * + * Unregister the DDC bus for this connector then free the driver private + * structure. + */ +void psb_intel_lvds_destroy(struct drm_connector *connector) +{ + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + + if (psb_intel_output->ddc_bus) + psb_intel_i2c_destroy(psb_intel_output->ddc_bus); + drm_sysfs_connector_remove(connector); + drm_connector_cleanup(connector); + kfree(connector); +} + +int psb_intel_lvds_set_property(struct drm_connector *connector, + struct drm_property *property, + uint64_t value) +{ + struct drm_encoder *pEncoder = connector->encoder; + + PSB_DEBUG_ENTRY("\n"); + + if (!strcmp(property->name, "scaling mode") && pEncoder) { + struct psb_intel_crtc *pPsbCrtc = + to_psb_intel_crtc(pEncoder->crtc); + uint64_t curValue; + + PSB_DEBUG_ENTRY("scaling mode\n"); + + if (!pPsbCrtc) + goto set_prop_error; + + switch (value) { + case DRM_MODE_SCALE_FULLSCREEN: + break; + case DRM_MODE_SCALE_NO_SCALE: + break; + case DRM_MODE_SCALE_ASPECT: + break; + default: + goto set_prop_error; + } + + if (drm_connector_property_get_value(connector, + property, + &curValue)) + goto set_prop_error; + + if (curValue == value) + goto set_prop_done; + + if (drm_connector_property_set_value(connector, + property, + value)) + goto set_prop_error; + + if (pPsbCrtc->saved_mode.hdisplay != 0 && + pPsbCrtc->saved_mode.vdisplay != 0) { + if (!drm_crtc_helper_set_mode(pEncoder->crtc, + &pPsbCrtc->saved_mode, + pEncoder->crtc->x, + pEncoder->crtc->y, + pEncoder->crtc->fb)) + goto set_prop_error; + } + } else if (!strcmp(property->name, "backlight") && pEncoder) { + PSB_DEBUG_ENTRY("backlight\n"); + + if (drm_connector_property_set_value(connector, + property, + value)) + goto set_prop_error; + else { +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + struct backlight_device bd; + bd.props.brightness = value; + psb_set_brightness(&bd); +#endif + } + } else if (!strcmp(property->name, "DPMS") && pEncoder) { + struct drm_encoder_helper_funcs *pEncHFuncs + = pEncoder->helper_private; + PSB_DEBUG_ENTRY("DPMS\n"); + pEncHFuncs->dpms(pEncoder, value); + } + +set_prop_done: + return 0; +set_prop_error: + return -1; +} + +static const struct drm_encoder_helper_funcs psb_intel_lvds_helper_funcs = { + .dpms = psb_intel_lvds_encoder_dpms, + .mode_fixup = psb_intel_lvds_mode_fixup, + .prepare = psb_intel_lvds_prepare, + .mode_set = psb_intel_lvds_mode_set, + .commit = psb_intel_lvds_commit, +}; + +static const struct drm_connector_helper_funcs + psb_intel_lvds_connector_helper_funcs = { + .get_modes = psb_intel_lvds_get_modes, + .mode_valid = psb_intel_lvds_mode_valid, + .best_encoder = psb_intel_best_encoder, +}; + +static const struct drm_connector_funcs psb_intel_lvds_connector_funcs = { + .dpms = drm_helper_connector_dpms, + .save = psb_intel_lvds_save, + .restore = psb_intel_lvds_restore, + .detect = psb_intel_lvds_detect, + .fill_modes = drm_helper_probe_single_connector_modes, + .set_property = psb_intel_lvds_set_property, + .destroy = psb_intel_lvds_destroy, +}; + + +static void psb_intel_lvds_enc_destroy(struct drm_encoder *encoder) +{ + drm_encoder_cleanup(encoder); +} + +const struct drm_encoder_funcs psb_intel_lvds_enc_funcs = { + .destroy = psb_intel_lvds_enc_destroy, +}; + + + +/** + * psb_intel_lvds_init - setup LVDS connectors on this device + * @dev: drm device + * + * Create the connector, register the LVDS DDC bus, and try to figure out what + * modes we can display on the LVDS panel (if present). + */ +void psb_intel_lvds_init(struct drm_device *dev, + struct psb_intel_mode_device *mode_dev) +{ + struct psb_intel_output *psb_intel_output; + struct psb_intel_lvds_priv *lvds_priv; + struct drm_connector *connector; + struct drm_encoder *encoder; + struct drm_display_mode *scan; /* *modes, *bios_mode; */ + struct drm_crtc *crtc; + struct drm_psb_private *dev_priv = + (struct drm_psb_private *)dev->dev_private; + u32 lvds; + int pipe; + + psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL); + if (!psb_intel_output) + return; + + lvds_priv = kzalloc(sizeof(struct psb_intel_lvds_priv), GFP_KERNEL); + if (!lvds_priv) { + kfree(psb_intel_output); + DRM_DEBUG("LVDS private allocation error\n"); + return; + } + + psb_intel_output->dev_priv = lvds_priv; + + psb_intel_output->mode_dev = mode_dev; + connector = &psb_intel_output->base; + encoder = &psb_intel_output->enc; + drm_connector_init(dev, &psb_intel_output->base, + &psb_intel_lvds_connector_funcs, + DRM_MODE_CONNECTOR_LVDS); + + drm_encoder_init(dev, &psb_intel_output->enc, + &psb_intel_lvds_enc_funcs, + DRM_MODE_ENCODER_LVDS); + + drm_mode_connector_attach_encoder(&psb_intel_output->base, + &psb_intel_output->enc); + psb_intel_output->type = INTEL_OUTPUT_LVDS; + + drm_encoder_helper_add(encoder, &psb_intel_lvds_helper_funcs); + drm_connector_helper_add(connector, + &psb_intel_lvds_connector_helper_funcs); + connector->display_info.subpixel_order = SubPixelHorizontalRGB; + connector->interlace_allowed = false; + connector->doublescan_allowed = false; + + /*Attach connector properties*/ + drm_connector_attach_property(connector, + dev->mode_config.scaling_mode_property, + DRM_MODE_SCALE_FULLSCREEN); + drm_connector_attach_property(connector, + dev_priv->backlight_property, + BRIGHTNESS_MAX_LEVEL); + + /** + * Set up I2C bus + * FIXME: distroy i2c_bus when exit + */ + psb_intel_output->i2c_bus = psb_intel_i2c_create(dev, + GPIOB, + "LVDSBLC_B"); + if (!psb_intel_output->i2c_bus) { + dev_printk(KERN_ERR, + &dev->pdev->dev, "I2C bus registration failed.\n"); + goto failed_blc_i2c; + } + psb_intel_output->i2c_bus->slave_addr = 0x2C; + dev_priv->lvds_i2c_bus = psb_intel_output->i2c_bus; + + /* + * LVDS discovery: + * 1) check for EDID on DDC + * 2) check for VBT data + * 3) check to see if LVDS is already on + * if none of the above, no panel + * 4) make sure lid is open + * if closed, act like it's not there for now + */ + + /* Set up the DDC bus. */ + psb_intel_output->ddc_bus = psb_intel_i2c_create(dev, + GPIOC, + "LVDSDDC_C"); + if (!psb_intel_output->ddc_bus) { + dev_printk(KERN_ERR, &dev->pdev->dev, + "DDC bus registration " "failed.\n"); + goto failed_ddc; + } + + /* + * Attempt to get the fixed panel mode from DDC. Assume that the + * preferred mode is the right one. + */ + psb_intel_ddc_get_modes(psb_intel_output); + list_for_each_entry(scan, &connector->probed_modes, head) { + if (scan->type & DRM_MODE_TYPE_PREFERRED) { + mode_dev->panel_fixed_mode = + drm_mode_duplicate(dev, scan); + goto out; /* FIXME: check for quirks */ + } + } + + /* Failed to get EDID, what about VBT? do we need this?*/ + if (mode_dev->vbt_mode) + mode_dev->panel_fixed_mode = + drm_mode_duplicate(dev, mode_dev->vbt_mode); + + if (!mode_dev->panel_fixed_mode) + if (dev_priv->lfp_lvds_vbt_mode) + mode_dev->panel_fixed_mode = + drm_mode_duplicate(dev, + dev_priv->lfp_lvds_vbt_mode); + + /* + * If we didn't get EDID, try checking if the panel is already turned + * on. If so, assume that whatever is currently programmed is the + * correct mode. + */ + lvds = REG_READ(LVDS); + pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; + crtc = psb_intel_get_crtc_from_pipe(dev, pipe); + + if (crtc && (lvds & LVDS_PORT_EN)) { + mode_dev->panel_fixed_mode = + psb_intel_crtc_mode_get(dev, crtc); + if (mode_dev->panel_fixed_mode) { + mode_dev->panel_fixed_mode->type |= + DRM_MODE_TYPE_PREFERRED; + goto out; /* FIXME: check for quirks */ + } + } + + /* If we still don't have a mode after all that, give up. */ + if (!mode_dev->panel_fixed_mode) { + DRM_DEBUG + ("Found no modes on the lvds, ignoring the LVDS\n"); + goto failed_find; + } + + /* + * Blacklist machines with BIOSes that list an LVDS panel without + * actually having one. + */ +out: + drm_sysfs_connector_add(connector); + + PSB_DEBUG_ENTRY("hdisplay = %d\n", + mode_dev->panel_fixed_mode->hdisplay); + PSB_DEBUG_ENTRY(" vdisplay = %d\n", + mode_dev->panel_fixed_mode->vdisplay); + PSB_DEBUG_ENTRY(" hsync_start = %d\n", + mode_dev->panel_fixed_mode->hsync_start); + PSB_DEBUG_ENTRY(" hsync_end = %d\n", + mode_dev->panel_fixed_mode->hsync_end); + PSB_DEBUG_ENTRY(" htotal = %d\n", + mode_dev->panel_fixed_mode->htotal); + PSB_DEBUG_ENTRY(" vsync_start = %d\n", + mode_dev->panel_fixed_mode->vsync_start); + PSB_DEBUG_ENTRY(" vsync_end = %d\n", + mode_dev->panel_fixed_mode->vsync_end); + PSB_DEBUG_ENTRY(" vtotal = %d\n", + mode_dev->panel_fixed_mode->vtotal); + PSB_DEBUG_ENTRY(" clock = %d\n", + mode_dev->panel_fixed_mode->clock); + + return; + +failed_find: + if (psb_intel_output->ddc_bus) + psb_intel_i2c_destroy(psb_intel_output->ddc_bus); +failed_ddc: + if (psb_intel_output->i2c_bus) + psb_intel_i2c_destroy(psb_intel_output->i2c_bus); +failed_blc_i2c: + drm_encoder_cleanup(encoder); + drm_connector_cleanup(connector); + kfree(connector); +} + diff --git a/drivers/staging/gma500/psb_intel_modes.c b/drivers/staging/gma500/psb_intel_modes.c new file mode 100644 index 000000000000..bde1aff96190 --- /dev/null +++ b/drivers/staging/gma500/psb_intel_modes.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Authers: Jesse Barnes + */ + +#include +#include +#include +#include "psb_intel_drv.h" + +/** + * psb_intel_ddc_probe + * + */ +bool psb_intel_ddc_probe(struct psb_intel_output *psb_intel_output) +{ + u8 out_buf[] = { 0x0, 0x0 }; + u8 buf[2]; + int ret; + struct i2c_msg msgs[] = { + { + .addr = 0x50, + .flags = 0, + .len = 1, + .buf = out_buf, + }, + { + .addr = 0x50, + .flags = I2C_M_RD, + .len = 1, + .buf = buf, + } + }; + + ret = i2c_transfer(&psb_intel_output->ddc_bus->adapter, msgs, 2); + if (ret == 2) + return true; + + return false; +} + +/** + * psb_intel_ddc_get_modes - get modelist from monitor + * @connector: DRM connector device to use + * + * Fetch the EDID information from @connector using the DDC bus. + */ +int psb_intel_ddc_get_modes(struct psb_intel_output *psb_intel_output) +{ + struct edid *edid; + int ret = 0; + + edid = + drm_get_edid(&psb_intel_output->base, + &psb_intel_output->ddc_bus->adapter); + if (edid) { + drm_mode_connector_update_edid_property(&psb_intel_output-> + base, edid); + ret = drm_add_edid_modes(&psb_intel_output->base, edid); + kfree(edid); + } + return ret; +} diff --git a/drivers/staging/gma500/psb_intel_opregion.c b/drivers/staging/gma500/psb_intel_opregion.c new file mode 100644 index 000000000000..65e3e9b8dc16 --- /dev/null +++ b/drivers/staging/gma500/psb_intel_opregion.c @@ -0,0 +1,78 @@ +/* + * Copyright 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "psb_drv.h" + +struct opregion_header { + u8 signature[16]; + u32 size; + u32 opregion_ver; + u8 bios_ver[32]; + u8 vbios_ver[16]; + u8 driver_ver[16]; + u32 mboxes; + u8 reserved[164]; +} __attribute__((packed)); + +struct opregion_apci { + /*FIXME: add it later*/ +} __attribute__((packed)); + +struct opregion_swsci { + /*FIXME: add it later*/ +} __attribute__((packed)); + +struct opregion_acpi { + /*FIXME: add it later*/ +} __attribute__((packed)); + +int psb_intel_opregion_init(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + /*struct psb_intel_opregion * opregion = &dev_priv->opregion;*/ + u32 opregion_phy; + void *base; + u32 *lid_state; + + dev_priv->lid_state = NULL; + + pci_read_config_dword(dev->pdev, 0xfc, &opregion_phy); + if (opregion_phy == 0) { + DRM_DEBUG("Opregion not supported, won't support lid-switch\n"); + return -ENOTSUPP; + } + DRM_DEBUG("OpRegion detected at 0x%8x\n", opregion_phy); + + base = ioremap(opregion_phy, 8*1024); + if (!base) + return -ENOMEM; + + lid_state = base + 0x01ac; + + DRM_DEBUG("Lid switch state 0x%08x\n", *lid_state); + + dev_priv->lid_state = lid_state; + dev_priv->lid_last_state = *lid_state; + return 0; +} diff --git a/drivers/staging/gma500/psb_intel_reg.h b/drivers/staging/gma500/psb_intel_reg.h new file mode 100644 index 000000000000..6cae11857545 --- /dev/null +++ b/drivers/staging/gma500/psb_intel_reg.h @@ -0,0 +1,1200 @@ +/* + * Copyright (c) 2009, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef __PSB_INTEL_REG_H__ +#define __PSB_INTEL_REG_H__ + +#define BLC_PWM_CTL 0x61254 +#define BLC_PWM_CTL2 0x61250 +#define BLC_PWM_CTL_C 0x62254 +#define BLC_PWM_CTL2_C 0x62250 +#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) +/** + * This is the most significant 15 bits of the number of backlight cycles in a + * complete cycle of the modulated backlight control. + * + * The actual value is this field multiplied by two. + */ +#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) +#define BLM_LEGACY_MODE (1 << 16) +/** + * This is the number of cycles out of the backlight modulation cycle for which + * the backlight is on. + * + * This field must be no greater than the number of cycles in the complete + * backlight modulation cycle. + */ +#define BACKLIGHT_DUTY_CYCLE_SHIFT (0) +#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) + +#define I915_GCFGC 0xf0 +#define I915_LOW_FREQUENCY_ENABLE (1 << 7) +#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4) +#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4) +#define I915_DISPLAY_CLOCK_MASK (7 << 4) + +#define I855_HPLLCC 0xc0 +#define I855_CLOCK_CONTROL_MASK (3 << 0) +#define I855_CLOCK_133_200 (0 << 0) +#define I855_CLOCK_100_200 (1 << 0) +#define I855_CLOCK_100_133 (2 << 0) +#define I855_CLOCK_166_250 (3 << 0) + +/* I830 CRTC registers */ +#define HTOTAL_A 0x60000 +#define HBLANK_A 0x60004 +#define HSYNC_A 0x60008 +#define VTOTAL_A 0x6000c +#define VBLANK_A 0x60010 +#define VSYNC_A 0x60014 +#define PIPEASRC 0x6001c +#define BCLRPAT_A 0x60020 +#define VSYNCSHIFT_A 0x60028 + +#define HTOTAL_B 0x61000 +#define HBLANK_B 0x61004 +#define HSYNC_B 0x61008 +#define VTOTAL_B 0x6100c +#define VBLANK_B 0x61010 +#define VSYNC_B 0x61014 +#define PIPEBSRC 0x6101c +#define BCLRPAT_B 0x61020 +#define VSYNCSHIFT_B 0x61028 + +#define HTOTAL_C 0x62000 +#define HBLANK_C 0x62004 +#define HSYNC_C 0x62008 +#define VTOTAL_C 0x6200c +#define VBLANK_C 0x62010 +#define VSYNC_C 0x62014 +#define PIPECSRC 0x6201c +#define BCLRPAT_C 0x62020 +#define VSYNCSHIFT_C 0x62028 + +#define PP_STATUS 0x61200 +# define PP_ON (1 << 31) +/** + * Indicates that all dependencies of the panel are on: + * + * - PLL enabled + * - pipe enabled + * - LVDS/DVOB/DVOC on + */ +# define PP_READY (1 << 30) +# define PP_SEQUENCE_NONE (0 << 28) +# define PP_SEQUENCE_ON (1 << 28) +# define PP_SEQUENCE_OFF (2 << 28) +# define PP_SEQUENCE_MASK 0x30000000 +#define PP_CONTROL 0x61204 +# define POWER_TARGET_ON (1 << 0) + +#define LVDSPP_ON 0x61208 +#define LVDSPP_OFF 0x6120c +#define PP_CYCLE 0x61210 + +#define PFIT_CONTROL 0x61230 +# define PFIT_ENABLE (1 << 31) +# define PFIT_PIPE_MASK (3 << 29) +# define PFIT_PIPE_SHIFT 29 +# define PFIT_SCALING_MODE_PILLARBOX (1 << 27) +# define PFIT_SCALING_MODE_LETTERBOX (3 << 26) +# define VERT_INTERP_DISABLE (0 << 10) +# define VERT_INTERP_BILINEAR (1 << 10) +# define VERT_INTERP_MASK (3 << 10) +# define VERT_AUTO_SCALE (1 << 9) +# define HORIZ_INTERP_DISABLE (0 << 6) +# define HORIZ_INTERP_BILINEAR (1 << 6) +# define HORIZ_INTERP_MASK (3 << 6) +# define HORIZ_AUTO_SCALE (1 << 5) +# define PANEL_8TO6_DITHER_ENABLE (1 << 3) + +#define PFIT_PGM_RATIOS 0x61234 +# define PFIT_VERT_SCALE_MASK 0xfff00000 +# define PFIT_HORIZ_SCALE_MASK 0x0000fff0 + +#define PFIT_AUTO_RATIOS 0x61238 + + +#define DPLL_A 0x06014 +#define DPLL_B 0x06018 +# define DPLL_VCO_ENABLE (1 << 31) +# define DPLL_DVO_HIGH_SPEED (1 << 30) +# define DPLL_SYNCLOCK_ENABLE (1 << 29) +# define DPLL_VGA_MODE_DIS (1 << 28) +# define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */ +# define DPLLB_MODE_LVDS (2 << 26) /* i915 */ +# define DPLL_MODE_MASK (3 << 26) +# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */ +# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */ +# define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ +# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ +# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ +# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ +/** + * The i830 generation, in DAC/serial mode, defines p1 as two plus this + * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set. + */ +# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 +/** + * The i830 generation, in LVDS mode, defines P1 as the bit number set within + * this field (only one bit may be set). + */ +# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 +# define DPLL_FPA01_P1_POST_DIV_SHIFT 16 +# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required + * in DVO non-gang */ +# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ +# define PLL_REF_INPUT_DREFCLK (0 << 13) +# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ +# define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO + * TVCLKIN */ +# define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) +# define PLL_REF_INPUT_MASK (3 << 13) +# define PLL_LOAD_PULSE_PHASE_SHIFT 9 +/* + * Parallel to Serial Load Pulse phase selection. + * Selects the phase for the 10X DPLL clock for the PCIe + * digital display port. The range is 4 to 13; 10 or more + * is just a flip delay. The default is 6 + */ +# define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT) +# define DISPLAY_RATE_SELECT_FPA1 (1 << 8) + +/** + * SDVO multiplier for 945G/GM. Not used on 965. + * + * \sa DPLL_MD_UDI_MULTIPLIER_MASK + */ +# define SDVO_MULTIPLIER_MASK 0x000000ff +# define SDVO_MULTIPLIER_SHIFT_HIRES 4 +# define SDVO_MULTIPLIER_SHIFT_VGA 0 + +/** @defgroup DPLL_MD + * @{ + */ +/** Pipe A SDVO/UDI clock multiplier/divider register for G965. */ +#define DPLL_A_MD 0x0601c +/** Pipe B SDVO/UDI clock multiplier/divider register for G965. */ +#define DPLL_B_MD 0x06020 +/** + * UDI pixel divider, controlling how many pixels are stuffed into a packet. + * + * Value is pixels minus 1. Must be set to 1 pixel for SDVO. + */ +# define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000 +# define DPLL_MD_UDI_DIVIDER_SHIFT 24 +/** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */ +# define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000 +# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16 +/** + * SDVO/UDI pixel multiplier. + * + * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus + * clock rate is 10 times the DPLL clock. At low resolution/refresh rate + * modes, the bus rate would be below the limits, so SDVO allows for stuffing + * dummy bytes in the datastream at an increased clock rate, with both sides of + * the link knowing how many bytes are fill. + * + * So, for a mode with a dotclock of 65Mhz, we would want to double the clock + * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be + * set to 130Mhz, and the SDVO multiplier set to 2x in this register and + * through an SDVO command. + * + * This register field has values of multiplication factor minus 1, with + * a maximum multiplier of 5 for SDVO. + */ +# define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00 +# define DPLL_MD_UDI_MULTIPLIER_SHIFT 8 +/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. + * This best be set to the default value (3) or the CRT won't work. No, + * I don't entirely understand what this does... + */ +# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f +# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 +/** @} */ + +#define DPLL_TEST 0x606c +# define DPLLB_TEST_SDVO_DIV_1 (0 << 22) +# define DPLLB_TEST_SDVO_DIV_2 (1 << 22) +# define DPLLB_TEST_SDVO_DIV_4 (2 << 22) +# define DPLLB_TEST_SDVO_DIV_MASK (3 << 22) +# define DPLLB_TEST_N_BYPASS (1 << 19) +# define DPLLB_TEST_M_BYPASS (1 << 18) +# define DPLLB_INPUT_BUFFER_ENABLE (1 << 16) +# define DPLLA_TEST_N_BYPASS (1 << 3) +# define DPLLA_TEST_M_BYPASS (1 << 2) +# define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) + +#define ADPA 0x61100 +#define ADPA_DAC_ENABLE (1<<31) +#define ADPA_DAC_DISABLE 0 +#define ADPA_PIPE_SELECT_MASK (1<<30) +#define ADPA_PIPE_A_SELECT 0 +#define ADPA_PIPE_B_SELECT (1<<30) +#define ADPA_USE_VGA_HVPOLARITY (1<<15) +#define ADPA_SETS_HVPOLARITY 0 +#define ADPA_VSYNC_CNTL_DISABLE (1<<11) +#define ADPA_VSYNC_CNTL_ENABLE 0 +#define ADPA_HSYNC_CNTL_DISABLE (1<<10) +#define ADPA_HSYNC_CNTL_ENABLE 0 +#define ADPA_VSYNC_ACTIVE_HIGH (1<<4) +#define ADPA_VSYNC_ACTIVE_LOW 0 +#define ADPA_HSYNC_ACTIVE_HIGH (1<<3) +#define ADPA_HSYNC_ACTIVE_LOW 0 + +#define FPA0 0x06040 +#define FPA1 0x06044 +#define FPB0 0x06048 +#define FPB1 0x0604c +# define FP_N_DIV_MASK 0x003f0000 +# define FP_N_DIV_SHIFT 16 +# define FP_M1_DIV_MASK 0x00003f00 +# define FP_M1_DIV_SHIFT 8 +# define FP_M2_DIV_MASK 0x0000003f +# define FP_M2_DIV_SHIFT 0 + + +#define PORT_HOTPLUG_EN 0x61110 +# define SDVOB_HOTPLUG_INT_EN (1 << 26) +# define SDVOC_HOTPLUG_INT_EN (1 << 25) +# define TV_HOTPLUG_INT_EN (1 << 18) +# define CRT_HOTPLUG_INT_EN (1 << 9) +# define CRT_HOTPLUG_FORCE_DETECT (1 << 3) + +#define PORT_HOTPLUG_STAT 0x61114 +# define CRT_HOTPLUG_INT_STATUS (1 << 11) +# define TV_HOTPLUG_INT_STATUS (1 << 10) +# define CRT_HOTPLUG_MONITOR_MASK (3 << 8) +# define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) +# define CRT_HOTPLUG_MONITOR_MONO (2 << 8) +# define CRT_HOTPLUG_MONITOR_NONE (0 << 8) +# define SDVOC_HOTPLUG_INT_STATUS (1 << 7) +# define SDVOB_HOTPLUG_INT_STATUS (1 << 6) + +#define SDVOB 0x61140 +#define SDVOC 0x61160 +#define SDVO_ENABLE (1 << 31) +#define SDVO_PIPE_B_SELECT (1 << 30) +#define SDVO_STALL_SELECT (1 << 29) +#define SDVO_INTERRUPT_ENABLE (1 << 26) +/** + * 915G/GM SDVO pixel multiplier. + * + * Programmed value is multiplier - 1, up to 5x. + * + * \sa DPLL_MD_UDI_MULTIPLIER_MASK + */ +#define SDVO_PORT_MULTIPLY_MASK (7 << 23) +#define SDVO_PORT_MULTIPLY_SHIFT 23 +#define SDVO_PHASE_SELECT_MASK (15 << 19) +#define SDVO_PHASE_SELECT_DEFAULT (6 << 19) +#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) +#define SDVOC_GANG_MODE (1 << 16) +#define SDVO_BORDER_ENABLE (1 << 7) +#define SDVOB_PCIE_CONCURRENCY (1 << 3) +#define SDVO_DETECTED (1 << 2) +/* Bits to be preserved when writing */ +#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14)) +#define SDVOC_PRESERVE_MASK (1 << 17) + +/** @defgroup LVDS + * @{ + */ +/** + * This register controls the LVDS output enable, pipe selection, and data + * format selection. + * + * All of the clock/data pairs are force powered down by power sequencing. + */ +#define LVDS 0x61180 +/** + * Enables the LVDS port. This bit must be set before DPLLs are enabled, as + * the DPLL semantics change when the LVDS is assigned to that pipe. + */ +# define LVDS_PORT_EN (1 << 31) +/** Selects pipe B for LVDS data. Must be set on pre-965. */ +# define LVDS_PIPEB_SELECT (1 << 30) + +/** Turns on border drawing to allow centered display. */ +# define LVDS_BORDER_EN (1 << 15) + +/** + * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per + * pixel. + */ +# define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) +# define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) +# define LVDS_A0A2_CLKA_POWER_UP (3 << 8) +/** + * Controls the A3 data pair, which contains the additional LSBs for 24 bit + * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be + * on. + */ +# define LVDS_A3_POWER_MASK (3 << 6) +# define LVDS_A3_POWER_DOWN (0 << 6) +# define LVDS_A3_POWER_UP (3 << 6) +/** + * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP + * is set. + */ +# define LVDS_CLKB_POWER_MASK (3 << 4) +# define LVDS_CLKB_POWER_DOWN (0 << 4) +# define LVDS_CLKB_POWER_UP (3 << 4) + +/** + * Controls the B0-B3 data pairs. This must be set to match the DPLL p2 + * setting for whether we are in dual-channel mode. The B3 pair will + * additionally only be powered up when LVDS_A3_POWER_UP is set. + */ +# define LVDS_B0B3_POWER_MASK (3 << 2) +# define LVDS_B0B3_POWER_DOWN (0 << 2) +# define LVDS_B0B3_POWER_UP (3 << 2) + +#define PIPEACONF 0x70008 +#define PIPEACONF_ENABLE (1<<31) +#define PIPEACONF_DISABLE 0 +#define PIPEACONF_DOUBLE_WIDE (1<<30) +#define PIPECONF_ACTIVE (1<<30) +#define I965_PIPECONF_ACTIVE (1<<30) +#define PIPECONF_DSIPLL_LOCK (1<<29) +#define PIPEACONF_SINGLE_WIDE 0 +#define PIPEACONF_PIPE_UNLOCKED 0 +#define PIPEACONF_DSR (1<<26) +#define PIPEACONF_PIPE_LOCKED (1<<25) +#define PIPEACONF_PALETTE 0 +#define PIPECONF_FORCE_BORDER (1<<25) +#define PIPEACONF_GAMMA (1<<24) +#define PIPECONF_PROGRESSIVE (0 << 21) +#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) +#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) +#define PIPECONF_PLANE_OFF (1<<19) +#define PIPECONF_CURSOR_OFF (1<<18) + + +#define PIPEBCONF 0x71008 +#define PIPEBCONF_ENABLE (1<<31) +#define PIPEBCONF_DISABLE 0 +#define PIPEBCONF_DOUBLE_WIDE (1<<30) +#define PIPEBCONF_DISABLE 0 +#define PIPEBCONF_GAMMA (1<<24) +#define PIPEBCONF_PALETTE 0 + +#define PIPECCONF 0x72008 + +#define PIPEBGCMAXRED 0x71010 +#define PIPEBGCMAXGREEN 0x71014 +#define PIPEBGCMAXBLUE 0x71018 + +#define PIPEASTAT 0x70024 +#define PIPEBSTAT 0x71024 +#define PIPECSTAT 0x72024 +#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1) +#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) +#define PIPE_VBLANK_CLEAR (1 << 1) +#define PIPE_VBLANK_STATUS (1 << 1) +#define PIPE_TE_STATUS (1UL<<6) +#define PIPE_DPST_EVENT_STATUS (1UL<<7) +#define PIPE_VSYNC_CLEAR (1UL<<9) +#define PIPE_VSYNC_STATUS (1UL<<9) +#define PIPE_HDMI_AUDIO_UNDERRUN_STATUS (1UL<<10) +#define PIPE_HDMI_AUDIO_BUFFER_DONE_STATUS (1UL<<11) +#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17) +#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) +#define PIPE_TE_ENABLE (1UL<<22) +#define PIPE_DPST_EVENT_ENABLE (1UL<<23) +#define PIPE_VSYNC_ENABL (1UL<<25) +#define PIPE_HDMI_AUDIO_UNDERRUN (1UL<<26) +#define PIPE_HDMI_AUDIO_BUFFER_DONE (1UL<<27) +#define PIPE_HDMI_AUDIO_INT_MASK (PIPE_HDMI_AUDIO_UNDERRUN | PIPE_HDMI_AUDIO_BUFFER_DONE) +#define PIPE_EVENT_MASK (BIT29|BIT28|BIT27|BIT26|BIT24|BIT23|BIT22|BIT21|BIT20|BIT16) +#define PIPE_VBLANK_MASK (BIT25|BIT24|BIT18|BIT17) +#define HISTOGRAM_INT_CONTROL 0x61268 +#define HISTOGRAM_BIN_DATA 0X61264 +#define HISTOGRAM_LOGIC_CONTROL 0x61260 +#define PWM_CONTROL_LOGIC 0x61250 +#define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL<<10) +#define HISTOGRAM_INTERRUPT_ENABLE (1UL<<31) +#define HISTOGRAM_LOGIC_ENABLE (1UL<<31) +#define PWM_LOGIC_ENABLE (1UL<<31) +#define PWM_PHASEIN_ENABLE (1UL<<25) +#define PWM_PHASEIN_INT_ENABLE (1UL<<24) +#define PWM_PHASEIN_VB_COUNT 0x00001f00 +#define PWM_PHASEIN_INC 0x0000001f +#define HISTOGRAM_INT_CTRL_CLEAR (1UL<<30) +#define DPST_YUV_LUMA_MODE 0 + +struct dpst_ie_histogram_control { + union { + uint32_t data; + struct { + uint32_t bin_reg_index:7; + uint32_t reserved:4; + uint32_t bin_reg_func_select:1; + uint32_t sync_to_phase_in:1; + uint32_t alt_enhancement_mode:2; + uint32_t reserved1:1; + uint32_t sync_to_phase_in_count:8; + uint32_t histogram_mode_select:1; + uint32_t reserved2:4; + uint32_t ie_pipe_assignment:1; + uint32_t ie_mode_table_enabled:1; + uint32_t ie_histogram_enable:1; + }; + }; +}; + +struct dpst_guardband { + union { + uint32_t data; + struct { + uint32_t guardband:22; + uint32_t guardband_interrupt_delay:8; + uint32_t interrupt_status:1; + uint32_t interrupt_enable:1; + }; + }; +}; + +#define PIPEAFRAMEHIGH 0x70040 +#define PIPEAFRAMEPIXEL 0x70044 +#define PIPEBFRAMEHIGH 0x71040 +#define PIPEBFRAMEPIXEL 0x71044 +#define PIPECFRAMEHIGH 0x72040 +#define PIPECFRAMEPIXEL 0x72044 +#define PIPE_FRAME_HIGH_MASK 0x0000ffff +#define PIPE_FRAME_HIGH_SHIFT 0 +#define PIPE_FRAME_LOW_MASK 0xff000000 +#define PIPE_FRAME_LOW_SHIFT 24 +#define PIPE_PIXEL_MASK 0x00ffffff +#define PIPE_PIXEL_SHIFT 0 + +#define DSPARB 0x70030 +#define DSPFW1 0x70034 +#define DSPFW2 0x70038 +#define DSPFW3 0x7003c +#define DSPFW4 0x70050 +#define DSPFW5 0x70054 +#define DSPFW6 0x70058 +#define DSPCHICKENBIT 0x70400 +#define DSPACNTR 0x70180 +#define DSPBCNTR 0x71180 +#define DSPCCNTR 0x72180 +#define DISPLAY_PLANE_ENABLE (1<<31) +#define DISPLAY_PLANE_DISABLE 0 +#define DISPPLANE_GAMMA_ENABLE (1<<30) +#define DISPPLANE_GAMMA_DISABLE 0 +#define DISPPLANE_PIXFORMAT_MASK (0xf<<26) +#define DISPPLANE_8BPP (0x2<<26) +#define DISPPLANE_15_16BPP (0x4<<26) +#define DISPPLANE_16BPP (0x5<<26) +#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) +#define DISPPLANE_32BPP (0x7<<26) +#define DISPPLANE_STEREO_ENABLE (1<<25) +#define DISPPLANE_STEREO_DISABLE 0 +#define DISPPLANE_SEL_PIPE_MASK (1<<24) +#define DISPPLANE_SEL_PIPE_POS 24 +#define DISPPLANE_SEL_PIPE_A 0 +#define DISPPLANE_SEL_PIPE_B (1<<24) +#define DISPPLANE_SRC_KEY_ENABLE (1<<22) +#define DISPPLANE_SRC_KEY_DISABLE 0 +#define DISPPLANE_LINE_DOUBLE (1<<20) +#define DISPPLANE_NO_LINE_DOUBLE 0 +#define DISPPLANE_STEREO_POLARITY_FIRST 0 +#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) +/* plane B only */ +#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15) +#define DISPPLANE_ALPHA_TRANS_DISABLE 0 +#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0 +#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1) +#define DISPPLANE_BOTTOM (4) + +#define DSPABASE 0x70184 +#define DSPALINOFF 0x70184 +#define DSPASTRIDE 0x70188 + +#define DSPBBASE 0x71184 +#define DSPBLINOFF 0X71184 +#define DSPBADDR DSPBBASE +#define DSPBSTRIDE 0x71188 + +#define DSPCBASE 0x72184 +#define DSPCLINOFF 0x72184 +#define DSPCSTRIDE 0x72188 + +#define DSPAKEYVAL 0x70194 +#define DSPAKEYMASK 0x70198 + +#define DSPAPOS 0x7018C /* reserved */ +#define DSPASIZE 0x70190 +#define DSPBPOS 0x7118C +#define DSPBSIZE 0x71190 +#define DSPCPOS 0x7218C +#define DSPCSIZE 0x72190 + +#define DSPASURF 0x7019C +#define DSPATILEOFF 0x701A4 + +#define DSPBSURF 0x7119C +#define DSPBTILEOFF 0x711A4 + +#define DSPCSURF 0x7219C +#define DSPCTILEOFF 0x721A4 +#define DSPCKEYMAXVAL 0x721A0 +#define DSPCKEYMINVAL 0x72194 +#define DSPCKEYMSK 0x72198 + +#define VGACNTRL 0x71400 +# define VGA_DISP_DISABLE (1 << 31) +# define VGA_2X_MODE (1 << 30) +# define VGA_PIPE_B_SELECT (1 << 29) + +/* + * Overlay registers + */ +#define OV_C_OFFSET 0x08000 +#define OV_OVADD 0x30000 +#define OV_DOVASTA 0x30008 +# define OV_PIPE_SELECT (BIT6|BIT7) +# define OV_PIPE_SELECT_POS 6 +# define OV_PIPE_A 0 +# define OV_PIPE_C 1 +#define OV_OGAMC5 0x30010 +#define OV_OGAMC4 0x30014 +#define OV_OGAMC3 0x30018 +#define OV_OGAMC2 0x3001C +#define OV_OGAMC1 0x30020 +#define OV_OGAMC0 0x30024 +#define OVC_OVADD 0x38000 +#define OVC_DOVCSTA 0x38008 +#define OVC_OGAMC5 0x38010 +#define OVC_OGAMC4 0x38014 +#define OVC_OGAMC3 0x38018 +#define OVC_OGAMC2 0x3801C +#define OVC_OGAMC1 0x38020 +#define OVC_OGAMC0 0x38024 + +/* + * Some BIOS scratch area registers. The 845 (and 830?) store the amount + * of video memory available to the BIOS in SWF1. + */ +#define SWF0 0x71410 +#define SWF1 0x71414 +#define SWF2 0x71418 +#define SWF3 0x7141c +#define SWF4 0x71420 +#define SWF5 0x71424 +#define SWF6 0x71428 + +/* + * 855 scratch registers. + */ +#define SWF00 0x70410 +#define SWF01 0x70414 +#define SWF02 0x70418 +#define SWF03 0x7041c +#define SWF04 0x70420 +#define SWF05 0x70424 +#define SWF06 0x70428 + +#define SWF10 SWF0 +#define SWF11 SWF1 +#define SWF12 SWF2 +#define SWF13 SWF3 +#define SWF14 SWF4 +#define SWF15 SWF5 +#define SWF16 SWF6 + +#define SWF30 0x72414 +#define SWF31 0x72418 +#define SWF32 0x7241c + + +/* + * Palette registers + */ +#define PALETTE_A 0x0a000 +#define PALETTE_B 0x0a800 +#define PALETTE_C 0x0ac00 + +#define IS_I830(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82830_CGC) +#define IS_845G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82845G_IG) +#define IS_I85X(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82855GM_IG) +#define IS_I855(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82855GM_IG) +#define IS_I865G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82865_IG) + + +/* || dev->pci_device == PCI_DEVICE_ID_INTELPCI_CHIP_E7221_G) */ +#define IS_I915G(dev) (dev->pci_device == PCI_DEVICE_ID_INTEL_82915G_IG) +#define IS_I915GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82915GM_IG) +#define IS_I945G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945G_IG) +#define IS_I945GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945GM_IG) + +#define IS_I965G(dev) ((dev)->pci_device == 0x2972 || \ + (dev)->pci_device == 0x2982 || \ + (dev)->pci_device == 0x2992 || \ + (dev)->pci_device == 0x29A2 || \ + (dev)->pci_device == 0x2A02 || \ + (dev)->pci_device == 0x2A12) + +#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02) + +#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \ + (dev)->pci_device == 0x29B2 || \ + (dev)->pci_device == 0x29D2) + +#define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \ + IS_I945GM(dev) || IS_I965G(dev) || IS_POULSBO(dev) || \ + IS_MRST(dev)) + +#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ + IS_I945GM(dev) || IS_I965GM(dev) || \ + IS_POULSBO(dev) || IS_MRST(dev)) + +/* Cursor A & B regs */ +#define CURACNTR 0x70080 +#define CURSOR_MODE_DISABLE 0x00 +#define CURSOR_MODE_64_32B_AX 0x07 +#define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX) +#define MCURSOR_GAMMA_ENABLE (1 << 26) +#define CURABASE 0x70084 +#define CURAPOS 0x70088 +#define CURSOR_POS_MASK 0x007FF +#define CURSOR_POS_SIGN 0x8000 +#define CURSOR_X_SHIFT 0 +#define CURSOR_Y_SHIFT 16 +#define CURBCNTR 0x700c0 +#define CURBBASE 0x700c4 +#define CURBPOS 0x700c8 +#define CURCCNTR 0x700e0 +#define CURCBASE 0x700e4 +#define CURCPOS 0x700e8 + +/* + * Interrupt Registers + */ +#define IER 0x020a0 +#define IIR 0x020a4 +#define IMR 0x020a8 +#define ISR 0x020ac + +/* + * MOORESTOWN delta registers + */ +#define MRST_DPLL_A 0x0f014 +#define MDFLD_DPLL_B 0x0f018 +#define MDFLD_INPUT_REF_SEL (1 << 14) +#define MDFLD_VCO_SEL (1 << 16) +#define DPLLA_MODE_LVDS (2 << 26) /* mrst */ +#define MDFLD_PLL_LATCHEN (1 << 28) +#define MDFLD_PWR_GATE_EN (1 << 30) +#define MDFLD_P1_MASK (0x1FF << 17) +#define MRST_FPA0 0x0f040 +#define MRST_FPA1 0x0f044 +#define MDFLD_DPLL_DIV0 0x0f048 +#define MDFLD_DPLL_DIV1 0x0f04c +#define MRST_PERF_MODE 0x020f4 + +/* MEDFIELD HDMI registers */ +#define HDMIPHYMISCCTL 0x61134 +# define HDMI_PHY_POWER_DOWN 0x7f +#define HDMIB_CONTROL 0x61140 +# define HDMIB_PORT_EN (1 << 31) +# define HDMIB_PIPE_B_SELECT (1 << 30) +# define HDMIB_NULL_PACKET (1 << 9) +#define HDMIB_HDCP_PORT (1 << 5) + +/* #define LVDS 0x61180 */ +# define MRST_PANEL_8TO6_DITHER_ENABLE (1 << 25) +# define MRST_PANEL_24_DOT_1_FORMAT (1 << 24) +# define LVDS_A3_POWER_UP_0_OUTPUT (1 << 6) + +#define MIPI 0x61190 +#define MIPI_C 0x62190 +# define MIPI_PORT_EN (1 << 31) +/** Turns on border drawing to allow centered display. */ +# define SEL_FLOPPED_HSTX (1 << 23) +# define PASS_FROM_SPHY_TO_AFE (1 << 16) +# define MIPI_BORDER_EN (1 << 15) +# define MIPIA_3LANE_MIPIC_1LANE 0x1 +# define MIPIA_2LANE_MIPIC_2LANE 0x2 +# define TE_TRIGGER_DSI_PROTOCOL (1 << 2) +# define TE_TRIGGER_GPIO_PIN (1 << 3) +#define MIPI_TE_COUNT 0x61194 + +/* #define PP_CONTROL 0x61204 */ +# define POWER_DOWN_ON_RESET (1 << 1) + +/* #define PFIT_CONTROL 0x61230 */ +# define PFIT_PIPE_SELECT (3 << 29) +# define PFIT_PIPE_SELECT_SHIFT (29) + +/* #define BLC_PWM_CTL 0x61254 */ +#define MRST_BACKLIGHT_MODULATION_FREQ_SHIFT (16) +#define MRST_BACKLIGHT_MODULATION_FREQ_MASK (0xffff << 16) + +/* #define PIPEACONF 0x70008 */ +#define PIPEACONF_PIPE_STATE (1<<30) +/* #define DSPACNTR 0x70180 */ + +#define MRST_DSPABASE 0x7019c +#define MRST_DSPBBASE 0x7119c +#define MDFLD_DSPCBASE 0x7219c + +/* + * Moorestown registers. + */ +/*=========================================================================== +; General Constants +;--------------------------------------------------------------------------*/ +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 +/*=========================================================================== +; MIPI IP registers +;--------------------------------------------------------------------------*/ +#define MIPIC_REG_OFFSET 0x800 +#define DEVICE_READY_REG 0xb000 +#define LP_OUTPUT_HOLD BIT16 +#define EXIT_ULPS_DEV_READY 0x3 +#define LP_OUTPUT_HOLD_RELEASE 0x810000 +# define ENTERING_ULPS (2 << 1) +# define EXITING_ULPS (1 << 1) +# define ULPS_MASK (3 << 1) +# define BUS_POSSESSION (1 << 3) +#define INTR_STAT_REG 0xb004 +#define RX_SOT_ERROR BIT0 +#define RX_SOT_SYNC_ERROR BIT1 +#define RX_ESCAPE_MODE_ENTRY_ERROR BIT3 +#define RX_LP_TX_SYNC_ERROR BIT4 +#define RX_HS_RECEIVE_TIMEOUT_ERROR BIT5 +#define RX_FALSE_CONTROL_ERROR BIT6 +#define RX_ECC_SINGLE_BIT_ERROR BIT7 +#define RX_ECC_MULTI_BIT_ERROR BIT8 +#define RX_CHECKSUM_ERROR BIT9 +#define RX_DSI_DATA_TYPE_NOT_RECOGNIZED BIT10 +#define RX_DSI_VC_ID_INVALID BIT11 +#define TX_FALSE_CONTROL_ERROR BIT12 +#define TX_ECC_SINGLE_BIT_ERROR BIT13 +#define TX_ECC_MULTI_BIT_ERROR BIT14 +#define TX_CHECKSUM_ERROR BIT15 +#define TX_DSI_DATA_TYPE_NOT_RECOGNIZED BIT16 +#define TX_DSI_VC_ID_INVALID BIT17 +#define HIGH_CONTENTION BIT18 +#define LOW_CONTENTION BIT19 +#define DPI_FIFO_UNDER_RUN BIT20 +#define HS_TX_TIMEOUT BIT21 +#define LP_RX_TIMEOUT BIT22 +#define TURN_AROUND_ACK_TIMEOUT BIT23 +#define ACK_WITH_NO_ERROR BIT24 +#define HS_GENERIC_WR_FIFO_FULL BIT27 +#define LP_GENERIC_WR_FIFO_FULL BIT28 +#define SPL_PKT_SENT BIT30 +#define INTR_EN_REG 0xb008 +#define DSI_FUNC_PRG_REG 0xb00c +#define DPI_CHANNEL_NUMBER_POS 0x03 +#define DBI_CHANNEL_NUMBER_POS 0x05 +#define FMT_DPI_POS 0x07 +#define FMT_DBI_POS 0x0A +#define DBI_DATA_WIDTH_POS 0x0D +/* DPI PIXEL FORMATS */ +#define RGB_565_FMT 0x01 /* RGB 565 FORMAT */ +#define RGB_666_FMT 0x02 /* RGB 666 FORMAT */ +#define LRGB_666_FMT 0x03 /* RGB LOOSELY PACKED + * 666 FORMAT + */ +#define RGB_888_FMT 0x04 /* RGB 888 FORMAT */ +#define VIRTUAL_CHANNEL_NUMBER_0 0x00 /* Virtual channel 0 */ +#define VIRTUAL_CHANNEL_NUMBER_1 0x01 /* Virtual channel 1 */ +#define VIRTUAL_CHANNEL_NUMBER_2 0x02 /* Virtual channel 2 */ +#define VIRTUAL_CHANNEL_NUMBER_3 0x03 /* Virtual channel 3 */ +#define DBI_NOT_SUPPORTED 0x00 /* command mode + * is not supported + */ +#define DBI_DATA_WIDTH_16BIT 0x01 /* 16 bit data */ +#define DBI_DATA_WIDTH_9BIT 0x02 /* 9 bit data */ +#define DBI_DATA_WIDTH_8BIT 0x03 /* 8 bit data */ +#define DBI_DATA_WIDTH_OPT1 0x04 /* option 1 */ +#define DBI_DATA_WIDTH_OPT2 0x05 /* option 2 */ +#define HS_TX_TIMEOUT_REG 0xb010 +#define LP_RX_TIMEOUT_REG 0xb014 +#define TURN_AROUND_TIMEOUT_REG 0xb018 +#define DEVICE_RESET_REG 0xb01C +#define DPI_RESOLUTION_REG 0xb020 +#define RES_V_POS 0x10 +#define DBI_RESOLUTION_REG 0xb024 /* Reserved for MDFLD */ +#define HORIZ_SYNC_PAD_COUNT_REG 0xb028 +#define HORIZ_BACK_PORCH_COUNT_REG 0xb02C +#define HORIZ_FRONT_PORCH_COUNT_REG 0xb030 +#define HORIZ_ACTIVE_AREA_COUNT_REG 0xb034 +#define VERT_SYNC_PAD_COUNT_REG 0xb038 +#define VERT_BACK_PORCH_COUNT_REG 0xb03c +#define VERT_FRONT_PORCH_COUNT_REG 0xb040 +#define HIGH_LOW_SWITCH_COUNT_REG 0xb044 +#define DPI_CONTROL_REG 0xb048 +#define DPI_SHUT_DOWN BIT0 +#define DPI_TURN_ON BIT1 +#define DPI_COLOR_MODE_ON BIT2 +#define DPI_COLOR_MODE_OFF BIT3 +#define DPI_BACK_LIGHT_ON BIT4 +#define DPI_BACK_LIGHT_OFF BIT5 +#define DPI_LP BIT6 +#define DPI_DATA_REG 0xb04c +#define DPI_BACK_LIGHT_ON_DATA 0x07 +#define DPI_BACK_LIGHT_OFF_DATA 0x17 +#define INIT_COUNT_REG 0xb050 +#define MAX_RET_PAK_REG 0xb054 +#define VIDEO_FMT_REG 0xb058 +#define COMPLETE_LAST_PCKT BIT2 +#define EOT_DISABLE_REG 0xb05c +#define ENABLE_CLOCK_STOPPING BIT1 +#define LP_BYTECLK_REG 0xb060 +#define LP_GEN_DATA_REG 0xb064 +#define HS_GEN_DATA_REG 0xb068 +#define LP_GEN_CTRL_REG 0xb06C +#define HS_GEN_CTRL_REG 0xb070 +#define DCS_CHANNEL_NUMBER_POS 0x06 +#define MCS_COMMANDS_POS 0x8 +#define WORD_COUNTS_POS 0x8 +#define MCS_PARAMETER_POS 0x10 +#define GEN_FIFO_STAT_REG 0xb074 +#define HS_DATA_FIFO_FULL BIT0 +#define HS_DATA_FIFO_HALF_EMPTY BIT1 +#define HS_DATA_FIFO_EMPTY BIT2 +#define LP_DATA_FIFO_FULL BIT8 +#define LP_DATA_FIFO_HALF_EMPTY BIT9 +#define LP_DATA_FIFO_EMPTY BIT10 +#define HS_CTRL_FIFO_FULL BIT16 +#define HS_CTRL_FIFO_HALF_EMPTY BIT17 +#define HS_CTRL_FIFO_EMPTY BIT18 +#define LP_CTRL_FIFO_FULL BIT24 +#define LP_CTRL_FIFO_HALF_EMPTY BIT25 +#define LP_CTRL_FIFO_EMPTY BIT26 +#define DBI_FIFO_EMPTY BIT27 +#define DPI_FIFO_EMPTY BIT28 +#define HS_LS_DBI_ENABLE_REG 0xb078 +#define TXCLKESC_REG 0xb07c +#define DPHY_PARAM_REG 0xb080 +#define DBI_BW_CTRL_REG 0xb084 +#define CLK_LANE_SWT_REG 0xb088 +/*=========================================================================== +; MIPI Adapter registers +;--------------------------------------------------------------------------*/ +#define MIPI_CONTROL_REG 0xb104 +#define MIPI_2X_CLOCK_BITS (BIT0 | BIT1) +#define MIPI_DATA_ADDRESS_REG 0xb108 +#define MIPI_DATA_LENGTH_REG 0xb10C +#define MIPI_COMMAND_ADDRESS_REG 0xb110 +#define MIPI_COMMAND_LENGTH_REG 0xb114 +#define MIPI_READ_DATA_RETURN_REG0 0xb118 +#define MIPI_READ_DATA_RETURN_REG1 0xb11C +#define MIPI_READ_DATA_RETURN_REG2 0xb120 +#define MIPI_READ_DATA_RETURN_REG3 0xb124 +#define MIPI_READ_DATA_RETURN_REG4 0xb128 +#define MIPI_READ_DATA_RETURN_REG5 0xb12C +#define MIPI_READ_DATA_RETURN_REG6 0xb130 +#define MIPI_READ_DATA_RETURN_REG7 0xb134 +#define MIPI_READ_DATA_VALID_REG 0xb138 +/* DBI COMMANDS */ +#define soft_reset 0x01 +/* ************************************************************************* *\ +The display module performs a software reset. +Registers are written with their SW Reset default values. +\* ************************************************************************* */ +#define get_power_mode 0x0a +/* ************************************************************************* *\ +The display module returns the current power mode +\* ************************************************************************* */ +#define get_address_mode 0x0b +/* ************************************************************************* *\ +The display module returns the current status. +\* ************************************************************************* */ +#define get_pixel_format 0x0c +/* ************************************************************************* *\ +This command gets the pixel format for the RGB image data +used by the interface. +\* ************************************************************************* */ +#define get_display_mode 0x0d +/* ************************************************************************* *\ +The display module returns the Display Image Mode status. +\* ************************************************************************* */ +#define get_signal_mode 0x0e +/* ************************************************************************* *\ +The display module returns the Display Signal Mode. +\* ************************************************************************* */ +#define get_diagnostic_result 0x0f +/* ************************************************************************* *\ +The display module returns the self-diagnostic results following +a Sleep Out command. +\* ************************************************************************* */ +#define enter_sleep_mode 0x10 +/* ************************************************************************* *\ +This command causes the display module to enter the Sleep mode. +In this mode, all unnecessary blocks inside the display module are disabled +except interface communication. This is the lowest power mode +the display module supports. +\* ************************************************************************* */ +#define exit_sleep_mode 0x11 +/* ************************************************************************* *\ +This command causes the display module to exit Sleep mode. +All blocks inside the display module are enabled. +\* ************************************************************************* */ +#define enter_partial_mode 0x12 +/* ************************************************************************* *\ +This command causes the display module to enter the Partial Display Mode. +The Partial Display Mode window is described by the set_partial_area command. +\* ************************************************************************* */ +#define enter_normal_mode 0x13 +/* ************************************************************************* *\ +This command causes the display module to enter the Normal mode. +Normal Mode is defined as Partial Display mode and Scroll mode are off +\* ************************************************************************* */ +#define exit_invert_mode 0x20 +/* ************************************************************************* *\ +This command causes the display module to stop inverting the image data on +the display device. The frame memory contents remain unchanged. +No status bits are changed. +\* ************************************************************************* */ +#define enter_invert_mode 0x21 +/* ************************************************************************* *\ +This command causes the display module to invert the image data only on +the display device. The frame memory contents remain unchanged. +No status bits are changed. +\* ************************************************************************* */ +#define set_gamma_curve 0x26 +/* ************************************************************************* *\ +This command selects the desired gamma curve for the display device. +Four fixed gamma curves are defined in section DCS spec. +\* ************************************************************************* */ +#define set_display_off 0x28 +/* ************************************************************************* *\ +This command causes the display module to stop displaying the image data +on the display device. The frame memory contents remain unchanged. +No status bits are changed. +\* ************************************************************************* */ +#define set_display_on 0x29 +/* ************************************************************************* *\ +This command causes the display module to start displaying the image data +on the display device. The frame memory contents remain unchanged. +No status bits are changed. +\* ************************************************************************* */ +#define set_column_address 0x2a +/* ************************************************************************* *\ +This command defines the column extent of the frame memory accessed by the +hostprocessor with the read_memory_continue and write_memory_continue commands. +No status bits are changed. +\* ************************************************************************* */ +#define set_page_addr 0x2b +/* ************************************************************************* *\ +This command defines the page extent of the frame memory accessed by the host +processor with the write_memory_continue and read_memory_continue command. +No status bits are changed. +\* ************************************************************************* */ +#define write_mem_start 0x2c +/* ************************************************************************* *\ +This command transfers image data from the host processor to the display +module s frame memory starting at the pixel location specified by +preceding set_column_address and set_page_address commands. +\* ************************************************************************* */ +#define set_partial_area 0x30 +/* ************************************************************************* *\ +This command defines the Partial Display mode s display area. +There are two parameters associated with +this command, the first defines the Start Row (SR) and the second the End Row +(ER). SR and ER refer to the Frame Memory Line Pointer. +\* ************************************************************************* */ +#define set_scroll_area 0x33 +/* ************************************************************************* *\ +This command defines the display modules Vertical Scrolling Area. +\* ************************************************************************* */ +#define set_tear_off 0x34 +/* ************************************************************************* *\ +This command turns off the display modules Tearing Effect output signal on +the TE signal line. +\* ************************************************************************* */ +#define set_tear_on 0x35 +/* ************************************************************************* *\ +This command turns on the display modules Tearing Effect output signal +on the TE signal line. +\* ************************************************************************* */ +#define set_address_mode 0x36 +/* ************************************************************************* *\ +This command sets the data order for transfers from the host processor to +display modules frame memory,bits B[7:5] and B3, and from the display +modules frame memory to the display device, bits B[2:0] and B4. +\* ************************************************************************* */ +#define set_scroll_start 0x37 +/* ************************************************************************* *\ +This command sets the start of the vertical scrolling area in the frame memory. +The vertical scrolling area is fully defined when this command is used with +the set_scroll_area command The set_scroll_start command has one parameter, +the Vertical Scroll Pointer. The VSP defines the line in the frame memory +that is written to the display device as the first line of the vertical +scroll area. +\* ************************************************************************* */ +#define exit_idle_mode 0x38 +/* ************************************************************************* *\ +This command causes the display module to exit Idle mode. +\* ************************************************************************* */ +#define enter_idle_mode 0x39 +/* ************************************************************************* *\ +This command causes the display module to enter Idle Mode. +In Idle Mode, color expression is reduced. Colors are shown on the display +device using the MSB of each of the R, G and B color components in the frame +memory +\* ************************************************************************* */ +#define set_pixel_format 0x3a +/* ************************************************************************* *\ +This command sets the pixel format for the RGB image data used by the interface. +Bits D[6:4] DPI Pixel Format Definition +Bits D[2:0] DBI Pixel Format Definition +Bits D7 and D3 are not used. +\* ************************************************************************* */ + #define DCS_PIXEL_FORMAT_3bbp 0x1 + #define DCS_PIXEL_FORMAT_8bbp 0x2 + #define DCS_PIXEL_FORMAT_12bbp 0x3 + #define DCS_PIXEL_FORMAT_16bbp 0x5 + #define DCS_PIXEL_FORMAT_18bbp 0x6 + #define DCS_PIXEL_FORMAT_24bbp 0x7 +#define write_mem_cont 0x3c +/* ************************************************************************* *\ +This command transfers image data from the host processor to the display +module's frame memory continuing from the pixel location following the +previous write_memory_continue or write_memory_start command. +\* ************************************************************************* */ +#define set_tear_scanline 0x44 +/* ************************************************************************* *\ +This command turns on the display modules Tearing Effect output signal on the +TE signal line when the display module reaches line N. +\* ************************************************************************* */ +#define get_scanline 0x45 +/* ************************************************************************* *\ +The display module returns the current scanline, N, used to update the +display device. The total number of scanlines on a display device is +defined as VSYNC + VBP + VACT + VFP.The first scanline is defined as +the first line of V Sync and is denoted as Line 0. +When in Sleep Mode, the value returned by get_scanline is undefined. +\* ************************************************************************* */ + +/* MCS or Generic COMMANDS */ +/* MCS/generic data type */ +#define GEN_SHORT_WRITE_0 0x03 /* generic short write, no parameters */ +#define GEN_SHORT_WRITE_1 0x13 /* generic short write, 1 parameters */ +#define GEN_SHORT_WRITE_2 0x23 /* generic short write, 2 parameters */ +#define GEN_READ_0 0x04 /* generic read, no parameters */ +#define GEN_READ_1 0x14 /* generic read, 1 parameters */ +#define GEN_READ_2 0x24 /* generic read, 2 parameters */ +#define GEN_LONG_WRITE 0x29 /* generic long write */ +#define MCS_SHORT_WRITE_0 0x05 /* MCS short write, no parameters */ +#define MCS_SHORT_WRITE_1 0x15 /* MCS short write, 1 parameters */ +#define MCS_READ 0x06 /* MCS read, no parameters */ +#define MCS_LONG_WRITE 0x39 /* MCS long write */ +/* MCS/generic commands */ +/*****TPO MCS**********/ +#define write_display_profile 0x50 +#define write_display_brightness 0x51 +#define write_ctrl_display 0x53 +#define write_ctrl_cabc 0x55 + #define UI_IMAGE 0x01 + #define STILL_IMAGE 0x02 + #define MOVING_IMAGE 0x03 +#define write_hysteresis 0x57 +#define write_gamma_setting 0x58 +#define write_cabc_min_bright 0x5e +#define write_kbbc_profile 0x60 +/*****TMD MCS**************/ +#define tmd_write_display_brightness 0x8c + +/* ************************************************************************* *\ +This command is used to control ambient light, panel backlight brightness and +gamma settings. +\* ************************************************************************* */ +#define BRIGHT_CNTL_BLOCK_ON BIT5 +#define AMBIENT_LIGHT_SENSE_ON BIT4 +#define DISPLAY_DIMMING_ON BIT3 +#define BACKLIGHT_ON BIT2 +#define DISPLAY_BRIGHTNESS_AUTO BIT1 +#define GAMMA_AUTO BIT0 + +/* DCS Interface Pixel Formats */ +#define DCS_PIXEL_FORMAT_3BPP 0x1 +#define DCS_PIXEL_FORMAT_8BPP 0x2 +#define DCS_PIXEL_FORMAT_12BPP 0x3 +#define DCS_PIXEL_FORMAT_16BPP 0x5 +#define DCS_PIXEL_FORMAT_18BPP 0x6 +#define DCS_PIXEL_FORMAT_24BPP 0x7 +/* ONE PARAMETER READ DATA */ +#define addr_mode_data 0xfc +#define diag_res_data 0x00 +#define disp_mode_data 0x23 +#define pxl_fmt_data 0x77 +#define pwr_mode_data 0x74 +#define sig_mode_data 0x00 +/* TWO PARAMETERS READ DATA */ +#define scanline_data1 0xff +#define scanline_data2 0xff +#define NON_BURST_MODE_SYNC_PULSE 0x01 /* Non Burst Mode + * with Sync Pulse + */ +#define NON_BURST_MODE_SYNC_EVENTS 0x02 /* Non Burst Mode + * with Sync events + */ +#define BURST_MODE 0x03 /* Burst Mode */ +#define DBI_COMMAND_BUFFER_SIZE 0x240 /* 0x32 */ /* 0x120 */ /* Allocate at least + * 0x100 Byte with 32 + * byte alignment + */ +#define DBI_DATA_BUFFER_SIZE 0x120 /* Allocate at least + * 0x100 Byte with 32 + * byte alignment + */ +#define DBI_CB_TIME_OUT 0xFFFF +#define GEN_FB_TIME_OUT 2000 +#define ALIGNMENT_32BYTE_MASK (~(BIT0|BIT1|BIT2|BIT3|BIT4)) +#define SKU_83 0x01 +#define SKU_100 0x02 +#define SKU_100L 0x04 +#define SKU_BYPASS 0x08 + +#endif diff --git a/drivers/staging/gma500/psb_intel_sdvo.c b/drivers/staging/gma500/psb_intel_sdvo.c new file mode 100644 index 000000000000..731a5a2261d3 --- /dev/null +++ b/drivers/staging/gma500/psb_intel_sdvo.c @@ -0,0 +1,1298 @@ +/* + * Copyright (c) 2006-2007 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Authors: + * Eric Anholt + */ + +#include +#include +/* #include */ +#include +#include "psb_drv.h" +#include "psb_intel_drv.h" +#include "psb_intel_reg.h" +#include "psb_intel_sdvo_regs.h" + +struct psb_intel_sdvo_priv { + struct psb_intel_i2c_chan *i2c_bus; + int slaveaddr; + int output_device; + + u16 active_outputs; + + struct psb_intel_sdvo_caps caps; + int pixel_clock_min, pixel_clock_max; + + int save_sdvo_mult; + u16 save_active_outputs; + struct psb_intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2; + struct psb_intel_sdvo_dtd save_output_dtd[16]; + u32 save_SDVOX; + u8 in_out_map[4]; + + u8 by_input_wiring; + u32 active_device; +}; + +/** + * Writes the SDVOB or SDVOC with the given value, but always writes both + * SDVOB and SDVOC to work around apparent hardware issues (according to + * comments in the BIOS). + */ +void psb_intel_sdvo_write_sdvox(struct psb_intel_output *psb_intel_output, + u32 val) +{ + struct drm_device *dev = psb_intel_output->base.dev; + struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; + u32 bval = val, cval = val; + int i; + + if (sdvo_priv->output_device == SDVOB) + cval = REG_READ(SDVOC); + else + bval = REG_READ(SDVOB); + /* + * Write the registers twice for luck. Sometimes, + * writing them only once doesn't appear to 'stick'. + * The BIOS does this too. Yay, magic + */ + for (i = 0; i < 2; i++) { + REG_WRITE(SDVOB, bval); + REG_READ(SDVOB); + REG_WRITE(SDVOC, cval); + REG_READ(SDVOC); + } +} + +static bool psb_intel_sdvo_read_byte( + struct psb_intel_output *psb_intel_output, + u8 addr, u8 *ch) +{ + struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; + u8 out_buf[2]; + u8 buf[2]; + int ret; + + struct i2c_msg msgs[] = { + { + .addr = sdvo_priv->i2c_bus->slave_addr, + .flags = 0, + .len = 1, + .buf = out_buf, + }, + { + .addr = sdvo_priv->i2c_bus->slave_addr, + .flags = I2C_M_RD, + .len = 1, + .buf = buf, + } + }; + + out_buf[0] = addr; + out_buf[1] = 0; + + ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2); + if (ret == 2) { + /* DRM_DEBUG("got back from addr %02X = %02x\n", + * out_buf[0], buf[0]); + */ + *ch = buf[0]; + return true; + } + + DRM_DEBUG("i2c transfer returned %d\n", ret); + return false; +} + +static bool psb_intel_sdvo_write_byte( + struct psb_intel_output *psb_intel_output, + int addr, u8 ch) +{ + u8 out_buf[2]; + struct i2c_msg msgs[] = { + { + .addr = psb_intel_output->i2c_bus->slave_addr, + .flags = 0, + .len = 2, + .buf = out_buf, + } + }; + + out_buf[0] = addr; + out_buf[1] = ch; + + if (i2c_transfer(&psb_intel_output->i2c_bus->adapter, msgs, 1) == 1) + return true; + return false; +} + +#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} +/** Mapping of command numbers to names, for debug output */ +static const struct _sdvo_cmd_name { + u8 cmd; + char *name; +} sdvo_cmd_names[] = { +SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG), + SDVO_CMD_NAME_ENTRY + (SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2), + SDVO_CMD_NAME_ENTRY + (SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING), + SDVO_CMD_NAME_ENTRY + (SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1), + SDVO_CMD_NAME_ENTRY + (SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2), + SDVO_CMD_NAME_ENTRY + (SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE), + SDVO_CMD_NAME_ENTRY + (SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE), + SDVO_CMD_NAME_ENTRY + (SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT), + SDVO_CMD_NAME_ENTRY + (SDVO_CMD_SET_TV_RESOLUTION_SUPPORT), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),}; + +#define SDVO_NAME(dev_priv) \ + ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC") +#define SDVO_PRIV(output) ((struct psb_intel_sdvo_priv *) (output)->dev_priv) + +static void psb_intel_sdvo_write_cmd(struct psb_intel_output *psb_intel_output, + u8 cmd, + void *args, + int args_len) +{ + struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; + int i; + + if (1) { + DRM_DEBUG("%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd); + for (i = 0; i < args_len; i++) + printk(KERN_INFO"%02X ", ((u8 *) args)[i]); + for (; i < 8; i++) + printk(" "); + for (i = 0; + i < + sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]); + i++) { + if (cmd == sdvo_cmd_names[i].cmd) { + printk("(%s)", sdvo_cmd_names[i].name); + break; + } + } + if (i == + sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0])) + printk("(%02X)", cmd); + printk("\n"); + } + + for (i = 0; i < args_len; i++) { + psb_intel_sdvo_write_byte(psb_intel_output, + SDVO_I2C_ARG_0 - i, + ((u8 *) args)[i]); + } + + psb_intel_sdvo_write_byte(psb_intel_output, SDVO_I2C_OPCODE, cmd); +} + +static const char *const cmd_status_names[] = { + "Power on", + "Success", + "Not supported", + "Invalid arg", + "Pending", + "Target not specified", + "Scaling not supported" +}; + +static u8 psb_intel_sdvo_read_response( + struct psb_intel_output *psb_intel_output, + void *response, int response_len) +{ + struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; + int i; + u8 status; + u8 retry = 50; + + while (retry--) { + /* Read the command response */ + for (i = 0; i < response_len; i++) { + psb_intel_sdvo_read_byte(psb_intel_output, + SDVO_I2C_RETURN_0 + i, + &((u8 *) response)[i]); + } + + /* read the return status */ + psb_intel_sdvo_read_byte(psb_intel_output, + SDVO_I2C_CMD_STATUS, + &status); + + if (1) { + DRM_DEBUG("%s: R: ", SDVO_NAME(sdvo_priv)); + for (i = 0; i < response_len; i++) + printk(KERN_INFO"%02X ", ((u8 *) response)[i]); + for (; i < 8; i++) + printk(" "); + if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP) + printk(KERN_INFO"(%s)", + cmd_status_names[status]); + else + printk(KERN_INFO"(??? %d)", status); + printk("\n"); + } + + if (status != SDVO_CMD_STATUS_PENDING) + return status; + + mdelay(50); + } + + return status; +} + +int psb_intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) +{ + if (mode->clock >= 100000) + return 1; + else if (mode->clock >= 50000) + return 2; + else + return 4; +} + +/** + * Don't check status code from this as it switches the bus back to the + * SDVO chips which defeats the purpose of doing a bus switch in the first + * place. + */ +void psb_intel_sdvo_set_control_bus_switch( + struct psb_intel_output *psb_intel_output, + u8 target) +{ + psb_intel_sdvo_write_cmd(psb_intel_output, + SDVO_CMD_SET_CONTROL_BUS_SWITCH, + &target, + 1); +} + +static bool psb_intel_sdvo_set_target_input( + struct psb_intel_output *psb_intel_output, + bool target_0, bool target_1) +{ + struct psb_intel_sdvo_set_target_input_args targets = { 0 }; + u8 status; + + if (target_0 && target_1) + return SDVO_CMD_STATUS_NOTSUPP; + + if (target_1) + targets.target_1 = 1; + + psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_TARGET_INPUT, + &targets, sizeof(targets)); + + status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); + + return status == SDVO_CMD_STATUS_SUCCESS; +} + +/** + * Return whether each input is trained. + * + * This function is making an assumption about the layout of the response, + * which should be checked against the docs. + */ +static bool psb_intel_sdvo_get_trained_inputs(struct psb_intel_output + *psb_intel_output, bool *input_1, + bool *input_2) +{ + struct psb_intel_sdvo_get_trained_inputs_response response; + u8 status; + + psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_GET_TRAINED_INPUTS, + NULL, 0); + status = + psb_intel_sdvo_read_response(psb_intel_output, &response, + sizeof(response)); + if (status != SDVO_CMD_STATUS_SUCCESS) + return false; + + *input_1 = response.input0_trained; + *input_2 = response.input1_trained; + return true; +} + +static bool psb_intel_sdvo_get_active_outputs(struct psb_intel_output + *psb_intel_output, u16 *outputs) +{ + u8 status; + + psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS, + NULL, 0); + status = + psb_intel_sdvo_read_response(psb_intel_output, outputs, + sizeof(*outputs)); + + return status == SDVO_CMD_STATUS_SUCCESS; +} + +static bool psb_intel_sdvo_set_active_outputs(struct psb_intel_output + *psb_intel_output, u16 outputs) +{ + u8 status; + + psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS, + &outputs, sizeof(outputs)); + status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); + return status == SDVO_CMD_STATUS_SUCCESS; +} + +static bool psb_intel_sdvo_set_encoder_power_state(struct psb_intel_output + *psb_intel_output, int mode) +{ + u8 status, state = SDVO_ENCODER_STATE_ON; + + switch (mode) { + case DRM_MODE_DPMS_ON: + state = SDVO_ENCODER_STATE_ON; + break; + case DRM_MODE_DPMS_STANDBY: + state = SDVO_ENCODER_STATE_STANDBY; + break; + case DRM_MODE_DPMS_SUSPEND: + state = SDVO_ENCODER_STATE_SUSPEND; + break; + case DRM_MODE_DPMS_OFF: + state = SDVO_ENCODER_STATE_OFF; + break; + } + + psb_intel_sdvo_write_cmd(psb_intel_output, + SDVO_CMD_SET_ENCODER_POWER_STATE, &state, + sizeof(state)); + status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); + + return status == SDVO_CMD_STATUS_SUCCESS; +} + +static bool psb_intel_sdvo_get_input_pixel_clock_range(struct psb_intel_output + *psb_intel_output, + int *clock_min, + int *clock_max) +{ + struct psb_intel_sdvo_pixel_clock_range clocks; + u8 status; + + psb_intel_sdvo_write_cmd(psb_intel_output, + SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, NULL, + 0); + + status = + psb_intel_sdvo_read_response(psb_intel_output, &clocks, + sizeof(clocks)); + + if (status != SDVO_CMD_STATUS_SUCCESS) + return false; + + /* Convert the values from units of 10 kHz to kHz. */ + *clock_min = clocks.min * 10; + *clock_max = clocks.max * 10; + + return true; +} + +static bool psb_intel_sdvo_set_target_output( + struct psb_intel_output *psb_intel_output, + u16 outputs) +{ + u8 status; + + psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_TARGET_OUTPUT, + &outputs, sizeof(outputs)); + + status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); + return status == SDVO_CMD_STATUS_SUCCESS; +} + +static bool psb_intel_sdvo_get_timing(struct psb_intel_output *psb_intel_output, + u8 cmd, struct psb_intel_sdvo_dtd *dtd) +{ + u8 status; + + psb_intel_sdvo_write_cmd(psb_intel_output, cmd, NULL, 0); + status = psb_intel_sdvo_read_response(psb_intel_output, &dtd->part1, + sizeof(dtd->part1)); + if (status != SDVO_CMD_STATUS_SUCCESS) + return false; + + psb_intel_sdvo_write_cmd(psb_intel_output, cmd + 1, NULL, 0); + status = psb_intel_sdvo_read_response(psb_intel_output, &dtd->part2, + sizeof(dtd->part2)); + if (status != SDVO_CMD_STATUS_SUCCESS) + return false; + + return true; +} + +static bool psb_intel_sdvo_get_input_timing( + struct psb_intel_output *psb_intel_output, + struct psb_intel_sdvo_dtd *dtd) +{ + return psb_intel_sdvo_get_timing(psb_intel_output, + SDVO_CMD_GET_INPUT_TIMINGS_PART1, + dtd); +} + +static bool psb_intel_sdvo_set_timing( + struct psb_intel_output *psb_intel_output, + u8 cmd, + struct psb_intel_sdvo_dtd *dtd) +{ + u8 status; + + psb_intel_sdvo_write_cmd(psb_intel_output, cmd, &dtd->part1, + sizeof(dtd->part1)); + status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); + if (status != SDVO_CMD_STATUS_SUCCESS) + return false; + + psb_intel_sdvo_write_cmd(psb_intel_output, cmd + 1, &dtd->part2, + sizeof(dtd->part2)); + status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); + if (status != SDVO_CMD_STATUS_SUCCESS) + return false; + + return true; +} + +static bool psb_intel_sdvo_set_input_timing( + struct psb_intel_output *psb_intel_output, + struct psb_intel_sdvo_dtd *dtd) +{ + return psb_intel_sdvo_set_timing(psb_intel_output, + SDVO_CMD_SET_INPUT_TIMINGS_PART1, + dtd); +} + +static bool psb_intel_sdvo_set_output_timing( + struct psb_intel_output *psb_intel_output, + struct psb_intel_sdvo_dtd *dtd) +{ + return psb_intel_sdvo_set_timing(psb_intel_output, + SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, + dtd); +} + +static int psb_intel_sdvo_get_clock_rate_mult(struct psb_intel_output + *psb_intel_output) +{ + u8 response, status; + + psb_intel_sdvo_write_cmd(psb_intel_output, + SDVO_CMD_GET_CLOCK_RATE_MULT, + NULL, + 0); + + status = psb_intel_sdvo_read_response(psb_intel_output, &response, 1); + + if (status != SDVO_CMD_STATUS_SUCCESS) { + DRM_DEBUG("Couldn't get SDVO clock rate multiplier\n"); + return SDVO_CLOCK_RATE_MULT_1X; + } else { + DRM_DEBUG("Current clock rate multiplier: %d\n", response); + } + + return response; +} + +static bool psb_intel_sdvo_set_clock_rate_mult(struct psb_intel_output + *psb_intel_output, u8 val) +{ + u8 status; + + psb_intel_sdvo_write_cmd(psb_intel_output, + SDVO_CMD_SET_CLOCK_RATE_MULT, + &val, + 1); + + status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); + if (status != SDVO_CMD_STATUS_SUCCESS) + return false; + + return true; +} + +static bool psb_sdvo_set_current_inoutmap(struct psb_intel_output *output, + u32 in0outputmask, + u32 in1outputmask) +{ + u8 byArgs[4]; + u8 status; + int i; + struct psb_intel_sdvo_priv *sdvo_priv = output->dev_priv; + + /* Make all fields of the args/ret to zero */ + memset(byArgs, 0, sizeof(byArgs)); + + /* Fill up the arguement values; */ + byArgs[0] = (u8) (in0outputmask & 0xFF); + byArgs[1] = (u8) ((in0outputmask >> 8) & 0xFF); + byArgs[2] = (u8) (in1outputmask & 0xFF); + byArgs[3] = (u8) ((in1outputmask >> 8) & 0xFF); + + + /*save inoutmap arg here*/ + for (i = 0; i < 4; i++) + sdvo_priv->in_out_map[i] = byArgs[0]; + + psb_intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP, byArgs, 4); + status = psb_intel_sdvo_read_response(output, NULL, 0); + + if (status != SDVO_CMD_STATUS_SUCCESS) + return false; + return true; +} + + +static void psb_intel_sdvo_set_iomap(struct psb_intel_output *output) +{ + u32 dwCurrentSDVOIn0 = 0; + u32 dwCurrentSDVOIn1 = 0; + u32 dwDevMask = 0; + + + struct psb_intel_sdvo_priv *sdvo_priv = output->dev_priv; + + /* Please DO NOT change the following code. */ + /* SDVOB_IN0 or SDVOB_IN1 ==> sdvo_in0 */ + /* SDVOC_IN0 or SDVOC_IN1 ==> sdvo_in1 */ + if (sdvo_priv->by_input_wiring & (SDVOB_IN0 | SDVOC_IN0)) { + switch (sdvo_priv->active_device) { + case SDVO_DEVICE_LVDS: + dwDevMask = SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1; + break; + case SDVO_DEVICE_TMDS: + dwDevMask = SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1; + break; + case SDVO_DEVICE_TV: + dwDevMask = + SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_SVID0 | + SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_YPRPB1 | + SDVO_OUTPUT_SVID1 | SDVO_OUTPUT_CVBS1 | + SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1; + break; + case SDVO_DEVICE_CRT: + dwDevMask = SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1; + break; + } + dwCurrentSDVOIn0 = (sdvo_priv->active_outputs & dwDevMask); + } else if (sdvo_priv->by_input_wiring & (SDVOB_IN1 | SDVOC_IN1)) { + switch (sdvo_priv->active_device) { + case SDVO_DEVICE_LVDS: + dwDevMask = SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1; + break; + case SDVO_DEVICE_TMDS: + dwDevMask = SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1; + break; + case SDVO_DEVICE_TV: + dwDevMask = + SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_SVID0 | + SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_YPRPB1 | + SDVO_OUTPUT_SVID1 | SDVO_OUTPUT_CVBS1 | + SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1; + break; + case SDVO_DEVICE_CRT: + dwDevMask = SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1; + break; + } + dwCurrentSDVOIn1 = (sdvo_priv->active_outputs & dwDevMask); + } + + psb_sdvo_set_current_inoutmap(output, dwCurrentSDVOIn0, + dwCurrentSDVOIn1); +} + + +static bool psb_intel_sdvo_mode_fixup(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + /* Make the CRTC code factor in the SDVO pixel multiplier. The SDVO + * device will be told of the multiplier during mode_set. + */ + adjusted_mode->clock *= psb_intel_sdvo_get_pixel_multiplier(mode); + return true; +} + +static void psb_intel_sdvo_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct drm_device *dev = encoder->dev; + struct drm_crtc *crtc = encoder->crtc; + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + struct psb_intel_output *psb_intel_output = + enc_to_psb_intel_output(encoder); + struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; + u16 width, height; + u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len; + u16 h_sync_offset, v_sync_offset; + u32 sdvox; + struct psb_intel_sdvo_dtd output_dtd; + int sdvo_pixel_multiply; + + if (!mode) + return; + + psb_intel_sdvo_set_target_output(psb_intel_output, 0); + + width = mode->crtc_hdisplay; + height = mode->crtc_vdisplay; + + /* do some mode translations */ + h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start; + h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; + + v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start; + v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; + + h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start; + v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; + + output_dtd.part1.clock = mode->clock / 10; + output_dtd.part1.h_active = width & 0xff; + output_dtd.part1.h_blank = h_blank_len & 0xff; + output_dtd.part1.h_high = (((width >> 8) & 0xf) << 4) | + ((h_blank_len >> 8) & 0xf); + output_dtd.part1.v_active = height & 0xff; + output_dtd.part1.v_blank = v_blank_len & 0xff; + output_dtd.part1.v_high = (((height >> 8) & 0xf) << 4) | + ((v_blank_len >> 8) & 0xf); + + output_dtd.part2.h_sync_off = h_sync_offset; + output_dtd.part2.h_sync_width = h_sync_len & 0xff; + output_dtd.part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 | + (v_sync_len & 0xf); + output_dtd.part2.sync_off_width_high = + ((h_sync_offset & 0x300) >> 2) | ((h_sync_len & 0x300) >> 4) | + ((v_sync_offset & 0x30) >> 2) | ((v_sync_len & 0x30) >> 4); + + output_dtd.part2.dtd_flags = 0x18; + if (mode->flags & DRM_MODE_FLAG_PHSYNC) + output_dtd.part2.dtd_flags |= 0x2; + if (mode->flags & DRM_MODE_FLAG_PVSYNC) + output_dtd.part2.dtd_flags |= 0x4; + + output_dtd.part2.sdvo_flags = 0; + output_dtd.part2.v_sync_off_high = v_sync_offset & 0xc0; + output_dtd.part2.reserved = 0; + + /* Set the output timing to the screen */ + psb_intel_sdvo_set_target_output(psb_intel_output, + sdvo_priv->active_outputs); + + /* Set the input timing to the screen. Assume always input 0. */ + psb_intel_sdvo_set_target_input(psb_intel_output, true, false); + + psb_intel_sdvo_set_output_timing(psb_intel_output, &output_dtd); + + /* We would like to use i830_sdvo_create_preferred_input_timing() to + * provide the device with a timing it can support, if it supports that + * feature. However, presumably we would need to adjust the CRTC to + * output the preferred timing, and we don't support that currently. + */ + psb_intel_sdvo_set_input_timing(psb_intel_output, &output_dtd); + + switch (psb_intel_sdvo_get_pixel_multiplier(mode)) { + case 1: + psb_intel_sdvo_set_clock_rate_mult(psb_intel_output, + SDVO_CLOCK_RATE_MULT_1X); + break; + case 2: + psb_intel_sdvo_set_clock_rate_mult(psb_intel_output, + SDVO_CLOCK_RATE_MULT_2X); + break; + case 4: + psb_intel_sdvo_set_clock_rate_mult(psb_intel_output, + SDVO_CLOCK_RATE_MULT_4X); + break; + } + + /* Set the SDVO control regs. */ + sdvox = REG_READ(sdvo_priv->output_device); + switch (sdvo_priv->output_device) { + case SDVOB: + sdvox &= SDVOB_PRESERVE_MASK; + break; + case SDVOC: + sdvox &= SDVOC_PRESERVE_MASK; + break; + } + sdvox |= (9 << 19) | SDVO_BORDER_ENABLE; + if (psb_intel_crtc->pipe == 1) + sdvox |= SDVO_PIPE_B_SELECT; + + sdvo_pixel_multiply = psb_intel_sdvo_get_pixel_multiplier(mode); + + psb_intel_sdvo_write_sdvox(psb_intel_output, sdvox); + + psb_intel_sdvo_set_iomap(psb_intel_output); +} + +static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode) +{ + struct drm_device *dev = encoder->dev; + struct psb_intel_output *psb_intel_output = + enc_to_psb_intel_output(encoder); + struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; + u32 temp; + + if (mode != DRM_MODE_DPMS_ON) { + psb_intel_sdvo_set_active_outputs(psb_intel_output, 0); + if (0) + psb_intel_sdvo_set_encoder_power_state( + psb_intel_output, + mode); + + if (mode == DRM_MODE_DPMS_OFF) { + temp = REG_READ(sdvo_priv->output_device); + if ((temp & SDVO_ENABLE) != 0) { + psb_intel_sdvo_write_sdvox(psb_intel_output, + temp & + ~SDVO_ENABLE); + } + } + } else { + bool input1, input2; + int i; + u8 status; + + temp = REG_READ(sdvo_priv->output_device); + if ((temp & SDVO_ENABLE) == 0) + psb_intel_sdvo_write_sdvox(psb_intel_output, + temp | SDVO_ENABLE); + for (i = 0; i < 2; i++) + psb_intel_wait_for_vblank(dev); + + status = + psb_intel_sdvo_get_trained_inputs(psb_intel_output, + &input1, + &input2); + + + /* Warn if the device reported failure to sync. + * A lot of SDVO devices fail to notify of sync, but it's + * a given it the status is a success, we succeeded. + */ + if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { + DRM_DEBUG + ("First %s output reported failure to sync\n", + SDVO_NAME(sdvo_priv)); + } + + if (0) + psb_intel_sdvo_set_encoder_power_state( + psb_intel_output, + mode); + psb_intel_sdvo_set_active_outputs(psb_intel_output, + sdvo_priv->active_outputs); + } + return; +} + +static void psb_intel_sdvo_save(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; + /*int o;*/ + + sdvo_priv->save_sdvo_mult = + psb_intel_sdvo_get_clock_rate_mult(psb_intel_output); + psb_intel_sdvo_get_active_outputs(psb_intel_output, + &sdvo_priv->save_active_outputs); + + if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { + psb_intel_sdvo_set_target_input(psb_intel_output, + true, + false); + psb_intel_sdvo_get_input_timing(psb_intel_output, + &sdvo_priv->save_input_dtd_1); + } + + if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { + psb_intel_sdvo_set_target_input(psb_intel_output, + false, + true); + psb_intel_sdvo_get_input_timing(psb_intel_output, + &sdvo_priv->save_input_dtd_2); + } + sdvo_priv->save_SDVOX = REG_READ(sdvo_priv->output_device); + + /*TODO: save the in_out_map state*/ +} + +static void psb_intel_sdvo_restore(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; + /*int o;*/ + int i; + bool input1, input2; + u8 status; + + psb_intel_sdvo_set_active_outputs(psb_intel_output, 0); + + if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { + psb_intel_sdvo_set_target_input(psb_intel_output, true, false); + psb_intel_sdvo_set_input_timing(psb_intel_output, + &sdvo_priv->save_input_dtd_1); + } + + if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { + psb_intel_sdvo_set_target_input(psb_intel_output, false, true); + psb_intel_sdvo_set_input_timing(psb_intel_output, + &sdvo_priv->save_input_dtd_2); + } + + psb_intel_sdvo_set_clock_rate_mult(psb_intel_output, + sdvo_priv->save_sdvo_mult); + + REG_WRITE(sdvo_priv->output_device, sdvo_priv->save_SDVOX); + + if (sdvo_priv->save_SDVOX & SDVO_ENABLE) { + for (i = 0; i < 2; i++) + psb_intel_wait_for_vblank(dev); + status = + psb_intel_sdvo_get_trained_inputs(psb_intel_output, + &input1, + &input2); + if (status == SDVO_CMD_STATUS_SUCCESS && !input1) + DRM_DEBUG + ("First %s output reported failure to sync\n", + SDVO_NAME(sdvo_priv)); + } + + psb_intel_sdvo_set_active_outputs(psb_intel_output, + sdvo_priv->save_active_outputs); + + /*TODO: restore in_out_map*/ + psb_intel_sdvo_write_cmd(psb_intel_output, + SDVO_CMD_SET_IN_OUT_MAP, + sdvo_priv->in_out_map, + 4); + + psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); +} + +static int psb_intel_sdvo_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; + + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) + return MODE_NO_DBLESCAN; + + if (sdvo_priv->pixel_clock_min > mode->clock) + return MODE_CLOCK_LOW; + + if (sdvo_priv->pixel_clock_max < mode->clock) + return MODE_CLOCK_HIGH; + + return MODE_OK; +} + +static bool psb_intel_sdvo_get_capabilities( + struct psb_intel_output *psb_intel_output, + struct psb_intel_sdvo_caps *caps) +{ + u8 status; + + psb_intel_sdvo_write_cmd(psb_intel_output, + SDVO_CMD_GET_DEVICE_CAPS, + NULL, + 0); + status = psb_intel_sdvo_read_response(psb_intel_output, + caps, + sizeof(*caps)); + if (status != SDVO_CMD_STATUS_SUCCESS) + return false; + + return true; +} + +struct drm_connector *psb_intel_sdvo_find(struct drm_device *dev, int sdvoB) +{ + struct drm_connector *connector = NULL; + struct psb_intel_output *iout = NULL; + struct psb_intel_sdvo_priv *sdvo; + + /* find the sdvo connector */ + list_for_each_entry(connector, &dev->mode_config.connector_list, + head) { + iout = to_psb_intel_output(connector); + + if (iout->type != INTEL_OUTPUT_SDVO) + continue; + + sdvo = iout->dev_priv; + + if (sdvo->output_device == SDVOB && sdvoB) + return connector; + + if (sdvo->output_device == SDVOC && !sdvoB) + return connector; + + } + + return NULL; +} + +int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector) +{ + u8 response[2]; + u8 status; + struct psb_intel_output *psb_intel_output; + DRM_DEBUG("\n"); + + if (!connector) + return 0; + + psb_intel_output = to_psb_intel_output(connector); + + psb_intel_sdvo_write_cmd(psb_intel_output, + SDVO_CMD_GET_HOT_PLUG_SUPPORT, + NULL, + 0); + status = psb_intel_sdvo_read_response(psb_intel_output, + &response, + 2); + + if (response[0] != 0) + return 1; + + return 0; +} + +void psb_intel_sdvo_set_hotplug(struct drm_connector *connector, int on) +{ + u8 response[2]; + u8 status; + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + + psb_intel_sdvo_write_cmd(psb_intel_output, + SDVO_CMD_GET_ACTIVE_HOT_PLUG, + NULL, + 0); + psb_intel_sdvo_read_response(psb_intel_output, &response, 2); + + if (on) { + psb_intel_sdvo_write_cmd(psb_intel_output, + SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, + 0); + status = psb_intel_sdvo_read_response(psb_intel_output, + &response, + 2); + + psb_intel_sdvo_write_cmd(psb_intel_output, + SDVO_CMD_SET_ACTIVE_HOT_PLUG, + &response, 2); + } else { + response[0] = 0; + response[1] = 0; + psb_intel_sdvo_write_cmd(psb_intel_output, + SDVO_CMD_SET_ACTIVE_HOT_PLUG, + &response, 2); + } + + psb_intel_sdvo_write_cmd(psb_intel_output, + SDVO_CMD_GET_ACTIVE_HOT_PLUG, + NULL, + 0); + psb_intel_sdvo_read_response(psb_intel_output, &response, 2); +} + +static enum drm_connector_status psb_intel_sdvo_detect(struct drm_connector + *connector, bool force) +{ + u8 response[2]; + u8 status; + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + + psb_intel_sdvo_write_cmd(psb_intel_output, + SDVO_CMD_GET_ATTACHED_DISPLAYS, + NULL, + 0); + status = psb_intel_sdvo_read_response(psb_intel_output, &response, 2); + + DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]); + if ((response[0] != 0) || (response[1] != 0)) + return connector_status_connected; + else + return connector_status_disconnected; +} + +static int psb_intel_sdvo_get_modes(struct drm_connector *connector) +{ + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + + /* set the bus switch and get the modes */ + psb_intel_sdvo_set_control_bus_switch(psb_intel_output, + SDVO_CONTROL_BUS_DDC2); + psb_intel_ddc_get_modes(psb_intel_output); + + if (list_empty(&connector->probed_modes)) + return 0; + return 1; +} + +static void psb_intel_sdvo_destroy(struct drm_connector *connector) +{ + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + + if (psb_intel_output->i2c_bus) + psb_intel_i2c_destroy(psb_intel_output->i2c_bus); + drm_sysfs_connector_remove(connector); + drm_connector_cleanup(connector); + kfree(psb_intel_output); +} + +static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = { + .dpms = psb_intel_sdvo_dpms, + .mode_fixup = psb_intel_sdvo_mode_fixup, + .prepare = psb_intel_encoder_prepare, + .mode_set = psb_intel_sdvo_mode_set, + .commit = psb_intel_encoder_commit, +}; + +static const struct drm_connector_funcs psb_intel_sdvo_connector_funcs = { + .dpms = drm_helper_connector_dpms, + .save = psb_intel_sdvo_save, + .restore = psb_intel_sdvo_restore, + .detect = psb_intel_sdvo_detect, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = psb_intel_sdvo_destroy, +}; + +static const struct drm_connector_helper_funcs + psb_intel_sdvo_connector_helper_funcs = { + .get_modes = psb_intel_sdvo_get_modes, + .mode_valid = psb_intel_sdvo_mode_valid, + .best_encoder = psb_intel_best_encoder, +}; + +void psb_intel_sdvo_enc_destroy(struct drm_encoder *encoder) +{ + drm_encoder_cleanup(encoder); +} + +static const struct drm_encoder_funcs psb_intel_sdvo_enc_funcs = { + .destroy = psb_intel_sdvo_enc_destroy, +}; + + +void psb_intel_sdvo_init(struct drm_device *dev, int output_device) +{ + struct drm_connector *connector; + struct psb_intel_output *psb_intel_output; + struct psb_intel_sdvo_priv *sdvo_priv; + struct psb_intel_i2c_chan *i2cbus = NULL; + int connector_type; + u8 ch[0x40]; + int i; + int encoder_type, output_id; + + psb_intel_output = + kcalloc(sizeof(struct psb_intel_output) + + sizeof(struct psb_intel_sdvo_priv), 1, GFP_KERNEL); + if (!psb_intel_output) + return; + + connector = &psb_intel_output->base; + + drm_connector_init(dev, connector, &psb_intel_sdvo_connector_funcs, + DRM_MODE_CONNECTOR_Unknown); + drm_connector_helper_add(connector, + &psb_intel_sdvo_connector_helper_funcs); + sdvo_priv = (struct psb_intel_sdvo_priv *) (psb_intel_output + 1); + psb_intel_output->type = INTEL_OUTPUT_SDVO; + + connector->interlace_allowed = 0; + connector->doublescan_allowed = 0; + + /* setup the DDC bus. */ + if (output_device == SDVOB) + i2cbus = + psb_intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); + else + i2cbus = + psb_intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); + + if (!i2cbus) + goto err_connector; + + sdvo_priv->i2c_bus = i2cbus; + + if (output_device == SDVOB) { + output_id = 1; + sdvo_priv->by_input_wiring = SDVOB_IN0; + sdvo_priv->i2c_bus->slave_addr = 0x38; + } else { + output_id = 2; + sdvo_priv->i2c_bus->slave_addr = 0x39; + } + + sdvo_priv->output_device = output_device; + psb_intel_output->i2c_bus = i2cbus; + psb_intel_output->dev_priv = sdvo_priv; + + + /* Read the regs to test if we can talk to the device */ + for (i = 0; i < 0x40; i++) { + if (!psb_intel_sdvo_read_byte(psb_intel_output, i, &ch[i])) { + DRM_DEBUG("No SDVO device found on SDVO%c\n", + output_device == SDVOB ? 'B' : 'C'); + goto err_i2c; + } + } + + psb_intel_sdvo_get_capabilities(psb_intel_output, &sdvo_priv->caps); + + memset(&sdvo_priv->active_outputs, 0, + sizeof(sdvo_priv->active_outputs)); + + /* TODO, CVBS, SVID, YPRPB & SCART outputs. */ + if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0) { + sdvo_priv->active_outputs = SDVO_OUTPUT_RGB0; + sdvo_priv->active_device = SDVO_DEVICE_CRT; + connector->display_info.subpixel_order = + SubPixelHorizontalRGB; + encoder_type = DRM_MODE_ENCODER_DAC; + connector_type = DRM_MODE_CONNECTOR_VGA; + } else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1) { + sdvo_priv->active_outputs = SDVO_OUTPUT_RGB1; + sdvo_priv->active_outputs = SDVO_DEVICE_CRT; + connector->display_info.subpixel_order = + SubPixelHorizontalRGB; + encoder_type = DRM_MODE_ENCODER_DAC; + connector_type = DRM_MODE_CONNECTOR_VGA; + } else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) { + sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS0; + sdvo_priv->active_device = SDVO_DEVICE_TMDS; + connector->display_info.subpixel_order = + SubPixelHorizontalRGB; + encoder_type = DRM_MODE_ENCODER_TMDS; + connector_type = DRM_MODE_CONNECTOR_DVID; + } else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS1) { + sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS1; + sdvo_priv->active_device = SDVO_DEVICE_TMDS; + connector->display_info.subpixel_order = + SubPixelHorizontalRGB; + encoder_type = DRM_MODE_ENCODER_TMDS; + connector_type = DRM_MODE_CONNECTOR_DVID; + } else { + unsigned char bytes[2]; + + memcpy(bytes, &sdvo_priv->caps.output_flags, 2); + DRM_DEBUG + ("%s: No active RGB or TMDS outputs (0x%02x%02x)\n", + SDVO_NAME(sdvo_priv), bytes[0], bytes[1]); + goto err_i2c; + } + + drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_sdvo_enc_funcs, + encoder_type); + drm_encoder_helper_add(&psb_intel_output->enc, + &psb_intel_sdvo_helper_funcs); + connector->connector_type = connector_type; + + drm_mode_connector_attach_encoder(&psb_intel_output->base, + &psb_intel_output->enc); + drm_sysfs_connector_add(connector); + + /* Set the input timing to the screen. Assume always input 0. */ + psb_intel_sdvo_set_target_input(psb_intel_output, true, false); + + psb_intel_sdvo_get_input_pixel_clock_range(psb_intel_output, + &sdvo_priv->pixel_clock_min, + &sdvo_priv-> + pixel_clock_max); + + + DRM_DEBUG("%s device VID/DID: %02X:%02X.%02X, " + "clock range %dMHz - %dMHz, " + "input 1: %c, input 2: %c, " + "output 1: %c, output 2: %c\n", + SDVO_NAME(sdvo_priv), + sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id, + sdvo_priv->caps.device_rev_id, + sdvo_priv->pixel_clock_min / 1000, + sdvo_priv->pixel_clock_max / 1000, + (sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N', + (sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N', + /* check currently supported outputs */ + sdvo_priv->caps.output_flags & + (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N', + sdvo_priv->caps.output_flags & + (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); + + psb_intel_output->ddc_bus = i2cbus; + + return; + +err_i2c: + psb_intel_i2c_destroy(psb_intel_output->i2c_bus); +err_connector: + drm_connector_cleanup(connector); + kfree(psb_intel_output); + + return; +} diff --git a/drivers/staging/gma500/psb_intel_sdvo_regs.h b/drivers/staging/gma500/psb_intel_sdvo_regs.h new file mode 100644 index 000000000000..ed2f1360df1a --- /dev/null +++ b/drivers/staging/gma500/psb_intel_sdvo_regs.h @@ -0,0 +1,338 @@ +/* + * SDVO command definitions and structures. + * + * Copyright (c) 2008, Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Authors: + * Eric Anholt + */ + +#define SDVO_OUTPUT_FIRST (0) +#define SDVO_OUTPUT_TMDS0 (1 << 0) +#define SDVO_OUTPUT_RGB0 (1 << 1) +#define SDVO_OUTPUT_CVBS0 (1 << 2) +#define SDVO_OUTPUT_SVID0 (1 << 3) +#define SDVO_OUTPUT_YPRPB0 (1 << 4) +#define SDVO_OUTPUT_SCART0 (1 << 5) +#define SDVO_OUTPUT_LVDS0 (1 << 6) +#define SDVO_OUTPUT_TMDS1 (1 << 8) +#define SDVO_OUTPUT_RGB1 (1 << 9) +#define SDVO_OUTPUT_CVBS1 (1 << 10) +#define SDVO_OUTPUT_SVID1 (1 << 11) +#define SDVO_OUTPUT_YPRPB1 (1 << 12) +#define SDVO_OUTPUT_SCART1 (1 << 13) +#define SDVO_OUTPUT_LVDS1 (1 << 14) +#define SDVO_OUTPUT_LAST (14) + +struct psb_intel_sdvo_caps { + u8 vendor_id; + u8 device_id; + u8 device_rev_id; + u8 sdvo_version_major; + u8 sdvo_version_minor; + unsigned int sdvo_inputs_mask:2; + unsigned int smooth_scaling:1; + unsigned int sharp_scaling:1; + unsigned int up_scaling:1; + unsigned int down_scaling:1; + unsigned int stall_support:1; + unsigned int pad:1; + u16 output_flags; +} __attribute__ ((packed)); + +/** This matches the EDID DTD structure, more or less */ +struct psb_intel_sdvo_dtd { + struct { + u16 clock; /**< pixel clock, in 10kHz units */ + u8 h_active; /**< lower 8 bits (pixels) */ + u8 h_blank; /**< lower 8 bits (pixels) */ + u8 h_high; /**< upper 4 bits each h_active, h_blank */ + u8 v_active; /**< lower 8 bits (lines) */ + u8 v_blank; /**< lower 8 bits (lines) */ + u8 v_high; /**< upper 4 bits each v_active, v_blank */ + } part1; + + struct { + u8 h_sync_off; + /**< lower 8 bits, from hblank start */ + u8 h_sync_width;/**< lower 8 bits (pixels) */ + /** lower 4 bits each vsync offset, vsync width */ + u8 v_sync_off_width; + /** + * 2 high bits of hsync offset, 2 high bits of hsync width, + * bits 4-5 of vsync offset, and 2 high bits of vsync width. + */ + u8 sync_off_width_high; + u8 dtd_flags; + u8 sdvo_flags; + /** bits 6-7 of vsync offset at bits 6-7 */ + u8 v_sync_off_high; + u8 reserved; + } part2; +} __attribute__ ((packed)); + +struct psb_intel_sdvo_pixel_clock_range { + u16 min; /**< pixel clock, in 10kHz units */ + u16 max; /**< pixel clock, in 10kHz units */ +} __attribute__ ((packed)); + +struct psb_intel_sdvo_preferred_input_timing_args { + u16 clock; + u16 width; + u16 height; +} __attribute__ ((packed)); + +/* I2C registers for SDVO */ +#define SDVO_I2C_ARG_0 0x07 +#define SDVO_I2C_ARG_1 0x06 +#define SDVO_I2C_ARG_2 0x05 +#define SDVO_I2C_ARG_3 0x04 +#define SDVO_I2C_ARG_4 0x03 +#define SDVO_I2C_ARG_5 0x02 +#define SDVO_I2C_ARG_6 0x01 +#define SDVO_I2C_ARG_7 0x00 +#define SDVO_I2C_OPCODE 0x08 +#define SDVO_I2C_CMD_STATUS 0x09 +#define SDVO_I2C_RETURN_0 0x0a +#define SDVO_I2C_RETURN_1 0x0b +#define SDVO_I2C_RETURN_2 0x0c +#define SDVO_I2C_RETURN_3 0x0d +#define SDVO_I2C_RETURN_4 0x0e +#define SDVO_I2C_RETURN_5 0x0f +#define SDVO_I2C_RETURN_6 0x10 +#define SDVO_I2C_RETURN_7 0x11 +#define SDVO_I2C_VENDOR_BEGIN 0x20 + +/* Status results */ +#define SDVO_CMD_STATUS_POWER_ON 0x0 +#define SDVO_CMD_STATUS_SUCCESS 0x1 +#define SDVO_CMD_STATUS_NOTSUPP 0x2 +#define SDVO_CMD_STATUS_INVALID_ARG 0x3 +#define SDVO_CMD_STATUS_PENDING 0x4 +#define SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED 0x5 +#define SDVO_CMD_STATUS_SCALING_NOT_SUPP 0x6 + +/* SDVO commands, argument/result registers */ + +#define SDVO_CMD_RESET 0x01 + +/** Returns a struct psb_intel_sdvo_caps */ +#define SDVO_CMD_GET_DEVICE_CAPS 0x02 + +#define SDVO_CMD_GET_FIRMWARE_REV 0x86 +# define SDVO_DEVICE_FIRMWARE_MINOR SDVO_I2C_RETURN_0 +# define SDVO_DEVICE_FIRMWARE_MAJOR SDVO_I2C_RETURN_1 +# define SDVO_DEVICE_FIRMWARE_PATCH SDVO_I2C_RETURN_2 + +/** + * Reports which inputs are trained (managed to sync). + * + * Devices must have trained within 2 vsyncs of a mode change. + */ +#define SDVO_CMD_GET_TRAINED_INPUTS 0x03 +struct psb_intel_sdvo_get_trained_inputs_response { + unsigned int input0_trained:1; + unsigned int input1_trained:1; + unsigned int pad:6; +} __attribute__ ((packed)); + +/** Returns a struct psb_intel_sdvo_output_flags of active outputs. */ +#define SDVO_CMD_GET_ACTIVE_OUTPUTS 0x04 + +/** + * Sets the current set of active outputs. + * + * Takes a struct psb_intel_sdvo_output_flags. + * Must be preceded by a SET_IN_OUT_MAP + * on multi-output devices. + */ +#define SDVO_CMD_SET_ACTIVE_OUTPUTS 0x05 + +/** + * Returns the current mapping of SDVO inputs to outputs on the device. + * + * Returns two struct psb_intel_sdvo_output_flags structures. + */ +#define SDVO_CMD_GET_IN_OUT_MAP 0x06 + +/** + * Sets the current mapping of SDVO inputs to outputs on the device. + * + * Takes two struct i380_sdvo_output_flags structures. + */ +#define SDVO_CMD_SET_IN_OUT_MAP 0x07 + +/** + * Returns a struct psb_intel_sdvo_output_flags of attached displays. + */ +#define SDVO_CMD_GET_ATTACHED_DISPLAYS 0x0b + +/** + * Returns a struct psb_intel_sdvo_ouptut_flags of displays supporting hot plugging. + */ +#define SDVO_CMD_GET_HOT_PLUG_SUPPORT 0x0c + +/** + * Takes a struct psb_intel_sdvo_output_flags. + */ +#define SDVO_CMD_SET_ACTIVE_HOT_PLUG 0x0d + +/** + * Returns a struct psb_intel_sdvo_output_flags of displays with hot plug + * interrupts enabled. + */ +#define SDVO_CMD_GET_ACTIVE_HOT_PLUG 0x0e + +#define SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE 0x0f +struct psb_intel_sdvo_get_interrupt_event_source_response { + u16 interrupt_status; + unsigned int ambient_light_interrupt:1; + unsigned int pad:7; +} __attribute__ ((packed)); + +/** + * Selects which input is affected by future input commands. + * + * Commands affected include SET_INPUT_TIMINGS_PART[12], + * GET_INPUT_TIMINGS_PART[12], GET_PREFERRED_INPUT_TIMINGS_PART[12], + * GET_INPUT_PIXEL_CLOCK_RANGE, and CREATE_PREFERRED_INPUT_TIMINGS. + */ +#define SDVO_CMD_SET_TARGET_INPUT 0x10 +struct psb_intel_sdvo_set_target_input_args { + unsigned int target_1:1; + unsigned int pad:7; +} __attribute__ ((packed)); + +/** + * Takes a struct psb_intel_sdvo_output_flags of which outputs are targetted by + * future output commands. + * + * Affected commands inclue SET_OUTPUT_TIMINGS_PART[12], + * GET_OUTPUT_TIMINGS_PART[12], and GET_OUTPUT_PIXEL_CLOCK_RANGE. + */ +#define SDVO_CMD_SET_TARGET_OUTPUT 0x11 + +#define SDVO_CMD_GET_INPUT_TIMINGS_PART1 0x12 +#define SDVO_CMD_GET_INPUT_TIMINGS_PART2 0x13 +#define SDVO_CMD_SET_INPUT_TIMINGS_PART1 0x14 +#define SDVO_CMD_SET_INPUT_TIMINGS_PART2 0x15 +#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART1 0x16 +#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART2 0x17 +#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART1 0x18 +#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART2 0x19 +/* Part 1 */ +# define SDVO_DTD_CLOCK_LOW SDVO_I2C_ARG_0 +# define SDVO_DTD_CLOCK_HIGH SDVO_I2C_ARG_1 +# define SDVO_DTD_H_ACTIVE SDVO_I2C_ARG_2 +# define SDVO_DTD_H_BLANK SDVO_I2C_ARG_3 +# define SDVO_DTD_H_HIGH SDVO_I2C_ARG_4 +# define SDVO_DTD_V_ACTIVE SDVO_I2C_ARG_5 +# define SDVO_DTD_V_BLANK SDVO_I2C_ARG_6 +# define SDVO_DTD_V_HIGH SDVO_I2C_ARG_7 +/* Part 2 */ +# define SDVO_DTD_HSYNC_OFF SDVO_I2C_ARG_0 +# define SDVO_DTD_HSYNC_WIDTH SDVO_I2C_ARG_1 +# define SDVO_DTD_VSYNC_OFF_WIDTH SDVO_I2C_ARG_2 +# define SDVO_DTD_SYNC_OFF_WIDTH_HIGH SDVO_I2C_ARG_3 +# define SDVO_DTD_DTD_FLAGS SDVO_I2C_ARG_4 +# define SDVO_DTD_DTD_FLAG_INTERLACED (1 << 7) +# define SDVO_DTD_DTD_FLAG_STEREO_MASK (3 << 5) +# define SDVO_DTD_DTD_FLAG_INPUT_MASK (3 << 3) +# define SDVO_DTD_DTD_FLAG_SYNC_MASK (3 << 1) +# define SDVO_DTD_SDVO_FLAS SDVO_I2C_ARG_5 +# define SDVO_DTD_SDVO_FLAG_STALL (1 << 7) +# define SDVO_DTD_SDVO_FLAG_CENTERED (0 << 6) +# define SDVO_DTD_SDVO_FLAG_UPPER_LEFT (1 << 6) +# define SDVO_DTD_SDVO_FLAG_SCALING_MASK (3 << 4) +# define SDVO_DTD_SDVO_FLAG_SCALING_NONE (0 << 4) +# define SDVO_DTD_SDVO_FLAG_SCALING_SHARP (1 << 4) +# define SDVO_DTD_SDVO_FLAG_SCALING_SMOOTH (2 << 4) +# define SDVO_DTD_VSYNC_OFF_HIGH SDVO_I2C_ARG_6 + +/** + * Generates a DTD based on the given width, height, and flags. + * + * This will be supported by any device supporting scaling or interlaced + * modes. + */ +#define SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING 0x1a +# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_LOW SDVO_I2C_ARG_0 +# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_HIGH SDVO_I2C_ARG_1 +# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_LOW SDVO_I2C_ARG_2 +# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_HIGH SDVO_I2C_ARG_3 +# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_LOW SDVO_I2C_ARG_4 +# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_HIGH SDVO_I2C_ARG_5 +# define SDVO_PREFERRED_INPUT_TIMING_FLAGS SDVO_I2C_ARG_6 +# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_INTERLACED (1 << 0) +# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_SCALED (1 << 1) + +#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1 0x1b +#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2 0x1c + +/** Returns a struct psb_intel_sdvo_pixel_clock_range */ +#define SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE 0x1d +/** Returns a struct psb_intel_sdvo_pixel_clock_range */ +#define SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE 0x1e + +/** Returns a byte bitfield containing SDVO_CLOCK_RATE_MULT_* flags */ +#define SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS 0x1f + +/** Returns a byte containing a SDVO_CLOCK_RATE_MULT_* flag */ +#define SDVO_CMD_GET_CLOCK_RATE_MULT 0x20 +/** Takes a byte containing a SDVO_CLOCK_RATE_MULT_* flag */ +#define SDVO_CMD_SET_CLOCK_RATE_MULT 0x21 +# define SDVO_CLOCK_RATE_MULT_1X (1 << 0) +# define SDVO_CLOCK_RATE_MULT_2X (1 << 1) +# define SDVO_CLOCK_RATE_MULT_4X (1 << 3) + +#define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27 + +#define SDVO_CMD_GET_TV_FORMAT 0x28 + +#define SDVO_CMD_SET_TV_FORMAT 0x29 + +#define SDVO_CMD_GET_SUPPORTED_POWER_STATES 0x2a +#define SDVO_CMD_GET_ENCODER_POWER_STATE 0x2b +#define SDVO_CMD_SET_ENCODER_POWER_STATE 0x2c +# define SDVO_ENCODER_STATE_ON (1 << 0) +# define SDVO_ENCODER_STATE_STANDBY (1 << 1) +# define SDVO_ENCODER_STATE_SUSPEND (1 << 2) +# define SDVO_ENCODER_STATE_OFF (1 << 3) + +#define SDVO_CMD_SET_TV_RESOLUTION_SUPPORT 0x93 + +#define SDVO_CMD_SET_CONTROL_BUS_SWITCH 0x7a +# define SDVO_CONTROL_BUS_PROM 0x0 +# define SDVO_CONTROL_BUS_DDC1 0x1 +# define SDVO_CONTROL_BUS_DDC2 0x2 +# define SDVO_CONTROL_BUS_DDC3 0x3 + +/* SDVO Bus & SDVO Inputs wiring details*/ +/* Bit 0: Is SDVOB connected to In0 (1 = yes, 0 = no*/ +/* Bit 1: Is SDVOB connected to In1 (1 = yes, 0 = no*/ +/* Bit 2: Is SDVOC connected to In0 (1 = yes, 0 = no*/ +/* Bit 3: Is SDVOC connected to In1 (1 = yes, 0 = no*/ +#define SDVOB_IN0 0x01 +#define SDVOB_IN1 0x02 +#define SDVOC_IN0 0x04 +#define SDVOC_IN1 0x08 + +#define SDVO_DEVICE_NONE 0x00 +#define SDVO_DEVICE_CRT 0x01 +#define SDVO_DEVICE_TV 0x02 +#define SDVO_DEVICE_LVDS 0x04 +#define SDVO_DEVICE_TMDS 0x08 + diff --git a/drivers/staging/gma500/psb_irq.c b/drivers/staging/gma500/psb_irq.c new file mode 100644 index 000000000000..3cdcd1e12556 --- /dev/null +++ b/drivers/staging/gma500/psb_irq.c @@ -0,0 +1,637 @@ +/************************************************************************** + * Copyright (c) 2007, Intel Corporation. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + * develop this driver. + * + **************************************************************************/ +/* + */ + +#include +#include "psb_drv.h" +#include "psb_reg.h" +#include "psb_intel_reg.h" +#include "psb_powermgmt.h" + + +/* + * inline functions + */ + +static inline u32 +psb_pipestat(int pipe) +{ + if (pipe == 0) + return PIPEASTAT; + if (pipe == 1) + return PIPEBSTAT; + if (pipe == 2) + return PIPECSTAT; + BUG(); +} + +static inline u32 +mid_pipe_event(int pipe) +{ + if (pipe == 0) + return _PSB_PIPEA_EVENT_FLAG; + if (pipe == 1) + return _MDFLD_PIPEB_EVENT_FLAG; + if (pipe == 2) + return _MDFLD_PIPEC_EVENT_FLAG; + BUG(); +} + +static inline u32 +mid_pipe_vsync(int pipe) +{ + if (pipe == 0) + return _PSB_VSYNC_PIPEA_FLAG; + if (pipe == 1) + return _PSB_VSYNC_PIPEB_FLAG; + if (pipe == 2) + return _MDFLD_PIPEC_VBLANK_FLAG; + BUG(); +} + +static inline u32 +mid_pipeconf(int pipe) +{ + if (pipe == 0) + return PIPEACONF; + if (pipe == 1) + return PIPEBCONF; + if (pipe == 2) + return PIPECCONF; + BUG(); +} + +void +psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) +{ + if ((dev_priv->pipestat[pipe] & mask) != mask) { + u32 reg = psb_pipestat(pipe); + dev_priv->pipestat[pipe] |= mask; + /* Enable the interrupt, clear any pending status */ + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_ONLY_IF_ON)) { + u32 writeVal = PSB_RVDC32(reg); + writeVal |= (mask | (mask >> 16)); + PSB_WVDC32(writeVal, reg); + (void) PSB_RVDC32(reg); + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } + } +} + +void +psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) +{ + if ((dev_priv->pipestat[pipe] & mask) != 0) { + u32 reg = psb_pipestat(pipe); + dev_priv->pipestat[pipe] &= ~mask; + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_ONLY_IF_ON)) { + u32 writeVal = PSB_RVDC32(reg); + writeVal &= ~mask; + PSB_WVDC32(writeVal, reg); + (void) PSB_RVDC32(reg); + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } + } +} + +void mid_enable_pipe_event(struct drm_psb_private *dev_priv, int pipe) +{ + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_ONLY_IF_ON)) { + u32 pipe_event = mid_pipe_event(pipe); + dev_priv->vdc_irq_mask |= pipe_event; + PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); + PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } +} + +void mid_disable_pipe_event(struct drm_psb_private *dev_priv, int pipe) +{ + if (dev_priv->pipestat[pipe] == 0) { + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_ONLY_IF_ON)) { + u32 pipe_event = mid_pipe_event(pipe); + dev_priv->vdc_irq_mask &= ~pipe_event; + PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); + PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } + } +} + +/** + * Display controller interrupt handler for vsync/vblank. + * + */ +static void mid_vblank_handler(struct drm_device *dev, uint32_t pipe) +{ + drm_handle_vblank(dev, pipe); +} + + +/** + * Display controller interrupt handler for pipe event. + * + */ +#define WAIT_STATUS_CLEAR_LOOP_COUNT 0xffff +static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe) +{ + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) dev->dev_private; + + uint32_t pipe_stat_val = 0; + uint32_t pipe_stat_reg = psb_pipestat(pipe); + uint32_t pipe_enable = dev_priv->pipestat[pipe]; + uint32_t pipe_status = dev_priv->pipestat[pipe] >> 16; + uint32_t i = 0; + + spin_lock(&dev_priv->irqmask_lock); + + pipe_stat_val = PSB_RVDC32(pipe_stat_reg); + pipe_stat_val &= pipe_enable | pipe_status; + pipe_stat_val &= pipe_stat_val >> 16; + + spin_unlock(&dev_priv->irqmask_lock); + + /* clear the 2nd level interrupt status bits */ + /** + * FIXME: shouldn't use while loop here. However, the interrupt + * status 'sticky' bits cannot be cleared by setting '1' to that + * bit once... + */ + for (i = 0; i < WAIT_STATUS_CLEAR_LOOP_COUNT; i++) { + PSB_WVDC32(PSB_RVDC32(pipe_stat_reg), pipe_stat_reg); + (void) PSB_RVDC32(pipe_stat_reg); + + if ((PSB_RVDC32(pipe_stat_reg) & pipe_status) == 0) + break; + } + + if (i == WAIT_STATUS_CLEAR_LOOP_COUNT) + DRM_ERROR("%s, can't clear the status bits in pipe_stat_reg, its value = 0x%x.\n", + __func__, PSB_RVDC32(pipe_stat_reg)); + + if (pipe_stat_val & PIPE_VBLANK_STATUS) + mid_vblank_handler(dev, pipe); + + if (pipe_stat_val & PIPE_TE_STATUS) + drm_handle_vblank(dev, pipe); +} + +/* + * Display controller interrupt handler. + */ +static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat) +{ + if (vdc_stat & _PSB_PIPEA_EVENT_FLAG) + mid_pipe_event_handler(dev, 0); +} + +irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) +{ + struct drm_device *dev = (struct drm_device *) arg; + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) dev->dev_private; + + uint32_t vdc_stat, dsp_int = 0, sgx_int = 0; + int handled = 0; + + spin_lock(&dev_priv->irqmask_lock); + + vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R); + + if (vdc_stat & _MDFLD_DISP_ALL_IRQ_FLAG) { + PSB_DEBUG_IRQ("Got DISP interrupt\n"); + dsp_int = 1; + } + + if (vdc_stat & _PSB_IRQ_SGX_FLAG) { + PSB_DEBUG_IRQ("Got SGX interrupt\n"); + sgx_int = 1; + } + if (vdc_stat & _PSB_IRQ_MSVDX_FLAG) + PSB_DEBUG_IRQ("Got MSVDX interrupt\n"); + + if (vdc_stat & _LNC_IRQ_TOPAZ_FLAG) + PSB_DEBUG_IRQ("Got TOPAZ interrupt\n"); + + + vdc_stat &= dev_priv->vdc_irq_mask; + spin_unlock(&dev_priv->irqmask_lock); + + if (dsp_int && ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) { + psb_vdc_interrupt(dev, vdc_stat); + handled = 1; + } + + if (sgx_int) { + /* Not expected - we have it masked, shut it up */ + u32 s, s2; + s = PSB_RSGX32(PSB_CR_EVENT_STATUS); + s2 = PSB_RSGX32(PSB_CR_EVENT_STATUS2); + PSB_WSGX32(s, PSB_CR_EVENT_HOST_CLEAR); + PSB_WSGX32(s2, PSB_CR_EVENT_HOST_CLEAR2); + /* if s & _PSB_CE_TWOD_COMPLETE we have 2D done but + we may as well poll even if we add that ! */ + } + + PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R); + (void) PSB_RVDC32(PSB_INT_IDENTITY_R); + DRM_READMEMORYBARRIER(); + + if (!handled) + return IRQ_NONE; + + return IRQ_HANDLED; +} + +void psb_irq_preinstall(struct drm_device *dev) +{ + psb_irq_preinstall_islands(dev, OSPM_ALL_ISLANDS); +} + +/** + * FIXME: should I remove display irq enable here?? + */ +void psb_irq_preinstall_islands(struct drm_device *dev, int hw_islands) +{ + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) dev->dev_private; + unsigned long irqflags; + + PSB_DEBUG_ENTRY("\n"); + + spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); + + if (hw_islands & OSPM_DISPLAY_ISLAND) { + if (ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) { + PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); + if (dev->vblank_enabled[0]) + dev_priv->vdc_irq_mask |= + _PSB_PIPEA_EVENT_FLAG; + if (dev->vblank_enabled[1]) + dev_priv->vdc_irq_mask |= + _MDFLD_PIPEB_EVENT_FLAG; + if (dev->vblank_enabled[2]) + dev_priv->vdc_irq_mask |= + _MDFLD_PIPEC_EVENT_FLAG; + } + } + if (hw_islands & OSPM_GRAPHICS_ISLAND) + dev_priv->vdc_irq_mask |= _PSB_IRQ_SGX_FLAG; + + /*This register is safe even if display island is off*/ + PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); + + spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); +} + +int psb_irq_postinstall(struct drm_device *dev) +{ + return psb_irq_postinstall_islands(dev, OSPM_ALL_ISLANDS); +} + +int psb_irq_postinstall_islands(struct drm_device *dev, int hw_islands) +{ + + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) dev->dev_private; + unsigned long irqflags; + + PSB_DEBUG_ENTRY("\n"); + + spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); + + /*This register is safe even if display island is off*/ + PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); + + if (hw_islands & OSPM_DISPLAY_ISLAND) { + if (true/*powermgmt_is_hw_on(dev->pdev, PSB_DISPLAY_ISLAND)*/) { + PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); + + if (dev->vblank_enabled[0]) + psb_enable_pipestat(dev_priv, 0, + PIPE_VBLANK_INTERRUPT_ENABLE); + else + psb_disable_pipestat(dev_priv, 0, + PIPE_VBLANK_INTERRUPT_ENABLE); + + if (dev->vblank_enabled[1]) + psb_enable_pipestat(dev_priv, 1, + PIPE_VBLANK_INTERRUPT_ENABLE); + else + psb_disable_pipestat(dev_priv, 1, + PIPE_VBLANK_INTERRUPT_ENABLE); + + if (dev->vblank_enabled[2]) + psb_enable_pipestat(dev_priv, 2, + PIPE_VBLANK_INTERRUPT_ENABLE); + else + psb_disable_pipestat(dev_priv, 2, + PIPE_VBLANK_INTERRUPT_ENABLE); + } + } + + spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); + + return 0; +} + +void psb_irq_uninstall(struct drm_device *dev) +{ + psb_irq_uninstall_islands(dev, OSPM_ALL_ISLANDS); +} + +void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands) +{ + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) dev->dev_private; + unsigned long irqflags; + + PSB_DEBUG_ENTRY("\n"); + + spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); + + if (hw_islands & OSPM_DISPLAY_ISLAND) { + if (true/*powermgmt_is_hw_on(dev->pdev, PSB_DISPLAY_ISLAND)*/) { + PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); + + if (dev->vblank_enabled[0]) + psb_disable_pipestat(dev_priv, 0, + PIPE_VBLANK_INTERRUPT_ENABLE); + + if (dev->vblank_enabled[1]) + psb_disable_pipestat(dev_priv, 1, + PIPE_VBLANK_INTERRUPT_ENABLE); + + if (dev->vblank_enabled[2]) + psb_disable_pipestat(dev_priv, 2, + PIPE_VBLANK_INTERRUPT_ENABLE); + } + dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG | + _PSB_IRQ_MSVDX_FLAG | + _LNC_IRQ_TOPAZ_FLAG; + } + /*TODO: remove following code*/ + if (hw_islands & OSPM_GRAPHICS_ISLAND) + dev_priv->vdc_irq_mask &= ~_PSB_IRQ_SGX_FLAG; + + /*These two registers are safe even if display island is off*/ + PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); + PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); + + wmb(); + + /*This register is safe even if display island is off*/ + PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R); + + spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); +} + +void psb_irq_turn_on_dpst(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) dev->dev_private; + u32 hist_reg; + u32 pwm_reg; + + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_ONLY_IF_ON)) { + PSB_WVDC32(BIT31, HISTOGRAM_LOGIC_CONTROL); + hist_reg = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL); + PSB_WVDC32(BIT31, HISTOGRAM_INT_CONTROL); + hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL); + + PSB_WVDC32(0x80010100, PWM_CONTROL_LOGIC); + pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); + PSB_WVDC32(pwm_reg | PWM_PHASEIN_ENABLE + | PWM_PHASEIN_INT_ENABLE, + PWM_CONTROL_LOGIC); + pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); + + psb_enable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE); + + hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL); + PSB_WVDC32(hist_reg | HISTOGRAM_INT_CTRL_CLEAR, + HISTOGRAM_INT_CONTROL); + pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); + PSB_WVDC32(pwm_reg | 0x80010100 | PWM_PHASEIN_ENABLE, + PWM_CONTROL_LOGIC); + + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } +} + +int psb_irq_enable_dpst(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) dev->dev_private; + unsigned long irqflags; + + PSB_DEBUG_ENTRY("\n"); + + spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); + + /* enable DPST */ + mid_enable_pipe_event(dev_priv, 0); + psb_irq_turn_on_dpst(dev); + + spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); + return 0; +} + +void psb_irq_turn_off_dpst(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) dev->dev_private; + u32 hist_reg; + u32 pwm_reg; + + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_ONLY_IF_ON)) { + PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL); + hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL); + + psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE); + + pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); + PSB_WVDC32(pwm_reg & !(PWM_PHASEIN_INT_ENABLE), + PWM_CONTROL_LOGIC); + pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); + + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } +} + +int psb_irq_disable_dpst(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) dev->dev_private; + unsigned long irqflags; + + PSB_DEBUG_ENTRY("\n"); + + spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); + + mid_disable_pipe_event(dev_priv, 0); + psb_irq_turn_off_dpst(dev); + + spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); + + return 0; +} + +#ifdef PSB_FIXME +static int psb_vblank_do_wait(struct drm_device *dev, + unsigned int *sequence, atomic_t *counter) +{ + unsigned int cur_vblank; + int ret = 0; + DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, + (((cur_vblank = atomic_read(counter)) + - *sequence) <= (1 << 23))); + *sequence = cur_vblank; + + return ret; +} +#endif + +/* + * It is used to enable VBLANK interrupt + */ +int psb_enable_vblank(struct drm_device *dev, int pipe) +{ + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) dev->dev_private; + unsigned long irqflags; + uint32_t reg_val = 0; + uint32_t pipeconf_reg = mid_pipeconf(pipe); + + PSB_DEBUG_ENTRY("\n"); + + if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, + OSPM_UHB_ONLY_IF_ON)) { + reg_val = REG_READ(pipeconf_reg); + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + } + + if (!(reg_val & PIPEACONF_ENABLE)) + return -EINVAL; + + spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); + + drm_psb_disable_vsync = 0; + mid_enable_pipe_event(dev_priv, pipe); + psb_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); + + spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); + + return 0; +} + +/* + * It is used to disable VBLANK interrupt + */ +void psb_disable_vblank(struct drm_device *dev, int pipe) +{ + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) dev->dev_private; + unsigned long irqflags; + + PSB_DEBUG_ENTRY("\n"); + + spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); + + drm_psb_disable_vsync = 1; + mid_disable_pipe_event(dev_priv, pipe); + psb_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); + + spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); +} + +/* Called from drm generic code, passed a 'crtc', which + * we use as a pipe index + */ +u32 psb_get_vblank_counter(struct drm_device *dev, int pipe) +{ + uint32_t high_frame = PIPEAFRAMEHIGH; + uint32_t low_frame = PIPEAFRAMEPIXEL; + uint32_t pipeconf_reg = PIPEACONF; + uint32_t reg_val = 0; + uint32_t high1 = 0, high2 = 0, low = 0, count = 0; + + switch (pipe) { + case 0: + break; + case 1: + high_frame = PIPEBFRAMEHIGH; + low_frame = PIPEBFRAMEPIXEL; + pipeconf_reg = PIPEBCONF; + break; + case 2: + high_frame = PIPECFRAMEHIGH; + low_frame = PIPECFRAMEPIXEL; + pipeconf_reg = PIPECCONF; + break; + default: + DRM_ERROR("%s, invalded pipe.\n", __func__); + return 0; + } + + if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, false)) + return 0; + + reg_val = REG_READ(pipeconf_reg); + + if (!(reg_val & PIPEACONF_ENABLE)) { + DRM_ERROR("trying to get vblank count for disabled pipe %d\n", + pipe); + goto psb_get_vblank_counter_exit; + } + + /* + * High & low register fields aren't synchronized, so make sure + * we get a low value that's stable across two reads of the high + * register. + */ + do { + high1 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> + PIPE_FRAME_HIGH_SHIFT); + low = ((REG_READ(low_frame) & PIPE_FRAME_LOW_MASK) >> + PIPE_FRAME_LOW_SHIFT); + high2 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >> + PIPE_FRAME_HIGH_SHIFT); + } while (high1 != high2); + + count = (high1 << 8) | low; + +psb_get_vblank_counter_exit: + + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); + + return count; +} + diff --git a/drivers/staging/gma500/psb_irq.h b/drivers/staging/gma500/psb_irq.h new file mode 100644 index 000000000000..3e56f33efa6b --- /dev/null +++ b/drivers/staging/gma500/psb_irq.h @@ -0,0 +1,49 @@ +/************************************************************************** + * Copyright (c) 2009, Intel Corporation. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Authors: + * Benjamin Defnet + * Rajesh Poornachandran + * + **************************************************************************/ + +#ifndef _SYSIRQ_H_ +#define _SYSIRQ_H_ + +#include + +bool sysirq_init(struct drm_device *dev); +void sysirq_uninit(struct drm_device *dev); + +void psb_irq_preinstall(struct drm_device *dev); +int psb_irq_postinstall(struct drm_device *dev); +void psb_irq_uninstall(struct drm_device *dev); +irqreturn_t psb_irq_handler(DRM_IRQ_ARGS); + +void psb_irq_preinstall_islands(struct drm_device *dev, int hw_islands); +int psb_irq_postinstall_islands(struct drm_device *dev, int hw_islands); +void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands); + +int psb_irq_enable_dpst(struct drm_device *dev); +int psb_irq_disable_dpst(struct drm_device *dev); +void psb_irq_turn_on_dpst(struct drm_device *dev); +void psb_irq_turn_off_dpst(struct drm_device *dev); +int psb_enable_vblank(struct drm_device *dev, int pipe); +void psb_disable_vblank(struct drm_device *dev, int pipe); +u32 psb_get_vblank_counter(struct drm_device *dev, int pipe); + +#endif //_SYSIRQ_H_ diff --git a/drivers/staging/gma500/psb_mmu.c b/drivers/staging/gma500/psb_mmu.c new file mode 100644 index 000000000000..edd0d4923e0f --- /dev/null +++ b/drivers/staging/gma500/psb_mmu.c @@ -0,0 +1,919 @@ +/************************************************************************** + * Copyright (c) 2007, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + **************************************************************************/ +#include +#include "psb_drv.h" +#include "psb_reg.h" + +/* + * Code for the SGX MMU: + */ + +/* + * clflush on one processor only: + * clflush should apparently flush the cache line on all processors in an + * SMP system. + */ + +/* + * kmap atomic: + * The usage of the slots must be completely encapsulated within a spinlock, and + * no other functions that may be using the locks for other purposed may be + * called from within the locked region. + * Since the slots are per processor, this will guarantee that we are the only + * user. + */ + +/* + * TODO: Inserting ptes from an interrupt handler: + * This may be desirable for some SGX functionality where the GPU can fault in + * needed pages. For that, we need to make an atomic insert_pages function, that + * may fail. + * If it fails, the caller need to insert the page using a workqueue function, + * but on average it should be fast. + */ + +struct psb_mmu_driver { + /* protects driver- and pd structures. Always take in read mode + * before taking the page table spinlock. + */ + struct rw_semaphore sem; + + /* protects page tables, directory tables and pt tables. + * and pt structures. + */ + spinlock_t lock; + + atomic_t needs_tlbflush; + + uint8_t __iomem *register_map; + struct psb_mmu_pd *default_pd; + /*uint32_t bif_ctrl;*/ + int has_clflush; + int clflush_add; + unsigned long clflush_mask; + + struct drm_psb_private *dev_priv; +}; + +struct psb_mmu_pd; + +struct psb_mmu_pt { + struct psb_mmu_pd *pd; + uint32_t index; + uint32_t count; + struct page *p; + uint32_t *v; +}; + +struct psb_mmu_pd { + struct psb_mmu_driver *driver; + int hw_context; + struct psb_mmu_pt **tables; + struct page *p; + struct page *dummy_pt; + struct page *dummy_page; + uint32_t pd_mask; + uint32_t invalid_pde; + uint32_t invalid_pte; +}; + +static inline uint32_t psb_mmu_pt_index(uint32_t offset) +{ + return (offset >> PSB_PTE_SHIFT) & 0x3FF; +} + +static inline uint32_t psb_mmu_pd_index(uint32_t offset) +{ + return offset >> PSB_PDE_SHIFT; +} + +static inline void psb_clflush(void *addr) +{ + __asm__ __volatile__("clflush (%0)\n" : : "r"(addr) : "memory"); +} + +static inline void psb_mmu_clflush(struct psb_mmu_driver *driver, + void *addr) +{ + if (!driver->has_clflush) + return; + + mb(); + psb_clflush(addr); + mb(); +} + +static void psb_page_clflush(struct psb_mmu_driver *driver, struct page* page) +{ + uint32_t clflush_add = driver->clflush_add >> PAGE_SHIFT; + uint32_t clflush_count = PAGE_SIZE / clflush_add; + int i; + uint8_t *clf; + + clf = kmap_atomic(page, KM_USER0); + mb(); + for (i = 0; i < clflush_count; ++i) { + psb_clflush(clf); + clf += clflush_add; + } + mb(); + kunmap_atomic(clf, KM_USER0); +} + +static void psb_pages_clflush(struct psb_mmu_driver *driver, + struct page *page[], unsigned long num_pages) +{ + int i; + + if (!driver->has_clflush) + return ; + + for (i = 0; i < num_pages; i++) + psb_page_clflush(driver, *page++); +} + +static void psb_mmu_flush_pd_locked(struct psb_mmu_driver *driver, + int force) +{ + atomic_set(&driver->needs_tlbflush, 0); +} + +static void psb_mmu_flush_pd(struct psb_mmu_driver *driver, int force) +{ + down_write(&driver->sem); + psb_mmu_flush_pd_locked(driver, force); + up_write(&driver->sem); +} + +void psb_mmu_flush(struct psb_mmu_driver *driver, int rc_prot) +{ + if (rc_prot) + down_write(&driver->sem); + if (rc_prot) + up_write(&driver->sem); +} + +void psb_mmu_set_pd_context(struct psb_mmu_pd *pd, int hw_context) +{ + /*ttm_tt_cache_flush(&pd->p, 1);*/ + psb_pages_clflush(pd->driver, &pd->p, 1); + down_write(&pd->driver->sem); + wmb(); + psb_mmu_flush_pd_locked(pd->driver, 1); + pd->hw_context = hw_context; + up_write(&pd->driver->sem); + +} + +static inline unsigned long psb_pd_addr_end(unsigned long addr, + unsigned long end) +{ + + addr = (addr + PSB_PDE_MASK + 1) & ~PSB_PDE_MASK; + return (addr < end) ? addr : end; +} + +static inline uint32_t psb_mmu_mask_pte(uint32_t pfn, int type) +{ + uint32_t mask = PSB_PTE_VALID; + + if (type & PSB_MMU_CACHED_MEMORY) + mask |= PSB_PTE_CACHED; + if (type & PSB_MMU_RO_MEMORY) + mask |= PSB_PTE_RO; + if (type & PSB_MMU_WO_MEMORY) + mask |= PSB_PTE_WO; + + return (pfn << PAGE_SHIFT) | mask; +} + +struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver, + int trap_pagefaults, int invalid_type) +{ + struct psb_mmu_pd *pd = kmalloc(sizeof(*pd), GFP_KERNEL); + uint32_t *v; + int i; + + if (!pd) + return NULL; + + pd->p = alloc_page(GFP_DMA32); + if (!pd->p) + goto out_err1; + pd->dummy_pt = alloc_page(GFP_DMA32); + if (!pd->dummy_pt) + goto out_err2; + pd->dummy_page = alloc_page(GFP_DMA32); + if (!pd->dummy_page) + goto out_err3; + + if (!trap_pagefaults) { + pd->invalid_pde = + psb_mmu_mask_pte(page_to_pfn(pd->dummy_pt), + invalid_type); + pd->invalid_pte = + psb_mmu_mask_pte(page_to_pfn(pd->dummy_page), + invalid_type); + } else { + pd->invalid_pde = 0; + pd->invalid_pte = 0; + } + + v = kmap(pd->dummy_pt); + for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i) + v[i] = pd->invalid_pte; + + kunmap(pd->dummy_pt); + + v = kmap(pd->p); + for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i) + v[i] = pd->invalid_pde; + + kunmap(pd->p); + + clear_page(kmap(pd->dummy_page)); + kunmap(pd->dummy_page); + + pd->tables = vmalloc_user(sizeof(struct psb_mmu_pt *) * 1024); + if (!pd->tables) + goto out_err4; + + pd->hw_context = -1; + pd->pd_mask = PSB_PTE_VALID; + pd->driver = driver; + + return pd; + +out_err4: + __free_page(pd->dummy_page); +out_err3: + __free_page(pd->dummy_pt); +out_err2: + __free_page(pd->p); +out_err1: + kfree(pd); + return NULL; +} + +void psb_mmu_free_pt(struct psb_mmu_pt *pt) +{ + __free_page(pt->p); + kfree(pt); +} + +void psb_mmu_free_pagedir(struct psb_mmu_pd *pd) +{ + struct psb_mmu_driver *driver = pd->driver; + struct psb_mmu_pt *pt; + int i; + + down_write(&driver->sem); + if (pd->hw_context != -1) + psb_mmu_flush_pd_locked(driver, 1); + + /* Should take the spinlock here, but we don't need to do that + since we have the semaphore in write mode. */ + + for (i = 0; i < 1024; ++i) { + pt = pd->tables[i]; + if (pt) + psb_mmu_free_pt(pt); + } + + vfree(pd->tables); + __free_page(pd->dummy_page); + __free_page(pd->dummy_pt); + __free_page(pd->p); + kfree(pd); + up_write(&driver->sem); +} + +static struct psb_mmu_pt *psb_mmu_alloc_pt(struct psb_mmu_pd *pd) +{ + struct psb_mmu_pt *pt = kmalloc(sizeof(*pt), GFP_KERNEL); + void *v; + uint32_t clflush_add = pd->driver->clflush_add >> PAGE_SHIFT; + uint32_t clflush_count = PAGE_SIZE / clflush_add; + spinlock_t *lock = &pd->driver->lock; + uint8_t *clf; + uint32_t *ptes; + int i; + + if (!pt) + return NULL; + + pt->p = alloc_page(GFP_DMA32); + if (!pt->p) { + kfree(pt); + return NULL; + } + + spin_lock(lock); + + v = kmap_atomic(pt->p, KM_USER0); + clf = (uint8_t *) v; + ptes = (uint32_t *) v; + for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i) + *ptes++ = pd->invalid_pte; + + + if (pd->driver->has_clflush && pd->hw_context != -1) { + mb(); + for (i = 0; i < clflush_count; ++i) { + psb_clflush(clf); + clf += clflush_add; + } + mb(); + } + + kunmap_atomic(v, KM_USER0); + spin_unlock(lock); + + pt->count = 0; + pt->pd = pd; + pt->index = 0; + + return pt; +} + +struct psb_mmu_pt *psb_mmu_pt_alloc_map_lock(struct psb_mmu_pd *pd, + unsigned long addr) +{ + uint32_t index = psb_mmu_pd_index(addr); + struct psb_mmu_pt *pt; + uint32_t *v; + spinlock_t *lock = &pd->driver->lock; + + spin_lock(lock); + pt = pd->tables[index]; + while (!pt) { + spin_unlock(lock); + pt = psb_mmu_alloc_pt(pd); + if (!pt) + return NULL; + spin_lock(lock); + + if (pd->tables[index]) { + spin_unlock(lock); + psb_mmu_free_pt(pt); + spin_lock(lock); + pt = pd->tables[index]; + continue; + } + + v = kmap_atomic(pd->p, KM_USER0); + pd->tables[index] = pt; + v[index] = (page_to_pfn(pt->p) << 12) | pd->pd_mask; + pt->index = index; + kunmap_atomic((void *) v, KM_USER0); + + if (pd->hw_context != -1) { + psb_mmu_clflush(pd->driver, (void *) &v[index]); + atomic_set(&pd->driver->needs_tlbflush, 1); + } + } + pt->v = kmap_atomic(pt->p, KM_USER0); + return pt; +} + +static struct psb_mmu_pt *psb_mmu_pt_map_lock(struct psb_mmu_pd *pd, + unsigned long addr) +{ + uint32_t index = psb_mmu_pd_index(addr); + struct psb_mmu_pt *pt; + spinlock_t *lock = &pd->driver->lock; + + spin_lock(lock); + pt = pd->tables[index]; + if (!pt) { + spin_unlock(lock); + return NULL; + } + pt->v = kmap_atomic(pt->p, KM_USER0); + return pt; +} + +static void psb_mmu_pt_unmap_unlock(struct psb_mmu_pt *pt) +{ + struct psb_mmu_pd *pd = pt->pd; + uint32_t *v; + + kunmap_atomic(pt->v, KM_USER0); + if (pt->count == 0) { + v = kmap_atomic(pd->p, KM_USER0); + v[pt->index] = pd->invalid_pde; + pd->tables[pt->index] = NULL; + + if (pd->hw_context != -1) { + psb_mmu_clflush(pd->driver, + (void *) &v[pt->index]); + atomic_set(&pd->driver->needs_tlbflush, 1); + } + kunmap_atomic(pt->v, KM_USER0); + spin_unlock(&pd->driver->lock); + psb_mmu_free_pt(pt); + return; + } + spin_unlock(&pd->driver->lock); +} + +static inline void psb_mmu_set_pte(struct psb_mmu_pt *pt, + unsigned long addr, uint32_t pte) +{ + pt->v[psb_mmu_pt_index(addr)] = pte; +} + +static inline void psb_mmu_invalidate_pte(struct psb_mmu_pt *pt, + unsigned long addr) +{ + pt->v[psb_mmu_pt_index(addr)] = pt->pd->invalid_pte; +} + +#if 0 +static uint32_t psb_mmu_check_pte_locked(struct psb_mmu_pd *pd, + uint32_t mmu_offset) +{ + uint32_t *v; + uint32_t pfn; + + v = kmap_atomic(pd->p, KM_USER0); + if (!v) { + printk(KERN_INFO "Could not kmap pde page.\n"); + return 0; + } + pfn = v[psb_mmu_pd_index(mmu_offset)]; + /* printk(KERN_INFO "pde is 0x%08x\n",pfn); */ + kunmap_atomic(v, KM_USER0); + if (((pfn & 0x0F) != PSB_PTE_VALID)) { + printk(KERN_INFO "Strange pde at 0x%08x: 0x%08x.\n", + mmu_offset, pfn); + } + v = ioremap(pfn & 0xFFFFF000, 4096); + if (!v) { + printk(KERN_INFO "Could not kmap pte page.\n"); + return 0; + } + pfn = v[psb_mmu_pt_index(mmu_offset)]; + /* printk(KERN_INFO "pte is 0x%08x\n",pfn); */ + iounmap(v); + if (((pfn & 0x0F) != PSB_PTE_VALID)) { + printk(KERN_INFO "Strange pte at 0x%08x: 0x%08x.\n", + mmu_offset, pfn); + } + return pfn >> PAGE_SHIFT; +} + +static void psb_mmu_check_mirrored_gtt(struct psb_mmu_pd *pd, + uint32_t mmu_offset, + uint32_t gtt_pages) +{ + uint32_t start; + uint32_t next; + + printk(KERN_INFO "Checking mirrored gtt 0x%08x %d\n", + mmu_offset, gtt_pages); + down_read(&pd->driver->sem); + start = psb_mmu_check_pte_locked(pd, mmu_offset); + mmu_offset += PAGE_SIZE; + gtt_pages -= 1; + while (gtt_pages--) { + next = psb_mmu_check_pte_locked(pd, mmu_offset); + if (next != start + 1) { + printk(KERN_INFO + "Ptes out of order: 0x%08x, 0x%08x.\n", + start, next); + } + start = next; + mmu_offset += PAGE_SIZE; + } + up_read(&pd->driver->sem); +} + +#endif + +void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd, + uint32_t mmu_offset, uint32_t gtt_start, + uint32_t gtt_pages) +{ + uint32_t *v; + uint32_t start = psb_mmu_pd_index(mmu_offset); + struct psb_mmu_driver *driver = pd->driver; + int num_pages = gtt_pages; + + down_read(&driver->sem); + spin_lock(&driver->lock); + + v = kmap_atomic(pd->p, KM_USER0); + v += start; + + while (gtt_pages--) { + *v++ = gtt_start | pd->pd_mask; + gtt_start += PAGE_SIZE; + } + + /*ttm_tt_cache_flush(&pd->p, num_pages);*/ + psb_pages_clflush(pd->driver, &pd->p, num_pages); + kunmap_atomic(v, KM_USER0); + spin_unlock(&driver->lock); + + if (pd->hw_context != -1) + atomic_set(&pd->driver->needs_tlbflush, 1); + + up_read(&pd->driver->sem); + psb_mmu_flush_pd(pd->driver, 0); +} + +struct psb_mmu_pd *psb_mmu_get_default_pd(struct psb_mmu_driver *driver) +{ + struct psb_mmu_pd *pd; + + /* down_read(&driver->sem); */ + pd = driver->default_pd; + /* up_read(&driver->sem); */ + + return pd; +} + +/* Returns the physical address of the PD shared by sgx/msvdx */ +uint32_t psb_get_default_pd_addr(struct psb_mmu_driver *driver) +{ + struct psb_mmu_pd *pd; + + pd = psb_mmu_get_default_pd(driver); + return page_to_pfn(pd->p) << PAGE_SHIFT; +} + +void psb_mmu_driver_takedown(struct psb_mmu_driver *driver) +{ + psb_mmu_free_pagedir(driver->default_pd); + kfree(driver); +} + +struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers, + int trap_pagefaults, + int invalid_type, + struct drm_psb_private *dev_priv) +{ + struct psb_mmu_driver *driver; + + driver = kmalloc(sizeof(*driver), GFP_KERNEL); + + if (!driver) + return NULL; + driver->dev_priv = dev_priv; + + driver->default_pd = psb_mmu_alloc_pd(driver, trap_pagefaults, + invalid_type); + if (!driver->default_pd) + goto out_err1; + + spin_lock_init(&driver->lock); + init_rwsem(&driver->sem); + down_write(&driver->sem); + driver->register_map = registers; + atomic_set(&driver->needs_tlbflush, 1); + + driver->has_clflush = 0; + + if (boot_cpu_has(X86_FEATURE_CLFLSH)) { + uint32_t tfms, misc, cap0, cap4, clflush_size; + + /* + * clflush size is determined at kernel setup for x86_64 + * but not for i386. We have to do it here. + */ + + cpuid(0x00000001, &tfms, &misc, &cap0, &cap4); + clflush_size = ((misc >> 8) & 0xff) * 8; + driver->has_clflush = 1; + driver->clflush_add = + PAGE_SIZE * clflush_size / sizeof(uint32_t); + driver->clflush_mask = driver->clflush_add - 1; + driver->clflush_mask = ~driver->clflush_mask; + } + + up_write(&driver->sem); + return driver; + +out_err1: + kfree(driver); + return NULL; +} + +static void psb_mmu_flush_ptes(struct psb_mmu_pd *pd, + unsigned long address, uint32_t num_pages, + uint32_t desired_tile_stride, + uint32_t hw_tile_stride) +{ + struct psb_mmu_pt *pt; + uint32_t rows = 1; + uint32_t i; + unsigned long addr; + unsigned long end; + unsigned long next; + unsigned long add; + unsigned long row_add; + unsigned long clflush_add = pd->driver->clflush_add; + unsigned long clflush_mask = pd->driver->clflush_mask; + + if (!pd->driver->has_clflush) { + /*ttm_tt_cache_flush(&pd->p, num_pages);*/ + psb_pages_clflush(pd->driver, &pd->p, num_pages); + return; + } + + if (hw_tile_stride) + rows = num_pages / desired_tile_stride; + else + desired_tile_stride = num_pages; + + add = desired_tile_stride << PAGE_SHIFT; + row_add = hw_tile_stride << PAGE_SHIFT; + mb(); + for (i = 0; i < rows; ++i) { + + addr = address; + end = addr + add; + + do { + next = psb_pd_addr_end(addr, end); + pt = psb_mmu_pt_map_lock(pd, addr); + if (!pt) + continue; + do { + psb_clflush(&pt->v + [psb_mmu_pt_index(addr)]); + } while (addr += + clflush_add, + (addr & clflush_mask) < next); + + psb_mmu_pt_unmap_unlock(pt); + } while (addr = next, next != end); + address += row_add; + } + mb(); +} + +void psb_mmu_remove_pfn_sequence(struct psb_mmu_pd *pd, + unsigned long address, uint32_t num_pages) +{ + struct psb_mmu_pt *pt; + unsigned long addr; + unsigned long end; + unsigned long next; + unsigned long f_address = address; + + down_read(&pd->driver->sem); + + addr = address; + end = addr + (num_pages << PAGE_SHIFT); + + do { + next = psb_pd_addr_end(addr, end); + pt = psb_mmu_pt_alloc_map_lock(pd, addr); + if (!pt) + goto out; + do { + psb_mmu_invalidate_pte(pt, addr); + --pt->count; + } while (addr += PAGE_SIZE, addr < next); + psb_mmu_pt_unmap_unlock(pt); + + } while (addr = next, next != end); + +out: + if (pd->hw_context != -1) + psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1); + + up_read(&pd->driver->sem); + + if (pd->hw_context != -1) + psb_mmu_flush(pd->driver, 0); + + return; +} + +void psb_mmu_remove_pages(struct psb_mmu_pd *pd, unsigned long address, + uint32_t num_pages, uint32_t desired_tile_stride, + uint32_t hw_tile_stride) +{ + struct psb_mmu_pt *pt; + uint32_t rows = 1; + uint32_t i; + unsigned long addr; + unsigned long end; + unsigned long next; + unsigned long add; + unsigned long row_add; + unsigned long f_address = address; + + if (hw_tile_stride) + rows = num_pages / desired_tile_stride; + else + desired_tile_stride = num_pages; + + add = desired_tile_stride << PAGE_SHIFT; + row_add = hw_tile_stride << PAGE_SHIFT; + + /* down_read(&pd->driver->sem); */ + + /* Make sure we only need to flush this processor's cache */ + + for (i = 0; i < rows; ++i) { + + addr = address; + end = addr + add; + + do { + next = psb_pd_addr_end(addr, end); + pt = psb_mmu_pt_map_lock(pd, addr); + if (!pt) + continue; + do { + psb_mmu_invalidate_pte(pt, addr); + --pt->count; + + } while (addr += PAGE_SIZE, addr < next); + psb_mmu_pt_unmap_unlock(pt); + + } while (addr = next, next != end); + address += row_add; + } + if (pd->hw_context != -1) + psb_mmu_flush_ptes(pd, f_address, num_pages, + desired_tile_stride, hw_tile_stride); + + /* up_read(&pd->driver->sem); */ + + if (pd->hw_context != -1) + psb_mmu_flush(pd->driver, 0); +} + +int psb_mmu_insert_pfn_sequence(struct psb_mmu_pd *pd, uint32_t start_pfn, + unsigned long address, uint32_t num_pages, + int type) +{ + struct psb_mmu_pt *pt; + uint32_t pte; + unsigned long addr; + unsigned long end; + unsigned long next; + unsigned long f_address = address; + int ret = 0; + + down_read(&pd->driver->sem); + + addr = address; + end = addr + (num_pages << PAGE_SHIFT); + + do { + next = psb_pd_addr_end(addr, end); + pt = psb_mmu_pt_alloc_map_lock(pd, addr); + if (!pt) { + ret = -ENOMEM; + goto out; + } + do { + pte = psb_mmu_mask_pte(start_pfn++, type); + psb_mmu_set_pte(pt, addr, pte); + pt->count++; + } while (addr += PAGE_SIZE, addr < next); + psb_mmu_pt_unmap_unlock(pt); + + } while (addr = next, next != end); + +out: + if (pd->hw_context != -1) + psb_mmu_flush_ptes(pd, f_address, num_pages, 1, 1); + + up_read(&pd->driver->sem); + + if (pd->hw_context != -1) + psb_mmu_flush(pd->driver, 1); + + return ret; +} + +int psb_mmu_insert_pages(struct psb_mmu_pd *pd, struct page **pages, + unsigned long address, uint32_t num_pages, + uint32_t desired_tile_stride, + uint32_t hw_tile_stride, int type) +{ + struct psb_mmu_pt *pt; + uint32_t rows = 1; + uint32_t i; + uint32_t pte; + unsigned long addr; + unsigned long end; + unsigned long next; + unsigned long add; + unsigned long row_add; + unsigned long f_address = address; + int ret = 0; + + if (hw_tile_stride) { + if (num_pages % desired_tile_stride != 0) + return -EINVAL; + rows = num_pages / desired_tile_stride; + } else { + desired_tile_stride = num_pages; + } + + add = desired_tile_stride << PAGE_SHIFT; + row_add = hw_tile_stride << PAGE_SHIFT; + + down_read(&pd->driver->sem); + + for (i = 0; i < rows; ++i) { + + addr = address; + end = addr + add; + + do { + next = psb_pd_addr_end(addr, end); + pt = psb_mmu_pt_alloc_map_lock(pd, addr); + if (!pt) { + ret = -ENOMEM; + goto out; + } + do { + pte = + psb_mmu_mask_pte(page_to_pfn(*pages++), + type); + psb_mmu_set_pte(pt, addr, pte); + pt->count++; + } while (addr += PAGE_SIZE, addr < next); + psb_mmu_pt_unmap_unlock(pt); + + } while (addr = next, next != end); + + address += row_add; + } +out: + if (pd->hw_context != -1) + psb_mmu_flush_ptes(pd, f_address, num_pages, + desired_tile_stride, hw_tile_stride); + + up_read(&pd->driver->sem); + + if (pd->hw_context != -1) + psb_mmu_flush(pd->driver, 1); + + return ret; +} + +int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual, + unsigned long *pfn) +{ + int ret; + struct psb_mmu_pt *pt; + uint32_t tmp; + spinlock_t *lock = &pd->driver->lock; + + down_read(&pd->driver->sem); + pt = psb_mmu_pt_map_lock(pd, virtual); + if (!pt) { + uint32_t *v; + + spin_lock(lock); + v = kmap_atomic(pd->p, KM_USER0); + tmp = v[psb_mmu_pd_index(virtual)]; + kunmap_atomic(v, KM_USER0); + spin_unlock(lock); + + if (tmp != pd->invalid_pde || !(tmp & PSB_PTE_VALID) || + !(pd->invalid_pte & PSB_PTE_VALID)) { + ret = -EINVAL; + goto out; + } + ret = 0; + *pfn = pd->invalid_pte >> PAGE_SHIFT; + goto out; + } + tmp = pt->v[psb_mmu_pt_index(virtual)]; + if (!(tmp & PSB_PTE_VALID)) { + ret = -EINVAL; + } else { + ret = 0; + *pfn = tmp >> PAGE_SHIFT; + } + psb_mmu_pt_unmap_unlock(pt); +out: + up_read(&pd->driver->sem); + return ret; +} diff --git a/drivers/staging/gma500/psb_powermgmt.c b/drivers/staging/gma500/psb_powermgmt.c new file mode 100644 index 000000000000..3a6ffb7ff11f --- /dev/null +++ b/drivers/staging/gma500/psb_powermgmt.c @@ -0,0 +1,797 @@ +/************************************************************************** + * Copyright (c) 2009, Intel Corporation. + * All Rights Reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Benjamin Defnet + * Rajesh Poornachandran + * + */ +#include "psb_powermgmt.h" +#include "psb_drv.h" +#include "psb_intel_reg.h" +#include +#include + +#undef OSPM_GFX_DPK + +extern u32 gui32SGXDeviceID; +extern u32 gui32MRSTDisplayDeviceID; +extern u32 gui32MRSTMSVDXDeviceID; +extern u32 gui32MRSTTOPAZDeviceID; + +struct drm_device *gpDrmDevice = NULL; +static struct mutex power_mutex; +static bool gbSuspendInProgress = false; +static bool gbResumeInProgress = false; +static int g_hw_power_status_mask; +static atomic_t g_display_access_count; +static atomic_t g_graphics_access_count; +static atomic_t g_videoenc_access_count; +static atomic_t g_videodec_access_count; +int allow_runtime_pm = 0; + +void ospm_power_island_up(int hw_islands); +void ospm_power_island_down(int hw_islands); +static bool gbSuspended = false; +bool gbgfxsuspended = false; + +/* + * ospm_power_init + * + * Description: Initialize this ospm power management module + */ +void ospm_power_init(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = (struct drm_psb_private *)dev->dev_private; + + gpDrmDevice = dev; + + dev_priv->apm_base = dev_priv->apm_reg & 0xffff; + dev_priv->ospm_base &= 0xffff; + + mutex_init(&power_mutex); + g_hw_power_status_mask = OSPM_ALL_ISLANDS; + atomic_set(&g_display_access_count, 0); + atomic_set(&g_graphics_access_count, 0); + atomic_set(&g_videoenc_access_count, 0); + atomic_set(&g_videodec_access_count, 0); +} + +/* + * ospm_power_uninit + * + * Description: Uninitialize this ospm power management module + */ +void ospm_power_uninit(void) +{ + mutex_destroy(&power_mutex); + pm_runtime_disable(&gpDrmDevice->pdev->dev); + pm_runtime_set_suspended(&gpDrmDevice->pdev->dev); +} + + +/* + * save_display_registers + * + * Description: We are going to suspend so save current display + * register state. + */ +static int save_display_registers(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct drm_crtc * crtc; + struct drm_connector * connector; + + /* Display arbitration control + watermarks */ + dev_priv->saveDSPARB = PSB_RVDC32(DSPARB); + dev_priv->saveDSPFW1 = PSB_RVDC32(DSPFW1); + dev_priv->saveDSPFW2 = PSB_RVDC32(DSPFW2); + dev_priv->saveDSPFW3 = PSB_RVDC32(DSPFW3); + dev_priv->saveDSPFW4 = PSB_RVDC32(DSPFW4); + dev_priv->saveDSPFW5 = PSB_RVDC32(DSPFW5); + dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6); + dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT); + + /*save crtc and output state*/ + mutex_lock(&dev->mode_config.mutex); + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + if(drm_helper_crtc_in_use(crtc)) { + crtc->funcs->save(crtc); + } + } + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + connector->funcs->save(connector); + } + mutex_unlock(&dev->mode_config.mutex); + + /* Interrupt state */ + /* + * Handled in psb_irq.c + */ + + return 0; +} + +/* + * restore_display_registers + * + * Description: We are going to resume so restore display register state. + */ +static int restore_display_registers(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct drm_crtc * crtc; + struct drm_connector * connector; + + /* Display arbitration + watermarks */ + PSB_WVDC32(dev_priv->saveDSPARB, DSPARB); + PSB_WVDC32(dev_priv->saveDSPFW1, DSPFW1); + PSB_WVDC32(dev_priv->saveDSPFW2, DSPFW2); + PSB_WVDC32(dev_priv->saveDSPFW3, DSPFW3); + PSB_WVDC32(dev_priv->saveDSPFW4, DSPFW4); + PSB_WVDC32(dev_priv->saveDSPFW5, DSPFW5); + PSB_WVDC32(dev_priv->saveDSPFW6, DSPFW6); + PSB_WVDC32(dev_priv->saveCHICKENBIT, DSPCHICKENBIT); + + /*make sure VGA plane is off. it initializes to on after reset!*/ + PSB_WVDC32(0x80000000, VGACNTRL); + + mutex_lock(&dev->mode_config.mutex); + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + if(drm_helper_crtc_in_use(crtc)) + crtc->funcs->restore(crtc); + } + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + connector->funcs->restore(connector); + } + mutex_unlock(&dev->mode_config.mutex); + + /*Interrupt state*/ + /* + * Handled in psb_irq.c + */ + + return 0; +} +/* + * powermgmt_suspend_display + * + * Description: Suspend the display hardware saving state and disabling + * as necessary. + */ +void ospm_suspend_display(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + int pp_stat, ret=0; + + printk(KERN_ALERT "%s \n", __func__); + +#ifdef OSPM_GFX_DPK + printk(KERN_ALERT "%s \n", __func__); +#endif + if (!(g_hw_power_status_mask & OSPM_DISPLAY_ISLAND)) + return; + + save_display_registers(dev); + + if (dev_priv->iLVDS_enable) { + /*shutdown the panel*/ + PSB_WVDC32(0, PP_CONTROL); + + do { + pp_stat = PSB_RVDC32(PP_STATUS); + } while (pp_stat & 0x80000000); + + /*turn off the plane*/ + PSB_WVDC32(0x58000000, DSPACNTR); + PSB_WVDC32(0, DSPASURF);/*trigger the plane disable*/ + /*wait ~4 ticks*/ + msleep(4); + + /*turn off pipe*/ + PSB_WVDC32(0x0, PIPEACONF); + /*wait ~8 ticks*/ + msleep(8); + + /*turn off PLLs*/ + PSB_WVDC32(0, MRST_DPLL_A); + } else { + PSB_WVDC32(DPI_SHUT_DOWN, DPI_CONTROL_REG); + PSB_WVDC32(0x0, PIPEACONF); + PSB_WVDC32(0x2faf0000, BLC_PWM_CTL); + while (REG_READ(0x70008) & 0x40000000); + while ((PSB_RVDC32(GEN_FIFO_STAT_REG) & DPI_FIFO_EMPTY) + != DPI_FIFO_EMPTY); + PSB_WVDC32(0, DEVICE_READY_REG); + /* turn off panel power */ + ret = 0; + } + ospm_power_island_down(OSPM_DISPLAY_ISLAND); +} + +/* + * ospm_resume_display + * + * Description: Resume the display hardware restoring state and enabling + * as necessary. + */ +void ospm_resume_display(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_gtt *pg = dev_priv->pg; + + printk(KERN_ALERT "%s \n", __func__); + +#ifdef OSPM_GFX_DPK + printk(KERN_ALERT "%s \n", __func__); +#endif + if (g_hw_power_status_mask & OSPM_DISPLAY_ISLAND) + return; + + /* turn on the display power island */ + ospm_power_island_up(OSPM_DISPLAY_ISLAND); + + PSB_WVDC32(pg->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL); + pci_write_config_word(pdev, PSB_GMCH_CTRL, + pg->gmch_ctrl | _PSB_GMCH_ENABLED); + + /* Don't reinitialize the GTT as it is unnecessary. The gtt is + * stored in memory so it will automatically be restored. All + * we need to do is restore the PGETBL_CTL which we already do + * above. + */ + /*psb_gtt_init(dev_priv->pg, 1);*/ + + restore_display_registers(dev); +} + +#if 1 +/* + * ospm_suspend_pci + * + * Description: Suspend the pci device saving state and disabling + * as necessary. + */ +static void ospm_suspend_pci(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + struct drm_psb_private *dev_priv = dev->dev_private; + int bsm, vbt; + + if (gbSuspended) + return; + +#ifdef OSPM_GFX_DPK + printk(KERN_ALERT "ospm_suspend_pci\n"); +#endif + +#ifdef CONFIG_MDFD_GL3 + // Power off GL3 after all GFX sub-systems are powered off. + ospm_power_island_down(OSPM_GL3_CACHE_ISLAND); +#endif + + pci_save_state(pdev); + pci_read_config_dword(pdev, 0x5C, &bsm); + dev_priv->saveBSM = bsm; + pci_read_config_dword(pdev, 0xFC, &vbt); + dev_priv->saveVBT = vbt; + pci_read_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, &dev_priv->msi_addr); + pci_read_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, &dev_priv->msi_data); + + pci_disable_device(pdev); + pci_set_power_state(pdev, PCI_D3hot); + + gbSuspended = true; + gbgfxsuspended = true; +} + +/* + * ospm_resume_pci + * + * Description: Resume the pci device restoring state and enabling + * as necessary. + */ +static bool ospm_resume_pci(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + struct drm_psb_private *dev_priv = dev->dev_private; + int ret = 0; + + if (!gbSuspended) + return true; + +#ifdef OSPM_GFX_DPK + printk(KERN_ALERT "ospm_resume_pci\n"); +#endif + + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + pci_write_config_dword(pdev, 0x5c, dev_priv->saveBSM); + pci_write_config_dword(pdev, 0xFC, dev_priv->saveVBT); + /* retoring MSI address and data in PCIx space */ + pci_write_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, dev_priv->msi_addr); + pci_write_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, dev_priv->msi_data); + ret = pci_enable_device(pdev); + + if (ret != 0) + printk(KERN_ALERT "ospm_resume_pci: pci_enable_device failed: %d\n", ret); + else + gbSuspended = false; + + return !gbSuspended; +} +#endif +/* + * ospm_power_suspend + * + * Description: OSPM is telling our driver to suspend so save state + * and power down all hardware. + */ +int ospm_power_suspend(struct pci_dev *pdev, pm_message_t state) +{ + int ret = 0; + int graphics_access_count; + int videoenc_access_count; + int videodec_access_count; + int display_access_count; + bool suspend_pci = true; + + if(gbSuspendInProgress || gbResumeInProgress) + { +#ifdef OSPM_GFX_DPK + printk(KERN_ALERT "OSPM_GFX_DPK: %s system BUSY \n", __func__); +#endif + return -EBUSY; + } + + mutex_lock(&power_mutex); + + if (!gbSuspended) { + graphics_access_count = atomic_read(&g_graphics_access_count); + videoenc_access_count = atomic_read(&g_videoenc_access_count); + videodec_access_count = atomic_read(&g_videodec_access_count); + display_access_count = atomic_read(&g_display_access_count); + + if (graphics_access_count || + videoenc_access_count || + videodec_access_count || + display_access_count) + ret = -EBUSY; + + if (!ret) { + gbSuspendInProgress = true; + + psb_irq_uninstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); + ospm_suspend_display(gpDrmDevice); + if (suspend_pci == true) { + ospm_suspend_pci(pdev); + } + gbSuspendInProgress = false; + } else { + printk(KERN_ALERT "ospm_power_suspend: device busy: graphics %d videoenc %d videodec %d display %d\n", graphics_access_count, videoenc_access_count, videodec_access_count, display_access_count); + } + } + + + mutex_unlock(&power_mutex); + return ret; +} + +/* + * ospm_power_island_up + * + * Description: Restore power to the specified island(s) (powergating) + */ +void ospm_power_island_up(int hw_islands) +{ + u32 pwr_cnt = 0; + u32 pwr_sts = 0; + u32 pwr_mask = 0; + + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) gpDrmDevice->dev_private; + + + if (hw_islands & OSPM_DISPLAY_ISLAND) { + pwr_mask = PSB_PWRGT_DISPLAY_MASK; + + pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC); + pwr_cnt &= ~pwr_mask; + outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC)); + + while (true) { + pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS); + if ((pwr_sts & pwr_mask) == 0) + break; + else + udelay(10); + } + } + + g_hw_power_status_mask |= hw_islands; +} + +/* + * ospm_power_resume + */ +int ospm_power_resume(struct pci_dev *pdev) +{ + if(gbSuspendInProgress || gbResumeInProgress) + { +#ifdef OSPM_GFX_DPK + printk(KERN_ALERT "OSPM_GFX_DPK: %s hw_island: Suspend || gbResumeInProgress!!!! \n", __func__); +#endif + return 0; + } + + mutex_lock(&power_mutex); + +#ifdef OSPM_GFX_DPK + printk(KERN_ALERT "OSPM_GFX_DPK: ospm_power_resume \n"); +#endif + + gbResumeInProgress = true; + + ospm_resume_pci(pdev); + + ospm_resume_display(gpDrmDevice->pdev); + psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); + psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); + + gbResumeInProgress = false; + + mutex_unlock(&power_mutex); + + return 0; +} + + +/* + * ospm_power_island_down + * + * Description: Cut power to the specified island(s) (powergating) + */ +void ospm_power_island_down(int islands) +{ +#if 0 + u32 pwr_cnt = 0; + u32 pwr_mask = 0; + u32 pwr_sts = 0; + + struct drm_psb_private *dev_priv = + (struct drm_psb_private *) gpDrmDevice->dev_private; + + g_hw_power_status_mask &= ~islands; + + if (islands & OSPM_GRAPHICS_ISLAND) { + pwr_cnt |= PSB_PWRGT_GFX_MASK; + pwr_mask |= PSB_PWRGT_GFX_MASK; + if (dev_priv->graphics_state == PSB_PWR_STATE_ON) { + dev_priv->gfx_on_time += (jiffies - dev_priv->gfx_last_mode_change) * 1000 / HZ; + dev_priv->gfx_last_mode_change = jiffies; + dev_priv->graphics_state = PSB_PWR_STATE_OFF; + dev_priv->gfx_off_cnt++; + } + } + if (islands & OSPM_VIDEO_ENC_ISLAND) { + pwr_cnt |= PSB_PWRGT_VID_ENC_MASK; + pwr_mask |= PSB_PWRGT_VID_ENC_MASK; + } + if (islands & OSPM_VIDEO_DEC_ISLAND) { + pwr_cnt |= PSB_PWRGT_VID_DEC_MASK; + pwr_mask |= PSB_PWRGT_VID_DEC_MASK; + } + if (pwr_cnt) { + pwr_cnt |= inl(dev_priv->apm_base); + outl(pwr_cnt, dev_priv->apm_base + PSB_APM_CMD); + while (true) { + pwr_sts = inl(dev_priv->apm_base + PSB_APM_STS); + + if ((pwr_sts & pwr_mask) == pwr_mask) + break; + else + udelay(10); + } + } + + if (islands & OSPM_DISPLAY_ISLAND) { + pwr_mask = PSB_PWRGT_DISPLAY_MASK; + + outl(pwr_mask, (dev_priv->ospm_base + PSB_PM_SSC)); + + while (true) { + pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS); + if ((pwr_sts & pwr_mask) == pwr_mask) + break; + else + udelay(10); + } + } +#endif +} + + +/* + * ospm_power_is_hw_on + * + * Description: do an instantaneous check for if the specified islands + * are on. Only use this in cases where you know the g_state_change_mutex + * is already held such as in irq install/uninstall. Otherwise, use + * ospm_power_using_hw_begin(). + */ +bool ospm_power_is_hw_on(int hw_islands) +{ + return ((g_hw_power_status_mask & hw_islands) == hw_islands) ? true:false; +} + +/* + * ospm_power_using_hw_begin + * + * Description: Notify PowerMgmt module that you will be accessing the + * specified island's hw so don't power it off. If force_on is true, + * this will power on the specified island if it is off. + * Otherwise, this will return false and the caller is expected to not + * access the hw. + * + * NOTE *** If this is called from and interrupt handler or other atomic + * context, then it will return false if we are in the middle of a + * power state transition and the caller will be expected to handle that + * even if force_on is set to true. + */ +bool ospm_power_using_hw_begin(int hw_island, UHBUsage usage) +{ + return 1; /*FIXMEAC */ +#if 0 + bool ret = true; + bool island_is_off = false; + bool b_atomic = (in_interrupt() || in_atomic()); + bool locked = true; + struct pci_dev *pdev = gpDrmDevice->pdev; + u32 deviceID = 0; + bool force_on = usage ? true: false; + /*quick path, not 100% race safe, but should be enough comapre to current other code in this file */ + if (!force_on) { + if (hw_island & (OSPM_ALL_ISLANDS & ~g_hw_power_status_mask)) + return false; + else { + locked = false; +#ifdef CONFIG_PM_RUNTIME + /* increment pm_runtime_refcount */ + pm_runtime_get(&pdev->dev); +#endif + goto increase_count; + } + } + + + if (!b_atomic) + mutex_lock(&power_mutex); + + island_is_off = hw_island & (OSPM_ALL_ISLANDS & ~g_hw_power_status_mask); + + if (b_atomic && (gbSuspendInProgress || gbResumeInProgress || gbSuspended) && force_on && island_is_off) + ret = false; + + if (ret && island_is_off && !force_on) + ret = false; + + if (ret && island_is_off && force_on) { + gbResumeInProgress = true; + + ret = ospm_resume_pci(pdev); + + if (ret) { + switch(hw_island) + { + case OSPM_DISPLAY_ISLAND: + deviceID = gui32MRSTDisplayDeviceID; + ospm_resume_display(pdev); + psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); + psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); + break; + case OSPM_GRAPHICS_ISLAND: + deviceID = gui32SGXDeviceID; + ospm_power_island_up(OSPM_GRAPHICS_ISLAND); + psb_irq_preinstall_islands(gpDrmDevice, OSPM_GRAPHICS_ISLAND); + psb_irq_postinstall_islands(gpDrmDevice, OSPM_GRAPHICS_ISLAND); + break; +#if 1 + case OSPM_VIDEO_DEC_ISLAND: + if(!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) { + //printk(KERN_ALERT "%s power on display for video decode use\n", __func__); + deviceID = gui32MRSTDisplayDeviceID; + ospm_resume_display(pdev); + psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); + psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); + } + else{ + //printk(KERN_ALERT "%s display is already on for video decode use\n", __func__); + } + + if(!ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND)) { + //printk(KERN_ALERT "%s power on video decode\n", __func__); + deviceID = gui32MRSTMSVDXDeviceID; + ospm_power_island_up(OSPM_VIDEO_DEC_ISLAND); + psb_irq_preinstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND); + psb_irq_postinstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND); + } + else{ + //printk(KERN_ALERT "%s video decode is already on\n", __func__); + } + + break; + case OSPM_VIDEO_ENC_ISLAND: + if(!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) { + //printk(KERN_ALERT "%s power on display for video encode\n", __func__); + deviceID = gui32MRSTDisplayDeviceID; + ospm_resume_display(pdev); + psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); + psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND); + } + else{ + //printk(KERN_ALERT "%s display is already on for video encode use\n", __func__); + } + + if(!ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND)) { + //printk(KERN_ALERT "%s power on video encode\n", __func__); + deviceID = gui32MRSTTOPAZDeviceID; + ospm_power_island_up(OSPM_VIDEO_ENC_ISLAND); + psb_irq_preinstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND); + psb_irq_postinstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND); + } + else{ + //printk(KERN_ALERT "%s video decode is already on\n", __func__); + } +#endif + break; + + default: + printk(KERN_ALERT "%s unknown island !!!! \n", __func__); + break; + } + + } + + if (!ret) + printk(KERN_ALERT "ospm_power_using_hw_begin: forcing on %d failed\n", hw_island); + + gbResumeInProgress = false; + } +increase_count: + if (ret) { + switch(hw_island) + { + case OSPM_GRAPHICS_ISLAND: + atomic_inc(&g_graphics_access_count); + break; + case OSPM_VIDEO_ENC_ISLAND: + atomic_inc(&g_videoenc_access_count); + break; + case OSPM_VIDEO_DEC_ISLAND: + atomic_inc(&g_videodec_access_count); + break; + case OSPM_DISPLAY_ISLAND: + atomic_inc(&g_display_access_count); + break; + } + } + + if (!b_atomic && locked) + mutex_unlock(&power_mutex); + + return ret; +#endif +} + + +/* + * ospm_power_using_hw_end + * + * Description: Notify PowerMgmt module that you are done accessing the + * specified island's hw so feel free to power it off. Note that this + * function doesn't actually power off the islands. + */ +void ospm_power_using_hw_end(int hw_island) +{ +#if 0 /* FIXMEAC */ + switch(hw_island) + { + case OSPM_GRAPHICS_ISLAND: + atomic_dec(&g_graphics_access_count); + break; + case OSPM_VIDEO_ENC_ISLAND: + atomic_dec(&g_videoenc_access_count); + break; + case OSPM_VIDEO_DEC_ISLAND: + atomic_dec(&g_videodec_access_count); + break; + case OSPM_DISPLAY_ISLAND: + atomic_dec(&g_display_access_count); + break; + } + + //decrement runtime pm ref count + pm_runtime_put(&gpDrmDevice->pdev->dev); + + WARN_ON(atomic_read(&g_graphics_access_count) < 0); + WARN_ON(atomic_read(&g_videoenc_access_count) < 0); + WARN_ON(atomic_read(&g_videodec_access_count) < 0); + WARN_ON(atomic_read(&g_display_access_count) < 0); +#endif +} + +int ospm_runtime_pm_allow(struct drm_device * dev) +{ + return 0; +} + +void ospm_runtime_pm_forbid(struct drm_device * dev) +{ + struct drm_psb_private * dev_priv = dev->dev_private; + + DRM_INFO("%s\n", __FUNCTION__); + + pm_runtime_forbid(&dev->pdev->dev); + dev_priv->rpm_enabled = 0; +} + +int psb_runtime_suspend(struct device *dev) +{ + pm_message_t state; + int ret = 0; + state.event = 0; + +#ifdef OSPM_GFX_DPK + printk(KERN_ALERT "OSPM_GFX_DPK: %s \n", __func__); +#endif + if (atomic_read(&g_graphics_access_count) || atomic_read(&g_videoenc_access_count) + || atomic_read(&g_videodec_access_count) || atomic_read(&g_display_access_count)){ +#ifdef OSPM_GFX_DPK + printk(KERN_ALERT "OSPM_GFX_DPK: GFX: %d VEC: %d VED: %d DC: %d DSR: %d \n", atomic_read(&g_graphics_access_count), + atomic_read(&g_videoenc_access_count), atomic_read(&g_videodec_access_count), atomic_read(&g_display_access_count)); +#endif + return -EBUSY; + } + else + ret = ospm_power_suspend(gpDrmDevice->pdev, state); + + return ret; +} + +int psb_runtime_resume(struct device *dev) +{ + return 0; +} + +int psb_runtime_idle(struct device *dev) +{ + /*printk (KERN_ALERT "lvds:%d,mipi:%d\n", dev_priv->is_lvds_on, dev_priv->is_mipi_on);*/ + if (atomic_read(&g_graphics_access_count) || atomic_read(&g_videoenc_access_count) + || atomic_read(&g_videodec_access_count) || atomic_read(&g_display_access_count)) + return 1; + else + return 0; +} + diff --git a/drivers/staging/gma500/psb_powermgmt.h b/drivers/staging/gma500/psb_powermgmt.h new file mode 100644 index 000000000000..bf6f27af03a8 --- /dev/null +++ b/drivers/staging/gma500/psb_powermgmt.h @@ -0,0 +1,96 @@ +/************************************************************************** + * Copyright (c) 2009, Intel Corporation. + * All Rights Reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Benjamin Defnet + * Rajesh Poornachandran + * + */ +#ifndef _PSB_POWERMGMT_H_ +#define _PSB_POWERMGMT_H_ + +#include +#include + +#define OSPM_GRAPHICS_ISLAND 0x1 +#define OSPM_VIDEO_ENC_ISLAND 0x2 +#define OSPM_VIDEO_DEC_ISLAND 0x4 +#define OSPM_DISPLAY_ISLAND 0x8 +#define OSPM_GL3_CACHE_ISLAND 0x10 +#define OSPM_ALL_ISLANDS 0x1f + +/* IPC message and command defines used to enable/disable mipi panel voltages */ +#define IPC_MSG_PANEL_ON_OFF 0xE9 +#define IPC_CMD_PANEL_ON 1 +#define IPC_CMD_PANEL_OFF 0 + +typedef enum _UHBUsage +{ + OSPM_UHB_ONLY_IF_ON = 0, + OSPM_UHB_FORCE_POWER_ON, +} UHBUsage; + +/* Use these functions to power down video HW for D0i3 purpose */ + +void ospm_power_init(struct drm_device *dev); +void ospm_power_uninit(void); + + +/* + * OSPM will call these functions + */ +int ospm_power_suspend(struct pci_dev *pdev, pm_message_t state); +int ospm_power_resume(struct pci_dev *pdev); + +/* + * These are the functions the driver should use to wrap all hw access + * (i.e. register reads and writes) + */ +bool ospm_power_using_hw_begin(int hw_island, UHBUsage usage); +void ospm_power_using_hw_end(int hw_island); + +/* + * Use this function to do an instantaneous check for if the hw is on. + * Only use this in cases where you know the g_state_change_mutex + * is already held such as in irq install/uninstall and you need to + * prevent a deadlock situation. Otherwise use ospm_power_using_hw_begin(). + */ +bool ospm_power_is_hw_on(int hw_islands); + +/* + * Power up/down different hw component rails/islands + */ +void ospm_power_island_down(int hw_islands); +void ospm_power_island_up(int hw_islands); +void ospm_suspend_graphics(void); +/* + * GFX-Runtime PM callbacks + */ +int psb_runtime_suspend(struct device *dev); +int psb_runtime_resume(struct device *dev); +int psb_runtime_idle(struct device *dev); +int ospm_runtime_pm_allow(struct drm_device * dev); +void ospm_runtime_pm_forbid(struct drm_device * dev); + + +#endif /*_PSB_POWERMGMT_H_*/ diff --git a/drivers/staging/gma500/psb_pvr_glue.c b/drivers/staging/gma500/psb_pvr_glue.c new file mode 100644 index 000000000000..da78946b57ad --- /dev/null +++ b/drivers/staging/gma500/psb_pvr_glue.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2009, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "psb_pvr_glue.h" + +/** + * FIXME: should NOT use these file under env/linux directly + */ + +int psb_get_meminfo_by_handle(void *hKernelMemInfo, + void **ppsKernelMemInfo) +{ + return -EINVAL; +#if 0 + void *psKernelMemInfo = IMG_NULL; + PVRSRV_PER_PROCESS_DATA *psPerProc = IMG_NULL; + PVRSRV_ERROR eError; + + psPerProc = PVRSRVPerProcessData(task_tgid_nr(current)); + eError = PVRSRVLookupHandle(psPerProc->psHandleBase, + (IMG_VOID *)&psKernelMemInfo, + hKernelMemInfo, + PVRSRV_HANDLE_TYPE_MEM_INFO); + if (eError != PVRSRV_OK) { + DRM_ERROR("Cannot find kernel meminfo for handle 0x%x\n", + (u32)hKernelMemInfo); + return -EINVAL; + } + + *ppsKernelMemInfo = psKernelMemInfo; + + DRM_DEBUG("Got Kernel MemInfo for handle %lx\n", + (u32)hKernelMemInfo); + return 0; +#endif +} + +int psb_get_pages_by_mem_handle(void *hOSMemHandle, struct page ***pages) +{ + return -EINVAL; +#if 0 + LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle; + struct page **page_list; + if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_ALLOC_PAGES) { + DRM_ERROR("MemArea type is not LINUX_MEM_AREA_ALLOC_PAGES\n"); + return -EINVAL; + } + + page_list = psLinuxMemArea->uData.sPageList.pvPageList; + if (!page_list) { + DRM_DEBUG("Page List is NULL\n"); + return -ENOMEM; + } + + *pages = page_list; + return 0; +#endif +} diff --git a/drivers/staging/gma500/psb_pvr_glue.h b/drivers/staging/gma500/psb_pvr_glue.h new file mode 100644 index 000000000000..63dd0946401f --- /dev/null +++ b/drivers/staging/gma500/psb_pvr_glue.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2009, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "psb_drv.h" + +extern int psb_get_meminfo_by_handle(void * hKernelMemInfo, + void **ppsKernelMemInfo); +extern u32 psb_get_tgid(void); +extern int psb_get_pages_by_mem_handle(void * hOSMemHandle, + struct page ***pages); diff --git a/drivers/staging/gma500/psb_reg.h b/drivers/staging/gma500/psb_reg.h new file mode 100644 index 000000000000..d80b4f3833c8 --- /dev/null +++ b/drivers/staging/gma500/psb_reg.h @@ -0,0 +1,588 @@ +/************************************************************************** + * + * Copyright (c) (2005-2007) Imagination Technologies Limited. + * Copyright (c) 2007, Intel Corporation. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.. + * + **************************************************************************/ + +#ifndef _PSB_REG_H_ +#define _PSB_REG_H_ + +#define PSB_CR_CLKGATECTL 0x0000 +#define _PSB_C_CLKGATECTL_AUTO_MAN_REG (1 << 24) +#define _PSB_C_CLKGATECTL_USE_CLKG_SHIFT (20) +#define _PSB_C_CLKGATECTL_USE_CLKG_MASK (0x3 << 20) +#define _PSB_C_CLKGATECTL_DPM_CLKG_SHIFT (16) +#define _PSB_C_CLKGATECTL_DPM_CLKG_MASK (0x3 << 16) +#define _PSB_C_CLKGATECTL_TA_CLKG_SHIFT (12) +#define _PSB_C_CLKGATECTL_TA_CLKG_MASK (0x3 << 12) +#define _PSB_C_CLKGATECTL_TSP_CLKG_SHIFT (8) +#define _PSB_C_CLKGATECTL_TSP_CLKG_MASK (0x3 << 8) +#define _PSB_C_CLKGATECTL_ISP_CLKG_SHIFT (4) +#define _PSB_C_CLKGATECTL_ISP_CLKG_MASK (0x3 << 4) +#define _PSB_C_CLKGATECTL_2D_CLKG_SHIFT (0) +#define _PSB_C_CLKGATECTL_2D_CLKG_MASK (0x3 << 0) +#define _PSB_C_CLKGATECTL_CLKG_ENABLED (0) +#define _PSB_C_CLKGATECTL_CLKG_DISABLED (1) +#define _PSB_C_CLKGATECTL_CLKG_AUTO (2) + +#define PSB_CR_CORE_ID 0x0010 +#define _PSB_CC_ID_ID_SHIFT (16) +#define _PSB_CC_ID_ID_MASK (0xFFFF << 16) +#define _PSB_CC_ID_CONFIG_SHIFT (0) +#define _PSB_CC_ID_CONFIG_MASK (0xFFFF << 0) + +#define PSB_CR_CORE_REVISION 0x0014 +#define _PSB_CC_REVISION_DESIGNER_SHIFT (24) +#define _PSB_CC_REVISION_DESIGNER_MASK (0xFF << 24) +#define _PSB_CC_REVISION_MAJOR_SHIFT (16) +#define _PSB_CC_REVISION_MAJOR_MASK (0xFF << 16) +#define _PSB_CC_REVISION_MINOR_SHIFT (8) +#define _PSB_CC_REVISION_MINOR_MASK (0xFF << 8) +#define _PSB_CC_REVISION_MAINTENANCE_SHIFT (0) +#define _PSB_CC_REVISION_MAINTENANCE_MASK (0xFF << 0) + +#define PSB_CR_DESIGNER_REV_FIELD1 0x0018 + +#define PSB_CR_SOFT_RESET 0x0080 +#define _PSB_CS_RESET_TSP_RESET (1 << 6) +#define _PSB_CS_RESET_ISP_RESET (1 << 5) +#define _PSB_CS_RESET_USE_RESET (1 << 4) +#define _PSB_CS_RESET_TA_RESET (1 << 3) +#define _PSB_CS_RESET_DPM_RESET (1 << 2) +#define _PSB_CS_RESET_TWOD_RESET (1 << 1) +#define _PSB_CS_RESET_BIF_RESET (1 << 0) + +#define PSB_CR_DESIGNER_REV_FIELD2 0x001C + +#define PSB_CR_EVENT_HOST_ENABLE2 0x0110 + +#define PSB_CR_EVENT_STATUS2 0x0118 + +#define PSB_CR_EVENT_HOST_CLEAR2 0x0114 +#define _PSB_CE2_BIF_REQUESTER_FAULT (1 << 4) + +#define PSB_CR_EVENT_STATUS 0x012C + +#define PSB_CR_EVENT_HOST_ENABLE 0x0130 + +#define PSB_CR_EVENT_HOST_CLEAR 0x0134 +#define _PSB_CE_MASTER_INTERRUPT (1 << 31) +#define _PSB_CE_TA_DPM_FAULT (1 << 28) +#define _PSB_CE_TWOD_COMPLETE (1 << 27) +#define _PSB_CE_DPM_OUT_OF_MEMORY_ZLS (1 << 25) +#define _PSB_CE_DPM_TA_MEM_FREE (1 << 24) +#define _PSB_CE_PIXELBE_END_RENDER (1 << 18) +#define _PSB_CE_SW_EVENT (1 << 14) +#define _PSB_CE_TA_FINISHED (1 << 13) +#define _PSB_CE_TA_TERMINATE (1 << 12) +#define _PSB_CE_DPM_REACHED_MEM_THRESH (1 << 3) +#define _PSB_CE_DPM_OUT_OF_MEMORY_GBL (1 << 2) +#define _PSB_CE_DPM_OUT_OF_MEMORY_MT (1 << 1) +#define _PSB_CE_DPM_3D_MEM_FREE (1 << 0) + + +#define PSB_USE_OFFSET_MASK 0x0007FFFF +#define PSB_USE_OFFSET_SIZE (PSB_USE_OFFSET_MASK + 1) +#define PSB_CR_USE_CODE_BASE0 0x0A0C +#define PSB_CR_USE_CODE_BASE1 0x0A10 +#define PSB_CR_USE_CODE_BASE2 0x0A14 +#define PSB_CR_USE_CODE_BASE3 0x0A18 +#define PSB_CR_USE_CODE_BASE4 0x0A1C +#define PSB_CR_USE_CODE_BASE5 0x0A20 +#define PSB_CR_USE_CODE_BASE6 0x0A24 +#define PSB_CR_USE_CODE_BASE7 0x0A28 +#define PSB_CR_USE_CODE_BASE8 0x0A2C +#define PSB_CR_USE_CODE_BASE9 0x0A30 +#define PSB_CR_USE_CODE_BASE10 0x0A34 +#define PSB_CR_USE_CODE_BASE11 0x0A38 +#define PSB_CR_USE_CODE_BASE12 0x0A3C +#define PSB_CR_USE_CODE_BASE13 0x0A40 +#define PSB_CR_USE_CODE_BASE14 0x0A44 +#define PSB_CR_USE_CODE_BASE15 0x0A48 +#define PSB_CR_USE_CODE_BASE(_i) (0x0A0C + ((_i) << 2)) +#define _PSB_CUC_BASE_DM_SHIFT (25) +#define _PSB_CUC_BASE_DM_MASK (0x3 << 25) +#define _PSB_CUC_BASE_ADDR_SHIFT (0) /* 1024-bit aligned address? */ +#define _PSB_CUC_BASE_ADDR_ALIGNSHIFT (7) +#define _PSB_CUC_BASE_ADDR_MASK (0x1FFFFFF << 0) +#define _PSB_CUC_DM_VERTEX (0) +#define _PSB_CUC_DM_PIXEL (1) +#define _PSB_CUC_DM_RESERVED (2) +#define _PSB_CUC_DM_EDM (3) + +#define PSB_CR_PDS_EXEC_BASE 0x0AB8 +#define _PSB_CR_PDS_EXEC_BASE_ADDR_SHIFT (20) /* 1MB aligned address */ +#define _PSB_CR_PDS_EXEC_BASE_ADDR_ALIGNSHIFT (20) + +#define PSB_CR_EVENT_KICKER 0x0AC4 +#define _PSB_CE_KICKER_ADDRESS_SHIFT (4) /* 128-bit aligned address */ + +#define PSB_CR_EVENT_KICK 0x0AC8 +#define _PSB_CE_KICK_NOW (1 << 0) + + +#define PSB_CR_BIF_DIR_LIST_BASE1 0x0C38 + +#define PSB_CR_BIF_CTRL 0x0C00 +#define _PSB_CB_CTRL_CLEAR_FAULT (1 << 4) +#define _PSB_CB_CTRL_INVALDC (1 << 3) +#define _PSB_CB_CTRL_FLUSH (1 << 2) + +#define PSB_CR_BIF_INT_STAT 0x0C04 + +#define PSB_CR_BIF_FAULT 0x0C08 +#define _PSB_CBI_STAT_PF_N_RW (1 << 14) +#define _PSB_CBI_STAT_FAULT_SHIFT (0) +#define _PSB_CBI_STAT_FAULT_MASK (0x3FFF << 0) +#define _PSB_CBI_STAT_FAULT_CACHE (1 << 1) +#define _PSB_CBI_STAT_FAULT_TA (1 << 2) +#define _PSB_CBI_STAT_FAULT_VDM (1 << 3) +#define _PSB_CBI_STAT_FAULT_2D (1 << 4) +#define _PSB_CBI_STAT_FAULT_PBE (1 << 5) +#define _PSB_CBI_STAT_FAULT_TSP (1 << 6) +#define _PSB_CBI_STAT_FAULT_ISP (1 << 7) +#define _PSB_CBI_STAT_FAULT_USSEPDS (1 << 8) +#define _PSB_CBI_STAT_FAULT_HOST (1 << 9) + +#define PSB_CR_BIF_BANK0 0x0C78 + +#define PSB_CR_BIF_BANK1 0x0C7C + +#define PSB_CR_BIF_DIR_LIST_BASE0 0x0C84 + +#define PSB_CR_BIF_TWOD_REQ_BASE 0x0C88 +#define PSB_CR_BIF_3D_REQ_BASE 0x0CAC + +#define PSB_CR_2D_SOCIF 0x0E18 +#define _PSB_C2_SOCIF_FREESPACE_SHIFT (0) +#define _PSB_C2_SOCIF_FREESPACE_MASK (0xFF << 0) +#define _PSB_C2_SOCIF_EMPTY (0x80 << 0) + +#define PSB_CR_2D_BLIT_STATUS 0x0E04 +#define _PSB_C2B_STATUS_BUSY (1 << 24) +#define _PSB_C2B_STATUS_COMPLETE_SHIFT (0) +#define _PSB_C2B_STATUS_COMPLETE_MASK (0xFFFFFF << 0) + +/* + * 2D defs. + */ + +/* + * 2D Slave Port Data : Block Header's Object Type + */ + +#define PSB_2D_CLIP_BH (0x00000000) +#define PSB_2D_PAT_BH (0x10000000) +#define PSB_2D_CTRL_BH (0x20000000) +#define PSB_2D_SRC_OFF_BH (0x30000000) +#define PSB_2D_MASK_OFF_BH (0x40000000) +#define PSB_2D_RESERVED1_BH (0x50000000) +#define PSB_2D_RESERVED2_BH (0x60000000) +#define PSB_2D_FENCE_BH (0x70000000) +#define PSB_2D_BLIT_BH (0x80000000) +#define PSB_2D_SRC_SURF_BH (0x90000000) +#define PSB_2D_DST_SURF_BH (0xA0000000) +#define PSB_2D_PAT_SURF_BH (0xB0000000) +#define PSB_2D_SRC_PAL_BH (0xC0000000) +#define PSB_2D_PAT_PAL_BH (0xD0000000) +#define PSB_2D_MASK_SURF_BH (0xE0000000) +#define PSB_2D_FLUSH_BH (0xF0000000) + +/* + * Clip Definition block (PSB_2D_CLIP_BH) + */ +#define PSB_2D_CLIPCOUNT_MAX (1) +#define PSB_2D_CLIPCOUNT_MASK (0x00000000) +#define PSB_2D_CLIPCOUNT_CLRMASK (0xFFFFFFFF) +#define PSB_2D_CLIPCOUNT_SHIFT (0) +/* clip rectangle min & max */ +#define PSB_2D_CLIP_XMAX_MASK (0x00FFF000) +#define PSB_2D_CLIP_XMAX_CLRMASK (0xFF000FFF) +#define PSB_2D_CLIP_XMAX_SHIFT (12) +#define PSB_2D_CLIP_XMIN_MASK (0x00000FFF) +#define PSB_2D_CLIP_XMIN_CLRMASK (0x00FFF000) +#define PSB_2D_CLIP_XMIN_SHIFT (0) +/* clip rectangle offset */ +#define PSB_2D_CLIP_YMAX_MASK (0x00FFF000) +#define PSB_2D_CLIP_YMAX_CLRMASK (0xFF000FFF) +#define PSB_2D_CLIP_YMAX_SHIFT (12) +#define PSB_2D_CLIP_YMIN_MASK (0x00000FFF) +#define PSB_2D_CLIP_YMIN_CLRMASK (0x00FFF000) +#define PSB_2D_CLIP_YMIN_SHIFT (0) + +/* + * Pattern Control (PSB_2D_PAT_BH) + */ +#define PSB_2D_PAT_HEIGHT_MASK (0x0000001F) +#define PSB_2D_PAT_HEIGHT_SHIFT (0) +#define PSB_2D_PAT_WIDTH_MASK (0x000003E0) +#define PSB_2D_PAT_WIDTH_SHIFT (5) +#define PSB_2D_PAT_YSTART_MASK (0x00007C00) +#define PSB_2D_PAT_YSTART_SHIFT (10) +#define PSB_2D_PAT_XSTART_MASK (0x000F8000) +#define PSB_2D_PAT_XSTART_SHIFT (15) + +/* + * 2D Control block (PSB_2D_CTRL_BH) + */ +/* Present Flags */ +#define PSB_2D_SRCCK_CTRL (0x00000001) +#define PSB_2D_DSTCK_CTRL (0x00000002) +#define PSB_2D_ALPHA_CTRL (0x00000004) +/* Colour Key Colour (SRC/DST)*/ +#define PSB_2D_CK_COL_MASK (0xFFFFFFFF) +#define PSB_2D_CK_COL_CLRMASK (0x00000000) +#define PSB_2D_CK_COL_SHIFT (0) +/* Colour Key Mask (SRC/DST)*/ +#define PSB_2D_CK_MASK_MASK (0xFFFFFFFF) +#define PSB_2D_CK_MASK_CLRMASK (0x00000000) +#define PSB_2D_CK_MASK_SHIFT (0) +/* Alpha Control (Alpha/RGB)*/ +#define PSB_2D_GBLALPHA_MASK (0x000FF000) +#define PSB_2D_GBLALPHA_CLRMASK (0xFFF00FFF) +#define PSB_2D_GBLALPHA_SHIFT (12) +#define PSB_2D_SRCALPHA_OP_MASK (0x00700000) +#define PSB_2D_SRCALPHA_OP_CLRMASK (0xFF8FFFFF) +#define PSB_2D_SRCALPHA_OP_SHIFT (20) +#define PSB_2D_SRCALPHA_OP_ONE (0x00000000) +#define PSB_2D_SRCALPHA_OP_SRC (0x00100000) +#define PSB_2D_SRCALPHA_OP_DST (0x00200000) +#define PSB_2D_SRCALPHA_OP_SG (0x00300000) +#define PSB_2D_SRCALPHA_OP_DG (0x00400000) +#define PSB_2D_SRCALPHA_OP_GBL (0x00500000) +#define PSB_2D_SRCALPHA_OP_ZERO (0x00600000) +#define PSB_2D_SRCALPHA_INVERT (0x00800000) +#define PSB_2D_SRCALPHA_INVERT_CLR (0xFF7FFFFF) +#define PSB_2D_DSTALPHA_OP_MASK (0x07000000) +#define PSB_2D_DSTALPHA_OP_CLRMASK (0xF8FFFFFF) +#define PSB_2D_DSTALPHA_OP_SHIFT (24) +#define PSB_2D_DSTALPHA_OP_ONE (0x00000000) +#define PSB_2D_DSTALPHA_OP_SRC (0x01000000) +#define PSB_2D_DSTALPHA_OP_DST (0x02000000) +#define PSB_2D_DSTALPHA_OP_SG (0x03000000) +#define PSB_2D_DSTALPHA_OP_DG (0x04000000) +#define PSB_2D_DSTALPHA_OP_GBL (0x05000000) +#define PSB_2D_DSTALPHA_OP_ZERO (0x06000000) +#define PSB_2D_DSTALPHA_INVERT (0x08000000) +#define PSB_2D_DSTALPHA_INVERT_CLR (0xF7FFFFFF) + +#define PSB_2D_PRE_MULTIPLICATION_ENABLE (0x10000000) +#define PSB_2D_PRE_MULTIPLICATION_CLRMASK (0xEFFFFFFF) +#define PSB_2D_ZERO_SOURCE_ALPHA_ENABLE (0x20000000) +#define PSB_2D_ZERO_SOURCE_ALPHA_CLRMASK (0xDFFFFFFF) + +/* + *Source Offset (PSB_2D_SRC_OFF_BH) + */ +#define PSB_2D_SRCOFF_XSTART_MASK ((0x00000FFF) << 12) +#define PSB_2D_SRCOFF_XSTART_SHIFT (12) +#define PSB_2D_SRCOFF_YSTART_MASK (0x00000FFF) +#define PSB_2D_SRCOFF_YSTART_SHIFT (0) + +/* + * Mask Offset (PSB_2D_MASK_OFF_BH) + */ +#define PSB_2D_MASKOFF_XSTART_MASK ((0x00000FFF) << 12) +#define PSB_2D_MASKOFF_XSTART_SHIFT (12) +#define PSB_2D_MASKOFF_YSTART_MASK (0x00000FFF) +#define PSB_2D_MASKOFF_YSTART_SHIFT (0) + +/* + * 2D Fence (see PSB_2D_FENCE_BH): bits 0:27 are ignored + */ + +/* + *Blit Rectangle (PSB_2D_BLIT_BH) + */ + +#define PSB_2D_ROT_MASK (3<<25) +#define PSB_2D_ROT_CLRMASK (~PSB_2D_ROT_MASK) +#define PSB_2D_ROT_NONE (0<<25) +#define PSB_2D_ROT_90DEGS (1<<25) +#define PSB_2D_ROT_180DEGS (2<<25) +#define PSB_2D_ROT_270DEGS (3<<25) + +#define PSB_2D_COPYORDER_MASK (3<<23) +#define PSB_2D_COPYORDER_CLRMASK (~PSB_2D_COPYORDER_MASK) +#define PSB_2D_COPYORDER_TL2BR (0<<23) +#define PSB_2D_COPYORDER_BR2TL (1<<23) +#define PSB_2D_COPYORDER_TR2BL (2<<23) +#define PSB_2D_COPYORDER_BL2TR (3<<23) + +#define PSB_2D_DSTCK_CLRMASK (0xFF9FFFFF) +#define PSB_2D_DSTCK_DISABLE (0x00000000) +#define PSB_2D_DSTCK_PASS (0x00200000) +#define PSB_2D_DSTCK_REJECT (0x00400000) + +#define PSB_2D_SRCCK_CLRMASK (0xFFE7FFFF) +#define PSB_2D_SRCCK_DISABLE (0x00000000) +#define PSB_2D_SRCCK_PASS (0x00080000) +#define PSB_2D_SRCCK_REJECT (0x00100000) + +#define PSB_2D_CLIP_ENABLE (0x00040000) + +#define PSB_2D_ALPHA_ENABLE (0x00020000) + +#define PSB_2D_PAT_CLRMASK (0xFFFEFFFF) +#define PSB_2D_PAT_MASK (0x00010000) +#define PSB_2D_USE_PAT (0x00010000) +#define PSB_2D_USE_FILL (0x00000000) +/* + * Tungsten Graphics note on rop codes: If rop A and rop B are + * identical, the mask surface will not be read and need not be + * set up. + */ + +#define PSB_2D_ROP3B_MASK (0x0000FF00) +#define PSB_2D_ROP3B_CLRMASK (0xFFFF00FF) +#define PSB_2D_ROP3B_SHIFT (8) +/* rop code A */ +#define PSB_2D_ROP3A_MASK (0x000000FF) +#define PSB_2D_ROP3A_CLRMASK (0xFFFFFF00) +#define PSB_2D_ROP3A_SHIFT (0) + +#define PSB_2D_ROP4_MASK (0x0000FFFF) +/* + * DWORD0: (Only pass if Pattern control == Use Fill Colour) + * Fill Colour RGBA8888 + */ +#define PSB_2D_FILLCOLOUR_MASK (0xFFFFFFFF) +#define PSB_2D_FILLCOLOUR_SHIFT (0) +/* + * DWORD1: (Always Present) + * X Start (Dest) + * Y Start (Dest) + */ +#define PSB_2D_DST_XSTART_MASK (0x00FFF000) +#define PSB_2D_DST_XSTART_CLRMASK (0xFF000FFF) +#define PSB_2D_DST_XSTART_SHIFT (12) +#define PSB_2D_DST_YSTART_MASK (0x00000FFF) +#define PSB_2D_DST_YSTART_CLRMASK (0xFFFFF000) +#define PSB_2D_DST_YSTART_SHIFT (0) +/* + * DWORD2: (Always Present) + * X Size (Dest) + * Y Size (Dest) + */ +#define PSB_2D_DST_XSIZE_MASK (0x00FFF000) +#define PSB_2D_DST_XSIZE_CLRMASK (0xFF000FFF) +#define PSB_2D_DST_XSIZE_SHIFT (12) +#define PSB_2D_DST_YSIZE_MASK (0x00000FFF) +#define PSB_2D_DST_YSIZE_CLRMASK (0xFFFFF000) +#define PSB_2D_DST_YSIZE_SHIFT (0) + +/* + * Source Surface (PSB_2D_SRC_SURF_BH) + */ +/* + * WORD 0 + */ + +#define PSB_2D_SRC_FORMAT_MASK (0x00078000) +#define PSB_2D_SRC_1_PAL (0x00000000) +#define PSB_2D_SRC_2_PAL (0x00008000) +#define PSB_2D_SRC_4_PAL (0x00010000) +#define PSB_2D_SRC_8_PAL (0x00018000) +#define PSB_2D_SRC_8_ALPHA (0x00020000) +#define PSB_2D_SRC_4_ALPHA (0x00028000) +#define PSB_2D_SRC_332RGB (0x00030000) +#define PSB_2D_SRC_4444ARGB (0x00038000) +#define PSB_2D_SRC_555RGB (0x00040000) +#define PSB_2D_SRC_1555ARGB (0x00048000) +#define PSB_2D_SRC_565RGB (0x00050000) +#define PSB_2D_SRC_0888ARGB (0x00058000) +#define PSB_2D_SRC_8888ARGB (0x00060000) +#define PSB_2D_SRC_8888UYVY (0x00068000) +#define PSB_2D_SRC_RESERVED (0x00070000) +#define PSB_2D_SRC_1555ARGB_LOOKUP (0x00078000) + + +#define PSB_2D_SRC_STRIDE_MASK (0x00007FFF) +#define PSB_2D_SRC_STRIDE_CLRMASK (0xFFFF8000) +#define PSB_2D_SRC_STRIDE_SHIFT (0) +/* + * WORD 1 - Base Address + */ +#define PSB_2D_SRC_ADDR_MASK (0x0FFFFFFC) +#define PSB_2D_SRC_ADDR_CLRMASK (0x00000003) +#define PSB_2D_SRC_ADDR_SHIFT (2) +#define PSB_2D_SRC_ADDR_ALIGNSHIFT (2) + +/* + * Pattern Surface (PSB_2D_PAT_SURF_BH) + */ +/* + * WORD 0 + */ + +#define PSB_2D_PAT_FORMAT_MASK (0x00078000) +#define PSB_2D_PAT_1_PAL (0x00000000) +#define PSB_2D_PAT_2_PAL (0x00008000) +#define PSB_2D_PAT_4_PAL (0x00010000) +#define PSB_2D_PAT_8_PAL (0x00018000) +#define PSB_2D_PAT_8_ALPHA (0x00020000) +#define PSB_2D_PAT_4_ALPHA (0x00028000) +#define PSB_2D_PAT_332RGB (0x00030000) +#define PSB_2D_PAT_4444ARGB (0x00038000) +#define PSB_2D_PAT_555RGB (0x00040000) +#define PSB_2D_PAT_1555ARGB (0x00048000) +#define PSB_2D_PAT_565RGB (0x00050000) +#define PSB_2D_PAT_0888ARGB (0x00058000) +#define PSB_2D_PAT_8888ARGB (0x00060000) + +#define PSB_2D_PAT_STRIDE_MASK (0x00007FFF) +#define PSB_2D_PAT_STRIDE_CLRMASK (0xFFFF8000) +#define PSB_2D_PAT_STRIDE_SHIFT (0) +/* + * WORD 1 - Base Address + */ +#define PSB_2D_PAT_ADDR_MASK (0x0FFFFFFC) +#define PSB_2D_PAT_ADDR_CLRMASK (0x00000003) +#define PSB_2D_PAT_ADDR_SHIFT (2) +#define PSB_2D_PAT_ADDR_ALIGNSHIFT (2) + +/* + * Destination Surface (PSB_2D_DST_SURF_BH) + */ +/* + * WORD 0 + */ + +#define PSB_2D_DST_FORMAT_MASK (0x00078000) +#define PSB_2D_DST_332RGB (0x00030000) +#define PSB_2D_DST_4444ARGB (0x00038000) +#define PSB_2D_DST_555RGB (0x00040000) +#define PSB_2D_DST_1555ARGB (0x00048000) +#define PSB_2D_DST_565RGB (0x00050000) +#define PSB_2D_DST_0888ARGB (0x00058000) +#define PSB_2D_DST_8888ARGB (0x00060000) +#define PSB_2D_DST_8888AYUV (0x00070000) + +#define PSB_2D_DST_STRIDE_MASK (0x00007FFF) +#define PSB_2D_DST_STRIDE_CLRMASK (0xFFFF8000) +#define PSB_2D_DST_STRIDE_SHIFT (0) +/* + * WORD 1 - Base Address + */ +#define PSB_2D_DST_ADDR_MASK (0x0FFFFFFC) +#define PSB_2D_DST_ADDR_CLRMASK (0x00000003) +#define PSB_2D_DST_ADDR_SHIFT (2) +#define PSB_2D_DST_ADDR_ALIGNSHIFT (2) + +/* + * Mask Surface (PSB_2D_MASK_SURF_BH) + */ +/* + * WORD 0 + */ +#define PSB_2D_MASK_STRIDE_MASK (0x00007FFF) +#define PSB_2D_MASK_STRIDE_CLRMASK (0xFFFF8000) +#define PSB_2D_MASK_STRIDE_SHIFT (0) +/* + * WORD 1 - Base Address + */ +#define PSB_2D_MASK_ADDR_MASK (0x0FFFFFFC) +#define PSB_2D_MASK_ADDR_CLRMASK (0x00000003) +#define PSB_2D_MASK_ADDR_SHIFT (2) +#define PSB_2D_MASK_ADDR_ALIGNSHIFT (2) + +/* + * Source Palette (PSB_2D_SRC_PAL_BH) + */ + +#define PSB_2D_SRCPAL_ADDR_SHIFT (0) +#define PSB_2D_SRCPAL_ADDR_CLRMASK (0xF0000007) +#define PSB_2D_SRCPAL_ADDR_MASK (0x0FFFFFF8) +#define PSB_2D_SRCPAL_BYTEALIGN (1024) + +/* + * Pattern Palette (PSB_2D_PAT_PAL_BH) + */ + +#define PSB_2D_PATPAL_ADDR_SHIFT (0) +#define PSB_2D_PATPAL_ADDR_CLRMASK (0xF0000007) +#define PSB_2D_PATPAL_ADDR_MASK (0x0FFFFFF8) +#define PSB_2D_PATPAL_BYTEALIGN (1024) + +/* + * Rop3 Codes (2 LS bytes) + */ + +#define PSB_2D_ROP3_SRCCOPY (0xCCCC) +#define PSB_2D_ROP3_PATCOPY (0xF0F0) +#define PSB_2D_ROP3_WHITENESS (0xFFFF) +#define PSB_2D_ROP3_BLACKNESS (0x0000) +#define PSB_2D_ROP3_SRC (0xCC) +#define PSB_2D_ROP3_PAT (0xF0) +#define PSB_2D_ROP3_DST (0xAA) + + +/* + * Sizes. + */ + +#define PSB_SCENE_HW_COOKIE_SIZE 16 +#define PSB_TA_MEM_HW_COOKIE_SIZE 16 + +/* + * Scene stuff. + */ + +#define PSB_NUM_HW_SCENES 2 + +/* + * Scheduler completion actions. + */ + +#define PSB_RASTER_BLOCK 0 +#define PSB_RASTER 1 +#define PSB_RETURN 2 +#define PSB_TA 3 + + +/*Power management*/ +#define PSB_PUNIT_PORT 0x04 +#define PSB_OSPMBA 0x78 +#define PSB_APMBA 0x7a +#define PSB_APM_CMD 0x0 +#define PSB_APM_STS 0x04 +#define PSB_PWRGT_VID_ENC_MASK 0x30 +#define PSB_PWRGT_VID_DEC_MASK 0xc +#define PSB_PWRGT_GL3_MASK 0xc0 + +#define PSB_PM_SSC 0x20 +#define PSB_PM_SSS 0x30 +#define PSB_PWRGT_DISPLAY_MASK 0xc /*on a different BA than video/gfx*/ +#define MDFLD_PWRGT_DISPLAY_A_CNTR 0x0000000c +#define MDFLD_PWRGT_DISPLAY_B_CNTR 0x0000c000 +#define MDFLD_PWRGT_DISPLAY_C_CNTR 0x00030000 +#define MDFLD_PWRGT_DISP_MIPI_CNTR 0x000c0000 +#define MDFLD_PWRGT_DISPLAY_CNTR (MDFLD_PWRGT_DISPLAY_A_CNTR | MDFLD_PWRGT_DISPLAY_B_CNTR | MDFLD_PWRGT_DISPLAY_C_CNTR | MDFLD_PWRGT_DISP_MIPI_CNTR)// 0x000fc00c +// Display SSS register bits are different in A0 vs. B0 +#define PSB_PWRGT_GFX_MASK 0x3 +#define MDFLD_PWRGT_DISPLAY_A_STS 0x000000c0 +#define MDFLD_PWRGT_DISPLAY_B_STS 0x00000300 +#define MDFLD_PWRGT_DISPLAY_C_STS 0x00000c00 +#define PSB_PWRGT_GFX_MASK_B0 0xc3 +#define MDFLD_PWRGT_DISPLAY_A_STS_B0 0x0000000c +#define MDFLD_PWRGT_DISPLAY_B_STS_B0 0x0000c000 +#define MDFLD_PWRGT_DISPLAY_C_STS_B0 0x00030000 +#define MDFLD_PWRGT_DISP_MIPI_STS 0x000c0000 +#define MDFLD_PWRGT_DISPLAY_STS_A0 (MDFLD_PWRGT_DISPLAY_A_STS | MDFLD_PWRGT_DISPLAY_B_STS | MDFLD_PWRGT_DISPLAY_C_STS | MDFLD_PWRGT_DISP_MIPI_STS)// 0x000fc00c +#define MDFLD_PWRGT_DISPLAY_STS_B0 (MDFLD_PWRGT_DISPLAY_A_STS_B0 | MDFLD_PWRGT_DISPLAY_B_STS_B0 | MDFLD_PWRGT_DISPLAY_C_STS_B0 | MDFLD_PWRGT_DISP_MIPI_STS)// 0x000fc00c +#endif diff --git a/drivers/staging/gma500/psb_reset.c b/drivers/staging/gma500/psb_reset.c new file mode 100644 index 000000000000..21fd202f2931 --- /dev/null +++ b/drivers/staging/gma500/psb_reset.c @@ -0,0 +1,90 @@ +/************************************************************************** + * Copyright (c) 2007, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Authors: Thomas Hellstrom + **************************************************************************/ + +#include +#include "psb_drv.h" +#include "psb_reg.h" +#include "psb_intel_reg.h" +#include + +static void psb_lid_timer_func(unsigned long data) +{ + struct drm_psb_private * dev_priv = (struct drm_psb_private *)data; + struct drm_device *dev = (struct drm_device *)dev_priv->dev; + struct timer_list *lid_timer = &dev_priv->lid_timer; + unsigned long irq_flags; + u32 *lid_state = dev_priv->lid_state; + u32 pp_status; + + if (*lid_state == dev_priv->lid_last_state) + goto lid_timer_schedule; + + if ((*lid_state) & 0x01) { + /*lid state is open*/ + REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | POWER_TARGET_ON); + do { + pp_status = REG_READ(PP_STATUS); + } while ((pp_status & PP_ON) == 0); + + /*FIXME: should be backlight level before*/ + psb_intel_lvds_set_brightness(dev, 100); + } else { + psb_intel_lvds_set_brightness(dev, 0); + + REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & ~POWER_TARGET_ON); + do { + pp_status = REG_READ(PP_STATUS); + } while ((pp_status & PP_ON) == 0); + } + /* printk(KERN_INFO"%s: lid: closed\n", __FUNCTION__); */ + + dev_priv->lid_last_state = *lid_state; + +lid_timer_schedule: + spin_lock_irqsave(&dev_priv->lid_lock, irq_flags); + if (!timer_pending(lid_timer)) { + lid_timer->expires = jiffies + PSB_LID_DELAY; + add_timer(lid_timer); + } + spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags); +} + +void psb_lid_timer_init(struct drm_psb_private *dev_priv) +{ + struct timer_list *lid_timer = &dev_priv->lid_timer; + unsigned long irq_flags; + + spin_lock_init(&dev_priv->lid_lock); + spin_lock_irqsave(&dev_priv->lid_lock, irq_flags); + + init_timer(lid_timer); + + lid_timer->data = (unsigned long)dev_priv; + lid_timer->function = psb_lid_timer_func; + lid_timer->expires = jiffies + PSB_LID_DELAY; + + add_timer(lid_timer); + spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags); +} + +void psb_lid_timer_takedown(struct drm_psb_private *dev_priv) +{ + del_timer_sync(&dev_priv->lid_timer); +} + diff --git a/drivers/staging/gma500/psb_sgx.c b/drivers/staging/gma500/psb_sgx.c new file mode 100644 index 000000000000..973134bc2345 --- /dev/null +++ b/drivers/staging/gma500/psb_sgx.c @@ -0,0 +1,238 @@ +/************************************************************************** + * Copyright (c) 2007, Intel Corporation. + * All Rights Reserved. + * Copyright (c) 2008, Tungsten Graphics, Inc. Cedar Park, TX. USA. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + **************************************************************************/ + +#include +#include "psb_drv.h" +#include "psb_drm.h" +#include "psb_reg.h" +#include "ttm/ttm_bo_api.h" +#include "ttm/ttm_execbuf_util.h" +#include "psb_ttm_userobj_api.h" +#include "ttm/ttm_placement.h" +#include "psb_sgx.h" +#include "psb_intel_reg.h" +#include "psb_powermgmt.h" + + +static inline int psb_same_page(unsigned long offset, + unsigned long offset2) +{ + return (offset & PAGE_MASK) == (offset2 & PAGE_MASK); +} + +static inline unsigned long psb_offset_end(unsigned long offset, + unsigned long end) +{ + offset = (offset + PAGE_SIZE) & PAGE_MASK; + return (end < offset) ? end : offset; +} + +struct psb_dstbuf_cache { + unsigned int dst; + struct ttm_buffer_object *dst_buf; + unsigned long dst_offset; + uint32_t *dst_page; + unsigned int dst_page_offset; + struct ttm_bo_kmap_obj dst_kmap; + bool dst_is_iomem; +}; + +struct psb_validate_buffer { + struct ttm_validate_buffer base; + struct psb_validate_req req; + int ret; + struct psb_validate_arg __user *user_val_arg; + uint32_t flags; + uint32_t offset; + int po_correct; +}; +static int +psb_placement_fence_type(struct ttm_buffer_object *bo, + uint64_t set_val_flags, + uint64_t clr_val_flags, + uint32_t new_fence_class, + uint32_t *new_fence_type) +{ + int ret; + uint32_t n_fence_type; + /* + uint32_t set_flags = set_val_flags & 0xFFFFFFFF; + uint32_t clr_flags = clr_val_flags & 0xFFFFFFFF; + */ + struct ttm_fence_object *old_fence; + uint32_t old_fence_type; + struct ttm_placement placement; + + if (unlikely + (!(set_val_flags & + (PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE)))) { + DRM_ERROR + ("GPU access type (read / write) is not indicated.\n"); + return -EINVAL; + } + + /* User space driver doesn't set any TTM placement flags in + set_val_flags or clr_val_flags */ + placement.num_placement = 0;/* FIXME */ + placement.num_busy_placement = 0; + placement.fpfn = 0; + placement.lpfn = 0; + ret = psb_ttm_bo_check_placement(bo, &placement); + if (unlikely(ret != 0)) + return ret; + + switch (new_fence_class) { + default: + n_fence_type = _PSB_FENCE_TYPE_EXE; + } + + *new_fence_type = n_fence_type; + old_fence = (struct ttm_fence_object *) bo->sync_obj; + old_fence_type = (uint32_t) (unsigned long) bo->sync_obj_arg; + + if (old_fence && ((new_fence_class != old_fence->fence_class) || + ((n_fence_type ^ old_fence_type) & + old_fence_type))) { + ret = ttm_bo_wait(bo, 0, 1, 0); + if (unlikely(ret != 0)) + return ret; + } + /* + bo->proposed_flags = (bo->proposed_flags | set_flags) + & ~clr_flags & TTM_PL_MASK_MEMTYPE; + */ + return 0; +} + +int psb_validate_kernel_buffer(struct psb_context *context, + struct ttm_buffer_object *bo, + uint32_t fence_class, + uint64_t set_flags, uint64_t clr_flags) +{ + struct psb_validate_buffer *item; + uint32_t cur_fence_type; + int ret; + + if (unlikely(context->used_buffers >= PSB_NUM_VALIDATE_BUFFERS)) { + DRM_ERROR("Out of free validation buffer entries for " + "kernel buffer validation.\n"); + return -ENOMEM; + } + + item = &context->buffers[context->used_buffers]; + item->user_val_arg = NULL; + item->base.reserved = 0; + + ret = ttm_bo_reserve(bo, 1, 0, 1, context->val_seq); + if (unlikely(ret != 0)) + return ret; + + ret = psb_placement_fence_type(bo, set_flags, clr_flags, fence_class, + &cur_fence_type); + if (unlikely(ret != 0)) { + ttm_bo_unreserve(bo); + return ret; + } + + item->base.bo = ttm_bo_reference(bo); + item->base.new_sync_obj_arg = (void *) (unsigned long) cur_fence_type; + item->base.reserved = 1; + + /* Internal locking ??? FIXMEAC */ + list_add_tail(&item->base.head, &context->kern_validate_list); + context->used_buffers++; + /* + ret = ttm_bo_validate(bo, 1, 0, 0); + if (unlikely(ret != 0)) + goto out_unlock; + */ + item->offset = bo->offset; + item->flags = bo->mem.placement; + context->fence_types |= cur_fence_type; + + return ret; +} + +void psb_fence_or_sync(struct drm_file *file_priv, + uint32_t engine, + uint32_t fence_types, + uint32_t fence_flags, + struct list_head *list, + struct psb_ttm_fence_rep *fence_arg, + struct ttm_fence_object **fence_p) +{ + struct drm_device *dev = file_priv->minor->dev; + struct drm_psb_private *dev_priv = psb_priv(dev); + struct ttm_fence_device *fdev = &dev_priv->fdev; + int ret; + struct ttm_fence_object *fence; + struct ttm_object_file *tfile = psb_fpriv(file_priv)->tfile; + uint32_t handle; + + ret = ttm_fence_user_create(fdev, tfile, + engine, fence_types, + TTM_FENCE_FLAG_EMIT, &fence, &handle); + if (ret) { + + /* + * Fence creation failed. + * Fall back to synchronous operation and idle the engine. + */ + + if (!(fence_flags & DRM_PSB_FENCE_NO_USER)) { + + /* + * Communicate to user-space that + * fence creation has failed and that + * the engine is idle. + */ + + fence_arg->handle = ~0; + fence_arg->error = ret; + } + + ttm_eu_backoff_reservation(list); + if (fence_p) + *fence_p = NULL; + return; + } + + ttm_eu_fence_buffer_objects(list, fence); + if (!(fence_flags & DRM_PSB_FENCE_NO_USER)) { + struct ttm_fence_info info = ttm_fence_get_info(fence); + fence_arg->handle = handle; + fence_arg->fence_class = ttm_fence_class(fence); + fence_arg->fence_type = ttm_fence_types(fence); + fence_arg->signaled_types = info.signaled_types; + fence_arg->error = 0; + } else { + ret = + ttm_ref_object_base_unref(tfile, handle, + ttm_fence_type); + BUG_ON(ret); + } + + if (fence_p) + *fence_p = fence; + else if (fence) + ttm_fence_object_unref(&fence); +} + diff --git a/drivers/staging/gma500/psb_sgx.h b/drivers/staging/gma500/psb_sgx.h new file mode 100644 index 000000000000..2934e5d146c5 --- /dev/null +++ b/drivers/staging/gma500/psb_sgx.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2008, Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Authors: + * Eric Anholt + * + **/ +#ifndef _PSB_SGX_H_ +#define _PSB_SGX_H_ + +extern int psb_submit_video_cmdbuf(struct drm_device *dev, + struct ttm_buffer_object *cmd_buffer, + unsigned long cmd_offset, + unsigned long cmd_size, + struct ttm_fence_object *fence); + +extern int drm_idle_check_interval; + +#endif diff --git a/drivers/staging/gma500/psb_ttm_fence.c b/drivers/staging/gma500/psb_ttm_fence.c new file mode 100644 index 000000000000..d1c359018cba --- /dev/null +++ b/drivers/staging/gma500/psb_ttm_fence.c @@ -0,0 +1,605 @@ +/************************************************************************** + * + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * All Rights Reserved. + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom + */ + +#include "psb_ttm_fence_api.h" +#include "psb_ttm_fence_driver.h" +#include +#include + +#include + +/* + * Simple implementation for now. + */ + +static void ttm_fence_lockup(struct ttm_fence_object *fence, uint32_t mask) +{ + struct ttm_fence_class_manager *fc = ttm_fence_fc(fence); + + printk(KERN_ERR "GPU lockup dectected on engine %u " + "fence type 0x%08x\n", + (unsigned int)fence->fence_class, (unsigned int)mask); + /* + * Give engines some time to idle? + */ + + write_lock(&fc->lock); + ttm_fence_handler(fence->fdev, fence->fence_class, + fence->sequence, mask, -EBUSY); + write_unlock(&fc->lock); +} + +/* + * Convenience function to be called by fence::wait methods that + * need polling. + */ + +int ttm_fence_wait_polling(struct ttm_fence_object *fence, bool lazy, + bool interruptible, uint32_t mask) +{ + struct ttm_fence_class_manager *fc = ttm_fence_fc(fence); + const struct ttm_fence_driver *driver = ttm_fence_driver(fence); + uint32_t count = 0; + int ret; + unsigned long end_jiffies = fence->timeout_jiffies; + + DECLARE_WAITQUEUE(entry, current); + add_wait_queue(&fc->fence_queue, &entry); + + ret = 0; + + for (;;) { + __set_current_state((interruptible) ? + TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); + if (ttm_fence_object_signaled(fence, mask)) + break; + if (time_after_eq(jiffies, end_jiffies)) { + if (driver->lockup) + driver->lockup(fence, mask); + else + ttm_fence_lockup(fence, mask); + continue; + } + if (lazy) + schedule_timeout(1); + else if ((++count & 0x0F) == 0) { + __set_current_state(TASK_RUNNING); + schedule(); + __set_current_state((interruptible) ? + TASK_INTERRUPTIBLE : + TASK_UNINTERRUPTIBLE); + } + if (interruptible && signal_pending(current)) { + ret = -ERESTART; + break; + } + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&fc->fence_queue, &entry); + return ret; +} + +/* + * Typically called by the IRQ handler. + */ + +void ttm_fence_handler(struct ttm_fence_device *fdev, uint32_t fence_class, + uint32_t sequence, uint32_t type, uint32_t error) +{ + int wake = 0; + uint32_t diff; + uint32_t relevant_type; + uint32_t new_type; + struct ttm_fence_class_manager *fc = &fdev->fence_class[fence_class]; + const struct ttm_fence_driver *driver = ttm_fence_driver_from_dev(fdev); + struct list_head *head; + struct ttm_fence_object *fence, *next; + bool found = false; + + if (list_empty(&fc->ring)) + return; + + list_for_each_entry(fence, &fc->ring, ring) { + diff = (sequence - fence->sequence) & fc->sequence_mask; + if (diff > fc->wrap_diff) { + found = true; + break; + } + } + + fc->waiting_types &= ~type; + head = (found) ? &fence->ring : &fc->ring; + + list_for_each_entry_safe_reverse(fence, next, head, ring) { + if (&fence->ring == &fc->ring) + break; + + DRM_DEBUG("Fence 0x%08lx, sequence 0x%08x, type 0x%08x\n", + (unsigned long)fence, fence->sequence, + fence->fence_type); + + if (error) { + fence->info.error = error; + fence->info.signaled_types = fence->fence_type; + list_del_init(&fence->ring); + wake = 1; + break; + } + + relevant_type = type & fence->fence_type; + new_type = (fence->info.signaled_types | relevant_type) ^ + fence->info.signaled_types; + + if (new_type) { + fence->info.signaled_types |= new_type; + DRM_DEBUG("Fence 0x%08lx signaled 0x%08x\n", + (unsigned long)fence, + fence->info.signaled_types); + + if (unlikely(driver->signaled)) + driver->signaled(fence); + + if (driver->needed_flush) + fc->pending_flush |= + driver->needed_flush(fence); + + if (new_type & fence->waiting_types) + wake = 1; + } + + fc->waiting_types |= + fence->waiting_types & ~fence->info.signaled_types; + + if (!(fence->fence_type & ~fence->info.signaled_types)) { + DRM_DEBUG("Fence completely signaled 0x%08lx\n", + (unsigned long)fence); + list_del_init(&fence->ring); + } + } + + /* + * Reinstate lost waiting types. + */ + + if ((fc->waiting_types & type) != type) { + head = head->prev; + list_for_each_entry(fence, head, ring) { + if (&fence->ring == &fc->ring) + break; + diff = + (fc->highest_waiting_sequence - + fence->sequence) & fc->sequence_mask; + if (diff > fc->wrap_diff) + break; + + fc->waiting_types |= + fence->waiting_types & ~fence->info.signaled_types; + } + } + + if (wake) + wake_up_all(&fc->fence_queue); +} + +static void ttm_fence_unring(struct ttm_fence_object *fence) +{ + struct ttm_fence_class_manager *fc = ttm_fence_fc(fence); + unsigned long irq_flags; + + write_lock_irqsave(&fc->lock, irq_flags); + list_del_init(&fence->ring); + write_unlock_irqrestore(&fc->lock, irq_flags); +} + +bool ttm_fence_object_signaled(struct ttm_fence_object *fence, uint32_t mask) +{ + unsigned long flags; + bool signaled; + const struct ttm_fence_driver *driver = ttm_fence_driver(fence); + struct ttm_fence_class_manager *fc = ttm_fence_fc(fence); + + mask &= fence->fence_type; + read_lock_irqsave(&fc->lock, flags); + signaled = (mask & fence->info.signaled_types) == mask; + read_unlock_irqrestore(&fc->lock, flags); + if (!signaled && driver->poll) { + write_lock_irqsave(&fc->lock, flags); + driver->poll(fence->fdev, fence->fence_class, mask); + signaled = (mask & fence->info.signaled_types) == mask; + write_unlock_irqrestore(&fc->lock, flags); + } + return signaled; +} + +int ttm_fence_object_flush(struct ttm_fence_object *fence, uint32_t type) +{ + const struct ttm_fence_driver *driver = ttm_fence_driver(fence); + struct ttm_fence_class_manager *fc = ttm_fence_fc(fence); + unsigned long irq_flags; + uint32_t saved_pending_flush; + uint32_t diff; + bool call_flush; + + if (type & ~fence->fence_type) { + DRM_ERROR("Flush trying to extend fence type, " + "0x%x, 0x%x\n", type, fence->fence_type); + return -EINVAL; + } + + write_lock_irqsave(&fc->lock, irq_flags); + fence->waiting_types |= type; + fc->waiting_types |= fence->waiting_types; + diff = (fence->sequence - fc->highest_waiting_sequence) & + fc->sequence_mask; + + if (diff < fc->wrap_diff) + fc->highest_waiting_sequence = fence->sequence; + + /* + * fence->waiting_types has changed. Determine whether + * we need to initiate some kind of flush as a result of this. + */ + + saved_pending_flush = fc->pending_flush; + if (driver->needed_flush) + fc->pending_flush |= driver->needed_flush(fence); + + if (driver->poll) + driver->poll(fence->fdev, fence->fence_class, + fence->waiting_types); + + call_flush = (fc->pending_flush != 0); + write_unlock_irqrestore(&fc->lock, irq_flags); + + if (call_flush && driver->flush) + driver->flush(fence->fdev, fence->fence_class); + + return 0; +} + +/* + * Make sure old fence objects are signaled before their fence sequences are + * wrapped around and reused. + */ + +void ttm_fence_flush_old(struct ttm_fence_device *fdev, + uint32_t fence_class, uint32_t sequence) +{ + struct ttm_fence_class_manager *fc = &fdev->fence_class[fence_class]; + struct ttm_fence_object *fence; + unsigned long irq_flags; + const struct ttm_fence_driver *driver = fdev->driver; + bool call_flush; + + uint32_t diff; + + write_lock_irqsave(&fc->lock, irq_flags); + + list_for_each_entry_reverse(fence, &fc->ring, ring) { + diff = (sequence - fence->sequence) & fc->sequence_mask; + if (diff <= fc->flush_diff) + break; + + fence->waiting_types = fence->fence_type; + fc->waiting_types |= fence->fence_type; + + if (driver->needed_flush) + fc->pending_flush |= driver->needed_flush(fence); + } + + if (driver->poll) + driver->poll(fdev, fence_class, fc->waiting_types); + + call_flush = (fc->pending_flush != 0); + write_unlock_irqrestore(&fc->lock, irq_flags); + + if (call_flush && driver->flush) + driver->flush(fdev, fence->fence_class); + + /* + * FIXME: Shold we implement a wait here for really old fences? + */ + +} + +int ttm_fence_object_wait(struct ttm_fence_object *fence, + bool lazy, bool interruptible, uint32_t mask) +{ + const struct ttm_fence_driver *driver = ttm_fence_driver(fence); + struct ttm_fence_class_manager *fc = ttm_fence_fc(fence); + int ret = 0; + unsigned long timeout; + unsigned long cur_jiffies; + unsigned long to_jiffies; + + if (mask & ~fence->fence_type) { + DRM_ERROR("Wait trying to extend fence type" + " 0x%08x 0x%08x\n", mask, fence->fence_type); + BUG(); + return -EINVAL; + } + + if (driver->wait) + return driver->wait(fence, lazy, interruptible, mask); + + ttm_fence_object_flush(fence, mask); +retry: + if (!driver->has_irq || + driver->has_irq(fence->fdev, fence->fence_class, mask)) { + + cur_jiffies = jiffies; + to_jiffies = fence->timeout_jiffies; + + timeout = (time_after(to_jiffies, cur_jiffies)) ? + to_jiffies - cur_jiffies : 1; + + if (interruptible) + ret = wait_event_interruptible_timeout + (fc->fence_queue, + ttm_fence_object_signaled(fence, mask), timeout); + else + ret = wait_event_timeout + (fc->fence_queue, + ttm_fence_object_signaled(fence, mask), timeout); + + if (unlikely(ret == -ERESTARTSYS)) + return -ERESTART; + + if (unlikely(ret == 0)) { + if (driver->lockup) + driver->lockup(fence, mask); + else + ttm_fence_lockup(fence, mask); + goto retry; + } + + return 0; + } + + return ttm_fence_wait_polling(fence, lazy, interruptible, mask); +} + +int ttm_fence_object_emit(struct ttm_fence_object *fence, uint32_t fence_flags, + uint32_t fence_class, uint32_t type) +{ + const struct ttm_fence_driver *driver = ttm_fence_driver(fence); + struct ttm_fence_class_manager *fc = ttm_fence_fc(fence); + unsigned long flags; + uint32_t sequence; + unsigned long timeout; + int ret; + + ttm_fence_unring(fence); + ret = driver->emit(fence->fdev, + fence_class, fence_flags, &sequence, &timeout); + if (ret) + return ret; + + write_lock_irqsave(&fc->lock, flags); + fence->fence_class = fence_class; + fence->fence_type = type; + fence->waiting_types = 0; + fence->info.signaled_types = 0; + fence->info.error = 0; + fence->sequence = sequence; + fence->timeout_jiffies = timeout; + if (list_empty(&fc->ring)) + fc->highest_waiting_sequence = sequence - 1; + list_add_tail(&fence->ring, &fc->ring); + fc->latest_queued_sequence = sequence; + write_unlock_irqrestore(&fc->lock, flags); + return 0; +} + +int ttm_fence_object_init(struct ttm_fence_device *fdev, + uint32_t fence_class, + uint32_t type, + uint32_t create_flags, + void (*destroy) (struct ttm_fence_object *), + struct ttm_fence_object *fence) +{ + int ret = 0; + + kref_init(&fence->kref); + fence->fence_class = fence_class; + fence->fence_type = type; + fence->info.signaled_types = 0; + fence->waiting_types = 0; + fence->sequence = 0; + fence->info.error = 0; + fence->fdev = fdev; + fence->destroy = destroy; + INIT_LIST_HEAD(&fence->ring); + atomic_inc(&fdev->count); + + if (create_flags & TTM_FENCE_FLAG_EMIT) { + ret = ttm_fence_object_emit(fence, create_flags, + fence->fence_class, type); + } + + return ret; +} + +int ttm_fence_object_create(struct ttm_fence_device *fdev, + uint32_t fence_class, + uint32_t type, + uint32_t create_flags, + struct ttm_fence_object **c_fence) +{ + struct ttm_fence_object *fence; + int ret; + + ret = ttm_mem_global_alloc(fdev->mem_glob, + sizeof(*fence), + false, + false); + if (unlikely(ret != 0)) { + printk(KERN_ERR "Out of memory creating fence object\n"); + return ret; + } + + fence = kmalloc(sizeof(*fence), GFP_KERNEL); + if (!fence) { + printk(KERN_ERR "Out of memory creating fence object\n"); + ttm_mem_global_free(fdev->mem_glob, sizeof(*fence)); + return -ENOMEM; + } + + ret = ttm_fence_object_init(fdev, fence_class, type, + create_flags, NULL, fence); + if (ret) { + ttm_fence_object_unref(&fence); + return ret; + } + *c_fence = fence; + + return 0; +} + +static void ttm_fence_object_destroy(struct kref *kref) +{ + struct ttm_fence_object *fence = + container_of(kref, struct ttm_fence_object, kref); + struct ttm_fence_class_manager *fc = ttm_fence_fc(fence); + unsigned long irq_flags; + + write_lock_irqsave(&fc->lock, irq_flags); + list_del_init(&fence->ring); + write_unlock_irqrestore(&fc->lock, irq_flags); + + atomic_dec(&fence->fdev->count); + if (fence->destroy) + fence->destroy(fence); + else { + ttm_mem_global_free(fence->fdev->mem_glob, + sizeof(*fence)); + kfree(fence); + } +} + +void ttm_fence_device_release(struct ttm_fence_device *fdev) +{ + kfree(fdev->fence_class); +} + +int +ttm_fence_device_init(int num_classes, + struct ttm_mem_global *mem_glob, + struct ttm_fence_device *fdev, + const struct ttm_fence_class_init *init, + bool replicate_init, + const struct ttm_fence_driver *driver) +{ + struct ttm_fence_class_manager *fc; + const struct ttm_fence_class_init *fci; + int i; + + fdev->mem_glob = mem_glob; + fdev->fence_class = kzalloc(num_classes * + sizeof(*fdev->fence_class), GFP_KERNEL); + + if (unlikely(!fdev->fence_class)) + return -ENOMEM; + + fdev->num_classes = num_classes; + atomic_set(&fdev->count, 0); + fdev->driver = driver; + + for (i = 0; i < fdev->num_classes; ++i) { + fc = &fdev->fence_class[i]; + fci = &init[(replicate_init) ? 0 : i]; + + fc->wrap_diff = fci->wrap_diff; + fc->flush_diff = fci->flush_diff; + fc->sequence_mask = fci->sequence_mask; + + rwlock_init(&fc->lock); + INIT_LIST_HEAD(&fc->ring); + init_waitqueue_head(&fc->fence_queue); + } + + return 0; +} + +struct ttm_fence_info ttm_fence_get_info(struct ttm_fence_object *fence) +{ + struct ttm_fence_class_manager *fc = ttm_fence_fc(fence); + struct ttm_fence_info tmp; + unsigned long irq_flags; + + read_lock_irqsave(&fc->lock, irq_flags); + tmp = fence->info; + read_unlock_irqrestore(&fc->lock, irq_flags); + + return tmp; +} + +void ttm_fence_object_unref(struct ttm_fence_object **p_fence) +{ + struct ttm_fence_object *fence = *p_fence; + + *p_fence = NULL; + (void)kref_put(&fence->kref, &ttm_fence_object_destroy); +} + +/* + * Placement / BO sync object glue. + */ + +bool ttm_fence_sync_obj_signaled(void *sync_obj, void *sync_arg) +{ + struct ttm_fence_object *fence = (struct ttm_fence_object *)sync_obj; + uint32_t fence_types = (uint32_t) (unsigned long)sync_arg; + + return ttm_fence_object_signaled(fence, fence_types); +} + +int ttm_fence_sync_obj_wait(void *sync_obj, void *sync_arg, + bool lazy, bool interruptible) +{ + struct ttm_fence_object *fence = (struct ttm_fence_object *)sync_obj; + uint32_t fence_types = (uint32_t) (unsigned long)sync_arg; + + return ttm_fence_object_wait(fence, lazy, interruptible, fence_types); +} + +int ttm_fence_sync_obj_flush(void *sync_obj, void *sync_arg) +{ + struct ttm_fence_object *fence = (struct ttm_fence_object *)sync_obj; + uint32_t fence_types = (uint32_t) (unsigned long)sync_arg; + + return ttm_fence_object_flush(fence, fence_types); +} + +void ttm_fence_sync_obj_unref(void **sync_obj) +{ + ttm_fence_object_unref((struct ttm_fence_object **)sync_obj); +} + +void *ttm_fence_sync_obj_ref(void *sync_obj) +{ + return (void *) + ttm_fence_object_ref((struct ttm_fence_object *)sync_obj); +} diff --git a/drivers/staging/gma500/psb_ttm_fence_api.h b/drivers/staging/gma500/psb_ttm_fence_api.h new file mode 100644 index 000000000000..d42904c4ec2f --- /dev/null +++ b/drivers/staging/gma500/psb_ttm_fence_api.h @@ -0,0 +1,272 @@ +/************************************************************************** + * + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * All Rights Reserved. + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom + */ +#ifndef _TTM_FENCE_API_H_ +#define _TTM_FENCE_API_H_ + +#include +#include + +#define TTM_FENCE_FLAG_EMIT (1 << 0) +#define TTM_FENCE_TYPE_EXE (1 << 0) + +struct ttm_fence_device; + +/** + * struct ttm_fence_info + * + * @fence_class: The fence class. + * @fence_type: Bitfield indicating types for this fence. + * @signaled_types: Bitfield indicating which types are signaled. + * @error: Last error reported from the device. + * + * Used as output from the ttm_fence_get_info + */ + +struct ttm_fence_info { + uint32_t signaled_types; + uint32_t error; +}; + +/** + * struct ttm_fence_object + * + * @fdev: Pointer to the fence device struct. + * @kref: Holds the reference count of this fence object. + * @ring: List head used for the circular list of not-completely + * signaled fences. + * @info: Data for fast retrieval using the ttm_fence_get_info() + * function. + * @timeout_jiffies: Absolute jiffies value indicating when this fence + * object times out and, if waited on, calls ttm_fence_lockup + * to check for and resolve a GPU lockup. + * @sequence: Fence sequence number. + * @waiting_types: Types currently waited on. + * @destroy: Called to free the fence object, when its refcount has + * reached zero. If NULL, kfree is used. + * + * This struct is provided in the driver interface so that drivers can + * derive from it and create their own fence implementation. All members + * are private to the fence implementation and the fence driver callbacks. + * Otherwise a driver may access the derived object using container_of(). + */ + +struct ttm_fence_object { + struct ttm_fence_device *fdev; + struct kref kref; + uint32_t fence_class; + uint32_t fence_type; + + /* + * The below fields are protected by the fence class + * manager spinlock. + */ + + struct list_head ring; + struct ttm_fence_info info; + unsigned long timeout_jiffies; + uint32_t sequence; + uint32_t waiting_types; + void (*destroy) (struct ttm_fence_object *); +}; + +/** + * ttm_fence_object_init + * + * @fdev: Pointer to a struct ttm_fence_device. + * @fence_class: Fence class for this fence. + * @type: Fence type for this fence. + * @create_flags: Flags indicating varios actions at init time. At this point + * there's only TTM_FENCE_FLAG_EMIT, which triggers a sequence emission to + * the command stream. + * @destroy: Destroy function. If NULL, kfree() is used. + * @fence: The struct ttm_fence_object to initialize. + * + * Initialize a pre-allocated fence object. This function, together with the + * destroy function makes it possible to derive driver-specific fence objects. + */ + +extern int +ttm_fence_object_init(struct ttm_fence_device *fdev, + uint32_t fence_class, + uint32_t type, + uint32_t create_flags, + void (*destroy) (struct ttm_fence_object *fence), + struct ttm_fence_object *fence); + +/** + * ttm_fence_object_create + * + * @fdev: Pointer to a struct ttm_fence_device. + * @fence_class: Fence class for this fence. + * @type: Fence type for this fence. + * @create_flags: Flags indicating varios actions at init time. At this point + * there's only TTM_FENCE_FLAG_EMIT, which triggers a sequence emission to + * the command stream. + * @c_fence: On successful termination, *(@c_fence) will point to the created + * fence object. + * + * Create and initialize a struct ttm_fence_object. The destroy function will + * be set to kfree(). + */ + +extern int +ttm_fence_object_create(struct ttm_fence_device *fdev, + uint32_t fence_class, + uint32_t type, + uint32_t create_flags, + struct ttm_fence_object **c_fence); + +/** + * ttm_fence_object_wait + * + * @fence: The fence object to wait on. + * @lazy: Allow sleeps to reduce the cpu-usage if polling. + * @interruptible: Sleep interruptible when waiting. + * @type_mask: Wait for the given type_mask to signal. + * + * Wait for a fence to signal the given type_mask. The function will + * perform a fence_flush using type_mask. (See ttm_fence_object_flush). + * + * Returns + * -ERESTART if interrupted by a signal. + * May return driver-specific error codes if timed-out. + */ + +extern int +ttm_fence_object_wait(struct ttm_fence_object *fence, + bool lazy, bool interruptible, uint32_t type_mask); + +/** + * ttm_fence_object_flush + * + * @fence: The fence object to flush. + * @flush_mask: Fence types to flush. + * + * Make sure that the given fence eventually signals the + * types indicated by @flush_mask. Note that this may or may not + * map to a CPU or GPU flush. + */ + +extern int +ttm_fence_object_flush(struct ttm_fence_object *fence, uint32_t flush_mask); + +/** + * ttm_fence_get_info + * + * @fence: The fence object. + * + * Copy the info block from the fence while holding relevant locks. + */ + +struct ttm_fence_info ttm_fence_get_info(struct ttm_fence_object *fence); + +/** + * ttm_fence_object_ref + * + * @fence: The fence object. + * + * Return a ref-counted pointer to the fence object indicated by @fence. + */ + +static inline struct ttm_fence_object *ttm_fence_object_ref(struct + ttm_fence_object + *fence) +{ + kref_get(&fence->kref); + return fence; +} + +/** + * ttm_fence_object_unref + * + * @p_fence: Pointer to a ref-counted pinter to a struct ttm_fence_object. + * + * Unreference the fence object pointed to by *(@p_fence), clearing + * *(p_fence). + */ + +extern void ttm_fence_object_unref(struct ttm_fence_object **p_fence); + +/** + * ttm_fence_object_signaled + * + * @fence: Pointer to the struct ttm_fence_object. + * @mask: Type mask to check whether signaled. + * + * This function checks (without waiting) whether the fence object + * pointed to by @fence has signaled the types indicated by @mask, + * and returns 1 if true, 0 if false. This function does NOT perform + * an implicit fence flush. + */ + +extern bool +ttm_fence_object_signaled(struct ttm_fence_object *fence, uint32_t mask); + +/** + * ttm_fence_class + * + * @fence: Pointer to the struct ttm_fence_object. + * + * Convenience function that returns the fence class of a + * struct ttm_fence_object. + */ + +static inline uint32_t ttm_fence_class(const struct ttm_fence_object *fence) +{ + return fence->fence_class; +} + +/** + * ttm_fence_types + * + * @fence: Pointer to the struct ttm_fence_object. + * + * Convenience function that returns the fence types of a + * struct ttm_fence_object. + */ + +static inline uint32_t ttm_fence_types(const struct ttm_fence_object *fence) +{ + return fence->fence_type; +} + +/* + * The functions below are wrappers to the above functions, with + * similar names but with sync_obj omitted. These wrappers are intended + * to be plugged directly into the buffer object driver's sync object + * API, if the driver chooses to use ttm_fence_objects as buffer object + * sync objects. In the prototypes below, a sync_obj is cast to a + * struct ttm_fence_object, whereas a sync_arg is cast to an + * uint32_t representing a fence_type argument. + */ + +extern bool ttm_fence_sync_obj_signaled(void *sync_obj, void *sync_arg); +extern int ttm_fence_sync_obj_wait(void *sync_obj, void *sync_arg, + bool lazy, bool interruptible); +extern int ttm_fence_sync_obj_flush(void *sync_obj, void *sync_arg); +extern void ttm_fence_sync_obj_unref(void **sync_obj); +extern void *ttm_fence_sync_obj_ref(void *sync_obj); + +#endif diff --git a/drivers/staging/gma500/psb_ttm_fence_driver.h b/drivers/staging/gma500/psb_ttm_fence_driver.h new file mode 100644 index 000000000000..233c6ba13121 --- /dev/null +++ b/drivers/staging/gma500/psb_ttm_fence_driver.h @@ -0,0 +1,302 @@ +/************************************************************************** + * + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * All Rights Reserved. + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom + */ +#ifndef _TTM_FENCE_DRIVER_H_ +#define _TTM_FENCE_DRIVER_H_ + +#include +#include +#include +#include "psb_ttm_fence_api.h" +#include "ttm/ttm_memory.h" + +/** @file ttm_fence_driver.h + * + * Definitions needed for a driver implementing the + * ttm_fence subsystem. + */ + +/** + * struct ttm_fence_class_manager: + * + * @wrap_diff: Sequence difference to catch 32-bit wrapping. + * if (seqa - seqb) > @wrap_diff, then seqa < seqb. + * @flush_diff: Sequence difference to trigger fence flush. + * if (cur_seq - seqa) > @flush_diff, then consider fence object with + * seqa as old an needing a flush. + * @sequence_mask: Mask of valid bits in a fence sequence. + * @lock: Lock protecting this struct as well as fence objects + * associated with this struct. + * @ring: Circular sequence-ordered list of fence objects. + * @pending_flush: Fence types currently needing a flush. + * @waiting_types: Fence types that are currently waited for. + * @fence_queue: Queue of waiters on fences belonging to this fence class. + * @highest_waiting_sequence: Sequence number of the fence with highest + * sequence number and that is waited for. + * @latest_queued_sequence: Sequence number of the fence latest queued + * on the ring. + */ + +struct ttm_fence_class_manager { + + /* + * Unprotected constant members. + */ + + uint32_t wrap_diff; + uint32_t flush_diff; + uint32_t sequence_mask; + + /* + * The rwlock protects this structure as well as + * the data in all fence objects belonging to this + * class. This should be OK as most fence objects are + * only read from once they're created. + */ + + rwlock_t lock; + struct list_head ring; + uint32_t pending_flush; + uint32_t waiting_types; + wait_queue_head_t fence_queue; + uint32_t highest_waiting_sequence; + uint32_t latest_queued_sequence; +}; + +/** + * struct ttm_fence_device + * + * @fence_class: Array of fence class managers. + * @num_classes: Array dimension of @fence_class. + * @count: Current number of fence objects for statistics. + * @driver: Driver struct. + * + * Provided in the driver interface so that the driver can derive + * from this struct for its driver_private, and accordingly + * access the driver_private from the fence driver callbacks. + * + * All members except "count" are initialized at creation and + * never touched after that. No protection needed. + * + * This struct is private to the fence implementation and to the fence + * driver callbacks, and may otherwise be used by drivers only to + * obtain the derived device_private object using container_of(). + */ + +struct ttm_fence_device { + struct ttm_mem_global *mem_glob; + struct ttm_fence_class_manager *fence_class; + uint32_t num_classes; + atomic_t count; + const struct ttm_fence_driver *driver; +}; + +/** + * struct ttm_fence_class_init + * + * @wrap_diff: Fence sequence number wrap indicator. If + * (sequence1 - sequence2) > @wrap_diff, then sequence1 is + * considered to be older than sequence2. + * @flush_diff: Fence sequence number flush indicator. + * If a non-completely-signaled fence has a fence sequence number + * sequence1 and (sequence1 - current_emit_sequence) > @flush_diff, + * the fence is considered too old and it will be flushed upon the + * next call of ttm_fence_flush_old(), to make sure no fences with + * stale sequence numbers remains unsignaled. @flush_diff should + * be sufficiently less than @wrap_diff. + * @sequence_mask: Mask with valid bits of the fence sequence + * number set to 1. + * + * This struct is used as input to ttm_fence_device_init. + */ + +struct ttm_fence_class_init { + uint32_t wrap_diff; + uint32_t flush_diff; + uint32_t sequence_mask; +}; + +/** + * struct ttm_fence_driver + * + * @has_irq: Called by a potential waiter. Should return 1 if a + * fence object with indicated parameters is expected to signal + * automatically, and 0 if the fence implementation needs to + * repeatedly call @poll to make it signal. + * @emit: Make sure a fence with the given parameters is + * present in the indicated command stream. Return its sequence number + * in "breadcrumb". + * @poll: Check and report sequences of the given "fence_class" + * that have signaled "types" + * @flush: Make sure that the types indicated by the bitfield + * ttm_fence_class_manager::pending_flush will eventually + * signal. These bits have been put together using the + * result from the needed_flush function described below. + * @needed_flush: Given the fence_class and fence_types indicated by + * "fence", and the last received fence sequence of this + * fence class, indicate what types need a fence flush to + * signal. Return as a bitfield. + * @wait: Set to non-NULL if the driver wants to override the fence + * wait implementation. Return 0 on success, -EBUSY on failure, + * and -ERESTART if interruptible and a signal is pending. + * @signaled: Driver callback that is called whenever a + * ttm_fence_object::signaled_types has changed status. + * This function is called from atomic context, + * with the ttm_fence_class_manager::lock held in write mode. + * @lockup: Driver callback that is called whenever a wait has exceeded + * the lifetime of a fence object. + * If there is a GPU lockup, + * this function should, if possible, reset the GPU, + * call the ttm_fence_handler with an error status, and + * return. If no lockup was detected, simply extend the + * fence timeout_jiffies and return. The driver might + * want to protect the lockup check with a mutex and cache a + * non-locked-up status for a while to avoid an excessive + * amount of lockup checks from every waiting thread. + */ + +struct ttm_fence_driver { + bool (*has_irq) (struct ttm_fence_device *fdev, + uint32_t fence_class, uint32_t flags); + int (*emit) (struct ttm_fence_device *fdev, + uint32_t fence_class, + uint32_t flags, + uint32_t *breadcrumb, unsigned long *timeout_jiffies); + void (*flush) (struct ttm_fence_device *fdev, uint32_t fence_class); + void (*poll) (struct ttm_fence_device *fdev, + uint32_t fence_class, uint32_t types); + uint32_t(*needed_flush) + (struct ttm_fence_object *fence); + int (*wait) (struct ttm_fence_object *fence, bool lazy, + bool interruptible, uint32_t mask); + void (*signaled) (struct ttm_fence_object *fence); + void (*lockup) (struct ttm_fence_object *fence, uint32_t fence_types); +}; + +/** + * function ttm_fence_device_init + * + * @num_classes: Number of fence classes for this fence implementation. + * @mem_global: Pointer to the global memory accounting info. + * @fdev: Pointer to an uninitialised struct ttm_fence_device. + * @init: Array of initialization info for each fence class. + * @replicate_init: Use the first @init initialization info for all classes. + * @driver: Driver callbacks. + * + * Initialize a struct ttm_fence_driver structure. Returns -ENOMEM if + * out-of-memory. Otherwise returns 0. + */ +extern int +ttm_fence_device_init(int num_classes, + struct ttm_mem_global *mem_glob, + struct ttm_fence_device *fdev, + const struct ttm_fence_class_init *init, + bool replicate_init, + const struct ttm_fence_driver *driver); + +/** + * function ttm_fence_device_release + * + * @fdev: Pointer to the fence device. + * + * Release all resources held by a fence device. Note that before + * this function is called, the caller must have made sure all fence + * objects belonging to this fence device are completely signaled. + */ + +extern void ttm_fence_device_release(struct ttm_fence_device *fdev); + +/** + * ttm_fence_handler - the fence handler. + * + * @fdev: Pointer to the fence device. + * @fence_class: Fence class that signals. + * @sequence: Signaled sequence. + * @type: Types that signal. + * @error: Error from the engine. + * + * This function signals all fences with a sequence previous to the + * @sequence argument, and belonging to @fence_class. The signaled fence + * types are provided in @type. If error is non-zero, the error member + * of the fence with sequence = @sequence is set to @error. This value + * may be reported back to user-space, indicating, for example an illegal + * 3D command or illegal mpeg data. + * + * This function is typically called from the driver::poll method when the + * command sequence preceding the fence marker has executed. It should be + * called with the ttm_fence_class_manager::lock held in write mode and + * may be called from interrupt context. + */ + +extern void +ttm_fence_handler(struct ttm_fence_device *fdev, + uint32_t fence_class, + uint32_t sequence, uint32_t type, uint32_t error); + +/** + * ttm_fence_driver_from_dev + * + * @fdev: The ttm fence device. + * + * Returns a pointer to the fence driver struct. + */ + +static inline const struct ttm_fence_driver *ttm_fence_driver_from_dev( + struct ttm_fence_device *fdev) +{ + return fdev->driver; +} + +/** + * ttm_fence_driver + * + * @fence: Pointer to a ttm fence object. + * + * Returns a pointer to the fence driver struct. + */ + +static inline const struct ttm_fence_driver *ttm_fence_driver(struct + ttm_fence_object + *fence) +{ + return ttm_fence_driver_from_dev(fence->fdev); +} + +/** + * ttm_fence_fc + * + * @fence: Pointer to a ttm fence object. + * + * Returns a pointer to the struct ttm_fence_class_manager for the + * fence class of @fence. + */ + +static inline struct ttm_fence_class_manager *ttm_fence_fc(struct + ttm_fence_object + *fence) +{ + return &fence->fdev->fence_class[fence->fence_class]; +} + +#endif diff --git a/drivers/staging/gma500/psb_ttm_fence_user.c b/drivers/staging/gma500/psb_ttm_fence_user.c new file mode 100644 index 000000000000..36f974fc607d --- /dev/null +++ b/drivers/staging/gma500/psb_ttm_fence_user.c @@ -0,0 +1,237 @@ +/************************************************************************** + * + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * All Rights Reserved. + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom + */ + +#include +#include "psb_ttm_fence_user.h" +#include "ttm/ttm_object.h" +#include "psb_ttm_fence_driver.h" +#include "psb_ttm_userobj_api.h" + +/** + * struct ttm_fence_user_object + * + * @base: The base object used for user-space visibility and refcounting. + * + * @fence: The fence object itself. + * + */ + +struct ttm_fence_user_object { + struct ttm_base_object base; + struct ttm_fence_object fence; +}; + +static struct ttm_fence_user_object *ttm_fence_user_object_lookup( + struct ttm_object_file *tfile, + uint32_t handle) +{ + struct ttm_base_object *base; + + base = ttm_base_object_lookup(tfile, handle); + if (unlikely(base == NULL)) { + printk(KERN_ERR "Invalid fence handle 0x%08lx\n", + (unsigned long)handle); + return NULL; + } + + if (unlikely(base->object_type != ttm_fence_type)) { + ttm_base_object_unref(&base); + printk(KERN_ERR "Invalid fence handle 0x%08lx\n", + (unsigned long)handle); + return NULL; + } + + return container_of(base, struct ttm_fence_user_object, base); +} + +/* + * The fence object destructor. + */ + +static void ttm_fence_user_destroy(struct ttm_fence_object *fence) +{ + struct ttm_fence_user_object *ufence = + container_of(fence, struct ttm_fence_user_object, fence); + + ttm_mem_global_free(fence->fdev->mem_glob, sizeof(*ufence)); + kfree(ufence); +} + +/* + * The base object destructor. We basically unly unreference the + * attached fence object. + */ + +static void ttm_fence_user_release(struct ttm_base_object **p_base) +{ + struct ttm_fence_user_object *ufence; + struct ttm_base_object *base = *p_base; + struct ttm_fence_object *fence; + + *p_base = NULL; + + if (unlikely(base == NULL)) + return; + + ufence = container_of(base, struct ttm_fence_user_object, base); + fence = &ufence->fence; + ttm_fence_object_unref(&fence); +} + +int +ttm_fence_user_create(struct ttm_fence_device *fdev, + struct ttm_object_file *tfile, + uint32_t fence_class, + uint32_t fence_types, + uint32_t create_flags, + struct ttm_fence_object **fence, + uint32_t *user_handle) +{ + int ret; + struct ttm_fence_object *tmp; + struct ttm_fence_user_object *ufence; + + ret = ttm_mem_global_alloc(fdev->mem_glob, + sizeof(*ufence), + false, + false); + if (unlikely(ret != 0)) + return -ENOMEM; + + ufence = kmalloc(sizeof(*ufence), GFP_KERNEL); + if (unlikely(ufence == NULL)) { + ttm_mem_global_free(fdev->mem_glob, sizeof(*ufence)); + return -ENOMEM; + } + + ret = ttm_fence_object_init(fdev, + fence_class, + fence_types, create_flags, + &ttm_fence_user_destroy, &ufence->fence); + + if (unlikely(ret != 0)) + goto out_err0; + + /* + * One fence ref is held by the fence ptr we return. + * The other one by the base object. Need to up the + * fence refcount before we publish this object to + * user-space. + */ + + tmp = ttm_fence_object_ref(&ufence->fence); + ret = ttm_base_object_init(tfile, &ufence->base, + false, ttm_fence_type, + &ttm_fence_user_release, NULL); + + if (unlikely(ret != 0)) + goto out_err1; + + *fence = &ufence->fence; + *user_handle = ufence->base.hash.key; + + return 0; +out_err1: + ttm_fence_object_unref(&tmp); + tmp = &ufence->fence; + ttm_fence_object_unref(&tmp); + return ret; +out_err0: + ttm_mem_global_free(fdev->mem_glob, sizeof(*ufence)); + kfree(ufence); + return ret; +} + +int ttm_fence_signaled_ioctl(struct ttm_object_file *tfile, void *data) +{ + int ret; + union ttm_fence_signaled_arg *arg = data; + struct ttm_fence_object *fence; + struct ttm_fence_info info; + struct ttm_fence_user_object *ufence; + struct ttm_base_object *base; + ret = 0; + + ufence = ttm_fence_user_object_lookup(tfile, arg->req.handle); + if (unlikely(ufence == NULL)) + return -EINVAL; + + fence = &ufence->fence; + + if (arg->req.flush) { + ret = ttm_fence_object_flush(fence, arg->req.fence_type); + if (unlikely(ret != 0)) + goto out; + } + + info = ttm_fence_get_info(fence); + arg->rep.signaled_types = info.signaled_types; + arg->rep.fence_error = info.error; + +out: + base = &ufence->base; + ttm_base_object_unref(&base); + return ret; +} + +int ttm_fence_finish_ioctl(struct ttm_object_file *tfile, void *data) +{ + int ret; + union ttm_fence_finish_arg *arg = data; + struct ttm_fence_user_object *ufence; + struct ttm_base_object *base; + struct ttm_fence_object *fence; + ret = 0; + + ufence = ttm_fence_user_object_lookup(tfile, arg->req.handle); + if (unlikely(ufence == NULL)) + return -EINVAL; + + fence = &ufence->fence; + + ret = ttm_fence_object_wait(fence, + arg->req.mode & TTM_FENCE_FINISH_MODE_LAZY, + true, arg->req.fence_type); + if (likely(ret == 0)) { + struct ttm_fence_info info = ttm_fence_get_info(fence); + + arg->rep.signaled_types = info.signaled_types; + arg->rep.fence_error = info.error; + } + + base = &ufence->base; + ttm_base_object_unref(&base); + + return ret; +} + +int ttm_fence_unref_ioctl(struct ttm_object_file *tfile, void *data) +{ + struct ttm_fence_unref_arg *arg = data; + int ret = 0; + + ret = ttm_ref_object_base_unref(tfile, arg->handle, ttm_fence_type); + return ret; +} diff --git a/drivers/staging/gma500/psb_ttm_fence_user.h b/drivers/staging/gma500/psb_ttm_fence_user.h new file mode 100644 index 000000000000..ee95e6a7db09 --- /dev/null +++ b/drivers/staging/gma500/psb_ttm_fence_user.h @@ -0,0 +1,140 @@ +/************************************************************************** + * + * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * All Rights Reserved. + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + **************************************************************************/ +/* + * Authors + * Thomas Hellström + */ + +#ifndef TTM_FENCE_USER_H +#define TTM_FENCE_USER_H + +#if !defined(__KERNEL__) && !defined(_KERNEL) +#include +#endif + +#define TTM_FENCE_MAJOR 0 +#define TTM_FENCE_MINOR 1 +#define TTM_FENCE_PL 0 +#define TTM_FENCE_DATE "080819" + +/** + * struct ttm_fence_signaled_req + * + * @handle: Handle to the fence object. Input. + * + * @fence_type: Fence types we want to flush. Input. + * + * @flush: Boolean. Flush the indicated fence_types. Input. + * + * Argument to the TTM_FENCE_SIGNALED ioctl. + */ + +struct ttm_fence_signaled_req { + uint32_t handle; + uint32_t fence_type; + int32_t flush; + uint32_t pad64; +}; + +/** + * struct ttm_fence_rep + * + * @signaled_types: Fence type that has signaled. + * + * @fence_error: Command execution error. + * Hardware errors that are consequences of the execution + * of the command stream preceding the fence are reported + * here. + * + * Output argument to the TTM_FENCE_SIGNALED and + * TTM_FENCE_FINISH ioctls. + */ + +struct ttm_fence_rep { + uint32_t signaled_types; + uint32_t fence_error; +}; + +union ttm_fence_signaled_arg { + struct ttm_fence_signaled_req req; + struct ttm_fence_rep rep; +}; + +/* + * Waiting mode flags for the TTM_FENCE_FINISH ioctl. + * + * TTM_FENCE_FINISH_MODE_LAZY: Allow for sleeps during polling + * wait. + * + * TTM_FENCE_FINISH_MODE_NO_BLOCK: Don't block waiting for GPU, + * but return -EBUSY if the buffer is busy. + */ + +#define TTM_FENCE_FINISH_MODE_LAZY (1 << 0) +#define TTM_FENCE_FINISH_MODE_NO_BLOCK (1 << 1) + +/** + * struct ttm_fence_finish_req + * + * @handle: Handle to the fence object. Input. + * + * @fence_type: Fence types we want to finish. + * + * @mode: Wait mode. + * + * Input to the TTM_FENCE_FINISH ioctl. + */ + +struct ttm_fence_finish_req { + uint32_t handle; + uint32_t fence_type; + uint32_t mode; + uint32_t pad64; +}; + +union ttm_fence_finish_arg { + struct ttm_fence_finish_req req; + struct ttm_fence_rep rep; +}; + +/** + * struct ttm_fence_unref_arg + * + * @handle: Handle to the fence object. + * + * Argument to the TTM_FENCE_UNREF ioctl. + */ + +struct ttm_fence_unref_arg { + uint32_t handle; + uint32_t pad64; +}; + +/* + * Ioctl offsets frome extenstion start. + */ + +#define TTM_FENCE_SIGNALED 0x01 +#define TTM_FENCE_FINISH 0x02 +#define TTM_FENCE_UNREF 0x03 + +#endif diff --git a/drivers/staging/gma500/psb_ttm_glue.c b/drivers/staging/gma500/psb_ttm_glue.c new file mode 100644 index 000000000000..d1d965e69ecd --- /dev/null +++ b/drivers/staging/gma500/psb_ttm_glue.c @@ -0,0 +1,349 @@ +/************************************************************************** + * Copyright (c) 2008, Intel Corporation. + * All Rights Reserved. + * Copyright (c) 2008, Tungsten Graphics Inc. Cedar Park, TX., USA. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + **************************************************************************/ + + +#include +#include "psb_drv.h" +#include "psb_ttm_userobj_api.h" +#include + + +static struct vm_operations_struct psb_ttm_vm_ops; + +/** + * NOTE: driver_private of drm_file is now a struct psb_file_data struct + * pPriv in struct psb_file_data contains the original psb_fpriv; + */ +int psb_open(struct inode *inode, struct file *filp) +{ + struct drm_file *file_priv; + struct drm_psb_private *dev_priv; + struct psb_fpriv *psb_fp; + struct psb_file_data *pvr_file_priv; + int ret; + + DRM_DEBUG("\n"); + + ret = drm_open(inode, filp); + if (unlikely(ret)) + return ret; + + psb_fp = kzalloc(sizeof(*psb_fp), GFP_KERNEL); + + if (unlikely(psb_fp == NULL)) + goto out_err0; + + file_priv = (struct drm_file *) filp->private_data; + dev_priv = psb_priv(file_priv->minor->dev); + + DRM_DEBUG("is_master %d\n", file_priv->is_master ? 1 : 0); + + psb_fp->tfile = ttm_object_file_init(dev_priv->tdev, + PSB_FILE_OBJECT_HASH_ORDER); + if (unlikely(psb_fp->tfile == NULL)) + goto out_err1; + + pvr_file_priv = (struct psb_file_data *)file_priv->driver_priv; + if (!pvr_file_priv) { + DRM_ERROR("drm file private is NULL\n"); + goto out_err1; + } + + pvr_file_priv->priv = psb_fp; + if (unlikely(dev_priv->bdev.dev_mapping == NULL)) + dev_priv->bdev.dev_mapping = dev_priv->dev->dev_mapping; + + return 0; + +out_err1: + kfree(psb_fp); +out_err0: + (void) drm_release(inode, filp); + return ret; +} + +int psb_release(struct inode *inode, struct file *filp) +{ + struct drm_file *file_priv; + struct psb_fpriv *psb_fp; + struct drm_psb_private *dev_priv; + int ret; + file_priv = (struct drm_file *) filp->private_data; + psb_fp = psb_fpriv(file_priv); + dev_priv = psb_priv(file_priv->minor->dev); + + ttm_object_file_release(&psb_fp->tfile); + kfree(psb_fp); + + ret = drm_release(inode, filp); + + return ret; +} + +int psb_fence_signaled_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + + return ttm_fence_signaled_ioctl(psb_fpriv(file_priv)->tfile, data); +} + +int psb_fence_finish_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + return ttm_fence_finish_ioctl(psb_fpriv(file_priv)->tfile, data); +} + +int psb_fence_unref_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + return ttm_fence_unref_ioctl(psb_fpriv(file_priv)->tfile, data); +} + +int psb_pl_waitidle_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + return ttm_pl_waitidle_ioctl(psb_fpriv(file_priv)->tfile, data); +} + +int psb_pl_setstatus_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + return ttm_pl_setstatus_ioctl(psb_fpriv(file_priv)->tfile, + &psb_priv(dev)->ttm_lock, data); + +} + +int psb_pl_synccpu_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + return ttm_pl_synccpu_ioctl(psb_fpriv(file_priv)->tfile, data); +} + +int psb_pl_unref_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + return ttm_pl_unref_ioctl(psb_fpriv(file_priv)->tfile, data); + +} + +int psb_pl_reference_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + return ttm_pl_reference_ioctl(psb_fpriv(file_priv)->tfile, data); + +} + +int psb_pl_create_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_psb_private *dev_priv = psb_priv(dev); + + return ttm_pl_create_ioctl(psb_fpriv(file_priv)->tfile, + &dev_priv->bdev, &dev_priv->ttm_lock, data); + +} + +int psb_pl_ub_create_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_psb_private *dev_priv = psb_priv(dev); + + return ttm_pl_ub_create_ioctl(psb_fpriv(file_priv)->tfile, + &dev_priv->bdev, &dev_priv->ttm_lock, data); + +} +/** + * psb_ttm_fault - Wrapper around the ttm fault method. + * + * @vma: The struct vm_area_struct as in the vm fault() method. + * @vmf: The struct vm_fault as in the vm fault() method. + * + * Since ttm_fault() will reserve buffers while faulting, + * we need to take the ttm read lock around it, as this driver + * relies on the ttm_lock in write mode to exclude all threads from + * reserving and thus validating buffers in aperture- and memory shortage + * situations. + */ + +static int psb_ttm_fault(struct vm_area_struct *vma, + struct vm_fault *vmf) +{ + struct ttm_buffer_object *bo = (struct ttm_buffer_object *) + vma->vm_private_data; + struct drm_psb_private *dev_priv = + container_of(bo->bdev, struct drm_psb_private, bdev); + int ret; + + ret = ttm_read_lock(&dev_priv->ttm_lock, true); + if (unlikely(ret != 0)) + return VM_FAULT_NOPAGE; + + ret = dev_priv->ttm_vm_ops->fault(vma, vmf); + + ttm_read_unlock(&dev_priv->ttm_lock); + return ret; +} + +/** + * if vm_pgoff < DRM_PSB_FILE_PAGE_OFFSET call directly to + * PVRMMap + */ +int psb_mmap(struct file *filp, struct vm_area_struct *vma) +{ + struct drm_file *file_priv; + struct drm_psb_private *dev_priv; + int ret; + + if (vma->vm_pgoff < DRM_PSB_FILE_PAGE_OFFSET || + vma->vm_pgoff > 2 * DRM_PSB_FILE_PAGE_OFFSET) +#if 0 /* FIXMEAC */ + return PVRMMap(filp, vma); +#else + return -EINVAL; +#endif + + file_priv = (struct drm_file *) filp->private_data; + dev_priv = psb_priv(file_priv->minor->dev); + + ret = ttm_bo_mmap(filp, vma, &dev_priv->bdev); + if (unlikely(ret != 0)) + return ret; + + if (unlikely(dev_priv->ttm_vm_ops == NULL)) { + dev_priv->ttm_vm_ops = (struct vm_operations_struct *) + vma->vm_ops; + psb_ttm_vm_ops = *vma->vm_ops; + psb_ttm_vm_ops.fault = &psb_ttm_fault; + } + + vma->vm_ops = &psb_ttm_vm_ops; + + return 0; +} +/* +ssize_t psb_ttm_write(struct file *filp, const char __user *buf, + size_t count, loff_t *f_pos) +{ + struct drm_file *file_priv = (struct drm_file *)filp->private_data; + struct drm_psb_private *dev_priv = psb_priv(file_priv->minor->dev); + + return ttm_bo_io(&dev_priv->bdev, filp, buf, NULL, count, f_pos, 1); +} + +ssize_t psb_ttm_read(struct file *filp, char __user *buf, + size_t count, loff_t *f_pos) +{ + struct drm_file *file_priv = (struct drm_file *)filp->private_data; + struct drm_psb_private *dev_priv = psb_priv(file_priv->minor->dev); + + return ttm_bo_io(&dev_priv->bdev, filp, NULL, buf, count, f_pos, 1); +} +*/ +int psb_verify_access(struct ttm_buffer_object *bo, + struct file *filp) +{ + struct drm_file *file_priv = (struct drm_file *)filp->private_data; + + if (capable(CAP_SYS_ADMIN)) + return 0; + + if (unlikely(!file_priv->authenticated)) + return -EPERM; + + return ttm_pl_verify_access(bo, psb_fpriv(file_priv)->tfile); +} + +static int psb_ttm_mem_global_init(struct drm_global_reference *ref) +{ + return ttm_mem_global_init(ref->object); +} + +static void psb_ttm_mem_global_release(struct drm_global_reference *ref) +{ + ttm_mem_global_release(ref->object); +} + +int psb_ttm_global_init(struct drm_psb_private *dev_priv) +{ + struct drm_global_reference *global_ref; + int ret; + + global_ref = &dev_priv->mem_global_ref; + global_ref->global_type = DRM_GLOBAL_TTM_MEM; + global_ref->size = sizeof(struct ttm_mem_global); + global_ref->init = &psb_ttm_mem_global_init; + global_ref->release = &psb_ttm_mem_global_release; + + ret = drm_global_item_ref(global_ref); + if (unlikely(ret != 0)) { + DRM_ERROR("Failed referencing a global TTM memory object.\n"); + return ret; + } + + dev_priv->bo_global_ref.mem_glob = dev_priv->mem_global_ref.object; + global_ref = &dev_priv->bo_global_ref.ref; + global_ref->global_type = DRM_GLOBAL_TTM_BO; + global_ref->size = sizeof(struct ttm_bo_global); + global_ref->init = &ttm_bo_global_init; + global_ref->release = &ttm_bo_global_release; + ret = drm_global_item_ref(global_ref); + if (ret != 0) { + DRM_ERROR("Failed setting up TTM BO subsystem.\n"); + drm_global_item_unref(global_ref); + return ret; + } + return 0; +} + +void psb_ttm_global_release(struct drm_psb_private *dev_priv) +{ + drm_global_item_unref(&dev_priv->mem_global_ref); +} + +int psb_getpageaddrs_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_psb_getpageaddrs_arg *arg = data; + struct ttm_buffer_object *bo; + struct ttm_tt *ttm; + struct page **tt_pages; + unsigned long i, num_pages; + unsigned long *p = arg->page_addrs; + int ret = 0; + + bo = ttm_buffer_object_lookup(psb_fpriv(file_priv)->tfile, + arg->handle); + if (unlikely(bo == NULL)) { + printk(KERN_ERR + "Could not find buffer object for getpageaddrs.\n"); + return -EINVAL; + } + + arg->gtt_offset = bo->offset; + ttm = bo->ttm; + num_pages = ttm->num_pages; + tt_pages = ttm->pages; + + for (i = 0; i < num_pages; i++) + p[i] = (unsigned long)page_to_phys(tt_pages[i]); + + return ret; +} diff --git a/drivers/staging/gma500/psb_ttm_placement_user.c b/drivers/staging/gma500/psb_ttm_placement_user.c new file mode 100644 index 000000000000..272b397982ed --- /dev/null +++ b/drivers/staging/gma500/psb_ttm_placement_user.c @@ -0,0 +1,628 @@ +/************************************************************************** + * + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom + */ + +#include "psb_ttm_placement_user.h" +#include "ttm/ttm_bo_driver.h" +#include "ttm/ttm_object.h" +#include "psb_ttm_userobj_api.h" +#include "ttm/ttm_lock.h" +#include +#include + +struct ttm_bo_user_object { + struct ttm_base_object base; + struct ttm_buffer_object bo; +}; + +static size_t pl_bo_size; + +static uint32_t psb_busy_prios[] = { + TTM_PL_TT, + TTM_PL_PRIV0, /* CI */ + TTM_PL_PRIV2, /* RAR */ + TTM_PL_PRIV1, /* DRM_PSB_MEM_MMU */ + TTM_PL_SYSTEM +}; + +static const struct ttm_placement default_placement = { + 0, 0, 0, NULL, 5, psb_busy_prios +}; + +static size_t ttm_pl_size(struct ttm_bo_device *bdev, unsigned long num_pages) +{ + size_t page_array_size = + (num_pages * sizeof(void *) + PAGE_SIZE - 1) & PAGE_MASK; + + if (unlikely(pl_bo_size == 0)) { + pl_bo_size = bdev->glob->ttm_bo_extra_size + + ttm_round_pot(sizeof(struct ttm_bo_user_object)); + } + + return bdev->glob->ttm_bo_size + 2 * page_array_size; +} + +static struct ttm_bo_user_object *ttm_bo_user_lookup(struct ttm_object_file + *tfile, uint32_t handle) +{ + struct ttm_base_object *base; + + base = ttm_base_object_lookup(tfile, handle); + if (unlikely(base == NULL)) { + printk(KERN_ERR "Invalid buffer object handle 0x%08lx.\n", + (unsigned long)handle); + return NULL; + } + + if (unlikely(base->object_type != ttm_buffer_type)) { + ttm_base_object_unref(&base); + printk(KERN_ERR "Invalid buffer object handle 0x%08lx.\n", + (unsigned long)handle); + return NULL; + } + + return container_of(base, struct ttm_bo_user_object, base); +} + +struct ttm_buffer_object *ttm_buffer_object_lookup(struct ttm_object_file + *tfile, uint32_t handle) +{ + struct ttm_bo_user_object *user_bo; + struct ttm_base_object *base; + + user_bo = ttm_bo_user_lookup(tfile, handle); + if (unlikely(user_bo == NULL)) + return NULL; + + (void)ttm_bo_reference(&user_bo->bo); + base = &user_bo->base; + ttm_base_object_unref(&base); + return &user_bo->bo; +} + +static void ttm_bo_user_destroy(struct ttm_buffer_object *bo) +{ + struct ttm_bo_user_object *user_bo = + container_of(bo, struct ttm_bo_user_object, bo); + + ttm_mem_global_free(bo->glob->mem_glob, bo->acc_size); + kfree(user_bo); +} + +static void ttm_bo_user_release(struct ttm_base_object **p_base) +{ + struct ttm_bo_user_object *user_bo; + struct ttm_base_object *base = *p_base; + struct ttm_buffer_object *bo; + + *p_base = NULL; + + if (unlikely(base == NULL)) + return; + + user_bo = container_of(base, struct ttm_bo_user_object, base); + bo = &user_bo->bo; + ttm_bo_unref(&bo); +} + +static void ttm_bo_user_ref_release(struct ttm_base_object *base, + enum ttm_ref_type ref_type) +{ + struct ttm_bo_user_object *user_bo = + container_of(base, struct ttm_bo_user_object, base); + struct ttm_buffer_object *bo = &user_bo->bo; + + switch (ref_type) { + case TTM_REF_SYNCCPU_WRITE: + ttm_bo_synccpu_write_release(bo); + break; + default: + BUG(); + } +} + +static void ttm_pl_fill_rep(struct ttm_buffer_object *bo, + struct ttm_pl_rep *rep) +{ + struct ttm_bo_user_object *user_bo = + container_of(bo, struct ttm_bo_user_object, bo); + + rep->gpu_offset = bo->offset; + rep->bo_size = bo->num_pages << PAGE_SHIFT; + rep->map_handle = bo->addr_space_offset; + rep->placement = bo->mem.placement; + rep->handle = user_bo->base.hash.key; + rep->sync_object_arg = (uint32_t) (unsigned long)bo->sync_obj_arg; +} + +/* FIXME Copy from upstream TTM */ +static inline size_t ttm_bo_size(struct ttm_bo_global *glob, + unsigned long num_pages) +{ + size_t page_array_size = (num_pages * sizeof(void *) + PAGE_SIZE - 1) & + PAGE_MASK; + + return glob->ttm_bo_size + 2 * page_array_size; +} + +/* FIXME Copy from upstream TTM "ttm_bo_create", upstream TTM does not + export this, so copy it here */ +static int ttm_bo_create_private(struct ttm_bo_device *bdev, + unsigned long size, + enum ttm_bo_type type, + struct ttm_placement *placement, + uint32_t page_alignment, + unsigned long buffer_start, + bool interruptible, + struct file *persistant_swap_storage, + struct ttm_buffer_object **p_bo) +{ + struct ttm_buffer_object *bo; + struct ttm_mem_global *mem_glob = bdev->glob->mem_glob; + int ret; + + size_t acc_size = + ttm_bo_size(bdev->glob, (size + PAGE_SIZE - 1) >> PAGE_SHIFT); + ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false); + if (unlikely(ret != 0)) + return ret; + + bo = kzalloc(sizeof(*bo), GFP_KERNEL); + + if (unlikely(bo == NULL)) { + ttm_mem_global_free(mem_glob, acc_size); + return -ENOMEM; + } + + ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment, + buffer_start, interruptible, + persistant_swap_storage, acc_size, NULL); + if (likely(ret == 0)) + *p_bo = bo; + + return ret; +} + +int psb_ttm_bo_check_placement(struct ttm_buffer_object *bo, + struct ttm_placement *placement) +{ + int i; + + for (i = 0; i < placement->num_placement; i++) { + if (!capable(CAP_SYS_ADMIN)) { + if (placement->placement[i] & TTM_PL_FLAG_NO_EVICT) { + printk(KERN_ERR TTM_PFX "Need to be root to " + "modify NO_EVICT status.\n"); + return -EINVAL; + } + } + } + for (i = 0; i < placement->num_busy_placement; i++) { + if (!capable(CAP_SYS_ADMIN)) { + if (placement->busy_placement[i] + & TTM_PL_FLAG_NO_EVICT) { + printk(KERN_ERR TTM_PFX "Need to be root to modify NO_EVICT status.\n"); + return -EINVAL; + } + } + } + return 0; +} + +int ttm_buffer_object_create(struct ttm_bo_device *bdev, + unsigned long size, + enum ttm_bo_type type, + uint32_t flags, + uint32_t page_alignment, + unsigned long buffer_start, + bool interruptible, + struct file *persistant_swap_storage, + struct ttm_buffer_object **p_bo) +{ + struct ttm_placement placement = default_placement; + int ret; + + if ((flags & TTM_PL_MASK_CACHING) == 0) + flags |= TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED; + + placement.num_placement = 1; + placement.placement = &flags; + + ret = ttm_bo_create_private(bdev, + size, + type, + &placement, + page_alignment, + buffer_start, + interruptible, + persistant_swap_storage, + p_bo); + + return ret; +} + + +int ttm_pl_create_ioctl(struct ttm_object_file *tfile, + struct ttm_bo_device *bdev, + struct ttm_lock *lock, void *data) +{ + union ttm_pl_create_arg *arg = data; + struct ttm_pl_create_req *req = &arg->req; + struct ttm_pl_rep *rep = &arg->rep; + struct ttm_buffer_object *bo; + struct ttm_buffer_object *tmp; + struct ttm_bo_user_object *user_bo; + uint32_t flags; + int ret = 0; + struct ttm_mem_global *mem_glob = bdev->glob->mem_glob; + struct ttm_placement placement = default_placement; + size_t acc_size = + ttm_pl_size(bdev, (req->size + PAGE_SIZE - 1) >> PAGE_SHIFT); + ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false); + if (unlikely(ret != 0)) + return ret; + + flags = req->placement; + user_bo = kzalloc(sizeof(*user_bo), GFP_KERNEL); + if (unlikely(user_bo == NULL)) { + ttm_mem_global_free(mem_glob, acc_size); + return -ENOMEM; + } + + bo = &user_bo->bo; + ret = ttm_read_lock(lock, true); + if (unlikely(ret != 0)) { + ttm_mem_global_free(mem_glob, acc_size); + kfree(user_bo); + return ret; + } + + placement.num_placement = 1; + placement.placement = &flags; + + if ((flags & TTM_PL_MASK_CACHING) == 0) + flags |= TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED; + + ret = ttm_bo_init(bdev, bo, req->size, + ttm_bo_type_device, &placement, + req->page_alignment, 0, true, + NULL, acc_size, &ttm_bo_user_destroy); + ttm_read_unlock(lock); + + /* + * Note that the ttm_buffer_object_init function + * would've called the destroy function on failure!! + */ + + if (unlikely(ret != 0)) + goto out; + + tmp = ttm_bo_reference(bo); + ret = ttm_base_object_init(tfile, &user_bo->base, + flags & TTM_PL_FLAG_SHARED, + ttm_buffer_type, + &ttm_bo_user_release, + &ttm_bo_user_ref_release); + if (unlikely(ret != 0)) + goto out_err; + + ttm_pl_fill_rep(bo, rep); + ttm_bo_unref(&bo); +out: + return 0; +out_err: + ttm_bo_unref(&tmp); + ttm_bo_unref(&bo); + return ret; +} + +int ttm_pl_ub_create_ioctl(struct ttm_object_file *tfile, + struct ttm_bo_device *bdev, + struct ttm_lock *lock, void *data) +{ + union ttm_pl_create_ub_arg *arg = data; + struct ttm_pl_create_ub_req *req = &arg->req; + struct ttm_pl_rep *rep = &arg->rep; + struct ttm_buffer_object *bo; + struct ttm_buffer_object *tmp; + struct ttm_bo_user_object *user_bo; + uint32_t flags; + int ret = 0; + struct ttm_mem_global *mem_glob = bdev->glob->mem_glob; + struct ttm_placement placement = default_placement; + size_t acc_size = + ttm_pl_size(bdev, (req->size + PAGE_SIZE - 1) >> PAGE_SHIFT); + ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false); + if (unlikely(ret != 0)) + return ret; + + flags = req->placement; + user_bo = kzalloc(sizeof(*user_bo), GFP_KERNEL); + if (unlikely(user_bo == NULL)) { + ttm_mem_global_free(mem_glob, acc_size); + return -ENOMEM; + } + ret = ttm_read_lock(lock, true); + if (unlikely(ret != 0)) { + ttm_mem_global_free(mem_glob, acc_size); + kfree(user_bo); + return ret; + } + bo = &user_bo->bo; + + placement.num_placement = 1; + placement.placement = &flags; + + ret = ttm_bo_init(bdev, + bo, + req->size, + ttm_bo_type_user, + &placement, + req->page_alignment, + req->user_address, + true, + NULL, + acc_size, + &ttm_bo_user_destroy); + + /* + * Note that the ttm_buffer_object_init function + * would've called the destroy function on failure!! + */ + ttm_read_unlock(lock); + if (unlikely(ret != 0)) + goto out; + + tmp = ttm_bo_reference(bo); + ret = ttm_base_object_init(tfile, &user_bo->base, + flags & TTM_PL_FLAG_SHARED, + ttm_buffer_type, + &ttm_bo_user_release, + &ttm_bo_user_ref_release); + if (unlikely(ret != 0)) + goto out_err; + + ttm_pl_fill_rep(bo, rep); + ttm_bo_unref(&bo); +out: + return 0; +out_err: + ttm_bo_unref(&tmp); + ttm_bo_unref(&bo); + return ret; +} + +int ttm_pl_reference_ioctl(struct ttm_object_file *tfile, void *data) +{ + union ttm_pl_reference_arg *arg = data; + struct ttm_pl_rep *rep = &arg->rep; + struct ttm_bo_user_object *user_bo; + struct ttm_buffer_object *bo; + struct ttm_base_object *base; + int ret; + + user_bo = ttm_bo_user_lookup(tfile, arg->req.handle); + if (unlikely(user_bo == NULL)) { + printk(KERN_ERR "Could not reference buffer object.\n"); + return -EINVAL; + } + + bo = &user_bo->bo; + ret = ttm_ref_object_add(tfile, &user_bo->base, TTM_REF_USAGE, NULL); + if (unlikely(ret != 0)) { + printk(KERN_ERR + "Could not add a reference to buffer object.\n"); + goto out; + } + + ttm_pl_fill_rep(bo, rep); + +out: + base = &user_bo->base; + ttm_base_object_unref(&base); + return ret; +} + +int ttm_pl_unref_ioctl(struct ttm_object_file *tfile, void *data) +{ + struct ttm_pl_reference_req *arg = data; + + return ttm_ref_object_base_unref(tfile, arg->handle, TTM_REF_USAGE); +} + +int ttm_pl_synccpu_ioctl(struct ttm_object_file *tfile, void *data) +{ + struct ttm_pl_synccpu_arg *arg = data; + struct ttm_bo_user_object *user_bo; + struct ttm_buffer_object *bo; + struct ttm_base_object *base; + bool existed; + int ret; + + switch (arg->op) { + case TTM_PL_SYNCCPU_OP_GRAB: + user_bo = ttm_bo_user_lookup(tfile, arg->handle); + if (unlikely(user_bo == NULL)) { + printk(KERN_ERR + "Could not find buffer object for synccpu.\n"); + return -EINVAL; + } + bo = &user_bo->bo; + base = &user_bo->base; + ret = ttm_bo_synccpu_write_grab(bo, + arg->access_mode & + TTM_PL_SYNCCPU_MODE_NO_BLOCK); + if (unlikely(ret != 0)) { + ttm_base_object_unref(&base); + goto out; + } + ret = ttm_ref_object_add(tfile, &user_bo->base, + TTM_REF_SYNCCPU_WRITE, &existed); + if (existed || ret != 0) + ttm_bo_synccpu_write_release(bo); + ttm_base_object_unref(&base); + break; + case TTM_PL_SYNCCPU_OP_RELEASE: + ret = ttm_ref_object_base_unref(tfile, arg->handle, + TTM_REF_SYNCCPU_WRITE); + break; + default: + ret = -EINVAL; + break; + } +out: + return ret; +} + +int ttm_pl_setstatus_ioctl(struct ttm_object_file *tfile, + struct ttm_lock *lock, void *data) +{ + union ttm_pl_setstatus_arg *arg = data; + struct ttm_pl_setstatus_req *req = &arg->req; + struct ttm_pl_rep *rep = &arg->rep; + struct ttm_buffer_object *bo; + struct ttm_bo_device *bdev; + struct ttm_placement placement = default_placement; + uint32_t flags[2]; + int ret; + + bo = ttm_buffer_object_lookup(tfile, req->handle); + if (unlikely(bo == NULL)) { + printk(KERN_ERR + "Could not find buffer object for setstatus.\n"); + return -EINVAL; + } + + bdev = bo->bdev; + + ret = ttm_read_lock(lock, true); + if (unlikely(ret != 0)) + goto out_err0; + + ret = ttm_bo_reserve(bo, true, false, false, 0); + if (unlikely(ret != 0)) + goto out_err1; + + ret = ttm_bo_wait_cpu(bo, false); + if (unlikely(ret != 0)) + goto out_err2; + + flags[0] = req->set_placement; + flags[1] = req->clr_placement; + + placement.num_placement = 2; + placement.placement = flags; + + /* Review internal locking ? FIXMEAC */ + ret = psb_ttm_bo_check_placement(bo, &placement); + if (unlikely(ret != 0)) + goto out_err2; + + placement.num_placement = 1; + flags[0] = (req->set_placement | bo->mem.placement) + & ~req->clr_placement; + + ret = ttm_bo_validate(bo, &placement, true, false, false); + if (unlikely(ret != 0)) + goto out_err2; + + ttm_pl_fill_rep(bo, rep); +out_err2: + ttm_bo_unreserve(bo); +out_err1: + ttm_read_unlock(lock); +out_err0: + ttm_bo_unref(&bo); + return ret; +} + +static int psb_ttm_bo_block_reservation(struct ttm_buffer_object *bo, + bool interruptible, bool no_wait) +{ + int ret; + + while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) { + if (no_wait) + return -EBUSY; + else if (interruptible) { + ret = wait_event_interruptible(bo->event_queue, + atomic_read(&bo->reserved) == 0); + if (unlikely(ret != 0)) + return -ERESTART; + } else { + wait_event(bo->event_queue, + atomic_read(&bo->reserved) == 0); + } + } + return 0; +} + +static void psb_ttm_bo_unblock_reservation(struct ttm_buffer_object *bo) +{ + atomic_set(&bo->reserved, 0); + wake_up_all(&bo->event_queue); +} + +int ttm_pl_waitidle_ioctl(struct ttm_object_file *tfile, void *data) +{ + struct ttm_pl_waitidle_arg *arg = data; + struct ttm_buffer_object *bo; + int ret; + + bo = ttm_buffer_object_lookup(tfile, arg->handle); + if (unlikely(bo == NULL)) { + printk(KERN_ERR "Could not find buffer object for waitidle.\n"); + return -EINVAL; + } + + ret = + psb_ttm_bo_block_reservation(bo, true, + arg->mode & TTM_PL_WAITIDLE_MODE_NO_BLOCK); + if (unlikely(ret != 0)) + goto out; + ret = ttm_bo_wait(bo, + arg->mode & TTM_PL_WAITIDLE_MODE_LAZY, + true, arg->mode & TTM_PL_WAITIDLE_MODE_NO_BLOCK); + psb_ttm_bo_unblock_reservation(bo); +out: + ttm_bo_unref(&bo); + return ret; +} + +int ttm_pl_verify_access(struct ttm_buffer_object *bo, + struct ttm_object_file *tfile) +{ + struct ttm_bo_user_object *ubo; + + /* + * Check bo subclass. + */ + + if (unlikely(bo->destroy != &ttm_bo_user_destroy)) + return -EPERM; + + ubo = container_of(bo, struct ttm_bo_user_object, bo); + if (likely(ubo->base.shareable || ubo->base.tfile == tfile)) + return 0; + + return -EPERM; +} diff --git a/drivers/staging/gma500/psb_ttm_placement_user.h b/drivers/staging/gma500/psb_ttm_placement_user.h new file mode 100644 index 000000000000..f17bf48828d3 --- /dev/null +++ b/drivers/staging/gma500/psb_ttm_placement_user.h @@ -0,0 +1,252 @@ +/************************************************************************** + * + * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * All Rights Reserved. + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + **************************************************************************/ +/* + * Authors + * Thomas Hellström + */ + +#ifndef _TTM_PLACEMENT_USER_H_ +#define _TTM_PLACEMENT_USER_H_ + +#if !defined(__KERNEL__) && !defined(_KERNEL) +#include +#else +#include +#endif + +#include "ttm/ttm_placement.h" + +#define TTM_PLACEMENT_MAJOR 0 +#define TTM_PLACEMENT_MINOR 1 +#define TTM_PLACEMENT_PL 0 +#define TTM_PLACEMENT_DATE "080819" + +/** + * struct ttm_pl_create_req + * + * @size: The buffer object size. + * @placement: Flags that indicate initial acceptable + * placement. + * @page_alignment: Required alignment in pages. + * + * Input to the TTM_BO_CREATE ioctl. + */ + +struct ttm_pl_create_req { + uint64_t size; + uint32_t placement; + uint32_t page_alignment; +}; + +/** + * struct ttm_pl_create_ub_req + * + * @size: The buffer object size. + * @user_address: User-space address of the memory area that + * should be used to back the buffer object cast to 64-bit. + * @placement: Flags that indicate initial acceptable + * placement. + * @page_alignment: Required alignment in pages. + * + * Input to the TTM_BO_CREATE_UB ioctl. + */ + +struct ttm_pl_create_ub_req { + uint64_t size; + uint64_t user_address; + uint32_t placement; + uint32_t page_alignment; +}; + +/** + * struct ttm_pl_rep + * + * @gpu_offset: The current offset into the memory region used. + * This can be used directly by the GPU if there are no + * additional GPU mapping procedures used by the driver. + * + * @bo_size: Actual buffer object size. + * + * @map_handle: Offset into the device address space. + * Used for map, seek, read, write. This will never change + * during the lifetime of an object. + * + * @placement: Flag indicating the placement status of + * the buffer object using the TTM_PL flags above. + * + * @sync_object_arg: Used for user-space synchronization and + * depends on the synchronization model used. If fences are + * used, this is the buffer_object::fence_type_mask + * + * Output from the TTM_PL_CREATE and TTM_PL_REFERENCE, and + * TTM_PL_SETSTATUS ioctls. + */ + +struct ttm_pl_rep { + uint64_t gpu_offset; + uint64_t bo_size; + uint64_t map_handle; + uint32_t placement; + uint32_t handle; + uint32_t sync_object_arg; + uint32_t pad64; +}; + +/** + * struct ttm_pl_setstatus_req + * + * @set_placement: Placement flags to set. + * + * @clr_placement: Placement flags to clear. + * + * @handle: The object handle + * + * Input to the TTM_PL_SETSTATUS ioctl. + */ + +struct ttm_pl_setstatus_req { + uint32_t set_placement; + uint32_t clr_placement; + uint32_t handle; + uint32_t pad64; +}; + +/** + * struct ttm_pl_reference_req + * + * @handle: The object to put a reference on. + * + * Input to the TTM_PL_REFERENCE and the TTM_PL_UNREFERENCE ioctls. + */ + +struct ttm_pl_reference_req { + uint32_t handle; + uint32_t pad64; +}; + +/* + * ACCESS mode flags for SYNCCPU. + * + * TTM_SYNCCPU_MODE_READ will guarantee that the GPU is not + * writing to the buffer. + * + * TTM_SYNCCPU_MODE_WRITE will guarantee that the GPU is not + * accessing the buffer. + * + * TTM_SYNCCPU_MODE_NO_BLOCK makes sure the call does not wait + * for GPU accesses to finish but return -EBUSY. + * + * TTM_SYNCCPU_MODE_TRYCACHED Try to place the buffer in cacheable + * memory while synchronized for CPU. + */ + +#define TTM_PL_SYNCCPU_MODE_READ TTM_ACCESS_READ +#define TTM_PL_SYNCCPU_MODE_WRITE TTM_ACCESS_WRITE +#define TTM_PL_SYNCCPU_MODE_NO_BLOCK (1 << 2) +#define TTM_PL_SYNCCPU_MODE_TRYCACHED (1 << 3) + +/** + * struct ttm_pl_synccpu_arg + * + * @handle: The object to synchronize. + * + * @access_mode: access mode indicated by the + * TTM_SYNCCPU_MODE flags. + * + * @op: indicates whether to grab or release the + * buffer for cpu usage. + * + * Input to the TTM_PL_SYNCCPU ioctl. + */ + +struct ttm_pl_synccpu_arg { + uint32_t handle; + uint32_t access_mode; + enum { + TTM_PL_SYNCCPU_OP_GRAB, + TTM_PL_SYNCCPU_OP_RELEASE + } op; + uint32_t pad64; +}; + +/* + * Waiting mode flags for the TTM_BO_WAITIDLE ioctl. + * + * TTM_WAITIDLE_MODE_LAZY: Allow for sleeps during polling + * wait. + * + * TTM_WAITIDLE_MODE_NO_BLOCK: Don't block waiting for GPU, + * but return -EBUSY if the buffer is busy. + */ + +#define TTM_PL_WAITIDLE_MODE_LAZY (1 << 0) +#define TTM_PL_WAITIDLE_MODE_NO_BLOCK (1 << 1) + +/** + * struct ttm_waitidle_arg + * + * @handle: The object to synchronize. + * + * @mode: wait mode indicated by the + * TTM_SYNCCPU_MODE flags. + * + * Argument to the TTM_BO_WAITIDLE ioctl. + */ + +struct ttm_pl_waitidle_arg { + uint32_t handle; + uint32_t mode; +}; + +union ttm_pl_create_arg { + struct ttm_pl_create_req req; + struct ttm_pl_rep rep; +}; + +union ttm_pl_reference_arg { + struct ttm_pl_reference_req req; + struct ttm_pl_rep rep; +}; + +union ttm_pl_setstatus_arg { + struct ttm_pl_setstatus_req req; + struct ttm_pl_rep rep; +}; + +union ttm_pl_create_ub_arg { + struct ttm_pl_create_ub_req req; + struct ttm_pl_rep rep; +}; + +/* + * Ioctl offsets. + */ + +#define TTM_PL_CREATE 0x00 +#define TTM_PL_REFERENCE 0x01 +#define TTM_PL_UNREF 0x02 +#define TTM_PL_SYNCCPU 0x03 +#define TTM_PL_WAITIDLE 0x04 +#define TTM_PL_SETSTATUS 0x05 +#define TTM_PL_CREATE_UB 0x06 + +#endif diff --git a/drivers/staging/gma500/psb_ttm_userobj_api.h b/drivers/staging/gma500/psb_ttm_userobj_api.h new file mode 100644 index 000000000000..c69fa88bf857 --- /dev/null +++ b/drivers/staging/gma500/psb_ttm_userobj_api.h @@ -0,0 +1,85 @@ +/************************************************************************** + * + * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * All Rights Reserved. + * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom + */ + +#ifndef _TTM_USEROBJ_API_H_ +#define _TTM_USEROBJ_API_H_ + +#include "psb_ttm_placement_user.h" +#include "psb_ttm_fence_user.h" +#include "ttm/ttm_object.h" +#include "psb_ttm_fence_api.h" +#include "ttm/ttm_bo_api.h" + +struct ttm_lock; + +/* + * User ioctls. + */ + +extern int ttm_pl_create_ioctl(struct ttm_object_file *tfile, + struct ttm_bo_device *bdev, + struct ttm_lock *lock, void *data); +extern int ttm_pl_ub_create_ioctl(struct ttm_object_file *tfile, + struct ttm_bo_device *bdev, + struct ttm_lock *lock, void *data); +extern int ttm_pl_reference_ioctl(struct ttm_object_file *tfile, void *data); +extern int ttm_pl_unref_ioctl(struct ttm_object_file *tfile, void *data); +extern int ttm_pl_synccpu_ioctl(struct ttm_object_file *tfile, void *data); +extern int ttm_pl_setstatus_ioctl(struct ttm_object_file *tfile, + struct ttm_lock *lock, void *data); +extern int ttm_pl_waitidle_ioctl(struct ttm_object_file *tfile, void *data); +extern int ttm_fence_signaled_ioctl(struct ttm_object_file *tfile, void *data); +extern int ttm_fence_finish_ioctl(struct ttm_object_file *tfile, void *data); +extern int ttm_fence_unref_ioctl(struct ttm_object_file *tfile, void *data); + +extern int +ttm_fence_user_create(struct ttm_fence_device *fdev, + struct ttm_object_file *tfile, + uint32_t fence_class, + uint32_t fence_types, + uint32_t create_flags, + struct ttm_fence_object **fence, uint32_t * user_handle); + +extern struct ttm_buffer_object *ttm_buffer_object_lookup(struct ttm_object_file + *tfile, + uint32_t handle); + +extern int +ttm_pl_verify_access(struct ttm_buffer_object *bo, + struct ttm_object_file *tfile); + +extern int ttm_buffer_object_create(struct ttm_bo_device *bdev, + unsigned long size, + enum ttm_bo_type type, + uint32_t flags, + uint32_t page_alignment, + unsigned long buffer_start, + bool interruptible, + struct file *persistant_swap_storage, + struct ttm_buffer_object **p_bo); + +extern int psb_ttm_bo_check_placement(struct ttm_buffer_object *bo, + struct ttm_placement *placement); +#endif -- cgit v1.2.3 From 8997fd21bb47a27661429be52707331cd8b2351d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 23 Feb 2011 13:47:57 -0800 Subject: Staging: gma500: remove psb_gfx.mod.c The mod.c file should not be part of the repo. Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_gfx.mod.c | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 drivers/staging/gma500/psb_gfx.mod.c (limited to 'drivers') diff --git a/drivers/staging/gma500/psb_gfx.mod.c b/drivers/staging/gma500/psb_gfx.mod.c deleted file mode 100644 index 1a663ab44400..000000000000 --- a/drivers/staging/gma500/psb_gfx.mod.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include - -MODULE_INFO(vermagic, VERMAGIC_STRING); - -struct module __this_module -__attribute__((section(".gnu.linkonce.this_module"))) = { - .name = KBUILD_MODNAME, - .init = init_module, -#ifdef CONFIG_MODULE_UNLOAD - .exit = cleanup_module, -#endif - .arch = MODULE_ARCH_INIT, -}; - -MODULE_INFO(staging, "Y"); - -static const char __module_depends[] -__used -__attribute__((section(".modinfo"))) = -"depends=ttm,drm,drm_kms_helper,i2c-core,cfbfillrect,cfbimgblt,cfbcopyarea,i2c-algo-bit"; - -MODULE_ALIAS("pci:v00008086d00008108sv*sd*bc*sc*i*"); -MODULE_ALIAS("pci:v00008086d00008109sv*sd*bc*sc*i*"); - -MODULE_INFO(srcversion, "933CCC78041722973001B78"); -- cgit v1.2.3 From 5352161fc449d7a7573b2e13bd02162aae7aeb69 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 23 Feb 2011 13:50:42 -0800 Subject: Staging: gma500: fix up trailing whitespace errors Lots of little ones all through the driver, mostly all in a cut-and-paste header comment. Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_drv.h | 10 ++++----- drivers/staging/gma500/psb_fb.h | 2 +- drivers/staging/gma500/psb_gtt.h | 2 +- drivers/staging/gma500/psb_intel_bios.h | 2 +- drivers/staging/gma500/psb_intel_display.h | 4 ++-- drivers/staging/gma500/psb_intel_drv.h | 2 +- drivers/staging/gma500/psb_intel_reg.h | 22 +++++++++--------- drivers/staging/gma500/psb_intel_sdvo_regs.h | 4 ++-- drivers/staging/gma500/psb_powermgmt.c | 30 ++++++++++++------------- drivers/staging/gma500/psb_pvr_glue.h | 2 +- drivers/staging/gma500/psb_reg.h | 12 +++++----- drivers/staging/gma500/psb_sgx.h | 2 +- drivers/staging/gma500/psb_ttm_fence_api.h | 2 +- drivers/staging/gma500/psb_ttm_fence_driver.h | 2 +- drivers/staging/gma500/psb_ttm_fence_user.h | 2 +- drivers/staging/gma500/psb_ttm_placement_user.h | 2 +- drivers/staging/gma500/psb_ttm_userobj_api.h | 2 +- 17 files changed, 52 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index b75b9d850723..79417a4b51ab 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -12,7 +12,7 @@ * more details. * * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., + * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * **************************************************************************/ @@ -232,7 +232,7 @@ enum { #define MDFLD_DSR_MIPI_CONTROL BIT6 #define MDFLD_DSR_2D_3D (MDFLD_DSR_2D_3D_0 | MDFLD_DSR_2D_3D_2) -#define MDFLD_DSR_RR 45 +#define MDFLD_DSR_RR 45 #define MDFLD_DPU_ENABLE BIT31 #define MDFLD_DSR_FULLSCREEN BIT30 #define MDFLD_DSR_DELAY (DRM_HZ / MDFLD_DSR_RR) @@ -344,9 +344,9 @@ struct psb_video_ctx { struct drm_psb_private { /* - * DSI info. + * DSI info. */ - void * dbi_dsr_info; + void * dbi_dsr_info; void * dsi_configs[2]; /* @@ -387,7 +387,7 @@ struct drm_psb_private { uint8_t *sgx_reg; uint8_t *vdc_reg; uint32_t gatt_free_offset; - + /* IMG video context */ struct list_head video_ctx; diff --git a/drivers/staging/gma500/psb_fb.h b/drivers/staging/gma500/psb_fb.h index d39d84ddab50..b4fab9262db5 100644 --- a/drivers/staging/gma500/psb_fb.h +++ b/drivers/staging/gma500/psb_fb.h @@ -11,7 +11,7 @@ * more details. * * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., + * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * * Authors: diff --git a/drivers/staging/gma500/psb_gtt.h b/drivers/staging/gma500/psb_gtt.h index 3544b4d92f11..0272f83b461e 100644 --- a/drivers/staging/gma500/psb_gtt.h +++ b/drivers/staging/gma500/psb_gtt.h @@ -12,7 +12,7 @@ * more details. * * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., + * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * **************************************************************************/ diff --git a/drivers/staging/gma500/psb_intel_bios.h b/drivers/staging/gma500/psb_intel_bios.h index dfcae6218308..ad30a6842529 100644 --- a/drivers/staging/gma500/psb_intel_bios.h +++ b/drivers/staging/gma500/psb_intel_bios.h @@ -11,7 +11,7 @@ * more details. * * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., + * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * * Authors: diff --git a/drivers/staging/gma500/psb_intel_display.h b/drivers/staging/gma500/psb_intel_display.h index 74e3b5e5deaf..3724b971e91c 100644 --- a/drivers/staging/gma500/psb_intel_display.h +++ b/drivers/staging/gma500/psb_intel_display.h @@ -1,5 +1,5 @@ /* copyright (c) 2008, Intel Corporation - * + * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. @@ -10,7 +10,7 @@ * more details. * * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., + * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * * Authors: diff --git a/drivers/staging/gma500/psb_intel_drv.h b/drivers/staging/gma500/psb_intel_drv.h index cb0a91b78173..f6229c56de40 100644 --- a/drivers/staging/gma500/psb_intel_drv.h +++ b/drivers/staging/gma500/psb_intel_drv.h @@ -11,7 +11,7 @@ * more details. * * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., + * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * */ diff --git a/drivers/staging/gma500/psb_intel_reg.h b/drivers/staging/gma500/psb_intel_reg.h index 6cae11857545..0c323c026f85 100644 --- a/drivers/staging/gma500/psb_intel_reg.h +++ b/drivers/staging/gma500/psb_intel_reg.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2009, Intel Corporation. - * + * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. @@ -11,7 +11,7 @@ * more details. * * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., + * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __PSB_INTEL_REG_H__ @@ -589,7 +589,7 @@ struct dpst_guardband { /* * Some BIOS scratch area registers. The 845 (and 830?) store the amount * of video memory available to the BIOS in SWF1. - */ + */ #define SWF0 0x71410 #define SWF1 0x71414 #define SWF2 0x71418 @@ -695,12 +695,12 @@ struct dpst_guardband { */ #define MRST_DPLL_A 0x0f014 #define MDFLD_DPLL_B 0x0f018 -#define MDFLD_INPUT_REF_SEL (1 << 14) -#define MDFLD_VCO_SEL (1 << 16) +#define MDFLD_INPUT_REF_SEL (1 << 14) +#define MDFLD_VCO_SEL (1 << 16) #define DPLLA_MODE_LVDS (2 << 26) /* mrst */ -#define MDFLD_PLL_LATCHEN (1 << 28) -#define MDFLD_PWR_GATE_EN (1 << 30) -#define MDFLD_P1_MASK (0x1FF << 17) +#define MDFLD_PLL_LATCHEN (1 << 28) +#define MDFLD_PWR_GATE_EN (1 << 30) +#define MDFLD_P1_MASK (0x1FF << 17) #define MRST_FPA0 0x0f040 #define MRST_FPA1 0x0f044 #define MDFLD_DPLL_DIV0 0x0f048 @@ -1094,8 +1094,8 @@ Bits D7 and D3 are not used. #define DCS_PIXEL_FORMAT_3bbp 0x1 #define DCS_PIXEL_FORMAT_8bbp 0x2 #define DCS_PIXEL_FORMAT_12bbp 0x3 - #define DCS_PIXEL_FORMAT_16bbp 0x5 - #define DCS_PIXEL_FORMAT_18bbp 0x6 + #define DCS_PIXEL_FORMAT_16bbp 0x5 + #define DCS_PIXEL_FORMAT_18bbp 0x6 #define DCS_PIXEL_FORMAT_24bbp 0x7 #define write_mem_cont 0x3c /* ************************************************************************* *\ @@ -1190,7 +1190,7 @@ gamma settings. * byte alignment */ #define DBI_CB_TIME_OUT 0xFFFF -#define GEN_FB_TIME_OUT 2000 +#define GEN_FB_TIME_OUT 2000 #define ALIGNMENT_32BYTE_MASK (~(BIT0|BIT1|BIT2|BIT3|BIT4)) #define SKU_83 0x01 #define SKU_100 0x02 diff --git a/drivers/staging/gma500/psb_intel_sdvo_regs.h b/drivers/staging/gma500/psb_intel_sdvo_regs.h index ed2f1360df1a..a1d1475a9315 100644 --- a/drivers/staging/gma500/psb_intel_sdvo_regs.h +++ b/drivers/staging/gma500/psb_intel_sdvo_regs.h @@ -1,6 +1,6 @@ /* * SDVO command definitions and structures. - * + * * Copyright (c) 2008, Intel Corporation * * This program is free software; you can redistribute it and/or modify it @@ -13,7 +13,7 @@ * more details. * * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., + * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * * Authors: diff --git a/drivers/staging/gma500/psb_powermgmt.c b/drivers/staging/gma500/psb_powermgmt.c index 3a6ffb7ff11f..39fa66a5f5d4 100644 --- a/drivers/staging/gma500/psb_powermgmt.c +++ b/drivers/staging/gma500/psb_powermgmt.c @@ -119,7 +119,7 @@ static int save_display_registers(struct drm_device *dev) crtc->funcs->save(crtc); } } - + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { connector->funcs->save(connector); } @@ -194,7 +194,7 @@ void ospm_suspend_display(struct drm_device *dev) return; save_display_registers(dev); - + if (dev_priv->iLVDS_enable) { /*shutdown the panel*/ PSB_WVDC32(0, PP_CONTROL); @@ -243,7 +243,7 @@ void ospm_resume_display(struct pci_dev *pdev) struct psb_gtt *pg = dev_priv->pg; printk(KERN_ALERT "%s \n", __func__); - + #ifdef OSPM_GFX_DPK printk(KERN_ALERT "%s \n", __func__); #endif @@ -263,7 +263,7 @@ void ospm_resume_display(struct pci_dev *pdev) * above. */ /*psb_gtt_init(dev_priv->pg, 1);*/ - + restore_display_registers(dev); } @@ -356,7 +356,7 @@ int ospm_power_suspend(struct pci_dev *pdev, pm_message_t state) int videoenc_access_count; int videodec_access_count; int display_access_count; - bool suspend_pci = true; + bool suspend_pci = true; if(gbSuspendInProgress || gbResumeInProgress) { @@ -518,7 +518,7 @@ void ospm_power_island_down(int islands) if (islands & OSPM_DISPLAY_ISLAND) { pwr_mask = PSB_PWRGT_DISPLAY_MASK; - + outl(pwr_mask, (dev_priv->ospm_base + PSB_PM_SSC)); while (true) { @@ -529,7 +529,7 @@ void ospm_power_island_down(int islands) udelay(10); } } -#endif +#endif } @@ -553,9 +553,9 @@ bool ospm_power_is_hw_on(int hw_islands) * specified island's hw so don't power it off. If force_on is true, * this will power on the specified island if it is off. * Otherwise, this will return false and the caller is expected to not - * access the hw. - * - * NOTE *** If this is called from and interrupt handler or other atomic + * access the hw. + * + * NOTE *** If this is called from and interrupt handler or other atomic * context, then it will return false if we are in the middle of a * power state transition and the caller will be expected to handle that * even if force_on is set to true. @@ -563,7 +563,7 @@ bool ospm_power_is_hw_on(int hw_islands) bool ospm_power_using_hw_begin(int hw_island, UHBUsage usage) { return 1; /*FIXMEAC */ -#if 0 +#if 0 bool ret = true; bool island_is_off = false; bool b_atomic = (in_interrupt() || in_atomic()); @@ -702,7 +702,7 @@ increase_count: mutex_unlock(&power_mutex); return ret; -#endif +#endif } @@ -739,7 +739,7 @@ void ospm_power_using_hw_end(int hw_island) WARN_ON(atomic_read(&g_videoenc_access_count) < 0); WARN_ON(atomic_read(&g_videodec_access_count) < 0); WARN_ON(atomic_read(&g_display_access_count) < 0); -#endif +#endif } int ospm_runtime_pm_allow(struct drm_device * dev) @@ -750,9 +750,9 @@ int ospm_runtime_pm_allow(struct drm_device * dev) void ospm_runtime_pm_forbid(struct drm_device * dev) { struct drm_psb_private * dev_priv = dev->dev_private; - + DRM_INFO("%s\n", __FUNCTION__); - + pm_runtime_forbid(&dev->pdev->dev); dev_priv->rpm_enabled = 0; } diff --git a/drivers/staging/gma500/psb_pvr_glue.h b/drivers/staging/gma500/psb_pvr_glue.h index 63dd0946401f..dee8cb2cadc0 100644 --- a/drivers/staging/gma500/psb_pvr_glue.h +++ b/drivers/staging/gma500/psb_pvr_glue.h @@ -11,7 +11,7 @@ * more details. * * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., + * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * */ diff --git a/drivers/staging/gma500/psb_reg.h b/drivers/staging/gma500/psb_reg.h index d80b4f3833c8..9ad49892070e 100644 --- a/drivers/staging/gma500/psb_reg.h +++ b/drivers/staging/gma500/psb_reg.h @@ -14,7 +14,7 @@ * more details. * * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., + * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.. * **************************************************************************/ @@ -568,10 +568,10 @@ #define PSB_PM_SSC 0x20 #define PSB_PM_SSS 0x30 #define PSB_PWRGT_DISPLAY_MASK 0xc /*on a different BA than video/gfx*/ -#define MDFLD_PWRGT_DISPLAY_A_CNTR 0x0000000c -#define MDFLD_PWRGT_DISPLAY_B_CNTR 0x0000c000 -#define MDFLD_PWRGT_DISPLAY_C_CNTR 0x00030000 -#define MDFLD_PWRGT_DISP_MIPI_CNTR 0x000c0000 +#define MDFLD_PWRGT_DISPLAY_A_CNTR 0x0000000c +#define MDFLD_PWRGT_DISPLAY_B_CNTR 0x0000c000 +#define MDFLD_PWRGT_DISPLAY_C_CNTR 0x00030000 +#define MDFLD_PWRGT_DISP_MIPI_CNTR 0x000c0000 #define MDFLD_PWRGT_DISPLAY_CNTR (MDFLD_PWRGT_DISPLAY_A_CNTR | MDFLD_PWRGT_DISPLAY_B_CNTR | MDFLD_PWRGT_DISPLAY_C_CNTR | MDFLD_PWRGT_DISP_MIPI_CNTR)// 0x000fc00c // Display SSS register bits are different in A0 vs. B0 #define PSB_PWRGT_GFX_MASK 0x3 @@ -582,7 +582,7 @@ #define MDFLD_PWRGT_DISPLAY_A_STS_B0 0x0000000c #define MDFLD_PWRGT_DISPLAY_B_STS_B0 0x0000c000 #define MDFLD_PWRGT_DISPLAY_C_STS_B0 0x00030000 -#define MDFLD_PWRGT_DISP_MIPI_STS 0x000c0000 +#define MDFLD_PWRGT_DISP_MIPI_STS 0x000c0000 #define MDFLD_PWRGT_DISPLAY_STS_A0 (MDFLD_PWRGT_DISPLAY_A_STS | MDFLD_PWRGT_DISPLAY_B_STS | MDFLD_PWRGT_DISPLAY_C_STS | MDFLD_PWRGT_DISP_MIPI_STS)// 0x000fc00c #define MDFLD_PWRGT_DISPLAY_STS_B0 (MDFLD_PWRGT_DISPLAY_A_STS_B0 | MDFLD_PWRGT_DISPLAY_B_STS_B0 | MDFLD_PWRGT_DISPLAY_C_STS_B0 | MDFLD_PWRGT_DISP_MIPI_STS)// 0x000fc00c #endif diff --git a/drivers/staging/gma500/psb_sgx.h b/drivers/staging/gma500/psb_sgx.h index 2934e5d146c5..9300e2da993a 100644 --- a/drivers/staging/gma500/psb_sgx.h +++ b/drivers/staging/gma500/psb_sgx.h @@ -11,7 +11,7 @@ * more details. * * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., + * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * * Authors: diff --git a/drivers/staging/gma500/psb_ttm_fence_api.h b/drivers/staging/gma500/psb_ttm_fence_api.h index d42904c4ec2f..b14a42711d03 100644 --- a/drivers/staging/gma500/psb_ttm_fence_api.h +++ b/drivers/staging/gma500/psb_ttm_fence_api.h @@ -15,7 +15,7 @@ * more details. * * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., + * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * **************************************************************************/ diff --git a/drivers/staging/gma500/psb_ttm_fence_driver.h b/drivers/staging/gma500/psb_ttm_fence_driver.h index 233c6ba13121..c35c569fa3f0 100644 --- a/drivers/staging/gma500/psb_ttm_fence_driver.h +++ b/drivers/staging/gma500/psb_ttm_fence_driver.h @@ -15,7 +15,7 @@ * more details. * * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., + * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * **************************************************************************/ diff --git a/drivers/staging/gma500/psb_ttm_fence_user.h b/drivers/staging/gma500/psb_ttm_fence_user.h index ee95e6a7db09..fc13f89c6e12 100644 --- a/drivers/staging/gma500/psb_ttm_fence_user.h +++ b/drivers/staging/gma500/psb_ttm_fence_user.h @@ -15,7 +15,7 @@ * more details. * * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., + * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * **************************************************************************/ diff --git a/drivers/staging/gma500/psb_ttm_placement_user.h b/drivers/staging/gma500/psb_ttm_placement_user.h index f17bf48828d3..8b7068b54441 100644 --- a/drivers/staging/gma500/psb_ttm_placement_user.h +++ b/drivers/staging/gma500/psb_ttm_placement_user.h @@ -15,7 +15,7 @@ * more details. * * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., + * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * **************************************************************************/ diff --git a/drivers/staging/gma500/psb_ttm_userobj_api.h b/drivers/staging/gma500/psb_ttm_userobj_api.h index c69fa88bf857..6a8f7c4ddc78 100644 --- a/drivers/staging/gma500/psb_ttm_userobj_api.h +++ b/drivers/staging/gma500/psb_ttm_userobj_api.h @@ -15,7 +15,7 @@ * more details. * * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., + * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * **************************************************************************/ -- cgit v1.2.3 From 108160db3fb0479edf89d1b74b267360d8a5fa65 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Sun, 20 Feb 2011 21:11:41 -0800 Subject: staging: ath6kl: update TODO file / maintainers This updates the TODO file to reflect new changes on development. Cc: Joe Perches Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/TODO | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/TODO b/drivers/staging/ath6kl/TODO index d4629274397d..019df4b471eb 100644 --- a/drivers/staging/ath6kl/TODO +++ b/drivers/staging/ath6kl/TODO @@ -1,8 +1,25 @@ -- The driver is a stop-gap measure until a proper mac80211 driver is available. -- The driver does not conform to the Linux coding style. -- The driver has been tested on a wide variety of embedded platforms running different versions of the Linux kernel but may still have bringup/performance issues with a new platform. -- Pls use the following link to get information about the driver's architecture, exposed APIs, supported features, limitations, testing, hardware availability and other details. - http://wireless.kernel.org/en/users/Drivers/ath6kl -- Pls send any patches to +TODO: + +We are working hard on cleaning up the driver. There's sooooooooo much todo +so instead of editign this file please use the wiki: + +http://wireless.kernel.org/en/users/Drivers/ath6kl + +There's a respective TODO page there. Please also subscribe to the wiki page +to get e-mail updates on changes. + +IRC: + +We *really* need to coordinate development for ath6kl as the cleanup +patches will break pretty much any other patches. Please use IRC to +help coordinate better: + +irc.freenode.net +#ath6kl + +Send patches to: + - Greg Kroah-Hartman - - Vipin Mehta + - Luis R. Rodriguez + - Joe Perches + - Naveen Singh -- cgit v1.2.3 From 253804a25b45aad7bf4f63483f7c7b1d14ab49e2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 20 Feb 2011 15:49:08 +0300 Subject: staging: ath6kl: cleanup in SEND_FRAME ioctl The original code was written in a funny way where every statement was part of else if blocks. I broke them up into separate statements by adding breaks on failure conditions. Signed-off-by: Dan Carpenter Acked-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ioctl.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index 6d15d2df8613..82c7611c2081 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -3162,29 +3162,31 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_OPT_SEND_FRAME: { - WMI_OPT_TX_FRAME_CMD optTxFrmCmd; + WMI_OPT_TX_FRAME_CMD optTxFrmCmd; u8 data[MAX_OPT_DATA_LEN]; if (ar->arWmiReady == false) { ret = -EIO; - } else if (copy_from_user(&optTxFrmCmd, userdata, - sizeof(optTxFrmCmd))) - { + break; + } + + if (copy_from_user(&optTxFrmCmd, userdata, sizeof(optTxFrmCmd))) { ret = -EFAULT; - } else if (copy_from_user(data, - userdata+sizeof(WMI_OPT_TX_FRAME_CMD)-1, - optTxFrmCmd.optIEDataLen)) - { + break; + } + + if (copy_from_user(data, userdata+sizeof(WMI_OPT_TX_FRAME_CMD) - 1, + optTxFrmCmd.optIEDataLen)) { ret = -EFAULT; - } else { - ret = wmi_opt_tx_frame_cmd(ar->arWmi, + break; + } + + ret = wmi_opt_tx_frame_cmd(ar->arWmi, optTxFrmCmd.frmType, optTxFrmCmd.dstAddr, optTxFrmCmd.bssid, optTxFrmCmd.optIEDataLen, data); - } - break; } case AR6000_XIOCTL_WMI_SETRETRYLIMITS: -- cgit v1.2.3 From 5b6567ee84d6e8f7015eaa7d7c4926b4fd81746e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 20 Feb 2011 15:49:53 +0300 Subject: staging: ath6kl: buffer overflow in SEND_FRAME ioctl We should check that optTxFrmCmd.optIEDataLen isn't too large before we copy it into the data buffer. Signed-off-by: Dan Carpenter Acked-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ioctl.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index 82c7611c2081..4f30b255fc1a 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -3175,6 +3175,11 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) break; } + if (optTxFrmCmd.optIEDataLen > MAX_OPT_DATA_LEN) { + ret = -EINVAL; + break; + } + if (copy_from_user(data, userdata+sizeof(WMI_OPT_TX_FRAME_CMD) - 1, optTxFrmCmd.optIEDataLen)) { ret = -EFAULT; -- cgit v1.2.3 From 5caf8fca2da11e368a2284f4c4f5c2cbbe1b3ec8 Mon Sep 17 00:00:00 2001 From: Vipin Mehta Date: Sun, 20 Feb 2011 07:00:38 -0800 Subject: staging: ath6kl: Eliminate cfg80211 warnings Cancel the pending scan operation once the interface is going down to avoid warnings from the cfg80211 module. Once the interface is down, cfg80211 checks for any pending scan requests and dumps a warning if it finds one. It expects the driver to abort any ongoing scan operation once the driver detects that the interface is going down. Signed-off-by: Vipin Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 5dc5cf0c5b16..21483812ea98 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -2331,6 +2331,7 @@ ar6000_close(struct net_device *dev) } ar->arWlanState = WLAN_DISABLED; } + ar6k_cfg80211_scanComplete_event(ar, A_ECANCELED); #endif /* ATH6K_CONFIG_CFG80211 */ return 0; -- cgit v1.2.3 From 3c8bb7aab9ad84bce7d81878fda64d631089a88d Mon Sep 17 00:00:00 2001 From: Nitin Gupta Date: Fri, 18 Feb 2011 17:33:18 -0500 Subject: staging: Allow sharing xvmalloc for zram and zcache Both zram and zcache use xvmalloc allocator. If xvmalloc is compiled separately for both of them, we will get linker error if they are both selected as "built-in". We can also get linker error regarding missing xvmalloc symbols if zram is not built. So, we now compile xvmalloc separately and export its symbols which are then used by both of zram and zcache. Signed-off-by: Nitin Gupta Acked-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Makefile | 1 + drivers/staging/zcache/Makefile | 4 +++- drivers/staging/zram/Kconfig | 5 +++++ drivers/staging/zram/Makefile | 3 ++- drivers/staging/zram/xvmalloc.c | 8 ++++++++ 5 files changed, 19 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 3519e5703d85..dcd47dba0e9a 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_DX_SEP) += sep/ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio/ obj-$(CONFIG_ZRAM) += zram/ +obj-$(CONFIG_XVMALLOC) += zram/ obj-$(CONFIG_ZCACHE) += zcache/ obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/ diff --git a/drivers/staging/zcache/Makefile b/drivers/staging/zcache/Makefile index 7f64de4dff3b..f5ec64f94470 100644 --- a/drivers/staging/zcache/Makefile +++ b/drivers/staging/zcache/Makefile @@ -1 +1,3 @@ -obj-$(CONFIG_ZCACHE) += zcache.o tmem.o +zcache-y := tmem.o + +obj-$(CONFIG_ZCACHE) += zcache.o diff --git a/drivers/staging/zram/Kconfig b/drivers/staging/zram/Kconfig index 2f3b484ce5a4..3bec4dba3fe5 100644 --- a/drivers/staging/zram/Kconfig +++ b/drivers/staging/zram/Kconfig @@ -1,6 +1,11 @@ +config XVMALLOC + bool + default n + config ZRAM tristate "Compressed RAM block device support" depends on BLOCK && SYSFS + select XVMALLOC select LZO_COMPRESS select LZO_DECOMPRESS default n diff --git a/drivers/staging/zram/Makefile b/drivers/staging/zram/Makefile index b1709c57f636..2a6d3213a756 100644 --- a/drivers/staging/zram/Makefile +++ b/drivers/staging/zram/Makefile @@ -1,3 +1,4 @@ -zram-y := zram_drv.o zram_sysfs.o xvmalloc.o +zram-y := zram_drv.o zram_sysfs.o obj-$(CONFIG_ZRAM) += zram.o +obj-$(CONFIG_XVMALLOC) += xvmalloc.o \ No newline at end of file diff --git a/drivers/staging/zram/xvmalloc.c b/drivers/staging/zram/xvmalloc.c index ae0623a65ab9..1f9c5082b6d5 100644 --- a/drivers/staging/zram/xvmalloc.c +++ b/drivers/staging/zram/xvmalloc.c @@ -14,6 +14,8 @@ #define DEBUG #endif +#include +#include #include #include #include @@ -315,11 +317,13 @@ struct xv_pool *xv_create_pool(void) return pool; } +EXPORT_SYMBOL_GPL(xv_create_pool); void xv_destroy_pool(struct xv_pool *pool) { kfree(pool); } +EXPORT_SYMBOL_GPL(xv_destroy_pool); /** * xv_malloc - Allocate block of given size from pool. @@ -408,6 +412,7 @@ int xv_malloc(struct xv_pool *pool, u32 size, struct page **page, return 0; } +EXPORT_SYMBOL_GPL(xv_malloc); /* * Free block identified with @@ -484,6 +489,7 @@ void xv_free(struct xv_pool *pool, struct page *page, u32 offset) put_ptr_atomic(page_start, KM_USER0); spin_unlock(&pool->lock); } +EXPORT_SYMBOL_GPL(xv_free); u32 xv_get_object_size(void *obj) { @@ -492,6 +498,7 @@ u32 xv_get_object_size(void *obj) blk = (struct block_header *)((char *)(obj) - XV_ALIGN); return blk->size; } +EXPORT_SYMBOL_GPL(xv_get_object_size); /* * Returns total memory used by allocator (userdata + metadata) @@ -500,3 +507,4 @@ u64 xv_get_total_size_bytes(struct xv_pool *pool) { return pool->total_pages << PAGE_SHIFT; } +EXPORT_SYMBOL_GPL(xv_get_total_size_bytes); -- cgit v1.2.3 From 1005f085743362129396d5c5e68d7c385392dafb Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Mon, 21 Feb 2011 09:07:12 +0100 Subject: staging: brcm80211: bugfix for crash on heavy transmit traffic With heavy transmit traffic, once in a while (range 15mins-1hr) a tx packet was added to a full transmit queue. Under certain conditions an other packet in the queue gets bumped to make room for the new packet. This is not considered an error condition, but normal operation. Despite that, there was an ASSERT(0) that caused the driver to oops. The ASSERT(0) has been removed. Driver was tested afterwards. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index 91a2de218e77..b617b6417054 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -5146,8 +5146,6 @@ wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, tx_failed[WME_PRIO2AC(p->priority)].bytes, pkttotlen(wlc->osh, p)); } - - ASSERT(0); pkt_buf_free_skb(wlc->osh, p, true); wlc->pub->_cnt->txnobuf++; } -- cgit v1.2.3 From 628f10ba81ed26e61c25cd6b79a3edb9041610ef Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Sun, 20 Feb 2011 21:43:32 +0300 Subject: staging: brcm80211: replace broadcom specific byte swapping routines HTON16/hton16 -> cpu_to_be16 (htons for networking code) HTON32/hton32 -> cpu_to_be32 (htonl for networking code) NTOH16/ntoh32 -> be16_to_cpu (ntohs for networking code) NTOH32/ntoh32 -> be32_to_cpu (ntohl for networking code) LTOH16/ltoh16 -> le16_to_cpu LTOH32/ltoh32 -> le32_to_cpu HTOL16/htol16 -> cpu_to_le16 HTOL32/htol32 -> cpu_to_le32 Signed-off-by: Stanislav Fomichev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 2 +- drivers/staging/brcm80211/brcmfmac/dhd_cdc.c | 30 ++-- drivers/staging/brcm80211/brcmfmac/dhd_common.c | 32 ++--- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 20 +-- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 36 ++--- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 16 +-- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 14 +- .../staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c | 6 +- drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c | 8 +- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 38 ++--- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 6 +- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 160 +++++++++++---------- drivers/staging/brcm80211/include/bcmendian.h | 42 ------ drivers/staging/brcm80211/util/hnddma.c | 4 +- 14 files changed, 188 insertions(+), 226 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 6cde62ac7dfc..8bf731f693ff 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -735,7 +735,7 @@ static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, u32 regaddr) } /* Only the lower 17-bits are valid */ - scratch = ltoh32(scratch); + scratch = le32_to_cpu(scratch); scratch &= 0x0001FFFF; return scratch; } diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c index ed204d535942..0083f0c3775b 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c @@ -65,7 +65,7 @@ typedef struct dhd_prot { static int dhdcdc_msg(dhd_pub_t *dhd) { dhd_prot_t *prot = dhd->prot; - int len = ltoh32(prot->msg.len) + sizeof(cdc_ioctl_t); + int len = le32_to_cpu(prot->msg.len) + sizeof(cdc_ioctl_t); DHD_TRACE(("%s: Enter\n", __func__)); @@ -93,7 +93,7 @@ static int dhdcdc_cmplt(dhd_pub_t *dhd, u32 id, u32 len) len + sizeof(cdc_ioctl_t)); if (ret < 0) break; - } while (CDC_IOC_ID(ltoh32(prot->msg.flags)) != id); + } while (CDC_IOC_ID(le32_to_cpu(prot->msg.flags)) != id); return ret; } @@ -124,11 +124,11 @@ dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len) memset(msg, 0, sizeof(cdc_ioctl_t)); - msg->cmd = htol32(cmd); - msg->len = htol32(len); + msg->cmd = cpu_to_le32(cmd); + msg->len = cpu_to_le32(len); msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT); CDC_SET_IF_IDX(msg, ifidx); - msg->flags = htol32(msg->flags); + msg->flags = cpu_to_le32(msg->flags); if (buf) memcpy(prot->buf, buf, len); @@ -146,7 +146,7 @@ retry: if (ret < 0) goto done; - flags = ltoh32(msg->flags); + flags = le32_to_cpu(msg->flags); id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT; if ((id < prot->reqid) && (++retries < RETRIES)) @@ -170,7 +170,7 @@ retry: /* Check the ERROR flag */ if (flags & CDCF_IOC_ERROR) { - ret = ltoh32(msg->status); + ret = le32_to_cpu(msg->status); /* Cache error from dongle */ dhd->dongle_error = ret; } @@ -191,11 +191,11 @@ int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len) memset(msg, 0, sizeof(cdc_ioctl_t)); - msg->cmd = htol32(cmd); - msg->len = htol32(len); + msg->cmd = cpu_to_le32(cmd); + msg->len = cpu_to_le32(len); msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT) | CDCF_IOC_SET; CDC_SET_IF_IDX(msg, ifidx); - msg->flags = htol32(msg->flags); + msg->flags = cpu_to_le32(msg->flags); if (buf) memcpy(prot->buf, buf, len); @@ -208,7 +208,7 @@ int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len) if (ret < 0) goto done; - flags = ltoh32(msg->flags); + flags = le32_to_cpu(msg->flags); id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT; if (id != prot->reqid) { @@ -220,7 +220,7 @@ int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len) /* Check the ERROR flag */ if (flags & CDCF_IOC_ERROR) { - ret = ltoh32(msg->status); + ret = le32_to_cpu(msg->status); /* Cache error from dongle */ dhd->dongle_error = ret; } @@ -276,8 +276,8 @@ dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t *ioc, void *buf, int len) ret = 0; else { cdc_ioctl_t *msg = &prot->msg; - ioc->needed = ltoh32(msg->len); /* len == needed when set/query - fails from dongle */ + /* len == needed when set/query fails from dongle */ + ioc->needed = le32_to_cpu(msg->len); } /* Intercept the wme_dp ioctl here */ @@ -287,7 +287,7 @@ dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t *ioc, void *buf, int len) slen = strlen("wme_dp") + 1; if (len >= (int)(slen + sizeof(int))) memcpy(&val, (char *)buf + slen, sizeof(int)); - dhd->wme_dp = (u8) ltoh32(val); + dhd->wme_dp = (u8) le32_to_cpu(val); } prot->pending = false; diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index b2a6fb247ef9..326020049c3d 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -577,12 +577,12 @@ static void wl_show_host_event(wl_event_msg_t *event, void *event_data) WLC_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"} }; uint event_type, flags, auth_type, datalen; - event_type = ntoh32(event->event_type); - flags = ntoh16(event->flags); - status = ntoh32(event->status); - reason = ntoh32(event->reason); - auth_type = ntoh32(event->auth_type); - datalen = ntoh32(event->datalen); + event_type = be32_to_cpu(event->event_type); + flags = be16_to_cpu(event->flags); + status = be32_to_cpu(event->status); + reason = be32_to_cpu(event->reason); + auth_type = be32_to_cpu(event->auth_type); + datalen = be32_to_cpu(event->datalen); /* debug dump of event messages */ sprintf(eabuf, "%pM", event->addr); @@ -750,24 +750,24 @@ static void wl_show_host_event(wl_event_msg_t *event, void *event_data) } /* There are 2 bytes available at the end of data */ - buf[MSGTRACE_HDRLEN + ntoh16(hdr.len)] = '\0'; + buf[MSGTRACE_HDRLEN + be16_to_cpu(hdr.len)] = '\0'; - if (ntoh32(hdr.discarded_bytes) - || ntoh32(hdr.discarded_printf)) { + if (be32_to_cpu(hdr.discarded_bytes) + || be32_to_cpu(hdr.discarded_printf)) { DHD_ERROR( ("\nWLC_E_TRACE: [Discarded traces in dongle -->" "discarded_bytes %d discarded_printf %d]\n", - ntoh32(hdr.discarded_bytes), - ntoh32(hdr.discarded_printf))); + be32_to_cpu(hdr.discarded_bytes), + be32_to_cpu(hdr.discarded_printf))); } - nblost = ntoh32(hdr.seqnum) - seqnum_prev - 1; + nblost = be32_to_cpu(hdr.seqnum) - seqnum_prev - 1; if (nblost > 0) { DHD_ERROR( ("\nWLC_E_TRACE: [Event lost --> seqnum %d nblost %d\n", - ntoh32(hdr.seqnum), nblost)); + be32_to_cpu(hdr.seqnum), nblost)); } - seqnum_prev = ntoh32(hdr.seqnum); + seqnum_prev = be32_to_cpu(hdr.seqnum); /* Display the trace buffer. Advance from \n to \n to * avoid display big @@ -788,7 +788,7 @@ static void wl_show_host_event(wl_event_msg_t *event, void *event_data) case WLC_E_RSSI: DHD_EVENT(("MACEVENT: %s %d\n", event_name, - ntoh32(*((int *)event_data)))); + be32_to_cpu(*((int *)event_data)))); break; default: @@ -898,7 +898,7 @@ wl_host_event(struct dhd_info *dhd, int *ifidx, void *pktdata, temp = ntoh32_ua((void *)&event->event_type); DHD_TRACE(("Converted to WLC_E_LINK type %d\n", temp)); - temp = ntoh32(WLC_E_NDIS_LINK); + temp = be32_to_cpu(WLC_E_NDIS_LINK); memcpy((void *)(&pvt_data->event.event_type), &temp, sizeof(pvt_data->event.event_type)); } diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index ffba7461700a..b6e3c0a87006 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -713,7 +713,7 @@ static void _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) strcpy(bufp, "mcast_list"); bufp += strlen("mcast_list") + 1; - cnt = htol32(cnt); + cnt = cpu_to_le32(cnt); memcpy(bufp, &cnt, sizeof(cnt)); bufp += sizeof(cnt); @@ -752,7 +752,7 @@ static void _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) dhd_ifname(&dhd->pub, ifidx))); return; } - allmulti = htol32(allmulti); + allmulti = cpu_to_le32(allmulti); if (!bcm_mkiovar ("allmulti", (void *)&allmulti, sizeof(allmulti), buf, buflen)) { @@ -772,7 +772,8 @@ static void _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); if (ret < 0) { DHD_ERROR(("%s: set allmulti %d failed\n", - dhd_ifname(&dhd->pub, ifidx), ltoh32(allmulti))); + dhd_ifname(&dhd->pub, ifidx), + le32_to_cpu(allmulti))); } kfree(buf); @@ -781,7 +782,7 @@ static void _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) driver does */ allmulti = (dev->flags & IFF_PROMISC) ? true : false; - allmulti = htol32(allmulti); + allmulti = cpu_to_le32(allmulti); memset(&ioc, 0, sizeof(ioc)); ioc.cmd = WLC_SET_PROMISC; @@ -792,7 +793,8 @@ static void _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); if (ret < 0) { DHD_ERROR(("%s: set promisc %d failed\n", - dhd_ifname(&dhd->pub, ifidx), ltoh32(allmulti))); + dhd_ifname(&dhd->pub, ifidx), + le32_to_cpu(allmulti))); } } @@ -1028,7 +1030,7 @@ int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf) if (is_multicast_ether_addr(eh->h_dest)) dhdp->tx_multicast++; - if (ntoh16(eh->h_proto) == ETH_P_PAE) + if (ntohs(eh->h_proto) == ETH_P_PAE) atomic_inc(&dhd->pend_8021x_cnt); } @@ -1208,7 +1210,7 @@ void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf, skb_pull(skb, ETH_HLEN); /* Process special event packets and then discard them */ - if (ntoh16(skb->protocol) == ETH_P_BRCM) + if (ntohs(skb->protocol) == ETH_P_BRCM) dhd_wl_host_event(dhd, &ifidx, skb_mac_header(skb), &event, &data); @@ -1253,7 +1255,7 @@ void dhd_txcomplete(dhd_pub_t *dhdp, struct sk_buff *txp, bool success) dhd_prot_hdrpull(dhdp, &ifidx, txp); eh = (struct ethhdr *)(txp->data); - type = ntoh16(eh->h_proto); + type = ntohs(eh->h_proto); if (type == ETH_P_PAE) atomic_dec(&dhd->pend_8021x_cnt); @@ -2749,7 +2751,7 @@ dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, /* send up locally generated event */ void dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data) { - switch (ntoh32(event->event_type)) { + switch (be32_to_cpu(event->event_type)) { default: break; } diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 916c5557f7b4..d47f697540e3 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -966,8 +966,8 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ len = (u16) (pkt->len); - *(u16 *) frame = htol16(len); - *(((u16 *) frame) + 1) = htol16(~len); + *(u16 *) frame = cpu_to_le16(len); + *(((u16 *) frame) + 1) = cpu_to_le16(~len); /* Software tag: channel, sequence number, data offset */ swheader = @@ -1281,8 +1281,8 @@ int dhd_bus_txctl(struct dhd_bus *bus, unsigned char *msg, uint msglen) dhdsdio_clkctl(bus, CLK_AVAIL, false); /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ - *(u16 *) frame = htol16((u16) msglen); - *(((u16 *) frame) + 1) = htol16(~msglen); + *(u16 *) frame = cpu_to_le16((u16) msglen); + *(((u16 *) frame) + 1) = cpu_to_le16(~msglen); /* Software tag: channel, sequence number, data offset */ swheader = @@ -1768,7 +1768,7 @@ static int dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh) if (rv < 0) return rv; - addr = ltoh32(addr); + addr = le32_to_cpu(addr); DHD_INFO(("sdpcm_shared address 0x%08X\n", addr)); @@ -1789,13 +1789,13 @@ static int dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh) return rv; /* Endianness */ - sh->flags = ltoh32(sh->flags); - sh->trap_addr = ltoh32(sh->trap_addr); - sh->assert_exp_addr = ltoh32(sh->assert_exp_addr); - sh->assert_file_addr = ltoh32(sh->assert_file_addr); - sh->assert_line = ltoh32(sh->assert_line); - sh->console_addr = ltoh32(sh->console_addr); - sh->msgtrace_addr = ltoh32(sh->msgtrace_addr); + sh->flags = le32_to_cpu(sh->flags); + sh->trap_addr = le32_to_cpu(sh->trap_addr); + sh->assert_exp_addr = le32_to_cpu(sh->assert_exp_addr); + sh->assert_file_addr = le32_to_cpu(sh->assert_file_addr); + sh->assert_line = le32_to_cpu(sh->assert_line); + sh->console_addr = le32_to_cpu(sh->console_addr); + sh->msgtrace_addr = le32_to_cpu(sh->msgtrace_addr); if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) { DHD_ERROR(("%s: sdpcm_shared version %d in dhd " @@ -2008,13 +2008,13 @@ static int dhdsdio_readconsole(dhd_bus_t *bus) /* Allocate console buffer (one time only) */ if (c->buf == NULL) { - c->bufsize = ltoh32(c->log.buf_size); + c->bufsize = le32_to_cpu(c->log.buf_size); c->buf = kmalloc(c->bufsize, GFP_ATOMIC); if (c->buf == NULL) return BCME_NOMEM; } - idx = ltoh32(c->log.idx); + idx = le32_to_cpu(c->log.idx); /* Protect against corrupt value */ if (idx > c->bufsize) @@ -2026,7 +2026,7 @@ static int dhdsdio_readconsole(dhd_bus_t *bus) return BCME_OK; /* Read the console buffer */ - addr = ltoh32(c->log.buf); + addr = le32_to_cpu(c->log.buf); rv = dhdsdio_membytes(bus, false, addr, c->buf, c->bufsize); if (rv < 0) return rv; @@ -2589,7 +2589,7 @@ static int dhdsdio_write_vars(dhd_bus_t *bus) } else { varsizew = varsize / 4; varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF); - varsizew = htol32(varsizew); + varsizew = cpu_to_le32(varsizew); } DHD_INFO(("New varsize is %d, length token=0x%08x\n", varsize, @@ -4986,7 +4986,7 @@ extern int dhd_bus_console_in(dhd_pub_t *dhdp, unsigned char *msg, uint msglen) /* Zero cbuf_index */ addr = bus->console_addr + offsetof(hndrte_cons_t, cbuf_idx); - val = htol32(0); + val = cpu_to_le32(0); rv = dhdsdio_membytes(bus, true, addr, (u8 *)&val, sizeof(val)); if (rv < 0) goto done; @@ -4999,7 +4999,7 @@ extern int dhd_bus_console_in(dhd_pub_t *dhdp, unsigned char *msg, uint msglen) /* Write length into vcons_in */ addr = bus->console_addr + offsetof(hndrte_cons_t, vcons_in); - val = htol32(msglen); + val = cpu_to_le32(msglen); rv = dhdsdio_membytes(bus, true, addr, (u8 *)&val, sizeof(val)); if (rv < 0) goto done; diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index c798c75a4a88..54169c49ee2e 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -2336,8 +2336,8 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e) { - u32 event = ntoh32(e->event_type); - u16 flags = ntoh16(e->flags); + u32 event = be32_to_cpu(e->event_type); + u16 flags = be16_to_cpu(e->flags); if (event == WLC_E_LINK) { if (flags & WLC_EVENT_MSG_LINK) { @@ -2355,8 +2355,8 @@ static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e) static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e) { - u32 event = ntoh32(e->event_type); - u16 flags = ntoh16(e->flags); + u32 event = be32_to_cpu(e->event_type); + u16 flags = be16_to_cpu(e->flags); if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) { return true; @@ -2370,8 +2370,8 @@ static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e) static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e) { - u32 event = ntoh32(e->event_type); - u32 status = ntoh32(e->status); + u32 event = be32_to_cpu(e->event_type); + u32 status = be32_to_cpu(e->status); if (event == WLC_E_SET_SSID || event == WLC_E_LINK) { if (status == WLC_E_STATUS_NO_NETWORKS) @@ -2681,7 +2681,7 @@ static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data) { - u16 flags = ntoh16(e->flags); + u16 flags = be16_to_cpu(e->flags); enum nl80211_key_type key_type; rtnl_lock(); @@ -3273,7 +3273,7 @@ static s32 wl_event_handler(void *data) void wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data) { - u32 event_type = ntoh32(e->event_type); + u32 event_type = be32_to_cpu(e->event_type); struct wl_priv *wl = ndev_to_wl(ndev); #if (WL_DBG_LEVEL > 0) s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ? diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index 50cd22979d29..83e6d5c10450 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -3353,9 +3353,9 @@ wl_iw_conn_status_str(u32 event_type, u32 status, u32 reason, static bool wl_iw_check_conn_fail(wl_event_msg_t *e, char *stringBuf, uint buflen) { - u32 event = ntoh32(e->event_type); - u32 status = ntoh32(e->status); - u32 reason = ntoh32(e->reason); + u32 event = be32_to_cpu(e->event_type); + u32 status = be32_to_cpu(e->status); + u32 reason = be32_to_cpu(e->reason); if (wl_iw_conn_status_str(event, status, reason, stringBuf, buflen)) { return true; @@ -3374,10 +3374,10 @@ void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) union iwreq_data wrqu; char extra[IW_CUSTOM_MAX + 1]; int cmd = 0; - u32 event_type = ntoh32(e->event_type); - u16 flags = ntoh16(e->flags); - u32 datalen = ntoh32(e->datalen); - u32 status = ntoh32(e->status); + u32 event_type = be32_to_cpu(e->event_type); + u16 flags = be16_to_cpu(e->flags); + u32 datalen = be32_to_cpu(e->datalen); + u32 status = be32_to_cpu(e->status); wl_iw_t *iw; u32 toto; memset(&wrqu, 0, sizeof(wrqu)); diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c index 0760d97b3ba1..d869efa781d4 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c @@ -2859,7 +2859,7 @@ void BCMFASTPATH wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx) { wlc_d11rxhdr_t *wlc_rxhdr = (wlc_d11rxhdr_t *) ctx; d11rxhdr_t *rxh = &wlc_rxhdr->rxhdr; - int rssi = ltoh16(rxh->PhyRxStatus_1) & PRXS1_JSSI_MASK; + int rssi = le16_to_cpu(rxh->PhyRxStatus_1) & PRXS1_JSSI_MASK; uint radioid = pih->radioid; phy_info_t *pi = (phy_info_t *) pih; @@ -2869,13 +2869,13 @@ void BCMFASTPATH wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx) } if ((pi->sh->corerev >= 11) - && !(ltoh16(rxh->RxStatus2) & RXS_PHYRXST_VALID)) { + && !(le16_to_cpu(rxh->RxStatus2) & RXS_PHYRXST_VALID)) { rssi = WLC_RSSI_INVALID; goto end; } if (ISLCNPHY(pi)) { - u8 gidx = (ltoh16(rxh->PhyRxStatus_2) & 0xFC00) >> 10; + u8 gidx = (le16_to_cpu(rxh->PhyRxStatus_2) & 0xFC00) >> 10; phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; if (rssi > 127) diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c index c6cce8de1aee..55ce0b8c4fdd 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c @@ -21478,16 +21478,16 @@ wlc_phy_rssi_compute_nphy(phy_info_t *pi, wlc_d11rxhdr_t *wlc_rxh) s16 phyRx0_l, phyRx2_l; rxpwr = 0; - rxpwr0 = ltoh16(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR0_MASK; - rxpwr1 = (ltoh16(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR1_MASK) >> 8; + rxpwr0 = le16_to_cpu(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR0_MASK; + rxpwr1 = (le16_to_cpu(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR1_MASK) >> 8; if (rxpwr0 > 127) rxpwr0 -= 256; if (rxpwr1 > 127) rxpwr1 -= 256; - phyRx0_l = ltoh16(rxh->PhyRxStatus_0) & 0x00ff; - phyRx2_l = ltoh16(rxh->PhyRxStatus_2) & 0x00ff; + phyRx0_l = le16_to_cpu(rxh->PhyRxStatus_0) & 0x00ff; + phyRx2_l = le16_to_cpu(rxh->PhyRxStatus_2) & 0x00ff; if (phyRx2_l > 127) phyRx2_l -= 256; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index ca27e826e14f..a5a4868ff3fa 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -594,13 +594,13 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, txh = (d11txh_t *) p->data; plcp = (u8 *) (txh + 1); h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); - seq = ltoh16(h->seq_ctrl) >> SEQNUM_SHIFT; + seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT; index = TX_SEQ_TO_INDEX(seq); /* check mcl fields and test whether it can be agg'd */ - mcl = ltoh16(txh->MacTxControlLow); + mcl = le16_to_cpu(txh->MacTxControlLow); mcl &= ~TXC_AMPDU_MASK; - fbr_iscck = !(ltoh16(txh->XtraFrameTypes) & 0x3); + fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x3); ASSERT(!fbr_iscck); txh->PreloadSize = 0; /* always default to 0 */ @@ -637,7 +637,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, /* refill the bits since might be a retx mpdu */ mcl |= TXC_STARTMSDU; rts = (struct ieee80211_rts *)&txh->rts_frame; - fc = ltoh16(rts->frame_control); + fc = le16_to_cpu(rts->frame_control); if ((fc & FC_KIND_MASK) == FC_RTS) { mcl |= TXC_SENDRTS; use_rts = true; @@ -659,7 +659,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, WL_AMPDU_TX("wl%d: wlc_sendampdu: ampdu_len %d seg_cnt %d null delim %d\n", wlc->pub->unit, ampdu_len, seg_cnt, ndelim); - txh->MacTxControlLow = htol16(mcl); + txh->MacTxControlLow = cpu_to_le16(mcl); /* this packet is added */ pkt[count++] = p; @@ -784,10 +784,10 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, /* patch up the last txh */ txh = (d11txh_t *) pkt[count - 1]->data; - mcl = ltoh16(txh->MacTxControlLow); + mcl = le16_to_cpu(txh->MacTxControlLow); mcl &= ~TXC_AMPDU_MASK; mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT); - txh->MacTxControlLow = htol16(mcl); + txh->MacTxControlLow = cpu_to_le16(mcl); /* remove the null delimiter after last mpdu */ ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; @@ -795,7 +795,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, ampdu_len -= ndelim * AMPDU_DELIMITER_LEN; /* remove the pad len from last mpdu */ - fbr_iscck = ((ltoh16(txh->XtraFrameTypes) & 0x3) == 0); + fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0); len = fbr_iscck ? WLC_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) : WLC_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); ampdu_len -= roundup(len, 4) - len; @@ -812,24 +812,24 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, if (txh->MModeLen) { u16 mmodelen = wlc_calc_lsig_len(wlc, rspec, ampdu_len); - txh->MModeLen = htol16(mmodelen); + txh->MModeLen = cpu_to_le16(mmodelen); preamble_type = WLC_MM_PREAMBLE; } if (txh->MModeFbrLen) { u16 mmfbrlen = wlc_calc_lsig_len(wlc, rspec_fallback, ampdu_len); - txh->MModeFbrLen = htol16(mmfbrlen); + txh->MModeFbrLen = cpu_to_le16(mmfbrlen); fbr_preamble_type = WLC_MM_PREAMBLE; } /* set the preload length */ if (MCS_RATE(mcs, true, false) >= f->dmaxferrate) { dma_len = min(dma_len, f->ampdu_pld_size); - txh->PreloadSize = htol16(dma_len); + txh->PreloadSize = cpu_to_le16(dma_len); } else txh->PreloadSize = 0; - mch = ltoh16(txh->MacTxControlHigh); + mch = le16_to_cpu(txh->MacTxControlHigh); /* update RTS dur fields */ if (use_rts || use_cts) { @@ -848,14 +848,14 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, rspec, rts_preamble_type, preamble_type, ampdu_len, true); - rts->duration = htol16(durid); + rts->duration = cpu_to_le16(durid); durid = wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec_fallback, rspec_fallback, rts_fbr_preamble_type, fbr_preamble_type, ampdu_len, true); - txh->RTSDurFallback = htol16(durid); + txh->RTSDurFallback = cpu_to_le16(durid); /* set TxFesTimeNormal */ txh->TxFesTimeNormal = rts->duration; /* set fallback rate version of TxFesTimeNormal */ @@ -867,7 +867,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, WLCNTADD(ampdu->cnt->txfbr_mpdu, count); WLCNTINCR(ampdu->cnt->txfbr_ampdu); mch |= TXC_AMPDU_FBR; - txh->MacTxControlHigh = htol16(mch); + txh->MacTxControlHigh = cpu_to_le16(mch); WLC_SET_MIMO_PLCP_AMPDU(plcp); WLC_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback); } @@ -876,7 +876,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, wlc->pub->unit, count, ampdu_len); /* inform rate_sel if it this is a rate probe pkt */ - frameid = ltoh16(txh->TxFrameID); + frameid = le16_to_cpu(txh->TxFrameID); if (frameid & TXFID_RATE_PROBE_MASK) { WL_ERROR("%s: XXX what to do with TXFID_RATE_PROBE_MASK!?\n", __func__); @@ -1082,14 +1082,14 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, tx_info = IEEE80211_SKB_CB(p); ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); txh = (d11txh_t *) p->data; - mcl = ltoh16(txh->MacTxControlLow); + mcl = le16_to_cpu(txh->MacTxControlLow); plcp = (u8 *) (txh + 1); h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); - seq = ltoh16(h->seq_ctrl) >> SEQNUM_SHIFT; + seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT; if (tot_mpdu == 0) { mcs = plcp[0] & MIMO_PLCP_MCS_MASK; - mimoantsel = ltoh16(txh->ABI_MimoAntSel); + mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel); } index = TX_SEQ_TO_INDEX(seq); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index ac068cdc578b..9419f27e7425 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -304,7 +304,7 @@ wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound) /* record the tsf_l in wlc_rxd11hdr */ wlc_rxhdr = (wlc_d11rxhdr_t *) p->data; - wlc_rxhdr->tsf_l = htol32(tsf_l); + wlc_rxhdr->tsf_l = cpu_to_le32(tsf_l); /* compute the RSSI from d11rxhdr and record it in wlc_rxd11hr */ wlc_phy_rssi_compute(wlc_hw->band->pi, wlc_rxhdr); @@ -1701,9 +1701,9 @@ wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, int len, memcpy(&word, buf, sizeof(u32)); if (be_bit) - word = hton32(word); + word = cpu_to_be32(word); else - word = htol32(word); + word = cpu_to_le32(word); W_REG(osh, ®s->tplatewrdata, word); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index b617b6417054..e7628fa6fcd5 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -1345,13 +1345,13 @@ void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe) 0, { {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA, - HTOL16(EDCF_AC_BE_TXOP_STA)}, + cpu_to_le16(EDCF_AC_BE_TXOP_STA)}, {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA, - HTOL16(EDCF_AC_BK_TXOP_STA)}, + cpu_to_le16(EDCF_AC_BK_TXOP_STA)}, {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA, - HTOL16(EDCF_AC_VI_TXOP_STA)}, + cpu_to_le16(EDCF_AC_VI_TXOP_STA)}, {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA, - HTOL16(EDCF_AC_VO_TXOP_STA)} + cpu_to_le16(EDCF_AC_VO_TXOP_STA)} } }; @@ -1390,7 +1390,7 @@ void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend) /* wlc->wme_admctl |= 1 << aci; *//* should be set ?? seems like off by default */ /* fill in shm ac params struct */ - acp_shm.txop = ltoh16(params->txop); + acp_shm.txop = le16_to_cpu(params->txop); /* convert from units of 32us to us for ucode */ wlc->edcf_txop[aci & 0x3] = acp_shm.txop = EDCF_TXOP2USEC(acp_shm.txop); @@ -1474,7 +1474,7 @@ void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend) } /* fill in shm ac params struct */ - acp_shm.txop = ltoh16(edcf_acp->TXOP); + acp_shm.txop = le16_to_cpu(edcf_acp->TXOP); /* convert from units of 32us to us for ucode */ wlc->edcf_txop[aci] = acp_shm.txop = EDCF_TXOP2USEC(acp_shm.txop); @@ -4750,7 +4750,7 @@ wlc_ctrupd_cache(u16 cur_stat, u16 *macstat_snapshot, u32 *macstat) u16 v; u16 delta; - v = ltoh16(cur_stat); + v = le16_to_cpu(cur_stat); delta = (u16)(v - *macstat_snapshot); if (delta != 0) { @@ -4927,32 +4927,32 @@ bool wlc_chipmatch(u16 vendor, u16 device) #if defined(BCMDBG) void wlc_print_txdesc(d11txh_t *txh) { - u16 mtcl = ltoh16(txh->MacTxControlLow); - u16 mtch = ltoh16(txh->MacTxControlHigh); - u16 mfc = ltoh16(txh->MacFrameControl); - u16 tfest = ltoh16(txh->TxFesTimeNormal); - u16 ptcw = ltoh16(txh->PhyTxControlWord); - u16 ptcw_1 = ltoh16(txh->PhyTxControlWord_1); - u16 ptcw_1_Fbr = ltoh16(txh->PhyTxControlWord_1_Fbr); - u16 ptcw_1_Rts = ltoh16(txh->PhyTxControlWord_1_Rts); - u16 ptcw_1_FbrRts = ltoh16(txh->PhyTxControlWord_1_FbrRts); - u16 mainrates = ltoh16(txh->MainRates); - u16 xtraft = ltoh16(txh->XtraFrameTypes); + u16 mtcl = le16_to_cpu(txh->MacTxControlLow); + u16 mtch = le16_to_cpu(txh->MacTxControlHigh); + u16 mfc = le16_to_cpu(txh->MacFrameControl); + u16 tfest = le16_to_cpu(txh->TxFesTimeNormal); + u16 ptcw = le16_to_cpu(txh->PhyTxControlWord); + u16 ptcw_1 = le16_to_cpu(txh->PhyTxControlWord_1); + u16 ptcw_1_Fbr = le16_to_cpu(txh->PhyTxControlWord_1_Fbr); + u16 ptcw_1_Rts = le16_to_cpu(txh->PhyTxControlWord_1_Rts); + u16 ptcw_1_FbrRts = le16_to_cpu(txh->PhyTxControlWord_1_FbrRts); + u16 mainrates = le16_to_cpu(txh->MainRates); + u16 xtraft = le16_to_cpu(txh->XtraFrameTypes); u8 *iv = txh->IV; u8 *ra = txh->TxFrameRA; - u16 tfestfb = ltoh16(txh->TxFesTimeFallback); + u16 tfestfb = le16_to_cpu(txh->TxFesTimeFallback); u8 *rtspfb = txh->RTSPLCPFallback; - u16 rtsdfb = ltoh16(txh->RTSDurFallback); + u16 rtsdfb = le16_to_cpu(txh->RTSDurFallback); u8 *fragpfb = txh->FragPLCPFallback; - u16 fragdfb = ltoh16(txh->FragDurFallback); - u16 mmodelen = ltoh16(txh->MModeLen); - u16 mmodefbrlen = ltoh16(txh->MModeFbrLen); - u16 tfid = ltoh16(txh->TxFrameID); - u16 txs = ltoh16(txh->TxStatus); - u16 mnmpdu = ltoh16(txh->MaxNMpdus); - u16 mabyte = ltoh16(txh->MaxABytes_MRT); - u16 mabyte_f = ltoh16(txh->MaxABytes_FBR); - u16 mmbyte = ltoh16(txh->MinMBytes); + u16 fragdfb = le16_to_cpu(txh->FragDurFallback); + u16 mmodelen = le16_to_cpu(txh->MModeLen); + u16 mmodefbrlen = le16_to_cpu(txh->MModeFbrLen); + u16 tfid = le16_to_cpu(txh->TxFrameID); + u16 txs = le16_to_cpu(txh->TxStatus); + u16 mnmpdu = le16_to_cpu(txh->MaxNMpdus); + u16 mabyte = le16_to_cpu(txh->MaxABytes_MRT); + u16 mabyte_f = le16_to_cpu(txh->MaxABytes_FBR); + u16 mmbyte = le16_to_cpu(txh->MinMBytes); u8 *rtsph = txh->RTSPhyHeader; struct ieee80211_rts rts = txh->rts_frame; @@ -5213,7 +5213,7 @@ wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, ASSERT(sdu); - fc = ltoh16(d11_header->frame_control); + fc = le16_to_cpu(d11_header->frame_control); type = (fc & IEEE80211_FCTL_FTYPE); /* 802.11 standard requires management traffic to go at highest priority */ @@ -5315,7 +5315,8 @@ bcmc_fid_generate(struct wlc_info *wlc, wlc_bsscfg_t *bsscfg, d11txh_t *txh) { u16 frameid; - frameid = ltoh16(txh->TxFrameID) & ~(TXFID_SEQ_MASK | TXFID_QUEUE_MASK); + frameid = le16_to_cpu(txh->TxFrameID) & ~(TXFID_SEQ_MASK | + TXFID_QUEUE_MASK); frameid |= (((wlc-> mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) | @@ -5338,7 +5339,7 @@ wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit, * ucode or BSS info as appropriate. */ if (fifo == TX_BCMC_FIFO) { - frameid = ltoh16(txh->TxFrameID); + frameid = le16_to_cpu(txh->TxFrameID); } @@ -5789,7 +5790,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* locate 802.11 MAC header */ h = (struct ieee80211_hdr *)(p->data); - fc = ltoh16(h->frame_control); + fc = le16_to_cpu(h->frame_control); type = (fc & IEEE80211_FCTL_FTYPE); qos = (type == IEEE80211_FTYPE_DATA && @@ -5834,9 +5835,9 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, } /* extract fragment number from frame first */ - seq = ltoh16(seq) & FRAGNUM_MASK; + seq = le16_to_cpu(seq) & FRAGNUM_MASK; seq |= (SCB_SEQNUM(scb, p->priority) << SEQNUM_SHIFT); - h->seq_ctrl = htol16(seq); + h->seq_ctrl = cpu_to_le16(seq); frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) | (queue & TXFID_QUEUE_MASK); @@ -6078,7 +6079,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, durid = wlc_compute_frame_dur(wlc, rspec[0], preamble_type[0], next_frag_len); - h->duration_id = htol16(durid); + h->duration_id = cpu_to_le16(durid); } else if (use_rifs) { /* NAV protect to end of next max packet size */ durid = @@ -6086,7 +6087,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, preamble_type[0], DOT11_MAX_FRAG_LEN); durid += RIFS_11N_TIME; - h->duration_id = htol16(durid); + h->duration_id = cpu_to_le16(durid); } /* DUR field for fallback rate */ @@ -6097,7 +6098,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, else { durid = wlc_compute_frame_dur(wlc, rspec[1], preamble_type[1], next_frag_len); - txh->FragDurFallback = htol16(durid); + txh->FragDurFallback = cpu_to_le16(durid); } /* (4) MAC-HDR: MacTxControlLow */ @@ -6117,7 +6118,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, if (hwtkmic) mcl |= TXC_AMIC; - txh->MacTxControlLow = htol16(mcl); + txh->MacTxControlLow = cpu_to_le16(mcl); /* MacTxControlHigh */ mch = 0; @@ -6133,28 +6134,28 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* MacFrameControl */ memcpy(&txh->MacFrameControl, &h->frame_control, sizeof(u16)); - txh->TxFesTimeNormal = htol16(0); + txh->TxFesTimeNormal = cpu_to_le16(0); - txh->TxFesTimeFallback = htol16(0); + txh->TxFesTimeFallback = cpu_to_le16(0); /* TxFrameRA */ memcpy(&txh->TxFrameRA, &h->addr1, ETH_ALEN); /* TxFrameID */ - txh->TxFrameID = htol16(frameid); + txh->TxFrameID = cpu_to_le16(frameid); /* TxStatus, Note the case of recreating the first frag of a suppressed frame * then we may need to reset the retry cnt's via the status reg */ - txh->TxStatus = htol16(status); + txh->TxStatus = cpu_to_le16(status); /* extra fields for ucode AMPDU aggregation, the new fields are added to * the END of previous structure so that it's compatible in driver. */ - txh->MaxNMpdus = htol16(0); - txh->MaxABytes_MRT = htol16(0); - txh->MaxABytes_FBR = htol16(0); - txh->MinMBytes = htol16(0); + txh->MaxNMpdus = cpu_to_le16(0); + txh->MaxABytes_MRT = cpu_to_le16(0); + txh->MaxABytes_FBR = cpu_to_le16(0); + txh->MinMBytes = cpu_to_le16(0); /* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration, furnish d11txh_t */ /* RTS PLCP header and RTS frame */ @@ -6184,10 +6185,10 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* RTS/CTS additions to MacTxControlLow */ if (use_cts) { - txh->MacTxControlLow |= htol16(TXC_SENDCTS); + txh->MacTxControlLow |= cpu_to_le16(TXC_SENDCTS); } else { - txh->MacTxControlLow |= htol16(TXC_SENDRTS); - txh->MacTxControlLow |= htol16(TXC_LONGFRAME); + txh->MacTxControlLow |= cpu_to_le16(TXC_SENDRTS); + txh->MacTxControlLow |= cpu_to_le16(TXC_LONGFRAME); } /* RTS PLCP header */ @@ -6212,19 +6213,19 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, durid = wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec[0], rspec[0], rts_preamble_type[0], preamble_type[0], phylen, false); - rts->duration = htol16(durid); + rts->duration = cpu_to_le16(durid); /* fallback rate version of RTS DUR field */ durid = wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec[1], rspec[1], rts_preamble_type[1], preamble_type[1], phylen, false); - txh->RTSDurFallback = htol16(durid); + txh->RTSDurFallback = cpu_to_le16(durid); if (use_cts) { - rts->frame_control = htol16(FC_CTS); + rts->frame_control = cpu_to_le16(FC_CTS); memcpy(&rts->ra, &h->addr2, ETH_ALEN); } else { - rts->frame_control = htol16((u16) FC_RTS); + rts->frame_control = cpu_to_le16((u16) FC_RTS); memcpy(&rts->ra, &h->addr1, 2 * ETH_ALEN); } @@ -6253,10 +6254,10 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, #endif /* Now that RTS/RTS FB preamble types are updated, write the final value */ - txh->MacTxControlHigh = htol16(mch); + txh->MacTxControlHigh = cpu_to_le16(mch); /* MainRates (both the rts and frag plcp rates have been calculated now) */ - txh->MainRates = htol16(mainrates); + txh->MainRates = cpu_to_le16(mainrates); /* XtraFrameTypes */ xfts = FRAMETYPE(rspec[1], wlc->mimoft); @@ -6264,7 +6265,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, xfts |= (FRAMETYPE(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT); xfts |= CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC) << XFTS_CHANNEL_SHIFT; - txh->XtraFrameTypes = htol16(xfts); + txh->XtraFrameTypes = cpu_to_le16(xfts); /* PhyTxControlWord */ phyctl = FRAMETYPE(rspec[0], wlc->mimoft); @@ -6279,22 +6280,22 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* phytxant is properly bit shifted */ phyctl |= wlc_stf_d11hdrs_phyctl_txant(wlc, rspec[0]); - txh->PhyTxControlWord = htol16(phyctl); + txh->PhyTxControlWord = cpu_to_le16(phyctl); /* PhyTxControlWord_1 */ if (WLC_PHY_11N_CAP(wlc->band)) { u16 phyctl1 = 0; phyctl1 = wlc_phytxctl1_calc(wlc, rspec[0]); - txh->PhyTxControlWord_1 = htol16(phyctl1); + txh->PhyTxControlWord_1 = cpu_to_le16(phyctl1); phyctl1 = wlc_phytxctl1_calc(wlc, rspec[1]); - txh->PhyTxControlWord_1_Fbr = htol16(phyctl1); + txh->PhyTxControlWord_1_Fbr = cpu_to_le16(phyctl1); if (use_rts || use_cts) { phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[0]); - txh->PhyTxControlWord_1_Rts = htol16(phyctl1); + txh->PhyTxControlWord_1_Rts = cpu_to_le16(phyctl1); phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[1]); - txh->PhyTxControlWord_1_FbrRts = htol16(phyctl1); + txh->PhyTxControlWord_1_FbrRts = cpu_to_le16(phyctl1); } /* @@ -6305,13 +6306,13 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, if (IS_MCS(rspec[0]) && (preamble_type[0] == WLC_MM_PREAMBLE)) { u16 mmodelen = wlc_calc_lsig_len(wlc, rspec[0], phylen); - txh->MModeLen = htol16(mmodelen); + txh->MModeLen = cpu_to_le16(mmodelen); } if (IS_MCS(rspec[1]) && (preamble_type[1] == WLC_MM_PREAMBLE)) { u16 mmodefbrlen = wlc_calc_lsig_len(wlc, rspec[1], phylen); - txh->MModeFbrLen = htol16(mmodefbrlen); + txh->MModeFbrLen = cpu_to_le16(mmodefbrlen); } } @@ -6345,8 +6346,9 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, wlc_calc_cts_time(wlc, rts_rspec[1], rts_preamble_type[1]); /* (SIFS + CTS) + SIFS + frame + SIFS + ACK */ - dur += ltoh16(rts->duration); - dur_fallback += ltoh16(txh->RTSDurFallback); + dur += le16_to_cpu(rts->duration); + dur_fallback += + le16_to_cpu(txh->RTSDurFallback); } else if (use_rifs) { dur = frag_dur; dur_fallback = 0; @@ -6366,9 +6368,10 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, preamble_type[1], 0); } /* NEED to set TxFesTimeNormal (hard) */ - txh->TxFesTimeNormal = htol16((u16) dur); + txh->TxFesTimeNormal = cpu_to_le16((u16) dur); /* NEED to set fallback rate version of TxFesTimeNormal (hard) */ - txh->TxFesTimeFallback = htol16((u16) dur_fallback); + txh->TxFesTimeFallback = + cpu_to_le16((u16) dur_fallback); /* update txop byte threshold (txop minus intraframe overhead) */ if (wlc->edcf_txop[ac] >= (dur - frag_dur)) { @@ -6636,7 +6639,7 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) goto fatal; txh = (d11txh_t *) (p->data); - mcl = ltoh16(txh->MacTxControlLow); + mcl = le16_to_cpu(txh->MacTxControlLow); if (txs->phyerr) { if (WL_ERROR_ON()) { @@ -6647,13 +6650,13 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) wlc_print_txstatus(txs); } - ASSERT(txs->frameid == htol16(txh->TxFrameID)); - if (txs->frameid != htol16(txh->TxFrameID)) + ASSERT(txs->frameid == cpu_to_le16(txh->TxFrameID)); + if (txs->frameid != cpu_to_le16(txh->TxFrameID)) goto fatal; tx_info = IEEE80211_SKB_CB(p); h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); - fc = ltoh16(h->frame_control); + fc = le16_to_cpu(h->frame_control); scb = (struct scb *)tx_info->control.sta->drv_priv; @@ -6676,7 +6679,7 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) WL_NONE("%s: Pkt tx suppressed, possibly channel %d\n", __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec)); - tx_rts = htol16(txh->MacTxControlLow) & TXC_SENDRTS; + tx_rts = cpu_to_le16(txh->MacTxControlLow) & TXC_SENDRTS; tx_frame_count = (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT; tx_rts_count = @@ -7091,7 +7094,7 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) /* check received pkt has at least frame control field */ if (len >= D11_PHY_HDR_LEN + sizeof(h->frame_control)) { - fc = ltoh16(h->frame_control); + fc = le16_to_cpu(h->frame_control); } else { wlc->pub->_cnt->rxrunt++; goto toss; @@ -7716,7 +7719,7 @@ wlc_bcn_prb_template(struct wlc_info *wlc, uint type, ratespec_t bcn_rspec, h = (struct ieee80211_mgmt *)&plcp[1]; /* fill in 802.11 header */ - h->frame_control = htol16((u16) type); + h->frame_control = cpu_to_le16((u16) type); /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */ /* A1 filled in by MAC for prb resp, broadcast for bcn */ @@ -7892,10 +7895,10 @@ int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) ASSERT(txh); h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); ASSERT(h); - fc = ltoh16(h->frame_control); + fc = le16_to_cpu(h->frame_control); /* get the pkt queue info. This was put at wlc_sendctl or wlc_send for PDU */ - fifo = ltoh16(txh->TxFrameID) & TXFID_QUEUE_MASK; + fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK; scb = NULL; @@ -7908,8 +7911,7 @@ int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) return BCME_BUSY; } - if ((ltoh16(txh->MacFrameControl) & IEEE80211_FCTL_FTYPE) != - IEEE80211_FTYPE_DATA) + if (!ieee80211_is_data(txh->MacFrameControl)) wlc->pub->_cnt->txctl++; return 0; diff --git a/drivers/staging/brcm80211/include/bcmendian.h b/drivers/staging/brcm80211/include/bcmendian.h index 4123aefa211c..44b9f91f60ee 100644 --- a/drivers/staging/brcm80211/include/bcmendian.h +++ b/drivers/staging/brcm80211/include/bcmendian.h @@ -34,48 +34,6 @@ ((u32)((((u32)(val) & (u32)0x0000ffffU) << 16) | \ (((u32)(val) & (u32)0xffff0000U) >> 16))) -/* Byte swapping macros - * Host <=> Network (Big Endian) for 16- and 32-bit values - * Host <=> Little-Endian for 16- and 32-bit values - */ -#ifndef hton16 -#ifndef IL_BIGENDIAN -#define HTON16(i) BCMSWAP16(i) -#define hton16(i) bcmswap16(i) -#define HTON32(i) BCMSWAP32(i) -#define hton32(i) bcmswap32(i) -#define NTOH16(i) BCMSWAP16(i) -#define ntoh16(i) bcmswap16(i) -#define NTOH32(i) BCMSWAP32(i) -#define ntoh32(i) bcmswap32(i) -#define LTOH16(i) (i) -#define ltoh16(i) (i) -#define LTOH32(i) (i) -#define ltoh32(i) (i) -#define HTOL16(i) (i) -#define htol16(i) (i) -#define HTOL32(i) (i) -#define htol32(i) (i) -#else /* IL_BIGENDIAN */ -#define HTON16(i) (i) -#define hton16(i) (i) -#define HTON32(i) (i) -#define hton32(i) (i) -#define NTOH16(i) (i) -#define ntoh16(i) (i) -#define NTOH32(i) (i) -#define ntoh32(i) (i) -#define LTOH16(i) BCMSWAP16(i) -#define ltoh16(i) bcmswap16(i) -#define LTOH32(i) BCMSWAP32(i) -#define ltoh32(i) bcmswap32(i) -#define HTOL16(i) BCMSWAP16(i) -#define htol16(i) bcmswap16(i) -#define HTOL32(i) BCMSWAP32(i) -#define htol32(i) bcmswap32(i) -#endif /* IL_BIGENDIAN */ -#endif /* hton16 */ - #ifndef IL_BIGENDIAN #define ltoh16_buf(buf, i) #define htol16_buf(buf, i) diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 3f1d63ee7c48..5d6489121b0a 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -746,7 +746,7 @@ static void *BCMFASTPATH _dma_rx(dma_info_t *di) if (head == NULL) return NULL; - len = ltoh16(*(u16 *) (head->data)); + len = le16_to_cpu(*(u16 *) (head->data)); DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); #if defined(__mips__) @@ -755,7 +755,7 @@ static void *BCMFASTPATH _dma_rx(dma_info_t *di) while (!(len = *(u16 *) OSL_UNCACHED(head->data))) udelay(1); - *(u16 *) (head->data) = htol16((u16) len); + *(u16 *) (head->data) = cpu_to_le16((u16) len); } #endif /* defined(__mips__) */ -- cgit v1.2.3 From 56dfe3c71b3c982b8c23e38a04bc68d6e57b482e Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Sun, 20 Feb 2011 21:43:33 +0300 Subject: staging: brcm80211: replace broadcom specific unaligned byte swapping routines htol16_ua_store -> put_unaligned_le16 htol32_ua_store -> put_unaligned_le32 hton16_ua_store -> put_unaligned_be16 hton32_ua_store -> put_unaligned_be32 ltoh16_ua -> get_unaligned_le16 ltoh32_ua -> get_unaligned_le32 ntoh16_ua -> get_unaligned_be16 ntoh32_ua -> get_unaligned_be32 removed unused: - load32_ua - load16_ua - store32_ua - store16_ua - ltoh_ua - ntoh_au Signed-off-by: Stanislav Fomichev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_common.c | 12 +- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 29 ++--- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 5 +- drivers/staging/brcm80211/include/bcmendian.h | 154 ------------------------ 4 files changed, 23 insertions(+), 177 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index 326020049c3d..5b8720d88ec0 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -826,7 +826,7 @@ wl_host_event(struct dhd_info *dhd, int *ifidx, void *pktdata, } /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */ - if (ntoh16_ua((void *)&pvt_data->bcm_hdr.usr_subtype) != + if (get_unaligned_be16(&pvt_data->bcm_hdr.usr_subtype) != BCMILCP_BCM_SUBTYPE_EVENT) { DHD_ERROR(("%s: mismatched subtype, bailing\n", __func__)); return BCME_ERROR; @@ -838,10 +838,10 @@ wl_host_event(struct dhd_info *dhd, int *ifidx, void *pktdata, /* memcpy since BRCM event pkt may be unaligned. */ memcpy(event, &pvt_data->event, sizeof(wl_event_msg_t)); - type = ntoh32_ua((void *)&event->event_type); - flags = ntoh16_ua((void *)&event->flags); - status = ntoh32_ua((void *)&event->status); - evlen = ntoh32_ua((void *)&event->datalen) + sizeof(bcm_event_t); + type = get_unaligned_be32(&event->event_type); + flags = get_unaligned_be16(&event->flags); + status = get_unaligned_be32(&event->status); + evlen = get_unaligned_be32(&event->datalen) + sizeof(bcm_event_t); switch (type) { case WLC_E_IF: @@ -895,7 +895,7 @@ wl_host_event(struct dhd_info *dhd, int *ifidx, void *pktdata, if (type == WLC_E_NDIS_LINK) { u32 temp; - temp = ntoh32_ua((void *)&event->event_type); + temp = get_unaligned_be32(&event->event_type); DHD_TRACE(("Converted to WLC_E_LINK type %d\n", temp)); temp = be32_to_cpu(WLC_E_NDIS_LINK); diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index d47f697540e3..41b76afe7c39 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -974,8 +974,9 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | bus->tx_seq | (((pad + SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK); - htol32_ua_store(swheader, frame + SDPCM_FRAMETAG_LEN); - htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); + + put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN); + put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); #ifdef DHD_DEBUG tx_packets[pkt->priority]++; @@ -1290,8 +1291,8 @@ int dhd_bus_txctl(struct dhd_bus *bus, unsigned char *msg, uint msglen) SDPCM_CHANNEL_MASK) | bus->tx_seq | ((doff << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK); - htol32_ua_store(swheader, frame + SDPCM_FRAMETAG_LEN); - htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); + put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN); + put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); if (!DATAOK(bus)) { DHD_INFO(("%s: No bus credit bus->tx_max %d, bus->tx_seq %d\n", @@ -3213,7 +3214,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) for (totlen = num = 0; dlen; num++) { /* Get (and move past) next length */ - sublen = ltoh16_ua(dptr); + sublen = get_unaligned_le16(dptr); dlen -= sizeof(u16); dptr += sizeof(u16); if ((sublen < SDPCM_HDRLEN) || @@ -3366,8 +3367,8 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) /* Validate the superframe header */ dptr = (u8 *) (pfirst->data); - sublen = ltoh16_ua(dptr); - check = ltoh16_ua(dptr + sizeof(u16)); + sublen = get_unaligned_le16(dptr); + check = get_unaligned_le16(dptr + sizeof(u16)); chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); @@ -3436,8 +3437,8 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) num++, pnext = pnext->next) { dptr = (u8 *) (pnext->data); dlen = (u16) (pnext->len); - sublen = ltoh16_ua(dptr); - check = ltoh16_ua(dptr + sizeof(u16)); + sublen = get_unaligned_le16(dptr); + check = get_unaligned_le16(dptr + sizeof(u16)); chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); #ifdef DHD_DEBUG @@ -3499,7 +3500,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) pfirst->next = NULL; dptr = (u8 *) (pfirst->data); - sublen = ltoh16_ua(dptr); + sublen = get_unaligned_le16(dptr); chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); @@ -3772,8 +3773,8 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) memcpy(bus->rxhdr, rxbuf, SDPCM_HDRLEN); /* Extract hardware header fields */ - len = ltoh16_ua(bus->rxhdr); - check = ltoh16_ua(bus->rxhdr + sizeof(u16)); + len = get_unaligned_le16(bus->rxhdr); + check = get_unaligned_le16(bus->rxhdr + sizeof(u16)); /* All zeros means readahead info was bad */ if (!(len | check)) { @@ -3964,8 +3965,8 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) #endif /* Extract hardware header fields */ - len = ltoh16_ua(bus->rxhdr); - check = ltoh16_ua(bus->rxhdr + sizeof(u16)); + len = get_unaligned_le16(bus->rxhdr); + check = get_unaligned_le16(bus->rxhdr + sizeof(u16)); /* All zeros means no more frames */ if (!(len | check)) { diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index 83e6d5c10450..eb31c74f65d4 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -3480,9 +3480,8 @@ void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) cmd = IWEVPMKIDCAND; pmkcandlist = data; - count = - ntoh32_ua((u8 *) & - pmkcandlist->npmkid_cand); + count = get_unaligned_be32(&pmkcandlist-> + npmkid_cand); ASSERT(count >= 0); wrqu.data.length = sizeof(struct iw_pmkid_cand); pmkidcand = pmkcandlist->pmkid_cand; diff --git a/drivers/staging/brcm80211/include/bcmendian.h b/drivers/staging/brcm80211/include/bcmendian.h index 44b9f91f60ee..a22116ae5f81 100644 --- a/drivers/staging/brcm80211/include/bcmendian.h +++ b/drivers/staging/brcm80211/include/bcmendian.h @@ -42,36 +42,6 @@ #define htol16_buf(buf, i) bcmswap16_buf((u16 *)(buf), (i)) #endif /* IL_BIGENDIAN */ -/* Unaligned loads and stores in host byte order */ -#ifndef IL_BIGENDIAN -#define load32_ua(a) ltoh32_ua(a) -#define store32_ua(a, v) htol32_ua_store(v, a) -#define load16_ua(a) ltoh16_ua(a) -#define store16_ua(a, v) htol16_ua_store(v, a) -#else -#define load32_ua(a) ntoh32_ua(a) -#define store32_ua(a, v) hton32_ua_store(v, a) -#define load16_ua(a) ntoh16_ua(a) -#define store16_ua(a, v) hton16_ua_store(v, a) -#endif /* IL_BIGENDIAN */ - -#define _LTOH16_UA(cp) ((cp)[0] | ((cp)[1] << 8)) -#define _LTOH32_UA(cp) ((cp)[0] | ((cp)[1] << 8) | ((cp)[2] << 16) | ((cp)[3] << 24)) -#define _NTOH16_UA(cp) (((cp)[0] << 8) | (cp)[1]) -#define _NTOH32_UA(cp) (((cp)[0] << 24) | ((cp)[1] << 16) | ((cp)[2] << 8) | (cp)[3]) - -#define ltoh_ua(ptr) \ - (sizeof(*(ptr)) == sizeof(u8) ? *(const u8 *)(ptr) : \ - sizeof(*(ptr)) == sizeof(u16) ? _LTOH16_UA((const u8 *)(ptr)) : \ - sizeof(*(ptr)) == sizeof(u32) ? _LTOH32_UA((const u8 *)(ptr)) : \ - *(u8 *)0) - -#define ntoh_ua(ptr) \ - (sizeof(*(ptr)) == sizeof(u8) ? *(const u8 *)(ptr) : \ - sizeof(*(ptr)) == sizeof(u16) ? _NTOH16_UA((const u8 *)(ptr)) : \ - sizeof(*(ptr)) == sizeof(u32) ? _NTOH32_UA((const u8 *)(ptr)) : \ - *(u8 *)0) - #ifdef __GNUC__ /* GNU macro versions avoid referencing the argument multiple times, while also @@ -102,58 +72,6 @@ } \ }) -#define htol16_ua_store(val, bytes) ({ \ - u16 _val = (val); \ - u8 *_bytes = (u8 *)(bytes); \ - _bytes[0] = _val & 0xff; \ - _bytes[1] = _val >> 8; \ -}) - -#define htol32_ua_store(val, bytes) ({ \ - u32 _val = (val); \ - u8 *_bytes = (u8 *)(bytes); \ - _bytes[0] = _val & 0xff; \ - _bytes[1] = (_val >> 8) & 0xff; \ - _bytes[2] = (_val >> 16) & 0xff; \ - _bytes[3] = _val >> 24; \ -}) - -#define hton16_ua_store(val, bytes) ({ \ - u16 _val = (val); \ - u8 *_bytes = (u8 *)(bytes); \ - _bytes[0] = _val >> 8; \ - _bytes[1] = _val & 0xff; \ -}) - -#define hton32_ua_store(val, bytes) ({ \ - u32 _val = (val); \ - u8 *_bytes = (u8 *)(bytes); \ - _bytes[0] = _val >> 24; \ - _bytes[1] = (_val >> 16) & 0xff; \ - _bytes[2] = (_val >> 8) & 0xff; \ - _bytes[3] = _val & 0xff; \ -}) - -#define ltoh16_ua(bytes) ({ \ - const u8 *_bytes = (const u8 *)(bytes); \ - _LTOH16_UA(_bytes); \ -}) - -#define ltoh32_ua(bytes) ({ \ - const u8 *_bytes = (const u8 *)(bytes); \ - _LTOH32_UA(_bytes); \ -}) - -#define ntoh16_ua(bytes) ({ \ - const u8 *_bytes = (const u8 *)(bytes); \ - _NTOH16_UA(_bytes); \ -}) - -#define ntoh32_ua(bytes) ({ \ - const u8 *_bytes = (const u8 *)(bytes); \ - _NTOH32_UA(_bytes); \ -}) - #else /* !__GNUC__ */ /* Inline versions avoid referencing the argument multiple times */ @@ -185,77 +103,5 @@ static inline void bcmswap16_buf(u16 *buf, uint len) } } -/* - * Store 16-bit value to unaligned little-endian byte array. - */ -static inline void htol16_ua_store(u16 val, u8 *bytes) -{ - bytes[0] = val & 0xff; - bytes[1] = val >> 8; -} - -/* - * Store 32-bit value to unaligned little-endian byte array. - */ -static inline void htol32_ua_store(u32 val, u8 *bytes) -{ - bytes[0] = val & 0xff; - bytes[1] = (val >> 8) & 0xff; - bytes[2] = (val >> 16) & 0xff; - bytes[3] = val >> 24; -} - -/* - * Store 16-bit value to unaligned network-(big-)endian byte array. - */ -static inline void hton16_ua_store(u16 val, u8 *bytes) -{ - bytes[0] = val >> 8; - bytes[1] = val & 0xff; -} - -/* - * Store 32-bit value to unaligned network-(big-)endian byte array. - */ -static inline void hton32_ua_store(u32 val, u8 *bytes) -{ - bytes[0] = val >> 24; - bytes[1] = (val >> 16) & 0xff; - bytes[2] = (val >> 8) & 0xff; - bytes[3] = val & 0xff; -} - -/* - * Load 16-bit value from unaligned little-endian byte array. - */ -static inline u16 ltoh16_ua(const void *bytes) -{ - return _LTOH16_UA((const u8 *)bytes); -} - -/* - * Load 32-bit value from unaligned little-endian byte array. - */ -static inline u32 ltoh32_ua(const void *bytes) -{ - return _LTOH32_UA((const u8 *)bytes); -} - -/* - * Load 16-bit value from unaligned big-(network-)endian byte array. - */ -static inline u16 ntoh16_ua(const void *bytes) -{ - return _NTOH16_UA((const u8 *)bytes); -} - -/* - * Load 32-bit value from unaligned big-(network-)endian byte array. - */ -static inline u32 ntoh32_ua(const void *bytes) -{ - return _NTOH32_UA((const u8 *)bytes); -} - #endif /* !__GNUC__ */ #endif /* !_BCMENDIAN_H_ */ -- cgit v1.2.3 From 458b2e4df48ea3d09f3cca952379cbf98668c0b3 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Sun, 20 Feb 2011 21:43:34 +0300 Subject: staging: brcm80211: remove unused broadcom byte swapping macroses - BCMSWAP32 - bcmswap32 - BCMSWAP32BY16 - bcmswap32by16 Signed-off-by: Stanislav Fomichev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/bcmendian.h | 32 --------------------------- 1 file changed, 32 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/bcmendian.h b/drivers/staging/brcm80211/include/bcmendian.h index a22116ae5f81..61c4edb98046 100644 --- a/drivers/staging/brcm80211/include/bcmendian.h +++ b/drivers/staging/brcm80211/include/bcmendian.h @@ -22,18 +22,6 @@ ((u16)((((u16)(val) & (u16)0x00ffU) << 8) | \ (((u16)(val) & (u16)0xff00U) >> 8))) -/* Reverse the bytes in a 32-bit value */ -#define BCMSWAP32(val) \ - ((u32)((((u32)(val) & (u32)0x000000ffU) << 24) | \ - (((u32)(val) & (u32)0x0000ff00U) << 8) | \ - (((u32)(val) & (u32)0x00ff0000U) >> 8) | \ - (((u32)(val) & (u32)0xff000000U) >> 24))) - -/* Reverse the two 16-bit halves of a 32-bit value */ -#define BCMSWAP32BY16(val) \ - ((u32)((((u32)(val) & (u32)0x0000ffffU) << 16) | \ - (((u32)(val) & (u32)0xffff0000U) >> 16))) - #ifndef IL_BIGENDIAN #define ltoh16_buf(buf, i) #define htol16_buf(buf, i) @@ -53,16 +41,6 @@ BCMSWAP16(_val); \ }) -#define bcmswap32(val) ({ \ - u32 _val = (val); \ - BCMSWAP32(_val); \ -}) - -#define bcmswap32by16(val) ({ \ - u32 _val = (val); \ - BCMSWAP32BY16(_val); \ -}) - #define bcmswap16_buf(buf, len) ({ \ u16 *_buf = (u16 *)(buf); \ uint _wds = (len) / 2; \ @@ -80,16 +58,6 @@ static inline u16 bcmswap16(u16 val) return BCMSWAP16(val); } -static inline u32 bcmswap32(u32 val) -{ - return BCMSWAP32(val); -} - -static inline u32 bcmswap32by16(u32 val) -{ - return BCMSWAP32BY16(val); -} - /* Reverse pairs of bytes in a buffer (not for high-performance use) */ /* buf - start of buffer of shorts to swap */ /* len - byte length of buffer */ -- cgit v1.2.3 From 29750b90b51ba58b0611718072991bbf7a2b8062 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Sun, 20 Feb 2011 21:43:35 +0300 Subject: staging: brcm80211: replace htod/dtoh broadcom defines htod32 -> cpu_to_le32 htod16 -> cpu_to_le16 dtoh32 -> le32_to_cpu dtoh16 -> le16_to_cpu For brcmfmac/dhd_common.c just removed defines. Signed-off-by: Stanislav Fomichev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_common.c | 97 ++++----- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 134 ++++++------ drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h | 20 +- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 264 +++++++++++------------ 4 files changed, 239 insertions(+), 276 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index 5b8720d88ec0..44dabd186eae 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -37,11 +37,6 @@ u32 dhd_conn_event; u32 dhd_conn_status; u32 dhd_conn_reason; -#define htod32(i) i -#define htod16(i) i -#define dtoh32(i) i -#define dtoh16(i) i - extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len); extern void dhd_ind_scan_confirm(void *h, bool status); @@ -975,10 +970,10 @@ dhd_pktfilter_offload_enable(dhd_pub_t *dhd, char *arg, int enable, pkt_filterp = (wl_pkt_filter_enable_t *) (buf + str_len + 1); /* Parse packet filter id. */ - enable_parm.id = htod32(simple_strtoul(argv[i], NULL, 0)); + enable_parm.id = simple_strtoul(argv[i], NULL, 0); /* Parse enable/disable value. */ - enable_parm.enable = htod32(enable); + enable_parm.enable = enable; buf_len += sizeof(enable_parm); memcpy((char *)pkt_filterp, &enable_parm, sizeof(enable_parm)); @@ -1063,7 +1058,7 @@ void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg) pkt_filterp = (wl_pkt_filter_t *) (buf + str_len + 1); /* Parse packet filter id. */ - pkt_filter.id = htod32(simple_strtoul(argv[i], NULL, 0)); + pkt_filter.id = simple_strtoul(argv[i], NULL, 0); if (NULL == argv[++i]) { DHD_ERROR(("Polarity not provided\n")); @@ -1071,7 +1066,7 @@ void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg) } /* Parse filter polarity. */ - pkt_filter.negate_match = htod32(simple_strtoul(argv[i], NULL, 0)); + pkt_filter.negate_match = simple_strtoul(argv[i], NULL, 0); if (NULL == argv[++i]) { DHD_ERROR(("Filter type not provided\n")); @@ -1079,7 +1074,7 @@ void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg) } /* Parse filter type. */ - pkt_filter.type = htod32(simple_strtoul(argv[i], NULL, 0)); + pkt_filter.type = simple_strtoul(argv[i], NULL, 0); if (NULL == argv[++i]) { DHD_ERROR(("Offset not provided\n")); @@ -1087,7 +1082,7 @@ void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg) } /* Parse pattern filter offset. */ - pkt_filter.u.pattern.offset = htod32(simple_strtoul(argv[i], NULL, 0)); + pkt_filter.u.pattern.offset = simple_strtoul(argv[i], NULL, 0); if (NULL == argv[++i]) { DHD_ERROR(("Bitmask not provided\n")); @@ -1096,8 +1091,8 @@ void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg) /* Parse pattern filter mask. */ mask_size = - htod32(wl_pattern_atoh - (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern)); + wl_pattern_atoh + (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern); if (NULL == argv[++i]) { DHD_ERROR(("Pattern not provided\n")); @@ -1106,9 +1101,9 @@ void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg) /* Parse pattern filter pattern. */ pattern_size = - htod32(wl_pattern_atoh(argv[i], + wl_pattern_atoh(argv[i], (char *)&pkt_filterp->u.pattern. - mask_and_pattern[mask_size])); + mask_and_pattern[mask_size]); if (mask_size != pattern_size) { DHD_ERROR(("Mask and pattern not the same size\n")); @@ -1428,8 +1423,7 @@ int dhd_iscan_print_cache(iscan_buf_t *iscan_skip) bi->BSSID.octet[2], bi->BSSID.octet[3], bi->BSSID.octet[4], bi->BSSID.octet[5])); - bi = (wl_bss_info_t *)((unsigned long)bi + - dtoh32(bi->length)); + bi = (wl_bss_info_t *)((unsigned long)bi + bi->length); } iscan_cur = iscan_cur->next; l++; @@ -1493,18 +1487,16 @@ int dhd_iscan_delete_bss(void *dhdp, void *addr, iscan_buf_t *iscan_skip) bi->BSSID.octet[5])); bi_new = bi; - bi = (wl_bss_info_t *)((unsigned long)bi + - dtoh32 - (bi->length)); + bi = (wl_bss_info_t *)((unsigned long) + bi + bi->length); /* if(bi && bi_new) { memcpy(bi_new, bi, results->buflen - - dtoh32(bi_new->length)); - results->buflen -= dtoh32(bi_new->length); + bi_new->length); + results->buflen -= bi_new->length; } */ - results->buflen -= - dtoh32(bi_new->length); + results->buflen -= bi_new->length; results->count--; for (j = i; j < results->count; j++) { @@ -1520,16 +1512,13 @@ int dhd_iscan_delete_bss(void *dhdp, void *addr, iscan_buf_t *iscan_skip) bi_next = (wl_bss_info_t *)((unsigned long)bi + - dtoh32 - (bi->length)); + bi->length); memcpy(bi_new, bi, - dtoh32 - (bi->length)); + bi->length); bi_new = (wl_bss_info_t *)((unsigned long)bi_new + - dtoh32 - (bi_new-> - length)); + bi_new-> + length); bi = bi_next; } } @@ -1544,7 +1533,7 @@ int dhd_iscan_delete_bss(void *dhdp, void *addr, iscan_buf_t *iscan_skip) break; } bi = (wl_bss_info_t *)((unsigned long)bi + - dtoh32(bi->length)); + bi->length); } } iscan_cur = iscan_cur->next; @@ -1598,7 +1587,7 @@ int dhd_iscan_remove_duplicates(void *dhdp, iscan_buf_t *iscan_cur) dhd_iscan_delete_bss(dhdp, bi->BSSID.octet, iscan_cur); - bi = (wl_bss_info_t *)((unsigned long)bi + dtoh32(bi->length)); + bi = (wl_bss_info_t *)((unsigned long)bi + bi->length); } done: @@ -1627,15 +1616,15 @@ int dhd_iscan_request(void *dhdp, u16 action) params.params.bss_type = DOT11_BSSTYPE_ANY; params.params.scan_type = DOT11_SCANTYPE_ACTIVE; - params.params.nprobes = htod32(-1); - params.params.active_time = htod32(-1); - params.params.passive_time = htod32(-1); - params.params.home_time = htod32(-1); - params.params.channel_num = htod32(0); + params.params.nprobes = -1; + params.params.active_time = -1; + params.params.passive_time = -1; + params.params.home_time = -1; + params.params.channel_num = 0; - params.version = htod32(ISCAN_REQ_VERSION); - params.action = htod16(action); - params.scan_duration = htod16(0); + params.version = ISCAN_REQ_VERSION; + params.action = action; + params.scan_duration = 0; bcm_mkiovar("iscan", (char *)¶ms, sizeof(wl_iscan_params_t), buf, WLC_IOCTL_SMLEN); @@ -1672,16 +1661,16 @@ static int dhd_iscan_get_partial_result(void *dhdp, uint *scan_count) results->count = 0; memset(&list, 0, sizeof(list)); - list.results.buflen = htod32(WLC_IW_ISCAN_MAXLEN); + list.results.buflen = WLC_IW_ISCAN_MAXLEN; bcm_mkiovar("iscanresults", (char *)&list, WL_ISCAN_RESULTS_FIXED_SIZE, iscan_cur->iscan_buf, WLC_IW_ISCAN_MAXLEN); rc = dhd_wl_ioctl(dhdp, WLC_GET_VAR, iscan_cur->iscan_buf, WLC_IW_ISCAN_MAXLEN); - results->buflen = dtoh32(results->buflen); - results->version = dtoh32(results->version); - *scan_count = results->count = dtoh32(results->count); - status = dtoh32(list_buf->status); + results->buflen = results->buflen; + results->version = results->version; + *scan_count = results->count = results->count; + status = list_buf->status; dhd_iscan_unlock(); @@ -1804,12 +1793,12 @@ dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t *ssids_local, int nssid, unsigned char sc memset(&pfn_element, 0, sizeof(pfn_element)); /* set pfn parameters */ - pfn_param.version = htod32(PFN_VERSION); - pfn_param.flags = htod16((PFN_LIST_ORDER << SORT_CRITERIA_BIT)); + pfn_param.version = PFN_VERSION; + pfn_param.flags = (PFN_LIST_ORDER << SORT_CRITERIA_BIT); /* set up pno scan fr */ if (scan_fr != 0) - pfn_param.scan_freq = htod32(scan_fr); + pfn_param.scan_freq = scan_fr; bcm_mkiovar("pfn_set", (char *)&pfn_param, sizeof(pfn_param), iovbuf, sizeof(iovbuf)); @@ -1818,11 +1807,11 @@ dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t *ssids_local, int nssid, unsigned char sc /* set all pfn ssid */ for (i = 0; i < nssid; i++) { - pfn_element.bss_type = htod32(DOT11_BSSTYPE_INFRASTRUCTURE); - pfn_element.auth = (DOT11_OPEN_SYSTEM); - pfn_element.wpa_auth = htod32(WPA_AUTH_PFN_ANY); - pfn_element.wsec = htod32(0); - pfn_element.infra = htod32(1); + pfn_element.bss_type = DOT11_BSSTYPE_INFRASTRUCTURE; + pfn_element.auth = DOT11_OPEN_SYSTEM; + pfn_element.wpa_auth = WPA_AUTH_PFN_ANY; + pfn_element.wsec = 0; + pfn_element.infra = 1; memcpy((char *)pfn_element.ssid.SSID, ssids_local[i].SSID, ssids_local[i].SSID_len); diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 54169c49ee2e..fe3379a93798 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -555,24 +555,24 @@ static const u32 __wl_cipher_suites[] = { static void swap_key_from_BE(struct wl_wsec_key *key) { - key->index = htod32(key->index); - key->len = htod32(key->len); - key->algo = htod32(key->algo); - key->flags = htod32(key->flags); - key->rxiv.hi = htod32(key->rxiv.hi); - key->rxiv.lo = htod16(key->rxiv.lo); - key->iv_initialized = htod32(key->iv_initialized); + key->index = cpu_to_le32(key->index); + key->len = cpu_to_le32(key->len); + key->algo = cpu_to_le32(key->algo); + key->flags = cpu_to_le32(key->flags); + key->rxiv.hi = cpu_to_le32(key->rxiv.hi); + key->rxiv.lo = cpu_to_le16(key->rxiv.lo); + key->iv_initialized = cpu_to_le32(key->iv_initialized); } static void swap_key_to_BE(struct wl_wsec_key *key) { - key->index = dtoh32(key->index); - key->len = dtoh32(key->len); - key->algo = dtoh32(key->algo); - key->flags = dtoh32(key->flags); - key->rxiv.hi = dtoh32(key->rxiv.hi); - key->rxiv.lo = dtoh16(key->rxiv.lo); - key->iv_initialized = dtoh32(key->iv_initialized); + key->index = le32_to_cpu(key->index); + key->len = le32_to_cpu(key->len); + key->algo = le32_to_cpu(key->algo); + key->flags = le32_to_cpu(key->flags); + key->rxiv.hi = le32_to_cpu(key->rxiv.hi); + key->rxiv.lo = le16_to_cpu(key->rxiv.lo); + key->iv_initialized = le32_to_cpu(key->iv_initialized); } static s32 @@ -626,8 +626,8 @@ wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, default: return -EINVAL; } - infra = htod32(infra); - ap = htod32(ap); + infra = cpu_to_le32(infra); + ap = cpu_to_le32(ap); wdev = ndev->ieee80211_ptr; wdev->iftype = type; WL_DBG("%s : ap (%d), infra (%d)\n", ndev->name, ap, infra); @@ -657,10 +657,10 @@ static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid) params->home_time = -1; params->channel_num = 0; - params->nprobes = htod32(params->nprobes); - params->active_time = htod32(params->active_time); - params->passive_time = htod32(params->passive_time); - params->home_time = htod32(params->home_time); + params->nprobes = cpu_to_le32(params->nprobes); + params->active_time = cpu_to_le32(params->active_time); + params->passive_time = cpu_to_le32(params->passive_time); + params->home_time = cpu_to_le32(params->home_time); if (ssid && ssid->SSID_len) memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t)); @@ -707,9 +707,9 @@ wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action) wl_iscan_prep(¶ms->params, ssid); - params->version = htod32(ISCAN_REQ_VERSION); - params->action = htod16(action); - params->scan_duration = htod16(0); + params->version = cpu_to_le32(ISCAN_REQ_VERSION); + params->action = cpu_to_le16(action); + params->scan_duration = cpu_to_le16(0); /* params_size += offsetof(wl_iscan_params_t, params); */ err = wl_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size, @@ -812,7 +812,7 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len); if (sr->ssid.SSID_len) { memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len); - sr->ssid.SSID_len = htod32(sr->ssid.SSID_len); + sr->ssid.SSID_len = cpu_to_le32(sr->ssid.SSID_len); WL_DBG("Specific scan ssid=\"%s\" len=%d\n", sr->ssid.SSID, sr->ssid.SSID_len); spec_scan = true; @@ -872,7 +872,7 @@ static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val) u32 len; s32 err = 0; - val = htod32(val); + val = cpu_to_le32(val); len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf)); BUG_ON(!len); @@ -903,7 +903,7 @@ wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval) if (unlikely(err)) { WL_ERR("error (%d)\n", err); } - *retval = dtoh32(var.val); + *retval = le32_to_cpu(var.val); return err; } @@ -937,7 +937,7 @@ static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l) s32 err = 0; u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL); - retry = htod32(retry); + retry = cpu_to_le32(retry); err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry)); if (unlikely(err)) { WL_ERR("cmd (%d) , error (%d)\n", cmd, err); @@ -1040,7 +1040,7 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, memset(&join_params, 0, sizeof(join_params)); memcpy((void *)join_params.ssid.SSID, (void *)params->ssid, params->ssid_len); - join_params.ssid.SSID_len = htod32(params->ssid_len); + join_params.ssid.SSID_len = cpu_to_le32(params->ssid_len); if (params->bssid) memcpy(&join_params.params.bssid, params->bssid, ETH_ALEN); @@ -1370,7 +1370,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len); memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len); - join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len); + join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len); wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID); memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN); @@ -1406,7 +1406,7 @@ wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, if (likely(act)) { scbval.val = reason_code; memcpy(&scbval.ea, &wl->bssid, ETH_ALEN); - scbval.val = htod32(scbval.val); + scbval.val = cpu_to_le32(scbval.val); err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)); if (unlikely(err)) { @@ -1448,7 +1448,7 @@ wl_cfg80211_set_tx_power(struct wiphy *wiphy, } /* Make sure radio is off or on as far as software is concerned */ disable = WL_RADIO_SW_DISABLE << 16; - disable = htod32(disable); + disable = cpu_to_le32(disable); err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable)); if (unlikely(err)) { WL_ERR("WLC_SET_RADIO error (%d)\n", err); @@ -1506,11 +1506,11 @@ wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, WL_ERR("WLC_GET_WSEC error (%d)\n", err); return err; } - wsec = dtoh32(wsec); + wsec = le32_to_cpu(wsec); if (wsec & WEP_ENABLED) { /* Just select a new current key */ index = (u32) key_idx; - index = htod32(index); + index = cpu_to_le32(index); err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index, sizeof(index)); if (unlikely(err)) { @@ -1683,7 +1683,7 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, } val = 1; /* assume shared key. otherwise 0 */ - val = htod32(val); + val = cpu_to_le32(val); err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val)); if (unlikely(err)) { WL_ERR("WLC_SET_AUTH error (%d)\n", err); @@ -1739,7 +1739,7 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, } val = 0; /* assume open key. otherwise 1 */ - val = htod32(val); + val = cpu_to_le32(val); err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val)); if (unlikely(err)) { WL_ERR("WLC_SET_AUTH error (%d)\n", err); @@ -1775,7 +1775,7 @@ wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, WL_ERR("WLC_GET_WSEC error (%d)\n", err); return err; } - wsec = dtoh32(wsec); + wsec = le32_to_cpu(wsec); switch (wsec) { case WEP_ENABLED: sec = wl_read_prof(wl, WL_PROF_SEC); @@ -1835,7 +1835,7 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, if (err) { WL_ERR("Could not get rate (%d)\n", err); } else { - rate = dtoh32(rate); + rate = le32_to_cpu(rate); sinfo->filled |= STATION_INFO_TX_BITRATE; sinfo->txrate.legacy = rate * 5; WL_DBG("Rate %d Mbps\n", rate / 2); @@ -1849,7 +1849,7 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, WL_ERR("Could not get rssi (%d)\n", err); return err; } - rssi = dtoh32(scb_val.val); + rssi = le32_to_cpu(scb_val.val); sinfo->filled |= STATION_INFO_SIGNAL; sinfo->signal = rssi; WL_DBG("RSSI %d dBm\n", rssi); @@ -1867,7 +1867,7 @@ wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, CHECK_SYS_UP(); pm = enabled ? PM_FAST : PM_OFF; - pm = htod32(pm); + pm = cpu_to_le32(pm); WL_DBG("power save %s\n", (pm ? "enabled" : "disabled")); err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)); if (unlikely(err)) { @@ -1930,7 +1930,7 @@ wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, return err; } - rateset.count = dtoh32(rateset.count); + rateset.count = le32_to_cpu(rateset.count); legacy = wl_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy); if (!legacy) @@ -2263,7 +2263,7 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) u32 freq; s32 err = 0; - if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) { + if (unlikely(le32_to_cpu(bi->length) > WL_BSS_INFO_MAX)) { WL_DBG("Beacon is larger than buffer. Discarding\n"); return err; } @@ -2536,10 +2536,10 @@ static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params, join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK; join_params->params.chanspec_list[0] |= chanspec; join_params->params.chanspec_list[0] = - htodchanspec(join_params->params.chanspec_list[0]); + cpu_to_le16(join_params->params.chanspec_list[0]); join_params->params.chanspec_num = - htod32(join_params->params.chanspec_num); + cpu_to_le32(join_params->params.chanspec_num); WL_DBG("join_params->params.chanspec_list[0]= %#X, channel %d, chanspec %#X\n", join_params->params.chanspec_list[0], ch, chanspec); @@ -2570,7 +2570,7 @@ static s32 wl_update_bss_info(struct wl_priv *wl) rtnl_lock(); if (unlikely(!bss)) { WL_DBG("Could not find the AP\n"); - *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX); + *(u32 *) wl->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX); err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO, wl->extra_buf, WL_EXTRA_BUF_MAX); if (unlikely(err)) { @@ -2722,7 +2722,7 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, WL_ERR("scan busy (%d)\n", err); goto scan_done_out; } - channel_inform.scan_channel = dtoh32(channel_inform.scan_channel); + channel_inform.scan_channel = le32_to_cpu(channel_inform.scan_channel); if (unlikely(channel_inform.scan_channel)) { WL_DBG("channel_inform.scan_channel (%d)\n", @@ -2731,16 +2731,16 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, wl->bss_list = wl->scan_results; bss_list = wl->bss_list; memset(bss_list, 0, len); - bss_list->buflen = htod32(len); + bss_list->buflen = cpu_to_le32(len); err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len); if (unlikely(err)) { WL_ERR("%s Scan_results error (%d)\n", ndev->name, err); err = -EINVAL; goto scan_done_out; } - bss_list->buflen = dtoh32(bss_list->buflen); - bss_list->version = dtoh32(bss_list->version); - bss_list->count = dtoh32(bss_list->count); + bss_list->buflen = le32_to_cpu(bss_list->buflen); + bss_list->version = le32_to_cpu(bss_list->version); + bss_list->count = le32_to_cpu(bss_list->count); err = wl_inform_bss(wl); if (err) @@ -2949,7 +2949,7 @@ wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status, results->count = 0; memset(&list, 0, sizeof(list)); - list.results.buflen = htod32(WL_ISCAN_BUF_MAX); + list.results.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX); err = wl_dev_iovar_getbuf(iscan->dev, "iscanresults", &list, WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf, WL_ISCAN_BUF_MAX); @@ -2957,12 +2957,12 @@ wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status, WL_ERR("error (%d)\n", err); return err; } - results->buflen = dtoh32(results->buflen); - results->version = dtoh32(results->version); - results->count = dtoh32(results->count); + results->buflen = le32_to_cpu(results->buflen); + results->version = le32_to_cpu(results->version); + results->count = le32_to_cpu(results->count); WL_DBG("results->count = %d\n", results->count); WL_DBG("results->buflen = %d\n", results->buflen); - *status = dtoh32(list_buf->status); + *status = le32_to_cpu(list_buf->status); *bss_list = results; return err; @@ -3392,8 +3392,8 @@ static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype) WL_ERR("invalid type (%d)\n", iftype); return err; } - infra = htod32(infra); - ap = htod32(ap); + infra = cpu_to_le32(infra); + ap = cpu_to_le32(ap); WL_DBG("%s ap (%d), infra (%d)\n", ndev->name, ap, infra); err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra)); if (unlikely(err)) { @@ -3655,26 +3655,28 @@ static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode) pkt_filterp = (struct wl_pkt_filter *)(buf + str_len + 1); /* Parse packet filter id. */ - pkt_filter.id = htod32(100); + pkt_filter.id = cpu_to_le32(100); /* Parse filter polarity. */ - pkt_filter.negate_match = htod32(0); + pkt_filter.negate_match = cpu_to_le32(0); /* Parse filter type. */ - pkt_filter.type = htod32(0); + pkt_filter.type = cpu_to_le32(0); /* Parse pattern filter offset. */ - pkt_filter.u.pattern.offset = htod32(0); + pkt_filter.u.pattern.offset = cpu_to_le32(0); /* Parse pattern filter mask. */ - mask_size = htod32(wl_pattern_atoh("0xff", - (char *)pkt_filterp->u.pattern. - mask_and_pattern)); + mask_size = cpu_to_le32(wl_pattern_atoh("0xff", + (char *)pkt_filterp->u.pattern. + mask_and_pattern)); /* Parse pattern filter pattern. */ - pattern_size = htod32(wl_pattern_atoh("0x00", - (char *)&pkt_filterp->u.pattern. - mask_and_pattern[mask_size])); + pattern_size = cpu_to_le32(wl_pattern_atoh("0x00", + (char *)&pkt_filterp->u. + pattern. + mask_and_pattern + [mask_size])); if (mask_size != pattern_size) { WL_ERR("Mask and pattern not the same size\n"); diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h index b7e2e59b82df..5112160e0ae3 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h @@ -28,23 +28,6 @@ struct wl_priv; struct wl_security; struct wl_ibss; -#if defined(IL_BIGENDIAN) -#include -#define htod32(i) (bcmswap32(i)) -#define htod16(i) (bcmswap16(i)) -#define dtoh32(i) (bcmswap32(i)) -#define dtoh16(i) (bcmswap16(i)) -#define htodchanspec(i) htod16(i) -#define dtohchanspec(i) dtoh16(i) -#else -#define htod32(i) i -#define htod16(i) i -#define dtoh32(i) i -#define dtoh16(i) i -#define htodchanspec(i) i -#define dtohchanspec(i) i -#endif - #define WL_DBG_NONE 0 #define WL_DBG_DBG (1 << 2) #define WL_DBG_INFO (1 << 1) @@ -365,7 +348,8 @@ static inline struct wl_bss_info *next_bss(struct wl_scan_results *list, { return bss = bss ? (struct wl_bss_info *)((unsigned long)bss + - dtoh32(bss->length)) : list->bss_info; + le32_to_cpu(bss->length)) : + list->bss_info; } #define for_each_bss(list, bss, __i) \ diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index eb31c74f65d4..0e4b13281611 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -70,23 +70,6 @@ uint wl_msg_level = WL_ERROR_VAL; #define MAX_WLIW_IOCTL_LEN 1024 -#if defined(IL_BIGENDIAN) -#include -#define htod32(i) (bcmswap32(i)) -#define htod16(i) (bcmswap16(i)) -#define dtoh32(i) (bcmswap32(i)) -#define dtoh16(i) (bcmswap16(i)) -#define htodchanspec(i) htod16(i) -#define dtohchanspec(i) dtoh16(i) -#else -#define htod32(i) i -#define htod16(i) i -#define dtoh32(i) i -#define dtoh16(i) i -#define htodchanspec(i) i -#define dtohchanspec(i) i -#endif - #ifdef CONFIG_WIRELESS_EXT extern struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev); @@ -159,24 +142,24 @@ wl_iw_get_scan_prep(wl_scan_results_t *list, static void swap_key_from_BE(wl_wsec_key_t *key) { - key->index = htod32(key->index); - key->len = htod32(key->len); - key->algo = htod32(key->algo); - key->flags = htod32(key->flags); - key->rxiv.hi = htod32(key->rxiv.hi); - key->rxiv.lo = htod16(key->rxiv.lo); - key->iv_initialized = htod32(key->iv_initialized); + key->index = cpu_to_le32(key->index); + key->len = cpu_to_le32(key->len); + key->algo = cpu_to_le32(key->algo); + key->flags = cpu_to_le32(key->flags); + key->rxiv.hi = cpu_to_le32(key->rxiv.hi); + key->rxiv.lo = cpu_to_le16(key->rxiv.lo); + key->iv_initialized = cpu_to_le32(key->iv_initialized); } static void swap_key_to_BE(wl_wsec_key_t *key) { - key->index = dtoh32(key->index); - key->len = dtoh32(key->len); - key->algo = dtoh32(key->algo); - key->flags = dtoh32(key->flags); - key->rxiv.hi = dtoh32(key->rxiv.hi); - key->rxiv.lo = dtoh16(key->rxiv.lo); - key->iv_initialized = dtoh32(key->iv_initialized); + key->index = le32_to_cpu(key->index); + key->len = le32_to_cpu(key->len); + key->algo = le32_to_cpu(key->algo); + key->flags = le32_to_cpu(key->flags); + key->rxiv.hi = le32_to_cpu(key->rxiv.hi); + key->rxiv.lo = le16_to_cpu(key->rxiv.lo); + key->iv_initialized = le32_to_cpu(key->iv_initialized); } static int dev_wlc_ioctl(struct net_device *dev, int cmd, void *arg, int len) @@ -224,7 +207,7 @@ static int dev_wlc_intvar_set(struct net_device *dev, char *name, int val) char buf[WLC_IOCTL_SMLEN]; uint len; - val = htod32(val); + val = cpu_to_le32(val); len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf)); ASSERT(len); @@ -311,7 +294,7 @@ static int dev_wlc_intvar_get(struct net_device *dev, char *name, int *retval) ASSERT(len); error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)&var, len); - *retval = dtoh32(var.val); + *retval = le32_to_cpu(var.val); return error; } @@ -341,7 +324,7 @@ wl_iw_config_commit(struct net_device *dev, if (error) return error; - ssid.SSID_len = dtoh32(ssid.SSID_len); + ssid.SSID_len = le32_to_cpu(ssid.SSID_len); if (!ssid.SSID_len) return 0; @@ -393,7 +376,7 @@ wl_iw_set_freq(struct net_device *dev, chan = wf_mhz2channel(fwrq->m, sf); } - chan = htod32(chan); + chan = cpu_to_le32(chan); error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan)); if (error) @@ -416,8 +399,8 @@ wl_iw_get_freq(struct net_device *dev, if (error) return error; - fwrq->m = dtoh32(ci.hw_channel); - fwrq->e = dtoh32(0); + fwrq->m = le32_to_cpu(ci.hw_channel); + fwrq->e = le32_to_cpu(0); return 0; } @@ -442,8 +425,8 @@ wl_iw_set_mode(struct net_device *dev, default: return -EINVAL; } - infra = htod32(infra); - ap = htod32(ap); + infra = cpu_to_le32(infra); + ap = cpu_to_le32(ap); error = dev_wlc_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(infra)); if (error) @@ -472,8 +455,8 @@ wl_iw_get_mode(struct net_device *dev, if (error) return error; - infra = dtoh32(infra); - ap = dtoh32(ap); + infra = le32_to_cpu(infra); + ap = le32_to_cpu(ap); *uwrq = infra ? ap ? IW_MODE_MASTER : IW_MODE_INFRA : IW_MODE_ADHOC; return 0; @@ -518,17 +501,18 @@ wl_iw_get_range(struct net_device *dev, range->min_nwid = range->max_nwid = 0; - list->count = htod32(MAXCHANNEL); + list->count = cpu_to_le32(MAXCHANNEL); error = dev_wlc_ioctl(dev, WLC_GET_VALID_CHANNELS, channels, (MAXCHANNEL + 1) * 4); if (error) { kfree(channels); return error; } - for (i = 0; i < dtoh32(list->count) && i < IW_MAX_FREQUENCIES; i++) { - range->freq[i].i = dtoh32(list->element[i]); + for (i = 0; i < le32_to_cpu(list->count) && i < IW_MAX_FREQUENCIES; + i++) { + range->freq[i].i = le32_to_cpu(list->element[i]); - ch = dtoh32(list->element[i]); + ch = le32_to_cpu(list->element[i]); if (ch <= CH_MAX_2G_CHANNEL) { range->freq[i].m = ieee80211_dsss_chan_to_freq(ch); } else { @@ -556,7 +540,7 @@ wl_iw_get_range(struct net_device *dev, kfree(channels); return error; } - rateset.count = dtoh32(rateset.count); + rateset.count = le32_to_cpu(rateset.count); range->num_bitrates = rateset.count; for (i = 0; i < rateset.count && i < IW_MAX_BITRATES; i++) range->bitrate[i] = (rateset.rates[i] & 0x7f) * 500000; @@ -568,7 +552,7 @@ wl_iw_get_range(struct net_device *dev, dev_wlc_intvar_get(dev, "sgi_tx", &sgi_tx); dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t)); - ci.hw_channel = dtoh32(ci.hw_channel); + ci.hw_channel = le32_to_cpu(ci.hw_channel); if (bw_cap == 0 || (bw_cap == 2 && ci.hw_channel <= 14)) { if (sgi_tx == 0) @@ -594,7 +578,7 @@ wl_iw_get_range(struct net_device *dev, kfree(channels); return error; } - i = dtoh32(i); + i = le32_to_cpu(i); if (i == WLC_PHY_TYPE_A) range->throughput = 24000000; else @@ -746,10 +730,10 @@ wl_iw_ch_to_chanspec(int ch, wl_join_params_t *join_params, join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK; join_params->params.chanspec_list[0] |= chanspec; join_params->params.chanspec_list[0] = - htodchanspec(join_params->params.chanspec_list[0]); + cpu_to_le16(join_params->params.chanspec_list[0]); join_params->params.chanspec_num = - htod32(join_params->params.chanspec_num); + cpu_to_le32(join_params->params.chanspec_num); WL_TRACE("%s join_params->params.chanspec_list[0]= %X\n", __func__, join_params->params.chanspec_list[0]); @@ -785,7 +769,7 @@ wl_iw_set_wap(struct net_device *dev, join_params_size = sizeof(join_params.ssid); memcpy(join_params.ssid.SSID, g_ssid.SSID, g_ssid.SSID_len); - join_params.ssid.SSID_len = htod32(g_ssid.SSID_len); + join_params.ssid.SSID_len = cpu_to_le32(g_ssid.SSID_len); memcpy(&join_params.params.bssid, awrq->sa_data, ETH_ALEN); WL_TRACE("%s target_channel=%d\n", @@ -844,12 +828,12 @@ wl_iw_mlme(struct net_device *dev, memcpy(&scbval.ea, &mlme->addr.sa_data, ETH_ALEN); if (mlme->cmd == IW_MLME_DISASSOC) { - scbval.val = htod32(scbval.val); + scbval.val = cpu_to_le32(scbval.val); error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)); } else if (mlme->cmd == IW_MLME_DEAUTH) { - scbval.val = htod32(scbval.val); + scbval.val = cpu_to_le32(scbval.val); error = dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval, sizeof(scb_val_t)); @@ -884,16 +868,16 @@ wl_iw_get_aplist(struct net_device *dev, if (!list) return -ENOMEM; memset(list, 0, buflen); - list->buflen = htod32(buflen); + list->buflen = cpu_to_le32(buflen); error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, buflen); if (error) { WL_ERROR("%d: Scan results error %d\n", __LINE__, error); kfree(list); return error; } - list->buflen = dtoh32(list->buflen); - list->version = dtoh32(list->version); - list->count = dtoh32(list->count); + list->buflen = le32_to_cpu(list->buflen); + list->version = le32_to_cpu(list->version); + list->count = le32_to_cpu(list->count); if (list->version != WL_BSS_INFO_VERSION) { WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n", __func__, list->version); @@ -904,18 +888,18 @@ wl_iw_get_aplist(struct net_device *dev, for (i = 0, dwrq->length = 0; i < list->count && dwrq->length < IW_MAX_AP; i++) { bi = bi ? (wl_bss_info_t *) ((unsigned long)bi + - dtoh32(bi->length)) : list-> + le32_to_cpu(bi->length)) : list-> bss_info; - ASSERT(((unsigned long)bi + dtoh32(bi->length)) <= + ASSERT(((unsigned long)bi + le32_to_cpu(bi->length)) <= ((unsigned long)list + buflen)); - if (!(dtoh16(bi->capability) & WLAN_CAPABILITY_ESS)) + if (!(le16_to_cpu(bi->capability) & WLAN_CAPABILITY_ESS)) continue; memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETH_ALEN); addr[dwrq->length].sa_family = ARPHRD_ETHER; - qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI)); - qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI); + qual[dwrq->length].qual = rssi_to_qual(le16_to_cpu(bi->RSSI)); + qual[dwrq->length].level = 0x100 + le16_to_cpu(bi->RSSI); qual[dwrq->length].noise = 0x100 + bi->phy_noise; #if WIRELESS_EXT > 18 @@ -976,20 +960,22 @@ wl_iw_iscan_get_aplist(struct net_device *dev, for (i = 0, dwrq->length = 0; i < list->count && dwrq->length < IW_MAX_AP; i++) { bi = bi ? (wl_bss_info_t *) ((unsigned long)bi + - dtoh32(bi->length)) : + le32_to_cpu(bi->length)) : list->bss_info; - ASSERT(((unsigned long)bi + dtoh32(bi->length)) <= + ASSERT(((unsigned long)bi + le32_to_cpu(bi->length)) <= ((unsigned long)list + WLC_IW_ISCAN_MAXLEN)); - if (!(dtoh16(bi->capability) & WLAN_CAPABILITY_ESS)) + if (!(le16_to_cpu(bi->capability) & + WLAN_CAPABILITY_ESS)) continue; memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETH_ALEN); addr[dwrq->length].sa_family = ARPHRD_ETHER; qual[dwrq->length].qual = - rssi_to_qual(dtoh16(bi->RSSI)); - qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI); + rssi_to_qual(le16_to_cpu(bi->RSSI)); + qual[dwrq->length].level = 0x100 + + le16_to_cpu(bi->RSSI); qual[dwrq->length].noise = 0x100 + bi->phy_noise; #if WIRELESS_EXT > 18 @@ -1025,10 +1011,10 @@ static int wl_iw_iscan_prep(wl_scan_params_t *params, wlc_ssid_t *ssid) params->home_time = -1; params->channel_num = 0; - params->nprobes = htod32(params->nprobes); - params->active_time = htod32(params->active_time); - params->passive_time = htod32(params->passive_time); - params->home_time = htod32(params->home_time); + params->nprobes = cpu_to_le32(params->nprobes); + params->active_time = cpu_to_le32(params->active_time); + params->passive_time = cpu_to_le32(params->passive_time); + params->home_time = cpu_to_le32(params->home_time); if (ssid && ssid->SSID_len) memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t)); @@ -1039,9 +1025,9 @@ static int wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, u16 action) { int err = 0; - iscan->iscan_ex_params_p->version = htod32(ISCAN_REQ_VERSION); - iscan->iscan_ex_params_p->action = htod16(action); - iscan->iscan_ex_params_p->scan_duration = htod16(0); + iscan->iscan_ex_params_p->version = cpu_to_le32(ISCAN_REQ_VERSION); + iscan->iscan_ex_params_p->action = cpu_to_le16(action); + iscan->iscan_ex_params_p->scan_duration = cpu_to_le16(0); WL_SCAN("%s : nprobes=%d\n", __func__, iscan->iscan_ex_params_p->params.nprobes); @@ -1125,19 +1111,19 @@ static u32 wl_iw_iscan_get(iscan_info_t *iscan) results->count = 0; memset(&list, 0, sizeof(list)); - list.results.buflen = htod32(WLC_IW_ISCAN_MAXLEN); + list.results.buflen = cpu_to_le32(WLC_IW_ISCAN_MAXLEN); res = dev_iw_iovar_getbuf(iscan->dev, "iscanresults", &list, WL_ISCAN_RESULTS_FIXED_SIZE, buf->iscan_buf, WLC_IW_ISCAN_MAXLEN); if (res == 0) { - results->buflen = dtoh32(results->buflen); - results->version = dtoh32(results->version); - results->count = dtoh32(results->count); + results->buflen = le32_to_cpu(results->buflen); + results->version = le32_to_cpu(results->version); + results->count = le32_to_cpu(results->count); WL_TRACE("results->count = %d\n", results->count); WL_TRACE("results->buflen = %d\n", results->buflen); - status = dtoh32(list_buf->status); + status = le32_to_cpu(list_buf->status); } else { WL_ERROR("%s returns error %d\n", __func__, res); status = WL_SCAN_RESULTS_NO_MEM; @@ -1284,7 +1270,7 @@ wl_iw_set_scan(struct net_device *dev, memcpy(g_specific_ssid.SSID, req->essid, g_specific_ssid.SSID_len); g_specific_ssid.SSID_len = - htod32(g_specific_ssid.SSID_len); + cpu_to_le32(g_specific_ssid.SSID_len); g_scan_specified_ssid = 1; WL_TRACE("### Specific scan ssid=%s len=%d\n", g_specific_ssid.SSID, @@ -1380,7 +1366,7 @@ wl_iw_iscan_set_scan(struct net_device *dev, ssid.SSID_len = min_t(size_t, sizeof(ssid.SSID), req->essid_len); memcpy(ssid.SSID, req->essid, ssid.SSID_len); - ssid.SSID_len = htod32(ssid.SSID_len); + ssid.SSID_len = cpu_to_le32(ssid.SSID_len); } else { g_scan_specified_ssid = 0; @@ -1506,7 +1492,7 @@ wl_iw_get_scan_prep(wl_scan_results_t *list, } bi = bi ? (wl_bss_info_t *)((unsigned long)bi + - dtoh32(bi->length)) : list-> + le32_to_cpu(bi->length)) : list-> bss_info; WL_TRACE("%s : %s\n", __func__, bi->SSID); @@ -1517,15 +1503,15 @@ wl_iw_get_scan_prep(wl_scan_results_t *list, event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN); - iwe.u.data.length = dtoh32(bi->SSID_len); + iwe.u.data.length = le32_to_cpu(bi->SSID_len); iwe.cmd = SIOCGIWESSID; iwe.u.data.flags = 1; event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID); - if (dtoh16(bi->capability) & (WLAN_CAPABILITY_ESS | + if (le16_to_cpu(bi->capability) & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) { iwe.cmd = SIOCGIWMODE; - if (dtoh16(bi->capability) & WLAN_CAPABILITY_ESS) + if (le16_to_cpu(bi->capability) & WLAN_CAPABILITY_ESS) iwe.u.mode = IW_MODE_INFRA; else iwe.u.mode = IW_MODE_ADHOC; @@ -1550,8 +1536,8 @@ wl_iw_get_scan_prep(wl_scan_results_t *list, IW_EV_FREQ_LEN); iwe.cmd = IWEVQUAL; - iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI)); - iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI); + iwe.u.qual.qual = rssi_to_qual(le16_to_cpu(bi->RSSI)); + iwe.u.qual.level = 0x100 + le16_to_cpu(bi->RSSI); iwe.u.qual.noise = 0x100 + bi->phy_noise; event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, @@ -1560,7 +1546,7 @@ wl_iw_get_scan_prep(wl_scan_results_t *list, wl_iw_handle_scanresults_ies(&event, end, info, bi); iwe.cmd = SIOCGIWENCODE; - if (dtoh16(bi->capability) & WLAN_CAPABILITY_PRIVACY) + if (le16_to_cpu(bi->capability) & WLAN_CAPABILITY_PRIVACY) iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; else iwe.u.data.flags = IW_ENCODE_DISABLED; @@ -1627,7 +1613,7 @@ wl_iw_get_scan(struct net_device *dev, error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci)); if (error) return error; - ci.scan_channel = dtoh32(ci.scan_channel); + ci.scan_channel = le32_to_cpu(ci.scan_channel); if (ci.scan_channel) return -EAGAIN; @@ -1642,7 +1628,7 @@ wl_iw_get_scan(struct net_device *dev, } memset(list, 0, len); - list->buflen = htod32(len); + list->buflen = cpu_to_le32(len); error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, len); if (error) { WL_ERROR("%s: %s : Scan_results ERROR %d\n", @@ -1654,9 +1640,9 @@ wl_iw_get_scan(struct net_device *dev, } return 0; } - list->buflen = dtoh32(list->buflen); - list->version = dtoh32(list->version); - list->count = dtoh32(list->count); + list->buflen = le32_to_cpu(list->buflen); + list->version = le32_to_cpu(list->version); + list->count = le32_to_cpu(list->count); if (list->version != WL_BSS_INFO_VERSION) { WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n", @@ -1776,9 +1762,9 @@ wl_iw_iscan_get_scan(struct net_device *dev, for (ii = 0; ii < list->count && apcnt < IW_MAX_AP; apcnt++, ii++) { bi = bi ? (wl_bss_info_t *)((unsigned long)bi + - dtoh32(bi->length)) : + le32_to_cpu(bi->length)) : list->bss_info; - ASSERT(((unsigned long)bi + dtoh32(bi->length)) <= + ASSERT(((unsigned long)bi + le32_to_cpu(bi->length)) <= ((unsigned long)list + WLC_IW_ISCAN_MAXLEN)); if (event + ETH_ALEN + bi->SSID_len + @@ -1793,17 +1779,17 @@ wl_iw_iscan_get_scan(struct net_device *dev, IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN); - iwe.u.data.length = dtoh32(bi->SSID_len); + iwe.u.data.length = le32_to_cpu(bi->SSID_len); iwe.cmd = SIOCGIWESSID; iwe.u.data.flags = 1; event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID); - if (dtoh16(bi->capability) & + if (le16_to_cpu(bi->capability) & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) { iwe.cmd = SIOCGIWMODE; - if (dtoh16(bi->capability) & + if (le16_to_cpu(bi->capability) & WLAN_CAPABILITY_ESS) iwe.u.mode = IW_MODE_INFRA; else @@ -1832,8 +1818,8 @@ wl_iw_iscan_get_scan(struct net_device *dev, IW_EV_FREQ_LEN); iwe.cmd = IWEVQUAL; - iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI)); - iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI); + iwe.u.qual.qual = rssi_to_qual(le16_to_cpu(bi->RSSI)); + iwe.u.qual.level = 0x100 + le16_to_cpu(bi->RSSI); iwe.u.qual.noise = 0x100 + bi->phy_noise; event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, @@ -1842,7 +1828,8 @@ wl_iw_iscan_get_scan(struct net_device *dev, wl_iw_handle_scanresults_ies(&event, end, info, bi); iwe.cmd = SIOCGIWENCODE; - if (dtoh16(bi->capability) & WLAN_CAPABILITY_PRIVACY) + if (le16_to_cpu(bi->capability) & + WLAN_CAPABILITY_PRIVACY) iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; else @@ -1922,13 +1909,13 @@ wl_iw_set_essid(struct net_device *dev, } else { g_ssid.SSID_len = 0; } - g_ssid.SSID_len = htod32(g_ssid.SSID_len); + g_ssid.SSID_len = cpu_to_le32(g_ssid.SSID_len); memset(&join_params, 0, sizeof(join_params)); join_params_size = sizeof(join_params.ssid); memcpy(&join_params.ssid.SSID, g_ssid.SSID, g_ssid.SSID_len); - join_params.ssid.SSID_len = htod32(g_ssid.SSID_len); + join_params.ssid.SSID_len = cpu_to_le32(g_ssid.SSID_len); memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN); wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, &join_params, @@ -1965,7 +1952,7 @@ wl_iw_get_essid(struct net_device *dev, return error; } - ssid.SSID_len = dtoh32(ssid.SSID_len); + ssid.SSID_len = le32_to_cpu(ssid.SSID_len); memcpy(extra, ssid.SSID, ssid.SSID_len); @@ -2027,7 +2014,7 @@ wl_iw_set_rate(struct net_device *dev, if (error) return error; - rateset.count = dtoh32(rateset.count); + rateset.count = le32_to_cpu(rateset.count); if (vwrq->value < 0) rate = rateset.rates[rateset.count - 1] & 0x7f; @@ -2052,7 +2039,7 @@ wl_iw_set_rate(struct net_device *dev, for (i = 0; i < rateset.count; i++) if ((rateset.rates[i] & 0x7f) > rate) break; - rateset.count = htod32(i); + rateset.count = cpu_to_le32(i); error = dev_wlc_ioctl(dev, WLC_SET_RATESET, &rateset, sizeof(rateset)); @@ -2074,7 +2061,7 @@ wl_iw_get_rate(struct net_device *dev, error = dev_wlc_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate)); if (error) return error; - rate = dtoh32(rate); + rate = le32_to_cpu(rate); vwrq->value = rate * 500000; return 0; @@ -2174,7 +2161,7 @@ wl_iw_set_txpow(struct net_device *dev, disable = vwrq->disabled ? WL_RADIO_SW_DISABLE : 0; disable += WL_RADIO_SW_DISABLE << 16; - disable = htod32(disable); + disable = cpu_to_le32(disable); error = dev_wlc_ioctl(dev, WLC_SET_RADIO, &disable, sizeof(disable)); if (error) return error; @@ -2216,7 +2203,7 @@ wl_iw_get_txpow(struct net_device *dev, if (error) return error; - disable = dtoh32(disable); + disable = le32_to_cpu(disable); result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE); vwrq->value = (s32) bcm_qdbm_to_mw(result); vwrq->fixed = 0; @@ -2251,7 +2238,7 @@ wl_iw_set_retry(struct net_device *dev, if ((vwrq->flags & IW_RETRY_MAX) || !(vwrq->flags & IW_RETRY_MIN)) { #endif - lrl = htod32(vwrq->value); + lrl = cpu_to_le32(vwrq->value); error = dev_wlc_ioctl(dev, WLC_SET_LRL, &lrl, sizeof(lrl)); if (error) @@ -2266,7 +2253,7 @@ wl_iw_set_retry(struct net_device *dev, if ((vwrq->flags & IW_RETRY_MIN) || !(vwrq->flags & IW_RETRY_MAX)) { #endif - srl = htod32(vwrq->value); + srl = cpu_to_le32(vwrq->value); error = dev_wlc_ioctl(dev, WLC_SET_SRL, &srl, sizeof(srl)); if (error) @@ -2298,8 +2285,8 @@ wl_iw_get_retry(struct net_device *dev, if (error) return error; - lrl = dtoh32(lrl); - srl = dtoh32(srl); + lrl = le32_to_cpu(lrl); + srl = le32_to_cpu(srl); if (vwrq->flags & IW_RETRY_MAX) { vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; @@ -2330,12 +2317,12 @@ wl_iw_set_encode(struct net_device *dev, if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; key.index++) { - val = htod32(key.index); + val = cpu_to_le32(key.index); error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, sizeof(val)); if (error) return error; - val = dtoh32(val); + val = le32_to_cpu(val); if (val) break; } @@ -2348,7 +2335,7 @@ wl_iw_set_encode(struct net_device *dev, } if (!extra || !dwrq->length || (dwrq->flags & IW_ENCODE_NOKEY)) { - val = htod32(key.index); + val = cpu_to_le32(key.index); error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, &val, sizeof(val)); if (error) @@ -2399,7 +2386,7 @@ wl_iw_set_encode(struct net_device *dev, return error; val = (dwrq->flags & IW_ENCODE_RESTRICTED) ? 1 : 0; - val = htod32(val); + val = cpu_to_le32(val); error = dev_wlc_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val)); if (error) return error; @@ -2427,7 +2414,7 @@ wl_iw_get_encode(struct net_device *dev, sizeof(val)); if (error) return error; - val = dtoh32(val); + val = le32_to_cpu(val); if (val) break; } @@ -2447,8 +2434,8 @@ wl_iw_get_encode(struct net_device *dev, swap_key_to_BE(&key); - wsec = dtoh32(wsec); - auth = dtoh32(auth); + wsec = le32_to_cpu(wsec); + auth = le32_to_cpu(auth); dwrq->length = min_t(u16, DOT11_MAX_KEY_SIZE, key.len); dwrq->flags = key.index + 1; @@ -2475,7 +2462,7 @@ wl_iw_set_power(struct net_device *dev, pm = vwrq->disabled ? PM_OFF : PM_MAX; - pm = htod32(pm); + pm = cpu_to_le32(pm); error = dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)); if (error) return error; @@ -2496,7 +2483,7 @@ wl_iw_get_power(struct net_device *dev, if (error) return error; - pm = dtoh32(pm); + pm = le32_to_cpu(pm); vwrq->disabled = pm ? 0 : 1; vwrq->flags = IW_POWER_ALL_R; @@ -2561,7 +2548,7 @@ wl_iw_set_encodeext(struct net_device *dev, if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { WL_WSEC("Changing the the primary Key to %d\n", key.index); - key.index = htod32(key.index); + key.index = cpu_to_le32(key.index); error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, &key.index, sizeof(key.index)); if (error) @@ -3579,7 +3566,7 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) if (res) goto done; - phy_noise = dtoh32(phy_noise); + phy_noise = le32_to_cpu(phy_noise); WL_TRACE("wl_iw_get_wireless_stats phy noise=%d\n", phy_noise); memset(&scb_val, 0, sizeof(scb_val_t)); @@ -3587,7 +3574,7 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) if (res) goto done; - rssi = dtoh32(scb_val.val); + rssi = le32_to_cpu(scb_val.val); WL_TRACE("wl_iw_get_wireless_stats rssi=%d\n", rssi); if (rssi <= WL_IW_RSSI_NO_SIGNAL) wstats->qual.qual = 0; @@ -3624,7 +3611,7 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) goto done; } - cnt.version = dtoh16(cnt.version); + cnt.version = le16_to_cpu(cnt.version); if (cnt.version != WL_CNT_T_VERSION) { WL_TRACE("\tIncorrect counter version: expected %d; got %d\n", WL_CNT_T_VERSION, cnt.version); @@ -3632,28 +3619,29 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) } wstats->discard.nwid = 0; - wstats->discard.code = dtoh32(cnt.rxundec); - wstats->discard.fragment = dtoh32(cnt.rxfragerr); - wstats->discard.retries = dtoh32(cnt.txfail); - wstats->discard.misc = dtoh32(cnt.rxrunt) + dtoh32(cnt.rxgiant); + wstats->discard.code = le32_to_cpu(cnt.rxundec); + wstats->discard.fragment = le32_to_cpu(cnt.rxfragerr); + wstats->discard.retries = le32_to_cpu(cnt.txfail); + wstats->discard.misc = le32_to_cpu(cnt.rxrunt) + + le32_to_cpu(cnt.rxgiant); wstats->miss.beacon = 0; WL_TRACE("wl_iw_get_wireless_stats counters txframe=%d txbyte=%d\n", - dtoh32(cnt.txframe), dtoh32(cnt.txbyte)); + le32_to_cpu(cnt.txframe), le32_to_cpu(cnt.txbyte)); WL_TRACE("wl_iw_get_wireless_stats counters rxfrmtoolong=%d\n", - dtoh32(cnt.rxfrmtoolong)); + le32_to_cpu(cnt.rxfrmtoolong)); WL_TRACE("wl_iw_get_wireless_stats counters rxbadplcp=%d\n", - dtoh32(cnt.rxbadplcp)); + le32_to_cpu(cnt.rxbadplcp)); WL_TRACE("wl_iw_get_wireless_stats counters rxundec=%d\n", - dtoh32(cnt.rxundec)); + le32_to_cpu(cnt.rxundec)); WL_TRACE("wl_iw_get_wireless_stats counters rxfragerr=%d\n", - dtoh32(cnt.rxfragerr)); + le32_to_cpu(cnt.rxfragerr)); WL_TRACE("wl_iw_get_wireless_stats counters txfail=%d\n", - dtoh32(cnt.txfail)); + le32_to_cpu(cnt.txfail)); WL_TRACE("wl_iw_get_wireless_stats counters rxrunt=%d\n", - dtoh32(cnt.rxrunt)); + le32_to_cpu(cnt.rxrunt)); WL_TRACE("wl_iw_get_wireless_stats counters rxgiant=%d\n", - dtoh32(cnt.rxgiant)); + le32_to_cpu(cnt.rxgiant)); #endif /* WIRELESS_EXT > 11 */ done: -- cgit v1.2.3 From f317154929f87d2fe799179761d1b639af33de74 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Mon, 21 Feb 2011 10:35:26 +0300 Subject: staging: brcm80211: remove the rest of broadcom specific byte swapping routines - move ltoh16_buf/htol16_buf util/bcmsrom.c - replace ltoh16_buf in brcmsmac/wlc_mac80211.c with several le16_to_cpu's Signed-off-by: Stanislav Fomichev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh.c | 1 - drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 1 - drivers/staging/brcm80211/brcmfmac/dhd_cdc.c | 1 - drivers/staging/brcm80211/brcmfmac/dhd_common.c | 1 - drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 1 - drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 1 - drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 1 - drivers/staging/brcm80211/brcmfmac/wl_iw.c | 1 - .../staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c | 1 - drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 13 +++- drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_rate.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_stf.c | 1 - drivers/staging/brcm80211/include/bcmendian.h | 75 ---------------------- drivers/staging/brcm80211/util/bcmotp.c | 1 - drivers/staging/brcm80211/util/bcmsrom.c | 13 +++- drivers/staging/brcm80211/util/bcmutils.c | 1 - drivers/staging/brcm80211/util/hnddma.c | 1 - drivers/staging/brcm80211/util/linux_osl.c | 1 - drivers/staging/brcm80211/util/nvram/nvram_ro.c | 1 - 23 files changed, 23 insertions(+), 98 deletions(-) delete mode 100644 drivers/staging/brcm80211/include/bcmendian.h (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c index df9a139213a5..77e65e4297a1 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 8bf731f693ff..4409443c69de 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include /* SDIO Device and Protocol Specs */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c index 0083f0c3775b..6c0620c9742f 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c @@ -21,7 +21,6 @@ #include #include -#include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index 44dabd186eae..784333c42014 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index b6e3c0a87006..3efc17a0a4e0 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 41b76afe7c39..097844f8569a 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -26,7 +26,6 @@ #include #include -#include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index fe3379a93798..86c18be7d64e 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -19,7 +19,6 @@ #include #include -#include #include diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index 0e4b13281611..91d848807537 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -22,7 +22,6 @@ #include #include -#include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c index d869efa781d4..2f80da7f0d0f 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c index 55ce0b8c4fdd..23b6086aa74d 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index a5a4868ff3fa..4f9d4dec768c 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 9419f27e7425..12bfb06b3013 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index e7628fa6fcd5..05bcda3b3791 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -7066,7 +7065,17 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) skb_pull(p, wlc->hwrxoff); /* fixup rx header endianness */ - ltoh16_buf((void *)rxh, sizeof(d11rxhdr_t)); + rxh->RxFrameSize = le16_to_cpu(rxh->RxFrameSize); + rxh->PhyRxStatus_0 = le16_to_cpu(rxh->PhyRxStatus_0); + rxh->PhyRxStatus_1 = le16_to_cpu(rxh->PhyRxStatus_1); + rxh->PhyRxStatus_2 = le16_to_cpu(rxh->PhyRxStatus_2); + rxh->PhyRxStatus_3 = le16_to_cpu(rxh->PhyRxStatus_3); + rxh->PhyRxStatus_4 = le16_to_cpu(rxh->PhyRxStatus_4); + rxh->PhyRxStatus_5 = le16_to_cpu(rxh->PhyRxStatus_5); + rxh->RxStatus1 = le16_to_cpu(rxh->RxStatus1); + rxh->RxStatus2 = le16_to_cpu(rxh->RxStatus2); + rxh->RxTSFTime = le16_to_cpu(rxh->RxTSFTime); + rxh->RxChan = le16_to_cpu(rxh->RxChan); /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ if (rxh->RxStatus1 & RXS_PBPRES) { diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c index 8bd4ede4c92a..f8f2a5d81103 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c index 6904f8b19092..d48dd47ef846 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c index 8b7620f2b880..5ac120e8d4fe 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/include/bcmendian.h b/drivers/staging/brcm80211/include/bcmendian.h deleted file mode 100644 index 61c4edb98046..000000000000 --- a/drivers/staging/brcm80211/include/bcmendian.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _BCMENDIAN_H_ -#define _BCMENDIAN_H_ - -/* Reverse the bytes in a 16-bit value */ -#define BCMSWAP16(val) \ - ((u16)((((u16)(val) & (u16)0x00ffU) << 8) | \ - (((u16)(val) & (u16)0xff00U) >> 8))) - -#ifndef IL_BIGENDIAN -#define ltoh16_buf(buf, i) -#define htol16_buf(buf, i) -#else -#define ltoh16_buf(buf, i) bcmswap16_buf((u16 *)(buf), (i)) -#define htol16_buf(buf, i) bcmswap16_buf((u16 *)(buf), (i)) -#endif /* IL_BIGENDIAN */ - -#ifdef __GNUC__ - -/* GNU macro versions avoid referencing the argument multiple times, while also - * avoiding the -fno-inline used in ROM builds. - */ - -#define bcmswap16(val) ({ \ - u16 _val = (val); \ - BCMSWAP16(_val); \ -}) - -#define bcmswap16_buf(buf, len) ({ \ - u16 *_buf = (u16 *)(buf); \ - uint _wds = (len) / 2; \ - while (_wds--) { \ - *_buf = bcmswap16(*_buf); \ - _buf++; \ - } \ -}) - -#else /* !__GNUC__ */ - -/* Inline versions avoid referencing the argument multiple times */ -static inline u16 bcmswap16(u16 val) -{ - return BCMSWAP16(val); -} - -/* Reverse pairs of bytes in a buffer (not for high-performance use) */ -/* buf - start of buffer of shorts to swap */ -/* len - byte length of buffer */ -static inline void bcmswap16_buf(u16 *buf, uint len) -{ - len = len / 2; - - while (len--) { - *buf = bcmswap16(*buf); - buf++; - } -} - -#endif /* !__GNUC__ */ -#endif /* !_BCMENDIAN_H_ */ diff --git a/drivers/staging/brcm80211/util/bcmotp.c b/drivers/staging/brcm80211/util/bcmotp.c index 6fa04ed93501..5c1ea4c1fbfd 100644 --- a/drivers/staging/brcm80211/util/bcmotp.c +++ b/drivers/staging/brcm80211/util/bcmotp.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index b26877c46023..3ef5a50f48af 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -1438,6 +1437,18 @@ srom_cc_cmd(si_t *sih, struct osl_info *osh, void *ccregs, u32 cmd, return 0xffff; } +static inline void ltoh16_buf(u16 *buf, unsigned int size) +{ + for (size /= 2; size; size--) + *(buf + size) = le16_to_cpu(*(buf + size)); +} + +static inline void htol16_buf(u16 *buf, unsigned int size) +{ + for (size /= 2; size; size--) + *(buf + size) = cpu_to_le16(*(buf + size)); +} + /* * Read in and validate sprom. * Return 0 on success, nonzero on error. diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index 707fd0da3d36..674caf6243df 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 5d6489121b0a..66ebdfdf6cd4 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index e6716e823baa..d7c3c3f9dd81 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -19,7 +19,6 @@ #ifdef mips #include #endif /* mips */ -#include #include #include #include diff --git a/drivers/staging/brcm80211/util/nvram/nvram_ro.c b/drivers/staging/brcm80211/util/nvram/nvram_ro.c index b2e6c0df137e..ec4077945140 100644 --- a/drivers/staging/brcm80211/util/nvram/nvram_ro.c +++ b/drivers/staging/brcm80211/util/nvram/nvram_ro.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From eff1b99a6fc8eb25913fab7cd30eaeb6ca91349a Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 22 Feb 2011 11:12:09 +0100 Subject: staging: brcm80211: allow changing channel by mac80211 when associated When associated on 5G the driver receives a probe request for 2G with a 2G rate specified. The driver asserts as the operating band is still 5G when the probe request packet is given. Root cause was that ioctl function did fail upon setting the channel as requested by mac80211 when we are associated. Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h | 1 - drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h b/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h index 0bb4a212dd71..8096b0f52156 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h @@ -111,7 +111,6 @@ struct wlc_bsscfg { pmkid_t pmkid[MAXPMKID]; /* PMKID cache */ uint npmkid; /* num cached PMKIDs */ - wlc_bss_info_t *target_bss; /* BSS parms during tran. to ASSOCIATED state */ wlc_bss_info_t *current_bss; /* BSS parms in ASSOCIATED state */ /* PM states */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index 05bcda3b3791..fc3c6ab81d2e 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -789,7 +789,7 @@ void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec) FOREACH_BSS(wlc, idx, cfg) { if (!cfg->associated) continue; - cfg->target_bss->chanspec = chanspec; + cfg->current_bss->chanspec = chanspec; } @@ -3209,7 +3209,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, wlc->default_bss->chanspec = chspec; /* wlc_BSSinit() will sanitize the rateset before using it.. */ - if (wlc->pub->up && !wlc->pub->associated && + if (wlc->pub->up && (WLC_BAND_PI_RADIO_CHANSPEC != chspec)) { wlc_set_home_chanspec(wlc, chspec); wlc_suspend_mac_and_wait(wlc); -- cgit v1.2.3 From ce774bdcfed03a8dbc892d9fa06ee3fb2be628ee Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 22 Feb 2011 11:12:10 +0100 Subject: staging: brcm80211: remove some bsscfg attribute that are redundant In the struct wlc_bsscfg a couple of attribute were held under a preprocessor definition, but these are not needed in the mac80211 driver context. Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h b/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h index 8096b0f52156..301270f4002b 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h @@ -53,15 +53,7 @@ struct wlc_bsscfg { bool associated; /* is BSS in ASSOCIATED state */ bool BSS; /* infraustructure or adhac */ bool dtim_programmed; -#ifdef LATER - bool _ap; /* is this configuration an AP */ - struct wlc_if *wlcif; /* virtual interface, NULL for primary bsscfg */ - void *sup; /* pointer to supplicant state */ - s8 sup_type; /* type of supplicant */ - bool sup_enable_wpa; /* supplicant WPA on/off */ - void *authenticator; /* pointer to authenticator state */ - bool sup_auth_pending; /* flag for auth timeout */ -#endif + u8 SSID_len; /* the length of SSID */ u8 SSID[IEEE80211_MAX_SSID_LEN]; /* SSID string */ struct scb *bcmc_scb[MAXBANDS]; /* one bcmc_scb per band */ -- cgit v1.2.3 From 55182a10063c40eda4dc5afecff712e5c3617ffc Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Wed, 23 Feb 2011 12:48:51 +0100 Subject: staging: brcm80211: cosmetic changes Code cleanup. Added lock related comments to wl_mac80211.c. Also removed a redundant function definition. Signed-off-by: Roland Vossen Reviewed-by: Arend van Spriel Reviewed-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 100 +++++++++++++++++++++- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h | 2 - 2 files changed, 98 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 56f5d3a26414..3109e3da31d1 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -231,6 +231,9 @@ wl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) WL_UNLOCK(wl); } +/* + * precondition: perimeter lock has been acquired + */ static int ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan, enum nl80211_channel_type type) @@ -681,6 +684,9 @@ static const struct ieee80211_ops wl_ops = { .rfkill_poll = wl_ops_rfkill_poll, }; +/* + * is called in wl_pci_probe() context, therefore no locking required. + */ static int wl_set_hint(struct wl_info *wl, char *abbrev) { WL_NONE("%s: Sending country code %c%c to MAC80211\n", @@ -698,6 +704,9 @@ static int wl_set_hint(struct wl_info *wl, char *abbrev) * is defined, wl_attach will never be called, and thus, gcc will issue * a warning that this function is defined but not used if we declare * it as static. + * + * + * is called in wl_pci_probe() context, therefore no locking required. */ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, uint bustype, void *btparam, uint irq) @@ -995,6 +1004,9 @@ static struct ieee80211_supported_band wl_band_5GHz_nphy = { } }; +/* + * is called in wl_pci_probe() context, therefore no locking required. + */ static int ieee_hw_rate_init(struct ieee80211_hw *hw) { struct wl_info *wl = HW_TO_WL(hw); @@ -1039,6 +1051,9 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw) return 0; } +/* + * is called in wl_pci_probe() context, therefore no locking required. + */ static int ieee_hw_init(struct ieee80211_hw *hw) { hw->flags = IEEE80211_HW_SIGNAL_DBM @@ -1071,6 +1086,7 @@ static int ieee_hw_init(struct ieee80211_hw *hw) * This function determines if a device pointed to by pdev is a WL device, * and if so, performs a wl_attach() on it. * + * Perimeter lock is initialized in the course of this function. */ int __devinit wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -1194,6 +1210,10 @@ static int wl_resume(struct pci_dev *pdev) return err; } +/* +* called from both kernel as from wl_*() +* precondition: perimeter lock is not acquired. +*/ static void wl_remove(struct pci_dev *pdev) { struct wl_info *wl; @@ -1299,6 +1319,8 @@ module_exit(wl_module_exit); * This function frees resources owned by the WL device pointed to * by the wl parameter. * + * precondition: can both be called locked and unlocked + * */ void wl_free(struct wl_info *wl) { @@ -1358,7 +1380,10 @@ void wl_free(struct wl_info *wl) osl_detach(osh); } -/* transmit a packet */ +/* + * transmit a packet + * precondition: perimeter lock has been acquired + */ static int BCMFASTPATH wl_start(struct sk_buff *skb, struct wl_info *wl) { if (!wl) @@ -1374,12 +1399,18 @@ wl_start_int(struct wl_info *wl, struct ieee80211_hw *hw, struct sk_buff *skb) return NETDEV_TX_OK; } +/* + * precondition: perimeter lock has been acquired + */ void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, int prio) { WL_ERROR("Shouldn't be here %s\n", __func__); } +/* + * precondition: perimeter lock has been acquired + */ void wl_init(struct wl_info *wl) { WL_TRACE("wl%d: wl_init\n", wl->pub->unit); @@ -1389,6 +1420,9 @@ void wl_init(struct wl_info *wl) wlc_init(wl->wlc); } +/* + * precondition: perimeter lock has been acquired + */ uint wl_reset(struct wl_info *wl) { WL_TRACE("wl%d: wl_reset\n", wl->pub->unit); @@ -1414,6 +1448,9 @@ void BCMFASTPATH wl_intrson(struct wl_info *wl) INT_UNLOCK(wl, flags); } +/* + * precondition: perimeter lock has been acquired + */ bool wl_alloc_dma_resources(struct wl_info *wl, uint addrwidth) { return true; @@ -1439,6 +1476,9 @@ void wl_intrsrestore(struct wl_info *wl, u32 macintmask) INT_UNLOCK(wl, flags); } +/* + * precondition: perimeter lock has been acquired + */ int wl_up(struct wl_info *wl) { int error = 0; @@ -1451,6 +1491,9 @@ int wl_up(struct wl_info *wl) return error; } +/* + * precondition: perimeter lock has been acquired + */ void wl_down(struct wl_info *wl) { uint callbacks, ret_val = 0; @@ -1545,6 +1588,9 @@ static void wl_link_down(struct wl_info *wl, char *ifname) WL_NONE("wl%d: link down (%s)\n", wl->pub->unit, ifname); } +/* + * precondition: perimeter lock has been acquired + */ void wl_event(struct wl_info *wl, char *ifname, wlc_event_t *e) { @@ -1561,11 +1607,17 @@ void wl_event(struct wl_info *wl, char *ifname, wlc_event_t *e) } } +/* + * is called by the kernel from software irq context + */ static void wl_timer(unsigned long data) { _wl_timer((wl_timer_t *) data); } +/* +* precondition: perimeter lock is not acquired + */ static void _wl_timer(wl_timer_t *t) { WL_LOCK(t->wl); @@ -1587,6 +1639,12 @@ static void _wl_timer(wl_timer_t *t) WL_UNLOCK(t->wl); } +/* + * Adds a timer to the list. Caller supplies a timer function. + * Is called from wlc. + * + * precondition: perimeter lock has been acquired + */ wl_timer_t *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg), void *arg, const char *name) { @@ -1620,6 +1678,8 @@ wl_timer_t *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg), void *arg, /* BMAC_NOTE: Add timer adds only the kernel timer since it's going to be more accurate * as well as it's easier to make it periodic + * + * precondition: perimeter lock has been acquired */ void wl_add_timer(struct wl_info *wl, wl_timer_t *t, uint ms, int periodic) { @@ -1640,7 +1700,11 @@ void wl_add_timer(struct wl_info *wl, wl_timer_t *t, uint ms, int periodic) add_timer(&t->timer); } -/* return true if timer successfully deleted, false if still pending */ +/* + * return true if timer successfully deleted, false if still pending + * + * precondition: perimeter lock has been acquired + */ bool wl_del_timer(struct wl_info *wl, wl_timer_t *t) { if (t->set) { @@ -1654,6 +1718,9 @@ bool wl_del_timer(struct wl_info *wl, wl_timer_t *t) return true; } +/* + * precondition: perimeter lock has been acquired + */ void wl_free_timer(struct wl_info *wl, wl_timer_t *t) { wl_timer_t *tmp; @@ -1688,6 +1755,11 @@ void wl_free_timer(struct wl_info *wl, wl_timer_t *t) } +/* + * runs in software irq context + * + * precondition: perimeter lock is not acquired + */ static int wl_linux_watchdog(void *ctx) { struct wl_info *wl = (struct wl_info *) ctx; @@ -1735,6 +1807,9 @@ char *wl_firmwares[WL_MAX_FW] = { NULL }; +/* + * precondition: perimeter lock has been acquired + */ int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx) { int i, entry; @@ -1763,6 +1838,10 @@ fail: return BCME_NOTFOUND; } +/* + * Precondition: Since this function is called in wl_pci_probe() context, + * no locking is required. + */ int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx) { int i, entry; @@ -1784,6 +1863,10 @@ int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx) return -1; } +/* + * Precondition: Since this function is called in wl_pci_probe() context, + * no locking is required. + */ static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) { int status; @@ -1822,11 +1905,18 @@ static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) return wl_ucode_data_init(wl); } +/* + * precondition: can both be called locked and unlocked + */ void wl_ucode_free_buf(void *p) { kfree(p); } +/* + * Precondition: Since this function is called in wl_pci_probe() context, + * no locking is required. + */ static void wl_release_fw(struct wl_info *wl) { int i; @@ -1839,6 +1929,9 @@ static void wl_release_fw(struct wl_info *wl) /* * checks validity of all firmware images loaded from user space + * + * Precondition: Since this function is called in wl_pci_probe() context, + * no locking is required. */ int wl_check_firmwares(struct wl_info *wl) { @@ -1886,6 +1979,9 @@ int wl_check_firmwares(struct wl_info *wl) return rc; } +/* + * precondition: perimeter lock has been acquired + */ bool wl_rfkill_set_hw_state(struct wl_info *wl) { bool blocked = wlc_check_radio_disabled(wl->wlc); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h index 4d058b503aa7..4a9a8c884eda 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h @@ -825,8 +825,6 @@ extern void wlc_get_rcmta(struct wlc_info *wlc, int idx, #endif extern void wlc_set_rcmta(struct wlc_info *wlc, int idx, const u8 *addr); -extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, - const u8 *addr); extern void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, u32 *tsf_h_ptr); extern void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin); -- cgit v1.2.3 From e34870f828f8d9b7e2205c632cbc135a76f7dde6 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Wed, 23 Feb 2011 12:48:52 +0100 Subject: staging: brcm80211: removed locks around Mac80211 calls A spinlock was acquired prior to calling the Mac80211 functions ieee80211_wake_queues() and ieee80211_stop_queues() and Cfg80211 functions wiphy_rfkill_set_hw_state() and wiphy_rfkill_start_polling(). This is not required and could even lead to instability. Therefore the locks were removed. Signed-off-by: Roland Vossen Reviewed-by: Arend van Spriel Reviewed-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 3109e3da31d1..791329cbc8a6 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -171,9 +171,7 @@ static int wl_ops_start(struct ieee80211_hw *hw) WL_NONE("%s : Initial channel: %d\n", __func__, curchan->hw_value); */ - WL_LOCK(wl); ieee80211_wake_queues(hw); - WL_UNLOCK(wl); blocked = wl_rfkill_set_hw_state(wl); if (!blocked) wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); @@ -185,9 +183,8 @@ static void wl_ops_stop(struct ieee80211_hw *hw) { struct wl_info *wl = hw->priv; ASSERT(wl); - WL_LOCK(wl); ieee80211_stop_queues(hw); - WL_UNLOCK(wl); + return; } static int @@ -1988,8 +1985,10 @@ bool wl_rfkill_set_hw_state(struct wl_info *wl) WL_NONE("%s: update hw state: blocked=%s\n", __func__, blocked ? "true" : "false"); + WL_UNLOCK(wl); wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked); if (blocked) wiphy_rfkill_start_polling(wl->pub->ieee_hw->wiphy); + WL_LOCK(wl); return blocked; } -- cgit v1.2.3 From 2d57aa7bb708ada6e902c200e103d1ece380fb9c Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Wed, 23 Feb 2011 12:48:53 +0100 Subject: staging: brcm80211: added locks in wl_mac80211.c Increasing robustness of the code, although no problem has been reported in the field. Several code paths were unshielded for multi thread access. Several lock acquisitions have been added to wl_mac80211.c Signed-off-by: Roland Vossen Reviewed-by: Arend van Spriel Reviewed-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 791329cbc8a6..7645c6c972fd 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -172,7 +172,9 @@ static int wl_ops_start(struct ieee80211_hw *hw) */ ieee80211_wake_queues(hw); + WL_LOCK(wl); blocked = wl_rfkill_set_hw_state(wl); + WL_UNLOCK(wl); if (!blocked) wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); @@ -351,7 +353,9 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, val = 1; else val = 0; + WL_LOCK(wl); wlc_set(wl->wlc, WLC_SET_SHORTSLOT_OVERRIDE, val); + WL_UNLOCK(wl); } if (changed & BSS_CHANGED_HT) { @@ -380,8 +384,10 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, /* BSSID changed, for whatever reason (IBSS and managed mode) */ WL_NONE("%s: new BSSID: aid %d bss:%pM\n", __func__, info->aid, info->bssid); + WL_LOCK(wl); wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid); + WL_UNLOCK(wl); } if (changed & BSS_CHANGED_BEACON) { /* Beacon data changed, retrieve new beacon (beaconing modes) */ @@ -609,6 +615,7 @@ wl_ops_ampdu_action(struct ieee80211_hw *hw, struct scb *scb = (struct scb *)sta->drv_priv; #endif struct wl_info *wl = hw->priv; + int status; ASSERT(scb->magic == SCB_MAGIC); switch (action) { @@ -619,7 +626,10 @@ wl_ops_ampdu_action(struct ieee80211_hw *hw, WL_NONE("%s: action = IEEE80211_AMPDU_RX_STOP\n", __func__); break; case IEEE80211_AMPDU_TX_START: - if (!wlc_aggregatable(wl->wlc, tid)) { + WL_LOCK(wl); + status = wlc_aggregatable(wl->wlc, tid); + WL_UNLOCK(wl); + if (!status) { /* WL_ERROR("START: tid %d is not agg' able, return FAILURE to stack\n", tid); */ return -1; } @@ -1215,6 +1225,7 @@ static void wl_remove(struct pci_dev *pdev) { struct wl_info *wl; struct ieee80211_hw *hw; + int status; hw = pci_get_drvdata(pdev); wl = HW_TO_WL(hw); @@ -1223,7 +1234,10 @@ static void wl_remove(struct pci_dev *pdev) return; } - if (!wlc_chipmatch(pdev->vendor, pdev->device)) { + WL_LOCK(wl); + status = wlc_chipmatch(pdev->vendor, pdev->device); + WL_UNLOCK(wl); + if (!status) { WL_ERROR("wl: wl_remove: wlc_chipmatch failed\n"); return; } -- cgit v1.2.3 From 668c711bfd80e96c0ee92c2c098b81de62bbf7d3 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 21 Feb 2011 00:03:08 +0900 Subject: staging: rtl8192e: Remove useless usermode callback Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_dm.c | 26 -------------------------- 1 file changed, 26 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index 1ade3672546e..ec09d9a80f76 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -195,34 +195,8 @@ void dm_CheckRxAggregation(struct net_device *dev) { } #endif - -// call the script file to enable -void dm_check_ac_dc_power(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - static char *ac_dc_check_script_path = "/etc/acpi/wireless-rtl-ac-dc-power.sh"; - char *argv[] = {ac_dc_check_script_path,DRV_NAME,NULL}; - static char *envp[] = {"HOME=/", - "TERM=linux", - "PATH=/usr/bin:/bin", - NULL}; - - if(priv->ResetProgress == RESET_TYPE_SILENT) - { - RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF), "GPIOChangeRFWorkItemCallBack(): Silent Reseting!!!!!!!\n"); - return; - } - - if(priv->ieee80211->state != IEEE80211_LINKED) { - return; - } - call_usermodehelper(ac_dc_check_script_path,argv,envp,1); -} - void hal_dm_watchdog(struct net_device *dev) { - dm_check_ac_dc_power(dev); - /*Add by amy 2008/05/15 ,porting from windows code.*/ dm_check_rate_adaptive(dev); dm_dynamic_txpower(dev); -- cgit v1.2.3 From 51de57ef21fd9fda1586d0c0a3e77e0dfdcb131a Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 21 Feb 2011 00:03:20 +0900 Subject: staging: rtl8192e: Remove USB related code Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_dm.c | 46 ------------------------------------ 1 file changed, 46 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index ec09d9a80f76..20b201d0401b 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -153,48 +153,6 @@ void deinit_hal_dm(struct net_device *dev) } - -#ifdef USB_RX_AGGREGATION_SUPPORT -void dm_CheckRxAggregation(struct net_device *dev) { - struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev); - PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo; - static unsigned long lastTxOkCnt = 0; - static unsigned long lastRxOkCnt = 0; - unsigned long curTxOkCnt = 0; - unsigned long curRxOkCnt = 0; - - curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; - curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; - - if((curTxOkCnt + curRxOkCnt) < 15000000) { - return; - } - - if(curTxOkCnt > 4*curRxOkCnt) { - if (priv->bCurrentRxAggrEnable) { - write_nic_dword(priv, 0x1a8, 0); - priv->bCurrentRxAggrEnable = false; - } - }else{ - if (!priv->bCurrentRxAggrEnable && !pHTInfo->bCurrentRT2RTAggregation) { - u32 ulValue; - ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) | - (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout); - /* - * If usb rx firmware aggregation is enabled, - * when anyone of three threshold conditions above is reached, - * firmware will send aggregated packet to driver. - */ - write_nic_dword(priv, 0x1a8, ulValue); - priv->bCurrentRxAggrEnable = true; - } - } - - lastTxOkCnt = priv->stats.txbytesunicast; - lastRxOkCnt = priv->stats.rxbytesunicast; -} -#endif - void hal_dm_watchdog(struct net_device *dev) { /*Add by amy 2008/05/15 ,porting from windows code.*/ @@ -216,10 +174,6 @@ void hal_dm_watchdog(struct net_device *dev) dm_check_pbc_gpio(dev); dm_send_rssi_tofw(dev); dm_ctstoself(dev); - -#ifdef USB_RX_AGGREGATION_SUPPORT - dm_CheckRxAggregation(dev); -#endif } -- cgit v1.2.3 From 09e4f231fcea4e4fa2d01b851ada488fa9cc395a Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 21 Feb 2011 00:03:36 +0900 Subject: staging: rtl8192e: Remove externs, redundant comments Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_dm.h | 117 +++++++---------------------------- 1 file changed, 23 insertions(+), 94 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_dm.h b/drivers/staging/rtl8192e/r8192E_dm.h index 237c30db8c3f..2ca9333d8773 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.h +++ b/drivers/staging/rtl8192e/r8192E_dm.h @@ -16,12 +16,10 @@ * 10/04/2007 MHC Create initial version. * *****************************************************************************/ - /* Check to see if the file has been included already. */ + #ifndef __R8192UDM_H__ #define __R8192UDM_H__ - -/*--------------------------Define Parameters-------------------------------*/ #define OFDM_Table_Length 19 #define CCK_Table_length 12 @@ -65,54 +63,7 @@ #define Initial_Tx_Rate_Reg 0x1e1 //0x1b9 #define Tx_Retry_Count_Reg 0x1ac #define RegC38_TH 20 -#if 0 -//---------------------------------------------------------------------------- -// 8190 Rate Adaptive Table Register (offset 0x320, 4 byte) -//---------------------------------------------------------------------------- - -//CCK -#define RATR_1M 0x00000001 -#define RATR_2M 0x00000002 -#define RATR_55M 0x00000004 -#define RATR_11M 0x00000008 -//OFDM -#define RATR_6M 0x00000010 -#define RATR_9M 0x00000020 -#define RATR_12M 0x00000040 -#define RATR_18M 0x00000080 -#define RATR_24M 0x00000100 -#define RATR_36M 0x00000200 -#define RATR_48M 0x00000400 -#define RATR_54M 0x00000800 -//MCS 1 Spatial Stream -#define RATR_MCS0 0x00001000 -#define RATR_MCS1 0x00002000 -#define RATR_MCS2 0x00004000 -#define RATR_MCS3 0x00008000 -#define RATR_MCS4 0x00010000 -#define RATR_MCS5 0x00020000 -#define RATR_MCS6 0x00040000 -#define RATR_MCS7 0x00080000 -//MCS 2 Spatial Stream -#define RATR_MCS8 0x00100000 -#define RATR_MCS9 0x00200000 -#define RATR_MCS10 0x00400000 -#define RATR_MCS11 0x00800000 -#define RATR_MCS12 0x01000000 -#define RATR_MCS13 0x02000000 -#define RATR_MCS14 0x04000000 -#define RATR_MCS15 0x08000000 -// ALL CCK Rate -#define RATE_ALL_CCK RATR_1M|RATR_2M|RATR_55M|RATR_11M -#define RATE_ALL_OFDM_AG RATR_6M|RATR_9M|RATR_12M|RATR_18M|RATR_24M\ - |RATR_36M|RATR_48M|RATR_54M -#define RATE_ALL_OFDM_2SS RATR_MCS8|RATR_MCS9 |RATR_MCS10|RATR_MCS11| \ - RATR_MCS12|RATR_MCS13|RATR_MCS14|RATR_MCS15 -#endif -/*--------------------------Define Parameters-------------------------------*/ - - -/*------------------------------Define structure----------------------------*/ + /* 2007/10/04 MH Define upper and lower threshold of DIG enable or disable. */ typedef struct _dynamic_initial_gain_threshold_ { @@ -256,55 +207,33 @@ typedef struct tag_Tx_Config_Cmd_Format u32 Length; /* Command packet length. */ u32 Value; }DCMD_TXCMD_T, *PDCMD_TXCMD_T; -/*------------------------------Define structure----------------------------*/ - - -/*------------------------Export global variable----------------------------*/ -extern dig_t dm_digtable; -extern DRxPathSel DM_RxPathSelTable; -/*------------------------Export global variable----------------------------*/ -/*------------------------Export Marco Definition---------------------------*/ +extern dig_t dm_digtable; +extern DRxPathSel DM_RxPathSelTable; -/*------------------------Export Marco Definition---------------------------*/ +void init_hal_dm(struct net_device *dev); +void deinit_hal_dm(struct net_device *dev); +void hal_dm_watchdog(struct net_device *dev); -/*--------------------------Exported Function prototype---------------------*/ -/*--------------------------Exported Function prototype---------------------*/ -extern void init_hal_dm(struct net_device *dev); -extern void deinit_hal_dm(struct net_device *dev); - -extern void hal_dm_watchdog(struct net_device *dev); - - -extern void init_rate_adaptive(struct net_device *dev); -extern void dm_txpower_trackingcallback(struct work_struct *work); - -extern void dm_cck_txpower_adjust(struct net_device *dev,bool binch14); -extern void dm_restore_dynamic_mechanism_state(struct net_device *dev); -extern void dm_backup_dynamic_mechanism_state(struct net_device *dev); -extern void dm_change_dynamic_initgain_thresh(struct net_device *dev, - u32 dm_type, - u32 dm_value); -extern void DM_ChangeFsyncSetting(struct net_device *dev, - s32 DM_Type, - s32 DM_Value); -extern void dm_force_tx_fw_info(struct net_device *dev, - u32 force_type, - u32 force_value); -extern void dm_init_edca_turbo(struct net_device *dev); -extern void dm_rf_operation_test_callback(unsigned long data); -extern void dm_rf_pathcheck_workitemcallback(struct work_struct *work); -extern void dm_fsync_timer_callback(unsigned long data); -#if 0 -extern bool dm_check_lbus_status(struct net_device *dev); -#endif -extern void dm_check_fsync(struct net_device *dev); -extern void dm_initialize_txpower_tracking(struct net_device *dev); +void init_rate_adaptive(struct net_device *dev); +void dm_txpower_trackingcallback(struct work_struct *work); +void dm_cck_txpower_adjust(struct net_device *dev,bool binch14); +void dm_restore_dynamic_mechanism_state(struct net_device *dev); +void dm_backup_dynamic_mechanism_state(struct net_device *dev); +void dm_change_dynamic_initgain_thresh(struct net_device *dev, u32 dm_type, + u32 dm_value); +void DM_ChangeFsyncSetting(struct net_device *dev, s32 DM_Type, s32 DM_Value); +void dm_force_tx_fw_info(struct net_device *dev, u32 force_type, + u32 force_value); +void dm_init_edca_turbo(struct net_device *dev); +void dm_rf_operation_test_callback(unsigned long data); +void dm_rf_pathcheck_workitemcallback(struct work_struct *work); +void dm_fsync_timer_callback(unsigned long data); +void dm_check_fsync(struct net_device *dev); +void dm_initialize_txpower_tracking(struct net_device *dev); #endif /*__R8192UDM_H__ */ - -/* End of r8192U_dm.h */ -- cgit v1.2.3 From 9c100d50fc7d9f0f3e5309c704da044ece2da5c6 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 21 Feb 2011 00:04:02 +0900 Subject: staging: rtl8192e: Delete dead code Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8190_rtl8256.c | 50 -------------------------------- 1 file changed, 50 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index 7896d23c4e20..8b182089b046 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -121,9 +121,6 @@ RT_STATUS phy_RF8256_Config_ParaFile(struct net_device* dev) pPhyReg = &priv->PHYRegDef[eRFPath]; - // Joseph test for shorten RF config - // pHalData->RfReg0Value[eRFPath] = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, rGlobalCtrl, bMaskDWord); - /*----Store original RFENV control type----*/ switch(eRFPath) { @@ -473,20 +470,17 @@ MgntDisconnectIBSS( ) { struct r8192_priv *priv = ieee80211_priv(dev); - //RT_OP_MODE OpMode; u8 i; bool bFilterOutNonAssociatedBSSID = false; priv->ieee80211->state = IEEE80211_NOLINK; -// PlatformZeroMemory( pMgntInfo->Bssid, 6 ); for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i]= 0x55; priv->OpMode = RT_OP_MODE_NO_LINK; write_nic_word(priv, BSSIDR, ((u16*)priv->ieee80211->current_network.bssid)[0]); write_nic_dword(priv, BSSIDR+2, ((u32*)(priv->ieee80211->current_network.bssid+2))[0]); { RT_OP_MODE OpMode = priv->OpMode; - //LED_CTL_MODE LedAction = LED_CTL_NO_LINK; u8 btMsr = read_nic_byte(priv, MSR); btMsr &= 0xfc; @@ -495,7 +489,6 @@ MgntDisconnectIBSS( { case RT_OP_MODE_INFRASTRUCTURE: btMsr |= MSR_LINK_MANAGED; - //LedAction = LED_CTL_LINK; break; case RT_OP_MODE_IBSS: @@ -505,7 +498,6 @@ MgntDisconnectIBSS( case RT_OP_MODE_AP: btMsr |= MSR_LINK_MASTER; - //LedAction = LED_CTL_LINK; break; default: @@ -514,9 +506,6 @@ MgntDisconnectIBSS( } write_nic_byte(priv, MSR, btMsr); - - // LED control - //Adapter->HalFunc.LedControlHandler(Adapter, LedAction); } ieee80211_stop_send_beacons(priv->ieee80211); @@ -538,7 +527,6 @@ MgntDisconnectIBSS( } } - //MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE ); notify_wx_assoc_event(priv->ieee80211); } @@ -562,14 +550,10 @@ MlmeDisassociateRequest( //ShuChen TODO: change media status. //ShuChen TODO: What to do when disassociate. priv->ieee80211->state = IEEE80211_NOLINK; - //pMgntInfo->AsocTimestamp = 0; for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i] = 0x22; -// pMgntInfo->mBrates.Length = 0; -// Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_BASIC_RATE, (pu1Byte)(&pMgntInfo->mBrates) ); priv->OpMode = RT_OP_MODE_NO_LINK; { RT_OP_MODE OpMode = priv->OpMode; - //LED_CTL_MODE LedAction = LED_CTL_NO_LINK; u8 btMsr = read_nic_byte(priv, MSR); btMsr &= 0xfc; @@ -578,7 +562,6 @@ MlmeDisassociateRequest( { case RT_OP_MODE_INFRASTRUCTURE: btMsr |= MSR_LINK_MANAGED; - //LedAction = LED_CTL_LINK; break; case RT_OP_MODE_IBSS: @@ -588,7 +571,6 @@ MlmeDisassociateRequest( case RT_OP_MODE_AP: btMsr |= MSR_LINK_MASTER; - //LedAction = LED_CTL_LINK; break; default: @@ -597,9 +579,6 @@ MlmeDisassociateRequest( } write_nic_byte(priv, MSR, btMsr); - - // LED control - //Adapter->HalFunc.LedControlHandler(Adapter, LedAction); } ieee80211_disassociate(priv->ieee80211); @@ -646,32 +625,6 @@ MgntDisconnect( { struct r8192_priv *priv = ieee80211_priv(dev); - // - // Schedule an workitem to wake up for ps mode, 070109, by rcnjko. - // -#ifdef TO_DO - if(pMgntInfo->mPss != eAwake) - { - // - // Using AwkaeTimer to prevent mismatch ps state. - // In the timer the state will be changed according to the RF is being awoke or not. By Bruce, 2007-10-31. - // - // PlatformScheduleWorkItem( &(pMgntInfo->AwakeWorkItem) ); - PlatformSetTimer( Adapter, &(pMgntInfo->AwakeTimer), 0 ); - } -#endif - // Follow 8180 AP mode, 2005.05.30, by rcnjko. -#ifdef TO_DO - if(pMgntInfo->mActingAsAp) - { - RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> AP_DisassociateAllStation\n")); - AP_DisassociateAllStation(Adapter, unspec_reason); - return TRUE; - } -#endif - // Indication of disassociation event. - //DrvIFIndicateDisassociation(Adapter, asRsn); - // In adhoc mode, update beacon frame. if( priv->ieee80211->state == IEEE80211_LINKED ) { @@ -688,9 +641,6 @@ MgntDisconnect( // frame to AP. 2005.01.27, by rcnjko. MgntDisconnectAP(dev, asRsn); } - - // Inidicate Disconnect, 2005.02.23, by rcnjko. - //MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE); } return true; -- cgit v1.2.3 From 9f17b076387f2fdb507578efe8651bb4786de2a4 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 21 Feb 2011 00:04:21 +0900 Subject: staging: rtl8192e: Make functions static Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 11 ----------- drivers/staging/rtl8192e/r8192E_core.c | 27 ++++++++++----------------- drivers/staging/rtl8192e/r8192E_wx.c | 2 +- drivers/staging/rtl8192e/r8192E_wx.h | 3 --- 4 files changed, 11 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index f25e97542660..c8df912ca2e2 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1048,27 +1048,17 @@ void write_nic_byte(struct r8192_priv *priv, int x,u8 y); void write_nic_word(struct r8192_priv *priv, int x,u16 y); void write_nic_dword(struct r8192_priv *priv, int x,u32 y); -void rtl8192_halt_adapter(struct net_device *dev, bool reset); -void rtl8192_rx_enable(struct net_device *); -void rtl8192_tx_enable(struct net_device *); - -void rtl8192_update_msr(struct net_device *dev); int rtl8192_down(struct net_device *dev); int rtl8192_up(struct net_device *dev); void rtl8192_commit(struct net_device *dev); -void rtl8192_set_chan(struct net_device *dev,short ch); void write_phy(struct net_device *dev, u8 adr, u8 data); -void write_phy_cck(struct net_device *dev, u8 adr, u32 data); -void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data); void CamResetAllEntry(struct net_device* dev); void EnableHWSecurityConfig8192(struct net_device *dev); void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent ); void dm_cck_txpower_adjust(struct net_device *dev, bool binch14); void firmware_init_param(struct net_device *dev); RT_STATUS cmpk_message_handle_tx(struct net_device *dev, u8* codevirtualaddress, u32 packettype, u32 buffer_len); -void rtl8192_hw_wakeup_wq (struct work_struct *work); -short rtl8192_is_tx_queue_empty(struct net_device *dev); #ifdef ENABLE_IPS void IPSEnter(struct net_device *dev); void IPSLeave(struct net_device *dev); @@ -1085,6 +1075,5 @@ void LeisurePSLeave(struct net_device *dev); bool NicIFEnableNIC(struct net_device* dev); bool NicIFDisableNIC(struct net_device* dev); -void rtl8192_irq_disable(struct net_device *dev); void PHY_SetRtl8192eRfOff(struct net_device* dev); #endif diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 9b2c07ebf477..f02ec6110aa3 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -595,7 +595,7 @@ static void rtl8192_proc_init_one(struct net_device *dev) } } -short check_nic_enough_desc(struct net_device *dev, int prio) +static short check_nic_enough_desc(struct net_device *dev, int prio) { struct r8192_priv *priv = ieee80211_priv(dev); struct rtl8192_tx_ring *ring = &priv->tx_ring[prio]; @@ -620,7 +620,7 @@ static void rtl8192_irq_enable(struct net_device *dev) write_nic_dword(priv, INTA_MASK, priv->irq_mask); } -void rtl8192_irq_disable(struct net_device *dev) +static void rtl8192_irq_disable(struct net_device *dev) { struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); @@ -628,7 +628,7 @@ void rtl8192_irq_disable(struct net_device *dev) synchronize_irq(dev->irq); } -void rtl8192_update_msr(struct net_device *dev) +static void rtl8192_update_msr(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); u8 msr; @@ -656,7 +656,7 @@ void rtl8192_update_msr(struct net_device *dev) write_nic_byte(priv, MSR, msr); } -void rtl8192_set_chan(struct net_device *dev,short ch) +static void rtl8192_set_chan(struct net_device *dev,short ch) { struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); @@ -668,7 +668,7 @@ void rtl8192_set_chan(struct net_device *dev,short ch) priv->rf_set_chan(dev, priv->chan); } -void rtl8192_rx_enable(struct net_device *dev) +static void rtl8192_rx_enable(struct net_device *dev) { struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); @@ -687,7 +687,7 @@ void rtl8192_rx_enable(struct net_device *dev) * BEACON_QUEUE ===> 8 * */ static const u32 TX_DESC_BASE[] = {BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA}; -void rtl8192_tx_enable(struct net_device *dev) +static void rtl8192_tx_enable(struct net_device *dev) { struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); u32 i; @@ -762,7 +762,7 @@ void PHY_SetRtl8192eRfOff(struct net_device* dev) } -void rtl8192_halt_adapter(struct net_device *dev, bool reset) +static void rtl8192_halt_adapter(struct net_device *dev, bool reset) { struct r8192_priv *priv = ieee80211_priv(dev); int i; @@ -819,13 +819,6 @@ void rtl8192_halt_adapter(struct net_device *dev, bool reset) skb_queue_purge(&priv->skb_queue); } -static const u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540}; -inline u16 rtl8192_rate2rate(short rate) -{ - if (rate >11) return 0; - return rtl_rate[rate]; -} - static void rtl8192_data_hard_stop(struct net_device *dev) { } @@ -1065,7 +1058,7 @@ static void rtl8192_net_update(struct net_device *dev) } } -void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb) +static void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb) { struct r8192_priv *priv = ieee80211_priv(dev); struct rtl8192_tx_ring *ring; @@ -1831,7 +1824,7 @@ static bool GetHalfNmodeSupportByAPs819xPci(struct net_device* dev) return ieee->bHalfWirelessN24GMode; } -short rtl8192_is_tx_queue_empty(struct net_device *dev) +static short rtl8192_is_tx_queue_empty(struct net_device *dev) { int i=0; struct r8192_priv *priv = ieee80211_priv(dev); @@ -1889,7 +1882,7 @@ static void rtl8192_hw_wakeup(struct net_device* dev) MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS); } -void rtl8192_hw_wakeup_wq (struct work_struct *work) +static void rtl8192_hw_wakeup_wq (struct work_struct *work) { struct delayed_work *dwork = container_of(work,struct delayed_work,work); struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq); diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c index a2e943293a79..529929c661be 100644 --- a/drivers/staging/rtl8192e/r8192E_wx.c +++ b/drivers/staging/rtl8192e/r8192E_wx.c @@ -1149,7 +1149,7 @@ static iw_handler r8192_private_handler[] = { r8192_wx_adapter_power_status, }; -struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev) +static struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); struct ieee80211_device* ieee = priv->ieee80211; diff --git a/drivers/staging/rtl8192e/r8192E_wx.h b/drivers/staging/rtl8192e/r8192E_wx.h index 291cb6a24486..25f06c165d45 100644 --- a/drivers/staging/rtl8192e/r8192E_wx.h +++ b/drivers/staging/rtl8192e/r8192E_wx.h @@ -14,8 +14,5 @@ #ifndef R8180_WX_H #define R8180_WX_H -//#include extern struct iw_handler_def r8192_wx_handlers_def; -/* Enable the rtl819x_core.c to share this function, david 2008.9.22 */ -struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev); #endif -- cgit v1.2.3 From 703fdcc39856a73800df8d749930c8d7bbf21571 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 21 Feb 2011 00:04:54 +0900 Subject: staging: rtl8192e: Make RT_TRACE use consistent Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 2 +- drivers/staging/rtl8192e/r8192E_core.c | 52 +++++++++++++++++----------------- drivers/staging/rtl8192e/r8192E_dm.c | 8 +++--- drivers/staging/rtl8192e/r8192E_wx.c | 2 +- drivers/staging/rtl8192e/r8192_pm.c | 2 +- drivers/staging/rtl8192e/r819xE_phy.c | 22 +++++++------- 6 files changed, 44 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index c8df912ca2e2..03306869620c 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -97,7 +97,7 @@ extern u32 rt_global_debug_component; #define RT_TRACE(component, x, args...) \ do { if(rt_global_debug_component & component) \ - printk(KERN_DEBUG RTL819xE_MODULE_NAME ":" x "\n" , \ + printk(KERN_DEBUG RTL819xE_MODULE_NAME ":" x , \ ##args);\ }while(0); diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index f02ec6110aa3..9a88f49d4fff 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -518,7 +518,7 @@ static int proc_get_stats_rx(char *page, char **start, static void rtl8192_proc_module_init(void) { - RT_TRACE(COMP_INIT, "Initializing proc filesystem"); + RT_TRACE(COMP_INIT, "Initializing proc filesystem\n"); rtl8192_proc=create_proc_entry(RTL819xE_MODULE_NAME, S_IFDIR, init_net.proc_net); } @@ -1297,7 +1297,7 @@ static short rtl8192_tx(struct net_device *dev, struct sk_buff* skb) pdesc = &ring->desc[idx]; if ((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) { - RT_TRACE(COMP_ERR, "No more TX desc@%d, ring->idx = %d,idx = %d,%x", + RT_TRACE(COMP_ERR, "No more TX desc@%d, ring->idx = %d,idx = %d,%x\n", tcb_desc->queue_index, ring->idx, idx, skb->len); spin_unlock_irqrestore(&priv->irq_th_lock, flags); return skb->len; @@ -1615,7 +1615,7 @@ static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv, if ((network->qos_data.active == 1) && (active_network == 1)) { queue_work(priv->priv_wq, &priv->qos_activate); - RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n"); + RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate\n"); } network->qos_data.active = 0; network->qos_data.supported = 0; @@ -1847,7 +1847,7 @@ static void rtl8192_hw_sleep_down(struct net_device *dev) spin_lock(&priv->rf_ps_lock); if (priv->RFChangeInProgress) { spin_unlock(&priv->rf_ps_lock); - RT_TRACE(COMP_RF, "rtl8192_hw_sleep_down(): RF Change in progress! \n"); + RT_TRACE(COMP_RF, "rtl8192_hw_sleep_down(): RF Change in progress!\n"); printk("rtl8192_hw_sleep_down(): RF Change in progress!\n"); return; } @@ -1872,7 +1872,7 @@ static void rtl8192_hw_wakeup(struct net_device* dev) spin_lock(&priv->rf_ps_lock); if (priv->RFChangeInProgress) { spin_unlock(&priv->rf_ps_lock); - RT_TRACE(COMP_RF, "rtl8192_hw_wakeup(): RF Change in progress! \n"); + RT_TRACE(COMP_RF, "rtl8192_hw_wakeup(): RF Change in progress!\n"); printk("rtl8192_hw_wakeup(): RF Change in progress! schedule wake up task again\n"); queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->hw_wakeup_wq,MSECS(10));//PowerSave is not supported if kernel version is below 2.6.20 return; @@ -2160,8 +2160,8 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) ICVer8192 = (IC_Version&0xf); //bit0~3; 1:A cut, 2:B cut, 3:C cut... ICVer8256 = ((IC_Version&0xf0)>>4);//bit4~6, bit7 reserved for other RF chip; 1:A cut, 2:B cut, 3:C cut... - RT_TRACE(COMP_INIT, "\nICVer8192 = 0x%x\n", ICVer8192); - RT_TRACE(COMP_INIT, "\nICVer8256 = 0x%x\n", ICVer8256); + RT_TRACE(COMP_INIT, "ICVer8192 = 0x%x\n", ICVer8192); + RT_TRACE(COMP_INIT, "ICVer8256 = 0x%x\n", ICVer8256); if(ICVer8192 == 0x2) //B-cut { if(ICVer8256 == 0x5) //E-cut @@ -2186,7 +2186,7 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) priv->eeprom_did = 0; priv->eeprom_CustomerID = 0; priv->eeprom_ChannelPlan = 0; - RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", 0xff); + RT_TRACE(COMP_INIT, "IC Version = 0x%x\n", 0xff); } RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid); @@ -2369,11 +2369,11 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) if(priv->rf_type == RF_1T2R) { - RT_TRACE(COMP_INIT, "\n1T2R config\n"); + RT_TRACE(COMP_INIT, "1T2R config\n"); } else if (priv->rf_type == RF_2T4R) { - RT_TRACE(COMP_INIT, "\n2T4R config\n"); + RT_TRACE(COMP_INIT, "2T4R config\n"); } // 2008/01/16 MH We can only know RF type in the function. So we have to init @@ -2486,8 +2486,8 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan); - RT_TRACE(COMP_INIT, "ChannelPlan = %d \n", priv->ChannelPlan); - RT_TRACE(COMP_INIT, "LedStrategy = %d \n", priv->LedStrategy); + RT_TRACE(COMP_INIT, "ChannelPlan = %d\n", priv->ChannelPlan); + RT_TRACE(COMP_INIT, "LedStrategy = %d\n", priv->LedStrategy); RT_TRACE(COMP_TRACE, "<==== ReadAdapterInfo\n"); return ; @@ -2875,12 +2875,12 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) { if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS) { // H/W or S/W RF OFF before sleep. - RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason); + RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d)\n", __FUNCTION__,priv->ieee80211->RfOffReason); MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason); } else if(priv->ieee80211->RfOffReason >= RF_CHANGE_BY_IPS) { // H/W or S/W RF OFF before sleep. - RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason); + RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d)\n", __FUNCTION__,priv->ieee80211->RfOffReason); MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason); } else @@ -3131,7 +3131,7 @@ void InactivePsWorkItemCallback(struct net_device *dev) struct r8192_priv *priv = ieee80211_priv(dev); PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); - RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() ---------> \n"); + RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() --------->\n"); // // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem // is really scheduled. @@ -3152,7 +3152,7 @@ void InactivePsWorkItemCallback(struct net_device *dev) // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20. // pPSC->bSwRfProcessing = FALSE; - RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <--------- \n"); + RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <---------\n"); } #ifdef ENABLE_LPS @@ -3507,7 +3507,7 @@ static int _rtl8192_up(struct net_device *dev) priv->up=1; priv->ieee80211->ieee_up=1; priv->bdisable_nic = false; //YJ,add,091111 - RT_TRACE(COMP_INIT, "Bringing up iface"); + RT_TRACE(COMP_INIT, "Bringing up iface\n"); init_status = rtl8192_adapter_start(dev); if(init_status != RT_STATUS_SUCCESS) @@ -3914,7 +3914,7 @@ static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct { if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath)) continue; - RT_TRACE(COMP_DBG,"Jacken -> pPreviousstats->RxMIMOSignalStrength[rfpath] = %d \n" ,pprevious_stats->RxMIMOSignalStrength[rfpath] ); + RT_TRACE(COMP_DBG, "pPreviousstats->RxMIMOSignalStrength[rfpath] = %d\n", pprevious_stats->RxMIMOSignalStrength[rfpath]); //Fixed by Jacken 2008-03-20 if(priv->stats.rx_rssi_percentage[rfpath] == 0) { @@ -3933,7 +3933,7 @@ static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) + (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor); } - RT_TRACE(COMP_DBG,"Jacken -> priv->RxStats.RxRSSIPercentage[rfPath] = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] ); + RT_TRACE(COMP_DBG, "priv->RxStats.RxRSSIPercentage[rfPath] = %d \n" , priv->stats.rx_rssi_percentage[rfpath]); } } @@ -4697,7 +4697,7 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, int ret = -ENODEV; unsigned long pmem_start, pmem_len, pmem_flags; - RT_TRACE(COMP_INIT,"Configuring chip resources"); + RT_TRACE(COMP_INIT,"Configuring chip resources\n"); if( pci_enable_device (pdev) ){ RT_TRACE(COMP_ERR,"Failed to enable PCI device"); @@ -4731,20 +4731,20 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, pmem_flags = pci_resource_flags (pdev, 1); if (!(pmem_flags & IORESOURCE_MEM)) { - RT_TRACE(COMP_ERR,"region #1 not a MMIO resource, aborting"); + RT_TRACE(COMP_ERR, "region #1 not a MMIO resource, aborting\n"); goto fail; } //DMESG("Memory mapped space @ 0x%08lx ", pmem_start); if( ! request_mem_region(pmem_start, pmem_len, RTL819xE_MODULE_NAME)) { - RT_TRACE(COMP_ERR,"request_mem_region failed!"); + RT_TRACE(COMP_ERR,"request_mem_region failed!\n"); goto fail; } ioaddr = (unsigned long)ioremap_nocache( pmem_start, pmem_len); if( ioaddr == (unsigned long)NULL ){ - RT_TRACE(COMP_ERR,"ioremap failed!"); + RT_TRACE(COMP_ERR,"ioremap failed!\n"); // release_mem_region( pmem_start, pmem_len ); goto fail1; } @@ -4778,7 +4778,7 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, RT_TRACE(COMP_INIT, "Driver probe completed1\n"); if(rtl8192_init(dev)!=0){ - RT_TRACE(COMP_ERR, "Initialization failed"); + RT_TRACE(COMP_ERR, "Initialization failed\n"); goto fail; } @@ -4896,7 +4896,7 @@ static int __init rtl8192_pci_module_init(void) printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n"); printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n"); - RT_TRACE(COMP_INIT, "Initializing module"); + RT_TRACE(COMP_INIT, "Initializing module\n"); rtl8192_proc_module_init(); if(0!=pci_register_driver(&rtl8192_pci_driver)) { @@ -4912,7 +4912,7 @@ static void __exit rtl8192_pci_module_exit(void) { pci_unregister_driver(&rtl8192_pci_driver); - RT_TRACE(COMP_DOWN, "Exiting"); + RT_TRACE(COMP_DOWN, "Exiting\n"); rtl8192_proc_module_remove(); ieee80211_rtl_exit(); } diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index 20b201d0401b..330e9d9e2583 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -751,12 +751,12 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev) // read and filter out unreasonable value tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078); // 0x12: RF Reg[10:7] - RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d \n", tmpRegA); + RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d\n", tmpRegA); if(tmpRegA < 3 || tmpRegA > 13) return; if(tmpRegA >= 12) // if over 12, TP will be bad when high temperature tmpRegA = 12; - RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d \n", tmpRegA); + RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d\n", tmpRegA); priv->ThermalMeter[0] = ThermalMeterVal; //We use fixed value by Bryant's suggestion priv->ThermalMeter[1] = ThermalMeterVal; //We use fixed value by Bryant's suggestion @@ -2656,7 +2656,7 @@ static void dm_dynamic_txpower(struct net_device *dev) txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW; } - RT_TRACE(COMP_TXAGC,"priv->undecorated_smoothed_pwdb = %ld \n" , priv->undecorated_smoothed_pwdb); + RT_TRACE(COMP_TXAGC, "priv->undecorated_smoothed_pwdb = %ld\n" , priv->undecorated_smoothed_pwdb); if(priv->ieee80211->state == IEEE80211_LINKED) { @@ -2693,7 +2693,7 @@ static void dm_dynamic_txpower(struct net_device *dev) if( (priv->bDynamicTxHighPower != priv->bLastDTPFlag_High ) || (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low ) ) { - RT_TRACE(COMP_TXAGC,"SetTxPowerLevel8190() channel = %d \n" , priv->ieee80211->current_network.channel); + RT_TRACE(COMP_TXAGC, "SetTxPowerLevel8190() channel = %d\n", priv->ieee80211->current_network.channel); rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel); diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c index 529929c661be..bd89bb04955e 100644 --- a/drivers/staging/rtl8192e/r8192E_wx.c +++ b/drivers/staging/rtl8192e/r8192E_wx.c @@ -653,7 +653,7 @@ static int r8192_wx_set_enc(struct net_device *dev, down(&priv->wx_sem); - RT_TRACE(COMP_SEC, "Setting SW wep key"); + RT_TRACE(COMP_SEC, "Setting SW wep key\n"); ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key); up(&priv->wx_sem); diff --git a/drivers/staging/rtl8192e/r8192_pm.c b/drivers/staging/rtl8192e/r8192_pm.c index 5679c8ba370d..a762c2c188a0 100644 --- a/drivers/staging/rtl8192e/r8192_pm.c +++ b/drivers/staging/rtl8192e/r8192_pm.c @@ -73,7 +73,7 @@ int rtl8192E_resume (struct pci_dev *pdev) int err; u32 val; - RT_TRACE(COMP_POWER, "================>r8192E resume call."); + RT_TRACE(COMP_POWER, "================>r8192E resume call.\n"); pci_set_power_state(pdev, PCI_D0); diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c index ef23b0eaf659..f4d220ad322a 100644 --- a/drivers/staging/rtl8192e/r819xE_phy.c +++ b/drivers/staging/rtl8192e/r819xE_phy.c @@ -1099,7 +1099,7 @@ void rtl8192_phyConfigBB(struct net_device* dev, u8 ConfigType) for (i=0; ierror=====dwRegRead: %x, WriteData: %x \n", dwRegRead, WriteData[i]); + RT_TRACE(COMP_ERR, "====>error=====dwRegRead: %x, WriteData: %x\n", dwRegRead, WriteData[i]); ret = RT_STATUS_FAILURE; break; } @@ -1416,14 +1416,14 @@ void rtl8192_phy_getTxPower(struct net_device* dev) priv->DefaultInitialGain[1] = read_nic_byte(priv, rOFDM0_XBAGCCore1); priv->DefaultInitialGain[2] = read_nic_byte(priv, rOFDM0_XCAGCCore1); priv->DefaultInitialGain[3] = read_nic_byte(priv, rOFDM0_XDAGCCore1); - RT_TRACE(COMP_INIT, "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x) \n", + RT_TRACE(COMP_INIT, "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n", priv->DefaultInitialGain[0], priv->DefaultInitialGain[1], priv->DefaultInitialGain[2], priv->DefaultInitialGain[3]); // read framesync priv->framesync = read_nic_byte(priv, rOFDM0_RxDetector3); priv->framesyncC34 = read_nic_dword(priv, rOFDM0_RxDetector2); - RT_TRACE(COMP_INIT, "Default framesync (0x%x) = 0x%x \n", + RT_TRACE(COMP_INIT, "Default framesync (0x%x) = 0x%x\n", rOFDM0_RxDetector3, priv->framesync); // read SIFS (save the value read fome MACPHY_REG.txt) priv->SifsTime = read_nic_word(priv, SIFS); @@ -1888,20 +1888,20 @@ u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel) case WIRELESS_MODE_A: case WIRELESS_MODE_N_5G: if (channel<=14){ - RT_TRACE(COMP_ERR, "WIRELESS_MODE_A but channel<=14"); + RT_TRACE(COMP_ERR, "WIRELESS_MODE_A but channel<=14\n"); return false; } break; case WIRELESS_MODE_B: if (channel>14){ - RT_TRACE(COMP_ERR, "WIRELESS_MODE_B but channel>14"); + RT_TRACE(COMP_ERR, "WIRELESS_MODE_B but channel>14\n"); return false; } break; case WIRELESS_MODE_G: case WIRELESS_MODE_N_24G: if (channel>14){ - RT_TRACE(COMP_ERR, "WIRELESS_MODE_G but channel>14"); + RT_TRACE(COMP_ERR, "WIRELESS_MODE_G but channel>14\n"); return false; } break; @@ -2141,7 +2141,7 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) atomic_dec(&(priv->ieee80211->atm_swbw)); priv->SetBWModeInProgress= false; - RT_TRACE(COMP_SWBW, "<==SetBWMode819xUsb()"); + RT_TRACE(COMP_SWBW, "<==SetBWMode819xUsb()\n"); } /****************************************************************************** @@ -2246,7 +2246,7 @@ void InitialGain819xPci(struct net_device *dev, u8 Operation) rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // FW DIG ON break; default: - RT_TRACE(COMP_SCAN, "Unknown IG Operation. \n"); + RT_TRACE(COMP_SCAN, "Unknown IG Operation.\n"); break; } } -- cgit v1.2.3 From ae9f66da3d7e2f4ffa1bb6b07e62cddcb7614fa6 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Mon, 21 Feb 2011 00:05:19 +0900 Subject: staging: rtl8192e: Remove struct member irq_mask Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 1 - drivers/staging/rtl8192e/r8192E_core.c | 14 ++++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 03306869620c..220f2b11424e 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -810,7 +810,6 @@ typedef struct r8192_priv struct mutex mutex; spinlock_t ps_lock; - u32 irq_mask; short chan; short sens; /* RX stuff */ diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 9a88f49d4fff..8f68ac07b567 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -617,7 +617,14 @@ static void tx_timeout(struct net_device *dev) static void rtl8192_irq_enable(struct net_device *dev) { struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - write_nic_dword(priv, INTA_MASK, priv->irq_mask); + u32 mask; + + mask = IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK | + IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK | + IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | IMR_RDU | IMR_RXFOVW | + IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER; + + write_nic_dword(priv, INTA_MASK, mask); } static void rtl8192_irq_disable(struct net_device *dev) @@ -2042,11 +2049,6 @@ static void rtl8192_init_priv_variable(struct net_device* dev) RCR_AAP | ((u32)7<irq_mask = (u32)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK | - IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK | - IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | IMR_RDU | IMR_RXFOVW | - IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER); - priv->pFirmware = vzalloc(sizeof(rt_firmware)); /* rx related queue */ -- cgit v1.2.3 From 81b504b81437457614ce44ce0dac48038d35f859 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 23 Feb 2011 09:06:49 +0000 Subject: atl1[ce]: fix sparse warnings The dmaw_block is an enum and max_pay_load is u32. Therefore sparse gives warning about comparison of unsigned and signed value. Resolve by using min_t to force cast. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/atl1c/atl1c_main.c | 4 ++-- drivers/net/atl1e/atl1e_main.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index e60595f0247c..7d9d5067a65c 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -1102,10 +1102,10 @@ static void atl1c_configure_tx(struct atl1c_adapter *adapter) AT_READ_REG(hw, REG_DEVICE_CTRL, &dev_ctrl_data); max_pay_load = (dev_ctrl_data >> DEVICE_CTRL_MAX_PAYLOAD_SHIFT) & DEVICE_CTRL_MAX_PAYLOAD_MASK; - hw->dmaw_block = min(max_pay_load, hw->dmaw_block); + hw->dmaw_block = min_t(u32, max_pay_load, hw->dmaw_block); max_pay_load = (dev_ctrl_data >> DEVICE_CTRL_MAX_RREQ_SZ_SHIFT) & DEVICE_CTRL_MAX_RREQ_SZ_MASK; - hw->dmar_block = min(max_pay_load, hw->dmar_block); + hw->dmar_block = min_t(u32, max_pay_load, hw->dmar_block); txq_ctrl_data = (hw->tpd_burst & TXQ_NUM_TPD_BURST_MASK) << TXQ_NUM_TPD_BURST_SHIFT; diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index bf7500ccd73f..21f501184023 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -932,11 +932,11 @@ static inline void atl1e_configure_tx(struct atl1e_adapter *adapter) max_pay_load = ((dev_ctrl_data >> DEVICE_CTRL_MAX_PAYLOAD_SHIFT)) & DEVICE_CTRL_MAX_PAYLOAD_MASK; - hw->dmaw_block = min(max_pay_load, hw->dmaw_block); + hw->dmaw_block = min_t(u32, max_pay_load, hw->dmaw_block); max_pay_load = ((dev_ctrl_data >> DEVICE_CTRL_MAX_RREQ_SZ_SHIFT)) & DEVICE_CTRL_MAX_RREQ_SZ_MASK; - hw->dmar_block = min(max_pay_load, hw->dmar_block); + hw->dmar_block = min_t(u32, max_pay_load, hw->dmar_block); if (hw->nic_type != athr_l2e_revB) AT_WRITE_REGW(hw, REG_TXQ_CTRL + 2, -- cgit v1.2.3 From ecc1058aecd986b9f00ba0b4b6ff3681dfb3ab47 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 23 Feb 2011 14:12:25 -0800 Subject: Revert "staging: iio: ak8975: add platform data." This reverts commit f2f1794835f1d8900d2b15d114c54e70c849809b. It should not be putting code into the include/input/ directory, and lots of other people have complained about it. Cc: Tony SIM Cc: Andrew Chew Cc: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/magnetometer/ak8975.c | 8 +------- include/linux/input/ak8975.h | 20 -------------------- 2 files changed, 1 insertion(+), 27 deletions(-) delete mode 100644 include/linux/input/ak8975.h (limited to 'drivers') diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c index 80c0f4137076..420f206cf517 100644 --- a/drivers/staging/iio/magnetometer/ak8975.c +++ b/drivers/staging/iio/magnetometer/ak8975.c @@ -29,7 +29,6 @@ #include #include -#include #include "../iio.h" #include "magnet.h" @@ -436,7 +435,6 @@ static int ak8975_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct ak8975_data *data; - struct ak8975_platform_data *pdata; int err; /* Allocate our device context. */ @@ -454,11 +452,7 @@ static int ak8975_probe(struct i2c_client *client, /* Grab and set up the supplied GPIO. */ data->eoc_irq = client->irq; - pdata = client->dev.platform_data; - if (pdata) - data->eoc_gpio = pdata->gpio; - else - data->eoc_gpio = irq_to_gpio(client->irq); + data->eoc_gpio = irq_to_gpio(client->irq); if (!data->eoc_gpio) { dev_err(&client->dev, "failed, no valid GPIO\n"); diff --git a/include/linux/input/ak8975.h b/include/linux/input/ak8975.h deleted file mode 100644 index 25d41eb10c3e..000000000000 --- a/include/linux/input/ak8975.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * ak8975 platform support - * - * Copyright (C) 2010 Renesas Solutions Corp. - * - * Author: Tony SIM - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _AK8975_H -#define _AK8975_H - -struct ak8975_platform_data { - int gpio; -}; - -#endif -- cgit v1.2.3 From e03da5e2b77dee7d0535c036a09e9f613dce7c48 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 21 Feb 2011 13:23:25 +0200 Subject: staging/easycap: fix style issues in easycap_usb_probe function fix some code styles and drop too verbose printouts and non relevant code Cc: Mike Thomas Signed-off-by: Tomas Winkler Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_main.c | 104 +++++++++------------------------ 1 file changed, 29 insertions(+), 75 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index e306357a2e5f..b7302785de45 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -3153,7 +3153,6 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, struct usb_host_interface *pusb_host_interface; struct usb_endpoint_descriptor *pepd; struct usb_interface_descriptor *pusb_interface_descriptor; - struct usb_interface_assoc_descriptor *pusb_interface_assoc_descriptor; struct urb *purb; struct easycap *peasycap; int ndong; @@ -3212,55 +3211,14 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, bInterfaceClass = pusb_interface_descriptor->bInterfaceClass; bInterfaceSubClass = pusb_interface_descriptor->bInterfaceSubClass; - JOT(4, "intf[%i]: pusb_interface->num_altsetting=%i\n", - bInterfaceNumber, pusb_interface->num_altsetting); - JOT(4, "intf[%i]: pusb_interface->cur_altsetting - " - "pusb_interface->altsetting=%li\n", bInterfaceNumber, - (long int)(pusb_interface->cur_altsetting - - pusb_interface->altsetting)); - switch (bInterfaceClass) { - case USB_CLASS_AUDIO: { - JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_AUDIO\n", - bInterfaceNumber, bInterfaceClass); break; - } - case USB_CLASS_VIDEO: { - JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VIDEO\n", - bInterfaceNumber, bInterfaceClass); break; - } - case USB_CLASS_VENDOR_SPEC: { - JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VENDOR_SPEC\n", - bInterfaceNumber, bInterfaceClass); break; - } - default: - break; - } - switch (bInterfaceSubClass) { - case 0x01: { - JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOCONTROL\n", - bInterfaceNumber, bInterfaceSubClass); break; - } - case 0x02: { - JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOSTREAMING\n", - bInterfaceNumber, bInterfaceSubClass); break; - } - case 0x03: { - JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=MIDISTREAMING\n", - bInterfaceNumber, bInterfaceSubClass); break; - } - default: - break; - } -/*---------------------------------------------------------------------------*/ - pusb_interface_assoc_descriptor = pusb_interface->intf_assoc; - if (NULL != pusb_interface_assoc_descriptor) { - JOT(4, "intf[%i]: bFirstInterface=0x%02X bInterfaceCount=0x%02X\n", - bInterfaceNumber, - pusb_interface_assoc_descriptor->bFirstInterface, - pusb_interface_assoc_descriptor->bInterfaceCount); - } else { - JOT(4, "intf[%i]: pusb_interface_assoc_descriptor is NULL\n", - bInterfaceNumber); - } + JOT(4, "intf[%i]: num_altsetting=%i\n", + bInterfaceNumber, pusb_interface->num_altsetting); + JOT(4, "intf[%i]: cur_altsetting - altsetting=%li\n", + bInterfaceNumber, + (long int)(pusb_interface->cur_altsetting - + pusb_interface->altsetting)); + JOT(4, "intf[%i]: bInterfaceClass=0x%02X bInterfaceSubClass=0x%02X\n", + bInterfaceNumber, bInterfaceClass, bInterfaceSubClass); /*---------------------------------------------------------------------------*/ /* * A NEW struct easycap IS ALWAYS ALLOCATED WHEN INTERFACE 0 IS PROBED. @@ -3278,7 +3236,6 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, SAY("ERROR: Could not allocate peasycap\n"); return -ENOMEM; } - SAM("allocated %p=peasycap\n", peasycap); /*---------------------------------------------------------------------------*/ /* * PERFORM URGENT INTIALIZATIONS ... @@ -3458,12 +3415,12 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, peasycap->inputset[k].format_offset = i; break; } - peasycap_format++; - i++; + peasycap_format++; + i++; } if (1 != m) { SAM("MISTAKE: easycap.inputset[].format_offset unpopulated\n"); - return -ENOENT; + return -ENOENT; } i = 0; @@ -3489,6 +3446,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, } i++; } + if (4 != m) { SAM("MISTAKE: easycap.inputset[].brightness,... " "underpopulated\n"); @@ -3623,8 +3581,8 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, INTbEndpointAddress = 0; if (0 == pusb_interface_descriptor->bNumEndpoints) - JOM(4, "intf[%i]alt[%i] has no endpoints\n", - bInterfaceNumber, i); + JOM(4, "intf[%i]alt[%i] has no endpoints\n", + bInterfaceNumber, i); /*---------------------------------------------------------------------------*/ for (j = 0; j < pusb_interface_descriptor->bNumEndpoints; j++) { pepd = &(pusb_host_interface->endpoint[j].desc); @@ -3660,9 +3618,8 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, SAM("...... continuing\n"); isin = 0; } - if ((pepd->bmAttributes & - USB_ENDPOINT_XFERTYPE_MASK) == - USB_ENDPOINT_XFER_ISOC) { + if ((pepd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_ISOC) { JOM(4, "intf[%i]alt[%i]end[%i] is an ISOC endpoint\n", bInterfaceNumber, i, j); if (isin) { @@ -3812,7 +3769,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, */ /*---------------------------------------------------------------------------*/ JOM(4, "initialization begins for interface %i\n", - pusb_interface_descriptor->bInterfaceNumber); + pusb_interface_descriptor->bInterfaceNumber); switch (bInterfaceNumber) { /*---------------------------------------------------------------------------*/ /* @@ -3840,19 +3797,17 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, peasycap->video_endpointnumber = okepn[isokalt - 1]; JOM(4, "%i=video_endpointnumber\n", peasycap->video_endpointnumber); maxpacketsize = okmps[isokalt - 1]; - if (USB_2_0_MAXPACKETSIZE > maxpacketsize) { - peasycap->video_isoc_maxframesize = maxpacketsize; - } else { - peasycap->video_isoc_maxframesize = - USB_2_0_MAXPACKETSIZE; - } - JOM(4, "%i=video_isoc_maxframesize\n", - peasycap->video_isoc_maxframesize); + + peasycap->video_isoc_maxframesize = + min(maxpacketsize, USB_2_0_MAXPACKETSIZE); if (0 >= peasycap->video_isoc_maxframesize) { SAM("ERROR: bad video_isoc_maxframesize\n"); SAM(" possibly because port is USB 1.1\n"); return -ENOENT; } + JOM(4, "%i=video_isoc_maxframesize\n", + peasycap->video_isoc_maxframesize); + peasycap->video_isoc_framesperdesc = VIDEO_ISOC_FRAMESPERDESC; JOM(4, "%i=video_isoc_framesperdesc\n", peasycap->video_isoc_framesperdesc); @@ -4354,16 +4309,16 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, SAM("ERROR: usb_alloc_urb returned NULL for buffer " "%i\n", k); return -ENOMEM; - } else - peasycap->allocation_audio_urb += 1 ; + } + peasycap->allocation_audio_urb += 1 ; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); if (NULL == pdata_urb) { SAM("ERROR: Could not allocate struct data_urb.\n"); return -ENOMEM; - } else - peasycap->allocation_audio_struct += - sizeof(struct data_urb); + } + peasycap->allocation_audio_struct += + sizeof(struct data_urb); pdata_urb->purb = purb; pdata_urb->isbuf = k; @@ -4487,8 +4442,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, return -EINVAL; } } - SAM("ends successfully for interface %i\n", - pusb_interface_descriptor->bInterfaceNumber); + SAM("ends successfully for interface %i\n", bInterfaceNumber); return 0; } /*****************************************************************************/ -- cgit v1.2.3 From b4a5916e6bdbd5585a961179799a59871d8722cc Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 21 Feb 2011 13:23:26 +0200 Subject: staging/easycap: revamp inputset population code make inputset population to be more compact and readable Cc: Mike Thomas Signed-off-by: Tomas Winkler Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_main.c | 105 ++++++++++++--------------------- 1 file changed, 39 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index b7302785de45..a75dc9305eb5 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -3177,6 +3177,8 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, u16 mask; s32 value; struct easycap_format *peasycap_format; + int fmtidx; + struct inputset *inputset; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #ifdef EASYCAP_IS_VIDEODEV_CLIENT struct v4l2_device *pv4l2_device; @@ -3345,116 +3347,87 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, * ... AND POPULATE easycap.inputset[] */ /*---------------------------------------------------------------------------*/ + /* FIXME: maybe we just use memset 0 */ + inputset = peasycap->inputset; for (k = 0; k < INPUT_MANY; k++) { - peasycap->inputset[k].input_ok = 0; - peasycap->inputset[k].standard_offset_ok = 0; - peasycap->inputset[k].format_offset_ok = 0; - peasycap->inputset[k].brightness_ok = 0; - peasycap->inputset[k].contrast_ok = 0; - peasycap->inputset[k].saturation_ok = 0; - peasycap->inputset[k].hue_ok = 0; + inputset[k].input_ok = 0; + inputset[k].standard_offset_ok = 0; + inputset[k].format_offset_ok = 0; + inputset[k].brightness_ok = 0; + inputset[k].contrast_ok = 0; + inputset[k].saturation_ok = 0; + inputset[k].hue_ok = 0; } - if (true == peasycap->ntsc) { - i = 0; - m = 0; - mask = 0; - while (0xFFFF != easycap_standard[i].mask) { - if (NTSC_M == easycap_standard[i]. - v4l2_standard.index) { - m++; - for (k = 0; k < INPUT_MANY; k++) { - peasycap->inputset[k]. - standard_offset = i; - } - mask = easycap_standard[i].mask; - } - i++; - } - } else { - i = 0; - m = 0; - mask = 0; - while (0xFFFF != easycap_standard[i].mask) { - if (PAL_BGHIN == easycap_standard[i]. - v4l2_standard.index) { - m++; - for (k = 0; k < INPUT_MANY; k++) { - peasycap->inputset[k]. - standard_offset = i; - } + + fmtidx = peasycap->ntsc ? NTSC_M : PAL_BGHIN; + m = 0; + mask = 0; + for (i = 0; 0xFFFF != easycap_standard[i].mask; i++) { + if (fmtidx == easycap_standard[i].v4l2_standard.index) { + m++; + for (k = 0; k < INPUT_MANY; k++) + inputset[k].standard_offset = i; + mask = easycap_standard[i].mask; - } - i++; } } if (1 != m) { - SAM("MISTAKE: easycap.inputset[].standard_offset " - "unpopulated, %i=m\n", m); + SAM("ERROR: " + "inputset->standard_offset unpopulated, %i=m\n", m); return -ENOENT; } peasycap_format = &easycap_format[0]; - i = 0; m = 0; - while (0 != peasycap_format->v4l2_format.fmt.pix.width) { + for (i = 0; peasycap_format->v4l2_format.fmt.pix.width; i++) { + struct v4l2_pix_format *pix = + &peasycap_format->v4l2_format.fmt.pix; if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && - (peasycap_format-> - v4l2_format.fmt.pix.field == - V4L2_FIELD_NONE) && - (peasycap_format-> - v4l2_format.fmt.pix.pixelformat == - V4L2_PIX_FMT_UYVY) && - (peasycap_format-> - v4l2_format.fmt.pix.width == - 640) && - (peasycap_format-> - v4l2_format.fmt.pix.height == 480)) { + pix->field == V4L2_FIELD_NONE && + pix->pixelformat == V4L2_PIX_FMT_UYVY && + pix->width == 640 && pix->height == 480) { m++; for (k = 0; k < INPUT_MANY; k++) - peasycap->inputset[k].format_offset = i; + inputset[k].format_offset = i; break; } peasycap_format++; - i++; } if (1 != m) { - SAM("MISTAKE: easycap.inputset[].format_offset unpopulated\n"); + SAM("ERROR: inputset[]->format_offset unpopulated\n"); return -ENOENT; } - i = 0; m = 0; - while (0xFFFFFFFF != easycap_control[i].id) { + for (i = 0; 0xFFFFFFFF != easycap_control[i].id; i++) { value = easycap_control[i].default_value; if (V4L2_CID_BRIGHTNESS == easycap_control[i].id) { m++; for (k = 0; k < INPUT_MANY; k++) - peasycap->inputset[k].brightness = value; + inputset[k].brightness = value; } else if (V4L2_CID_CONTRAST == easycap_control[i].id) { m++; for (k = 0; k < INPUT_MANY; k++) - peasycap->inputset[k].contrast = value; + inputset[k].contrast = value; } else if (V4L2_CID_SATURATION == easycap_control[i].id) { m++; for (k = 0; k < INPUT_MANY; k++) - peasycap->inputset[k].saturation = value; + inputset[k].saturation = value; } else if (V4L2_CID_HUE == easycap_control[i].id) { m++; for (k = 0; k < INPUT_MANY; k++) - peasycap->inputset[k].hue = value; + inputset[k].hue = value; } - i++; } if (4 != m) { - SAM("MISTAKE: easycap.inputset[].brightness,... " - "underpopulated\n"); + SAM("ERROR: inputset[]->brightness underpopulated\n"); return -ENOENT; } for (k = 0; k < INPUT_MANY; k++) - peasycap->inputset[k].input = k; - JOM(4, "populated easycap.inputset[]\n"); + inputset[k].input = k; + JOM(4, "populated inputset[]\n"); JOM(4, "finished initialization\n"); } else { /*---------------------------------------------------------------------------*/ -- cgit v1.2.3 From dfcce7bf0913cc81d57a41d8da3175b201ec1664 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 21 Feb 2011 13:23:27 +0200 Subject: staging/easycap: easycap_usb_probe: more indentation cleanups Cc: Mike Thomas Signed-off-by: Tomas Winkler Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_main.c | 38 ++++++++++++++-------------------- 1 file changed, 16 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index a75dc9305eb5..ea8a2e0e184d 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -3258,7 +3258,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, init_waitqueue_head(&peasycap->wq_trigger); if (mutex_lock_interruptible(&mutex_dongle)) { - SAY("ERROR: cannot down mutex_dongle\n"); + SAY("ERROR: cannot down mutex_dongle\n"); return -ERESTARTSYS; } else { /*---------------------------------------------------------------------------*/ @@ -3476,10 +3476,10 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, container_of(pv4l2_device, struct easycap, v4l2_device); } #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -} + } /*---------------------------------------------------------------------------*/ if ((USB_CLASS_VIDEO == bInterfaceClass) || - (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) { + (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) { if (-1 == peasycap->video_interface) { peasycap->video_interface = bInterfaceNumber; JOM(4, "setting peasycap->video_interface=%i\n", @@ -3494,7 +3494,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, } } } else if ((USB_CLASS_AUDIO == bInterfaceClass) && - (0x02 == bInterfaceSubClass)) { + (0x02 == bInterfaceSubClass)) { if (-1 == peasycap->audio_interface) { peasycap->audio_interface = bInterfaceNumber; JOM(4, "setting peasycap->audio_interface=%i\n", @@ -4085,7 +4085,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ break; -} + } /*--------------------------------------------------------------------------*/ /* * INTERFACE 1 IS THE AUDIO CONTROL INTERFACE @@ -4332,7 +4332,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, JOM(4, " purb->iso_frame_desc[j].length = %i;\n", peasycap->audio_isoc_maxframesize); JOM(4, " }\n"); - } + } purb->interval = 1; purb->dev = peasycap->pusb_device; @@ -4377,10 +4377,10 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, err("easycap_alsa_probe() returned %i\n", rc); return -ENODEV; } else { - JOM(8, "kref_get() with %i=peasycap->kref.refcount.counter\n", - (int)peasycap->kref.refcount.counter); + JOM(8, "kref_get() with %i=kref.refcount.counter\n", + peasycap->kref.refcount.counter); kref_get(&peasycap->kref); - (peasycap->registered_audio)++; + peasycap->registered_audio++; } #else /* CONFIG_EASYCAP_OSS */ @@ -4390,30 +4390,24 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, usb_set_intfdata(pusb_interface, NULL); return -ENODEV; } else { - JOM(8, "kref_get() with %i=peasycap->kref.refcount.counter\n", - (int)peasycap->kref.refcount.counter); + JOM(8, "kref_get() with %i=kref.refcount.counter\n", + peasycap->kref.refcount.counter); kref_get(&peasycap->kref); - (peasycap->registered_audio)++; + peasycap->registered_audio++; } -/*---------------------------------------------------------------------------*/ -/* - * LET THE USER KNOW WHAT NODE THE AUDIO DEVICE IS ATTACHED TO. - */ -/*---------------------------------------------------------------------------*/ SAM("easyoss attached to minor #%d\n", pusb_interface->minor); #endif /* CONFIG_EASYCAP_OSS */ break; -} + } /*---------------------------------------------------------------------------*/ /* * INTERFACES OTHER THAN 0, 1 AND 2 ARE UNEXPECTED */ /*---------------------------------------------------------------------------*/ - default: { - JOM(4, "ERROR: unexpected interface %i\n", bInterfaceNumber); - return -EINVAL; - } + default: + JOM(4, "ERROR: unexpected interface %i\n", bInterfaceNumber); + return -EINVAL; } SAM("ends successfully for interface %i\n", bInterfaceNumber); return 0; -- cgit v1.2.3 From fc3cc2caa07568de92cc84780b89b5cf9fbf28b7 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 21 Feb 2011 16:09:55 +0200 Subject: staging/easycap: use USB_SUBCLASS_AUDIOSTREAMING instead of 0x02 use USB_SUBCLASS_AUDIOSTREAMING constant from usb/audio.h instead of 0x02 Cc: Mike Thomas Cc: Dan Carpenter Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index ea8a2e0e184d..fc1a1781227e 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -29,6 +29,7 @@ /*****************************************************************************/ #include "easycap.h" +#include MODULE_LICENSE("GPL"); @@ -3494,7 +3495,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, } } } else if ((USB_CLASS_AUDIO == bInterfaceClass) && - (0x02 == bInterfaceSubClass)) { + (USB_SUBCLASS_AUDIOSTREAMING == bInterfaceSubClass)) { if (-1 == peasycap->audio_interface) { peasycap->audio_interface = bInterfaceNumber; JOM(4, "setting peasycap->audio_interface=%i\n", @@ -3654,7 +3655,8 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, break; } case USB_CLASS_AUDIO: { - if (0x02 != bInterfaceSubClass) + if (bInterfaceSubClass != + USB_SUBCLASS_AUDIOSTREAMING) break; if (!peasycap) { SAM("MISTAKE: " -- cgit v1.2.3 From cfd6ea0b731d048037ba00b8dd3777a91b9675e0 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 21 Feb 2011 10:09:05 +0100 Subject: Staging: xgifb: Removes dead code xgifb staging driver has code that dependens on XGIfb_accel != 0. But as Dan Carpenter noticed, XGIfb_accel value is always 0 in current driver. So there is code that never gets executed. This patch removes this dead code. Signed-off-by: Javier Martinez Canillas Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_accel.c | 57 +++------------------------------------ 1 file changed, 3 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_accel.c b/drivers/staging/xgifb/XGI_accel.c index 79549742cff1..7f485fea391a 100644 --- a/drivers/staging/xgifb/XGI_accel.c +++ b/drivers/staging/xgifb/XGI_accel.c @@ -216,73 +216,22 @@ void XGIfb_syncaccel(void) int fbcon_XGI_sync(struct fb_info *info) { - if(!XGIfb_accel) return 0; - CRITFLAGS - - XGI310Sync(); - - CRITEND - return 0; + return 0; } void fbcon_XGI_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { - int col=0; - CRITFLAGS - - - if(!rect->width || !rect->height) - return; + if (!rect->width || !rect->height) + return; - if(!XGIfb_accel) { cfb_fillrect(info, rect); return; - } - - switch(info->var.bits_per_pixel) { - case 8: col = rect->color; - break; - case 16: col = ((u32 *)(info->pseudo_palette))[rect->color]; - break; - case 32: col = ((u32 *)(info->pseudo_palette))[rect->color]; - break; - } - - - CRITBEGIN - XGI310SetupForSolidFill(col, myrops[rect->rop], 0); - XGI310SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height); - CRITEND - XGI310Sync(); - - } void fbcon_XGI_copyarea(struct fb_info *info, const struct fb_copyarea *area) { - int xdir, ydir; - CRITFLAGS - - - if(!XGIfb_accel) { cfb_copyarea(info, area); return; - } - - if(!area->width || !area->height) - return; - - if(area->sx < area->dx) xdir = 0; - else xdir = 1; - if(area->sy < area->dy) ydir = 0; - else ydir = 1; - - CRITBEGIN - XGI310SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1); - XGI310SubsequentScreenToScreenCopy(area->sx, area->sy, area->dx, area->dy, area->width, area->height); - CRITEND - XGI310Sync(); - } -- cgit v1.2.3 From 898fcb98066cfcd6051d61638e7e3a305de34c85 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 21 Feb 2011 10:09:06 +0100 Subject: Staging: xgifb: Remove unused functions Earlier patch removed code that never got executed because it depended on XGIfb_accel variable value to de distinct than 0. But this variable is always 0 in current driver. That dead code used a set of functions that not remains unused. This patch removes these unused functions. Signed-off-by: Javier Martinez Canillas Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_accel.c | 96 --------------------------------------- 1 file changed, 96 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_accel.c b/drivers/staging/xgifb/XGI_accel.c index 7f485fea391a..e6241fed04fa 100644 --- a/drivers/staging/xgifb/XGI_accel.c +++ b/drivers/staging/xgifb/XGI_accel.c @@ -99,102 +99,6 @@ XGI310Sync(void) XGI310Idle } -/* 310/325 series ------------------------------------------------ */ - -static void -XGI310SetupForScreenToScreenCopy(int xdir, int ydir, int rop, - unsigned int planemask, int trans_color) -{ - XGI310SetupDSTColorDepth(xgi_video_info.DstColor); - XGI310SetupSRCPitch(xgi_video_info.video_linelength) - XGI310SetupDSTRect(xgi_video_info.video_linelength, 0xFFF) - if (trans_color != -1) { - XGI310SetupROP(0x0A) - XGI310SetupSRCTrans(trans_color) - XGI310SetupCMDFlag(TRANSPARENT_BITBLT) - } else { - XGI310SetupROP(XGIALUConv[rop]) - /* Set command - not needed, both 0 */ - /* XGISetupCMDFlag(BITBLT | SRCVIDEO) */ - } - XGI310SetupCMDFlag(xgi_video_info.XGI310_AccelDepth) - /* TW: The 310/325 series is smart enough to know the direction */ -} - -static void -XGI310SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y, - int width, int height) -{ - long srcbase, dstbase; - int mymin, mymax; - - srcbase = dstbase = 0; - mymin = min(src_y, dst_y); - mymax = max(src_y, dst_y); - - /* Although the chip knows the direction to use - * if the source and destination areas overlap, - * that logic fails if we fiddle with the bitmap - * addresses. Therefore, we check if the source - * and destination blitting areas overlap and - * adapt the bitmap addresses synchronously - * if the coordinates exceed the valid range. - * The the areas do not overlap, we do our - * normal check. - */ - if((mymax - mymin) < height) { - if((src_y >= 2048) || (dst_y >= 2048)) { - srcbase = xgi_video_info.video_linelength * mymin; - dstbase = xgi_video_info.video_linelength * mymin; - src_y -= mymin; - dst_y -= mymin; - } - } else { - if(src_y >= 2048) { - srcbase = xgi_video_info.video_linelength * src_y; - src_y = 0; - } - if(dst_y >= 2048) { - dstbase = xgi_video_info.video_linelength * dst_y; - dst_y = 0; - } - } - - XGI310SetupSRCBase(srcbase); - XGI310SetupDSTBase(dstbase); - XGI310SetupRect(width, height) - XGI310SetupSRCXY(src_x, src_y) - XGI310SetupDSTXY(dst_x, dst_y) - XGI310DoCMD -} - -static void -XGI310SetupForSolidFill(int color, int rop, unsigned int planemask) -{ - XGI310SetupPATFG(color) - XGI310SetupDSTRect(xgi_video_info.video_linelength, 0xFFF) - XGI310SetupDSTColorDepth(xgi_video_info.DstColor); - XGI310SetupROP(XGIPatALUConv[rop]) - XGI310SetupCMDFlag(PATFG | xgi_video_info.XGI310_AccelDepth) -} - -static void -XGI310SubsequentSolidFillRect(int x, int y, int w, int h) -{ - long dstbase; - - dstbase = 0; - if(y >= 2048) { - dstbase = xgi_video_info.video_linelength * y; - y = 0; - } - XGI310SetupDSTBase(dstbase) - XGI310SetupDSTXY(x,y) - XGI310SetupRect(w,h) - XGI310SetupCMDFlag(BITBLT) - XGI310DoCMD -} - /* --------------------------------------------------------------------- */ /* The exported routines */ -- cgit v1.2.3 From c73d0d55069b94630338bfeeae6d8149770e0451 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 21 Feb 2011 10:09:07 +0100 Subject: Staging: xgifb: Remove unused spinlock conditional compilation logic xgifb staging driver for XG20, XG21, XG40, XG42 frame buffer device has a accelerator engine that never get used (XGIfb_accel is always 0). Also the driver has a set of defines that hides the synchronization mechanism used to access critical sections and a way to disable spinlocks use at compile time. In a earlier patch all the code that depends on the accelerator being active was deleted because it was dead code. Since the only usage of this synchronization defines were in that dead code, this patch removes all the now unused spinlock conditional compilation logic. Signed-off-by: Javier Martinez Canillas Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_accel.c | 3 --- drivers/staging/xgifb/XGI_accel.h | 14 -------------- 2 files changed, 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_accel.c b/drivers/staging/xgifb/XGI_accel.c index e6241fed04fa..7c69e0711a90 100644 --- a/drivers/staging/xgifb/XGI_accel.c +++ b/drivers/staging/xgifb/XGI_accel.c @@ -105,9 +105,6 @@ XGI310Sync(void) int XGIfb_initaccel(void) { -#ifdef XGIFB_USE_SPINLOCKS - spin_lock_init(&xgi_video_info.lockaccel); -#endif return(0); } diff --git a/drivers/staging/xgifb/XGI_accel.h b/drivers/staging/xgifb/XGI_accel.h index 5a0395bef2f2..3087e907121c 100644 --- a/drivers/staging/xgifb/XGI_accel.h +++ b/drivers/staging/xgifb/XGI_accel.h @@ -18,20 +18,6 @@ #ifndef _XGIFB_ACCEL_H #define _XGIFB_ACCEL_H -/* Guard accelerator accesses with spin_lock_irqsave? Works well without. */ -#undef XGIFB_USE_SPINLOCKS - -#ifdef XGIFB_USE_SPINLOCKS -#include -#define CRITBEGIN spin_lock_irqsave(&xgi_video_info.lockaccel), critflags); -#define CRITEND spin_unlock_irqrestore(&xgi_video_info.lockaccel), critflags); -#define CRITFLAGS unsigned long critflags; -#else -#define CRITBEGIN -#define CRITEND -#define CRITFLAGS -#endif - /* Definitions for the XGI engine communication. */ #define PATREGSIZE 384 /* Pattern register size. 384 bytes @ 0x8300 */ -- cgit v1.2.3 From 0089bf1fb1e524fba4f86e98a9af7f03a0a8c932 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 21 Feb 2011 18:16:43 +0100 Subject: Staging: xgifb: Remove all the references to XGIfb_accel xgifb framebuffer driver has an option to use an accelerator engine that never get used (XGIfb_accel is always 0). An earlier patchset remove the code that depends on the accelerator being activated. This patch removes all the references to XGIfb_accel. Signed-off-by: Javier Martinez Canillas Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_accel.h | 1 - drivers/staging/xgifb/XGI_main_26.c | 17 +---------------- 2 files changed, 1 insertion(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_accel.h b/drivers/staging/xgifb/XGI_accel.h index 3087e907121c..6cecdf7ca2e2 100644 --- a/drivers/staging/xgifb/XGI_accel.h +++ b/drivers/staging/xgifb/XGI_accel.h @@ -478,7 +478,6 @@ int fbcon_XGI_sync(struct fb_info *info); extern struct video_info xgi_video_info; -extern int XGIfb_accel; void fbcon_XGI_fillrect(struct fb_info *info, const struct fb_fillrect *rect); void fbcon_XGI_copyarea(struct fb_info *info, const struct fb_copyarea *area); diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 7f821ae20cf2..b52e11f3e4c6 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -43,8 +43,6 @@ #include "XGI_main.h" #include "vb_util.h" -int XGIfb_accel = 0; - #define Index_CR_GPIO_Reg1 0x48 #define Index_CR_GPIO_Reg2 0x49 #define Index_CR_GPIO_Reg3 0x4a @@ -1190,10 +1188,6 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, xgi_video_info.video_linelength = info->var.xres_virtual * (xgi_video_info.video_bpp >> 3); xgi_video_info.accel = 0; - if (XGIfb_accel) { - xgi_video_info.accel = (var->accel_flags - & FB_ACCELF_TEXT) ? -1 : 0; - } switch (xgi_video_info.video_bpp) { case 8: xgi_video_info.DstColor = 0x0000; @@ -2856,8 +2850,6 @@ XGIINITSTATIC int __init XGIfb_setup(char *options) printk(KERN_INFO "XGIfb: Illegal pdc parameter\n"); XGIfb_pdc = 0; } - } else if (!strncmp(this_opt, "noaccel", 7)) { - XGIfb_accel = 0; } else if (!strncmp(this_opt, "noypan", 6)) { XGIfb_ypan = 0; } else if (!strncmp(this_opt, "userom:", 7)) { @@ -2872,11 +2864,9 @@ XGIINITSTATIC int __init XGIfb_setup(char *options) /* TW: Acceleration only with MMIO mode */ if ((XGIfb_queuemode != -1) && (XGIfb_queuemode != MMIO_CMD)) { XGIfb_ypan = 0; - XGIfb_accel = 0; } /* TW: Panning only with acceleration */ - if (XGIfb_accel == 0) - XGIfb_ypan = 0; + XGIfb_ypan = 0; } printk("\nxgifb: outa xgifb_setup 3450"); @@ -3370,11 +3360,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, } xgi_video_info.accel = 0; - if (XGIfb_accel) { - xgi_video_info.accel = -1; - default_var.accel_flags |= FB_ACCELF_TEXT; - XGIfb_initaccel(); - } fb_info->flags = FBINFO_FLAG_DEFAULT; fb_info->var = default_var; -- cgit v1.2.3 From 522f1f63cfca29a14ff5efacac9c2cce69d8508b Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 21 Feb 2011 18:16:44 +0100 Subject: Staging: xgifb: Remove unused spinlock in struct video_info xgifb framebuffer driver had an option to use an accelerator engine that never got used (XGIfb_accel was always 0). An earlier patchset removed the code relevant to the accelerator. Since this spinlock was used only for that code, it can be deleted as well. Signed-off-by: Javier Martinez Canillas Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGIfb.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGIfb.h b/drivers/staging/xgifb/XGIfb.h index bb4640abda98..b6715ba9b681 100644 --- a/drivers/staging/xgifb/XGIfb.h +++ b/drivers/staging/xgifb/XGIfb.h @@ -1,6 +1,5 @@ #ifndef _LINUX_XGIFB #define _LINUX_XGIFB -#include #include #include @@ -190,8 +189,6 @@ struct video_info{ unsigned long XGI310_AccelDepth; unsigned long CommandReg; - spinlock_t lockaccel; - unsigned int pcibus; unsigned int pcislot; unsigned int pcifunc; -- cgit v1.2.3 From da1545c0f2e5be5702ca37ad6fcddb3fa0d5094e Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 21 Feb 2011 18:44:35 +0100 Subject: Staging: xgifb: Remove unused function fbcon_XGI_sync Due a cleanup in earlier patches, the function fbcon_XGI_sync now does nothing so it has to be removed. This patches removes the unused function. Signed-off-by: Javier Martinez Canillas Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_accel.c | 5 ----- drivers/staging/xgifb/XGI_main.h | 1 - drivers/staging/xgifb/XGI_main_26.c | 1 - 3 files changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_accel.c b/drivers/staging/xgifb/XGI_accel.c index 7c69e0711a90..905b34ae5e9b 100644 --- a/drivers/staging/xgifb/XGI_accel.c +++ b/drivers/staging/xgifb/XGI_accel.c @@ -115,11 +115,6 @@ void XGIfb_syncaccel(void) } -int fbcon_XGI_sync(struct fb_info *info) -{ - return 0; -} - void fbcon_XGI_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { if (!rect->width || !rect->height) diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index e8e2bfe75573..1b454148cb78 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -797,7 +797,6 @@ extern void fbcon_XGI_fillrect(struct fb_info *info, const struct fb_fillrect *rect); extern void fbcon_XGI_copyarea(struct fb_info *info, const struct fb_copyarea *area); -extern int fbcon_XGI_sync(struct fb_info *info); static int XGIfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg); diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index b52e11f3e4c6..c77ac4ad5094 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1741,7 +1741,6 @@ static struct fb_ops XGIfb_ops = { .fb_fillrect = fbcon_XGI_fillrect, .fb_copyarea = fbcon_XGI_copyarea, .fb_imageblit = cfb_imageblit, - .fb_sync = fbcon_XGI_sync, .fb_ioctl = XGIfb_ioctl, /* .fb_mmap = XGIfb_mmap, */ }; -- cgit v1.2.3 From 7bc5e8374f22c46e6326ab219c45e75867dc9acd Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 22 Feb 2011 00:14:25 +0200 Subject: staging: xgifb: delete dead code for skipping the video memory sizing Delete dead code for skipping the video memory sizing. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 1 - drivers/staging/xgifb/vb_init.c | 23 +++-------------------- drivers/staging/xgifb/vgatypes.h | 2 -- 3 files changed, 3 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index c77ac4ad5094..9fdfc543a92a 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -3014,7 +3014,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, printk(KERN_INFO "XGIfb: Video ROM usage disabled\n"); } XGIhw_ext.pjCustomizedROMImage = NULL; - XGIhw_ext.bSkipDramSizing = 0; XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space; /* XGIhw_ext.pQueryNorthBridgeSpace = &XGIfb_query_north_bridge_space; */ strcpy(XGIhw_ext.szVBIOSVer, "0.84"); diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 8d591828cee5..9a5aa6c9f929 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -120,8 +120,6 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) /* unsigned long j, k; */ - struct XGI_DSReg *pSR; - unsigned long Temp; pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase; @@ -427,24 +425,9 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) XGINew_SetDRAMDefaultRegister340(HwDeviceExtension, pVBInfo->P3d4, pVBInfo); - if (HwDeviceExtension->bSkipDramSizing == 1) { - pSR = HwDeviceExtension->pSR; - if (pSR != NULL) { - while (pSR->jIdx != 0xFF) { - XGINew_SetReg1(pVBInfo->P3c4, pSR->jIdx, pSR->jVal); - pSR++; - } - } - /* XGINew_SetDRAMModeRegister340(pVBInfo); */ - } /* SkipDramSizing */ - else { - { - printk("20"); - XGINew_SetDRAMSize_340(HwDeviceExtension, pVBInfo); - } - printk("21"); - - } + printk("20"); + XGINew_SetDRAMSize_340(HwDeviceExtension, pVBInfo); + printk("21"); } /* XG40 */ printk("22"); diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h index df839eeb5efd..92a9ee5b07dd 100644 --- a/drivers/staging/xgifb/vgatypes.h +++ b/drivers/staging/xgifb/vgatypes.h @@ -101,8 +101,6 @@ struct xgi_hw_device_info unsigned char bIntegratedMMEnabled;/* supporting integration MM enable */ - unsigned char bSkipDramSizing; /* True: Skip video memory sizing. */ - unsigned char bSkipSense; unsigned char bIsPowerSaving; /* True: XGIInit() is invoked by power management, -- cgit v1.2.3 From 3f60554cb121b951d250639b01c828cf41aa09da Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 22 Feb 2011 00:14:26 +0200 Subject: staging: xgifb: delete redundant XGIhw_ext fields pSR and pCR fields can be deleted with no changes in the functionality. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 18 ------------------ drivers/staging/xgifb/vgatypes.h | 10 ---------- 2 files changed, 28 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 9fdfc543a92a..5e69728623b7 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -3018,22 +3018,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, /* XGIhw_ext.pQueryNorthBridgeSpace = &XGIfb_query_north_bridge_space; */ strcpy(XGIhw_ext.szVBIOSVer, "0.84"); - XGIhw_ext.pSR = vmalloc(sizeof(struct XGI_DSReg) * SR_BUFFER_SIZE); - if (XGIhw_ext.pSR == NULL) { - printk(KERN_ERR "XGIfb: Fatal error: Allocating SRReg space failed.\n"); - ret = -ENODEV; - goto error; - } - XGIhw_ext.pSR[0].jIdx = XGIhw_ext.pSR[0].jVal = 0xFF; - - XGIhw_ext.pCR = vmalloc(sizeof(struct XGI_DSReg) * CR_BUFFER_SIZE); - if (XGIhw_ext.pCR == NULL) { - printk(KERN_ERR "XGIfb: Fatal error: Allocating CRReg space failed.\n"); - ret = -ENODEV; - goto error; - } - XGIhw_ext.pCR[0].jIdx = XGIhw_ext.pCR[0].jVal = 0xFF; - if (!XGIvga_enabled) { /* Mapping Max FB Size for 315 Init */ XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000); @@ -3403,8 +3387,6 @@ error_0: xgi_video_info.video_size); error: vfree(XGIhw_ext.pjVirtualRomBase); - vfree(XGIhw_ext.pSR); - vfree(XGIhw_ext.pCR); framebuffer_release(fb_info); return ret; } diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h index 92a9ee5b07dd..dacdac3e204c 100644 --- a/drivers/staging/xgifb/vgatypes.h +++ b/drivers/staging/xgifb/vgatypes.h @@ -106,16 +106,6 @@ struct xgi_hw_device_info unsigned char bIsPowerSaving; /* True: XGIInit() is invoked by power management, otherwise by 2nd adapter's initialzation */ - struct XGI_DSReg *pSR; /* restore SR registers in initial function. */ - /* end data :(idx, val) = (FF, FF). */ - /* Note : restore SR registers if */ - /* bSkipDramSizing = 1 */ - - struct XGI_DSReg *pCR; /* restore CR registers in initial function. */ - /* end data :(idx, val) = (FF, FF) */ - /* Note : restore cR registers if */ - /* bSkipDramSizing = 1 */ - unsigned char(*pQueryVGAConfigSpace)(struct xgi_hw_device_info *, unsigned long, unsigned long, unsigned long *); -- cgit v1.2.3 From 193cfca5cc754b2a9b178a37f70fbb78d1731333 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Wed, 23 Feb 2011 04:32:34 +0000 Subject: r6040: fix multicast operations The original code does not work well when the number of mulitcast address to handle is greater than MCAST_MAX. It only enable promiscous mode instead of multicast hash table mode, so the hash table function will not be activated and all multicast frames will be recieved in this condition. This patch fixes the following issues with the r6040 NIC operating in multicast: 1) When the IFF_ALLMULTI flag is set, we should write 0xffff to the NIC hash table registers to make it process multicast traffic. 2) When the number of multicast address to handle is smaller than MCAST_MAX, we should use the NIC multicast registers MID1_{L,M,H}. 3) The hashing of the address was not correct, due to an invalid substraction (15 - (crc & 0x0f)) instead of (crc & 0x0f) and an incorrect crc algorithm (ether_crc_le) instead of (ether_crc). 4) If necessary, we should set HASH_EN flag in MCR0 to enable multicast hash table function. Reported-by: Marc Leclerc Tested-by: Marc Leclerc Signed-off-by: Shawn Lin Signed-off-by: Albert Chen Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/r6040.c | 111 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 27e6f6d43cac..7965ae42eae4 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -69,6 +69,8 @@ /* MAC registers */ #define MCR0 0x00 /* Control register 0 */ +#define MCR0_PROMISC 0x0020 /* Promiscuous mode */ +#define MCR0_HASH_EN 0x0100 /* Enable multicast hash table function */ #define MCR1 0x04 /* Control register 1 */ #define MAC_RST 0x0001 /* Reset the MAC */ #define MBCR 0x08 /* Bus control */ @@ -851,77 +853,92 @@ static void r6040_multicast_list(struct net_device *dev) { struct r6040_private *lp = netdev_priv(dev); void __iomem *ioaddr = lp->base; - u16 *adrp; - u16 reg; unsigned long flags; struct netdev_hw_addr *ha; int i; + u16 *adrp; + u16 hash_table[4] = { 0 }; + + spin_lock_irqsave(&lp->lock, flags); - /* MAC Address */ + /* Keep our MAC Address */ adrp = (u16 *)dev->dev_addr; iowrite16(adrp[0], ioaddr + MID_0L); iowrite16(adrp[1], ioaddr + MID_0M); iowrite16(adrp[2], ioaddr + MID_0H); - /* Promiscous Mode */ - spin_lock_irqsave(&lp->lock, flags); - /* Clear AMCP & PROM bits */ - reg = ioread16(ioaddr) & ~0x0120; - if (dev->flags & IFF_PROMISC) { - reg |= 0x0020; - lp->mcr0 |= 0x0020; - } - /* Too many multicast addresses - * accept all traffic */ - else if ((netdev_mc_count(dev) > MCAST_MAX) || - (dev->flags & IFF_ALLMULTI)) - reg |= 0x0020; + lp->mcr0 = ioread16(ioaddr + MCR0) & ~(MCR0_PROMISC | MCR0_HASH_EN); - iowrite16(reg, ioaddr); - spin_unlock_irqrestore(&lp->lock, flags); + /* Promiscuous mode */ + if (dev->flags & IFF_PROMISC) + lp->mcr0 |= MCR0_PROMISC; - /* Build the hash table */ - if (netdev_mc_count(dev) > MCAST_MAX) { - u16 hash_table[4]; - u32 crc; + /* Enable multicast hash table function to + * receive all multicast packets. */ + else if (dev->flags & IFF_ALLMULTI) { + lp->mcr0 |= MCR0_HASH_EN; - for (i = 0; i < 4; i++) - hash_table[i] = 0; + for (i = 0; i < MCAST_MAX ; i++) { + iowrite16(0, ioaddr + MID_1L + 8 * i); + iowrite16(0, ioaddr + MID_1M + 8 * i); + iowrite16(0, ioaddr + MID_1H + 8 * i); + } + for (i = 0; i < 4; i++) + hash_table[i] = 0xffff; + } + /* Use internal multicast address registers if the number of + * multicast addresses is not greater than MCAST_MAX. */ + else if (netdev_mc_count(dev) <= MCAST_MAX) { + i = 0; netdev_for_each_mc_addr(ha, dev) { - char *addrs = ha->addr; + u16 *adrp = (u16 *) ha->addr; + iowrite16(adrp[0], ioaddr + MID_1L + 8 * i); + iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); + iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); + i++; + } + while (i < MCAST_MAX) { + iowrite16(0, ioaddr + MID_1L + 8 * i); + iowrite16(0, ioaddr + MID_1M + 8 * i); + iowrite16(0, ioaddr + MID_1H + 8 * i); + i++; + } + } + /* Otherwise, Enable multicast hash table function. */ + else { + u32 crc; - if (!(*addrs & 1)) - continue; + lp->mcr0 |= MCR0_HASH_EN; + + for (i = 0; i < MCAST_MAX ; i++) { + iowrite16(0, ioaddr + MID_1L + 8 * i); + iowrite16(0, ioaddr + MID_1M + 8 * i); + iowrite16(0, ioaddr + MID_1H + 8 * i); + } - crc = ether_crc_le(6, addrs); + /* Build multicast hash table */ + netdev_for_each_mc_addr(ha, dev) { + u8 *addrs = ha->addr; + + crc = ether_crc(ETH_ALEN, addrs); crc >>= 26; - hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf)); + hash_table[crc >> 4] |= 1 << (crc & 0xf); } - /* Fill the MAC hash tables with their values */ + } + + iowrite16(lp->mcr0, ioaddr + MCR0); + + /* Fill the MAC hash tables with their values */ + if (lp->mcr0 && MCR0_HASH_EN) { iowrite16(hash_table[0], ioaddr + MAR0); iowrite16(hash_table[1], ioaddr + MAR1); iowrite16(hash_table[2], ioaddr + MAR2); iowrite16(hash_table[3], ioaddr + MAR3); } - /* Multicast Address 1~4 case */ - i = 0; - netdev_for_each_mc_addr(ha, dev) { - if (i >= MCAST_MAX) - break; - adrp = (u16 *) ha->addr; - iowrite16(adrp[0], ioaddr + MID_1L + 8 * i); - iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); - iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); - i++; - } - while (i < MCAST_MAX) { - iowrite16(0xffff, ioaddr + MID_1L + 8 * i); - iowrite16(0xffff, ioaddr + MID_1M + 8 * i); - iowrite16(0xffff, ioaddr + MID_1H + 8 * i); - i++; - } + + spin_unlock_irqrestore(&lp->lock, flags); } static void netdev_get_drvinfo(struct net_device *dev, -- cgit v1.2.3 From a9a6fb374547044088ca37a30d4c3ca581cec80d Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 23 Feb 2011 04:32:37 +0000 Subject: r6040: bump to version 0.27 and date 23Feb2011 Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/r6040.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 7965ae42eae4..e3ebd90ae651 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -49,8 +49,8 @@ #include #define DRV_NAME "r6040" -#define DRV_VERSION "0.26" -#define DRV_RELDATE "30May2010" +#define DRV_VERSION "0.27" +#define DRV_RELDATE "23Feb2011" /* PHY CHIP Address */ #define PHY1_ADDR 1 /* For MAC1 */ -- cgit v1.2.3 From 9ce13ca8fc43f6fbb7ee55a283d44ff2f4ba1c06 Mon Sep 17 00:00:00 2001 From: amit salecha Date: Wed, 23 Feb 2011 03:21:24 +0000 Subject: qlcnic: fix checks for auto_fw_reset o Remove checks of 1 for auto_fw_reset module parameter. auto_fw_reset is of type int and can have value > 1. o Remove unnecessary #define for 1 Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 1 - drivers/net/qlcnic/qlcnic_main.c | 9 ++++----- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 44e316fd67b8..fa7f794de29c 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -867,7 +867,6 @@ struct qlcnic_nic_intr_coalesce { #define LINKEVENT_LINKSPEED_MBPS 0 #define LINKEVENT_LINKSPEED_ENCODED 1 -#define AUTO_FW_RESET_ENABLED 0x01 /* firmware response header: * 63:58 - message type * 57:56 - owner diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 37c04b4fade3..4994b947fd21 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -42,7 +42,7 @@ static int use_msi_x = 1; module_param(use_msi_x, int, 0444); MODULE_PARM_DESC(use_msi_x, "MSI-X interrupt (0=disabled, 1=enabled"); -static int auto_fw_reset = AUTO_FW_RESET_ENABLED; +static int auto_fw_reset = 1; module_param(auto_fw_reset, int, 0644); MODULE_PARM_DESC(auto_fw_reset, "Auto firmware reset (0=disabled, 1=enabled"); @@ -2959,8 +2959,7 @@ qlcnic_check_health(struct qlcnic_adapter *adapter) if (adapter->need_fw_reset) goto detach; - if (adapter->reset_context && - auto_fw_reset == AUTO_FW_RESET_ENABLED) { + if (adapter->reset_context && auto_fw_reset) { qlcnic_reset_hw_context(adapter); adapter->netdev->trans_start = jiffies; } @@ -2973,7 +2972,7 @@ qlcnic_check_health(struct qlcnic_adapter *adapter) qlcnic_dev_request_reset(adapter); - if ((auto_fw_reset == AUTO_FW_RESET_ENABLED)) + if (auto_fw_reset) clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state); dev_info(&netdev->dev, "firmware hang detected\n"); @@ -2982,7 +2981,7 @@ detach: adapter->dev_state = (state == QLCNIC_DEV_NEED_QUISCENT) ? state : QLCNIC_DEV_NEED_RESET; - if ((auto_fw_reset == AUTO_FW_RESET_ENABLED) && + if (auto_fw_reset && !test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) { qlcnic_schedule_work(adapter, qlcnic_detach_work, 0); -- cgit v1.2.3 From d12b0d9adc46888e3bb0224886105bf3b188553b Mon Sep 17 00:00:00 2001 From: Rajesh Borundia Date: Wed, 23 Feb 2011 03:21:25 +0000 Subject: qlcnic: Remove validation for max tx and max rx queues Max rx queues and tx queues are governed by fimware. So driver should not validate these values. Signed-off-by: Rajesh Borundia Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic.h | 4 ---- drivers/net/qlcnic/qlcnic_main.c | 6 ++---- 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index fa7f794de29c..dc44564ef6f9 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -1132,14 +1132,10 @@ struct qlcnic_eswitch { #define MAX_BW 100 /* % of link speed */ #define MAX_VLAN_ID 4095 #define MIN_VLAN_ID 2 -#define MAX_TX_QUEUES 1 -#define MAX_RX_QUEUES 4 #define DEFAULT_MAC_LEARN 1 #define IS_VALID_VLAN(vlan) (vlan >= MIN_VLAN_ID && vlan < MAX_VLAN_ID) #define IS_VALID_BW(bw) (bw <= MAX_BW) -#define IS_VALID_TX_QUEUES(que) (que > 0 && que <= MAX_TX_QUEUES) -#define IS_VALID_RX_QUEUES(que) (que > 0 && que <= MAX_RX_QUEUES) struct qlcnic_pci_func_cfg { u16 func_type; diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 4994b947fd21..cd88c7e1bfa9 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -3653,10 +3653,8 @@ validate_npar_config(struct qlcnic_adapter *adapter, if (adapter->npars[pci_func].type != QLCNIC_TYPE_NIC) return QL_STATUS_INVALID_PARAM; - if (!IS_VALID_BW(np_cfg[i].min_bw) - || !IS_VALID_BW(np_cfg[i].max_bw) - || !IS_VALID_RX_QUEUES(np_cfg[i].max_rx_queues) - || !IS_VALID_TX_QUEUES(np_cfg[i].max_tx_queues)) + if (!IS_VALID_BW(np_cfg[i].min_bw) || + !IS_VALID_BW(np_cfg[i].max_bw)) return QL_STATUS_INVALID_PARAM; } return 0; -- cgit v1.2.3 From 8dde924217fdf5b69f6cbbdca099d077ba269ad0 Mon Sep 17 00:00:00 2001 From: Henry Nestler Date: Sun, 20 Feb 2011 11:44:58 +0000 Subject: DM9000B: Fix reg_save after spin_lock in dm9000_timeout The spin_lock should hold before reading register. Signed-off-by: David S. Miller --- drivers/net/dm9000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 2d4c4fc1d900..2bbd49653aa2 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -852,8 +852,8 @@ static void dm9000_timeout(struct net_device *dev) unsigned long flags; /* Save previous register address */ - reg_save = readb(db->io_addr); spin_lock_irqsave(&db->lock, flags); + reg_save = readb(db->io_addr); netif_stop_queue(dev); dm9000_reset(db); -- cgit v1.2.3 From 108f518cc4f81eb8e3b46a0bd5cb902ef90a51a8 Mon Sep 17 00:00:00 2001 From: Henry Nestler Date: Tue, 22 Feb 2011 11:29:42 +0000 Subject: DM9000B: Fix PHY power for network down/up DM9000 revision B needs 1 ms delay after PHY power-on. PHY must be powered on by writing 0 into register DM9000_GPR before all other settings will change (see Davicom spec and example code). Remember, that register DM9000_GPR was not changed by reset sequence. Without this fix the FIFO is out of sync and sends wrong data after sequence of "ifconfig ethX down ; ifconfig ethX up". Signed-off-by: David S. Miller --- drivers/net/dm9000.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 2bbd49653aa2..461dd6f905f7 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -802,10 +802,7 @@ dm9000_init_dm9000(struct net_device *dev) /* Checksum mode */ dm9000_set_rx_csum_unlocked(dev, db->rx_csum); - /* GPIO0 on pre-activate PHY */ - iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */ iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */ - iow(db, DM9000_GPR, 0); /* Enable PHY */ ncr = (db->flags & DM9000_PLATF_EXT_PHY) ? NCR_EXT_PHY : 0; @@ -1194,6 +1191,10 @@ dm9000_open(struct net_device *dev) if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev)) return -EAGAIN; + /* GPIO0 on pre-activate PHY, Reg 1F is not set by reset */ + iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */ + mdelay(1); /* delay needs by DM9000B */ + /* Initialize DM9000 board */ dm9000_reset(db); dm9000_init_dm9000(dev); -- cgit v1.2.3 From fac5b3caa1f5bc07ecfb4f5ce98f8112638dc8fb Mon Sep 17 00:00:00 2001 From: Hayes Wang Date: Tue, 22 Feb 2011 17:26:20 +0800 Subject: r8169: fix incorrect args to oob notify. It results in the wrong point address and influences RTL8168DP. Signed-off-by: Hayes Wang Acked-by: Francois Romieu --- drivers/net/r8169.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 469ab0b7ce31..550c86589649 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -617,8 +617,9 @@ static void ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, u32 data) } } -static void rtl8168_oob_notify(void __iomem *ioaddr, u8 cmd) +static void rtl8168_oob_notify(struct rtl8169_private *tp, u8 cmd) { + void __iomem *ioaddr = tp->mmio_addr; int i; RTL_W8(ERIDR, cmd); @@ -630,7 +631,7 @@ static void rtl8168_oob_notify(void __iomem *ioaddr, u8 cmd) break; } - ocp_write(ioaddr, 0x1, 0x30, 0x00000001); + ocp_write(tp, 0x1, 0x30, 0x00000001); } #define OOB_CMD_RESET 0x00 -- cgit v1.2.3 From d24e9aafe5d5dfdf6d114b29e67f8afd5fae5ef0 Mon Sep 17 00:00:00 2001 From: Hayes Wang Date: Tue, 22 Feb 2011 17:26:19 +0800 Subject: r8169: correct settings of rtl8102e. Adjust and remove certain settings of RTL8102E which are for previous chips. Signed-off-by: Hayes Wang Acked-off-by: Francois Romieu --- drivers/net/r8169.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 550c86589649..336ba9480e18 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -3043,7 +3043,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_mwi_2; } - tp->cp_cmd = PCIMulRW | RxChkSum; + tp->cp_cmd = RxChkSum; if ((sizeof(dma_addr_t) > 4) && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && use_dac) { @@ -3848,8 +3848,7 @@ static void rtl_hw_start_8168(struct net_device *dev) Cxpl_dbg_sel | \ ASF | \ PktCntrDisable | \ - PCIDAC | \ - PCIMulRW) + Mac_dbgo_sel) static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev) { @@ -3879,8 +3878,6 @@ static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev) if ((cfg1 & LEDS0) && (cfg1 & LEDS1)) RTL_W8(Config1, cfg1 & ~LEDS0); - RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK); - rtl_ephy_init(ioaddr, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1)); } @@ -3892,8 +3889,6 @@ static void rtl_hw_start_8102e_2(void __iomem *ioaddr, struct pci_dev *pdev) RTL_W8(Config1, MEMMAP | IOMAP | VPD | PMEnable); RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); - - RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK); } static void rtl_hw_start_8102e_3(void __iomem *ioaddr, struct pci_dev *pdev) @@ -3919,6 +3914,8 @@ static void rtl_hw_start_8101(struct net_device *dev) } } + RTL_W8(Cfg9346, Cfg9346_Unlock); + switch (tp->mac_version) { case RTL_GIGA_MAC_VER_07: rtl_hw_start_8102e_1(ioaddr, pdev); @@ -3933,14 +3930,13 @@ static void rtl_hw_start_8101(struct net_device *dev) break; } - RTL_W8(Cfg9346, Cfg9346_Unlock); + RTL_W8(Cfg9346, Cfg9346_Lock); RTL_W8(MaxTxPacketSize, TxPacketMax); rtl_set_rx_max_size(ioaddr, rx_buf_sz); - tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; - + tp->cp_cmd &= ~R810X_CPCMD_QUIRK_MASK; RTL_W16(CPlusCmd, tp->cp_cmd); RTL_W16(IntrMitigate, 0x0000); @@ -3950,14 +3946,10 @@ static void rtl_hw_start_8101(struct net_device *dev) RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); rtl_set_rx_tx_config_registers(tp); - RTL_W8(Cfg9346, Cfg9346_Lock); - RTL_R8(IntrMask); rtl_set_rx_mode(dev); - RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); - RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000); RTL_W16(IntrMask, tp->intr_event); -- cgit v1.2.3 From 5d2e19572a66be1e349faba289b7bd049b85bc98 Mon Sep 17 00:00:00 2001 From: Hayes Wang Date: Tue, 22 Feb 2011 17:26:22 +0800 Subject: r8169: fix RTL8168DP power off issue. - fix the RTL8111DP turn off the power when DASH is enabled. - RTL_GIGA_MAC_VER_27 must wait for tx finish before reset. Signed-off-by: Hayes Wang Acked-by: Francois Romieu --- drivers/net/r8169.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 336ba9480e18..ef2133b16f8c 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -2869,8 +2869,11 @@ static void r8168_pll_power_down(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - if (tp->mac_version == RTL_GIGA_MAC_VER_27) + if (((tp->mac_version == RTL_GIGA_MAC_VER_27) || + (tp->mac_version == RTL_GIGA_MAC_VER_28)) && + (ocp_read(tp, 0x0f, 0x0010) & 0x00008000)) { return; + } if (((tp->mac_version == RTL_GIGA_MAC_VER_23) || (tp->mac_version == RTL_GIGA_MAC_VER_24)) && @@ -2892,6 +2895,8 @@ static void r8168_pll_power_down(struct rtl8169_private *tp) switch (tp->mac_version) { case RTL_GIGA_MAC_VER_25: case RTL_GIGA_MAC_VER_26: + case RTL_GIGA_MAC_VER_27: + case RTL_GIGA_MAC_VER_28: RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80); break; } @@ -2901,12 +2906,17 @@ static void r8168_pll_power_up(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - if (tp->mac_version == RTL_GIGA_MAC_VER_27) + if (((tp->mac_version == RTL_GIGA_MAC_VER_27) || + (tp->mac_version == RTL_GIGA_MAC_VER_28)) && + (ocp_read(tp, 0x0f, 0x0010) & 0x00008000)) { return; + } switch (tp->mac_version) { case RTL_GIGA_MAC_VER_25: case RTL_GIGA_MAC_VER_26: + case RTL_GIGA_MAC_VER_27: + case RTL_GIGA_MAC_VER_28: RTL_W8(PMCH, RTL_R8(PMCH) | 0x80); break; } @@ -3319,7 +3329,8 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) /* Disable interrupts */ rtl8169_irq_mask_and_ack(ioaddr); - if (tp->mac_version == RTL_GIGA_MAC_VER_28) { + if (tp->mac_version == RTL_GIGA_MAC_VER_27 || + tp->mac_version == RTL_GIGA_MAC_VER_28) { while (RTL_R8(TxPoll) & NPQ) udelay(20); -- cgit v1.2.3 From 67158cebde60edb1a11cf4743f1cb9ded847c5fc Mon Sep 17 00:00:00 2001 From: Shahar Havivi Date: Tue, 22 Feb 2011 04:41:11 +0000 Subject: Added support for usb ethernet (0x0fe6, 0x9700) The device is very similar to (0x0fe6, 0x8101), And works well with dm9601 driver. Signed-off-by: Shahar Havivi Acked-by: Peter Korsgaard Signed-off-by: David S. Miller --- drivers/net/usb/dm9601.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 02b622e3b9fb..5002f5be47be 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -650,6 +650,10 @@ static const struct usb_device_id products[] = { USB_DEVICE(0x0fe6, 0x8101), /* DM9601 USB to Fast Ethernet Adapter */ .driver_info = (unsigned long)&dm9601_info, }, + { + USB_DEVICE(0x0fe6, 0x9700), /* DM9601 USB to Fast Ethernet Adapter */ + .driver_info = (unsigned long)&dm9601_info, + }, { USB_DEVICE(0x0a46, 0x9000), /* DM9000E */ .driver_info = (unsigned long)&dm9601_info, -- cgit v1.2.3 From 1af4791552e462b37d0174407dc3173917e35ea0 Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Sun, 20 Feb 2011 20:03:34 +0100 Subject: staging/et131x: fix et131x_rx_dma_disable halt_status usage Commit 1bd751c1abc1029e8a0ae63ef4f19357c735a2a3 ("Staging: et131x: Clean up rxdma_csr") changed csr from bitfield to u32, but failed to convert 2 uses of halt_status bit. It did: - if (csr.bits.halt_status != 1) + if ((csr & 0x00020000) != 1) which is wrong, because second version is always true. Fix it. This bug was found by coccinelle (http://coccinelle.lip6.fr/). Signed-off-by: Marcin Slusarz Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et1310_rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c index a87da6848f9c..339136f64be1 100644 --- a/drivers/staging/et131x/et1310_rx.c +++ b/drivers/staging/et131x/et1310_rx.c @@ -717,10 +717,10 @@ void et131x_rx_dma_disable(struct et131x_adapter *etdev) /* Setup the receive dma configuration register */ writel(0x00002001, &etdev->regs->rxdma.csr); csr = readl(&etdev->regs->rxdma.csr); - if ((csr & 0x00020000) != 1) { /* Check halt status (bit 17) */ + if ((csr & 0x00020000) == 0) { /* Check halt status (bit 17) */ udelay(5); csr = readl(&etdev->regs->rxdma.csr); - if ((csr & 0x00020000) != 1) + if ((csr & 0x00020000) == 0) dev_err(&etdev->pdev->dev, "RX Dma failed to enter halt state. CSR 0x%08x\n", csr); -- cgit v1.2.3 From 87be424a9a4be41df26b25b3360969211cedd5d1 Mon Sep 17 00:00:00 2001 From: Christopher Brannon Date: Mon, 21 Feb 2011 14:07:10 +0000 Subject: Staging: speakup: fix an out-of-bounds error. The cur_item variable from keyhelp.c is an index into a table of messages. The following condition should always hold: MSG_FUNCNAMES_START + cur_item <= MSG_FUNCNAMES_END. The check in keyhelp.c was wrong. It allowed cur_item to be incremented to an out-of-bounds value. Signed-off-by: Christopher Brannon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/keyhelp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/speakup/keyhelp.c b/drivers/staging/speakup/keyhelp.c index 236f06d35ca6..23cf7f44f450 100644 --- a/drivers/staging/speakup/keyhelp.c +++ b/drivers/staging/speakup/keyhelp.c @@ -161,7 +161,9 @@ int handle_help(struct vc_data *vc, u_char type, u_char ch, u_short key) } cur_item = letter_offsets[ch-'a']; } else if (type == KT_CUR) { - if (ch == 0 && (cur_item + 1) <= MSG_FUNCNAMES_END) + if (ch == 0 + && (MSG_FUNCNAMES_START + cur_item + 1) <= + MSG_FUNCNAMES_END) cur_item++; else if (ch == 3 && cur_item > 0) cur_item--; -- cgit v1.2.3 From 6a3a81e7ca9b1ddaaf8d644b4102aff0fe2a7c40 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 21 Feb 2011 14:39:08 -0800 Subject: staging: fix olpc_dcon kconfig and build errors drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c:106: error: 'acpi_gbl_FADT' undeclared (first use in this function) Fixing that one gives: ERROR: "backlight_device_register" [drivers/staging/olpc_dcon/olpc-dcon.ko] undefined! ERROR: "registered_fb" [drivers/staging/olpc_dcon/olpc-dcon.ko] undefined! ERROR: "lock_fb_info" [drivers/staging/olpc_dcon/olpc-dcon.ko] undefined! ERROR: "backlight_device_unregister" [drivers/staging/olpc_dcon/olpc-dcon.ko] undefined! ERROR: "num_registered_fb" [drivers/staging/olpc_dcon/olpc-dcon.ko] undefined! ERROR: "fb_blank" [drivers/staging/olpc_dcon/olpc-dcon.ko] undefined! Signed-off-by: Randy Dunlap Cc: Chris Ball Cc: Jon Nettleton Acked-By: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/Kconfig b/drivers/staging/olpc_dcon/Kconfig index acb0a79a949a..f1082f50fdce 100644 --- a/drivers/staging/olpc_dcon/Kconfig +++ b/drivers/staging/olpc_dcon/Kconfig @@ -1,6 +1,6 @@ config FB_OLPC_DCON tristate "One Laptop Per Child Display CONtroller support" - depends on OLPC + depends on OLPC && FB select I2C ---help--- Add support for the OLPC XO DCON controller. This controller is @@ -19,7 +19,7 @@ config FB_OLPC_DCON_1 config FB_OLPC_DCON_1_5 bool "OLPC XO-1.5 DCON support" - depends on FB_OLPC_DCON + depends on FB_OLPC_DCON && ACPI default y ---help--- Enable support for the DCON in XO-1.5 model laptops. The kernel -- cgit v1.2.3 From 363907af85816adac5e60d48d3d84bba8f7201df Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Sun, 20 Feb 2011 22:41:16 -0600 Subject: Bluetooth: btwilink driver This is the bluetooth protocol driver for the TI WiLink7 chipsets. Texas Instrument's WiLink chipsets combine wireless technologies like BT, FM, GPS and WLAN onto a single chip. This Bluetooth driver works on top of the TI_ST shared transport line discipline driver which also allows other drivers like FM V4L2 and GPS character driver to make use of the same UART interface. Kconfig and Makefile modifications to enable the Bluetooth driver for Texas Instrument's WiLink 7 chipset. Signed-off-by: Pavan Savoy Acked-by: Gustavo F. Padovan Signed-off-by: Greg Kroah-Hartman --- drivers/bluetooth/Kconfig | 10 ++ drivers/bluetooth/Makefile | 1 + drivers/bluetooth/btwilink.c | 395 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 406 insertions(+) create mode 100644 drivers/bluetooth/btwilink.c (limited to 'drivers') diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index 02deef424926..8e0de9a05867 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -219,4 +219,14 @@ config BT_ATH3K Say Y here to compile support for "Atheros firmware download driver" into the kernel or say M to compile it as module (ath3k). +config BT_WILINK + tristate "Texas Instruments WiLink7 driver" + depends on TI_ST + help + This enables the Bluetooth driver for Texas Instrument's BT/FM/GPS + combo devices. This makes use of shared transport line discipline + core driver to communicate with the BT core of the combo chip. + + Say Y here to compile support for Texas Instrument's WiLink7 driver + into the kernel or say M to compile it as module. endmenu diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile index 71bdf13287c4..f4460f4f4b78 100644 --- a/drivers/bluetooth/Makefile +++ b/drivers/bluetooth/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_BT_HCIBTSDIO) += btsdio.o obj-$(CONFIG_BT_ATH3K) += ath3k.o obj-$(CONFIG_BT_MRVL) += btmrvl.o obj-$(CONFIG_BT_MRVL_SDIO) += btmrvl_sdio.o +obj-$(CONFIG_BT_WILINK) += btwilink.o btmrvl-y := btmrvl_main.o btmrvl-$(CONFIG_DEBUG_FS) += btmrvl_debugfs.o diff --git a/drivers/bluetooth/btwilink.c b/drivers/bluetooth/btwilink.c new file mode 100644 index 000000000000..65d27aff553a --- /dev/null +++ b/drivers/bluetooth/btwilink.c @@ -0,0 +1,395 @@ +/* + * Texas Instrument's Bluetooth Driver For Shared Transport. + * + * Bluetooth Driver acts as interface between HCI core and + * TI Shared Transport Layer. + * + * Copyright (C) 2009-2010 Texas Instruments + * Author: Raja Mani + * Pavan Savoy + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#define DEBUG +#include +#include +#include +#include + +#include + +/* Bluetooth Driver Version */ +#define VERSION "1.0" +#define MAX_BT_CHNL_IDS 3 + +/* Number of seconds to wait for registration completion + * when ST returns PENDING status. + */ +#define BT_REGISTER_TIMEOUT 6000 /* 6 sec */ + +/** + * struct ti_st - driver operation structure + * @hdev: hci device pointer which binds to bt driver + * @reg_status: ST registration callback status + * @st_write: write function provided by the ST driver + * to be used by the driver during send_frame. + * @wait_reg_completion - completion sync between ti_st_open + * and st_reg_completion_cb. + */ +struct ti_st { + struct hci_dev *hdev; + char reg_status; + long (*st_write) (struct sk_buff *); + struct completion wait_reg_completion; +}; + +/* Increments HCI counters based on pocket ID (cmd,acl,sco) */ +static inline void ti_st_tx_complete(struct ti_st *hst, int pkt_type) +{ + struct hci_dev *hdev = hst->hdev; + + /* Update HCI stat counters */ + switch (pkt_type) { + case HCI_COMMAND_PKT: + hdev->stat.cmd_tx++; + break; + + case HCI_ACLDATA_PKT: + hdev->stat.acl_tx++; + break; + + case HCI_SCODATA_PKT: + hdev->stat.sco_tx++; + break; + } +} + +/* ------- Interfaces to Shared Transport ------ */ + +/* Called by ST layer to indicate protocol registration completion + * status.ti_st_open() function will wait for signal from this + * API when st_register() function returns ST_PENDING. + */ +static void st_reg_completion_cb(void *priv_data, char data) +{ + struct ti_st *lhst = priv_data; + + /* Save registration status for use in ti_st_open() */ + lhst->reg_status = data; + /* complete the wait in ti_st_open() */ + complete(&lhst->wait_reg_completion); +} + +/* Called by Shared Transport layer when receive data is + * available */ +static long st_receive(void *priv_data, struct sk_buff *skb) +{ + struct ti_st *lhst = priv_data; + int err; + + if (!skb) + return -EFAULT; + + if (!lhst) { + kfree_skb(skb); + return -EFAULT; + } + + skb->dev = (void *) lhst->hdev; + + /* Forward skb to HCI core layer */ + err = hci_recv_frame(skb); + if (err < 0) { + BT_ERR("Unable to push skb to HCI core(%d)", err); + return err; + } + + lhst->hdev->stat.byte_rx += skb->len; + + return 0; +} + +/* ------- Interfaces to HCI layer ------ */ +/* protocol structure registered with shared transport */ +static struct st_proto_s ti_st_proto[MAX_BT_CHNL_IDS] = { + { + .chnl_id = HCI_ACLDATA_PKT, /* ACL */ + .hdr_len = sizeof(struct hci_acl_hdr), + .offset_len_in_hdr = offsetof(struct hci_acl_hdr, dlen), + .len_size = 2, /* sizeof(dlen) in struct hci_acl_hdr */ + .reserve = 8, + }, + { + .chnl_id = HCI_SCODATA_PKT, /* SCO */ + .hdr_len = sizeof(struct hci_sco_hdr), + .offset_len_in_hdr = offsetof(struct hci_sco_hdr, dlen), + .len_size = 1, /* sizeof(dlen) in struct hci_sco_hdr */ + .reserve = 8, + }, + { + .chnl_id = HCI_EVENT_PKT, /* HCI Events */ + .hdr_len = sizeof(struct hci_event_hdr), + .offset_len_in_hdr = offsetof(struct hci_event_hdr, plen), + .len_size = 1, /* sizeof(plen) in struct hci_event_hdr */ + .reserve = 8, + }, +}; + +/* Called from HCI core to initialize the device */ +static int ti_st_open(struct hci_dev *hdev) +{ + unsigned long timeleft; + struct ti_st *hst; + int err, i; + + BT_DBG("%s %p", hdev->name, hdev); + + if (test_and_set_bit(HCI_RUNNING, &hdev->flags)) + return -EBUSY; + + /* provide contexts for callbacks from ST */ + hst = hdev->driver_data; + + for (i = 0; i < MAX_BT_CHNL_IDS; i++) { + ti_st_proto[i].priv_data = hst; + ti_st_proto[i].max_frame_size = HCI_MAX_FRAME_SIZE; + ti_st_proto[i].recv = st_receive; + ti_st_proto[i].reg_complete_cb = st_reg_completion_cb; + + /* Prepare wait-for-completion handler */ + init_completion(&hst->wait_reg_completion); + /* Reset ST registration callback status flag, + * this value will be updated in + * st_reg_completion_cb() + * function whenever it called from ST driver. + */ + hst->reg_status = -EINPROGRESS; + + err = st_register(&ti_st_proto[i]); + if (!err) + goto done; + + if (err != -EINPROGRESS) { + clear_bit(HCI_RUNNING, &hdev->flags); + BT_ERR("st_register failed %d", err); + return err; + } + + /* ST is busy with either protocol + * registration or firmware download. + */ + BT_DBG("waiting for registration " + "completion signal from ST"); + timeleft = wait_for_completion_timeout + (&hst->wait_reg_completion, + msecs_to_jiffies(BT_REGISTER_TIMEOUT)); + if (!timeleft) { + clear_bit(HCI_RUNNING, &hdev->flags); + BT_ERR("Timeout(%d sec),didn't get reg " + "completion signal from ST", + BT_REGISTER_TIMEOUT / 1000); + return -ETIMEDOUT; + } + + /* Is ST registration callback + * called with ERROR status? */ + if (hst->reg_status != 0) { + clear_bit(HCI_RUNNING, &hdev->flags); + BT_ERR("ST registration completed with invalid " + "status %d", hst->reg_status); + return -EAGAIN; + } + +done: + hst->st_write = ti_st_proto[i].write; + if (!hst->st_write) { + BT_ERR("undefined ST write function"); + clear_bit(HCI_RUNNING, &hdev->flags); + for (i = 0; i < MAX_BT_CHNL_IDS; i++) { + /* Undo registration with ST */ + err = st_unregister(&ti_st_proto[i]); + if (err) + BT_ERR("st_unregister() failed with " + "error %d", err); + hst->st_write = NULL; + } + return -EIO; + } + } + return 0; +} + +/* Close device */ +static int ti_st_close(struct hci_dev *hdev) +{ + int err, i; + struct ti_st *hst = hdev->driver_data; + + if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) + return 0; + + for (i = 0; i < MAX_BT_CHNL_IDS; i++) { + err = st_unregister(&ti_st_proto[i]); + if (err) + BT_ERR("st_unregister(%d) failed with error %d", + ti_st_proto[i].chnl_id, err); + } + + hst->st_write = NULL; + + return err; +} + +static int ti_st_send_frame(struct sk_buff *skb) +{ + struct hci_dev *hdev; + struct ti_st *hst; + long len; + + hdev = (struct hci_dev *)skb->dev; + + if (!test_bit(HCI_RUNNING, &hdev->flags)) + return -EBUSY; + + hst = hdev->driver_data; + + /* Prepend skb with frame type */ + memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); + + BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, + skb->len); + + /* Insert skb to shared transport layer's transmit queue. + * Freeing skb memory is taken care in shared transport layer, + * so don't free skb memory here. + */ + len = hst->st_write(skb); + if (len < 0) { + kfree_skb(skb); + BT_ERR("ST write failed (%ld)", len); + /* Try Again, would only fail if UART has gone bad */ + return -EAGAIN; + } + + /* ST accepted our skb. So, Go ahead and do rest */ + hdev->stat.byte_tx += len; + ti_st_tx_complete(hst, bt_cb(skb)->pkt_type); + + return 0; +} + +static void ti_st_destruct(struct hci_dev *hdev) +{ + BT_DBG("%s", hdev->name); + /* do nothing here, since platform remove + * would free the hdev->driver_data + */ +} + +static int bt_ti_probe(struct platform_device *pdev) +{ + static struct ti_st *hst; + struct hci_dev *hdev; + int err; + + hst = kzalloc(sizeof(struct ti_st), GFP_KERNEL); + if (!hst) + return -ENOMEM; + + /* Expose "hciX" device to user space */ + hdev = hci_alloc_dev(); + if (!hdev) { + kfree(hst); + return -ENOMEM; + } + + BT_DBG("hdev %p", hdev); + + hst->hdev = hdev; + hdev->bus = HCI_UART; + hdev->driver_data = hst; + hdev->open = ti_st_open; + hdev->close = ti_st_close; + hdev->flush = NULL; + hdev->send = ti_st_send_frame; + hdev->destruct = ti_st_destruct; + hdev->owner = THIS_MODULE; + + err = hci_register_dev(hdev); + if (err < 0) { + BT_ERR("Can't register HCI device error %d", err); + kfree(hst); + hci_free_dev(hdev); + return err; + } + + BT_DBG("HCI device registered (hdev %p)", hdev); + + dev_set_drvdata(&pdev->dev, hst); + return err; +} + +static int bt_ti_remove(struct platform_device *pdev) +{ + struct hci_dev *hdev; + struct ti_st *hst = dev_get_drvdata(&pdev->dev); + + if (!hst) + return -EFAULT; + + BT_DBG("%s", hst->hdev->name); + + hdev = hst->hdev; + ti_st_close(hdev); + hci_unregister_dev(hdev); + + hci_free_dev(hdev); + kfree(hst); + + dev_set_drvdata(&pdev->dev, NULL); + return 0; +} + +static struct platform_driver btwilink_driver = { + .probe = bt_ti_probe, + .remove = bt_ti_remove, + .driver = { + .name = "btwilink", + .owner = THIS_MODULE, + }, +}; + +/* ------- Module Init/Exit interfaces ------ */ +static int __init btwilink_init(void) +{ + BT_INFO("Bluetooth Driver for TI WiLink - Version %s", VERSION); + + return platform_driver_register(&btwilink_driver); +} + +static void __exit btwilink_exit(void) +{ + platform_driver_unregister(&btwilink_driver); +} + +module_init(btwilink_init); +module_exit(btwilink_exit); + +/* ------ Module Info ------ */ + +MODULE_AUTHOR("Raja Mani "); +MODULE_DESCRIPTION("Bluetooth Driver for TI Shared Transport" VERSION); +MODULE_VERSION(VERSION); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From b9618c0cacd7cf56cc3d073c1e9e9a8a3a12864e Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 22 Feb 2011 21:46:18 +0100 Subject: staging: IIO: ADC: New driver for AD7606/AD7606-6/AD7606-4 This patch adds support for the: AD7606/AD7606-6/AD7606-4 8/6/4-Channel Data Acquisition system (DAS) with 16-Bit, Bipolar, Simultaneous Sampling ADC. Changes since V1: IIO: ADC: New driver for AD7606/AD7606-6/AD7606-4: Apply review feedback Rename sysfs node oversampling to oversampling_ratio. Kconfig: Add GPIOLIB dependency. Use range in mV to better match HWMON. Rename ad7606_check_oversampling. Fix various comments and style. Reorder is_visible cases. Use new gpio_request_one/array and friends. Drop check for SPI max_speed_hz. Changes since V2: IIO: ADC: New driver for AD7606/AD7606-6/AD7606-4: Apply review feedback Documentation: specify unit Avoid raise condition in ad7606_scan_direct() Check return value of bus ops read_block() Changes since V3: IIO: ADC: New driver for AD7606/AD7606-6/AD7606-4: Add missing include file Add linux/sched.h Changes since V4: IIO: ADC: New driver for AD7606/AD7606-6/AD7606-4: Fix kconfig declaration consistently use tristate to avoid configuration mismatches Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/sysfs-bus-iio | 25 ++ drivers/staging/iio/adc/Kconfig | 28 ++ drivers/staging/iio/adc/Makefile | 6 + drivers/staging/iio/adc/ad7606.h | 117 +++++ drivers/staging/iio/adc/ad7606_core.c | 556 ++++++++++++++++++++++++ drivers/staging/iio/adc/ad7606_par.c | 188 ++++++++ drivers/staging/iio/adc/ad7606_ring.c | 266 ++++++++++++ drivers/staging/iio/adc/ad7606_spi.c | 126 ++++++ 8 files changed, 1312 insertions(+) create mode 100644 drivers/staging/iio/adc/ad7606.h create mode 100644 drivers/staging/iio/adc/ad7606_core.c create mode 100644 drivers/staging/iio/adc/ad7606_par.c create mode 100644 drivers/staging/iio/adc/ad7606_ring.c create mode 100644 drivers/staging/iio/adc/ad7606_spi.c (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio b/drivers/staging/iio/Documentation/sysfs-bus-iio index 8e5d8d1f3b2f..da25bc73983a 100644 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio @@ -53,6 +53,31 @@ Description: When the internal sampling clock can only take a small discrete set of values, this file lists those available. +What: /sys/bus/iio/devices/deviceX/range +KernelVersion: 2.6.38 +Contact: linux-iio@vger.kernel.org +Description: + Hardware dependent ADC Full Scale Range in mVolt. + +What: /sys/bus/iio/devices/deviceX/range_available +KernelVersion: 2.6.38 +Contact: linux-iio@vger.kernel.org +Description: + Hardware dependent supported vales for ADC Full Scale Range. + +What: /sys/bus/iio/devices/deviceX/oversampling_ratio +KernelVersion: 2.6.38 +Contact: linux-iio@vger.kernel.org +Description: + Hardware dependent ADC oversampling. Controls the sampling ratio + of the digital filter if available. + +What: /sys/bus/iio/devices/deviceX/oversampling_ratio_available +KernelVersion: 2.6.38 +Contact: linux-iio@vger.kernel.org +Description: + Hardware dependent values supported by the oversampling filter. + What: /sys/bus/iio/devices/deviceX/inY_raw What: /sys/bus/iio/devices/deviceX/inY_supply_raw KernelVersion: 2.6.35 diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 86869cd233ae..5613b30bc663 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -62,6 +62,34 @@ config AD7314 Say yes here to build support for Analog Devices AD7314 temperature sensors. +config AD7606 + tristate "Analog Devices AD7606 ADC driver" + depends on GPIOLIB + select IIO_RING_BUFFER + select IIO_TRIGGER + select IIO_SW_RING + help + Say yes here to build support for Analog Devices: + ad7606, ad7606-6, ad7606-4 analog to digital convertors (ADC). + + To compile this driver as a module, choose M here: the + module will be called ad7606. + +config AD7606_IFACE_PARALLEL + tristate "parallel interface support" + depends on AD7606 + help + Say yes here to include parallel interface support on the AD7606 + ADC driver. + +config AD7606_IFACE_SPI + tristate "spi interface support" + depends on AD7606 + depends on SPI + help + Say yes here to include parallel interface support on the AD7606 + ADC driver. + config AD799X tristate "Analog Devices AD799x ADC driver" depends on I2C diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index 6f231a2cb777..cb73346d6d9e 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -7,6 +7,12 @@ max1363-y += max1363_ring.o obj-$(CONFIG_MAX1363) += max1363.o +ad7606-y := ad7606_core.o +ad7606-$(CONFIG_IIO_RING_BUFFER) += ad7606_ring.o +ad7606-$(CONFIG_AD7606_IFACE_PARALLEL) += ad7606_par.o +ad7606-$(CONFIG_AD7606_IFACE_SPI) += ad7606_spi.o +obj-$(CONFIG_AD7606) += ad7606.o + ad799x-y := ad799x_core.o ad799x-$(CONFIG_AD799X_RING_BUFFER) += ad799x_ring.o obj-$(CONFIG_AD799X) += ad799x.o diff --git a/drivers/staging/iio/adc/ad7606.h b/drivers/staging/iio/adc/ad7606.h new file mode 100644 index 000000000000..338bade801a7 --- /dev/null +++ b/drivers/staging/iio/adc/ad7606.h @@ -0,0 +1,117 @@ +/* + * AD7606 ADC driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#ifndef IIO_ADC_AD7606_H_ +#define IIO_ADC_AD7606_H_ + +/* + * TODO: struct ad7606_platform_data needs to go into include/linux/iio + */ + +/** + * struct ad7606_platform_data - platform/board specifc information + * @default_os: default oversampling value {0, 2, 4, 8, 16, 32, 64} + * @default_range: default range +/-{5000, 10000} mVolt + * @gpio_convst: number of gpio connected to the CONVST pin + * @gpio_reset: gpio connected to the RESET pin, if not used set to -1 + * @gpio_range: gpio connected to the RANGE pin, if not used set to -1 + * @gpio_os0: gpio connected to the OS0 pin, if not used set to -1 + * @gpio_os1: gpio connected to the OS1 pin, if not used set to -1 + * @gpio_os2: gpio connected to the OS2 pin, if not used set to -1 + * @gpio_frstdata: gpio connected to the FRSTDAT pin, if not used set to -1 + * @gpio_stby: gpio connected to the STBY pin, if not used set to -1 + */ + +struct ad7606_platform_data { + unsigned default_os; + unsigned default_range; + unsigned gpio_convst; + unsigned gpio_reset; + unsigned gpio_range; + unsigned gpio_os0; + unsigned gpio_os1; + unsigned gpio_os2; + unsigned gpio_frstdata; + unsigned gpio_stby; +}; + +/** + * struct ad7606_chip_info - chip specifc information + * @name: indentification string for chip + * @bits: accuracy of the adc in bits + * @bits: output coding [s]igned or [u]nsigned + * @int_vref_mv: the internal reference voltage + * @num_channels: number of physical inputs on chip + */ + +struct ad7606_chip_info { + char name[10]; + u8 bits; + char sign; + u16 int_vref_mv; + unsigned num_channels; +}; + +/** + * struct ad7606_state - driver instance specific data + */ + +struct ad7606_state { + struct iio_dev *indio_dev; + struct device *dev; + const struct ad7606_chip_info *chip_info; + struct ad7606_platform_data *pdata; + struct regulator *reg; + struct work_struct poll_work; + wait_queue_head_t wq_data_avail; + atomic_t protect_ring; + size_t d_size; + const struct ad7606_bus_ops *bops; + int irq; + unsigned id; + unsigned range; + unsigned oversampling; + bool done; + bool have_frstdata; + bool have_os; + bool have_stby; + bool have_reset; + bool have_range; + void __iomem *base_address; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + + unsigned short data[8] ____cacheline_aligned; +}; + +struct ad7606_bus_ops { + /* more methods added in future? */ + int (*read_block)(struct device *, int, void *); +}; + +void ad7606_suspend(struct ad7606_state *st); +void ad7606_resume(struct ad7606_state *st); +struct ad7606_state *ad7606_probe(struct device *dev, int irq, + void __iomem *base_address, unsigned id, + const struct ad7606_bus_ops *bops); +int ad7606_remove(struct ad7606_state *st); +int ad7606_reset(struct ad7606_state *st); + +enum ad7606_supported_device_ids { + ID_AD7606_8, + ID_AD7606_6, + ID_AD7606_4 +}; + +int ad7606_scan_from_ring(struct ad7606_state *st, unsigned ch); +int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev); +void ad7606_ring_cleanup(struct iio_dev *indio_dev); +#endif /* IIO_ADC_AD7606_H_ */ diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c new file mode 100644 index 000000000000..4c700f07fb83 --- /dev/null +++ b/drivers/staging/iio/adc/ad7606_core.c @@ -0,0 +1,556 @@ +/* + * AD7606 SPI ADC driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../ring_generic.h" +#include "adc.h" + +#include "ad7606.h" + +int ad7606_reset(struct ad7606_state *st) +{ + if (st->have_reset) { + gpio_set_value(st->pdata->gpio_reset, 1); + ndelay(100); /* t_reset >= 100ns */ + gpio_set_value(st->pdata->gpio_reset, 0); + return 0; + } + + return -ENODEV; +} + +static int ad7606_scan_direct(struct ad7606_state *st, unsigned ch) +{ + int ret; + + st->done = false; + gpio_set_value(st->pdata->gpio_convst, 1); + + ret = wait_event_interruptible(st->wq_data_avail, st->done); + if (ret) + goto error_ret; + + if (st->have_frstdata) { + ret = st->bops->read_block(st->dev, 1, st->data); + if (ret) + goto error_ret; + if (!gpio_get_value(st->pdata->gpio_frstdata)) { + /* This should never happen */ + ad7606_reset(st); + ret = -EIO; + goto error_ret; + } + ret = st->bops->read_block(st->dev, + st->chip_info->num_channels - 1, &st->data[1]); + if (ret) + goto error_ret; + } else { + ret = st->bops->read_block(st->dev, + st->chip_info->num_channels, st->data); + if (ret) + goto error_ret; + } + + ret = st->data[ch]; + +error_ret: + gpio_set_value(st->pdata->gpio_convst, 0); + + return ret; +} + +static ssize_t ad7606_scan(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7606_state *st = dev_info->dev_data; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + + mutex_lock(&dev_info->mlock); + if (iio_ring_enabled(dev_info)) + ret = ad7606_scan_from_ring(st, this_attr->address); + else + ret = ad7606_scan_direct(st, this_attr->address); + mutex_unlock(&dev_info->mlock); + + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", (short) ret); +} + +static IIO_DEV_ATTR_IN_RAW(0, ad7606_scan, 0); +static IIO_DEV_ATTR_IN_RAW(1, ad7606_scan, 1); +static IIO_DEV_ATTR_IN_RAW(2, ad7606_scan, 2); +static IIO_DEV_ATTR_IN_RAW(3, ad7606_scan, 3); +static IIO_DEV_ATTR_IN_RAW(4, ad7606_scan, 4); +static IIO_DEV_ATTR_IN_RAW(5, ad7606_scan, 5); +static IIO_DEV_ATTR_IN_RAW(6, ad7606_scan, 6); +static IIO_DEV_ATTR_IN_RAW(7, ad7606_scan, 7); + +static ssize_t ad7606_show_scale(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + /* Driver currently only support internal vref */ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7606_state *st = iio_dev_get_devdata(dev_info); + unsigned int scale_uv = (st->range * 1000 * 2) >> st->chip_info->bits; + + return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000); +} +static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7606_show_scale, NULL, 0); + +static ssize_t ad7606_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7606_state *st = iio_dev_get_devdata(dev_info); + + return sprintf(buf, "%s\n", st->chip_info->name); +} + +static IIO_DEVICE_ATTR(name, S_IRUGO, ad7606_show_name, NULL, 0); + +static ssize_t ad7606_show_range(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7606_state *st = iio_dev_get_devdata(dev_info); + + return sprintf(buf, "%u\n", st->range); +} + +static ssize_t ad7606_store_range(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7606_state *st = iio_dev_get_devdata(dev_info); + unsigned long lval; + + if (strict_strtoul(buf, 10, &lval)) + return -EINVAL; + if (!(lval == 5000 || lval == 10000)) { + dev_err(dev, "range is not supported\n"); + return -EINVAL; + } + mutex_lock(&dev_info->mlock); + gpio_set_value(st->pdata->gpio_range, lval == 10000); + st->range = lval; + mutex_unlock(&dev_info->mlock); + + return count; +} + +static IIO_DEVICE_ATTR(range, S_IRUGO | S_IWUSR, \ + ad7606_show_range, ad7606_store_range, 0); +static IIO_CONST_ATTR(range_available, "5000 10000"); + +static ssize_t ad7606_show_oversampling_ratio(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7606_state *st = iio_dev_get_devdata(dev_info); + + return sprintf(buf, "%u\n", st->oversampling); +} + +static int ad7606_oversampling_get_index(unsigned val) +{ + unsigned char supported[] = {0, 2, 4, 8, 16, 32, 64}; + int i; + + for (i = 0; i < ARRAY_SIZE(supported); i++) + if (val == supported[i]) + return i; + + return -EINVAL; +} + +static ssize_t ad7606_store_oversampling_ratio(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7606_state *st = iio_dev_get_devdata(dev_info); + unsigned long lval; + int ret; + + if (strict_strtoul(buf, 10, &lval)) + return -EINVAL; + + ret = ad7606_oversampling_get_index(lval); + if (ret < 0) { + dev_err(dev, "oversampling %lu is not supported\n", lval); + return ret; + } + + mutex_lock(&dev_info->mlock); + gpio_set_value(st->pdata->gpio_os0, (ret >> 0) & 1); + gpio_set_value(st->pdata->gpio_os1, (ret >> 1) & 1); + gpio_set_value(st->pdata->gpio_os1, (ret >> 2) & 1); + st->oversampling = lval; + mutex_unlock(&dev_info->mlock); + + return count; +} + +static IIO_DEVICE_ATTR(oversampling_ratio, S_IRUGO | S_IWUSR, + ad7606_show_oversampling_ratio, + ad7606_store_oversampling_ratio, 0); +static IIO_CONST_ATTR(oversampling_ratio_available, "0 2 4 8 16 32 64"); + +static struct attribute *ad7606_attributes[] = { + &iio_dev_attr_in0_raw.dev_attr.attr, + &iio_dev_attr_in1_raw.dev_attr.attr, + &iio_dev_attr_in2_raw.dev_attr.attr, + &iio_dev_attr_in3_raw.dev_attr.attr, + &iio_dev_attr_in4_raw.dev_attr.attr, + &iio_dev_attr_in5_raw.dev_attr.attr, + &iio_dev_attr_in6_raw.dev_attr.attr, + &iio_dev_attr_in7_raw.dev_attr.attr, + &iio_dev_attr_in_scale.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + &iio_dev_attr_range.dev_attr.attr, + &iio_const_attr_range_available.dev_attr.attr, + &iio_dev_attr_oversampling_ratio.dev_attr.attr, + &iio_const_attr_oversampling_ratio_available.dev_attr.attr, + NULL, +}; + +static mode_t ad7606_attr_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7606_state *st = iio_dev_get_devdata(dev_info); + + mode_t mode = attr->mode; + + if (st->chip_info->num_channels <= 6 && + (attr == &iio_dev_attr_in7_raw.dev_attr.attr || + attr == &iio_dev_attr_in6_raw.dev_attr.attr)) + mode = 0; + else if (st->chip_info->num_channels <= 4 && + (attr == &iio_dev_attr_in5_raw.dev_attr.attr || + attr == &iio_dev_attr_in4_raw.dev_attr.attr)) + mode = 0; + else if (!st->have_os && + (attr == &iio_dev_attr_oversampling_ratio.dev_attr.attr || + attr == + &iio_const_attr_oversampling_ratio_available.dev_attr.attr)) + mode = 0; + else if (!st->have_range && + (attr == &iio_dev_attr_range.dev_attr.attr || + attr == &iio_const_attr_range_available.dev_attr.attr)) + mode = 0; + + return mode; +} + +static const struct attribute_group ad7606_attribute_group = { + .attrs = ad7606_attributes, + .is_visible = ad7606_attr_is_visible, +}; + +static const struct ad7606_chip_info ad7606_chip_info_tbl[] = { + /* + * More devices added in future + */ + [ID_AD7606_8] = { + .name = "ad7606", + .bits = 16, + .sign = IIO_SCAN_EL_TYPE_SIGNED, + .int_vref_mv = 2500, + .num_channels = 8, + }, + [ID_AD7606_6] = { + .name = "ad7606-6", + .bits = 16, + .sign = IIO_SCAN_EL_TYPE_SIGNED, + .int_vref_mv = 2500, + .num_channels = 6, + }, + [ID_AD7606_4] = { + .name = "ad7606-4", + .bits = 16, + .sign = IIO_SCAN_EL_TYPE_SIGNED, + .int_vref_mv = 2500, + .num_channels = 4, + }, +}; + +static int ad7606_request_gpios(struct ad7606_state *st) +{ + struct gpio gpio_array[3] = { + [0] = { + .gpio = st->pdata->gpio_os0, + .flags = GPIOF_DIR_OUT | ((st->oversampling & 1) ? + GPIOF_INIT_HIGH : GPIOF_INIT_LOW), + .label = "AD7606_OS0", + }, + [1] = { + .gpio = st->pdata->gpio_os1, + .flags = GPIOF_DIR_OUT | ((st->oversampling & 2) ? + GPIOF_INIT_HIGH : GPIOF_INIT_LOW), + .label = "AD7606_OS1", + }, + [2] = { + .gpio = st->pdata->gpio_os2, + .flags = GPIOF_DIR_OUT | ((st->oversampling & 4) ? + GPIOF_INIT_HIGH : GPIOF_INIT_LOW), + .label = "AD7606_OS2", + }, + }; + int ret; + + ret = gpio_request_one(st->pdata->gpio_convst, GPIOF_OUT_INIT_LOW, + "AD7606_CONVST"); + if (ret) { + dev_err(st->dev, "failed to request GPIO CONVST\n"); + return ret; + } + + ret = gpio_request_array(gpio_array, ARRAY_SIZE(gpio_array)); + if (!ret) { + st->have_os = true; + } + + ret = gpio_request_one(st->pdata->gpio_reset, GPIOF_OUT_INIT_LOW, + "AD7606_RESET"); + if (!ret) + st->have_reset = true; + + ret = gpio_request_one(st->pdata->gpio_range, GPIOF_DIR_OUT | + ((st->range == 10000) ? GPIOF_INIT_HIGH : + GPIOF_INIT_LOW), "AD7606_RANGE"); + if (!ret) + st->have_range = true; + + ret = gpio_request_one(st->pdata->gpio_stby, GPIOF_OUT_INIT_HIGH, + "AD7606_STBY"); + if (!ret) + st->have_stby = true; + + if (gpio_is_valid(st->pdata->gpio_frstdata)) { + ret = gpio_request_one(st->pdata->gpio_frstdata, GPIOF_IN, + "AD7606_FRSTDATA"); + if (!ret) + st->have_frstdata = true; + } + + return 0; +} + +static void ad7606_free_gpios(struct ad7606_state *st) +{ + if (st->have_range) + gpio_free(st->pdata->gpio_range); + + if (st->have_stby) + gpio_free(st->pdata->gpio_stby); + + if (st->have_os) { + gpio_free(st->pdata->gpio_os0); + gpio_free(st->pdata->gpio_os1); + gpio_free(st->pdata->gpio_os2); + } + + if (st->have_reset) + gpio_free(st->pdata->gpio_reset); + + if (st->have_frstdata) + gpio_free(st->pdata->gpio_frstdata); + + gpio_free(st->pdata->gpio_convst); +} + +/** + * Interrupt handler + */ +static irqreturn_t ad7606_interrupt(int irq, void *dev_id) +{ + struct ad7606_state *st = dev_id; + + if (iio_ring_enabled(st->indio_dev)) { + if (!work_pending(&st->poll_work)) + schedule_work(&st->poll_work); + } else { + st->done = true; + wake_up_interruptible(&st->wq_data_avail); + } + + return IRQ_HANDLED; +}; + +struct ad7606_state *ad7606_probe(struct device *dev, int irq, + void __iomem *base_address, + unsigned id, + const struct ad7606_bus_ops *bops) +{ + struct ad7606_platform_data *pdata = dev->platform_data; + struct ad7606_state *st; + int ret; + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + st->dev = dev; + st->id = id; + st->irq = irq; + st->bops = bops; + st->base_address = base_address; + st->range = pdata->default_range == 10000 ? 10000 : 5000; + + ret = ad7606_oversampling_get_index(pdata->default_os); + if (ret < 0) { + dev_warn(dev, "oversampling %d is not supported\n", + pdata->default_os); + st->oversampling = 0; + } else { + st->oversampling = pdata->default_os; + } + + st->reg = regulator_get(dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + } + + st->pdata = pdata; + st->chip_info = &ad7606_chip_info_tbl[id]; + + atomic_set(&st->protect_ring, 0); + + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_disable_reg; + } + + st->indio_dev->dev.parent = dev; + st->indio_dev->attrs = &ad7606_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + init_waitqueue_head(&st->wq_data_avail); + + ret = ad7606_request_gpios(st); + if (ret) + goto error_free_device; + + ret = ad7606_reset(st); + if (ret) + dev_warn(st->dev, "failed to RESET: no RESET GPIO specified\n"); + + ret = request_irq(st->irq, ad7606_interrupt, + IRQF_TRIGGER_FALLING, st->chip_info->name, st); + if (ret) + goto error_free_gpios; + + ret = ad7606_register_ring_funcs_and_init(st->indio_dev); + if (ret) + goto error_free_irq; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_free_irq; + + ret = iio_ring_buffer_register(st->indio_dev->ring, 0); + if (ret) + goto error_cleanup_ring; + + return st; + +error_cleanup_ring: + ad7606_ring_cleanup(st->indio_dev); + iio_device_unregister(st->indio_dev); + +error_free_irq: + free_irq(st->irq, st); + +error_free_gpios: + ad7606_free_gpios(st); + +error_free_device: + iio_free_device(st->indio_dev); + +error_disable_reg: + if (!IS_ERR(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR(st->reg)) + regulator_put(st->reg); + kfree(st); +error_ret: + return ERR_PTR(ret); +} + +int ad7606_remove(struct ad7606_state *st) +{ + struct iio_dev *indio_dev = st->indio_dev; + iio_ring_buffer_unregister(indio_dev->ring); + ad7606_ring_cleanup(indio_dev); + iio_device_unregister(indio_dev); + free_irq(st->irq, st); + if (!IS_ERR(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + + ad7606_free_gpios(st); + + kfree(st); + return 0; +} + +void ad7606_suspend(struct ad7606_state *st) +{ + if (st->have_stby) { + if (st->have_range) + gpio_set_value(st->pdata->gpio_range, 1); + gpio_set_value(st->pdata->gpio_stby, 0); + } +} + +void ad7606_resume(struct ad7606_state *st) +{ + if (st->have_stby) { + if (st->have_range) + gpio_set_value(st->pdata->gpio_range, + st->range == 10000); + + gpio_set_value(st->pdata->gpio_stby, 1); + ad7606_reset(st); + } +} + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD7606 ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/ad7606_par.c b/drivers/staging/iio/adc/ad7606_par.c new file mode 100644 index 000000000000..43a554ce753d --- /dev/null +++ b/drivers/staging/iio/adc/ad7606_par.c @@ -0,0 +1,188 @@ +/* + * AD7606 Parallel Interface ADC driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include + +#include "ad7606.h" + +static int ad7606_par16_read_block(struct device *dev, + int count, void *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct ad7606_state *st = platform_get_drvdata(pdev); + + insw((unsigned long) st->base_address, buf, count); + + return 0; +} + +static const struct ad7606_bus_ops ad7606_par16_bops = { + .read_block = ad7606_par16_read_block, +}; + +static int ad7606_par8_read_block(struct device *dev, + int count, void *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct ad7606_state *st = platform_get_drvdata(pdev); + + insb((unsigned long) st->base_address, buf, count * 2); + + return 0; +} + +static const struct ad7606_bus_ops ad7606_par8_bops = { + .read_block = ad7606_par8_read_block, +}; + +static int __devinit ad7606_par_probe(struct platform_device *pdev) +{ + struct resource *res; + struct ad7606_state *st; + void __iomem *addr; + resource_size_t remap_size; + int ret, irq; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "no irq\n"); + return -ENODEV; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + remap_size = resource_size(res); + + /* Request the regions */ + if (!request_mem_region(res->start, remap_size, "iio-ad7606")) { + ret = -EBUSY; + goto out1; + } + addr = ioremap(res->start, remap_size); + if (!addr) { + ret = -ENOMEM; + goto out1; + } + + st = ad7606_probe(&pdev->dev, irq, addr, + platform_get_device_id(pdev)->driver_data, + remap_size > 1 ? &ad7606_par16_bops : + &ad7606_par8_bops); + + if (IS_ERR(st)) { + ret = PTR_ERR(st); + goto out2; + } + + platform_set_drvdata(pdev, st); + + return 0; + +out2: + iounmap(addr); +out1: + release_mem_region(res->start, remap_size); + + return ret; +} + +static int __devexit ad7606_par_remove(struct platform_device *pdev) +{ + struct ad7606_state *st = platform_get_drvdata(pdev); + struct resource *res; + + ad7606_remove(st); + + iounmap(st->base_address); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(res->start, resource_size(res)); + + platform_set_drvdata(pdev, NULL); + + return 0; +} + +#ifdef CONFIG_PM +static int ad7606_par_suspend(struct device *dev) +{ + struct ad7606_state *st = dev_get_drvdata(dev); + + ad7606_suspend(st); + + return 0; +} + +static int ad7606_par_resume(struct device *dev) +{ + struct ad7606_state *st = dev_get_drvdata(dev); + + ad7606_resume(st); + + return 0; +} + +static const struct dev_pm_ops ad7606_pm_ops = { + .suspend = ad7606_par_suspend, + .resume = ad7606_par_resume, +}; +#define AD7606_PAR_PM_OPS (&ad7606_pm_ops) + +#else +#define AD7606_PAR_PM_OPS NULL +#endif /* CONFIG_PM */ + +static struct platform_device_id ad7606_driver_ids[] = { + { + .name = "ad7606-8", + .driver_data = ID_AD7606_8, + }, { + .name = "ad7606-6", + .driver_data = ID_AD7606_6, + }, { + .name = "ad7606-4", + .driver_data = ID_AD7606_4, + }, + { } +}; + +MODULE_DEVICE_TABLE(platform, ad7606_driver_ids); + +static struct platform_driver ad7606_driver = { + .probe = ad7606_par_probe, + .remove = __devexit_p(ad7606_par_remove), + .id_table = ad7606_driver_ids, + .driver = { + .name = "ad7606", + .owner = THIS_MODULE, + .pm = AD7606_PAR_PM_OPS, + }, +}; + +static int __init ad7606_init(void) +{ + return platform_driver_register(&ad7606_driver); +} + +static void __exit ad7606_cleanup(void) +{ + platform_driver_unregister(&ad7606_driver); +} + +module_init(ad7606_init); +module_exit(ad7606_cleanup); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD7606 ADC"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:ad7606_par"); diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c new file mode 100644 index 000000000000..9889680232d8 --- /dev/null +++ b/drivers/staging/iio/adc/ad7606_ring.c @@ -0,0 +1,266 @@ +/* + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../ring_generic.h" +#include "../ring_sw.h" +#include "../trigger.h" +#include "../sysfs.h" + +#include "ad7606.h" + +static IIO_SCAN_EL_C(in0, 0, 0, NULL); +static IIO_SCAN_EL_C(in1, 1, 0, NULL); +static IIO_SCAN_EL_C(in2, 2, 0, NULL); +static IIO_SCAN_EL_C(in3, 3, 0, NULL); +static IIO_SCAN_EL_C(in4, 4, 0, NULL); +static IIO_SCAN_EL_C(in5, 5, 0, NULL); +static IIO_SCAN_EL_C(in6, 6, 0, NULL); +static IIO_SCAN_EL_C(in7, 7, 0, NULL); + +static ssize_t ad7606_show_type(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_ring_buffer *ring = dev_get_drvdata(dev); + struct iio_dev *indio_dev = ring->indio_dev; + struct ad7606_state *st = indio_dev->dev_data; + + return sprintf(buf, "%c%d/%d\n", st->chip_info->sign, + st->chip_info->bits, st->chip_info->bits); +} +static IIO_DEVICE_ATTR(in_type, S_IRUGO, ad7606_show_type, NULL, 0); + +static struct attribute *ad7606_scan_el_attrs[] = { + &iio_scan_el_in0.dev_attr.attr, + &iio_const_attr_in0_index.dev_attr.attr, + &iio_scan_el_in1.dev_attr.attr, + &iio_const_attr_in1_index.dev_attr.attr, + &iio_scan_el_in2.dev_attr.attr, + &iio_const_attr_in2_index.dev_attr.attr, + &iio_scan_el_in3.dev_attr.attr, + &iio_const_attr_in3_index.dev_attr.attr, + &iio_scan_el_in4.dev_attr.attr, + &iio_const_attr_in4_index.dev_attr.attr, + &iio_scan_el_in5.dev_attr.attr, + &iio_const_attr_in5_index.dev_attr.attr, + &iio_scan_el_in6.dev_attr.attr, + &iio_const_attr_in6_index.dev_attr.attr, + &iio_scan_el_in7.dev_attr.attr, + &iio_const_attr_in7_index.dev_attr.attr, + &iio_dev_attr_in_type.dev_attr.attr, + NULL, +}; + +static mode_t ad7606_scan_el_attr_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct iio_ring_buffer *ring = dev_get_drvdata(dev); + struct iio_dev *indio_dev = ring->indio_dev; + struct ad7606_state *st = indio_dev->dev_data; + + mode_t mode = attr->mode; + + if (st->chip_info->num_channels <= 6 && + (attr == &iio_scan_el_in7.dev_attr.attr || + attr == &iio_const_attr_in7_index.dev_attr.attr || + attr == &iio_scan_el_in6.dev_attr.attr || + attr == &iio_const_attr_in6_index.dev_attr.attr)) + mode = 0; + else if (st->chip_info->num_channels <= 4 && + (attr == &iio_scan_el_in5.dev_attr.attr || + attr == &iio_const_attr_in5_index.dev_attr.attr || + attr == &iio_scan_el_in4.dev_attr.attr || + attr == &iio_const_attr_in4_index.dev_attr.attr)) + mode = 0; + + return mode; +} + +static struct attribute_group ad7606_scan_el_group = { + .name = "scan_elements", + .attrs = ad7606_scan_el_attrs, + .is_visible = ad7606_scan_el_attr_is_visible, +}; + +int ad7606_scan_from_ring(struct ad7606_state *st, unsigned ch) +{ + struct iio_ring_buffer *ring = st->indio_dev->ring; + int ret; + u16 *ring_data; + + ring_data = kmalloc(ring->access.get_bytes_per_datum(ring), GFP_KERNEL); + if (ring_data == NULL) { + ret = -ENOMEM; + goto error_ret; + } + ret = ring->access.read_last(ring, (u8 *) ring_data); + if (ret) + goto error_free_ring_data; + + ret = ring_data[ch]; + +error_free_ring_data: + kfree(ring_data); +error_ret: + return ret; +} + +/** + * ad7606_ring_preenable() setup the parameters of the ring before enabling + * + * The complex nature of the setting of the nuber of bytes per datum is due + * to this driver currently ensuring that the timestamp is stored at an 8 + * byte boundary. + **/ +static int ad7606_ring_preenable(struct iio_dev *indio_dev) +{ + struct ad7606_state *st = indio_dev->dev_data; + struct iio_ring_buffer *ring = indio_dev->ring; + size_t d_size; + + d_size = st->chip_info->num_channels * + st->chip_info->bits / 8 + sizeof(s64); + + if (d_size % sizeof(s64)) + d_size += sizeof(s64) - (d_size % sizeof(s64)); + + if (ring->access.set_bytes_per_datum) + ring->access.set_bytes_per_datum(ring, d_size); + + st->d_size = d_size; + + return 0; +} + +/** + * ad7606_poll_func_th() th of trigger launched polling to ring buffer + * + **/ +static void ad7606_poll_func_th(struct iio_dev *indio_dev, s64 time) +{ + struct ad7606_state *st = indio_dev->dev_data; + gpio_set_value(st->pdata->gpio_convst, 1); + + return; +} +/** + * ad7606_poll_bh_to_ring() bh of trigger launched polling to ring buffer + * @work_s: the work struct through which this was scheduled + * + * Currently there is no option in this driver to disable the saving of + * timestamps within the ring. + * I think the one copy of this at a time was to avoid problems if the + * trigger was set far too high and the reads then locked up the computer. + **/ +static void ad7606_poll_bh_to_ring(struct work_struct *work_s) +{ + struct ad7606_state *st = container_of(work_s, struct ad7606_state, + poll_work); + struct iio_dev *indio_dev = st->indio_dev; + struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring); + struct iio_ring_buffer *ring = indio_dev->ring; + s64 time_ns; + __u8 *buf; + int ret; + + /* Ensure only one copy of this function running at a time */ + if (atomic_inc_return(&st->protect_ring) > 1) + return; + + buf = kzalloc(st->d_size, GFP_KERNEL); + if (buf == NULL) + return; + + if (st->have_frstdata) { + ret = st->bops->read_block(st->dev, 1, buf); + if (ret) + goto done; + if (!gpio_get_value(st->pdata->gpio_frstdata)) { + /* This should never happen. However + * some signal glitch caused by bad PCB desgin or + * electrostatic discharge, could cause an extra read + * or clock. This allows recovery. + */ + ad7606_reset(st); + goto done; + } + ret = st->bops->read_block(st->dev, + st->chip_info->num_channels - 1, buf + 2); + if (ret) + goto done; + } else { + ret = st->bops->read_block(st->dev, + st->chip_info->num_channels, buf); + if (ret) + goto done; + } + + time_ns = iio_get_time_ns(); + memcpy(buf + st->d_size - sizeof(s64), &time_ns, sizeof(time_ns)); + + ring->access.store_to(&sw_ring->buf, buf, time_ns); +done: + gpio_set_value(st->pdata->gpio_convst, 0); + kfree(buf); + atomic_dec(&st->protect_ring); +} + +int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev) +{ + struct ad7606_state *st = indio_dev->dev_data; + int ret; + + indio_dev->ring = iio_sw_rb_allocate(indio_dev); + if (!indio_dev->ring) { + ret = -ENOMEM; + goto error_ret; + } + + /* Effectively select the ring buffer implementation */ + iio_ring_sw_register_funcs(&indio_dev->ring->access); + ret = iio_alloc_pollfunc(indio_dev, NULL, &ad7606_poll_func_th); + if (ret) + goto error_deallocate_sw_rb; + + /* Ring buffer functions - here trigger setup related */ + + indio_dev->ring->preenable = &ad7606_ring_preenable; + indio_dev->ring->postenable = &iio_triggered_ring_postenable; + indio_dev->ring->predisable = &iio_triggered_ring_predisable; + indio_dev->ring->scan_el_attrs = &ad7606_scan_el_group; + + INIT_WORK(&st->poll_work, &ad7606_poll_bh_to_ring); + + /* Flag that polled ring buffering is possible */ + indio_dev->modes |= INDIO_RING_TRIGGERED; + return 0; +error_deallocate_sw_rb: + iio_sw_rb_free(indio_dev->ring); +error_ret: + return ret; +} + +void ad7606_ring_cleanup(struct iio_dev *indio_dev) +{ + if (indio_dev->trig) { + iio_put_trigger(indio_dev->trig); + iio_trigger_dettach_poll_func(indio_dev->trig, + indio_dev->pollfunc); + } + kfree(indio_dev->pollfunc); + iio_sw_rb_free(indio_dev->ring); +} diff --git a/drivers/staging/iio/adc/ad7606_spi.c b/drivers/staging/iio/adc/ad7606_spi.c new file mode 100644 index 000000000000..d738491222f2 --- /dev/null +++ b/drivers/staging/iio/adc/ad7606_spi.c @@ -0,0 +1,126 @@ +/* + * AD7606 SPI ADC driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include "ad7606.h" + +#define MAX_SPI_FREQ_HZ 23500000 /* VDRIVE above 4.75 V */ + +static int ad7606_spi_read_block(struct device *dev, + int count, void *buf) +{ + struct spi_device *spi = to_spi_device(dev); + int i, ret; + unsigned short *data = buf; + + ret = spi_read(spi, (u8 *)buf, count * 2); + if (ret < 0) { + dev_err(&spi->dev, "SPI read error\n"); + return ret; + } + + for (i = 0; i < count; i++) + data[i] = be16_to_cpu(data[i]); + + return 0; +} + +static const struct ad7606_bus_ops ad7606_spi_bops = { + .read_block = ad7606_spi_read_block, +}; + +static int __devinit ad7606_spi_probe(struct spi_device *spi) +{ + struct ad7606_state *st; + + st = ad7606_probe(&spi->dev, spi->irq, NULL, + spi_get_device_id(spi)->driver_data, + &ad7606_spi_bops); + + if (IS_ERR(st)) + return PTR_ERR(st); + + spi_set_drvdata(spi, st); + + return 0; +} + +static int __devexit ad7606_spi_remove(struct spi_device *spi) +{ + struct ad7606_state *st = dev_get_drvdata(&spi->dev); + + return ad7606_remove(st); +} + +#ifdef CONFIG_PM +static int ad7606_spi_suspend(struct device *dev) +{ + struct ad7606_state *st = dev_get_drvdata(dev); + + ad7606_suspend(st); + + return 0; +} + +static int ad7606_spi_resume(struct device *dev) +{ + struct ad7606_state *st = dev_get_drvdata(dev); + + ad7606_resume(st); + + return 0; +} + +static const struct dev_pm_ops ad7606_pm_ops = { + .suspend = ad7606_spi_suspend, + .resume = ad7606_spi_resume, +}; +#define AD7606_SPI_PM_OPS (&ad7606_pm_ops) + +#else +#define AD7606_SPI_PM_OPS NULL +#endif + +static const struct spi_device_id ad7606_id[] = { + {"ad7606-8", ID_AD7606_8}, + {"ad7606-6", ID_AD7606_6}, + {"ad7606-4", ID_AD7606_4}, + {} +}; + +static struct spi_driver ad7606_driver = { + .driver = { + .name = "ad7606", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + .pm = AD7606_SPI_PM_OPS, + }, + .probe = ad7606_spi_probe, + .remove = __devexit_p(ad7606_spi_remove), + .id_table = ad7606_id, +}; + +static int __init ad7606_spi_init(void) +{ + return spi_register_driver(&ad7606_driver); +} +module_init(ad7606_spi_init); + +static void __exit ad7606_spi_exit(void) +{ + spi_unregister_driver(&ad7606_driver); +} +module_exit(ad7606_spi_exit); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD7606 ADC"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("spi:ad7606_spi"); -- cgit v1.2.3 From 0772268aa98fce8a5931f8a39049658465319f3e Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Wed, 23 Feb 2011 10:45:47 +0100 Subject: staging: IIO: DAC: Add support for the AD5543/AD5553 Add support for the AD5543/AD5553 SPI 16-/14-Bit DACs Fix typo in kconfig description Changes since V1: reorder Kconfig help text Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/Kconfig | 4 ++-- drivers/staging/iio/dac/ad5446.c | 12 ++++++++++++ drivers/staging/iio/dac/ad5446.h | 2 ++ 3 files changed, 16 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/dac/Kconfig b/drivers/staging/iio/dac/Kconfig index 2120904ae85d..3c72871389a2 100644 --- a/drivers/staging/iio/dac/Kconfig +++ b/drivers/staging/iio/dac/Kconfig @@ -11,11 +11,11 @@ config AD5624R_SPI AD5664R convertors (DAC). This driver uses the common SPI interface. config AD5446 - tristate "Analog Devices AD5444/6, AD5620/40/60 and AD5541A/12A DAC SPI driver" + tristate "Analog Devices AD5444/6, AD5620/40/60 and AD5542A/12A DAC SPI driver" depends on SPI help Say yes here to build support for Analog Devices AD5444, AD5446, - AD5620, AD5640, AD5660 and AD5541A, AD5512A DACs. + AD5512A, AD5542A, AD5543, AD5553, AD5620, AD5640, AD5660 DACs. To compile this driver as a module, choose M here: the module will be called ad5446. diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index 0f87ecac82fc..dcec29733807 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -132,12 +132,24 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { .left_shift = 0, .store_sample = ad5542_store_sample, }, + [ID_AD5543] = { + .bits = 16, + .storagebits = 16, + .left_shift = 0, + .store_sample = ad5542_store_sample, + }, [ID_AD5512A] = { .bits = 12, .storagebits = 16, .left_shift = 4, .store_sample = ad5542_store_sample, }, + [ID_AD5553] = { + .bits = 14, + .storagebits = 16, + .left_shift = 0, + .store_sample = ad5542_store_sample, + }, [ID_AD5620_2500] = { .bits = 12, .storagebits = 16, diff --git a/drivers/staging/iio/dac/ad5446.h b/drivers/staging/iio/dac/ad5446.h index 902542e22c4a..0cb9c14279e6 100644 --- a/drivers/staging/iio/dac/ad5446.h +++ b/drivers/staging/iio/dac/ad5446.h @@ -84,7 +84,9 @@ enum ad5446_supported_device_ids { ID_AD5444, ID_AD5446, ID_AD5542A, + ID_AD5543, ID_AD5512A, + ID_AD5553, ID_AD5620_2500, ID_AD5620_1250, ID_AD5640_2500, -- cgit v1.2.3 From ea5dbf96dbbfa4cf29925e82af3a0a613079b1bd Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Wed, 23 Feb 2011 12:33:12 +0100 Subject: staging: IIO: trigger: New Blackfin specific trigger driver iio-trig-bfin-timer This driver allows any Blackfin system timer to be used as IIO trigger. It supports trigger rates from 0 to 100kHz in Hz resolution. Changes since V1: IIO: trigger: Apply review feedback Add comment explaining Blackfin hardware timer configurations Fix frequency_store, don't return -EINVAL for frequency set to 0 Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/trigger/Kconfig | 10 + drivers/staging/iio/trigger/Makefile | 1 + drivers/staging/iio/trigger/iio-trig-bfin-timer.c | 252 ++++++++++++++++++++++ 3 files changed, 263 insertions(+) create mode 100644 drivers/staging/iio/trigger/iio-trig-bfin-timer.c (limited to 'drivers') diff --git a/drivers/staging/iio/trigger/Kconfig b/drivers/staging/iio/trigger/Kconfig index 3a82013e2b8b..c33777e0a8b3 100644 --- a/drivers/staging/iio/trigger/Kconfig +++ b/drivers/staging/iio/trigger/Kconfig @@ -28,4 +28,14 @@ config IIO_SYSFS_TRIGGER To compile this driver as a module, choose M here: the module will be called iio-trig-sysfs. +config IIO_BFIN_TMR_TRIGGER + tristate "Blackfin TIMER trigger" + depends on BLACKFIN + help + Provides support for using a Blackfin timer as IIO triggers. + If unsure, say N (but it's safe to say "Y"). + + To compile this driver as a module, choose M here: the + module will be called iio-trig-bfin-timer. + endif # IIO_TRIGGER diff --git a/drivers/staging/iio/trigger/Makefile b/drivers/staging/iio/trigger/Makefile index 504b9c07970c..b088b57da335 100644 --- a/drivers/staging/iio/trigger/Makefile +++ b/drivers/staging/iio/trigger/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_IIO_PERIODIC_RTC_TRIGGER) += iio-trig-periodic-rtc.o obj-$(CONFIG_IIO_GPIO_TRIGGER) += iio-trig-gpio.o obj-$(CONFIG_IIO_SYSFS_TRIGGER) += iio-trig-sysfs.o +obj-$(CONFIG_IIO_BFIN_TMR_TRIGGER) += iio-trig-bfin-timer.o diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c new file mode 100644 index 000000000000..583bef0936e8 --- /dev/null +++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c @@ -0,0 +1,252 @@ +/* + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../iio.h" +#include "../trigger.h" + +struct bfin_timer { + unsigned short id, bit; + unsigned long irqbit; + int irq; +}; + +/* + * this covers all hardware timer configurations on + * all Blackfin derivatives out there today + */ + +static struct bfin_timer iio_bfin_timer_code[MAX_BLACKFIN_GPTIMERS] = { + {TIMER0_id, TIMER0bit, TIMER_STATUS_TIMIL0, IRQ_TIMER0}, + {TIMER1_id, TIMER1bit, TIMER_STATUS_TIMIL1, IRQ_TIMER1}, + {TIMER2_id, TIMER2bit, TIMER_STATUS_TIMIL2, IRQ_TIMER2}, +#if (MAX_BLACKFIN_GPTIMERS > 3) + {TIMER3_id, TIMER3bit, TIMER_STATUS_TIMIL3, IRQ_TIMER3}, + {TIMER4_id, TIMER4bit, TIMER_STATUS_TIMIL4, IRQ_TIMER4}, + {TIMER5_id, TIMER5bit, TIMER_STATUS_TIMIL5, IRQ_TIMER5}, + {TIMER6_id, TIMER6bit, TIMER_STATUS_TIMIL6, IRQ_TIMER6}, + {TIMER7_id, TIMER7bit, TIMER_STATUS_TIMIL7, IRQ_TIMER7}, +#endif +#if (MAX_BLACKFIN_GPTIMERS > 8) + {TIMER8_id, TIMER8bit, TIMER_STATUS_TIMIL8, IRQ_TIMER8}, + {TIMER9_id, TIMER9bit, TIMER_STATUS_TIMIL9, IRQ_TIMER9}, + {TIMER10_id, TIMER10bit, TIMER_STATUS_TIMIL10, IRQ_TIMER10}, +#if (MAX_BLACKFIN_GPTIMERS > 11) + {TIMER11_id, TIMER11bit, TIMER_STATUS_TIMIL11, IRQ_TIMER11}, +#endif +#endif +}; + +struct bfin_tmr_state { + struct iio_trigger *trig; + struct bfin_timer *t; + unsigned timer_num; + int irq; +}; + +static ssize_t iio_bfin_tmr_frequency_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct iio_trigger *trig = dev_get_drvdata(dev); + struct bfin_tmr_state *st = trig->private_data; + long val; + int ret; + + ret = strict_strtoul(buf, 10, &val); + if (ret) + goto error_ret; + + if (val > 100000) { + ret = -EINVAL; + goto error_ret; + } + + disable_gptimers(st->t->bit); + + if (!val) + goto error_ret; + + val = get_sclk() / val; + if (val <= 4) { + ret = -EINVAL; + goto error_ret; + } + + set_gptimer_period(st->t->id, val); + set_gptimer_pwidth(st->t->id, 1); + enable_gptimers(st->t->bit); + +error_ret: + return ret ? ret : count; +} + +static ssize_t iio_bfin_tmr_frequency_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_trigger *trig = dev_get_drvdata(dev); + struct bfin_tmr_state *st = trig->private_data; + + return sprintf(buf, "%lu\n", + get_sclk() / get_gptimer_period(st->t->id)); +} + +static DEVICE_ATTR(frequency, S_IRUGO | S_IWUSR, iio_bfin_tmr_frequency_show, + iio_bfin_tmr_frequency_store); +static IIO_TRIGGER_NAME_ATTR; + +static struct attribute *iio_bfin_tmr_trigger_attrs[] = { + &dev_attr_frequency.attr, + &dev_attr_name.attr, + NULL, +}; + +static const struct attribute_group iio_bfin_tmr_trigger_attr_group = { + .attrs = iio_bfin_tmr_trigger_attrs, +}; + + +static irqreturn_t iio_bfin_tmr_trigger_isr(int irq, void *devid) +{ + struct bfin_tmr_state *st = devid; + + clear_gptimer_intr(st->t->id); + iio_trigger_poll(st->trig, 0); + + return IRQ_HANDLED; +} + +static int iio_bfin_tmr_get_number(int irq) +{ + int i; + + for (i = 0; i < MAX_BLACKFIN_GPTIMERS; i++) + if (iio_bfin_timer_code[i].irq == irq) + return i; + + return -ENODEV; +} + +static int __devinit iio_bfin_tmr_trigger_probe(struct platform_device *pdev) +{ + struct bfin_tmr_state *st; + int ret; + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) { + ret = -ENOMEM; + goto out; + } + + st->irq = platform_get_irq(pdev, 0); + if (!st->irq) { + dev_err(&pdev->dev, "No IRQs specified"); + ret = -ENODEV; + goto out1; + } + + ret = iio_bfin_tmr_get_number(st->irq); + if (ret < 0) + goto out1; + + st->timer_num = ret; + st->t = &iio_bfin_timer_code[st->timer_num]; + + st->trig = iio_allocate_trigger(); + if (!st->trig) { + ret = -ENOMEM; + goto out1; + } + + st->trig->private_data = st; + st->trig->control_attrs = &iio_bfin_tmr_trigger_attr_group; + st->trig->owner = THIS_MODULE; + st->trig->name = kasprintf(GFP_KERNEL, "bfintmr%d", st->timer_num); + if (st->trig->name == NULL) { + ret = -ENOMEM; + goto out2; + } + + ret = iio_trigger_register(st->trig); + if (ret) + goto out3; + + ret = request_irq(st->irq, iio_bfin_tmr_trigger_isr, + 0, st->trig->name, st); + if (ret) { + dev_err(&pdev->dev, + "request IRQ-%d failed", st->irq); + goto out4; + } + + set_gptimer_config(st->t->id, OUT_DIS | PWM_OUT | PERIOD_CNT | IRQ_ENA); + + dev_info(&pdev->dev, "iio trigger Blackfin TMR%d, IRQ-%d", + st->timer_num, st->irq); + platform_set_drvdata(pdev, st); + + return 0; +out4: + iio_trigger_unregister(st->trig); +out3: + kfree(st->trig->name); +out2: + iio_put_trigger(st->trig); +out1: + kfree(st); +out: + return ret; +} + +static int __devexit iio_bfin_tmr_trigger_remove(struct platform_device *pdev) +{ + struct bfin_tmr_state *st = platform_get_drvdata(pdev); + + disable_gptimers(st->t->bit); + free_irq(st->irq, st); + iio_trigger_unregister(st->trig); + kfree(st->trig->name); + iio_put_trigger(st->trig); + kfree(st); + + return 0; +} + +static struct platform_driver iio_bfin_tmr_trigger_driver = { + .driver = { + .name = "iio_bfin_tmr_trigger", + .owner = THIS_MODULE, + }, + .probe = iio_bfin_tmr_trigger_probe, + .remove = __devexit_p(iio_bfin_tmr_trigger_remove), +}; + +static int __init iio_bfin_tmr_trig_init(void) +{ + return platform_driver_register(&iio_bfin_tmr_trigger_driver); +} +module_init(iio_bfin_tmr_trig_init); + +static void __exit iio_bfin_tmr_trig_exit(void) +{ + platform_driver_unregister(&iio_bfin_tmr_trigger_driver); +} +module_exit(iio_bfin_tmr_trig_exit); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Blackfin system timer based trigger for the iio subsystem"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:iio-trig-bfin-timer"); -- cgit v1.2.3 From 6012795b13cd15b1e2216dc8558461ce99aecc30 Mon Sep 17 00:00:00 2001 From: Manohar Vanga Date: Wed, 23 Feb 2011 14:25:27 +0100 Subject: staging: vme: remove unreachable code Removed some unreachable code from vme_register_bridge Signed-off-by: Manohar Vanga Acked-by: Martyn Welch Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/vme.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c index d9fc8644376e..88bf45520125 100644 --- a/drivers/staging/vme/vme.c +++ b/drivers/staging/vme/vme.c @@ -1363,7 +1363,6 @@ int vme_register_bridge(struct vme_bridge *bridge) return retval; - i = VME_SLOTS_MAX; err_reg: while (i > -1) { dev = &bridge->dev[i]; -- cgit v1.2.3 From da1bbd1d85ca4b68c58986f997f859327fd7f648 Mon Sep 17 00:00:00 2001 From: Manohar Vanga Date: Wed, 23 Feb 2011 14:25:28 +0100 Subject: staging: vme: fix loop condition Fix loop condition in vme_register_bridge that results in an infinite loop in the event that device_register fails. Signed-off-by: Manohar Vanga Acked-by: Martyn Welch Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/vme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c index 88bf45520125..c1ec230f005a 100644 --- a/drivers/staging/vme/vme.c +++ b/drivers/staging/vme/vme.c @@ -1364,7 +1364,7 @@ int vme_register_bridge(struct vme_bridge *bridge) return retval; err_reg: - while (i > -1) { + while (--i >= 0) { dev = &bridge->dev[i]; device_unregister(dev); } -- cgit v1.2.3 From c2e0eb167070a6e9dcb49c84c13c79a30d672431 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 22 Feb 2011 18:25:49 +0100 Subject: drm/i915: fix corruptions on i8xx due to relaxed fencing It looks like gen2 has a peculiar interleaved 2-row inter-tile layout. Probably inherited from i81x which had 2kb tiles (which naturally fit an even-number-of-tile-rows scheme to fit onto 4kb pages). There is no other mention of this in any docs (also not in the Intel internal documention according to Chris Wilson). Problem manifests itself in corruptions in the second half of the last tile row (if the bo has an odd number of tiles). Which can only happen with relaxed tiling (introduced in a00b10c360b35d6431a9). So reject set_tiling calls that don't satisfy this constrain to prevent broken userspace from causing havoc. While at it, also check the size for newer chipsets. LKML: https://lkml.org/lkml/2011/2/19/5 Reported-by: Indan Zupancic Tested-by: Indan Zupancic Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem_tiling.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 22a32b9932c5..79a04fde69b5 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -184,7 +184,7 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) static bool i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) { - int tile_width; + int tile_width, tile_height; /* Linear is always fine */ if (tiling_mode == I915_TILING_NONE) @@ -215,6 +215,20 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) } } + if (IS_GEN2(dev) || + (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))) + tile_height = 32; + else + tile_height = 8; + /* i8xx is strange: It has 2 interleaved rows of tiles, so needs an even + * number of tile rows. */ + if (IS_GEN2(dev)) + tile_height *= 2; + + /* Size needs to be aligned to a full tile row */ + if (size & (tile_height * stride - 1)) + return false; + /* 965+ just needs multiples of tile width */ if (INTEL_INFO(dev)->gen >= 4) { if (stride & (tile_width - 1)) -- cgit v1.2.3 From 78794b2cdeac37ac1fd950fc9c4454b56d88ac03 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 23 Feb 2011 19:42:03 -0800 Subject: Revert "Bluetooth: Enable USB autosuspend by default on btusb" This reverts commit 556ea928f78a390fe16ae584e6433dff304d3014. Jeff Chua reports that it can cause some bluetooth devices (he mentions an Bluetooth Intermec scanner) to just stop responding after a while with messages like [ 4533.361959] btusb 8-1:1.0: no reset_resume for driver btusb? [ 4533.361964] btusb 8-1:1.1: no reset_resume for driver btusb? from the kernel. See also https://bugzilla.kernel.org/show_bug.cgi?id=26182 for other reports. Reported-by: Jeff Chua Reported-by: Andrew Meakovski Reported-by: Jim Faulkner Acked-by: Greg KH Acked-by: Matthew Garrett Acked-by: Gustavo F. Padovan Cc: stable@kernel.org (for 2.6.37) Signed-off-by: Linus Torvalds --- drivers/bluetooth/btusb.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index b7f2f373c631..700a3840fddc 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -1044,8 +1044,6 @@ static int btusb_probe(struct usb_interface *intf, usb_set_intfdata(intf, data); - usb_enable_autosuspend(interface_to_usbdev(intf)); - return 0; } -- cgit v1.2.3 From 93b270f76e7ef3b81001576860c2701931cdc78b Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 24 Feb 2011 17:25:47 +1100 Subject: Fix over-zealous flush_disk when changing device size. There are two cases when we call flush_disk. In one, the device has disappeared (check_disk_change) so any data will hold becomes irrelevant. In the oter, the device has changed size (check_disk_size_change) so data we hold may be irrelevant. In both cases it makes sense to discard any 'clean' buffers, so they will be read back from the device if needed. In the former case it makes sense to discard 'dirty' buffers as there will never be anywhere safe to write the data. In the second case it *does*not* make sense to discard dirty buffers as that will lead to file system corruption when you simply enlarge the containing devices. flush_disk calls __invalidate_devices. __invalidate_device calls both invalidate_inodes and invalidate_bdev. invalidate_inodes *does* discard I_DIRTY inodes and this does lead to fs corruption. invalidate_bev *does*not* discard dirty pages, but I don't really care about that at present. So this patch adds a flag to __invalidate_device (calling it __invalidate_device2) to indicate whether dirty buffers should be killed, and this is passed to invalidate_inodes which can choose to skip dirty inodes. flusk_disk then passes true from check_disk_change and false from check_disk_size_change. dm avoids tripping over this problem by calling i_size_write directly rathher than using check_disk_size_change. md does use check_disk_size_change and so is affected. This regression was introduced by commit 608aeef17a which causes check_disk_size_change to call flush_disk, so it is suitable for any kernel since 2.6.27. Cc: stable@kernel.org Acked-by: Jeff Moyer Cc: Andrew Patterson Cc: Jens Axboe Signed-off-by: NeilBrown --- block/genhd.c | 2 +- drivers/block/floppy.c | 2 +- fs/block_dev.c | 12 ++++++------ fs/inode.c | 9 ++++++++- fs/internal.h | 2 +- include/linux/fs.h | 2 +- 6 files changed, 18 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/block/genhd.c b/block/genhd.c index 6a5b772aa201..cbf1112a885c 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -1355,7 +1355,7 @@ int invalidate_partition(struct gendisk *disk, int partno) struct block_device *bdev = bdget_disk(disk, partno); if (bdev) { fsync_bdev(bdev); - res = __invalidate_device(bdev); + res = __invalidate_device(bdev, true); bdput(bdev); } return res; diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index b9ba04fc2b34..77fc76f8aea9 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -3281,7 +3281,7 @@ static int set_geometry(unsigned int cmd, struct floppy_struct *g, struct block_device *bdev = opened_bdev[cnt]; if (!bdev || ITYPE(drive_state[cnt].fd_device) != type) continue; - __invalidate_device(bdev); + __invalidate_device(bdev, true); } mutex_unlock(&open_lock); } else { diff --git a/fs/block_dev.c b/fs/block_dev.c index 333a7bb4cb9c..5e23152d04ad 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -927,9 +927,9 @@ EXPORT_SYMBOL_GPL(bd_unlink_disk_holder); * when a disk has been changed -- either by a media change or online * resize. */ -static void flush_disk(struct block_device *bdev) +static void flush_disk(struct block_device *bdev, bool kill_dirty) { - if (__invalidate_device(bdev)) { + if (__invalidate_device(bdev, kill_dirty)) { char name[BDEVNAME_SIZE] = ""; if (bdev->bd_disk) @@ -966,7 +966,7 @@ void check_disk_size_change(struct gendisk *disk, struct block_device *bdev) "%s: detected capacity change from %lld to %lld\n", name, bdev_size, disk_size); i_size_write(bdev->bd_inode, disk_size); - flush_disk(bdev); + flush_disk(bdev, false); } } EXPORT_SYMBOL(check_disk_size_change); @@ -1019,7 +1019,7 @@ int check_disk_change(struct block_device *bdev) if (!(events & DISK_EVENT_MEDIA_CHANGE)) return 0; - flush_disk(bdev); + flush_disk(bdev, true); if (bdops->revalidate_disk) bdops->revalidate_disk(bdev->bd_disk); return 1; @@ -1601,7 +1601,7 @@ fail: } EXPORT_SYMBOL(lookup_bdev); -int __invalidate_device(struct block_device *bdev) +int __invalidate_device(struct block_device *bdev, bool kill_dirty) { struct super_block *sb = get_super(bdev); int res = 0; @@ -1614,7 +1614,7 @@ int __invalidate_device(struct block_device *bdev) * hold). */ shrink_dcache_sb(sb); - res = invalidate_inodes(sb); + res = invalidate_inodes(sb, kill_dirty); drop_super(sb); } invalidate_bdev(bdev); diff --git a/fs/inode.c b/fs/inode.c index da85e56378f3..c50d7feb87b1 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -540,11 +540,14 @@ void evict_inodes(struct super_block *sb) /** * invalidate_inodes - attempt to free all inodes on a superblock * @sb: superblock to operate on + * @kill_dirty: flag to guide handling of dirty inodes * * Attempts to free all inodes for a given superblock. If there were any * busy inodes return a non-zero value, else zero. + * If @kill_dirty is set, discard dirty inodes too, otherwise treat + * them as busy. */ -int invalidate_inodes(struct super_block *sb) +int invalidate_inodes(struct super_block *sb, bool kill_dirty) { int busy = 0; struct inode *inode, *next; @@ -556,6 +559,10 @@ int invalidate_inodes(struct super_block *sb) list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) { if (inode->i_state & (I_NEW | I_FREEING | I_WILL_FREE)) continue; + if (inode->i_state & I_DIRTY && !kill_dirty) { + busy = 1; + continue; + } if (atomic_read(&inode->i_count)) { busy = 1; continue; diff --git a/fs/internal.h b/fs/internal.h index 0663568b1247..9b976b57d7fe 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -112,4 +112,4 @@ extern void release_open_intent(struct nameidata *); */ extern int get_nr_dirty_inodes(void); extern void evict_inodes(struct super_block *); -extern int invalidate_inodes(struct super_block *); +extern int invalidate_inodes(struct super_block *, bool); diff --git a/include/linux/fs.h b/include/linux/fs.h index 32b38cd829d3..683f4c566c82 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2139,7 +2139,7 @@ extern void check_disk_size_change(struct gendisk *disk, struct block_device *bdev); extern int revalidate_disk(struct gendisk *); extern int check_disk_change(struct block_device *); -extern int __invalidate_device(struct block_device *); +extern int __invalidate_device(struct block_device *, bool); extern int invalidate_partition(struct gendisk *, int); #endif unsigned long invalidate_mapping_pages(struct address_space *mapping, -- cgit v1.2.3 From f0b4f7e2f29af678bd9af43422c537dcb6008603 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 24 Feb 2011 17:26:41 +1100 Subject: md: Fix - again - partition detection when array becomes active Revert b821eaa572fd737faaf6928ba046e571526c36c6 and f3b99be19ded511a1bf05a148276239d9f13eefa When I wrote the first of these I had a wrong idea about the lifetime of 'struct block_device'. It can disappear at any time that the block device is not open if it falls out of the inode cache. So relying on the 'size' recorded with it to detect when the device size has changed and so we need to revalidate, is wrong. Rather, we really do need the 'changed' attribute stored directly in the mddev and set/tested as appropriate. Without this patch, a sequence of: mknod / open / close / unlink (which can cause a block_device to be created and then destroyed) will result in a rescan of the partition table and consequence removal and addition of partitions. Several of these in a row can get udev racing to create and unlink and other code can get confused. With the patch, the rescan is only performed when needed and so there are no races. This is suitable for any stable kernel from 2.6.35. Reported-by: "Wojcik, Krzysztof" Signed-off-by: NeilBrown Cc: stable@kernel.org --- drivers/md/md.c | 22 +++++++++++++++++++++- drivers/md/md.h | 2 ++ 2 files changed, 23 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 330addfe9b77..818313e277e7 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4627,6 +4627,7 @@ static int do_md_run(mddev_t *mddev) } set_capacity(mddev->gendisk, mddev->array_sectors); revalidate_disk(mddev->gendisk); + mddev->changed = 1; kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE); out: return err; @@ -4715,6 +4716,7 @@ static void md_clean(mddev_t *mddev) mddev->sync_speed_min = mddev->sync_speed_max = 0; mddev->recovery = 0; mddev->in_sync = 0; + mddev->changed = 0; mddev->degraded = 0; mddev->safemode = 0; mddev->bitmap_info.offset = 0; @@ -4830,6 +4832,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) set_capacity(disk, 0); mutex_unlock(&mddev->open_mutex); + mddev->changed = 1; revalidate_disk(disk); if (mddev->ro) @@ -6014,7 +6017,7 @@ static int md_open(struct block_device *bdev, fmode_t mode) atomic_inc(&mddev->openers); mutex_unlock(&mddev->open_mutex); - check_disk_size_change(mddev->gendisk, bdev); + check_disk_change(bdev); out: return err; } @@ -6029,6 +6032,21 @@ static int md_release(struct gendisk *disk, fmode_t mode) return 0; } + +static int md_media_changed(struct gendisk *disk) +{ + mddev_t *mddev = disk->private_data; + + return mddev->changed; +} + +static int md_revalidate(struct gendisk *disk) +{ + mddev_t *mddev = disk->private_data; + + mddev->changed = 0; + return 0; +} static const struct block_device_operations md_fops = { .owner = THIS_MODULE, @@ -6039,6 +6057,8 @@ static const struct block_device_operations md_fops = .compat_ioctl = md_compat_ioctl, #endif .getgeo = md_getgeo, + .media_changed = md_media_changed, + .revalidate_disk= md_revalidate, }; static int md_thread(void * arg) diff --git a/drivers/md/md.h b/drivers/md/md.h index 7e90b8593b2a..12215d437fcc 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -274,6 +274,8 @@ struct mddev_s atomic_t active; /* general refcount */ atomic_t openers; /* number of active opens */ + int changed; /* True if we might need to + * reread partition info */ int degraded; /* whether md should consider * adding a spare */ -- cgit v1.2.3 From e9f9807262083a663829d0154b3da10bafb713bb Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Wed, 26 Jan 2011 01:06:07 +0000 Subject: ixgbe: Enable Jumbo Frames on the X540 10Gigabit Controller The X540 controller supports jumbo frames in SR-IOV mode. Allow configuration of jumbo frames either in the PF driver or on behalf of a VF. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 18 ++++++++++++++++-- drivers/net/ixgbe/ixgbe_sriov.c | 29 ++++++++++++++++++++++++++++- drivers/net/ixgbe/ixgbe_type.h | 2 ++ 3 files changed, 46 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index eca762d954c6..f0d0c5aad2b4 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3077,6 +3077,14 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, ixgbe_configure_srrctl(adapter, ring); ixgbe_configure_rscctl(adapter, ring); + /* If operating in IOV mode set RLPML for X540 */ + if ((adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) && + hw->mac.type == ixgbe_mac_X540) { + rxdctl &= ~IXGBE_RXDCTL_RLPMLMASK; + rxdctl |= ((ring->netdev->mtu + ETH_HLEN + + ETH_FCS_LEN + VLAN_HLEN) | IXGBE_RXDCTL_RLPML_EN); + } + if (hw->mac.type == ixgbe_mac_82598EB) { /* * enable cache line friendly hardware writes: @@ -5441,8 +5449,14 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu) int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; /* MTU < 68 is an error and causes problems on some kernels */ - if ((new_mtu < 68) || (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE)) - return -EINVAL; + if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED && + hw->mac.type != ixgbe_mac_X540) { + if ((new_mtu < 68) || (max_frame > MAXIMUM_ETHERNET_VLAN_SIZE)) + return -EINVAL; + } else { + if ((new_mtu < 68) || (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE)) + return -EINVAL; + } e_info(probe, "changing MTU from %d to %d\n", netdev->mtu, new_mtu); /* must set new MTU before calling down or up */ diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c index 187b3a16ec1f..fb4868d0a32d 100644 --- a/drivers/net/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ixgbe/ixgbe_sriov.c @@ -110,6 +110,33 @@ static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add); } +void ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf) +{ + struct ixgbe_hw *hw = &adapter->hw; + int new_mtu = msgbuf[1]; + u32 max_frs; + int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; + + /* Only X540 supports jumbo frames in IOV mode */ + if (adapter->hw.mac.type != ixgbe_mac_X540) + return; + + /* MTU < 68 is an error and causes problems on some kernels */ + if ((new_mtu < 68) || (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE)) { + e_err(drv, "VF mtu %d out of range\n", new_mtu); + return; + } + + max_frs = (IXGBE_READ_REG(hw, IXGBE_MAXFRS) & + IXGBE_MHADD_MFS_MASK) >> IXGBE_MHADD_MFS_SHIFT; + if (max_frs < new_mtu) { + max_frs = new_mtu << IXGBE_MHADD_MFS_SHIFT; + IXGBE_WRITE_REG(hw, IXGBE_MAXFRS, max_frs); + } + + e_info(hw, "VF requests change max MTU to %d\n", new_mtu); +} + static void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe) { u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf)); @@ -302,7 +329,7 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) hash_list, vf); break; case IXGBE_VF_SET_LPE: - WARN_ON((msgbuf[0] & 0xFFFF) == IXGBE_VF_SET_LPE); + ixgbe_set_vf_lpe(adapter, msgbuf); break; case IXGBE_VF_SET_VLAN: add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index fd3358f54139..ab65d13969fd 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -1680,6 +1680,8 @@ #define IXGBE_RXCTRL_DMBYPS 0x00000002 /* Descriptor Monitor Bypass */ #define IXGBE_RXDCTL_ENABLE 0x02000000 /* Enable specific Rx Queue */ #define IXGBE_RXDCTL_VME 0x40000000 /* VLAN mode enable */ +#define IXGBE_RXDCTL_RLPMLMASK 0x00003FFF /* Only supported on the X540 */ +#define IXGBE_RXDCTL_RLPML_EN 0x00008000 #define IXGBE_FCTRL_SBP 0x00000002 /* Store Bad Packet */ #define IXGBE_FCTRL_MPE 0x00000100 /* Multicast Promiscuous Ena*/ -- cgit v1.2.3 From 69bfbec47d1c120f66f2f24d5f2cb13a72fc88df Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Wed, 26 Jan 2011 01:06:12 +0000 Subject: ixgbevf: Enable jumbo frame support for X540 VF The X540 controller allows jumbo frame setup on a per VF basis. Enable use of jumbo frames when the VF device belongs to the X540 controller. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher --- drivers/net/ixgbevf/defines.h | 2 ++ drivers/net/ixgbevf/ixgbevf_main.c | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbevf/defines.h b/drivers/net/ixgbevf/defines.h index de643eb2ada6..78abb6f1a866 100644 --- a/drivers/net/ixgbevf/defines.h +++ b/drivers/net/ixgbevf/defines.h @@ -65,6 +65,8 @@ typedef u32 ixgbe_link_speed; #define IXGBE_RXCTRL_DMBYPS 0x00000002 /* Descriptor Monitor Bypass */ #define IXGBE_RXDCTL_ENABLE 0x02000000 /* Enable specific Rx Queue */ #define IXGBE_RXDCTL_VME 0x40000000 /* VLAN mode enable */ +#define IXGBE_RXDCTL_RLPMLMASK 0x00003FFF /* Only supported on the X540 */ +#define IXGBE_RXDCTL_RLPML_EN 0x00008000 /* DCA Control */ #define IXGBE_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */ diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 464e6c9d3fc2..1f36f8fb41fc 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -51,7 +51,7 @@ char ixgbevf_driver_name[] = "ixgbevf"; static const char ixgbevf_driver_string[] = "Intel(R) 82599 Virtual Function"; -#define DRV_VERSION "1.0.19-k0" +#define DRV_VERSION "1.1.0-k0" const char ixgbevf_driver_version[] = DRV_VERSION; static char ixgbevf_copyright[] = "Copyright (c) 2009 - 2010 Intel Corporation."; @@ -1665,6 +1665,11 @@ static int ixgbevf_up_complete(struct ixgbevf_adapter *adapter) j = adapter->rx_ring[i].reg_idx; rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(j)); rxdctl |= IXGBE_RXDCTL_ENABLE; + if (hw->mac.type == ixgbe_mac_X540_vf) { + rxdctl &= ~IXGBE_RXDCTL_RLPMLMASK; + rxdctl |= ((netdev->mtu + ETH_HLEN + ETH_FCS_LEN) | + IXGBE_RXDCTL_RLPML_EN); + } IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(j), rxdctl); ixgbevf_rx_desc_queue_enable(adapter, i); } @@ -3217,10 +3222,16 @@ static int ixgbevf_set_mac(struct net_device *netdev, void *p) static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu) { struct ixgbevf_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; + int max_possible_frame = MAXIMUM_ETHERNET_VLAN_SIZE; + u32 msg[2]; + + if (adapter->hw.mac.type == ixgbe_mac_X540_vf) + max_possible_frame = IXGBE_MAX_JUMBO_FRAME_SIZE; /* MTU < 68 is an error and causes problems on some kernels */ - if ((new_mtu < 68) || (max_frame > MAXIMUM_ETHERNET_VLAN_SIZE)) + if ((new_mtu < 68) || (max_frame > max_possible_frame)) return -EINVAL; hw_dbg(&adapter->hw, "changing MTU from %d to %d\n", @@ -3228,6 +3239,10 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu) /* must set new MTU before calling down or up */ netdev->mtu = new_mtu; + msg[0] = IXGBE_VF_SET_LPE; + msg[1] = max_frame; + hw->mbx.ops.write_posted(hw, msg, 2); + if (netif_running(netdev)) ixgbevf_reinit_locked(adapter); -- cgit v1.2.3 From 65d676c8c13c39301ebf813c7af00a13f05b2035 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Thu, 3 Feb 2011 06:54:13 +0000 Subject: ixgbevf: Fix name of function in function header comment Some of the function names in function header comments did not match actual name of the function. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher --- drivers/net/ixgbevf/ixgbevf_main.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 1f36f8fb41fc..43af761cdb16 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -107,7 +107,7 @@ static inline void ixgbevf_release_rx_desc(struct ixgbe_hw *hw, } /* - * ixgbe_set_ivar - set the IVAR registers, mapping interrupt causes to vectors + * ixgbevf_set_ivar - set IVAR registers - maps interrupt causes to vectors * @adapter: pointer to adapter struct * @direction: 0 for Rx, 1 for Tx, -1 for other causes * @queue: queue to map the corresponding interrupt to @@ -1017,7 +1017,7 @@ static irqreturn_t ixgbevf_msix_clean_tx(int irq, void *data) } /** - * ixgbe_msix_clean_rx - single unshared vector rx clean (all queues) + * ixgbevf_msix_clean_rx - single unshared vector rx clean (all queues) * @irq: unused * @data: pointer to our q_vector struct for this interrupt vector **/ @@ -1972,7 +1972,7 @@ static void ixgbevf_acquire_msix_vectors(struct ixgbevf_adapter *adapter, } /* - * ixgbe_set_num_queues: Allocate queues for device, feature dependant + * ixgbevf_set_num_queues: Allocate queues for device, feature dependant * @adapter: board private structure to initialize * * This is the top level queue allocation routine. The order here is very @@ -3534,9 +3534,9 @@ static struct pci_driver ixgbevf_driver = { }; /** - * ixgbe_init_module - Driver Registration Routine + * ixgbevf_init_module - Driver Registration Routine * - * ixgbe_init_module is the first routine called when the driver is + * ixgbevf_init_module is the first routine called when the driver is * loaded. All it does is register with the PCI subsystem. **/ static int __init ixgbevf_init_module(void) @@ -3554,9 +3554,9 @@ static int __init ixgbevf_init_module(void) module_init(ixgbevf_init_module); /** - * ixgbe_exit_module - Driver Exit Cleanup Routine + * ixgbevf_exit_module - Driver Exit Cleanup Routine * - * ixgbe_exit_module is called just before the driver is removed + * ixgbevf_exit_module is called just before the driver is removed * from memory. **/ static void __exit ixgbevf_exit_module(void) @@ -3566,7 +3566,7 @@ static void __exit ixgbevf_exit_module(void) #ifdef DEBUG /** - * ixgbe_get_hw_dev_name - return device name string + * ixgbevf_get_hw_dev_name - return device name string * used by hardware layer to print debugging information **/ char *ixgbevf_get_hw_dev_name(struct ixgbe_hw *hw) -- cgit v1.2.3 From 6799746ad63b3df7ddf47797bb06467db35c6f94 Mon Sep 17 00:00:00 2001 From: Lior Levy Date: Fri, 11 Feb 2011 03:38:04 +0000 Subject: igbvf: remove Tx hang detection Removed Tx hang detection mechanism from igbvf. This mechanism has no affect and can cause false alarm message in some cases. Signed-off-by: Lior Levy Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/igbvf/igbvf.h | 3 --- drivers/net/igbvf/netdev.c | 60 ---------------------------------------------- 2 files changed, 63 deletions(-) (limited to 'drivers') diff --git a/drivers/net/igbvf/igbvf.h b/drivers/net/igbvf/igbvf.h index 990c329e6c3b..d5dad5d607d6 100644 --- a/drivers/net/igbvf/igbvf.h +++ b/drivers/net/igbvf/igbvf.h @@ -201,9 +201,6 @@ struct igbvf_adapter { unsigned int restart_queue; u32 txd_cmd; - bool detect_tx_hung; - u8 tx_timeout_factor; - u32 tx_int_delay; u32 tx_abs_int_delay; diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 6352c8158e6d..42fdf5977be9 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -396,35 +396,6 @@ static void igbvf_put_txbuf(struct igbvf_adapter *adapter, buffer_info->time_stamp = 0; } -static void igbvf_print_tx_hang(struct igbvf_adapter *adapter) -{ - struct igbvf_ring *tx_ring = adapter->tx_ring; - unsigned int i = tx_ring->next_to_clean; - unsigned int eop = tx_ring->buffer_info[i].next_to_watch; - union e1000_adv_tx_desc *eop_desc = IGBVF_TX_DESC_ADV(*tx_ring, eop); - - /* detected Tx unit hang */ - dev_err(&adapter->pdev->dev, - "Detected Tx Unit Hang:\n" - " TDH <%x>\n" - " TDT <%x>\n" - " next_to_use <%x>\n" - " next_to_clean <%x>\n" - "buffer_info[next_to_clean]:\n" - " time_stamp <%lx>\n" - " next_to_watch <%x>\n" - " jiffies <%lx>\n" - " next_to_watch.status <%x>\n", - readl(adapter->hw.hw_addr + tx_ring->head), - readl(adapter->hw.hw_addr + tx_ring->tail), - tx_ring->next_to_use, - tx_ring->next_to_clean, - tx_ring->buffer_info[eop].time_stamp, - eop, - jiffies, - eop_desc->wb.status); -} - /** * igbvf_setup_tx_resources - allocate Tx resources (Descriptors) * @adapter: board private structure @@ -771,7 +742,6 @@ static void igbvf_set_itr(struct igbvf_adapter *adapter) static bool igbvf_clean_tx_irq(struct igbvf_ring *tx_ring) { struct igbvf_adapter *adapter = tx_ring->adapter; - struct e1000_hw *hw = &adapter->hw; struct net_device *netdev = adapter->netdev; struct igbvf_buffer *buffer_info; struct sk_buff *skb; @@ -832,22 +802,6 @@ static bool igbvf_clean_tx_irq(struct igbvf_ring *tx_ring) } } - if (adapter->detect_tx_hung) { - /* Detect a transmit hang in hardware, this serializes the - * check with the clearing of time_stamp and movement of i */ - adapter->detect_tx_hung = false; - if (tx_ring->buffer_info[i].time_stamp && - time_after(jiffies, tx_ring->buffer_info[i].time_stamp + - (adapter->tx_timeout_factor * HZ)) && - !(er32(STATUS) & E1000_STATUS_TXOFF)) { - - tx_desc = IGBVF_TX_DESC_ADV(*tx_ring, i); - /* detected Tx unit hang */ - igbvf_print_tx_hang(adapter); - - netif_stop_queue(netdev); - } - } adapter->net_stats.tx_bytes += total_bytes; adapter->net_stats.tx_packets += total_packets; return count < tx_ring->count; @@ -1863,17 +1817,6 @@ static void igbvf_watchdog_task(struct work_struct *work) &adapter->link_duplex); igbvf_print_link_info(adapter); - /* adjust timeout factor according to speed/duplex */ - adapter->tx_timeout_factor = 1; - switch (adapter->link_speed) { - case SPEED_10: - adapter->tx_timeout_factor = 16; - break; - case SPEED_100: - /* maybe add some timeout factor ? */ - break; - } - netif_carrier_on(netdev); netif_wake_queue(netdev); } @@ -1907,9 +1850,6 @@ static void igbvf_watchdog_task(struct work_struct *work) /* Cause software interrupt to ensure Rx ring is cleaned */ ew32(EICS, adapter->rx_ring->eims_value); - /* Force detection of hung controller every watchdog period */ - adapter->detect_tx_hung = 1; - /* Reset the timer */ if (!test_bit(__IGBVF_DOWN, &adapter->state)) mod_timer(&adapter->watchdog_timer, -- cgit v1.2.3 From 17dc566c5ee46e14021e6b8dd89098d3cb237208 Mon Sep 17 00:00:00 2001 From: Lior Levy Date: Tue, 8 Feb 2011 02:28:46 +0000 Subject: igb: add support for VF Transmit rate limit using iproute2 Implemented igb_ndo_set_vf_bw function which is being used by iproute2 tool. In addition, updated igb_ndo_get_vf_config function to show the actual rate limit to the user. The rate limitation can be configured only when the link is up. The rate limit value can be ranged between 0 and actual link speed measured in Mbps. A value of '0' disables the rate limit for this specific VF. iproute2 usage will be 'ip link set ethX vf Y rate Z'. After the command is made, the rate will be changed instantly. To view the current rate limit, use 'ip link show ethX'. The rates will be zeroed only upon driver reload or a link speed change. This feature is being supported only by 82576 device. Signed-off-by: Lior Levy Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/igb/e1000_defines.h | 7 ++++ drivers/net/igb/e1000_regs.h | 4 ++ drivers/net/igb/igb.h | 2 + drivers/net/igb/igb_main.c | 88 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 99 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index 6319ed902bc0..ff46c91520af 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h @@ -770,4 +770,11 @@ #define E1000_PCIEMISC_LX_DECISION 0x00000080 /* Lx power decision based on DMA coal */ +/* Tx Rate-Scheduler Config fields */ +#define E1000_RTTBCNRC_RS_ENA 0x80000000 +#define E1000_RTTBCNRC_RF_DEC_MASK 0x00003FFF +#define E1000_RTTBCNRC_RF_INT_SHIFT 14 +#define E1000_RTTBCNRC_RF_INT_MASK \ + (E1000_RTTBCNRC_RF_DEC_MASK << E1000_RTTBCNRC_RF_INT_SHIFT) + #endif diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h index 8ac83c5190d5..3a6f8471aea2 100644 --- a/drivers/net/igb/e1000_regs.h +++ b/drivers/net/igb/e1000_regs.h @@ -106,6 +106,10 @@ #define E1000_RQDPC(_n) (0x0C030 + ((_n) * 0x40)) +/* TX Rate Limit Registers */ +#define E1000_RTTDQSEL 0x3604 /* Tx Desc Plane Queue Select - WO */ +#define E1000_RTTBCNRC 0x36B0 /* Tx BCN Rate-Scheduler Config - WO */ + /* Split and Replication RX Control - RW */ #define E1000_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */ /* diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index 92a4ef09e55c..bbc5ebfe254a 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h @@ -77,6 +77,7 @@ struct vf_data_storage { unsigned long last_nack; u16 pf_vlan; /* When set, guest VLAN config not allowed. */ u16 pf_qos; + u16 tx_rate; }; #define IGB_VF_FLAG_CTS 0x00000001 /* VF is clear to send data */ @@ -323,6 +324,7 @@ struct igb_adapter { u16 rx_ring_count; unsigned int vfs_allocated_count; struct vf_data_storage *vf_data; + int vf_rate_link_speed; u32 rss_queues; u32 wvbr; }; diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index cb6bf7b815ae..88f8925b2d85 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -150,6 +150,7 @@ static int igb_ndo_set_vf_vlan(struct net_device *netdev, static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate); static int igb_ndo_get_vf_config(struct net_device *netdev, int vf, struct ifla_vf_info *ivi); +static void igb_check_vf_rate_limit(struct igb_adapter *); #ifdef CONFIG_PM static int igb_suspend(struct pci_dev *, pm_message_t); @@ -3511,6 +3512,7 @@ static void igb_watchdog_task(struct work_struct *work) netif_carrier_on(netdev); igb_ping_all_vfs(adapter); + igb_check_vf_rate_limit(adapter); /* link state has changed, schedule phy info update */ if (!test_bit(__IGB_DOWN, &adapter->state)) @@ -6599,9 +6601,91 @@ static int igb_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) return igb_set_vf_mac(adapter, vf, mac); } +static int igb_link_mbps(int internal_link_speed) +{ + switch (internal_link_speed) { + case SPEED_100: + return 100; + case SPEED_1000: + return 1000; + default: + return 0; + } +} + +static void igb_set_vf_rate_limit(struct e1000_hw *hw, int vf, int tx_rate, + int link_speed) +{ + int rf_dec, rf_int; + u32 bcnrc_val; + + if (tx_rate != 0) { + /* Calculate the rate factor values to set */ + rf_int = link_speed / tx_rate; + rf_dec = (link_speed - (rf_int * tx_rate)); + rf_dec = (rf_dec * (1<vf_rate_link_speed == 0) || + (adapter->hw.mac.type != e1000_82576)) + return; + + actual_link_speed = igb_link_mbps(adapter->link_speed); + if (actual_link_speed != adapter->vf_rate_link_speed) { + reset_rate = true; + adapter->vf_rate_link_speed = 0; + dev_info(&adapter->pdev->dev, + "Link speed has been changed. VF Transmit " + "rate is disabled\n"); + } + + for (i = 0; i < adapter->vfs_allocated_count; i++) { + if (reset_rate) + adapter->vf_data[i].tx_rate = 0; + + igb_set_vf_rate_limit(&adapter->hw, i, + adapter->vf_data[i].tx_rate, + actual_link_speed); + } +} + static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate) { - return -EOPNOTSUPP; + struct igb_adapter *adapter = netdev_priv(netdev); + struct e1000_hw *hw = &adapter->hw; + int actual_link_speed; + + if (hw->mac.type != e1000_82576) + return -EOPNOTSUPP; + + actual_link_speed = igb_link_mbps(adapter->link_speed); + if ((vf >= adapter->vfs_allocated_count) || + (!(rd32(E1000_STATUS) & E1000_STATUS_LU)) || + (tx_rate < 0) || (tx_rate > actual_link_speed)) + return -EINVAL; + + adapter->vf_rate_link_speed = actual_link_speed; + adapter->vf_data[vf].tx_rate = (u16)tx_rate; + igb_set_vf_rate_limit(hw, vf, tx_rate, actual_link_speed); + + return 0; } static int igb_ndo_get_vf_config(struct net_device *netdev, @@ -6612,7 +6696,7 @@ static int igb_ndo_get_vf_config(struct net_device *netdev, return -EINVAL; ivi->vf = vf; memcpy(&ivi->mac, adapter->vf_data[vf].vf_mac_addresses, ETH_ALEN); - ivi->tx_rate = 0; + ivi->tx_rate = adapter->vf_data[vf].tx_rate; ivi->vlan = adapter->vf_data[vf].pf_vlan; ivi->qos = adapter->vf_data[vf].pf_qos; return 0; -- cgit v1.2.3 From 4c4b42cb2f7b8273f8e458a23f08b62d89c337f3 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Thu, 17 Feb 2011 09:02:30 +0000 Subject: igb: Update Intel copyright notice for driver source. This fix updates copyright information to include current year 2011. Signed-off-by: Carolyn Wyborny Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/igb/igb_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 88f8925b2d85..a55fa1708baa 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -55,7 +55,7 @@ char igb_driver_name[] = "igb"; char igb_driver_version[] = DRV_VERSION; static const char igb_driver_string[] = "Intel(R) Gigabit Ethernet Network Driver"; -static const char igb_copyright[] = "Copyright (c) 2007-2009 Intel Corporation."; +static const char igb_copyright[] = "Copyright (c) 2007-2011 Intel Corporation."; static const struct e1000_info *igb_info_tbl[] = { [board_82575] = &e1000_82575_info, -- cgit v1.2.3 From c2b6a059cf4d527e1e71f384e9e45326bcc8b41f Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Wed, 16 Feb 2011 05:09:46 +0000 Subject: igb: update version string This will synchronize the version with the out of tree driver which shares its functionality. Signed-off-by: Carolyn Wyborny Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/igb/igb_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index a55fa1708baa..579dbba5f9e4 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -50,7 +50,7 @@ #endif #include "igb.h" -#define DRV_VERSION "2.1.0-k2" +#define DRV_VERSION "2.4.13-k2" char igb_driver_name[] = "igb"; char igb_driver_version[] = DRV_VERSION; static const char igb_driver_string[] = -- cgit v1.2.3 From 995073072c2ae72255b595b192cc63f43fd386ef Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 24 Feb 2011 09:42:52 +0000 Subject: drm/i915: Fix unintended recursion in ironlake_disable_rc6 After disabling, we're meant to teardown the bo used for the contexts, not recurse into ourselves again and preventing module unload. Reported-and-tested-by: Ben Widawsky Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9ca1bb2554fc..e79b25bbee6c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6575,7 +6575,7 @@ static void ironlake_disable_rc6(struct drm_device *dev) POSTING_READ(RSTDBYCTL); } - ironlake_disable_rc6(dev); + ironlake_teardown_rc6(dev); } static int ironlake_setup_rc6(struct drm_device *dev) -- cgit v1.2.3 From 2949ad50711cc161721cf788711722eeeca33764 Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Sat, 19 Feb 2011 14:18:08 +0100 Subject: ACPI / debugfs: Fix buffer overflows, double free File position is not controlled, it may lead to overwrites of arbitrary kernel memory. Also the code may kfree() the same pointer multiple times. One more flaw is still present: if multiple processes open the file then all 3 static variables are shared, leading to various race conditions. They should be moved to file->private_data. Signed-off-by: Vasiliy Kulikov Reviewed-by: WANG Cong Reviewed-by: Eugene Teo Cc: stable@kernel.org Signed-off-by: Rafael J. Wysocki --- drivers/acpi/debugfs.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c index 5df67f1d6c61..384f7abcff77 100644 --- a/drivers/acpi/debugfs.c +++ b/drivers/acpi/debugfs.c @@ -26,7 +26,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, size_t count, loff_t *ppos) { static char *buf; - static int uncopied_bytes; + static u32 max_size; + static u32 uncopied_bytes; + struct acpi_table_header table; acpi_status status; @@ -37,19 +39,24 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, if (copy_from_user(&table, user_buf, sizeof(struct acpi_table_header))) return -EFAULT; - uncopied_bytes = table.length; - buf = kzalloc(uncopied_bytes, GFP_KERNEL); + uncopied_bytes = max_size = table.length; + buf = kzalloc(max_size, GFP_KERNEL); if (!buf) return -ENOMEM; } - if (uncopied_bytes < count) { - kfree(buf); + if (buf == NULL) + return -EINVAL; + + if ((*ppos > max_size) || + (*ppos + count > max_size) || + (*ppos + count < count) || + (count > uncopied_bytes)) return -EINVAL; - } if (copy_from_user(buf + (*ppos), user_buf, count)) { kfree(buf); + buf = NULL; return -EFAULT; } @@ -59,6 +66,7 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, if (!uncopied_bytes) { status = acpi_install_method(buf); kfree(buf); + buf = NULL; if (ACPI_FAILURE(status)) return -EINVAL; add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); -- cgit v1.2.3 From 981858bd7a401aa9607d9f430d5de920025fc3ea Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 24 Feb 2011 19:59:21 +0100 Subject: ACPI / ACPICA: Implicit notify for multiple devices Commit bba63a2 (ACPICA: Implicit notify support) introduced a mechanism that causes a notify request of type ACPI_NOTIFY_DEVICE_WAKE to be queued automatically by acpi_ev_asynch_execute_gpe_method() for the device whose _PRW points to the GPE being handled if that GPE is not associated with an _Lxx/_Exx method. However, it turns out that on some systems there are multiple devices with _PRW pointing to the same GPE without _Lxx/_Exx and the mechanism introduced by commit bba63a2 needs to be extended so that "implicit" notify requests of type ACPI_NOTIFY_DEVICE_WAKE can be queued automatically for all those devices at the same time. Reported-and-tested-by: Matthew Garrett Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/aclocal.h | 7 ++++++- drivers/acpi/acpica/evgpe.c | 17 +++++++++++++---- drivers/acpi/acpica/evxfgpe.c | 42 +++++++++++++++++++++++++++++++++--------- 3 files changed, 52 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 54784bb42cec..edc25867ad9d 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -416,10 +416,15 @@ struct acpi_gpe_handler_info { u8 originally_enabled; /* True if GPE was originally enabled */ }; +struct acpi_gpe_notify_object { + struct acpi_namespace_node *node; + struct acpi_gpe_notify_object *next; +}; + union acpi_gpe_dispatch_info { struct acpi_namespace_node *method_node; /* Method node for this GPE level */ struct acpi_gpe_handler_info *handler; /* Installed GPE handler */ - struct acpi_namespace_node *device_node; /* Parent _PRW device for implicit notify */ + struct acpi_gpe_notify_object device; /* List of _PRW devices for implicit notify */ }; /* diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 14988a86066f..f4725212eb48 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -457,6 +457,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) acpi_status status; struct acpi_gpe_event_info *local_gpe_event_info; struct acpi_evaluate_info *info; + struct acpi_gpe_notify_object *notify_object; ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); @@ -508,10 +509,18 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) * from this thread -- because handlers may in turn run other * control methods. */ - status = - acpi_ev_queue_notify_request(local_gpe_event_info->dispatch. - device_node, - ACPI_NOTIFY_DEVICE_WAKE); + status = acpi_ev_queue_notify_request( + local_gpe_event_info->dispatch.device.node, + ACPI_NOTIFY_DEVICE_WAKE); + + notify_object = local_gpe_event_info->dispatch.device.next; + while (ACPI_SUCCESS(status) && notify_object) { + status = acpi_ev_queue_notify_request( + notify_object->node, + ACPI_NOTIFY_DEVICE_WAKE); + notify_object = notify_object->next; + } + break; case ACPI_GPE_DISPATCH_METHOD: diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index 3b20a3401b64..52aaff3df562 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c @@ -198,7 +198,9 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device, acpi_status status = AE_BAD_PARAMETER; struct acpi_gpe_event_info *gpe_event_info; struct acpi_namespace_node *device_node; + struct acpi_gpe_notify_object *notify_object; acpi_cpu_flags flags; + u8 gpe_dispatch_mask; ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake); @@ -221,27 +223,49 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device, goto unlock_and_exit; } + if (wake_device == ACPI_ROOT_OBJECT) { + goto out; + } + /* * If there is no method or handler for this GPE, then the * wake_device will be notified whenever this GPE fires (aka * "implicit notify") Note: The GPE is assumed to be * level-triggered (for windows compatibility). */ - if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == - ACPI_GPE_DISPATCH_NONE) && (wake_device != ACPI_ROOT_OBJECT)) { + gpe_dispatch_mask = gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK; + if (gpe_dispatch_mask != ACPI_GPE_DISPATCH_NONE + && gpe_dispatch_mask != ACPI_GPE_DISPATCH_NOTIFY) { + goto out; + } - /* Validate wake_device is of type Device */ + /* Validate wake_device is of type Device */ - device_node = ACPI_CAST_PTR(struct acpi_namespace_node, - wake_device); - if (device_node->type != ACPI_TYPE_DEVICE) { - goto unlock_and_exit; - } + device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device); + if (device_node->type != ACPI_TYPE_DEVICE) { + goto unlock_and_exit; + } + + if (gpe_dispatch_mask == ACPI_GPE_DISPATCH_NONE) { gpe_event_info->flags = (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED); - gpe_event_info->dispatch.device_node = device_node; + gpe_event_info->dispatch.device.node = device_node; + gpe_event_info->dispatch.device.next = NULL; + } else { + /* There are multiple devices to notify implicitly. */ + + notify_object = ACPI_ALLOCATE_ZEROED(sizeof(*notify_object)); + if (!notify_object) { + status = AE_NO_MEMORY; + goto unlock_and_exit; + } + + notify_object->node = device_node; + notify_object->next = gpe_event_info->dispatch.device.next; + gpe_event_info->dispatch.device.next = notify_object; } + out: gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; status = AE_OK; -- cgit v1.2.3 From ec95d35a6bd0047f05fe8a21e6c52f8bb418da55 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Feb 2011 10:36:53 +0200 Subject: usb: musb: core: set has_tt flag MUSB is a non-standard host implementation which can handle all speeds with the same core. We need to set has_tt flag after commit d199c96d41d80a567493e12b8e96ea056a1350c1 (USB: prevent buggy hubs from crashing the USB stack) in order for MUSB HCD to continue working. Signed-off-by: Felipe Balbi Cc: stable Cc: Alan Stern Tested-by: Michael Jones Tested-by: Alexander Holler Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 54a8bd1047d6..c292d5c499e7 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1864,6 +1864,7 @@ allocate_instance(struct device *dev, INIT_LIST_HEAD(&musb->out_bulk); hcd->uses_new_polling = 1; + hcd->has_tt = 1; musb->vbuserr_retry = VBUSERR_RETRY_COUNT; musb->a_wait_bcon = OTG_TIME_A_WAIT_BCON; -- cgit v1.2.3 From 41cae2d01385af4199666db57274c0df3283b065 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 24 Feb 2011 20:39:05 +0100 Subject: rtl8192c: fix compilation errors On my G5 this fails to compile with drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c:701: error: __ksymtab__rtl92c_phy_txpwr_idx_to_dbm causes a section type conflict drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c:701: error: __ksymtab__rtl92c_phy_txpwr_idx_to_dbm causes a section type conflict drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c:677: error: __ksymtab__rtl92c_phy_dbm_to_txpwr_Idx causes a section type conflict drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c:677: error: __ksymtab__rtl92c_phy_dbm_to_txpwr_Idx causes a section type conflict since you can't export static functions. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | 12 ++++++------ drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index 30e3ef8badee..a70228278398 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c @@ -644,9 +644,9 @@ void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval) } EXPORT_SYMBOL(rtl92c_phy_set_beacon_hw_reg); -static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, - long power_indbm) +u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + long power_indbm) { u8 txpwridx; long offset; @@ -676,9 +676,9 @@ static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, } EXPORT_SYMBOL(_rtl92c_phy_dbm_to_txpwr_Idx); -static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, - u8 txpwridx) +long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx) { long offset; long pwrout_dbm; diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h index 148bc019f4bd..53ffb0981586 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h @@ -228,12 +228,12 @@ void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); void rtl92c_phy_set_io(struct ieee80211_hw *hw); void rtl92c_bb_block_on(struct ieee80211_hw *hw); u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); -static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, - u8 txpwridx); -static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, - long power_indbm); +long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx); +u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + long power_indbm); void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, u32 cmdtableidx, u32 cmdtablesz, -- cgit v1.2.3 From cdf64c803e6cfec72259f7bb2654261584bb80a8 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 23 Feb 2011 14:52:43 +0000 Subject: skge: don't mark carrier down at start The API for network devices has changed so that setting carrier off at probe is no longer required. This should fix the IPv6 addrconf issue. Addresses https://bugzilla.kernel.org/show_bug.cgi?id=29612 Signed-off-by: Stephen Hemminger Reported-by: George Billios Cc: David Miller Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/skge.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 42daf98ba736..35b28f42d208 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -3856,9 +3856,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN); memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); - /* device is off until link detection */ - netif_carrier_off(dev); - return dev; } -- cgit v1.2.3 From b08cd667c4b6641c4d16a3f87f4550f81a6d69ac Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 24 Feb 2011 22:50:30 -0800 Subject: rtlwifi: Need to include vmalloc.h Signed-off-by: David S. Miller --- drivers/net/wireless/rtlwifi/wifi.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 4b90b35f211e..7d47184d6bfe 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include "debug.h" -- cgit v1.2.3 From 9ee291a453c1db310c0298f8e6c28794cd2c52bd Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 2 Feb 2011 20:17:22 +0000 Subject: regulator: Fix warning with CONFIG_BUG disabled Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/wm831x-dcdc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 8b0d2c4bde91..06df898842c0 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -120,6 +120,7 @@ static unsigned int wm831x_dcdc_get_mode(struct regulator_dev *rdev) return REGULATOR_MODE_IDLE; default: BUG(); + return -EINVAL; } } -- cgit v1.2.3 From 4b2f67d756cf4a5ed8e8d11caa7dcea06c41a09e Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Wed, 23 Feb 2011 23:45:55 +0100 Subject: regulator, mc13xxx: Remove pointless test for unsigned less than zero The variable 'val' is a 'unsigned int', so it can never be less than zero. This fact makes the "val < 0" part of the test done in BUG_ON() in mc13xxx_regulator_get_voltage() rather pointles since it can never have any effect. This patch removes the pointless test. Signed-off-by: Jesper Juhl Acked-by: Alberto Panizzo Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/mc13xxx-regulator-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c index f53d31b950d4..2bb5de1f2421 100644 --- a/drivers/regulator/mc13xxx-regulator-core.c +++ b/drivers/regulator/mc13xxx-regulator-core.c @@ -174,7 +174,7 @@ static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev) dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val); - BUG_ON(val < 0 || val > mc13xxx_regulators[id].desc.n_voltages); + BUG_ON(val > mc13xxx_regulators[id].desc.n_voltages); return mc13xxx_regulators[id].voltages[val]; } -- cgit v1.2.3 From 702d4eb9b3de4398ab99cf0a4e799e552c7ab756 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Thu, 2 Dec 2010 17:54:50 +0000 Subject: xen: no need to delay xen_setup_shutdown_event for hvm guests anymore Now that xenstore_ready is used correctly for PV on HVM guests too, we don't need to delay the initialization of xen_setup_shutdown_event anymore. Signed-off-by: Stefano Stabellini Acked-by: Jeremy Fitzhardinge --- drivers/xen/manage.c | 17 ++++------------- drivers/xen/platform-pci.c | 3 --- 2 files changed, 4 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 24177272bcb8..b2a8d7856ce3 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -291,27 +291,18 @@ static int shutdown_event(struct notifier_block *notifier, return NOTIFY_DONE; } -static int __init __setup_shutdown_event(void) -{ - /* Delay initialization in the PV on HVM case */ - if (xen_hvm_domain()) - return 0; - - if (!xen_pv_domain()) - return -ENODEV; - - return xen_setup_shutdown_event(); -} - int xen_setup_shutdown_event(void) { static struct notifier_block xenstore_notifier = { .notifier_call = shutdown_event }; + + if (!xen_domain()) + return -ENODEV; register_xenstore_notifier(&xenstore_notifier); return 0; } EXPORT_SYMBOL_GPL(xen_setup_shutdown_event); -subsys_initcall(__setup_shutdown_event); +subsys_initcall(xen_setup_shutdown_event); diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c index afbe041f42c5..319dd0a94d51 100644 --- a/drivers/xen/platform-pci.c +++ b/drivers/xen/platform-pci.c @@ -156,9 +156,6 @@ static int __devinit platform_pci_init(struct pci_dev *pdev, if (ret) goto out; xenbus_probe(NULL); - ret = xen_setup_shutdown_event(); - if (ret) - goto out; return 0; out: -- cgit v1.2.3 From c80a420995e721099906607b07c09a24543b31d9 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Thu, 2 Dec 2010 17:55:00 +0000 Subject: xen-blkfront: handle Xen major numbers other than XENVBD This patch makes sure blkfront handles correctly virtual device numbers corresponding to Xen emulated IDE and SCSI disks: in those cases blkfront translates the major number to XENVBD and the minor number to a low xvd minor. Note: this behaviour is different from what old xenlinux PV guests used to do: they used to steal an IDE or SCSI major number and use it instead. Signed-off-by: Stefano Stabellini Acked-by: Jeremy Fitzhardinge --- drivers/block/xen-blkfront.c | 79 +++++++++++++++++++++++++++++++++++++--- include/xen/interface/io/blkif.h | 21 +++++++++++ 2 files changed, 95 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index d7aa39e349a6..64d9c6dfc634 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -120,6 +120,10 @@ static DEFINE_SPINLOCK(minor_lock); #define EXTENDED (1<feature_flush ? "enabled" : "disabled"); } +static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset) +{ + int major; + major = BLKIF_MAJOR(vdevice); + *minor = BLKIF_MINOR(vdevice); + switch (major) { + case XEN_IDE0_MAJOR: + *offset = (*minor / 64) + EMULATED_HD_DISK_NAME_OFFSET; + *minor = ((*minor / 64) * PARTS_PER_DISK) + + EMULATED_HD_DISK_MINOR_OFFSET; + break; + case XEN_IDE1_MAJOR: + *offset = (*minor / 64) + 2 + EMULATED_HD_DISK_NAME_OFFSET; + *minor = (((*minor / 64) + 2) * PARTS_PER_DISK) + + EMULATED_HD_DISK_MINOR_OFFSET; + break; + case XEN_SCSI_DISK0_MAJOR: + *offset = (*minor / PARTS_PER_DISK) + EMULATED_SD_DISK_NAME_OFFSET; + *minor = *minor + EMULATED_SD_DISK_MINOR_OFFSET; + break; + case XEN_SCSI_DISK1_MAJOR: + case XEN_SCSI_DISK2_MAJOR: + case XEN_SCSI_DISK3_MAJOR: + case XEN_SCSI_DISK4_MAJOR: + case XEN_SCSI_DISK5_MAJOR: + case XEN_SCSI_DISK6_MAJOR: + case XEN_SCSI_DISK7_MAJOR: + *offset = (*minor / PARTS_PER_DISK) + + ((major - XEN_SCSI_DISK1_MAJOR + 1) * 16) + + EMULATED_SD_DISK_NAME_OFFSET; + *minor = *minor + + ((major - XEN_SCSI_DISK1_MAJOR + 1) * 16 * PARTS_PER_DISK) + + EMULATED_SD_DISK_MINOR_OFFSET; + break; + case XEN_SCSI_DISK8_MAJOR: + case XEN_SCSI_DISK9_MAJOR: + case XEN_SCSI_DISK10_MAJOR: + case XEN_SCSI_DISK11_MAJOR: + case XEN_SCSI_DISK12_MAJOR: + case XEN_SCSI_DISK13_MAJOR: + case XEN_SCSI_DISK14_MAJOR: + case XEN_SCSI_DISK15_MAJOR: + *offset = (*minor / PARTS_PER_DISK) + + ((major - XEN_SCSI_DISK8_MAJOR + 8) * 16) + + EMULATED_SD_DISK_NAME_OFFSET; + *minor = *minor + + ((major - XEN_SCSI_DISK8_MAJOR + 8) * 16 * PARTS_PER_DISK) + + EMULATED_SD_DISK_MINOR_OFFSET; + break; + case XENVBD_MAJOR: + *offset = *minor / PARTS_PER_DISK; + break; + default: + printk(KERN_WARNING "blkfront: your disk configuration is " + "incorrect, please use an xvd device instead\n"); + return -ENODEV; + } + return 0; +} static int xlvbd_alloc_gendisk(blkif_sector_t capacity, struct blkfront_info *info, @@ -441,7 +504,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, { struct gendisk *gd; int nr_minors = 1; - int err = -ENODEV; + int err; unsigned int offset; int minor; int nr_parts; @@ -456,12 +519,20 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, } if (!VDEV_IS_EXTENDED(info->vdevice)) { - minor = BLKIF_MINOR(info->vdevice); - nr_parts = PARTS_PER_DISK; + err = xen_translate_vdev(info->vdevice, &minor, &offset); + if (err) + return err; + nr_parts = PARTS_PER_DISK; } else { minor = BLKIF_MINOR_EXT(info->vdevice); nr_parts = PARTS_PER_EXT_DISK; + offset = minor / nr_parts; + if (xen_hvm_domain() && offset <= EMULATED_HD_DISK_NAME_OFFSET + 4) + printk(KERN_WARNING "blkfront: vdevice 0x%x might conflict with " + "emulated IDE disks,\n\t choose an xvd device name" + "from xvde on\n", info->vdevice); } + err = -ENODEV; if ((minor % nr_parts) == 0) nr_minors = nr_parts; @@ -475,8 +546,6 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, if (gd == NULL) goto release; - offset = minor / nr_parts; - if (nr_minors > 1) { if (offset < 26) sprintf(gd->disk_name, "%s%c", DEV_NAME, 'a' + offset); diff --git a/include/xen/interface/io/blkif.h b/include/xen/interface/io/blkif.h index c2d1fa4dc1ee..68dd2b49635c 100644 --- a/include/xen/interface/io/blkif.h +++ b/include/xen/interface/io/blkif.h @@ -91,4 +91,25 @@ DEFINE_RING_TYPES(blkif, struct blkif_request, struct blkif_response); #define VDISK_REMOVABLE 0x2 #define VDISK_READONLY 0x4 +/* Xen-defined major numbers for virtual disks, they look strangely + * familiar */ +#define XEN_IDE0_MAJOR 3 +#define XEN_IDE1_MAJOR 22 +#define XEN_SCSI_DISK0_MAJOR 8 +#define XEN_SCSI_DISK1_MAJOR 65 +#define XEN_SCSI_DISK2_MAJOR 66 +#define XEN_SCSI_DISK3_MAJOR 67 +#define XEN_SCSI_DISK4_MAJOR 68 +#define XEN_SCSI_DISK5_MAJOR 69 +#define XEN_SCSI_DISK6_MAJOR 70 +#define XEN_SCSI_DISK7_MAJOR 71 +#define XEN_SCSI_DISK8_MAJOR 128 +#define XEN_SCSI_DISK9_MAJOR 129 +#define XEN_SCSI_DISK10_MAJOR 130 +#define XEN_SCSI_DISK11_MAJOR 131 +#define XEN_SCSI_DISK12_MAJOR 132 +#define XEN_SCSI_DISK13_MAJOR 133 +#define XEN_SCSI_DISK14_MAJOR 134 +#define XEN_SCSI_DISK15_MAJOR 135 + #endif /* __XEN_PUBLIC_IO_BLKIF_H__ */ -- cgit v1.2.3 From 53d5522cad291a0e93a385e0594b6aea6b54a071 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Thu, 2 Dec 2010 17:55:05 +0000 Subject: xen: make the ballon driver work for hvm domains Signed-off-by: Stefano Stabellini --- drivers/xen/balloon.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 43f9f02c7db0..9294f25dcb2c 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -232,7 +232,7 @@ static int increase_reservation(unsigned long nr_pages) set_phys_to_machine(pfn, frame_list[i]); /* Link back into the page tables if not highmem. */ - if (pfn < max_low_pfn) { + if (!xen_hvm_domain() && pfn < max_low_pfn) { int ret; ret = HYPERVISOR_update_va_mapping( (unsigned long)__va(pfn << PAGE_SHIFT), @@ -280,7 +280,7 @@ static int decrease_reservation(unsigned long nr_pages) scrub_page(page); - if (!PageHighMem(page)) { + if (!xen_hvm_domain() && !PageHighMem(page)) { ret = HYPERVISOR_update_va_mapping( (unsigned long)__va(pfn << PAGE_SHIFT), __pte_ma(0), 0); @@ -392,15 +392,19 @@ static struct notifier_block xenstore_notifier; static int __init balloon_init(void) { - unsigned long pfn, extra_pfn_end; + unsigned long pfn, nr_pages, extra_pfn_end; struct page *page; - if (!xen_pv_domain()) + if (!xen_domain()) return -ENODEV; pr_info("xen_balloon: Initialising balloon driver.\n"); - balloon_stats.current_pages = min(xen_start_info->nr_pages, max_pfn); + if (xen_pv_domain()) + nr_pages = xen_start_info->nr_pages; + else + nr_pages = max_pfn; + balloon_stats.current_pages = min(nr_pages, max_pfn); balloon_stats.target_pages = balloon_stats.current_pages; balloon_stats.balloon_low = 0; balloon_stats.balloon_high = 0; -- cgit v1.2.3 From 552717231e50b478dfd19d63fd97879476ae051d Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 17 Feb 2011 11:04:20 +0000 Subject: xen: do not respond to unknown xenstore control requests The PV xenbus control/shutdown node is written by the toolstack as a request to the guest to perform a particular action (shutdown, reboot, suspend etc). The guest is expected to acknowledge that it will complete a request by clearing the control node. Previously it would acknowledge any request, even if it did not know what to do with it. Specifically in the case where CONFIG_PM_SLEEP is not enabled the kernel would acknowledge a suspend request even though it was not actually going to do anything. Instead make the kernel only acknowledge requests if it is actually going to do something with it. This will improve the toolstack's ability to diagnose and deal with failures. Signed-off-by: Ian Campbell Reviewed-by: Konrad Rzeszutek Wilk --- drivers/xen/manage.c | 49 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index b2a8d7856ce3..972bf783a182 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -172,12 +172,39 @@ out: } #endif /* CONFIG_PM_SLEEP */ +struct shutdown_handler { + const char *command; + void (*cb)(void); +}; + +static void do_poweroff(void) +{ + shutting_down = SHUTDOWN_POWEROFF; + orderly_poweroff(false); +} + +static void do_reboot(void) +{ + shutting_down = SHUTDOWN_POWEROFF; /* ? */ + ctrl_alt_del(); +} + static void shutdown_handler(struct xenbus_watch *watch, const char **vec, unsigned int len) { char *str; struct xenbus_transaction xbt; int err; + static struct shutdown_handler handlers[] = { + { "poweroff", do_poweroff }, + { "halt", do_poweroff }, + { "reboot", do_reboot }, +#ifdef CONFIG_PM_SLEEP + { "suspend", do_suspend }, +#endif + {NULL, NULL}, + }; + static struct shutdown_handler *handler; if (shutting_down != SHUTDOWN_INVALID) return; @@ -194,7 +221,14 @@ static void shutdown_handler(struct xenbus_watch *watch, return; } - xenbus_write(xbt, "control", "shutdown", ""); + for (handler = &handlers[0]; handler->command; handler++) { + if (strcmp(str, handler->command) == 0) + break; + } + + /* Only acknowledge commands which we are prepared to handle. */ + if (handler->cb) + xenbus_write(xbt, "control", "shutdown", ""); err = xenbus_transaction_end(xbt, 0); if (err == -EAGAIN) { @@ -202,17 +236,8 @@ static void shutdown_handler(struct xenbus_watch *watch, goto again; } - if (strcmp(str, "poweroff") == 0 || - strcmp(str, "halt") == 0) { - shutting_down = SHUTDOWN_POWEROFF; - orderly_poweroff(false); - } else if (strcmp(str, "reboot") == 0) { - shutting_down = SHUTDOWN_POWEROFF; /* ? */ - ctrl_alt_del(); -#ifdef CONFIG_PM_SLEEP - } else if (strcmp(str, "suspend") == 0) { - do_suspend(); -#endif + if (handler->cb) { + handler->cb(); } else { printk(KERN_INFO "Ignoring shutdown request: %s\n", str); shutting_down = SHUTDOWN_INVALID; -- cgit v1.2.3 From bd1c0ad28451df4610d352c7e438213c84de0c28 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 17 Feb 2011 11:04:20 +0000 Subject: xen: suspend: use HYPERVISOR_suspend for PVHVM case instead of open coding Signed-off-by: Ian Campbell Reviewed-by: Konrad Rzeszutek Wilk --- drivers/xen/manage.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 972bf783a182..4dd01865ad18 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -38,7 +38,6 @@ static enum shutdown_state shutting_down = SHUTDOWN_INVALID; static int xen_hvm_suspend(void *data) { int err; - struct sched_shutdown r = { .reason = SHUTDOWN_suspend }; int *cancelled = data; BUG_ON(!irqs_disabled()); @@ -50,7 +49,12 @@ static int xen_hvm_suspend(void *data) return err; } - *cancelled = HYPERVISOR_sched_op(SCHEDOP_shutdown, &r); + /* + * This hypercall returns 1 if suspend was cancelled + * or the domain was merely checkpointed, and 0 if it + * is resuming in a new domain. + */ + *cancelled = HYPERVISOR_suspend(0UL); xen_hvm_post_suspend(*cancelled); gnttab_resume(); -- cgit v1.2.3 From ceb180294790c8a6a437533488616f6b591b49d0 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 17 Feb 2011 11:04:20 +0000 Subject: xen: suspend: refactor cancellation flag into a structure Will add extra fields in subsequent patches. Signed-off-by: Ian Campbell Reviewed-by: Konrad Rzeszutek Wilk --- drivers/xen/manage.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 4dd01865ad18..5c0184fb9d84 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -34,11 +34,15 @@ enum shutdown_state { /* Ignore multiple shutdown requests. */ static enum shutdown_state shutting_down = SHUTDOWN_INVALID; +struct suspend_info { + int cancelled; +}; + #ifdef CONFIG_PM_SLEEP static int xen_hvm_suspend(void *data) { + struct suspend_info *si = data; int err; - int *cancelled = data; BUG_ON(!irqs_disabled()); @@ -54,12 +58,12 @@ static int xen_hvm_suspend(void *data) * or the domain was merely checkpointed, and 0 if it * is resuming in a new domain. */ - *cancelled = HYPERVISOR_suspend(0UL); + si->cancelled = HYPERVISOR_suspend(0UL); - xen_hvm_post_suspend(*cancelled); + xen_hvm_post_suspend(si->cancelled); gnttab_resume(); - if (!*cancelled) { + if (!si->cancelled) { xen_irq_resume(); xen_console_resume(); xen_timer_resume(); @@ -72,8 +76,8 @@ static int xen_hvm_suspend(void *data) static int xen_suspend(void *data) { + struct suspend_info *si = data; int err; - int *cancelled = data; BUG_ON(!irqs_disabled()); @@ -93,13 +97,13 @@ static int xen_suspend(void *data) * or the domain was merely checkpointed, and 0 if it * is resuming in a new domain. */ - *cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info)); + si->cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info)); - xen_post_suspend(*cancelled); + xen_post_suspend(si->cancelled); gnttab_resume(); xen_mm_unpin_all(); - if (!*cancelled) { + if (!si->cancelled) { xen_irq_resume(); xen_console_resume(); xen_timer_resume(); @@ -113,7 +117,7 @@ static int xen_suspend(void *data) static void do_suspend(void) { int err; - int cancelled = 1; + struct suspend_info si; shutting_down = SHUTDOWN_SUSPEND; @@ -143,20 +147,22 @@ static void do_suspend(void) goto out_resume; } + si.cancelled = 1; + if (xen_hvm_domain()) - err = stop_machine(xen_hvm_suspend, &cancelled, cpumask_of(0)); + err = stop_machine(xen_hvm_suspend, &si, cpumask_of(0)); else - err = stop_machine(xen_suspend, &cancelled, cpumask_of(0)); + err = stop_machine(xen_suspend, &si, cpumask_of(0)); dpm_resume_noirq(PMSG_RESUME); if (err) { printk(KERN_ERR "failed to start xen_suspend: %d\n", err); - cancelled = 1; + si.cancelled = 1; } out_resume: - if (!cancelled) { + if (!si.cancelled) { xen_arch_resume(); xs_resume(); } else -- cgit v1.2.3 From 36b401e2c2788c7b4881115ddbbff603fe4cf78d Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 17 Feb 2011 11:04:20 +0000 Subject: xen: suspend: pass extra hypercall argument via suspend_info struct Signed-off-by: Ian Campbell Reviewed-by: Konrad Rzeszutek Wilk --- drivers/xen/manage.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 5c0184fb9d84..6ce6b91e7645 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -36,6 +36,7 @@ static enum shutdown_state shutting_down = SHUTDOWN_INVALID; struct suspend_info { int cancelled; + unsigned long arg; /* extra hypercall argument */ }; #ifdef CONFIG_PM_SLEEP @@ -58,7 +59,7 @@ static int xen_hvm_suspend(void *data) * or the domain was merely checkpointed, and 0 if it * is resuming in a new domain. */ - si->cancelled = HYPERVISOR_suspend(0UL); + si->cancelled = HYPERVISOR_suspend(si->arg); xen_hvm_post_suspend(si->cancelled); gnttab_resume(); @@ -97,7 +98,7 @@ static int xen_suspend(void *data) * or the domain was merely checkpointed, and 0 if it * is resuming in a new domain. */ - si->cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info)); + si->cancelled = HYPERVISOR_suspend(si->arg); xen_post_suspend(si->cancelled); gnttab_resume(); @@ -149,6 +150,11 @@ static void do_suspend(void) si.cancelled = 1; + if (xen_hvm_domain()) + si.arg = 0UL; + else + si.arg = virt_to_mfn(xen_start_info); + if (xen_hvm_domain()) err = stop_machine(xen_hvm_suspend, &si, cpumask_of(0)); else -- cgit v1.2.3 From 03c8142bd2fb3b87effa6ecb2f8957be588bc85f Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 17 Feb 2011 11:04:20 +0000 Subject: xen: suspend: add "arch" to pre/post suspend hooks xen_pre_device_suspend is unused on ia64. Signed-off-by: Ian Campbell Reviewed-by: Konrad Rzeszutek Wilk --- arch/ia64/xen/suspend.c | 9 ++------- arch/x86/xen/suspend.c | 6 +++--- drivers/xen/manage.c | 6 +++--- include/xen/xen-ops.h | 6 +++--- 4 files changed, 11 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/arch/ia64/xen/suspend.c b/arch/ia64/xen/suspend.c index fd66b048c6fa..419c8620945a 100644 --- a/arch/ia64/xen/suspend.c +++ b/arch/ia64/xen/suspend.c @@ -37,19 +37,14 @@ xen_mm_unpin_all(void) /* nothing */ } -void xen_pre_device_suspend(void) -{ - /* nothing */ -} - void -xen_pre_suspend() +xen_arch_pre_suspend() { /* nothing */ } void -xen_post_suspend(int suspend_cancelled) +xen_arch_post_suspend(int suspend_cancelled) { if (suspend_cancelled) return; diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c index 4a3d3dd3dd30..45329c8c226e 100644 --- a/arch/x86/xen/suspend.c +++ b/arch/x86/xen/suspend.c @@ -12,7 +12,7 @@ #include "xen-ops.h" #include "mmu.h" -void xen_pre_suspend(void) +void xen_arch_pre_suspend(void) { xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn); xen_start_info->console.domU.mfn = @@ -26,7 +26,7 @@ void xen_pre_suspend(void) BUG(); } -void xen_hvm_post_suspend(int suspend_cancelled) +void xen_arch_hvm_post_suspend(int suspend_cancelled) { #ifdef CONFIG_XEN_PVHVM int cpu; @@ -41,7 +41,7 @@ void xen_hvm_post_suspend(int suspend_cancelled) #endif } -void xen_post_suspend(int suspend_cancelled) +void xen_arch_post_suspend(int suspend_cancelled) { xen_build_mfn_list_list(); diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 6ce6b91e7645..134eb73ca596 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -61,7 +61,7 @@ static int xen_hvm_suspend(void *data) */ si->cancelled = HYPERVISOR_suspend(si->arg); - xen_hvm_post_suspend(si->cancelled); + xen_arch_hvm_post_suspend(si->cancelled); gnttab_resume(); if (!si->cancelled) { @@ -91,7 +91,7 @@ static int xen_suspend(void *data) xen_mm_pin_all(); gnttab_suspend(); - xen_pre_suspend(); + xen_arch_pre_suspend(); /* * This hypercall returns 1 if suspend was cancelled @@ -100,7 +100,7 @@ static int xen_suspend(void *data) */ si->cancelled = HYPERVISOR_suspend(si->arg); - xen_post_suspend(si->cancelled); + xen_arch_post_suspend(si->cancelled); gnttab_resume(); xen_mm_unpin_all(); diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index 98b92154a264..03c85d7387fb 100644 --- a/include/xen/xen-ops.h +++ b/include/xen/xen-ops.h @@ -5,9 +5,9 @@ DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu); -void xen_pre_suspend(void); -void xen_post_suspend(int suspend_cancelled); -void xen_hvm_post_suspend(int suspend_cancelled); +void xen_arch_pre_suspend(void); +void xen_arch_post_suspend(int suspend_cancelled); +void xen_arch_hvm_post_suspend(int suspend_cancelled); void xen_mm_pin_all(void); void xen_mm_unpin_all(void); -- cgit v1.2.3 From 82043bb60d24d2897074905c94be5a53071e8913 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 17 Feb 2011 11:04:20 +0000 Subject: xen: suspend: refactor non-arch specific pre/post suspend hooks Signed-off-by: Ian Campbell Reviewed-by: Konrad Rzeszutek Wilk --- drivers/xen/manage.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 134eb73ca596..33312c09829e 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -39,6 +39,23 @@ struct suspend_info { unsigned long arg; /* extra hypercall argument */ }; +static void xen_hvm_post_suspend(void) +{ + gnttab_resume(); +} + +static void xen_pre_suspend(void) +{ + xen_mm_pin_all(); + gnttab_suspend(); +} + +static void xen_post_suspend(void) +{ + gnttab_resume(); + xen_mm_unpin_all(); +} + #ifdef CONFIG_PM_SLEEP static int xen_hvm_suspend(void *data) { @@ -62,7 +79,7 @@ static int xen_hvm_suspend(void *data) si->cancelled = HYPERVISOR_suspend(si->arg); xen_arch_hvm_post_suspend(si->cancelled); - gnttab_resume(); + xen_hvm_post_suspend(); if (!si->cancelled) { xen_irq_resume(); @@ -89,8 +106,7 @@ static int xen_suspend(void *data) return err; } - xen_mm_pin_all(); - gnttab_suspend(); + xen_pre_suspend(); xen_arch_pre_suspend(); /* @@ -101,8 +117,7 @@ static int xen_suspend(void *data) si->cancelled = HYPERVISOR_suspend(si->arg); xen_arch_post_suspend(si->cancelled); - gnttab_resume(); - xen_mm_unpin_all(); + xen_post_suspend(); if (!si->cancelled) { xen_irq_resume(); -- cgit v1.2.3 From 07af38102fc4f260cc5a2418ec833707f53cdf70 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 17 Feb 2011 11:04:20 +0000 Subject: xen: suspend: move arch specific pre/post suspend hooks into generic hooks Signed-off-by: Ian Campbell Reviewed-by: Konrad Rzeszutek Wilk --- drivers/xen/manage.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 33312c09829e..a6bd2e9ca106 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -39,8 +39,9 @@ struct suspend_info { unsigned long arg; /* extra hypercall argument */ }; -static void xen_hvm_post_suspend(void) +static void xen_hvm_post_suspend(int cancelled) { + xen_arch_hvm_post_suspend(cancelled); gnttab_resume(); } @@ -48,10 +49,12 @@ static void xen_pre_suspend(void) { xen_mm_pin_all(); gnttab_suspend(); + xen_arch_pre_suspend(); } -static void xen_post_suspend(void) +static void xen_post_suspend(int cancelled) { + xen_arch_post_suspend(cancelled); gnttab_resume(); xen_mm_unpin_all(); } @@ -78,8 +81,7 @@ static int xen_hvm_suspend(void *data) */ si->cancelled = HYPERVISOR_suspend(si->arg); - xen_arch_hvm_post_suspend(si->cancelled); - xen_hvm_post_suspend(); + xen_hvm_post_suspend(si->cancelled); if (!si->cancelled) { xen_irq_resume(); @@ -107,7 +109,6 @@ static int xen_suspend(void *data) } xen_pre_suspend(); - xen_arch_pre_suspend(); /* * This hypercall returns 1 if suspend was cancelled @@ -116,8 +117,7 @@ static int xen_suspend(void *data) */ si->cancelled = HYPERVISOR_suspend(si->arg); - xen_arch_post_suspend(si->cancelled); - xen_post_suspend(); + xen_post_suspend(si->cancelled); if (!si->cancelled) { xen_irq_resume(); -- cgit v1.2.3 From 55fb4acef7089a6d4d93ed8caae6c258d06cfaf7 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 17 Feb 2011 11:04:20 +0000 Subject: xen: suspend: pull pre/post suspend hooks out into suspend_info Signed-off-by: Ian Campbell Reviewed-by: Konrad Rzeszutek Wilk --- drivers/xen/manage.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index a6bd2e9ca106..5b7a0a9402e7 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -37,6 +37,8 @@ static enum shutdown_state shutting_down = SHUTDOWN_INVALID; struct suspend_info { int cancelled; unsigned long arg; /* extra hypercall argument */ + void (*pre)(void); + void (*post)(int cancelled); }; static void xen_hvm_post_suspend(int cancelled) @@ -74,6 +76,9 @@ static int xen_hvm_suspend(void *data) return err; } + if (si->pre) + si->pre(); + /* * This hypercall returns 1 if suspend was cancelled * or the domain was merely checkpointed, and 0 if it @@ -81,7 +86,8 @@ static int xen_hvm_suspend(void *data) */ si->cancelled = HYPERVISOR_suspend(si->arg); - xen_hvm_post_suspend(si->cancelled); + if (si->post) + si->post(si->cancelled); if (!si->cancelled) { xen_irq_resume(); @@ -108,7 +114,8 @@ static int xen_suspend(void *data) return err; } - xen_pre_suspend(); + if (si->pre) + si->pre(); /* * This hypercall returns 1 if suspend was cancelled @@ -117,7 +124,8 @@ static int xen_suspend(void *data) */ si->cancelled = HYPERVISOR_suspend(si->arg); - xen_post_suspend(si->cancelled); + if (si->post) + si->post(si->cancelled); if (!si->cancelled) { xen_irq_resume(); @@ -165,10 +173,15 @@ static void do_suspend(void) si.cancelled = 1; - if (xen_hvm_domain()) + if (xen_hvm_domain()) { si.arg = 0UL; - else + si.pre = NULL; + si.post = &xen_hvm_post_suspend; + } else { si.arg = virt_to_mfn(xen_start_info); + si.pre = &xen_pre_suspend; + si.post = &xen_post_suspend; + } if (xen_hvm_domain()) err = stop_machine(xen_hvm_suspend, &si, cpumask_of(0)); -- cgit v1.2.3 From b056b6a0144de90707cd22cf7b4f60bf69c86d59 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 17 Feb 2011 11:04:20 +0000 Subject: xen: suspend: remove xen_hvm_suspend It is now identical to xen_suspend, the differences are encapsulated in the suspend_info struct. Signed-off-by: Ian Campbell Reviewed-by: Konrad Rzeszutek Wilk --- drivers/xen/manage.c | 43 +------------------------------------------ 1 file changed, 1 insertion(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 5b7a0a9402e7..ebb292859b59 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -62,44 +62,6 @@ static void xen_post_suspend(int cancelled) } #ifdef CONFIG_PM_SLEEP -static int xen_hvm_suspend(void *data) -{ - struct suspend_info *si = data; - int err; - - BUG_ON(!irqs_disabled()); - - err = sysdev_suspend(PMSG_SUSPEND); - if (err) { - printk(KERN_ERR "xen_hvm_suspend: sysdev_suspend failed: %d\n", - err); - return err; - } - - if (si->pre) - si->pre(); - - /* - * This hypercall returns 1 if suspend was cancelled - * or the domain was merely checkpointed, and 0 if it - * is resuming in a new domain. - */ - si->cancelled = HYPERVISOR_suspend(si->arg); - - if (si->post) - si->post(si->cancelled); - - if (!si->cancelled) { - xen_irq_resume(); - xen_console_resume(); - xen_timer_resume(); - } - - sysdev_resume(); - - return 0; -} - static int xen_suspend(void *data) { struct suspend_info *si = data; @@ -183,10 +145,7 @@ static void do_suspend(void) si.post = &xen_post_suspend; } - if (xen_hvm_domain()) - err = stop_machine(xen_hvm_suspend, &si, cpumask_of(0)); - else - err = stop_machine(xen_suspend, &si, cpumask_of(0)); + err = stop_machine(xen_suspend, &si, cpumask_of(0)); dpm_resume_noirq(PMSG_RESUME); -- cgit v1.2.3 From 310388beea4d00bb1c56e81ded82bdc25bdcf719 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 25 Feb 2011 09:53:41 -0800 Subject: tty: forgot to remove ipwireless from drivers/char/pcmcia/Makefile This caused a build error. Many thanks to Stephen Rothwell for pointing this mistake out. Reported-by: Stephen Rothwell Signed-off-by: Greg Kroah-Hartman --- drivers/char/pcmcia/Makefile | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/pcmcia/Makefile b/drivers/char/pcmcia/Makefile index be8f287aa398..0aae20985d57 100644 --- a/drivers/char/pcmcia/Makefile +++ b/drivers/char/pcmcia/Makefile @@ -4,8 +4,6 @@ # Makefile for the Linux PCMCIA char device drivers. # -obj-y += ipwireless/ - obj-$(CONFIG_SYNCLINK_CS) += synclink_cs.o obj-$(CONFIG_CARDMAN_4000) += cm4000_cs.o obj-$(CONFIG_CARDMAN_4040) += cm4040_cs.o -- cgit v1.2.3 From 65c56e073e4fd10385283561b91189572e33b519 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 25 Feb 2011 14:28:30 +0100 Subject: tty: phase out of ioctl file pointer for tty3270 as well The patch "tty: now phase out the ioctl file pointer for good" missed the tty3270 driver. This is the missing piece. Signed-off-by: Heiko Carstens Signed-off-by: Greg Kroah-Hartman --- drivers/s390/char/keyboard.c | 4 +--- drivers/s390/char/keyboard.h | 2 +- drivers/s390/char/tty3270.c | 14 ++++++-------- 3 files changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c index 8cd58e412b5e..d6673345c5f4 100644 --- a/drivers/s390/char/keyboard.c +++ b/drivers/s390/char/keyboard.c @@ -455,9 +455,7 @@ do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry __user *u_kbs, return 0; } -int -kbd_ioctl(struct kbd_data *kbd, struct file *file, - unsigned int cmd, unsigned long arg) +int kbd_ioctl(struct kbd_data *kbd, unsigned int cmd, unsigned long arg) { void __user *argp; int ct, perm; diff --git a/drivers/s390/char/keyboard.h b/drivers/s390/char/keyboard.h index 5ccfe9cf126d..7e736aaeae6e 100644 --- a/drivers/s390/char/keyboard.h +++ b/drivers/s390/char/keyboard.h @@ -36,7 +36,7 @@ void kbd_free(struct kbd_data *); void kbd_ascebc(struct kbd_data *, unsigned char *); void kbd_keycode(struct kbd_data *, unsigned int); -int kbd_ioctl(struct kbd_data *, struct file *, unsigned int, unsigned long); +int kbd_ioctl(struct kbd_data *, unsigned int, unsigned long); /* * Helper Functions. diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 911822db614d..d33554df2b06 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -1718,9 +1718,8 @@ tty3270_wait_until_sent(struct tty_struct *tty, int timeout) { } -static int -tty3270_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) +static int tty3270_ioctl(struct tty_struct *tty, unsigned int cmd, + unsigned long arg) { struct tty3270 *tp; @@ -1729,13 +1728,12 @@ tty3270_ioctl(struct tty_struct *tty, struct file *file, return -ENODEV; if (tty->flags & (1 << TTY_IO_ERROR)) return -EIO; - return kbd_ioctl(tp->kbd, file, cmd, arg); + return kbd_ioctl(tp->kbd, cmd, arg); } #ifdef CONFIG_COMPAT -static long -tty3270_compat_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) +static long tty3270_compat_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) { struct tty3270 *tp; @@ -1744,7 +1742,7 @@ tty3270_compat_ioctl(struct tty_struct *tty, struct file *file, return -ENODEV; if (tty->flags & (1 << TTY_IO_ERROR)) return -EIO; - return kbd_ioctl(tp->kbd, file, cmd, (unsigned long)compat_ptr(arg)); + return kbd_ioctl(tp->kbd, cmd, (unsigned long)compat_ptr(arg)); } #endif -- cgit v1.2.3 From 8c6e9112ebc7ba5a782e986152c8e766dad1486f Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 22 Feb 2011 19:12:21 -0700 Subject: tty/serial: Relax the device_type restriction from of_serial There is no need to test for a device_type property in ns8250 compatible serial ports. device_type is an OpenFirmware property that is not required when using the flattened tree representation. Signed-off-by: Grant Likely Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/of_serial.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 5c7abe4c94dd..6a18ca6ddaa9 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -160,17 +160,17 @@ static int of_platform_serial_remove(struct platform_device *ofdev) * A few common types, add more as needed. */ static struct of_device_id __devinitdata of_platform_serial_table[] = { - { .type = "serial", .compatible = "ns8250", .data = (void *)PORT_8250, }, - { .type = "serial", .compatible = "ns16450", .data = (void *)PORT_16450, }, - { .type = "serial", .compatible = "ns16550a", .data = (void *)PORT_16550A, }, - { .type = "serial", .compatible = "ns16550", .data = (void *)PORT_16550, }, - { .type = "serial", .compatible = "ns16750", .data = (void *)PORT_16750, }, - { .type = "serial", .compatible = "ns16850", .data = (void *)PORT_16850, }, + { .compatible = "ns8250", .data = (void *)PORT_8250, }, + { .compatible = "ns16450", .data = (void *)PORT_16450, }, + { .compatible = "ns16550a", .data = (void *)PORT_16550A, }, + { .compatible = "ns16550", .data = (void *)PORT_16550, }, + { .compatible = "ns16750", .data = (void *)PORT_16750, }, + { .compatible = "ns16850", .data = (void *)PORT_16850, }, #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL - { .type = "serial", .compatible = "ibm,qpace-nwp-serial", - .data = (void *)PORT_NWPSERIAL, }, + { .compatible = "ibm,qpace-nwp-serial", + .data = (void *)PORT_NWPSERIAL, }, #endif - { .type = "serial", .data = (void *)PORT_UNKNOWN, }, + { .type = "serial", .data = (void *)PORT_UNKNOWN, }, { /* end of list */ }, }; -- cgit v1.2.3 From 294d95f2cbc2aef5346258f216cd9df570e271a5 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 11 Jan 2011 12:26:48 -0500 Subject: ehci: Check individual port status registers on resume If a device plug/unplug is detected on an ATI SB700 USB controller in D3, it appears to set the port status register but not the controller status register. As a result we'll fail to detect the plug event. Check the port status register on resume as well in order to catch this case. Signed-off-by: Matthew Garrett Cc: stable [after .39-rc1 is out] Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hub.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index c0b37fedfbc2..ae0140dd9b9b 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -106,6 +106,27 @@ static void ehci_handover_companion_ports(struct ehci_hcd *ehci) ehci->owned_ports = 0; } +static int ehci_port_change(struct ehci_hcd *ehci) +{ + int i = HCS_N_PORTS(ehci->hcs_params); + + /* First check if the controller indicates a change event */ + + if (ehci_readl(ehci, &ehci->regs->status) & STS_PCD) + return 1; + + /* + * Not all controllers appear to update this while going from D3 to D0, + * so check the individual port status registers as well + */ + + while (i--) + if (ehci_readl(ehci, &ehci->regs->port_status[i]) & PORT_CSC) + return 1; + + return 0; +} + static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, bool suspending, bool do_wakeup) { @@ -173,7 +194,7 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, } /* Does the root hub have a port wakeup pending? */ - if (!suspending && (ehci_readl(ehci, &ehci->regs->status) & STS_PCD)) + if (!suspending && ehci_port_change(ehci)) usb_hcd_resume_root_hub(ehci_to_hcd(ehci)); spin_unlock_irqrestore(&ehci->lock, flags); -- cgit v1.2.3 From 108be95f9ffc53660c9a35b5ceef94121b1e23c4 Mon Sep 17 00:00:00 2001 From: Yusuke Goda Date: Mon, 21 Feb 2011 12:55:32 +0900 Subject: usb: m66592-udc: Fixed bufnum of Bulk Signed-off-by: Yusuke Goda Acked-by: Yoshihiro Shimoda Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/m66592-udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 51b19f3027e7..084aa080a2d5 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -258,7 +258,7 @@ static int pipe_buffer_setting(struct m66592 *m66592, break; case M66592_BULK: /* isochronous pipes may be used as bulk pipes */ - if (info->pipe > M66592_BASE_PIPENUM_BULK) + if (info->pipe >= M66592_BASE_PIPENUM_BULK) bufnum = info->pipe - M66592_BASE_PIPENUM_BULK; else bufnum = info->pipe - M66592_BASE_PIPENUM_ISOC; -- cgit v1.2.3 From d866150a1914453c3d57689adfd8d01bf741d9d4 Mon Sep 17 00:00:00 2001 From: Huzaifa Sidhpurwala Date: Mon, 21 Feb 2011 12:58:44 +0530 Subject: USB: serial: keyspan: Fix possible null pointer dereference. Signed-off-by: Huzaifa Sidhpurwala Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/keyspan.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 0791778a66f3..67f41b526570 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -2121,16 +2121,16 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial, /* Work out which port within the device is being setup */ device_port = port->number - port->serial->minor; - dbg("%s - endpoint %d port %d (%d)", - __func__, usb_pipeendpoint(this_urb->pipe), - port->number, device_port); - - /* Make sure we have an urb then send the message */ + /* Make sure we have an urb then send the message */ if (this_urb == NULL) { dbg("%s - oops no urb for port %d.", __func__, port->number); return -1; } + dbg("%s - endpoint %d port %d (%d)", + __func__, usb_pipeendpoint(this_urb->pipe), + port->number, device_port); + /* Save reset port val for resend. Don't overwrite resend for open/close condition. */ if ((reset_port + 1) > p_priv->resend_cont) -- cgit v1.2.3 From 91f58ae61913b40da35e119017e70b3420c6f3a0 Mon Sep 17 00:00:00 2001 From: Huzaifa Sidhpurwala Date: Mon, 21 Feb 2011 12:58:45 +0530 Subject: USB: serial: mos7720: Fix possible null pointer dereference Signed-off-by: Huzaifa Sidhpurwala Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mos7720.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 7d3bc9a3e2b6..ae506f4ee29d 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -2052,7 +2052,7 @@ static int mos7720_startup(struct usb_serial *serial) struct usb_device *dev; int i; char data; - u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); + u16 product; int ret_val; dbg("%s: Entering ..........", __func__); @@ -2062,6 +2062,7 @@ static int mos7720_startup(struct usb_serial *serial) return -ENODEV; } + product = le16_to_cpu(serial->dev->descriptor.idProduct); dev = serial->dev; /* -- cgit v1.2.3 From 0e6ca1998e4c803b0be98f97a1d1e1ea562b8964 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Fri, 18 Feb 2011 17:43:16 +0530 Subject: USB: gadget: Implement hardware queuing in ci13xxx_udc Chipidea USB controller provides a means (Add dTD TripWire semaphore) for safely adding a new dTD to an active endpoint's linked list. Make use of this feature to improve performance. Dynamically allocate and free dTD for supporting zero length packet termination. Honor no_interrupt flag set by gadget drivers. Signed-off-by: Pavankumar Kondeti Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/ci13xxx_udc.c | 176 ++++++++++++++++++++++----------------- drivers/usb/gadget/ci13xxx_udc.h | 4 + 2 files changed, 104 insertions(+), 76 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index a1c67ae1572a..da01f333a51c 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c @@ -434,20 +434,6 @@ static int hw_ep_get_halt(int num, int dir) return hw_cread(CAP_ENDPTCTRL + num * sizeof(u32), mask) ? 1 : 0; } -/** - * hw_ep_is_primed: test if endpoint is primed (execute without interruption) - * @num: endpoint number - * @dir: endpoint direction - * - * This function returns true if endpoint primed - */ -static int hw_ep_is_primed(int num, int dir) -{ - u32 reg = hw_cread(CAP_ENDPTPRIME, ~0) | hw_cread(CAP_ENDPTSTAT, ~0); - - return test_bit(hw_ep_bit(num, dir), (void *)®); -} - /** * hw_test_and_clear_setup_status: test & clear setup status (execute without * interruption) @@ -472,10 +458,6 @@ static int hw_ep_prime(int num, int dir, int is_ctrl) { int n = hw_ep_bit(num, dir); - /* the caller should flush first */ - if (hw_ep_is_primed(num, dir)) - return -EBUSY; - if (is_ctrl && dir == RX && hw_cread(CAP_ENDPTSETUPSTAT, BIT(num))) return -EAGAIN; @@ -1434,6 +1416,8 @@ static inline u8 _usb_addr(struct ci13xxx_ep *ep) static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) { unsigned i; + int ret = 0; + unsigned length = mReq->req.length; trace("%p, %p", mEp, mReq); @@ -1441,53 +1425,91 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) if (mReq->req.status == -EALREADY) return -EALREADY; - if (hw_ep_is_primed(mEp->num, mEp->dir)) - return -EBUSY; - mReq->req.status = -EALREADY; - - if (mReq->req.length && !mReq->req.dma) { + if (length && !mReq->req.dma) { mReq->req.dma = \ dma_map_single(mEp->device, mReq->req.buf, - mReq->req.length, mEp->dir ? - DMA_TO_DEVICE : DMA_FROM_DEVICE); + length, mEp->dir ? DMA_TO_DEVICE : + DMA_FROM_DEVICE); if (mReq->req.dma == 0) return -ENOMEM; mReq->map = 1; } + if (mReq->req.zero && length && (length % mEp->ep.maxpacket == 0)) { + mReq->zptr = dma_pool_alloc(mEp->td_pool, GFP_ATOMIC, + &mReq->zdma); + if (mReq->zptr == NULL) { + if (mReq->map) { + dma_unmap_single(mEp->device, mReq->req.dma, + length, mEp->dir ? DMA_TO_DEVICE : + DMA_FROM_DEVICE); + mReq->req.dma = 0; + mReq->map = 0; + } + return -ENOMEM; + } + memset(mReq->zptr, 0, sizeof(*mReq->zptr)); + mReq->zptr->next = TD_TERMINATE; + mReq->zptr->token = TD_STATUS_ACTIVE; + if (!mReq->req.no_interrupt) + mReq->zptr->token |= TD_IOC; + } /* * TD configuration * TODO - handle requests which spawns into several TDs */ memset(mReq->ptr, 0, sizeof(*mReq->ptr)); - mReq->ptr->next |= TD_TERMINATE; - mReq->ptr->token = mReq->req.length << ffs_nr(TD_TOTAL_BYTES); + mReq->ptr->token = length << ffs_nr(TD_TOTAL_BYTES); mReq->ptr->token &= TD_TOTAL_BYTES; - mReq->ptr->token |= TD_IOC; mReq->ptr->token |= TD_STATUS_ACTIVE; + if (mReq->zptr) { + mReq->ptr->next = mReq->zdma; + } else { + mReq->ptr->next = TD_TERMINATE; + if (!mReq->req.no_interrupt) + mReq->ptr->token |= TD_IOC; + } mReq->ptr->page[0] = mReq->req.dma; for (i = 1; i < 5; i++) mReq->ptr->page[i] = (mReq->req.dma + i * CI13XXX_PAGE_SIZE) & ~TD_RESERVED_MASK; - /* - * QH configuration - * At this point it's guaranteed exclusive access to qhead - * (endpt is not primed) so it's no need to use tripwire - */ + if (!list_empty(&mEp->qh.queue)) { + struct ci13xxx_req *mReqPrev; + int n = hw_ep_bit(mEp->num, mEp->dir); + int tmp_stat; + + mReqPrev = list_entry(mEp->qh.queue.prev, + struct ci13xxx_req, queue); + if (mReqPrev->zptr) + mReqPrev->zptr->next = mReq->dma & TD_ADDR_MASK; + else + mReqPrev->ptr->next = mReq->dma & TD_ADDR_MASK; + wmb(); + if (hw_cread(CAP_ENDPTPRIME, BIT(n))) + goto done; + do { + hw_cwrite(CAP_USBCMD, USBCMD_ATDTW, USBCMD_ATDTW); + tmp_stat = hw_cread(CAP_ENDPTSTAT, BIT(n)); + } while (!hw_cread(CAP_USBCMD, USBCMD_ATDTW)); + hw_cwrite(CAP_USBCMD, USBCMD_ATDTW, 0); + if (tmp_stat) + goto done; + } + + /* QH configuration */ mEp->qh.ptr->td.next = mReq->dma; /* TERMINATE = 0 */ mEp->qh.ptr->td.token &= ~TD_STATUS; /* clear status */ - if (mReq->req.zero == 0) - mEp->qh.ptr->cap |= QH_ZLT; - else - mEp->qh.ptr->cap &= ~QH_ZLT; + mEp->qh.ptr->cap |= QH_ZLT; wmb(); /* synchronize before ep prime */ - return hw_ep_prime(mEp->num, mEp->dir, + ret = hw_ep_prime(mEp->num, mEp->dir, mEp->type == USB_ENDPOINT_XFER_CONTROL); +done: + return ret; } /** @@ -1504,8 +1526,15 @@ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) if (mReq->req.status != -EALREADY) return -EINVAL; - if (hw_ep_is_primed(mEp->num, mEp->dir)) - hw_ep_flush(mEp->num, mEp->dir); + if ((TD_STATUS_ACTIVE & mReq->ptr->token) != 0) + return -EBUSY; + + if (mReq->zptr) { + if ((TD_STATUS_ACTIVE & mReq->zptr->token) != 0) + return -EBUSY; + dma_pool_free(mEp->td_pool, mReq->zptr, mReq->zdma); + mReq->zptr = NULL; + } mReq->req.status = 0; @@ -1517,9 +1546,7 @@ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) } mReq->req.status = mReq->ptr->token & TD_STATUS; - if ((TD_STATUS_ACTIVE & mReq->req.status) != 0) - mReq->req.status = -ECONNRESET; - else if ((TD_STATUS_HALTED & mReq->req.status) != 0) + if ((TD_STATUS_HALTED & mReq->req.status) != 0) mReq->req.status = -1; else if ((TD_STATUS_DT_ERR & mReq->req.status) != 0) mReq->req.status = -1; @@ -1783,7 +1810,7 @@ static int isr_tr_complete_low(struct ci13xxx_ep *mEp) __releases(mEp->lock) __acquires(mEp->lock) { - struct ci13xxx_req *mReq; + struct ci13xxx_req *mReq, *mReqTemp; int retval; trace("%p", mEp); @@ -1791,34 +1818,25 @@ __acquires(mEp->lock) if (list_empty(&mEp->qh.queue)) return -EINVAL; - /* pop oldest request */ - mReq = list_entry(mEp->qh.queue.next, - struct ci13xxx_req, queue); - list_del_init(&mReq->queue); - - retval = _hardware_dequeue(mEp, mReq); - if (retval < 0) { - dbg_event(_usb_addr(mEp), "DONE", retval); - goto done; - } - - dbg_done(_usb_addr(mEp), mReq->ptr->token, retval); - - if (!list_empty(&mEp->qh.queue)) { - struct ci13xxx_req* mReqEnq; - - mReqEnq = list_entry(mEp->qh.queue.next, - struct ci13xxx_req, queue); - _hardware_enqueue(mEp, mReqEnq); + list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue, + queue) { + retval = _hardware_dequeue(mEp, mReq); + if (retval < 0) + break; + list_del_init(&mReq->queue); + dbg_done(_usb_addr(mEp), mReq->ptr->token, retval); + if (mReq->req.complete != NULL) { + spin_unlock(mEp->lock); + mReq->req.complete(&mEp->ep, &mReq->req); + spin_lock(mEp->lock); + } } - if (mReq->req.complete != NULL) { - spin_unlock(mEp->lock); - mReq->req.complete(&mEp->ep, &mReq->req); - spin_lock(mEp->lock); - } + if (retval == EBUSY) + retval = 0; + if (retval < 0) + dbg_event(_usb_addr(mEp), "DONE", retval); - done: return retval; } @@ -2178,15 +2196,15 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req, /* push request */ mReq->req.status = -EINPROGRESS; mReq->req.actual = 0; - list_add_tail(&mReq->queue, &mEp->qh.queue); - if (list_is_singular(&mEp->qh.queue)) - retval = _hardware_enqueue(mEp, mReq); + retval = _hardware_enqueue(mEp, mReq); if (retval == -EALREADY) { dbg_event(_usb_addr(mEp), "QUEUE", retval); retval = 0; } + if (!retval) + list_add_tail(&mReq->queue, &mEp->qh.queue); done: spin_unlock_irqrestore(mEp->lock, flags); @@ -2206,19 +2224,25 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req) trace("%p, %p", ep, req); - if (ep == NULL || req == NULL || mEp->desc == NULL || - list_empty(&mReq->queue) || list_empty(&mEp->qh.queue)) + if (ep == NULL || req == NULL || mReq->req.status != -EALREADY || + mEp->desc == NULL || list_empty(&mReq->queue) || + list_empty(&mEp->qh.queue)) return -EINVAL; spin_lock_irqsave(mEp->lock, flags); dbg_event(_usb_addr(mEp), "DEQUEUE", 0); - if (mReq->req.status == -EALREADY) - _hardware_dequeue(mEp, mReq); + hw_ep_flush(mEp->num, mEp->dir); /* pop request */ list_del_init(&mReq->queue); + if (mReq->map) { + dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length, + mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + mReq->req.dma = 0; + mReq->map = 0; + } req->status = -ECONNRESET; if (mReq->req.complete != NULL) { diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h index a2492b65f98c..3fad3adeacc8 100644 --- a/drivers/usb/gadget/ci13xxx_udc.h +++ b/drivers/usb/gadget/ci13xxx_udc.h @@ -33,6 +33,7 @@ struct ci13xxx_td { /* 0 */ u32 next; #define TD_TERMINATE BIT(0) +#define TD_ADDR_MASK (0xFFFFFFEUL << 5) /* 1 */ u32 token; #define TD_STATUS (0x00FFUL << 0) @@ -74,6 +75,8 @@ struct ci13xxx_req { struct list_head queue; struct ci13xxx_td *ptr; dma_addr_t dma; + struct ci13xxx_td *zptr; + dma_addr_t zdma; }; /* Extension of usb_ep */ @@ -152,6 +155,7 @@ struct ci13xxx { #define USBCMD_RS BIT(0) #define USBCMD_RST BIT(1) #define USBCMD_SUTW BIT(13) +#define USBCMD_ATDTW BIT(14) /* USBSTS & USBINTR */ #define USBi_UI BIT(0) -- cgit v1.2.3 From e2b61c1df650595d0216c6d086024b5a98d949c7 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Fri, 18 Feb 2011 17:43:17 +0530 Subject: USB: gadget: Implement remote wakeup in ci13xxx_udc This patch adds support for remote wakeup. The following things are handled: - Process SET_FEATURE/CLEAR_FEATURE control requests sent by host for enabling/disabling remote wakeup feature. - Report remote wakeup enable status in response to GET_STATUS control request. - Implement wakeup method defined in usb_gadget_ops for initiating remote wakeup. - Notify gadget driver about suspend and resume. Signed-off-by: Pavankumar Kondeti Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/ci13xxx_udc.c | 124 ++++++++++++++++++++++++++++++--------- drivers/usb/gadget/ci13xxx_udc.h | 4 ++ 2 files changed, 99 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index da01f333a51c..17526759c9ce 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c @@ -1608,12 +1608,19 @@ static int _gadget_stop_activity(struct usb_gadget *gadget) { struct usb_ep *ep; struct ci13xxx *udc = container_of(gadget, struct ci13xxx, gadget); + unsigned long flags; trace("%p", gadget); if (gadget == NULL) return -EINVAL; + spin_lock_irqsave(udc->lock, flags); + udc->gadget.speed = USB_SPEED_UNKNOWN; + udc->remote_wakeup = 0; + udc->suspended = 0; + spin_unlock_irqrestore(udc->lock, flags); + /* flush all endpoints */ gadget_for_each_ep(ep, gadget) { usb_ep_fifo_flush(ep); @@ -1747,7 +1754,8 @@ __acquires(mEp->lock) } if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) { - /* TODO: D1 - Remote Wakeup; D0 - Self Powered */ + /* Assume that device is bus powered for now. */ + *((u16 *)req->buf) = _udc->remote_wakeup << 1; retval = 0; } else if ((setup->bRequestType & USB_RECIP_MASK) \ == USB_RECIP_ENDPOINT) { @@ -1913,22 +1921,32 @@ __acquires(udc->lock) switch (req.bRequest) { case USB_REQ_CLEAR_FEATURE: - if (type != (USB_DIR_OUT|USB_RECIP_ENDPOINT) && - le16_to_cpu(req.wValue) != USB_ENDPOINT_HALT) - goto delegate; - if (req.wLength != 0) - break; - num = le16_to_cpu(req.wIndex); - num &= USB_ENDPOINT_NUMBER_MASK; - if (!udc->ci13xxx_ep[num].wedge) { - spin_unlock(udc->lock); - err = usb_ep_clear_halt( - &udc->ci13xxx_ep[num].ep); - spin_lock(udc->lock); - if (err) + if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) && + le16_to_cpu(req.wValue) == + USB_ENDPOINT_HALT) { + if (req.wLength != 0) + break; + num = le16_to_cpu(req.wIndex); + num &= USB_ENDPOINT_NUMBER_MASK; + if (!udc->ci13xxx_ep[num].wedge) { + spin_unlock(udc->lock); + err = usb_ep_clear_halt( + &udc->ci13xxx_ep[num].ep); + spin_lock(udc->lock); + if (err) + break; + } + err = isr_setup_status_phase(udc); + } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE) && + le16_to_cpu(req.wValue) == + USB_DEVICE_REMOTE_WAKEUP) { + if (req.wLength != 0) break; + udc->remote_wakeup = 0; + err = isr_setup_status_phase(udc); + } else { + goto delegate; } - err = isr_setup_status_phase(udc); break; case USB_REQ_GET_STATUS: if (type != (USB_DIR_IN|USB_RECIP_DEVICE) && @@ -1952,20 +1970,29 @@ __acquires(udc->lock) err = isr_setup_status_phase(udc); break; case USB_REQ_SET_FEATURE: - if (type != (USB_DIR_OUT|USB_RECIP_ENDPOINT) && - le16_to_cpu(req.wValue) != USB_ENDPOINT_HALT) - goto delegate; - if (req.wLength != 0) - break; - num = le16_to_cpu(req.wIndex); - num &= USB_ENDPOINT_NUMBER_MASK; + if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) && + le16_to_cpu(req.wValue) == + USB_ENDPOINT_HALT) { + if (req.wLength != 0) + break; + num = le16_to_cpu(req.wIndex); + num &= USB_ENDPOINT_NUMBER_MASK; - spin_unlock(udc->lock); - err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep); - spin_lock(udc->lock); - if (err) - break; - err = isr_setup_status_phase(udc); + spin_unlock(udc->lock); + err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep); + spin_lock(udc->lock); + if (!err) + err = isr_setup_status_phase(udc); + } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE) && + le16_to_cpu(req.wValue) == + USB_DEVICE_REMOTE_WAKEUP) { + if (req.wLength != 0) + break; + udc->remote_wakeup = 1; + err = isr_setup_status_phase(udc); + } else { + goto delegate; + } break; default: delegate: @@ -2401,6 +2428,31 @@ static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active) return 0; } +static int ci13xxx_wakeup(struct usb_gadget *_gadget) +{ + struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget); + unsigned long flags; + int ret = 0; + + trace(); + + spin_lock_irqsave(udc->lock, flags); + if (!udc->remote_wakeup) { + ret = -EOPNOTSUPP; + dbg_trace("remote wakeup feature is not enabled\n"); + goto out; + } + if (!hw_cread(CAP_PORTSC, PORTSC_SUSP)) { + ret = -EINVAL; + dbg_trace("port is not suspended\n"); + goto out; + } + hw_cwrite(CAP_PORTSC, PORTSC_FPR, PORTSC_FPR); +out: + spin_unlock_irqrestore(udc->lock, flags); + return ret; +} + /** * Device operations part of the API to the USB controller hardware, * which don't involve endpoints (or i/o) @@ -2408,6 +2460,7 @@ static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active) */ static const struct usb_gadget_ops usb_gadget_ops = { .vbus_session = ci13xxx_vbus_session, + .wakeup = ci13xxx_wakeup, }; /** @@ -2650,6 +2703,12 @@ static irqreturn_t udc_irq(void) isr_statistics.pci++; udc->gadget.speed = hw_port_is_high_speed() ? USB_SPEED_HIGH : USB_SPEED_FULL; + if (udc->suspended) { + spin_unlock(udc->lock); + udc->driver->resume(&udc->gadget); + spin_lock(udc->lock); + udc->suspended = 0; + } } if (USBi_UEI & intr) isr_statistics.uei++; @@ -2657,8 +2716,15 @@ static irqreturn_t udc_irq(void) isr_statistics.ui++; isr_tr_complete_handler(udc); } - if (USBi_SLI & intr) + if (USBi_SLI & intr) { + if (udc->gadget.speed != USB_SPEED_UNKNOWN) { + udc->suspended = 1; + spin_unlock(udc->lock); + udc->driver->suspend(&udc->gadget); + spin_lock(udc->lock); + } isr_statistics.sli++; + } retval = IRQ_HANDLED; } else { isr_statistics.none++; diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h index 3fad3adeacc8..6cfab20db6bd 100644 --- a/drivers/usb/gadget/ci13xxx_udc.h +++ b/drivers/usb/gadget/ci13xxx_udc.h @@ -128,6 +128,9 @@ struct ci13xxx { u32 ep0_dir; /* ep0 direction */ #define ep0out ci13xxx_ep[0] #define ep0in ci13xxx_ep[16] + u8 remote_wakeup; /* Is remote wakeup feature + enabled by the host? */ + u8 suspended; /* suspended by the host */ struct usb_gadget_driver *driver; /* 3rd party gadget driver */ struct ci13xxx_udc_driver *udc_driver; /* device controller driver */ @@ -169,6 +172,7 @@ struct ci13xxx { #define DEVICEADDR_USBADR (0x7FUL << 25) /* PORTSC */ +#define PORTSC_FPR BIT(6) #define PORTSC_SUSP BIT(7) #define PORTSC_HSP BIT(9) #define PORTSC_PTC (0x0FUL << 16) -- cgit v1.2.3 From 541cace8cd619808424ffaf1c8f7a006e5d55742 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Fri, 18 Feb 2011 17:43:18 +0530 Subject: USB: gadget: Add test mode support for ci13xxx_udc Implement the test modes mentioned in 7.1.20 section of USB 2.0 specification. High-speed capable devices must support these test modes to facilitate compliance testing. Signed-off-by: Pavankumar Kondeti Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/ci13xxx_udc.c | 56 +++++++++++++++++++++++++++++++++++----- drivers/usb/gadget/ci13xxx_udc.h | 1 + 2 files changed, 51 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index 17526759c9ce..e09178bc1450 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c @@ -1783,6 +1783,28 @@ __acquires(mEp->lock) return retval; } +/** + * isr_setup_status_complete: setup_status request complete function + * @ep: endpoint + * @req: request handled + * + * Caller must release lock. Put the port in test mode if test mode + * feature is selected. + */ +static void +isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req) +{ + struct ci13xxx *udc = req->context; + unsigned long flags; + + trace("%p, %p", ep, req); + + spin_lock_irqsave(udc->lock, flags); + if (udc->test_mode) + hw_port_test_set(udc->test_mode); + spin_unlock_irqrestore(udc->lock, flags); +} + /** * isr_setup_status_phase: queues the status phase of a setup transation * @udc: udc struct @@ -1799,6 +1821,8 @@ __acquires(mEp->lock) trace("%p", udc); mEp = (udc->ep0_dir == TX) ? &udc->ep0out : &udc->ep0in; + udc->status->context = udc; + udc->status->complete = isr_setup_status_complete; spin_unlock(mEp->lock); retval = usb_ep_queue(&mEp->ep, udc->status, GFP_ATOMIC); @@ -1859,6 +1883,7 @@ __releases(udc->lock) __acquires(udc->lock) { unsigned i; + u8 tmode = 0; trace("%p", udc); @@ -1982,14 +2007,33 @@ __acquires(udc->lock) err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep); spin_lock(udc->lock); if (!err) - err = isr_setup_status_phase(udc); - } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE) && - le16_to_cpu(req.wValue) == - USB_DEVICE_REMOTE_WAKEUP) { + isr_setup_status_phase(udc); + } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE)) { if (req.wLength != 0) break; - udc->remote_wakeup = 1; - err = isr_setup_status_phase(udc); + switch (le16_to_cpu(req.wValue)) { + case USB_DEVICE_REMOTE_WAKEUP: + udc->remote_wakeup = 1; + err = isr_setup_status_phase(udc); + break; + case USB_DEVICE_TEST_MODE: + tmode = le16_to_cpu(req.wIndex) >> 8; + switch (tmode) { + case TEST_J: + case TEST_K: + case TEST_SE0_NAK: + case TEST_PACKET: + case TEST_FORCE_EN: + udc->test_mode = tmode; + err = isr_setup_status_phase( + udc); + break; + default: + break; + } + default: + goto delegate; + } } else { goto delegate; } diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h index 6cfab20db6bd..23707775cb43 100644 --- a/drivers/usb/gadget/ci13xxx_udc.h +++ b/drivers/usb/gadget/ci13xxx_udc.h @@ -131,6 +131,7 @@ struct ci13xxx { u8 remote_wakeup; /* Is remote wakeup feature enabled by the host? */ u8 suspended; /* suspended by the host */ + u8 test_mode; /* the selected test mode */ struct usb_gadget_driver *driver; /* 3rd party gadget driver */ struct ci13xxx_udc_driver *udc_driver; /* device controller driver */ -- cgit v1.2.3 From 18f53461e786f21e5625124b507802a797337f6f Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Fri, 18 Feb 2011 17:30:11 +0530 Subject: USB: EHCI: Fix compiler warnings with MSM driver This patch fixes the following compile warnings drivers/usb/host/ehci-dbg.c:45: warning: 'dbg_hcs_params' defined but not used drivers/usb/host/ehci-dbg.c:89: warning: 'dbg_hcc_params' defined but not used Signed-off-by: Pavankumar Kondeti Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-msm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index a80001420e3e..9ce1b0bc186d 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -1,6 +1,6 @@ /* ehci-msm.c - HSUSB Host Controller Driver Implementation * - * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. + * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved. * * Partly derived from ehci-fsl.c and ehci-hcd.c * Copyright (c) 2000-2004 by David Brownell @@ -42,6 +42,8 @@ static int ehci_msm_reset(struct usb_hcd *hcd) ehci->caps = USB_CAPLENGTH; ehci->regs = USB_CAPLENGTH + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + dbg_hcs_params(ehci, "reset"); + dbg_hcc_params(ehci, "reset"); /* cache the data to minimize the chip reads*/ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); -- cgit v1.2.3 From 10408bb9c4bf669f56f8de380f3ce18ef601a3d4 Mon Sep 17 00:00:00 2001 From: Rémi Denis-Courmont Date: Mon, 21 Feb 2011 16:16:53 +0200 Subject: USB: f_phonet: avoid pskb_pull(), fix OOPS with CONFIG_HIGHMEM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is similar to what we already do in cdc-phonet.c in the same situation. Signed-off-by: Rémi Denis-Courmont Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/f_phonet.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index 3c6e1a058745..5e1495097ec3 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/f_phonet.c @@ -346,14 +346,19 @@ static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req) if (unlikely(!skb)) break; - skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, 0, - req->actual); - page = NULL; - if (req->actual < req->length) { /* Last fragment */ + if (skb->len == 0) { /* First fragment */ skb->protocol = htons(ETH_P_PHONET); skb_reset_mac_header(skb); - pskb_pull(skb, 1); + /* Can't use pskb_pull() on page in IRQ */ + memcpy(skb_put(skb, 1), page_address(page), 1); + } + + skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, + skb->len == 0, req->actual); + page = NULL; + + if (req->actual < req->length) { /* Last fragment */ skb->dev = dev; dev->stats.rx_packets++; dev->stats.rx_bytes += skb->len; -- cgit v1.2.3 From 3b29b68b1627781b5eecb581d3b9d5f0043a72f2 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 22 Feb 2011 09:53:41 -0500 Subject: USB: use "device number" instead of "address" The USB stack historically has conflated device numbers (i.e., the value of udev->devnum) with device addresses. This is understandable, because until recently the two values were always the same. But with USB-3.0 they aren't the same, so we should start calling these things by their correct names. This patch (as1449b) changes many of the references to "address" in the hub driver to "device number" or "devnum". The patch also removes some unnecessary or misleading comments. Signed-off-by: Alan Stern Reported-by: Luben Tuikov Reviewed-by: Sarah Sharp Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 48 ++++++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index d041c6826e43..c168121f9f97 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1499,6 +1499,13 @@ void usb_set_device_state(struct usb_device *udev, EXPORT_SYMBOL_GPL(usb_set_device_state); /* + * Choose a device number. + * + * Device numbers are used as filenames in usbfs. On USB-1.1 and + * USB-2.0 buses they are also used as device addresses, however on + * USB-3.0 buses the address is assigned by the controller hardware + * and it usually is not the same as the device number. + * * WUSB devices are simple: they have no hubs behind, so the mapping * device <-> virtual port number becomes 1:1. Why? to simplify the * life of the device connection logic in @@ -1520,7 +1527,7 @@ EXPORT_SYMBOL_GPL(usb_set_device_state); * the HCD must setup data structures before issuing a set address * command to the hardware. */ -static void choose_address(struct usb_device *udev) +static void choose_devnum(struct usb_device *udev) { int devnum; struct usb_bus *bus = udev->bus; @@ -1545,7 +1552,7 @@ static void choose_address(struct usb_device *udev) } } -static void release_address(struct usb_device *udev) +static void release_devnum(struct usb_device *udev) { if (udev->devnum > 0) { clear_bit(udev->devnum, udev->bus->devmap.devicemap); @@ -1553,7 +1560,7 @@ static void release_address(struct usb_device *udev) } } -static void update_address(struct usb_device *udev, int devnum) +static void update_devnum(struct usb_device *udev, int devnum) { /* The address for a WUSB device is managed by wusbcore. */ if (!udev->wusb) @@ -1600,7 +1607,8 @@ void usb_disconnect(struct usb_device **pdev) * this quiesces everyting except pending urbs. */ usb_set_device_state(udev, USB_STATE_NOTATTACHED); - dev_info (&udev->dev, "USB disconnect, address %d\n", udev->devnum); + dev_info(&udev->dev, "USB disconnect, device number %d\n", + udev->devnum); usb_lock_device(udev); @@ -1630,7 +1638,7 @@ void usb_disconnect(struct usb_device **pdev) /* Free the device number and delete the parent's children[] * (or root_hub) pointer. */ - release_address(udev); + release_devnum(udev); /* Avoid races with recursively_mark_NOTATTACHED() */ spin_lock_irq(&device_state_lock); @@ -2071,7 +2079,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1, case 0: /* TRSTRCY = 10 ms; plus some extra */ msleep(10 + 40); - update_address(udev, 0); + update_devnum(udev, 0); if (hcd->driver->reset_device) { status = hcd->driver->reset_device(hcd, udev); if (status < 0) { @@ -2634,7 +2642,7 @@ static int hub_set_address(struct usb_device *udev, int devnum) USB_REQ_SET_ADDRESS, 0, devnum, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); if (retval == 0) { - update_address(udev, devnum); + update_devnum(udev, devnum); /* Device now using proper address. */ usb_set_device_state(udev, USB_STATE_ADDRESS); usb_ep0_reinit(udev); @@ -2743,9 +2751,9 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, } if (udev->speed != USB_SPEED_SUPER) dev_info(&udev->dev, - "%s %s speed %sUSB device using %s and address %d\n", + "%s %s speed %sUSB device number %d using %s\n", (udev->config) ? "reset" : "new", speed, type, - udev->bus->controller->driver->name, devnum); + devnum, udev->bus->controller->driver->name); /* Set up TT records, if needed */ if (hdev->tt) { @@ -2775,10 +2783,6 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, * value. */ for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) { - /* - * An xHCI controller cannot send any packets to a device until - * a set address command successfully completes. - */ if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3)) { struct usb_device_descriptor *buf; int r = 0; @@ -2861,9 +2865,9 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, if (udev->speed == USB_SPEED_SUPER) { devnum = udev->devnum; dev_info(&udev->dev, - "%s SuperSpeed USB device using %s and address %d\n", + "%s SuperSpeed USB device number %d using %s\n", (udev->config) ? "reset" : "new", - udev->bus->controller->driver->name, devnum); + devnum, udev->bus->controller->driver->name); } /* cope with hardware quirkiness: @@ -2926,7 +2930,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, fail: if (retval) { hub_port_disable(hub, port1, 0); - update_address(udev, devnum); /* for disconnect processing */ + update_devnum(udev, devnum); /* for disconnect processing */ } mutex_unlock(&usb_address0_mutex); return retval; @@ -3135,15 +3139,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, else udev->speed = USB_SPEED_UNKNOWN; - /* - * Set the address. - * Note xHCI needs to issue an address device command later - * in the hub_port_init sequence for SS/HS/FS/LS devices, - * and xHC will assign an address to the device. But use - * kernel assigned address here, to avoid any address conflict - * issue. - */ - choose_address(udev); + choose_devnum(udev); if (udev->devnum <= 0) { status = -ENOTCONN; /* Don't retry */ goto loop; @@ -3235,7 +3231,7 @@ loop_disable: hub_port_disable(hub, port1, 1); loop: usb_ep0_reinit(udev); - release_address(udev); + release_devnum(udev); hub_free_dev(udev); usb_put_dev(udev); if ((status == -ENOTCONN) || (status == -ENOTSUPP)) -- cgit v1.2.3 From 2edb11cbac95231f66f1239b3ca26bdc0967183a Mon Sep 17 00:00:00 2001 From: Maulik Mankad Date: Tue, 22 Feb 2011 19:08:42 +0530 Subject: usb: gadget: composite: fix req->length in composite_setup() When USB CV MSC tests are run on f_mass_storage gadget Bulk Only Mass Storage Reset fails since req->length is set to USB_BUFSIZ=1024 in composite_setup(). Initialize req->length to zero to fix this. Signed-off-by: Maulik Mankad Cc: Alan Stern Cc: Michal Nazarewicz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/composite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 53e0496c71b5..c2251c40a205 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -813,7 +813,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) */ req->zero = 0; req->complete = composite_setup_complete; - req->length = USB_BUFSIZ; + req->length = 0; gadget->ep0->driver_data = cdev; switch (ctrl->bRequest) { -- cgit v1.2.3 From 22ced6874fc47bb051e7460443e454ca8efc457e Mon Sep 17 00:00:00 2001 From: Anoop Date: Thu, 24 Feb 2011 19:26:28 +0530 Subject: USB: EHCI bus glue for on-chip PMC MSP USB controller This patch add bus glue for USB controller commonly found in PMC-Sierra MSP71xx family of SoC's. Signed-off-by: Anoop P A Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 15 +- drivers/usb/host/ehci-hcd.c | 5 + drivers/usb/host/ehci-pmcmsp.c | 383 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 401 insertions(+), 2 deletions(-) create mode 100644 drivers/usb/host/ehci-pmcmsp.c (limited to 'drivers') diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 0e6afa260ed8..923e5a079b59 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -91,17 +91,28 @@ config USB_EHCI_TT_NEWSCHED If unsure, say Y. +config USB_EHCI_HCD_PMC_MSP + tristate "EHCI support for on-chip PMC MSP71xx USB controller" + depends on USB_EHCI_HCD && MSP_HAS_USB + default n + select USB_EHCI_BIG_ENDIAN_DESC + select USB_EHCI_BIG_ENDIAN_MMIO + ---help--- + Enables support for the onchip USB controller on the PMC_MSP7100 Family SoC's. + If unsure, say N. + config USB_EHCI_BIG_ENDIAN_MMIO bool depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || \ ARCH_IXP4XX || XPS_USB_HCD_XILINX || \ - PPC_MPC512x || CPU_CAVIUM_OCTEON) + PPC_MPC512x || CPU_CAVIUM_OCTEON || \ + PMC_MSP) default y config USB_EHCI_BIG_ENDIAN_DESC bool depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX || \ - PPC_MPC512x) + PPC_MPC512x || PMC_MSP) default y config XPS_USB_HCD_XILINX diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 4c77a818fd80..f69305d3a9b8 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1259,6 +1259,11 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_msm_driver #endif +#ifdef CONFIG_USB_EHCI_HCD_PMC_MSP +#include "ehci-pmcmsp.c" +#define PLATFORM_DRIVER ehci_hcd_msp_driver +#endif + #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ !defined(XILINX_OF_PLATFORM_DRIVER) diff --git a/drivers/usb/host/ehci-pmcmsp.c b/drivers/usb/host/ehci-pmcmsp.c new file mode 100644 index 000000000000..a2168642175b --- /dev/null +++ b/drivers/usb/host/ehci-pmcmsp.c @@ -0,0 +1,383 @@ +/* + * PMC MSP EHCI (Host Controller Driver) for USB. + * + * (C) Copyright 2006-2010 PMC-Sierra Inc + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ + +/* includes */ +#include +#include +#include +#include + +/* stream disable*/ +#define USB_CTRL_MODE_STREAM_DISABLE 0x10 + +/* threshold */ +#define USB_CTRL_FIFO_THRESH 0x00300000 + +/* register offset for usb_mode */ +#define USB_EHCI_REG_USB_MODE 0x68 + +/* register offset for usb fifo */ +#define USB_EHCI_REG_USB_FIFO 0x24 + +/* register offset for usb status */ +#define USB_EHCI_REG_USB_STATUS 0x44 + +/* serial/parallel transceiver */ +#define USB_EHCI_REG_BIT_STAT_STS (1<<29) + +/* TWI USB0 host device pin */ +#define MSP_PIN_USB0_HOST_DEV 49 + +/* TWI USB1 host device pin */ +#define MSP_PIN_USB1_HOST_DEV 50 + + +static void usb_hcd_tdi_set_mode(struct ehci_hcd *ehci) +{ + u8 *base; + u8 *statreg; + u8 *fiforeg; + u32 val; + struct ehci_regs *reg_base = ehci->regs; + + /* get register base */ + base = (u8 *)reg_base + USB_EHCI_REG_USB_MODE; + statreg = (u8 *)reg_base + USB_EHCI_REG_USB_STATUS; + fiforeg = (u8 *)reg_base + USB_EHCI_REG_USB_FIFO; + + /* Disable controller mode stream */ + val = ehci_readl(ehci, (u32 *)base); + ehci_writel(ehci, (val | USB_CTRL_MODE_STREAM_DISABLE), + (u32 *)base); + + /* clear STS to select parallel transceiver interface */ + val = ehci_readl(ehci, (u32 *)statreg); + val = val & ~USB_EHCI_REG_BIT_STAT_STS; + ehci_writel(ehci, val, (u32 *)statreg); + + /* write to set the proper fifo threshold */ + ehci_writel(ehci, USB_CTRL_FIFO_THRESH, (u32 *)fiforeg); + + /* set TWI GPIO USB_HOST_DEV pin high */ + gpio_direction_output(MSP_PIN_USB0_HOST_DEV, 1); +#ifdef CONFIG_MSP_HAS_DUAL_USB + gpio_direction_output(MSP_PIN_USB1_HOST_DEV, 1); +#endif +} + +/* called during probe() after chip reset completes */ +static int ehci_msp_setup(struct usb_hcd *hcd) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + int retval; + ehci->big_endian_mmio = 1; + ehci->big_endian_desc = 1; + + ehci->caps = hcd->regs; + ehci->regs = hcd->regs + + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + dbg_hcs_params(ehci, "reset"); + dbg_hcc_params(ehci, "reset"); + + /* cache this readonly data; minimize chip reads */ + ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); + hcd->has_tt = 1; + + retval = ehci_halt(ehci); + if (retval) + return retval; + + ehci_reset(ehci); + + /* data structure init */ + retval = ehci_init(hcd); + if (retval) + return retval; + + usb_hcd_tdi_set_mode(ehci); + ehci_port_power(ehci, 0); + + return retval; +} + + +/* configure so an HC device and id are always provided + * always called with process context; sleeping is OK + */ + +static int usb_hcd_msp_map_regs(struct mspusb_device *dev) +{ + struct resource *res; + struct platform_device *pdev = &dev->dev; + u32 res_len; + int retval; + + /* MAB register space */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (res == NULL) + return -ENOMEM; + res_len = res->end - res->start + 1; + if (!request_mem_region(res->start, res_len, "mab regs")) + return -EBUSY; + + dev->mab_regs = ioremap_nocache(res->start, res_len); + if (dev->mab_regs == NULL) { + retval = -ENOMEM; + goto err1; + } + + /* MSP USB register space */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 2); + if (res == NULL) { + retval = -ENOMEM; + goto err2; + } + res_len = res->end - res->start + 1; + if (!request_mem_region(res->start, res_len, "usbid regs")) { + retval = -EBUSY; + goto err2; + } + dev->usbid_regs = ioremap_nocache(res->start, res_len); + if (dev->usbid_regs == NULL) { + retval = -ENOMEM; + goto err3; + } + + return 0; +err3: + res = platform_get_resource(pdev, IORESOURCE_MEM, 2); + res_len = res->end - res->start + 1; + release_mem_region(res->start, res_len); +err2: + iounmap(dev->mab_regs); +err1: + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + res_len = res->end - res->start + 1; + release_mem_region(res->start, res_len); + dev_err(&pdev->dev, "Failed to map non-EHCI regs.\n"); + return retval; +} + +/** + * usb_hcd_msp_probe - initialize PMC MSP-based HCDs + * Context: !in_interrupt() + * + * Allocates basic resources for this USB host controller, and + * then invokes the start() method for the HCD associated with it + * through the hotplug entry's driver_data. + * + */ +int usb_hcd_msp_probe(const struct hc_driver *driver, + struct platform_device *dev) +{ + int retval; + struct usb_hcd *hcd; + struct resource *res; + struct ehci_hcd *ehci ; + + hcd = usb_create_hcd(driver, &dev->dev, "pmcmsp"); + if (!hcd) + return -ENOMEM; + + res = platform_get_resource(dev, IORESOURCE_MEM, 0); + if (res == NULL) { + pr_debug("No IOMEM resource info for %s.\n", dev->name); + retval = -ENOMEM; + goto err1; + } + hcd->rsrc_start = res->start; + hcd->rsrc_len = res->end - res->start + 1; + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, dev->name)) { + retval = -EBUSY; + goto err1; + } + hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); + if (!hcd->regs) { + pr_debug("ioremap failed"); + retval = -ENOMEM; + goto err2; + } + + res = platform_get_resource(dev, IORESOURCE_IRQ, 0); + if (res == NULL) { + dev_err(&dev->dev, "No IRQ resource info for %s.\n", dev->name); + retval = -ENOMEM; + goto err3; + } + + /* Map non-EHCI register spaces */ + retval = usb_hcd_msp_map_regs(to_mspusb_device(dev)); + if (retval != 0) + goto err3; + + ehci = hcd_to_ehci(hcd); + ehci->big_endian_mmio = 1; + ehci->big_endian_desc = 1; + + + retval = usb_add_hcd(hcd, res->start, IRQF_SHARED); + if (retval == 0) + return 0; + + usb_remove_hcd(hcd); +err3: + iounmap(hcd->regs); +err2: + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +err1: + usb_put_hcd(hcd); + + return retval; +} + + + +/** + * usb_hcd_msp_remove - shutdown processing for PMC MSP-based HCDs + * @dev: USB Host Controller being removed + * Context: !in_interrupt() + * + * Reverses the effect of usb_hcd_msp_probe(), first invoking + * the HCD's stop() method. It is always called from a thread + * context, normally "rmmod", "apmd", or something similar. + * + * may be called without controller electrically present + * may be called with controller, bus, and devices active + */ +void usb_hcd_msp_remove(struct usb_hcd *hcd, struct platform_device *dev) +{ + usb_remove_hcd(hcd); + iounmap(hcd->regs); + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); + usb_put_hcd(hcd); +} + +#ifdef CONFIG_MSP_HAS_DUAL_USB +/* + * Wrapper around the main ehci_irq. Since both USB host controllers are + * sharing the same IRQ, need to first determine whether we're the intended + * recipient of this interrupt. + */ +static irqreturn_t ehci_msp_irq(struct usb_hcd *hcd) +{ + u32 int_src; + struct device *dev = hcd->self.controller; + struct platform_device *pdev; + struct mspusb_device *mdev; + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + /* need to reverse-map a couple of containers to get our device */ + pdev = to_platform_device(dev); + mdev = to_mspusb_device(pdev); + + /* Check to see if this interrupt is for this host controller */ + int_src = ehci_readl(ehci, &mdev->mab_regs->int_stat); + if (int_src & (1 << pdev->id)) + return ehci_irq(hcd); + + /* Not for this device */ + return IRQ_NONE; +} +#endif /* DUAL_USB */ + +static const struct hc_driver ehci_msp_hc_driver = { + .description = hcd_name, + .product_desc = "PMC MSP EHCI", + .hcd_priv_size = sizeof(struct ehci_hcd), + + /* + * generic hardware linkage + */ +#ifdef CONFIG_MSP_HAS_DUAL_USB + .irq = ehci_msp_irq, +#else + .irq = ehci_irq, +#endif + .flags = HCD_MEMORY | HCD_USB2, + + /* + * basic lifecycle operations + */ + .reset = ehci_msp_setup, + .start = ehci_run, + .shutdown = ehci_shutdown, + .start = ehci_run, + .stop = ehci_stop, + + /* + * managing i/o requests and associated device resources + */ + .urb_enqueue = ehci_urb_enqueue, + .urb_dequeue = ehci_urb_dequeue, + .endpoint_disable = ehci_endpoint_disable, + .endpoint_reset = ehci_endpoint_reset, + + /* + * scheduling support + */ + .get_frame_number = ehci_get_frame, + + /* + * root hub support + */ + .hub_status_data = ehci_hub_status_data, + .hub_control = ehci_hub_control, + .bus_suspend = ehci_bus_suspend, + .bus_resume = ehci_bus_resume, + .relinquish_port = ehci_relinquish_port, + .port_handed_over = ehci_port_handed_over, + + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, +}; + +static int ehci_hcd_msp_drv_probe(struct platform_device *pdev) +{ + int ret; + + pr_debug("In ehci_hcd_msp_drv_probe"); + + if (usb_disabled()) + return -ENODEV; + + gpio_request(MSP_PIN_USB0_HOST_DEV, "USB0_HOST_DEV_GPIO"); +#ifdef CONFIG_MSP_HAS_DUAL_USB + gpio_request(MSP_PIN_USB1_HOST_DEV, "USB1_HOST_DEV_GPIO"); +#endif + + ret = usb_hcd_msp_probe(&ehci_msp_hc_driver, pdev); + + return ret; +} + +static int ehci_hcd_msp_drv_remove(struct platform_device *pdev) +{ + struct usb_hcd *hcd = platform_get_drvdata(pdev); + + usb_hcd_msp_remove(hcd, pdev); + + /* free TWI GPIO USB_HOST_DEV pin */ + gpio_free(MSP_PIN_USB0_HOST_DEV); +#ifdef CONFIG_MSP_HAS_DUAL_USB + gpio_free(MSP_PIN_USB1_HOST_DEV); +#endif + + return 0; +} + +MODULE_ALIAS("pmcmsp-ehci"); + +static struct platform_driver ehci_hcd_msp_driver = { + .probe = ehci_hcd_msp_drv_probe, + .remove = ehci_hcd_msp_drv_remove, + .driver = { + .name = "pmcmsp-ehci", + .owner = THIS_MODULE, + }, +}; -- cgit v1.2.3 From 969e3033ae7733a0af8f7742ca74cd16c0857e71 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 23 Feb 2011 15:28:18 -0500 Subject: USB: serial drivers need to use larger bulk-in buffers When a driver doesn't know how much data a device is going to send, the buffer size should be at least as big as the endpoint's maxpacket value. The serial drivers don't follow this rule; many of them request only 256-byte bulk-in buffers. As a result, they suffer overflow errors if a high-speed device wants to send a lot of data, because high-speed bulk endpoints are required to have a maxpacket size of 512. This patch (as1450) fixes the problem by using the driver's bulk_in_size value as a minimum, always allocating buffers no smaller than the endpoint's maxpacket size. Signed-off-by: Alan Stern Tested-by: Flynn Marquardt CC: [after .39-rc1 is out] Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 5 ++--- include/linux/usb/serial.h | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 546a52179bec..2ff90a9c8f47 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -911,9 +911,8 @@ int usb_serial_probe(struct usb_interface *interface, dev_err(&interface->dev, "No free urbs available\n"); goto probe_error; } - buffer_size = serial->type->bulk_in_size; - if (!buffer_size) - buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); + buffer_size = max_t(int, serial->type->bulk_in_size, + le16_to_cpu(endpoint->wMaxPacketSize)); port->bulk_in_size = buffer_size; port->bulk_in_endpointAddress = endpoint->bEndpointAddress; port->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index c9049139a7a5..45f3b9db4258 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -191,7 +191,8 @@ static inline void usb_set_serial_data(struct usb_serial *serial, void *data) * @id_table: pointer to a list of usb_device_id structures that define all * of the devices this structure can support. * @num_ports: the number of different ports this device will have. - * @bulk_in_size: bytes to allocate for bulk-in buffer (0 = end-point size) + * @bulk_in_size: minimum number of bytes to allocate for bulk-in buffer + * (0 = end-point size) * @bulk_out_size: bytes to allocate for bulk-out buffer (0 = end-point size) * @calc_num_ports: pointer to a function to determine how many ports this * device has dynamically. It will be called after the probe() -- cgit v1.2.3 From 309a057932ab20057da9fe4cb18fb61803dfc924 Mon Sep 17 00:00:00 2001 From: Martin Jansen Date: Thu, 24 Feb 2011 14:50:16 +0100 Subject: USB: opticon: add rts and cts support Add support for RTS and CTS line status Signed-off-by: Martin Jansen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/opticon.c | 156 +++++++++++++++++++++++++++++++------------ 1 file changed, 112 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index eda1f9266c4e..ce82396fc4e8 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -1,6 +1,7 @@ /* * Opticon USB barcode to serial driver * + * Copyright (C) 2011 Martin Jansen * Copyright (C) 2008 - 2009 Greg Kroah-Hartman * Copyright (C) 2008 - 2009 Novell Inc. * @@ -21,6 +22,16 @@ #include #include +#define CONTROL_RTS 0x02 +#define RESEND_CTS_STATE 0x03 + +/* max number of write urbs in flight */ +#define URB_UPPER_LIMIT 8 + +/* This driver works for the Opticon 1D barcode reader + * an examples of 1D barcode types are EAN, UPC, Code39, IATA etc.. */ +#define DRIVER_DESC "Opticon USB barcode to serial driver (1D)" + static int debug; static const struct usb_device_id id_table[] = { @@ -42,13 +53,13 @@ struct opticon_private { bool throttled; bool actually_throttled; bool rts; + bool cts; int outstanding_urbs; }; -/* max number of write urbs in flight */ -#define URB_UPPER_LIMIT 4 -static void opticon_bulk_callback(struct urb *urb) + +static void opticon_read_bulk_callback(struct urb *urb) { struct opticon_private *priv = urb->context; unsigned char *data = urb->transfer_buffer; @@ -57,6 +68,7 @@ static void opticon_bulk_callback(struct urb *urb) struct tty_struct *tty; int result; int data_length; + unsigned long flags; dbg("%s - port %d", __func__, port->number); @@ -87,10 +99,10 @@ static void opticon_bulk_callback(struct urb *urb) * Data from the device comes with a 2 byte header: * * <0x00><0x00>data... - * This is real data to be sent to the tty layer + * This is real data to be sent to the tty layer * <0x00><0x01)level - * This is a RTS level change, the third byte is the RTS - * value (0 for low, 1 for high). + * This is a CTS level change, the third byte is the CTS + * value (0 for low, 1 for high). */ if ((data[0] == 0x00) && (data[1] == 0x00)) { /* real data, send it to the tty layer */ @@ -103,10 +115,13 @@ static void opticon_bulk_callback(struct urb *urb) } } else { if ((data[0] == 0x00) && (data[1] == 0x01)) { + spin_lock_irqsave(&priv->lock, flags); + /* CTS status infomation package */ if (data[2] == 0x00) - priv->rts = false; + priv->cts = false; else - priv->rts = true; + priv->cts = true; + spin_unlock_irqrestore(&priv->lock, flags); } else { dev_dbg(&priv->udev->dev, "Unknown data packet received from the device:" @@ -129,7 +144,7 @@ exit: usb_rcvbulkpipe(priv->udev, priv->bulk_address), priv->bulk_in_buffer, priv->buffer_size, - opticon_bulk_callback, priv); + opticon_read_bulk_callback, priv); result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC); if (result) dev_err(&port->dev, @@ -140,6 +155,24 @@ exit: spin_unlock(&priv->lock); } +static int send_control_msg(struct usb_serial_port *port, u8 requesttype, + u8 val) +{ + struct usb_serial *serial = port->serial; + int retval; + u8 buffer[2]; + + buffer[0] = val; + /* Send the message to the vendor control endpoint + * of the connected device */ + retval = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), + requesttype, + USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, + 0, 0, buffer, 1, 0); + + return retval; +} + static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port) { struct opticon_private *priv = usb_get_serial_data(port->serial); @@ -152,19 +185,30 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port) priv->throttled = false; priv->actually_throttled = false; priv->port = port; + priv->rts = false; spin_unlock_irqrestore(&priv->lock, flags); - /* Start reading from the device */ + /* Clear RTS line */ + send_control_msg(port, CONTROL_RTS, 0); + + /* Setup the read URB and start reading from the device */ usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev, usb_rcvbulkpipe(priv->udev, priv->bulk_address), priv->bulk_in_buffer, priv->buffer_size, - opticon_bulk_callback, priv); + opticon_read_bulk_callback, priv); + + /* clear the halt status of the enpoint */ + usb_clear_halt(priv->udev, priv->bulk_read_urb->pipe); + result = usb_submit_urb(priv->bulk_read_urb, GFP_KERNEL); if (result) dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result); + /* Request CTS line state, sometimes during opening the current + * CTS state can be missed. */ + send_control_msg(port, RESEND_CTS_STATE, 1); return result; } @@ -178,7 +222,7 @@ static void opticon_close(struct usb_serial_port *port) usb_kill_urb(priv->bulk_read_urb); } -static void opticon_write_bulk_callback(struct urb *urb) +static void opticon_write_control_callback(struct urb *urb) { struct opticon_private *priv = urb->context; int status = urb->status; @@ -210,6 +254,7 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, unsigned char *buffer; unsigned long flags; int status; + struct usb_ctrlrequest *dr; dbg("%s - port %d", __func__, port->number); @@ -226,6 +271,7 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, if (!buffer) { dev_err(&port->dev, "out of memory\n"); count = -ENOMEM; + goto error_no_buffer; } @@ -240,35 +286,28 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); - if (port->bulk_out_endpointAddress) { - usb_fill_bulk_urb(urb, serial->dev, - usb_sndbulkpipe(serial->dev, - port->bulk_out_endpointAddress), - buffer, count, opticon_write_bulk_callback, priv); - } else { - struct usb_ctrlrequest *dr; - - dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO); - if (!dr) - return -ENOMEM; - - dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT; - dr->bRequest = 0x01; - dr->wValue = 0; - dr->wIndex = 0; - dr->wLength = cpu_to_le16(count); - - usb_fill_control_urb(urb, serial->dev, - usb_sndctrlpipe(serial->dev, 0), - (unsigned char *)dr, buffer, count, - opticon_write_bulk_callback, priv); - } + /* The conncected devices do not have a bulk write endpoint, + * to transmit data to de barcode device the control endpoint is used */ + dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO); + if (!dr) + return -ENOMEM; + + dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT; + dr->bRequest = 0x01; + dr->wValue = 0; + dr->wIndex = 0; + dr->wLength = cpu_to_le16(count); + + usb_fill_control_urb(urb, serial->dev, + usb_sndctrlpipe(serial->dev, 0), + (unsigned char *)dr, buffer, count, + opticon_write_control_callback, priv); /* send it down the pipe */ status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { dev_err(&port->dev, - "%s - usb_submit_urb(write bulk) failed with status = %d\n", + "%s - usb_submit_urb(write endpoint) failed status = %d\n", __func__, status); count = status; goto error; @@ -360,16 +399,49 @@ static int opticon_tiocmget(struct tty_struct *tty, struct file *file) int result = 0; dbg("%s - port %d", __func__, port->number); + if (!usb_get_intfdata(port->serial->interface)) + return -ENODEV; spin_lock_irqsave(&priv->lock, flags); if (priv->rts) - result = TIOCM_RTS; + result |= TIOCM_RTS; + if (priv->cts) + result |= TIOCM_CTS; spin_unlock_irqrestore(&priv->lock, flags); dbg("%s - %x", __func__, result); return result; } +static int opticon_tiocmset(struct tty_struct *tty, struct file *file, + unsigned int set, unsigned int clear) +{ + struct usb_serial_port *port = tty->driver_data; + struct opticon_private *priv = usb_get_serial_data(port->serial); + unsigned long flags; + bool rts; + bool changed = false; + + if (!usb_get_intfdata(port->serial->interface)) + return -ENODEV; + /* We only support RTS so we only handle that */ + spin_lock_irqsave(&priv->lock, flags); + + rts = priv->rts; + if (set & TIOCM_RTS) + priv->rts = true; + if (clear & TIOCM_RTS) + priv->rts = false; + changed = rts ^ priv->rts; + spin_unlock_irqrestore(&priv->lock, flags); + + if (!changed) + return 0; + + /* Send the new RTS state to the connected device */ + return send_control_msg(port, CONTROL_RTS, !rts); +} + static int get_serial_info(struct opticon_private *priv, struct serial_struct __user *serial) { @@ -431,6 +503,7 @@ static int opticon_startup(struct usb_serial *serial) priv->serial = serial; priv->port = serial->port[0]; priv->udev = serial->dev; + priv->outstanding_urbs = 0; /* Init the outstanding urbs */ /* find our bulk endpoint */ intf = serial->interface->altsetting; @@ -456,13 +529,6 @@ static int opticon_startup(struct usb_serial *serial) priv->bulk_address = endpoint->bEndpointAddress; - /* set up our bulk urb */ - usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev, - usb_rcvbulkpipe(priv->udev, - endpoint->bEndpointAddress), - priv->bulk_in_buffer, priv->buffer_size, - opticon_bulk_callback, priv); - bulk_in_found = true; break; } @@ -558,6 +624,7 @@ static struct usb_serial_driver opticon_device = { .unthrottle = opticon_unthrottle, .ioctl = opticon_ioctl, .tiocmget = opticon_tiocmget, + .tiocmset = opticon_tiocmset, }; static int __init opticon_init(void) @@ -581,6 +648,7 @@ static void __exit opticon_exit(void) module_init(opticon_init); module_exit(opticon_exit); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); module_param(debug, bool, S_IRUGO | S_IWUSR); -- cgit v1.2.3 From 7aed9dfedd39ab77fb661d0e6d331aeabe61aa85 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Thu, 24 Feb 2011 22:11:55 -0800 Subject: drivers:usb:wusbhc.h remove one to many l's in the word. The patch below removes an extra "l" in the word. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/usb/wusbcore/wusbhc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/wusbcore/wusbhc.h b/drivers/usb/wusbcore/wusbhc.h index 3d94c4247f46..6bd426b7ec07 100644 --- a/drivers/usb/wusbcore/wusbhc.h +++ b/drivers/usb/wusbcore/wusbhc.h @@ -132,7 +132,7 @@ static inline void wusb_dev_put(struct wusb_dev *wusb_dev) } /** - * Wireless USB Host Controlller root hub "fake" ports + * Wireless USB Host Controller root hub "fake" ports * (state and device information) * * Wireless USB is wireless, so there are no ports; but we -- cgit v1.2.3 From 601e72a067f0230cb815ae0c206081c3ea19c095 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Thu, 24 Feb 2011 22:13:09 -0800 Subject: drivers:uwb:scan.c remove one to many l's in the word. The patch below removes an extra "l" in the word. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/uwb/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/uwb/scan.c b/drivers/uwb/scan.c index 76a1a1ed7d3e..367aa12786b9 100644 --- a/drivers/uwb/scan.c +++ b/drivers/uwb/scan.c @@ -42,7 +42,7 @@ /** * Start/stop scanning in a radio controller * - * @rc: UWB Radio Controlller + * @rc: UWB Radio Controller * @channel: Channel to scan; encodings in WUSB1.0[Table 5.12] * @type: Type of scanning to do. * @bpst_offset: value at which to start scanning (if type == -- cgit v1.2.3 From 2c590f3ca99c193a04fe90ec89046138b66fcc1e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 24 Jan 2011 17:54:48 +0100 Subject: nozomi: don't use flush_scheduled_work() flush_scheduled_work() in tty_exit() doesn't seem to target any specific work. If it was to flush work items used in tty generic layer, they're already flushed properly during tty release. flush_scheduled_work() is going away. Remove the seemingly redundant usage. Signed-off-by: Tejun Heo Cc: Jiri Slaby Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/nozomi.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index 513ba12064ea..f4f11164efe5 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -1514,8 +1514,6 @@ static void __devexit tty_exit(struct nozomi *dc) DBG1(" "); - flush_scheduled_work(); - for (i = 0; i < MAX_PORT; ++i) { struct tty_struct *tty = tty_port_tty_get(&dc->port[i].port); if (tty && list_empty(&tty->hangup_work.entry)) -- cgit v1.2.3 From 948af1f0bbc8526448e8cbe3f8d3bf211bdf5181 Mon Sep 17 00:00:00 2001 From: Mike Waychison Date: Tue, 22 Feb 2011 17:53:21 -0800 Subject: firmware: Basic dmi-sysfs support Introduce a new module "dmi-sysfs" that exports the broken out entries of the DMI table through sysfs. Entries are enumerated via dmi_walk() on module load, and are populated as kobjects rooted at /sys/firmware/dmi/entries. Entries are named "-", where: : is the type of the entry, and : is the ordinal count within the DMI table of that entry type. This instance is used in lieu the DMI entry's handle as no assurances are made by the kernel that handles are unique. All entries export the following attributes: length : The length of the formatted portion of the entry handle : The handle given to this entry by the firmware raw : The raw bytes of the entire entry, including the formatted portion, the unformatted (strings) portion, and the two terminating nul characters. type : The DMI entry type instance : The ordinal instance of this entry given its type. position : The position ordinal of the entry within the table in its entirety. Entries in dmi-sysfs are kobject backed members called "struct dmi_sysfs_entry" and belong to dmi_kset. They are threaded through entry_list (protected by entry_list_lock) so that we can find them at cleanup time. Signed-off-by: Mike Waychison Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/Kconfig | 11 ++ drivers/firmware/Makefile | 1 + drivers/firmware/dmi-sysfs.c | 396 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 408 insertions(+) create mode 100644 drivers/firmware/dmi-sysfs.c (limited to 'drivers') diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index e710424b59ea..3c56afc5eb1b 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -113,6 +113,17 @@ config DMIID information from userspace through /sys/class/dmi/id/ or if you want DMI-based module auto-loading. +config DMI_SYSFS + tristate "DMI table support in sysfs" + depends on SYSFS && DMI + default n + help + Say Y or M here to enable the exporting of the raw DMI table + data via sysfs. This is useful for consuming the data without + requiring any access to /dev/mem at all. Tables are found + under /sys/firmware/dmi when this option is enabled and + loaded. + config ISCSI_IBFT_FIND bool "iSCSI Boot Firmware Table Attributes" depends on X86 diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index 1c3c17343dbe..20c17fca1232 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -2,6 +2,7 @@ # Makefile for the linux kernel. # obj-$(CONFIG_DMI) += dmi_scan.o +obj-$(CONFIG_DMI_SYSFS) += dmi-sysfs.o obj-$(CONFIG_EDD) += edd.o obj-$(CONFIG_EFI_VARS) += efivars.o obj-$(CONFIG_EFI_PCDP) += pcdp.o diff --git a/drivers/firmware/dmi-sysfs.c b/drivers/firmware/dmi-sysfs.c new file mode 100644 index 000000000000..2d8a04a95085 --- /dev/null +++ b/drivers/firmware/dmi-sysfs.c @@ -0,0 +1,396 @@ +/* + * dmi-sysfs.c + * + * This module exports the DMI tables read-only to userspace through the + * sysfs file system. + * + * Data is currently found below + * /sys/firmware/dmi/... + * + * DMI attributes are presented in attribute files with names + * formatted using %d-%d, so that the first integer indicates the + * structure type (0-255), and the second field is the instance of that + * entry. + * + * Copyright 2011 Google, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_ENTRY_TYPE 255 /* Most of these aren't used, but we consider + the top entry type is only 8 bits */ + +struct dmi_sysfs_entry { + struct dmi_header dh; + struct kobject kobj; + int instance; + int position; + struct list_head list; +}; + +/* + * Global list of dmi_sysfs_entry. Even though this should only be + * manipulated at setup and teardown, the lazy nature of the kobject + * system means we get lazy removes. + */ +static LIST_HEAD(entry_list); +static DEFINE_SPINLOCK(entry_list_lock); + +/* dmi_sysfs_attribute - Top level attribute. used by all entries. */ +struct dmi_sysfs_attribute { + struct attribute attr; + ssize_t (*show)(struct dmi_sysfs_entry *entry, char *buf); +}; + +#define DMI_SYSFS_ATTR(_entry, _name) \ +struct dmi_sysfs_attribute dmi_sysfs_attr_##_entry##_##_name = { \ + .attr = {.name = __stringify(_name), .mode = 0400}, \ + .show = dmi_sysfs_##_entry##_##_name, \ +} + +/* + * dmi_sysfs_mapped_attribute - Attribute where we require the entry be + * mapped in. Use in conjunction with dmi_sysfs_specialize_attr_ops. + */ +struct dmi_sysfs_mapped_attribute { + struct attribute attr; + ssize_t (*show)(struct dmi_sysfs_entry *entry, + const struct dmi_header *dh, + char *buf); +}; + +#define DMI_SYSFS_MAPPED_ATTR(_entry, _name) \ +struct dmi_sysfs_mapped_attribute dmi_sysfs_attr_##_entry##_##_name = { \ + .attr = {.name = __stringify(_name), .mode = 0400}, \ + .show = dmi_sysfs_##_entry##_##_name, \ +} + +/************************************************* + * Generic DMI entry support. + *************************************************/ + +static struct dmi_sysfs_entry *to_entry(struct kobject *kobj) +{ + return container_of(kobj, struct dmi_sysfs_entry, kobj); +} + +static struct dmi_sysfs_attribute *to_attr(struct attribute *attr) +{ + return container_of(attr, struct dmi_sysfs_attribute, attr); +} + +static ssize_t dmi_sysfs_attr_show(struct kobject *kobj, + struct attribute *_attr, char *buf) +{ + struct dmi_sysfs_entry *entry = to_entry(kobj); + struct dmi_sysfs_attribute *attr = to_attr(_attr); + + /* DMI stuff is only ever admin visible */ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + return attr->show(entry, buf); +} + +static const struct sysfs_ops dmi_sysfs_attr_ops = { + .show = dmi_sysfs_attr_show, +}; + +typedef ssize_t (*dmi_callback)(struct dmi_sysfs_entry *, + const struct dmi_header *dh, void *); + +struct find_dmi_data { + struct dmi_sysfs_entry *entry; + dmi_callback callback; + void *private; + int instance_countdown; + ssize_t ret; +}; + +static void find_dmi_entry_helper(const struct dmi_header *dh, + void *_data) +{ + struct find_dmi_data *data = _data; + struct dmi_sysfs_entry *entry = data->entry; + + /* Is this the entry we want? */ + if (dh->type != entry->dh.type) + return; + + if (data->instance_countdown != 0) { + /* try the next instance? */ + data->instance_countdown--; + return; + } + + /* + * Don't ever revisit the instance. Short circuit later + * instances by letting the instance_countdown run negative + */ + data->instance_countdown--; + + /* Found the entry */ + data->ret = data->callback(entry, dh, data->private); +} + +/* State for passing the read parameters through dmi_find_entry() */ +struct dmi_read_state { + char *buf; + loff_t pos; + size_t count; +}; + +static ssize_t find_dmi_entry(struct dmi_sysfs_entry *entry, + dmi_callback callback, void *private) +{ + struct find_dmi_data data = { + .entry = entry, + .callback = callback, + .private = private, + .instance_countdown = entry->instance, + .ret = -EIO, /* To signal the entry disappeared */ + }; + int ret; + + ret = dmi_walk(find_dmi_entry_helper, &data); + /* This shouldn't happen, but just in case. */ + if (ret) + return -EINVAL; + return data.ret; +} + +/* + * Calculate and return the byte length of the dmi entry identified by + * dh. This includes both the formatted portion as well as the + * unformatted string space, including the two trailing nul characters. + */ +static size_t dmi_entry_length(const struct dmi_header *dh) +{ + const char *p = (const char *)dh; + + p += dh->length; + + while (p[0] || p[1]) + p++; + + return 2 + p - (const char *)dh; +} + +/************************************************* + * Generic DMI entry support. + *************************************************/ + +static ssize_t dmi_sysfs_entry_length(struct dmi_sysfs_entry *entry, char *buf) +{ + return sprintf(buf, "%d\n", entry->dh.length); +} + +static ssize_t dmi_sysfs_entry_handle(struct dmi_sysfs_entry *entry, char *buf) +{ + return sprintf(buf, "%d\n", entry->dh.handle); +} + +static ssize_t dmi_sysfs_entry_type(struct dmi_sysfs_entry *entry, char *buf) +{ + return sprintf(buf, "%d\n", entry->dh.type); +} + +static ssize_t dmi_sysfs_entry_instance(struct dmi_sysfs_entry *entry, + char *buf) +{ + return sprintf(buf, "%d\n", entry->instance); +} + +static ssize_t dmi_sysfs_entry_position(struct dmi_sysfs_entry *entry, + char *buf) +{ + return sprintf(buf, "%d\n", entry->position); +} + +static DMI_SYSFS_ATTR(entry, length); +static DMI_SYSFS_ATTR(entry, handle); +static DMI_SYSFS_ATTR(entry, type); +static DMI_SYSFS_ATTR(entry, instance); +static DMI_SYSFS_ATTR(entry, position); + +static struct attribute *dmi_sysfs_entry_attrs[] = { + &dmi_sysfs_attr_entry_length.attr, + &dmi_sysfs_attr_entry_handle.attr, + &dmi_sysfs_attr_entry_type.attr, + &dmi_sysfs_attr_entry_instance.attr, + &dmi_sysfs_attr_entry_position.attr, + NULL, +}; + +static ssize_t dmi_entry_raw_read_helper(struct dmi_sysfs_entry *entry, + const struct dmi_header *dh, + void *_state) +{ + struct dmi_read_state *state = _state; + size_t entry_length; + + entry_length = dmi_entry_length(dh); + + return memory_read_from_buffer(state->buf, state->count, + &state->pos, dh, entry_length); +} + +static ssize_t dmi_entry_raw_read(struct file *filp, + struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t pos, size_t count) +{ + struct dmi_sysfs_entry *entry = to_entry(kobj); + struct dmi_read_state state = { + .buf = buf, + .pos = pos, + .count = count, + }; + + return find_dmi_entry(entry, dmi_entry_raw_read_helper, &state); +} + +static const struct bin_attribute dmi_entry_raw_attr = { + .attr = {.name = "raw", .mode = 0400}, + .read = dmi_entry_raw_read, +}; + +static void dmi_sysfs_entry_release(struct kobject *kobj) +{ + struct dmi_sysfs_entry *entry = to_entry(kobj); + sysfs_remove_bin_file(&entry->kobj, &dmi_entry_raw_attr); + spin_lock(&entry_list_lock); + list_del(&entry->list); + spin_unlock(&entry_list_lock); + kfree(entry); +} + +static struct kobj_type dmi_sysfs_entry_ktype = { + .release = dmi_sysfs_entry_release, + .sysfs_ops = &dmi_sysfs_attr_ops, + .default_attrs = dmi_sysfs_entry_attrs, +}; + +static struct kobject *dmi_kobj; +static struct kset *dmi_kset; + +/* Global count of all instances seen. Only for setup */ +static int __initdata instance_counts[MAX_ENTRY_TYPE + 1]; + +/* Global positional count of all entries seen. Only for setup */ +static int __initdata position_count; + +static void __init dmi_sysfs_register_handle(const struct dmi_header *dh, + void *_ret) +{ + struct dmi_sysfs_entry *entry; + int *ret = _ret; + + /* If a previous entry saw an error, short circuit */ + if (*ret) + return; + + /* Allocate and register a new entry into the entries set */ + entry = kzalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) { + *ret = -ENOMEM; + return; + } + + /* Set the key */ + entry->dh = *dh; + entry->instance = instance_counts[dh->type]++; + entry->position = position_count++; + + entry->kobj.kset = dmi_kset; + *ret = kobject_init_and_add(&entry->kobj, &dmi_sysfs_entry_ktype, NULL, + "%d-%d", dh->type, entry->instance); + + if (*ret) { + kfree(entry); + return; + } + + /* Thread on the global list for cleanup */ + spin_lock(&entry_list_lock); + list_add_tail(&entry->list, &entry_list); + spin_unlock(&entry_list_lock); + + /* Create the raw binary file to access the entry */ + *ret = sysfs_create_bin_file(&entry->kobj, &dmi_entry_raw_attr); + if (*ret) + goto out_err; + + return; +out_err: + kobject_put(&entry->kobj); + return; +} + +static void cleanup_entry_list(void) +{ + struct dmi_sysfs_entry *entry, *next; + + /* No locks, we are on our way out */ + list_for_each_entry_safe(entry, next, &entry_list, list) { + kobject_put(&entry->kobj); + } +} + +static int __init dmi_sysfs_init(void) +{ + int error = -ENOMEM; + int val; + + /* Set up our directory */ + dmi_kobj = kobject_create_and_add("dmi", firmware_kobj); + if (!dmi_kobj) + goto err; + + dmi_kset = kset_create_and_add("entries", NULL, dmi_kobj); + if (!dmi_kset) + goto err; + + val = 0; + error = dmi_walk(dmi_sysfs_register_handle, &val); + if (error) + goto err; + if (val) { + error = val; + goto err; + } + + pr_debug("dmi-sysfs: loaded.\n"); + + return 0; +err: + cleanup_entry_list(); + kset_unregister(dmi_kset); + kobject_put(dmi_kobj); + return error; +} + +/* clean up everything. */ +static void __exit dmi_sysfs_exit(void) +{ + pr_debug("dmi-sysfs: unloading.\n"); + cleanup_entry_list(); + kset_unregister(dmi_kset); + kobject_put(dmi_kobj); +} + +module_init(dmi_sysfs_init); +module_exit(dmi_sysfs_exit); + +MODULE_AUTHOR("Mike Waychison "); +MODULE_DESCRIPTION("DMI sysfs support"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 925a1da7477fc4ba5849c6f0243934fa5072493c Mon Sep 17 00:00:00 2001 From: Mike Waychison Date: Tue, 22 Feb 2011 17:53:26 -0800 Subject: firmware: Break out system_event_log in dmi-sysfs The optional type 15 entry of the DMI table describes a non-volatile storage-backed system event log. In preparation for the next commit which exposes the raw bits of the event log to userland, create a new sub-directory within the dmi entry called "system_event_log" and expose attribute files that describe the event log itself. Currently, only a single child object is permitted within a dmi_sysfs_entry. We simply point at this child from the dmi_sysfs_entry if it exists. Signed-off-by: Mike Waychison Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/dmi-sysfs.c | 159 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) (limited to 'drivers') diff --git a/drivers/firmware/dmi-sysfs.c b/drivers/firmware/dmi-sysfs.c index 2d8a04a95085..d20961011039 100644 --- a/drivers/firmware/dmi-sysfs.c +++ b/drivers/firmware/dmi-sysfs.c @@ -35,6 +35,7 @@ struct dmi_sysfs_entry { int instance; int position; struct list_head list; + struct kobject *child; }; /* @@ -77,6 +78,10 @@ struct dmi_sysfs_mapped_attribute dmi_sysfs_attr_##_entry##_##_name = { \ /************************************************* * Generic DMI entry support. *************************************************/ +static void dmi_entry_free(struct kobject *kobj) +{ + kfree(kobj); +} static struct dmi_sysfs_entry *to_entry(struct kobject *kobj) { @@ -185,6 +190,146 @@ static size_t dmi_entry_length(const struct dmi_header *dh) return 2 + p - (const char *)dh; } +/************************************************* + * Support bits for specialized DMI entry support + *************************************************/ +struct dmi_entry_attr_show_data { + struct attribute *attr; + char *buf; +}; + +static ssize_t dmi_entry_attr_show_helper(struct dmi_sysfs_entry *entry, + const struct dmi_header *dh, + void *_data) +{ + struct dmi_entry_attr_show_data *data = _data; + struct dmi_sysfs_mapped_attribute *attr; + + attr = container_of(data->attr, + struct dmi_sysfs_mapped_attribute, attr); + return attr->show(entry, dh, data->buf); +} + +static ssize_t dmi_entry_attr_show(struct kobject *kobj, + struct attribute *attr, + char *buf) +{ + struct dmi_entry_attr_show_data data = { + .attr = attr, + .buf = buf, + }; + /* Find the entry according to our parent and call the + * normalized show method hanging off of the attribute */ + return find_dmi_entry(to_entry(kobj->parent), + dmi_entry_attr_show_helper, &data); +} + +static const struct sysfs_ops dmi_sysfs_specialize_attr_ops = { + .show = dmi_entry_attr_show, +}; + +/************************************************* + * Specialized DMI entry support. + *************************************************/ + +/*** Type 15 - System Event Table ***/ + +#define DMI_SEL_ACCESS_METHOD_IO8 0x00 +#define DMI_SEL_ACCESS_METHOD_IO2x8 0x01 +#define DMI_SEL_ACCESS_METHOD_IO16 0x02 +#define DMI_SEL_ACCESS_METHOD_PHYS32 0x03 +#define DMI_SEL_ACCESS_METHOD_GPNV 0x04 + +struct dmi_system_event_log { + struct dmi_header header; + u16 area_length; + u16 header_start_offset; + u16 data_start_offset; + u8 access_method; + u8 status; + u32 change_token; + union { + struct { + u16 index_addr; + u16 data_addr; + } io; + u32 phys_addr32; + u16 gpnv_handle; + u32 access_method_address; + }; + u8 header_format; + u8 type_descriptors_supported_count; + u8 per_log_type_descriptor_length; + u8 supported_log_type_descriptos[0]; +} __packed; + +static const struct dmi_system_event_log *to_sel(const struct dmi_header *dh) +{ + return (const struct dmi_system_event_log *)dh; +} + +#define DMI_SYSFS_SEL_FIELD(_field) \ +static ssize_t dmi_sysfs_sel_##_field(struct dmi_sysfs_entry *entry, \ + const struct dmi_header *dh, \ + char *buf) \ +{ \ + const struct dmi_system_event_log *sel = to_sel(dh); \ + if (sizeof(*sel) > dmi_entry_length(dh)) \ + return -EIO; \ + return sprintf(buf, "%u\n", sel->_field); \ +} \ +static DMI_SYSFS_MAPPED_ATTR(sel, _field) + +DMI_SYSFS_SEL_FIELD(area_length); +DMI_SYSFS_SEL_FIELD(header_start_offset); +DMI_SYSFS_SEL_FIELD(data_start_offset); +DMI_SYSFS_SEL_FIELD(access_method); +DMI_SYSFS_SEL_FIELD(status); +DMI_SYSFS_SEL_FIELD(change_token); +DMI_SYSFS_SEL_FIELD(access_method_address); +DMI_SYSFS_SEL_FIELD(header_format); +DMI_SYSFS_SEL_FIELD(type_descriptors_supported_count); +DMI_SYSFS_SEL_FIELD(per_log_type_descriptor_length); + +static struct attribute *dmi_sysfs_sel_attrs[] = { + &dmi_sysfs_attr_sel_area_length.attr, + &dmi_sysfs_attr_sel_header_start_offset.attr, + &dmi_sysfs_attr_sel_data_start_offset.attr, + &dmi_sysfs_attr_sel_access_method.attr, + &dmi_sysfs_attr_sel_status.attr, + &dmi_sysfs_attr_sel_change_token.attr, + &dmi_sysfs_attr_sel_access_method_address.attr, + &dmi_sysfs_attr_sel_header_format.attr, + &dmi_sysfs_attr_sel_type_descriptors_supported_count.attr, + &dmi_sysfs_attr_sel_per_log_type_descriptor_length.attr, + NULL, +}; + + +static struct kobj_type dmi_system_event_log_ktype = { + .release = dmi_entry_free, + .sysfs_ops = &dmi_sysfs_specialize_attr_ops, + .default_attrs = dmi_sysfs_sel_attrs, +}; + +static int dmi_system_event_log(struct dmi_sysfs_entry *entry) +{ + int ret; + + entry->child = kzalloc(sizeof(*entry->child), GFP_KERNEL); + if (!entry->child) + return -ENOMEM; + ret = kobject_init_and_add(entry->child, + &dmi_system_event_log_ktype, + &entry->kobj, + "system_event_log"); + if (ret) + goto out_free; +out_free: + kfree(entry->child); + return ret; +} + /************************************************* * Generic DMI entry support. *************************************************/ @@ -325,6 +470,18 @@ static void __init dmi_sysfs_register_handle(const struct dmi_header *dh, list_add_tail(&entry->list, &entry_list); spin_unlock(&entry_list_lock); + /* Handle specializations by type */ + switch (dh->type) { + case DMI_ENTRY_SYSTEM_EVENT_LOG: + *ret = dmi_system_event_log(entry); + break; + default: + /* No specialization */ + break; + } + if (*ret) + goto out_err; + /* Create the raw binary file to access the entry */ *ret = sysfs_create_bin_file(&entry->kobj, &dmi_entry_raw_attr); if (*ret) @@ -332,6 +489,7 @@ static void __init dmi_sysfs_register_handle(const struct dmi_header *dh, return; out_err: + kobject_put(entry->child); kobject_put(&entry->kobj); return; } @@ -342,6 +500,7 @@ static void cleanup_entry_list(void) /* No locks, we are on our way out */ list_for_each_entry_safe(entry, next, &entry_list, list) { + kobject_put(entry->child); kobject_put(&entry->kobj); } } -- cgit v1.2.3 From a3857a5c9893aa69d44be6e881927b0950b1d931 Mon Sep 17 00:00:00 2001 From: Mike Waychison Date: Tue, 22 Feb 2011 17:53:31 -0800 Subject: firmware: Expose DMI type 15 System Event Log The System Event Log described by DMI entry type 15 may be backed by either memory or may be indirectly accessed via an IO index/data register pair. In order to get read access to this log, expose it in the "system_event_log" sub-directory of type 15 DMI entries, ie: /sys/firmware/dmi/entries/15-0/system_event_log/raw_event_log. This commit handles both IO accessed and memory access system event logs. OEM specific access and GPNV support is explicitly not handled and we error out in the logs when we do not recognize the access method. Signed-off-by: Mike Waychison Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/dmi-sysfs.c | 143 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) (limited to 'drivers') diff --git a/drivers/firmware/dmi-sysfs.c b/drivers/firmware/dmi-sysfs.c index d20961011039..a5afd805e66f 100644 --- a/drivers/firmware/dmi-sysfs.c +++ b/drivers/firmware/dmi-sysfs.c @@ -312,6 +312,140 @@ static struct kobj_type dmi_system_event_log_ktype = { .default_attrs = dmi_sysfs_sel_attrs, }; +typedef u8 (*sel_io_reader)(const struct dmi_system_event_log *sel, + loff_t offset); + +static DEFINE_MUTEX(io_port_lock); + +static u8 read_sel_8bit_indexed_io(const struct dmi_system_event_log *sel, + loff_t offset) +{ + u8 ret; + + mutex_lock(&io_port_lock); + outb((u8)offset, sel->io.index_addr); + ret = inb(sel->io.data_addr); + mutex_unlock(&io_port_lock); + return ret; +} + +static u8 read_sel_2x8bit_indexed_io(const struct dmi_system_event_log *sel, + loff_t offset) +{ + u8 ret; + + mutex_lock(&io_port_lock); + outb((u8)offset, sel->io.index_addr); + outb((u8)(offset >> 8), sel->io.index_addr + 1); + ret = inb(sel->io.data_addr); + mutex_unlock(&io_port_lock); + return ret; +} + +static u8 read_sel_16bit_indexed_io(const struct dmi_system_event_log *sel, + loff_t offset) +{ + u8 ret; + + mutex_lock(&io_port_lock); + outw((u16)offset, sel->io.index_addr); + ret = inb(sel->io.data_addr); + mutex_unlock(&io_port_lock); + return ret; +} + +static sel_io_reader sel_io_readers[] = { + [DMI_SEL_ACCESS_METHOD_IO8] = read_sel_8bit_indexed_io, + [DMI_SEL_ACCESS_METHOD_IO2x8] = read_sel_2x8bit_indexed_io, + [DMI_SEL_ACCESS_METHOD_IO16] = read_sel_16bit_indexed_io, +}; + +static ssize_t dmi_sel_raw_read_io(struct dmi_sysfs_entry *entry, + const struct dmi_system_event_log *sel, + char *buf, loff_t pos, size_t count) +{ + ssize_t wrote = 0; + + sel_io_reader io_reader = sel_io_readers[sel->access_method]; + + while (count && pos < sel->area_length) { + count--; + *(buf++) = io_reader(sel, pos++); + wrote++; + } + + return wrote; +} + +static ssize_t dmi_sel_raw_read_phys32(struct dmi_sysfs_entry *entry, + const struct dmi_system_event_log *sel, + char *buf, loff_t pos, size_t count) +{ + u8 __iomem *mapped; + ssize_t wrote = 0; + + mapped = ioremap(sel->access_method_address, sel->area_length); + if (!mapped) + return -EIO; + + while (count && pos < sel->area_length) { + count--; + *(buf++) = readb(mapped + pos++); + wrote++; + } + + iounmap(mapped); + return wrote; +} + +static ssize_t dmi_sel_raw_read_helper(struct dmi_sysfs_entry *entry, + const struct dmi_header *dh, + void *_state) +{ + struct dmi_read_state *state = _state; + const struct dmi_system_event_log *sel = to_sel(dh); + + if (sizeof(*sel) > dmi_entry_length(dh)) + return -EIO; + + switch (sel->access_method) { + case DMI_SEL_ACCESS_METHOD_IO8: + case DMI_SEL_ACCESS_METHOD_IO2x8: + case DMI_SEL_ACCESS_METHOD_IO16: + return dmi_sel_raw_read_io(entry, sel, state->buf, + state->pos, state->count); + case DMI_SEL_ACCESS_METHOD_PHYS32: + return dmi_sel_raw_read_phys32(entry, sel, state->buf, + state->pos, state->count); + case DMI_SEL_ACCESS_METHOD_GPNV: + pr_info("dmi-sysfs: GPNV support missing.\n"); + return -EIO; + default: + pr_info("dmi-sysfs: Unknown access method %02x\n", + sel->access_method); + return -EIO; + } +} + +static ssize_t dmi_sel_raw_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t pos, size_t count) +{ + struct dmi_sysfs_entry *entry = to_entry(kobj->parent); + struct dmi_read_state state = { + .buf = buf, + .pos = pos, + .count = count, + }; + + return find_dmi_entry(entry, dmi_sel_raw_read_helper, &state); +} + +static struct bin_attribute dmi_sel_raw_attr = { + .attr = {.name = "raw_event_log", .mode = 0400}, + .read = dmi_sel_raw_read, +}; + static int dmi_system_event_log(struct dmi_sysfs_entry *entry) { int ret; @@ -325,6 +459,15 @@ static int dmi_system_event_log(struct dmi_sysfs_entry *entry) "system_event_log"); if (ret) goto out_free; + + ret = sysfs_create_bin_file(entry->child, &dmi_sel_raw_attr); + if (ret) + goto out_del; + + return 0; + +out_del: + kobject_del(entry->child); out_free: kfree(entry->child); return ret; -- cgit v1.2.3 From 385918cc6af74e2b7ae10ec3ccaeea9a83e8e43e Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 21 Feb 2011 15:02:41 +0100 Subject: ath9k: correct ath9k_hw_set_interrupts Commit 4df3071ebd92ef7115b409da64d0eb405d24a631 "ath9k_hw: optimize interrupt mask changes", changed ath9k_hw_set_interrupts function to enable interrupts regardless of function argument, what could possibly be wrong. Correct that behaviour and check "ints" arguments before enabling interrupts, also disable interrupts if ints do not have ATH9K_INT_GLOBAL flag set. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/mac.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 180170d3ce25..2915b11edefb 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -885,7 +885,7 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) struct ath_common *common = ath9k_hw_common(ah); if (!(ints & ATH9K_INT_GLOBAL)) - ath9k_hw_enable_interrupts(ah); + ath9k_hw_disable_interrupts(ah); ath_dbg(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); @@ -963,7 +963,8 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); } - ath9k_hw_enable_interrupts(ah); + if (ints & ATH9K_INT_GLOBAL) + ath9k_hw_enable_interrupts(ah); return; } -- cgit v1.2.3 From c86664e5a285af1afa06416e450e7c4af04daa7c Mon Sep 17 00:00:00 2001 From: Jan Puk Date: Tue, 22 Feb 2011 14:49:43 +0100 Subject: carl9170: add Airlive X.USB a/b/g/n USBID "AirLive X.USB now works perfectly under a Linux environment!" Cc: Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/usb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index 537732e5964f..f82c400be288 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -118,6 +118,8 @@ static struct usb_device_id carl9170_usb_ids[] = { { USB_DEVICE(0x057c, 0x8402) }, /* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */ { USB_DEVICE(0x1668, 0x1200) }, + /* Airlive X.USB a/b/g/n */ + { USB_DEVICE(0x1b75, 0x9170) }, /* terminate */ {} -- cgit v1.2.3 From 63453c05da685323d45b7063cc27cf5e44b4134c Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Thu, 24 Feb 2011 12:25:42 +0200 Subject: rndis_wlan: use power save only for BCM4320b BCM4320a breaks when enabling power save (bug 29732). So disable power save for anything but BCM4320b that is known to work. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 848cc2cce247..518542b4bf9e 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2597,6 +2597,9 @@ static int rndis_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, __le32 mode; int ret; + if (priv->device_type != RNDIS_BCM4320B) + return -ENOTSUPP; + netdev_dbg(usbdev->net, "%s(): %s, %d\n", __func__, enabled ? "enabled" : "disabled", timeout); -- cgit v1.2.3 From 3083e83c86e604ac7005c100b7d7242389407ba5 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Thu, 24 Feb 2011 14:12:20 +0100 Subject: p54: implement set_coverage_class The callback sets slot time as specified in IEEE 802.11-2007 section 17.3.8.6 and raises round trip delay accordingly. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/fwio.c | 9 ++++++++- drivers/net/wireless/p54/main.c | 12 ++++++++++++ drivers/net/wireless/p54/p54.h | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c index 0d3d108f6fe2..2fab7d20ffc2 100644 --- a/drivers/net/wireless/p54/fwio.c +++ b/drivers/net/wireless/p54/fwio.c @@ -559,6 +559,7 @@ int p54_set_edcf(struct p54_common *priv) { struct sk_buff *skb; struct p54_edcf *edcf; + u8 rtd; skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf), P54_CONTROL_TYPE_DCFINIT, GFP_ATOMIC); @@ -575,9 +576,15 @@ int p54_set_edcf(struct p54_common *priv) edcf->sifs = 0x0a; edcf->eofpad = 0x06; } + /* + * calculate the extra round trip delay according to the + * formula from 802.11-2007 17.3.8.6. + */ + rtd = 3 * priv->coverage_class; + edcf->slottime += rtd; + edcf->round_trip_delay = cpu_to_le16(rtd); /* (see prism54/isl_oid.h for further details) */ edcf->frameburst = cpu_to_le16(0); - edcf->round_trip_delay = cpu_to_le16(0); edcf->flags = 0; memset(edcf->mapping, 0, sizeof(edcf->mapping)); memcpy(edcf->queue, priv->qos_params, sizeof(edcf->queue)); diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index e14a05bbc485..d7a92af24dd5 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c @@ -566,6 +566,17 @@ static void p54_flush(struct ieee80211_hw *dev, bool drop) WARN(total, "tx flush timeout, unresponsive firmware"); } +static void p54_set_coverage_class(struct ieee80211_hw *dev, u8 coverage_class) +{ + struct p54_common *priv = dev->priv; + + mutex_lock(&priv->conf_mutex); + /* support all coverage class values as in 802.11-2007 Table 7-27 */ + priv->coverage_class = clamp_t(u8, coverage_class, 0, 31); + p54_set_edcf(priv); + mutex_unlock(&priv->conf_mutex); +} + static const struct ieee80211_ops p54_ops = { .tx = p54_tx_80211, .start = p54_start, @@ -584,6 +595,7 @@ static const struct ieee80211_ops p54_ops = { .conf_tx = p54_conf_tx, .get_stats = p54_get_stats, .get_survey = p54_get_survey, + .set_coverage_class = p54_set_coverage_class, }; struct ieee80211_hw *p54_init_common(size_t priv_data_len) diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h index f951c8f31863..50730fc23fe5 100644 --- a/drivers/net/wireless/p54/p54.h +++ b/drivers/net/wireless/p54/p54.h @@ -217,6 +217,7 @@ struct p54_common { u32 tsf_low32, tsf_high32; u32 basic_rate_mask; u16 aid; + u8 coverage_class; bool powersave_override; __le32 beacon_req_id; struct completion beacon_comp; -- cgit v1.2.3 From 43f12d47f0580e04e26c14c03cb19cea9687854e Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 24 Feb 2011 14:23:55 +0100 Subject: iwlegacy: do not set tx power when channel is changing Same fix as f844a709a7d8f8be61a571afc31dfaca9e779621 "iwlwifi: do not set tx power when channel is changing". Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-4965.c | 2 +- drivers/net/wireless/iwlegacy/iwl-core.c | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c index 080444c89022..f5433c74b845 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965.c @@ -1319,7 +1319,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c /* If we issue a new RXON command which required a tune then we must * send a new TXPOWER command or we won't be able to Tx any frames */ - ret = iwl_legacy_set_tx_power(priv, priv->tx_power_user_lmt, true); + ret = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true); if (ret) { IWL_ERR(priv, "Error sending TX power (%d)\n", ret); return ret; diff --git a/drivers/net/wireless/iwlegacy/iwl-core.c b/drivers/net/wireless/iwlegacy/iwl-core.c index c95c3bcb724d..7cc560bc4f95 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.c +++ b/drivers/net/wireless/iwlegacy/iwl-core.c @@ -1114,6 +1114,8 @@ int iwl_legacy_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) { int ret; s8 prev_tx_power; + bool defer; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; lockdep_assert_held(&priv->mutex); @@ -1141,10 +1143,15 @@ int iwl_legacy_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) if (!iwl_legacy_is_ready_rf(priv)) return -EIO; - /* scan complete use tx_power_next, need to be updated */ + /* scan complete and commit_rxon use tx_power_next value, + * it always need to be updated for newest request */ priv->tx_power_next = tx_power; - if (test_bit(STATUS_SCANNING, &priv->status) && !force) { - IWL_DEBUG_INFO(priv, "Deferring tx power set while scanning\n"); + + /* do not set tx power when scanning or channel changing */ + defer = test_bit(STATUS_SCANNING, &priv->status) || + memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)); + if (defer && !force) { + IWL_DEBUG_INFO(priv, "Deferring tx power set\n"); return 0; } -- cgit v1.2.3 From 7bb4568372856688bc070917265bce0b88bb7d4d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 24 Feb 2011 14:42:06 +0100 Subject: mac80211: make tx() operation return void The return value of the tx operation is commonly misused by drivers, leading to errors. All drivers will drop frames if they fail to TX the frame, and they must also properly manage the queues (if they didn't, mac80211 would already warn). Removing the ability for drivers to return a BUSY value also allows significant cleanups of the TX TX handling code in mac80211. Note that this also fixes a bug in ath9k_htc, the old "return -1" there was wrong. Signed-off-by: Johannes Berg Tested-by: Sedat Dilek [ath5k] Acked-by: Gertjan van Wingerde [rt2x00] Acked-by: Larry Finger [b43, rtl8187, rtlwifi] Acked-by: Luciano Coelho [wl12xx] Signed-off-by: John W. Linville --- drivers/net/wireless/adm8211.c | 4 +- drivers/net/wireless/at76c50x-usb.c | 7 +- drivers/net/wireless/ath/ar9170/ar9170.h | 2 +- drivers/net/wireless/ath/ar9170/main.c | 5 +- drivers/net/wireless/ath/ath5k/ath5k.h | 4 +- drivers/net/wireless/ath/ath5k/base.c | 5 +- drivers/net/wireless/ath/ath5k/mac80211-ops.c | 6 +- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 7 +- drivers/net/wireless/ath/ath9k/main.c | 6 +- drivers/net/wireless/ath/carl9170/carl9170.h | 2 +- drivers/net/wireless/ath/carl9170/tx.c | 5 +- drivers/net/wireless/b43/main.c | 6 +- drivers/net/wireless/b43legacy/main.c | 5 +- drivers/net/wireless/iwlegacy/iwl-4965.h | 2 +- drivers/net/wireless/iwlegacy/iwl3945-base.c | 3 +- drivers/net/wireless/iwlegacy/iwl4965-base.c | 3 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 +- drivers/net/wireless/iwlwifi/iwl-agn.h | 2 +- drivers/net/wireless/libertas_tf/main.c | 3 +- drivers/net/wireless/mac80211_hwsim.c | 5 +- drivers/net/wireless/mwl8k.c | 15 +-- drivers/net/wireless/p54/lmac.h | 2 +- drivers/net/wireless/p54/main.c | 2 +- drivers/net/wireless/p54/txrx.c | 11 +- drivers/net/wireless/rt2x00/rt2x00.h | 2 +- drivers/net/wireless/rt2x00/rt2x00mac.c | 5 +- drivers/net/wireless/rtl818x/rtl8180/dev.c | 8 +- drivers/net/wireless/rtl818x/rtl8187/dev.c | 6 +- drivers/net/wireless/rtlwifi/core.c | 5 +- drivers/net/wireless/wl1251/main.c | 4 +- drivers/net/wireless/wl12xx/main.c | 4 +- drivers/net/wireless/zd1211rw/zd_mac.c | 5 +- drivers/staging/brcm80211/sys/wl_mac80211.c | 28 +---- drivers/staging/winbond/wbusb.c | 7 +- include/net/mac80211.h | 2 +- net/mac80211/driver-ops.h | 4 +- net/mac80211/tx.c | 164 +++++++++----------------- 37 files changed, 122 insertions(+), 237 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index f9aa1bc0a947..afe2cbc6cb24 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c @@ -1658,7 +1658,7 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb, } /* Put adm8211_tx_hdr on skb and transmit */ -static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb) +static void adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb) { struct adm8211_tx_hdr *txhdr; size_t payload_len, hdrlen; @@ -1707,8 +1707,6 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb) txhdr->retry_limit = info->control.rates[0].count; adm8211_tx_raw(dev, skb, plcp_signal, hdrlen); - - return NETDEV_TX_OK; } static int adm8211_alloc_rings(struct ieee80211_hw *dev) diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 1476314afa8a..10b4393d7fe0 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c @@ -1728,7 +1728,7 @@ static void at76_mac80211_tx_callback(struct urb *urb) ieee80211_wake_queues(priv->hw); } -static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +static void at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct at76_priv *priv = hw->priv; struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer; @@ -1741,7 +1741,8 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) if (priv->tx_urb->status == -EINPROGRESS) { wiphy_err(priv->hw->wiphy, "%s called while tx urb is pending\n", __func__); - return NETDEV_TX_BUSY; + dev_kfree_skb_any(skb); + return; } /* The following code lines are important when the device is going to @@ -1795,8 +1796,6 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) priv->tx_urb, priv->tx_urb->hcpriv, priv->tx_urb->complete); } - - return 0; } static int at76_mac80211_start(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h index 4f845f80c098..371e4ce49528 100644 --- a/drivers/net/wireless/ath/ar9170/ar9170.h +++ b/drivers/net/wireless/ath/ar9170/ar9170.h @@ -224,7 +224,7 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len); int ar9170_nag_limiter(struct ar9170 *ar); /* MAC */ -int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); +void ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); int ar9170_init_mac(struct ar9170 *ar); int ar9170_set_qos(struct ar9170 *ar); int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hast); diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index a9111e1161fd..b761fec0d721 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c @@ -1475,7 +1475,7 @@ static void ar9170_tx(struct ar9170 *ar) msecs_to_jiffies(AR9170_JANITOR_DELAY)); } -int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +void ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct ar9170 *ar = hw->priv; struct ieee80211_tx_info *info; @@ -1493,11 +1493,10 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) skb_queue_tail(&ar->tx_pending[queue], skb); ar9170_tx(ar); - return NETDEV_TX_OK; + return; err_free: dev_kfree_skb_any(skb); - return NETDEV_TX_OK; } static int ar9170_op_add_interface(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 70abb61e9eff..0ee54eb333de 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1164,8 +1164,8 @@ struct ath5k_txq; void set_beacon_filter(struct ieee80211_hw *hw, bool enable); bool ath_any_vif_assoc(struct ath5k_softc *sc); -int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, - struct ath5k_txq *txq); +void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, + struct ath5k_txq *txq); int ath5k_init_hw(struct ath5k_softc *sc); int ath5k_stop_hw(struct ath5k_softc *sc); void ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif); diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 80d9cf0c4cd2..91411e9b4b68 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1518,7 +1518,7 @@ unlock: * TX Handling * \*************/ -int +void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, struct ath5k_txq *txq) { @@ -1567,11 +1567,10 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, spin_unlock_irqrestore(&sc->txbuflock, flags); goto drop_packet; } - return NETDEV_TX_OK; + return; drop_packet: dev_kfree_skb_any(skb); - return NETDEV_TX_OK; } static void diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index a60a726a140c..1fbe3c0b9f08 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -52,7 +52,7 @@ extern int ath5k_modparam_nohwcrypt; * Mac80211 functions * \********************/ -static int +static void ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct ath5k_softc *sc = hw->priv; @@ -60,10 +60,10 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) if (WARN_ON(qnum >= sc->ah->ah_capabilities.cap_queues.q_tx_num)) { dev_kfree_skb_any(skb); - return 0; + return; } - return ath5k_tx_queue(hw, skb, &sc->txqs[qnum]); + ath5k_tx_queue(hw, skb, &sc->txqs[qnum]); } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 7367d6c1c649..71adab34006c 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1036,7 +1036,7 @@ set_timer: /* mac80211 Callbacks */ /**********************/ -static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct ieee80211_hdr *hdr; struct ath9k_htc_priv *priv = hw->priv; @@ -1049,7 +1049,7 @@ static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) padsize = padpos & 3; if (padsize && skb->len > padpos) { if (skb_headroom(skb) < padsize) - return -1; + goto fail_tx; skb_push(skb, padsize); memmove(skb->data, skb->data + padsize, padpos); } @@ -1070,11 +1070,10 @@ static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) goto fail_tx; } - return 0; + return; fail_tx: dev_kfree_skb_any(skb); - return 0; } static int ath9k_htc_start(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a71550049d84..39a72ae80970 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1142,8 +1142,7 @@ mutex_unlock: return r; } -static int ath9k_tx(struct ieee80211_hw *hw, - struct sk_buff *skb) +static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct ath_softc *sc = hw->priv; struct ath_common *common = ath9k_hw_common(sc->sc_ah); @@ -1200,10 +1199,9 @@ static int ath9k_tx(struct ieee80211_hw *hw, goto exit; } - return 0; + return; exit: dev_kfree_skb_any(skb); - return 0; } static void ath9k_stop(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index 420d437f9580..c6a5fae634a0 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -534,7 +534,7 @@ void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len); void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len); /* TX */ -int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); +void carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); void carl9170_tx_janitor(struct work_struct *work); void carl9170_tx_process_status(struct ar9170 *ar, const struct carl9170_rsp *cmd); diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index 6f41e21d3a1c..0ef70b6fc512 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -1339,7 +1339,7 @@ err_unlock_rcu: return false; } -int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +void carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct ar9170 *ar = hw->priv; struct ieee80211_tx_info *info; @@ -1373,12 +1373,11 @@ int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) } carl9170_tx(ar); - return NETDEV_TX_OK; + return; err_free: ar->tx_dropped++; dev_kfree_skb_any(skb); - return NETDEV_TX_OK; } void carl9170_tx_scheduler(struct ar9170 *ar) diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 22bc9f17f634..57eb5b649730 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -3203,7 +3203,7 @@ static void b43_tx_work(struct work_struct *work) mutex_unlock(&wl->mutex); } -static int b43_op_tx(struct ieee80211_hw *hw, +static void b43_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct b43_wl *wl = hw_to_b43_wl(hw); @@ -3211,14 +3211,12 @@ static int b43_op_tx(struct ieee80211_hw *hw, if (unlikely(skb->len < 2 + 2 + 6)) { /* Too short, this can't be a valid frame. */ dev_kfree_skb_any(skb); - return NETDEV_TX_OK; + return; } B43_WARN_ON(skb_shinfo(skb)->nr_frags); skb_queue_tail(&wl->tx_queue, skb); ieee80211_queue_work(wl->hw, &wl->tx_work); - - return NETDEV_TX_OK; } static void b43_qos_params_upload(struct b43_wldev *dev, diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 1f11e1670bf0..c7fd73e3ad76 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -2442,8 +2442,8 @@ static int b43legacy_rng_init(struct b43legacy_wl *wl) return err; } -static int b43legacy_op_tx(struct ieee80211_hw *hw, - struct sk_buff *skb) +static void b43legacy_op_tx(struct ieee80211_hw *hw, + struct sk_buff *skb) { struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); struct b43legacy_wldev *dev = wl->current_dev; @@ -2466,7 +2466,6 @@ out: /* Drop the packet. */ dev_kfree_skb_any(skb); } - return NETDEV_TX_OK; } static int b43legacy_op_conf_tx(struct ieee80211_hw *hw, u16 queue, diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.h b/drivers/net/wireless/iwlegacy/iwl-4965.h index 79e206770f71..01f8163daf16 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965.h +++ b/drivers/net/wireless/iwlegacy/iwl-4965.h @@ -253,7 +253,7 @@ void iwl4965_eeprom_release_semaphore(struct iwl_priv *priv); int iwl4965_eeprom_check_version(struct iwl_priv *priv); /* mac80211 handlers (for 4965) */ -int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb); +void iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb); int iwl4965_mac_start(struct ieee80211_hw *hw); void iwl4965_mac_stop(struct ieee80211_hw *hw); void iwl4965_configure_filter(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/iwlegacy/iwl3945-base.c b/drivers/net/wireless/iwlegacy/iwl3945-base.c index ef94d161b783..a6af9817efce 100644 --- a/drivers/net/wireless/iwlegacy/iwl3945-base.c +++ b/drivers/net/wireless/iwlegacy/iwl3945-base.c @@ -3170,7 +3170,7 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw) IWL_DEBUG_MAC80211(priv, "leave\n"); } -static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +static void iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct iwl_priv *priv = hw->priv; @@ -3183,7 +3183,6 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) dev_kfree_skb_any(skb); IWL_DEBUG_MAC80211(priv, "leave\n"); - return NETDEV_TX_OK; } void iwl3945_config_ap(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlegacy/iwl4965-base.c b/drivers/net/wireless/iwlegacy/iwl4965-base.c index c0e07685059a..4d53d0ff5fc7 100644 --- a/drivers/net/wireless/iwlegacy/iwl4965-base.c +++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c @@ -2631,7 +2631,7 @@ void iwl4965_mac_stop(struct ieee80211_hw *hw) IWL_DEBUG_MAC80211(priv, "leave\n"); } -int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +void iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct iwl_priv *priv = hw->priv; @@ -2644,7 +2644,6 @@ int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) dev_kfree_skb_any(skb); IWL_DEBUG_MACDUMP(priv, "leave\n"); - return NETDEV_TX_OK; } void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d08fa938501a..8cdbd8c4027f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3330,7 +3330,7 @@ void iwlagn_mac_stop(struct ieee80211_hw *hw) IWL_DEBUG_MAC80211(priv, "leave\n"); } -int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct iwl_priv *priv = hw->priv; @@ -3343,7 +3343,6 @@ int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) dev_kfree_skb_any(skb); IWL_DEBUG_MACDUMP(priv, "leave\n"); - return NETDEV_TX_OK; } void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index d00e1ea50a8d..88c7210dfb91 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -356,7 +356,7 @@ iwlagn_remove_notification(struct iwl_priv *priv, struct iwl_notification_wait *wait_entry); /* mac80211 handlers (for 4965) */ -int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb); +void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb); int iwlagn_mac_start(struct ieee80211_hw *hw); void iwlagn_mac_stop(struct ieee80211_hw *hw); void iwlagn_configure_filter(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c index 9278b3c8ee30..d4005081f1df 100644 --- a/drivers/net/wireless/libertas_tf/main.c +++ b/drivers/net/wireless/libertas_tf/main.c @@ -225,7 +225,7 @@ static void lbtf_free_adapter(struct lbtf_private *priv) lbtf_deb_leave(LBTF_DEB_MAIN); } -static int lbtf_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +static void lbtf_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct lbtf_private *priv = hw->priv; @@ -236,7 +236,6 @@ static int lbtf_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * there are no buffered multicast frames to send */ ieee80211_stop_queues(priv->hw); - return NETDEV_TX_OK; } static void lbtf_tx_work(struct work_struct *work) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 5d39b2840584..56f439d58013 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -541,7 +541,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, } -static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { bool ack; struct ieee80211_tx_info *txi; @@ -551,7 +551,7 @@ static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) if (skb->len < 10) { /* Should not happen; just a sanity check for addr1 use */ dev_kfree_skb(skb); - return NETDEV_TX_OK; + return; } ack = mac80211_hwsim_tx_frame(hw, skb); @@ -571,7 +571,6 @@ static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK) && ack) txi->flags |= IEEE80211_TX_STAT_ACK; ieee80211_tx_status_irqsafe(hw, skb); - return NETDEV_TX_OK; } diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 03f2584aed12..df5959f36d0b 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -1573,7 +1573,7 @@ static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index) txq->txd = NULL; } -static int +static void mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) { struct mwl8k_priv *priv = hw->priv; @@ -1635,7 +1635,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) wiphy_debug(hw->wiphy, "failed to dma map skb, dropping TX frame.\n"); dev_kfree_skb(skb); - return NETDEV_TX_OK; + return; } spin_lock_bh(&priv->tx_lock); @@ -1672,8 +1672,6 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) mwl8k_tx_start(priv); spin_unlock_bh(&priv->tx_lock); - - return NETDEV_TX_OK; } @@ -3742,22 +3740,19 @@ static void mwl8k_rx_poll(unsigned long data) /* * Core driver operations. */ -static int mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +static void mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct mwl8k_priv *priv = hw->priv; int index = skb_get_queue_mapping(skb); - int rc; if (!priv->radio_on) { wiphy_debug(hw->wiphy, "dropped TX frame since radio disabled\n"); dev_kfree_skb(skb); - return NETDEV_TX_OK; + return; } - rc = mwl8k_txq_xmit(hw, index, skb); - - return rc; + mwl8k_txq_xmit(hw, index, skb); } static int mwl8k_start(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/p54/lmac.h b/drivers/net/wireless/p54/lmac.h index 5ca117e6f95b..eb581abc1079 100644 --- a/drivers/net/wireless/p54/lmac.h +++ b/drivers/net/wireless/p54/lmac.h @@ -526,7 +526,7 @@ int p54_init_leds(struct p54_common *priv); void p54_unregister_leds(struct p54_common *priv); /* xmit functions */ -int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb); +void p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb); int p54_tx_cancel(struct p54_common *priv, __le32 req_id); void p54_tx(struct p54_common *priv, struct sk_buff *skb); diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index d7a92af24dd5..356e6bb443a6 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c @@ -157,7 +157,7 @@ static int p54_beacon_update(struct p54_common *priv, * to cancel the old beacon template by hand, instead the firmware * will release the previous one through the feedback mechanism. */ - WARN_ON(p54_tx_80211(priv->hw, beacon)); + p54_tx_80211(priv->hw, beacon); priv->tsf_high32 = 0; priv->tsf_low32 = 0; diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index a408ff333920..7834c26c2954 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c @@ -696,7 +696,7 @@ static u8 p54_convert_algo(u32 cipher) } } -int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb) +void p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb) { struct p54_common *priv = dev->priv; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -717,12 +717,8 @@ int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb) &hdr_flags, &aid, &burst_allowed); if (p54_tx_qos_accounting_alloc(priv, skb, queue)) { - if (!IS_QOS_QUEUE(queue)) { - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } else { - return NETDEV_TX_BUSY; - } + dev_kfree_skb_any(skb); + return; } padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3; @@ -865,5 +861,4 @@ int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb) p54info->extra_len = extra_len; p54_tx(priv, skb); - return NETDEV_TX_OK; } diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 1df432c1f2c7..19453d23e90d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1185,7 +1185,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry); /* * mac80211 handlers. */ -int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb); +void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb); int rt2x00mac_start(struct ieee80211_hw *hw); void rt2x00mac_stop(struct ieee80211_hw *hw); int rt2x00mac_add_interface(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 1b3edef9e3d2..c2c35838c2f3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -99,7 +99,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, return retval; } -int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct rt2x00_dev *rt2x00dev = hw->priv; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); @@ -155,12 +155,11 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) if (rt2x00queue_threshold(queue)) rt2x00queue_pause_queue(queue); - return NETDEV_TX_OK; + return; exit_fail: ieee80211_stop_queue(rt2x00dev->hw, qid); dev_kfree_skb_any(skb); - return NETDEV_TX_OK; } EXPORT_SYMBOL_GPL(rt2x00mac_tx); diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c index b85debb4f7b1..80db5cabc9b9 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c @@ -240,7 +240,7 @@ static irqreturn_t rtl8180_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) +static void rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; @@ -321,8 +321,6 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) spin_unlock_irqrestore(&priv->lock, flags); rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4))); - - return 0; } void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam) @@ -687,7 +685,6 @@ static void rtl8180_beacon_work(struct work_struct *work) 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)) @@ -708,8 +705,7 @@ static void rtl8180_beacon_work(struct work_struct *work) /* TODO: use actual beacon queue */ skb_set_queue_mapping(skb, 0); - err = rtl8180_tx(dev, skb); - WARN_ON(err); + rtl8180_tx(dev, skb); resched: /* diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index 1f5df12cb156..c5a5e788f25f 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c @@ -227,7 +227,7 @@ static void rtl8187_tx_cb(struct urb *urb) } } -static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) +static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) { struct rtl8187_priv *priv = dev->priv; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -241,7 +241,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { kfree_skb(skb); - return NETDEV_TX_OK; + return; } flags = skb->len; @@ -309,8 +309,6 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) kfree_skb(skb); } usb_free_urb(urb); - - return NETDEV_TX_OK; } static void rtl8187_rx_cb(struct urb *urb) diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index b0996bf8a214..059ab036b01d 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -82,7 +82,7 @@ static void rtl_op_stop(struct ieee80211_hw *hw) mutex_unlock(&rtlpriv->locks.conf_mutex); } -static int rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +static void rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); @@ -97,11 +97,10 @@ static int rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) rtlpriv->intf_ops->adapter_tx(hw, skb); - return NETDEV_TX_OK; + return; err_free: dev_kfree_skb_any(skb); - return NETDEV_TX_OK; } static int rtl_op_add_interface(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index 5a1c13878eaf..12c9e635a6d6 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c @@ -375,7 +375,7 @@ out: mutex_unlock(&wl->mutex); } -static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +static void wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct wl1251 *wl = hw->priv; unsigned long flags; @@ -401,8 +401,6 @@ static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) wl->tx_queue_stopped = true; spin_unlock_irqrestore(&wl->wl_lock, flags); } - - return NETDEV_TX_OK; } static int wl1251_op_start(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 95aa19ae84e5..947491a1d9cc 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1034,7 +1034,7 @@ int wl1271_plt_stop(struct wl1271 *wl) return ret; } -static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct wl1271 *wl = hw->priv; unsigned long flags; @@ -1073,8 +1073,6 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags)) ieee80211_queue_work(wl->hw, &wl->tx_work); - - return NETDEV_TX_OK; } static struct notifier_block wl1271_dev_notifier = { diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 74a269ebbeb9..5037c8b2b415 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -850,7 +850,7 @@ static int fill_ctrlset(struct zd_mac *mac, * control block of the skbuff will be initialized. If necessary the incoming * mac80211 queues will be stopped. */ -static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +static void zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct zd_mac *mac = zd_hw_mac(hw); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -865,11 +865,10 @@ static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) r = zd_usb_tx(&mac->chip.usb, skb); if (r) goto fail; - return 0; + return; fail: dev_kfree_skb(skb); - return 0; } /** diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index bdd629d72a75..c83bdcc640a5 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -104,9 +104,6 @@ static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev); static void wl_release_fw(struct wl_info *wl); /* local prototypes */ -static int wl_start(struct sk_buff *skb, struct wl_info *wl); -static int wl_start_int(struct wl_info *wl, struct ieee80211_hw *hw, - struct sk_buff *skb); static void wl_dpc(unsigned long data); MODULE_AUTHOR("Broadcom Corporation"); @@ -135,7 +132,6 @@ module_param(phymsglevel, int, 0); #define HW_TO_WL(hw) (hw->priv) #define WL_TO_HW(wl) (wl->pub->ieee_hw) -static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb); static int wl_ops_start(struct ieee80211_hw *hw); static void wl_ops_stop(struct ieee80211_hw *hw); static int wl_ops_add_interface(struct ieee80211_hw *hw, @@ -173,20 +169,18 @@ static int wl_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, struct ieee80211_sta *sta, u16 tid, u16 *ssn); -static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +static void wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { - int status; struct wl_info *wl = hw->priv; WL_LOCK(wl); if (!wl->pub->up) { WL_ERROR("ops->tx called while down\n"); - status = -ENETDOWN; + kfree_skb(skb); goto done; } - status = wl_start(skb, wl); + wlc_sendpkt_mac80211(wl->wlc, skb, hw); done: WL_UNLOCK(wl); - return status; } static int wl_ops_start(struct ieee80211_hw *hw) @@ -1316,22 +1310,6 @@ void wl_free(struct wl_info *wl) osl_detach(osh); } -/* transmit a packet */ -static int BCMFASTPATH wl_start(struct sk_buff *skb, struct wl_info *wl) -{ - if (!wl) - return -ENETDOWN; - - return wl_start_int(wl, WL_TO_HW(wl), skb); -} - -static int BCMFASTPATH -wl_start_int(struct wl_info *wl, struct ieee80211_hw *hw, struct sk_buff *skb) -{ - wlc_sendpkt_mac80211(wl->wlc, skb, hw); - return NETDEV_TX_OK; -} - void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, int prio) { diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index 2163d60c2eaf..3724e1e67ec2 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c @@ -118,13 +118,14 @@ static void wbsoft_configure_filter(struct ieee80211_hw *dev, *total_flags = new_flags; } -static int wbsoft_tx(struct ieee80211_hw *dev, struct sk_buff *skb) +static void wbsoft_tx(struct ieee80211_hw *dev, struct sk_buff *skb) { struct wbsoft_priv *priv = dev->priv; if (priv->sMlmeFrame.IsInUsed != PACKET_FREE_TO_USE) { priv->sMlmeFrame.wNumTxMMPDUDiscarded++; - return NETDEV_TX_BUSY; + kfree_skb(skb); + return; } priv->sMlmeFrame.IsInUsed = PACKET_COME_FROM_MLME; @@ -140,8 +141,6 @@ static int wbsoft_tx(struct ieee80211_hw *dev, struct sk_buff *skb) */ Mds_Tx(priv); - - return NETDEV_TX_OK; } static int wbsoft_start(struct ieee80211_hw *dev) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index a13c8d8fca5c..96cc7ed35169 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1801,7 +1801,7 @@ enum ieee80211_ampdu_mlme_action { * aborted before it expires. This callback may sleep. */ struct ieee80211_ops { - int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); + void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); int (*start)(struct ieee80211_hw *hw); void (*stop)(struct ieee80211_hw *hw); int (*add_interface)(struct ieee80211_hw *hw, diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 78af32d4bc58..32f05c1abbaf 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -5,9 +5,9 @@ #include "ieee80211_i.h" #include "driver-trace.h" -static inline int drv_tx(struct ieee80211_local *local, struct sk_buff *skb) +static inline void drv_tx(struct ieee80211_local *local, struct sk_buff *skb) { - return local->ops->tx(&local->hw, skb); + local->ops->tx(&local->hw, skb); } static inline int drv_start(struct ieee80211_local *local) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 34edf7f22b0e..081dcaf6577b 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -33,10 +33,6 @@ #include "wme.h" #include "rate.h" -#define IEEE80211_TX_OK 0 -#define IEEE80211_TX_AGAIN 1 -#define IEEE80211_TX_PENDING 2 - /* misc utils */ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, @@ -1285,16 +1281,17 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, return TX_CONTINUE; } -static int __ieee80211_tx(struct ieee80211_local *local, - struct sk_buff **skbp, - struct sta_info *sta, - bool txpending) +/* + * Returns false if the frame couldn't be transmitted but was queued instead. + */ +static bool __ieee80211_tx(struct ieee80211_local *local, struct sk_buff **skbp, + struct sta_info *sta, bool txpending) { struct sk_buff *skb = *skbp, *next; struct ieee80211_tx_info *info; struct ieee80211_sub_if_data *sdata; unsigned long flags; - int ret, len; + int len; bool fragm = false; while (skb) { @@ -1302,13 +1299,37 @@ static int __ieee80211_tx(struct ieee80211_local *local, __le16 fc; spin_lock_irqsave(&local->queue_stop_reason_lock, flags); - ret = IEEE80211_TX_OK; if (local->queue_stop_reasons[q] || - (!txpending && !skb_queue_empty(&local->pending[q]))) - ret = IEEE80211_TX_PENDING; + (!txpending && !skb_queue_empty(&local->pending[q]))) { + /* + * Since queue is stopped, queue up frames for later + * transmission from the tx-pending tasklet when the + * queue is woken again. + */ + + do { + next = skb->next; + skb->next = NULL; + /* + * NB: If txpending is true, next must already + * be NULL since we must've gone through this + * loop before already; therefore we can just + * queue the frame to the head without worrying + * about reordering of fragments. + */ + if (unlikely(txpending)) + __skb_queue_head(&local->pending[q], + skb); + else + __skb_queue_tail(&local->pending[q], + skb); + } while ((skb = next)); + + spin_unlock_irqrestore(&local->queue_stop_reason_lock, + flags); + return false; + } spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); - if (ret != IEEE80211_TX_OK) - return ret; info = IEEE80211_SKB_CB(skb); @@ -1343,15 +1364,7 @@ static int __ieee80211_tx(struct ieee80211_local *local, info->control.sta = NULL; fc = ((struct ieee80211_hdr *)skb->data)->frame_control; - ret = drv_tx(local, skb); - if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) { - dev_kfree_skb(skb); - ret = NETDEV_TX_OK; - } - if (ret != NETDEV_TX_OK) { - info->control.vif = &sdata->vif; - return IEEE80211_TX_AGAIN; - } + drv_tx(local, skb); ieee80211_tpt_led_trig_tx(local, fc, len); *skbp = skb = next; @@ -1359,7 +1372,7 @@ static int __ieee80211_tx(struct ieee80211_local *local, fragm = true; } - return IEEE80211_TX_OK; + return true; } /* @@ -1419,23 +1432,24 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) return 0; } -static void ieee80211_tx(struct ieee80211_sub_if_data *sdata, +/* + * Returns false if the frame couldn't be transmitted but was queued instead. + */ +static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, bool txpending) { struct ieee80211_local *local = sdata->local; struct ieee80211_tx_data tx; ieee80211_tx_result res_prepare; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct sk_buff *next; - unsigned long flags; - int ret, retries; u16 queue; + bool result = true; queue = skb_get_queue_mapping(skb); if (unlikely(skb->len < 10)) { dev_kfree_skb(skb); - return; + return true; } rcu_read_lock(); @@ -1445,85 +1459,19 @@ static void ieee80211_tx(struct ieee80211_sub_if_data *sdata, if (unlikely(res_prepare == TX_DROP)) { dev_kfree_skb(skb); - rcu_read_unlock(); - return; + goto out; } else if (unlikely(res_prepare == TX_QUEUED)) { - rcu_read_unlock(); - return; + goto out; } tx.channel = local->hw.conf.channel; info->band = tx.channel->band; - if (invoke_tx_handlers(&tx)) - goto out; - - retries = 0; - retry: - ret = __ieee80211_tx(local, &tx.skb, tx.sta, txpending); - switch (ret) { - case IEEE80211_TX_OK: - break; - case IEEE80211_TX_AGAIN: - /* - * Since there are no fragmented frames on A-MPDU - * queues, there's no reason for a driver to reject - * a frame there, warn and drop it. - */ - if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU)) - goto drop; - /* fall through */ - case IEEE80211_TX_PENDING: - skb = tx.skb; - - spin_lock_irqsave(&local->queue_stop_reason_lock, flags); - - if (local->queue_stop_reasons[queue] || - !skb_queue_empty(&local->pending[queue])) { - /* - * if queue is stopped, queue up frames for later - * transmission from the tasklet - */ - do { - next = skb->next; - skb->next = NULL; - if (unlikely(txpending)) - __skb_queue_head(&local->pending[queue], - skb); - else - __skb_queue_tail(&local->pending[queue], - skb); - } while ((skb = next)); - - spin_unlock_irqrestore(&local->queue_stop_reason_lock, - flags); - } else { - /* - * otherwise retry, but this is a race condition or - * a driver bug (which we warn about if it persists) - */ - spin_unlock_irqrestore(&local->queue_stop_reason_lock, - flags); - - retries++; - if (WARN(retries > 10, "tx refused but queue active\n")) - goto drop; - goto retry; - } - } + if (!invoke_tx_handlers(&tx)) + result = __ieee80211_tx(local, &tx.skb, tx.sta, txpending); out: rcu_read_unlock(); - return; - - drop: - rcu_read_unlock(); - - skb = tx.skb; - while (skb) { - next = skb->next; - dev_kfree_skb(skb); - skb = next; - } + return result; } /* device xmit handlers */ @@ -2070,6 +2018,11 @@ void ieee80211_clear_tx_pending(struct ieee80211_local *local) skb_queue_purge(&local->pending[i]); } +/* + * Returns false if the frame couldn't be transmitted but was queued instead, + * which in this case means re-queued -- take as an indication to stop sending + * more pending frames. + */ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local, struct sk_buff *skb) { @@ -2077,20 +2030,17 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata; struct sta_info *sta; struct ieee80211_hdr *hdr; - int ret; - bool result = true; + bool result; sdata = vif_to_sdata(info->control.vif); if (info->flags & IEEE80211_TX_INTFL_NEED_TXPROCESSING) { - ieee80211_tx(sdata, skb, true); + result = ieee80211_tx(sdata, skb, true); } else { hdr = (struct ieee80211_hdr *)skb->data; sta = sta_info_get(sdata, hdr->addr1); - ret = __ieee80211_tx(local, &skb, sta, true); - if (ret != IEEE80211_TX_OK) - result = false; + result = __ieee80211_tx(local, &skb, sta, true); } return result; @@ -2132,8 +2082,6 @@ void ieee80211_tx_pending(unsigned long data) flags); txok = ieee80211_tx_pending_skb(local, skb); - if (!txok) - __skb_queue_head(&local->pending[i], skb); spin_lock_irqsave(&local->queue_stop_reason_lock, flags); if (!txok) -- cgit v1.2.3 From 46c2cb8cae87c903caba67eb8afc0f8985832956 Mon Sep 17 00:00:00 2001 From: Joe Gunn Date: Fri, 25 Feb 2011 02:08:49 -0800 Subject: orinoco: Drop scan results with unknown channels If the frequency can not be mapped to a channel structure log it and drop it. Signed-off-by: Joseph J. Gunn Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/scan.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c index 86cb54c842e7..e99ca1c1e0d8 100644 --- a/drivers/net/wireless/orinoco/scan.c +++ b/drivers/net/wireless/orinoco/scan.c @@ -111,6 +111,11 @@ static void orinoco_add_hostscan_result(struct orinoco_private *priv, freq = ieee80211_dsss_chan_to_freq(le16_to_cpu(bss->a.channel)); channel = ieee80211_get_channel(wiphy, freq); + if (!channel) { + printk(KERN_DEBUG "Invalid channel designation %04X(%04X)", + bss->a.channel, freq); + return; /* Then ignore it for now */ + } timestamp = 0; capability = le16_to_cpu(bss->a.capabilities); beacon_interval = le16_to_cpu(bss->a.beacon_interv); -- cgit v1.2.3 From 850bedcc10377629ea88c96c07f8e1d0a99cf4ca Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 25 Feb 2011 12:24:11 +0100 Subject: iwlagn: fix iwlagn_check_needed_chains This function was intended to calculate the number of RX chains needed, but could only work where the AP's streams were asymmetric, i.e. 2 TX and 3 RX or similar. In the case where IEEE80211_HT_MCS_TX_RX_DIFF was not set, this function would calculate the wrong information. Additionally, mac80211 didn't pass through the required values at all, so it couldn't work anyway. Rewrite the logic in this function and add appropriate comments to make it readable. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 58 ++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 6c2adc58d654..dfdbea6e8f99 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -471,6 +471,7 @@ static void iwlagn_check_needed_chains(struct iwl_priv *priv, struct iwl_rxon_context *tmp; struct ieee80211_sta *sta; struct iwl_ht_config *ht_conf = &priv->current_ht_config; + struct ieee80211_sta_ht_cap *ht_cap; bool need_multiple; lockdep_assert_held(&priv->mutex); @@ -479,23 +480,7 @@ static void iwlagn_check_needed_chains(struct iwl_priv *priv, case NL80211_IFTYPE_STATION: rcu_read_lock(); sta = ieee80211_find_sta(vif, bss_conf->bssid); - if (sta) { - struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; - int maxstreams; - - maxstreams = (ht_cap->mcs.tx_params & - IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK) - >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; - maxstreams += 1; - - need_multiple = true; - - if ((ht_cap->mcs.rx_mask[1] == 0) && - (ht_cap->mcs.rx_mask[2] == 0)) - need_multiple = false; - if (maxstreams <= 1) - need_multiple = false; - } else { + if (!sta) { /* * If at all, this can only happen through a race * when the AP disconnects us while we're still @@ -503,7 +488,46 @@ static void iwlagn_check_needed_chains(struct iwl_priv *priv, * will soon tell us about that. */ need_multiple = false; + rcu_read_unlock(); + break; + } + + ht_cap = &sta->ht_cap; + + need_multiple = true; + + /* + * If the peer advertises no support for receiving 2 and 3 + * stream MCS rates, it can't be transmitting them either. + */ + if (ht_cap->mcs.rx_mask[1] == 0 && + ht_cap->mcs.rx_mask[2] == 0) { + need_multiple = false; + } else if (!(ht_cap->mcs.tx_params & + IEEE80211_HT_MCS_TX_DEFINED)) { + /* If it can't TX MCS at all ... */ + need_multiple = false; + } else if (ht_cap->mcs.tx_params & + IEEE80211_HT_MCS_TX_RX_DIFF) { + int maxstreams; + + /* + * But if it can receive them, it might still not + * be able to transmit them, which is what we need + * to check here -- so check the number of streams + * it advertises for TX (if different from RX). + */ + + maxstreams = (ht_cap->mcs.tx_params & + IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK); + maxstreams >>= + IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; + maxstreams += 1; + + if (maxstreams <= 1) + need_multiple = false; } + rcu_read_unlock(); break; case NL80211_IFTYPE_ADHOC: -- cgit v1.2.3 From 3311abbbbff1719bbbc8208761e4a75f095f383c Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Fri, 25 Feb 2011 12:34:11 +0100 Subject: b43: fill PHY ctl word1 in TX header for N-PHY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes tramissing on OFDM rates for PHYs 1 and 2. There is still something wrong with PHYs 3+. Tests has shown decreasing of performance on CCK rates by 1-2%, we have to live with that. Additionaly this noticeably reduces amount of PHY errors. They were mostly produced by auto-switching to higher rate for better performanced, which resulted in no transmit at all and PHY errors. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/xmit.c | 73 +++++++++++++++++++++++++++++++++++++++++ drivers/net/wireless/b43/xmit.h | 6 ++++ 2 files changed, 79 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index ad605bcdd40e..e5be381c17bc 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c @@ -32,6 +32,36 @@ #include "dma.h" #include "pio.h" +static const struct b43_tx_legacy_rate_phy_ctl_entry b43_tx_legacy_rate_phy_ctl[] = { + { B43_CCK_RATE_1MB, 0x0, 0x0 }, + { B43_CCK_RATE_2MB, 0x0, 0x1 }, + { B43_CCK_RATE_5MB, 0x0, 0x2 }, + { B43_CCK_RATE_11MB, 0x0, 0x3 }, + { B43_OFDM_RATE_6MB, B43_TXH_PHY1_CRATE_1_2, B43_TXH_PHY1_MODUL_BPSK }, + { B43_OFDM_RATE_9MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_BPSK }, + { B43_OFDM_RATE_12MB, B43_TXH_PHY1_CRATE_1_2, B43_TXH_PHY1_MODUL_QPSK }, + { B43_OFDM_RATE_18MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_QPSK }, + { B43_OFDM_RATE_24MB, B43_TXH_PHY1_CRATE_1_2, B43_TXH_PHY1_MODUL_QAM16 }, + { B43_OFDM_RATE_36MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_QAM16 }, + { B43_OFDM_RATE_48MB, B43_TXH_PHY1_CRATE_2_3, B43_TXH_PHY1_MODUL_QAM64 }, + { B43_OFDM_RATE_54MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_QAM64 }, +}; + +static const struct b43_tx_legacy_rate_phy_ctl_entry * +b43_tx_legacy_rate_phy_ctl_ent(u8 bitrate) +{ + const struct b43_tx_legacy_rate_phy_ctl_entry *e; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(b43_tx_legacy_rate_phy_ctl); i++) { + e = &(b43_tx_legacy_rate_phy_ctl[i]); + if (e->bitrate == bitrate) + return e; + } + + B43_WARN_ON(1); + return NULL; +} /* Extract the bitrate index out of a CCK PLCP header. */ static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp) @@ -145,6 +175,34 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, } } +static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate) +{ + const struct b43_phy *phy = &dev->phy; + const struct b43_tx_legacy_rate_phy_ctl_entry *e; + u16 control = 0; + u16 bw; + + if (phy->type == B43_PHYTYPE_LP) + bw = B43_TXH_PHY1_BW_20; + else /* FIXME */ + bw = B43_TXH_PHY1_BW_20; + + if (0) { /* FIXME: MIMO */ + } else if (b43_is_cck_rate(bitrate) && phy->type != B43_PHYTYPE_LP) { + control = bw; + } else { + control = bw; + e = b43_tx_legacy_rate_phy_ctl_ent(bitrate); + if (e) { + control |= e->coding_rate; + control |= e->modulation; + } + control |= B43_TXH_PHY1_MODE_SISO; + } + + return control; +} + static u8 b43_calc_fallback_rate(u8 bitrate) { switch (bitrate) { @@ -437,6 +495,14 @@ int b43_generate_txhdr(struct b43_wldev *dev, extra_ft |= B43_TXH_EFT_RTSFB_OFDM; else extra_ft |= B43_TXH_EFT_RTSFB_CCK; + + if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS && + phy->type == B43_PHYTYPE_N) { + txhdr->phy_ctl1_rts = cpu_to_le16( + b43_generate_tx_phy_ctl1(dev, rts_rate)); + txhdr->phy_ctl1_rts_fb = cpu_to_le16( + b43_generate_tx_phy_ctl1(dev, rts_rate_fb)); + } } /* Magic cookie */ @@ -445,6 +511,13 @@ int b43_generate_txhdr(struct b43_wldev *dev, else txhdr->new_format.cookie = cpu_to_le16(cookie); + if (phy->type == B43_PHYTYPE_N) { + txhdr->phy_ctl1 = + cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate)); + txhdr->phy_ctl1_fb = + cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate_fb)); + } + /* Apply the bitfields */ txhdr->mac_ctl = cpu_to_le32(mac_ctl); txhdr->phy_ctl = cpu_to_le16(phy_ctl); diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h index d4cf9b390af3..42debb5cd6fa 100644 --- a/drivers/net/wireless/b43/xmit.h +++ b/drivers/net/wireless/b43/xmit.h @@ -73,6 +73,12 @@ struct b43_txhdr { } __packed; } __packed; +struct b43_tx_legacy_rate_phy_ctl_entry { + u8 bitrate; + u16 coding_rate; + u16 modulation; +}; + /* MAC TX control */ #define B43_TXH_MAC_USEFBR 0x10000000 /* Use fallback rate for this AMPDU */ #define B43_TXH_MAC_KEYIDX 0x0FF00000 /* Security key index */ -- cgit v1.2.3 From 06fed5737932585775f0f70bc06eb0fac76c7a27 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Fri, 25 Feb 2011 17:31:01 +0530 Subject: ath9k_hw: Fix pcie_serdes setting for AR9485 1.1 version. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 6fa3c24af2da..7f5de6e4448b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -78,15 +78,15 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) /* Awake Setting */ INIT_INI_ARRAY(&ah->iniPcieSerdes, - ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1, - ARRAY_SIZE(ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1), + ar9485_1_1_pcie_phy_clkreq_disable_L1, + ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1), 2); /* Sleep Setting */ INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, - ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1, - ARRAY_SIZE(ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1), + ar9485_1_1_pcie_phy_clkreq_disable_L1, + ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1), 2); } else if (AR_SREV_9485(ah)) { /* mac */ -- cgit v1.2.3 From 7e3514fdc0f2c1c007f46f0ca584808edbfaee8f Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Fri, 25 Feb 2011 17:31:02 +0530 Subject: ath9k: Cancel pll_work while disabling radio. pll_work should be cancelled on full_sleep or it may cause redundant chip reset. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 39a72ae80970..b8496696460e 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -910,6 +910,8 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) ath9k_hw_set_gpio(ah, ah->led_pin, 0); ieee80211_wake_queues(hw); + ieee80211_queue_delayed_work(hw, &sc->hw_pll_work, HZ/2); + out: spin_unlock_bh(&sc->sc_pcu_lock); @@ -923,6 +925,8 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) int r; ath9k_ps_wakeup(sc); + cancel_delayed_work_sync(&sc->hw_pll_work); + spin_lock_bh(&sc->sc_pcu_lock); ieee80211_stop_queues(hw); -- cgit v1.2.3 From 08f6c85223b71ba7bf2a5ebbdf735881475a8e3c Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Fri, 25 Feb 2011 17:31:03 +0530 Subject: ath9k: Fix compilation warning. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initialize txq to avoid this warning: drivers/net/wireless/ath/ath9k/main.c: In function ‘ath9k_flush’: drivers/net/wireless/ath/ath9k/main.c:2138: warning: ‘txq’ may be used uninitialized in this function Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index b8496696460e..97830c7f62c9 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2133,7 +2133,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) { #define ATH_FLUSH_TIMEOUT 60 /* ms */ struct ath_softc *sc = hw->priv; - struct ath_txq *txq; + struct ath_txq *txq = NULL; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); int i, j, npend = 0; -- cgit v1.2.3 From 5f5b5c51858e79fb0b338dd0d96c8789ba876878 Mon Sep 17 00:00:00 2001 From: Richard Schütz Date: Fri, 11 Feb 2011 17:27:19 +0100 Subject: staging: samsung-laptop: add support for N145P/N250P/N260P machines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add DMI data for Samsung N145P/N250P/N260P Signed-off-by: Richard Schütz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index 51ec6216b1ea..678d1a2be1c7 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -592,6 +592,15 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, .callback = dmi_check_cb, }, + { + .ident = "N145P/N250P/N260P", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "N145P/N250P/N260P"), + DMI_MATCH(DMI_BOARD_NAME, "N145P/N250P/N260P"), + }, + .callback = dmi_check_cb, + }, { }, }; MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); -- cgit v1.2.3 From e20b6f359ad9d1fe26eae08a0051bcbd277be540 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 25 Feb 2011 13:05:30 -0800 Subject: staging: samsung-laptop: add support for r70 laptops Reported-by: Evgeny Bobkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index 678d1a2be1c7..c042ed5b0bce 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -601,6 +601,16 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, .callback = dmi_check_cb, }, + { + .ident = "R70/R71", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "R70/R71"), + DMI_MATCH(DMI_BOARD_NAME, "R70/R71"), + }, + .callback = dmi_check_cb, + }, { }, }; MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); -- cgit v1.2.3 From 9b5040be4779b36d208362a3c0df00bb97f6c0a0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 25 Feb 2011 13:35:41 -0800 Subject: staging: samsung-laptop: add support for R519 laptops Reported-by: Piotr Mitas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index c042ed5b0bce..575694b74e9b 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -564,6 +564,16 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, .callback = dmi_check_cb, }, + { + .ident = "R519/R719", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "R519/R719"), + DMI_MATCH(DMI_BOARD_NAME, "R519/R719"), + }, + .callback = dmi_check_cb, + }, { .ident = "N150/N210/N220", .matches = { -- cgit v1.2.3 From db559b079a60535f45a06f64595fbe4b78e2efbb Mon Sep 17 00:00:00 2001 From: Roman Grebennikov Date: Fri, 18 Feb 2011 13:15:57 +0300 Subject: staging: samsung-laptop: Add support for Samsung NP-X120/X170 laptop Add Samsung NP-X120/X170 laptop DMI signature to samsung-laptop DMI table. Signed-off-by: Roman Grebennikov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index 575694b74e9b..17e2c9e943d4 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -524,6 +524,16 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, .callback = dmi_check_cb, }, + { + .ident = "X120/X170", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "X120/X170"), + DMI_MATCH(DMI_BOARD_NAME, "X120/X170"), + }, + .callback = dmi_check_cb, + }, { .ident = "NC10", .matches = { -- cgit v1.2.3 From d40358509ee862d7e4049187bc05eba1911a2959 Mon Sep 17 00:00:00 2001 From: Jelle Martijn Kok Date: Fri, 25 Feb 2011 11:13:55 -0800 Subject: RTC: fix typo in drivers/rtc/rtc-at91sam9.c The member of the rtc_class_ops struct is called alarm_irq_enable and not alarm_irq_enabled CC: Thomas Gleixner Signed-off-by: Jelle Martijn Kok Signed-off-by: John Stultz Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-at91sam9.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index c36749e4c926..5469c52cba3d 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -309,7 +309,7 @@ static const struct rtc_class_ops at91_rtc_ops = { .read_alarm = at91_rtc_readalarm, .set_alarm = at91_rtc_setalarm, .proc = at91_rtc_proc, - .alarm_irq_enabled = at91_rtc_alarm_irq_enable, + .alarm_irq_enable = at91_rtc_alarm_irq_enable, }; /* -- cgit v1.2.3 From ef33417dc9be8d8daca3c715fb5d1226b250725c Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Fri, 25 Feb 2011 15:51:01 -0500 Subject: iwlegacy: change some symbols duplicated from iwlwifi directory drivers/net/wireless/iwlegacy/built-in.o:(.rodata+0x29f0): multiple definition of `iwl_rates' drivers/net/wireless/iwlwifi/built-in.o:(.rodata+0xa68): first defined here powerpc64-linux-ld: Warning: size of symbol `iwl_rates' changed from 143 in drivers/net/wireless/iwlwifi/built-in.o to 130 in drivers/net/wireless/iwlegacy/built-in.o drivers/net/wireless/iwlegacy/built-in.o:(.data+0x0): multiple definition of `bt_coex_active' drivers/net/wireless/iwlwifi/built-in.o:(.data+0x668): first defined here drivers/net/wireless/iwlegacy/built-in.o:(.rodata+0x750): multiple definition of `iwl_eeprom_band_1' drivers/net/wireless/iwlwifi/built-in.o:(.rodata+0x27d0): first defined here drivers/net/wireless/iwlegacy/built-in.o:(.rodata+0x3f0): multiple definition of `iwl_bcast_addr' drivers/net/wireless/iwlwifi/built-in.o:(.rodata+0x24f8): first defined here drivers/net/wireless/iwlegacy/built-in.o:(.bss+0x3d48): multiple definition of `iwl_debug_level' drivers/net/wireless/iwlwifi/built-in.o:(.bss+0x21950): first defined here Reported-by: Stephen Rothwell Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-4965-lib.c | 4 +- drivers/net/wireless/iwlegacy/iwl-4965-rs.c | 20 +++++----- drivers/net/wireless/iwlegacy/iwl-4965-sta.c | 5 ++- drivers/net/wireless/iwlegacy/iwl-4965-tx.c | 2 +- drivers/net/wireless/iwlegacy/iwl-core.c | 21 +++++------ drivers/net/wireless/iwlegacy/iwl-core.h | 2 - drivers/net/wireless/iwlegacy/iwl-debug.h | 2 +- drivers/net/wireless/iwlegacy/iwl-debugfs.c | 4 +- drivers/net/wireless/iwlegacy/iwl-dev.h | 8 ++-- drivers/net/wireless/iwlegacy/iwl-eeprom.c | 54 +++++++++++++-------------- drivers/net/wireless/iwlegacy/iwl-eeprom.h | 2 +- drivers/net/wireless/iwlegacy/iwl-legacy-rs.h | 4 +- drivers/net/wireless/iwlegacy/iwl-scan.c | 4 +- drivers/net/wireless/iwlegacy/iwl3945-base.c | 6 +-- drivers/net/wireless/iwlegacy/iwl4965-base.c | 6 +-- 15 files changed, 71 insertions(+), 73 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c index bd9618a4269d..5a8a3cce27bc 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c @@ -424,7 +424,7 @@ int iwl4965_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band) if (band == IEEE80211_BAND_5GHZ) band_offset = IWL_FIRST_OFDM_RATE; for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++) - if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF)) + if (iwlegacy_rates[idx].plcp == (rate_n_flags & 0xFF)) return idx - band_offset; } @@ -995,7 +995,7 @@ int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) /* use bcast addr, will not be transmitted but must be valid */ cmd_len = iwl_legacy_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, - iwl_bcast_addr, NULL, 0, + iwlegacy_bcast_addr, NULL, 0, IWL_MAX_SCAN_SIZE - sizeof(*scan)); } diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c index 69abd2816f8d..31ac672b64e1 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c @@ -97,7 +97,7 @@ static const u8 ant_toggle_lookup[] = { * maps to IWL_RATE_INVALID * */ -const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = { +const struct iwl_rate_info iwlegacy_rates[IWL_RATE_COUNT] = { IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2), /* 1mbps */ IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5), /* 2mbps */ IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11), /*5.5mbps */ @@ -133,8 +133,8 @@ static int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags) /* legacy rate format, search for match in table */ } else { - for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++) - if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF)) + for (idx = 0; idx < ARRAY_SIZE(iwlegacy_rates); idx++) + if (iwlegacy_rates[idx].plcp == (rate_n_flags & 0xFF)) return idx; } @@ -500,7 +500,7 @@ static u32 iwl4965_rate_n_flags_from_tbl(struct iwl_priv *priv, u32 rate_n_flags = 0; if (is_legacy(tbl->lq_type)) { - rate_n_flags = iwl_rates[index].plcp; + rate_n_flags = iwlegacy_rates[index].plcp; if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE) rate_n_flags |= RATE_MCS_CCK_MSK; @@ -512,9 +512,9 @@ static u32 iwl4965_rate_n_flags_from_tbl(struct iwl_priv *priv, rate_n_flags = RATE_MCS_HT_MSK; if (is_siso(tbl->lq_type)) - rate_n_flags |= iwl_rates[index].plcp_siso; + rate_n_flags |= iwlegacy_rates[index].plcp_siso; else - rate_n_flags |= iwl_rates[index].plcp_mimo2; + rate_n_flags |= iwlegacy_rates[index].plcp_mimo2; } else { IWL_ERR(priv, "Invalid tbl->lq_type %d\n", tbl->lq_type); } @@ -703,7 +703,7 @@ iwl4965_rs_get_adjacent_rate(struct iwl_priv *priv, u8 index, u16 rate_mask, low = index; while (low != IWL_RATE_INVALID) { - low = iwl_rates[low].prev_rs; + low = iwlegacy_rates[low].prev_rs; if (low == IWL_RATE_INVALID) break; if (rate_mask & (1 << low)) @@ -713,7 +713,7 @@ iwl4965_rs_get_adjacent_rate(struct iwl_priv *priv, u8 index, u16 rate_mask, high = index; while (high != IWL_RATE_INVALID) { - high = iwl_rates[high].next_rs; + high = iwlegacy_rates[high].next_rs; if (high == IWL_RATE_INVALID) break; if (rate_mask & (1 << high)) @@ -2221,7 +2221,7 @@ static void iwl4965_rs_initialize_lq(struct iwl_priv *priv, if ((i < 0) || (i >= IWL_RATE_COUNT)) i = 0; - rate = iwl_rates[i].plcp; + rate = iwlegacy_rates[i].plcp; tbl->ant_type = iwl4965_first_antenna(valid_tx_ant); rate |= tbl->ant_type << RATE_MCS_ANT_POS; @@ -2791,7 +2791,7 @@ static ssize_t iwl4965_rs_sta_dbgfs_rate_scale_data_read(struct file *file, else desc += sprintf(buff+desc, "Bit Rate= %d Mb/s\n", - iwl_rates[lq_sta->last_txrate_idx].ieee >> 1); + iwlegacy_rates[lq_sta->last_txrate_idx].ieee >> 1); ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); return ret; diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-sta.c b/drivers/net/wireless/iwlegacy/iwl-4965-sta.c index 057da2c3bf95..a262c23553d2 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-sta.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-sta.c @@ -59,7 +59,8 @@ iwl4965_sta_alloc_lq(struct iwl_priv *priv, u8 sta_id) rate_flags |= iwl4965_first_antenna(priv->hw_params.valid_tx_ant) << RATE_MCS_ANT_POS; - rate_n_flags = iwl4965_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); + rate_n_flags = iwl4965_hw_set_rate_n_flags(iwlegacy_rates[r].plcp, + rate_flags); for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) link_cmd->rs_table[i].rate_n_flags = rate_n_flags; @@ -553,7 +554,7 @@ int iwl4965_alloc_bcast_station(struct iwl_priv *priv, u8 sta_id; spin_lock_irqsave(&priv->sta_lock, flags); - sta_id = iwl_legacy_prep_station(priv, ctx, iwl_bcast_addr, + sta_id = iwl_legacy_prep_station(priv, ctx, iwlegacy_bcast_addr, false, NULL); if (sta_id == IWL_INVALID_STATION) { IWL_ERR(priv, "Unable to prepare broadcast station\n"); diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-tx.c b/drivers/net/wireless/iwlegacy/iwl-4965-tx.c index 2e0f0dbf87ec..829db91896b0 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-tx.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-tx.c @@ -203,7 +203,7 @@ static void iwl4965_tx_cmd_build_rate(struct iwl_priv *priv, if (info->band == IEEE80211_BAND_5GHZ) rate_idx += IWL_FIRST_OFDM_RATE; /* Get PLCP rate for tx_cmd->rate_n_flags */ - rate_plcp = iwl_rates[rate_idx].plcp; + rate_plcp = iwlegacy_rates[rate_idx].plcp; /* Zero out flags for this packet */ rate_flags = 0; diff --git a/drivers/net/wireless/iwlegacy/iwl-core.c b/drivers/net/wireless/iwlegacy/iwl-core.c index 7cc560bc4f95..d418b647be80 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.c +++ b/drivers/net/wireless/iwlegacy/iwl-core.c @@ -64,16 +64,15 @@ MODULE_LICENSE("GPL"); * * default: bt_coex_active = true (BT_COEX_ENABLE) */ -bool bt_coex_active = true; -EXPORT_SYMBOL_GPL(bt_coex_active); +static bool bt_coex_active = true; module_param(bt_coex_active, bool, S_IRUGO); MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist"); -u32 iwl_debug_level; -EXPORT_SYMBOL(iwl_debug_level); +u32 iwlegacy_debug_level; +EXPORT_SYMBOL(iwlegacy_debug_level); -const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -EXPORT_SYMBOL(iwl_bcast_addr); +const u8 iwlegacy_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +EXPORT_SYMBOL(iwlegacy_bcast_addr); /* This function both allocates and initializes hw and priv. */ @@ -183,7 +182,7 @@ int iwl_legacy_init_geos(struct iwl_priv *priv) /* 5.2GHz channels start after the 2.4GHz channels */ sband = &priv->bands[IEEE80211_BAND_5GHZ]; - sband->channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)]; + sband->channels = &channels[ARRAY_SIZE(iwlegacy_eeprom_band_1)]; /* just OFDM */ sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; @@ -1489,7 +1488,7 @@ int iwl_legacy_alloc_traffic_mem(struct iwl_priv *priv) { u32 traffic_size = IWL_TRAFFIC_DUMP_SIZE; - if (iwl_debug_level & IWL_DL_TX) { + if (iwlegacy_debug_level & IWL_DL_TX) { if (!priv->tx_traffic) { priv->tx_traffic = kzalloc(traffic_size, GFP_KERNEL); @@ -1497,7 +1496,7 @@ int iwl_legacy_alloc_traffic_mem(struct iwl_priv *priv) return -ENOMEM; } } - if (iwl_debug_level & IWL_DL_RX) { + if (iwlegacy_debug_level & IWL_DL_RX) { if (!priv->rx_traffic) { priv->rx_traffic = kzalloc(traffic_size, GFP_KERNEL); @@ -1526,7 +1525,7 @@ void iwl_legacy_dbg_log_tx_data_frame(struct iwl_priv *priv, __le16 fc; u16 len; - if (likely(!(iwl_debug_level & IWL_DL_TX))) + if (likely(!(iwlegacy_debug_level & IWL_DL_TX))) return; if (!priv->tx_traffic) @@ -1551,7 +1550,7 @@ void iwl_legacy_dbg_log_rx_data_frame(struct iwl_priv *priv, __le16 fc; u16 len; - if (likely(!(iwl_debug_level & IWL_DL_RX))) + if (likely(!(iwlegacy_debug_level & IWL_DL_RX))) return; if (!priv->rx_traffic) diff --git a/drivers/net/wireless/iwlegacy/iwl-core.h b/drivers/net/wireless/iwlegacy/iwl-core.h index 1159b0d255b8..c6d12d7e96b6 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.h +++ b/drivers/net/wireless/iwlegacy/iwl-core.h @@ -628,8 +628,6 @@ static inline const struct ieee80211_supported_band *iwl_get_hw_mode( return priv->hw->wiphy->bands[band]; } -extern bool bt_coex_active; - /* mac80211 handlers */ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed); void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/iwlegacy/iwl-debug.h b/drivers/net/wireless/iwlegacy/iwl-debug.h index 665789f3e75d..ae13112701bf 100644 --- a/drivers/net/wireless/iwlegacy/iwl-debug.h +++ b/drivers/net/wireless/iwlegacy/iwl-debug.h @@ -30,7 +30,7 @@ #define __iwl_legacy_debug_h__ struct iwl_priv; -extern u32 iwl_debug_level; +extern u32 iwlegacy_debug_level; #define IWL_ERR(p, f, a...) dev_err(&((p)->pci_dev->dev), f, ## a) #define IWL_WARN(p, f, a...) dev_warn(&((p)->pci_dev->dev), f, ## a) diff --git a/drivers/net/wireless/iwlegacy/iwl-debugfs.c b/drivers/net/wireless/iwlegacy/iwl-debugfs.c index 6ea9c4fbcd3a..2d32438b4cb8 100644 --- a/drivers/net/wireless/iwlegacy/iwl-debugfs.c +++ b/drivers/net/wireless/iwlegacy/iwl-debugfs.c @@ -748,7 +748,7 @@ static ssize_t iwl_legacy_dbgfs_traffic_log_read(struct file *file, "q[%d]: read_ptr: %u, write_ptr: %u\n", cnt, q->read_ptr, q->write_ptr); } - if (priv->tx_traffic && (iwl_debug_level & IWL_DL_TX)) { + if (priv->tx_traffic && (iwlegacy_debug_level & IWL_DL_TX)) { ptr = priv->tx_traffic; pos += scnprintf(buf + pos, bufsz - pos, "Tx Traffic idx: %u\n", priv->tx_traffic_idx); @@ -771,7 +771,7 @@ static ssize_t iwl_legacy_dbgfs_traffic_log_read(struct file *file, "read: %u, write: %u\n", rxq->read, rxq->write); - if (priv->rx_traffic && (iwl_debug_level & IWL_DL_RX)) { + if (priv->rx_traffic && (iwlegacy_debug_level & IWL_DL_RX)) { ptr = priv->rx_traffic; pos += scnprintf(buf + pos, bufsz - pos, "Rx Traffic idx: %u\n", priv->rx_traffic_idx); diff --git a/drivers/net/wireless/iwlegacy/iwl-dev.h b/drivers/net/wireless/iwlegacy/iwl-dev.h index 25718cf9919a..9ee849d669f3 100644 --- a/drivers/net/wireless/iwlegacy/iwl-dev.h +++ b/drivers/net/wireless/iwlegacy/iwl-dev.h @@ -624,7 +624,7 @@ struct iwl_hw_params { * ****************************************************************************/ extern void iwl4965_update_chain_flags(struct iwl_priv *priv); -extern const u8 iwl_bcast_addr[ETH_ALEN]; +extern const u8 iwlegacy_bcast_addr[ETH_ALEN]; extern int iwl_legacy_queue_space(const struct iwl_queue *q); static inline int iwl_legacy_queue_used(const struct iwl_queue *q, int i) { @@ -1285,7 +1285,7 @@ struct iwl_priv { #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG /* debugging info */ u32 debug_level; /* per device debugging will override global - iwl_debug_level if set */ + iwlegacy_debug_level if set */ #endif /* CONFIG_IWLWIFI_LEGACY_DEBUG */ #ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS /* debugfs */ @@ -1338,12 +1338,12 @@ static inline u32 iwl_legacy_get_debug_level(struct iwl_priv *priv) if (priv->debug_level) return priv->debug_level; else - return iwl_debug_level; + return iwlegacy_debug_level; } #else static inline u32 iwl_legacy_get_debug_level(struct iwl_priv *priv) { - return iwl_debug_level; + return iwlegacy_debug_level; } #endif diff --git a/drivers/net/wireless/iwlegacy/iwl-eeprom.c b/drivers/net/wireless/iwlegacy/iwl-eeprom.c index 39e577323942..04c5648027df 100644 --- a/drivers/net/wireless/iwlegacy/iwl-eeprom.c +++ b/drivers/net/wireless/iwlegacy/iwl-eeprom.c @@ -77,7 +77,7 @@ /************************** EEPROM BANDS **************************** * - * The iwl_eeprom_band definitions below provide the mapping from the + * The iwlegacy_eeprom_band definitions below provide the mapping from the * EEPROM contents to the specific channel number supported for each * band. * @@ -107,32 +107,32 @@ *********************************************************************/ /* 2.4 GHz */ -const u8 iwl_eeprom_band_1[14] = { +const u8 iwlegacy_eeprom_band_1[14] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }; /* 5.2 GHz bands */ -static const u8 iwl_eeprom_band_2[] = { /* 4915-5080MHz */ +static const u8 iwlegacy_eeprom_band_2[] = { /* 4915-5080MHz */ 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 }; -static const u8 iwl_eeprom_band_3[] = { /* 5170-5320MHz */ +static const u8 iwlegacy_eeprom_band_3[] = { /* 5170-5320MHz */ 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 }; -static const u8 iwl_eeprom_band_4[] = { /* 5500-5700MHz */ +static const u8 iwlegacy_eeprom_band_4[] = { /* 5500-5700MHz */ 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 }; -static const u8 iwl_eeprom_band_5[] = { /* 5725-5825MHz */ +static const u8 iwlegacy_eeprom_band_5[] = { /* 5725-5825MHz */ 145, 149, 153, 157, 161, 165 }; -static const u8 iwl_eeprom_band_6[] = { /* 2.4 ht40 channel */ +static const u8 iwlegacy_eeprom_band_6[] = { /* 2.4 ht40 channel */ 1, 2, 3, 4, 5, 6, 7 }; -static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */ +static const u8 iwlegacy_eeprom_band_7[] = { /* 5.2 ht40 channel */ 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 }; @@ -273,46 +273,46 @@ static void iwl_legacy_init_band_reference(const struct iwl_priv *priv, eeprom_ops.regulatory_bands[eep_band - 1]; switch (eep_band) { case 1: /* 2.4GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1); + *eeprom_ch_count = ARRAY_SIZE(iwlegacy_eeprom_band_1); *eeprom_ch_info = (struct iwl_eeprom_channel *) iwl_legacy_eeprom_query_addr(priv, offset); - *eeprom_ch_index = iwl_eeprom_band_1; + *eeprom_ch_index = iwlegacy_eeprom_band_1; break; case 2: /* 4.9GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2); + *eeprom_ch_count = ARRAY_SIZE(iwlegacy_eeprom_band_2); *eeprom_ch_info = (struct iwl_eeprom_channel *) iwl_legacy_eeprom_query_addr(priv, offset); - *eeprom_ch_index = iwl_eeprom_band_2; + *eeprom_ch_index = iwlegacy_eeprom_band_2; break; case 3: /* 5.2GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3); + *eeprom_ch_count = ARRAY_SIZE(iwlegacy_eeprom_band_3); *eeprom_ch_info = (struct iwl_eeprom_channel *) iwl_legacy_eeprom_query_addr(priv, offset); - *eeprom_ch_index = iwl_eeprom_band_3; + *eeprom_ch_index = iwlegacy_eeprom_band_3; break; case 4: /* 5.5GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4); + *eeprom_ch_count = ARRAY_SIZE(iwlegacy_eeprom_band_4); *eeprom_ch_info = (struct iwl_eeprom_channel *) iwl_legacy_eeprom_query_addr(priv, offset); - *eeprom_ch_index = iwl_eeprom_band_4; + *eeprom_ch_index = iwlegacy_eeprom_band_4; break; case 5: /* 5.7GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5); + *eeprom_ch_count = ARRAY_SIZE(iwlegacy_eeprom_band_5); *eeprom_ch_info = (struct iwl_eeprom_channel *) iwl_legacy_eeprom_query_addr(priv, offset); - *eeprom_ch_index = iwl_eeprom_band_5; + *eeprom_ch_index = iwlegacy_eeprom_band_5; break; case 6: /* 2.4GHz ht40 channels */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6); + *eeprom_ch_count = ARRAY_SIZE(iwlegacy_eeprom_band_6); *eeprom_ch_info = (struct iwl_eeprom_channel *) iwl_legacy_eeprom_query_addr(priv, offset); - *eeprom_ch_index = iwl_eeprom_band_6; + *eeprom_ch_index = iwlegacy_eeprom_band_6; break; case 7: /* 5 GHz ht40 channels */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7); + *eeprom_ch_count = ARRAY_SIZE(iwlegacy_eeprom_band_7); *eeprom_ch_info = (struct iwl_eeprom_channel *) iwl_legacy_eeprom_query_addr(priv, offset); - *eeprom_ch_index = iwl_eeprom_band_7; + *eeprom_ch_index = iwlegacy_eeprom_band_7; break; default: BUG(); @@ -388,11 +388,11 @@ int iwl_legacy_init_channel_map(struct iwl_priv *priv) IWL_DEBUG_EEPROM(priv, "Initializing regulatory info from EEPROM\n"); priv->channel_count = - ARRAY_SIZE(iwl_eeprom_band_1) + - ARRAY_SIZE(iwl_eeprom_band_2) + - ARRAY_SIZE(iwl_eeprom_band_3) + - ARRAY_SIZE(iwl_eeprom_band_4) + - ARRAY_SIZE(iwl_eeprom_band_5); + ARRAY_SIZE(iwlegacy_eeprom_band_1) + + ARRAY_SIZE(iwlegacy_eeprom_band_2) + + ARRAY_SIZE(iwlegacy_eeprom_band_3) + + ARRAY_SIZE(iwlegacy_eeprom_band_4) + + ARRAY_SIZE(iwlegacy_eeprom_band_5); IWL_DEBUG_EEPROM(priv, "Parsing data for %d channels.\n", priv->channel_count); diff --git a/drivers/net/wireless/iwlegacy/iwl-eeprom.h b/drivers/net/wireless/iwlegacy/iwl-eeprom.h index 0744f8da63b4..c59c81002022 100644 --- a/drivers/net/wireless/iwlegacy/iwl-eeprom.h +++ b/drivers/net/wireless/iwlegacy/iwl-eeprom.h @@ -144,7 +144,7 @@ struct iwl_eeprom_channel { #define EEPROM_4965_BOARD_PBA (2*0x56+1) /* 9 bytes */ /* 2.4 GHz */ -extern const u8 iwl_eeprom_band_1[14]; +extern const u8 iwlegacy_eeprom_band_1[14]; /* * factory calibration data for one txpower level, on one channel, diff --git a/drivers/net/wireless/iwlegacy/iwl-legacy-rs.h b/drivers/net/wireless/iwlegacy/iwl-legacy-rs.h index f66a1b2c0397..38647e481eb0 100644 --- a/drivers/net/wireless/iwlegacy/iwl-legacy-rs.h +++ b/drivers/net/wireless/iwlegacy/iwl-legacy-rs.h @@ -56,7 +56,7 @@ struct iwl3945_rate_info { /* * These serve as indexes into - * struct iwl_rate_info iwl_rates[IWL_RATE_COUNT]; + * struct iwl_rate_info iwlegacy_rates[IWL_RATE_COUNT]; */ enum { IWL_RATE_1M_INDEX = 0, @@ -268,7 +268,7 @@ enum { #define TID_MAX_TIME_DIFF ((TID_QUEUE_MAX_SIZE - 1) * TID_QUEUE_CELL_SPACING) #define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y)) -extern const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT]; +extern const struct iwl_rate_info iwlegacy_rates[IWL_RATE_COUNT]; enum iwl_table_type { LQ_NONE, diff --git a/drivers/net/wireless/iwlegacy/iwl-scan.c b/drivers/net/wireless/iwlegacy/iwl-scan.c index 842f0b46b6df..60f597f796ca 100644 --- a/drivers/net/wireless/iwlegacy/iwl-scan.c +++ b/drivers/net/wireless/iwlegacy/iwl-scan.c @@ -492,9 +492,9 @@ iwl_legacy_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, return 0; frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); - memcpy(frame->da, iwl_bcast_addr, ETH_ALEN); + memcpy(frame->da, iwlegacy_bcast_addr, ETH_ALEN); memcpy(frame->sa, ta, ETH_ALEN); - memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN); + memcpy(frame->bssid, iwlegacy_bcast_addr, ETH_ALEN); frame->seq_ctrl = 0; len += 24; diff --git a/drivers/net/wireless/iwlegacy/iwl3945-base.c b/drivers/net/wireless/iwlegacy/iwl3945-base.c index a6af9817efce..ab87e1b73529 100644 --- a/drivers/net/wireless/iwlegacy/iwl3945-base.c +++ b/drivers/net/wireless/iwlegacy/iwl3945-base.c @@ -2630,7 +2630,7 @@ static int iwl3945_alloc_bcast_station(struct iwl_priv *priv) spin_lock_irqsave(&priv->sta_lock, flags); sta_id = iwl_legacy_prep_station(priv, ctx, - iwl_bcast_addr, false, NULL); + iwlegacy_bcast_addr, false, NULL); if (sta_id == IWL_INVALID_STATION) { IWL_ERR(priv, "Unable to prepare broadcast station\n"); spin_unlock_irqrestore(&priv->sta_lock, flags); @@ -2929,7 +2929,7 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->tx_cmd.len = cpu_to_le16( iwl_legacy_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, - iwl_bcast_addr, NULL, 0, + iwlegacy_bcast_addr, NULL, 0, IWL_MAX_SCAN_SIZE - sizeof(*scan))); } /* select Rx antennas */ @@ -4283,7 +4283,7 @@ module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0) (deprecated)"); #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG -module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR); +module_param_named(debug, iwlegacy_debug_level, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "debug output mask"); #endif module_param_named(fw_restart, iwl3945_mod_params.restart_fw, int, S_IRUGO); diff --git a/drivers/net/wireless/iwlegacy/iwl4965-base.c b/drivers/net/wireless/iwlegacy/iwl4965-base.c index 4d53d0ff5fc7..91b3d8b9d7a5 100644 --- a/drivers/net/wireless/iwlegacy/iwl4965-base.c +++ b/drivers/net/wireless/iwlegacy/iwl4965-base.c @@ -3057,7 +3057,7 @@ static void iwl4965_init_hw_rates(struct iwl_priv *priv, int i; for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) { - rates[i].bitrate = iwl_rates[i].ieee * 5; + rates[i].bitrate = iwlegacy_rates[i].ieee * 5; rates[i].hw_value = i; /* Rate scaling will work on indexes */ rates[i].hw_value_short = i; rates[i].flags = 0; @@ -3066,7 +3066,7 @@ static void iwl4965_init_hw_rates(struct iwl_priv *priv, * If CCK != 1M then set short preamble rate flag. */ rates[i].flags |= - (iwl_rates[i].plcp == IWL_RATE_1M_PLCP) ? + (iwlegacy_rates[i].plcp == IWL_RATE_1M_PLCP) ? 0 : IEEE80211_RATE_SHORT_PREAMBLE; } } @@ -3615,7 +3615,7 @@ module_exit(iwl4965_exit); module_init(iwl4965_init); #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG -module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR); +module_param_named(debug, iwlegacy_debug_level, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "debug output mask"); #endif -- cgit v1.2.3 From 189b5d559c49b6ba422a9e2e8d676b6f30f5d898 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 25 Feb 2011 14:32:26 -0800 Subject: Staging: samsung-laptop: fix header address for N128 When doing the conversion to the "support more than one model" the header address of the N128 was incorrectly copied. This fixes the driver to work properly now on this laptop model. Cc: Ingmar Steen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index 17e2c9e943d4..5a2899e23b9f 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -115,7 +115,7 @@ static struct sabi_config sabi_configs[] = { { .test_string = "SECLINUX", - .main_function = 0x4c59, + .main_function = 0x4c49, .header_offsets = { .port = 0x00, -- cgit v1.2.3 From 00bfe272bb7f26511919da1b44fa5d21e67bab15 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 25 Feb 2011 14:41:06 -0800 Subject: staging: samsung-laptop: address review comments Fixed up the printk stuff to use pr_XXX where applicable, and reversed the logic when testing for commands to complete properly. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 68 ++++++++++++------------- 1 file changed, 33 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index 5a2899e23b9f..a8e82b8eb5d7 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -1,14 +1,16 @@ /* * Samsung Laptop driver * - * Copyright (C) 2009 Greg Kroah-Hartman (gregkh@suse.de) - * Copyright (C) 2009 Novell Inc. + * Copyright (C) 2009,2011 Greg Kroah-Hartman (gregkh@suse.de) + * Copyright (C) 2009,2011 Novell Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -232,6 +234,7 @@ static int sabi_get_command(u8 command, struct sabi_retval *sretval) { int retval = 0; u16 port = readw(sabi + sabi_config->header_offsets.port); + u8 complete, iface_data; mutex_lock(&sabi_mutex); @@ -248,27 +251,25 @@ static int sabi_get_command(u8 command, struct sabi_retval *sretval) outb(readb(sabi + sabi_config->header_offsets.re_mem), port); /* see if the command actually succeeded */ - if (readb(sabi_iface + SABI_IFACE_COMPLETE) == 0xaa && - readb(sabi_iface + SABI_IFACE_DATA) != 0xff) { - /* - * It did! - * Save off the data into a structure so the caller use it. - * Right now we only care about the first 4 bytes, - * I suppose there are commands that need more, but I don't - * know about them. - */ - sretval->retval[0] = readb(sabi_iface + SABI_IFACE_DATA); - sretval->retval[1] = readb(sabi_iface + SABI_IFACE_DATA + 1); - sretval->retval[2] = readb(sabi_iface + SABI_IFACE_DATA + 2); - sretval->retval[3] = readb(sabi_iface + SABI_IFACE_DATA + 3); + complete = readb(sabi_iface + SABI_IFACE_COMPLETE); + iface_data = readb(sabi_iface + SABI_IFACE_DATA); + if (complete != 0xaa || iface_data == 0xff) { + pr_warn("SABI get command 0x%02x failed with completion flag 0x%02x and data 0x%02x\n", + command, complete, iface_data); + retval = -EINVAL; goto exit; } + /* + * Save off the data into a structure so the caller use it. + * Right now we only want the first 4 bytes, + * There are commands that need more, but not for the ones we + * currently care about. + */ + sretval->retval[0] = readb(sabi_iface + SABI_IFACE_DATA); + sretval->retval[1] = readb(sabi_iface + SABI_IFACE_DATA + 1); + sretval->retval[2] = readb(sabi_iface + SABI_IFACE_DATA + 2); + sretval->retval[3] = readb(sabi_iface + SABI_IFACE_DATA + 3); - /* Something bad happened, so report it and error out */ - printk(KERN_WARNING "SABI command 0x%02x failed with completion flag 0x%02x and output 0x%02x\n", - command, readb(sabi_iface + SABI_IFACE_COMPLETE), - readb(sabi_iface + SABI_IFACE_DATA)); - retval = -EINVAL; exit: mutex_unlock(&sabi_mutex); return retval; @@ -279,6 +280,7 @@ static int sabi_set_command(u8 command, u8 data) { int retval = 0; u16 port = readw(sabi + sabi_config->header_offsets.port); + u8 complete, iface_data; mutex_lock(&sabi_mutex); @@ -296,18 +298,14 @@ static int sabi_set_command(u8 command, u8 data) outb(readb(sabi + sabi_config->header_offsets.re_mem), port); /* see if the command actually succeeded */ - if (readb(sabi_iface + SABI_IFACE_COMPLETE) == 0xaa && - readb(sabi_iface + SABI_IFACE_DATA) != 0xff) { - /* it did! */ - goto exit; + complete = readb(sabi_iface + SABI_IFACE_COMPLETE); + iface_data = readb(sabi_iface + SABI_IFACE_DATA); + if (complete != 0xaa || iface_data == 0xff) { + pr_warn("SABI set command 0x%02x failed with completion flag 0x%02x and data 0x%02x\n", + command, complete, iface_data); + retval = -EINVAL; } - /* Something bad happened, so report it and error out */ - printk(KERN_WARNING "SABI command 0x%02x failed with completion flag 0x%02x and output 0x%02x\n", - command, readb(sabi_iface + SABI_IFACE_COMPLETE), - readb(sabi_iface + SABI_IFACE_DATA)); - retval = -EINVAL; -exit: mutex_unlock(&sabi_mutex); return retval; } @@ -488,7 +486,7 @@ static DEVICE_ATTR(performance_level, S_IWUSR | S_IRUGO, static int __init dmi_check_cb(const struct dmi_system_id *id) { - printk(KERN_INFO KBUILD_MODNAME ": found laptop model '%s'\n", + pr_info("found laptop model '%s'\n", id->ident); return 0; } @@ -670,7 +668,7 @@ static int __init samsung_init(void) f0000_segment = ioremap(0xf0000, 0xffff); if (!f0000_segment) { - printk(KERN_ERR "Can't map the segment at 0xf0000\n"); + pr_err("Can't map the segment at 0xf0000\n"); return -EINVAL; } @@ -683,7 +681,7 @@ static int __init samsung_init(void) } if (loca == 0xffff) { - printk(KERN_ERR "This computer does not support SABI\n"); + pr_err("This computer does not support SABI\n"); goto error_no_signature; } @@ -714,7 +712,7 @@ static int __init samsung_init(void) ifaceP += readw(sabi + sabi_config->header_offsets.data_offset) & 0x0ffff; sabi_iface = ioremap(ifaceP, 16); if (!sabi_iface) { - printk(KERN_ERR "Can't remap %x\n", ifaceP); + pr_err("Can't remap %x\n", ifaceP); goto exit; } if (debug) { @@ -734,7 +732,7 @@ static int __init samsung_init(void) retval = sabi_set_command(sabi_config->commands.set_linux, 0x81); if (retval) { - printk(KERN_ERR KBUILD_MODNAME ": Linux mode was not set!\n"); + pr_warn("Linux mode was not set!\n"); goto error_no_platform; } } -- cgit v1.2.3 From d73fa4b914eab332d9919132b273b6797b8aface Mon Sep 17 00:00:00 2001 From: "Matti J. Aaltonen" Date: Fri, 25 Feb 2011 14:44:18 -0800 Subject: drivers/nfc/Kconfig: use full form of the NFC acronym Spell out the NFC acronym when it's shown for the first time. Signed-off-by: Matti J. Aaltonen Acked-by: Wolfram Sang Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/nfc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig index ffedfd492754..ea1580085347 100644 --- a/drivers/nfc/Kconfig +++ b/drivers/nfc/Kconfig @@ -3,7 +3,7 @@ # menuconfig NFC_DEVICES - bool "NFC devices" + bool "Near Field Communication (NFC) devices" default n ---help--- You'll have to say Y if your computer contains an NFC device that -- cgit v1.2.3 From ac3c8304190ed0daaa2fb01ce2a069be5e2a52a7 Mon Sep 17 00:00:00 2001 From: "Matti J. Aaltonen" Date: Fri, 25 Feb 2011 14:44:19 -0800 Subject: drivers/nfc/pn544.c: add missing regulator The regulator framework is used for power management. The regulators are only named in the driver code, the actual control stuff is in the board file for each architecture or use case. The PN544 chip has three regulators that can be controlled or not - depending on the architecture where the chip is being used. So some of the regulators may not be controllable. In our current case the third regulator, which was missing from the code, went unnoticed because we didn't need to control it. To be as general as possible - in this respect - the driver needs to list all regulators. Then the board file can be used to actually set the usage. Signed-off-by: Matti J. Aaltonen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/nfc/pn544.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/nfc/pn544.c b/drivers/nfc/pn544.c index bae647264dd6..724f65d8f9e4 100644 --- a/drivers/nfc/pn544.c +++ b/drivers/nfc/pn544.c @@ -60,7 +60,7 @@ enum pn544_irq { struct pn544_info { struct miscdevice miscdev; struct i2c_client *i2c_dev; - struct regulator_bulk_data regs[2]; + struct regulator_bulk_data regs[3]; enum pn544_state state; wait_queue_head_t read_wait; @@ -74,6 +74,7 @@ struct pn544_info { static const char reg_vdd_io[] = "Vdd_IO"; static const char reg_vbat[] = "VBat"; +static const char reg_vsim[] = "VSim"; /* sysfs interface */ static ssize_t pn544_test(struct device *dev, @@ -740,6 +741,7 @@ static int __devinit pn544_probe(struct i2c_client *client, info->regs[0].supply = reg_vdd_io; info->regs[1].supply = reg_vbat; + info->regs[2].supply = reg_vsim; r = regulator_bulk_get(&client->dev, ARRAY_SIZE(info->regs), info->regs); if (r < 0) -- cgit v1.2.3 From a2d6d2fa90c0e1d2cc1d59ccb5bbe93bb28b7413 Mon Sep 17 00:00:00 2001 From: Lei Xu Date: Fri, 25 Feb 2011 14:44:23 -0800 Subject: drivers/rtc/rtc-ds3232.c: fix time range difference between linux and RTC chip In linux rtc_time struct, tm_mon range is 0~11, tm_wday range is 0~6, while in RTC HW REG, month range is 1~12, day of the week range is 1~7, this patch adjusts difference of them. The efect of this bug was that most of month will be operated on as the next month by the hardware (When in Jan it maybe even worse). For example, if in May, software wrote 4 to the hardware, which handled it as April. Then the logic would be different between software and hardware, which would cause weird things to happen. Signed-off-by: Lei Xu Cc: Alessandro Zummo Cc: john stultz Cc: Jack Lan Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds3232.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index 23a9ee19764c..950735415a7c 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c @@ -1,7 +1,7 @@ /* * RTC client/driver for the Maxim/Dallas DS3232 Real-Time Clock over I2C * - * Copyright (C) 2009-2010 Freescale Semiconductor. + * Copyright (C) 2009-2011 Freescale Semiconductor. * Author: Jack Lan * * This program is free software; you can redistribute it and/or modify it @@ -141,9 +141,11 @@ static int ds3232_read_time(struct device *dev, struct rtc_time *time) time->tm_hour = bcd2bin(hour); } - time->tm_wday = bcd2bin(week); + /* Day of the week in linux range is 0~6 while 1~7 in RTC chip */ + time->tm_wday = bcd2bin(week) - 1; time->tm_mday = bcd2bin(day); - time->tm_mon = bcd2bin(month & 0x7F); + /* linux tm_mon range:0~11, while month range is 1~12 in RTC chip */ + time->tm_mon = bcd2bin(month & 0x7F) - 1; if (century) add_century = 100; @@ -162,9 +164,11 @@ static int ds3232_set_time(struct device *dev, struct rtc_time *time) buf[0] = bin2bcd(time->tm_sec); buf[1] = bin2bcd(time->tm_min); buf[2] = bin2bcd(time->tm_hour); - buf[3] = bin2bcd(time->tm_wday); /* Day of the week */ + /* Day of the week in linux range is 0~6 while 1~7 in RTC chip */ + buf[3] = bin2bcd(time->tm_wday + 1); buf[4] = bin2bcd(time->tm_mday); /* Date */ - buf[5] = bin2bcd(time->tm_mon); + /* linux tm_mon range:0~11, while month range is 1~12 in RTC chip */ + buf[5] = bin2bcd(time->tm_mon + 1); if (time->tm_year >= 100) { buf[5] |= 0x80; buf[6] = bin2bcd(time->tm_year - 100); -- cgit v1.2.3 From 99b0d365e5ade293c5fa25a9f1a49ac764656670 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Fri, 25 Feb 2011 14:44:30 -0800 Subject: pps: initialize ts_real properly Initialize ts_real.flags to fix compiler warning about possible uninitialized use of this field. Signed-off-by: Alexander Gordeev Cc: john stultz Cc: Rodolfo Giometti Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pps/kapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pps/kapi.c b/drivers/pps/kapi.c index cba1b43f7519..a4e8eb9fece6 100644 --- a/drivers/pps/kapi.c +++ b/drivers/pps/kapi.c @@ -168,7 +168,7 @@ void pps_event(struct pps_device *pps, struct pps_event_time *ts, int event, { unsigned long flags; int captured = 0; - struct pps_ktime ts_real; + struct pps_ktime ts_real = { .sec = 0, .nsec = 0, .flags = 0 }; /* check event type */ BUG_ON((event & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR)) == 0); -- cgit v1.2.3 From fe41947e1aa12e96a50edaee123b4e4de03b668b Mon Sep 17 00:00:00 2001 From: Alexandre Bounine Date: Fri, 25 Feb 2011 14:44:31 -0800 Subject: rapidio: fix sysfs config attribute to access 16MB of maint space Fixes sysfs config attribute to allow access to entire 16MB maintenance space of RapidIO devices. Signed-off-by: Alexandre Bounine Cc: Kumar Gala Cc: Matt Porter Cc: Li Yang Cc: Thomas Moll Cc: Micha Nelissen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rapidio/rio-sysfs.c | 12 ++++++------ include/linux/rio_regs.h | 4 +++- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c index 76b41853a877..1269fbd2deca 100644 --- a/drivers/rapidio/rio-sysfs.c +++ b/drivers/rapidio/rio-sysfs.c @@ -77,9 +77,9 @@ rio_read_config(struct file *filp, struct kobject *kobj, /* Several chips lock up trying to read undefined config space */ if (capable(CAP_SYS_ADMIN)) - size = 0x200000; + size = RIO_MAINT_SPACE_SZ; - if (off > size) + if (off >= size) return 0; if (off + count > size) { size -= off; @@ -147,10 +147,10 @@ rio_write_config(struct file *filp, struct kobject *kobj, loff_t init_off = off; u8 *data = (u8 *) buf; - if (off > 0x200000) + if (off >= RIO_MAINT_SPACE_SZ) return 0; - if (off + count > 0x200000) { - size = 0x200000 - off; + if (off + count > RIO_MAINT_SPACE_SZ) { + size = RIO_MAINT_SPACE_SZ - off; count = size; } @@ -200,7 +200,7 @@ static struct bin_attribute rio_config_attr = { .name = "config", .mode = S_IRUGO | S_IWUSR, }, - .size = 0x200000, + .size = RIO_MAINT_SPACE_SZ, .read = rio_read_config, .write = rio_write_config, }; diff --git a/include/linux/rio_regs.h b/include/linux/rio_regs.h index d63dcbaea169..9026b30238f3 100644 --- a/include/linux/rio_regs.h +++ b/include/linux/rio_regs.h @@ -14,10 +14,12 @@ #define LINUX_RIO_REGS_H /* - * In RapidIO, each device has a 2MB configuration space that is + * In RapidIO, each device has a 16MB configuration space that is * accessed via maintenance transactions. Portions of configuration * space are standardized and/or reserved. */ +#define RIO_MAINT_SPACE_SZ 0x1000000 /* 16MB of RapidIO mainenance space */ + #define RIO_DEV_ID_CAR 0x00 /* [I] Device Identity CAR */ #define RIO_DEV_INFO_CAR 0x04 /* [I] Device Information CAR */ #define RIO_ASM_ID_CAR 0x08 /* [I] Assembly Identity CAR */ -- cgit v1.2.3 From 66245ad025e02fe9e727c03d43308bb24e346bb6 Mon Sep 17 00:00:00 2001 From: Mike Waychison Date: Fri, 25 Feb 2011 15:41:49 -0800 Subject: firmware: Fix unaligned memory accesses in dmi-sysfs DMI entries are arranged in memory back to back with no alignment guarantees. This means that the struct dmi_header passed to callbacks from dmi_walk() itself isn't byte aligned. This causes problems on architectures that expect aligned data, such as IA64. The dmi-sysfs patchset introduced structure member accesses through this passed in dmi_header. Fix this by memcpy()ing the structures to temporary locations on stack when inspecting/copying them. Signed-off-by: Mike Waychison Tested-by: Tony Luck Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/dmi-sysfs.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/dmi-sysfs.c b/drivers/firmware/dmi-sysfs.c index a5afd805e66f..eb26d62e5188 100644 --- a/drivers/firmware/dmi-sysfs.c +++ b/drivers/firmware/dmi-sysfs.c @@ -263,20 +263,16 @@ struct dmi_system_event_log { u8 supported_log_type_descriptos[0]; } __packed; -static const struct dmi_system_event_log *to_sel(const struct dmi_header *dh) -{ - return (const struct dmi_system_event_log *)dh; -} - #define DMI_SYSFS_SEL_FIELD(_field) \ static ssize_t dmi_sysfs_sel_##_field(struct dmi_sysfs_entry *entry, \ const struct dmi_header *dh, \ char *buf) \ { \ - const struct dmi_system_event_log *sel = to_sel(dh); \ - if (sizeof(*sel) > dmi_entry_length(dh)) \ + struct dmi_system_event_log sel; \ + if (sizeof(sel) > dmi_entry_length(dh)) \ return -EIO; \ - return sprintf(buf, "%u\n", sel->_field); \ + memcpy(&sel, dh, sizeof(sel)); \ + return sprintf(buf, "%u\n", sel._field); \ } \ static DMI_SYSFS_MAPPED_ATTR(sel, _field) @@ -403,26 +399,28 @@ static ssize_t dmi_sel_raw_read_helper(struct dmi_sysfs_entry *entry, void *_state) { struct dmi_read_state *state = _state; - const struct dmi_system_event_log *sel = to_sel(dh); + struct dmi_system_event_log sel; - if (sizeof(*sel) > dmi_entry_length(dh)) + if (sizeof(sel) > dmi_entry_length(dh)) return -EIO; - switch (sel->access_method) { + memcpy(&sel, dh, sizeof(sel)); + + switch (sel.access_method) { case DMI_SEL_ACCESS_METHOD_IO8: case DMI_SEL_ACCESS_METHOD_IO2x8: case DMI_SEL_ACCESS_METHOD_IO16: - return dmi_sel_raw_read_io(entry, sel, state->buf, + return dmi_sel_raw_read_io(entry, &sel, state->buf, state->pos, state->count); case DMI_SEL_ACCESS_METHOD_PHYS32: - return dmi_sel_raw_read_phys32(entry, sel, state->buf, + return dmi_sel_raw_read_phys32(entry, &sel, state->buf, state->pos, state->count); case DMI_SEL_ACCESS_METHOD_GPNV: pr_info("dmi-sysfs: GPNV support missing.\n"); return -EIO; default: pr_info("dmi-sysfs: Unknown access method %02x\n", - sel->access_method); + sel.access_method); return -EIO; } } @@ -595,7 +593,7 @@ static void __init dmi_sysfs_register_handle(const struct dmi_header *dh, } /* Set the key */ - entry->dh = *dh; + memcpy(&entry->dh, dh, sizeof(*dh)); entry->instance = instance_counts[dh->type]++; entry->position = position_count++; -- cgit v1.2.3 From 6407deb59466372fd7addca38fa2f44898591897 Mon Sep 17 00:00:00 2001 From: axel lin Date: Thu, 24 Feb 2011 02:20:37 +0000 Subject: hwmon: (ad7414) add MODULE_DEVICE_TABLE The device table is required to load modules based on modaliases. Signed-off-by: Axel Lin Signed-off-by: Guenter Roeck --- drivers/hwmon/ad7414.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/hwmon/ad7414.c b/drivers/hwmon/ad7414.c index 86d822aa9bbf..d46c0c758ddf 100644 --- a/drivers/hwmon/ad7414.c +++ b/drivers/hwmon/ad7414.c @@ -242,6 +242,7 @@ static const struct i2c_device_id ad7414_id[] = { { "ad7414", 0 }, {} }; +MODULE_DEVICE_TABLE(i2c, ad7414_id); static struct i2c_driver ad7414_driver = { .driver = { -- cgit v1.2.3 From a7254d68b61c7873ce20591f0c56bf0245b72a76 Mon Sep 17 00:00:00 2001 From: axel lin Date: Thu, 24 Feb 2011 02:22:01 +0000 Subject: hwmon: (adt7411) add MODULE_DEVICE_TABLE The device table is required to load modules based on modaliases. Signed-off-by: Axel Lin Acked-by: Wolfram Sang Signed-off-by: Guenter Roeck --- drivers/hwmon/adt7411.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/hwmon/adt7411.c b/drivers/hwmon/adt7411.c index f13c843a2964..5cc3e3784b42 100644 --- a/drivers/hwmon/adt7411.c +++ b/drivers/hwmon/adt7411.c @@ -334,6 +334,7 @@ static const struct i2c_device_id adt7411_id[] = { { "adt7411", 0 }, { } }; +MODULE_DEVICE_TABLE(i2c, adt7411_id); static struct i2c_driver adt7411_driver = { .driver = { -- cgit v1.2.3 From 5596026081198f8012b52e0f589530f2bb6f9b40 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 18 Feb 2011 17:23:50 -0800 Subject: iwlagn: name change for BT config command No functional changes, name changes to reflect the structure used by 6000 series. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +- drivers/net/wireless/iwlwifi/iwl-commands.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 0d0572ca7e77..8c70f0be6b77 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1804,7 +1804,7 @@ static const __le32 iwlagn_concurrent_lookup[12] = { void iwlagn_send_advance_bt_config(struct iwl_priv *priv) { - struct iwlagn_bt_cmd bt_cmd = { + struct iwl6000_bt_cmd bt_cmd = { .max_kill = IWLAGN_BT_MAX_KILL_DEFAULT, .bt3_timer_t7_value = IWLAGN_BT3_T7_DEFAULT, .bt3_prio_sample_time = IWLAGN_BT3_PRIO_SAMPLE_DEFAULT, diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 0a1d4aeb36aa..58919f883f02 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2477,7 +2477,7 @@ struct iwl_bt_cmd { IWLAGN_BT_VALID_BT4_TIMES | \ IWLAGN_BT_VALID_3W_LUT) -struct iwlagn_bt_cmd { +struct iwl6000_bt_cmd { u8 flags; u8 ledtime; /* unused */ u8 max_kill; -- cgit v1.2.3 From d6f626553d13e66b36a1ea2dbf23a5c21277a004 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 18 Feb 2011 17:23:51 -0800 Subject: iwlagn: add bt config structure support for 2000 series 2000 series has different bt config command structure, add support for it Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-commands.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 58919f883f02..b32b143458be 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2499,6 +2499,29 @@ struct iwl6000_bt_cmd { __le16 rx_prio_boost; /* SW boost of WiFi rx priority */ }; +struct iwl2000_bt_cmd { + u8 flags; + u8 ledtime; /* unused */ + u8 max_kill; + u8 bt3_timer_t7_value; + __le32 kill_ack_mask; + __le32 kill_cts_mask; + u8 bt3_prio_sample_time; + u8 bt3_timer_t2_value; + __le16 bt4_reaction_time; /* unused */ + __le32 bt3_lookup_table[12]; + __le16 bt4_decision_time; /* unused */ + __le16 valid; + __le32 prio_boost; + /* + * set IWLAGN_BT_VALID_BOOST to "1" in "valid" bitmask + * if configure the following patterns + */ + u8 reserved; + u8 tx_prio_boost; /* SW boost of WiFi tx priority */ + __le16 rx_prio_boost; /* SW boost of WiFi rx priority */ +}; + #define IWLAGN_BT_SCO_ACTIVE cpu_to_le32(BIT(0)) struct iwlagn_bt_sco_cmd { -- cgit v1.2.3 From d7220f0d4f7a7e84470916a3da8113a51f480514 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 18 Feb 2011 17:23:52 -0800 Subject: iwlagn: add BT Session Activity 2 UART message (BT -> WiFi) additional UART message defines Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-commands.h | 78 +++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index b32b143458be..df6abbf0b9d3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -4173,6 +4173,7 @@ enum iwl_bt_coex_profile_traffic_load { */ }; +/* BT UART message - Share Part (BT -> WiFi) */ #define BT_UART_MSG_FRAME1MSGTYPE_POS (0) #define BT_UART_MSG_FRAME1MSGTYPE_MSK \ (0x7 << BT_UART_MSG_FRAME1MSGTYPE_POS) @@ -4267,6 +4268,83 @@ enum iwl_bt_coex_profile_traffic_load { #define BT_UART_MSG_FRAME7RESERVED_MSK \ (0x3 << BT_UART_MSG_FRAME7RESERVED_POS) +/* BT Session Activity 2 UART message (BT -> WiFi) */ +#define BT_UART_MSG_2_FRAME1RESERVED1_POS (5) +#define BT_UART_MSG_2_FRAME1RESERVED1_MSK \ + (0x1< Date: Tue, 22 Feb 2011 08:24:22 -0800 Subject: iwlagn: split BT page and inquiry UART msg Both inquiry and page was combine in frame7 of UART message, separate it Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 10 ++++++---- drivers/net/wireless/iwlwifi/iwl-commands.h | 9 ++++++--- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 8c70f0be6b77..dc7055eee2d8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1984,12 +1984,14 @@ static void iwlagn_print_uartmsg(struct iwl_priv *priv, (BT_UART_MSG_FRAME6DISCOVERABLE_MSK & uart_msg->frame6) >> BT_UART_MSG_FRAME6DISCOVERABLE_POS); - IWL_DEBUG_NOTIF(priv, "Sniff Activity = 0x%X, Inquiry/Page SR Mode = " - "0x%X, Connectable = 0x%X", + IWL_DEBUG_NOTIF(priv, "Sniff Activity = 0x%X, Page = " + "0x%X, Inquiry = 0x%X, Connectable = 0x%X", (BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK & uart_msg->frame7) >> BT_UART_MSG_FRAME7SNIFFACTIVITY_POS, - (BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_MSK & uart_msg->frame7) >> - BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS, + (BT_UART_MSG_FRAME7PAGE_MSK & uart_msg->frame7) >> + BT_UART_MSG_FRAME7PAGE_POS, + (BT_UART_MSG_FRAME7INQUIRY_MSK & uart_msg->frame7) >> + BT_UART_MSG_FRAME7INQUIRY_POS, (BT_UART_MSG_FRAME7CONNECTABLE_MSK & uart_msg->frame7) >> BT_UART_MSG_FRAME7CONNECTABLE_POS); } diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index df6abbf0b9d3..3629ee351478 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -4258,9 +4258,12 @@ enum iwl_bt_coex_profile_traffic_load { #define BT_UART_MSG_FRAME7SNIFFACTIVITY_POS (0) #define BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK \ (0x7 << BT_UART_MSG_FRAME7SNIFFACTIVITY_POS) -#define BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS (3) -#define BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_MSK \ - (0x3 << BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS) +#define BT_UART_MSG_FRAME7PAGE_POS (3) +#define BT_UART_MSG_FRAME7PAGE_MSK \ + (0x1 << BT_UART_MSG_FRAME7PAGE_POS) +#define BT_UART_MSG_FRAME7INQUIRY_POS (4) +#define BT_UART_MSG_FRAME7INQUIRY_MSK \ + (0x1 << BT_UART_MSG_FRAME7INQUIRY_POS) #define BT_UART_MSG_FRAME7CONNECTABLE_POS (5) #define BT_UART_MSG_FRAME7CONNECTABLE_MSK \ (0x1 << BT_UART_MSG_FRAME7CONNECTABLE_POS) -- cgit v1.2.3 From 6013270a030e370400e459922176c467a6c19293 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 18 Feb 2011 17:23:54 -0800 Subject: iwlagn: enable BT session 2 type UART for 2000 series For 2000 series device, use session 2 type of BT UART message Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-2000.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 68 +++++++++++++++++++---------- drivers/net/wireless/iwlwifi/iwl-commands.h | 22 ++++------ drivers/net/wireless/iwlwifi/iwl-core.h | 1 + 4 files changed, 57 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 30483e27ce5c..335adedcee43 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -418,6 +418,7 @@ static struct iwl_bt_params iwl2030_bt_params = { .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, .bt_sco_disable = true, + .bt_session_2 = true, }; #define IWL_DEVICE_2000 \ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index dc7055eee2d8..8e192072df15 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1804,26 +1804,39 @@ static const __le32 iwlagn_concurrent_lookup[12] = { void iwlagn_send_advance_bt_config(struct iwl_priv *priv) { - struct iwl6000_bt_cmd bt_cmd = { + struct iwl_basic_bt_cmd basic = { .max_kill = IWLAGN_BT_MAX_KILL_DEFAULT, .bt3_timer_t7_value = IWLAGN_BT3_T7_DEFAULT, .bt3_prio_sample_time = IWLAGN_BT3_PRIO_SAMPLE_DEFAULT, .bt3_timer_t2_value = IWLAGN_BT3_T2_DEFAULT, }; + struct iwl6000_bt_cmd bt_cmd_6000; + struct iwl2000_bt_cmd bt_cmd_2000; + int ret; BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) != - sizeof(bt_cmd.bt3_lookup_table)); - - if (priv->cfg->bt_params) - bt_cmd.prio_boost = priv->cfg->bt_params->bt_prio_boost; - else - bt_cmd.prio_boost = 0; - bt_cmd.kill_ack_mask = priv->kill_ack_mask; - bt_cmd.kill_cts_mask = priv->kill_cts_mask; + sizeof(basic.bt3_lookup_table)); + + if (priv->cfg->bt_params) { + if (priv->cfg->bt_params->bt_session_2) { + bt_cmd_2000.prio_boost = cpu_to_le32( + priv->cfg->bt_params->bt_prio_boost); + bt_cmd_2000.tx_prio_boost = 0; + bt_cmd_2000.rx_prio_boost = 0; + } else { + bt_cmd_6000.prio_boost = + priv->cfg->bt_params->bt_prio_boost; + bt_cmd_6000.tx_prio_boost = 0; + bt_cmd_6000.rx_prio_boost = 0; + } + } else { + IWL_ERR(priv, "failed to construct BT Coex Config\n"); + return; + } - bt_cmd.valid = priv->bt_valid; - bt_cmd.tx_prio_boost = 0; - bt_cmd.rx_prio_boost = 0; + basic.kill_ack_mask = priv->kill_ack_mask; + basic.kill_cts_mask = priv->kill_cts_mask; + basic.valid = priv->bt_valid; /* * Configure BT coex mode to "no coexistence" when the @@ -1832,32 +1845,43 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) * IBSS mode (no proper uCode support for coex then). */ if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) { - bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_DISABLED; + basic.flags = IWLAGN_BT_FLAG_COEX_MODE_DISABLED; } else { - bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_3W << + basic.flags = IWLAGN_BT_FLAG_COEX_MODE_3W << IWLAGN_BT_FLAG_COEX_MODE_SHIFT; if (priv->cfg->bt_params && priv->cfg->bt_params->bt_sco_disable) - bt_cmd.flags |= IWLAGN_BT_FLAG_SYNC_2_BT_DISABLE; + basic.flags |= IWLAGN_BT_FLAG_SYNC_2_BT_DISABLE; if (priv->bt_ch_announce) - bt_cmd.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION; - IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", bt_cmd.flags); + basic.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION; + IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", basic.flags); } - priv->bt_enable_flag = bt_cmd.flags; + priv->bt_enable_flag = basic.flags; if (priv->bt_full_concurrent) - memcpy(bt_cmd.bt3_lookup_table, iwlagn_concurrent_lookup, + memcpy(basic.bt3_lookup_table, iwlagn_concurrent_lookup, sizeof(iwlagn_concurrent_lookup)); else - memcpy(bt_cmd.bt3_lookup_table, iwlagn_def_3w_lookup, + memcpy(basic.bt3_lookup_table, iwlagn_def_3w_lookup, sizeof(iwlagn_def_3w_lookup)); IWL_DEBUG_INFO(priv, "BT coex %s in %s mode\n", - bt_cmd.flags ? "active" : "disabled", + basic.flags ? "active" : "disabled", priv->bt_full_concurrent ? "full concurrency" : "3-wire"); - if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, sizeof(bt_cmd), &bt_cmd)) + if (priv->cfg->bt_params->bt_session_2) { + memcpy(&bt_cmd_2000.basic, &basic, + sizeof(basic)); + ret = iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, + sizeof(bt_cmd_2000), &bt_cmd_2000); + } else { + memcpy(&bt_cmd_6000.basic, &basic, + sizeof(basic)); + ret = iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, + sizeof(bt_cmd_6000), &bt_cmd_6000); + } + if (ret) IWL_ERR(priv, "failed to send BT Coex Config\n"); } diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 3629ee351478..03cfb74da2bc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2477,7 +2477,7 @@ struct iwl_bt_cmd { IWLAGN_BT_VALID_BT4_TIMES | \ IWLAGN_BT_VALID_3W_LUT) -struct iwl6000_bt_cmd { +struct iwl_basic_bt_cmd { u8 flags; u8 ledtime; /* unused */ u8 max_kill; @@ -2490,6 +2490,10 @@ struct iwl6000_bt_cmd { __le32 bt3_lookup_table[12]; __le16 bt4_decision_time; /* unused */ __le16 valid; +}; + +struct iwl6000_bt_cmd { + struct iwl_basic_bt_cmd basic; u8 prio_boost; /* * set IWLAGN_BT_VALID_BOOST to "1" in "valid" bitmask @@ -2500,18 +2504,7 @@ struct iwl6000_bt_cmd { }; struct iwl2000_bt_cmd { - u8 flags; - u8 ledtime; /* unused */ - u8 max_kill; - u8 bt3_timer_t7_value; - __le32 kill_ack_mask; - __le32 kill_cts_mask; - u8 bt3_prio_sample_time; - u8 bt3_timer_t2_value; - __le16 bt4_reaction_time; /* unused */ - __le32 bt3_lookup_table[12]; - __le16 bt4_decision_time; /* unused */ - __le16 valid; + struct iwl_basic_bt_cmd basic; __le32 prio_boost; /* * set IWLAGN_BT_VALID_BOOST to "1" in "valid" bitmask @@ -4173,6 +4166,9 @@ enum iwl_bt_coex_profile_traffic_load { */ }; +#define BT_SESSION_ACTIVITY_1_UART_MSG 0x1 +#define BT_SESSION_ACTIVITY_2_UART_MSG 0x2 + /* BT UART message - Share Part (BT -> WiFi) */ #define BT_UART_MSG_FRAME1MSGTYPE_POS (0) #define BT_UART_MSG_FRAME1MSGTYPE_MSK \ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index e0ec17079dc0..909b42d5d9c0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -339,6 +339,7 @@ struct iwl_bt_params { u8 ampdu_factor; u8 ampdu_density; bool bt_sco_disable; + bool bt_session_2; }; /* * @use_rts_for_aggregation: use rts/cts protection for HT traffic -- cgit v1.2.3 From 70919e23ac35c9c244dfd73f97312894cae7d65f Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Sat, 26 Feb 2011 22:41:36 -0800 Subject: qeth: remove needless IPA-commands in offline If a qeth device is set offline, data and control subchannels are cleared, which means removal of all IP Assist Primitive settings implicitly. There is no need to delete those settings explicitly. This patch removes all IP Assist invocations from offline. Signed-off-by: Ursula Braun Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 1 - drivers/s390/net/qeth_core_main.c | 52 +++++++++++------------------------- drivers/s390/net/qeth_l2_main.c | 45 ++++++++++---------------------- drivers/s390/net/qeth_l3_main.c | 55 +++------------------------------------ 4 files changed, 33 insertions(+), 120 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index f47a714538db..c5d763ed406e 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -741,7 +741,6 @@ struct qeth_card { /* QDIO buffer handling */ struct qeth_qdio_info qdio; struct qeth_perf_stats perf_stats; - int use_hard_stop; int read_or_write_problem; struct qeth_osn_info osn_info; struct qeth_discipline discipline; diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 019ae58ab913..f3d98ac16e9f 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -302,12 +302,15 @@ static void qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd, int rc, int com = cmd->hdr.command; ipa_name = qeth_get_ipa_cmd_name(com); if (rc) - QETH_DBF_MESSAGE(2, "IPA: %s(x%X) for %s returned x%X \"%s\"\n", - ipa_name, com, QETH_CARD_IFNAME(card), - rc, qeth_get_ipa_msg(rc)); + QETH_DBF_MESSAGE(2, "IPA: %s(x%X) for %s/%s returned " + "x%X \"%s\"\n", + ipa_name, com, dev_name(&card->gdev->dev), + QETH_CARD_IFNAME(card), rc, + qeth_get_ipa_msg(rc)); else - QETH_DBF_MESSAGE(5, "IPA: %s(x%X) for %s succeeded\n", - ipa_name, com, QETH_CARD_IFNAME(card)); + QETH_DBF_MESSAGE(5, "IPA: %s(x%X) for %s/%s succeeded\n", + ipa_name, com, dev_name(&card->gdev->dev), + QETH_CARD_IFNAME(card)); } static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card, @@ -1083,7 +1086,6 @@ static int qeth_setup_card(struct qeth_card *card) card->data.state = CH_STATE_DOWN; card->state = CARD_STATE_DOWN; card->lan_online = 0; - card->use_hard_stop = 0; card->read_or_write_problem = 0; card->dev = NULL; spin_lock_init(&card->vlanlock); @@ -1732,20 +1734,22 @@ int qeth_send_control_data(struct qeth_card *card, int len, }; } + if (reply->rc == -EIO) + goto error; rc = reply->rc; qeth_put_reply(reply); return rc; time_err: + reply->rc = -ETIME; spin_lock_irqsave(&reply->card->lock, flags); list_del_init(&reply->list); spin_unlock_irqrestore(&reply->card->lock, flags); - reply->rc = -ETIME; atomic_inc(&reply->received); +error: atomic_set(&card->write.irq_pending, 0); qeth_release_buffer(iob->channel, iob); card->write.buf_no = (card->write.buf_no + 1) % QETH_CMD_BUFFER_NO; - wake_up(&reply->wait_q); rc = reply->rc; qeth_put_reply(reply); return rc; @@ -2490,45 +2494,19 @@ int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, } EXPORT_SYMBOL_GPL(qeth_send_ipa_cmd); -static int qeth_send_startstoplan(struct qeth_card *card, - enum qeth_ipa_cmds ipacmd, enum qeth_prot_versions prot) -{ - int rc; - struct qeth_cmd_buffer *iob; - - iob = qeth_get_ipacmd_buffer(card, ipacmd, prot); - rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); - - return rc; -} - int qeth_send_startlan(struct qeth_card *card) { int rc; + struct qeth_cmd_buffer *iob; QETH_DBF_TEXT(SETUP, 2, "strtlan"); - rc = qeth_send_startstoplan(card, IPA_CMD_STARTLAN, 0); + iob = qeth_get_ipacmd_buffer(card, IPA_CMD_STARTLAN, 0); + rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); return rc; } EXPORT_SYMBOL_GPL(qeth_send_startlan); -int qeth_send_stoplan(struct qeth_card *card) -{ - int rc = 0; - - /* - * TODO: according to the IPA format document page 14, - * TCP/IP (we!) never issue a STOPLAN - * is this right ?!? - */ - QETH_DBF_TEXT(SETUP, 2, "stoplan"); - - rc = qeth_send_startstoplan(card, IPA_CMD_STOPLAN, 0); - return rc; -} -EXPORT_SYMBOL_GPL(qeth_send_stoplan); - int qeth_default_setadapterparms_cb(struct qeth_card *card, struct qeth_reply *reply, unsigned long data) { diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index ada0fe782373..6fbaacb21943 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -202,17 +202,19 @@ static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac, int vmac) kfree(mc); } -static void qeth_l2_del_all_mc(struct qeth_card *card) +static void qeth_l2_del_all_mc(struct qeth_card *card, int del) { struct qeth_mc_mac *mc, *tmp; spin_lock_bh(&card->mclock); list_for_each_entry_safe(mc, tmp, &card->mc_list, list) { - if (mc->is_vmac) - qeth_l2_send_setdelmac(card, mc->mc_addr, + if (del) { + if (mc->is_vmac) + qeth_l2_send_setdelmac(card, mc->mc_addr, IPA_CMD_DELVMAC, NULL); - else - qeth_l2_send_delgroupmac(card, mc->mc_addr); + else + qeth_l2_send_delgroupmac(card, mc->mc_addr); + } list_del(&mc->list); kfree(mc); } @@ -288,18 +290,13 @@ static int qeth_l2_send_setdelvlan(struct qeth_card *card, __u16 i, qeth_l2_send_setdelvlan_cb, NULL); } -static void qeth_l2_process_vlans(struct qeth_card *card, int clear) +static void qeth_l2_process_vlans(struct qeth_card *card) { struct qeth_vlan_vid *id; QETH_CARD_TEXT(card, 3, "L2prcvln"); spin_lock_bh(&card->vlanlock); list_for_each_entry(id, &card->vid_list, list) { - if (clear) - qeth_l2_send_setdelvlan(card, id->vid, - IPA_CMD_DELVLAN); - else - qeth_l2_send_setdelvlan(card, id->vid, - IPA_CMD_SETVLAN); + qeth_l2_send_setdelvlan(card, id->vid, IPA_CMD_SETVLAN); } spin_unlock_bh(&card->vlanlock); } @@ -379,19 +376,11 @@ static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode) dev_close(card->dev); rtnl_unlock(); } - if (!card->use_hard_stop || - recovery_mode) { - __u8 *mac = &card->dev->dev_addr[0]; - rc = qeth_l2_send_delmac(card, mac); - QETH_DBF_TEXT_(SETUP, 2, "Lerr%d", rc); - } + card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; card->state = CARD_STATE_SOFTSETUP; } if (card->state == CARD_STATE_SOFTSETUP) { - qeth_l2_process_vlans(card, 1); - if (!card->use_hard_stop || - recovery_mode) - qeth_l2_del_all_mc(card); + qeth_l2_del_all_mc(card, 0); qeth_clear_ipacmd_list(card); card->state = CARD_STATE_HARDSETUP; } @@ -405,7 +394,6 @@ static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode) qeth_clear_cmd_buffers(&card->read); qeth_clear_cmd_buffers(&card->write); } - card->use_hard_stop = 0; return rc; } @@ -705,7 +693,7 @@ static void qeth_l2_set_multicast_list(struct net_device *dev) if (qeth_threads_running(card, QETH_RECOVER_THREAD) && (card->state != CARD_STATE_UP)) return; - qeth_l2_del_all_mc(card); + qeth_l2_del_all_mc(card, 1); spin_lock_bh(&card->mclock); netdev_for_each_mc_addr(ha, dev) qeth_l2_add_mc(card, ha->addr, 0); @@ -907,10 +895,8 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev) qeth_set_allowed_threads(card, 0, 1); wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); - if (cgdev->state == CCWGROUP_ONLINE) { - card->use_hard_stop = 1; + if (cgdev->state == CCWGROUP_ONLINE) qeth_l2_set_offline(cgdev); - } if (card->dev) { unregister_netdev(card->dev); @@ -1040,7 +1026,7 @@ contin: if (card->info.type != QETH_CARD_TYPE_OSN && card->info.type != QETH_CARD_TYPE_OSM) - qeth_l2_process_vlans(card, 0); + qeth_l2_process_vlans(card); netif_tx_disable(card->dev); @@ -1076,7 +1062,6 @@ contin: return 0; out_remove: - card->use_hard_stop = 1; qeth_l2_stop_card(card, 0); ccw_device_set_offline(CARD_DDEV(card)); ccw_device_set_offline(CARD_WDEV(card)); @@ -1144,7 +1129,6 @@ static int qeth_l2_recover(void *ptr) QETH_CARD_TEXT(card, 2, "recover2"); dev_warn(&card->gdev->dev, "A recovery process has been started for the device\n"); - card->use_hard_stop = 1; __qeth_l2_set_offline(card->gdev, 1); rc = __qeth_l2_set_online(card->gdev, 1); if (!rc) @@ -1191,7 +1175,6 @@ static int qeth_l2_pm_suspend(struct ccwgroup_device *gdev) if (gdev->state == CCWGROUP_OFFLINE) return 0; if (card->state == CARD_STATE_UP) { - card->use_hard_stop = 1; __qeth_l2_set_offline(card->gdev, 1); } else __qeth_l2_set_offline(card->gdev, 0); diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index d09b0c44fc3d..6a9cc58321a0 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -510,8 +510,7 @@ static void qeth_l3_set_ip_addr_list(struct qeth_card *card) kfree(tbd_list); } -static void qeth_l3_clear_ip_list(struct qeth_card *card, int clean, - int recover) +static void qeth_l3_clear_ip_list(struct qeth_card *card, int recover) { struct qeth_ipaddr *addr, *tmp; unsigned long flags; @@ -530,11 +529,6 @@ static void qeth_l3_clear_ip_list(struct qeth_card *card, int clean, addr = list_entry(card->ip_list.next, struct qeth_ipaddr, entry); list_del_init(&addr->entry); - if (clean) { - spin_unlock_irqrestore(&card->ip_lock, flags); - qeth_l3_deregister_addr_entry(card, addr); - spin_lock_irqsave(&card->ip_lock, flags); - } if (!recover || addr->is_multicast) { kfree(addr); continue; @@ -1611,29 +1605,6 @@ static int qeth_l3_start_ipassists(struct qeth_card *card) return 0; } -static int qeth_l3_put_unique_id(struct qeth_card *card) -{ - - int rc = 0; - struct qeth_cmd_buffer *iob; - struct qeth_ipa_cmd *cmd; - - QETH_CARD_TEXT(card, 2, "puniqeid"); - - if ((card->info.unique_id & UNIQUE_ID_NOT_BY_CARD) == - UNIQUE_ID_NOT_BY_CARD) - return -1; - iob = qeth_get_ipacmd_buffer(card, IPA_CMD_DESTROY_ADDR, - QETH_PROT_IPV6); - cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); - *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) = - card->info.unique_id; - memcpy(&cmd->data.create_destroy_addr.unique_id[0], - card->dev->dev_addr, OSA_ADDR_LEN); - rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); - return rc; -} - static int qeth_l3_iqd_read_initial_mac_cb(struct qeth_card *card, struct qeth_reply *reply, unsigned long data) { @@ -2324,25 +2295,14 @@ static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode) dev_close(card->dev); rtnl_unlock(); } - if (!card->use_hard_stop) { - rc = qeth_send_stoplan(card); - if (rc) - QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); - } card->state = CARD_STATE_SOFTSETUP; } if (card->state == CARD_STATE_SOFTSETUP) { - qeth_l3_clear_ip_list(card, !card->use_hard_stop, 1); + qeth_l3_clear_ip_list(card, 1); qeth_clear_ipacmd_list(card); card->state = CARD_STATE_HARDSETUP; } if (card->state == CARD_STATE_HARDSETUP) { - if (!card->use_hard_stop && - (card->info.type != QETH_CARD_TYPE_IQD)) { - rc = qeth_l3_put_unique_id(card); - if (rc) - QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); - } qeth_qdio_clear_card(card, 0); qeth_clear_qdio_buffers(card); qeth_clear_working_pool_list(card); @@ -2352,7 +2312,6 @@ static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode) qeth_clear_cmd_buffers(&card->read); qeth_clear_cmd_buffers(&card->write); } - card->use_hard_stop = 0; return rc; } @@ -3483,17 +3442,15 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev) qeth_set_allowed_threads(card, 0, 1); wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); - if (cgdev->state == CCWGROUP_ONLINE) { - card->use_hard_stop = 1; + if (cgdev->state == CCWGROUP_ONLINE) qeth_l3_set_offline(cgdev); - } if (card->dev) { unregister_netdev(card->dev); card->dev = NULL; } - qeth_l3_clear_ip_list(card, 0, 0); + qeth_l3_clear_ip_list(card, 0); qeth_l3_clear_ipato_list(card); return; } @@ -3594,7 +3551,6 @@ contin: mutex_unlock(&card->discipline_mutex); return 0; out_remove: - card->use_hard_stop = 1; qeth_l3_stop_card(card, 0); ccw_device_set_offline(CARD_DDEV(card)); ccw_device_set_offline(CARD_WDEV(card)); @@ -3663,7 +3619,6 @@ static int qeth_l3_recover(void *ptr) QETH_CARD_TEXT(card, 2, "recover2"); dev_warn(&card->gdev->dev, "A recovery process has been started for the device\n"); - card->use_hard_stop = 1; __qeth_l3_set_offline(card->gdev, 1); rc = __qeth_l3_set_online(card->gdev, 1); if (!rc) @@ -3684,7 +3639,6 @@ static int qeth_l3_recover(void *ptr) static void qeth_l3_shutdown(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - qeth_l3_clear_ip_list(card, 0, 0); qeth_qdio_clear_card(card, 0); qeth_clear_qdio_buffers(card); } @@ -3700,7 +3654,6 @@ static int qeth_l3_pm_suspend(struct ccwgroup_device *gdev) if (gdev->state == CCWGROUP_OFFLINE) return 0; if (card->state == CARD_STATE_UP) { - card->use_hard_stop = 1; __qeth_l3_set_offline(card->gdev, 1); } else __qeth_l3_set_offline(card->gdev, 0); -- cgit v1.2.3 From 8d9bd9002dc8c3a05e11c5f40d95d06e15e83f71 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Wed, 23 Feb 2011 02:30:28 +0300 Subject: ARM: pxa/colibri: don't register pxa2xx-pcmcia nodes on non-colibri platforms PXA supports multi-machine kernels since long ago. However a kernel compiled with support for colibri and any other PXA machine and with PCMCIA enabled will barf at runtime about duplicate registration of pxa2xx-pcmcia device. Fix that. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Eric Miao --- drivers/pcmcia/pxa2xx_colibri.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c index c3f72192af66..a52039564e74 100644 --- a/drivers/pcmcia/pxa2xx_colibri.c +++ b/drivers/pcmcia/pxa2xx_colibri.c @@ -181,6 +181,9 @@ static int __init colibri_pcmcia_init(void) { int ret; + if (!machine_is_colibri() && !machine_is_colibri320()) + return -ENODEV; + colibri_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); if (!colibri_pcmcia_device) return -ENOMEM; -- cgit v1.2.3 From dc5ecf45f3e772a9845c1afebfbc423474f2e46a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 25 Feb 2011 15:57:36 -0800 Subject: Staging: samsung-laptop: Constify samsung-laptop.c Change sabi_config to const. Reduces data, increases text ~200 bytes. $ size drivers/platform/x86/samsung-laptop.o* text data bss dec hex filename 6933 5084 1560 13577 3509 drivers/platform/x86/samsung-laptop.o.new 6765 5252 1560 13577 3509 drivers/platform/x86/samsung-laptop.o.old Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index a8e82b8eb5d7..720c9eb2f8d2 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -108,12 +108,12 @@ struct sabi_performance_level { struct sabi_config { const char *test_string; u16 main_function; - struct sabi_header_offsets header_offsets; - struct sabi_commands commands; - struct sabi_performance_level performance_levels[4]; + const struct sabi_header_offsets header_offsets; + const struct sabi_commands commands; + const struct sabi_performance_level performance_levels[4]; }; -static struct sabi_config sabi_configs[] = { +static const struct sabi_config sabi_configs[] = { { .test_string = "SECLINUX", @@ -211,7 +211,7 @@ static struct sabi_config sabi_configs[] = { { }, }; -static struct sabi_config *sabi_config; +static const struct sabi_config *sabi_config; static void __iomem *sabi; static void __iomem *sabi_iface; @@ -467,7 +467,7 @@ static ssize_t set_performance_level(struct device *dev, if (count >= 1) { int i; for (i = 0; sabi_config->performance_levels[i].name; ++i) { - struct sabi_performance_level *level = + const struct sabi_performance_level *level = &sabi_config->performance_levels[i]; if (!strncasecmp(level->name, buf, strlen(level->name))) { sabi_set_command(sabi_config->commands.set_performance_level, -- cgit v1.2.3 From 8aa2bb43646aa24bcee5298bf83051a8ce9967a6 Mon Sep 17 00:00:00 2001 From: Riccardo Magliocchetti Date: Sat, 26 Feb 2011 17:06:44 +0100 Subject: Staging: samsung-laptop: Add P460 to supported laptops Signed-off-by: Riccardo Magliocchetti Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index 720c9eb2f8d2..0983741b9c40 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -629,6 +629,15 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, .callback = dmi_check_cb, }, + { + .ident = "P460", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "P460"), + DMI_MATCH(DMI_BOARD_NAME, "P460"), + }, + .callback = dmi_check_cb, + }, { }, }; MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); -- cgit v1.2.3 From 50d1ae2f8084807be80313796548a46f756dff91 Mon Sep 17 00:00:00 2001 From: Nils Faerber Date: Sat, 26 Feb 2011 23:45:42 +0100 Subject: Staging: samsung-laptop: fix brightness level and add new device ids The patch is against the 2.6.37 drivers/staging/samsung-laptop driver and implements some extra enhancements. It fixes an issue that the brightness would not change the level at once as well as and some other oddities. It was resolved by reallocated the SABI memory reagion using the "nocache" option. The patch also introduces a new set of supported netbook models, especially the NC10plus which was used for testing this patch. This new set of models also offer 9 instead of just 8 brightness levels so it also introduces an additional parameter for the models struct so that models can define their own brightness range. Signed-off-by: Nils Faerber Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 32 +++++++++++++++++++------ 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index 0983741b9c40..e0b390d45d8d 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -111,6 +111,8 @@ struct sabi_config { const struct sabi_header_offsets header_offsets; const struct sabi_commands commands; const struct sabi_performance_level performance_levels[4]; + u8 min_brightness; + u8 max_brightness; }; static const struct sabi_config sabi_configs[] = { @@ -158,6 +160,8 @@ static const struct sabi_config sabi_configs[] = { }, { }, }, + .min_brightness = 1, + .max_brightness = 8, }, { .test_string = "SwSmi@", @@ -207,6 +211,8 @@ static const struct sabi_config sabi_configs[] = { }, { }, }, + .min_brightness = 0, + .max_brightness = 8, }, { }, }; @@ -362,17 +368,19 @@ static u8 read_brightness(void) retval = sabi_get_command(sabi_config->commands.get_brightness, &sretval); - if (!retval) + if (!retval) { user_brightness = sretval.retval[0]; if (user_brightness != 0) - --user_brightness; + user_brightness -= sabi_config->min_brightness; + } return user_brightness; } static void set_brightness(u8 user_brightness) { - sabi_set_command(sabi_config->commands.set_brightness, - user_brightness + 1); + u8 user_level = user_brightness - sabi_config->min_brightness; + + sabi_set_command(sabi_config->commands.set_brightness, user_level); } static int get_brightness(struct backlight_device *bd) @@ -592,6 +600,16 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, .callback = dmi_check_cb, }, + { + .ident = "N150P/N210P/N220P", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "N150P/N210P/N220P"), + DMI_MATCH(DMI_BOARD_NAME, "N150P/N210P/N220P"), + }, + .callback = dmi_check_cb, + }, { .ident = "R530/R730", .matches = { @@ -675,7 +693,7 @@ static int __init samsung_init(void) if (!force && !dmi_check_system(samsung_dmi_table)) return -ENODEV; - f0000_segment = ioremap(0xf0000, 0xffff); + f0000_segment = ioremap_nocache(0xf0000, 0xffff); if (!f0000_segment) { pr_err("Can't map the segment at 0xf0000\n"); return -EINVAL; @@ -719,7 +737,7 @@ static int __init samsung_init(void) /* Get a pointer to the SABI Interface */ ifaceP = (readw(sabi + sabi_config->header_offsets.data_segment) & 0x0ffff) << 4; ifaceP += readw(sabi + sabi_config->header_offsets.data_offset) & 0x0ffff; - sabi_iface = ioremap(ifaceP, 16); + sabi_iface = ioremap_nocache(ifaceP, 16); if (!sabi_iface) { pr_err("Can't remap %x\n", ifaceP); goto exit; @@ -753,7 +771,7 @@ static int __init samsung_init(void) /* create a backlight device to talk to this one */ memset(&props, 0, sizeof(struct backlight_properties)); - props.max_brightness = MAX_BRIGHT; + props.max_brightness = sabi_config->max_brightness; backlight_device = backlight_device_register("samsung", &sdev->dev, NULL, &backlight_ops, &props); -- cgit v1.2.3 From 0c3a6ede3c9ffff6771915320504e8e140ac18b8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 27 Feb 2011 07:43:10 -0800 Subject: Staging: hv: add mouse driver This driver adds mouse support to the hyper-v subsystem. The code was originally written by Citrix, modified heavily by Hank at Microsoft, and then further by me, to get it to build properly due to all of the recent hyperv changes in the tree. At the moment, it is marked "BROKEN" as it has not been tested well, and it will conflict with other api changes that KY is doing, which I will fix up later in this driver. It still needs lots of work, and normal "cleanup". I don't recommend anyone running it on their machine unless they are very brave and know how to debug kernel drivers in a hyperv system. Signed-off-by: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Kconfig | 7 + drivers/staging/hv/Makefile | 2 + drivers/staging/hv/hv_mouse_drv.c | 335 ++++++++++++++ drivers/staging/hv/mouse_vsc.c | 763 ++++++++++++++++++++++++++++++++ drivers/staging/hv/mousevsc_api.h | 73 +++ drivers/staging/hv/vmbus_hid_protocol.h | 120 +++++ 6 files changed, 1300 insertions(+) create mode 100644 drivers/staging/hv/hv_mouse_drv.c create mode 100644 drivers/staging/hv/mouse_vsc.c create mode 100644 drivers/staging/hv/mousevsc_api.h create mode 100644 drivers/staging/hv/vmbus_hid_protocol.h (limited to 'drivers') diff --git a/drivers/staging/hv/Kconfig b/drivers/staging/hv/Kconfig index 2780312cc30d..2985f0cd2916 100644 --- a/drivers/staging/hv/Kconfig +++ b/drivers/staging/hv/Kconfig @@ -36,4 +36,11 @@ config HYPERV_UTILS help Select this option to enable the Hyper-V Utilities. +config HYPERV_MOUSE + tristate "Microsoft Hyper-V mouse driver" + depends on HID && BROKEN + default HYPERV + help + Select this option to enable the Hyper-V mouse driver. + endif diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index 737e51796e63..0a7af4709c37 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_HYPERV_STORAGE) += hv_storvsc.o obj-$(CONFIG_HYPERV_BLOCK) += hv_blkvsc.o obj-$(CONFIG_HYPERV_NET) += hv_netvsc.o obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o +obj-$(CONFIG_HYPERV_MOUSE) += hv_mouse.o hv_vmbus-y := vmbus_drv.o \ hv.o connection.o channel.o \ @@ -11,3 +12,4 @@ hv_storvsc-y := storvsc_drv.o storvsc.o hv_blkvsc-y := blkvsc_drv.o blkvsc.o hv_netvsc-y := netvsc_drv.o netvsc.o rndis_filter.o hv_utils-y := hv_util.o hv_kvp.o +hv_mouse-objs := hv_mouse_drv.o mouse_vsc.o diff --git a/drivers/staging/hv/hv_mouse_drv.c b/drivers/staging/hv/hv_mouse_drv.c new file mode 100644 index 000000000000..09f7d05f1495 --- /dev/null +++ b/drivers/staging/hv/hv_mouse_drv.c @@ -0,0 +1,335 @@ +/* + * Copyright 2009 Citrix Systems, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * For clarity, the licensor of this program does not intend that a + * "derivative work" include code which compiles header information from + * this program. + * + * This code has been modified from its original by + * Hank Janssen + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#include "osd.h" +#include "hv_api.h" +#include "logging.h" +#include "version_info.h" +#include "vmbus.h" +#include "mousevsc_api.h" + +#define NBITS(x) (((x)/BITS_PER_LONG)+1) + + +/* + * Data types + */ +struct input_device_context { + struct vm_device *device_ctx; + struct hid_device *hid_device; + struct input_dev_info device_info; + int connected; +}; + +struct mousevsc_driver_context { + struct driver_context drv_ctx; + struct mousevsc_drv_obj drv_obj; +}; + +static struct mousevsc_driver_context g_mousevsc_drv; + +void mousevsc_deviceinfo_callback(struct hv_device *dev, + struct input_dev_info *info) +{ + struct vm_device *device_ctx = to_vm_device(dev); + struct input_device_context *input_device_ctx = + dev_get_drvdata(&device_ctx->device); + + memcpy(&input_device_ctx->device_info, info, + sizeof(struct input_dev_info)); + + DPRINT_INFO(INPUTVSC_DRV, "mousevsc_deviceinfo_callback()"); +} + +void mousevsc_inputreport_callback(struct hv_device *dev, void *packet, u32 len) +{ + int ret = 0; + + struct vm_device *device_ctx = to_vm_device(dev); + struct input_device_context *input_dev_ctx = + dev_get_drvdata(&device_ctx->device); + + ret = hid_input_report(input_dev_ctx->hid_device, + HID_INPUT_REPORT, packet, len, 1); + + DPRINT_DBG(INPUTVSC_DRV, "hid_input_report (ret %d)", ret); +} + +int mousevsc_hid_open(struct hid_device *hid) +{ + return 0; +} + +void mousevsc_hid_close(struct hid_device *hid) +{ +} + +int mousevsc_probe(struct device *device) +{ + int ret = 0; + + struct driver_context *driver_ctx = + driver_to_driver_context(device->driver); + struct mousevsc_driver_context *mousevsc_drv_ctx = + (struct mousevsc_driver_context *)driver_ctx; + struct mousevsc_drv_obj *mousevsc_drv_obj = &mousevsc_drv_ctx->drv_obj; + + struct vm_device *device_ctx = device_to_vm_device(device); + struct hv_device *device_obj = &device_ctx->device_obj; + struct input_device_context *input_dev_ctx; + + input_dev_ctx = kmalloc(sizeof(struct input_device_context), + GFP_KERNEL); + + dev_set_drvdata(device, input_dev_ctx); + + /* Call to the vsc driver to add the device */ + ret = mousevsc_drv_obj->Base.dev_add(device_obj, NULL); + + if (ret != 0) { + DPRINT_ERR(INPUTVSC_DRV, "unable to add input vsc device"); + + return -1; + } + + return 0; +} + + +int mousevsc_remove(struct device *device) +{ + int ret = 0; + + struct driver_context *driver_ctx = + driver_to_driver_context(device->driver); + struct mousevsc_driver_context *mousevsc_drv_ctx = + (struct mousevsc_driver_context *)driver_ctx; + struct mousevsc_drv_obj *mousevsc_drv_obj = &mousevsc_drv_ctx->drv_obj; + + struct vm_device *device_ctx = device_to_vm_device(device); + struct hv_device *device_obj = &device_ctx->device_obj; + struct input_device_context *input_dev_ctx; + + input_dev_ctx = kmalloc(sizeof(struct input_device_context), + GFP_KERNEL); + + dev_set_drvdata(device, input_dev_ctx); + + if (input_dev_ctx->connected) { + hidinput_disconnect(input_dev_ctx->hid_device); + input_dev_ctx->connected = 0; + } + + if (!mousevsc_drv_obj->Base.dev_rm) { + return -1; + } + + /* + * Call to the vsc driver to let it know that the device + * is being removed + */ + ret = mousevsc_drv_obj->Base.dev_rm(device_obj); + + if (ret != 0) { + DPRINT_ERR(INPUTVSC_DRV, + "unable to remove vsc device (ret %d)", ret); + } + + kfree(input_dev_ctx); + + return ret; +} + +void mousevsc_reportdesc_callback(struct hv_device *dev, void *packet, u32 len) +{ + struct vm_device *device_ctx = to_vm_device(dev); + struct input_device_context *input_device_ctx = + dev_get_drvdata(&device_ctx->device); + struct hid_device *hid_dev; + + /* hid_debug = -1; */ + hid_dev = kmalloc(sizeof(struct hid_device), GFP_KERNEL); + + if (hid_parse_report(hid_dev, packet, len)) { + DPRINT_INFO(INPUTVSC_DRV, "Unable to call hd_parse_report"); + return; + } + + if (hid_dev) { + DPRINT_INFO(INPUTVSC_DRV, "hid_device created"); + + hid_dev->ll_driver->open = mousevsc_hid_open; + hid_dev->ll_driver->close = mousevsc_hid_close; + + hid_dev->bus = 0x06; /* BUS_VIRTUAL */ + hid_dev->vendor = input_device_ctx->device_info.VendorID; + hid_dev->product = input_device_ctx->device_info.ProductID; + hid_dev->version = input_device_ctx->device_info.VersionNumber; + hid_dev->dev = device_ctx->device; + + sprintf(hid_dev->name, "%s", + input_device_ctx->device_info.Name); + + /* + * HJ Do we want to call it with a 0 + */ + if (!hidinput_connect(hid_dev, 0)) { + hid_dev->claimed |= HID_CLAIMED_INPUT; + + input_device_ctx->connected = 1; + + DPRINT_INFO(INPUTVSC_DRV, + "HID device claimed by input\n"); + } + + if (!hid_dev->claimed) { + DPRINT_ERR(INPUTVSC_DRV, + "HID device not claimed by " + "input or hiddev\n"); + } + + input_device_ctx->hid_device = hid_dev; + } + + kfree(hid_dev); +} + +/* + * + * Name: mousevsc_drv_init() + * + * Desc: Driver initialization. + */ +int mousevsc_drv_init(int (*pfn_drv_init)(struct hv_driver *pfn_drv_init)) +{ + int ret = 0; + struct mousevsc_drv_obj *input_drv_obj = &g_mousevsc_drv.drv_obj; + struct driver_context *drv_ctx = &g_mousevsc_drv.drv_ctx; + +// vmbus_get_interface(&input_drv_obj->Base.VmbusChannelInterface); + + input_drv_obj->OnDeviceInfo = mousevsc_deviceinfo_callback; + input_drv_obj->OnInputReport = mousevsc_inputreport_callback; + input_drv_obj->OnReportDescriptor = mousevsc_reportdesc_callback; + + /* Callback to client driver to complete the initialization */ + pfn_drv_init(&input_drv_obj->Base); + + drv_ctx->driver.name = input_drv_obj->Base.name; + memcpy(&drv_ctx->class_id, &input_drv_obj->Base.dev_type, + sizeof(struct hv_guid)); + + drv_ctx->probe = mousevsc_probe; + drv_ctx->remove = mousevsc_remove; + + /* The driver belongs to vmbus */ + vmbus_child_driver_register(drv_ctx); + + return ret; +} + + +int mousevsc_drv_exit_cb(struct device *dev, void *data) +{ + struct device **curr = (struct device **)data; + *curr = dev; + + return 1; +} + +void mousevsc_drv_exit(void) +{ + struct mousevsc_drv_obj *mousevsc_drv_obj = &g_mousevsc_drv.drv_obj; + struct driver_context *drv_ctx = &g_mousevsc_drv.drv_ctx; + int ret; + + struct device *current_dev = NULL; + + while (1) { + current_dev = NULL; + + /* Get the device */ + ret = driver_for_each_device(&drv_ctx->driver, NULL, (void *)¤t_dev, mousevsc_drv_exit_cb); + if (ret) + printk(KERN_ERR "Can't find mouse device!\n"); + + if (current_dev == NULL) + break; + + /* Initiate removal from the top-down */ + device_unregister(current_dev); + } + + if (mousevsc_drv_obj->Base.cleanup) + mousevsc_drv_obj->Base.cleanup(&mousevsc_drv_obj->Base); + + vmbus_child_driver_unregister(drv_ctx); + + return; +} + +static int __init mousevsc_init(void) +{ + int ret; + + DPRINT_INFO(INPUTVSC_DRV, "Hyper-V Mouse driver initializing."); + + ret = mousevsc_drv_init(mouse_vsc_initialize); + + return ret; +} + +static void __exit mousevsc_exit(void) +{ + mousevsc_drv_exit(); +} + +/* + * We use a PCI table to determine if we should autoload this driver This is + * needed by distro tools to determine if the hyperv drivers should be + * installed and/or configured. We don't do anything else with the table, but + * it needs to be present. + */ +const static struct pci_device_id microsoft_hv_pci_table[] = { + { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */ + { 0 } +}; +MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table); + +MODULE_LICENSE("GPL"); +MODULE_VERSION(HV_DRV_VERSION); +module_init(mousevsc_init); +module_exit(mousevsc_exit); + diff --git a/drivers/staging/hv/mouse_vsc.c b/drivers/staging/hv/mouse_vsc.c new file mode 100644 index 000000000000..6c8d0afb0b0f --- /dev/null +++ b/drivers/staging/hv/mouse_vsc.c @@ -0,0 +1,763 @@ +/* + * Copyright 2009 Citrix Systems, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * For clarity, the licensor of this program does not intend that a + * "derivative work" include code which compiles header information from + * this program. + * + * This code has been modified from its original by + * Hank Janssen + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hv_api.h" +#include "vmbus.h" +#include "vmbus_api.h" +#include "channel.h" +#include "logging.h" + +#include "mousevsc_api.h" +#include "vmbus_packet_format.h" +#include "vmbus_hid_protocol.h" + + +enum pipe_prot_msg_type +{ + PipeMessageInvalid = 0, + PipeMessageData, + PipeMessageMaximum +}; + + +struct pipe_prt_msg +{ + enum pipe_prot_msg_type PacketType; + u32 DataSize; + char Data[1]; +}; + +/* + * Data types + */ +struct mousevsc_prt_msg { + enum pipe_prot_msg_type PacketType; + u32 DataSize; + union { + SYNTHHID_PROTOCOL_REQUEST Request; + SYNTHHID_PROTOCOL_RESPONSE Response; + SYNTHHID_DEVICE_INFO_ACK Ack; + } u; +}; + +/* + * Represents an mousevsc device + */ +struct mousevsc_dev { + struct hv_device *Device; + /* 0 indicates the device is being destroyed */ + atomic_t RefCount; + int NumOutstandingRequests; + unsigned char bInitializeComplete; + struct mousevsc_prt_msg ProtocolReq; + struct mousevsc_prt_msg ProtocolResp; + /* Synchronize the request/response if needed */ + wait_queue_head_t ProtocolWaitEvent; + wait_queue_head_t DeviceInfoWaitEvent; + int protocol_wait_condition; + int device_wait_condition; + int DeviceInfoStatus; + + struct hid_descriptor *HidDesc; + unsigned char *ReportDesc; + u32 ReportDescSize; + struct input_dev_info DeviceAttr; +}; + + +/* + * Globals + */ +static const char* gDriverName = "mousevsc"; + +/* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */ +static const struct hv_guid gMousevscDeviceType = { + .data = {0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c, + 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A} +}; + +/* + * Internal routines + */ +static int MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo); + +static int MousevscOnDeviceRemove(struct hv_device *Device); + +static void MousevscOnCleanup(struct hv_driver *Device); + +static void MousevscOnChannelCallback(void *Context); + +static int MousevscConnectToVsp(struct hv_device *Device); + +static void MousevscOnReceive(struct hv_device *Device, + struct vmpacket_descriptor *Packet); + +static inline struct mousevsc_dev *AllocInputDevice(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + + inputDevice = kzalloc(sizeof(struct mousevsc_dev), GFP_KERNEL); + + if (!inputDevice) + return NULL; + + /* + * Set to 2 to allow both inbound and outbound traffics + * (ie GetInputDevice() and MustGetInputDevice()) to proceed. + */ + atomic_cmpxchg(&inputDevice->RefCount, 0, 2); + + inputDevice->Device = Device; + Device->ext = inputDevice; + + return inputDevice; +} + +static inline void FreeInputDevice(struct mousevsc_dev *Device) +{ + WARN_ON(atomic_read(&Device->RefCount) == 0); + kfree(Device); +} + +/* + * Get the inputdevice object if exists and its refcount > 1 + */ +static inline struct mousevsc_dev* GetInputDevice(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + + inputDevice = (struct mousevsc_dev*)Device->ext; + +// printk(KERN_ERR "-------------------------> REFCOUNT = %d", +// inputDevice->RefCount); + + if (inputDevice && atomic_read(&inputDevice->RefCount) > 1) + atomic_inc(&inputDevice->RefCount); + else + inputDevice = NULL; + + return inputDevice; +} + +/* + * Get the inputdevice object iff exists and its refcount > 0 + */ +static inline struct mousevsc_dev* MustGetInputDevice(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + + inputDevice = (struct mousevsc_dev*)Device->ext; + + if (inputDevice && atomic_read(&inputDevice->RefCount)) + atomic_inc(&inputDevice->RefCount); + else + inputDevice = NULL; + + return inputDevice; +} + +static inline void PutInputDevice(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + + inputDevice = (struct mousevsc_dev*)Device->ext; + + atomic_dec(&inputDevice->RefCount); +} + +/* + * Drop ref count to 1 to effectively disable GetInputDevice() + */ +static inline struct mousevsc_dev* ReleaseInputDevice(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + + inputDevice = (struct mousevsc_dev*)Device->ext; + + /* Busy wait until the ref drop to 2, then set it to 1 */ + while (atomic_cmpxchg(&inputDevice->RefCount, 2, 1) != 2) + udelay(100); + + return inputDevice; +} + +/* + * Drop ref count to 0. No one can use InputDevice object. + */ +static inline struct mousevsc_dev* FinalReleaseInputDevice(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + + inputDevice = (struct mousevsc_dev*)Device->ext; + + /* Busy wait until the ref drop to 1, then set it to 0 */ + while (atomic_cmpxchg(&inputDevice->RefCount, 1, 0) != 1) + udelay(100); + + Device->ext = NULL; + return inputDevice; +} + +/* + * + * Name: + * MousevscInitialize() + * + * Description: + * Main entry point + * + */ +int mouse_vsc_initialize(struct hv_driver *Driver) +{ + struct mousevsc_drv_obj *inputDriver = + (struct mousevsc_drv_obj *)Driver; + int ret = 0; + + Driver->name = gDriverName; + memcpy(&Driver->dev_type, &gMousevscDeviceType, + sizeof(struct hv_guid)); + + /* Setup the dispatch table */ + inputDriver->Base.dev_add = MousevscOnDeviceAdd; + inputDriver->Base.dev_rm = MousevscOnDeviceRemove; + inputDriver->Base.cleanup = MousevscOnCleanup; + + inputDriver->OnOpen = NULL; + inputDriver->OnClose = NULL; + + return ret; +} + +/* + * + * Name: + * MousevscOnDeviceAdd() + * + * Description: + * Callback when the device belonging to this driver is added + * + */ +int +MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) +{ + int ret = 0; + struct mousevsc_dev *inputDevice; + struct mousevsc_drv_obj *inputDriver; + struct input_dev_info deviceInfo; + + inputDevice = AllocInputDevice(Device); + + if (!inputDevice) { + ret = -1; + goto Cleanup; + } + + inputDevice->bInitializeComplete = false; + + /* Open the channel */ + ret = vmbus_open(Device->channel, + INPUTVSC_SEND_RING_BUFFER_SIZE, + INPUTVSC_RECV_RING_BUFFER_SIZE, + NULL, + 0, + MousevscOnChannelCallback, + Device + ); + + if (ret != 0) { + pr_err("unable to open channel: %d", ret); + return -1; + } + + pr_info("InputVsc channel open: %d", ret); + + ret = MousevscConnectToVsp(Device); + + if (ret != 0) { + pr_err("unable to connect channel: %d", ret); + + vmbus_close(Device->channel); + return ret; + } + + inputDriver = (struct mousevsc_drv_obj *)inputDevice->Device->drv; + + deviceInfo.VendorID = inputDevice->DeviceAttr.VendorID; + deviceInfo.ProductID = inputDevice->DeviceAttr.ProductID; + deviceInfo.VersionNumber = inputDevice->DeviceAttr.VersionNumber; + strcpy(deviceInfo.Name, "Microsoft Vmbus HID-compliant Mouse"); + + /* Send the device info back up */ + inputDriver->OnDeviceInfo(Device, &deviceInfo); + + /* Send the report desc back up */ + /* workaround SA-167 */ + if (inputDevice->ReportDesc[14] == 0x25) + inputDevice->ReportDesc[14] = 0x29; + + inputDriver->OnReportDescriptor(Device, inputDevice->ReportDesc, inputDevice->ReportDescSize); + + inputDevice->bInitializeComplete = true; + +Cleanup: + return ret; +} + +int +MousevscConnectToVsp(struct hv_device *Device) +{ + int ret=0; + struct mousevsc_dev *inputDevice; + struct mousevsc_prt_msg *request; + struct mousevsc_prt_msg *response; + + inputDevice = GetInputDevice(Device); + + if (!inputDevice) { + pr_err("unable to get input device...device being destroyed?"); + return -1; + } + + init_waitqueue_head(&inputDevice->ProtocolWaitEvent); + init_waitqueue_head(&inputDevice->DeviceInfoWaitEvent); + + request = &inputDevice->ProtocolReq; + + /* + * Now, initiate the vsc/vsp initialization protocol on the open channel + */ + memset(request, sizeof(struct mousevsc_prt_msg), 0); + + request->PacketType = PipeMessageData; + request->DataSize = sizeof(SYNTHHID_PROTOCOL_REQUEST); + + request->u.Request.Header.Type = SynthHidProtocolRequest; + request->u.Request.Header.Size = sizeof(unsigned long); + request->u.Request.VersionRequested.AsDWord = + SYNTHHID_INPUT_VERSION_DWORD; + + pr_info("SYNTHHID_PROTOCOL_REQUEST..."); + + ret = vmbus_sendpacket(Device->channel, request, + sizeof(struct pipe_prt_msg) - + sizeof(unsigned char) + + sizeof(SYNTHHID_PROTOCOL_REQUEST), + (unsigned long)request, + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if ( ret != 0) { + pr_err("unable to send SYNTHHID_PROTOCOL_REQUEST"); + goto Cleanup; + } + + inputDevice->protocol_wait_condition = 0; + wait_event_timeout(inputDevice->ProtocolWaitEvent, inputDevice->protocol_wait_condition, msecs_to_jiffies(1000)); + if (inputDevice->protocol_wait_condition == 0) { + ret = -ETIMEDOUT; + goto Cleanup; + } + + response = &inputDevice->ProtocolResp; + + if (!response->u.Response.Approved) { + pr_err("SYNTHHID_PROTOCOL_REQUEST failed (version %d)", + SYNTHHID_INPUT_VERSION_DWORD); + ret = -1; + goto Cleanup; + } + + inputDevice->device_wait_condition = 0; + wait_event_timeout(inputDevice->DeviceInfoWaitEvent, inputDevice->device_wait_condition, msecs_to_jiffies(1000)); + if (inputDevice->device_wait_condition == 0) { + ret = -ETIMEDOUT; + goto Cleanup; + } + + /* + * We should have gotten the device attr, hid desc and report + * desc at this point + */ + if (!inputDevice->DeviceInfoStatus) + pr_info("**** input channel up and running!! ****"); + else + ret = -1; + +Cleanup: + PutInputDevice(Device); + + return ret; +} + + +/* + * + * Name: + * MousevscOnDeviceRemove() + * + * Description: + * Callback when the our device is being removed + * + */ +int +MousevscOnDeviceRemove(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + int ret=0; + + pr_info("disabling input device (%p)...", + Device->ext); + + inputDevice = ReleaseInputDevice(Device); + + + /* + * At this point, all outbound traffic should be disable. We only + * allow inbound traffic (responses) to proceed + * + * so that outstanding requests can be completed. + */ + while (inputDevice->NumOutstandingRequests) + { + pr_info("waiting for %d requests to complete...", inputDevice->NumOutstandingRequests); + + udelay(100); + } + + pr_info("removing input device (%p)...", Device->ext); + + inputDevice = FinalReleaseInputDevice(Device); + + pr_info("input device (%p) safe to remove", inputDevice); + + /* Close the channel */ + vmbus_close(Device->channel); + + FreeInputDevice(inputDevice); + + return ret; +} + + +/* + * + * Name: + * MousevscOnCleanup() + * + * Description: + * Perform any cleanup when the driver is removed + */ +static void MousevscOnCleanup(struct hv_driver *drv) +{ +} + + +static void +MousevscOnSendCompletion(struct hv_device *Device, + struct vmpacket_descriptor *Packet) +{ + struct mousevsc_dev *inputDevice; + void *request; + + inputDevice = MustGetInputDevice(Device); + if (!inputDevice) { + pr_err("unable to get input device...device being destroyed?"); + return; + } + + request = (void*)(unsigned long *) Packet->trans_id; + + if (request == &inputDevice->ProtocolReq) + { + + } + + PutInputDevice(Device); +} + +void +MousevscOnReceiveDeviceInfo( + struct mousevsc_dev* InputDevice, + SYNTHHID_DEVICE_INFO* DeviceInfo + ) +{ + int ret = 0; + struct hid_descriptor *desc; + struct mousevsc_prt_msg ack; + + /* Assume success for now */ + InputDevice->DeviceInfoStatus = 0; + + /* Save the device attr */ + memcpy(&InputDevice->DeviceAttr, &DeviceInfo->HidDeviceAttributes, sizeof(struct input_dev_info)); + + /* Save the hid desc */ + desc = (struct hid_descriptor *)DeviceInfo->HidDescriptorInformation; + WARN_ON(desc->bLength > 0); + + InputDevice->HidDesc = kzalloc(desc->bLength, GFP_KERNEL); + + if (!InputDevice->HidDesc) { + pr_err("unable to allocate hid descriptor - size %d", desc->bLength); + goto Cleanup; + } + + memcpy(InputDevice->HidDesc, desc, desc->bLength); + + /* Save the report desc */ + InputDevice->ReportDescSize = desc->desc[0].wDescriptorLength; + InputDevice->ReportDesc = kzalloc(InputDevice->ReportDescSize, + GFP_KERNEL); + + if (!InputDevice->ReportDesc) { + pr_err("unable to allocate report descriptor - size %d", + InputDevice->ReportDescSize); + goto Cleanup; + } + + memcpy(InputDevice->ReportDesc, + ((unsigned char *)desc) + desc->bLength, + desc->desc[0].wDescriptorLength); + + /* Send the ack */ + memset(&ack, sizeof(struct mousevsc_prt_msg), 0); + + ack.PacketType = PipeMessageData; + ack.DataSize = sizeof(SYNTHHID_DEVICE_INFO_ACK); + + ack.u.Ack.Header.Type = SynthHidInitialDeviceInfoAck; + ack.u.Ack.Header.Size = 1; + ack.u.Ack.Reserved = 0; + + ret = vmbus_sendpacket(InputDevice->Device->channel, + &ack, + sizeof(struct pipe_prt_msg) - sizeof(unsigned char) + sizeof(SYNTHHID_DEVICE_INFO_ACK), + (unsigned long)&ack, + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if (ret != 0) { + pr_err("unable to send SYNTHHID_DEVICE_INFO_ACK - ret %d", + ret); + goto Cleanup; + } + + InputDevice->device_wait_condition = 1; + wake_up(&InputDevice->DeviceInfoWaitEvent); + + return; + +Cleanup: + if (InputDevice->HidDesc) + { + kfree(InputDevice->HidDesc); + InputDevice->HidDesc = NULL; + } + + if (InputDevice->ReportDesc) + { + kfree(InputDevice->ReportDesc); + InputDevice->ReportDesc = NULL; + } + + InputDevice->DeviceInfoStatus = -1; + InputDevice->device_wait_condition = 1; + wake_up(&InputDevice->DeviceInfoWaitEvent); +} + + +void +MousevscOnReceiveInputReport( + struct mousevsc_dev* InputDevice, + SYNTHHID_INPUT_REPORT *InputReport + ) +{ + struct mousevsc_drv_obj *inputDriver; + + if (!InputDevice->bInitializeComplete) + { + pr_info("Initialization incomplete...ignoring InputReport msg"); + return; + } + + inputDriver = (struct mousevsc_drv_obj *)InputDevice->Device->drv; + + inputDriver->OnInputReport(InputDevice->Device, + InputReport->ReportBuffer, + InputReport->Header.Size); +} + +void +MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet) +{ + struct pipe_prt_msg *pipeMsg; + SYNTHHID_MESSAGE *hidMsg; + struct mousevsc_dev *inputDevice; + + inputDevice = MustGetInputDevice(Device); + if (!inputDevice) + { + pr_err("unable to get input device...device being destroyed?"); + return; + } + + pipeMsg = (struct pipe_prt_msg *)((unsigned long)Packet + (Packet->offset8 << 3)); + + if (pipeMsg->PacketType != PipeMessageData) { + pr_err("unknown pipe msg type - type %d len %d", + pipeMsg->PacketType, pipeMsg->DataSize); + PutInputDevice(Device); + return ; + } + + hidMsg = (SYNTHHID_MESSAGE*)&pipeMsg->Data[0]; + + switch (hidMsg->Header.Type) { + case SynthHidProtocolResponse: + memcpy(&inputDevice->ProtocolResp, pipeMsg, pipeMsg->DataSize+sizeof(struct pipe_prt_msg) - sizeof(unsigned char)); + inputDevice->protocol_wait_condition = 1; + wake_up(&inputDevice->ProtocolWaitEvent); + break; + + case SynthHidInitialDeviceInfo: + WARN_ON(pipeMsg->DataSize >= sizeof(struct input_dev_info)); + + /* + * Parse out the device info into device attr, + * hid desc and report desc + */ + MousevscOnReceiveDeviceInfo(inputDevice, + (SYNTHHID_DEVICE_INFO*)&pipeMsg->Data[0]); + break; + case SynthHidInputReport: + MousevscOnReceiveInputReport(inputDevice, + (SYNTHHID_INPUT_REPORT*)&pipeMsg->Data[0]); + + break; + default: + pr_err("unsupported hid msg type - type %d len %d", + hidMsg->Header.Type, hidMsg->Header.Size); + break; + } + + PutInputDevice(Device); +} + +void MousevscOnChannelCallback(void *Context) +{ + const int packetSize = 0x100; + int ret = 0; + struct hv_device *device = (struct hv_device *)Context; + struct mousevsc_dev *inputDevice; + + u32 bytesRecvd; + u64 requestId; + unsigned char packet[packetSize]; + struct vmpacket_descriptor *desc; + unsigned char *buffer = packet; + int bufferlen = packetSize; + + inputDevice = MustGetInputDevice(device); + + if (!inputDevice) { + pr_err("unable to get input device...device being destroyed?"); + return; + } + + do { + ret = vmbus_recvpacket_raw(device->channel, buffer, bufferlen, &bytesRecvd, &requestId); + + if (ret == 0) { + if (bytesRecvd > 0) { + desc = (struct vmpacket_descriptor *)buffer; + + switch (desc->type) + { + case VM_PKT_COMP: + MousevscOnSendCompletion(device, + desc); + break; + + case VM_PKT_DATA_INBAND: + MousevscOnReceive(device, desc); + break; + + default: + pr_err("unhandled packet type %d, tid %llx len %d\n", + desc->type, + requestId, + bytesRecvd); + break; + } + + /* reset */ + if (bufferlen > packetSize) { + kfree(buffer); + + buffer = packet; + bufferlen = packetSize; + } + } else { + /* + * pr_debug("nothing else to read..."); + * reset + */ + if (bufferlen > packetSize) { + kfree(buffer); + + buffer = packet; + bufferlen = packetSize; + } + break; + } + } else if (ret == -2) { + /* Handle large packet */ + bufferlen = bytesRecvd; + buffer = kzalloc(bytesRecvd, GFP_KERNEL); + + if (buffer == NULL) { + buffer = packet; + bufferlen = packetSize; + + /* Try again next time around */ + pr_err("unable to allocate buffer of size %d!", + bytesRecvd); + break; + } + } + } while (1); + + PutInputDevice(device); + + return; +} + diff --git a/drivers/staging/hv/mousevsc_api.h b/drivers/staging/hv/mousevsc_api.h new file mode 100644 index 000000000000..f3610867143d --- /dev/null +++ b/drivers/staging/hv/mousevsc_api.h @@ -0,0 +1,73 @@ +/* + * Copyright 2009 Citrix Systems, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * For clarity, the licensor of this program does not intend that a + * "derivative work" include code which compiles header information from + * this program. + * + * This code has been modified from its original by + * Hank Janssen + * + */ + +#ifndef _INPUTVSC_API_H_ +#define _INPUTVSC_API_H_ + +#include "vmbus_api.h" + +/* + * Defines + */ +#define INPUTVSC_SEND_RING_BUFFER_SIZE 10*PAGE_SIZE +#define INPUTVSC_RECV_RING_BUFFER_SIZE 10*PAGE_SIZE + + +/* + * Data types + */ +struct input_dev_info { + unsigned short VendorID; + unsigned short ProductID; + unsigned short VersionNumber; + char Name[128]; +}; + +/* Represents the input vsc driver */ +struct mousevsc_drv_obj { + struct hv_driver Base; // Must be the first field + /* + * This is set by the caller to allow us to callback when + * we receive a packet from the "wire" + */ + void (*OnDeviceInfo)(struct hv_device *dev, + struct input_dev_info* info); + void (*OnInputReport)(struct hv_device *dev, void* packet, u32 len); + void (*OnReportDescriptor)(struct hv_device *dev, + void* packet, u32 len); + /* Specific to this driver */ + int (*OnOpen)(struct hv_device *Device); + int (*OnClose)(struct hv_device *Device); + void *Context; +}; + + +/* + * Interface + */ +int mouse_vsc_initialize(struct hv_driver *drv); + +#endif // _INPUTVSC_API_H_ diff --git a/drivers/staging/hv/vmbus_hid_protocol.h b/drivers/staging/hv/vmbus_hid_protocol.h new file mode 100644 index 000000000000..65f3001e6202 --- /dev/null +++ b/drivers/staging/hv/vmbus_hid_protocol.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Hank Janssen + */ +#ifndef _VMBUS_HID_PROTOCOL_ +#define _VMBUS_HID_PROTOCOL_ + +/* The maximum size of a synthetic input message. */ +#define SYNTHHID_MAX_INPUT_REPORT_SIZE 16 + +/* + * Current version + * + * History: + * Beta, RC < 2008/1/22 1,0 + * RC > 2008/1/22 2,0 + */ +#define SYNTHHID_INPUT_VERSION_MAJOR 2 +#define SYNTHHID_INPUT_VERSION_MINOR 0 +#define SYNTHHID_INPUT_VERSION_DWORD (SYNTHHID_INPUT_VERSION_MINOR | \ + (SYNTHHID_INPUT_VERSION_MAJOR << 16)) + + +#pragma pack(push,1) + +/* + * Message types in the synthetic input protocol + */ +enum synthhid_msg_type +{ + SynthHidProtocolRequest, + SynthHidProtocolResponse, + SynthHidInitialDeviceInfo, + SynthHidInitialDeviceInfoAck, + SynthHidInputReport, + SynthHidMax +}; + + +/* + * Basic message structures. + */ +typedef struct +{ + enum synthhid_msg_type Type; /* Type of the enclosed message */ + u32 Size; /* Size of the enclosed message + * (size of the data payload) + */ +} SYNTHHID_MESSAGE_HEADER, *PSYNTHHID_MESSAGE_HEADER; + +typedef struct +{ + SYNTHHID_MESSAGE_HEADER Header; + char Data[1]; /* Enclosed message */ +} SYNTHHID_MESSAGE, *PSYNTHHID_MESSAGE; + +typedef union +{ + struct { + u16 Minor; + u16 Major; + }; + + u32 AsDWord; +} SYNTHHID_VERSION, *PSYNTHHID_VERSION; + +/* + * Protocol messages + */ +typedef struct +{ + SYNTHHID_MESSAGE_HEADER Header; + SYNTHHID_VERSION VersionRequested; +} SYNTHHID_PROTOCOL_REQUEST, *PSYNTHHID_PROTOCOL_REQUEST; + +typedef struct +{ + SYNTHHID_MESSAGE_HEADER Header; + SYNTHHID_VERSION VersionRequested; + unsigned char Approved; +} SYNTHHID_PROTOCOL_RESPONSE, *PSYNTHHID_PROTOCOL_RESPONSE; + +typedef struct +{ + SYNTHHID_MESSAGE_HEADER Header; + struct input_dev_info HidDeviceAttributes; + unsigned char HidDescriptorInformation[1]; +} SYNTHHID_DEVICE_INFO, *PSYNTHHID_DEVICE_INFO; + +typedef struct +{ + SYNTHHID_MESSAGE_HEADER Header; + unsigned char Reserved; +} SYNTHHID_DEVICE_INFO_ACK, *PSYNTHHID_DEVICE_INFO_ACK; + +typedef struct +{ + SYNTHHID_MESSAGE_HEADER Header; + char ReportBuffer[1]; +} SYNTHHID_INPUT_REPORT, *PSYNTHHID_INPUT_REPORT; + +#pragma pack(pop) + +#endif /* _VMBUS_HID_PROTOCOL_ */ + -- cgit v1.2.3 From df213559f029047b4b3d06a25a36f4779de9b989 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Sun, 20 Feb 2011 04:27:05 +0000 Subject: bnx2x: Add a missing bit for PXP parity register of 57712. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_init.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_init.h b/drivers/net/bnx2x/bnx2x_init.h index 5a268e9a0895..fa6dbe3f2058 100644 --- a/drivers/net/bnx2x/bnx2x_init.h +++ b/drivers/net/bnx2x/bnx2x_init.h @@ -241,7 +241,7 @@ static const struct { /* Block IGU, MISC, PXP and PXP2 parity errors as long as we don't * want to handle "system kill" flow at the moment. */ - BLOCK_PRTY_INFO(PXP, 0x3ffffff, 0x3ffffff, 0x3ffffff, 0x3ffffff), + BLOCK_PRTY_INFO(PXP, 0x7ffffff, 0x3ffffff, 0x3ffffff, 0x7ffffff), BLOCK_PRTY_INFO_0(PXP2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), BLOCK_PRTY_INFO_1(PXP2, 0x7ff, 0x7f, 0x7f, 0x7ff), BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0), -- cgit v1.2.3 From 8a8efa22f51b3c3f879d272914e3dbbc2041bf91 Mon Sep 17 00:00:00 2001 From: Amerigo Wang Date: Thu, 17 Feb 2011 23:43:32 +0000 Subject: bonding: sync netpoll code with bridge V4: rebase to net-next-2.6 V3: remove an useless #ifdef. This patch unifies the netpoll code in bonding with netpoll code in bridge, thanks to Herbert that code is much cleaner now. Signed-off-by: WANG Cong Acked-by: Neil Horman Cc: Herbert Xu Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 155 +++++++++++++++++++++++++--------------- drivers/net/bonding/bonding.h | 20 ++++++ 2 files changed, 118 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 77e3c6a7176a..2ed662464cac 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -59,7 +59,6 @@ #include #include #include -#include #include #include #include @@ -424,15 +423,11 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, { skb->dev = slave_dev; skb->priority = 1; -#ifdef CONFIG_NET_POLL_CONTROLLER - if (unlikely(bond->dev->priv_flags & IFF_IN_NETPOLL)) { - struct netpoll *np = bond->dev->npinfo->netpoll; - slave_dev->npinfo = bond->dev->npinfo; + if (unlikely(netpoll_tx_running(slave_dev))) { slave_dev->priv_flags |= IFF_IN_NETPOLL; - netpoll_send_skb_on_dev(np, skb, slave_dev); + bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb); slave_dev->priv_flags &= ~IFF_IN_NETPOLL; } else -#endif dev_queue_xmit(skb); return 0; @@ -1288,63 +1283,113 @@ static void bond_detach_slave(struct bonding *bond, struct slave *slave) } #ifdef CONFIG_NET_POLL_CONTROLLER -/* - * You must hold read lock on bond->lock before calling this. - */ -static bool slaves_support_netpoll(struct net_device *bond_dev) +static inline int slave_enable_netpoll(struct slave *slave) { - struct bonding *bond = netdev_priv(bond_dev); - struct slave *slave; - int i = 0; - bool ret = true; + struct netpoll *np; + int err = 0; - bond_for_each_slave(bond, slave, i) { - if ((slave->dev->priv_flags & IFF_DISABLE_NETPOLL) || - !slave->dev->netdev_ops->ndo_poll_controller) - ret = false; + np = kzalloc(sizeof(*np), GFP_KERNEL); + err = -ENOMEM; + if (!np) + goto out; + + np->dev = slave->dev; + err = __netpoll_setup(np); + if (err) { + kfree(np); + goto out; } - return i != 0 && ret; + slave->np = np; +out: + return err; +} +static inline void slave_disable_netpoll(struct slave *slave) +{ + struct netpoll *np = slave->np; + + if (!np) + return; + + slave->np = NULL; + synchronize_rcu_bh(); + __netpoll_cleanup(np); + kfree(np); +} +static inline bool slave_dev_support_netpoll(struct net_device *slave_dev) +{ + if (slave_dev->priv_flags & IFF_DISABLE_NETPOLL) + return false; + if (!slave_dev->netdev_ops->ndo_poll_controller) + return false; + return true; } static void bond_poll_controller(struct net_device *bond_dev) { - struct bonding *bond = netdev_priv(bond_dev); +} + +static void __bond_netpoll_cleanup(struct bonding *bond) +{ struct slave *slave; int i; - bond_for_each_slave(bond, slave, i) { - if (slave->dev && IS_UP(slave->dev)) - netpoll_poll_dev(slave->dev); - } + bond_for_each_slave(bond, slave, i) + if (IS_UP(slave->dev)) + slave_disable_netpoll(slave); } - static void bond_netpoll_cleanup(struct net_device *bond_dev) { struct bonding *bond = netdev_priv(bond_dev); + + read_lock(&bond->lock); + __bond_netpoll_cleanup(bond); + read_unlock(&bond->lock); +} + +static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni) +{ + struct bonding *bond = netdev_priv(dev); struct slave *slave; - const struct net_device_ops *ops; - int i; + int i, err = 0; read_lock(&bond->lock); - bond_dev->npinfo = NULL; bond_for_each_slave(bond, slave, i) { - if (slave->dev) { - ops = slave->dev->netdev_ops; - if (ops->ndo_netpoll_cleanup) - ops->ndo_netpoll_cleanup(slave->dev); - else - slave->dev->npinfo = NULL; + if (!IS_UP(slave->dev)) + continue; + err = slave_enable_netpoll(slave); + if (err) { + __bond_netpoll_cleanup(bond); + break; } } read_unlock(&bond->lock); + return err; } -#else +static struct netpoll_info *bond_netpoll_info(struct bonding *bond) +{ + return bond->dev->npinfo; +} +#else +static inline int slave_enable_netpoll(struct slave *slave) +{ + return 0; +} +static inline void slave_disable_netpoll(struct slave *slave) +{ +} static void bond_netpoll_cleanup(struct net_device *bond_dev) { } - +static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni) +{ + return 0; +} +static struct netpoll_info *bond_netpoll_info(struct bonding *bond) +{ + return NULL; +} #endif /*---------------------------------- IOCTL ----------------------------------*/ @@ -1782,17 +1827,19 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) bond_set_carrier(bond); #ifdef CONFIG_NET_POLL_CONTROLLER - if (slaves_support_netpoll(bond_dev)) { - bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL; - if (bond_dev->npinfo) - slave_dev->npinfo = bond_dev->npinfo; - } else if (!(bond_dev->priv_flags & IFF_DISABLE_NETPOLL)) { - bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; - pr_info("New slave device %s does not support netpoll\n", - slave_dev->name); - pr_info("Disabling netpoll support for %s\n", bond_dev->name); + slave_dev->npinfo = bond_netpoll_info(bond); + if (slave_dev->npinfo) { + if (slave_enable_netpoll(new_slave)) { + read_unlock(&bond->lock); + pr_info("Error, %s: master_dev is using netpoll, " + "but new slave device does not support netpoll.\n", + bond_dev->name); + res = -EBUSY; + goto err_close; + } } #endif + read_unlock(&bond->lock); res = bond_create_slave_symlinks(bond_dev, slave_dev); @@ -1994,17 +2041,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) netdev_set_bond_master(slave_dev, NULL); -#ifdef CONFIG_NET_POLL_CONTROLLER - read_lock_bh(&bond->lock); - - if (slaves_support_netpoll(bond_dev)) - bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL; - read_unlock_bh(&bond->lock); - if (slave_dev->netdev_ops->ndo_netpoll_cleanup) - slave_dev->netdev_ops->ndo_netpoll_cleanup(slave_dev); - else - slave_dev->npinfo = NULL; -#endif + slave_disable_netpoll(slave); /* close slave before restoring its mac address */ dev_close(slave_dev); @@ -2039,6 +2076,7 @@ static int bond_release_and_destroy(struct net_device *bond_dev, ret = bond_release(bond_dev, slave_dev); if ((ret == 0) && (bond->slave_cnt == 0)) { + bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; pr_info("%s: destroying bond %s.\n", bond_dev->name, bond_dev->name); unregister_netdevice(bond_dev); @@ -2116,6 +2154,8 @@ static int bond_release_all(struct net_device *bond_dev) netdev_set_bond_master(slave_dev, NULL); + slave_disable_netpoll(slave); + /* close slave before restoring its mac address */ dev_close(slave_dev); @@ -4654,6 +4694,7 @@ static const struct net_device_ops bond_netdev_ops = { .ndo_vlan_rx_add_vid = bond_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid, #ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_netpoll_setup = bond_netpoll_setup, .ndo_netpoll_cleanup = bond_netpoll_cleanup, .ndo_poll_controller = bond_poll_controller, #endif diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 31fe980e4e28..0a3e00b220b7 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "bond_3ad.h" #include "bond_alb.h" @@ -198,6 +199,9 @@ struct slave { u16 queue_id; struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */ struct tlb_slave_info tlb_info; +#ifdef CONFIG_NET_POLL_CONTROLLER + struct netpoll *np; +#endif }; /* @@ -323,6 +327,22 @@ static inline unsigned long slave_last_rx(struct bonding *bond, return slave->dev->last_rx; } +#ifdef CONFIG_NET_POLL_CONTROLLER +static inline void bond_netpoll_send_skb(const struct slave *slave, + struct sk_buff *skb) +{ + struct netpoll *np = slave->np; + + if (np) + netpoll_send_skb(np, skb); +} +#else +static inline void bond_netpoll_send_skb(const struct slave *slave, + struct sk_buff *skb) +{ +} +#endif + static inline void bond_set_slave_inactive_flags(struct slave *slave) { struct bonding *bond = netdev_priv(slave->dev->master); -- cgit v1.2.3 From 080e4130b1fb6a02e75149a1cccc8192e734713d Mon Sep 17 00:00:00 2001 From: Amerigo Wang Date: Thu, 17 Feb 2011 23:43:33 +0000 Subject: netpoll: remove IFF_IN_NETPOLL flag V4: rebase to net-next-2.6 This patch removes the flag IFF_IN_NETPOLL, we don't need it any more since we have netpoll_tx_running() now. Signed-off-by: WANG Cong Acked-by: Neil Horman Cc: Herbert Xu Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 6 ++---- drivers/net/bonding/bonding.h | 2 +- include/linux/if.h | 9 ++++----- net/core/netpoll.c | 2 -- 4 files changed, 7 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 2ed662464cac..c75126ddc646 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -423,11 +423,9 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, { skb->dev = slave_dev; skb->priority = 1; - if (unlikely(netpoll_tx_running(slave_dev))) { - slave_dev->priv_flags |= IFF_IN_NETPOLL; + if (unlikely(netpoll_tx_running(slave_dev))) bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb); - slave_dev->priv_flags &= ~IFF_IN_NETPOLL; - } else + else dev_queue_xmit(skb); return 0; diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 0a3e00b220b7..a401b8df84f0 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -133,7 +133,7 @@ static inline void unblock_netpoll_tx(void) static inline int is_netpoll_tx_blocked(struct net_device *dev) { - if (unlikely(dev->priv_flags & IFF_IN_NETPOLL)) + if (unlikely(netpoll_tx_running(dev))) return atomic_read(&netpoll_block_tx); return 0; } diff --git a/include/linux/if.h b/include/linux/if.h index 123959927745..3bc63e6a02f7 100644 --- a/include/linux/if.h +++ b/include/linux/if.h @@ -71,11 +71,10 @@ * release skb->dst */ #define IFF_DONT_BRIDGE 0x800 /* disallow bridging this ether dev */ -#define IFF_IN_NETPOLL 0x1000 /* whether we are processing netpoll */ -#define IFF_DISABLE_NETPOLL 0x2000 /* disable netpoll at run-time */ -#define IFF_MACVLAN_PORT 0x4000 /* device used as macvlan port */ -#define IFF_BRIDGE_PORT 0x8000 /* device used as bridge port */ -#define IFF_OVS_DATAPATH 0x10000 /* device used as Open vSwitch +#define IFF_DISABLE_NETPOLL 0x1000 /* disable netpoll at run-time */ +#define IFF_MACVLAN_PORT 0x2000 /* device used as macvlan port */ +#define IFF_BRIDGE_PORT 0x4000 /* device used as bridge port */ +#define IFF_OVS_DATAPATH 0x8000 /* device used as Open vSwitch * datapath port */ #define IF_GET_IFACE 0x0001 /* for querying only */ diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 02dc2cbcbe86..f68e6949294e 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -313,9 +313,7 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, tries > 0; --tries) { if (__netif_tx_trylock(txq)) { if (!netif_tx_queue_stopped(txq)) { - dev->priv_flags |= IFF_IN_NETPOLL; status = ops->ndo_start_xmit(skb, dev); - dev->priv_flags &= ~IFF_IN_NETPOLL; if (status == NETDEV_TX_OK) txq_trans_update(txq); } -- cgit v1.2.3 From 7db26623257a16c901a4b77bfc5096ee05304932 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 28 Feb 2011 14:22:12 +1000 Subject: drm/nv50-nvc0: make sure vma is definitely unmapped when destroying bo Somehow fixes a misrendering + hang at GDM startup on my NVA8... My first guess would have been stale TLB entries laying around that a new bo then accidentally inherits. That doesn't make a great deal of sense however, as when we mapped the pages for the new bo the TLBs would've gotten flushed anyway. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index d38a4d9f9b0b..a52184007f5f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -49,7 +49,10 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo) DRM_ERROR("bo %p still attached to GEM object\n", bo); nv10_mem_put_tile_region(dev, nvbo->tile, NULL); - nouveau_vm_put(&nvbo->vma); + if (nvbo->vma.node) { + nouveau_vm_unmap(&nvbo->vma); + nouveau_vm_put(&nvbo->vma); + } kfree(nvbo); } -- cgit v1.2.3 From 1922756124ddd53846877416d92ba4a802bc658f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 24 Feb 2011 08:35:06 +1000 Subject: drm: fix unsigned vs signed comparison issue in modeset ctl ioctl. This fixes CVE-2011-1013. Reported-by: Matthiew Herrb (OpenBSD X.org team) Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_irq.c | 3 ++- include/drm/drmP.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 53120a72a48c..28d1d3c24d65 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -1012,7 +1012,8 @@ int drm_modeset_ctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_modeset_ctl *modeset = data; - int crtc, ret = 0; + int ret = 0; + unsigned int crtc; /* If drm_vblank_init() hasn't been called yet, just no-op */ if (!dev->num_crtcs) diff --git a/include/drm/drmP.h b/include/drm/drmP.h index fe29aadb129d..348843b80150 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1101,7 +1101,7 @@ struct drm_device { struct platform_device *platformdev; /**< Platform device struture */ struct drm_sg_mem *sg; /**< Scatter gather memory */ - int num_crtcs; /**< Number of CRTCs on this device */ + unsigned int num_crtcs; /**< Number of CRTCs on this device */ void *dev_private; /**< device private data */ void *mm_private; struct address_space *dev_mapping; -- cgit v1.2.3 From 5b2c4dd2ec12cf0e53b2bd2926f0fe2d1fbb4eda Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 23 Feb 2011 09:05:42 +0000 Subject: net: convert bonding to use rx_handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch converts bonding to use rx_handler. Results in cleaner __netif_receive_skb() with much less exceptions needed. Also bond-specific work is moved into bond code. Did performance test using pktgen and counting incoming packets by iptables. No regression noted. Signed-off-by: Jiri Pirko Reviewed-by: Nicolas de Pesloüan Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 74 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index c75126ddc646..584f97b73060 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1466,6 +1466,67 @@ static void bond_setup_by_slave(struct net_device *bond_dev, bond->setup_by_slave = 1; } +/* On bonding slaves other than the currently active slave, suppress + * duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and + * ARP on active-backup slaves with arp_validate enabled. + */ +static bool bond_should_deliver_exact_match(struct sk_buff *skb, + struct net_device *slave_dev, + struct net_device *bond_dev) +{ + if (slave_dev->priv_flags & IFF_SLAVE_INACTIVE) { + if (slave_dev->priv_flags & IFF_SLAVE_NEEDARP && + skb->protocol == __cpu_to_be16(ETH_P_ARP)) + return false; + + if (bond_dev->priv_flags & IFF_MASTER_ALB && + skb->pkt_type != PACKET_BROADCAST && + skb->pkt_type != PACKET_MULTICAST) + return false; + + if (bond_dev->priv_flags & IFF_MASTER_8023AD && + skb->protocol == __cpu_to_be16(ETH_P_SLOW)) + return false; + + return true; + } + return false; +} + +static struct sk_buff *bond_handle_frame(struct sk_buff *skb) +{ + struct net_device *slave_dev; + struct net_device *bond_dev; + + skb = skb_share_check(skb, GFP_ATOMIC); + if (unlikely(!skb)) + return NULL; + slave_dev = skb->dev; + bond_dev = ACCESS_ONCE(slave_dev->master); + if (unlikely(!bond_dev)) + return skb; + + if (bond_dev->priv_flags & IFF_MASTER_ARPMON) + slave_dev->last_rx = jiffies; + + if (bond_should_deliver_exact_match(skb, slave_dev, bond_dev)) { + skb->deliver_no_wcard = 1; + return skb; + } + + skb->dev = bond_dev; + + if (bond_dev->priv_flags & IFF_MASTER_ALB && + bond_dev->priv_flags & IFF_BRIDGE_PORT && + skb->pkt_type == PACKET_HOST) { + u16 *dest = (u16 *) eth_hdr(skb)->h_dest; + + memcpy(dest, bond_dev->dev_addr, ETH_ALEN); + } + + return skb; +} + /* enslave device to bond device */ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) { @@ -1642,11 +1703,17 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) pr_debug("Error %d calling netdev_set_bond_master\n", res); goto err_restore_mac; } + res = netdev_rx_handler_register(slave_dev, bond_handle_frame, NULL); + if (res) { + pr_debug("Error %d calling netdev_rx_handler_register\n", res); + goto err_unset_master; + } + /* open the slave since the application closed it */ res = dev_open(slave_dev); if (res) { pr_debug("Opening slave %s failed\n", slave_dev->name); - goto err_unset_master; + goto err_unreg_rxhandler; } new_slave->dev = slave_dev; @@ -1856,6 +1923,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) err_close: dev_close(slave_dev); +err_unreg_rxhandler: + netdev_rx_handler_unregister(slave_dev); + err_unset_master: netdev_set_bond_master(slave_dev, NULL); @@ -2037,6 +2107,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) netif_addr_unlock_bh(bond_dev); } + netdev_rx_handler_unregister(slave_dev); netdev_set_bond_master(slave_dev, NULL); slave_disable_netpoll(slave); @@ -2150,6 +2221,7 @@ static int bond_release_all(struct net_device *bond_dev) netif_addr_unlock_bh(bond_dev); } + netdev_rx_handler_unregister(slave_dev); netdev_set_bond_master(slave_dev, NULL); slave_disable_netpoll(slave); -- cgit v1.2.3 From 710ac54be44e0cc53f5bf29b03d12c8706e7077a Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 17 Feb 2011 00:26:57 -0700 Subject: dt/powerpc: move of_bus_type infrastructure to ibmebus arch/powerpc/kernel/ibmebus.c is the only remaining user of the of_bus_type support code for initializing the bus and registering drivers. All others have either been switched to the vanilla platform bus or already have their own infrastructure. This patch moves the functionality that ibmebus is using out of drivers/of/{platform,device}.c and into ibmebus.c where it is actually used. Also renames the moved symbols from of_platform_* to ibmebus_bus_* to reflect the actual usage. This patch is part of moving all of the of_platform_bus_type users over to the platform_bus_type. Signed-off-by: Grant Likely --- arch/powerpc/kernel/ibmebus.c | 404 +++++++++++++++++++++++++++++++++++++++++- drivers/of/device.c | 34 ---- drivers/of/platform.c | 393 ---------------------------------------- include/linux/of_platform.h | 6 - 4 files changed, 400 insertions(+), 437 deletions(-) (limited to 'drivers') diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index f62efdfd1769..c00d4ca1ee15 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -201,13 +201,14 @@ int ibmebus_register_driver(struct of_platform_driver *drv) /* If the driver uses devices that ibmebus doesn't know, add them */ ibmebus_create_devices(drv->driver.of_match_table); - return of_register_driver(drv, &ibmebus_bus_type); + drv->driver.bus = &ibmebus_bus_type; + return driver_register(&drv->driver); } EXPORT_SYMBOL(ibmebus_register_driver); void ibmebus_unregister_driver(struct of_platform_driver *drv) { - of_unregister_driver(drv); + driver_unregister(&drv->driver); } EXPORT_SYMBOL(ibmebus_unregister_driver); @@ -308,15 +309,410 @@ static ssize_t ibmebus_store_remove(struct bus_type *bus, } } + static struct bus_attribute ibmebus_bus_attrs[] = { __ATTR(probe, S_IWUSR, NULL, ibmebus_store_probe), __ATTR(remove, S_IWUSR, NULL, ibmebus_store_remove), __ATTR_NULL }; +static int ibmebus_bus_bus_match(struct device *dev, struct device_driver *drv) +{ + const struct of_device_id *matches = drv->of_match_table; + + if (!matches) + return 0; + + return of_match_device(matches, dev) != NULL; +} + +static int ibmebus_bus_device_probe(struct device *dev) +{ + int error = -ENODEV; + struct of_platform_driver *drv; + struct platform_device *of_dev; + const struct of_device_id *match; + + drv = to_of_platform_driver(dev->driver); + of_dev = to_platform_device(dev); + + if (!drv->probe) + return error; + + of_dev_get(of_dev); + + match = of_match_device(drv->driver.of_match_table, dev); + if (match) + error = drv->probe(of_dev, match); + if (error) + of_dev_put(of_dev); + + return error; +} + +static int ibmebus_bus_device_remove(struct device *dev) +{ + struct platform_device *of_dev = to_platform_device(dev); + struct of_platform_driver *drv = to_of_platform_driver(dev->driver); + + if (dev->driver && drv->remove) + drv->remove(of_dev); + return 0; +} + +static void ibmebus_bus_device_shutdown(struct device *dev) +{ + struct platform_device *of_dev = to_platform_device(dev); + struct of_platform_driver *drv = to_of_platform_driver(dev->driver); + + if (dev->driver && drv->shutdown) + drv->shutdown(of_dev); +} + +/* + * ibmebus_bus_device_attrs + */ +static ssize_t devspec_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct platform_device *ofdev; + + ofdev = to_platform_device(dev); + return sprintf(buf, "%s\n", ofdev->dev.of_node->full_name); +} + +static ssize_t name_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct platform_device *ofdev; + + ofdev = to_platform_device(dev); + return sprintf(buf, "%s\n", ofdev->dev.of_node->name); +} + +static ssize_t modalias_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t len = of_device_get_modalias(dev, buf, PAGE_SIZE - 2); + buf[len] = '\n'; + buf[len+1] = 0; + return len+1; +} + +struct device_attribute ibmebus_bus_device_attrs[] = { + __ATTR_RO(devspec), + __ATTR_RO(name), + __ATTR_RO(modalias), + __ATTR_NULL +}; + +#ifdef CONFIG_PM_SLEEP +static int ibmebus_bus_legacy_suspend(struct device *dev, pm_message_t mesg) +{ + struct platform_device *of_dev = to_platform_device(dev); + struct of_platform_driver *drv = to_of_platform_driver(dev->driver); + int ret = 0; + + if (dev->driver && drv->suspend) + ret = drv->suspend(of_dev, mesg); + return ret; +} + +static int ibmebus_bus_legacy_resume(struct device *dev) +{ + struct platform_device *of_dev = to_platform_device(dev); + struct of_platform_driver *drv = to_of_platform_driver(dev->driver); + int ret = 0; + + if (dev->driver && drv->resume) + ret = drv->resume(of_dev); + return ret; +} + +static int ibmebus_bus_pm_prepare(struct device *dev) +{ + struct device_driver *drv = dev->driver; + int ret = 0; + + if (drv && drv->pm && drv->pm->prepare) + ret = drv->pm->prepare(dev); + + return ret; +} + +static void ibmebus_bus_pm_complete(struct device *dev) +{ + struct device_driver *drv = dev->driver; + + if (drv && drv->pm && drv->pm->complete) + drv->pm->complete(dev); +} + +#ifdef CONFIG_SUSPEND + +static int ibmebus_bus_pm_suspend(struct device *dev) +{ + struct device_driver *drv = dev->driver; + int ret = 0; + + if (!drv) + return 0; + + if (drv->pm) { + if (drv->pm->suspend) + ret = drv->pm->suspend(dev); + } else { + ret = ibmebus_bus_legacy_suspend(dev, PMSG_SUSPEND); + } + + return ret; +} + +static int ibmebus_bus_pm_suspend_noirq(struct device *dev) +{ + struct device_driver *drv = dev->driver; + int ret = 0; + + if (!drv) + return 0; + + if (drv->pm) { + if (drv->pm->suspend_noirq) + ret = drv->pm->suspend_noirq(dev); + } + + return ret; +} + +static int ibmebus_bus_pm_resume(struct device *dev) +{ + struct device_driver *drv = dev->driver; + int ret = 0; + + if (!drv) + return 0; + + if (drv->pm) { + if (drv->pm->resume) + ret = drv->pm->resume(dev); + } else { + ret = ibmebus_bus_legacy_resume(dev); + } + + return ret; +} + +static int ibmebus_bus_pm_resume_noirq(struct device *dev) +{ + struct device_driver *drv = dev->driver; + int ret = 0; + + if (!drv) + return 0; + + if (drv->pm) { + if (drv->pm->resume_noirq) + ret = drv->pm->resume_noirq(dev); + } + + return ret; +} + +#else /* !CONFIG_SUSPEND */ + +#define ibmebus_bus_pm_suspend NULL +#define ibmebus_bus_pm_resume NULL +#define ibmebus_bus_pm_suspend_noirq NULL +#define ibmebus_bus_pm_resume_noirq NULL + +#endif /* !CONFIG_SUSPEND */ + +#ifdef CONFIG_HIBERNATION + +static int ibmebus_bus_pm_freeze(struct device *dev) +{ + struct device_driver *drv = dev->driver; + int ret = 0; + + if (!drv) + return 0; + + if (drv->pm) { + if (drv->pm->freeze) + ret = drv->pm->freeze(dev); + } else { + ret = ibmebus_bus_legacy_suspend(dev, PMSG_FREEZE); + } + + return ret; +} + +static int ibmebus_bus_pm_freeze_noirq(struct device *dev) +{ + struct device_driver *drv = dev->driver; + int ret = 0; + + if (!drv) + return 0; + + if (drv->pm) { + if (drv->pm->freeze_noirq) + ret = drv->pm->freeze_noirq(dev); + } + + return ret; +} + +static int ibmebus_bus_pm_thaw(struct device *dev) +{ + struct device_driver *drv = dev->driver; + int ret = 0; + + if (!drv) + return 0; + + if (drv->pm) { + if (drv->pm->thaw) + ret = drv->pm->thaw(dev); + } else { + ret = ibmebus_bus_legacy_resume(dev); + } + + return ret; +} + +static int ibmebus_bus_pm_thaw_noirq(struct device *dev) +{ + struct device_driver *drv = dev->driver; + int ret = 0; + + if (!drv) + return 0; + + if (drv->pm) { + if (drv->pm->thaw_noirq) + ret = drv->pm->thaw_noirq(dev); + } + + return ret; +} + +static int ibmebus_bus_pm_poweroff(struct device *dev) +{ + struct device_driver *drv = dev->driver; + int ret = 0; + + if (!drv) + return 0; + + if (drv->pm) { + if (drv->pm->poweroff) + ret = drv->pm->poweroff(dev); + } else { + ret = ibmebus_bus_legacy_suspend(dev, PMSG_HIBERNATE); + } + + return ret; +} + +static int ibmebus_bus_pm_poweroff_noirq(struct device *dev) +{ + struct device_driver *drv = dev->driver; + int ret = 0; + + if (!drv) + return 0; + + if (drv->pm) { + if (drv->pm->poweroff_noirq) + ret = drv->pm->poweroff_noirq(dev); + } + + return ret; +} + +static int ibmebus_bus_pm_restore(struct device *dev) +{ + struct device_driver *drv = dev->driver; + int ret = 0; + + if (!drv) + return 0; + + if (drv->pm) { + if (drv->pm->restore) + ret = drv->pm->restore(dev); + } else { + ret = ibmebus_bus_legacy_resume(dev); + } + + return ret; +} + +static int ibmebus_bus_pm_restore_noirq(struct device *dev) +{ + struct device_driver *drv = dev->driver; + int ret = 0; + + if (!drv) + return 0; + + if (drv->pm) { + if (drv->pm->restore_noirq) + ret = drv->pm->restore_noirq(dev); + } + + return ret; +} + +#else /* !CONFIG_HIBERNATION */ + +#define ibmebus_bus_pm_freeze NULL +#define ibmebus_bus_pm_thaw NULL +#define ibmebus_bus_pm_poweroff NULL +#define ibmebus_bus_pm_restore NULL +#define ibmebus_bus_pm_freeze_noirq NULL +#define ibmebus_bus_pm_thaw_noirq NULL +#define ibmebus_bus_pm_poweroff_noirq NULL +#define ibmebus_bus_pm_restore_noirq NULL + +#endif /* !CONFIG_HIBERNATION */ + +static struct dev_pm_ops ibmebus_bus_dev_pm_ops = { + .prepare = ibmebus_bus_pm_prepare, + .complete = ibmebus_bus_pm_complete, + .suspend = ibmebus_bus_pm_suspend, + .resume = ibmebus_bus_pm_resume, + .freeze = ibmebus_bus_pm_freeze, + .thaw = ibmebus_bus_pm_thaw, + .poweroff = ibmebus_bus_pm_poweroff, + .restore = ibmebus_bus_pm_restore, + .suspend_noirq = ibmebus_bus_pm_suspend_noirq, + .resume_noirq = ibmebus_bus_pm_resume_noirq, + .freeze_noirq = ibmebus_bus_pm_freeze_noirq, + .thaw_noirq = ibmebus_bus_pm_thaw_noirq, + .poweroff_noirq = ibmebus_bus_pm_poweroff_noirq, + .restore_noirq = ibmebus_bus_pm_restore_noirq, +}; + +#define IBMEBUS_BUS_PM_OPS_PTR (&ibmebus_bus_dev_pm_ops) + +#else /* !CONFIG_PM_SLEEP */ + +#define IBMEBUS_BUS_PM_OPS_PTR NULL + +#endif /* !CONFIG_PM_SLEEP */ + struct bus_type ibmebus_bus_type = { + .name = "ibmebus", .uevent = of_device_uevent, - .bus_attrs = ibmebus_bus_attrs + .bus_attrs = ibmebus_bus_attrs, + .match = ibmebus_bus_bus_match, + .probe = ibmebus_bus_device_probe, + .remove = ibmebus_bus_device_remove, + .shutdown = ibmebus_bus_device_shutdown, + .dev_attrs = ibmebus_bus_device_attrs, + .pm = IBMEBUS_BUS_PM_OPS_PTR, }; EXPORT_SYMBOL(ibmebus_bus_type); @@ -326,7 +722,7 @@ static int __init ibmebus_bus_init(void) printk(KERN_INFO "IBM eBus Device Driver\n"); - err = of_bus_type_init(&ibmebus_bus_type, "ibmebus"); + err = bus_register(&ibmebus_bus_type); if (err) { printk(KERN_ERR "%s: failed to register IBM eBus.\n", __func__); diff --git a/drivers/of/device.c b/drivers/of/device.c index 45d86530799f..62b4b32ac887 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -47,40 +47,6 @@ void of_dev_put(struct platform_device *dev) } EXPORT_SYMBOL(of_dev_put); -static ssize_t devspec_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct platform_device *ofdev; - - ofdev = to_platform_device(dev); - return sprintf(buf, "%s\n", ofdev->dev.of_node->full_name); -} - -static ssize_t name_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct platform_device *ofdev; - - ofdev = to_platform_device(dev); - return sprintf(buf, "%s\n", ofdev->dev.of_node->name); -} - -static ssize_t modalias_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - ssize_t len = of_device_get_modalias(dev, buf, PAGE_SIZE - 2); - buf[len] = '\n'; - buf[len+1] = 0; - return len+1; -} - -struct device_attribute of_platform_device_attrs[] = { - __ATTR_RO(devspec), - __ATTR_RO(name), - __ATTR_RO(modalias), - __ATTR_NULL -}; - int of_device_add(struct platform_device *ofdev) { BUG_ON(ofdev->dev.of_node == NULL); diff --git a/drivers/of/platform.c b/drivers/of/platform.c index c01cd1ac7617..b71d0cdc4209 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -114,399 +114,6 @@ EXPORT_SYMBOL(of_unregister_platform_driver); #include #endif -extern struct device_attribute of_platform_device_attrs[]; - -static int of_platform_bus_match(struct device *dev, struct device_driver *drv) -{ - const struct of_device_id *matches = drv->of_match_table; - - if (!matches) - return 0; - - return of_match_device(matches, dev) != NULL; -} - -static int of_platform_device_probe(struct device *dev) -{ - int error = -ENODEV; - struct of_platform_driver *drv; - struct platform_device *of_dev; - const struct of_device_id *match; - - drv = to_of_platform_driver(dev->driver); - of_dev = to_platform_device(dev); - - if (!drv->probe) - return error; - - of_dev_get(of_dev); - - match = of_match_device(drv->driver.of_match_table, dev); - if (match) - error = drv->probe(of_dev, match); - if (error) - of_dev_put(of_dev); - - return error; -} - -static int of_platform_device_remove(struct device *dev) -{ - struct platform_device *of_dev = to_platform_device(dev); - struct of_platform_driver *drv = to_of_platform_driver(dev->driver); - - if (dev->driver && drv->remove) - drv->remove(of_dev); - return 0; -} - -static void of_platform_device_shutdown(struct device *dev) -{ - struct platform_device *of_dev = to_platform_device(dev); - struct of_platform_driver *drv = to_of_platform_driver(dev->driver); - - if (dev->driver && drv->shutdown) - drv->shutdown(of_dev); -} - -#ifdef CONFIG_PM_SLEEP - -static int of_platform_legacy_suspend(struct device *dev, pm_message_t mesg) -{ - struct platform_device *of_dev = to_platform_device(dev); - struct of_platform_driver *drv = to_of_platform_driver(dev->driver); - int ret = 0; - - if (dev->driver && drv->suspend) - ret = drv->suspend(of_dev, mesg); - return ret; -} - -static int of_platform_legacy_resume(struct device *dev) -{ - struct platform_device *of_dev = to_platform_device(dev); - struct of_platform_driver *drv = to_of_platform_driver(dev->driver); - int ret = 0; - - if (dev->driver && drv->resume) - ret = drv->resume(of_dev); - return ret; -} - -static int of_platform_pm_prepare(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (drv && drv->pm && drv->pm->prepare) - ret = drv->pm->prepare(dev); - - return ret; -} - -static void of_platform_pm_complete(struct device *dev) -{ - struct device_driver *drv = dev->driver; - - if (drv && drv->pm && drv->pm->complete) - drv->pm->complete(dev); -} - -#ifdef CONFIG_SUSPEND - -static int of_platform_pm_suspend(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->suspend) - ret = drv->pm->suspend(dev); - } else { - ret = of_platform_legacy_suspend(dev, PMSG_SUSPEND); - } - - return ret; -} - -static int of_platform_pm_suspend_noirq(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->suspend_noirq) - ret = drv->pm->suspend_noirq(dev); - } - - return ret; -} - -static int of_platform_pm_resume(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->resume) - ret = drv->pm->resume(dev); - } else { - ret = of_platform_legacy_resume(dev); - } - - return ret; -} - -static int of_platform_pm_resume_noirq(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->resume_noirq) - ret = drv->pm->resume_noirq(dev); - } - - return ret; -} - -#else /* !CONFIG_SUSPEND */ - -#define of_platform_pm_suspend NULL -#define of_platform_pm_resume NULL -#define of_platform_pm_suspend_noirq NULL -#define of_platform_pm_resume_noirq NULL - -#endif /* !CONFIG_SUSPEND */ - -#ifdef CONFIG_HIBERNATION - -static int of_platform_pm_freeze(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->freeze) - ret = drv->pm->freeze(dev); - } else { - ret = of_platform_legacy_suspend(dev, PMSG_FREEZE); - } - - return ret; -} - -static int of_platform_pm_freeze_noirq(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->freeze_noirq) - ret = drv->pm->freeze_noirq(dev); - } - - return ret; -} - -static int of_platform_pm_thaw(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->thaw) - ret = drv->pm->thaw(dev); - } else { - ret = of_platform_legacy_resume(dev); - } - - return ret; -} - -static int of_platform_pm_thaw_noirq(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->thaw_noirq) - ret = drv->pm->thaw_noirq(dev); - } - - return ret; -} - -static int of_platform_pm_poweroff(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->poweroff) - ret = drv->pm->poweroff(dev); - } else { - ret = of_platform_legacy_suspend(dev, PMSG_HIBERNATE); - } - - return ret; -} - -static int of_platform_pm_poweroff_noirq(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->poweroff_noirq) - ret = drv->pm->poweroff_noirq(dev); - } - - return ret; -} - -static int of_platform_pm_restore(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->restore) - ret = drv->pm->restore(dev); - } else { - ret = of_platform_legacy_resume(dev); - } - - return ret; -} - -static int of_platform_pm_restore_noirq(struct device *dev) -{ - struct device_driver *drv = dev->driver; - int ret = 0; - - if (!drv) - return 0; - - if (drv->pm) { - if (drv->pm->restore_noirq) - ret = drv->pm->restore_noirq(dev); - } - - return ret; -} - -#else /* !CONFIG_HIBERNATION */ - -#define of_platform_pm_freeze NULL -#define of_platform_pm_thaw NULL -#define of_platform_pm_poweroff NULL -#define of_platform_pm_restore NULL -#define of_platform_pm_freeze_noirq NULL -#define of_platform_pm_thaw_noirq NULL -#define of_platform_pm_poweroff_noirq NULL -#define of_platform_pm_restore_noirq NULL - -#endif /* !CONFIG_HIBERNATION */ - -static struct dev_pm_ops of_platform_dev_pm_ops = { - .prepare = of_platform_pm_prepare, - .complete = of_platform_pm_complete, - .suspend = of_platform_pm_suspend, - .resume = of_platform_pm_resume, - .freeze = of_platform_pm_freeze, - .thaw = of_platform_pm_thaw, - .poweroff = of_platform_pm_poweroff, - .restore = of_platform_pm_restore, - .suspend_noirq = of_platform_pm_suspend_noirq, - .resume_noirq = of_platform_pm_resume_noirq, - .freeze_noirq = of_platform_pm_freeze_noirq, - .thaw_noirq = of_platform_pm_thaw_noirq, - .poweroff_noirq = of_platform_pm_poweroff_noirq, - .restore_noirq = of_platform_pm_restore_noirq, -}; - -#define OF_PLATFORM_PM_OPS_PTR (&of_platform_dev_pm_ops) - -#else /* !CONFIG_PM_SLEEP */ - -#define OF_PLATFORM_PM_OPS_PTR NULL - -#endif /* !CONFIG_PM_SLEEP */ - -int of_bus_type_init(struct bus_type *bus, const char *name) -{ - bus->name = name; - bus->match = of_platform_bus_match; - bus->probe = of_platform_device_probe; - bus->remove = of_platform_device_remove; - bus->shutdown = of_platform_device_shutdown; - bus->dev_attrs = of_platform_device_attrs; - bus->pm = OF_PLATFORM_PM_OPS_PTR; - return bus_register(bus); -} - -int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) -{ - /* - * Temporary: of_platform_bus used to be distinct from the platform - * bus. It isn't anymore, and so drivers on the platform bus need - * to be registered in a special way. - * - * After all of_platform_bus_type drivers are converted to - * platform_drivers, this exception can be removed. - */ - if (bus == &platform_bus_type) - return of_register_platform_driver(drv); - - /* register with core */ - drv->driver.bus = bus; - return driver_register(&drv->driver); -} -EXPORT_SYMBOL(of_register_driver); - -void of_unregister_driver(struct of_platform_driver *drv) -{ - if (drv->driver.bus == &platform_bus_type) - of_unregister_platform_driver(drv); - else - driver_unregister(&drv->driver); -} -EXPORT_SYMBOL(of_unregister_driver); - #if !defined(CONFIG_SPARC) /* * The following routines scan a subtree and registers a device for diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index a68716ad38ce..048949fa1d10 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -47,10 +47,6 @@ struct of_platform_driver #define to_of_platform_driver(drv) \ container_of(drv,struct of_platform_driver, driver) -extern int of_register_driver(struct of_platform_driver *drv, - struct bus_type *bus); -extern void of_unregister_driver(struct of_platform_driver *drv); - /* Platform drivers register/unregister */ extern int of_register_platform_driver(struct of_platform_driver *drv); extern void of_unregister_platform_driver(struct of_platform_driver *drv); @@ -60,8 +56,6 @@ extern struct platform_device *of_device_alloc(struct device_node *np, struct device *parent); extern struct platform_device *of_find_device_by_node(struct device_node *np); -extern int of_bus_type_init(struct bus_type *bus, const char *name); - #if !defined(CONFIG_SPARC) /* SPARC has its own device registration method */ /* Platform devices and busses creation */ extern struct platform_device *of_platform_device_create(struct device_node *np, -- cgit v1.2.3 From 000061245a6797d542854106463b6b20fbdcb12e Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 22 Feb 2011 19:59:54 -0700 Subject: dt/powerpc: Eliminate users of of_platform_{,un}register_driver Get rid of old users of of_platform_driver in arch/powerpc. Most of_platform_driver users can be converted to use the platform_bus directly. Signed-off-by: Grant Likely --- arch/powerpc/kernel/of_platform.c | 7 +++---- arch/powerpc/platforms/52xx/mpc52xx_gpio.c | 14 ++++++-------- arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 10 +++------- arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c | 11 ++++------- arch/powerpc/platforms/82xx/ep8248e.c | 7 +++---- arch/powerpc/platforms/83xx/suspend.c | 14 +++++++++----- arch/powerpc/platforms/cell/axon_msi.c | 11 ++++------- arch/powerpc/platforms/pasemi/gpio_mdio.c | 9 ++++----- arch/powerpc/sysdev/axonram.c | 11 +++++------ arch/powerpc/sysdev/bestcomm/bestcomm.c | 9 ++++----- arch/powerpc/sysdev/fsl_85xx_l2ctlr.c | 9 ++++----- arch/powerpc/sysdev/fsl_msi.c | 13 ++++++++----- arch/powerpc/sysdev/fsl_pmc.c | 7 +++---- arch/powerpc/sysdev/fsl_rio.c | 7 +++---- arch/powerpc/sysdev/pmi.c | 9 ++++----- arch/powerpc/sysdev/qe_lib/qe.c | 7 +++---- drivers/char/hw_random/pasemi-rng.c | 9 ++++----- drivers/crypto/amcc/crypto4xx_core.c | 9 ++++----- drivers/dma/fsldma.c | 14 +++----------- drivers/dma/mpc512x_dma.c | 9 ++++----- drivers/dma/ppc4xx/adma.c | 11 +++++------ drivers/edac/mpc85xx_edac.c | 27 ++++++++++++--------------- drivers/edac/ppc4xx_edac.c | 23 +++++++---------------- drivers/macintosh/smu.c | 7 +++---- drivers/macintosh/therm_pm72.c | 8 ++++---- drivers/macintosh/therm_windtunnel.c | 9 ++++----- 26 files changed, 120 insertions(+), 161 deletions(-) (limited to 'drivers') diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 9bd951c67767..24582181b6ec 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -36,8 +36,7 @@ * lacking some bits needed here. */ -static int __devinit of_pci_phb_probe(struct platform_device *dev, - const struct of_device_id *match) +static int __devinit of_pci_phb_probe(struct platform_device *dev) { struct pci_controller *phb; @@ -104,7 +103,7 @@ static struct of_device_id of_pci_phb_ids[] = { {} }; -static struct of_platform_driver of_pci_phb_driver = { +static struct platform_driver of_pci_phb_driver = { .probe = of_pci_phb_probe, .driver = { .name = "of-pci", @@ -115,7 +114,7 @@ static struct of_platform_driver of_pci_phb_driver = { static __init int of_pci_phb_init(void) { - return of_register_platform_driver(&of_pci_phb_driver); + return platform_driver_register(&of_pci_phb_driver); } device_initcall(of_pci_phb_init); diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index 0dad9a935eb5..1757d1db4b51 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c @@ -147,8 +147,7 @@ mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) return 0; } -static int __devinit mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev) { struct mpc52xx_gpiochip *chip; struct mpc52xx_gpio_wkup __iomem *regs; @@ -191,7 +190,7 @@ static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = { {} }; -static struct of_platform_driver mpc52xx_wkup_gpiochip_driver = { +static struct platform_driver mpc52xx_wkup_gpiochip_driver = { .driver = { .name = "gpio_wkup", .owner = THIS_MODULE, @@ -310,8 +309,7 @@ mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) return 0; } -static int __devinit mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev) { struct mpc52xx_gpiochip *chip; struct gpio_chip *gc; @@ -349,7 +347,7 @@ static const struct of_device_id mpc52xx_simple_gpiochip_match[] = { {} }; -static struct of_platform_driver mpc52xx_simple_gpiochip_driver = { +static struct platform_driver mpc52xx_simple_gpiochip_driver = { .driver = { .name = "gpio", .owner = THIS_MODULE, @@ -361,10 +359,10 @@ static struct of_platform_driver mpc52xx_simple_gpiochip_driver = { static int __init mpc52xx_gpio_init(void) { - if (of_register_platform_driver(&mpc52xx_wkup_gpiochip_driver)) + if (platform_driver_register(&mpc52xx_wkup_gpiochip_driver)) printk(KERN_ERR "Unable to register wakeup GPIO driver\n"); - if (of_register_platform_driver(&mpc52xx_simple_gpiochip_driver)) + if (platform_driver_register(&mpc52xx_simple_gpiochip_driver)) printk(KERN_ERR "Unable to register simple GPIO driver\n"); return 0; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index e0d703c7fdf7..859abf1c6d4b 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -721,8 +721,7 @@ static inline int mpc52xx_gpt_wdt_setup(struct mpc52xx_gpt_priv *gpt, /* --------------------------------------------------------------------- * of_platform bus binding code */ -static int __devinit mpc52xx_gpt_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit mpc52xx_gpt_probe(struct platform_device *ofdev) { struct mpc52xx_gpt_priv *gpt; @@ -781,7 +780,7 @@ static const struct of_device_id mpc52xx_gpt_match[] = { {} }; -static struct of_platform_driver mpc52xx_gpt_driver = { +static struct platform_driver mpc52xx_gpt_driver = { .driver = { .name = "mpc52xx-gpt", .owner = THIS_MODULE, @@ -793,10 +792,7 @@ static struct of_platform_driver mpc52xx_gpt_driver = { static int __init mpc52xx_gpt_init(void) { - if (of_register_platform_driver(&mpc52xx_gpt_driver)) - pr_err("error registering MPC52xx GPT driver\n"); - - return 0; + return platform_driver_register(&mpc52xx_gpt_driver); } /* Make sure GPIOs and IRQs get set up before anyone tries to use them */ diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c index f4ac213c89c0..6385d883cb8d 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c @@ -436,8 +436,7 @@ void mpc52xx_lpbfifo_abort(struct mpc52xx_lpbfifo_request *req) } EXPORT_SYMBOL(mpc52xx_lpbfifo_abort); -static int __devinit mpc52xx_lpbfifo_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit mpc52xx_lpbfifo_probe(struct platform_device *op) { struct resource res; int rc = -ENOMEM; @@ -536,7 +535,7 @@ static struct of_device_id mpc52xx_lpbfifo_match[] __devinitconst = { {}, }; -static struct of_platform_driver mpc52xx_lpbfifo_driver = { +static struct platform_driver mpc52xx_lpbfifo_driver = { .driver = { .name = "mpc52xx-lpbfifo", .owner = THIS_MODULE, @@ -551,14 +550,12 @@ static struct of_platform_driver mpc52xx_lpbfifo_driver = { */ static int __init mpc52xx_lpbfifo_init(void) { - pr_debug("Registering LocalPlus bus FIFO driver\n"); - return of_register_platform_driver(&mpc52xx_lpbfifo_driver); + return platform_driver_register(&mpc52xx_lpbfifo_driver); } module_init(mpc52xx_lpbfifo_init); static void __exit mpc52xx_lpbfifo_exit(void) { - pr_debug("Unregistering LocalPlus bus FIFO driver\n"); - of_unregister_platform_driver(&mpc52xx_lpbfifo_driver); + platform_driver_unregister(&mpc52xx_lpbfifo_driver); } module_exit(mpc52xx_lpbfifo_exit); diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c index 1565e0446dc8..10ff526cd046 100644 --- a/arch/powerpc/platforms/82xx/ep8248e.c +++ b/arch/powerpc/platforms/82xx/ep8248e.c @@ -111,8 +111,7 @@ static struct mdiobb_ctrl ep8248e_mdio_ctrl = { .ops = &ep8248e_mdio_ops, }; -static int __devinit ep8248e_mdio_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit ep8248e_mdio_probe(struct platform_device *ofdev) { struct mii_bus *bus; struct resource res; @@ -167,7 +166,7 @@ static const struct of_device_id ep8248e_mdio_match[] = { {}, }; -static struct of_platform_driver ep8248e_mdio_driver = { +static struct platform_driver ep8248e_mdio_driver = { .driver = { .name = "ep8248e-mdio-bitbang", .owner = THIS_MODULE, @@ -308,7 +307,7 @@ static __initdata struct of_device_id of_bus_ids[] = { static int __init declare_of_platform_devices(void) { of_platform_bus_probe(NULL, of_bus_ids, NULL); - of_register_platform_driver(&ep8248e_mdio_driver); + platform_driver_register(&ep8248e_mdio_driver); return 0; } diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index fd4f2f2f19e6..188272934cfb 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -318,14 +318,18 @@ static const struct platform_suspend_ops mpc83xx_suspend_ops = { .end = mpc83xx_suspend_end, }; -static int pmc_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int pmc_probe(struct platform_device *ofdev) { struct device_node *np = ofdev->dev.of_node; struct resource res; - struct pmc_type *type = match->data; + struct pmc_type *type; int ret = 0; + if (!ofdev->dev.of_match) + return -EINVAL; + + type = ofdev->dev.of_match->data; + if (!of_device_is_available(np)) return -ENODEV; @@ -422,7 +426,7 @@ static struct of_device_id pmc_match[] = { {} }; -static struct of_platform_driver pmc_driver = { +static struct platform_driver pmc_driver = { .driver = { .name = "mpc83xx-pmc", .owner = THIS_MODULE, @@ -434,7 +438,7 @@ static struct of_platform_driver pmc_driver = { static int pmc_init(void) { - return of_register_platform_driver(&pmc_driver); + return platform_driver_register(&pmc_driver); } module_init(pmc_init); diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index e3e379c6caa7..c35099af340e 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -328,7 +328,7 @@ static struct irq_host_ops msic_host_ops = { .map = msic_host_map, }; -static int axon_msi_shutdown(struct platform_device *device) +static void axon_msi_shutdown(struct platform_device *device) { struct axon_msic *msic = dev_get_drvdata(&device->dev); u32 tmp; @@ -338,12 +338,9 @@ static int axon_msi_shutdown(struct platform_device *device) tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG); tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE; msic_dcr_write(msic, MSIC_CTRL_REG, tmp); - - return 0; } -static int axon_msi_probe(struct platform_device *device, - const struct of_device_id *device_id) +static int axon_msi_probe(struct platform_device *device) { struct device_node *dn = device->dev.of_node; struct axon_msic *msic; @@ -446,7 +443,7 @@ static const struct of_device_id axon_msi_device_id[] = { {} }; -static struct of_platform_driver axon_msi_driver = { +static struct platform_driver axon_msi_driver = { .probe = axon_msi_probe, .shutdown = axon_msi_shutdown, .driver = { @@ -458,7 +455,7 @@ static struct of_platform_driver axon_msi_driver = { static int __init axon_msi_init(void) { - return of_register_platform_driver(&axon_msi_driver); + return platform_driver_register(&axon_msi_driver); } subsys_initcall(axon_msi_init); diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c index a5d907b5a4c2..9886296e08da 100644 --- a/arch/powerpc/platforms/pasemi/gpio_mdio.c +++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c @@ -216,8 +216,7 @@ static int gpio_mdio_reset(struct mii_bus *bus) } -static int __devinit gpio_mdio_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit gpio_mdio_probe(struct platform_device *ofdev) { struct device *dev = &ofdev->dev; struct device_node *np = ofdev->dev.of_node; @@ -299,7 +298,7 @@ static struct of_device_id gpio_mdio_match[] = }; MODULE_DEVICE_TABLE(of, gpio_mdio_match); -static struct of_platform_driver gpio_mdio_driver = +static struct platform_driver gpio_mdio_driver = { .probe = gpio_mdio_probe, .remove = gpio_mdio_remove, @@ -326,13 +325,13 @@ int gpio_mdio_init(void) if (!gpio_regs) return -ENODEV; - return of_register_platform_driver(&gpio_mdio_driver); + return platform_driver_register(&gpio_mdio_driver); } module_init(gpio_mdio_init); void gpio_mdio_exit(void) { - of_unregister_platform_driver(&gpio_mdio_driver); + platform_driver_unregister(&gpio_mdio_driver); if (gpio_regs) iounmap(gpio_regs); } diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c index 2659a60bd7b8..27402c7d309d 100644 --- a/arch/powerpc/sysdev/axonram.c +++ b/arch/powerpc/sysdev/axonram.c @@ -172,10 +172,9 @@ static const struct block_device_operations axon_ram_devops = { /** * axon_ram_probe - probe() method for platform driver - * @device, @device_id: see of_platform_driver method + * @device: see platform_driver method */ -static int axon_ram_probe(struct platform_device *device, - const struct of_device_id *device_id) +static int axon_ram_probe(struct platform_device *device) { static int axon_ram_bank_id = -1; struct axon_ram_bank *bank; @@ -326,7 +325,7 @@ static struct of_device_id axon_ram_device_id[] = { {} }; -static struct of_platform_driver axon_ram_driver = { +static struct platform_driver axon_ram_driver = { .probe = axon_ram_probe, .remove = axon_ram_remove, .driver = { @@ -350,7 +349,7 @@ axon_ram_init(void) } azfs_minor = 0; - return of_register_platform_driver(&axon_ram_driver); + return platform_driver_register(&axon_ram_driver); } /** @@ -359,7 +358,7 @@ axon_ram_init(void) static void __exit axon_ram_exit(void) { - of_unregister_platform_driver(&axon_ram_driver); + platform_driver_unregister(&axon_ram_driver); unregister_blkdev(azfs_major, AXON_RAM_DEVICE_NAME); } diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c index 650256115064..b3fbb271be87 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm.c +++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c @@ -365,8 +365,7 @@ bcom_engine_cleanup(void) /* OF platform driver */ /* ======================================================================== */ -static int __devinit mpc52xx_bcom_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit mpc52xx_bcom_probe(struct platform_device *op) { struct device_node *ofn_sram; struct resource res_bcom; @@ -492,7 +491,7 @@ static struct of_device_id mpc52xx_bcom_of_match[] = { MODULE_DEVICE_TABLE(of, mpc52xx_bcom_of_match); -static struct of_platform_driver mpc52xx_bcom_of_platform_driver = { +static struct platform_driver mpc52xx_bcom_of_platform_driver = { .probe = mpc52xx_bcom_probe, .remove = mpc52xx_bcom_remove, .driver = { @@ -510,13 +509,13 @@ static struct of_platform_driver mpc52xx_bcom_of_platform_driver = { static int __init mpc52xx_bcom_init(void) { - return of_register_platform_driver(&mpc52xx_bcom_of_platform_driver); + return platform_driver_register(&mpc52xx_bcom_of_platform_driver); } static void __exit mpc52xx_bcom_exit(void) { - of_unregister_platform_driver(&mpc52xx_bcom_of_platform_driver); + platform_driver_unregister(&mpc52xx_bcom_of_platform_driver); } /* If we're not a module, we must make sure everything is setup before */ diff --git a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c index cc8d6556d799..2b9f0c925326 100644 --- a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c +++ b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c @@ -71,8 +71,7 @@ static int __init get_offset_from_cmdline(char *str) __setup("cache-sram-size=", get_size_from_cmdline); __setup("cache-sram-offset=", get_offset_from_cmdline); -static int __devinit mpc85xx_l2ctlr_of_probe(struct platform_device *dev, - const struct of_device_id *match) +static int __devinit mpc85xx_l2ctlr_of_probe(struct platform_device *dev) { long rval; unsigned int rem; @@ -204,7 +203,7 @@ static struct of_device_id mpc85xx_l2ctlr_of_match[] = { {}, }; -static struct of_platform_driver mpc85xx_l2ctlr_of_platform_driver = { +static struct platform_driver mpc85xx_l2ctlr_of_platform_driver = { .driver = { .name = "fsl-l2ctlr", .owner = THIS_MODULE, @@ -216,12 +215,12 @@ static struct of_platform_driver mpc85xx_l2ctlr_of_platform_driver = { static __init int mpc85xx_l2ctlr_of_init(void) { - return of_register_platform_driver(&mpc85xx_l2ctlr_of_platform_driver); + return platform_driver_register(&mpc85xx_l2ctlr_of_platform_driver); } static void __exit mpc85xx_l2ctlr_of_exit(void) { - of_unregister_platform_driver(&mpc85xx_l2ctlr_of_platform_driver); + platform_driver_unregister(&mpc85xx_l2ctlr_of_platform_driver); } subsys_initcall(mpc85xx_l2ctlr_of_init); diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 108d76fa8f1c..ee6a8a52ac71 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -273,8 +273,7 @@ static int fsl_of_msi_remove(struct platform_device *ofdev) return 0; } -static int __devinit fsl_of_msi_probe(struct platform_device *dev, - const struct of_device_id *match) +static int __devinit fsl_of_msi_probe(struct platform_device *dev) { struct fsl_msi *msi; struct resource res; @@ -282,11 +281,15 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev, int rc; int virt_msir; const u32 *p; - struct fsl_msi_feature *features = match->data; + struct fsl_msi_feature *features; struct fsl_msi_cascade_data *cascade_data = NULL; int len; u32 offset; + if (!dev->dev.of_match) + return -EINVAL; + features = dev->dev.of_match->data; + printk(KERN_DEBUG "Setting up Freescale MSI support\n"); msi = kzalloc(sizeof(struct fsl_msi), GFP_KERNEL); @@ -411,7 +414,7 @@ static const struct of_device_id fsl_of_msi_ids[] = { {} }; -static struct of_platform_driver fsl_of_msi_driver = { +static struct platform_driver fsl_of_msi_driver = { .driver = { .name = "fsl-msi", .owner = THIS_MODULE, @@ -423,7 +426,7 @@ static struct of_platform_driver fsl_of_msi_driver = { static __init int fsl_of_msi_init(void) { - return of_register_platform_driver(&fsl_of_msi_driver); + return platform_driver_register(&fsl_of_msi_driver); } subsys_initcall(fsl_of_msi_init); diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index e9381bfefb21..f122e8961d32 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c @@ -58,8 +58,7 @@ static const struct platform_suspend_ops pmc_suspend_ops = { .enter = pmc_suspend_enter, }; -static int pmc_probe(struct platform_device *ofdev, - const struct of_device_id *id) +static int pmc_probe(struct platform_device *ofdev) { pmc_regs = of_iomap(ofdev->dev.of_node, 0); if (!pmc_regs) @@ -76,7 +75,7 @@ static const struct of_device_id pmc_ids[] = { { }, }; -static struct of_platform_driver pmc_driver = { +static struct platform_driver pmc_driver = { .driver = { .name = "fsl-pmc", .owner = THIS_MODULE, @@ -87,6 +86,6 @@ static struct of_platform_driver pmc_driver = { static int __init pmc_init(void) { - return of_register_platform_driver(&pmc_driver); + return platform_driver_register(&pmc_driver); } device_initcall(pmc_init); diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 8c6cab013278..3eff2c3a9ad5 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -1570,8 +1570,7 @@ err_ops: /* The probe function for RapidIO peer-to-peer network. */ -static int __devinit fsl_of_rio_rpn_probe(struct platform_device *dev, - const struct of_device_id *match) +static int __devinit fsl_of_rio_rpn_probe(struct platform_device *dev) { int rc; printk(KERN_INFO "Setting up RapidIO peer-to-peer network %s\n", @@ -1594,7 +1593,7 @@ static const struct of_device_id fsl_of_rio_rpn_ids[] = { {}, }; -static struct of_platform_driver fsl_of_rio_rpn_driver = { +static struct platform_driver fsl_of_rio_rpn_driver = { .driver = { .name = "fsl-of-rio", .owner = THIS_MODULE, @@ -1605,7 +1604,7 @@ static struct of_platform_driver fsl_of_rio_rpn_driver = { static __init int fsl_of_rio_rpn_init(void) { - return of_register_platform_driver(&fsl_of_rio_rpn_driver); + return platform_driver_register(&fsl_of_rio_rpn_driver); } subsys_initcall(fsl_of_rio_rpn_init); diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c index 4260f368db52..8ce4fc3d9828 100644 --- a/arch/powerpc/sysdev/pmi.c +++ b/arch/powerpc/sysdev/pmi.c @@ -121,8 +121,7 @@ static void pmi_notify_handlers(struct work_struct *work) spin_unlock(&data->handler_spinlock); } -static int pmi_of_probe(struct platform_device *dev, - const struct of_device_id *match) +static int pmi_of_probe(struct platform_device *dev) { struct device_node *np = dev->dev.of_node; int rc; @@ -205,7 +204,7 @@ static int pmi_of_remove(struct platform_device *dev) return 0; } -static struct of_platform_driver pmi_of_platform_driver = { +static struct platform_driver pmi_of_platform_driver = { .probe = pmi_of_probe, .remove = pmi_of_remove, .driver = { @@ -217,13 +216,13 @@ static struct of_platform_driver pmi_of_platform_driver = { static int __init pmi_module_init(void) { - return of_register_platform_driver(&pmi_of_platform_driver); + return platform_driver_register(&pmi_of_platform_driver); } module_init(pmi_module_init); static void __exit pmi_module_exit(void) { - of_unregister_platform_driver(&pmi_of_platform_driver); + platform_driver_unregister(&pmi_of_platform_driver); } module_exit(pmi_module_exit); diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 90020de4dcf2..904c6cbaf45b 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c @@ -659,8 +659,7 @@ static int qe_resume(struct platform_device *ofdev) return 0; } -static int qe_probe(struct platform_device *ofdev, - const struct of_device_id *id) +static int qe_probe(struct platform_device *ofdev) { return 0; } @@ -670,7 +669,7 @@ static const struct of_device_id qe_ids[] = { { }, }; -static struct of_platform_driver qe_driver = { +static struct platform_driver qe_driver = { .driver = { .name = "fsl-qe", .owner = THIS_MODULE, @@ -682,7 +681,7 @@ static struct of_platform_driver qe_driver = { static int __init qe_drv_init(void) { - return of_register_platform_driver(&qe_driver); + return platform_driver_register(&qe_driver); } device_initcall(qe_drv_init); #endif /* defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) */ diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c index a31c830ca8cd..1d504815e6db 100644 --- a/drivers/char/hw_random/pasemi-rng.c +++ b/drivers/char/hw_random/pasemi-rng.c @@ -94,8 +94,7 @@ static struct hwrng pasemi_rng = { .data_read = pasemi_rng_data_read, }; -static int __devinit rng_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit rng_probe(struct platform_device *ofdev) { void __iomem *rng_regs; struct device_node *rng_np = ofdev->dev.of_node; @@ -139,7 +138,7 @@ static struct of_device_id rng_match[] = { { }, }; -static struct of_platform_driver rng_driver = { +static struct platform_driver rng_driver = { .driver = { .name = "pasemi-rng", .owner = THIS_MODULE, @@ -151,13 +150,13 @@ static struct of_platform_driver rng_driver = { static int __init rng_init(void) { - return of_register_platform_driver(&rng_driver); + return platform_driver_register(&rng_driver); } module_init(rng_init); static void __exit rng_exit(void) { - of_unregister_platform_driver(&rng_driver); + platform_driver_unregister(&rng_driver); } module_exit(rng_exit); diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c index 2b1baee525bc..18912521a7a5 100644 --- a/drivers/crypto/amcc/crypto4xx_core.c +++ b/drivers/crypto/amcc/crypto4xx_core.c @@ -1150,8 +1150,7 @@ struct crypto4xx_alg_common crypto4xx_alg[] = { /** * Module Initialization Routine */ -static int __init crypto4xx_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __init crypto4xx_probe(struct platform_device *ofdev) { int rc; struct resource res; @@ -1280,7 +1279,7 @@ static const struct of_device_id crypto4xx_match[] = { { }, }; -static struct of_platform_driver crypto4xx_driver = { +static struct platform_driver crypto4xx_driver = { .driver = { .name = "crypto4xx", .owner = THIS_MODULE, @@ -1292,12 +1291,12 @@ static struct of_platform_driver crypto4xx_driver = { static int __init crypto4xx_init(void) { - return of_register_platform_driver(&crypto4xx_driver); + return platform_driver_register(&crypto4xx_driver); } static void __exit crypto4xx_exit(void) { - of_unregister_platform_driver(&crypto4xx_driver); + platform_driver_unregister(&crypto4xx_driver); } module_init(crypto4xx_init); diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 4de947a450fc..e3854a8f0de0 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -1281,8 +1281,7 @@ static void fsl_dma_chan_remove(struct fsldma_chan *chan) kfree(chan); } -static int __devinit fsldma_of_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit fsldma_of_probe(struct platform_device *op) { struct fsldma_device *fdev; struct device_node *child; @@ -1414,20 +1413,13 @@ static struct of_platform_driver fsldma_of_driver = { static __init int fsldma_init(void) { - int ret; - pr_info("Freescale Elo / Elo Plus DMA driver\n"); - - ret = of_register_platform_driver(&fsldma_of_driver); - if (ret) - pr_err("fsldma: failed to register platform driver\n"); - - return ret; + return platform_driver_register(&fsldma_of_driver); } static void __exit fsldma_exit(void) { - of_unregister_platform_driver(&fsldma_of_driver); + platform_driver_unregister(&fsldma_of_driver); } subsys_initcall(fsldma_init); diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 59c270192ccc..4f95d31f5a20 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -649,8 +649,7 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src, return &mdesc->desc; } -static int __devinit mpc_dma_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit mpc_dma_probe(struct platform_device *op) { struct device_node *dn = op->dev.of_node; struct device *dev = &op->dev; @@ -827,7 +826,7 @@ static struct of_device_id mpc_dma_match[] = { {}, }; -static struct of_platform_driver mpc_dma_driver = { +static struct platform_driver mpc_dma_driver = { .probe = mpc_dma_probe, .remove = __devexit_p(mpc_dma_remove), .driver = { @@ -839,13 +838,13 @@ static struct of_platform_driver mpc_dma_driver = { static int __init mpc_dma_init(void) { - return of_register_platform_driver(&mpc_dma_driver); + return platform_driver_register(&mpc_dma_driver); } module_init(mpc_dma_init); static void __exit mpc_dma_exit(void) { - of_unregister_platform_driver(&mpc_dma_driver); + platform_driver_unregister(&mpc_dma_driver); } module_exit(mpc_dma_exit); diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index cef584533ee8..3b0247e74cc4 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -4393,8 +4393,7 @@ static void ppc440spe_adma_release_irqs(struct ppc440spe_adma_device *adev, /** * ppc440spe_adma_probe - probe the asynch device */ -static int __devinit ppc440spe_adma_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit ppc440spe_adma_probe(struct platform_device *ofdev) { struct device_node *np = ofdev->dev.of_node; struct resource res; @@ -4944,7 +4943,7 @@ static const struct of_device_id ppc440spe_adma_of_match[] __devinitconst = { }; MODULE_DEVICE_TABLE(of, ppc440spe_adma_of_match); -static struct of_platform_driver ppc440spe_adma_driver = { +static struct platform_driver ppc440spe_adma_driver = { .probe = ppc440spe_adma_probe, .remove = __devexit_p(ppc440spe_adma_remove), .driver = { @@ -4962,7 +4961,7 @@ static __init int ppc440spe_adma_init(void) if (ret) return ret; - ret = of_register_platform_driver(&ppc440spe_adma_driver); + ret = platform_driver_register(&ppc440spe_adma_driver); if (ret) { pr_err("%s: failed to register platform driver\n", __func__); @@ -4996,7 +4995,7 @@ out_dev: /* User will not be able to enable h/w RAID-6 */ pr_err("%s: failed to create RAID-6 driver interface\n", __func__); - of_unregister_platform_driver(&ppc440spe_adma_driver); + platform_driver_unregister(&ppc440spe_adma_driver); out_reg: dcr_unmap(ppc440spe_mq_dcr_host, ppc440spe_mq_dcr_len); kfree(ppc440spe_dma_fifo_buf); @@ -5011,7 +5010,7 @@ static void __exit ppc440spe_adma_exit(void) &driver_attr_enable); driver_remove_file(&ppc440spe_adma_driver.driver, &driver_attr_devices); - of_unregister_platform_driver(&ppc440spe_adma_driver); + platform_driver_unregister(&ppc440spe_adma_driver); dcr_unmap(ppc440spe_mq_dcr_host, ppc440spe_mq_dcr_len); kfree(ppc440spe_dma_fifo_buf); } diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index b123bb308a4a..ffb5ad080bee 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c @@ -200,8 +200,7 @@ static irqreturn_t mpc85xx_pci_isr(int irq, void *dev_id) return IRQ_HANDLED; } -static int __devinit mpc85xx_pci_err_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit mpc85xx_pci_err_probe(struct platform_device *op) { struct edac_pci_ctl_info *pci; struct mpc85xx_pci_pdata *pdata; @@ -338,7 +337,7 @@ static struct of_device_id mpc85xx_pci_err_of_match[] = { }; MODULE_DEVICE_TABLE(of, mpc85xx_pci_err_of_match); -static struct of_platform_driver mpc85xx_pci_err_driver = { +static struct platform_driver mpc85xx_pci_err_driver = { .probe = mpc85xx_pci_err_probe, .remove = __devexit_p(mpc85xx_pci_err_remove), .driver = { @@ -503,8 +502,7 @@ static irqreturn_t mpc85xx_l2_isr(int irq, void *dev_id) return IRQ_HANDLED; } -static int __devinit mpc85xx_l2_err_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit mpc85xx_l2_err_probe(struct platform_device *op) { struct edac_device_ctl_info *edac_dev; struct mpc85xx_l2_pdata *pdata; @@ -656,7 +654,7 @@ static struct of_device_id mpc85xx_l2_err_of_match[] = { }; MODULE_DEVICE_TABLE(of, mpc85xx_l2_err_of_match); -static struct of_platform_driver mpc85xx_l2_err_driver = { +static struct platform_driver mpc85xx_l2_err_driver = { .probe = mpc85xx_l2_err_probe, .remove = mpc85xx_l2_err_remove, .driver = { @@ -956,8 +954,7 @@ static void __devinit mpc85xx_init_csrows(struct mem_ctl_info *mci) } } -static int __devinit mpc85xx_mc_err_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit mpc85xx_mc_err_probe(struct platform_device *op) { struct mem_ctl_info *mci; struct mpc85xx_mc_pdata *pdata; @@ -1136,7 +1133,7 @@ static struct of_device_id mpc85xx_mc_err_of_match[] = { }; MODULE_DEVICE_TABLE(of, mpc85xx_mc_err_of_match); -static struct of_platform_driver mpc85xx_mc_err_driver = { +static struct platform_driver mpc85xx_mc_err_driver = { .probe = mpc85xx_mc_err_probe, .remove = mpc85xx_mc_err_remove, .driver = { @@ -1171,16 +1168,16 @@ static int __init mpc85xx_mc_init(void) break; } - res = of_register_platform_driver(&mpc85xx_mc_err_driver); + res = platform_driver_register(&mpc85xx_mc_err_driver); if (res) printk(KERN_WARNING EDAC_MOD_STR "MC fails to register\n"); - res = of_register_platform_driver(&mpc85xx_l2_err_driver); + res = platform_driver_register(&mpc85xx_l2_err_driver); if (res) printk(KERN_WARNING EDAC_MOD_STR "L2 fails to register\n"); #ifdef CONFIG_PCI - res = of_register_platform_driver(&mpc85xx_pci_err_driver); + res = platform_driver_register(&mpc85xx_pci_err_driver); if (res) printk(KERN_WARNING EDAC_MOD_STR "PCI fails to register\n"); #endif @@ -1212,10 +1209,10 @@ static void __exit mpc85xx_mc_exit(void) on_each_cpu(mpc85xx_mc_restore_hid1, NULL, 0); #endif #ifdef CONFIG_PCI - of_unregister_platform_driver(&mpc85xx_pci_err_driver); + platform_driver_unregister(&mpc85xx_pci_err_driver); #endif - of_unregister_platform_driver(&mpc85xx_l2_err_driver); - of_unregister_platform_driver(&mpc85xx_mc_err_driver); + platform_driver_unregister(&mpc85xx_l2_err_driver); + platform_driver_unregister(&mpc85xx_mc_err_driver); } module_exit(mpc85xx_mc_exit); diff --git a/drivers/edac/ppc4xx_edac.c b/drivers/edac/ppc4xx_edac.c index b9f0c20df1aa..c1f0045ceb8e 100644 --- a/drivers/edac/ppc4xx_edac.c +++ b/drivers/edac/ppc4xx_edac.c @@ -184,8 +184,7 @@ struct ppc4xx_ecc_status { /* Function Prototypes */ -static int ppc4xx_edac_probe(struct platform_device *device, - const struct of_device_id *device_id); +static int ppc4xx_edac_probe(struct platform_device *device) static int ppc4xx_edac_remove(struct platform_device *device); /* Global Variables */ @@ -201,7 +200,7 @@ static struct of_device_id ppc4xx_edac_match[] = { { } }; -static struct of_platform_driver ppc4xx_edac_driver = { +static struct platform_driver ppc4xx_edac_driver = { .probe = ppc4xx_edac_probe, .remove = ppc4xx_edac_remove, .driver = { @@ -997,9 +996,6 @@ ppc4xx_edac_init_csrows(struct mem_ctl_info *mci, u32 mcopt1) * initialized. * @op: A pointer to the OpenFirmware device tree node associated * with the controller this EDAC instance is bound to. - * @match: A pointer to the OpenFirmware device tree match - * information associated with the controller this EDAC instance - * is bound to. * @dcr_host: A pointer to the DCR data containing the DCR mapping * for this controller instance. * @mcopt1: The 32-bit Memory Controller Option 1 register value @@ -1015,7 +1011,6 @@ ppc4xx_edac_init_csrows(struct mem_ctl_info *mci, u32 mcopt1) static int __devinit ppc4xx_edac_mc_init(struct mem_ctl_info *mci, struct platform_device *op, - const struct of_device_id *match, const dcr_host_t *dcr_host, u32 mcopt1) { @@ -1024,7 +1019,7 @@ ppc4xx_edac_mc_init(struct mem_ctl_info *mci, struct ppc4xx_edac_pdata *pdata = NULL; const struct device_node *np = op->dev.of_node; - if (match == NULL) + if (op->dev.of_match == NULL) return -EINVAL; /* Initial driver pointers and private data */ @@ -1227,9 +1222,6 @@ ppc4xx_edac_map_dcrs(const struct device_node *np, dcr_host_t *dcr_host) * ppc4xx_edac_probe - check controller and bind driver * @op: A pointer to the OpenFirmware device tree node associated * with the controller being probed for driver binding. - * @match: A pointer to the OpenFirmware device tree match - * information associated with the controller being probed - * for driver binding. * * This routine probes a specific ibm,sdram-4xx-ddr2 controller * instance for binding with the driver. @@ -1237,8 +1229,7 @@ ppc4xx_edac_map_dcrs(const struct device_node *np, dcr_host_t *dcr_host) * Returns 0 if the controller instance was successfully bound to the * driver; otherwise, < 0 on error. */ -static int __devinit -ppc4xx_edac_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit ppc4xx_edac_probe(struct platform_device *op) { int status = 0; u32 mcopt1, memcheck; @@ -1304,7 +1295,7 @@ ppc4xx_edac_probe(struct platform_device *op, const struct of_device_id *match) goto done; } - status = ppc4xx_edac_mc_init(mci, op, match, &dcr_host, mcopt1); + status = ppc4xx_edac_mc_init(mci, op, &dcr_host, mcopt1); if (status) { ppc4xx_edac_mc_printk(KERN_ERR, mci, @@ -1421,7 +1412,7 @@ ppc4xx_edac_init(void) ppc4xx_edac_opstate_init(); - return of_register_platform_driver(&ppc4xx_edac_driver); + return platform_driver_register(&ppc4xx_edac_driver); } /** @@ -1434,7 +1425,7 @@ ppc4xx_edac_init(void) static void __exit ppc4xx_edac_exit(void) { - of_unregister_platform_driver(&ppc4xx_edac_driver); + platform_driver_unregister(&ppc4xx_edac_driver); } module_init(ppc4xx_edac_init); diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index 290cb325a94c..116a49ce74b2 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c @@ -645,8 +645,7 @@ static void smu_expose_childs(struct work_struct *unused) static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs); -static int smu_platform_probe(struct platform_device* dev, - const struct of_device_id *match) +static int smu_platform_probe(struct platform_device* dev) { if (!smu) return -ENODEV; @@ -669,7 +668,7 @@ static const struct of_device_id smu_platform_match[] = {}, }; -static struct of_platform_driver smu_of_platform_driver = +static struct platform_driver smu_of_platform_driver = { .driver = { .name = "smu", @@ -689,7 +688,7 @@ static int __init smu_init_sysfs(void) * I'm a bit too far from figuring out how that works with those * new chipsets, but that will come back and bite us */ - of_register_platform_driver(&smu_of_platform_driver); + platform_driver_register(&smu_of_platform_driver); return 0; } diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index f3a29f264db9..bca2af2e3760 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -2210,7 +2210,7 @@ static void fcu_lookup_fans(struct device_node *fcu_node) } } -static int fcu_of_probe(struct platform_device* dev, const struct of_device_id *match) +static int fcu_of_probe(struct platform_device* dev) { state = state_detached; of_dev = dev; @@ -2240,7 +2240,7 @@ static const struct of_device_id fcu_match[] = }; MODULE_DEVICE_TABLE(of, fcu_match); -static struct of_platform_driver fcu_of_platform_driver = +static struct platform_driver fcu_of_platform_driver = { .driver = { .name = "temperature", @@ -2263,12 +2263,12 @@ static int __init therm_pm72_init(void) !rackmac) return -ENODEV; - return of_register_platform_driver(&fcu_of_platform_driver); + return platform_driver_register(&fcu_of_platform_driver); } static void __exit therm_pm72_exit(void) { - of_unregister_platform_driver(&fcu_of_platform_driver); + platform_driver_unregister(&fcu_of_platform_driver); } module_init(therm_pm72_init); diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index c89f396e4c53..d37819fd5ad3 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c @@ -443,8 +443,7 @@ static struct i2c_driver g4fan_driver = { /* initialization / cleanup */ /************************************************************************/ -static int -therm_of_probe( struct platform_device *dev, const struct of_device_id *match ) +static int therm_of_probe(struct platform_device *dev) { return i2c_add_driver( &g4fan_driver ); } @@ -462,7 +461,7 @@ static const struct of_device_id therm_of_match[] = {{ }, {} }; -static struct of_platform_driver therm_of_driver = { +static struct platform_driver therm_of_driver = { .driver = { .name = "temperature", .owner = THIS_MODULE, @@ -509,14 +508,14 @@ g4fan_init( void ) return -ENODEV; } - of_register_platform_driver( &therm_of_driver ); + platform_driver_register( &therm_of_driver ); return 0; } static void __exit g4fan_exit( void ) { - of_unregister_platform_driver( &therm_of_driver ); + platform_driver_unregister( &therm_of_driver ); if( x.of_dev ) of_device_unregister( x.of_dev ); -- cgit v1.2.3 From 4ebb24f707187196937607c60810d42f7112d7aa Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 22 Feb 2011 20:01:33 -0700 Subject: dt/sparc: Eliminate users of of_platform_{,un}register_driver Get rid of old users of of_platform_driver in arch/sparc. Most of_platform_driver users can be converted to use the platform_bus directly. Signed-off-by: Grant Likely --- arch/sparc/include/asm/parport.h | 6 +++--- arch/sparc/kernel/apc.c | 7 +++---- arch/sparc/kernel/auxio_64.c | 7 +++---- arch/sparc/kernel/central.c | 14 ++++++-------- arch/sparc/kernel/chmc.c | 19 ++++++++----------- arch/sparc/kernel/pci_fire.c | 7 +++---- arch/sparc/kernel/pci_psycho.c | 7 +++---- arch/sparc/kernel/pci_sabre.c | 9 ++++----- arch/sparc/kernel/pci_schizo.c | 11 ++++++----- arch/sparc/kernel/pci_sun4v.c | 7 +++---- arch/sparc/kernel/pmc.c | 7 +++---- arch/sparc/kernel/power.c | 6 +++--- arch/sparc/kernel/time_32.c | 6 +++--- arch/sparc/kernel/time_64.c | 18 +++++++++--------- drivers/char/hw_random/n2-drv.c | 16 +++++++++------- drivers/crypto/n2_core.c | 20 +++++++++----------- drivers/hwmon/ultra45_env.c | 9 ++++----- drivers/input/misc/sparcspkr.c | 22 ++++++++++------------ drivers/input/serio/i8042-sparcio.h | 8 ++++---- drivers/parport/parport_sunbpp.c | 8 ++++---- drivers/sbus/char/bbc_i2c.c | 9 ++++----- drivers/sbus/char/display7seg.c | 9 ++++----- drivers/sbus/char/envctrl.c | 9 ++++----- drivers/sbus/char/flash.c | 9 ++++----- drivers/sbus/char/uctrl.c | 9 ++++----- drivers/scsi/qlogicpti.c | 14 +++++++++----- drivers/scsi/sun_esp.c | 8 ++++---- 27 files changed, 133 insertions(+), 148 deletions(-) (limited to 'drivers') diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index aa4c82648d88..cb33608cc68f 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h @@ -103,7 +103,7 @@ static inline unsigned int get_dma_residue(unsigned int dmanr) return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info); } -static int __devinit ecpp_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit ecpp_probe(struct platform_device *op) { unsigned long base = op->resource[0].start; unsigned long config = op->resource[1].start; @@ -235,7 +235,7 @@ static const struct of_device_id ecpp_match[] = { {}, }; -static struct of_platform_driver ecpp_driver = { +static struct platform_driver ecpp_driver = { .driver = { .name = "ecpp", .owner = THIS_MODULE, @@ -247,7 +247,7 @@ static struct of_platform_driver ecpp_driver = { static int parport_pc_find_nonpci_ports(int autoirq, int autodma) { - return of_register_platform_driver(&ecpp_driver); + return platform_driver_register(&ecpp_driver); } #endif /* !(_ASM_SPARC64_PARPORT_H */ diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c index 52de4a9424e8..f679c57644d5 100644 --- a/arch/sparc/kernel/apc.c +++ b/arch/sparc/kernel/apc.c @@ -137,8 +137,7 @@ static const struct file_operations apc_fops = { static struct miscdevice apc_miscdev = { APC_MINOR, APC_DEVNAME, &apc_fops }; -static int __devinit apc_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit apc_probe(struct platform_device *op) { int err; @@ -174,7 +173,7 @@ static struct of_device_id __initdata apc_match[] = { }; MODULE_DEVICE_TABLE(of, apc_match); -static struct of_platform_driver apc_driver = { +static struct platform_driver apc_driver = { .driver = { .name = "apc", .owner = THIS_MODULE, @@ -185,7 +184,7 @@ static struct of_platform_driver apc_driver = { static int __init apc_init(void) { - return of_register_platform_driver(&apc_driver); + return platform_driver_register(&apc_driver); } /* This driver is not critical to the boot process diff --git a/arch/sparc/kernel/auxio_64.c b/arch/sparc/kernel/auxio_64.c index 3efd3c5af6a9..2abace076c7d 100644 --- a/arch/sparc/kernel/auxio_64.c +++ b/arch/sparc/kernel/auxio_64.c @@ -102,8 +102,7 @@ static struct of_device_id __initdata auxio_match[] = { MODULE_DEVICE_TABLE(of, auxio_match); -static int __devinit auxio_probe(struct platform_device *dev, - const struct of_device_id *match) +static int __devinit auxio_probe(struct platform_device *dev) { struct device_node *dp = dev->dev.of_node; unsigned long size; @@ -132,7 +131,7 @@ static int __devinit auxio_probe(struct platform_device *dev, return 0; } -static struct of_platform_driver auxio_driver = { +static struct platform_driver auxio_driver = { .probe = auxio_probe, .driver = { .name = "auxio", @@ -143,7 +142,7 @@ static struct of_platform_driver auxio_driver = { static int __init auxio_init(void) { - return of_register_platform_driver(&auxio_driver); + return platform_driver_register(&auxio_driver); } /* Must be after subsys_initcall() so that busses are probed. Must diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index cfa2624c5332..136d3718a74a 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -59,8 +59,7 @@ static int __devinit clock_board_calc_nslots(struct clock_board *p) } } -static int __devinit clock_board_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit clock_board_probe(struct platform_device *op) { struct clock_board *p = kzalloc(sizeof(*p), GFP_KERNEL); int err = -ENOMEM; @@ -148,7 +147,7 @@ static struct of_device_id __initdata clock_board_match[] = { {}, }; -static struct of_platform_driver clock_board_driver = { +static struct platform_driver clock_board_driver = { .probe = clock_board_probe, .driver = { .name = "clock_board", @@ -157,8 +156,7 @@ static struct of_platform_driver clock_board_driver = { }, }; -static int __devinit fhc_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit fhc_probe(struct platform_device *op) { struct fhc *p = kzalloc(sizeof(*p), GFP_KERNEL); int err = -ENOMEM; @@ -254,7 +252,7 @@ static struct of_device_id __initdata fhc_match[] = { {}, }; -static struct of_platform_driver fhc_driver = { +static struct platform_driver fhc_driver = { .probe = fhc_probe, .driver = { .name = "fhc", @@ -265,8 +263,8 @@ static struct of_platform_driver fhc_driver = { static int __init sunfire_init(void) { - (void) of_register_platform_driver(&fhc_driver); - (void) of_register_platform_driver(&clock_board_driver); + (void) platform_driver_register(&fhc_driver); + (void) platform_driver_register(&clock_board_driver); return 0; } diff --git a/arch/sparc/kernel/chmc.c b/arch/sparc/kernel/chmc.c index 08c466ebb32b..668c7be5d365 100644 --- a/arch/sparc/kernel/chmc.c +++ b/arch/sparc/kernel/chmc.c @@ -392,8 +392,7 @@ static void __devinit jbusmc_construct_dimm_groups(struct jbusmc *p, } } -static int __devinit jbusmc_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit jbusmc_probe(struct platform_device *op) { const struct linux_prom64_registers *mem_regs; struct device_node *mem_node; @@ -690,8 +689,7 @@ static void chmc_fetch_decode_regs(struct chmc *p) chmc_read_mcreg(p, CHMCTRL_DECODE4)); } -static int __devinit chmc_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit chmc_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; unsigned long ver; @@ -765,13 +763,12 @@ out_free: goto out; } -static int __devinit us3mc_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit us3mc_probe(struct platform_device *op) { if (mc_type == MC_TYPE_SAFARI) - return chmc_probe(op, match); + return chmc_probe(op); else if (mc_type == MC_TYPE_JBUS) - return jbusmc_probe(op, match); + return jbusmc_probe(op); return -ENODEV; } @@ -810,7 +807,7 @@ static const struct of_device_id us3mc_match[] = { }; MODULE_DEVICE_TABLE(of, us3mc_match); -static struct of_platform_driver us3mc_driver = { +static struct platform_driver us3mc_driver = { .driver = { .name = "us3mc", .owner = THIS_MODULE, @@ -848,7 +845,7 @@ static int __init us3mc_init(void) ret = register_dimm_printer(us3mc_dimm_printer); if (!ret) { - ret = of_register_platform_driver(&us3mc_driver); + ret = platform_driver_register(&us3mc_driver); if (ret) unregister_dimm_printer(us3mc_dimm_printer); } @@ -859,7 +856,7 @@ static void __exit us3mc_cleanup(void) { if (us3mc_platform()) { unregister_dimm_printer(us3mc_dimm_printer); - of_unregister_platform_driver(&us3mc_driver); + platform_driver_unregister(&us3mc_driver); } } diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c index efb896d68754..be5e2441c6d7 100644 --- a/arch/sparc/kernel/pci_fire.c +++ b/arch/sparc/kernel/pci_fire.c @@ -455,8 +455,7 @@ static int __devinit pci_fire_pbm_init(struct pci_pbm_info *pbm, return 0; } -static int __devinit fire_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit fire_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; struct pci_pbm_info *pbm; @@ -507,7 +506,7 @@ static struct of_device_id __initdata fire_match[] = { {}, }; -static struct of_platform_driver fire_driver = { +static struct platform_driver fire_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, @@ -518,7 +517,7 @@ static struct of_platform_driver fire_driver = { static int __init fire_init(void) { - return of_register_platform_driver(&fire_driver); + return platform_driver_register(&fire_driver); } subsys_initcall(fire_init); diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c index 22eab7cf3b11..56ee745064de 100644 --- a/arch/sparc/kernel/pci_psycho.c +++ b/arch/sparc/kernel/pci_psycho.c @@ -503,8 +503,7 @@ static struct pci_pbm_info * __devinit psycho_find_sibling(u32 upa_portid) #define PSYCHO_CONFIGSPACE 0x001000000UL -static int __devinit psycho_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit psycho_probe(struct platform_device *op) { const struct linux_prom64_registers *pr_regs; struct device_node *dp = op->dev.of_node; @@ -601,7 +600,7 @@ static struct of_device_id __initdata psycho_match[] = { {}, }; -static struct of_platform_driver psycho_driver = { +static struct platform_driver psycho_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, @@ -612,7 +611,7 @@ static struct of_platform_driver psycho_driver = { static int __init psycho_init(void) { - return of_register_platform_driver(&psycho_driver); + return platform_driver_register(&psycho_driver); } subsys_initcall(psycho_init); diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c index 5c3f5ec4cabc..2857073342d2 100644 --- a/arch/sparc/kernel/pci_sabre.c +++ b/arch/sparc/kernel/pci_sabre.c @@ -452,8 +452,7 @@ static void __devinit sabre_pbm_init(struct pci_pbm_info *pbm, sabre_scan_bus(pbm, &op->dev); } -static int __devinit sabre_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit sabre_probe(struct platform_device *op) { const struct linux_prom64_registers *pr_regs; struct device_node *dp = op->dev.of_node; @@ -464,7 +463,7 @@ static int __devinit sabre_probe(struct platform_device *op, const u32 *vdma; u64 clear_irq; - hummingbird_p = (match->data != NULL); + hummingbird_p = op->dev.of_match && (op->dev.of_match->data != NULL); if (!hummingbird_p) { struct device_node *cpu_dp; @@ -595,7 +594,7 @@ static struct of_device_id __initdata sabre_match[] = { {}, }; -static struct of_platform_driver sabre_driver = { +static struct platform_driver sabre_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, @@ -606,7 +605,7 @@ static struct of_platform_driver sabre_driver = { static int __init sabre_init(void) { - return of_register_platform_driver(&sabre_driver); + return platform_driver_register(&sabre_driver); } subsys_initcall(sabre_init); diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index 445a47a2fb3d..6783410ceb02 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c @@ -1460,10 +1460,11 @@ out_err: return err; } -static int __devinit schizo_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit schizo_probe(struct platform_device *op) { - return __schizo_init(op, (unsigned long) match->data); + if (!op->dev.of_match) + return -EINVAL; + return __schizo_init(op, (unsigned long) op->dev.of_match->data); } /* The ordering of this table is very important. Some Tomatillo @@ -1490,7 +1491,7 @@ static struct of_device_id __initdata schizo_match[] = { {}, }; -static struct of_platform_driver schizo_driver = { +static struct platform_driver schizo_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, @@ -1501,7 +1502,7 @@ static struct of_platform_driver schizo_driver = { static int __init schizo_init(void) { - return of_register_platform_driver(&schizo_driver); + return platform_driver_register(&schizo_driver); } subsys_initcall(schizo_init); diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 743344aa6d8a..158cd739b263 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -918,8 +918,7 @@ static int __devinit pci_sun4v_pbm_init(struct pci_pbm_info *pbm, return 0; } -static int __devinit pci_sun4v_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit pci_sun4v_probe(struct platform_device *op) { const struct linux_prom64_registers *regs; static int hvapi_negotiated = 0; @@ -1008,7 +1007,7 @@ static struct of_device_id __initdata pci_sun4v_match[] = { {}, }; -static struct of_platform_driver pci_sun4v_driver = { +static struct platform_driver pci_sun4v_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, @@ -1019,7 +1018,7 @@ static struct of_platform_driver pci_sun4v_driver = { static int __init pci_sun4v_init(void) { - return of_register_platform_driver(&pci_sun4v_driver); + return platform_driver_register(&pci_sun4v_driver); } subsys_initcall(pci_sun4v_init); diff --git a/arch/sparc/kernel/pmc.c b/arch/sparc/kernel/pmc.c index 94536a85f161..93d7b4465f8d 100644 --- a/arch/sparc/kernel/pmc.c +++ b/arch/sparc/kernel/pmc.c @@ -51,8 +51,7 @@ static void pmc_swift_idle(void) #endif } -static int __devinit pmc_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit pmc_probe(struct platform_device *op) { regs = of_ioremap(&op->resource[0], 0, resource_size(&op->resource[0]), PMC_OBPNAME); @@ -78,7 +77,7 @@ static struct of_device_id __initdata pmc_match[] = { }; MODULE_DEVICE_TABLE(of, pmc_match); -static struct of_platform_driver pmc_driver = { +static struct platform_driver pmc_driver = { .driver = { .name = "pmc", .owner = THIS_MODULE, @@ -89,7 +88,7 @@ static struct of_platform_driver pmc_driver = { static int __init pmc_init(void) { - return of_register_platform_driver(&pmc_driver); + return platform_driver_register(&pmc_driver); } /* This driver is not critical to the boot process diff --git a/arch/sparc/kernel/power.c b/arch/sparc/kernel/power.c index 2c59f4d387dd..cd725fe238b2 100644 --- a/arch/sparc/kernel/power.c +++ b/arch/sparc/kernel/power.c @@ -33,7 +33,7 @@ static int __devinit has_button_interrupt(unsigned int irq, struct device_node * return 1; } -static int __devinit power_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit power_probe(struct platform_device *op) { struct resource *res = &op->resource[0]; unsigned int irq = op->archdata.irqs[0]; @@ -59,7 +59,7 @@ static struct of_device_id __initdata power_match[] = { {}, }; -static struct of_platform_driver power_driver = { +static struct platform_driver power_driver = { .probe = power_probe, .driver = { .name = "power", @@ -70,7 +70,7 @@ static struct of_platform_driver power_driver = { static int __init power_init(void) { - return of_register_platform_driver(&power_driver); + return platform_driver_register(&power_driver); } device_initcall(power_init); diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index 9c743b1886ff..23ccd737fc79 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c @@ -142,7 +142,7 @@ static struct platform_device m48t59_rtc = { }, }; -static int __devinit clock_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit clock_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; const char *model = of_get_property(dp, "model", NULL); @@ -176,7 +176,7 @@ static struct of_device_id __initdata clock_match[] = { {}, }; -static struct of_platform_driver clock_driver = { +static struct platform_driver clock_driver = { .probe = clock_probe, .driver = { .name = "rtc", @@ -189,7 +189,7 @@ static struct of_platform_driver clock_driver = { /* Probe for the mostek real time clock chip. */ static int __init clock_init(void) { - return of_register_platform_driver(&clock_driver); + return platform_driver_register(&clock_driver); } /* Must be after subsys_initcall() so that busses are probed. Must * be before device_initcall() because things like the RTC driver diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index 3bc9c9979b92..e1862793a61d 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -419,7 +419,7 @@ static struct platform_device rtc_cmos_device = { .num_resources = 1, }; -static int __devinit rtc_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit rtc_probe(struct platform_device *op) { struct resource *r; @@ -462,7 +462,7 @@ static struct of_device_id __initdata rtc_match[] = { {}, }; -static struct of_platform_driver rtc_driver = { +static struct platform_driver rtc_driver = { .probe = rtc_probe, .driver = { .name = "rtc", @@ -477,7 +477,7 @@ static struct platform_device rtc_bq4802_device = { .num_resources = 1, }; -static int __devinit bq4802_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit bq4802_probe(struct platform_device *op) { printk(KERN_INFO "%s: BQ4802 regs at 0x%llx\n", @@ -495,7 +495,7 @@ static struct of_device_id __initdata bq4802_match[] = { {}, }; -static struct of_platform_driver bq4802_driver = { +static struct platform_driver bq4802_driver = { .probe = bq4802_probe, .driver = { .name = "bq4802", @@ -534,7 +534,7 @@ static struct platform_device m48t59_rtc = { }, }; -static int __devinit mostek_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit mostek_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; @@ -559,7 +559,7 @@ static struct of_device_id __initdata mostek_match[] = { {}, }; -static struct of_platform_driver mostek_driver = { +static struct platform_driver mostek_driver = { .probe = mostek_probe, .driver = { .name = "mostek", @@ -586,9 +586,9 @@ static int __init clock_init(void) if (tlb_type == hypervisor) return platform_device_register(&rtc_sun4v_device); - (void) of_register_platform_driver(&rtc_driver); - (void) of_register_platform_driver(&mostek_driver); - (void) of_register_platform_driver(&bq4802_driver); + (void) platform_driver_register(&rtc_driver); + (void) platform_driver_register(&mostek_driver); + (void) platform_driver_register(&bq4802_driver); return 0; } diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index a3f5e381e746..43ac61978d8b 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c @@ -619,15 +619,17 @@ static void __devinit n2rng_driver_version(void) pr_info("%s", version); } -static int __devinit n2rng_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit n2rng_probe(struct platform_device *op) { - int victoria_falls = (match->data != NULL); + int victoria_falls; int err = -ENOMEM; struct n2rng *np; - n2rng_driver_version(); + if (!op->dev.of_match) + return -EINVAL; + victoria_falls = (op->dev.of_match->data != NULL); + n2rng_driver_version(); np = kzalloc(sizeof(*np), GFP_KERNEL); if (!np) goto out; @@ -750,7 +752,7 @@ static const struct of_device_id n2rng_match[] = { }; MODULE_DEVICE_TABLE(of, n2rng_match); -static struct of_platform_driver n2rng_driver = { +static struct platform_driver n2rng_driver = { .driver = { .name = "n2rng", .owner = THIS_MODULE, @@ -762,12 +764,12 @@ static struct of_platform_driver n2rng_driver = { static int __init n2rng_init(void) { - return of_register_platform_driver(&n2rng_driver); + return platform_driver_register(&n2rng_driver); } static void __exit n2rng_exit(void) { - of_unregister_platform_driver(&n2rng_driver); + platform_driver_unregister(&n2rng_driver); } module_init(n2rng_init); diff --git a/drivers/crypto/n2_core.c b/drivers/crypto/n2_core.c index 80dc094e78c6..2e5b2044c96f 100644 --- a/drivers/crypto/n2_core.c +++ b/drivers/crypto/n2_core.c @@ -2004,8 +2004,7 @@ static void __devinit n2_spu_driver_version(void) pr_info("%s", version); } -static int __devinit n2_crypto_probe(struct platform_device *dev, - const struct of_device_id *match) +static int __devinit n2_crypto_probe(struct platform_device *dev) { struct mdesc_handle *mdesc; const char *full_name; @@ -2116,8 +2115,7 @@ static void free_ncp(struct n2_mau *mp) kfree(mp); } -static int __devinit n2_mau_probe(struct platform_device *dev, - const struct of_device_id *match) +static int __devinit n2_mau_probe(struct platform_device *dev) { struct mdesc_handle *mdesc; const char *full_name; @@ -2211,7 +2209,7 @@ static struct of_device_id n2_crypto_match[] = { MODULE_DEVICE_TABLE(of, n2_crypto_match); -static struct of_platform_driver n2_crypto_driver = { +static struct platform_driver n2_crypto_driver = { .driver = { .name = "n2cp", .owner = THIS_MODULE, @@ -2235,7 +2233,7 @@ static struct of_device_id n2_mau_match[] = { MODULE_DEVICE_TABLE(of, n2_mau_match); -static struct of_platform_driver n2_mau_driver = { +static struct platform_driver n2_mau_driver = { .driver = { .name = "ncp", .owner = THIS_MODULE, @@ -2247,20 +2245,20 @@ static struct of_platform_driver n2_mau_driver = { static int __init n2_init(void) { - int err = of_register_platform_driver(&n2_crypto_driver); + int err = platform_driver_register(&n2_crypto_driver); if (!err) { - err = of_register_platform_driver(&n2_mau_driver); + err = platform_driver_register(&n2_mau_driver); if (err) - of_unregister_platform_driver(&n2_crypto_driver); + platform_driver_unregister(&n2_crypto_driver); } return err; } static void __exit n2_exit(void) { - of_unregister_platform_driver(&n2_mau_driver); - of_unregister_platform_driver(&n2_crypto_driver); + platform_driver_unregister(&n2_mau_driver); + platform_driver_unregister(&n2_crypto_driver); } module_init(n2_init); diff --git a/drivers/hwmon/ultra45_env.c b/drivers/hwmon/ultra45_env.c index d863e13a50b8..1f36c635d933 100644 --- a/drivers/hwmon/ultra45_env.c +++ b/drivers/hwmon/ultra45_env.c @@ -234,8 +234,7 @@ static const struct attribute_group env_group = { .attrs = env_attributes, }; -static int __devinit env_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit env_probe(struct platform_device *op) { struct env *p = kzalloc(sizeof(*p), GFP_KERNEL); int err = -ENOMEM; @@ -299,7 +298,7 @@ static const struct of_device_id env_match[] = { }; MODULE_DEVICE_TABLE(of, env_match); -static struct of_platform_driver env_driver = { +static struct platform_driver env_driver = { .driver = { .name = "ultra45_env", .owner = THIS_MODULE, @@ -311,12 +310,12 @@ static struct of_platform_driver env_driver = { static int __init env_init(void) { - return of_register_platform_driver(&env_driver); + return platform_driver_register(&env_driver); } static void __exit env_exit(void) { - of_unregister_platform_driver(&env_driver); + platform_driver_unregister(&env_driver); } module_init(env_init); diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index 8e130bf7d32b..0122f5351577 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c @@ -173,18 +173,16 @@ static int __devinit sparcspkr_probe(struct device *dev) return 0; } -static int sparcspkr_shutdown(struct platform_device *dev) +static void sparcspkr_shutdown(struct platform_device *dev) { struct sparcspkr_state *state = dev_get_drvdata(&dev->dev); struct input_dev *input_dev = state->input_dev; /* turn off the speaker */ state->event(input_dev, EV_SND, SND_BELL, 0); - - return 0; } -static int __devinit bbc_beep_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit bbc_beep_probe(struct platform_device *op) { struct sparcspkr_state *state; struct bbc_beep_info *info; @@ -258,7 +256,7 @@ static const struct of_device_id bbc_beep_match[] = { {}, }; -static struct of_platform_driver bbc_beep_driver = { +static struct platform_driver bbc_beep_driver = { .driver = { .name = "bbcbeep", .owner = THIS_MODULE, @@ -269,7 +267,7 @@ static struct of_platform_driver bbc_beep_driver = { .shutdown = sparcspkr_shutdown, }; -static int __devinit grover_beep_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit grover_beep_probe(struct platform_device *op) { struct sparcspkr_state *state; struct grover_beep_info *info; @@ -340,7 +338,7 @@ static const struct of_device_id grover_beep_match[] = { {}, }; -static struct of_platform_driver grover_beep_driver = { +static struct platform_driver grover_beep_driver = { .driver = { .name = "groverbeep", .owner = THIS_MODULE, @@ -353,12 +351,12 @@ static struct of_platform_driver grover_beep_driver = { static int __init sparcspkr_init(void) { - int err = of_register_platform_driver(&bbc_beep_driver); + int err = platform_driver_register(&bbc_beep_driver); if (!err) { - err = of_register_platform_driver(&grover_beep_driver); + err = platform_driver_register(&grover_beep_driver); if (err) - of_unregister_platform_driver(&bbc_beep_driver); + platform_driver_unregister(&bbc_beep_driver); } return err; @@ -366,8 +364,8 @@ static int __init sparcspkr_init(void) static void __exit sparcspkr_exit(void) { - of_unregister_platform_driver(&bbc_beep_driver); - of_unregister_platform_driver(&grover_beep_driver); + platform_driver_unregister(&bbc_beep_driver); + platform_driver_unregister(&grover_beep_driver); } module_init(sparcspkr_init); diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h index c5cc4508d6df..395a9af3adcd 100644 --- a/drivers/input/serio/i8042-sparcio.h +++ b/drivers/input/serio/i8042-sparcio.h @@ -49,7 +49,7 @@ static inline void i8042_write_command(int val) #define OBP_PS2MS_NAME1 "kdmouse" #define OBP_PS2MS_NAME2 "mouse" -static int __devinit sparc_i8042_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit sparc_i8042_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; @@ -95,7 +95,7 @@ static const struct of_device_id sparc_i8042_match[] = { }; MODULE_DEVICE_TABLE(of, sparc_i8042_match); -static struct of_platform_driver sparc_i8042_driver = { +static struct platform_driver sparc_i8042_driver = { .driver = { .name = "i8042", .owner = THIS_MODULE, @@ -116,7 +116,7 @@ static int __init i8042_platform_init(void) if (!kbd_iobase) return -ENODEV; } else { - int err = of_register_platform_driver(&sparc_i8042_driver); + int err = platform_driver_register(&sparc_i8042_driver); if (err) return err; @@ -140,7 +140,7 @@ static inline void i8042_platform_exit(void) struct device_node *root = of_find_node_by_path("/"); if (strcmp(root->name, "SUNW,JavaStation-1")) - of_unregister_platform_driver(&sparc_i8042_driver); + platform_driver_unregister(&sparc_i8042_driver); } #else /* !CONFIG_PCI */ diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c index 55ba118f1cf1..910c5a26e347 100644 --- a/drivers/parport/parport_sunbpp.c +++ b/drivers/parport/parport_sunbpp.c @@ -286,7 +286,7 @@ static struct parport_operations parport_sunbpp_ops = .owner = THIS_MODULE, }; -static int __devinit bpp_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit bpp_probe(struct platform_device *op) { struct parport_operations *ops; struct bpp_regs __iomem *regs; @@ -381,7 +381,7 @@ static const struct of_device_id bpp_match[] = { MODULE_DEVICE_TABLE(of, bpp_match); -static struct of_platform_driver bpp_sbus_driver = { +static struct platform_driver bpp_sbus_driver = { .driver = { .name = "bpp", .owner = THIS_MODULE, @@ -393,12 +393,12 @@ static struct of_platform_driver bpp_sbus_driver = { static int __init parport_sunbpp_init(void) { - return of_register_platform_driver(&bpp_sbus_driver); + return platform_driver_register(&bpp_sbus_driver); } static void __exit parport_sunbpp_exit(void) { - of_unregister_platform_driver(&bpp_sbus_driver); + platform_driver_unregister(&bpp_sbus_driver); } MODULE_AUTHOR("Derrick J Brashear"); diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c index 614a5e114a19..5f94d22c491e 100644 --- a/drivers/sbus/char/bbc_i2c.c +++ b/drivers/sbus/char/bbc_i2c.c @@ -361,8 +361,7 @@ fail: extern int bbc_envctrl_init(struct bbc_i2c_bus *bp); extern void bbc_envctrl_cleanup(struct bbc_i2c_bus *bp); -static int __devinit bbc_i2c_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit bbc_i2c_probe(struct platform_device *op) { struct bbc_i2c_bus *bp; int err, index = 0; @@ -413,7 +412,7 @@ static const struct of_device_id bbc_i2c_match[] = { }; MODULE_DEVICE_TABLE(of, bbc_i2c_match); -static struct of_platform_driver bbc_i2c_driver = { +static struct platform_driver bbc_i2c_driver = { .driver = { .name = "bbc_i2c", .owner = THIS_MODULE, @@ -425,12 +424,12 @@ static struct of_platform_driver bbc_i2c_driver = { static int __init bbc_i2c_init(void) { - return of_register_platform_driver(&bbc_i2c_driver); + return platform_driver_register(&bbc_i2c_driver); } static void __exit bbc_i2c_exit(void) { - of_unregister_platform_driver(&bbc_i2c_driver); + platform_driver_unregister(&bbc_i2c_driver); } module_init(bbc_i2c_init); diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c index 55f71ea9c418..740da4465447 100644 --- a/drivers/sbus/char/display7seg.c +++ b/drivers/sbus/char/display7seg.c @@ -171,8 +171,7 @@ static struct miscdevice d7s_miscdev = { .fops = &d7s_fops }; -static int __devinit d7s_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit d7s_probe(struct platform_device *op) { struct device_node *opts; int err = -EINVAL; @@ -266,7 +265,7 @@ static const struct of_device_id d7s_match[] = { }; MODULE_DEVICE_TABLE(of, d7s_match); -static struct of_platform_driver d7s_driver = { +static struct platform_driver d7s_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, @@ -278,12 +277,12 @@ static struct of_platform_driver d7s_driver = { static int __init d7s_init(void) { - return of_register_platform_driver(&d7s_driver); + return platform_driver_register(&d7s_driver); } static void __exit d7s_exit(void) { - of_unregister_platform_driver(&d7s_driver); + platform_driver_unregister(&d7s_driver); } module_init(d7s_init); diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index 8ce414e39489..be7b4e56154f 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c @@ -1028,8 +1028,7 @@ static int kenvctrld(void *__unused) return 0; } -static int __devinit envctrl_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit envctrl_probe(struct platform_device *op) { struct device_node *dp; int index, err; @@ -1129,7 +1128,7 @@ static const struct of_device_id envctrl_match[] = { }; MODULE_DEVICE_TABLE(of, envctrl_match); -static struct of_platform_driver envctrl_driver = { +static struct platform_driver envctrl_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, @@ -1141,12 +1140,12 @@ static struct of_platform_driver envctrl_driver = { static int __init envctrl_init(void) { - return of_register_platform_driver(&envctrl_driver); + return platform_driver_register(&envctrl_driver); } static void __exit envctrl_exit(void) { - of_unregister_platform_driver(&envctrl_driver); + platform_driver_unregister(&envctrl_driver); } module_init(envctrl_init); diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index 2b4b4b613c48..73dd4e7afaaa 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c @@ -160,8 +160,7 @@ static const struct file_operations flash_fops = { static struct miscdevice flash_dev = { FLASH_MINOR, "flash", &flash_fops }; -static int __devinit flash_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit flash_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; struct device_node *parent; @@ -207,7 +206,7 @@ static const struct of_device_id flash_match[] = { }; MODULE_DEVICE_TABLE(of, flash_match); -static struct of_platform_driver flash_driver = { +static struct platform_driver flash_driver = { .driver = { .name = "flash", .owner = THIS_MODULE, @@ -219,12 +218,12 @@ static struct of_platform_driver flash_driver = { static int __init flash_init(void) { - return of_register_platform_driver(&flash_driver); + return platform_driver_register(&flash_driver); } static void __exit flash_cleanup(void) { - of_unregister_platform_driver(&flash_driver); + platform_driver_unregister(&flash_driver); } module_init(flash_init); diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index 1b345be5cc02..ebce9639a26a 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c @@ -348,8 +348,7 @@ static void uctrl_get_external_status(struct uctrl_driver *driver) } -static int __devinit uctrl_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit uctrl_probe(struct platform_device *op) { struct uctrl_driver *p; int err = -ENOMEM; @@ -425,7 +424,7 @@ static const struct of_device_id uctrl_match[] = { }; MODULE_DEVICE_TABLE(of, uctrl_match); -static struct of_platform_driver uctrl_driver = { +static struct platform_driver uctrl_driver = { .driver = { .name = "uctrl", .owner = THIS_MODULE, @@ -438,12 +437,12 @@ static struct of_platform_driver uctrl_driver = { static int __init uctrl_init(void) { - return of_register_platform_driver(&uctrl_driver); + return platform_driver_register(&uctrl_driver); } static void __exit uctrl_exit(void) { - of_unregister_platform_driver(&uctrl_driver); + platform_driver_unregister(&uctrl_driver); } module_init(uctrl_init); diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 664c9572d0c9..e2d45c91b8e8 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -1292,15 +1292,19 @@ static struct scsi_host_template qpti_template = { .use_clustering = ENABLE_CLUSTERING, }; -static int __devinit qpti_sbus_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit qpti_sbus_probe(struct platform_device *op) { - struct scsi_host_template *tpnt = match->data; + struct scsi_host_template *tpnt; struct device_node *dp = op->dev.of_node; struct Scsi_Host *host; struct qlogicpti *qpti; static int nqptis; const char *fcode; + if (!op->dev.of_match) + return -EINVAL; + tpnt = op->dev.of_match->data; + /* Sometimes Antares cards come up not completely * setup, and we get a report of a zero IRQ. */ @@ -1457,7 +1461,7 @@ static const struct of_device_id qpti_match[] = { }; MODULE_DEVICE_TABLE(of, qpti_match); -static struct of_platform_driver qpti_sbus_driver = { +static struct platform_driver qpti_sbus_driver = { .driver = { .name = "qpti", .owner = THIS_MODULE, @@ -1469,12 +1473,12 @@ static struct of_platform_driver qpti_sbus_driver = { static int __init qpti_init(void) { - return of_register_platform_driver(&qpti_sbus_driver); + return platform_driver_register(&qpti_sbus_driver); } static void __exit qpti_exit(void) { - of_unregister_platform_driver(&qpti_sbus_driver); + platform_driver_unregister(&qpti_sbus_driver); } MODULE_DESCRIPTION("QlogicISP SBUS driver"); diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c index 193b37ba1834..676fe9ac7f61 100644 --- a/drivers/scsi/sun_esp.c +++ b/drivers/scsi/sun_esp.c @@ -562,7 +562,7 @@ fail: return err; } -static int __devinit esp_sbus_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit esp_sbus_probe(struct platform_device *op) { struct device_node *dma_node = NULL; struct device_node *dp = op->dev.of_node; @@ -632,7 +632,7 @@ static const struct of_device_id esp_match[] = { }; MODULE_DEVICE_TABLE(of, esp_match); -static struct of_platform_driver esp_sbus_driver = { +static struct platform_driver esp_sbus_driver = { .driver = { .name = "esp", .owner = THIS_MODULE, @@ -644,12 +644,12 @@ static struct of_platform_driver esp_sbus_driver = { static int __init sunesp_init(void) { - return of_register_platform_driver(&esp_sbus_driver); + return platform_driver_register(&esp_sbus_driver); } static void __exit sunesp_exit(void) { - of_unregister_platform_driver(&esp_sbus_driver); + platform_driver_unregister(&esp_sbus_driver); } MODULE_DESCRIPTION("Sun ESP SCSI driver"); -- cgit v1.2.3 From a314c5c0040aab51ebb1ecfd37a9198a91962243 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 22 Feb 2011 20:06:04 -0700 Subject: leds/leds-gpio: merge platform_driver with of_platform_driver Both interfaces can be driven with the same driver, and of_platform_driver is getting removed. This patch merges the two driver registrations. Signed-off-by: Grant Likely --- drivers/leds/leds-gpio.c | 214 +++++++++++++++++++---------------------------- 1 file changed, 87 insertions(+), 127 deletions(-) (limited to 'drivers') diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 4d9fa38d9ff6..b0480c8fbcbf 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include @@ -151,96 +153,34 @@ static void delete_gpio_led(struct gpio_led_data *led) gpio_free(led->gpio); } -#ifdef CONFIG_LEDS_GPIO_PLATFORM -static int __devinit gpio_led_probe(struct platform_device *pdev) -{ - struct gpio_led_platform_data *pdata = pdev->dev.platform_data; - struct gpio_led_data *leds_data; - int i, ret = 0; - - if (!pdata) - return -EBUSY; - - leds_data = kzalloc(sizeof(struct gpio_led_data) * pdata->num_leds, - GFP_KERNEL); - if (!leds_data) - return -ENOMEM; - - for (i = 0; i < pdata->num_leds; i++) { - ret = create_gpio_led(&pdata->leds[i], &leds_data[i], - &pdev->dev, pdata->gpio_blink_set); - if (ret < 0) - goto err; - } - - platform_set_drvdata(pdev, leds_data); - - return 0; - -err: - for (i = i - 1; i >= 0; i--) - delete_gpio_led(&leds_data[i]); - - kfree(leds_data); - - return ret; -} +struct gpio_leds_priv { + int num_leds; + struct gpio_led_data leds[]; +}; -static int __devexit gpio_led_remove(struct platform_device *pdev) +static inline int sizeof_gpio_leds_priv(int num_leds) { - int i; - struct gpio_led_platform_data *pdata = pdev->dev.platform_data; - struct gpio_led_data *leds_data; - - leds_data = platform_get_drvdata(pdev); - - for (i = 0; i < pdata->num_leds; i++) - delete_gpio_led(&leds_data[i]); - - kfree(leds_data); - - return 0; + return sizeof(struct gpio_leds_priv) + + (sizeof(struct gpio_led_data) * num_leds); } -static struct platform_driver gpio_led_driver = { - .probe = gpio_led_probe, - .remove = __devexit_p(gpio_led_remove), - .driver = { - .name = "leds-gpio", - .owner = THIS_MODULE, - }, -}; - -MODULE_ALIAS("platform:leds-gpio"); -#endif /* CONFIG_LEDS_GPIO_PLATFORM */ - /* Code to create from OpenFirmware platform devices */ #ifdef CONFIG_LEDS_GPIO_OF -#include -#include - -struct gpio_led_of_platform_data { - int num_leds; - struct gpio_led_data led_data[]; -}; - -static int __devinit of_gpio_leds_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_device *pdev) { - struct device_node *np = ofdev->dev.of_node, *child; - struct gpio_led_of_platform_data *pdata; + struct device_node *np = pdev->dev.of_node, *child; + struct gpio_leds_priv *priv; int count = 0, ret; - /* count LEDs defined by this device, so we know how much to allocate */ + /* count LEDs in this device, so we know how much to allocate */ for_each_child_of_node(np, child) count++; if (!count) - return 0; /* or ENODEV? */ + return NULL; - pdata = kzalloc(sizeof(*pdata) + sizeof(struct gpio_led_data) * count, - GFP_KERNEL); - if (!pdata) - return -ENOMEM; + priv = kzalloc(sizeof_gpio_leds_priv(count), GFP_KERNEL); + if (!priv) + return NULL; for_each_child_of_node(np, child) { struct gpio_led led = {}; @@ -256,92 +196,112 @@ static int __devinit of_gpio_leds_probe(struct platform_device *ofdev, if (state) { if (!strcmp(state, "keep")) led.default_state = LEDS_GPIO_DEFSTATE_KEEP; - else if(!strcmp(state, "on")) + else if (!strcmp(state, "on")) led.default_state = LEDS_GPIO_DEFSTATE_ON; else led.default_state = LEDS_GPIO_DEFSTATE_OFF; } - ret = create_gpio_led(&led, &pdata->led_data[pdata->num_leds++], - &ofdev->dev, NULL); + ret = create_gpio_led(&led, &priv->leds[priv->num_leds++], + &pdev->dev, NULL); if (ret < 0) { of_node_put(child); goto err; } } - dev_set_drvdata(&ofdev->dev, pdata); - - return 0; + return priv; err: - for (count = pdata->num_leds - 2; count >= 0; count--) - delete_gpio_led(&pdata->led_data[count]); + for (count = priv->num_leds - 2; count >= 0; count--) + delete_gpio_led(&priv->leds[count]); + kfree(priv); + return NULL; +} - kfree(pdata); +static const struct of_device_id of_gpio_leds_match[] = { + { .compatible = "gpio-leds", }, + {}, +}; +#else +static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_device *pdev) +{ + return NULL; +} +#define of_gpio_leds_match NULL +#endif - return ret; + +static int __devinit gpio_led_probe(struct platform_device *pdev) +{ + struct gpio_led_platform_data *pdata = pdev->dev.platform_data; + struct gpio_leds_priv *priv; + int i, ret = 0; + + if (pdata && pdata->num_leds) { + priv = kzalloc(sizeof_gpio_leds_priv(pdata->num_leds), + GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->num_leds = pdata->num_leds; + for (i = 0; i < priv->num_leds; i++) { + ret = create_gpio_led(&pdata->leds[i], + &priv->leds[i], + &pdev->dev, pdata->gpio_blink_set); + if (ret < 0) { + /* On failure: unwind the led creations */ + for (i = i - 1; i >= 0; i--) + delete_gpio_led(&priv->leds[i]); + kfree(priv); + return ret; + } + } + } else { + priv = gpio_leds_create_of(pdev); + if (!priv) + return -ENODEV; + } + + platform_set_drvdata(pdev, priv); + + return 0; } -static int __devexit of_gpio_leds_remove(struct platform_device *ofdev) +static int __devexit gpio_led_remove(struct platform_device *pdev) { - struct gpio_led_of_platform_data *pdata = dev_get_drvdata(&ofdev->dev); + struct gpio_leds_priv *priv = dev_get_drvdata(&pdev->dev); int i; - for (i = 0; i < pdata->num_leds; i++) - delete_gpio_led(&pdata->led_data[i]); - - kfree(pdata); + for (i = 0; i < priv->num_leds; i++) + delete_gpio_led(&priv->leds[i]); - dev_set_drvdata(&ofdev->dev, NULL); + dev_set_drvdata(&pdev->dev, NULL); + kfree(priv); return 0; } -static const struct of_device_id of_gpio_leds_match[] = { - { .compatible = "gpio-leds", }, - {}, -}; - -static struct of_platform_driver of_gpio_leds_driver = { - .driver = { - .name = "of_gpio_leds", - .owner = THIS_MODULE, +static struct platform_driver gpio_led_driver = { + .probe = gpio_led_probe, + .remove = __devexit_p(gpio_led_remove), + .driver = { + .name = "leds-gpio", + .owner = THIS_MODULE, .of_match_table = of_gpio_leds_match, }, - .probe = of_gpio_leds_probe, - .remove = __devexit_p(of_gpio_leds_remove), }; -#endif + +MODULE_ALIAS("platform:leds-gpio"); static int __init gpio_led_init(void) { - int ret = 0; - -#ifdef CONFIG_LEDS_GPIO_PLATFORM - ret = platform_driver_register(&gpio_led_driver); - if (ret) - return ret; -#endif -#ifdef CONFIG_LEDS_GPIO_OF - ret = of_register_platform_driver(&of_gpio_leds_driver); -#endif -#ifdef CONFIG_LEDS_GPIO_PLATFORM - if (ret) - platform_driver_unregister(&gpio_led_driver); -#endif - - return ret; + return platform_driver_register(&gpio_led_driver); } static void __exit gpio_led_exit(void) { -#ifdef CONFIG_LEDS_GPIO_PLATFORM platform_driver_unregister(&gpio_led_driver); -#endif -#ifdef CONFIG_LEDS_GPIO_OF - of_unregister_platform_driver(&of_gpio_leds_driver); -#endif } module_init(gpio_led_init); -- cgit v1.2.3 From 2e820f58f7ad8eaca2f194ccdfea0de63e9c6d78 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Mon, 9 Feb 2009 12:05:50 -0800 Subject: xen/irq: implement bind_interdomain_evtchn_to_irqhandler for backend drivers Impact: new Xen-internal API Signed-off-by: Ian Campbell Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/events.c | 38 ++++++++++++++++++++++++++++++++++++++ include/xen/events.h | 6 ++++++ 2 files changed, 44 insertions(+) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 74681478100a..a41601675633 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -864,6 +864,21 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu) return irq; } +static int bind_interdomain_evtchn_to_irq(unsigned int remote_domain, + unsigned int remote_port) +{ + struct evtchn_bind_interdomain bind_interdomain; + int err; + + bind_interdomain.remote_dom = remote_domain; + bind_interdomain.remote_port = remote_port; + + err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, + &bind_interdomain); + + return err ? : bind_evtchn_to_irq(bind_interdomain.local_port); +} + int bind_virq_to_irq(unsigned int virq, unsigned int cpu) { @@ -959,6 +974,29 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn, } EXPORT_SYMBOL_GPL(bind_evtchn_to_irqhandler); +int bind_interdomain_evtchn_to_irqhandler(unsigned int remote_domain, + unsigned int remote_port, + irq_handler_t handler, + unsigned long irqflags, + const char *devname, + void *dev_id) +{ + int irq, retval; + + irq = bind_interdomain_evtchn_to_irq(remote_domain, remote_port); + if (irq < 0) + return irq; + + retval = request_irq(irq, handler, irqflags, devname, dev_id); + if (retval != 0) { + unbind_from_irq(irq); + return retval; + } + + return irq; +} +EXPORT_SYMBOL_GPL(bind_interdomain_evtchn_to_irqhandler); + int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu, irq_handler_t handler, unsigned long irqflags, const char *devname, void *dev_id) diff --git a/include/xen/events.h b/include/xen/events.h index 00f53ddcc062..bd03b1e4a2f4 100644 --- a/include/xen/events.h +++ b/include/xen/events.h @@ -23,6 +23,12 @@ int bind_ipi_to_irqhandler(enum ipi_vector ipi, unsigned long irqflags, const char *devname, void *dev_id); +int bind_interdomain_evtchn_to_irqhandler(unsigned int remote_domain, + unsigned int remote_port, + irq_handler_t handler, + unsigned long irqflags, + const char *devname, + void *dev_id); /* * Common unbind function for all event sources. Takes IRQ to unbind from. -- cgit v1.2.3 From 52208ae3fc60cbcb214c10fb8b82304199e2cc3a Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Thu, 24 Feb 2011 16:58:20 -0800 Subject: [SCSI] target: Fix t_transport_aborted handling in LUN_RESET + active I/O shutdown This patch addresses two outstanding bugs related to T_TASK(cmd)->t_transport_aborted handling during TMR LUN_RESET and active I/O shutdown. This first involves adding two explict t_transport_aborted=1 assignments in core_tmr_lun_reset() in order to signal the task has been aborted, and updating transport_generic_wait_for_tasks() to skip sleeping when t_transport_aborted=1 has been set. This fixes an issue where transport_generic_wait_for_tasks() would end up sleeping indefinately when called from fabric module context while TMR LUN_RESET was happening with long outstanding backend struct se_task not yet being completed. The second adds a missing call to transport_remove_task_from_execute_queue() when task->task_execute_queue=1 is set in order to fix an OOPs when task->t_execute_list has not been dropped. It also fixes the same case in transport_processing_shutdown() to prevent the issue from happening during active I/O struct se_device shutdown. Signed-off-by: Nicholas A. Bellinger Signed-off-by: James Bottomley --- drivers/target/target_core_tmr.c | 5 +++++ drivers/target/target_core_transport.c | 8 ++++++-- include/target/target_core_transport.h | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 158cecbec718..4a109835e420 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c @@ -282,6 +282,9 @@ int core_tmr_lun_reset( atomic_set(&task->task_active, 0); atomic_set(&task->task_stop, 0); + } else { + if (atomic_read(&task->task_execute_queue) != 0) + transport_remove_task_from_execute_queue(task, dev); } __transport_stop_task_timer(task, &flags); @@ -301,6 +304,7 @@ int core_tmr_lun_reset( DEBUG_LR("LUN_RESET: got t_transport_active = 1 for" " task: %p, t_fe_count: %d dev: %p\n", task, fe_count, dev); + atomic_set(&T_TASK(cmd)->t_transport_aborted, 1); spin_unlock_irqrestore(&T_TASK(cmd)->t_state_lock, flags); core_tmr_handle_tas_abort(tmr_nacl, cmd, tas, fe_count); @@ -310,6 +314,7 @@ int core_tmr_lun_reset( } DEBUG_LR("LUN_RESET: Got t_transport_active = 0 for task: %p," " t_fe_count: %d dev: %p\n", task, fe_count, dev); + atomic_set(&T_TASK(cmd)->t_transport_aborted, 1); spin_unlock_irqrestore(&T_TASK(cmd)->t_state_lock, flags); core_tmr_handle_tas_abort(tmr_nacl, cmd, tas, fe_count); diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 236e22d8cfae..4bbf6c147f89 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1207,7 +1207,7 @@ transport_get_task_from_execute_queue(struct se_device *dev) * * */ -static void transport_remove_task_from_execute_queue( +void transport_remove_task_from_execute_queue( struct se_task *task, struct se_device *dev) { @@ -5549,7 +5549,8 @@ static void transport_generic_wait_for_tasks( atomic_set(&T_TASK(cmd)->transport_lun_stop, 0); } - if (!atomic_read(&T_TASK(cmd)->t_transport_active)) + if (!atomic_read(&T_TASK(cmd)->t_transport_active) || + atomic_read(&T_TASK(cmd)->t_transport_aborted)) goto remove; atomic_set(&T_TASK(cmd)->t_transport_stop, 1); @@ -5956,6 +5957,9 @@ static void transport_processing_shutdown(struct se_device *dev) atomic_set(&task->task_active, 0); atomic_set(&task->task_stop, 0); + } else { + if (atomic_read(&task->task_execute_queue) != 0) + transport_remove_task_from_execute_queue(task, dev); } __transport_stop_task_timer(task, &flags); diff --git a/include/target/target_core_transport.h b/include/target/target_core_transport.h index 246940511579..2e8ec51f0615 100644 --- a/include/target/target_core_transport.h +++ b/include/target/target_core_transport.h @@ -135,6 +135,8 @@ extern void transport_complete_task(struct se_task *, int); extern void transport_add_task_to_execute_queue(struct se_task *, struct se_task *, struct se_device *); +extern void transport_remove_task_from_execute_queue(struct se_task *, + struct se_device *); unsigned char *transport_dump_cmd_direction(struct se_cmd *); extern void transport_dump_dev_state(struct se_device *, char *, int *); extern void transport_dump_dev_info(struct se_device *, struct se_lun *, -- cgit v1.2.3 From 2c27392dc4d4f5ee8a3967a520b8f6cac0418031 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Sun, 27 Feb 2011 09:23:52 +0530 Subject: ath9k_htc: Fix an endian issue The stream length/tag fields have to be in little endian format. Fixing this makes the driver work on big-endian platforms. Cc: stable@kernel.org Tested-by: raghunathan.kailasanathan@wipro.com Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 5ab3084eb9cb..07b1633b7f3f 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -219,8 +219,9 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) struct tx_buf *tx_buf = NULL; struct sk_buff *nskb = NULL; int ret = 0, i; - u16 *hdr, tx_skb_cnt = 0; + u16 tx_skb_cnt = 0; u8 *buf; + __le16 *hdr; if (hif_dev->tx.tx_skb_cnt == 0) return 0; @@ -245,9 +246,9 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) buf = tx_buf->buf; buf += tx_buf->offset; - hdr = (u16 *)buf; - *hdr++ = nskb->len; - *hdr++ = ATH_USB_TX_STREAM_MODE_TAG; + hdr = (__le16 *)buf; + *hdr++ = cpu_to_le16(nskb->len); + *hdr++ = cpu_to_le16(ATH_USB_TX_STREAM_MODE_TAG); buf += 4; memcpy(buf, nskb->data, nskb->len); tx_buf->len = nskb->len + 4; -- cgit v1.2.3 From 10889f1330660fd73dc38aadbff7c930fbc4fe20 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Fri, 25 Feb 2011 15:38:09 -0500 Subject: at76c50x-usb: fix warning caused by at76_mac80211_tx now returning void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CC [M] drivers/net/wireless/at76c50x-usb.o drivers/net/wireless/at76c50x-usb.c: In function ‘at76_mac80211_tx’: drivers/net/wireless/at76c50x-usb.c:1759:4: warning: ‘return’ with a value, in function returning void This is fallout from commit 7bb4568372856688bc070917265bce0b88bb7d4d ("mac80211: make tx() operation return void"). Signed-off-by: John W. Linville --- drivers/net/wireless/at76c50x-usb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 10b4393d7fe0..298601436ee2 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c @@ -1756,7 +1756,8 @@ static void at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) if (compare_ether_addr(priv->bssid, mgmt->bssid)) { memcpy(priv->bssid, mgmt->bssid, ETH_ALEN); ieee80211_queue_work(hw, &priv->work_join_bssid); - return NETDEV_TX_BUSY; + dev_kfree_skb_any(skb); + return; } } -- cgit v1.2.3 From 2b799a6b25bb9f9fbc478782cd9503e8066ab618 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 26 Feb 2011 12:58:06 +0100 Subject: p54usb: add Senao NUB-350 usbid Reported-by: Mark Davis Cc: Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54usb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 21713a7638c4..9b344a921e74 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -98,6 +98,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */ {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ {USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */ + {USB_DEVICE(0x1740, 0x1000)}, /* Senao NUB-350 */ {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ {USB_DEVICE(0x2001, 0x3705)}, /* D-Link DWL-G120 rev C1 */ {USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */ -- cgit v1.2.3 From c3371d64d2b2fd029033976046cb4ca641485506 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 26 Feb 2011 04:56:53 +0300 Subject: iwlwifi: remove duplicate initialization rate_mask is initialized again later so this can be removed. Btw, if rate_control_send_low(sta, priv_sta, txrc) returns false, that means that "sta" is non-NULL. That's why the second initialization of rate_mask is a little simpler than the first. Signed-off-by: Dan Carpenter Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-3945-rs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/iwl-3945-rs.c b/drivers/net/wireless/iwlegacy/iwl-3945-rs.c index 4fabc5439858..977bd2477c6a 100644 --- a/drivers/net/wireless/iwlegacy/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlegacy/iwl-3945-rs.c @@ -644,7 +644,7 @@ static void iwl3945_rs_get_rate(void *priv_r, struct ieee80211_sta *sta, u32 fail_count; s8 scale_action = 0; unsigned long flags; - u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0; + u16 rate_mask; s8 max_rate_idx = -1; struct iwl_priv *priv __maybe_unused = (struct iwl_priv *)priv_r; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -- cgit v1.2.3 From 701c2be03aac62a54decaa685c70d2b734afde67 Mon Sep 17 00:00:00 2001 From: Alessio Igor Bogani Date: Mon, 28 Feb 2011 18:46:44 +0100 Subject: rtlwifi: Add the missing rcu_read_lock/unlock =================================================== [ INFO: suspicious rcu_dereference_check() usage. ] --------------------------------------------------- net/mac80211/sta_info.c:125 invoked rcu_dereference_check() without protection! other info that might help us debug this: rcu_scheduler_active = 1, debug_locks = 0 5 locks held by wpa_supplicant/468: #0: (rtnl_mutex){+.+.+.}, at: [] rtnl_lock+0x14/0x20 #1: (&rdev->mtx){+.+.+.}, at: [] cfg80211_mgd_wext_siwfreq+0x6b/0x170 [cfg80211] #2: (&rdev->devlist_mtx){+.+.+.}, at: [] cfg80211_mgd_wext_siwfreq+0x77/0x170 [cfg80211] #3: (&wdev->mtx){+.+.+.}, at: [] cfg80211_mgd_wext_siwfreq+0x84/0x170 [cfg80211] #4: (&rtlpriv->locks.conf_mutex){+.+.+.}, at: [] rtl_op_bss_info_changed+0x26/0xc10 [rtlwifi] stack backtrace: Pid: 468, comm: wpa_supplicant Not tainted 2.6.38-rc6+ #79 Call Trace: [] ? lockdep_rcu_dereference+0xaa/0xb0 [] ? sta_info_get_bss+0x19c/0x1b0 [mac80211] [] ? ieee80211_find_sta+0x22/0x40 [mac80211] [] ? rtl_op_bss_info_changed+0x1cc/0xc10 [rtlwifi] [] ? __mutex_unlock_slowpath+0x14c/0x160 [] ? mutex_unlock+0xd/0x10 [] ? rtl_op_config+0x120/0x310 [rtlwifi] [] ? trace_hardirqs_on+0xb/0x10 [] ? ieee80211_bss_info_change_notify+0xf9/0x1f0 [mac80211] [] ? rtl_op_bss_info_changed+0x0/0xc10 [rtlwifi] [] ? ieee80211_set_channel+0xbf/0xd0 [mac80211] [] ? cfg80211_set_freq+0x121/0x180 [cfg80211] [] ? ieee80211_set_channel+0x0/0xd0 [mac80211] [] ? cfg80211_mgd_wext_siwfreq+0x12b/0x170 [cfg80211] [] ? cfg80211_wext_siwfreq+0x9b/0x100 [cfg80211] [] ? sub_preempt_count+0x7b/0xb0 [] ? ioctl_standard_call+0x74/0x3b0 [] ? rtnl_lock+0x14/0x20 [] ? cfg80211_wext_siwfreq+0x0/0x100 [cfg80211] [] ? __dev_get_by_name+0x8d/0xb0 [] ? wext_handle_ioctl+0x16b/0x180 [] ? cfg80211_wext_siwfreq+0x0/0x100 [cfg80211] [] ? dev_ioctl+0x5ba/0x720 [] ? __lock_acquire+0x3e7/0x19b0 [] ? sock_ioctl+0x1eb/0x290 [] ? lock_release_non_nested+0x95/0x2f0 [] ? sock_ioctl+0x0/0x290 [] ? do_vfs_ioctl+0x7d/0x5c0 [] ? might_fault+0x62/0xb0 [] ? fget_light+0x226/0x390 [] ? might_fault+0xa8/0xb0 [] ? sys_ioctl+0x87/0x90 [] ? sysenter_do_call+0x12/0x38 This work was supported by a hardware donation from the CE Linux Forum. Signed-off-by: Alessio Igor Bogani Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/core.c | 4 ++++ drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 5 ++++- drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 5 ++++- 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 059ab036b01d..e4f4aee8f298 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -551,6 +551,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, ("BSS_CHANGED_HT\n")); + rcu_read_lock(); sta = ieee80211_find_sta(mac->vif, mac->bssid); if (sta) { @@ -563,6 +564,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, mac->current_ampdu_factor = sta->ht_cap.ampdu_factor; } + rcu_read_unlock(); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SHORTGI_DENSITY, (u8 *) (&mac->max_mss_density)); @@ -614,6 +616,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, else mac->mode = WIRELESS_MODE_G; + rcu_read_lock(); sta = ieee80211_find_sta(mac->vif, mac->bssid); if (sta) { @@ -648,6 +651,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, */ } } + rcu_read_unlock(); /*mac80211 just give us CCK rates any time *So we add G rate in basic rates when diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 8a67372f71fb..e14f74367396 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -730,7 +730,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); bool defaultadapter = true; - struct ieee80211_sta *sta = ieee80211_find_sta(mac->vif, mac->bssid); + struct ieee80211_sta *sta; u8 *pdesc = (u8 *) pdesc_tx; struct rtl_tcb_desc tcb_desc; u8 *qc = ieee80211_get_qos_ctl(hdr); @@ -810,10 +810,13 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, SET_TX_DESC_LINIP(pdesc, 0); SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len); + rcu_read_lock(); + sta = ieee80211_find_sta(mac->vif, mac->bssid); if (sta) { u8 ampdu_density = sta->ht_cap.ampdu_density; SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density); } + rcu_read_unlock(); if (info->control.hw_key) { struct ieee80211_key_conf *keyconf = diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 659e0ca95c64..d0b0d43b9a6d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -504,7 +504,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); bool defaultadapter = true; - struct ieee80211_sta *sta = ieee80211_find_sta(mac->vif, mac->bssid); + struct ieee80211_sta *sta; struct rtl_tcb_desc tcb_desc; u8 *qc = ieee80211_get_qos_ctl(hdr); u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; @@ -562,10 +562,13 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, SET_TX_DESC_DATA_BW(txdesc, 0); SET_TX_DESC_DATA_SC(txdesc, 0); } + rcu_read_lock(); + sta = ieee80211_find_sta(mac->vif, mac->bssid); if (sta) { u8 ampdu_density = sta->ht_cap.ampdu_density; SET_TX_DESC_AMPDU_DENSITY(txdesc, ampdu_density); } + rcu_read_unlock(); if (info->control.hw_key) { struct ieee80211_key_conf *keyconf = info->control.hw_key; switch (keyconf->cipher) { -- cgit v1.2.3 From c2a7dca0ce0e6ceb13f9030ff8e9731eaa14cc02 Mon Sep 17 00:00:00 2001 From: Alessio Igor Bogani Date: Mon, 28 Feb 2011 09:11:55 +0100 Subject: rtlwifi: fix places where uninitialized data is used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/net/wireless/rtlwifi/rtl8192ce/trx.c: In function ‘rtl92ce_rx_query_desc’: drivers/net/wireless/rtlwifi/rtl8192ce/trx.c:255:5: warning: ‘rf_rx_num’ may be used uninitialized in this function drivers/net/wireless/rtlwifi/rtl8192ce/trx.c:257:12: warning: ‘total_rssi’ may be used uninitialized in this function drivers/net/wireless/rtlwifi/rtl8192ce/trx.c:466:6: warning: ‘weighting’ may be used uninitialized in this function This work was supported by a hardware donation from the CE Linux Forum. Signed-off-by: Alessio Igor Bogani Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index e14f74367396..aa2b5815600f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -252,9 +252,9 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct phy_sts_cck_8192s_t *cck_buf; s8 rx_pwr_all, rx_pwr[4]; - u8 rf_rx_num, evm, pwdb_all; + u8 evm, pwdb_all, rf_rx_num = 0; u8 i, max_spatial_stream; - u32 rssi, total_rssi; + u32 rssi, total_rssi = 0; bool is_cck_rate; is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); @@ -463,7 +463,7 @@ static void _rtl92ce_update_rxsignalstatistics(struct ieee80211_hw *hw, struct rtl_stats *pstats) { struct rtl_priv *rtlpriv = rtl_priv(hw); - int weighting; + int weighting = 0; if (rtlpriv->stats.recv_signal_power == 0) rtlpriv->stats.recv_signal_power = pstats->recvsignalpower; -- cgit v1.2.3 From a5a7103fe18eb4312bd89c9f136fb850af58faf4 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 27 Feb 2011 22:19:22 +0100 Subject: p54: fix a NULL pointer dereference bug If the RSSI calibration table was not found or not parsed properly, priv->rssi_db will be NULL, p54_rssi_find needs to be able to deal with that. Signed-off-by: Felix Fietkau Acked-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/eeprom.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c index f54e15fcd623..13d750da9301 100644 --- a/drivers/net/wireless/p54/eeprom.c +++ b/drivers/net/wireless/p54/eeprom.c @@ -524,10 +524,13 @@ err_data: struct p54_rssi_db_entry *p54_rssi_find(struct p54_common *priv, const u16 freq) { - struct p54_rssi_db_entry *entry = (void *)(priv->rssi_db->data + - priv->rssi_db->offset); + struct p54_rssi_db_entry *entry; int i, found = -1; + if (!priv->rssi_db) + return &p54_rssi_default; + + entry = (void *)(priv->rssi_db->data + priv->rssi_db->offset); for (i = 0; i < priv->rssi_db->entries; i++) { if (!same_band(freq, entry[i].freq)) continue; -- cgit v1.2.3 From 0cf55c21ec401632043db2b8acb7cd3bef64c9e6 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 27 Feb 2011 22:26:40 +0100 Subject: ath9k: use generic mac80211 LED blinking code Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 42 ++++----- drivers/net/wireless/ath/ath9k/gpio.c | 164 +++++---------------------------- drivers/net/wireless/ath/ath9k/init.c | 22 +++++ drivers/net/wireless/ath/ath9k/main.c | 3 - 4 files changed, 61 insertions(+), 170 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index f9f0389b92ab..367b51430ff0 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -449,26 +449,20 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc); #define ATH_LED_PIN_DEF 1 #define ATH_LED_PIN_9287 8 -#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */ -#define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */ - -enum ath_led_type { - ATH_LED_RADIO, - ATH_LED_ASSOC, - ATH_LED_TX, - ATH_LED_RX -}; - -struct ath_led { - struct ath_softc *sc; - struct led_classdev led_cdev; - enum ath_led_type led_type; - char name[32]; - bool registered; -}; +#ifdef CONFIG_MAC80211_LEDS void ath_init_leds(struct ath_softc *sc); void ath_deinit_leds(struct ath_softc *sc); +#else +static inline void ath_init_leds(struct ath_softc *sc) +{ +} + +static inline void ath_deinit_leds(struct ath_softc *sc) +{ +} +#endif + /* Antenna diversity/combining */ #define ATH_ANT_RX_CURRENT_SHIFT 4 @@ -620,15 +614,11 @@ struct ath_softc { struct ath_beacon beacon; struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; - struct ath_led radio_led; - struct ath_led assoc_led; - struct ath_led tx_led; - struct ath_led rx_led; - struct delayed_work ath_led_blink_work; - int led_on_duration; - int led_off_duration; - int led_on_cnt; - int led_off_cnt; +#ifdef CONFIG_MAC80211_LEDS + bool led_registered; + char led_name[32]; + struct led_classdev led_cdev; +#endif struct ath9k_hw_cal_data caldata; int last_rssi; diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index fb4f17a5183d..e369bf7e575f 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -20,117 +20,25 @@ /* LED functions */ /********************************/ -static void ath_led_blink_work(struct work_struct *work) -{ - struct ath_softc *sc = container_of(work, struct ath_softc, - ath_led_blink_work.work); - - if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED)) - return; - - if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) || - (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE)) - ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); - else - ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, - (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0); - - ieee80211_queue_delayed_work(sc->hw, - &sc->ath_led_blink_work, - (sc->sc_flags & SC_OP_LED_ON) ? - msecs_to_jiffies(sc->led_off_duration) : - msecs_to_jiffies(sc->led_on_duration)); - - sc->led_on_duration = sc->led_on_cnt ? - max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) : - ATH_LED_ON_DURATION_IDLE; - sc->led_off_duration = sc->led_off_cnt ? - max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) : - ATH_LED_OFF_DURATION_IDLE; - sc->led_on_cnt = sc->led_off_cnt = 0; - if (sc->sc_flags & SC_OP_LED_ON) - sc->sc_flags &= ~SC_OP_LED_ON; - else - sc->sc_flags |= SC_OP_LED_ON; -} - +#ifdef CONFIG_MAC80211_LEDS static void ath_led_brightness(struct led_classdev *led_cdev, enum led_brightness brightness) { - struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev); - struct ath_softc *sc = led->sc; - - switch (brightness) { - case LED_OFF: - if (led->led_type == ATH_LED_ASSOC || - led->led_type == ATH_LED_RADIO) { - ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, - (led->led_type == ATH_LED_RADIO)); - sc->sc_flags &= ~SC_OP_LED_ASSOCIATED; - if (led->led_type == ATH_LED_RADIO) - sc->sc_flags &= ~SC_OP_LED_ON; - } else { - sc->led_off_cnt++; - } - break; - case LED_FULL: - if (led->led_type == ATH_LED_ASSOC) { - sc->sc_flags |= SC_OP_LED_ASSOCIATED; - if (led_blink) - ieee80211_queue_delayed_work(sc->hw, - &sc->ath_led_blink_work, 0); - } else if (led->led_type == ATH_LED_RADIO) { - ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); - sc->sc_flags |= SC_OP_LED_ON; - } else { - sc->led_on_cnt++; - } - break; - default: - break; - } -} - -static int ath_register_led(struct ath_softc *sc, struct ath_led *led, - char *trigger) -{ - int ret; - - led->sc = sc; - led->led_cdev.name = led->name; - led->led_cdev.default_trigger = trigger; - led->led_cdev.brightness_set = ath_led_brightness; - - ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev); - if (ret) - ath_err(ath9k_hw_common(sc->sc_ah), - "Failed to register led:%s", led->name); - else - led->registered = 1; - return ret; -} - -static void ath_unregister_led(struct ath_led *led) -{ - if (led->registered) { - led_classdev_unregister(&led->led_cdev); - led->registered = 0; - } + struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev); + ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, (brightness == LED_OFF)); } void ath_deinit_leds(struct ath_softc *sc) { - ath_unregister_led(&sc->assoc_led); - sc->sc_flags &= ~SC_OP_LED_ASSOCIATED; - ath_unregister_led(&sc->tx_led); - ath_unregister_led(&sc->rx_led); - ath_unregister_led(&sc->radio_led); - ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); + if (!sc->led_registered) + return; + + ath_led_brightness(&sc->led_cdev, LED_OFF); + led_classdev_unregister(&sc->led_cdev); } void ath_init_leds(struct ath_softc *sc) { - char *trigger; int ret; if (AR_SREV_9287(sc->sc_ah)) @@ -144,48 +52,22 @@ void ath_init_leds(struct ath_softc *sc) /* LED off, active low */ ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); - if (led_blink) - INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work); - - trigger = ieee80211_get_radio_led_name(sc->hw); - snprintf(sc->radio_led.name, sizeof(sc->radio_led.name), - "ath9k-%s::radio", wiphy_name(sc->hw->wiphy)); - ret = ath_register_led(sc, &sc->radio_led, trigger); - sc->radio_led.led_type = ATH_LED_RADIO; - if (ret) - goto fail; - - trigger = ieee80211_get_assoc_led_name(sc->hw); - snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name), - "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy)); - ret = ath_register_led(sc, &sc->assoc_led, trigger); - sc->assoc_led.led_type = ATH_LED_ASSOC; - if (ret) - goto fail; - - trigger = ieee80211_get_tx_led_name(sc->hw); - snprintf(sc->tx_led.name, sizeof(sc->tx_led.name), - "ath9k-%s::tx", wiphy_name(sc->hw->wiphy)); - ret = ath_register_led(sc, &sc->tx_led, trigger); - sc->tx_led.led_type = ATH_LED_TX; - if (ret) - goto fail; - - trigger = ieee80211_get_rx_led_name(sc->hw); - snprintf(sc->rx_led.name, sizeof(sc->rx_led.name), - "ath9k-%s::rx", wiphy_name(sc->hw->wiphy)); - ret = ath_register_led(sc, &sc->rx_led, trigger); - sc->rx_led.led_type = ATH_LED_RX; - if (ret) - goto fail; - - return; - -fail: - if (led_blink) - cancel_delayed_work_sync(&sc->ath_led_blink_work); - ath_deinit_leds(sc); + if (!led_blink) + sc->led_cdev.default_trigger = + ieee80211_get_radio_led_name(sc->hw); + + snprintf(sc->led_name, sizeof(sc->led_name), + "ath9k-%s", wiphy_name(sc->hw->wiphy)); + sc->led_cdev.name = sc->led_name; + sc->led_cdev.brightness_set = ath_led_brightness; + + ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev); + if (ret < 0) + return; + + sc->led_registered = true; } +#endif /*******************/ /* Rfkill */ diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index f66c882a39e2..79aec983279f 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -140,6 +140,21 @@ static struct ieee80211_rate ath9k_legacy_rates[] = { RATE(540, 0x0c, 0), }; +#ifdef CONFIG_MAC80211_LEDS +static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = { + { .throughput = 0 * 1024, .blink_time = 334 }, + { .throughput = 1 * 1024, .blink_time = 260 }, + { .throughput = 5 * 1024, .blink_time = 220 }, + { .throughput = 10 * 1024, .blink_time = 190 }, + { .throughput = 20 * 1024, .blink_time = 170 }, + { .throughput = 50 * 1024, .blink_time = 150 }, + { .throughput = 70 * 1024, .blink_time = 130 }, + { .throughput = 100 * 1024, .blink_time = 110 }, + { .throughput = 200 * 1024, .blink_time = 80 }, + { .throughput = 300 * 1024, .blink_time = 50 }, +}; +#endif + static void ath9k_deinit_softc(struct ath_softc *sc); /* @@ -731,6 +746,13 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, ath9k_init_txpower_limits(sc); +#ifdef CONFIG_MAC80211_LEDS + /* must be initialized before ieee80211_register_hw */ + sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw, + IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink, + ARRAY_SIZE(ath9k_tpt_blink)); +#endif + /* Register with mac80211 */ error = ieee80211_register_hw(hw); if (error) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 97830c7f62c9..2e228aada1a9 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1216,9 +1216,6 @@ static void ath9k_stop(struct ieee80211_hw *hw) mutex_lock(&sc->mutex); - if (led_blink) - cancel_delayed_work_sync(&sc->ath_led_blink_work); - cancel_delayed_work_sync(&sc->tx_complete_work); cancel_delayed_work_sync(&sc->hw_pll_work); cancel_work_sync(&sc->paprd_work); -- cgit v1.2.3 From 15178535ad2f8fd8f7e803791f25395aa69f80ac Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Mon, 28 Feb 2011 15:16:47 +0530 Subject: ath9k: Fix incorrect GPIO LED pin for AR9485 AR9485 doesn't use the default GPIO pin for LED and GPIO 6 is actually used for this. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/gpio.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 367b51430ff0..c718ab512a97 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -449,6 +449,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc); #define ATH_LED_PIN_DEF 1 #define ATH_LED_PIN_9287 8 +#define ATH_LED_PIN_9485 6 #ifdef CONFIG_MAC80211_LEDS void ath_init_leds(struct ath_softc *sc); diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index e369bf7e575f..0fb8f8ac275a 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -43,6 +43,8 @@ void ath_init_leds(struct ath_softc *sc) if (AR_SREV_9287(sc->sc_ah)) sc->sc_ah->led_pin = ATH_LED_PIN_9287; + else if (AR_SREV_9485(sc->sc_ah)) + sc->sc_ah->led_pin = ATH_LED_PIN_9485; else sc->sc_ah->led_pin = ATH_LED_PIN_DEF; -- cgit v1.2.3 From 387f3381f732d8fa1b62213ae3276f2ae712dbe2 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 28 Feb 2011 14:33:13 +0100 Subject: iwlwifi: fix dma mappings and skbs leak Since commit commit 470058e0ad82fcfaaffd57307d8bf8c094e8e9d7 "iwlwifi: avoid Tx queue memory allocation in interface down" we do not unmap dma and free skbs when down device and there is pending transfer. What in consequence may cause that system hung (waiting for free skb's) when performing shutdown at iptables module unload. DMA leak manifest itself following warning: WARNING: at lib/dma-debug.c:689 dma_debug_device_change+0x15a/0x1b0() Hardware name: HP xw8600 Workstation pci 0000:80:00.0: DMA-API: device driver has pending DMA allocations while released from device [count=240] Modules linked in: iwlagn(-) aes_x86_64 aes_generic fuse cpufreq_ondemand acpi_cpufreq freq_table mperf xt_physdev ipt_REJECT nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables ipv6 ext3 jbd dm_mirror dm_region_hash dm_log dm_mod uinput hp_wmi sparse_keymap sg wmi microcode serio_raw tg3 arc4 ecb shpchp mac80211 cfg80211 rfkill ext4 mbcache jbd2 sr_mod cdrom sd_mod crc_t10dif firewire_ohci firewire_core crc_itu_t mptsas mptscsih mptbase scsi_transport_sas pata_acpi ata_generic ata_piix ahci libahci floppy nouveau ttm drm_kms_helper drm i2c_algo_bit i2c_core video [last unloaded: iwlagn] Pid: 9131, comm: rmmod Tainted: G W 2.6.38-rc6-wl+ #33 Call Trace: [] ? warn_slowpath_common+0x7f/0xc0 [] ? warn_slowpath_fmt+0x46/0x50 [] ? dma_debug_device_change+0xdb/0x1b0 [] ? dma_debug_device_change+0x15a/0x1b0 [] ? notifier_call_chain+0x58/0xb0 [] ? __blocking_notifier_call_chain+0x60/0x90 [] ? blocking_notifier_call_chain+0x16/0x20 [] ? __device_release_driver+0xbc/0xe0 [] ? driver_detach+0xd8/0xe0 [] ? bus_remove_driver+0x91/0x100 [] ? driver_unregister+0x62/0xa0 [] ? pci_unregister_driver+0x44/0xa0 [] ? iwl_exit+0x15/0x1c [iwlagn] [] ? sys_delete_module+0x1a2/0x270 [] ? trace_hardirqs_on_thunk+0x3a/0x3f [] ? system_call_fastpath+0x16/0x1b I still can observe above warning after apply patch, but it is very hard to reproduce it, and have count=1. Whereas that one is easy to reproduce using debugfs force_reset while transmitting data, and have very big counts eg. 240, like quoted here. So count=1 WARNING seems to be different issue that need to be resolved separately. v1 -> v2: fix infinity loop bug I made during "for" to "while" loop transition. v2 -> v3: remove unneeded EXPORT_SYMBOL Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 12 +++++- drivers/net/wireless/iwlwifi/iwl-core.h | 2 + drivers/net/wireless/iwlwifi/iwl-tx.c | 71 ++++++++++++++++++++----------- 3 files changed, 59 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 266490d8a397..a709d05c5868 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -947,7 +947,7 @@ void iwlagn_txq_ctx_reset(struct iwl_priv *priv) */ void iwlagn_txq_ctx_stop(struct iwl_priv *priv) { - int ch; + int ch, txq_id; unsigned long flags; /* Turn off all Tx DMA fifos */ @@ -966,6 +966,16 @@ void iwlagn_txq_ctx_stop(struct iwl_priv *priv) iwl_read_direct32(priv, FH_TSSR_TX_STATUS_REG)); } spin_unlock_irqrestore(&priv->lock, flags); + + if (!priv->txq) + return; + + /* Unmap DMA from host system and free skb's */ + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) + if (txq_id == priv->cmd_queue) + iwl_cmd_queue_unmap(priv); + else + iwl_tx_queue_unmap(priv, txq_id); } /* diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 909b42d5d9c0..ce368d8d402b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -510,6 +510,7 @@ void iwl_rx_reply_error(struct iwl_priv *priv, * RX ******************************************************/ void iwl_cmd_queue_free(struct iwl_priv *priv); +void iwl_cmd_queue_unmap(struct iwl_priv *priv); int iwl_rx_queue_alloc(struct iwl_priv *priv); void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q); @@ -534,6 +535,7 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, int slots_num, u32 txq_id); void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); +void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id); void iwl_setup_watchdog(struct iwl_priv *priv); /***************************************************** * TX power diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 7e607d39da1c..277c9175dcf6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -85,6 +85,23 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) txq->need_update = 0; } +/** + * iwl_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's + */ +void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id) +{ + struct iwl_tx_queue *txq = &priv->txq[txq_id]; + struct iwl_queue *q = &txq->q; + + if (q->n_bd == 0) + return; + + while (q->write_ptr != q->read_ptr) { + priv->cfg->ops->lib->txq_free_tfd(priv, txq); + q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); + } +} + /** * iwl_tx_queue_free - Deallocate DMA queue. * @txq: Transmit queue to deallocate. @@ -96,17 +113,10 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) { struct iwl_tx_queue *txq = &priv->txq[txq_id]; - struct iwl_queue *q = &txq->q; struct device *dev = &priv->pci_dev->dev; int i; - if (q->n_bd == 0) - return; - - /* first, empty all BD's */ - for (; q->write_ptr != q->read_ptr; - q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) - priv->cfg->ops->lib->txq_free_tfd(priv, txq); + iwl_tx_queue_unmap(priv, txq_id); /* De-alloc array of command/tx buffers */ for (i = 0; i < TFD_TX_CMD_SLOTS; i++) @@ -132,39 +142,33 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) } /** - * iwl_cmd_queue_free - Deallocate DMA queue. - * @txq: Transmit queue to deallocate. - * - * Empty queue by removing and destroying all BD's. - * Free all buffers. - * 0-fill, but do not free "txq" descriptor structure. + * iwl_cmd_queue_unmap - Unmap any remaining DMA mappings from command queue */ -void iwl_cmd_queue_free(struct iwl_priv *priv) +void iwl_cmd_queue_unmap(struct iwl_priv *priv) { struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; struct iwl_queue *q = &txq->q; - struct device *dev = &priv->pci_dev->dev; int i; bool huge = false; if (q->n_bd == 0) return; - for (; q->read_ptr != q->write_ptr; - q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { + while (q->read_ptr != q->write_ptr) { /* we have no way to tell if it is a huge cmd ATM */ i = get_cmd_index(q, q->read_ptr, 0); - if (txq->meta[i].flags & CMD_SIZE_HUGE) { + if (txq->meta[i].flags & CMD_SIZE_HUGE) huge = true; - continue; - } + else + pci_unmap_single(priv->pci_dev, + dma_unmap_addr(&txq->meta[i], mapping), + dma_unmap_len(&txq->meta[i], len), + PCI_DMA_BIDIRECTIONAL); - pci_unmap_single(priv->pci_dev, - dma_unmap_addr(&txq->meta[i], mapping), - dma_unmap_len(&txq->meta[i], len), - PCI_DMA_BIDIRECTIONAL); + q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); } + if (huge) { i = q->n_window; pci_unmap_single(priv->pci_dev, @@ -172,6 +176,23 @@ void iwl_cmd_queue_free(struct iwl_priv *priv) dma_unmap_len(&txq->meta[i], len), PCI_DMA_BIDIRECTIONAL); } +} + +/** + * iwl_cmd_queue_free - Deallocate DMA queue. + * @txq: Transmit queue to deallocate. + * + * Empty queue by removing and destroying all BD's. + * Free all buffers. + * 0-fill, but do not free "txq" descriptor structure. + */ +void iwl_cmd_queue_free(struct iwl_priv *priv) +{ + struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; + struct device *dev = &priv->pci_dev->dev; + int i; + + iwl_cmd_queue_unmap(priv); /* De-alloc array of command/tx buffers */ for (i = 0; i <= TFD_CMD_SLOTS; i++) -- cgit v1.2.3 From 8a032c132b7ca011813df7c441b4a6fc89e5baee Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 28 Feb 2011 14:33:14 +0100 Subject: iwlegacy: fix dma mappings and skbs leak Fix possible dma mappings and skbs introduced by commit 470058e0ad82fcfaaffd57307d8bf8c094e8e9d7 "iwlwifi: avoid Tx queue memory allocation in interface down". Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-4965-tx.c | 12 ++++- drivers/net/wireless/iwlegacy/iwl-core.h | 2 + drivers/net/wireless/iwlegacy/iwl-tx.c | 75 +++++++++++++++++++---------- 3 files changed, 62 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-tx.c b/drivers/net/wireless/iwlegacy/iwl-4965-tx.c index 829db91896b0..5c40502f869a 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-tx.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-tx.c @@ -698,7 +698,7 @@ void iwl4965_txq_ctx_reset(struct iwl_priv *priv) */ void iwl4965_txq_ctx_stop(struct iwl_priv *priv) { - int ch; + int ch, txq_id; unsigned long flags; /* Turn off all Tx DMA fifos */ @@ -719,6 +719,16 @@ void iwl4965_txq_ctx_stop(struct iwl_priv *priv) FH_TSSR_TX_STATUS_REG)); } spin_unlock_irqrestore(&priv->lock, flags); + + if (!priv->txq) + return; + + /* Unmap DMA from host system and free skb's */ + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) + if (txq_id == priv->cmd_queue) + iwl_legacy_cmd_queue_unmap(priv); + else + iwl_legacy_tx_queue_unmap(priv, txq_id); } /* diff --git a/drivers/net/wireless/iwlegacy/iwl-core.h b/drivers/net/wireless/iwlegacy/iwl-core.h index c6d12d7e96b6..f03b463e4378 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.h +++ b/drivers/net/wireless/iwlegacy/iwl-core.h @@ -388,6 +388,7 @@ void iwl_legacy_rx_reply_error(struct iwl_priv *priv, /***************************************************** * RX ******************************************************/ +void iwl_legacy_cmd_queue_unmap(struct iwl_priv *priv); void iwl_legacy_cmd_queue_free(struct iwl_priv *priv); int iwl_legacy_rx_queue_alloc(struct iwl_priv *priv); void iwl_legacy_rx_queue_update_write_ptr(struct iwl_priv *priv, @@ -415,6 +416,7 @@ int iwl_legacy_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, void iwl_legacy_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, int slots_num, u32 txq_id); +void iwl_legacy_tx_queue_unmap(struct iwl_priv *priv, int txq_id); void iwl_legacy_tx_queue_free(struct iwl_priv *priv, int txq_id); void iwl_legacy_setup_watchdog(struct iwl_priv *priv); /***************************************************** diff --git a/drivers/net/wireless/iwlegacy/iwl-tx.c b/drivers/net/wireless/iwlegacy/iwl-tx.c index 7db8340d1c07..a227773cb384 100644 --- a/drivers/net/wireless/iwlegacy/iwl-tx.c +++ b/drivers/net/wireless/iwlegacy/iwl-tx.c @@ -81,6 +81,24 @@ iwl_legacy_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) } EXPORT_SYMBOL(iwl_legacy_txq_update_write_ptr); +/** + * iwl_legacy_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's + */ +void iwl_legacy_tx_queue_unmap(struct iwl_priv *priv, int txq_id) +{ + struct iwl_tx_queue *txq = &priv->txq[txq_id]; + struct iwl_queue *q = &txq->q; + + if (q->n_bd == 0) + return; + + while (q->write_ptr != q->read_ptr) { + priv->cfg->ops->lib->txq_free_tfd(priv, txq); + q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd); + } +} +EXPORT_SYMBOL(iwl_legacy_tx_queue_unmap); + /** * iwl_legacy_tx_queue_free - Deallocate DMA queue. * @txq: Transmit queue to deallocate. @@ -92,17 +110,10 @@ EXPORT_SYMBOL(iwl_legacy_txq_update_write_ptr); void iwl_legacy_tx_queue_free(struct iwl_priv *priv, int txq_id) { struct iwl_tx_queue *txq = &priv->txq[txq_id]; - struct iwl_queue *q = &txq->q; struct device *dev = &priv->pci_dev->dev; int i; - if (q->n_bd == 0) - return; - - /* first, empty all BD's */ - for (; q->write_ptr != q->read_ptr; - q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd)) - priv->cfg->ops->lib->txq_free_tfd(priv, txq); + iwl_legacy_tx_queue_unmap(priv, txq_id); /* De-alloc array of command/tx buffers */ for (i = 0; i < TFD_TX_CMD_SLOTS; i++) @@ -129,39 +140,33 @@ void iwl_legacy_tx_queue_free(struct iwl_priv *priv, int txq_id) EXPORT_SYMBOL(iwl_legacy_tx_queue_free); /** - * iwl_legacy_cmd_queue_free - Deallocate DMA queue. - * @txq: Transmit queue to deallocate. - * - * Empty queue by removing and destroying all BD's. - * Free all buffers. - * 0-fill, but do not free "txq" descriptor structure. + * iwl_cmd_queue_unmap - Unmap any remaining DMA mappings from command queue */ -void iwl_legacy_cmd_queue_free(struct iwl_priv *priv) +void iwl_legacy_cmd_queue_unmap(struct iwl_priv *priv) { struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; struct iwl_queue *q = &txq->q; - struct device *dev = &priv->pci_dev->dev; - int i; bool huge = false; + int i; if (q->n_bd == 0) return; - for (; q->read_ptr != q->write_ptr; - q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd)) { + while (q->read_ptr != q->write_ptr) { /* we have no way to tell if it is a huge cmd ATM */ i = iwl_legacy_get_cmd_index(q, q->read_ptr, 0); - if (txq->meta[i].flags & CMD_SIZE_HUGE) { + if (txq->meta[i].flags & CMD_SIZE_HUGE) huge = true; - continue; - } + else + pci_unmap_single(priv->pci_dev, + dma_unmap_addr(&txq->meta[i], mapping), + dma_unmap_len(&txq->meta[i], len), + PCI_DMA_BIDIRECTIONAL); - pci_unmap_single(priv->pci_dev, - dma_unmap_addr(&txq->meta[i], mapping), - dma_unmap_len(&txq->meta[i], len), - PCI_DMA_BIDIRECTIONAL); + q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd); } + if (huge) { i = q->n_window; pci_unmap_single(priv->pci_dev, @@ -169,6 +174,24 @@ void iwl_legacy_cmd_queue_free(struct iwl_priv *priv) dma_unmap_len(&txq->meta[i], len), PCI_DMA_BIDIRECTIONAL); } +} +EXPORT_SYMBOL(iwl_legacy_cmd_queue_unmap); + +/** + * iwl_legacy_cmd_queue_free - Deallocate DMA queue. + * @txq: Transmit queue to deallocate. + * + * Empty queue by removing and destroying all BD's. + * Free all buffers. + * 0-fill, but do not free "txq" descriptor structure. + */ +void iwl_legacy_cmd_queue_free(struct iwl_priv *priv) +{ + struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; + struct device *dev = &priv->pci_dev->dev; + int i; + + iwl_legacy_cmd_queue_unmap(priv); /* De-alloc array of command/tx buffers */ for (i = 0; i <= TFD_CMD_SLOTS; i++) -- cgit v1.2.3 From b7977ffaab5187ad75edaf04ac854615cea93828 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 28 Feb 2011 14:33:15 +0100 Subject: iwlwifi: add {ack,plpc}_check module parameters Add module ack_check, and plcp_check parameters. Ack_check is disabled by default since is proved that check ack health can cause troubles. Plcp_check is enabled by default. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn.c | 6 ++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-rx.c | 8 ++++++-- 4 files changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 8e192072df15..fd142bee9189 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -609,6 +609,7 @@ const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv, struct iwl_mod_params iwlagn_mod_params = { .amsdu_size_8K = 1, .restart_fw = 1, + .plcp_check = true, /* the rest are 0 by default */ }; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 8cdbd8c4027f..4792418191e4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4785,3 +4785,9 @@ MODULE_PARM_DESC(antenna_coupling, module_param_named(bt_ch_inhibition, iwlagn_bt_ch_announce, bool, S_IRUGO); MODULE_PARM_DESC(bt_ch_inhibition, "Disable BT channel inhibition (default: enable)"); + +module_param_named(plcp_check, iwlagn_mod_params.plcp_check, bool, S_IRUGO); +MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])"); + +module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); +MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index ce368d8d402b..1be7f2957411 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -261,6 +261,8 @@ struct iwl_mod_params { int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */ int antenna; /* def: 0 = both antennas (use diversity) */ int restart_fw; /* def: 1 = restart firmware */ + bool plcp_check; /* def: true = enable plcp health check */ + bool ack_check; /* def: false = disable ack health check */ }; /* diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index a21f6fe10fb7..fd84d53db3ac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -230,18 +230,22 @@ void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt) { + const struct iwl_mod_params *mod_params = priv->cfg->mod_params; + if (test_bit(STATUS_EXIT_PENDING, &priv->status) || !iwl_is_any_associated(priv)) return; - if (priv->cfg->ops->lib->check_ack_health && + if (mod_params->ack_check && + priv->cfg->ops->lib->check_ack_health && !priv->cfg->ops->lib->check_ack_health(priv, pkt)) { IWL_ERR(priv, "low ack count detected, restart firmware\n"); if (!iwl_force_reset(priv, IWL_FW_RESET, false)) return; } - if (priv->cfg->ops->lib->check_plcp_health && + if (mod_params->plcp_check && + priv->cfg->ops->lib->check_plcp_health && !priv->cfg->ops->lib->check_plcp_health(priv, pkt)) iwl_force_reset(priv, IWL_RF_RESET, false); } -- cgit v1.2.3 From ad6e82a5348e494c0023d77fa55933f23b55711c Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 28 Feb 2011 14:33:16 +0100 Subject: iwlwifi: move check health code into iwl-rx.c Remove check_plcp_health and check_ack_health ops methods, they are unneeded after iwlegacy driver split. Merge check health code into to iwl-rx.c and make functions static. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 - drivers/net/wireless/iwlwifi/iwl-2000.c | 2 - drivers/net/wireless/iwlwifi/iwl-5000.c | 4 - drivers/net/wireless/iwlwifi/iwl-6000.c | 4 - drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 87 ---------------- drivers/net/wireless/iwlwifi/iwl-agn.c | 66 ------------ drivers/net/wireless/iwlwifi/iwl-agn.h | 4 - drivers/net/wireless/iwlwifi/iwl-core.h | 7 +- drivers/net/wireless/iwlwifi/iwl-rx.c | 162 ++++++++++++++++++++++++++++-- 9 files changed, 155 insertions(+), 183 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index ba78bc8a259f..e8e1c2dc8659 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -232,8 +232,6 @@ static struct iwl_lib_ops iwl1000_lib = { .bt_stats_read = iwl_ucode_bt_stats_read, .reply_tx_error = iwl_reply_tx_error_read, }, - .check_plcp_health = iwl_good_plcp_health, - .check_ack_health = iwl_good_ack_health, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, .tt_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 335adedcee43..d7b6126408c9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -315,8 +315,6 @@ static struct iwl_lib_ops iwl2000_lib = { .bt_stats_read = iwl_ucode_bt_stats_read, .reply_tx_error = iwl_reply_tx_error_read, }, - .check_plcp_health = iwl_good_plcp_health, - .check_ack_health = iwl_good_ack_health, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, .tt_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 79ab0a6b1386..90e727b1b4c1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -402,8 +402,6 @@ static struct iwl_lib_ops iwl5000_lib = { .bt_stats_read = iwl_ucode_bt_stats_read, .reply_tx_error = iwl_reply_tx_error_read, }, - .check_plcp_health = iwl_good_plcp_health, - .check_ack_health = iwl_good_ack_health, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, .tt_ops = { @@ -471,8 +469,6 @@ static struct iwl_lib_ops iwl5150_lib = { .bt_stats_read = iwl_ucode_bt_stats_read, .reply_tx_error = iwl_reply_tx_error_read, }, - .check_plcp_health = iwl_good_plcp_health, - .check_ack_health = iwl_good_ack_health, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, .tt_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index f6493f77610d..a745b01c0ec1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -343,8 +343,6 @@ static struct iwl_lib_ops iwl6000_lib = { .bt_stats_read = iwl_ucode_bt_stats_read, .reply_tx_error = iwl_reply_tx_error_read, }, - .check_plcp_health = iwl_good_plcp_health, - .check_ack_health = iwl_good_ack_health, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, .tt_ops = { @@ -415,8 +413,6 @@ static struct iwl_lib_ops iwl6030_lib = { .bt_stats_read = iwl_ucode_bt_stats_read, .reply_tx_error = iwl_reply_tx_error_read, }, - .check_plcp_health = iwl_good_plcp_health, - .check_ack_health = iwl_good_ack_health, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, .tt_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index b192ca842f0a..7a89a55ec316 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -169,93 +169,6 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv, #define REG_RECALIB_PERIOD (60) -/** - * iwl_good_plcp_health - checks for plcp error. - * - * When the plcp error is exceeding the thresholds, reset the radio - * to improve the throughput. - */ -bool iwl_good_plcp_health(struct iwl_priv *priv, - struct iwl_rx_packet *pkt) -{ - bool rc = true; - int combined_plcp_delta; - unsigned int plcp_msec; - unsigned long plcp_received_jiffies; - - if (priv->cfg->base_params->plcp_delta_threshold == - IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { - IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); - return rc; - } - - /* - * check for plcp_err and trigger radio reset if it exceeds - * the plcp error threshold plcp_delta. - */ - plcp_received_jiffies = jiffies; - plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - - (long) priv->plcp_jiffies); - priv->plcp_jiffies = plcp_received_jiffies; - /* - * check to make sure plcp_msec is not 0 to prevent division - * by zero. - */ - if (plcp_msec) { - struct statistics_rx_phy *ofdm; - struct statistics_rx_ht_phy *ofdm_ht; - - if (iwl_bt_statistics(priv)) { - ofdm = &pkt->u.stats_bt.rx.ofdm; - ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht; - combined_plcp_delta = - (le32_to_cpu(ofdm->plcp_err) - - le32_to_cpu(priv->_agn.statistics_bt. - rx.ofdm.plcp_err)) + - (le32_to_cpu(ofdm_ht->plcp_err) - - le32_to_cpu(priv->_agn.statistics_bt. - rx.ofdm_ht.plcp_err)); - } else { - ofdm = &pkt->u.stats.rx.ofdm; - ofdm_ht = &pkt->u.stats.rx.ofdm_ht; - combined_plcp_delta = - (le32_to_cpu(ofdm->plcp_err) - - le32_to_cpu(priv->_agn.statistics. - rx.ofdm.plcp_err)) + - (le32_to_cpu(ofdm_ht->plcp_err) - - le32_to_cpu(priv->_agn.statistics. - rx.ofdm_ht.plcp_err)); - } - - if ((combined_plcp_delta > 0) && - ((combined_plcp_delta * 100) / plcp_msec) > - priv->cfg->base_params->plcp_delta_threshold) { - /* - * if plcp_err exceed the threshold, - * the following data is printed in csv format: - * Text: plcp_err exceeded %d, - * Received ofdm.plcp_err, - * Current ofdm.plcp_err, - * Received ofdm_ht.plcp_err, - * Current ofdm_ht.plcp_err, - * combined_plcp_delta, - * plcp_msec - */ - IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " - "%u, %u, %u, %u, %d, %u mSecs\n", - priv->cfg->base_params->plcp_delta_threshold, - le32_to_cpu(ofdm->plcp_err), - le32_to_cpu(ofdm->plcp_err), - le32_to_cpu(ofdm_ht->plcp_err), - le32_to_cpu(ofdm_ht->plcp_err), - combined_plcp_delta, plcp_msec); - - rc = false; - } - } - return rc; -} - void iwl_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 4792418191e4..c96d4ad5def0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1413,72 +1413,6 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) iwl_enable_rfkill_int(priv); } -/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */ -#define ACK_CNT_RATIO (50) -#define BA_TIMEOUT_CNT (5) -#define BA_TIMEOUT_MAX (16) - -/** - * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries. - * - * When the ACK count ratio is low and aggregated BA timeout retries exceeding - * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal - * operation state. - */ -bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt) -{ - int actual_delta, expected_delta, ba_timeout_delta; - struct statistics_tx *cur, *old; - - if (priv->_agn.agg_tids_count) - return true; - - if (iwl_bt_statistics(priv)) { - cur = &pkt->u.stats_bt.tx; - old = &priv->_agn.statistics_bt.tx; - } else { - cur = &pkt->u.stats.tx; - old = &priv->_agn.statistics.tx; - } - - actual_delta = le32_to_cpu(cur->actual_ack_cnt) - - le32_to_cpu(old->actual_ack_cnt); - expected_delta = le32_to_cpu(cur->expected_ack_cnt) - - le32_to_cpu(old->expected_ack_cnt); - - /* Values should not be negative, but we do not trust the firmware */ - if (actual_delta <= 0 || expected_delta <= 0) - return true; - - ba_timeout_delta = le32_to_cpu(cur->agg.ba_timeout) - - le32_to_cpu(old->agg.ba_timeout); - - if ((actual_delta * 100 / expected_delta) < ACK_CNT_RATIO && - ba_timeout_delta > BA_TIMEOUT_CNT) { - IWL_DEBUG_RADIO(priv, "deltas: actual %d expected %d ba_timeout %d\n", - actual_delta, expected_delta, ba_timeout_delta); - -#ifdef CONFIG_IWLWIFI_DEBUGFS - /* - * This is ifdef'ed on DEBUGFS because otherwise the - * statistics aren't available. If DEBUGFS is set but - * DEBUG is not, these will just compile out. - */ - IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n", - priv->_agn.delta_statistics.tx.rx_detected_cnt); - IWL_DEBUG_RADIO(priv, - "ack_or_ba_timeout_collision delta %d\n", - priv->_agn.delta_statistics.tx.ack_or_ba_timeout_collision); -#endif - - if (ba_timeout_delta >= BA_TIMEOUT_MAX) - return false; - } - - return true; -} - - /***************************************************************************** * * sysfs attributes diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 88c7210dfb91..b5a169be48e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -121,8 +121,6 @@ void iwl_disable_ict(struct iwl_priv *priv); int iwl_alloc_isr_ict(struct iwl_priv *priv); void iwl_free_isr_ict(struct iwl_priv *priv); irqreturn_t iwl_isr_ict(int irq, void *data); -bool iwl_good_ack_health(struct iwl_priv *priv, - struct iwl_rx_packet *pkt); /* tx queue */ void iwlagn_set_wr_ptrs(struct iwl_priv *priv, @@ -248,8 +246,6 @@ u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid); /* rx */ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); -bool iwl_good_plcp_health(struct iwl_priv *priv, - struct iwl_rx_packet *pkt); void iwl_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); void iwl_reply_statistics(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 1be7f2957411..193ca98a6231 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -210,12 +210,7 @@ struct iwl_lib_ops { /* temperature */ struct iwl_temp_ops temp_ops; - /* check for plcp health */ - bool (*check_plcp_health)(struct iwl_priv *priv, - struct iwl_rx_packet *pkt); - /* check for ack health */ - bool (*check_ack_health)(struct iwl_priv *priv, - struct iwl_rx_packet *pkt); + int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control); void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control); diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index fd84d53db3ac..feee76181ac5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -227,8 +227,158 @@ void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, priv->measurement_status |= MEASUREMENT_READY; } -void iwl_recover_from_statistics(struct iwl_priv *priv, - struct iwl_rx_packet *pkt) +/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */ +#define ACK_CNT_RATIO (50) +#define BA_TIMEOUT_CNT (5) +#define BA_TIMEOUT_MAX (16) + +/** + * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries. + * + * When the ACK count ratio is low and aggregated BA timeout retries exceeding + * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal + * operation state. + */ +static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt) +{ + int actual_delta, expected_delta, ba_timeout_delta; + struct statistics_tx *cur, *old; + + if (priv->_agn.agg_tids_count) + return true; + + if (iwl_bt_statistics(priv)) { + cur = &pkt->u.stats_bt.tx; + old = &priv->_agn.statistics_bt.tx; + } else { + cur = &pkt->u.stats.tx; + old = &priv->_agn.statistics.tx; + } + + actual_delta = le32_to_cpu(cur->actual_ack_cnt) - + le32_to_cpu(old->actual_ack_cnt); + expected_delta = le32_to_cpu(cur->expected_ack_cnt) - + le32_to_cpu(old->expected_ack_cnt); + + /* Values should not be negative, but we do not trust the firmware */ + if (actual_delta <= 0 || expected_delta <= 0) + return true; + + ba_timeout_delta = le32_to_cpu(cur->agg.ba_timeout) - + le32_to_cpu(old->agg.ba_timeout); + + if ((actual_delta * 100 / expected_delta) < ACK_CNT_RATIO && + ba_timeout_delta > BA_TIMEOUT_CNT) { + IWL_DEBUG_RADIO(priv, "deltas: actual %d expected %d ba_timeout %d\n", + actual_delta, expected_delta, ba_timeout_delta); + +#ifdef CONFIG_IWLWIFI_DEBUGFS + /* + * This is ifdef'ed on DEBUGFS because otherwise the + * statistics aren't available. If DEBUGFS is set but + * DEBUG is not, these will just compile out. + */ + IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n", + priv->_agn.delta_statistics.tx.rx_detected_cnt); + IWL_DEBUG_RADIO(priv, + "ack_or_ba_timeout_collision delta %d\n", + priv->_agn.delta_statistics.tx.ack_or_ba_timeout_collision); +#endif + + if (ba_timeout_delta >= BA_TIMEOUT_MAX) + return false; + } + + return true; +} + +/** + * iwl_good_plcp_health - checks for plcp error. + * + * When the plcp error is exceeding the thresholds, reset the radio + * to improve the throughput. + */ +static bool iwl_good_plcp_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt) +{ + bool rc = true; + int combined_plcp_delta; + unsigned int plcp_msec; + unsigned long plcp_received_jiffies; + + if (priv->cfg->base_params->plcp_delta_threshold == + IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { + IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); + return rc; + } + + /* + * check for plcp_err and trigger radio reset if it exceeds + * the plcp error threshold plcp_delta. + */ + plcp_received_jiffies = jiffies; + plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - + (long) priv->plcp_jiffies); + priv->plcp_jiffies = plcp_received_jiffies; + /* + * check to make sure plcp_msec is not 0 to prevent division + * by zero. + */ + if (plcp_msec) { + struct statistics_rx_phy *ofdm; + struct statistics_rx_ht_phy *ofdm_ht; + + if (iwl_bt_statistics(priv)) { + ofdm = &pkt->u.stats_bt.rx.ofdm; + ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht; + combined_plcp_delta = + (le32_to_cpu(ofdm->plcp_err) - + le32_to_cpu(priv->_agn.statistics_bt. + rx.ofdm.plcp_err)) + + (le32_to_cpu(ofdm_ht->plcp_err) - + le32_to_cpu(priv->_agn.statistics_bt. + rx.ofdm_ht.plcp_err)); + } else { + ofdm = &pkt->u.stats.rx.ofdm; + ofdm_ht = &pkt->u.stats.rx.ofdm_ht; + combined_plcp_delta = + (le32_to_cpu(ofdm->plcp_err) - + le32_to_cpu(priv->_agn.statistics. + rx.ofdm.plcp_err)) + + (le32_to_cpu(ofdm_ht->plcp_err) - + le32_to_cpu(priv->_agn.statistics. + rx.ofdm_ht.plcp_err)); + } + + if ((combined_plcp_delta > 0) && + ((combined_plcp_delta * 100) / plcp_msec) > + priv->cfg->base_params->plcp_delta_threshold) { + /* + * if plcp_err exceed the threshold, + * the following data is printed in csv format: + * Text: plcp_err exceeded %d, + * Received ofdm.plcp_err, + * Current ofdm.plcp_err, + * Received ofdm_ht.plcp_err, + * Current ofdm_ht.plcp_err, + * combined_plcp_delta, + * plcp_msec + */ + IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " + "%u, %u, %u, %u, %d, %u mSecs\n", + priv->cfg->base_params->plcp_delta_threshold, + le32_to_cpu(ofdm->plcp_err), + le32_to_cpu(ofdm->plcp_err), + le32_to_cpu(ofdm_ht->plcp_err), + le32_to_cpu(ofdm_ht->plcp_err), + combined_plcp_delta, plcp_msec); + + rc = false; + } + } + return rc; +} + +void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt) { const struct iwl_mod_params *mod_params = priv->cfg->mod_params; @@ -236,17 +386,13 @@ void iwl_recover_from_statistics(struct iwl_priv *priv, !iwl_is_any_associated(priv)) return; - if (mod_params->ack_check && - priv->cfg->ops->lib->check_ack_health && - !priv->cfg->ops->lib->check_ack_health(priv, pkt)) { + if (mod_params->ack_check && !iwl_good_ack_health(priv, pkt)) { IWL_ERR(priv, "low ack count detected, restart firmware\n"); if (!iwl_force_reset(priv, IWL_FW_RESET, false)) return; } - if (mod_params->plcp_check && - priv->cfg->ops->lib->check_plcp_health && - !priv->cfg->ops->lib->check_plcp_health(priv, pkt)) + if (mod_params->plcp_check && !iwl_good_plcp_health(priv, pkt)) iwl_force_reset(priv, IWL_RF_RESET, false); } -- cgit v1.2.3 From 67289941d80f18fd8239e350e015a4b84878412b Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 28 Feb 2011 14:33:17 +0100 Subject: iwlwifi: move remaining iwl-agn-rx.c code into iwl-rx.c There is no need to have separate iwl-agn-rx.c file after iwlegacy split. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Makefile | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 264 ------------------------------ drivers/net/wireless/iwlwifi/iwl-core.h | 2 - drivers/net/wireless/iwlwifi/iwl-rx.c | 226 ++++++++++++++++++++++++- 4 files changed, 225 insertions(+), 269 deletions(-) delete mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-rx.c (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index aab7d15bd5ed..9d6ee836426c 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -2,7 +2,7 @@ obj-$(CONFIG_IWLAGN) += iwlagn.o iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o -iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o +iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o iwlagn-objs += iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c deleted file mode 100644 index 7a89a55ec316..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ /dev/null @@ -1,264 +0,0 @@ -/****************************************************************************** - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include -#include - -#include "iwl-dev.h" -#include "iwl-core.h" -#include "iwl-agn-calib.h" -#include "iwl-sta.h" -#include "iwl-io.h" -#include "iwl-helpers.h" -#include "iwl-agn-hw.h" -#include "iwl-agn.h" - -void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) - -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_missed_beacon_notif *missed_beacon; - - missed_beacon = &pkt->u.missed_beacon; - if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) > - priv->missed_beacon_threshold) { - IWL_DEBUG_CALIB(priv, - "missed bcn cnsq %d totl %d rcd %d expctd %d\n", - le32_to_cpu(missed_beacon->consecutive_missed_beacons), - le32_to_cpu(missed_beacon->total_missed_becons), - le32_to_cpu(missed_beacon->num_recvd_beacons), - le32_to_cpu(missed_beacon->num_expected_beacons)); - if (!test_bit(STATUS_SCANNING, &priv->status)) - iwl_init_sensitivity(priv); - } -} - -/* Calculate noise level, based on measurements during network silence just - * before arriving beacon. This measurement can be done only if we know - * exactly when to expect beacons, therefore only when we're associated. */ -static void iwl_rx_calc_noise(struct iwl_priv *priv) -{ - struct statistics_rx_non_phy *rx_info; - int num_active_rx = 0; - int total_silence = 0; - int bcn_silence_a, bcn_silence_b, bcn_silence_c; - int last_rx_noise; - - if (iwl_bt_statistics(priv)) - rx_info = &(priv->_agn.statistics_bt.rx.general.common); - else - rx_info = &(priv->_agn.statistics.rx.general); - bcn_silence_a = - le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; - bcn_silence_b = - le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER; - bcn_silence_c = - le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER; - - if (bcn_silence_a) { - total_silence += bcn_silence_a; - num_active_rx++; - } - if (bcn_silence_b) { - total_silence += bcn_silence_b; - num_active_rx++; - } - if (bcn_silence_c) { - total_silence += bcn_silence_c; - num_active_rx++; - } - - /* Average among active antennas */ - if (num_active_rx) - last_rx_noise = (total_silence / num_active_rx) - 107; - else - last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; - - IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n", - bcn_silence_a, bcn_silence_b, bcn_silence_c, - last_rx_noise); -} - -#ifdef CONFIG_IWLWIFI_DEBUGFS -/* - * based on the assumption of all statistics counter are in DWORD - * FIXME: This function is for debugging, do not deal with - * the case of counters roll-over. - */ -static void iwl_accumulative_statistics(struct iwl_priv *priv, - __le32 *stats) -{ - int i, size; - __le32 *prev_stats; - u32 *accum_stats; - u32 *delta, *max_delta; - struct statistics_general_common *general, *accum_general; - struct statistics_tx *tx, *accum_tx; - - if (iwl_bt_statistics(priv)) { - prev_stats = (__le32 *)&priv->_agn.statistics_bt; - accum_stats = (u32 *)&priv->_agn.accum_statistics_bt; - size = sizeof(struct iwl_bt_notif_statistics); - general = &priv->_agn.statistics_bt.general.common; - accum_general = &priv->_agn.accum_statistics_bt.general.common; - tx = &priv->_agn.statistics_bt.tx; - accum_tx = &priv->_agn.accum_statistics_bt.tx; - delta = (u32 *)&priv->_agn.delta_statistics_bt; - max_delta = (u32 *)&priv->_agn.max_delta_bt; - } else { - prev_stats = (__le32 *)&priv->_agn.statistics; - accum_stats = (u32 *)&priv->_agn.accum_statistics; - size = sizeof(struct iwl_notif_statistics); - general = &priv->_agn.statistics.general.common; - accum_general = &priv->_agn.accum_statistics.general.common; - tx = &priv->_agn.statistics.tx; - accum_tx = &priv->_agn.accum_statistics.tx; - delta = (u32 *)&priv->_agn.delta_statistics; - max_delta = (u32 *)&priv->_agn.max_delta; - } - for (i = sizeof(__le32); i < size; - i += sizeof(__le32), stats++, prev_stats++, delta++, - max_delta++, accum_stats++) { - if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { - *delta = (le32_to_cpu(*stats) - - le32_to_cpu(*prev_stats)); - *accum_stats += *delta; - if (*delta > *max_delta) - *max_delta = *delta; - } - } - - /* reset accumulative statistics for "no-counter" type statistics */ - accum_general->temperature = general->temperature; - accum_general->temperature_m = general->temperature_m; - accum_general->ttl_timestamp = general->ttl_timestamp; - accum_tx->tx_power.ant_a = tx->tx_power.ant_a; - accum_tx->tx_power.ant_b = tx->tx_power.ant_b; - accum_tx->tx_power.ant_c = tx->tx_power.ant_c; -} -#endif - -#define REG_RECALIB_PERIOD (60) - -void iwl_rx_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - int change; - struct iwl_rx_packet *pkt = rxb_addr(rxb); - - if (iwl_bt_statistics(priv)) { - IWL_DEBUG_RX(priv, - "Statistics notification received (%d vs %d).\n", - (int)sizeof(struct iwl_bt_notif_statistics), - le32_to_cpu(pkt->len_n_flags) & - FH_RSCSR_FRAME_SIZE_MSK); - - change = ((priv->_agn.statistics_bt.general.common.temperature != - pkt->u.stats_bt.general.common.temperature) || - ((priv->_agn.statistics_bt.flag & - STATISTICS_REPLY_FLG_HT40_MODE_MSK) != - (pkt->u.stats_bt.flag & - STATISTICS_REPLY_FLG_HT40_MODE_MSK))); -#ifdef CONFIG_IWLWIFI_DEBUGFS - iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt); -#endif - - } else { - IWL_DEBUG_RX(priv, - "Statistics notification received (%d vs %d).\n", - (int)sizeof(struct iwl_notif_statistics), - le32_to_cpu(pkt->len_n_flags) & - FH_RSCSR_FRAME_SIZE_MSK); - - change = ((priv->_agn.statistics.general.common.temperature != - pkt->u.stats.general.common.temperature) || - ((priv->_agn.statistics.flag & - STATISTICS_REPLY_FLG_HT40_MODE_MSK) != - (pkt->u.stats.flag & - STATISTICS_REPLY_FLG_HT40_MODE_MSK))); -#ifdef CONFIG_IWLWIFI_DEBUGFS - iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); -#endif - - } - - iwl_recover_from_statistics(priv, pkt); - - if (iwl_bt_statistics(priv)) - memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt, - sizeof(priv->_agn.statistics_bt)); - else - memcpy(&priv->_agn.statistics, &pkt->u.stats, - sizeof(priv->_agn.statistics)); - - set_bit(STATUS_STATISTICS, &priv->status); - - /* Reschedule the statistics timer to occur in - * REG_RECALIB_PERIOD seconds to ensure we get a - * thermal update even if the uCode doesn't give - * us one */ - mod_timer(&priv->statistics_periodic, jiffies + - msecs_to_jiffies(REG_RECALIB_PERIOD * 1000)); - - if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && - (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { - iwl_rx_calc_noise(priv); - queue_work(priv->workqueue, &priv->run_time_calib_work); - } - if (priv->cfg->ops->lib->temp_ops.temperature && change) - priv->cfg->ops->lib->temp_ops.temperature(priv); -} - -void iwl_reply_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - - if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { -#ifdef CONFIG_IWLWIFI_DEBUGFS - memset(&priv->_agn.accum_statistics, 0, - sizeof(struct iwl_notif_statistics)); - memset(&priv->_agn.delta_statistics, 0, - sizeof(struct iwl_notif_statistics)); - memset(&priv->_agn.max_delta, 0, - sizeof(struct iwl_notif_statistics)); - memset(&priv->_agn.accum_statistics_bt, 0, - sizeof(struct iwl_bt_notif_statistics)); - memset(&priv->_agn.delta_statistics_bt, 0, - sizeof(struct iwl_bt_notif_statistics)); - memset(&priv->_agn.max_delta_bt, 0, - sizeof(struct iwl_bt_notif_statistics)); -#endif - IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); - } - iwl_rx_statistics(priv, rxb); -} diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 193ca98a6231..d47f3a87fce4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -516,8 +516,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); /* Handlers */ void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); -void iwl_recover_from_statistics(struct iwl_priv *priv, - struct iwl_rx_packet *pkt); void iwl_chswitch_done(struct iwl_priv *priv, bool is_success); void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index feee76181ac5..566e2d979ce3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -37,6 +37,7 @@ #include "iwl-sta.h" #include "iwl-io.h" #include "iwl-helpers.h" +#include "iwl-agn-calib.h" /************************** RX-FUNCTIONS ****************************/ /* * Rx theory of operation @@ -210,7 +211,6 @@ err_bd: return -ENOMEM; } - void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { @@ -378,7 +378,7 @@ static bool iwl_good_plcp_health(struct iwl_priv *priv, struct iwl_rx_packet *pk return rc; } -void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt) +static void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt) { const struct iwl_mod_params *mod_params = priv->cfg->mod_params; @@ -396,6 +396,228 @@ void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pk iwl_force_reset(priv, IWL_RF_RESET, false); } +/* Calculate noise level, based on measurements during network silence just + * before arriving beacon. This measurement can be done only if we know + * exactly when to expect beacons, therefore only when we're associated. */ +static void iwl_rx_calc_noise(struct iwl_priv *priv) +{ + struct statistics_rx_non_phy *rx_info; + int num_active_rx = 0; + int total_silence = 0; + int bcn_silence_a, bcn_silence_b, bcn_silence_c; + int last_rx_noise; + + if (iwl_bt_statistics(priv)) + rx_info = &(priv->_agn.statistics_bt.rx.general.common); + else + rx_info = &(priv->_agn.statistics.rx.general); + bcn_silence_a = + le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER; + bcn_silence_b = + le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER; + bcn_silence_c = + le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER; + + if (bcn_silence_a) { + total_silence += bcn_silence_a; + num_active_rx++; + } + if (bcn_silence_b) { + total_silence += bcn_silence_b; + num_active_rx++; + } + if (bcn_silence_c) { + total_silence += bcn_silence_c; + num_active_rx++; + } + + /* Average among active antennas */ + if (num_active_rx) + last_rx_noise = (total_silence / num_active_rx) - 107; + else + last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; + + IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n", + bcn_silence_a, bcn_silence_b, bcn_silence_c, + last_rx_noise); +} + +#ifdef CONFIG_IWLWIFI_DEBUGFS +/* + * based on the assumption of all statistics counter are in DWORD + * FIXME: This function is for debugging, do not deal with + * the case of counters roll-over. + */ +static void iwl_accumulative_statistics(struct iwl_priv *priv, + __le32 *stats) +{ + int i, size; + __le32 *prev_stats; + u32 *accum_stats; + u32 *delta, *max_delta; + struct statistics_general_common *general, *accum_general; + struct statistics_tx *tx, *accum_tx; + + if (iwl_bt_statistics(priv)) { + prev_stats = (__le32 *)&priv->_agn.statistics_bt; + accum_stats = (u32 *)&priv->_agn.accum_statistics_bt; + size = sizeof(struct iwl_bt_notif_statistics); + general = &priv->_agn.statistics_bt.general.common; + accum_general = &priv->_agn.accum_statistics_bt.general.common; + tx = &priv->_agn.statistics_bt.tx; + accum_tx = &priv->_agn.accum_statistics_bt.tx; + delta = (u32 *)&priv->_agn.delta_statistics_bt; + max_delta = (u32 *)&priv->_agn.max_delta_bt; + } else { + prev_stats = (__le32 *)&priv->_agn.statistics; + accum_stats = (u32 *)&priv->_agn.accum_statistics; + size = sizeof(struct iwl_notif_statistics); + general = &priv->_agn.statistics.general.common; + accum_general = &priv->_agn.accum_statistics.general.common; + tx = &priv->_agn.statistics.tx; + accum_tx = &priv->_agn.accum_statistics.tx; + delta = (u32 *)&priv->_agn.delta_statistics; + max_delta = (u32 *)&priv->_agn.max_delta; + } + for (i = sizeof(__le32); i < size; + i += sizeof(__le32), stats++, prev_stats++, delta++, + max_delta++, accum_stats++) { + if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { + *delta = (le32_to_cpu(*stats) - + le32_to_cpu(*prev_stats)); + *accum_stats += *delta; + if (*delta > *max_delta) + *max_delta = *delta; + } + } + + /* reset accumulative statistics for "no-counter" type statistics */ + accum_general->temperature = general->temperature; + accum_general->temperature_m = general->temperature_m; + accum_general->ttl_timestamp = general->ttl_timestamp; + accum_tx->tx_power.ant_a = tx->tx_power.ant_a; + accum_tx->tx_power.ant_b = tx->tx_power.ant_b; + accum_tx->tx_power.ant_c = tx->tx_power.ant_c; +} +#endif + +#define REG_RECALIB_PERIOD (60) + +void iwl_rx_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + int change; + struct iwl_rx_packet *pkt = rxb_addr(rxb); + + if (iwl_bt_statistics(priv)) { + IWL_DEBUG_RX(priv, + "Statistics notification received (%d vs %d).\n", + (int)sizeof(struct iwl_bt_notif_statistics), + le32_to_cpu(pkt->len_n_flags) & + FH_RSCSR_FRAME_SIZE_MSK); + + change = ((priv->_agn.statistics_bt.general.common.temperature != + pkt->u.stats_bt.general.common.temperature) || + ((priv->_agn.statistics_bt.flag & + STATISTICS_REPLY_FLG_HT40_MODE_MSK) != + (pkt->u.stats_bt.flag & + STATISTICS_REPLY_FLG_HT40_MODE_MSK))); +#ifdef CONFIG_IWLWIFI_DEBUGFS + iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt); +#endif + + } else { + IWL_DEBUG_RX(priv, + "Statistics notification received (%d vs %d).\n", + (int)sizeof(struct iwl_notif_statistics), + le32_to_cpu(pkt->len_n_flags) & + FH_RSCSR_FRAME_SIZE_MSK); + + change = ((priv->_agn.statistics.general.common.temperature != + pkt->u.stats.general.common.temperature) || + ((priv->_agn.statistics.flag & + STATISTICS_REPLY_FLG_HT40_MODE_MSK) != + (pkt->u.stats.flag & + STATISTICS_REPLY_FLG_HT40_MODE_MSK))); +#ifdef CONFIG_IWLWIFI_DEBUGFS + iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); +#endif + + } + + iwl_recover_from_statistics(priv, pkt); + + if (iwl_bt_statistics(priv)) + memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt, + sizeof(priv->_agn.statistics_bt)); + else + memcpy(&priv->_agn.statistics, &pkt->u.stats, + sizeof(priv->_agn.statistics)); + + set_bit(STATUS_STATISTICS, &priv->status); + + /* Reschedule the statistics timer to occur in + * REG_RECALIB_PERIOD seconds to ensure we get a + * thermal update even if the uCode doesn't give + * us one */ + mod_timer(&priv->statistics_periodic, jiffies + + msecs_to_jiffies(REG_RECALIB_PERIOD * 1000)); + + if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && + (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { + iwl_rx_calc_noise(priv); + queue_work(priv->workqueue, &priv->run_time_calib_work); + } + if (priv->cfg->ops->lib->temp_ops.temperature && change) + priv->cfg->ops->lib->temp_ops.temperature(priv); +} + +void iwl_reply_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + + if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { +#ifdef CONFIG_IWLWIFI_DEBUGFS + memset(&priv->_agn.accum_statistics, 0, + sizeof(struct iwl_notif_statistics)); + memset(&priv->_agn.delta_statistics, 0, + sizeof(struct iwl_notif_statistics)); + memset(&priv->_agn.max_delta, 0, + sizeof(struct iwl_notif_statistics)); + memset(&priv->_agn.accum_statistics_bt, 0, + sizeof(struct iwl_bt_notif_statistics)); + memset(&priv->_agn.delta_statistics_bt, 0, + sizeof(struct iwl_bt_notif_statistics)); + memset(&priv->_agn.max_delta_bt, 0, + sizeof(struct iwl_bt_notif_statistics)); +#endif + IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); + } + iwl_rx_statistics(priv, rxb); +} + +void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) + +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_missed_beacon_notif *missed_beacon; + + missed_beacon = &pkt->u.missed_beacon; + if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) > + priv->missed_beacon_threshold) { + IWL_DEBUG_CALIB(priv, + "missed bcn cnsq %d totl %d rcd %d expctd %d\n", + le32_to_cpu(missed_beacon->consecutive_missed_beacons), + le32_to_cpu(missed_beacon->total_missed_becons), + le32_to_cpu(missed_beacon->num_recvd_beacons), + le32_to_cpu(missed_beacon->num_expected_beacons)); + if (!test_bit(STATUS_SCANNING, &priv->status)) + iwl_init_sensitivity(priv); + } +} + /* * returns non-zero if packet should be dropped */ -- cgit v1.2.3 From ff938e43d39e926de74b32a3656c190f979ab642 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 28 Feb 2011 11:57:33 -0800 Subject: net: use pci_dev->revision, again Several more network drivers that read the device's revision ID from the PCI configuration register were merged after the commit 44c10138fd4bbc4b6d6bff0873c24902f2a9da65 (PCI: Change all drivers to use pci_device->revision), so it's time to do another pass of conversion to using the 'revision' field of 'struct pci_dev'... Signed-off-by: Sergei Shtylyov Acked-by: "John W. Linville" Signed-off-by: David S. Miller --- drivers/net/atl1e/atl1e_main.c | 2 +- drivers/net/atlx/atl2.c | 2 +- drivers/net/cnic.c | 14 +++++--------- drivers/net/e1000e/ethtool.c | 6 ++---- drivers/net/igbvf/ethtool.c | 6 ++---- drivers/net/igbvf/netdev.c | 3 +-- drivers/net/ipg.c | 4 +--- drivers/net/ixgbevf/ixgbevf_main.c | 2 +- drivers/net/jme.c | 2 +- drivers/net/vxge/vxge-main.c | 18 +----------------- drivers/net/wireless/iwlwifi/iwl-3945.c | 4 +--- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/rtlwifi/pci.c | 4 +--- 13 files changed, 19 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index 21f501184023..1ff001a8270c 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -547,8 +547,8 @@ static int __devinit atl1e_sw_init(struct atl1e_adapter *adapter) hw->device_id = pdev->device; hw->subsystem_vendor_id = pdev->subsystem_vendor; hw->subsystem_id = pdev->subsystem_device; + hw->revision_id = pdev->revision; - pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id); pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); phy_status_data = AT_READ_REG(hw, REG_PHY_STATUS); diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index 4e6f4e95a5a0..e637e9f28fd4 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c @@ -93,8 +93,8 @@ static int __devinit atl2_sw_init(struct atl2_adapter *adapter) hw->device_id = pdev->device; hw->subsystem_vendor_id = pdev->subsystem_vendor; hw->subsystem_id = pdev->subsystem_device; + hw->revision_id = pdev->revision; - pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id); pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); adapter->wol = 0; diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 2d2d28f58e91..5274de3e1bb9 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -5158,15 +5158,11 @@ static struct cnic_dev *init_bnx2_cnic(struct net_device *dev) dev_hold(dev); pci_dev_get(pdev); - if (pdev->device == PCI_DEVICE_ID_NX2_5709 || - pdev->device == PCI_DEVICE_ID_NX2_5709S) { - u8 rev; - - pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); - if (rev < 0x10) { - pci_dev_put(pdev); - goto cnic_err; - } + if ((pdev->device == PCI_DEVICE_ID_NX2_5709 || + pdev->device == PCI_DEVICE_ID_NX2_5709S) && + (pdev->revision < 0x10)) { + pci_dev_put(pdev); + goto cnic_err; } pci_dev_put(pdev); diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 65ef9b5548d8..d4e51aa231b9 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -433,13 +433,11 @@ static void e1000_get_regs(struct net_device *netdev, struct e1000_hw *hw = &adapter->hw; u32 *regs_buff = p; u16 phy_data; - u8 revision_id; memset(p, 0, E1000_REGS_LEN * sizeof(u32)); - pci_read_config_byte(adapter->pdev, PCI_REVISION_ID, &revision_id); - - regs->version = (1 << 24) | (revision_id << 16) | adapter->pdev->device; + regs->version = (1 << 24) | (adapter->pdev->revision << 16) | + adapter->pdev->device; regs_buff[0] = er32(CTRL); regs_buff[1] = er32(STATUS); diff --git a/drivers/net/igbvf/ethtool.c b/drivers/net/igbvf/ethtool.c index ed6e3d910247..1d943aa7c7a6 100644 --- a/drivers/net/igbvf/ethtool.c +++ b/drivers/net/igbvf/ethtool.c @@ -201,13 +201,11 @@ static void igbvf_get_regs(struct net_device *netdev, struct igbvf_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; u32 *regs_buff = p; - u8 revision_id; memset(p, 0, IGBVF_REGS_LEN * sizeof(u32)); - pci_read_config_byte(adapter->pdev, PCI_REVISION_ID, &revision_id); - - regs->version = (1 << 24) | (revision_id << 16) | adapter->pdev->device; + regs->version = (1 << 24) | (adapter->pdev->revision << 16) | + adapter->pdev->device; regs_buff[0] = er32(CTRL); regs_buff[1] = er32(STATUS); diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 42fdf5977be9..6ccc32fd7338 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -2639,8 +2639,7 @@ static int __devinit igbvf_probe(struct pci_dev *pdev, hw->device_id = pdev->device; hw->subsystem_vendor_id = pdev->subsystem_vendor; hw->subsystem_device_id = pdev->subsystem_device; - - pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id); + hw->revision_id = pdev->revision; err = -EIO; adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, 0), diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index aa93655c3aa7..a5b0f0e194bb 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c @@ -2025,7 +2025,6 @@ static void ipg_init_mii(struct net_device *dev) if (phyaddr != 0x1f) { u16 mii_phyctrl, mii_1000cr; - u8 revisionid = 0; mii_1000cr = mdio_read(dev, phyaddr, MII_CTRL1000); mii_1000cr |= ADVERTISE_1000FULL | ADVERTISE_1000HALF | @@ -2035,8 +2034,7 @@ static void ipg_init_mii(struct net_device *dev) mii_phyctrl = mdio_read(dev, phyaddr, MII_BMCR); /* Set default phyparam */ - pci_read_config_byte(sp->pdev, PCI_REVISION_ID, &revisionid); - ipg_set_phy_default_param(revisionid, dev, phyaddr); + ipg_set_phy_default_param(sp->pdev->revision, dev, phyaddr); /* Reset PHY */ mii_phyctrl |= BMCR_RESET | BMCR_ANRESTART; diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 43af761cdb16..1e735a14091c 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -2221,7 +2221,7 @@ static int __devinit ixgbevf_sw_init(struct ixgbevf_adapter *adapter) hw->vendor_id = pdev->vendor; hw->device_id = pdev->device; - pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id); + hw->revision_id = pdev->revision; hw->subsystem_vendor_id = pdev->subsystem_vendor; hw->subsystem_device_id = pdev->subsystem_device; diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 5b441b75e138..f690474f4409 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -3095,7 +3095,7 @@ jme_init_one(struct pci_dev *pdev, jme_clear_pm(jme); jme_set_phyfifo_5level(jme); - pci_read_config_byte(pdev, PCI_REVISION_ID, &jme->pcirev); + jme->pcirev = pdev->revision; if (!jme->fpgaver) jme_phy_init(jme); jme_phy_off(jme); diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index e40f619b62b1..395423aeec00 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -3387,19 +3387,6 @@ static const struct net_device_ops vxge_netdev_ops = { #endif }; -static int __devinit vxge_device_revision(struct vxgedev *vdev) -{ - int ret; - u8 revision; - - ret = pci_read_config_byte(vdev->pdev, PCI_REVISION_ID, &revision); - if (ret) - return -EIO; - - vdev->titan1 = (revision == VXGE_HW_TITAN1_PCI_REVISION); - return 0; -} - static int __devinit vxge_device_register(struct __vxge_hw_device *hldev, struct vxge_config *config, int high_dma, int no_of_vpath, @@ -3439,10 +3426,7 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev, memcpy(&vdev->config, config, sizeof(struct vxge_config)); vdev->rx_csum = 1; /* Enable Rx CSUM by default. */ vdev->rx_hwts = 0; - - ret = vxge_device_revision(vdev); - if (ret < 0) - goto _out1; + vdev->titan1 = (vdev->pdev->revision == VXGE_HW_TITAN1_PCI_REVISION); SET_NETDEV_DEV(ndev, &vdev->pdev->dev); diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 166e9f742596..f4cd9370e7fa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -898,13 +898,11 @@ static void iwl3945_nic_config(struct iwl_priv *priv) { struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; unsigned long flags; - u8 rev_id = 0; + u8 rev_id = priv->pci_dev->revision; spin_lock_irqsave(&priv->lock, flags); /* Determine HW type */ - pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id); - IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id); if (rev_id & PCI_CFG_REV_ID_BIT_RTP) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index abd0461bd307..8025c62d4d0c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -4056,7 +4056,7 @@ static void iwl_hw_detect(struct iwl_priv *priv) { priv->hw_rev = _iwl_read32(priv, CSR_HW_REV); priv->hw_wa_rev = _iwl_read32(priv, CSR_HW_REV_WA_REG); - pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &priv->rev_id); + priv->rev_id = priv->pci_dev->revision; IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id); } diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 1f18bf7df741..9cd7703c2a30 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1477,13 +1477,11 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, struct pci_dev *bridge_pdev = pdev->bus->self; u16 venderid; u16 deviceid; - u8 revisionid; u16 irqline; u8 tmp; venderid = pdev->vendor; deviceid = pdev->device; - pci_read_config_byte(pdev, 0x8, &revisionid); pci_read_config_word(pdev, 0x3C, &irqline); if (deviceid == RTL_PCI_8192_DID || @@ -1494,7 +1492,7 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, deviceid == RTL_PCI_8173_DID || deviceid == RTL_PCI_8172_DID || deviceid == RTL_PCI_8171_DID) { - switch (revisionid) { + switch (pdev->revision) { case RTL_PCI_REVISION_ID_8192PCIE: RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("8192 PCI-E is found - " -- cgit v1.2.3 From 27aadb615a2d767d629966e88dc7212ceb7c712e Mon Sep 17 00:00:00 2001 From: Ken Kawasaki Date: Sun, 20 Feb 2011 05:07:20 +0000 Subject: fmvj18x_cs: add new id fmvj18x_cs:add new id Toshiba lan&modem multifuction card (model name:IPC5010A) Signed-off-by: Ken Kawasaki Signed-off-by: David S. Miller --- drivers/net/pcmcia/fmvj18x_cs.c | 1 + drivers/tty/serial/serial_cs.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 9226cda4d054..530ab5a10bd3 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -691,6 +691,7 @@ static struct pcmcia_device_id fmvj18x_ids[] = { PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0e0a), PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0e01), PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0a05), + PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0b05), PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x1101), PCMCIA_DEVICE_NULL, }; diff --git a/drivers/tty/serial/serial_cs.c b/drivers/tty/serial/serial_cs.c index 93760b2ea172..1ef4df9bf7e4 100644 --- a/drivers/tty/serial/serial_cs.c +++ b/drivers/tty/serial/serial_cs.c @@ -712,6 +712,7 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf), PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0e01), PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0a05), + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0b05), PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x1101), PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070), PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562), -- cgit v1.2.3 From 19d73f3c6fe86dca01e409f226ec51a0fde9662e Mon Sep 17 00:00:00 2001 From: Justin Mattock Date: Sun, 20 Feb 2011 20:31:21 +0000 Subject: drivers:isdn:istream.c Fix typo pice to piece The below patch changes a typo "pice" to "piece" Signed-off-by: Justin P. Mattock Signed-off-by: David S. Miller --- drivers/isdn/hardware/eicon/istream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/isdn/hardware/eicon/istream.c b/drivers/isdn/hardware/eicon/istream.c index 18f8798442fa..7bd5baa547be 100644 --- a/drivers/isdn/hardware/eicon/istream.c +++ b/drivers/isdn/hardware/eicon/istream.c @@ -62,7 +62,7 @@ void diva_xdi_provide_istream_info (ADAPTER* a, stream interface. If synchronous service was requested, then function does return amount of data written to stream. - 'final' does indicate that pice of data to be written is + 'final' does indicate that piece of data to be written is final part of frame (necessary only by structured datatransfer) return 0 if zero lengh packet was written return -1 if stream is full -- cgit v1.2.3 From dad3d44dcb054e9d0514fbf65ee4a2d88cf1698f Mon Sep 17 00:00:00 2001 From: Kurt Van Dijck Date: Sun, 20 Feb 2011 23:04:22 +0000 Subject: CAN: add controller hardware name for Softing cards I just found that the controller hardware name is not set for the Softing driver. After this patch, "$ ip -d link show" looks nicer. Signed-off-by: Kurt Van Dijck Acked-by: Marc Kleine-Budde Signed-off-by: David S. Miller --- drivers/net/can/softing/softing_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c index 5157e15e96eb..aeea9f9ff6e8 100644 --- a/drivers/net/can/softing/softing_main.c +++ b/drivers/net/can/softing/softing_main.c @@ -633,6 +633,7 @@ static const struct net_device_ops softing_netdev_ops = { }; static const struct can_bittiming_const softing_btr_const = { + .name = "softing", .tseg1_min = 1, .tseg1_max = 16, .tseg2_min = 1, -- cgit v1.2.3 From 985076720187af7ac0c2de4dfe912acba9b4f586 Mon Sep 17 00:00:00 2001 From: Shmulik Ravid Date: Mon, 28 Feb 2011 12:19:55 -0800 Subject: bnx2x: use dcb_setapp to manage negotiated application tlvs With this patch the bnx2x uses the generic dcbnl application tlv list instead of implementing its own get-app handler. When the driver is alerted to a change in the DCB negotiated parameters, it calls dcb_setapp to update the dcbnl application tlvs list making it available to user mode applications and registered notifiers. Signed-off-by: Shmulik Ravid Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 2 +- drivers/net/bnx2x/bnx2x_dcb.c | 137 ++++++++++++++++++++++++----------------- drivers/net/bnx2x/bnx2x_dcb.h | 5 +- drivers/net/bnx2x/bnx2x_main.c | 7 ++- 4 files changed, 92 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index c0dd30d870ae..1914026a7b63 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -31,7 +31,7 @@ #define BNX2X_NEW_NAPI #if defined(CONFIG_DCB) -#define BCM_DCB +#define BCM_DCBNL #endif #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE) #define BCM_CNIC 1 diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c index fb60021f81fb..9a24d79c71d9 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.c +++ b/drivers/net/bnx2x/bnx2x_dcb.c @@ -19,6 +19,9 @@ #include #include #include +#ifdef BCM_DCBNL +#include +#endif #include "bnx2x.h" #include "bnx2x_cmn.h" @@ -508,13 +511,75 @@ static int bnx2x_dcbx_read_shmem_neg_results(struct bnx2x *bp) return 0; } + +#ifdef BCM_DCBNL +static inline +u8 bnx2x_dcbx_dcbnl_app_up(struct dcbx_app_priority_entry *ent) +{ + u8 pri; + + /* Choose the highest priority */ + for (pri = MAX_PFC_PRIORITIES - 1; pri > 0; pri--) + if (ent->pri_bitmap & (1 << pri)) + break; + return pri; +} + +static inline +u8 bnx2x_dcbx_dcbnl_app_idtype(struct dcbx_app_priority_entry *ent) +{ + return ((ent->appBitfield & DCBX_APP_ENTRY_SF_MASK) == + DCBX_APP_SF_PORT) ? DCB_APP_IDTYPE_PORTNUM : + DCB_APP_IDTYPE_ETHTYPE; +} + +static inline +void bnx2x_dcbx_invalidate_local_apps(struct bnx2x *bp) +{ + int i; + for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) + bp->dcbx_local_feat.app.app_pri_tbl[i].appBitfield &= + ~DCBX_APP_ENTRY_VALID; +} + +int bnx2x_dcbnl_update_applist(struct bnx2x *bp, bool delall) +{ + int i, err = 0; + + for (i = 0; i < DCBX_MAX_APP_PROTOCOL && err == 0; i++) { + struct dcbx_app_priority_entry *ent = + &bp->dcbx_local_feat.app.app_pri_tbl[i]; + + if (ent->appBitfield & DCBX_APP_ENTRY_VALID) { + u8 up = bnx2x_dcbx_dcbnl_app_up(ent); + + /* avoid invalid user-priority */ + if (up) { + struct dcb_app app; + app.selector = bnx2x_dcbx_dcbnl_app_idtype(ent); + app.protocol = ent->app_id; + app.priority = delall ? 0 : up; + err = dcb_setapp(bp->dev, &app); + } + } + } + return err; +} +#endif + void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) { switch (state) { case BNX2X_DCBX_STATE_NEG_RECEIVED: { DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_NEG_RECEIVED\n"); - +#ifdef BCM_DCBNL + /** + * Delete app tlvs from dcbnl before reading new + * negotiation results + */ + bnx2x_dcbnl_update_applist(bp, true); +#endif /* Read neg results if dcbx is in the FW */ if (bnx2x_dcbx_read_shmem_neg_results(bp)) return; @@ -526,10 +591,24 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) bp->dcbx_error); if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) { +#ifdef BCM_DCBNL + /** + * Add new app tlvs to dcbnl + */ + bnx2x_dcbnl_update_applist(bp, false); +#endif bnx2x_dcbx_stop_hw_tx(bp); return; } /* fall through */ +#ifdef BCM_DCBNL + /** + * Invalidate the local app tlvs if they are not added + * to the dcbnl app list to avoid deleting them from + * the list later on + */ + bnx2x_dcbx_invalidate_local_apps(bp); +#endif } case BNX2X_DCBX_STATE_TX_PAUSED: DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_TX_PAUSED\n"); @@ -1505,8 +1584,7 @@ static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp) bnx2x_dcbx_print_cos_params(bp, pfc_fw_cfg); } /* DCB netlink */ -#ifdef BCM_DCB -#include +#ifdef BCM_DCBNL #define BNX2X_DCBX_CAPS (DCB_CAP_DCBX_LLD_MANAGED | \ DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_STATIC) @@ -1816,32 +1894,6 @@ static void bnx2x_dcbnl_set_pfc_state(struct net_device *netdev, u8 state) bp->dcbx_config_params.admin_pfc_enable = (state ? 1 : 0); } -static bool bnx2x_app_is_equal(struct dcbx_app_priority_entry *app_ent, - u8 idtype, u16 idval) -{ - if (!(app_ent->appBitfield & DCBX_APP_ENTRY_VALID)) - return false; - - switch (idtype) { - case DCB_APP_IDTYPE_ETHTYPE: - if ((app_ent->appBitfield & DCBX_APP_ENTRY_SF_MASK) != - DCBX_APP_SF_ETH_TYPE) - return false; - break; - case DCB_APP_IDTYPE_PORTNUM: - if ((app_ent->appBitfield & DCBX_APP_ENTRY_SF_MASK) != - DCBX_APP_SF_PORT) - return false; - break; - default: - return false; - } - if (app_ent->app_id != idval) - return false; - - return true; -} - static void bnx2x_admin_app_set_ent( struct bnx2x_admin_priority_app_table *app_ent, u8 idtype, u16 idval, u8 up) @@ -1943,30 +1995,6 @@ static u8 bnx2x_dcbnl_set_app_up(struct net_device *netdev, u8 idtype, return bnx2x_set_admin_app_up(bp, idtype, idval, up); } -static u8 bnx2x_dcbnl_get_app_up(struct net_device *netdev, u8 idtype, - u16 idval) -{ - int i; - u8 up = 0; - - struct bnx2x *bp = netdev_priv(netdev); - DP(NETIF_MSG_LINK, "app_type %d, app_id 0x%x\n", idtype, idval); - - /* iterate over the app entries looking for idtype and idval */ - for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) - if (bnx2x_app_is_equal(&bp->dcbx_local_feat.app.app_pri_tbl[i], - idtype, idval)) - break; - - if (i < DCBX_MAX_APP_PROTOCOL) - /* if found return up */ - up = bp->dcbx_local_feat.app.app_pri_tbl[i].pri_bitmap; - else - DP(NETIF_MSG_LINK, "app not found\n"); - - return up; -} - static u8 bnx2x_dcbnl_get_dcbx(struct net_device *netdev) { struct bnx2x *bp = netdev_priv(netdev); @@ -2107,7 +2135,6 @@ const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops = { .setnumtcs = bnx2x_dcbnl_set_numtcs, .getpfcstate = bnx2x_dcbnl_get_pfc_state, .setpfcstate = bnx2x_dcbnl_set_pfc_state, - .getapp = bnx2x_dcbnl_get_app_up, .setapp = bnx2x_dcbnl_set_app_up, .getdcbx = bnx2x_dcbnl_get_dcbx, .setdcbx = bnx2x_dcbnl_set_dcbx, @@ -2115,4 +2142,4 @@ const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops = { .setfeatcfg = bnx2x_dcbnl_set_featcfg, }; -#endif /* BCM_DCB */ +#endif /* BCM_DCBNL */ diff --git a/drivers/net/bnx2x/bnx2x_dcb.h b/drivers/net/bnx2x/bnx2x_dcb.h index f650f98e4092..71b8eda43bd0 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.h +++ b/drivers/net/bnx2x/bnx2x_dcb.h @@ -189,8 +189,9 @@ enum { void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state); /* DCB netlink */ -#ifdef BCM_DCB +#ifdef BCM_DCBNL extern const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops; -#endif /* BCM_DCB */ +int bnx2x_dcbnl_update_applist(struct bnx2x *bp, bool delall); +#endif /* BCM_DCBNL */ #endif /* BNX2X_DCB_H */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 6c7745eee00d..061733e5e5ca 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -9441,7 +9441,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); dev->vlan_features |= NETIF_F_TSO6; -#ifdef BCM_DCB +#ifdef BCM_DCBNL dev->dcbnl_ops = &bnx2x_dcbnl_ops; #endif @@ -9848,6 +9848,11 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) } #endif +#ifdef BCM_DCBNL + /* Delete app tlvs from dcbnl */ + bnx2x_dcbnl_update_applist(bp, true); +#endif + unregister_netdev(dev); /* Delete all NAPI objects */ -- cgit v1.2.3 From 915239472a5015c7667025551a73e11d6e2abee0 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Mon, 28 Feb 2011 04:05:25 +0000 Subject: macb: don't use platform_set_drvdata() on a net_device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 71d6429 (Driver core: convert platform_{get,set}_drvdata to static inline functions) now triggers a warning in the macb network driver: CC drivers/net/macb.o drivers/net/macb.c: In function ‘macb_mii_init’: drivers/net/macb.c:263: warning: passing argument 1 of ‘platform_set_drvdata’ from incompatible pointer type include/linux/platform_device.h:138: note: expected ‘struct platform_device *’ but argument is of type ‘struct net_device *’ Use dev_set_drvdata() on the device embedded in the net_device instead. Cc: Nicolas Ferre Signed-off-by: Jamie Iles Signed-off-by: David S. Miller --- drivers/net/macb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/macb.c b/drivers/net/macb.c index f69e73e2191e..79ccb54ab00c 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -260,7 +260,7 @@ static int macb_mii_init(struct macb *bp) for (i = 0; i < PHY_MAX_ADDR; i++) bp->mii_bus->irq[i] = PHY_POLL; - platform_set_drvdata(bp->dev, bp->mii_bus); + dev_set_drvdata(&bp->dev->dev, bp->mii_bus); if (mdiobus_register(bp->mii_bus)) goto err_out_free_mdio_irq; -- cgit v1.2.3 From b093dd96844186cd03318aaf0cd96f91db3970ef Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Mon, 21 Feb 2011 10:20:30 +0000 Subject: dnet: fix wrong use of platform_set_drvdata() platform_set_drvdata() was used with argument of incorrect type and could cause memory corruption. Moreover, because of not setting drvdata in the correct place not all resources were freed upon module unload. Signed-off-by: Ilya Yanok Signed-off-by: David S. Miller --- drivers/net/dnet.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dnet.c b/drivers/net/dnet.c index 9d8a20b72fa9..8318ea06cb6d 100644 --- a/drivers/net/dnet.c +++ b/drivers/net/dnet.c @@ -337,8 +337,6 @@ static int dnet_mii_init(struct dnet *bp) for (i = 0; i < PHY_MAX_ADDR; i++) bp->mii_bus->irq[i] = PHY_POLL; - platform_set_drvdata(bp->dev, bp->mii_bus); - if (mdiobus_register(bp->mii_bus)) { err = -ENXIO; goto err_out_free_mdio_irq; @@ -863,6 +861,7 @@ static int __devinit dnet_probe(struct platform_device *pdev) bp = netdev_priv(dev); bp->dev = dev; + platform_set_drvdata(pdev, dev); SET_NETDEV_DEV(dev, &pdev->dev); spin_lock_init(&bp->lock); -- cgit v1.2.3 From a1e9c9dd3383e6a1a762464ad604b1081774dbda Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 23 Feb 2011 15:37:59 -0600 Subject: ipmi: convert OF driver to platform driver of_bus is deprecated in favor of the plain platform bus. This patch merges the ipmi OF driver with the existing platform driver. CONFIG_PPC_OF occurrances are removed or replaced with CONFIG_OF. Compile tested with and without CONFIG_OF. Tested OF probe and default probe cases. Signed-off-by: Rob Herring Signed-off-by: Grant Likely --- drivers/char/ipmi/ipmi_si_intf.c | 70 +++++++++++++--------------------------- 1 file changed, 23 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 7855f9f45b8e..dcfc39ca753e 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -66,13 +66,10 @@ #include #include #include - -#ifdef CONFIG_PPC_OF #include #include #include #include -#endif #define PFX "ipmi_si: " @@ -116,13 +113,7 @@ static char *ipmi_addr_src_to_str[] = { NULL, "hotmod", "hardcoded", "SPMI", #define DEVICE_NAME "ipmi_si" -static struct platform_driver ipmi_driver = { - .driver = { - .name = DEVICE_NAME, - .bus = &platform_bus_type - } -}; - +static struct platform_driver ipmi_driver; /* * Indexes into stats[] in smi_info below. @@ -308,9 +299,6 @@ static int pci_registered; #ifdef CONFIG_ACPI static int pnp_registered; #endif -#ifdef CONFIG_PPC_OF -static int of_registered; -#endif static unsigned int kipmid_max_busy_us[SI_MAX_PARMS]; static int num_max_busy_us; @@ -1860,8 +1848,9 @@ static int hotmod_handler(const char *val, struct kernel_param *kp) return rv; } -static void __devinit hardcode_find_bmc(void) +static int __devinit hardcode_find_bmc(void) { + int ret = -ENODEV; int i; struct smi_info *info; @@ -1871,7 +1860,7 @@ static void __devinit hardcode_find_bmc(void) info = smi_info_alloc(); if (!info) - return; + return -ENOMEM; info->addr_source = SI_HARDCODED; printk(KERN_INFO PFX "probing via hardcoded address\n"); @@ -1924,10 +1913,12 @@ static void __devinit hardcode_find_bmc(void) if (!add_smi(info)) { if (try_smi_init(info)) cleanup_one_si(info); + ret = 0; } else { kfree(info); } } + return ret; } #ifdef CONFIG_ACPI @@ -2555,11 +2546,9 @@ static struct pci_driver ipmi_pci_driver = { }; #endif /* CONFIG_PCI */ - -#ifdef CONFIG_PPC_OF -static int __devinit ipmi_of_probe(struct platform_device *dev, - const struct of_device_id *match) +static int __devinit ipmi_probe(struct platform_device *dev) { +#ifdef CONFIG_OF struct smi_info *info; struct resource resource; const __be32 *regsize, *regspacing, *regshift; @@ -2569,6 +2558,9 @@ static int __devinit ipmi_of_probe(struct platform_device *dev, dev_info(&dev->dev, "probing via device tree\n"); + if (!dev->dev.of_match) + return -EINVAL; + ret = of_address_to_resource(np, 0, &resource); if (ret) { dev_warn(&dev->dev, PFX "invalid address from OF\n"); @@ -2601,7 +2593,7 @@ static int __devinit ipmi_of_probe(struct platform_device *dev, return -ENOMEM; } - info->si_type = (enum si_type) match->data; + info->si_type = (enum si_type) dev->dev.of_match->data; info->addr_source = SI_DEVICETREE; info->irq_setup = std_irq_setup; @@ -2632,13 +2624,15 @@ static int __devinit ipmi_of_probe(struct platform_device *dev, kfree(info); return -EBUSY; } - +#endif return 0; } -static int __devexit ipmi_of_remove(struct platform_device *dev) +static int __devexit ipmi_remove(struct platform_device *dev) { +#ifdef CONFIG_OF cleanup_one_si(dev_get_drvdata(&dev->dev)); +#endif return 0; } @@ -2653,16 +2647,15 @@ static struct of_device_id ipmi_match[] = {}, }; -static struct of_platform_driver ipmi_of_platform_driver = { +static struct platform_driver ipmi_driver = { .driver = { - .name = "ipmi", + .name = DEVICE_NAME, .owner = THIS_MODULE, .of_match_table = ipmi_match, }, - .probe = ipmi_of_probe, - .remove = __devexit_p(ipmi_of_remove), + .probe = ipmi_probe, + .remove = __devexit_p(ipmi_remove), }; -#endif /* CONFIG_PPC_OF */ static int wait_for_msg_done(struct smi_info *smi_info) { @@ -3340,8 +3333,7 @@ static int __devinit init_ipmi_si(void) return 0; initialized = 1; - /* Register the device drivers. */ - rv = driver_register(&ipmi_driver.driver); + rv = platform_driver_register(&ipmi_driver); if (rv) { printk(KERN_ERR PFX "Unable to register driver: %d\n", rv); return rv; @@ -3365,15 +3357,9 @@ static int __devinit init_ipmi_si(void) printk(KERN_INFO "IPMI System Interface driver.\n"); - hardcode_find_bmc(); - /* If the user gave us a device, they presumably want us to use it */ - mutex_lock(&smi_infos_lock); - if (!list_empty(&smi_infos)) { - mutex_unlock(&smi_infos_lock); + if (!hardcode_find_bmc()) return 0; - } - mutex_unlock(&smi_infos_lock); #ifdef CONFIG_PCI rv = pci_register_driver(&ipmi_pci_driver); @@ -3396,11 +3382,6 @@ static int __devinit init_ipmi_si(void) spmi_find_bmc(); #endif -#ifdef CONFIG_PPC_OF - of_register_platform_driver(&ipmi_of_platform_driver); - of_registered = 1; -#endif - /* We prefer devices with interrupts, but in the case of a machine with multiple BMCs we assume that there will be several instances of a given type so if we succeed in registering a type then also @@ -3548,17 +3529,12 @@ static void __exit cleanup_ipmi_si(void) pnp_unregister_driver(&ipmi_pnp_driver); #endif -#ifdef CONFIG_PPC_OF - if (of_registered) - of_unregister_platform_driver(&ipmi_of_platform_driver); -#endif + platform_driver_unregister(&ipmi_driver); mutex_lock(&smi_infos_lock); list_for_each_entry_safe(e, tmp_e, &smi_infos, link) cleanup_one_si(e); mutex_unlock(&smi_infos_lock); - - driver_unregister(&ipmi_driver.driver); } module_exit(cleanup_ipmi_si); -- cgit v1.2.3 From 55f19d56742a7b544e80b47339c17bfcfd0ff3b4 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 22 Feb 2011 20:13:26 -0700 Subject: dt: xilinx_hwicap: merge platform and of_platform driver bindings of_platform_driver is getting removed, and a single platform_driver can now support both devicetree and non-devicetree use cases. This patch merges the two driver registrations. Signed-off-by: Grant Likely Acked-by: Stephen Neuendorffer --- drivers/char/xilinx_hwicap/xilinx_hwicap.c | 129 +++++++++++------------------ 1 file changed, 47 insertions(+), 82 deletions(-) (limited to 'drivers') diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 9f2272e6de1c..d3c9d755ed98 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -714,20 +714,29 @@ static int __devexit hwicap_remove(struct device *dev) return 0; /* success */ } -static int __devinit hwicap_drv_probe(struct platform_device *pdev) +#ifdef CONFIG_OF +static int __devinit hwicap_of_probe(struct platform_device *op) { - struct resource *res; - const struct config_registers *regs; + struct resource res; + const unsigned int *id; const char *family; + int rc; + const struct hwicap_driver_config *config = op->dev.of_match->data; + const struct config_registers *regs; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; + + rc = of_address_to_resource(op->dev.of_node, 0, &res); + if (rc) { + dev_err(&op->dev, "invalid address\n"); + return rc; + } + + id = of_get_property(op->dev.of_node, "port-number", NULL); /* It's most likely that we're using V4, if the family is not specified */ regs = &v4_config_registers; - family = pdev->dev.platform_data; + family = of_get_property(op->dev.of_node, "xlnx,family", NULL); if (family) { if (!strcmp(family, "virtex2p")) { @@ -738,54 +747,33 @@ static int __devinit hwicap_drv_probe(struct platform_device *pdev) regs = &v5_config_registers; } } - - return hwicap_setup(&pdev->dev, pdev->id, res, - &buffer_icap_config, regs); + return hwicap_setup(&op->dev, id ? *id : -1, &res, config, + regs); } - -static int __devexit hwicap_drv_remove(struct platform_device *pdev) +#else +static inline int hwicap_of_probe(struct platform_device *op) { - return hwicap_remove(&pdev->dev); + return -EINVAL; } +#endif /* CONFIG_OF */ -static struct platform_driver hwicap_platform_driver = { - .probe = hwicap_drv_probe, - .remove = hwicap_drv_remove, - .driver = { - .owner = THIS_MODULE, - .name = DRIVER_NAME, - }, -}; - -/* --------------------------------------------------------------------- - * OF bus binding - */ - -#if defined(CONFIG_OF) -static int __devinit -hwicap_of_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit hwicap_drv_probe(struct platform_device *pdev) { - struct resource res; - const unsigned int *id; - const char *family; - int rc; - const struct hwicap_driver_config *config = match->data; + struct resource *res; const struct config_registers *regs; + const char *family; - dev_dbg(&op->dev, "hwicap_of_probe(%p, %p)\n", op, match); - - rc = of_address_to_resource(op->dev.of_node, 0, &res); - if (rc) { - dev_err(&op->dev, "invalid address\n"); - return rc; - } + if (pdev->dev.of_match) + return hwicap_of_probe(pdev); - id = of_get_property(op->dev.of_node, "port-number", NULL); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; /* It's most likely that we're using V4, if the family is not specified */ regs = &v4_config_registers; - family = of_get_property(op->dev.of_node, "xlnx,family", NULL); + family = pdev->dev.platform_data; if (family) { if (!strcmp(family, "virtex2p")) { @@ -796,50 +784,38 @@ hwicap_of_probe(struct platform_device *op, const struct of_device_id *match) regs = &v5_config_registers; } } - return hwicap_setup(&op->dev, id ? *id : -1, &res, config, - regs); + + return hwicap_setup(&pdev->dev, pdev->id, res, + &buffer_icap_config, regs); } -static int __devexit hwicap_of_remove(struct platform_device *op) +static int __devexit hwicap_drv_remove(struct platform_device *pdev) { - return hwicap_remove(&op->dev); + return hwicap_remove(&pdev->dev); } -/* Match table for of_platform binding */ +#ifdef CONFIG_OF +/* Match table for device tree binding */ static const struct of_device_id __devinitconst hwicap_of_match[] = { { .compatible = "xlnx,opb-hwicap-1.00.b", .data = &buffer_icap_config}, { .compatible = "xlnx,xps-hwicap-1.00.a", .data = &fifo_icap_config}, {}, }; MODULE_DEVICE_TABLE(of, hwicap_of_match); +#else +#define hwicap_of_match NULL +#endif -static struct of_platform_driver hwicap_of_driver = { - .probe = hwicap_of_probe, - .remove = __devexit_p(hwicap_of_remove), +static struct platform_driver hwicap_platform_driver = { + .probe = hwicap_drv_probe, + .remove = hwicap_drv_remove, .driver = { - .name = DRIVER_NAME, .owner = THIS_MODULE, + .name = DRIVER_NAME, .of_match_table = hwicap_of_match, }, }; -/* Registration helpers to keep the number of #ifdefs to a minimum */ -static inline int __init hwicap_of_register(void) -{ - pr_debug("hwicap: calling of_register_platform_driver()\n"); - return of_register_platform_driver(&hwicap_of_driver); -} - -static inline void __exit hwicap_of_unregister(void) -{ - of_unregister_platform_driver(&hwicap_of_driver); -} -#else /* CONFIG_OF */ -/* CONFIG_OF not enabled; do nothing helpers */ -static inline int __init hwicap_of_register(void) { return 0; } -static inline void __exit hwicap_of_unregister(void) { } -#endif /* CONFIG_OF */ - static int __init hwicap_module_init(void) { dev_t devt; @@ -856,21 +832,12 @@ static int __init hwicap_module_init(void) return retval; retval = platform_driver_register(&hwicap_platform_driver); - - if (retval) - goto failed1; - - retval = hwicap_of_register(); - if (retval) - goto failed2; + goto failed; return retval; - failed2: - platform_driver_unregister(&hwicap_platform_driver); - - failed1: + failed: unregister_chrdev_region(devt, HWICAP_DEVICES); return retval; @@ -884,8 +851,6 @@ static void __exit hwicap_module_cleanup(void) platform_driver_unregister(&hwicap_platform_driver); - hwicap_of_unregister(); - unregister_chrdev_region(devt, HWICAP_DEVICES); } -- cgit v1.2.3 From e5263a517688b83861d406223a0f111a6e4116ff Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 22 Feb 2011 20:16:13 -0700 Subject: dt: uartlite: merge platform and of_platform driver bindings of_platform_driver is getting removed, and a single platform_driver can now support both devicetree and non-devicetree use cases. This patch merges the two driver registrations. Signed-off-by: Grant Likely Acked-by: Peter Korsgaard --- drivers/tty/serial/uartlite.c | 103 ++++++++++-------------------------------- 1 file changed, 24 insertions(+), 79 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index d2fce865b731..8af1ed83a4c0 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c @@ -19,22 +19,11 @@ #include #include #include -#if defined(CONFIG_OF) && (defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE)) #include #include #include #include -/* Match table for of_platform binding */ -static struct of_device_id ulite_of_match[] __devinitdata = { - { .compatible = "xlnx,opb-uartlite-1.00.b", }, - { .compatible = "xlnx,xps-uartlite-1.00.a", }, - {} -}; -MODULE_DEVICE_TABLE(of, ulite_of_match); - -#endif - #define ULITE_NAME "ttyUL" #define ULITE_MAJOR 204 #define ULITE_MINOR 187 @@ -571,9 +560,29 @@ static int __devexit ulite_release(struct device *dev) * Platform bus binding */ +#if defined(CONFIG_OF) +/* Match table for of_platform binding */ +static struct of_device_id ulite_of_match[] __devinitdata = { + { .compatible = "xlnx,opb-uartlite-1.00.b", }, + { .compatible = "xlnx,xps-uartlite-1.00.a", }, + {} +}; +MODULE_DEVICE_TABLE(of, ulite_of_match); +#else /* CONFIG_OF */ +#define ulite_of_match NULL +#endif /* CONFIG_OF */ + static int __devinit ulite_probe(struct platform_device *pdev) { struct resource *res, *res2; + int id = pdev->id; +#ifdef CONFIG_OF + const __be32 *prop; + + prop = of_get_property(pdev->dev.of_node, "port-number", NULL); + if (prop) + id = be32_to_cpup(prop); +#endif res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) @@ -583,7 +592,7 @@ static int __devinit ulite_probe(struct platform_device *pdev) if (!res2) return -ENODEV; - return ulite_assign(&pdev->dev, pdev->id, res->start, res2->start); + return ulite_assign(&pdev->dev, id, res->start, res2->start); } static int __devexit ulite_remove(struct platform_device *pdev) @@ -595,72 +604,15 @@ static int __devexit ulite_remove(struct platform_device *pdev) MODULE_ALIAS("platform:uartlite"); static struct platform_driver ulite_platform_driver = { - .probe = ulite_probe, - .remove = __devexit_p(ulite_remove), - .driver = { - .owner = THIS_MODULE, - .name = "uartlite", - }, -}; - -/* --------------------------------------------------------------------- - * OF bus bindings - */ -#if defined(CONFIG_OF) && (defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE)) -static int __devinit -ulite_of_probe(struct platform_device *op, const struct of_device_id *match) -{ - struct resource res; - const unsigned int *id; - int irq, rc; - - dev_dbg(&op->dev, "%s(%p, %p)\n", __func__, op, match); - - rc = of_address_to_resource(op->dev.of_node, 0, &res); - if (rc) { - dev_err(&op->dev, "invalid address\n"); - return rc; - } - - irq = irq_of_parse_and_map(op->dev.of_node, 0); - - id = of_get_property(op->dev.of_node, "port-number", NULL); - - return ulite_assign(&op->dev, id ? *id : -1, res.start, irq); -} - -static int __devexit ulite_of_remove(struct platform_device *op) -{ - return ulite_release(&op->dev); -} - -static struct of_platform_driver ulite_of_driver = { - .probe = ulite_of_probe, - .remove = __devexit_p(ulite_of_remove), + .probe = ulite_probe, + .remove = __devexit_p(ulite_remove), .driver = { - .name = "uartlite", .owner = THIS_MODULE, + .name = "uartlite", .of_match_table = ulite_of_match, }, }; -/* Registration helpers to keep the number of #ifdefs to a minimum */ -static inline int __init ulite_of_register(void) -{ - pr_debug("uartlite: calling of_register_platform_driver()\n"); - return of_register_platform_driver(&ulite_of_driver); -} - -static inline void __exit ulite_of_unregister(void) -{ - of_unregister_platform_driver(&ulite_of_driver); -} -#else /* CONFIG_OF && (CONFIG_PPC32 || CONFIG_MICROBLAZE) */ -/* Appropriate config not enabled; do nothing helpers */ -static inline int __init ulite_of_register(void) { return 0; } -static inline void __exit ulite_of_unregister(void) { } -#endif /* CONFIG_OF && (CONFIG_PPC32 || CONFIG_MICROBLAZE) */ - /* --------------------------------------------------------------------- * Module setup/teardown */ @@ -674,10 +626,6 @@ int __init ulite_init(void) if (ret) goto err_uart; - ret = ulite_of_register(); - if (ret) - goto err_of; - pr_debug("uartlite: calling platform_driver_register()\n"); ret = platform_driver_register(&ulite_platform_driver); if (ret) @@ -686,8 +634,6 @@ int __init ulite_init(void) return 0; err_plat: - ulite_of_unregister(); -err_of: uart_unregister_driver(&ulite_uart_driver); err_uart: printk(KERN_ERR "registering uartlite driver failed: err=%i", ret); @@ -697,7 +643,6 @@ err_uart: void __exit ulite_exit(void) { platform_driver_unregister(&ulite_platform_driver); - ulite_of_unregister(); uart_unregister_driver(&ulite_uart_driver); } -- cgit v1.2.3 From 18d306d1375696b0e6b5b39e4744d7fa2ad5e170 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 22 Feb 2011 21:02:43 -0700 Subject: dt/spi: Eliminate users of of_platform_{,un}register_driver Get rid of users of of_platform_driver in drivers/spi. The of_platform_{,un}register_driver functions are going away, so the users need to be converted to using the platform_bus_type directly. Signed-off-by: Grant Likely --- drivers/spi/mpc512x_psc_spi.c | 9 ++++----- drivers/spi/mpc52xx_psc_spi.c | 9 ++++----- drivers/spi/mpc52xx_spi.c | 9 ++++----- drivers/spi/spi_fsl_espi.c | 11 +++++------ drivers/spi/spi_fsl_lib.c | 3 +-- drivers/spi/spi_fsl_lib.h | 3 +-- drivers/spi/spi_fsl_spi.c | 11 +++++------ drivers/spi/spi_ppc4xx.c | 9 ++++----- 8 files changed, 28 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/mpc512x_psc_spi.c b/drivers/spi/mpc512x_psc_spi.c index 77d9e7ee8b27..6a5b4238fb6b 100644 --- a/drivers/spi/mpc512x_psc_spi.c +++ b/drivers/spi/mpc512x_psc_spi.c @@ -507,8 +507,7 @@ static int __devexit mpc512x_psc_spi_do_remove(struct device *dev) return 0; } -static int __devinit mpc512x_psc_spi_of_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit mpc512x_psc_spi_of_probe(struct platform_device *op) { const u32 *regaddr_p; u64 regaddr64, size64; @@ -551,7 +550,7 @@ static struct of_device_id mpc512x_psc_spi_of_match[] = { MODULE_DEVICE_TABLE(of, mpc512x_psc_spi_of_match); -static struct of_platform_driver mpc512x_psc_spi_of_driver = { +static struct platform_driver mpc512x_psc_spi_of_driver = { .probe = mpc512x_psc_spi_of_probe, .remove = __devexit_p(mpc512x_psc_spi_of_remove), .driver = { @@ -563,13 +562,13 @@ static struct of_platform_driver mpc512x_psc_spi_of_driver = { static int __init mpc512x_psc_spi_init(void) { - return of_register_platform_driver(&mpc512x_psc_spi_of_driver); + return platform_driver_register(&mpc512x_psc_spi_of_driver); } module_init(mpc512x_psc_spi_init); static void __exit mpc512x_psc_spi_exit(void) { - of_unregister_platform_driver(&mpc512x_psc_spi_of_driver); + platform_driver_unregister(&mpc512x_psc_spi_of_driver); } module_exit(mpc512x_psc_spi_exit); diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 8a904c1c8485..e30baf0852ac 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c @@ -450,8 +450,7 @@ free_master: return ret; } -static int __devinit mpc52xx_psc_spi_of_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit mpc52xx_psc_spi_of_probe(struct platform_device *op) { const u32 *regaddr_p; u64 regaddr64, size64; @@ -503,7 +502,7 @@ static const struct of_device_id mpc52xx_psc_spi_of_match[] = { MODULE_DEVICE_TABLE(of, mpc52xx_psc_spi_of_match); -static struct of_platform_driver mpc52xx_psc_spi_of_driver = { +static struct platform_driver mpc52xx_psc_spi_of_driver = { .probe = mpc52xx_psc_spi_of_probe, .remove = __devexit_p(mpc52xx_psc_spi_of_remove), .driver = { @@ -515,13 +514,13 @@ static struct of_platform_driver mpc52xx_psc_spi_of_driver = { static int __init mpc52xx_psc_spi_init(void) { - return of_register_platform_driver(&mpc52xx_psc_spi_of_driver); + return platform_driver_register(&mpc52xx_psc_spi_of_driver); } module_init(mpc52xx_psc_spi_init); static void __exit mpc52xx_psc_spi_exit(void) { - of_unregister_platform_driver(&mpc52xx_psc_spi_of_driver); + platform_driver_unregister(&mpc52xx_psc_spi_of_driver); } module_exit(mpc52xx_psc_spi_exit); diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c index 84439f655601..015a974bed72 100644 --- a/drivers/spi/mpc52xx_spi.c +++ b/drivers/spi/mpc52xx_spi.c @@ -390,8 +390,7 @@ static int mpc52xx_spi_transfer(struct spi_device *spi, struct spi_message *m) /* * OF Platform Bus Binding */ -static int __devinit mpc52xx_spi_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit mpc52xx_spi_probe(struct platform_device *op) { struct spi_master *master; struct mpc52xx_spi *ms; @@ -556,7 +555,7 @@ static const struct of_device_id mpc52xx_spi_match[] __devinitconst = { }; MODULE_DEVICE_TABLE(of, mpc52xx_spi_match); -static struct of_platform_driver mpc52xx_spi_of_driver = { +static struct platform_driver mpc52xx_spi_of_driver = { .driver = { .name = "mpc52xx-spi", .owner = THIS_MODULE, @@ -568,13 +567,13 @@ static struct of_platform_driver mpc52xx_spi_of_driver = { static int __init mpc52xx_spi_init(void) { - return of_register_platform_driver(&mpc52xx_spi_of_driver); + return platform_driver_register(&mpc52xx_spi_of_driver); } module_init(mpc52xx_spi_init); static void __exit mpc52xx_spi_exit(void) { - of_unregister_platform_driver(&mpc52xx_spi_of_driver); + platform_driver_unregister(&mpc52xx_spi_of_driver); } module_exit(mpc52xx_spi_exit); diff --git a/drivers/spi/spi_fsl_espi.c b/drivers/spi/spi_fsl_espi.c index a99e2333b949..900e921ab80e 100644 --- a/drivers/spi/spi_fsl_espi.c +++ b/drivers/spi/spi_fsl_espi.c @@ -685,8 +685,7 @@ static int of_fsl_espi_get_chipselects(struct device *dev) return 0; } -static int __devinit of_fsl_espi_probe(struct platform_device *ofdev, - const struct of_device_id *ofid) +static int __devinit of_fsl_espi_probe(struct platform_device *ofdev) { struct device *dev = &ofdev->dev; struct device_node *np = ofdev->dev.of_node; @@ -695,7 +694,7 @@ static int __devinit of_fsl_espi_probe(struct platform_device *ofdev, struct resource irq; int ret = -ENOMEM; - ret = of_mpc8xxx_spi_probe(ofdev, ofid); + ret = of_mpc8xxx_spi_probe(ofdev); if (ret) return ret; @@ -736,7 +735,7 @@ static const struct of_device_id of_fsl_espi_match[] = { }; MODULE_DEVICE_TABLE(of, of_fsl_espi_match); -static struct of_platform_driver fsl_espi_driver = { +static struct platform_driver fsl_espi_driver = { .driver = { .name = "fsl_espi", .owner = THIS_MODULE, @@ -748,13 +747,13 @@ static struct of_platform_driver fsl_espi_driver = { static int __init fsl_espi_init(void) { - return of_register_platform_driver(&fsl_espi_driver); + return platform_driver_register(&fsl_espi_driver); } module_init(fsl_espi_init); static void __exit fsl_espi_exit(void) { - of_unregister_platform_driver(&fsl_espi_driver); + platform_driver_unregister(&fsl_espi_driver); } module_exit(fsl_espi_exit); diff --git a/drivers/spi/spi_fsl_lib.c b/drivers/spi/spi_fsl_lib.c index 5cd741fdb5c3..ff59f42ae990 100644 --- a/drivers/spi/spi_fsl_lib.c +++ b/drivers/spi/spi_fsl_lib.c @@ -189,8 +189,7 @@ int __devexit mpc8xxx_spi_remove(struct device *dev) return 0; } -int __devinit of_mpc8xxx_spi_probe(struct platform_device *ofdev, - const struct of_device_id *ofid) +int __devinit of_mpc8xxx_spi_probe(struct platform_device *ofdev) { struct device *dev = &ofdev->dev; struct device_node *np = ofdev->dev.of_node; diff --git a/drivers/spi/spi_fsl_lib.h b/drivers/spi/spi_fsl_lib.h index 281e060977cd..cbe881b9ea76 100644 --- a/drivers/spi/spi_fsl_lib.h +++ b/drivers/spi/spi_fsl_lib.h @@ -118,7 +118,6 @@ extern const char *mpc8xxx_spi_strmode(unsigned int flags); extern int mpc8xxx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq); extern int mpc8xxx_spi_remove(struct device *dev); -extern int of_mpc8xxx_spi_probe(struct platform_device *ofdev, - const struct of_device_id *ofid); +extern int of_mpc8xxx_spi_probe(struct platform_device *ofdev); #endif /* __SPI_FSL_LIB_H__ */ diff --git a/drivers/spi/spi_fsl_spi.c b/drivers/spi/spi_fsl_spi.c index 7ca52d3ae8f8..7963c9b49566 100644 --- a/drivers/spi/spi_fsl_spi.c +++ b/drivers/spi/spi_fsl_spi.c @@ -1042,8 +1042,7 @@ static int of_fsl_spi_free_chipselects(struct device *dev) return 0; } -static int __devinit of_fsl_spi_probe(struct platform_device *ofdev, - const struct of_device_id *ofid) +static int __devinit of_fsl_spi_probe(struct platform_device *ofdev) { struct device *dev = &ofdev->dev; struct device_node *np = ofdev->dev.of_node; @@ -1052,7 +1051,7 @@ static int __devinit of_fsl_spi_probe(struct platform_device *ofdev, struct resource irq; int ret = -ENOMEM; - ret = of_mpc8xxx_spi_probe(ofdev, ofid); + ret = of_mpc8xxx_spi_probe(ofdev); if (ret) return ret; @@ -1100,7 +1099,7 @@ static const struct of_device_id of_fsl_spi_match[] = { }; MODULE_DEVICE_TABLE(of, of_fsl_spi_match); -static struct of_platform_driver of_fsl_spi_driver = { +static struct platform_driver of_fsl_spi_driver = { .driver = { .name = "fsl_spi", .owner = THIS_MODULE, @@ -1177,13 +1176,13 @@ static void __exit legacy_driver_unregister(void) {} static int __init fsl_spi_init(void) { legacy_driver_register(); - return of_register_platform_driver(&of_fsl_spi_driver); + return platform_driver_register(&of_fsl_spi_driver); } module_init(fsl_spi_init); static void __exit fsl_spi_exit(void) { - of_unregister_platform_driver(&of_fsl_spi_driver); + platform_driver_unregister(&of_fsl_spi_driver); legacy_driver_unregister(); } module_exit(fsl_spi_exit); diff --git a/drivers/spi/spi_ppc4xx.c b/drivers/spi/spi_ppc4xx.c index 80e172d3e72a..2a298c029194 100644 --- a/drivers/spi/spi_ppc4xx.c +++ b/drivers/spi/spi_ppc4xx.c @@ -390,8 +390,7 @@ static void free_gpios(struct ppc4xx_spi *hw) /* * platform_device layer stuff... */ -static int __init spi_ppc4xx_of_probe(struct platform_device *op, - const struct of_device_id *match) +static int __init spi_ppc4xx_of_probe(struct platform_device *op) { struct ppc4xx_spi *hw; struct spi_master *master; @@ -586,7 +585,7 @@ static const struct of_device_id spi_ppc4xx_of_match[] = { MODULE_DEVICE_TABLE(of, spi_ppc4xx_of_match); -static struct of_platform_driver spi_ppc4xx_of_driver = { +static struct platform_driver spi_ppc4xx_of_driver = { .probe = spi_ppc4xx_of_probe, .remove = __exit_p(spi_ppc4xx_of_remove), .driver = { @@ -598,13 +597,13 @@ static struct of_platform_driver spi_ppc4xx_of_driver = { static int __init spi_ppc4xx_init(void) { - return of_register_platform_driver(&spi_ppc4xx_of_driver); + return platform_driver_register(&spi_ppc4xx_of_driver); } module_init(spi_ppc4xx_init); static void __exit spi_ppc4xx_exit(void) { - of_unregister_platform_driver(&spi_ppc4xx_of_driver); + platform_driver_unregister(&spi_ppc4xx_of_driver); } module_exit(spi_ppc4xx_exit); -- cgit v1.2.3 From 74888760d40b3ac9054f9c5fa07b566c0676ba2d Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 22 Feb 2011 21:05:51 -0700 Subject: dt/net: Eliminate users of of_platform_{,un}register_driver Get rid of users of of_platform_driver in drivers/net. The of_platform_{,un}register_driver functions are going away, so the users need to be converted to using the platform_bus_type directly. Signed-off-by: Grant Likely --- drivers/net/can/mscan/mpc5xxx_can.c | 15 +++++++++------ drivers/net/can/sja1000/sja1000_of_platform.c | 9 ++++----- drivers/net/fec_mpc52xx.c | 13 ++++++------- drivers/net/fec_mpc52xx.h | 2 +- drivers/net/fec_mpc52xx_phy.c | 5 ++--- drivers/net/fs_enet/fs_enet-main.c | 16 +++++++++------- drivers/net/fs_enet/mii-bitbang.c | 9 ++++----- drivers/net/fs_enet/mii-fec.c | 15 +++++++++------ drivers/net/fsl_pq_mdio.c | 9 ++++----- drivers/net/gianfar.c | 12 +++++------- drivers/net/greth.c | 8 ++++---- drivers/net/ibm_newemac/core.c | 9 ++++----- drivers/net/ibm_newemac/mal.c | 9 ++++----- drivers/net/ibm_newemac/rgmii.c | 9 ++++----- drivers/net/ibm_newemac/tah.c | 9 ++++----- drivers/net/ibm_newemac/zmii.c | 9 ++++----- drivers/net/ll_temac_main.c | 9 ++++----- drivers/net/myri_sbus.c | 8 ++++---- drivers/net/niu.c | 11 +++++------ drivers/net/phy/mdio-gpio.c | 9 ++++----- drivers/net/sunbmac.c | 9 ++++----- drivers/net/sunhme.c | 14 +++++++++----- drivers/net/sunlance.c | 8 ++++---- drivers/net/sunqe.c | 8 ++++---- drivers/net/ucc_geth.c | 8 ++++---- drivers/net/xilinx_emaclite.c | 9 ++++----- 26 files changed, 123 insertions(+), 128 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c index 312b9c8f4f3b..c0a1bc5b1435 100644 --- a/drivers/net/can/mscan/mpc5xxx_can.c +++ b/drivers/net/can/mscan/mpc5xxx_can.c @@ -247,10 +247,9 @@ static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev, } #endif /* CONFIG_PPC_MPC512x */ -static int __devinit mpc5xxx_can_probe(struct platform_device *ofdev, - const struct of_device_id *id) +static int __devinit mpc5xxx_can_probe(struct platform_device *ofdev) { - struct mpc5xxx_can_data *data = (struct mpc5xxx_can_data *)id->data; + struct mpc5xxx_can_data *data; struct device_node *np = ofdev->dev.of_node; struct net_device *dev; struct mscan_priv *priv; @@ -259,6 +258,10 @@ static int __devinit mpc5xxx_can_probe(struct platform_device *ofdev, int irq, mscan_clksrc = 0; int err = -ENOMEM; + if (!ofdev->dev.of_match) + return -EINVAL; + data = (struct mpc5xxx_can_data *)of_dev->dev.of_match->data; + base = of_iomap(np, 0); if (!base) { dev_err(&ofdev->dev, "couldn't ioremap\n"); @@ -391,7 +394,7 @@ static struct of_device_id __devinitdata mpc5xxx_can_table[] = { {}, }; -static struct of_platform_driver mpc5xxx_can_driver = { +static struct platform_driver mpc5xxx_can_driver = { .driver = { .name = "mpc5xxx_can", .owner = THIS_MODULE, @@ -407,13 +410,13 @@ static struct of_platform_driver mpc5xxx_can_driver = { static int __init mpc5xxx_can_init(void) { - return of_register_platform_driver(&mpc5xxx_can_driver); + return platform_driver_register(&mpc5xxx_can_driver); } module_init(mpc5xxx_can_init); static void __exit mpc5xxx_can_exit(void) { - return of_unregister_platform_driver(&mpc5xxx_can_driver); + platform_driver_unregister(&mpc5xxx_can_driver); }; module_exit(mpc5xxx_can_exit); diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c index 09c3e9db9316..9793df6e3455 100644 --- a/drivers/net/can/sja1000/sja1000_of_platform.c +++ b/drivers/net/can/sja1000/sja1000_of_platform.c @@ -87,8 +87,7 @@ static int __devexit sja1000_ofp_remove(struct platform_device *ofdev) return 0; } -static int __devinit sja1000_ofp_probe(struct platform_device *ofdev, - const struct of_device_id *id) +static int __devinit sja1000_ofp_probe(struct platform_device *ofdev) { struct device_node *np = ofdev->dev.of_node; struct net_device *dev; @@ -210,7 +209,7 @@ static struct of_device_id __devinitdata sja1000_ofp_table[] = { }; MODULE_DEVICE_TABLE(of, sja1000_ofp_table); -static struct of_platform_driver sja1000_ofp_driver = { +static struct platform_driver sja1000_ofp_driver = { .driver = { .owner = THIS_MODULE, .name = DRV_NAME, @@ -222,12 +221,12 @@ static struct of_platform_driver sja1000_ofp_driver = { static int __init sja1000_ofp_init(void) { - return of_register_platform_driver(&sja1000_ofp_driver); + return platform_driver_register(&sja1000_ofp_driver); } module_init(sja1000_ofp_init); static void __exit sja1000_ofp_exit(void) { - return of_unregister_platform_driver(&sja1000_ofp_driver); + return platform_driver_unregister(&sja1000_ofp_driver); }; module_exit(sja1000_ofp_exit); diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index 50c1213f61fe..9f81b1ac130e 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -840,8 +840,7 @@ static const struct net_device_ops mpc52xx_fec_netdev_ops = { /* OF Driver */ /* ======================================================================== */ -static int __devinit -mpc52xx_fec_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit mpc52xx_fec_probe(struct platform_device *op) { int rv; struct net_device *ndev; @@ -1049,7 +1048,7 @@ static struct of_device_id mpc52xx_fec_match[] = { MODULE_DEVICE_TABLE(of, mpc52xx_fec_match); -static struct of_platform_driver mpc52xx_fec_driver = { +static struct platform_driver mpc52xx_fec_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, @@ -1073,21 +1072,21 @@ mpc52xx_fec_init(void) { #ifdef CONFIG_FEC_MPC52xx_MDIO int ret; - ret = of_register_platform_driver(&mpc52xx_fec_mdio_driver); + ret = platform_driver_register(&mpc52xx_fec_mdio_driver); if (ret) { printk(KERN_ERR DRIVER_NAME ": failed to register mdio driver\n"); return ret; } #endif - return of_register_platform_driver(&mpc52xx_fec_driver); + return platform_driver_register(&mpc52xx_fec_driver); } static void __exit mpc52xx_fec_exit(void) { - of_unregister_platform_driver(&mpc52xx_fec_driver); + platform_driver_unregister(&mpc52xx_fec_driver); #ifdef CONFIG_FEC_MPC52xx_MDIO - of_unregister_platform_driver(&mpc52xx_fec_mdio_driver); + platform_driver_unregister(&mpc52xx_fec_mdio_driver); #endif } diff --git a/drivers/net/fec_mpc52xx.h b/drivers/net/fec_mpc52xx.h index a227a525bdbb..41d2dffde55b 100644 --- a/drivers/net/fec_mpc52xx.h +++ b/drivers/net/fec_mpc52xx.h @@ -289,6 +289,6 @@ struct mpc52xx_fec { #define FEC_XMIT_FSM_ENABLE_CRC 0x01000000 -extern struct of_platform_driver mpc52xx_fec_mdio_driver; +extern struct platform_driver mpc52xx_fec_mdio_driver; #endif /* __DRIVERS_NET_MPC52XX_FEC_H__ */ diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c index 0b4cb6f15984..360a578c2bb7 100644 --- a/drivers/net/fec_mpc52xx_phy.c +++ b/drivers/net/fec_mpc52xx_phy.c @@ -61,8 +61,7 @@ static int mpc52xx_fec_mdio_write(struct mii_bus *bus, int phy_id, int reg, data | FEC_MII_WRITE_FRAME); } -static int mpc52xx_fec_mdio_probe(struct platform_device *of, - const struct of_device_id *match) +static int mpc52xx_fec_mdio_probe(struct platform_device *of) { struct device *dev = &of->dev; struct device_node *np = of->dev.of_node; @@ -145,7 +144,7 @@ static struct of_device_id mpc52xx_fec_mdio_match[] = { }; MODULE_DEVICE_TABLE(of, mpc52xx_fec_mdio_match); -struct of_platform_driver mpc52xx_fec_mdio_driver = { +struct platform_driver mpc52xx_fec_mdio_driver = { .driver = { .name = "mpc5200b-fec-phy", .owner = THIS_MODULE, diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 7a1f3d0ffa78..24cb953900dd 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -998,8 +998,7 @@ static const struct net_device_ops fs_enet_netdev_ops = { #endif }; -static int __devinit fs_enet_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit fs_enet_probe(struct platform_device *ofdev) { struct net_device *ndev; struct fs_enet_private *fep; @@ -1008,11 +1007,14 @@ static int __devinit fs_enet_probe(struct platform_device *ofdev, const u8 *mac_addr; int privsize, len, ret = -ENODEV; + if (!ofdev->dev.of_match) + return -EINVAL; + fpi = kzalloc(sizeof(*fpi), GFP_KERNEL); if (!fpi) return -ENOMEM; - if (!IS_FEC(match)) { + if (!IS_FEC(ofdev->dev.of_match)) { data = of_get_property(ofdev->dev.of_node, "fsl,cpm-command", &len); if (!data || len != 4) goto out_free_fpi; @@ -1047,7 +1049,7 @@ static int __devinit fs_enet_probe(struct platform_device *ofdev, fep->dev = &ofdev->dev; fep->ndev = ndev; fep->fpi = fpi; - fep->ops = match->data; + fep->ops = ofdev->dev.of_match->data; ret = fep->ops->setup_data(ndev); if (ret) @@ -1156,7 +1158,7 @@ static struct of_device_id fs_enet_match[] = { }; MODULE_DEVICE_TABLE(of, fs_enet_match); -static struct of_platform_driver fs_enet_driver = { +static struct platform_driver fs_enet_driver = { .driver = { .owner = THIS_MODULE, .name = "fs_enet", @@ -1168,12 +1170,12 @@ static struct of_platform_driver fs_enet_driver = { static int __init fs_init(void) { - return of_register_platform_driver(&fs_enet_driver); + return platform_driver_register(&fs_enet_driver); } static void __exit fs_cleanup(void) { - of_unregister_platform_driver(&fs_enet_driver); + platform_driver_unregister(&fs_enet_driver); } #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c index 3cda2b515471..ad2975440719 100644 --- a/drivers/net/fs_enet/mii-bitbang.c +++ b/drivers/net/fs_enet/mii-bitbang.c @@ -150,8 +150,7 @@ static int __devinit fs_mii_bitbang_init(struct mii_bus *bus, return 0; } -static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev) { struct mii_bus *new_bus; struct bb_info *bitbang; @@ -223,7 +222,7 @@ static struct of_device_id fs_enet_mdio_bb_match[] = { }; MODULE_DEVICE_TABLE(of, fs_enet_mdio_bb_match); -static struct of_platform_driver fs_enet_bb_mdio_driver = { +static struct platform_driver fs_enet_bb_mdio_driver = { .driver = { .name = "fsl-bb-mdio", .owner = THIS_MODULE, @@ -235,12 +234,12 @@ static struct of_platform_driver fs_enet_bb_mdio_driver = { static int fs_enet_mdio_bb_init(void) { - return of_register_platform_driver(&fs_enet_bb_mdio_driver); + return platform_driver_register(&fs_enet_bb_mdio_driver); } static void fs_enet_mdio_bb_exit(void) { - of_unregister_platform_driver(&fs_enet_bb_mdio_driver); + platform_driver_unregister(&fs_enet_bb_mdio_driver); } module_init(fs_enet_mdio_bb_init); diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c index dbb9c48623df..7e840d373ab3 100644 --- a/drivers/net/fs_enet/mii-fec.c +++ b/drivers/net/fs_enet/mii-fec.c @@ -101,15 +101,18 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus) return 0; } -static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev) { struct resource res; struct mii_bus *new_bus; struct fec_info *fec; - int (*get_bus_freq)(struct device_node *) = match->data; + int (*get_bus_freq)(struct device_node *); int ret = -ENOMEM, clock, speed; + if (!ofdev->dev.of_match) + return -EINVAL; + get_bus_freq = ofdev->dev.of_match->data; + new_bus = mdiobus_alloc(); if (!new_bus) goto out; @@ -221,7 +224,7 @@ static struct of_device_id fs_enet_mdio_fec_match[] = { }; MODULE_DEVICE_TABLE(of, fs_enet_mdio_fec_match); -static struct of_platform_driver fs_enet_fec_mdio_driver = { +static struct platform_driver fs_enet_fec_mdio_driver = { .driver = { .name = "fsl-fec-mdio", .owner = THIS_MODULE, @@ -233,12 +236,12 @@ static struct of_platform_driver fs_enet_fec_mdio_driver = { static int fs_enet_mdio_fec_init(void) { - return of_register_platform_driver(&fs_enet_fec_mdio_driver); + return platform_driver_register(&fs_enet_fec_mdio_driver); } static void fs_enet_mdio_fec_exit(void) { - of_unregister_platform_driver(&fs_enet_fec_mdio_driver); + platform_driver_unregister(&fs_enet_fec_mdio_driver); } module_init(fs_enet_mdio_fec_init); diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index 8d3a2ccbc953..52f4e8ad48e7 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -265,8 +265,7 @@ static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id) #endif -static int fsl_pq_mdio_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int fsl_pq_mdio_probe(struct platform_device *ofdev) { struct device_node *np = ofdev->dev.of_node; struct device_node *tbi; @@ -471,7 +470,7 @@ static struct of_device_id fsl_pq_mdio_match[] = { }; MODULE_DEVICE_TABLE(of, fsl_pq_mdio_match); -static struct of_platform_driver fsl_pq_mdio_driver = { +static struct platform_driver fsl_pq_mdio_driver = { .driver = { .name = "fsl-pq_mdio", .owner = THIS_MODULE, @@ -483,13 +482,13 @@ static struct of_platform_driver fsl_pq_mdio_driver = { int __init fsl_pq_mdio_init(void) { - return of_register_platform_driver(&fsl_pq_mdio_driver); + return platform_driver_register(&fsl_pq_mdio_driver); } module_init(fsl_pq_mdio_init); void fsl_pq_mdio_exit(void) { - of_unregister_platform_driver(&fsl_pq_mdio_driver); + platform_driver_unregister(&fsl_pq_mdio_driver); } module_exit(fsl_pq_mdio_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 5ed8f9f9419f..ccb231c4d933 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -123,8 +123,7 @@ static irqreturn_t gfar_interrupt(int irq, void *dev_id); static void adjust_link(struct net_device *dev); static void init_registers(struct net_device *dev); static int init_phy(struct net_device *dev); -static int gfar_probe(struct platform_device *ofdev, - const struct of_device_id *match); +static int gfar_probe(struct platform_device *ofdev); static int gfar_remove(struct platform_device *ofdev); static void free_skb_resources(struct gfar_private *priv); static void gfar_set_multi(struct net_device *dev); @@ -957,8 +956,7 @@ static void gfar_detect_errata(struct gfar_private *priv) /* Set up the ethernet device structure, private data, * and anything else we need before we start */ -static int gfar_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int gfar_probe(struct platform_device *ofdev) { u32 tempval; struct net_device *dev = NULL; @@ -3256,7 +3254,7 @@ static struct of_device_id gfar_match[] = MODULE_DEVICE_TABLE(of, gfar_match); /* Structure for a device driver */ -static struct of_platform_driver gfar_driver = { +static struct platform_driver gfar_driver = { .driver = { .name = "fsl-gianfar", .owner = THIS_MODULE, @@ -3269,12 +3267,12 @@ static struct of_platform_driver gfar_driver = { static int __init gfar_init(void) { - return of_register_platform_driver(&gfar_driver); + return platform_driver_register(&gfar_driver); } static void __exit gfar_exit(void) { - of_unregister_platform_driver(&gfar_driver); + platform_driver_unregister(&gfar_driver); } module_init(gfar_init); diff --git a/drivers/net/greth.c b/drivers/net/greth.c index fdb0333f5cb6..396ff7d785d1 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -1411,7 +1411,7 @@ error: } /* Initialize the GRETH MAC */ -static int __devinit greth_of_probe(struct platform_device *ofdev, const struct of_device_id *match) +static int __devinit greth_of_probe(struct platform_device *ofdev) { struct net_device *dev; struct greth_private *greth; @@ -1646,7 +1646,7 @@ static struct of_device_id greth_of_match[] = { MODULE_DEVICE_TABLE(of, greth_of_match); -static struct of_platform_driver greth_of_driver = { +static struct platform_driver greth_of_driver = { .driver = { .name = "grlib-greth", .owner = THIS_MODULE, @@ -1658,12 +1658,12 @@ static struct of_platform_driver greth_of_driver = { static int __init greth_init(void) { - return of_register_platform_driver(&greth_of_driver); + return platform_driver_register(&greth_of_driver); } static void __exit greth_cleanup(void) { - of_unregister_platform_driver(&greth_of_driver); + platform_driver_unregister(&greth_of_driver); } module_init(greth_init); diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 6d9275c52e05..3bb990b6651a 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -2719,8 +2719,7 @@ static const struct net_device_ops emac_gige_netdev_ops = { .ndo_change_mtu = emac_change_mtu, }; -static int __devinit emac_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit emac_probe(struct platform_device *ofdev) { struct net_device *ndev; struct emac_instance *dev; @@ -2994,7 +2993,7 @@ static struct of_device_id emac_match[] = }; MODULE_DEVICE_TABLE(of, emac_match); -static struct of_platform_driver emac_driver = { +static struct platform_driver emac_driver = { .driver = { .name = "emac", .owner = THIS_MODULE, @@ -3069,7 +3068,7 @@ static int __init emac_init(void) rc = tah_init(); if (rc) goto err_rgmii; - rc = of_register_platform_driver(&emac_driver); + rc = platform_driver_register(&emac_driver); if (rc) goto err_tah; @@ -3091,7 +3090,7 @@ static void __exit emac_exit(void) { int i; - of_unregister_platform_driver(&emac_driver); + platform_driver_unregister(&emac_driver); tah_exit(); rgmii_exit(); diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c index d5717e2123e1..d268f404b7b0 100644 --- a/drivers/net/ibm_newemac/mal.c +++ b/drivers/net/ibm_newemac/mal.c @@ -517,8 +517,7 @@ void *mal_dump_regs(struct mal_instance *mal, void *buf) return regs + 1; } -static int __devinit mal_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit mal_probe(struct platform_device *ofdev) { struct mal_instance *mal; int err = 0, i, bd_size; @@ -789,7 +788,7 @@ static struct of_device_id mal_platform_match[] = {}, }; -static struct of_platform_driver mal_of_driver = { +static struct platform_driver mal_of_driver = { .driver = { .name = "mcmal", .owner = THIS_MODULE, @@ -801,10 +800,10 @@ static struct of_platform_driver mal_of_driver = { int __init mal_init(void) { - return of_register_platform_driver(&mal_of_driver); + return platform_driver_register(&mal_of_driver); } void mal_exit(void) { - of_unregister_platform_driver(&mal_of_driver); + platform_driver_unregister(&mal_of_driver); } diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c index dd61798897ac..4fa53f3def64 100644 --- a/drivers/net/ibm_newemac/rgmii.c +++ b/drivers/net/ibm_newemac/rgmii.c @@ -228,8 +228,7 @@ void *rgmii_dump_regs(struct platform_device *ofdev, void *buf) } -static int __devinit rgmii_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit rgmii_probe(struct platform_device *ofdev) { struct device_node *np = ofdev->dev.of_node; struct rgmii_instance *dev; @@ -318,7 +317,7 @@ static struct of_device_id rgmii_match[] = {}, }; -static struct of_platform_driver rgmii_driver = { +static struct platform_driver rgmii_driver = { .driver = { .name = "emac-rgmii", .owner = THIS_MODULE, @@ -330,10 +329,10 @@ static struct of_platform_driver rgmii_driver = { int __init rgmii_init(void) { - return of_register_platform_driver(&rgmii_driver); + return platform_driver_register(&rgmii_driver); } void rgmii_exit(void) { - of_unregister_platform_driver(&rgmii_driver); + platform_driver_unregister(&rgmii_driver); } diff --git a/drivers/net/ibm_newemac/tah.c b/drivers/net/ibm_newemac/tah.c index 299aa49490c0..8ead6a96abaa 100644 --- a/drivers/net/ibm_newemac/tah.c +++ b/drivers/net/ibm_newemac/tah.c @@ -87,8 +87,7 @@ void *tah_dump_regs(struct platform_device *ofdev, void *buf) return regs + 1; } -static int __devinit tah_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit tah_probe(struct platform_device *ofdev) { struct device_node *np = ofdev->dev.of_node; struct tah_instance *dev; @@ -165,7 +164,7 @@ static struct of_device_id tah_match[] = {}, }; -static struct of_platform_driver tah_driver = { +static struct platform_driver tah_driver = { .driver = { .name = "emac-tah", .owner = THIS_MODULE, @@ -177,10 +176,10 @@ static struct of_platform_driver tah_driver = { int __init tah_init(void) { - return of_register_platform_driver(&tah_driver); + return platform_driver_register(&tah_driver); } void tah_exit(void) { - of_unregister_platform_driver(&tah_driver); + platform_driver_unregister(&tah_driver); } diff --git a/drivers/net/ibm_newemac/zmii.c b/drivers/net/ibm_newemac/zmii.c index 34ed6ee8ca8a..97449e786d61 100644 --- a/drivers/net/ibm_newemac/zmii.c +++ b/drivers/net/ibm_newemac/zmii.c @@ -231,8 +231,7 @@ void *zmii_dump_regs(struct platform_device *ofdev, void *buf) return regs + 1; } -static int __devinit zmii_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit zmii_probe(struct platform_device *ofdev) { struct device_node *np = ofdev->dev.of_node; struct zmii_instance *dev; @@ -312,7 +311,7 @@ static struct of_device_id zmii_match[] = {}, }; -static struct of_platform_driver zmii_driver = { +static struct platform_driver zmii_driver = { .driver = { .name = "emac-zmii", .owner = THIS_MODULE, @@ -324,10 +323,10 @@ static struct of_platform_driver zmii_driver = { int __init zmii_init(void) { - return of_register_platform_driver(&zmii_driver); + return platform_driver_register(&zmii_driver); } void zmii_exit(void) { - of_unregister_platform_driver(&zmii_driver); + platform_driver_unregister(&zmii_driver); } diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index f35554d11441..b7948ccfcf7d 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -952,8 +952,7 @@ static const struct attribute_group temac_attr_group = { .attrs = temac_device_attrs, }; -static int __devinit -temac_of_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit temac_of_probe(struct platform_device *op) { struct device_node *np; struct temac_local *lp; @@ -1123,7 +1122,7 @@ static struct of_device_id temac_of_match[] __devinitdata = { }; MODULE_DEVICE_TABLE(of, temac_of_match); -static struct of_platform_driver temac_of_driver = { +static struct platform_driver temac_of_driver = { .probe = temac_of_probe, .remove = __devexit_p(temac_of_remove), .driver = { @@ -1135,13 +1134,13 @@ static struct of_platform_driver temac_of_driver = { static int __init temac_init(void) { - return of_register_platform_driver(&temac_of_driver); + return platform_driver_register(&temac_of_driver); } module_init(temac_init); static void __exit temac_exit(void) { - of_unregister_platform_driver(&temac_of_driver); + platform_driver_unregister(&temac_of_driver); } module_exit(temac_exit); diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index 4846e131a04e..a761076b69c3 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -926,7 +926,7 @@ static const struct net_device_ops myri_ops = { .ndo_validate_addr = eth_validate_addr, }; -static int __devinit myri_sbus_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit myri_sbus_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; static unsigned version_printed; @@ -1160,7 +1160,7 @@ static const struct of_device_id myri_sbus_match[] = { MODULE_DEVICE_TABLE(of, myri_sbus_match); -static struct of_platform_driver myri_sbus_driver = { +static struct platform_driver myri_sbus_driver = { .driver = { .name = "myri", .owner = THIS_MODULE, @@ -1172,12 +1172,12 @@ static struct of_platform_driver myri_sbus_driver = { static int __init myri_sbus_init(void) { - return of_register_platform_driver(&myri_sbus_driver); + return platform_driver_register(&myri_sbus_driver); } static void __exit myri_sbus_exit(void) { - of_unregister_platform_driver(&myri_sbus_driver); + platform_driver_unregister(&myri_sbus_driver); } module_init(myri_sbus_init); diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 9fb59d3f9c92..40fa59e2fd5c 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -10062,8 +10062,7 @@ static const struct niu_ops niu_phys_ops = { .unmap_single = niu_phys_unmap_single, }; -static int __devinit niu_of_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit niu_of_probe(struct platform_device *op) { union niu_parent_id parent_id; struct net_device *dev; @@ -10223,7 +10222,7 @@ static const struct of_device_id niu_match[] = { }; MODULE_DEVICE_TABLE(of, niu_match); -static struct of_platform_driver niu_of_driver = { +static struct platform_driver niu_of_driver = { .driver = { .name = "niu", .owner = THIS_MODULE, @@ -10244,14 +10243,14 @@ static int __init niu_init(void) niu_debug = netif_msg_init(debug, NIU_MSG_DEFAULT); #ifdef CONFIG_SPARC64 - err = of_register_platform_driver(&niu_of_driver); + err = platform_driver_register(&niu_of_driver); #endif if (!err) { err = pci_register_driver(&niu_pci_driver); #ifdef CONFIG_SPARC64 if (err) - of_unregister_platform_driver(&niu_of_driver); + platform_driver_unregister(&niu_of_driver); #endif } @@ -10262,7 +10261,7 @@ static void __exit niu_exit(void) { pci_unregister_driver(&niu_pci_driver); #ifdef CONFIG_SPARC64 - of_unregister_platform_driver(&niu_of_driver); + platform_driver_unregister(&niu_of_driver); #endif } diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index f62c7b717bc8..47c8339a0359 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -188,8 +188,7 @@ static int __devexit mdio_gpio_remove(struct platform_device *pdev) #ifdef CONFIG_OF_GPIO -static int __devinit mdio_ofgpio_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit mdio_ofgpio_probe(struct platform_device *ofdev) { struct mdio_gpio_platform_data *pdata; struct mii_bus *new_bus; @@ -240,7 +239,7 @@ static struct of_device_id mdio_ofgpio_match[] = { }; MODULE_DEVICE_TABLE(of, mdio_ofgpio_match); -static struct of_platform_driver mdio_ofgpio_driver = { +static struct platform_driver mdio_ofgpio_driver = { .driver = { .name = "mdio-gpio", .owner = THIS_MODULE, @@ -252,12 +251,12 @@ static struct of_platform_driver mdio_ofgpio_driver = { static inline int __init mdio_ofgpio_init(void) { - return of_register_platform_driver(&mdio_ofgpio_driver); + return platform_driver_register(&mdio_ofgpio_driver); } static inline void __exit mdio_ofgpio_exit(void) { - of_unregister_platform_driver(&mdio_ofgpio_driver); + platform_driver_unregister(&mdio_ofgpio_driver); } #else static inline int __init mdio_ofgpio_init(void) { return 0; } diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index 0a6a5ced3c1c..aa4765803a4c 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -1242,8 +1242,7 @@ fail_and_cleanup: /* QEC can be the parent of either QuadEthernet or a BigMAC. We want * the latter. */ -static int __devinit bigmac_sbus_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit bigmac_sbus_probe(struct platform_device *op) { struct device *parent = op->dev.parent; struct platform_device *qec_op; @@ -1289,7 +1288,7 @@ static const struct of_device_id bigmac_sbus_match[] = { MODULE_DEVICE_TABLE(of, bigmac_sbus_match); -static struct of_platform_driver bigmac_sbus_driver = { +static struct platform_driver bigmac_sbus_driver = { .driver = { .name = "sunbmac", .owner = THIS_MODULE, @@ -1301,12 +1300,12 @@ static struct of_platform_driver bigmac_sbus_driver = { static int __init bigmac_init(void) { - return of_register_platform_driver(&bigmac_sbus_driver); + return platform_driver_register(&bigmac_sbus_driver); } static void __exit bigmac_exit(void) { - of_unregister_platform_driver(&bigmac_sbus_driver); + platform_driver_unregister(&bigmac_sbus_driver); } module_init(bigmac_init); diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index 55bbb9c15d96..eb4f59fb01e9 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -3237,11 +3237,15 @@ static void happy_meal_pci_exit(void) #endif #ifdef CONFIG_SBUS -static int __devinit hme_sbus_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit hme_sbus_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; const char *model = of_get_property(dp, "model", NULL); - int is_qfe = (match->data != NULL); + int is_qfe; + + if (!op->dev.of_match) + return -EINVAL; + is_qfe = (op->dev.of_match->data != NULL); if (!is_qfe && model && !strcmp(model, "SUNW,sbus-qfe")) is_qfe = 1; @@ -3292,7 +3296,7 @@ static const struct of_device_id hme_sbus_match[] = { MODULE_DEVICE_TABLE(of, hme_sbus_match); -static struct of_platform_driver hme_sbus_driver = { +static struct platform_driver hme_sbus_driver = { .driver = { .name = "hme", .owner = THIS_MODULE, @@ -3306,7 +3310,7 @@ static int __init happy_meal_sbus_init(void) { int err; - err = of_register_platform_driver(&hme_sbus_driver); + err = platform_driver_register(&hme_sbus_driver); if (!err) err = quattro_sbus_register_irqs(); @@ -3315,7 +3319,7 @@ static int __init happy_meal_sbus_init(void) static void happy_meal_sbus_exit(void) { - of_unregister_platform_driver(&hme_sbus_driver); + platform_driver_unregister(&hme_sbus_driver); quattro_sbus_free_irqs(); while (qfe_sbus_list) { diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 767e1e2b210d..32a5c7f63c43 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1495,7 +1495,7 @@ fail: return -ENODEV; } -static int __devinit sunlance_sbus_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit sunlance_sbus_probe(struct platform_device *op) { struct platform_device *parent = to_platform_device(op->dev.parent); struct device_node *parent_dp = parent->dev.of_node; @@ -1536,7 +1536,7 @@ static const struct of_device_id sunlance_sbus_match[] = { MODULE_DEVICE_TABLE(of, sunlance_sbus_match); -static struct of_platform_driver sunlance_sbus_driver = { +static struct platform_driver sunlance_sbus_driver = { .driver = { .name = "sunlance", .owner = THIS_MODULE, @@ -1550,12 +1550,12 @@ static struct of_platform_driver sunlance_sbus_driver = { /* Find all the lance cards on the system and initialize them */ static int __init sparc_lance_init(void) { - return of_register_platform_driver(&sunlance_sbus_driver); + return platform_driver_register(&sunlance_sbus_driver); } static void __exit sparc_lance_exit(void) { - of_unregister_platform_driver(&sunlance_sbus_driver); + platform_driver_unregister(&sunlance_sbus_driver); } module_init(sparc_lance_init); diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index 9536b2f010be..18ecdc303751 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c @@ -941,7 +941,7 @@ fail: return res; } -static int __devinit qec_sbus_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit qec_sbus_probe(struct platform_device *op) { return qec_ether_init(op); } @@ -976,7 +976,7 @@ static const struct of_device_id qec_sbus_match[] = { MODULE_DEVICE_TABLE(of, qec_sbus_match); -static struct of_platform_driver qec_sbus_driver = { +static struct platform_driver qec_sbus_driver = { .driver = { .name = "qec", .owner = THIS_MODULE, @@ -988,12 +988,12 @@ static struct of_platform_driver qec_sbus_driver = { static int __init qec_init(void) { - return of_register_platform_driver(&qec_sbus_driver); + return platform_driver_register(&qec_sbus_driver); } static void __exit qec_exit(void) { - of_unregister_platform_driver(&qec_sbus_driver); + platform_driver_unregister(&qec_sbus_driver); while (root_qec_dev) { struct sunqec *next = root_qec_dev->next_module; diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 715e7b47e7e9..ef041057d9d3 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3740,7 +3740,7 @@ static const struct net_device_ops ucc_geth_netdev_ops = { #endif }; -static int ucc_geth_probe(struct platform_device* ofdev, const struct of_device_id *match) +static int ucc_geth_probe(struct platform_device* ofdev) { struct device *device = &ofdev->dev; struct device_node *np = ofdev->dev.of_node; @@ -3986,7 +3986,7 @@ static struct of_device_id ucc_geth_match[] = { MODULE_DEVICE_TABLE(of, ucc_geth_match); -static struct of_platform_driver ucc_geth_driver = { +static struct platform_driver ucc_geth_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, @@ -4008,14 +4008,14 @@ static int __init ucc_geth_init(void) memcpy(&(ugeth_info[i]), &ugeth_primary_info, sizeof(ugeth_primary_info)); - ret = of_register_platform_driver(&ucc_geth_driver); + ret = platform_driver_register(&ucc_geth_driver); return ret; } static void __exit ucc_geth_exit(void) { - of_unregister_platform_driver(&ucc_geth_driver); + platform_driver_unregister(&ucc_geth_driver); } module_init(ucc_geth_init); diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index cad66ce1640b..2642af4ee491 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -1101,8 +1101,7 @@ static struct net_device_ops xemaclite_netdev_ops; * Return: 0, if the driver is bound to the Emaclite device, or * a negative error if there is failure. */ -static int __devinit xemaclite_of_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit xemaclite_of_probe(struct platform_device *ofdev) { struct resource r_irq; /* Interrupt resources */ struct resource r_mem; /* IO mem resources */ @@ -1288,7 +1287,7 @@ static struct of_device_id xemaclite_of_match[] __devinitdata = { }; MODULE_DEVICE_TABLE(of, xemaclite_of_match); -static struct of_platform_driver xemaclite_of_driver = { +static struct platform_driver xemaclite_of_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, @@ -1306,7 +1305,7 @@ static struct of_platform_driver xemaclite_of_driver = { static int __init xemaclite_init(void) { /* No kernel boot options used, we just need to register the driver */ - return of_register_platform_driver(&xemaclite_of_driver); + return platform_driver_register(&xemaclite_of_driver); } /** @@ -1314,7 +1313,7 @@ static int __init xemaclite_init(void) */ static void __exit xemaclite_cleanup(void) { - of_unregister_platform_driver(&xemaclite_of_driver); + platform_driver_unregister(&xemaclite_of_driver); } module_init(xemaclite_init); -- cgit v1.2.3 From 28541d0f1894cd0c8f4a90c6e006c88d38ad3ac0 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 22 Feb 2011 21:07:43 -0700 Subject: dt/video: Eliminate users of of_platform_{,un}register_driver Get rid of users of of_platform_driver in drivers/video. The of_platform_{,un}register_driver functions are going away, so the users need to be converted to using the platform_bus_type directly. Signed-off-by: Grant Likely --- drivers/video/bw2.c | 8 ++++---- drivers/video/cg14.c | 8 ++++---- drivers/video/cg3.c | 9 ++++----- drivers/video/cg6.c | 9 ++++----- drivers/video/ffb.c | 9 ++++----- drivers/video/fsl-diu-fb.c | 9 ++++----- drivers/video/leo.c | 9 ++++----- drivers/video/mb862xx/mb862xxfb.c | 9 ++++----- drivers/video/p9100.c | 8 ++++---- drivers/video/platinumfb.c | 9 ++++----- drivers/video/sunxvr1000.c | 9 ++++----- drivers/video/tcx.c | 9 ++++----- drivers/video/xilinxfb.c | 11 ++++------- 13 files changed, 52 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c index 4dc13467281d..7ba74cd4be61 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c @@ -273,7 +273,7 @@ static int __devinit bw2_do_default_mode(struct bw2_par *par, return 0; } -static int __devinit bw2_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit bw2_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; struct fb_info *info; @@ -375,7 +375,7 @@ static const struct of_device_id bw2_match[] = { }; MODULE_DEVICE_TABLE(of, bw2_match); -static struct of_platform_driver bw2_driver = { +static struct platform_driver bw2_driver = { .driver = { .name = "bw2", .owner = THIS_MODULE, @@ -390,12 +390,12 @@ static int __init bw2_init(void) if (fb_get_options("bw2fb", NULL)) return -ENODEV; - return of_register_platform_driver(&bw2_driver); + return platform_driver_register(&bw2_driver); } static void __exit bw2_exit(void) { - of_unregister_platform_driver(&bw2_driver); + platform_driver_unregister(&bw2_driver); } module_init(bw2_init); diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c index 24249535ac86..e2c85b0db632 100644 --- a/drivers/video/cg14.c +++ b/drivers/video/cg14.c @@ -463,7 +463,7 @@ static void cg14_unmap_regs(struct platform_device *op, struct fb_info *info, info->screen_base, info->fix.smem_len); } -static int __devinit cg14_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit cg14_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; struct fb_info *info; @@ -595,7 +595,7 @@ static const struct of_device_id cg14_match[] = { }; MODULE_DEVICE_TABLE(of, cg14_match); -static struct of_platform_driver cg14_driver = { +static struct platform_driver cg14_driver = { .driver = { .name = "cg14", .owner = THIS_MODULE, @@ -610,12 +610,12 @@ static int __init cg14_init(void) if (fb_get_options("cg14fb", NULL)) return -ENODEV; - return of_register_platform_driver(&cg14_driver); + return platform_driver_register(&cg14_driver); } static void __exit cg14_exit(void) { - of_unregister_platform_driver(&cg14_driver); + platform_driver_unregister(&cg14_driver); } module_init(cg14_init); diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c index 09c0c3c42482..f927a7b1a8d4 100644 --- a/drivers/video/cg3.c +++ b/drivers/video/cg3.c @@ -346,8 +346,7 @@ static int __devinit cg3_do_default_mode(struct cg3_par *par) return 0; } -static int __devinit cg3_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit cg3_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; struct fb_info *info; @@ -462,7 +461,7 @@ static const struct of_device_id cg3_match[] = { }; MODULE_DEVICE_TABLE(of, cg3_match); -static struct of_platform_driver cg3_driver = { +static struct platform_driver cg3_driver = { .driver = { .name = "cg3", .owner = THIS_MODULE, @@ -477,12 +476,12 @@ static int __init cg3_init(void) if (fb_get_options("cg3fb", NULL)) return -ENODEV; - return of_register_platform_driver(&cg3_driver); + return platform_driver_register(&cg3_driver); } static void __exit cg3_exit(void) { - of_unregister_platform_driver(&cg3_driver); + platform_driver_unregister(&cg3_driver); } module_init(cg3_init); diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index 2b5a97058b08..4ffad90bde42 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c @@ -737,8 +737,7 @@ static void cg6_unmap_regs(struct platform_device *op, struct fb_info *info, info->fix.smem_len); } -static int __devinit cg6_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit cg6_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; struct fb_info *info; @@ -855,7 +854,7 @@ static const struct of_device_id cg6_match[] = { }; MODULE_DEVICE_TABLE(of, cg6_match); -static struct of_platform_driver cg6_driver = { +static struct platform_driver cg6_driver = { .driver = { .name = "cg6", .owner = THIS_MODULE, @@ -870,12 +869,12 @@ static int __init cg6_init(void) if (fb_get_options("cg6fb", NULL)) return -ENODEV; - return of_register_platform_driver(&cg6_driver); + return platform_driver_register(&cg6_driver); } static void __exit cg6_exit(void) { - of_unregister_platform_driver(&cg6_driver); + platform_driver_unregister(&cg6_driver); } module_init(cg6_init); diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c index 6739b2af3bc0..910c5e6f6702 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/ffb.c @@ -893,8 +893,7 @@ static void ffb_init_fix(struct fb_info *info) info->fix.accel = FB_ACCEL_SUN_CREATOR; } -static int __devinit ffb_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit ffb_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; struct ffb_fbc __iomem *fbc; @@ -1052,7 +1051,7 @@ static const struct of_device_id ffb_match[] = { }; MODULE_DEVICE_TABLE(of, ffb_match); -static struct of_platform_driver ffb_driver = { +static struct platform_driver ffb_driver = { .driver = { .name = "ffb", .owner = THIS_MODULE, @@ -1067,12 +1066,12 @@ static int __init ffb_init(void) if (fb_get_options("ffb", NULL)) return -ENODEV; - return of_register_platform_driver(&ffb_driver); + return platform_driver_register(&ffb_driver); } static void __exit ffb_exit(void) { - of_unregister_platform_driver(&ffb_driver); + platform_driver_unregister(&ffb_driver); } module_init(ffb_init); diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 8bbbf08fa3ce..9048f87fa8c1 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c @@ -1487,8 +1487,7 @@ static ssize_t show_monitor(struct device *device, return diu_ops.show_monitor_port(machine_data->monitor_port, buf); } -static int __devinit fsl_diu_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit fsl_diu_probe(struct platform_device *ofdev) { struct device_node *np = ofdev->dev.of_node; struct mfb_info *mfbi; @@ -1735,7 +1734,7 @@ static struct of_device_id fsl_diu_match[] = { }; MODULE_DEVICE_TABLE(of, fsl_diu_match); -static struct of_platform_driver fsl_diu_driver = { +static struct platform_driver fsl_diu_driver = { .driver = { .name = "fsl_diu", .owner = THIS_MODULE, @@ -1797,7 +1796,7 @@ static int __init fsl_diu_init(void) if (!coherence_data) return -ENOMEM; #endif - ret = of_register_platform_driver(&fsl_diu_driver); + ret = platform_driver_register(&fsl_diu_driver); if (ret) { printk(KERN_ERR "fsl-diu: failed to register platform driver\n"); @@ -1811,7 +1810,7 @@ static int __init fsl_diu_init(void) static void __exit fsl_diu_exit(void) { - of_unregister_platform_driver(&fsl_diu_driver); + platform_driver_unregister(&fsl_diu_driver); #if defined(CONFIG_NOT_COHERENT_CACHE) vfree(coherence_data); #endif diff --git a/drivers/video/leo.c b/drivers/video/leo.c index b599e5e36ced..9e946e2c1da9 100644 --- a/drivers/video/leo.c +++ b/drivers/video/leo.c @@ -547,8 +547,7 @@ static void leo_unmap_regs(struct platform_device *op, struct fb_info *info, of_iounmap(&op->resource[0], info->screen_base, 0x800000); } -static int __devinit leo_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit leo_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; struct fb_info *info; @@ -662,7 +661,7 @@ static const struct of_device_id leo_match[] = { }; MODULE_DEVICE_TABLE(of, leo_match); -static struct of_platform_driver leo_driver = { +static struct platform_driver leo_driver = { .driver = { .name = "leo", .owner = THIS_MODULE, @@ -677,12 +676,12 @@ static int __init leo_init(void) if (fb_get_options("leofb", NULL)) return -ENODEV; - return of_register_platform_driver(&leo_driver); + return platform_driver_register(&leo_driver); } static void __exit leo_exit(void) { - of_unregister_platform_driver(&leo_driver); + platform_driver_unregister(&leo_driver); } module_init(leo_init); diff --git a/drivers/video/mb862xx/mb862xxfb.c b/drivers/video/mb862xx/mb862xxfb.c index b1c4374cf940..c76e663a6cd4 100644 --- a/drivers/video/mb862xx/mb862xxfb.c +++ b/drivers/video/mb862xx/mb862xxfb.c @@ -550,8 +550,7 @@ static int mb862xx_gdc_init(struct mb862xxfb_par *par) return 0; } -static int __devinit of_platform_mb862xx_probe(struct platform_device *ofdev, - const struct of_device_id *id) +static int __devinit of_platform_mb862xx_probe(struct platform_device *ofdev) { struct device_node *np = ofdev->dev.of_node; struct device *dev = &ofdev->dev; @@ -717,7 +716,7 @@ static struct of_device_id __devinitdata of_platform_mb862xx_tbl[] = { { /* end */ } }; -static struct of_platform_driver of_platform_mb862xxfb_driver = { +static struct platform_driver of_platform_mb862xxfb_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, @@ -1038,7 +1037,7 @@ static int __devinit mb862xxfb_init(void) int ret = -ENODEV; #if defined(CONFIG_FB_MB862XX_LIME) - ret = of_register_platform_driver(&of_platform_mb862xxfb_driver); + ret = platform_driver_register(&of_platform_mb862xxfb_driver); #endif #if defined(CONFIG_FB_MB862XX_PCI_GDC) ret = pci_register_driver(&mb862xxfb_pci_driver); @@ -1049,7 +1048,7 @@ static int __devinit mb862xxfb_init(void) static void __exit mb862xxfb_exit(void) { #if defined(CONFIG_FB_MB862XX_LIME) - of_unregister_platform_driver(&of_platform_mb862xxfb_driver); + platform_driver_unregister(&of_platform_mb862xxfb_driver); #endif #if defined(CONFIG_FB_MB862XX_PCI_GDC) pci_unregister_driver(&mb862xxfb_pci_driver); diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c index b6c3fc2db632..d57cc58c5168 100644 --- a/drivers/video/p9100.c +++ b/drivers/video/p9100.c @@ -249,7 +249,7 @@ static void p9100_init_fix(struct fb_info *info, int linebytes, struct device_no info->fix.accel = FB_ACCEL_SUN_CGTHREE; } -static int __devinit p9100_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit p9100_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; struct fb_info *info; @@ -352,7 +352,7 @@ static const struct of_device_id p9100_match[] = { }; MODULE_DEVICE_TABLE(of, p9100_match); -static struct of_platform_driver p9100_driver = { +static struct platform_driver p9100_driver = { .driver = { .name = "p9100", .owner = THIS_MODULE, @@ -367,12 +367,12 @@ static int __init p9100_init(void) if (fb_get_options("p9100fb", NULL)) return -ENODEV; - return of_register_platform_driver(&p9100_driver); + return platform_driver_register(&p9100_driver); } static void __exit p9100_exit(void) { - of_unregister_platform_driver(&p9100_driver); + platform_driver_unregister(&p9100_driver); } module_init(p9100_init); diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index a50e1977b316..ef532d9d3c99 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c @@ -533,8 +533,7 @@ static int __init platinumfb_setup(char *options) #define invalidate_cache(addr) #endif -static int __devinit platinumfb_probe(struct platform_device* odev, - const struct of_device_id *match) +static int __devinit platinumfb_probe(struct platform_device* odev) { struct device_node *dp = odev->dev.of_node; struct fb_info *info; @@ -677,7 +676,7 @@ static struct of_device_id platinumfb_match[] = {}, }; -static struct of_platform_driver platinum_driver = +static struct platform_driver platinum_driver = { .driver = { .name = "platinumfb", @@ -697,14 +696,14 @@ static int __init platinumfb_init(void) return -ENODEV; platinumfb_setup(option); #endif - of_register_platform_driver(&platinum_driver); + platform_driver_register(&platinum_driver); return 0; } static void __exit platinumfb_exit(void) { - of_unregister_platform_driver(&platinum_driver); + platform_driver_unregister(&platinum_driver); } MODULE_LICENSE("GPL"); diff --git a/drivers/video/sunxvr1000.c b/drivers/video/sunxvr1000.c index 5dbe06af2226..b7f27acaf817 100644 --- a/drivers/video/sunxvr1000.c +++ b/drivers/video/sunxvr1000.c @@ -111,8 +111,7 @@ static int __devinit gfb_set_fbinfo(struct gfb_info *gp) return 0; } -static int __devinit gfb_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit gfb_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; struct fb_info *info; @@ -198,7 +197,7 @@ static const struct of_device_id gfb_match[] = { }; MODULE_DEVICE_TABLE(of, ffb_match); -static struct of_platform_driver gfb_driver = { +static struct platform_driver gfb_driver = { .probe = gfb_probe, .remove = __devexit_p(gfb_remove), .driver = { @@ -213,12 +212,12 @@ static int __init gfb_init(void) if (fb_get_options("gfb", NULL)) return -ENODEV; - return of_register_platform_driver(&gfb_driver); + return platform_driver_register(&gfb_driver); } static void __exit gfb_exit(void) { - of_unregister_platform_driver(&gfb_driver); + platform_driver_unregister(&gfb_driver); } module_init(gfb_init); diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c index 77ad27955cf0..855b71993f61 100644 --- a/drivers/video/tcx.c +++ b/drivers/video/tcx.c @@ -362,8 +362,7 @@ static void tcx_unmap_regs(struct platform_device *op, struct fb_info *info, info->screen_base, info->fix.smem_len); } -static int __devinit tcx_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit tcx_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; struct fb_info *info; @@ -511,7 +510,7 @@ static const struct of_device_id tcx_match[] = { }; MODULE_DEVICE_TABLE(of, tcx_match); -static struct of_platform_driver tcx_driver = { +static struct platform_driver tcx_driver = { .driver = { .name = "tcx", .owner = THIS_MODULE, @@ -526,12 +525,12 @@ static int __init tcx_init(void) if (fb_get_options("tcxfb", NULL)) return -ENODEV; - return of_register_platform_driver(&tcx_driver); + return platform_driver_register(&tcx_driver); } static void __exit tcx_exit(void) { - of_unregister_platform_driver(&tcx_driver); + platform_driver_unregister(&tcx_driver); } module_init(tcx_init); diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 68bd23476c64..77dea015ff69 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -404,8 +404,7 @@ static int xilinxfb_release(struct device *dev) * OF bus binding */ -static int __devinit -xilinxfb_of_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit xilinxfb_of_probe(struct platform_device *op) { const u32 *prop; u32 *p; @@ -418,8 +417,6 @@ xilinxfb_of_probe(struct platform_device *op, const struct of_device_id *match) /* Copy with the default pdata (not a ptr reference!) */ pdata = xilinx_fb_default_pdata; - dev_dbg(&op->dev, "xilinxfb_of_probe(%p, %p)\n", op, match); - /* Allocate the driver data region */ drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); if (!drvdata) { @@ -505,7 +502,7 @@ static struct of_device_id xilinxfb_of_match[] __devinitdata = { }; MODULE_DEVICE_TABLE(of, xilinxfb_of_match); -static struct of_platform_driver xilinxfb_of_driver = { +static struct platform_driver xilinxfb_of_driver = { .probe = xilinxfb_of_probe, .remove = __devexit_p(xilinxfb_of_remove), .driver = { @@ -523,13 +520,13 @@ static struct of_platform_driver xilinxfb_of_driver = { static int __init xilinxfb_init(void) { - return of_register_platform_driver(&xilinxfb_of_driver); + return platform_driver_register(&xilinxfb_of_driver); } static void __exit xilinxfb_cleanup(void) { - of_unregister_platform_driver(&xilinxfb_of_driver); + platform_driver_unregister(&xilinxfb_of_driver); } module_init(xilinxfb_init); -- cgit v1.2.3 From d35fb6417655ebf6de93e2135dc386c3c470f545 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 22 Feb 2011 21:08:34 -0700 Subject: dt/usb: Eliminate users of of_platform_{,un}register_driver Get rid of users of of_platform_driver in drivers/usb. The of_platform_{,un}register_driver functions are going away, so the users need to be converted to using the platform_bus_type directly. Signed-off-by: Grant Likely --- drivers/usb/gadget/fsl_qe_udc.c | 14 ++++++++------ drivers/usb/host/ehci-hcd.c | 12 ++++++------ drivers/usb/host/ehci-ppc-of.c | 9 +++------ drivers/usb/host/ehci-xilinx-of.c | 6 ++---- drivers/usb/host/fhci-hcd.c | 9 ++++----- drivers/usb/host/isp1760-if.c | 9 ++++----- drivers/usb/host/ohci-hcd.c | 6 +++--- drivers/usb/host/ohci-ppc-of.c | 9 +++------ 8 files changed, 33 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index 792d5ef40137..aee7e3c53c38 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -2523,8 +2523,7 @@ static void qe_udc_release(struct device *dev) } /* Driver probe functions */ -static int __devinit qe_udc_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit qe_udc_probe(struct platform_device *ofdev) { struct device_node *np = ofdev->dev.of_node; struct qe_ep *ep; @@ -2532,6 +2531,9 @@ static int __devinit qe_udc_probe(struct platform_device *ofdev, unsigned int i; const void *prop; + if (!ofdev->dev.of_match) + return -EINVAL; + prop = of_get_property(np, "mode", NULL); if (!prop || strcmp(prop, "peripheral")) return -ENODEV; @@ -2543,7 +2545,7 @@ static int __devinit qe_udc_probe(struct platform_device *ofdev, return -ENOMEM; } - udc_controller->soc_type = (unsigned long)match->data; + udc_controller->soc_type = (unsigned long)ofdev->dev.of_match->data; udc_controller->usb_regs = of_iomap(np, 0); if (!udc_controller->usb_regs) { ret = -ENOMEM; @@ -2768,7 +2770,7 @@ static const struct of_device_id qe_udc_match[] __devinitconst = { MODULE_DEVICE_TABLE(of, qe_udc_match); -static struct of_platform_driver udc_driver = { +static struct platform_driver udc_driver = { .driver = { .name = (char *)driver_name, .owner = THIS_MODULE, @@ -2786,12 +2788,12 @@ static int __init qe_udc_init(void) { printk(KERN_INFO "%s: %s, %s\n", driver_name, driver_desc, DRIVER_VERSION); - return of_register_platform_driver(&udc_driver); + return platform_driver_register(&udc_driver); } static void __exit qe_udc_exit(void) { - of_unregister_platform_driver(&udc_driver); + platform_driver_unregister(&udc_driver); } module_init(qe_udc_init); diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 74dcf49bd015..c4de2d75a3d7 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1306,24 +1306,24 @@ static int __init ehci_hcd_init(void) #endif #ifdef OF_PLATFORM_DRIVER - retval = of_register_platform_driver(&OF_PLATFORM_DRIVER); + retval = platform_driver_register(&OF_PLATFORM_DRIVER); if (retval < 0) goto clean3; #endif #ifdef XILINX_OF_PLATFORM_DRIVER - retval = of_register_platform_driver(&XILINX_OF_PLATFORM_DRIVER); + retval = platform_driver_register(&XILINX_OF_PLATFORM_DRIVER); if (retval < 0) goto clean4; #endif return retval; #ifdef XILINX_OF_PLATFORM_DRIVER - /* of_unregister_platform_driver(&XILINX_OF_PLATFORM_DRIVER); */ + /* platform_driver_unregister(&XILINX_OF_PLATFORM_DRIVER); */ clean4: #endif #ifdef OF_PLATFORM_DRIVER - of_unregister_platform_driver(&OF_PLATFORM_DRIVER); + platform_driver_unregister(&OF_PLATFORM_DRIVER); clean3: #endif #ifdef PS3_SYSTEM_BUS_DRIVER @@ -1351,10 +1351,10 @@ module_init(ehci_hcd_init); static void __exit ehci_hcd_cleanup(void) { #ifdef XILINX_OF_PLATFORM_DRIVER - of_unregister_platform_driver(&XILINX_OF_PLATFORM_DRIVER); + platform_driver_unregister(&XILINX_OF_PLATFORM_DRIVER); #endif #ifdef OF_PLATFORM_DRIVER - of_unregister_platform_driver(&OF_PLATFORM_DRIVER); + platform_driver_unregister(&OF_PLATFORM_DRIVER); #endif #ifdef PLATFORM_DRIVER platform_driver_unregister(&PLATFORM_DRIVER); diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index ba52be473027..1f09f253697e 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -105,8 +105,7 @@ ppc44x_enable_bmt(struct device_node *dn) } -static int __devinit -ehci_hcd_ppc_of_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit ehci_hcd_ppc_of_probe(struct platform_device *op) { struct device_node *dn = op->dev.of_node; struct usb_hcd *hcd; @@ -255,14 +254,12 @@ static int ehci_hcd_ppc_of_remove(struct platform_device *op) } -static int ehci_hcd_ppc_of_shutdown(struct platform_device *op) +static void ehci_hcd_ppc_of_shutdown(struct platform_device *op) { struct usb_hcd *hcd = dev_get_drvdata(&op->dev); if (hcd->driver->shutdown) hcd->driver->shutdown(hcd); - - return 0; } @@ -275,7 +272,7 @@ static const struct of_device_id ehci_hcd_ppc_of_match[] = { MODULE_DEVICE_TABLE(of, ehci_hcd_ppc_of_match); -static struct of_platform_driver ehci_hcd_ppc_of_driver = { +static struct platform_driver ehci_hcd_ppc_of_driver = { .probe = ehci_hcd_ppc_of_probe, .remove = ehci_hcd_ppc_of_remove, .shutdown = ehci_hcd_ppc_of_shutdown, diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index e8f4f36fdf0b..17c1b1142e38 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c @@ -142,15 +142,13 @@ static const struct hc_driver ehci_xilinx_of_hc_driver = { /** * ehci_hcd_xilinx_of_probe - Probe method for the USB host controller * @op: pointer to the platform_device bound to the host controller - * @match: pointer to of_device_id structure, not used * * This function requests resources and sets up appropriate properties for the * host controller. Because the Xilinx USB host controller can be configured * as HS only or HS/FS only, it checks the configuration in the device tree * entry, and sets an appropriate value for hcd->has_tt. */ -static int __devinit -ehci_hcd_xilinx_of_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit ehci_hcd_xilinx_of_probe(struct platform_device *op) { struct device_node *dn = op->dev.of_node; struct usb_hcd *hcd; @@ -288,7 +286,7 @@ static const struct of_device_id ehci_hcd_xilinx_of_match[] = { }; MODULE_DEVICE_TABLE(of, ehci_hcd_xilinx_of_match); -static struct of_platform_driver ehci_hcd_xilinx_of_driver = { +static struct platform_driver ehci_hcd_xilinx_of_driver = { .probe = ehci_hcd_xilinx_of_probe, .remove = ehci_hcd_xilinx_of_remove, .shutdown = ehci_hcd_xilinx_of_shutdown, diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 12fd184226f2..b84ff7e51896 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -561,8 +561,7 @@ static const struct hc_driver fhci_driver = { .hub_control = fhci_hub_control, }; -static int __devinit of_fhci_probe(struct platform_device *ofdev, - const struct of_device_id *ofid) +static int __devinit of_fhci_probe(struct platform_device *ofdev) { struct device *dev = &ofdev->dev; struct device_node *node = dev->of_node; @@ -812,7 +811,7 @@ static const struct of_device_id of_fhci_match[] = { }; MODULE_DEVICE_TABLE(of, of_fhci_match); -static struct of_platform_driver of_fhci_driver = { +static struct platform_driver of_fhci_driver = { .driver = { .name = "fsl,usb-fhci", .owner = THIS_MODULE, @@ -824,13 +823,13 @@ static struct of_platform_driver of_fhci_driver = { static int __init fhci_module_init(void) { - return of_register_platform_driver(&of_fhci_driver); + return platform_driver_register(&of_fhci_driver); } module_init(fhci_module_init); static void __exit fhci_module_exit(void) { - of_unregister_platform_driver(&of_fhci_driver); + platform_driver_unregister(&of_fhci_driver); } module_exit(fhci_module_exit); diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 3b28dbfca058..7ee30056f373 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -27,8 +27,7 @@ #endif #ifdef CONFIG_PPC_OF -static int of_isp1760_probe(struct platform_device *dev, - const struct of_device_id *match) +static int of_isp1760_probe(struct platform_device *dev) { struct usb_hcd *hcd; struct device_node *dp = dev->dev.of_node; @@ -119,7 +118,7 @@ static const struct of_device_id of_isp1760_match[] = { }; MODULE_DEVICE_TABLE(of, of_isp1760_match); -static struct of_platform_driver isp1760_of_driver = { +static struct platform_driver isp1760_of_driver = { .driver = { .name = "nxp-isp1760", .owner = THIS_MODULE, @@ -398,7 +397,7 @@ static int __init isp1760_init(void) if (!ret) any_ret = 0; #ifdef CONFIG_PPC_OF - ret = of_register_platform_driver(&isp1760_of_driver); + ret = platform_driver_register(&isp1760_of_driver); if (!ret) any_ret = 0; #endif @@ -418,7 +417,7 @@ static void __exit isp1760_exit(void) { platform_driver_unregister(&isp1760_plat_driver); #ifdef CONFIG_PPC_OF - of_unregister_platform_driver(&isp1760_of_driver); + platform_driver_unregister(&isp1760_of_driver); #endif #ifdef CONFIG_PCI pci_unregister_driver(&isp1761_pci_driver); diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 759a12ff8048..54240f6bd2db 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1180,7 +1180,7 @@ static int __init ohci_hcd_mod_init(void) #endif #ifdef OF_PLATFORM_DRIVER - retval = of_register_platform_driver(&OF_PLATFORM_DRIVER); + retval = platform_driver_register(&OF_PLATFORM_DRIVER); if (retval < 0) goto error_of_platform; #endif @@ -1239,7 +1239,7 @@ static int __init ohci_hcd_mod_init(void) error_sa1111: #endif #ifdef OF_PLATFORM_DRIVER - of_unregister_platform_driver(&OF_PLATFORM_DRIVER); + platform_driver_unregister(&OF_PLATFORM_DRIVER); error_of_platform: #endif #ifdef PLATFORM_DRIVER @@ -1287,7 +1287,7 @@ static void __exit ohci_hcd_mod_exit(void) sa1111_driver_unregister(&SA1111_DRIVER); #endif #ifdef OF_PLATFORM_DRIVER - of_unregister_platform_driver(&OF_PLATFORM_DRIVER); + platform_driver_unregister(&OF_PLATFORM_DRIVER); #endif #ifdef PLATFORM_DRIVER platform_driver_unregister(&PLATFORM_DRIVER); diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index b2c2dbf08766..1ca1821320f4 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c @@ -80,8 +80,7 @@ static const struct hc_driver ohci_ppc_of_hc_driver = { }; -static int __devinit -ohci_hcd_ppc_of_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit ohci_hcd_ppc_of_probe(struct platform_device *op) { struct device_node *dn = op->dev.of_node; struct usb_hcd *hcd; @@ -201,14 +200,12 @@ static int ohci_hcd_ppc_of_remove(struct platform_device *op) return 0; } -static int ohci_hcd_ppc_of_shutdown(struct platform_device *op) +static void ohci_hcd_ppc_of_shutdown(struct platform_device *op) { struct usb_hcd *hcd = dev_get_drvdata(&op->dev); if (hcd->driver->shutdown) hcd->driver->shutdown(hcd); - - return 0; } @@ -243,7 +240,7 @@ MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_match); #endif -static struct of_platform_driver ohci_hcd_ppc_of_driver = { +static struct platform_driver ohci_hcd_ppc_of_driver = { .probe = ohci_hcd_ppc_of_probe, .remove = ohci_hcd_ppc_of_remove, .shutdown = ohci_hcd_ppc_of_shutdown, -- cgit v1.2.3 From 793218dfea146946a076f4fe51e574db61034a3e Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 22 Feb 2011 21:10:26 -0700 Subject: dt/serial: Eliminate users of of_platform_{,un}register_driver Get rid of users of of_platform_driver in drivers/serial. The of_platform_{,un}register_driver functions are going away, so the users need to be converted to using the platform_bus_type directly. Signed-off-by: Grant Likely Reviewed-by: Arnd Bergmann --- drivers/tty/serial/apbuart.c | 11 +++++------ drivers/tty/serial/cpm_uart/cpm_uart_core.c | 9 ++++----- drivers/tty/serial/mpc52xx_uart.c | 13 +++++-------- drivers/tty/serial/of_serial.c | 14 ++++++++------ drivers/tty/serial/sunhv.c | 8 ++++---- drivers/tty/serial/sunsab.c | 8 ++++---- drivers/tty/serial/sunsu.c | 6 +++--- drivers/tty/serial/sunzilog.c | 10 +++++----- drivers/tty/serial/ucc_uart.c | 9 ++++----- 9 files changed, 42 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c index 095a5d562618..1ab999b04ef3 100644 --- a/drivers/tty/serial/apbuart.c +++ b/drivers/tty/serial/apbuart.c @@ -553,8 +553,7 @@ static struct uart_driver grlib_apbuart_driver = { /* OF Platform Driver */ /* ======================================================================== */ -static int __devinit apbuart_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit apbuart_probe(struct platform_device *op) { int i = -1; struct uart_port *port = NULL; @@ -587,7 +586,7 @@ static struct of_device_id __initdata apbuart_match[] = { {}, }; -static struct of_platform_driver grlib_apbuart_of_driver = { +static struct platform_driver grlib_apbuart_of_driver = { .probe = apbuart_probe, .driver = { .owner = THIS_MODULE, @@ -676,10 +675,10 @@ static int __init grlib_apbuart_init(void) return ret; } - ret = of_register_platform_driver(&grlib_apbuart_of_driver); + ret = platform_driver_register(&grlib_apbuart_of_driver); if (ret) { printk(KERN_ERR - "%s: of_register_platform_driver failed (%i)\n", + "%s: platform_driver_register failed (%i)\n", __FILE__, ret); uart_unregister_driver(&grlib_apbuart_driver); return ret; @@ -697,7 +696,7 @@ static void __exit grlib_apbuart_exit(void) &grlib_apbuart_ports[i]); uart_unregister_driver(&grlib_apbuart_driver); - of_unregister_platform_driver(&grlib_apbuart_of_driver); + platform_driver_unregister(&grlib_apbuart_of_driver); } module_init(grlib_apbuart_init); diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index 8692ff98fc07..a9a6a5fd169e 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -1359,8 +1359,7 @@ static struct uart_driver cpm_reg = { static int probe_index; -static int __devinit cpm_uart_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit cpm_uart_probe(struct platform_device *ofdev) { int index = probe_index++; struct uart_cpm_port *pinfo = &cpm_uart_ports[index]; @@ -1405,7 +1404,7 @@ static struct of_device_id cpm_uart_match[] = { {} }; -static struct of_platform_driver cpm_uart_driver = { +static struct platform_driver cpm_uart_driver = { .driver = { .name = "cpm_uart", .owner = THIS_MODULE, @@ -1421,7 +1420,7 @@ static int __init cpm_uart_init(void) if (ret) return ret; - ret = of_register_platform_driver(&cpm_uart_driver); + ret = platform_driver_register(&cpm_uart_driver); if (ret) uart_unregister_driver(&cpm_reg); @@ -1430,7 +1429,7 @@ static int __init cpm_uart_init(void) static void __exit cpm_uart_exit(void) { - of_unregister_platform_driver(&cpm_uart_driver); + platform_driver_unregister(&cpm_uart_driver); uart_unregister_driver(&cpm_reg); } diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 126ec7f568ec..a0bcd8a3758d 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -1302,8 +1302,7 @@ static struct of_device_id mpc52xx_uart_of_match[] = { {}, }; -static int __devinit -mpc52xx_uart_of_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit mpc52xx_uart_of_probe(struct platform_device *op) { int idx = -1; unsigned int uartclk; @@ -1311,8 +1310,6 @@ mpc52xx_uart_of_probe(struct platform_device *op, const struct of_device_id *mat struct resource res; int ret; - dev_dbg(&op->dev, "mpc52xx_uart_probe(op=%p, match=%p)\n", op, match); - /* Check validity & presence */ for (idx = 0; idx < MPC52xx_PSC_MAXNUM; idx++) if (mpc52xx_uart_nodes[idx] == op->dev.of_node) @@ -1453,7 +1450,7 @@ mpc52xx_uart_of_enumerate(void) MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match); -static struct of_platform_driver mpc52xx_uart_of_driver = { +static struct platform_driver mpc52xx_uart_of_driver = { .probe = mpc52xx_uart_of_probe, .remove = mpc52xx_uart_of_remove, #ifdef CONFIG_PM @@ -1497,9 +1494,9 @@ mpc52xx_uart_init(void) return ret; } - ret = of_register_platform_driver(&mpc52xx_uart_of_driver); + ret = platform_driver_register(&mpc52xx_uart_of_driver); if (ret) { - printk(KERN_ERR "%s: of_register_platform_driver failed (%i)\n", + printk(KERN_ERR "%s: platform_driver_register failed (%i)\n", __FILE__, ret); uart_unregister_driver(&mpc52xx_uart_driver); return ret; @@ -1514,7 +1511,7 @@ mpc52xx_uart_exit(void) if (psc_ops->fifoc_uninit) psc_ops->fifoc_uninit(); - of_unregister_platform_driver(&mpc52xx_uart_of_driver); + platform_driver_unregister(&mpc52xx_uart_of_driver); uart_unregister_driver(&mpc52xx_uart_driver); } diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 5c7abe4c94dd..1a43197138cf 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -80,14 +80,16 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, /* * Try to register a serial port */ -static int __devinit of_platform_serial_probe(struct platform_device *ofdev, - const struct of_device_id *id) +static int __devinit of_platform_serial_probe(struct platform_device *ofdev) { struct of_serial_info *info; struct uart_port port; int port_type; int ret; + if (!ofdev->dev.of_match) + return -EINVAL; + if (of_find_property(ofdev->dev.of_node, "used-by-rtas", NULL)) return -EBUSY; @@ -95,7 +97,7 @@ static int __devinit of_platform_serial_probe(struct platform_device *ofdev, if (info == NULL) return -ENOMEM; - port_type = (unsigned long)id->data; + port_type = (unsigned long)ofdev->dev.of_match->data; ret = of_platform_serial_setup(ofdev, port_type, &port); if (ret) goto out; @@ -174,7 +176,7 @@ static struct of_device_id __devinitdata of_platform_serial_table[] = { { /* end of list */ }, }; -static struct of_platform_driver of_platform_serial_driver = { +static struct platform_driver of_platform_serial_driver = { .driver = { .name = "of_serial", .owner = THIS_MODULE, @@ -186,13 +188,13 @@ static struct of_platform_driver of_platform_serial_driver = { static int __init of_platform_serial_init(void) { - return of_register_platform_driver(&of_platform_serial_driver); + return platform_driver_register(&of_platform_serial_driver); } module_init(of_platform_serial_init); static void __exit of_platform_serial_exit(void) { - return of_unregister_platform_driver(&of_platform_serial_driver); + return platform_driver_unregister(&of_platform_serial_driver); }; module_exit(of_platform_serial_exit); diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index c9014868297d..c0b7246d7339 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c @@ -519,7 +519,7 @@ static struct console sunhv_console = { .data = &sunhv_reg, }; -static int __devinit hv_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit hv_probe(struct platform_device *op) { struct uart_port *port; unsigned long minor; @@ -629,7 +629,7 @@ static const struct of_device_id hv_match[] = { }; MODULE_DEVICE_TABLE(of, hv_match); -static struct of_platform_driver hv_driver = { +static struct platform_driver hv_driver = { .driver = { .name = "hv", .owner = THIS_MODULE, @@ -644,12 +644,12 @@ static int __init sunhv_init(void) if (tlb_type != hypervisor) return -ENODEV; - return of_register_platform_driver(&hv_driver); + return platform_driver_register(&hv_driver); } static void __exit sunhv_exit(void) { - of_unregister_platform_driver(&hv_driver); + platform_driver_unregister(&hv_driver); } module_init(sunhv_init); diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index 5b246b18f42f..b5fa2a57b9da 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c @@ -1006,7 +1006,7 @@ static int __devinit sunsab_init_one(struct uart_sunsab_port *up, return 0; } -static int __devinit sab_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit sab_probe(struct platform_device *op) { static int inst; struct uart_sunsab_port *up; @@ -1092,7 +1092,7 @@ static const struct of_device_id sab_match[] = { }; MODULE_DEVICE_TABLE(of, sab_match); -static struct of_platform_driver sab_driver = { +static struct platform_driver sab_driver = { .driver = { .name = "sab", .owner = THIS_MODULE, @@ -1130,12 +1130,12 @@ static int __init sunsab_init(void) } } - return of_register_platform_driver(&sab_driver); + return platform_driver_register(&sab_driver); } static void __exit sunsab_exit(void) { - of_unregister_platform_driver(&sab_driver); + platform_driver_unregister(&sab_driver); if (sunsab_reg.nr) { sunserial_unregister_minors(&sunsab_reg, sunsab_reg.nr); } diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index 551ebfe3ccbb..92aa54550e84 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c @@ -1406,7 +1406,7 @@ static enum su_type __devinit su_get_type(struct device_node *dp) return SU_PORT_PORT; } -static int __devinit su_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit su_probe(struct platform_device *op) { static int inst; struct device_node *dp = op->dev.of_node; @@ -1543,7 +1543,7 @@ static const struct of_device_id su_match[] = { }; MODULE_DEVICE_TABLE(of, su_match); -static struct of_platform_driver su_driver = { +static struct platform_driver su_driver = { .driver = { .name = "su", .owner = THIS_MODULE, @@ -1586,7 +1586,7 @@ static int __init sunsu_init(void) return err; } - err = of_register_platform_driver(&su_driver); + err = platform_driver_register(&su_driver); if (err && num_uart) sunserial_unregister_minors(&sunsu_reg, num_uart); diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index c1967ac1c07f..99ff9abf57ce 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c @@ -1399,7 +1399,7 @@ static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up) static int zilog_irq = -1; -static int __devinit zs_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit zs_probe(struct platform_device *op) { static int kbm_inst, uart_inst; int inst; @@ -1540,7 +1540,7 @@ static const struct of_device_id zs_match[] = { }; MODULE_DEVICE_TABLE(of, zs_match); -static struct of_platform_driver zs_driver = { +static struct platform_driver zs_driver = { .driver = { .name = "zs", .owner = THIS_MODULE, @@ -1576,7 +1576,7 @@ static int __init sunzilog_init(void) goto out_free_tables; } - err = of_register_platform_driver(&zs_driver); + err = platform_driver_register(&zs_driver); if (err) goto out_unregister_uart; @@ -1604,7 +1604,7 @@ out: return err; out_unregister_driver: - of_unregister_platform_driver(&zs_driver); + platform_driver_unregister(&zs_driver); out_unregister_uart: if (num_sunzilog) { @@ -1619,7 +1619,7 @@ out_free_tables: static void __exit sunzilog_exit(void) { - of_unregister_platform_driver(&zs_driver); + platform_driver_unregister(&zs_driver); if (zilog_irq != -1) { struct uart_sunzilog_port *up = sunzilog_irq_chain; diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index 3f4848e2174a..ff51dae1df0c 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -1194,8 +1194,7 @@ static void uart_firmware_cont(const struct firmware *fw, void *context) release_firmware(fw); } -static int ucc_uart_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int ucc_uart_probe(struct platform_device *ofdev) { struct device_node *np = ofdev->dev.of_node; const unsigned int *iprop; /* Integer OF properties */ @@ -1485,7 +1484,7 @@ static struct of_device_id ucc_uart_match[] = { }; MODULE_DEVICE_TABLE(of, ucc_uart_match); -static struct of_platform_driver ucc_uart_of_driver = { +static struct platform_driver ucc_uart_of_driver = { .driver = { .name = "ucc_uart", .owner = THIS_MODULE, @@ -1510,7 +1509,7 @@ static int __init ucc_uart_init(void) return ret; } - ret = of_register_platform_driver(&ucc_uart_of_driver); + ret = platform_driver_register(&ucc_uart_of_driver); if (ret) printk(KERN_ERR "ucc-uart: could not register platform driver\n"); @@ -1523,7 +1522,7 @@ static void __exit ucc_uart_exit(void) printk(KERN_INFO "Freescale QUICC Engine UART device driver unloading\n"); - of_unregister_platform_driver(&ucc_uart_of_driver); + platform_driver_unregister(&ucc_uart_of_driver); uart_unregister_driver(&ucc_uart_driver); } -- cgit v1.2.3 From 1c48a5c93da63132b92c4bbcd18e690c51539df6 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 17 Feb 2011 02:43:24 -0700 Subject: dt: Eliminate of_platform_{,un}register_driver Final step to eliminate of_platform_bus_type. They're all just platform drivers now. v2: fix type in pasemi_nand.c (thanks to Stephen Rothwell) Signed-off-by: Grant Likely --- drivers/ata/pata_mpc52xx.c | 8 ++++---- drivers/ata/pata_of_platform.c | 9 ++++----- drivers/ata/sata_dwc_460ex.c | 9 ++++----- drivers/ata/sata_fsl.c | 9 ++++----- drivers/atm/fore200e.c | 17 ++++++++++------- drivers/block/xsysace.c | 11 ++++------- drivers/crypto/talitos.c | 9 ++++----- drivers/i2c/busses/i2c-cpm.c | 9 ++++----- drivers/i2c/busses/i2c-ibm_iic.c | 9 ++++----- drivers/i2c/busses/i2c-mpc.c | 22 +++++++++------------- drivers/input/serio/xilinx_ps2.c | 9 ++++----- drivers/media/video/fsl-viu.c | 9 ++++----- drivers/mmc/host/sdhci-of-core.c | 15 +++++++++------ drivers/mtd/maps/physmap_of.c | 15 +++++++++------ drivers/mtd/maps/sun_uflash.c | 8 ++++---- drivers/mtd/nand/fsl_upm.c | 9 ++++----- drivers/mtd/nand/mpc5121_nfc.c | 9 ++++----- drivers/mtd/nand/ndfc.c | 9 ++++----- drivers/mtd/nand/pasemi_nand.c | 9 ++++----- drivers/mtd/nand/socrates_nand.c | 9 ++++----- drivers/pcmcia/electra_cf.c | 9 ++++----- drivers/pcmcia/m8xx_pcmcia.c | 9 ++++----- drivers/rtc/rtc-mpc5121.c | 9 ++++----- drivers/watchdog/cpwd.c | 9 ++++----- drivers/watchdog/gef_wdt.c | 9 ++++----- drivers/watchdog/mpc8xxx_wdt.c | 15 +++++++++------ drivers/watchdog/riowd.c | 9 ++++----- 27 files changed, 134 insertions(+), 148 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index d7d8026cde99..2fcac511d39c 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -680,7 +680,7 @@ mpc52xx_ata_remove_one(struct device *dev) /* ======================================================================== */ static int __devinit -mpc52xx_ata_probe(struct platform_device *op, const struct of_device_id *match) +mpc52xx_ata_probe(struct platform_device *op) { unsigned int ipb_freq; struct resource res_mem; @@ -883,7 +883,7 @@ static struct of_device_id mpc52xx_ata_of_match[] = { }; -static struct of_platform_driver mpc52xx_ata_of_platform_driver = { +static struct platform_driver mpc52xx_ata_of_platform_driver = { .probe = mpc52xx_ata_probe, .remove = mpc52xx_ata_remove, #ifdef CONFIG_PM @@ -906,13 +906,13 @@ static int __init mpc52xx_ata_init(void) { printk(KERN_INFO "ata: MPC52xx IDE/ATA libata driver\n"); - return of_register_platform_driver(&mpc52xx_ata_of_platform_driver); + return platform_driver_register(&mpc52xx_ata_of_platform_driver); } static void __exit mpc52xx_ata_exit(void) { - of_unregister_platform_driver(&mpc52xx_ata_of_platform_driver); + platform_driver_unregister(&mpc52xx_ata_of_platform_driver); } module_init(mpc52xx_ata_init); diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c index 480e043ce6b8..f3054009bd25 100644 --- a/drivers/ata/pata_of_platform.c +++ b/drivers/ata/pata_of_platform.c @@ -14,8 +14,7 @@ #include #include -static int __devinit pata_of_platform_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit pata_of_platform_probe(struct platform_device *ofdev) { int ret; struct device_node *dn = ofdev->dev.of_node; @@ -90,7 +89,7 @@ static struct of_device_id pata_of_platform_match[] = { }; MODULE_DEVICE_TABLE(of, pata_of_platform_match); -static struct of_platform_driver pata_of_platform_driver = { +static struct platform_driver pata_of_platform_driver = { .driver = { .name = "pata_of_platform", .owner = THIS_MODULE, @@ -102,13 +101,13 @@ static struct of_platform_driver pata_of_platform_driver = { static int __init pata_of_platform_init(void) { - return of_register_platform_driver(&pata_of_platform_driver); + return platform_driver_register(&pata_of_platform_driver); } module_init(pata_of_platform_init); static void __exit pata_of_platform_exit(void) { - of_unregister_platform_driver(&pata_of_platform_driver); + platform_driver_unregister(&pata_of_platform_driver); } module_exit(pata_of_platform_exit); diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index 6cf57c5c2b5f..685a3a4b4d82 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c @@ -1588,8 +1588,7 @@ static const struct ata_port_info sata_dwc_port_info[] = { }, }; -static int sata_dwc_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int sata_dwc_probe(struct platform_device *ofdev) { struct sata_dwc_device *hsdev; u32 idr, versionr; @@ -1727,7 +1726,7 @@ static const struct of_device_id sata_dwc_match[] = { }; MODULE_DEVICE_TABLE(of, sata_dwc_match); -static struct of_platform_driver sata_dwc_driver = { +static struct platform_driver sata_dwc_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, @@ -1739,12 +1738,12 @@ static struct of_platform_driver sata_dwc_driver = { static int __init sata_dwc_init(void) { - return of_register_platform_driver(&sata_dwc_driver); + return platform_driver_register(&sata_dwc_driver); } static void __exit sata_dwc_exit(void) { - of_unregister_platform_driver(&sata_dwc_driver); + platform_driver_unregister(&sata_dwc_driver); } module_init(sata_dwc_init); diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index b0214d00d50b..b843e8e9605e 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -1293,8 +1293,7 @@ static const struct ata_port_info sata_fsl_port_info[] = { }, }; -static int sata_fsl_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int sata_fsl_probe(struct platform_device *ofdev) { int retval = -ENXIO; void __iomem *hcr_base = NULL; @@ -1423,7 +1422,7 @@ static struct of_device_id fsl_sata_match[] = { MODULE_DEVICE_TABLE(of, fsl_sata_match); -static struct of_platform_driver fsl_sata_driver = { +static struct platform_driver fsl_sata_driver = { .driver = { .name = "fsl-sata", .owner = THIS_MODULE, @@ -1439,13 +1438,13 @@ static struct of_platform_driver fsl_sata_driver = { static int __init sata_fsl_init(void) { - of_register_platform_driver(&fsl_sata_driver); + platform_driver_register(&fsl_sata_driver); return 0; } static void __exit sata_fsl_exit(void) { - of_unregister_platform_driver(&fsl_sata_driver); + platform_driver_unregister(&fsl_sata_driver); } MODULE_LICENSE("GPL"); diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index 44f778507770..bdd2719f3f68 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -2643,14 +2643,17 @@ fore200e_init(struct fore200e* fore200e, struct device *parent) } #ifdef CONFIG_SBUS -static int __devinit fore200e_sba_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit fore200e_sba_probe(struct platform_device *op) { - const struct fore200e_bus *bus = match->data; + const struct fore200e_bus *bus; struct fore200e *fore200e; static int index = 0; int err; + if (!op->dev.of_match) + return -EINVAL; + bus = op->dev.of_match->data; + fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL); if (!fore200e) return -ENOMEM; @@ -2694,7 +2697,7 @@ static const struct of_device_id fore200e_sba_match[] = { }; MODULE_DEVICE_TABLE(of, fore200e_sba_match); -static struct of_platform_driver fore200e_sba_driver = { +static struct platform_driver fore200e_sba_driver = { .driver = { .name = "fore_200e", .owner = THIS_MODULE, @@ -2795,7 +2798,7 @@ static int __init fore200e_module_init(void) printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n"); #ifdef CONFIG_SBUS - err = of_register_platform_driver(&fore200e_sba_driver); + err = platform_driver_register(&fore200e_sba_driver); if (err) return err; #endif @@ -2806,7 +2809,7 @@ static int __init fore200e_module_init(void) #ifdef CONFIG_SBUS if (err) - of_unregister_platform_driver(&fore200e_sba_driver); + platform_driver_unregister(&fore200e_sba_driver); #endif return err; @@ -2818,7 +2821,7 @@ static void __exit fore200e_module_cleanup(void) pci_unregister_driver(&fore200e_pca_driver); #endif #ifdef CONFIG_SBUS - of_unregister_platform_driver(&fore200e_sba_driver); + platform_driver_unregister(&fore200e_sba_driver); #endif } diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 829161edae53..2c590a796aa1 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -1195,16 +1195,13 @@ static struct platform_driver ace_platform_driver = { */ #if defined(CONFIG_OF) -static int __devinit -ace_of_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit ace_of_probe(struct platform_device *op) { struct resource res; resource_size_t physaddr; const u32 *id; int irq, bus_width, rc; - dev_dbg(&op->dev, "ace_of_probe(%p, %p)\n", op, match); - /* device id */ id = of_get_property(op->dev.of_node, "port-number", NULL); @@ -1245,7 +1242,7 @@ static const struct of_device_id ace_of_match[] __devinitconst = { }; MODULE_DEVICE_TABLE(of, ace_of_match); -static struct of_platform_driver ace_of_driver = { +static struct platform_driver ace_of_driver = { .probe = ace_of_probe, .remove = __devexit_p(ace_of_remove), .driver = { @@ -1259,12 +1256,12 @@ static struct of_platform_driver ace_of_driver = { static inline int __init ace_of_register(void) { pr_debug("xsysace: registering OF binding\n"); - return of_register_platform_driver(&ace_of_driver); + return platform_driver_register(&ace_of_driver); } static inline void __exit ace_of_unregister(void) { - of_unregister_platform_driver(&ace_of_driver); + platform_driver_unregister(&ace_of_driver); } #else /* CONFIG_OF */ /* CONFIG_OF not enabled; do nothing helpers */ diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index b879c3f5d7c0..854e2632f9a6 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -2402,8 +2402,7 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev, return t_alg; } -static int talitos_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int talitos_probe(struct platform_device *ofdev) { struct device *dev = &ofdev->dev; struct device_node *np = ofdev->dev.of_node; @@ -2580,7 +2579,7 @@ static const struct of_device_id talitos_match[] = { }; MODULE_DEVICE_TABLE(of, talitos_match); -static struct of_platform_driver talitos_driver = { +static struct platform_driver talitos_driver = { .driver = { .name = "talitos", .owner = THIS_MODULE, @@ -2592,13 +2591,13 @@ static struct of_platform_driver talitos_driver = { static int __init talitos_init(void) { - return of_register_platform_driver(&talitos_driver); + return platform_driver_register(&talitos_driver); } module_init(talitos_init); static void __exit talitos_exit(void) { - of_unregister_platform_driver(&talitos_driver); + platform_driver_unregister(&talitos_driver); } module_exit(talitos_exit); diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index f2de3be35df3..3a20961bef1e 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -634,8 +634,7 @@ static void cpm_i2c_shutdown(struct cpm_i2c *cpm) cpm_muram_free(cpm->i2c_addr); } -static int __devinit cpm_i2c_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit cpm_i2c_probe(struct platform_device *ofdev) { int result, len; struct cpm_i2c *cpm; @@ -718,7 +717,7 @@ static const struct of_device_id cpm_i2c_match[] = { MODULE_DEVICE_TABLE(of, cpm_i2c_match); -static struct of_platform_driver cpm_i2c_driver = { +static struct platform_driver cpm_i2c_driver = { .probe = cpm_i2c_probe, .remove = __devexit_p(cpm_i2c_remove), .driver = { @@ -730,12 +729,12 @@ static struct of_platform_driver cpm_i2c_driver = { static int __init cpm_i2c_init(void) { - return of_register_platform_driver(&cpm_i2c_driver); + return platform_driver_register(&cpm_i2c_driver); } static void __exit cpm_i2c_exit(void) { - of_unregister_platform_driver(&cpm_i2c_driver); + platform_driver_unregister(&cpm_i2c_driver); } module_init(cpm_i2c_init); diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 6e3c38240336..e4f88dca99b5 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -691,8 +691,7 @@ static int __devinit iic_request_irq(struct platform_device *ofdev, /* * Register single IIC interface */ -static int __devinit iic_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit iic_probe(struct platform_device *ofdev) { struct device_node *np = ofdev->dev.of_node; struct ibm_iic_private *dev; @@ -806,7 +805,7 @@ static const struct of_device_id ibm_iic_match[] = { {} }; -static struct of_platform_driver ibm_iic_driver = { +static struct platform_driver ibm_iic_driver = { .driver = { .name = "ibm-iic", .owner = THIS_MODULE, @@ -818,12 +817,12 @@ static struct of_platform_driver ibm_iic_driver = { static int __init iic_init(void) { - return of_register_platform_driver(&ibm_iic_driver); + return platform_driver_register(&ibm_iic_driver); } static void __exit iic_exit(void) { - of_unregister_platform_driver(&ibm_iic_driver); + platform_driver_unregister(&ibm_iic_driver); } module_init(iic_init); diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index b74e6dc6886c..75b984c519ac 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -560,8 +560,7 @@ static struct i2c_adapter mpc_ops = { .timeout = HZ, }; -static int __devinit fsl_i2c_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit fsl_i2c_probe(struct platform_device *op) { struct mpc_i2c *i2c; const u32 *prop; @@ -569,6 +568,9 @@ static int __devinit fsl_i2c_probe(struct platform_device *op, int result = 0; int plen; + if (!op->dev.of_match) + return -EINVAL; + i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); if (!i2c) return -ENOMEM; @@ -603,8 +605,8 @@ static int __devinit fsl_i2c_probe(struct platform_device *op, clock = *prop; } - if (match->data) { - struct mpc_i2c_data *data = match->data; + if (op->dev.of_match->data) { + struct mpc_i2c_data *data = op->dev.of_match->data; data->setup(op->dev.of_node, i2c, clock, data->prescaler); } else { /* Backwards compatibility */ @@ -700,7 +702,7 @@ static const struct of_device_id mpc_i2c_of_match[] = { MODULE_DEVICE_TABLE(of, mpc_i2c_of_match); /* Structure for a device driver */ -static struct of_platform_driver mpc_i2c_driver = { +static struct platform_driver mpc_i2c_driver = { .probe = fsl_i2c_probe, .remove = __devexit_p(fsl_i2c_remove), .driver = { @@ -712,18 +714,12 @@ static struct of_platform_driver mpc_i2c_driver = { static int __init fsl_i2c_init(void) { - int rv; - - rv = of_register_platform_driver(&mpc_i2c_driver); - if (rv) - printk(KERN_ERR DRV_NAME - " of_register_platform_driver failed (%i)\n", rv); - return rv; + return platform_driver_register(&mpc_i2c_driver); } static void __exit fsl_i2c_exit(void) { - of_unregister_platform_driver(&mpc_i2c_driver); + platform_driver_unregister(&mpc_i2c_driver); } module_init(fsl_i2c_init); diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index bb14449fb022..7540bafc95cf 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -232,8 +232,7 @@ static void sxps2_close(struct serio *pserio) * It returns 0, if the driver is bound to the PS/2 device, or a negative * value if there is an error. */ -static int __devinit xps2_of_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit xps2_of_probe(struct platform_device *ofdev) { struct resource r_irq; /* Interrupt resources */ struct resource r_mem; /* IO mem resources */ @@ -361,7 +360,7 @@ static const struct of_device_id xps2_of_match[] __devinitconst = { }; MODULE_DEVICE_TABLE(of, xps2_of_match); -static struct of_platform_driver xps2_of_driver = { +static struct platform_driver xps2_of_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, @@ -373,12 +372,12 @@ static struct of_platform_driver xps2_of_driver = { static int __init xps2_init(void) { - return of_register_platform_driver(&xps2_of_driver); + return platform_driver_register(&xps2_of_driver); } static void __exit xps2_cleanup(void) { - of_unregister_platform_driver(&xps2_of_driver); + platform_driver_unregister(&xps2_of_driver); } module_init(xps2_init); diff --git a/drivers/media/video/fsl-viu.c b/drivers/media/video/fsl-viu.c index e4bba88254c7..031af1610154 100644 --- a/drivers/media/video/fsl-viu.c +++ b/drivers/media/video/fsl-viu.c @@ -1445,8 +1445,7 @@ static struct video_device viu_template = { .current_norm = V4L2_STD_NTSC_M, }; -static int __devinit viu_of_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit viu_of_probe(struct platform_device *op) { struct viu_dev *viu_dev; struct video_device *vdev; @@ -1627,7 +1626,7 @@ static struct of_device_id mpc512x_viu_of_match[] = { }; MODULE_DEVICE_TABLE(of, mpc512x_viu_of_match); -static struct of_platform_driver viu_of_platform_driver = { +static struct platform_driver viu_of_platform_driver = { .probe = viu_of_probe, .remove = __devexit_p(viu_of_remove), #ifdef CONFIG_PM @@ -1643,12 +1642,12 @@ static struct of_platform_driver viu_of_platform_driver = { static int __init viu_init(void) { - return of_register_platform_driver(&viu_of_platform_driver); + return platform_driver_register(&viu_of_platform_driver); } static void __exit viu_exit(void) { - of_unregister_platform_driver(&viu_of_platform_driver); + platform_driver_unregister(&viu_of_platform_driver); } module_init(viu_init); diff --git a/drivers/mmc/host/sdhci-of-core.c b/drivers/mmc/host/sdhci-of-core.c index dd84124f4209..f9b611fc773e 100644 --- a/drivers/mmc/host/sdhci-of-core.c +++ b/drivers/mmc/host/sdhci-of-core.c @@ -124,17 +124,20 @@ static bool __devinit sdhci_of_wp_inverted(struct device_node *np) #endif } -static int __devinit sdhci_of_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit sdhci_of_probe(struct platform_device *ofdev) { struct device_node *np = ofdev->dev.of_node; - struct sdhci_of_data *sdhci_of_data = match->data; + struct sdhci_of_data *sdhci_of_data; struct sdhci_host *host; struct sdhci_of_host *of_host; const __be32 *clk; int size; int ret; + if (!ofdev->dev.of_match) + return -EINVAL; + sdhci_of_data = ofdev->dev.of_match->data; + if (!of_device_is_available(np)) return -ENODEV; @@ -217,7 +220,7 @@ static const struct of_device_id sdhci_of_match[] = { }; MODULE_DEVICE_TABLE(of, sdhci_of_match); -static struct of_platform_driver sdhci_of_driver = { +static struct platform_driver sdhci_of_driver = { .driver = { .name = "sdhci-of", .owner = THIS_MODULE, @@ -231,13 +234,13 @@ static struct of_platform_driver sdhci_of_driver = { static int __init sdhci_of_init(void) { - return of_register_platform_driver(&sdhci_of_driver); + return platform_driver_register(&sdhci_of_driver); } module_init(sdhci_of_init); static void __exit sdhci_of_exit(void) { - of_unregister_platform_driver(&sdhci_of_driver); + platform_driver_unregister(&sdhci_of_driver); } module_exit(sdhci_of_exit); diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 8506578e6a35..3db0cb083d31 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -216,8 +216,7 @@ static void __devinit of_free_probes(const char **probes) } #endif -static int __devinit of_flash_probe(struct platform_device *dev, - const struct of_device_id *match) +static int __devinit of_flash_probe(struct platform_device *dev) { #ifdef CONFIG_MTD_PARTITIONS const char **part_probe_types; @@ -225,7 +224,7 @@ static int __devinit of_flash_probe(struct platform_device *dev, struct device_node *dp = dev->dev.of_node; struct resource res; struct of_flash *info; - const char *probe_type = match->data; + const char *probe_type; const __be32 *width; int err; int i; @@ -235,6 +234,10 @@ static int __devinit of_flash_probe(struct platform_device *dev, struct mtd_info **mtd_list = NULL; resource_size_t res_size; + if (!dev->dev.of_match) + return -EINVAL; + probe_type = dev->dev.of_match->data; + reg_tuple_size = (of_n_addr_cells(dp) + of_n_size_cells(dp)) * sizeof(u32); /* @@ -418,7 +421,7 @@ static struct of_device_id of_flash_match[] = { }; MODULE_DEVICE_TABLE(of, of_flash_match); -static struct of_platform_driver of_flash_driver = { +static struct platform_driver of_flash_driver = { .driver = { .name = "of-flash", .owner = THIS_MODULE, @@ -430,12 +433,12 @@ static struct of_platform_driver of_flash_driver = { static int __init of_flash_init(void) { - return of_register_platform_driver(&of_flash_driver); + return platform_driver_register(&of_flash_driver); } static void __exit of_flash_exit(void) { - of_unregister_platform_driver(&of_flash_driver); + platform_driver_unregister(&of_flash_driver); } module_init(of_flash_init); diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index 3582ba1f9b09..3f1cb328a574 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c @@ -108,7 +108,7 @@ int uflash_devinit(struct platform_device *op, struct device_node *dp) return 0; } -static int __devinit uflash_probe(struct platform_device *op, const struct of_device_id *match) +static int __devinit uflash_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; @@ -148,7 +148,7 @@ static const struct of_device_id uflash_match[] = { MODULE_DEVICE_TABLE(of, uflash_match); -static struct of_platform_driver uflash_driver = { +static struct platform_driver uflash_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, @@ -160,12 +160,12 @@ static struct of_platform_driver uflash_driver = { static int __init uflash_init(void) { - return of_register_platform_driver(&uflash_driver); + return platform_driver_register(&uflash_driver); } static void __exit uflash_exit(void) { - of_unregister_platform_driver(&uflash_driver); + platform_driver_unregister(&uflash_driver); } module_init(uflash_init); diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index efdcca94ce55..073ee026a17c 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c @@ -217,8 +217,7 @@ err: return ret; } -static int __devinit fun_probe(struct platform_device *ofdev, - const struct of_device_id *ofid) +static int __devinit fun_probe(struct platform_device *ofdev) { struct fsl_upm_nand *fun; struct resource io_res; @@ -360,7 +359,7 @@ static const struct of_device_id of_fun_match[] = { }; MODULE_DEVICE_TABLE(of, of_fun_match); -static struct of_platform_driver of_fun_driver = { +static struct platform_driver of_fun_driver = { .driver = { .name = "fsl,upm-nand", .owner = THIS_MODULE, @@ -372,13 +371,13 @@ static struct of_platform_driver of_fun_driver = { static int __init fun_module_init(void) { - return of_register_platform_driver(&of_fun_driver); + return platform_driver_register(&of_fun_driver); } module_init(fun_module_init); static void __exit fun_module_exit(void) { - of_unregister_platform_driver(&of_fun_driver); + platform_driver_unregister(&of_fun_driver); } module_exit(fun_module_exit); diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c index 469e649c911c..c2f95437e5e9 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/mpc5121_nfc.c @@ -650,8 +650,7 @@ static void mpc5121_nfc_free(struct device *dev, struct mtd_info *mtd) iounmap(prv->csreg); } -static int __devinit mpc5121_nfc_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit mpc5121_nfc_probe(struct platform_device *op) { struct device_node *rootnode, *dn = op->dev.of_node; struct device *dev = &op->dev; @@ -891,7 +890,7 @@ static struct of_device_id mpc5121_nfc_match[] __devinitdata = { {}, }; -static struct of_platform_driver mpc5121_nfc_driver = { +static struct platform_driver mpc5121_nfc_driver = { .probe = mpc5121_nfc_probe, .remove = __devexit_p(mpc5121_nfc_remove), .driver = { @@ -903,14 +902,14 @@ static struct of_platform_driver mpc5121_nfc_driver = { static int __init mpc5121_nfc_init(void) { - return of_register_platform_driver(&mpc5121_nfc_driver); + return platform_driver_register(&mpc5121_nfc_driver); } module_init(mpc5121_nfc_init); static void __exit mpc5121_nfc_cleanup(void) { - of_unregister_platform_driver(&mpc5121_nfc_driver); + platform_driver_unregister(&mpc5121_nfc_driver); } module_exit(mpc5121_nfc_cleanup); diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index c9ae0a5023b6..bbe6d451290d 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -225,8 +225,7 @@ err: return ret; } -static int __devinit ndfc_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit ndfc_probe(struct platform_device *ofdev) { struct ndfc_controller *ndfc = &ndfc_ctrl; const __be32 *reg; @@ -292,7 +291,7 @@ static const struct of_device_id ndfc_match[] = { }; MODULE_DEVICE_TABLE(of, ndfc_match); -static struct of_platform_driver ndfc_driver = { +static struct platform_driver ndfc_driver = { .driver = { .name = "ndfc", .owner = THIS_MODULE, @@ -304,12 +303,12 @@ static struct of_platform_driver ndfc_driver = { static int __init ndfc_nand_init(void) { - return of_register_platform_driver(&ndfc_driver); + return platform_driver_register(&ndfc_driver); } static void __exit ndfc_nand_exit(void) { - of_unregister_platform_driver(&ndfc_driver); + platform_driver_unregister(&ndfc_driver); } module_init(ndfc_nand_init); diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index bb277a54986f..59efa829ef24 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c @@ -89,8 +89,7 @@ int pasemi_device_ready(struct mtd_info *mtd) return !!(inl(lpcctl) & LBICTRL_LPCCTL_NR); } -static int __devinit pasemi_nand_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit pasemi_nand_probe(struct platform_device *ofdev) { struct pci_dev *pdev; struct device_node *np = ofdev->dev.of_node; @@ -219,7 +218,7 @@ static const struct of_device_id pasemi_nand_match[] = MODULE_DEVICE_TABLE(of, pasemi_nand_match); -static struct of_platform_driver pasemi_nand_driver = +static struct platform_driver pasemi_nand_driver = { .driver = { .name = (char*)driver_name, @@ -232,13 +231,13 @@ static struct of_platform_driver pasemi_nand_driver = static int __init pasemi_nand_init(void) { - return of_register_platform_driver(&pasemi_nand_driver); + return platform_driver_register(&pasemi_nand_driver); } module_init(pasemi_nand_init); static void __exit pasemi_nand_exit(void) { - of_unregister_platform_driver(&pasemi_nand_driver); + platform_driver_unregister(&pasemi_nand_driver); } module_exit(pasemi_nand_exit); diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c index a8e403eebedb..a853548986f0 100644 --- a/drivers/mtd/nand/socrates_nand.c +++ b/drivers/mtd/nand/socrates_nand.c @@ -162,8 +162,7 @@ static const char *part_probes[] = { "cmdlinepart", NULL }; /* * Probe for the NAND device. */ -static int __devinit socrates_nand_probe(struct platform_device *ofdev, - const struct of_device_id *ofid) +static int __devinit socrates_nand_probe(struct platform_device *ofdev) { struct socrates_nand_host *host; struct mtd_info *mtd; @@ -300,7 +299,7 @@ static const struct of_device_id socrates_nand_match[] = MODULE_DEVICE_TABLE(of, socrates_nand_match); -static struct of_platform_driver socrates_nand_driver = { +static struct platform_driver socrates_nand_driver = { .driver = { .name = "socrates_nand", .owner = THIS_MODULE, @@ -312,12 +311,12 @@ static struct of_platform_driver socrates_nand_driver = { static int __init socrates_nand_init(void) { - return of_register_platform_driver(&socrates_nand_driver); + return platform_driver_register(&socrates_nand_driver); } static void __exit socrates_nand_exit(void) { - of_unregister_platform_driver(&socrates_nand_driver); + platform_driver_unregister(&socrates_nand_driver); } module_init(socrates_nand_init); diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index 546d3024b6f0..6defd4a8168e 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c @@ -181,8 +181,7 @@ static struct pccard_operations electra_cf_ops = { .set_mem_map = electra_cf_set_mem_map, }; -static int __devinit electra_cf_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit electra_cf_probe(struct platform_device *ofdev) { struct device *device = &ofdev->dev; struct device_node *np = ofdev->dev.of_node; @@ -356,7 +355,7 @@ static const struct of_device_id electra_cf_match[] = { }; MODULE_DEVICE_TABLE(of, electra_cf_match); -static struct of_platform_driver electra_cf_driver = { +static struct platform_driver electra_cf_driver = { .driver = { .name = (char *)driver_name, .owner = THIS_MODULE, @@ -368,13 +367,13 @@ static struct of_platform_driver electra_cf_driver = { static int __init electra_cf_init(void) { - return of_register_platform_driver(&electra_cf_driver); + return platform_driver_register(&electra_cf_driver); } module_init(electra_cf_init); static void __exit electra_cf_exit(void) { - of_unregister_platform_driver(&electra_cf_driver); + platform_driver_unregister(&electra_cf_driver); } module_exit(electra_cf_exit); diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 0db482771fb5..271a590a5f3c 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c @@ -1148,8 +1148,7 @@ static struct pccard_operations m8xx_services = { .set_mem_map = m8xx_set_mem_map, }; -static int __init m8xx_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __init m8xx_probe(struct platform_device *ofdev) { struct pcmcia_win *w; unsigned int i, m, hwirq; @@ -1295,7 +1294,7 @@ static const struct of_device_id m8xx_pcmcia_match[] = { MODULE_DEVICE_TABLE(of, m8xx_pcmcia_match); -static struct of_platform_driver m8xx_pcmcia_driver = { +static struct platform_driver m8xx_pcmcia_driver = { .driver = { .name = driver_name, .owner = THIS_MODULE, @@ -1307,12 +1306,12 @@ static struct of_platform_driver m8xx_pcmcia_driver = { static int __init m8xx_init(void) { - return of_register_platform_driver(&m8xx_pcmcia_driver); + return platform_driver_register(&m8xx_pcmcia_driver); } static void __exit m8xx_exit(void) { - of_unregister_platform_driver(&m8xx_pcmcia_driver); + platform_driver_unregister(&m8xx_pcmcia_driver); } module_init(m8xx_init); diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index dfcdf0901d21..2b952c654b14 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c @@ -268,8 +268,7 @@ static const struct rtc_class_ops mpc5121_rtc_ops = { .update_irq_enable = mpc5121_rtc_update_irq_enable, }; -static int __devinit mpc5121_rtc_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit mpc5121_rtc_probe(struct platform_device *op) { struct mpc5121_rtc_data *rtc; int err = 0; @@ -364,7 +363,7 @@ static struct of_device_id mpc5121_rtc_match[] __devinitdata = { {}, }; -static struct of_platform_driver mpc5121_rtc_driver = { +static struct platform_driver mpc5121_rtc_driver = { .driver = { .name = "mpc5121-rtc", .owner = THIS_MODULE, @@ -376,13 +375,13 @@ static struct of_platform_driver mpc5121_rtc_driver = { static int __init mpc5121_rtc_init(void) { - return of_register_platform_driver(&mpc5121_rtc_driver); + return platform_driver_register(&mpc5121_rtc_driver); } module_init(mpc5121_rtc_init); static void __exit mpc5121_rtc_exit(void) { - of_unregister_platform_driver(&mpc5121_rtc_driver); + platform_driver_unregister(&mpc5121_rtc_driver); } module_exit(mpc5121_rtc_exit); diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index eca855a55c0d..45db1d570df1 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c @@ -528,8 +528,7 @@ static const struct file_operations cpwd_fops = { .llseek = no_llseek, }; -static int __devinit cpwd_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit cpwd_probe(struct platform_device *op) { struct device_node *options; const char *str_prop; @@ -678,7 +677,7 @@ static const struct of_device_id cpwd_match[] = { }; MODULE_DEVICE_TABLE(of, cpwd_match); -static struct of_platform_driver cpwd_driver = { +static struct platform_driver cpwd_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, @@ -690,12 +689,12 @@ static struct of_platform_driver cpwd_driver = { static int __init cpwd_init(void) { - return of_register_platform_driver(&cpwd_driver); + return platform_driver_register(&cpwd_driver); } static void __exit cpwd_exit(void) { - of_unregister_platform_driver(&cpwd_driver); + platform_driver_unregister(&cpwd_driver); } module_init(cpwd_init); diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c index f6bd6f10fcec..29a7cd4b90c8 100644 --- a/drivers/watchdog/gef_wdt.c +++ b/drivers/watchdog/gef_wdt.c @@ -261,8 +261,7 @@ static struct miscdevice gef_wdt_miscdev = { }; -static int __devinit gef_wdt_probe(struct platform_device *dev, - const struct of_device_id *match) +static int __devinit gef_wdt_probe(struct platform_device *dev) { int timeout = 10; u32 freq; @@ -303,7 +302,7 @@ static const struct of_device_id gef_wdt_ids[] = { {}, }; -static struct of_platform_driver gef_wdt_driver = { +static struct platform_driver gef_wdt_driver = { .driver = { .name = "gef_wdt", .owner = THIS_MODULE, @@ -315,12 +314,12 @@ static struct of_platform_driver gef_wdt_driver = { static int __init gef_wdt_init(void) { printk(KERN_INFO "GE watchdog driver\n"); - return of_register_platform_driver(&gef_wdt_driver); + return platform_driver_register(&gef_wdt_driver); } static void __exit gef_wdt_exit(void) { - of_unregister_platform_driver(&gef_wdt_driver); + platform_driver_unregister(&gef_wdt_driver); } module_init(gef_wdt_init); diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c index 8fa213cdb499..ea438ad53055 100644 --- a/drivers/watchdog/mpc8xxx_wdt.c +++ b/drivers/watchdog/mpc8xxx_wdt.c @@ -185,15 +185,18 @@ static struct miscdevice mpc8xxx_wdt_miscdev = { .fops = &mpc8xxx_wdt_fops, }; -static int __devinit mpc8xxx_wdt_probe(struct platform_device *ofdev, - const struct of_device_id *match) +static int __devinit mpc8xxx_wdt_probe(struct platform_device *ofdev) { int ret; struct device_node *np = ofdev->dev.of_node; - struct mpc8xxx_wdt_type *wdt_type = match->data; + struct mpc8xxx_wdt_type *wdt_type; u32 freq = fsl_get_sys_freq(); bool enabled; + if (!ofdev->dev.of_match) + return -EINVAL; + wdt_type = match->data; + if (!freq || freq == -1) return -EINVAL; @@ -272,7 +275,7 @@ static const struct of_device_id mpc8xxx_wdt_match[] = { }; MODULE_DEVICE_TABLE(of, mpc8xxx_wdt_match); -static struct of_platform_driver mpc8xxx_wdt_driver = { +static struct platform_driver mpc8xxx_wdt_driver = { .probe = mpc8xxx_wdt_probe, .remove = __devexit_p(mpc8xxx_wdt_remove), .driver = { @@ -308,13 +311,13 @@ module_init(mpc8xxx_wdt_init_late); static int __init mpc8xxx_wdt_init(void) { - return of_register_platform_driver(&mpc8xxx_wdt_driver); + return platform_driver_register(&mpc8xxx_wdt_driver); } arch_initcall(mpc8xxx_wdt_init); static void __exit mpc8xxx_wdt_exit(void) { - of_unregister_platform_driver(&mpc8xxx_wdt_driver); + platform_driver_unregister(&mpc8xxx_wdt_driver); } module_exit(mpc8xxx_wdt_exit); diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c index 3faee1ae64bd..109b533896b7 100644 --- a/drivers/watchdog/riowd.c +++ b/drivers/watchdog/riowd.c @@ -172,8 +172,7 @@ static struct miscdevice riowd_miscdev = { .fops = &riowd_fops }; -static int __devinit riowd_probe(struct platform_device *op, - const struct of_device_id *match) +static int __devinit riowd_probe(struct platform_device *op) { struct riowd *p; int err = -EINVAL; @@ -238,7 +237,7 @@ static const struct of_device_id riowd_match[] = { }; MODULE_DEVICE_TABLE(of, riowd_match); -static struct of_platform_driver riowd_driver = { +static struct platform_driver riowd_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, @@ -250,12 +249,12 @@ static struct of_platform_driver riowd_driver = { static int __init riowd_init(void) { - return of_register_platform_driver(&riowd_driver); + return platform_driver_register(&riowd_driver); } static void __exit riowd_exit(void) { - of_unregister_platform_driver(&riowd_driver); + platform_driver_unregister(&riowd_driver); } module_init(riowd_init); -- cgit v1.2.3 From eaaa3a7c4da2bdc48e536bb750860253150cb931 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 28 Feb 2011 12:29:34 -0800 Subject: sis900: use pci_dev->revision This driver uses PCI_CLASS_REVISION instead of PCI_REVISION_ID, so it wasn't converted by commit 44c10138fd4bbc4b6d6bff0873c24902f2a9da65 (PCI: Change all drivers to use pci_device->revision). Signed-off-by: Sergei Shtylyov Signed-off-by: David S. Miller --- drivers/net/sis900.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 640e368ebeee..84d4167eee9a 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -495,7 +495,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev, sis_priv->mii_info.reg_num_mask = 0x1f; /* Get Mac address according to the chip revision */ - pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &(sis_priv->chipset_rev)); + sis_priv->chipset_rev = pci_dev->revision; if(netif_msg_probe(sis_priv)) printk(KERN_DEBUG "%s: detected revision %2.2x, " "trying to get MAC address...\n", @@ -532,7 +532,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev, /* save our host bridge revision */ dev = pci_get_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630, NULL); if (dev) { - pci_read_config_byte(dev, PCI_CLASS_REVISION, &sis_priv->host_bridge_rev); + sis_priv->host_bridge_rev = dev->revision; pci_dev_put(dev); } -- cgit v1.2.3 From 9eb0e6f26e48ef22cc56a2b81b1572ace999f70f Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 22 Feb 2011 23:28:46 +0000 Subject: net/fec: fix unterminated platform_device_id table The platform_device_id table is supposed to be zero-terminated. Signed-off-by: Axel Lin Signed-off-by: David S. Miller --- drivers/net/fec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 2a71373719ae..cd0282d5d40f 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -74,7 +74,8 @@ static struct platform_device_id fec_devtype[] = { }, { .name = "imx28-fec", .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME, - } + }, + { } }; static unsigned char macaddr[ETH_ALEN]; -- cgit v1.2.3 From f5a45325284ec10a907b96052ebf2168e7166b5c Mon Sep 17 00:00:00 2001 From: Rémi Denis-Courmont Date: Wed, 23 Feb 2011 02:51:33 +0000 Subject: f_phonet: avoid pskb_pull(), fix OOPS with CONFIG_HIGHMEM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is similar to what we already do in cdc-phonet.c in the same situation. pskb_pull() refuses to work with HIGHMEM, even if it is known that the socket buffer is entirely in "low" memory. Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- drivers/usb/gadget/f_phonet.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index 3c6e1a058745..5e1495097ec3 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/f_phonet.c @@ -346,14 +346,19 @@ static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req) if (unlikely(!skb)) break; - skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, 0, - req->actual); - page = NULL; - if (req->actual < req->length) { /* Last fragment */ + if (skb->len == 0) { /* First fragment */ skb->protocol = htons(ETH_P_PHONET); skb_reset_mac_header(skb); - pskb_pull(skb, 1); + /* Can't use pskb_pull() on page in IRQ */ + memcpy(skb_put(skb, 1), page_address(page), 1); + } + + skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, + skb->len == 0, req->actual); + page = NULL; + + if (req->actual < req->length) { /* Last fragment */ skb->dev = dev; dev->stats.rx_packets++; dev->stats.rx_bytes += skb->len; -- cgit v1.2.3 From 4ec952b8ab636e87465ed78a1ca5fa5efe0d5e0f Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 23 Feb 2011 07:40:33 +0000 Subject: bonding: fix sparse warning Fix use of zero where NULL expected. And wrap long line. Signed-off-by: Stephen Hemminger Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bonding.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index a401b8df84f0..ff4e26980220 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -269,7 +269,8 @@ struct bonding { * * Caller must hold bond lock for read */ -static inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct net_device *slave_dev) +static inline struct slave *bond_get_slave_by_dev(struct bonding *bond, + struct net_device *slave_dev) { struct slave *slave = NULL; int i; @@ -280,7 +281,7 @@ static inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct n } } - return 0; + return NULL; } static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) -- cgit v1.2.3 From 6f2e154b68b9321d958391bc0b1ffc2b90d57d71 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 23 Feb 2011 07:54:27 +0000 Subject: qla3xxx: add missing __iomem annotation Add necessary annotations about pointer to io memory space that is checked by sparse. Signed-off-by: Stephen Hemminger Acked-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qla3xxx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index 1a3584edd79c..2d21c60085bc 100644 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -379,7 +379,7 @@ static void fm93c56a_select(struct ql3_adapter *qdev) { struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - u32 *spir = &port_regs->CommonRegs.serialPortInterfaceReg; + __iomem u32 *spir = &port_regs->CommonRegs.serialPortInterfaceReg; qdev->eeprom_cmd_data = AUBURN_EEPROM_CS_1; ql_write_nvram_reg(qdev, spir, ISP_NVRAM_MASK | qdev->eeprom_cmd_data); @@ -398,7 +398,7 @@ static void fm93c56a_cmd(struct ql3_adapter *qdev, u32 cmd, u32 eepromAddr) u32 previousBit; struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - u32 *spir = &port_regs->CommonRegs.serialPortInterfaceReg; + __iomem u32 *spir = &port_regs->CommonRegs.serialPortInterfaceReg; /* Clock in a zero, then do the start bit */ ql_write_nvram_reg(qdev, spir, @@ -467,7 +467,7 @@ static void fm93c56a_deselect(struct ql3_adapter *qdev) { struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - u32 *spir = &port_regs->CommonRegs.serialPortInterfaceReg; + __iomem u32 *spir = &port_regs->CommonRegs.serialPortInterfaceReg; qdev->eeprom_cmd_data = AUBURN_EEPROM_CS_0; ql_write_nvram_reg(qdev, spir, ISP_NVRAM_MASK | qdev->eeprom_cmd_data); @@ -483,7 +483,7 @@ static void fm93c56a_datain(struct ql3_adapter *qdev, unsigned short *value) u32 dataBit; struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - u32 *spir = &port_regs->CommonRegs.serialPortInterfaceReg; + __iomem u32 *spir = &port_regs->CommonRegs.serialPortInterfaceReg; /* Read the data bits */ /* The first bit is a dummy. Clock right over it. */ @@ -3011,7 +3011,7 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev) u32 value; struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - u32 *spir = &port_regs->CommonRegs.serialPortInterfaceReg; + __iomem u32 *spir = &port_regs->CommonRegs.serialPortInterfaceReg; struct ql3xxx_host_memory_registers __iomem *hmem_regs = (void __iomem *)port_regs; u32 delay = 10; -- cgit v1.2.3 From 85e6b8c5d8be1e901b5402bfe42ce408912ab83e Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 24 Feb 2011 03:17:12 +0000 Subject: DM9000: Allow randomised ethernet address Allow randomised ethernet address if the device does not have a valid EEPROM or pre-set MAC address. Signed-off-by: Ben Dooks Signed-off-by: Mark Brown Signed-off-by: David S. Miller --- drivers/net/dm9000.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 2d4c4fc1d900..c30935587207 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -1592,10 +1592,15 @@ dm9000_probe(struct platform_device *pdev) ndev->dev_addr[i] = ior(db, i+DM9000_PAR); } - if (!is_valid_ether_addr(ndev->dev_addr)) + if (!is_valid_ether_addr(ndev->dev_addr)) { dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please " "set using ifconfig\n", ndev->name); + random_ether_addr(ndev->dev_addr); + mac_src = "random"; + } + + platform_set_drvdata(pdev, ndev); ret = register_netdev(ndev); -- cgit v1.2.3 From 8da83f8e73a42fa3142843938aa1590b82acb6ec Mon Sep 17 00:00:00 2001 From: Roopa Prabhu Date: Wed, 23 Feb 2011 15:16:01 +0000 Subject: enic: Flush driver cache of registered addr lists during port profile disassociate During a port profile disassociate all address registrations for the interface are blown away from the adapter. This patch resets the driver cache of registered address lists to zero after a port profile disassociate. Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: Christian Benvenuti Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 2 +- drivers/net/enic/enic_main.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index aee5256e522b..e816bbb9fbf9 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "2.1.1.9" +#define DRV_VERSION "2.1.1.10" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 4f1710e31eb4..8b9cad5e9712 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1126,6 +1126,8 @@ static int enic_set_port_profile(struct enic *enic, u8 *mac) if (err) return err; + enic_reset_addr_lists(enic); + switch (enic->pp.request) { case PORT_REQUEST_ASSOCIATE: -- cgit v1.2.3 From faa6fcbbba110c7c4bc299bc90f59d9f7b51ac6e Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Mon, 28 Feb 2011 03:37:20 +0000 Subject: bnx2x: (NPAR mode) Fix FW initialization Fix FW initialization according to max BW stored in percents for NPAR mode. Protect HW from being configured to speed 0. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 17 +++++++++-------- drivers/net/bnx2x/bnx2x_cmn.h | 20 ++++++++++++++++++++ drivers/net/bnx2x/bnx2x_ethtool.c | 13 +++++++------ drivers/net/bnx2x/bnx2x_main.c | 15 ++++++++++++--- 4 files changed, 48 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 710ce5d04c53..a58baf35d229 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -703,19 +703,20 @@ u16 bnx2x_get_mf_speed(struct bnx2x *bp) { u16 line_speed = bp->link_vars.line_speed; if (IS_MF(bp)) { - u16 maxCfg = (bp->mf_config[BP_VN(bp)] & - FUNC_MF_CFG_MAX_BW_MASK) >> - FUNC_MF_CFG_MAX_BW_SHIFT; - /* Calculate the current MAX line speed limit for the DCC - * capable devices + u16 maxCfg = bnx2x_extract_max_cfg(bp, + bp->mf_config[BP_VN(bp)]); + + /* Calculate the current MAX line speed limit for the MF + * devices */ - if (IS_MF_SD(bp)) { + if (IS_MF_SI(bp)) + line_speed = (line_speed * maxCfg) / 100; + else { /* SD mode */ u16 vn_max_rate = maxCfg * 100; if (vn_max_rate < line_speed) line_speed = vn_max_rate; - } else /* IS_MF_SI(bp)) */ - line_speed = (line_speed * maxCfg) / 100; + } } return line_speed; diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 03eb4d68e6bb..326ba44b3ded 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -1044,4 +1044,24 @@ static inline void storm_memset_cmng(struct bnx2x *bp, void bnx2x_acquire_phy_lock(struct bnx2x *bp); void bnx2x_release_phy_lock(struct bnx2x *bp); +/** + * Extracts MAX BW part from MF configuration. + * + * @param bp + * @param mf_cfg + * + * @return u16 + */ +static inline u16 bnx2x_extract_max_cfg(struct bnx2x *bp, u32 mf_cfg) +{ + u16 max_cfg = (mf_cfg & FUNC_MF_CFG_MAX_BW_MASK) >> + FUNC_MF_CFG_MAX_BW_SHIFT; + if (!max_cfg) { + BNX2X_ERR("Illegal configuration detected for Max BW - " + "using 100 instead\n"); + max_cfg = 100; + } + return max_cfg; +} + #endif /* BNX2X_CMN_H */ diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 5b44a8b48509..b3da295c453c 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -238,7 +238,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) speed |= (cmd->speed_hi << 16); if (IS_MF_SI(bp)) { - u32 param = 0; + u32 param = 0, part; u32 line_speed = bp->link_vars.line_speed; /* use 10G if no link detected */ @@ -251,9 +251,11 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) REQ_BC_VER_4_SET_MF_BW); return -EINVAL; } - if (line_speed < speed) { - BNX2X_DEV_INFO("New speed should be less or equal " - "to actual line speed\n"); + part = (speed * 100) / line_speed; + if (line_speed < speed || !part) { + BNX2X_DEV_INFO("Speed setting should be in a range " + "from 1%% to 100%% " + "of actual line speed\n"); return -EINVAL; } /* load old values */ @@ -263,8 +265,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) param &= FUNC_MF_CFG_MIN_BW_MASK; /* set new MAX value */ - param |= (((speed * 100) / line_speed) - << FUNC_MF_CFG_MAX_BW_SHIFT) + param |= (part << FUNC_MF_CFG_MAX_BW_SHIFT) & FUNC_MF_CFG_MAX_BW_MASK; bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, param); diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index d584d32c747d..203e9bf65875 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -1974,13 +1974,22 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn) vn_max_rate = 0; } else { + u32 maxCfg = bnx2x_extract_max_cfg(bp, vn_cfg); + vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >> FUNC_MF_CFG_MIN_BW_SHIFT) * 100; - /* If min rate is zero - set it to 1 */ + /* If fairness is enabled (not all min rates are zeroes) and + if current min rate is zero - set it to 1. + This is a requirement of the algorithm. */ if (bp->vn_weight_sum && (vn_min_rate == 0)) vn_min_rate = DEF_MIN_RATE; - vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >> - FUNC_MF_CFG_MAX_BW_SHIFT) * 100; + + if (IS_MF_SI(bp)) + /* maxCfg in percents of linkspeed */ + vn_max_rate = (bp->link_vars.line_speed * maxCfg) / 100; + else + /* maxCfg is absolute in 100Mb units */ + vn_max_rate = maxCfg * 100; } DP(NETIF_MSG_IFUP, -- cgit v1.2.3 From d4215ef71f4ec21c236a1f255f1808af2cfa6aa0 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Mon, 28 Feb 2011 03:37:13 +0000 Subject: bnx2x: Fix nvram test for single port devices. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_ethtool.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index b3da295c453c..5b0fe7a35ac8 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -1782,9 +1782,7 @@ static int bnx2x_test_nvram(struct bnx2x *bp) { 0x100, 0x350 }, /* manuf_info */ { 0x450, 0xf0 }, /* feature_info */ { 0x640, 0x64 }, /* upgrade_key_info */ - { 0x6a4, 0x64 }, { 0x708, 0x70 }, /* manuf_key_info */ - { 0x778, 0x70 }, { 0, 0 } }; __be32 buf[0x350 / 4]; -- cgit v1.2.3 From 633ac3637a1ff84eb85d5659380a41d96c4fdbae Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Mon, 28 Feb 2011 03:37:12 +0000 Subject: bnx2x: Fix ethtool -t link test for MF (non-pmf) devices. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_ethtool.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 5b0fe7a35ac8..ef2919987a10 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -1932,11 +1932,11 @@ static void bnx2x_self_test(struct net_device *dev, buf[4] = 1; etest->flags |= ETH_TEST_FL_FAILED; } - if (bp->port.pmf) - if (bnx2x_link_test(bp, is_serdes) != 0) { - buf[5] = 1; - etest->flags |= ETH_TEST_FL_FAILED; - } + + if (bnx2x_link_test(bp, is_serdes) != 0) { + buf[5] = 1; + etest->flags |= ETH_TEST_FL_FAILED; + } #ifdef BNX2X_EXTRA_DEBUG bnx2x_panic_dump(bp); -- cgit v1.2.3 From ff80ee029b562c21ca40724dfe9a63e0e0e0ce3d Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Mon, 28 Feb 2011 03:37:11 +0000 Subject: bnx2x: properly configure coefficients for MinBW algorithm (NPAR mode). Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 26 +++++++++++++++----------- drivers/net/bnx2x/bnx2x_main.c | 3 ++- 2 files changed, 17 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 653c62475cb6..368cfcd0a211 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1613,19 +1613,23 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define BNX2X_BTR 4 #define MAX_SPQ_PENDING 8 - -/* CMNG constants - derived from lab experiments, and not from system spec calculations !!! */ -#define DEF_MIN_RATE 100 +/* CMNG constants, as derived from system spec calculations */ +/* default MIN rate in case VNIC min rate is configured to zero - 100Mbps */ +#define DEF_MIN_RATE 100 /* resolution of the rate shaping timer - 100 usec */ -#define RS_PERIODIC_TIMEOUT_USEC 100 -/* resolution of fairness algorithm in usecs - - coefficient for calculating the actual t fair */ -#define T_FAIR_COEF 10000000 +#define RS_PERIODIC_TIMEOUT_USEC 100 /* number of bytes in single QM arbitration cycle - - coefficient for calculating the fairness timer */ -#define QM_ARB_BYTES 40000 -#define FAIR_MEM 2 + * coefficient for calculating the fairness timer */ +#define QM_ARB_BYTES 160000 +/* resolution of Min algorithm 1:100 */ +#define MIN_RES 100 +/* how many bytes above threshold for the minimal credit of Min algorithm*/ +#define MIN_ABOVE_THRESH 32768 +/* Fairness algorithm integration time coefficient - + * for calculating the actual Tfair */ +#define T_FAIR_COEF ((MIN_ABOVE_THRESH + QM_ARB_BYTES) * 8 * MIN_RES) +/* Memory of fairness algorithm . 2 cycles */ +#define FAIR_MEM 2 #define ATTN_NIG_FOR_FUNC (1L << 8) diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 203e9bf65875..032ae184b605 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -2015,7 +2015,8 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn) m_fair_vn.vn_credit_delta = max_t(u32, (vn_min_rate * (T_FAIR_COEF / (8 * bp->vn_weight_sum))), - (bp->cmng.fair_vars.fair_threshold * 2)); + (bp->cmng.fair_vars.fair_threshold + + MIN_ABOVE_THRESH)); DP(NETIF_MSG_IFUP, "m_fair_vn.vn_credit_delta %d\n", m_fair_vn.vn_credit_delta); } -- cgit v1.2.3 From 63135281af8c7fb2b7c84b63f5f974238b7d843e Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Mon, 28 Feb 2011 03:37:10 +0000 Subject: bnx2x: perform statistics "action" before state transition. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c index bda60d590fa8..3445ded6674f 100644 --- a/drivers/net/bnx2x/bnx2x_stats.c +++ b/drivers/net/bnx2x/bnx2x_stats.c @@ -1239,14 +1239,14 @@ void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) if (unlikely(bp->panic)) return; + bnx2x_stats_stm[bp->stats_state][event].action(bp); + /* Protect a state change flow */ spin_lock_bh(&bp->stats_lock); state = bp->stats_state; bp->stats_state = bnx2x_stats_stm[state][event].next_state; spin_unlock_bh(&bp->stats_lock); - bnx2x_stats_stm[state][event].action(bp); - if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", state, event, bp->stats_state); -- cgit v1.2.3 From e4e3c02a1a90b12d1b31e5fd9826ad84866ee526 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Mon, 28 Feb 2011 03:37:10 +0000 Subject: bnx2x: properly calculate lro_mss Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 48 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index a58baf35d229..93798129061b 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -259,10 +259,44 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, #endif } +/* Timestamp option length allowed for TPA aggregation: + * + * nop nop kind length echo val + */ +#define TPA_TSTAMP_OPT_LEN 12 +/** + * Calculate the approximate value of the MSS for this + * aggregation using the first packet of it. + * + * @param bp + * @param parsing_flags Parsing flags from the START CQE + * @param len_on_bd Total length of the first packet for the + * aggregation. + */ +static inline u16 bnx2x_set_lro_mss(struct bnx2x *bp, u16 parsing_flags, + u16 len_on_bd) +{ + /* TPA arrgregation won't have an IP options and TCP options + * other than timestamp. + */ + u16 hdrs_len = ETH_HLEN + sizeof(struct iphdr) + sizeof(struct tcphdr); + + + /* Check if there was a TCP timestamp, if there is it's will + * always be 12 bytes length: nop nop kind length echo val. + * + * Otherwise FW would close the aggregation. + */ + if (parsing_flags & PARSING_FLAGS_TIME_STAMP_EXIST_FLAG) + hdrs_len += TPA_TSTAMP_OPT_LEN; + + return len_on_bd - hdrs_len; +} + static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, struct sk_buff *skb, struct eth_fast_path_rx_cqe *fp_cqe, - u16 cqe_idx) + u16 cqe_idx, u16 parsing_flags) { struct sw_rx_page *rx_pg, old_rx_pg; u16 len_on_bd = le16_to_cpu(fp_cqe->len_on_bd); @@ -275,8 +309,8 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, /* This is needed in order to enable forwarding support */ if (frag_size) - skb_shinfo(skb)->gso_size = min((u32)SGE_PAGE_SIZE, - max(frag_size, (u32)len_on_bd)); + skb_shinfo(skb)->gso_size = bnx2x_set_lro_mss(bp, parsing_flags, + len_on_bd); #ifdef BNX2X_STOP_ON_ERROR if (pages > min_t(u32, 8, MAX_SKB_FRAGS)*SGE_PAGE_SIZE*PAGES_PER_SGE) { @@ -344,6 +378,8 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, if (likely(new_skb)) { /* fix ip xsum and give it to the stack */ /* (no need to map the new skb) */ + u16 parsing_flags = + le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags); prefetch(skb); prefetch(((char *)(skb)) + L1_CACHE_BYTES); @@ -373,9 +409,9 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, } if (!bnx2x_fill_frag_skb(bp, fp, skb, - &cqe->fast_path_cqe, cqe_idx)) { - if ((le16_to_cpu(cqe->fast_path_cqe. - pars_flags.flags) & PARSING_FLAGS_VLAN)) + &cqe->fast_path_cqe, cqe_idx, + parsing_flags)) { + if (parsing_flags & PARSING_FLAGS_VLAN) __vlan_hwaccel_put_tag(skb, le16_to_cpu(cqe->fast_path_cqe. vlan_tag)); -- cgit v1.2.3 From b746f7e52fe33ce66ea0cf6127838eff507839ff Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Mon, 28 Feb 2011 03:37:09 +0000 Subject: bnx2x: update driver version to 1.62.00-6 Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 368cfcd0a211..7897d114b290 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -22,7 +22,7 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.62.00-5" +#define DRV_MODULE_VERSION "1.62.00-6" #define DRV_MODULE_RELDATE "2011/01/30" #define BNX2X_BC_VER 0x040200 -- cgit v1.2.3 From 0a5f38467765ee15478db90d81e40c269c8dda20 Mon Sep 17 00:00:00 2001 From: "Hegde, Vinay" Date: Thu, 24 Feb 2011 23:56:28 +0000 Subject: davinci_emac: Add Carrier Link OK check in Davinci RX Handler This patch adds an additional check in the Davinci EMAC RX Handler, which tests the __LINK_STATE_NOCARRIER flag along with the __LINK_STATE_START flag as part EMAC shutting down procedure. This avoids WARNING: at drivers/net/davinci_emac.c:1040 emac_rx_handler+0xf8/0x120() during rtcwake used to suspend the target for a specified duration. Signed-off-by: Hegde, Vinay Acked-by: Cyril Chemparathy Signed-off-by: David S. Miller --- drivers/net/davinci_emac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 2a628d17d178..7018bfe408a4 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -1008,7 +1008,7 @@ static void emac_rx_handler(void *token, int len, int status) int ret; /* free and bail if we are shutting down */ - if (unlikely(!netif_running(ndev))) { + if (unlikely(!netif_running(ndev) || !netif_carrier_ok(ndev))) { dev_kfree_skb_any(skb); return; } -- cgit v1.2.3 From c976cc3aa99e813084fc4bd295c9f7b706738b48 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 28 Feb 2011 22:28:31 +0300 Subject: Staging: generic_serial: fix double locking bug spin_lock_irqsave() is not nestable. The second time that it gets called it overwrites the "flags" variable and so IRQs can't be restored properly. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/generic_serial/generic_serial.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/generic_serial/generic_serial.c b/drivers/staging/generic_serial/generic_serial.c index 5954ee1dc953..466988dbc37d 100644 --- a/drivers/staging/generic_serial/generic_serial.c +++ b/drivers/staging/generic_serial/generic_serial.c @@ -566,9 +566,9 @@ void gs_close(struct tty_struct * tty, struct file * filp) * line status register. */ - spin_lock_irqsave(&port->driver_lock, flags); + spin_lock(&port->driver_lock); port->rd->disable_rx_interrupts (port); - spin_unlock_irqrestore(&port->driver_lock, flags); + spin_unlock(&port->driver_lock); spin_unlock_irqrestore(&port->port.lock, flags); /* close has no way of returning "EINTR", so discard return value */ -- cgit v1.2.3 From e364a3416d81c7717dd642dc9b3ab132b7885f66 Mon Sep 17 00:00:00 2001 From: Amerigo Wang Date: Sun, 27 Feb 2011 23:34:28 +0000 Subject: bonding: use the correct size for _simple_hash() Clearly it should be the size of ->ip_dst here. Although this is harmless, but it still reads odd. Signed-off-by: WANG Cong Signed-off-by: David S. Miller --- drivers/net/bonding/bond_alb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 5c6fba802f2b..9bc5de3e04a8 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -604,7 +604,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon _lock_rx_hashtbl(bond); - hash_index = _simple_hash((u8 *)&arp->ip_dst, sizeof(arp->ip_src)); + hash_index = _simple_hash((u8 *)&arp->ip_dst, sizeof(arp->ip_dst)); client_info = &(bond_info->rx_hashtbl[hash_index]); if (client_info->assigned) { -- cgit v1.2.3 From b00464677923a7878b8c3164d7462b80f641bba6 Mon Sep 17 00:00:00 2001 From: Manohar Vanga Date: Sat, 26 Feb 2011 23:36:15 +0100 Subject: staging: vme: remove unreachable code Remove some unreachable code (kfree calls) from vme.c Signed-off-by: Manohar Vanga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/vme.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c index c1ec230f005a..c078ce369df9 100644 --- a/drivers/staging/vme/vme.c +++ b/drivers/staging/vme/vme.c @@ -441,7 +441,6 @@ struct vme_resource *vme_master_request(struct device *dev, return resource; - kfree(resource); err_alloc: /* Unlock image */ spin_lock(&master_image->lock); @@ -768,7 +767,6 @@ struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, return attributes; - kfree(pattern_attr); err_pat: kfree(attributes); err_attr: @@ -809,7 +807,6 @@ struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t address) return attributes; - kfree(pci_attr); err_pci: kfree(attributes); err_attr: @@ -851,7 +848,6 @@ struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long address, return attributes; - kfree(vme_attr); err_vme: kfree(attributes); err_attr: -- cgit v1.2.3 From 5bfcf90bfb1889885211e8a853c6b70500065fce Mon Sep 17 00:00:00 2001 From: Manohar Vanga Date: Sun, 27 Feb 2011 00:15:35 +0100 Subject: staging: vme: remove unreachable code Remove some more unreachable code found in bridges/vme_ca91cx42.c and bridges/vme_tsi148.c Signed-off-by: Manohar Vanga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/bridges/vme_ca91cx42.c | 3 --- drivers/staging/vme/bridges/vme_tsi148.c | 2 -- 2 files changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c index 42de83e6f1d9..5d734d9ed27d 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ b/drivers/staging/vme/bridges/vme_ca91cx42.c @@ -560,8 +560,6 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image, return 0; - iounmap(image->kern_base); - image->kern_base = NULL; err_remap: release_resource(&image->bus_resource); err_resource: @@ -1782,7 +1780,6 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) return 0; - vme_unregister_bridge(ca91cx42_bridge); err_reg: ca91cx42_crcsr_exit(ca91cx42_bridge, pdev); err_lm: diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index 26ea42fa784d..2df19eacbca5 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -869,8 +869,6 @@ static int tsi148_alloc_resource(struct vme_master_resource *image, return 0; - iounmap(image->kern_base); - image->kern_base = NULL; err_remap: release_resource(&image->bus_resource); err_resource: -- cgit v1.2.3 From 7c31b984c4d119d0e32a1696fd4ca6b506a73d10 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 24 Feb 2011 12:32:45 +0100 Subject: IIO: ADC: New driver for the AD7298 8-channel SPI ADC This patch adds support for the AD7298: 8-Channel, 1MSPS, 12-Bit SAR ADC with Temperature Sensor via SPI bus. This patch replaces the existing ad7298.c driver completely. It was necessary since, the old driver did not comply with the IIO ABI for such devices. Changes since V1: IIO: ADC: New driver for the AD7298 8-channel SPI ADC Add documentation for new sysfs file tempX_input. Simplify bit defines. Remove outdated comments. Fix indention style. ad7298_show_temp(): Add locking. Simplify temperature calculation. Change temperature result from degrees into milli degrees Celsius. Rename file according to new sysfs ABI documentation Add timestamp attributes. Revise timestamp handling accordingly. Preset timestamp generation. Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Reviewed-by: Shubhrajyoti Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/sysfs-bus-iio | 6 + drivers/staging/iio/adc/Kconfig | 7 +- drivers/staging/iio/adc/Makefile | 5 +- drivers/staging/iio/adc/ad7298.c | 501 ------------------------ drivers/staging/iio/adc/ad7298.h | 80 ++++ drivers/staging/iio/adc/ad7298_core.c | 287 ++++++++++++++ drivers/staging/iio/adc/ad7298_ring.c | 258 ++++++++++++ 7 files changed, 640 insertions(+), 504 deletions(-) delete mode 100644 drivers/staging/iio/adc/ad7298.c create mode 100644 drivers/staging/iio/adc/ad7298.h create mode 100644 drivers/staging/iio/adc/ad7298_core.c create mode 100644 drivers/staging/iio/adc/ad7298_ring.c (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio b/drivers/staging/iio/Documentation/sysfs-bus-iio index da25bc73983a..8058fcbb87d7 100644 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio @@ -111,6 +111,12 @@ Description: sensor is associated with one part of a compound device (e.g. a gyroscope axis). +What: /sys/bus/iio/devices/deviceX/tempX_input +KernelVersion: 2.6.38 +Contact: linux-iio@vger.kernel.org +Description: + Scaled temperature measurement in milli degrees Celsius. + What: /sys/bus/iio/devices/deviceX/accel_x_raw What: /sys/bus/iio/devices/deviceX/accel_y_raw What: /sys/bus/iio/devices/deviceX/accel_z_raw diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 5613b30bc663..6692a3d87f23 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -49,11 +49,14 @@ config AD7291 temperature sensors. config AD7298 - tristate "Analog Devices AD7298 temperature sensor and ADC driver" + tristate "Analog Devices AD7298 ADC driver" depends on SPI help Say yes here to build support for Analog Devices AD7298 - temperature sensors and ADC. + 8 Channel ADC with temperature sensor. + + To compile this driver as a module, choose M here: the + module will be called ad7298. config AD7314 tristate "Analog Devices AD7314 temperature sensor driver" diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index cb73346d6d9e..31067defd79b 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -25,10 +25,13 @@ ad7887-y := ad7887_core.o ad7887-$(CONFIG_IIO_RING_BUFFER) += ad7887_ring.o obj-$(CONFIG_AD7887) += ad7887.o +ad7298-y := ad7298_core.o +ad7298-$(CONFIG_IIO_RING_BUFFER) += ad7298_ring.o +obj-$(CONFIG_AD7298) += ad7298.o + obj-$(CONFIG_AD7150) += ad7150.o obj-$(CONFIG_AD7152) += ad7152.o obj-$(CONFIG_AD7291) += ad7291.o -obj-$(CONFIG_AD7298) += ad7298.o obj-$(CONFIG_AD7314) += ad7314.o obj-$(CONFIG_AD7745) += ad7745.o obj-$(CONFIG_AD7816) += ad7816.o diff --git a/drivers/staging/iio/adc/ad7298.c b/drivers/staging/iio/adc/ad7298.c deleted file mode 100644 index 1a080c977637..000000000000 --- a/drivers/staging/iio/adc/ad7298.c +++ /dev/null @@ -1,501 +0,0 @@ -/* - * AD7298 digital temperature sensor driver supporting AD7298 - * - * Copyright 2010 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../iio.h" -#include "../sysfs.h" - -/* - * AD7298 command - */ -#define AD7298_PD 0x1 -#define AD7298_T_AVG_MASK 0x2 -#define AD7298_EXT_REF 0x4 -#define AD7298_T_SENSE_MASK 0x20 -#define AD7298_VOLTAGE_MASK 0x3fc0 -#define AD7298_VOLTAGE_OFFSET 0x6 -#define AD7298_VOLTAGE_LIMIT_COUNT 8 -#define AD7298_REPEAT 0x40 -#define AD7298_WRITE 0x80 - -/* - * AD7298 value masks - */ -#define AD7298_CHANNEL_MASK 0xf000 -#define AD7298_VALUE_MASK 0xfff -#define AD7298_T_VALUE_SIGN 0x400 -#define AD7298_T_VALUE_FLOAT_OFFSET 2 -#define AD7298_T_VALUE_FLOAT_MASK 0x2 - -/* - * struct ad7298_chip_info - chip specifc information - */ - -struct ad7298_chip_info { - const char *name; - struct spi_device *spi_dev; - struct iio_dev *indio_dev; - u16 command; - u16 busy_pin; - u8 channels; /* Active voltage channels */ -}; - -/* - * ad7298 register access by SPI - */ -static int ad7298_spi_write(struct ad7298_chip_info *chip, u16 data) -{ - struct spi_device *spi_dev = chip->spi_dev; - int ret = 0; - - data |= AD7298_WRITE; - data = cpu_to_be16(data); - ret = spi_write(spi_dev, (u8 *)&data, sizeof(data)); - if (ret < 0) - dev_err(&spi_dev->dev, "SPI write error\n"); - - return ret; -} - -static int ad7298_spi_read(struct ad7298_chip_info *chip, u16 mask, u16 *data) -{ - struct spi_device *spi_dev = chip->spi_dev; - int ret = 0; - u8 count = chip->channels; - u16 command; - int i; - - if (mask & AD7298_T_SENSE_MASK) { - command = chip->command & ~(AD7298_T_AVG_MASK | AD7298_VOLTAGE_MASK); - command |= AD7298_T_SENSE_MASK; - count = 1; - } else if (mask & AD7298_T_AVG_MASK) { - command = chip->command & ~AD7298_VOLTAGE_MASK; - command |= AD7298_T_SENSE_MASK | AD7298_T_AVG_MASK; - count = 2; - } else if (mask & AD7298_VOLTAGE_MASK) { - command = chip->command & ~(AD7298_T_AVG_MASK | AD7298_T_SENSE_MASK); - count = chip->channels; - } - - ret = ad7298_spi_write(chip, chip->command); - if (ret < 0) { - dev_err(&spi_dev->dev, "SPI write command error\n"); - return ret; - } - - ret = spi_read(spi_dev, (u8 *)&command, sizeof(command)); - if (ret < 0) { - dev_err(&spi_dev->dev, "SPI read error\n"); - return ret; - } - - i = 10000; - while (i && gpio_get_value(chip->busy_pin)) { - cpu_relax(); - i--; - } - if (!i) { - dev_err(&spi_dev->dev, "Always in busy convertion.\n"); - return -EBUSY; - } - - for (i = 0; i < count; i++) { - ret = spi_read(spi_dev, (u8 *)&data[i], sizeof(data[i])); - if (ret < 0) { - dev_err(&spi_dev->dev, "SPI read error\n"); - return ret; - } - *data = be16_to_cpu(data[i]); - } - - return 0; -} - -static ssize_t ad7298_show_mode(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7298_chip_info *chip = dev_info->dev_data; - - if (chip->command & AD7298_REPEAT) - return sprintf(buf, "repeat\n"); - else - return sprintf(buf, "normal\n"); -} - -static ssize_t ad7298_store_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7298_chip_info *chip = dev_info->dev_data; - - if (strcmp(buf, "repeat")) - chip->command |= AD7298_REPEAT; - else - chip->command &= (~AD7298_REPEAT); - - return 1; -} - -static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, - ad7298_show_mode, - ad7298_store_mode, - 0); - -static ssize_t ad7298_show_available_modes(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "normal\nrepeat\n"); -} - -static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7298_show_available_modes, NULL, 0); - -static ssize_t ad7298_store_reset(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7298_chip_info *chip = dev_info->dev_data; - u16 command; - int ret; - - command = chip->command & ~AD7298_PD; - - ret = ad7298_spi_write(chip, command); - if (ret) - return -EIO; - - command = chip->command | AD7298_PD; - - ret = ad7298_spi_write(chip, command); - if (ret) - return -EIO; - - return len; -} - -static IIO_DEVICE_ATTR(reset, S_IWUSR, - NULL, - ad7298_store_reset, - 0); - -static ssize_t ad7298_show_ext_ref(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7298_chip_info *chip = dev_info->dev_data; - - return sprintf(buf, "%d\n", !!(chip->command & AD7298_EXT_REF)); -} - -static ssize_t ad7298_store_ext_ref(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7298_chip_info *chip = dev_info->dev_data; - u16 command; - int ret; - - command = chip->command & (~AD7298_EXT_REF); - if (strcmp(buf, "1")) - command |= AD7298_EXT_REF; - - ret = ad7298_spi_write(chip, command); - if (ret) - return -EIO; - - chip->command = command; - - return len; -} - -static IIO_DEVICE_ATTR(ext_ref, S_IRUGO | S_IWUSR, - ad7298_show_ext_ref, - ad7298_store_ext_ref, - 0); - -static ssize_t ad7298_show_t_sense(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7298_chip_info *chip = dev_info->dev_data; - u16 data; - char sign = ' '; - int ret; - - ret = ad7298_spi_read(chip, AD7298_T_SENSE_MASK, &data); - if (ret) - return -EIO; - - if (data & AD7298_T_VALUE_SIGN) { - /* convert supplement to positive value */ - data = (AD7298_T_VALUE_SIGN << 1) - data; - sign = '-'; - } - - return sprintf(buf, "%c%d.%.2d\n", sign, - (data >> AD7298_T_VALUE_FLOAT_OFFSET), - (data & AD7298_T_VALUE_FLOAT_MASK) * 25); -} - -static IIO_DEVICE_ATTR(t_sense, S_IRUGO, ad7298_show_t_sense, NULL, 0); - -static ssize_t ad7298_show_t_average(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7298_chip_info *chip = dev_info->dev_data; - u16 data[2]; - char sign = ' '; - int ret; - - ret = ad7298_spi_read(chip, AD7298_T_AVG_MASK, data); - if (ret) - return -EIO; - - if (data[1] & AD7298_T_VALUE_SIGN) { - /* convert supplement to positive value */ - data[1] = (AD7298_T_VALUE_SIGN << 1) - data[1]; - sign = '-'; - } - - return sprintf(buf, "%c%d.%.2d\n", sign, - (data[1] >> AD7298_T_VALUE_FLOAT_OFFSET), - (data[1] & AD7298_T_VALUE_FLOAT_MASK) * 25); -} - -static IIO_DEVICE_ATTR(t_average, S_IRUGO, ad7298_show_t_average, NULL, 0); - -static ssize_t ad7298_show_voltage(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7298_chip_info *chip = dev_info->dev_data; - u16 data[AD7298_VOLTAGE_LIMIT_COUNT]; - int i, size, ret; - - ret = ad7298_spi_read(chip, AD7298_VOLTAGE_MASK, data); - if (ret) - return -EIO; - - for (i = 0; i < AD7298_VOLTAGE_LIMIT_COUNT; i++) { - if (chip->command & (AD7298_T_SENSE_MASK << i)) { - ret = sprintf(buf, "channel[%d]=%d\n", i, - data[i] & AD7298_VALUE_MASK); - if (ret < 0) - break; - buf += ret; - size += ret; - } - } - - return size; -} - -static IIO_DEVICE_ATTR(voltage, S_IRUGO, ad7298_show_voltage, NULL, 0); - -static ssize_t ad7298_show_channel_mask(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7298_chip_info *chip = dev_info->dev_data; - - return sprintf(buf, "0x%x\n", (chip->command & AD7298_VOLTAGE_MASK) >> - AD7298_VOLTAGE_OFFSET); -} - -static ssize_t ad7298_store_channel_mask(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7298_chip_info *chip = dev_info->dev_data; - unsigned long data; - int i, ret; - - ret = strict_strtoul(buf, 16, &data); - if (ret || data > 0xff) - return -EINVAL; - - chip->command &= (~AD7298_VOLTAGE_MASK); - chip->command |= data << AD7298_VOLTAGE_OFFSET; - - for (i = 0, chip->channels = 0; i < AD7298_VOLTAGE_LIMIT_COUNT; i++) { - if (chip->command & (AD7298_T_SENSE_MASK << i)) - chip->channels++; - } - - return ret; -} - -static IIO_DEVICE_ATTR(channel_mask, S_IRUGO | S_IWUSR, - ad7298_show_channel_mask, - ad7298_store_channel_mask, - 0); - -static ssize_t ad7298_show_name(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7298_chip_info *chip = dev_info->dev_data; - return sprintf(buf, "%s\n", chip->name); -} - -static IIO_DEVICE_ATTR(name, S_IRUGO, ad7298_show_name, NULL, 0); - -static struct attribute *ad7298_attributes[] = { - &iio_dev_attr_available_modes.dev_attr.attr, - &iio_dev_attr_mode.dev_attr.attr, - &iio_dev_attr_reset.dev_attr.attr, - &iio_dev_attr_ext_ref.dev_attr.attr, - &iio_dev_attr_t_sense.dev_attr.attr, - &iio_dev_attr_t_average.dev_attr.attr, - &iio_dev_attr_voltage.dev_attr.attr, - &iio_dev_attr_channel_mask.dev_attr.attr, - &iio_dev_attr_name.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad7298_attribute_group = { - .attrs = ad7298_attributes, -}; - -/* - * device probe and remove - */ -static int __devinit ad7298_probe(struct spi_device *spi_dev) -{ - struct ad7298_chip_info *chip; - unsigned short *pins = spi_dev->dev.platform_data; - int ret = 0; - - chip = kzalloc(sizeof(struct ad7298_chip_info), GFP_KERNEL); - - if (chip == NULL) - return -ENOMEM; - - /* this is only used for device removal purposes */ - dev_set_drvdata(&spi_dev->dev, chip); - - chip->spi_dev = spi_dev; - chip->name = spi_dev->modalias; - chip->busy_pin = pins[0]; - - ret = gpio_request(chip->busy_pin, chip->name); - if (ret) { - dev_err(&spi_dev->dev, "Fail to request busy gpio PIN %d.\n", - chip->busy_pin); - goto error_free_chip; - } - gpio_direction_input(chip->busy_pin); - - chip->indio_dev = iio_allocate_device(); - if (chip->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_gpio; - } - - chip->indio_dev->dev.parent = &spi_dev->dev; - chip->indio_dev->attrs = &ad7298_attribute_group; - chip->indio_dev->dev_data = (void *)chip; - chip->indio_dev->driver_module = THIS_MODULE; - chip->indio_dev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(chip->indio_dev); - if (ret) - goto error_free_dev; - - dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n", - chip->name); - - return 0; - -error_free_dev: - iio_free_device(chip->indio_dev); -error_free_gpio: - gpio_free(chip->busy_pin); -error_free_chip: - kfree(chip); - - return ret; -} - -static int __devexit ad7298_remove(struct spi_device *spi_dev) -{ - struct ad7298_chip_info *chip = dev_get_drvdata(&spi_dev->dev); - struct iio_dev *indio_dev = chip->indio_dev; - - dev_set_drvdata(&spi_dev->dev, NULL); - iio_device_unregister(indio_dev); - iio_free_device(chip->indio_dev); - gpio_free(chip->busy_pin); - kfree(chip); - - return 0; -} - -static const struct spi_device_id ad7298_id[] = { - { "ad7298", 0 }, - {} -}; - -MODULE_DEVICE_TABLE(spi, ad7298_id); - -static struct spi_driver ad7298_driver = { - .driver = { - .name = "ad7298", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = ad7298_probe, - .remove = __devexit_p(ad7298_remove), - .id_table = ad7298_id, -}; - -static __init int ad7298_init(void) -{ - return spi_register_driver(&ad7298_driver); -} - -static __exit void ad7298_exit(void) -{ - spi_unregister_driver(&ad7298_driver); -} - -MODULE_AUTHOR("Sonic Zhang "); -MODULE_DESCRIPTION("Analog Devices AD7298 digital" - " temperature sensor and ADC driver"); -MODULE_LICENSE("GPL v2"); - -module_init(ad7298_init); -module_exit(ad7298_exit); diff --git a/drivers/staging/iio/adc/ad7298.h b/drivers/staging/iio/adc/ad7298.h new file mode 100644 index 000000000000..fe7ed77d638f --- /dev/null +++ b/drivers/staging/iio/adc/ad7298.h @@ -0,0 +1,80 @@ +/* + * AD7298 SPI ADC driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#ifndef IIO_ADC_AD7298_H_ +#define IIO_ADC_AD7298_H_ + +#define AD7298_WRITE (1 << 15) /* write to the control register */ +#define AD7298_REPEAT (1 << 14) /* repeated conversion enable */ +#define AD7298_CH(x) (1 << (13 - (x))) /* channel select */ +#define AD7298_TSENSE (1 << 5) /* temperature conversion enable */ +#define AD7298_EXTREF (1 << 2) /* external reference enable */ +#define AD7298_TAVG (1 << 1) /* temperature sensor averaging enable */ +#define AD7298_PDD (1 << 0) /* partial power down enable */ + +#define AD7298_CH_MASK (AD7298_CH0 | AD7298_CH1 | AD7298_CH2 | AD7298_CH3 | \ + AD7298_CH4 | AD7298_CH5 | AD7298_CH6 | AD7298_CH7) + +#define AD7298_MAX_CHAN 8 +#define AD7298_BITS 12 +#define AD7298_STORAGE_BITS 16 +#define AD7298_INTREF_mV 2500 + +#define RES_MASK(bits) ((1 << (bits)) - 1) + +/* + * TODO: struct ad7298_platform_data needs to go into include/linux/iio + */ + +struct ad7298_platform_data { + /* External Vref voltage applied */ + u16 vref_mv; +}; + +struct ad7298_state { + struct iio_dev *indio_dev; + struct spi_device *spi; + struct regulator *reg; + struct work_struct poll_work; + atomic_t protect_ring; + size_t d_size; + u16 int_vref_mv; + unsigned ext_ref; + struct spi_transfer ring_xfer[10]; + struct spi_transfer scan_single_xfer[3]; + struct spi_message ring_msg; + struct spi_message scan_single_msg; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + unsigned short rx_buf[8] ____cacheline_aligned; + unsigned short tx_buf[2]; +}; + +#ifdef CONFIG_IIO_RING_BUFFER +int ad7298_scan_from_ring(struct ad7298_state *st, long ch); +int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev); +void ad7298_ring_cleanup(struct iio_dev *indio_dev); +#else /* CONFIG_IIO_RING_BUFFER */ +static inline int ad7298_scan_from_ring(struct ad7298_state *st, long ch) +{ + return 0; +} + +static inline int +ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline void ad7298_ring_cleanup(struct iio_dev *indio_dev) +{ +} +#endif /* CONFIG_IIO_RING_BUFFER */ +#endif /* IIO_ADC_AD7298_H_ */ diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c new file mode 100644 index 000000000000..2e9154e7d887 --- /dev/null +++ b/drivers/staging/iio/adc/ad7298_core.c @@ -0,0 +1,287 @@ +/* + * AD7298 SPI ADC driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../ring_generic.h" +#include "adc.h" + +#include "ad7298.h" + +static int ad7298_scan_direct(struct ad7298_state *st, unsigned ch) +{ + int ret; + st->tx_buf[0] = cpu_to_be16(AD7298_WRITE | st->ext_ref | + (AD7298_CH(0) >> ch)); + + ret = spi_sync(st->spi, &st->scan_single_msg); + if (ret) + return ret; + + return be16_to_cpu(st->rx_buf[0]); +} + +static ssize_t ad7298_scan(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7298_state *st = dev_info->dev_data; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + + mutex_lock(&dev_info->mlock); + if (iio_ring_enabled(dev_info)) + ret = ad7298_scan_from_ring(st, this_attr->address); + else + ret = ad7298_scan_direct(st, this_attr->address); + mutex_unlock(&dev_info->mlock); + + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", ret & RES_MASK(AD7298_BITS)); +} + +static IIO_DEV_ATTR_IN_RAW(0, ad7298_scan, 0); +static IIO_DEV_ATTR_IN_RAW(1, ad7298_scan, 1); +static IIO_DEV_ATTR_IN_RAW(2, ad7298_scan, 2); +static IIO_DEV_ATTR_IN_RAW(3, ad7298_scan, 3); +static IIO_DEV_ATTR_IN_RAW(4, ad7298_scan, 4); +static IIO_DEV_ATTR_IN_RAW(5, ad7298_scan, 5); +static IIO_DEV_ATTR_IN_RAW(6, ad7298_scan, 6); +static IIO_DEV_ATTR_IN_RAW(7, ad7298_scan, 7); + +static ssize_t ad7298_show_temp(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7298_state *st = iio_dev_get_devdata(dev_info); + int tmp; + + tmp = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE | + AD7298_TAVG | st->ext_ref); + + mutex_lock(&dev_info->mlock); + spi_write(st->spi, (u8 *)&tmp, 2); + tmp = 0; + spi_write(st->spi, (u8 *)&tmp, 2); + usleep_range(101, 1000); /* sleep > 100us */ + spi_read(st->spi, (u8 *)&tmp, 2); + mutex_unlock(&dev_info->mlock); + + tmp = be16_to_cpu(tmp) & RES_MASK(AD7298_BITS); + + /* + * One LSB of the ADC corresponds to 0.25 deg C. + * The temperature reading is in 12-bit twos complement format + */ + + if (tmp & (1 << (AD7298_BITS - 1))) { + tmp = (4096 - tmp) * 250; + tmp -= (2 * tmp); + + } else { + tmp *= 250; /* temperature in milli degrees Celsius */ + } + + return sprintf(buf, "%d\n", tmp); +} + +static IIO_DEVICE_ATTR(temp0_input, S_IRUGO, ad7298_show_temp, NULL, 0); + +static ssize_t ad7298_show_scale(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7298_state *st = iio_dev_get_devdata(dev_info); + /* Corresponds to Vref / 2^(bits) */ + unsigned int scale_uv = (st->int_vref_mv * 1000) >> AD7298_BITS; + + return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000); +} +static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7298_show_scale, NULL, 0); + +static ssize_t ad7298_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7298_state *st = iio_dev_get_devdata(dev_info); + + return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name); +} +static IIO_DEVICE_ATTR(name, S_IRUGO, ad7298_show_name, NULL, 0); + +static struct attribute *ad7298_attributes[] = { + &iio_dev_attr_in0_raw.dev_attr.attr, + &iio_dev_attr_in1_raw.dev_attr.attr, + &iio_dev_attr_in2_raw.dev_attr.attr, + &iio_dev_attr_in3_raw.dev_attr.attr, + &iio_dev_attr_in4_raw.dev_attr.attr, + &iio_dev_attr_in5_raw.dev_attr.attr, + &iio_dev_attr_in6_raw.dev_attr.attr, + &iio_dev_attr_in7_raw.dev_attr.attr, + &iio_dev_attr_in_scale.dev_attr.attr, + &iio_dev_attr_temp0_input.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad7298_attribute_group = { + .attrs = ad7298_attributes, +}; + +static int __devinit ad7298_probe(struct spi_device *spi) +{ + struct ad7298_platform_data *pdata = spi->dev.platform_data; + struct ad7298_state *st; + int ret; + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + st->reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + } + + spi_set_drvdata(spi, st); + + atomic_set(&st->protect_ring, 0); + st->spi = spi; + + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_disable_reg; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->attrs = &ad7298_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + /* Setup default message */ + + st->scan_single_xfer[0].tx_buf = &st->tx_buf[0]; + st->scan_single_xfer[0].len = 2; + st->scan_single_xfer[0].cs_change = 1; + st->scan_single_xfer[1].tx_buf = &st->tx_buf[1]; + st->scan_single_xfer[1].len = 2; + st->scan_single_xfer[1].cs_change = 1; + st->scan_single_xfer[2].rx_buf = &st->rx_buf[0]; + st->scan_single_xfer[2].len = 2; + + spi_message_init(&st->scan_single_msg); + spi_message_add_tail(&st->scan_single_xfer[0], &st->scan_single_msg); + spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg); + spi_message_add_tail(&st->scan_single_xfer[2], &st->scan_single_msg); + + if (pdata && pdata->vref_mv) { + st->int_vref_mv = pdata->vref_mv; + st->ext_ref = AD7298_EXTREF; + } else { + st->int_vref_mv = AD7298_INTREF_mV; + } + + ret = ad7298_register_ring_funcs_and_init(st->indio_dev); + if (ret) + goto error_free_device; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_free_device; + + ret = iio_ring_buffer_register(st->indio_dev->ring, 0); + if (ret) + goto error_cleanup_ring; + return 0; + +error_cleanup_ring: + ad7298_ring_cleanup(st->indio_dev); + iio_device_unregister(st->indio_dev); +error_free_device: + iio_free_device(st->indio_dev); +error_disable_reg: + if (!IS_ERR(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR(st->reg)) + regulator_put(st->reg); + kfree(st); +error_ret: + return ret; +} + +static int __devexit ad7298_remove(struct spi_device *spi) +{ + struct ad7298_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + iio_ring_buffer_unregister(indio_dev->ring); + ad7298_ring_cleanup(indio_dev); + iio_device_unregister(indio_dev); + if (!IS_ERR(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + kfree(st); + return 0; +} + +static const struct spi_device_id ad7298_id[] = { + {"ad7298", 0}, + {} +}; + +static struct spi_driver ad7298_driver = { + .driver = { + .name = "ad7298", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = ad7298_probe, + .remove = __devexit_p(ad7298_remove), + .id_table = ad7298_id, +}; + +static int __init ad7298_init(void) +{ + return spi_register_driver(&ad7298_driver); +} +module_init(ad7298_init); + +static void __exit ad7298_exit(void) +{ + spi_unregister_driver(&ad7298_driver); +} +module_exit(ad7298_exit); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD7298 ADC"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("spi:ad7298"); diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c new file mode 100644 index 000000000000..19d1aced1e6c --- /dev/null +++ b/drivers/staging/iio/adc/ad7298_ring.c @@ -0,0 +1,258 @@ +/* + * AD7298 SPI ADC driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../ring_generic.h" +#include "../ring_sw.h" +#include "../trigger.h" +#include "../sysfs.h" + +#include "ad7298.h" + +static IIO_SCAN_EL_C(in0, 0, 0, NULL); +static IIO_SCAN_EL_C(in1, 1, 0, NULL); +static IIO_SCAN_EL_C(in2, 2, 0, NULL); +static IIO_SCAN_EL_C(in3, 3, 0, NULL); +static IIO_SCAN_EL_C(in4, 4, 0, NULL); +static IIO_SCAN_EL_C(in5, 5, 0, NULL); +static IIO_SCAN_EL_C(in6, 6, 0, NULL); +static IIO_SCAN_EL_C(in7, 7, 0, NULL); + +static IIO_SCAN_EL_TIMESTAMP(8); +static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64); + +static IIO_CONST_ATTR(in_type, "u12/16") ; + +static struct attribute *ad7298_scan_el_attrs[] = { + &iio_scan_el_in0.dev_attr.attr, + &iio_const_attr_in0_index.dev_attr.attr, + &iio_scan_el_in1.dev_attr.attr, + &iio_const_attr_in1_index.dev_attr.attr, + &iio_scan_el_in2.dev_attr.attr, + &iio_const_attr_in2_index.dev_attr.attr, + &iio_scan_el_in3.dev_attr.attr, + &iio_const_attr_in3_index.dev_attr.attr, + &iio_scan_el_in4.dev_attr.attr, + &iio_const_attr_in4_index.dev_attr.attr, + &iio_scan_el_in5.dev_attr.attr, + &iio_const_attr_in5_index.dev_attr.attr, + &iio_scan_el_in6.dev_attr.attr, + &iio_const_attr_in6_index.dev_attr.attr, + &iio_scan_el_in7.dev_attr.attr, + &iio_const_attr_in7_index.dev_attr.attr, + &iio_const_attr_timestamp_index.dev_attr.attr, + &iio_scan_el_timestamp.dev_attr.attr, + &iio_const_attr_timestamp_type.dev_attr.attr, + &iio_const_attr_in_type.dev_attr.attr, + NULL, +}; + +static struct attribute_group ad7298_scan_el_group = { + .name = "scan_elements", + .attrs = ad7298_scan_el_attrs, +}; + +int ad7298_scan_from_ring(struct ad7298_state *st, long ch) +{ + struct iio_ring_buffer *ring = st->indio_dev->ring; + int ret; + u16 *ring_data; + + if (!(ring->scan_mask & (1 << ch))) { + ret = -EBUSY; + goto error_ret; + } + + ring_data = kmalloc(ring->access.get_bytes_per_datum(ring), GFP_KERNEL); + if (ring_data == NULL) { + ret = -ENOMEM; + goto error_ret; + } + ret = ring->access.read_last(ring, (u8 *) ring_data); + if (ret) + goto error_free_ring_data; + + ret = be16_to_cpu(ring_data[ch]); + +error_free_ring_data: + kfree(ring_data); +error_ret: + return ret; +} + +/** + * ad7298_ring_preenable() setup the parameters of the ring before enabling + * + * The complex nature of the setting of the number of bytes per datum is due + * to this driver currently ensuring that the timestamp is stored at an 8 + * byte boundary. + **/ +static int ad7298_ring_preenable(struct iio_dev *indio_dev) +{ + struct ad7298_state *st = indio_dev->dev_data; + struct iio_ring_buffer *ring = indio_dev->ring; + size_t d_size; + int i, m; + unsigned short command; + + d_size = ring->scan_count * (AD7298_STORAGE_BITS / 8); + + if (ring->scan_timestamp) { + d_size += sizeof(s64); + + if (d_size % sizeof(s64)) + d_size += sizeof(s64) - (d_size % sizeof(s64)); + } + + if (ring->access.set_bytes_per_datum) + ring->access.set_bytes_per_datum(ring, d_size); + + st->d_size = d_size; + + command = AD7298_WRITE | st->ext_ref; + + for (i = 0, m = AD7298_CH(0); i < AD7298_MAX_CHAN; i++, m >>= 1) + if (ring->scan_mask & (1 << i)) + command |= m; + + st->tx_buf[0] = cpu_to_be16(command); + + /* build spi ring message */ + st->ring_xfer[0].tx_buf = &st->tx_buf[0]; + st->ring_xfer[0].len = 2; + st->ring_xfer[0].cs_change = 1; + st->ring_xfer[1].tx_buf = &st->tx_buf[1]; + st->ring_xfer[1].len = 2; + st->ring_xfer[1].cs_change = 1; + + spi_message_init(&st->ring_msg); + spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg); + spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg); + + for (i = 0; i < ring->scan_count; i++) { + st->ring_xfer[i + 2].rx_buf = &st->rx_buf[i]; + st->ring_xfer[i + 2].len = 2; + st->ring_xfer[i + 2].cs_change = 1; + spi_message_add_tail(&st->ring_xfer[i + 2], &st->ring_msg); + } + /* make sure last transfer cs_change is not set */ + st->ring_xfer[i + 1].cs_change = 0; + + return 0; +} + +/** + * ad7298_poll_func_th() th of trigger launched polling to ring buffer + * + * As sampling only occurs on spi comms occuring, leave timestamping until + * then. Some triggers will generate their own time stamp. Currently + * there is no way of notifying them when no one cares. + **/ +static void ad7298_poll_func_th(struct iio_dev *indio_dev, s64 time) +{ + struct ad7298_state *st = indio_dev->dev_data; + + schedule_work(&st->poll_work); + return; +} + +/** + * ad7298_poll_bh_to_ring() bh of trigger launched polling to ring buffer + * @work_s: the work struct through which this was scheduled + * + * Currently there is no option in this driver to disable the saving of + * timestamps within the ring. + * I think the one copy of this at a time was to avoid problems if the + * trigger was set far too high and the reads then locked up the computer. + **/ +static void ad7298_poll_bh_to_ring(struct work_struct *work_s) +{ + struct ad7298_state *st = container_of(work_s, struct ad7298_state, + poll_work); + struct iio_dev *indio_dev = st->indio_dev; + struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring); + struct iio_ring_buffer *ring = indio_dev->ring; + s64 time_ns; + __u16 buf[16]; + int b_sent, i; + + /* Ensure only one copy of this function running at a time */ + if (atomic_inc_return(&st->protect_ring) > 1) + return; + + b_sent = spi_sync(st->spi, &st->ring_msg); + if (b_sent) + goto done; + + if (ring->scan_timestamp) { + time_ns = iio_get_time_ns(); + memcpy((u8 *)buf + st->d_size - sizeof(s64), + &time_ns, sizeof(time_ns)); + } + + for (i = 0; i < ring->scan_count; i++) + buf[i] = be16_to_cpu(st->rx_buf[i]); + + indio_dev->ring->access.store_to(&sw_ring->buf, (u8 *)buf, time_ns); +done: + atomic_dec(&st->protect_ring); +} + +int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev) +{ + struct ad7298_state *st = indio_dev->dev_data; + int ret; + + indio_dev->ring = iio_sw_rb_allocate(indio_dev); + if (!indio_dev->ring) { + ret = -ENOMEM; + goto error_ret; + } + /* Effectively select the ring buffer implementation */ + iio_ring_sw_register_funcs(&indio_dev->ring->access); + ret = iio_alloc_pollfunc(indio_dev, NULL, &ad7298_poll_func_th); + if (ret) + goto error_deallocate_sw_rb; + + /* Ring buffer functions - here trigger setup related */ + + indio_dev->ring->preenable = &ad7298_ring_preenable; + indio_dev->ring->postenable = &iio_triggered_ring_postenable; + indio_dev->ring->predisable = &iio_triggered_ring_predisable; + indio_dev->ring->scan_el_attrs = &ad7298_scan_el_group; + indio_dev->ring->scan_timestamp = true; + + INIT_WORK(&st->poll_work, &ad7298_poll_bh_to_ring); + + /* Flag that polled ring buffering is possible */ + indio_dev->modes |= INDIO_RING_TRIGGERED; + return 0; +error_deallocate_sw_rb: + iio_sw_rb_free(indio_dev->ring); +error_ret: + return ret; +} + +void ad7298_ring_cleanup(struct iio_dev *indio_dev) +{ + if (indio_dev->trig) { + iio_put_trigger(indio_dev->trig); + iio_trigger_dettach_poll_func(indio_dev->trig, + indio_dev->pollfunc); + } + kfree(indio_dev->pollfunc); + iio_sw_rb_free(indio_dev->ring); +} -- cgit v1.2.3 From 065896e904eac598bafd5e607b944da34c4aaf09 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 24 Feb 2011 16:34:50 +0100 Subject: IIO: Documentation: generic_buffer example: Avoid NULL pointer dereference In case optarg n is not given return/exit Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/generic_buffer.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c index 771b23627797..3cc18ab4ebfd 100644 --- a/drivers/staging/iio/Documentation/generic_buffer.c +++ b/drivers/staging/iio/Documentation/generic_buffer.c @@ -168,6 +168,9 @@ int main(int argc, char **argv) } } + if (device_name == NULL) + return -1; + /* Find the device requested */ dev_num = find_type_by_name(device_name, "device"); if (dev_num < 0) { -- cgit v1.2.3 From cb771cbdbdb153b68275cd5b9eca593c4e5026e8 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 24 Feb 2011 16:34:51 +0100 Subject: IIO: Documentation: iio_utils: Avoid double free() filename is used and freed later Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/iio_utils.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index 4dc961ced35e..3cf01a532b55 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -319,7 +319,6 @@ inline int build_channel_array(const char *device_dir, } fscanf(sysfsfp, "%u", ¤t->enabled); fclose(sysfsfp); - free(filename); current->scale = 1.0; current->offset = 0; current->name = strndup(ent->d_name, -- cgit v1.2.3 From 2bf99c70cee1d9347145ec0d96ba39764e2193bc Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 24 Feb 2011 16:34:52 +0100 Subject: IIO: Documentation: iio_utils: style consistency fix No functional changes Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/iio_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index 3cf01a532b55..4b023aa14198 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -374,7 +374,7 @@ inline int build_channel_array(const char *device_dir, } } /* reorder so that the array is in index order*/ - current = malloc(sizeof(**ci_array)**counter); + current = malloc(sizeof(**ci_array)*(*counter)); if (current == NULL) { ret = -ENOMEM; goto error_cleanup_array; -- cgit v1.2.3 From 7ccd4506fa49600a3c59cf64608b2c9e669b6c97 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 24 Feb 2011 16:34:53 +0100 Subject: IIO: Documentation: iio_utils: Prevent buffer overflow The first part of build_channel_array()identifies the number of enabled channels. Further down this count is used to allocate the ci_array. The next section parses the scan_elements directory again, and fills ci_array regardless if the channel is enabled or not. So if less than available channels are enabled ci_array memory is overflowed. This fix makes sure that we allocate enough memory. But the whole approach looks a bit cumbersome to me. Why not allocate memory for MAX_CHANNLES, less say 64 (I never seen a part with more than that channels). And skip the first part entirely. Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/iio_utils.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index 4b023aa14198..bde231352a87 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -290,15 +290,17 @@ inline int build_channel_array(const char *device_dir, fscanf(sysfsfp, "%u", &ret); if (ret == 1) (*counter)++; + count++; fclose(sysfsfp); free(filename); } - *ci_array = malloc(sizeof(**ci_array)*(*counter)); + *ci_array = malloc(sizeof(**ci_array)*count); if (*ci_array == NULL) { ret = -ENOMEM; goto error_close_dir; } seekdir(dp, 0); + count = 0; while (ent = readdir(dp), ent != NULL) { if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"), "_en") == 0) { -- cgit v1.2.3 From fc7f95a94606fd81d8a3910c1477ea7340b52b9f Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 24 Feb 2011 16:34:54 +0100 Subject: IIO: Documentation: iio_utils: fix mask generation Variable sizeint is used uninitialized. Remove sizeint completely and use bits_used instead. Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/iio_utils.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index bde231352a87..1b33c040bad7 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -113,7 +113,7 @@ inline int iioutils_get_type(unsigned *is_signed, DIR *dp; char *scan_el_dir, *builtname, *builtname_generic, *filename = 0; char signchar; - unsigned sizeint, padint; + unsigned padint; const struct dirent *ent; ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, device_dir); @@ -159,7 +159,7 @@ inline int iioutils_get_type(unsigned *is_signed, fscanf(sysfsfp, "%c%u/%u", &signchar, bits_used, &padint); *bytes = padint / 8; - if (sizeint == 64) + if (*bits_used == 64) *mask = ~0; else *mask = (1 << *bits_used) - 1; -- cgit v1.2.3 From 86f702ab1d5f3a181937bf462c176d0c95f95a24 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 24 Feb 2011 22:19:47 +0100 Subject: IIO: ADC: AD7476: Update timestamp handling Add timestamp attributes. Revise timestamp handling accordingly. Preset timestamp generation. Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/ad7476.h | 1 + drivers/staging/iio/adc/ad7476_ring.c | 37 +++++++++++++++++++++-------------- 2 files changed, 23 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/ad7476.h b/drivers/staging/iio/adc/ad7476.h index b51b49e4abd6..f917e9c3d54f 100644 --- a/drivers/staging/iio/adc/ad7476.h +++ b/drivers/staging/iio/adc/ad7476.h @@ -33,6 +33,7 @@ struct ad7476_state { struct regulator *reg; struct work_struct poll_work; atomic_t protect_ring; + size_t d_size; u16 int_vref_mv; struct spi_transfer xfer; struct spi_message msg; diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c index 85de14274ad7..1d654c86099d 100644 --- a/drivers/staging/iio/adc/ad7476_ring.c +++ b/drivers/staging/iio/adc/ad7476_ring.c @@ -26,6 +26,8 @@ #include "ad7476.h" static IIO_SCAN_EL_C(in0, 0, 0, NULL); +static IIO_SCAN_EL_TIMESTAMP(1); +static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64); static ssize_t ad7476_show_type(struct device *dev, struct device_attribute *attr, @@ -44,6 +46,9 @@ static IIO_DEVICE_ATTR(in_type, S_IRUGO, ad7476_show_type, NULL, 0); static struct attribute *ad7476_scan_el_attrs[] = { &iio_scan_el_in0.dev_attr.attr, &iio_const_attr_in0_index.dev_attr.attr, + &iio_const_attr_timestamp_index.dev_attr.attr, + &iio_scan_el_timestamp.dev_attr.attr, + &iio_const_attr_timestamp_type.dev_attr.attr, &iio_dev_attr_in_type.dev_attr.attr, NULL, }; @@ -86,16 +91,21 @@ error_ret: static int ad7476_ring_preenable(struct iio_dev *indio_dev) { struct ad7476_state *st = indio_dev->dev_data; - size_t d_size; + struct iio_ring_buffer *ring = indio_dev->ring; - if (indio_dev->ring->access.set_bytes_per_datum) { - d_size = st->chip_info->storagebits / 8 + sizeof(s64); - if (d_size % 8) - d_size += 8 - (d_size % 8); - indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, - d_size); + st->d_size = ring->scan_count * st->chip_info->storagebits / 8; + + if (ring->scan_timestamp) { + st->d_size += sizeof(s64); + + if (st->d_size % sizeof(s64)) + st->d_size += sizeof(s64) - (st->d_size % sizeof(s64)); } + if (indio_dev->ring->access.set_bytes_per_datum) + indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, + st->d_size); + return 0; } @@ -131,18 +141,12 @@ static void ad7476_poll_bh_to_ring(struct work_struct *work_s) s64 time_ns; __u8 *rxbuf; int b_sent; - size_t d_size; - - /* Ensure the timestamp is 8 byte aligned */ - d_size = st->chip_info->storagebits / 8 + sizeof(s64); - if (d_size % sizeof(s64)) - d_size += sizeof(s64) - (d_size % sizeof(s64)); /* Ensure only one copy of this function running at a time */ if (atomic_inc_return(&st->protect_ring) > 1) return; - rxbuf = kzalloc(d_size, GFP_KERNEL); + rxbuf = kzalloc(st->d_size, GFP_KERNEL); if (rxbuf == NULL) return; @@ -152,7 +156,9 @@ static void ad7476_poll_bh_to_ring(struct work_struct *work_s) time_ns = iio_get_time_ns(); - memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns)); + if (indio_dev->ring->scan_timestamp) + memcpy(rxbuf + st->d_size - sizeof(s64), + &time_ns, sizeof(time_ns)); indio_dev->ring->access.store_to(&sw_ring->buf, rxbuf, time_ns); done: @@ -182,6 +188,7 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->ring->postenable = &iio_triggered_ring_postenable; indio_dev->ring->predisable = &iio_triggered_ring_predisable; indio_dev->ring->scan_el_attrs = &ad7476_scan_el_group; + indio_dev->ring->scan_timestamp = true; INIT_WORK(&st->poll_work, &ad7476_poll_bh_to_ring); -- cgit v1.2.3 From e08d02658cac30a826565d2faebb74586f60d601 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 24 Feb 2011 22:19:48 +0100 Subject: IIO: ADC: AD7887: Update timestamp handling Add timestamp attributes. Revise timestamp handling accordingly. Preset timestamp generation. Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/ad7887.h | 1 + drivers/staging/iio/adc/ad7887_ring.c | 36 ++++++++++++++++++++--------------- 2 files changed, 22 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h index 8c2a218c9496..439c802b38f2 100644 --- a/drivers/staging/iio/adc/ad7887.h +++ b/drivers/staging/iio/adc/ad7887.h @@ -63,6 +63,7 @@ struct ad7887_state { struct regulator *reg; struct work_struct poll_work; atomic_t protect_ring; + size_t d_size; u16 int_vref_mv; bool en_dual; struct spi_transfer xfer[4]; diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c index 6b9cb1f95a1e..2d7fe65049dd 100644 --- a/drivers/staging/iio/adc/ad7887_ring.c +++ b/drivers/staging/iio/adc/ad7887_ring.c @@ -27,6 +27,8 @@ static IIO_SCAN_EL_C(in0, 0, 0, NULL); static IIO_SCAN_EL_C(in1, 1, 0, NULL); +static IIO_SCAN_EL_TIMESTAMP(2); +static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64); static ssize_t ad7887_show_type(struct device *dev, struct device_attribute *attr, @@ -47,6 +49,9 @@ static struct attribute *ad7887_scan_el_attrs[] = { &iio_const_attr_in0_index.dev_attr.attr, &iio_scan_el_in1.dev_attr.attr, &iio_const_attr_in1_index.dev_attr.attr, + &iio_const_attr_timestamp_index.dev_attr.attr, + &iio_scan_el_timestamp.dev_attr.attr, + &iio_const_attr_timestamp_type.dev_attr.attr, &iio_dev_attr_in_type.dev_attr.attr, NULL, }; @@ -118,16 +123,20 @@ static int ad7887_ring_preenable(struct iio_dev *indio_dev) { struct ad7887_state *st = indio_dev->dev_data; struct iio_ring_buffer *ring = indio_dev->ring; - size_t d_size; - if (indio_dev->ring->access.set_bytes_per_datum) { - d_size = st->chip_info->storagebits / 8 + sizeof(s64); - if (d_size % 8) - d_size += 8 - (d_size % 8); - indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, - d_size); + st->d_size = ring->scan_count * st->chip_info->storagebits / 8; + + if (ring->scan_timestamp) { + st->d_size += sizeof(s64); + + if (st->d_size % sizeof(s64)) + st->d_size += sizeof(s64) - (st->d_size % sizeof(s64)); } + if (indio_dev->ring->access.set_bytes_per_datum) + indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, + st->d_size); + switch (ring->scan_mask) { case (1 << 0): st->ring_msg = &st->msg[AD7887_CH0]; @@ -186,20 +195,14 @@ static void ad7887_poll_bh_to_ring(struct work_struct *work_s) s64 time_ns; __u8 *buf; int b_sent; - size_t d_size; unsigned int bytes = ring->scan_count * st->chip_info->storagebits / 8; - /* Ensure the timestamp is 8 byte aligned */ - d_size = bytes + sizeof(s64); - if (d_size % sizeof(s64)) - d_size += sizeof(s64) - (d_size % sizeof(s64)); - /* Ensure only one copy of this function running at a time */ if (atomic_inc_return(&st->protect_ring) > 1) return; - buf = kzalloc(d_size, GFP_KERNEL); + buf = kzalloc(st->d_size, GFP_KERNEL); if (buf == NULL) return; @@ -210,7 +213,9 @@ static void ad7887_poll_bh_to_ring(struct work_struct *work_s) time_ns = iio_get_time_ns(); memcpy(buf, st->data, bytes); - memcpy(buf + d_size - sizeof(s64), &time_ns, sizeof(time_ns)); + if (ring->scan_timestamp) + memcpy(buf + st->d_size - sizeof(s64), + &time_ns, sizeof(time_ns)); indio_dev->ring->access.store_to(&sw_ring->buf, buf, time_ns); done: @@ -241,6 +246,7 @@ int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->ring->predisable = &iio_triggered_ring_predisable; indio_dev->ring->postdisable = &ad7887_ring_postdisable; indio_dev->ring->scan_el_attrs = &ad7887_scan_el_group; + indio_dev->ring->scan_timestamp = true; INIT_WORK(&st->poll_work, &ad7887_poll_bh_to_ring); -- cgit v1.2.3 From dcfb0863eec8ff0a3b2cee13e4f0e5bb5f0c3122 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 24 Feb 2011 22:19:49 +0100 Subject: IIO: ADC: AD7606: Update timestamp handling Add timestamp attributes. Revise timestamp handling accordingly. Preset timestamp generation. Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/ad7606_ring.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c index 9889680232d8..b32cb0dea6d8 100644 --- a/drivers/staging/iio/adc/ad7606_ring.c +++ b/drivers/staging/iio/adc/ad7606_ring.c @@ -30,6 +30,9 @@ static IIO_SCAN_EL_C(in5, 5, 0, NULL); static IIO_SCAN_EL_C(in6, 6, 0, NULL); static IIO_SCAN_EL_C(in7, 7, 0, NULL); +static IIO_SCAN_EL_TIMESTAMP(8); +static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64); + static ssize_t ad7606_show_type(struct device *dev, struct device_attribute *attr, char *buf) @@ -60,6 +63,9 @@ static struct attribute *ad7606_scan_el_attrs[] = { &iio_const_attr_in6_index.dev_attr.attr, &iio_scan_el_in7.dev_attr.attr, &iio_const_attr_in7_index.dev_attr.attr, + &iio_const_attr_timestamp_index.dev_attr.attr, + &iio_scan_el_timestamp.dev_attr.attr, + &iio_const_attr_timestamp_type.dev_attr.attr, &iio_dev_attr_in_type.dev_attr.attr, NULL, }; @@ -133,10 +139,14 @@ static int ad7606_ring_preenable(struct iio_dev *indio_dev) size_t d_size; d_size = st->chip_info->num_channels * - st->chip_info->bits / 8 + sizeof(s64); + st->chip_info->bits / 8; + + if (ring->scan_timestamp) { + d_size += sizeof(s64); - if (d_size % sizeof(s64)) - d_size += sizeof(s64) - (d_size % sizeof(s64)); + if (d_size % sizeof(s64)) + d_size += sizeof(s64) - (d_size % sizeof(s64)); + } if (ring->access.set_bytes_per_datum) ring->access.set_bytes_per_datum(ring, d_size); @@ -210,7 +220,10 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s) } time_ns = iio_get_time_ns(); - memcpy(buf + st->d_size - sizeof(s64), &time_ns, sizeof(time_ns)); + + if (ring->scan_timestamp) + memcpy(buf + st->d_size - sizeof(s64), + &time_ns, sizeof(time_ns)); ring->access.store_to(&sw_ring->buf, buf, time_ns); done: @@ -242,6 +255,7 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->ring->postenable = &iio_triggered_ring_postenable; indio_dev->ring->predisable = &iio_triggered_ring_predisable; indio_dev->ring->scan_el_attrs = &ad7606_scan_el_group; + indio_dev->ring->scan_timestamp = true ; INIT_WORK(&st->poll_work, &ad7606_poll_bh_to_ring); -- cgit v1.2.3 From a2396dfc63d4b133d0b820db978065367529f6ac Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 24 Feb 2011 22:19:50 +0100 Subject: IIO: ADC: AD799x: Update timestamp handling Add timestamp attributes. Revise timestamp handling accordingly. Preset timestamp generation. Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/ad799x.h | 1 + drivers/staging/iio/adc/ad799x_core.c | 12 ++++++++++ drivers/staging/iio/adc/ad799x_ring.c | 43 +++++++++++++---------------------- 3 files changed, 29 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/ad799x.h b/drivers/staging/iio/adc/ad799x.h index 81a20d524b77..a421362c77f9 100644 --- a/drivers/staging/iio/adc/ad799x.h +++ b/drivers/staging/iio/adc/ad799x.h @@ -116,6 +116,7 @@ struct ad799x_state { struct work_struct poll_work; struct work_struct work_thresh; atomic_t protect_ring; + size_t d_size; struct iio_trigger *trig; struct regulator *reg; s64 last_timestamp; diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c index 89ccf375a188..e50841b3ac69 100644 --- a/drivers/staging/iio/adc/ad799x_core.c +++ b/drivers/staging/iio/adc/ad799x_core.c @@ -123,6 +123,9 @@ static AD799X_SCAN_EL(5); static AD799X_SCAN_EL(6); static AD799X_SCAN_EL(7); +static IIO_SCAN_EL_TIMESTAMP(8); +static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64) + static ssize_t ad799x_show_type(struct device *dev, struct device_attribute *attr, char *buf) @@ -471,6 +474,9 @@ static struct attribute *ad7991_5_9_3_4_scan_el_attrs[] = { &iio_const_attr_in2_index.dev_attr.attr, &iio_scan_el_in3.dev_attr.attr, &iio_const_attr_in3_index.dev_attr.attr, + &iio_const_attr_timestamp_index.dev_attr.attr, + &iio_scan_el_timestamp.dev_attr.attr, + &iio_const_attr_timestamp_type.dev_attr.attr, &iio_dev_attr_in_type.dev_attr.attr, NULL, }; @@ -497,6 +503,9 @@ static struct attribute *ad7992_scan_el_attrs[] = { &iio_const_attr_in0_index.dev_attr.attr, &iio_scan_el_in1.dev_attr.attr, &iio_const_attr_in1_index.dev_attr.attr, + &iio_const_attr_timestamp_index.dev_attr.attr, + &iio_scan_el_timestamp.dev_attr.attr, + &iio_const_attr_timestamp_type.dev_attr.attr, &iio_dev_attr_in_type.dev_attr.attr, NULL, }; @@ -541,6 +550,9 @@ static struct attribute *ad7997_8_scan_el_attrs[] = { &iio_const_attr_in6_index.dev_attr.attr, &iio_scan_el_in7.dev_attr.attr, &iio_const_attr_in7_index.dev_attr.attr, + &iio_const_attr_timestamp_index.dev_attr.attr, + &iio_scan_el_timestamp.dev_attr.attr, + &iio_const_attr_timestamp_type.dev_attr.attr, &iio_dev_attr_in_type.dev_attr.attr, NULL, }; diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c index 975cdcbf0830..56abc395f177 100644 --- a/drivers/staging/iio/adc/ad799x_ring.c +++ b/drivers/staging/iio/adc/ad799x_ring.c @@ -73,8 +73,6 @@ static int ad799x_ring_preenable(struct iio_dev *indio_dev) { struct iio_ring_buffer *ring = indio_dev->ring; struct ad799x_state *st = indio_dev->dev_data; - size_t d_size; - unsigned long numvals; /* * Need to figure out the current mode based upon the requested @@ -84,15 +82,19 @@ static int ad799x_ring_preenable(struct iio_dev *indio_dev) if (st->id == ad7997 || st->id == ad7998) ad799x_set_scan_mode(st, ring->scan_mask); - numvals = ring->scan_count; + st->d_size = ring->scan_count * 2; - if (ring->access.set_bytes_per_datum) { - d_size = numvals*2 + sizeof(s64); - if (d_size % 8) - d_size += 8 - (d_size % 8); - ring->access.set_bytes_per_datum(ring, d_size); + if (ring->scan_timestamp) { + st->d_size += sizeof(s64); + + if (st->d_size % sizeof(s64)) + st->d_size += sizeof(s64) - (st->d_size % sizeof(s64)); } + if (indio_dev->ring->access.set_bytes_per_datum) + indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, + st->d_size); + return 0; } @@ -130,29 +132,13 @@ static void ad799x_poll_bh_to_ring(struct work_struct *work_s) s64 time_ns; __u8 *rxbuf; int b_sent; - size_t d_size; u8 cmd; - unsigned long numvals = ring->scan_count; - - /* Ensure the timestamp is 8 byte aligned */ - d_size = numvals*2 + sizeof(s64); - - if (d_size % sizeof(s64)) - d_size += sizeof(s64) - (d_size % sizeof(s64)); - /* Ensure only one copy of this function running at a time */ if (atomic_inc_return(&st->protect_ring) > 1) return; - /* Monitor mode prevents reading. Whilst not currently implemented - * might as well have this test in here in the meantime as it does - * no harm. - */ - if (numvals == 0) - return; - - rxbuf = kmalloc(d_size, GFP_KERNEL); + rxbuf = kmalloc(st->d_size, GFP_KERNEL); if (rxbuf == NULL) return; @@ -177,13 +163,15 @@ static void ad799x_poll_bh_to_ring(struct work_struct *work_s) } b_sent = i2c_smbus_read_i2c_block_data(st->client, - cmd, numvals*2, rxbuf); + cmd, ring->scan_count * 2, rxbuf); if (b_sent < 0) goto done; time_ns = iio_get_time_ns(); - memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns)); + if (ring->scan_timestamp) + memcpy(rxbuf + st->d_size - sizeof(s64), + &time_ns, sizeof(time_ns)); ring->access.store_to(&ring_sw->buf, rxbuf, time_ns); done: @@ -213,6 +201,7 @@ int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->ring->preenable = &ad799x_ring_preenable; indio_dev->ring->postenable = &iio_triggered_ring_postenable; indio_dev->ring->predisable = &iio_triggered_ring_predisable; + indio_dev->ring->scan_timestamp = true; INIT_WORK(&st->poll_work, &ad799x_poll_bh_to_ring); -- cgit v1.2.3 From 85c3c562aa52d863e286049973cd508deb9f869a Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Mon, 28 Feb 2011 20:59:21 +0200 Subject: staging: xgifb: eliminate fbcon_XGI_copyarea() fbcon_XGI_copyarea() implementation is trivial and can be replaced with cfb_copyarea(). Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_accel.c | 9 --------- drivers/staging/xgifb/XGI_accel.h | 2 -- drivers/staging/xgifb/XGI_main.h | 2 -- drivers/staging/xgifb/XGI_main_26.c | 2 +- 4 files changed, 1 insertion(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_accel.c b/drivers/staging/xgifb/XGI_accel.c index 905b34ae5e9b..968ac04c4d52 100644 --- a/drivers/staging/xgifb/XGI_accel.c +++ b/drivers/staging/xgifb/XGI_accel.c @@ -123,12 +123,3 @@ void fbcon_XGI_fillrect(struct fb_info *info, const struct fb_fillrect *rect) cfb_fillrect(info, rect); return; } - -void fbcon_XGI_copyarea(struct fb_info *info, const struct fb_copyarea *area) -{ - cfb_copyarea(info, area); - return; -} - - - diff --git a/drivers/staging/xgifb/XGI_accel.h b/drivers/staging/xgifb/XGI_accel.h index 6cecdf7ca2e2..836ee40cbf7f 100644 --- a/drivers/staging/xgifb/XGI_accel.h +++ b/drivers/staging/xgifb/XGI_accel.h @@ -479,7 +479,5 @@ int fbcon_XGI_sync(struct fb_info *info); extern struct video_info xgi_video_info; void fbcon_XGI_fillrect(struct fb_info *info, const struct fb_fillrect *rect); -void fbcon_XGI_copyarea(struct fb_info *info, const struct fb_copyarea *area); - #endif diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index 1b454148cb78..15d72eece878 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -795,8 +795,6 @@ static int XGIfb_blank(int blank, */ extern void fbcon_XGI_fillrect(struct fb_info *info, const struct fb_fillrect *rect); -extern void fbcon_XGI_copyarea(struct fb_info *info, - const struct fb_copyarea *area); static int XGIfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg); diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 5e69728623b7..6cf2eea0871b 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1739,7 +1739,7 @@ static struct fb_ops XGIfb_ops = { #endif .fb_blank = XGIfb_blank, .fb_fillrect = fbcon_XGI_fillrect, - .fb_copyarea = fbcon_XGI_copyarea, + .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_ioctl = XGIfb_ioctl, /* .fb_mmap = XGIfb_mmap, */ -- cgit v1.2.3 From 1b402967bc0ba7a8b0dd075e6c69c137f227a1eb Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Mon, 28 Feb 2011 20:59:22 +0200 Subject: staging: xgifb: eliminate fbcon_XGI_fillrect() fbcon_XGI_fillrect() implementation is trivial and can be replaced with cfb_fillrect(). Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_accel.c | 9 --------- drivers/staging/xgifb/XGI_accel.h | 2 -- drivers/staging/xgifb/XGI_main.h | 2 -- drivers/staging/xgifb/XGI_main_26.c | 2 +- 4 files changed, 1 insertion(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_accel.c b/drivers/staging/xgifb/XGI_accel.c index 968ac04c4d52..1e4c06c8198b 100644 --- a/drivers/staging/xgifb/XGI_accel.c +++ b/drivers/staging/xgifb/XGI_accel.c @@ -114,12 +114,3 @@ void XGIfb_syncaccel(void) XGI310Sync(); } - -void fbcon_XGI_fillrect(struct fb_info *info, const struct fb_fillrect *rect) -{ - if (!rect->width || !rect->height) - return; - - cfb_fillrect(info, rect); - return; -} diff --git a/drivers/staging/xgifb/XGI_accel.h b/drivers/staging/xgifb/XGI_accel.h index 836ee40cbf7f..a1fb5d39b153 100644 --- a/drivers/staging/xgifb/XGI_accel.h +++ b/drivers/staging/xgifb/XGI_accel.h @@ -478,6 +478,4 @@ int fbcon_XGI_sync(struct fb_info *info); extern struct video_info xgi_video_info; -void fbcon_XGI_fillrect(struct fb_info *info, const struct fb_fillrect *rect); - #endif diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index 15d72eece878..39e15ded7f4f 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -793,8 +793,6 @@ static int XGIfb_blank(int blank, /*static int XGIfb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma); */ -extern void fbcon_XGI_fillrect(struct fb_info *info, - const struct fb_fillrect *rect); static int XGIfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg); diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 6cf2eea0871b..fa97c3796a01 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1738,7 +1738,7 @@ static struct fb_ops XGIfb_ops = { .fb_pan_display = XGIfb_pan_display, #endif .fb_blank = XGIfb_blank, - .fb_fillrect = fbcon_XGI_fillrect, + .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_ioctl = XGIfb_ioctl, -- cgit v1.2.3 From 5b863c34ecd4240e32339f277796654f5ae1feac Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Mon, 28 Feb 2011 20:59:23 +0200 Subject: staging: xgifb: eliminate "accel" field from video_info The value is always false, so the field can be eliminated. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 9 --------- drivers/staging/xgifb/XGIfb.h | 1 - 2 files changed, 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index fa97c3796a01..f2a4a2a6bd71 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1187,7 +1187,6 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, xgi_video_info.org_x = xgi_video_info.org_y = 0; xgi_video_info.video_linelength = info->var.xres_virtual * (xgi_video_info.video_bpp >> 3); - xgi_video_info.accel = 0; switch (xgi_video_info.video_bpp) { case 8: xgi_video_info.DstColor = 0x0000; @@ -1219,7 +1218,6 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, default: xgi_video_info.video_cmap_len = 16; printk(KERN_ERR "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp); - xgi_video_info.accel = 0; break; } } @@ -1635,7 +1633,6 @@ static int XGIfb_ioctl(struct fb_info *info, unsigned int cmd, default: xgi_video_info.video_cmap_len = 16; printk(KERN_ERR "XGIfb: Unsupported accel depth %d", xgi_video_info.video_bpp); - xgi_video_info.accel = 0; break; } @@ -2617,10 +2614,6 @@ static void XGIfb_pre_setmode(void) outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30); outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31); outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F)); - - if (xgi_video_info.accel) - XGIfb_syncaccel(); - } static void XGIfb_post_setmode(void) @@ -3341,8 +3334,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, } - xgi_video_info.accel = 0; - fb_info->flags = FBINFO_FLAG_DEFAULT; fb_info->var = default_var; fb_info->fix = XGIfb_fix; diff --git a/drivers/staging/xgifb/XGIfb.h b/drivers/staging/xgifb/XGIfb.h index b6715ba9b681..8e59e15281b7 100644 --- a/drivers/staging/xgifb/XGIfb.h +++ b/drivers/staging/xgifb/XGIfb.h @@ -193,7 +193,6 @@ struct video_info{ unsigned int pcislot; unsigned int pcifunc; - int accel; unsigned short subsysvendor; unsigned short subsysdevice; -- cgit v1.2.3 From 26046bc16acb3141bd7634458f3f2ed0e56846b3 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Mon, 28 Feb 2011 20:59:24 +0200 Subject: staging: xgifb: delete XGI_accel.[ch] The files contain nothing actually needed by the driver. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/Makefile | 2 +- drivers/staging/xgifb/XGI_accel.c | 116 --------- drivers/staging/xgifb/XGI_accel.h | 481 -------------------------------------- drivers/staging/xgifb/XGI_main.h | 4 - 4 files changed, 1 insertion(+), 602 deletions(-) delete mode 100644 drivers/staging/xgifb/XGI_accel.c delete mode 100644 drivers/staging/xgifb/XGI_accel.h (limited to 'drivers') diff --git a/drivers/staging/xgifb/Makefile b/drivers/staging/xgifb/Makefile index f2ca6b1f4cc6..3c8c7de9eadd 100644 --- a/drivers/staging/xgifb/Makefile +++ b/drivers/staging/xgifb/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_FB_XGI) += xgifb.o -xgifb-y := XGI_main_26.o XGI_accel.o vb_init.o vb_setmode.o vb_util.o vb_ext.o +xgifb-y := XGI_main_26.o vb_init.o vb_setmode.o vb_util.o vb_ext.o diff --git a/drivers/staging/xgifb/XGI_accel.c b/drivers/staging/xgifb/XGI_accel.c deleted file mode 100644 index 1e4c06c8198b..000000000000 --- a/drivers/staging/xgifb/XGI_accel.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * XGI 300/630/730/540/315/550/650/740 frame buffer driver - * for Linux kernels 2.4.x and 2.5.x - * - * 2D acceleration part - * - * Based on the X driver's XGI300_accel.c which is - * Copyright Xavier Ducoin - * Copyright 2002 by Thomas Winischhofer, Vienna, Austria - * and XGI310_accel.c which is - * Copyright 2002 by Thomas Winischhofer, Vienna, Austria - * - * Author: Thomas Winischhofer - * (see http://www.winischhofer.net/ - * for more information and updates) - */ - -//#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifdef CONFIG_MTRR -#include -#endif - -#include "vgatypes.h" -#include "vb_struct.h" -#include "XGIfb.h" -#include "XGI_accel.h" - -static const int XGIALUConv[] = -{ - 0x00, /* dest = 0; 0, GXclear, 0 */ - 0x88, /* dest &= src; DSa, GXand, 0x1 */ - 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */ - 0xCC, /* dest = src; S, GXcopy, 0x3 */ - 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */ - 0xAA, /* dest = dest; D, GXnoop, 0x5 */ - 0x66, /* dest = ^src; DSx, GXxor, 0x6 */ - 0xEE, /* dest |= src; DSo, GXor, 0x7 */ - 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */ - 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */ - 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */ - 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */ - 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */ - 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */ - 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */ - 0xFF, /* dest = 0xFF; 1, GXset, 0xF */ -}; -/* same ROP but with Pattern as Source */ -static const int XGIPatALUConv[] = -{ - 0x00, /* dest = 0; 0, GXclear, 0 */ - 0xA0, /* dest &= src; DPa, GXand, 0x1 */ - 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */ - 0xF0, /* dest = src; P, GXcopy, 0x3 */ - 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */ - 0xAA, /* dest = dest; D, GXnoop, 0x5 */ - 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */ - 0xFA, /* dest |= src; DPo, GXor, 0x7 */ - 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */ - 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */ - 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */ - 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */ - 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */ - 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */ - 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */ - 0xFF, /* dest = 0xFF; 1, GXset, 0xF */ -}; - -static const unsigned char myrops[] = { - 3, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 - }; - -/* 300 series */ -static void -XGI310Sync(void) -{ - XGI310Idle -} - -/* --------------------------------------------------------------------- */ - -/* The exported routines */ - -int XGIfb_initaccel(void) -{ - return(0); -} - -void XGIfb_syncaccel(void) -{ - - XGI310Sync(); - -} diff --git a/drivers/staging/xgifb/XGI_accel.h b/drivers/staging/xgifb/XGI_accel.h deleted file mode 100644 index a1fb5d39b153..000000000000 --- a/drivers/staging/xgifb/XGI_accel.h +++ /dev/null @@ -1,481 +0,0 @@ -/* - * XGI 300/630/730/540/315/550/650/740 frame buffer driver - * for Linux kernels 2.4.x and 2.5.x - * - * 2D acceleration part - * - * Based on the X driver's XGI300_accel.h which is - * Copyright Xavier Ducoin - * Copyright 2002 by Thomas Winischhofer, Vienna, Austria - * and XGI310_accel.h which is - * Copyright 2002 by Thomas Winischhofer, Vienna, Austria - * - * Author: Thomas Winischhofer : - * (see http://www.winischhofer.net/ - * for more information and updates) - */ - -#ifndef _XGIFB_ACCEL_H -#define _XGIFB_ACCEL_H - -/* Definitions for the XGI engine communication. */ - -#define PATREGSIZE 384 /* Pattern register size. 384 bytes @ 0x8300 */ -#define BR(x) (0x8200 | (x) << 2) -#define PBR(x) (0x8300 | (x) << 2) - -/* XGI300 engine commands */ -#define BITBLT 0x00000000 /* Blit */ -#define COLOREXP 0x00000001 /* Color expand */ -#define ENCOLOREXP 0x00000002 /* Enhanced color expand */ -#define MULTIPLE_SCANLINE 0x00000003 /* ? */ -#define LINE 0x00000004 /* Draw line */ -#define TRAPAZOID_FILL 0x00000005 /* Fill trapezoid */ -#define TRANSPARENT_BITBLT 0x00000006 /* Transparent Blit */ - -/* Additional engine commands for 310/325 */ -#define ALPHA_BLEND 0x00000007 /* Alpha blend ? */ -#define A3D_FUNCTION 0x00000008 /* 3D command ? */ -#define CLEAR_Z_BUFFER 0x00000009 /* ? */ -#define GRADIENT_FILL 0x0000000A /* Gradient fill */ -#define STRETCH_BITBLT 0x0000000B /* Stretched Blit */ - -/* source select */ -#define SRCVIDEO 0x00000000 /* source is video RAM */ -#define SRCSYSTEM 0x00000010 /* source is system memory */ -#define SRCCPUBLITBUF SRCSYSTEM /* source is CPU-driven BitBuffer (for color expand) */ -#define SRCAGP 0x00000020 /* source is AGP memory (?) */ - -/* Pattern flags */ -#define PATFG 0x00000000 /* foreground color */ -#define PATPATREG 0x00000040 /* pattern in pattern buffer (0x8300) */ -#define PATMONO 0x00000080 /* mono pattern */ - -/* blitting direction (300 series only) */ -#define X_INC 0x00010000 -#define X_DEC 0x00000000 -#define Y_INC 0x00020000 -#define Y_DEC 0x00000000 - -/* Clipping flags */ -#define NOCLIP 0x00000000 -#define NOMERGECLIP 0x04000000 -#define CLIPENABLE 0x00040000 -#define CLIPWITHOUTMERGE 0x04040000 - -/* Transparency */ -#define OPAQUE 0x00000000 -#define TRANSPARENT 0x00100000 - -/* ? */ -#define DSTAGP 0x02000000 -#define DSTVIDEO 0x02000000 - -/* Line */ -#define LINE_STYLE 0x00800000 -#define NO_RESET_COUNTER 0x00400000 -#define NO_LAST_PIXEL 0x00200000 - -/* Subfunctions for Color/Enhanced Color Expansion (310/325 only) */ -#define COLOR_TO_MONO 0x00100000 -#define AA_TEXT 0x00200000 - -/* Some general registers for 310/325 series */ -#define SRC_ADDR 0x8200 -#define SRC_PITCH 0x8204 -#define AGP_BASE 0x8206 /* color-depth dependent value */ -#define SRC_Y 0x8208 -#define SRC_X 0x820A -#define DST_Y 0x820C -#define DST_X 0x820E -#define DST_ADDR 0x8210 -#define DST_PITCH 0x8214 -#define DST_HEIGHT 0x8216 -#define RECT_WIDTH 0x8218 -#define RECT_HEIGHT 0x821A -#define PAT_FGCOLOR 0x821C -#define PAT_BGCOLOR 0x8220 -#define SRC_FGCOLOR 0x8224 -#define SRC_BGCOLOR 0x8228 -#define MONO_MASK 0x822C -#define LEFT_CLIP 0x8234 -#define TOP_CLIP 0x8236 -#define RIGHT_CLIP 0x8238 -#define BOTTOM_CLIP 0x823A -#define COMMAND_READY 0x823C -#define FIRE_TRIGGER 0x8240 - -#define PATTERN_REG 0x8300 /* 384 bytes pattern buffer */ - -/* Line registers */ -#define LINE_X0 SRC_Y -#define LINE_X1 DST_Y -#define LINE_Y0 SRC_X -#define LINE_Y1 DST_X -#define LINE_COUNT RECT_WIDTH -#define LINE_STYLE_PERIOD RECT_HEIGHT -#define LINE_STYLE_0 MONO_MASK -#define LINE_STYLE_1 0x8230 -#define LINE_XN PATTERN_REG -#define LINE_YN PATTERN_REG+2 - -/* Transparent bitblit registers */ -#define TRANS_DST_KEY_HIGH PAT_FGCOLOR -#define TRANS_DST_KEY_LOW PAT_BGCOLOR -#define TRANS_SRC_KEY_HIGH SRC_FGCOLOR -#define TRANS_SRC_KEY_LOW SRC_BGCOLOR - -/* Queue */ -#define Q_BASE_ADDR 0x85C0 /* Base address of software queue (?) */ -#define Q_WRITE_PTR 0x85C4 /* Current write pointer (?) */ -#define Q_READ_PTR 0x85C8 /* Current read pointer (?) */ -#define Q_STATUS 0x85CC /* queue status */ - - -#define MMIO_IN8(base, offset) \ - *(volatile u8 *)(((u8*)(base)) + (offset)) -#define MMIO_IN16(base, offset) \ - *(volatile u16 *)(void *)(((u8*)(base)) + (offset)) -#define MMIO_IN32(base, offset) \ - *(volatile u32 *)(void *)(((u8*)(base)) + (offset)) -#define MMIO_OUT8(base, offset, val) \ - *(volatile u8 *)(((u8*)(base)) + (offset)) = (val) -#define MMIO_OUT16(base, offset, val) \ - *(volatile u16 *)(void *)(((u8*)(base)) + (offset)) = (val) -#define MMIO_OUT32(base, offset, val) \ - *(volatile u32 *)(void *)(((u8*)(base)) + (offset)) = (val) - - - -/* ------------- XGI 300 series -------------- */ - -/* Macros to do useful things with the XGI BitBLT engine */ - -/* BR(16) (0x8420): - - bit 31 2D engine: 1 is idle, - bit 30 3D engine: 1 is idle, - bit 29 Command queue: 1 is empty - - bits 28:24: Current CPU driven BitBlt buffer stage bit[4:0] - - bits 15:0: Current command queue length - -*/ - -/* TW: BR(16)+2 = 0x8242 */ - -static int xgiCmdQueLen; - -#define XGI300Idle \ - { \ - while( (MMIO_IN16(xgi_video_info.mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \ - while( (MMIO_IN16(xgi_video_info.mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \ - while( (MMIO_IN16(xgi_video_info.mmio_vbase, BR(16)+2) & 0xE000) != 0xE000){}; \ - xgiCmdQueLen=MMIO_IN16(xgi_video_info.mmio_vbase, 0x8240); \ - } -/* TW: (do three times, because 2D engine seems quite unsure about whether or not it's idle) */ - -#define XGI300SetupSRCBase(base) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(0), base);\ - xgiCmdQueLen --; - -#define XGI300SetupSRCPitch(pitch) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT16(xgi_video_info.mmio_vbase, BR(1), pitch);\ - xgiCmdQueLen --; - -#define XGI300SetupSRCXY(x,y) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(2), (x)<<16 | (y) );\ - xgiCmdQueLen --; - -#define XGI300SetupDSTBase(base) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(4), base);\ - xgiCmdQueLen --; - -#define XGI300SetupDSTXY(x,y) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(3), (x)<<16 | (y) );\ - xgiCmdQueLen --; - -#define XGI300SetupDSTRect(x,y) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(5), (y)<<16 | (x) );\ - xgiCmdQueLen --; - -#define XGI300SetupDSTColorDepth(bpp) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT16(xgi_video_info.mmio_vbase, BR(1)+2, bpp);\ - xgiCmdQueLen --; - -#define XGI300SetupRect(w,h) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(6), (h)<<16 | (w) );\ - xgiCmdQueLen --; - -#define XGI300SetupPATFG(color) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(7), color);\ - xgiCmdQueLen --; - -#define XGI300SetupPATBG(color) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(8), color);\ - xgiCmdQueLen --; - -#define XGI300SetupSRCFG(color) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(9), color);\ - xgiCmdQueLen --; - -#define XGI300SetupSRCBG(color) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(10), color);\ - xgiCmdQueLen --; - -/* 0x8224 src colorkey high */ -/* 0x8228 src colorkey low */ -/* 0x821c dest colorkey high */ -/* 0x8220 dest colorkey low */ -#define XGI300SetupSRCTrans(color) \ - if (xgiCmdQueLen <= 1) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, 0x8224, color);\ - MMIO_OUT32(xgi_video_info.mmio_vbase, 0x8228, color);\ - xgiCmdQueLen -= 2; - -#define XGI300SetupDSTTrans(color) \ - if (xgiCmdQueLen <= 1) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, 0x821C, color); \ - MMIO_OUT32(xgi_video_info.mmio_vbase, 0x8220, color); \ - xgiCmdQueLen -= 2; - -#define XGI300SetupMONOPAT(p0,p1) \ - if (xgiCmdQueLen <= 1) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(11), p0);\ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(12), p1);\ - xgiCmdQueLen -= 2; - -#define XGI300SetupClipLT(left,top) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(13), ((left) & 0xFFFF) | (top)<<16 );\ - xgiCmdQueLen--; - -#define XGI300SetupClipRB(right,bottom) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(14), ((right) & 0xFFFF) | (bottom)<<16 );\ - xgiCmdQueLen--; - -/* General */ -#define XGI300SetupROP(rop) \ - xgi_video_info.CommandReg = (rop) << 8; - -#define XGI300SetupCMDFlag(flags) \ - xgi_video_info.CommandReg |= (flags); - -#define XGI300DoCMD \ - if (xgiCmdQueLen <= 1) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(15), xgi_video_info.CommandReg); \ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(16), 0);\ - xgiCmdQueLen -= 2; - -/* Line */ -#define XGI300SetupX0Y0(x,y) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(2), (y)<<16 | (x) );\ - xgiCmdQueLen--; - -#define XGI300SetupX1Y1(x,y) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(3), (y)<<16 | (x) );\ - xgiCmdQueLen--; - -#define XGI300SetupLineCount(c) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT16(xgi_video_info.mmio_vbase, BR(6), c);\ - xgiCmdQueLen--; - -#define XGI300SetupStylePeriod(p) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT16(xgi_video_info.mmio_vbase, BR(6)+2, p);\ - xgiCmdQueLen--; - -#define XGI300SetupStyleLow(ls) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(11), ls);\ - xgiCmdQueLen--; - -#define XGI300SetupStyleHigh(ls) \ - if (xgiCmdQueLen <= 0) XGI300Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, BR(12), ls);\ - xgiCmdQueLen--; - - - -/* ----------- XGI 310/325 series --------------- */ - -/* Q_STATUS: - bit 31 = 1: All engines idle and all queues empty - bit 30 = 1: Hardware Queue (=HW CQ, 2D queue, 3D queue) empty - bit 29 = 1: 2D engine is idle - bit 28 = 1: 3D engine is idle - bit 27 = 1: HW command queue empty - bit 26 = 1: 2D queue empty - bit 25 = 1: 3D queue empty - bit 24 = 1: SW command queue empty - bits 23:16: 2D counter 3 - bits 15:8: 2D counter 2 - bits 7:0: 2D counter 1 - - Where is the command queue length (current amount of commands the queue - can accept) on the 310/325 series? (The current implementation is taken - from 300 series and certainly wrong...) -*/ - -/* TW: FIXME: xgiCmdQueLen is... where....? */ -#define XGI310Idle \ - { \ - while( (MMIO_IN16(xgi_video_info.mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ - while( (MMIO_IN16(xgi_video_info.mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \ - xgiCmdQueLen=MMIO_IN16(xgi_video_info.mmio_vbase, Q_STATUS); \ - } - -#define XGI310SetupSRCBase(base) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, SRC_ADDR, base);\ - xgiCmdQueLen--; - -#define XGI310SetupSRCPitch(pitch) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT16(xgi_video_info.mmio_vbase, SRC_PITCH, pitch);\ - xgiCmdQueLen--; - -#define XGI310SetupSRCXY(x,y) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, SRC_Y, (x)<<16 | (y) );\ - xgiCmdQueLen--; - -#define XGI310SetupDSTBase(base) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, DST_ADDR, base);\ - xgiCmdQueLen--; - -#define XGI310SetupDSTXY(x,y) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, DST_Y, (x)<<16 | (y) );\ - xgiCmdQueLen--; - -#define XGI310SetupDSTRect(x,y) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, DST_PITCH, (y)<<16 | (x) );\ - xgiCmdQueLen--; - -#define XGI310SetupDSTColorDepth(bpp) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT16(xgi_video_info.mmio_vbase, AGP_BASE, bpp);\ - xgiCmdQueLen--; - -#define XGI310SetupRect(w,h) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, RECT_WIDTH, (h)<<16 | (w) );\ - xgiCmdQueLen--; - -#define XGI310SetupPATFG(color) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, PAT_FGCOLOR, color);\ - xgiCmdQueLen--; - -#define XGI310SetupPATBG(color) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, PAT_BGCOLOR, color);\ - xgiCmdQueLen--; - -#define XGI310SetupSRCFG(color) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, SRC_FGCOLOR, color);\ - xgiCmdQueLen--; - -#define XGI310SetupSRCBG(color) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, SRC_BGCOLOR, color);\ - xgiCmdQueLen--; - -#define XGI310SetupSRCTrans(color) \ - if (xgiCmdQueLen <= 1) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, TRANS_SRC_KEY_HIGH, color);\ - MMIO_OUT32(xgi_video_info.mmio_vbase, TRANS_SRC_KEY_LOW, color);\ - xgiCmdQueLen -= 2; - -#define XGI310SetupDSTTrans(color) \ - if (xgiCmdQueLen <= 1) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, TRANS_DST_KEY_HIGH, color); \ - MMIO_OUT32(xgi_video_info.mmio_vbase, TRANS_DST_KEY_LOW, color); \ - xgiCmdQueLen -= 2; - -#define XGI310SetupMONOPAT(p0,p1) \ - if (xgiCmdQueLen <= 1) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, MONO_MASK, p0);\ - MMIO_OUT32(xgi_video_info.mmio_vbase, MONO_MASK+4, p1);\ - xgiCmdQueLen -= 2; - -#define XGI310SetupClipLT(left,top) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, LEFT_CLIP, ((left) & 0xFFFF) | (top)<<16 );\ - xgiCmdQueLen--; - -#define XGI310SetupClipRB(right,bottom) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, RIGHT_CLIP, ((right) & 0xFFFF) | (bottom)<<16 );\ - xgiCmdQueLen--; - -#define XGI310SetupROP(rop) \ - xgi_video_info.CommandReg = (rop) << 8; - -#define XGI310SetupCMDFlag(flags) \ - xgi_video_info.CommandReg |= (flags); - -#define XGI310DoCMD \ - if (xgiCmdQueLen <= 1) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, COMMAND_READY, xgi_video_info.CommandReg); \ - MMIO_OUT32(xgi_video_info.mmio_vbase, FIRE_TRIGGER, 0); \ - xgiCmdQueLen -= 2; - -#define XGI310SetupX0Y0(x,y) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, LINE_X0, (y)<<16 | (x) );\ - xgiCmdQueLen--; - -#define XGI310SetupX1Y1(x,y) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, LINE_X1, (y)<<16 | (x) );\ - xgiCmdQueLen--; - -#define XGI310SetupLineCount(c) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT16(xgi_video_info.mmio_vbase, LINE_COUNT, c);\ - xgiCmdQueLen--; - -#define XGI310SetupStylePeriod(p) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT16(xgi_video_info.mmio_vbase, LINE_STYLE_PERIOD, p);\ - xgiCmdQueLen--; - -#define XGI310SetupStyleLow(ls) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, LINE_STYLE_0, ls);\ - xgiCmdQueLen--; - -#define XGI310SetupStyleHigh(ls) \ - if (xgiCmdQueLen <= 0) XGI310Idle;\ - MMIO_OUT32(xgi_video_info.mmio_vbase, LINE_STYLE_1, ls);\ - xgiCmdQueLen--; - -int XGIfb_initaccel(void); -void XGIfb_syncaccel(void); -int fbcon_XGI_sync(struct fb_info *info); - -extern struct video_info xgi_video_info; - -#endif diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index 39e15ded7f4f..eb0f79aeb380 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -814,10 +814,6 @@ extern unsigned char XGI_SearchModeID(unsigned short ModeNo, static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info); -/* Internal 2D accelerator functions */ -extern int XGIfb_initaccel(void); -extern void XGIfb_syncaccel(void); - /* Internal general routines */ static void XGIfb_search_mode(const char *name); static int XGIfb_validate_mode(int modeindex); -- cgit v1.2.3 From 6653eb317facd4f020ca0a0378867d6f33f9a921 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Mon, 28 Feb 2011 20:59:25 +0200 Subject: staging: xgifb: delete unused module parameter "noaccel" The parameter is not used by the driver. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index f2a4a2a6bd71..c569d9744e81 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -3435,7 +3435,6 @@ static char *forcecrt2type = NULL; static int forcecrt1 = -1; static int pdc = -1; static int pdc1 = -1; -static int noaccel = -1; static int noypan = -1; static int nomax = -1; static int userom = -1; @@ -3456,7 +3455,6 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("XGITECH , Others"); module_param(mem, int, 0); -module_param(noaccel, int, 0); module_param(noypan, int, 0); module_param(nomax, int, 0); module_param(userom, int, 0); @@ -3490,10 +3488,6 @@ MODULE_PARM_DESC(mem, "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n" "for XFree86 4.x/X.org 6.7 and later.\n"); -MODULE_PARM_DESC(noaccel, - "\nIf set to anything other than 0, 2D acceleration will be disabled.\n" - "(default: 0)\n"); - MODULE_PARM_DESC(noypan, "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n" "will be performed by redrawing the screen. (default: 0)\n"); -- cgit v1.2.3 From c750665850dfed34d3ff0f73ddf367cc7b729b77 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 28 Feb 2011 19:27:06 +0200 Subject: staging/easycap: add first level indentation to easycap_main Add first level indentation to easayca_main.c This created around 300 lines over 80 characters. Around 100 of straight forward once were fixed in this patch. The another 200 require more code movement and need to be fixed later Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_main.c | 4566 ++++++++++++++++---------------- 1 file changed, 2235 insertions(+), 2331 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index fc1a1781227e..e33c3cb7b397 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -125,89 +125,87 @@ const char *strerror(int err) * THIS ROUTINE DOES NOT DETECT DUPLICATE OCCURRENCES OF POINTER peasycap */ /*---------------------------------------------------------------------------*/ -int -isdongle(struct easycap *peasycap) +int isdongle(struct easycap *peasycap) { -int k; -if (NULL == peasycap) - return -2; -for (k = 0; k < DONGLE_MANY; k++) { - if (easycapdc60_dongle[k].peasycap == peasycap) { - peasycap->isdongle = k; - return k; + int k; + if (NULL == peasycap) + return -2; + for (k = 0; k < DONGLE_MANY; k++) { + if (easycapdc60_dongle[k].peasycap == peasycap) { + peasycap->isdongle = k; + return k; + } } -} -return -1; + return -1; } /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ static int easycap_open(struct inode *inode, struct file *file) { -#ifndef EASYCAP_IS_VIDEODEV_CLIENT -struct usb_interface *pusb_interface; -#else -struct video_device *pvideo_device; -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -struct easycap *peasycap; -int rc; + #ifndef EASYCAP_IS_VIDEODEV_CLIENT + struct usb_interface *pusb_interface; + #else + struct video_device *pvideo_device; + #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ + struct easycap *peasycap; + int rc; -JOT(4, "\n"); -SAY("==========OPEN=========\n"); + JOT(4, "\n"); + SAY("==========OPEN=========\n"); /*---------------------------------------------------------------------------*/ #ifndef EASYCAP_IS_VIDEODEV_CLIENT -if (NULL == inode) { - SAY("ERROR: inode is NULL.\n"); - return -EFAULT; -} -pusb_interface = usb_find_interface(&easycap_usb_driver, iminor(inode)); -if (!pusb_interface) { - SAY("ERROR: pusb_interface is NULL.\n"); - return -EFAULT; -} -peasycap = usb_get_intfdata(pusb_interface); + if (NULL == inode) { + SAY("ERROR: inode is NULL.\n"); + return -EFAULT; + } + pusb_interface = usb_find_interface(&easycap_usb_driver, iminor(inode)); + if (!pusb_interface) { + SAY("ERROR: pusb_interface is NULL.\n"); + return -EFAULT; + } + peasycap = usb_get_intfdata(pusb_interface); /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #else -pvideo_device = video_devdata(file); -if (NULL == pvideo_device) { - SAY("ERROR: pvideo_device is NULL.\n"); - return -EFAULT; -} -peasycap = (struct easycap *)video_get_drvdata(pvideo_device); + pvideo_device = video_devdata(file); + if (NULL == pvideo_device) { + SAY("ERROR: pvideo_device is NULL.\n"); + return -EFAULT; + } + peasycap = (struct easycap *)video_get_drvdata(pvideo_device); #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} else { - JOM(16, "peasycap->pusb_device=%p\n", peasycap->pusb_device); -} -file->private_data = peasycap; -rc = wakeup_device(peasycap->pusb_device); -if (0 == rc) - JOM(8, "wakeup_device() OK\n"); -else { - SAM("ERROR: wakeup_device() returned %i\n", rc); - if (-ENODEV == rc) - SAM("ERROR: wakeup_device() returned -ENODEV\n"); - else - SAM("ERROR: wakeup_device() returned %i\n", rc); - return rc; -} -peasycap->input = 0; -rc = reset(peasycap); -if (rc) { - SAM("ERROR: reset() returned %i\n", rc); - return -EFAULT; -} -return 0; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + return -EFAULT; + } + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } else { + JOM(16, "peasycap->pusb_device=%p\n", peasycap->pusb_device); + } + file->private_data = peasycap; + rc = wakeup_device(peasycap->pusb_device); + if (0 == rc) + JOM(8, "wakeup_device() OK\n"); + else { + SAM("ERROR: wakeup_device() rc = %i\n", rc); + if (-ENODEV == rc) + SAM("ERROR: wakeup_device() returned -ENODEV\n"); + else + SAM("ERROR: wakeup_device() rc = %i\n", rc); + return rc; + } + peasycap->input = 0; + rc = reset(peasycap); + if (rc) { + SAM("ERROR: reset() rc = %i\n", rc); + return -EFAULT; + } + return 0; } /*****************************************************************************/ @@ -221,15 +219,16 @@ return 0; /*---------------------------------------------------------------------------*/ static int reset(struct easycap *peasycap) { -struct easycap_standard const *peasycap_standard; -int i, rc, input, rate; -bool ntsc, other; + struct easycap_standard const *peasycap_standard; + int i, rc, input, rate; + bool ntsc, other; + int fmtidx; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -input = peasycap->input; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + input = peasycap->input; /*---------------------------------------------------------------------------*/ /* @@ -242,74 +241,70 @@ input = peasycap->input; * COMPLETE, SO SHOULD NOT BE INVOKED WITHOUT GOOD REASON. */ /*---------------------------------------------------------------------------*/ -other = false; -if (true == peasycap->ntsc) - JOM(8, "true=peasycap->ntsc\n"); -else - JOM(8, "false=peasycap->ntsc\n"); -rate = ready_saa(peasycap->pusb_device); -if (0 > rate) { - JOM(8, "not ready to capture after %i ms ...\n", PATIENCE); - if (true == peasycap->ntsc) { - JOM(8, "... trying PAL ...\n"); ntsc = false; - } else { - JOM(8, "... trying NTSC ...\n"); ntsc = true; -} -rc = setup_stk(peasycap->pusb_device, ntsc); -if (0 == rc) - JOM(4, "setup_stk() OK\n"); -else { - SAM("ERROR: setup_stk() returned %i\n", rc); - return -EFAULT; -} -rc = setup_saa(peasycap->pusb_device, ntsc); -if (0 == rc) - JOM(4, "setup_saa() OK\n"); -else { - SAM("ERROR: setup_saa() returned %i\n", rc); - return -EFAULT; -} -rate = ready_saa(peasycap->pusb_device); -if (0 > rate) { - JOM(8, "not ready to capture after %i ms ...\n", PATIENCE); - JOM(8, "... saa register 0x1F has 0x%02X\n", - read_saa(peasycap->pusb_device, 0x1F)); - ntsc = peasycap->ntsc; + other = false; + JOM(8, "peasycap->ntsc=%d\n", peasycap->ntsc); + + rate = ready_saa(peasycap->pusb_device); + if (0 > rate) { + JOM(8, "not ready to capture after %i ms ...\n", PATIENCE); + if (true == peasycap->ntsc) { + JOM(8, "... trying PAL ...\n"); ntsc = false; + } else { + JOM(8, "... trying NTSC ...\n"); ntsc = true; + } + rc = setup_stk(peasycap->pusb_device, ntsc); + if (0 == rc) + JOM(4, "setup_stk() OK\n"); + else { + SAM("ERROR: setup_stk() rc = %i\n", rc); + return -EFAULT; + } + rc = setup_saa(peasycap->pusb_device, ntsc); + if (0 == rc) + JOM(4, "setup_saa() OK\n"); + else { + SAM("ERROR: setup_saa() rc = %i\n", rc); + return -EFAULT; + } + rate = ready_saa(peasycap->pusb_device); + if (0 > rate) { + JOM(8, "not ready to capture after %i ms ...\n", PATIENCE); + JOM(8, "... saa register 0x1F has 0x%02X\n", + read_saa(peasycap->pusb_device, 0x1F)); + ntsc = peasycap->ntsc; + } else { + JOM(8, "... success at second try: %i=rate\n", rate); + ntsc = (0 < (rate/2)) ? true : false ; + other = true; + } } else { - JOM(8, "... success at second try: %i=rate\n", rate); - ntsc = (0 < (rate/2)) ? true : false ; - other = true; + JOM(8, "... success at first try: %i=rate\n", rate); + ntsc = (0 < rate/2) ? true : false ; } -} else { - JOM(8, "... success at first try: %i=rate\n", rate); - ntsc = (0 < rate/2) ? true : false ; -} -if (true == ntsc) - JOM(8, "true=ntsc\n"); -else - JOM(8, "false=ntsc\n"); -/*---------------------------------------------------------------------------*/ - -rc = setup_stk(peasycap->pusb_device, ntsc); -if (0 == rc) - JOM(4, "setup_stk() OK\n"); -else { - SAM("ERROR: setup_stk() returned %i\n", rc); - return -EFAULT; -} -rc = setup_saa(peasycap->pusb_device, ntsc); -if (0 == rc) - JOM(4, "setup_saa() OK\n"); -else { - SAM("ERROR: setup_saa() returned %i\n", rc); - return -EFAULT; -} + JOM(8, "ntsc=%d\n", ntsc); +/*---------------------------------------------------------------------------*/ -for (i = 0; i < 180; i++) - peasycap->merit[i] = 0; -peasycap->video_eof = 0; -peasycap->audio_eof = 0; -do_gettimeofday(&peasycap->timeval7); + rc = setup_stk(peasycap->pusb_device, ntsc); + if (0 == rc) + JOM(4, "setup_stk() OK\n"); + else { + SAM("ERROR: setup_stk() rc = %i\n", rc); + return -EFAULT; + } + rc = setup_saa(peasycap->pusb_device, ntsc); + if (0 == rc) + JOM(4, "setup_saa() OK\n"); + else { + SAM("ERROR: setup_saa() rc = %i\n", rc); + return -EFAULT; + } + + for (i = 0; i < 180; i++) + peasycap->merit[i] = 0; + + peasycap->video_eof = 0; + peasycap->audio_eof = 0; + do_gettimeofday(&peasycap->timeval7); /*---------------------------------------------------------------------------*/ /* * RESTORE INPUT AND FORCE REFRESH OF STANDARD, FORMAT, ETC. @@ -317,86 +312,75 @@ do_gettimeofday(&peasycap->timeval7); * WHILE THIS PROCEDURE IS IN PROGRESS, SOME IOCTL COMMANDS WILL RETURN -EBUSY. */ /*---------------------------------------------------------------------------*/ -peasycap->input = -8192; -peasycap->standard_offset = -8192; -if (true == other) { - peasycap_standard = &easycap_standard[0]; - while (0xFFFF != peasycap_standard->mask) { - if (true == ntsc) { - if (NTSC_M == peasycap_standard->v4l2_standard.index) { - peasycap->inputset[input].standard_offset = - peasycap_standard - - &easycap_standard[0]; - break; - } - } else { - if (PAL_BGHIN == - peasycap_standard->v4l2_standard.index) { + peasycap->input = -8192; + peasycap->standard_offset = -8192; + fmtidx = ntsc ? NTSC_M : PAL_BGHIN; + if (other) { + peasycap_standard = &easycap_standard[0]; + while (0xFFFF != peasycap_standard->mask) { + if (fmtidx == peasycap_standard->v4l2_standard.index) { peasycap->inputset[input].standard_offset = - peasycap_standard - - &easycap_standard[0]; + peasycap_standard - easycap_standard; break; } + peasycap_standard++; } - peasycap_standard++; - } - if (0xFFFF == peasycap_standard->mask) { - SAM("ERROR: standard not found\n"); - return -EINVAL; + if (0xFFFF == peasycap_standard->mask) { + SAM("ERROR: standard not found\n"); + return -EINVAL; + } + JOM(8, "%i=peasycap->inputset[%i].standard_offset\n", + peasycap->inputset[input].standard_offset, input); } -JOM(8, "%i=peasycap->inputset[%i].standard_offset\n", - peasycap->inputset[input].standard_offset, input); -} -peasycap->format_offset = -8192; -peasycap->brightness = -8192; -peasycap->contrast = -8192; -peasycap->saturation = -8192; -peasycap->hue = -8192; + peasycap->format_offset = -8192; + peasycap->brightness = -8192; + peasycap->contrast = -8192; + peasycap->saturation = -8192; + peasycap->hue = -8192; -rc = newinput(peasycap, input); + rc = newinput(peasycap, input); -if (0 == rc) + if (rc) { + SAM("ERROR: newinput(.,%i) rc = %i\n", rc, input); + return -EFAULT; + } JOM(4, "restored input, standard and format\n"); -else { - SAM("ERROR: newinput(.,%i) returned %i\n", rc, input); - return -EFAULT; -} -if (true == peasycap->ntsc) - JOM(8, "true=peasycap->ntsc\n"); -else - JOM(8, "false=peasycap->ntsc\n"); - -if (0 > peasycap->input) { - SAM("MISTAKE: %i=peasycap->input\n", peasycap->input); - return -ENOENT; -} -if (0 > peasycap->standard_offset) { - SAM("MISTAKE: %i=peasycap->standard_offset\n", - peasycap->standard_offset); - return -ENOENT; -} -if (0 > peasycap->format_offset) { - SAM("MISTAKE: %i=peasycap->format_offset\n", - peasycap->format_offset); - return -ENOENT; -} -if (0 > peasycap->brightness) { - SAM("MISTAKE: %i=peasycap->brightness\n", peasycap->brightness); - return -ENOENT; -} -if (0 > peasycap->contrast) { - SAM("MISTAKE: %i=peasycap->contrast\n", peasycap->contrast); - return -ENOENT; -} -if (0 > peasycap->saturation) { - SAM("MISTAKE: %i=peasycap->saturation\n", peasycap->saturation); - return -ENOENT; -} -if (0 > peasycap->hue) { - SAM("MISTAKE: %i=peasycap->hue\n", peasycap->hue); - return -ENOENT; -} -return 0; + + JOM(8, "true=peasycap->ntsc %d\n", peasycap->ntsc); + + if (0 > peasycap->input) { + SAM("MISTAKE: %i=peasycap->input\n", peasycap->input); + return -ENOENT; + } + if (0 > peasycap->standard_offset) { + SAM("MISTAKE: %i=peasycap->standard_offset\n", + peasycap->standard_offset); + return -ENOENT; + } + if (0 > peasycap->format_offset) { + SAM("MISTAKE: %i=peasycap->format_offset\n", + peasycap->format_offset); + return -ENOENT; + } + if (0 > peasycap->brightness) { + SAM("MISTAKE: %i=peasycap->brightness\n", + peasycap->brightness); + return -ENOENT; + } + if (0 > peasycap->contrast) { + SAM("MISTAKE: %i=peasycap->contrast\n", peasycap->contrast); + return -ENOENT; + } + if (0 > peasycap->saturation) { + SAM("MISTAKE: %i=peasycap->saturation\n", + peasycap->saturation); + return -ENOENT; + } + if (0 > peasycap->hue) { + SAM("MISTAKE: %i=peasycap->hue\n", peasycap->hue); + return -ENOENT; + } + return 0; } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ @@ -418,21 +402,21 @@ return 0; int newinput(struct easycap *peasycap, int input) { -int rc, k, m, mood, off; -int inputnow, video_idlenow, audio_idlenow; -bool resubmit; + int rc, k, m, mood, off; + int inputnow, video_idlenow, audio_idlenow; + bool resubmit; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -JOM(8, "%i=input sought\n", input); + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + JOM(8, "%i=input sought\n", input); -if (0 > input && INPUT_MANY <= input) - return -ENOENT; -inputnow = peasycap->input; -if (input == inputnow) - return 0; + if (0 > input && INPUT_MANY <= input) + return -ENOENT; + inputnow = peasycap->input; + if (input == inputnow) + return 0; /*---------------------------------------------------------------------------*/ /* * IF STREAMING IS IN PROGRESS THE URBS ARE KILLED AT THIS @@ -441,183 +425,187 @@ if (input == inputnow) * ROUTINE. */ /*---------------------------------------------------------------------------*/ -video_idlenow = peasycap->video_idle; -audio_idlenow = peasycap->audio_idle; + video_idlenow = peasycap->video_idle; + audio_idlenow = peasycap->audio_idle; -peasycap->video_idle = 1; -peasycap->audio_idle = 1; -if (peasycap->video_isoc_streaming) { - resubmit = true; - kill_video_urbs(peasycap); -} else - resubmit = false; + peasycap->video_idle = 1; + peasycap->audio_idle = 1; + if (peasycap->video_isoc_streaming) { + resubmit = true; + kill_video_urbs(peasycap); + } else { + resubmit = false; + } /*---------------------------------------------------------------------------*/ -if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -ENODEV; -} -rc = usb_set_interface(peasycap->pusb_device, - peasycap->video_interface, - peasycap->video_altsetting_off); -if (rc) { - SAM("ERROR: usb_set_interface() returned %i\n", rc); - return -EFAULT; -} -rc = stop_100(peasycap->pusb_device); -if (rc) { - SAM("ERROR: stop_100() returned %i\n", rc); - return -EFAULT; -} -for (k = 0; k < FIELD_BUFFER_MANY; k++) { - for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) - memset(peasycap->field_buffer[k][m].pgo, 0, PAGE_SIZE); -} -for (k = 0; k < FRAME_BUFFER_MANY; k++) { - for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) - memset(peasycap->frame_buffer[k][m].pgo, 0, PAGE_SIZE); -} -peasycap->field_page = 0; -peasycap->field_read = 0; -peasycap->field_fill = 0; - -peasycap->frame_read = 0; -peasycap->frame_fill = 0; -for (k = 0; k < peasycap->input; k++) { - (peasycap->frame_fill)++; - if (peasycap->frame_buffer_many <= peasycap->frame_fill) - peasycap->frame_fill = 0; -} -peasycap->input = input; -select_input(peasycap->pusb_device, peasycap->input, 9); + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -ENODEV; + } + rc = usb_set_interface(peasycap->pusb_device, + peasycap->video_interface, + peasycap->video_altsetting_off); + if (rc) { + SAM("ERROR: usb_set_interface() rc = %i\n", rc); + return -EFAULT; + } + rc = stop_100(peasycap->pusb_device); + if (rc) { + SAM("ERROR: stop_100() rc = %i\n", rc); + return -EFAULT; + } + for (k = 0; k < FIELD_BUFFER_MANY; k++) { + for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) + memset(peasycap->field_buffer[k][m].pgo, 0, PAGE_SIZE); + } + for (k = 0; k < FRAME_BUFFER_MANY; k++) { + for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) + memset(peasycap->frame_buffer[k][m].pgo, 0, PAGE_SIZE); + } + peasycap->field_page = 0; + peasycap->field_read = 0; + peasycap->field_fill = 0; + + peasycap->frame_read = 0; + peasycap->frame_fill = 0; + for (k = 0; k < peasycap->input; k++) { + (peasycap->frame_fill)++; + if (peasycap->frame_buffer_many <= peasycap->frame_fill) + peasycap->frame_fill = 0; + } + peasycap->input = input; + select_input(peasycap->pusb_device, peasycap->input, 9); /*---------------------------------------------------------------------------*/ -if (input == peasycap->inputset[input].input) { - off = peasycap->inputset[input].standard_offset; - if (off != peasycap->standard_offset) { - rc = adjust_standard(peasycap, + if (input == peasycap->inputset[input].input) { + off = peasycap->inputset[input].standard_offset; + if (off != peasycap->standard_offset) { + rc = adjust_standard(peasycap, easycap_standard[off].v4l2_standard.id); - if (rc) { - SAM("ERROR: adjust_standard() returned %i\n", rc); - return -EFAULT; - } - JOM(8, "%i=peasycap->standard_offset\n", - peasycap->standard_offset); - } else { - JOM(8, "%i=peasycap->standard_offset unchanged\n", + if (rc) { + SAM("ERROR: adjust_standard() rc = %i\n", rc); + return -EFAULT; + } + JOM(8, "%i=peasycap->standard_offset\n", + peasycap->standard_offset); + } else { + JOM(8, "%i=peasycap->standard_offset unchanged\n", peasycap->standard_offset); - } - off = peasycap->inputset[input].format_offset; - if (off != peasycap->format_offset) { - rc = adjust_format(peasycap, - easycap_format[off].v4l2_format.fmt.pix.width, - easycap_format[off].v4l2_format.fmt.pix.height, - easycap_format[off].v4l2_format.fmt.pix.pixelformat, - easycap_format[off].v4l2_format.fmt.pix.field, false); - if (0 > rc) { - SAM("ERROR: adjust_format() returned %i\n", rc); - return -EFAULT; } - JOM(8, "%i=peasycap->format_offset\n", peasycap->format_offset); - } else { - JOM(8, "%i=peasycap->format_offset unchanged\n", - peasycap->format_offset); - } - mood = peasycap->inputset[input].brightness; - if (mood != peasycap->brightness) { - rc = adjust_brightness(peasycap, mood); - if (rc) { - SAM("ERROR: adjust_brightness returned %i\n", rc); - return -EFAULT; + off = peasycap->inputset[input].format_offset; + if (off != peasycap->format_offset) { + struct v4l2_pix_format *pix = + &easycap_format[off].v4l2_format.fmt.pix; + rc = adjust_format(peasycap, + pix->width, pix->height, + pix->pixelformat, pix->field, false); + if (0 > rc) { + SAM("ERROR: adjust_format() rc = %i\n", rc); + return -EFAULT; + } + JOM(8, "%i=peasycap->format_offset\n", + peasycap->format_offset); + } else { + JOM(8, "%i=peasycap->format_offset unchanged\n", + peasycap->format_offset); } - JOM(8, "%i=peasycap->brightness\n", peasycap->brightness); - } - mood = peasycap->inputset[input].contrast; - if (mood != peasycap->contrast) { - rc = adjust_contrast(peasycap, mood); - if (rc) { - SAM("ERROR: adjust_contrast returned %i\n", rc); - return -EFAULT; + mood = peasycap->inputset[input].brightness; + if (mood != peasycap->brightness) { + rc = adjust_brightness(peasycap, mood); + if (rc) { + SAM("ERROR: adjust_brightness rc = %i\n", rc); + return -EFAULT; + } + JOM(8, "%i=peasycap->brightness\n", + peasycap->brightness); } - JOM(8, "%i=peasycap->contrast\n", peasycap->contrast); - } - mood = peasycap->inputset[input].saturation; - if (mood != peasycap->saturation) { - rc = adjust_saturation(peasycap, mood); - if (rc) { - SAM("ERROR: adjust_saturation returned %i\n", rc); - return -EFAULT; + mood = peasycap->inputset[input].contrast; + if (mood != peasycap->contrast) { + rc = adjust_contrast(peasycap, mood); + if (rc) { + SAM("ERROR: adjust_contrast rc = %i\n", rc); + return -EFAULT; + } + JOM(8, "%i=peasycap->contrast\n", peasycap->contrast); } - JOM(8, "%i=peasycap->saturation\n", peasycap->saturation); - } - mood = peasycap->inputset[input].hue; - if (mood != peasycap->hue) { - rc = adjust_hue(peasycap, mood); - if (rc) { - SAM("ERROR: adjust_hue returned %i\n", rc); - return -EFAULT; + mood = peasycap->inputset[input].saturation; + if (mood != peasycap->saturation) { + rc = adjust_saturation(peasycap, mood); + if (rc) { + SAM("ERROR: adjust_saturation rc = %i\n", rc); + return -EFAULT; + } + JOM(8, "%i=peasycap->saturation\n", + peasycap->saturation); + } + mood = peasycap->inputset[input].hue; + if (mood != peasycap->hue) { + rc = adjust_hue(peasycap, mood); + if (rc) { + SAM("ERROR: adjust_hue rc = %i\n", rc); + return -EFAULT; + } + JOM(8, "%i=peasycap->hue\n", peasycap->hue); } - JOM(8, "%i=peasycap->hue\n", peasycap->hue); + } else { + SAM("MISTAKE: easycap.inputset[%i] unpopulated\n", input); + return -ENOENT; } -} else { - SAM("MISTAKE: easycap.inputset[%i] unpopulated\n", input); - return -ENOENT; -} /*---------------------------------------------------------------------------*/ -if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -ENODEV; -} -rc = usb_set_interface(peasycap->pusb_device, - peasycap->video_interface, - peasycap->video_altsetting_on); -if (rc) { - SAM("ERROR: usb_set_interface() returned %i\n", rc); - return -EFAULT; -} -rc = start_100(peasycap->pusb_device); -if (rc) { - SAM("ERROR: start_100() returned %i\n", rc); - return -EFAULT; -} -if (true == resubmit) - submit_video_urbs(peasycap); + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -ENODEV; + } + rc = usb_set_interface(peasycap->pusb_device, + peasycap->video_interface, + peasycap->video_altsetting_on); + if (rc) { + SAM("ERROR: usb_set_interface() rc = %i\n", rc); + return -EFAULT; + } + rc = start_100(peasycap->pusb_device); + if (rc) { + SAM("ERROR: start_100() rc = %i\n", rc); + return -EFAULT; + } + if (true == resubmit) + submit_video_urbs(peasycap); -peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1; -peasycap->video_idle = video_idlenow; -peasycap->audio_idle = audio_idlenow; -peasycap->video_junk = 0; + peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1; + peasycap->video_idle = video_idlenow; + peasycap->audio_idle = audio_idlenow; + peasycap->video_junk = 0; -return 0; + return 0; } /*****************************************************************************/ int submit_video_urbs(struct easycap *peasycap) { -struct data_urb *pdata_urb; -struct urb *purb; -struct list_head *plist_head; -int j, isbad, nospc, m, rc; -int isbuf; - -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} + struct data_urb *pdata_urb; + struct urb *purb; + struct list_head *plist_head; + int j, isbad, nospc, m, rc; + int isbuf; -if (NULL == peasycap->purb_video_head) { - SAY("ERROR: peasycap->urb_video_head uninitialized\n"); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); - return -ENODEV; -} -if (!peasycap->video_isoc_streaming) { - JOM(4, "submission of all video urbs\n"); - isbad = 0; nospc = 0; m = 0; - list_for_each(plist_head, (peasycap->purb_video_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (NULL != pdata_urb) { - purb = pdata_urb->purb; - if (NULL != purb) { + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + + if (NULL == peasycap->purb_video_head) { + SAY("ERROR: peasycap->urb_video_head uninitialized\n"); + return -EFAULT; + } + if (NULL == peasycap->pusb_device) { + SAY("ERROR: peasycap->pusb_device is NULL\n"); + return -ENODEV; + } + if (!peasycap->video_isoc_streaming) { + JOM(4, "submission of all video urbs\n"); + isbad = 0; nospc = 0; m = 0; + list_for_each(plist_head, (peasycap->purb_video_head)) { + pdata_urb = list_entry(plist_head, + struct data_urb, list_head); + if (pdata_urb && pdata_urb->purb) { + purb = pdata_urb->purb; isbuf = pdata_urb->isbuf; purb->interval = 1; purb->dev = peasycap->pusb_device; @@ -635,22 +623,18 @@ if (!peasycap->video_isoc_streaming) { purb->number_of_packets = peasycap->video_isoc_framesperdesc; - for (j = 0; j < peasycap-> - video_isoc_framesperdesc; j++) { - purb->iso_frame_desc[j]. - offset = j * - peasycap-> - video_isoc_maxframesize; - purb->iso_frame_desc[j]. - length = peasycap-> - video_isoc_maxframesize; - } + for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) { + purb->iso_frame_desc[j]. offset = + j * peasycap->video_isoc_maxframesize; + purb->iso_frame_desc[j]. length = + peasycap->video_isoc_maxframesize; + } rc = usb_submit_urb(purb, GFP_KERNEL); if (rc) { isbad++; SAM("ERROR: usb_submit_urb() failed " - "for urb with rc:-%s\n", + "for urb with rc:-%s\n", strerror(rc)); if (rc == -ENOSPC) nospc++; @@ -660,74 +644,68 @@ if (!peasycap->video_isoc_streaming) { } else { isbad++; } - } else { - isbad++; } - } - if (nospc) { - SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc); - SAM("..... possibly inadequate USB bandwidth\n"); - peasycap->video_eof = 1; - } + if (nospc) { + SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc); + SAM("..... possibly inadequate USB bandwidth\n"); + peasycap->video_eof = 1; + } - if (isbad) { - JOM(4, "attempting cleanup instead of submitting\n"); - list_for_each(plist_head, (peasycap->purb_video_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, - list_head); - if (NULL != pdata_urb) { - purb = pdata_urb->purb; - if (NULL != purb) - usb_kill_urb(purb); + if (isbad) { + JOM(4, "attempting cleanup instead of submitting\n"); + list_for_each(plist_head, (peasycap->purb_video_head)) { + pdata_urb = list_entry(plist_head, + struct data_urb, list_head); + if (NULL != pdata_urb) { + purb = pdata_urb->purb; + if (NULL != purb) + usb_kill_urb(purb); + } } + peasycap->video_isoc_streaming = 0; + } else { + peasycap->video_isoc_streaming = 1; + JOM(4, "submitted %i video urbs\n", m); } - peasycap->video_isoc_streaming = 0; } else { - peasycap->video_isoc_streaming = 1; - JOM(4, "submitted %i video urbs\n", m); + JOM(4, "already streaming video urbs\n"); } -} else { - JOM(4, "already streaming video urbs\n"); -} -return 0; + return 0; } /*****************************************************************************/ -int -kill_video_urbs(struct easycap *peasycap) +int kill_video_urbs(struct easycap *peasycap) { -int m; -struct list_head *plist_head; -struct data_urb *pdata_urb; + int m; + struct list_head *plist_head; + struct data_urb *pdata_urb; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (peasycap->video_isoc_streaming) { - if (NULL != peasycap->purb_video_head) { - peasycap->video_isoc_streaming = 0; - JOM(4, "killing video urbs\n"); - m = 0; - list_for_each(plist_head, (peasycap->purb_video_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, - list_head); - if (NULL != pdata_urb) { - if (NULL != pdata_urb->purb) { - usb_kill_urb(pdata_urb->purb); - m++; - } - } - } - JOM(4, "%i video urbs killed\n", m); - } else { + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (!peasycap->video_isoc_streaming) { + JOM(8, "%i=video_isoc_streaming, no video urbs killed\n", + peasycap->video_isoc_streaming); + return 0; + } + if (!peasycap->purb_video_head) { SAM("ERROR: peasycap->purb_video_head is NULL\n"); return -EFAULT; } -} else { - JOM(8, "%i=video_isoc_streaming, no video urbs killed\n", - peasycap->video_isoc_streaming); -} -return 0; + + peasycap->video_isoc_streaming = 0; + JOM(4, "killing video urbs\n"); + m = 0; + list_for_each(plist_head, (peasycap->purb_video_head)) { + pdata_urb = list_entry(plist_head, struct data_urb, list_head); + if (pdata_urb && pdata_urb->purb) { + usb_kill_urb(pdata_urb->purb); + m++; + } + } + JOM(4, "%i video urbs killed\n", m); + + return 0; } /****************************************************************************/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ @@ -735,32 +713,27 @@ return 0; static int easycap_release(struct inode *inode, struct file *file) { #ifndef EASYCAP_IS_VIDEODEV_CLIENT -struct easycap *peasycap; + struct easycap *peasycap; -JOT(4, "\n"); -peasycap = file->private_data; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL.\n"); - SAY("ending unsuccessfully\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return -EFAULT; -} -if (0 != kill_video_urbs(peasycap)) { - SAM("ERROR: kill_video_urbs() failed\n"); - return -EFAULT; -} -JOM(4, "ending successfully\n"); -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#else -# -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + peasycap = file->private_data; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL.\n"); + SAY("ending unsuccessfully\n"); + return -EFAULT; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + return -EFAULT; + } + if (0 != kill_video_urbs(peasycap)) { + SAM("ERROR: kill_video_urbs() failed\n"); + return -EFAULT; + } + JOM(4, "ending successfully\n"); #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -return 0; + return 0; } #ifdef EASYCAP_IS_VIDEODEV_CLIENT static int easycap_open_noinode(struct file *file) @@ -774,26 +747,24 @@ static int easycap_release_noinode(struct file *file) } static int videodev_release(struct video_device *pvideo_device) { -struct easycap *peasycap; - -JOT(4, "\n"); + struct easycap *peasycap; -peasycap = video_get_drvdata(pvideo_device); -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - SAY("ending unsuccessfully\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return -EFAULT; -} -if (0 != kill_video_urbs(peasycap)) { - SAM("ERROR: kill_video_urbs() failed\n"); - return -EFAULT; -} -JOM(4, "ending successfully\n"); -return 0; + peasycap = video_get_drvdata(pvideo_device); + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + SAY("ending unsuccessfully\n"); + return -EFAULT; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + return -EFAULT; + } + if (0 != kill_video_urbs(peasycap)) { + SAM("ERROR: kill_video_urbs() failed\n"); + return -EFAULT; + } + JOM(4, "ending successfully\n"); + return 0; } #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ @@ -809,325 +780,329 @@ return 0; /*---------------------------------------------------------------------------*/ static void easycap_delete(struct kref *pkref) { -int k, m, gone, kd; -int allocation_video_urb, allocation_video_page, allocation_video_struct; -int allocation_audio_urb, allocation_audio_page, allocation_audio_struct; -int registered_video, registered_audio; -struct easycap *peasycap; -struct data_urb *pdata_urb; -struct list_head *plist_head, *plist_next; - -JOT(4, "\n"); - -peasycap = container_of(pkref, struct easycap, kref); -if (NULL == peasycap) { - SAM("ERROR: peasycap is NULL: cannot perform deletions\n"); - return; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return; -} -kd = isdongle(peasycap); + struct easycap *peasycap; + struct data_urb *pdata_urb; + struct list_head *plist_head, *plist_next; + int k, m, gone, kd; + int allocation_video_urb; + int allocation_video_page; + int allocation_video_struct; + int allocation_audio_urb; + int allocation_audio_page; + int allocation_audio_struct; + int registered_video, registered_audio; + + peasycap = container_of(pkref, struct easycap, kref); + if (NULL == peasycap) { + SAM("ERROR: peasycap is NULL: cannot perform deletions\n"); + return; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + return; + } + kd = isdongle(peasycap); /*---------------------------------------------------------------------------*/ /* * FREE VIDEO. */ /*---------------------------------------------------------------------------*/ -if (NULL != peasycap->purb_video_head) { - JOM(4, "freeing video urbs\n"); - m = 0; - list_for_each(plist_head, (peasycap->purb_video_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (NULL == pdata_urb) - JOM(4, "ERROR: pdata_urb is NULL\n"); - else { - if (NULL != pdata_urb->purb) { - usb_free_urb(pdata_urb->purb); - pdata_urb->purb = NULL; - peasycap->allocation_video_urb -= 1; - m++; + if (NULL != peasycap->purb_video_head) { + JOM(4, "freeing video urbs\n"); + m = 0; + list_for_each(plist_head, (peasycap->purb_video_head)) { + pdata_urb = list_entry(plist_head, + struct data_urb, list_head); + if (NULL == pdata_urb) { + JOM(4, "ERROR: pdata_urb is NULL\n"); + } else { + if (NULL != pdata_urb->purb) { + usb_free_urb(pdata_urb->purb); + pdata_urb->purb = NULL; + peasycap->allocation_video_urb -= 1; + m++; + } } } - } - JOM(4, "%i video urbs freed\n", m); + JOM(4, "%i video urbs freed\n", m); /*---------------------------------------------------------------------------*/ - JOM(4, "freeing video data_urb structures.\n"); - m = 0; - list_for_each_safe(plist_head, plist_next, peasycap->purb_video_head) { - pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (NULL != pdata_urb) { - kfree(pdata_urb); pdata_urb = NULL; - peasycap->allocation_video_struct -= + JOM(4, "freeing video data_urb structures.\n"); + m = 0; + list_for_each_safe(plist_head, plist_next, + peasycap->purb_video_head) { + pdata_urb = list_entry(plist_head, + struct data_urb, list_head); + if (pdata_urb) { + peasycap->allocation_video_struct -= sizeof(struct data_urb); - m++; + kfree(pdata_urb); + pdata_urb = NULL; + m++; + } } + JOM(4, "%i video data_urb structures freed\n", m); + JOM(4, "setting peasycap->purb_video_head=NULL\n"); + peasycap->purb_video_head = NULL; } - JOM(4, "%i video data_urb structures freed\n", m); - JOM(4, "setting peasycap->purb_video_head=NULL\n"); - peasycap->purb_video_head = NULL; -} /*---------------------------------------------------------------------------*/ -JOM(4, "freeing video isoc buffers.\n"); -m = 0; -for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { - if (NULL != peasycap->video_isoc_buffer[k].pgo) { - free_pages((unsigned long) - (peasycap->video_isoc_buffer[k].pgo), - VIDEO_ISOC_ORDER); - peasycap->video_isoc_buffer[k].pgo = NULL; - peasycap->allocation_video_page -= - ((unsigned int)(0x01 << VIDEO_ISOC_ORDER)); - m++; + JOM(4, "freeing video isoc buffers.\n"); + m = 0; + for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { + if (peasycap->video_isoc_buffer[k].pgo) { + free_pages((unsigned long) + peasycap->video_isoc_buffer[k].pgo, + VIDEO_ISOC_ORDER); + peasycap->video_isoc_buffer[k].pgo = NULL; + peasycap->allocation_video_page -= + BIT(VIDEO_ISOC_ORDER); + m++; + } } -} -JOM(4, "isoc video buffers freed: %i pages\n", m * (0x01 << VIDEO_ISOC_ORDER)); -/*---------------------------------------------------------------------------*/ -JOM(4, "freeing video field buffers.\n"); -gone = 0; -for (k = 0; k < FIELD_BUFFER_MANY; k++) { - for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { - if (NULL != peasycap->field_buffer[k][m].pgo) { - free_page((unsigned long) - (peasycap->field_buffer[k][m].pgo)); - peasycap->field_buffer[k][m].pgo = NULL; - peasycap->allocation_video_page -= 1; - gone++; + JOM(4, "isoc video buffers freed: %i pages\n", + m * (0x01 << VIDEO_ISOC_ORDER)); +/*---------------------------------------------------------------------------*/ + JOM(4, "freeing video field buffers.\n"); + gone = 0; + for (k = 0; k < FIELD_BUFFER_MANY; k++) { + for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { + if (NULL != peasycap->field_buffer[k][m].pgo) { + free_page((unsigned long) + peasycap->field_buffer[k][m].pgo); + peasycap->field_buffer[k][m].pgo = NULL; + peasycap->allocation_video_page -= 1; + gone++; + } } } -} -JOM(4, "video field buffers freed: %i pages\n", gone); -/*---------------------------------------------------------------------------*/ -JOM(4, "freeing video frame buffers.\n"); -gone = 0; -for (k = 0; k < FRAME_BUFFER_MANY; k++) { - for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { - if (NULL != peasycap->frame_buffer[k][m].pgo) { - free_page((unsigned long) - (peasycap->frame_buffer[k][m].pgo)); - peasycap->frame_buffer[k][m].pgo = NULL; - peasycap->allocation_video_page -= 1; - gone++; + JOM(4, "video field buffers freed: %i pages\n", gone); +/*---------------------------------------------------------------------------*/ + JOM(4, "freeing video frame buffers.\n"); + gone = 0; + for (k = 0; k < FRAME_BUFFER_MANY; k++) { + for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { + if (NULL != peasycap->frame_buffer[k][m].pgo) { + free_page((unsigned long) + peasycap->frame_buffer[k][m].pgo); + peasycap->frame_buffer[k][m].pgo = NULL; + peasycap->allocation_video_page -= 1; + gone++; + } } } -} -JOM(4, "video frame buffers freed: %i pages\n", gone); + JOM(4, "video frame buffers freed: %i pages\n", gone); /*---------------------------------------------------------------------------*/ /* * FREE AUDIO. */ /*---------------------------------------------------------------------------*/ -if (NULL != peasycap->purb_audio_head) { - JOM(4, "freeing audio urbs\n"); - m = 0; - list_for_each(plist_head, (peasycap->purb_audio_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (NULL == pdata_urb) - JOM(4, "ERROR: pdata_urb is NULL\n"); - else { - if (NULL != pdata_urb->purb) { - usb_free_urb(pdata_urb->purb); - pdata_urb->purb = NULL; - peasycap->allocation_audio_urb -= 1; + if (NULL != peasycap->purb_audio_head) { + JOM(4, "freeing audio urbs\n"); + m = 0; + list_for_each(plist_head, (peasycap->purb_audio_head)) { + pdata_urb = list_entry(plist_head, + struct data_urb, list_head); + if (NULL == pdata_urb) + JOM(4, "ERROR: pdata_urb is NULL\n"); + else { + if (NULL != pdata_urb->purb) { + usb_free_urb(pdata_urb->purb); + pdata_urb->purb = NULL; + peasycap->allocation_audio_urb -= 1; + m++; + } + } + } + JOM(4, "%i audio urbs freed\n", m); +/*---------------------------------------------------------------------------*/ + JOM(4, "freeing audio data_urb structures.\n"); + m = 0; + list_for_each_safe(plist_head, plist_next, + peasycap->purb_audio_head) { + pdata_urb = list_entry(plist_head, + struct data_urb, list_head); + if (pdata_urb) { + peasycap->allocation_audio_struct -= + sizeof(struct data_urb); + kfree(pdata_urb); + pdata_urb = NULL; m++; } } + JOM(4, "%i audio data_urb structures freed\n", m); + JOM(4, "setting peasycap->purb_audio_head=NULL\n"); + peasycap->purb_audio_head = NULL; } - JOM(4, "%i audio urbs freed\n", m); /*---------------------------------------------------------------------------*/ - JOM(4, "freeing audio data_urb structures.\n"); + JOM(4, "freeing audio isoc buffers.\n"); m = 0; - list_for_each_safe(plist_head, plist_next, peasycap->purb_audio_head) { - pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (NULL != pdata_urb) { - kfree(pdata_urb); pdata_urb = NULL; - peasycap->allocation_audio_struct -= - sizeof(struct data_urb); + for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { + if (NULL != peasycap->audio_isoc_buffer[k].pgo) { + free_pages((unsigned long) + (peasycap->audio_isoc_buffer[k].pgo), + AUDIO_ISOC_ORDER); + peasycap->audio_isoc_buffer[k].pgo = NULL; + peasycap->allocation_audio_page -= + BIT(AUDIO_ISOC_ORDER); m++; } } -JOM(4, "%i audio data_urb structures freed\n", m); -JOM(4, "setting peasycap->purb_audio_head=NULL\n"); -peasycap->purb_audio_head = NULL; -} -/*---------------------------------------------------------------------------*/ -JOM(4, "freeing audio isoc buffers.\n"); -m = 0; -for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { - if (NULL != peasycap->audio_isoc_buffer[k].pgo) { - free_pages((unsigned long) - (peasycap->audio_isoc_buffer[k].pgo), - AUDIO_ISOC_ORDER); - peasycap->audio_isoc_buffer[k].pgo = NULL; - peasycap->allocation_audio_page -= - ((unsigned int)(0x01 << AUDIO_ISOC_ORDER)); - m++; - } -} -JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n", + JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n", m * (0x01 << AUDIO_ISOC_ORDER)); /*---------------------------------------------------------------------------*/ #ifdef CONFIG_EASYCAP_OSS -JOM(4, "freeing audio buffers.\n"); -gone = 0; -for (k = 0; k < peasycap->audio_buffer_page_many; k++) { - if (NULL != peasycap->audio_buffer[k].pgo) { - free_page((unsigned long)(peasycap->audio_buffer[k].pgo)); - peasycap->audio_buffer[k].pgo = NULL; - peasycap->allocation_audio_page -= 1; - gone++; + JOM(4, "freeing audio buffers.\n"); + gone = 0; + for (k = 0; k < peasycap->audio_buffer_page_many; k++) { + if (NULL != peasycap->audio_buffer[k].pgo) { + free_page((unsigned long)peasycap->audio_buffer[k].pgo); + peasycap->audio_buffer[k].pgo = NULL; + peasycap->allocation_audio_page -= 1; + gone++; + } } -} -JOM(4, "easyoss_delete(): audio buffers freed: %i pages\n", gone); + JOM(4, "easyoss_delete(): audio buffers freed: %i pages\n", gone); #endif /* CONFIG_EASYCAP_OSS */ /*---------------------------------------------------------------------------*/ -JOM(4, "freeing easycap structure.\n"); -allocation_video_urb = peasycap->allocation_video_urb; -allocation_video_page = peasycap->allocation_video_page; -allocation_video_struct = peasycap->allocation_video_struct; -registered_video = peasycap->registered_video; -allocation_audio_urb = peasycap->allocation_audio_urb; -allocation_audio_page = peasycap->allocation_audio_page; -allocation_audio_struct = peasycap->allocation_audio_struct; -registered_audio = peasycap->registered_audio; - -kfree(peasycap); - -if (0 <= kd && DONGLE_MANY > kd) { - if (mutex_lock_interruptible(&mutex_dongle)) { - SAY("ERROR: cannot down mutex_dongle\n"); + JOM(4, "freeing easycap structure.\n"); + allocation_video_urb = peasycap->allocation_video_urb; + allocation_video_page = peasycap->allocation_video_page; + allocation_video_struct = peasycap->allocation_video_struct; + registered_video = peasycap->registered_video; + allocation_audio_urb = peasycap->allocation_audio_urb; + allocation_audio_page = peasycap->allocation_audio_page; + allocation_audio_struct = peasycap->allocation_audio_struct; + registered_audio = peasycap->registered_audio; + + kfree(peasycap); + + if (0 <= kd && DONGLE_MANY > kd) { + if (mutex_lock_interruptible(&mutex_dongle)) { + SAY("ERROR: cannot down mutex_dongle\n"); + } else { + JOM(4, "locked mutex_dongle\n"); + easycapdc60_dongle[kd].peasycap = NULL; + mutex_unlock(&mutex_dongle); + JOM(4, "unlocked mutex_dongle\n"); + JOT(4, " null-->dongle[%i].peasycap\n", kd); + allocation_video_struct -= sizeof(struct easycap); + } } else { - JOM(4, "locked mutex_dongle\n"); - easycapdc60_dongle[kd].peasycap = NULL; - mutex_unlock(&mutex_dongle); - JOM(4, "unlocked mutex_dongle\n"); - JOT(4, " null-->easycapdc60_dongle[%i].peasycap\n", kd); - allocation_video_struct -= sizeof(struct easycap); - } -} else { - SAY("ERROR: cannot purge easycapdc60_dongle[].peasycap"); -} + SAY("ERROR: cannot purge dongle[].peasycap"); + } /*---------------------------------------------------------------------------*/ -SAY("%8i= video urbs after all deletions\n", allocation_video_urb); -SAY("%8i= video pages after all deletions\n", allocation_video_page); -SAY("%8i= video structs after all deletions\n", allocation_video_struct); -SAY("%8i= video devices after all deletions\n", registered_video); -SAY("%8i= audio urbs after all deletions\n", allocation_audio_urb); -SAY("%8i= audio pages after all deletions\n", allocation_audio_page); -SAY("%8i= audio structs after all deletions\n", allocation_audio_struct); -SAY("%8i= audio devices after all deletions\n", registered_audio); - -JOT(4, "ending.\n"); -return; + SAY("%8i=video urbs after all deletions\n", allocation_video_urb); + SAY("%8i=video pages after all deletions\n", allocation_video_page); + SAY("%8i=video structs after all deletions\n", allocation_video_struct); + SAY("%8i=video devices after all deletions\n", registered_video); + SAY("%8i=audio urbs after all deletions\n", allocation_audio_urb); + SAY("%8i=audio pages after all deletions\n", allocation_audio_page); + SAY("%8i=audio structs after all deletions\n", allocation_audio_struct); + SAY("%8i=audio devices after all deletions\n", registered_audio); + + JOT(4, "ending.\n"); + return; } /*****************************************************************************/ static unsigned int easycap_poll(struct file *file, poll_table *wait) { -struct easycap *peasycap; -int rc, kd; + struct easycap *peasycap; + int rc, kd; -JOT(8, "\n"); + JOT(8, "\n"); -if (NULL == ((poll_table *)wait)) - JOT(8, "WARNING: poll table pointer is NULL ... continuing\n"); -if (NULL == file) { - SAY("ERROR: file pointer is NULL\n"); - return -ERESTARTSYS; -} -peasycap = file->private_data; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -/*---------------------------------------------------------------------------*/ -kd = isdongle(peasycap); -if (0 <= kd && DONGLE_MANY > kd) { - if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { - SAY("ERROR: cannot down " - "easycapdc60_dongle[%i].mutex_video\n", kd); - return -ERESTARTSYS; - } - JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd); - /*-------------------------------------------------------------------*/ - /* - * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER - * peasycap, IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. - * IF NECESSARY, BAIL OUT. - */ - /*-------------------------------------------------------------------*/ - if (kd != isdongle(peasycap)) - return -ERESTARTSYS; + if (NULL == ((poll_table *)wait)) + JOT(8, "WARNING: poll table pointer is NULL ... continuing\n"); if (NULL == file) { - SAY("ERROR: file is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + SAY("ERROR: file pointer is NULL\n"); return -ERESTARTSYS; } peasycap = file->private_data; if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -ERESTARTSYS; + return -EFAULT; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { SAY("ERROR: bad peasycap: %p\n", peasycap); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -ERESTARTSYS; + return -EFAULT; } if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -ERESTARTSYS; + SAY("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; } -} else - /*-------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + kd = isdongle(peasycap); + if (0 <= kd && DONGLE_MANY > kd) { + if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { + SAY("ERROR: cannot down dongle[%i].mutex_video\n", kd); + return -ERESTARTSYS; + } + JOM(4, "locked dongle[%i].mutex_video\n", kd); + /* + * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER + * peasycap, IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. + * IF NECESSARY, BAIL OUT. + */ + if (kd != isdongle(peasycap)) + return -ERESTARTSYS; + if (NULL == file) { + SAY("ERROR: file is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ERESTARTSYS; + } + peasycap = file->private_data; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ERESTARTSYS; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ERESTARTSYS; + } + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ERESTARTSYS; + } + } else /* * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap * BEFORE THE ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL * HAVE FAILED. BAIL OUT. */ - /*-------------------------------------------------------------------*/ - return -ERESTARTSYS; -/*---------------------------------------------------------------------------*/ -rc = easycap_dqbuf(peasycap, 0); -peasycap->polled = 1; -mutex_unlock(&easycapdc60_dongle[kd].mutex_video); -if (0 == rc) - return POLLIN | POLLRDNORM; -else - return POLLERR; -} + return -ERESTARTSYS; +/*---------------------------------------------------------------------------*/ + rc = easycap_dqbuf(peasycap, 0); + peasycap->polled = 1; + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + if (0 == rc) + return POLLIN | POLLRDNORM; + else + return POLLERR; + } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* * IF mode IS NONZERO THIS ROUTINE RETURNS -EAGAIN RATHER THAN BLOCKING. */ /*---------------------------------------------------------------------------*/ -int -easycap_dqbuf(struct easycap *peasycap, int mode) +int easycap_dqbuf(struct easycap *peasycap, int mode) { -int input, ifield, miss, rc; + int input, ifield, miss, rc; -JOT(8, "\n"); -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -ifield = 0; -JOM(8, "%i=ifield\n", ifield); + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (NULL == peasycap->pusb_device) { + SAY("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } + ifield = 0; + JOM(8, "%i=ifield\n", ifield); /*---------------------------------------------------------------------------*/ /* * CHECK FOR LOST INPUT SIGNAL. @@ -1143,187 +1118,186 @@ JOM(8, "%i=ifield\n", ifield); * INPUT 0 UNPLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 BARS, SCREEN 4 BARS */ /*---------------------------------------------------------------------------*/ -input = peasycap->input; -if (0 <= input && INPUT_MANY > input) { - rc = read_saa(peasycap->pusb_device, 0x1F); - if (0 <= rc) { - if (rc & 0x40) - peasycap->lost[input] += 1; - else - peasycap->lost[input] -= 2; + input = peasycap->input; + if (0 <= input && INPUT_MANY > input) { + rc = read_saa(peasycap->pusb_device, 0x1F); + if (0 <= rc) { + if (rc & 0x40) + peasycap->lost[input] += 1; + else + peasycap->lost[input] -= 2; - if (0 > peasycap->lost[input]) - peasycap->lost[input] = 0; - else if ((2 * VIDEO_LOST_TOLERATE) < peasycap->lost[input]) - peasycap->lost[input] = (2 * VIDEO_LOST_TOLERATE); + if (0 > peasycap->lost[input]) + peasycap->lost[input] = 0; + else if ((2 * VIDEO_LOST_TOLERATE) < peasycap->lost[input]) + peasycap->lost[input] = (2 * VIDEO_LOST_TOLERATE); + } } -} /*---------------------------------------------------------------------------*/ /* * WAIT FOR FIELD ifield (0 => TOP, 1 => BOTTOM) */ /*---------------------------------------------------------------------------*/ -miss = 0; -while ((peasycap->field_read == peasycap->field_fill) || - (0 != (0xFF00 & peasycap->field_buffer + miss = 0; + while ((peasycap->field_read == peasycap->field_fill) || + (0 != (0xFF00 & peasycap->field_buffer [peasycap->field_read][0].kount)) || - (ifield != (0x00FF & peasycap->field_buffer + (ifield != (0x00FF & peasycap->field_buffer [peasycap->field_read][0].kount))) { - if (mode) - return -EAGAIN; - - JOM(8, "first wait on wq_video, " - "%i=field_read %i=field_fill\n", - peasycap->field_read, peasycap->field_fill); + if (mode) + return -EAGAIN; - if (0 != (wait_event_interruptible(peasycap->wq_video, - (peasycap->video_idle || peasycap->video_eof || - ((peasycap->field_read != peasycap->field_fill) && - (0 == (0xFF00 & peasycap->field_buffer - [peasycap->field_read][0].kount)) && - (ifield == (0x00FF & peasycap->field_buffer - [peasycap->field_read][0].kount))))))) { - SAM("aborted by signal\n"); - return -EIO; - } - if (peasycap->video_idle) { - JOM(8, "%i=peasycap->video_idle ... returning -EAGAIN\n", - peasycap->video_idle); - return -EAGAIN; - } - if (peasycap->video_eof) { - JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof); - #if defined(PERSEVERE) - if (1 == peasycap->status) { - JOM(8, "persevering ...\n"); - peasycap->video_eof = 0; - peasycap->audio_eof = 0; - if (0 != reset(peasycap)) { - JOM(8, " ... failed ... returning -EIO\n"); - peasycap->video_eof = 1; - peasycap->audio_eof = 1; - kill_video_urbs(peasycap); - return -EIO; + JOM(8, "first wait on wq_video, " + "%i=field_read %i=field_fill\n", + peasycap->field_read, peasycap->field_fill); + + if (0 != (wait_event_interruptible(peasycap->wq_video, + (peasycap->video_idle || peasycap->video_eof || + ((peasycap->field_read != peasycap->field_fill) && + (0 == (0xFF00 & peasycap->field_buffer + [peasycap->field_read][0].kount)) && + (ifield == (0x00FF & peasycap->field_buffer + [peasycap->field_read][0].kount))))))) { + SAM("aborted by signal\n"); + return -EIO; } - peasycap->status = 0; - JOM(8, " ... OK ... returning -EAGAIN\n"); + if (peasycap->video_idle) { + JOM(8, "%i=peasycap->video_idle returning -EAGAIN\n", + peasycap->video_idle); return -EAGAIN; } - #endif /*PERSEVERE*/ - peasycap->video_eof = 1; - peasycap->audio_eof = 1; - kill_video_urbs(peasycap); - JOM(8, "returning -EIO\n"); - return -EIO; + if (peasycap->video_eof) { + JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof); + #if defined(PERSEVERE) + if (1 == peasycap->status) { + JOM(8, "persevering ...\n"); + peasycap->video_eof = 0; + peasycap->audio_eof = 0; + if (0 != reset(peasycap)) { + JOM(8, " ... failed returning -EIO\n"); + peasycap->video_eof = 1; + peasycap->audio_eof = 1; + kill_video_urbs(peasycap); + return -EIO; + } + peasycap->status = 0; + JOM(8, " ... OK returning -EAGAIN\n"); + return -EAGAIN; + } + #endif /*PERSEVERE*/ + peasycap->video_eof = 1; + peasycap->audio_eof = 1; + kill_video_urbs(peasycap); + JOM(8, "returning -EIO\n"); + return -EIO; + } + miss++; } -miss++; -} -JOM(8, "first awakening on wq_video after %i waits\n", miss); + JOM(8, "first awakening on wq_video after %i waits\n", miss); -rc = field2frame(peasycap); -if (rc) - SAM("ERROR: field2frame() returned %i\n", rc); + rc = field2frame(peasycap); + if (rc) + SAM("ERROR: field2frame() rc = %i\n", rc); /*---------------------------------------------------------------------------*/ /* * WAIT FOR THE OTHER FIELD */ /*---------------------------------------------------------------------------*/ -if (ifield) - ifield = 0; -else - ifield = 1; -miss = 0; -while ((peasycap->field_read == peasycap->field_fill) || - (0 != (0xFF00 & peasycap->field_buffer + if (ifield) + ifield = 0; + else + ifield = 1; + miss = 0; + while ((peasycap->field_read == peasycap->field_fill) || + (0 != (0xFF00 & peasycap->field_buffer [peasycap->field_read][0].kount)) || - (ifield != (0x00FF & peasycap->field_buffer + (ifield != (0x00FF & peasycap->field_buffer [peasycap->field_read][0].kount))) { - if (mode) - return -EAGAIN; + if (mode) + return -EAGAIN; - JOM(8, "second wait on wq_video, " - "%i=field_read %i=field_fill\n", + JOM(8, "second wait on wq_video %i=field_read %i=field_fill\n", peasycap->field_read, peasycap->field_fill); - if (0 != (wait_event_interruptible(peasycap->wq_video, + if (0 != (wait_event_interruptible(peasycap->wq_video, (peasycap->video_idle || peasycap->video_eof || ((peasycap->field_read != peasycap->field_fill) && - (0 == (0xFF00 & peasycap->field_buffer + (0 == (0xFF00 & peasycap->field_buffer [peasycap->field_read][0].kount)) && - (ifield == (0x00FF & peasycap->field_buffer - [peasycap->field_read][0]. + (ifield == (0x00FF & peasycap->field_buffer + [peasycap->field_read][0]. kount))))))) { - SAM("aborted by signal\n"); - return -EIO; - } - if (peasycap->video_idle) { - JOM(8, "%i=peasycap->video_idle ... returning -EAGAIN\n", + SAM("aborted by signal\n"); + return -EIO; + } + if (peasycap->video_idle) { + JOM(8, "%i=peasycap->video_idle returning -EAGAIN\n", peasycap->video_idle); - return -EAGAIN; - } - if (peasycap->video_eof) { - JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof); - #if defined(PERSEVERE) - if (1 == peasycap->status) { - JOM(8, "persevering ...\n"); - peasycap->video_eof = 0; - peasycap->audio_eof = 0; - if (0 != reset(peasycap)) { - JOM(8, " ... failed ... returning -EIO\n"); - peasycap->video_eof = 1; - peasycap->audio_eof = 1; - kill_video_urbs(peasycap); - return -EIO; - } - peasycap->status = 0; - JOM(8, " ... OK ... returning -EAGAIN\n"); return -EAGAIN; } - #endif /*PERSEVERE*/ - peasycap->video_eof = 1; - peasycap->audio_eof = 1; - kill_video_urbs(peasycap); - JOM(8, "returning -EIO\n"); - return -EIO; + if (peasycap->video_eof) { + JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof); + #if defined(PERSEVERE) + if (1 == peasycap->status) { + JOM(8, "persevering ...\n"); + peasycap->video_eof = 0; + peasycap->audio_eof = 0; + if (0 != reset(peasycap)) { + JOM(8, " ... failed returning -EIO\n"); + peasycap->video_eof = 1; + peasycap->audio_eof = 1; + kill_video_urbs(peasycap); + return -EIO; + } + peasycap->status = 0; + JOM(8, " ... OK ... returning -EAGAIN\n"); + return -EAGAIN; + } + #endif /*PERSEVERE*/ + peasycap->video_eof = 1; + peasycap->audio_eof = 1; + kill_video_urbs(peasycap); + JOM(8, "returning -EIO\n"); + return -EIO; + } + miss++; } -miss++; -} -JOM(8, "second awakening on wq_video after %i waits\n", miss); + JOM(8, "second awakening on wq_video after %i waits\n", miss); -rc = field2frame(peasycap); -if (rc) - SAM("ERROR: field2frame() returned %i\n", rc); + rc = field2frame(peasycap); + if (rc) + SAM("ERROR: field2frame() rc = %i\n", rc); /*---------------------------------------------------------------------------*/ /* * WASTE THIS FRAME */ /*---------------------------------------------------------------------------*/ -if (0 != peasycap->skip) { - peasycap->skipped++; - if (peasycap->skip != peasycap->skipped) - return peasycap->skip - peasycap->skipped; - peasycap->skipped = 0; -} + if (0 != peasycap->skip) { + peasycap->skipped++; + if (peasycap->skip != peasycap->skipped) + return peasycap->skip - peasycap->skipped; + peasycap->skipped = 0; + } /*---------------------------------------------------------------------------*/ -peasycap->frame_read = peasycap->frame_fill; -peasycap->queued[peasycap->frame_read] = 0; -peasycap->done[peasycap->frame_read] = V4L2_BUF_FLAG_DONE; + peasycap->frame_read = peasycap->frame_fill; + peasycap->queued[peasycap->frame_read] = 0; + peasycap->done[peasycap->frame_read] = V4L2_BUF_FLAG_DONE; -(peasycap->frame_fill)++; -if (peasycap->frame_buffer_many <= peasycap->frame_fill) - peasycap->frame_fill = 0; + peasycap->frame_fill++; + if (peasycap->frame_buffer_many <= peasycap->frame_fill) + peasycap->frame_fill = 0; -if (0x01 & easycap_standard[peasycap->standard_offset].mask) { - peasycap->frame_buffer[peasycap->frame_read][0].kount = + if (0x01 & easycap_standard[peasycap->standard_offset].mask) + peasycap->frame_buffer[peasycap->frame_read][0].kount = V4L2_FIELD_TOP; -} else { - peasycap->frame_buffer[peasycap->frame_read][0].kount = + else + peasycap->frame_buffer[peasycap->frame_read][0].kount = V4L2_FIELD_BOTTOM; -} -JOM(8, "setting: %i=peasycap->frame_read\n", peasycap->frame_read); -JOM(8, "bumped to: %i=peasycap->frame_fill\n", peasycap->frame_fill); -return 0; + JOM(8, "setting: %i=peasycap->frame_read\n", peasycap->frame_read); + JOM(8, "bumped to: %i=peasycap->frame_fill\n", peasycap->frame_fill); + + return 0; } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ @@ -1341,222 +1315,213 @@ return 0; int field2frame(struct easycap *peasycap) { -struct timeval timeval; -long long int above, below; -u32 remainder; -struct signed_div_result sdr; - -void *pex, *pad; -int kex, kad, mex, mad, rex, rad, rad2; -int c2, c3, w2, w3, cz, wz; -int rc, bytesperpixel, multiplier, much, more, over, rump, caches, input; -u8 mask, margin; -bool odd, isuy, decimatepixel, offerfields, badinput; - -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} + struct timeval timeval; + long long int above, below; + u32 remainder; + struct signed_div_result sdr; + + void *pex, *pad; + int kex, kad, mex, mad, rex, rad, rad2; + int c2, c3, w2, w3, cz, wz; + int rc, bytesperpixel, multiplier; + int much, more, over, rump, caches, input; + u8 mask, margin; + bool odd, isuy, decimatepixel, offerfields, badinput; + + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } -badinput = false; -input = 0x07 & peasycap->field_buffer[peasycap->field_read][0].input; + badinput = false; + input = 0x07 & peasycap->field_buffer[peasycap->field_read][0].input; -JOM(8, "===== parity %i, input 0x%02X, field buffer %i --> " - "frame buffer %i\n", + JOM(8, "===== parity %i, input 0x%02X, field buffer %i --> " + "frame buffer %i\n", peasycap->field_buffer[peasycap->field_read][0].kount, peasycap->field_buffer[peasycap->field_read][0].input, peasycap->field_read, peasycap->frame_fill); -JOM(8, "===== %i=bytesperpixel\n", peasycap->bytesperpixel); -if (true == peasycap->offerfields) - JOM(8, "===== offerfields\n"); + JOM(8, "===== %i=bytesperpixel\n", peasycap->bytesperpixel); + if (true == peasycap->offerfields) + JOM(8, "===== offerfields\n"); /*---------------------------------------------------------------------------*/ /* * REJECT OR CLEAN BAD FIELDS */ /*---------------------------------------------------------------------------*/ -if (peasycap->field_read == peasycap->field_fill) { - SAM("ERROR: on entry, still filling field buffer %i\n", - peasycap->field_read); - return 0; -} + if (peasycap->field_read == peasycap->field_fill) { + SAM("ERROR: on entry, still filling field buffer %i\n", + peasycap->field_read); + return 0; + } #ifdef EASYCAP_TESTCARD -easycap_testcard(peasycap, peasycap->field_read); + easycap_testcard(peasycap, peasycap->field_read); #else -if (0 <= input && INPUT_MANY > input) { - if (easycap_bars && VIDEO_LOST_TOLERATE <= peasycap->lost[input]) - easycap_testcard(peasycap, peasycap->field_read); -} + if (0 <= input && INPUT_MANY > input) { + if (easycap_bars && VIDEO_LOST_TOLERATE <= peasycap->lost[input]) + easycap_testcard(peasycap, peasycap->field_read); + } #endif /*EASYCAP_TESTCARD*/ /*---------------------------------------------------------------------------*/ -offerfields = peasycap->offerfields; -bytesperpixel = peasycap->bytesperpixel; -decimatepixel = peasycap->decimatepixel; + offerfields = peasycap->offerfields; + bytesperpixel = peasycap->bytesperpixel; + decimatepixel = peasycap->decimatepixel; -if ((2 != bytesperpixel) && - (3 != bytesperpixel) && - (4 != bytesperpixel)) { - SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel); - return -EFAULT; -} -if (true == decimatepixel) - multiplier = 2; -else - multiplier = 1; - -w2 = 2 * multiplier * (peasycap->width); -w3 = bytesperpixel * - multiplier * - (peasycap->width); -wz = multiplier * - (peasycap->height) * - multiplier * - (peasycap->width); - -kex = peasycap->field_read; mex = 0; -kad = peasycap->frame_fill; mad = 0; - -pex = peasycap->field_buffer[kex][0].pgo; rex = PAGE_SIZE; -pad = peasycap->frame_buffer[kad][0].pgo; rad = PAGE_SIZE; -if (peasycap->field_buffer[kex][0].kount) - odd = true; -else - odd = false; - -if ((true == odd) && (false == decimatepixel)) { - JOM(8, " initial skipping %4i bytes p.%4i\n", - w3/multiplier, mad); - pad += (w3 / multiplier); rad -= (w3 / multiplier); -} -isuy = true; -mask = 0; rump = 0; caches = 0; + if ((2 != bytesperpixel) && + (3 != bytesperpixel) && + (4 != bytesperpixel)) { + SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel); + return -EFAULT; + } + if (true == decimatepixel) + multiplier = 2; + else + multiplier = 1; -cz = 0; -while (cz < wz) { - /*-------------------------------------------------------------------*/ - /* - ** PROCESS ONE LINE OF FRAME AT FULL RESOLUTION: - ** READ w2 BYTES FROM FIELD BUFFER, - ** WRITE w3 BYTES TO FRAME BUFFER - **/ - /*-------------------------------------------------------------------*/ - if (false == decimatepixel) { - over = w2; - do { - much = over; more = 0; margin = 0; mask = 0x00; - if (rex < much) - much = rex; - rump = 0; - - if (much % 2) { - SAM("MISTAKE: much is odd\n"); - return -EFAULT; - } + w2 = 2 * multiplier * (peasycap->width); + w3 = bytesperpixel * multiplier * (peasycap->width); + wz = multiplier * (peasycap->height) * + multiplier * (peasycap->width); + + kex = peasycap->field_read; mex = 0; + kad = peasycap->frame_fill; mad = 0; + + pex = peasycap->field_buffer[kex][0].pgo; rex = PAGE_SIZE; + pad = peasycap->frame_buffer[kad][0].pgo; rad = PAGE_SIZE; + odd = !!(peasycap->field_buffer[kex][0].kount); + + if ((true == odd) && (false == decimatepixel)) { + JOM(8, "initial skipping %4i bytes p.%4i\n", + w3/multiplier, mad); + pad += (w3 / multiplier); rad -= (w3 / multiplier); + } + isuy = true; + mask = 0; rump = 0; caches = 0; + + cz = 0; + while (cz < wz) { + /* + * PROCESS ONE LINE OF FRAME AT FULL RESOLUTION: + * READ w2 BYTES FROM FIELD BUFFER, + * WRITE w3 BYTES TO FRAME BUFFER + */ + if (false == decimatepixel) { + over = w2; + do { + much = over; more = 0; + margin = 0; mask = 0x00; + if (rex < much) + much = rex; + rump = 0; + + if (much % 2) { + SAM("MISTAKE: much is odd\n"); + return -EFAULT; + } - more = (bytesperpixel * - much) / 2; + more = (bytesperpixel * + much) / 2; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - if (1 < bytesperpixel) { - if (rad * 2 < much * bytesperpixel) { - /* - ** INJUDICIOUS ALTERATION OF THIS - ** STATEMENT BLOCK WILL CAUSE - ** BREAKAGE. BEWARE. - **/ - rad2 = rad + bytesperpixel - 1; - much = ((((2 * - rad2)/bytesperpixel)/2) * 2); - rump = ((bytesperpixel * - much) / 2) - rad; - more = rad; + if (1 < bytesperpixel) { + if (rad * 2 < much * bytesperpixel) { + /* + * INJUDICIOUS ALTERATION OF + * THIS STATEMENT BLOCK WILL + * CAUSE BREAKAGE. BEWARE. + */ + rad2 = rad + bytesperpixel - 1; + much = ((((2 * + rad2)/bytesperpixel)/2) * 2); + rump = ((bytesperpixel * + much) / 2) - rad; + more = rad; + } + mask = (u8)rump; + margin = 0; + if (much == rex) { + mask |= 0x04; + if ((mex + 1) < FIELD_BUFFER_SIZE/ + PAGE_SIZE) { + margin = *((u8 *)(peasycap-> + field_buffer + [kex][mex + 1].pgo)); + } else + mask |= 0x08; } - mask = (u8)rump; - margin = 0; - if (much == rex) { - mask |= 0x04; - if ((mex + 1) < FIELD_BUFFER_SIZE/ - PAGE_SIZE) { - margin = *((u8 *)(peasycap-> - field_buffer - [kex][mex + 1].pgo)); - } else - mask |= 0x08; + } else { + SAM("MISTAKE: %i=bytesperpixel\n", + bytesperpixel); + return -EFAULT; } -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - } else { - SAM("MISTAKE: %i=bytesperpixel\n", - bytesperpixel); - return -EFAULT; - } -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - if (rump) - caches++; - if (true == badinput) { - JOM(8, "ERROR: 0x%02X=->field_buffer" - "[%i][%i].input, " - "0x%02X=(0x08|->input)\n", - peasycap->field_buffer - [kex][mex].input, kex, mex, - (0x08|peasycap->input)); + if (rump) + caches++; + if (true == badinput) { + JOM(8, "ERROR: 0x%02X=->field_buffer" + "[%i][%i].input, " + "0x%02X=(0x08|->input)\n", + peasycap->field_buffer + [kex][mex].input, kex, mex, + (0x08|peasycap->input)); + } + rc = redaub(peasycap, pad, pex, much, more, + mask, margin, isuy); + if (0 > rc) { + SAM("ERROR: redaub() failed\n"); + return -EFAULT; } - rc = redaub(peasycap, pad, pex, much, more, - mask, margin, isuy); - if (0 > rc) { - SAM("ERROR: redaub() failed\n"); - return -EFAULT; - } - if (much % 4) { - if (isuy) - isuy = false; - else - isuy = true; - } - over -= much; cz += much; - pex += much; rex -= much; - if (!rex) { - mex++; - pex = peasycap->field_buffer[kex][mex].pgo; - rex = PAGE_SIZE; - if (peasycap->field_buffer[kex][mex].input != - (0x08|peasycap->input)) - badinput = true; - } - pad += more; - rad -= more; - if (!rad) { - mad++; - pad = peasycap->frame_buffer[kad][mad].pgo; - rad = PAGE_SIZE; - if (rump) { - pad += rump; - rad -= rump; + if (much % 4) { + if (isuy) + isuy = false; + else + isuy = true; } - } - } while (over); + over -= much; cz += much; + pex += much; rex -= much; + if (!rex) { + mex++; + pex = peasycap->field_buffer[kex][mex].pgo; + rex = PAGE_SIZE; + if (peasycap->field_buffer[kex][mex].input != + (0x08|peasycap->input)) + badinput = true; + } + pad += more; + rad -= more; + if (!rad) { + mad++; + pad = peasycap->frame_buffer[kad][mad].pgo; + rad = PAGE_SIZE; + if (rump) { + pad += rump; + rad -= rump; + } + } + } while (over); /*---------------------------------------------------------------------------*/ /* * SKIP w3 BYTES IN TARGET FRAME BUFFER, * UNLESS IT IS THE LAST LINE OF AN ODD FRAME */ /*---------------------------------------------------------------------------*/ - if ((false == odd) || (cz != wz)) { - over = w3; - do { - if (!rad) { - mad++; - pad = peasycap->frame_buffer - [kad][mad].pgo; - rad = PAGE_SIZE; - } - more = over; - if (rad < more) - more = rad; - over -= more; - pad += more; - rad -= more; - } while (over); - } + if ((false == odd) || (cz != wz)) { + over = w3; + do { + if (!rad) { + mad++; + pad = peasycap->frame_buffer + [kad][mad].pgo; + rad = PAGE_SIZE; + } + more = over; + if (rad < more) + more = rad; + over -= more; + pad += more; + rad -= more; + } while (over); + } /*---------------------------------------------------------------------------*/ /* * PROCESS ONE LINE OF FRAME AT REDUCED RESOLUTION: @@ -1565,48 +1530,47 @@ while (cz < wz) { * WRITE w3 / 2 BYTES TO FRAME BUFFER */ /*---------------------------------------------------------------------------*/ - } else if (false == odd) { - over = w2; - do { - much = over; more = 0; margin = 0; mask = 0x00; - if (rex < much) - much = rex; - rump = 0; + } else if (false == odd) { + over = w2; + do { + much = over; more = 0; margin = 0; mask = 0x00; + if (rex < much) + much = rex; + rump = 0; - if (much % 2) { - SAM("MISTAKE: much is odd\n"); - return -EFAULT; - } + if (much % 2) { + SAM("MISTAKE: much is odd\n"); + return -EFAULT; + } - more = (bytesperpixel * - much) / 4; + more = (bytesperpixel * much) / 4; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - if (1 < bytesperpixel) { - if (rad * 4 < much * bytesperpixel) { - /* - ** INJUDICIOUS ALTERATION OF THIS - ** STATEMENT BLOCK WILL CAUSE - ** BREAKAGE. BEWARE. - **/ - rad2 = rad + bytesperpixel - 1; - much = ((((2 * rad2)/bytesperpixel)/2) - * 4); - rump = ((bytesperpixel * - much) / 4) - rad; - more = rad; + if (1 < bytesperpixel) { + if (rad * 4 < much * bytesperpixel) { + /* + * INJUDICIOUS ALTERATION OF + * THIS STATEMENT BLOCK + * WILL CAUSE BREAKAGE. + * BEWARE. + */ + rad2 = rad + bytesperpixel - 1; + much = ((((2 * rad2)/bytesperpixel)/2) + * 4); + rump = ((bytesperpixel * + much) / 4) - rad; + more = rad; } - mask = (u8)rump; - margin = 0; - if (much == rex) { - mask |= 0x04; - if ((mex + 1) < FIELD_BUFFER_SIZE/ - PAGE_SIZE) { - margin = *((u8 *)(peasycap-> - field_buffer - [kex][mex + 1].pgo)); - } - else - mask |= 0x08; + mask = (u8)rump; + margin = 0; + if (much == rex) { + mask |= 0x04; + if ((mex + 1) < FIELD_BUFFER_SIZE/ + PAGE_SIZE) { + margin = *((u8 *)(peasycap-> + field_buffer + [kex][mex + 1].pgo)); + } else + mask |= 0x08; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ } else { @@ -1615,164 +1579,161 @@ while (cz < wz) { return -EFAULT; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - if (rump) - caches++; - - if (true == badinput) { - JOM(8, "ERROR: 0x%02X=->field_buffer" - "[%i][%i].input, " - "0x%02X=(0x08|->input)\n", - peasycap->field_buffer - [kex][mex].input, kex, mex, - (0x08|peasycap->input)); - } - rc = redaub(peasycap, pad, pex, much, more, + if (rump) + caches++; + + if (true == badinput) { + JOM(8, "ERROR: 0x%02X=->field_buffer" + "[%i][%i].input, " + "0x%02X=(0x08|->input)\n", + peasycap->field_buffer + [kex][mex].input, kex, mex, + (0x08|peasycap->input)); + } + rc = redaub(peasycap, pad, pex, much, more, mask, margin, isuy); - if (0 > rc) { - SAM("ERROR: redaub() failed\n"); - return -EFAULT; - } - over -= much; cz += much; - pex += much; rex -= much; - if (!rex) { - mex++; - pex = peasycap->field_buffer[kex][mex].pgo; - rex = PAGE_SIZE; - if (peasycap->field_buffer[kex][mex].input != - (0x08|peasycap->input)) - badinput = true; - } - pad += more; - rad -= more; - if (!rad) { - mad++; - pad = peasycap->frame_buffer[kad][mad].pgo; - rad = PAGE_SIZE; - if (rump) { - pad += rump; - rad -= rump; + if (0 > rc) { + SAM("ERROR: redaub() failed\n"); + return -EFAULT; } - } - } while (over); + over -= much; cz += much; + pex += much; rex -= much; + if (!rex) { + mex++; + pex = peasycap->field_buffer[kex][mex].pgo; + rex = PAGE_SIZE; + if (peasycap->field_buffer[kex][mex].input != + (0x08|peasycap->input)) + badinput = true; + } + pad += more; + rad -= more; + if (!rad) { + mad++; + pad = peasycap->frame_buffer[kad][mad].pgo; + rad = PAGE_SIZE; + if (rump) { + pad += rump; + rad -= rump; + } + } + } while (over); /*---------------------------------------------------------------------------*/ /* * OTHERWISE JUST * READ w2 BYTES FROM FIELD BUFFER AND DISCARD THEM */ /*---------------------------------------------------------------------------*/ - } else { - over = w2; - do { - if (!rex) { - mex++; - pex = peasycap->field_buffer[kex][mex].pgo; - rex = PAGE_SIZE; - if (peasycap->field_buffer[kex][mex].input != - (0x08|peasycap->input)) { - JOM(8, "ERROR: 0x%02X=->field_buffer" - "[%i][%i].input, " - "0x%02X=(0x08|->input)\n", - peasycap->field_buffer - [kex][mex].input, kex, mex, - (0x08|peasycap->input)); - badinput = true; + } else { + over = w2; + do { + if (!rex) { + mex++; + pex = peasycap->field_buffer[kex][mex].pgo; + rex = PAGE_SIZE; + if (peasycap->field_buffer[kex][mex].input != + (0x08|peasycap->input)) { + JOM(8, "ERROR: 0x%02X=->field_buffer" + "[%i][%i].input, " + "0x%02X=(0x08|->input)\n", + peasycap->field_buffer + [kex][mex].input, kex, mex, + (0x08|peasycap->input)); + badinput = true; + } } - } - much = over; - if (rex < much) - much = rex; - over -= much; - cz += much; - pex += much; - rex -= much; - } while (over); + much = over; + if (rex < much) + much = rex; + over -= much; + cz += much; + pex += much; + rex -= much; + } while (over); + } } -} /*---------------------------------------------------------------------------*/ /* * SANITY CHECKS */ /*---------------------------------------------------------------------------*/ -c2 = (mex + 1)*PAGE_SIZE - rex; -if (cz != c2) - SAM("ERROR: discrepancy %i in bytes read\n", c2 - cz); -c3 = (mad + 1)*PAGE_SIZE - rad; - -if (false == decimatepixel) { - if (bytesperpixel * - cz != c3) - SAM("ERROR: discrepancy %i in bytes written\n", - c3 - (bytesperpixel * - cz)); -} else { - if (false == odd) { - if (bytesperpixel * - cz != (4 * c3)) + c2 = (mex + 1)*PAGE_SIZE - rex; + if (cz != c2) + SAM("ERROR: discrepancy %i in bytes read\n", c2 - cz); + c3 = (mad + 1)*PAGE_SIZE - rad; + + if (false == decimatepixel) { + if (bytesperpixel * cz != c3) SAM("ERROR: discrepancy %i in bytes written\n", - (2*c3)-(bytesperpixel * - cz)); - } else { - if (0 != c3) - SAM("ERROR: discrepancy %i " - "in bytes written\n", c3); - } -} -if (rump) - SAM("WORRY: undischarged cache at end of line in frame buffer\n"); + c3 - (bytesperpixel * cz)); + } else { + if (false == odd) { + if (bytesperpixel * + cz != (4 * c3)) + SAM("ERROR: discrepancy %i in bytes written\n", + (2*c3)-(bytesperpixel * cz)); + } else { + if (0 != c3) + SAM("ERROR: discrepancy %i " + "in bytes written\n", c3); + } + } + if (rump) + SAM("WORRY: undischarged cache at end of line in frame buffer\n"); -JOM(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2, c3); -JOM(8, "===== field2frame(): %i=mad %i=rad\n", mad, rad); + JOM(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2, c3); + JOM(8, "===== field2frame(): %i=mad %i=rad\n", mad, rad); -if (true == odd) - JOM(8, "+++++ field2frame(): frame buffer %i is full\n", kad); + if (true == odd) + JOM(8, "+++++ field2frame(): frame buffer %i is full\n", kad); -if (peasycap->field_read == peasycap->field_fill) - SAM("WARNING: on exit, filling field buffer %i\n", - peasycap->field_read); + if (peasycap->field_read == peasycap->field_fill) + SAM("WARNING: on exit, filling field buffer %i\n", + peasycap->field_read); /*---------------------------------------------------------------------------*/ /* * CALCULATE VIDEO STREAMING RATE */ /*---------------------------------------------------------------------------*/ -do_gettimeofday(&timeval); -if (peasycap->timeval6.tv_sec) { - below = ((long long int)(1000000)) * - ((long long int)(timeval.tv_sec - - peasycap->timeval6.tv_sec)) + - (long long int)(timeval.tv_usec - peasycap->timeval6.tv_usec); - above = (long long int)1000000; + do_gettimeofday(&timeval); + if (peasycap->timeval6.tv_sec) { + below = ((long long int)(1000000)) * + ((long long int)(timeval.tv_sec - + peasycap->timeval6.tv_sec)) + + (long long int)(timeval.tv_usec - peasycap->timeval6.tv_usec); + above = (long long int)1000000; - sdr = signed_div(above, below); - above = sdr.quotient; - remainder = (u32)sdr.remainder; + sdr = signed_div(above, below); + above = sdr.quotient; + remainder = (u32)sdr.remainder; - JOM(8, "video streaming at %3lli.%03i fields per second\n", above, - (remainder/1000)); -} -peasycap->timeval6 = timeval; + JOM(8, "video streaming at %3lli.%03i fields per second\n", + above, (remainder/1000)); + } + peasycap->timeval6 = timeval; -if (caches) - JOM(8, "%i=caches\n", caches); -return 0; + if (caches) + JOM(8, "%i=caches\n", caches); + return 0; } /*****************************************************************************/ struct signed_div_result signed_div(long long int above, long long int below) { -struct signed_div_result sdr; - -if (((0 <= above) && (0 <= below)) || ((0 > above) && (0 > below))) { - sdr.remainder = (unsigned long long int) do_div(above, below); - sdr.quotient = (long long int) above; -} else { - if (0 > above) - above = -above; - if (0 > below) - below = -below; - sdr.remainder = (unsigned long long int) do_div(above, below); - sdr.quotient = -((long long int) above); -} -return sdr; + struct signed_div_result sdr; + + if (((0 <= above) && (0 <= below)) || ((0 > above) && (0 > below))) { + sdr.remainder = (unsigned long long int) do_div(above, below); + sdr.quotient = (long long int) above; + } else { + if (0 > above) + above = -above; + if (0 > below) + below = -below; + sdr.remainder = (unsigned long long int) do_div(above, below); + sdr.quotient = -((long long int) above); + } + return sdr; } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ @@ -1804,335 +1765,166 @@ int redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, u8 mask, u8 margin, bool isuy) { -static s32 ay[256], bu[256], rv[256], gu[256], gv[256]; -u8 *pcache; -u8 r, g, b, y, u, v, c, *p2, *p3, *pz, *pr; -int bytesperpixel; -bool byteswaporder, decimatepixel, last; -int j, rump; -s32 tmp; - -if (much % 2) { - SAM("MISTAKE: much is odd\n"); - return -EFAULT; -} -bytesperpixel = peasycap->bytesperpixel; -byteswaporder = peasycap->byteswaporder; -decimatepixel = peasycap->decimatepixel; - -/*---------------------------------------------------------------------------*/ -if (!bu[255]) { - for (j = 0; j < 112; j++) { - tmp = (0xFF00 & (453 * j)) >> 8; - bu[j + 128] = tmp; bu[127 - j] = -tmp; - tmp = (0xFF00 & (359 * j)) >> 8; - rv[j + 128] = tmp; rv[127 - j] = -tmp; - tmp = (0xFF00 & (88 * j)) >> 8; - gu[j + 128] = tmp; gu[127 - j] = -tmp; - tmp = (0xFF00 & (183 * j)) >> 8; - gv[j + 128] = tmp; gv[127 - j] = -tmp; - } - for (j = 0; j < 16; j++) { - bu[j] = bu[16]; rv[j] = rv[16]; - gu[j] = gu[16]; gv[j] = gv[16]; - } - for (j = 240; j < 256; j++) { - bu[j] = bu[239]; rv[j] = rv[239]; - gu[j] = gu[239]; gv[j] = gv[239]; - } - for (j = 16; j < 236; j++) - ay[j] = j; - for (j = 0; j < 16; j++) - ay[j] = ay[16]; - for (j = 236; j < 256; j++) - ay[j] = ay[235]; - JOM(8, "lookup tables are prepared\n"); -} -pcache = peasycap->pcache; -if (NULL == pcache) - pcache = &peasycap->cache[0]; + static s32 ay[256], bu[256], rv[256], gu[256], gv[256]; + u8 *pcache; + u8 r, g, b, y, u, v, c, *p2, *p3, *pz, *pr; + int bytesperpixel; + bool byteswaporder, decimatepixel, last; + int j, rump; + s32 tmp; + + if (much % 2) { + SAM("MISTAKE: much is odd\n"); + return -EFAULT; + } + bytesperpixel = peasycap->bytesperpixel; + byteswaporder = peasycap->byteswaporder; + decimatepixel = peasycap->decimatepixel; + +/*---------------------------------------------------------------------------*/ + if (!bu[255]) { + for (j = 0; j < 112; j++) { + tmp = (0xFF00 & (453 * j)) >> 8; + bu[j + 128] = tmp; bu[127 - j] = -tmp; + tmp = (0xFF00 & (359 * j)) >> 8; + rv[j + 128] = tmp; rv[127 - j] = -tmp; + tmp = (0xFF00 & (88 * j)) >> 8; + gu[j + 128] = tmp; gu[127 - j] = -tmp; + tmp = (0xFF00 & (183 * j)) >> 8; + gv[j + 128] = tmp; gv[127 - j] = -tmp; + } + for (j = 0; j < 16; j++) { + bu[j] = bu[16]; rv[j] = rv[16]; + gu[j] = gu[16]; gv[j] = gv[16]; + } + for (j = 240; j < 256; j++) { + bu[j] = bu[239]; rv[j] = rv[239]; + gu[j] = gu[239]; gv[j] = gv[239]; + } + for (j = 16; j < 236; j++) + ay[j] = j; + for (j = 0; j < 16; j++) + ay[j] = ay[16]; + for (j = 236; j < 256; j++) + ay[j] = ay[235]; + JOM(8, "lookup tables are prepared\n"); + } + pcache = peasycap->pcache; + if (NULL == pcache) + pcache = &peasycap->cache[0]; /*---------------------------------------------------------------------------*/ /* * TRANSFER CONTENTS OF CACHE TO THE FRAME BUFFER */ /*---------------------------------------------------------------------------*/ -if (!pcache) { - SAM("MISTAKE: pcache is NULL\n"); - return -EFAULT; -} + if (!pcache) { + SAM("MISTAKE: pcache is NULL\n"); + return -EFAULT; + } -if (pcache != &peasycap->cache[0]) - JOM(16, "cache has %i bytes\n", (int)(pcache - &peasycap->cache[0])); -p2 = &peasycap->cache[0]; -p3 = (u8 *)pad - (int)(pcache - &peasycap->cache[0]); -while (p2 < pcache) { - *p3++ = *p2; p2++; -} -pcache = &peasycap->cache[0]; -if (p3 != pad) { - SAM("MISTAKE: pointer misalignment\n"); - return -EFAULT; -} + if (pcache != &peasycap->cache[0]) + JOM(16, "cache has %i bytes\n", (int)(pcache - &peasycap->cache[0])); + p2 = &peasycap->cache[0]; + p3 = (u8 *)pad - (int)(pcache - &peasycap->cache[0]); + while (p2 < pcache) { + *p3++ = *p2; p2++; + } + pcache = &peasycap->cache[0]; + if (p3 != pad) { + SAM("MISTAKE: pointer misalignment\n"); + return -EFAULT; + } /*---------------------------------------------------------------------------*/ -rump = (int)(0x03 & mask); -u = 0; v = 0; -p2 = (u8 *)pex; pz = p2 + much; pr = p3 + more; last = false; -p2++; + rump = (int)(0x03 & mask); + u = 0; v = 0; + p2 = (u8 *)pex; pz = p2 + much; pr = p3 + more; last = false; + p2++; -if (true == isuy) - u = *(p2 - 1); -else - v = *(p2 - 1); + if (true == isuy) + u = *(p2 - 1); + else + v = *(p2 - 1); -if (rump) - JOM(16, "%4i=much %4i=more %i=rump\n", much, more, rump); + if (rump) + JOM(16, "%4i=much %4i=more %i=rump\n", much, more, rump); /*---------------------------------------------------------------------------*/ -switch (bytesperpixel) { -case 2: { - if (false == decimatepixel) { - memcpy(pad, pex, (size_t)much); - if (false == byteswaporder) - /*---------------------------------------------------*/ - /* - ** UYVY - */ - /*---------------------------------------------------*/ - return 0; - else { - /*---------------------------------------------------*/ - /* - ** YUYV - */ - /*---------------------------------------------------*/ - p3 = (u8 *)pad; pz = p3 + much; - while (pz > p3) { - c = *p3; - *p3 = *(p3 + 1); - *(p3 + 1) = c; - p3 += 2; - } - return 0; - } - } else { - if (false == byteswaporder) { - /*---------------------------------------------------*/ - /* - ** UYVY DECIMATED - */ - /*---------------------------------------------------*/ - p2 = (u8 *)pex; p3 = (u8 *)pad; pz = p2 + much; - while (pz > p2) { - *p3 = *p2; - *(p3 + 1) = *(p2 + 1); - *(p3 + 2) = *(p2 + 2); - *(p3 + 3) = *(p2 + 3); - p3 += 4; p2 += 8; - } - return 0; - } else { - /*---------------------------------------------------*/ - /* - ** YUYV DECIMATED - **/ - /*---------------------------------------------------*/ - p2 = (u8 *)pex; p3 = (u8 *)pad; pz = p2 + much; - while (pz > p2) { - *p3 = *(p2 + 1); - *(p3 + 1) = *p2; - *(p3 + 2) = *(p2 + 3); - *(p3 + 3) = *(p2 + 2); - p3 += 4; p2 += 8; - } - return 0; - } - } - break; - } -case 3: - { - if (false == decimatepixel) { - if (false == byteswaporder) { - /*---------------------------------------------------*/ - /* - ** RGB - **/ - /*---------------------------------------------------*/ - while (pz > p2) { - if (pr <= (p3 + bytesperpixel)) - last = true; - else - last = false; - y = *p2; - if ((true == last) && (0x0C & mask)) { - if (0x04 & mask) { - if (true == isuy) - v = margin; - else - u = margin; - } else - if (0x08 & mask) - ; - } else { - if (true == isuy) - v = *(p2 + 1); - else - u = *(p2 + 1); - } - - tmp = ay[(int)y] + rv[(int)v]; - r = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); - tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); - tmp = ay[(int)y] + bu[(int)u]; - b = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); - - if ((true == last) && rump) { - pcache = &peasycap->cache[0]; - switch (bytesperpixel - rump) { - case 1: { - *p3 = r; - *pcache++ = g; - *pcache++ = b; - break; - } - case 2: { - *p3 = r; - *(p3 + 1) = g; - *pcache++ = b; - break; - } - default: { - SAM("MISTAKE: %i=rump\n", - bytesperpixel - rump); - return -EFAULT; - } - } - } else { - *p3 = r; - *(p3 + 1) = g; - *(p3 + 2) = b; + switch (bytesperpixel) { + case 2: { + if (false == decimatepixel) { + memcpy(pad, pex, (size_t)much); + if (false == byteswaporder) { + /* UYVY */ + return 0; + } else { + /* YUYV */ + p3 = (u8 *)pad; pz = p3 + much; + while (pz > p3) { + c = *p3; + *p3 = *(p3 + 1); + *(p3 + 1) = c; + p3 += 2; } - p2 += 2; - if (true == isuy) - isuy = false; - else - isuy = true; - p3 += bytesperpixel; + return 0; } - return 0; } else { - /*---------------------------------------------------*/ - /* - ** BGR - */ - /*---------------------------------------------------*/ - while (pz > p2) { - if (pr <= (p3 + bytesperpixel)) - last = true; - else - last = false; - y = *p2; - if ((true == last) && (0x0C & mask)) { - if (0x04 & mask) { - if (true == isuy) - v = margin; - else - u = margin; - } - else - if (0x08 & mask) - ; - } else { - if (true == isuy) - v = *(p2 + 1); - else - u = *(p2 + 1); + if (false == byteswaporder) { + /* UYVY DECIMATED */ + p2 = (u8 *)pex; p3 = (u8 *)pad; pz = p2 + much; + while (pz > p2) { + *p3 = *p2; + *(p3 + 1) = *(p2 + 1); + *(p3 + 2) = *(p2 + 2); + *(p3 + 3) = *(p2 + 3); + p3 += 4; p2 += 8; } - - tmp = ay[(int)y] + rv[(int)v]; - r = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); - tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); - tmp = ay[(int)y] + bu[(int)u]; - b = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); - - if ((true == last) && rump) { - pcache = &peasycap->cache[0]; - switch (bytesperpixel - rump) { - case 1: { - *p3 = b; - *pcache++ = g; - *pcache++ = r; - break; - } - case 2: { - *p3 = b; - *(p3 + 1) = g; - *pcache++ = r; - break; - } - default: { - SAM("MISTAKE: %i=rump\n", - bytesperpixel - rump); - return -EFAULT; - } - } - } else { - *p3 = b; - *(p3 + 1) = g; - *(p3 + 2) = r; - } - p2 += 2; - if (true == isuy) - isuy = false; - else - isuy = true; - p3 += bytesperpixel; + return 0; + } else { + /* YUYV DECIMATED */ + p2 = (u8 *)pex; p3 = (u8 *)pad; pz = p2 + much; + while (pz > p2) { + *p3 = *(p2 + 1); + *(p3 + 1) = *p2; + *(p3 + 2) = *(p2 + 3); + *(p3 + 3) = *(p2 + 2); + p3 += 4; p2 += 8; } + return 0; } - return 0; - } else { - if (false == byteswaporder) { - /*---------------------------------------------------*/ - /* - ** RGB DECIMATED - */ - /*---------------------------------------------------*/ - while (pz > p2) { - if (pr <= (p3 + bytesperpixel)) - last = true; - else - last = false; - y = *p2; - if ((true == last) && (0x0C & mask)) { - if (0x04 & mask) { + } + break; + } + case 3: + { + if (false == decimatepixel) { + if (false == byteswaporder) { + /* RGB */ + while (pz > p2) { + if (pr <= (p3 + bytesperpixel)) + last = true; + else + last = false; + y = *p2; + if ((true == last) && (0x0C & mask)) { + if (0x04 & mask) { + if (true == isuy) + v = margin; + else + u = margin; + } else + if (0x08 & mask) + ; + } else { if (true == isuy) - v = margin; + v = *(p2 + 1); else - u = margin; - } else - if (0x08 & mask) - ; - } else { - if (true == isuy) - v = *(p2 + 1); - else - u = *(p2 + 1); - } + u = *(p2 + 1); + } - if (true == isuy) { tmp = ay[(int)y] + rv[(int)v]; r = (255 < tmp) ? 255 : ((0 > tmp) ? 0 : (u8)tmp); - tmp = ay[(int)y] - gu[(int)u] - - gv[(int)v]; + tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; g = (255 < tmp) ? 255 : ((0 > tmp) ? 0 : (u8)tmp); tmp = ay[(int)y] + bu[(int)u]; @@ -2155,9 +1947,8 @@ case 3: break; } default: { - SAM("MISTAKE: " - "%i=rump\n", - bytesperpixel - rump); + SAM("MISTAKE: %i=rump\n", + bytesperpixel - rump); return -EFAULT; } } @@ -2166,54 +1957,48 @@ case 3: *(p3 + 1) = g; *(p3 + 2) = b; } - isuy = false; + p2 += 2; + if (true == isuy) + isuy = false; + else + isuy = true; p3 += bytesperpixel; - } else { - isuy = true; } - p2 += 2; - } - return 0; - } else { - /*---------------------------------------------------*/ - /* - * BGR DECIMATED - */ - /*---------------------------------------------------*/ - while (pz > p2) { - if (pr <= (p3 + bytesperpixel)) - last = true; - else - last = false; - y = *p2; - if ((true == last) && (0x0C & mask)) { - if (0x04 & mask) { - if (true == isuy) - v = margin; - else - u = margin; - } else + return 0; + } else { + /* BGR */ + while (pz > p2) { + if (pr <= (p3 + bytesperpixel)) + last = true; + else + last = false; + y = *p2; + if ((true == last) && (0x0C & mask)) { + if (0x04 & mask) { + if (true == isuy) + v = margin; + else + u = margin; + } + else if (0x08 & mask) ; - } else { - if (true == isuy) - v = *(p2 + 1); - else - u = *(p2 + 1); - } - - if (true == isuy) { + } else { + if (true == isuy) + v = *(p2 + 1); + else + u = *(p2 + 1); + } tmp = ay[(int)y] + rv[(int)v]; r = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); - tmp = ay[(int)y] - gu[(int)u] - - gv[(int)v]; + 0 : (u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; g = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); + 0 : (u8)tmp); tmp = ay[(int)y] + bu[(int)u]; b = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); + 0 : (u8)tmp); if ((true == last) && rump) { pcache = &peasycap->cache[0]; @@ -2231,9 +2016,8 @@ case 3: break; } default: { - SAM("MISTAKE: " - "%i=rump\n", - bytesperpixel - rump); + SAM("MISTAKE: %i=rump\n", + bytesperpixel - rump); return -EFAULT; } } @@ -2242,227 +2026,199 @@ case 3: *(p3 + 1) = g; *(p3 + 2) = r; } - isuy = false; + p2 += 2; + if (true == isuy) + isuy = false; + else + isuy = true; p3 += bytesperpixel; } - else - isuy = true; - p2 += 2; } return 0; - } - } - break; - } -case 4: - { - if (false == decimatepixel) { - if (false == byteswaporder) { - /*---------------------------------------------------*/ - /* - ** RGBA - */ - /*---------------------------------------------------*/ - while (pz > p2) { - if (pr <= (p3 + bytesperpixel)) - last = true; - else - last = false; - y = *p2; - if ((true == last) && (0x0C & mask)) { - if (0x04 & mask) { + } else { + if (false == byteswaporder) { + /* RGB DECIMATED */ + while (pz > p2) { + if (pr <= (p3 + bytesperpixel)) + last = true; + else + last = false; + y = *p2; + if ((true == last) && (0x0C & mask)) { + if (0x04 & mask) { + if (true == isuy) + v = margin; + else + u = margin; + } else + if (0x08 & mask) + ; + } else { if (true == isuy) - v = margin; + v = *(p2 + 1); else - u = margin; - } else - if (0x08 & mask) - ; - } else { - if (true == isuy) - v = *(p2 + 1); - else - u = *(p2 + 1); - } - - tmp = ay[(int)y] + rv[(int)v]; - r = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); - tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); - tmp = ay[(int)y] + bu[(int)u]; - b = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); - - if ((true == last) && rump) { - pcache = &peasycap->cache[0]; - switch (bytesperpixel - rump) { - case 1: { - *p3 = r; - *pcache++ = g; - *pcache++ = b; - *pcache++ = 0; - break; - } - case 2: { - *p3 = r; - *(p3 + 1) = g; - *pcache++ = b; - *pcache++ = 0; - break; - } - case 3: { - *p3 = r; - *(p3 + 1) = g; - *(p3 + 2) = b; - *pcache++ = 0; - break; - } - default: { - SAM("MISTAKE: %i=rump\n", - bytesperpixel - rump); - return -EFAULT; + u = *(p2 + 1); } + + if (true == isuy) { + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - + gv[(int)v]; + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + + if ((true == last) && rump) { + pcache = &peasycap->cache[0]; + switch (bytesperpixel - rump) { + case 1: { + *p3 = r; + *pcache++ = g; + *pcache++ = b; + break; + } + case 2: { + *p3 = r; + *(p3 + 1) = g; + *pcache++ = b; + break; + } + default: { + SAM("MISTAKE: " + "%i=rump\n", + bytesperpixel - rump); + return -EFAULT; + } + } + } else { + *p3 = r; + *(p3 + 1) = g; + *(p3 + 2) = b; + } + isuy = false; + p3 += bytesperpixel; + } else { + isuy = true; } - } else { - *p3 = r; - *(p3 + 1) = g; - *(p3 + 2) = b; - *(p3 + 3) = 0; + p2 += 2; } - p2 += 2; - if (true == isuy) - isuy = false; - else - isuy = true; - p3 += bytesperpixel; - } - return 0; - } else { - /*---------------------------------------------------*/ - /* - ** BGRA - */ - /*---------------------------------------------------*/ - while (pz > p2) { - if (pr <= (p3 + bytesperpixel)) - last = true; - else - last = false; - y = *p2; - if ((true == last) && (0x0C & mask)) { - if (0x04 & mask) { + return 0; + } else { + /* BGR DECIMATED */ + while (pz > p2) { + if (pr <= (p3 + bytesperpixel)) + last = true; + else + last = false; + y = *p2; + if ((true == last) && (0x0C & mask)) { + if (0x04 & mask) { + if (true == isuy) + v = margin; + else + u = margin; + } else + if (0x08 & mask) + ; + } else { if (true == isuy) - v = margin; + v = *(p2 + 1); else - u = margin; - } else - if (0x08 & mask) - ; - } else { - if (true == isuy) - v = *(p2 + 1); - else - u = *(p2 + 1); - } - - tmp = ay[(int)y] + rv[(int)v]; - r = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); - tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); - tmp = ay[(int)y] + bu[(int)u]; - b = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); - - if ((true == last) && rump) { - pcache = &peasycap->cache[0]; - switch (bytesperpixel - rump) { - case 1: { - *p3 = b; - *pcache++ = g; - *pcache++ = r; - *pcache++ = 0; - break; - } - case 2: { - *p3 = b; - *(p3 + 1) = g; - *pcache++ = r; - *pcache++ = 0; - break; - } - case 3: { - *p3 = b; - *(p3 + 1) = g; - *(p3 + 2) = r; - *pcache++ = 0; - break; - } - default: { - SAM("MISTAKE: %i=rump\n", - bytesperpixel - rump); - return -EFAULT; + u = *(p2 + 1); } + + if (true == isuy) { + + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - + gv[(int)v]; + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + + if ((true == last) && rump) { + pcache = &peasycap->cache[0]; + switch (bytesperpixel - rump) { + case 1: { + *p3 = b; + *pcache++ = g; + *pcache++ = r; + break; + } + case 2: { + *p3 = b; + *(p3 + 1) = g; + *pcache++ = r; + break; + } + default: { + SAM("MISTAKE: " + "%i=rump\n", + bytesperpixel - rump); + return -EFAULT; + } + } + } else { + *p3 = b; + *(p3 + 1) = g; + *(p3 + 2) = r; + } + isuy = false; + p3 += bytesperpixel; + } + else + isuy = true; + p2 += 2; } - } else { - *p3 = b; - *(p3 + 1) = g; - *(p3 + 2) = r; - *(p3 + 3) = 0; + return 0; } - p2 += 2; - if (true == isuy) - isuy = false; - else - isuy = true; - p3 += bytesperpixel; } + break; } - return 0; - } else { - if (false == byteswaporder) { - /*---------------------------------------------------*/ - /* - ** RGBA DECIMATED - */ - /*---------------------------------------------------*/ - while (pz > p2) { - if (pr <= (p3 + bytesperpixel)) - last = true; - else - last = false; - y = *p2; - if ((true == last) && (0x0C & mask)) { - if (0x04 & mask) { + case 4: + { + if (false == decimatepixel) { + if (false == byteswaporder) { + /* RGBA */ + while (pz > p2) { + if (pr <= (p3 + bytesperpixel)) + last = true; + else + last = false; + y = *p2; + if ((true == last) && (0x0C & mask)) { + if (0x04 & mask) { + if (true == isuy) + v = margin; + else + u = margin; + } else + if (0x08 & mask) + ; + } else { if (true == isuy) - v = margin; + v = *(p2 + 1); else - u = margin; - } else - if (0x08 & mask) - ; - } else { - if (true == isuy) - v = *(p2 + 1); - else - u = *(p2 + 1); - } - - if (true == isuy) { + u = *(p2 + 1); + } tmp = ay[(int)y] + rv[(int)v]; r = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); - tmp = ay[(int)y] - gu[(int)u] - - gv[(int)v]; + 0 : (u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; g = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); + 0 : (u8)tmp); tmp = ay[(int)y] + bu[(int)u]; b = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); + 0 : (u8)tmp); if ((true == last) && rump) { pcache = &peasycap->cache[0]; @@ -2489,65 +2245,60 @@ case 4: break; } default: { - SAM("MISTAKE: " - "%i=rump\n", - bytesperpixel - - rump); + SAM("MISTAKE: %i=rump\n", + bytesperpixel - rump); return -EFAULT; - } + } } } else { *p3 = r; *(p3 + 1) = g; *(p3 + 2) = b; *(p3 + 3) = 0; - } - isuy = false; - p3 += bytesperpixel; - } else - isuy = true; - p2 += 2; - } - return 0; - } else { - /*---------------------------------------------------*/ - /* - ** BGRA DECIMATED - */ - /*---------------------------------------------------*/ - while (pz > p2) { - if (pr <= (p3 + bytesperpixel)) - last = true; - else - last = false; - y = *p2; - if ((true == last) && (0x0C & mask)) { - if (0x04 & mask) { - if (true == isuy) - v = margin; - else - u = margin; - } else - if (0x08 & mask) - ; - } else { + } + p2 += 2; if (true == isuy) - v = *(p2 + 1); + isuy = false; else - u = *(p2 + 1); + isuy = true; + p3 += bytesperpixel; } + return 0; + } else { + /* + * BGRA + */ + while (pz > p2) { + if (pr <= (p3 + bytesperpixel)) + last = true; + else + last = false; + y = *p2; + if ((true == last) && (0x0C & mask)) { + if (0x04 & mask) { + if (true == isuy) + v = margin; + else + u = margin; + } else + if (0x08 & mask) + ; + } else { + if (true == isuy) + v = *(p2 + 1); + else + u = *(p2 + 1); + } - if (true == isuy) { tmp = ay[(int)y] + rv[(int)v]; r = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); - tmp = ay[(int)y] - gu[(int)u] - - gv[(int)v]; + 0 : (u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; g = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); + 0 : (u8)tmp); tmp = ay[(int)y] + bu[(int)u]; b = (255 < tmp) ? 255 : ((0 > tmp) ? - 0 : (u8)tmp); + 0 : (u8)tmp); if ((true == last) && rump) { pcache = &peasycap->cache[0]; @@ -2573,139 +2324,304 @@ case 4: *pcache++ = 0; break; } - default: { - SAM("MISTAKE: " - "%i=rump\n", - bytesperpixel - rump); + default: + SAM("MISTAKE: %i=rump\n", + bytesperpixel - rump); return -EFAULT; } - } } else { *p3 = b; *(p3 + 1) = g; *(p3 + 2) = r; *(p3 + 3) = 0; } - isuy = false; + p2 += 2; + if (true == isuy) + isuy = false; + else + isuy = true; p3 += bytesperpixel; - } else - isuy = true; + } + } + return 0; + } else { + if (false == byteswaporder) { + /* + * RGBA DECIMATED + */ + while (pz > p2) { + if (pr <= (p3 + bytesperpixel)) + last = true; + else + last = false; + y = *p2; + if ((true == last) && (0x0C & mask)) { + if (0x04 & mask) { + if (true == isuy) + v = margin; + else + u = margin; + } else + if (0x08 & mask) + ; + } else { + if (true == isuy) + v = *(p2 + 1); + else + u = *(p2 + 1); + } + + if (true == isuy) { + + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - + gv[(int)v]; + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + + if ((true == last) && rump) { + pcache = &peasycap->cache[0]; + switch (bytesperpixel - rump) { + case 1: { + *p3 = r; + *pcache++ = g; + *pcache++ = b; + *pcache++ = 0; + break; + } + case 2: { + *p3 = r; + *(p3 + 1) = g; + *pcache++ = b; + *pcache++ = 0; + break; + } + case 3: { + *p3 = r; + *(p3 + 1) = g; + *(p3 + 2) = b; + *pcache++ = 0; + break; + } + default: { + SAM("MISTAKE: " + "%i=rump\n", + bytesperpixel - + rump); + return -EFAULT; + } + } + } else { + *p3 = r; + *(p3 + 1) = g; + *(p3 + 2) = b; + *(p3 + 3) = 0; + } + isuy = false; + p3 += bytesperpixel; + } else + isuy = true; p2 += 2; } - return 0; + return 0; + } else { + /* + * BGRA DECIMATED + */ + while (pz > p2) { + if (pr <= (p3 + bytesperpixel)) + last = true; + else + last = false; + y = *p2; + if ((true == last) && (0x0C & mask)) { + if (0x04 & mask) { + if (true == isuy) + v = margin; + else + u = margin; + } else + if (0x08 & mask) + ; + } else { + if (true == isuy) + v = *(p2 + 1); + else + u = *(p2 + 1); + } + + if (true == isuy) { + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - + gv[(int)v]; + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + + if ((true == last) && rump) { + pcache = &peasycap->cache[0]; + switch (bytesperpixel - rump) { + case 1: { + *p3 = b; + *pcache++ = g; + *pcache++ = r; + *pcache++ = 0; + break; + } + case 2: { + *p3 = b; + *(p3 + 1) = g; + *pcache++ = r; + *pcache++ = 0; + break; + } + case 3: { + *p3 = b; + *(p3 + 1) = g; + *(p3 + 2) = r; + *pcache++ = 0; + break; + } + default: { + SAM("MISTAKE: " + "%i=rump\n", + bytesperpixel - rump); + return -EFAULT; + } + } + } else { + *p3 = b; + *(p3 + 1) = g; + *(p3 + 2) = r; + *(p3 + 3) = 0; + } + isuy = false; + p3 += bytesperpixel; + } else + isuy = true; + p2 += 2; + } + return 0; + } } + break; + } + default: { + SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel); + return -EFAULT; } - break; - } -default: { - SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel); - return -EFAULT; } -} -return 0; + return 0; } /*****************************************************************************/ -/*---------------------------------------------------------------------------*/ /* * SEE CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGES 430-434 */ -/*---------------------------------------------------------------------------*/ /*****************************************************************************/ static void easycap_vma_open(struct vm_area_struct *pvma) { -struct easycap *peasycap; + struct easycap *peasycap; -peasycap = pvma->vm_private_data; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); + peasycap = pvma->vm_private_data; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + return; + } + peasycap->vma_many++; + JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); return; } -peasycap->vma_many++; -JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); -return; -} /*****************************************************************************/ static void easycap_vma_close(struct vm_area_struct *pvma) { -struct easycap *peasycap; + struct easycap *peasycap; -peasycap = pvma->vm_private_data; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); + peasycap = pvma->vm_private_data; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + return; + } + peasycap->vma_many--; + JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); return; } -peasycap->vma_many--; -JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); -return; -} /*****************************************************************************/ static int easycap_vma_fault(struct vm_area_struct *pvma, struct vm_fault *pvmf) { -int k, m, retcode; -void *pbuf; -struct page *page; -struct easycap *peasycap; + int k, m, retcode; + void *pbuf; + struct page *page; + struct easycap *peasycap; -retcode = VM_FAULT_NOPAGE; + retcode = VM_FAULT_NOPAGE; -if (NULL == pvma) { - SAY("pvma is NULL\n"); - return retcode; -} -if (NULL == pvmf) { - SAY("pvmf is NULL\n"); - return retcode; -} + if (NULL == pvma) { + SAY("pvma is NULL\n"); + return retcode; + } + if (NULL == pvmf) { + SAY("pvmf is NULL\n"); + return retcode; + } -k = (pvmf->pgoff) / (FRAME_BUFFER_SIZE/PAGE_SIZE); -m = (pvmf->pgoff) % (FRAME_BUFFER_SIZE/PAGE_SIZE); + k = (pvmf->pgoff) / (FRAME_BUFFER_SIZE/PAGE_SIZE); + m = (pvmf->pgoff) % (FRAME_BUFFER_SIZE/PAGE_SIZE); -if (!m) - JOT(4, "%4i=k, %4i=m\n", k, m); -else - JOT(16, "%4i=k, %4i=m\n", k, m); + if (!m) + JOT(4, "%4i=k, %4i=m\n", k, m); + else + JOT(16, "%4i=k, %4i=m\n", k, m); -if ((0 > k) || (FRAME_BUFFER_MANY <= k)) { - SAY("ERROR: buffer index %i out of range\n", k); - return retcode; -} -if ((0 > m) || (FRAME_BUFFER_SIZE/PAGE_SIZE <= m)) { - SAY("ERROR: page number %i out of range\n", m); - return retcode; -} -peasycap = pvma->vm_private_data; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return retcode; -} + if ((0 > k) || (FRAME_BUFFER_MANY <= k)) { + SAY("ERROR: buffer index %i out of range\n", k); + return retcode; + } + if ((0 > m) || (FRAME_BUFFER_SIZE/PAGE_SIZE <= m)) { + SAY("ERROR: page number %i out of range\n", m); + return retcode; + } + peasycap = pvma->vm_private_data; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return retcode; + } /*---------------------------------------------------------------------------*/ -pbuf = peasycap->frame_buffer[k][m].pgo; -if (NULL == pbuf) { - SAM("ERROR: pbuf is NULL\n"); - return retcode; -} -page = virt_to_page(pbuf); -if (NULL == page) { - SAM("ERROR: page is NULL\n"); - return retcode; -} -get_page(page); + pbuf = peasycap->frame_buffer[k][m].pgo; + if (NULL == pbuf) { + SAM("ERROR: pbuf is NULL\n"); + return retcode; + } + page = virt_to_page(pbuf); + if (NULL == page) { + SAM("ERROR: page is NULL\n"); + return retcode; + } + get_page(page); /*---------------------------------------------------------------------------*/ -if (NULL == page) { - SAM("ERROR: page is NULL after get_page(page)\n"); -} else { - pvmf->page = page; - retcode = VM_FAULT_MINOR; -} -return retcode; + if (NULL == page) { + SAM("ERROR: page is NULL after get_page(page)\n"); + } else { + pvmf->page = page; + retcode = VM_FAULT_MINOR; + } + return retcode; } static const struct vm_operations_struct easycap_vm_ops = { @@ -2754,127 +2670,126 @@ static int easycap_mmap(struct file *file, struct vm_area_struct *pvma) /*---------------------------------------------------------------------------*/ static void easycap_complete(struct urb *purb) { -struct easycap *peasycap; -struct data_buffer *pfield_buffer; -char errbuf[16]; -int i, more, much, leap, rc, last; -int videofieldamount; -unsigned int override, bad; -int framestatus, framelength, frameactual, frameoffset; -u8 *pu; - -if (NULL == purb) { - SAY("ERROR: easycap_complete(): purb is NULL\n"); - return; -} -peasycap = purb->context; -if (NULL == peasycap) { - SAY("ERROR: easycap_complete(): peasycap is NULL\n"); - return; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return; -} -if (peasycap->video_eof) - return; -for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) - if (purb->transfer_buffer == peasycap->video_isoc_buffer[i].pgo) - break; -JOM(16, "%2i=urb\n", i); -last = peasycap->video_isoc_sequence; -if ((((VIDEO_ISOC_BUFFER_MANY - 1) == last) && - (0 != i)) || - (((VIDEO_ISOC_BUFFER_MANY - 1) != last) && - ((last + 1) != i))) { - JOM(16, "ERROR: out-of-order urbs %i,%i ... continuing\n", last, i); -} -peasycap->video_isoc_sequence = i; + struct easycap *peasycap; + struct data_buffer *pfield_buffer; + char errbuf[16]; + int i, more, much, leap, rc, last; + int videofieldamount; + unsigned int override, bad; + int framestatus, framelength, frameactual, frameoffset; + u8 *pu; + + if (NULL == purb) { + SAY("ERROR: easycap_complete(): purb is NULL\n"); + return; + } + peasycap = purb->context; + if (NULL == peasycap) { + SAY("ERROR: easycap_complete(): peasycap is NULL\n"); + return; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + return; + } + if (peasycap->video_eof) + return; + for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) + if (purb->transfer_buffer == peasycap->video_isoc_buffer[i].pgo) + break; + JOM(16, "%2i=urb\n", i); + last = peasycap->video_isoc_sequence; + if ((((VIDEO_ISOC_BUFFER_MANY - 1) == last) && (0 != i)) || + (((VIDEO_ISOC_BUFFER_MANY - 1) != last) && ((last + 1) != i))) { + JOM(16, "ERROR: out-of-order urbs %i,%i ... continuing\n", + last, i); + } + peasycap->video_isoc_sequence = i; -if (peasycap->video_idle) { - JOM(16, "%i=video_idle %i=video_isoc_streaming\n", - peasycap->video_idle, peasycap->video_isoc_streaming); - if (peasycap->video_isoc_streaming) { - rc = usb_submit_urb(purb, GFP_ATOMIC); - if (rc) { - SAM("%s:%d ENOMEM\n", strerror(rc), rc); - if (-ENODEV != rc) - SAM("ERROR: while %i=video_idle, " - "usb_submit_urb() " - "failed with rc:\n", - peasycap->video_idle); + if (peasycap->video_idle) { + JOM(16, "%i=video_idle %i=video_isoc_streaming\n", + peasycap->video_idle, peasycap->video_isoc_streaming); + if (peasycap->video_isoc_streaming) { + rc = usb_submit_urb(purb, GFP_ATOMIC); + if (rc) { + SAM("%s:%d ENOMEM\n", strerror(rc), rc); + if (-ENODEV != rc) + SAM("ERROR: while %i=video_idle, " + "usb_submit_urb() " + "failed with rc:\n", + peasycap->video_idle); + } } + return; } -return; -} -override = 0; + override = 0; /*---------------------------------------------------------------------------*/ -if (FIELD_BUFFER_MANY <= peasycap->field_fill) { - SAM("ERROR: bad peasycap->field_fill\n"); - return; -} -if (purb->status) { - if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) { - JOM(8, "urb status -ESHUTDOWN or -ENOENT\n"); + if (FIELD_BUFFER_MANY <= peasycap->field_fill) { + SAM("ERROR: bad peasycap->field_fill\n"); return; } + if (purb->status) { + if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) { + JOM(8, "urb status -ESHUTDOWN or -ENOENT\n"); + return; + } - (peasycap->field_buffer[peasycap->field_fill][0].kount) |= 0x8000 ; - SAM("ERROR: bad urb status -%s: %d\n", - strerror(purb->status), purb->status); + (peasycap->field_buffer[peasycap->field_fill][0].kount) |= 0x8000 ; + SAM("ERROR: bad urb status -%s: %d\n", + strerror(purb->status), purb->status); /*---------------------------------------------------------------------------*/ -} else { - for (i = 0; i < purb->number_of_packets; i++) { - if (0 != purb->iso_frame_desc[i].status) { - (peasycap->field_buffer - [peasycap->field_fill][0].kount) |= 0x8000 ; - /* FIXME: 1. missing '-' check boundaries */ - strcpy(&errbuf[0], - strerror(purb->iso_frame_desc[i].status)); - } - framestatus = purb->iso_frame_desc[i].status; - framelength = purb->iso_frame_desc[i].length; - frameactual = purb->iso_frame_desc[i].actual_length; - frameoffset = purb->iso_frame_desc[i].offset; - - JOM(16, "frame[%2i]:" - "%4i=status " - "%4i=actual " - "%4i=length " - "%5i=offset\n", - i, framestatus, frameactual, framelength, frameoffset); - if (!purb->iso_frame_desc[i].status) { - more = purb->iso_frame_desc[i].actual_length; - pfield_buffer = &peasycap->field_buffer - [peasycap->field_fill][peasycap->field_page]; - videofieldamount = (peasycap->field_page * - PAGE_SIZE) + - (int)(pfield_buffer->pto - pfield_buffer->pgo); - if (4 == more) - peasycap->video_mt++; - if (4 < more) { - if (peasycap->video_mt) { - JOM(8, "%4i empty video urb frames\n", - peasycap->video_mt); - peasycap->video_mt = 0; - } - if (FIELD_BUFFER_MANY <= peasycap->field_fill) { - SAM("ERROR: bad peasycap->field_fill\n"); - return; - } - if (FIELD_BUFFER_SIZE/PAGE_SIZE <= - peasycap->field_page) { - SAM("ERROR: bad peasycap->field_page\n"); - return; + } else { + for (i = 0; i < purb->number_of_packets; i++) { + if (0 != purb->iso_frame_desc[i].status) { + (peasycap->field_buffer + [peasycap->field_fill][0].kount) |= 0x8000 ; + /* FIXME: 1. missing '-' check boundaries */ + strcpy(&errbuf[0], + strerror(purb->iso_frame_desc[i].status)); } - pfield_buffer = &peasycap->field_buffer - [peasycap->field_fill][peasycap->field_page]; - pu = (u8 *)(purb->transfer_buffer + - purb->iso_frame_desc[i].offset); - if (0x80 & *pu) - leap = 8; - else - leap = 4; + framestatus = purb->iso_frame_desc[i].status; + framelength = purb->iso_frame_desc[i].length; + frameactual = purb->iso_frame_desc[i].actual_length; + frameoffset = purb->iso_frame_desc[i].offset; + + JOM(16, "frame[%2i]:" + "%4i=status " + "%4i=actual " + "%4i=length " + "%5i=offset\n", + i, framestatus, frameactual, framelength, frameoffset); + if (!purb->iso_frame_desc[i].status) { + more = purb->iso_frame_desc[i].actual_length; + pfield_buffer = &peasycap->field_buffer + [peasycap->field_fill][peasycap->field_page]; + videofieldamount = (peasycap->field_page * + PAGE_SIZE) + + (int)(pfield_buffer->pto - pfield_buffer->pgo); + if (4 == more) + peasycap->video_mt++; + if (4 < more) { + if (peasycap->video_mt) { + JOM(8, "%4i empty video urb frames\n", + peasycap->video_mt); + peasycap->video_mt = 0; + } + if (FIELD_BUFFER_MANY <= peasycap->field_fill) { + SAM("ERROR: bad peasycap->field_fill\n"); + return; + } + if (FIELD_BUFFER_SIZE/PAGE_SIZE <= + peasycap->field_page) { + SAM("ERROR: bad peasycap->field_page\n"); + return; + } + pfield_buffer = &peasycap->field_buffer + [peasycap->field_fill][peasycap->field_page]; + pu = (u8 *)(purb->transfer_buffer + + purb->iso_frame_desc[i].offset); + if (0x80 & *pu) + leap = 8; + else + leap = 4; /*--------------------------------------------------------------------------*/ /* * EIGHT-BYTE END-OF-VIDEOFIELD MARKER. @@ -2892,196 +2807,195 @@ if (purb->status) { * RESTS WITH dqbuf(). */ /*---------------------------------------------------------------------------*/ - if ((8 == more) || override) { - if (videofieldamount > - peasycap->videofieldamount) { - if (2 == videofieldamount - - peasycap-> - videofieldamount) { - (peasycap->field_buffer - [peasycap->field_fill] - [0].kount) |= 0x0100; - peasycap->video_junk += (1 + - VIDEO_JUNK_TOLERATE); - } else - (peasycap->field_buffer - [peasycap->field_fill] - [0].kount) |= 0x4000; - } else if (videofieldamount < - peasycap-> - videofieldamount) { - (peasycap->field_buffer - [peasycap->field_fill] - [0].kount) |= 0x2000; - } - bad = 0xFF00 & peasycap->field_buffer - [peasycap->field_fill] - [0].kount; - if (!bad) { - (peasycap->video_junk)--; - if (-VIDEO_JUNK_TOLERATE > - peasycap->video_junk) - peasycap->video_junk = - -VIDEO_JUNK_TOLERATE; - peasycap->field_read = - (peasycap-> - field_fill)++; - if (FIELD_BUFFER_MANY <= + if ((8 == more) || override) { + if (videofieldamount > + peasycap->videofieldamount) { + if (2 == videofieldamount - + peasycap-> + videofieldamount) { + (peasycap->field_buffer + [peasycap->field_fill] + [0].kount) |= 0x0100; + peasycap->video_junk += (1 + + VIDEO_JUNK_TOLERATE); + } else + (peasycap->field_buffer + [peasycap->field_fill] + [0].kount) |= 0x4000; + } else if (videofieldamount < + peasycap-> + videofieldamount) { + (peasycap->field_buffer + [peasycap->field_fill] + [0].kount) |= 0x2000; + } + bad = 0xFF00 & peasycap->field_buffer + [peasycap->field_fill] + [0].kount; + if (!bad) { + (peasycap->video_junk)--; + if (-VIDEO_JUNK_TOLERATE > + peasycap->video_junk) + peasycap->video_junk = + -VIDEO_JUNK_TOLERATE; + peasycap->field_read = + (peasycap-> + field_fill)++; + if (FIELD_BUFFER_MANY <= + peasycap-> + field_fill) peasycap-> - field_fill) - peasycap-> - field_fill = 0; + field_fill = 0; + peasycap->field_page = 0; + pfield_buffer = &peasycap-> + field_buffer + [peasycap-> + field_fill] + [peasycap-> + field_page]; + pfield_buffer->pto = + pfield_buffer->pgo; + JOM(8, "bumped to: %i=" + "peasycap->" + "field_fill %i=" + "parity\n", + peasycap->field_fill, + 0x00FF & + pfield_buffer->kount); + JOM(8, "field buffer %i has " + "%i bytes fit to be " + "read\n", + peasycap->field_read, + videofieldamount); + JOM(8, "wakeup call to " + "wq_video, " + "%i=field_read " + "%i=field_fill " + "%i=parity\n", + peasycap->field_read, + peasycap->field_fill, + 0x00FF & peasycap-> + field_buffer + [peasycap-> + field_read][0].kount); + wake_up_interruptible + (&(peasycap-> + wq_video)); + do_gettimeofday + (&peasycap->timeval7); + } else { + peasycap->video_junk++; + if (bad & 0x0010) + peasycap->video_junk += + (1 + VIDEO_JUNK_TOLERATE/2); + JOM(8, "field buffer %i had %i " + "bytes, now discarded: " + "0x%04X\n", + peasycap->field_fill, + videofieldamount, + (0xFF00 & + peasycap->field_buffer + [peasycap->field_fill][0]. + kount)); + (peasycap->field_fill)++; + + if (FIELD_BUFFER_MANY <= + peasycap->field_fill) + peasycap->field_fill = 0; peasycap->field_page = 0; - pfield_buffer = &peasycap-> - field_buffer - [peasycap-> - field_fill] - [peasycap-> - field_page]; + pfield_buffer = + &peasycap->field_buffer + [peasycap->field_fill] + [peasycap->field_page]; pfield_buffer->pto = - pfield_buffer->pgo; - JOM(8, "bumped to: %i=" - "peasycap->" - "field_fill %i=" - "parity\n", - peasycap->field_fill, - 0x00FF & - pfield_buffer->kount); - JOM(8, "field buffer %i has " - "%i bytes fit to be " - "read\n", - peasycap->field_read, - videofieldamount); - JOM(8, "wakeup call to " - "wq_video, " - "%i=field_read " - "%i=field_fill " - "%i=parity\n", - peasycap->field_read, + pfield_buffer->pgo; + + JOM(8, "bumped to: %i=peasycap->" + "field_fill %i=parity\n", peasycap->field_fill, - 0x00FF & peasycap-> - field_buffer - [peasycap-> - field_read][0].kount); - wake_up_interruptible - (&(peasycap-> - wq_video)); - do_gettimeofday - (&peasycap->timeval7); - } else { - peasycap->video_junk++; - if (bad & 0x0010) - peasycap->video_junk += - (1 + VIDEO_JUNK_TOLERATE/2); - JOM(8, "field buffer %i had %i " - "bytes, now discarded: " - "0x%04X\n", - peasycap->field_fill, - videofieldamount, - (0xFF00 & - peasycap->field_buffer - [peasycap->field_fill][0]. - kount)); - (peasycap->field_fill)++; - - if (FIELD_BUFFER_MANY <= - peasycap->field_fill) - peasycap->field_fill = 0; - peasycap->field_page = 0; - pfield_buffer = - &peasycap->field_buffer - [peasycap->field_fill] - [peasycap->field_page]; - pfield_buffer->pto = - pfield_buffer->pgo; - - JOM(8, "bumped to: %i=peasycap->" - "field_fill %i=parity\n", - peasycap->field_fill, - 0x00FF & pfield_buffer->kount); - } - if (8 == more) { - JOM(8, "end-of-field: received " - "parity byte 0x%02X\n", - (0xFF & *pu)); - if (0x40 & *pu) - pfield_buffer->kount = 0x0000; - else - pfield_buffer->kount = 0x0001; - pfield_buffer->input = 0x08 | - (0x07 & peasycap->input); - JOM(8, "end-of-field: 0x%02X=kount\n", - 0xFF & pfield_buffer->kount); + 0x00FF & pfield_buffer->kount); + } + if (8 == more) { + JOM(8, "end-of-field: received " + "parity byte 0x%02X\n", + (0xFF & *pu)); + if (0x40 & *pu) + pfield_buffer->kount = 0x0000; + else + pfield_buffer->kount = 0x0001; + pfield_buffer->input = 0x08 | + (0x07 & peasycap->input); + JOM(8, "end-of-field: 0x%02X=kount\n", + 0xFF & pfield_buffer->kount); + } } - } /*---------------------------------------------------------------------------*/ /* * COPY more BYTES FROM ISOC BUFFER TO FIELD BUFFER */ /*---------------------------------------------------------------------------*/ - pu += leap; - more -= leap; + pu += leap; + more -= leap; - if (FIELD_BUFFER_MANY <= peasycap->field_fill) { - SAM("ERROR: bad peasycap->field_fill\n"); - return; - } - if (FIELD_BUFFER_SIZE/PAGE_SIZE <= - peasycap->field_page) { - SAM("ERROR: bad peasycap->field_page\n"); - return; - } - pfield_buffer = &peasycap->field_buffer - [peasycap->field_fill][peasycap->field_page]; - while (more) { - pfield_buffer = &peasycap->field_buffer - [peasycap->field_fill] - [peasycap->field_page]; - if (PAGE_SIZE < (pfield_buffer->pto - - pfield_buffer->pgo)) { - SAM("ERROR: bad pfield_buffer->pto\n"); + if (FIELD_BUFFER_MANY <= peasycap->field_fill) { + SAM("ERROR: bad peasycap->field_fill\n"); return; } - if (PAGE_SIZE == (pfield_buffer->pto - - pfield_buffer->pgo)) { - (peasycap->field_page)++; - if (FIELD_BUFFER_SIZE/PAGE_SIZE <= - peasycap->field_page) { - JOM(16, "wrapping peasycap->" - "field_page\n"); - peasycap->field_page = 0; - } - pfield_buffer = &peasycap-> - field_buffer + if (FIELD_BUFFER_SIZE/PAGE_SIZE <= peasycap->field_page) { + SAM("ERROR: bad peasycap->field_page\n"); + return; + } + pfield_buffer = &peasycap->field_buffer + [peasycap->field_fill][peasycap->field_page]; + while (more) { + pfield_buffer = &peasycap->field_buffer [peasycap->field_fill] [peasycap->field_page]; - pfield_buffer->pto = - pfield_buffer->pgo; - pfield_buffer->input = 0x08 | - (0x07 & peasycap->input); - if ((peasycap->field_buffer[peasycap-> - field_fill][0]). - input != - pfield_buffer->input) - (peasycap->field_buffer - [peasycap->field_fill] - [0]).kount |= 0x1000; - } + if (PAGE_SIZE < (pfield_buffer->pto - + pfield_buffer->pgo)) { + SAM("ERROR: bad pfield_buffer->pto\n"); + return; + } + if (PAGE_SIZE == (pfield_buffer->pto - + pfield_buffer->pgo)) { + (peasycap->field_page)++; + if (FIELD_BUFFER_SIZE/PAGE_SIZE <= + peasycap->field_page) { + JOM(16, "wrapping peasycap->" + "field_page\n"); + peasycap->field_page = 0; + } + pfield_buffer = &peasycap-> + field_buffer + [peasycap->field_fill] + [peasycap->field_page]; + pfield_buffer->pto = pfield_buffer->pgo; + pfield_buffer->input = 0x08 | + (0x07 & peasycap->input); + if ((peasycap->field_buffer[peasycap-> + field_fill][0]). + input != + pfield_buffer->input) + (peasycap->field_buffer + [peasycap->field_fill] + [0]).kount |= 0x1000; + } - much = PAGE_SIZE - (int)(pfield_buffer->pto - + much = PAGE_SIZE - + (int)(pfield_buffer->pto - pfield_buffer->pgo); - if (much > more) - much = more; - memcpy(pfield_buffer->pto, pu, much); - pu += much; - (pfield_buffer->pto) += much; - more -= much; + if (much > more) + much = more; + memcpy(pfield_buffer->pto, pu, much); + pu += much; + (pfield_buffer->pto) += much; + more -= much; + } } } } } -} /*---------------------------------------------------------------------------*/ /* * RESUBMIT THIS URB, UNLESS A SEVERE PERSISTENT ERROR CONDITION EXISTS. @@ -3090,30 +3004,30 @@ if (purb->status) { * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE. */ /*---------------------------------------------------------------------------*/ -if (VIDEO_ISOC_BUFFER_MANY <= peasycap->video_junk) { - SAM("easycap driver shutting down on condition green\n"); - peasycap->status = 1; - peasycap->video_eof = 1; - peasycap->video_junk = 0; - wake_up_interruptible(&peasycap->wq_video); + if (VIDEO_ISOC_BUFFER_MANY <= peasycap->video_junk) { + SAM("easycap driver shutting down on condition green\n"); + peasycap->status = 1; + peasycap->video_eof = 1; + peasycap->video_junk = 0; + wake_up_interruptible(&peasycap->wq_video); #if !defined(PERSEVERE) - peasycap->audio_eof = 1; - wake_up_interruptible(&peasycap->wq_audio); + peasycap->audio_eof = 1; + wake_up_interruptible(&peasycap->wq_audio); #endif /*PERSEVERE*/ - return; -} -if (peasycap->video_isoc_streaming) { - rc = usb_submit_urb(purb, GFP_ATOMIC); - if (rc) { - SAM("%s: %d\n", strerror(rc), rc); - if (-ENODEV != rc) - SAM("ERROR: while %i=video_idle, " - "usb_submit_urb() " - "failed with rc:\n", - peasycap->video_idle); + return; } -} -return; + if (peasycap->video_isoc_streaming) { + rc = usb_submit_urb(purb, GFP_ATOMIC); + if (rc) { + SAM("%s: %d\n", strerror(rc), rc); + if (-ENODEV != rc) + SAM("ERROR: while %i=video_idle, " + "usb_submit_urb() " + "failed with rc:\n", + peasycap->video_idle); + } + } + return; } static const struct file_operations easycap_fops = { .owner = THIS_MODULE, @@ -3339,7 +3253,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, /*---------------------------------------------------------------------------*/ rc = fillin_formats(); if (0 > rc) { - SAM("ERROR: fillin_formats() returned %i\n", rc); + SAM("ERROR: fillin_formats() rc = %i\n", rc); return -EFAULT; } JOM(4, "%i formats available\n", rc); @@ -3443,8 +3357,8 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, if (pusb_device == easycapdc60_dongle[ndong].peasycap-> pusb_device) { peasycap = easycapdc60_dongle[ndong].peasycap; - JOT(8, "intf[%i]: easycapdc60_dongle[%i].peasycap-->" - "peasycap\n", bInterfaceNumber, ndong); + JOT(8, "intf[%i]: dongle[%i].peasycap\n", + bInterfaceNumber, ndong); break; } } @@ -4024,7 +3938,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, easycap_ntsc ? "NTSC" : "PAL"); rc = reset(peasycap); if (rc) { - SAM("ERROR: reset() returned %i\n", rc); + SAM("ERROR: reset() rc = %i\n", rc); return -EFAULT; } /*--------------------------------------------------------------------------*/ @@ -4109,7 +4023,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, pusb_interface_descriptor->bInterfaceNumber); break; } - /*--------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------*/ case 2: { if (!peasycap) { SAM("MISTAKE: peasycap is NULL\n"); @@ -4376,7 +4290,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, rc = easycap_alsa_probe(peasycap); if (rc) { - err("easycap_alsa_probe() returned %i\n", rc); + err("easycap_alsa_probe() rc = %i\n", rc); return -ENODEV; } else { JOM(8, "kref_get() with %i=kref.refcount.counter\n", @@ -4539,10 +4453,9 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) } break; } -/*---------------------------------------------------------------------------*/ default: break; -} + } /*--------------------------------------------------------------------------*/ /* * DEREGISTER @@ -4552,145 +4465,136 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) * AN EasyCAP IS UNPLUGGED WHILE THE URBS ARE RUNNING. BEWARE. */ /*--------------------------------------------------------------------------*/ -kd = isdongle(peasycap); -switch (bInterfaceNumber) { -case 0: { - if (0 <= kd && DONGLE_MANY > kd) { - wake_up_interruptible(&peasycap->wq_video); - JOM(4, "about to lock easycapdc60_dongle[%i].mutex_video\n", - kd); - if (mutex_lock_interruptible(&easycapdc60_dongle[kd]. + kd = isdongle(peasycap); + switch (bInterfaceNumber) { + case 0: { + if (0 <= kd && DONGLE_MANY > kd) { + wake_up_interruptible(&peasycap->wq_video); + JOM(4, "about to lock dongle[%i].mutex_video\n", kd); + if (mutex_lock_interruptible(&easycapdc60_dongle[kd]. mutex_video)) { - SAY("ERROR: cannot lock easycapdc60_dongle[%i]." - "mutex_video\n", kd); - return; + SAY("ERROR: " + "cannot lock dongle[%i].mutex_video\n", kd); + return; + } + JOM(4, "locked dongle[%i].mutex_video\n", kd); + } else { + SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); } - JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd); - } else - SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); /*---------------------------------------------------------------------------*/ #ifndef EASYCAP_IS_VIDEODEV_CLIENT - if (NULL == peasycap) { - SAM("ERROR: peasycap has become NULL\n"); - } else { - usb_deregister_dev(pusb_interface, &easycap_class); - (peasycap->registered_video)--; - JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber); - SAM("easycap detached from minor #%d\n", minor); - } + if (NULL == peasycap) { + SAM("ERROR: peasycap has become NULL\n"); + } else { + usb_deregister_dev(pusb_interface, &easycap_class); + peasycap->registered_video--; + JOM(4, "intf[%i]: usb_deregister_dev() minor = %i\n", + bInterfaceNumber, minor); + } /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #else - if (!peasycap->v4l2_device.name[0]) { - SAM("ERROR: peasycap->v4l2_device.name is empty\n"); - if (0 <= kd && DONGLE_MANY > kd) - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return; - } - v4l2_device_disconnect(&peasycap->v4l2_device); - JOM(4, "v4l2_device_disconnect() OK\n"); - v4l2_device_unregister(&peasycap->v4l2_device); - JOM(4, "v4l2_device_unregister() OK\n"); - - video_unregister_device(&peasycap->video_device); - JOM(4, "intf[%i]: video_unregister_device() OK\n", bInterfaceNumber); - (peasycap->registered_video)--; - JOM(4, "unregistered with videodev: %i=minor\n", minor); + if (!peasycap->v4l2_device.name[0]) { + SAM("ERROR: peasycap->v4l2_device.name is empty\n"); + if (0 <= kd && DONGLE_MANY > kd) + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return; + } + v4l2_device_disconnect(&peasycap->v4l2_device); + JOM(4, "v4l2_device_disconnect() OK\n"); + v4l2_device_unregister(&peasycap->v4l2_device); + JOM(4, "v4l2_device_unregister() OK\n"); + + video_unregister_device(&peasycap->video_device); + JOM(4, "intf[%i]: video_unregister_device() minor=%i\n", + bInterfaceNumber, minor); + peasycap->registered_video--; #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - if (0 <= kd && DONGLE_MANY > kd) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd); + if (0 <= kd && DONGLE_MANY > kd) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + JOM(4, "unlocked dongle[%i].mutex_video\n", kd); + } + break; } - break; -} -case 2: { - if (0 <= kd && DONGLE_MANY > kd) { - wake_up_interruptible(&peasycap->wq_audio); - JOM(4, "about to lock easycapdc60_dongle[%i].mutex_audio\n", - kd); - if (mutex_lock_interruptible(&easycapdc60_dongle[kd]. + case 2: { + if (0 <= kd && DONGLE_MANY > kd) { + wake_up_interruptible(&peasycap->wq_audio); + JOM(4, "about to lock dongle[%i].mutex_audio\n", kd); + if (mutex_lock_interruptible(&easycapdc60_dongle[kd]. mutex_audio)) { - SAY("ERROR: cannot lock easycapdc60_dongle[%i]." - "mutex_audio\n", kd); - return; - } - JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd); - } else - SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); + SAY("ERROR: " + "cannot lock dongle[%i].mutex_audio\n", kd); + return; + } + JOM(4, "locked dongle[%i].mutex_audio\n", kd); + } else + SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); #ifndef CONFIG_EASYCAP_OSS - - - - if (0 != snd_card_free(peasycap->psnd_card)) { - SAY("ERROR: snd_card_free() failed\n"); - } else { - peasycap->psnd_card = NULL; - (peasycap->registered_audio)--; - } - - + if (0 != snd_card_free(peasycap->psnd_card)) { + SAY("ERROR: snd_card_free() failed\n"); + } else { + peasycap->psnd_card = NULL; + (peasycap->registered_audio)--; + } #else /* CONFIG_EASYCAP_OSS */ - usb_deregister_dev(pusb_interface, &easyoss_class); - (peasycap->registered_audio)--; - JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber); - SAM("easyoss detached from minor #%d\n", minor); + usb_deregister_dev(pusb_interface, &easyoss_class); + peasycap->registered_audio--; + JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber); + SAM("easyoss detached from minor #%d\n", minor); #endif /* CONFIG_EASYCAP_OSS */ - - if (0 <= kd && DONGLE_MANY > kd) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - JOM(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd); + if (0 <= kd && DONGLE_MANY > kd) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + JOM(4, "unlocked dongle[%i].mutex_audio\n", kd); + } + break; + } + default: + break; } - break; -} -default: - break; -} /*---------------------------------------------------------------------------*/ /* * CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap * (ALSO WHEN ALSA HAS BEEN IN USE) */ /*---------------------------------------------------------------------------*/ -if (!peasycap->kref.refcount.counter) { - SAM("ERROR: peasycap->kref.refcount.counter is zero " - "so cannot call kref_put()\n"); - SAM("ending unsuccessfully: may cause memory leak\n"); - return; -} -if (0 <= kd && DONGLE_MANY > kd) { - JOM(4, "about to lock easycapdc60_dongle[%i].mutex_video\n", kd); - if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { - SAY("ERROR: cannot down " - "easycapdc60_dongle[%i].mutex_video\n", kd); - SAM("ending unsuccessfully: may cause memory leak\n"); - return; - } - JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd); - JOM(4, "about to lock easycapdc60_dongle[%i].mutex_audio\n", kd); - if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_audio)) { - SAY("ERROR: cannot down " - "easycapdc60_dongle[%i].mutex_audio\n", kd); - mutex_unlock(&(easycapdc60_dongle[kd].mutex_video)); - JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd); + if (!peasycap->kref.refcount.counter) { + SAM("ERROR: peasycap->kref.refcount.counter is zero " + "so cannot call kref_put()\n"); SAM("ending unsuccessfully: may cause memory leak\n"); return; } - JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd); -} -JOM(4, "intf[%i]: %i=peasycap->kref.refcount.counter\n", - bInterfaceNumber, (int)peasycap->kref.refcount.counter); -kref_put(&peasycap->kref, easycap_delete); -JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber); -if (0 <= kd && DONGLE_MANY > kd) { - mutex_unlock(&(easycapdc60_dongle[kd].mutex_audio)); - JOT(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - JOT(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd); -} + if (0 <= kd && DONGLE_MANY > kd) { + JOM(4, "about to lock dongle[%i].mutex_video\n", kd); + if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { + SAY("ERROR: cannot lock dongle[%i].mutex_video\n", kd); + SAM("ending unsuccessfully: may cause memory leak\n"); + return; + } + JOM(4, "locked dongle[%i].mutex_video\n", kd); + JOM(4, "about to lock dongle[%i].mutex_audio\n", kd); + if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_audio)) { + SAY("ERROR: cannot lock dongle[%i].mutex_audio\n", kd); + mutex_unlock(&(easycapdc60_dongle[kd].mutex_video)); + JOM(4, "unlocked dongle[%i].mutex_video\n", kd); + SAM("ending unsuccessfully: may cause memory leak\n"); + return; + } + JOM(4, "locked dongle[%i].mutex_audio\n", kd); + } + JOM(4, "intf[%i]: %i=peasycap->kref.refcount.counter\n", + bInterfaceNumber, (int)peasycap->kref.refcount.counter); + kref_put(&peasycap->kref, easycap_delete); + JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber); + if (0 <= kd && DONGLE_MANY > kd) { + mutex_unlock(&(easycapdc60_dongle[kd].mutex_audio)); + JOT(4, "unlocked dongle[%i].mutex_audio\n", kd); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + JOT(4, "unlocked dongle[%i].mutex_video\n", kd); + } /*---------------------------------------------------------------------------*/ -JOM(4, "ends\n"); -return; + JOM(4, "ends\n"); + return; } /*****************************************************************************/ -- cgit v1.2.3 From a75af07718d2f2552f7b9e9c7e3799485b8b9329 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 28 Feb 2011 19:27:07 +0200 Subject: staging/easycap: add first level indentation to easycap_sound.c Add the first level indentation to easycap_sound.c with astyle -t8. 41 lines over 80 characters were left out for further fix Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_sound.c | 1164 +++++++++++++++---------------- 1 file changed, 572 insertions(+), 592 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index 0d647c81ed55..86b9ae0366d0 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -47,8 +47,9 @@ static const struct snd_pcm_hardware alsa_hardware = { .rate_max = 48000, .channels_min = 2, .channels_max = 2, - .buffer_bytes_max = PAGE_SIZE * PAGES_PER_AUDIO_FRAGMENT * - AUDIO_FRAGMENT_MANY, + .buffer_bytes_max = PAGE_SIZE * + PAGES_PER_AUDIO_FRAGMENT * + AUDIO_FRAGMENT_MANY, .period_bytes_min = PAGE_SIZE * PAGES_PER_AUDIO_FRAGMENT, .period_bytes_max = PAGE_SIZE * PAGES_PER_AUDIO_FRAGMENT * 2, .periods_min = AUDIO_FRAGMENT_MANY, @@ -67,64 +68,64 @@ static const struct snd_pcm_hardware alsa_hardware = { void easycap_alsa_complete(struct urb *purb) { -struct easycap *peasycap; -struct snd_pcm_substream *pss; -struct snd_pcm_runtime *prt; -int dma_bytes, fragment_bytes; -int isfragment; -u8 *p1, *p2; -s16 tmp; -int i, j, more, much, rc; + struct easycap *peasycap; + struct snd_pcm_substream *pss; + struct snd_pcm_runtime *prt; + int dma_bytes, fragment_bytes; + int isfragment; + u8 *p1, *p2; + s16 tmp; + int i, j, more, much, rc; #ifdef UPSAMPLE -int k; -s16 oldaudio, newaudio, delta; + int k; + s16 oldaudio, newaudio, delta; #endif /*UPSAMPLE*/ -JOT(16, "\n"); + JOT(16, "\n"); -if (NULL == purb) { - SAY("ERROR: purb is NULL\n"); - return; -} -peasycap = purb->context; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return; -} -much = 0; -if (peasycap->audio_idle) { - JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n", - peasycap->audio_idle, peasycap->audio_isoc_streaming); - if (peasycap->audio_isoc_streaming) - goto resubmit; -} + if (NULL == purb) { + SAY("ERROR: purb is NULL\n"); + return; + } + peasycap = purb->context; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return; + } + much = 0; + if (peasycap->audio_idle) { + JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n", + peasycap->audio_idle, peasycap->audio_isoc_streaming); + if (peasycap->audio_isoc_streaming) + goto resubmit; + } /*---------------------------------------------------------------------------*/ -pss = peasycap->psubstream; -if (NULL == pss) - goto resubmit; -prt = pss->runtime; -if (NULL == prt) - goto resubmit; -dma_bytes = (int)prt->dma_bytes; -if (0 == dma_bytes) - goto resubmit; -fragment_bytes = 4 * ((int)prt->period_size); -if (0 == fragment_bytes) - goto resubmit; + pss = peasycap->psubstream; + if (NULL == pss) + goto resubmit; + prt = pss->runtime; + if (NULL == prt) + goto resubmit; + dma_bytes = (int)prt->dma_bytes; + if (0 == dma_bytes) + goto resubmit; + fragment_bytes = 4 * ((int)prt->period_size); + if (0 == fragment_bytes) + goto resubmit; /* -------------------------------------------------------------------------*/ -if (purb->status) { - if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) { - JOM(16, "urb status -ESHUTDOWN or -ENOENT\n"); - return; + if (purb->status) { + if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) { + JOM(16, "urb status -ESHUTDOWN or -ENOENT\n"); + return; + } + SAM("ERROR: non-zero urb status: -%s: %d\n", + strerror(purb->status), purb->status); + goto resubmit; } - SAM("ERROR: non-zero urb status: -%s: %d\n", - strerror(purb->status), purb->status); - goto resubmit; -} /*---------------------------------------------------------------------------*/ /* * PROCEED HERE WHEN NO ERROR @@ -132,352 +133,342 @@ if (purb->status) { /*---------------------------------------------------------------------------*/ #ifdef UPSAMPLE -oldaudio = peasycap->oldaudio; + oldaudio = peasycap->oldaudio; #endif /*UPSAMPLE*/ -for (i = 0; i < purb->number_of_packets; i++) { - if (purb->iso_frame_desc[i].status < 0) { - SAM("-%s: %d\n", - strerror(purb->iso_frame_desc[i].status), - purb->iso_frame_desc[i].status); - } - if (!purb->iso_frame_desc[i].status) { - more = purb->iso_frame_desc[i].actual_length; - if (!more) - peasycap->audio_mt++; - else { - if (peasycap->audio_mt) { - JOM(12, "%4i empty audio urb frames\n", - peasycap->audio_mt); - peasycap->audio_mt = 0; - } + for (i = 0; i < purb->number_of_packets; i++) { + if (purb->iso_frame_desc[i].status < 0) { + SAM("-%s: %d\n", + strerror(purb->iso_frame_desc[i].status), + purb->iso_frame_desc[i].status); + } + if (!purb->iso_frame_desc[i].status) { + more = purb->iso_frame_desc[i].actual_length; + if (!more) + peasycap->audio_mt++; + else { + if (peasycap->audio_mt) { + JOM(12, "%4i empty audio urb frames\n", + peasycap->audio_mt); + peasycap->audio_mt = 0; + } - p1 = (u8 *)(purb->transfer_buffer + + p1 = (u8 *)(purb->transfer_buffer + purb->iso_frame_desc[i].offset); -/*---------------------------------------------------------------------------*/ -/* - * COPY more BYTES FROM ISOC BUFFER TO THE DMA BUFFER, - * CONVERTING 8-BIT MONO TO 16-BIT SIGNED LITTLE-ENDIAN SAMPLES IF NECESSARY - */ -/*---------------------------------------------------------------------------*/ - while (more) { - if (0 > more) { - SAM("MISTAKE: more is negative\n"); - return; - } - much = dma_bytes - peasycap->dma_fill; - if (0 > much) { - SAM("MISTAKE: much is negative\n"); - return; - } - if (0 == much) { - peasycap->dma_fill = 0; - peasycap->dma_next = fragment_bytes; - JOM(8, "wrapped dma buffer\n"); - } - if (false == peasycap->microphone) { - if (much > more) - much = more; - memcpy(prt->dma_area + - peasycap->dma_fill, - p1, much); - p1 += much; - more -= much; - } else { + /* + * COPY more BYTES FROM ISOC BUFFER + * TO THE DMA BUFFER, CONVERTING + * 8-BIT MONO TO 16-BIT SIGNED + * LITTLE-ENDIAN SAMPLES IF NECESSARY + */ + while (more) { + if (0 > more) { + SAM("MISTAKE: more is negative\n"); + return; + } + much = dma_bytes - peasycap->dma_fill; + if (0 > much) { + SAM("MISTAKE: much is negative\n"); + return; + } + if (0 == much) { + peasycap->dma_fill = 0; + peasycap->dma_next = fragment_bytes; + JOM(8, "wrapped dma buffer\n"); + } + if (false == peasycap->microphone) { + if (much > more) + much = more; + memcpy(prt->dma_area + + peasycap->dma_fill, + p1, much); + p1 += much; + more -= much; + } else { #ifdef UPSAMPLE - if (much % 16) - JOM(8, "MISTAKE? much" - " is not divisible by 16\n"); - if (much > (16 * - more)) - much = 16 * - more; - p2 = (u8 *)(prt->dma_area + - peasycap->dma_fill); - - for (j = 0; j < (much/16); j++) { - newaudio = ((int) *p1) - 128; - newaudio = 128 * - newaudio; - - delta = (newaudio - oldaudio) - / 4; - tmp = oldaudio + delta; - - for (k = 0; k < 4; k++) { - *p2 = (0x00FF & tmp); - *(p2 + 1) = (0xFF00 & - tmp) >> 8; - p2 += 2; + if (much % 16) + JOM(8, "MISTAKE? much" + " is not divisible by 16\n"); + if (much > (16 * more)) + much = 16 * + more; + p2 = (u8 *)(prt->dma_area + peasycap->dma_fill); + + for (j = 0; j < (much/16); j++) { + newaudio = ((int) *p1) - 128; + newaudio = 128 * newaudio; + + delta = (newaudio - oldaudio) / 4; + tmp = oldaudio + delta; + + for (k = 0; k < 4; k++) { + *p2 = (0x00FF & tmp); + *(p2 + 1) = (0xFF00 & tmp) >> 8; + p2 += 2; + *p2 = (0x00FF & tmp); + *(p2 + 1) = (0xFF00 & tmp) >> 8; + p2 += 2; + tmp += delta; + } + p1++; + more--; + oldaudio = tmp; + } +#else /*!UPSAMPLE*/ + if (much > (2 * more)) + much = 2 * more; + p2 = (u8 *)(prt->dma_area + peasycap->dma_fill); + + for (j = 0; j < (much / 2); j++) { + tmp = ((int) *p1) - 128; + tmp = 128 * tmp; *p2 = (0x00FF & tmp); - *(p2 + 1) = (0xFF00 & - tmp) >> 8; + *(p2 + 1) = (0xFF00 & tmp) >> 8; + p1++; p2 += 2; - tmp += delta; + more--; } - p1++; - more--; - oldaudio = tmp; - } -#else /*!UPSAMPLE*/ - if (much > (2 * more)) - much = 2 * more; - p2 = (u8 *)(prt->dma_area + - peasycap->dma_fill); - - for (j = 0; j < (much / 2); j++) { - tmp = ((int) *p1) - 128; - tmp = 128 * tmp; - *p2 = (0x00FF & tmp); - *(p2 + 1) = (0xFF00 & tmp) >> - 8; - p1++; p2 += 2; - more--; - } #endif /*UPSAMPLE*/ - } - peasycap->dma_fill += much; - if (peasycap->dma_fill >= peasycap->dma_next) { - isfragment = peasycap->dma_fill / - fragment_bytes; - if (0 > isfragment) { - SAM("MISTAKE: isfragment is " - "negative\n"); - return; } - peasycap->dma_read = (isfragment - - 1) * fragment_bytes; - peasycap->dma_next = (isfragment - + 1) * fragment_bytes; - if (dma_bytes < peasycap->dma_next) { - peasycap->dma_next = - fragment_bytes; - } - if (0 <= peasycap->dma_read) { - JOM(8, "snd_pcm_period_elap" - "sed(), %i=" - "isfragment\n", - isfragment); - snd_pcm_period_elapsed(pss); + peasycap->dma_fill += much; + if (peasycap->dma_fill >= peasycap->dma_next) { + isfragment = peasycap->dma_fill / fragment_bytes; + if (0 > isfragment) { + SAM("MISTAKE: isfragment is " + "negative\n"); + return; + } + peasycap->dma_read = (isfragment - 1) * fragment_bytes; + peasycap->dma_next = (isfragment + 1) * fragment_bytes; + if (dma_bytes < peasycap->dma_next) + peasycap->dma_next = fragment_bytes; + + if (0 <= peasycap->dma_read) { + JOM(8, "snd_pcm_period_elap" + "sed(), %i=" + "isfragment\n", + isfragment); + snd_pcm_period_elapsed(pss); + } } } } + } else { + JOM(12, "discarding audio samples because " + "%i=purb->iso_frame_desc[i].status\n", + purb->iso_frame_desc[i].status); } - } else { - JOM(12, "discarding audio samples because " - "%i=purb->iso_frame_desc[i].status\n", - purb->iso_frame_desc[i].status); - } #ifdef UPSAMPLE -peasycap->oldaudio = oldaudio; + peasycap->oldaudio = oldaudio; #endif /*UPSAMPLE*/ -} + } /*---------------------------------------------------------------------------*/ /* * RESUBMIT THIS URB */ /*---------------------------------------------------------------------------*/ resubmit: -if (peasycap->audio_isoc_streaming) { - rc = usb_submit_urb(purb, GFP_ATOMIC); - if (rc) { - if ((-ENODEV != rc) && (-ENOENT != rc)) { - SAM("ERROR: while %i=audio_idle, " - "usb_submit_urb() failed " - "with rc: -%s :%d\n", peasycap->audio_idle, - strerror(rc), rc); + if (peasycap->audio_isoc_streaming) { + rc = usb_submit_urb(purb, GFP_ATOMIC); + if (rc) { + if ((-ENODEV != rc) && (-ENOENT != rc)) { + SAM("ERROR: while %i=audio_idle, " + "usb_submit_urb() failed " + "with rc: -%s :%d\n", peasycap->audio_idle, + strerror(rc), rc); + } + if (0 < peasycap->audio_isoc_streaming) + (peasycap->audio_isoc_streaming)--; } - if (0 < peasycap->audio_isoc_streaming) - (peasycap->audio_isoc_streaming)--; } -} -return; + return; } /*****************************************************************************/ static int easycap_alsa_open(struct snd_pcm_substream *pss) { -struct snd_pcm *psnd_pcm; -struct snd_card *psnd_card; -struct easycap *peasycap; - -JOT(4, "\n"); -if (NULL == pss) { - SAY("ERROR: pss is NULL\n"); - return -EFAULT; -} -psnd_pcm = pss->pcm; -if (NULL == psnd_pcm) { - SAY("ERROR: psnd_pcm is NULL\n"); - return -EFAULT; -} -psnd_card = psnd_pcm->card; -if (NULL == psnd_card) { - SAY("ERROR: psnd_card is NULL\n"); - return -EFAULT; -} + struct snd_pcm *psnd_pcm; + struct snd_card *psnd_card; + struct easycap *peasycap; -peasycap = psnd_card->private_data; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; -} -if (peasycap->psnd_card != psnd_card) { - SAM("ERROR: bad peasycap->psnd_card\n"); - return -EFAULT; -} -if (NULL != peasycap->psubstream) { - SAM("ERROR: bad peasycap->psubstream\n"); - return -EFAULT; -} -pss->private_data = peasycap; -peasycap->psubstream = pss; -pss->runtime->hw = peasycap->alsa_hardware; -pss->runtime->private_data = peasycap; -pss->private_data = peasycap; - -if (0 != easycap_sound_setup(peasycap)) { - JOM(4, "ending unsuccessfully\n"); - return -EFAULT; -} -JOM(4, "ending successfully\n"); -return 0; + JOT(4, "\n"); + if (NULL == pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; + } + psnd_pcm = pss->pcm; + if (NULL == psnd_pcm) { + SAY("ERROR: psnd_pcm is NULL\n"); + return -EFAULT; + } + psnd_card = psnd_pcm->card; + if (NULL == psnd_card) { + SAY("ERROR: psnd_card is NULL\n"); + return -EFAULT; + } + + peasycap = psnd_card->private_data; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; + } + if (peasycap->psnd_card != psnd_card) { + SAM("ERROR: bad peasycap->psnd_card\n"); + return -EFAULT; + } + if (NULL != peasycap->psubstream) { + SAM("ERROR: bad peasycap->psubstream\n"); + return -EFAULT; + } + pss->private_data = peasycap; + peasycap->psubstream = pss; + pss->runtime->hw = peasycap->alsa_hardware; + pss->runtime->private_data = peasycap; + pss->private_data = peasycap; + + if (0 != easycap_sound_setup(peasycap)) { + JOM(4, "ending unsuccessfully\n"); + return -EFAULT; + } + JOM(4, "ending successfully\n"); + return 0; } /*****************************************************************************/ static int easycap_alsa_close(struct snd_pcm_substream *pss) { -struct easycap *peasycap; + struct easycap *peasycap; -JOT(4, "\n"); -if (NULL == pss) { - SAY("ERROR: pss is NULL\n"); - return -EFAULT; -} -peasycap = snd_pcm_substream_chip(pss); -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; -} -pss->private_data = NULL; -peasycap->psubstream = NULL; -JOT(4, "ending successfully\n"); -return 0; + JOT(4, "\n"); + if (NULL == pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; + } + peasycap = snd_pcm_substream_chip(pss); + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; + } + pss->private_data = NULL; + peasycap->psubstream = NULL; + JOT(4, "ending successfully\n"); + return 0; } /*****************************************************************************/ static int easycap_alsa_vmalloc(struct snd_pcm_substream *pss, size_t sz) { -struct snd_pcm_runtime *prt; -JOT(4, "\n"); + struct snd_pcm_runtime *prt; + JOT(4, "\n"); -if (NULL == pss) { - SAY("ERROR: pss is NULL\n"); - return -EFAULT; -} -prt = pss->runtime; -if (NULL == prt) { - SAY("ERROR: substream.runtime is NULL\n"); - return -EFAULT; -} -if (prt->dma_area) { - if (prt->dma_bytes > sz) - return 0; - vfree(prt->dma_area); -} -prt->dma_area = vmalloc(sz); -if (NULL == prt->dma_area) - return -ENOMEM; -prt->dma_bytes = sz; -return 0; + if (NULL == pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; + } + prt = pss->runtime; + if (NULL == prt) { + SAY("ERROR: substream.runtime is NULL\n"); + return -EFAULT; + } + if (prt->dma_area) { + if (prt->dma_bytes > sz) + return 0; + vfree(prt->dma_area); + } + prt->dma_area = vmalloc(sz); + if (NULL == prt->dma_area) + return -ENOMEM; + prt->dma_bytes = sz; + return 0; } /*****************************************************************************/ static int easycap_alsa_hw_params(struct snd_pcm_substream *pss, - struct snd_pcm_hw_params *phw) + struct snd_pcm_hw_params *phw) { -int rc; + int rc; -JOT(4, "%i\n", (params_buffer_bytes(phw))); -if (NULL == pss) { - SAY("ERROR: pss is NULL\n"); - return -EFAULT; -} -rc = easycap_alsa_vmalloc(pss, params_buffer_bytes(phw)); -if (rc) - return rc; -return 0; + JOT(4, "%i\n", (params_buffer_bytes(phw))); + if (NULL == pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; + } + rc = easycap_alsa_vmalloc(pss, params_buffer_bytes(phw)); + if (rc) + return rc; + return 0; } /*****************************************************************************/ static int easycap_alsa_hw_free(struct snd_pcm_substream *pss) { -struct snd_pcm_runtime *prt; -JOT(4, "\n"); + struct snd_pcm_runtime *prt; + JOT(4, "\n"); -if (NULL == pss) { - SAY("ERROR: pss is NULL\n"); - return -EFAULT; -} -prt = pss->runtime; -if (NULL == prt) { - SAY("ERROR: substream.runtime is NULL\n"); - return -EFAULT; -} -if (NULL != prt->dma_area) { - JOT(8, "prt->dma_area = %p\n", prt->dma_area); - vfree(prt->dma_area); - prt->dma_area = NULL; -} else - JOT(8, "dma_area already freed\n"); -return 0; + if (NULL == pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; + } + prt = pss->runtime; + if (NULL == prt) { + SAY("ERROR: substream.runtime is NULL\n"); + return -EFAULT; + } + if (NULL != prt->dma_area) { + JOT(8, "prt->dma_area = %p\n", prt->dma_area); + vfree(prt->dma_area); + prt->dma_area = NULL; + } else + JOT(8, "dma_area already freed\n"); + return 0; } /*****************************************************************************/ static int easycap_alsa_prepare(struct snd_pcm_substream *pss) { -struct easycap *peasycap; -struct snd_pcm_runtime *prt; + struct easycap *peasycap; + struct snd_pcm_runtime *prt; -JOT(4, "\n"); -if (NULL == pss) { - SAY("ERROR: pss is NULL\n"); - return -EFAULT; -} -prt = pss->runtime; -peasycap = snd_pcm_substream_chip(pss); -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; -} + JOT(4, "\n"); + if (NULL == pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; + } + prt = pss->runtime; + peasycap = snd_pcm_substream_chip(pss); + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; + } -JOM(16, "ALSA decides %8i Hz=rate\n", (int)pss->runtime->rate); -JOM(16, "ALSA decides %8i =period_size\n", (int)pss->runtime->period_size); -JOM(16, "ALSA decides %8i =periods\n", (int)pss->runtime->periods); -JOM(16, "ALSA decides %8i =buffer_size\n", (int)pss->runtime->buffer_size); -JOM(16, "ALSA decides %8i =dma_bytes\n", (int)pss->runtime->dma_bytes); -JOM(16, "ALSA decides %8i =boundary\n", (int)pss->runtime->boundary); -JOM(16, "ALSA decides %8i =period_step\n", (int)pss->runtime->period_step); -JOM(16, "ALSA decides %8i =sample_bits\n", (int)pss->runtime->sample_bits); -JOM(16, "ALSA decides %8i =frame_bits\n", (int)pss->runtime->frame_bits); -JOM(16, "ALSA decides %8i =min_align\n", (int)pss->runtime->min_align); -JOM(12, "ALSA decides %8i =hw_ptr_base\n", (int)pss->runtime->hw_ptr_base); -JOM(12, "ALSA decides %8i =hw_ptr_interrupt\n", - (int)pss->runtime->hw_ptr_interrupt); -if (prt->dma_bytes != 4 * ((int)prt->period_size) * ((int)prt->periods)) { - SAY("MISTAKE: unexpected ALSA parameters\n"); - return -ENOENT; -} -return 0; + JOM(16, "ALSA decides %8i Hz=rate\n", pss->runtime->rate); + JOM(16, "ALSA decides %8ld =period_size\n", pss->runtime->period_size); + JOM(16, "ALSA decides %8i =periods\n", pss->runtime->periods); + JOM(16, "ALSA decides %8ld =buffer_size\n", pss->runtime->buffer_size); + JOM(16, "ALSA decides %8zd =dma_bytes\n", pss->runtime->dma_bytes); + JOM(16, "ALSA decides %8ld =boundary\n", pss->runtime->boundary); + JOM(16, "ALSA decides %8i =period_step\n", pss->runtime->period_step); + JOM(16, "ALSA decides %8i =sample_bits\n", pss->runtime->sample_bits); + JOM(16, "ALSA decides %8i =frame_bits\n", pss->runtime->frame_bits); + JOM(16, "ALSA decides %8ld =min_align\n", pss->runtime->min_align); + JOM(12, "ALSA decides %8ld =hw_ptr_base\n", pss->runtime->hw_ptr_base); + JOM(12, "ALSA decides %8ld =hw_ptr_interrupt\n", + pss->runtime->hw_ptr_interrupt); + + if (prt->dma_bytes != 4 * ((int)prt->period_size) * ((int)prt->periods)) { + SAY("MISTAKE: unexpected ALSA parameters\n"); + return -ENOENT; + } + return 0; } /*****************************************************************************/ static int easycap_alsa_ack(struct snd_pcm_substream *pss) @@ -487,81 +478,81 @@ static int easycap_alsa_ack(struct snd_pcm_substream *pss) /*****************************************************************************/ static int easycap_alsa_trigger(struct snd_pcm_substream *pss, int cmd) { -struct easycap *peasycap; -int retval; - -JOT(4, "%i=cmd cf %i=START %i=STOP\n", cmd, SNDRV_PCM_TRIGGER_START, - SNDRV_PCM_TRIGGER_STOP); -if (NULL == pss) { - SAY("ERROR: pss is NULL\n"); - return -EFAULT; -} -peasycap = snd_pcm_substream_chip(pss); -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; -} + struct easycap *peasycap; + int retval; -switch (cmd) { -case SNDRV_PCM_TRIGGER_START: { - peasycap->audio_idle = 0; - break; -} -case SNDRV_PCM_TRIGGER_STOP: { - peasycap->audio_idle = 1; - break; -} -default: - retval = -EINVAL; -} -return 0; + JOT(4, "%i=cmd cf %i=START %i=STOP\n", cmd, SNDRV_PCM_TRIGGER_START, + SNDRV_PCM_TRIGGER_STOP); + if (NULL == pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; + } + peasycap = snd_pcm_substream_chip(pss); + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; + } + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: { + peasycap->audio_idle = 0; + break; + } + case SNDRV_PCM_TRIGGER_STOP: { + peasycap->audio_idle = 1; + break; + } + default: + retval = -EINVAL; + } + return 0; } /*****************************************************************************/ static snd_pcm_uframes_t easycap_alsa_pointer(struct snd_pcm_substream *pss) { -struct easycap *peasycap; -snd_pcm_uframes_t offset; + struct easycap *peasycap; + snd_pcm_uframes_t offset; -JOT(16, "\n"); -if (NULL == pss) { - SAY("ERROR: pss is NULL\n"); - return -EFAULT; -} -peasycap = snd_pcm_substream_chip(pss); -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; -} -if ((0 != peasycap->audio_eof) || (0 != peasycap->audio_idle)) { - JOM(8, "returning -EIO because " - "%i=audio_idle %i=audio_eof\n", - peasycap->audio_idle, peasycap->audio_eof); - return -EIO; -} + JOT(16, "\n"); + if (NULL == pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; + } + peasycap = snd_pcm_substream_chip(pss); + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; + } + if ((0 != peasycap->audio_eof) || (0 != peasycap->audio_idle)) { + JOM(8, "returning -EIO because " + "%i=audio_idle %i=audio_eof\n", + peasycap->audio_idle, peasycap->audio_eof); + return -EIO; + } /*---------------------------------------------------------------------------*/ -if (0 > peasycap->dma_read) { - JOM(8, "returning -EBUSY\n"); - return -EBUSY; -} -offset = ((snd_pcm_uframes_t)peasycap->dma_read)/4; -JOM(8, "ALSA decides %8i =hw_ptr_base\n", (int)pss->runtime->hw_ptr_base); -JOM(8, "ALSA decides %8i =hw_ptr_interrupt\n", - (int)pss->runtime->hw_ptr_interrupt); -JOM(8, "%7i=offset %7i=dma_read %7i=dma_next\n", - (int)offset, peasycap->dma_read, peasycap->dma_next); -return offset; + if (0 > peasycap->dma_read) { + JOM(8, "returning -EBUSY\n"); + return -EBUSY; + } + offset = ((snd_pcm_uframes_t)peasycap->dma_read)/4; + JOM(8, "ALSA decides %8i =hw_ptr_base\n", (int)pss->runtime->hw_ptr_base); + JOM(8, "ALSA decides %8i =hw_ptr_interrupt\n", + (int)pss->runtime->hw_ptr_interrupt); + JOM(8, "%7i=offset %7i=dma_read %7i=dma_next\n", + (int)offset, peasycap->dma_read, peasycap->dma_next); + return offset; } /*****************************************************************************/ -static struct page *easycap_alsa_page(struct snd_pcm_substream *pss, - unsigned long offset) +static struct page * +easycap_alsa_page(struct snd_pcm_substream *pss, unsigned long offset) { return vmalloc_to_page(pss->runtime->dma_area + offset); } @@ -589,37 +580,36 @@ static struct snd_pcm_ops easycap_alsa_pcm_ops = { /*---------------------------------------------------------------------------*/ int easycap_alsa_probe(struct easycap *peasycap) { -int rc; -struct snd_card *psnd_card; -struct snd_pcm *psnd_pcm; + int rc; + struct snd_card *psnd_card; + struct snd_pcm *psnd_pcm; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -ENODEV; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; -} -if (0 > peasycap->minor) { - SAY("ERROR: no minor\n"); - return -ENODEV; -} + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -ENODEV; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; + } + if (0 > peasycap->minor) { + SAY("ERROR: no minor\n"); + return -ENODEV; + } -peasycap->alsa_hardware = alsa_hardware; -if (true == peasycap->microphone) { - peasycap->alsa_hardware.rates = SNDRV_PCM_RATE_32000; - peasycap->alsa_hardware.rate_min = 32000; - peasycap->alsa_hardware.rate_max = 32000; -} else { - peasycap->alsa_hardware.rates = SNDRV_PCM_RATE_48000; - peasycap->alsa_hardware.rate_min = 48000; - peasycap->alsa_hardware.rate_max = 48000; -} + peasycap->alsa_hardware = alsa_hardware; + if (true == peasycap->microphone) { + peasycap->alsa_hardware.rates = SNDRV_PCM_RATE_32000; + peasycap->alsa_hardware.rate_min = 32000; + peasycap->alsa_hardware.rate_max = 32000; + } else { + peasycap->alsa_hardware.rates = SNDRV_PCM_RATE_48000; + peasycap->alsa_hardware.rate_min = 48000; + peasycap->alsa_hardware.rate_max = 48000; + } if (0 != snd_card_create(SNDRV_DEFAULT_IDX1, "easycap_alsa", - THIS_MODULE, 0, - &psnd_card)) { + THIS_MODULE, 0, &psnd_card)) { SAY("ERROR: Cannot do ALSA snd_card_create()\n"); return -EFAULT; } @@ -641,7 +631,7 @@ if (true == peasycap->microphone) { } snd_pcm_set_ops(psnd_pcm, SNDRV_PCM_STREAM_CAPTURE, - &easycap_alsa_pcm_ops); + &easycap_alsa_pcm_ops); psnd_pcm->info_flags = 0; strcpy(&psnd_pcm->name[0], &psnd_card->id[0]); psnd_pcm->private_data = peasycap; @@ -654,10 +644,10 @@ if (true == peasycap->microphone) { snd_card_free(psnd_card); return -EFAULT; } else { - ; - SAM("registered %s\n", &psnd_card->id[0]); + ; + SAM("registered %s\n", &psnd_card->id[0]); } -return 0; + return 0; } #endif /*! CONFIG_EASYCAP_OSS */ @@ -675,50 +665,50 @@ return 0; int easycap_sound_setup(struct easycap *peasycap) { -int rc; + int rc; -JOM(4, "starting initialization\n"); + JOM(4, "starting initialization\n"); -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL.\n"); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -ENODEV; -} -JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device); + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL.\n"); + return -EFAULT; + } + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -ENODEV; + } + JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device); -rc = audio_setup(peasycap); -JOM(8, "audio_setup() returned %i\n", rc); + rc = audio_setup(peasycap); + JOM(8, "audio_setup() returned %i\n", rc); -if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device has become NULL\n"); - return -ENODEV; -} + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device has become NULL\n"); + return -ENODEV; + } /*---------------------------------------------------------------------------*/ -if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device has become NULL\n"); - return -ENODEV; -} -rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, - peasycap->audio_altsetting_on); -JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, - peasycap->audio_altsetting_on, rc); + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device has become NULL\n"); + return -ENODEV; + } + rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, + peasycap->audio_altsetting_on); + JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, + peasycap->audio_altsetting_on, rc); -rc = wakeup_device(peasycap->pusb_device); -JOM(8, "wakeup_device() returned %i\n", rc); + rc = wakeup_device(peasycap->pusb_device); + JOM(8, "wakeup_device() returned %i\n", rc); -peasycap->audio_eof = 0; -peasycap->audio_idle = 0; + peasycap->audio_eof = 0; + peasycap->audio_idle = 0; -peasycap->timeval1.tv_sec = 0; -peasycap->timeval1.tv_usec = 0; + peasycap->timeval1.tv_sec = 0; + peasycap->timeval1.tv_usec = 0; -submit_audio_urbs(peasycap); + submit_audio_urbs(peasycap); -JOM(4, "finished initialization\n"); -return 0; + JOM(4, "finished initialization\n"); + return 0; } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ @@ -729,112 +719,103 @@ return 0; int submit_audio_urbs(struct easycap *peasycap) { -struct data_urb *pdata_urb; -struct urb *purb; -struct list_head *plist_head; -int j, isbad, nospc, m, rc; -int isbuf; - -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (NULL == peasycap->purb_audio_head) { - SAM("ERROR: peasycap->urb_audio_head uninitialized\n"); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -if (!peasycap->audio_isoc_streaming) { - JOM(4, "initial submission of all audio urbs\n"); - rc = usb_set_interface(peasycap->pusb_device, - peasycap->audio_interface, - peasycap->audio_altsetting_on); - JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", - peasycap->audio_interface, - peasycap->audio_altsetting_on, rc); - - isbad = 0; nospc = 0; m = 0; - list_for_each(plist_head, (peasycap->purb_audio_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (NULL != pdata_urb) { - purb = pdata_urb->purb; - if (NULL != purb) { - isbuf = pdata_urb->isbuf; - - purb->interval = 1; - purb->dev = peasycap->pusb_device; - purb->pipe = - usb_rcvisocpipe(peasycap->pusb_device, - peasycap->audio_endpointnumber); - purb->transfer_flags = URB_ISO_ASAP; - purb->transfer_buffer = - peasycap->audio_isoc_buffer[isbuf].pgo; - purb->transfer_buffer_length = - peasycap->audio_isoc_buffer_size; + struct data_urb *pdata_urb; + struct urb *purb; + struct list_head *plist_head; + int j, isbad, nospc, m, rc; + int isbuf; + + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (NULL == peasycap->purb_audio_head) { + SAM("ERROR: peasycap->urb_audio_head uninitialized\n"); + return -EFAULT; + } + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } + if (!peasycap->audio_isoc_streaming) { + JOM(4, "initial submission of all audio urbs\n"); + rc = usb_set_interface(peasycap->pusb_device, + peasycap->audio_interface, + peasycap->audio_altsetting_on); + JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", + peasycap->audio_interface, + peasycap->audio_altsetting_on, rc); + + isbad = 0; + nospc = 0; + m = 0; + list_for_each(plist_head, (peasycap->purb_audio_head)) { + pdata_urb = list_entry(plist_head, struct data_urb, list_head); + if (NULL != pdata_urb) { + purb = pdata_urb->purb; + if (NULL != purb) { + isbuf = pdata_urb->isbuf; + + purb->interval = 1; + purb->dev = peasycap->pusb_device; + purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, + peasycap->audio_endpointnumber); + purb->transfer_flags = URB_ISO_ASAP; + purb->transfer_buffer = peasycap->audio_isoc_buffer[isbuf].pgo; + purb->transfer_buffer_length = peasycap->audio_isoc_buffer_size; #ifdef CONFIG_EASYCAP_OSS - purb->complete = easyoss_complete; + purb->complete = easyoss_complete; #else /* CONFIG_EASYCAP_OSS */ - purb->complete = easycap_alsa_complete; + purb->complete = easycap_alsa_complete; #endif /* CONFIG_EASYCAP_OSS */ - purb->context = peasycap; - purb->start_frame = 0; - purb->number_of_packets = - peasycap->audio_isoc_framesperdesc; - for (j = 0; j < peasycap-> - audio_isoc_framesperdesc; - j++) { - purb->iso_frame_desc[j].offset = j * - peasycap-> - audio_isoc_maxframesize; - purb->iso_frame_desc[j].length = - peasycap-> - audio_isoc_maxframesize; - } + purb->context = peasycap; + purb->start_frame = 0; + purb->number_of_packets = peasycap->audio_isoc_framesperdesc; + for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) { + purb->iso_frame_desc[j].offset = j * peasycap->audio_isoc_maxframesize; + purb->iso_frame_desc[j].length = peasycap->audio_isoc_maxframesize; + } - rc = usb_submit_urb(purb, GFP_KERNEL); - if (rc) { - isbad++; - SAM("ERROR: usb_submit_urb() failed" - " for urb with rc: -%s: %d\n", - strerror(rc), rc); + rc = usb_submit_urb(purb, GFP_KERNEL); + if (rc) { + isbad++; + SAM("ERROR: usb_submit_urb() failed" + " for urb with rc: -%s: %d\n", + strerror(rc), rc); + } else { + m++; + } } else { - m++; + isbad++; } } else { isbad++; } - } else { - isbad++; } - } - if (nospc) { - SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc); - SAM("..... possibly inadequate USB bandwidth\n"); - peasycap->audio_eof = 1; - } - if (isbad) { - JOM(4, "attempting cleanup instead of submitting\n"); - list_for_each(plist_head, (peasycap->purb_audio_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, - list_head); - if (NULL != pdata_urb) { - purb = pdata_urb->purb; - if (NULL != purb) - usb_kill_urb(purb); + if (nospc) { + SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc); + SAM("..... possibly inadequate USB bandwidth\n"); + peasycap->audio_eof = 1; + } + if (isbad) { + JOM(4, "attempting cleanup instead of submitting\n"); + list_for_each(plist_head, (peasycap->purb_audio_head)) { + pdata_urb = list_entry(plist_head, struct data_urb, list_head); + if (NULL != pdata_urb) { + purb = pdata_urb->purb; + if (NULL != purb) + usb_kill_urb(purb); + } } + peasycap->audio_isoc_streaming = 0; + } else { + peasycap->audio_isoc_streaming = m; + JOM(4, "submitted %i audio urbs\n", m); } - peasycap->audio_isoc_streaming = 0; - } else { - peasycap->audio_isoc_streaming = m; - JOM(4, "submitted %i audio urbs\n", m); - } -} else - JOM(4, "already streaming audio urbs\n"); + } else + JOM(4, "already streaming audio urbs\n"); -return 0; + return 0; } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ @@ -845,38 +826,37 @@ return 0; int kill_audio_urbs(struct easycap *peasycap) { -int m; -struct list_head *plist_head; -struct data_urb *pdata_urb; + int m; + struct list_head *plist_head; + struct data_urb *pdata_urb; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (peasycap->audio_isoc_streaming) { - if (NULL != peasycap->purb_audio_head) { - peasycap->audio_isoc_streaming = 0; - JOM(4, "killing audio urbs\n"); - m = 0; - list_for_each(plist_head, (peasycap->purb_audio_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, - list_head); - if (NULL != pdata_urb) { - if (NULL != pdata_urb->purb) { - usb_kill_urb(pdata_urb->purb); - m++; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (peasycap->audio_isoc_streaming) { + if (NULL != peasycap->purb_audio_head) { + peasycap->audio_isoc_streaming = 0; + JOM(4, "killing audio urbs\n"); + m = 0; + list_for_each(plist_head, (peasycap->purb_audio_head)) { + pdata_urb = list_entry(plist_head, struct data_urb, list_head); + if (NULL != pdata_urb) { + if (NULL != pdata_urb->purb) { + usb_kill_urb(pdata_urb->purb); + m++; + } } } + JOM(4, "%i audio urbs killed\n", m); + } else { + SAM("ERROR: peasycap->purb_audio_head is NULL\n"); + return -EFAULT; } - JOM(4, "%i audio urbs killed\n", m); } else { - SAM("ERROR: peasycap->purb_audio_head is NULL\n"); - return -EFAULT; + JOM(8, "%i=audio_isoc_streaming, no audio urbs killed\n", + peasycap->audio_isoc_streaming); } -} else { - JOM(8, "%i=audio_isoc_streaming, no audio urbs killed\n", - peasycap->audio_isoc_streaming); -} -return 0; + return 0; } /*****************************************************************************/ -- cgit v1.2.3 From 980aebddb6459130f6f90af07152a0833c596088 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 28 Feb 2011 19:27:08 +0200 Subject: staging/easycap: add first level indentation to easycap_sound_oss.c Add first level indentation to easycap_sound_oss.c with astyle -t8 62 lines over 80 characters were left out for further fix Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_sound_oss.c | 1384 +++++++++++++-------------- 1 file changed, 673 insertions(+), 711 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c index e817b3571885..e36f341ae118 100644 --- a/drivers/staging/easycap/easycap_sound_oss.c +++ b/drivers/staging/easycap/easycap_sound_oss.c @@ -51,247 +51,218 @@ void easyoss_complete(struct urb *purb) { -struct easycap *peasycap; -struct data_buffer *paudio_buffer; -u8 *p1, *p2; -s16 tmp; -int i, j, more, much, leap, rc; + struct easycap *peasycap; + struct data_buffer *paudio_buffer; + u8 *p1, *p2; + s16 tmp; + int i, j, more, much, leap, rc; #ifdef UPSAMPLE -int k; -s16 oldaudio, newaudio, delta; + int k; + s16 oldaudio, newaudio, delta; #endif /*UPSAMPLE*/ -JOT(16, "\n"); + JOT(16, "\n"); -if (NULL == purb) { - SAY("ERROR: purb is NULL\n"); - return; -} -peasycap = purb->context; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return; -} -much = 0; -if (peasycap->audio_idle) { - JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n", - peasycap->audio_idle, peasycap->audio_isoc_streaming); - if (peasycap->audio_isoc_streaming) { - rc = usb_submit_urb(purb, GFP_ATOMIC); - if (rc) { - if (-ENODEV != rc && -ENOENT != rc) { - SAM("ERROR: while %i=audio_idle, " - "usb_submit_urb() failed with rc: -%s: %d\n", - peasycap->audio_idle, - strerror(rc), rc); + if (NULL == purb) { + SAY("ERROR: purb is NULL\n"); + return; + } + peasycap = purb->context; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return; + } + much = 0; + if (peasycap->audio_idle) { + JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n", + peasycap->audio_idle, peasycap->audio_isoc_streaming); + if (peasycap->audio_isoc_streaming) { + rc = usb_submit_urb(purb, GFP_ATOMIC); + if (rc) { + if (-ENODEV != rc && -ENOENT != rc) { + SAM("ERROR: while %i=audio_idle, " + "usb_submit_urb() failed with rc: -%s: %d\n", + peasycap->audio_idle, + strerror(rc), rc); + } } } + return; } -return; -} /*---------------------------------------------------------------------------*/ -if (purb->status) { - if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) { - JOM(16, "urb status -ESHUTDOWN or -ENOENT\n"); - return; + if (purb->status) { + if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) { + JOM(16, "urb status -ESHUTDOWN or -ENOENT\n"); + return; + } + SAM("ERROR: non-zero urb status: -%s: %d\n", + strerror(purb->status), purb->status); + goto resubmit; } - SAM("ERROR: non-zero urb status: -%s: %d\n", - strerror(purb->status), purb->status); - goto resubmit; -} /*---------------------------------------------------------------------------*/ /* * PROCEED HERE WHEN NO ERROR */ /*---------------------------------------------------------------------------*/ #ifdef UPSAMPLE -oldaudio = peasycap->oldaudio; + oldaudio = peasycap->oldaudio; #endif /*UPSAMPLE*/ -for (i = 0; i < purb->number_of_packets; i++) { - if (!purb->iso_frame_desc[i].status) { + for (i = 0; i < purb->number_of_packets; i++) { + if (!purb->iso_frame_desc[i].status) { - SAM("-%s\n", strerror(purb->iso_frame_desc[i].status)); + SAM("-%s\n", strerror(purb->iso_frame_desc[i].status)); - more = purb->iso_frame_desc[i].actual_length; + more = purb->iso_frame_desc[i].actual_length; - if (!more) - peasycap->audio_mt++; - else { - if (peasycap->audio_mt) { - JOM(12, "%4i empty audio urb frames\n", - peasycap->audio_mt); - peasycap->audio_mt = 0; - } + if (!more) + peasycap->audio_mt++; + else { + if (peasycap->audio_mt) { + JOM(12, "%4i empty audio urb frames\n", + peasycap->audio_mt); + peasycap->audio_mt = 0; + } - p1 = (u8 *)(purb->transfer_buffer + - purb->iso_frame_desc[i].offset); + p1 = (u8 *)(purb->transfer_buffer + purb->iso_frame_desc[i].offset); + + leap = 0; + p1 += leap; + more -= leap; + /* + * COPY more BYTES FROM ISOC BUFFER + * TO AUDIO BUFFER, CONVERTING + * 8-BIT MONO TO 16-BIT SIGNED + * LITTLE-ENDIAN SAMPLES IF NECESSARY + */ + while (more) { + if (0 > more) { + SAM("MISTAKE: more is negative\n"); + return; + } + if (peasycap->audio_buffer_page_many <= peasycap->audio_fill) { + SAM("ERROR: bad peasycap->audio_fill\n"); + return; + } - leap = 0; - p1 += leap; - more -= leap; -/*---------------------------------------------------------------------------*/ -/* - * COPY more BYTES FROM ISOC BUFFER TO AUDIO BUFFER, - * CONVERTING 8-BIT MONO TO 16-BIT SIGNED LITTLE-ENDIAN SAMPLES IF NECESSARY - */ -/*---------------------------------------------------------------------------*/ - while (more) { - if (0 > more) { - SAM("MISTAKE: more is negative\n"); - return; - } - if (peasycap->audio_buffer_page_many <= - peasycap->audio_fill) { - SAM("ERROR: bad " - "peasycap->audio_fill\n"); - return; - } + paudio_buffer = &peasycap->audio_buffer[peasycap->audio_fill]; + if (PAGE_SIZE < (paudio_buffer->pto - paudio_buffer->pgo)) { + SAM("ERROR: bad paudio_buffer->pto\n"); + return; + } + if (PAGE_SIZE == (paudio_buffer->pto - paudio_buffer->pgo)) { - paudio_buffer = &peasycap->audio_buffer - [peasycap->audio_fill]; - if (PAGE_SIZE < (paudio_buffer->pto - - paudio_buffer->pgo)) { - SAM("ERROR: bad paudio_buffer->pto\n"); - return; - } - if (PAGE_SIZE == (paudio_buffer->pto - - paudio_buffer->pgo)) { - - paudio_buffer->pto = - paudio_buffer->pgo; - (peasycap->audio_fill)++; - if (peasycap-> - audio_buffer_page_many <= - peasycap->audio_fill) - peasycap->audio_fill = 0; - - JOM(8, "bumped peasycap->" - "audio_fill to %i\n", - peasycap->audio_fill); - - paudio_buffer = &peasycap-> - audio_buffer - [peasycap->audio_fill]; - paudio_buffer->pto = - paudio_buffer->pgo; - - if (!(peasycap->audio_fill % - peasycap-> - audio_pages_per_fragment)) { - JOM(12, "wakeup call on wq_" - "audio, %i=frag reading %i" - "=fragment fill\n", - (peasycap->audio_read / - peasycap-> - audio_pages_per_fragment), - (peasycap->audio_fill / - peasycap-> - audio_pages_per_fragment)); - wake_up_interruptible - (&(peasycap->wq_audio)); + paudio_buffer->pto = paudio_buffer->pgo; + (peasycap->audio_fill)++; + if (peasycap->audio_buffer_page_many <= peasycap->audio_fill) + peasycap->audio_fill = 0; + + JOM(8, "bumped peasycap->" + "audio_fill to %i\n", + peasycap->audio_fill); + + paudio_buffer = &peasycap->audio_buffer[peasycap->audio_fill]; + paudio_buffer->pto = paudio_buffer->pgo; + + if (!(peasycap->audio_fill % peasycap->audio_pages_per_fragment)) { + JOM(12, "wakeup call on wq_audio, %i=frag reading %i=fragment fill\n", + (peasycap->audio_read / peasycap->audio_pages_per_fragment), + (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); + wake_up_interruptible(&(peasycap->wq_audio)); + } } - } - much = PAGE_SIZE - (int)(paudio_buffer->pto - - paudio_buffer->pgo); + much = PAGE_SIZE - (int)(paudio_buffer->pto - paudio_buffer->pgo); - if (false == peasycap->microphone) { - if (much > more) - much = more; + if (false == peasycap->microphone) { + if (much > more) + much = more; - memcpy(paudio_buffer->pto, p1, much); - p1 += much; - more -= much; - } else { + memcpy(paudio_buffer->pto, p1, much); + p1 += much; + more -= much; + } else { #ifdef UPSAMPLE - if (much % 16) - JOM(8, "MISTAKE? much" - " is not divisible by 16\n"); - if (much > (16 * - more)) - much = 16 * - more; - p2 = (u8 *)paudio_buffer->pto; - - for (j = 0; j < (much/16); j++) { - newaudio = ((int) *p1) - 128; - newaudio = 128 * - newaudio; - - delta = (newaudio - oldaudio) - / 4; - tmp = oldaudio + delta; - - for (k = 0; k < 4; k++) { - *p2 = (0x00FF & tmp); - *(p2 + 1) = (0xFF00 & - tmp) >> 8; - p2 += 2; + if (much % 16) + JOM(8, "MISTAKE? much" + " is not divisible by 16\n"); + if (much > (16 * more)) + much = 16 * more; + p2 = (u8 *)paudio_buffer->pto; + + for (j = 0; j < (much/16); j++) { + newaudio = ((int) *p1) - 128; + newaudio = 128 * newaudio; + + delta = (newaudio - oldaudio) / 4; + tmp = oldaudio + delta; + + for (k = 0; k < 4; k++) { + *p2 = (0x00FF & tmp); + *(p2 + 1) = (0xFF00 & tmp) >> 8; + p2 += 2; + *p2 = (0x00FF & tmp); + *(p2 + 1) = (0xFF00 & tmp) >> 8; + p2 += 2; + + tmp += delta; + } + p1++; + more--; + oldaudio = tmp; + } +#else /*!UPSAMPLE*/ + if (much > (2 * more)) + much = 2 * more; + p2 = (u8 *)paudio_buffer->pto; + + for (j = 0; j < (much / 2); j++) { + tmp = ((int) *p1) - 128; + tmp = 128 * tmp; *p2 = (0x00FF & tmp); - *(p2 + 1) = (0xFF00 & - tmp) >> 8; + *(p2 + 1) = (0xFF00 & tmp) >> 8; + p1++; p2 += 2; - - tmp += delta; + more--; } - p1++; - more--; - oldaudio = tmp; - } -#else /*!UPSAMPLE*/ - if (much > (2 * more)) - much = 2 * more; - p2 = (u8 *)paudio_buffer->pto; - - for (j = 0; j < (much / 2); j++) { - tmp = ((int) *p1) - 128; - tmp = 128 * - tmp; - *p2 = (0x00FF & tmp); - *(p2 + 1) = (0xFF00 & tmp) >> - 8; - p1++; p2 += 2; - more--; - } #endif /*UPSAMPLE*/ + } + (paudio_buffer->pto) += much; } - (paudio_buffer->pto) += much; } + } else { + JOM(12, "discarding audio samples because " + "%i=purb->iso_frame_desc[i].status\n", + purb->iso_frame_desc[i].status); } - } else { - JOM(12, "discarding audio samples because " - "%i=purb->iso_frame_desc[i].status\n", - purb->iso_frame_desc[i].status); - } #ifdef UPSAMPLE -peasycap->oldaudio = oldaudio; + peasycap->oldaudio = oldaudio; #endif /*UPSAMPLE*/ -} + } /*---------------------------------------------------------------------------*/ /* * RESUBMIT THIS URB */ /*---------------------------------------------------------------------------*/ resubmit: -if (peasycap->audio_isoc_streaming) { - rc = usb_submit_urb(purb, GFP_ATOMIC); - if (rc) { - if (-ENODEV != rc && -ENOENT != rc) { - SAM("ERROR: while %i=audio_idle, " - "usb_submit_urb() failed " - "with rc: -%s: %d\n", peasycap->audio_idle, - strerror(rc), rc); + if (peasycap->audio_isoc_streaming) { + rc = usb_submit_urb(purb, GFP_ATOMIC); + if (rc) { + if (-ENODEV != rc && -ENOENT != rc) { + SAM("ERROR: while %i=audio_idle, " + "usb_submit_urb() failed " + "with rc: -%s: %d\n", peasycap->audio_idle, + strerror(rc), rc); + } } } -} -return; + return; } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ @@ -303,31 +274,31 @@ return; /*---------------------------------------------------------------------------*/ static int easyoss_open(struct inode *inode, struct file *file) { -struct usb_interface *pusb_interface; -struct easycap *peasycap; -int subminor; + struct usb_interface *pusb_interface; + struct easycap *peasycap; + int subminor; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #ifdef EASYCAP_IS_VIDEODEV_CLIENT -struct v4l2_device *pv4l2_device; + struct v4l2_device *pv4l2_device; #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -JOT(4, "begins\n"); + JOT(4, "begins\n"); -subminor = iminor(inode); + subminor = iminor(inode); -pusb_interface = usb_find_interface(&easycap_usb_driver, subminor); -if (NULL == pusb_interface) { - SAY("ERROR: pusb_interface is NULL\n"); - SAY("ending unsuccessfully\n"); - return -1; -} -peasycap = usb_get_intfdata(pusb_interface); -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - SAY("ending unsuccessfully\n"); - return -1; -} + pusb_interface = usb_find_interface(&easycap_usb_driver, subminor); + if (NULL == pusb_interface) { + SAY("ERROR: pusb_interface is NULL\n"); + SAY("ending unsuccessfully\n"); + return -1; + } + peasycap = usb_get_intfdata(pusb_interface); + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + SAY("ending unsuccessfully\n"); + return -1; + } /*---------------------------------------------------------------------------*/ #ifdef EASYCAP_IS_VIDEODEV_CLIENT /*---------------------------------------------------------------------------*/ @@ -338,68 +309,68 @@ if (NULL == peasycap) { * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED. */ /*---------------------------------------------------------------------------*/ -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - pv4l2_device = usb_get_intfdata(pusb_interface); - if (NULL == pv4l2_device) { - SAY("ERROR: pv4l2_device is NULL\n"); - return -EFAULT; + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + pv4l2_device = usb_get_intfdata(pusb_interface); + if (NULL == pv4l2_device) { + SAY("ERROR: pv4l2_device is NULL\n"); + return -EFAULT; + } + peasycap = container_of(pv4l2_device, + struct easycap, v4l2_device); } - peasycap = (struct easycap *) - container_of(pv4l2_device, struct easycap, v4l2_device); -} #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*---------------------------------------------------------------------------*/ -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return -EFAULT; -} + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + return -EFAULT; + } /*---------------------------------------------------------------------------*/ -file->private_data = peasycap; + file->private_data = peasycap; -if (0 != easycap_sound_setup(peasycap)) { - ; - ; -} -return 0; + if (0 != easycap_sound_setup(peasycap)) { + ; + ; + } + return 0; } /*****************************************************************************/ static int easyoss_release(struct inode *inode, struct file *file) { -struct easycap *peasycap; + struct easycap *peasycap; -JOT(4, "begins\n"); + JOT(4, "begins\n"); -peasycap = file->private_data; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL.\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return -EFAULT; -} -if (0 != kill_audio_urbs(peasycap)) { - SAM("ERROR: kill_audio_urbs() failed\n"); - return -EFAULT; -} -JOM(4, "ending successfully\n"); -return 0; + peasycap = file->private_data; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL.\n"); + return -EFAULT; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + return -EFAULT; + } + if (0 != kill_audio_urbs(peasycap)) { + SAM("ERROR: kill_audio_urbs() failed\n"); + return -EFAULT; + } + JOM(4, "ending successfully\n"); + return 0; } /*****************************************************************************/ static ssize_t easyoss_read(struct file *file, char __user *puserspacebuffer, - size_t kount, loff_t *poff) + size_t kount, loff_t *poff) { -struct timeval timeval; -long long int above, below, mean; -struct signed_div_result sdr; -unsigned char *p0; -long int kount1, more, rc, l0, lm; -int fragment, kd; -struct easycap *peasycap; -struct data_buffer *pdata_buffer; -size_t szret; + struct timeval timeval; + long long int above, below, mean; + struct signed_div_result sdr; + unsigned char *p0; + long int kount1, more, rc, l0, lm; + int fragment, kd; + struct easycap *peasycap; + struct data_buffer *pdata_buffer; + size_t szret; /*---------------------------------------------------------------------------*/ /* @@ -412,178 +383,133 @@ size_t szret; */ /*---------------------------------------------------------------------------*/ -JOT(8, "%5i=kount %5i=*poff\n", (int)kount, (int)(*poff)); + JOT(8, "%5zd=kount %5lld=*poff\n", kount, *poff); -if (NULL == file) { - SAY("ERROR: file is NULL\n"); - return -ERESTARTSYS; -} -peasycap = file->private_data; -if (NULL == peasycap) { - SAY("ERROR in easyoss_read(): peasycap is NULL\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -kd = isdongle(peasycap); -if (0 <= kd && DONGLE_MANY > kd) { - if (mutex_lock_interruptible(&(easycapdc60_dongle[kd].mutex_audio))) { - SAY("ERROR: " - "cannot lock easycapdc60_dongle[%i].mutex_audio\n", kd); - return -ERESTARTSYS; - } - JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd); -/*---------------------------------------------------------------------------*/ -/* - * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap, - * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. - * IF NECESSARY, BAIL OUT. -*/ -/*---------------------------------------------------------------------------*/ - if (kd != isdongle(peasycap)) - return -ERESTARTSYS; if (NULL == file) { SAY("ERROR: file is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; } peasycap = file->private_data; if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; + SAY("ERROR in easyoss_read(): peasycap is NULL\n"); + return -EFAULT; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { SAY("ERROR: bad peasycap: %p\n", peasycap); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; + return -EFAULT; } if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; + SAY("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; } -} else { -/*---------------------------------------------------------------------------*/ -/* - * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE - * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT. -*/ -/*---------------------------------------------------------------------------*/ - return -ERESTARTSYS; -} -/*---------------------------------------------------------------------------*/ -if (file->f_flags & O_NONBLOCK) - JOT(16, "NONBLOCK kount=%i, *poff=%i\n", (int)kount, (int)(*poff)); -else - JOT(8, "BLOCKING kount=%i, *poff=%i\n", (int)kount, (int)(*poff)); - -if ((0 > peasycap->audio_read) || - (peasycap->audio_buffer_page_many <= peasycap->audio_read)) { - SAM("ERROR: peasycap->audio_read out of range\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; -} -pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; -if (NULL == pdata_buffer) { - SAM("ERROR: pdata_buffer is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; -} -JOM(12, "before wait, %i=frag read %i=frag fill\n", - (peasycap->audio_read / peasycap->audio_pages_per_fragment), - (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); -fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment); -while ((fragment == (peasycap->audio_fill / - peasycap->audio_pages_per_fragment)) || - (0 == (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))) { - if (file->f_flags & O_NONBLOCK) { - JOM(16, "returning -EAGAIN as instructed\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EAGAIN; - } - rc = wait_event_interruptible(peasycap->wq_audio, - (peasycap->audio_idle || peasycap->audio_eof || - ((fragment != (peasycap->audio_fill / - peasycap->audio_pages_per_fragment)) && - (0 < (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))))); - if (rc) { - SAM("aborted by signal\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + kd = isdongle(peasycap); + if (0 <= kd && DONGLE_MANY > kd) { + if (mutex_lock_interruptible(&(easycapdc60_dongle[kd].mutex_audio))) { + SAY("ERROR: " + "cannot lock dongle[%i].mutex_audio\n", kd); + return -ERESTARTSYS; + } + JOM(4, "locked dongle[%i].mutex_audio\n", kd); + /* + * MEANWHILE, easycap_usb_disconnect() + * MAY HAVE FREED POINTER peasycap, + * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. + * IF NECESSARY, BAIL OUT. + */ + if (kd != isdongle(peasycap)) + return -ERESTARTSYS; + if (NULL == file) { + SAY("ERROR: file is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + peasycap = file->private_data; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + } else { + /* + * IF easycap_usb_disconnect() + * HAS ALREADY FREED POINTER peasycap BEFORE THE + * ATTEMPT TO ACQUIRE THE SEMAPHORE, + * isdongle() WILL HAVE FAILED. BAIL OUT. + */ return -ERESTARTSYS; } - if (peasycap->audio_eof) { - JOM(8, "returning 0 because %i=audio_eof\n", - peasycap->audio_eof); - kill_audio_urbs(peasycap); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return 0; - } - if (peasycap->audio_idle) { - JOM(16, "returning 0 because %i=audio_idle\n", - peasycap->audio_idle); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return 0; - } - if (!peasycap->audio_isoc_streaming) { - JOM(16, "returning 0 because audio urbs not streaming\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return 0; - } -} -JOM(12, "after wait, %i=frag read %i=frag fill\n", - (peasycap->audio_read / peasycap->audio_pages_per_fragment), - (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); -szret = (size_t)0; -fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment); -while (fragment == (peasycap->audio_read / - peasycap->audio_pages_per_fragment)) { - if (NULL == pdata_buffer->pgo) { - SAM("ERROR: pdata_buffer->pgo is NULL\n"); +/*---------------------------------------------------------------------------*/ + JOT(16, "%sBLOCKING kount=%zd, *poff=%lld\n", + (file->f_flags & O_NONBLOCK) ? "NON" : "", kount, *poff); + + if ((0 > peasycap->audio_read) || + (peasycap->audio_buffer_page_many <= peasycap->audio_read)) { + SAM("ERROR: peasycap->audio_read out of range\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } - if (NULL == pdata_buffer->pto) { - SAM("ERROR: pdata_buffer->pto is NULL\n"); + pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; + if (NULL == pdata_buffer) { + SAM("ERROR: pdata_buffer is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } - kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo); - if (0 > kount1) { - SAM("MISTAKE: kount1 is negative\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } - if (!kount1) { - (peasycap->audio_read)++; - if (peasycap->audio_buffer_page_many <= peasycap->audio_read) - peasycap->audio_read = 0; - JOM(12, "bumped peasycap->audio_read to %i\n", - peasycap->audio_read); - - if (fragment != (peasycap->audio_read / - peasycap->audio_pages_per_fragment)) - break; - - if ((0 > peasycap->audio_read) || - (peasycap->audio_buffer_page_many <= - peasycap->audio_read)) { - SAM("ERROR: peasycap->audio_read out of range\n"); + JOM(12, "before wait, %i=frag read %i=frag fill\n", + (peasycap->audio_read / peasycap->audio_pages_per_fragment), + (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); + fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment); + while ((fragment == (peasycap->audio_fill / peasycap->audio_pages_per_fragment)) || + (0 == (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))) { + if (file->f_flags & O_NONBLOCK) { + JOM(16, "returning -EAGAIN as instructed\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; + return -EAGAIN; } - pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; - if (NULL == pdata_buffer) { - SAM("ERROR: pdata_buffer is NULL\n"); + rc = wait_event_interruptible(peasycap->wq_audio, + (peasycap->audio_idle || peasycap->audio_eof || + ((fragment != + (peasycap->audio_fill / peasycap->audio_pages_per_fragment)) && + (0 < (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))))); + if (rc) { + SAM("aborted by signal\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; + return -ERESTARTSYS; + } + if (peasycap->audio_eof) { + JOM(8, "returning 0 because %i=audio_eof\n", + peasycap->audio_eof); + kill_audio_urbs(peasycap); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return 0; + } + if (peasycap->audio_idle) { + JOM(16, "returning 0 because %i=audio_idle\n", + peasycap->audio_idle); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return 0; + } + if (!peasycap->audio_isoc_streaming) { + JOM(16, "returning 0 because audio urbs not streaming\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return 0; } + } + JOM(12, "after wait, %i=frag read %i=frag fill\n", + (peasycap->audio_read / peasycap->audio_pages_per_fragment), + (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); + szret = (size_t)0; + fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment); + while (fragment == (peasycap->audio_read / peasycap->audio_pages_per_fragment)) { if (NULL == pdata_buffer->pgo) { SAM("ERROR: pdata_buffer->pgo is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); @@ -595,391 +521,428 @@ while (fragment == (peasycap->audio_read / return -EFAULT; } kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo); - } - JOM(12, "ready to send %li bytes\n", (long int) kount1); - JOM(12, "still to send %li bytes\n", (long int) kount); - more = kount1; - if (more > kount) - more = kount; - JOM(12, "agreed to send %li bytes from page %i\n", - more, peasycap->audio_read); - if (!more) - break; + if (0 > kount1) { + SAM("MISTAKE: kount1 is negative\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + if (!kount1) { + peasycap->audio_read++; + if (peasycap->audio_buffer_page_many <= peasycap->audio_read) + peasycap->audio_read = 0; + JOM(12, "bumped peasycap->audio_read to %i\n", + peasycap->audio_read); + + if (fragment != (peasycap->audio_read / peasycap->audio_pages_per_fragment)) + break; + + if ((0 > peasycap->audio_read) || + (peasycap->audio_buffer_page_many <= peasycap->audio_read)) { + SAM("ERROR: peasycap->audio_read out of range\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; + if (NULL == pdata_buffer) { + SAM("ERROR: pdata_buffer is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + if (NULL == pdata_buffer->pgo) { + SAM("ERROR: pdata_buffer->pgo is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + if (NULL == pdata_buffer->pto) { + SAM("ERROR: pdata_buffer->pto is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo); + } + JOM(12, "ready to send %zd bytes\n", kount1); + JOM(12, "still to send %li bytes\n", (long int) kount); + more = kount1; + if (more > kount) + more = kount; + JOM(12, "agreed to send %li bytes from page %i\n", + more, peasycap->audio_read); + if (!more) + break; -/*---------------------------------------------------------------------------*/ -/* - * ACCUMULATE DYNAMIC-RANGE INFORMATION - */ -/*---------------------------------------------------------------------------*/ - p0 = (unsigned char *)pdata_buffer->pgo; l0 = 0; lm = more/2; - while (l0 < lm) { - SUMMER(p0, &peasycap->audio_sample, &peasycap->audio_niveau, - &peasycap->audio_square); l0++; p0 += 2; + /* + * ACCUMULATE DYNAMIC-RANGE INFORMATION + */ + p0 = (unsigned char *)pdata_buffer->pgo; + l0 = 0; + lm = more/2; + while (l0 < lm) { + SUMMER(p0, &peasycap->audio_sample, + &peasycap->audio_niveau, + &peasycap->audio_square); + l0++; + p0 += 2; + } + /*-----------------------------------------------------------*/ + rc = copy_to_user(puserspacebuffer, pdata_buffer->pto, more); + if (rc) { + SAM("ERROR: copy_to_user() returned %li\n", rc); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + *poff += (loff_t)more; + szret += (size_t)more; + pdata_buffer->pto += more; + puserspacebuffer += more; + kount -= (size_t)more; } -/*---------------------------------------------------------------------------*/ - rc = copy_to_user(puserspacebuffer, pdata_buffer->pto, more); - if (rc) { - SAM("ERROR: copy_to_user() returned %li\n", rc); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; + JOM(12, "after read, %i=frag read %i=frag fill\n", + (peasycap->audio_read / peasycap->audio_pages_per_fragment), + (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); + if (kount < 0) { + SAM("MISTAKE: %li=kount %li=szret\n", + (long int)kount, (long int)szret); } - *poff += (loff_t)more; - szret += (size_t)more; - pdata_buffer->pto += more; - puserspacebuffer += more; - kount -= (size_t)more; -} -JOM(12, "after read, %i=frag read %i=frag fill\n", - (peasycap->audio_read / peasycap->audio_pages_per_fragment), - (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); -if (kount < 0) { - SAM("MISTAKE: %li=kount %li=szret\n", - (long int)kount, (long int)szret); -} /*---------------------------------------------------------------------------*/ /* * CALCULATE DYNAMIC RANGE FOR (VAPOURWARE) AUTOMATIC VOLUME CONTROL */ /*---------------------------------------------------------------------------*/ -if (peasycap->audio_sample) { - below = peasycap->audio_sample; - above = peasycap->audio_square; - sdr = signed_div(above, below); - above = sdr.quotient; - mean = peasycap->audio_niveau; - sdr = signed_div(mean, peasycap->audio_sample); - - JOM(8, "%8lli=mean %8lli=meansquare after %lli samples, =>\n", - sdr.quotient, above, peasycap->audio_sample); - - sdr = signed_div(above, 32768); - JOM(8, "audio dynamic range is roughly %lli\n", sdr.quotient); -} + if (peasycap->audio_sample) { + below = peasycap->audio_sample; + above = peasycap->audio_square; + sdr = signed_div(above, below); + above = sdr.quotient; + mean = peasycap->audio_niveau; + sdr = signed_div(mean, peasycap->audio_sample); + + JOM(8, "%8lli=mean %8lli=meansquare after %lli samples, =>\n", + sdr.quotient, above, peasycap->audio_sample); + + sdr = signed_div(above, 32768); + JOM(8, "audio dynamic range is roughly %lli\n", sdr.quotient); + } /*---------------------------------------------------------------------------*/ /* * UPDATE THE AUDIO CLOCK */ /*---------------------------------------------------------------------------*/ -do_gettimeofday(&timeval); -if (!peasycap->timeval1.tv_sec) { - peasycap->audio_bytes = 0; - peasycap->timeval3 = timeval; - peasycap->timeval1 = peasycap->timeval3; - sdr.quotient = 192000; -} else { - peasycap->audio_bytes += (long long int) szret; - below = ((long long int)(1000000)) * - ((long long int)(timeval.tv_sec - - peasycap->timeval3.tv_sec)) + - (long long int)(timeval.tv_usec - peasycap->timeval3.tv_usec); - above = 1000000 * ((long long int) peasycap->audio_bytes); - - if (below) - sdr = signed_div(above, below); - else + do_gettimeofday(&timeval); + if (!peasycap->timeval1.tv_sec) { + peasycap->audio_bytes = 0; + peasycap->timeval3 = timeval; + peasycap->timeval1 = peasycap->timeval3; sdr.quotient = 192000; -} -JOM(8, "audio streaming at %lli bytes/second\n", sdr.quotient); -peasycap->dnbydt = sdr.quotient; + } else { + peasycap->audio_bytes += (long long int) szret; + below = ((long long int)(1000000)) * + ((long long int)(timeval.tv_sec - peasycap->timeval3.tv_sec)) + + (long long int)(timeval.tv_usec - peasycap->timeval3.tv_usec); + above = 1000000 * ((long long int) peasycap->audio_bytes); -mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); -JOM(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd); -JOM(8, "returning %li\n", (long int)szret); -return szret; + if (below) + sdr = signed_div(above, below); + else + sdr.quotient = 192000; + } + JOM(8, "audio streaming at %lli bytes/second\n", sdr.quotient); + peasycap->dnbydt = sdr.quotient; + + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + JOM(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd); + JOM(8, "returning %li\n", (long int)szret); + return szret; } /*---------------------------------------------------------------------------*/ static long easyoss_unlocked_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { -struct easycap *peasycap; -struct usb_device *p; -int kd; + struct easycap *peasycap; + struct usb_device *p; + int kd; -if (NULL == file) { - SAY("ERROR: file is NULL\n"); - return -ERESTARTSYS; -} -peasycap = file->private_data; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL.\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; -} -p = peasycap->pusb_device; -if (NULL == p) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -kd = isdongle(peasycap); -if (0 <= kd && DONGLE_MANY > kd) { - if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_audio)) { - SAY("ERROR: cannot lock " - "easycapdc60_dongle[%i].mutex_audio\n", kd); - return -ERESTARTSYS; - } - JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd); -/*---------------------------------------------------------------------------*/ -/* - * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap, - * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. - * IF NECESSARY, BAIL OUT. -*/ -/*---------------------------------------------------------------------------*/ - if (kd != isdongle(peasycap)) - return -ERESTARTSYS; if (NULL == file) { SAY("ERROR: file is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; } peasycap = file->private_data; if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; + SAY("ERROR: peasycap is NULL.\n"); + return -EFAULT; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { SAY("ERROR: bad peasycap\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } p = peasycap->pusb_device; - if (NULL == peasycap->pusb_device) { + if (NULL == p) { SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + kd = isdongle(peasycap); + if (0 <= kd && DONGLE_MANY > kd) { + if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_audio)) { + SAY("ERROR: cannot lock " + "easycapdc60_dongle[%i].mutex_audio\n", kd); + return -ERESTARTSYS; + } + JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd); + /* + * MEANWHILE, easycap_usb_disconnect() + * MAY HAVE FREED POINTER peasycap, + * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. + * IF NECESSARY, BAIL OUT. + */ + if (kd != isdongle(peasycap)) + return -ERESTARTSYS; + if (NULL == file) { + SAY("ERROR: file is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + peasycap = file->private_data; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + p = peasycap->pusb_device; + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + } else { + /* + * IF easycap_usb_disconnect() + * HAS ALREADY FREED POINTER peasycap BEFORE THE + * ATTEMPT TO ACQUIRE THE SEMAPHORE, + * isdongle() WILL HAVE FAILED. BAIL OUT. + */ return -ERESTARTSYS; } -} else { -/*---------------------------------------------------------------------------*/ -/* - * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE - * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT. -*/ /*---------------------------------------------------------------------------*/ - return -ERESTARTSYS; -} -/*---------------------------------------------------------------------------*/ -switch (cmd) { -case SNDCTL_DSP_GETCAPS: { - int caps; - JOM(8, "SNDCTL_DSP_GETCAPS\n"); + switch (cmd) { + case SNDCTL_DSP_GETCAPS: { + int caps; + JOM(8, "SNDCTL_DSP_GETCAPS\n"); #ifdef UPSAMPLE - if (true == peasycap->microphone) - caps = 0x04400000; - else - caps = 0x04400000; + if (true == peasycap->microphone) + caps = 0x04400000; + else + caps = 0x04400000; #else - if (true == peasycap->microphone) - caps = 0x02400000; - else - caps = 0x04400000; + if (true == peasycap->microphone) + caps = 0x02400000; + else + caps = 0x04400000; #endif /*UPSAMPLE*/ - if (0 != copy_to_user((void __user *)arg, &caps, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; + if (copy_to_user((void __user *)arg, &caps, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; } - break; -} -case SNDCTL_DSP_GETFMTS: { - int incoming; - JOM(8, "SNDCTL_DSP_GETFMTS\n"); + case SNDCTL_DSP_GETFMTS: { + int incoming; + JOM(8, "SNDCTL_DSP_GETFMTS\n"); #ifdef UPSAMPLE - if (true == peasycap->microphone) - incoming = AFMT_S16_LE; - else - incoming = AFMT_S16_LE; + if (peasycap->microphone) + incoming = AFMT_S16_LE; + else + incoming = AFMT_S16_LE; #else - if (true == peasycap->microphone) - incoming = AFMT_S16_LE; - else - incoming = AFMT_S16_LE; + if (peasycap->microphone) + incoming = AFMT_S16_LE; + else + incoming = AFMT_S16_LE; #endif /*UPSAMPLE*/ - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - break; -} -case SNDCTL_DSP_SETFMT: { - int incoming, outgoing; - JOM(8, "SNDCTL_DSP_SETFMT\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; + if (copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; } - JOM(8, "........... %i=incoming\n", incoming); + case SNDCTL_DSP_SETFMT: { + int incoming, outgoing; + JOM(8, "SNDCTL_DSP_SETFMT\n"); + if (copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + JOM(8, "........... %i=incoming\n", incoming); #ifdef UPSAMPLE - if (true == peasycap->microphone) - outgoing = AFMT_S16_LE; - else - outgoing = AFMT_S16_LE; + if (true == peasycap->microphone) + outgoing = AFMT_S16_LE; + else + outgoing = AFMT_S16_LE; #else - if (true == peasycap->microphone) - outgoing = AFMT_S16_LE; - else - outgoing = AFMT_S16_LE; + if (true == peasycap->microphone) + outgoing = AFMT_S16_LE; + else + outgoing = AFMT_S16_LE; #endif /*UPSAMPLE*/ - if (incoming != outgoing) { - JOM(8, "........... %i=outgoing\n", outgoing); - JOM(8, " cf. %i=AFMT_S16_LE\n", AFMT_S16_LE); - JOM(8, " cf. %i=AFMT_U8\n", AFMT_U8); - if (0 != copy_to_user((void __user *)arg, &outgoing, - sizeof(int))) { + if (incoming != outgoing) { + JOM(8, "........... %i=outgoing\n", outgoing); + JOM(8, " cf. %i=AFMT_S16_LE\n", AFMT_S16_LE); + JOM(8, " cf. %i=AFMT_U8\n", AFMT_U8); + if (copy_to_user((void __user *)arg, &outgoing, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; + return -EINVAL ; } - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EINVAL ; - } - break; -} -case SNDCTL_DSP_STEREO: { - int incoming; - JOM(8, "SNDCTL_DSP_STEREO\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; + break; } - JOM(8, "........... %i=incoming\n", incoming); + case SNDCTL_DSP_STEREO: { + int incoming; + JOM(8, "SNDCTL_DSP_STEREO\n"); + if (copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + JOM(8, "........... %i=incoming\n", incoming); #ifdef UPSAMPLE - if (true == peasycap->microphone) - incoming = 1; - else - incoming = 1; + if (true == peasycap->microphone) + incoming = 1; + else + incoming = 1; #else - if (true == peasycap->microphone) - incoming = 0; - else - incoming = 1; + if (true == peasycap->microphone) + incoming = 0; + else + incoming = 1; #endif /*UPSAMPLE*/ - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - break; -} -case SNDCTL_DSP_SPEED: { - int incoming; - JOM(8, "SNDCTL_DSP_SPEED\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; + if (copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; } - JOM(8, "........... %i=incoming\n", incoming); + case SNDCTL_DSP_SPEED: { + int incoming; + JOM(8, "SNDCTL_DSP_SPEED\n"); + if (copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + JOM(8, "........... %i=incoming\n", incoming); #ifdef UPSAMPLE - if (true == peasycap->microphone) - incoming = 32000; - else - incoming = 48000; + if (true == peasycap->microphone) + incoming = 32000; + else + incoming = 48000; #else - if (true == peasycap->microphone) - incoming = 8000; - else - incoming = 48000; + if (true == peasycap->microphone) + incoming = 8000; + else + incoming = 48000; #endif /*UPSAMPLE*/ - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - break; -} -case SNDCTL_DSP_GETTRIGGER: { - int incoming; - JOM(8, "SNDCTL_DSP_GETTRIGGER\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; + if (copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; } - JOM(8, "........... %i=incoming\n", incoming); + case SNDCTL_DSP_GETTRIGGER: { + int incoming; + JOM(8, "SNDCTL_DSP_GETTRIGGER\n"); + if (copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + JOM(8, "........... %i=incoming\n", incoming); - incoming = PCM_ENABLE_INPUT; - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - break; -} -case SNDCTL_DSP_SETTRIGGER: { - int incoming; - JOM(8, "SNDCTL_DSP_SETTRIGGER\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; + incoming = PCM_ENABLE_INPUT; + if (copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; } - JOM(8, "........... %i=incoming\n", incoming); - JOM(8, "........... cf 0x%x=PCM_ENABLE_INPUT " - "0x%x=PCM_ENABLE_OUTPUT\n", - PCM_ENABLE_INPUT, PCM_ENABLE_OUTPUT); - ; - ; - ; - ; - break; -} -case SNDCTL_DSP_GETBLKSIZE: { - int incoming; - JOM(8, "SNDCTL_DSP_GETBLKSIZE\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; + case SNDCTL_DSP_SETTRIGGER: { + int incoming; + JOM(8, "SNDCTL_DSP_SETTRIGGER\n"); + if (copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + JOM(8, "........... %i=incoming\n", incoming); + JOM(8, "........... cf 0x%x=PCM_ENABLE_INPUT " + "0x%x=PCM_ENABLE_OUTPUT\n", + PCM_ENABLE_INPUT, PCM_ENABLE_OUTPUT); + ; + ; + ; + ; + break; } - JOM(8, "........... %i=incoming\n", incoming); - incoming = peasycap->audio_bytes_per_fragment; - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; + case SNDCTL_DSP_GETBLKSIZE: { + int incoming; + JOM(8, "SNDCTL_DSP_GETBLKSIZE\n"); + if (copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + JOM(8, "........... %i=incoming\n", incoming); + incoming = peasycap->audio_bytes_per_fragment; + if (copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; } - break; -} -case SNDCTL_DSP_GETISPACE: { - struct audio_buf_info audio_buf_info; + case SNDCTL_DSP_GETISPACE: { + struct audio_buf_info audio_buf_info; - JOM(8, "SNDCTL_DSP_GETISPACE\n"); + JOM(8, "SNDCTL_DSP_GETISPACE\n"); - audio_buf_info.bytes = peasycap->audio_bytes_per_fragment; - audio_buf_info.fragments = 1; - audio_buf_info.fragsize = 0; - audio_buf_info.fragstotal = 0; + audio_buf_info.bytes = peasycap->audio_bytes_per_fragment; + audio_buf_info.fragments = 1; + audio_buf_info.fragsize = 0; + audio_buf_info.fragstotal = 0; - if (0 != copy_to_user((void __user *)arg, &audio_buf_info, - sizeof(int))) { + if (copy_to_user((void __user *)arg, &audio_buf_info, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; + } + case 0x00005401: + case 0x00005402: + case 0x00005403: + case 0x00005404: + case 0x00005405: + case 0x00005406: { + JOM(8, "SNDCTL_TMR_...: 0x%08X unsupported\n", cmd); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; + return -ENOIOCTLCMD; + } + default: { + JOM(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ENOIOCTLCMD; + } } - break; -} -case 0x00005401: -case 0x00005402: -case 0x00005403: -case 0x00005404: -case 0x00005405: -case 0x00005406: { - JOM(8, "SNDCTL_TMR_...: 0x%08X unsupported\n", cmd); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ENOIOCTLCMD; -} -default: { - JOM(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ENOIOCTLCMD; -} -} -mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); -return 0; + return 0; } /*****************************************************************************/ @@ -997,4 +960,3 @@ struct usb_class_driver easyoss_class = { .minor_base = USB_SKEL_MINOR_BASE, }; /*****************************************************************************/ - -- cgit v1.2.3 From abb46c8cc0826ab67cea69949e3f7757fc92783a Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 28 Feb 2011 19:27:09 +0200 Subject: staging/easycap: add first level indentation to easycap_testcard.c Add the first level indentation to easycap_testcard.c with astyle -t8. No chackpatch warnings were created Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_testcard.c | 209 +++++++++++++++-------------- 1 file changed, 106 insertions(+), 103 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_testcard.c b/drivers/staging/easycap/easycap_testcard.c index e3aa95f9508e..9db26af34441 100644 --- a/drivers/staging/easycap/easycap_testcard.c +++ b/drivers/staging/easycap/easycap_testcard.c @@ -32,121 +32,124 @@ void easycap_testcard(struct easycap *peasycap, int field) { -int total; -int y, u, v, r, g, b; -unsigned char uyvy[4]; -int i1, line, k, m, n, more, much, barwidth, barheight; -unsigned char bfbar[TESTCARD_BYTESPERLINE / 8], *p1, *p2; -struct data_buffer *pfield_buffer; + int total; + int y, u, v, r, g, b; + unsigned char uyvy[4]; + int i1, line, k, m, n, more, much, barwidth, barheight; + unsigned char bfbar[TESTCARD_BYTESPERLINE / 8], *p1, *p2; + struct data_buffer *pfield_buffer; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return; -} -JOM(8, "%i=field\n", field); -switch (peasycap->width) { -case 720: -case 360: { - barwidth = (2 * 720) / 8; - break; -} -case 704: -case 352: { - barwidth = (2 * 704) / 8; - break; -} -case 640: -case 320: { - barwidth = (2 * 640) / 8; - break; -} -default: { - SAM("ERROR: cannot set barwidth\n"); - return; -} -} -if (TESTCARD_BYTESPERLINE < barwidth) { - SAM("ERROR: barwidth is too large\n"); - return; -} -switch (peasycap->height) { -case 576: -case 288: { - barheight = 576; - break; -} -case 480: -case 240: { - barheight = 480; - break; -} -default: { - SAM("ERROR: cannot set barheight\n"); - return; -} -} -total = 0; -k = field; -m = 0; -n = 0; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return; + } + JOM(8, "%i=field\n", field); + switch (peasycap->width) { + case 720: + case 360: { + barwidth = (2 * 720) / 8; + break; + } + case 704: + case 352: { + barwidth = (2 * 704) / 8; + break; + } + case 640: + case 320: { + barwidth = (2 * 640) / 8; + break; + } + default: { + SAM("ERROR: cannot set barwidth\n"); + return; + } + } + if (TESTCARD_BYTESPERLINE < barwidth) { + SAM("ERROR: barwidth is too large\n"); + return; + } + switch (peasycap->height) { + case 576: + case 288: { + barheight = 576; + break; + } + case 480: + case 240: { + barheight = 480; + break; + } + default: { + SAM("ERROR: cannot set barheight\n"); + return; + } + } + total = 0; + k = field; + m = 0; + n = 0; -for (line = 0; line < (barheight / 2); line++) { - for (i1 = 0; i1 < 8; i1++) { - r = (i1 * 256)/8; - g = (i1 * 256)/8; - b = (i1 * 256)/8; + for (line = 0; line < (barheight / 2); line++) { + for (i1 = 0; i1 < 8; i1++) { + r = (i1 * 256)/8; + g = (i1 * 256)/8; + b = (i1 * 256)/8; - y = 299*r/1000 + 587*g/1000 + 114*b/1000 ; - u = -147*r/1000 - 289*g/1000 + 436*b/1000 ; u = u + 128; - v = 615*r/1000 - 515*g/1000 - 100*b/1000 ; v = v + 128; + y = 299*r/1000 + 587*g/1000 + 114*b/1000 ; + u = -147*r/1000 - 289*g/1000 + 436*b/1000 ; + u = u + 128; + v = 615*r/1000 - 515*g/1000 - 100*b/1000 ; + v = v + 128; - uyvy[0] = 0xFF & u ; - uyvy[1] = 0xFF & y ; - uyvy[2] = 0xFF & v ; - uyvy[3] = 0xFF & y ; + uyvy[0] = 0xFF & u ; + uyvy[1] = 0xFF & y ; + uyvy[2] = 0xFF & v ; + uyvy[3] = 0xFF & y ; - p1 = &bfbar[0]; - while (p1 < &bfbar[barwidth]) { - *p1++ = uyvy[0] ; - *p1++ = uyvy[1] ; - *p1++ = uyvy[2] ; - *p1++ = uyvy[3] ; - total += 4; + p1 = &bfbar[0]; + while (p1 < &bfbar[barwidth]) { + *p1++ = uyvy[0] ; + *p1++ = uyvy[1] ; + *p1++ = uyvy[2] ; + *p1++ = uyvy[3] ; + total += 4; } - p1 = &bfbar[0]; - more = barwidth; + p1 = &bfbar[0]; + more = barwidth; - while (more) { - if ((FIELD_BUFFER_SIZE/PAGE_SIZE) <= m) { - SAM("ERROR: bad m reached\n"); - return; - } - if (PAGE_SIZE < n) { - SAM("ERROR: bad n reached\n"); return; - } + while (more) { + if ((FIELD_BUFFER_SIZE/PAGE_SIZE) <= m) { + SAM("ERROR: bad m reached\n"); + return; + } + if (PAGE_SIZE < n) { + SAM("ERROR: bad n reached\n"); + return; + } - if (0 > more) { - SAM("ERROR: internal fault\n"); - return; - } + if (0 > more) { + SAM("ERROR: internal fault\n"); + return; + } - much = PAGE_SIZE - n; - if (much > more) - much = more; - pfield_buffer = &peasycap->field_buffer[k][m]; - p2 = pfield_buffer->pgo + n; - memcpy(p2, p1, much); + much = PAGE_SIZE - n; + if (much > more) + much = more; + pfield_buffer = &peasycap->field_buffer[k][m]; + p2 = pfield_buffer->pgo + n; + memcpy(p2, p1, much); - p1 += much; - n += much; - more -= much; - if (PAGE_SIZE == n) { - m++; - n = 0; + p1 += much; + n += much; + more -= much; + if (PAGE_SIZE == n) { + m++; + n = 0; + } } } } -} -return; + return; } -- cgit v1.2.3 From 50e1fbdc1c9965b6ddbc5c9900377ff18bbf9ae8 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 28 Feb 2011 19:27:10 +0200 Subject: staging/easycap: add first level indentation to easycap_ioctl.c Add the first level indentation to easycap_testcard.c with astyle -t8. About 100 of 80 columns warnings were left out for further fix Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_ioctl.c | 3973 ++++++++++++++++--------------- 1 file changed, 1995 insertions(+), 1978 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index d6d0b725256e..8d8d07fd244d 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -42,257 +42,277 @@ /*---------------------------------------------------------------------------*/ int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id) { -struct easycap_standard const *peasycap_standard; -u16 reg, set; -int ir, rc, need, k; -unsigned int itwas, isnow; -bool resubmit; - -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -peasycap_standard = &easycap_standard[0]; -while (0xFFFF != peasycap_standard->mask) { - if (std_id == peasycap_standard->v4l2_standard.id) - break; - peasycap_standard++; -} -if (0xFFFF == peasycap_standard->mask) { + struct easycap_standard const *peasycap_standard; + u16 reg, set; + int ir, rc, need, k; + unsigned int itwas, isnow; + bool resubmit; + + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } peasycap_standard = &easycap_standard[0]; while (0xFFFF != peasycap_standard->mask) { - if (std_id & peasycap_standard->v4l2_standard.id) + if (std_id == peasycap_standard->v4l2_standard.id) break; peasycap_standard++; } -} -if (0xFFFF == peasycap_standard->mask) { - SAM("ERROR: 0x%08X=std_id: standard not found\n", - (unsigned int)std_id); - return -EINVAL; -} -SAM("selected standard: %s\n", - &(peasycap_standard->v4l2_standard.name[0])); -if (peasycap->standard_offset == - (int)(peasycap_standard - &easycap_standard[0])) { - SAM("requested standard already in effect\n"); - return 0; -} -peasycap->standard_offset = (int)(peasycap_standard - &easycap_standard[0]); -for (k = 0; k < INPUT_MANY; k++) { - if (!peasycap->inputset[k].standard_offset_ok) { + if (0xFFFF == peasycap_standard->mask) { + peasycap_standard = &easycap_standard[0]; + while (0xFFFF != peasycap_standard->mask) { + if (std_id & peasycap_standard->v4l2_standard.id) + break; + peasycap_standard++; + } + } + if (0xFFFF == peasycap_standard->mask) { + SAM("ERROR: 0x%08X=std_id: standard not found\n", + (unsigned int)std_id); + return -EINVAL; + } + SAM("selected standard: %s\n", + &(peasycap_standard->v4l2_standard.name[0])); + if (peasycap->standard_offset == peasycap_standard - easycap_standard) { + SAM("requested standard already in effect\n"); + return 0; + } + peasycap->standard_offset = peasycap_standard - easycap_standard; + for (k = 0; k < INPUT_MANY; k++) { + if (!peasycap->inputset[k].standard_offset_ok) { peasycap->inputset[k].standard_offset = - peasycap->standard_offset; + peasycap->standard_offset; + } } -} -if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { - peasycap->inputset[peasycap->input].standard_offset = - peasycap->standard_offset; - peasycap->inputset[peasycap->input].standard_offset_ok = 1; -} else - JOM(8, "%i=peasycap->input\n", peasycap->input); -peasycap->fps = peasycap_standard->v4l2_standard.frameperiod.denominator / - peasycap_standard->v4l2_standard.frameperiod.numerator; -switch (peasycap->fps) { -case 6: -case 30: { - peasycap->ntsc = true; - break; -} -case 5: -case 25: { - peasycap->ntsc = false; - break; -} -default: { - SAM("MISTAKE: %i=frames-per-second\n", peasycap->fps); - return -ENOENT; -} -} -JOM(8, "%i frames-per-second\n", peasycap->fps); -if (0x8000 & peasycap_standard->mask) { - peasycap->skip = 5; - peasycap->usec = 1000000 / (2 * (5 * peasycap->fps)); - peasycap->tolerate = 1000 * (25 / (5 * peasycap->fps)); -} else { - peasycap->skip = 0; - peasycap->usec = 1000000 / (2 * peasycap->fps); - peasycap->tolerate = 1000 * (25 / peasycap->fps); -} -if (peasycap->video_isoc_streaming) { - resubmit = true; - kill_video_urbs(peasycap); -} else - resubmit = false; + if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { + peasycap->inputset[peasycap->input].standard_offset = + peasycap->standard_offset; + peasycap->inputset[peasycap->input].standard_offset_ok = 1; + } else + JOM(8, "%i=peasycap->input\n", peasycap->input); + + peasycap->fps = peasycap_standard->v4l2_standard.frameperiod.denominator / + peasycap_standard->v4l2_standard.frameperiod.numerator; + switch (peasycap->fps) { + case 6: + case 30: { + peasycap->ntsc = true; + break; + } + case 5: + case 25: { + peasycap->ntsc = false; + break; + } + default: { + SAM("MISTAKE: %i=frames-per-second\n", peasycap->fps); + return -ENOENT; + } + } + JOM(8, "%i frames-per-second\n", peasycap->fps); + if (0x8000 & peasycap_standard->mask) { + peasycap->skip = 5; + peasycap->usec = 1000000 / (2 * (5 * peasycap->fps)); + peasycap->tolerate = 1000 * (25 / (5 * peasycap->fps)); + } else { + peasycap->skip = 0; + peasycap->usec = 1000000 / (2 * peasycap->fps); + peasycap->tolerate = 1000 * (25 / peasycap->fps); + } + if (peasycap->video_isoc_streaming) { + resubmit = true; + kill_video_urbs(peasycap); + } else + resubmit = false; /*--------------------------------------------------------------------------*/ /* * SAA7113H DATASHEET PAGE 44, TABLE 42 */ /*--------------------------------------------------------------------------*/ -need = 0; itwas = 0; reg = 0x00; set = 0x00; -switch (peasycap_standard->mask & 0x000F) { -case NTSC_M_JP: { - reg = 0x0A; set = 0x95; - ir = read_saa(peasycap->pusb_device, reg); - if (0 > ir) - SAM("ERROR: cannot read SAA register 0x%02X\n", reg); - else - itwas = (unsigned int)ir; - rc = write_saa(peasycap->pusb_device, reg, set); - if (rc) - SAM("ERROR: failed to set SAA register " - "0x%02X to 0x%02X for JP standard\n", reg, set); - else { - isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); + need = 0; + itwas = 0; + reg = 0x00; + set = 0x00; + switch (peasycap_standard->mask & 0x000F) { + case NTSC_M_JP: { + reg = 0x0A; + set = 0x95; + ir = read_saa(peasycap->pusb_device, reg); if (0 > ir) - JOM(8, "SAA register 0x%02X changed " - "to 0x%02X\n", reg, isnow); + SAM("ERROR: cannot read SAA register 0x%02X\n", reg); else - JOM(8, "SAA register 0x%02X changed " - "from 0x%02X to 0x%02X\n", reg, itwas, isnow); - } + itwas = (unsigned int)ir; + rc = write_saa(peasycap->pusb_device, reg, set); + if (rc) + SAM("ERROR: failed to set SAA register " + "0x%02X to 0x%02X for JP standard\n", reg, set); + else { + isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); + if (0 > ir) + JOM(8, "SAA register 0x%02X changed " + "to 0x%02X\n", reg, isnow); + else + JOM(8, "SAA register 0x%02X changed " + "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + } - reg = 0x0B; set = 0x48; - ir = read_saa(peasycap->pusb_device, reg); - if (0 > ir) - SAM("ERROR: cannot read SAA register 0x%02X\n", reg); - else - itwas = (unsigned int)ir; - rc = write_saa(peasycap->pusb_device, reg, set); - if (rc) - SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X " - "for JP standard\n", reg, set); - else { - isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); + reg = 0x0B; + set = 0x48; + ir = read_saa(peasycap->pusb_device, reg); if (0 > ir) - JOM(8, "SAA register 0x%02X changed " - "to 0x%02X\n", reg, isnow); + SAM("ERROR: cannot read SAA register 0x%02X\n", reg); else - JOM(8, "SAA register 0x%02X changed " - "from 0x%02X to 0x%02X\n", reg, itwas, isnow); - } + itwas = (unsigned int)ir; + rc = write_saa(peasycap->pusb_device, reg, set); + if (rc) + SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X " + "for JP standard\n", reg, set); + else { + isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); + if (0 > ir) + JOM(8, "SAA register 0x%02X changed " + "to 0x%02X\n", reg, isnow); + else + JOM(8, "SAA register 0x%02X changed " + "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + } /*--------------------------------------------------------------------------*/ /* * NOTE: NO break HERE: RUN ON TO NEXT CASE */ /*--------------------------------------------------------------------------*/ -} -case NTSC_M: -case PAL_BGHIN: { - reg = 0x0E; set = 0x01; need = 1; break; -} -case NTSC_N_443: -case PAL_60: { - reg = 0x0E; set = 0x11; need = 1; break; -} -case NTSC_443: -case PAL_Nc: { - reg = 0x0E; set = 0x21; need = 1; break; -} -case NTSC_N: -case PAL_M: { - reg = 0x0E; set = 0x31; need = 1; break; -} -case SECAM: { - reg = 0x0E; set = 0x51; need = 1; break; -} -default: - break; -} + } + case NTSC_M: + case PAL_BGHIN: { + reg = 0x0E; + set = 0x01; + need = 1; + break; + } + case NTSC_N_443: + case PAL_60: { + reg = 0x0E; + set = 0x11; + need = 1; + break; + } + case NTSC_443: + case PAL_Nc: { + reg = 0x0E; + set = 0x21; + need = 1; + break; + } + case NTSC_N: + case PAL_M: { + reg = 0x0E; + set = 0x31; + need = 1; + break; + } + case SECAM: { + reg = 0x0E; + set = 0x51; + need = 1; + break; + } + default: + break; + } /*--------------------------------------------------------------------------*/ -if (need) { - ir = read_saa(peasycap->pusb_device, reg); - if (0 > ir) - SAM("ERROR: failed to read SAA register 0x%02X\n", reg); - else - itwas = (unsigned int)ir; - rc = write_saa(peasycap->pusb_device, reg, set); - if (0 != write_saa(peasycap->pusb_device, reg, set)) { - SAM("ERROR: failed to set SAA register " - "0x%02X to 0x%02X for table 42\n", reg, set); - } else { - isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); + if (need) { + ir = read_saa(peasycap->pusb_device, reg); if (0 > ir) - JOM(8, "SAA register 0x%02X changed " - "to 0x%02X\n", reg, isnow); + SAM("ERROR: failed to read SAA register 0x%02X\n", reg); else - JOM(8, "SAA register 0x%02X changed " - "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + itwas = (unsigned int)ir; + rc = write_saa(peasycap->pusb_device, reg, set); + if (0 != write_saa(peasycap->pusb_device, reg, set)) { + SAM("ERROR: failed to set SAA register " + "0x%02X to 0x%02X for table 42\n", reg, set); + } else { + isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); + if (0 > ir) + JOM(8, "SAA register 0x%02X changed " + "to 0x%02X\n", reg, isnow); + else + JOM(8, "SAA register 0x%02X changed " + "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + } } -} /*--------------------------------------------------------------------------*/ /* - * SAA7113H DATASHEET PAGE 41 - */ + * SAA7113H DATASHEET PAGE 41 + */ /*--------------------------------------------------------------------------*/ -reg = 0x08; -ir = read_saa(peasycap->pusb_device, reg); -if (0 > ir) - SAM("ERROR: failed to read SAA register 0x%02X " - "so cannot reset\n", reg); -else { - itwas = (unsigned int)ir; - if (peasycap_standard->mask & 0x0001) - set = itwas | 0x40 ; - else - set = itwas & ~0x40 ; - rc = write_saa(peasycap->pusb_device, reg, set); - if (rc) - SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", - reg, set); + reg = 0x08; + ir = read_saa(peasycap->pusb_device, reg); + if (0 > ir) + SAM("ERROR: failed to read SAA register 0x%02X " + "so cannot reset\n", reg); else { - isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); - if (0 > ir) - JOM(8, "SAA register 0x%02X changed to 0x%02X\n", - reg, isnow); + itwas = (unsigned int)ir; + if (peasycap_standard->mask & 0x0001) + set = itwas | 0x40 ; else - JOM(8, "SAA register 0x%02X changed " - "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + set = itwas & ~0x40 ; + rc = write_saa(peasycap->pusb_device, reg, set); + if (rc) + SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", + reg, set); + else { + isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); + if (0 > ir) + JOM(8, "SAA register 0x%02X changed to 0x%02X\n", + reg, isnow); + else + JOM(8, "SAA register 0x%02X changed " + "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + } } -} /*--------------------------------------------------------------------------*/ /* * SAA7113H DATASHEET PAGE 51, TABLE 57 */ /*---------------------------------------------------------------------------*/ -reg = 0x40; -ir = read_saa(peasycap->pusb_device, reg); -if (0 > ir) - SAM("ERROR: failed to read SAA register 0x%02X " - "so cannot reset\n", reg); -else { - itwas = (unsigned int)ir; - if (peasycap_standard->mask & 0x0001) - set = itwas | 0x80 ; - else - set = itwas & ~0x80 ; - rc = write_saa(peasycap->pusb_device, reg, set); - if (rc) - SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", - reg, set); + reg = 0x40; + ir = read_saa(peasycap->pusb_device, reg); + if (0 > ir) + SAM("ERROR: failed to read SAA register 0x%02X " + "so cannot reset\n", reg); else { - isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); - if (0 > ir) - JOM(8, "SAA register 0x%02X changed to 0x%02X\n", - reg, isnow); + itwas = (unsigned int)ir; + if (peasycap_standard->mask & 0x0001) + set = itwas | 0x80 ; else - JOM(8, "SAA register 0x%02X changed " - "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + set = itwas & ~0x80 ; + rc = write_saa(peasycap->pusb_device, reg, set); + if (rc) + SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", + reg, set); + else { + isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); + if (0 > ir) + JOM(8, "SAA register 0x%02X changed to 0x%02X\n", + reg, isnow); + else + JOM(8, "SAA register 0x%02X changed " + "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + } } -} /*--------------------------------------------------------------------------*/ /* - * SAA7113H DATASHEET PAGE 53, TABLE 66 - */ + * SAA7113H DATASHEET PAGE 53, TABLE 66 + */ /*--------------------------------------------------------------------------*/ -reg = 0x5A; -ir = read_saa(peasycap->pusb_device, reg); -if (0 > ir) - SAM("ERROR: failed to read SAA register 0x%02X but continuing\n", reg); + reg = 0x5A; + ir = read_saa(peasycap->pusb_device, reg); + if (0 > ir) + SAM("ERROR: failed to read SAA register 0x%02X but continuing\n", reg); itwas = (unsigned int)ir; if (peasycap_standard->mask & 0x0001) set = 0x0A ; @@ -300,19 +320,19 @@ if (0 > ir) set = 0x07 ; if (0 != write_saa(peasycap->pusb_device, reg, set)) SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", - reg, set); + reg, set); else { isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); if (0 > ir) JOM(8, "SAA register 0x%02X changed " - "to 0x%02X\n", reg, isnow); + "to 0x%02X\n", reg, isnow); else JOM(8, "SAA register 0x%02X changed " - "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + "from 0x%02X to 0x%02X\n", reg, itwas, isnow); } -if (true == resubmit) - submit_video_urbs(peasycap); -return 0; + if (true == resubmit) + submit_video_urbs(peasycap); + return 0; } /*****************************************************************************/ /*--------------------------------------------------------------------------*/ @@ -340,564 +360,545 @@ return 0; */ /*--------------------------------------------------------------------------*/ int adjust_format(struct easycap *peasycap, - u32 width, u32 height, u32 pixelformat, int field, bool try) + u32 width, u32 height, u32 pixelformat, int field, bool try) { -struct easycap_format *peasycap_format, *peasycap_best_format; -u16 mask; -struct usb_device *p; -int miss, multiplier, best, k; -char bf[5], fo[32], *pc; -u32 uc; -bool resubmit; - -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (0 > peasycap->standard_offset) { - JOM(8, "%i=peasycap->standard_offset\n", peasycap->standard_offset); - return -EBUSY; -} -p = peasycap->pusb_device; -if (NULL == p) { - SAM("ERROR: peaycap->pusb_device is NULL\n"); - return -EFAULT; -} -pc = &bf[0]; -uc = pixelformat; -memcpy((void *)pc, (void *)(&uc), 4); -bf[4] = 0; -mask = 0xFF & easycap_standard[peasycap->standard_offset].mask; -SAM("sought: %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n", - width, height, pc, pixelformat, field, mask); -switch (field) { -case V4L2_FIELD_ANY: { - strcpy(&fo[0], "V4L2_FIELD_ANY "); - break; -} -case V4L2_FIELD_NONE: { - strcpy(&fo[0], "V4L2_FIELD_NONE"); - break; -} -case V4L2_FIELD_TOP: { - strcpy(&fo[0], "V4L2_FIELD_TOP"); - break; -} -case V4L2_FIELD_BOTTOM: { - strcpy(&fo[0], "V4L2_FIELD_BOTTOM"); - break; -} -case V4L2_FIELD_INTERLACED: { - strcpy(&fo[0], "V4L2_FIELD_INTERLACED"); - break; -} -case V4L2_FIELD_SEQ_TB: { - strcpy(&fo[0], "V4L2_FIELD_SEQ_TB"); - break; -} -case V4L2_FIELD_SEQ_BT: { - strcpy(&fo[0], "V4L2_FIELD_SEQ_BT"); - break; -} -case V4L2_FIELD_ALTERNATE: { - strcpy(&fo[0], "V4L2_FIELD_ALTERNATE"); - break; -} -case V4L2_FIELD_INTERLACED_TB: { - strcpy(&fo[0], "V4L2_FIELD_INTERLACED_TB"); - break; -} -case V4L2_FIELD_INTERLACED_BT: { - strcpy(&fo[0], "V4L2_FIELD_INTERLACED_BT"); - break; -} -default: { - strcpy(&fo[0], "V4L2_FIELD_... UNKNOWN "); - break; -} -} -SAM("sought: %s\n", &fo[0]); -if (V4L2_FIELD_ANY == field) { - field = V4L2_FIELD_NONE; - SAM("prefer: V4L2_FIELD_NONE=field, was V4L2_FIELD_ANY\n"); -} -peasycap_best_format = NULL; -peasycap_format = &easycap_format[0]; -while (0 != peasycap_format->v4l2_format.fmt.pix.width) { - JOM(16, ".> %i %i 0x%08X %ix%i\n", - peasycap_format->mask & 0x01, - peasycap_format->v4l2_format.fmt.pix.field, - peasycap_format->v4l2_format.fmt.pix.pixelformat, - peasycap_format->v4l2_format.fmt.pix.width, - peasycap_format->v4l2_format.fmt.pix.height); - - if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && - (peasycap_format->v4l2_format.fmt.pix.field == field) && - (peasycap_format->v4l2_format.fmt.pix.pixelformat == - pixelformat) && - (peasycap_format->v4l2_format.fmt.pix.width == width) && - (peasycap_format->v4l2_format.fmt.pix.height == height)) { + struct easycap_format *peasycap_format, *peasycap_best_format; + u16 mask; + struct usb_device *p; + int miss, multiplier, best, k; + char bf[5], fo[32], *pc; + u32 uc; + bool resubmit; + + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (0 > peasycap->standard_offset) { + JOM(8, "%i=peasycap->standard_offset\n", peasycap->standard_offset); + return -EBUSY; + } + p = peasycap->pusb_device; + if (NULL == p) { + SAM("ERROR: peaycap->pusb_device is NULL\n"); + return -EFAULT; + } + pc = &bf[0]; + uc = pixelformat; + memcpy((void *)pc, (void *)(&uc), 4); + bf[4] = 0; + mask = 0xFF & easycap_standard[peasycap->standard_offset].mask; + SAM("sought: %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n", + width, height, pc, pixelformat, field, mask); + switch (field) { + case V4L2_FIELD_ANY: { + strcpy(&fo[0], "V4L2_FIELD_ANY "); + break; + } + case V4L2_FIELD_NONE: { + strcpy(&fo[0], "V4L2_FIELD_NONE"); + break; + } + case V4L2_FIELD_TOP: { + strcpy(&fo[0], "V4L2_FIELD_TOP"); + break; + } + case V4L2_FIELD_BOTTOM: { + strcpy(&fo[0], "V4L2_FIELD_BOTTOM"); + break; + } + case V4L2_FIELD_INTERLACED: { + strcpy(&fo[0], "V4L2_FIELD_INTERLACED"); + break; + } + case V4L2_FIELD_SEQ_TB: { + strcpy(&fo[0], "V4L2_FIELD_SEQ_TB"); + break; + } + case V4L2_FIELD_SEQ_BT: { + strcpy(&fo[0], "V4L2_FIELD_SEQ_BT"); + break; + } + case V4L2_FIELD_ALTERNATE: { + strcpy(&fo[0], "V4L2_FIELD_ALTERNATE"); + break; + } + case V4L2_FIELD_INTERLACED_TB: { + strcpy(&fo[0], "V4L2_FIELD_INTERLACED_TB"); + break; + } + case V4L2_FIELD_INTERLACED_BT: { + strcpy(&fo[0], "V4L2_FIELD_INTERLACED_BT"); + break; + } + default: { + strcpy(&fo[0], "V4L2_FIELD_... UNKNOWN "); + break; + } + } + SAM("sought: %s\n", &fo[0]); + if (V4L2_FIELD_ANY == field) { + field = V4L2_FIELD_NONE; + SAM("prefer: V4L2_FIELD_NONE=field, was V4L2_FIELD_ANY\n"); + } + peasycap_best_format = NULL; + peasycap_format = &easycap_format[0]; + while (0 != peasycap_format->v4l2_format.fmt.pix.width) { + JOM(16, ".> %i %i 0x%08X %ix%i\n", + peasycap_format->mask & 0x01, + peasycap_format->v4l2_format.fmt.pix.field, + peasycap_format->v4l2_format.fmt.pix.pixelformat, + peasycap_format->v4l2_format.fmt.pix.width, + peasycap_format->v4l2_format.fmt.pix.height); + + if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && + (peasycap_format->v4l2_format.fmt.pix.field == field) && + (peasycap_format->v4l2_format.fmt.pix.pixelformat == pixelformat) && + (peasycap_format->v4l2_format.fmt.pix.width == width) && + (peasycap_format->v4l2_format.fmt.pix.height == height)) { + peasycap_best_format = peasycap_format; break; } - peasycap_format++; -} -if (0 == peasycap_format->v4l2_format.fmt.pix.width) { - SAM("cannot do: %ix%i with standard mask 0x%02X\n", - width, height, mask); - peasycap_format = &easycap_format[0]; best = -1; - while (0 != peasycap_format->v4l2_format.fmt.pix.width) { - if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && - (peasycap_format->v4l2_format.fmt.pix - .field == field) && - (peasycap_format->v4l2_format.fmt.pix - .pixelformat == pixelformat)) { - miss = abs(peasycap_format-> - v4l2_format.fmt.pix.width - width); - if ((best > miss) || (best < 0)) { - best = miss; - peasycap_best_format = peasycap_format; - if (!miss) - break; + peasycap_format++; + } + if (0 == peasycap_format->v4l2_format.fmt.pix.width) { + SAM("cannot do: %ix%i with standard mask 0x%02X\n", + width, height, mask); + peasycap_format = &easycap_format[0]; + best = -1; + while (0 != peasycap_format->v4l2_format.fmt.pix.width) { + if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && + (peasycap_format->v4l2_format.fmt.pix.field == field) && + (peasycap_format->v4l2_format.fmt.pix.pixelformat == pixelformat)) { + + miss = abs(peasycap_format->v4l2_format.fmt.pix.width - width); + if ((best > miss) || (best < 0)) { + best = miss; + peasycap_best_format = peasycap_format; + if (!miss) + break; + } } + peasycap_format++; + } + if (-1 == best) { + SAM("cannot do %ix... with standard mask 0x%02X\n", + width, mask); + SAM("cannot do ...x%i with standard mask 0x%02X\n", + height, mask); + SAM(" %ix%i unmatched\n", width, height); + return peasycap->format_offset; } - peasycap_format++; } - if (-1 == best) { - SAM("cannot do %ix... with standard mask 0x%02X\n", - width, mask); - SAM("cannot do ...x%i with standard mask 0x%02X\n", - height, mask); - SAM(" %ix%i unmatched\n", width, height); - return peasycap->format_offset; + if (NULL == peasycap_best_format) { + SAM("MISTAKE: peasycap_best_format is NULL"); + return -EINVAL; } -} -if (NULL == peasycap_best_format) { - SAM("MISTAKE: peasycap_best_format is NULL"); - return -EINVAL; -} -peasycap_format = peasycap_best_format; + peasycap_format = peasycap_best_format; /*...........................................................................*/ -if (true == try) - return (int)(peasycap_best_format - &easycap_format[0]); + if (try) + return peasycap_best_format - easycap_format; /*...........................................................................*/ -if (false != try) { - SAM("MISTAKE: true==try where is should be false\n"); - return -EINVAL; -} -SAM("actioning: %ix%i %s\n", - peasycap_format->v4l2_format.fmt.pix.width, - peasycap_format->v4l2_format.fmt.pix.height, - &peasycap_format->name[0]); -peasycap->height = peasycap_format->v4l2_format.fmt.pix.height; -peasycap->width = peasycap_format->v4l2_format.fmt.pix.width; -peasycap->pixelformat = peasycap_format->v4l2_format.fmt.pix.pixelformat; -peasycap->format_offset = (int)(peasycap_format - &easycap_format[0]); + if (false != try) { + SAM("MISTAKE: true==try where is should be false\n"); + return -EINVAL; + } + SAM("actioning: %ix%i %s\n", + peasycap_format->v4l2_format.fmt.pix.width, + peasycap_format->v4l2_format.fmt.pix.height, + &peasycap_format->name[0]); + peasycap->height = peasycap_format->v4l2_format.fmt.pix.height; + peasycap->width = peasycap_format->v4l2_format.fmt.pix.width; + peasycap->pixelformat = peasycap_format->v4l2_format.fmt.pix.pixelformat; + peasycap->format_offset = peasycap_format - easycap_format; -for (k = 0; k < INPUT_MANY; k++) { - if (!peasycap->inputset[k].format_offset_ok) { - peasycap->inputset[k].format_offset = - peasycap->format_offset; + for (k = 0; k < INPUT_MANY; k++) { + if (!peasycap->inputset[k].format_offset_ok) { + peasycap->inputset[k].format_offset = + peasycap->format_offset; + } } -} -if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { - peasycap->inputset[peasycap->input].format_offset = - peasycap->format_offset; - peasycap->inputset[peasycap->input].format_offset_ok = 1; -} else - JOM(8, "%i=peasycap->input\n", peasycap->input); - - - -peasycap->bytesperpixel = (0x00E0 & peasycap_format->mask) >> 5 ; -if (0x0100 & peasycap_format->mask) - peasycap->byteswaporder = true; -else - peasycap->byteswaporder = false; -if (0x0200 & peasycap_format->mask) - peasycap->skip = 5; -else - peasycap->skip = 0; -if (0x0800 & peasycap_format->mask) - peasycap->decimatepixel = true; -else - peasycap->decimatepixel = false; -if (0x1000 & peasycap_format->mask) - peasycap->offerfields = true; -else - peasycap->offerfields = false; -if (true == peasycap->decimatepixel) - multiplier = 2; -else - multiplier = 1; -peasycap->videofieldamount = multiplier * peasycap->width * - multiplier * peasycap->height; -peasycap->frame_buffer_used = peasycap->bytesperpixel * - peasycap->width * peasycap->height; -if (peasycap->video_isoc_streaming) { - resubmit = true; - kill_video_urbs(peasycap); -} else - resubmit = false; + if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { + peasycap->inputset[peasycap->input].format_offset = + peasycap->format_offset; + peasycap->inputset[peasycap->input].format_offset_ok = 1; + } else + JOM(8, "%i=peasycap->input\n", peasycap->input); + + + + peasycap->bytesperpixel = (0x00E0 & peasycap_format->mask) >> 5 ; + if (0x0100 & peasycap_format->mask) + peasycap->byteswaporder = true; + else + peasycap->byteswaporder = false; + if (0x0200 & peasycap_format->mask) + peasycap->skip = 5; + else + peasycap->skip = 0; + if (0x0800 & peasycap_format->mask) + peasycap->decimatepixel = true; + else + peasycap->decimatepixel = false; + if (0x1000 & peasycap_format->mask) + peasycap->offerfields = true; + else + peasycap->offerfields = false; + if (true == peasycap->decimatepixel) + multiplier = 2; + else + multiplier = 1; + peasycap->videofieldamount = + multiplier * peasycap->width * multiplier * peasycap->height; + peasycap->frame_buffer_used = + peasycap->bytesperpixel * peasycap->width * peasycap->height; + if (peasycap->video_isoc_streaming) { + resubmit = true; + kill_video_urbs(peasycap); + } else + resubmit = false; /*---------------------------------------------------------------------------*/ /* - * PAL - */ + * PAL + */ /*---------------------------------------------------------------------------*/ -if (0 == (0x01 & peasycap_format->mask)) { - if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && - (576 == - peasycap_format->v4l2_format.fmt.pix.height)) || - ((360 == - peasycap_format->v4l2_format.fmt.pix.width) && - (288 == - peasycap_format->v4l2_format.fmt.pix.height))) { - if (0 != set_resolution(p, 0x0000, 0x0001, 0x05A0, 0x0121)) { - SAM("ERROR: set_resolution() failed\n"); - return -EINVAL; - } - } else if ((704 == peasycap_format->v4l2_format.fmt.pix.width) && - (576 == peasycap_format->v4l2_format.fmt.pix.height)) { - if (0 != set_resolution(p, 0x0004, 0x0001, 0x0584, 0x0121)) { - SAM("ERROR: set_resolution() failed\n"); - return -EINVAL; - } - } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && - (480 == - peasycap_format->v4l2_format.fmt.pix.height)) || - ((320 == - peasycap_format->v4l2_format.fmt.pix.width) && - (240 == - peasycap_format->v4l2_format.fmt.pix.height))) { - if (0 != set_resolution(p, 0x0014, 0x0020, 0x0514, 0x0110)) { - SAM("ERROR: set_resolution() failed\n"); + if (0 == (0x01 & peasycap_format->mask)) { + if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && + (576 == peasycap_format->v4l2_format.fmt.pix.height)) || + ((360 == peasycap_format->v4l2_format.fmt.pix.width) && + (288 == peasycap_format->v4l2_format.fmt.pix.height))) { + if (set_resolution(p, 0x0000, 0x0001, 0x05A0, 0x0121)) { + SAM("ERROR: set_resolution() failed\n"); + return -EINVAL; + } + } else if ((704 == peasycap_format->v4l2_format.fmt.pix.width) && + (576 == peasycap_format->v4l2_format.fmt.pix.height)) { + if (set_resolution(p, 0x0004, 0x0001, 0x0584, 0x0121)) { + SAM("ERROR: set_resolution() failed\n"); + return -EINVAL; + } + } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && + (480 == peasycap_format->v4l2_format.fmt.pix.height)) || + ((320 == peasycap_format->v4l2_format.fmt.pix.width) && + (240 == peasycap_format->v4l2_format.fmt.pix.height))) { + if (set_resolution(p, 0x0014, 0x0020, 0x0514, 0x0110)) { + SAM("ERROR: set_resolution() failed\n"); + return -EINVAL; + } + } else { + SAM("MISTAKE: bad format, cannot set resolution\n"); return -EINVAL; } - } else { - SAM("MISTAKE: bad format, cannot set resolution\n"); - return -EINVAL; - } /*---------------------------------------------------------------------------*/ /* * NTSC */ /*---------------------------------------------------------------------------*/ -} else { - if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && - (480 == - peasycap_format->v4l2_format.fmt.pix.height)) || - ((360 == - peasycap_format->v4l2_format.fmt.pix.width) && - (240 == - peasycap_format->v4l2_format.fmt.pix.height))) { - if (0 != set_resolution(p, 0x0000, 0x0003, 0x05A0, 0x00F3)) { - SAM("ERROR: set_resolution() failed\n"); - return -EINVAL; - } - } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && - (480 == - peasycap_format->v4l2_format.fmt.pix.height)) || - ((320 == - peasycap_format->v4l2_format.fmt.pix.width) && - (240 == - peasycap_format->v4l2_format.fmt.pix.height))) { - if (0 != set_resolution(p, 0x0014, 0x0003, 0x0514, 0x00F3)) { - SAM("ERROR: set_resolution() failed\n"); + } else { + if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && + (480 == peasycap_format->v4l2_format.fmt.pix.height)) || + ((360 == peasycap_format->v4l2_format.fmt.pix.width) && + (240 == peasycap_format->v4l2_format.fmt.pix.height))) { + if (set_resolution(p, 0x0000, 0x0003, 0x05A0, 0x00F3)) { + SAM("ERROR: set_resolution() failed\n"); + return -EINVAL; + } + } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && + (480 == peasycap_format->v4l2_format.fmt.pix.height)) || + ((320 == peasycap_format->v4l2_format.fmt.pix.width) && + (240 == peasycap_format->v4l2_format.fmt.pix.height))) { + if (set_resolution(p, 0x0014, 0x0003, 0x0514, 0x00F3)) { + SAM("ERROR: set_resolution() failed\n"); + return -EINVAL; + } + } else { + SAM("MISTAKE: bad format, cannot set resolution\n"); return -EINVAL; } - } else { - SAM("MISTAKE: bad format, cannot set resolution\n"); - return -EINVAL; } -} /*---------------------------------------------------------------------------*/ -if (true == resubmit) - submit_video_urbs(peasycap); -return (int)(peasycap_best_format - &easycap_format[0]); + if (resubmit) + submit_video_urbs(peasycap); + + return peasycap_best_format - easycap_format; } /*****************************************************************************/ int adjust_brightness(struct easycap *peasycap, int value) { -unsigned int mood; -int i1, k; + unsigned int mood; + int i1, k; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -i1 = 0; -while (0xFFFFFFFF != easycap_control[i1].id) { - if (V4L2_CID_BRIGHTNESS == easycap_control[i1].id) { - if ((easycap_control[i1].minimum > value) || - (easycap_control[i1].maximum < value)) - value = easycap_control[i1].default_value; - - if ((easycap_control[i1].minimum <= peasycap->brightness) && - (easycap_control[i1].maximum >= - peasycap->brightness)) { - if (peasycap->brightness == value) { - SAM("unchanged brightness at 0x%02X\n", - value); + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } + i1 = 0; + while (0xFFFFFFFF != easycap_control[i1].id) { + if (V4L2_CID_BRIGHTNESS == easycap_control[i1].id) { + if ((easycap_control[i1].minimum > value) || + (easycap_control[i1].maximum < value)) + value = easycap_control[i1].default_value; + + if ((easycap_control[i1].minimum <= peasycap->brightness) && + (easycap_control[i1].maximum >= peasycap->brightness)) { + if (peasycap->brightness == value) { + SAM("unchanged brightness at 0x%02X\n", + value); + return 0; + } + } + peasycap->brightness = value; + for (k = 0; k < INPUT_MANY; k++) { + if (!peasycap->inputset[k].brightness_ok) + peasycap->inputset[k].brightness = + peasycap->brightness; + } + if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { + peasycap->inputset[peasycap->input].brightness = + peasycap->brightness; + peasycap->inputset[peasycap->input].brightness_ok = 1; + } else + JOM(8, "%i=peasycap->input\n", peasycap->input); + mood = 0x00FF & (unsigned int)peasycap->brightness; + if (!write_saa(peasycap->pusb_device, 0x0A, mood)) { + SAM("adjusting brightness to 0x%02X\n", mood); return 0; + } else { + SAM("WARNING: failed to adjust brightness " + "to 0x%02X\n", mood); + return -ENOENT; } + break; } - peasycap->brightness = value; - for (k = 0; k < INPUT_MANY; k++) { - if (!peasycap->inputset[k].brightness_ok) - peasycap->inputset[k].brightness = - peasycap->brightness; - } - if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { - peasycap->inputset[peasycap->input].brightness = - peasycap->brightness; - peasycap->inputset[peasycap->input].brightness_ok = 1; - } else - JOM(8, "%i=peasycap->input\n", peasycap->input); - mood = 0x00FF & (unsigned int)peasycap->brightness; - if (!write_saa(peasycap->pusb_device, 0x0A, mood)) { - SAM("adjusting brightness to 0x%02X\n", mood); - return 0; - } else { - SAM("WARNING: failed to adjust brightness " - "to 0x%02X\n", mood); - return -ENOENT; - } - break; + i1++; } - i1++; -} -SAM("WARNING: failed to adjust brightness: control not found\n"); -return -ENOENT; + SAM("WARNING: failed to adjust brightness: control not found\n"); + return -ENOENT; } /*****************************************************************************/ int adjust_contrast(struct easycap *peasycap, int value) { -unsigned int mood; -int i1, k; - -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -i1 = 0; -while (0xFFFFFFFF != easycap_control[i1].id) { - if (V4L2_CID_CONTRAST == easycap_control[i1].id) { - if ((easycap_control[i1].minimum > value) || - (easycap_control[i1].maximum < value)) - value = easycap_control[i1].default_value; - - + unsigned int mood; + int i1, k; - if ((easycap_control[i1].minimum <= peasycap->contrast) && - (easycap_control[i1].maximum >= - peasycap->contrast)) { - if (peasycap->contrast == value) { - SAM("unchanged contrast at 0x%02X\n", value); - return 0; - } - } - peasycap->contrast = value; - for (k = 0; k < INPUT_MANY; k++) { - if (!peasycap->inputset[k].contrast_ok) { - peasycap->inputset[k].contrast = - peasycap->contrast; - } - } - if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { - peasycap->inputset[peasycap->input].contrast = - peasycap->contrast; - peasycap->inputset[peasycap->input].contrast_ok = 1; - } else - JOM(8, "%i=peasycap->input\n", peasycap->input); - mood = 0x00FF & (unsigned int) (peasycap->contrast - 128); - if (!write_saa(peasycap->pusb_device, 0x0B, mood)) { - SAM("adjusting contrast to 0x%02X\n", mood); - return 0; - } else { - SAM("WARNING: failed to adjust contrast to " - "0x%02X\n", mood); - return -ENOENT; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } + i1 = 0; + while (0xFFFFFFFF != easycap_control[i1].id) { + if (V4L2_CID_CONTRAST == easycap_control[i1].id) { + if ((easycap_control[i1].minimum > value) || + (easycap_control[i1].maximum < value)) + value = easycap_control[i1].default_value; + + + if ((easycap_control[i1].minimum <= peasycap->contrast) && + (easycap_control[i1].maximum >= peasycap->contrast)) { + if (peasycap->contrast == value) { + SAM("unchanged contrast at 0x%02X\n", value); + return 0; + } + } + peasycap->contrast = value; + for (k = 0; k < INPUT_MANY; k++) { + if (!peasycap->inputset[k].contrast_ok) + peasycap->inputset[k].contrast = peasycap->contrast; + } + + if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { + peasycap->inputset[peasycap->input].contrast = + peasycap->contrast; + peasycap->inputset[peasycap->input].contrast_ok = 1; + } else + JOM(8, "%i=peasycap->input\n", peasycap->input); + + mood = 0x00FF & (unsigned int) (peasycap->contrast - 128); + if (!write_saa(peasycap->pusb_device, 0x0B, mood)) { + SAM("adjusting contrast to 0x%02X\n", mood); + return 0; + } else { + SAM("WARNING: failed to adjust contrast to " + "0x%02X\n", mood); + return -ENOENT; + } + break; } - break; + i1++; } - i1++; -} -SAM("WARNING: failed to adjust contrast: control not found\n"); -return -ENOENT; + SAM("WARNING: failed to adjust contrast: control not found\n"); + return -ENOENT; } /*****************************************************************************/ int adjust_saturation(struct easycap *peasycap, int value) { -unsigned int mood; -int i1, k; + unsigned int mood; + int i1, k; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -i1 = 0; -while (0xFFFFFFFF != easycap_control[i1].id) { - if (V4L2_CID_SATURATION == easycap_control[i1].id) { - if ((easycap_control[i1].minimum > value) || - (easycap_control[i1].maximum < value)) - value = easycap_control[i1].default_value; - - - if ((easycap_control[i1].minimum <= peasycap->saturation) && - (easycap_control[i1].maximum >= - peasycap->saturation)) { - if (peasycap->saturation == value) { - SAM("unchanged saturation at 0x%02X\n", - value); - return 0; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } + i1 = 0; + while (0xFFFFFFFF != easycap_control[i1].id) { + if (V4L2_CID_SATURATION == easycap_control[i1].id) { + if ((easycap_control[i1].minimum > value) || + (easycap_control[i1].maximum < value)) + value = easycap_control[i1].default_value; + + + if ((easycap_control[i1].minimum <= peasycap->saturation) && + (easycap_control[i1].maximum >= peasycap->saturation)) { + if (peasycap->saturation == value) { + SAM("unchanged saturation at 0x%02X\n", + value); + return 0; + } } - } - peasycap->saturation = value; - for (k = 0; k < INPUT_MANY; k++) { - if (!peasycap->inputset[k].saturation_ok) { - peasycap->inputset[k].saturation = - peasycap->saturation; + peasycap->saturation = value; + for (k = 0; k < INPUT_MANY; k++) { + if (!peasycap->inputset[k].saturation_ok) + peasycap->inputset[k].saturation = + peasycap->saturation; } + if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { + peasycap->inputset[peasycap->input].saturation = + peasycap->saturation; + peasycap->inputset[peasycap->input].saturation_ok = 1; + } else + JOM(8, "%i=peasycap->input\n", peasycap->input); + mood = 0x00FF & (unsigned int) (peasycap->saturation - 128); + if (!write_saa(peasycap->pusb_device, 0x0C, mood)) { + SAM("adjusting saturation to 0x%02X\n", mood); + return 0; + } else { + SAM("WARNING: failed to adjust saturation to " + "0x%02X\n", mood); + return -ENOENT; + } + break; } - if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { - peasycap->inputset[peasycap->input].saturation = - peasycap->saturation; - peasycap->inputset[peasycap->input].saturation_ok = 1; - } else - JOM(8, "%i=peasycap->input\n", peasycap->input); - mood = 0x00FF & (unsigned int) (peasycap->saturation - 128); - if (!write_saa(peasycap->pusb_device, 0x0C, mood)) { - SAM("adjusting saturation to 0x%02X\n", mood); - return 0; - } else { - SAM("WARNING: failed to adjust saturation to " - "0x%02X\n", mood); - return -ENOENT; - } - break; + i1++; } - i1++; -} -SAM("WARNING: failed to adjust saturation: control not found\n"); -return -ENOENT; + SAM("WARNING: failed to adjust saturation: control not found\n"); + return -ENOENT; } /*****************************************************************************/ int adjust_hue(struct easycap *peasycap, int value) { -unsigned int mood; -int i1, i2, k; + unsigned int mood; + int i1, i2, k; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -i1 = 0; -while (0xFFFFFFFF != easycap_control[i1].id) { - if (V4L2_CID_HUE == easycap_control[i1].id) { - if ((easycap_control[i1].minimum > value) || - (easycap_control[i1].maximum < value)) - value = easycap_control[i1].default_value; - - if ((easycap_control[i1].minimum <= peasycap->hue) && - (easycap_control[i1].maximum >= - peasycap->hue)) { - if (peasycap->hue == value) { - SAM("unchanged hue at 0x%02X\n", value); + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } + i1 = 0; + while (0xFFFFFFFF != easycap_control[i1].id) { + if (V4L2_CID_HUE == easycap_control[i1].id) { + if ((easycap_control[i1].minimum > value) || + (easycap_control[i1].maximum < value)) + value = easycap_control[i1].default_value; + + if ((easycap_control[i1].minimum <= peasycap->hue) && + (easycap_control[i1].maximum >= peasycap->hue)) { + if (peasycap->hue == value) { + SAM("unchanged hue at 0x%02X\n", value); + return 0; + } + } + peasycap->hue = value; + for (k = 0; k < INPUT_MANY; k++) { + if (!peasycap->inputset[k].hue_ok) + peasycap->inputset[k].hue = peasycap->hue; + } + if (0 <= peasycap->input && INPUT_MANY > peasycap->input) { + peasycap->inputset[peasycap->input].hue = peasycap->hue; + peasycap->inputset[peasycap->input].hue_ok = 1; + } else + JOM(8, "%i=peasycap->input\n", peasycap->input); + i2 = peasycap->hue - 128; + mood = 0x00FF & ((int) i2); + if (!write_saa(peasycap->pusb_device, 0x0D, mood)) { + SAM("adjusting hue to 0x%02X\n", mood); return 0; + } else { + SAM("WARNING: failed to adjust hue to 0x%02X\n", mood); + return -ENOENT; } + break; } - peasycap->hue = value; - for (k = 0; k < INPUT_MANY; k++) { - if (!peasycap->inputset[k].hue_ok) - peasycap->inputset[k].hue = peasycap->hue; - } - if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { - peasycap->inputset[peasycap->input].hue = - peasycap->hue; - peasycap->inputset[peasycap->input].hue_ok = 1; - } else - JOM(8, "%i=peasycap->input\n", peasycap->input); - i2 = peasycap->hue - 128; - mood = 0x00FF & ((int) i2); - if (!write_saa(peasycap->pusb_device, 0x0D, mood)) { - SAM("adjusting hue to 0x%02X\n", mood); - return 0; - } else { - SAM("WARNING: failed to adjust hue to 0x%02X\n", mood); - return -ENOENT; - } - break; + i1++; } - i1++; -} -SAM("WARNING: failed to adjust hue: control not found\n"); -return -ENOENT; + SAM("WARNING: failed to adjust hue: control not found\n"); + return -ENOENT; } /*****************************************************************************/ int adjust_volume(struct easycap *peasycap, int value) { -s8 mood; -int i1; + s8 mood; + int i1; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -i1 = 0; -while (0xFFFFFFFF != easycap_control[i1].id) { - if (V4L2_CID_AUDIO_VOLUME == easycap_control[i1].id) { - if ((easycap_control[i1].minimum > value) || - (easycap_control[i1].maximum < value)) - value = easycap_control[i1].default_value; - if ((easycap_control[i1].minimum <= peasycap->volume) && - (easycap_control[i1].maximum >= - peasycap->volume)) { - if (peasycap->volume == value) { - SAM("unchanged volume at 0x%02X\n", value); + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } + i1 = 0; + while (0xFFFFFFFF != easycap_control[i1].id) { + if (V4L2_CID_AUDIO_VOLUME == easycap_control[i1].id) { + if ((easycap_control[i1].minimum > value) || + (easycap_control[i1].maximum < value)) + value = easycap_control[i1].default_value; + + if ((easycap_control[i1].minimum <= peasycap->volume) && + (easycap_control[i1].maximum >= peasycap->volume)) { + if (peasycap->volume == value) { + SAM("unchanged volume at 0x%02X\n", value); + return 0; + } + } + peasycap->volume = value; + mood = (16 > peasycap->volume) ? 16 : + ((31 < peasycap->volume) ? 31 : + (s8) peasycap->volume); + if (!audio_gainset(peasycap->pusb_device, mood)) { + SAM("adjusting volume to 0x%02X\n", mood); return 0; + } else { + SAM("WARNING: failed to adjust volume to " + "0x%2X\n", mood); + return -ENOENT; } + break; } - peasycap->volume = value; - mood = (16 > peasycap->volume) ? 16 : - ((31 < peasycap->volume) ? 31 : - (s8) peasycap->volume); - if (!audio_gainset(peasycap->pusb_device, mood)) { - SAM("adjusting volume to 0x%02X\n", mood); - return 0; - } else { - SAM("WARNING: failed to adjust volume to " - "0x%2X\n", mood); - return -ENOENT; - } - break; + i1++; } -i1++; -} -SAM("WARNING: failed to adjust volume: control not found\n"); -return -ENOENT; + SAM("WARNING: failed to adjust volume: control not found\n"); + return -ENOENT; } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ @@ -913,1550 +914,1566 @@ return -ENOENT; /*---------------------------------------------------------------------------*/ static int adjust_mute(struct easycap *peasycap, int value) { -int i1; + int i1; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -i1 = 0; -while (0xFFFFFFFF != easycap_control[i1].id) { - if (V4L2_CID_AUDIO_MUTE == easycap_control[i1].id) { - peasycap->mute = value; - switch (peasycap->mute) { - case 1: { - peasycap->audio_idle = 1; - peasycap->timeval0.tv_sec = 0; - SAM("adjusting mute: %i=peasycap->audio_idle\n", - peasycap->audio_idle); - return 0; - } - default: { - peasycap->audio_idle = 0; - SAM("adjusting mute: %i=peasycap->audio_idle\n", - peasycap->audio_idle); - return 0; - } + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } + i1 = 0; + while (0xFFFFFFFF != easycap_control[i1].id) { + if (V4L2_CID_AUDIO_MUTE == easycap_control[i1].id) { + peasycap->mute = value; + switch (peasycap->mute) { + case 1: { + peasycap->audio_idle = 1; + peasycap->timeval0.tv_sec = 0; + SAM("adjusting mute: %i=peasycap->audio_idle\n", + peasycap->audio_idle); + return 0; + } + default: { + peasycap->audio_idle = 0; + SAM("adjusting mute: %i=peasycap->audio_idle\n", + peasycap->audio_idle); + return 0; + } + } + break; } - break; + i1++; } - i1++; -} -SAM("WARNING: failed to adjust mute: control not found\n"); -return -ENOENT; + SAM("WARNING: failed to adjust mute: control not found\n"); + return -ENOENT; } /*---------------------------------------------------------------------------*/ long easycap_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { -struct easycap *peasycap; -struct usb_device *p; -int kd; + struct easycap *peasycap; + struct usb_device *p; + int kd; -if (NULL == file) { - SAY("ERROR: file is NULL\n"); - return -ERESTARTSYS; -} -peasycap = file->private_data; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -1; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; -} -p = peasycap->pusb_device; -if (NULL == p) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -kd = isdongle(peasycap); -if (0 <= kd && DONGLE_MANY > kd) { - if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { - SAY("ERROR: cannot lock " - "easycapdc60_dongle[%i].mutex_video\n", kd); - return -ERESTARTSYS; - } - JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd); -/*---------------------------------------------------------------------------*/ -/* - * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap, - * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. - * IF NECESSARY, BAIL OUT. -*/ -/*---------------------------------------------------------------------------*/ - if (kd != isdongle(peasycap)) - return -ERESTARTSYS; if (NULL == file) { SAY("ERROR: file is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; } peasycap = file->private_data; if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -ERESTARTSYS; + return -1; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { SAY("ERROR: bad peasycap\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } p = peasycap->pusb_device; - if (NULL == peasycap->pusb_device) { + if (NULL == p) { SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -ERESTARTSYS; + return -EFAULT; } -} else { + kd = isdongle(peasycap); + if (0 <= kd && DONGLE_MANY > kd) { + if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { + SAY("ERROR: cannot lock " + "easycapdc60_dongle[%i].mutex_video\n", kd); + return -ERESTARTSYS; + } + JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd); +/*---------------------------------------------------------------------------*/ +/* + * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap, + * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. + * IF NECESSARY, BAIL OUT. + */ +/*---------------------------------------------------------------------------*/ + if (kd != isdongle(peasycap)) + return -ERESTARTSYS; + if (NULL == file) { + SAY("ERROR: file is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ERESTARTSYS; + } + peasycap = file->private_data; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ERESTARTSYS; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + p = peasycap->pusb_device; + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ERESTARTSYS; + } + } else { /*---------------------------------------------------------------------------*/ /* * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT. -*/ + */ /*---------------------------------------------------------------------------*/ - return -ERESTARTSYS; -} + return -ERESTARTSYS; + } /*---------------------------------------------------------------------------*/ -switch (cmd) { -case VIDIOC_QUERYCAP: { - struct v4l2_capability v4l2_capability; - char version[16], *p1, *p2; - int i, rc, k[3]; - long lng; + switch (cmd) { + case VIDIOC_QUERYCAP: { + struct v4l2_capability v4l2_capability; + char version[16], *p1, *p2; + int i, rc, k[3]; + long lng; - JOM(8, "VIDIOC_QUERYCAP\n"); + JOM(8, "VIDIOC_QUERYCAP\n"); - if (16 <= strlen(EASYCAP_DRIVER_VERSION)) { - SAM("ERROR: bad driver version string\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; - } - strcpy(&version[0], EASYCAP_DRIVER_VERSION); - for (i = 0; i < 3; i++) - k[i] = 0; - p2 = &version[0]; i = 0; - while (*p2) { - p1 = p2; - while (*p2 && ('.' != *p2)) - p2++; - if (*p2) - *p2++ = 0; - if (3 > i) { - rc = (int) strict_strtol(p1, 10, &lng); - if (rc) { - SAM("ERROR: %i=strict_strtol(%s,.,,)\n", - rc, p1); - mutex_unlock(&easycapdc60_dongle[kd]. - mutex_video); - return -EINVAL; + if (16 <= strlen(EASYCAP_DRIVER_VERSION)) { + SAM("ERROR: bad driver version string\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + strcpy(&version[0], EASYCAP_DRIVER_VERSION); + for (i = 0; i < 3; i++) + k[i] = 0; + p2 = &version[0]; + i = 0; + while (*p2) { + p1 = p2; + while (*p2 && ('.' != *p2)) + p2++; + if (*p2) + *p2++ = 0; + if (3 > i) { + rc = (int) strict_strtol(p1, 10, &lng); + if (rc) { + SAM("ERROR: %i=strict_strtol(%s,.,,)\n", + rc, p1); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + k[i] = (int)lng; } - k[i] = (int)lng; + i++; } - i++; - } - memset(&v4l2_capability, 0, sizeof(struct v4l2_capability)); - strlcpy(&v4l2_capability.driver[0], "easycap", - sizeof(v4l2_capability.driver)); + memset(&v4l2_capability, 0, sizeof(struct v4l2_capability)); + strlcpy(&v4l2_capability.driver[0], + "easycap", sizeof(v4l2_capability.driver)); - v4l2_capability.capabilities = - V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | - V4L2_CAP_AUDIO | V4L2_CAP_READWRITE; + v4l2_capability.capabilities = V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_STREAMING | + V4L2_CAP_AUDIO | + V4L2_CAP_READWRITE; - v4l2_capability.version = KERNEL_VERSION(k[0], k[1], k[2]); - JOM(8, "v4l2_capability.version=(%i,%i,%i)\n", k[0], k[1], k[2]); + v4l2_capability.version = KERNEL_VERSION(k[0], k[1], k[2]); + JOM(8, "v4l2_capability.version=(%i,%i,%i)\n", k[0], k[1], k[2]); - strlcpy(&v4l2_capability.card[0], "EasyCAP DC60", - sizeof(v4l2_capability.card)); + strlcpy(&v4l2_capability.card[0], + "EasyCAP DC60", sizeof(v4l2_capability.card)); - if (usb_make_path(peasycap->pusb_device, &v4l2_capability.bus_info[0], + if (usb_make_path(peasycap->pusb_device, + &v4l2_capability.bus_info[0], sizeof(v4l2_capability.bus_info)) < 0) { - strlcpy(&v4l2_capability.bus_info[0], "EasyCAP bus_info", - sizeof(v4l2_capability.bus_info)); - JOM(8, "%s=v4l2_capability.bus_info\n", - &v4l2_capability.bus_info[0]); - } - if (0 != copy_to_user((void __user *)arg, &v4l2_capability, - sizeof(struct v4l2_capability))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; + + strlcpy(&v4l2_capability.bus_info[0], "EasyCAP bus_info", + sizeof(v4l2_capability.bus_info)); + JOM(8, "%s=v4l2_capability.bus_info\n", + &v4l2_capability.bus_info[0]); + } + if (copy_to_user((void __user *)arg, &v4l2_capability, + sizeof(struct v4l2_capability))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_ENUMINPUT: { - struct v4l2_input v4l2_input; - u32 index; + case VIDIOC_ENUMINPUT: { + struct v4l2_input v4l2_input; + u32 index; - JOM(8, "VIDIOC_ENUMINPUT\n"); + JOM(8, "VIDIOC_ENUMINPUT\n"); - if (0 != copy_from_user(&v4l2_input, (void __user *)arg, + if (copy_from_user(&v4l2_input, (void __user *)arg, sizeof(struct v4l2_input))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - index = v4l2_input.index; - memset(&v4l2_input, 0, sizeof(struct v4l2_input)); - - switch (index) { - case 0: { - v4l2_input.index = index; - strcpy(&v4l2_input.name[0], "CVBS0"); - v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; - v4l2_input.audioset = 0x01; - v4l2_input.tuner = 0; - v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | - V4L2_STD_NTSC ; - v4l2_input.status = 0; - JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); - break; - } - case 1: { - v4l2_input.index = index; - strcpy(&v4l2_input.name[0], "CVBS1"); - v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; - v4l2_input.audioset = 0x01; - v4l2_input.tuner = 0; - v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | - V4L2_STD_NTSC ; - v4l2_input.status = 0; - JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); - break; - } - case 2: { - v4l2_input.index = index; - strcpy(&v4l2_input.name[0], "CVBS2"); - v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; - v4l2_input.audioset = 0x01; - v4l2_input.tuner = 0; - v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | - V4L2_STD_NTSC ; - v4l2_input.status = 0; - JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); - break; - } - case 3: { - v4l2_input.index = index; - strcpy(&v4l2_input.name[0], "CVBS3"); - v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; - v4l2_input.audioset = 0x01; - v4l2_input.tuner = 0; - v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | - V4L2_STD_NTSC ; - v4l2_input.status = 0; - JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); - break; - } - case 4: { - v4l2_input.index = index; - strcpy(&v4l2_input.name[0], "CVBS4"); - v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; - v4l2_input.audioset = 0x01; - v4l2_input.tuner = 0; - v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | - V4L2_STD_NTSC ; - v4l2_input.status = 0; - JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); - break; - } - case 5: { - v4l2_input.index = index; - strcpy(&v4l2_input.name[0], "S-VIDEO"); - v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; - v4l2_input.audioset = 0x01; - v4l2_input.tuner = 0; - v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | - V4L2_STD_NTSC ; - v4l2_input.status = 0; - JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); - break; - } - default: { - JOM(8, "%i=index: exhausts inputs\n", index); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; - } - } + index = v4l2_input.index; + memset(&v4l2_input, 0, sizeof(struct v4l2_input)); - if (0 != copy_to_user((void __user *)arg, &v4l2_input, - sizeof(struct v4l2_input))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; + switch (index) { + case 0: { + v4l2_input.index = index; + strcpy(&v4l2_input.name[0], "CVBS0"); + v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; + v4l2_input.audioset = 0x01; + v4l2_input.tuner = 0; + v4l2_input.std = V4L2_STD_PAL | + V4L2_STD_SECAM | + V4L2_STD_NTSC ; + v4l2_input.status = 0; + JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); + break; + } + case 1: { + v4l2_input.index = index; + strcpy(&v4l2_input.name[0], "CVBS1"); + v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; + v4l2_input.audioset = 0x01; + v4l2_input.tuner = 0; + v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | + V4L2_STD_NTSC; + v4l2_input.status = 0; + JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); + break; + } + case 2: { + v4l2_input.index = index; + strcpy(&v4l2_input.name[0], "CVBS2"); + v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; + v4l2_input.audioset = 0x01; + v4l2_input.tuner = 0; + v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | + V4L2_STD_NTSC ; + v4l2_input.status = 0; + JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); + break; + } + case 3: { + v4l2_input.index = index; + strcpy(&v4l2_input.name[0], "CVBS3"); + v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; + v4l2_input.audioset = 0x01; + v4l2_input.tuner = 0; + v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | + V4L2_STD_NTSC ; + v4l2_input.status = 0; + JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); + break; + } + case 4: { + v4l2_input.index = index; + strcpy(&v4l2_input.name[0], "CVBS4"); + v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; + v4l2_input.audioset = 0x01; + v4l2_input.tuner = 0; + v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | + V4L2_STD_NTSC ; + v4l2_input.status = 0; + JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); + break; + } + case 5: { + v4l2_input.index = index; + strcpy(&v4l2_input.name[0], "S-VIDEO"); + v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; + v4l2_input.audioset = 0x01; + v4l2_input.tuner = 0; + v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | + V4L2_STD_NTSC ; + v4l2_input.status = 0; + JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); + break; + } + default: { + JOM(8, "%i=index: exhausts inputs\n", index); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + } + + if (copy_to_user((void __user *)arg, &v4l2_input, + sizeof(struct v4l2_input))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_G_INPUT: { - u32 index; + case VIDIOC_G_INPUT: { + u32 index; - JOM(8, "VIDIOC_G_INPUT\n"); - index = (u32)peasycap->input; - JOM(8, "user is told: %i\n", index); - if (0 != copy_to_user((void __user *)arg, &index, sizeof(u32))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; + JOM(8, "VIDIOC_G_INPUT\n"); + index = (u32)peasycap->input; + JOM(8, "user is told: %i\n", index); + if (copy_to_user((void __user *)arg, &index, sizeof(u32))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_S_INPUT: + case VIDIOC_S_INPUT: { - u32 index; - int rc; + u32 index; + int rc; - JOM(8, "VIDIOC_S_INPUT\n"); + JOM(8, "VIDIOC_S_INPUT\n"); - if (0 != copy_from_user(&index, (void __user *)arg, sizeof(u32))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + if (0 != copy_from_user(&index, (void __user *)arg, sizeof(u32))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + + JOM(8, "user requests input %i\n", index); + + if ((int)index == peasycap->input) { + SAM("requested input already in effect\n"); + break; + } - JOM(8, "user requests input %i\n", index); + if ((0 > index) || (INPUT_MANY <= index)) { + JOM(8, "ERROR: bad requested input: %i\n", index); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } - if ((int)index == peasycap->input) { - SAM("requested input already in effect\n"); + rc = newinput(peasycap, (int)index); + if (0 == rc) { + JOM(8, "newinput(.,%i) OK\n", (int)index); + } else { + SAM("ERROR: newinput(.,%i) returned %i\n", (int)index, rc); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } break; } - - if ((0 > index) || (INPUT_MANY <= index)) { - JOM(8, "ERROR: bad requested input: %i\n", index); +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + case VIDIOC_ENUMAUDIO: { + JOM(8, "VIDIOC_ENUMAUDIO\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } - - rc = newinput(peasycap, (int)index); - if (0 == rc) { - JOM(8, "newinput(.,%i) OK\n", (int)index); - } else { - SAM("ERROR: newinput(.,%i) returned %i\n", (int)index, rc); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_ENUMAUDIO: { - JOM(8, "VIDIOC_ENUMAUDIO\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_ENUMAUDOUT: { - struct v4l2_audioout v4l2_audioout; + case VIDIOC_ENUMAUDOUT: { + struct v4l2_audioout v4l2_audioout; - JOM(8, "VIDIOC_ENUMAUDOUT\n"); + JOM(8, "VIDIOC_ENUMAUDOUT\n"); - if (0 != copy_from_user(&v4l2_audioout, (void __user *)arg, + if (copy_from_user(&v4l2_audioout, (void __user *)arg, sizeof(struct v4l2_audioout))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - if (0 != v4l2_audioout.index) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; - } - memset(&v4l2_audioout, 0, sizeof(struct v4l2_audioout)); - v4l2_audioout.index = 0; - strcpy(&v4l2_audioout.name[0], "Soundtrack"); + if (0 != v4l2_audioout.index) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + memset(&v4l2_audioout, 0, sizeof(struct v4l2_audioout)); + v4l2_audioout.index = 0; + strcpy(&v4l2_audioout.name[0], "Soundtrack"); - if (0 != copy_to_user((void __user *)arg, &v4l2_audioout, - sizeof(struct v4l2_audioout))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; + if (copy_to_user((void __user *)arg, &v4l2_audioout, + sizeof(struct v4l2_audioout))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_QUERYCTRL: { - int i1; - struct v4l2_queryctrl v4l2_queryctrl; + case VIDIOC_QUERYCTRL: { + int i1; + struct v4l2_queryctrl v4l2_queryctrl; - JOM(8, "VIDIOC_QUERYCTRL\n"); + JOM(8, "VIDIOC_QUERYCTRL\n"); - if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg, - sizeof(struct v4l2_queryctrl))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg, + sizeof(struct v4l2_queryctrl))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - i1 = 0; - while (0xFFFFFFFF != easycap_control[i1].id) { - if (easycap_control[i1].id == v4l2_queryctrl.id) { - JOM(8, "VIDIOC_QUERYCTRL %s=easycap_control[%i]" - ".name\n", &easycap_control[i1].name[0], i1); - memcpy(&v4l2_queryctrl, &easycap_control[i1], - sizeof(struct v4l2_queryctrl)); - break; + i1 = 0; + while (0xFFFFFFFF != easycap_control[i1].id) { + if (easycap_control[i1].id == v4l2_queryctrl.id) { + JOM(8, "VIDIOC_QUERYCTRL %s=easycap_control[%i]" + ".name\n", &easycap_control[i1].name[0], i1); + memcpy(&v4l2_queryctrl, &easycap_control[i1], + sizeof(struct v4l2_queryctrl)); + break; + } + i1++; } - i1++; + if (0xFFFFFFFF == easycap_control[i1].id) { + JOM(8, "%i=index: exhausts controls\n", i1); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + if (copy_to_user((void __user *)arg, &v4l2_queryctrl, + sizeof(struct v4l2_queryctrl))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - if (0xFFFFFFFF == easycap_control[i1].id) { - JOM(8, "%i=index: exhausts controls\n", i1); +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + case VIDIOC_QUERYMENU: { + JOM(8, "VIDIOC_QUERYMENU unsupported\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } - if (0 != copy_to_user((void __user *)arg, &v4l2_queryctrl, - sizeof(struct v4l2_queryctrl))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } - break; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_QUERYMENU: { - JOM(8, "VIDIOC_QUERYMENU unsupported\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_G_CTRL: { - struct v4l2_control *pv4l2_control; + case VIDIOC_G_CTRL: { + struct v4l2_control *pv4l2_control; - JOM(8, "VIDIOC_G_CTRL\n"); - pv4l2_control = kzalloc(sizeof(struct v4l2_control), GFP_KERNEL); - if (!pv4l2_control) { - SAM("ERROR: out of memory\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -ENOMEM; - } - if (0 != copy_from_user(pv4l2_control, (void __user *)arg, - sizeof(struct v4l2_control))) { - kfree(pv4l2_control); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + JOM(8, "VIDIOC_G_CTRL\n"); + pv4l2_control = kzalloc(sizeof(struct v4l2_control), GFP_KERNEL); + if (!pv4l2_control) { + SAM("ERROR: out of memory\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ENOMEM; + } + if (0 != copy_from_user(pv4l2_control, (void __user *)arg, + sizeof(struct v4l2_control))) { + kfree(pv4l2_control); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - switch (pv4l2_control->id) { - case V4L2_CID_BRIGHTNESS: { - pv4l2_control->value = peasycap->brightness; - JOM(8, "user enquires brightness: %i\n", pv4l2_control->value); - break; - } - case V4L2_CID_CONTRAST: { - pv4l2_control->value = peasycap->contrast; - JOM(8, "user enquires contrast: %i\n", pv4l2_control->value); - break; - } - case V4L2_CID_SATURATION: { - pv4l2_control->value = peasycap->saturation; - JOM(8, "user enquires saturation: %i\n", pv4l2_control->value); - break; - } - case V4L2_CID_HUE: { - pv4l2_control->value = peasycap->hue; - JOM(8, "user enquires hue: %i\n", pv4l2_control->value); - break; - } - case V4L2_CID_AUDIO_VOLUME: { - pv4l2_control->value = peasycap->volume; - JOM(8, "user enquires volume: %i\n", pv4l2_control->value); - break; - } - case V4L2_CID_AUDIO_MUTE: { - if (1 == peasycap->mute) - pv4l2_control->value = true; - else - pv4l2_control->value = false; - JOM(8, "user enquires mute: %i\n", pv4l2_control->value); - break; - } - default: { - SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", - pv4l2_control->id); - kfree(pv4l2_control); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; - } - } - if (0 != copy_to_user((void __user *)arg, pv4l2_control, - sizeof(struct v4l2_control))) { + switch (pv4l2_control->id) { + case V4L2_CID_BRIGHTNESS: { + pv4l2_control->value = peasycap->brightness; + JOM(8, "user enquires brightness: %i\n", pv4l2_control->value); + break; + } + case V4L2_CID_CONTRAST: { + pv4l2_control->value = peasycap->contrast; + JOM(8, "user enquires contrast: %i\n", pv4l2_control->value); + break; + } + case V4L2_CID_SATURATION: { + pv4l2_control->value = peasycap->saturation; + JOM(8, "user enquires saturation: %i\n", pv4l2_control->value); + break; + } + case V4L2_CID_HUE: { + pv4l2_control->value = peasycap->hue; + JOM(8, "user enquires hue: %i\n", pv4l2_control->value); + break; + } + case V4L2_CID_AUDIO_VOLUME: { + pv4l2_control->value = peasycap->volume; + JOM(8, "user enquires volume: %i\n", pv4l2_control->value); + break; + } + case V4L2_CID_AUDIO_MUTE: { + if (1 == peasycap->mute) + pv4l2_control->value = true; + else + pv4l2_control->value = false; + JOM(8, "user enquires mute: %i\n", pv4l2_control->value); + break; + } + default: { + SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", + pv4l2_control->id); + kfree(pv4l2_control); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + } + if (copy_to_user((void __user *)arg, pv4l2_control, + sizeof(struct v4l2_control))) { + kfree(pv4l2_control); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } kfree(pv4l2_control); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; + break; } - kfree(pv4l2_control); - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_S_CTRL: + case VIDIOC_S_CTRL: { - struct v4l2_control v4l2_control; + struct v4l2_control v4l2_control; - JOM(8, "VIDIOC_S_CTRL\n"); + JOM(8, "VIDIOC_S_CTRL\n"); - if (0 != copy_from_user(&v4l2_control, (void __user *)arg, - sizeof(struct v4l2_control))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + if (0 != copy_from_user(&v4l2_control, (void __user *)arg, + sizeof(struct v4l2_control))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - switch (v4l2_control.id) { - case V4L2_CID_BRIGHTNESS: { - JOM(8, "user requests brightness %i\n", v4l2_control.value); - if (0 != adjust_brightness(peasycap, v4l2_control.value)) - ; - break; - } - case V4L2_CID_CONTRAST: { - JOM(8, "user requests contrast %i\n", v4l2_control.value); - if (0 != adjust_contrast(peasycap, v4l2_control.value)) - ; - break; - } - case V4L2_CID_SATURATION: { - JOM(8, "user requests saturation %i\n", v4l2_control.value); - if (0 != adjust_saturation(peasycap, v4l2_control.value)) - ; - break; - } - case V4L2_CID_HUE: { - JOM(8, "user requests hue %i\n", v4l2_control.value); - if (0 != adjust_hue(peasycap, v4l2_control.value)) - ; - break; - } - case V4L2_CID_AUDIO_VOLUME: { - JOM(8, "user requests volume %i\n", v4l2_control.value); - if (0 != adjust_volume(peasycap, v4l2_control.value)) - ; - break; - } - case V4L2_CID_AUDIO_MUTE: { - int mute; + switch (v4l2_control.id) { + case V4L2_CID_BRIGHTNESS: { + JOM(8, "user requests brightness %i\n", v4l2_control.value); + if (0 != adjust_brightness(peasycap, v4l2_control.value)) + ; + break; + } + case V4L2_CID_CONTRAST: { + JOM(8, "user requests contrast %i\n", v4l2_control.value); + if (0 != adjust_contrast(peasycap, v4l2_control.value)) + ; + break; + } + case V4L2_CID_SATURATION: { + JOM(8, "user requests saturation %i\n", v4l2_control.value); + if (0 != adjust_saturation(peasycap, v4l2_control.value)) + ; + break; + } + case V4L2_CID_HUE: { + JOM(8, "user requests hue %i\n", v4l2_control.value); + if (0 != adjust_hue(peasycap, v4l2_control.value)) + ; + break; + } + case V4L2_CID_AUDIO_VOLUME: { + JOM(8, "user requests volume %i\n", v4l2_control.value); + if (0 != adjust_volume(peasycap, v4l2_control.value)) + ; + break; + } + case V4L2_CID_AUDIO_MUTE: { + int mute; - JOM(8, "user requests mute %i\n", v4l2_control.value); - if (true == v4l2_control.value) - mute = 1; - else - mute = 0; + JOM(8, "user requests mute %i\n", v4l2_control.value); + if (true == v4l2_control.value) + mute = 1; + else + mute = 0; - if (0 != adjust_mute(peasycap, mute)) - SAM("WARNING: failed to adjust mute to %i\n", mute); + if (0 != adjust_mute(peasycap, mute)) + SAM("WARNING: failed to adjust mute to %i\n", mute); + break; + } + default: { + SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", + v4l2_control.id); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + } break; } - default: { - SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", - v4l2_control.id); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; - } - } - break; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_S_EXT_CTRLS: { - JOM(8, "VIDIOC_S_EXT_CTRLS unsupported\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_ENUM_FMT: { - u32 index; - struct v4l2_fmtdesc v4l2_fmtdesc; - - JOM(8, "VIDIOC_ENUM_FMT\n"); - - if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg, - sizeof(struct v4l2_fmtdesc))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } - - index = v4l2_fmtdesc.index; - memset(&v4l2_fmtdesc, 0, sizeof(struct v4l2_fmtdesc)); - - v4l2_fmtdesc.index = index; - v4l2_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - switch (index) { - case 0: { - v4l2_fmtdesc.flags = 0; - strcpy(&v4l2_fmtdesc.description[0], "uyvy"); - v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_UYVY; - JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); - break; - } - case 1: { - v4l2_fmtdesc.flags = 0; - strcpy(&v4l2_fmtdesc.description[0], "yuy2"); - v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_YUYV; - JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); - break; - } - case 2: { - v4l2_fmtdesc.flags = 0; - strcpy(&v4l2_fmtdesc.description[0], "rgb24"); - v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB24; - JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); - break; - } - case 3: { - v4l2_fmtdesc.flags = 0; - strcpy(&v4l2_fmtdesc.description[0], "rgb32"); - v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB32; - JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); - break; - } - case 4: { - v4l2_fmtdesc.flags = 0; - strcpy(&v4l2_fmtdesc.description[0], "bgr24"); - v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR24; - JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); - break; - } - case 5: { - v4l2_fmtdesc.flags = 0; - strcpy(&v4l2_fmtdesc.description[0], "bgr32"); - v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR32; - JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); - break; - } - default: { - JOM(8, "%i=index: exhausts formats\n", index); + case VIDIOC_S_EXT_CTRLS: { + JOM(8, "VIDIOC_S_EXT_CTRLS unsupported\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } - } - if (0 != copy_to_user((void __user *)arg, &v4l2_fmtdesc, - sizeof(struct v4l2_fmtdesc))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -/* - * THE RESPONSE TO VIDIOC_ENUM_FRAMESIZES MUST BE CONDITIONED ON THE - * THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE. -*/ -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_ENUM_FRAMESIZES: { - u32 index; - struct v4l2_frmsizeenum v4l2_frmsizeenum; + case VIDIOC_ENUM_FMT: { + u32 index; + struct v4l2_fmtdesc v4l2_fmtdesc; - JOM(8, "VIDIOC_ENUM_FRAMESIZES\n"); + JOM(8, "VIDIOC_ENUM_FMT\n"); - if (0 != copy_from_user(&v4l2_frmsizeenum, (void __user *)arg, - sizeof(struct v4l2_frmsizeenum))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg, + sizeof(struct v4l2_fmtdesc))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - index = v4l2_frmsizeenum.index; + index = v4l2_fmtdesc.index; + memset(&v4l2_fmtdesc, 0, sizeof(struct v4l2_fmtdesc)); - v4l2_frmsizeenum.type = (u32) V4L2_FRMSIZE_TYPE_DISCRETE; + v4l2_fmtdesc.index = index; + v4l2_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (true == peasycap->ntsc) { switch (index) { case 0: { - v4l2_frmsizeenum.discrete.width = 640; - v4l2_frmsizeenum.discrete.height = 480; - JOM(8, "%i=index: %ix%i\n", index, - (int)(v4l2_frmsizeenum. - discrete.width), - (int)(v4l2_frmsizeenum. - discrete.height)); + v4l2_fmtdesc.flags = 0; + strcpy(&v4l2_fmtdesc.description[0], "uyvy"); + v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_UYVY; + JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); break; } case 1: { - v4l2_frmsizeenum.discrete.width = 320; - v4l2_frmsizeenum.discrete.height = 240; - JOM(8, "%i=index: %ix%i\n", index, - (int)(v4l2_frmsizeenum. - discrete.width), - (int)(v4l2_frmsizeenum. - discrete.height)); + v4l2_fmtdesc.flags = 0; + strcpy(&v4l2_fmtdesc.description[0], "yuy2"); + v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_YUYV; + JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); break; } case 2: { - v4l2_frmsizeenum.discrete.width = 720; - v4l2_frmsizeenum.discrete.height = 480; - JOM(8, "%i=index: %ix%i\n", index, - (int)(v4l2_frmsizeenum. - discrete.width), - (int)(v4l2_frmsizeenum. - discrete.height)); + v4l2_fmtdesc.flags = 0; + strcpy(&v4l2_fmtdesc.description[0], "rgb24"); + v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB24; + JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); break; } case 3: { - v4l2_frmsizeenum.discrete.width = 360; - v4l2_frmsizeenum.discrete.height = 240; - JOM(8, "%i=index: %ix%i\n", index, - (int)(v4l2_frmsizeenum. - discrete.width), - (int)(v4l2_frmsizeenum. - discrete.height)); + v4l2_fmtdesc.flags = 0; + strcpy(&v4l2_fmtdesc.description[0], "rgb32"); + v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB32; + JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); break; } - default: { - JOM(8, "%i=index: exhausts framesizes\n", index); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; - } - } - } else { - switch (index) { - case 0: { - v4l2_frmsizeenum.discrete.width = 640; - v4l2_frmsizeenum.discrete.height = 480; - JOM(8, "%i=index: %ix%i\n", index, - (int)(v4l2_frmsizeenum. - discrete.width), - (int)(v4l2_frmsizeenum. - discrete.height)); - break; - } - case 1: { - v4l2_frmsizeenum.discrete.width = 320; - v4l2_frmsizeenum.discrete.height = 240; - JOM(8, "%i=index: %ix%i\n", index, - (int)(v4l2_frmsizeenum. - discrete.width), - (int)(v4l2_frmsizeenum. - discrete.height)); - break; - } - case 2: { - v4l2_frmsizeenum.discrete.width = 704; - v4l2_frmsizeenum.discrete.height = 576; - JOM(8, "%i=index: %ix%i\n", index, - (int)(v4l2_frmsizeenum. - discrete.width), - (int)(v4l2_frmsizeenum. - discrete.height)); - break; - } - case 3: { - v4l2_frmsizeenum.discrete.width = 720; - v4l2_frmsizeenum.discrete.height = 576; - JOM(8, "%i=index: %ix%i\n", index, - (int)(v4l2_frmsizeenum. - discrete.width), - (int)(v4l2_frmsizeenum. - discrete.height)); + case 4: { + v4l2_fmtdesc.flags = 0; + strcpy(&v4l2_fmtdesc.description[0], "bgr24"); + v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR24; + JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); break; } - case 4: { - v4l2_frmsizeenum.discrete.width = 360; - v4l2_frmsizeenum.discrete.height = 288; - JOM(8, "%i=index: %ix%i\n", index, - (int)(v4l2_frmsizeenum. - discrete.width), - (int)(v4l2_frmsizeenum. - discrete.height)); + case 5: { + v4l2_fmtdesc.flags = 0; + strcpy(&v4l2_fmtdesc.description[0], "bgr32"); + v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR32; + JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); break; } default: { - JOM(8, "%i=index: exhausts framesizes\n", index); + JOM(8, "%i=index: exhausts formats\n", index); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } } + if (copy_to_user((void __user *)arg, &v4l2_fmtdesc, + sizeof(struct v4l2_fmtdesc))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - if (0 != copy_to_user((void __user *)arg, &v4l2_frmsizeenum, - sizeof(struct v4l2_frmsizeenum))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* - * THE RESPONSE TO VIDIOC_ENUM_FRAMEINTERVALS MUST BE CONDITIONED ON THE - * THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE. -*/ + * THE RESPONSE TO VIDIOC_ENUM_FRAMESIZES MUST BE CONDITIONED ON THE + * THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE. + */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_ENUM_FRAMEINTERVALS: { - u32 index; - int denominator; - struct v4l2_frmivalenum v4l2_frmivalenum; - - JOM(8, "VIDIOC_ENUM_FRAMEINTERVALS\n"); + case VIDIOC_ENUM_FRAMESIZES: { + u32 index; + struct v4l2_frmsizeenum v4l2_frmsizeenum; - if (peasycap->fps) - denominator = peasycap->fps; - else { - if (true == peasycap->ntsc) - denominator = 30; - else - denominator = 25; - } + JOM(8, "VIDIOC_ENUM_FRAMESIZES\n"); - if (0 != copy_from_user(&v4l2_frmivalenum, (void __user *)arg, - sizeof(struct v4l2_frmivalenum))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + if (0 != copy_from_user(&v4l2_frmsizeenum, (void __user *)arg, + sizeof(struct v4l2_frmsizeenum))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - index = v4l2_frmivalenum.index; + index = v4l2_frmsizeenum.index; - v4l2_frmivalenum.type = (u32) V4L2_FRMIVAL_TYPE_DISCRETE; + v4l2_frmsizeenum.type = (u32) V4L2_FRMSIZE_TYPE_DISCRETE; - switch (index) { - case 0: { - v4l2_frmivalenum.discrete.numerator = 1; - v4l2_frmivalenum.discrete.denominator = denominator; - JOM(8, "%i=index: %i/%i\n", index, - (int)(v4l2_frmivalenum.discrete.numerator), - (int)(v4l2_frmivalenum.discrete.denominator)); - break; - } - case 1: { - v4l2_frmivalenum.discrete.numerator = 1; - v4l2_frmivalenum.discrete.denominator = denominator/5; - JOM(8, "%i=index: %i/%i\n", index, - (int)(v4l2_frmivalenum.discrete.numerator), - (int)(v4l2_frmivalenum.discrete.denominator)); + if (true == peasycap->ntsc) { + switch (index) { + case 0: { + v4l2_frmsizeenum.discrete.width = 640; + v4l2_frmsizeenum.discrete.height = 480; + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. + discrete.height)); + break; + } + case 1: { + v4l2_frmsizeenum.discrete.width = 320; + v4l2_frmsizeenum.discrete.height = 240; + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. + discrete.height)); + break; + } + case 2: { + v4l2_frmsizeenum.discrete.width = 720; + v4l2_frmsizeenum.discrete.height = 480; + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. + discrete.height)); + break; + } + case 3: { + v4l2_frmsizeenum.discrete.width = 360; + v4l2_frmsizeenum.discrete.height = 240; + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. + discrete.height)); + break; + } + default: { + JOM(8, "%i=index: exhausts framesizes\n", index); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + } + } else { + switch (index) { + case 0: { + v4l2_frmsizeenum.discrete.width = 640; + v4l2_frmsizeenum.discrete.height = 480; + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. + discrete.height)); + break; + } + case 1: { + v4l2_frmsizeenum.discrete.width = 320; + v4l2_frmsizeenum.discrete.height = 240; + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. + discrete.height)); + break; + } + case 2: { + v4l2_frmsizeenum.discrete.width = 704; + v4l2_frmsizeenum.discrete.height = 576; + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. + discrete.height)); + break; + } + case 3: { + v4l2_frmsizeenum.discrete.width = 720; + v4l2_frmsizeenum.discrete.height = 576; + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. + discrete.height)); + break; + } + case 4: { + v4l2_frmsizeenum.discrete.width = 360; + v4l2_frmsizeenum.discrete.height = 288; + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. + discrete.height)); + break; + } + default: { + JOM(8, "%i=index: exhausts framesizes\n", index); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + } + } + if (copy_to_user((void __user *)arg, &v4l2_frmsizeenum, + sizeof(struct v4l2_frmsizeenum))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } break; } - default: { - JOM(8, "%i=index: exhausts frameintervals\n", index); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; - } - } - if (0 != copy_to_user((void __user *)arg, &v4l2_frmivalenum, +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +/* + * THE RESPONSE TO VIDIOC_ENUM_FRAMEINTERVALS MUST BE CONDITIONED ON THE + * THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE. + */ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + case VIDIOC_ENUM_FRAMEINTERVALS: { + u32 index; + int denominator; + struct v4l2_frmivalenum v4l2_frmivalenum; + + JOM(8, "VIDIOC_ENUM_FRAMEINTERVALS\n"); + + if (peasycap->fps) + denominator = peasycap->fps; + else { + if (true == peasycap->ntsc) + denominator = 30; + else + denominator = 25; + } + + if (0 != copy_from_user(&v4l2_frmivalenum, (void __user *)arg, + sizeof(struct v4l2_frmivalenum))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + + index = v4l2_frmivalenum.index; + + v4l2_frmivalenum.type = (u32) V4L2_FRMIVAL_TYPE_DISCRETE; + + switch (index) { + case 0: { + v4l2_frmivalenum.discrete.numerator = 1; + v4l2_frmivalenum.discrete.denominator = denominator; + JOM(8, "%i=index: %i/%i\n", index, + (int)(v4l2_frmivalenum.discrete.numerator), + (int)(v4l2_frmivalenum.discrete.denominator)); + break; + } + case 1: { + v4l2_frmivalenum.discrete.numerator = 1; + v4l2_frmivalenum.discrete.denominator = denominator/5; + JOM(8, "%i=index: %i/%i\n", index, + (int)(v4l2_frmivalenum.discrete.numerator), + (int)(v4l2_frmivalenum.discrete.denominator)); + break; + } + default: { + JOM(8, "%i=index: exhausts frameintervals\n", index); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + } + if (copy_to_user((void __user *)arg, &v4l2_frmivalenum, sizeof(struct v4l2_frmivalenum))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_G_FMT: { - struct v4l2_format *pv4l2_format; - struct v4l2_pix_format *pv4l2_pix_format; - - JOM(8, "VIDIOC_G_FMT\n"); - pv4l2_format = kzalloc(sizeof(struct v4l2_format), GFP_KERNEL); - if (!pv4l2_format) { - SAM("ERROR: out of memory\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -ENOMEM; - } - pv4l2_pix_format = kzalloc(sizeof(struct v4l2_pix_format), GFP_KERNEL); - if (!pv4l2_pix_format) { - SAM("ERROR: out of memory\n"); - kfree(pv4l2_format); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -ENOMEM; - } - if (0 != copy_from_user(pv4l2_format, (void __user *)arg, + case VIDIOC_G_FMT: { + struct v4l2_format *pv4l2_format; + struct v4l2_pix_format *pv4l2_pix_format; + + JOM(8, "VIDIOC_G_FMT\n"); + pv4l2_format = kzalloc(sizeof(struct v4l2_format), GFP_KERNEL); + if (!pv4l2_format) { + SAM("ERROR: out of memory\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ENOMEM; + } + pv4l2_pix_format = kzalloc(sizeof(struct v4l2_pix_format), GFP_KERNEL); + if (!pv4l2_pix_format) { + SAM("ERROR: out of memory\n"); + kfree(pv4l2_format); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ENOMEM; + } + if (0 != copy_from_user(pv4l2_format, (void __user *)arg, sizeof(struct v4l2_format))) { - kfree(pv4l2_format); - kfree(pv4l2_pix_format); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + kfree(pv4l2_format); + kfree(pv4l2_pix_format); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - if (pv4l2_format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - kfree(pv4l2_format); - kfree(pv4l2_pix_format); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; - } + if (pv4l2_format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + kfree(pv4l2_format); + kfree(pv4l2_pix_format); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } - memset(pv4l2_pix_format, 0, sizeof(struct v4l2_pix_format)); - pv4l2_format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - memcpy(&pv4l2_format->fmt.pix, - &easycap_format[peasycap->format_offset] - .v4l2_format.fmt.pix, sizeof(struct v4l2_pix_format)); - JOM(8, "user is told: %s\n", - &easycap_format[peasycap->format_offset].name[0]); + memset(pv4l2_pix_format, 0, sizeof(struct v4l2_pix_format)); + pv4l2_format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + memcpy(&pv4l2_format->fmt.pix, + &easycap_format[peasycap->format_offset] + .v4l2_format.fmt.pix, sizeof(struct v4l2_pix_format)); + JOM(8, "user is told: %s\n", + &easycap_format[peasycap->format_offset].name[0]); - if (0 != copy_to_user((void __user *)arg, pv4l2_format, + if (copy_to_user((void __user *)arg, pv4l2_format, sizeof(struct v4l2_format))) { + kfree(pv4l2_format); + kfree(pv4l2_pix_format); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } kfree(pv4l2_format); kfree(pv4l2_pix_format); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; + break; } - kfree(pv4l2_format); - kfree(pv4l2_pix_format); - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_TRY_FMT: -case VIDIOC_S_FMT: { - struct v4l2_format v4l2_format; - struct v4l2_pix_format v4l2_pix_format; - bool try; - int best_format; - - if (VIDIOC_TRY_FMT == cmd) { - JOM(8, "VIDIOC_TRY_FMT\n"); - try = true; - } else { - JOM(8, "VIDIOC_S_FMT\n"); - try = false; - } + case VIDIOC_TRY_FMT: + case VIDIOC_S_FMT: { + struct v4l2_format v4l2_format; + struct v4l2_pix_format v4l2_pix_format; + bool try; + int best_format; + + if (VIDIOC_TRY_FMT == cmd) { + JOM(8, "VIDIOC_TRY_FMT\n"); + try = true; + } else { + JOM(8, "VIDIOC_S_FMT\n"); + try = false; + } - if (0 != copy_from_user(&v4l2_format, (void __user *)arg, + if (0 != copy_from_user(&v4l2_format, (void __user *)arg, sizeof(struct v4l2_format))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - best_format = adjust_format(peasycap, + best_format = adjust_format(peasycap, v4l2_format.fmt.pix.width, v4l2_format.fmt.pix.height, v4l2_format.fmt.pix.pixelformat, v4l2_format.fmt.pix.field, try); - if (0 > best_format) { - if (-EBUSY == best_format) { + if (0 > best_format) { + if (-EBUSY == best_format) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EBUSY; + } + JOM(8, "WARNING: adjust_format() returned %i\n", best_format); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EBUSY; + return -ENOENT; } - JOM(8, "WARNING: adjust_format() returned %i\n", best_format); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -ENOENT; - } /*...........................................................................*/ - memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format)); - v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format)); + v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - memcpy(&(v4l2_format.fmt.pix), &(easycap_format[best_format] - .v4l2_format.fmt.pix), sizeof(v4l2_pix_format)); - JOM(8, "user is told: %s\n", &easycap_format[best_format].name[0]); + memcpy(&(v4l2_format.fmt.pix), + &(easycap_format[best_format].v4l2_format.fmt.pix), + sizeof(v4l2_pix_format)); + JOM(8, "user is told: %s\n", &easycap_format[best_format].name[0]); - if (0 != copy_to_user((void __user *)arg, &v4l2_format, + if (copy_to_user((void __user *)arg, &v4l2_format, sizeof(struct v4l2_format))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_CROPCAP: { - struct v4l2_cropcap v4l2_cropcap; + case VIDIOC_CROPCAP: { + struct v4l2_cropcap v4l2_cropcap; - JOM(8, "VIDIOC_CROPCAP\n"); + JOM(8, "VIDIOC_CROPCAP\n"); - if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg, + if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg, sizeof(struct v4l2_cropcap))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } - - if (v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - JOM(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); - - memset(&v4l2_cropcap, 0, sizeof(struct v4l2_cropcap)); - v4l2_cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - v4l2_cropcap.bounds.left = 0; - v4l2_cropcap.bounds.top = 0; - v4l2_cropcap.bounds.width = peasycap->width; - v4l2_cropcap.bounds.height = peasycap->height; - v4l2_cropcap.defrect.left = 0; - v4l2_cropcap.defrect.top = 0; - v4l2_cropcap.defrect.width = peasycap->width; - v4l2_cropcap.defrect.height = peasycap->height; - v4l2_cropcap.pixelaspect.numerator = 1; - v4l2_cropcap.pixelaspect.denominator = 1; - - JOM(8, "user is told: %ix%i\n", peasycap->width, peasycap->height); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - if (0 != copy_to_user((void __user *)arg, &v4l2_cropcap, + if (v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + JOM(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); + + memset(&v4l2_cropcap, 0, sizeof(struct v4l2_cropcap)); + v4l2_cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + v4l2_cropcap.bounds.left = 0; + v4l2_cropcap.bounds.top = 0; + v4l2_cropcap.bounds.width = peasycap->width; + v4l2_cropcap.bounds.height = peasycap->height; + v4l2_cropcap.defrect.left = 0; + v4l2_cropcap.defrect.top = 0; + v4l2_cropcap.defrect.width = peasycap->width; + v4l2_cropcap.defrect.height = peasycap->height; + v4l2_cropcap.pixelaspect.numerator = 1; + v4l2_cropcap.pixelaspect.denominator = 1; + + JOM(8, "user is told: %ix%i\n", peasycap->width, peasycap->height); + + if (copy_to_user((void __user *)arg, &v4l2_cropcap, sizeof(struct v4l2_cropcap))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_G_CROP: -case VIDIOC_S_CROP: { - JOM(8, "VIDIOC_G_CROP|VIDIOC_S_CROP unsupported\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_QUERYSTD: { - JOM(8, "VIDIOC_QUERYSTD: " - "EasyCAP is incapable of detecting standard\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; - break; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -/*---------------------------------------------------------------------------*/ -/* - * THE MANIPULATIONS INVOLVING last0,last1,last2,last3 CONSTITUTE A WORKAROUND - * FOR WHAT APPEARS TO BE A BUG IN 64-BIT mplayer. - * NOT NEEDED, BUT HOPEFULLY HARMLESS, FOR 32-BIT mplayer. - */ -/*---------------------------------------------------------------------------*/ -case VIDIOC_ENUMSTD: { - int last0 = -1, last1 = -1, last2 = -1, last3 = -1; - struct v4l2_standard v4l2_standard; - u32 index; - struct easycap_standard const *peasycap_standard; - - JOM(8, "VIDIOC_ENUMSTD\n"); - - if (0 != copy_from_user(&v4l2_standard, (void __user *)arg, - sizeof(struct v4l2_standard))) { + case VIDIOC_G_CROP: + case VIDIOC_S_CROP: { + JOM(8, "VIDIOC_G_CROP|VIDIOC_S_CROP unsupported\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } - index = v4l2_standard.index; - - last3 = last2; last2 = last1; last1 = last0; last0 = index; - if ((index == last3) && (index == last2) && - (index == last1) && (index == last0)) { - index++; - last3 = last2; last2 = last1; last1 = last0; last0 = index; - } - - memset(&v4l2_standard, 0, sizeof(struct v4l2_standard)); - - peasycap_standard = &easycap_standard[0]; - while (0xFFFF != peasycap_standard->mask) { - if ((int)(peasycap_standard - &easycap_standard[0]) == index) - break; - peasycap_standard++; + return -EINVAL; } - if (0xFFFF == peasycap_standard->mask) { - JOM(8, "%i=index: exhausts standards\n", index); +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + case VIDIOC_QUERYSTD: { + JOM(8, "VIDIOC_QUERYSTD: " + "EasyCAP is incapable of detecting standard\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; + break; } - JOM(8, "%i=index: %s\n", index, - &(peasycap_standard->v4l2_standard.name[0])); - memcpy(&v4l2_standard, &(peasycap_standard->v4l2_standard), - sizeof(struct v4l2_standard)); + /*-------------------------------------------------------------------*/ + /* + * THE MANIPULATIONS INVOLVING last0,last1,last2,last3 + * CONSTITUTE A WORKAROUND * FOR WHAT APPEARS TO BE + * A BUG IN 64-BIT mplayer. + * NOT NEEDED, BUT HOPEFULLY HARMLESS, FOR 32-BIT mplayer. + */ + /*------------------------------------------------------------------*/ + case VIDIOC_ENUMSTD: { + int last0 = -1, last1 = -1, last2 = -1, last3 = -1; + struct v4l2_standard v4l2_standard; + u32 index; + struct easycap_standard const *peasycap_standard; + + JOM(8, "VIDIOC_ENUMSTD\n"); + + if (0 != copy_from_user(&v4l2_standard, (void __user *)arg, + sizeof(struct v4l2_standard))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + index = v4l2_standard.index; + + last3 = last2; + last2 = last1; + last1 = last0; + last0 = index; + if ((index == last3) && (index == last2) && + (index == last1) && (index == last0)) { + index++; + last3 = last2; + last2 = last1; + last1 = last0; + last0 = index; + } - v4l2_standard.index = index; + memset(&v4l2_standard, 0, sizeof(struct v4l2_standard)); - if (0 != copy_to_user((void __user *)arg, &v4l2_standard, - sizeof(struct v4l2_standard))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; + peasycap_standard = &easycap_standard[0]; + while (0xFFFF != peasycap_standard->mask) { + if ((int)(peasycap_standard - &easycap_standard[0]) == index) + break; + peasycap_standard++; + } + if (0xFFFF == peasycap_standard->mask) { + JOM(8, "%i=index: exhausts standards\n", index); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + JOM(8, "%i=index: %s\n", index, + &(peasycap_standard->v4l2_standard.name[0])); + memcpy(&v4l2_standard, &(peasycap_standard->v4l2_standard), + sizeof(struct v4l2_standard)); + + v4l2_standard.index = index; + + if (copy_to_user((void __user *)arg, &v4l2_standard, + sizeof(struct v4l2_standard))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_G_STD: { - v4l2_std_id std_id; - struct easycap_standard const *peasycap_standard; + case VIDIOC_G_STD: { + v4l2_std_id std_id; + struct easycap_standard const *peasycap_standard; - JOM(8, "VIDIOC_G_STD\n"); + JOM(8, "VIDIOC_G_STD\n"); - if (0 > peasycap->standard_offset) { - JOM(8, "%i=peasycap->standard_offset\n", - peasycap->standard_offset); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EBUSY; - } + if (0 > peasycap->standard_offset) { + JOM(8, "%i=peasycap->standard_offset\n", + peasycap->standard_offset); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EBUSY; + } - if (0 != copy_from_user(&std_id, (void __user *)arg, - sizeof(v4l2_std_id))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + if (0 != copy_from_user(&std_id, (void __user *)arg, + sizeof(v4l2_std_id))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - peasycap_standard = &easycap_standard[peasycap->standard_offset]; - std_id = peasycap_standard->v4l2_standard.id; + peasycap_standard = &easycap_standard[peasycap->standard_offset]; + std_id = peasycap_standard->v4l2_standard.id; - JOM(8, "user is told: %s\n", - &peasycap_standard->v4l2_standard.name[0]); + JOM(8, "user is told: %s\n", + &peasycap_standard->v4l2_standard.name[0]); - if (0 != copy_to_user((void __user *)arg, &std_id, - sizeof(v4l2_std_id))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; + if (copy_to_user((void __user *)arg, &std_id, + sizeof(v4l2_std_id))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_S_STD: { - v4l2_std_id std_id; - int rc; + case VIDIOC_S_STD: { + v4l2_std_id std_id; + int rc; - JOM(8, "VIDIOC_S_STD\n"); + JOM(8, "VIDIOC_S_STD\n"); - if (0 != copy_from_user(&std_id, (void __user *)arg, - sizeof(v4l2_std_id))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + if (0 != copy_from_user(&std_id, (void __user *)arg, + sizeof(v4l2_std_id))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - JOM(8, "User requests standard: 0x%08X%08X\n", - (int)((std_id & (((v4l2_std_id)0xFFFFFFFF) << 32)) >> 32), - (int)(std_id & ((v4l2_std_id)0xFFFFFFFF))); + JOM(8, "User requests standard: 0x%08X%08X\n", + (int)((std_id & (((v4l2_std_id)0xFFFFFFFF) << 32)) >> 32), + (int)(std_id & ((v4l2_std_id)0xFFFFFFFF))); - rc = adjust_standard(peasycap, std_id); - if (0 > rc) { - JOM(8, "WARNING: adjust_standard() returned %i\n", rc); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -ENOENT; + rc = adjust_standard(peasycap, std_id); + if (0 > rc) { + JOM(8, "WARNING: adjust_standard() returned %i\n", rc); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ENOENT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_REQBUFS: { - int nbuffers; - struct v4l2_requestbuffers v4l2_requestbuffers; + case VIDIOC_REQBUFS: { + int nbuffers; + struct v4l2_requestbuffers v4l2_requestbuffers; - JOM(8, "VIDIOC_REQBUFS\n"); + JOM(8, "VIDIOC_REQBUFS\n"); - if (0 != copy_from_user(&v4l2_requestbuffers, (void __user *)arg, - sizeof(struct v4l2_requestbuffers))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + if (0 != copy_from_user(&v4l2_requestbuffers, + (void __user *)arg, + sizeof(struct v4l2_requestbuffers))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; - } - if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; - } - nbuffers = v4l2_requestbuffers.count; - JOM(8, " User requests %i buffers ...\n", nbuffers); - if (nbuffers < 2) - nbuffers = 2; - if (nbuffers > FRAME_BUFFER_MANY) - nbuffers = FRAME_BUFFER_MANY; - if (v4l2_requestbuffers.count == nbuffers) { - JOM(8, " ... agree to %i buffers\n", - nbuffers); - } else { - JOM(8, " ... insist on %i buffers\n", - nbuffers); - v4l2_requestbuffers.count = nbuffers; - } - peasycap->frame_buffer_many = nbuffers; + if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + nbuffers = v4l2_requestbuffers.count; + JOM(8, " User requests %i buffers ...\n", nbuffers); + if (nbuffers < 2) + nbuffers = 2; + if (nbuffers > FRAME_BUFFER_MANY) + nbuffers = FRAME_BUFFER_MANY; + if (v4l2_requestbuffers.count == nbuffers) { + JOM(8, " ... agree to %i buffers\n", + nbuffers); + } else { + JOM(8, " ... insist on %i buffers\n", + nbuffers); + v4l2_requestbuffers.count = nbuffers; + } + peasycap->frame_buffer_many = nbuffers; - if (0 != copy_to_user((void __user *)arg, &v4l2_requestbuffers, - sizeof(struct v4l2_requestbuffers))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; + if (copy_to_user((void __user *)arg, &v4l2_requestbuffers, + sizeof(struct v4l2_requestbuffers))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_QUERYBUF: { - u32 index; - struct v4l2_buffer v4l2_buffer; + case VIDIOC_QUERYBUF: { + u32 index; + struct v4l2_buffer v4l2_buffer; - JOM(8, "VIDIOC_QUERYBUF\n"); + JOM(8, "VIDIOC_QUERYBUF\n"); - if (peasycap->video_eof) { - JOM(8, "returning -EIO because %i=video_eof\n", - peasycap->video_eof); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EIO; - } + if (peasycap->video_eof) { + JOM(8, "returning -EIO because %i=video_eof\n", + peasycap->video_eof); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EIO; + } - if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, + if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, sizeof(struct v4l2_buffer))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; - } - index = v4l2_buffer.index; - if (index < 0 || index >= peasycap->frame_buffer_many) - return -EINVAL; - memset(&v4l2_buffer, 0, sizeof(struct v4l2_buffer)); - v4l2_buffer.index = index; - v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - v4l2_buffer.bytesused = peasycap->frame_buffer_used; - v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | - peasycap->done[index] | - peasycap->queued[index]; - v4l2_buffer.field = V4L2_FIELD_NONE; - v4l2_buffer.memory = V4L2_MEMORY_MMAP; - v4l2_buffer.m.offset = index * FRAME_BUFFER_SIZE; - v4l2_buffer.length = FRAME_BUFFER_SIZE; - - JOM(16, " %10i=index\n", v4l2_buffer.index); - JOM(16, " 0x%08X=type\n", v4l2_buffer.type); - JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused); - JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags); - JOM(16, " %10i=field\n", v4l2_buffer.field); - JOM(16, " %10li=timestamp.tv_usec\n", - (long)v4l2_buffer.timestamp.tv_usec); - JOM(16, " %10i=sequence\n", v4l2_buffer.sequence); - JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory); - JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset); - JOM(16, " %10i=length\n", v4l2_buffer.length); - - if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, + if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + index = v4l2_buffer.index; + if (index < 0 || index >= peasycap->frame_buffer_many) + return -EINVAL; + memset(&v4l2_buffer, 0, sizeof(struct v4l2_buffer)); + v4l2_buffer.index = index; + v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + v4l2_buffer.bytesused = peasycap->frame_buffer_used; + v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | + peasycap->done[index] | + peasycap->queued[index]; + v4l2_buffer.field = V4L2_FIELD_NONE; + v4l2_buffer.memory = V4L2_MEMORY_MMAP; + v4l2_buffer.m.offset = index * FRAME_BUFFER_SIZE; + v4l2_buffer.length = FRAME_BUFFER_SIZE; + + JOM(16, " %10i=index\n", v4l2_buffer.index); + JOM(16, " 0x%08X=type\n", v4l2_buffer.type); + JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused); + JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags); + JOM(16, " %10i=field\n", v4l2_buffer.field); + JOM(16, " %10li=timestamp.tv_usec\n", + (long)v4l2_buffer.timestamp.tv_usec); + JOM(16, " %10i=sequence\n", v4l2_buffer.sequence); + JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory); + JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset); + JOM(16, " %10i=length\n", v4l2_buffer.length); + + if (copy_to_user((void __user *)arg, &v4l2_buffer, sizeof(struct v4l2_buffer))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_QBUF: { - struct v4l2_buffer v4l2_buffer; + case VIDIOC_QBUF: { + struct v4l2_buffer v4l2_buffer; - JOM(8, "VIDIOC_QBUF\n"); + JOM(8, "VIDIOC_QBUF\n"); - if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, + if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, sizeof(struct v4l2_buffer))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; - } - if (v4l2_buffer.memory != V4L2_MEMORY_MMAP) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; - } - if (v4l2_buffer.index < 0 || - (v4l2_buffer.index >= peasycap->frame_buffer_many)) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; - } - v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED; + if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + if (v4l2_buffer.memory != V4L2_MEMORY_MMAP) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + if (v4l2_buffer.index < 0 || + v4l2_buffer.index >= peasycap->frame_buffer_many) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED; - peasycap->done[v4l2_buffer.index] = 0; - peasycap->queued[v4l2_buffer.index] = V4L2_BUF_FLAG_QUEUED; + peasycap->done[v4l2_buffer.index] = 0; + peasycap->queued[v4l2_buffer.index] = V4L2_BUF_FLAG_QUEUED; - if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, + if (copy_to_user((void __user *)arg, &v4l2_buffer, sizeof(struct v4l2_buffer))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - JOM(8, "..... user queueing frame buffer %i\n", - (int)v4l2_buffer.index); + JOM(8, "..... user queueing frame buffer %i\n", + (int)v4l2_buffer.index); - peasycap->frame_lock = 0; + peasycap->frame_lock = 0; - break; -} + break; + } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_DQBUF: + case VIDIOC_DQBUF: { - struct timeval timeval, timeval2; - int i, j; - struct v4l2_buffer v4l2_buffer; - int rcdq; - u16 input; - - JOM(8, "VIDIOC_DQBUF\n"); - - if ((peasycap->video_idle) || (peasycap->video_eof)) { - JOM(8, "returning -EIO because " - "%i=video_idle %i=video_eof\n", - peasycap->video_idle, peasycap->video_eof); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EIO; - } - - if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, - sizeof(struct v4l2_buffer))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + struct timeval timeval, timeval2; + int i, j; + struct v4l2_buffer v4l2_buffer; + int rcdq; + u16 input; + + JOM(8, "VIDIOC_DQBUF\n"); + + if ((peasycap->video_idle) || (peasycap->video_eof)) { + JOM(8, "returning -EIO because " + "%i=video_idle %i=video_eof\n", + peasycap->video_idle, peasycap->video_eof); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EIO; + } - if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; - } + if (copy_from_user(&v4l2_buffer, (void __user *)arg, + sizeof(struct v4l2_buffer))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - if (true == peasycap->offerfields) { - /*-----------------------------------------------------------*/ - /* - * IN ITS 50 "fps" MODE tvtime SEEMS ALWAYS TO REQUEST - * V4L2_FIELD_BOTTOM - */ - /*-----------------------------------------------------------*/ - if (V4L2_FIELD_TOP == v4l2_buffer.field) - JOM(8, "user wants V4L2_FIELD_TOP\n"); - else if (V4L2_FIELD_BOTTOM == v4l2_buffer.field) - JOM(8, "user wants V4L2_FIELD_BOTTOM\n"); - else if (V4L2_FIELD_ANY == v4l2_buffer.field) - JOM(8, "user wants V4L2_FIELD_ANY\n"); - else - JOM(8, "user wants V4L2_FIELD_...UNKNOWN: %i\n", - v4l2_buffer.field); - } + if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } - if (!peasycap->video_isoc_streaming) { - JOM(16, "returning -EIO because video urbs not streaming\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EIO; - } -/*---------------------------------------------------------------------------*/ -/* - * IF THE USER HAS PREVIOUSLY CALLED easycap_poll(), AS DETERMINED BY FINDING - * THE FLAG peasycap->polled SET, THERE MUST BE NO FURTHER WAIT HERE. IN THIS - * CASE, JUST CHOOSE THE FRAME INDICATED BY peasycap->frame_read - */ -/*---------------------------------------------------------------------------*/ + if (peasycap->offerfields) { + /*---------------------------------------------------*/ + /* + * IN ITS 50 "fps" MODE tvtime SEEMS ALWAYS TO REQUEST + * V4L2_FIELD_BOTTOM + */ + /*---------------------------------------------------*/ + if (V4L2_FIELD_TOP == v4l2_buffer.field) + JOM(8, "user wants V4L2_FIELD_TOP\n"); + else if (V4L2_FIELD_BOTTOM == v4l2_buffer.field) + JOM(8, "user wants V4L2_FIELD_BOTTOM\n"); + else if (V4L2_FIELD_ANY == v4l2_buffer.field) + JOM(8, "user wants V4L2_FIELD_ANY\n"); + else + JOM(8, "user wants V4L2_FIELD_...UNKNOWN: %i\n", + v4l2_buffer.field); + } - if (!peasycap->polled) { - do { - rcdq = easycap_dqbuf(peasycap, 0); - if (-EIO == rcdq) { - JOM(8, "returning -EIO because " - "dqbuf() returned -EIO\n"); - mutex_unlock(&easycapdc60_dongle[kd]. - mutex_video); - return -EIO; - } - } while (0 != rcdq); - } else { - if (peasycap->video_eof) { + if (!peasycap->video_isoc_streaming) { + JOM(16, "returning -EIO because video urbs not streaming\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EIO; } - } - if (V4L2_BUF_FLAG_DONE != peasycap->done[peasycap->frame_read]) { - JOM(8, "V4L2_BUF_FLAG_DONE != 0x%08X\n", - peasycap->done[peasycap->frame_read]); - } - peasycap->polled = 0; - - if (!(peasycap->isequence % 10)) { - for (i = 0; i < 179; i++) - peasycap->merit[i] = peasycap->merit[i+1]; - peasycap->merit[179] = merit_saa(peasycap->pusb_device); - j = 0; - for (i = 0; i < 180; i++) - j += peasycap->merit[i]; - if (90 < j) { - SAM("easycap driver shutting down " - "on condition blue\n"); - peasycap->video_eof = 1; peasycap->audio_eof = 1; + /*-------------------------------------------------------------------*/ + /* + * IF THE USER HAS PREVIOUSLY CALLED easycap_poll(), + * AS DETERMINED BY FINDING + * THE FLAG peasycap->polled SET, THERE MUST BE + * NO FURTHER WAIT HERE. IN THIS + * CASE, JUST CHOOSE THE FRAME INDICATED BY peasycap->frame_read + */ + /*-------------------------------------------------------------------*/ + + if (!peasycap->polled) { + do { + rcdq = easycap_dqbuf(peasycap, 0); + if (-EIO == rcdq) { + JOM(8, "returning -EIO because " + "dqbuf() returned -EIO\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EIO; + } + } while (0 != rcdq); + } else { + if (peasycap->video_eof) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EIO; + } + } + if (V4L2_BUF_FLAG_DONE != peasycap->done[peasycap->frame_read]) { + JOM(8, "V4L2_BUF_FLAG_DONE != 0x%08X\n", + peasycap->done[peasycap->frame_read]); + } + peasycap->polled = 0; + + if (!(peasycap->isequence % 10)) { + for (i = 0; i < 179; i++) + peasycap->merit[i] = peasycap->merit[i+1]; + peasycap->merit[179] = merit_saa(peasycap->pusb_device); + j = 0; + for (i = 0; i < 180; i++) + j += peasycap->merit[i]; + if (90 < j) { + SAM("easycap driver shutting down " + "on condition blue\n"); + peasycap->video_eof = 1; + peasycap->audio_eof = 1; + } } - } - v4l2_buffer.index = peasycap->frame_read; - v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - v4l2_buffer.bytesused = peasycap->frame_buffer_used; - v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE; - if (true == peasycap->offerfields) - v4l2_buffer.field = V4L2_FIELD_BOTTOM; - else - v4l2_buffer.field = V4L2_FIELD_NONE; - do_gettimeofday(&timeval); - timeval2 = timeval; - - v4l2_buffer.timestamp = timeval2; - v4l2_buffer.sequence = peasycap->isequence++; - v4l2_buffer.memory = V4L2_MEMORY_MMAP; - v4l2_buffer.m.offset = v4l2_buffer.index * FRAME_BUFFER_SIZE; - v4l2_buffer.length = FRAME_BUFFER_SIZE; - - JOM(16, " %10i=index\n", v4l2_buffer.index); - JOM(16, " 0x%08X=type\n", v4l2_buffer.type); - JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused); - JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags); - JOM(16, " %10i=field\n", v4l2_buffer.field); - JOM(16, " %10li=timestamp.tv_sec\n", - (long)v4l2_buffer.timestamp.tv_sec); - JOM(16, " %10li=timestamp.tv_usec\n", - (long)v4l2_buffer.timestamp.tv_usec); - JOM(16, " %10i=sequence\n", v4l2_buffer.sequence); - JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory); - JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset); - JOM(16, " %10i=length\n", v4l2_buffer.length); - - if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, - sizeof(struct v4l2_buffer))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + v4l2_buffer.index = peasycap->frame_read; + v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + v4l2_buffer.bytesused = peasycap->frame_buffer_used; + v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE; + if (true == peasycap->offerfields) + v4l2_buffer.field = V4L2_FIELD_BOTTOM; + else + v4l2_buffer.field = V4L2_FIELD_NONE; + do_gettimeofday(&timeval); + timeval2 = timeval; + + v4l2_buffer.timestamp = timeval2; + v4l2_buffer.sequence = peasycap->isequence++; + v4l2_buffer.memory = V4L2_MEMORY_MMAP; + v4l2_buffer.m.offset = v4l2_buffer.index * FRAME_BUFFER_SIZE; + v4l2_buffer.length = FRAME_BUFFER_SIZE; + + JOM(16, " %10i=index\n", v4l2_buffer.index); + JOM(16, " 0x%08X=type\n", v4l2_buffer.type); + JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused); + JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags); + JOM(16, " %10i=field\n", v4l2_buffer.field); + JOM(16, " %10li=timestamp.tv_sec\n", + (long)v4l2_buffer.timestamp.tv_sec); + JOM(16, " %10li=timestamp.tv_usec\n", + (long)v4l2_buffer.timestamp.tv_usec); + JOM(16, " %10i=sequence\n", v4l2_buffer.sequence); + JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory); + JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset); + JOM(16, " %10i=length\n", v4l2_buffer.length); + + if (copy_to_user((void __user *)arg, &v4l2_buffer, + sizeof(struct v4l2_buffer))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - input = peasycap->frame_buffer[peasycap->frame_read][0].input; - if (0x08 & input) { - JOM(8, "user is offered frame buffer %i, input %i\n", - peasycap->frame_read, (0x07 & input)); - } else { - JOM(8, "user is offered frame buffer %i\n", - peasycap->frame_read); - } - peasycap->frame_lock = 1; - JOM(8, "%i=peasycap->frame_fill\n", peasycap->frame_fill); - if (peasycap->frame_read == peasycap->frame_fill) { - if (peasycap->frame_lock) { - JOM(8, "WORRY: filling frame buffer " - "while offered to user\n"); + input = peasycap->frame_buffer[peasycap->frame_read][0].input; + if (0x08 & input) { + JOM(8, "user is offered frame buffer %i, input %i\n", + peasycap->frame_read, (0x07 & input)); + } else { + JOM(8, "user is offered frame buffer %i\n", + peasycap->frame_read); + } + peasycap->frame_lock = 1; + JOM(8, "%i=peasycap->frame_fill\n", peasycap->frame_fill); + if (peasycap->frame_read == peasycap->frame_fill) { + if (peasycap->frame_lock) { + JOM(8, "WORRY: filling frame buffer " + "while offered to user\n"); + } } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_STREAMON: { - int i; + case VIDIOC_STREAMON: { + int i; - JOM(8, "VIDIOC_STREAMON\n"); + JOM(8, "VIDIOC_STREAMON\n"); - peasycap->isequence = 0; - for (i = 0; i < 180; i++) - peasycap->merit[i] = 0; - if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; + peasycap->isequence = 0; + for (i = 0; i < 180; i++) + peasycap->merit[i] = 0; + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + submit_video_urbs(peasycap); + peasycap->video_idle = 0; + peasycap->audio_idle = 0; + peasycap->video_eof = 0; + peasycap->audio_eof = 0; + break; } - submit_video_urbs(peasycap); - peasycap->video_idle = 0; - peasycap->audio_idle = 0; - peasycap->video_eof = 0; - peasycap->audio_eof = 0; - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_STREAMOFF: { - JOM(8, "VIDIOC_STREAMOFF\n"); + case VIDIOC_STREAMOFF: { + JOM(8, "VIDIOC_STREAMOFF\n"); - if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - peasycap->video_idle = 1; - peasycap->audio_idle = 1; peasycap->timeval0.tv_sec = 0; + peasycap->video_idle = 1; + peasycap->audio_idle = 1; + peasycap->timeval0.tv_sec = 0; /*---------------------------------------------------------------------------*/ /* * IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO THE STREAMOFF COMMAND * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE. */ /*---------------------------------------------------------------------------*/ - JOM(8, "calling wake_up on wq_video and wq_audio\n"); - wake_up_interruptible(&(peasycap->wq_video)); + JOM(8, "calling wake_up on wq_video and wq_audio\n"); + wake_up_interruptible(&(peasycap->wq_video)); #ifdef CONFIG_EASYCAP_OSS - wake_up_interruptible(&(peasycap->wq_audio)); + wake_up_interruptible(&(peasycap->wq_audio)); #else - if (NULL != peasycap->psubstream) - snd_pcm_period_elapsed(peasycap->psubstream); + if (NULL != peasycap->psubstream) + snd_pcm_period_elapsed(peasycap->psubstream); #endif /* CONFIG_EASYCAP_OSS */ /*---------------------------------------------------------------------------*/ - break; -} + break; + } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_G_PARM: { - struct v4l2_streamparm *pv4l2_streamparm; + case VIDIOC_G_PARM: { + struct v4l2_streamparm *pv4l2_streamparm; - JOM(8, "VIDIOC_G_PARM\n"); - pv4l2_streamparm = kzalloc(sizeof(struct v4l2_streamparm), GFP_KERNEL); - if (!pv4l2_streamparm) { - SAM("ERROR: out of memory\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -ENOMEM; - } - if (0 != copy_from_user(pv4l2_streamparm, (void __user *)arg, - sizeof(struct v4l2_streamparm))) { - kfree(pv4l2_streamparm); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } + JOM(8, "VIDIOC_G_PARM\n"); + pv4l2_streamparm = kzalloc(sizeof(struct v4l2_streamparm), GFP_KERNEL); + if (!pv4l2_streamparm) { + SAM("ERROR: out of memory\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ENOMEM; + } + if (copy_from_user(pv4l2_streamparm, + (void __user *)arg, sizeof(struct v4l2_streamparm))) { + kfree(pv4l2_streamparm); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - if (pv4l2_streamparm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - kfree(pv4l2_streamparm); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; - } - pv4l2_streamparm->parm.capture.capability = 0; - pv4l2_streamparm->parm.capture.capturemode = 0; - pv4l2_streamparm->parm.capture.timeperframe.numerator = 1; + if (pv4l2_streamparm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + kfree(pv4l2_streamparm); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + pv4l2_streamparm->parm.capture.capability = 0; + pv4l2_streamparm->parm.capture.capturemode = 0; + pv4l2_streamparm->parm.capture.timeperframe.numerator = 1; - if (peasycap->fps) { - pv4l2_streamparm->parm.capture.timeperframe. - denominator = peasycap->fps; - } else { - if (true == peasycap->ntsc) { + if (peasycap->fps) { pv4l2_streamparm->parm.capture.timeperframe. - denominator = 30; + denominator = peasycap->fps; } else { - pv4l2_streamparm->parm.capture.timeperframe. - denominator = 25; + if (true == peasycap->ntsc) { + pv4l2_streamparm->parm.capture.timeperframe. + denominator = 30; + } else { + pv4l2_streamparm->parm.capture.timeperframe. + denominator = 25; + } } - } - pv4l2_streamparm->parm.capture.readbuffers = - peasycap->frame_buffer_many; - pv4l2_streamparm->parm.capture.extendedmode = 0; - if (0 != copy_to_user((void __user *)arg, pv4l2_streamparm, - sizeof(struct v4l2_streamparm))) { + pv4l2_streamparm->parm.capture.readbuffers = + peasycap->frame_buffer_many; + pv4l2_streamparm->parm.capture.extendedmode = 0; + if (copy_to_user((void __user *)arg, + pv4l2_streamparm, + sizeof(struct v4l2_streamparm))) { + kfree(pv4l2_streamparm); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } kfree(pv4l2_streamparm); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; + break; } - kfree(pv4l2_streamparm); - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_S_PARM: { - JOM(8, "VIDIOC_S_PARM unsupported\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; -} + case VIDIOC_S_PARM: { + JOM(8, "VIDIOC_S_PARM unsupported\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_G_AUDIO: { - JOM(8, "VIDIOC_G_AUDIO unsupported\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; -} + case VIDIOC_G_AUDIO: { + JOM(8, "VIDIOC_G_AUDIO unsupported\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_S_AUDIO: { - JOM(8, "VIDIOC_S_AUDIO unsupported\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; -} + case VIDIOC_S_AUDIO: { + JOM(8, "VIDIOC_S_AUDIO unsupported\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_S_TUNER: { - JOM(8, "VIDIOC_S_TUNER unsupported\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; -} + case VIDIOC_S_TUNER: { + JOM(8, "VIDIOC_S_TUNER unsupported\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_G_FBUF: -case VIDIOC_S_FBUF: -case VIDIOC_OVERLAY: { - JOM(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; -} + case VIDIOC_G_FBUF: + case VIDIOC_S_FBUF: + case VIDIOC_OVERLAY: { + JOM(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_G_TUNER: { - JOM(8, "VIDIOC_G_TUNER unsupported\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; -} -case VIDIOC_G_FREQUENCY: -case VIDIOC_S_FREQUENCY: { - JOM(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EINVAL; -} + case VIDIOC_G_TUNER: { + JOM(8, "VIDIOC_G_TUNER unsupported\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + case VIDIOC_G_FREQUENCY: + case VIDIOC_S_FREQUENCY: { + JOM(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -default: { - JOM(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd); + default: { + JOM(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ENOIOCTLCMD; + } + } mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -ENOIOCTLCMD; -} -} -mutex_unlock(&easycapdc60_dongle[kd].mutex_video); -JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd); -return 0; + JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd); + return 0; } /*****************************************************************************/ -- cgit v1.2.3 From 8ba5366adacef220b6ce16dca777600433a22a42 Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Thu, 24 Feb 2011 23:36:01 +0000 Subject: sfc: Reduce size of efx_rx_buffer by unionising skb and page [bwh: Forward-ported to net-next-2.6.] Signed-off-by: Ben Hutchings --- drivers/net/sfc/net_driver.h | 8 +++- drivers/net/sfc/rx.c | 96 +++++++++++++++++++++----------------------- 2 files changed, 51 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 15b9068e5b87..59ff32ac7ec6 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -216,13 +216,17 @@ struct efx_tx_queue { * If both this and skb are %NULL, the buffer slot is currently free. * @data: Pointer to ethernet header * @len: Buffer length, in bytes. + * @is_page: Indicates if @page is valid. If false, @skb is valid. */ struct efx_rx_buffer { dma_addr_t dma_addr; - struct sk_buff *skb; - struct page *page; + union { + struct sk_buff *skb; + struct page *page; + } u; char *data; unsigned int len; + bool is_page; }; /** diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 3925fd621177..bcbd2ec2d92a 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -129,6 +129,7 @@ static int efx_init_rx_buffers_skb(struct efx_rx_queue *rx_queue) struct efx_nic *efx = rx_queue->efx; struct net_device *net_dev = efx->net_dev; struct efx_rx_buffer *rx_buf; + struct sk_buff *skb; int skb_len = efx->rx_buffer_len; unsigned index, count; @@ -136,24 +137,24 @@ static int efx_init_rx_buffers_skb(struct efx_rx_queue *rx_queue) index = rx_queue->added_count & rx_queue->ptr_mask; rx_buf = efx_rx_buffer(rx_queue, index); - rx_buf->skb = netdev_alloc_skb(net_dev, skb_len); - if (unlikely(!rx_buf->skb)) + rx_buf->u.skb = skb = netdev_alloc_skb(net_dev, skb_len); + if (unlikely(!skb)) return -ENOMEM; - rx_buf->page = NULL; /* Adjust the SKB for padding and checksum */ - skb_reserve(rx_buf->skb, NET_IP_ALIGN); + skb_reserve(skb, NET_IP_ALIGN); + rx_buf->data = (char *)skb->data; rx_buf->len = skb_len - NET_IP_ALIGN; - rx_buf->data = (char *)rx_buf->skb->data; - rx_buf->skb->ip_summed = CHECKSUM_UNNECESSARY; + rx_buf->is_page = false; + skb->ip_summed = CHECKSUM_UNNECESSARY; rx_buf->dma_addr = pci_map_single(efx->pci_dev, rx_buf->data, rx_buf->len, PCI_DMA_FROMDEVICE); if (unlikely(pci_dma_mapping_error(efx->pci_dev, rx_buf->dma_addr))) { - dev_kfree_skb_any(rx_buf->skb); - rx_buf->skb = NULL; + dev_kfree_skb_any(skb); + rx_buf->u.skb = NULL; return -EIO; } @@ -211,10 +212,10 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) index = rx_queue->added_count & rx_queue->ptr_mask; rx_buf = efx_rx_buffer(rx_queue, index); rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN; - rx_buf->skb = NULL; - rx_buf->page = page; + rx_buf->u.page = page; rx_buf->data = page_addr + EFX_PAGE_IP_ALIGN; rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN; + rx_buf->is_page = true; ++rx_queue->added_count; ++rx_queue->alloc_page_count; ++state->refcnt; @@ -235,19 +236,17 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) static void efx_unmap_rx_buffer(struct efx_nic *efx, struct efx_rx_buffer *rx_buf) { - if (rx_buf->page) { + if (rx_buf->is_page && rx_buf->u.page) { struct efx_rx_page_state *state; - EFX_BUG_ON_PARANOID(rx_buf->skb); - - state = page_address(rx_buf->page); + state = page_address(rx_buf->u.page); if (--state->refcnt == 0) { pci_unmap_page(efx->pci_dev, state->dma_addr, efx_rx_buf_size(efx), PCI_DMA_FROMDEVICE); } - } else if (likely(rx_buf->skb)) { + } else if (!rx_buf->is_page && rx_buf->u.skb) { pci_unmap_single(efx->pci_dev, rx_buf->dma_addr, rx_buf->len, PCI_DMA_FROMDEVICE); } @@ -256,12 +255,12 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx, static void efx_free_rx_buffer(struct efx_nic *efx, struct efx_rx_buffer *rx_buf) { - if (rx_buf->page) { - __free_pages(rx_buf->page, efx->rx_buffer_order); - rx_buf->page = NULL; - } else if (likely(rx_buf->skb)) { - dev_kfree_skb_any(rx_buf->skb); - rx_buf->skb = NULL; + if (rx_buf->is_page && rx_buf->u.page) { + __free_pages(rx_buf->u.page, efx->rx_buffer_order); + rx_buf->u.page = NULL; + } else if (!rx_buf->is_page && rx_buf->u.skb) { + dev_kfree_skb_any(rx_buf->u.skb); + rx_buf->u.skb = NULL; } } @@ -277,7 +276,7 @@ static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue, static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue, struct efx_rx_buffer *rx_buf) { - struct efx_rx_page_state *state = page_address(rx_buf->page); + struct efx_rx_page_state *state = page_address(rx_buf->u.page); struct efx_rx_buffer *new_buf; unsigned fill_level, index; @@ -292,16 +291,16 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue, } ++state->refcnt; - get_page(rx_buf->page); + get_page(rx_buf->u.page); index = rx_queue->added_count & rx_queue->ptr_mask; new_buf = efx_rx_buffer(rx_queue, index); new_buf->dma_addr = rx_buf->dma_addr ^ (PAGE_SIZE >> 1); - new_buf->skb = NULL; - new_buf->page = rx_buf->page; + new_buf->u.page = rx_buf->u.page; new_buf->data = (void *) ((__force unsigned long)rx_buf->data ^ (PAGE_SIZE >> 1)); new_buf->len = rx_buf->len; + new_buf->is_page = true; ++rx_queue->added_count; } @@ -315,16 +314,15 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel, struct efx_rx_buffer *new_buf; unsigned index; - if (rx_buf->page != NULL && efx->rx_buffer_len <= EFX_RX_HALF_PAGE && - page_count(rx_buf->page) == 1) + if (rx_buf->is_page && efx->rx_buffer_len <= EFX_RX_HALF_PAGE && + page_count(rx_buf->u.page) == 1) efx_resurrect_rx_buffer(rx_queue, rx_buf); index = rx_queue->added_count & rx_queue->ptr_mask; new_buf = efx_rx_buffer(rx_queue, index); memcpy(new_buf, rx_buf, sizeof(*new_buf)); - rx_buf->page = NULL; - rx_buf->skb = NULL; + rx_buf->u.page = NULL; ++rx_queue->added_count; } @@ -428,7 +426,7 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, * data at the end of the skb will be trashed. So * we have no choice but to leak the fragment. */ - *leak_packet = (rx_buf->skb != NULL); + *leak_packet = !rx_buf->is_page; efx_schedule_reset(efx, RESET_TYPE_RX_RECOVERY); } else { if (net_ratelimit()) @@ -454,13 +452,12 @@ static void efx_rx_packet_gro(struct efx_channel *channel, gro_result_t gro_result; /* Pass the skb/page into the GRO engine */ - if (rx_buf->page) { + if (rx_buf->is_page) { struct efx_nic *efx = channel->efx; - struct page *page = rx_buf->page; + struct page *page = rx_buf->u.page; struct sk_buff *skb; - EFX_BUG_ON_PARANOID(rx_buf->skb); - rx_buf->page = NULL; + rx_buf->u.page = NULL; skb = napi_get_frags(napi); if (!skb) { @@ -487,11 +484,10 @@ static void efx_rx_packet_gro(struct efx_channel *channel, gro_result = napi_gro_frags(napi); } else { - struct sk_buff *skb = rx_buf->skb; + struct sk_buff *skb = rx_buf->u.skb; - EFX_BUG_ON_PARANOID(!skb); EFX_BUG_ON_PARANOID(!checksummed); - rx_buf->skb = NULL; + rx_buf->u.skb = NULL; gro_result = napi_gro_receive(napi, skb); } @@ -514,8 +510,6 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, rx_buf = efx_rx_buffer(rx_queue, index); EFX_BUG_ON_PARANOID(!rx_buf->data); - EFX_BUG_ON_PARANOID(rx_buf->skb && rx_buf->page); - EFX_BUG_ON_PARANOID(!(rx_buf->skb || rx_buf->page)); /* This allows the refill path to post another buffer. * EFX_RXD_HEAD_ROOM ensures that the slot we are using @@ -587,32 +581,32 @@ void __efx_rx_packet(struct efx_channel *channel, return; } - if (rx_buf->skb) { - prefetch(skb_shinfo(rx_buf->skb)); + if (!rx_buf->is_page) { + skb = rx_buf->u.skb; + + prefetch(skb_shinfo(skb)); - skb_reserve(rx_buf->skb, efx->type->rx_buffer_hash_size); - skb_put(rx_buf->skb, rx_buf->len); + skb_reserve(skb, efx->type->rx_buffer_hash_size); + skb_put(skb, rx_buf->len); if (efx->net_dev->features & NETIF_F_RXHASH) - rx_buf->skb->rxhash = efx_rx_buf_hash(rx_buf); + skb->rxhash = efx_rx_buf_hash(rx_buf); /* Move past the ethernet header. rx_buf->data still points * at the ethernet header */ - rx_buf->skb->protocol = eth_type_trans(rx_buf->skb, - efx->net_dev); + skb->protocol = eth_type_trans(skb, efx->net_dev); - skb_record_rx_queue(rx_buf->skb, channel->channel); + skb_record_rx_queue(skb, channel->channel); } - if (likely(checksummed || rx_buf->page)) { + if (likely(checksummed || rx_buf->is_page)) { efx_rx_packet_gro(channel, rx_buf, checksummed); return; } /* We now own the SKB */ - skb = rx_buf->skb; - rx_buf->skb = NULL; - EFX_BUG_ON_PARANOID(!skb); + skb = rx_buf->u.skb; + rx_buf->u.skb = NULL; /* Set the SKB flags */ skb_checksum_none_assert(skb); -- cgit v1.2.3 From a526f140b22131376b0e49577210e6af73e2b89f Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Thu, 24 Feb 2011 23:45:16 +0000 Subject: sfc: Reduce size of efx_rx_buffer further by removing data member Instead calculate the KVA of receive data. It's not like it's a hard sum. [bwh: Fixed to work with GRO.] Signed-off-by: Ben Hutchings --- drivers/net/sfc/net_driver.h | 2 -- drivers/net/sfc/rx.c | 50 +++++++++++++++++++++++++------------------- 2 files changed, 28 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 59ff32ac7ec6..5b001c1c73d4 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -214,7 +214,6 @@ struct efx_tx_queue { * If both this and page are %NULL, the buffer slot is currently free. * @page: The associated page buffer, if any. * If both this and skb are %NULL, the buffer slot is currently free. - * @data: Pointer to ethernet header * @len: Buffer length, in bytes. * @is_page: Indicates if @page is valid. If false, @skb is valid. */ @@ -224,7 +223,6 @@ struct efx_rx_buffer { struct sk_buff *skb; struct page *page; } u; - char *data; unsigned int len; bool is_page; }; diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index bcbd2ec2d92a..81bec873e9d3 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -89,24 +89,37 @@ static unsigned int rx_refill_limit = 95; */ #define EFX_RXD_HEAD_ROOM 2 -static inline unsigned int efx_rx_buf_offset(struct efx_rx_buffer *buf) +/* Offset of ethernet header within page */ +static inline unsigned int efx_rx_buf_offset(struct efx_nic *efx, + struct efx_rx_buffer *buf) { /* Offset is always within one page, so we don't need to consider * the page order. */ - return (__force unsigned long) buf->data & (PAGE_SIZE - 1); + return (((__force unsigned long) buf->dma_addr & (PAGE_SIZE - 1)) + + efx->type->rx_buffer_hash_size); } static inline unsigned int efx_rx_buf_size(struct efx_nic *efx) { return PAGE_SIZE << efx->rx_buffer_order; } -static inline u32 efx_rx_buf_hash(struct efx_rx_buffer *buf) +static u8 *efx_rx_buf_eh(struct efx_nic *efx, struct efx_rx_buffer *buf) { + if (buf->is_page) + return page_address(buf->u.page) + efx_rx_buf_offset(efx, buf); + else + return ((u8 *)buf->u.skb->data + + efx->type->rx_buffer_hash_size); +} + +static inline u32 efx_rx_buf_hash(const u8 *eh) +{ + /* The ethernet header is always directly after any hash. */ #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) || NET_IP_ALIGN % 4 == 0 - return __le32_to_cpup((const __le32 *)(buf->data - 4)); + return __le32_to_cpup((const __le32 *)(eh - 4)); #else - const u8 *data = (const u8 *)(buf->data - 4); + const u8 *data = eh - 4; return ((u32)data[0] | (u32)data[1] << 8 | (u32)data[2] << 16 | @@ -143,13 +156,12 @@ static int efx_init_rx_buffers_skb(struct efx_rx_queue *rx_queue) /* Adjust the SKB for padding and checksum */ skb_reserve(skb, NET_IP_ALIGN); - rx_buf->data = (char *)skb->data; rx_buf->len = skb_len - NET_IP_ALIGN; rx_buf->is_page = false; skb->ip_summed = CHECKSUM_UNNECESSARY; rx_buf->dma_addr = pci_map_single(efx->pci_dev, - rx_buf->data, rx_buf->len, + skb->data, rx_buf->len, PCI_DMA_FROMDEVICE); if (unlikely(pci_dma_mapping_error(efx->pci_dev, rx_buf->dma_addr))) { @@ -213,7 +225,6 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) rx_buf = efx_rx_buffer(rx_queue, index); rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN; rx_buf->u.page = page; - rx_buf->data = page_addr + EFX_PAGE_IP_ALIGN; rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN; rx_buf->is_page = true; ++rx_queue->added_count; @@ -297,8 +308,6 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue, new_buf = efx_rx_buffer(rx_queue, index); new_buf->dma_addr = rx_buf->dma_addr ^ (PAGE_SIZE >> 1); new_buf->u.page = rx_buf->u.page; - new_buf->data = (void *) - ((__force unsigned long)rx_buf->data ^ (PAGE_SIZE >> 1)); new_buf->len = rx_buf->len; new_buf->is_page = true; ++rx_queue->added_count; @@ -446,7 +455,7 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, */ static void efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf, - bool checksummed) + const u8 *eh, bool checksummed) { struct napi_struct *napi = &channel->napi_str; gro_result_t gro_result; @@ -466,11 +475,11 @@ static void efx_rx_packet_gro(struct efx_channel *channel, } if (efx->net_dev->features & NETIF_F_RXHASH) - skb->rxhash = efx_rx_buf_hash(rx_buf); + skb->rxhash = efx_rx_buf_hash(eh); skb_shinfo(skb)->frags[0].page = page; skb_shinfo(skb)->frags[0].page_offset = - efx_rx_buf_offset(rx_buf); + efx_rx_buf_offset(efx, rx_buf); skb_shinfo(skb)->frags[0].size = rx_buf->len; skb_shinfo(skb)->nr_frags = 1; @@ -509,7 +518,6 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, bool leak_packet = false; rx_buf = efx_rx_buffer(rx_queue, index); - EFX_BUG_ON_PARANOID(!rx_buf->data); /* This allows the refill path to post another buffer. * EFX_RXD_HEAD_ROOM ensures that the slot we are using @@ -548,12 +556,12 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, /* Prefetch nice and early so data will (hopefully) be in cache by * the time we look at it. */ - prefetch(rx_buf->data); + prefetch(efx_rx_buf_eh(efx, rx_buf)); /* Pipeline receives so that we give time for packet headers to be * prefetched into cache. */ - rx_buf->len = len; + rx_buf->len = len - efx->type->rx_buffer_hash_size; out: if (channel->rx_pkt) __efx_rx_packet(channel, @@ -568,15 +576,13 @@ void __efx_rx_packet(struct efx_channel *channel, { struct efx_nic *efx = channel->efx; struct sk_buff *skb; - - rx_buf->data += efx->type->rx_buffer_hash_size; - rx_buf->len -= efx->type->rx_buffer_hash_size; + u8 *eh = efx_rx_buf_eh(efx, rx_buf); /* If we're in loopback test, then pass the packet directly to the * loopback layer, and free the rx_buf here */ if (unlikely(efx->loopback_selftest)) { - efx_loopback_rx_packet(efx, rx_buf->data, rx_buf->len); + efx_loopback_rx_packet(efx, eh, rx_buf->len); efx_free_rx_buffer(efx, rx_buf); return; } @@ -590,7 +596,7 @@ void __efx_rx_packet(struct efx_channel *channel, skb_put(skb, rx_buf->len); if (efx->net_dev->features & NETIF_F_RXHASH) - skb->rxhash = efx_rx_buf_hash(rx_buf); + skb->rxhash = efx_rx_buf_hash(eh); /* Move past the ethernet header. rx_buf->data still points * at the ethernet header */ @@ -600,7 +606,7 @@ void __efx_rx_packet(struct efx_channel *channel, } if (likely(checksummed || rx_buf->is_page)) { - efx_rx_packet_gro(channel, rx_buf, checksummed); + efx_rx_packet_gro(channel, rx_buf, eh, checksummed); return; } -- cgit v1.2.3 From e5f0fd278084d79d6be0920043519749374b0507 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 24 Feb 2011 23:57:47 +0000 Subject: sfc: Read MC firmware version when requested through ethtool We currently make no use of siena_nic_data::fw_{version,build} except to format the firmware version for ethtool_get_drvinfo(). Since we only read the version at start of day, this information is incorrect after an MC firmware update. Remove the cached version information and read it via MCDI whenever it is requested. Signed-off-by: Ben Hutchings --- drivers/net/sfc/ethtool.c | 4 ++-- drivers/net/sfc/mcdi.c | 21 ++++++--------------- drivers/net/sfc/mcdi.h | 2 +- drivers/net/sfc/nic.h | 6 ------ drivers/net/sfc/siena.c | 17 ----------------- 5 files changed, 9 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 272cfe724e1b..3e974b11db0e 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -237,8 +237,8 @@ static void efx_ethtool_get_drvinfo(struct net_device *net_dev, strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); strlcpy(info->version, EFX_DRIVER_VERSION, sizeof(info->version)); if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0) - siena_print_fwver(efx, info->fw_version, - sizeof(info->fw_version)); + efx_mcdi_print_fwver(efx, info->fw_version, + sizeof(info->fw_version)); strlcpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info)); } diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c index b716e827b291..88e786b11ed1 100644 --- a/drivers/net/sfc/mcdi.c +++ b/drivers/net/sfc/mcdi.c @@ -602,7 +602,7 @@ void efx_mcdi_process_event(struct efx_channel *channel, ************************************************************************** */ -int efx_mcdi_fwver(struct efx_nic *efx, u64 *version, u32 *build) +void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len) { u8 outbuf[ALIGN(MC_CMD_GET_VERSION_V1_OUT_LEN, 4)]; size_t outlength; @@ -616,29 +616,20 @@ int efx_mcdi_fwver(struct efx_nic *efx, u64 *version, u32 *build) if (rc) goto fail; - if (outlength == MC_CMD_GET_VERSION_V0_OUT_LEN) { - *version = 0; - *build = MCDI_DWORD(outbuf, GET_VERSION_OUT_FIRMWARE); - return 0; - } - if (outlength < MC_CMD_GET_VERSION_V1_OUT_LEN) { rc = -EIO; goto fail; } ver_words = (__le16 *)MCDI_PTR(outbuf, GET_VERSION_OUT_VERSION); - *version = (((u64)le16_to_cpu(ver_words[0]) << 48) | - ((u64)le16_to_cpu(ver_words[1]) << 32) | - ((u64)le16_to_cpu(ver_words[2]) << 16) | - le16_to_cpu(ver_words[3])); - *build = MCDI_DWORD(outbuf, GET_VERSION_OUT_FIRMWARE); - - return 0; + snprintf(buf, len, "%u.%u.%u.%u", + le16_to_cpu(ver_words[0]), le16_to_cpu(ver_words[1]), + le16_to_cpu(ver_words[2]), le16_to_cpu(ver_words[3])); + return; fail: netif_err(efx, probe, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); - return rc; + buf[0] = 0; } int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, diff --git a/drivers/net/sfc/mcdi.h b/drivers/net/sfc/mcdi.h index c792f1d65e48..9bac250143d9 100644 --- a/drivers/net/sfc/mcdi.h +++ b/drivers/net/sfc/mcdi.h @@ -93,7 +93,7 @@ extern void efx_mcdi_process_event(struct efx_channel *channel, #define MCDI_EVENT_FIELD(_ev, _field) \ EFX_QWORD_FIELD(_ev, MCDI_EVENT_ ## _field) -extern int efx_mcdi_fwver(struct efx_nic *efx, u64 *version, u32 *build); +extern void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len); extern int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, bool *was_attached_out); extern int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, diff --git a/drivers/net/sfc/nic.h b/drivers/net/sfc/nic.h index eb0586925b51..17407eac0030 100644 --- a/drivers/net/sfc/nic.h +++ b/drivers/net/sfc/nic.h @@ -142,20 +142,14 @@ static inline struct falcon_board *falcon_board(struct efx_nic *efx) /** * struct siena_nic_data - Siena NIC state - * @fw_version: Management controller firmware version - * @fw_build: Firmware build number * @mcdi: Management-Controller-to-Driver Interface * @wol_filter_id: Wake-on-LAN packet filter id */ struct siena_nic_data { - u64 fw_version; - u32 fw_build; struct efx_mcdi_iface mcdi; int wol_filter_id; }; -extern void siena_print_fwver(struct efx_nic *efx, char *buf, size_t len); - extern struct efx_nic_type falcon_a1_nic_type; extern struct efx_nic_type falcon_b0_nic_type; extern struct efx_nic_type siena_a0_nic_type; diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index bf8456176443..07b59a8c9a4c 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -227,13 +227,6 @@ static int siena_probe_nic(struct efx_nic *efx) if (rc) goto fail1; - rc = efx_mcdi_fwver(efx, &nic_data->fw_version, &nic_data->fw_build); - if (rc) { - netif_err(efx, probe, efx->net_dev, - "Failed to read MCPU firmware version - rc %d\n", rc); - goto fail1; /* MCPU absent? */ - } - /* Let the BMC know that the driver is now in charge of link and * filter settings. We must do this before we reset the NIC */ rc = efx_mcdi_drv_attach(efx, true, &already_attached); @@ -514,16 +507,6 @@ static void siena_stop_nic_stats(struct efx_nic *efx) efx_mcdi_mac_stats(efx, efx->stats_buffer.dma_addr, 0, 0, 0); } -void siena_print_fwver(struct efx_nic *efx, char *buf, size_t len) -{ - struct siena_nic_data *nic_data = efx->nic_data; - snprintf(buf, len, "%u.%u.%u.%u", - (unsigned int)(nic_data->fw_version >> 48), - (unsigned int)(nic_data->fw_version >> 32 & 0xffff), - (unsigned int)(nic_data->fw_version >> 16 & 0xffff), - (unsigned int)(nic_data->fw_version & 0xffff)); -} - /************************************************************************** * * Wake on LAN -- cgit v1.2.3 From a461103ba2e22cbb70771588b36f40df39a50f46 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 24 Feb 2011 23:59:15 +0000 Subject: sfc: Do not read STAT1.FAULT in efx_mdio_check_mmd() This field does not exist in all MMDs we want to check, and all callers allow it to be set (fault_fatal = 0). Remove the loopback condition, as STAT2.DEVPRST should be valid regardless of any fault. Signed-off-by: Ben Hutchings --- drivers/net/sfc/mdio_10g.c | 32 +++++--------------------------- drivers/net/sfc/mdio_10g.h | 3 +-- drivers/net/sfc/tenxpress.c | 2 +- drivers/net/sfc/txc43128_phy.c | 2 +- 4 files changed, 8 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c index 56b0266b441f..6e82e5ba583a 100644 --- a/drivers/net/sfc/mdio_10g.c +++ b/drivers/net/sfc/mdio_10g.c @@ -51,13 +51,10 @@ int efx_mdio_reset_mmd(struct efx_nic *port, int mmd, return spins ? spins : -ETIMEDOUT; } -static int efx_mdio_check_mmd(struct efx_nic *efx, int mmd, int fault_fatal) +static int efx_mdio_check_mmd(struct efx_nic *efx, int mmd) { int status; - if (LOOPBACK_INTERNAL(efx)) - return 0; - if (mmd != MDIO_MMD_AN) { /* Read MMD STATUS2 to check it is responding. */ status = efx_mdio_read(efx, mmd, MDIO_STAT2); @@ -68,20 +65,6 @@ static int efx_mdio_check_mmd(struct efx_nic *efx, int mmd, int fault_fatal) } } - /* Read MMD STATUS 1 to check for fault. */ - status = efx_mdio_read(efx, mmd, MDIO_STAT1); - if (status & MDIO_STAT1_FAULT) { - if (fault_fatal) { - netif_err(efx, hw, efx->net_dev, - "PHY MMD %d reporting fatal" - " fault: status %x\n", mmd, status); - return -EIO; - } else { - netif_dbg(efx, hw, efx->net_dev, - "PHY MMD %d reporting status" - " %x (expected)\n", mmd, status); - } - } return 0; } @@ -130,8 +113,7 @@ int efx_mdio_wait_reset_mmds(struct efx_nic *efx, unsigned int mmd_mask) return rc; } -int efx_mdio_check_mmds(struct efx_nic *efx, - unsigned int mmd_mask, unsigned int fatal_mask) +int efx_mdio_check_mmds(struct efx_nic *efx, unsigned int mmd_mask) { int mmd = 0, probe_mmd, devs1, devs2; u32 devices; @@ -161,13 +143,9 @@ int efx_mdio_check_mmds(struct efx_nic *efx, /* Check all required MMDs are responding and happy. */ while (mmd_mask) { - if (mmd_mask & 1) { - int fault_fatal = fatal_mask & 1; - if (efx_mdio_check_mmd(efx, mmd, fault_fatal)) - return -EIO; - } + if ((mmd_mask & 1) && efx_mdio_check_mmd(efx, mmd)) + return -EIO; mmd_mask = mmd_mask >> 1; - fatal_mask = fatal_mask >> 1; mmd++; } @@ -337,7 +315,7 @@ int efx_mdio_test_alive(struct efx_nic *efx) "no MDIO PHY present with ID %d\n", efx->mdio.prtad); rc = -EINVAL; } else { - rc = efx_mdio_check_mmds(efx, efx->mdio.mmds, 0); + rc = efx_mdio_check_mmds(efx, efx->mdio.mmds); } mutex_unlock(&efx->mac_lock); diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h index 75791d3d4963..44c5dee52107 100644 --- a/drivers/net/sfc/mdio_10g.h +++ b/drivers/net/sfc/mdio_10g.h @@ -68,8 +68,7 @@ extern int efx_mdio_reset_mmd(struct efx_nic *efx, int mmd, int spins, int spintime); /* As efx_mdio_check_mmd but for multiple MMDs */ -int efx_mdio_check_mmds(struct efx_nic *efx, - unsigned int mmd_mask, unsigned int fatal_mask); +int efx_mdio_check_mmds(struct efx_nic *efx, unsigned int mmd_mask); /* Check the link status of specified mmds in bit mask */ extern bool efx_mdio_links_ok(struct efx_nic *efx, unsigned int mmd_mask); diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index f102912eba91..581911f70441 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -196,7 +196,7 @@ static int tenxpress_phy_init(struct efx_nic *efx) if (rc < 0) return rc; - rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); + rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS); if (rc < 0) return rc; } diff --git a/drivers/net/sfc/txc43128_phy.c b/drivers/net/sfc/txc43128_phy.c index 351794a79215..4e2b48a8f5c4 100644 --- a/drivers/net/sfc/txc43128_phy.c +++ b/drivers/net/sfc/txc43128_phy.c @@ -193,7 +193,7 @@ static int txc_reset_phy(struct efx_nic *efx) goto fail; /* Check that all the MMDs we expect are present and responding. */ - rc = efx_mdio_check_mmds(efx, TXC_REQUIRED_DEVS, 0); + rc = efx_mdio_check_mmds(efx, TXC_REQUIRED_DEVS); if (rc < 0) goto fail; -- cgit v1.2.3 From 0a6f40c66ba388e6349a11bea146955716c4d492 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 25 Feb 2011 00:01:34 +0000 Subject: sfc: Update copyright dates Signed-off-by: Ben Hutchings --- drivers/net/sfc/efx.c | 2 +- drivers/net/sfc/efx.h | 2 +- drivers/net/sfc/ethtool.c | 2 +- drivers/net/sfc/falcon.c | 2 +- drivers/net/sfc/falcon_boards.c | 2 +- drivers/net/sfc/falcon_xmac.c | 2 +- drivers/net/sfc/io.h | 2 +- drivers/net/sfc/mcdi.c | 2 +- drivers/net/sfc/mcdi.h | 2 +- drivers/net/sfc/mcdi_mac.c | 2 +- drivers/net/sfc/mcdi_pcol.h | 2 +- drivers/net/sfc/mcdi_phy.c | 2 +- drivers/net/sfc/mdio_10g.c | 2 +- drivers/net/sfc/mdio_10g.h | 2 +- drivers/net/sfc/mtd.c | 2 +- drivers/net/sfc/net_driver.h | 2 +- drivers/net/sfc/nic.c | 2 +- drivers/net/sfc/nic.h | 2 +- drivers/net/sfc/phy.h | 2 +- drivers/net/sfc/qt202x_phy.c | 2 +- drivers/net/sfc/regs.h | 2 +- drivers/net/sfc/rx.c | 2 +- drivers/net/sfc/selftest.c | 2 +- drivers/net/sfc/selftest.h | 2 +- drivers/net/sfc/siena.c | 2 +- drivers/net/sfc/spi.h | 2 +- drivers/net/sfc/tenxpress.c | 2 +- drivers/net/sfc/tx.c | 2 +- drivers/net/sfc/txc43128_phy.c | 2 +- drivers/net/sfc/workarounds.h | 2 +- 30 files changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 35b7bc52a2d1..d563049859a8 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2005-2009 Solarflare Communications Inc. + * Copyright 2005-2011 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index cbce62b9c996..3d83a1f74fef 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2006-2009 Solarflare Communications Inc. + * Copyright 2006-2010 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 3e974b11db0e..52fa661aede9 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2006-2009 Solarflare Communications Inc. + * Copyright 2006-2010 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 61ddd2c6e750..87481a6df42c 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2006-2009 Solarflare Communications Inc. + * Copyright 2006-2010 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c index 2dd16f0b3ced..b9cc846811d6 100644 --- a/drivers/net/sfc/falcon_boards.c +++ b/drivers/net/sfc/falcon_boards.c @@ -1,6 +1,6 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards - * Copyright 2007-2009 Solarflare Communications Inc. + * Copyright 2007-2010 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c index b49e84394641..2c9ee5db3bf7 100644 --- a/drivers/net/sfc/falcon_xmac.c +++ b/drivers/net/sfc/falcon_xmac.c @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2006-2009 Solarflare Communications Inc. + * Copyright 2006-2010 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/io.h b/drivers/net/sfc/io.h index 6da4ae20a039..dc45110b2456 100644 --- a/drivers/net/sfc/io.h +++ b/drivers/net/sfc/io.h @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2006-2009 Solarflare Communications Inc. + * Copyright 2006-2010 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c index 88e786b11ed1..8bba8955f310 100644 --- a/drivers/net/sfc/mcdi.c +++ b/drivers/net/sfc/mcdi.c @@ -1,6 +1,6 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards - * Copyright 2008-2009 Solarflare Communications Inc. + * Copyright 2008-2011 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/mcdi.h b/drivers/net/sfc/mcdi.h index 9bac250143d9..aced2a7856fc 100644 --- a/drivers/net/sfc/mcdi.h +++ b/drivers/net/sfc/mcdi.h @@ -1,6 +1,6 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards - * Copyright 2008-2009 Solarflare Communications Inc. + * Copyright 2008-2010 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/mcdi_mac.c b/drivers/net/sfc/mcdi_mac.c index f88f4bf986ff..33f7294edb47 100644 --- a/drivers/net/sfc/mcdi_mac.c +++ b/drivers/net/sfc/mcdi_mac.c @@ -1,6 +1,6 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards - * Copyright 2009 Solarflare Communications Inc. + * Copyright 2009-2010 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/mcdi_pcol.h b/drivers/net/sfc/mcdi_pcol.h index 90359e644006..b86a15f221ad 100644 --- a/drivers/net/sfc/mcdi_pcol.h +++ b/drivers/net/sfc/mcdi_pcol.h @@ -1,6 +1,6 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards - * Copyright 2009 Solarflare Communications Inc. + * Copyright 2009-2011 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/mcdi_phy.c b/drivers/net/sfc/mcdi_phy.c index 0e97eed663c6..ec3f740f5465 100644 --- a/drivers/net/sfc/mcdi_phy.c +++ b/drivers/net/sfc/mcdi_phy.c @@ -1,6 +1,6 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards - * Copyright 2009 Solarflare Communications Inc. + * Copyright 2009-2010 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c index 6e82e5ba583a..19e68c26d103 100644 --- a/drivers/net/sfc/mdio_10g.c +++ b/drivers/net/sfc/mdio_10g.c @@ -1,6 +1,6 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards - * Copyright 2006-2009 Solarflare Communications Inc. + * Copyright 2006-2011 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h index 44c5dee52107..df0703940c83 100644 --- a/drivers/net/sfc/mdio_10g.h +++ b/drivers/net/sfc/mdio_10g.h @@ -1,6 +1,6 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards - * Copyright 2006-2009 Solarflare Communications Inc. + * Copyright 2006-2011 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/mtd.c b/drivers/net/sfc/mtd.c index d38627448c22..e646bfce2d84 100644 --- a/drivers/net/sfc/mtd.c +++ b/drivers/net/sfc/mtd.c @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2006-2009 Solarflare Communications Inc. + * Copyright 2006-2010 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 5b001c1c73d4..9ea6cc2d205e 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2005-2009 Solarflare Communications Inc. + * Copyright 2005-2011 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index 1d0b8b6f25c4..fb25b87a1835 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2006-2009 Solarflare Communications Inc. + * Copyright 2006-2011 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/nic.h b/drivers/net/sfc/nic.h index 17407eac0030..1daaee6c7f07 100644 --- a/drivers/net/sfc/nic.h +++ b/drivers/net/sfc/nic.h @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2006-2009 Solarflare Communications Inc. + * Copyright 2006-2011 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h index 1dab609757fb..b3b79472421e 100644 --- a/drivers/net/sfc/phy.h +++ b/drivers/net/sfc/phy.h @@ -1,6 +1,6 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards - * Copyright 2007-2009 Solarflare Communications Inc. + * Copyright 2007-2010 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c index ea3ae0089315..55f90924247e 100644 --- a/drivers/net/sfc/qt202x_phy.c +++ b/drivers/net/sfc/qt202x_phy.c @@ -1,6 +1,6 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards - * Copyright 2006-2009 Solarflare Communications Inc. + * Copyright 2006-2010 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/regs.h b/drivers/net/sfc/regs.h index 8227de62014f..cc2c86b76a7b 100644 --- a/drivers/net/sfc/regs.h +++ b/drivers/net/sfc/regs.h @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2006-2009 Solarflare Communications Inc. + * Copyright 2006-2010 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 81bec873e9d3..c0fdb59030fb 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2005-2009 Solarflare Communications Inc. + * Copyright 2005-2011 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index f936892aa423..a0f49b348d62 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2006-2009 Solarflare Communications Inc. + * Copyright 2006-2010 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/selftest.h b/drivers/net/sfc/selftest.h index aed495a4dad7..dba5456e70f3 100644 --- a/drivers/net/sfc/selftest.h +++ b/drivers/net/sfc/selftest.h @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2006-2008 Solarflare Communications Inc. + * Copyright 2006-2010 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index 07b59a8c9a4c..8bd537e1de7f 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2006-2009 Solarflare Communications Inc. + * Copyright 2006-2010 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/spi.h b/drivers/net/sfc/spi.h index 879b7f6bde3d..71f2e3ebe1c7 100644 --- a/drivers/net/sfc/spi.h +++ b/drivers/net/sfc/spi.h @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005 Fen Systems Ltd. - * Copyright 2006 Solarflare Communications Inc. + * Copyright 2006-2010 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index 581911f70441..efdceb35aaae 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -1,6 +1,6 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards - * Copyright 2007-2009 Solarflare Communications Inc. + * Copyright 2007-2011 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index 1a51653bb92b..139801908217 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2005-2009 Solarflare Communications Inc. + * Copyright 2005-2010 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/txc43128_phy.c b/drivers/net/sfc/txc43128_phy.c index 4e2b48a8f5c4..d9886addcc99 100644 --- a/drivers/net/sfc/txc43128_phy.c +++ b/drivers/net/sfc/txc43128_phy.c @@ -1,6 +1,6 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards - * Copyright 2006-2010 Solarflare Communications Inc. + * Copyright 2006-2011 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h index e0d63083c3a8..e4dd3a7f304b 100644 --- a/drivers/net/sfc/workarounds.h +++ b/drivers/net/sfc/workarounds.h @@ -1,6 +1,6 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards - * Copyright 2006-2009 Solarflare Communications Inc. + * Copyright 2006-2010 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published -- cgit v1.2.3 From 119226c563be011c6396c6a2d268d1ca7e467bd3 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 18 Feb 2011 19:14:13 +0000 Subject: sfc: Expose TX push and TSO counters through ethtool statistics Signed-off-by: Ben Hutchings --- drivers/net/sfc/ethtool.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 52fa661aede9..158d5b5630b6 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -28,7 +28,8 @@ struct efx_ethtool_stat { enum { EFX_ETHTOOL_STAT_SOURCE_mac_stats, EFX_ETHTOOL_STAT_SOURCE_nic, - EFX_ETHTOOL_STAT_SOURCE_channel + EFX_ETHTOOL_STAT_SOURCE_channel, + EFX_ETHTOOL_STAT_SOURCE_tx_queue } source; unsigned offset; u64(*get_stat) (void *field); /* Reader function */ @@ -86,6 +87,10 @@ static u64 efx_get_atomic_stat(void *field) EFX_ETHTOOL_STAT(field, channel, n_##field, \ unsigned int, efx_get_uint_stat) +#define EFX_ETHTOOL_UINT_TXQ_STAT(field) \ + EFX_ETHTOOL_STAT(tx_##field, tx_queue, field, \ + unsigned int, efx_get_uint_stat) + static struct efx_ethtool_stat efx_ethtool_stats[] = { EFX_ETHTOOL_U64_MAC_STAT(tx_bytes), EFX_ETHTOOL_U64_MAC_STAT(tx_good_bytes), @@ -116,6 +121,10 @@ static struct efx_ethtool_stat efx_ethtool_stats[] = { EFX_ETHTOOL_ULONG_MAC_STAT(tx_non_tcpudp), EFX_ETHTOOL_ULONG_MAC_STAT(tx_mac_src_error), EFX_ETHTOOL_ULONG_MAC_STAT(tx_ip_src_error), + EFX_ETHTOOL_UINT_TXQ_STAT(tso_bursts), + EFX_ETHTOOL_UINT_TXQ_STAT(tso_long_headers), + EFX_ETHTOOL_UINT_TXQ_STAT(tso_packets), + EFX_ETHTOOL_UINT_TXQ_STAT(pushes), EFX_ETHTOOL_U64_MAC_STAT(rx_bytes), EFX_ETHTOOL_U64_MAC_STAT(rx_good_bytes), EFX_ETHTOOL_U64_MAC_STAT(rx_bad_bytes), @@ -470,6 +479,7 @@ static void efx_ethtool_get_stats(struct net_device *net_dev, struct efx_mac_stats *mac_stats = &efx->mac_stats; struct efx_ethtool_stat *stat; struct efx_channel *channel; + struct efx_tx_queue *tx_queue; struct rtnl_link_stats64 temp; int i; @@ -495,6 +505,15 @@ static void efx_ethtool_get_stats(struct net_device *net_dev, data[i] += stat->get_stat((void *)channel + stat->offset); break; + case EFX_ETHTOOL_STAT_SOURCE_tx_queue: + data[i] = 0; + efx_for_each_channel(channel, efx) { + efx_for_each_channel_tx_queue(tx_queue, channel) + data[i] += + stat->get_stat((void *)tx_queue + + stat->offset); + } + break; } } } -- cgit v1.2.3 From 5fb6b06d4eda2167eab662ad5e30058cecd67b8b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 24 Feb 2011 19:30:41 +0000 Subject: sfc: Remove configurable FIFO thresholds for pause frame generation In Falcon we can configure the fill levels of the RX data FIFO which trigger the generation of pause frames (if enabled), and we have module parameters for this. Siena does not allow the levels to be configured (or, if it does, this is done by the MC firmware and is not configurable by drivers). So far as I can tell, the module parameters are not used by our internal scripts and have not been documented (with the exception of the short parameter descriptions). Therefore, remove them and always initialise Falcon with the default values. Signed-off-by: Ben Hutchings --- drivers/net/sfc/falcon.c | 20 +++++--------------- drivers/net/sfc/nic.c | 20 -------------------- drivers/net/sfc/nic.h | 1 - drivers/net/sfc/siena.c | 5 ----- 4 files changed, 5 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 87481a6df42c..734fcfb52e85 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1478,36 +1478,26 @@ static void falcon_init_rx_cfg(struct efx_nic *efx) /* RX control FIFO thresholds (32 entries) */ const unsigned ctrl_xon_thr = 20; const unsigned ctrl_xoff_thr = 25; - /* RX data FIFO thresholds (256-byte units; size varies) */ - int data_xon_thr = efx_nic_rx_xon_thresh >> 8; - int data_xoff_thr = efx_nic_rx_xoff_thresh >> 8; efx_oword_t reg; efx_reado(efx, ®, FR_AZ_RX_CFG); if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1) { /* Data FIFO size is 5.5K */ - if (data_xon_thr < 0) - data_xon_thr = 512 >> 8; - if (data_xoff_thr < 0) - data_xoff_thr = 2048 >> 8; EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_DESC_PUSH_EN, 0); EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_USR_BUF_SIZE, huge_buf_size); - EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XON_MAC_TH, data_xon_thr); - EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XOFF_MAC_TH, data_xoff_thr); + EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XON_MAC_TH, 512 >> 8); + EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XOFF_MAC_TH, 2048 >> 8); EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XON_TX_TH, ctrl_xon_thr); EFX_SET_OWORD_FIELD(reg, FRF_AA_RX_XOFF_TX_TH, ctrl_xoff_thr); } else { /* Data FIFO size is 80K; register fields moved */ - if (data_xon_thr < 0) - data_xon_thr = 27648 >> 8; /* ~3*max MTU */ - if (data_xoff_thr < 0) - data_xoff_thr = 54272 >> 8; /* ~80Kb - 3*max MTU */ EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_DESC_PUSH_EN, 0); EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_USR_BUF_SIZE, huge_buf_size); - EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XON_MAC_TH, data_xon_thr); - EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XOFF_MAC_TH, data_xoff_thr); + /* Send XON and XOFF at ~3 * max MTU away from empty/full */ + EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XON_MAC_TH, 27648 >> 8); + EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XOFF_MAC_TH, 54272 >> 8); EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XON_TX_TH, ctrl_xon_thr); EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_XOFF_TX_TH, ctrl_xoff_thr); EFX_SET_OWORD_FIELD(reg, FRF_BZ_RX_INGR_EN, 1); diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index fb25b87a1835..e8396614daf3 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -41,26 +41,6 @@ #define RX_DC_ENTRIES 64 #define RX_DC_ENTRIES_ORDER 3 -/* RX FIFO XOFF watermark - * - * When the amount of the RX FIFO increases used increases past this - * watermark send XOFF. Only used if RX flow control is enabled (ethtool -A) - * This also has an effect on RX/TX arbitration - */ -int efx_nic_rx_xoff_thresh = -1; -module_param_named(rx_xoff_thresh_bytes, efx_nic_rx_xoff_thresh, int, 0644); -MODULE_PARM_DESC(rx_xoff_thresh_bytes, "RX fifo XOFF threshold"); - -/* RX FIFO XON watermark - * - * When the amount of the RX FIFO used decreases below this - * watermark send XON. Only used if TX flow control is enabled (ethtool -A) - * This also has an effect on RX/TX arbitration - */ -int efx_nic_rx_xon_thresh = -1; -module_param_named(rx_xon_thresh_bytes, efx_nic_rx_xon_thresh, int, 0644); -MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); - /* If EFX_MAX_INT_ERRORS internal errors occur within * EFX_INT_ERROR_EXPIRE seconds, we consider the NIC broken and * disable it. diff --git a/drivers/net/sfc/nic.h b/drivers/net/sfc/nic.h index 1daaee6c7f07..d9de1b647d41 100644 --- a/drivers/net/sfc/nic.h +++ b/drivers/net/sfc/nic.h @@ -188,7 +188,6 @@ extern void efx_nic_eventq_read_ack(struct efx_channel *channel); /* MAC/PHY */ extern void falcon_drain_tx_fifo(struct efx_nic *efx); extern void falcon_reconfigure_mac_wrapper(struct efx_nic *efx); -extern int efx_nic_rx_xoff_thresh, efx_nic_rx_xon_thresh; /* Interrupts and test events */ extern int efx_nic_init_interrupt(struct efx_nic *efx); diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index 8bd537e1de7f..e4dd8986b1fe 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -341,11 +341,6 @@ static int siena_init_nic(struct efx_nic *efx) FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH / 8); efx_writeo(efx, &temp, FR_CZ_RX_RSS_IPV6_REG3); - if (efx_nic_rx_xoff_thresh >= 0 || efx_nic_rx_xon_thresh >= 0) - /* No MCDI operation has been defined to set thresholds */ - netif_err(efx, hw, efx->net_dev, - "ignoring RX flow control thresholds\n"); - /* Enable event logging */ rc = efx_mcdi_log_ctrl(efx, true, false, 0); if (rc) -- cgit v1.2.3 From 6d84b986b26bac1d4d678ff10c10a633bf53f834 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 25 Feb 2011 00:04:42 +0000 Subject: sfc: Bump version to 3.1 All features originally planned for version 3.1 (and some that weren't) have been implemented. Signed-off-by: Ben Hutchings --- drivers/net/sfc/net_driver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 9ea6cc2d205e..215d5c51bfa0 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -41,7 +41,7 @@ * **************************************************************************/ -#define EFX_DRIVER_VERSION "3.0" +#define EFX_DRIVER_VERSION "3.1" #ifdef EFX_ENABLE_DEBUG #define EFX_BUG_ON_PARANOID(x) BUG_ON(x) -- cgit v1.2.3 From 35d2b6f9b194ef99ceb6ea565c875af7cea34fa0 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 25 Feb 2011 16:09:07 +0000 Subject: staging:iio:gyro: adis16080 cleanup, move to abi and bug fixes. Moved to standard sysfs naming and got rid of direct register writing from userspace. The rx and tx buffers are never used together so just have one and avoid the need to malloc it by using putting it in the state structure and using the ____cacheline_aligned trick. Couple of obvious bug fixes whilst I was here. I don't have one of these so can't test. This is done off datasheet. Note that as with the adis16060 driver there are parts that definitely wouldn't work before this patch. Now it 'might' assuming I haven't messed up too badly. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/gyro/adis16080.h | 36 ---------- drivers/staging/iio/gyro/adis16080_core.c | 113 +++++++++++++----------------- 2 files changed, 47 insertions(+), 102 deletions(-) delete mode 100644 drivers/staging/iio/gyro/adis16080.h (limited to 'drivers') diff --git a/drivers/staging/iio/gyro/adis16080.h b/drivers/staging/iio/gyro/adis16080.h deleted file mode 100644 index f4e38510ec46..000000000000 --- a/drivers/staging/iio/gyro/adis16080.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef SPI_ADIS16080_H_ -#define SPI_ADIS16080_H_ - -/* Output data format setting. 0: Twos complement. 1: Offset binary. */ -#define ADIS16080_DIN_CODE 4 -#define ADIS16080_DIN_GYRO (0 << 10) /* Gyroscope output */ -#define ADIS16080_DIN_TEMP (1 << 10) /* Temperature output */ -#define ADIS16080_DIN_AIN1 (2 << 10) -#define ADIS16080_DIN_AIN2 (3 << 10) - -/* - * 1: Write contents on DIN to control register. - * 0: No changes to control register. - */ - -#define ADIS16080_DIN_WRITE (1 << 15) - -#define ADIS16080_MAX_TX 2 -#define ADIS16080_MAX_RX 2 - -/** - * struct adis16080_state - device instance specific data - * @us: actual spi_device to write data - * @indio_dev: industrial I/O device structure - * @tx: transmit buffer - * @rx: recieve buffer - * @buf_lock: mutex to protect tx and rx - **/ -struct adis16080_state { - struct spi_device *us; - struct iio_dev *indio_dev; - u8 *tx; - u8 *rx; - struct mutex buf_lock; -}; -#endif /* SPI_ADIS16080_H_ */ diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c index 252080b238e8..fb4336c7d2a6 100644 --- a/drivers/staging/iio/gyro/adis16080_core.c +++ b/drivers/staging/iio/gyro/adis16080_core.c @@ -5,9 +5,6 @@ * * Licensed under the GPL-2 or later. */ - -#include -#include #include #include #include @@ -16,14 +13,38 @@ #include #include #include -#include #include "../iio.h" #include "../sysfs.h" #include "gyro.h" #include "../adc/adc.h" -#include "adis16080.h" +#define ADIS16080_DIN_GYRO (0 << 10) /* Gyroscope output */ +#define ADIS16080_DIN_TEMP (1 << 10) /* Temperature output */ +#define ADIS16080_DIN_AIN1 (2 << 10) +#define ADIS16080_DIN_AIN2 (3 << 10) + +/* + * 1: Write contents on DIN to control register. + * 0: No changes to control register. + */ + +#define ADIS16080_DIN_WRITE (1 << 15) + +/** + * struct adis16080_state - device instance specific data + * @us: actual spi_device to write data + * @indio_dev: industrial I/O device structure + * @buf: transmit or recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct adis16080_state { + struct spi_device *us; + struct iio_dev *indio_dev; + struct mutex buf_lock; + + u8 buf[2] ____cacheline_aligned; +}; static int adis16080_spi_write(struct device *dev, u16 val) @@ -33,10 +54,10 @@ static int adis16080_spi_write(struct device *dev, struct adis16080_state *st = iio_dev_get_devdata(indio_dev); mutex_lock(&st->buf_lock); - st->tx[0] = val >> 8; - st->tx[1] = val; + st->buf[0] = val >> 8; + st->buf[1] = val; - ret = spi_write(st->us, st->tx, 2); + ret = spi_write(st->us, st->buf, 2); mutex_unlock(&st->buf_lock); return ret; @@ -51,10 +72,10 @@ static int adis16080_spi_read(struct device *dev, mutex_lock(&st->buf_lock); - ret = spi_read(st->us, st->rx, 2); + ret = spi_read(st->us, st->buf, 2); if (ret == 0) - *val = ((st->rx[0] & 0xF) << 8) | st->rx[1]; + *val = ((st->buf[0] & 0xF) << 8) | st->buf[1]; mutex_unlock(&st->buf_lock); return ret; @@ -64,13 +85,19 @@ static ssize_t adis16080_read(struct device *dev, struct device_attribute *attr, char *buf) { + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_dev *indio_dev = dev_get_drvdata(dev); u16 val = 0; ssize_t ret; /* Take the iio_dev status lock */ mutex_lock(&indio_dev->mlock); + ret = adis16080_spi_write(dev, + this_attr->address | ADIS16080_DIN_WRITE); + if (ret < 0) + goto error_ret; ret = adis16080_spi_read(dev, &val); +error_ret: mutex_unlock(&indio_dev->mlock); if (ret == 0) @@ -78,46 +105,18 @@ static ssize_t adis16080_read(struct device *dev, else return ret; } - -static ssize_t adis16080_write(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - int ret; - long val; - - ret = strict_strtol(buf, 16, &val); - if (ret) - goto error_ret; - ret = adis16080_spi_write(dev, val); - -error_ret: - return ret ? ret : len; -} - -#define IIO_DEV_ATTR_IN(_show) \ - IIO_DEVICE_ATTR(in, S_IRUGO, _show, NULL, 0) - -#define IIO_DEV_ATTR_OUT(_store) \ - IIO_DEVICE_ATTR(out, S_IRUGO, NULL, _store, 0) - -static IIO_DEV_ATTR_IN(adis16080_read); -static IIO_DEV_ATTR_OUT(adis16080_write); - +static IIO_DEV_ATTR_GYRO_Z(adis16080_read, ADIS16080_DIN_GYRO); +static IIO_DEVICE_ATTR(temp_raw, S_IRUGO, adis16080_read, NULL, + ADIS16080_DIN_TEMP); +static IIO_DEV_ATTR_IN_RAW(0, adis16080_read, ADIS16080_DIN_AIN1); +static IIO_DEV_ATTR_IN_RAW(1, adis16080_read, ADIS16080_DIN_AIN2); static IIO_CONST_ATTR(name, "adis16080"); -static struct attribute *adis16080_event_attributes[] = { - NULL -}; - -static struct attribute_group adis16080_event_attribute_group = { - .attrs = adis16080_event_attributes, -}; - static struct attribute *adis16080_attributes[] = { - &iio_dev_attr_in.dev_attr.attr, - &iio_dev_attr_out.dev_attr.attr, + &iio_dev_attr_gyro_z_raw.dev_attr.attr, + &iio_dev_attr_temp_raw.dev_attr.attr, + &iio_dev_attr_in0_raw.dev_attr.attr, + &iio_dev_attr_in1_raw.dev_attr.attr, &iio_const_attr_name.dev_attr.attr, NULL }; @@ -138,28 +137,16 @@ static int __devinit adis16080_probe(struct spi_device *spi) spi_set_drvdata(spi, st); /* Allocate the comms buffers */ - st->rx = kzalloc(sizeof(*st->rx)*ADIS16080_MAX_RX, GFP_KERNEL); - if (st->rx == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->tx = kzalloc(sizeof(*st->tx)*ADIS16080_MAX_TX, GFP_KERNEL); - if (st->tx == NULL) { - ret = -ENOMEM; - goto error_free_rx; - } st->us = spi; mutex_init(&st->buf_lock); /* setup the industrialio driver allocated elements */ st->indio_dev = iio_allocate_device(); if (st->indio_dev == NULL) { ret = -ENOMEM; - goto error_free_tx; + goto error_free_st; } st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->num_interrupt_lines = 1; - st->indio_dev->event_attrs = &adis16080_event_attribute_group; st->indio_dev->attrs = &adis16080_attribute_group; st->indio_dev->dev_data = (void *)(st); st->indio_dev->driver_module = THIS_MODULE; @@ -177,10 +164,6 @@ error_free_dev: iio_device_unregister(st->indio_dev); else iio_free_device(st->indio_dev); -error_free_tx: - kfree(st->tx); -error_free_rx: - kfree(st->rx); error_free_st: kfree(st); error_ret: @@ -194,8 +177,6 @@ static int adis16080_remove(struct spi_device *spi) struct iio_dev *indio_dev = st->indio_dev; iio_device_unregister(indio_dev); - kfree(st->tx); - kfree(st->rx); kfree(st); return 0; -- cgit v1.2.3 From 03d1b7d3e4debbdbca4a676c749214b39025c8dd Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 26 Feb 2011 17:27:17 +0000 Subject: staging:iio:gyro: add adis16251 support to adis16260 driver These parts are very similar and the adis16260 driver supports a lot of additional functionality. Precursor to removal of adis16251 driver. Note that some supported devices were missing from Kconfig help text and are also added in this patch. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/gyro/Kconfig | 4 +-- drivers/staging/iio/gyro/adis16260_core.c | 49 ++++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/gyro/Kconfig b/drivers/staging/iio/gyro/Kconfig index 236f15fdbfc9..5bba4b05f965 100644 --- a/drivers/staging/iio/gyro/Kconfig +++ b/drivers/staging/iio/gyro/Kconfig @@ -25,13 +25,13 @@ config ADIS16130 Angular Rate Sensor driver. config ADIS16260 - tristate "Analog Devices ADIS16260 ADIS16265 Digital Gyroscope Sensor SPI driver" + tristate "Analog Devices ADIS16260 Digital Gyroscope Sensor SPI driver" depends on SPI select IIO_TRIGGER if IIO_RING_BUFFER select IIO_SW_RING if IIO_RING_BUFFER help Say yes here to build support for Analog Devices ADIS16260 ADIS16265 - programmable digital gyroscope sensor. + ADIS16250 ADIS16255 and ADIS16251 programmable digital gyroscope sensors. This driver can also be built as a module. If so, the module will be called adis16260. diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 045e27da980a..69a29ec93101 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -238,10 +238,24 @@ error_ret: return ret ? ret : len; } +static ssize_t adis16260_read_frequency_available(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16260_state *st = iio_dev_get_devdata(indio_dev); + if (spi_get_device_id(st->us)->driver_data) + return sprintf(buf, "%s\n", "0.129 ~ 256"); + else + return sprintf(buf, "%s\n", "256 2048"); +} + static ssize_t adis16260_read_frequency(struct device *dev, struct device_attribute *attr, char *buf) { + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16260_state *st = iio_dev_get_devdata(indio_dev); int ret, len = 0; u16 t; int sps; @@ -250,7 +264,11 @@ static ssize_t adis16260_read_frequency(struct device *dev, &t); if (ret) return ret; - sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 66 : 2048; + + if (spi_get_device_id(st->us)->driver_data) /* If an adis16251 */ + sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 8 : 256; + else + sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 66 : 2048; sps /= (t & ADIS16260_SMPL_PRD_DIV_MASK) + 1; len = sprintf(buf, "%d SPS\n", sps); return len; @@ -272,16 +290,21 @@ static ssize_t adis16260_write_frequency(struct device *dev, return ret; mutex_lock(&indio_dev->mlock); - - t = (2048 / val); - if (t > 0) - t--; - t &= ADIS16260_SMPL_PRD_DIV_MASK; + if (spi_get_device_id(st->us)) { + t = (256 / val); + if (t > 0) + t--; + t &= ADIS16260_SMPL_PRD_DIV_MASK; + } else { + t = (2048 / val); + if (t > 0) + t--; + t &= ADIS16260_SMPL_PRD_DIV_MASK; + } if ((t & ADIS16260_SMPL_PRD_DIV_MASK) >= 0x0A) st->us->max_speed_hz = ADIS16260_SPI_SLOW; else st->us->max_speed_hz = ADIS16260_SPI_FAST; - ret = adis16260_spi_write_reg_8(dev, ADIS16260_SMPL_PRD, t); @@ -302,7 +325,10 @@ static ssize_t adis16260_read_gyro_scale(struct device *dev, if (st->negate) ret = sprintf(buf, "-"); /* Take the iio_dev status lock */ - ret += sprintf(buf + ret, "%s\n", "0.00127862821"); + if (spi_get_device_id(st->us)->driver_data) + ret += sprintf(buf + ret, "%s\n", "0.00031974432"); + else + ret += sprintf(buf + ret, "%s\n", "0.00127862821"); return ret; } @@ -475,7 +501,9 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16260_write_reset, 0); -static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("256 2048"); + +static IIO_DEVICE_ATTR(sampling_frequency_available, + S_IRUGO, adis16260_read_frequency_available, NULL, 0); static IIO_CONST_ATTR_NAME("adis16260"); @@ -525,7 +553,7 @@ static ADIS16260_GYRO_ATTR_SET(_Z); &iio_dev_attr_in1_raw.dev_attr.attr, \ &iio_const_attr_in1_scale.dev_attr.attr, \ &iio_dev_attr_sampling_frequency.dev_attr.attr, \ - &iio_const_attr_sampling_frequency_available.dev_attr.attr, \ + &iio_dev_attr_sampling_frequency_available.dev_attr.attr, \ &iio_dev_attr_reset.dev_attr.attr, \ &iio_const_attr_name.dev_attr.attr, \ NULL \ @@ -693,6 +721,7 @@ static const struct spi_device_id adis16260_id[] = { {"adis16265", 0}, {"adis16250", 0}, {"adis16255", 0}, + {"adis16251", 1}, {} }; -- cgit v1.2.3 From a301d425e6cc8b1f7d7449c0e5d72e9463652d90 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 26 Feb 2011 17:27:18 +0000 Subject: staging:iio:gyro remove adis16251 driver as now supported by adis16260 driver Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/gyro/Kconfig | 10 - drivers/staging/iio/gyro/adis16251.h | 185 ------- drivers/staging/iio/gyro/adis16251_core.c | 777 ------------------------------ 3 files changed, 972 deletions(-) delete mode 100644 drivers/staging/iio/gyro/adis16251.h delete mode 100644 drivers/staging/iio/gyro/adis16251_core.c (limited to 'drivers') diff --git a/drivers/staging/iio/gyro/Kconfig b/drivers/staging/iio/gyro/Kconfig index 5bba4b05f965..8b78fa0e6316 100644 --- a/drivers/staging/iio/gyro/Kconfig +++ b/drivers/staging/iio/gyro/Kconfig @@ -35,13 +35,3 @@ config ADIS16260 This driver can also be built as a module. If so, the module will be called adis16260. - -config ADIS16251 - tristate "Analog Devices ADIS16251 Digital Gyroscope Sensor SPI driver" - depends on SPI - help - Say yes here to build support for Analog Devices adis16261 programmable - digital gyroscope sensor. - - This driver can also be built as a module. If so, the module - will be called adis16251. diff --git a/drivers/staging/iio/gyro/adis16251.h b/drivers/staging/iio/gyro/adis16251.h deleted file mode 100644 index d23852cf78e8..000000000000 --- a/drivers/staging/iio/gyro/adis16251.h +++ /dev/null @@ -1,185 +0,0 @@ -#ifndef SPI_ADIS16251_H_ -#define SPI_ADIS16251_H_ - -#define ADIS16251_STARTUP_DELAY 220 /* ms */ - -#define ADIS16251_READ_REG(a) a -#define ADIS16251_WRITE_REG(a) ((a) | 0x80) - -#define ADIS16251_ENDURANCE 0x00 /* Flash memory write count */ -#define ADIS16251_SUPPLY_OUT 0x02 /* Power supply measurement */ -#define ADIS16251_GYRO_OUT 0x04 /* X-axis gyroscope output */ -#define ADIS16251_AUX_ADC 0x0A /* analog input channel measurement */ -#define ADIS16251_TEMP_OUT 0x0C /* internal temperature measurement */ -#define ADIS16251_ANGL_OUT 0x0E /* angle displacement */ -#define ADIS16251_GYRO_OFF 0x14 /* Calibration, offset/bias adjustment */ -#define ADIS16251_GYRO_SCALE 0x16 /* Calibration, scale adjustment */ -#define ADIS16251_ALM_MAG1 0x20 /* Alarm 1 magnitude/polarity setting */ -#define ADIS16251_ALM_MAG2 0x22 /* Alarm 2 magnitude/polarity setting */ -#define ADIS16251_ALM_SMPL1 0x24 /* Alarm 1 dynamic rate of change setting */ -#define ADIS16251_ALM_SMPL2 0x26 /* Alarm 2 dynamic rate of change setting */ -#define ADIS16251_ALM_CTRL 0x28 /* Alarm control */ -#define ADIS16251_AUX_DAC 0x30 /* Auxiliary DAC data */ -#define ADIS16251_GPIO_CTRL 0x32 /* Control, digital I/O line */ -#define ADIS16251_MSC_CTRL 0x34 /* Control, data ready, self-test settings */ -#define ADIS16251_SMPL_PRD 0x36 /* Control, internal sample rate */ -#define ADIS16251_SENS_AVG 0x38 /* Control, dynamic range, filtering */ -#define ADIS16251_SLP_CNT 0x3A /* Control, sleep mode initiation */ -#define ADIS16251_DIAG_STAT 0x3C /* Diagnostic, error flags */ -#define ADIS16251_GLOB_CMD 0x3E /* Control, global commands */ - -#define ADIS16251_ERROR_ACTIVE (1<<14) -#define ADIS16251_NEW_DATA (1<<14) - -/* MSC_CTRL */ -#define ADIS16251_MSC_CTRL_INT_SELF_TEST (1<<10) /* Internal self-test enable */ -#define ADIS16251_MSC_CTRL_NEG_SELF_TEST (1<<9) -#define ADIS16251_MSC_CTRL_POS_SELF_TEST (1<<8) -#define ADIS16251_MSC_CTRL_DATA_RDY_EN (1<<2) -#define ADIS16251_MSC_CTRL_DATA_RDY_POL_HIGH (1<<1) -#define ADIS16251_MSC_CTRL_DATA_RDY_DIO2 (1<<0) - -/* SMPL_PRD */ -#define ADIS16251_SMPL_PRD_TIME_BASE (1<<7) /* Time base (tB): 0 = 1.953 ms, 1 = 60.54 ms */ -#define ADIS16251_SMPL_PRD_DIV_MASK 0x7F - -/* SLP_CNT */ -#define ADIS16251_SLP_CNT_POWER_OFF 0x80 - -/* DIAG_STAT */ -#define ADIS16251_DIAG_STAT_ALARM2 (1<<9) -#define ADIS16251_DIAG_STAT_ALARM1 (1<<8) -#define ADIS16251_DIAG_STAT_SELF_TEST (1<<5) -#define ADIS16251_DIAG_STAT_OVERFLOW (1<<4) -#define ADIS16251_DIAG_STAT_SPI_FAIL (1<<3) -#define ADIS16251_DIAG_STAT_FLASH_UPT (1<<2) -#define ADIS16251_DIAG_STAT_POWER_HIGH (1<<1) -#define ADIS16251_DIAG_STAT_POWER_LOW (1<<0) - -#define ADIS16251_DIAG_STAT_ERR_MASK (ADIS16251_DIAG_STAT_ALARM2 | \ - ADIS16251_DIAG_STAT_ALARM1 | \ - ADIS16251_DIAG_STAT_SELF_TEST | \ - ADIS16251_DIAG_STAT_OVERFLOW | \ - ADIS16251_DIAG_STAT_SPI_FAIL | \ - ADIS16251_DIAG_STAT_FLASH_UPT | \ - ADIS16251_DIAG_STAT_POWER_HIGH | \ - ADIS16251_DIAG_STAT_POWER_LOW) - -/* GLOB_CMD */ -#define ADIS16251_GLOB_CMD_SW_RESET (1<<7) -#define ADIS16251_GLOB_CMD_FLASH_UPD (1<<3) -#define ADIS16251_GLOB_CMD_DAC_LATCH (1<<2) -#define ADIS16251_GLOB_CMD_FAC_CALIB (1<<1) -#define ADIS16251_GLOB_CMD_AUTO_NULL (1<<0) - -#define ADIS16251_MAX_TX 24 -#define ADIS16251_MAX_RX 24 - -#define ADIS16251_SPI_SLOW (u32)(300 * 1000) -#define ADIS16251_SPI_BURST (u32)(1000 * 1000) -#define ADIS16251_SPI_FAST (u32)(2000 * 1000) - -/** - * struct adis16251_state - device instance specific data - * @us: actual spi_device - * @work_trigger_to_ring: bh for triggered event handling - * @inter: used to check if new interrupt has been triggered - * @last_timestamp: passing timestamp from th to bh of interrupt handler - * @indio_dev: industrial I/O device structure - * @trig: data ready trigger registered with iio - * @tx: transmit buffer - * @rx: recieve buffer - * @buf_lock: mutex to protect tx and rx - **/ -struct adis16251_state { - struct spi_device *us; - struct work_struct work_trigger_to_ring; - s64 last_timestamp; - struct iio_dev *indio_dev; - struct iio_trigger *trig; - u8 *tx; - u8 *rx; - struct mutex buf_lock; -}; - -int adis16251_spi_write_reg_8(struct device *dev, - u8 reg_address, - u8 val); - -int adis16251_spi_read_burst(struct device *dev, u8 *rx); - -int adis16251_spi_read_sequence(struct device *dev, - u8 *tx, u8 *rx, int num); - -int adis16251_set_irq(struct device *dev, bool enable); - -int adis16251_reset(struct device *dev); - -int adis16251_stop_device(struct device *dev); - -int adis16251_check_status(struct device *dev); - -#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT) -/* At the moment triggers are only used for ring buffer - * filling. This may change! - */ - -enum adis16251_scan { - ADIS16251_SCAN_SUPPLY, - ADIS16251_SCAN_GYRO, - ADIS16251_SCAN_TEMP, - ADIS16251_SCAN_ADC_0, -}; - -void adis16251_remove_trigger(struct iio_dev *indio_dev); -int adis16251_probe_trigger(struct iio_dev *indio_dev); - -ssize_t adis16251_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - - -int adis16251_configure_ring(struct iio_dev *indio_dev); -void adis16251_unconfigure_ring(struct iio_dev *indio_dev); - -int adis16251_initialize_ring(struct iio_ring_buffer *ring); -void adis16251_uninitialize_ring(struct iio_ring_buffer *ring); -#else /* CONFIG_IIO_RING_BUFFER */ - -static inline void adis16251_remove_trigger(struct iio_dev *indio_dev) -{ -} - -static inline int adis16251_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline ssize_t -adis16251_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static int adis16251_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void adis16251_unconfigure_ring(struct iio_dev *indio_dev) -{ -} - -static inline int adis16251_initialize_ring(struct iio_ring_buffer *ring) -{ - return 0; -} - -static inline void adis16251_uninitialize_ring(struct iio_ring_buffer *ring) -{ -} - -#endif /* CONFIG_IIO_RING_BUFFER */ -#endif /* SPI_ADIS16251_H_ */ diff --git a/drivers/staging/iio/gyro/adis16251_core.c b/drivers/staging/iio/gyro/adis16251_core.c deleted file mode 100644 index a0d400f7ee62..000000000000 --- a/drivers/staging/iio/gyro/adis16251_core.c +++ /dev/null @@ -1,777 +0,0 @@ -/* - * ADIS16251 Programmable Digital Gyroscope Sensor Driver - * - * Copyright 2010 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../iio.h" -#include "../sysfs.h" -#include "gyro.h" -#include "../adc/adc.h" - -#include "adis16251.h" - -#define DRIVER_NAME "adis16251" - -/* At the moment the spi framework doesn't allow global setting of cs_change. - * It's in the likely to be added comment at the top of spi.h. - * This means that use cannot be made of spi_write etc. - */ - -/** - * adis16251_spi_write_reg_8() - write single byte to a register - * @dev: device associated with child of actual device (iio_dev or iio_trig) - * @reg_address: the address of the register to be written - * @val: the value to write - **/ -int adis16251_spi_write_reg_8(struct device *dev, - u8 reg_address, - u8 val) -{ - int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16251_state *st = iio_dev_get_devdata(indio_dev); - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16251_WRITE_REG(reg_address); - st->tx[1] = val; - - ret = spi_write(st->us, st->tx, 2); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16251_spi_write_reg_16() - write 2 bytes to a pair of registers - * @dev: device associated with child of actual device (iio_dev or iio_trig) - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: value to be written - **/ -static int adis16251_spi_write_reg_16(struct device *dev, - u8 lower_reg_address, - u16 value) -{ - int ret; - struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16251_state *st = iio_dev_get_devdata(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - }, { - .tx_buf = st->tx + 2, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16251_WRITE_REG(lower_reg_address); - st->tx[1] = value & 0xFF; - st->tx[2] = ADIS16251_WRITE_REG(lower_reg_address + 1); - st->tx[3] = (value >> 8) & 0xFF; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16251_spi_read_reg_16() - read 2 bytes from a 16-bit register - * @dev: device associated with child of actual device (iio_dev or iio_trig) - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: somewhere to pass back the value read - **/ -static int adis16251_spi_read_reg_16(struct device *dev, - u8 lower_reg_address, - u16 *val) -{ - struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16251_state *st = iio_dev_get_devdata(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - }, { - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16251_READ_REG(lower_reg_address); - st->tx[1] = 0; - st->tx[2] = 0; - st->tx[3] = 0; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - if (ret) { - dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", - lower_reg_address); - goto error_ret; - } - *val = (st->rx[0] << 8) | st->rx[1]; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - -/** - * adis16251_spi_read_burst() - read all data registers - * @dev: device associated with child of actual device (iio_dev or iio_trig) - * @rx: somewhere to pass back the value read (min size is 24 bytes) - **/ -int adis16251_spi_read_burst(struct device *dev, u8 *rx) -{ - struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16251_state *st = iio_dev_get_devdata(indio_dev); - u32 old_speed_hz = st->us->max_speed_hz; - int ret; - - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 0, - }, { - .rx_buf = rx, - .bits_per_word = 8, - .len = 24, - .cs_change = 1, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16251_READ_REG(ADIS16251_GLOB_CMD); - st->tx[1] = 0; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - - st->us->max_speed_hz = min(ADIS16251_SPI_BURST, old_speed_hz); - spi_setup(st->us); - - ret = spi_sync(st->us, &msg); - if (ret) - dev_err(&st->us->dev, "problem when burst reading"); - - st->us->max_speed_hz = old_speed_hz; - spi_setup(st->us); - mutex_unlock(&st->buf_lock); - return ret; -} - -/** - * adis16251_spi_read_sequence() - read a sequence of 16-bit registers - * @dev: device associated with child of actual device (iio_dev or iio_trig) - * @tx: register addresses in bytes 0,2,4,6... (min size is 2*num bytes) - * @rx: somewhere to pass back the value read (min size is 2*num bytes) - **/ -int adis16251_spi_read_sequence(struct device *dev, - u8 *tx, u8 *rx, int num) -{ - struct spi_message msg; - struct spi_transfer *xfers; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16251_state *st = iio_dev_get_devdata(indio_dev); - int ret, i; - - xfers = kzalloc(num + 1, GFP_KERNEL); - if (xfers == NULL) { - dev_err(&st->us->dev, "memory alloc failed"); - ret = -ENOMEM; - goto error_ret; - } - - /* tx: |add1|addr2|addr3|...|addrN |zero| - * rx: |zero|res1 |res2 |...|resN-1|resN| */ - spi_message_init(&msg); - for (i = 0; i < num + 1; i++) { - if (i > 0) - xfers[i].rx_buf = st->rx + 2*(i - 1); - if (i < num) - xfers[i].tx_buf = st->tx + 2*i; - xfers[i].bits_per_word = 8; - xfers[i].len = 2; - xfers[i].cs_change = 1; - spi_message_add_tail(&xfers[i], &msg); - } - - mutex_lock(&st->buf_lock); - - ret = spi_sync(st->us, &msg); - if (ret) - dev_err(&st->us->dev, "problem when reading sequence"); - - mutex_unlock(&st->buf_lock); - kfree(xfers); - -error_ret: - return ret; -} - -static ssize_t adis16251_spi_read_signed(struct device *dev, - struct device_attribute *attr, - char *buf, - unsigned bits) -{ - int ret; - s16 val = 0; - unsigned shift = 16 - bits; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - - ret = adis16251_spi_read_reg_16(dev, this_attr->address, (u16 *)&val); - if (ret) - return ret; - - if (val & ADIS16251_ERROR_ACTIVE) - adis16251_check_status(dev); - val = ((s16)(val << shift) >> shift); - return sprintf(buf, "%d\n", val); -} - -static ssize_t adis16251_read_12bit_unsigned(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - u16 val = 0; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - - ret = adis16251_spi_read_reg_16(dev, this_attr->address, &val); - if (ret) - return ret; - - if (val & ADIS16251_ERROR_ACTIVE) - adis16251_check_status(dev); - - return sprintf(buf, "%u\n", val & 0x0FFF); -} - -static ssize_t adis16251_read_14bit_signed(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - ssize_t ret; - - /* Take the iio_dev status lock */ - mutex_lock(&indio_dev->mlock); - ret = adis16251_spi_read_signed(dev, attr, buf, 14); - mutex_unlock(&indio_dev->mlock); - - return ret; -} - -static ssize_t adis16251_read_12bit_signed(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - ssize_t ret; - - /* Take the iio_dev status lock */ - mutex_lock(&indio_dev->mlock); - ret = adis16251_spi_read_signed(dev, attr, buf, 12); - mutex_unlock(&indio_dev->mlock); - - return ret; -} - -static ssize_t adis16251_write_16bit(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int ret; - long val; - - ret = strict_strtol(buf, 10, &val); - if (ret) - goto error_ret; - ret = adis16251_spi_write_reg_16(dev, this_attr->address, val); - -error_ret: - return ret ? ret : len; -} - -static ssize_t adis16251_read_frequency(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret, len = 0; - u16 t; - int sps; - ret = adis16251_spi_read_reg_16(dev, - ADIS16251_SMPL_PRD, - &t); - if (ret) - return ret; - sps = (t & ADIS16251_SMPL_PRD_TIME_BASE) ? 8 : 256; - sps /= (t & ADIS16251_SMPL_PRD_DIV_MASK) + 1; - len = sprintf(buf, "%d SPS\n", sps); - return len; -} - -static ssize_t adis16251_write_frequency(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16251_state *st = iio_dev_get_devdata(indio_dev); - long val; - int ret; - u8 t; - - ret = strict_strtol(buf, 10, &val); - if (ret) - return ret; - - mutex_lock(&indio_dev->mlock); - - t = (256 / val); - if (t > 0) - t--; - t &= ADIS16251_SMPL_PRD_DIV_MASK; - if ((t & ADIS16251_SMPL_PRD_DIV_MASK) >= 0x0A) - st->us->max_speed_hz = ADIS16251_SPI_SLOW; - else - st->us->max_speed_hz = ADIS16251_SPI_FAST; - - ret = adis16251_spi_write_reg_8(dev, - ADIS16251_SMPL_PRD, - t); - - mutex_unlock(&indio_dev->mlock); - - return ret ? ret : len; -} - -static ssize_t adis16251_write_reset(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - if (len < 1) - return -1; - switch (buf[0]) { - case '1': - case 'y': - case 'Y': - return adis16251_reset(dev); - } - return -1; -} - - - -int adis16251_set_irq(struct device *dev, bool enable) -{ - int ret; - u16 msc; - ret = adis16251_spi_read_reg_16(dev, ADIS16251_MSC_CTRL, &msc); - if (ret) - goto error_ret; - - msc |= ADIS16251_MSC_CTRL_DATA_RDY_POL_HIGH; - if (enable) - msc |= ADIS16251_MSC_CTRL_DATA_RDY_EN; - else - msc &= ~ADIS16251_MSC_CTRL_DATA_RDY_EN; - - ret = adis16251_spi_write_reg_16(dev, ADIS16251_MSC_CTRL, msc); - if (ret) - goto error_ret; - -error_ret: - return ret; -} - -int adis16251_reset(struct device *dev) -{ - int ret; - ret = adis16251_spi_write_reg_8(dev, - ADIS16251_GLOB_CMD, - ADIS16251_GLOB_CMD_SW_RESET); - if (ret) - dev_err(dev, "problem resetting device"); - - return ret; -} - -/* Power down the device */ -int adis16251_stop_device(struct device *dev) -{ - int ret; - u16 val = ADIS16251_SLP_CNT_POWER_OFF; - - ret = adis16251_spi_write_reg_16(dev, ADIS16251_SLP_CNT, val); - if (ret) - dev_err(dev, "problem with turning device off: SLP_CNT"); - - return ret; -} - -static int adis16251_self_test(struct device *dev) -{ - int ret; - - ret = adis16251_spi_write_reg_16(dev, - ADIS16251_MSC_CTRL, - ADIS16251_MSC_CTRL_INT_SELF_TEST); - if (ret) { - dev_err(dev, "problem starting self test"); - goto err_ret; - } - - adis16251_check_status(dev); - -err_ret: - return ret; -} - -int adis16251_check_status(struct device *dev) -{ - u16 status; - int ret; - - ret = adis16251_spi_read_reg_16(dev, ADIS16251_DIAG_STAT, &status); - - if (ret < 0) { - dev_err(dev, "Reading status failed\n"); - goto error_ret; - } - - if (!(status & ADIS16251_DIAG_STAT_ERR_MASK)) { - ret = 0; - goto error_ret; - } - - ret = -EFAULT; - - if (status & ADIS16251_DIAG_STAT_ALARM2) - dev_err(dev, "Alarm 2 active\n"); - if (status & ADIS16251_DIAG_STAT_ALARM1) - dev_err(dev, "Alarm 1 active\n"); - if (status & ADIS16251_DIAG_STAT_SELF_TEST) - dev_err(dev, "Self test error\n"); - if (status & ADIS16251_DIAG_STAT_OVERFLOW) - dev_err(dev, "Sensor overrange\n"); - if (status & ADIS16251_DIAG_STAT_SPI_FAIL) - dev_err(dev, "SPI failure\n"); - if (status & ADIS16251_DIAG_STAT_FLASH_UPT) - dev_err(dev, "Flash update failed\n"); - if (status & ADIS16251_DIAG_STAT_POWER_HIGH) - dev_err(dev, "Power supply above 5.25V\n"); - if (status & ADIS16251_DIAG_STAT_POWER_LOW) - dev_err(dev, "Power supply below 4.75V\n"); - -error_ret: - return ret; -} - -static int adis16251_initial_setup(struct adis16251_state *st) -{ - int ret; - u16 smp_prd; - struct device *dev = &st->indio_dev->dev; - - /* use low spi speed for init */ - st->us->max_speed_hz = ADIS16251_SPI_SLOW; - st->us->mode = SPI_MODE_3; - spi_setup(st->us); - - /* Disable IRQ */ - ret = adis16251_set_irq(dev, false); - if (ret) { - dev_err(dev, "disable irq failed"); - goto err_ret; - } - - /* Do self test */ - - /* Read status register to check the result */ - ret = adis16251_check_status(dev); - if (ret) { - adis16251_reset(dev); - dev_err(dev, "device not playing ball -> reset"); - msleep(ADIS16251_STARTUP_DELAY); - ret = adis16251_check_status(dev); - if (ret) { - dev_err(dev, "giving up"); - goto err_ret; - } - } - - printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n", - st->us->chip_select, st->us->irq); - - /* use high spi speed if possible */ - ret = adis16251_spi_read_reg_16(dev, ADIS16251_SMPL_PRD, &smp_prd); - if (!ret && (smp_prd & ADIS16251_SMPL_PRD_DIV_MASK) < 0x0A) { - st->us->max_speed_hz = ADIS16251_SPI_SLOW; - spi_setup(st->us); - } - -err_ret: - return ret; -} - -static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16251_read_12bit_signed, - ADIS16251_SUPPLY_OUT); -static IIO_CONST_ATTR(in0_supply_scale, "0.0018315"); - -static IIO_DEV_ATTR_GYRO(adis16251_read_14bit_signed, - ADIS16251_GYRO_OUT); -static IIO_DEV_ATTR_GYRO_SCALE(S_IWUSR | S_IRUGO, - adis16251_read_12bit_signed, - adis16251_write_16bit, - ADIS16251_GYRO_SCALE); -static IIO_DEV_ATTR_GYRO_OFFSET(S_IWUSR | S_IRUGO, - adis16251_read_12bit_signed, - adis16251_write_16bit, - ADIS16251_GYRO_OFF); - -static IIO_DEV_ATTR_TEMP_RAW(adis16251_read_12bit_signed); -static IIO_CONST_ATTR(temp_offset, "25 K"); -static IIO_CONST_ATTR(temp_scale, "0.1453 K"); - -static IIO_DEV_ATTR_IN_NAMED_RAW(1, aux, adis16251_read_12bit_unsigned, - ADIS16251_AUX_ADC); -static IIO_CONST_ATTR(in1_aux_scale, "0.0006105"); - -static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, - adis16251_read_frequency, - adis16251_write_frequency); -static IIO_DEV_ATTR_ANGL(adis16251_read_14bit_signed, - ADIS16251_ANGL_OUT); - -static IIO_DEV_ATTR_RESET(adis16251_write_reset); - -static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("0.129 ~ 256"); - -static IIO_CONST_ATTR(name, "adis16251"); - -static struct attribute *adis16251_event_attributes[] = { - NULL -}; - -static struct attribute_group adis16251_event_attribute_group = { - .attrs = adis16251_event_attributes, -}; - -static struct attribute *adis16251_attributes[] = { - &iio_dev_attr_in0_supply_raw.dev_attr.attr, - &iio_const_attr_in0_supply_scale.dev_attr.attr, - &iio_dev_attr_gyro_raw.dev_attr.attr, - &iio_dev_attr_gyro_scale.dev_attr.attr, - &iio_dev_attr_gyro_offset.dev_attr.attr, - &iio_dev_attr_angl_raw.dev_attr.attr, - &iio_dev_attr_temp_raw.dev_attr.attr, - &iio_const_attr_temp_offset.dev_attr.attr, - &iio_const_attr_temp_scale.dev_attr.attr, - &iio_dev_attr_in1_aux_raw.dev_attr.attr, - &iio_const_attr_in1_aux_scale.dev_attr.attr, - &iio_dev_attr_sampling_frequency.dev_attr.attr, - &iio_const_attr_sampling_frequency_available.dev_attr.attr, - &iio_dev_attr_reset.dev_attr.attr, - &iio_const_attr_name.dev_attr.attr, - NULL -}; - -static const struct attribute_group adis16251_attribute_group = { - .attrs = adis16251_attributes, -}; - -static int __devinit adis16251_probe(struct spi_device *spi) -{ - int ret, regdone = 0; - struct adis16251_state *st = kzalloc(sizeof *st, GFP_KERNEL); - if (!st) { - ret = -ENOMEM; - goto error_ret; - } - /* this is only used for removal purposes */ - spi_set_drvdata(spi, st); - - /* Allocate the comms buffers */ - st->rx = kzalloc(sizeof(*st->rx)*ADIS16251_MAX_RX, GFP_KERNEL); - if (st->rx == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->tx = kzalloc(sizeof(*st->tx)*ADIS16251_MAX_TX, GFP_KERNEL); - if (st->tx == NULL) { - ret = -ENOMEM; - goto error_free_rx; - } - st->us = spi; - mutex_init(&st->buf_lock); - /* setup the industrialio driver allocated elements */ - st->indio_dev = iio_allocate_device(); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_tx; - } - - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->num_interrupt_lines = 1; - st->indio_dev->event_attrs = &adis16251_event_attribute_group; - st->indio_dev->attrs = &adis16251_attribute_group; - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->driver_module = THIS_MODULE; - st->indio_dev->modes = INDIO_DIRECT_MODE; - - ret = adis16251_configure_ring(st->indio_dev); - if (ret) - goto error_free_dev; - - ret = iio_device_register(st->indio_dev); - if (ret) - goto error_unreg_ring_funcs; - regdone = 1; - - ret = adis16251_initialize_ring(st->indio_dev->ring); - if (ret) { - printk(KERN_ERR "failed to initialize the ring\n"); - goto error_unreg_ring_funcs; - } - - if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) { - ret = iio_register_interrupt_line(spi->irq, - st->indio_dev, - 0, - IRQF_TRIGGER_RISING, - "adis16251"); - if (ret) - goto error_uninitialize_ring; - - ret = adis16251_probe_trigger(st->indio_dev); - if (ret) - goto error_unregister_line; - } - - /* Get the device into a sane initial state */ - ret = adis16251_initial_setup(st); - if (ret) - goto error_remove_trigger; - return 0; - -error_remove_trigger: - if (st->indio_dev->modes & INDIO_RING_TRIGGERED) - adis16251_remove_trigger(st->indio_dev); -error_unregister_line: - if (st->indio_dev->modes & INDIO_RING_TRIGGERED) - iio_unregister_interrupt_line(st->indio_dev, 0); -error_uninitialize_ring: - adis16251_uninitialize_ring(st->indio_dev->ring); -error_unreg_ring_funcs: - adis16251_unconfigure_ring(st->indio_dev); -error_free_dev: - if (regdone) - iio_device_unregister(st->indio_dev); - else - iio_free_device(st->indio_dev); -error_free_tx: - kfree(st->tx); -error_free_rx: - kfree(st->rx); -error_free_st: - kfree(st); -error_ret: - return ret; -} - -/* fixme, confirm ordering in this function */ -static int adis16251_remove(struct spi_device *spi) -{ - int ret; - struct adis16251_state *st = spi_get_drvdata(spi); - struct iio_dev *indio_dev = st->indio_dev; - - ret = adis16251_stop_device(&(indio_dev->dev)); - if (ret) - goto err_ret; - - flush_scheduled_work(); - - adis16251_remove_trigger(indio_dev); - if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) - iio_unregister_interrupt_line(indio_dev, 0); - - adis16251_uninitialize_ring(indio_dev->ring); - adis16251_unconfigure_ring(indio_dev); - iio_device_unregister(indio_dev); - kfree(st->tx); - kfree(st->rx); - kfree(st); - - return 0; - -err_ret: - return ret; -} - -static struct spi_driver adis16251_driver = { - .driver = { - .name = "adis16251", - .owner = THIS_MODULE, - }, - .probe = adis16251_probe, - .remove = __devexit_p(adis16251_remove), -}; - -static __init int adis16251_init(void) -{ - return spi_register_driver(&adis16251_driver); -} -module_init(adis16251_init); - -static __exit void adis16251_exit(void) -{ - spi_unregister_driver(&adis16251_driver); -} -module_exit(adis16251_exit); - -MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); -MODULE_DESCRIPTION("Analog Devices ADIS16251 Digital Gyroscope Sensor SPI driver"); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 8e67875141b263ada64b7c74f0e593b6686ea8ed Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 26 Feb 2011 17:30:18 +0000 Subject: staging:iio:gyro: adis16130 cleanup, move to abi and bug fixes. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/gyro/adis16130.h | 42 --------- drivers/staging/iio/gyro/adis16130_core.c | 148 ++++++++++++++---------------- 2 files changed, 69 insertions(+), 121 deletions(-) delete mode 100644 drivers/staging/iio/gyro/adis16130.h (limited to 'drivers') diff --git a/drivers/staging/iio/gyro/adis16130.h b/drivers/staging/iio/gyro/adis16130.h deleted file mode 100644 index 9efc4c773207..000000000000 --- a/drivers/staging/iio/gyro/adis16130.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef SPI_ADIS16130_H_ -#define SPI_ADIS16130_H_ - -#define ADIS16130_CON 0x0 -#define ADIS16130_CON_RD (1 << 6) -#define ADIS16130_IOP 0x1 - -/* 1 = data-ready signal low when unread data on all channels; */ -#define ADIS16130_IOP_ALL_RDY (1 << 3) -#define ADIS16130_IOP_SYNC (1 << 0) /* 1 = synchronization enabled */ -#define ADIS16130_RATEDATA 0x8 /* Gyroscope output, rate of rotation */ -#define ADIS16130_TEMPDATA 0xA /* Temperature output */ -#define ADIS16130_RATECS 0x28 /* Gyroscope channel setup */ -#define ADIS16130_RATECS_EN (1 << 3) /* 1 = channel enable; */ -#define ADIS16130_TEMPCS 0x2A /* Temperature channel setup */ -#define ADIS16130_TEMPCS_EN (1 << 3) -#define ADIS16130_RATECONV 0x30 -#define ADIS16130_TEMPCONV 0x32 -#define ADIS16130_MODE 0x38 -#define ADIS16130_MODE_24BIT (1 << 1) /* 1 = 24-bit resolution; */ - -#define ADIS16130_MAX_TX 4 -#define ADIS16130_MAX_RX 4 - -/** - * struct adis16130_state - device instance specific data - * @us: actual spi_device to write data - * @indio_dev: industrial I/O device structure - * @tx: transmit buffer - * @rx: recieve buffer - * @buf_lock: mutex to protect tx and rx - **/ -struct adis16130_state { - struct spi_device *us; - struct iio_dev *indio_dev; - u8 *tx; - u8 *rx; - u32 mode; /* 1: 24bits mode 0:16bits mode */ - struct mutex buf_lock; -}; - -#endif /* SPI_ADIS16130_H_ */ diff --git a/drivers/staging/iio/gyro/adis16130_core.c b/drivers/staging/iio/gyro/adis16130_core.c index 04d81d4b2cf2..70e2831f8fb8 100644 --- a/drivers/staging/iio/gyro/adis16130_core.c +++ b/drivers/staging/iio/gyro/adis16130_core.c @@ -6,9 +6,6 @@ * Licensed under the GPL-2 or later. */ -#include -#include -#include #include #include #include @@ -23,7 +20,39 @@ #include "gyro.h" #include "../adc/adc.h" -#include "adis16130.h" +#define ADIS16130_CON 0x0 +#define ADIS16130_CON_RD (1 << 6) +#define ADIS16130_IOP 0x1 + +/* 1 = data-ready signal low when unread data on all channels; */ +#define ADIS16130_IOP_ALL_RDY (1 << 3) +#define ADIS16130_IOP_SYNC (1 << 0) /* 1 = synchronization enabled */ +#define ADIS16130_RATEDATA 0x8 /* Gyroscope output, rate of rotation */ +#define ADIS16130_TEMPDATA 0xA /* Temperature output */ +#define ADIS16130_RATECS 0x28 /* Gyroscope channel setup */ +#define ADIS16130_RATECS_EN (1 << 3) /* 1 = channel enable; */ +#define ADIS16130_TEMPCS 0x2A /* Temperature channel setup */ +#define ADIS16130_TEMPCS_EN (1 << 3) +#define ADIS16130_RATECONV 0x30 +#define ADIS16130_TEMPCONV 0x32 +#define ADIS16130_MODE 0x38 +#define ADIS16130_MODE_24BIT (1 << 1) /* 1 = 24-bit resolution; */ + +/** + * struct adis16130_state - device instance specific data + * @us: actual spi_device to write data + * @indio_dev: industrial I/O device structure + * @mode: 24 bits (1) or 16 bits (0) + * @buf_lock: mutex to protect tx and rx + * @buf: unified tx/rx buffer + **/ +struct adis16130_state { + struct spi_device *us; + struct iio_dev *indio_dev; + u32 mode; + struct mutex buf_lock; + u8 buf[4] ____cacheline_aligned; +}; static int adis16130_spi_write(struct device *dev, u8 reg_addr, u8 val) @@ -33,10 +62,10 @@ static int adis16130_spi_write(struct device *dev, u8 reg_addr, struct adis16130_state *st = iio_dev_get_devdata(indio_dev); mutex_lock(&st->buf_lock); - st->tx[0] = reg_addr; - st->tx[1] = val; + st->buf[0] = reg_addr; + st->buf[1] = val; - ret = spi_write(st->us, st->tx, 2); + ret = spi_write(st->us, st->buf, 2); mutex_unlock(&st->buf_lock); return ret; @@ -51,17 +80,19 @@ static int adis16130_spi_read(struct device *dev, u8 reg_addr, mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16130_CON_RD | reg_addr; + st->buf[0] = ADIS16130_CON_RD | reg_addr; if (st->mode) - ret = spi_read(st->us, st->rx, 4); + ret = spi_read(st->us, st->buf, 4); else - ret = spi_read(st->us, st->rx, 3); + ret = spi_read(st->us, st->buf, 3); if (ret == 0) { if (st->mode) - *val = (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3]; + *val = (st->buf[1] << 16) | + (st->buf[2] << 8) | + st->buf[3]; else - *val = (st->rx[1] << 8) | st->rx[2]; + *val = (st->buf[1] << 8) | st->buf[2]; } mutex_unlock(&st->buf_lock); @@ -69,36 +100,18 @@ static int adis16130_spi_read(struct device *dev, u8 reg_addr, return ret; } -static ssize_t adis16130_gyro_read(struct device *dev, +static ssize_t adis16130_val_read(struct device *dev, struct device_attribute *attr, char *buf) { + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_dev *indio_dev = dev_get_drvdata(dev); u32 val; ssize_t ret; /* Take the iio_dev status lock */ mutex_lock(&indio_dev->mlock); - ret = adis16130_spi_read(dev, ADIS16130_RATEDATA, &val); - mutex_unlock(&indio_dev->mlock); - - if (ret == 0) - return sprintf(buf, "%d\n", val); - else - return ret; -} - -static ssize_t adis16130_temp_read(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - u32 val; - ssize_t ret; - - /* Take the iio_dev status lock */ - mutex_lock(&indio_dev->mlock); - ret = adis16130_spi_read(dev, ADIS16130_TEMPDATA, &val); + ret = adis16130_spi_read(dev, this_attr->address, &val); mutex_unlock(&indio_dev->mlock); if (ret == 0) @@ -114,7 +127,10 @@ static ssize_t adis16130_bitsmode_read(struct device *dev, struct iio_dev *indio_dev = dev_get_drvdata(dev); struct adis16130_state *st = iio_dev_get_devdata(indio_dev); - return sprintf(buf, "%d\n", st->mode); + if (st->mode == 1) + return sprintf(buf, "s24\n"); + else + return sprintf(buf, "s16\n"); } static ssize_t adis16130_bitsmode_write(struct device *dev, @@ -123,44 +139,38 @@ static ssize_t adis16130_bitsmode_write(struct device *dev, size_t len) { int ret; - long val; + u8 val; - ret = strict_strtol(buf, 16, &val); - if (ret) - goto error_ret; - ret = adis16130_spi_write(dev, ADIS16130_MODE, !!val); + if (sysfs_streq(buf, "s16")) + val = 0; + else if (sysfs_streq(buf, "s24")) + val = 1; + else + return -EINVAL; + + ret = adis16130_spi_write(dev, ADIS16130_MODE, val); -error_ret: return ret ? ret : len; } - -static IIO_DEV_ATTR_TEMP_RAW(adis16130_temp_read); +static IIO_DEVICE_ATTR(temp_raw, S_IRUGO, adis16130_val_read, NULL, + ADIS16130_TEMPDATA); static IIO_CONST_ATTR(name, "adis16130"); -static IIO_DEV_ATTR_GYRO(adis16130_gyro_read, - ADIS16130_RATEDATA); - -#define IIO_DEV_ATTR_BITS_MODE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(bits_mode, _mode, _show, _store, _addr) +static IIO_DEV_ATTR_GYRO_Z(adis16130_val_read, ADIS16130_RATEDATA); -static IIO_DEV_ATTR_BITS_MODE(S_IWUSR | S_IRUGO, adis16130_bitsmode_read, +static IIO_DEVICE_ATTR(gyro_z_type, S_IWUSR | S_IRUGO, adis16130_bitsmode_read, adis16130_bitsmode_write, ADIS16130_MODE); -static struct attribute *adis16130_event_attributes[] = { - NULL -}; - -static struct attribute_group adis16130_event_attribute_group = { - .attrs = adis16130_event_attributes, -}; +static IIO_CONST_ATTR(gyro_z_type_available, "s16 s24"); static struct attribute *adis16130_attributes[] = { &iio_dev_attr_temp_raw.dev_attr.attr, &iio_const_attr_name.dev_attr.attr, - &iio_dev_attr_gyro_raw.dev_attr.attr, - &iio_dev_attr_bits_mode.dev_attr.attr, + &iio_dev_attr_gyro_z_raw.dev_attr.attr, + &iio_dev_attr_gyro_z_type.dev_attr.attr, + &iio_const_attr_gyro_z_type_available.dev_attr.attr, NULL }; @@ -178,30 +188,16 @@ static int __devinit adis16130_probe(struct spi_device *spi) } /* this is only used for removal purposes */ spi_set_drvdata(spi, st); - - /* Allocate the comms buffers */ - st->rx = kzalloc(sizeof(*st->rx)*ADIS16130_MAX_RX, GFP_KERNEL); - if (st->rx == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->tx = kzalloc(sizeof(*st->tx)*ADIS16130_MAX_TX, GFP_KERNEL); - if (st->tx == NULL) { - ret = -ENOMEM; - goto error_free_rx; - } st->us = spi; mutex_init(&st->buf_lock); /* setup the industrialio driver allocated elements */ st->indio_dev = iio_allocate_device(); if (st->indio_dev == NULL) { ret = -ENOMEM; - goto error_free_tx; + goto error_free_st; } st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->num_interrupt_lines = 1; - st->indio_dev->event_attrs = &adis16130_event_attribute_group; st->indio_dev->attrs = &adis16130_attribute_group; st->indio_dev->dev_data = (void *)(st); st->indio_dev->driver_module = THIS_MODULE; @@ -216,10 +212,6 @@ static int __devinit adis16130_probe(struct spi_device *spi) error_free_dev: iio_free_device(st->indio_dev); -error_free_tx: - kfree(st->tx); -error_free_rx: - kfree(st->rx); error_free_st: kfree(st); error_ret: @@ -233,8 +225,6 @@ static int adis16130_remove(struct spi_device *spi) struct iio_dev *indio_dev = st->indio_dev; iio_device_unregister(indio_dev); - kfree(st->tx); - kfree(st->rx); kfree(st); return 0; @@ -262,5 +252,5 @@ static __exit void adis16130_exit(void) module_exit(adis16130_exit); MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); -MODULE_DESCRIPTION("Analog Devices ADIS16130 High Precision Angular Rate Sensor driver"); +MODULE_DESCRIPTION("Analog Devices ADIS16130 High Precision Angular Rate"); MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 14f983264a74a5734541e094d97a0e681b2f3bb2 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 28 Feb 2011 12:33:42 +0000 Subject: staging:iio:gyro: adis16060 cleanup, move to abi and bug fixes. Moved to standard sysfs naming and got rid of direct register writing from userspace. The rx and tx buffers are never used together so just have one and avoid the need to malloc it by using putting it in the state structure and using the ____cacheline_aligned trick. A number of obvious bugs also fixed and correction of register address defines in header which has now been squashed into the driver. I don't have one of these so can't test. This is done off datasheet. Note that the driver had parts that definitely wouldn't work before this patch. Now it 'might' assuming I haven't messed up too badly. I've left fixing the fact that you can only have one of these on a given machine for another day. Signed-off-by: Jonathan Cameron Acked-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/gyro/adis16060.h | 31 -------- drivers/staging/iio/gyro/adis16060_core.c | 125 ++++++++++++------------------ 2 files changed, 49 insertions(+), 107 deletions(-) delete mode 100644 drivers/staging/iio/gyro/adis16060.h (limited to 'drivers') diff --git a/drivers/staging/iio/gyro/adis16060.h b/drivers/staging/iio/gyro/adis16060.h deleted file mode 100644 index e85121bff57e..000000000000 --- a/drivers/staging/iio/gyro/adis16060.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef SPI_ADIS16060_H_ -#define SPI_ADIS16060_H_ - -#define ADIS16060_GYRO 0x20 /* Measure Angular Rate (Gyro) */ -#define ADIS16060_SUPPLY_OUT 0x10 /* Measure Temperature */ -#define ADIS16060_AIN2 0x80 /* Measure AIN2 */ -#define ADIS16060_AIN1 0x40 /* Measure AIN1 */ -#define ADIS16060_TEMP_OUT 0x22 /* Set Positive Self-Test and Output for Angular Rate */ -#define ADIS16060_ANGL_OUT 0x21 /* Set Negative Self-Test and Output for Angular Rate */ - -#define ADIS16060_MAX_TX 3 -#define ADIS16060_MAX_RX 3 - -/** - * struct adis16060_state - device instance specific data - * @us_w: actual spi_device to write data - * @indio_dev: industrial I/O device structure - * @tx: transmit buffer - * @rx: recieve buffer - * @buf_lock: mutex to protect tx and rx - **/ -struct adis16060_state { - struct spi_device *us_w; - struct spi_device *us_r; - struct iio_dev *indio_dev; - u8 *tx; - u8 *rx; - struct mutex buf_lock; -}; - -#endif /* SPI_ADIS16060_H_ */ diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c index 11f51f28d706..700eb3980f9e 100644 --- a/drivers/staging/iio/gyro/adis16060_core.c +++ b/drivers/staging/iio/gyro/adis16060_core.c @@ -6,9 +6,6 @@ * Licensed under the GPL-2 or later. */ -#include -#include -#include #include #include #include @@ -16,14 +13,34 @@ #include #include #include -#include + #include "../iio.h" #include "../sysfs.h" #include "gyro.h" #include "../adc/adc.h" -#include "adis16060.h" +#define ADIS16060_GYRO 0x20 /* Measure Angular Rate (Gyro) */ +#define ADIS16060_TEMP_OUT 0x10 /* Measure Temperature */ +#define ADIS16060_AIN2 0x80 /* Measure AIN2 */ +#define ADIS16060_AIN1 0x40 /* Measure AIN1 */ + +/** + * struct adis16060_state - device instance specific data + * @us_w: actual spi_device to write config + * @us_r: actual spi_device to read back data + * @indio_dev: industrial I/O device structure + * @buf: transmit or recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct adis16060_state { + struct spi_device *us_w; + struct spi_device *us_r; + struct iio_dev *indio_dev; + struct mutex buf_lock; + + u8 buf[3] ____cacheline_aligned; +}; static struct adis16060_state *adis16060_st; @@ -35,11 +52,8 @@ static int adis16060_spi_write(struct device *dev, struct adis16060_state *st = iio_dev_get_devdata(indio_dev); mutex_lock(&st->buf_lock); - st->tx[0] = 0; - st->tx[1] = 0; - st->tx[2] = val; /* The last 8 bits clocked in are latched */ - - ret = spi_write(st->us_w, st->tx, 3); + st->buf[2] = val; /* The last 8 bits clocked in are latched */ + ret = spi_write(st->us_w, st->buf, 3); mutex_unlock(&st->buf_lock); return ret; @@ -54,7 +68,7 @@ static int adis16060_spi_read(struct device *dev, mutex_lock(&st->buf_lock); - ret = spi_read(st->us_r, st->rx, 3); + ret = spi_read(st->us_r, st->buf, 3); /* The internal successive approximation ADC begins the * conversion process on the falling edge of MSEL1 and @@ -62,9 +76,9 @@ static int adis16060_spi_read(struct device *dev, * the 6th falling edge of SCLK */ if (ret == 0) - *val = ((st->rx[0] & 0x3) << 12) | - (st->rx[1] << 4) | - ((st->rx[2] >> 4) & 0xF); + *val = ((st->buf[0] & 0x3) << 12) | + (st->buf[1] << 4) | + ((st->buf[2] >> 4) & 0xF); mutex_unlock(&st->buf_lock); return ret; @@ -74,13 +88,19 @@ static ssize_t adis16060_read(struct device *dev, struct device_attribute *attr, char *buf) { + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_dev *indio_dev = dev_get_drvdata(dev); u16 val = 0; ssize_t ret; /* Take the iio_dev status lock */ mutex_lock(&indio_dev->mlock); - ret = adis16060_spi_read(dev, &val); + + ret = adis16060_spi_write(dev, this_attr->address); + if (ret < 0) + goto error_ret; + ret = adis16060_spi_read(dev, &val); +error_ret: mutex_unlock(&indio_dev->mlock); if (ret == 0) @@ -89,45 +109,22 @@ static ssize_t adis16060_read(struct device *dev, return ret; } -static ssize_t adis16060_write(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - int ret; - long val; - - ret = strict_strtol(buf, 16, &val); - if (ret) - goto error_ret; - ret = adis16060_spi_write(dev, val); - -error_ret: - return ret ? ret : len; -} - -#define IIO_DEV_ATTR_IN(_show) \ - IIO_DEVICE_ATTR(in, S_IRUGO, _show, NULL, 0) - -#define IIO_DEV_ATTR_OUT(_store) \ - IIO_DEVICE_ATTR(out, S_IRUGO, NULL, _store, 0) - -static IIO_DEV_ATTR_IN(adis16060_read); -static IIO_DEV_ATTR_OUT(adis16060_write); - +static IIO_DEV_ATTR_GYRO_Z(adis16060_read, ADIS16060_GYRO); +static IIO_DEVICE_ATTR(temp_raw, S_IRUGO, adis16060_read, NULL, + ADIS16060_TEMP_OUT); +static IIO_CONST_ATTR_TEMP_SCALE("34"); /* Milli degrees C */ +static IIO_CONST_ATTR_TEMP_OFFSET("-7461.117"); /* Milli degrees C */ +static IIO_DEV_ATTR_IN_RAW(0, adis16060_read, ADIS16060_AIN1); +static IIO_DEV_ATTR_IN_RAW(1, adis16060_read, ADIS16060_AIN2); static IIO_CONST_ATTR(name, "adis16060"); -static struct attribute *adis16060_event_attributes[] = { - NULL -}; - -static struct attribute_group adis16060_event_attribute_group = { - .attrs = adis16060_event_attributes, -}; - static struct attribute *adis16060_attributes[] = { - &iio_dev_attr_in.dev_attr.attr, - &iio_dev_attr_out.dev_attr.attr, + &iio_dev_attr_gyro_z_raw.dev_attr.attr, + &iio_dev_attr_temp_raw.dev_attr.attr, + &iio_const_attr_temp_scale.dev_attr.attr, + &iio_const_attr_temp_offset.dev_attr.attr, + &iio_dev_attr_in0_raw.dev_attr.attr, + &iio_dev_attr_in1_raw.dev_attr.attr, &iio_const_attr_name.dev_attr.attr, NULL }; @@ -147,29 +144,16 @@ static int __devinit adis16060_r_probe(struct spi_device *spi) /* this is only used for removal purposes */ spi_set_drvdata(spi, st); - /* Allocate the comms buffers */ - st->rx = kzalloc(sizeof(*st->rx)*ADIS16060_MAX_RX, GFP_KERNEL); - if (st->rx == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->tx = kzalloc(sizeof(*st->tx)*ADIS16060_MAX_TX, GFP_KERNEL); - if (st->tx == NULL) { - ret = -ENOMEM; - goto error_free_rx; - } st->us_r = spi; mutex_init(&st->buf_lock); /* setup the industrialio driver allocated elements */ st->indio_dev = iio_allocate_device(); if (st->indio_dev == NULL) { ret = -ENOMEM; - goto error_free_tx; + goto error_free_st; } st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->num_interrupt_lines = 1; - st->indio_dev->event_attrs = &adis16060_event_attribute_group; st->indio_dev->attrs = &adis16060_attribute_group; st->indio_dev->dev_data = (void *)(st); st->indio_dev->driver_module = THIS_MODULE; @@ -188,10 +172,6 @@ error_free_dev: iio_device_unregister(st->indio_dev); else iio_free_device(st->indio_dev); -error_free_tx: - kfree(st->tx); -error_free_rx: - kfree(st->rx); error_free_st: kfree(st); error_ret: @@ -204,14 +184,7 @@ static int adis16060_r_remove(struct spi_device *spi) struct adis16060_state *st = spi_get_drvdata(spi); struct iio_dev *indio_dev = st->indio_dev; - flush_scheduled_work(); - - if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) - iio_unregister_interrupt_line(indio_dev, 0); - iio_device_unregister(indio_dev); - kfree(st->tx); - kfree(st->rx); kfree(st); return 0; -- cgit v1.2.3 From b75ae07963f99f89319b17935af20513d57df577 Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Thu, 24 Feb 2011 08:06:53 -0600 Subject: staging: delete ti-st from staging The 2 drivers originally staged, the core ti-st driver and the btwilink bluetooth driver have now moved to relevant directories, so deleting the ti-st/ from staging. Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/ti-st/Kconfig | 14 -- drivers/staging/ti-st/Makefile | 5 - drivers/staging/ti-st/TODO | 8 - drivers/staging/ti-st/btwilink.c | 363 --------------------------------------- drivers/staging/ti-st/sysfs-uim | 28 --- 7 files changed, 421 deletions(-) delete mode 100644 drivers/staging/ti-st/Kconfig delete mode 100644 drivers/staging/ti-st/Makefile delete mode 100644 drivers/staging/ti-st/TODO delete mode 100644 drivers/staging/ti-st/btwilink.c delete mode 100644 drivers/staging/ti-st/sysfs-uim (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 4b137a6d9937..5295d8518d19 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -143,8 +143,6 @@ source "drivers/staging/crystalhd/Kconfig" source "drivers/staging/cxt1e1/Kconfig" -source "drivers/staging/ti-st/Kconfig" - source "drivers/staging/xgifb/Kconfig" source "drivers/staging/msm/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index dcd47dba0e9a..0983edca5bd2 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -54,7 +54,6 @@ obj-$(CONFIG_FB_SM7XX) += sm7xx/ obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/ obj-$(CONFIG_CRYSTALHD) += crystalhd/ obj-$(CONFIG_CXT1E1) += cxt1e1/ -obj-$(CONFIG_TI_ST) += ti-st/ obj-$(CONFIG_FB_XGI) += xgifb/ obj-$(CONFIG_MSM_STAGING) += msm/ obj-$(CONFIG_EASYCAP) += easycap/ diff --git a/drivers/staging/ti-st/Kconfig b/drivers/staging/ti-st/Kconfig deleted file mode 100644 index 074b8e89e913..000000000000 --- a/drivers/staging/ti-st/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -# -# TI's shared transport line discipline and the protocol -# drivers (BT, FM and GPS) -# -menu "Texas Instruments shared transport line discipline" -config ST_BT - tristate "BlueZ bluetooth driver for ST" - depends on BT && RFKILL - select TI_ST - help - This enables the Bluetooth driver for TI BT/FM/GPS combo devices. - This makes use of shared transport line discipline core driver to - communicate with the BT core of the combo chip. -endmenu diff --git a/drivers/staging/ti-st/Makefile b/drivers/staging/ti-st/Makefile deleted file mode 100644 index 9125462807d4..000000000000 --- a/drivers/staging/ti-st/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for TI's shared transport line discipline -# and its protocol drivers (BT, FM, GPS) -# -obj-$(CONFIG_ST_BT) += btwilink.o diff --git a/drivers/staging/ti-st/TODO b/drivers/staging/ti-st/TODO deleted file mode 100644 index ebfd6bb60176..000000000000 --- a/drivers/staging/ti-st/TODO +++ /dev/null @@ -1,8 +0,0 @@ -TODO: - -1. Step up and maintain this driver to ensure that it continues -to work. Having the hardware for this is pretty much a -requirement. If this does not happen, the will be removed in -the 2.6.35 kernel release. - -Please send patches to Greg Kroah-Hartman . diff --git a/drivers/staging/ti-st/btwilink.c b/drivers/staging/ti-st/btwilink.c deleted file mode 100644 index 71e69f8394c9..000000000000 --- a/drivers/staging/ti-st/btwilink.c +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Texas Instrument's Bluetooth Driver For Shared Transport. - * - * Bluetooth Driver acts as interface between HCI core and - * TI Shared Transport Layer. - * - * Copyright (C) 2009-2010 Texas Instruments - * Author: Raja Mani - * Pavan Savoy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include - -#include - -/* Bluetooth Driver Version */ -#define VERSION "1.0" - -/* Number of seconds to wait for registration completion - * when ST returns PENDING status. - */ -#define BT_REGISTER_TIMEOUT 6000 /* 6 sec */ - -/** - * struct ti_st - driver operation structure - * @hdev: hci device pointer which binds to bt driver - * @reg_status: ST registration callback status - * @st_write: write function provided by the ST driver - * to be used by the driver during send_frame. - * @wait_reg_completion - completion sync between ti_st_open - * and ti_st_registration_completion_cb. - */ -struct ti_st { - struct hci_dev *hdev; - char reg_status; - long (*st_write) (struct sk_buff *); - struct completion wait_reg_completion; -}; - -/* Increments HCI counters based on pocket ID (cmd,acl,sco) */ -static inline void ti_st_tx_complete(struct ti_st *hst, int pkt_type) -{ - struct hci_dev *hdev = hst->hdev; - - /* Update HCI stat counters */ - switch (pkt_type) { - case HCI_COMMAND_PKT: - hdev->stat.cmd_tx++; - break; - - case HCI_ACLDATA_PKT: - hdev->stat.acl_tx++; - break; - - case HCI_SCODATA_PKT: - hdev->stat.sco_tx++; - break; - } -} - -/* ------- Interfaces to Shared Transport ------ */ - -/* Called by ST layer to indicate protocol registration completion - * status.ti_st_open() function will wait for signal from this - * API when st_register() function returns ST_PENDING. - */ -static void st_registration_completion_cb(void *priv_data, char data) -{ - struct ti_st *lhst = priv_data; - - /* Save registration status for use in ti_st_open() */ - lhst->reg_status = data; - /* complete the wait in ti_st_open() */ - complete(&lhst->wait_reg_completion); -} - -/* Called by Shared Transport layer when receive data is - * available */ -static long st_receive(void *priv_data, struct sk_buff *skb) -{ - struct ti_st *lhst = priv_data; - int err; - - if (!skb) - return -EFAULT; - - if (!lhst) { - kfree_skb(skb); - return -EFAULT; - } - - skb->dev = (void *) lhst->hdev; - - /* Forward skb to HCI core layer */ - err = hci_recv_frame(skb); - if (err < 0) { - BT_ERR("Unable to push skb to HCI core(%d)", err); - return err; - } - - lhst->hdev->stat.byte_rx += skb->len; - - return 0; -} - -/* ------- Interfaces to HCI layer ------ */ -/* protocol structure registered with shared transport */ -static struct st_proto_s ti_st_proto = { - .type = ST_BT, - .recv = st_receive, - .reg_complete_cb = st_registration_completion_cb, -}; - -/* Called from HCI core to initialize the device */ -static int ti_st_open(struct hci_dev *hdev) -{ - unsigned long timeleft; - struct ti_st *hst; - int err; - - BT_DBG("%s %p", hdev->name, hdev); - if (test_and_set_bit(HCI_RUNNING, &hdev->flags)) { - BT_ERR("btwilink already opened"); - return -EBUSY; - } - - /* provide contexts for callbacks from ST */ - hst = hdev->driver_data; - ti_st_proto.priv_data = hst; - - err = st_register(&ti_st_proto); - if (err == -EINPROGRESS) { - /* ST is busy with either protocol registration or firmware - * download. - */ - /* Prepare wait-for-completion handler data structures. - */ - init_completion(&hst->wait_reg_completion); - - /* Reset ST registration callback status flag , this value - * will be updated in ti_st_registration_completion_cb() - * function whenever it called from ST driver. - */ - hst->reg_status = -EINPROGRESS; - - BT_DBG("waiting for registration completion signal from ST"); - timeleft = wait_for_completion_timeout - (&hst->wait_reg_completion, - msecs_to_jiffies(BT_REGISTER_TIMEOUT)); - if (!timeleft) { - clear_bit(HCI_RUNNING, &hdev->flags); - BT_ERR("Timeout(%d sec),didn't get reg " - "completion signal from ST", - BT_REGISTER_TIMEOUT / 1000); - return -ETIMEDOUT; - } - - /* Is ST registration callback called with ERROR status? */ - if (hst->reg_status != 0) { - clear_bit(HCI_RUNNING, &hdev->flags); - BT_ERR("ST registration completed with invalid " - "status %d", hst->reg_status); - return -EAGAIN; - } - err = 0; - } else if (err != 0) { - clear_bit(HCI_RUNNING, &hdev->flags); - BT_ERR("st_register failed %d", err); - return err; - } - - /* ti_st_proto.write is filled up by the underlying shared - * transport driver upon registration - */ - hst->st_write = ti_st_proto.write; - if (!hst->st_write) { - BT_ERR("undefined ST write function"); - clear_bit(HCI_RUNNING, &hdev->flags); - - /* Undo registration with ST */ - err = st_unregister(ST_BT); - if (err) - BT_ERR("st_unregister() failed with error %d", err); - - hst->st_write = NULL; - return err; - } - - return err; -} - -/* Close device */ -static int ti_st_close(struct hci_dev *hdev) -{ - int err; - struct ti_st *hst = hdev->driver_data; - - if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) - return 0; - - /* continue to unregister from transport */ - err = st_unregister(ST_BT); - if (err) - BT_ERR("st_unregister() failed with error %d", err); - - hst->st_write = NULL; - - return err; -} - -static int ti_st_send_frame(struct sk_buff *skb) -{ - struct hci_dev *hdev; - struct ti_st *hst; - long len; - - hdev = (struct hci_dev *)skb->dev; - - if (!test_bit(HCI_RUNNING, &hdev->flags)) - return -EBUSY; - - hst = hdev->driver_data; - - /* Prepend skb with frame type */ - memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); - - BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, - skb->len); - - /* Insert skb to shared transport layer's transmit queue. - * Freeing skb memory is taken care in shared transport layer, - * so don't free skb memory here. - */ - len = hst->st_write(skb); - if (len < 0) { - kfree_skb(skb); - BT_ERR("ST write failed (%ld)", len); - /* Try Again, would only fail if UART has gone bad */ - return -EAGAIN; - } - - /* ST accepted our skb. So, Go ahead and do rest */ - hdev->stat.byte_tx += len; - ti_st_tx_complete(hst, bt_cb(skb)->pkt_type); - - return 0; -} - -static void ti_st_destruct(struct hci_dev *hdev) -{ - BT_DBG("%s", hdev->name); - kfree(hdev->driver_data); -} - -static int bt_ti_probe(struct platform_device *pdev) -{ - static struct ti_st *hst; - struct hci_dev *hdev; - int err; - - hst = kzalloc(sizeof(struct ti_st), GFP_KERNEL); - if (!hst) - return -ENOMEM; - - /* Expose "hciX" device to user space */ - hdev = hci_alloc_dev(); - if (!hdev) { - kfree(hst); - return -ENOMEM; - } - - BT_DBG("hdev %p", hdev); - - hst->hdev = hdev; - hdev->bus = HCI_UART; - hdev->driver_data = hst; - hdev->open = ti_st_open; - hdev->close = ti_st_close; - hdev->flush = NULL; - hdev->send = ti_st_send_frame; - hdev->destruct = ti_st_destruct; - hdev->owner = THIS_MODULE; - - err = hci_register_dev(hdev); - if (err < 0) { - BT_ERR("Can't register HCI device error %d", err); - kfree(hst); - hci_free_dev(hdev); - return err; - } - - BT_DBG("HCI device registered (hdev %p)", hdev); - - dev_set_drvdata(&pdev->dev, hst); - return err; -} - -static int bt_ti_remove(struct platform_device *pdev) -{ - struct hci_dev *hdev; - struct ti_st *hst = dev_get_drvdata(&pdev->dev); - - if (!hst) - return -EFAULT; - - hdev = hst->hdev; - ti_st_close(hdev); - hci_unregister_dev(hdev); - - hci_free_dev(hdev); - kfree(hst); - - dev_set_drvdata(&pdev->dev, NULL); - return 0; -} - -static struct platform_driver btwilink_driver = { - .probe = bt_ti_probe, - .remove = bt_ti_remove, - .driver = { - .name = "btwilink", - .owner = THIS_MODULE, - }, -}; - -/* ------- Module Init/Exit interfaces ------ */ -static int __init btwilink_init(void) -{ - BT_INFO("Bluetooth Driver for TI WiLink - Version %s", VERSION); - - return platform_driver_register(&btwilink_driver); -} - -static void __exit btwilink_exit(void) -{ - platform_driver_unregister(&btwilink_driver); -} - -module_init(btwilink_init); -module_exit(btwilink_exit); - -/* ------ Module Info ------ */ - -MODULE_AUTHOR("Raja Mani "); -MODULE_DESCRIPTION("Bluetooth Driver for TI Shared Transport" VERSION); -MODULE_VERSION(VERSION); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/ti-st/sysfs-uim b/drivers/staging/ti-st/sysfs-uim deleted file mode 100644 index 626bda51ee87..000000000000 --- a/drivers/staging/ti-st/sysfs-uim +++ /dev/null @@ -1,28 +0,0 @@ -What: /sys/class/rfkill/rfkill%d/ -Date: March 22 -Contact: Pavan Savoy -Description: - Creates the rfkill entries for Radio apps like - BT app, FM app or GPS app to toggle corresponding - cores of the chip - -What: /dev/rfkill -Date: March 22 -Contact: Pavan Savoy -Description: - A daemon which maintains the ldisc installation and - uninstallation would be ppolling on this device and listening - on events which would suggest either to install or un-install - line discipline - -What: /sys/kernel/debug/ti-st/version -Contact: Pavan Savoy -Description: - WiLink chip's ROM version exposed to user-space for some - proprietary protocol stacks to make use of. - -What: /sys/kernel/debug/ti-st/protocols -Contact: Pavan Savoy -Description: - The reason for chip being ON, the list of protocols registered. - -- cgit v1.2.3 From aa19d8e9901ea9056e4e1e5c25af9b154d4e069b Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 24 Feb 2011 16:24:50 +0000 Subject: staging: gma500: Add 2D acceleration This is taken from Richard Purdie's previous attempt to rip the heart out of the PVR driver and stake it. Accelerate copies and fills. [Revised patch which disables the methods until we can finish debugging them] Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/Makefile | 1 + drivers/staging/gma500/psb_2d.c | 411 +++++++++++++++++++++++++++++++++++++++ drivers/staging/gma500/psb_drv.c | 12 +- drivers/staging/gma500/psb_drv.h | 13 ++ drivers/staging/gma500/psb_fb.c | 8 +- drivers/staging/gma500/psb_irq.c | 4 +- 6 files changed, 444 insertions(+), 5 deletions(-) create mode 100644 drivers/staging/gma500/psb_2d.c (limited to 'drivers') diff --git a/drivers/staging/gma500/Makefile b/drivers/staging/gma500/Makefile index 21381eb4031b..a52ba48be518 100644 --- a/drivers/staging/gma500/Makefile +++ b/drivers/staging/gma500/Makefile @@ -6,6 +6,7 @@ ccflags-y += -Iinclude/drm psb_gfx-y += psb_bl.o \ psb_drv.o \ psb_fb.o \ + psb_2d.o \ psb_gtt.o \ psb_intel_bios.o \ psb_intel_opregion.o \ diff --git a/drivers/staging/gma500/psb_2d.c b/drivers/staging/gma500/psb_2d.c new file mode 100644 index 000000000000..e4cae5d77d01 --- /dev/null +++ b/drivers/staging/gma500/psb_2d.c @@ -0,0 +1,411 @@ +/************************************************************************** + * Copyright (c) 2007, Intel Corporation. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + * develop this driver. + * + **************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "psb_drv.h" +#include "psb_reg.h" +#include "psb_drv.h" +#include "psb_fb.h" +#include "psb_sgx.h" + +void psb_spank(struct drm_psb_private *dev_priv) +{ + PSB_WSGX32(_PSB_CS_RESET_BIF_RESET | _PSB_CS_RESET_DPM_RESET | + _PSB_CS_RESET_TA_RESET | _PSB_CS_RESET_USE_RESET | + _PSB_CS_RESET_ISP_RESET | _PSB_CS_RESET_TSP_RESET | + _PSB_CS_RESET_TWOD_RESET, PSB_CR_SOFT_RESET); + (void) PSB_RSGX32(PSB_CR_SOFT_RESET); + + msleep(1); + + PSB_WSGX32(0, PSB_CR_SOFT_RESET); + wmb(); + PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_CB_CTRL_CLEAR_FAULT, + PSB_CR_BIF_CTRL); + wmb(); + (void) PSB_RSGX32(PSB_CR_BIF_CTRL); + + msleep(1); + PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) & ~_PSB_CB_CTRL_CLEAR_FAULT, + PSB_CR_BIF_CTRL); + (void) PSB_RSGX32(PSB_CR_BIF_CTRL); + PSB_WSGX32(dev_priv->pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE); +} + +static int psb_2d_wait_available(struct drm_psb_private *dev_priv, + unsigned size) +{ + uint32_t avail = PSB_RSGX32(PSB_CR_2D_SOCIF); + unsigned long t = jiffies + HZ; + + while(avail < size) { + avail = PSB_RSGX32(PSB_CR_2D_SOCIF); + if (time_after(jiffies, t)) { + psb_spank(dev_priv); + return -EIO; + } + } + return 0; +} + +/* FIXME: Remember if we expose the 2D engine to the DRM we need to serialize + it with console use */ + +static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf, + unsigned size) +{ + int ret = 0; + int i; + unsigned submit_size; + + while (size > 0) { + submit_size = (size < 0x60) ? size : 0x60; + size -= submit_size; + ret = psb_2d_wait_available(dev_priv, submit_size); + if (ret) + return ret; + + submit_size <<= 2; + for (i = 0; i < submit_size; i += 4) { + PSB_WSGX32(*cmdbuf++, PSB_SGX_2D_SLAVE_PORT + i); + } + (void)PSB_RSGX32(PSB_SGX_2D_SLAVE_PORT + i - 4); + } + return 0; +} + +static int psb_accel_2d_fillrect(struct drm_psb_private *dev_priv, + uint32_t dst_offset, uint32_t dst_stride, + uint32_t dst_format, uint16_t dst_x, + uint16_t dst_y, uint16_t size_x, + uint16_t size_y, uint32_t fill) +{ + uint32_t buffer[10]; + uint32_t *buf; + + buf = buffer; + + *buf++ = PSB_2D_FENCE_BH; + + *buf++ = + PSB_2D_DST_SURF_BH | dst_format | (dst_stride << + PSB_2D_DST_STRIDE_SHIFT); + *buf++ = dst_offset; + + *buf++ = + PSB_2D_BLIT_BH | + PSB_2D_ROT_NONE | + PSB_2D_COPYORDER_TL2BR | + PSB_2D_DSTCK_DISABLE | + PSB_2D_SRCCK_DISABLE | PSB_2D_USE_FILL | PSB_2D_ROP3_PATCOPY; + + *buf++ = fill << PSB_2D_FILLCOLOUR_SHIFT; + *buf++ = + (dst_x << PSB_2D_DST_XSTART_SHIFT) | (dst_y << + PSB_2D_DST_YSTART_SHIFT); + *buf++ = + (size_x << PSB_2D_DST_XSIZE_SHIFT) | (size_y << + PSB_2D_DST_YSIZE_SHIFT); + *buf++ = PSB_2D_FLUSH_BH; + + return psbfb_2d_submit(dev_priv, buffer, buf - buffer); +} + +static void psbfb_fillrect_accel(struct fb_info *info, + const struct fb_fillrect *r) +{ + struct psb_fbdev *fbdev = info->par; + struct psb_framebuffer *psbfb = fbdev->pfb; + struct drm_device *dev = psbfb->base.dev; + struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb; + struct drm_psb_private *dev_priv = dev->dev_private; + + uint32_t offset; + uint32_t stride; + uint32_t format; + + if (!fb) + return; + + offset = psbfb->offset; + stride = fb->pitch; + + switch (fb->depth) { + case 8: + format = PSB_2D_DST_332RGB; + break; + case 15: + format = PSB_2D_DST_555RGB; + break; + case 16: + format = PSB_2D_DST_565RGB; + break; + case 24: + case 32: + /* this is wrong but since we don't do blending its okay */ + format = PSB_2D_DST_8888ARGB; + break; + default: + /* software fallback */ + cfb_fillrect(info, r); + return; + } + + psb_accel_2d_fillrect(dev_priv, + offset, stride, format, + r->dx, r->dy, r->width, r->height, r->color); +} + +void psbfb_fillrect(struct fb_info *info, + const struct fb_fillrect *rect) +{ + if (unlikely(info->state != FBINFO_STATE_RUNNING)) + return; + + if (1 || (info->flags & FBINFO_HWACCEL_DISABLED)) + return cfb_fillrect(info, rect); + + /*psb_check_power_state(dev, PSB_DEVICE_SGX); */ + psbfb_fillrect_accel(info, rect); + /* Drop power again here on MRST FIXMEAC */ +} + +static u32 psb_accel_2d_copy_direction(int xdir, int ydir) +{ + if (xdir < 0) + return (ydir < 0) ? PSB_2D_COPYORDER_BR2TL : + PSB_2D_COPYORDER_TR2BL; + else + return (ydir < 0) ? PSB_2D_COPYORDER_BL2TR : + PSB_2D_COPYORDER_TL2BR; +} + +/* + * @src_offset in bytes + * @src_stride in bytes + * @src_format psb 2D format defines + * @dst_offset in bytes + * @dst_stride in bytes + * @dst_format psb 2D format defines + * @src_x offset in pixels + * @src_y offset in pixels + * @dst_x offset in pixels + * @dst_y offset in pixels + * @size_x of the copied area + * @size_y of the copied area + */ +static int psb_accel_2d_copy(struct drm_psb_private *dev_priv, + uint32_t src_offset, uint32_t src_stride, + uint32_t src_format, uint32_t dst_offset, + uint32_t dst_stride, uint32_t dst_format, + uint16_t src_x, uint16_t src_y, + uint16_t dst_x, uint16_t dst_y, + uint16_t size_x, uint16_t size_y) +{ + uint32_t blit_cmd; + uint32_t buffer[10]; + uint32_t *buf; + uint32_t direction; + + buf = buffer; + + direction = + psb_accel_2d_copy_direction(src_x - dst_x, src_y - dst_y); + + if (direction == PSB_2D_COPYORDER_BR2TL || + direction == PSB_2D_COPYORDER_TR2BL) { + src_x += size_x - 1; + dst_x += size_x - 1; + } + if (direction == PSB_2D_COPYORDER_BR2TL || + direction == PSB_2D_COPYORDER_BL2TR) { + src_y += size_y - 1; + dst_y += size_y - 1; + } + + blit_cmd = + PSB_2D_BLIT_BH | + PSB_2D_ROT_NONE | + PSB_2D_DSTCK_DISABLE | + PSB_2D_SRCCK_DISABLE | + PSB_2D_USE_PAT | PSB_2D_ROP3_SRCCOPY | direction; + + *buf++ = PSB_2D_FENCE_BH; + *buf++ = + PSB_2D_DST_SURF_BH | dst_format | (dst_stride << + PSB_2D_DST_STRIDE_SHIFT); + *buf++ = dst_offset; + *buf++ = + PSB_2D_SRC_SURF_BH | src_format | (src_stride << + PSB_2D_SRC_STRIDE_SHIFT); + *buf++ = src_offset; + *buf++ = + PSB_2D_SRC_OFF_BH | (src_x << PSB_2D_SRCOFF_XSTART_SHIFT) | + (src_y << PSB_2D_SRCOFF_YSTART_SHIFT); + *buf++ = blit_cmd; + *buf++ = + (dst_x << PSB_2D_DST_XSTART_SHIFT) | (dst_y << + PSB_2D_DST_YSTART_SHIFT); + *buf++ = + (size_x << PSB_2D_DST_XSIZE_SHIFT) | (size_y << + PSB_2D_DST_YSIZE_SHIFT); + *buf++ = PSB_2D_FLUSH_BH; + + return psbfb_2d_submit(dev_priv, buffer, buf - buffer); +} + +static void psbfb_copyarea_accel(struct fb_info *info, + const struct fb_copyarea *a) +{ + struct psb_fbdev *fbdev = info->par; + struct psb_framebuffer *psbfb = fbdev->pfb; + struct drm_device *dev = psbfb->base.dev; + struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb; + struct drm_psb_private *dev_priv = dev->dev_private; + uint32_t offset; + uint32_t stride; + uint32_t src_format; + uint32_t dst_format; + + if (!fb) + return; + + offset = psbfb->offset; + stride = fb->pitch; + + switch (fb->depth) { + case 8: + src_format = PSB_2D_SRC_332RGB; + dst_format = PSB_2D_DST_332RGB; + break; + case 15: + src_format = PSB_2D_SRC_555RGB; + dst_format = PSB_2D_DST_555RGB; + break; + case 16: + src_format = PSB_2D_SRC_565RGB; + dst_format = PSB_2D_DST_565RGB; + break; + case 24: + case 32: + /* this is wrong but since we don't do blending its okay */ + src_format = PSB_2D_SRC_8888ARGB; + dst_format = PSB_2D_DST_8888ARGB; + break; + default: + /* software fallback */ + cfb_copyarea(info, a); + return; + } + + psb_accel_2d_copy(dev_priv, + offset, stride, src_format, + offset, stride, dst_format, + a->sx, a->sy, a->dx, a->dy, a->width, a->height); +} + +void psbfb_copyarea(struct fb_info *info, + const struct fb_copyarea *region) +{ + if (unlikely(info->state != FBINFO_STATE_RUNNING)) + return; + + if (1 || (info->flags & FBINFO_HWACCEL_DISABLED)) + return cfb_copyarea(info, region); + + /* psb_check_power_state(dev, PSB_DEVICE_SGX); */ + psbfb_copyarea_accel(info, region); + /* Need to power back off here for MRST FIXMEAC */ +} + +void psbfb_imageblit(struct fb_info *info, const struct fb_image *image) +{ + /* For now */ + cfb_imageblit(info, image); +} + +int psbfb_sync(struct fb_info *info) +{ + struct psb_fbdev *fbdev = info->par; + struct psb_framebuffer *psbfb = fbdev->pfb; + struct drm_device *dev = psbfb->base.dev; + struct drm_psb_private *dev_priv = dev->dev_private; + unsigned long _end = jiffies + DRM_HZ; + int busy = 0; + +#if 0 + /* Just a way to quickly test if cmd issue explodes */ + u32 test[2] = { + PSB_2D_FENCE_BH, + }; + psbfb_2d_submit(dev_priv, test, 1); +#endif + /* + * First idle the 2D engine. + */ + + if ((PSB_RSGX32(PSB_CR_2D_SOCIF) == _PSB_C2_SOCIF_EMPTY) && + ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) & _PSB_C2B_STATUS_BUSY) == 0)) + goto out; + + do { + busy = (PSB_RSGX32(PSB_CR_2D_SOCIF) != _PSB_C2_SOCIF_EMPTY); + cpu_relax(); + } while (busy && !time_after_eq(jiffies, _end)); + + if (busy) + busy = (PSB_RSGX32(PSB_CR_2D_SOCIF) != _PSB_C2_SOCIF_EMPTY); + if (busy) + goto out; + + do { + busy = ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) & + _PSB_C2B_STATUS_BUSY) != 0); + cpu_relax(); + } while (busy && !time_after_eq(jiffies, _end)); + if (busy) + busy = ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) & + _PSB_C2B_STATUS_BUSY) != 0); + +out: + return (busy) ? -EBUSY : 0; +} + +/* + info->fix.accel = FB_ACCEL_I830; + info->flags = FBINFO_DEFAULT; +*/ diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index 2fe09c828a9b..2b410af91dfa 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -446,6 +446,7 @@ static int psb_do_init(struct drm_device *dev) goto out_err; } + stolen_gtt = (pg->stolen_size >> PAGE_SHIFT) * 4; stolen_gtt = (stolen_gtt + PAGE_SIZE - 1) >> PAGE_SHIFT; stolen_gtt = @@ -471,6 +472,7 @@ static int psb_do_init(struct drm_device *dev) _PSB_CC_REVISION_DESIGNER_SHIFT); } + spin_lock_init(&dev_priv->irqmask_lock); tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ? @@ -479,6 +481,14 @@ static int psb_do_init(struct drm_device *dev) tt_pages -= tt_start >> PAGE_SHIFT; dev_priv->sizes.ta_mem_size = 0; + PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0); + PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1); + PSB_RSGX32(PSB_CR_BIF_BANK1); + PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_MMU_ER_MASK, + PSB_CR_BIF_CTRL); + psb_spank(dev_priv); + + PSB_WSGX32(pg->mmu_gatt_start, PSB_CR_BIF_TWOD_REQ_BASE); /* TT region managed by TTM. */ if (!ttm_bo_init_mm(bdev, TTM_PL_TT, @@ -500,7 +510,6 @@ static int psb_do_init(struct drm_device *dev) PSB_MEM_TT_START / (1024*1024); } - PSB_DEBUG_INIT("Init MSVDX\n"); return 0; out_err: @@ -786,6 +795,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) dev_priv->pipestat[1] = 0; dev_priv->pipestat[2] = 0; spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); + PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R); PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index 79417a4b51ab..f7c976299adc 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -918,6 +918,19 @@ extern int psbfb_kms_on_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern void *psbfb_vdc_reg(struct drm_device* dev); +/* + * psb_2d.c + */ +extern void psbfb_fillrect(struct fb_info *info, + const struct fb_fillrect *rect); +extern void psbfb_copyarea(struct fb_info *info, + const struct fb_copyarea *region); +extern void psbfb_imageblit(struct fb_info *info, + const struct fb_image *image); +extern int psbfb_sync(struct fb_info *info); + +extern void psb_spank(struct drm_psb_private *dev_priv); + /* *psb_reset.c */ diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c index 6585e8882243..94d845740313 100644 --- a/drivers/staging/gma500/psb_fb.c +++ b/drivers/staging/gma500/psb_fb.c @@ -279,10 +279,11 @@ static struct fb_ops psbfb_ops = { .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank, .fb_setcolreg = psbfb_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect = psbfb_fillrect, + .fb_copyarea = psbfb_copyarea, + .fb_imageblit = psbfb_imageblit, .fb_mmap = psbfb_mmap, + .fb_sync = psbfb_sync, }; static struct drm_framebuffer *psb_framebuffer_create @@ -394,6 +395,7 @@ static struct drm_framebuffer *psb_user_framebuffer_create strcpy(info->fix.id, "psbfb"); info->flags = FBINFO_DEFAULT; + info->fix.accel = FB_ACCEL_I830; /*FIXMEAC*/ info->fbops = &psbfb_ops; info->fix.smem_start = dev->mode_config.fb_base; diff --git a/drivers/staging/gma500/psb_irq.c b/drivers/staging/gma500/psb_irq.c index 3cdcd1e12556..ce7dbf4e555c 100644 --- a/drivers/staging/gma500/psb_irq.c +++ b/drivers/staging/gma500/psb_irq.c @@ -256,6 +256,7 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) PSB_WSGX32(s2, PSB_CR_EVENT_HOST_CLEAR2); /* if s & _PSB_CE_TWOD_COMPLETE we have 2D done but we may as well poll even if we add that ! */ + handled = 1; } PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R); @@ -300,9 +301,10 @@ void psb_irq_preinstall_islands(struct drm_device *dev, int hw_islands) _MDFLD_PIPEC_EVENT_FLAG; } } +/* NO I DONT WANT ANY IRQS GRRR FIXMEAC */ if (hw_islands & OSPM_GRAPHICS_ISLAND) dev_priv->vdc_irq_mask |= _PSB_IRQ_SGX_FLAG; - +/* */ /*This register is safe even if display island is off*/ PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); -- cgit v1.2.3 From af06216a8ef1c430cc6ad22b562f3a11a512c5dd Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 1 Mar 2011 01:12:19 +0100 Subject: ACPI: Fix build for CONFIG_NET unset Several ACPI drivers fail to build if CONFIG_NET is unset, because they refer to things depending on CONFIG_THERMAL that in turn depends on CONFIG_NET. However, CONFIG_THERMAL doesn't really need to depend on CONFIG_NET, because the only part of it requiring CONFIG_NET is the netlink interface in thermal_sys.c. Put the netlink interface in thermal_sys.c under #ifdef CONFIG_NET and remove the dependency of CONFIG_THERMAL on CONFIG_NET from drivers/thermal/Kconfig. Signed-off-by: Rafael J. Wysocki Acked-by: Randy Dunlap Cc: Ingo Molnar Cc: Len Brown Cc: Stephen Rothwell Cc: Luming Yu Cc: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/thermal/Kconfig | 1 - drivers/thermal/thermal_sys.c | 40 +++++++++++++++++++++------------------- include/linux/thermal.h | 8 ++++++++ 3 files changed, 29 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index f7a5dba3ca23..bf7c687519ef 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -4,7 +4,6 @@ menuconfig THERMAL tristate "Generic Thermal sysfs driver" - depends on NET help Generic Thermal Sysfs driver offers a generic mechanism for thermal management. Usually it's made up of one or more thermal diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 7d0e63c79280..713b7ea4a607 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -62,20 +62,6 @@ static DEFINE_MUTEX(thermal_list_lock); static unsigned int thermal_event_seqnum; -static struct genl_family thermal_event_genl_family = { - .id = GENL_ID_GENERATE, - .name = THERMAL_GENL_FAMILY_NAME, - .version = THERMAL_GENL_VERSION, - .maxattr = THERMAL_GENL_ATTR_MAX, -}; - -static struct genl_multicast_group thermal_event_mcgrp = { - .name = THERMAL_GENL_MCAST_GROUP_NAME, -}; - -static int genetlink_init(void); -static void genetlink_exit(void); - static int get_idr(struct idr *idr, struct mutex *lock, int *id) { int err; @@ -1225,6 +1211,18 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) EXPORT_SYMBOL(thermal_zone_device_unregister); +#ifdef CONFIG_NET +static struct genl_family thermal_event_genl_family = { + .id = GENL_ID_GENERATE, + .name = THERMAL_GENL_FAMILY_NAME, + .version = THERMAL_GENL_VERSION, + .maxattr = THERMAL_GENL_ATTR_MAX, +}; + +static struct genl_multicast_group thermal_event_mcgrp = { + .name = THERMAL_GENL_MCAST_GROUP_NAME, +}; + int generate_netlink_event(u32 orig, enum events event) { struct sk_buff *skb; @@ -1301,6 +1299,15 @@ static int genetlink_init(void) return result; } +static void genetlink_exit(void) +{ + genl_unregister_family(&thermal_event_genl_family); +} +#else /* !CONFIG_NET */ +static inline int genetlink_init(void) { return 0; } +static inline void genetlink_exit(void) {} +#endif /* !CONFIG_NET */ + static int __init thermal_init(void) { int result = 0; @@ -1316,11 +1323,6 @@ static int __init thermal_init(void) return result; } -static void genetlink_exit(void) -{ - genl_unregister_family(&thermal_event_genl_family); -} - static void __exit thermal_exit(void) { class_unregister(&thermal_class); diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 8651556dbd52..d3ec89fb4122 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -172,6 +172,14 @@ void thermal_zone_device_update(struct thermal_zone_device *); struct thermal_cooling_device *thermal_cooling_device_register(char *, void *, const struct thermal_cooling_device_ops *); void thermal_cooling_device_unregister(struct thermal_cooling_device *); + +#ifdef CONFIG_NET extern int generate_netlink_event(u32 orig, enum events event); +#else +static inline int generate_netlink_event(u32 orig, enum events event) +{ + return 0; +} +#endif #endif /* __THERMAL_H__ */ -- cgit v1.2.3 From 8d9e9d09b78bd131f488bbd2746852a05bcf557f Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Thu, 24 Feb 2011 12:04:34 +0100 Subject: staging: brcm80211: removed compile warning A warning was generated if CONFIG_BRCMDBG=n. Fixed this by introducing an function. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 7645c6c972fd..98ceaed1700d 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -183,10 +183,11 @@ static int wl_ops_start(struct ieee80211_hw *hw) static void wl_ops_stop(struct ieee80211_hw *hw) { +#ifdef BRCMDBG struct wl_info *wl = hw->priv; ASSERT(wl); +#endif /*BRCMDBG*/ ieee80211_stop_queues(hw); - return; } static int -- cgit v1.2.3 From 2d586ea6de0ffe3e119ed0f1d4cb0adeb6874cbc Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Thu, 24 Feb 2011 22:11:48 +0100 Subject: staging: brcm80211: Fix memory leak after kmalloc failure This error was spotted by cppcheck: drivers/staging/brcm80211/phy/wlc_phy_lcn.c:4053: error: Memory leak: ptr Cc: Brett Rudley Cc: Henry Ptasinski Cc: linux-wireless@vger.kernel.org Cc: devel@driverdev.osuosl.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Stefan Weil Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c index 3fbbbb46a360..f027d5076c7d 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c @@ -4051,6 +4051,7 @@ wlc_lcnphy_a1(phy_info_t *pi, int cal_type, int num_levels, int step_size_lg2) phy_c32 = kmalloc(sizeof(u16) * 20, GFP_ATOMIC); if (NULL == phy_c32) { + kfree(ptr); return; } phy_c26 = read_phy_reg(pi, 0x6da); -- cgit v1.2.3 From 9010c46c3722d37befaf3d6e0d5024293efa3074 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 25 Feb 2011 16:39:09 +0100 Subject: staging: brcm80211: Remove abstractions for pci_(un)map_single The driver had abstracted DMA mapping functions. As abstraction is not required for the linux driver, these have been removed and replaced by native linux functions. Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/osl.h | 10 ---------- drivers/staging/brcm80211/util/hnddma.c | 15 +++++++-------- drivers/staging/brcm80211/util/linux_osl.c | 20 -------------------- 3 files changed, 7 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index 17fc274ef240..49015bdc6536 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -70,16 +70,6 @@ extern void osl_dma_free_consistent(struct osl_info *osh, void *va, #define DMA_TX 1 /* TX direction for DMA */ #define DMA_RX 2 /* RX direction for DMA */ -/* map/unmap shared (dma-able) memory */ -#define DMA_MAP(osh, va, size, direction, p, dmah) \ - osl_dma_map((osh), (va), (size), (direction)) -#define DMA_UNMAP(osh, pa, size, direction, p, dmah) \ - osl_dma_unmap((osh), (pa), (size), (direction)) -extern uint osl_dma_map(struct osl_info *osh, void *va, uint size, - int direction); -extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, - int direction); - /* register access macros */ #if defined(BCMSDIO) #ifdef BRCM_FULLMAC diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 66ebdfdf6cd4..bd701fc64598 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -76,7 +76,7 @@ typedef struct dma_info { uint *msg_level; /* message level pointer */ char name[MAXNAMEL]; /* callers name for diag msgs */ - void *osh; /* os handle */ + struct osl_info *osh; /* os handle */ si_t *sih; /* sb handle */ bool dma64; /* this dma engine is operating in 64-bit mode */ @@ -866,8 +866,8 @@ static bool BCMFASTPATH _dma_rxfill(dma_info_t *di) memset(&di->rxp_dmah[rxout], 0, sizeof(hnddma_seg_map_t)); - pa = DMA_MAP(di->osh, p->data, - di->rxbufsize, DMA_RX, p, &di->rxp_dmah[rxout]); + pa = pci_map_single(di->osh->pdev, p->data, + di->rxbufsize, PCI_DMA_FROMDEVICE); ASSERT(IS_ALIGNED(PHYSADDRLO(pa), 4)); @@ -1383,7 +1383,7 @@ static int dma64_txunframed(dma_info_t *di, void *buf, uint len, bool commit) if (len == 0) return 0; - pa = DMA_MAP(di->osh, buf, len, DMA_TX, NULL, &di->txp_dmah[txout]); + pa = pci_map_single(di->osh->pdev, buf, len, PCI_DMA_TODEVICE); flags = (D64_CTRL1_SOF | D64_CTRL1_IOC | D64_CTRL1_EOF); @@ -1463,8 +1463,7 @@ static int BCMFASTPATH dma64_txfast(dma_info_t *di, struct sk_buff *p0, memset(&di->txp_dmah[txout], 0, sizeof(hnddma_seg_map_t)); - pa = DMA_MAP(di->osh, data, len, DMA_TX, p, - &di->txp_dmah[txout]); + pa = pci_map_single(di->osh->pdev, data, len, PCI_DMA_TODEVICE); if (DMASGLIST_ENAB) { map = &di->txp_dmah[txout]; @@ -1626,7 +1625,7 @@ static void *BCMFASTPATH dma64_getnexttxp(dma_info_t *di, txd_range_t range) i = NEXTTXD(i); } - DMA_UNMAP(di->osh, pa, size, DMA_TX, txp, map); + pci_unmap_single(di->osh->pdev, pa, size, PCI_DMA_TODEVICE); } di->txin = i; @@ -1677,7 +1676,7 @@ static void *BCMFASTPATH dma64_getnextrxp(dma_info_t *di, bool forceall) di->dataoffsethigh)); /* clear this packet from the descriptor ring */ - DMA_UNMAP(di->osh, pa, di->rxbufsize, DMA_RX, rxp, &di->rxp_dmah[i]); + pci_unmap_single(di->osh->pdev, pa, di->rxbufsize, PCI_DMA_FROMDEVICE); W_SM(&di->rxd64[i].addrlow, 0xdeadbeef); W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef); diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index d7c3c3f9dd81..c0b06f95b48a 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -161,26 +161,6 @@ void osl_dma_free_consistent(struct osl_info *osh, void *va, uint size, pci_free_consistent(osh->pdev, size, va, (dma_addr_t) pa); } -uint BCMFASTPATH osl_dma_map(struct osl_info *osh, void *va, uint size, - int direction) -{ - int dir; - - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - dir = (direction == DMA_TX) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE; - return pci_map_single(osh->pdev, va, size, dir); -} - -void BCMFASTPATH osl_dma_unmap(struct osl_info *osh, uint pa, uint size, - int direction) -{ - int dir; - - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - dir = (direction == DMA_TX) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE; - pci_unmap_single(osh->pdev, (u32) pa, size, dir); -} - #if defined(BCMDBG_ASSERT) void osl_assert(char *exp, char *file, int line) { -- cgit v1.2.3 From 235742ae4da1c8398a3968b2d5110256fc33d536 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 25 Feb 2011 16:39:10 +0100 Subject: staging: brcm80211: Remove abstraction of pci_(alloc/free)_consistent The abstraction for allocating and freeing dma descriptor memory has been removed and replaced by usage of pci_alloc_consistent and pci_free_consistent. Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/osl.h | 16 ------------ drivers/staging/brcm80211/util/hnddma.c | 40 ++++++++++++++++++++---------- drivers/staging/brcm80211/util/linux_osl.c | 22 ---------------- 3 files changed, 27 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index 49015bdc6536..c3800d01c484 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -50,22 +50,6 @@ extern uint osl_pci_slot(struct osl_info *osh); #define BUS_SWAP32(v) (v) -extern void *osl_dma_alloc_consistent(struct osl_info *osh, uint size, - u16 align, uint *tot, unsigned long *pap); - -#ifdef BRCM_FULLMAC -#define DMA_ALLOC_CONSISTENT(osh, size, pap, dmah, alignbits) \ - osl_dma_alloc_consistent((osh), (size), (0), (tot), (pap)) -#else -#define DMA_ALLOC_CONSISTENT(osh, size, align, tot, pap, dmah) \ - osl_dma_alloc_consistent((osh), (size), (align), (tot), (pap)) -#endif /* BRCM_FULLMAC */ - -#define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \ - osl_dma_free_consistent((osh), (void *)(va), (size), (pa)) -extern void osl_dma_free_consistent(struct osl_info *osh, void *va, - uint size, unsigned long pa); - /* map/unmap direction */ #define DMA_TX 1 /* TX direction for DMA */ #define DMA_RX 2 /* RX direction for DMA */ diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index bd701fc64598..3c913a65da0d 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -32,6 +32,10 @@ #include #endif +#ifdef BRCM_FULLMAC +#error "hnddma.c shouldn't be needed for FULLMAC" +#endif + /* debug/trace */ #ifdef BCMDBG #define DMA_ERROR(args) \ @@ -527,6 +531,18 @@ static bool _dma_alloc(dma_info_t *di, uint direction) return dma64_alloc(di, direction); } +void *dma_alloc_consistent(struct osl_info *osh, uint size, u16 align_bits, + uint *alloced, unsigned long *pap) +{ + if (align_bits) { + u16 align = (1 << align_bits); + if (!IS_ALIGNED(PAGE_SIZE, align)) + size += align; + *alloced = size; + } + return pci_alloc_consistent(osh->pdev, size, (dma_addr_t *) pap); +} + /* !! may be called with core in reset */ static void _dma_detach(dma_info_t *di) { @@ -539,15 +555,13 @@ static void _dma_detach(dma_info_t *di) /* free dma descriptor rings */ if (di->txd64) - DMA_FREE_CONSISTENT(di->osh, - ((s8 *)di->txd64 - - di->txdalign), di->txdalloc, - (di->txdpaorig), &di->tx_dmah); + pci_free_consistent(di->osh->pdev, di->txdalloc, + ((s8 *)di->txd64 - di->txdalign), + (di->txdpaorig)); if (di->rxd64) - DMA_FREE_CONSISTENT(di->osh, - ((s8 *)di->rxd64 - - di->rxdalign), di->rxdalloc, - (di->rxdpaorig), &di->rx_dmah); + pci_free_consistent(di->osh->pdev, di->rxdalloc, + ((s8 *)di->rxd64 - di->rxdalign), + (di->rxdpaorig)); /* free packet pointer vectors */ if (di->txp) @@ -1080,8 +1094,8 @@ static void *dma_ringalloc(struct osl_info *osh, u32 boundary, uint size, u32 desc_strtaddr; u32 alignbytes = 1 << *alignbits; - va = DMA_ALLOC_CONSISTENT(osh, size, *alignbits, alloced, descpa, - dmah); + va = dma_alloc_consistent(osh, size, *alignbits, alloced, descpa); + if (NULL == va) return NULL; @@ -1089,9 +1103,9 @@ static void *dma_ringalloc(struct osl_info *osh, u32 boundary, uint size, if (((desc_strtaddr + size - 1) & boundary) != (desc_strtaddr & boundary)) { *alignbits = dma_align_sizetobits(size); - DMA_FREE_CONSISTENT(osh, va, size, *descpa, dmah); - va = DMA_ALLOC_CONSISTENT(osh, size, *alignbits, alloced, - descpa, dmah); + pci_free_consistent(osh->pdev, size, va, *descpa); + va = dma_alloc_consistent(osh, size, *alignbits, + alloced, descpa); } return va; } diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index c0b06f95b48a..bcbce6e2401c 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -139,28 +139,6 @@ uint osl_pci_slot(struct osl_info *osh) return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn); } -void *osl_dma_alloc_consistent(struct osl_info *osh, uint size, u16 align_bits, - uint *alloced, unsigned long *pap) -{ - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - - if (align_bits) { - u16 align = (1 << align_bits); - if (!IS_ALIGNED(PAGE_SIZE, align)) - size += align; - *alloced = size; - } - return pci_alloc_consistent(osh->pdev, size, (dma_addr_t *) pap); -} - -void osl_dma_free_consistent(struct osl_info *osh, void *va, uint size, - unsigned long pa) -{ - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - - pci_free_consistent(osh->pdev, size, va, (dma_addr_t) pa); -} - #if defined(BCMDBG_ASSERT) void osl_assert(char *exp, char *file, int line) { -- cgit v1.2.3 From 371d72a1776bae3289cc984e656ef91172f2e925 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 25 Feb 2011 16:39:11 +0100 Subject: staging: brcm80211: relocate skb_get/free routines Getting rid of os abstraction layer (ie. osl) is ongoing. Some routines which are still required have been moved to bcmutils module. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/bcmutils.h | 5 +++ drivers/staging/brcm80211/include/osl.h | 3 -- drivers/staging/brcm80211/util/bcmutils.c | 46 ++++++++++++++++++++++++++++ drivers/staging/brcm80211/util/linux_osl.c | 45 --------------------------- 4 files changed, 51 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h index b8c800abd30e..a3d3f66b3638 100644 --- a/drivers/staging/brcm80211/include/bcmutils.h +++ b/drivers/staging/brcm80211/include/bcmutils.h @@ -94,6 +94,11 @@ extern struct sk_buff *pktq_penq_head(struct pktq *pq, int prec, extern struct sk_buff *pktq_pdeq(struct pktq *pq, int prec); extern struct sk_buff *pktq_pdeq_tail(struct pktq *pq, int prec); +/* packet primitives */ +extern struct sk_buff *pkt_buf_get_skb(struct osl_info *osh, uint len); +extern void pkt_buf_free_skb(struct osl_info *osh, + struct sk_buff *skb, bool send); + /* Empty the queue at particular precedence level */ #ifdef BRCM_FULLMAC extern void pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index c3800d01c484..f118b30552ea 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -176,8 +176,5 @@ extern uint osl_pci_slot(struct osl_info *osh); } while (0) #endif /* IL_BIGENDIAN */ -/* packet primitives */ -extern struct sk_buff *pkt_buf_get_skb(struct osl_info *osh, uint len); -extern void pkt_buf_free_skb(struct osl_info *osh, struct sk_buff *skb, bool send); #endif /* _osl_h_ */ diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index 674caf6243df..696220edb0bc 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -30,6 +30,52 @@ #include #include +struct sk_buff *BCMFASTPATH pkt_buf_get_skb(struct osl_info *osh, uint len) +{ + struct sk_buff *skb; + + skb = dev_alloc_skb(len); + if (skb) { + skb_put(skb, len); + skb->priority = 0; + + osh->pktalloced++; + } + + return skb; +} + +/* Free the driver packet. Free the tag if present */ +void BCMFASTPATH pkt_buf_free_skb(struct osl_info *osh, + struct sk_buff *skb, bool send) +{ + struct sk_buff *nskb; + int nest = 0; + + ASSERT(skb); + + /* perversion: we use skb->next to chain multi-skb packets */ + while (skb) { + nskb = skb->next; + skb->next = NULL; + + if (skb->destructor) + /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if + * destructor exists + */ + dev_kfree_skb_any(skb); + else + /* can free immediately (even in_irq()) if destructor + * does not exist + */ + dev_kfree_skb(skb); + + osh->pktalloced--; + nest++; + skb = nskb; + } +} + /* copy a buffer into a pkt buffer chain */ uint pktfrombuf(struct osl_info *osh, struct sk_buff *p, uint offset, int len, unsigned char *buf) diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index bcbce6e2401c..99e449603a9f 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -78,51 +78,6 @@ void osl_detach(struct osl_info *osh) kfree(osh); } -struct sk_buff *BCMFASTPATH pkt_buf_get_skb(struct osl_info *osh, uint len) -{ - struct sk_buff *skb; - - skb = dev_alloc_skb(len); - if (skb) { - skb_put(skb, len); - skb->priority = 0; - - osh->pktalloced++; - } - - return skb; -} - -/* Free the driver packet. Free the tag if present */ -void BCMFASTPATH pkt_buf_free_skb(struct osl_info *osh, struct sk_buff *skb, bool send) -{ - struct sk_buff *nskb; - int nest = 0; - - ASSERT(skb); - - /* perversion: we use skb->next to chain multi-skb packets */ - while (skb) { - nskb = skb->next; - skb->next = NULL; - - if (skb->destructor) - /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if - * destructor exists - */ - dev_kfree_skb_any(skb); - else - /* can free immediately (even in_irq()) if destructor - * does not exist - */ - dev_kfree_skb(skb); - - osh->pktalloced--; - nest++; - skb = nskb; - } -} - /* return bus # for the pci device pointed by osh->pdev */ uint osl_pci_bus(struct osl_info *osh) { -- cgit v1.2.3 From b693380f616d3a31c267d7b6da700ffa27fc308d Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Feb 2011 16:39:12 +0100 Subject: staging: brcm80211: remove unused module from softmac driver The softmac driver contained an event queue mechanism which was properly initialized and queried but no event are ever posted to it. Therefor the module has been removed. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/Makefile | 1 - drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 29 ---- drivers/staging/brcm80211/brcmsmac/wlc_alloc.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_antsel.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_channel.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_event.c | 203 ---------------------- drivers/staging/brcm80211/brcmsmac/wlc_event.h | 50 ------ drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 40 ----- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h | 3 - drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_stf.c | 1 - 13 files changed, 333 deletions(-) delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_event.c delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_event.h (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/Makefile b/drivers/staging/brcm80211/brcmsmac/Makefile index 5da39be0f769..315f1ae9de0f 100644 --- a/drivers/staging/brcm80211/brcmsmac/Makefile +++ b/drivers/staging/brcm80211/brcmsmac/Makefile @@ -36,7 +36,6 @@ BRCMSMAC_OFILES := \ wlc_antsel.o \ wlc_bmac.o \ wlc_channel.o \ - wlc_event.o \ wlc_mac80211.o \ wlc_phy_shim.o \ wlc_rate.o \ diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 98ceaed1700d..ac9edae3a22d 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -1590,35 +1590,6 @@ static void BCMFASTPATH wl_dpc(unsigned long data) WL_UNLOCK(wl); } -static void wl_link_up(struct wl_info *wl, char *ifname) -{ - WL_NONE("wl%d: link up (%s)\n", wl->pub->unit, ifname); -} - -static void wl_link_down(struct wl_info *wl, char *ifname) -{ - WL_NONE("wl%d: link down (%s)\n", wl->pub->unit, ifname); -} - -/* - * precondition: perimeter lock has been acquired - */ -void wl_event(struct wl_info *wl, char *ifname, wlc_event_t *e) -{ - - switch (e->event.event_type) { - case WLC_E_LINK: - case WLC_E_NDIS_LINK: - if (e->event.flags & WLC_EVENT_MSG_LINK) - wl_link_up(wl, ifname); - else - wl_link_down(wl, ifname); - break; - case WLC_E_RADIO: - break; - } -} - /* * is called by the kernel from software irq context */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c index 2db96c1e1701..064a3ffe5d8f 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index 4f9d4dec768c..699890ba190f 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c index 402ddf8f3371..da19a082ee46 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 12bfb06b3013..b40ca62b6894 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -48,7 +48,6 @@ * At some point we may be able to skip the include of wlc.h and instead just * define a stub wlc_info and band struct to allow rpc calls to get the rpc handle. */ -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c index 06b31a0364f4..ea23728a7727 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_event.c b/drivers/staging/brcm80211/brcmsmac/wlc_event.c deleted file mode 100644 index 7926c4104310..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/wlc_event.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* Local prototypes */ -static void wlc_timer_cb(void *arg); - -/* Private data structures */ -struct wlc_eventq { - wlc_event_t *head; - wlc_event_t *tail; - struct wlc_info *wlc; - void *wl; - struct wlc_pub *pub; - bool tpending; - bool workpending; - struct wl_timer *timer; - wlc_eventq_cb_t cb; - u8 event_inds_mask[broken_roundup(WLC_E_LAST, NBBY) / NBBY]; -}; - -/* - * Export functions - */ -wlc_eventq_t *wlc_eventq_attach(struct wlc_pub *pub, struct wlc_info *wlc, - void *wl, - wlc_eventq_cb_t cb) -{ - wlc_eventq_t *eq; - - eq = kzalloc(sizeof(wlc_eventq_t), GFP_ATOMIC); - if (eq == NULL) - return NULL; - - eq->cb = cb; - eq->wlc = wlc; - eq->wl = wl; - eq->pub = pub; - - eq->timer = wl_init_timer(eq->wl, wlc_timer_cb, eq, "eventq"); - if (!eq->timer) { - WL_ERROR("wl%d: wlc_eventq_attach: timer failed\n", - pub->unit); - kfree(eq); - return NULL; - } - - return eq; -} - -int wlc_eventq_detach(wlc_eventq_t *eq) -{ - /* Clean up pending events */ - wlc_eventq_down(eq); - - if (eq->timer) { - if (eq->tpending) { - wl_del_timer(eq->wl, eq->timer); - eq->tpending = false; - } - wl_free_timer(eq->wl, eq->timer); - eq->timer = NULL; - } - - ASSERT(wlc_eventq_avail(eq) == false); - kfree(eq); - return 0; -} - -int wlc_eventq_down(wlc_eventq_t *eq) -{ - int callbacks = 0; - if (eq->tpending && !eq->workpending) { - if (!wl_del_timer(eq->wl, eq->timer)) - callbacks++; - - ASSERT(wlc_eventq_avail(eq) == true); - ASSERT(eq->workpending == false); - eq->workpending = true; - if (eq->cb) - eq->cb(eq->wlc); - - ASSERT(eq->workpending == true); - eq->workpending = false; - eq->tpending = false; - } else { - ASSERT(eq->workpending || wlc_eventq_avail(eq) == false); - } - return callbacks; -} - -wlc_event_t *wlc_event_alloc(wlc_eventq_t *eq) -{ - wlc_event_t *e; - - e = kzalloc(sizeof(wlc_event_t), GFP_ATOMIC); - - if (e == NULL) - return NULL; - - return e; -} - -void wlc_event_free(wlc_eventq_t *eq, wlc_event_t *e) -{ - ASSERT(e->data == NULL); - ASSERT(e->next == NULL); - kfree(e); -} - -void wlc_eventq_enq(wlc_eventq_t *eq, wlc_event_t *e) -{ - ASSERT(e->next == NULL); - e->next = NULL; - - if (eq->tail) { - eq->tail->next = e; - eq->tail = e; - } else - eq->head = eq->tail = e; - - if (!eq->tpending) { - eq->tpending = true; - /* Use a zero-delay timer to trigger - * delayed processing of the event. - */ - wl_add_timer(eq->wl, eq->timer, 0, 0); - } -} - -wlc_event_t *wlc_eventq_deq(wlc_eventq_t *eq) -{ - wlc_event_t *e; - - e = eq->head; - if (e) { - eq->head = e->next; - e->next = NULL; - - if (eq->head == NULL) - eq->tail = eq->head; - } - return e; -} - -bool wlc_eventq_avail(wlc_eventq_t *eq) -{ - return (eq->head != NULL); -} - -/* - * Local Functions - */ -static void wlc_timer_cb(void *arg) -{ - struct wlc_eventq *eq = (struct wlc_eventq *)arg; - - ASSERT(eq->tpending == true); - ASSERT(wlc_eventq_avail(eq) == true); - ASSERT(eq->workpending == false); - eq->workpending = true; - - if (eq->cb) - eq->cb(eq->wlc); - - ASSERT(wlc_eventq_avail(eq) == false); - ASSERT(eq->tpending == true); - eq->workpending = false; - eq->tpending = false; -} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_event.h b/drivers/staging/brcm80211/brcmsmac/wlc_event.h deleted file mode 100644 index 8151ba500681..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/wlc_event.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _WLC_EVENT_H_ -#define _WLC_EVENT_H_ - -typedef struct wlc_eventq wlc_eventq_t; - -typedef void (*wlc_eventq_cb_t) (void *arg); - -extern wlc_eventq_t *wlc_eventq_attach(struct wlc_pub *pub, - struct wlc_info *wlc, - void *wl, wlc_eventq_cb_t cb); -extern int wlc_eventq_detach(wlc_eventq_t *eq); -extern int wlc_eventq_down(wlc_eventq_t *eq); -extern void wlc_event_free(wlc_eventq_t *eq, wlc_event_t *e); -extern bool wlc_eventq_avail(wlc_eventq_t *eq); -extern wlc_event_t *wlc_eventq_deq(wlc_eventq_t *eq); -extern void wlc_eventq_enq(wlc_eventq_t *eq, wlc_event_t *e); -extern wlc_event_t *wlc_event_alloc(wlc_eventq_t *eq); - -extern int wlc_eventq_register_ind(wlc_eventq_t *eq, void *bitvect); -extern int wlc_eventq_query_ind(wlc_eventq_t *eq, void *bitvect); -extern int wlc_eventq_test_ind(wlc_eventq_t *eq, int et); -extern int wlc_eventq_set_ind(wlc_eventq_t *eq, uint et, bool on); -extern void wlc_eventq_flush(wlc_eventq_t *eq); -extern void wlc_assign_event_msg(struct wlc_info *wlc, wl_event_msg_t *msg, - const wlc_event_t *e, u8 *data, - u32 len); - -#ifdef MSGTRACE -extern void wlc_event_sendup_trace(struct wlc_info *wlc, hndrte_dev_t *bus, - u8 *hdr, u16 hdrlen, u8 *buf, - u16 buflen); -#endif - -#endif /* _WLC_EVENT_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index fc3c6ab81d2e..26d40aa818a9 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -46,7 +45,6 @@ #include #include #include -#include #include #include "d11ucode_ext.h" #include @@ -304,7 +302,6 @@ static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val); static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val); static void wlc_war16165(struct wlc_info *wlc, bool tx); -static void wlc_process_eventq(void *arg); static void wlc_wme_retries_write(struct wlc_info *wlc); static bool wlc_attach_stf_ant_init(struct wlc_info *wlc); static uint wlc_attach_module(struct wlc_info *wlc); @@ -1699,15 +1696,6 @@ static uint wlc_attach_module(struct wlc_info *wlc) goto fail; } - /* Initialize event queue; needed before following calls */ - wlc->eventq = - wlc_eventq_attach(wlc->pub, wlc, wlc->wl, wlc_process_eventq); - if (wlc->eventq == NULL) { - WL_ERROR("wl%d: wlc_attach: wlc_eventq_attachfailed\n", unit); - err = 57; - goto fail; - } - if ((wlc_stf_attach(wlc) != 0)) { WL_ERROR("wl%d: wlc_attach: wlc_stf_attach failed\n", unit); err = 68; @@ -2159,11 +2147,6 @@ uint wlc_detach(struct wlc_info *wlc) if (!wlc_radio_monitor_stop(wlc)) callbacks++; - if (wlc->eventq) { - wlc_eventq_detach(wlc->eventq); - wlc->eventq = NULL; - } - wlc_channel_mgr_detach(wlc->cmi); wlc_timers_deinit(wlc); @@ -2740,12 +2723,6 @@ uint wlc_down(struct wlc_info *wlc) ASSERT(pktq_empty(&qi->q)); } - /* flush event queue. - * Should be the last thing done after all the events are generated - * Just delivers the events synchronously instead of waiting for a timer - */ - callbacks += wlc_eventq_down(wlc->eventq); - callbacks += wlc_bmac_down_finish(wlc->hw); /* wlc_bmac_down_finish has done wlc_coredisable(). so clk is off */ @@ -8024,23 +8001,6 @@ static void wlc_bss_default_init(struct wlc_info *wlc) bi->flags |= WLC_BSS_HT; } -/* Deferred event processing */ -static void wlc_process_eventq(void *arg) -{ - struct wlc_info *wlc = (struct wlc_info *) arg; - wlc_event_t *etmp; - - while ((etmp = wlc_eventq_deq(wlc->eventq))) { - /* Perform OS specific event processing */ - wl_event(wlc->wl, etmp->event.ifname, etmp); - if (etmp->data) { - kfree(etmp->data); - etmp->data = NULL; - } - wlc_event_free(wlc->eventq, etmp); - } -} - void wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, u32 b_low) { diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h index 4a9a8c884eda..72bfb8fa4d0e 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h @@ -642,9 +642,6 @@ struct wlc_info { /* tx queue */ wlc_txq_info_t *tx_queues; /* common TX Queue list */ - /* event */ - wlc_eventq_t *eventq; /* event queue for deferred processing */ - /* security */ wsec_key_t *wsec_keys[WSEC_MAX_KEYS]; /* dynamic key storage */ wsec_key_t *wsec_def_keys[WLC_DEFAULT_KEYS]; /* default key storage */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c index f8f2a5d81103..4eaec04c527c 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c @@ -46,7 +46,6 @@ #include #include #include -#include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c index 5ac120e8d4fe..d5b0f780ef20 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From 62b54dca17ef40116491b0ca27ca35fbe9daedc6 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Feb 2011 16:39:13 +0100 Subject: staging: brcm80211: cleanup function prototypes in header files Several header files were specifying function prototypes although no other module was relying on them. They have been moved to the related source file and made static or removed if the functions were non-existent in the driver. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_export.h | 3 -- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 16 +++++--- drivers/staging/brcm80211/brcmsmac/wl_mac80211.h | 17 -------- drivers/staging/brcm80211/brcmsmac/wlc_alloc.c | 6 ++- drivers/staging/brcm80211/brcmsmac/wlc_alloc.h | 4 -- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 6 ++- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h | 4 -- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 28 +++++++++----- drivers/staging/brcm80211/brcmsmac/wlc_bmac.h | 42 ++------------------ drivers/staging/brcm80211/brcmsmac/wlc_channel.c | 47 +++++++++++++++++------ drivers/staging/brcm80211/brcmsmac/wlc_channel.h | 29 +------------- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 3 +- drivers/staging/brcm80211/brcmsmac/wlc_pub.h | 25 ------------ drivers/staging/brcm80211/brcmsmac/wlc_stf.c | 3 ++ drivers/staging/brcm80211/brcmsmac/wlc_stf.h | 6 +-- 15 files changed, 84 insertions(+), 155 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_export.h b/drivers/staging/brcm80211/brcmsmac/wl_export.h index 16c626a8458c..03585745c49c 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_export.h +++ b/drivers/staging/brcm80211/brcmsmac/wl_export.h @@ -26,9 +26,6 @@ extern uint wl_reset(struct wl_info *wl); extern void wl_intrson(struct wl_info *wl); extern u32 wl_intrsoff(struct wl_info *wl); extern void wl_intrsrestore(struct wl_info *wl, u32 macintmask); -extern void wl_event(struct wl_info *wl, char *ifname, wlc_event_t *e); -extern void wl_event_sendup(struct wl_info *wl, const wlc_event_t *e, - u8 *data, u32 len); extern int wl_up(struct wl_info *wl); extern void wl_down(struct wl_info *wl); extern void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index ac9edae3a22d..6e421b947271 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -78,6 +78,12 @@ static int wl_start(struct sk_buff *skb, struct wl_info *wl); static int wl_start_int(struct wl_info *wl, struct ieee80211_hw *hw, struct sk_buff *skb); static void wl_dpc(unsigned long data); +static irqreturn_t wl_isr(int irq, void *dev_id); + +static int __devinit wl_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent); +static void wl_remove(struct pci_dev *pdev); +static void wl_free(struct wl_info *wl); MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver."); @@ -93,8 +99,6 @@ static struct pci_device_id wl_id_table[] = { }; MODULE_DEVICE_TABLE(pci, wl_id_table); -static void wl_remove(struct pci_dev *pdev); - #ifdef BCMDBG static int msglevel = 0xdeadbeef; @@ -105,6 +109,8 @@ module_param(phymsglevel, int, 0); #define HW_TO_WL(hw) (hw->priv) #define WL_TO_HW(wl) (wl->pub->ieee_hw) + +/* MAC80211 callback functions */ static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb); static int wl_ops_start(struct ieee80211_hw *hw); static void wl_ops_stop(struct ieee80211_hw *hw); @@ -1096,7 +1102,7 @@ static int ieee_hw_init(struct ieee80211_hw *hw) * * Perimeter lock is initialized in the course of this function. */ -int __devinit +static int __devinit wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int rc; @@ -1334,7 +1340,7 @@ module_exit(wl_module_exit); * precondition: can both be called locked and unlocked * */ -void wl_free(struct wl_info *wl) +static void wl_free(struct wl_info *wl) { wl_timer_t *t, *next; struct osl_info *osh; @@ -1525,7 +1531,7 @@ void wl_down(struct wl_info *wl) WL_LOCK(wl); } -irqreturn_t BCMFASTPATH wl_isr(int irq, void *dev_id) +static irqreturn_t BCMFASTPATH wl_isr(int irq, void *dev_id) { struct wl_info *wl; bool ours, wantdpc; diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h index 070fa94d9422..b7407caa4db2 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h @@ -88,21 +88,4 @@ struct wl_info { #define INT_LOCK(wl, flags) spin_lock_irqsave(&(wl)->isr_lock, flags) #define INT_UNLOCK(wl, flags) spin_unlock_irqrestore(&(wl)->isr_lock, flags) -#ifndef PCI_D0 -#define PCI_D0 0 -#endif - -#ifndef PCI_D3hot -#define PCI_D3hot 3 -#endif - -/* exported functions */ - -extern irqreturn_t wl_isr(int irq, void *dev_id); - -extern int __devinit wl_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent); -extern void wl_free(struct wl_info *wl); -extern int wl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); - #endif /* _wl_mac80211_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c index 064a3ffe5d8f..a4555f745127 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c @@ -31,6 +31,8 @@ #include #include +static struct wlc_bsscfg *wlc_bsscfg_malloc(struct osl_info *osh, uint unit); +static void wlc_bsscfg_mfree(struct osl_info *osh, struct wlc_bsscfg *cfg); static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, uint *err, uint devid); static void wlc_pub_mfree(struct osl_info *osh, struct wlc_pub *pub); @@ -114,7 +116,7 @@ static void wlc_pub_mfree(struct osl_info *osh, struct wlc_pub *pub) kfree(pub); } -wlc_bsscfg_t *wlc_bsscfg_malloc(struct osl_info *osh, uint unit) +static wlc_bsscfg_t *wlc_bsscfg_malloc(struct osl_info *osh, uint unit) { wlc_bsscfg_t *cfg; @@ -134,7 +136,7 @@ wlc_bsscfg_t *wlc_bsscfg_malloc(struct osl_info *osh, uint unit) return NULL; } -void wlc_bsscfg_mfree(struct osl_info *osh, wlc_bsscfg_t *cfg) +static void wlc_bsscfg_mfree(struct osl_info *osh, wlc_bsscfg_t *cfg) { if (cfg == NULL) return; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h index ac34f782b400..86bfdded909e 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h @@ -19,7 +19,3 @@ extern void *wlc_calloc(struct osl_info *osh, uint unit, uint size); extern struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, uint devid); extern void wlc_detach_mfree(struct wlc_info *wlc, struct osl_info *osh); - -struct wlc_bsscfg; -extern struct wlc_bsscfg *wlc_bsscfg_malloc(struct osl_info *osh, uint unit); -extern void wlc_bsscfg_mfree(struct osl_info *osh, struct wlc_bsscfg *cfg); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index 699890ba190f..d6475af0f7e3 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -154,6 +154,8 @@ static void wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p, tx_status_t *txs, u32 frmtxstatus, u32 frmtxstatus2); +static bool wlc_ampdu_cap(struct ampdu_info *ampdu); +static int wlc_ampdu_set(struct ampdu_info *ampdu, bool on); struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc) { @@ -1227,7 +1229,7 @@ static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu, return ini; } -int wlc_ampdu_set(struct ampdu_info *ampdu, bool on) +static int wlc_ampdu_set(struct ampdu_info *ampdu, bool on) { struct wlc_info *wlc = ampdu->wlc; @@ -1250,7 +1252,7 @@ int wlc_ampdu_set(struct ampdu_info *ampdu, bool on) return 0; } -bool wlc_ampdu_cap(struct ampdu_info *ampdu) +static bool wlc_ampdu_cap(struct ampdu_info *ampdu) { if (WLC_PHY_11N_CAP(ampdu->wlc->band)) return true; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h index 03457f63f2ab..33f315c2eb3a 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h @@ -19,8 +19,6 @@ extern struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc); extern void wlc_ampdu_detach(struct ampdu_info *ampdu); -extern bool wlc_ampdu_cap(struct ampdu_info *ampdu); -extern int wlc_ampdu_set(struct ampdu_info *ampdu, bool on); extern int wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, struct sk_buff **aggp, int prec); extern void wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, @@ -28,9 +26,7 @@ extern void wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, extern void wlc_ampdu_reset(struct ampdu_info *ampdu); extern void wlc_ampdu_macaddr_upd(struct wlc_info *wlc); extern void wlc_ampdu_shm_upd(struct ampdu_info *ampdu); - extern u8 wlc_ampdu_null_delim_cnt(struct ampdu_info *ampdu, struct scb *scb, ratespec_t rspec, int phylen); -extern void scb_ampdu_cleanup(struct ampdu_info *ampdu, struct scb *scb); #endif /* _wlc_ampdu_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index b40ca62b6894..20ce4c3777ee 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -130,20 +130,30 @@ static void wlc_flushqueues(struct wlc_info *wlc); static void wlc_write_mhf(struct wlc_hw_info *wlc_hw, u16 *mhfs); static void wlc_mctrl_reset(struct wlc_hw_info *wlc_hw); static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw); +static bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, + uint tx_fifo); +static void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo); +static void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo); /* Low Level Prototypes */ +static int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw); +static void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw); +static void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want); static u16 wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, u32 sel); static void wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset, u16 v, u32 sel); +static void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk); static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme); static void wlc_bmac_detach_dmapio(struct wlc_hw_info *wlc_hw); static void wlc_ucode_bsinit(struct wlc_hw_info *wlc_hw); static bool wlc_validboardtype(struct wlc_hw_info *wlc); static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw); +static bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw); static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw); static void wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init); static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw); +static void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool want, mbool flags); static void wlc_ucode_mute_override_set(struct wlc_hw_info *wlc_hw); static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw); static u32 wlc_wlintrsoff(struct wlc_info *wlc); @@ -984,7 +994,7 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, * may get overrides later in this function * BMAC_NOTES, move low out and resolve the dangling ones */ -void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw) +static void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw) { struct wlc_info *wlc = wlc_hw->wlc; @@ -1276,7 +1286,7 @@ void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, u8 *ea) memcpy(ea, wlc_hw->etheraddr, ETH_ALEN); } -int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw) +static int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw) { return wlc_hw->band->bandtype; } @@ -1864,7 +1874,7 @@ WLBANDINITFN(wlc_bmac_bsinit) (struct wlc_info *wlc, chanspec_t chanspec) wlc_bmac_upd_synthpu(wlc_hw); } -void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk) +static void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk) { WL_TRACE("wl%d: wlc_bmac_core_phy_clk: clk %d\n", wlc_hw->unit, clk); @@ -2863,7 +2873,7 @@ void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask) W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, wlc->macintmask); } -void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool on, mbool flags) +static void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool on, mbool flags) { u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; @@ -2918,7 +2928,7 @@ int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, uint *blocks) * be pulling data into a tx fifo, by the time the MAC acks the suspend * request. */ -bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, uint tx_fifo) +static bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, uint tx_fifo) { /* check that a suspend has been requested and is no longer pending */ @@ -2937,7 +2947,7 @@ bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, uint tx_fifo) return false; } -void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo) +static void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo) { u8 fifo = 1 << tx_fifo; @@ -2968,7 +2978,7 @@ void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo) } } -void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo) +static void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo) { /* BMAC_NOTE: WLC_TX_FIFO_ENAB is done in wlc_dpc() for DMA case but need to be done * here for PIO otherwise the watchdog will catch the inconsistency and fire @@ -3380,7 +3390,7 @@ wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr, return; } -bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) +static bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) { d11regs_t *regs; u32 w, val; @@ -3542,7 +3552,7 @@ void wlc_coredisable(struct wlc_hw_info *wlc_hw) } /* power both the pll and external oscillator on/off */ -void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want) +static void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want) { WL_TRACE("wl%d: wlc_bmac_xtal: want %d\n", wlc_hw->unit, want); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h index 5eabb8e0860e..21c9747a53dd 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h @@ -13,6 +13,8 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifndef _wlc_bmac_h_ +#define _wlc_bmac_h_ /* XXXXX this interface is under wlc.c by design * http://hwnbu-twiki.broadcom.com/bin/view/Mwgroup/WlBmacDesign @@ -77,30 +79,13 @@ enum { IOV_BMAC_LAST }; -typedef enum { - BMAC_DUMP_GPIO_ID, - BMAC_DUMP_SI_ID, - BMAC_DUMP_SIREG_ID, - BMAC_DUMP_SICLK_ID, - BMAC_DUMP_CCREG_ID, - BMAC_DUMP_PCIEREG_ID, - BMAC_DUMP_PHYREG_ID, - BMAC_DUMP_PHYTBL_ID, - BMAC_DUMP_PHYTBL2_ID, - BMAC_DUMP_PHY_RADIOREG_ID, - BMAC_DUMP_LAST -} wlc_bmac_dump_id_t; - extern int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, bool piomode, struct osl_info *osh, void *regsva, uint bustype, void *btparam); extern int wlc_bmac_detach(struct wlc_info *wlc); extern void wlc_bmac_watchdog(void *arg); -extern void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw); /* up/down, reset, clk */ -extern void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want); - extern void wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw, uint offset, const void *buf, int len, u32 sel); @@ -111,7 +96,6 @@ extern void wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset, #define wlc_bmac_copyto_shm(wlc_hw, offset, buf, len) \ wlc_bmac_copyto_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL) -extern void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk); extern void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw); extern void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on); extern void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk); @@ -125,17 +109,13 @@ extern int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw); extern int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw); extern int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw); extern int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags); extern void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode); /* chanspec, ucode interface */ -extern int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw); extern void wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, bool mute, struct txpwr_limits *txpwr); -extern void wlc_bmac_txfifo(struct wlc_hw_info *wlc_hw, uint fifo, void *p, - bool commit, u16 frameid, u8 txpktpend); extern int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, uint *blocks); extern void wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, @@ -157,22 +137,14 @@ extern void wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, extern void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, uint *len); -extern void wlc_bmac_process_ps_switch(struct wlc_hw_info *wlc, - struct ether_addr *ea, s8 ps_on); extern void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, u8 *ea); -extern bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw); extern bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw); extern void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot); -extern void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool want, mbool flags); extern void wlc_bmac_band_stf_ss_set(struct wlc_hw_info *wlc_hw, u8 stf_mode); extern void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw); -extern bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, - uint tx_fifo); -extern void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo); -extern void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo); extern void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, u32 override_bit); @@ -206,13 +178,7 @@ extern void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, mbool req_bit); extern bool wlc_bmac_taclear(struct wlc_hw_info *wlc_hw, bool ta_ok); extern void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw); - -extern void wlc_bmac_dump(struct wlc_hw_info *wlc_hw, struct bcmstrbuf *b, - wlc_bmac_dump_id_t dump_id); - extern u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate); - -extern void wlc_bmac_assert_type_set(struct wlc_hw_info *wlc_hw, u32 type); -extern void wlc_bmac_blink_sync(struct wlc_hw_info *wlc_hw, u32 led_pins); - extern void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail); + +#endif /* _wlc_bmac_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c index ea23728a7727..d53a9587589e 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c @@ -34,6 +34,11 @@ #include #include +#define VALID_CHANNEL20_DB(wlc, val) wlc_valid_channel20_db((wlc)->cmi, val) +#define VALID_CHANNEL20_IN_BAND(wlc, bandunit, val) \ + wlc_valid_channel20_in_band((wlc)->cmi, bandunit, val) +#define VALID_CHANNEL20(wlc, val) wlc_valid_channel20((wlc)->cmi, val) + typedef struct wlc_cm_band { u8 locale_flags; /* locale_info_t flags */ chanvec_t valid_channels; /* List of valid channels in the country */ @@ -62,6 +67,10 @@ static void wlc_set_country_common(wlc_cm_info_t *wlc_cm, const char *country_abbrev, const char *ccode, uint regrev, const country_info_t *country); +static int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode); +static int wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, + const char *country_abbrev, + const char *ccode, int regrev); static int wlc_country_aggregate_map(wlc_cm_info_t *wlc_cm, const char *ccode, char *mapped_ccode, uint *mapped_regrev); static const country_info_t *wlc_country_lookup_direct(const char *ccode, @@ -71,6 +80,19 @@ static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm, char *mapped_ccode, uint *mapped_regrev); static void wlc_channels_commit(wlc_cm_info_t *wlc_cm); +static void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm); +static bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec); +static bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val); +static bool wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, + uint val); +static bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val); +static const country_info_t *wlc_country_lookup(struct wlc_info *wlc, + const char *ccode); +static void wlc_locale_get_channels(const locale_info_t *locale, + chanvec_t *valid_channels); +static const locale_info_t *wlc_get_locale_2g(u8 locale_idx); +static const locale_info_t *wlc_get_locale_5g(u8 locale_idx); +static bool wlc_japan(struct wlc_info *wlc); static bool wlc_japan_ccode(const char *ccode); static void wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t * wlc_cm, @@ -377,7 +399,8 @@ void wlc_locale_add_channels(chanvec_t *target, const chanvec_t *channels) } } -void wlc_locale_get_channels(const locale_info_t *locale, chanvec_t *channels) +static void wlc_locale_get_channels(const locale_info_t *locale, + chanvec_t *channels) { u8 i; @@ -563,7 +586,7 @@ struct chan20_info chan20_info[] = { }; #endif /* SUPPORT_40MHZ */ -const locale_info_t *wlc_get_locale_2g(u8 locale_idx) +static const locale_info_t *wlc_get_locale_2g(u8 locale_idx) { if (locale_idx >= ARRAY_SIZE(g_locale_2g_table)) { WL_ERROR("%s: locale 2g index size out of range %d\n", @@ -574,7 +597,7 @@ const locale_info_t *wlc_get_locale_2g(u8 locale_idx) return g_locale_2g_table[locale_idx]; } -const locale_info_t *wlc_get_locale_5g(u8 locale_idx) +static const locale_info_t *wlc_get_locale_5g(u8 locale_idx) { if (locale_idx >= ARRAY_SIZE(g_locale_5g_table)) { WL_ERROR("%s: locale 5g index size out of range %d\n", @@ -665,14 +688,14 @@ u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, uint bandunit) /* set the driver's current country and regulatory information using a country code * as the source. Lookup built in country information found with the country code. */ -int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode) +static int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode) { char country_abbrev[WLC_CNTRY_BUF_SZ]; strncpy(country_abbrev, ccode, WLC_CNTRY_BUF_SZ); return wlc_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1); } -int +static int wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, const char *country_abbrev, const char *ccode, int regrev) @@ -767,7 +790,7 @@ wlc_set_country_common(wlc_cm_info_t *wlc_cm, /* Lookup a country info structure from a null terminated country code * The lookup is case sensitive. */ -const country_info_t *wlc_country_lookup(struct wlc_info *wlc, +static const country_info_t *wlc_country_lookup(struct wlc_info *wlc, const char *ccode) { const country_info_t *country; @@ -970,7 +993,7 @@ static void wlc_channels_commit(wlc_cm_info_t *wlc_cm) } /* reset the quiet channels vector to the union of the restricted and radar channel sets */ -void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm) +static void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm) { struct wlc_info *wlc = wlc_cm->wlc; uint i, j; @@ -991,7 +1014,7 @@ void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm) } } -bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec) +static bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec) { return N_ENAB(wlc_cm->wlc->pub) && CHSPEC_IS40(chspec) ? (isset @@ -1008,7 +1031,7 @@ bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec) /* Is the channel valid for the current locale? (but don't consider channels not * available due to bandlocking) */ -bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val) +static bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val) { struct wlc_info *wlc = wlc_cm->wlc; @@ -1018,7 +1041,7 @@ bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val) } /* Is the channel valid for the current locale and specified band? */ -bool +static bool wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, uint val) { return ((val < MAXCHANNEL) @@ -1026,7 +1049,7 @@ wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, uint val) } /* Is the channel valid for the current locale and current band? */ -bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val) +static bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val) { struct wlc_info *wlc = wlc_cm->wlc; @@ -1470,7 +1493,7 @@ wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, } /* Returns true if currently set country is Japan or variant */ -bool wlc_japan(struct wlc_info *wlc) +static bool wlc_japan(struct wlc_info *wlc) { return wlc_japan_ccode(wlc->cmi->country_abbrev); } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.h b/drivers/staging/brcm80211/brcmsmac/wlc_channel.h index d569ec45267c..9b3bf11d445b 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_channel.h @@ -107,27 +107,10 @@ typedef struct wlc_cm_info wlc_cm_info_t; extern wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc); extern void wlc_channel_mgr_detach(wlc_cm_info_t *wlc_cm); -extern int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode); -extern int wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, - const char *country_abbrev, - const char *ccode, int regrev); - extern u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, - uint bandunit); - -extern void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm); -extern bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec); - -#define VALID_CHANNEL20_DB(wlc, val) wlc_valid_channel20_db((wlc)->cmi, val) -#define VALID_CHANNEL20_IN_BAND(wlc, bandunit, val) \ - wlc_valid_channel20_in_band((wlc)->cmi, bandunit, val) -#define VALID_CHANNEL20(wlc, val) wlc_valid_channel20((wlc)->cmi, val) + uint bandunit); extern bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec); -extern bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val); -extern bool wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, - uint val); -extern bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val); extern void wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, @@ -136,14 +119,4 @@ extern void wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, u8 local_constraint_qdbm); -extern const country_info_t *wlc_country_lookup(struct wlc_info *wlc, - const char *ccode); -extern void wlc_locale_get_channels(const locale_info_t *locale, - chanvec_t *valid_channels); -extern const locale_info_t *wlc_get_locale_2g(u8 locale_idx); -extern const locale_info_t *wlc_get_locale_5g(u8 locale_idx); -extern bool wlc_japan(struct wlc_info *wlc); - -extern u8 wlc_get_regclass(wlc_cm_info_t *wlc_cm, chanspec_t chanspec); - #endif /* _WLC_CHANNEL_H */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index 26d40aa818a9..77cd2c9f1dd4 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -253,6 +253,7 @@ static ratespec_t mac80211_wlc_set_nrate(struct wlc_info *wlc, static void wlc_tx_prec_map_init(struct wlc_info *wlc); static void wlc_watchdog(void *arg); static void wlc_watchdog_by_timer(void *arg); +static u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate); static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg); static int wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, const bcm_iovar_t *vi); @@ -5051,7 +5052,7 @@ int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len) } #endif /* defined(BCMDBG) */ -u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate) +static u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate) { return wlc_bmac_rate_shm_offset(wlc->hw, rate); } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h index ded018adda69..d4d3cd21f800 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h @@ -150,18 +150,6 @@ struct rsn_parms { IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_GRN_FLD |\ HT_CAP_MAX_AMSDU | IEEE80211_HT_CAP_DSSSCCK40) -/* Event data type */ -typedef struct wlc_event { - wl_event_msg_t event; /* encapsulated event */ - struct ether_addr *addr; /* used to keep a trace of the potential present of - * an address in wlc_event_msg_t - */ - int bsscfgidx; /* BSS config when needed */ - struct wl_if *wlif; /* pointer to wlif */ - void *data; /* used to hang additional data on an event */ - struct wlc_event *next; /* enables ordered list of pending events */ -} wlc_event_t; - /* wlc internal bss_info, wl external one is in wlioctl.h */ typedef struct wlc_bss_info { u8 BSSID[ETH_ALEN]; /* network BSSID */ @@ -570,13 +558,8 @@ extern int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, watchdog_fn_t watchdog_fn, down_fn_t down_fn); extern int wlc_module_unregister(struct wlc_pub *pub, const char *name, void *hdl); -extern void wlc_event_if(struct wlc_info *wlc, struct wlc_bsscfg *cfg, - wlc_event_t *e, const struct ether_addr *addr); extern void wlc_suspend_mac_and_wait(struct wlc_info *wlc); extern void wlc_enable_mac(struct wlc_info *wlc); -extern u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate); -extern u32 wlc_get_rspec_history(struct wlc_bsscfg *cfg); -extern u32 wlc_get_current_highest_rate(struct wlc_bsscfg *cfg); extern void wlc_associate_upd(struct wlc_info *wlc, bool state); extern void wlc_scan_start(struct wlc_info *wlc); extern void wlc_scan_stop(struct wlc_info *wlc); @@ -607,11 +590,6 @@ extern int wlc_iocpichk(struct wlc_info *wlc, uint phytype); #endif /* helper functions */ -extern void wlc_getrand(struct wlc_info *wlc, u8 *buf, int len); - -struct scb; -extern void wlc_ps_on(struct wlc_info *wlc, struct scb *scb); -extern void wlc_ps_off(struct wlc_info *wlc, struct scb *scb, bool discard); extern bool wlc_check_radio_disabled(struct wlc_info *wlc); extern bool wlc_radio_monitor_stop(struct wlc_info *wlc); @@ -619,9 +597,6 @@ extern bool wlc_radio_monitor_stop(struct wlc_info *wlc); extern int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len); #endif -extern void wlc_pmkid_build_cand_list(struct wlc_bsscfg *cfg, bool check_SSID); -extern void wlc_pmkid_event(struct wlc_bsscfg *cfg); - #define MAXBANDS 2 /* Maximum #of bands */ /* bandstate array indices */ #define BAND_2G_INDEX 0 /* wlc->bandstate[x] index */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c index d5b0f780ef20..46556ead78c1 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c @@ -39,6 +39,9 @@ #include #include +#define MIN_SPATIAL_EXPANSION 0 +#define MAX_SPATIAL_EXPANSION 1 + #define WLC_STF_SS_STBC_RX(wlc) (WLCISNPHY(wlc->band) && \ NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6)) diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.h b/drivers/staging/brcm80211/brcmsmac/wlc_stf.h index e127862c4449..2b1180b128a8 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_stf.h @@ -17,9 +17,6 @@ #ifndef _wlc_stf_h_ #define _wlc_stf_h_ -#define MIN_SPATIAL_EXPANSION 0 -#define MAX_SPATIAL_EXPANSION 1 - extern int wlc_stf_attach(struct wlc_info *wlc); extern void wlc_stf_detach(struct wlc_info *wlc); @@ -37,6 +34,5 @@ extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc); extern void wlc_stf_phy_chain_calc(struct wlc_info *wlc); extern u16 wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec); extern u16 wlc_stf_d11hdrs_phyctl_txant(struct wlc_info *wlc, ratespec_t rspec); -extern u16 wlc_stf_spatial_expansion_get(struct wlc_info *wlc, - ratespec_t rspec); + #endif /* _wlc_stf_h_ */ -- cgit v1.2.3 From 45575664fb22c50a686719f1f1e07b13cd04ef1c Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Feb 2011 16:39:14 +0100 Subject: staging: brcm80211: remove nested include statements In order to analyze include file usage nested includes have been removed from the driver sources. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 38 +++++++------- drivers/staging/brcm80211/brcmsmac/wl_mac80211.h | 2 - drivers/staging/brcm80211/brcmsmac/wlc_alloc.c | 30 +++++++---- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 32 +++++++----- drivers/staging/brcm80211/brcmsmac/wlc_antsel.c | 35 +++++++------ drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 63 ++++++++++------------- drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h | 4 -- drivers/staging/brcm80211/brcmsmac/wlc_channel.c | 33 +++++++----- drivers/staging/brcm80211/brcmsmac/wlc_channel.h | 2 - drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 46 +++++++++-------- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h | 6 --- drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c | 42 ++++++++------- drivers/staging/brcm80211/brcmsmac/wlc_pub.h | 4 -- drivers/staging/brcm80211/brcmsmac/wlc_rate.c | 22 ++++---- drivers/staging/brcm80211/brcmsmac/wlc_scb.h | 2 - drivers/staging/brcm80211/brcmsmac/wlc_stf.c | 36 +++++++------ 16 files changed, 208 insertions(+), 189 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 6e421b947271..1b3f12ba5edb 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -18,35 +18,35 @@ #include #include -#include +#include #include -#include #include #include #include -#include -#define WLC_MAXBSSCFG 1 /* single BSS configs */ - -#include +#include #include -#include + +#include +#include +#include #include #include #include -#include -#include #include -#include -#include -#include -#include -#include - -#include -#include -#include -#include +#include "wlc_cfg.h" +#include "phy/phy_version.h" +#include "wlc_key.h" +#include "sbhndpio.h" +#include "phy/wlc_phy_hal.h" +#include "wlc_channel.h" +#include "wlc_scb.h" +#include "wlc_pub.h" +#include "wl_dbg.h" +#include "wl_export.h" +#include "wl_ucode.h" +#include "d11ucode_ext.h" +#include "wl_mac80211.h" static void wl_timer(unsigned long data); static void _wl_timer(wl_timer_t *t); diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h index b7407caa4db2..f761fd14ee44 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h @@ -17,8 +17,6 @@ #ifndef _wl_mac80211_h_ #define _wl_mac80211_h_ -#include - /* BMAC Note: High-only driver is no longer working in softirq context as it needs to block and * sleep so perimeter lock has to be a semaphore instead of spinlock. This requires timers to be * submitted to workqueue instead of being on kernel timer diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c index a4555f745127..20a0f86a2cd7 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c @@ -14,22 +14,30 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include -#include -#include -#include -#include -#include +#include + +#include #include +#include #include #include #include -#include -#include -#include #include -#include -#include -#include + +#include "sbhndpio.h" +#include "d11.h" +#include "wlc_types.h" +#include "wlc_cfg.h" +#include "wlc_scb.h" +#include "wlc_pub.h" +#include "wlc_key.h" +#include "wlc_alloc.h" +#include "wl_dbg.h" +#include "wlc_rate.h" +#include "wlc_bsscfg.h" +#include "phy/wlc_phy_hal.h" +#include "wlc_channel.h" +#include "wlc_mac80211.h" static struct wlc_bsscfg *wlc_bsscfg_malloc(struct osl_info *osh, uint unit); static void wlc_bsscfg_mfree(struct osl_info *osh, struct wlc_bsscfg *cfg); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index d6475af0f7e3..68b65a0c896b 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -14,9 +14,11 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include -#include -#include +#include + +#include #include +#include #include #include #include @@ -24,17 +26,21 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include + +#include "wlc_types.h" +#include "wlc_cfg.h" +#include "wlc_rate.h" +#include "wlc_scb.h" +#include "wlc_pub.h" +#include "wlc_key.h" +#include "phy/wlc_phy_hal.h" +#include "wlc_antsel.h" +#include "wl_export.h" +#include "wl_dbg.h" +#include "wlc_bsscfg.h" +#include "wlc_channel.h" +#include "wlc_mac80211.h" +#include "wlc_ampdu.h" /* * Disable AMPDU statistics counters for now diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c index da19a082ee46..a5f2508367e8 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c @@ -21,26 +21,31 @@ #include #include #include -#include + +#include #include +#include #include #include -#include - #include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include + +#include "sbhndpio.h" +#include "d11.h" +#include "wlc_rate.h" +#include "wlc_key.h" +#include "wlc_scb.h" +#include "wlc_pub.h" +#include "wl_dbg.h" +#include "phy/wlc_phy_hal.h" +#include "wlc_bmac.h" +#include "wlc_channel.h" +#include "wlc_bsscfg.h" +#include "wlc_mac80211.h" +#include "wl_export.h" +#include "wlc_phy_shim.h" +#include "wlc_antsel.h" /* useful macros */ #define WLC_ANTSEL_11N_0(ant) ((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf) diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 20ce4c3777ee..dc41593d956e 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -16,57 +16,50 @@ #include -#include #include #include #include #include -#include -#include + #include +#include +#include +#include +#include #include -#include #include +#include +#include +#include #include #include #include #include -#include #include #include #include -#include -#include -#include -#include -#include -#include -#include -/* BMAC_NOTE: a WLC_HIGH compile include of wlc.h adds in more structures and type - * dependencies. Need to include these to files to allow a clean include of wlc.h - * with WLC_HIGH defined. - * At some point we may be able to skip the include of wlc.h and instead just - * define a stub wlc_info and band struct to allow rpc calls to get the rpc handle. - */ -#include -#include -#include -#include -#include + +#include "wlc_types.h" +#include "sbhndpio.h" +#include "d11.h" +#include "wlc_cfg.h" +#include "wlc_rate.h" +#include "wlc_scb.h" +#include "wlc_pub.h" +#include "wlc_key.h" +#include "wlc_phy_shim.h" +#include "phy/wlc_phy_hal.h" +#include "wlc_channel.h" +#include "wlc_bsscfg.h" +#include "wlc_mac80211.h" +#include "wl_export.h" #include "wl_ucode.h" #include "d11ucode_ext.h" -#include - -/* BMAC_NOTE: With WLC_HIGH defined, some fns in this file make calls to high level - * functions defined in the headers below. We should be eliminating those calls and - * will be able to delete these include lines. - */ -#include - -#include - -#include -#include +#include "wlc_antsel.h" +#include "pcie_core.h" +#include "wlc_alloc.h" +#include "wl_dbg.h" +#include "wlc_bmac.h" #define TIMER_INTERVAL_WATCHDOG_BMAC 1000 /* watchdog timer, in unit of ms */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h b/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h index 301270f4002b..0951574ea604 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h @@ -17,8 +17,6 @@ #ifndef _WLC_BSSCFG_H_ #define _WLC_BSSCFG_H_ -#include - /* Check if a particular BSS config is AP or STA */ #define BSSCFG_AP(cfg) (0) #define BSSCFG_STA(cfg) (1) @@ -28,8 +26,6 @@ /* forward declarations */ typedef struct wlc_bsscfg wlc_bsscfg_t; -#include - #define NTXRATE 64 /* # tx MPDUs rate is reported for */ #define MAXMACLIST 64 /* max # source MAC matches */ #define BCN_TEMPLATE_COUNT 2 diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c index d53a9587589e..edfc392d75ab 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c @@ -15,24 +15,33 @@ */ #include -#include -#include -#include -#include +#include #include #include + +#include +#include +#include #include #include -#include #include #include -#include -#include -#include -#include -#include -#include -#include + +#include "wlc_types.h" +#include "sbhndpio.h" +#include "d11.h" +#include "wlc_cfg.h" +#include "wlc_scb.h" +#include "wlc_pub.h" +#include "wlc_key.h" +#include "phy/wlc_phy_hal.h" +#include "wlc_bmac.h" +#include "wlc_rate.h" +#include "wlc_channel.h" +#include "wlc_bsscfg.h" +#include "wlc_mac80211.h" +#include "wlc_stf.h" +#include "wl_dbg.h" #define VALID_CHANNEL20_DB(wlc, val) wlc_valid_channel20_db((wlc)->cmi, val) #define VALID_CHANNEL20_IN_BAND(wlc, bandunit, val) \ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.h b/drivers/staging/brcm80211/brcmsmac/wlc_channel.h index 9b3bf11d445b..b8dec5b39d85 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_channel.h @@ -17,8 +17,6 @@ #ifndef _WLC_CHANNEL_H_ #define _WLC_CHANNEL_H_ -#include - #define WLC_TXPWR_DB_FACTOR 4 /* conversion for phy txpwr cacluations that use .25 dB units */ struct wlc_info; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index 77cd2c9f1dd4..1d8434586d25 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -16,10 +16,11 @@ #include #include #include -#include +#include + +#include #include #include -#include #include #include #include @@ -27,29 +28,32 @@ #include #include #include -#include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include + +#include "sbhndpio.h" +#include "d11.h" +#include "wlc_types.h" +#include "wlc_cfg.h" +#include "wlc_rate.h" +#include "wlc_scb.h" +#include "wlc_pub.h" +#include "wlc_key.h" +#include "wlc_bsscfg.h" +#include "phy/wlc_phy_hal.h" +#include "wlc_channel.h" +#include "wlc_mac80211.h" +#include "wlc_bmac.h" +#include "wlc_phy_hal.h" +#include "wlc_phy_shim.h" +#include "wlc_antsel.h" +#include "wlc_stf.h" +#include "wlc_ampdu.h" +#include "wl_export.h" #include "d11ucode_ext.h" -#include -#include -#include +#include "wlc_alloc.h" +#include "wl_dbg.h" /* * Disable statistics counting for WME diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h index 72bfb8fa4d0e..3914e2b18fa4 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h @@ -17,12 +17,6 @@ #ifndef _wlc_h_ #define _wlc_h_ -#include -#include -#include -#include -#include - #define MA_WINDOW_SZ 8 /* moving average window size */ #define WL_HWRXOFF 38 /* chip rx buffer offset */ #define INVCHANNEL 255 /* invalid channel */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c index 4eaec04c527c..ff595ab11739 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c @@ -22,38 +22,42 @@ */ #include -#include -#include #include #include -#include -#include #include +#include +#include +#include +#include #include #include #include #include #include #include -#include #include #include #include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include + +#include "wlc_types.h" +#include "wl_dbg.h" +#include "sbhndpio.h" +#include "wlc_cfg.h" +#include "d11.h" +#include "wlc_rate.h" +#include "wlc_scb.h" +#include "wlc_pub.h" +#include "phy/wlc_phy_hal.h" +#include "wlc_channel.h" +#include "bcmsrom.h" +#include "wlc_key.h" +#include "wlc_bmac.h" +#include "wlc_phy_hal.h" +#include "wl_export.h" +#include "wlc_bsscfg.h" +#include "wlc_mac80211.h" +#include "wlc_phy_shim.h" /* PHY SHIM module specific state */ struct wlc_phy_shim_info { diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h index d4d3cd21f800..af5d82ca3d21 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h @@ -17,10 +17,6 @@ #ifndef _wlc_pub_h_ #define _wlc_pub_h_ -#include -#include -#include - #define WLC_NUMRATES 16 /* max # of rates in a rateset */ #define MAXMULTILIST 32 /* max # multicast addresses */ #define D11_PHY_HDR_LEN 6 /* Phy header length - 6 bytes */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c index d48dd47ef846..a8e30016a655 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c @@ -14,21 +14,25 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include +#include + +#include +#include #include -#include #include -#include #include #include #include - -#include #include -#include -#include -#include -#include -#include + +#include "wlc_types.h" +#include "sbhndpio.h" +#include "d11.h" +#include "wl_dbg.h" +#include "wlc_cfg.h" +#include "wlc_scb.h" +#include "wlc_pub.h" +#include "wlc_rate.h" /* Rate info per rate: It tells whether a rate is ofdm or not and its phy_rate value */ const u8 rate_info[WLC_MAXRATE + 1] = { diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_scb.h b/drivers/staging/brcm80211/brcmsmac/wlc_scb.h index 142b75674444..73260068898f 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_scb.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_scb.h @@ -17,8 +17,6 @@ #ifndef _wlc_scb_h_ #define _wlc_scb_h_ -#include - extern bool wlc_aggregatable(struct wlc_info *wlc, u8 tid); #define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c index 46556ead78c1..6574fb4d6937 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c @@ -16,28 +16,34 @@ #include #include -#include + +#include +#include + #include #include #include #include -#include #include #include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include + +#include "wlc_types.h" +#include "sbhndpio.h" +#include "d11.h" +#include "wl_dbg.h" +#include "wlc_cfg.h" +#include "wlc_rate.h" +#include "wlc_scb.h" +#include "wlc_pub.h" +#include "wlc_key.h" +#include "phy/wlc_phy_hal.h" +#include "wlc_channel.h" +#include "wlc_bsscfg.h" +#include "wlc_mac80211.h" +#include "wl_export.h" +#include "wlc_bmac.h" +#include "wlc_stf.h" #define MIN_SPATIAL_EXPANSION 0 #define MAX_SPATIAL_EXPANSION 1 -- cgit v1.2.3 From 12bacc1bce320e43b4a6fd1195980a355823127d Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Feb 2011 16:39:15 +0100 Subject: staging: brcm80211: remove typedefs that were flagged by checkpatch The previous patch resulted in checkpatch to complain about 'new' typedefs that were relocated to another include file. This commits removes those typedef structures. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_alloc.c | 22 +++--- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 6 +- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 96 +++++++++++------------ drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h | 70 +++++++++-------- 6 files changed, 100 insertions(+), 98 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c index 20a0f86a2cd7..8e4908b3ecf3 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c @@ -204,8 +204,8 @@ struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, } wlc->hw->wlc = wlc; - wlc->hw->bandstate[0] = (wlc_hwband_t *)wlc_calloc(osh, unit, - (sizeof(wlc_hwband_t) * MAXBANDS)); + wlc->hw->bandstate[0] = wlc_calloc(osh, unit, + (sizeof(struct wlc_hwband) * MAXBANDS)); if (wlc->hw->bandstate[0] == NULL) { *err = 1006; goto fail; @@ -213,14 +213,14 @@ struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, int i; for (i = 1; i < MAXBANDS; i++) { - wlc->hw->bandstate[i] = (wlc_hwband_t *) + wlc->hw->bandstate[i] = (struct wlc_hwband *) ((unsigned long)wlc->hw->bandstate[0] + - (sizeof(wlc_hwband_t) * i)); + (sizeof(struct wlc_hwband) * i)); } } - wlc->modulecb = (modulecb_t *)wlc_calloc(osh, unit, - sizeof(modulecb_t) * WLC_MAXMODULES); + wlc->modulecb = wlc_calloc(osh, unit, + sizeof(struct modulecb) * WLC_MAXMODULES); if (wlc->modulecb == NULL) { *err = 1009; goto fail; @@ -240,8 +240,8 @@ struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, } wlc_bsscfg_ID_assign(wlc, wlc->cfg); - wlc->pkt_callback = (pkt_cb_t *)wlc_calloc(osh, unit, - (sizeof(pkt_cb_t) * (wlc->pub->tunables->maxpktcb + 1))); + wlc->pkt_callback = wlc_calloc(osh, unit, + (sizeof(struct pkt_cb) * (wlc->pub->tunables->maxpktcb + 1))); if (wlc->pkt_callback == NULL) { *err = 1013; goto fail; @@ -261,14 +261,14 @@ struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, } } - wlc->protection = (wlc_protection_t *)wlc_calloc(osh, unit, - sizeof(wlc_protection_t)); + wlc->protection = wlc_calloc(osh, unit, + sizeof(struct wlc_protection)); if (wlc->protection == NULL) { *err = 1016; goto fail; } - wlc->stf = (wlc_stf_t *)wlc_calloc(osh, unit, sizeof(wlc_stf_t)); + wlc->stf = wlc_calloc(osh, unit, sizeof(struct wlc_stf)); if (wlc->stf == NULL) { *err = 1017; goto fail; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index 68b65a0c896b..a6572db522b4 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -494,7 +494,7 @@ wlc_ampdu_agg(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p, } int BCMFASTPATH -wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, +wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, struct sk_buff **pdu, int prec) { struct wlc_info *wlc; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h index 33f315c2eb3a..17e9ebc0dfe2 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h @@ -19,7 +19,7 @@ extern struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc); extern void wlc_ampdu_detach(struct ampdu_info *ampdu); -extern int wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, +extern int wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, struct sk_buff **aggp, int prec); extern void wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p, tx_status_t *txs); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index dc41593d956e..f450c55735a0 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -1012,7 +1012,7 @@ static void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw) int wlc_bmac_detach(struct wlc_info *wlc) { uint i; - wlc_hwband_t *band; + struct wlc_hwband *band; struct wlc_hw_info *wlc_hw = wlc->hw; int callbacks; @@ -1397,7 +1397,7 @@ wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, u16 val, M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4, M_HOST_FLAGS5 }; - wlc_hwband_t *band; + struct wlc_hwband *band; ASSERT((val & ~mask) == 0); ASSERT(idx < MHFMAX); @@ -1445,7 +1445,7 @@ wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, u16 val, u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands) { - wlc_hwband_t *band; + struct wlc_hwband *band; ASSERT(idx < MHFMAX); switch (bands) { diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index 1d8434586d25..4ae75a344592 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -264,11 +264,12 @@ static int wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc); /* send and receive */ -static wlc_txq_info_t *wlc_txq_alloc(struct wlc_info *wlc, - struct osl_info *osh); +static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc, + struct osl_info *osh); static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh, - wlc_txq_info_t *qi); -static void wlc_txflowcontrol_signal(struct wlc_info *wlc, wlc_txq_info_t *qi, + struct wlc_txq_info *qi); +static void wlc_txflowcontrol_signal(struct wlc_info *wlc, + struct wlc_txq_info *qi, bool on, int prio); static void wlc_txflowcontrol_reset(struct wlc_info *wlc); static u16 wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, @@ -1728,7 +1729,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, uint err = 0; uint j; struct wlc_pub *pub; - wlc_txq_info_t *qi; + struct wlc_txq_info *qi; uint n_disabled; WL_NONE("wl%d: %s: vendor 0x%x device 0x%x\n", @@ -2170,7 +2171,7 @@ uint wlc_detach(struct wlc_info *wlc) { /* free dumpcb list */ - dumpcb_t *prev, *ptr; + struct dumpcb_s *prev, *ptr; prev = ptr = wlc->dumpcb_head; while (ptr) { ptr = prev->next; @@ -2676,7 +2677,7 @@ uint wlc_down(struct wlc_info *wlc) uint callbacks = 0; int i; bool dev_gone = false; - wlc_txq_info_t *qi; + struct wlc_txq_info *qi; WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__); @@ -4346,7 +4347,7 @@ int wlc_module_unregister(struct wlc_pub *pub, const char *name, void *hdl) for (i = 0; i < WLC_MAXMODULES; i++) { if (!strcmp(wlc->modulecb[i].name, name) && (wlc->modulecb[i].hdl == hdl)) { - memset(&wlc->modulecb[i], 0, sizeof(modulecb_t)); + memset(&wlc->modulecb[i], 0, sizeof(struct modulecb)); return 0; } } @@ -5145,7 +5146,7 @@ void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, uint prec) { struct wlc_info *wlc = (struct wlc_info *) ctx; - wlc_txq_info_t *qi = wlc->active_queue; /* Check me */ + struct wlc_txq_info *qi = wlc->active_queue; /* Check me */ struct pktq *q = &qi->q; int prio; @@ -5217,7 +5218,7 @@ wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, return 0; } -void BCMFASTPATH wlc_send_q(struct wlc_info *wlc, wlc_txq_info_t *qi) +void BCMFASTPATH wlc_send_q(struct wlc_info *wlc, struct wlc_txq_info *qi) { struct sk_buff *pkt[DOT11_MAXNUMFRAGS]; int prec; @@ -7001,10 +7002,9 @@ wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, d11rxhdr_t *rxh, return; } -void wlc_bss_list_free(struct wlc_info *wlc, wlc_bss_list_t *bss_list) +void wlc_bss_list_free(struct wlc_info *wlc, struct wlc_bss_list *bss_list) { uint index; - wlc_bss_info_t *bi; if (!bss_list) { WL_ERROR("%s: Attempting to free NULL list\n", __func__); @@ -7012,11 +7012,8 @@ void wlc_bss_list_free(struct wlc_info *wlc, wlc_bss_list_t *bss_list) } /* inspect all BSS descriptor */ for (index = 0; index < bss_list->count; index++) { - bi = bss_list->ptrs[index]; - if (bi) { - kfree(bi); - bss_list->ptrs[index] = NULL; - } + kfree(bss_list->ptrs[index]); + bss_list->ptrs[index] = NULL; } bss_list->count = 0; } @@ -8322,7 +8319,8 @@ void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode) /* check for the particular priority flow control bit being set */ bool -wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, wlc_txq_info_t *q, int prio) +wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, struct wlc_txq_info *q, + int prio) { uint prio_mask; @@ -8337,7 +8335,7 @@ wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, wlc_txq_info_t *q, int prio) } /* propogate the flow control to all interfaces using the given tx queue */ -void wlc_txflowcontrol(struct wlc_info *wlc, wlc_txq_info_t *qi, +void wlc_txflowcontrol(struct wlc_info *wlc, struct wlc_txq_info *qi, bool on, int prio) { uint prio_bits; @@ -8380,8 +8378,8 @@ void wlc_txflowcontrol(struct wlc_info *wlc, wlc_txq_info_t *qi, } void -wlc_txflowcontrol_override(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, - uint override) +wlc_txflowcontrol_override(struct wlc_info *wlc, struct wlc_txq_info *qi, + bool on, uint override) { uint prev_override; @@ -8429,7 +8427,7 @@ wlc_txflowcontrol_override(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, static void wlc_txflowcontrol_reset(struct wlc_info *wlc) { - wlc_txq_info_t *qi; + struct wlc_txq_info *qi; for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { if (qi->stopped) { @@ -8440,7 +8438,7 @@ static void wlc_txflowcontrol_reset(struct wlc_info *wlc) } static void -wlc_txflowcontrol_signal(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, +wlc_txflowcontrol_signal(struct wlc_info *wlc, struct wlc_txq_info *qi, bool on, int prio) { struct wlc_if *wlcif; @@ -8451,40 +8449,40 @@ wlc_txflowcontrol_signal(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, } } -static wlc_txq_info_t *wlc_txq_alloc(struct wlc_info *wlc, struct osl_info *osh) +static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc, + struct osl_info *osh) { - wlc_txq_info_t *qi, *p; - - qi = (wlc_txq_info_t *) wlc_calloc(osh, wlc->pub->unit, - sizeof(wlc_txq_info_t)); - if (qi == NULL) { - return NULL; - } + struct wlc_txq_info *qi, *p; - /* Have enough room for control packets along with HI watermark */ - /* Also, add room to txq for total psq packets if all the SCBs leave PS mode */ - /* The watermark for flowcontrol to OS packets will remain the same */ - pktq_init(&qi->q, WLC_PREC_COUNT, - (2 * wlc->pub->tunables->datahiwat) + PKTQ_LEN_DEFAULT + - wlc->pub->psq_pkts_total); - - /* add this queue to the the global list */ - p = wlc->tx_queues; - if (p == NULL) { - wlc->tx_queues = qi; - } else { - while (p->next != NULL) - p = p->next; - p->next = qi; + qi = wlc_calloc(osh, wlc->pub->unit, sizeof(struct wlc_txq_info)); + if (qi != NULL) { + /* + * Have enough room for control packets along with HI watermark + * Also, add room to txq for total psq packets if all the SCBs + * leave PS mode. The watermark for flowcontrol to OS packets + * will remain the same + */ + pktq_init(&qi->q, WLC_PREC_COUNT, + (2 * wlc->pub->tunables->datahiwat) + PKTQ_LEN_DEFAULT + + wlc->pub->psq_pkts_total); + + /* add this queue to the the global list */ + p = wlc->tx_queues; + if (p == NULL) { + wlc->tx_queues = qi; + } else { + while (p->next != NULL) + p = p->next; + p->next = qi; + } } - return qi; } static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh, - wlc_txq_info_t *qi) + struct wlc_txq_info *qi) { - wlc_txq_info_t *p; + struct wlc_txq_info *p; if (qi == NULL) return; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h index 3914e2b18fa4..6ddb2baf2857 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h @@ -36,11 +36,11 @@ #define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN) /* For managing scan result lists */ -typedef struct wlc_bss_list { +struct wlc_bss_list { uint count; bool beacon; /* set for beacon, cleared for probe response */ wlc_bss_info_t *ptrs[MAXBSS]; -} wlc_bss_list_t; +}; #define SW_TIMER_MAC_STAT_UPD 30 /* periodic MAC stats update */ @@ -200,7 +200,7 @@ extern const u8 prio2fifo[]; #define WLCWLUNIT(wlc) ((wlc)->pub->unit) -typedef struct wlc_protection { +struct wlc_protection { bool _g; /* use g spec protection, driver internal */ s8 g_override; /* override for use of g spec protection */ u8 gmode_user; /* user config gmode, operating band->gmode is different */ @@ -225,10 +225,10 @@ typedef struct wlc_protection { uint ht20in40_ovlp_timeout; /* #sec until 20MHz overlapping OPMODE gone */ uint ht20in40_ibss_timeout; /* #sec until 20MHz-only HT station bcns gone */ uint non_gf_ibss_timeout; /* #sec until non-GF bcns gone */ -} wlc_protection_t; +}; /* anything affects the single/dual streams/antenna operation */ -typedef struct wlc_stf { +struct wlc_stf { u8 hw_txchain; /* HW txchain bitmap cfg */ u8 txchain; /* txchain bitmap being used */ u8 txstreams; /* number of txchains being used */ @@ -252,7 +252,7 @@ typedef struct wlc_stf { s8 ldpc; /* AUTO/ON/OFF ldpc cap supported */ u8 txcore[MAX_STREAMS_SUPPORTED + 1]; /* bitmap of selected core for each Nsts */ s8 spatial_policy; -} wlc_stf_t; +}; #define WLC_STF_SS_STBC_TX(wlc, scb) \ (((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) || \ @@ -330,15 +330,15 @@ struct wlcband { /* tx completion callback takes 3 args */ typedef void (*pkcb_fn_t) (struct wlc_info *wlc, uint txstatus, void *arg); -typedef struct pkt_cb { +struct pkt_cb { pkcb_fn_t fn; /* function to call when tx frame completes */ void *arg; /* void arg for fn */ u8 nextidx; /* index of next call back if threading */ bool entered; /* recursion check */ -} pkt_cb_t; +}; - /* module control blocks */ -typedef struct modulecb { +/* module control blocks */ +struct modulecb { char name[32]; /* module name : NULL indicates empty array member */ const bcm_iovar_t *iovars; /* iovar table */ void *hdl; /* handle passed when handler 'doiovar' is called */ @@ -349,15 +349,15 @@ typedef struct modulecb { * number of timers that could not be * freed. */ -} modulecb_t; +}; - /* dump control blocks */ -typedef struct dumpcb_s { +/* dump control blocks */ +struct dumpcb_s { const char *name; /* dump name */ dump_fn_t dump_fn; /* 'wl dump' handler */ void *dump_fn_arg; struct dumpcb_s *next; -} dumpcb_t; +}; /* virtual interface */ struct wlc_if { @@ -379,7 +379,7 @@ struct wlc_if { /* flags for the interface */ #define WLC_IF_LINKED 0x02 /* this interface is linked to a wl_if */ -typedef struct wlc_hwband { +struct wlc_hwband { int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */ uint bandunit; /* bandstate[] index */ u16 mhfs[MHFMAX]; /* MHF array shadow */ @@ -394,7 +394,7 @@ typedef struct wlc_hwband { u16 radiorev; wlc_phy_t *pi; /* pointer to phy specific information */ bool abgphy_encore; -} wlc_hwband_t; +}; struct wlc_hw_info { struct osl_info *osh; /* pointer to os handle */ @@ -424,8 +424,8 @@ struct wlc_hw_info { d11regs_t *regs; /* pointer to device registers */ void *physhim; /* phy shim layer handler */ void *phy_sh; /* pointer to shared phy state */ - wlc_hwband_t *band; /* pointer to active per-band state */ - wlc_hwband_t *bandstate[MAXBANDS]; /* per-band state (one per phy/radio) */ + struct wlc_hwband *band;/* pointer to active per-band state */ + struct wlc_hwband *bandstate[MAXBANDS];/* band state per phy/radio */ u16 bmac_phytxant; /* cache of high phytxant state */ bool shortslot; /* currently using 11g ShortSlot timing */ u16 SRL; /* 802.11 dot11ShortRetryLimit */ @@ -478,11 +478,11 @@ struct wlc_hw_info { * if they belong to the same flow of traffic from the device. For multi-channel * operation there are independent TX Queues for each channel. */ -typedef struct wlc_txq_info { +struct wlc_txq_info { struct wlc_txq_info *next; struct pktq q; uint stopped; /* tx flow control bits */ -} wlc_txq_info_t; +}; /* * Principal common (os-independent) software data structure. @@ -634,7 +634,7 @@ struct wlc_info { bool bcmcfifo_drain; /* TX_BCMC_FIFO is set to drain */ /* tx queue */ - wlc_txq_info_t *tx_queues; /* common TX Queue list */ + struct wlc_txq_info *tx_queues; /* common TX Queue list */ /* security */ wsec_key_t *wsec_keys[WSEC_MAX_KEYS]; /* dynamic key storage */ @@ -642,8 +642,8 @@ struct wlc_info { bool wsec_swkeys; /* indicates that all keys should be * treated as sw keys (used for debugging) */ - modulecb_t *modulecb; - dumpcb_t *dumpcb_head; + struct modulecb *modulecb; + struct dumpcb_s *dumpcb_head; u8 mimoft; /* SIGN or 11N */ u8 mimo_band_bwcap; /* bw cap per band type */ @@ -710,12 +710,12 @@ struct wlc_info { bool ignore_bcns; /* override: ignore non shortslot bcns in a 11g network */ bool legacy_probe; /* restricts probe requests to CCK rates */ - wlc_protection_t *protection; + struct wlc_protection *protection; s8 PLCPHdr_override; /* 802.11b Preamble Type override */ - wlc_stf_t *stf; + struct wlc_stf *stf; - pkt_cb_t *pkt_callback; /* tx completion callback handlers */ + struct pkt_cb *pkt_callback; /* tx completion callback handlers */ u32 txretried; /* tx retried number in one msdu */ @@ -747,7 +747,9 @@ struct wlc_info { u16 next_bsscfg_ID; struct wlc_if *wlcif_list; /* linked list of wlc_if structs */ - wlc_txq_info_t *active_queue; /* txq for the currently active transmit context */ + struct wlc_txq_info *active_queue; /* txq for the currently active + * transmit context + */ u32 mpc_dur; /* total time (ms) in mpc mode except for the * portion since radio is turned off last time */ @@ -852,13 +854,14 @@ extern int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config); extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc); extern void wlc_mac_bcn_promisc(struct wlc_info *wlc); extern void wlc_mac_promisc(struct wlc_info *wlc); -extern void wlc_txflowcontrol(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, - int prio); -extern void wlc_txflowcontrol_override(struct wlc_info *wlc, wlc_txq_info_t *qi, +extern void wlc_txflowcontrol(struct wlc_info *wlc, struct wlc_txq_info *qi, + bool on, int prio); +extern void wlc_txflowcontrol_override(struct wlc_info *wlc, + struct wlc_txq_info *qi, bool on, uint override); extern bool wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, - wlc_txq_info_t *qi, int prio); -extern void wlc_send_q(struct wlc_info *wlc, wlc_txq_info_t *qi); + struct wlc_txq_info *qi, int prio); +extern void wlc_send_q(struct wlc_info *wlc, struct wlc_txq_info *qi); extern int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifo); extern u16 wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, @@ -958,6 +961,7 @@ extern bool wlc_ps_allowed(struct wlc_info *wlc); extern bool wlc_stay_awake(struct wlc_info *wlc); extern void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe); -extern void wlc_bss_list_free(struct wlc_info *wlc, wlc_bss_list_t *bss_list); +extern void wlc_bss_list_free(struct wlc_info *wlc, + struct wlc_bss_list *bss_list); extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode); #endif /* _wlc_h_ */ -- cgit v1.2.3 From 44bb83af01dcbfd3982af0f4ef4dec916ab04168 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Feb 2011 16:39:16 +0100 Subject: staging: brcm80211: remove typedef for struct wl_timer Typedefinitions for structures are considered affecting the code readability. This removes use of wl_timer_t which is typedef for struct wl_timer. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 26 ++++++++++++------------ drivers/staging/brcm80211/brcmsmac/wl_mac80211.h | 4 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 1b3f12ba5edb..ea4981e4e3fd 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -49,7 +49,7 @@ #include "wl_mac80211.h" static void wl_timer(unsigned long data); -static void _wl_timer(wl_timer_t *t); +static void _wl_timer(struct wl_timer *t); static int ieee_hw_init(struct ieee80211_hw *hw); @@ -1342,7 +1342,7 @@ module_exit(wl_module_exit); */ static void wl_free(struct wl_info *wl) { - wl_timer_t *t, *next; + struct wl_timer *t, *next; struct osl_info *osh; ASSERT(wl); @@ -1601,13 +1601,13 @@ static void BCMFASTPATH wl_dpc(unsigned long data) */ static void wl_timer(unsigned long data) { - _wl_timer((wl_timer_t *) data); + _wl_timer((struct wl_timer *) data); } /* * precondition: perimeter lock is not acquired */ -static void _wl_timer(wl_timer_t *t) +static void _wl_timer(struct wl_timer *t) { WL_LOCK(t->wl); @@ -1634,18 +1634,18 @@ static void _wl_timer(wl_timer_t *t) * * precondition: perimeter lock has been acquired */ -wl_timer_t *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg), void *arg, - const char *name) +struct wl_timer *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg), + void *arg, const char *name) { - wl_timer_t *t; + struct wl_timer *t; - t = kmalloc(sizeof(wl_timer_t), GFP_ATOMIC); + t = kmalloc(sizeof(struct wl_timer), GFP_ATOMIC); if (!t) { WL_ERROR("wl%d: wl_init_timer: out of memory\n", wl->pub->unit); return 0; } - memset(t, 0, sizeof(wl_timer_t)); + memset(t, 0, sizeof(struct wl_timer)); init_timer(&t->timer); t->timer.data = (unsigned long) t; @@ -1670,7 +1670,7 @@ wl_timer_t *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg), void *arg, * * precondition: perimeter lock has been acquired */ -void wl_add_timer(struct wl_info *wl, wl_timer_t *t, uint ms, int periodic) +void wl_add_timer(struct wl_info *wl, struct wl_timer *t, uint ms, int periodic) { #ifdef BCMDBG if (t->set) { @@ -1694,7 +1694,7 @@ void wl_add_timer(struct wl_info *wl, wl_timer_t *t, uint ms, int periodic) * * precondition: perimeter lock has been acquired */ -bool wl_del_timer(struct wl_info *wl, wl_timer_t *t) +bool wl_del_timer(struct wl_info *wl, struct wl_timer *t) { if (t->set) { t->set = false; @@ -1710,9 +1710,9 @@ bool wl_del_timer(struct wl_info *wl, wl_timer_t *t) /* * precondition: perimeter lock has been acquired */ -void wl_free_timer(struct wl_info *wl, wl_timer_t *t) +void wl_free_timer(struct wl_info *wl, struct wl_timer *t) { - wl_timer_t *tmp; + struct wl_timer *tmp; /* delete the timer in case it is active */ wl_del_timer(wl, t); diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h index f761fd14ee44..a4bed8bd629e 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h @@ -21,7 +21,7 @@ * sleep so perimeter lock has to be a semaphore instead of spinlock. This requires timers to be * submitted to workqueue instead of being on kernel timer */ -typedef struct wl_timer { +struct wl_timer { struct timer_list timer; struct wl_info *wl; void (*fn) (void *); @@ -33,7 +33,7 @@ typedef struct wl_timer { #ifdef BCMDBG char *name; /* Description of the timer */ #endif -} wl_timer_t; +}; struct wl_if { uint subunit; /* WDS/BSS unit */ -- cgit v1.2.3 From 70dfb584a70adae99ae597a3deb418a8311a0998 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Feb 2011 16:39:17 +0100 Subject: staging: brcm80211: remove include file proto/802.1d.h Aim to reduce the number of source and include files. This include file is not used anymore and can be removed. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 9 +++++- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 5 +-- drivers/staging/brcm80211/brcmsmac/wlc_alloc.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_antsel.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_channel.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 7 ++++- drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_rate.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_stf.c | 1 - drivers/staging/brcm80211/include/bcmdefs.h | 14 +++++++++ drivers/staging/brcm80211/include/proto/802.1d.h | 37 ----------------------- drivers/staging/brcm80211/util/bcmutils.c | 1 - 14 files changed, 31 insertions(+), 50 deletions(-) delete mode 100644 drivers/staging/brcm80211/include/proto/802.1d.h (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 097844f8569a..4c10fd6e447f 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -43,7 +43,6 @@ #include #include -#include #include #include @@ -143,6 +142,14 @@ */ #define PKTFREE2() if ((bus->bus != SPI_BUS) || bus->usebufpool) \ pkt_buf_free_skb(bus->dhd->osh, pkt, false); + +/* + * Conversion of 802.1D priority to precedence level + */ +#define PRIO2PREC(prio) \ + (((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? \ + ((prio^2)) : (prio)) + DHD_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep); extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len); diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index ea4981e4e3fd..b57c3a004612 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -26,9 +26,10 @@ #include #include -#include -#include +#include #include +#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c index 8e4908b3ecf3..ff5516946ae1 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index a6572db522b4..ea6bb85d2c4b 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c index a5f2508367e8..ec99420c9b95 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c @@ -22,7 +22,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index f450c55735a0..b55ab25b1ed2 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -22,7 +22,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c index edfc392d75ab..c89ce5fede24 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index 4ae75a344592..c7f0630f0202 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -18,7 +18,6 @@ #include #include -#include #include #include #include @@ -71,6 +70,12 @@ #define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS #define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS +/* + * Indication for txflowcontrol that all priority bits in + * TXQ_STOP_FOR_PRIOFC_MASK are to be considered. + */ +#define ALLPRIO -1 + /* * buffer length needed for wlc_format_ssid * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c index ff595ab11739..0b25bd767d53 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c @@ -26,7 +26,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c index a8e30016a655..e22ff84ba678 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c @@ -17,7 +17,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c index 6574fb4d6937..2d98f0d69a92 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c @@ -18,7 +18,6 @@ #include #include -#include #include #include diff --git a/drivers/staging/brcm80211/include/bcmdefs.h b/drivers/staging/brcm80211/include/bcmdefs.h index 74601fc971c9..601ec706878c 100644 --- a/drivers/staging/brcm80211/include/bcmdefs.h +++ b/drivers/staging/brcm80211/include/bcmdefs.h @@ -138,6 +138,20 @@ typedef struct { (((val) & (~(field ## _M << field ## _S))) | \ ((unsigned)(bits) << field ## _S)) +/* + * Priority definitions according 802.1D + */ +#define PRIO_8021D_NONE 2 +#define PRIO_8021D_BK 1 +#define PRIO_8021D_BE 0 +#define PRIO_8021D_EE 3 +#define PRIO_8021D_CL 4 +#define PRIO_8021D_VI 5 +#define PRIO_8021D_VO 6 +#define PRIO_8021D_NC 7 +#define MAXPRIO 7 +#define NUMPRIO (MAXPRIO + 1) + /* Max. nvram variable table size */ #define MAXSZ_NVRAM_VARS 4096 diff --git a/drivers/staging/brcm80211/include/proto/802.1d.h b/drivers/staging/brcm80211/include/proto/802.1d.h deleted file mode 100644 index 9802d8776628..000000000000 --- a/drivers/staging/brcm80211/include/proto/802.1d.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _802_1_D_ -#define _802_1_D_ - -#define PRIO_8021D_NONE 2 -#define PRIO_8021D_BK 1 -#define PRIO_8021D_BE 0 -#define PRIO_8021D_EE 3 -#define PRIO_8021D_CL 4 -#define PRIO_8021D_VI 5 -#define PRIO_8021D_VO 6 -#define PRIO_8021D_NC 7 -#define MAXPRIO 7 -#define NUMPRIO (MAXPRIO + 1) - -#define ALLPRIO -1 - -#define PRIO2PREC(prio) \ - (((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? \ - ((prio^2)) : (prio)) - -#endif /* _802_1_D_ */ diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index 696220edb0bc..670cde1421a3 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -27,7 +27,6 @@ #include #include #include -#include #include struct sk_buff *BCMFASTPATH pkt_buf_get_skb(struct osl_info *osh, uint len) -- cgit v1.2.3 From 8a0939f500aac72e3bc47147c66c2575160a43ca Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Feb 2011 16:39:18 +0100 Subject: staging: brcm80211: remove include file sbhndpio.h All source files including sbhndpio.h were needing it only because they needed d11.h and it had a dependency. The content of sbhndpio.h has been merged in d11.h. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/d11.h | 31 +++++++++++++ .../staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c | 1 - .../staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c | 1 - drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c | 1 - .../brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c | 1 - .../staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c | 1 - drivers/staging/brcm80211/brcmsmac/sbhndpio.h | 52 ---------------------- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 5 ++- drivers/staging/brcm80211/brcmsmac/wlc_alloc.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_antsel.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_channel.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_rate.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_stf.c | 1 - 17 files changed, 34 insertions(+), 68 deletions(-) delete mode 100644 drivers/staging/brcm80211/brcmsmac/sbhndpio.h (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/d11.h b/drivers/staging/brcm80211/brcmsmac/d11.h index 80a8489b8548..a9d182f49023 100644 --- a/drivers/staging/brcm80211/brcmsmac/d11.h +++ b/drivers/staging/brcm80211/brcmsmac/d11.h @@ -59,6 +59,37 @@ typedef volatile struct { u32 intmask; } intctrlregs_t; +/* PIO structure, + * support two PIO format: 2 bytes access and 4 bytes access + * basic FIFO register set is per channel(transmit or receive) + * a pair of channels is defined for convenience + */ +/* 2byte-wide pio register set per channel(xmt or rcv) */ +typedef volatile struct { + u16 fifocontrol; + u16 fifodata; + u16 fifofree; /* only valid in xmt channel, not in rcv channel */ + u16 PAD; +} pio2regs_t; + +/* a pair of pio channels(tx and rx) */ +typedef volatile struct { + pio2regs_t tx; + pio2regs_t rx; +} pio2regp_t; + +/* 4byte-wide pio register set per channel(xmt or rcv) */ +typedef volatile struct { + u32 fifocontrol; + u32 fifodata; +} pio4regs_t; + +/* a pair of pio channels(tx and rx) */ +typedef volatile struct { + pio4regs_t tx; + pio4regs_t rx; +} pio4regp_t; + /* read: 32-bit register that can be read as 32-bit or as 2 16-bit * write: only low 16b-it half can be written */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c index 2f80da7f0d0f..151c9b262766 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c index f027d5076c7d..36dea14b7d7f 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c @@ -26,7 +26,6 @@ #include #include -#include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c index 23b6086aa74d..af8291f1bc0f 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c @@ -26,7 +26,6 @@ #include #include -#include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c index 330b88152b65..e962902d7228 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c @@ -15,7 +15,6 @@ */ #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c index a9fc193721ef..3dbce71f83ab 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c @@ -16,7 +16,6 @@ #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/sbhndpio.h b/drivers/staging/brcm80211/brcmsmac/sbhndpio.h deleted file mode 100644 index 9eabdb56da73..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/sbhndpio.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _sbhndpio_h_ -#define _sbhndpio_h_ - -/* PIO structure, - * support two PIO format: 2 bytes access and 4 bytes access - * basic FIFO register set is per channel(transmit or receive) - * a pair of channels is defined for convenience - */ - -/* 2byte-wide pio register set per channel(xmt or rcv) */ -typedef volatile struct { - u16 fifocontrol; - u16 fifodata; - u16 fifofree; /* only valid in xmt channel, not in rcv channel */ - u16 PAD; -} pio2regs_t; - -/* a pair of pio channels(tx and rx) */ -typedef volatile struct { - pio2regs_t tx; - pio2regs_t rx; -} pio2regp_t; - -/* 4byte-wide pio register set per channel(xmt or rcv) */ -typedef volatile struct { - u32 fifocontrol; - u32 fifodata; -} pio4regs_t; - -/* a pair of pio channels(tx and rx) */ -typedef volatile struct { - pio4regs_t tx; - pio4regs_t rx; -} pio4regp_t; - -#endif /* _sbhndpio_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index b57c3a004612..137a382bac52 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -35,11 +35,12 @@ #include #include +#include "phy/wlc_phy_int.h" +#include "d11.h" +#include "wlc_types.h" #include "wlc_cfg.h" #include "phy/phy_version.h" #include "wlc_key.h" -#include "sbhndpio.h" -#include "phy/wlc_phy_hal.h" #include "wlc_channel.h" #include "wlc_scb.h" #include "wlc_pub.h" diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c index ff5516946ae1..dc06b1ac11f9 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c @@ -23,7 +23,6 @@ #include #include -#include "sbhndpio.h" #include "d11.h" #include "wlc_types.h" #include "wlc_cfg.h" diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index ea6bb85d2c4b..d438d9a2a3c3 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c index ec99420c9b95..3e453899db31 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c @@ -30,7 +30,6 @@ #include #include -#include "sbhndpio.h" #include "d11.h" #include "wlc_rate.h" #include "wlc_key.h" diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index b55ab25b1ed2..4a7346f0f918 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -39,7 +39,6 @@ #include #include "wlc_types.h" -#include "sbhndpio.h" #include "d11.h" #include "wlc_cfg.h" #include "wlc_rate.h" diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c index c89ce5fede24..8e2a3848496c 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c @@ -27,7 +27,6 @@ #include #include "wlc_types.h" -#include "sbhndpio.h" #include "d11.h" #include "wlc_cfg.h" #include "wlc_scb.h" diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index c7f0630f0202..29d9dee38f8a 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -31,7 +31,6 @@ #include #include -#include "sbhndpio.h" #include "d11.h" #include "wlc_types.h" #include "wlc_cfg.h" diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c index 0b25bd767d53..fa3f73ffff17 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c @@ -41,7 +41,6 @@ #include "wlc_types.h" #include "wl_dbg.h" -#include "sbhndpio.h" #include "wlc_cfg.h" #include "d11.h" #include "wlc_rate.h" diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c index e22ff84ba678..863f18f86ece 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c @@ -25,7 +25,6 @@ #include #include "wlc_types.h" -#include "sbhndpio.h" #include "d11.h" #include "wl_dbg.h" #include "wlc_cfg.h" diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c index 2d98f0d69a92..25fbcdac4f77 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c @@ -28,7 +28,6 @@ #include #include "wlc_types.h" -#include "sbhndpio.h" #include "d11.h" #include "wl_dbg.h" #include "wlc_cfg.h" -- cgit v1.2.3 From 16d691b60ea94be876cc12a62faa839803184a5e Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Feb 2011 16:39:19 +0100 Subject: staging: brcm80211: remove include file d11ucode_ext.h Include file required by wl_ucode.h only so merged content of d11ucode_ext.h into that include file to reduce number of include files in the driver. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/d11ucode_ext.h | 35 -------------------- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 1 - drivers/staging/brcm80211/brcmsmac/wl_ucode.h | 26 +++++++-------- .../staging/brcm80211/brcmsmac/wl_ucode_loader.c | 38 +++++++++++++++------- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 7 ++-- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 1 - 6 files changed, 44 insertions(+), 64 deletions(-) delete mode 100644 drivers/staging/brcm80211/brcmsmac/d11ucode_ext.h (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/d11ucode_ext.h b/drivers/staging/brcm80211/brcmsmac/d11ucode_ext.h deleted file mode 100644 index c0c0d661e00e..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/d11ucode_ext.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -enum { - D11UCODE_NAMETAG_START = 0, - D11LCN0BSINITVALS24, - D11LCN0INITVALS24, - D11LCN1BSINITVALS24, - D11LCN1INITVALS24, - D11LCN2BSINITVALS24, - D11LCN2INITVALS24, - D11N0ABSINITVALS16, - D11N0BSINITVALS16, - D11N0INITVALS16, - D11UCODE_OVERSIGHT16_MIMO, - D11UCODE_OVERSIGHT16_MIMOSZ, - D11UCODE_OVERSIGHT24_LCN, - D11UCODE_OVERSIGHT24_LCNSZ, - D11UCODE_OVERSIGHT_BOMMAJOR, - D11UCODE_OVERSIGHT_BOMMINOR -}; -#define UCODE_LOADER_API_VER 0 diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 137a382bac52..de245ac38c7b 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -47,7 +47,6 @@ #include "wl_dbg.h" #include "wl_export.h" #include "wl_ucode.h" -#include "d11ucode_ext.h" #include "wl_mac80211.h" static void wl_timer(unsigned long data); diff --git a/drivers/staging/brcm80211/brcmsmac/wl_ucode.h b/drivers/staging/brcm80211/brcmsmac/wl_ucode.h index 2a0f4028f6f3..6933fda0e6a0 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_ucode.h +++ b/drivers/staging/brcm80211/brcmsmac/wl_ucode.h @@ -17,27 +17,27 @@ #define MIN_FW_SIZE 40000 /* minimum firmware file size in bytes */ #define MAX_FW_SIZE 150000 -typedef struct d11init { +#define UCODE_LOADER_API_VER 0 + +struct d11init { u16 addr; u16 size; u32 value; -} d11init_t; +}; -extern d11init_t *d11lcn0bsinitvals24; -extern d11init_t *d11lcn0initvals24; -extern d11init_t *d11lcn1bsinitvals24; -extern d11init_t *d11lcn1initvals24; -extern d11init_t *d11lcn2bsinitvals24; -extern d11init_t *d11lcn2initvals24; -extern d11init_t *d11n0absinitvals16; -extern d11init_t *d11n0bsinitvals16; -extern d11init_t *d11n0initvals16; +extern struct d11init *d11lcn0bsinitvals24; +extern struct d11init *d11lcn0initvals24; +extern struct d11init *d11lcn1bsinitvals24; +extern struct d11init *d11lcn1initvals24; +extern struct d11init *d11lcn2bsinitvals24; +extern struct d11init *d11lcn2initvals24; +extern struct d11init *d11n0absinitvals16; +extern struct d11init *d11n0bsinitvals16; +extern struct d11init *d11n0initvals16; extern u32 *bcm43xx_16_mimo; extern u32 bcm43xx_16_mimosz; extern u32 *bcm43xx_24_lcn; extern u32 bcm43xx_24_lcnsz; -extern u32 *bcm43xx_bommajor; -extern u32 *bcm43xx_bomminor; extern int wl_ucode_data_init(struct wl_info *wl); extern void wl_ucode_data_free(void); diff --git a/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c b/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c index c84e6a70e71d..cc00dd19746b 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c @@ -16,20 +16,36 @@ #include #include -#include #include +enum { + D11UCODE_NAMETAG_START = 0, + D11LCN0BSINITVALS24, + D11LCN0INITVALS24, + D11LCN1BSINITVALS24, + D11LCN1INITVALS24, + D11LCN2BSINITVALS24, + D11LCN2INITVALS24, + D11N0ABSINITVALS16, + D11N0BSINITVALS16, + D11N0INITVALS16, + D11UCODE_OVERSIGHT16_MIMO, + D11UCODE_OVERSIGHT16_MIMOSZ, + D11UCODE_OVERSIGHT24_LCN, + D11UCODE_OVERSIGHT24_LCNSZ, + D11UCODE_OVERSIGHT_BOMMAJOR, + D11UCODE_OVERSIGHT_BOMMINOR +}; - -d11init_t *d11lcn0bsinitvals24; -d11init_t *d11lcn0initvals24; -d11init_t *d11lcn1bsinitvals24; -d11init_t *d11lcn1initvals24; -d11init_t *d11lcn2bsinitvals24; -d11init_t *d11lcn2initvals24; -d11init_t *d11n0absinitvals16; -d11init_t *d11n0bsinitvals16; -d11init_t *d11n0initvals16; +struct d11init *d11lcn0bsinitvals24; +struct d11init *d11lcn0initvals24; +struct d11init *d11lcn1bsinitvals24; +struct d11init *d11lcn1initvals24; +struct d11init *d11lcn2bsinitvals24; +struct d11init *d11lcn2initvals24; +struct d11init *d11n0absinitvals16; +struct d11init *d11n0bsinitvals16; +struct d11init *d11n0initvals16; u32 *bcm43xx_16_mimo; u32 bcm43xx_16_mimosz; u32 *bcm43xx_24_lcn; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 4a7346f0f918..3eb7a4a659cd 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -52,7 +52,6 @@ #include "wlc_mac80211.h" #include "wl_export.h" #include "wl_ucode.h" -#include "d11ucode_ext.h" #include "wlc_antsel.h" #include "pcie_core.h" #include "wlc_alloc.h" @@ -103,7 +102,8 @@ static void wlc_clkctl_clk(struct wlc_hw_info *wlc, uint mode); static void wlc_coreinit(struct wlc_info *wlc); /* used by wlc_wakeucode_init() */ -static void wlc_write_inits(struct wlc_hw_info *wlc_hw, const d11init_t *inits); +static void wlc_write_inits(struct wlc_hw_info *wlc_hw, + const struct d11init *inits); static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[], const uint nbytes); static void wlc_ucode_download(struct wlc_hw_info *wlc); @@ -2672,7 +2672,8 @@ static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[], W_REG(osh, ®s->objdata, ucode[i]); } -static void wlc_write_inits(struct wlc_hw_info *wlc_hw, const d11init_t *inits) +static void wlc_write_inits(struct wlc_hw_info *wlc_hw, + const struct d11init *inits) { int i; struct osl_info *osh; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index 29d9dee38f8a..fb88890d0423 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -49,7 +49,6 @@ #include "wlc_stf.h" #include "wlc_ampdu.h" #include "wl_export.h" -#include "d11ucode_ext.h" #include "wlc_alloc.h" #include "wl_dbg.h" -- cgit v1.2.3 From 61044c4cef8b0380e8ec4b06eff24884e4c7d9b9 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Feb 2011 16:39:20 +0100 Subject: staging: brcm80211: remove checks for ANTSEL related compiler definitions The source module antsel is always included in the current driver so any checks for it being compiled in are redundant and have been removed. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 3 +- drivers/staging/brcm80211/brcmsmac/wlc_antsel.c | 4 -- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 64 +++++++++++------------ drivers/staging/brcm80211/brcmsmac/wlc_cfg.h | 6 --- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 25 ++++----- 5 files changed, 42 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index d438d9a2a3c3..7aaa958a738d 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -1178,8 +1178,7 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, wlc_send_q(wlc, wlc->active_queue); /* update rate state */ - if (WLANTSEL_ENAB(wlc)) - antselid = wlc_antsel_antsel2id(wlc->asi, mimoantsel); + antselid = wlc_antsel_antsel2id(wlc->asi, mimoantsel); wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight); } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c index 3e453899db31..8c59898a418b 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c @@ -16,8 +16,6 @@ #include -#ifdef WLANTSEL - #include #include #include @@ -327,5 +325,3 @@ static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel) return 0; } - -#endif /* WLANTSEL */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 3eb7a4a659cd..1a49c6e52e41 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -2582,39 +2582,39 @@ static void wlc_gpio_init(struct wlc_info *wlc) gc = gm = 0; /* Allocate GPIOs for mimo antenna diversity feature */ - if (WLANTSEL_ENAB(wlc)) { - if (wlc_hw->antsel_type == ANTSEL_2x3) { - /* Enable antenna diversity, use 2x3 mode */ - wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, - MHF3_ANTSEL_EN, WLC_BAND_ALL); - wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, - MHF3_ANTSEL_MODE, WLC_BAND_ALL); - - /* init superswitch control */ - wlc_phy_antsel_init(wlc_hw->band->pi, false); - - } else if (wlc_hw->antsel_type == ANTSEL_2x4) { - ASSERT((gm & BOARD_GPIO_12) == 0); - gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13); - /* The board itself is powered by these GPIOs (when not sending pattern) - * So set them high - */ - OR_REG(osh, ®s->psm_gpio_oe, - (BOARD_GPIO_12 | BOARD_GPIO_13)); - OR_REG(osh, ®s->psm_gpio_out, - (BOARD_GPIO_12 | BOARD_GPIO_13)); - - /* Enable antenna diversity, use 2x4 mode */ - wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, - MHF3_ANTSEL_EN, WLC_BAND_ALL); - wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0, - WLC_BAND_ALL); - - /* Configure the desired clock to be 4Mhz */ - wlc_bmac_write_shm(wlc_hw, M_ANTSEL_CLKDIV, - ANTSEL_CLKDIV_4MHZ); - } + if (wlc_hw->antsel_type == ANTSEL_2x3) { + /* Enable antenna diversity, use 2x3 mode */ + wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, + MHF3_ANTSEL_EN, WLC_BAND_ALL); + wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, + MHF3_ANTSEL_MODE, WLC_BAND_ALL); + + /* init superswitch control */ + wlc_phy_antsel_init(wlc_hw->band->pi, false); + + } else if (wlc_hw->antsel_type == ANTSEL_2x4) { + ASSERT((gm & BOARD_GPIO_12) == 0); + gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13); + /* + * The board itself is powered by these GPIOs + * (when not sending pattern) so set them high + */ + OR_REG(osh, ®s->psm_gpio_oe, + (BOARD_GPIO_12 | BOARD_GPIO_13)); + OR_REG(osh, ®s->psm_gpio_out, + (BOARD_GPIO_12 | BOARD_GPIO_13)); + + /* Enable antenna diversity, use 2x4 mode */ + wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, + MHF3_ANTSEL_EN, WLC_BAND_ALL); + wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0, + WLC_BAND_ALL); + + /* Configure the desired clock to be 4Mhz */ + wlc_bmac_write_shm(wlc_hw, M_ANTSEL_CLKDIV, + ANTSEL_CLKDIV_4MHZ); } + /* gpio 9 controls the PA. ucode is responsible for wiggling out and oe */ if (wlc_hw->boardflags & BFL_PACTRL) gm |= gc |= BOARD_GPIO_PACTRL; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_cfg.h b/drivers/staging/brcm80211/brcmsmac/wlc_cfg.h index 3decb7d1a5e5..85fbd0635310 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_cfg.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_cfg.h @@ -69,10 +69,6 @@ #define SSLPNCONF SSLPNPHY_DEFAULT #endif -#define BAND2G -#define BAND5G -#define WLANTSEL 1 - /******************************************************************** * Phy/Core Configuration. Defines macros to to check core phy/rev * * compile-time configuration. Defines default core support. * @@ -281,6 +277,4 @@ #define WLBANDINITDATA(_data) _data #define WLBANDINITFN(_fn) _fn -#define WLANTSEL_ENAB(wlc) 1 - #endif /* _wlc_cfg_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index fb88890d0423..628019862f58 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -861,8 +861,7 @@ void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec) /* init antenna selection */ if (CHSPEC_WLC_BW(old_chanspec) != CHSPEC_WLC_BW(chanspec)) { - if (WLANTSEL_ENAB(wlc)) - wlc_antsel_init(wlc->asi); + wlc_antsel_init(wlc->asi); /* Fix the hardware rateset based on bw. * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz @@ -1308,8 +1307,7 @@ static void WLBANDINITFN(wlc_bsinit) (struct wlc_info *wlc) wlc_ucode_mac_upd(wlc); /* init antenna selection */ - if (WLANTSEL_ENAB(wlc)) - wlc_antsel_init(wlc->asi); + wlc_antsel_init(wlc->asi); } @@ -2003,15 +2001,13 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, /* initialize radio_mpc_disable according to wlc->mpc */ wlc_radio_mpc_upd(wlc); - if (WLANTSEL_ENAB(wlc)) { - if ((wlc->pub->sih->chip) == BCM43235_CHIP_ID) { - if ((getintvar(wlc->pub->vars, "aa2g") == 7) || - (getintvar(wlc->pub->vars, "aa5g") == 7)) { - wlc_bmac_antsel_set(wlc->hw, 1); - } - } else { - wlc_bmac_antsel_set(wlc->hw, wlc->asi->antsel_avail); + if ((wlc->pub->sih->chip) == BCM43235_CHIP_ID) { + if ((getintvar(wlc->pub->vars, "aa2g") == 7) || + (getintvar(wlc->pub->vars, "aa5g") == 7)) { + wlc_bmac_antsel_set(wlc->hw, 1); } + } else { + wlc_bmac_antsel_set(wlc->hw, wlc->asi->antsel_avail); } if (perr) @@ -5753,11 +5749,9 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, u32 rate_val[2]; bool hwtkmic = false; u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; -#ifdef WLANTSEL #define ANTCFG_NONE 0xFF u8 antcfg = ANTCFG_NONE; u8 fbantcfg = ANTCFG_NONE; -#endif uint phyctl1_stf = 0; u16 durid = 0; struct ieee80211_tx_rate *txrate[2]; @@ -5891,8 +5885,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, ASSERT(RSPEC_ACTIVE(rspec[k])); rspec[k] = WLC_RATE_1M; } else { - if (WLANTSEL_ENAB(wlc) && - !is_multicast_ether_addr(h->addr1)) { + if (!is_multicast_ether_addr(h->addr1)) { /* set tx antenna config */ wlc_antsel_antcfg_get(wlc->asi, false, false, 0, 0, &antcfg, &fbantcfg); -- cgit v1.2.3 From d6075c9c0ca52cc560f6a5be27c361aaa15603c6 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Feb 2011 16:39:21 +0100 Subject: staging: brcm80211: remove osl handle from pkttotlen function The function pkttotlen was part of osl function and as such was called with struct osl_info parameter although not used within the function. As part of remove the whole osl concept from the drivers this parameter has been removed from the function prototype. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 4 ++-- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 6 +++--- drivers/staging/brcm80211/include/bcmutils.h | 2 +- drivers/staging/brcm80211/util/bcmutils.c | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 4c10fd6e447f..67f6127498bd 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -3309,7 +3309,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) } pfirst = bus->glom; - dlen = (u16) pkttotlen(osh, pfirst); + dlen = (u16) pkttotlen(pfirst); /* Do an SDIO read for the superframe. Configurable iovar to * read directly into the chained packet, or allocate a large diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index 7aaa958a738d..eff174d0827b 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -658,7 +658,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, len = roundup(len, 4); ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN); - dma_len += (u16) pkttotlen(osh, p); + dma_len += (u16) pkttotlen(p); WL_AMPDU_TX("wl%d: wlc_sendampdu: ampdu_len %d seg_cnt %d null delim %d\n", wlc->pub->unit, ampdu_len, seg_cnt, ndelim); @@ -755,7 +755,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, ((u8) (p->priority) == tid)) { plen = - pkttotlen(osh, p) + AMPDU_MAX_MPDU_OVERHEAD; + pkttotlen(p) + AMPDU_MAX_MPDU_OVERHEAD; plen = max(scb_ampdu->min_len, plen); if ((plen + ampdu_len) > maxlen) { diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index 628019862f58..a857fccdb530 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -5125,7 +5125,7 @@ wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, tx_failed[WME_PRIO2AC(p->priority)].packets); WLCNTADD(wlc->pub->_wme_cnt-> tx_failed[WME_PRIO2AC(p->priority)].bytes, - pkttotlen(wlc->osh, p)); + pkttotlen(p)); } pkt_buf_free_skb(wlc->osh, p, true); wlc->pub->_cnt->txnobuf++; @@ -5776,7 +5776,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, FC_SUBTYPE_ANY_QOS(fc)); /* compute length of frame in bytes for use in PLCP computations */ - len = pkttotlen(osh, p); + len = pkttotlen(p); phylen = len + FCS_LEN; /* If WEP enabled, add room in phylen for the additional bytes of @@ -6702,7 +6702,7 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) tx_info->flags |= IEEE80211_TX_STAT_ACK; } - totlen = pkttotlen(osh, p); + totlen = pkttotlen(p); free_pdu = true; wlc_txfifo_complete(wlc, queue, 1); diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h index a3d3f66b3638..3a125b124114 100644 --- a/drivers/staging/brcm80211/include/bcmutils.h +++ b/drivers/staging/brcm80211/include/bcmutils.h @@ -142,7 +142,7 @@ extern struct sk_buff *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); /* packet */ extern uint pktfrombuf(struct osl_info *osh, struct sk_buff *p, uint offset, int len, unsigned char *buf); - extern uint pkttotlen(struct osl_info *osh, struct sk_buff *p); + extern uint pkttotlen(struct sk_buff *p); /* ethernet address */ extern int bcm_ether_atoe(char *p, u8 *ea); diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index 670cde1421a3..2073762f425d 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -104,7 +104,7 @@ uint pktfrombuf(struct osl_info *osh, struct sk_buff *p, uint offset, int len, return ret; } /* return total length of buffer chain */ -uint BCMFASTPATH pkttotlen(struct osl_info *osh, struct sk_buff *p) +uint BCMFASTPATH pkttotlen(struct sk_buff *p) { uint total; -- cgit v1.2.3 From 6cab915077bc3b54316ddf1e9c047df56eff556e Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Feb 2011 16:39:22 +0100 Subject: staging: brcm80211: remove struct osl_info parameter from wlc_alloc The functions within wlc_alloc had parameter of struct osl_info type but it was never used. As part of osl concept removal this parameter has been removed from the function prototypes. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_alloc.c | 76 +++++++++++------------ drivers/staging/brcm80211/brcmsmac/wlc_alloc.h | 7 +-- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 6 +- 3 files changed, 43 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c index dc06b1ac11f9..8d6e0ea5d046 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c @@ -37,14 +37,14 @@ #include "wlc_channel.h" #include "wlc_mac80211.h" -static struct wlc_bsscfg *wlc_bsscfg_malloc(struct osl_info *osh, uint unit); -static void wlc_bsscfg_mfree(struct osl_info *osh, struct wlc_bsscfg *cfg); -static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, +static struct wlc_bsscfg *wlc_bsscfg_malloc(uint unit); +static void wlc_bsscfg_mfree(struct wlc_bsscfg *cfg); +static struct wlc_pub *wlc_pub_malloc(uint unit, uint *err, uint devid); -static void wlc_pub_mfree(struct osl_info *osh, struct wlc_pub *pub); +static void wlc_pub_mfree(struct wlc_pub *pub); static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid); -void *wlc_calloc(struct osl_info *osh, uint unit, uint size) +void *wlc_calloc(uint unit, uint size) { void *item; @@ -72,18 +72,17 @@ void wlc_tunables_init(wlc_tunables_t *tunables, uint devid) tunables->txsbnd = TXSBND; } -static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, - uint *err, uint devid) +static struct wlc_pub *wlc_pub_malloc(uint unit, uint *err, uint devid) { struct wlc_pub *pub; - pub = wlc_calloc(osh, unit, sizeof(struct wlc_pub)); + pub = wlc_calloc(unit, sizeof(struct wlc_pub)); if (pub == NULL) { *err = 1001; goto fail; } - pub->tunables = wlc_calloc(osh, unit, + pub->tunables = wlc_calloc(unit, sizeof(wlc_tunables_t)); if (pub->tunables == NULL) { *err = 1028; @@ -93,11 +92,11 @@ static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, /* need to init the tunables now */ wlc_tunables_init(pub->tunables, devid); - pub->_cnt = wlc_calloc(osh, unit, sizeof(struct wl_cnt)); + pub->_cnt = wlc_calloc(unit, sizeof(struct wl_cnt)); if (pub->_cnt == NULL) goto fail; - pub->multicast = (u8 *)wlc_calloc(osh, unit, + pub->multicast = (u8 *)wlc_calloc(unit, (ETH_ALEN * MAXMULTILIST)); if (pub->multicast == NULL) { *err = 1003; @@ -107,11 +106,11 @@ static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, return pub; fail: - wlc_pub_mfree(osh, pub); + wlc_pub_mfree(pub); return NULL; } -static void wlc_pub_mfree(struct osl_info *osh, struct wlc_pub *pub) +static void wlc_pub_mfree(struct wlc_pub *pub) { if (pub == NULL) return; @@ -122,15 +121,15 @@ static void wlc_pub_mfree(struct osl_info *osh, struct wlc_pub *pub) kfree(pub); } -static wlc_bsscfg_t *wlc_bsscfg_malloc(struct osl_info *osh, uint unit) +static wlc_bsscfg_t *wlc_bsscfg_malloc(uint unit) { wlc_bsscfg_t *cfg; - cfg = (wlc_bsscfg_t *) wlc_calloc(osh, unit, sizeof(wlc_bsscfg_t)); + cfg = (wlc_bsscfg_t *) wlc_calloc(unit, sizeof(wlc_bsscfg_t)); if (cfg == NULL) goto fail; - cfg->current_bss = (wlc_bss_info_t *)wlc_calloc(osh, unit, + cfg->current_bss = (wlc_bss_info_t *)wlc_calloc(unit, sizeof(wlc_bss_info_t)); if (cfg->current_bss == NULL) goto fail; @@ -138,11 +137,11 @@ static wlc_bsscfg_t *wlc_bsscfg_malloc(struct osl_info *osh, uint unit) return cfg; fail: - wlc_bsscfg_mfree(osh, cfg); + wlc_bsscfg_mfree(cfg); return NULL; } -static void wlc_bsscfg_mfree(struct osl_info *osh, wlc_bsscfg_t *cfg) +static void wlc_bsscfg_mfree(wlc_bsscfg_t *cfg) { if (cfg == NULL) return; @@ -170,13 +169,11 @@ void wlc_bsscfg_ID_assign(struct wlc_info *wlc, wlc_bsscfg_t *bsscfg) /* * The common driver entry routine. Error codes should be unique */ -struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, - uint devid) +struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid) { struct wlc_info *wlc; - wlc = (struct wlc_info *) wlc_calloc(osh, unit, - sizeof(struct wlc_info)); + wlc = (struct wlc_info *) wlc_calloc(unit, sizeof(struct wlc_info)); if (wlc == NULL) { *err = 1002; goto fail; @@ -185,7 +182,7 @@ struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, wlc->hwrxoff = WL_HWRXOFF; /* allocate struct wlc_pub state structure */ - wlc->pub = wlc_pub_malloc(osh, unit, err, devid); + wlc->pub = wlc_pub_malloc(unit, err, devid); if (wlc->pub == NULL) { *err = 1003; goto fail; @@ -194,15 +191,15 @@ struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, /* allocate struct wlc_hw_info state structure */ - wlc->hw = (struct wlc_hw_info *)wlc_calloc(osh, unit, - sizeof(struct wlc_hw_info)); + wlc->hw = (struct wlc_hw_info *)wlc_calloc(unit, + sizeof(struct wlc_hw_info)); if (wlc->hw == NULL) { *err = 1005; goto fail; } wlc->hw->wlc = wlc; - wlc->hw->bandstate[0] = wlc_calloc(osh, unit, + wlc->hw->bandstate[0] = wlc_calloc(unit, (sizeof(struct wlc_hwband) * MAXBANDS)); if (wlc->hw->bandstate[0] == NULL) { *err = 1006; @@ -217,35 +214,35 @@ struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, } } - wlc->modulecb = wlc_calloc(osh, unit, + wlc->modulecb = wlc_calloc(unit, sizeof(struct modulecb) * WLC_MAXMODULES); if (wlc->modulecb == NULL) { *err = 1009; goto fail; } - wlc->default_bss = (wlc_bss_info_t *)wlc_calloc(osh, unit, + wlc->default_bss = (wlc_bss_info_t *)wlc_calloc(unit, sizeof(wlc_bss_info_t)); if (wlc->default_bss == NULL) { *err = 1010; goto fail; } - wlc->cfg = wlc_bsscfg_malloc(osh, unit); + wlc->cfg = wlc_bsscfg_malloc(unit); if (wlc->cfg == NULL) { *err = 1011; goto fail; } wlc_bsscfg_ID_assign(wlc, wlc->cfg); - wlc->pkt_callback = wlc_calloc(osh, unit, + wlc->pkt_callback = wlc_calloc(unit, (sizeof(struct pkt_cb) * (wlc->pub->tunables->maxpktcb + 1))); if (wlc->pkt_callback == NULL) { *err = 1013; goto fail; } - wlc->wsec_def_keys[0] = (wsec_key_t *)wlc_calloc(osh, unit, + wlc->wsec_def_keys[0] = (wsec_key_t *)wlc_calloc(unit, (sizeof(wsec_key_t) * WLC_DEFAULT_KEYS)); if (wlc->wsec_def_keys[0] == NULL) { *err = 1015; @@ -259,20 +256,20 @@ struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, } } - wlc->protection = wlc_calloc(osh, unit, + wlc->protection = wlc_calloc(unit, sizeof(struct wlc_protection)); if (wlc->protection == NULL) { *err = 1016; goto fail; } - wlc->stf = wlc_calloc(osh, unit, sizeof(struct wlc_stf)); + wlc->stf = wlc_calloc(unit, sizeof(struct wlc_stf)); if (wlc->stf == NULL) { *err = 1017; goto fail; } - wlc->bandstate[0] = (struct wlcband *)wlc_calloc(osh, unit, + wlc->bandstate[0] = (struct wlcband *)wlc_calloc(unit, (sizeof(struct wlcband)*MAXBANDS)); if (wlc->bandstate[0] == NULL) { *err = 1025; @@ -287,7 +284,7 @@ struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, } } - wlc->corestate = (struct wlccore *)wlc_calloc(osh, unit, + wlc->corestate = (struct wlccore *)wlc_calloc(unit, sizeof(struct wlccore)); if (wlc->corestate == NULL) { *err = 1026; @@ -295,7 +292,7 @@ struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, } wlc->corestate->macstat_snapshot = - (macstat_t *)wlc_calloc(osh, unit, sizeof(macstat_t)); + (macstat_t *)wlc_calloc(unit, sizeof(macstat_t)); if (wlc->corestate->macstat_snapshot == NULL) { *err = 1027; goto fail; @@ -304,11 +301,11 @@ struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, return wlc; fail: - wlc_detach_mfree(wlc, osh); + wlc_detach_mfree(wlc); return NULL; } -void wlc_detach_mfree(struct wlc_info *wlc, struct osl_info *osh) +void wlc_detach_mfree(struct wlc_info *wlc) { if (wlc == NULL) return; @@ -349,7 +346,8 @@ void wlc_detach_mfree(struct wlc_info *wlc, struct osl_info *osh) if (wlc->corestate) { if (wlc->corestate->macstat_snapshot) { - kfree(wlc->corestate->macstat_snapshot); wlc->corestate->macstat_snapshot = NULL; + kfree(wlc->corestate->macstat_snapshot); + wlc->corestate->macstat_snapshot = NULL; } kfree(wlc->corestate); wlc->corestate = NULL; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h index 86bfdded909e..1fb7430b26a9 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h @@ -14,8 +14,7 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -extern void *wlc_calloc(struct osl_info *osh, uint unit, uint size); +extern void *wlc_calloc(uint unit, uint size); -extern struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, - uint *err, uint devid); -extern void wlc_detach_mfree(struct wlc_info *wlc, struct osl_info *osh); +extern struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid); +extern void wlc_detach_mfree(struct wlc_info *wlc); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index a857fccdb530..e7028ec03dfd 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -1770,7 +1770,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, && 4 == WLC_NUMRXIVS)); /* allocate struct wlc_info state and its substructures */ - wlc = (struct wlc_info *) wlc_attach_malloc(osh, unit, &err, device); + wlc = (struct wlc_info *) wlc_attach_malloc(unit, &err, device); if (wlc == NULL) goto fail; wlc->osh = osh; @@ -2194,7 +2194,7 @@ uint wlc_detach(struct wlc_info *wlc) for (i = 0; i < WLC_MAXMODULES; i++) ASSERT(wlc->modulecb[i].name[0] == '\0'); - wlc_detach_mfree(wlc, wlc->osh); + wlc_detach_mfree(wlc); return callbacks; } @@ -8450,7 +8450,7 @@ static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc, { struct wlc_txq_info *qi, *p; - qi = wlc_calloc(osh, wlc->pub->unit, sizeof(struct wlc_txq_info)); + qi = wlc_calloc(wlc->pub->unit, sizeof(struct wlc_txq_info)); if (qi != NULL) { /* * Have enough room for control packets along with HI watermark -- cgit v1.2.3 From 7c0e45d7fb4ca3f9505b316598f4c2d748f3e8d0 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Feb 2011 16:39:23 +0100 Subject: staging: brcm80211: remove NULL pointer checks before calling kfree kfree function can handle NULL pointer as passed parameter so there is no need for the calling function to check for this before calling kfree. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_alloc.c | 85 ++++------------------- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 4 +- drivers/staging/brcm80211/brcmsmac/wlc_antsel.c | 3 - drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 6 +- drivers/staging/brcm80211/brcmsmac/wlc_channel.c | 3 +- drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c | 3 - 6 files changed, 19 insertions(+), 85 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c index 8d6e0ea5d046..fecafc3958e2 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c @@ -146,17 +146,8 @@ static void wlc_bsscfg_mfree(wlc_bsscfg_t *cfg) if (cfg == NULL) return; - if (cfg->maclist) { - kfree(cfg->maclist); - cfg->maclist = NULL; - } - - if (cfg->current_bss != NULL) { - wlc_bss_info_t *current_bss = cfg->current_bss; - kfree(current_bss); - cfg->current_bss = NULL; - } - + kfree(cfg->maclist); + kfree(cfg->current_bss); kfree(cfg); } @@ -310,65 +301,19 @@ void wlc_detach_mfree(struct wlc_info *wlc) if (wlc == NULL) return; - if (wlc->modulecb) { - kfree(wlc->modulecb); - wlc->modulecb = NULL; - } - - if (wlc->default_bss) { - kfree(wlc->default_bss); - wlc->default_bss = NULL; - } - if (wlc->cfg) { - wlc_bsscfg_mfree(osh, wlc->cfg); - wlc->cfg = NULL; - } - - if (wlc->pkt_callback && wlc->pub && wlc->pub->tunables) { - kfree(wlc->pkt_callback); - wlc->pkt_callback = NULL; - } - - if (wlc->wsec_def_keys[0]) - kfree(wlc->wsec_def_keys[0]); - if (wlc->protection) { - kfree(wlc->protection); - wlc->protection = NULL; - } - - if (wlc->stf) { - kfree(wlc->stf); - wlc->stf = NULL; - } - - if (wlc->bandstate[0]) - kfree(wlc->bandstate[0]); - - if (wlc->corestate) { - if (wlc->corestate->macstat_snapshot) { - kfree(wlc->corestate->macstat_snapshot); - wlc->corestate->macstat_snapshot = NULL; - } - kfree(wlc->corestate); - wlc->corestate = NULL; - } - - if (wlc->pub) { - /* free pub struct */ - wlc_pub_mfree(osh, wlc->pub); - wlc->pub = NULL; - } - - if (wlc->hw) { - if (wlc->hw->bandstate[0]) { - kfree(wlc->hw->bandstate[0]); - wlc->hw->bandstate[0] = NULL; - } - - /* free hw struct */ - kfree(wlc->hw); - wlc->hw = NULL; - } + wlc_bsscfg_mfree(wlc->cfg); + wlc_pub_mfree(wlc->pub); + kfree(wlc->modulecb); + kfree(wlc->default_bss); + kfree(wlc->pkt_callback); + kfree(wlc->wsec_def_keys[0]); + kfree(wlc->protection); + kfree(wlc->stf); + kfree(wlc->bandstate[0]); + kfree(wlc->corestate->macstat_snapshot); + kfree(wlc->corestate); + kfree(wlc->hw->bandstate[0]); + kfree(wlc->hw); /* free the wlc */ kfree(wlc); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index eff174d0827b..19e22c8b2d9c 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -232,9 +232,7 @@ void wlc_ampdu_detach(struct ampdu_info *ampdu) /* free all ini's which were to be freed on callbacks which were never called */ for (i = 0; i < AMPDU_INI_FREE; i++) { - if (ampdu->ini_free[i]) { - kfree(ampdu->ini_free[i]); - } + kfree(ampdu->ini_free[i]); } wlc_module_unregister(ampdu->wlc->pub, "ampdu", ampdu); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c index 8c59898a418b..0a52989313ed 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c @@ -161,9 +161,6 @@ struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc, void wlc_antsel_detach(struct antsel_info *asi) { - if (!asi) - return; - kfree(asi); } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 1a49c6e52e41..353f1ea3694c 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -1044,10 +1044,8 @@ int wlc_bmac_detach(struct wlc_info *wlc) wlc_phy_shim_detach(wlc_hw->physhim); /* free vars */ - if (wlc_hw->vars) { - kfree(wlc_hw->vars); - wlc_hw->vars = NULL; - } + kfree(wlc_hw->vars); + wlc_hw->vars = NULL; if (wlc_hw->sih) { si_detach(wlc_hw->sih); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c index 8e2a3848496c..71731a4618c6 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c @@ -683,8 +683,7 @@ wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc) void wlc_channel_mgr_detach(wlc_cm_info_t *wlc_cm) { - if (wlc_cm) - kfree(wlc_cm); + kfree(wlc_cm); } u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, uint bandunit) diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c index fa3f73ffff17..95aafddcc95d 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c @@ -83,9 +83,6 @@ wlc_phy_shim_info_t *wlc_phy_shim_attach(struct wlc_hw_info *wlc_hw, void wlc_phy_shim_detach(wlc_phy_shim_info_t *physhim) { - if (!physhim) - return; - kfree(physhim); } -- cgit v1.2.3 From 06d278c51a072a655d7da23e3acc53f676967375 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 25 Feb 2011 16:39:24 +0100 Subject: staging: brcm80211: remove usage of struct osl_info to access device For accessing the PCI or SDIO device in the driver the device is stored in a separate structure osl_info. To get rid of the osl concept the use of this device pointer attribute is removed from the drivers. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- .../staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c | 2 +- drivers/staging/brcm80211/include/nicpci.h | 4 +- drivers/staging/brcm80211/include/osl.h | 21 ++++---- drivers/staging/brcm80211/include/siutils.h | 4 +- drivers/staging/brcm80211/util/aiutils.c | 6 +-- drivers/staging/brcm80211/util/hnddma.c | 34 +++++++------ drivers/staging/brcm80211/util/nicpci.c | 59 ++++++++++++---------- drivers/staging/brcm80211/util/siutils.c | 53 +++++++++---------- 8 files changed, 93 insertions(+), 90 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c index 151c9b262766..faca5e5449f7 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c @@ -442,7 +442,7 @@ void write_phy_reg(phy_info_t *pi, u16 addr, u16 val) if (addr == 0x72) (void)R_REG(osh, ®s->phyregdata); #else - W_REG(osh, (volatile u32 *)(®s->phyregaddr), + W_REG(osh, (u32 *)(®s->phyregaddr), addr | (val << 16)); if (pi->sh->bustype == PCI_BUS) { if (++pi->phy_wreg >= pi->phy_wreg_limit) { diff --git a/drivers/staging/brcm80211/include/nicpci.h b/drivers/staging/brcm80211/include/nicpci.h index 928818daedd7..eb842c838df1 100644 --- a/drivers/staging/brcm80211/include/nicpci.h +++ b/drivers/staging/brcm80211/include/nicpci.h @@ -45,7 +45,7 @@ #else struct sbpcieregs; -extern u8 pcicore_find_pci_capability(struct osl_info *osh, u8 req_cap_id, +extern u8 pcicore_find_pci_capability(void *dev, u8 req_cap_id, unsigned char *buf, u32 *buflen); extern uint pcie_readreg(struct osl_info *osh, struct sbpcieregs *pcieregs, uint addrtype, uint offset); @@ -70,7 +70,7 @@ extern u32 pcicore_pcieserdesreg(void *pch, u32 mdioslave, u32 offset, extern u32 pcicore_pciereg(void *pch, u32 offset, u32 mask, u32 val, uint type); -extern bool pcicore_pmecap_fast(struct osl_info *osh); +extern bool pcicore_pmecap_fast(void *pch); extern void pcicore_pmeen(void *pch); extern void pcicore_pmeclr(void *pch); extern bool pcicore_pmestat(void *pch); diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index f118b30552ea..0aac64af8de6 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -66,14 +66,11 @@ extern uint osl_pci_slot(struct osl_info *osh); #endif #if defined(BCMSDIO) -#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) \ - if ((osh)->mmbus) \ - mmap_op else bus_op -#define SELECT_BUS_READ(osh, mmap_op, bus_op) \ - ((osh)->mmbus) ? mmap_op : bus_op +#define SELECT_BUS_WRITE(mmap_op, bus_op) bus_op +#define SELECT_BUS_READ(mmap_op, bus_op) bus_op #else -#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) mmap_op -#define SELECT_BUS_READ(osh, mmap_op, bus_op) mmap_op +#define SELECT_BUS_WRITE(mmap_op, bus_op) mmap_op +#define SELECT_BUS_READ(mmap_op, bus_op) mmap_op #endif /* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ @@ -89,14 +86,14 @@ extern uint osl_pci_slot(struct osl_info *osh); #ifndef IL_BIGENDIAN #ifndef __mips__ #define R_REG(osh, r) (\ - SELECT_BUS_READ(osh, sizeof(*(r)) == sizeof(u8) ? \ + SELECT_BUS_READ(sizeof(*(r)) == sizeof(u8) ? \ readb((volatile u8*)(r)) : \ sizeof(*(r)) == sizeof(u16) ? readw((volatile u16*)(r)) : \ readl((volatile u32*)(r)), OSL_READ_REG(osh, r)) \ ) #else /* __mips__ */ #define R_REG(osh, r) (\ - SELECT_BUS_READ(osh, \ + SELECT_BUS_READ( \ ({ \ __typeof(*(r)) __osl_v; \ __asm__ __volatile__("sync"); \ @@ -126,7 +123,7 @@ extern uint osl_pci_slot(struct osl_info *osh); #endif /* __mips__ */ #define W_REG(osh, r, v) do { \ - SELECT_BUS_WRITE(osh, \ + SELECT_BUS_WRITE( \ switch (sizeof(*(r))) { \ case sizeof(u8): \ writeb((u8)(v), (volatile u8*)(r)); break; \ @@ -139,7 +136,7 @@ extern uint osl_pci_slot(struct osl_info *osh); } while (0) #else /* IL_BIGENDIAN */ #define R_REG(osh, r) (\ - SELECT_BUS_READ(osh, \ + SELECT_BUS_READ( \ ({ \ __typeof(*(r)) __osl_v; \ switch (sizeof(*(r))) { \ @@ -160,7 +157,7 @@ extern uint osl_pci_slot(struct osl_info *osh); OSL_READ_REG(osh, r)) \ ) #define W_REG(osh, r, v) do { \ - SELECT_BUS_WRITE(osh, \ + SELECT_BUS_WRITE( \ switch (sizeof(*(r))) { \ case sizeof(u8): \ writeb((u8)(v), \ diff --git a/drivers/staging/brcm80211/include/siutils.h b/drivers/staging/brcm80211/include/siutils.h index 2932bf582785..3301cf07cd2e 100644 --- a/drivers/staging/brcm80211/include/siutils.h +++ b/drivers/staging/brcm80211/include/siutils.h @@ -212,9 +212,9 @@ typedef struct gpioh_item { /* misc si info needed by some of the routines */ typedef struct si_info { - struct si_pub pub; /* back plane public state (must be first field) */ + struct si_pub pub; /* back plane public state (must be first) */ struct osl_info *osh; /* osl os handle */ - void *sdh; /* bcmsdh handle */ + void *pbus; /* handle to bus (pci/sdio/..) */ uint dev_coreid; /* the core provides driver functions */ void *intr_arg; /* interrupt callback function arg */ si_intrsoff_t intrsoff_fn; /* turns chip interrupts off */ diff --git a/drivers/staging/brcm80211/util/aiutils.c b/drivers/staging/brcm80211/util/aiutils.c index e4842c12ccf7..67d3706e055f 100644 --- a/drivers/staging/brcm80211/util/aiutils.c +++ b/drivers/staging/brcm80211/util/aiutils.c @@ -127,7 +127,7 @@ void ai_scan(si_t *sih, void *regs, uint devid) sii->curwrap = (void *)((unsigned long)regs + SI_CORE_SIZE); /* Now point the window at the erom */ - pci_write_config_dword(sii->osh->pdev, PCI_BAR0_WIN, erombase); + pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, erombase); eromptr = regs; break; @@ -347,10 +347,10 @@ void *ai_setcoreidx(si_t *sih, uint coreidx) case PCI_BUS: /* point bar0 window */ - pci_write_config_dword(sii->osh->pdev, PCI_BAR0_WIN, addr); + pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, addr); regs = sii->curmap; /* point bar0 2nd 4KB window */ - pci_write_config_dword(sii->osh->pdev, PCI_BAR0_WIN2, wrap); + pci_write_config_dword(sii->pbus, PCI_BAR0_WIN2, wrap); break; case SPI_BUS: diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 3c913a65da0d..3c71f7549d1c 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -81,6 +81,7 @@ typedef struct dma_info { char name[MAXNAMEL]; /* callers name for diag msgs */ struct osl_info *osh; /* os handle */ + void *pbus; /* bus handle */ si_t *sih; /* sb handle */ bool dma64; /* this dma engine is operating in 64-bit mode */ @@ -201,7 +202,7 @@ static void _dma_counterreset(dma_info_t *di); static void _dma_fifoloopbackenable(dma_info_t *di); static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags); static u8 dma_align_sizetobits(uint size); -static void *dma_ringalloc(struct osl_info *osh, u32 boundary, uint size, +static void *dma_ringalloc(dma_info_t *di, u32 boundary, uint size, u16 *alignbits, uint *alloced, dmaaddr_t *descpa, osldma_t **dmah); @@ -338,6 +339,7 @@ struct hnddma_pub *dma_attach(struct osl_info *osh, char *name, si_t *sih, di->osh = osh; di->sih = sih; + di->pbus = osh->pdev; /* save tunables */ di->ntxd = (u16) ntxd; @@ -531,7 +533,7 @@ static bool _dma_alloc(dma_info_t *di, uint direction) return dma64_alloc(di, direction); } -void *dma_alloc_consistent(struct osl_info *osh, uint size, u16 align_bits, +void *dma_alloc_consistent(struct pci_dev *pdev, uint size, u16 align_bits, uint *alloced, unsigned long *pap) { if (align_bits) { @@ -540,7 +542,7 @@ void *dma_alloc_consistent(struct osl_info *osh, uint size, u16 align_bits, size += align; *alloced = size; } - return pci_alloc_consistent(osh->pdev, size, (dma_addr_t *) pap); + return pci_alloc_consistent(pdev, size, (dma_addr_t *) pap); } /* !! may be called with core in reset */ @@ -555,11 +557,11 @@ static void _dma_detach(dma_info_t *di) /* free dma descriptor rings */ if (di->txd64) - pci_free_consistent(di->osh->pdev, di->txdalloc, + pci_free_consistent(di->pbus, di->txdalloc, ((s8 *)di->txd64 - di->txdalign), (di->txdpaorig)); if (di->rxd64) - pci_free_consistent(di->osh->pdev, di->rxdalloc, + pci_free_consistent(di->pbus, di->rxdalloc, ((s8 *)di->rxd64 - di->rxdalign), (di->rxdpaorig)); @@ -880,7 +882,7 @@ static bool BCMFASTPATH _dma_rxfill(dma_info_t *di) memset(&di->rxp_dmah[rxout], 0, sizeof(hnddma_seg_map_t)); - pa = pci_map_single(di->osh->pdev, p->data, + pa = pci_map_single(di->pbus, p->data, di->rxbufsize, PCI_DMA_FROMDEVICE); ASSERT(IS_ALIGNED(PHYSADDRLO(pa), 4)); @@ -1086,7 +1088,7 @@ u8 dma_align_sizetobits(uint size) * descriptor ring size aligned location. This will ensure that the ring will * not cross page boundary */ -static void *dma_ringalloc(struct osl_info *osh, u32 boundary, uint size, +static void *dma_ringalloc(dma_info_t *di, u32 boundary, uint size, u16 *alignbits, uint *alloced, dmaaddr_t *descpa, osldma_t **dmah) { @@ -1094,7 +1096,7 @@ static void *dma_ringalloc(struct osl_info *osh, u32 boundary, uint size, u32 desc_strtaddr; u32 alignbytes = 1 << *alignbits; - va = dma_alloc_consistent(osh, size, *alignbits, alloced, descpa); + va = dma_alloc_consistent(di->pbus, size, *alignbits, alloced, descpa); if (NULL == va) return NULL; @@ -1103,8 +1105,8 @@ static void *dma_ringalloc(struct osl_info *osh, u32 boundary, uint size, if (((desc_strtaddr + size - 1) & boundary) != (desc_strtaddr & boundary)) { *alignbits = dma_align_sizetobits(size); - pci_free_consistent(osh->pdev, size, va, *descpa); - va = dma_alloc_consistent(osh, size, *alignbits, + pci_free_consistent(di->pbus, size, va, *descpa); + va = dma_alloc_consistent(di->pbus, size, *alignbits, alloced, descpa); } return va; @@ -1228,7 +1230,7 @@ static bool dma64_alloc(dma_info_t *di, uint direction) align = (1 << align_bits); if (direction == DMA_TX) { - va = dma_ringalloc(di->osh, D64RINGALIGN, size, &align_bits, + va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, &alloced, &di->txdpaorig, &di->tx_dmah); if (va == NULL) { DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name)); @@ -1246,7 +1248,7 @@ static bool dma64_alloc(dma_info_t *di, uint direction) di->txdalloc = alloced; ASSERT(IS_ALIGNED((unsigned long)di->txd64, align)); } else { - va = dma_ringalloc(di->osh, D64RINGALIGN, size, &align_bits, + va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, &alloced, &di->rxdpaorig, &di->rx_dmah); if (va == NULL) { DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name)); @@ -1397,7 +1399,7 @@ static int dma64_txunframed(dma_info_t *di, void *buf, uint len, bool commit) if (len == 0) return 0; - pa = pci_map_single(di->osh->pdev, buf, len, PCI_DMA_TODEVICE); + pa = pci_map_single(di->pbus, buf, len, PCI_DMA_TODEVICE); flags = (D64_CTRL1_SOF | D64_CTRL1_IOC | D64_CTRL1_EOF); @@ -1477,7 +1479,7 @@ static int BCMFASTPATH dma64_txfast(dma_info_t *di, struct sk_buff *p0, memset(&di->txp_dmah[txout], 0, sizeof(hnddma_seg_map_t)); - pa = pci_map_single(di->osh->pdev, data, len, PCI_DMA_TODEVICE); + pa = pci_map_single(di->pbus, data, len, PCI_DMA_TODEVICE); if (DMASGLIST_ENAB) { map = &di->txp_dmah[txout]; @@ -1639,7 +1641,7 @@ static void *BCMFASTPATH dma64_getnexttxp(dma_info_t *di, txd_range_t range) i = NEXTTXD(i); } - pci_unmap_single(di->osh->pdev, pa, size, PCI_DMA_TODEVICE); + pci_unmap_single(di->pbus, pa, size, PCI_DMA_TODEVICE); } di->txin = i; @@ -1690,7 +1692,7 @@ static void *BCMFASTPATH dma64_getnextrxp(dma_info_t *di, bool forceall) di->dataoffsethigh)); /* clear this packet from the descriptor ring */ - pci_unmap_single(di->osh->pdev, pa, di->rxbufsize, PCI_DMA_FROMDEVICE); + pci_unmap_single(di->pbus, pa, di->rxbufsize, PCI_DMA_FROMDEVICE); W_SM(&di->rxd64[i].addrlow, 0xdeadbeef); W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef); diff --git a/drivers/staging/brcm80211/util/nicpci.c b/drivers/staging/brcm80211/util/nicpci.c index 56e658c429a8..7f587f30844d 100644 --- a/drivers/staging/brcm80211/util/nicpci.c +++ b/drivers/staging/brcm80211/util/nicpci.c @@ -36,6 +36,7 @@ typedef struct { } regs; /* Memory mapped register to the core */ si_t *sih; /* System interconnect handle */ + struct pci_dev *dev; struct osl_info *osh; /* OSL handle */ u8 pciecap_lcreg_offset; /* PCIE capability LCreg offset in the config space */ bool pcie_pr42767; @@ -95,12 +96,13 @@ void *pcicore_init(si_t *sih, struct osl_info *osh, void *regs) pi->sih = sih; pi->osh = osh; + pi->dev = osh->pdev; if (sih->buscoretype == PCIE_CORE_ID) { u8 cap_ptr; pi->regs.pcieregs = (sbpcieregs_t *) regs; cap_ptr = - pcicore_find_pci_capability(pi->osh, PCI_CAP_PCIECAP_ID, + pcicore_find_pci_capability(pi->dev, PCI_CAP_PCIECAP_ID, NULL, NULL); ASSERT(cap_ptr); pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET; @@ -122,7 +124,7 @@ void pcicore_deinit(void *pch) /* return cap_offset if requested capability exists in the PCI config space */ /* Note that it's caller's responsibility to make sure it's a pci bus */ u8 -pcicore_find_pci_capability(struct osl_info *osh, u8 req_cap_id, +pcicore_find_pci_capability(void *dev, u8 req_cap_id, unsigned char *buf, u32 *buflen) { u8 cap_id; @@ -131,29 +133,29 @@ pcicore_find_pci_capability(struct osl_info *osh, u8 req_cap_id, u8 byte_val; /* check for Header type 0 */ - pci_read_config_byte(osh->pdev, PCI_CFG_HDR, &byte_val); + pci_read_config_byte(dev, PCI_CFG_HDR, &byte_val); if ((byte_val & 0x7f) != PCI_HEADER_NORMAL) goto end; /* check if the capability pointer field exists */ - pci_read_config_byte(osh->pdev, PCI_CFG_STAT, &byte_val); + pci_read_config_byte(dev, PCI_CFG_STAT, &byte_val); if (!(byte_val & PCI_CAPPTR_PRESENT)) goto end; - pci_read_config_byte(osh->pdev, PCI_CFG_CAPPTR, &cap_ptr); + pci_read_config_byte(dev, PCI_CFG_CAPPTR, &cap_ptr); /* check if the capability pointer is 0x00 */ if (cap_ptr == 0x00) goto end; /* loop thr'u the capability list and see if the pcie capabilty exists */ - pci_read_config_byte(osh->pdev, cap_ptr, &cap_id); + pci_read_config_byte(dev, cap_ptr, &cap_id); while (cap_id != req_cap_id) { - pci_read_config_byte(osh->pdev, cap_ptr + 1, &cap_ptr); + pci_read_config_byte(dev, cap_ptr + 1, &cap_ptr); if (cap_ptr == 0x00) break; - pci_read_config_byte(osh->pdev, cap_ptr, &cap_id); + pci_read_config_byte(dev, cap_ptr, &cap_id); } if (cap_id != req_cap_id) { goto end; @@ -172,7 +174,7 @@ pcicore_find_pci_capability(struct osl_info *osh, u8 req_cap_id, bufsize = SZPCR - cap_data; *buflen = bufsize; while (bufsize--) { - pci_read_config_byte(osh->pdev, cap_data, buf); + pci_read_config_byte(dev, cap_data, buf); cap_data++; buf++; } @@ -347,15 +349,15 @@ u8 pcie_clkreq(void *pch, u32 mask, u32 val) if (!offset) return 0; - pci_read_config_dword(pi->osh->pdev, offset, ®_val); + pci_read_config_dword(pi->dev, offset, ®_val); /* set operation */ if (mask) { if (val) reg_val |= PCIE_CLKREQ_ENAB; else reg_val &= ~PCIE_CLKREQ_ENAB; - pci_write_config_dword(pi->osh->pdev, offset, reg_val); - pci_read_config_dword(pi->osh->pdev, offset, ®_val); + pci_write_config_dword(pi->dev, offset, reg_val); + pci_read_config_dword(pi->dev, offset, ®_val); } if (reg_val & PCIE_CLKREQ_ENAB) return 1; @@ -476,11 +478,11 @@ static void pcie_war_aspm_clkreq(pcicore_info_t *pi) W_REG(pi->osh, reg16, val16); - pci_read_config_dword(pi->osh->pdev, pi->pciecap_lcreg_offset, + pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w); w &= ~PCIE_ASPM_ENAB; w |= pi->pcie_war_aspm_ovr; - pci_write_config_dword(pi->osh->pdev, + pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w); } @@ -668,9 +670,9 @@ void pcicore_sleep(void *pch) if (!pi || !PCIE_ASPM(pi->sih)) return; - pci_read_config_dword(pi->osh->pdev, pi->pciecap_lcreg_offset, &w); + pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w); w &= ~PCIE_CAP_LCREG_ASPML1; - pci_write_config_dword(pi->osh->pdev, pi->pciecap_lcreg_offset, w); + pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w); pi->pcie_pr42767 = false; } @@ -690,19 +692,20 @@ void pcicore_down(void *pch, int state) /* ***** Wake-on-wireless-LAN (WOWL) support functions ***** */ /* Just uses PCI config accesses to find out, when needed before sb_attach is done */ -bool pcicore_pmecap_fast(struct osl_info *osh) +bool pcicore_pmecap_fast(void *pch) { + pcicore_info_t *pi = (pcicore_info_t *) pch; u8 cap_ptr; u32 pmecap; cap_ptr = - pcicore_find_pci_capability(osh, PCI_CAP_POWERMGMTCAP_ID, NULL, + pcicore_find_pci_capability(pi->dev, PCI_CAP_POWERMGMTCAP_ID, NULL, NULL); if (!cap_ptr) return false; - pci_read_config_dword(osh->pdev, cap_ptr, &pmecap); + pci_read_config_dword(pi->dev, cap_ptr, &pmecap); return (pmecap & PME_CAP_PM_STATES) != 0; } @@ -717,7 +720,7 @@ static bool pcicore_pmecap(pcicore_info_t *pi) if (!pi->pmecap_offset) { cap_ptr = - pcicore_find_pci_capability(pi->osh, + pcicore_find_pci_capability(pi->dev, PCI_CAP_POWERMGMTCAP_ID, NULL, NULL); if (!cap_ptr) @@ -725,7 +728,7 @@ static bool pcicore_pmecap(pcicore_info_t *pi) pi->pmecap_offset = cap_ptr; - pci_read_config_dword(pi->osh->pdev, pi->pmecap_offset, + pci_read_config_dword(pi->dev, pi->pmecap_offset, &pmecap); /* At least one state can generate PME */ @@ -745,10 +748,10 @@ void pcicore_pmeen(void *pch) if (!pcicore_pmecap(pi)) return; - pci_read_config_dword(pi->osh->pdev, pi->pmecap_offset + PME_CSR_OFFSET, + pci_read_config_dword(pi->dev, pi->pmecap_offset + PME_CSR_OFFSET, &w); w |= (PME_CSR_PME_EN); - pci_write_config_dword(pi->osh->pdev, + pci_write_config_dword(pi->dev, pi->pmecap_offset + PME_CSR_OFFSET, w); } @@ -763,7 +766,7 @@ bool pcicore_pmestat(void *pch) if (!pcicore_pmecap(pi)) return false; - pci_read_config_dword(pi->osh->pdev, pi->pmecap_offset + PME_CSR_OFFSET, + pci_read_config_dword(pi->dev, pi->pmecap_offset + PME_CSR_OFFSET, &w); return (w & PME_CSR_PME_STAT) == PME_CSR_PME_STAT; @@ -779,7 +782,7 @@ void pcicore_pmeclr(void *pch) if (!pcicore_pmecap(pi)) return; - pci_read_config_dword(pi->osh->pdev, pi->pmecap_offset + PME_CSR_OFFSET, + pci_read_config_dword(pi->dev, pi->pmecap_offset + PME_CSR_OFFSET, &w); PCI_ERROR(("pcicore_pci_pmeclr PMECSR : 0x%x\n", w)); @@ -787,7 +790,7 @@ void pcicore_pmeclr(void *pch) /* PMESTAT is cleared by writing 1 to it */ w &= ~(PME_CSR_PME_EN); - pci_write_config_dword(pi->osh->pdev, + pci_write_config_dword(pi->dev, pi->pmecap_offset + PME_CSR_OFFSET, w); } @@ -803,9 +806,9 @@ u32 pcie_lcreg(void *pch, u32 mask, u32 val) /* set operation */ if (mask) - pci_write_config_dword(pi->osh->pdev, offset, val); + pci_write_config_dword(pi->dev, offset, val); - pci_read_config_dword(pi->osh->pdev, offset, &tmpval); + pci_read_config_dword(pi->dev, offset, &tmpval); return tmpval; } diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index 5631d5b55c22..9a2e2c0f77be 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -313,7 +313,7 @@ static __used void si_nvram_process(si_info_t *sii, char *pvars) switch (sii->pub.bustype) { case PCI_BUS: /* do a pci config read to get subsystem id and subvendor id */ - pci_read_config_dword(sii->osh->pdev, PCI_CFG_SVID, &w); + pci_read_config_dword(sii->pbus, PCI_CFG_SVID, &w); /* Let nvram variables override subsystem Vend/ID */ sii->pub.boardvendor = (u16)si_getdevpathintvar(&sii->pub, "boardvendor"); @@ -367,7 +367,7 @@ static __used void si_nvram_process(si_info_t *sii, char *pvars) /* this has been customized for the bcm 4329 ONLY */ #ifdef BCMSDIO static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, - void *regs, uint bustype, void *sdh, + void *regs, uint bustype, void *pbus, char **vars, uint *varsz) { struct si_pub *sih = &sii->pub; @@ -385,7 +385,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, sih->buscoreidx = BADIDX; sii->curmap = regs; - sii->sdh = sdh; + sii->pbus = pbus; sii->osh = osh; /* find Chipcommon address */ @@ -393,7 +393,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, sih->bustype = bustype; /* bus/core/clk setup for register access */ - if (!si_buscore_prep(sii, bustype, devid, sdh)) { + if (!si_buscore_prep(sii, bustype, devid, pbus)) { SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", bustype)); return NULL; @@ -497,7 +497,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, #else /* BCMSDIO */ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, - void *regs, uint bustype, void *sdh, + void *regs, uint bustype, void *pbus, char **vars, uint *varsz) { struct si_pub *sih = &sii->pub; @@ -515,12 +515,12 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, sih->buscoreidx = BADIDX; sii->curmap = regs; - sii->sdh = sdh; + sii->pbus = pbus; sii->osh = osh; /* check to see if we are a si core mimic'ing a pci core */ if (bustype == PCI_BUS) { - pci_read_config_dword(sii->osh->pdev, PCI_SPROM_CONTROL, &w); + pci_read_config_dword(sii->pbus, PCI_SPROM_CONTROL, &w); if (w == 0xffffffff) { SI_ERROR(("%s: incoming bus is PCI but it's a lie, " " switching to SI devid:0x%x\n", @@ -531,10 +531,10 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, /* find Chipcommon address */ if (bustype == PCI_BUS) { - pci_read_config_dword(sii->osh->pdev, PCI_BAR0_WIN, &savewin); + pci_read_config_dword(sii->pbus, PCI_BAR0_WIN, &savewin); if (!GOODCOREADDR(savewin, SI_ENUM_BASE)) savewin = SI_ENUM_BASE; - pci_write_config_dword(sii->osh->pdev, PCI_BAR0_WIN, + pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, SI_ENUM_BASE); cc = (chipcregs_t *) regs; } else { @@ -544,7 +544,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, sih->bustype = bustype; /* bus/core/clk setup for register access */ - if (!si_buscore_prep(sii, bustype, devid, sdh)) { + if (!si_buscore_prep(sii, bustype, devid, pbus)) { SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", bustype)); return NULL; @@ -1087,7 +1087,7 @@ static uint si_slowclk_src(si_info_t *sii) if (sii->pub.ccrev < 6) { if (sii->pub.bustype == PCI_BUS) { - pci_read_config_dword(sii->osh->pdev, PCI_GPIO_OUT, + pci_read_config_dword(sii->pbus, PCI_GPIO_OUT, &val); if (val & PCI_CFG_GPIO_SCS) return SCC_SS_PCI; @@ -1274,9 +1274,9 @@ int si_clkctl_xtal(si_t *sih, uint what, bool on) if (PCIE(sii)) return -1; - pci_read_config_dword(sii->osh->pdev, PCI_GPIO_IN, &in); - pci_read_config_dword(sii->osh->pdev, PCI_GPIO_OUT, &out); - pci_read_config_dword(sii->osh->pdev, PCI_GPIO_OUTEN, &outen); + pci_read_config_dword(sii->pbus, PCI_GPIO_IN, &in); + pci_read_config_dword(sii->pbus, PCI_GPIO_OUT, &out); + pci_read_config_dword(sii->pbus, PCI_GPIO_OUTEN, &outen); /* * Avoid glitching the clock if GPRS is already using it. @@ -1297,9 +1297,9 @@ int si_clkctl_xtal(si_t *sih, uint what, bool on) out |= PCI_CFG_GPIO_XTAL; if (what & PLL) out |= PCI_CFG_GPIO_PLL; - pci_write_config_dword(sii->osh->pdev, + pci_write_config_dword(sii->pbus, PCI_GPIO_OUT, out); - pci_write_config_dword(sii->osh->pdev, + pci_write_config_dword(sii->pbus, PCI_GPIO_OUTEN, outen); udelay(XTAL_ON_DELAY); } @@ -1307,7 +1307,7 @@ int si_clkctl_xtal(si_t *sih, uint what, bool on) /* turn pll on */ if (what & PLL) { out &= ~PCI_CFG_GPIO_PLL; - pci_write_config_dword(sii->osh->pdev, + pci_write_config_dword(sii->pbus, PCI_GPIO_OUT, out); mdelay(2); } @@ -1316,9 +1316,9 @@ int si_clkctl_xtal(si_t *sih, uint what, bool on) out &= ~PCI_CFG_GPIO_XTAL; if (what & PLL) out |= PCI_CFG_GPIO_PLL; - pci_write_config_dword(sii->osh->pdev, + pci_write_config_dword(sii->pbus, PCI_GPIO_OUT, out); - pci_write_config_dword(sii->osh->pdev, + pci_write_config_dword(sii->pbus, PCI_GPIO_OUTEN, outen); } @@ -1463,8 +1463,9 @@ int si_devpath(si_t *sih, char *path, int size) case PCI_BUS: ASSERT((SI_INFO(sih))->osh != NULL); slen = snprintf(path, (size_t) size, "pci/%u/%u/", - OSL_PCI_BUS((SI_INFO(sih))->osh), - OSL_PCI_SLOT((SI_INFO(sih))->osh)); + ((struct pci_dev *)((SI_INFO(sih))->pbus))->bus->number, + PCI_SLOT( + ((struct pci_dev *)((SI_INFO(sih))->pbus))->devfn)); break; #ifdef BCMSDIO @@ -1549,7 +1550,7 @@ static __used bool si_ispcie(si_info_t *sii) return false; cap_ptr = - pcicore_find_pci_capability(sii->osh, PCI_CAP_PCIECAP_ID, NULL, + pcicore_find_pci_capability(sii->pbus, PCI_CAP_PCIECAP_ID, NULL, NULL); if (!cap_ptr) return false; @@ -1591,7 +1592,7 @@ void si_sdio_init(si_t *sih) } /* enable interrupts */ - bcmsdh_intr_enable(sii->sdh); + bcmsdh_intr_enable(sii->pbus); } #endif /* BCMSDIO */ @@ -1687,9 +1688,9 @@ void si_pci_setup(si_t *sih, uint coremask) */ if (PCIE(sii) || (PCI(sii) && ((sii->pub.buscorerev) >= 6))) { /* pci config write to set this core bit in PCIIntMask */ - pci_read_config_dword(sii->osh->pdev, PCI_INT_MASK, &w); + pci_read_config_dword(sii->pbus, PCI_INT_MASK, &w); w |= (coremask << PCI_SBIM_SHIFT); - pci_write_config_dword(sii->osh->pdev, PCI_INT_MASK, w); + pci_write_config_dword(sii->pbus, PCI_INT_MASK, w); } else { /* set sbintvec bit for our flag number */ si_setint(sih, siflag); @@ -1927,7 +1928,7 @@ bool si_deviceremoved(si_t *sih) switch (sih->bustype) { case PCI_BUS: ASSERT(sii->osh != NULL); - pci_read_config_dword(sii->osh->pdev, PCI_CFG_VID, &w); + pci_read_config_dword(sii->pbus, PCI_CFG_VID, &w); if ((w & 0xFFFF) != VENDOR_BROADCOM) return true; break; -- cgit v1.2.3 From 682a45382be47957860ac0a1eec7470a556bb30b Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Thu, 24 Feb 2011 22:13:27 -0800 Subject: staging: vt6656: main_usb.c remove one to many l's in the word. The patch below removes an extra "l" in the word. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/main_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 56ce9be5f86a..37d639602c8b 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1457,7 +1457,7 @@ static unsigned char *Config_FileOperation(PSDevice pDevice) buffer = kmalloc(1024, GFP_KERNEL); if(buffer==NULL) { - printk("alllocate mem for file fail?\n"); + printk("allocate mem for file fail?\n"); result = -1; goto error1; } -- cgit v1.2.3 From 8c7f9ae856348d75fe79c179fa5c66e1f9717a20 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Thu, 24 Feb 2011 22:13:46 -0800 Subject: staging: comedi: pcl816.c remove one to many l's in the word. The patch below removes an extra "l" in the word. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl816.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 3d0f018faa6b..ef3cc4f3be6e 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -108,7 +108,7 @@ struct pcl816_board { const char *name; /* board name */ int n_ranges; /* len of range list */ int n_aichan; /* num of A/D chans in diferencial mode */ - unsigned int ai_ns_min; /* minimal alllowed delay between samples (in ns) */ + unsigned int ai_ns_min; /* minimal allowed delay between samples (in ns) */ int n_aochan; /* num of D/A chans */ int n_dichan; /* num of DI chans */ int n_dochan; /* num of DO chans */ -- cgit v1.2.3 From 39eaedb68e54408c5476304a71ede713f31df37c Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Thu, 24 Feb 2011 22:14:05 -0800 Subject: staging: comedi: pcl818.c remove one to many l's in the word. The patch below removes an extra "l" in the word. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl818.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index d2bd6f82b830..f58d75be7295 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -261,7 +261,7 @@ struct pcl818_board { int n_ranges; /* len of range list */ int n_aichan_se; /* num of A/D chans in single ended mode */ int n_aichan_diff; /* num of A/D chans in diferencial mode */ - unsigned int ns_min; /* minimal alllowed delay between samples (in ns) */ + unsigned int ns_min; /* minimal allowed delay between samples (in ns) */ int n_aochan; /* num of D/A chans */ int n_dichan; /* num of DI chans */ int n_dochan; /* num of DO chans */ @@ -349,7 +349,7 @@ struct pcl818_private { long dma_runs_to_end; /* how many we must permorm DMA transfer to end of record */ unsigned long last_dma_run; /* how many bytes we must transfer on last DMA page */ unsigned char neverending_ai; /* if=1, then we do neverending record (you must use cancel()) */ - unsigned int ns_min; /* manimal alllowed delay between samples (in us) for actual card */ + unsigned int ns_min; /* manimal allowed delay between samples (in us) for actual card */ int i8253_osc_base; /* 1/frequency of on board oscilator in ns */ int irq_free; /* 1=have allocated IRQ */ int irq_blocked; /* 1=IRQ now uses any subdev */ -- cgit v1.2.3 From 3cbeb42e1e224338bfd4ad5f173b925a31cfb1e2 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Thu, 24 Feb 2011 22:14:23 -0800 Subject: staging: rtl8712: rtl871x_pwrctrl.c remove one to many l's in the word. The patch below removes an extra "l" in the word. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_pwrctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.c b/drivers/staging/rtl8712/rtl871x_pwrctrl.c index 9244c8a6d943..23e72a0401a8 100644 --- a/drivers/staging/rtl8712/rtl871x_pwrctrl.c +++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.c @@ -92,7 +92,7 @@ void r8712_set_ps_mode(struct _adapter *padapter, uint ps_mode, uint smart_ps) * * This will be called when CPWM interrupt is up. * - * using to update cpwn of drv; and drv willl make a decision to up or + * using to update cpwn of drv; and drv will make a decision to up or * down pwr level */ void r8712_cpwm_int_hdl(struct _adapter *padapter, -- cgit v1.2.3 From 0ffa3db9946ba2534d612d70cf40fa51fd5b63a4 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Thu, 24 Feb 2011 22:14:42 -0800 Subject: staging: vt6655: device_main.c remove one to many l's in the word. The patch below removes an extra "l" in the word. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 4fbacf8fdf21..638e3916774d 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -3032,7 +3032,7 @@ int Config_FileOperation(PSDevice pDevice,bool fwrite,unsigned char *Parameter) buffer = kmalloc(1024, GFP_KERNEL); if(buffer==NULL) { - printk("alllocate mem for file fail?\n"); + printk("allocate mem for file fail?\n"); result = -1; goto error1; } -- cgit v1.2.3 From 979cdcc90b5d4934e66cc7d7119cae949776d8bc Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Sat, 26 Feb 2011 20:34:01 -0800 Subject: drivers:staging:westbridge:astoria Remove one to many n's in a word. The Patch below removes one to many "n's" in a word.. Signed-off-by: Justin P. Mattock CC: Greg Kroah-Hartman CC: David Cross CC: devel@driverdev.osuosl.org Signed-off-by: Greg Kroah-Hartman --- drivers/staging/westbridge/astoria/api/src/cyasusb.c | 4 ++-- drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/westbridge/astoria/api/src/cyasusb.c b/drivers/staging/westbridge/astoria/api/src/cyasusb.c index d9cb7d49ae7d..92ea42503bf3 100644 --- a/drivers/staging/westbridge/astoria/api/src/cyasusb.c +++ b/drivers/staging/westbridge/astoria/api/src/cyasusb.c @@ -1058,8 +1058,8 @@ destroy: * This method asks the West Bridge device to connect the * internal USB D+ and D- signals to the USB pins, thus * starting the enumeration processes if the external pins -* are connnected to a USB host. If the external pins are -* not connect to a USB host, enumeration will begin as soon +* are connected to a USB host. If the external pins are +* not connected to a USB host, enumeration will begin as soon * as the USB pins are connected to a host. */ cy_as_return_status_t diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb.h index 9049c8d9fe6a..4a549e146812 100644 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb.h +++ b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb.h @@ -746,7 +746,7 @@ cy_as_usb_register_callback( the West Bridge device as a different device when necessary. This function connects the D+ and D- signal physically to the USB host - if they have been previously disconnnected. + if they have been previously disconnected. * Valid In Asynchronous Callback: YES (if cb supplied) * Nestable: YES -- cgit v1.2.3 From a0fe6029bce5ca2f1e7bcc8e248be1b3d2a2f6f4 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Sat, 26 Feb 2011 20:34:02 -0800 Subject: drivers:staging:bcm:CmHost.c Remove one to many n's in a word. The Patch below removes one to many "n's" in a word.. Signed-off-by: Justin P. Mattock CC: Greg Kroah-Hartman CC: Stephen Hemminger CC: devel@driverdev.osuosl.org Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index 5ac45820d564..017b4717b25b 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -1,6 +1,6 @@ /************************************************************ * CMHOST.C -* This file contains the routines for handling Connnection +* This file contains the routines for handling Connection * Management. ************************************************************/ -- cgit v1.2.3 From 012983a2e8aa36b8f2d62aaee6a540b331e6dcb4 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Sat, 26 Feb 2011 20:34:00 -0800 Subject: drivers:staging:dspbridge:node.h Remove one to many n's in a word. The Patch below removes one to many "n's" in a word.. Signed-off-by: Justin P. Mattock CC: Greg Kroah-Hartman CC: Rene Sapiens CC: devel@driverdev.osuosl.org Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tidspbridge/include/dspbridge/node.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/include/dspbridge/node.h b/drivers/staging/tidspbridge/include/dspbridge/node.h index 63739c8ffe0b..53da0ef483c8 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/node.h +++ b/drivers/staging/tidspbridge/include/dspbridge/node.h @@ -116,7 +116,7 @@ extern int node_change_priority(struct node_object *hnode, s32 prio); * ======== node_connect ======== * Purpose: * Connect two nodes on the DSP, or a node on the DSP to the GPP. In the - * case that the connnection is being made between a node on the DSP and + * case that the connection is being made between a node on the DSP and * the GPP, one of the node handles (either node1 or node2) must be * the constant NODE_HGPPNODE. * Parameters: -- cgit v1.2.3 From 1f2b472cc92d6178c5b24c12687783a0dedb9202 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Sat, 26 Feb 2011 20:33:59 -0800 Subject: drivers:staging:rt2860 Remove one to many n's in a word. The Patch below removes one to many "n's" in a word.. Signed-off-by: Justin P. Mattock CC: Greg Kroah-Hartman CC: Andy Shevchenko CC: Jesper Juhl CC: devel@driverdev.osuosl.org Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/common/ba_action.c | 2 +- drivers/staging/rt2860/common/cmm_data.c | 2 +- drivers/staging/rt2860/rtmp.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/common/ba_action.c b/drivers/staging/rt2860/common/ba_action.c index b046c2b814c5..62f6f6be4acb 100644 --- a/drivers/staging/rt2860/common/ba_action.c +++ b/drivers/staging/rt2860/common/ba_action.c @@ -107,7 +107,7 @@ void Announce_Reordering_Packet(struct rt_rtmp_adapter *pAd, if (mpdu->bAMSDU) { ASSERT(0); - BA_Reorder_AMSDU_Annnounce(pAd, pPacket); + BA_Reorder_AMSDU_Announce(pAd, pPacket); } else { /* */ /* pass this 802.3 packet to upper layer or forward this packet to WM directly */ diff --git a/drivers/staging/rt2860/common/cmm_data.c b/drivers/staging/rt2860/common/cmm_data.c index 2204c2bda386..f6c193cb84ee 100644 --- a/drivers/staging/rt2860/common/cmm_data.c +++ b/drivers/staging/rt2860/common/cmm_data.c @@ -1481,7 +1481,7 @@ u32 deaggregate_AMSDU_announce(struct rt_rtmp_adapter *pAd, return nMSDU; } -u32 BA_Reorder_AMSDU_Annnounce(struct rt_rtmp_adapter *pAd, void *pPacket) +u32 BA_Reorder_AMSDU_Announce(struct rt_rtmp_adapter *pAd, void *pPacket) { u8 *pData; u16 DataSize; diff --git a/drivers/staging/rt2860/rtmp.h b/drivers/staging/rt2860/rtmp.h index 70daaa4f9ac2..d16b06a6e2ac 100644 --- a/drivers/staging/rt2860/rtmp.h +++ b/drivers/staging/rt2860/rtmp.h @@ -3611,7 +3611,7 @@ struct rt_rtmp_sg_list *rt_get_sg_list_from_packet(void *pPacket, void announce_802_3_packet(struct rt_rtmp_adapter *pAd, void *pPacket); -u32 BA_Reorder_AMSDU_Annnounce(struct rt_rtmp_adapter *pAd, void *pPacket); +u32 BA_Reorder_AMSDU_Announce(struct rt_rtmp_adapter *pAd, void *pPacket); struct net_device *get_netdev_from_bssid(struct rt_rtmp_adapter *pAd, u8 FromWhichBSSID); -- cgit v1.2.3 From 0e83f46d3869a5255a04b875bb885bd141a609ef Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 26 Feb 2011 15:48:12 +0300 Subject: staging: gma500: fix some swapped gotos These gotos were swapped. In the original code, the first would result in a NULL dereference and the second would result in a memory leak. Signed-off-by: Dan Carpenter Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_fb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c index 94d845740313..f67f53b12937 100644 --- a/drivers/staging/gma500/psb_fb.c +++ b/drivers/staging/gma500/psb_fb.c @@ -460,7 +460,7 @@ static int psbfb_create(struct psb_fbdev *fbdev, if (!fb) { DRM_ERROR("failed to allocate fb.\n"); ret = -ENOMEM; - goto out_err0; + goto out_err1; } psbfb = to_psb_fb(fb); psbfb->size = size; @@ -468,7 +468,7 @@ static int psbfb_create(struct psb_fbdev *fbdev, info = framebuffer_alloc(sizeof(struct psb_fbdev), device); if (!info) { ret = -ENOMEM; - goto out_err1; + goto out_err0; } info->par = fbdev; -- cgit v1.2.3 From 2f7cf8d1ef94a450c5d147cb0c5e1fdf1542a96d Mon Sep 17 00:00:00 2001 From: Roel Van Nyen Date: Sun, 27 Feb 2011 23:20:24 +0100 Subject: staging: keucr: Change the custom counting functions to hweight8 and hweight16 Change the custom counting functions to hweight8 and hweight16 Signed-off-by: Roel Van Nyen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/keucr/smcommon.h | 2 -- drivers/staging/keucr/smilsub.c | 37 ++++++------------------------------- 2 files changed, 6 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/keucr/smcommon.h b/drivers/staging/keucr/smcommon.h index 169460547662..00064cabf4ed 100644 --- a/drivers/staging/keucr/smcommon.h +++ b/drivers/staging/keucr/smcommon.h @@ -25,8 +25,6 @@ Define Difinetion #define ERR_NoSmartMedia 0x003A /* Medium Not Present */ /***************************************************************************/ -char Bit_D_Count(BYTE); -char Bit_D_CountWord(WORD); void StringCopy(char *, char *, int); int StringCmp(char *, char *, int); diff --git a/drivers/staging/keucr/smilsub.c b/drivers/staging/keucr/smilsub.c index 6dbc81de637b..80da61c37bff 100644 --- a/drivers/staging/keucr/smilsub.c +++ b/drivers/staging/keucr/smilsub.c @@ -79,7 +79,7 @@ int Check_D_FailBlock(BYTE *redundant) return(SUCCESS); if (!*redundant) return(ERROR); - if (Bit_D_Count(*redundant)<7) + if (hweight8(*redundant)<7) return(ERROR); return(SUCCESS); @@ -100,7 +100,7 @@ int Check_D_DataStatus(BYTE *redundant) else ErrXDCode = NO_ERROR; - if (Bit_D_Count(*redundant)<5) + if (hweight8(*redundant)<5) return(ERROR); return(SUCCESS); @@ -120,14 +120,14 @@ int Load_D_LogBlockAddr(BYTE *redundant) if ((addr1 &0xF000)==0x1000) { Media.LogBlock=(addr1 &0x0FFF)/2; return(SUCCESS); } - if (Bit_D_CountWord((WORD)(addr1^addr2))!=0x01) return(ERROR); + if (hweight16((WORD)(addr1^addr2))!=0x01) return(ERROR); if ((addr1 &0xF000)==0x1000) - if (!(Bit_D_CountWord(addr1) &0x01)) + if (!(hweight16(addr1) &0x01)) { Media.LogBlock=(addr1 &0x0FFF)/2; return(SUCCESS); } if ((addr2 &0xF000)==0x1000) - if (!(Bit_D_CountWord(addr2) &0x01)) + if (!(hweight16(addr2) &0x01)) { Media.LogBlock=(addr2 &0x0FFF)/2; return(SUCCESS); } return(ERROR); @@ -151,7 +151,7 @@ void Set_D_LogBlockAddr(BYTE *redundant) *(redundant+REDT_DATA) =0xFF; addr=Media.LogBlock*2+0x1000; - if ((Bit_D_CountWord(addr)%2)) + if ((hweight16(addr)%2)) addr++; *(redundant+REDT_ADDR1H)=*(redundant+REDT_ADDR2H)=(BYTE)(addr/0x0100); @@ -1549,31 +1549,6 @@ void Set_D_RightECC(BYTE *redundant) // StringCopy((char *)(redundant+0x08),(char *)(EccBuf+0x03),3); //} */ -//Common Subroutine -char Bit_D_Count(BYTE cdata) -{ - WORD bitcount=0; - - while(cdata) { - bitcount+=(WORD)(cdata &0x01); - cdata /=2; - } - - return((char)bitcount); -} - -//----- -char Bit_D_CountWord(WORD cdata) -{ - WORD bitcount=0; - - while(cdata) { - bitcount+=(cdata &0x01); - cdata /=2; - } - - return((char)bitcount); -} /* //----- SM_ReadBlock() --------------------------------------------- -- cgit v1.2.3 From fd4bd42ead80c26877e54072a546290dfcb1576c Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Sun, 27 Feb 2011 23:28:19 +0300 Subject: staging: brcm80211: replace broadcom specific auth related defines - DOT11_OPEN_SYSTEM -> WLAN_AUTH_OPEN - DOT11_SHARED_KEY -> WLAN_AUTH_SHARED_KEY - remove unused DOT11_MGMT_HDR_LEN Signed-off-by: Stanislav Fomichev Acked-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_common.c | 6 +++--- drivers/staging/brcm80211/include/proto/802.11.h | 5 ----- 2 files changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index 784333c42014..2d4a4b3bafeb 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -632,9 +632,9 @@ static void wl_show_host_event(wl_event_msg_t *event, void *event_data) case WLC_E_AUTH: case WLC_E_AUTH_IND: - if (auth_type == DOT11_OPEN_SYSTEM) + if (auth_type == WLAN_AUTH_OPEN) auth_str = "Open System"; - else if (auth_type == DOT11_SHARED_KEY) + else if (auth_type == WLAN_AUTH_SHARED_KEY) auth_str = "Shared Key"; else { sprintf(err_msg, "AUTH unknown: %d", (int)auth_type); @@ -1807,7 +1807,7 @@ dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t *ssids_local, int nssid, unsigned char sc for (i = 0; i < nssid; i++) { pfn_element.bss_type = DOT11_BSSTYPE_INFRASTRUCTURE; - pfn_element.auth = DOT11_OPEN_SYSTEM; + pfn_element.auth = WLAN_AUTH_OPEN; pfn_element.wpa_auth = WPA_AUTH_PFN_ANY; pfn_element.wsec = 0; pfn_element.infra = 1; diff --git a/drivers/staging/brcm80211/include/proto/802.11.h b/drivers/staging/brcm80211/include/proto/802.11.h index 8ca674e1a3d5..141e95f57c6b 100644 --- a/drivers/staging/brcm80211/include/proto/802.11.h +++ b/drivers/staging/brcm80211/include/proto/802.11.h @@ -48,8 +48,6 @@ #define DOT11_BA_BITMAP_LEN 128 #define DOT11_BA_LEN 4 -#define DOT11_MGMT_HDR_LEN 24 - #define WME_OUI "\x00\x50\xf2" #define WME_VER 1 #define WME_TYPE 2 @@ -114,9 +112,6 @@ typedef struct wme_param_ie wme_param_ie_t; #define EDCF_AC_VO_TXOP_AP 0x002f -#define DOT11_OPEN_SYSTEM 0 -#define DOT11_SHARED_KEY 1 - #define SEQNUM_SHIFT 4 #define SEQNUM_MAX 0x1000 #define FRAGNUM_MASK 0xF -- cgit v1.2.3 From f4728c386ce4f57affe6096b8d216bdd899958d6 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Sun, 27 Feb 2011 23:28:21 +0300 Subject: brcm80211: replace broadcom specific defines AMPDU_RX_FACTOR_64K -> IEEE80211_HT_MAX_AMPDU_64K AMPDU_RX_FACTOR_32K -> IEEE80211_HT_MAX_AMPDU_32K DOT11_MAX_KEY_SIZE -> WLAN_MAX_KEY_LEN HT_CAP_MIMO_PS_MASK -> IEEE80211_HT_CAP_SM_PS HT_CAP_MAX_AMSDU -> IEEE80211_HT_CAP_MAX_AMSDU HT_CAP_RX_STBC_MASK -> IEEE80211_HT_CAP_RX_STBC HT_CAP_RX_STBC_SHIFT -> IEEE80211_HT_CAP_RX_STBC_SHIFT HT_PARAMS_RX_FACTOR_MASK -> IEEE80211_HT_AMPDU_PARM_FACTOR Signed-off-by: Stanislav Fomichev Acked-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 2 +- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 2 +- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 6 +++--- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 8 ++++---- drivers/staging/brcm80211/brcmsmac/wlc_key.h | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_pub.h | 4 ++-- drivers/staging/brcm80211/brcmsmac/wlc_stf.c | 4 ++-- drivers/staging/brcm80211/include/proto/802.11.h | 15 +-------------- drivers/staging/brcm80211/include/wlioctl.h | 2 +- 10 files changed, 17 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 86c18be7d64e..fc920787cdaa 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -1766,7 +1766,7 @@ wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, key.index = key_idx; swap_key_to_BE(&key); memset(¶ms, 0, sizeof(params)); - params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len); + params.key_len = (u8) min_t(u8, WLAN_MAX_KEY_LEN, key.len); memcpy(params.key, key.data, params.key_len); err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)); diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index 91d848807537..f82c10ef8bad 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -2435,7 +2435,7 @@ wl_iw_get_encode(struct net_device *dev, wsec = le32_to_cpu(wsec); auth = le32_to_cpu(auth); - dwrq->length = min_t(u16, DOT11_MAX_KEY_SIZE, key.len); + dwrq->length = min_t(u16, WLAN_MAX_KEY_LEN, key.len); dwrq->flags = key.index + 1; if (!(wsec & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))) diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index de245ac38c7b..57c1789832a6 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -595,7 +595,7 @@ wl_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, AMPDU_MAX_SCB_TID * PKTQ_LEN_DEFAULT); sta->ht_cap.ht_supported = true; - sta->ht_cap.ampdu_factor = AMPDU_RX_FACTOR_64K; + sta->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; sta->ht_cap.ampdu_density = AMPDU_DEF_MPDU_DENSITY; sta->ht_cap.cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | @@ -989,7 +989,7 @@ static struct ieee80211_supported_band wl_band_2GHz_nphy = { IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, .ht_supported = true, - .ampdu_factor = AMPDU_RX_FACTOR_64K, + .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, .ampdu_density = AMPDU_DEF_MPDU_DENSITY, .mcs = { /* placeholders for now */ @@ -1009,7 +1009,7 @@ static struct ieee80211_supported_band wl_band_5GHz_nphy = { /* use IEEE80211_HT_CAP_* from include/linux/ieee80211.h */ .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, /* No 40 mhz yet */ .ht_supported = true, - .ampdu_factor = AMPDU_RX_FACTOR_64K, + .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, .ampdu_density = AMPDU_DEF_MPDU_DENSITY, .mcs = { /* placeholders for now */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index 19e22c8b2d9c..b198797fa307 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -201,9 +201,9 @@ struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc) ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD; /* bump max ampdu rcv size to 64k for all 11n devices except 4321A0 and 4321A1 */ if (WLCISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2)) - ampdu->rx_factor = AMPDU_RX_FACTOR_32K; + ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_32K; else - ampdu->rx_factor = AMPDU_RX_FACTOR_64K; + ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_64K; ampdu->retry_limit = AMPDU_DEF_RETRY_LIMIT; ampdu->rr_retry_limit = AMPDU_DEF_RR_RETRY_LIMIT; @@ -1340,8 +1340,8 @@ void wlc_ampdu_shm_upd(struct ampdu_info *ampdu) struct wlc_info *wlc = ampdu->wlc; /* Extend ucode internal watchdog timer to match larger received frames */ - if ((ampdu->rx_factor & HT_PARAMS_RX_FACTOR_MASK) == - AMPDU_RX_FACTOR_64K) { + if ((ampdu->rx_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) == + IEEE80211_HT_MAX_AMPDU_64K) { wlc_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX); wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX); } else { diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_key.h b/drivers/staging/brcm80211/brcmsmac/wlc_key.h index 70d3173e9fde..50a4e38b4cca 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_key.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_key.h @@ -98,7 +98,7 @@ typedef struct wsec_key { s8 icv_len; /* ICV length */ u32 len; /* key length..don't move this var */ /* data is 4byte aligned */ - u8 data[DOT11_MAX_KEY_SIZE]; /* key data */ + u8 data[WLAN_MAX_KEY_LEN]; /* key data */ wsec_iv_t rxiv[WLC_NUMRXIVS]; /* Rx IV (one per TID) */ wsec_iv_t txiv; /* Tx IV */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index e7028ec03dfd..26eb69fd552a 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -8304,7 +8304,7 @@ void wlc_reset_bmac_done(struct wlc_info *wlc) void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode) { - wlc->ht_cap.cap_info &= ~HT_CAP_MIMO_PS_MASK; + wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_SM_PS; wlc->ht_cap.cap_info |= (mimops_mode << IEEE80211_HT_CAP_SM_PS_SHIFT); if (AP_ENAB(wlc->pub) && wlc->clk) { diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h index af5d82ca3d21..0cd98910987a 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h @@ -142,9 +142,9 @@ struct rsn_parms { #define AMPDU_DEF_MPDU_DENSITY 6 /* default mpdu density (110 ==> 4us) */ /* defaults for the HT (MIMO) bss */ -#define HT_CAP ((HT_CAP_MIMO_PS_OFF << IEEE80211_HT_CAP_SM_PS_SHIFT) |\ +#define HT_CAP (IEEE80211_HT_CAP_SM_PS |\ IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_GRN_FLD |\ - HT_CAP_MAX_AMSDU | IEEE80211_HT_CAP_DSSSCCK40) + IEEE80211_HT_CAP_MAX_AMSDU | IEEE80211_HT_CAP_DSSSCCK40) /* wlc internal bss_info, wl external one is in wlioctl.h */ typedef struct wlc_bss_info { diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c index 25fbcdac4f77..9e27be9d49f9 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c @@ -80,8 +80,8 @@ static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val) return; } - wlc->ht_cap.cap_info &= ~HT_CAP_RX_STBC_MASK; - wlc->ht_cap.cap_info |= (val << HT_CAP_RX_STBC_SHIFT); + wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_RX_STBC; + wlc->ht_cap.cap_info |= (val << IEEE80211_HT_CAP_RX_STBC_SHIFT); if (wlc->pub->up) { wlc_update_beacon(wlc); diff --git a/drivers/staging/brcm80211/include/proto/802.11.h b/drivers/staging/brcm80211/include/proto/802.11.h index 141e95f57c6b..913cb547731b 100644 --- a/drivers/staging/brcm80211/include/proto/802.11.h +++ b/drivers/staging/brcm80211/include/proto/802.11.h @@ -186,22 +186,10 @@ typedef struct d11cnt { #define HT_CAP_IE_LEN 26 -#define HT_CAP_MIMO_PS_MASK 0x000C -#define HT_CAP_MIMO_PS_OFF 0x0003 -#define HT_CAP_MIMO_PS_ON 0x0000 -#define HT_CAP_RX_STBC_MASK 0x0300 -#define HT_CAP_RX_STBC_SHIFT 8 -#define HT_CAP_MAX_AMSDU 0x0800 - #define HT_CAP_RX_STBC_NO 0x0 #define HT_CAP_RX_STBC_ONE_STREAM 0x1 -#define HT_PARAMS_RX_FACTOR_MASK 0x03 - -#define AMPDU_MAX_MPDU_DENSITY 7 -#define AMPDU_RX_FACTOR_16K 1 -#define AMPDU_RX_FACTOR_32K 2 -#define AMPDU_RX_FACTOR_64K 3 +#define AMPDU_MAX_MPDU_DENSITY IEEE80211_HT_MPDU_DENSITY_16 #define AMPDU_DELIMITER_LEN 4 @@ -220,7 +208,6 @@ typedef struct d11cnt { #define RSN_AKM_PSK 2 #define DOT11_MAX_DEFAULT_KEYS 4 -#define DOT11_MAX_KEY_SIZE 32 #define DOT11_WPA_KEY_RSC_LEN 8 #define BRCM_OUI "\x00\x10\x18" diff --git a/drivers/staging/brcm80211/include/wlioctl.h b/drivers/staging/brcm80211/include/wlioctl.h index 2de49b84cb63..5e2b11bcfc6f 100644 --- a/drivers/staging/brcm80211/include/wlioctl.h +++ b/drivers/staging/brcm80211/include/wlioctl.h @@ -474,7 +474,7 @@ typedef struct wl_rm_rep { typedef struct wl_wsec_key { u32 index; /* key index */ u32 len; /* key length */ - u8 data[DOT11_MAX_KEY_SIZE]; /* key data */ + u8 data[WLAN_MAX_KEY_LEN]; /* key data */ u32 pad_1[18]; u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ u32 flags; /* misc flags */ -- cgit v1.2.3 From c0365f04f65e2055caefbf0971d4f23969af47ee Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 27 Feb 2011 21:54:14 +0100 Subject: staging: brcm80211: Add buf_size parameter to ampdu_action handler function struct ieee80211_ops.ampdu_action function pointer definition now includes a u8 buf_size parameter. Update wl_ops_ampdu_action handler function according to this new signature. Signed-off-by: Javier Martinez Canillas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 57c1789832a6..6059e4cc3aa1 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -149,7 +149,8 @@ static int wl_ops_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, static int wl_ops_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn); + struct ieee80211_sta *sta, u16 tid, u16 *ssn, + u8 buf_size); static void wl_ops_rfkill_poll(struct ieee80211_hw *hw); static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) @@ -617,7 +618,8 @@ static int wl_ops_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn) + struct ieee80211_sta *sta, u16 tid, u16 *ssn, + u8 buf_size) { #if defined(BCMDBG) struct scb *scb = (struct scb *)sta->drv_priv; -- cgit v1.2.3 From cecf826df8648c843ea8db63b1f82c154a74db36 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Thu, 24 Feb 2011 14:49:00 -0500 Subject: staging: winbond: needs for msleep and friends linux/delay.h is pulled in somehow on x86 but not on ia64 or powerpc. This fixes a build failure on those arches since they use [mu]delay. Signed-off-by: Jeff Mahoney Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/core.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/winbond/core.h b/drivers/staging/winbond/core.h index d7b3aca5ddeb..6160b2fab833 100644 --- a/drivers/staging/winbond/core.h +++ b/drivers/staging/winbond/core.h @@ -3,6 +3,7 @@ #include #include +#include #include "wbhal.h" #include "mto.h" -- cgit v1.2.3 From 06125beb41af06fd197a7d216d57aa32b83f6cbd Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Sat, 26 Feb 2011 20:33:57 -0800 Subject: usb: host: uhci-hcd.c Remove one to many n's in a word. The Patch below removes one to many "n's" in a word.. Signed-off-by: Justin P. Mattock CC: Alan Stern CC: linux-usb@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index cee867829ec9..4f65b14e5e08 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -471,7 +471,7 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd) /* * Store the current frame number in uhci->frame_number if the controller - * is runnning. Expand from 11 bits (of which we use only 10) to a + * is running. Expand from 11 bits (of which we use only 10) to a * full-sized integer. * * Like many other parts of the driver, this code relies on being polled -- cgit v1.2.3 From 6d42fcdb685e3b7af45c77181537db4bc1a715f9 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Sat, 26 Feb 2011 20:33:56 -0800 Subject: usb: core: hub.c Remove one to many n's in a word. The Patch below removes one to many "n's" in a word.. Signed-off-by: Justin P. Mattock CC: Alan Stern CC: linux-usb@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index c168121f9f97..395754edd063 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -616,7 +616,7 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state) } /* - * Disable a port and mark a logical connnect-change event, so that some + * Disable a port and mark a logical connect-change event, so that some * time later khubd will disconnect() any existing usb_device on the port * and will re-enumerate if there actually is a device attached. */ -- cgit v1.2.3 From bedc0c31ac3db828e6ade7a8c5cb708688f0a7e1 Mon Sep 17 00:00:00 2001 From: Arvid Brodin Date: Sat, 26 Feb 2011 22:02:57 +0100 Subject: usb/isp1760: Move to native-endian ptds This helps users with platform-bus-connected isp176xs, big-endian cpu, and missing byteswapping on the data bus. It does so by collecting all SW byteswaps in one place and also fixes a bug with non-32-bit io transfers on this hardware, where payload has to be byteswapped instead of ptds. Signed-off-by: Arvid Brodin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp1760-hcd.c | 663 ++++++++++++++++++++--------------------- drivers/usb/host/isp1760-hcd.h | 33 +- 2 files changed, 339 insertions(+), 357 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index c470cc83dbb0..47ce0373a3c9 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -114,75 +114,149 @@ struct isp1760_qh { #define ehci_port_speed(priv, portsc) USB_PORT_STAT_HIGH_SPEED -static unsigned int isp1760_readl(__u32 __iomem *regs) +/* + * Access functions for isp176x registers (addresses 0..0x03FF). + */ +static u32 reg_read32(void __iomem *base, u32 reg) { - return readl(regs); + return readl(base + reg); } -static void isp1760_writel(const unsigned int val, __u32 __iomem *regs) +static void reg_write32(void __iomem *base, u32 reg, u32 val) { - writel(val, regs); + writel(val, base + reg); } /* - * The next two copy via MMIO data to/from the device. memcpy_{to|from}io() + * Access functions for isp176x memory (offset >= 0x0400). + * + * bank_reads8() reads memory locations prefetched by an earlier write to + * HC_MEMORY_REG (see isp176x datasheet). Unless you want to do fancy multi- + * bank optimizations, you should use the more generic mem_reads8() below. + * + * For access to ptd memory, use the specialized ptd_read() and ptd_write() + * below. + * + * These functions copy via MMIO data to/from the device. memcpy_{to|from}io() * doesn't quite work because some people have to enforce 32-bit access */ -static void priv_read_copy(struct isp1760_hcd *priv, u32 *src, - __u32 __iomem *dst, u32 len) +static void bank_reads8(void __iomem *src_base, u32 src_offset, u32 bank_addr, + __u32 *dst, u32 bytes) { + __u32 __iomem *src; u32 val; - u8 *buff8; + __u8 *src_byteptr; + __u8 *dst_byteptr; - if (!src) { - printk(KERN_ERR "ERROR: buffer: %p len: %d\n", src, len); - return; - } + src = src_base + (bank_addr | src_offset); - while (len >= 4) { - *src = __raw_readl(dst); - len -= 4; - src++; - dst++; + if (src_offset < PAYLOAD_OFFSET) { + while (bytes >= 4) { + *dst = le32_to_cpu(__raw_readl(src)); + bytes -= 4; + src++; + dst++; + } + } else { + while (bytes >= 4) { + *dst = __raw_readl(src); + bytes -= 4; + src++; + dst++; + } } - if (!len) + if (!bytes) return; /* in case we have 3, 2 or 1 by left. The dst buffer may not be fully * allocated. */ - val = isp1760_readl(dst); - - buff8 = (u8 *)src; - while (len) { - - *buff8 = val; - val >>= 8; - len--; - buff8++; + if (src_offset < PAYLOAD_OFFSET) + val = le32_to_cpu(__raw_readl(src)); + else + val = __raw_readl(src); + + dst_byteptr = (void *) dst; + src_byteptr = (void *) &val; + while (bytes > 0) { + *dst_byteptr = *src_byteptr; + dst_byteptr++; + src_byteptr++; + bytes--; } } -static void priv_write_copy(const struct isp1760_hcd *priv, const u32 *src, - __u32 __iomem *dst, u32 len) +static void mem_reads8(void __iomem *src_base, u32 src_offset, void *dst, + u32 bytes) { - while (len >= 4) { - __raw_writel(*src, dst); - len -= 4; - src++; - dst++; + reg_write32(src_base, HC_MEMORY_REG, src_offset + ISP_BANK(0)); + ndelay(90); + bank_reads8(src_base, src_offset, ISP_BANK(0), dst, bytes); +} + +static void mem_writes8(void __iomem *dst_base, u32 dst_offset, + __u32 const *src, u32 bytes) +{ + __u32 __iomem *dst; + + dst = dst_base + dst_offset; + + if (dst_offset < PAYLOAD_OFFSET) { + while (bytes >= 4) { + __raw_writel(cpu_to_le32(*src), dst); + bytes -= 4; + src++; + dst++; + } + } else { + while (bytes >= 4) { + __raw_writel(*src, dst); + bytes -= 4; + src++; + dst++; + } } - if (!len) + if (!bytes) return; - /* in case we have 3, 2 or 1 by left. The buffer is allocated and the - * extra bytes should not be read by the HW + /* in case we have 3, 2 or 1 bytes left. The buffer is allocated and the + * extra bytes should not be read by the HW. */ - __raw_writel(*src, dst); + if (dst_offset < PAYLOAD_OFFSET) + __raw_writel(cpu_to_le32(*src), dst); + else + __raw_writel(*src, dst); } +/* + * Read and write ptds. 'ptd_offset' should be one of ISO_PTD_OFFSET, + * INT_PTD_OFFSET, and ATL_PTD_OFFSET. 'slot' should be less than 32. + */ +static void ptd_read(void __iomem *base, u32 ptd_offset, u32 slot, + struct ptd *ptd) +{ + reg_write32(base, HC_MEMORY_REG, + ISP_BANK(0) + ptd_offset + slot*sizeof(*ptd)); + ndelay(90); + bank_reads8(base, ptd_offset + slot*sizeof(*ptd), ISP_BANK(0), + (void *) ptd, sizeof(*ptd)); +} + +static void ptd_write(void __iomem *base, u32 ptd_offset, u32 slot, + struct ptd *ptd) +{ + mem_writes8(base, ptd_offset + slot*sizeof(*ptd) + sizeof(ptd->dw0), + &ptd->dw1, 7*sizeof(ptd->dw1)); + /* Make sure dw0 gets written last (after other dw's and after payload) + since it contains the enable bit */ + wmb(); + mem_writes8(base, ptd_offset + slot*sizeof(*ptd), &ptd->dw0, + sizeof(ptd->dw0)); +} + + /* memory management of the 60kb on the chip from 0x1000 to 0xffff */ static void init_memory(struct isp1760_hcd *priv) { @@ -269,29 +343,23 @@ static void free_mem(struct isp1760_hcd *priv, u32 mem) static void isp1760_init_regs(struct usb_hcd *hcd) { - isp1760_writel(0, hcd->regs + HC_BUFFER_STATUS_REG); - isp1760_writel(NO_TRANSFER_ACTIVE, hcd->regs + - HC_ATL_PTD_SKIPMAP_REG); - isp1760_writel(NO_TRANSFER_ACTIVE, hcd->regs + - HC_INT_PTD_SKIPMAP_REG); - isp1760_writel(NO_TRANSFER_ACTIVE, hcd->regs + - HC_ISO_PTD_SKIPMAP_REG); - - isp1760_writel(~NO_TRANSFER_ACTIVE, hcd->regs + - HC_ATL_PTD_DONEMAP_REG); - isp1760_writel(~NO_TRANSFER_ACTIVE, hcd->regs + - HC_INT_PTD_DONEMAP_REG); - isp1760_writel(~NO_TRANSFER_ACTIVE, hcd->regs + - HC_ISO_PTD_DONEMAP_REG); + reg_write32(hcd->regs, HC_BUFFER_STATUS_REG, 0); + reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE); + reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE); + reg_write32(hcd->regs, HC_ISO_PTD_SKIPMAP_REG, NO_TRANSFER_ACTIVE); + + reg_write32(hcd->regs, HC_ATL_PTD_DONEMAP_REG, ~NO_TRANSFER_ACTIVE); + reg_write32(hcd->regs, HC_INT_PTD_DONEMAP_REG, ~NO_TRANSFER_ACTIVE); + reg_write32(hcd->regs, HC_ISO_PTD_DONEMAP_REG, ~NO_TRANSFER_ACTIVE); } -static int handshake(struct isp1760_hcd *priv, void __iomem *ptr, +static int handshake(struct usb_hcd *hcd, u32 reg, u32 mask, u32 done, int usec) { u32 result; do { - result = isp1760_readl(ptr); + result = reg_read32(hcd->regs, reg); if (result == ~0) return -ENODEV; result &= mask; @@ -308,13 +376,13 @@ static int ehci_reset(struct isp1760_hcd *priv) { int retval; struct usb_hcd *hcd = priv_to_hcd(priv); - u32 command = isp1760_readl(hcd->regs + HC_USBCMD); + u32 command = reg_read32(hcd->regs, HC_USBCMD); command |= CMD_RESET; - isp1760_writel(command, hcd->regs + HC_USBCMD); + reg_write32(hcd->regs, HC_USBCMD, command); hcd->state = HC_STATE_HALT; priv->next_statechange = jiffies; - retval = handshake(priv, hcd->regs + HC_USBCMD, + retval = handshake(hcd, HC_USBCMD, CMD_RESET, 0, 250 * 1000); return retval; } @@ -362,7 +430,7 @@ static int priv_init(struct usb_hcd *hcd) priv->periodic_size = DEFAULT_I_TDPS; /* controllers may cache some of the periodic schedule ... */ - hcc_params = isp1760_readl(hcd->regs + HC_HCCPARAMS); + hcc_params = reg_read32(hcd->regs, HC_HCCPARAMS); /* full frame cache */ if (HCC_ISOC_CACHE(hcc_params)) priv->i_thresh = 8; @@ -399,13 +467,13 @@ static int isp1760_hc_setup(struct usb_hcd *hcd) * Write it twice to ensure correct upper bits if switching * to 16-bit mode. */ - isp1760_writel(hwmode, hcd->regs + HC_HW_MODE_CTRL); - isp1760_writel(hwmode, hcd->regs + HC_HW_MODE_CTRL); + reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode); + reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode); - isp1760_writel(0xdeadbabe, hcd->regs + HC_SCRATCH_REG); + reg_write32(hcd->regs, HC_SCRATCH_REG, 0xdeadbabe); /* Change bus pattern */ - scratch = isp1760_readl(hcd->regs + HC_CHIP_ID_REG); - scratch = isp1760_readl(hcd->regs + HC_SCRATCH_REG); + scratch = reg_read32(hcd->regs, HC_CHIP_ID_REG); + scratch = reg_read32(hcd->regs, HC_SCRATCH_REG); if (scratch != 0xdeadbabe) { printk(KERN_ERR "ISP1760: Scratch test failed.\n"); return -ENODEV; @@ -415,10 +483,10 @@ static int isp1760_hc_setup(struct usb_hcd *hcd) isp1760_init_regs(hcd); /* reset */ - isp1760_writel(SW_RESET_RESET_ALL, hcd->regs + HC_RESET_REG); + reg_write32(hcd->regs, HC_RESET_REG, SW_RESET_RESET_ALL); mdelay(100); - isp1760_writel(SW_RESET_RESET_HC, hcd->regs + HC_RESET_REG); + reg_write32(hcd->regs, HC_RESET_REG, SW_RESET_RESET_HC); mdelay(100); result = ehci_reset(priv); @@ -433,12 +501,12 @@ static int isp1760_hc_setup(struct usb_hcd *hcd) "analog" : "digital"); /* ATL reset */ - isp1760_writel(hwmode | ALL_ATX_RESET, hcd->regs + HC_HW_MODE_CTRL); + reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode | ALL_ATX_RESET); mdelay(10); - isp1760_writel(hwmode, hcd->regs + HC_HW_MODE_CTRL); + reg_write32(hcd->regs, HC_HW_MODE_CTRL, hwmode); - isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_REG); - isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_ENABLE); + reg_write32(hcd->regs, HC_INTERRUPT_REG, INTERRUPT_ENABLE_MASK); + reg_write32(hcd->regs, HC_INTERRUPT_ENABLE, INTERRUPT_ENABLE_MASK); /* * PORT 1 Control register of the ISP1760 is the OTG control @@ -446,11 +514,10 @@ static int isp1760_hc_setup(struct usb_hcd *hcd) * support in this driver, we use port 1 as a "normal" USB host port on * both chips. */ - isp1760_writel(PORT1_POWER | PORT1_INIT2, - hcd->regs + HC_PORT1_CTRL); + reg_write32(hcd->regs, HC_PORT1_CTRL, PORT1_POWER | PORT1_INIT2); mdelay(10); - priv->hcs_params = isp1760_readl(hcd->regs + HC_HCSPARAMS); + priv->hcs_params = reg_read32(hcd->regs, HC_HCSPARAMS); return priv_init(hcd); } @@ -458,19 +525,19 @@ static int isp1760_hc_setup(struct usb_hcd *hcd) static void isp1760_init_maps(struct usb_hcd *hcd) { /*set last maps, for iso its only 1, else 32 tds bitmap*/ - isp1760_writel(0x80000000, hcd->regs + HC_ATL_PTD_LASTPTD_REG); - isp1760_writel(0x80000000, hcd->regs + HC_INT_PTD_LASTPTD_REG); - isp1760_writel(0x00000001, hcd->regs + HC_ISO_PTD_LASTPTD_REG); + reg_write32(hcd->regs, HC_ATL_PTD_LASTPTD_REG, 0x80000000); + reg_write32(hcd->regs, HC_INT_PTD_LASTPTD_REG, 0x80000000); + reg_write32(hcd->regs, HC_ISO_PTD_LASTPTD_REG, 0x00000001); } static void isp1760_enable_interrupts(struct usb_hcd *hcd) { - isp1760_writel(0, hcd->regs + HC_ATL_IRQ_MASK_AND_REG); - isp1760_writel(0, hcd->regs + HC_ATL_IRQ_MASK_OR_REG); - isp1760_writel(0, hcd->regs + HC_INT_IRQ_MASK_AND_REG); - isp1760_writel(0, hcd->regs + HC_INT_IRQ_MASK_OR_REG); - isp1760_writel(0, hcd->regs + HC_ISO_IRQ_MASK_AND_REG); - isp1760_writel(0xffffffff, hcd->regs + HC_ISO_IRQ_MASK_OR_REG); + reg_write32(hcd->regs, HC_ATL_IRQ_MASK_AND_REG, 0); + reg_write32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG, 0); + reg_write32(hcd->regs, HC_INT_IRQ_MASK_AND_REG, 0); + reg_write32(hcd->regs, HC_INT_IRQ_MASK_OR_REG, 0); + reg_write32(hcd->regs, HC_ISO_IRQ_MASK_AND_REG, 0); + reg_write32(hcd->regs, HC_ISO_IRQ_MASK_OR_REG, 0xffffffff); /* step 23 passed */ } @@ -486,15 +553,15 @@ static int isp1760_run(struct usb_hcd *hcd) hcd->state = HC_STATE_RUNNING; isp1760_enable_interrupts(hcd); - temp = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL); - isp1760_writel(temp | HW_GLOBAL_INTR_EN, hcd->regs + HC_HW_MODE_CTRL); + temp = reg_read32(hcd->regs, HC_HW_MODE_CTRL); + reg_write32(hcd->regs, HC_HW_MODE_CTRL, temp | HW_GLOBAL_INTR_EN); - command = isp1760_readl(hcd->regs + HC_USBCMD); + command = reg_read32(hcd->regs, HC_USBCMD); command &= ~(CMD_LRESET|CMD_RESET); command |= CMD_RUN; - isp1760_writel(command, hcd->regs + HC_USBCMD); + reg_write32(hcd->regs, HC_USBCMD, command); - retval = handshake(priv, hcd->regs + HC_USBCMD, CMD_RUN, CMD_RUN, + retval = handshake(hcd, HC_USBCMD, CMD_RUN, CMD_RUN, 250 * 1000); if (retval) return retval; @@ -505,15 +572,14 @@ static int isp1760_run(struct usb_hcd *hcd) * the semaphore while doing so. */ down_write(&ehci_cf_port_reset_rwsem); - isp1760_writel(FLAG_CF, hcd->regs + HC_CONFIGFLAG); + reg_write32(hcd->regs, HC_CONFIGFLAG, FLAG_CF); - retval = handshake(priv, hcd->regs + HC_CONFIGFLAG, FLAG_CF, FLAG_CF, - 250 * 1000); + retval = handshake(hcd, HC_CONFIGFLAG, FLAG_CF, FLAG_CF, 250 * 1000); up_write(&ehci_cf_port_reset_rwsem); if (retval) return retval; - chipid = isp1760_readl(hcd->regs + HC_CHIP_ID_REG); + chipid = reg_read32(hcd->regs, HC_CHIP_ID_REG); isp1760_info(priv, "USB ISP %04x HW rev. %d started\n", chipid & 0xffff, chipid >> 16); @@ -537,87 +603,78 @@ static void transform_into_atl(struct isp1760_hcd *priv, struct isp1760_qh *qh, struct isp1760_qtd *qtd, struct urb *urb, u32 payload, struct ptd *ptd) { - u32 dw0; - u32 dw1; - u32 dw2; - u32 dw3; u32 maxpacket; u32 multi; u32 pid_code; u32 rl = RL_COUNTER; u32 nak = NAK_COUNTER; + memset(ptd, 0, sizeof(*ptd)); + /* according to 3.6.2, max packet len can not be > 0x400 */ maxpacket = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); multi = 1 + ((maxpacket >> 11) & 0x3); maxpacket &= 0x7ff; /* DW0 */ - dw0 = PTD_VALID; - dw0 |= PTD_LENGTH(qtd->length); - dw0 |= PTD_MAXPACKET(maxpacket); - dw0 |= PTD_ENDPOINT(usb_pipeendpoint(urb->pipe)); - dw1 = usb_pipeendpoint(urb->pipe) >> 1; + ptd->dw0 = PTD_VALID; + ptd->dw0 |= PTD_LENGTH(qtd->length); + ptd->dw0 |= PTD_MAXPACKET(maxpacket); + ptd->dw0 |= PTD_ENDPOINT(usb_pipeendpoint(urb->pipe)); + ptd->dw1 = usb_pipeendpoint(urb->pipe) >> 1; /* DW1 */ - dw1 |= PTD_DEVICE_ADDR(usb_pipedevice(urb->pipe)); + ptd->dw1 |= PTD_DEVICE_ADDR(usb_pipedevice(urb->pipe)); pid_code = qtd->packet_type; - dw1 |= PTD_PID_TOKEN(pid_code); + ptd->dw1 |= PTD_PID_TOKEN(pid_code); if (usb_pipebulk(urb->pipe)) - dw1 |= PTD_TRANS_BULK; + ptd->dw1 |= PTD_TRANS_BULK; else if (usb_pipeint(urb->pipe)) - dw1 |= PTD_TRANS_INT; + ptd->dw1 |= PTD_TRANS_INT; if (urb->dev->speed != USB_SPEED_HIGH) { /* split transaction */ - dw1 |= PTD_TRANS_SPLIT; + ptd->dw1 |= PTD_TRANS_SPLIT; if (urb->dev->speed == USB_SPEED_LOW) - dw1 |= PTD_SE_USB_LOSPEED; + ptd->dw1 |= PTD_SE_USB_LOSPEED; - dw1 |= PTD_PORT_NUM(urb->dev->ttport); - dw1 |= PTD_HUB_NUM(urb->dev->tt->hub->devnum); + ptd->dw1 |= PTD_PORT_NUM(urb->dev->ttport); + ptd->dw1 |= PTD_HUB_NUM(urb->dev->tt->hub->devnum); /* SE bit for Split INT transfers */ if (usb_pipeint(urb->pipe) && (urb->dev->speed == USB_SPEED_LOW)) - dw1 |= 2 << 16; + ptd->dw1 |= 2 << 16; - dw3 = 0; + ptd->dw3 = 0; rl = 0; nak = 0; } else { - dw0 |= PTD_MULTI(multi); + ptd->dw0 |= PTD_MULTI(multi); if (usb_pipecontrol(urb->pipe) || usb_pipebulk(urb->pipe)) - dw3 = qh->ping; + ptd->dw3 = qh->ping; else - dw3 = 0; + ptd->dw3 = 0; } /* DW2 */ - dw2 = 0; - dw2 |= PTD_DATA_START_ADDR(base_to_chip(payload)); - dw2 |= PTD_RL_CNT(rl); - dw3 |= PTD_NAC_CNT(nak); + ptd->dw2 = 0; + ptd->dw2 |= PTD_DATA_START_ADDR(base_to_chip(payload)); + ptd->dw2 |= PTD_RL_CNT(rl); + ptd->dw3 |= PTD_NAC_CNT(nak); /* DW3 */ if (usb_pipecontrol(urb->pipe)) - dw3 |= PTD_DATA_TOGGLE(qtd->toggle); + ptd->dw3 |= PTD_DATA_TOGGLE(qtd->toggle); else - dw3 |= qh->toggle; + ptd->dw3 |= qh->toggle; - dw3 |= PTD_ACTIVE; + ptd->dw3 |= PTD_ACTIVE; /* Cerr */ - dw3 |= PTD_CERR(ERR_COUNTER); - - memset(ptd, 0, sizeof(*ptd)); - - ptd->dw0 = cpu_to_le32(dw0); - ptd->dw1 = cpu_to_le32(dw1); - ptd->dw2 = cpu_to_le32(dw2); - ptd->dw3 = cpu_to_le32(dw3); + ptd->dw3 |= PTD_CERR(ERR_COUNTER); } static void transform_add_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, @@ -650,7 +707,7 @@ static void transform_add_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, if (urb->dev->speed != USB_SPEED_HIGH) { /* split */ - ptd->dw5 = cpu_to_le32(0x1c); + ptd->dw5 = 0x1c; if (qh->period >= 32) period = qh->period / 2; @@ -677,8 +734,8 @@ static void transform_add_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, } } - ptd->dw2 |= cpu_to_le32(period); - ptd->dw4 = cpu_to_le32(usof); + ptd->dw2 |= period; + ptd->dw4 = usof; } static void transform_into_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, @@ -710,20 +767,18 @@ static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len, static int check_error(struct ptd *ptd) { int error = 0; - u32 dw3; - dw3 = le32_to_cpu(ptd->dw3); - if (dw3 & DW3_HALT_BIT) { + if (ptd->dw3 & DW3_HALT_BIT) { error = -EPIPE; - if (dw3 & DW3_ERROR_BIT) + if (ptd->dw3 & DW3_ERROR_BIT) pr_err("error bit is set in DW3\n"); } - if (dw3 & DW3_QTD_ACTIVE) { + if (ptd->dw3 & DW3_QTD_ACTIVE) { printk(KERN_ERR "transfer active bit is set DW3\n"); - printk(KERN_ERR "nak counter: %d, rl: %d\n", (dw3 >> 19) & 0xf, - (le32_to_cpu(ptd->dw2) >> 25) & 0xf); + printk(KERN_ERR "nak counter: %d, rl: %d\n", + (ptd->dw3 >> 19) & 0xf, (ptd->dw2 >> 25) & 0xf); } return error; @@ -767,14 +822,13 @@ static void enqueue_one_qtd(struct isp1760_qtd *qtd, struct isp1760_hcd *priv, break; case OUT_PID: case SETUP_PID: - priv_write_copy(priv, qtd->data_buffer, - hcd->regs + payload, - qtd->length); + mem_writes8(hcd->regs, payload, qtd->data_buffer, + qtd->length); } } } -static void enqueue_one_atl_qtd(u32 atl_regs, u32 payload, +static void enqueue_one_atl_qtd(u32 payload, struct isp1760_hcd *priv, struct isp1760_qh *qh, struct urb *urb, u32 slot, struct isp1760_qtd *qtd) { @@ -782,7 +836,7 @@ static void enqueue_one_atl_qtd(u32 atl_regs, u32 payload, struct usb_hcd *hcd = priv_to_hcd(priv); transform_into_atl(priv, qh, qtd, urb, payload, &ptd); - priv_write_copy(priv, (u32 *)&ptd, hcd->regs + atl_regs, sizeof(ptd)); + ptd_write(hcd->regs, ATL_PTD_OFFSET, slot, &ptd); enqueue_one_qtd(qtd, priv, payload); priv->atl_ints[slot].urb = urb; @@ -794,7 +848,7 @@ static void enqueue_one_atl_qtd(u32 atl_regs, u32 payload, qtd->status |= slot << 16; } -static void enqueue_one_int_qtd(u32 int_regs, u32 payload, +static void enqueue_one_int_qtd(u32 payload, struct isp1760_hcd *priv, struct isp1760_qh *qh, struct urb *urb, u32 slot, struct isp1760_qtd *qtd) { @@ -802,7 +856,7 @@ static void enqueue_one_int_qtd(u32 int_regs, u32 payload, struct usb_hcd *hcd = priv_to_hcd(priv); transform_into_int(priv, qh, qtd, urb, payload, &ptd); - priv_write_copy(priv, (u32 *)&ptd, hcd->regs + int_regs, sizeof(ptd)); + ptd_write(hcd->regs, INT_PTD_OFFSET, slot, &ptd); enqueue_one_qtd(qtd, priv, payload); priv->int_ints[slot].urb = urb; @@ -821,7 +875,7 @@ static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, u32 skip_map, or_map; u32 queue_entry; u32 slot; - u32 atl_regs, payload; + u32 payload; u32 buffstatus; /* @@ -832,33 +886,31 @@ static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, */ mmiowb(); ndelay(195); - skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG); + skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG); BUG_ON(!skip_map); slot = __ffs(skip_map); queue_entry = 1 << slot; - atl_regs = ATL_REGS_OFFSET + slot * sizeof(struct ptd); - payload = alloc_mem(priv, qtd->length); - enqueue_one_atl_qtd(atl_regs, payload, priv, qh, qtd->urb, slot, qtd); + enqueue_one_atl_qtd(payload, priv, qh, qtd->urb, slot, qtd); - or_map = isp1760_readl(hcd->regs + HC_ATL_IRQ_MASK_OR_REG); + or_map = reg_read32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG); or_map |= queue_entry; - isp1760_writel(or_map, hcd->regs + HC_ATL_IRQ_MASK_OR_REG); + reg_write32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG, or_map); skip_map &= ~queue_entry; - isp1760_writel(skip_map, hcd->regs + HC_ATL_PTD_SKIPMAP_REG); + reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, skip_map); priv->atl_queued++; if (priv->atl_queued == 2) - isp1760_writel(INTERRUPT_ENABLE_SOT_MASK, - hcd->regs + HC_INTERRUPT_ENABLE); + reg_write32(hcd->regs, HC_INTERRUPT_ENABLE, + INTERRUPT_ENABLE_SOT_MASK); - buffstatus = isp1760_readl(hcd->regs + HC_BUFFER_STATUS_REG); + buffstatus = reg_read32(hcd->regs, HC_BUFFER_STATUS_REG); buffstatus |= ATL_BUFFER; - isp1760_writel(buffstatus, hcd->regs + HC_BUFFER_STATUS_REG); + reg_write32(hcd->regs, HC_BUFFER_STATUS_REG, buffstatus); } static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, @@ -868,7 +920,7 @@ static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, u32 skip_map, or_map; u32 queue_entry; u32 slot; - u32 int_regs, payload; + u32 payload; u32 buffstatus; /* @@ -879,31 +931,30 @@ static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, */ mmiowb(); ndelay(195); - skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG); + skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG); BUG_ON(!skip_map); slot = __ffs(skip_map); queue_entry = 1 << slot; - int_regs = INT_REGS_OFFSET + slot * sizeof(struct ptd); - payload = alloc_mem(priv, qtd->length); - enqueue_one_int_qtd(int_regs, payload, priv, qh, qtd->urb, slot, qtd); + enqueue_one_int_qtd(payload, priv, qh, qtd->urb, slot, qtd); - or_map = isp1760_readl(hcd->regs + HC_INT_IRQ_MASK_OR_REG); + or_map = reg_read32(hcd->regs, HC_INT_IRQ_MASK_OR_REG); or_map |= queue_entry; - isp1760_writel(or_map, hcd->regs + HC_INT_IRQ_MASK_OR_REG); + reg_write32(hcd->regs, HC_INT_IRQ_MASK_OR_REG, or_map); skip_map &= ~queue_entry; - isp1760_writel(skip_map, hcd->regs + HC_INT_PTD_SKIPMAP_REG); + reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, skip_map); - buffstatus = isp1760_readl(hcd->regs + HC_BUFFER_STATUS_REG); + buffstatus = reg_read32(hcd->regs, HC_BUFFER_STATUS_REG); buffstatus |= INT_BUFFER; - isp1760_writel(buffstatus, hcd->regs + HC_BUFFER_STATUS_REG); + reg_write32(hcd->regs, HC_BUFFER_STATUS_REG, buffstatus); } -static void isp1760_urb_done(struct isp1760_hcd *priv, struct urb *urb, int status) +static void isp1760_urb_done(struct isp1760_hcd *priv, struct urb *urb, + int status) __releases(priv->lock) __acquires(priv->lock) { @@ -963,14 +1014,12 @@ static struct isp1760_qtd *clean_up_qtdlist(struct isp1760_qtd *qtd) return qtd; } -static void do_atl_int(struct usb_hcd *usb_hcd) +static void do_atl_int(struct usb_hcd *hcd) { - struct isp1760_hcd *priv = hcd_to_priv(usb_hcd); + struct isp1760_hcd *priv = hcd_to_priv(hcd); u32 done_map, skip_map; struct ptd ptd; struct urb *urb = NULL; - u32 atl_regs_base; - u32 atl_regs; u32 queue_entry; u32 payload; u32 length; @@ -982,21 +1031,14 @@ static void do_atl_int(struct usb_hcd *usb_hcd) u32 rl; u32 nakcount; - done_map = isp1760_readl(usb_hcd->regs + - HC_ATL_PTD_DONEMAP_REG); - skip_map = isp1760_readl(usb_hcd->regs + - HC_ATL_PTD_SKIPMAP_REG); + done_map = reg_read32(hcd->regs, HC_ATL_PTD_DONEMAP_REG); + skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG); - or_map = isp1760_readl(usb_hcd->regs + HC_ATL_IRQ_MASK_OR_REG); + or_map = reg_read32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG); or_map &= ~done_map; - isp1760_writel(or_map, usb_hcd->regs + HC_ATL_IRQ_MASK_OR_REG); + reg_write32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG, or_map); - atl_regs_base = ATL_REGS_OFFSET; while (done_map) { - u32 dw1; - u32 dw2; - u32 dw3; - status = 0; priv->atl_queued--; @@ -1004,8 +1046,6 @@ static void do_atl_int(struct usb_hcd *usb_hcd) done_map &= ~(1 << queue_entry); skip_map |= 1 << queue_entry; - atl_regs = atl_regs_base + queue_entry * sizeof(struct ptd); - urb = priv->atl_ints[queue_entry].urb; qtd = priv->atl_ints[queue_entry].qtd; qh = priv->atl_ints[queue_entry].qh; @@ -1015,30 +1055,14 @@ static void do_atl_int(struct usb_hcd *usb_hcd) printk(KERN_ERR "qh is 0\n"); continue; } - isp1760_writel(atl_regs + ISP_BANK(0), usb_hcd->regs + - HC_MEMORY_REG); - isp1760_writel(payload + ISP_BANK(1), usb_hcd->regs + - HC_MEMORY_REG); - /* - * write bank1 address twice to ensure the 90ns delay (time - * between BANK0 write and the priv_read_copy() call is at - * least 3*t_WHWL + 2*t_w11 = 3*25ns + 2*17ns = 109ns) - */ - isp1760_writel(payload + ISP_BANK(1), usb_hcd->regs + - HC_MEMORY_REG); + ptd_read(hcd->regs, ATL_PTD_OFFSET, queue_entry, &ptd); - priv_read_copy(priv, (u32 *)&ptd, usb_hcd->regs + atl_regs + - ISP_BANK(0), sizeof(ptd)); - - dw1 = le32_to_cpu(ptd.dw1); - dw2 = le32_to_cpu(ptd.dw2); - dw3 = le32_to_cpu(ptd.dw3); - rl = (dw2 >> 25) & 0x0f; - nakcount = (dw3 >> 19) & 0xf; + rl = (ptd.dw2 >> 25) & 0x0f; + nakcount = (ptd.dw3 >> 19) & 0xf; /* Transfer Error, *but* active and no HALT -> reload */ - if ((dw3 & DW3_ERROR_BIT) && (dw3 & DW3_QTD_ACTIVE) && - !(dw3 & DW3_HALT_BIT)) { + if ((ptd.dw3 & DW3_ERROR_BIT) && (ptd.dw3 & DW3_QTD_ACTIVE) && + !(ptd.dw3 & DW3_HALT_BIT)) { /* according to ppriv code, we have to * reload this one if trasfered bytes != requested bytes @@ -1047,13 +1071,13 @@ static void do_atl_int(struct usb_hcd *usb_hcd) * triggered so far. */ - length = PTD_XFERRED_LENGTH(dw3); + length = PTD_XFERRED_LENGTH(ptd.dw3); printk(KERN_ERR "Should reload now.... transfered %d " "of %zu\n", length, qtd->length); BUG(); } - if (!nakcount && (dw3 & DW3_QTD_ACTIVE)) { + if (!nakcount && (ptd.dw3 & DW3_QTD_ACTIVE)) { u32 buffstatus; /* @@ -1063,10 +1087,10 @@ static void do_atl_int(struct usb_hcd *usb_hcd) */ /* RL counter = ERR counter */ - dw3 &= ~(0xf << 19); - dw3 |= rl << 19; - dw3 &= ~(3 << (55 - 32)); - dw3 |= ERR_COUNTER << (55 - 32); + ptd.dw3 &= ~(0xf << 19); + ptd.dw3 |= rl << 19; + ptd.dw3 &= ~(3 << (55 - 32)); + ptd.dw3 |= ERR_COUNTER << (55 - 32); /* * It is not needed to write skip map back because it @@ -1074,30 +1098,23 @@ static void do_atl_int(struct usb_hcd *usb_hcd) * unskipped once it gets written to the HW. */ skip_map &= ~(1 << queue_entry); - or_map = isp1760_readl(usb_hcd->regs + - HC_ATL_IRQ_MASK_OR_REG); + or_map = reg_read32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG); or_map |= 1 << queue_entry; - isp1760_writel(or_map, usb_hcd->regs + - HC_ATL_IRQ_MASK_OR_REG); - - ptd.dw3 = cpu_to_le32(dw3); - priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + - atl_regs, sizeof(ptd)); + reg_write32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG, or_map); - ptd.dw0 |= cpu_to_le32(PTD_VALID); - priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + - atl_regs, sizeof(ptd)); + ptd.dw0 |= PTD_VALID; + ptd_write(hcd->regs, ATL_PTD_OFFSET, queue_entry, &ptd); priv->atl_queued++; if (priv->atl_queued == 2) - isp1760_writel(INTERRUPT_ENABLE_SOT_MASK, - usb_hcd->regs + HC_INTERRUPT_ENABLE); + reg_write32(hcd->regs, HC_INTERRUPT_ENABLE, + INTERRUPT_ENABLE_SOT_MASK); - buffstatus = isp1760_readl(usb_hcd->regs + - HC_BUFFER_STATUS_REG); + buffstatus = reg_read32(hcd->regs, + HC_BUFFER_STATUS_REG); buffstatus |= ATL_BUFFER; - isp1760_writel(buffstatus, usb_hcd->regs + - HC_BUFFER_STATUS_REG); + reg_write32(hcd->regs, HC_BUFFER_STATUS_REG, + buffstatus); continue; } @@ -1118,20 +1135,19 @@ static void do_atl_int(struct usb_hcd *usb_hcd) #endif } else { if (usb_pipetype(urb->pipe) == PIPE_BULK) { - priv->atl_ints[queue_entry].qh->toggle = dw3 & - (1 << 25); - priv->atl_ints[queue_entry].qh->ping = dw3 & - (1 << 26); + priv->atl_ints[queue_entry].qh->toggle = + ptd.dw3 & (1 << 25); + priv->atl_ints[queue_entry].qh->ping = + ptd.dw3 & (1 << 26); } } - length = PTD_XFERRED_LENGTH(dw3); + length = PTD_XFERRED_LENGTH(ptd.dw3); if (length) { - switch (DW1_GET_PID(dw1)) { + switch (DW1_GET_PID(ptd.dw1)) { case IN_PID: - priv_read_copy(priv, + mem_reads8(hcd->regs, payload, priv->atl_ints[queue_entry].data_buffer, - usb_hcd->regs + payload + ISP_BANK(1), length); case OUT_PID: @@ -1150,8 +1166,7 @@ static void do_atl_int(struct usb_hcd *usb_hcd) free_mem(priv, payload); - isp1760_writel(skip_map, usb_hcd->regs + - HC_ATL_PTD_SKIPMAP_REG); + reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, skip_map); if (urb->status == -EPIPE) { /* HALT was received */ @@ -1193,24 +1208,21 @@ static void do_atl_int(struct usb_hcd *usb_hcd) } if (qtd) - enqueue_an_ATL_packet(usb_hcd, qh, qtd); + enqueue_an_ATL_packet(hcd, qh, qtd); - skip_map = isp1760_readl(usb_hcd->regs + - HC_ATL_PTD_SKIPMAP_REG); + skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG); } if (priv->atl_queued <= 1) - isp1760_writel(INTERRUPT_ENABLE_MASK, - usb_hcd->regs + HC_INTERRUPT_ENABLE); + reg_write32(hcd->regs, HC_INTERRUPT_ENABLE, + INTERRUPT_ENABLE_MASK); } -static void do_intl_int(struct usb_hcd *usb_hcd) +static void do_intl_int(struct usb_hcd *hcd) { - struct isp1760_hcd *priv = hcd_to_priv(usb_hcd); + struct isp1760_hcd *priv = hcd_to_priv(hcd); u32 done_map, skip_map; struct ptd ptd; struct urb *urb = NULL; - u32 int_regs; - u32 int_regs_base; u32 payload; u32 length; u32 or_map; @@ -1219,26 +1231,18 @@ static void do_intl_int(struct usb_hcd *usb_hcd) struct isp1760_qtd *qtd; struct isp1760_qh *qh; - done_map = isp1760_readl(usb_hcd->regs + - HC_INT_PTD_DONEMAP_REG); - skip_map = isp1760_readl(usb_hcd->regs + - HC_INT_PTD_SKIPMAP_REG); + done_map = reg_read32(hcd->regs, HC_INT_PTD_DONEMAP_REG); + skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG); - or_map = isp1760_readl(usb_hcd->regs + HC_INT_IRQ_MASK_OR_REG); + or_map = reg_read32(hcd->regs, HC_INT_IRQ_MASK_OR_REG); or_map &= ~done_map; - isp1760_writel(or_map, usb_hcd->regs + HC_INT_IRQ_MASK_OR_REG); - - int_regs_base = INT_REGS_OFFSET; + reg_write32(hcd->regs, HC_INT_IRQ_MASK_OR_REG, or_map); while (done_map) { - u32 dw1; - u32 dw3; - queue_entry = __ffs(done_map); done_map &= ~(1 << queue_entry); skip_map |= 1 << queue_entry; - int_regs = int_regs_base + queue_entry * sizeof(struct ptd); urb = priv->int_ints[queue_entry].urb; qtd = priv->int_ints[queue_entry].qtd; qh = priv->int_ints[queue_entry].qh; @@ -1249,23 +1253,8 @@ static void do_intl_int(struct usb_hcd *usb_hcd) continue; } - isp1760_writel(int_regs + ISP_BANK(0), usb_hcd->regs + - HC_MEMORY_REG); - isp1760_writel(payload + ISP_BANK(1), usb_hcd->regs + - HC_MEMORY_REG); - /* - * write bank1 address twice to ensure the 90ns delay (time - * between BANK0 write and the priv_read_copy() call is at - * least 3*t_WHWL + 2*t_w11 = 3*25ns + 2*17ns = 92ns) - */ - isp1760_writel(payload + ISP_BANK(1), usb_hcd->regs + - HC_MEMORY_REG); - - priv_read_copy(priv, (u32 *)&ptd, usb_hcd->regs + int_regs + - ISP_BANK(0), sizeof(ptd)); - dw1 = le32_to_cpu(ptd.dw1); - dw3 = le32_to_cpu(ptd.dw3); - check_int_err_status(le32_to_cpu(ptd.dw4)); + ptd_read(hcd->regs, INT_PTD_OFFSET, queue_entry, &ptd); + check_int_err_status(ptd.dw4); error = check_error(&ptd); if (error) { @@ -1283,21 +1272,21 @@ static void do_intl_int(struct usb_hcd *usb_hcd) } else { priv->int_ints[queue_entry].qh->toggle = - dw3 & (1 << 25); - priv->int_ints[queue_entry].qh->ping = dw3 & (1 << 26); + ptd.dw3 & (1 << 25); + priv->int_ints[queue_entry].qh->ping = + ptd.dw3 & (1 << 26); } if (urb->dev->speed != USB_SPEED_HIGH) - length = PTD_XFERRED_LENGTH_LO(dw3); + length = PTD_XFERRED_LENGTH_LO(ptd.dw3); else - length = PTD_XFERRED_LENGTH(dw3); + length = PTD_XFERRED_LENGTH(ptd.dw3); if (length) { - switch (DW1_GET_PID(dw1)) { + switch (DW1_GET_PID(ptd.dw1)) { case IN_PID: - priv_read_copy(priv, + mem_reads8(hcd->regs, payload, priv->int_ints[queue_entry].data_buffer, - usb_hcd->regs + payload + ISP_BANK(1), length); case OUT_PID: @@ -1313,8 +1302,7 @@ static void do_intl_int(struct usb_hcd *usb_hcd) priv->int_ints[queue_entry].qtd = NULL; priv->int_ints[queue_entry].qh = NULL; - isp1760_writel(skip_map, usb_hcd->regs + - HC_INT_PTD_SKIPMAP_REG); + reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, skip_map); free_mem(priv, payload); if (urb->status == -EPIPE) { @@ -1339,10 +1327,9 @@ static void do_intl_int(struct usb_hcd *usb_hcd) } if (qtd) - enqueue_an_INT_packet(usb_hcd, qh, qtd); + enqueue_an_INT_packet(hcd, qh, qtd); - skip_map = isp1760_readl(usb_hcd->regs + - HC_INT_PTD_SKIPMAP_REG); + skip_map = reg_read32(hcd->regs, HC_INT_PTD_SKIPMAP_REG); } } @@ -1691,7 +1678,7 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, case PIPE_INTERRUPT: ints = priv->int_ints; - reg_base = INT_REGS_OFFSET; + reg_base = INT_PTD_OFFSET; or_reg = HC_INT_IRQ_MASK_OR_REG; skip_reg = HC_INT_PTD_SKIPMAP_REG; pe = enqueue_an_INT_packet; @@ -1699,7 +1686,7 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, default: ints = priv->atl_ints; - reg_base = ATL_REGS_OFFSET; + reg_base = ATL_PTD_OFFSET; or_reg = HC_ATL_IRQ_MASK_OR_REG; skip_reg = HC_ATL_PTD_SKIPMAP_REG; pe = enqueue_an_ATL_packet; @@ -1716,16 +1703,16 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, struct isp1760_qtd *qtd; struct isp1760_qh *qh = ints->qh; - skip_map = isp1760_readl(hcd->regs + skip_reg); + skip_map = reg_read32(hcd->regs, skip_reg); skip_map |= 1 << i; - isp1760_writel(skip_map, hcd->regs + skip_reg); + reg_write32(hcd->regs, skip_reg, skip_map); - or_map = isp1760_readl(hcd->regs + or_reg); + or_map = reg_read32(hcd->regs, or_reg); or_map &= ~(1 << i); - isp1760_writel(or_map, hcd->regs + or_reg); + reg_write32(hcd->regs, or_reg, or_map); + + ptd_write(hcd->regs, reg_base, i, &ptd); - priv_write_copy(priv, (u32 *)&ptd, hcd->regs + reg_base - + i * sizeof(ptd), sizeof(ptd)); qtd = ints->qtd; qtd = clean_up_qtdlist(qtd); @@ -1747,7 +1734,8 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, for (qtd = ints->qtd->hw_next; qtd; qtd = qtd->hw_next) { if (qtd->urb == urb) { - prev_qtd->hw_next = clean_up_qtdlist(qtd); + prev_qtd->hw_next = + clean_up_qtdlist(qtd); isp1760_urb_done(priv, urb, status); break; } @@ -1775,11 +1763,11 @@ static irqreturn_t isp1760_irq(struct usb_hcd *usb_hcd) if (!(usb_hcd->state & HC_STATE_RUNNING)) goto leave; - imask = isp1760_readl(usb_hcd->regs + HC_INTERRUPT_REG); + imask = reg_read32(usb_hcd->regs, HC_INTERRUPT_REG); if (unlikely(!imask)) goto leave; - isp1760_writel(imask, usb_hcd->regs + HC_INTERRUPT_REG); + reg_write32(usb_hcd->regs, HC_INTERRUPT_REG, imask); if (imask & (HC_ATL_INT | HC_SOT_INT)) do_atl_int(usb_hcd); @@ -1809,12 +1797,12 @@ static int isp1760_hub_status_data(struct usb_hcd *hcd, char *buf) mask = PORT_CSC; spin_lock_irqsave(&priv->lock, flags); - temp = isp1760_readl(hcd->regs + HC_PORTSC1); + temp = reg_read32(hcd->regs, HC_PORTSC1); if (temp & PORT_OWNER) { if (temp & PORT_CSC) { temp &= ~PORT_CSC; - isp1760_writel(temp, hcd->regs + HC_PORTSC1); + reg_write32(hcd->regs, HC_PORTSC1, temp); goto done; } } @@ -1871,8 +1859,8 @@ static void isp1760_hub_descriptor(struct isp1760_hcd *priv, #define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E) -static int check_reset_complete(struct isp1760_hcd *priv, int index, - u32 __iomem *status_reg, int port_status) +static int check_reset_complete(struct usb_hcd *hcd, int index, + int port_status) { if (!(port_status & PORT_CONNECT)) return port_status; @@ -1885,7 +1873,7 @@ static int check_reset_complete(struct isp1760_hcd *priv, int index, port_status |= PORT_OWNER; port_status &= ~PORT_RWC_BITS; - isp1760_writel(port_status, status_reg); + reg_write32(hcd->regs, HC_PORTSC1, port_status); } else printk(KERN_ERR "port %d high speed\n", index + 1); @@ -1898,7 +1886,6 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, { struct isp1760_hcd *priv = hcd_to_priv(hcd); int ports = HCS_N_PORTS(priv->hcs_params); - u32 __iomem *status_reg = hcd->regs + HC_PORTSC1; u32 temp, status; unsigned long flags; int retval = 0; @@ -1927,7 +1914,7 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, if (!wIndex || wIndex > ports) goto error; wIndex--; - temp = isp1760_readl(status_reg); + temp = reg_read32(hcd->regs, HC_PORTSC1); /* * Even if OWNER is set, so the port is owned by the @@ -1938,7 +1925,7 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, switch (wValue) { case USB_PORT_FEAT_ENABLE: - isp1760_writel(temp & ~PORT_PE, status_reg); + reg_write32(hcd->regs, HC_PORTSC1, temp & ~PORT_PE); break; case USB_PORT_FEAT_C_ENABLE: /* XXX error? */ @@ -1952,8 +1939,8 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, goto error; /* resume signaling for 20 msec */ temp &= ~(PORT_RWC_BITS); - isp1760_writel(temp | PORT_RESUME, - status_reg); + reg_write32(hcd->regs, HC_PORTSC1, + temp | PORT_RESUME); priv->reset_done = jiffies + msecs_to_jiffies(20); } @@ -1963,11 +1950,11 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, break; case USB_PORT_FEAT_POWER: if (HCS_PPC(priv->hcs_params)) - isp1760_writel(temp & ~PORT_POWER, status_reg); + reg_write32(hcd->regs, HC_PORTSC1, + temp & ~PORT_POWER); break; case USB_PORT_FEAT_C_CONNECTION: - isp1760_writel(temp | PORT_CSC, - status_reg); + reg_write32(hcd->regs, HC_PORTSC1, temp | PORT_CSC); break; case USB_PORT_FEAT_C_OVER_CURRENT: /* XXX error ?*/ @@ -1978,7 +1965,7 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, default: goto error; } - isp1760_readl(hcd->regs + HC_USBCMD); + reg_read32(hcd->regs, HC_USBCMD); break; case GetHubDescriptor: isp1760_hub_descriptor(priv, (struct usb_hub_descriptor *) @@ -1993,7 +1980,7 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, goto error; wIndex--; status = 0; - temp = isp1760_readl(status_reg); + temp = reg_read32(hcd->regs, HC_PORTSC1); /* wPortChange bits */ if (temp & PORT_CSC) @@ -2021,11 +2008,10 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, priv->reset_done = 0; /* stop resume signaling */ - temp = isp1760_readl(status_reg); - isp1760_writel( - temp & ~(PORT_RWC_BITS | PORT_RESUME), - status_reg); - retval = handshake(priv, status_reg, + temp = reg_read32(hcd->regs, HC_PORTSC1); + reg_write32(hcd->regs, HC_PORTSC1, + temp & ~(PORT_RWC_BITS | PORT_RESUME)); + retval = handshake(hcd, HC_PORTSC1, PORT_RESUME, 0, 2000 /* 2msec */); if (retval != 0) { isp1760_err(priv, @@ -2045,12 +2031,11 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, priv->reset_done = 0; /* force reset to complete */ - isp1760_writel(temp & ~PORT_RESET, - status_reg); + reg_write32(hcd->regs, HC_PORTSC1, temp & ~PORT_RESET); /* REVISIT: some hardware needs 550+ usec to clear * this bit; seems too long to spin routinely... */ - retval = handshake(priv, status_reg, + retval = handshake(hcd, HC_PORTSC1, PORT_RESET, 0, 750); if (retval != 0) { isp1760_err(priv, "port %d reset error %d\n", @@ -2059,8 +2044,8 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, } /* see what we found out */ - temp = check_reset_complete(priv, wIndex, status_reg, - isp1760_readl(status_reg)); + temp = check_reset_complete(hcd, wIndex, + reg_read32(hcd->regs, HC_PORTSC1)); } /* * Even if OWNER is set, there's no harm letting khubd @@ -2103,14 +2088,14 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, if (!wIndex || wIndex > ports) goto error; wIndex--; - temp = isp1760_readl(status_reg); + temp = reg_read32(hcd->regs, HC_PORTSC1); if (temp & PORT_OWNER) break; /* temp &= ~PORT_RWC_BITS; */ switch (wValue) { case USB_PORT_FEAT_ENABLE: - isp1760_writel(temp | PORT_PE, status_reg); + reg_write32(hcd->regs, HC_PORTSC1, temp | PORT_PE); break; case USB_PORT_FEAT_SUSPEND: @@ -2118,12 +2103,12 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, || (temp & PORT_RESET) != 0) goto error; - isp1760_writel(temp | PORT_SUSPEND, status_reg); + reg_write32(hcd->regs, HC_PORTSC1, temp | PORT_SUSPEND); break; case USB_PORT_FEAT_POWER: if (HCS_PPC(priv->hcs_params)) - isp1760_writel(temp | PORT_POWER, - status_reg); + reg_write32(hcd->regs, HC_PORTSC1, + temp | PORT_POWER); break; case USB_PORT_FEAT_RESET: if (temp & PORT_RESUME) @@ -2146,12 +2131,12 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, priv->reset_done = jiffies + msecs_to_jiffies(50); } - isp1760_writel(temp, status_reg); + reg_write32(hcd->regs, HC_PORTSC1, temp); break; default: goto error; } - isp1760_readl(hcd->regs + HC_USBCMD); + reg_read32(hcd->regs, HC_USBCMD); break; default: @@ -2213,7 +2198,7 @@ static int isp1760_get_frame(struct usb_hcd *hcd) struct isp1760_hcd *priv = hcd_to_priv(hcd); u32 fr; - fr = isp1760_readl(hcd->regs + HC_FRINDEX); + fr = reg_read32(hcd->regs, HC_FRINDEX); return (fr >> 3) % priv->periodic_size; } @@ -2229,11 +2214,11 @@ static void isp1760_stop(struct usb_hcd *hcd) spin_lock_irq(&priv->lock); ehci_reset(priv); /* Disable IRQ */ - temp = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL); - isp1760_writel(temp &= ~HW_GLOBAL_INTR_EN, hcd->regs + HC_HW_MODE_CTRL); + temp = reg_read32(hcd->regs, HC_HW_MODE_CTRL); + reg_write32(hcd->regs, HC_HW_MODE_CTRL, temp &= ~HW_GLOBAL_INTR_EN); spin_unlock_irq(&priv->lock); - isp1760_writel(0, hcd->regs + HC_CONFIGFLAG); + reg_write32(hcd->regs, HC_CONFIGFLAG, 0); } static void isp1760_shutdown(struct usb_hcd *hcd) @@ -2241,12 +2226,12 @@ static void isp1760_shutdown(struct usb_hcd *hcd) u32 command, temp; isp1760_stop(hcd); - temp = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL); - isp1760_writel(temp &= ~HW_GLOBAL_INTR_EN, hcd->regs + HC_HW_MODE_CTRL); + temp = reg_read32(hcd->regs, HC_HW_MODE_CTRL); + reg_write32(hcd->regs, HC_HW_MODE_CTRL, temp &= ~HW_GLOBAL_INTR_EN); - command = isp1760_readl(hcd->regs + HC_USBCMD); + command = reg_read32(hcd->regs, HC_USBCMD); command &= ~CMD_RUN; - isp1760_writel(command, hcd->regs + HC_USBCMD); + reg_write32(hcd->regs, HC_USBCMD, command); } static const struct hc_driver isp1760_hc_driver = { diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h index 612bce5dce03..c01c59171bc7 100644 --- a/drivers/usb/host/isp1760-hcd.h +++ b/drivers/usb/host/isp1760-hcd.h @@ -84,30 +84,27 @@ void deinit_kmem_cache(void); #define HC_INT_IRQ_MASK_AND_REG 0x328 #define HC_ATL_IRQ_MASK_AND_REG 0x32C -/* Register sets */ -#define HC_BEGIN_OF_ATL 0x0c00 -#define HC_BEGIN_OF_INT 0x0800 -#define HC_BEGIN_OF_ISO 0x0400 -#define HC_BEGIN_OF_PAYLOAD 0x1000 - /* urb state*/ #define DELETE_URB (0x0008) #define NO_TRANSFER_ACTIVE (0xffffffff) -#define ATL_REGS_OFFSET (0xc00) -#define INT_REGS_OFFSET (0x800) - -/* Philips Transfer Descriptor (PTD) */ +/* Philips Proprietary Transfer Descriptor (PTD) */ +typedef __u32 __bitwise __dw; struct ptd { - __le32 dw0; - __le32 dw1; - __le32 dw2; - __le32 dw3; - __le32 dw4; - __le32 dw5; - __le32 dw6; - __le32 dw7; + __dw dw0; + __dw dw1; + __dw dw2; + __dw dw3; + __dw dw4; + __dw dw5; + __dw dw6; + __dw dw7; }; +#define PTD_OFFSET 0x0400 +#define ISO_PTD_OFFSET 0x0400 +#define INT_PTD_OFFSET 0x0800 +#define ATL_PTD_OFFSET 0x0c00 +#define PAYLOAD_OFFSET 0x1000 struct inter_packet_info { void *data_buffer; -- cgit v1.2.3 From fd436aee97d157ff6441e7aaff2a2dc802765b5b Mon Sep 17 00:00:00 2001 From: Arvid Brodin Date: Sat, 26 Feb 2011 22:03:49 +0100 Subject: usb/isp1760: Remove redundant variables and defines Removes the redundant hw_next list pointer from struct isp1760_qtd, removes some unused #defines, removes redundant "urb" member from struct inter_packet_info. Signed-off-by: Arvid Brodin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp1760-hcd.c | 126 +++++++++++++++++++---------------------- drivers/usb/host/isp1760-hcd.h | 1 - 2 files changed, 58 insertions(+), 69 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 47ce0373a3c9..2342f11d0f30 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -81,7 +81,6 @@ static inline struct usb_hcd *priv_to_hcd(struct isp1760_hcd *priv) #define PORT_RWC_BITS (PORT_CSC) struct isp1760_qtd { - struct isp1760_qtd *hw_next; u8 packet_type; u8 toggle; @@ -93,10 +92,7 @@ struct isp1760_qtd { /* isp special*/ u32 status; -#define URB_COMPLETE_NOTIFY (1 << 0) #define URB_ENQUEUED (1 << 1) -#define URB_TYPE_ATL (1 << 2) -#define URB_TYPE_INT (1 << 3) }; struct isp1760_qh { @@ -839,12 +835,11 @@ static void enqueue_one_atl_qtd(u32 payload, ptd_write(hcd->regs, ATL_PTD_OFFSET, slot, &ptd); enqueue_one_qtd(qtd, priv, payload); - priv->atl_ints[slot].urb = urb; priv->atl_ints[slot].qh = qh; priv->atl_ints[slot].qtd = qtd; priv->atl_ints[slot].data_buffer = qtd->data_buffer; priv->atl_ints[slot].payload = payload; - qtd->status |= URB_ENQUEUED | URB_TYPE_ATL; + qtd->status |= URB_ENQUEUED; qtd->status |= slot << 16; } @@ -859,12 +854,11 @@ static void enqueue_one_int_qtd(u32 payload, ptd_write(hcd->regs, INT_PTD_OFFSET, slot, &ptd); enqueue_one_qtd(qtd, priv, payload); - priv->int_ints[slot].urb = urb; priv->int_ints[slot].qh = qh; priv->int_ints[slot].qtd = qtd; priv->int_ints[slot].data_buffer = qtd->data_buffer; priv->int_ints[slot].payload = payload; - qtd->status |= URB_ENQUEUED | URB_TYPE_INT; + qtd->status |= URB_ENQUEUED; qtd->status |= slot << 16; } @@ -983,11 +977,16 @@ static void isp1760_qtd_free(struct isp1760_qtd *qtd) kmem_cache_free(qtd_cachep, qtd); } -static struct isp1760_qtd *clean_this_qtd(struct isp1760_qtd *qtd) +static struct isp1760_qtd *clean_this_qtd(struct isp1760_qtd *qtd, + struct isp1760_qh *qh) { struct isp1760_qtd *tmp_qtd; - tmp_qtd = qtd->hw_next; + if (list_is_last(&qtd->qtd_list, &qh->qtd_list)) + tmp_qtd = NULL; + else + tmp_qtd = list_entry(qtd->qtd_list.next, struct isp1760_qtd, + qtd_list); list_del(&qtd->qtd_list); isp1760_qtd_free(qtd); return tmp_qtd; @@ -998,22 +997,31 @@ static struct isp1760_qtd *clean_this_qtd(struct isp1760_qtd *qtd) * isn't the last one than remove also his successor(s). * Returns the QTD which is part of an new URB and should be enqueued. */ -static struct isp1760_qtd *clean_up_qtdlist(struct isp1760_qtd *qtd) +static struct isp1760_qtd *clean_up_qtdlist(struct isp1760_qtd *qtd, + struct isp1760_qh *qh) { - struct isp1760_qtd *tmp_qtd; - int last_one; + struct urb *urb; + urb = qtd->urb; do { - tmp_qtd = qtd->hw_next; - last_one = qtd->status & URB_COMPLETE_NOTIFY; - list_del(&qtd->qtd_list); - isp1760_qtd_free(qtd); - qtd = tmp_qtd; - } while (!last_one && qtd); + qtd = clean_this_qtd(qtd, qh); + } while (qtd && (qtd->urb == urb)); return qtd; } +static int last_qtd_of_urb(struct isp1760_qtd *qtd, struct isp1760_qh *qh) +{ + struct urb *urb; + + if (list_is_last(&qtd->qtd_list, &qh->qtd_list)) + return 1; + + urb = qtd->urb; + qtd = list_entry(qtd->qtd_list.next, typeof(*qtd), qtd_list); + return (qtd->urb != urb); +} + static void do_atl_int(struct usb_hcd *hcd) { struct isp1760_hcd *priv = hcd_to_priv(hcd); @@ -1046,8 +1054,8 @@ static void do_atl_int(struct usb_hcd *hcd) done_map &= ~(1 << queue_entry); skip_map |= 1 << queue_entry; - urb = priv->atl_ints[queue_entry].urb; qtd = priv->atl_ints[queue_entry].qtd; + urb = qtd->urb; qh = priv->atl_ints[queue_entry].qh; payload = priv->atl_ints[queue_entry].payload; @@ -1160,7 +1168,6 @@ static void do_atl_int(struct usb_hcd *hcd) } priv->atl_ints[queue_entry].data_buffer = NULL; - priv->atl_ints[queue_entry].urb = NULL; priv->atl_ints[queue_entry].qtd = NULL; priv->atl_ints[queue_entry].qh = NULL; @@ -1171,7 +1178,7 @@ static void do_atl_int(struct usb_hcd *hcd) if (urb->status == -EPIPE) { /* HALT was received */ - qtd = clean_up_qtdlist(qtd); + qtd = clean_up_qtdlist(qtd, qh); isp1760_urb_done(priv, urb, urb->status); } else if (usb_pipebulk(urb->pipe) && (length < qtd->length)) { @@ -1187,23 +1194,23 @@ static void do_atl_int(struct usb_hcd *hcd) if (urb->status == -EINPROGRESS) urb->status = 0; - qtd = clean_up_qtdlist(qtd); + qtd = clean_up_qtdlist(qtd, qh); isp1760_urb_done(priv, urb, urb->status); - } else if (qtd->status & URB_COMPLETE_NOTIFY) { + } else if (last_qtd_of_urb(qtd, qh)) { /* that was the last qtd of that URB */ if (urb->status == -EINPROGRESS) urb->status = 0; - qtd = clean_this_qtd(qtd); + qtd = clean_this_qtd(qtd, qh); isp1760_urb_done(priv, urb, urb->status); } else { /* next QTD of this URB */ - qtd = clean_this_qtd(qtd); + qtd = clean_this_qtd(qtd, qh); BUG_ON(!qtd); } @@ -1243,8 +1250,8 @@ static void do_intl_int(struct usb_hcd *hcd) done_map &= ~(1 << queue_entry); skip_map |= 1 << queue_entry; - urb = priv->int_ints[queue_entry].urb; qtd = priv->int_ints[queue_entry].qtd; + urb = qtd->urb; qh = priv->int_ints[queue_entry].qh; payload = priv->int_ints[queue_entry].payload; @@ -1298,7 +1305,6 @@ static void do_intl_int(struct usb_hcd *hcd) } priv->int_ints[queue_entry].data_buffer = NULL; - priv->int_ints[queue_entry].urb = NULL; priv->int_ints[queue_entry].qtd = NULL; priv->int_ints[queue_entry].qh = NULL; @@ -1308,21 +1314,21 @@ static void do_intl_int(struct usb_hcd *hcd) if (urb->status == -EPIPE) { /* HALT received */ - qtd = clean_up_qtdlist(qtd); + qtd = clean_up_qtdlist(qtd, qh); isp1760_urb_done(priv, urb, urb->status); - } else if (qtd->status & URB_COMPLETE_NOTIFY) { + } else if (last_qtd_of_urb(qtd, qh)) { if (urb->status == -EINPROGRESS) urb->status = 0; - qtd = clean_this_qtd(qtd); + qtd = clean_this_qtd(qtd, qh); isp1760_urb_done(priv, urb, urb->status); } else { /* next QTD of this URB */ - qtd = clean_this_qtd(qtd); + qtd = clean_this_qtd(qtd, qh); BUG_ON(!qtd); } @@ -1390,8 +1396,6 @@ static struct isp1760_qh *qh_append_tds(struct isp1760_hcd *priv, void **ptr) { struct isp1760_qh *qh; - struct isp1760_qtd *qtd; - struct isp1760_qtd *prev_qtd; qh = (struct isp1760_qh *)*ptr; if (!qh) { @@ -1402,21 +1406,8 @@ static struct isp1760_qh *qh_append_tds(struct isp1760_hcd *priv, *ptr = qh; } - qtd = list_entry(qtd_list->next, struct isp1760_qtd, - qtd_list); - if (!list_empty(&qh->qtd_list)) - prev_qtd = list_entry(qh->qtd_list.prev, - struct isp1760_qtd, qtd_list); - else - prev_qtd = NULL; - list_splice(qtd_list, qh->qtd_list.prev); - if (prev_qtd) { - BUG_ON(prev_qtd->hw_next); - prev_qtd->hw_next = qtd; - } - urb->hcpriv = qh; return qh; } @@ -1497,7 +1488,7 @@ static struct isp1760_qtd *isp1760_qtd_alloc(struct isp1760_hcd *priv, static struct list_head *qh_urb_transaction(struct isp1760_hcd *priv, struct urb *urb, struct list_head *head, gfp_t flags) { - struct isp1760_qtd *qtd, *qtd_prev; + struct isp1760_qtd *qtd; void *buf; int len, maxpacket; int is_input; @@ -1527,12 +1518,10 @@ static struct list_head *qh_urb_transaction(struct isp1760_hcd *priv, /* ... and always at least one more pid */ token ^= DATA_TOGGLE; - qtd_prev = qtd; qtd = isp1760_qtd_alloc(priv, flags); if (!qtd) goto cleanup; qtd->urb = urb; - qtd_prev->hw_next = qtd; list_add_tail(&qtd->qtd_list, head); /* for zero length DATA stages, STATUS is always IN */ @@ -1578,12 +1567,10 @@ static struct list_head *qh_urb_transaction(struct isp1760_hcd *priv, if (len <= 0) break; - qtd_prev = qtd; qtd = isp1760_qtd_alloc(priv, flags); if (!qtd) goto cleanup; qtd->urb = urb; - qtd_prev->hw_next = qtd; list_add_tail(&qtd->qtd_list, head); } @@ -1606,12 +1593,10 @@ static struct list_head *qh_urb_transaction(struct isp1760_hcd *priv, one_more = 1; } if (one_more) { - qtd_prev = qtd; qtd = isp1760_qtd_alloc(priv, flags); if (!qtd) goto cleanup; qtd->urb = urb; - qtd_prev->hw_next = qtd; list_add_tail(&qtd->qtd_list, head); /* never any data in such packets */ @@ -1619,7 +1604,7 @@ static struct list_head *qh_urb_transaction(struct isp1760_hcd *priv, } } - qtd->status = URB_COMPLETE_NOTIFY; + qtd->status = 0; return head; cleanup: @@ -1697,11 +1682,15 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, spin_lock_irqsave(&priv->lock, flags); for (i = 0; i < 32; i++) { - if (ints->urb == urb) { + if (!ints[i].qh) + continue; + BUG_ON(!ints[i].qtd); + + if (ints[i].qtd->urb == urb) { u32 skip_map; u32 or_map; struct isp1760_qtd *qtd; - struct isp1760_qh *qh = ints->qh; + struct isp1760_qh *qh; skip_map = reg_read32(hcd->regs, skip_reg); skip_map |= 1 << i; @@ -1714,11 +1703,11 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, ptd_write(hcd->regs, reg_base, i, &ptd); qtd = ints->qtd; - qtd = clean_up_qtdlist(qtd); + qh = ints[i].qh; + qtd = clean_up_qtdlist(qtd, qh); free_mem(priv, ints->payload); - ints->urb = NULL; ints->qh = NULL; ints->qtd = NULL; ints->data_buffer = NULL; @@ -1729,20 +1718,21 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, pe(hcd, qh, qtd); break; - } else if (ints->qtd) { - struct isp1760_qtd *qtd, *prev_qtd = ints->qtd; + } else { + struct isp1760_qtd *qtd; - for (qtd = ints->qtd->hw_next; qtd; qtd = qtd->hw_next) { + list_for_each_entry(qtd, &ints[i].qtd->qtd_list, + qtd_list) { if (qtd->urb == urb) { - prev_qtd->hw_next = - clean_up_qtdlist(qtd); + clean_up_qtdlist(qtd, ints[i].qh); isp1760_urb_done(priv, urb, status); + qtd = NULL; break; } - prev_qtd = qtd; } - /* we found the urb before the end of the list */ - if (qtd) + + /* We found the urb before the last slot */ + if (!qtd) break; } ints++; @@ -2179,7 +2169,7 @@ static void isp1760_endpoint_disable(struct usb_hcd *usb_hcd, struct urb *urb; urb = qtd->urb; - clean_up_qtdlist(qtd); + clean_up_qtdlist(qtd, qh); isp1760_urb_done(priv, urb, -ECONNRESET); } } while (1); diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h index c01c59171bc7..a0599183b28b 100644 --- a/drivers/usb/host/isp1760-hcd.h +++ b/drivers/usb/host/isp1760-hcd.h @@ -111,7 +111,6 @@ struct inter_packet_info { u32 payload; #define PTD_FIRE_NEXT (1 << 0) #define PTD_URB_FINISHED (1 << 1) - struct urb *urb; struct isp1760_qh *qh; struct isp1760_qtd *qtd; }; -- cgit v1.2.3 From a041d8e4375ee6d78409a721221878dcad5eff8a Mon Sep 17 00:00:00 2001 From: Arvid Brodin Date: Sat, 26 Feb 2011 22:04:40 +0100 Subject: usb/isp1760: Clean up payload address handling Encapsulate payload addresses within qtds. Signed-off-by: Arvid Brodin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp1760-hcd.c | 197 +++++++++++++++++++---------------------- drivers/usb/host/isp1760-hcd.h | 9 +- 2 files changed, 95 insertions(+), 111 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 2342f11d0f30..cfb8e8ab9338 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -85,6 +85,8 @@ struct isp1760_qtd { u8 toggle; void *data_buffer; + u32 payload_addr; + /* the rest is HCD-private */ struct list_head qtd_list; struct urb *urb; @@ -256,54 +258,56 @@ static void ptd_write(void __iomem *base, u32 ptd_offset, u32 slot, /* memory management of the 60kb on the chip from 0x1000 to 0xffff */ static void init_memory(struct isp1760_hcd *priv) { - int i; - u32 payload; + int i, curr; + u32 payload_addr; - payload = 0x1000; + payload_addr = PAYLOAD_OFFSET; for (i = 0; i < BLOCK_1_NUM; i++) { - priv->memory_pool[i].start = payload; + priv->memory_pool[i].start = payload_addr; priv->memory_pool[i].size = BLOCK_1_SIZE; priv->memory_pool[i].free = 1; - payload += priv->memory_pool[i].size; + payload_addr += priv->memory_pool[i].size; } - - for (i = BLOCK_1_NUM; i < BLOCK_1_NUM + BLOCK_2_NUM; i++) { - priv->memory_pool[i].start = payload; - priv->memory_pool[i].size = BLOCK_2_SIZE; - priv->memory_pool[i].free = 1; - payload += priv->memory_pool[i].size; + curr = i; + for (i = 0; i < BLOCK_2_NUM; i++) { + priv->memory_pool[curr + i].start = payload_addr; + priv->memory_pool[curr + i].size = BLOCK_2_SIZE; + priv->memory_pool[curr + i].free = 1; + payload_addr += priv->memory_pool[curr + i].size; } - - for (i = BLOCK_1_NUM + BLOCK_2_NUM; i < BLOCKS; i++) { - priv->memory_pool[i].start = payload; - priv->memory_pool[i].size = BLOCK_3_SIZE; - priv->memory_pool[i].free = 1; - payload += priv->memory_pool[i].size; + curr = i; + for (i = 0; i < BLOCK_3_NUM; i++) { + priv->memory_pool[curr + i].start = payload_addr; + priv->memory_pool[curr + i].size = BLOCK_3_SIZE; + priv->memory_pool[curr + i].free = 1; + payload_addr += priv->memory_pool[curr + i].size; } - BUG_ON(payload - priv->memory_pool[i - 1].size > PAYLOAD_SIZE); + BUG_ON(payload_addr - priv->memory_pool[0].start > PAYLOAD_AREA_SIZE); } -static u32 alloc_mem(struct isp1760_hcd *priv, u32 size) +static void alloc_mem(struct isp1760_hcd *priv, struct isp1760_qtd *qtd) { int i; - if (!size) - return ISP1760_NULL_POINTER; + BUG_ON(qtd->payload_addr); + + if (!qtd->length) + return; for (i = 0; i < BLOCKS; i++) { - if (priv->memory_pool[i].size >= size && + if (priv->memory_pool[i].size >= qtd->length && priv->memory_pool[i].free) { - priv->memory_pool[i].free = 0; - return priv->memory_pool[i].start; + qtd->payload_addr = priv->memory_pool[i].start; + return; } } - printk(KERN_ERR "ISP1760 MEM: can not allocate %d bytes of memory\n", - size); + printk(KERN_ERR "ISP1760 MEM: can not allocate %lu bytes of memory\n", + qtd->length); printk(KERN_ERR "Current memory map:\n"); for (i = 0; i < BLOCKS; i++) { printk(KERN_ERR "Pool %2d size %4d status: %d\n", @@ -312,28 +316,27 @@ static u32 alloc_mem(struct isp1760_hcd *priv, u32 size) } /* XXX maybe -ENOMEM could be possible */ BUG(); - return 0; + return; } -static void free_mem(struct isp1760_hcd *priv, u32 mem) +static void free_mem(struct isp1760_hcd *priv, struct isp1760_qtd *qtd) { int i; - if (mem == ISP1760_NULL_POINTER) + if (!qtd->payload_addr) return; for (i = 0; i < BLOCKS; i++) { - if (priv->memory_pool[i].start == mem) { - + if (priv->memory_pool[i].start == qtd->payload_addr) { BUG_ON(priv->memory_pool[i].free); - priv->memory_pool[i].free = 1; - return ; + qtd->payload_addr = 0; + return; } } - printk(KERN_ERR "Trying to free not-here-allocated memory :%08x\n", - mem); + printk(KERN_ERR "%s: Invalid pointer: %08x\n", __func__, + qtd->payload_addr); BUG(); } @@ -596,8 +599,7 @@ static u32 base_to_chip(u32 base) } static void transform_into_atl(struct isp1760_hcd *priv, struct isp1760_qh *qh, - struct isp1760_qtd *qtd, struct urb *urb, - u32 payload, struct ptd *ptd) + struct isp1760_qtd *qtd, struct ptd *ptd) { u32 maxpacket; u32 multi; @@ -608,7 +610,8 @@ static void transform_into_atl(struct isp1760_hcd *priv, struct isp1760_qh *qh, memset(ptd, 0, sizeof(*ptd)); /* according to 3.6.2, max packet len can not be > 0x400 */ - maxpacket = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); + maxpacket = usb_maxpacket(qtd->urb->dev, qtd->urb->pipe, + usb_pipeout(qtd->urb->pipe)); multi = 1 + ((maxpacket >> 11) & 0x3); maxpacket &= 0x7ff; @@ -616,33 +619,33 @@ static void transform_into_atl(struct isp1760_hcd *priv, struct isp1760_qh *qh, ptd->dw0 = PTD_VALID; ptd->dw0 |= PTD_LENGTH(qtd->length); ptd->dw0 |= PTD_MAXPACKET(maxpacket); - ptd->dw0 |= PTD_ENDPOINT(usb_pipeendpoint(urb->pipe)); - ptd->dw1 = usb_pipeendpoint(urb->pipe) >> 1; + ptd->dw0 |= PTD_ENDPOINT(usb_pipeendpoint(qtd->urb->pipe)); /* DW1 */ - ptd->dw1 |= PTD_DEVICE_ADDR(usb_pipedevice(urb->pipe)); + ptd->dw1 = usb_pipeendpoint(qtd->urb->pipe) >> 1; + ptd->dw1 |= PTD_DEVICE_ADDR(usb_pipedevice(qtd->urb->pipe)); pid_code = qtd->packet_type; ptd->dw1 |= PTD_PID_TOKEN(pid_code); - if (usb_pipebulk(urb->pipe)) + if (usb_pipebulk(qtd->urb->pipe)) ptd->dw1 |= PTD_TRANS_BULK; - else if (usb_pipeint(urb->pipe)) + else if (usb_pipeint(qtd->urb->pipe)) ptd->dw1 |= PTD_TRANS_INT; - if (urb->dev->speed != USB_SPEED_HIGH) { + if (qtd->urb->dev->speed != USB_SPEED_HIGH) { /* split transaction */ ptd->dw1 |= PTD_TRANS_SPLIT; - if (urb->dev->speed == USB_SPEED_LOW) + if (qtd->urb->dev->speed == USB_SPEED_LOW) ptd->dw1 |= PTD_SE_USB_LOSPEED; - ptd->dw1 |= PTD_PORT_NUM(urb->dev->ttport); - ptd->dw1 |= PTD_HUB_NUM(urb->dev->tt->hub->devnum); + ptd->dw1 |= PTD_PORT_NUM(qtd->urb->dev->ttport); + ptd->dw1 |= PTD_HUB_NUM(qtd->urb->dev->tt->hub->devnum); /* SE bit for Split INT transfers */ - if (usb_pipeint(urb->pipe) && - (urb->dev->speed == USB_SPEED_LOW)) + if (usb_pipeint(qtd->urb->pipe) && + (qtd->urb->dev->speed == USB_SPEED_LOW)) ptd->dw1 |= 2 << 16; ptd->dw3 = 0; @@ -650,19 +653,20 @@ static void transform_into_atl(struct isp1760_hcd *priv, struct isp1760_qh *qh, nak = 0; } else { ptd->dw0 |= PTD_MULTI(multi); - if (usb_pipecontrol(urb->pipe) || usb_pipebulk(urb->pipe)) + if (usb_pipecontrol(qtd->urb->pipe) || + usb_pipebulk(qtd->urb->pipe)) ptd->dw3 = qh->ping; else ptd->dw3 = 0; } /* DW2 */ ptd->dw2 = 0; - ptd->dw2 |= PTD_DATA_START_ADDR(base_to_chip(payload)); + ptd->dw2 |= PTD_DATA_START_ADDR(base_to_chip(qtd->payload_addr)); ptd->dw2 |= PTD_RL_CNT(rl); ptd->dw3 |= PTD_NAC_CNT(nak); /* DW3 */ - if (usb_pipecontrol(urb->pipe)) + if (usb_pipecontrol(qtd->urb->pipe)) ptd->dw3 |= PTD_DATA_TOGGLE(qtd->toggle); else ptd->dw3 |= qh->toggle; @@ -674,8 +678,7 @@ static void transform_into_atl(struct isp1760_hcd *priv, struct isp1760_qh *qh, } static void transform_add_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, - struct isp1760_qtd *qtd, struct urb *urb, - u32 payload, struct ptd *ptd) + struct isp1760_qtd *qtd, struct ptd *ptd) { u32 maxpacket; u32 multi; @@ -684,14 +687,15 @@ static void transform_add_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, u32 usofmask, usof; u32 period; - maxpacket = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); + maxpacket = usb_maxpacket(qtd->urb->dev, qtd->urb->pipe, + usb_pipeout(qtd->urb->pipe)); multi = 1 + ((maxpacket >> 11) & 0x3); maxpacket &= 0x7ff; /* length of the data per uframe */ maxpacket = multi * maxpacket; - numberofusofs = urb->transfer_buffer_length / maxpacket; - if (urb->transfer_buffer_length % maxpacket) + numberofusofs = qtd->urb->transfer_buffer_length / maxpacket; + if (qtd->urb->transfer_buffer_length % maxpacket) numberofusofs += 1; usofmask = 1; @@ -701,7 +705,7 @@ static void transform_add_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, usofmask <<= 1; } - if (urb->dev->speed != USB_SPEED_HIGH) { + if (qtd->urb->dev->speed != USB_SPEED_HIGH) { /* split */ ptd->dw5 = 0x1c; @@ -735,11 +739,10 @@ static void transform_add_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, } static void transform_into_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, - struct isp1760_qtd *qtd, struct urb *urb, - u32 payload, struct ptd *ptd) + struct isp1760_qtd *qtd, struct ptd *ptd) { - transform_into_atl(priv, qh, qtd, urb, payload, ptd); - transform_add_int(priv, qh, qtd, urb, payload, ptd); + transform_into_atl(priv, qh, qtd, ptd); + transform_add_int(priv, qh, qtd, ptd); } static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len, @@ -751,8 +754,8 @@ static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len, qtd->packet_type = GET_QTD_TOKEN_TYPE(token); qtd->toggle = GET_DATA_TOGGLE(token); - if (len > HC_ATL_PL_SIZE) - count = HC_ATL_PL_SIZE; + if (len > MAX_PAYLOAD_SIZE) + count = MAX_PAYLOAD_SIZE; else count = len; @@ -804,60 +807,56 @@ static void check_int_err_status(u32 dw4) } } -static void enqueue_one_qtd(struct isp1760_qtd *qtd, struct isp1760_hcd *priv, - u32 payload) +static void enqueue_one_qtd(struct isp1760_qtd *qtd, struct isp1760_hcd *priv) { - u32 token; struct usb_hcd *hcd = priv_to_hcd(priv); - token = qtd->packet_type; - - if (qtd->length && (qtd->length <= HC_ATL_PL_SIZE)) { - switch (token) { + if (qtd->length && (qtd->length <= MAX_PAYLOAD_SIZE)) { + switch (qtd->packet_type) { case IN_PID: break; case OUT_PID: case SETUP_PID: - mem_writes8(hcd->regs, payload, qtd->data_buffer, - qtd->length); + mem_writes8(hcd->regs, qtd->payload_addr, + qtd->data_buffer, qtd->length); } } } -static void enqueue_one_atl_qtd(u32 payload, - struct isp1760_hcd *priv, struct isp1760_qh *qh, - struct urb *urb, u32 slot, struct isp1760_qtd *qtd) +static void enqueue_one_atl_qtd(struct isp1760_hcd *priv, + struct isp1760_qh *qh, u32 slot, + struct isp1760_qtd *qtd) { struct ptd ptd; struct usb_hcd *hcd = priv_to_hcd(priv); - transform_into_atl(priv, qh, qtd, urb, payload, &ptd); + alloc_mem(priv, qtd); + transform_into_atl(priv, qh, qtd, &ptd); ptd_write(hcd->regs, ATL_PTD_OFFSET, slot, &ptd); - enqueue_one_qtd(qtd, priv, payload); + enqueue_one_qtd(qtd, priv); priv->atl_ints[slot].qh = qh; priv->atl_ints[slot].qtd = qtd; priv->atl_ints[slot].data_buffer = qtd->data_buffer; - priv->atl_ints[slot].payload = payload; qtd->status |= URB_ENQUEUED; qtd->status |= slot << 16; } -static void enqueue_one_int_qtd(u32 payload, - struct isp1760_hcd *priv, struct isp1760_qh *qh, - struct urb *urb, u32 slot, struct isp1760_qtd *qtd) +static void enqueue_one_int_qtd(struct isp1760_hcd *priv, + struct isp1760_qh *qh, u32 slot, + struct isp1760_qtd *qtd) { struct ptd ptd; struct usb_hcd *hcd = priv_to_hcd(priv); - transform_into_int(priv, qh, qtd, urb, payload, &ptd); + alloc_mem(priv, qtd); + transform_into_int(priv, qh, qtd, &ptd); ptd_write(hcd->regs, INT_PTD_OFFSET, slot, &ptd); - enqueue_one_qtd(qtd, priv, payload); + enqueue_one_qtd(qtd, priv); priv->int_ints[slot].qh = qh; priv->int_ints[slot].qtd = qtd; priv->int_ints[slot].data_buffer = qtd->data_buffer; - priv->int_ints[slot].payload = payload; qtd->status |= URB_ENQUEUED; qtd->status |= slot << 16; } @@ -869,7 +868,6 @@ static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, u32 skip_map, or_map; u32 queue_entry; u32 slot; - u32 payload; u32 buffstatus; /* @@ -886,9 +884,7 @@ static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, slot = __ffs(skip_map); queue_entry = 1 << slot; - payload = alloc_mem(priv, qtd->length); - - enqueue_one_atl_qtd(payload, priv, qh, qtd->urb, slot, qtd); + enqueue_one_atl_qtd(priv, qh, slot, qtd); or_map = reg_read32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG); or_map |= queue_entry; @@ -914,7 +910,6 @@ static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, u32 skip_map, or_map; u32 queue_entry; u32 slot; - u32 payload; u32 buffstatus; /* @@ -931,9 +926,7 @@ static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, slot = __ffs(skip_map); queue_entry = 1 << slot; - payload = alloc_mem(priv, qtd->length); - - enqueue_one_int_qtd(payload, priv, qh, qtd->urb, slot, qtd); + enqueue_one_int_qtd(priv, qh, slot, qtd); or_map = reg_read32(hcd->regs, HC_INT_IRQ_MASK_OR_REG); or_map |= queue_entry; @@ -974,6 +967,7 @@ __acquires(priv->lock) static void isp1760_qtd_free(struct isp1760_qtd *qtd) { + BUG_ON(qtd->payload_addr); kmem_cache_free(qtd_cachep, qtd); } @@ -1029,7 +1023,6 @@ static void do_atl_int(struct usb_hcd *hcd) struct ptd ptd; struct urb *urb = NULL; u32 queue_entry; - u32 payload; u32 length; u32 or_map; u32 status = -EINVAL; @@ -1057,7 +1050,6 @@ static void do_atl_int(struct usb_hcd *hcd) qtd = priv->atl_ints[queue_entry].qtd; urb = qtd->urb; qh = priv->atl_ints[queue_entry].qh; - payload = priv->atl_ints[queue_entry].payload; if (!qh) { printk(KERN_ERR "qh is 0\n"); @@ -1154,7 +1146,7 @@ static void do_atl_int(struct usb_hcd *hcd) if (length) { switch (DW1_GET_PID(ptd.dw1)) { case IN_PID: - mem_reads8(hcd->regs, payload, + mem_reads8(hcd->regs, qtd->payload_addr, priv->atl_ints[queue_entry].data_buffer, length); @@ -1171,7 +1163,7 @@ static void do_atl_int(struct usb_hcd *hcd) priv->atl_ints[queue_entry].qtd = NULL; priv->atl_ints[queue_entry].qh = NULL; - free_mem(priv, payload); + free_mem(priv, qtd); reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, skip_map); @@ -1230,7 +1222,6 @@ static void do_intl_int(struct usb_hcd *hcd) u32 done_map, skip_map; struct ptd ptd; struct urb *urb = NULL; - u32 payload; u32 length; u32 or_map; int error; @@ -1253,7 +1244,6 @@ static void do_intl_int(struct usb_hcd *hcd) qtd = priv->int_ints[queue_entry].qtd; urb = qtd->urb; qh = priv->int_ints[queue_entry].qh; - payload = priv->int_ints[queue_entry].payload; if (!qh) { printk(KERN_ERR "(INT) qh is 0\n"); @@ -1292,7 +1282,7 @@ static void do_intl_int(struct usb_hcd *hcd) if (length) { switch (DW1_GET_PID(ptd.dw1)) { case IN_PID: - mem_reads8(hcd->regs, payload, + mem_reads8(hcd->regs, qtd->payload_addr, priv->int_ints[queue_entry].data_buffer, length); case OUT_PID: @@ -1309,7 +1299,7 @@ static void do_intl_int(struct usb_hcd *hcd) priv->int_ints[queue_entry].qh = NULL; reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, skip_map); - free_mem(priv, payload); + free_mem(priv, qtd); if (urb->status == -EPIPE) { /* HALT received */ @@ -1704,14 +1694,13 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, qtd = ints->qtd; qh = ints[i].qh; - qtd = clean_up_qtdlist(qtd, qh); - free_mem(priv, ints->payload); + free_mem(priv, qtd); + qtd = clean_up_qtdlist(qtd, qh); ints->qh = NULL; ints->qtd = NULL; ints->data_buffer = NULL; - ints->payload = 0; isp1760_urb_done(priv, urb, status); if (qtd) diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h index a0599183b28b..587adbaa111a 100644 --- a/drivers/usb/host/isp1760-hcd.h +++ b/drivers/usb/host/isp1760-hcd.h @@ -108,7 +108,6 @@ struct ptd { struct inter_packet_info { void *data_buffer; - u32 payload; #define PTD_FIRE_NEXT (1 << 0) #define PTD_URB_FINISHED (1 << 1) struct isp1760_qh *qh; @@ -164,10 +163,8 @@ struct memory_chunk { #define BLOCK_2_SIZE 1024 #define BLOCK_3_SIZE 8192 #define BLOCKS (BLOCK_1_NUM + BLOCK_2_NUM + BLOCK_3_NUM) -#define PAYLOAD_SIZE 0xf000 - -/* I saw if some reloads if the pointer was negative */ -#define ISP1760_NULL_POINTER (0x400) +#define MAX_PAYLOAD_SIZE BLOCK_3_SIZE +#define PAYLOAD_AREA_SIZE 0xf000 /* ATL */ /* DW0 */ @@ -221,6 +218,4 @@ struct memory_chunk { #define NAK_COUNTER (0) #define ERR_COUNTER (2) -#define HC_ATL_PL_SIZE (8192) - #endif -- cgit v1.2.3 From bbaa387674b65a2f784631cc4c87c77ec9d3374e Mon Sep 17 00:00:00 2001 From: Arvid Brodin Date: Sat, 26 Feb 2011 22:05:26 +0100 Subject: usb/isp1760: Remove redundant "data_buffer" member from struct inter_packet_info Signed-off-by: Arvid Brodin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp1760-hcd.c | 11 ++--------- drivers/usb/host/isp1760-hcd.h | 1 - 2 files changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index cfb8e8ab9338..e0d9704b2039 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -837,7 +837,6 @@ static void enqueue_one_atl_qtd(struct isp1760_hcd *priv, priv->atl_ints[slot].qh = qh; priv->atl_ints[slot].qtd = qtd; - priv->atl_ints[slot].data_buffer = qtd->data_buffer; qtd->status |= URB_ENQUEUED; qtd->status |= slot << 16; } @@ -856,7 +855,6 @@ static void enqueue_one_int_qtd(struct isp1760_hcd *priv, priv->int_ints[slot].qh = qh; priv->int_ints[slot].qtd = qtd; - priv->int_ints[slot].data_buffer = qtd->data_buffer; qtd->status |= URB_ENQUEUED; qtd->status |= slot << 16; } @@ -1147,8 +1145,7 @@ static void do_atl_int(struct usb_hcd *hcd) switch (DW1_GET_PID(ptd.dw1)) { case IN_PID: mem_reads8(hcd->regs, qtd->payload_addr, - priv->atl_ints[queue_entry].data_buffer, - length); + qtd->data_buffer, length); case OUT_PID: @@ -1159,7 +1156,6 @@ static void do_atl_int(struct usb_hcd *hcd) } } - priv->atl_ints[queue_entry].data_buffer = NULL; priv->atl_ints[queue_entry].qtd = NULL; priv->atl_ints[queue_entry].qh = NULL; @@ -1283,8 +1279,7 @@ static void do_intl_int(struct usb_hcd *hcd) switch (DW1_GET_PID(ptd.dw1)) { case IN_PID: mem_reads8(hcd->regs, qtd->payload_addr, - priv->int_ints[queue_entry].data_buffer, - length); + qtd->data_buffer, length); case OUT_PID: urb->actual_length += length; @@ -1294,7 +1289,6 @@ static void do_intl_int(struct usb_hcd *hcd) } } - priv->int_ints[queue_entry].data_buffer = NULL; priv->int_ints[queue_entry].qtd = NULL; priv->int_ints[queue_entry].qh = NULL; @@ -1700,7 +1694,6 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, ints->qh = NULL; ints->qtd = NULL; - ints->data_buffer = NULL; isp1760_urb_done(priv, urb, status); if (qtd) diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h index 587adbaa111a..aadd77bc271c 100644 --- a/drivers/usb/host/isp1760-hcd.h +++ b/drivers/usb/host/isp1760-hcd.h @@ -107,7 +107,6 @@ struct ptd { #define PAYLOAD_OFFSET 0x1000 struct inter_packet_info { - void *data_buffer; #define PTD_FIRE_NEXT (1 << 0) #define PTD_URB_FINISHED (1 << 1) struct isp1760_qh *qh; -- cgit v1.2.3 From 6bda21bc0941c11f07cbf436ff6ca85e7e6e47f0 Mon Sep 17 00:00:00 2001 From: Arvid Brodin Date: Sat, 26 Feb 2011 22:06:37 +0100 Subject: usb/isp1760: Consolidate printouts and remove unused code Consolidate printouts to use dev_XXX functions instead of an assortment of printks and driver specific macros. Remove some unused code snippets and struct members. Remove some unused function parameters and #defines. Change the "queue_entry" variable name which has different but related meanings in different places and use "slot" only. Signed-off-by: Arvid Brodin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp1760-hcd.c | 397 ++++++++++++++++++++--------------------- drivers/usb/host/isp1760-hcd.h | 11 -- 2 files changed, 190 insertions(+), 218 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index e0d9704b2039..0f5b48946739 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -48,10 +48,6 @@ static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd) { return (struct isp1760_hcd *) (hcd->hcd_priv); } -static inline struct usb_hcd *priv_to_hcd(struct isp1760_hcd *priv) -{ - return container_of((void *) priv, struct usb_hcd, hcd_priv); -} /* Section 2.2 Host Controller Capability Registers */ #define HC_LENGTH(p) (((p)>>00)&0x00ff) /* bits 7:0 */ @@ -100,18 +96,14 @@ struct isp1760_qtd { struct isp1760_qh { /* first part defined by EHCI spec */ struct list_head qtd_list; - struct isp1760_hcd *priv; /* periodic schedule info */ unsigned short period; /* polling interval */ - struct usb_device *dev; u32 toggle; u32 ping; }; -#define ehci_port_speed(priv, portsc) USB_PORT_STAT_HIGH_SPEED - /* * Access functions for isp176x registers (addresses 0..0x03FF). */ @@ -288,8 +280,9 @@ static void init_memory(struct isp1760_hcd *priv) BUG_ON(payload_addr - priv->memory_pool[0].start > PAYLOAD_AREA_SIZE); } -static void alloc_mem(struct isp1760_hcd *priv, struct isp1760_qtd *qtd) +static void alloc_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd) { + struct isp1760_hcd *priv = hcd_to_priv(hcd); int i; BUG_ON(qtd->payload_addr); @@ -306,11 +299,12 @@ static void alloc_mem(struct isp1760_hcd *priv, struct isp1760_qtd *qtd) } } - printk(KERN_ERR "ISP1760 MEM: can not allocate %lu bytes of memory\n", - qtd->length); - printk(KERN_ERR "Current memory map:\n"); + dev_err(hcd->self.controller, + "%s: Can not allocate %lu bytes of memory\n" + "Current memory map:\n", + __func__, qtd->length); for (i = 0; i < BLOCKS; i++) { - printk(KERN_ERR "Pool %2d size %4d status: %d\n", + dev_err(hcd->self.controller, "Pool %2d size %4d status: %d\n", i, priv->memory_pool[i].size, priv->memory_pool[i].free); } @@ -319,8 +313,9 @@ static void alloc_mem(struct isp1760_hcd *priv, struct isp1760_qtd *qtd) return; } -static void free_mem(struct isp1760_hcd *priv, struct isp1760_qtd *qtd) +static void free_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd) { + struct isp1760_hcd *priv = hcd_to_priv(hcd); int i; if (!qtd->payload_addr) @@ -335,8 +330,8 @@ static void free_mem(struct isp1760_hcd *priv, struct isp1760_qtd *qtd) } } - printk(KERN_ERR "%s: Invalid pointer: %08x\n", __func__, - qtd->payload_addr); + dev_err(hcd->self.controller, "%s: Invalid pointer: %08x\n", + __func__, qtd->payload_addr); BUG(); } @@ -371,10 +366,11 @@ static int handshake(struct usb_hcd *hcd, u32 reg, } /* reset a non-running (STS_HALT == 1) controller */ -static int ehci_reset(struct isp1760_hcd *priv) +static int ehci_reset(struct usb_hcd *hcd) { int retval; - struct usb_hcd *hcd = priv_to_hcd(priv); + struct isp1760_hcd *priv = hcd_to_priv(hcd); + u32 command = reg_read32(hcd->regs, HC_USBCMD); command |= CMD_RESET; @@ -392,8 +388,7 @@ static void qh_destroy(struct isp1760_qh *qh) kmem_cache_free(qh_cachep, qh); } -static struct isp1760_qh *isp1760_qh_alloc(struct isp1760_hcd *priv, - gfp_t flags) +static struct isp1760_qh *isp1760_qh_alloc(gfp_t flags) { struct isp1760_qh *qh; @@ -402,7 +397,6 @@ static struct isp1760_qh *isp1760_qh_alloc(struct isp1760_hcd *priv, return qh; INIT_LIST_HEAD(&qh->qtd_list); - qh->priv = priv; return qh; } @@ -474,7 +468,7 @@ static int isp1760_hc_setup(struct usb_hcd *hcd) scratch = reg_read32(hcd->regs, HC_CHIP_ID_REG); scratch = reg_read32(hcd->regs, HC_SCRATCH_REG); if (scratch != 0xdeadbabe) { - printk(KERN_ERR "ISP1760: Scratch test failed.\n"); + dev_err(hcd->self.controller, "Scratch test failed.\n"); return -ENODEV; } @@ -488,13 +482,13 @@ static int isp1760_hc_setup(struct usb_hcd *hcd) reg_write32(hcd->regs, HC_RESET_REG, SW_RESET_RESET_HC); mdelay(100); - result = ehci_reset(priv); + result = ehci_reset(hcd); if (result) return result; /* Step 11 passed */ - isp1760_info(priv, "bus width: %d, oc: %s\n", + dev_info(hcd->self.controller, "bus width: %d, oc: %s\n", (priv->devflags & ISP1760_FLAG_BUS_WIDTH_16) ? 16 : 32, (priv->devflags & ISP1760_FLAG_ANALOG_OC) ? "analog" : "digital"); @@ -542,7 +536,6 @@ static void isp1760_enable_interrupts(struct usb_hcd *hcd) static int isp1760_run(struct usb_hcd *hcd) { - struct isp1760_hcd *priv = hcd_to_priv(hcd); int retval; u32 temp; u32 command; @@ -579,8 +572,8 @@ static int isp1760_run(struct usb_hcd *hcd) return retval; chipid = reg_read32(hcd->regs, HC_CHIP_ID_REG); - isp1760_info(priv, "USB ISP %04x HW rev. %d started\n", chipid & 0xffff, - chipid >> 16); + dev_info(hcd->self.controller, "USB ISP %04x HW rev. %d started\n", + chipid & 0xffff, chipid >> 16); /* PTD Register Init Part 2, Step 28 */ /* enable INTs */ @@ -598,7 +591,7 @@ static u32 base_to_chip(u32 base) return ((base - 0x400) >> 3); } -static void transform_into_atl(struct isp1760_hcd *priv, struct isp1760_qh *qh, +static void transform_into_atl(struct isp1760_qh *qh, struct isp1760_qtd *qtd, struct ptd *ptd) { u32 maxpacket; @@ -677,7 +670,7 @@ static void transform_into_atl(struct isp1760_hcd *priv, struct isp1760_qh *qh, ptd->dw3 |= PTD_CERR(ERR_COUNTER); } -static void transform_add_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, +static void transform_add_int(struct isp1760_qh *qh, struct isp1760_qtd *qtd, struct ptd *ptd) { u32 maxpacket; @@ -738,11 +731,11 @@ static void transform_add_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, ptd->dw4 = usof; } -static void transform_into_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, +static void transform_into_int(struct isp1760_qh *qh, struct isp1760_qtd *qtd, struct ptd *ptd) { - transform_into_atl(priv, qh, qtd, ptd); - transform_add_int(priv, qh, qtd, ptd); + transform_into_atl(qh, qtd, ptd); + transform_add_int(qh, qtd, ptd); } static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len, @@ -763,7 +756,7 @@ static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len, return count; } -static int check_error(struct ptd *ptd) +static int check_error(struct usb_hcd *hcd, struct ptd *ptd) { int error = 0; @@ -775,15 +768,15 @@ static int check_error(struct ptd *ptd) } if (ptd->dw3 & DW3_QTD_ACTIVE) { - printk(KERN_ERR "transfer active bit is set DW3\n"); - printk(KERN_ERR "nak counter: %d, rl: %d\n", - (ptd->dw3 >> 19) & 0xf, (ptd->dw2 >> 25) & 0xf); + dev_err(hcd->self.controller, "Transfer active bit is set DW3\n" + "nak counter: %d, rl: %d\n", + (ptd->dw3 >> 19) & 0xf, (ptd->dw2 >> 25) & 0xf); } return error; } -static void check_int_err_status(u32 dw4) +static void check_int_err_status(struct usb_hcd *hcd, u32 dw4) { u32 i; @@ -792,25 +785,24 @@ static void check_int_err_status(u32 dw4) for (i = 0; i < 8; i++) { switch (dw4 & 0x7) { case INT_UNDERRUN: - printk(KERN_ERR "ERROR: under run , %d\n", i); + dev_err(hcd->self.controller, "Underrun (%d)\n", i); break; case INT_EXACT: - printk(KERN_ERR "ERROR: transaction error, %d\n", i); + dev_err(hcd->self.controller, + "Transaction error (%d)\n", i); break; case INT_BABBLE: - printk(KERN_ERR "ERROR: babble error, %d\n", i); + dev_err(hcd->self.controller, "Babble error (%d)\n", i); break; } dw4 >>= 3; } } -static void enqueue_one_qtd(struct isp1760_qtd *qtd, struct isp1760_hcd *priv) +static void enqueue_one_qtd(struct usb_hcd *hcd, struct isp1760_qtd *qtd) { - struct usb_hcd *hcd = priv_to_hcd(priv); - if (qtd->length && (qtd->length <= MAX_PAYLOAD_SIZE)) { switch (qtd->packet_type) { case IN_PID: @@ -823,17 +815,16 @@ static void enqueue_one_qtd(struct isp1760_qtd *qtd, struct isp1760_hcd *priv) } } -static void enqueue_one_atl_qtd(struct isp1760_hcd *priv, - struct isp1760_qh *qh, u32 slot, - struct isp1760_qtd *qtd) +static void enqueue_one_atl_qtd(struct usb_hcd *hcd, struct isp1760_qh *qh, + u32 slot, struct isp1760_qtd *qtd) { + struct isp1760_hcd *priv = hcd_to_priv(hcd); struct ptd ptd; - struct usb_hcd *hcd = priv_to_hcd(priv); - alloc_mem(priv, qtd); - transform_into_atl(priv, qh, qtd, &ptd); + alloc_mem(hcd, qtd); + transform_into_atl(qh, qtd, &ptd); ptd_write(hcd->regs, ATL_PTD_OFFSET, slot, &ptd); - enqueue_one_qtd(qtd, priv); + enqueue_one_qtd(hcd, qtd); priv->atl_ints[slot].qh = qh; priv->atl_ints[slot].qtd = qtd; @@ -841,17 +832,16 @@ static void enqueue_one_atl_qtd(struct isp1760_hcd *priv, qtd->status |= slot << 16; } -static void enqueue_one_int_qtd(struct isp1760_hcd *priv, - struct isp1760_qh *qh, u32 slot, - struct isp1760_qtd *qtd) +static void enqueue_one_int_qtd(struct usb_hcd *hcd, struct isp1760_qh *qh, + u32 slot, struct isp1760_qtd *qtd) { + struct isp1760_hcd *priv = hcd_to_priv(hcd); struct ptd ptd; - struct usb_hcd *hcd = priv_to_hcd(priv); - alloc_mem(priv, qtd); - transform_into_int(priv, qh, qtd, &ptd); + alloc_mem(hcd, qtd); + transform_into_int(qh, qtd, &ptd); ptd_write(hcd->regs, INT_PTD_OFFSET, slot, &ptd); - enqueue_one_qtd(qtd, priv); + enqueue_one_qtd(hcd, qtd); priv->int_ints[slot].qh = qh; priv->int_ints[slot].qtd = qtd; @@ -864,7 +854,6 @@ static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, { struct isp1760_hcd *priv = hcd_to_priv(hcd); u32 skip_map, or_map; - u32 queue_entry; u32 slot; u32 buffstatus; @@ -880,15 +869,14 @@ static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, BUG_ON(!skip_map); slot = __ffs(skip_map); - queue_entry = 1 << slot; - enqueue_one_atl_qtd(priv, qh, slot, qtd); + enqueue_one_atl_qtd(hcd, qh, slot, qtd); or_map = reg_read32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG); - or_map |= queue_entry; + or_map |= (1 << slot); reg_write32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG, or_map); - skip_map &= ~queue_entry; + skip_map &= ~(1 << slot); reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, skip_map); priv->atl_queued++; @@ -904,9 +892,7 @@ static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, struct isp1760_qtd *qtd) { - struct isp1760_hcd *priv = hcd_to_priv(hcd); u32 skip_map, or_map; - u32 queue_entry; u32 slot; u32 buffstatus; @@ -922,15 +908,14 @@ static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, BUG_ON(!skip_map); slot = __ffs(skip_map); - queue_entry = 1 << slot; - enqueue_one_int_qtd(priv, qh, slot, qtd); + enqueue_one_int_qtd(hcd, qh, slot, qtd); or_map = reg_read32(hcd->regs, HC_INT_IRQ_MASK_OR_REG); - or_map |= queue_entry; + or_map |= (1 << slot); reg_write32(hcd->regs, HC_INT_IRQ_MASK_OR_REG, or_map); - skip_map &= ~queue_entry; + skip_map &= ~(1 << slot); reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, skip_map); buffstatus = reg_read32(hcd->regs, HC_BUFFER_STATUS_REG); @@ -938,14 +923,15 @@ static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, reg_write32(hcd->regs, HC_BUFFER_STATUS_REG, buffstatus); } -static void isp1760_urb_done(struct isp1760_hcd *priv, struct urb *urb, - int status) +static void isp1760_urb_done(struct usb_hcd *hcd, struct urb *urb) __releases(priv->lock) __acquires(priv->lock) { + struct isp1760_hcd *priv = hcd_to_priv(hcd); + if (!urb->unlinked) { - if (status == -EINPROGRESS) - status = 0; + if (urb->status == -EINPROGRESS) + urb->status = 0; } if (usb_pipein(urb->pipe) && usb_pipetype(urb->pipe) != PIPE_CONTROL) { @@ -957,9 +943,9 @@ __acquires(priv->lock) } /* complete() can reenter this HCD */ - usb_hcd_unlink_urb_from_ep(priv_to_hcd(priv), urb); + usb_hcd_unlink_urb_from_ep(hcd, urb); spin_unlock(&priv->lock); - usb_hcd_giveback_urb(priv_to_hcd(priv), urb, status); + usb_hcd_giveback_urb(hcd, urb, urb->status); spin_lock(&priv->lock); } @@ -1019,8 +1005,8 @@ static void do_atl_int(struct usb_hcd *hcd) struct isp1760_hcd *priv = hcd_to_priv(hcd); u32 done_map, skip_map; struct ptd ptd; - struct urb *urb = NULL; - u32 queue_entry; + struct urb *urb; + u32 slot; u32 length; u32 or_map; u32 status = -EINVAL; @@ -1041,19 +1027,18 @@ static void do_atl_int(struct usb_hcd *hcd) status = 0; priv->atl_queued--; - queue_entry = __ffs(done_map); - done_map &= ~(1 << queue_entry); - skip_map |= 1 << queue_entry; + slot = __ffs(done_map); + done_map &= ~(1 << slot); + skip_map |= (1 << slot); - qtd = priv->atl_ints[queue_entry].qtd; - urb = qtd->urb; - qh = priv->atl_ints[queue_entry].qh; + qtd = priv->atl_ints[slot].qtd; + qh = priv->atl_ints[slot].qh; if (!qh) { - printk(KERN_ERR "qh is 0\n"); + dev_err(hcd->self.controller, "qh is 0\n"); continue; } - ptd_read(hcd->regs, ATL_PTD_OFFSET, queue_entry, &ptd); + ptd_read(hcd->regs, ATL_PTD_OFFSET, slot, &ptd); rl = (ptd.dw2 >> 25) & 0x0f; nakcount = (ptd.dw3 >> 19) & 0xf; @@ -1070,7 +1055,8 @@ static void do_atl_int(struct usb_hcd *hcd) */ length = PTD_XFERRED_LENGTH(ptd.dw3); - printk(KERN_ERR "Should reload now.... transfered %d " + dev_err(hcd->self.controller, + "Should reload now... transferred %d " "of %zu\n", length, qtd->length); BUG(); } @@ -1095,13 +1081,13 @@ static void do_atl_int(struct usb_hcd *hcd) * is unchanged. Just make sure that this entry is * unskipped once it gets written to the HW. */ - skip_map &= ~(1 << queue_entry); + skip_map &= ~(1 << slot); or_map = reg_read32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG); - or_map |= 1 << queue_entry; + or_map |= 1 << slot; reg_write32(hcd->regs, HC_ATL_IRQ_MASK_OR_REG, or_map); ptd.dw0 |= PTD_VALID; - ptd_write(hcd->regs, ATL_PTD_OFFSET, queue_entry, &ptd); + ptd_write(hcd->regs, ATL_PTD_OFFSET, slot, &ptd); priv->atl_queued++; if (priv->atl_queued == 2) @@ -1116,12 +1102,12 @@ static void do_atl_int(struct usb_hcd *hcd) continue; } - error = check_error(&ptd); + error = check_error(hcd, &ptd); if (error) { status = error; - priv->atl_ints[queue_entry].qh->toggle = 0; - priv->atl_ints[queue_entry].qh->ping = 0; - urb->status = -EPIPE; + priv->atl_ints[slot].qh->toggle = 0; + priv->atl_ints[slot].qh->ping = 0; + qtd->urb->status = -EPIPE; #if 0 printk(KERN_ERR "Error in %s().\n", __func__); @@ -1132,10 +1118,10 @@ static void do_atl_int(struct usb_hcd *hcd) ptd.dw4, ptd.dw5, ptd.dw6, ptd.dw7); #endif } else { - if (usb_pipetype(urb->pipe) == PIPE_BULK) { - priv->atl_ints[queue_entry].qh->toggle = + if (usb_pipetype(qtd->urb->pipe) == PIPE_BULK) { + priv->atl_ints[slot].qh->toggle = ptd.dw3 & (1 << 25); - priv->atl_ints[queue_entry].qh->ping = + priv->atl_ints[slot].qh->ping = ptd.dw3 & (1 << 26); } } @@ -1149,51 +1135,55 @@ static void do_atl_int(struct usb_hcd *hcd) case OUT_PID: - urb->actual_length += length; + qtd->urb->actual_length += length; case SETUP_PID: break; } } - priv->atl_ints[queue_entry].qtd = NULL; - priv->atl_ints[queue_entry].qh = NULL; + priv->atl_ints[slot].qtd = NULL; + priv->atl_ints[slot].qh = NULL; - free_mem(priv, qtd); + free_mem(hcd, qtd); reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, skip_map); - if (urb->status == -EPIPE) { + if (qtd->urb->status == -EPIPE) { /* HALT was received */ + urb = qtd->urb; qtd = clean_up_qtdlist(qtd, qh); - isp1760_urb_done(priv, urb, urb->status); + isp1760_urb_done(hcd, urb); - } else if (usb_pipebulk(urb->pipe) && (length < qtd->length)) { + } else if (usb_pipebulk(qtd->urb->pipe) && + (length < qtd->length)) { /* short BULK received */ - if (urb->transfer_flags & URB_SHORT_NOT_OK) { - urb->status = -EREMOTEIO; - isp1760_dbg(priv, "short bulk, %d instead %zu " - "with URB_SHORT_NOT_OK flag.\n", - length, qtd->length); + if (qtd->urb->transfer_flags & URB_SHORT_NOT_OK) { + qtd->urb->status = -EREMOTEIO; + dev_dbg(hcd->self.controller, + "short bulk, %d instead %zu " + "with URB_SHORT_NOT_OK flag.\n", + length, qtd->length); } - if (urb->status == -EINPROGRESS) - urb->status = 0; + if (qtd->urb->status == -EINPROGRESS) + qtd->urb->status = 0; + urb = qtd->urb; qtd = clean_up_qtdlist(qtd, qh); - - isp1760_urb_done(priv, urb, urb->status); + isp1760_urb_done(hcd, urb); } else if (last_qtd_of_urb(qtd, qh)) { /* that was the last qtd of that URB */ - if (urb->status == -EINPROGRESS) - urb->status = 0; + if (qtd->urb->status == -EINPROGRESS) + qtd->urb->status = 0; - qtd = clean_this_qtd(qtd, qh); - isp1760_urb_done(priv, urb, urb->status); + urb = qtd->urb; + qtd = clean_up_qtdlist(qtd, qh); + isp1760_urb_done(hcd, urb); } else { /* next QTD of this URB */ @@ -1217,11 +1207,11 @@ static void do_intl_int(struct usb_hcd *hcd) struct isp1760_hcd *priv = hcd_to_priv(hcd); u32 done_map, skip_map; struct ptd ptd; - struct urb *urb = NULL; + struct urb *urb; u32 length; u32 or_map; int error; - u32 queue_entry; + u32 slot; struct isp1760_qtd *qtd; struct isp1760_qh *qh; @@ -1233,23 +1223,22 @@ static void do_intl_int(struct usb_hcd *hcd) reg_write32(hcd->regs, HC_INT_IRQ_MASK_OR_REG, or_map); while (done_map) { - queue_entry = __ffs(done_map); - done_map &= ~(1 << queue_entry); - skip_map |= 1 << queue_entry; + slot = __ffs(done_map); + done_map &= ~(1 << slot); + skip_map |= (1 << slot); - qtd = priv->int_ints[queue_entry].qtd; - urb = qtd->urb; - qh = priv->int_ints[queue_entry].qh; + qtd = priv->int_ints[slot].qtd; + qh = priv->int_ints[slot].qh; if (!qh) { - printk(KERN_ERR "(INT) qh is 0\n"); + dev_err(hcd->self.controller, "(INT) qh is 0\n"); continue; } - ptd_read(hcd->regs, INT_PTD_OFFSET, queue_entry, &ptd); - check_int_err_status(ptd.dw4); + ptd_read(hcd->regs, INT_PTD_OFFSET, slot, &ptd); + check_int_err_status(hcd, ptd.dw4); - error = check_error(&ptd); + error = check_error(hcd, &ptd); if (error) { #if 0 printk(KERN_ERR "Error in %s().\n", __func__); @@ -1259,18 +1248,16 @@ static void do_intl_int(struct usb_hcd *hcd) ptd.dw0, ptd.dw1, ptd.dw2, ptd.dw3, ptd.dw4, ptd.dw5, ptd.dw6, ptd.dw7); #endif - urb->status = -EPIPE; - priv->int_ints[queue_entry].qh->toggle = 0; - priv->int_ints[queue_entry].qh->ping = 0; + qtd->urb->status = -EPIPE; + priv->int_ints[slot].qh->toggle = 0; + priv->int_ints[slot].qh->ping = 0; } else { - priv->int_ints[queue_entry].qh->toggle = - ptd.dw3 & (1 << 25); - priv->int_ints[queue_entry].qh->ping = - ptd.dw3 & (1 << 26); + priv->int_ints[slot].qh->toggle = ptd.dw3 & (1 << 25); + priv->int_ints[slot].qh->ping = ptd.dw3 & (1 << 26); } - if (urb->dev->speed != USB_SPEED_HIGH) + if (qtd->urb->dev->speed != USB_SPEED_HIGH) length = PTD_XFERRED_LENGTH_LO(ptd.dw3); else length = PTD_XFERRED_LENGTH(ptd.dw3); @@ -1282,32 +1269,34 @@ static void do_intl_int(struct usb_hcd *hcd) qtd->data_buffer, length); case OUT_PID: - urb->actual_length += length; + qtd->urb->actual_length += length; case SETUP_PID: break; } } - priv->int_ints[queue_entry].qtd = NULL; - priv->int_ints[queue_entry].qh = NULL; + priv->int_ints[slot].qtd = NULL; + priv->int_ints[slot].qh = NULL; reg_write32(hcd->regs, HC_INT_PTD_SKIPMAP_REG, skip_map); - free_mem(priv, qtd); + free_mem(hcd, qtd); - if (urb->status == -EPIPE) { + if (qtd->urb->status == -EPIPE) { /* HALT received */ - qtd = clean_up_qtdlist(qtd, qh); - isp1760_urb_done(priv, urb, urb->status); + urb = qtd->urb; + qtd = clean_up_qtdlist(qtd, qh); + isp1760_urb_done(hcd, urb); } else if (last_qtd_of_urb(qtd, qh)) { - if (urb->status == -EINPROGRESS) - urb->status = 0; + if (qtd->urb->status == -EINPROGRESS) + qtd->urb->status = 0; - qtd = clean_this_qtd(qtd, qh); - isp1760_urb_done(priv, urb, urb->status); + urb = qtd->urb; + qtd = clean_up_qtdlist(qtd, qh); + isp1760_urb_done(hcd, urb); } else { /* next QTD of this URB */ @@ -1323,14 +1312,13 @@ static void do_intl_int(struct usb_hcd *hcd) } } -#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff) -static struct isp1760_qh *qh_make(struct isp1760_hcd *priv, struct urb *urb, +static struct isp1760_qh *qh_make(struct usb_hcd *hcd, struct urb *urb, gfp_t flags) { struct isp1760_qh *qh; int is_input, type; - qh = isp1760_qh_alloc(priv, flags); + qh = isp1760_qh_alloc(flags); if (!qh) return qh; @@ -1350,7 +1338,7 @@ static struct isp1760_qh *qh_make(struct isp1760_hcd *priv, struct urb *urb, * But interval 1 scheduling is simpler, and * includes high bandwidth. */ - printk(KERN_ERR "intr period %d uframes, NYET!", + dev_err(hcd->self.controller, "intr period %d uframes, NYET!", urb->interval); qh_destroy(qh); return NULL; @@ -1360,9 +1348,6 @@ static struct isp1760_qh *qh_make(struct isp1760_hcd *priv, struct urb *urb, } } - /* support for tt scheduling, and access to toggles */ - qh->dev = urb->dev; - if (!usb_pipecontrol(urb->pipe)) usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), !is_input, 1); @@ -1375,7 +1360,7 @@ static struct isp1760_qh *qh_make(struct isp1760_hcd *priv, struct urb *urb, * Returns null if it can't allocate a QH it needs to. * If the QH has TDs (urbs) already, that's great. */ -static struct isp1760_qh *qh_append_tds(struct isp1760_hcd *priv, +static struct isp1760_qh *qh_append_tds(struct usb_hcd *hcd, struct urb *urb, struct list_head *qtd_list, int epnum, void **ptr) { @@ -1384,7 +1369,7 @@ static struct isp1760_qh *qh_append_tds(struct isp1760_hcd *priv, qh = (struct isp1760_qh *)*ptr; if (!qh) { /* can't sleep here, we have priv->lock... */ - qh = qh_make(priv, urb, GFP_ATOMIC); + qh = qh_make(hcd, urb, GFP_ATOMIC); if (!qh) return qh; *ptr = qh; @@ -1395,8 +1380,7 @@ static struct isp1760_qh *qh_append_tds(struct isp1760_hcd *priv, return qh; } -static void qtd_list_free(struct isp1760_hcd *priv, struct urb *urb, - struct list_head *qtd_list) +static void qtd_list_free(struct urb *urb, struct list_head *qtd_list) { struct list_head *entry, *temp; @@ -1409,9 +1393,10 @@ static void qtd_list_free(struct isp1760_hcd *priv, struct urb *urb, } } -static int isp1760_prepare_enqueue(struct isp1760_hcd *priv, struct urb *urb, +static int isp1760_prepare_enqueue(struct usb_hcd *hcd, struct urb *urb, struct list_head *qtd_list, gfp_t mem_flags, packet_enqueue *p) { + struct isp1760_hcd *priv = hcd_to_priv(hcd); struct isp1760_qtd *qtd; int epnum; unsigned long flags; @@ -1423,11 +1408,11 @@ static int isp1760_prepare_enqueue(struct isp1760_hcd *priv, struct urb *urb, epnum = urb->ep->desc.bEndpointAddress; spin_lock_irqsave(&priv->lock, flags); - if (!HCD_HW_ACCESSIBLE(priv_to_hcd(priv))) { + if (!HCD_HW_ACCESSIBLE(hcd)) { rc = -ESHUTDOWN; goto done; } - rc = usb_hcd_link_urb_to_ep(priv_to_hcd(priv), urb); + rc = usb_hcd_link_urb_to_ep(hcd, urb); if (rc) goto done; @@ -1437,25 +1422,24 @@ static int isp1760_prepare_enqueue(struct isp1760_hcd *priv, struct urb *urb, else qh_busy = 0; - qh = qh_append_tds(priv, urb, qtd_list, epnum, &urb->ep->hcpriv); + qh = qh_append_tds(hcd, urb, qtd_list, epnum, &urb->ep->hcpriv); if (!qh) { - usb_hcd_unlink_urb_from_ep(priv_to_hcd(priv), urb); + usb_hcd_unlink_urb_from_ep(hcd, urb); rc = -ENOMEM; goto done; } if (!qh_busy) - p(priv_to_hcd(priv), qh, qtd); + p(hcd, qh, qtd); done: spin_unlock_irqrestore(&priv->lock, flags); if (!qh) - qtd_list_free(priv, urb, qtd_list); + qtd_list_free(urb, qtd_list); return rc; } -static struct isp1760_qtd *isp1760_qtd_alloc(struct isp1760_hcd *priv, - gfp_t flags) +static struct isp1760_qtd *isp1760_qtd_alloc(gfp_t flags) { struct isp1760_qtd *qtd; @@ -1469,7 +1453,8 @@ static struct isp1760_qtd *isp1760_qtd_alloc(struct isp1760_hcd *priv, /* * create a list of filled qtds for this URB; won't link into qh. */ -static struct list_head *qh_urb_transaction(struct isp1760_hcd *priv, +#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff) +static struct list_head *qh_urb_transaction(struct usb_hcd *hcd, struct urb *urb, struct list_head *head, gfp_t flags) { struct isp1760_qtd *qtd; @@ -1481,7 +1466,7 @@ static struct list_head *qh_urb_transaction(struct isp1760_hcd *priv, /* * URBs map to sequences of QTDs: one logical transaction */ - qtd = isp1760_qtd_alloc(priv, flags); + qtd = isp1760_qtd_alloc(flags); if (!qtd) return NULL; @@ -1502,7 +1487,7 @@ static struct list_head *qh_urb_transaction(struct isp1760_hcd *priv, /* ... and always at least one more pid */ token ^= DATA_TOGGLE; - qtd = isp1760_qtd_alloc(priv, flags); + qtd = isp1760_qtd_alloc(flags); if (!qtd) goto cleanup; qtd->urb = urb; @@ -1535,7 +1520,7 @@ static struct list_head *qh_urb_transaction(struct isp1760_hcd *priv, if (!buf && len) { /* XXX This looks like usb storage / SCSI bug */ - printk(KERN_ERR "buf is null, dma is %08lx len is %d\n", + dev_err(hcd->self.controller, "buf is null, dma is %08lx len is %d\n", (long unsigned)urb->transfer_dma, len); WARN_ON(1); } @@ -1551,7 +1536,7 @@ static struct list_head *qh_urb_transaction(struct isp1760_hcd *priv, if (len <= 0) break; - qtd = isp1760_qtd_alloc(priv, flags); + qtd = isp1760_qtd_alloc(flags); if (!qtd) goto cleanup; qtd->urb = urb; @@ -1577,7 +1562,7 @@ static struct list_head *qh_urb_transaction(struct isp1760_hcd *priv, one_more = 1; } if (one_more) { - qtd = isp1760_qtd_alloc(priv, flags); + qtd = isp1760_qtd_alloc(flags); if (!qtd) goto cleanup; qtd->urb = urb; @@ -1592,14 +1577,13 @@ static struct list_head *qh_urb_transaction(struct isp1760_hcd *priv, return head; cleanup: - qtd_list_free(priv, urb, head); + qtd_list_free(urb, head); return NULL; } static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) { - struct isp1760_hcd *priv = hcd_to_priv(hcd); struct list_head qtd_list; packet_enqueue *pe; @@ -1608,29 +1592,27 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, switch (usb_pipetype(urb->pipe)) { case PIPE_CONTROL: case PIPE_BULK: - - if (!qh_urb_transaction(priv, urb, &qtd_list, mem_flags)) + if (!qh_urb_transaction(hcd, urb, &qtd_list, mem_flags)) return -ENOMEM; pe = enqueue_an_ATL_packet; break; case PIPE_INTERRUPT: - if (!qh_urb_transaction(priv, urb, &qtd_list, mem_flags)) + if (!qh_urb_transaction(hcd, urb, &qtd_list, mem_flags)) return -ENOMEM; pe = enqueue_an_INT_packet; break; case PIPE_ISOCHRONOUS: - printk(KERN_ERR "PIPE_ISOCHRONOUS ain't supported\n"); + dev_err(hcd->self.controller, "PIPE_ISOCHRONOUS ain't supported\n"); default: return -EPIPE; } - return isp1760_prepare_enqueue(priv, urb, &qtd_list, mem_flags, pe); + return isp1760_prepare_enqueue(hcd, urb, &qtd_list, mem_flags, pe); } -static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, - int status) +static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) { struct isp1760_hcd *priv = hcd_to_priv(hcd); struct inter_packet_info *ints; @@ -1689,13 +1671,13 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, qtd = ints->qtd; qh = ints[i].qh; - free_mem(priv, qtd); + free_mem(hcd, qtd); qtd = clean_up_qtdlist(qtd, qh); ints->qh = NULL; ints->qtd = NULL; - isp1760_urb_done(priv, urb, status); + isp1760_urb_done(hcd, urb); if (qtd) pe(hcd, qh, qtd); break; @@ -1707,7 +1689,7 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, qtd_list) { if (qtd->urb == urb) { clean_up_qtdlist(qtd, ints[i].qh); - isp1760_urb_done(priv, urb, status); + isp1760_urb_done(hcd, urb); qtd = NULL; break; } @@ -1724,27 +1706,27 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, return 0; } -static irqreturn_t isp1760_irq(struct usb_hcd *usb_hcd) +static irqreturn_t isp1760_irq(struct usb_hcd *hcd) { - struct isp1760_hcd *priv = hcd_to_priv(usb_hcd); + struct isp1760_hcd *priv = hcd_to_priv(hcd); u32 imask; irqreturn_t irqret = IRQ_NONE; spin_lock(&priv->lock); - if (!(usb_hcd->state & HC_STATE_RUNNING)) + if (!(hcd->state & HC_STATE_RUNNING)) goto leave; - imask = reg_read32(usb_hcd->regs, HC_INTERRUPT_REG); + imask = reg_read32(hcd->regs, HC_INTERRUPT_REG); if (unlikely(!imask)) goto leave; - reg_write32(usb_hcd->regs, HC_INTERRUPT_REG, imask); + reg_write32(hcd->regs, HC_INTERRUPT_REG, imask); if (imask & (HC_ATL_INT | HC_SOT_INT)) - do_atl_int(usb_hcd); + do_atl_int(hcd); if (imask & HC_INTL_INT) - do_intl_int(usb_hcd); + do_intl_int(hcd); irqret = IRQ_HANDLED; leave: @@ -1840,15 +1822,17 @@ static int check_reset_complete(struct usb_hcd *hcd, int index, /* if reset finished and it's still not enabled -- handoff */ if (!(port_status & PORT_PE)) { - printk(KERN_ERR "port %d full speed --> companion\n", - index + 1); + dev_err(hcd->self.controller, + "port %d full speed --> companion\n", + index + 1); port_status |= PORT_OWNER; port_status &= ~PORT_RWC_BITS; reg_write32(hcd->regs, HC_PORTSC1, port_status); } else - printk(KERN_ERR "port %d high speed\n", index + 1); + dev_err(hcd->self.controller, "port %d high speed\n", + index + 1); return port_status; } @@ -1961,7 +1945,7 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, /* whoever resumes must GetPortStatus to complete it!! */ if (temp & PORT_RESUME) { - printk(KERN_ERR "Port resume should be skipped.\n"); + dev_err(hcd->self.controller, "Port resume should be skipped.\n"); /* Remote Wakeup received? */ if (!priv->reset_done) { @@ -1969,8 +1953,7 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, priv->reset_done = jiffies + msecs_to_jiffies(20); /* check the port again */ - mod_timer(&priv_to_hcd(priv)->rh_timer, - priv->reset_done); + mod_timer(&hcd->rh_timer, priv->reset_done); } /* resume completed? */ @@ -1986,7 +1969,7 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, retval = handshake(hcd, HC_PORTSC1, PORT_RESUME, 0, 2000 /* 2msec */); if (retval != 0) { - isp1760_err(priv, + dev_err(hcd->self.controller, "port %d resume error %d\n", wIndex + 1, retval); goto error; @@ -2010,7 +1993,7 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, retval = handshake(hcd, HC_PORTSC1, PORT_RESET, 0, 750); if (retval != 0) { - isp1760_err(priv, "port %d reset error %d\n", + dev_err(hcd->self.controller, "port %d reset error %d\n", wIndex + 1, retval); goto error; } @@ -2026,12 +2009,12 @@ static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq, */ if (temp & PORT_OWNER) - printk(KERN_ERR "Warning: PORT_OWNER is set\n"); + dev_err(hcd->self.controller, "PORT_OWNER is set\n"); if (temp & PORT_CONNECT) { status |= USB_PORT_STAT_CONNECTION; /* status may be from integrated TT */ - status |= ehci_port_speed(priv, temp); + status |= USB_PORT_STAT_HIGH_SPEED; } if (temp & PORT_PE) status |= USB_PORT_STAT_ENABLE; @@ -2120,10 +2103,10 @@ error: return retval; } -static void isp1760_endpoint_disable(struct usb_hcd *usb_hcd, +static void isp1760_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep) { - struct isp1760_hcd *priv = hcd_to_priv(usb_hcd); + struct isp1760_hcd *priv = hcd_to_priv(hcd); struct isp1760_qh *qh; struct isp1760_qtd *qtd; unsigned long flags; @@ -2143,16 +2126,16 @@ static void isp1760_endpoint_disable(struct usb_hcd *usb_hcd, qtd_list); if (qtd->status & URB_ENQUEUED) { - spin_unlock_irqrestore(&priv->lock, flags); - isp1760_urb_dequeue(usb_hcd, qtd->urb, -ECONNRESET); + isp1760_urb_dequeue(hcd, qtd->urb, -ECONNRESET); spin_lock_irqsave(&priv->lock, flags); } else { struct urb *urb; urb = qtd->urb; clean_up_qtdlist(qtd, qh); - isp1760_urb_done(priv, urb, -ECONNRESET); + urb->status = -ECONNRESET; + isp1760_urb_done(hcd, urb); } } while (1); @@ -2184,7 +2167,7 @@ static void isp1760_stop(struct usb_hcd *hcd) mdelay(20); spin_lock_irq(&priv->lock); - ehci_reset(priv); + ehci_reset(hcd); /* Disable IRQ */ temp = reg_read32(hcd->regs, HC_HW_MODE_CTRL); reg_write32(hcd->regs, HC_HW_MODE_CTRL, temp &= ~HW_GLOBAL_INTR_EN); diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h index aadd77bc271c..870507690607 100644 --- a/drivers/usb/host/isp1760-hcd.h +++ b/drivers/usb/host/isp1760-hcd.h @@ -107,8 +107,6 @@ struct ptd { #define PAYLOAD_OFFSET 0x1000 struct inter_packet_info { -#define PTD_FIRE_NEXT (1 << 0) -#define PTD_URB_FINISHED (1 << 1) struct isp1760_qh *qh; struct isp1760_qtd *qtd; }; @@ -117,15 +115,6 @@ struct inter_packet_info { typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh, struct isp1760_qtd *qtd); -#define isp1760_dbg(priv, fmt, args...) \ - dev_dbg(priv_to_hcd(priv)->self.controller, fmt, ##args) - -#define isp1760_info(priv, fmt, args...) \ - dev_info(priv_to_hcd(priv)->self.controller, fmt, ##args) - -#define isp1760_err(priv, fmt, args...) \ - dev_err(priv_to_hcd(priv)->self.controller, fmt, ##args) - /* * Device flags that can vary from board to board. All of these * indicate the most "atypical" case, so that a devflags of 0 is -- cgit v1.2.3 From 65f1b5255ce0e657e4d8de92098837d36831320a Mon Sep 17 00:00:00 2001 From: Arvid Brodin Date: Sat, 26 Feb 2011 22:07:35 +0100 Subject: usb/isp1760: Replace period calculation for INT packets with something readable Replace the period calculation for INT packets with something readable. Seems to fix a rare bug with quickly repeated insertion/removal of several USB devices simultaneously (hub control INT packets). Signed-off-by: Arvid Brodin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp1760-hcd.c | 106 ++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 69 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 0f5b48946739..fd718ff6afab 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -97,9 +97,6 @@ struct isp1760_qh { /* first part defined by EHCI spec */ struct list_head qtd_list; - /* periodic schedule info */ - unsigned short period; /* polling interval */ - u32 toggle; u32 ping; }; @@ -673,60 +670,51 @@ static void transform_into_atl(struct isp1760_qh *qh, static void transform_add_int(struct isp1760_qh *qh, struct isp1760_qtd *qtd, struct ptd *ptd) { - u32 maxpacket; - u32 multi; - u32 numberofusofs; - u32 i; - u32 usofmask, usof; + u32 usof; u32 period; - maxpacket = usb_maxpacket(qtd->urb->dev, qtd->urb->pipe, - usb_pipeout(qtd->urb->pipe)); - multi = 1 + ((maxpacket >> 11) & 0x3); - maxpacket &= 0x7ff; - /* length of the data per uframe */ - maxpacket = multi * maxpacket; - - numberofusofs = qtd->urb->transfer_buffer_length / maxpacket; - if (qtd->urb->transfer_buffer_length % maxpacket) - numberofusofs += 1; - - usofmask = 1; - usof = 0; - for (i = 0; i < numberofusofs; i++) { - usof |= usofmask; - usofmask <<= 1; - } - - if (qtd->urb->dev->speed != USB_SPEED_HIGH) { - /* split */ - ptd->dw5 = 0x1c; + /* + * Most of this is guessing. ISP1761 datasheet is quite unclear, and + * the algorithm from the original Philips driver code, which was + * pretty much used in this driver before as well, is quite horrendous + * and, i believe, incorrect. The code below follows the datasheet and + * USB2.0 spec as far as I can tell, and plug/unplug seems to be much + * more reliable this way (fingers crossed...). + */ - if (qh->period >= 32) - period = qh->period / 2; + if (qtd->urb->dev->speed == USB_SPEED_HIGH) { + /* urb->interval is in units of microframes (1/8 ms) */ + period = qtd->urb->interval >> 3; + + if (qtd->urb->interval > 4) + usof = 0x01; /* One bit set => + interval 1 ms * uFrame-match */ + else if (qtd->urb->interval > 2) + usof = 0x22; /* Two bits set => interval 1/2 ms */ + else if (qtd->urb->interval > 1) + usof = 0x55; /* Four bits set => interval 1/4 ms */ else - period = qh->period; - + usof = 0xff; /* All bits set => interval 1/8 ms */ } else { + /* urb->interval is in units of frames (1 ms) */ + period = qtd->urb->interval; + usof = 0x0f; /* Execute Start Split on any of the + four first uFrames */ - if (qh->period >= 8) - period = qh->period/8; - else - period = qh->period; - - if (period >= 32) - period = 16; - - if (qh->period >= 8) { - /* millisecond period */ - period = (period << 3); - } else { - /* usof based tranmsfers */ - /* minimum 4 usofs */ - usof = 0x11; - } + /* + * First 8 bits in dw5 is uSCS and "specifies which uSOF the + * complete split needs to be sent. Valid only for IN." Also, + * "All bits can be set to one for every transfer." (p 82, + * ISP1761 data sheet.) 0x1c is from Philips driver. Where did + * that number come from? 0xff seems to work fine... + */ + /* ptd->dw5 = 0x1c; */ + ptd->dw5 = 0xff; /* Execute Complete Split on any uFrame */ } + period = period >> 1;/* Ensure equal or shorter period than requested */ + period &= 0xf8; /* Mask off too large values and lowest unused 3 bits */ + ptd->dw2 |= period; ptd->dw4 = usof; } @@ -1328,26 +1316,6 @@ static struct isp1760_qh *qh_make(struct usb_hcd *hcd, struct urb *urb, is_input = usb_pipein(urb->pipe); type = usb_pipetype(urb->pipe); - if (type == PIPE_INTERRUPT) { - - if (urb->dev->speed == USB_SPEED_HIGH) { - - qh->period = urb->interval >> 3; - if (qh->period == 0 && urb->interval != 1) { - /* NOTE interval 2 or 4 uframes could work. - * But interval 1 scheduling is simpler, and - * includes high bandwidth. - */ - dev_err(hcd->self.controller, "intr period %d uframes, NYET!", - urb->interval); - qh_destroy(qh); - return NULL; - } - } else { - qh->period = urb->interval; - } - } - if (!usb_pipecontrol(urb->pipe)) usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), !is_input, 1); -- cgit v1.2.3 From 7adc14b14b43b6ca9f2f00ac7a4780577dbe883b Mon Sep 17 00:00:00 2001 From: Arvid Brodin Date: Sat, 26 Feb 2011 22:08:47 +0100 Subject: usb/isp1760: Handle toggle bit in queue heads only Remove redundant "toggle" member from struct isp1760_qtd, and store toggle status in struct isp1760_qh only. Signed-off-by: Arvid Brodin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp1760-hcd.c | 54 ++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index fd718ff6afab..d2b674ace0be 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -78,8 +78,6 @@ static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd) struct isp1760_qtd { u8 packet_type; - u8 toggle; - void *data_buffer; u32 payload_addr; @@ -588,6 +586,18 @@ static u32 base_to_chip(u32 base) return ((base - 0x400) >> 3); } +static int last_qtd_of_urb(struct isp1760_qtd *qtd, struct isp1760_qh *qh) +{ + struct urb *urb; + + if (list_is_last(&qtd->qtd_list, &qh->qtd_list)) + return 1; + + urb = qtd->urb; + qtd = list_entry(qtd->qtd_list.next, typeof(*qtd), qtd_list); + return (qtd->urb != urb); +} + static void transform_into_atl(struct isp1760_qh *qh, struct isp1760_qtd *qtd, struct ptd *ptd) { @@ -656,11 +666,13 @@ static void transform_into_atl(struct isp1760_qh *qh, ptd->dw3 |= PTD_NAC_CNT(nak); /* DW3 */ - if (usb_pipecontrol(qtd->urb->pipe)) - ptd->dw3 |= PTD_DATA_TOGGLE(qtd->toggle); - else - ptd->dw3 |= qh->toggle; - + ptd->dw3 |= qh->toggle; + if (usb_pipecontrol(qtd->urb->pipe)) { + if (qtd->data_buffer == qtd->urb->setup_packet) + ptd->dw3 &= ~PTD_DATA_TOGGLE(1); + else if (last_qtd_of_urb(qtd, qh)) + ptd->dw3 |= PTD_DATA_TOGGLE(1); + } ptd->dw3 |= PTD_ACTIVE; /* Cerr */ @@ -733,7 +745,6 @@ static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len, qtd->data_buffer = databuffer; qtd->packet_type = GET_QTD_TOKEN_TYPE(token); - qtd->toggle = GET_DATA_TOGGLE(token); if (len > MAX_PAYLOAD_SIZE) count = MAX_PAYLOAD_SIZE; @@ -976,18 +987,6 @@ static struct isp1760_qtd *clean_up_qtdlist(struct isp1760_qtd *qtd, return qtd; } -static int last_qtd_of_urb(struct isp1760_qtd *qtd, struct isp1760_qh *qh) -{ - struct urb *urb; - - if (list_is_last(&qtd->qtd_list, &qh->qtd_list)) - return 1; - - urb = qtd->urb; - qtd = list_entry(qtd->qtd_list.next, typeof(*qtd), qtd_list); - return (qtd->urb != urb); -} - static void do_atl_int(struct usb_hcd *hcd) { struct isp1760_hcd *priv = hcd_to_priv(hcd); @@ -1106,12 +1105,8 @@ static void do_atl_int(struct usb_hcd *hcd) ptd.dw4, ptd.dw5, ptd.dw6, ptd.dw7); #endif } else { - if (usb_pipetype(qtd->urb->pipe) == PIPE_BULK) { - priv->atl_ints[slot].qh->toggle = - ptd.dw3 & (1 << 25); - priv->atl_ints[slot].qh->ping = - ptd.dw3 & (1 << 26); - } + priv->atl_ints[slot].qh->toggle = ptd.dw3 & (1 << 25); + priv->atl_ints[slot].qh->ping = ptd.dw3 & (1 << 26); } length = PTD_XFERRED_LENGTH(ptd.dw3); @@ -1454,7 +1449,6 @@ static struct list_head *qh_urb_transaction(struct usb_hcd *hcd, token | SETUP_PID); /* ... and always at least one more pid */ - token ^= DATA_TOGGLE; qtd = isp1760_qtd_alloc(flags); if (!qtd) goto cleanup; @@ -1497,10 +1491,6 @@ static struct list_head *qh_urb_transaction(struct usb_hcd *hcd, len -= this_qtd_len; buf += this_qtd_len; - /* qh makes control packets use qtd toggle; maybe switch it */ - if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0) - token ^= DATA_TOGGLE; - if (len <= 0) break; @@ -1522,8 +1512,6 @@ static struct list_head *qh_urb_transaction(struct usb_hcd *hcd, one_more = 1; /* "in" <--> "out" */ token ^= IN_PID; - /* force DATA1 */ - token |= DATA_TOGGLE; } else if (usb_pipebulk(urb->pipe) && (urb->transfer_flags & URB_ZERO_PACKET) && !(urb->transfer_buffer_length % maxpacket)) { -- cgit v1.2.3 From f7d7aedfcd4e20e7dfc7356d30cc22dc0b0f493e Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 28 Feb 2011 10:34:05 +0100 Subject: USB: serial/keyspan_pda, fix potential tty NULL dereferences Make sure that we check the return value of tty_port_tty_get. Sometimes it may return NULL and we later dereference that. There are several places to check. For easier handling, tty_port_tty_get is moved directly to the palce where needed in keyspan_pda_rx_interrupt. Signed-off-by: Jiri Slaby Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/keyspan_pda.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 554a8693a463..7b690f3282a2 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -173,7 +173,8 @@ static void keyspan_pda_wakeup_write(struct work_struct *work) container_of(work, struct keyspan_pda_private, wakeup_work); struct usb_serial_port *port = priv->port; struct tty_struct *tty = tty_port_tty_get(&port->port); - tty_wakeup(tty); + if (tty) + tty_wakeup(tty); tty_kref_put(tty); } @@ -206,7 +207,7 @@ static void keyspan_pda_request_unthrottle(struct work_struct *work) static void keyspan_pda_rx_interrupt(struct urb *urb) { struct usb_serial_port *port = urb->context; - struct tty_struct *tty = tty_port_tty_get(&port->port); + struct tty_struct *tty; unsigned char *data = urb->transfer_buffer; int retval; int status = urb->status; @@ -223,7 +224,7 @@ static void keyspan_pda_rx_interrupt(struct urb *urb) /* this urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", __func__, status); - goto out; + return; default: dbg("%s - nonzero urb status received: %d", __func__, status); @@ -233,12 +234,14 @@ static void keyspan_pda_rx_interrupt(struct urb *urb) /* see if the message is data or a status interrupt */ switch (data[0]) { case 0: - /* rest of message is rx data */ - if (urb->actual_length) { + tty = tty_port_tty_get(&port->port); + /* rest of message is rx data */ + if (tty && urb->actual_length) { tty_insert_flip_string(tty, data + 1, urb->actual_length - 1); tty_flip_buffer_push(tty); } + tty_kref_put(tty); break; case 1: /* status interrupt */ @@ -265,8 +268,6 @@ exit: dev_err(&port->dev, "%s - usb_submit_urb failed with result %d", __func__, retval); -out: - tty_kref_put(tty); } -- cgit v1.2.3 From 6960f40a954619857e7095a6179eef896f297077 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 28 Feb 2011 10:34:06 +0100 Subject: USB: serial/kobil_sct, fix potential tty NULL dereference Make sure that we check the return value of tty_port_tty_get. Sometimes it may return NULL and we later dereference that. The only place here is in kobil_read_int_callback, so fix it. Signed-off-by: Jiri Slaby Cc: Alan Cox Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/kobil_sct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index bd5bd8589e04..b382d9a0274d 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -372,7 +372,7 @@ static void kobil_read_int_callback(struct urb *urb) } tty = tty_port_tty_get(&port->port); - if (urb->actual_length) { + if (tty && urb->actual_length) { /* BEGIN DEBUG */ /* -- cgit v1.2.3 From 4cbbf084436caddeb815534df4ebaa018c970196 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 28 Feb 2011 10:44:50 +0200 Subject: usb: musb: gadget: fix list_head usage commit ad1adb89a0d9410345d573b6995a1fa9f9b7c74a (usb: musb: gadget: do not poke with gadget's list_head) fixed a bug in musb where it was corrupting the list_head which is supposed to be used by gadget drivers. While doing that, I forgot to fix the usage in musb_gadget_dequeue() method. Fix that. Reported-by: Pavol Kurina Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index da8c93bfb6fb..2a3aee4e108f 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1274,7 +1274,8 @@ cleanup: static int musb_gadget_dequeue(struct usb_ep *ep, struct usb_request *request) { struct musb_ep *musb_ep = to_musb_ep(ep); - struct usb_request *r; + struct musb_request *req = to_musb_request(request); + struct musb_request *r; unsigned long flags; int status = 0; struct musb *musb = musb_ep->musb; @@ -1285,10 +1286,10 @@ static int musb_gadget_dequeue(struct usb_ep *ep, struct usb_request *request) spin_lock_irqsave(&musb->lock, flags); list_for_each_entry(r, &musb_ep->req_list, list) { - if (r == request) + if (r == req) break; } - if (r != request) { + if (r != req) { DBG(3, "request %p not queued to %s\n", request, ep->name); status = -EINVAL; goto done; -- cgit v1.2.3 From da68ccec210c45eb99e461ad31b499b4e7043c41 Mon Sep 17 00:00:00 2001 From: Hema HK Date: Mon, 28 Feb 2011 14:19:33 +0530 Subject: usb: musb: Remove platform context save/restore API For OMAP3 and OMAP4 for offmode and retention support, musb sysconfig is configured to force idle and standby with ENABLE_FORCE bit of OTG_FORCESTNDBY set. And on wakeup configure to no ilde/standby with resetting the ENABLE_FORCE bit. There is not need to save and restore of this register anymore so removed omap2430_save_context/omap2430_restore_context functions. and also removed otg_forcestandby member of musb_context_registers structure Signed-off-by: Hema HK Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.h | 4 ---- drivers/usb/musb/omap2430.c | 11 ----------- 2 files changed, 15 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 5216729bd4b2..5cb50f8f2907 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -358,10 +358,6 @@ struct musb_csr_regs { struct musb_context_registers { -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ - defined(CONFIG_ARCH_OMAP4) - u32 otg_forcestandby; -#endif u8 power; u16 intrtxe, intrrxe; u8 intrusbe; diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 64cf2431c05e..b6dcc7eaa21f 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -488,15 +488,6 @@ static int __exit omap2430_remove(struct platform_device *pdev) } #ifdef CONFIG_PM -static void omap2430_save_context(struct musb *musb) -{ - musb->context.otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY); -} - -static void omap2430_restore_context(struct musb *musb) -{ - musb_writel(musb->mregs, OTG_FORCESTDBY, musb->context.otg_forcestandby); -} static int omap2430_suspend(struct device *dev) { @@ -505,7 +496,6 @@ static int omap2430_suspend(struct device *dev) omap2430_low_level_exit(musb); otg_set_suspend(musb->xceiv, 1); - omap2430_save_context(musb); if (!pm_runtime_suspended(dev) && dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend) @@ -524,7 +514,6 @@ static int omap2430_resume(struct device *dev) dev->bus->pm->runtime_resume(dev); omap2430_low_level_init(musb); - omap2430_restore_context(musb); otg_set_suspend(musb->xceiv, 0); return 0; -- cgit v1.2.3 From 7acc6197b76edd0b932a7cbcc6cfad0a8a87f026 Mon Sep 17 00:00:00 2001 From: Hema HK Date: Mon, 28 Feb 2011 14:19:34 +0530 Subject: usb: musb: Idle path retention and offmode support for OMAP3 This patch supports the retention and offmode support in the idle path for musb driver using runtime pm APIs. This is restricted to support offmode and retention only when device not connected.When device/cable connected with gadget driver loaded,configured to no idle/standby which will not allow the core transition to retention or off. There is no context save/restore done by hardware for musb in OMAP3 and OMAP4,driver has to take care of saving and restoring the context during offmode. Musb has a requirement of configuring sysconfig register to force idle/standby mode and set the ENFORCE bit in module STANDBY register for retention and offmode support. Runtime pm and hwmod frameworks will take care of configuring to force idle/standby when pm_runtime_put_sync is called and back to no idle/standby when pm_runeime_get_sync is called. Compile, boot tested and also tested the retention in the idle path on OMAP3630Zoom3. And tested the global suspend/resume with offmode enabled. Usb basic functionality tested on OMAP4430SDP. There is some problem with idle path offmode in mainline, I could not test with offmode. But I have tested this patch with resetting the controller in the idle path when wakeup from retention just to make sure that the context is lost, and restore path is working fine. Removed .suspend/.resume fnction pointers and functions because there is no need of having these functions as all required work is done at runtime in the driver. There is no need to call the runtime pm api with glue driver device as glue layer device is the parent of musb core device, when runtime apis are called for the child, parent device runtime functionality will be invoked. Design overview: pm_runtime_get_sync: When called with musb core device takes care of enabling the clock, calling runtime callback function of omap2430 glue layer, runtime call back of musb driver and configure the musb sysconfig to no idle/standby pm_runtime_put: Takes care of calling runtime callback function of omap2430 glue layer, runtime call back of musb driver, Configure the musb sysconfig to force idle/standby and disable the clock. During musb driver load: Call pm_runtime_get_sync. End of musb driver load: Call pm_runtime_put During gadget driver load: Call pm_runtime_get_sync, End of gadget driver load: Call pm_runtime_put if there is no device or cable is connected. During unload of the gadget driver:Call pm_runtime_get_sync if cable/device is not connected. End of the gadget driver unload : pm_runtime_put During unload of musb driver : Call pm_runtime_get_sync End of unload: Call pm_runtime_put On connect of usb cable/device -> transceiver notification(VBUS and ID-GND): pm_runtime_get_sync only if the gadget driver loaded. On disconnect of the cable/device -> Disconnect Notification: pm_runtime_put if the gadget driver is loaded. Signed-off-by: Hema HK Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 40 ++++++++++++++++++++++++++++++++++ drivers/usb/musb/musb_gadget.c | 11 ++++++++++ drivers/usb/musb/omap2430.c | 49 +++++++++++++++++++++++------------------- 3 files changed, 78 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index bc296557dc1b..36376d2b1a7c 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1956,6 +1956,10 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) goto fail0; } + pm_runtime_use_autosuspend(musb->controller); + pm_runtime_set_autosuspend_delay(musb->controller, 200); + pm_runtime_enable(musb->controller); + spin_lock_init(&musb->lock); musb->board_mode = plat->mode; musb->board_set_power = plat->set_power; @@ -2091,6 +2095,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) if (status < 0) goto fail3; + pm_runtime_put(musb->controller); + status = musb_init_debugfs(musb); if (status < 0) goto fail4; @@ -2190,9 +2196,11 @@ static int __exit musb_remove(struct platform_device *pdev) * - Peripheral mode: peripheral is deactivated (or never-activated) * - OTG mode: both roles are deactivated (or never-activated) */ + pm_runtime_get_sync(musb->controller); musb_exit_debugfs(musb); musb_shutdown(pdev); + pm_runtime_put(musb->controller); musb_free(musb); iounmap(ctrl_base); device_init_wakeup(&pdev->dev, 0); @@ -2378,9 +2386,41 @@ static int musb_resume_noirq(struct device *dev) return 0; } +static int musb_runtime_suspend(struct device *dev) +{ + struct musb *musb = dev_to_musb(dev); + + musb_save_context(musb); + + return 0; +} + +static int musb_runtime_resume(struct device *dev) +{ + struct musb *musb = dev_to_musb(dev); + static int first = 1; + + /* + * When pm_runtime_get_sync called for the first time in driver + * init, some of the structure is still not initialized which is + * used in restore function. But clock needs to be + * enabled before any register access, so + * pm_runtime_get_sync has to be called. + * Also context restore without save does not make + * any sense + */ + if (!first) + musb_restore_context(musb); + first = 0; + + return 0; +} + static const struct dev_pm_ops musb_dev_pm_ops = { .suspend = musb_suspend, .resume_noirq = musb_resume_noirq, + .runtime_suspend = musb_runtime_suspend, + .runtime_resume = musb_runtime_resume, }; #define MUSB_DEV_PM_OPS (&musb_dev_pm_ops) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 2a3aee4e108f..5c7b321d3959 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1821,6 +1821,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, goto err0; } + pm_runtime_get_sync(musb->controller); + DBG(3, "registering driver %s\n", driver->function); if (musb->gadget_driver) { @@ -1885,6 +1887,10 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, } hcd->self.uses_pio_for_control = 1; + + if (musb->xceiv->last_event == USB_EVENT_NONE) + pm_runtime_put(musb->controller); + } return 0; @@ -1961,6 +1967,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) if (!musb->gadget_driver) return -EINVAL; + if (musb->xceiv->last_event == USB_EVENT_NONE) + pm_runtime_get_sync(musb->controller); + /* * REVISIT always use otg_set_peripheral() here too; * this needs to shut down the OTG engine. @@ -2002,6 +2011,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) if (!is_otg_enabled(musb)) musb_stop(musb); + pm_runtime_put(musb->controller); + return 0; } EXPORT_SYMBOL(usb_gadget_unregister_driver); diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index b6dcc7eaa21f..47267987077d 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -244,6 +244,7 @@ static int musb_otg_notifications(struct notifier_block *nb, if (is_otg_enabled(musb)) { #ifdef CONFIG_USB_GADGET_MUSB_HDRC if (musb->gadget_driver) { + pm_runtime_get_sync(musb->controller); otg_init(musb->xceiv); if (data->interface_type == @@ -253,6 +254,7 @@ static int musb_otg_notifications(struct notifier_block *nb, } #endif } else { + pm_runtime_get_sync(musb->controller); otg_init(musb->xceiv); if (data->interface_type == MUSB_INTERFACE_UTMI) @@ -263,12 +265,24 @@ static int musb_otg_notifications(struct notifier_block *nb, case USB_EVENT_VBUS: DBG(4, "VBUS Connect\n"); + if (musb->gadget_driver) + pm_runtime_get_sync(musb->controller); + otg_init(musb->xceiv); break; case USB_EVENT_NONE: DBG(4, "VBUS Disconnect\n"); +#ifdef CONFIG_USB_GADGET_MUSB_HDRC + if (is_otg_enabled(musb)) + if (musb->gadget_driver) +#endif + { + pm_runtime_mark_last_busy(musb->controller); + pm_runtime_put_autosuspend(musb->controller); + } + if (data->interface_type == MUSB_INTERFACE_UTMI) { if (musb->xceiv->set_vbus) otg_set_vbus(musb->xceiv, 0); @@ -300,7 +314,11 @@ static int omap2430_musb_init(struct musb *musb) return -ENODEV; } - omap2430_low_level_init(musb); + status = pm_runtime_get_sync(dev); + if (status < 0) { + dev_err(dev, "pm_runtime_get_sync FAILED"); + goto err1; + } l = musb_readl(musb->mregs, OTG_INTERFSEL); @@ -331,6 +349,10 @@ static int omap2430_musb_init(struct musb *musb) setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); return 0; + +err1: + pm_runtime_disable(dev); + return status; } static void omap2430_musb_enable(struct musb *musb) @@ -407,8 +429,6 @@ static int __init omap2430_probe(struct platform_device *pdev) struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; struct omap2430_glue *glue; - int status = 0; - int ret = -ENOMEM; glue = kzalloc(sizeof(*glue), GFP_KERNEL); @@ -454,16 +474,9 @@ static int __init omap2430_probe(struct platform_device *pdev) } pm_runtime_enable(&pdev->dev); - status = pm_runtime_get_sync(&pdev->dev); - if (status < 0) { - dev_err(&pdev->dev, "pm_runtime_get_sync FAILED"); - goto err3; - } return 0; -err3: - pm_runtime_disable(&pdev->dev); err2: platform_device_put(musb); @@ -489,7 +502,7 @@ static int __exit omap2430_remove(struct platform_device *pdev) #ifdef CONFIG_PM -static int omap2430_suspend(struct device *dev) +static int omap2430_runtime_suspend(struct device *dev) { struct omap2430_glue *glue = dev_get_drvdata(dev); struct musb *musb = glue_to_musb(glue); @@ -497,22 +510,14 @@ static int omap2430_suspend(struct device *dev) omap2430_low_level_exit(musb); otg_set_suspend(musb->xceiv, 1); - if (!pm_runtime_suspended(dev) && dev->bus && dev->bus->pm && - dev->bus->pm->runtime_suspend) - dev->bus->pm->runtime_suspend(dev); - return 0; } -static int omap2430_resume(struct device *dev) +static int omap2430_runtime_resume(struct device *dev) { struct omap2430_glue *glue = dev_get_drvdata(dev); struct musb *musb = glue_to_musb(glue); - if (!pm_runtime_suspended(dev) && dev->bus && dev->bus->pm && - dev->bus->pm->runtime_resume) - dev->bus->pm->runtime_resume(dev); - omap2430_low_level_init(musb); otg_set_suspend(musb->xceiv, 0); @@ -520,8 +525,8 @@ static int omap2430_resume(struct device *dev) } static struct dev_pm_ops omap2430_pm_ops = { - .suspend = omap2430_suspend, - .resume = omap2430_resume, + .runtime_suspend = omap2430_runtime_suspend, + .runtime_resume = omap2430_runtime_resume, }; #define DEV_PM_OPS (&omap2430_pm_ops) -- cgit v1.2.3 From 37db3af11f02c2ccdf44a788694da16062a0333c Mon Sep 17 00:00:00 2001 From: Hema HK Date: Mon, 28 Feb 2011 14:19:32 +0530 Subject: usb: otg: TWL4030: Update the last_event variable. Update the last_event variable of otg_transceiver. This will be used in the musb platform glue driver for runtime idling the device. Signed-off-by: Hema HK Cc: Felipe Balbi Signed-off-by: Felipe Balbi --- drivers/usb/otg/twl4030-usb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 2362d8352bc8..e01b073cc489 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c @@ -275,6 +275,8 @@ static enum usb_xceiv_events twl4030_usb_linkstat(struct twl4030_usb *twl) dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", status, status, linkstat); + twl->otg.last_event = linkstat; + /* REVISIT this assumes host and peripheral controllers * are registered, and that both are active... */ -- cgit v1.2.3 From 70045c57f31f998a7206baa81167c7bc9f452cef Mon Sep 17 00:00:00 2001 From: Hema HK Date: Mon, 28 Feb 2011 15:05:29 +0530 Subject: usb: musb: OMAP3xxx: Fix device detection in otg & host mode In OMAP3xxx with OTG mode or host only mode, When the device is inserted after the gadget driver loading the enumeration was not through. This is because the mentor controller will start sensing the ID PIN only after setting the session bit. So after ID-GND, need to set the session bit for mentor to get it configured as A device. This is a fix to set the session bit again in ID_GND notification handler. Tested with OMAP3630Zoom3 platform. Signed-off-by: Hema HK Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 47267987077d..f5d4f368be9e 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -246,19 +246,13 @@ static int musb_otg_notifications(struct notifier_block *nb, if (musb->gadget_driver) { pm_runtime_get_sync(musb->controller); otg_init(musb->xceiv); - - if (data->interface_type == - MUSB_INTERFACE_UTMI) - omap2430_musb_set_vbus(musb, 1); - + omap2430_musb_set_vbus(musb, 1); } #endif } else { pm_runtime_get_sync(musb->controller); otg_init(musb->xceiv); - if (data->interface_type == - MUSB_INTERFACE_UTMI) - omap2430_musb_set_vbus(musb, 1); + omap2430_musb_set_vbus(musb, 1); } break; -- cgit v1.2.3 From c88ba39c1ea6a1591b6842199069ff50748d2073 Mon Sep 17 00:00:00 2001 From: Huzaifa Sidhpurwala Date: Tue, 1 Mar 2011 15:54:22 +0530 Subject: usb: musb: tusb: Fix possible null pointer dereference in tusb6010_omap.c tusb_dma was being dereferenced when it was nul Signed-off-by: Huzaifa Sidhpurwala Signed-off-by: Felipe Balbi --- drivers/usb/musb/tusb6010_omap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c index c061a88f2b0f..99cb541e4ef0 100644 --- a/drivers/usb/musb/tusb6010_omap.c +++ b/drivers/usb/musb/tusb6010_omap.c @@ -680,7 +680,7 @@ dma_controller_create(struct musb *musb, void __iomem *base) tusb_dma = kzalloc(sizeof(struct tusb_omap_dma), GFP_KERNEL); if (!tusb_dma) - goto cleanup; + goto out; tusb_dma->musb = musb; tusb_dma->tbase = musb->ctrl_base; @@ -721,6 +721,6 @@ dma_controller_create(struct musb *musb, void __iomem *base) cleanup: dma_controller_destroy(&tusb_dma->controller); - +out: return NULL; } -- cgit v1.2.3 From 87ecc73b3d74ca70100e7100313c005fa471f177 Mon Sep 17 00:00:00 2001 From: Anand Gadiyar Date: Wed, 16 Feb 2011 15:43:14 +0530 Subject: usb: ehci: omap: add support for TLL mode on OMAP4 The EHCI controller in OMAP4 supports a transceiver-less link mode (TLL mode), similar to the one in OMAP3. On the OMAP4 however, there are an additional set of clocks that need to be turned on to get this working. Request and configure these for each port if that port is connected in TLL mode. Signed-off-by: Anand Gadiyar Cc: Greg Kroah-Hartman Signed-off-by: Felipe Balbi --- drivers/usb/host/ehci-omap.c | 134 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index f784ceb862a3..d7e223be1c9c 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -195,7 +195,11 @@ struct ehci_hcd_omap { struct clk *xclk60mhsp1_ck; struct clk *xclk60mhsp2_ck; struct clk *utmi_p1_fck; + struct clk *usbhost_p1_fck; + struct clk *usbtll_p1_fck; struct clk *utmi_p2_fck; + struct clk *usbhost_p2_fck; + struct clk *usbtll_p2_fck; /* FIXME the following two workarounds are * board specific not silicon-specific so these @@ -410,6 +414,50 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) } break; case EHCI_HCD_OMAP_MODE_TLL: + omap->xclk60mhsp1_ck = clk_get(omap->dev, + "init_60m_fclk"); + if (IS_ERR(omap->xclk60mhsp1_ck)) { + ret = PTR_ERR(omap->xclk60mhsp1_ck); + dev_err(omap->dev, + "Unable to get Port1 ULPI clock\n"); + } + + omap->utmi_p1_fck = clk_get(omap->dev, + "utmi_p1_gfclk"); + if (IS_ERR(omap->utmi_p1_fck)) { + ret = PTR_ERR(omap->utmi_p1_fck); + dev_err(omap->dev, + "Unable to get utmi_p1_fck\n"); + } + + ret = clk_set_parent(omap->utmi_p1_fck, + omap->xclk60mhsp1_ck); + if (ret != 0) { + dev_err(omap->dev, + "Unable to set P1 f-clock\n"); + } + + omap->usbhost_p1_fck = clk_get(omap->dev, + "usb_host_hs_utmi_p1_clk"); + if (IS_ERR(omap->usbhost_p1_fck)) { + ret = PTR_ERR(omap->usbhost_p1_fck); + dev_err(omap->dev, + "Unable to get HOST PORT 1 clk\n"); + } else { + clk_enable(omap->usbhost_p1_fck); + } + + omap->usbtll_p1_fck = clk_get(omap->dev, + "usb_tll_hs_usb_ch0_clk"); + + if (IS_ERR(omap->usbtll_p1_fck)) { + ret = PTR_ERR(omap->usbtll_p1_fck); + dev_err(omap->dev, + "Unable to get TLL CH0 clk\n"); + } else { + clk_enable(omap->usbtll_p1_fck); + } + break; /* TODO */ default: break; @@ -440,6 +488,50 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) } break; case EHCI_HCD_OMAP_MODE_TLL: + omap->xclk60mhsp2_ck = clk_get(omap->dev, + "init_60m_fclk"); + if (IS_ERR(omap->xclk60mhsp2_ck)) { + ret = PTR_ERR(omap->xclk60mhsp2_ck); + dev_err(omap->dev, + "Unable to get Port2 ULPI clock\n"); + } + + omap->utmi_p2_fck = clk_get(omap->dev, + "utmi_p2_gfclk"); + if (IS_ERR(omap->utmi_p2_fck)) { + ret = PTR_ERR(omap->utmi_p2_fck); + dev_err(omap->dev, + "Unable to get utmi_p2_fck\n"); + } + + ret = clk_set_parent(omap->utmi_p2_fck, + omap->xclk60mhsp2_ck); + if (ret != 0) { + dev_err(omap->dev, + "Unable to set P2 f-clock\n"); + } + + omap->usbhost_p2_fck = clk_get(omap->dev, + "usb_host_hs_utmi_p2_clk"); + if (IS_ERR(omap->usbhost_p2_fck)) { + ret = PTR_ERR(omap->usbhost_p2_fck); + dev_err(omap->dev, + "Unable to get HOST PORT 2 clk\n"); + } else { + clk_enable(omap->usbhost_p2_fck); + } + + omap->usbtll_p2_fck = clk_get(omap->dev, + "usb_tll_hs_usb_ch1_clk"); + + if (IS_ERR(omap->usbtll_p2_fck)) { + ret = PTR_ERR(omap->usbtll_p2_fck); + dev_err(omap->dev, + "Unable to get TLL CH1 clk\n"); + } else { + clk_enable(omap->usbtll_p2_fck); + } + break; /* TODO */ default: break; @@ -602,6 +694,24 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) return 0; err_sys_status: + + if (omap->usbtll_p2_fck != NULL) { + clk_disable(omap->usbtll_p2_fck); + clk_put(omap->usbtll_p2_fck); + } + if (omap->usbhost_p2_fck != NULL) { + clk_disable(omap->usbhost_p2_fck); + clk_put(omap->usbhost_p2_fck); + } + if (omap->usbtll_p1_fck != NULL) { + clk_disable(omap->usbtll_p1_fck); + clk_put(omap->usbtll_p1_fck); + } + if (omap->usbhost_p1_fck != NULL) { + clk_disable(omap->usbhost_p1_fck); + clk_put(omap->usbhost_p1_fck); + } + clk_disable(omap->utmi_p2_fck); clk_put(omap->utmi_p2_fck); clk_disable(omap->xclk60mhsp2_ck); @@ -740,6 +850,30 @@ static void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) clk_put(omap->utmi_p2_fck); omap->utmi_p2_fck = NULL; } + + if (omap->usbtll_p2_fck != NULL) { + clk_disable(omap->usbtll_p2_fck); + clk_put(omap->usbtll_p2_fck); + omap->usbtll_p2_fck = NULL; + } + + if (omap->usbhost_p2_fck != NULL) { + clk_disable(omap->usbhost_p2_fck); + clk_put(omap->usbhost_p2_fck); + omap->usbhost_p2_fck = NULL; + } + + if (omap->usbtll_p1_fck != NULL) { + clk_disable(omap->usbtll_p1_fck); + clk_put(omap->usbtll_p1_fck); + omap->usbtll_p1_fck = NULL; + } + + if (omap->usbhost_p1_fck != NULL) { + clk_disable(omap->usbhost_p1_fck); + clk_put(omap->usbhost_p1_fck); + omap->usbhost_p1_fck = NULL; + } } if (omap->phy_reset) { -- cgit v1.2.3 From 09f0607d8be62469a9b33034c8d3def9a5c7cbb7 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 1 Mar 2011 20:08:14 +0530 Subject: usb: host: omap: switch to platform_get_resource_byname now that we have names on all memory bases, we can switch to use platform_get_resource_byname() which will make it simpler when we move to a setup where OHCI and EHCI on OMAP play well together. Signed-off-by: Felipe Balbi --- drivers/usb/host/ehci-omap.c | 6 +++--- drivers/usb/host/ohci-omap3.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index d7e223be1c9c..15277213f928 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -947,7 +947,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) omap->ehci = hcd_to_ehci(hcd); omap->ehci->sbrn = 0x20; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ehci"); hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); @@ -963,7 +963,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) omap->ehci->caps = hcd->regs; omap->ehci_base = hcd->regs; - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh"); omap->uhh_base = ioremap(res->start, resource_size(res)); if (!omap->uhh_base) { dev_err(&pdev->dev, "UHH ioremap failed\n"); @@ -971,7 +971,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) goto err_uhh_ioremap; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 2); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll"); omap->tll_base = ioremap(res->start, resource_size(res)); if (!omap->tll_base) { dev_err(&pdev->dev, "TLL ioremap failed\n"); diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c index a37d5993e4e3..32f56bbec214 100644 --- a/drivers/usb/host/ohci-omap3.c +++ b/drivers/usb/host/ohci-omap3.c @@ -618,7 +618,7 @@ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev) omap->es2_compatibility = pdata->es2_compatibility; omap->ohci = hcd_to_ohci(hcd); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ohci"); hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); @@ -630,7 +630,7 @@ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev) goto err_ioremap; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh"); omap->uhh_base = ioremap(res->start, resource_size(res)); if (!omap->uhh_base) { dev_err(&pdev->dev, "UHH ioremap failed\n"); @@ -638,7 +638,7 @@ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev) goto err_uhh_ioremap; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 2); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll"); omap->tll_base = ioremap(res->start, resource_size(res)); if (!omap->tll_base) { dev_err(&pdev->dev, "TLL ioremap failed\n"); -- cgit v1.2.3 From 181b250cf53233a7a7c6d7e1e9df402506712e93 Mon Sep 17 00:00:00 2001 From: Keshava Munegowda Date: Tue, 1 Mar 2011 20:08:16 +0530 Subject: arm: omap: usb: create common enums and structures for ehci and ohci Create the ehci and ohci specific platform data structures. The port enum values are made common for both ehci and ohci. Signed-off-by: Keshava Munegowda Signed-off-by: Felipe Balbi --- arch/arm/mach-omap2/board-3430sdp.c | 10 +++--- arch/arm/mach-omap2/board-3630sdp.c | 10 +++--- arch/arm/mach-omap2/board-4430sdp.c | 10 +++--- arch/arm/mach-omap2/board-am3517crane.c | 10 +++--- arch/arm/mach-omap2/board-am3517evm.c | 12 +++---- arch/arm/mach-omap2/board-cm-t35.c | 10 +++--- arch/arm/mach-omap2/board-cm-t3517.c | 8 ++--- arch/arm/mach-omap2/board-devkit8000.c | 10 +++--- arch/arm/mach-omap2/board-igep0020.c | 10 +++--- arch/arm/mach-omap2/board-igep0030.c | 10 +++--- arch/arm/mach-omap2/board-omap3beagle.c | 10 +++--- arch/arm/mach-omap2/board-omap3evm.c | 14 ++++---- arch/arm/mach-omap2/board-omap3pandora.c | 10 +++--- arch/arm/mach-omap2/board-omap3stalker.c | 10 +++--- arch/arm/mach-omap2/board-omap3touchbook.c | 10 +++--- arch/arm/mach-omap2/board-omap4panda.c | 10 +++--- arch/arm/mach-omap2/board-overo.c | 10 +++--- arch/arm/mach-omap2/board-zoom.c | 10 +++--- arch/arm/mach-omap2/usb-host.c | 50 +++++++++++++-------------- arch/arm/plat-omap/include/plat/usb.h | 54 +++++++++++++++++++----------- drivers/usb/host/ehci-omap.c | 42 +++++++++++------------ drivers/usb/host/ohci-omap3.c | 22 ++++++------ 22 files changed, 184 insertions(+), 168 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index d4e41ef86aa5..a991aeb56091 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -653,11 +653,11 @@ static void enable_board_wakeup_source(void) OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); } -static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { +static const struct usbhs_omap_board_data usbhs_bdata __initconst = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, .phy_reset = true, .reset_gpio_port[0] = 57, @@ -816,7 +816,7 @@ static void __init omap_3430sdp_init(void) board_flash_init(sdp_flash_partitions, chip_sel_3430); sdp3430_display_init(); enable_board_wakeup_source(); - usb_ehci_init(&ehci_pdata); + usb_ehci_init(&usbhs_bdata); } MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board") diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index 62645640f5e4..03fd8aca3cc8 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -54,11 +54,11 @@ static void enable_board_wakeup_source(void) OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); } -static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { +static const struct usbhs_omap_board_data usbhs_bdata __initconst = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, .phy_reset = true, .reset_gpio_port[0] = 126, @@ -211,7 +211,7 @@ static void __init omap_sdp_init(void) board_smc91x_init(); board_flash_init(sdp_flash_partitions, chip_sel_sdp); enable_board_wakeup_source(); - usb_ehci_init(&ehci_pdata); + usb_ehci_init(&usbhs_bdata); } MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board") diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 9cf8e333255f..0e1609d3fa85 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -251,10 +251,10 @@ static void __init omap_4430sdp_init_irq(void) gic_init_irq(); } -static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN, - .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, +static const struct usbhs_omap_board_data usbhs_bdata __initconst = { + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, .phy_reset = false, .reset_gpio_port[0] = -EINVAL, .reset_gpio_port[1] = -EINVAL, @@ -584,7 +584,7 @@ static void __init omap_4430sdp_init(void) else gpio_direction_output(OMAP4SDP_MDM_PWR_EN_GPIO, 1); - usb_ehci_init(&ehci_pdata); + usb_ehci_init(&usbhs_bdata); usb_musb_init(&musb_board_data); status = omap_ethernet_init(); diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c index 71acb5ab281c..1b825a00c5b0 100644 --- a/arch/arm/mach-omap2/board-am3517crane.c +++ b/arch/arm/mach-omap2/board-am3517crane.c @@ -59,10 +59,10 @@ static void __init am3517_crane_init_irq(void) omap_init_irq(); } -static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN, - .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, +static struct usbhs_omap_board_data usbhs_bdata __initdata = { + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, .phy_reset = true, .reset_gpio_port[0] = GPIO_USB_NRESET, @@ -103,7 +103,7 @@ static void __init am3517_crane_init(void) return; } - usb_ehci_init(&ehci_pdata); + usb_ehci_init(&usbhs_bdata); } MACHINE_START(CRANEBOARD, "AM3517/05 CRANEBOARD") diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 10d60b7743cf..f5bc1c6ccf5e 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -430,15 +430,15 @@ static __init void am3517_evm_musb_init(void) usb_musb_init(&musb_board_data); } -static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, +static const struct usbhs_omap_board_data usbhs_bdata __initconst = { + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, #if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \ defined(CONFIG_PANEL_SHARP_LQ043T1DG01_MODULE) - .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN, + .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, #else - .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, #endif - .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, .phy_reset = true, .reset_gpio_port[0] = 57, @@ -502,7 +502,7 @@ static void __init am3517_evm_init(void) /* Configure GPIO for EHCI port */ omap_mux_init_gpio(57, OMAP_PIN_OUTPUT); - usb_ehci_init(&ehci_pdata); + usb_ehci_init(&usbhs_bdata); am3517_evm_hecc_init(&am3517_evm_hecc_pdata); /* DSS */ am3517_evm_display_init(); diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index dac141610666..c79aa9be72f7 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -605,10 +605,10 @@ static struct omap2_hsmmc_info mmc[] = { {} /* Terminator */ }; -static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, +static struct usbhs_omap_board_data usbhs_bdata __initdata = { + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, .phy_reset = true, .reset_gpio_port[0] = OMAP_MAX_GPIO_LINES + 6, @@ -810,7 +810,7 @@ static void __init cm_t35_init(void) cm_t35_init_display(); usb_musb_init(&musb_board_data); - usb_ehci_init(&ehci_pdata); + usb_ehci_init(&usbhs_bdata); } MACHINE_START(CM_T35, "Compulab CM-T35") diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c index 8f9a64d650ee..8288a0b9159e 100644 --- a/arch/arm/mach-omap2/board-cm-t3517.c +++ b/arch/arm/mach-omap2/board-cm-t3517.c @@ -167,10 +167,10 @@ static inline void cm_t3517_init_rtc(void) {} #define HSUSB2_RESET_GPIO (147) #define USB_HUB_RESET_GPIO (152) -static struct ehci_hcd_omap_platform_data cm_t3517_ehci_pdata __initdata = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, +static struct usbhs_omap_board_data cm_t3517_ehci_pdata __initdata = { + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, .phy_reset = true, .reset_gpio_port[0] = HSUSB1_RESET_GPIO, diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index 9a2a31e011ce..e0131dda5792 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c @@ -620,11 +620,11 @@ static struct omap_musb_board_data musb_board_data = { .power = 100, }; -static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { +static const struct usbhs_omap_board_data usbhs_bdata __initconst = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN, - .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, .phy_reset = true, .reset_gpio_port[0] = -EINVAL, @@ -803,7 +803,7 @@ static void __init devkit8000_init(void) devkit8000_ads7846_init(); usb_musb_init(&musb_board_data); - usb_ehci_init(&ehci_pdata); + usb_ehci_init(&usbhs_bdata); devkit8000_flash_init(); /* Ensure SDRC pins are mux'd for self-refresh */ diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 3be85a1f55f4..a9d7d1dc63ab 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -627,10 +627,10 @@ static struct omap_musb_board_data musb_board_data = { .power = 100, }; -static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN, - .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, +static const struct usbhs_omap_board_data usbhs_bdata __initconst = { + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, .phy_reset = true, .reset_gpio_port[0] = IGEP2_GPIO_USBH_NRESET, @@ -699,7 +699,7 @@ static void __init igep2_init(void) platform_add_devices(igep2_devices, ARRAY_SIZE(igep2_devices)); omap_serial_init(); usb_musb_init(&musb_board_data); - usb_ehci_init(&ehci_pdata); + usb_ehci_init(&usbhs_bdata); igep2_flash_init(); igep2_leds_init(); diff --git a/arch/arm/mach-omap2/board-igep0030.c b/arch/arm/mach-omap2/board-igep0030.c index 4dc62a9b9cb2..1b441eafdba7 100644 --- a/arch/arm/mach-omap2/board-igep0030.c +++ b/arch/arm/mach-omap2/board-igep0030.c @@ -408,10 +408,10 @@ static void __init igep3_wifi_bt_init(void) void __init igep3_wifi_bt_init(void) {} #endif -static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN, - .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, +static const struct usbhs_omap_board_data usbhs_bdata __initconst = { + .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, .phy_reset = true, .reset_gpio_port[0] = -EINVAL, @@ -435,7 +435,7 @@ static void __init igep3_init(void) platform_add_devices(igep3_devices, ARRAY_SIZE(igep3_devices)); omap_serial_init(); usb_musb_init(&musb_board_data); - usb_ehci_init(&ehci_pdata); + usb_ehci_init(&usbhs_bdata); igep3_flash_init(); igep3_leds_init(); diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 46d814ab5656..b84a6418ec1e 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -586,11 +586,11 @@ static void __init omap3beagle_flash_init(void) } } -static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { +static const struct usbhs_omap_board_data usbhs_bdata __initconst = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, .phy_reset = true, .reset_gpio_port[0] = -EINVAL, @@ -625,7 +625,7 @@ static void __init omap3_beagle_init(void) gpio_direction_output(170, true); usb_musb_init(&musb_board_data); - usb_ehci_init(&ehci_pdata); + usb_ehci_init(&usbhs_bdata); omap3beagle_flash_init(); /* Ensure SDRC pins are mux'd for self-refresh */ diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index 323c3809ce39..ed5e4118147d 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c @@ -638,11 +638,11 @@ static struct platform_device *omap3_evm_devices[] __initdata = { &omap3_evm_dss_device, }; -static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = { +static struct usbhs_omap_board_data usbhs_bdata __initdata = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN, - .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, + .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, .phy_reset = true, /* PHY reset GPIO will be runtime programmed based on EVM version */ @@ -700,7 +700,7 @@ static void __init omap3_evm_init(void) /* setup EHCI phy reset config */ omap_mux_init_gpio(21, OMAP_PIN_INPUT_PULLUP); - ehci_pdata.reset_gpio_port[1] = 21; + usbhs_bdata.reset_gpio_port[1] = 21; /* EVM REV >= E can supply 500mA with EXTVBUS programming */ musb_board_data.power = 500; @@ -708,10 +708,10 @@ static void __init omap3_evm_init(void) } else { /* setup EHCI phy reset on MDC */ omap_mux_init_gpio(135, OMAP_PIN_OUTPUT); - ehci_pdata.reset_gpio_port[1] = 135; + usbhs_bdata.reset_gpio_port[1] = 135; } usb_musb_init(&musb_board_data); - usb_ehci_init(&ehci_pdata); + usb_ehci_init(&usbhs_bdata); ads7846_dev_init(); omap3evm_init_smsc911x(); omap3_evm_display_init(); diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index 0b34beded11f..241e632a4662 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -681,11 +681,11 @@ static struct platform_device *omap3pandora_devices[] __initdata = { &pandora_vwlan_device, }; -static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { +static const struct usbhs_omap_board_data usbhs_bdata __initconst = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN, - .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, .phy_reset = true, .reset_gpio_port[0] = 16, @@ -716,7 +716,7 @@ static void __init omap3pandora_init(void) spi_register_board_info(omap3pandora_spi_board_info, ARRAY_SIZE(omap3pandora_spi_board_info)); omap3pandora_ads7846_init(); - usb_ehci_init(&ehci_pdata); + usb_ehci_init(&usbhs_bdata); usb_musb_init(&musb_board_data); gpmc_nand_init(&pandora_nand_data); diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c index 2a2dad447e86..eaad924b6244 100644 --- a/arch/arm/mach-omap2/board-omap3stalker.c +++ b/arch/arm/mach-omap2/board-omap3stalker.c @@ -608,10 +608,10 @@ static struct platform_device *omap3_stalker_devices[] __initdata = { &keys_gpio, }; -static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN, - .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, +static struct usbhs_omap_board_data usbhs_bdata __initconst = { + .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, .phy_reset = true, .reset_gpio_port[0] = -EINVAL, @@ -649,7 +649,7 @@ static void __init omap3_stalker_init(void) omap_serial_init(); usb_musb_init(&musb_board_data); - usb_ehci_init(&ehci_pdata); + usb_ehci_init(&usbhs_bdata); ads7846_dev_init(); omap_mux_init_gpio(21, OMAP_PIN_OUTPUT); diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c index db1f74fe6c4f..4e3a1ae2ac96 100644 --- a/arch/arm/mach-omap2/board-omap3touchbook.c +++ b/arch/arm/mach-omap2/board-omap3touchbook.c @@ -468,11 +468,11 @@ static void __init omap3touchbook_flash_init(void) } } -static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { +static const struct usbhs_omap_board_data usbhs_bdata __initconst = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, .phy_reset = true, .reset_gpio_port[0] = -EINVAL, @@ -527,7 +527,7 @@ static void __init omap3_touchbook_init(void) ARRAY_SIZE(omap3_ads7846_spi_board_info)); omap3_ads7846_init(); usb_musb_init(&musb_board_data); - usb_ehci_init(&ehci_pdata); + usb_ehci_init(&usbhs_bdata); omap3touchbook_flash_init(); /* Ensure SDRC pins are mux'd for self-refresh */ diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 77748f813667..b88c1909434a 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -83,10 +83,10 @@ static void __init omap4_panda_init_irq(void) gic_init_irq(); } -static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN, - .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, +static const struct usbhs_omap_board_data usbhs_bdata __initconst = { + .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, .phy_reset = false, .reset_gpio_port[0] = -EINVAL, .reset_gpio_port[1] = -EINVAL, @@ -128,7 +128,7 @@ static void __init omap4_ehci_init(void) gpio_set_value(GPIO_HUB_NRESET, 0); gpio_set_value(GPIO_HUB_NRESET, 1); - usb_ehci_init(&ehci_pdata); + usb_ehci_init(&usbhs_bdata); /* enable power to hub */ gpio_set_value(GPIO_HUB_POWER, 1); diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index cb26e5d8268d..f78b74c369df 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c @@ -423,10 +423,10 @@ static struct platform_device *overo_devices[] __initdata = { &overo_lcd_device, }; -static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN, - .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, +static const struct usbhs_omap_board_data usbhs_bdata __initconst = { + .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, .phy_reset = true, .reset_gpio_port[0] = -EINVAL, @@ -454,7 +454,7 @@ static void __init overo_init(void) omap_serial_init(); overo_flash_init(); usb_musb_init(&musb_board_data); - usb_ehci_init(&ehci_pdata); + usb_ehci_init(&usbhs_bdata); overo_ads7846_init(); overo_init_smsc911x(); diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c index e26754c24ee8..19b99128df76 100644 --- a/arch/arm/mach-omap2/board-zoom.c +++ b/arch/arm/mach-omap2/board-zoom.c @@ -106,10 +106,10 @@ static struct mtd_partition zoom_nand_partitions[] = { }, }; -static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN, - .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, - .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, +static const struct usbhs_omap_board_data usbhs_bdata __initconst = { + .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, .phy_reset = true, .reset_gpio_port[0] = -EINVAL, .reset_gpio_port[1] = ZOOM3_EHCI_RESET_GPIO, @@ -123,7 +123,7 @@ static void __init omap_zoom_init(void) } else if (machine_is_omap_zoom3()) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBP); omap_mux_init_gpio(ZOOM3_EHCI_RESET_GPIO, OMAP_PIN_OUTPUT); - usb_ehci_init(&ehci_pdata); + usb_ehci_init(&usbhs_bdata); } board_nand_init(zoom_nand_partitions, diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c index 45f9b80b6d20..b04ce6f8f013 100644 --- a/arch/arm/mach-omap2/usb-host.c +++ b/arch/arm/mach-omap2/usb-host.c @@ -64,10 +64,10 @@ static struct platform_device ehci_device = { /* * setup_ehci_io_mux - initialize IO pad mux for USBHOST */ -static void setup_ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode) +static void setup_ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) { switch (port_mode[0]) { - case EHCI_HCD_OMAP_MODE_PHY: + case OMAP_EHCI_PORT_MODE_PHY: omap_mux_init_signal("hsusb1_stp", OMAP_PIN_OUTPUT); omap_mux_init_signal("hsusb1_clk", OMAP_PIN_OUTPUT); omap_mux_init_signal("hsusb1_dir", OMAP_PIN_INPUT_PULLDOWN); @@ -81,7 +81,7 @@ static void setup_ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode) omap_mux_init_signal("hsusb1_data6", OMAP_PIN_INPUT_PULLDOWN); omap_mux_init_signal("hsusb1_data7", OMAP_PIN_INPUT_PULLDOWN); break; - case EHCI_HCD_OMAP_MODE_TLL: + case OMAP_EHCI_PORT_MODE_TLL: omap_mux_init_signal("hsusb1_tll_stp", OMAP_PIN_INPUT_PULLUP); omap_mux_init_signal("hsusb1_tll_clk", @@ -107,14 +107,14 @@ static void setup_ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode) omap_mux_init_signal("hsusb1_tll_data7", OMAP_PIN_INPUT_PULLDOWN); break; - case EHCI_HCD_OMAP_MODE_UNKNOWN: + case OMAP_USBHS_PORT_MODE_UNUSED: /* FALLTHROUGH */ default: break; } switch (port_mode[1]) { - case EHCI_HCD_OMAP_MODE_PHY: + case OMAP_EHCI_PORT_MODE_PHY: omap_mux_init_signal("hsusb2_stp", OMAP_PIN_OUTPUT); omap_mux_init_signal("hsusb2_clk", OMAP_PIN_OUTPUT); omap_mux_init_signal("hsusb2_dir", OMAP_PIN_INPUT_PULLDOWN); @@ -136,7 +136,7 @@ static void setup_ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode) omap_mux_init_signal("hsusb2_data7", OMAP_PIN_INPUT_PULLDOWN); break; - case EHCI_HCD_OMAP_MODE_TLL: + case OMAP_EHCI_PORT_MODE_TLL: omap_mux_init_signal("hsusb2_tll_stp", OMAP_PIN_INPUT_PULLUP); omap_mux_init_signal("hsusb2_tll_clk", @@ -162,17 +162,17 @@ static void setup_ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode) omap_mux_init_signal("hsusb2_tll_data7", OMAP_PIN_INPUT_PULLDOWN); break; - case EHCI_HCD_OMAP_MODE_UNKNOWN: + case OMAP_USBHS_PORT_MODE_UNUSED: /* FALLTHROUGH */ default: break; } switch (port_mode[2]) { - case EHCI_HCD_OMAP_MODE_PHY: + case OMAP_EHCI_PORT_MODE_PHY: printk(KERN_WARNING "Port3 can't be used in PHY mode\n"); break; - case EHCI_HCD_OMAP_MODE_TLL: + case OMAP_EHCI_PORT_MODE_TLL: omap_mux_init_signal("hsusb3_tll_stp", OMAP_PIN_INPUT_PULLUP); omap_mux_init_signal("hsusb3_tll_clk", @@ -198,7 +198,7 @@ static void setup_ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode) omap_mux_init_signal("hsusb3_tll_data7", OMAP_PIN_INPUT_PULLDOWN); break; - case EHCI_HCD_OMAP_MODE_UNKNOWN: + case OMAP_USBHS_PORT_MODE_UNUSED: /* FALLTHROUGH */ default: break; @@ -207,10 +207,10 @@ static void setup_ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode) return; } -static void setup_4430ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode) +static void setup_4430ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) { switch (port_mode[0]) { - case EHCI_HCD_OMAP_MODE_PHY: + case OMAP_EHCI_PORT_MODE_PHY: omap_mux_init_signal("usbb1_ulpiphy_stp", OMAP_PIN_OUTPUT); omap_mux_init_signal("usbb1_ulpiphy_clk", @@ -236,7 +236,7 @@ static void setup_4430ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode) omap_mux_init_signal("usbb1_ulpiphy_dat7", OMAP_PIN_INPUT_PULLDOWN); break; - case EHCI_HCD_OMAP_MODE_TLL: + case OMAP_EHCI_PORT_MODE_TLL: omap_mux_init_signal("usbb1_ulpitll_stp", OMAP_PIN_INPUT_PULLUP); omap_mux_init_signal("usbb1_ulpitll_clk", @@ -262,12 +262,12 @@ static void setup_4430ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode) omap_mux_init_signal("usbb1_ulpitll_dat7", OMAP_PIN_INPUT_PULLDOWN); break; - case EHCI_HCD_OMAP_MODE_UNKNOWN: + case OMAP_USBHS_PORT_MODE_UNUSED: default: break; } switch (port_mode[1]) { - case EHCI_HCD_OMAP_MODE_PHY: + case OMAP_EHCI_PORT_MODE_PHY: omap_mux_init_signal("usbb2_ulpiphy_stp", OMAP_PIN_OUTPUT); omap_mux_init_signal("usbb2_ulpiphy_clk", @@ -293,7 +293,7 @@ static void setup_4430ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode) omap_mux_init_signal("usbb2_ulpiphy_dat7", OMAP_PIN_INPUT_PULLDOWN); break; - case EHCI_HCD_OMAP_MODE_TLL: + case OMAP_EHCI_PORT_MODE_TLL: omap_mux_init_signal("usbb2_ulpitll_stp", OMAP_PIN_INPUT_PULLUP); omap_mux_init_signal("usbb2_ulpitll_clk", @@ -319,13 +319,13 @@ static void setup_4430ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode) omap_mux_init_signal("usbb2_ulpitll_dat7", OMAP_PIN_INPUT_PULLDOWN); break; - case EHCI_HCD_OMAP_MODE_UNKNOWN: + case OMAP_USBHS_PORT_MODE_UNUSED: default: break; } } -void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata) +void __init usb_ehci_init(const struct usbhs_omap_board_data *pdata) { platform_device_add_data(&ehci_device, pdata, sizeof(*pdata)); @@ -363,7 +363,7 @@ void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata) #else -void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata) +void __init usb_ehci_init(const struct usbhs_omap_board_data *pdata) { } @@ -411,7 +411,7 @@ static struct platform_device ohci_device = { .resource = ohci_resources, }; -static void setup_ohci_io_mux(const enum ohci_omap3_port_mode *port_mode) +static void setup_ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) { switch (port_mode[0]) { case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: @@ -439,7 +439,7 @@ static void setup_ohci_io_mux(const enum ohci_omap3_port_mode *port_mode) omap_mux_init_signal("mm1_txdat", OMAP_PIN_INPUT_PULLDOWN); break; - case OMAP_OHCI_PORT_MODE_UNUSED: + case OMAP_USBHS_PORT_MODE_UNUSED: /* FALLTHROUGH */ default: break; @@ -470,7 +470,7 @@ static void setup_ohci_io_mux(const enum ohci_omap3_port_mode *port_mode) omap_mux_init_signal("mm2_txdat", OMAP_PIN_INPUT_PULLDOWN); break; - case OMAP_OHCI_PORT_MODE_UNUSED: + case OMAP_USBHS_PORT_MODE_UNUSED: /* FALLTHROUGH */ default: break; @@ -501,14 +501,14 @@ static void setup_ohci_io_mux(const enum ohci_omap3_port_mode *port_mode) omap_mux_init_signal("mm3_txdat", OMAP_PIN_INPUT_PULLDOWN); break; - case OMAP_OHCI_PORT_MODE_UNUSED: + case OMAP_USBHS_PORT_MODE_UNUSED: /* FALLTHROUGH */ default: break; } } -void __init usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata) +void __init usb_ohci_init(const struct usbhs_omap_board_data *pdata) { platform_device_add_data(&ohci_device, pdata, sizeof(*pdata)); @@ -524,7 +524,7 @@ void __init usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata) #else -void __init usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata) +void __init usb_ohci_init(const struct usbhs_omap_board_data *pdata) { } diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h index f888e0e57dc8..32dfe08023a4 100644 --- a/arch/arm/plat-omap/include/plat/usb.h +++ b/arch/arm/plat-omap/include/plat/usb.h @@ -7,15 +7,12 @@ #include #define OMAP3_HS_USB_PORTS 3 -enum ehci_hcd_omap_mode { - EHCI_HCD_OMAP_MODE_UNKNOWN, - EHCI_HCD_OMAP_MODE_PHY, - EHCI_HCD_OMAP_MODE_TLL, - EHCI_HCD_OMAP_MODE_HSIC, -}; -enum ohci_omap3_port_mode { - OMAP_OHCI_PORT_MODE_UNUSED, +enum usbhs_omap_port_mode { + OMAP_USBHS_PORT_MODE_UNUSED, + OMAP_EHCI_PORT_MODE_PHY, + OMAP_EHCI_PORT_MODE_TLL, + OMAP_EHCI_PORT_MODE_HSIC, OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0, OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM, OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0, @@ -25,24 +22,45 @@ enum ohci_omap3_port_mode { OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0, OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM, OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0, - OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM, + OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM }; -struct ehci_hcd_omap_platform_data { - enum ehci_hcd_omap_mode port_mode[OMAP3_HS_USB_PORTS]; - unsigned phy_reset:1; +struct usbhs_omap_board_data { + enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS]; /* have to be valid if phy_reset is true and portx is in phy mode */ int reset_gpio_port[OMAP3_HS_USB_PORTS]; + + /* Set this to true for ES2.x silicon */ + unsigned es2_compatibility:1; + + unsigned phy_reset:1; + + /* + * Regulators for USB PHYs. + * Each PHY can have a separate regulator. + */ + struct regulator *regulator[OMAP3_HS_USB_PORTS]; }; -struct ohci_hcd_omap_platform_data { - enum ohci_omap3_port_mode port_mode[OMAP3_HS_USB_PORTS]; +struct ehci_hcd_omap_platform_data { + enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS]; + int reset_gpio_port[OMAP3_HS_USB_PORTS]; + struct regulator *regulator[OMAP3_HS_USB_PORTS]; + unsigned phy_reset:1; +}; - /* Set this to true for ES2.x silicon */ +struct ohci_hcd_omap_platform_data { + enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS]; unsigned es2_compatibility:1; }; +struct usbhs_omap_platform_data { + enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS]; + + struct ehci_hcd_omap_platform_data *ehci_data; + struct ohci_hcd_omap_platform_data *ohci_data; +}; /*-------------------------------------------------------------------------*/ #define OMAP1_OTG_BASE 0xfffb0400 @@ -80,19 +98,17 @@ enum musb_interface {MUSB_INTERFACE_ULPI, MUSB_INTERFACE_UTMI}; extern void usb_musb_init(struct omap_musb_board_data *board_data); -extern void usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata); +extern void usb_ehci_init(const struct usbhs_omap_board_data *pdata); -extern void usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata); +extern void usb_ohci_init(const struct usbhs_omap_board_data *pdata); extern int omap4430_phy_power(struct device *dev, int ID, int on); extern int omap4430_phy_set_clk(struct device *dev, int on); extern int omap4430_phy_init(struct device *dev); extern int omap4430_phy_exit(struct device *dev); extern int omap4430_phy_suspend(struct device *dev, int suspend); - #endif - /* * FIXME correct answer depends on hmc_mode, * as does (on omap1) any nonzero value for config->otg port number diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 15277213f928..18df6c6a5803 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -155,9 +155,9 @@ #define is_omap_ehci_rev1(x) (x->omap_ehci_rev == OMAP_EHCI_REV1) #define is_omap_ehci_rev2(x) (x->omap_ehci_rev == OMAP_EHCI_REV2) -#define is_ehci_phy_mode(x) (x == EHCI_HCD_OMAP_MODE_PHY) -#define is_ehci_tll_mode(x) (x == EHCI_HCD_OMAP_MODE_TLL) -#define is_ehci_hsic_mode(x) (x == EHCI_HCD_OMAP_MODE_HSIC) +#define is_ehci_phy_mode(x) (x == OMAP_EHCI_PORT_MODE_PHY) +#define is_ehci_tll_mode(x) (x == OMAP_EHCI_PORT_MODE_TLL) +#define is_ehci_hsic_mode(x) (x == OMAP_EHCI_PORT_MODE_HSIC) /*-------------------------------------------------------------------------*/ @@ -220,7 +220,7 @@ struct ehci_hcd_omap { u32 omap_ehci_rev; /* desired phy_mode: TLL, PHY */ - enum ehci_hcd_omap_mode port_mode[OMAP3_HS_USB_PORTS]; + enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS]; void __iomem *uhh_base; void __iomem *tll_base; @@ -389,7 +389,7 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) */ if (is_omap_ehci_rev2(omap)) { switch (omap->port_mode[0]) { - case EHCI_HCD_OMAP_MODE_PHY: + case OMAP_EHCI_PORT_MODE_PHY: omap->xclk60mhsp1_ck = clk_get(omap->dev, "xclk60mhsp1_ck"); if (IS_ERR(omap->xclk60mhsp1_ck)) { @@ -413,7 +413,7 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) "Unable to set P1 f-clock\n"); } break; - case EHCI_HCD_OMAP_MODE_TLL: + case OMAP_EHCI_PORT_MODE_TLL: omap->xclk60mhsp1_ck = clk_get(omap->dev, "init_60m_fclk"); if (IS_ERR(omap->xclk60mhsp1_ck)) { @@ -463,7 +463,7 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) break; } switch (omap->port_mode[1]) { - case EHCI_HCD_OMAP_MODE_PHY: + case OMAP_EHCI_PORT_MODE_PHY: omap->xclk60mhsp2_ck = clk_get(omap->dev, "xclk60mhsp2_ck"); if (IS_ERR(omap->xclk60mhsp2_ck)) { @@ -487,7 +487,7 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) "Unable to set P2 f-clock\n"); } break; - case EHCI_HCD_OMAP_MODE_TLL: + case OMAP_EHCI_PORT_MODE_TLL: omap->xclk60mhsp2_ck = clk_get(omap->dev, "init_60m_fclk"); if (IS_ERR(omap->xclk60mhsp2_ck)) { @@ -591,11 +591,11 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; if (is_omap_ehci_rev1(omap)) { - if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_UNKNOWN) + if (omap->port_mode[0] == OMAP_USBHS_PORT_MODE_UNUSED) reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; - if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_UNKNOWN) + if (omap->port_mode[1] == OMAP_USBHS_PORT_MODE_UNUSED) reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; - if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_UNKNOWN) + if (omap->port_mode[2] == OMAP_USBHS_PORT_MODE_UNUSED) reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; /* Bypass the TLL module for PHY mode operation */ @@ -656,15 +656,15 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) ehci_omap_writel(omap->ehci_base, EHCI_INSNREG04, EHCI_INSNREG04_DISABLE_UNSUSPEND); - if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) || - (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) || - (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL)) { + if ((omap->port_mode[0] == OMAP_EHCI_PORT_MODE_TLL) || + (omap->port_mode[1] == OMAP_EHCI_PORT_MODE_TLL) || + (omap->port_mode[2] == OMAP_EHCI_PORT_MODE_TLL)) { - if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) + if (omap->port_mode[0] == OMAP_EHCI_PORT_MODE_TLL) tll_ch_mask |= OMAP_TLL_CHANNEL_1_EN_MASK; - if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) + if (omap->port_mode[1] == OMAP_EHCI_PORT_MODE_TLL) tll_ch_mask |= OMAP_TLL_CHANNEL_2_EN_MASK; - if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL) + if (omap->port_mode[2] == OMAP_EHCI_PORT_MODE_TLL) tll_ch_mask |= OMAP_TLL_CHANNEL_3_EN_MASK; /* Enable UTMI mode for required TLL channels */ @@ -686,9 +686,9 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) } /* Soft reset the PHY using PHY reset command over ULPI */ - if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) + if (omap->port_mode[0] == OMAP_EHCI_PORT_MODE_PHY) omap_ehci_soft_phy_reset(omap, 0); - if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) + if (omap->port_mode[1] == OMAP_EHCI_PORT_MODE_PHY) omap_ehci_soft_phy_reset(omap, 1); return 0; @@ -903,7 +903,7 @@ static const struct hc_driver ehci_omap_hc_driver; */ static int ehci_hcd_omap_probe(struct platform_device *pdev) { - struct ehci_hcd_omap_platform_data *pdata = pdev->dev.platform_data; + struct usbhs_omap_board_data *pdata = pdev->dev.platform_data; struct ehci_hcd_omap *omap; struct resource *res; struct usb_hcd *hcd; @@ -981,7 +981,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) /* get ehci regulator and enable */ for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { - if (omap->port_mode[i] != EHCI_HCD_OMAP_MODE_PHY) { + if (omap->port_mode[i] != OMAP_EHCI_PORT_MODE_PHY) { omap->regulator[i] = NULL; continue; } diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c index 32f56bbec214..3f9db87fe525 100644 --- a/drivers/usb/host/ohci-omap3.c +++ b/drivers/usb/host/ohci-omap3.c @@ -141,7 +141,7 @@ struct ohci_hcd_omap3 { struct clk *usbtll_ick; /* port_mode: TLL/PHY, 2/3/4/6-PIN, DP-DM/DAT-SE0 */ - enum ohci_omap3_port_mode port_mode[OMAP3_HS_USB_PORTS]; + enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS]; void __iomem *uhh_base; void __iomem *tll_base; void __iomem *ohci_base; @@ -206,10 +206,10 @@ static int ohci_omap3_start(struct usb_hcd *hcd) * convert the port-mode enum to a value we can use in the FSLSMODE * field of USBTLL_CHANNEL_CONF */ -static unsigned ohci_omap3_fslsmode(enum ohci_omap3_port_mode mode) +static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode) { switch (mode) { - case OMAP_OHCI_PORT_MODE_UNUSED: + case OMAP_USBHS_PORT_MODE_UNUSED: case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: return 0x0; @@ -266,7 +266,7 @@ static void ohci_omap3_tll_config(struct ohci_hcd_omap3 *omap) for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) { /* Enable only those channels that are actually used */ - if (omap->port_mode[i] == OMAP_OHCI_PORT_MODE_UNUSED) + if (omap->port_mode[i] == OMAP_USBHS_PORT_MODE_UNUSED) continue; reg = ohci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); @@ -382,11 +382,11 @@ static int omap3_start_ohci(struct ohci_hcd_omap3 *omap, struct usb_hcd *hcd) * * For now, turn off all the Pi_CONNECT_STATUS bits * - if (omap->port_mode[0] == OMAP_OHCI_PORT_MODE_UNUSED) + if (omap->port_mode[0] == OMAP_USBHS_PORT_MODE_UNUSED) reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; - if (omap->port_mode[1] == OMAP_OHCI_PORT_MODE_UNUSED) + if (omap->port_mode[1] == OMAP_USBHS_PORT_MODE_UNUSED) reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; - if (omap->port_mode[2] == OMAP_OHCI_PORT_MODE_UNUSED) + if (omap->port_mode[2] == OMAP_USBHS_PORT_MODE_UNUSED) reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; */ reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; @@ -403,17 +403,17 @@ static int omap3_start_ohci(struct ohci_hcd_omap3 *omap, struct usb_hcd *hcd) reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; } else { dev_dbg(omap->dev, "OMAP3 ES version > ES2.1\n"); - if (omap->port_mode[0] == OMAP_OHCI_PORT_MODE_UNUSED) + if (omap->port_mode[0] == OMAP_USBHS_PORT_MODE_UNUSED) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; - if (omap->port_mode[1] == OMAP_OHCI_PORT_MODE_UNUSED) + if (omap->port_mode[1] == OMAP_USBHS_PORT_MODE_UNUSED) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; - if (omap->port_mode[2] == OMAP_OHCI_PORT_MODE_UNUSED) + if (omap->port_mode[2] == OMAP_USBHS_PORT_MODE_UNUSED) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; @@ -580,7 +580,7 @@ static const struct hc_driver ohci_omap3_hc_driver = { */ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev) { - struct ohci_hcd_omap_platform_data *pdata = pdev->dev.platform_data; + struct usbhs_omap_board_data *pdata = pdev->dev.platform_data; struct ohci_hcd_omap3 *omap; struct resource *res; struct usb_hcd *hcd; -- cgit v1.2.3 From 17cdd29d6e1ab4164c792d78c6f096fbafb94e3f Mon Sep 17 00:00:00 2001 From: Keshava Munegowda Date: Tue, 1 Mar 2011 20:08:17 +0530 Subject: usb: host: omap: common usb host core driver enabling and disabling the common clocks for ehci and ohci is implemented. usbhs is a common parent platform driver for EHCI and OHCI driver. This driver receives the clock enable and disable requests from ehci and ohci drivers.The UHH and TLL initialization is also performed. Signed-off-by: Keshava Munegowda Signed-off-by: Felipe Balbi --- arch/arm/plat-omap/include/plat/usb.h | 3 + drivers/mfd/Kconfig | 9 + drivers/mfd/Makefile | 1 + drivers/mfd/omap-usb-host.c | 1061 +++++++++++++++++++++++++++++++++ 4 files changed, 1074 insertions(+) create mode 100644 drivers/mfd/omap-usb-host.c (limited to 'drivers') diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h index 32dfe08023a4..5dd27764eb6f 100644 --- a/arch/arm/plat-omap/include/plat/usb.h +++ b/arch/arm/plat-omap/include/plat/usb.h @@ -102,6 +102,9 @@ extern void usb_ehci_init(const struct usbhs_omap_board_data *pdata); extern void usb_ohci_init(const struct usbhs_omap_board_data *pdata); +extern int omap_usbhs_enable(struct device *dev); +extern void omap_usbhs_disable(struct device *dev); + extern int omap4430_phy_power(struct device *dev, int ID, int on); extern int omap4430_phy_set_clk(struct device *dev, int on); extern int omap4430_phy_init(struct device *dev); diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index fd018366d670..a6dfa37a674d 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -624,6 +624,15 @@ config MFD_WL1273_CORE driver connects the radio-wl1273 V4L2 module and the wl1273 audio codec. +config MFD_OMAP_USB_HOST + bool "Support OMAP USBHS core driver" + depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3 + default y + help + This is the core driver for the OAMP EHCI and OHCI drivers. + This MFD driver does the required setup functionalities for + OMAP USB Host drivers. + endif # MFD_SUPPORT menu "Multimedia Capabilities Port drivers" diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index a54e2c7c6a1c..91fe384459ab 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -83,3 +83,4 @@ obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o obj-$(CONFIG_MFD_VX855) += vx855.o obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o +obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c new file mode 100644 index 000000000000..cb01209754e0 --- /dev/null +++ b/drivers/mfd/omap-usb-host.c @@ -0,0 +1,1061 @@ +/** + * omap-usb-host.c - The USBHS core driver for OMAP EHCI & OHCI + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com + * Author: Keshava Munegowda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 of + * the License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define USBHS_DRIVER_NAME "usbhs-omap" +#define OMAP_EHCI_DEVICE "ehci-omap" +#define OMAP_OHCI_DEVICE "ohci-omap3" + +/* OMAP USBHOST Register addresses */ + +/* TLL Register Set */ +#define OMAP_USBTLL_REVISION (0x00) +#define OMAP_USBTLL_SYSCONFIG (0x10) +#define OMAP_USBTLL_SYSCONFIG_CACTIVITY (1 << 8) +#define OMAP_USBTLL_SYSCONFIG_SIDLEMODE (1 << 3) +#define OMAP_USBTLL_SYSCONFIG_ENAWAKEUP (1 << 2) +#define OMAP_USBTLL_SYSCONFIG_SOFTRESET (1 << 1) +#define OMAP_USBTLL_SYSCONFIG_AUTOIDLE (1 << 0) + +#define OMAP_USBTLL_SYSSTATUS (0x14) +#define OMAP_USBTLL_SYSSTATUS_RESETDONE (1 << 0) + +#define OMAP_USBTLL_IRQSTATUS (0x18) +#define OMAP_USBTLL_IRQENABLE (0x1C) + +#define OMAP_TLL_SHARED_CONF (0x30) +#define OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN (1 << 6) +#define OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN (1 << 5) +#define OMAP_TLL_SHARED_CONF_USB_DIVRATION (1 << 2) +#define OMAP_TLL_SHARED_CONF_FCLK_REQ (1 << 1) +#define OMAP_TLL_SHARED_CONF_FCLK_IS_ON (1 << 0) + +#define OMAP_TLL_CHANNEL_CONF(num) (0x040 + 0x004 * num) +#define OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT 24 +#define OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF (1 << 11) +#define OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE (1 << 10) +#define OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE (1 << 9) +#define OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE (1 << 8) +#define OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS (1 << 1) +#define OMAP_TLL_CHANNEL_CONF_CHANEN (1 << 0) + +#define OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0 0x0 +#define OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM 0x1 +#define OMAP_TLL_FSLSMODE_3PIN_PHY 0x2 +#define OMAP_TLL_FSLSMODE_4PIN_PHY 0x3 +#define OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0 0x4 +#define OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM 0x5 +#define OMAP_TLL_FSLSMODE_3PIN_TLL 0x6 +#define OMAP_TLL_FSLSMODE_4PIN_TLL 0x7 +#define OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0 0xA +#define OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM 0xB + +#define OMAP_TLL_ULPI_FUNCTION_CTRL(num) (0x804 + 0x100 * num) +#define OMAP_TLL_ULPI_INTERFACE_CTRL(num) (0x807 + 0x100 * num) +#define OMAP_TLL_ULPI_OTG_CTRL(num) (0x80A + 0x100 * num) +#define OMAP_TLL_ULPI_INT_EN_RISE(num) (0x80D + 0x100 * num) +#define OMAP_TLL_ULPI_INT_EN_FALL(num) (0x810 + 0x100 * num) +#define OMAP_TLL_ULPI_INT_STATUS(num) (0x813 + 0x100 * num) +#define OMAP_TLL_ULPI_INT_LATCH(num) (0x814 + 0x100 * num) +#define OMAP_TLL_ULPI_DEBUG(num) (0x815 + 0x100 * num) +#define OMAP_TLL_ULPI_SCRATCH_REGISTER(num) (0x816 + 0x100 * num) + +#define OMAP_TLL_CHANNEL_COUNT 3 +#define OMAP_TLL_CHANNEL_1_EN_MASK (1 << 0) +#define OMAP_TLL_CHANNEL_2_EN_MASK (1 << 1) +#define OMAP_TLL_CHANNEL_3_EN_MASK (1 << 2) + +/* UHH Register Set */ +#define OMAP_UHH_REVISION (0x00) +#define OMAP_UHH_SYSCONFIG (0x10) +#define OMAP_UHH_SYSCONFIG_MIDLEMODE (1 << 12) +#define OMAP_UHH_SYSCONFIG_CACTIVITY (1 << 8) +#define OMAP_UHH_SYSCONFIG_SIDLEMODE (1 << 3) +#define OMAP_UHH_SYSCONFIG_ENAWAKEUP (1 << 2) +#define OMAP_UHH_SYSCONFIG_SOFTRESET (1 << 1) +#define OMAP_UHH_SYSCONFIG_AUTOIDLE (1 << 0) + +#define OMAP_UHH_SYSSTATUS (0x14) +#define OMAP_UHH_HOSTCONFIG (0x40) +#define OMAP_UHH_HOSTCONFIG_ULPI_BYPASS (1 << 0) +#define OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS (1 << 0) +#define OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS (1 << 11) +#define OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS (1 << 12) +#define OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN (1 << 2) +#define OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN (1 << 3) +#define OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN (1 << 4) +#define OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN (1 << 5) +#define OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS (1 << 8) +#define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS (1 << 9) +#define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS (1 << 10) +#define OMAP4_UHH_HOSTCONFIG_APP_START_CLK (1 << 31) + +/* OMAP4-specific defines */ +#define OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR (3 << 2) +#define OMAP4_UHH_SYSCONFIG_NOIDLE (1 << 2) +#define OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR (3 << 4) +#define OMAP4_UHH_SYSCONFIG_NOSTDBY (1 << 4) +#define OMAP4_UHH_SYSCONFIG_SOFTRESET (1 << 0) + +#define OMAP4_P1_MODE_CLEAR (3 << 16) +#define OMAP4_P1_MODE_TLL (1 << 16) +#define OMAP4_P1_MODE_HSIC (3 << 16) +#define OMAP4_P2_MODE_CLEAR (3 << 18) +#define OMAP4_P2_MODE_TLL (1 << 18) +#define OMAP4_P2_MODE_HSIC (3 << 18) + +#define OMAP_REV2_TLL_CHANNEL_COUNT 2 + +#define OMAP_UHH_DEBUG_CSR (0x44) + +/* Values of UHH_REVISION - Note: these are not given in the TRM */ +#define OMAP_USBHS_REV1 0x00000010 /* OMAP3 */ +#define OMAP_USBHS_REV2 0x50700100 /* OMAP4 */ + +#define is_omap_usbhs_rev1(x) (x->usbhs_rev == OMAP_USBHS_REV1) +#define is_omap_usbhs_rev2(x) (x->usbhs_rev == OMAP_USBHS_REV2) + +#define is_ehci_phy_mode(x) (x == OMAP_EHCI_PORT_MODE_PHY) +#define is_ehci_tll_mode(x) (x == OMAP_EHCI_PORT_MODE_TLL) +#define is_ehci_hsic_mode(x) (x == OMAP_EHCI_PORT_MODE_HSIC) + + +struct usbhs_hcd_omap { + struct clk *usbhost_ick; + struct clk *usbhost_hs_fck; + struct clk *usbhost_fs_fck; + struct clk *xclk60mhsp1_ck; + struct clk *xclk60mhsp2_ck; + struct clk *utmi_p1_fck; + struct clk *usbhost_p1_fck; + struct clk *usbtll_p1_fck; + struct clk *utmi_p2_fck; + struct clk *usbhost_p2_fck; + struct clk *usbtll_p2_fck; + struct clk *init_60m_fclk; + struct clk *usbtll_fck; + struct clk *usbtll_ick; + + void __iomem *uhh_base; + void __iomem *tll_base; + + struct usbhs_omap_platform_data platdata; + + u32 usbhs_rev; + spinlock_t lock; + int count; +}; +/*-------------------------------------------------------------------------*/ + +const char usbhs_driver_name[] = USBHS_DRIVER_NAME; +static u64 usbhs_dmamask = ~(u32)0; + +/*-------------------------------------------------------------------------*/ + +static inline void usbhs_write(void __iomem *base, u32 reg, u32 val) +{ + __raw_writel(val, base + reg); +} + +static inline u32 usbhs_read(void __iomem *base, u32 reg) +{ + return __raw_readl(base + reg); +} + +static inline void usbhs_writeb(void __iomem *base, u8 reg, u8 val) +{ + __raw_writeb(val, base + reg); +} + +static inline u8 usbhs_readb(void __iomem *base, u8 reg) +{ + return __raw_readb(base + reg); +} + +/*-------------------------------------------------------------------------*/ + +static struct platform_device *omap_usbhs_alloc_child(const char *name, + struct resource *res, int num_resources, void *pdata, + size_t pdata_size, struct device *dev) +{ + struct platform_device *child; + int ret; + + child = platform_device_alloc(name, 0); + + if (!child) { + dev_err(dev, "platform_device_alloc %s failed\n", name); + goto err_end; + } + + ret = platform_device_add_resources(child, res, num_resources); + if (ret) { + dev_err(dev, "platform_device_add_resources failed\n"); + goto err_alloc; + } + + ret = platform_device_add_data(child, pdata, pdata_size); + if (ret) { + dev_err(dev, "platform_device_add_data failed\n"); + goto err_alloc; + } + + child->dev.dma_mask = &usbhs_dmamask; + child->dev.coherent_dma_mask = 0xffffffff; + child->dev.parent = dev; + + ret = platform_device_add(child); + if (ret) { + dev_err(dev, "platform_device_add failed\n"); + goto err_alloc; + } + + return child; + +err_alloc: + platform_device_put(child); + +err_end: + return NULL; +} + +static int omap_usbhs_alloc_children(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct usbhs_hcd_omap *omap; + struct ehci_hcd_omap_platform_data *ehci_data; + struct ohci_hcd_omap_platform_data *ohci_data; + struct platform_device *ehci; + struct platform_device *ohci; + struct resource *res; + struct resource resources[2]; + int ret; + + omap = platform_get_drvdata(pdev); + ehci_data = omap->platdata.ehci_data; + ohci_data = omap->platdata.ohci_data; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ehci"); + if (!res) { + dev_err(dev, "EHCI get resource IORESOURCE_MEM failed\n"); + ret = -ENODEV; + goto err_end; + } + resources[0] = *res; + + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ehci-irq"); + if (!res) { + dev_err(dev, " EHCI get resource IORESOURCE_IRQ failed\n"); + ret = -ENODEV; + goto err_end; + } + resources[1] = *res; + + ehci = omap_usbhs_alloc_child(OMAP_EHCI_DEVICE, resources, 2, ehci_data, + sizeof(*ehci_data), dev); + + if (!ehci) { + dev_err(dev, "omap_usbhs_alloc_child failed\n"); + goto err_end; + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ohci"); + if (!res) { + dev_err(dev, "OHCI get resource IORESOURCE_MEM failed\n"); + ret = -ENODEV; + goto err_ehci; + } + resources[0] = *res; + + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ohci-irq"); + if (!res) { + dev_err(dev, "OHCI get resource IORESOURCE_IRQ failed\n"); + ret = -ENODEV; + goto err_ehci; + } + resources[1] = *res; + + ohci = omap_usbhs_alloc_child(OMAP_OHCI_DEVICE, resources, 2, ohci_data, + sizeof(*ohci_data), dev); + if (!ohci) { + dev_err(dev, "omap_usbhs_alloc_child failed\n"); + goto err_ehci; + } + + return 0; + +err_ehci: + platform_device_put(ehci); + +err_end: + return ret; +} + +/** + * usbhs_omap_probe - initialize TI-based HCDs + * + * Allocates basic resources for this USB host controller. + */ +static int __devinit usbhs_omap_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct usbhs_omap_platform_data *pdata = dev->platform_data; + struct usbhs_hcd_omap *omap; + struct resource *res; + int ret = 0; + int i; + + if (!pdata) { + dev_err(dev, "Missing platfrom data\n"); + ret = -ENOMEM; + goto end_probe; + } + + omap = kzalloc(sizeof(*omap), GFP_KERNEL); + if (!omap) { + dev_err(dev, "Memory allocation failed\n"); + ret = -ENOMEM; + goto end_probe; + } + + spin_lock_init(&omap->lock); + + for (i = 0; i < OMAP3_HS_USB_PORTS; i++) + omap->platdata.port_mode[i] = pdata->port_mode[i]; + + omap->platdata.ehci_data = pdata->ehci_data; + omap->platdata.ohci_data = pdata->ohci_data; + + omap->usbhost_ick = clk_get(dev, "usbhost_ick"); + if (IS_ERR(omap->usbhost_ick)) { + ret = PTR_ERR(omap->usbhost_ick); + dev_err(dev, "usbhost_ick failed error:%d\n", ret); + goto err_end; + } + + omap->usbhost_hs_fck = clk_get(dev, "hs_fck"); + if (IS_ERR(omap->usbhost_hs_fck)) { + ret = PTR_ERR(omap->usbhost_hs_fck); + dev_err(dev, "usbhost_hs_fck failed error:%d\n", ret); + goto err_usbhost_ick; + } + + omap->usbhost_fs_fck = clk_get(dev, "fs_fck"); + if (IS_ERR(omap->usbhost_fs_fck)) { + ret = PTR_ERR(omap->usbhost_fs_fck); + dev_err(dev, "usbhost_fs_fck failed error:%d\n", ret); + goto err_usbhost_hs_fck; + } + + omap->usbtll_fck = clk_get(dev, "usbtll_fck"); + if (IS_ERR(omap->usbtll_fck)) { + ret = PTR_ERR(omap->usbtll_fck); + dev_err(dev, "usbtll_fck failed error:%d\n", ret); + goto err_usbhost_fs_fck; + } + + omap->usbtll_ick = clk_get(dev, "usbtll_ick"); + if (IS_ERR(omap->usbtll_ick)) { + ret = PTR_ERR(omap->usbtll_ick); + dev_err(dev, "usbtll_ick failed error:%d\n", ret); + goto err_usbtll_fck; + } + + omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); + if (IS_ERR(omap->utmi_p1_fck)) { + ret = PTR_ERR(omap->utmi_p1_fck); + dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); + goto err_usbtll_ick; + } + + omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); + if (IS_ERR(omap->xclk60mhsp1_ck)) { + ret = PTR_ERR(omap->xclk60mhsp1_ck); + dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret); + goto err_utmi_p1_fck; + } + + omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk"); + if (IS_ERR(omap->utmi_p2_fck)) { + ret = PTR_ERR(omap->utmi_p2_fck); + dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret); + goto err_xclk60mhsp1_ck; + } + + omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck"); + if (IS_ERR(omap->xclk60mhsp2_ck)) { + ret = PTR_ERR(omap->xclk60mhsp2_ck); + dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret); + goto err_utmi_p2_fck; + } + + omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk"); + if (IS_ERR(omap->usbhost_p1_fck)) { + ret = PTR_ERR(omap->usbhost_p1_fck); + dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret); + goto err_xclk60mhsp2_ck; + } + + omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk"); + if (IS_ERR(omap->usbtll_p1_fck)) { + ret = PTR_ERR(omap->usbtll_p1_fck); + dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret); + goto err_usbhost_p1_fck; + } + + omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk"); + if (IS_ERR(omap->usbhost_p2_fck)) { + ret = PTR_ERR(omap->usbhost_p2_fck); + dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret); + goto err_usbtll_p1_fck; + } + + omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk"); + if (IS_ERR(omap->usbtll_p2_fck)) { + ret = PTR_ERR(omap->usbtll_p2_fck); + dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret); + goto err_usbhost_p2_fck; + } + + omap->init_60m_fclk = clk_get(dev, "init_60m_fclk"); + if (IS_ERR(omap->init_60m_fclk)) { + ret = PTR_ERR(omap->init_60m_fclk); + dev_err(dev, "init_60m_fclk failed error:%d\n", ret); + goto err_usbtll_p2_fck; + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh"); + if (!res) { + dev_err(dev, "UHH EHCI get resource failed\n"); + ret = -ENODEV; + goto err_init_60m_fclk; + } + + omap->uhh_base = ioremap(res->start, resource_size(res)); + if (!omap->uhh_base) { + dev_err(dev, "UHH ioremap failed\n"); + ret = -ENOMEM; + goto err_init_60m_fclk; + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll"); + if (!res) { + dev_err(dev, "UHH EHCI get resource failed\n"); + ret = -ENODEV; + goto err_tll; + } + + omap->tll_base = ioremap(res->start, resource_size(res)); + if (!omap->tll_base) { + dev_err(dev, "TLL ioremap failed\n"); + ret = -ENOMEM; + goto err_tll; + } + + platform_set_drvdata(pdev, omap); + + ret = omap_usbhs_alloc_children(pdev); + if (ret) { + dev_err(dev, "omap_usbhs_alloc_children failed\n"); + goto err_alloc; + } + + goto end_probe; + +err_alloc: + iounmap(omap->tll_base); + +err_tll: + iounmap(omap->uhh_base); + +err_init_60m_fclk: + clk_put(omap->init_60m_fclk); + +err_usbtll_p2_fck: + clk_put(omap->usbtll_p2_fck); + +err_usbhost_p2_fck: + clk_put(omap->usbhost_p2_fck); + +err_usbtll_p1_fck: + clk_put(omap->usbtll_p1_fck); + +err_usbhost_p1_fck: + clk_put(omap->usbhost_p1_fck); + +err_xclk60mhsp2_ck: + clk_put(omap->xclk60mhsp2_ck); + +err_utmi_p2_fck: + clk_put(omap->utmi_p2_fck); + +err_xclk60mhsp1_ck: + clk_put(omap->xclk60mhsp1_ck); + +err_utmi_p1_fck: + clk_put(omap->utmi_p1_fck); + +err_usbtll_ick: + clk_put(omap->usbtll_ick); + +err_usbtll_fck: + clk_put(omap->usbtll_fck); + +err_usbhost_fs_fck: + clk_put(omap->usbhost_fs_fck); + +err_usbhost_hs_fck: + clk_put(omap->usbhost_hs_fck); + +err_usbhost_ick: + clk_put(omap->usbhost_ick); + +err_end: + kfree(omap); + +end_probe: + return ret; +} + +/** + * usbhs_omap_remove - shutdown processing for UHH & TLL HCDs + * @pdev: USB Host Controller being removed + * + * Reverses the effect of usbhs_omap_probe(). + */ +static int __devexit usbhs_omap_remove(struct platform_device *pdev) +{ + struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); + + if (omap->count != 0) { + dev_err(&pdev->dev, + "Either EHCI or OHCI is still using usbhs core\n"); + return -EBUSY; + } + + iounmap(omap->tll_base); + iounmap(omap->uhh_base); + clk_put(omap->init_60m_fclk); + clk_put(omap->usbtll_p2_fck); + clk_put(omap->usbhost_p2_fck); + clk_put(omap->usbtll_p1_fck); + clk_put(omap->usbhost_p1_fck); + clk_put(omap->xclk60mhsp2_ck); + clk_put(omap->utmi_p2_fck); + clk_put(omap->xclk60mhsp1_ck); + clk_put(omap->utmi_p1_fck); + clk_put(omap->usbtll_ick); + clk_put(omap->usbtll_fck); + clk_put(omap->usbhost_fs_fck); + clk_put(omap->usbhost_hs_fck); + clk_put(omap->usbhost_ick); + kfree(omap); + + return 0; +} + +static bool is_ohci_port(enum usbhs_omap_port_mode pmode) +{ + switch (pmode) { + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: + case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: + case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: + return true; + + default: + return false; + } +} + +/* + * convert the port-mode enum to a value we can use in the FSLSMODE + * field of USBTLL_CHANNEL_CONF + */ +static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode) +{ + switch (mode) { + case OMAP_USBHS_PORT_MODE_UNUSED: + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: + return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0; + + case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: + return OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM; + + case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: + return OMAP_TLL_FSLSMODE_3PIN_PHY; + + case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: + return OMAP_TLL_FSLSMODE_4PIN_PHY; + + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: + return OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0; + + case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: + return OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM; + + case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: + return OMAP_TLL_FSLSMODE_3PIN_TLL; + + case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: + return OMAP_TLL_FSLSMODE_4PIN_TLL; + + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: + return OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0; + + case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: + return OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM; + default: + pr_warning("Invalid port mode, using default\n"); + return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0; + } +} + +static void usbhs_omap_tll_init(struct device *dev, u8 tll_channel_count) +{ + struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); + struct usbhs_omap_platform_data *pdata = dev->platform_data; + unsigned reg; + int i; + + /* Program Common TLL register */ + reg = usbhs_read(omap->tll_base, OMAP_TLL_SHARED_CONF); + reg |= (OMAP_TLL_SHARED_CONF_FCLK_IS_ON + | OMAP_TLL_SHARED_CONF_USB_DIVRATION); + reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN; + reg &= ~OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN; + + usbhs_write(omap->tll_base, OMAP_TLL_SHARED_CONF, reg); + + /* Enable channels now */ + for (i = 0; i < tll_channel_count; i++) { + reg = usbhs_read(omap->tll_base, + OMAP_TLL_CHANNEL_CONF(i)); + + if (is_ohci_port(pdata->port_mode[i])) { + reg |= ohci_omap3_fslsmode(pdata->port_mode[i]) + << OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT; + reg |= OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS; + } else if (pdata->port_mode[i] == OMAP_EHCI_PORT_MODE_TLL) { + + /* Disable AutoIdle, BitStuffing and use SDR Mode */ + reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE + | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF + | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE); + + reg |= (1 << (i + 1)); + } else + continue; + + reg |= OMAP_TLL_CHANNEL_CONF_CHANEN; + usbhs_write(omap->tll_base, + OMAP_TLL_CHANNEL_CONF(i), reg); + + usbhs_writeb(omap->tll_base, + OMAP_TLL_ULPI_SCRATCH_REGISTER(i), 0xbe); + } +} + +static int usbhs_enable(struct device *dev) +{ + struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); + struct usbhs_omap_platform_data *pdata = &omap->platdata; + unsigned long flags = 0; + int ret = 0; + unsigned long timeout; + unsigned reg; + + dev_dbg(dev, "starting TI HSUSB Controller\n"); + if (!pdata) { + dev_dbg(dev, "missing platform_data\n"); + ret = -ENODEV; + goto end_enable; + } + + spin_lock_irqsave(&omap->lock, flags); + if (omap->count > 0) + goto end_count; + + clk_enable(omap->usbhost_ick); + clk_enable(omap->usbhost_hs_fck); + clk_enable(omap->usbhost_fs_fck); + clk_enable(omap->usbtll_fck); + clk_enable(omap->usbtll_ick); + + if (pdata->ehci_data->phy_reset) { + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) { + gpio_request(pdata->ehci_data->reset_gpio_port[0], + "USB1 PHY reset"); + gpio_direction_output + (pdata->ehci_data->reset_gpio_port[0], 1); + } + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) { + gpio_request(pdata->ehci_data->reset_gpio_port[1], + "USB2 PHY reset"); + gpio_direction_output + (pdata->ehci_data->reset_gpio_port[1], 1); + } + + /* Hold the PHY in RESET for enough time till DIR is high */ + udelay(10); + } + + omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); + dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); + + /* perform TLL soft reset, and wait until reset is complete */ + usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, + OMAP_USBTLL_SYSCONFIG_SOFTRESET); + + /* Wait for TLL reset to complete */ + timeout = jiffies + msecs_to_jiffies(1000); + while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS) + & OMAP_USBTLL_SYSSTATUS_RESETDONE)) { + cpu_relax(); + + if (time_after(jiffies, timeout)) { + dev_dbg(dev, "operation timed out\n"); + ret = -EINVAL; + goto err_tll; + } + } + + dev_dbg(dev, "TLL RESET DONE\n"); + + /* (1<<3) = no idle mode only for initial debugging */ + usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, + OMAP_USBTLL_SYSCONFIG_ENAWAKEUP | + OMAP_USBTLL_SYSCONFIG_SIDLEMODE | + OMAP_USBTLL_SYSCONFIG_AUTOIDLE); + + /* Put UHH in NoIdle/NoStandby mode */ + reg = usbhs_read(omap->uhh_base, OMAP_UHH_SYSCONFIG); + if (is_omap_usbhs_rev1(omap)) { + reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP + | OMAP_UHH_SYSCONFIG_SIDLEMODE + | OMAP_UHH_SYSCONFIG_CACTIVITY + | OMAP_UHH_SYSCONFIG_MIDLEMODE); + reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; + + + } else if (is_omap_usbhs_rev2(omap)) { + reg &= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR; + reg |= OMAP4_UHH_SYSCONFIG_NOIDLE; + reg &= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR; + reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY; + } + + usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); + + reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG); + /* setup ULPI bypass and burst configurations */ + reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN + | OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN + | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN); + reg |= OMAP4_UHH_HOSTCONFIG_APP_START_CLK; + reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; + + if (is_omap_usbhs_rev1(omap)) { + if (pdata->port_mode[0] == OMAP_USBHS_PORT_MODE_UNUSED) + reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; + if (pdata->port_mode[1] == OMAP_USBHS_PORT_MODE_UNUSED) + reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; + if (pdata->port_mode[2] == OMAP_USBHS_PORT_MODE_UNUSED) + reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; + + /* Bypass the TLL module for PHY mode operation */ + if (cpu_is_omap3430() && (omap_rev() <= OMAP3430_REV_ES2_1)) { + dev_dbg(dev, "OMAP3 ES version <= ES2.1\n"); + if (is_ehci_phy_mode(pdata->port_mode[0]) || + is_ehci_phy_mode(pdata->port_mode[1]) || + is_ehci_phy_mode(pdata->port_mode[2])) + reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; + else + reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; + } else { + dev_dbg(dev, "OMAP3 ES version > ES2.1\n"); + if (is_ehci_phy_mode(pdata->port_mode[0])) + reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; + else + reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; + if (is_ehci_phy_mode(pdata->port_mode[1])) + reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; + else + reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; + if (is_ehci_phy_mode(pdata->port_mode[2])) + reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; + else + reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; + } + } else if (is_omap_usbhs_rev2(omap)) { + /* Clear port mode fields for PHY mode*/ + reg &= ~OMAP4_P1_MODE_CLEAR; + reg &= ~OMAP4_P2_MODE_CLEAR; + + if (is_ehci_phy_mode(pdata->port_mode[0])) { + ret = clk_set_parent(omap->utmi_p1_fck, + omap->xclk60mhsp1_ck); + if (ret != 0) { + dev_err(dev, "xclk60mhsp1_ck set parent" + "failed error:%d\n", ret); + goto err_tll; + } + } else if (is_ehci_tll_mode(pdata->port_mode[0])) { + ret = clk_set_parent(omap->utmi_p1_fck, + omap->init_60m_fclk); + if (ret != 0) { + dev_err(dev, "init_60m_fclk set parent" + "failed error:%d\n", ret); + goto err_tll; + } + clk_enable(omap->usbhost_p1_fck); + clk_enable(omap->usbtll_p1_fck); + } + + if (is_ehci_phy_mode(pdata->port_mode[1])) { + ret = clk_set_parent(omap->utmi_p2_fck, + omap->xclk60mhsp2_ck); + if (ret != 0) { + dev_err(dev, "xclk60mhsp1_ck set parent" + "failed error:%d\n", ret); + goto err_tll; + } + } else if (is_ehci_tll_mode(pdata->port_mode[1])) { + ret = clk_set_parent(omap->utmi_p2_fck, + omap->init_60m_fclk); + if (ret != 0) { + dev_err(dev, "init_60m_fclk set parent" + "failed error:%d\n", ret); + goto err_tll; + } + clk_enable(omap->usbhost_p2_fck); + clk_enable(omap->usbtll_p2_fck); + } + + clk_enable(omap->utmi_p1_fck); + clk_enable(omap->utmi_p2_fck); + + if (is_ehci_tll_mode(pdata->port_mode[0]) || + (is_ohci_port(pdata->port_mode[0]))) + reg |= OMAP4_P1_MODE_TLL; + else if (is_ehci_hsic_mode(pdata->port_mode[0])) + reg |= OMAP4_P1_MODE_HSIC; + + if (is_ehci_tll_mode(pdata->port_mode[1]) || + (is_ohci_port(pdata->port_mode[1]))) + reg |= OMAP4_P2_MODE_TLL; + else if (is_ehci_hsic_mode(pdata->port_mode[1])) + reg |= OMAP4_P2_MODE_HSIC; + } + + usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); + dev_dbg(dev, "UHH setup done, uhh_hostconfig=%x\n", reg); + + if (is_ehci_tll_mode(pdata->port_mode[0]) || + is_ehci_tll_mode(pdata->port_mode[1]) || + is_ehci_tll_mode(pdata->port_mode[2]) || + (is_ohci_port(pdata->port_mode[0])) || + (is_ohci_port(pdata->port_mode[1])) || + (is_ohci_port(pdata->port_mode[2]))) { + + /* Enable UTMI mode for required TLL channels */ + if (is_omap_usbhs_rev2(omap)) + usbhs_omap_tll_init(dev, OMAP_REV2_TLL_CHANNEL_COUNT); + else + usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT); + } + + if (pdata->ehci_data->phy_reset) { + /* Hold the PHY in RESET for enough time till + * PHY is settled and ready + */ + udelay(10); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) + gpio_set_value + (pdata->ehci_data->reset_gpio_port[0], 0); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) + gpio_set_value + (pdata->ehci_data->reset_gpio_port[1], 0); + } + +end_count: + omap->count++; + goto end_enable; + +err_tll: + if (pdata->ehci_data->phy_reset) { + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) + gpio_free(pdata->ehci_data->reset_gpio_port[0]); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) + gpio_free(pdata->ehci_data->reset_gpio_port[1]); + } + + clk_disable(omap->usbtll_ick); + clk_disable(omap->usbtll_fck); + clk_disable(omap->usbhost_fs_fck); + clk_disable(omap->usbhost_hs_fck); + clk_disable(omap->usbhost_ick); + +end_enable: + spin_unlock_irqrestore(&omap->lock, flags); + return ret; +} + +static void usbhs_disable(struct device *dev) +{ + struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); + struct usbhs_omap_platform_data *pdata = &omap->platdata; + unsigned long flags = 0; + unsigned long timeout; + + dev_dbg(dev, "stopping TI HSUSB Controller\n"); + + spin_lock_irqsave(&omap->lock, flags); + + if (omap->count == 0) + goto end_disble; + + omap->count--; + + if (omap->count != 0) + goto end_disble; + + /* Reset OMAP modules for insmod/rmmod to work */ + usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, + is_omap_usbhs_rev2(omap) ? + OMAP4_UHH_SYSCONFIG_SOFTRESET : + OMAP_UHH_SYSCONFIG_SOFTRESET); + + timeout = jiffies + msecs_to_jiffies(100); + while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS) + & (1 << 0))) { + cpu_relax(); + + if (time_after(jiffies, timeout)) + dev_dbg(dev, "operation timed out\n"); + } + + while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS) + & (1 << 1))) { + cpu_relax(); + + if (time_after(jiffies, timeout)) + dev_dbg(dev, "operation timed out\n"); + } + + while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS) + & (1 << 2))) { + cpu_relax(); + + if (time_after(jiffies, timeout)) + dev_dbg(dev, "operation timed out\n"); + } + + usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, (1 << 1)); + + while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS) + & (1 << 0))) { + cpu_relax(); + + if (time_after(jiffies, timeout)) + dev_dbg(dev, "operation timed out\n"); + } + + if (pdata->ehci_data->phy_reset) { + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) + gpio_free(pdata->ehci_data->reset_gpio_port[0]); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) + gpio_free(pdata->ehci_data->reset_gpio_port[1]); + } + + clk_disable(omap->utmi_p2_fck); + clk_disable(omap->utmi_p1_fck); + clk_disable(omap->usbtll_ick); + clk_disable(omap->usbtll_fck); + clk_disable(omap->usbhost_fs_fck); + clk_disable(omap->usbhost_hs_fck); + clk_disable(omap->usbhost_ick); + +end_disble: + spin_unlock_irqrestore(&omap->lock, flags); +} + +int omap_usbhs_enable(struct device *dev) +{ + return usbhs_enable(dev->parent); +} +EXPORT_SYMBOL_GPL(omap_usbhs_enable); + +void omap_usbhs_disable(struct device *dev) +{ + usbhs_disable(dev->parent); +} +EXPORT_SYMBOL_GPL(omap_usbhs_disable); + +static struct platform_driver usbhs_omap_driver = { + .driver = { + .name = (char *)usbhs_driver_name, + .owner = THIS_MODULE, + }, + .remove = __exit_p(usbhs_omap_remove), +}; + +MODULE_AUTHOR("Keshava Munegowda "); +MODULE_ALIAS("platform:" USBHS_DRIVER_NAME); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("usb host common core driver for omap EHCI and OHCI"); + +static int __init omap_usbhs_drvinit(void) +{ + return platform_driver_probe(&usbhs_omap_driver, usbhs_omap_probe); +} + +/* + * init before ehci and ohci drivers; + * The usbhs core driver should be initialized much before + * the omap ehci and ohci probe functions are called. + */ +fs_initcall(omap_usbhs_drvinit); + +static void __exit omap_usbhs_drvexit(void) +{ + platform_driver_unregister(&usbhs_omap_driver); +} +module_exit(omap_usbhs_drvexit); -- cgit v1.2.3 From 19403165c272cc4ed00c97973e7271714b009708 Mon Sep 17 00:00:00 2001 From: Keshava Munegowda Date: Tue, 1 Mar 2011 20:08:21 +0530 Subject: usb: host: omap: ehci and ohci simplification The ehci and ohci drivers are simplified; Since UHH and TLL initialization, clock handling are done by common usbhs core driver, these functionalities are removed from ehci and ohci drivers. Signed-off-by: Keshava Munegowda Signed-off-by: Felipe Balbi --- drivers/usb/host/ehci-omap.c | 1016 ++++------------------------------------- drivers/usb/host/ohci-omap3.c | 584 ++--------------------- 2 files changed, 132 insertions(+), 1468 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 18df6c6a5803..7e41a95c5ceb 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -4,9 +4,10 @@ * Bus Glue for the EHCI controllers in OMAP3/4 * Tested on several OMAP3 boards, and OMAP4 Pandaboard * - * Copyright (C) 2007-2010 Texas Instruments, Inc. + * Copyright (C) 2007-2011 Texas Instruments, Inc. * Author: Vikram Pandita * Author: Anand Gadiyar + * Author: Keshava Munegowda * * Copyright (C) 2009 Nokia Corporation * Contact: Felipe Balbi @@ -27,116 +28,19 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * TODO (last updated Nov 21, 2010): + * TODO (last updated Feb 27, 2010): * - add kernel-doc * - enable AUTOIDLE * - add suspend/resume - * - move workarounds to board-files - * - factor out code common to OHCI * - add HSIC and TLL support * - convert to use hwmod and runtime PM */ #include -#include -#include -#include #include #include #include -/* - * OMAP USBHOST Register addresses: VIRTUAL ADDRESSES - * Use ehci_omap_readl()/ehci_omap_writel() functions - */ - -/* TLL Register Set */ -#define OMAP_USBTLL_REVISION (0x00) -#define OMAP_USBTLL_SYSCONFIG (0x10) -#define OMAP_USBTLL_SYSCONFIG_CACTIVITY (1 << 8) -#define OMAP_USBTLL_SYSCONFIG_SIDLEMODE (1 << 3) -#define OMAP_USBTLL_SYSCONFIG_ENAWAKEUP (1 << 2) -#define OMAP_USBTLL_SYSCONFIG_SOFTRESET (1 << 1) -#define OMAP_USBTLL_SYSCONFIG_AUTOIDLE (1 << 0) - -#define OMAP_USBTLL_SYSSTATUS (0x14) -#define OMAP_USBTLL_SYSSTATUS_RESETDONE (1 << 0) - -#define OMAP_USBTLL_IRQSTATUS (0x18) -#define OMAP_USBTLL_IRQENABLE (0x1C) - -#define OMAP_TLL_SHARED_CONF (0x30) -#define OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN (1 << 6) -#define OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN (1 << 5) -#define OMAP_TLL_SHARED_CONF_USB_DIVRATION (1 << 2) -#define OMAP_TLL_SHARED_CONF_FCLK_REQ (1 << 1) -#define OMAP_TLL_SHARED_CONF_FCLK_IS_ON (1 << 0) - -#define OMAP_TLL_CHANNEL_CONF(num) (0x040 + 0x004 * num) -#define OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF (1 << 11) -#define OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE (1 << 10) -#define OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE (1 << 9) -#define OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE (1 << 8) -#define OMAP_TLL_CHANNEL_CONF_CHANEN (1 << 0) - -#define OMAP_TLL_ULPI_FUNCTION_CTRL(num) (0x804 + 0x100 * num) -#define OMAP_TLL_ULPI_INTERFACE_CTRL(num) (0x807 + 0x100 * num) -#define OMAP_TLL_ULPI_OTG_CTRL(num) (0x80A + 0x100 * num) -#define OMAP_TLL_ULPI_INT_EN_RISE(num) (0x80D + 0x100 * num) -#define OMAP_TLL_ULPI_INT_EN_FALL(num) (0x810 + 0x100 * num) -#define OMAP_TLL_ULPI_INT_STATUS(num) (0x813 + 0x100 * num) -#define OMAP_TLL_ULPI_INT_LATCH(num) (0x814 + 0x100 * num) -#define OMAP_TLL_ULPI_DEBUG(num) (0x815 + 0x100 * num) -#define OMAP_TLL_ULPI_SCRATCH_REGISTER(num) (0x816 + 0x100 * num) - -#define OMAP_TLL_CHANNEL_COUNT 3 -#define OMAP_TLL_CHANNEL_1_EN_MASK (1 << 0) -#define OMAP_TLL_CHANNEL_2_EN_MASK (1 << 1) -#define OMAP_TLL_CHANNEL_3_EN_MASK (1 << 2) - -/* UHH Register Set */ -#define OMAP_UHH_REVISION (0x00) -#define OMAP_UHH_SYSCONFIG (0x10) -#define OMAP_UHH_SYSCONFIG_MIDLEMODE (1 << 12) -#define OMAP_UHH_SYSCONFIG_CACTIVITY (1 << 8) -#define OMAP_UHH_SYSCONFIG_SIDLEMODE (1 << 3) -#define OMAP_UHH_SYSCONFIG_ENAWAKEUP (1 << 2) -#define OMAP_UHH_SYSCONFIG_SOFTRESET (1 << 1) -#define OMAP_UHH_SYSCONFIG_AUTOIDLE (1 << 0) - -#define OMAP_UHH_SYSSTATUS (0x14) -#define OMAP_UHH_HOSTCONFIG (0x40) -#define OMAP_UHH_HOSTCONFIG_ULPI_BYPASS (1 << 0) -#define OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS (1 << 0) -#define OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS (1 << 11) -#define OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS (1 << 12) -#define OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN (1 << 2) -#define OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN (1 << 3) -#define OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN (1 << 4) -#define OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN (1 << 5) -#define OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS (1 << 8) -#define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS (1 << 9) -#define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS (1 << 10) - -/* OMAP4-specific defines */ -#define OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR (3 << 2) -#define OMAP4_UHH_SYSCONFIG_NOIDLE (1 << 2) - -#define OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR (3 << 4) -#define OMAP4_UHH_SYSCONFIG_NOSTDBY (1 << 4) -#define OMAP4_UHH_SYSCONFIG_SOFTRESET (1 << 0) - -#define OMAP4_P1_MODE_CLEAR (3 << 16) -#define OMAP4_P1_MODE_TLL (1 << 16) -#define OMAP4_P1_MODE_HSIC (3 << 16) -#define OMAP4_P2_MODE_CLEAR (3 << 18) -#define OMAP4_P2_MODE_TLL (1 << 18) -#define OMAP4_P2_MODE_HSIC (3 << 18) - -#define OMAP_REV2_TLL_CHANNEL_COUNT 2 - -#define OMAP_UHH_DEBUG_CSR (0x44) - /* EHCI Register Set */ #define EHCI_INSNREG04 (0xA0) #define EHCI_INSNREG04_DISABLE_UNSUSPEND (1 << 5) @@ -148,141 +52,24 @@ #define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8 #define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0 -/* Values of UHH_REVISION - Note: these are not given in the TRM */ -#define OMAP_EHCI_REV1 0x00000010 /* OMAP3 */ -#define OMAP_EHCI_REV2 0x50700100 /* OMAP4 */ +/*-------------------------------------------------------------------------*/ -#define is_omap_ehci_rev1(x) (x->omap_ehci_rev == OMAP_EHCI_REV1) -#define is_omap_ehci_rev2(x) (x->omap_ehci_rev == OMAP_EHCI_REV2) +static const struct hc_driver ehci_omap_hc_driver; -#define is_ehci_phy_mode(x) (x == OMAP_EHCI_PORT_MODE_PHY) -#define is_ehci_tll_mode(x) (x == OMAP_EHCI_PORT_MODE_TLL) -#define is_ehci_hsic_mode(x) (x == OMAP_EHCI_PORT_MODE_HSIC) -/*-------------------------------------------------------------------------*/ - -static inline void ehci_omap_writel(void __iomem *base, u32 reg, u32 val) +static inline void ehci_write(void __iomem *base, u32 reg, u32 val) { __raw_writel(val, base + reg); } -static inline u32 ehci_omap_readl(void __iomem *base, u32 reg) +static inline u32 ehci_read(void __iomem *base, u32 reg) { return __raw_readl(base + reg); } -static inline void ehci_omap_writeb(void __iomem *base, u8 reg, u8 val) -{ - __raw_writeb(val, base + reg); -} - -static inline u8 ehci_omap_readb(void __iomem *base, u8 reg) -{ - return __raw_readb(base + reg); -} - -/*-------------------------------------------------------------------------*/ - -struct ehci_hcd_omap { - struct ehci_hcd *ehci; - struct device *dev; - - struct clk *usbhost_ick; - struct clk *usbhost_hs_fck; - struct clk *usbhost_fs_fck; - struct clk *usbtll_fck; - struct clk *usbtll_ick; - struct clk *xclk60mhsp1_ck; - struct clk *xclk60mhsp2_ck; - struct clk *utmi_p1_fck; - struct clk *usbhost_p1_fck; - struct clk *usbtll_p1_fck; - struct clk *utmi_p2_fck; - struct clk *usbhost_p2_fck; - struct clk *usbtll_p2_fck; - - /* FIXME the following two workarounds are - * board specific not silicon-specific so these - * should be moved to board-file instead. - * - * Maybe someone from TI will know better which - * board is affected and needs the workarounds - * to be applied - */ - - /* gpio for resetting phy */ - int reset_gpio_port[OMAP3_HS_USB_PORTS]; - - /* phy reset workaround */ - int phy_reset; - - /* IP revision */ - u32 omap_ehci_rev; - - /* desired phy_mode: TLL, PHY */ - enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS]; - - void __iomem *uhh_base; - void __iomem *tll_base; - void __iomem *ehci_base; - - /* Regulators for USB PHYs. - * Each PHY can have a separate regulator. - */ - struct regulator *regulator[OMAP3_HS_USB_PORTS]; -}; - -/*-------------------------------------------------------------------------*/ - -static void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask, - u8 tll_channel_count) -{ - unsigned reg; - int i; - - /* Program the 3 TLL channels upfront */ - for (i = 0; i < tll_channel_count; i++) { - reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); - - /* Disable AutoIdle, BitStuffing and use SDR Mode */ - reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE - | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF - | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE); - ehci_omap_writel(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i), reg); - } - - /* Program Common TLL register */ - reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_SHARED_CONF); - reg |= (OMAP_TLL_SHARED_CONF_FCLK_IS_ON - | OMAP_TLL_SHARED_CONF_USB_DIVRATION - | OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN); - reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN; - - ehci_omap_writel(omap->tll_base, OMAP_TLL_SHARED_CONF, reg); - - /* Enable channels now */ - for (i = 0; i < tll_channel_count; i++) { - reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); - - /* Enable only the reg that is needed */ - if (!(tll_channel_mask & 1<tll_base, OMAP_TLL_CHANNEL_CONF(i), reg); - - ehci_omap_writeb(omap->tll_base, - OMAP_TLL_ULPI_SCRATCH_REGISTER(i), 0xbe); - dev_dbg(omap->dev, "ULPI_SCRATCH_REG[ch=%d]= 0x%02x\n", - i+1, ehci_omap_readb(omap->tll_base, - OMAP_TLL_ULPI_SCRATCH_REGISTER(i))); - } -} - -/*-------------------------------------------------------------------------*/ - -static void omap_ehci_soft_phy_reset(struct ehci_hcd_omap *omap, u8 port) +static void omap_ehci_soft_phy_reset(struct platform_device *pdev, u8 port) { + struct usb_hcd *hcd = dev_get_drvdata(&pdev->dev); unsigned long timeout = jiffies + msecs_to_jiffies(1000); unsigned reg = 0; @@ -296,600 +83,20 @@ static void omap_ehci_soft_phy_reset(struct ehci_hcd_omap *omap, u8 port) /* start ULPI access*/ | (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT); - ehci_omap_writel(omap->ehci_base, EHCI_INSNREG05_ULPI, reg); + ehci_write(hcd->regs, EHCI_INSNREG05_ULPI, reg); /* Wait for ULPI access completion */ - while ((ehci_omap_readl(omap->ehci_base, EHCI_INSNREG05_ULPI) + while ((ehci_read(hcd->regs, EHCI_INSNREG05_ULPI) & (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT))) { cpu_relax(); if (time_after(jiffies, timeout)) { - dev_dbg(omap->dev, "phy reset operation timed out\n"); + dev_dbg(&pdev->dev, "phy reset operation timed out\n"); break; } } } -/* omap_start_ehc - * - Start the TI USBHOST controller - */ -static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(1000); - u8 tll_ch_mask = 0; - unsigned reg = 0; - int ret = 0; - - dev_dbg(omap->dev, "starting TI EHCI USB Controller\n"); - - /* Enable Clocks for USBHOST */ - omap->usbhost_ick = clk_get(omap->dev, "usbhost_ick"); - if (IS_ERR(omap->usbhost_ick)) { - ret = PTR_ERR(omap->usbhost_ick); - goto err_host_ick; - } - clk_enable(omap->usbhost_ick); - - omap->usbhost_hs_fck = clk_get(omap->dev, "hs_fck"); - if (IS_ERR(omap->usbhost_hs_fck)) { - ret = PTR_ERR(omap->usbhost_hs_fck); - goto err_host_120m_fck; - } - clk_enable(omap->usbhost_hs_fck); - - omap->usbhost_fs_fck = clk_get(omap->dev, "fs_fck"); - if (IS_ERR(omap->usbhost_fs_fck)) { - ret = PTR_ERR(omap->usbhost_fs_fck); - goto err_host_48m_fck; - } - clk_enable(omap->usbhost_fs_fck); - - if (omap->phy_reset) { - /* Refer: ISSUE1 */ - if (gpio_is_valid(omap->reset_gpio_port[0])) { - gpio_request(omap->reset_gpio_port[0], - "USB1 PHY reset"); - gpio_direction_output(omap->reset_gpio_port[0], 0); - } - - if (gpio_is_valid(omap->reset_gpio_port[1])) { - gpio_request(omap->reset_gpio_port[1], - "USB2 PHY reset"); - gpio_direction_output(omap->reset_gpio_port[1], 0); - } - - /* Hold the PHY in RESET for enough time till DIR is high */ - udelay(10); - } - - /* Configure TLL for 60Mhz clk for ULPI */ - omap->usbtll_fck = clk_get(omap->dev, "usbtll_fck"); - if (IS_ERR(omap->usbtll_fck)) { - ret = PTR_ERR(omap->usbtll_fck); - goto err_tll_fck; - } - clk_enable(omap->usbtll_fck); - - omap->usbtll_ick = clk_get(omap->dev, "usbtll_ick"); - if (IS_ERR(omap->usbtll_ick)) { - ret = PTR_ERR(omap->usbtll_ick); - goto err_tll_ick; - } - clk_enable(omap->usbtll_ick); - - omap->omap_ehci_rev = ehci_omap_readl(omap->uhh_base, - OMAP_UHH_REVISION); - dev_dbg(omap->dev, "OMAP UHH_REVISION 0x%x\n", - omap->omap_ehci_rev); - - /* - * Enable per-port clocks as needed (newer controllers only). - * - External ULPI clock for PHY mode - * - Internal clocks for TLL and HSIC modes (TODO) - */ - if (is_omap_ehci_rev2(omap)) { - switch (omap->port_mode[0]) { - case OMAP_EHCI_PORT_MODE_PHY: - omap->xclk60mhsp1_ck = clk_get(omap->dev, - "xclk60mhsp1_ck"); - if (IS_ERR(omap->xclk60mhsp1_ck)) { - ret = PTR_ERR(omap->xclk60mhsp1_ck); - dev_err(omap->dev, - "Unable to get Port1 ULPI clock\n"); - } - - omap->utmi_p1_fck = clk_get(omap->dev, - "utmi_p1_gfclk"); - if (IS_ERR(omap->utmi_p1_fck)) { - ret = PTR_ERR(omap->utmi_p1_fck); - dev_err(omap->dev, - "Unable to get utmi_p1_fck\n"); - } - - ret = clk_set_parent(omap->utmi_p1_fck, - omap->xclk60mhsp1_ck); - if (ret != 0) { - dev_err(omap->dev, - "Unable to set P1 f-clock\n"); - } - break; - case OMAP_EHCI_PORT_MODE_TLL: - omap->xclk60mhsp1_ck = clk_get(omap->dev, - "init_60m_fclk"); - if (IS_ERR(omap->xclk60mhsp1_ck)) { - ret = PTR_ERR(omap->xclk60mhsp1_ck); - dev_err(omap->dev, - "Unable to get Port1 ULPI clock\n"); - } - - omap->utmi_p1_fck = clk_get(omap->dev, - "utmi_p1_gfclk"); - if (IS_ERR(omap->utmi_p1_fck)) { - ret = PTR_ERR(omap->utmi_p1_fck); - dev_err(omap->dev, - "Unable to get utmi_p1_fck\n"); - } - - ret = clk_set_parent(omap->utmi_p1_fck, - omap->xclk60mhsp1_ck); - if (ret != 0) { - dev_err(omap->dev, - "Unable to set P1 f-clock\n"); - } - - omap->usbhost_p1_fck = clk_get(omap->dev, - "usb_host_hs_utmi_p1_clk"); - if (IS_ERR(omap->usbhost_p1_fck)) { - ret = PTR_ERR(omap->usbhost_p1_fck); - dev_err(omap->dev, - "Unable to get HOST PORT 1 clk\n"); - } else { - clk_enable(omap->usbhost_p1_fck); - } - - omap->usbtll_p1_fck = clk_get(omap->dev, - "usb_tll_hs_usb_ch0_clk"); - - if (IS_ERR(omap->usbtll_p1_fck)) { - ret = PTR_ERR(omap->usbtll_p1_fck); - dev_err(omap->dev, - "Unable to get TLL CH0 clk\n"); - } else { - clk_enable(omap->usbtll_p1_fck); - } - break; - /* TODO */ - default: - break; - } - switch (omap->port_mode[1]) { - case OMAP_EHCI_PORT_MODE_PHY: - omap->xclk60mhsp2_ck = clk_get(omap->dev, - "xclk60mhsp2_ck"); - if (IS_ERR(omap->xclk60mhsp2_ck)) { - ret = PTR_ERR(omap->xclk60mhsp2_ck); - dev_err(omap->dev, - "Unable to get Port2 ULPI clock\n"); - } - - omap->utmi_p2_fck = clk_get(omap->dev, - "utmi_p2_gfclk"); - if (IS_ERR(omap->utmi_p2_fck)) { - ret = PTR_ERR(omap->utmi_p2_fck); - dev_err(omap->dev, - "Unable to get utmi_p2_fck\n"); - } - - ret = clk_set_parent(omap->utmi_p2_fck, - omap->xclk60mhsp2_ck); - if (ret != 0) { - dev_err(omap->dev, - "Unable to set P2 f-clock\n"); - } - break; - case OMAP_EHCI_PORT_MODE_TLL: - omap->xclk60mhsp2_ck = clk_get(omap->dev, - "init_60m_fclk"); - if (IS_ERR(omap->xclk60mhsp2_ck)) { - ret = PTR_ERR(omap->xclk60mhsp2_ck); - dev_err(omap->dev, - "Unable to get Port2 ULPI clock\n"); - } - - omap->utmi_p2_fck = clk_get(omap->dev, - "utmi_p2_gfclk"); - if (IS_ERR(omap->utmi_p2_fck)) { - ret = PTR_ERR(omap->utmi_p2_fck); - dev_err(omap->dev, - "Unable to get utmi_p2_fck\n"); - } - - ret = clk_set_parent(omap->utmi_p2_fck, - omap->xclk60mhsp2_ck); - if (ret != 0) { - dev_err(omap->dev, - "Unable to set P2 f-clock\n"); - } - - omap->usbhost_p2_fck = clk_get(omap->dev, - "usb_host_hs_utmi_p2_clk"); - if (IS_ERR(omap->usbhost_p2_fck)) { - ret = PTR_ERR(omap->usbhost_p2_fck); - dev_err(omap->dev, - "Unable to get HOST PORT 2 clk\n"); - } else { - clk_enable(omap->usbhost_p2_fck); - } - - omap->usbtll_p2_fck = clk_get(omap->dev, - "usb_tll_hs_usb_ch1_clk"); - - if (IS_ERR(omap->usbtll_p2_fck)) { - ret = PTR_ERR(omap->usbtll_p2_fck); - dev_err(omap->dev, - "Unable to get TLL CH1 clk\n"); - } else { - clk_enable(omap->usbtll_p2_fck); - } - break; - /* TODO */ - default: - break; - } - } - - - /* perform TLL soft reset, and wait until reset is complete */ - ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, - OMAP_USBTLL_SYSCONFIG_SOFTRESET); - - /* Wait for TLL reset to complete */ - while (!(ehci_omap_readl(omap->tll_base, OMAP_USBTLL_SYSSTATUS) - & OMAP_USBTLL_SYSSTATUS_RESETDONE)) { - cpu_relax(); - - if (time_after(jiffies, timeout)) { - dev_dbg(omap->dev, "operation timed out\n"); - ret = -EINVAL; - goto err_sys_status; - } - } - - dev_dbg(omap->dev, "TLL RESET DONE\n"); - - /* (1<<3) = no idle mode only for initial debugging */ - ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, - OMAP_USBTLL_SYSCONFIG_ENAWAKEUP | - OMAP_USBTLL_SYSCONFIG_SIDLEMODE | - OMAP_USBTLL_SYSCONFIG_CACTIVITY); - - - /* Put UHH in NoIdle/NoStandby mode */ - reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG); - if (is_omap_ehci_rev1(omap)) { - reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP - | OMAP_UHH_SYSCONFIG_SIDLEMODE - | OMAP_UHH_SYSCONFIG_CACTIVITY - | OMAP_UHH_SYSCONFIG_MIDLEMODE); - reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; - - - } else if (is_omap_ehci_rev2(omap)) { - reg &= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR; - reg |= OMAP4_UHH_SYSCONFIG_NOIDLE; - reg &= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR; - reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY; - } - ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); - - reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG); - - /* setup ULPI bypass and burst configurations */ - reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN - | OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN - | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN); - reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; - - if (is_omap_ehci_rev1(omap)) { - if (omap->port_mode[0] == OMAP_USBHS_PORT_MODE_UNUSED) - reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; - if (omap->port_mode[1] == OMAP_USBHS_PORT_MODE_UNUSED) - reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; - if (omap->port_mode[2] == OMAP_USBHS_PORT_MODE_UNUSED) - reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; - - /* Bypass the TLL module for PHY mode operation */ - if (cpu_is_omap3430() && (omap_rev() <= OMAP3430_REV_ES2_1)) { - dev_dbg(omap->dev, "OMAP3 ES version <= ES2.1\n"); - if (is_ehci_phy_mode(omap->port_mode[0]) || - is_ehci_phy_mode(omap->port_mode[1]) || - is_ehci_phy_mode(omap->port_mode[2])) - reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; - else - reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; - } else { - dev_dbg(omap->dev, "OMAP3 ES version > ES2.1\n"); - if (is_ehci_phy_mode(omap->port_mode[0])) - reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; - else if (is_ehci_tll_mode(omap->port_mode[0])) - reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; - - if (is_ehci_phy_mode(omap->port_mode[1])) - reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; - else if (is_ehci_tll_mode(omap->port_mode[1])) - reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; - - if (is_ehci_phy_mode(omap->port_mode[2])) - reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; - else if (is_ehci_tll_mode(omap->port_mode[2])) - reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; - } - } else if (is_omap_ehci_rev2(omap)) { - /* Clear port mode fields for PHY mode*/ - reg &= ~OMAP4_P1_MODE_CLEAR; - reg &= ~OMAP4_P2_MODE_CLEAR; - - if (is_ehci_tll_mode(omap->port_mode[0])) - reg |= OMAP4_P1_MODE_TLL; - else if (is_ehci_hsic_mode(omap->port_mode[0])) - reg |= OMAP4_P1_MODE_HSIC; - - if (is_ehci_tll_mode(omap->port_mode[1])) - reg |= OMAP4_P2_MODE_TLL; - else if (is_ehci_hsic_mode(omap->port_mode[1])) - reg |= OMAP4_P2_MODE_HSIC; - } - - ehci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); - dev_dbg(omap->dev, "UHH setup done, uhh_hostconfig=%x\n", reg); - - - /* - * An undocumented "feature" in the OMAP3 EHCI controller, - * causes suspended ports to be taken out of suspend when - * the USBCMD.Run/Stop bit is cleared (for example when - * we do ehci_bus_suspend). - * This breaks suspend-resume if the root-hub is allowed - * to suspend. Writing 1 to this undocumented register bit - * disables this feature and restores normal behavior. - */ - ehci_omap_writel(omap->ehci_base, EHCI_INSNREG04, - EHCI_INSNREG04_DISABLE_UNSUSPEND); - - if ((omap->port_mode[0] == OMAP_EHCI_PORT_MODE_TLL) || - (omap->port_mode[1] == OMAP_EHCI_PORT_MODE_TLL) || - (omap->port_mode[2] == OMAP_EHCI_PORT_MODE_TLL)) { - - if (omap->port_mode[0] == OMAP_EHCI_PORT_MODE_TLL) - tll_ch_mask |= OMAP_TLL_CHANNEL_1_EN_MASK; - if (omap->port_mode[1] == OMAP_EHCI_PORT_MODE_TLL) - tll_ch_mask |= OMAP_TLL_CHANNEL_2_EN_MASK; - if (omap->port_mode[2] == OMAP_EHCI_PORT_MODE_TLL) - tll_ch_mask |= OMAP_TLL_CHANNEL_3_EN_MASK; - - /* Enable UTMI mode for required TLL channels */ - omap_usb_utmi_init(omap, tll_ch_mask, OMAP_TLL_CHANNEL_COUNT); - } - - if (omap->phy_reset) { - /* Refer ISSUE1: - * Hold the PHY in RESET for enough time till - * PHY is settled and ready - */ - udelay(10); - - if (gpio_is_valid(omap->reset_gpio_port[0])) - gpio_set_value(omap->reset_gpio_port[0], 1); - - if (gpio_is_valid(omap->reset_gpio_port[1])) - gpio_set_value(omap->reset_gpio_port[1], 1); - } - - /* Soft reset the PHY using PHY reset command over ULPI */ - if (omap->port_mode[0] == OMAP_EHCI_PORT_MODE_PHY) - omap_ehci_soft_phy_reset(omap, 0); - if (omap->port_mode[1] == OMAP_EHCI_PORT_MODE_PHY) - omap_ehci_soft_phy_reset(omap, 1); - - return 0; - -err_sys_status: - - if (omap->usbtll_p2_fck != NULL) { - clk_disable(omap->usbtll_p2_fck); - clk_put(omap->usbtll_p2_fck); - } - if (omap->usbhost_p2_fck != NULL) { - clk_disable(omap->usbhost_p2_fck); - clk_put(omap->usbhost_p2_fck); - } - if (omap->usbtll_p1_fck != NULL) { - clk_disable(omap->usbtll_p1_fck); - clk_put(omap->usbtll_p1_fck); - } - if (omap->usbhost_p1_fck != NULL) { - clk_disable(omap->usbhost_p1_fck); - clk_put(omap->usbhost_p1_fck); - } - - clk_disable(omap->utmi_p2_fck); - clk_put(omap->utmi_p2_fck); - clk_disable(omap->xclk60mhsp2_ck); - clk_put(omap->xclk60mhsp2_ck); - clk_disable(omap->utmi_p1_fck); - clk_put(omap->utmi_p1_fck); - clk_disable(omap->xclk60mhsp1_ck); - clk_put(omap->xclk60mhsp1_ck); - clk_disable(omap->usbtll_ick); - clk_put(omap->usbtll_ick); - -err_tll_ick: - clk_disable(omap->usbtll_fck); - clk_put(omap->usbtll_fck); - -err_tll_fck: - clk_disable(omap->usbhost_fs_fck); - clk_put(omap->usbhost_fs_fck); - - if (omap->phy_reset) { - if (gpio_is_valid(omap->reset_gpio_port[0])) - gpio_free(omap->reset_gpio_port[0]); - - if (gpio_is_valid(omap->reset_gpio_port[1])) - gpio_free(omap->reset_gpio_port[1]); - } - -err_host_48m_fck: - clk_disable(omap->usbhost_hs_fck); - clk_put(omap->usbhost_hs_fck); - -err_host_120m_fck: - clk_disable(omap->usbhost_ick); - clk_put(omap->usbhost_ick); - -err_host_ick: - return ret; -} - -static void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(100); - - dev_dbg(omap->dev, "stopping TI EHCI USB Controller\n"); - - /* Reset OMAP modules for insmod/rmmod to work */ - ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, - is_omap_ehci_rev2(omap) ? - OMAP4_UHH_SYSCONFIG_SOFTRESET : - OMAP_UHH_SYSCONFIG_SOFTRESET); - while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) - & (1 << 0))) { - cpu_relax(); - - if (time_after(jiffies, timeout)) - dev_dbg(omap->dev, "operation timed out\n"); - } - - while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) - & (1 << 1))) { - cpu_relax(); - - if (time_after(jiffies, timeout)) - dev_dbg(omap->dev, "operation timed out\n"); - } - - while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) - & (1 << 2))) { - cpu_relax(); - - if (time_after(jiffies, timeout)) - dev_dbg(omap->dev, "operation timed out\n"); - } - - ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, (1 << 1)); - - while (!(ehci_omap_readl(omap->tll_base, OMAP_USBTLL_SYSSTATUS) - & (1 << 0))) { - cpu_relax(); - - if (time_after(jiffies, timeout)) - dev_dbg(omap->dev, "operation timed out\n"); - } - - if (omap->usbtll_fck != NULL) { - clk_disable(omap->usbtll_fck); - clk_put(omap->usbtll_fck); - omap->usbtll_fck = NULL; - } - - if (omap->usbhost_ick != NULL) { - clk_disable(omap->usbhost_ick); - clk_put(omap->usbhost_ick); - omap->usbhost_ick = NULL; - } - - if (omap->usbhost_fs_fck != NULL) { - clk_disable(omap->usbhost_fs_fck); - clk_put(omap->usbhost_fs_fck); - omap->usbhost_fs_fck = NULL; - } - - if (omap->usbhost_hs_fck != NULL) { - clk_disable(omap->usbhost_hs_fck); - clk_put(omap->usbhost_hs_fck); - omap->usbhost_hs_fck = NULL; - } - - if (omap->usbtll_ick != NULL) { - clk_disable(omap->usbtll_ick); - clk_put(omap->usbtll_ick); - omap->usbtll_ick = NULL; - } - - if (is_omap_ehci_rev2(omap)) { - if (omap->xclk60mhsp1_ck != NULL) { - clk_disable(omap->xclk60mhsp1_ck); - clk_put(omap->xclk60mhsp1_ck); - omap->xclk60mhsp1_ck = NULL; - } - - if (omap->utmi_p1_fck != NULL) { - clk_disable(omap->utmi_p1_fck); - clk_put(omap->utmi_p1_fck); - omap->utmi_p1_fck = NULL; - } - - if (omap->xclk60mhsp2_ck != NULL) { - clk_disable(omap->xclk60mhsp2_ck); - clk_put(omap->xclk60mhsp2_ck); - omap->xclk60mhsp2_ck = NULL; - } - - if (omap->utmi_p2_fck != NULL) { - clk_disable(omap->utmi_p2_fck); - clk_put(omap->utmi_p2_fck); - omap->utmi_p2_fck = NULL; - } - - if (omap->usbtll_p2_fck != NULL) { - clk_disable(omap->usbtll_p2_fck); - clk_put(omap->usbtll_p2_fck); - omap->usbtll_p2_fck = NULL; - } - - if (omap->usbhost_p2_fck != NULL) { - clk_disable(omap->usbhost_p2_fck); - clk_put(omap->usbhost_p2_fck); - omap->usbhost_p2_fck = NULL; - } - - if (omap->usbtll_p1_fck != NULL) { - clk_disable(omap->usbtll_p1_fck); - clk_put(omap->usbtll_p1_fck); - omap->usbtll_p1_fck = NULL; - } - - if (omap->usbhost_p1_fck != NULL) { - clk_disable(omap->usbhost_p1_fck); - clk_put(omap->usbhost_p1_fck); - omap->usbhost_p1_fck = NULL; - } - } - - if (omap->phy_reset) { - if (gpio_is_valid(omap->reset_gpio_port[0])) - gpio_free(omap->reset_gpio_port[0]); - - if (gpio_is_valid(omap->reset_gpio_port[1])) - gpio_free(omap->reset_gpio_port[1]); - } - - dev_dbg(omap->dev, "Clock to USB host has been disabled\n"); -} - -/*-------------------------------------------------------------------------*/ - -static const struct hc_driver ehci_omap_hc_driver; /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ @@ -903,155 +110,113 @@ static const struct hc_driver ehci_omap_hc_driver; */ static int ehci_hcd_omap_probe(struct platform_device *pdev) { - struct usbhs_omap_board_data *pdata = pdev->dev.platform_data; - struct ehci_hcd_omap *omap; - struct resource *res; - struct usb_hcd *hcd; + struct device *dev = &pdev->dev; + struct ehci_hcd_omap_platform_data *pdata = dev->platform_data; + struct resource *res; + struct usb_hcd *hcd; + void __iomem *regs; + struct ehci_hcd *omap_ehci; + int ret = -ENODEV; + int irq; - int irq = platform_get_irq(pdev, 0); - int ret = -ENODEV; - int i; - char supply[7]; + if (usb_disabled()) + return -ENODEV; - if (!pdata) { - dev_dbg(&pdev->dev, "missing platform_data\n"); - goto err_pdata; + if (!dev->parent) { + dev_err(dev, "Missing parent device\n"); + return -ENODEV; } - if (usb_disabled()) - goto err_disabled; + irq = platform_get_irq_byname(pdev, "ehci-irq"); + if (irq < 0) { + dev_err(dev, "EHCI irq failed\n"); + return -ENODEV; + } - omap = kzalloc(sizeof(*omap), GFP_KERNEL); - if (!omap) { - ret = -ENOMEM; - goto err_disabled; + res = platform_get_resource_byname(pdev, + IORESOURCE_MEM, "ehci"); + if (!res) { + dev_err(dev, "UHH EHCI get resource failed\n"); + return -ENODEV; + } + + regs = ioremap(res->start, resource_size(res)); + if (!regs) { + dev_err(dev, "UHH EHCI ioremap failed\n"); + return -ENOMEM; } - hcd = usb_create_hcd(&ehci_omap_hc_driver, &pdev->dev, - dev_name(&pdev->dev)); + hcd = usb_create_hcd(&ehci_omap_hc_driver, dev, + dev_name(dev)); if (!hcd) { - dev_err(&pdev->dev, "failed to create hcd with err %d\n", ret); + dev_err(dev, "failed to create hcd with err %d\n", ret); ret = -ENOMEM; - goto err_create_hcd; + goto err_io; } - platform_set_drvdata(pdev, omap); - omap->dev = &pdev->dev; - omap->phy_reset = pdata->phy_reset; - omap->reset_gpio_port[0] = pdata->reset_gpio_port[0]; - omap->reset_gpio_port[1] = pdata->reset_gpio_port[1]; - omap->reset_gpio_port[2] = pdata->reset_gpio_port[2]; - omap->port_mode[0] = pdata->port_mode[0]; - omap->port_mode[1] = pdata->port_mode[1]; - omap->port_mode[2] = pdata->port_mode[2]; - omap->ehci = hcd_to_ehci(hcd); - omap->ehci->sbrn = 0x20; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ehci"); - hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); + hcd->regs = regs; - hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); - if (!hcd->regs) { - dev_err(&pdev->dev, "EHCI ioremap failed\n"); - ret = -ENOMEM; - goto err_ioremap; - } - - /* we know this is the memory we want, no need to ioremap again */ - omap->ehci->caps = hcd->regs; - omap->ehci_base = hcd->regs; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh"); - omap->uhh_base = ioremap(res->start, resource_size(res)); - if (!omap->uhh_base) { - dev_err(&pdev->dev, "UHH ioremap failed\n"); - ret = -ENOMEM; - goto err_uhh_ioremap; + ret = omap_usbhs_enable(dev); + if (ret) { + dev_err(dev, "failed to start usbhs with err %d\n", ret); + goto err_enable; } - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll"); - omap->tll_base = ioremap(res->start, resource_size(res)); - if (!omap->tll_base) { - dev_err(&pdev->dev, "TLL ioremap failed\n"); - ret = -ENOMEM; - goto err_tll_ioremap; - } + /* + * An undocumented "feature" in the OMAP3 EHCI controller, + * causes suspended ports to be taken out of suspend when + * the USBCMD.Run/Stop bit is cleared (for example when + * we do ehci_bus_suspend). + * This breaks suspend-resume if the root-hub is allowed + * to suspend. Writing 1 to this undocumented register bit + * disables this feature and restores normal behavior. + */ + ehci_write(regs, EHCI_INSNREG04, + EHCI_INSNREG04_DISABLE_UNSUSPEND); - /* get ehci regulator and enable */ - for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { - if (omap->port_mode[i] != OMAP_EHCI_PORT_MODE_PHY) { - omap->regulator[i] = NULL; - continue; - } - snprintf(supply, sizeof(supply), "hsusb%d", i); - omap->regulator[i] = regulator_get(omap->dev, supply); - if (IS_ERR(omap->regulator[i])) { - omap->regulator[i] = NULL; - dev_dbg(&pdev->dev, - "failed to get ehci port%d regulator\n", i); - } else { - regulator_enable(omap->regulator[i]); - } - } + /* Soft reset the PHY using PHY reset command over ULPI */ + if (pdata->port_mode[0] == OMAP_EHCI_PORT_MODE_PHY) + omap_ehci_soft_phy_reset(pdev, 0); + if (pdata->port_mode[1] == OMAP_EHCI_PORT_MODE_PHY) + omap_ehci_soft_phy_reset(pdev, 1); - ret = omap_start_ehc(omap, hcd); - if (ret) { - dev_err(&pdev->dev, "failed to start ehci with err %d\n", ret); - goto err_start; - } + omap_ehci = hcd_to_ehci(hcd); + omap_ehci->sbrn = 0x20; - omap->ehci->regs = hcd->regs - + HC_LENGTH(readl(&omap->ehci->caps->hc_capbase)); + /* we know this is the memory we want, no need to ioremap again */ + omap_ehci->caps = hcd->regs; + omap_ehci->regs = hcd->regs + + HC_LENGTH(readl(&omap_ehci->caps->hc_capbase)); - dbg_hcs_params(omap->ehci, "reset"); - dbg_hcc_params(omap->ehci, "reset"); + dbg_hcs_params(omap_ehci, "reset"); + dbg_hcc_params(omap_ehci, "reset"); /* cache this readonly data; minimize chip reads */ - omap->ehci->hcs_params = readl(&omap->ehci->caps->hcs_params); + omap_ehci->hcs_params = readl(&omap_ehci->caps->hcs_params); ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (ret) { - dev_err(&pdev->dev, "failed to add hcd with err %d\n", ret); + dev_err(dev, "failed to add hcd with err %d\n", ret); goto err_add_hcd; } /* root ports should always stay powered */ - ehci_port_power(omap->ehci, 1); + ehci_port_power(omap_ehci, 1); return 0; err_add_hcd: - omap_stop_ehc(omap, hcd); + omap_usbhs_disable(dev); -err_start: - for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { - if (omap->regulator[i]) { - regulator_disable(omap->regulator[i]); - regulator_put(omap->regulator[i]); - } - } - iounmap(omap->tll_base); - -err_tll_ioremap: - iounmap(omap->uhh_base); - -err_uhh_ioremap: - iounmap(hcd->regs); - -err_ioremap: +err_enable: usb_put_hcd(hcd); -err_create_hcd: - kfree(omap); -err_disabled: -err_pdata: +err_io: return ret; } -/* may be called without controller electrically present */ -/* may be called with controller, bus, and devices active */ /** * ehci_hcd_omap_remove - shutdown processing for EHCI HCDs @@ -1063,31 +228,18 @@ err_pdata: */ static int ehci_hcd_omap_remove(struct platform_device *pdev) { - struct ehci_hcd_omap *omap = platform_get_drvdata(pdev); - struct usb_hcd *hcd = ehci_to_hcd(omap->ehci); - int i; + struct device *dev = &pdev->dev; + struct usb_hcd *hcd = dev_get_drvdata(dev); usb_remove_hcd(hcd); - omap_stop_ehc(omap, hcd); - iounmap(hcd->regs); - for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { - if (omap->regulator[i]) { - regulator_disable(omap->regulator[i]); - regulator_put(omap->regulator[i]); - } - } - iounmap(omap->tll_base); - iounmap(omap->uhh_base); + omap_usbhs_disable(dev); usb_put_hcd(hcd); - kfree(omap); - return 0; } static void ehci_hcd_omap_shutdown(struct platform_device *pdev) { - struct ehci_hcd_omap *omap = platform_get_drvdata(pdev); - struct usb_hcd *hcd = ehci_to_hcd(omap->ehci); + struct usb_hcd *hcd = dev_get_drvdata(&pdev->dev); if (hcd->driver->shutdown) hcd->driver->shutdown(hcd); diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c index 3f9db87fe525..6048f2f64f73 100644 --- a/drivers/usb/host/ohci-omap3.c +++ b/drivers/usb/host/ohci-omap3.c @@ -7,6 +7,7 @@ * Copyright (C) 2007-2010 Texas Instruments, Inc. * Author: Vikram Pandita * Author: Anand Gadiyar + * Author: Keshava Munegowda * * Based on ehci-omap.c and some other ohci glue layers * @@ -24,150 +25,15 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * TODO (last updated Mar 10th, 2010): + * TODO (last updated Feb 27, 2011): * - add kernel-doc - * - Factor out code common to EHCI to a separate file - * - Make EHCI and OHCI coexist together - * - needs newer silicon versions to actually work - * - the last one to be loaded currently steps on the other's toes - * - Add hooks for configuring transceivers, etc. at init/exit - * - Add aggressive clock-management code */ #include -#include - #include -/* - * OMAP USBHOST Register addresses: VIRTUAL ADDRESSES - * Use ohci_omap_readl()/ohci_omap_writel() functions - */ - -/* TLL Register Set */ -#define OMAP_USBTLL_REVISION (0x00) -#define OMAP_USBTLL_SYSCONFIG (0x10) -#define OMAP_USBTLL_SYSCONFIG_CACTIVITY (1 << 8) -#define OMAP_USBTLL_SYSCONFIG_SIDLEMODE (1 << 3) -#define OMAP_USBTLL_SYSCONFIG_ENAWAKEUP (1 << 2) -#define OMAP_USBTLL_SYSCONFIG_SOFTRESET (1 << 1) -#define OMAP_USBTLL_SYSCONFIG_AUTOIDLE (1 << 0) - -#define OMAP_USBTLL_SYSSTATUS (0x14) -#define OMAP_USBTLL_SYSSTATUS_RESETDONE (1 << 0) - -#define OMAP_USBTLL_IRQSTATUS (0x18) -#define OMAP_USBTLL_IRQENABLE (0x1C) - -#define OMAP_TLL_SHARED_CONF (0x30) -#define OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN (1 << 6) -#define OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN (1 << 5) -#define OMAP_TLL_SHARED_CONF_USB_DIVRATION (1 << 2) -#define OMAP_TLL_SHARED_CONF_FCLK_REQ (1 << 1) -#define OMAP_TLL_SHARED_CONF_FCLK_IS_ON (1 << 0) - -#define OMAP_TLL_CHANNEL_CONF(num) (0x040 + 0x004 * num) -#define OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT 24 -#define OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF (1 << 11) -#define OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE (1 << 10) -#define OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE (1 << 9) -#define OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE (1 << 8) -#define OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS (1 << 1) -#define OMAP_TLL_CHANNEL_CONF_CHANEN (1 << 0) - -#define OMAP_TLL_CHANNEL_COUNT 3 - -/* UHH Register Set */ -#define OMAP_UHH_REVISION (0x00) -#define OMAP_UHH_SYSCONFIG (0x10) -#define OMAP_UHH_SYSCONFIG_MIDLEMODE (1 << 12) -#define OMAP_UHH_SYSCONFIG_CACTIVITY (1 << 8) -#define OMAP_UHH_SYSCONFIG_SIDLEMODE (1 << 3) -#define OMAP_UHH_SYSCONFIG_ENAWAKEUP (1 << 2) -#define OMAP_UHH_SYSCONFIG_SOFTRESET (1 << 1) -#define OMAP_UHH_SYSCONFIG_AUTOIDLE (1 << 0) - -#define OMAP_UHH_SYSSTATUS (0x14) -#define OMAP_UHH_SYSSTATUS_UHHRESETDONE (1 << 0) -#define OMAP_UHH_SYSSTATUS_OHCIRESETDONE (1 << 1) -#define OMAP_UHH_SYSSTATUS_EHCIRESETDONE (1 << 2) -#define OMAP_UHH_HOSTCONFIG (0x40) -#define OMAP_UHH_HOSTCONFIG_ULPI_BYPASS (1 << 0) -#define OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS (1 << 0) -#define OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS (1 << 11) -#define OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS (1 << 12) -#define OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN (1 << 2) -#define OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN (1 << 3) -#define OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN (1 << 4) -#define OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN (1 << 5) -#define OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS (1 << 8) -#define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS (1 << 9) -#define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS (1 << 10) - -#define OMAP_UHH_DEBUG_CSR (0x44) - /*-------------------------------------------------------------------------*/ -static inline void ohci_omap_writel(void __iomem *base, u32 reg, u32 val) -{ - __raw_writel(val, base + reg); -} - -static inline u32 ohci_omap_readl(void __iomem *base, u32 reg) -{ - return __raw_readl(base + reg); -} - -static inline void ohci_omap_writeb(void __iomem *base, u8 reg, u8 val) -{ - __raw_writeb(val, base + reg); -} - -static inline u8 ohci_omap_readb(void __iomem *base, u8 reg) -{ - return __raw_readb(base + reg); -} - -/*-------------------------------------------------------------------------*/ - -struct ohci_hcd_omap3 { - struct ohci_hcd *ohci; - struct device *dev; - - struct clk *usbhost_ick; - struct clk *usbhost2_120m_fck; - struct clk *usbhost1_48m_fck; - struct clk *usbtll_fck; - struct clk *usbtll_ick; - - /* port_mode: TLL/PHY, 2/3/4/6-PIN, DP-DM/DAT-SE0 */ - enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS]; - void __iomem *uhh_base; - void __iomem *tll_base; - void __iomem *ohci_base; - - unsigned es2_compatibility:1; -}; - -/*-------------------------------------------------------------------------*/ - -static void ohci_omap3_clock_power(struct ohci_hcd_omap3 *omap, int on) -{ - if (on) { - clk_enable(omap->usbtll_ick); - clk_enable(omap->usbtll_fck); - clk_enable(omap->usbhost_ick); - clk_enable(omap->usbhost1_48m_fck); - clk_enable(omap->usbhost2_120m_fck); - } else { - clk_disable(omap->usbhost2_120m_fck); - clk_disable(omap->usbhost1_48m_fck); - clk_disable(omap->usbhost_ick); - clk_disable(omap->usbtll_fck); - clk_disable(omap->usbtll_ick); - } -} - static int ohci_omap3_init(struct usb_hcd *hcd) { dev_dbg(hcd->self.controller, "starting OHCI controller\n"); @@ -175,7 +41,6 @@ static int ohci_omap3_init(struct usb_hcd *hcd) return ohci_init(hcd_to_ohci(hcd)); } - /*-------------------------------------------------------------------------*/ static int ohci_omap3_start(struct usb_hcd *hcd) @@ -202,325 +67,6 @@ static int ohci_omap3_start(struct usb_hcd *hcd) /*-------------------------------------------------------------------------*/ -/* - * convert the port-mode enum to a value we can use in the FSLSMODE - * field of USBTLL_CHANNEL_CONF - */ -static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode) -{ - switch (mode) { - case OMAP_USBHS_PORT_MODE_UNUSED: - case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: - return 0x0; - - case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM: - return 0x1; - - case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0: - return 0x2; - - case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM: - return 0x3; - - case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0: - return 0x4; - - case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM: - return 0x5; - - case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0: - return 0x6; - - case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM: - return 0x7; - - case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0: - return 0xA; - - case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM: - return 0xB; - default: - pr_warning("Invalid port mode, using default\n"); - return 0x0; - } -} - -static void ohci_omap3_tll_config(struct ohci_hcd_omap3 *omap) -{ - u32 reg; - int i; - - /* Program TLL SHARED CONF */ - reg = ohci_omap_readl(omap->tll_base, OMAP_TLL_SHARED_CONF); - reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN; - reg &= ~OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN; - reg |= OMAP_TLL_SHARED_CONF_USB_DIVRATION; - reg |= OMAP_TLL_SHARED_CONF_FCLK_IS_ON; - ohci_omap_writel(omap->tll_base, OMAP_TLL_SHARED_CONF, reg); - - /* Program each TLL channel */ - /* - * REVISIT: Only the 3-pin and 4-pin PHY modes have - * actually been tested. - */ - for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) { - - /* Enable only those channels that are actually used */ - if (omap->port_mode[i] == OMAP_USBHS_PORT_MODE_UNUSED) - continue; - - reg = ohci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); - reg |= ohci_omap3_fslsmode(omap->port_mode[i]) - << OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT; - reg |= OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS; - reg |= OMAP_TLL_CHANNEL_CONF_CHANEN; - ohci_omap_writel(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i), reg); - } -} - -/* omap3_start_ohci - * - Start the TI USBHOST controller - */ -static int omap3_start_ohci(struct ohci_hcd_omap3 *omap, struct usb_hcd *hcd) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(1000); - u32 reg = 0; - int ret = 0; - - dev_dbg(omap->dev, "starting TI OHCI USB Controller\n"); - - /* Get all the clock handles we need */ - omap->usbhost_ick = clk_get(omap->dev, "usbhost_ick"); - if (IS_ERR(omap->usbhost_ick)) { - dev_err(omap->dev, "could not get usbhost_ick\n"); - ret = PTR_ERR(omap->usbhost_ick); - goto err_host_ick; - } - - omap->usbhost2_120m_fck = clk_get(omap->dev, "usbhost_120m_fck"); - if (IS_ERR(omap->usbhost2_120m_fck)) { - dev_err(omap->dev, "could not get usbhost_120m_fck\n"); - ret = PTR_ERR(omap->usbhost2_120m_fck); - goto err_host_120m_fck; - } - - omap->usbhost1_48m_fck = clk_get(omap->dev, "usbhost_48m_fck"); - if (IS_ERR(omap->usbhost1_48m_fck)) { - dev_err(omap->dev, "could not get usbhost_48m_fck\n"); - ret = PTR_ERR(omap->usbhost1_48m_fck); - goto err_host_48m_fck; - } - - omap->usbtll_fck = clk_get(omap->dev, "usbtll_fck"); - if (IS_ERR(omap->usbtll_fck)) { - dev_err(omap->dev, "could not get usbtll_fck\n"); - ret = PTR_ERR(omap->usbtll_fck); - goto err_tll_fck; - } - - omap->usbtll_ick = clk_get(omap->dev, "usbtll_ick"); - if (IS_ERR(omap->usbtll_ick)) { - dev_err(omap->dev, "could not get usbtll_ick\n"); - ret = PTR_ERR(omap->usbtll_ick); - goto err_tll_ick; - } - - /* Now enable all the clocks in the correct order */ - ohci_omap3_clock_power(omap, 1); - - /* perform TLL soft reset, and wait until reset is complete */ - ohci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, - OMAP_USBTLL_SYSCONFIG_SOFTRESET); - - /* Wait for TLL reset to complete */ - while (!(ohci_omap_readl(omap->tll_base, OMAP_USBTLL_SYSSTATUS) - & OMAP_USBTLL_SYSSTATUS_RESETDONE)) { - cpu_relax(); - - if (time_after(jiffies, timeout)) { - dev_dbg(omap->dev, "operation timed out\n"); - ret = -EINVAL; - goto err_sys_status; - } - } - - dev_dbg(omap->dev, "TLL reset done\n"); - - /* (1<<3) = no idle mode only for initial debugging */ - ohci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, - OMAP_USBTLL_SYSCONFIG_ENAWAKEUP | - OMAP_USBTLL_SYSCONFIG_SIDLEMODE | - OMAP_USBTLL_SYSCONFIG_CACTIVITY); - - - /* Put UHH in NoIdle/NoStandby mode */ - reg = ohci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG); - reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP - | OMAP_UHH_SYSCONFIG_SIDLEMODE - | OMAP_UHH_SYSCONFIG_CACTIVITY - | OMAP_UHH_SYSCONFIG_MIDLEMODE); - reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; - reg &= ~OMAP_UHH_SYSCONFIG_SOFTRESET; - - ohci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); - - reg = ohci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG); - - /* setup ULPI bypass and burst configurations */ - reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN - | OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN - | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN); - reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; - - /* - * REVISIT: Pi_CONNECT_STATUS controls MStandby - * assertion and Swakeup generation - let us not - * worry about this for now. OMAP HWMOD framework - * might take care of this later. If not, we can - * update these registers when adding aggressive - * clock management code. - * - * For now, turn off all the Pi_CONNECT_STATUS bits - * - if (omap->port_mode[0] == OMAP_USBHS_PORT_MODE_UNUSED) - reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; - if (omap->port_mode[1] == OMAP_USBHS_PORT_MODE_UNUSED) - reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; - if (omap->port_mode[2] == OMAP_USBHS_PORT_MODE_UNUSED) - reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; - */ - reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; - reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; - reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; - - if (omap->es2_compatibility) { - /* - * All OHCI modes need to go through the TLL, - * unlike in the EHCI case. So use UTMI mode - * for all ports for OHCI, on ES2.x silicon - */ - dev_dbg(omap->dev, "OMAP3 ES version <= ES2.1\n"); - reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; - } else { - dev_dbg(omap->dev, "OMAP3 ES version > ES2.1\n"); - if (omap->port_mode[0] == OMAP_USBHS_PORT_MODE_UNUSED) - reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; - else - reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; - - if (omap->port_mode[1] == OMAP_USBHS_PORT_MODE_UNUSED) - reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; - else - reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; - - if (omap->port_mode[2] == OMAP_USBHS_PORT_MODE_UNUSED) - reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; - else - reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; - - } - ohci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); - dev_dbg(omap->dev, "UHH setup done, uhh_hostconfig=%x\n", reg); - - ohci_omap3_tll_config(omap); - - return 0; - -err_sys_status: - ohci_omap3_clock_power(omap, 0); - clk_put(omap->usbtll_ick); - -err_tll_ick: - clk_put(omap->usbtll_fck); - -err_tll_fck: - clk_put(omap->usbhost1_48m_fck); - -err_host_48m_fck: - clk_put(omap->usbhost2_120m_fck); - -err_host_120m_fck: - clk_put(omap->usbhost_ick); - -err_host_ick: - return ret; -} - -static void omap3_stop_ohci(struct ohci_hcd_omap3 *omap, struct usb_hcd *hcd) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(100); - - dev_dbg(omap->dev, "stopping TI EHCI USB Controller\n"); - - /* Reset USBHOST for insmod/rmmod to work */ - ohci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, - OMAP_UHH_SYSCONFIG_SOFTRESET); - while (!(ohci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) - & OMAP_UHH_SYSSTATUS_UHHRESETDONE)) { - cpu_relax(); - - if (time_after(jiffies, timeout)) - dev_dbg(omap->dev, "operation timed out\n"); - } - - while (!(ohci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) - & OMAP_UHH_SYSSTATUS_OHCIRESETDONE)) { - cpu_relax(); - - if (time_after(jiffies, timeout)) - dev_dbg(omap->dev, "operation timed out\n"); - } - - while (!(ohci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) - & OMAP_UHH_SYSSTATUS_EHCIRESETDONE)) { - cpu_relax(); - - if (time_after(jiffies, timeout)) - dev_dbg(omap->dev, "operation timed out\n"); - } - - ohci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, (1 << 1)); - - while (!(ohci_omap_readl(omap->tll_base, OMAP_USBTLL_SYSSTATUS) - & (1 << 0))) { - cpu_relax(); - - if (time_after(jiffies, timeout)) - dev_dbg(omap->dev, "operation timed out\n"); - } - - ohci_omap3_clock_power(omap, 0); - - if (omap->usbtll_fck != NULL) { - clk_put(omap->usbtll_fck); - omap->usbtll_fck = NULL; - } - - if (omap->usbhost_ick != NULL) { - clk_put(omap->usbhost_ick); - omap->usbhost_ick = NULL; - } - - if (omap->usbhost1_48m_fck != NULL) { - clk_put(omap->usbhost1_48m_fck); - omap->usbhost1_48m_fck = NULL; - } - - if (omap->usbhost2_120m_fck != NULL) { - clk_put(omap->usbhost2_120m_fck); - omap->usbhost2_120m_fck = NULL; - } - - if (omap->usbtll_ick != NULL) { - clk_put(omap->usbtll_ick); - omap->usbtll_ick = NULL; - } - - dev_dbg(omap->dev, "Clock to USB host has been disabled\n"); -} - -/*-------------------------------------------------------------------------*/ - static const struct hc_driver ohci_omap3_hc_driver = { .description = hcd_name, .product_desc = "OMAP3 OHCI Host Controller", @@ -580,107 +126,77 @@ static const struct hc_driver ohci_omap3_hc_driver = { */ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev) { - struct usbhs_omap_board_data *pdata = pdev->dev.platform_data; - struct ohci_hcd_omap3 *omap; - struct resource *res; - struct usb_hcd *hcd; - int ret = -ENODEV; - int irq; + struct device *dev = &pdev->dev; + struct usb_hcd *hcd = NULL; + void __iomem *regs = NULL; + struct resource *res; + int ret = -ENODEV; + int irq; if (usb_disabled()) - goto err_disabled; + goto err_end; - if (!pdata) { - dev_dbg(&pdev->dev, "missing platform_data\n"); - goto err_pdata; + if (!dev->parent) { + dev_err(dev, "Missing parent device\n"); + return -ENODEV; } - irq = platform_get_irq(pdev, 0); + irq = platform_get_irq_byname(pdev, "ohci-irq"); + if (irq < 0) { + dev_err(dev, "OHCI irq failed\n"); + return -ENODEV; + } - omap = kzalloc(sizeof(*omap), GFP_KERNEL); - if (!omap) { - ret = -ENOMEM; - goto err_disabled; + res = platform_get_resource_byname(pdev, + IORESOURCE_MEM, "ohci"); + if (!ret) { + dev_err(dev, "UHH OHCI get resource failed\n"); + return -ENOMEM; } - hcd = usb_create_hcd(&ohci_omap3_hc_driver, &pdev->dev, - dev_name(&pdev->dev)); - if (!hcd) { - ret = -ENOMEM; - goto err_create_hcd; + regs = ioremap(res->start, resource_size(res)); + if (!regs) { + dev_err(dev, "UHH OHCI ioremap failed\n"); + return -ENOMEM; } - platform_set_drvdata(pdev, omap); - omap->dev = &pdev->dev; - omap->port_mode[0] = pdata->port_mode[0]; - omap->port_mode[1] = pdata->port_mode[1]; - omap->port_mode[2] = pdata->port_mode[2]; - omap->es2_compatibility = pdata->es2_compatibility; - omap->ohci = hcd_to_ohci(hcd); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ohci"); + hcd = usb_create_hcd(&ohci_omap3_hc_driver, dev, + dev_name(dev)); + if (!hcd) { + dev_err(dev, "usb_create_hcd failed\n"); + goto err_io; + } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); + hcd->regs = regs; - hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); - if (!hcd->regs) { - dev_err(&pdev->dev, "OHCI ioremap failed\n"); - ret = -ENOMEM; - goto err_ioremap; - } - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh"); - omap->uhh_base = ioremap(res->start, resource_size(res)); - if (!omap->uhh_base) { - dev_err(&pdev->dev, "UHH ioremap failed\n"); - ret = -ENOMEM; - goto err_uhh_ioremap; - } - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll"); - omap->tll_base = ioremap(res->start, resource_size(res)); - if (!omap->tll_base) { - dev_err(&pdev->dev, "TLL ioremap failed\n"); - ret = -ENOMEM; - goto err_tll_ioremap; - } - - ret = omap3_start_ohci(omap, hcd); + ret = omap_usbhs_enable(dev); if (ret) { - dev_dbg(&pdev->dev, "failed to start ohci\n"); - goto err_start; + dev_dbg(dev, "failed to start ohci\n"); + goto err_end; } - ohci_hcd_init(omap->ohci); + ohci_hcd_init(hcd_to_ohci(hcd)); ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); if (ret) { - dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); + dev_dbg(dev, "failed to add hcd with err %d\n", ret); goto err_add_hcd; } return 0; err_add_hcd: - omap3_stop_ohci(omap, hcd); - -err_start: - iounmap(omap->tll_base); - -err_tll_ioremap: - iounmap(omap->uhh_base); - -err_uhh_ioremap: - iounmap(hcd->regs); + omap_usbhs_disable(dev); -err_ioremap: +err_end: usb_put_hcd(hcd); -err_create_hcd: - kfree(omap); -err_pdata: -err_disabled: +err_io: + iounmap(regs); + return ret; } @@ -699,24 +215,20 @@ err_disabled: */ static int __devexit ohci_hcd_omap3_remove(struct platform_device *pdev) { - struct ohci_hcd_omap3 *omap = platform_get_drvdata(pdev); - struct usb_hcd *hcd = ohci_to_hcd(omap->ohci); + struct device *dev = &pdev->dev; + struct usb_hcd *hcd = dev_get_drvdata(dev); - usb_remove_hcd(hcd); - omap3_stop_ohci(omap, hcd); iounmap(hcd->regs); - iounmap(omap->tll_base); - iounmap(omap->uhh_base); + usb_remove_hcd(hcd); + omap_usbhs_disable(dev); usb_put_hcd(hcd); - kfree(omap); return 0; } static void ohci_hcd_omap3_shutdown(struct platform_device *pdev) { - struct ohci_hcd_omap3 *omap = platform_get_drvdata(pdev); - struct usb_hcd *hcd = ohci_to_hcd(omap->ohci); + struct usb_hcd *hcd = dev_get_drvdata(&pdev->dev); if (hcd->driver->shutdown) hcd->driver->shutdown(hcd); -- cgit v1.2.3 From d714d1979d7b4df7e2c127407f4014ce71f73cd0 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 22 Feb 2011 20:22:44 -0700 Subject: dt: eliminate of_platform_driver shim code Commit eca393016, "of: Merge of_platform_bus_type with platform_bus_type" added a shim to allow of_platform_drivers to get registers onto the platform bus so that there was time to migrate the existing drivers to the platform_bus_type. This patch removes the shim since there are no more users of the old interface. Signed-off-by: Grant Likely --- drivers/of/platform.c | 68 --------------------------------------------- include/linux/of_platform.h | 12 +------- 2 files changed, 1 insertion(+), 79 deletions(-) (limited to 'drivers') diff --git a/drivers/of/platform.c b/drivers/of/platform.c index b71d0cdc4209..1ce4c45c4ab2 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -42,74 +42,6 @@ struct platform_device *of_find_device_by_node(struct device_node *np) } EXPORT_SYMBOL(of_find_device_by_node); -static int platform_driver_probe_shim(struct platform_device *pdev) -{ - struct platform_driver *pdrv; - struct of_platform_driver *ofpdrv; - const struct of_device_id *match; - - pdrv = container_of(pdev->dev.driver, struct platform_driver, driver); - ofpdrv = container_of(pdrv, struct of_platform_driver, platform_driver); - - /* There is an unlikely chance that an of_platform driver might match - * on a non-OF platform device. If so, then of_match_device() will - * come up empty. Return -EINVAL in this case so other drivers get - * the chance to bind. */ - match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev); - return match ? ofpdrv->probe(pdev, match) : -EINVAL; -} - -static void platform_driver_shutdown_shim(struct platform_device *pdev) -{ - struct platform_driver *pdrv; - struct of_platform_driver *ofpdrv; - - pdrv = container_of(pdev->dev.driver, struct platform_driver, driver); - ofpdrv = container_of(pdrv, struct of_platform_driver, platform_driver); - ofpdrv->shutdown(pdev); -} - -/** - * of_register_platform_driver - */ -int of_register_platform_driver(struct of_platform_driver *drv) -{ - char *of_name; - - /* setup of_platform_driver to platform_driver adaptors */ - drv->platform_driver.driver = drv->driver; - - /* Prefix the driver name with 'of:' to avoid namespace collisions - * and bogus matches. There are some drivers in the tree that - * register both an of_platform_driver and a platform_driver with - * the same name. This is a temporary measure until they are all - * cleaned up --gcl July 29, 2010 */ - of_name = kmalloc(strlen(drv->driver.name) + 5, GFP_KERNEL); - if (!of_name) - return -ENOMEM; - sprintf(of_name, "of:%s", drv->driver.name); - drv->platform_driver.driver.name = of_name; - - if (drv->probe) - drv->platform_driver.probe = platform_driver_probe_shim; - drv->platform_driver.remove = drv->remove; - if (drv->shutdown) - drv->platform_driver.shutdown = platform_driver_shutdown_shim; - drv->platform_driver.suspend = drv->suspend; - drv->platform_driver.resume = drv->resume; - - return platform_driver_register(&drv->platform_driver); -} -EXPORT_SYMBOL(of_register_platform_driver); - -void of_unregister_platform_driver(struct of_platform_driver *drv) -{ - platform_driver_unregister(&drv->platform_driver); - kfree(drv->platform_driver.driver.name); - drv->platform_driver.driver.name = NULL; -} -EXPORT_SYMBOL(of_unregister_platform_driver); - #if defined(CONFIG_PPC_DCR) #include #endif diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index 048949fa1d10..17c7e21c0bd7 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -23,13 +23,7 @@ * of_platform_driver - Legacy of-aware driver for platform devices. * * An of_platform_driver driver is attached to a basic platform_device on - * ether the "platform bus" (platform_bus_type), or the ibm ebus - * (ibmebus_bus_type). - * - * of_platform_driver is being phased out when used with the platform_bus_type, - * and regular platform_drivers should be used instead. When the transition - * is complete, only ibmebus will be using this structure, and the - * platform_driver member of this structure will be removed. + * the ibm ebus (ibmebus_bus_type). */ struct of_platform_driver { @@ -42,15 +36,11 @@ struct of_platform_driver int (*shutdown)(struct platform_device* dev); struct device_driver driver; - struct platform_driver platform_driver; }; #define to_of_platform_driver(drv) \ container_of(drv,struct of_platform_driver, driver) /* Platform drivers register/unregister */ -extern int of_register_platform_driver(struct of_platform_driver *drv); -extern void of_unregister_platform_driver(struct of_platform_driver *drv); - extern struct platform_device *of_device_alloc(struct device_node *np, const char *bus_id, struct device *parent); -- cgit v1.2.3 From 7c9325d79a3c3d51c98812161d47876d6830c062 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 18 Feb 2011 11:35:32 +0100 Subject: tty: serial: altera_uart: Add devicetree support With the recent switch of the (currently still out-of-tree) Nios2 Linux port to devicetree we want to be able to retrieve the resources and properties from dts. The old method to retrieve resources and properties from platform data is still supported. Signed-off-by: Tobias Klauser Acked-by: Greg Kroah-Hartman Signed-off-by: Grant Likely --- .../devicetree/bindings/serial/altera_uart.txt | 7 +++ drivers/tty/serial/altera_uart.c | 51 ++++++++++++++++++++-- 2 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 Documentation/devicetree/bindings/serial/altera_uart.txt (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/serial/altera_uart.txt b/Documentation/devicetree/bindings/serial/altera_uart.txt new file mode 100644 index 000000000000..71cae3f70100 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/altera_uart.txt @@ -0,0 +1,7 @@ +Altera UART + +Required properties: +- compatible : should be "ALTR,uart-1.0" + +Optional properties: +- clock-frequency : frequency of the clock input to the UART diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 721216292a50..1803c37d58ab 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -511,6 +512,29 @@ static struct uart_driver altera_uart_driver = { .cons = ALTERA_UART_CONSOLE, }; +#ifdef CONFIG_OF +static int altera_uart_get_of_uartclk(struct platform_device *pdev, + struct uart_port *port) +{ + int len; + const __be32 *clk; + + clk = of_get_property(pdev->dev.of_node, "clock-frequency", &len); + if (!clk || len < sizeof(__be32)) + return -ENODEV; + + port->uartclk = be32_to_cpup(clk); + + return 0; +} +#else +static int altera_uart_get_of_uartclk(struct platform_device *pdev, + struct uart_port *port) +{ + return -ENODEV; +} +#endif /* CONFIG_OF */ + static int __devinit altera_uart_probe(struct platform_device *pdev) { struct altera_uart_platform_uart *platp = pdev->dev.platform_data; @@ -518,6 +542,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) struct resource *res_mem; struct resource *res_irq; int i = pdev->id; + int ret; /* -1 emphasizes that the platform must have one port, no .N suffix */ if (i == -1) @@ -542,6 +567,15 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) else if (platp->irq) port->irq = platp->irq; + /* Check platform data first so we can override device node data */ + if (platp) + port->uartclk = platp->uartclk; + else { + ret = altera_uart_get_of_uartclk(pdev, port); + if (ret) + return ret; + } + port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE); if (!port->membase) return -ENOMEM; @@ -549,7 +583,6 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) port->line = i; port->type = PORT_ALTERA_UART; port->iotype = SERIAL_IO_MEM; - port->uartclk = platp->uartclk; port->ops = &altera_uart_ops; port->flags = UPF_BOOT_AUTOCONF; port->private_data = platp; @@ -567,13 +600,23 @@ static int __devexit altera_uart_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_OF +static struct of_device_id altera_uart_match[] = { + { .compatible = "ALTR,uart-1.0", }, + {}, +}; +MODULE_DEVICE_TABLE(of, altera_uart_match); +#else +#define altera_uart_match NULL +#endif /* CONFIG_OF */ + static struct platform_driver altera_uart_platform_driver = { .probe = altera_uart_probe, .remove = __devexit_p(altera_uart_remove), .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - .pm = NULL, + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = altera_uart_match, }, }; -- cgit v1.2.3 From 9f15444fefdb33509132ff5c9be60cb315c44cb2 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 18 Feb 2011 09:10:01 +0100 Subject: tty: serial: altera_jtaguart: Add device tree support Advertise the possibility to use this driver with device tree if CONFIG_OF is set. Signed-off-by: Tobias Klauser Signed-off-by: Grant Likely --- .../devicetree/bindings/serial/altera_jtaguart.txt | 4 ++++ drivers/tty/serial/altera_jtaguart.c | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/serial/altera_jtaguart.txt (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/serial/altera_jtaguart.txt b/Documentation/devicetree/bindings/serial/altera_jtaguart.txt new file mode 100644 index 000000000000..c152f65f9a28 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/altera_jtaguart.txt @@ -0,0 +1,4 @@ +Altera JTAG UART + +Required properties: +- compatible : should be "ALTR,juart-1.0" diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index f9b49b5ff5e1..a20927fc3e1a 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -465,12 +465,23 @@ static int __devexit altera_jtaguart_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_OF +static struct of_device_id altera_jtaguart_match[] = { + { .compatible = "ALTR,juart-1.0", }, + {}, +}; +MODULE_DEVICE_TABLE(of, altera_jtaguart_match); +#else +#define altera_jtaguart_match NULL +#endif /* CONFIG_OF */ + static struct platform_driver altera_jtaguart_platform_driver = { .probe = altera_jtaguart_probe, .remove = __devexit_p(altera_jtaguart_remove), .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = altera_jtaguart_match, }, }; -- cgit v1.2.3 From 716b50a31fb237c480e67ad66dc23feb35d40772 Mon Sep 17 00:00:00 2001 From: Hayes Wang Date: Tue, 22 Feb 2011 17:26:18 +0800 Subject: r8169: adjust rtl8169_set_speed_xmii function. - adjust code of rtl8169_set_speed_xmii function - remove parts of code which are done in rtl_pll_power_up function (8168 only) Signed-off-by: Hayes Wang Acked-by: Francois Romieu --- drivers/net/r8169.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 469ab0b7ce31..de94489cf96e 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1124,6 +1124,8 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, struct rtl8169_private *tp = netdev_priv(dev); int giga_ctrl, bmcr; + rtl_writephy(tp, 0x1f, 0x0000); + if (autoneg == AUTONEG_ENABLE) { int auto_nego; @@ -1152,18 +1154,6 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, bmcr = BMCR_ANENABLE | BMCR_ANRESTART; - if ((tp->mac_version == RTL_GIGA_MAC_VER_11) || - (tp->mac_version == RTL_GIGA_MAC_VER_12) || - (tp->mac_version >= RTL_GIGA_MAC_VER_17)) { - /* - * Wake up the PHY. - * Vendor specific (0x1f) and reserved (0x0e) MII - * registers. - */ - rtl_writephy(tp, 0x1f, 0x0000); - rtl_writephy(tp, 0x0e, 0x0000); - } - rtl_writephy(tp, MII_ADVERTISE, auto_nego); rtl_writephy(tp, MII_CTRL1000, giga_ctrl); } else { @@ -1178,8 +1168,6 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, if (duplex == DUPLEX_FULL) bmcr |= BMCR_FULLDPLX; - - rtl_writephy(tp, 0x1f, 0x0000); } tp->phy_1000_ctrl_reg = giga_ctrl; -- cgit v1.2.3 From e7a2a4f5e61ccfae03185384e06b852dbb1e3630 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Sun, 27 Feb 2011 09:20:40 +0530 Subject: ath9k_htc: Handle BSSID/AID for multiple interfaces The AID and BSSID should be set in the HW only for the first station interface or adhoc interface. Also, cancel the ANI timer in stop() for multi-STA scenario. And finally configure the HW beacon timers only for the first station interface. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 1 + drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 58 ++++++++++++++++++++++--- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 42 ++++++++++++------ 3 files changed, 81 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index e9c51cae88ab..753a245c5ad1 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -243,6 +243,7 @@ struct ath9k_htc_target_stats { struct ath9k_htc_vif { u8 index; u16 seq_no; + bool beacon_configured; }; struct ath9k_vif_iter_data { diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 007b99fc50c8..8d1d8792436d 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -123,8 +123,9 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, /* TSF out of range threshold fixed at 1 second */ bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD; - ath_dbg(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu); - ath_dbg(common, ATH_DBG_BEACON, + ath_dbg(common, ATH_DBG_CONFIG, "intval: %u tsf: %llu tsftu: %u\n", + intval, tsf, tsftu); + ath_dbg(common, ATH_DBG_CONFIG, "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n", bs.bs_bmissthreshold, bs.bs_sleepduration, bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext); @@ -309,12 +310,23 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) } } -void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, - struct ieee80211_vif *vif) +static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif) +{ + bool *beacon_configured = (bool *)data; + struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv; + + if (vif->type == NL80211_IFTYPE_STATION && + avp->beacon_configured) + *beacon_configured = true; +} + +static bool ath9k_htc_check_beacon_config(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif) { struct ath_common *common = ath9k_hw_common(priv->ah); struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf; struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + bool beacon_configured; /* * Changing the beacon interval when multiple AP interfaces @@ -327,7 +339,7 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, (cur_conf->beacon_interval != bss_conf->beacon_int)) { ath_dbg(common, ATH_DBG_CONFIG, "Changing beacon interval of multiple AP interfaces !\n"); - return; + return false; } /* @@ -338,9 +350,42 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, (vif->type != NL80211_IFTYPE_AP)) { ath_dbg(common, ATH_DBG_CONFIG, "HW in AP mode, cannot set STA beacon parameters\n"); - return; + return false; + } + + /* + * The beacon parameters are configured only for the first + * station interface. + */ + if ((priv->ah->opmode == NL80211_IFTYPE_STATION) && + (priv->num_sta_vif > 1) && + (vif->type == NL80211_IFTYPE_STATION)) { + beacon_configured = false; + ieee80211_iterate_active_interfaces_atomic(priv->hw, + ath9k_htc_beacon_iter, + &beacon_configured); + + if (beacon_configured) { + ath_dbg(common, ATH_DBG_CONFIG, + "Beacon already configured for a station interface\n"); + return false; + } } + return true; +} + +void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, + struct ieee80211_vif *vif) +{ + struct ath_common *common = ath9k_hw_common(priv->ah); + struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf; + struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv; + + if (!ath9k_htc_check_beacon_config(priv, vif)) + return; + cur_conf->beacon_interval = bss_conf->beacon_int; if (cur_conf->beacon_interval == 0) cur_conf->beacon_interval = 100; @@ -352,6 +397,7 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, switch (vif->type) { case NL80211_IFTYPE_STATION: ath9k_htc_beacon_config_sta(priv, cur_conf); + avp->beacon_configured = true; break; case NL80211_IFTYPE_ADHOC: ath9k_htc_beacon_config_adhoc(priv, cur_conf); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 71adab34006c..db8c0c044e9e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1601,30 +1601,44 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, struct ath9k_htc_priv *priv = hw->priv; struct ath_hw *ah = priv->ah; struct ath_common *common = ath9k_hw_common(ah); + bool set_assoc; mutex_lock(&priv->mutex); ath9k_htc_ps_wakeup(priv); + /* + * Set the HW AID/BSSID only for the first station interface + * or in IBSS mode. + */ + set_assoc = !!((priv->ah->opmode == NL80211_IFTYPE_ADHOC) || + ((priv->ah->opmode == NL80211_IFTYPE_STATION) && + (priv->num_sta_vif == 1))); + + if (changed & BSS_CHANGED_ASSOC) { - common->curaid = bss_conf->assoc ? - bss_conf->aid : 0; - ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", - bss_conf->assoc); + if (set_assoc) { + ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", + bss_conf->assoc); - if (bss_conf->assoc) - ath9k_htc_start_ani(priv); - else - ath9k_htc_stop_ani(priv); + common->curaid = bss_conf->assoc ? + bss_conf->aid : 0; + + if (bss_conf->assoc) + ath9k_htc_start_ani(priv); + else + ath9k_htc_stop_ani(priv); + } } if (changed & BSS_CHANGED_BSSID) { - /* Set BSSID */ - memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); - ath9k_hw_write_associd(ah); + if (set_assoc) { + memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); + ath9k_hw_write_associd(ah); - ath_dbg(common, ATH_DBG_CONFIG, - "BSSID: %pM aid: 0x%x\n", - common->curbssid, common->curaid); + ath_dbg(common, ATH_DBG_CONFIG, + "BSSID: %pM aid: 0x%x\n", + common->curbssid, common->curaid); + } } if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) { -- cgit v1.2.3 From 375ff4c7780e88bc4e0de4145099a7ed9aa57995 Mon Sep 17 00:00:00 2001 From: Chaoming Li Date: Mon, 28 Feb 2011 16:40:28 -0600 Subject: rtlwifi: Fix error registering rate-control When a second module such as rtl8192ce or rtl8192cu links to rtlwifi, the attempt to register a rate-control mechanism fails with the warning shown below. The fix is to select the RC mechanism when rtlwifi is initialized. WARNING: at net/mac80211/rate.c:42 ieee80211_rate_control_register+0xc9/0x100 [mac80211]() Hardware name: HP Pavilion dv2700 Notebook PC Modules linked in: arc4 ecb rtl8192ce rtl8192cu(+) rtl8192c_common rtlwifi snd_hda_codec_conexant amd74xx(+) ide_core sg mac80211 snd_hda_intel snd_hda_codec i2c_nforce2 snd_pcm snd_timer cfg80211 snd k8temp hwmon serio_raw joydev i2c_core soundcore snd_page_alloc rfkill forcedeth video ac battery button ext3 jbd mbcache sd_mod ohci_hcd ahci libahci libata scsi_mod ehci_hcd usbcore fan processor thermal Pid: 2227, comm: modprobe Not tainted 2.6.38-rc6-wl+ #468 Call Trace: [] ? warn_slowpath_common+0x7a/0xb0 [] ? warn_slowpath_null+0x15/0x20 [] ? ieee80211_rate_control_register+0xc9/0x100 [mac80211] [] ? rtl_rate_control_register+0x10/0x20 [rtlwifi] [] ? rtl_init_core+0x189/0x620 [rtlwifi] [] ? __raw_spin_lock_init+0x38/0x70 [] ? rtl_usb_probe+0x709/0x82e [rtlwifi] [] ? usb_match_one_id+0x3d/0xc0 [usbcore] [] ? usb_probe_interface+0xb9/0x160 [usbcore] [] ? driver_probe_device+0x89/0x1a0 [] ? __driver_attach+0xa3/0xb0 [] ? __driver_attach+0x0/0xb0 [] ? bus_for_each_dev+0x5e/0x90 [] ? driver_attach+0x19/0x20 [] ? bus_add_driver+0x158/0x290 [] ? driver_register+0x71/0x140 [] ? __raw_spin_lock_init+0x38/0x70 [] ? usb_register_driver+0xdc/0x190 [usbcore] [] ? rtl8192cu_init+0x0/0x20 [rtl8192cu] [] ? rtl8192cu_init+0x1e/0x20 [rtl8192cu] [] ? do_one_initcall+0x3f/0x180 [] ? sys_init_module+0xbb/0x200 [] ? system_call_fastpath+0x16/0x1b ---[ end trace 726271c07a47439e ]--- rtlwifi:rtl_init_core():<0-0> rtl: Unable to register rtl_rc,use default RC !! ieee80211 phy0: Selected rate control algorithm 'minstrel_ht' Signed-off-by: Chaoming Li Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 3f40dc2b129c..bb0c781f4a1b 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -283,13 +283,7 @@ int rtl_init_core(struct ieee80211_hw *hw) rtlmac->hw = hw; /* <2> rate control register */ - if (rtl_rate_control_register()) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("rtl: Unable to register rtl_rc," - "use default RC !!\n")); - } else { - hw->rate_control_algorithm = "rtl_rc"; - } + hw->rate_control_algorithm = "rtl_rc"; /* * <3> init CRDA must come after init @@ -325,8 +319,6 @@ int rtl_init_core(struct ieee80211_hw *hw) void rtl_deinit_core(struct ieee80211_hw *hw) { - /*RC*/ - rtl_rate_control_unregister(); } void rtl_init_rx_config(struct ieee80211_hw *hw) @@ -945,11 +937,16 @@ MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core"); static int __init rtl_core_module_init(void) { + if (rtl_rate_control_register()) + printk(KERN_ERR "rtlwifi: Unable to register rtl_rc," + "use default RC !!\n"); return 0; } static void __exit rtl_core_module_exit(void) { + /*RC*/ + rtl_rate_control_unregister(); } module_init(rtl_core_module_init); -- cgit v1.2.3 From 27b4eb26cd06df0192781b0615719b324e30d1cd Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 1 Mar 2011 13:28:36 +0100 Subject: b43: N-PHY: rev3+: add static tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This finally makes TX on OFDM rates possible on my dev with PHY rev 4. We still have lower performance than wl, but at least speeds around 15M become possible. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/tables_nphy.c | 1106 +++++++++++++++++++++++++++++++- drivers/net/wireless/b43/tables_nphy.h | 27 + 2 files changed, 1131 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index dc8ef09a8552..c42b2acea24e 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -1097,6 +1097,1080 @@ static const u32 b43_ntab_tmap[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, }; +/* static tables, PHY revision >= 3 */ +static const u32 b43_ntab_framestruct_r3[] = { + 0x08004a04, 0x00100000, 0x01000a05, 0x00100020, + 0x09804506, 0x00100030, 0x09804507, 0x00100030, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x08004a0c, 0x00100004, 0x01000a0d, 0x00100024, + 0x0980450e, 0x00100034, 0x0980450f, 0x00100034, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000a04, 0x00100000, 0x11008a05, 0x00100020, + 0x1980c506, 0x00100030, 0x21810506, 0x00100030, + 0x21810506, 0x00100030, 0x01800504, 0x00100030, + 0x11808505, 0x00100030, 0x29814507, 0x01100030, + 0x00000a04, 0x00100000, 0x11008a05, 0x00100020, + 0x21810506, 0x00100030, 0x21810506, 0x00100030, + 0x29814507, 0x01100030, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000a0c, 0x00100008, 0x11008a0d, 0x00100028, + 0x1980c50e, 0x00100038, 0x2181050e, 0x00100038, + 0x2181050e, 0x00100038, 0x0180050c, 0x00100038, + 0x1180850d, 0x00100038, 0x2981450f, 0x01100038, + 0x00000a0c, 0x00100008, 0x11008a0d, 0x00100028, + 0x2181050e, 0x00100038, 0x2181050e, 0x00100038, + 0x2981450f, 0x01100038, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x08004a04, 0x00100000, 0x01000a05, 0x00100020, + 0x1980c506, 0x00100030, 0x1980c506, 0x00100030, + 0x11808504, 0x00100030, 0x3981ca05, 0x00100030, + 0x29814507, 0x01100030, 0x00000000, 0x00000000, + 0x10008a04, 0x00100000, 0x3981ca05, 0x00100030, + 0x1980c506, 0x00100030, 0x29814507, 0x01100030, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x08004a0c, 0x00100008, 0x01000a0d, 0x00100028, + 0x1980c50e, 0x00100038, 0x1980c50e, 0x00100038, + 0x1180850c, 0x00100038, 0x3981ca0d, 0x00100038, + 0x2981450f, 0x01100038, 0x00000000, 0x00000000, + 0x10008a0c, 0x00100008, 0x3981ca0d, 0x00100038, + 0x1980c50e, 0x00100038, 0x2981450f, 0x01100038, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x40021404, 0x00100000, 0x02001405, 0x00100040, + 0x0b004a06, 0x01900060, 0x13008a06, 0x01900060, + 0x13008a06, 0x01900060, 0x43020a04, 0x00100060, + 0x1b00ca05, 0x00100060, 0x23010a07, 0x01500060, + 0x40021404, 0x00100000, 0x1a00d405, 0x00100040, + 0x13008a06, 0x01900060, 0x13008a06, 0x01900060, + 0x23010a07, 0x01500060, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x4002140c, 0x00100010, 0x0200140d, 0x00100050, + 0x0b004a0e, 0x01900070, 0x13008a0e, 0x01900070, + 0x13008a0e, 0x01900070, 0x43020a0c, 0x00100070, + 0x1b00ca0d, 0x00100070, 0x23010a0f, 0x01500070, + 0x4002140c, 0x00100010, 0x1a00d40d, 0x00100050, + 0x13008a0e, 0x01900070, 0x13008a0e, 0x01900070, + 0x23010a0f, 0x01500070, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x50029404, 0x00100000, 0x32019405, 0x00100040, + 0x0b004a06, 0x01900060, 0x0b004a06, 0x01900060, + 0x5b02ca04, 0x00100060, 0x3b01d405, 0x00100060, + 0x23010a07, 0x01500060, 0x00000000, 0x00000000, + 0x5802d404, 0x00100000, 0x3b01d405, 0x00100060, + 0x0b004a06, 0x01900060, 0x23010a07, 0x01500060, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x5002940c, 0x00100010, 0x3201940d, 0x00100050, + 0x0b004a0e, 0x01900070, 0x0b004a0e, 0x01900070, + 0x5b02ca0c, 0x00100070, 0x3b01d40d, 0x00100070, + 0x23010a0f, 0x01500070, 0x00000000, 0x00000000, + 0x5802d40c, 0x00100010, 0x3b01d40d, 0x00100070, + 0x0b004a0e, 0x01900070, 0x23010a0f, 0x01500070, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x40021404, 0x000f4800, 0x62031405, 0x00100040, + 0x53028a06, 0x01900060, 0x53028a07, 0x01900060, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x4002140c, 0x000f4808, 0x6203140d, 0x00100048, + 0x53028a0e, 0x01900068, 0x53028a0f, 0x01900068, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000a0c, 0x00100004, 0x11008a0d, 0x00100024, + 0x1980c50e, 0x00100034, 0x2181050e, 0x00100034, + 0x2181050e, 0x00100034, 0x0180050c, 0x00100038, + 0x1180850d, 0x00100038, 0x1181850d, 0x00100038, + 0x2981450f, 0x01100038, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000a0c, 0x00100008, 0x11008a0d, 0x00100028, + 0x2181050e, 0x00100038, 0x2181050e, 0x00100038, + 0x1181850d, 0x00100038, 0x2981450f, 0x01100038, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x08004a04, 0x00100000, 0x01000a05, 0x00100020, + 0x0180c506, 0x00100030, 0x0180c506, 0x00100030, + 0x2180c50c, 0x00100030, 0x49820a0d, 0x0016a130, + 0x41824a0d, 0x0016a130, 0x2981450f, 0x01100030, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x2000ca0c, 0x00100000, 0x49820a0d, 0x0016a130, + 0x1980c50e, 0x00100030, 0x41824a0d, 0x0016a130, + 0x2981450f, 0x01100030, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x4002140c, 0x00100008, 0x0200140d, 0x00100048, + 0x0b004a0e, 0x01900068, 0x13008a0e, 0x01900068, + 0x13008a0e, 0x01900068, 0x43020a0c, 0x00100070, + 0x1b00ca0d, 0x00100070, 0x1b014a0d, 0x00100070, + 0x23010a0f, 0x01500070, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x4002140c, 0x00100010, 0x1a00d40d, 0x00100050, + 0x13008a0e, 0x01900070, 0x13008a0e, 0x01900070, + 0x1b014a0d, 0x00100070, 0x23010a0f, 0x01500070, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x50029404, 0x00100000, 0x32019405, 0x00100040, + 0x03004a06, 0x01900060, 0x03004a06, 0x01900060, + 0x6b030a0c, 0x00100060, 0x4b02140d, 0x0016a160, + 0x4302540d, 0x0016a160, 0x23010a0f, 0x01500060, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x6b03140c, 0x00100060, 0x4b02140d, 0x0016a160, + 0x0b004a0e, 0x01900060, 0x4302540d, 0x0016a160, + 0x23010a0f, 0x01500060, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x40021404, 0x00100000, 0x1a00d405, 0x00100040, + 0x53028a06, 0x01900060, 0x5b02ca06, 0x01900060, + 0x5b02ca06, 0x01900060, 0x43020a04, 0x00100060, + 0x1b00ca05, 0x00100060, 0x53028a07, 0x0190c060, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x4002140c, 0x00100010, 0x1a00d40d, 0x00100050, + 0x53028a0e, 0x01900070, 0x5b02ca0e, 0x01900070, + 0x5b02ca0e, 0x01900070, 0x43020a0c, 0x00100070, + 0x1b00ca0d, 0x00100070, 0x53028a0f, 0x0190c070, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x40021404, 0x00100000, 0x1a00d405, 0x00100040, + 0x5b02ca06, 0x01900060, 0x5b02ca06, 0x01900060, + 0x53028a07, 0x0190c060, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x4002140c, 0x00100010, 0x1a00d40d, 0x00100050, + 0x5b02ca0e, 0x01900070, 0x5b02ca0e, 0x01900070, + 0x53028a0f, 0x0190c070, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static const u16 b43_ntab_pilot_r3[] = { + 0xff08, 0xff08, 0xff08, 0xff08, 0xff08, 0xff08, + 0xff08, 0xff08, 0x80d5, 0x80d5, 0x80d5, 0x80d5, + 0x80d5, 0x80d5, 0x80d5, 0x80d5, 0xff0a, 0xff82, + 0xffa0, 0xff28, 0xffff, 0xffff, 0xffff, 0xffff, + 0xff82, 0xffa0, 0xff28, 0xff0a, 0xffff, 0xffff, + 0xffff, 0xffff, 0xf83f, 0xfa1f, 0xfa97, 0xfab5, + 0xf2bd, 0xf0bf, 0xffff, 0xffff, 0xf017, 0xf815, + 0xf215, 0xf095, 0xf035, 0xf01d, 0xffff, 0xffff, + 0xff08, 0xff02, 0xff80, 0xff20, 0xff08, 0xff02, + 0xff80, 0xff20, 0xf01f, 0xf817, 0xfa15, 0xf295, + 0xf0b5, 0xf03d, 0xffff, 0xffff, 0xf82a, 0xfa0a, + 0xfa82, 0xfaa0, 0xf2a8, 0xf0aa, 0xffff, 0xffff, + 0xf002, 0xf800, 0xf200, 0xf080, 0xf020, 0xf008, + 0xffff, 0xffff, 0xf00a, 0xf802, 0xfa00, 0xf280, + 0xf0a0, 0xf028, 0xffff, 0xffff, +}; + +static const u32 b43_ntab_tmap_r3[] = { + 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888, + 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8, + 0xf1111110, 0x11111111, 0x11f11111, 0x00000111, + 0x11000000, 0x1111f111, 0x11111111, 0x111111f1, + 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x000aa888, + 0x88880000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8, + 0xa1111110, 0x11111111, 0x11c11111, 0x00000111, + 0x11000000, 0x1111a111, 0x11111111, 0x111111a1, + 0xa2222220, 0x22222222, 0x22c22222, 0x00000222, + 0x22000000, 0x2222a222, 0x22222222, 0x222222a2, + 0xf1111110, 0x11111111, 0x11f11111, 0x00011111, + 0x11110000, 0x1111f111, 0x11111111, 0x111111f1, + 0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00088aaa, + 0xaaaa0000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a, + 0xaaa8aaa0, 0x8aaa8aaa, 0xaa8a8a8a, 0x000aaa88, + 0x8aaa0000, 0xaaa8a888, 0x8aa88a8a, 0x8a88a888, + 0x08080a00, 0x0a08080a, 0x080a0a08, 0x00080808, + 0x080a0000, 0x080a0808, 0x080a0808, 0x0a0a0a08, + 0xa0a0a0a0, 0x80a0a080, 0x8080a0a0, 0x00008080, + 0x80a00000, 0x80a080a0, 0xa080a0a0, 0x8080a0a0, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x99999000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9, + 0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999, + 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8, + 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888, + 0x22000000, 0x2222b222, 0x22222222, 0x222222b2, + 0xb2222220, 0x22222222, 0x22d22222, 0x00000222, + 0x11000000, 0x1111a111, 0x11111111, 0x111111a1, + 0xa1111110, 0x11111111, 0x11c11111, 0x00000111, + 0x33000000, 0x3333b333, 0x33333333, 0x333333b3, + 0xb3333330, 0x33333333, 0x33d33333, 0x00000333, + 0x22000000, 0x2222a222, 0x22222222, 0x222222a2, + 0xa2222220, 0x22222222, 0x22c22222, 0x00000222, + 0x99b99b00, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9, + 0x9b99bb99, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999, + 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8, + 0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888, + 0x22222200, 0x2222f222, 0x22222222, 0x222222f2, + 0x22222222, 0x22222222, 0x22f22222, 0x00000222, + 0x11000000, 0x1111f111, 0x11111111, 0x11111111, + 0xf1111111, 0x11111111, 0x11f11111, 0x01111111, + 0xbb9bb900, 0xb9b9bb99, 0xb99bbbbb, 0xbbbb9b9b, + 0xb9bb99bb, 0xb99999b9, 0xb9b9b99b, 0x00000bbb, + 0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a, + 0xa8aa88aa, 0xa88888a8, 0xa8a8a88a, 0x0a888aaa, + 0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a, + 0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00000aaa, + 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8, + 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888, + 0xbbbbbb00, 0x999bbbbb, 0x9bb99b9b, 0xb9b9b9bb, + 0xb9b99bbb, 0xb9b9b9bb, 0xb9bb9b99, 0x00000999, + 0x8a000000, 0xaa88a888, 0xa88888aa, 0xa88a8a88, + 0xa88aa88a, 0x88a8aaaa, 0xa8aa8aaa, 0x0888a88a, + 0x0b0b0b00, 0x090b0b0b, 0x0b090b0b, 0x0909090b, + 0x09090b0b, 0x09090b0b, 0x09090b09, 0x00000909, + 0x0a000000, 0x0a080808, 0x080a080a, 0x080a0a08, + 0x080a080a, 0x0808080a, 0x0a0a0a08, 0x0808080a, + 0xb0b0b000, 0x9090b0b0, 0x90b09090, 0xb0b0b090, + 0xb0b090b0, 0x90b0b0b0, 0xb0b09090, 0x00000090, + 0x80000000, 0xa080a080, 0xa08080a0, 0xa0808080, + 0xa080a080, 0x80a0a0a0, 0xa0a080a0, 0x00a0a0a0, + 0x22000000, 0x2222f222, 0x22222222, 0x222222f2, + 0xf2222220, 0x22222222, 0x22f22222, 0x00000222, + 0x11000000, 0x1111f111, 0x11111111, 0x111111f1, + 0xf1111110, 0x11111111, 0x11f11111, 0x00000111, + 0x33000000, 0x3333f333, 0x33333333, 0x333333f3, + 0xf3333330, 0x33333333, 0x33f33333, 0x00000333, + 0x22000000, 0x2222f222, 0x22222222, 0x222222f2, + 0xf2222220, 0x22222222, 0x22f22222, 0x00000222, + 0x99000000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9, + 0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999, + 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8, + 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888, + 0x88888000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8, + 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888, + 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8, + 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888, + 0x88a88a00, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8, + 0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888, + 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8, + 0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888, + 0x11000000, 0x1111a111, 0x11111111, 0x111111a1, + 0xa1111110, 0x11111111, 0x11c11111, 0x00000111, + 0x11000000, 0x1111a111, 0x11111111, 0x111111a1, + 0xa1111110, 0x11111111, 0x11c11111, 0x00000111, + 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8, + 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888, + 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8, + 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static const u32 b43_ntab_intlevel_r3[] = { + 0x00802070, 0x0671188d, 0x0a60192c, 0x0a300e46, + 0x00c1188d, 0x080024d2, 0x00000070, +}; + +static const u32 b43_ntab_tdtrn_r3[] = { + 0x061c061c, 0x0050ee68, 0xf592fe36, 0xfe5212f6, + 0x00000c38, 0xfe5212f6, 0xf592fe36, 0x0050ee68, + 0x061c061c, 0xee680050, 0xfe36f592, 0x12f6fe52, + 0x0c380000, 0x12f6fe52, 0xfe36f592, 0xee680050, + 0x061c061c, 0x0050ee68, 0xf592fe36, 0xfe5212f6, + 0x00000c38, 0xfe5212f6, 0xf592fe36, 0x0050ee68, + 0x061c061c, 0xee680050, 0xfe36f592, 0x12f6fe52, + 0x0c380000, 0x12f6fe52, 0xfe36f592, 0xee680050, + 0x05e305e3, 0x004def0c, 0xf5f3fe47, 0xfe611246, + 0x00000bc7, 0xfe611246, 0xf5f3fe47, 0x004def0c, + 0x05e305e3, 0xef0c004d, 0xfe47f5f3, 0x1246fe61, + 0x0bc70000, 0x1246fe61, 0xfe47f5f3, 0xef0c004d, + 0x05e305e3, 0x004def0c, 0xf5f3fe47, 0xfe611246, + 0x00000bc7, 0xfe611246, 0xf5f3fe47, 0x004def0c, + 0x05e305e3, 0xef0c004d, 0xfe47f5f3, 0x1246fe61, + 0x0bc70000, 0x1246fe61, 0xfe47f5f3, 0xef0c004d, + 0xfa58fa58, 0xf895043b, 0xff4c09c0, 0xfbc6ffa8, + 0xfb84f384, 0x0798f6f9, 0x05760122, 0x058409f6, + 0x0b500000, 0x05b7f542, 0x08860432, 0x06ddfee7, + 0xfb84f384, 0xf9d90664, 0xf7e8025c, 0x00fff7bd, + 0x05a805a8, 0xf7bd00ff, 0x025cf7e8, 0x0664f9d9, + 0xf384fb84, 0xfee706dd, 0x04320886, 0xf54205b7, + 0x00000b50, 0x09f60584, 0x01220576, 0xf6f90798, + 0xf384fb84, 0xffa8fbc6, 0x09c0ff4c, 0x043bf895, + 0x02d402d4, 0x07de0270, 0xfc96079c, 0xf90afe94, + 0xfe00ff2c, 0x02d4065d, 0x092a0096, 0x0014fbb8, + 0xfd2cfd2c, 0x076afb3c, 0x0096f752, 0xf991fd87, + 0xfb2c0200, 0xfeb8f960, 0x08e0fc96, 0x049802a8, + 0xfd2cfd2c, 0x02a80498, 0xfc9608e0, 0xf960feb8, + 0x0200fb2c, 0xfd87f991, 0xf7520096, 0xfb3c076a, + 0xfd2cfd2c, 0xfbb80014, 0x0096092a, 0x065d02d4, + 0xff2cfe00, 0xfe94f90a, 0x079cfc96, 0x027007de, + 0x02d402d4, 0x027007de, 0x079cfc96, 0xfe94f90a, + 0xff2cfe00, 0x065d02d4, 0x0096092a, 0xfbb80014, + 0xfd2cfd2c, 0xfb3c076a, 0xf7520096, 0xfd87f991, + 0x0200fb2c, 0xf960feb8, 0xfc9608e0, 0x02a80498, + 0xfd2cfd2c, 0x049802a8, 0x08e0fc96, 0xfeb8f960, + 0xfb2c0200, 0xf991fd87, 0x0096f752, 0x076afb3c, + 0xfd2cfd2c, 0x0014fbb8, 0x092a0096, 0x02d4065d, + 0xfe00ff2c, 0xf90afe94, 0xfc96079c, 0x07de0270, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x062a0000, 0xfefa0759, 0x08b80908, 0xf396fc2d, + 0xf9d6045c, 0xfc4ef608, 0xf748f596, 0x07b207bf, + 0x062a062a, 0xf84ef841, 0xf748f596, 0x03b209f8, + 0xf9d6045c, 0x0c6a03d3, 0x08b80908, 0x0106f8a7, + 0x062a0000, 0xfefaf8a7, 0x08b8f6f8, 0xf39603d3, + 0xf9d6fba4, 0xfc4e09f8, 0xf7480a6a, 0x07b2f841, + 0x062af9d6, 0xf84e07bf, 0xf7480a6a, 0x03b2f608, + 0xf9d6fba4, 0x0c6afc2d, 0x08b8f6f8, 0x01060759, + 0x062a0000, 0xfefa0759, 0x08b80908, 0xf396fc2d, + 0xf9d6045c, 0xfc4ef608, 0xf748f596, 0x07b207bf, + 0x062a062a, 0xf84ef841, 0xf748f596, 0x03b209f8, + 0xf9d6045c, 0x0c6a03d3, 0x08b80908, 0x0106f8a7, + 0x062a0000, 0xfefaf8a7, 0x08b8f6f8, 0xf39603d3, + 0xf9d6fba4, 0xfc4e09f8, 0xf7480a6a, 0x07b2f841, + 0x062af9d6, 0xf84e07bf, 0xf7480a6a, 0x03b2f608, + 0xf9d6fba4, 0x0c6afc2d, 0x08b8f6f8, 0x01060759, + 0x061c061c, 0xff30009d, 0xffb21141, 0xfd87fb54, + 0xf65dfe59, 0x02eef99e, 0x0166f03c, 0xfff809b6, + 0x000008a4, 0x000af42b, 0x00eff577, 0xfa840bf2, + 0xfc02ff51, 0x08260f67, 0xfff0036f, 0x0842f9c3, + 0x00000000, 0x063df7be, 0xfc910010, 0xf099f7da, + 0x00af03fe, 0xf40e057c, 0x0a89ff11, 0x0bd5fff6, + 0xf75c0000, 0xf64a0008, 0x0fc4fe9a, 0x0662fd12, + 0x01a709a3, 0x04ac0279, 0xeebf004e, 0xff6300d0, + 0xf9e4f9e4, 0x00d0ff63, 0x004eeebf, 0x027904ac, + 0x09a301a7, 0xfd120662, 0xfe9a0fc4, 0x0008f64a, + 0x0000f75c, 0xfff60bd5, 0xff110a89, 0x057cf40e, + 0x03fe00af, 0xf7daf099, 0x0010fc91, 0xf7be063d, + 0x00000000, 0xf9c30842, 0x036ffff0, 0x0f670826, + 0xff51fc02, 0x0bf2fa84, 0xf57700ef, 0xf42b000a, + 0x08a40000, 0x09b6fff8, 0xf03c0166, 0xf99e02ee, + 0xfe59f65d, 0xfb54fd87, 0x1141ffb2, 0x009dff30, + 0x05e30000, 0xff060705, 0x085408a0, 0xf425fc59, + 0xfa1d042a, 0xfc78f67a, 0xf7acf60e, 0x075a0766, + 0x05e305e3, 0xf8a6f89a, 0xf7acf60e, 0x03880986, + 0xfa1d042a, 0x0bdb03a7, 0x085408a0, 0x00faf8fb, + 0x05e30000, 0xff06f8fb, 0x0854f760, 0xf42503a7, + 0xfa1dfbd6, 0xfc780986, 0xf7ac09f2, 0x075af89a, + 0x05e3fa1d, 0xf8a60766, 0xf7ac09f2, 0x0388f67a, + 0xfa1dfbd6, 0x0bdbfc59, 0x0854f760, 0x00fa0705, + 0x05e30000, 0xff060705, 0x085408a0, 0xf425fc59, + 0xfa1d042a, 0xfc78f67a, 0xf7acf60e, 0x075a0766, + 0x05e305e3, 0xf8a6f89a, 0xf7acf60e, 0x03880986, + 0xfa1d042a, 0x0bdb03a7, 0x085408a0, 0x00faf8fb, + 0x05e30000, 0xff06f8fb, 0x0854f760, 0xf42503a7, + 0xfa1dfbd6, 0xfc780986, 0xf7ac09f2, 0x075af89a, + 0x05e3fa1d, 0xf8a60766, 0xf7ac09f2, 0x0388f67a, + 0xfa1dfbd6, 0x0bdbfc59, 0x0854f760, 0x00fa0705, + 0xfa58fa58, 0xf8f0fe00, 0x0448073d, 0xfdc9fe46, + 0xf9910258, 0x089d0407, 0xfd5cf71a, 0x02affde0, + 0x083e0496, 0xff5a0740, 0xff7afd97, 0x00fe01f1, + 0x0009082e, 0xfa94ff75, 0xfecdf8ea, 0xffb0f693, + 0xfd2cfa58, 0x0433ff16, 0xfba405dd, 0xfa610341, + 0x06a606cb, 0x0039fd2d, 0x0677fa97, 0x01fa05e0, + 0xf896003e, 0x075a068b, 0x012cfc3e, 0xfa23f98d, + 0xfc7cfd43, 0xff90fc0d, 0x01c10982, 0x00c601d6, + 0xfd2cfd2c, 0x01d600c6, 0x098201c1, 0xfc0dff90, + 0xfd43fc7c, 0xf98dfa23, 0xfc3e012c, 0x068b075a, + 0x003ef896, 0x05e001fa, 0xfa970677, 0xfd2d0039, + 0x06cb06a6, 0x0341fa61, 0x05ddfba4, 0xff160433, + 0xfa58fd2c, 0xf693ffb0, 0xf8eafecd, 0xff75fa94, + 0x082e0009, 0x01f100fe, 0xfd97ff7a, 0x0740ff5a, + 0x0496083e, 0xfde002af, 0xf71afd5c, 0x0407089d, + 0x0258f991, 0xfe46fdc9, 0x073d0448, 0xfe00f8f0, + 0xfd2cfd2c, 0xfce00500, 0xfc09fddc, 0xfe680157, + 0x04c70571, 0xfc3aff21, 0xfcd70228, 0x056d0277, + 0x0200fe00, 0x0022f927, 0xfe3c032b, 0xfc44ff3c, + 0x03e9fbdb, 0x04570313, 0x04c9ff5c, 0x000d03b8, + 0xfa580000, 0xfbe900d2, 0xf9d0fe0b, 0x0125fdf9, + 0x042501bf, 0x0328fa2b, 0xffa902f0, 0xfa250157, + 0x0200fe00, 0x03740438, 0xff0405fd, 0x030cfe52, + 0x0037fb39, 0xff6904c5, 0x04f8fd23, 0xfd31fc1b, + 0xfd2cfd2c, 0xfc1bfd31, 0xfd2304f8, 0x04c5ff69, + 0xfb390037, 0xfe52030c, 0x05fdff04, 0x04380374, + 0xfe000200, 0x0157fa25, 0x02f0ffa9, 0xfa2b0328, + 0x01bf0425, 0xfdf90125, 0xfe0bf9d0, 0x00d2fbe9, + 0x0000fa58, 0x03b8000d, 0xff5c04c9, 0x03130457, + 0xfbdb03e9, 0xff3cfc44, 0x032bfe3c, 0xf9270022, + 0xfe000200, 0x0277056d, 0x0228fcd7, 0xff21fc3a, + 0x057104c7, 0x0157fe68, 0xfddcfc09, 0x0500fce0, + 0xfd2cfd2c, 0x0500fce0, 0xfddcfc09, 0x0157fe68, + 0x057104c7, 0xff21fc3a, 0x0228fcd7, 0x0277056d, + 0xfe000200, 0xf9270022, 0x032bfe3c, 0xff3cfc44, + 0xfbdb03e9, 0x03130457, 0xff5c04c9, 0x03b8000d, + 0x0000fa58, 0x00d2fbe9, 0xfe0bf9d0, 0xfdf90125, + 0x01bf0425, 0xfa2b0328, 0x02f0ffa9, 0x0157fa25, + 0xfe000200, 0x04380374, 0x05fdff04, 0xfe52030c, + 0xfb390037, 0x04c5ff69, 0xfd2304f8, 0xfc1bfd31, + 0xfd2cfd2c, 0xfd31fc1b, 0x04f8fd23, 0xff6904c5, + 0x0037fb39, 0x030cfe52, 0xff0405fd, 0x03740438, + 0x0200fe00, 0xfa250157, 0xffa902f0, 0x0328fa2b, + 0x042501bf, 0x0125fdf9, 0xf9d0fe0b, 0xfbe900d2, + 0xfa580000, 0x000d03b8, 0x04c9ff5c, 0x04570313, + 0x03e9fbdb, 0xfc44ff3c, 0xfe3c032b, 0x0022f927, + 0x0200fe00, 0x056d0277, 0xfcd70228, 0xfc3aff21, + 0x04c70571, 0xfe680157, 0xfc09fddc, 0xfce00500, + 0x05a80000, 0xff1006be, 0x0800084a, 0xf49cfc7e, + 0xfa580400, 0xfc9cf6da, 0xf800f672, 0x0710071c, + 0x05a805a8, 0xf8f0f8e4, 0xf800f672, 0x03640926, + 0xfa580400, 0x0b640382, 0x0800084a, 0x00f0f942, + 0x05a80000, 0xff10f942, 0x0800f7b6, 0xf49c0382, + 0xfa58fc00, 0xfc9c0926, 0xf800098e, 0x0710f8e4, + 0x05a8fa58, 0xf8f0071c, 0xf800098e, 0x0364f6da, + 0xfa58fc00, 0x0b64fc7e, 0x0800f7b6, 0x00f006be, + 0x05a80000, 0xff1006be, 0x0800084a, 0xf49cfc7e, + 0xfa580400, 0xfc9cf6da, 0xf800f672, 0x0710071c, + 0x05a805a8, 0xf8f0f8e4, 0xf800f672, 0x03640926, + 0xfa580400, 0x0b640382, 0x0800084a, 0x00f0f942, + 0x05a80000, 0xff10f942, 0x0800f7b6, 0xf49c0382, + 0xfa58fc00, 0xfc9c0926, 0xf800098e, 0x0710f8e4, + 0x05a8fa58, 0xf8f0071c, 0xf800098e, 0x0364f6da, + 0xfa58fc00, 0x0b64fc7e, 0x0800f7b6, 0x00f006be, +}; + +static const u32 b43_ntab_noisevar0_r3[] = { + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, +}; + +static const u32 b43_ntab_noisevar1_r3[] = { + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, + 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, +}; + +static const u16 b43_ntab_mcs_r3[] = { + 0x0000, 0x0008, 0x000a, 0x0010, 0x0012, 0x0019, + 0x001a, 0x001c, 0x0080, 0x0088, 0x008a, 0x0090, + 0x0092, 0x0099, 0x009a, 0x009c, 0x0100, 0x0108, + 0x010a, 0x0110, 0x0112, 0x0119, 0x011a, 0x011c, + 0x0180, 0x0188, 0x018a, 0x0190, 0x0192, 0x0199, + 0x019a, 0x019c, 0x0000, 0x0098, 0x00a0, 0x00a8, + 0x009a, 0x00a2, 0x00aa, 0x0120, 0x0128, 0x0128, + 0x0130, 0x0138, 0x0138, 0x0140, 0x0122, 0x012a, + 0x012a, 0x0132, 0x013a, 0x013a, 0x0142, 0x01a8, + 0x01b0, 0x01b8, 0x01b0, 0x01b8, 0x01c0, 0x01c8, + 0x01c0, 0x01c8, 0x01d0, 0x01d0, 0x01d8, 0x01aa, + 0x01b2, 0x01ba, 0x01b2, 0x01ba, 0x01c2, 0x01ca, + 0x01c2, 0x01ca, 0x01d2, 0x01d2, 0x01da, 0x0001, + 0x0002, 0x0004, 0x0009, 0x000c, 0x0011, 0x0014, + 0x0018, 0x0020, 0x0021, 0x0022, 0x0024, 0x0081, + 0x0082, 0x0084, 0x0089, 0x008c, 0x0091, 0x0094, + 0x0098, 0x00a0, 0x00a1, 0x00a2, 0x00a4, 0x0007, + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, + 0x0007, 0x0007, +}; + +static const u32 b43_ntab_tdi20a0_r3[] = { + 0x00091226, 0x000a1429, 0x000b56ad, 0x000c58b0, + 0x000d5ab3, 0x000e9cb6, 0x000f9eba, 0x0000c13d, + 0x00020301, 0x00030504, 0x00040708, 0x0005090b, + 0x00064b8e, 0x00095291, 0x000a5494, 0x000b9718, + 0x000c9927, 0x000d9b2a, 0x000edd2e, 0x000fdf31, + 0x000101b4, 0x000243b7, 0x000345bb, 0x000447be, + 0x00058982, 0x00068c05, 0x00099309, 0x000a950c, + 0x000bd78f, 0x000cd992, 0x000ddb96, 0x000f1d99, + 0x00005fa8, 0x0001422c, 0x0002842f, 0x00038632, + 0x00048835, 0x0005ca38, 0x0006ccbc, 0x0009d3bf, + 0x000b1603, 0x000c1806, 0x000d1a0a, 0x000e1c0d, + 0x000f5e10, 0x00008093, 0x00018297, 0x0002c49a, + 0x0003c680, 0x0004c880, 0x00060b00, 0x00070d00, + 0x00000000, 0x00000000, 0x00000000, +}; + +static const u32 b43_ntab_tdi20a1_r3[] = { + 0x00014b26, 0x00028d29, 0x000393ad, 0x00049630, + 0x0005d833, 0x0006da36, 0x00099c3a, 0x000a9e3d, + 0x000bc081, 0x000cc284, 0x000dc488, 0x000f068b, + 0x0000488e, 0x00018b91, 0x0002d214, 0x0003d418, + 0x0004d6a7, 0x000618aa, 0x00071aae, 0x0009dcb1, + 0x000b1eb4, 0x000c0137, 0x000d033b, 0x000e053e, + 0x000f4702, 0x00008905, 0x00020c09, 0x0003128c, + 0x0004148f, 0x00051712, 0x00065916, 0x00091b19, + 0x000a1d28, 0x000b5f2c, 0x000c41af, 0x000d43b2, + 0x000e85b5, 0x000f87b8, 0x0000c9bc, 0x00024cbf, + 0x00035303, 0x00045506, 0x0005978a, 0x0006998d, + 0x00095b90, 0x000a5d93, 0x000b9f97, 0x000c821a, + 0x000d8400, 0x000ec600, 0x000fc800, 0x00010a00, + 0x00000000, 0x00000000, 0x00000000, +}; + +static const u32 b43_ntab_tdi40a0_r3[] = { + 0x0011a346, 0x00136ccf, 0x0014f5d9, 0x001641e2, + 0x0017cb6b, 0x00195475, 0x001b2383, 0x001cad0c, + 0x001e7616, 0x0000821f, 0x00020ba8, 0x0003d4b2, + 0x00056447, 0x00072dd0, 0x0008b6da, 0x000a02e3, + 0x000b8c6c, 0x000d15f6, 0x0011e484, 0x0013ae0d, + 0x00153717, 0x00168320, 0x00180ca9, 0x00199633, + 0x001b6548, 0x001ceed1, 0x001eb7db, 0x0000c3e4, + 0x00024d6d, 0x000416f7, 0x0005a585, 0x00076f0f, + 0x0008f818, 0x000a4421, 0x000bcdab, 0x000d9734, + 0x00122649, 0x0013efd2, 0x001578dc, 0x0016c4e5, + 0x00184e6e, 0x001a17f8, 0x001ba686, 0x001d3010, + 0x001ef999, 0x00010522, 0x00028eac, 0x00045835, + 0x0005e74a, 0x0007b0d3, 0x00093a5d, 0x000a85e6, + 0x000c0f6f, 0x000dd8f9, 0x00126787, 0x00143111, + 0x0015ba9a, 0x00170623, 0x00188fad, 0x001a5936, + 0x001be84b, 0x001db1d4, 0x001f3b5e, 0x000146e7, + 0x00031070, 0x000499fa, 0x00062888, 0x0007f212, + 0x00097b9b, 0x000ac7a4, 0x000c50ae, 0x000e1a37, + 0x0012a94c, 0x001472d5, 0x0015fc5f, 0x00174868, + 0x0018d171, 0x001a9afb, 0x001c2989, 0x001df313, + 0x001f7c9c, 0x000188a5, 0x000351af, 0x0004db38, + 0x0006aa4d, 0x000833d7, 0x0009bd60, 0x000b0969, + 0x000c9273, 0x000e5bfc, 0x00132a8a, 0x0014b414, + 0x00163d9d, 0x001789a6, 0x001912b0, 0x001adc39, + 0x001c6bce, 0x001e34d8, 0x001fbe61, 0x0001ca6a, + 0x00039374, 0x00051cfd, 0x0006ec0b, 0x00087515, + 0x0009fe9e, 0x000b4aa7, 0x000cd3b1, 0x000e9d3a, + 0x00000000, 0x00000000, +}; + +static const u32 b43_ntab_tdi40a1_r3[] = { + 0x001edb36, 0x000129ca, 0x0002b353, 0x00047cdd, + 0x0005c8e6, 0x000791ef, 0x00091bf9, 0x000aaa07, + 0x000c3391, 0x000dfd1a, 0x00120923, 0x0013d22d, + 0x00155c37, 0x0016eacb, 0x00187454, 0x001a3dde, + 0x001b89e7, 0x001d12f0, 0x001f1cfa, 0x00016b88, + 0x00033492, 0x0004be1b, 0x00060a24, 0x0007d32e, + 0x00095d38, 0x000aec4c, 0x000c7555, 0x000e3edf, + 0x00124ae8, 0x001413f1, 0x0015a37b, 0x00172c89, + 0x0018b593, 0x001a419c, 0x001bcb25, 0x001d942f, + 0x001f63b9, 0x0001ad4d, 0x00037657, 0x0004c260, + 0x00068be9, 0x000814f3, 0x0009a47c, 0x000b2d8a, + 0x000cb694, 0x000e429d, 0x00128c26, 0x001455b0, + 0x0015e4ba, 0x00176e4e, 0x0018f758, 0x001a8361, + 0x001c0cea, 0x001dd674, 0x001fa57d, 0x0001ee8b, + 0x0003b795, 0x0005039e, 0x0006cd27, 0x000856b1, + 0x0009e5c6, 0x000b6f4f, 0x000cf859, 0x000e8462, + 0x00130deb, 0x00149775, 0x00162603, 0x0017af8c, + 0x00193896, 0x001ac49f, 0x001c4e28, 0x001e17b2, + 0x0000a6c7, 0x00023050, 0x0003f9da, 0x00054563, + 0x00070eec, 0x00089876, 0x000a2704, 0x000bb08d, + 0x000d3a17, 0x001185a0, 0x00134f29, 0x0014d8b3, + 0x001667c8, 0x0017f151, 0x00197adb, 0x001b0664, + 0x001c8fed, 0x001e5977, 0x0000e805, 0x0002718f, + 0x00043b18, 0x000586a1, 0x0007502b, 0x0008d9b4, + 0x000a68c9, 0x000bf252, 0x000dbbdc, 0x0011c7e5, + 0x001390ee, 0x00151a78, 0x0016a906, 0x00183290, + 0x0019bc19, 0x001b4822, 0x001cd12c, 0x001e9ab5, + 0x00000000, 0x00000000, +}; + +static const u32 b43_ntab_pilotlt_r3[] = { + 0x76540213, 0x62407351, 0x76543210, 0x76540213, + 0x76540213, 0x76430521, +}; + +static const u32 b43_ntab_channelest_r3[] = { + 0x44444444, 0x44444444, 0x44444444, 0x44444444, + 0x44444444, 0x44444444, 0x44444444, 0x44444444, + 0x10101010, 0x10101010, 0x10101010, 0x10101010, + 0x10101010, 0x10101010, 0x10101010, 0x10101010, + 0x44444444, 0x44444444, 0x44444444, 0x44444444, + 0x44444444, 0x44444444, 0x44444444, 0x44444444, + 0x10101010, 0x10101010, 0x10101010, 0x10101010, + 0x10101010, 0x10101010, 0x10101010, 0x10101010, + 0x44444444, 0x44444444, 0x44444444, 0x44444444, + 0x44444444, 0x44444444, 0x44444444, 0x44444444, + 0x44444444, 0x44444444, 0x44444444, 0x44444444, + 0x44444444, 0x44444444, 0x44444444, 0x44444444, + 0x10101010, 0x10101010, 0x10101010, 0x10101010, + 0x10101010, 0x10101010, 0x10101010, 0x10101010, + 0x10101010, 0x10101010, 0x10101010, 0x10101010, + 0x10101010, 0x10101010, 0x10101010, 0x10101010, + 0x44444444, 0x44444444, 0x44444444, 0x44444444, + 0x44444444, 0x44444444, 0x44444444, 0x44444444, + 0x44444444, 0x44444444, 0x44444444, 0x44444444, + 0x44444444, 0x44444444, 0x44444444, 0x44444444, + 0x10101010, 0x10101010, 0x10101010, 0x10101010, + 0x10101010, 0x10101010, 0x10101010, 0x10101010, + 0x10101010, 0x10101010, 0x10101010, 0x10101010, + 0x10101010, 0x10101010, 0x10101010, 0x10101010, +}; + +static const u8 b43_ntab_framelookup_r3[] = { + 0x02, 0x04, 0x14, 0x14, 0x03, 0x05, 0x16, 0x16, + 0x0a, 0x0c, 0x1c, 0x1c, 0x0b, 0x0d, 0x1e, 0x1e, + 0x06, 0x08, 0x18, 0x18, 0x07, 0x09, 0x1a, 0x1a, + 0x0e, 0x10, 0x20, 0x28, 0x0f, 0x11, 0x22, 0x2a, +}; + +static const u8 b43_ntab_estimatepowerlt0_r3[] = { + 0x55, 0x54, 0x54, 0x53, 0x52, 0x52, 0x51, 0x51, + 0x50, 0x4f, 0x4f, 0x4e, 0x4e, 0x4d, 0x4c, 0x4c, + 0x4b, 0x4a, 0x49, 0x49, 0x48, 0x47, 0x46, 0x46, + 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, 0x40, 0x3f, + 0x3e, 0x3d, 0x3c, 0x3a, 0x39, 0x38, 0x37, 0x36, + 0x35, 0x33, 0x32, 0x31, 0x2f, 0x2e, 0x2c, 0x2b, + 0x29, 0x27, 0x25, 0x23, 0x21, 0x1f, 0x1d, 0x1a, + 0x18, 0x15, 0x12, 0x0e, 0x0b, 0x07, 0x02, 0xfd, +}; + +static const u8 b43_ntab_estimatepowerlt1_r3[] = { + 0x55, 0x54, 0x54, 0x53, 0x52, 0x52, 0x51, 0x51, + 0x50, 0x4f, 0x4f, 0x4e, 0x4e, 0x4d, 0x4c, 0x4c, + 0x4b, 0x4a, 0x49, 0x49, 0x48, 0x47, 0x46, 0x46, + 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, 0x40, 0x3f, + 0x3e, 0x3d, 0x3c, 0x3a, 0x39, 0x38, 0x37, 0x36, + 0x35, 0x33, 0x32, 0x31, 0x2f, 0x2e, 0x2c, 0x2b, + 0x29, 0x27, 0x25, 0x23, 0x21, 0x1f, 0x1d, 0x1a, + 0x18, 0x15, 0x12, 0x0e, 0x0b, 0x07, 0x02, 0xfd, +}; + +static const u8 b43_ntab_adjustpower0_r3[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static const u8 b43_ntab_adjustpower1_r3[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static const u32 b43_ntab_gainctl0_r3[] = { + 0x5bf70044, 0x5bf70042, 0x5bf70040, 0x5bf7003e, + 0x5bf7003c, 0x5bf7003b, 0x5bf70039, 0x5bf70037, + 0x5bf70036, 0x5bf70034, 0x5bf70033, 0x5bf70031, + 0x5bf70030, 0x5ba70044, 0x5ba70042, 0x5ba70040, + 0x5ba7003e, 0x5ba7003c, 0x5ba7003b, 0x5ba70039, + 0x5ba70037, 0x5ba70036, 0x5ba70034, 0x5ba70033, + 0x5b770044, 0x5b770042, 0x5b770040, 0x5b77003e, + 0x5b77003c, 0x5b77003b, 0x5b770039, 0x5b770037, + 0x5b770036, 0x5b770034, 0x5b770033, 0x5b770031, + 0x5b770030, 0x5b77002f, 0x5b77002d, 0x5b77002c, + 0x5b470044, 0x5b470042, 0x5b470040, 0x5b47003e, + 0x5b47003c, 0x5b47003b, 0x5b470039, 0x5b470037, + 0x5b470036, 0x5b470034, 0x5b470033, 0x5b470031, + 0x5b470030, 0x5b47002f, 0x5b47002d, 0x5b47002c, + 0x5b47002b, 0x5b47002a, 0x5b270044, 0x5b270042, + 0x5b270040, 0x5b27003e, 0x5b27003c, 0x5b27003b, + 0x5b270039, 0x5b270037, 0x5b270036, 0x5b270034, + 0x5b270033, 0x5b270031, 0x5b270030, 0x5b27002f, + 0x5b170044, 0x5b170042, 0x5b170040, 0x5b17003e, + 0x5b17003c, 0x5b17003b, 0x5b170039, 0x5b170037, + 0x5b170036, 0x5b170034, 0x5b170033, 0x5b170031, + 0x5b170030, 0x5b17002f, 0x5b17002d, 0x5b17002c, + 0x5b17002b, 0x5b17002a, 0x5b170028, 0x5b170027, + 0x5b170026, 0x5b170025, 0x5b170024, 0x5b170023, + 0x5b070044, 0x5b070042, 0x5b070040, 0x5b07003e, + 0x5b07003c, 0x5b07003b, 0x5b070039, 0x5b070037, + 0x5b070036, 0x5b070034, 0x5b070033, 0x5b070031, + 0x5b070030, 0x5b07002f, 0x5b07002d, 0x5b07002c, + 0x5b07002b, 0x5b07002a, 0x5b070028, 0x5b070027, + 0x5b070026, 0x5b070025, 0x5b070024, 0x5b070023, + 0x5b070022, 0x5b070021, 0x5b070020, 0x5b07001f, + 0x5b07001e, 0x5b07001d, 0x5b07001d, 0x5b07001c, +}; + +static const u32 b43_ntab_gainctl1_r3[] = { + 0x5bf70044, 0x5bf70042, 0x5bf70040, 0x5bf7003e, + 0x5bf7003c, 0x5bf7003b, 0x5bf70039, 0x5bf70037, + 0x5bf70036, 0x5bf70034, 0x5bf70033, 0x5bf70031, + 0x5bf70030, 0x5ba70044, 0x5ba70042, 0x5ba70040, + 0x5ba7003e, 0x5ba7003c, 0x5ba7003b, 0x5ba70039, + 0x5ba70037, 0x5ba70036, 0x5ba70034, 0x5ba70033, + 0x5b770044, 0x5b770042, 0x5b770040, 0x5b77003e, + 0x5b77003c, 0x5b77003b, 0x5b770039, 0x5b770037, + 0x5b770036, 0x5b770034, 0x5b770033, 0x5b770031, + 0x5b770030, 0x5b77002f, 0x5b77002d, 0x5b77002c, + 0x5b470044, 0x5b470042, 0x5b470040, 0x5b47003e, + 0x5b47003c, 0x5b47003b, 0x5b470039, 0x5b470037, + 0x5b470036, 0x5b470034, 0x5b470033, 0x5b470031, + 0x5b470030, 0x5b47002f, 0x5b47002d, 0x5b47002c, + 0x5b47002b, 0x5b47002a, 0x5b270044, 0x5b270042, + 0x5b270040, 0x5b27003e, 0x5b27003c, 0x5b27003b, + 0x5b270039, 0x5b270037, 0x5b270036, 0x5b270034, + 0x5b270033, 0x5b270031, 0x5b270030, 0x5b27002f, + 0x5b170044, 0x5b170042, 0x5b170040, 0x5b17003e, + 0x5b17003c, 0x5b17003b, 0x5b170039, 0x5b170037, + 0x5b170036, 0x5b170034, 0x5b170033, 0x5b170031, + 0x5b170030, 0x5b17002f, 0x5b17002d, 0x5b17002c, + 0x5b17002b, 0x5b17002a, 0x5b170028, 0x5b170027, + 0x5b170026, 0x5b170025, 0x5b170024, 0x5b170023, + 0x5b070044, 0x5b070042, 0x5b070040, 0x5b07003e, + 0x5b07003c, 0x5b07003b, 0x5b070039, 0x5b070037, + 0x5b070036, 0x5b070034, 0x5b070033, 0x5b070031, + 0x5b070030, 0x5b07002f, 0x5b07002d, 0x5b07002c, + 0x5b07002b, 0x5b07002a, 0x5b070028, 0x5b070027, + 0x5b070026, 0x5b070025, 0x5b070024, 0x5b070023, + 0x5b070022, 0x5b070021, 0x5b070020, 0x5b07001f, + 0x5b07001e, 0x5b07001d, 0x5b07001d, 0x5b07001c, +}; + +static const u32 b43_ntab_iqlt0_r3[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static const u32 b43_ntab_iqlt1_r3[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +static const u16 b43_ntab_loftlt0_r3[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, +}; + +static const u16 b43_ntab_loftlt1_r3[] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, +}; + +/* TX gain tables */ const u32 b43_ntab_tx_gain_rev0_1_2[] = { 0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42, 0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44, @@ -1813,7 +2887,6 @@ void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset, #define ntab_upload(dev, offset, data) do { \ b43_ntab_write_bulk(dev, offset, offset##_SIZE, data); \ } while (0) - void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev) { /* Static tables */ @@ -1847,10 +2920,39 @@ void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev) ntab_upload(dev, B43_NTAB_C1_LOFEEDTH, b43_ntab_loftlt1); } +#define ntab_upload_r3(dev, offset, data) do { \ + b43_ntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \ + } while (0) void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev) { /* Static tables */ - /* TODO */ + ntab_upload_r3(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3); + ntab_upload_r3(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3); + ntab_upload_r3(dev, B43_NTAB_TMAP_R3, b43_ntab_tmap_r3); + ntab_upload_r3(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3); + ntab_upload_r3(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3); + ntab_upload_r3(dev, B43_NTAB_NOISEVAR0_R3, b43_ntab_noisevar0_r3); + ntab_upload_r3(dev, B43_NTAB_NOISEVAR1_R3, b43_ntab_noisevar1_r3); + ntab_upload_r3(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3); + ntab_upload_r3(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3); + ntab_upload_r3(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3); + ntab_upload_r3(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3); + ntab_upload_r3(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3); + ntab_upload_r3(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3); + ntab_upload_r3(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3); + ntab_upload_r3(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3); + ntab_upload_r3(dev, B43_NTAB_C0_ESTPLT_R3, + b43_ntab_estimatepowerlt0_r3); + ntab_upload_r3(dev, B43_NTAB_C1_ESTPLT_R3, + b43_ntab_estimatepowerlt1_r3); + ntab_upload_r3(dev, B43_NTAB_C0_ADJPLT_R3, b43_ntab_adjustpower0_r3); + ntab_upload_r3(dev, B43_NTAB_C1_ADJPLT_R3, b43_ntab_adjustpower1_r3); + ntab_upload_r3(dev, B43_NTAB_C0_GAINCTL_R3, b43_ntab_gainctl0_r3); + ntab_upload_r3(dev, B43_NTAB_C1_GAINCTL_R3, b43_ntab_gainctl1_r3); + ntab_upload_r3(dev, B43_NTAB_C0_IQLT_R3, b43_ntab_iqlt0_r3); + ntab_upload_r3(dev, B43_NTAB_C1_IQLT_R3, b43_ntab_iqlt1_r3); + ntab_upload_r3(dev, B43_NTAB_C0_LOFEEDTH_R3, b43_ntab_loftlt0_r3); + ntab_upload_r3(dev, B43_NTAB_C1_LOFEEDTH_R3, b43_ntab_loftlt1_r3); /* Volatile tables */ /* TODO */ diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 4ec593ba3eef..016a480b2dc6 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h @@ -109,6 +109,33 @@ b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq); #define B43_NTAB_C1_LOFEEDTH B43_NTAB16(0x1B, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 1 */ #define B43_NTAB_C1_LOFEEDTH_SIZE 128 +/* Static N-PHY tables, PHY revision >= 3 */ +#define B43_NTAB_FRAMESTRUCT_R3 B43_NTAB32(10, 000) /* frame struct */ +#define B43_NTAB_PILOT_R3 B43_NTAB16(11, 000) /* pilot */ +#define B43_NTAB_TMAP_R3 B43_NTAB32(12, 000) /* TM AP */ +#define B43_NTAB_INTLEVEL_R3 B43_NTAB32(13, 000) /* INT LV */ +#define B43_NTAB_TDTRN_R3 B43_NTAB32(14, 000) /* TD TRN */ +#define B43_NTAB_NOISEVAR0_R3 B43_NTAB32(16, 000) /* noise variance 0 */ +#define B43_NTAB_NOISEVAR1_R3 B43_NTAB32(16, 128) /* noise variance 1 */ +#define B43_NTAB_MCS_R3 B43_NTAB16(18, 000) /* MCS */ +#define B43_NTAB_TDI20A0_R3 B43_NTAB32(19, 128) /* TDI 20/0 */ +#define B43_NTAB_TDI20A1_R3 B43_NTAB32(19, 256) /* TDI 20/1 */ +#define B43_NTAB_TDI40A0_R3 B43_NTAB32(19, 640) /* TDI 40/0 */ +#define B43_NTAB_TDI40A1_R3 B43_NTAB32(19, 768) /* TDI 40/1 */ +#define B43_NTAB_PILOTLT_R3 B43_NTAB32(20, 000) /* PLT lookup */ +#define B43_NTAB_CHANEST_R3 B43_NTAB32(22, 000) /* channel estimate */ +#define B43_NTAB_FRAMELT_R3 B43_NTAB8 (24, 000) /* frame lookup */ +#define B43_NTAB_C0_ESTPLT_R3 B43_NTAB8 (26, 000) /* estimated power lookup 0 */ +#define B43_NTAB_C1_ESTPLT_R3 B43_NTAB8 (27, 000) /* estimated power lookup 1 */ +#define B43_NTAB_C0_ADJPLT_R3 B43_NTAB8 (26, 064) /* adjusted power lookup 0 */ +#define B43_NTAB_C1_ADJPLT_R3 B43_NTAB8 (27, 064) /* adjusted power lookup 1 */ +#define B43_NTAB_C0_GAINCTL_R3 B43_NTAB32(26, 192) /* gain control lookup 0 */ +#define B43_NTAB_C1_GAINCTL_R3 B43_NTAB32(27, 192) /* gain control lookup 1 */ +#define B43_NTAB_C0_IQLT_R3 B43_NTAB32(26, 320) /* I/Q lookup 0 */ +#define B43_NTAB_C1_IQLT_R3 B43_NTAB32(27, 320) /* I/Q lookup 1 */ +#define B43_NTAB_C0_LOFEEDTH_R3 B43_NTAB16(26, 448) /* Local Oscillator Feed Through lookup 0 */ +#define B43_NTAB_C1_LOFEEDTH_R3 B43_NTAB16(27, 448) /* Local Oscillator Feed Through lookup 1 */ + #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE 18 #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_SIZE 18 #define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_40_SIZE 18 -- cgit v1.2.3 From ad93562bdeecdded7d02eaaaf1aa5705ab57b1b7 Mon Sep 17 00:00:00 2001 From: Andiry Xu Date: Tue, 1 Mar 2011 14:57:05 +0800 Subject: USB host: Move AMD PLL quirk to pci-quirks.c This patch moves the AMD PLL quirk code in OHCI/EHCI driver to pci-quirks.c, and exports the functions to be used by xHCI driver later. AMD PLL quirk disable the optional PM feature inside specific SB700/SB800/Hudson-2/3 platforms under the following conditions: 1. If an isochronous device is connected to OHCI/EHCI/xHCI port and is active; 2. Optional PM feature that powers down the internal Bus PLL when the link is in low power state is enabled. Without AMD PLL quirk, USB isochronous stream may stutter or have breaks occasionally, which greatly impair the performance of audio/video streams. Currently AMD PLL quirk is implemented in OHCI and EHCI driver, and will be added to xHCI driver too. They are doing similar things actually, so move the quirk code to pci-quirks.c, which has several advantages: 1. Remove duplicate defines and functions in OHCI/EHCI (and xHCI) driver and make them cleaner; 2. AMD chipset information will be probed only once and then stored. Currently they're probed during every OHCI/EHCI initialization, move the detect code to pci-quirks.c saves the repeat detect cost; 3. Build up synchronization among OHCI/EHCI/xHCI driver. In current code, every host controller enable/disable PLL only according to its own status, and may enable PLL while there is still isoc transfer on other HCs. Move the quirk to pci-quirks.c prevents this issue. Signed-off-by: Andiry Xu Cc: David Brownell Cc: Alex He Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 10 +- drivers/usb/host/ehci-pci.c | 45 +------- drivers/usb/host/ehci-sched.c | 73 ++---------- drivers/usb/host/ehci.h | 2 +- drivers/usb/host/ohci-hcd.c | 13 +-- drivers/usb/host/ohci-pci.c | 110 ++---------------- drivers/usb/host/ohci-q.c | 4 +- drivers/usb/host/ohci.h | 4 +- drivers/usb/host/pci-quirks.c | 258 ++++++++++++++++++++++++++++++++++++++++++ drivers/usb/host/pci-quirks.h | 10 ++ 10 files changed, 300 insertions(+), 229 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index f69305d3a9b8..e6277536f392 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -114,13 +114,11 @@ MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us\n"); #define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT) -/* for ASPM quirk of ISOC on AMD SB800 */ -static struct pci_dev *amd_nb_dev; - /*-------------------------------------------------------------------------*/ #include "ehci.h" #include "ehci-dbg.c" +#include "pci-quirks.h" /*-------------------------------------------------------------------------*/ @@ -532,10 +530,8 @@ static void ehci_stop (struct usb_hcd *hcd) spin_unlock_irq (&ehci->lock); ehci_mem_cleanup (ehci); - if (amd_nb_dev) { - pci_dev_put(amd_nb_dev); - amd_nb_dev = NULL; - } + if (ehci->amd_pll_fix == 1) + usb_amd_dev_put(); #ifdef EHCI_STATS ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n", diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 07bb982e59f6..d5eaea7caf89 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -44,42 +44,6 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) return 0; } -static int ehci_quirk_amd_hudson(struct ehci_hcd *ehci) -{ - struct pci_dev *amd_smbus_dev; - u8 rev = 0; - - amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, 0x4385, NULL); - if (amd_smbus_dev) { - pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev); - if (rev < 0x40) { - pci_dev_put(amd_smbus_dev); - amd_smbus_dev = NULL; - return 0; - } - } else { - amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x780b, NULL); - if (!amd_smbus_dev) - return 0; - pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev); - if (rev < 0x11 || rev > 0x18) { - pci_dev_put(amd_smbus_dev); - amd_smbus_dev = NULL; - return 0; - } - } - - if (!amd_nb_dev) - amd_nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1510, NULL); - - ehci_info(ehci, "QUIRK: Enable exception for AMD Hudson ASPM\n"); - - pci_dev_put(amd_smbus_dev); - amd_smbus_dev = NULL; - - return 1; -} - /* called during probe() after chip reset completes */ static int ehci_pci_setup(struct usb_hcd *hcd) { @@ -138,9 +102,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) /* cache this readonly data; minimize chip reads */ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); - if (ehci_quirk_amd_hudson(ehci)) - ehci->amd_l1_fix = 1; - retval = ehci_halt(ehci); if (retval) return retval; @@ -191,6 +152,9 @@ static int ehci_pci_setup(struct usb_hcd *hcd) } break; case PCI_VENDOR_ID_AMD: + /* AMD PLL quirk */ + if (usb_amd_find_chipset_info()) + ehci->amd_pll_fix = 1; /* AMD8111 EHCI doesn't work, according to AMD errata */ if (pdev->device == 0x7463) { ehci_info(ehci, "ignoring AMD8111 (errata)\n"); @@ -236,6 +200,9 @@ static int ehci_pci_setup(struct usb_hcd *hcd) } break; case PCI_VENDOR_ID_ATI: + /* AMD PLL quirk */ + if (usb_amd_find_chipset_info()) + ehci->amd_pll_fix = 1; /* SB600 and old version of SB700 have a bug in EHCI controller, * which causes usb devices lose response in some cases. */ diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 30fbdbe1cf1e..1543c838b3d1 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1587,63 +1587,6 @@ itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); } -#define AB_REG_BAR_LOW 0xe0 -#define AB_REG_BAR_HIGH 0xe1 -#define AB_INDX(addr) ((addr) + 0x00) -#define AB_DATA(addr) ((addr) + 0x04) -#define NB_PCIE_INDX_ADDR 0xe0 -#define NB_PCIE_INDX_DATA 0xe4 -#define NB_PIF0_PWRDOWN_0 0x01100012 -#define NB_PIF0_PWRDOWN_1 0x01100013 - -static void ehci_quirk_amd_L1(struct ehci_hcd *ehci, int disable) -{ - u32 addr, addr_low, addr_high, val; - - outb_p(AB_REG_BAR_LOW, 0xcd6); - addr_low = inb_p(0xcd7); - outb_p(AB_REG_BAR_HIGH, 0xcd6); - addr_high = inb_p(0xcd7); - addr = addr_high << 8 | addr_low; - outl_p(0x30, AB_INDX(addr)); - outl_p(0x40, AB_DATA(addr)); - outl_p(0x34, AB_INDX(addr)); - val = inl_p(AB_DATA(addr)); - - if (disable) { - val &= ~0x8; - val |= (1 << 4) | (1 << 9); - } else { - val |= 0x8; - val &= ~((1 << 4) | (1 << 9)); - } - outl_p(val, AB_DATA(addr)); - - if (amd_nb_dev) { - addr = NB_PIF0_PWRDOWN_0; - pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_ADDR, addr); - pci_read_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, &val); - if (disable) - val &= ~(0x3f << 7); - else - val |= 0x3f << 7; - - pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, val); - - addr = NB_PIF0_PWRDOWN_1; - pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_ADDR, addr); - pci_read_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, &val); - if (disable) - val &= ~(0x3f << 7); - else - val |= 0x3f << 7; - - pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, val); - } - - return; -} - /* fit urb's itds into the selected schedule slot; activate as needed */ static int itd_link_urb ( @@ -1672,8 +1615,8 @@ itd_link_urb ( } if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { - if (ehci->amd_l1_fix == 1) - ehci_quirk_amd_L1(ehci, 1); + if (ehci->amd_pll_fix == 1) + usb_amd_quirk_pll_disable(); } ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; @@ -1801,8 +1744,8 @@ itd_complete ( ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { - if (ehci->amd_l1_fix == 1) - ehci_quirk_amd_L1(ehci, 0); + if (ehci->amd_pll_fix == 1) + usb_amd_quirk_pll_enable(); } if (unlikely(list_is_singular(&stream->td_list))) { @@ -2092,8 +2035,8 @@ sitd_link_urb ( } if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { - if (ehci->amd_l1_fix == 1) - ehci_quirk_amd_L1(ehci, 1); + if (ehci->amd_pll_fix == 1) + usb_amd_quirk_pll_disable(); } ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; @@ -2197,8 +2140,8 @@ sitd_complete ( ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { - if (ehci->amd_l1_fix == 1) - ehci_quirk_amd_L1(ehci, 0); + if (ehci->amd_pll_fix == 1) + usb_amd_quirk_pll_enable(); } if (list_is_singular(&stream->td_list)) { diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 799ac16a54b4..f86d3fa20214 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -131,7 +131,7 @@ struct ehci_hcd { /* one per controller */ unsigned has_amcc_usb23:1; unsigned need_io_watchdog:1; unsigned broken_periodic:1; - unsigned amd_l1_fix:1; + unsigned amd_pll_fix:1; unsigned fs_i_thresh:1; /* Intel iso scheduling */ unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/ diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 759a12ff8048..7b791bf1e7b4 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -75,6 +75,7 @@ static const char hcd_name [] = "ohci_hcd"; #define STATECHANGE_DELAY msecs_to_jiffies(300) #include "ohci.h" +#include "pci-quirks.h" static void ohci_dump (struct ohci_hcd *ohci, int verbose); static int ohci_init (struct ohci_hcd *ohci); @@ -85,18 +86,8 @@ static int ohci_restart (struct ohci_hcd *ohci); #endif #ifdef CONFIG_PCI -static void quirk_amd_pll(int state); -static void amd_iso_dev_put(void); static void sb800_prefetch(struct ohci_hcd *ohci, int on); #else -static inline void quirk_amd_pll(int state) -{ - return; -} -static inline void amd_iso_dev_put(void) -{ - return; -} static inline void sb800_prefetch(struct ohci_hcd *ohci, int on) { return; @@ -912,7 +903,7 @@ static void ohci_stop (struct usb_hcd *hcd) if (quirk_zfmicro(ohci)) del_timer(&ohci->unlink_watchdog); if (quirk_amdiso(ohci)) - amd_iso_dev_put(); + usb_amd_dev_put(); remove_debug_files (ohci); ohci_mem_cleanup (ohci); diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 36ee9a666e93..9816a2870d00 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -22,24 +22,6 @@ #include -/* constants used to work around PM-related transfer - * glitches in some AMD 700 series southbridges - */ -#define AB_REG_BAR 0xf0 -#define AB_INDX(addr) ((addr) + 0x00) -#define AB_DATA(addr) ((addr) + 0x04) -#define AX_INDXC 0X30 -#define AX_DATAC 0x34 - -#define NB_PCIE_INDX_ADDR 0xe0 -#define NB_PCIE_INDX_DATA 0xe4 -#define PCIE_P_CNTL 0x10040 -#define BIF_NB 0x10002 - -static struct pci_dev *amd_smbus_dev; -static struct pci_dev *amd_hb_dev; -static int amd_ohci_iso_count; - /*-------------------------------------------------------------------------*/ static int broken_suspend(struct usb_hcd *hcd) @@ -168,11 +150,14 @@ static int ohci_quirk_nec(struct usb_hcd *hcd) static int ohci_quirk_amd700(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); + struct pci_dev *amd_smbus_dev; u8 rev = 0; - if (!amd_smbus_dev) - amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, - PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); + if (usb_amd_find_chipset_info()) + ohci->flags |= OHCI_QUIRK_AMD_PLL; + + amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, + PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); if (!amd_smbus_dev) return 0; @@ -184,19 +169,8 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd) ohci_dbg(ohci, "enabled AMD prefetch quirk\n"); } - if ((rev > 0x3b) || (rev < 0x30)) { - pci_dev_put(amd_smbus_dev); - amd_smbus_dev = NULL; - return 0; - } - - amd_ohci_iso_count++; - - if (!amd_hb_dev) - amd_hb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x9600, NULL); - - ohci->flags |= OHCI_QUIRK_AMD_ISO; - ohci_dbg(ohci, "enabled AMD ISO transfers quirk\n"); + pci_dev_put(amd_smbus_dev); + amd_smbus_dev = NULL; return 0; } @@ -215,74 +189,6 @@ static int ohci_quirk_nvidia_shutdown(struct usb_hcd *hcd) return 0; } -/* - * The hardware normally enables the A-link power management feature, which - * lets the system lower the power consumption in idle states. - * - * Assume the system is configured to have USB 1.1 ISO transfers going - * to or from a USB device. Without this quirk, that stream may stutter - * or have breaks occasionally. For transfers going to speakers, this - * makes a very audible mess... - * - * That audio playback corruption is due to the audio stream getting - * interrupted occasionally when the link goes in lower power state - * This USB quirk prevents the link going into that lower power state - * during audio playback or other ISO operations. - */ -static void quirk_amd_pll(int on) -{ - u32 addr; - u32 val; - u32 bit = (on > 0) ? 1 : 0; - - pci_read_config_dword(amd_smbus_dev, AB_REG_BAR, &addr); - - /* BIT names/meanings are NDA-protected, sorry ... */ - - outl(AX_INDXC, AB_INDX(addr)); - outl(0x40, AB_DATA(addr)); - outl(AX_DATAC, AB_INDX(addr)); - val = inl(AB_DATA(addr)); - val &= ~((1 << 3) | (1 << 4) | (1 << 9)); - val |= (bit << 3) | ((!bit) << 4) | ((!bit) << 9); - outl(val, AB_DATA(addr)); - - if (amd_hb_dev) { - addr = PCIE_P_CNTL; - pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_ADDR, addr); - - pci_read_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, &val); - val &= ~(1 | (1 << 3) | (1 << 4) | (1 << 9) | (1 << 12)); - val |= bit | (bit << 3) | (bit << 12); - val |= ((!bit) << 4) | ((!bit) << 9); - pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, val); - - addr = BIF_NB; - pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_ADDR, addr); - - pci_read_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, &val); - val &= ~(1 << 8); - val |= bit << 8; - pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, val); - } -} - -static void amd_iso_dev_put(void) -{ - amd_ohci_iso_count--; - if (amd_ohci_iso_count == 0) { - if (amd_smbus_dev) { - pci_dev_put(amd_smbus_dev); - amd_smbus_dev = NULL; - } - if (amd_hb_dev) { - pci_dev_put(amd_hb_dev); - amd_hb_dev = NULL; - } - } - -} - static void sb800_prefetch(struct ohci_hcd *ohci, int on) { struct pci_dev *pdev; diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 83094d067e0f..dd24fc115e48 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -52,7 +52,7 @@ __acquires(ohci->lock) ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--; if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) { if (quirk_amdiso(ohci)) - quirk_amd_pll(1); + usb_amd_quirk_pll_enable(); if (quirk_amdprefetch(ohci)) sb800_prefetch(ohci, 0); } @@ -686,7 +686,7 @@ static void td_submit_urb ( } if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) { if (quirk_amdiso(ohci)) - quirk_amd_pll(0); + usb_amd_quirk_pll_disable(); if (quirk_amdprefetch(ohci)) sb800_prefetch(ohci, 1); } diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 51facb985c84..bad11a72c202 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -401,7 +401,7 @@ struct ohci_hcd { #define OHCI_QUIRK_NEC 0x40 /* lost interrupts */ #define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */ #define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */ -#define OHCI_QUIRK_AMD_ISO 0x200 /* ISO transfers*/ +#define OHCI_QUIRK_AMD_PLL 0x200 /* AMD PLL quirk*/ #define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */ #define OHCI_QUIRK_SHUTDOWN 0x800 /* nVidia power bug */ // there are also chip quirks/bugs in init logic @@ -433,7 +433,7 @@ static inline int quirk_zfmicro(struct ohci_hcd *ohci) } static inline int quirk_amdiso(struct ohci_hcd *ohci) { - return ohci->flags & OHCI_QUIRK_AMD_ISO; + return ohci->flags & OHCI_QUIRK_AMD_PLL; } static inline int quirk_amdprefetch(struct ohci_hcd *ohci) { diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 4c502c890ebd..1d586d4f7b56 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -52,6 +52,264 @@ #define EHCI_USBLEGCTLSTS 4 /* legacy control/status */ #define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */ +/* AMD quirk use */ +#define AB_REG_BAR_LOW 0xe0 +#define AB_REG_BAR_HIGH 0xe1 +#define AB_REG_BAR_SB700 0xf0 +#define AB_INDX(addr) ((addr) + 0x00) +#define AB_DATA(addr) ((addr) + 0x04) +#define AX_INDXC 0x30 +#define AX_DATAC 0x34 + +#define NB_PCIE_INDX_ADDR 0xe0 +#define NB_PCIE_INDX_DATA 0xe4 +#define PCIE_P_CNTL 0x10040 +#define BIF_NB 0x10002 +#define NB_PIF0_PWRDOWN_0 0x01100012 +#define NB_PIF0_PWRDOWN_1 0x01100013 + +static struct amd_chipset_info { + struct pci_dev *nb_dev; + struct pci_dev *smbus_dev; + int nb_type; + int sb_type; + int isoc_reqs; + int probe_count; + int probe_result; +} amd_chipset; + +static DEFINE_SPINLOCK(amd_lock); + +int usb_amd_find_chipset_info(void) +{ + u8 rev = 0; + unsigned long flags; + + spin_lock_irqsave(&amd_lock, flags); + + amd_chipset.probe_count++; + /* probe only once */ + if (amd_chipset.probe_count > 1) { + spin_unlock_irqrestore(&amd_lock, flags); + return amd_chipset.probe_result; + } + + amd_chipset.smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, 0x4385, NULL); + if (amd_chipset.smbus_dev) { + rev = amd_chipset.smbus_dev->revision; + if (rev >= 0x40) + amd_chipset.sb_type = 1; + else if (rev >= 0x30 && rev <= 0x3b) + amd_chipset.sb_type = 3; + } else { + amd_chipset.smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, + 0x780b, NULL); + if (!amd_chipset.smbus_dev) { + spin_unlock_irqrestore(&amd_lock, flags); + return 0; + } + rev = amd_chipset.smbus_dev->revision; + if (rev >= 0x11 && rev <= 0x18) + amd_chipset.sb_type = 2; + } + + if (amd_chipset.sb_type == 0) { + if (amd_chipset.smbus_dev) { + pci_dev_put(amd_chipset.smbus_dev); + amd_chipset.smbus_dev = NULL; + } + spin_unlock_irqrestore(&amd_lock, flags); + return 0; + } + + amd_chipset.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x9601, NULL); + if (amd_chipset.nb_dev) { + amd_chipset.nb_type = 1; + } else { + amd_chipset.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, + 0x1510, NULL); + if (amd_chipset.nb_dev) { + amd_chipset.nb_type = 2; + } else { + amd_chipset.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, + 0x9600, NULL); + if (amd_chipset.nb_dev) + amd_chipset.nb_type = 3; + } + } + + amd_chipset.probe_result = 1; + printk(KERN_DEBUG "QUIRK: Enable AMD PLL fix\n"); + + spin_unlock_irqrestore(&amd_lock, flags); + return amd_chipset.probe_result; +} +EXPORT_SYMBOL_GPL(usb_amd_find_chipset_info); + +/* + * The hardware normally enables the A-link power management feature, which + * lets the system lower the power consumption in idle states. + * + * This USB quirk prevents the link going into that lower power state + * during isochronous transfers. + * + * Without this quirk, isochronous stream on OHCI/EHCI/xHCI controllers of + * some AMD platforms may stutter or have breaks occasionally. + */ +static void usb_amd_quirk_pll(int disable) +{ + u32 addr, addr_low, addr_high, val; + u32 bit = disable ? 0 : 1; + unsigned long flags; + + spin_lock_irqsave(&amd_lock, flags); + + if (disable) { + amd_chipset.isoc_reqs++; + if (amd_chipset.isoc_reqs > 1) { + spin_unlock_irqrestore(&amd_lock, flags); + return; + } + } else { + amd_chipset.isoc_reqs--; + if (amd_chipset.isoc_reqs > 0) { + spin_unlock_irqrestore(&amd_lock, flags); + return; + } + } + + if (amd_chipset.sb_type == 1 || amd_chipset.sb_type == 2) { + outb_p(AB_REG_BAR_LOW, 0xcd6); + addr_low = inb_p(0xcd7); + outb_p(AB_REG_BAR_HIGH, 0xcd6); + addr_high = inb_p(0xcd7); + addr = addr_high << 8 | addr_low; + + outl_p(0x30, AB_INDX(addr)); + outl_p(0x40, AB_DATA(addr)); + outl_p(0x34, AB_INDX(addr)); + val = inl_p(AB_DATA(addr)); + } else if (amd_chipset.sb_type == 3) { + pci_read_config_dword(amd_chipset.smbus_dev, + AB_REG_BAR_SB700, &addr); + outl(AX_INDXC, AB_INDX(addr)); + outl(0x40, AB_DATA(addr)); + outl(AX_DATAC, AB_INDX(addr)); + val = inl(AB_DATA(addr)); + } else { + spin_unlock_irqrestore(&amd_lock, flags); + return; + } + + if (disable) { + val &= ~0x08; + val |= (1 << 4) | (1 << 9); + } else { + val |= 0x08; + val &= ~((1 << 4) | (1 << 9)); + } + outl_p(val, AB_DATA(addr)); + + if (!amd_chipset.nb_dev) { + spin_unlock_irqrestore(&amd_lock, flags); + return; + } + + if (amd_chipset.nb_type == 1 || amd_chipset.nb_type == 3) { + addr = PCIE_P_CNTL; + pci_write_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_ADDR, addr); + pci_read_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_DATA, &val); + + val &= ~(1 | (1 << 3) | (1 << 4) | (1 << 9) | (1 << 12)); + val |= bit | (bit << 3) | (bit << 12); + val |= ((!bit) << 4) | ((!bit) << 9); + pci_write_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_DATA, val); + + addr = BIF_NB; + pci_write_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_ADDR, addr); + pci_read_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_DATA, &val); + val &= ~(1 << 8); + val |= bit << 8; + + pci_write_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_DATA, val); + } else if (amd_chipset.nb_type == 2) { + addr = NB_PIF0_PWRDOWN_0; + pci_write_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_ADDR, addr); + pci_read_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_DATA, &val); + if (disable) + val &= ~(0x3f << 7); + else + val |= 0x3f << 7; + + pci_write_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_DATA, val); + + addr = NB_PIF0_PWRDOWN_1; + pci_write_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_ADDR, addr); + pci_read_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_DATA, &val); + if (disable) + val &= ~(0x3f << 7); + else + val |= 0x3f << 7; + + pci_write_config_dword(amd_chipset.nb_dev, + NB_PCIE_INDX_DATA, val); + } + + spin_unlock_irqrestore(&amd_lock, flags); + return; +} + +void usb_amd_quirk_pll_disable(void) +{ + usb_amd_quirk_pll(1); +} +EXPORT_SYMBOL_GPL(usb_amd_quirk_pll_disable); + +void usb_amd_quirk_pll_enable(void) +{ + usb_amd_quirk_pll(0); +} +EXPORT_SYMBOL_GPL(usb_amd_quirk_pll_enable); + +void usb_amd_dev_put(void) +{ + unsigned long flags; + + spin_lock_irqsave(&amd_lock, flags); + + amd_chipset.probe_count--; + if (amd_chipset.probe_count > 0) { + spin_unlock_irqrestore(&amd_lock, flags); + return; + } + + if (amd_chipset.nb_dev) { + pci_dev_put(amd_chipset.nb_dev); + amd_chipset.nb_dev = NULL; + } + if (amd_chipset.smbus_dev) { + pci_dev_put(amd_chipset.smbus_dev); + amd_chipset.smbus_dev = NULL; + } + amd_chipset.nb_type = 0; + amd_chipset.sb_type = 0; + amd_chipset.isoc_reqs = 0; + amd_chipset.probe_result = 0; + + spin_unlock_irqrestore(&amd_lock, flags); +} +EXPORT_SYMBOL_GPL(usb_amd_dev_put); /* * Make sure the controller is completely inactive, unable to diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index 1564edfff6fe..6ae9f78e9938 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h @@ -1,7 +1,17 @@ #ifndef __LINUX_USB_PCI_QUIRKS_H #define __LINUX_USB_PCI_QUIRKS_H +#ifdef CONFIG_PCI void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); +int usb_amd_find_chipset_info(void); +void usb_amd_dev_put(void); +void usb_amd_quirk_pll_disable(void); +void usb_amd_quirk_pll_enable(void); +#else +static inline void usb_amd_quirk_pll_disable(void) {} +static inline void usb_amd_quirk_pll_enable(void) {} +static inline void usb_amd_dev_put(void) {} +#endif /* CONFIG_PCI */ #endif /* __LINUX_USB_PCI_QUIRKS_H */ -- cgit v1.2.3 From 60b0bf0f11a02a6c288c7a923b2521aa7cfdc6c3 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 1 Mar 2011 16:58:37 +0900 Subject: usb: EHCI, OHCI: Add configuration for the SH USB controller The SH EHCI/OHCI driver hardcoded the CPU type in {ehci,ohci}-hcd.c. So if we will add the new CPU, we had to add to the hcd driver each time. The patch adds the CONFIG_USB_{EHCI,OHCI}_SH configuration. So if we want to use the SH EHCI/OHCI, we only enable the configuration. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 14 ++++++++++++++ drivers/usb/host/ehci-hcd.c | 2 +- drivers/usb/host/ohci-hcd.c | 5 +---- 3 files changed, 16 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 923e5a079b59..9116d30bcdac 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -173,6 +173,13 @@ config USB_EHCI_HCD_PPC_OF Enables support for the USB controller present on the PowerPC OpenFirmware platform bus. +config USB_EHCI_SH + bool "EHCI support for SuperH USB controller" + depends on USB_EHCI_HCD && SUPERH + ---help--- + Enables support for the on-chip EHCI controller on the SuperH. + If you use the PCI EHCI controller, this option is not necessary. + config USB_W90X900_EHCI bool "W90X900(W90P910) EHCI support" depends on USB_EHCI_HCD && ARCH_W90X900 @@ -326,6 +333,13 @@ config USB_OHCI_HCD_SSB If unsure, say N. +config USB_OHCI_SH + bool "OHCI support for SuperH USB controller" + depends on USB_OHCI_HCD && SUPERH + ---help--- + Enables support for the on-chip OHCI controller on the SuperH. + If you use the PCI OHCI controller, this option is not necessary. + config USB_CNS3XXX_OHCI bool "Cavium CNS3XXX OHCI Module" depends on USB_OHCI_HCD && ARCH_CNS3XXX diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index e6277536f392..cfeb24b3ee09 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1180,7 +1180,7 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_mxc_driver #endif -#ifdef CONFIG_CPU_SUBTYPE_SH7786 +#ifdef CONFIG_USB_EHCI_SH #include "ehci-sh.c" #define PLATFORM_DRIVER ehci_hcd_sh_driver #endif diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 7b791bf1e7b4..fb035751e4b2 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1059,10 +1059,7 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ohci_hcd_da8xx_driver #endif -#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ - defined(CONFIG_CPU_SUBTYPE_SH7721) || \ - defined(CONFIG_CPU_SUBTYPE_SH7763) || \ - defined(CONFIG_CPU_SUBTYPE_SH7786) +#ifdef CONFIG_USB_OHCI_SH #include "ohci-sh.c" #define PLATFORM_DRIVER ohci_hcd_sh_driver #endif -- cgit v1.2.3 From 751b3840d216f1ecd3b91ff5251bf7703b690cd8 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 1 Mar 2011 13:12:47 +0800 Subject: pcmcia: synclink_cs: fix prototype for mgslpc_ioctl() The ioctl file pointer was removed in commit 6caa76 "tty: now phase out the ioctl file pointer for good". Thus fix the prototype for mgslpc_ioctl() and eliminate below warning: CC [M] drivers/char/pcmcia/synclink_cs.o drivers/char/pcmcia/synclink_cs.c:2787: warning: initialization from incompatible pointer type Signed-off-by: Axel Lin Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/char/pcmcia/synclink_cs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 02127cad0980..beca80bb9bdb 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -2222,13 +2222,12 @@ static int mgslpc_get_icount(struct tty_struct *tty, * Arguments: * * tty pointer to tty instance data - * file pointer to associated file object for device * cmd IOCTL command code * arg command argument/context * * Return Value: 0 if success, otherwise error code */ -static int mgslpc_ioctl(struct tty_struct *tty, struct file * file, +static int mgslpc_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data; -- cgit v1.2.3 From ff31c54c9d15261ca4780cd0ab5183589438143f Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 1 Mar 2011 10:56:54 +0100 Subject: staging: brcm80211: remove usage of struct osl_info for register access Register access to the device uses a flag in struct osl_info to determine whether to use memory mapped access or not. This check was not needed as it boils down to memory mapped for brcmsmac driver and not for brcmfmac driver. Only use of struct osl_info is reduced to keeping track of the number of allocated sk_buffs within the driver(s). Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 6 +- .../staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c | 170 +++---- .../staging/brcm80211/brcmsmac/phy/wlc_phy_int.h | 2 +- .../staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c | 44 +- drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c | 50 +- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 6 +- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 312 +++++++------ drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 78 ++-- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h | 2 +- drivers/staging/brcm80211/include/bcmutils.h | 8 +- drivers/staging/brcm80211/include/osl.h | 24 +- drivers/staging/brcm80211/util/aiutils.c | 52 +-- drivers/staging/brcm80211/util/bcmotp.c | 30 +- drivers/staging/brcm80211/util/bcmsrom.c | 14 +- drivers/staging/brcm80211/util/hnddma.c | 114 ++--- drivers/staging/brcm80211/util/hndpmu.c | 507 ++++++++++----------- drivers/staging/brcm80211/util/nicpci.c | 50 +- drivers/staging/brcm80211/util/nvram/nvram_ro.c | 5 +- drivers/staging/brcm80211/util/sbutils.c | 12 +- drivers/staging/brcm80211/util/siutils.c | 96 ++-- 20 files changed, 782 insertions(+), 800 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 67f6127498bd..65015b85b10e 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -391,7 +391,7 @@ static bool dhd_readahead; do { \ retryvar = 0; \ do { \ - regvar = R_REG(bus->dhd->osh, regaddr); \ + regvar = R_REG(regaddr); \ } while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \ if (retryvar) { \ bus->regfails += (retryvar-1); \ @@ -407,7 +407,7 @@ do { \ do { \ retryvar = 0; \ do { \ - W_REG(bus->dhd->osh, regaddr, regval); \ + W_REG(regaddr, regval); \ } while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \ if (retryvar) { \ bus->regfails += (retryvar-1); \ @@ -5370,7 +5370,7 @@ dhdsdio_probe_attach(struct dhd_bus *bus, struct osl_info *osh, void *sdh, bus->sdpcmrev = si_corerev(bus->sih); /* Set core control so an SDIO reset does a backplane reset */ - OR_REG(osh, &bus->regs->corecontrol, CC_BPRESEN); + OR_REG(&bus->regs->corecontrol, CC_BPRESEN); pktq_init(&bus->txq, (PRIOMASK + 1), QLEN); diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c index faca5e5449f7..35b43677d213 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c @@ -212,7 +212,7 @@ void wlc_radioreg_exit(wlc_phy_t *pih) phy_info_t *pi = (phy_info_t *) pih; volatile u16 dummy; - dummy = R_REG(pi->sh->osh, &pi->regs->phyversion); + dummy = R_REG(&pi->regs->phyversion); pi->phy_wreg = 0; wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, 0); } @@ -248,23 +248,23 @@ u16 read_radio_reg(phy_info_t *pi, u16 addr) if ((D11REV_GE(pi->sh->corerev, 24)) || (D11REV_IS(pi->sh->corerev, 22) && (pi->pubpi.phy_type != PHY_TYPE_SSN))) { - W_REG(pi->sh->osh, &pi->regs->radioregaddr, addr); + W_REG(&pi->regs->radioregaddr, addr); #ifdef __mips__ - (void)R_REG(pi->sh->osh, &pi->regs->radioregaddr); + (void)R_REG(&pi->regs->radioregaddr); #endif - data = R_REG(pi->sh->osh, &pi->regs->radioregdata); + data = R_REG(&pi->regs->radioregdata); } else { - W_REG(pi->sh->osh, &pi->regs->phy4waddr, addr); + W_REG(&pi->regs->phy4waddr, addr); #ifdef __mips__ - (void)R_REG(pi->sh->osh, &pi->regs->phy4waddr); + (void)R_REG(&pi->regs->phy4waddr); #endif #ifdef __ARM_ARCH_4T__ __asm__(" .align 4 "); __asm__(" nop "); - data = R_REG(pi->sh->osh, &pi->regs->phy4wdatalo); + data = R_REG(&pi->regs->phy4wdatalo); #else - data = R_REG(pi->sh->osh, &pi->regs->phy4wdatalo); + data = R_REG(&pi->regs->phy4wdatalo); #endif } @@ -286,22 +286,22 @@ void write_radio_reg(phy_info_t *pi, u16 addr, u16 val) (D11REV_IS(pi->sh->corerev, 22) && (pi->pubpi.phy_type != PHY_TYPE_SSN))) { - W_REG(osh, &pi->regs->radioregaddr, addr); + W_REG(&pi->regs->radioregaddr, addr); #ifdef __mips__ - (void)R_REG(osh, &pi->regs->radioregaddr); + (void)R_REG(&pi->regs->radioregaddr); #endif - W_REG(osh, &pi->regs->radioregdata, val); + W_REG(&pi->regs->radioregdata, val); } else { - W_REG(osh, &pi->regs->phy4waddr, addr); + W_REG(&pi->regs->phy4waddr, addr); #ifdef __mips__ - (void)R_REG(osh, &pi->regs->phy4waddr); + (void)R_REG(&pi->regs->phy4waddr); #endif - W_REG(osh, &pi->regs->phy4wdatalo, val); + W_REG(&pi->regs->phy4wdatalo, val); } if (pi->sh->bustype == PCI_BUS) { if (++pi->phy_wreg >= pi->phy_wreg_limit) { - (void)R_REG(osh, &pi->regs->maccontrol); + (void)R_REG(&pi->regs->maccontrol); pi->phy_wreg = 0; } } @@ -317,31 +317,31 @@ static u32 read_radio_id(phy_info_t *pi) if (D11REV_GE(pi->sh->corerev, 24)) { u32 b0, b1, b2; - W_REG(pi->sh->osh, &pi->regs->radioregaddr, 0); + W_REG(&pi->regs->radioregaddr, 0); #ifdef __mips__ - (void)R_REG(pi->sh->osh, &pi->regs->radioregaddr); + (void)R_REG(&pi->regs->radioregaddr); #endif - b0 = (u32) R_REG(pi->sh->osh, &pi->regs->radioregdata); - W_REG(pi->sh->osh, &pi->regs->radioregaddr, 1); + b0 = (u32) R_REG(&pi->regs->radioregdata); + W_REG(&pi->regs->radioregaddr, 1); #ifdef __mips__ - (void)R_REG(pi->sh->osh, &pi->regs->radioregaddr); + (void)R_REG(&pi->regs->radioregaddr); #endif - b1 = (u32) R_REG(pi->sh->osh, &pi->regs->radioregdata); - W_REG(pi->sh->osh, &pi->regs->radioregaddr, 2); + b1 = (u32) R_REG(&pi->regs->radioregdata); + W_REG(&pi->regs->radioregaddr, 2); #ifdef __mips__ - (void)R_REG(pi->sh->osh, &pi->regs->radioregaddr); + (void)R_REG(&pi->regs->radioregaddr); #endif - b2 = (u32) R_REG(pi->sh->osh, &pi->regs->radioregdata); + b2 = (u32) R_REG(&pi->regs->radioregdata); id = ((b0 & 0xf) << 28) | (((b2 << 8) | b1) << 12) | ((b0 >> 4) & 0xf); } else { - W_REG(pi->sh->osh, &pi->regs->phy4waddr, RADIO_IDCODE); + W_REG(&pi->regs->phy4waddr, RADIO_IDCODE); #ifdef __mips__ - (void)R_REG(pi->sh->osh, &pi->regs->phy4waddr); + (void)R_REG(&pi->regs->phy4waddr); #endif - id = (u32) R_REG(pi->sh->osh, &pi->regs->phy4wdatalo); - id |= (u32) R_REG(pi->sh->osh, &pi->regs->phy4wdatahi) << 16; + id = (u32) R_REG(&pi->regs->phy4wdatalo); + id |= (u32) R_REG(&pi->regs->phy4wdatahi) << 16; } pi->phy_wreg = 0; return id; @@ -393,13 +393,13 @@ void mod_radio_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val) void write_phy_channel_reg(phy_info_t *pi, uint val) { - W_REG(pi->sh->osh, &pi->regs->phychannel, val); + W_REG(&pi->regs->phychannel, val); } #if defined(BCMDBG) static bool wlc_phy_war41476(phy_info_t *pi) { - u32 mc = R_REG(pi->sh->osh, &pi->regs->maccontrol); + u32 mc = R_REG(&pi->regs->maccontrol); return ((mc & MCTL_EN_MAC) == 0) || ((mc & MCTL_PHYLOCK) == MCTL_PHYLOCK); @@ -414,9 +414,9 @@ u16 read_phy_reg(phy_info_t *pi, u16 addr) osh = pi->sh->osh; regs = pi->regs; - W_REG(osh, ®s->phyregaddr, addr); + W_REG(®s->phyregaddr, addr); #ifdef __mips__ - (void)R_REG(osh, ®s->phyregaddr); + (void)R_REG(®s->phyregaddr); #endif ASSERT(! @@ -424,7 +424,7 @@ u16 read_phy_reg(phy_info_t *pi, u16 addr) || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi)); pi->phy_wreg = 0; - return R_REG(osh, ®s->phyregdata); + return R_REG(®s->phyregdata); } void write_phy_reg(phy_info_t *pi, u16 addr, u16 val) @@ -436,18 +436,18 @@ void write_phy_reg(phy_info_t *pi, u16 addr, u16 val) regs = pi->regs; #ifdef __mips__ - W_REG(osh, ®s->phyregaddr, addr); - (void)R_REG(osh, ®s->phyregaddr); - W_REG(osh, ®s->phyregdata, val); + W_REG(®s->phyregaddr, addr); + (void)R_REG(®s->phyregaddr); + W_REG(®s->phyregdata, val); if (addr == 0x72) - (void)R_REG(osh, ®s->phyregdata); + (void)R_REG(®s->phyregdata); #else - W_REG(osh, (u32 *)(®s->phyregaddr), + W_REG((u32 *)(®s->phyregaddr), addr | (val << 16)); if (pi->sh->bustype == PCI_BUS) { if (++pi->phy_wreg >= pi->phy_wreg_limit) { pi->phy_wreg = 0; - (void)R_REG(osh, ®s->phyversion); + (void)R_REG(®s->phyversion); } } #endif @@ -461,16 +461,16 @@ void and_phy_reg(phy_info_t *pi, u16 addr, u16 val) osh = pi->sh->osh; regs = pi->regs; - W_REG(osh, ®s->phyregaddr, addr); + W_REG(®s->phyregaddr, addr); #ifdef __mips__ - (void)R_REG(osh, ®s->phyregaddr); + (void)R_REG(®s->phyregaddr); #endif ASSERT(! (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi)); - W_REG(osh, ®s->phyregdata, (R_REG(osh, ®s->phyregdata) & val)); + W_REG(®s->phyregdata, (R_REG(®s->phyregdata) & val)); pi->phy_wreg = 0; } @@ -482,16 +482,16 @@ void or_phy_reg(phy_info_t *pi, u16 addr, u16 val) osh = pi->sh->osh; regs = pi->regs; - W_REG(osh, ®s->phyregaddr, addr); + W_REG(®s->phyregaddr, addr); #ifdef __mips__ - (void)R_REG(osh, ®s->phyregaddr); + (void)R_REG(®s->phyregaddr); #endif ASSERT(! (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi)); - W_REG(osh, ®s->phyregdata, (R_REG(osh, ®s->phyregdata) | val)); + W_REG(®s->phyregdata, (R_REG(®s->phyregdata) | val)); pi->phy_wreg = 0; } @@ -503,17 +503,17 @@ void mod_phy_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val) osh = pi->sh->osh; regs = pi->regs; - W_REG(osh, ®s->phyregaddr, addr); + W_REG(®s->phyregaddr, addr); #ifdef __mips__ - (void)R_REG(osh, ®s->phyregaddr); + (void)R_REG(®s->phyregaddr); #endif ASSERT(! (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi)); - W_REG(osh, ®s->phyregdata, - ((R_REG(osh, ®s->phyregdata) & ~mask) | (val & mask))); + W_REG(®s->phyregdata, + ((R_REG(®s->phyregdata) & ~mask) | (val & mask))); pi->phy_wreg = 0; } @@ -658,7 +658,7 @@ wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, char *vars } wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags); - phyversion = R_REG(osh, &pi->regs->phyversion); + phyversion = R_REG(&pi->regs->phyversion); pi->pubpi.phy_type = PHY_TYPE(phyversion); pi->pubpi.phy_rev = phyversion & PV_PV_MASK; @@ -985,7 +985,7 @@ void WLBANDINITFN(wlc_phy_init) (wlc_phy_t *pih, chanspec_t chanspec) pi->radio_chanspec = chanspec; - mc = R_REG(pi->sh->osh, &pi->regs->maccontrol); + mc = R_REG(&pi->regs->maccontrol); if ((mc & MCTL_EN_MAC) != 0) { ASSERT((const char *) "wlc_phy_init: Called with the MAC running!" == NULL); @@ -1037,7 +1037,7 @@ void wlc_phy_cal_init(wlc_phy_t *pih) phy_info_t *pi = (phy_info_t *) pih; initfn_t cal_init = NULL; - ASSERT((R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC) == 0); + ASSERT((R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) == 0); if (!pi->initialized) { cal_init = pi->pi_fptr.calinit; @@ -1267,34 +1267,34 @@ void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on) }; u32 *dummypkt; - ASSERT((R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC) == 0); + ASSERT((R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) == 0); dummypkt = (u32 *) (ofdm ? ofdmpkt : cckpkt); wlapi_bmac_write_template_ram(pi->sh->physhim, 0, DUMMY_PKT_LEN, dummypkt); - W_REG(pi->sh->osh, ®s->xmtsel, 0); + W_REG(®s->xmtsel, 0); if (D11REV_GE(pi->sh->corerev, 11)) - W_REG(pi->sh->osh, ®s->wepctl, 0x100); + W_REG(®s->wepctl, 0x100); else - W_REG(pi->sh->osh, ®s->wepctl, 0); + W_REG(®s->wepctl, 0); - W_REG(pi->sh->osh, ®s->txe_phyctl, (ofdm ? 1 : 0) | PHY_TXC_ANT_0); + W_REG(®s->txe_phyctl, (ofdm ? 1 : 0) | PHY_TXC_ANT_0); if (ISNPHY(pi) || ISLCNPHY(pi)) { ASSERT(ofdm); - W_REG(pi->sh->osh, ®s->txe_phyctl1, 0x1A02); + W_REG(®s->txe_phyctl1, 0x1A02); } - W_REG(pi->sh->osh, ®s->txe_wm_0, 0); - W_REG(pi->sh->osh, ®s->txe_wm_1, 0); + W_REG(®s->txe_wm_0, 0); + W_REG(®s->txe_wm_1, 0); - W_REG(pi->sh->osh, ®s->xmttplatetxptr, 0); - W_REG(pi->sh->osh, ®s->xmttxcnt, DUMMY_PKT_LEN); + W_REG(®s->xmttplatetxptr, 0); + W_REG(®s->xmttxcnt, DUMMY_PKT_LEN); - W_REG(pi->sh->osh, ®s->xmtsel, ((8 << 8) | (1 << 5) | (1 << 2) | 2)); + W_REG(®s->xmtsel, ((8 << 8) | (1 << 5) | (1 << 2) | 2)); - W_REG(pi->sh->osh, ®s->txe_ctl, 0); + W_REG(®s->txe_ctl, 0); if (!pa_on) { if (ISNPHY(pi)) @@ -1302,11 +1302,11 @@ void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on) } if (ISNPHY(pi) || ISLCNPHY(pi)) - W_REG(pi->sh->osh, ®s->txe_aux, 0xD0); + W_REG(®s->txe_aux, 0xD0); else - W_REG(pi->sh->osh, ®s->txe_aux, ((1 << 5) | (1 << 4))); + W_REG(®s->txe_aux, ((1 << 5) | (1 << 4))); - (void)R_REG(pi->sh->osh, ®s->txe_aux); + (void)R_REG(®s->txe_aux); i = 0; count = ofdm ? 30 : 250; @@ -1316,22 +1316,22 @@ void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on) } while ((i++ < count) - && (R_REG(pi->sh->osh, ®s->txe_status) & (1 << 7))) { + && (R_REG(®s->txe_status) & (1 << 7))) { udelay(10); } i = 0; while ((i++ < 10) - && ((R_REG(pi->sh->osh, ®s->txe_status) & (1 << 10)) == 0)) { + && ((R_REG(®s->txe_status) & (1 << 10)) == 0)) { udelay(10); } i = 0; - while ((i++ < 10) && ((R_REG(pi->sh->osh, ®s->ifsstat) & (1 << 8)))) { + while ((i++ < 10) && ((R_REG(®s->ifsstat) & (1 << 8)))) udelay(10); - } + if (!pa_on) { if (ISNPHY(pi)) wlc_phy_pa_override_nphy(pi, ON); @@ -1396,7 +1396,7 @@ void wlc_phy_switch_radio(wlc_phy_t *pih, bool on) { uint mc; - mc = R_REG(pi->sh->osh, &pi->regs->maccontrol); + mc = R_REG(&pi->regs->maccontrol); } if (ISNPHY(pi)) { @@ -1648,7 +1648,7 @@ void wlc_phy_txpower_target_set(wlc_phy_t *ppi, struct txpwr_limits *txpwr) memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SDM], &txpwr->mcs_40_mimo[0], WLC_NUM_RATES_MCS_2_STREAM); - if (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC) + if (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) mac_enabled = true; if (mac_enabled) @@ -1680,7 +1680,7 @@ int wlc_phy_txpower_set(wlc_phy_t *ppi, uint qdbm, bool override) suspend = (0 == - (R_REG(pi->sh->osh, &pi->regs->maccontrol) & + (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) @@ -2096,18 +2096,18 @@ void wlc_phy_runbist_config(wlc_phy_t *ppi, bool start_end) if (NREV_IS(pi->pubpi.phy_rev, 3) || NREV_IS(pi->pubpi.phy_rev, 4)) { - W_REG(pi->sh->osh, &pi->regs->phyregaddr, 0xa0); - (void)R_REG(pi->sh->osh, &pi->regs->phyregaddr); - rxc = R_REG(pi->sh->osh, &pi->regs->phyregdata); - W_REG(pi->sh->osh, &pi->regs->phyregdata, + W_REG(&pi->regs->phyregaddr, 0xa0); + (void)R_REG(&pi->regs->phyregaddr); + rxc = R_REG(&pi->regs->phyregdata); + W_REG(&pi->regs->phyregdata, (0x1 << 15) | rxc); } } else { if (NREV_IS(pi->pubpi.phy_rev, 3) || NREV_IS(pi->pubpi.phy_rev, 4)) { - W_REG(pi->sh->osh, &pi->regs->phyregaddr, 0xa0); - (void)R_REG(pi->sh->osh, &pi->regs->phyregaddr); - W_REG(pi->sh->osh, &pi->regs->phyregdata, rxc); + W_REG(&pi->regs->phyregaddr, 0xa0); + (void)R_REG(&pi->regs->phyregaddr); + W_REG(&pi->regs->phyregdata, rxc); } wlc_phy_por_inform(ppi); @@ -2234,7 +2234,7 @@ void wlc_phy_txpower_hw_ctrl_set(wlc_phy_t *ppi, bool hwpwrctrl) if (ISNPHY(pi)) { suspend = (0 == - (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); @@ -2476,7 +2476,7 @@ void wlc_phy_ant_rxdiv_set(wlc_phy_t *ppi, u8 val) return; suspend = - (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); @@ -2590,7 +2590,7 @@ wlc_phy_noise_sample_request(wlc_phy_t *pih, u8 reason, u8 ch) wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0); wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0); - OR_REG(pi->sh->osh, &pi->regs->maccommand, + OR_REG(&pi->regs->maccommand, MCMD_BG_NOISE); } else { wlapi_suspend_mac_and_wait(pi->sh->physhim); @@ -2609,7 +2609,7 @@ wlc_phy_noise_sample_request(wlc_phy_t *pih, u8 reason, u8 ch) wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0); wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0); - OR_REG(pi->sh->osh, &pi->regs->maccommand, + OR_REG(&pi->regs->maccommand, MCMD_BG_NOISE); } else { phy_iq_est_t est[PHY_CORE_MAX]; diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h index 72eee9120c2f..0530b1ddb3ca 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h @@ -1159,7 +1159,7 @@ extern void wlc_phy_table_write_nphy(phy_info_t *pi, u32, u32, u32, #define WLC_PHY_WAR_PR51571(pi) \ if (((pi)->sh->bustype == PCI_BUS) && NREV_LT((pi)->pubpi.phy_rev, 3)) \ - (void)R_REG((pi)->sh->osh, &(pi)->regs->maccontrol) + (void)R_REG(&(pi)->regs->maccontrol) extern void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype); extern void wlc_phy_aci_reset_nphy(phy_info_t *pi); diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c index 36dea14b7d7f..825bf767a2d5 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c @@ -2100,7 +2100,7 @@ static void wlc_lcnphy_idle_tssi_est(wlc_phy_t *ppi) idleTssi = read_phy_reg(pi, 0x4ab); suspend = (0 == - (R_REG(pi->sh->osh, &((phy_info_t *) pi)->regs->maccontrol) & + (R_REG(&((phy_info_t *) pi)->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); @@ -2176,7 +2176,7 @@ static void wlc_lcnphy_vbat_temp_sense_setup(phy_info_t *pi, u8 mode) for (i = 0; i < 14; i++) values_to_save[i] = read_phy_reg(pi, tempsense_phy_regs[i]); suspend = - (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); save_txpwrCtrlEn = read_radio_reg(pi, 0x4a4); @@ -2303,7 +2303,7 @@ void WLBANDINITFN(wlc_lcnphy_tx_pwr_ctrl_init) (wlc_phy_t *ppi) phy_info_t *pi = (phy_info_t *) ppi; suspend = - (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); @@ -2989,7 +2989,7 @@ s16 wlc_lcnphy_tempsense_new(phy_info_t *pi, bool mode) if (mode == 1) { suspend = (0 == - (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE); @@ -3036,7 +3036,7 @@ u16 wlc_lcnphy_tempsense(phy_info_t *pi, bool mode) if (mode == 1) { suspend = (0 == - (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE); @@ -3104,7 +3104,7 @@ s8 wlc_lcnphy_vbatsense(phy_info_t *pi, bool mode) if (mode == 1) { suspend = (0 == - (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); wlc_lcnphy_vbat_temp_sense_setup(pi, VBATSENSE); @@ -3459,7 +3459,7 @@ static void wlc_lcnphy_glacial_timer_based_cal(phy_info_t *pi) u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; suspend = - (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); wlc_lcnphy_deaf_mode(pi, true); @@ -3501,7 +3501,7 @@ static void wlc_lcnphy_periodic_cal(phy_info_t *pi) index = pi_lcn->lcnphy_current_index; suspend = - (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) { wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000); @@ -3859,15 +3859,15 @@ wlc_lcnphy_samp_cap(phy_info_t *pi, int clip_detect_algo, u16 thresh, timer = 0; old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); - curval1 = R_REG(pi->sh->osh, &pi->regs->psm_corectlsts); + curval1 = R_REG(&pi->regs->psm_corectlsts); ptr[130] = 0; - W_REG(pi->sh->osh, &pi->regs->psm_corectlsts, ((1 << 6) | curval1)); + W_REG(&pi->regs->psm_corectlsts, ((1 << 6) | curval1)); - W_REG(pi->sh->osh, &pi->regs->smpl_clct_strptr, 0x7E00); - W_REG(pi->sh->osh, &pi->regs->smpl_clct_stpptr, 0x8000); + W_REG(&pi->regs->smpl_clct_strptr, 0x7E00); + W_REG(&pi->regs->smpl_clct_stpptr, 0x8000); udelay(20); - curval2 = R_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param); - W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, curval2 | 0x30); + curval2 = R_REG(&pi->regs->psm_phy_hdr_param); + W_REG(&pi->regs->psm_phy_hdr_param, curval2 | 0x30); write_phy_reg(pi, 0x555, 0x0); write_phy_reg(pi, 0x5a6, 0x5); @@ -3884,19 +3884,19 @@ wlc_lcnphy_samp_cap(phy_info_t *pi, int clip_detect_algo, u16 thresh, sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); write_phy_reg(pi, 0x6da, (u32) (sslpnCalibClkEnCtrl | 0x2008)); - stpptr = R_REG(pi->sh->osh, &pi->regs->smpl_clct_stpptr); - curptr = R_REG(pi->sh->osh, &pi->regs->smpl_clct_curptr); + stpptr = R_REG(&pi->regs->smpl_clct_stpptr); + curptr = R_REG(&pi->regs->smpl_clct_curptr); do { udelay(10); - curptr = R_REG(pi->sh->osh, &pi->regs->smpl_clct_curptr); + curptr = R_REG(&pi->regs->smpl_clct_curptr); timer++; } while ((curptr != stpptr) && (timer < 500)); - W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, 0x2); + W_REG(&pi->regs->psm_phy_hdr_param, 0x2); strptr = 0x7E00; - W_REG(pi->sh->osh, &pi->regs->tplatewrptr, strptr); + W_REG(&pi->regs->tplatewrptr, strptr); while (strptr < 0x8000) { - val = R_REG(pi->sh->osh, &pi->regs->tplatewrdata); + val = R_REG(&pi->regs->tplatewrdata); imag = ((val >> 16) & 0x3ff); real = ((val) & 0x3ff); if (imag > 511) { @@ -3919,8 +3919,8 @@ wlc_lcnphy_samp_cap(phy_info_t *pi, int clip_detect_algo, u16 thresh, } write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl); - W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, curval2); - W_REG(pi->sh->osh, &pi->regs->psm_corectlsts, curval1); + W_REG(&pi->regs->psm_phy_hdr_param, curval2); + W_REG(&pi->regs->psm_corectlsts, curval1); } static void wlc_lcnphy_tx_iqlo_soft_cal_full(phy_info_t *pi) diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c index af8291f1bc0f..a76fae2ba83f 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c @@ -14569,11 +14569,11 @@ void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi) &origidx, &intr_val); ASSERT(regs != NULL); - d11_clk_ctl_st = R_REG(pi->sh->osh, ®s->clk_ctl_st); - AND_REG(pi->sh->osh, ®s->clk_ctl_st, + d11_clk_ctl_st = R_REG(®s->clk_ctl_st); + AND_REG(®s->clk_ctl_st, ~(CCS_FORCEHT | CCS_HTAREQ)); - W_REG(pi->sh->osh, ®s->clk_ctl_st, d11_clk_ctl_st); + W_REG(®s->clk_ctl_st, d11_clk_ctl_st); si_restore_core(pi->sh->sih, origidx, intr_val); } @@ -14964,7 +14964,7 @@ static void wlc_phy_resetcca_nphy(phy_info_t *pi) { u16 val; - ASSERT(0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + ASSERT(0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON); @@ -15057,7 +15057,7 @@ void wlc_phy_rxcore_setstate_nphy(wlc_phy_t *pih, u8 rxcore_bitmask) return; suspend = - (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); @@ -18983,28 +18983,28 @@ wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chanspec, val = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand; if (CHSPEC_IS5G(chanspec) && !val) { - val = R_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param); - W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, + val = R_REG(&pi->regs->psm_phy_hdr_param); + W_REG(&pi->regs->psm_phy_hdr_param, (val | MAC_PHY_FORCE_CLK)); or_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG), (BBCFG_RESETCCA | BBCFG_RESETRX)); - W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, val); + W_REG(&pi->regs->psm_phy_hdr_param, val); or_phy_reg(pi, 0x09, NPHY_BandControl_currentBand); } else if (!CHSPEC_IS5G(chanspec) && val) { and_phy_reg(pi, 0x09, ~NPHY_BandControl_currentBand); - val = R_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param); - W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, + val = R_REG(&pi->regs->psm_phy_hdr_param); + W_REG(&pi->regs->psm_phy_hdr_param, (val | MAC_PHY_FORCE_CLK)); and_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG), (u16) (~(BBCFG_RESETCCA | BBCFG_RESETRX))); - W_REG(pi->sh->osh, &pi->regs->psm_phy_hdr_param, val); + W_REG(&pi->regs->psm_phy_hdr_param, val); } write_phy_reg(pi, 0x1ce, ci->PHY_BW1a); @@ -19095,15 +19095,15 @@ wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chanspec, if (spuravoid == 1) { - W_REG(pi->sh->osh, &pi->regs->tsf_clk_frac_l, + W_REG(&pi->regs->tsf_clk_frac_l, 0x5341); - W_REG(pi->sh->osh, &pi->regs->tsf_clk_frac_h, + W_REG(&pi->regs->tsf_clk_frac_h, 0x8); } else { - W_REG(pi->sh->osh, &pi->regs->tsf_clk_frac_l, + W_REG(&pi->regs->tsf_clk_frac_l, 0x8889); - W_REG(pi->sh->osh, &pi->regs->tsf_clk_frac_h, + W_REG(&pi->regs->tsf_clk_frac_h, 0x8); } } @@ -19609,13 +19609,13 @@ void wlc_phy_antsel_init(wlc_phy_t *ppi, bool lut_init) si_gpiocontrol(pi->sh->sih, mask, mask, GPIO_DRV_PRIORITY); - mc = R_REG(pi->sh->osh, &pi->regs->maccontrol); + mc = R_REG(&pi->regs->maccontrol); mc &= ~MCTL_GPOUT_SEL_MASK; - W_REG(pi->sh->osh, &pi->regs->maccontrol, mc); + W_REG(&pi->regs->maccontrol, mc); - OR_REG(pi->sh->osh, &pi->regs->psm_gpio_oe, mask); + OR_REG(&pi->regs->psm_gpio_oe, mask); - AND_REG(pi->sh->osh, &pi->regs->psm_gpio_out, ~mask); + AND_REG(&pi->regs->psm_gpio_out, ~mask); if (lut_init) { write_phy_reg(pi, 0xf8, 0x02d8); @@ -19633,7 +19633,7 @@ u16 wlc_phy_classifier_nphy(phy_info_t *pi, u16 mask, u16 val) if (D11REV_IS(pi->sh->corerev, 16)) { suspended = - (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC) ? + (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) ? false : true; if (!suspended) wlapi_suspend_mac_and_wait(pi->sh->physhim); @@ -27257,7 +27257,7 @@ static void wlc_phy_a4(phy_info_t *pi, bool full_cal) return; phy_b3 = - (0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!phy_b3) { wlapi_suspend_mac_and_wait(pi->sh->physhim); } @@ -28221,7 +28221,7 @@ void wlc_phy_txpower_recalc_target_nphy(phy_info_t *pi) if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) { wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK); - (void)R_REG(pi->sh->osh, &pi->regs->maccontrol); + (void)R_REG(&pi->regs->maccontrol); udelay(1); } @@ -28492,7 +28492,7 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(phy_info_t *pi) if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) { wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK); - (void)R_REG(pi->sh->osh, &pi->regs->maccontrol); + (void)R_REG(&pi->regs->maccontrol); udelay(1); } @@ -28649,7 +28649,7 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(phy_info_t *pi) if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) { wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK); - (void)R_REG(pi->sh->osh, &pi->regs->maccontrol); + (void)R_REG(&pi->regs->maccontrol); udelay(1); } @@ -29194,7 +29194,7 @@ void wlc_phy_stay_in_carriersearch_nphy(phy_info_t *pi, bool enable) { u16 clip_off[] = { 0xffff, 0xffff }; - ASSERT(0 == (R_REG(pi->sh->osh, &pi->regs->maccontrol) & MCTL_EN_MAC)); + ASSERT(0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (enable) { if (pi->nphy_deaf_count == 0) { diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index b198797fa307..2b25c0d45875 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -920,9 +920,7 @@ wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, u8 status_delay = 0; /* wait till the next 8 bytes of txstatus is available */ - while (((s1 = - R_REG(wlc->osh, - &wlc->regs->frmtxstatus)) & TXS_V) == 0) { + while (((s1 = R_REG(&wlc->regs->frmtxstatus)) & TXS_V) == 0) { udelay(1); status_delay++; if (status_delay > 10) { @@ -933,7 +931,7 @@ wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, ASSERT(!(s1 & TX_STATUS_INTERMEDIATE)); ASSERT(s1 & TX_STATUS_AMPDU); - s2 = R_REG(wlc->osh, &wlc->regs->frmtxstatus2); + s2 = R_REG(&wlc->regs->frmtxstatus2); } wlc_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 353f1ea3694c..0cb94332af30 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -193,11 +193,11 @@ static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw, if (shortslot) { /* 11g short slot: 11a timing */ - W_REG(osh, ®s->ifs_slot, 0x0207); /* APHY_SLOT_TIME */ + W_REG(®s->ifs_slot, 0x0207); /* APHY_SLOT_TIME */ wlc_bmac_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME); } else { /* 11g long slot: 11b timing */ - W_REG(osh, ®s->ifs_slot, 0x0212); /* BPHY_SLOT_TIME */ + W_REG(®s->ifs_slot, 0x0212); /* BPHY_SLOT_TIME */ wlc_bmac_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME); } } @@ -240,7 +240,7 @@ static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit) ASSERT(bandunit != wlc_hw->band->bandunit); ASSERT(si_iscoreup(wlc_hw->sih)); - ASSERT((R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol) & MCTL_EN_MAC) == + ASSERT((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) == 0); /* disable interrupts */ @@ -371,7 +371,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) if (macintstatus & MI_ATIMWINEND) { WL_TRACE("wlc_isr: end of ATIM window\n"); - OR_REG(wlc_hw->osh, ®s->maccommand, wlc->qvalid); + OR_REG(®s->maccommand, wlc->qvalid); wlc->qvalid = 0; } @@ -415,7 +415,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) /* gptimer timeout */ if (macintstatus & MI_TO) { - W_REG(wlc_hw->osh, ®s->gptimer, 0); + W_REG(®s->gptimer, 0); } if (macintstatus & MI_RFDISABLE) { @@ -855,7 +855,7 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G; wlc->core->coreidx = si_coreidx(wlc_hw->sih); - wlc_hw->machwcap = R_REG(wlc_hw->osh, ®s->machwcap); + wlc_hw->machwcap = R_REG(®s->machwcap); wlc_hw->machwcap_backup = wlc_hw->machwcap; /* init tx fifo size */ @@ -1240,7 +1240,7 @@ int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw) /* Reset and disable the core */ if (si_iscoreup(wlc_hw->sih)) { - if (R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol) & + if (R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) wlc_suspend_mac_and_wait(wlc_hw->wlc); callbacks += wl_reset(wlc_hw->wlc->wl); @@ -1292,33 +1292,29 @@ static void wlc_clkctl_clk(struct wlc_hw_info *wlc_hw, uint mode) if (wlc_hw->clk) { if (mode == CLK_FAST) { - OR_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, + OR_REG(&wlc_hw->regs->clk_ctl_st, CCS_FORCEHT); udelay(64); SPINWAIT(((R_REG - (wlc_hw->osh, - &wlc_hw->regs-> + (&wlc_hw->regs-> clk_ctl_st) & CCS_HTAVAIL) == 0), PMU_MAX_TRANSITION_DLY); ASSERT(R_REG - (wlc_hw->osh, - &wlc_hw->regs-> + (&wlc_hw->regs-> clk_ctl_st) & CCS_HTAVAIL); } else { if ((wlc_hw->sih->pmurev == 0) && (R_REG - (wlc_hw->osh, - &wlc_hw->regs-> + (&wlc_hw->regs-> clk_ctl_st) & (CCS_FORCEHT | CCS_HTAREQ))) SPINWAIT(((R_REG - (wlc_hw->osh, - &wlc_hw->regs-> + (&wlc_hw->regs-> clk_ctl_st) & CCS_HTAVAIL) == 0), PMU_MAX_TRANSITION_DLY); - AND_REG(wlc_hw->osh, &wlc_hw->regs->clk_ctl_st, + AND_REG(&wlc_hw->regs->clk_ctl_st, ~CCS_FORCEHT); } } @@ -1530,7 +1526,7 @@ static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw) maccontrol |= MCTL_INFRA; } - W_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol, maccontrol); + W_REG(&wlc_hw->regs->maccontrol, maccontrol); } void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, u32 override_bit) @@ -1625,12 +1621,12 @@ wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, osh = wlc_hw->osh; - W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, ®s->objdata, mac_hm); - W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1))); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, objdata16, mac_l); + W_REG(®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); + (void)R_REG(®s->objaddr); + W_REG(®s->objdata, mac_hm); + W_REG(®s->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1))); + (void)R_REG(®s->objaddr); + W_REG(objdata16, mac_l); } /* @@ -1658,10 +1654,10 @@ wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset, osh = wlc_hw->osh; /* enter the MAC addr into the RXE match registers */ - W_REG(osh, ®s->rcm_ctl, RCM_INC_DATA | match_reg_offset); - W_REG(osh, ®s->rcm_mat_data, mac_l); - W_REG(osh, ®s->rcm_mat_data, mac_m); - W_REG(osh, ®s->rcm_mat_data, mac_h); + W_REG(®s->rcm_ctl, RCM_INC_DATA | match_reg_offset); + W_REG(®s->rcm_mat_data, mac_l); + W_REG(®s->rcm_mat_data, mac_m); + W_REG(®s->rcm_mat_data, mac_h); } @@ -1686,13 +1682,13 @@ wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, int len, ASSERT(IS_ALIGNED(len, sizeof(u32))); ASSERT((offset & ~0xffff) == 0); - W_REG(osh, ®s->tplatewrptr, offset); + W_REG(®s->tplatewrptr, offset); /* if MCTL_BIGEND bit set in mac control register, * the chip swaps data in fifo, as well as data in * template ram */ - be_bit = (R_REG(osh, ®s->maccontrol) & MCTL_BIGEND) != 0; + be_bit = (R_REG(®s->maccontrol) & MCTL_BIGEND) != 0; while (len > 0) { memcpy(&word, buf, sizeof(u32)); @@ -1702,7 +1698,7 @@ wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, int len, else word = cpu_to_le32(word); - W_REG(osh, ®s->tplatewrdata, word); + W_REG(®s->tplatewrdata, word); buf = (u8 *) buf + sizeof(u32); len -= sizeof(u32); @@ -1716,9 +1712,9 @@ void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin) osh = wlc_hw->osh; wlc_hw->band->CWmin = newmin; - W_REG(osh, &wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMIN); - (void)R_REG(osh, &wlc_hw->regs->objaddr); - W_REG(osh, &wlc_hw->regs->objdata, newmin); + W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMIN); + (void)R_REG(&wlc_hw->regs->objaddr); + W_REG(&wlc_hw->regs->objdata, newmin); } void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax) @@ -1728,9 +1724,9 @@ void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax) osh = wlc_hw->osh; wlc_hw->band->CWmax = newmax; - W_REG(osh, &wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMAX); - (void)R_REG(osh, &wlc_hw->regs->objaddr); - W_REG(osh, &wlc_hw->regs->objdata, newmax); + W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMAX); + (void)R_REG(&wlc_hw->regs->objaddr); + W_REG(&wlc_hw->regs->objdata, newmax); } void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw) @@ -1765,7 +1761,7 @@ wlc_write_hw_bcntemplate0(struct wlc_hw_info *wlc_hw, void *bcn, int len) ASSERT(len < 65536); wlc_bmac_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len); /* mark beacon0 valid */ - OR_REG(wlc_hw->osh, ®s->maccommand, MCMD_BCN0VLD); + OR_REG(®s->maccommand, MCMD_BCN0VLD); } static void @@ -1779,7 +1775,7 @@ wlc_write_hw_bcntemplate1(struct wlc_hw_info *wlc_hw, void *bcn, int len) ASSERT(len < 65536); wlc_bmac_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len); /* mark beacon1 valid */ - OR_REG(wlc_hw->osh, ®s->maccommand, MCMD_BCN1VLD); + OR_REG(®s->maccommand, MCMD_BCN1VLD); } /* mac is assumed to be suspended at this point */ @@ -1794,11 +1790,11 @@ wlc_bmac_write_hw_bcntemplates(struct wlc_hw_info *wlc_hw, void *bcn, int len, wlc_write_hw_bcntemplate1(wlc_hw, bcn, len); } else { /* bcn 0 */ - if (!(R_REG(wlc_hw->osh, ®s->maccommand) & MCMD_BCN0VLD)) + if (!(R_REG(®s->maccommand) & MCMD_BCN0VLD)) wlc_write_hw_bcntemplate0(wlc_hw, bcn, len); /* bcn 1 */ else if (! - (R_REG(wlc_hw->osh, ®s->maccommand) & MCMD_BCN1VLD)) + (R_REG(®s->maccommand) & MCMD_BCN1VLD)) wlc_write_hw_bcntemplate1(wlc_hw, bcn, len); else /* one template should always have been available */ ASSERT(0); @@ -1832,10 +1828,10 @@ WLBANDINITFN(wlc_bmac_bsinit) (struct wlc_info *wlc, chanspec_t chanspec) wlc_hw->unit, wlc_hw->band->bandunit); /* sanity check */ - if (PHY_TYPE(R_REG(wlc_hw->osh, &wlc_hw->regs->phyversion)) != + if (PHY_TYPE(R_REG(&wlc_hw->regs->phyversion)) != PHY_TYPE_LCNXN) ASSERT((uint) - PHY_TYPE(R_REG(wlc_hw->osh, &wlc_hw->regs->phyversion)) + PHY_TYPE(R_REG(&wlc_hw->regs->phyversion)) == wlc_hw->band->phytype); wlc_ucode_bsinit(wlc_hw); @@ -2011,7 +2007,7 @@ WLBANDINITFN(wlc_bmac_setband) (struct wlc_hw_info *wlc_hw, uint bandunit, wl_intrsrestore(wlc->wl, macintmask); /* ucode should still be suspended.. */ - ASSERT((R_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol) & MCTL_EN_MAC) == + ASSERT((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) == 0); } @@ -2128,7 +2124,7 @@ bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw) wlc_mctrl_reset(wlc_hw); } - v = ((R_REG(wlc_hw->osh, &wlc_hw->regs->phydebug) & PDBG_RFD) != 0); + v = ((R_REG(&wlc_hw->regs->phydebug) & PDBG_RFD) != 0); /* put core back into reset */ if (!clk) @@ -2304,11 +2300,11 @@ static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw) txfifo_cmd = TXFIFOCMD_RESET_MASK | (fifo_nu << TXFIFOCMD_FIFOSEL_SHIFT); - W_REG(osh, ®s->xmtfifocmd, txfifo_cmd); - W_REG(osh, ®s->xmtfifodef, txfifo_def); - W_REG(osh, ®s->xmtfifodef1, txfifo_def1); + W_REG(®s->xmtfifocmd, txfifo_cmd); + W_REG(®s->xmtfifodef, txfifo_def); + W_REG(®s->xmtfifodef1, txfifo_def1); - W_REG(osh, ®s->xmtfifocmd, txfifo_cmd); + W_REG(®s->xmtfifocmd, txfifo_cmd); txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu]; } @@ -2363,14 +2359,14 @@ static void wlc_coreinit(struct wlc_info *wlc) fifosz_fixup = true; /* let the PSM run to the suspended state, set mode to BSS STA */ - W_REG(osh, ®s->macintstatus, -1); + W_REG(®s->macintstatus, -1); wlc_bmac_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_INFRA | MCTL_PSM_RUN | MCTL_WAKE)); /* wait for ucode to self-suspend after auto-init */ - SPINWAIT(((R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD) == 0), + SPINWAIT(((R_REG(®s->macintstatus) & MI_MACSSPNDD) == 0), 1000 * 1000); - if ((R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD) == 0) + if ((R_REG(®s->macintstatus) & MI_MACSSPNDD) == 0) WL_ERROR("wl%d: wlc_coreinit: ucode did not self-suspend!\n", wlc_hw->unit); @@ -2441,7 +2437,7 @@ static void wlc_coreinit(struct wlc_info *wlc) } /* make sure we can still talk to the mac */ - ASSERT(R_REG(osh, ®s->maccontrol) != 0xffffffff); + ASSERT(R_REG(®s->maccontrol) != 0xffffffff); /* band-specific inits done by wlc_bsinit() */ @@ -2450,7 +2446,7 @@ static void wlc_coreinit(struct wlc_info *wlc) wlc_bmac_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT); /* enable one rx interrupt per received frame */ - W_REG(osh, ®s->intrcvlazy[0], (1 << IRL_FC_SHIFT)); + W_REG(®s->intrcvlazy[0], (1 << IRL_FC_SHIFT)); /* set the station mode (BSS STA) */ wlc_bmac_mctrl(wlc_hw, @@ -2459,19 +2455,19 @@ static void wlc_coreinit(struct wlc_info *wlc) /* set up Beacon interval */ bcnint_us = 0x8000 << 10; - W_REG(osh, ®s->tsf_cfprep, (bcnint_us << CFPREP_CBI_SHIFT)); - W_REG(osh, ®s->tsf_cfpstart, bcnint_us); - W_REG(osh, ®s->macintstatus, MI_GP1); + W_REG(®s->tsf_cfprep, (bcnint_us << CFPREP_CBI_SHIFT)); + W_REG(®s->tsf_cfpstart, bcnint_us); + W_REG(®s->macintstatus, MI_GP1); /* write interrupt mask */ - W_REG(osh, ®s->intctrlregs[RX_FIFO].intmask, DEF_RXINTMASK); + W_REG(®s->intctrlregs[RX_FIFO].intmask, DEF_RXINTMASK); /* allow the MAC to control the PHY clock (dynamic on/off) */ wlc_bmac_macphyclk_set(wlc_hw, ON); /* program dynamic clock control fast powerup delay register */ wlc->fastpwrup_dly = si_clkctl_fast_pwrup_delay(wlc_hw->sih); - W_REG(osh, ®s->scc_fastpwrup_dly, wlc->fastpwrup_dly); + W_REG(®s->scc_fastpwrup_dly, wlc->fastpwrup_dly); /* tell the ucode the corerev */ wlc_bmac_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev); @@ -2484,19 +2480,19 @@ static void wlc_coreinit(struct wlc_info *wlc) machwcap >> 16) & 0xffff)); /* write retry limits to SCR, this done after PSM init */ - W_REG(osh, ®s->objaddr, OBJADDR_SCR_SEL | S_DOT11_SRC_LMT); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, ®s->objdata, wlc_hw->SRL); - W_REG(osh, ®s->objaddr, OBJADDR_SCR_SEL | S_DOT11_LRC_LMT); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, ®s->objdata, wlc_hw->LRL); + W_REG(®s->objaddr, OBJADDR_SCR_SEL | S_DOT11_SRC_LMT); + (void)R_REG(®s->objaddr); + W_REG(®s->objdata, wlc_hw->SRL); + W_REG(®s->objaddr, OBJADDR_SCR_SEL | S_DOT11_LRC_LMT); + (void)R_REG(®s->objaddr); + W_REG(®s->objdata, wlc_hw->LRL); /* write rate fallback retry limits */ wlc_bmac_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL); wlc_bmac_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL); - AND_REG(osh, ®s->ifs_ctl, 0x0FFF); - W_REG(osh, ®s->ifs_aifsn, EDCF_AIFSN_MIN); + AND_REG(®s->ifs_ctl, 0x0FFF); + W_REG(®s->ifs_aifsn, EDCF_AIFSN_MIN); /* dma initializations */ wlc->txpend16165war = 0; @@ -2535,22 +2531,22 @@ void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode) if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || (wlc_hw->sih->chip == BCM43225_CHIP_ID)) { if (spurmode == WL_SPURAVOID_ON2) { /* 126Mhz */ - W_REG(osh, ®s->tsf_clk_frac_l, 0x2082); - W_REG(osh, ®s->tsf_clk_frac_h, 0x8); + W_REG(®s->tsf_clk_frac_l, 0x2082); + W_REG(®s->tsf_clk_frac_h, 0x8); } else if (spurmode == WL_SPURAVOID_ON1) { /* 123Mhz */ - W_REG(osh, ®s->tsf_clk_frac_l, 0x5341); - W_REG(osh, ®s->tsf_clk_frac_h, 0x8); + W_REG(®s->tsf_clk_frac_l, 0x5341); + W_REG(®s->tsf_clk_frac_h, 0x8); } else { /* 120Mhz */ - W_REG(osh, ®s->tsf_clk_frac_l, 0x8889); - W_REG(osh, ®s->tsf_clk_frac_h, 0x8); + W_REG(®s->tsf_clk_frac_l, 0x8889); + W_REG(®s->tsf_clk_frac_h, 0x8); } } else if (WLCISLCNPHY(wlc_hw->band)) { if (spurmode == WL_SPURAVOID_ON1) { /* 82Mhz */ - W_REG(osh, ®s->tsf_clk_frac_l, 0x7CE0); - W_REG(osh, ®s->tsf_clk_frac_h, 0xC); + W_REG(®s->tsf_clk_frac_l, 0x7CE0); + W_REG(®s->tsf_clk_frac_h, 0xC); } else { /* 80Mhz */ - W_REG(osh, ®s->tsf_clk_frac_l, 0xCCCD); - W_REG(osh, ®s->tsf_clk_frac_h, 0xC); + W_REG(®s->tsf_clk_frac_l, 0xCCCD); + W_REG(®s->tsf_clk_frac_h, 0xC); } } } @@ -2597,9 +2593,9 @@ static void wlc_gpio_init(struct wlc_info *wlc) * The board itself is powered by these GPIOs * (when not sending pattern) so set them high */ - OR_REG(osh, ®s->psm_gpio_oe, + OR_REG(®s->psm_gpio_oe, (BOARD_GPIO_12 | BOARD_GPIO_13)); - OR_REG(osh, ®s->psm_gpio_out, + OR_REG(®s->psm_gpio_out, (BOARD_GPIO_12 | BOARD_GPIO_13)); /* Enable antenna diversity, use 2x4 mode */ @@ -2664,10 +2660,10 @@ static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[], count = (nbytes / sizeof(u32)); - W_REG(osh, ®s->objaddr, (OBJADDR_AUTO_INC | OBJADDR_UCM_SEL)); - (void)R_REG(osh, ®s->objaddr); + W_REG(®s->objaddr, (OBJADDR_AUTO_INC | OBJADDR_UCM_SEL)); + (void)R_REG(®s->objaddr); for (i = 0; i < count; i++) - W_REG(osh, ®s->objdata, ucode[i]); + W_REG(®s->objdata, ucode[i]); } static void wlc_write_inits(struct wlc_hw_info *wlc_hw, @@ -2686,10 +2682,10 @@ static void wlc_write_inits(struct wlc_hw_info *wlc_hw, ASSERT((inits[i].size == 2) || (inits[i].size == 4)); if (inits[i].size == 2) - W_REG(osh, (u16 *)(base + inits[i].addr), + W_REG((u16 *)(base + inits[i].addr), inits[i].value); else if (inits[i].size == 4) - W_REG(osh, (u32 *)(base + inits[i].addr), + W_REG((u32 *)(base + inits[i].addr), inits[i].value); } } @@ -2748,8 +2744,7 @@ void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw) for (idx = 0; idx < NFIFO; idx++) { /* read intstatus register and ignore any non-error bits */ intstatus = - R_REG(wlc_hw->osh, - ®s->intctrlregs[idx].intstatus) & I_ERRORS; + R_REG(®s->intctrlregs[idx].intstatus) & I_ERRORS; if (!intstatus) continue; @@ -2800,7 +2795,7 @@ void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw) wlc_fatal_error(wlc_hw->wlc); /* big hammer */ break; } else - W_REG(wlc_hw->osh, ®s->intctrlregs[idx].intstatus, + W_REG(®s->intctrlregs[idx].intstatus, intstatus); } } @@ -2810,7 +2805,7 @@ void wlc_intrson(struct wlc_info *wlc) struct wlc_hw_info *wlc_hw = wlc->hw; ASSERT(wlc->defmacintmask); wlc->macintmask = wlc->defmacintmask; - W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, wlc->macintmask); + W_REG(&wlc_hw->regs->macintmask, wlc->macintmask); } /* callback for siutils.c, which has only wlc handler, no wl @@ -2844,8 +2839,8 @@ u32 wlc_intrsoff(struct wlc_info *wlc) macintmask = wlc->macintmask; /* isr can still happen */ - W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, 0); - (void)R_REG(wlc_hw->osh, &wlc_hw->regs->macintmask); /* sync readback */ + W_REG(&wlc_hw->regs->macintmask, 0); + (void)R_REG(&wlc_hw->regs->macintmask); /* sync readback */ udelay(1); /* ensure int line is no longer driven */ wlc->macintmask = 0; @@ -2860,7 +2855,7 @@ void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask) return; wlc->macintmask = macintmask; - W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, wlc->macintmask); + W_REG(&wlc_hw->regs->macintmask, wlc->macintmask); } static void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool on, mbool flags) @@ -2930,7 +2925,7 @@ static bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, uint tx_fifo) * may be acked before or after the DMA is suspended. */ if (dma_txsuspended(wlc_hw->di[tx_fifo]) && - (R_REG(wlc_hw->osh, &wlc_hw->regs->chnstatus) & + (R_REG(&wlc_hw->regs->chnstatus) & (1 << tx_fifo)) == 0) return true; @@ -3006,7 +3001,7 @@ static inline u32 wlc_intstatus(struct wlc_info *wlc, bool in_isr) osh = wlc_hw->osh; /* macintstatus includes a DMA interrupt summary bit */ - macintstatus = R_REG(osh, ®s->macintstatus); + macintstatus = R_REG(®s->macintstatus); WL_TRACE("wl%d: macintstatus: 0x%x\n", wlc_hw->unit, macintstatus); @@ -3032,20 +3027,21 @@ static inline u32 wlc_intstatus(struct wlc_info *wlc, bool in_isr) * consequences */ /* turn off the interrupts */ - W_REG(osh, ®s->macintmask, 0); - (void)R_REG(osh, ®s->macintmask); /* sync readback */ + W_REG(®s->macintmask, 0); + (void)R_REG(®s->macintmask); /* sync readback */ wlc->macintmask = 0; /* clear device interrupts */ - W_REG(osh, ®s->macintstatus, macintstatus); + W_REG(®s->macintstatus, macintstatus); /* MI_DMAINT is indication of non-zero intstatus */ if (macintstatus & MI_DMAINT) { /* - * only fifo interrupt enabled is I_RI in RX_FIFO. If - * MI_DMAINT is set, assume it is set and clear the interrupt. + * only fifo interrupt enabled is I_RI in + * RX_FIFO. If MI_DMAINT is set, assume it + * is set and clear the interrupt. */ - W_REG(osh, ®s->intctrlregs[RX_FIFO].intstatus, + W_REG(®s->intctrlregs[RX_FIFO].intstatus, DEF_RXINTMASK); } @@ -3150,16 +3146,16 @@ wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal) regs = wlc_hw->regs; osh = wlc_hw->osh; while (!(*fatal) - && (s1 = R_REG(osh, ®s->frmtxstatus)) & TXS_V) { + && (s1 = R_REG(®s->frmtxstatus)) & TXS_V) { if (s1 == 0xffffffff) { WL_ERROR("wl%d: %s: dead chip\n", - wlc_hw->unit, __func__); + wlc_hw->unit, __func__); ASSERT(s1 != 0xffffffff); return morepending; } - s2 = R_REG(osh, ®s->frmtxstatus2); + s2 = R_REG(®s->frmtxstatus2); txs->status = s1 & TXS_STATUS_MASK; txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT; @@ -3208,7 +3204,7 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) /* force the core awake */ wlc_ucode_wake_override_set(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND); - mc = R_REG(osh, ®s->maccontrol); + mc = R_REG(®s->maccontrol); if (mc == 0xffffffff) { WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); @@ -3219,7 +3215,7 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) ASSERT(mc & MCTL_PSM_RUN); ASSERT(mc & MCTL_EN_MAC); - mi = R_REG(osh, ®s->macintstatus); + mi = R_REG(®s->macintstatus); if (mi == 0xffffffff) { WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); wl_down(wlc->wl); @@ -3229,20 +3225,20 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, 0); - SPINWAIT(!(R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD), + SPINWAIT(!(R_REG(®s->macintstatus) & MI_MACSSPNDD), WLC_MAX_MAC_SUSPEND); - if (!(R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD)) { + if (!(R_REG(®s->macintstatus) & MI_MACSSPNDD)) { WL_ERROR("wl%d: wlc_suspend_mac_and_wait: waited %d uS and MI_MACSSPNDD is still not on.\n", wlc_hw->unit, WLC_MAX_MAC_SUSPEND); WL_ERROR("wl%d: psmdebug 0x%08x, phydebug 0x%08x, psm_brc 0x%04x\n", wlc_hw->unit, - R_REG(osh, ®s->psmdebug), - R_REG(osh, ®s->phydebug), - R_REG(osh, ®s->psm_brc)); + R_REG(®s->psmdebug), + R_REG(®s->phydebug), + R_REG(®s->psm_brc)); } - mc = R_REG(osh, ®s->maccontrol); + mc = R_REG(®s->maccontrol); if (mc == 0xffffffff) { WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); wl_down(wlc->wl); @@ -3273,20 +3269,20 @@ void wlc_enable_mac(struct wlc_info *wlc) osh = wlc_hw->osh; - mc = R_REG(osh, ®s->maccontrol); + mc = R_REG(®s->maccontrol); ASSERT(!(mc & MCTL_PSM_JMP_0)); ASSERT(!(mc & MCTL_EN_MAC)); ASSERT(mc & MCTL_PSM_RUN); wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC); - W_REG(osh, ®s->macintstatus, MI_MACSSPNDD); + W_REG(®s->macintstatus, MI_MACSSPNDD); - mc = R_REG(osh, ®s->maccontrol); + mc = R_REG(®s->maccontrol); ASSERT(!(mc & MCTL_PSM_JMP_0)); ASSERT(mc & MCTL_EN_MAC); ASSERT(mc & MCTL_PSM_RUN); - mi = R_REG(osh, ®s->macintstatus); + mi = R_REG(®s->macintstatus); ASSERT(!(mi & MI_MACSSPNDD)); wlc_ucode_wake_override_clear(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND); @@ -3374,8 +3370,8 @@ wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr, d11regs_t *regs = wlc_hw->regs; /* read the tsf timer low, then high to get an atomic read */ - *tsf_l_ptr = R_REG(wlc_hw->osh, ®s->tsf_timerlow); - *tsf_h_ptr = R_REG(wlc_hw->osh, ®s->tsf_timerhigh); + *tsf_l_ptr = R_REG(®s->tsf_timerlow); + *tsf_h_ptr = R_REG(®s->tsf_timerhigh); return; } @@ -3393,45 +3389,45 @@ static bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) /* Validate dchip register access */ - W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(osh, ®s->objaddr); - w = R_REG(osh, ®s->objdata); + W_REG(®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(®s->objaddr); + w = R_REG(®s->objdata); /* Can we write and read back a 32bit register? */ - W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, ®s->objdata, (u32) 0xaa5555aa); + W_REG(®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(®s->objaddr); + W_REG(®s->objdata, (u32) 0xaa5555aa); - W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(osh, ®s->objaddr); - val = R_REG(osh, ®s->objdata); + W_REG(®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(®s->objaddr); + val = R_REG(®s->objdata); if (val != (u32) 0xaa5555aa) { WL_ERROR("wl%d: validate_chip_access: SHM = 0x%x, expected 0xaa5555aa\n", wlc_hw->unit, val); return false; } - W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, ®s->objdata, (u32) 0x55aaaa55); + W_REG(®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(®s->objaddr); + W_REG(®s->objdata, (u32) 0x55aaaa55); - W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(osh, ®s->objaddr); - val = R_REG(osh, ®s->objdata); + W_REG(®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(®s->objaddr); + val = R_REG(®s->objdata); if (val != (u32) 0x55aaaa55) { WL_ERROR("wl%d: validate_chip_access: SHM = 0x%x, expected 0x55aaaa55\n", wlc_hw->unit, val); return false; } - W_REG(osh, ®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(osh, ®s->objaddr); - W_REG(osh, ®s->objdata, w); + W_REG(®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(®s->objaddr); + W_REG(®s->objdata, w); /* clear CFPStart */ - W_REG(osh, ®s->tsf_cfpstart, 0); + W_REG(®s->tsf_cfpstart, 0); - w = R_REG(osh, ®s->maccontrol); + w = R_REG(®s->maccontrol); if ((w != (MCTL_IHR_EN | MCTL_WAKE)) && (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) { WL_ERROR("wl%d: validate_chip_access: maccontrol = 0x%x, expected 0x%x or 0x%x\n", @@ -3460,14 +3456,14 @@ void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on) if (on) { if ((wlc_hw->sih->chip == BCM4313_CHIP_ID)) { - OR_REG(osh, ®s->clk_ctl_st, + OR_REG(®s->clk_ctl_st, (CCS_ERSRC_REQ_HT | CCS_ERSRC_REQ_D11PLL | CCS_ERSRC_REQ_PHYPLL)); - SPINWAIT((R_REG(osh, ®s->clk_ctl_st) & + SPINWAIT((R_REG(®s->clk_ctl_st) & (CCS_ERSRC_AVAIL_HT)) != (CCS_ERSRC_AVAIL_HT), PHYPLL_WAIT_US); - tmp = R_REG(osh, ®s->clk_ctl_st); + tmp = R_REG(®s->clk_ctl_st); if ((tmp & (CCS_ERSRC_AVAIL_HT)) != (CCS_ERSRC_AVAIL_HT)) { WL_ERROR("%s: turn on PHY PLL failed\n", @@ -3475,15 +3471,15 @@ void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on) ASSERT(0); } } else { - OR_REG(osh, ®s->clk_ctl_st, + OR_REG(®s->clk_ctl_st, (CCS_ERSRC_REQ_D11PLL | CCS_ERSRC_REQ_PHYPLL)); - SPINWAIT((R_REG(osh, ®s->clk_ctl_st) & + SPINWAIT((R_REG(®s->clk_ctl_st) & (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) != (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL), PHYPLL_WAIT_US); - tmp = R_REG(osh, ®s->clk_ctl_st); + tmp = R_REG(®s->clk_ctl_st); if ((tmp & (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) != @@ -3497,8 +3493,8 @@ void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on) /* Since the PLL may be shared, other cores can still be requesting it; * so we'll deassert the request but not wait for status to comply. */ - AND_REG(osh, ®s->clk_ctl_st, ~CCS_ERSRC_REQ_PHYPLL); - tmp = R_REG(osh, ®s->clk_ctl_st); + AND_REG(®s->clk_ctl_st, ~CCS_ERSRC_REQ_PHYPLL); + tmp = R_REG(®s->clk_ctl_st); } } @@ -3621,12 +3617,12 @@ wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, u32 sel) ASSERT((offset & 1) == 0); - W_REG(wlc_hw->osh, ®s->objaddr, sel | (offset >> 2)); - (void)R_REG(wlc_hw->osh, ®s->objaddr); + W_REG(®s->objaddr, sel | (offset >> 2)); + (void)R_REG(®s->objaddr); if (offset & 2) { - v = R_REG(wlc_hw->osh, objdata_hi); + v = R_REG(objdata_hi); } else { - v = R_REG(wlc_hw->osh, objdata_lo); + v = R_REG(objdata_lo); } return v; @@ -3641,12 +3637,12 @@ wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset, u16 v, u32 sel) ASSERT((offset & 1) == 0); - W_REG(wlc_hw->osh, ®s->objaddr, sel | (offset >> 2)); - (void)R_REG(wlc_hw->osh, ®s->objaddr); + W_REG(®s->objaddr, sel | (offset >> 2)); + (void)R_REG(®s->objaddr); if (offset & 2) { - W_REG(wlc_hw->osh, objdata_hi, v); + W_REG(objdata_hi, v); } else { - W_REG(wlc_hw->osh, objdata_lo, v); + W_REG(objdata_lo, v); } } @@ -3719,14 +3715,14 @@ void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL, u16 LRL) /* write retry limit to SCR, shouldn't need to suspend */ if (wlc_hw->up) { - W_REG(wlc_hw->osh, &wlc_hw->regs->objaddr, + W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_SRC_LMT); - (void)R_REG(wlc_hw->osh, &wlc_hw->regs->objaddr); - W_REG(wlc_hw->osh, &wlc_hw->regs->objdata, wlc_hw->SRL); - W_REG(wlc_hw->osh, &wlc_hw->regs->objaddr, + (void)R_REG(&wlc_hw->regs->objaddr); + W_REG(&wlc_hw->regs->objdata, wlc_hw->SRL); + W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_LRC_LMT); - (void)R_REG(wlc_hw->osh, &wlc_hw->regs->objaddr); - W_REG(wlc_hw->osh, &wlc_hw->regs->objdata, wlc_hw->LRL); + (void)R_REG(&wlc_hw->regs->objaddr); + W_REG(&wlc_hw->regs->objdata, wlc_hw->LRL); } } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index 26eb69fd552a..c00051bcf9a7 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -333,16 +333,16 @@ void wlc_get_rcmta(struct wlc_info *wlc, int idx, u8 *addr) osh = wlc->osh; - W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); - (void)R_REG(osh, ®s->objaddr); - v32 = R_REG(osh, ®s->objdata); + W_REG(®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); + (void)R_REG(®s->objaddr); + v32 = R_REG(®s->objdata); addr[0] = (u8) v32; addr[1] = (u8) (v32 >> 8); addr[2] = (u8) (v32 >> 16); addr[3] = (u8) (v32 >> 24); - W_REG(osh, ®s->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1))); - (void)R_REG(osh, ®s->objaddr); - v32 = R_REG(osh, (volatile u16 *)®s->objdata); + W_REG(®s->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1))); + (void)R_REG(®s->objaddr); + v32 = R_REG(®s->objdata); addr[4] = (u8) v32; addr[5] = (u8) (v32 >> 8); } @@ -485,11 +485,13 @@ void wlc_init(struct wlc_info *wlc) if (bsscfg->up) { u32 bi; - /* get beacon period from bsscfg and convert to uS */ + /* get beacon period and convert to uS */ bi = bsscfg->current_bss->beacon_period << 10; - /* update the tsf_cfprep register */ - /* since init path would reset to default value */ - W_REG(wlc->osh, ®s->tsf_cfprep, + /* + * update since init path would reset + * to default value + */ + W_REG(®s->tsf_cfprep, (bi << CFPREP_CBI_SHIFT)); /* Update maccontrol PM related bits */ @@ -526,7 +528,7 @@ void wlc_init(struct wlc_info *wlc) /* Enable EDCF mode (while the MAC is suspended) */ if (EDCF_ENAB(wlc->pub)) { - OR_REG(wlc->osh, ®s->ifs_ctl, IFS_USEEDCF); + OR_REG(®s->ifs_ctl, IFS_USEEDCF); wlc_edcf_setparams(wlc->cfg, false); } @@ -550,7 +552,7 @@ void wlc_init(struct wlc_info *wlc) wlc->tx_suspended = false; /* enable the RF Disable Delay timer */ - W_REG(wlc->osh, &wlc->regs->rfdisabledly, RFDISABLE_DEFAULT); + W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT); /* initialize mpc delay */ wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; @@ -615,12 +617,13 @@ bool wlc_ps_check(struct wlc_info *wlc) bool wake_ok; if (!AP_ACTIVE(wlc)) { - volatile u32 tmp; - tmp = R_REG(wlc->osh, &wlc->regs->maccontrol); + u32 tmp; + tmp = R_REG(&wlc->regs->maccontrol); - /* If deviceremoved is detected, then don't take any action as this can be called - * in any context. Assume that caller will take care of the condition. This is just - * to avoid assert + /* + * If deviceremoved is detected, then don't take any action as + * this can be called in any context. Assume that caller will + * take care of the condition. This is just to avoid assert */ if (tmp == 0xffffffff) { WL_ERROR("wl%d: %s: dead chip\n", @@ -670,7 +673,7 @@ void wlc_set_ps_ctrl(struct wlc_info *wlc) WL_TRACE("wl%d: wlc_set_ps_ctrl: hps %d wake %d\n", wlc->pub->unit, hps, wake); - v1 = R_REG(wlc->osh, &wlc->regs->maccontrol); + v1 = R_REG(&wlc->regs->maccontrol); v2 = 0; if (hps) v2 |= MCTL_HPS; @@ -1414,7 +1417,7 @@ void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend) acp_shm.cwmax = params->cw_max; acp_shm.cwcur = acp_shm.cwmin; acp_shm.bslots = - R_REG(wlc->osh, &wlc->regs->tsf_random) & acp_shm.cwcur; + R_REG(&wlc->regs->tsf_random) & acp_shm.cwcur; acp_shm.reggap = acp_shm.bslots + acp_shm.aifs; /* Indicate the new params to the ucode */ acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO + @@ -1501,7 +1504,7 @@ void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend) >> EDCF_ECWMAX_SHIFT); acp_shm.cwcur = acp_shm.cwmin; acp_shm.bslots = - R_REG(wlc->osh, &wlc->regs->tsf_random) & acp_shm.cwcur; + R_REG(&wlc->regs->tsf_random) & acp_shm.cwcur; acp_shm.reggap = acp_shm.bslots + acp_shm.aifs; /* Indicate the new params to the ucode */ acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO + @@ -3319,13 +3322,11 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, } if (r->size == sizeof(u32)) r->val = - R_REG(osh, - (u32 *)((unsigned char *)(unsigned long)regs + + R_REG((u32 *)((unsigned char *)(unsigned long)regs + r->byteoff)); else if (r->size == sizeof(u16)) r->val = - R_REG(osh, - (u16 *)((unsigned char *)(unsigned long)regs + + R_REG((u16 *)((unsigned char *)(unsigned long)regs + r->byteoff)); else bcmerror = BCME_BADADDR; @@ -3354,12 +3355,10 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, break; } if (r->size == sizeof(u32)) - W_REG(osh, - (u32 *)((unsigned char *)(unsigned long) regs + + W_REG((u32 *)((unsigned char *)(unsigned long) regs + r->byteoff), r->val); else if (r->size == sizeof(u16)) - W_REG(osh, - (u16 *)((unsigned char *)(unsigned long) regs + + W_REG((u16 *)((unsigned char *)(unsigned long) regs + r->byteoff), r->val); else bcmerror = BCME_BADADDR; @@ -3429,7 +3428,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, break; } - rxstatus = R_REG(wlc->osh, &wlc->regs->phyrxstatus0); + rxstatus = R_REG(&wlc->regs->phyrxstatus0); if (rxstatus == 0xdead || rxstatus == (u16) -1) { bcmerror = BCME_ERROR; break; @@ -6433,12 +6432,12 @@ void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs) /* GP timer is a freerunning 32 bit counter, decrements at 1 us rate */ void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us) { - W_REG(wlc->osh, &wlc->regs->gptimer, us); + W_REG(&wlc->regs->gptimer, us); } void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc) { - W_REG(wlc->osh, &wlc->regs->gptimer, 0); + W_REG(&wlc->regs->gptimer, 0); } static void wlc_hwtimer_gptimer_cb(struct wlc_info *wlc) @@ -6446,7 +6445,7 @@ static void wlc_hwtimer_gptimer_cb(struct wlc_info *wlc) /* when interrupt is generated, the counter is loaded with last value * written and continue to decrement. So it has to be cleaned first */ - W_REG(wlc->osh, &wlc->regs->gptimer, 0); + W_REG(&wlc->regs->gptimer, 0); } /* @@ -6529,9 +6528,9 @@ void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus) if (macintstatus & MI_RFDISABLE) { WL_ERROR("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n", wlc->pub->unit, - R_REG(wlc->osh, ®s->phydebug) & PDBG_RFD); + R_REG(®s->phydebug) & PDBG_RFD); /* delay the cleanup to wl_down in IBSS case */ - if ((R_REG(wlc->osh, ®s->phydebug) & PDBG_RFD)) { + if ((R_REG(®s->phydebug) & PDBG_RFD)) { int idx; wlc_bsscfg_t *bsscfg; FOREACH_BSS(wlc, idx, bsscfg) { @@ -7738,8 +7737,9 @@ void wlc_bss_update_beacon(struct wlc_info *wlc, wlc_bsscfg_t *cfg) return; } - if (MBSS_BCN_ENAB(cfg)) { /* Optimize: Some of if/else could be combined */ - } else if (HWBCN_ENAB(cfg)) { /* Hardware beaconing for this config */ + /* Optimize: Some of if/else could be combined */ + if (!MBSS_BCN_ENAB(cfg) && HWBCN_ENAB(cfg)) { + /* Hardware beaconing for this config */ u16 bcn[BCN_TMPL_LEN / 2]; u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD; d11regs_t *regs = wlc->regs; @@ -7750,14 +7750,14 @@ void wlc_bss_update_beacon(struct wlc_info *wlc, wlc_bsscfg_t *cfg) /* Check if both templates are in use, if so sched. an interrupt * that will call back into this routine */ - if ((R_REG(osh, ®s->maccommand) & both_valid) == both_valid) { + if ((R_REG(®s->maccommand) & both_valid) == both_valid) { /* clear any previous status */ - W_REG(osh, ®s->macintstatus, MI_BCNTPL); + W_REG(®s->macintstatus, MI_BCNTPL); } /* Check that after scheduling the interrupt both of the * templates are still busy. if not clear the int. & remask */ - if ((R_REG(osh, ®s->maccommand) & both_valid) == both_valid) { + if ((R_REG(®s->maccommand) & both_valid) == both_valid) { wlc->defmacintmask |= MI_BCNTPL; return; } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h index 6ddb2baf2857..f65be0ed1c1a 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h @@ -194,7 +194,7 @@ extern const u8 prio2fifo[]; */ #define DEVICEREMOVED(wlc) \ ((wlc->hw->clk) ? \ - ((R_REG(wlc->hw->osh, &wlc->hw->regs->maccontrol) & \ + ((R_REG(&wlc->hw->regs->maccontrol) & \ (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN) : \ (si_deviceremoved(wlc->hw->sih))) diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h index 3a125b124114..9c3a97997fa3 100644 --- a/drivers/staging/brcm80211/include/bcmutils.h +++ b/drivers/staging/brcm80211/include/bcmutils.h @@ -361,11 +361,11 @@ extern struct sk_buff *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); #endif /* Register operations */ -#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) -#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) +#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) +#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) -#define SET_REG(osh, r, mask, val) \ - W_REG((osh), (r), ((R_REG((osh), r) & ~(mask)) | (val))) +#define SET_REG(r, mask, val) \ + W_REG((r), ((R_REG(r) & ~(mask)) | (val))) #ifndef setbit #ifndef NBBY /* the BSD family defines NBBY */ diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index 0aac64af8de6..51619629b584 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -59,9 +59,9 @@ extern uint osl_pci_slot(struct osl_info *osh); #ifdef BRCM_FULLMAC #include #endif -#define OSL_WRITE_REG(osh, r, v) \ +#define OSL_WRITE_REG(r, v) \ (bcmsdh_reg_write(NULL, (unsigned long)(r), sizeof(*(r)), (v))) -#define OSL_READ_REG(osh, r) \ +#define OSL_READ_REG(r) \ (bcmsdh_reg_read(NULL, (unsigned long)(r), sizeof(*(r)))) #endif @@ -85,14 +85,14 @@ extern uint osl_pci_slot(struct osl_info *osh); /* register access macros */ #ifndef IL_BIGENDIAN #ifndef __mips__ -#define R_REG(osh, r) (\ +#define R_REG(r) (\ SELECT_BUS_READ(sizeof(*(r)) == sizeof(u8) ? \ readb((volatile u8*)(r)) : \ sizeof(*(r)) == sizeof(u16) ? readw((volatile u16*)(r)) : \ - readl((volatile u32*)(r)), OSL_READ_REG(osh, r)) \ + readl((volatile u32*)(r)), OSL_READ_REG(r)) \ ) #else /* __mips__ */ -#define R_REG(osh, r) (\ +#define R_REG(r) (\ SELECT_BUS_READ( \ ({ \ __typeof(*(r)) __osl_v; \ @@ -115,14 +115,14 @@ extern uint osl_pci_slot(struct osl_info *osh); ({ \ __typeof(*(r)) __osl_v; \ __asm__ __volatile__("sync"); \ - __osl_v = OSL_READ_REG(osh, r); \ + __osl_v = OSL_READ_REG(r); \ __asm__ __volatile__("sync"); \ __osl_v; \ })) \ ) #endif /* __mips__ */ -#define W_REG(osh, r, v) do { \ +#define W_REG(r, v) do { \ SELECT_BUS_WRITE( \ switch (sizeof(*(r))) { \ case sizeof(u8): \ @@ -132,10 +132,10 @@ extern uint osl_pci_slot(struct osl_info *osh); case sizeof(u32): \ writel((u32)(v), (volatile u32*)(r)); break; \ }, \ - (OSL_WRITE_REG(osh, r, v))); \ + (OSL_WRITE_REG(r, v))); \ } while (0) #else /* IL_BIGENDIAN */ -#define R_REG(osh, r) (\ +#define R_REG(r) (\ SELECT_BUS_READ( \ ({ \ __typeof(*(r)) __osl_v; \ @@ -154,9 +154,9 @@ extern uint osl_pci_slot(struct osl_info *osh); } \ __osl_v; \ }), \ - OSL_READ_REG(osh, r)) \ + OSL_READ_REG(r)) \ ) -#define W_REG(osh, r, v) do { \ +#define W_REG(r, v) do { \ SELECT_BUS_WRITE( \ switch (sizeof(*(r))) { \ case sizeof(u8): \ @@ -169,7 +169,7 @@ extern uint osl_pci_slot(struct osl_info *osh); writel((u32)(v), \ (volatile u32*)(r)); break; \ }, \ - (OSL_WRITE_REG(osh, r, v))); \ + (OSL_WRITE_REG(r, v))); \ } while (0) #endif /* IL_BIGENDIAN */ diff --git a/drivers/staging/brcm80211/util/aiutils.c b/drivers/staging/brcm80211/util/aiutils.c index 67d3706e055f..917989774520 100644 --- a/drivers/staging/brcm80211/util/aiutils.c +++ b/drivers/staging/brcm80211/util/aiutils.c @@ -41,7 +41,7 @@ get_erom_ent(si_t *sih, u32 **eromptr, u32 mask, u32 match) uint inv = 0, nom = 0; while (true) { - ent = R_REG(si_osh(sih), *eromptr); + ent = R_REG(*eromptr); (*eromptr)++; if (mask == 0) @@ -115,7 +115,7 @@ void ai_scan(si_t *sih, void *regs, uint devid) chipcregs_t *cc = (chipcregs_t *) regs; u32 erombase, *eromptr, *eromlim; - erombase = R_REG(sii->osh, &cc->eromptr); + erombase = R_REG(&cc->eromptr); switch (sih->bustype) { case SI_BUS: @@ -427,7 +427,7 @@ uint ai_flag(si_t *sih) } ai = sii->curwrap; - return R_REG(sii->osh, &ai->oobselouta30) & 0x1f; + return R_REG(&ai->oobselouta30) & 0x1f; } void ai_setint(si_t *sih, int siflag) @@ -438,7 +438,7 @@ void ai_write_wrap_reg(si_t *sih, u32 offset, u32 val) { si_info_t *sii = SI_INFO(sih); u32 *w = (u32 *) sii->curwrap; - W_REG(sii->osh, w + (offset / 4), val); + W_REG(w + (offset / 4), val); return; } @@ -470,9 +470,9 @@ bool ai_iscoreup(si_t *sih) sii = SI_INFO(sih); ai = sii->curwrap; - return (((R_REG(sii->osh, &ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) == + return (((R_REG(&ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) == SICF_CLOCK_EN) - && ((R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) == 0)); + && ((R_REG(&ai->resetctrl) & AIRC_RESET) == 0)); } /* @@ -553,12 +553,12 @@ uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) /* mask and set */ if (mask || val) { - w = (R_REG(sii->osh, r) & ~mask) | val; - W_REG(sii->osh, r, w); + w = (R_REG(r) & ~mask) | val; + W_REG(r, w); } /* readback */ - w = R_REG(sii->osh, r); + w = R_REG(r); if (!fast) { /* restore core index */ @@ -583,14 +583,14 @@ void ai_core_disable(si_t *sih, u32 bits) ai = sii->curwrap; /* if core is already in reset, just return */ - if (R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) + if (R_REG(&ai->resetctrl) & AIRC_RESET) return; - W_REG(sii->osh, &ai->ioctrl, bits); - dummy = R_REG(sii->osh, &ai->ioctrl); + W_REG(&ai->ioctrl, bits); + dummy = R_REG(&ai->ioctrl); udelay(10); - W_REG(sii->osh, &ai->resetctrl, AIRC_RESET); + W_REG(&ai->resetctrl, AIRC_RESET); udelay(1); } @@ -617,13 +617,13 @@ void ai_core_reset(si_t *sih, u32 bits, u32 resetbits) /* * Now do the initialization sequence. */ - W_REG(sii->osh, &ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN)); - dummy = R_REG(sii->osh, &ai->ioctrl); - W_REG(sii->osh, &ai->resetctrl, 0); + W_REG(&ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN)); + dummy = R_REG(&ai->ioctrl); + W_REG(&ai->resetctrl, 0); udelay(1); - W_REG(sii->osh, &ai->ioctrl, (bits | SICF_CLOCK_EN)); - dummy = R_REG(sii->osh, &ai->ioctrl); + W_REG(&ai->ioctrl, (bits | SICF_CLOCK_EN)); + dummy = R_REG(&ai->ioctrl); udelay(1); } @@ -647,8 +647,8 @@ void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val) ASSERT((val & ~mask) == 0); if (mask || val) { - w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val); - W_REG(sii->osh, &ai->ioctrl, w); + w = ((R_REG(&ai->ioctrl) & ~mask) | val); + W_REG(&ai->ioctrl, w); } } @@ -671,11 +671,11 @@ u32 ai_core_cflags(si_t *sih, u32 mask, u32 val) ASSERT((val & ~mask) == 0); if (mask || val) { - w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val); - W_REG(sii->osh, &ai->ioctrl, w); + w = ((R_REG(&ai->ioctrl) & ~mask) | val); + W_REG(&ai->ioctrl, w); } - return R_REG(sii->osh, &ai->ioctrl); + return R_REG(&ai->ioctrl); } u32 ai_core_sflags(si_t *sih, u32 mask, u32 val) @@ -697,10 +697,10 @@ u32 ai_core_sflags(si_t *sih, u32 mask, u32 val) ASSERT((mask & ~SISF_CORE_BITS) == 0); if (mask || val) { - w = ((R_REG(sii->osh, &ai->iostatus) & ~mask) | val); - W_REG(sii->osh, &ai->iostatus, w); + w = ((R_REG(&ai->iostatus) & ~mask) | val); + W_REG(&ai->iostatus, w); } - return R_REG(sii->osh, &ai->iostatus); + return R_REG(&ai->iostatus); } diff --git a/drivers/staging/brcm80211/util/bcmotp.c b/drivers/staging/brcm80211/util/bcmotp.c index 5c1ea4c1fbfd..1049462df1a9 100644 --- a/drivers/staging/brcm80211/util/bcmotp.c +++ b/drivers/staging/brcm80211/util/bcmotp.c @@ -182,7 +182,7 @@ static u16 ipxotp_otpr(void *oh, chipcregs_t *cc, uint wn) ASSERT(wn < oi->wsize); ASSERT(cc != NULL); - return R_REG(oi->osh, &cc->sromotp[wn]); + return R_REG(&cc->sromotp[wn]); } static u16 ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off) @@ -198,10 +198,10 @@ static u16 ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off) ((OTPPOC_READ << OTPP_OC_SHIFT) & OTPP_OC_MASK) | ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) | ((col << OTPP_COL_SHIFT) & OTPP_COL_MASK); - W_REG(oi->osh, &cc->otpprog, otpp); + W_REG(&cc->otpprog, otpp); for (k = 0; - ((st = R_REG(oi->osh, &cc->otpprog)) & OTPP_START_BUSY) + ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY) && (k < OTPP_TRIES); k++) ; if (k >= OTPP_TRIES) { @@ -260,9 +260,9 @@ static void _ipxotp_init(otpinfo_t *oi, chipcregs_t *cc) otpp = OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK); - W_REG(oi->osh, &cc->otpprog, otpp); + W_REG(&cc->otpprog, otpp); for (k = 0; - ((st = R_REG(oi->osh, &cc->otpprog)) & OTPP_START_BUSY) + ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY) && (k < OTPP_TRIES); k++) ; if (k >= OTPP_TRIES) { @@ -270,7 +270,7 @@ static void _ipxotp_init(otpinfo_t *oi, chipcregs_t *cc) } /* Read OTP lock bits and subregion programmed indication bits */ - oi->status = R_REG(oi->osh, &cc->otpstatus); + oi->status = R_REG(&cc->otpstatus); if ((oi->sih->chip == BCM43224_CHIP_ID) || (oi->sih->chip == BCM43225_CHIP_ID)) { @@ -579,7 +579,7 @@ static u16 hndotp_otpr(void *oh, chipcregs_t *cc, uint wn) osh = si_osh(oi->sih); ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP); - return R_REG(osh, &ptr[wn]); + return R_REG(&ptr[wn]); } static u16 hndotp_otproff(void *oh, chipcregs_t *cc, int woff) @@ -596,7 +596,7 @@ static u16 hndotp_otproff(void *oh, chipcregs_t *cc, int woff) ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP); - return R_REG(osh, &ptr[(oi->size / 2) + woff]); + return R_REG(&ptr[(oi->size / 2) + woff]); } static u16 hndotp_read_bit(void *oh, chipcregs_t *cc, uint idx) @@ -613,12 +613,12 @@ static u16 hndotp_read_bit(void *oh, chipcregs_t *cc, uint idx) otpp = OTPP_START_BUSY | OTPP_READ | ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) | (col & OTPP_COL_MASK); - W_REG(osh, &cc->otpprog, otpp); - st = R_REG(osh, &cc->otpprog); + W_REG(&cc->otpprog, otpp); + st = R_REG(&cc->otpprog); for (k = 0; ((st & OTPP_START_BUSY) == OTPP_START_BUSY) && (k < OTPP_TRIES); k++) - st = R_REG(osh, &cc->otpprog); + st = R_REG(&cc->otpprog); if (k >= OTPP_TRIES) { return 0xffff; @@ -647,7 +647,7 @@ static void *hndotp_init(si_t *sih) /* Check for otp */ cc = si_setcoreidx(sih, SI_CC_IDX); if (cc != NULL) { - cap = R_REG(osh, &cc->capabilities); + cap = R_REG(&cc->capabilities); if ((cap & CC_CAP_OTPSIZE) == 0) { /* Nothing there */ goto out; @@ -670,7 +670,7 @@ static void *hndotp_init(si_t *sih) if (oi->ccrev >= 18) oi->size -= ((OTP_RC0_OFF - OTP_BOUNDARY_OFF) * 2); - oi->hwprot = (int)(R_REG(osh, &cc->otpstatus) & OTPS_PROTECT); + oi->hwprot = (int)(R_REG(&cc->otpstatus) & OTPS_PROTECT); oi->boundary = -1; /* Check the region signature */ @@ -690,10 +690,10 @@ static void *hndotp_init(si_t *sih) otpdiv = 12; if (otpdiv) { - clkdiv = R_REG(osh, &cc->clkdiv); + clkdiv = R_REG(&cc->clkdiv); clkdiv = (clkdiv & ~CLKD_OTP) | (otpdiv << CLKD_OTP_SHIFT); - W_REG(osh, &cc->clkdiv, clkdiv); + W_REG(&cc->clkdiv, clkdiv); } udelay(10); diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index 3ef5a50f48af..cff25a391d43 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -1415,15 +1415,15 @@ srom_cc_cmd(si_t *sih, struct osl_info *osh, void *ccregs, u32 cmd, uint wait_cnt = 1000; if ((cmd == SRC_OP_READ) || (cmd == SRC_OP_WRITE)) { - W_REG(osh, &cc->sromaddress, wordoff * 2); + W_REG(&cc->sromaddress, wordoff * 2); if (cmd == SRC_OP_WRITE) - W_REG(osh, &cc->sromdata, data); + W_REG(&cc->sromdata, data); } - W_REG(osh, &cc->sromcontrol, SRC_START | cmd); + W_REG(&cc->sromcontrol, SRC_START | cmd); while (wait_cnt--) { - if ((R_REG(osh, &cc->sromcontrol) & SRC_BUSY) == 0) + if ((R_REG(&cc->sromcontrol) & SRC_BUSY) == 0) break; } @@ -1432,7 +1432,7 @@ srom_cc_cmd(si_t *sih, struct osl_info *osh, void *ccregs, u32 cmd, return 0xffff; } if (cmd == SRC_OP_READ) - return (u16) R_REG(osh, &cc->sromdata); + return (u16) R_REG(&cc->sromdata); else return 0xffff; } @@ -1476,9 +1476,9 @@ sprom_read_pci(struct osl_info *osh, si_t *sih, u16 *sprom, uint wordoff, } else { if (ISSIM_ENAB(sih)) - buf[i] = R_REG(osh, &sprom[wordoff + i]); + buf[i] = R_REG(&sprom[wordoff + i]); - buf[i] = R_REG(osh, &sprom[wordoff + i]); + buf[i] = R_REG(&sprom[wordoff + i]); } } diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 3c71f7549d1c..4646b7bfe0bf 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -590,13 +590,13 @@ static bool _dma_descriptor_align(dma_info_t *di) /* Check to see if the descriptors need to be aligned on 4K/8K or not */ if (di->d64txregs != NULL) { - W_REG(di->osh, &di->d64txregs->addrlow, 0xff0); - addrl = R_REG(di->osh, &di->d64txregs->addrlow); + W_REG(&di->d64txregs->addrlow, 0xff0); + addrl = R_REG(&di->d64txregs->addrlow); if (addrl != 0) return false; } else if (di->d64rxregs != NULL) { - W_REG(di->osh, &di->d64rxregs->addrlow, 0xff0); - addrl = R_REG(di->osh, &di->d64rxregs->addrlow); + W_REG(&di->d64rxregs->addrlow, 0xff0); + addrl = R_REG(&di->d64rxregs->addrlow); if (addrl != 0) return false; } @@ -640,14 +640,14 @@ static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa) if ((di->ddoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) { if (direction == DMA_TX) { - W_REG(di->osh, &di->d64txregs->addrlow, + W_REG(&di->d64txregs->addrlow, (PHYSADDRLO(pa) + di->ddoffsetlow)); - W_REG(di->osh, &di->d64txregs->addrhigh, + W_REG(&di->d64txregs->addrhigh, (PHYSADDRHI(pa) + di->ddoffsethigh)); } else { - W_REG(di->osh, &di->d64rxregs->addrlow, + W_REG(&di->d64rxregs->addrlow, (PHYSADDRLO(pa) + di->ddoffsetlow)); - W_REG(di->osh, &di->d64rxregs->addrhigh, + W_REG(&di->d64rxregs->addrhigh, (PHYSADDRHI(pa) + di->ddoffsethigh)); } } else { @@ -662,18 +662,18 @@ static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa) PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH; if (direction == DMA_TX) { - W_REG(di->osh, &di->d64txregs->addrlow, + W_REG(&di->d64txregs->addrlow, (PHYSADDRLO(pa) + di->ddoffsetlow)); - W_REG(di->osh, &di->d64txregs->addrhigh, + W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh); - SET_REG(di->osh, &di->d64txregs->control, + SET_REG(&di->d64txregs->control, D64_XC_AE, (ae << D64_XC_AE_SHIFT)); } else { - W_REG(di->osh, &di->d64rxregs->addrlow, + W_REG(&di->d64rxregs->addrlow, (PHYSADDRLO(pa) + di->ddoffsetlow)); - W_REG(di->osh, &di->d64rxregs->addrhigh, + W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh); - SET_REG(di->osh, &di->d64rxregs->control, + SET_REG(&di->d64rxregs->control, D64_RC_AE, (ae << D64_RC_AE_SHIFT)); } } @@ -683,7 +683,7 @@ static void _dma_fifoloopbackenable(dma_info_t *di) { DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name)); - OR_REG(di->osh, &di->d64txregs->control, D64_XC_LE); + OR_REG(&di->d64txregs->control, D64_XC_LE); } static void _dma_rxinit(dma_info_t *di) @@ -719,7 +719,7 @@ static void _dma_rxenable(dma_info_t *di) DMA_TRACE(("%s: dma_rxenable\n", di->name)); control = - (R_REG(di->osh, &di->d64rxregs->control) & D64_RC_AE) | + (R_REG(&di->d64rxregs->control) & D64_RC_AE) | D64_RC_RE; if ((dmactrlflags & DMA_CTRL_PEN) == 0) @@ -728,7 +728,7 @@ static void _dma_rxenable(dma_info_t *di) if (dmactrlflags & DMA_CTRL_ROC) control |= D64_RC_OC; - W_REG(di->osh, &di->d64rxregs->control, + W_REG(&di->d64rxregs->control, ((di->rxoffset << D64_RC_RO_SHIFT) | control)); } @@ -796,7 +796,7 @@ static void *BCMFASTPATH _dma_rx(dma_info_t *di) uint cur; ASSERT(p == NULL); cur = - B2I(((R_REG(di->osh, &di->d64rxregs->status0) & + B2I(((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t); @@ -904,7 +904,7 @@ static bool BCMFASTPATH _dma_rxfill(dma_info_t *di) di->rxout = rxout; /* update the chip lastdscr pointer */ - W_REG(di->osh, &di->d64rxregs->ptr, + W_REG(&di->d64rxregs->ptr, di->rcvptrbase + I2B(rxout, dma64dd_t)); return ring_empty; @@ -919,7 +919,7 @@ static void *_dma_peeknexttxp(dma_info_t *di) return NULL; end = - B2I(((R_REG(di->osh, &di->d64txregs->status0) & + B2I(((R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t); @@ -939,7 +939,7 @@ static void *_dma_peeknextrxp(dma_info_t *di) return NULL; end = - B2I(((R_REG(di->osh, &di->d64rxregs->status0) & + B2I(((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t); @@ -988,7 +988,7 @@ static uint _dma_txpending(dma_info_t *di) uint curr; curr = - B2I(((R_REG(di->osh, &di->d64txregs->status0) & + B2I(((R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t); @@ -1003,7 +1003,7 @@ static uint _dma_txcommitted(dma_info_t *di) if (txin == di->txout) return 0; - ptr = B2I(R_REG(di->osh, &di->d64txregs->ptr), dma64dd_t); + ptr = B2I(R_REG(&di->d64txregs->ptr), dma64dd_t); return NTXDACTIVE(di->txin, ptr); } @@ -1039,14 +1039,14 @@ static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags) if (dmactrlflags & DMA_CTRL_PEN) { u32 control; - control = R_REG(di->osh, &di->d64txregs->control); - W_REG(di->osh, &di->d64txregs->control, + control = R_REG(&di->d64txregs->control); + W_REG(&di->d64txregs->control, control | D64_XC_PD); - if (R_REG(di->osh, &di->d64txregs->control) & D64_XC_PD) { + if (R_REG(&di->d64txregs->control) & D64_XC_PD) { /* We *can* disable it so it is supported, * restore control register */ - W_REG(di->osh, &di->d64txregs->control, + W_REG(&di->d64txregs->control, control); } else { /* Not supported, don't allow it to be enabled */ @@ -1137,7 +1137,7 @@ static void dma64_txinit(dma_info_t *di) if ((di->hnddma.dmactrlflags & DMA_CTRL_PEN) == 0) control |= D64_XC_PD; - OR_REG(di->osh, &di->d64txregs->control, control); + OR_REG(&di->d64txregs->control, control); /* DMA engine with alignment requirement requires table to be inited * before enabling the engine @@ -1151,7 +1151,7 @@ static bool dma64_txenabled(dma_info_t *di) u32 xc; /* If the chip is dead, it is not enabled :-) */ - xc = R_REG(di->osh, &di->d64txregs->control); + xc = R_REG(&di->d64txregs->control); return (xc != 0xffffffff) && (xc & D64_XC_XE); } @@ -1162,7 +1162,7 @@ static void dma64_txsuspend(dma_info_t *di) if (di->ntxd == 0) return; - OR_REG(di->osh, &di->d64txregs->control, D64_XC_SE); + OR_REG(&di->d64txregs->control, D64_XC_SE); } static void dma64_txresume(dma_info_t *di) @@ -1172,13 +1172,13 @@ static void dma64_txresume(dma_info_t *di) if (di->ntxd == 0) return; - AND_REG(di->osh, &di->d64txregs->control, ~D64_XC_SE); + AND_REG(&di->d64txregs->control, ~D64_XC_SE); } static bool dma64_txsuspended(dma_info_t *di) { return (di->ntxd == 0) || - ((R_REG(di->osh, &di->d64txregs->control) & D64_XC_SE) == + ((R_REG(&di->d64txregs->control) & D64_XC_SE) == D64_XC_SE); } @@ -1204,13 +1204,13 @@ static void BCMFASTPATH dma64_txreclaim(dma_info_t *di, txd_range_t range) static bool dma64_txstopped(dma_info_t *di) { - return ((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK) == + return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_STOPPED); } static bool dma64_rxstopped(dma_info_t *di) { - return ((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_RS_MASK) == + return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) == D64_RS0_RS_STOPPED); } @@ -1278,15 +1278,15 @@ static bool dma64_txreset(dma_info_t *di) return true; /* suspend tx DMA first */ - W_REG(di->osh, &di->d64txregs->control, D64_XC_SE); + W_REG(&di->d64txregs->control, D64_XC_SE); SPINWAIT(((status = - (R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK)) + (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED) && (status != D64_XS0_XS_IDLE) && (status != D64_XS0_XS_STOPPED), 10000); - W_REG(di->osh, &di->d64txregs->control, 0); + W_REG(&di->d64txregs->control, 0); SPINWAIT(((status = - (R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK)) + (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED), 10000); /* wait for the last transaction to complete */ @@ -1302,8 +1302,8 @@ static bool dma64_rxidle(dma_info_t *di) if (di->nrxd == 0) return true; - return ((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) == - (R_REG(di->osh, &di->d64rxregs->ptr) & D64_RS0_CD_MASK)); + return ((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) == + (R_REG(&di->d64rxregs->ptr) & D64_RS0_CD_MASK)); } static bool dma64_rxreset(dma_info_t *di) @@ -1313,9 +1313,9 @@ static bool dma64_rxreset(dma_info_t *di) if (di->nrxd == 0) return true; - W_REG(di->osh, &di->d64rxregs->control, 0); + W_REG(&di->d64rxregs->control, 0); SPINWAIT(((status = - (R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_RS_MASK)) + (R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK)) != D64_RS0_RS_DISABLED), 10000); return status == D64_RS0_RS_DISABLED; @@ -1325,7 +1325,7 @@ static bool dma64_rxenabled(dma_info_t *di) { u32 rc; - rc = R_REG(di->osh, &di->d64rxregs->control); + rc = R_REG(&di->d64rxregs->control); return (rc != 0xffffffff) && (rc & D64_RC_RE); } @@ -1335,10 +1335,10 @@ static bool dma64_txsuspendedidle(dma_info_t *di) if (di->ntxd == 0) return true; - if (!(R_REG(di->osh, &di->d64txregs->control) & D64_XC_SE)) + if (!(R_REG(&di->d64txregs->control) & D64_XC_SE)) return 0; - if ((R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_XS_MASK) == + if ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_IDLE) return 1; @@ -1357,12 +1357,12 @@ static void *dma64_getpos(dma_info_t *di, bool direction) if (direction == DMA_TX) { cd_offset = - R_REG(di->osh, &di->d64txregs->status0) & D64_XS0_CD_MASK; + R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK; idle = !NTXDACTIVE(di->txin, di->txout); va = di->txp[B2I(cd_offset, dma64dd_t)]; } else { cd_offset = - R_REG(di->osh, &di->d64rxregs->status0) & D64_XS0_CD_MASK; + R_REG(&di->d64rxregs->status0) & D64_XS0_CD_MASK; idle = !NRXDACTIVE(di->rxin, di->rxout); va = di->rxp[B2I(cd_offset, dma64dd_t)]; } @@ -1418,7 +1418,7 @@ static int dma64_txunframed(dma_info_t *di, void *buf, uint len, bool commit) /* kick the chip */ if (commit) { - W_REG(di->osh, &di->d64txregs->ptr, + W_REG(&di->d64txregs->ptr, di->xmtptrbase + I2B(txout, dma64dd_t)); } @@ -1538,7 +1538,7 @@ static int BCMFASTPATH dma64_txfast(dma_info_t *di, struct sk_buff *p0, /* kick the chip */ if (commit) - W_REG(di->osh, &di->d64txregs->ptr, + W_REG(&di->d64txregs->ptr, di->xmtptrbase + I2B(txout, dma64dd_t)); /* tx flow control */ @@ -1589,13 +1589,13 @@ static void *BCMFASTPATH dma64_getnexttxp(dma_info_t *di, txd_range_t range) end = (u16) (B2I - (((R_REG(di->osh, &dregs->status0) & + (((R_REG(&dregs->status0) & D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t)); if (range == HNDDMA_RANGE_TRANSFERED) { active_desc = - (u16) (R_REG(di->osh, &dregs->status1) & + (u16) (R_REG(&dregs->status1) & D64_XS1_AD_MASK); active_desc = (active_desc - di->xmtptrbase) & D64_XS0_CD_MASK; @@ -1672,7 +1672,7 @@ static void *BCMFASTPATH dma64_getnextrxp(dma_info_t *di, bool forceall) return NULL; curr = - B2I(((R_REG(di->osh, &di->d64rxregs->status0) & D64_RS0_CD_MASK) - + B2I(((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t); /* ignore curr if forceall */ @@ -1705,9 +1705,9 @@ static void *BCMFASTPATH dma64_getnextrxp(dma_info_t *di, bool forceall) static bool _dma64_addrext(struct osl_info *osh, dma64regs_t * dma64regs) { u32 w; - OR_REG(osh, &dma64regs->control, D64_XC_AE); - w = R_REG(osh, &dma64regs->control); - AND_REG(osh, &dma64regs->control, ~D64_XC_AE); + OR_REG(&dma64regs->control, D64_XC_AE); + w = R_REG(&dma64regs->control); + AND_REG(&dma64regs->control, ~D64_XC_AE); return (w & D64_XC_AE) == D64_XC_AE; } @@ -1727,7 +1727,7 @@ static void dma64_txrotate(dma_info_t *di) nactive = _dma_txactive(di); ad = (u16) (B2I - ((((R_REG(di->osh, &di->d64txregs->status1) & + ((((R_REG(&di->d64txregs->status1) & D64_XS1_AD_MASK) - di->xmtptrbase) & D64_XS1_AD_MASK), dma64dd_t)); rot = TXD(ad - di->txin); @@ -1786,7 +1786,7 @@ static void dma64_txrotate(dma_info_t *di) di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; /* kick the chip */ - W_REG(di->osh, &di->d64txregs->ptr, + W_REG(&di->d64txregs->ptr, di->xmtptrbase + I2B(di->txout, dma64dd_t)); } diff --git a/drivers/staging/brcm80211/util/hndpmu.c b/drivers/staging/brcm80211/util/hndpmu.c index 5240341cbad8..a683b1895b70 100644 --- a/drivers/staging/brcm80211/util/hndpmu.c +++ b/drivers/staging/brcm80211/util/hndpmu.c @@ -120,11 +120,11 @@ void si_pmu_set_switcher_voltage(si_t *sih, struct osl_info *osh, u8 bb_voltage, cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); - W_REG(osh, &cc->regcontrol_addr, 0x01); - W_REG(osh, &cc->regcontrol_data, (u32) (bb_voltage & 0x1f) << 22); + W_REG(&cc->regcontrol_addr, 0x01); + W_REG(&cc->regcontrol_data, (u32) (bb_voltage & 0x1f) << 22); - W_REG(osh, &cc->regcontrol_addr, 0x00); - W_REG(osh, &cc->regcontrol_data, (u32) (rf_voltage & 0x1f) << 14); + W_REG(&cc->regcontrol_addr, 0x00); + W_REG(&cc->regcontrol_data, (u32) (rf_voltage & 0x1f) << 14); /* Return to original core */ si_setcoreidx(sih, origidx); @@ -278,12 +278,12 @@ u32 si_pmu_force_ilp(si_t *sih, struct osl_info *osh, bool force) cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); - oldpmucontrol = R_REG(osh, &cc->pmucontrol); + oldpmucontrol = R_REG(&cc->pmucontrol); if (force) - W_REG(osh, &cc->pmucontrol, oldpmucontrol & + W_REG(&cc->pmucontrol, oldpmucontrol & ~(PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN)); else - W_REG(osh, &cc->pmucontrol, oldpmucontrol | + W_REG(&cc->pmucontrol, oldpmucontrol | (PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN)); /* Return to original core */ @@ -778,9 +778,9 @@ void si_pmu_res_init(si_t *sih, struct osl_info *osh) PMU_MSG(("Changing rsrc %d res_updn_timer to 0x%x\n", pmu_res_updown_table[pmu_res_updown_table_sz].resnum, pmu_res_updown_table[pmu_res_updown_table_sz].updown)); - W_REG(osh, &cc->res_table_sel, + W_REG(&cc->res_table_sel, pmu_res_updown_table[pmu_res_updown_table_sz].resnum); - W_REG(osh, &cc->res_updn_timer, + W_REG(&cc->res_updn_timer, pmu_res_updown_table[pmu_res_updown_table_sz].updown); } /* Apply nvram overrides to up/down timers */ @@ -791,8 +791,8 @@ void si_pmu_res_init(si_t *sih, struct osl_info *osh) continue; PMU_MSG(("Applying %s=%s to rsrc %d res_updn_timer\n", name, val, i)); - W_REG(osh, &cc->res_table_sel, (u32) i); - W_REG(osh, &cc->res_updn_timer, + W_REG(&cc->res_table_sel, (u32) i); + W_REG(&cc->res_updn_timer, (u32) simple_strtoul(val, NULL, 0)); } @@ -807,24 +807,24 @@ void si_pmu_res_init(si_t *sih, struct osl_info *osh) if ((pmu_res_depend_table[pmu_res_depend_table_sz]. res_mask & PMURES_BIT(i)) == 0) continue; - W_REG(osh, &cc->res_table_sel, i); + W_REG(&cc->res_table_sel, i); switch (pmu_res_depend_table[pmu_res_depend_table_sz]. action) { case RES_DEPEND_SET: PMU_MSG(("Changing rsrc %d res_dep_mask to 0x%x\n", i, pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask)); - W_REG(osh, &cc->res_dep_mask, + W_REG(&cc->res_dep_mask, pmu_res_depend_table [pmu_res_depend_table_sz].depend_mask); break; case RES_DEPEND_ADD: PMU_MSG(("Adding 0x%x to rsrc %d res_dep_mask\n", pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask, i)); - OR_REG(osh, &cc->res_dep_mask, + OR_REG(&cc->res_dep_mask, pmu_res_depend_table [pmu_res_depend_table_sz].depend_mask); break; case RES_DEPEND_REMOVE: PMU_MSG(("Removing 0x%x from rsrc %d res_dep_mask\n", pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask, i)); - AND_REG(osh, &cc->res_dep_mask, + AND_REG(&cc->res_dep_mask, ~pmu_res_depend_table [pmu_res_depend_table_sz].depend_mask); break; @@ -842,8 +842,8 @@ void si_pmu_res_init(si_t *sih, struct osl_info *osh) continue; PMU_MSG(("Applying %s=%s to rsrc %d res_dep_mask\n", name, val, i)); - W_REG(osh, &cc->res_table_sel, (u32) i); - W_REG(osh, &cc->res_dep_mask, + W_REG(&cc->res_table_sel, (u32) i); + W_REG(&cc->res_dep_mask, (u32) simple_strtoul(val, NULL, 0)); } @@ -856,14 +856,14 @@ void si_pmu_res_init(si_t *sih, struct osl_info *osh) if (max_mask) { PMU_MSG(("Changing max_res_mask to 0x%x\n", max_mask)); - W_REG(osh, &cc->max_res_mask, max_mask); + W_REG(&cc->max_res_mask, max_mask); } /* Program min resource mask */ if (min_mask) { PMU_MSG(("Changing min_res_mask to 0x%x\n", min_mask)); - W_REG(osh, &cc->min_res_mask, min_mask); + W_REG(&cc->min_res_mask, min_mask); } /* Add some delay; allow resources to come up and settle. */ @@ -1190,7 +1190,7 @@ si_pmu1_alpclk0(si_t *sih, struct osl_info *osh, chipcregs_t *cc) u32 xf; /* Find the frequency in the table */ - xf = (R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> + xf = (R_REG(&cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> PCTL_XTALFREQ_SHIFT; for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt++) if (xt->xf == xf) @@ -1238,7 +1238,7 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, /* for 4319 bootloader already programs the PLL but bootloader does not program the PLL4 and PLL5. So Skip this check for 4319 */ - if ((((R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> + if ((((R_REG(&cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> PCTL_XTALFREQ_SHIFT) == xt->xf) && !((sih->chip == BCM4319_CHIP_ID) || (sih->chip == BCM4330_CHIP_ID))) { @@ -1255,16 +1255,16 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, case BCM4329_CHIP_ID: /* Change the BBPLL drive strength to 8 for all channels */ buf_strength = 0x888888; - AND_REG(osh, &cc->min_res_mask, + AND_REG(&cc->min_res_mask, ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) | PMURES_BIT(RES4329_HT_AVAIL))); - AND_REG(osh, &cc->max_res_mask, + AND_REG(&cc->max_res_mask, ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) | PMURES_BIT(RES4329_HT_AVAIL))); - SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, + SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); - ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); + ASSERT(!(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL)); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); if (xt->fref == 38400) tmp = 0x200024C0; else if (xt->fref == 37400) @@ -1273,17 +1273,16 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, tmp = 0x200024C0; else tmp = 0x200005C0; /* Chip Dflt Settings */ - W_REG(osh, &cc->pllcontrol_data, tmp); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); + W_REG(&cc->pllcontrol_data, tmp); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); tmp = - R_REG(osh, - &cc->pllcontrol_data) & PMU1_PLL0_PC5_CLK_DRV_MASK; + R_REG(&cc->pllcontrol_data) & PMU1_PLL0_PC5_CLK_DRV_MASK; if ((xt->fref == 38400) || (xt->fref == 37400) || (xt->fref == 26000)) tmp |= 0x15; else tmp |= 0x25; /* Chip Dflt Settings */ - W_REG(osh, &cc->pllcontrol_data, tmp); + W_REG(&cc->pllcontrol_data, tmp); break; case BCM4319_CHIP_ID: @@ -1295,50 +1294,50 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, * after a delay (more than downtime for HT_AVAIL) remove the * BBPLL resource; backplane clock moves to ALP from HT. */ - AND_REG(osh, &cc->min_res_mask, + AND_REG(&cc->min_res_mask, ~(PMURES_BIT(RES4319_HT_AVAIL))); - AND_REG(osh, &cc->max_res_mask, + AND_REG(&cc->max_res_mask, ~(PMURES_BIT(RES4319_HT_AVAIL))); udelay(100); - AND_REG(osh, &cc->min_res_mask, + AND_REG(&cc->min_res_mask, ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU))); - AND_REG(osh, &cc->max_res_mask, + AND_REG(&cc->max_res_mask, ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU))); udelay(100); - SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, + SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); - ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); + ASSERT(!(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL)); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); tmp = 0x200005c0; - W_REG(osh, &cc->pllcontrol_data, tmp); + W_REG(&cc->pllcontrol_data, tmp); break; case BCM4336_CHIP_ID: - AND_REG(osh, &cc->min_res_mask, + AND_REG(&cc->min_res_mask, ~(PMURES_BIT(RES4336_HT_AVAIL) | PMURES_BIT(RES4336_MACPHY_CLKAVAIL))); - AND_REG(osh, &cc->max_res_mask, + AND_REG(&cc->max_res_mask, ~(PMURES_BIT(RES4336_HT_AVAIL) | PMURES_BIT(RES4336_MACPHY_CLKAVAIL))); udelay(100); - SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, + SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); - ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); + ASSERT(!(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL)); break; case BCM4330_CHIP_ID: - AND_REG(osh, &cc->min_res_mask, + AND_REG(&cc->min_res_mask, ~(PMURES_BIT(RES4330_HT_AVAIL) | PMURES_BIT(RES4330_MACPHY_CLKAVAIL))); - AND_REG(osh, &cc->max_res_mask, + AND_REG(&cc->max_res_mask, ~(PMURES_BIT(RES4330_HT_AVAIL) | PMURES_BIT(RES4330_MACPHY_CLKAVAIL))); udelay(100); - SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, + SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY); - ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); + ASSERT(!(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL)); break; default: @@ -1348,15 +1347,15 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, PMU_MSG(("Done masking\n")); /* Write p1div and p2div to pllcontrol[0] */ - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - tmp = R_REG(osh, &cc->pllcontrol_data) & + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + tmp = R_REG(&cc->pllcontrol_data) & ~(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK); tmp |= ((xt-> p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) | ((xt-> p2div << PMU1_PLL0_PC0_P2DIV_SHIFT) & PMU1_PLL0_PC0_P2DIV_MASK); - W_REG(osh, &cc->pllcontrol_data, tmp); + W_REG(&cc->pllcontrol_data, tmp); if ((sih->chip == BCM4330_CHIP_ID)) si_pmu_set_4330_plldivs(sih); @@ -1364,11 +1363,11 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, if ((sih->chip == BCM4329_CHIP_ID) && (sih->chiprev == 0)) { - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - tmp = R_REG(osh, &cc->pllcontrol_data); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); + tmp = R_REG(&cc->pllcontrol_data); tmp = tmp & (~DOT11MAC_880MHZ_CLK_DIVISOR_MASK); tmp = tmp | DOT11MAC_880MHZ_CLK_DIVISOR_VAL; - W_REG(osh, &cc->pllcontrol_data, tmp); + W_REG(&cc->pllcontrol_data, tmp); } if ((sih->chip == BCM4319_CHIP_ID) || (sih->chip == BCM4336_CHIP_ID) || @@ -1378,8 +1377,8 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MASH; /* Write ndiv_int and ndiv_mode to pllcontrol[2] */ - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - tmp = R_REG(osh, &cc->pllcontrol_data) & + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + tmp = R_REG(&cc->pllcontrol_data) & ~(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK); tmp |= ((xt-> @@ -1387,26 +1386,25 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, PMU1_PLL0_PC2_NDIV_INT_MASK) | ((ndiv_mode << PMU1_PLL0_PC2_NDIV_MODE_SHIFT) & PMU1_PLL0_PC2_NDIV_MODE_MASK); - W_REG(osh, &cc->pllcontrol_data, tmp); + W_REG(&cc->pllcontrol_data, tmp); /* Write ndiv_frac to pllcontrol[3] */ - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - tmp = R_REG(osh, &cc->pllcontrol_data) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK; + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); + tmp = R_REG(&cc->pllcontrol_data) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK; tmp |= ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) & PMU1_PLL0_PC3_NDIV_FRAC_MASK); - W_REG(osh, &cc->pllcontrol_data, tmp); + W_REG(&cc->pllcontrol_data, tmp); /* Write clock driving strength to pllcontrol[5] */ if (buf_strength) { PMU_MSG(("Adjusting PLL buffer drive strength: %x\n", buf_strength)); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); tmp = - R_REG(osh, - &cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK; + R_REG(&cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK; tmp |= (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT); - W_REG(osh, &cc->pllcontrol_data, tmp); + W_REG(&cc->pllcontrol_data, tmp); } PMU_MSG(("Done pll\n")); @@ -1416,10 +1414,9 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, */ if ((sih->chip == BCM4319_CHIP_ID) && (xt->fref != XTAL_FREQ_30000MHZ)) { - W_REG(osh, &cc->chipcontrol_addr, PMU1_PLL0_CHIPCTL2); + W_REG(&cc->chipcontrol_addr, PMU1_PLL0_CHIPCTL2); tmp = - R_REG(osh, - &cc->chipcontrol_data) & ~CCTL_4319USB_XTAL_SEL_MASK; + R_REG(&cc->chipcontrol_data) & ~CCTL_4319USB_XTAL_SEL_MASK; if (xt->fref == XTAL_FREQ_24000MHZ) { tmp |= (CCTL_4319USB_24MHZ_PLL_SEL << @@ -1429,15 +1426,15 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, (CCTL_4319USB_48MHZ_PLL_SEL << CCTL_4319USB_XTAL_SEL_SHIFT); } - W_REG(osh, &cc->chipcontrol_data, tmp); + W_REG(&cc->chipcontrol_data, tmp); } /* Flush deferred pll control registers writes */ if (sih->pmurev >= 2) - OR_REG(osh, &cc->pmucontrol, PCTL_PLL_PLLCTL_UPD); + OR_REG(&cc->pmucontrol, PCTL_PLL_PLLCTL_UPD); /* Write XtalFreq. Set the divisor also. */ - tmp = R_REG(osh, &cc->pmucontrol) & + tmp = R_REG(&cc->pmucontrol) & ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK); tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) & PCTL_ILP_DIV_MASK) | @@ -1446,11 +1443,11 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, if ((sih->chip == BCM4329_CHIP_ID) && sih->chiprev == 0) { /* clear the htstretch before clearing HTReqEn */ - AND_REG(osh, &cc->clkstretch, ~CSTRETCH_HT); + AND_REG(&cc->clkstretch, ~CSTRETCH_HT); tmp &= ~PCTL_HT_REQ_EN; } - W_REG(osh, &cc->pmucontrol, tmp); + W_REG(&cc->pmucontrol, tmp); } /* query the CPU clock frequency */ @@ -1465,25 +1462,25 @@ si_pmu1_cpuclk0(si_t *sih, struct osl_info *osh, chipcregs_t *cc) u32 FVCO = si_pmu1_pllfvco0(sih); /* Read m1div from pllcontrol[1] */ - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - tmp = R_REG(osh, &cc->pllcontrol_data); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); + tmp = R_REG(&cc->pllcontrol_data); m1div = (tmp & PMU1_PLL0_PC1_M1DIV_MASK) >> PMU1_PLL0_PC1_M1DIV_SHIFT; #ifdef BCMDBG /* Read p2div/p1div from pllcontrol[0] */ - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - tmp = R_REG(osh, &cc->pllcontrol_data); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + tmp = R_REG(&cc->pllcontrol_data); p2div = (tmp & PMU1_PLL0_PC0_P2DIV_MASK) >> PMU1_PLL0_PC0_P2DIV_SHIFT; p1div = (tmp & PMU1_PLL0_PC0_P1DIV_MASK) >> PMU1_PLL0_PC0_P1DIV_SHIFT; /* Calculate fvco based on xtal freq and ndiv and pdiv */ - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - tmp = R_REG(osh, &cc->pllcontrol_data); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + tmp = R_REG(&cc->pllcontrol_data); ndiv_int = (tmp & PMU1_PLL0_PC2_NDIV_INT_MASK) >> PMU1_PLL0_PC2_NDIV_INT_SHIFT; - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - tmp = R_REG(osh, &cc->pllcontrol_data); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); + tmp = R_REG(&cc->pllcontrol_data); ndiv_frac = (tmp & PMU1_PLL0_PC3_NDIV_FRAC_MASK) >> PMU1_PLL0_PC3_NDIV_FRAC_SHIFT; @@ -1554,7 +1551,7 @@ void si_pmu_pll_init(si_t *sih, struct osl_info *osh, uint xtalfreq) } #ifdef BCMDBG_FORCEHT - OR_REG(osh, &cc->clk_ctl_st, CCS_FORCEHT); + OR_REG(&cc->clk_ctl_st, CCS_FORCEHT); #endif /* Return to original core */ @@ -1640,25 +1637,24 @@ si_pmu5_clock(si_t *sih, struct osl_info *osh, chipcregs_t *cc, uint pll0, if (sih->chip == BCM5357_CHIP_ID) { /* Detect failure in clock setting */ - if ((R_REG(osh, &cc->chipstatus) & 0x40000) != 0) { + if ((R_REG(&cc->chipstatus) & 0x40000) != 0) return 133 * 1000000; - } } - W_REG(osh, &cc->pllcontrol_addr, pll0 + PMU5_PLL_P1P2_OFF); - (void)R_REG(osh, &cc->pllcontrol_addr); - tmp = R_REG(osh, &cc->pllcontrol_data); + W_REG(&cc->pllcontrol_addr, pll0 + PMU5_PLL_P1P2_OFF); + (void)R_REG(&cc->pllcontrol_addr); + tmp = R_REG(&cc->pllcontrol_data); p1 = (tmp & PMU5_PLL_P1_MASK) >> PMU5_PLL_P1_SHIFT; p2 = (tmp & PMU5_PLL_P2_MASK) >> PMU5_PLL_P2_SHIFT; - W_REG(osh, &cc->pllcontrol_addr, pll0 + PMU5_PLL_M14_OFF); - (void)R_REG(osh, &cc->pllcontrol_addr); - tmp = R_REG(osh, &cc->pllcontrol_data); + W_REG(&cc->pllcontrol_addr, pll0 + PMU5_PLL_M14_OFF); + (void)R_REG(&cc->pllcontrol_addr); + tmp = R_REG(&cc->pllcontrol_data); div = (tmp >> ((m - 1) * PMU5_PLL_MDIV_WIDTH)) & PMU5_PLL_MDIV_MASK; - W_REG(osh, &cc->pllcontrol_addr, pll0 + PMU5_PLL_NM5_OFF); - (void)R_REG(osh, &cc->pllcontrol_addr); - tmp = R_REG(osh, &cc->pllcontrol_data); + W_REG(&cc->pllcontrol_addr, pll0 + PMU5_PLL_NM5_OFF); + (void)R_REG(&cc->pllcontrol_addr); + tmp = R_REG(&cc->pllcontrol_data); ndiv = (tmp & PMU5_PLL_NDIV_MASK) >> PMU5_PLL_NDIV_SHIFT; /* Do calculation in Mhz */ @@ -1858,9 +1854,9 @@ u32 si_pmu_ilp_clock(si_t *sih, struct osl_info *osh) u32 origidx = si_coreidx(sih); chipcregs_t *cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); - start = R_REG(osh, &cc->pmutimer); + start = R_REG(&cc->pmutimer); mdelay(ILP_CALC_DUR); - end = R_REG(osh, &cc->pmutimer); + end = R_REG(&cc->pmutimer); delta = end - start; ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR); si_setcoreidx(sih, origidx); @@ -1967,12 +1963,12 @@ si_sdiod_drive_strength_init(si_t *sih, struct osl_info *osh, } } - W_REG(osh, &cc->chipcontrol_addr, 1); - cc_data_temp = R_REG(osh, &cc->chipcontrol_data); + W_REG(&cc->chipcontrol_addr, 1); + cc_data_temp = R_REG(&cc->chipcontrol_data); cc_data_temp &= ~str_mask; drivestrength_sel <<= str_shift; cc_data_temp |= drivestrength_sel; - W_REG(osh, &cc->chipcontrol_data, cc_data_temp); + W_REG(&cc->chipcontrol_data, cc_data_temp); PMU_MSG(("SDIO: %dmA drive strength selected, set to 0x%08x\n", drivestrength, cc_data_temp)); @@ -1996,17 +1992,17 @@ void si_pmu_init(si_t *sih, struct osl_info *osh) ASSERT(cc != NULL); if (sih->pmurev == 1) - AND_REG(osh, &cc->pmucontrol, ~PCTL_NOILP_ON_WAIT); + AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT); else if (sih->pmurev >= 2) - OR_REG(osh, &cc->pmucontrol, PCTL_NOILP_ON_WAIT); + OR_REG(&cc->pmucontrol, PCTL_NOILP_ON_WAIT); if ((sih->chip == BCM4329_CHIP_ID) && (sih->chiprev == 2)) { /* Fix for 4329b0 bad LPOM state. */ - W_REG(osh, &cc->regcontrol_addr, 2); - OR_REG(osh, &cc->regcontrol_data, 0x100); + W_REG(&cc->regcontrol_addr, 2); + OR_REG(&cc->regcontrol_data, 0x100); - W_REG(osh, &cc->regcontrol_addr, 3); - OR_REG(osh, &cc->regcontrol_data, 0x4); + W_REG(&cc->regcontrol_addr, 3); + OR_REG(&cc->regcontrol_data, 0x4); } /* Return to original core */ @@ -2022,8 +2018,8 @@ si_pmu_res_uptime(si_t *sih, struct osl_info *osh, chipcregs_t *cc, u32 min_mask = 0, max_mask = 0; /* uptime of resource 'rsrc' */ - W_REG(osh, &cc->res_table_sel, rsrc); - up = (R_REG(osh, &cc->res_updn_timer) >> 8) & 0xff; + W_REG(&cc->res_table_sel, rsrc); + up = (R_REG(&cc->res_updn_timer) >> 8) & 0xff; /* direct dependancies of resource 'rsrc' */ deps = si_pmu_res_deps(sih, osh, cc, PMURES_BIT(rsrc), false); @@ -2061,8 +2057,8 @@ si_pmu_res_deps(si_t *sih, struct osl_info *osh, chipcregs_t *cc, u32 rsrcs, for (i = 0; i <= PMURES_MAX_RESNUM; i++) { if (!(rsrcs & PMURES_BIT(i))) continue; - W_REG(osh, &cc->res_table_sel, i); - deps |= R_REG(osh, &cc->res_dep_mask); + W_REG(&cc->res_table_sel, i); + deps |= R_REG(&cc->res_dep_mask); } return !all ? deps : (deps @@ -2120,17 +2116,17 @@ void si_pmu_otp_power(si_t *sih, struct osl_info *osh, bool on) if (on) { PMU_MSG(("Adding rsrc 0x%x to min_res_mask\n", rsrcs | deps)); - OR_REG(osh, &cc->min_res_mask, (rsrcs | deps)); - SPINWAIT(!(R_REG(osh, &cc->res_state) & rsrcs), + OR_REG(&cc->min_res_mask, (rsrcs | deps)); + SPINWAIT(!(R_REG(&cc->res_state) & rsrcs), PMU_MAX_TRANSITION_DLY); - ASSERT(R_REG(osh, &cc->res_state) & rsrcs); + ASSERT(R_REG(&cc->res_state) & rsrcs); } else { PMU_MSG(("Removing rsrc 0x%x from min_res_mask\n", rsrcs | deps)); - AND_REG(osh, &cc->min_res_mask, ~(rsrcs | deps)); + AND_REG(&cc->min_res_mask, ~(rsrcs | deps)); } - SPINWAIT((((otps = R_REG(osh, &cc->otpstatus)) & OTPS_READY) != + SPINWAIT((((otps = R_REG(&cc->otpstatus)) & OTPS_READY) != (on ? OTPS_READY : 0)), 100); ASSERT((otps & OTPS_READY) == (on ? OTPS_READY : 0)); if ((otps & OTPS_READY) != (on ? OTPS_READY : 0)) @@ -2160,60 +2156,56 @@ void si_pmu_rcal(si_t *sih, struct osl_info *osh) u32 val; /* Kick RCal */ - W_REG(osh, &cc->chipcontrol_addr, 1); + W_REG(&cc->chipcontrol_addr, 1); /* Power Down RCAL Block */ - AND_REG(osh, &cc->chipcontrol_data, ~0x04); + AND_REG(&cc->chipcontrol_data, ~0x04); /* Power Up RCAL block */ - OR_REG(osh, &cc->chipcontrol_data, 0x04); + OR_REG(&cc->chipcontrol_data, 0x04); /* Wait for completion */ - SPINWAIT(0 == (R_REG(osh, &cc->chipstatus) & 0x08), + SPINWAIT(0 == (R_REG(&cc->chipstatus) & 0x08), 10 * 1000 * 1000); - ASSERT(R_REG(osh, &cc->chipstatus) & 0x08); + ASSERT(R_REG(&cc->chipstatus) & 0x08); /* Drop the LSB to convert from 5 bit code to 4 bit code */ rcal_code = - (u8) (R_REG(osh, &cc->chipstatus) >> 5) & 0x0f; + (u8) (R_REG(&cc->chipstatus) >> 5) & 0x0f; PMU_MSG(("RCal completed, status 0x%x, code 0x%x\n", - R_REG(osh, &cc->chipstatus), rcal_code)); + R_REG(&cc->chipstatus), rcal_code)); /* Write RCal code into pmu_vreg_ctrl[32:29] */ - W_REG(osh, &cc->regcontrol_addr, 0); + W_REG(&cc->regcontrol_addr, 0); val = - R_REG(osh, - &cc-> - regcontrol_data) & ~((u32) 0x07 << 29); + R_REG(&cc->regcontrol_data) & ~((u32) 0x07 << 29); val |= (u32) (rcal_code & 0x07) << 29; - W_REG(osh, &cc->regcontrol_data, val); - W_REG(osh, &cc->regcontrol_addr, 1); - val = R_REG(osh, &cc->regcontrol_data) & ~(u32) 0x01; + W_REG(&cc->regcontrol_data, val); + W_REG(&cc->regcontrol_addr, 1); + val = R_REG(&cc->regcontrol_data) & ~(u32) 0x01; val |= (u32) ((rcal_code >> 3) & 0x01); - W_REG(osh, &cc->regcontrol_data, val); + W_REG(&cc->regcontrol_data, val); /* Write RCal code into pmu_chip_ctrl[33:30] */ - W_REG(osh, &cc->chipcontrol_addr, 0); + W_REG(&cc->chipcontrol_addr, 0); val = - R_REG(osh, - &cc-> - chipcontrol_data) & ~((u32) 0x03 << 30); + R_REG(&cc->chipcontrol_data) & ~((u32) 0x03 << 30); val |= (u32) (rcal_code & 0x03) << 30; - W_REG(osh, &cc->chipcontrol_data, val); - W_REG(osh, &cc->chipcontrol_addr, 1); + W_REG(&cc->chipcontrol_data, val); + W_REG(&cc->chipcontrol_addr, 1); val = - R_REG(osh, &cc->chipcontrol_data) & ~(u32) 0x03; + R_REG(&cc->chipcontrol_data) & ~(u32) 0x03; val |= (u32) ((rcal_code >> 2) & 0x03); - W_REG(osh, &cc->chipcontrol_data, val); + W_REG(&cc->chipcontrol_data, val); /* Set override in pmu_chip_ctrl[29] */ - W_REG(osh, &cc->chipcontrol_addr, 0); - OR_REG(osh, &cc->chipcontrol_data, (0x01 << 29)); + W_REG(&cc->chipcontrol_addr, 0); + OR_REG(&cc->chipcontrol_data, (0x01 << 29)); /* Power off RCal block */ - W_REG(osh, &cc->chipcontrol_addr, 1); - AND_REG(osh, &cc->chipcontrol_data, ~0x04); + W_REG(&cc->chipcontrol_addr, 1); + AND_REG(&cc->chipcontrol_data, ~0x04); break; } @@ -2238,13 +2230,13 @@ void si_pmu_spuravoid(si_t *sih, struct osl_info *osh, u8 spuravoid) /* force the HT off */ if (sih->chip == BCM4336_CHIP_ID) { - tmp = R_REG(osh, &cc->max_res_mask); + tmp = R_REG(&cc->max_res_mask); tmp &= ~RES4336_HT_AVAIL; - W_REG(osh, &cc->max_res_mask, tmp); + W_REG(&cc->max_res_mask, tmp); /* wait for the ht to really go away */ - SPINWAIT(((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) == 0), + SPINWAIT(((R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL) == 0), 10000); - ASSERT((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) == 0); + ASSERT((R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL) == 0); } /* update the pll changes */ @@ -2252,9 +2244,9 @@ void si_pmu_spuravoid(si_t *sih, struct osl_info *osh, u8 spuravoid) /* enable HT back on */ if (sih->chip == BCM4336_CHIP_ID) { - tmp = R_REG(osh, &cc->max_res_mask); + tmp = R_REG(&cc->max_res_mask); tmp |= RES4336_HT_AVAIL; - W_REG(osh, &cc->max_res_mask, tmp); + W_REG(&cc->max_res_mask, tmp); } /* Return to original core */ @@ -2280,44 +2272,44 @@ si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, struct osl_info *osh, phypll_offset = (sih->chip == BCM5357_CHIP_ID) ? 6 : 0; /* RMW only the P1 divider */ - W_REG(osh, &cc->pllcontrol_addr, + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0 + phypll_offset); - tmp = R_REG(osh, &cc->pllcontrol_data); + tmp = R_REG(&cc->pllcontrol_data); tmp &= (~(PMU1_PLL0_PC0_P1DIV_MASK)); tmp |= (bcm5357_bcm43236_p1div[spuravoid] << PMU1_PLL0_PC0_P1DIV_SHIFT); - W_REG(osh, &cc->pllcontrol_data, tmp); + W_REG(&cc->pllcontrol_data, tmp); /* RMW only the int feedback divider */ - W_REG(osh, &cc->pllcontrol_addr, + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2 + phypll_offset); - tmp = R_REG(osh, &cc->pllcontrol_data); + tmp = R_REG(&cc->pllcontrol_data); tmp &= ~(PMU1_PLL0_PC2_NDIV_INT_MASK); tmp |= (bcm5357_bcm43236_ndiv[spuravoid]) << PMU1_PLL0_PC2_NDIV_INT_SHIFT; - W_REG(osh, &cc->pllcontrol_data, tmp); + W_REG(&cc->pllcontrol_data, tmp); tmp = 1 << 10; break; case BCM4331_CHIP_ID: if (spuravoid == 2) { - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(osh, &cc->pllcontrol_data, 0x11500014); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(osh, &cc->pllcontrol_data, 0x0FC00a08); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11500014); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x0FC00a08); } else if (spuravoid == 1) { - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(osh, &cc->pllcontrol_data, 0x11500014); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(osh, &cc->pllcontrol_data, 0x0F600a08); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11500014); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x0F600a08); } else { - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(osh, &cc->pllcontrol_data, 0x11100014); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(osh, &cc->pllcontrol_data, 0x03000a08); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11100014); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x03000a08); } tmp = 1 << 10; break; @@ -2327,47 +2319,47 @@ si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, struct osl_info *osh, case BCM43421_CHIP_ID: case BCM6362_CHIP_ID: if (spuravoid == 1) { - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(osh, &cc->pllcontrol_data, 0x11500010); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(osh, &cc->pllcontrol_data, 0x000C0C06); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(osh, &cc->pllcontrol_data, 0x0F600a08); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - W_REG(osh, &cc->pllcontrol_data, 0x00000000); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - W_REG(osh, &cc->pllcontrol_data, 0x2001E920); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(osh, &cc->pllcontrol_data, 0x88888815); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11500010); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); + W_REG(&cc->pllcontrol_data, 0x000C0C06); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x0F600a08); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); + W_REG(&cc->pllcontrol_data, 0x00000000); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); + W_REG(&cc->pllcontrol_data, 0x2001E920); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); + W_REG(&cc->pllcontrol_data, 0x88888815); } else { - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(osh, &cc->pllcontrol_data, 0x11100010); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(osh, &cc->pllcontrol_data, 0x000c0c06); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(osh, &cc->pllcontrol_data, 0x03000a08); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - W_REG(osh, &cc->pllcontrol_data, 0x00000000); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - W_REG(osh, &cc->pllcontrol_data, 0x200005c0); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(osh, &cc->pllcontrol_data, 0x88888815); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11100010); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); + W_REG(&cc->pllcontrol_data, 0x000c0c06); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x03000a08); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); + W_REG(&cc->pllcontrol_data, 0x00000000); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); + W_REG(&cc->pllcontrol_data, 0x200005c0); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); + W_REG(&cc->pllcontrol_data, 0x88888815); } tmp = 1 << 10; break; - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(osh, &cc->pllcontrol_data, 0x11100008); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(osh, &cc->pllcontrol_data, 0x0c000c06); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(osh, &cc->pllcontrol_data, 0x03000a08); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - W_REG(osh, &cc->pllcontrol_data, 0x00000000); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - W_REG(osh, &cc->pllcontrol_data, 0x200005c0); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(osh, &cc->pllcontrol_data, 0x88888855); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11100008); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); + W_REG(&cc->pllcontrol_data, 0x0c000c06); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x03000a08); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); + W_REG(&cc->pllcontrol_data, 0x00000000); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); + W_REG(&cc->pllcontrol_data, 0x200005c0); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); + W_REG(&cc->pllcontrol_data, 0x88888855); tmp = 1 << 10; break; @@ -2376,74 +2368,74 @@ si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, struct osl_info *osh, case BCM4748_CHIP_ID: case BCM47162_CHIP_ID: if (spuravoid == 1) { - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(osh, &cc->pllcontrol_data, 0x11500060); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(osh, &cc->pllcontrol_data, 0x080C0C06); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(osh, &cc->pllcontrol_data, 0x0F600000); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - W_REG(osh, &cc->pllcontrol_data, 0x00000000); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - W_REG(osh, &cc->pllcontrol_data, 0x2001E924); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(osh, &cc->pllcontrol_data, 0x88888815); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11500060); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); + W_REG(&cc->pllcontrol_data, 0x080C0C06); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x0F600000); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); + W_REG(&cc->pllcontrol_data, 0x00000000); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); + W_REG(&cc->pllcontrol_data, 0x2001E924); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); + W_REG(&cc->pllcontrol_data, 0x88888815); } else { - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(osh, &cc->pllcontrol_data, 0x11100060); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(osh, &cc->pllcontrol_data, 0x080c0c06); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(osh, &cc->pllcontrol_data, 0x03000000); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - W_REG(osh, &cc->pllcontrol_data, 0x00000000); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - W_REG(osh, &cc->pllcontrol_data, 0x200005c0); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(osh, &cc->pllcontrol_data, 0x88888815); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11100060); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); + W_REG(&cc->pllcontrol_data, 0x080c0c06); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x03000000); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); + W_REG(&cc->pllcontrol_data, 0x00000000); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); + W_REG(&cc->pllcontrol_data, 0x200005c0); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); + W_REG(&cc->pllcontrol_data, 0x88888815); } tmp = 3 << 9; break; case BCM4319_CHIP_ID: - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(osh, &cc->pllcontrol_data, 0x11100070); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(osh, &cc->pllcontrol_data, 0x1014140a); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(osh, &cc->pllcontrol_data, 0x88888854); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11100070); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); + W_REG(&cc->pllcontrol_data, 0x1014140a); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); + W_REG(&cc->pllcontrol_data, 0x88888854); if (spuravoid == 1) { /* spur_avoid ON, enable 41/82/164Mhz clock mode */ - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(osh, &cc->pllcontrol_data, 0x05201828); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x05201828); } else { /* enable 40/80/160Mhz clock mode */ - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(osh, &cc->pllcontrol_data, 0x05001828); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x05001828); } break; case BCM4336_CHIP_ID: /* Looks like these are only for default xtal freq 26MHz */ - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(osh, &cc->pllcontrol_data, 0x02100020); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x02100020); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(osh, &cc->pllcontrol_data, 0x0C0C0C0C); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); + W_REG(&cc->pllcontrol_data, 0x0C0C0C0C); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(osh, &cc->pllcontrol_data, 0x01240C0C); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x01240C0C); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - W_REG(osh, &cc->pllcontrol_data, 0x202C2820); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); + W_REG(&cc->pllcontrol_data, 0x202C2820); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(osh, &cc->pllcontrol_data, 0x88888825); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); + W_REG(&cc->pllcontrol_data, 0x88888825); - W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); if (spuravoid == 1) { - W_REG(osh, &cc->pllcontrol_data, 0x00EC4EC4); + W_REG(&cc->pllcontrol_data, 0x00EC4EC4); } else { - W_REG(osh, &cc->pllcontrol_data, 0x00762762); + W_REG(&cc->pllcontrol_data, 0x00762762); } tmp = PCTL_PLL_PLLCTL_UPD; @@ -2454,8 +2446,8 @@ si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, struct osl_info *osh, break; } - tmp |= R_REG(osh, &cc->pmucontrol); - W_REG(osh, &cc->pmucontrol, tmp); + tmp |= R_REG(&cc->pmucontrol); + W_REG(&cc->pmucontrol, tmp); } bool si_pmu_is_otp_powered(si_t *sih, struct osl_info *osh) @@ -2471,19 +2463,19 @@ bool si_pmu_is_otp_powered(si_t *sih, struct osl_info *osh) switch (sih->chip) { case BCM4329_CHIP_ID: - st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4329_OTP_PU)) + st = (R_REG(&cc->res_state) & PMURES_BIT(RES4329_OTP_PU)) != 0; break; case BCM4319_CHIP_ID: - st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4319_OTP_PU)) + st = (R_REG(&cc->res_state) & PMURES_BIT(RES4319_OTP_PU)) != 0; break; case BCM4336_CHIP_ID: - st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4336_OTP_PU)) + st = (R_REG(&cc->res_state) & PMURES_BIT(RES4336_OTP_PU)) != 0; break; case BCM4330_CHIP_ID: - st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4330_OTP_PU)) + st = (R_REG(&cc->res_state) & PMURES_BIT(RES4330_OTP_PU)) != 0; break; @@ -2603,12 +2595,12 @@ si_pmu_waitforclk_on_backplane(si_t *sih, struct osl_info *osh, u32 clk, ASSERT(cc != NULL); if (delay) - SPINWAIT(((R_REG(osh, &cc->pmustatus) & clk) != clk), delay); + SPINWAIT(((R_REG(&cc->pmustatus) & clk) != clk), delay); /* Return to original core */ si_setcoreidx(sih, origidx); - return R_REG(osh, &cc->pmustatus) & clk; + return R_REG(&cc->pmustatus) & clk; } /* @@ -2634,11 +2626,11 @@ u32 si_pmu_measure_alpclk(si_t *sih, struct osl_info *osh) cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); - if (R_REG(osh, &cc->pmustatus) & PST_EXTLPOAVAIL) { + if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) { u32 ilp_ctr, alp_hz; /* Enable the reg to measure the freq, in case disabled before */ - W_REG(osh, &cc->pmu_xtalfreq, + W_REG(&cc->pmu_xtalfreq, 1U << PMU_XTALFREQ_REG_MEASURE_SHIFT); /* Delay for well over 4 ILP clocks */ @@ -2646,11 +2638,10 @@ u32 si_pmu_measure_alpclk(si_t *sih, struct osl_info *osh) /* Read the latched number of ALP ticks per 4 ILP ticks */ ilp_ctr = - R_REG(osh, - &cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK; + R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK; /* Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT bit to save power */ - W_REG(osh, &cc->pmu_xtalfreq, 0); + W_REG(&cc->pmu_xtalfreq, 0); /* Calculate ALP frequency */ alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4; diff --git a/drivers/staging/brcm80211/util/nicpci.c b/drivers/staging/brcm80211/util/nicpci.c index 7f587f30844d..c8f08d88870f 100644 --- a/drivers/staging/brcm80211/util/nicpci.c +++ b/drivers/staging/brcm80211/util/nicpci.c @@ -194,14 +194,14 @@ pcie_readreg(struct osl_info *osh, sbpcieregs_t *pcieregs, uint addrtype, switch (addrtype) { case PCIE_CONFIGREGS: - W_REG(osh, (&pcieregs->configaddr), offset); - (void)R_REG(osh, (&pcieregs->configaddr)); - retval = R_REG(osh, &(pcieregs->configdata)); + W_REG((&pcieregs->configaddr), offset); + (void)R_REG((&pcieregs->configaddr)); + retval = R_REG(&(pcieregs->configdata)); break; case PCIE_PCIEREGS: - W_REG(osh, &(pcieregs->pcieindaddr), offset); - (void)R_REG(osh, (&pcieregs->pcieindaddr)); - retval = R_REG(osh, &(pcieregs->pcieinddata)); + W_REG(&(pcieregs->pcieindaddr), offset); + (void)R_REG((&pcieregs->pcieindaddr)); + retval = R_REG(&(pcieregs->pcieinddata)); break; default: ASSERT(0); @@ -219,12 +219,12 @@ pcie_writereg(struct osl_info *osh, sbpcieregs_t *pcieregs, uint addrtype, switch (addrtype) { case PCIE_CONFIGREGS: - W_REG(osh, (&pcieregs->configaddr), offset); - W_REG(osh, (&pcieregs->configdata), val); + W_REG((&pcieregs->configaddr), offset); + W_REG((&pcieregs->configdata), val); break; case PCIE_PCIEREGS: - W_REG(osh, (&pcieregs->pcieindaddr), offset); - W_REG(osh, (&pcieregs->pcieinddata), val); + W_REG((&pcieregs->pcieindaddr), offset); + W_REG((&pcieregs->pcieinddata), val); break; default: ASSERT(0); @@ -244,12 +244,12 @@ static bool pcie_mdiosetblock(pcicore_info_t *pi, uint blk) MDIODATA_DEVADDR_SHF) | (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) | MDIODATA_TA | (blk << 4); - W_REG(pi->osh, &pcieregs->mdiodata, mdiodata); + W_REG(&pcieregs->mdiodata, mdiodata); PR28829_DELAY(); /* retry till the transaction is complete */ while (i < pcie_serdes_spinwait) { - if (R_REG(pi->osh, &(pcieregs->mdiocontrol)) & + if (R_REG(&(pcieregs->mdiocontrol)) & MDIOCTL_ACCESS_DONE) { break; } @@ -275,7 +275,7 @@ pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr, bool write, uint pcie_serdes_spinwait = 10; /* enable mdio access to SERDES */ - W_REG(pi->osh, (&pcieregs->mdiocontrol), + W_REG((&pcieregs->mdiocontrol), MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL); if (pi->sih->buscorerev >= 10) { @@ -296,22 +296,22 @@ pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr, bool write, mdiodata |= (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA | *val); - W_REG(pi->osh, &pcieregs->mdiodata, mdiodata); + W_REG(&pcieregs->mdiodata, mdiodata); PR28829_DELAY(); /* retry till the transaction is complete */ while (i < pcie_serdes_spinwait) { - if (R_REG(pi->osh, &(pcieregs->mdiocontrol)) & + if (R_REG(&(pcieregs->mdiocontrol)) & MDIOCTL_ACCESS_DONE) { if (!write) { PR28829_DELAY(); *val = - (R_REG(pi->osh, &(pcieregs->mdiodata)) & + (R_REG(&(pcieregs->mdiodata)) & MDIODATA_MASK); } /* Disable mdio access to SERDES */ - W_REG(pi->osh, (&pcieregs->mdiocontrol), 0); + W_REG((&pcieregs->mdiocontrol), 0); return 0; } udelay(1000); @@ -320,7 +320,7 @@ pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr, bool write, PCI_ERROR(("pcie_mdioop: timed out op: %d\n", write)); /* Disable mdio access to SERDES */ - W_REG(pi->osh, (&pcieregs->mdiocontrol), 0); + W_REG((&pcieregs->mdiocontrol), 0); return 1; } @@ -466,7 +466,7 @@ static void pcie_war_aspm_clkreq(pcicore_info_t *pi) if (!ISSIM_ENAB(sih)) { reg16 = &pcieregs->sprom[SRSH_ASPM_OFFSET]; - val16 = R_REG(pi->osh, reg16); + val16 = R_REG(reg16); val16 &= ~SRSH_ASPM_ENB; if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB) @@ -476,7 +476,7 @@ static void pcie_war_aspm_clkreq(pcicore_info_t *pi) else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB) val16 |= SRSH_ASPM_L0s_ENB; - W_REG(pi->osh, reg16, val16); + W_REG(reg16, val16); pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w); @@ -487,7 +487,7 @@ static void pcie_war_aspm_clkreq(pcicore_info_t *pi) } reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV5]; - val16 = R_REG(pi->osh, reg16); + val16 = R_REG(reg16); if (pi->pcie_war_aspm_ovr != PCIE_ASPM_DISAB) { val16 |= SRSH_CLKREQ_ENB; @@ -495,7 +495,7 @@ static void pcie_war_aspm_clkreq(pcicore_info_t *pi) } else val16 &= ~SRSH_CLKREQ_ENB; - W_REG(pi->osh, reg16, val16); + W_REG(reg16, val16); } /* Apply the polarity determined at the start */ @@ -523,11 +523,11 @@ static void pcie_misc_config_fixup(pcicore_info_t *pi) u16 val16, *reg16; reg16 = &pcieregs->sprom[SRSH_PCIE_MISC_CONFIG]; - val16 = R_REG(pi->osh, reg16); + val16 = R_REG(reg16); if ((val16 & SRSH_L23READY_EXIT_NOPERST) == 0) { val16 |= SRSH_L23READY_EXIT_NOPERST; - W_REG(pi->osh, reg16, val16); + W_REG(reg16, val16); } } @@ -546,7 +546,7 @@ static void pcie_war_noplldown(pcicore_info_t *pi) /* clear srom shadow backdoor */ reg16 = &pcieregs->sprom[SRSH_BD_OFFSET]; - W_REG(pi->osh, reg16, 0); + W_REG(reg16, 0); } /* Needs to happen when coming out of 'standby'/'hibernate' */ diff --git a/drivers/staging/brcm80211/util/nvram/nvram_ro.c b/drivers/staging/brcm80211/util/nvram/nvram_ro.c index ec4077945140..a5e8c4daaa15 100644 --- a/drivers/staging/brcm80211/util/nvram/nvram_ro.c +++ b/drivers/staging/brcm80211/util/nvram/nvram_ro.c @@ -48,13 +48,10 @@ static char *findvar(char *vars, char *lim, const char *name); /* copy flash to ram */ static void get_flash_nvram(si_t *sih, struct nvram_header *nvh) { - struct osl_info *osh; uint nvs, bufsz; vars_t *new; - osh = si_osh(sih); - - nvs = R_REG(osh, &nvh->len) - sizeof(struct nvram_header); + nvs = R_REG(&nvh->len) - sizeof(struct nvram_header); bufsz = nvs + VARS_T_OH; new = kmalloc(bufsz, GFP_ATOMIC); diff --git a/drivers/staging/brcm80211/util/sbutils.c b/drivers/staging/brcm80211/util/sbutils.c index 6d63dc1fca11..75381e4d6da7 100644 --- a/drivers/staging/brcm80211/util/sbutils.c +++ b/drivers/staging/brcm80211/util/sbutils.c @@ -54,12 +54,12 @@ static void *_sb_setcoreidx(si_info_t *sii, uint coreidx); static u32 sb_read_sbreg(si_info_t *sii, volatile u32 *sbr) { - return R_REG(sii->osh, sbr); + return R_REG(sbr); } static void sb_write_sbreg(si_info_t *sii, volatile u32 *sbr, u32 v) { - W_REG(sii->osh, sbr, v); + W_REG(sbr, v); } uint sb_coreid(si_t *sih) @@ -178,8 +178,8 @@ uint sb_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) w = (R_SBREG(sii, r) & ~mask) | val; W_SBREG(sii, r, w); } else { - w = (R_REG(sii->osh, r) & ~mask) | val; - W_REG(sii->osh, r, w); + w = (R_REG(r) & ~mask) | val; + W_REG(r, w); } } @@ -187,7 +187,7 @@ uint sb_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) if (regoff >= SBCONFIGOFF) w = R_SBREG(sii, r); else - w = R_REG(sii->osh, r); + w = R_REG(r); if (!fast) { /* restore core index */ @@ -246,7 +246,7 @@ static uint _sb_scan(si_info_t *sii, u32 sba, void *regs, uint bus, u32 sbba, total # cores in the chip */ if (((ccrev == 4) || (ccrev >= 6))) numcores = - (R_REG(sii->osh, &cc->chipid) & CID_CC_MASK) + (R_REG(&cc->chipid) & CID_CC_MASK) >> CID_CC_SHIFT; else { /* Older chips */ diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index 9a2e2c0f77be..1357302ffb87 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -180,19 +180,19 @@ static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, /* get chipcommon chipstatus */ if (sii->pub.ccrev >= 11) - sii->pub.chipst = R_REG(sii->osh, &cc->chipstatus); + sii->pub.chipst = R_REG(&cc->chipstatus); /* get chipcommon capabilites */ - sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities); + sii->pub.cccaps = R_REG(&cc->capabilities); /* get chipcommon extended capabilities */ #ifndef BRCM_FULLMAC if (sii->pub.ccrev >= 35) - sii->pub.cccaps_ext = R_REG(sii->osh, &cc->capabilities_ext); + sii->pub.cccaps_ext = R_REG(&cc->capabilities_ext); #endif /* get pmu rev and caps */ if (sii->pub.cccaps & CC_CAP_PMU) { - sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities); + sii->pub.pmucaps = R_REG(&cc->pmucapabilities); sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK; } @@ -404,7 +404,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon), * some way of recognizing them needs to be added here. */ - w = R_REG(osh, &cc->chipid); + w = R_REG(&cc->chipid); sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT; /* Might as wll fill in chip id rev & pkg */ sih->chip = w & CID_ID_MASK; @@ -455,8 +455,8 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, if (sii->pub.ccrev >= 20) { #endif cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0); - W_REG(osh, &cc->gpiopullup, 0); - W_REG(osh, &cc->gpiopulldown, 0); + W_REG(&cc->gpiopullup, 0); + W_REG(&cc->gpiopulldown, 0); sb_setcoreidx(sih, origidx); #ifdef BRCM_FULLMAC } @@ -555,7 +555,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon), * some way of recognizing them needs to be added here. */ - w = R_REG(osh, &cc->chipid); + w = R_REG(&cc->chipid); sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT; /* Might as wll fill in chip id rev & pkg */ sih->chip = w & CID_ID_MASK; @@ -595,10 +595,10 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, if ((cc->chipstatus & CST43236_BP_CLK) != 0) { uint clkdiv; - clkdiv = R_REG(osh, &cc->clkdiv); + clkdiv = R_REG(&cc->clkdiv); /* otp_clk_div is even number, 120/14 < 9mhz */ clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT); - W_REG(osh, &cc->clkdiv, clkdiv); + W_REG(&cc->clkdiv, clkdiv); SI_ERROR(("%s: set clkdiv to %x\n", __func__, clkdiv)); } udelay(10); @@ -618,8 +618,8 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, /* === NVRAM, clock is ready === */ cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0); - W_REG(osh, &cc->gpiopullup, 0); - W_REG(osh, &cc->gpiopulldown, 0); + W_REG(&cc->gpiopullup, 0); + W_REG(&cc->gpiopulldown, 0); si_setcoreidx(sih, origidx); /* PMU specific initializations */ @@ -1095,7 +1095,7 @@ static uint si_slowclk_src(si_info_t *sii) return SCC_SS_XTAL; } else if (sii->pub.ccrev < 10) { cc = (chipcregs_t *) si_setcoreidx(&sii->pub, sii->curidx); - return R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_SS_MASK; + return R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK; } else /* Insta-clock */ return SCC_SS_XTAL; } @@ -1109,7 +1109,7 @@ static uint si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc) ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID); /* shouldn't be here unless we've established the chip has dynamic clk control */ - ASSERT(R_REG(sii->osh, &cc->capabilities) & CC_CAP_PWR_CTL); + ASSERT(R_REG(&cc->capabilities) & CC_CAP_PWR_CTL); slowclk = si_slowclk_src(sii); if (sii->pub.ccrev < 6) { @@ -1121,7 +1121,7 @@ static uint si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc) : (XTALMINFREQ / 32); } else if (sii->pub.ccrev < 10) { div = 4 * - (((R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >> + (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); if (slowclk == SCC_SS_LPO) return max_freq ? LPOMAXFREQ : LPOMINFREQ; @@ -1135,7 +1135,7 @@ static uint si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc) ASSERT(0); } else { /* Chipc rev 10 is InstaClock */ - div = R_REG(sii->osh, &cc->system_clk_ctl) >> SYCC_CD_SHIFT; + div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT; div = 4 * (div + 1); return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div); } @@ -1165,8 +1165,8 @@ static void si_clkctl_setdelay(si_info_t *sii, void *chipcregs) pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; - W_REG(sii->osh, &cc->pll_on_delay, pll_on_delay); - W_REG(sii->osh, &cc->fref_sel_delay, fref_sel_delay); + W_REG(&cc->pll_on_delay, pll_on_delay); + W_REG(&cc->fref_sel_delay, fref_sel_delay); } /* initialize power control delay registers */ @@ -1196,7 +1196,7 @@ void si_clkctl_init(si_t *sih) /* set all Instaclk chip ILP to 1 MHz */ if (sih->ccrev >= 10) - SET_REG(sii->osh, &cc->system_clk_ctl, SYCC_CD_MASK, + SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK, (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); si_clkctl_setdelay(sii, (void *)cc); @@ -1243,7 +1243,7 @@ u16 si_clkctl_fast_pwrup_delay(si_t *sih) ASSERT(cc != NULL); slowminfreq = si_slowclk_freq(sii, false, cc); - fpdelay = (((R_REG(sii->osh, &cc->pll_on_delay) + 2) * 1000000) + + fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) + (slowminfreq - 1)) / slowminfreq; done: @@ -1394,20 +1394,20 @@ static bool _si_clkctl_cc(si_info_t *sii, uint mode) if (sii->pub.ccrev < 10) { /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */ si_clkctl_xtal(&sii->pub, XTAL, ON); - SET_REG(sii->osh, &cc->slow_clk_ctl, + SET_REG(&cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP); } else if (sii->pub.ccrev < 20) { - OR_REG(sii->osh, &cc->system_clk_ctl, SYCC_HR); + OR_REG(&cc->system_clk_ctl, SYCC_HR); } else { - OR_REG(sii->osh, &cc->clk_ctl_st, CCS_FORCEHT); + OR_REG(&cc->clk_ctl_st, CCS_FORCEHT); } /* wait for the PLL */ if (PMUCTL_ENAB(&sii->pub)) { u32 htavail = CCS_HTAVAIL; - SPINWAIT(((R_REG(sii->osh, &cc->clk_ctl_st) & htavail) + SPINWAIT(((R_REG(&cc->clk_ctl_st) & htavail) == 0), PMU_MAX_TRANSITION_DLY); - ASSERT(R_REG(sii->osh, &cc->clk_ctl_st) & htavail); + ASSERT(R_REG(&cc->clk_ctl_st) & htavail); } else { udelay(PLL_DELAY); } @@ -1415,20 +1415,20 @@ static bool _si_clkctl_cc(si_info_t *sii, uint mode) case CLK_DYNAMIC: /* enable dynamic clock control */ if (sii->pub.ccrev < 10) { - scc = R_REG(sii->osh, &cc->slow_clk_ctl); + scc = R_REG(&cc->slow_clk_ctl); scc &= ~(SCC_FS | SCC_IP | SCC_XC); if ((scc & SCC_SS_MASK) != SCC_SS_XTAL) scc |= SCC_XC; - W_REG(sii->osh, &cc->slow_clk_ctl, scc); + W_REG(&cc->slow_clk_ctl, scc); /* for dynamic control, we have to release our xtal_pu "force on" */ if (scc & SCC_XC) si_clkctl_xtal(&sii->pub, XTAL, OFF); } else if (sii->pub.ccrev < 20) { /* Instaclock */ - AND_REG(sii->osh, &cc->system_clk_ctl, ~SYCC_HR); + AND_REG(&cc->system_clk_ctl, ~SYCC_HR); } else { - AND_REG(sii->osh, &cc->clk_ctl_st, ~CCS_FORCEHT); + AND_REG(&cc->clk_ctl_st, ~CCS_FORCEHT); } break; @@ -1583,8 +1583,8 @@ void si_sdio_init(si_t *sih) SI_MSG(("si_sdio_init: For PCMCIA/SDIO Corerev %d, enable ints from core %d " "through SD core %d (%p)\n", sih->buscorerev, idx, sii->curidx, sdpregs)); /* enable backplane error and core interrupts */ - W_REG(sii->osh, &sdpregs->hostintmask, I_SBINT); - W_REG(sii->osh, &sdpregs->sbintmask, + W_REG(&sdpregs->hostintmask, I_SBINT); + W_REG(&sdpregs->sbintmask, (I_SB_SERR | I_SB_RESPERR | (1 << idx))); /* switch back to previous core */ @@ -1697,15 +1697,15 @@ void si_pci_setup(si_t *sih, uint coremask) } if (PCI(sii)) { - OR_REG(sii->osh, &pciregs->sbtopci2, + OR_REG(&pciregs->sbtopci2, (SBTOPCI_PREF | SBTOPCI_BURST)); if (sii->pub.buscorerev >= 11) { - OR_REG(sii->osh, &pciregs->sbtopci2, + OR_REG(&pciregs->sbtopci2, SBTOPCI_RC_READMULTI); - w = R_REG(sii->osh, &pciregs->clkrun); - W_REG(sii->osh, &pciregs->clkrun, + w = R_REG(&pciregs->clkrun); + W_REG(&pciregs->clkrun, (w | PCI_CLKRUN_DSBL)); - w = R_REG(sii->osh, &pciregs->clkrun); + w = R_REG(&pciregs->clkrun); } /* switch back to previous core */ @@ -1747,12 +1747,12 @@ int si_pci_fixcfg(si_t *sih) reg16 = &pciregs->sprom[SRSH_PI_OFFSET]; } pciidx = si_coreidx(&sii->pub); - val16 = R_REG(sii->osh, reg16); + val16 = R_REG(reg16); if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16) pciidx) { val16 = (u16) (pciidx << SRSH_PI_SHIFT) | (val16 & ~SRSH_PI_MASK); - W_REG(sii->osh, reg16, val16); + W_REG(reg16, val16); } /* restore the original index */ @@ -1793,8 +1793,8 @@ socram_banksize(si_info_t *sii, sbsocramregs_t *regs, u8 index, ASSERT(mem_type <= SOCRAM_MEMTYPE_DEVRAM); - W_REG(sii->osh, ®s->bankidx, bankidx); - bankinfo = R_REG(sii->osh, ®s->bankinfo); + W_REG(®s->bankidx, bankidx); + bankinfo = R_REG(®s->bankinfo); banksize = SOCRAM_BANKINFO_SZBASE * ((bankinfo & SOCRAM_BANKINFO_SZMASK) + 1); return banksize; @@ -1829,7 +1829,7 @@ u32 si_socram_size(si_t *sih) if (!wasup) si_core_reset(sih, 0, 0); corerev = si_corerev(sih); - coreinfo = R_REG(sii->osh, ®s->coreinfo); + coreinfo = R_REG(®s->coreinfo); /* Calculate size from coreinfo based on rev */ if (corerev == 0) @@ -1877,22 +1877,22 @@ void si_chipcontrl_epa4331(si_t *sih, bool on) cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0); - val = R_REG(sii->osh, &cc->chipcontrol); + val = R_REG(&cc->chipcontrol); if (on) { if (sih->chippkg == 9 || sih->chippkg == 0xb) { /* Ext PA Controls for 4331 12x9 Package */ - W_REG(sii->osh, &cc->chipcontrol, val | + W_REG(&cc->chipcontrol, val | (CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5)); } else { /* Ext PA Controls for 4331 12x12 Package */ - W_REG(sii->osh, &cc->chipcontrol, + W_REG(&cc->chipcontrol, val | (CCTRL4331_EXTPA_EN)); } } else { val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5); - W_REG(sii->osh, &cc->chipcontrol, val); + W_REG(&cc->chipcontrol, val); } si_setcoreidx(sih, origidx); @@ -1911,8 +1911,8 @@ void si_epa_4313war(si_t *sih) cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0); /* EPA Fix */ - W_REG(sii->osh, &cc->gpiocontrol, - R_REG(sii->osh, &cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK); + W_REG(&cc->gpiocontrol, + R_REG(&cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK); si_setcoreidx(sih, origidx); } @@ -1950,7 +1950,7 @@ bool si_is_sprom_available(si_t *sih) sii = SI_INFO(sih); origidx = sii->curidx; cc = si_setcoreidx(sih, SI_CC_IDX); - sromctrl = R_REG(sii->osh, &cc->sromcontrol); + sromctrl = R_REG(&cc->sromcontrol); si_setcoreidx(sih, origidx); return sromctrl & SRC_PRESENT; } -- cgit v1.2.3 From 26bcc1810b7c982ee3a220425c485c2a301abec1 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 1 Mar 2011 10:56:55 +0100 Subject: staging: brcm80211: remove usage of struct osl_info from util sources Most of the util source files do not need the osl_info anymore due to previous patches so usage of it has been removed. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 8 +- drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c | 4 +- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 4 +- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 2 +- drivers/staging/brcm80211/include/bcmsrom.h | 6 +- drivers/staging/brcm80211/include/bcmutils.h | 7 +- drivers/staging/brcm80211/include/hndpmu.h | 47 ++++--- drivers/staging/brcm80211/include/nicpci.h | 6 +- drivers/staging/brcm80211/include/siutils.h | 6 +- drivers/staging/brcm80211/util/bcmotp.c | 15 +-- drivers/staging/brcm80211/util/bcmsrom.c | 106 ++++++++-------- drivers/staging/brcm80211/util/bcmutils.c | 4 +- drivers/staging/brcm80211/util/hnddma.c | 12 +- drivers/staging/brcm80211/util/hndpmu.c | 136 ++++++++++----------- drivers/staging/brcm80211/util/nicpci.c | 37 +++--- drivers/staging/brcm80211/util/siutils.c | 64 ++++------ 16 files changed, 207 insertions(+), 257 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 65015b85b10e..32551a24b4be 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -2283,7 +2283,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, case IOV_SVAL(IOV_SDIOD_DRIVE): dhd_sdiod_drive_strength = int_val; - si_sdiod_drive_strength_init(bus->sih, bus->dhd->osh, + si_sdiod_drive_strength_init(bus->sih, dhd_sdiod_drive_strength); break; @@ -3329,7 +3329,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) F2SYNC, bus->dataptr, dlen, NULL, NULL, NULL); sublen = - (u16) pktfrombuf(osh, pfirst, 0, dlen, + (u16) pktfrombuf(pfirst, 0, dlen, bus->dataptr); if (sublen != dlen) { DHD_ERROR(("%s: FAILED TO COPY, dlen %d sublen %d\n", @@ -5317,7 +5317,7 @@ dhdsdio_probe_attach(struct dhd_bus *bus, struct osl_info *osh, void *sdh, #endif /* DHD_DEBUG */ /* si_attach() will provide an SI handle and scan the backplane */ - bus->sih = si_attach((uint) devid, osh, regsva, DHD_BUS, sdh, + bus->sih = si_attach((uint) devid, regsva, DHD_BUS, sdh, &bus->vars, &bus->varsz); if (!(bus->sih)) { DHD_ERROR(("%s: si_attach failed!\n", __func__)); @@ -5332,7 +5332,7 @@ dhdsdio_probe_attach(struct dhd_bus *bus, struct osl_info *osh, void *sdh, goto fail; } - si_sdiod_drive_strength_init(bus->sih, osh, dhd_sdiod_drive_strength); + si_sdiod_drive_strength_init(bus->sih, dhd_sdiod_drive_strength); /* Get info on the ARM and SOCRAM cores... */ if (!DHD_NOPMU(bus)) { diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c index a76fae2ba83f..e51d303c83f5 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c @@ -19082,10 +19082,10 @@ wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chanspec, if ((pi->sh->chip == BCM4716_CHIP_ID) || (pi->sh->chip == BCM47162_CHIP_ID)) { - si_pmu_spuravoid(pi->sh->sih, pi->sh->osh, spuravoid); + si_pmu_spuravoid(pi->sh->sih, spuravoid); } else { wlapi_bmac_core_phypll_ctl(pi->sh->physhim, false); - si_pmu_spuravoid(pi->sh->sih, pi->sh->osh, spuravoid); + si_pmu_spuravoid(pi->sh->sih, spuravoid); wlapi_bmac_core_phypll_ctl(pi->sh->physhim, true); } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index 2b25c0d45875..05e99e5369bd 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -494,7 +494,6 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, struct sk_buff **pdu, int prec) { struct wlc_info *wlc; - struct osl_info *osh; struct sk_buff *p, *pkt[AMPDU_MAX_MPDU]; u8 tid, ndelim; int err = 0; @@ -526,7 +525,6 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, u16 qlen; wlc = ampdu->wlc; - osh = wlc->osh; p = *pdu; ASSERT(p); @@ -1070,7 +1068,7 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, wlc->pub->unit, txs->phyerr); if (WL_ERROR_ON()) { - prpkt("txpkt (AMPDU)", wlc->osh, p); + prpkt("txpkt (AMPDU)", p); wlc_print_txdesc((d11txh_t *) p->data); } wlc_print_txstatus(txs); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 0cb94332af30..b6e49f7af063 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -674,7 +674,7 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, * Also initialize software state that depends on the particular hardware * we are running. */ - wlc_hw->sih = si_attach((uint) device, osh, regsva, bustype, btparam, + wlc_hw->sih = si_attach((uint) device, regsva, bustype, btparam, &wlc_hw->vars, &wlc_hw->vars_size); if (wlc_hw->sih == NULL) { WL_ERROR("wl%d: wlc_bmac_attach: si_attach failed\n", unit); diff --git a/drivers/staging/brcm80211/include/bcmsrom.h b/drivers/staging/brcm80211/include/bcmsrom.h index cdcef746284f..b2dc8951c5d2 100644 --- a/drivers/staging/brcm80211/include/bcmsrom.h +++ b/drivers/staging/brcm80211/include/bcmsrom.h @@ -21,14 +21,14 @@ /* Prototypes */ extern int srom_var_init(si_t *sih, uint bus, void *curmap, - struct osl_info *osh, char **vars, uint *count); + char **vars, uint *count); -extern int srom_read(si_t *sih, uint bus, void *curmap, struct osl_info *osh, +extern int srom_read(si_t *sih, uint bus, void *curmap, uint byteoff, uint nbytes, u16 *buf, bool check_crc); /* parse standard PCMCIA cis, normally used by SB/PCMCIA/SDIO/SPI/OTP * and extract from it into name=value pairs */ -extern int srom_parsecis(struct osl_info *osh, u8 **pcis, uint ciscnt, +extern int srom_parsecis(u8 **pcis, uint ciscnt, char **vars, uint *count); #endif /* _bcmsrom_h_ */ diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h index 9c3a97997fa3..358bbbf27e01 100644 --- a/drivers/staging/brcm80211/include/bcmutils.h +++ b/drivers/staging/brcm80211/include/bcmutils.h @@ -140,7 +140,7 @@ extern struct sk_buff *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); /* externs */ /* packet */ - extern uint pktfrombuf(struct osl_info *osh, struct sk_buff *p, + extern uint pktfrombuf(struct sk_buff *p, uint offset, int len, unsigned char *buf); extern uint pkttotlen(struct sk_buff *p); @@ -155,10 +155,9 @@ extern struct sk_buff *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); extern char *getvar(char *vars, const char *name); extern int getintvar(char *vars, const char *name); #ifdef BCMDBG - extern void prpkt(const char *msg, struct osl_info *osh, - struct sk_buff *p0); + extern void prpkt(const char *msg, struct sk_buff *p0); #else -#define prpkt(a, b, c) +#define prpkt(a, b) #endif /* BCMDBG */ #define bcm_perf_enable() diff --git a/drivers/staging/brcm80211/include/hndpmu.h b/drivers/staging/brcm80211/include/hndpmu.h index a0110e4c9ac4..3eea1f9fbc39 100644 --- a/drivers/staging/brcm80211/include/hndpmu.h +++ b/drivers/staging/brcm80211/include/hndpmu.h @@ -28,44 +28,41 @@ #define SET_LDO_VOLTAGE_LNLDO1 9 #define SET_LDO_VOLTAGE_LNLDO2_SEL 10 -extern void si_pmu_init(si_t *sih, struct osl_info *osh); -extern void si_pmu_chip_init(si_t *sih, struct osl_info *osh); -extern void si_pmu_pll_init(si_t *sih, struct osl_info *osh, u32 xtalfreq); -extern void si_pmu_res_init(si_t *sih, struct osl_info *osh); -extern void si_pmu_swreg_init(si_t *sih, struct osl_info *osh); +extern void si_pmu_init(si_t *sih); +extern void si_pmu_chip_init(si_t *sih); +extern void si_pmu_pll_init(si_t *sih, u32 xtalfreq); +extern void si_pmu_res_init(si_t *sih); +extern void si_pmu_swreg_init(si_t *sih); -extern u32 si_pmu_force_ilp(si_t *sih, struct osl_info *osh, bool force); +extern u32 si_pmu_force_ilp(si_t *sih, bool force); -extern u32 si_pmu_si_clock(si_t *sih, struct osl_info *osh); -extern u32 si_pmu_cpu_clock(si_t *sih, struct osl_info *osh); -extern u32 si_pmu_mem_clock(si_t *sih, struct osl_info *osh); -extern u32 si_pmu_alp_clock(si_t *sih, struct osl_info *osh); -extern u32 si_pmu_ilp_clock(si_t *sih, struct osl_info *osh); +extern u32 si_pmu_si_clock(si_t *sih); +extern u32 si_pmu_cpu_clock(si_t *sih); +extern u32 si_pmu_mem_clock(si_t *sih); +extern u32 si_pmu_alp_clock(si_t *sih); +extern u32 si_pmu_ilp_clock(si_t *sih); -extern void si_pmu_set_switcher_voltage(si_t *sih, struct osl_info *osh, +extern void si_pmu_set_switcher_voltage(si_t *sih, u8 bb_voltage, u8 rf_voltage); -extern void si_pmu_set_ldo_voltage(si_t *sih, struct osl_info *osh, u8 ldo, - u8 voltage); -extern u16 si_pmu_fast_pwrup_delay(si_t *sih, struct osl_info *osh); -extern void si_pmu_rcal(si_t *sih, struct osl_info *osh); +extern void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage); +extern u16 si_pmu_fast_pwrup_delay(si_t *sih); +extern void si_pmu_rcal(si_t *sih); extern void si_pmu_pllupd(si_t *sih); -extern void si_pmu_spuravoid(si_t *sih, struct osl_info *osh, u8 spuravoid); +extern void si_pmu_spuravoid(si_t *sih, u8 spuravoid); -extern bool si_pmu_is_otp_powered(si_t *sih, struct osl_info *osh); -extern u32 si_pmu_measure_alpclk(si_t *sih, struct osl_info *osh); +extern bool si_pmu_is_otp_powered(si_t *sih); +extern u32 si_pmu_measure_alpclk(si_t *sih); extern u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val); extern u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val); extern u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val); extern void si_pmu_pllupd(si_t *sih); -extern void si_pmu_sprom_enable(si_t *sih, struct osl_info *osh, bool enable); +extern void si_pmu_sprom_enable(si_t *sih, bool enable); extern void si_pmu_radio_enable(si_t *sih, bool enable); -extern u32 si_pmu_waitforclk_on_backplane(si_t *sih, struct osl_info *osh, - u32 clk, u32 delay); +extern u32 si_pmu_waitforclk_on_backplane(si_t *sih, u32 clk, u32 delay); -extern void si_pmu_otp_power(si_t *sih, struct osl_info *osh, bool on); -extern void si_sdiod_drive_strength_init(si_t *sih, struct osl_info *osh, - u32 drivestrength); +extern void si_pmu_otp_power(si_t *sih, bool on); +extern void si_sdiod_drive_strength_init(si_t *sih, u32 drivestrength); #endif /* _hndpmu_h_ */ diff --git a/drivers/staging/brcm80211/include/nicpci.h b/drivers/staging/brcm80211/include/nicpci.h index eb842c838df1..30321eb0477e 100644 --- a/drivers/staging/brcm80211/include/nicpci.h +++ b/drivers/staging/brcm80211/include/nicpci.h @@ -47,15 +47,15 @@ struct sbpcieregs; extern u8 pcicore_find_pci_capability(void *dev, u8 req_cap_id, unsigned char *buf, u32 *buflen); -extern uint pcie_readreg(struct osl_info *osh, struct sbpcieregs *pcieregs, +extern uint pcie_readreg(struct sbpcieregs *pcieregs, uint addrtype, uint offset); -extern uint pcie_writereg(struct osl_info *osh, struct sbpcieregs *pcieregs, +extern uint pcie_writereg(struct sbpcieregs *pcieregs, uint addrtype, uint offset, uint val); extern u8 pcie_clkreq(void *pch, u32 mask, u32 val); extern u32 pcie_lcreg(void *pch, u32 mask, u32 val); -extern void *pcicore_init(si_t *sih, struct osl_info *osh, void *regs); +extern void *pcicore_init(si_t *sih, void *pdev, void *regs); extern void pcicore_deinit(void *pch); extern void pcicore_attach(void *pch, char *pvars, int state); extern void pcicore_hwup(void *pch); diff --git a/drivers/staging/brcm80211/include/siutils.h b/drivers/staging/brcm80211/include/siutils.h index 3301cf07cd2e..f84057ed6b71 100644 --- a/drivers/staging/brcm80211/include/siutils.h +++ b/drivers/staging/brcm80211/include/siutils.h @@ -118,8 +118,8 @@ typedef void (*gpio_handler_t) (u32 stat, void *arg); #define GPIO_CTRL_EPA_EN_MASK 0x40 /* === exported functions === */ -extern si_t *si_attach(uint pcidev, struct osl_info *osh, void *regs, - uint bustype, void *sdh, char **vars, uint *varsz); +extern si_t *si_attach(uint pcidev, void *regs, uint bustype, + void *sdh, char **vars, uint *varsz); extern void si_detach(si_t *sih); extern bool si_pci_war16165(si_t *sih); @@ -128,7 +128,6 @@ extern uint si_coreid(si_t *sih); extern uint si_flag(si_t *sih); extern uint si_coreidx(si_t *sih); extern uint si_corerev(si_t *sih); -struct osl_info *si_osh(si_t *sih); extern uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); extern void si_write_wrapperreg(si_t *sih, u32 offset, u32 val); @@ -213,7 +212,6 @@ typedef struct gpioh_item { /* misc si info needed by some of the routines */ typedef struct si_info { struct si_pub pub; /* back plane public state (must be first) */ - struct osl_info *osh; /* osl os handle */ void *pbus; /* handle to bus (pci/sdio/..) */ uint dev_coreid; /* the core provides driver functions */ void *intr_arg; /* interrupt callback function arg */ diff --git a/drivers/staging/brcm80211/util/bcmotp.c b/drivers/staging/brcm80211/util/bcmotp.c index 1049462df1a9..e763a0de7989 100644 --- a/drivers/staging/brcm80211/util/bcmotp.c +++ b/drivers/staging/brcm80211/util/bcmotp.c @@ -78,7 +78,6 @@ typedef struct { uint ccrev; /* chipc revision */ otp_fn_t *fn; /* OTP functions */ si_t *sih; /* Saved sb handle */ - struct osl_info *osh; #ifdef BCMIPXOTP /* IPX OTP section */ @@ -569,15 +568,14 @@ static int hndotp_size(void *oh) static u16 hndotp_otpr(void *oh, chipcregs_t *cc, uint wn) { +#ifdef BCMDBG otpinfo_t *oi = (otpinfo_t *) oh; - struct osl_info *osh; +#endif volatile u16 *ptr; ASSERT(wn < ((oi->size / 2) + OTP_RC_LIM_OFF)); ASSERT(cc != NULL); - osh = si_osh(oi->sih); - ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP); return R_REG(&ptr[wn]); } @@ -585,15 +583,12 @@ static u16 hndotp_otpr(void *oh, chipcregs_t *cc, uint wn) static u16 hndotp_otproff(void *oh, chipcregs_t *cc, int woff) { otpinfo_t *oi = (otpinfo_t *) oh; - struct osl_info *osh; volatile u16 *ptr; ASSERT(woff >= (-((int)oi->size / 2))); ASSERT(woff < OTP_LIM_OFF); ASSERT(cc != NULL); - osh = si_osh(oi->sih); - ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP); return R_REG(&ptr[(oi->size / 2) + woff]); @@ -601,12 +596,9 @@ static u16 hndotp_otproff(void *oh, chipcregs_t *cc, int woff) static u16 hndotp_read_bit(void *oh, chipcregs_t *cc, uint idx) { - otpinfo_t *oi = (otpinfo_t *) oh; uint k, row, col; u32 otpp, st; - struct osl_info *osh; - osh = si_osh(oi->sih); row = idx / 65; col = idx % 65; @@ -637,12 +629,10 @@ static void *hndotp_init(si_t *sih) otpinfo_t *oi; u32 cap = 0, clkdiv, otpdiv = 0; void *ret = NULL; - struct osl_info *osh; oi = &otpinfo; idx = si_coreidx(sih); - osh = si_osh(oi->sih); /* Check for otp */ cc = si_setcoreidx(sih, SI_CC_IDX); @@ -920,7 +910,6 @@ void *otp_init(si_t *sih) } oi->sih = sih; - oi->osh = si_osh(oi->sih); ret = (oi->fn->init) (sih); diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index cff25a391d43..11b5c0861f00 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -67,29 +67,26 @@ extern uint _varsz; #define SROM_CIS_SINGLE 1 -static int initvars_srom_si(si_t *sih, struct osl_info *osh, void *curmap, - char **vars, uint *count); -static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, - varbuf_t *b); -static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, - uint *count); +static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *count); +static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b); +static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count); static int initvars_flash_si(si_t *sih, char **vars, uint *count); #ifdef BCMSDIO -static int initvars_cis_sdio(struct osl_info *osh, char **vars, uint *count); -static int sprom_cmd_sdio(struct osl_info *osh, u8 cmd); -static int sprom_read_sdio(struct osl_info *osh, u16 addr, u16 *data); +static int initvars_cis_sdio(char **vars, uint *count); +static int sprom_cmd_sdio(u8 cmd); +static int sprom_read_sdio(u16 addr, u16 *data); #endif /* BCMSDIO */ -static int sprom_read_pci(struct osl_info *osh, si_t *sih, u16 *sprom, +static int sprom_read_pci(si_t *sih, u16 *sprom, uint wordoff, u16 *buf, uint nwords, bool check_crc); #if defined(BCMNVRAMR) -static int otp_read_pci(struct osl_info *osh, si_t *sih, u16 *buf, uint bufsz); +static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz); #endif -static u16 srom_cc_cmd(si_t *sih, struct osl_info *osh, void *ccregs, u32 cmd, +static u16 srom_cc_cmd(si_t *sih, void *ccregs, u32 cmd, uint wordoff, u16 data); -static int initvars_table(struct osl_info *osh, char *start, char *end, +static int initvars_table(char *start, char *end, char **vars, uint *count); -static int initvars_flash(si_t *sih, struct osl_info *osh, char **vp, +static int initvars_flash(si_t *sih, char **vp, uint len); /* Initialization of varbuf structure */ @@ -157,7 +154,7 @@ static int varbuf_append(varbuf_t *b, const char *fmt, ...) * Initialize local vars from the right source for this platform. * Return 0 on success, nonzero on error. */ -int srom_var_init(si_t *sih, uint bustype, void *curmap, struct osl_info *osh, +int srom_var_init(si_t *sih, uint bustype, void *curmap, char **vars, uint *count) { uint len; @@ -174,7 +171,7 @@ int srom_var_init(si_t *sih, uint bustype, void *curmap, struct osl_info *osh, switch (bustype) { case SI_BUS: case JTAG_BUS: - return initvars_srom_si(sih, osh, curmap, vars, count); + return initvars_srom_si(sih, curmap, vars, count); case PCI_BUS: ASSERT(curmap != NULL); @@ -185,7 +182,7 @@ int srom_var_init(si_t *sih, uint bustype, void *curmap, struct osl_info *osh, #ifdef BCMSDIO case SDIO_BUS: - return initvars_cis_sdio(osh, vars, count); + return initvars_cis_sdio(vars, count); #endif /* BCMSDIO */ default: @@ -196,7 +193,7 @@ int srom_var_init(si_t *sih, uint bustype, void *curmap, struct osl_info *osh, /* support only 16-bit word read from srom */ int -srom_read(si_t *sih, uint bustype, void *curmap, struct osl_info *osh, +srom_read(si_t *sih, uint bustype, void *curmap, uint byteoff, uint nbytes, u16 *buf, bool check_crc) { uint off, nw; @@ -225,12 +222,12 @@ srom_read(si_t *sih, uint bustype, void *curmap, struct osl_info *osh, return 1; if (sprom_read_pci - (osh, sih, srom, off, buf, nw, check_crc)) + (sih, srom, off, buf, nw, check_crc)) return 1; } #if defined(BCMNVRAMR) else { - if (otp_read_pci(osh, sih, buf, SROM_MAX)) + if (otp_read_pci(sih, buf, SROM_MAX)) return 1; } #endif @@ -240,7 +237,7 @@ srom_read(si_t *sih, uint bustype, void *curmap, struct osl_info *osh, nw = nbytes / 2; for (i = 0; i < nw; i++) { if (sprom_read_sdio - (osh, (u16) (off + i), (u16 *) (buf + i))) + ((u16) (off + i), (u16 *) (buf + i))) return 1; } #endif /* BCMSDIO */ @@ -378,7 +375,7 @@ u8 patch_pair; /* For dongle HW, accept partial calibration parameters */ #define BCMDONGLECASE(n) -int srom_parsecis(struct osl_info *osh, u8 *pcis[], uint ciscnt, char **vars, +int srom_parsecis(u8 *pcis[], uint ciscnt, char **vars, uint *count) { char eabuf[32]; @@ -1398,7 +1395,7 @@ int srom_parsecis(struct osl_info *osh, u8 *pcis[], uint ciscnt, char **vars, *b.buf++ = '\0'; ASSERT(b.buf - base <= MAXSZ_NVRAM_VARS); - err = initvars_table(osh, base, b.buf, vars, count); + err = initvars_table(base, b.buf, vars, count); kfree(base); return err; @@ -1408,7 +1405,7 @@ int srom_parsecis(struct osl_info *osh, u8 *pcis[], uint ciscnt, char **vars, * not in the bus cores. */ static u16 -srom_cc_cmd(si_t *sih, struct osl_info *osh, void *ccregs, u32 cmd, +srom_cc_cmd(si_t *sih, void *ccregs, u32 cmd, uint wordoff, u16 data) { chipcregs_t *cc = (chipcregs_t *) ccregs; @@ -1454,7 +1451,7 @@ static inline void htol16_buf(u16 *buf, unsigned int size) * Return 0 on success, nonzero on error. */ static int -sprom_read_pci(struct osl_info *osh, si_t *sih, u16 *sprom, uint wordoff, +sprom_read_pci(si_t *sih, u16 *sprom, uint wordoff, u16 *buf, uint nwords, bool check_crc) { int err = 0; @@ -1471,7 +1468,7 @@ sprom_read_pci(struct osl_info *osh, si_t *sih, u16 *sprom, uint wordoff, ccregs = (void *)((u8 *) sprom - CC_SROM_OTP); buf[i] = - srom_cc_cmd(sih, osh, ccregs, SRC_OP_READ, + srom_cc_cmd(sih, ccregs, SRC_OP_READ, wordoff + i, 0); } else { @@ -1514,7 +1511,7 @@ sprom_read_pci(struct osl_info *osh, si_t *sih, u16 *sprom, uint wordoff, } #if defined(BCMNVRAMR) -static int otp_read_pci(struct osl_info *osh, si_t *sih, u16 *buf, uint bufsz) +static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz) { u8 *otp; uint sz = OTP_SZ_MAX / 2; /* size in words */ @@ -1562,7 +1559,7 @@ static int otp_read_pci(struct osl_info *osh, si_t *sih, u16 *buf, uint bufsz) * Create variable table from memory. * Return 0 on success, nonzero on error. */ -static int initvars_table(struct osl_info *osh, char *start, char *end, +static int initvars_table(char *start, char *end, char **vars, uint *count) { int c = (int)(end - start); @@ -1589,8 +1586,7 @@ static int initvars_table(struct osl_info *osh, char *start, char *end, * of the table upon enter and to the end of the table upon exit when success. * Return 0 on success, nonzero on error. */ -static int initvars_flash(si_t *sih, struct osl_info *osh, char **base, - uint len) +static int initvars_flash(si_t *sih, char **base, uint len) { char *vp = *base; char *flash; @@ -1650,7 +1646,6 @@ static int initvars_flash(si_t *sih, struct osl_info *osh, char **base, */ static int initvars_flash_si(si_t *sih, char **vars, uint *count) { - struct osl_info *osh = si_osh(sih); char *vp, *base; int err; @@ -1662,9 +1657,9 @@ static int initvars_flash_si(si_t *sih, char **vars, uint *count) if (!vp) return BCME_NOMEM; - err = initvars_flash(sih, osh, &vp, MAXSZ_NVRAM_VARS); + err = initvars_flash(sih, &vp, MAXSZ_NVRAM_VARS); if (err == 0) - err = initvars_table(osh, base, vp, vars, count); + err = initvars_table(base, vp, vars, count); kfree(base); @@ -1861,7 +1856,6 @@ static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count) u32 sr; varbuf_t b; char *vp, *base = NULL; - struct osl_info *osh = si_osh(sih); bool flash = false; int err = 0; @@ -1879,7 +1873,7 @@ static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count) sromwindow = (u16 *) SROM_OFFSET(sih); if (si_is_sprom_available(sih)) { err = - sprom_read_pci(osh, sih, sromwindow, 0, srom, SROM_WORDS, + sprom_read_pci(sih, sromwindow, 0, srom, SROM_WORDS, true); if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) || @@ -1889,7 +1883,7 @@ static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count) && (sih->buscorerev >= 0xe)))) { /* sromrev >= 4, read more */ err = - sprom_read_pci(osh, sih, sromwindow, 0, srom, + sprom_read_pci(sih, sromwindow, 0, srom, SROM4_WORDS, true); sromrev = srom[SROM4_CRCREV] & 0xff; if (err) @@ -1907,24 +1901,29 @@ static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count) } #if defined(BCMNVRAMR) /* Use OTP if SPROM not available */ - else if ((err = otp_read_pci(osh, sih, srom, SROM_MAX)) == 0) { - /* OTP only contain SROM rev8/rev9 for now */ - sromrev = srom[SROM4_CRCREV] & 0xff; - } -#endif else { - err = 1; - BS_ERROR(("Neither SPROM nor OTP has valid image\n")); + err = otp_read_pci(sih, srom, SROM_MAX); + if (err == 0) + /* OTP only contain SROM rev8/rev9 for now */ + sromrev = srom[SROM4_CRCREV] & 0xff; + else + err = 1; } +#else + else + err = 1; +#endif - /* We want internal/wltest driver to come up with default sromvars so we can - * program a blank SPROM/OTP. + /* + * We want internal/wltest driver to come up with default + * sromvars so we can program a blank SPROM/OTP. */ if (err) { char *value; u32 val; val = 0; + BS_ERROR(("Neither SPROM nor OTP has valid image\n")); value = si_getdevpathvar(sih, "sromrev"); if (value) { sromrev = (u8) simple_strtoul(value, NULL, 0); @@ -1968,7 +1967,7 @@ static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count) /* read variables from flash */ if (flash) { - err = initvars_flash(sih, osh, &vp, MAXSZ_NVRAM_VARS); + err = initvars_flash(sih, &vp, MAXSZ_NVRAM_VARS); if (err) goto errout; goto varsdone; @@ -1987,7 +1986,7 @@ static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count) ASSERT((vp - base) <= MAXSZ_NVRAM_VARS); varsdone: - err = initvars_table(osh, base, vp, vars, count); + err = initvars_table(base, vp, vars, count); errout: if (base) @@ -2002,7 +2001,7 @@ static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count) * Read the SDIO cis and call parsecis to initialize the vars. * Return 0 on success, nonzero on error. */ -static int initvars_cis_sdio(struct osl_info *osh, char **vars, uint *count) +static int initvars_cis_sdio(char **vars, uint *count) { u8 *cis[SBSDIO_NUM_FUNCTION + 1]; uint fn, numfn; @@ -2027,7 +2026,7 @@ static int initvars_cis_sdio(struct osl_info *osh, char **vars, uint *count) } if (!rc) - rc = srom_parsecis(osh, cis, fn, vars, count); + rc = srom_parsecis(cis, fn, vars, count); while (fn-- > 0) kfree(cis[fn]); @@ -2036,7 +2035,7 @@ static int initvars_cis_sdio(struct osl_info *osh, char **vars, uint *count) } /* set SDIO sprom command register */ -static int sprom_cmd_sdio(struct osl_info *osh, u8 cmd) +static int sprom_cmd_sdio(u8 cmd) { u8 status = 0; uint wait_cnt = 1000; @@ -2056,7 +2055,7 @@ static int sprom_cmd_sdio(struct osl_info *osh, u8 cmd) } /* read a word from the SDIO srom */ -static int sprom_read_sdio(struct osl_info *osh, u16 addr, u16 *data) +static int sprom_read_sdio(u16 addr, u16 *data) { u8 addr_l, addr_h, data_l, data_h; @@ -2070,7 +2069,7 @@ static int sprom_read_sdio(struct osl_info *osh, u16 addr, u16 *data) NULL); /* do read */ - if (sprom_cmd_sdio(osh, SBSDIO_SPROM_READ)) + if (sprom_cmd_sdio(SBSDIO_SPROM_READ)) return 1; /* read data */ @@ -2084,8 +2083,7 @@ static int sprom_read_sdio(struct osl_info *osh, u16 addr, u16 *data) } #endif /* BCMSDIO */ -static int initvars_srom_si(si_t *sih, struct osl_info *osh, void *curmap, - char **vars, uint *varsz) +static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *varsz) { /* Search flash nvram section for srom variables */ return initvars_flash_si(sih, vars, varsz); diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index 2073762f425d..e31151b9dbeb 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -76,7 +76,7 @@ void BCMFASTPATH pkt_buf_free_skb(struct osl_info *osh, } /* copy a buffer into a pkt buffer chain */ -uint pktfrombuf(struct osl_info *osh, struct sk_buff *p, uint offset, int len, +uint pktfrombuf(struct sk_buff *p, uint offset, int len, unsigned char *buf) { uint n, ret = 0; @@ -453,7 +453,7 @@ int getintvar(char *vars, const char *name) #if defined(BCMDBG) /* pretty hex print a pkt buffer chain */ -void prpkt(const char *msg, struct osl_info *osh, struct sk_buff *p0) +void prpkt(const char *msg, struct sk_buff *p0) { struct sk_buff *p; diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 4646b7bfe0bf..b7bc84d62c38 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -228,7 +228,7 @@ static void dma64_txreclaim(dma_info_t *di, txd_range_t range); static bool dma64_txstopped(dma_info_t *di); static bool dma64_rxstopped(dma_info_t *di); static bool dma64_rxenabled(dma_info_t *di); -static bool _dma64_addrext(struct osl_info *osh, dma64regs_t *dma64regs); +static bool _dma64_addrext(dma64regs_t *dma64regs); static inline u32 parity32(u32 data); @@ -610,14 +610,14 @@ static bool _dma_isaddrext(dma_info_t *di) /* not all tx or rx channel are available */ if (di->d64txregs != NULL) { - if (!_dma64_addrext(di->osh, di->d64txregs)) { + if (!_dma64_addrext(di->d64txregs)) { DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have " "AE set\n", di->name)); ASSERT(0); } return true; } else if (di->d64rxregs != NULL) { - if (!_dma64_addrext(di->osh, di->d64rxregs)) { + if (!_dma64_addrext(di->d64rxregs)) { DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have " "AE set\n", di->name)); ASSERT(0); @@ -1702,7 +1702,7 @@ static void *BCMFASTPATH dma64_getnextrxp(dma_info_t *di, bool forceall) return rxp; } -static bool _dma64_addrext(struct osl_info *osh, dma64regs_t * dma64regs) +static bool _dma64_addrext(dma64regs_t *dma64regs) { u32 w; OR_REG(&dma64regs->control, D64_XC_AE); @@ -1792,10 +1792,6 @@ static void dma64_txrotate(dma_info_t *di) uint dma_addrwidth(si_t *sih, void *dmaregs) { - struct osl_info *osh; - - osh = si_osh(sih); - /* Perform 64-bit checks only if we want to advertise 64-bit (> 32bit) capability) */ /* DMA engine is 64-bit capable */ if ((si_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64) { diff --git a/drivers/staging/brcm80211/util/hndpmu.c b/drivers/staging/brcm80211/util/hndpmu.c index a683b1895b70..911374955d63 100644 --- a/drivers/staging/brcm80211/util/hndpmu.c +++ b/drivers/staging/brcm80211/util/hndpmu.c @@ -46,23 +46,20 @@ #define PMU_NONE(args) /* PLL controls/clocks */ -static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, - u32 xtal); -static u32 si_pmu1_cpuclk0(si_t *sih, struct osl_info *osh, chipcregs_t *cc); -static u32 si_pmu1_alpclk0(si_t *sih, struct osl_info *osh, chipcregs_t *cc); +static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal); +static u32 si_pmu1_cpuclk0(si_t *sih, chipcregs_t *cc); +static u32 si_pmu1_alpclk0(si_t *sih, chipcregs_t *cc); /* PMU resources */ static bool si_pmu_res_depfltr_bb(si_t *sih); static bool si_pmu_res_depfltr_ncb(si_t *sih); static bool si_pmu_res_depfltr_paldo(si_t *sih); static bool si_pmu_res_depfltr_npaldo(si_t *sih); -static u32 si_pmu_res_deps(si_t *sih, struct osl_info *osh, chipcregs_t *cc, - u32 rsrcs, bool all); -static uint si_pmu_res_uptime(si_t *sih, struct osl_info *osh, chipcregs_t *cc, - u8 rsrc); +static u32 si_pmu_res_deps(si_t *sih, chipcregs_t *cc, u32 rsrcs, bool all); +static uint si_pmu_res_uptime(si_t *sih, chipcregs_t *cc, u8 rsrc); static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax); static void si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, - struct osl_info *osh, u8 spuravoid); + u8 spuravoid); static void si_pmu_set_4330_plldivs(si_t *sih); @@ -107,8 +104,7 @@ void si_pmu_pllupd(si_t *sih) } /* Setup switcher voltage */ -void si_pmu_set_switcher_voltage(si_t *sih, struct osl_info *osh, u8 bb_voltage, - u8 rf_voltage) +void si_pmu_set_switcher_voltage(si_t *sih, u8 bb_voltage, u8 rf_voltage) { chipcregs_t *cc; uint origidx; @@ -130,7 +126,7 @@ void si_pmu_set_switcher_voltage(si_t *sih, struct osl_info *osh, u8 bb_voltage, si_setcoreidx(sih, origidx); } -void si_pmu_set_ldo_voltage(si_t *sih, struct osl_info *osh, u8 ldo, u8 voltage) +void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage) { u8 sr_cntl_shift = 0, rc_shift = 0, shift = 0, mask = 0; u8 addr = 0; @@ -188,7 +184,7 @@ void si_pmu_set_ldo_voltage(si_t *sih, struct osl_info *osh, u8 ldo, u8 voltage) /* d11 slow to fast clock transition time in slow clock cycles */ #define D11SCC_SLOW2FAST_TRANSITION 2 -u16 si_pmu_fast_pwrup_delay(si_t *sih, struct osl_info *osh) +u16 si_pmu_fast_pwrup_delay(si_t *sih) { uint delay = PMU_MAX_TRANSITION_DLY; chipcregs_t *cc; @@ -223,7 +219,7 @@ u16 si_pmu_fast_pwrup_delay(si_t *sih, struct osl_info *osh) else { u32 ilp = si_ilp_clock(sih); delay = - (si_pmu_res_uptime(sih, osh, cc, RES4329_HT_AVAIL) + + (si_pmu_res_uptime(sih, cc, RES4329_HT_AVAIL) + D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); delay = (11 * delay) / 10; @@ -238,7 +234,7 @@ u16 si_pmu_fast_pwrup_delay(si_t *sih, struct osl_info *osh) else { u32 ilp = si_ilp_clock(sih); delay = - (si_pmu_res_uptime(sih, osh, cc, RES4336_HT_AVAIL) + + (si_pmu_res_uptime(sih, cc, RES4336_HT_AVAIL) + D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); delay = (11 * delay) / 10; @@ -250,7 +246,7 @@ u16 si_pmu_fast_pwrup_delay(si_t *sih, struct osl_info *osh) else { u32 ilp = si_ilp_clock(sih); delay = - (si_pmu_res_uptime(sih, osh, cc, RES4330_HT_AVAIL) + + (si_pmu_res_uptime(sih, cc, RES4330_HT_AVAIL) + D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp); delay = (11 * delay) / 10; @@ -265,7 +261,7 @@ u16 si_pmu_fast_pwrup_delay(si_t *sih, struct osl_info *osh) return (u16) delay; } -u32 si_pmu_force_ilp(si_t *sih, struct osl_info *osh, bool force) +u32 si_pmu_force_ilp(si_t *sih, bool force) { chipcregs_t *cc; uint origidx; @@ -683,7 +679,7 @@ static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax) } /* initialize PMU resources */ -void si_pmu_res_init(si_t *sih, struct osl_info *osh) +void si_pmu_res_init(si_t *sih) { chipcregs_t *cc; uint origidx; @@ -1184,7 +1180,7 @@ static u32 si_pmu1_pllfvco0(si_t *sih) /* query alp/xtal clock frequency */ static u32 -si_pmu1_alpclk0(si_t *sih, struct osl_info *osh, chipcregs_t *cc) +si_pmu1_alpclk0(si_t *sih, chipcregs_t *cc) { const pmu1_xtaltab0_t *xt; u32 xf; @@ -1209,8 +1205,7 @@ si_pmu1_alpclk0(si_t *sih, struct osl_info *osh, chipcregs_t *cc) * case the xtal frequency is unknown to the s/w so we need to call * si_pmu1_xtaldef0() wherever it is needed to return a default value. */ -static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, - u32 xtal) +static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal) { const pmu1_xtaltab0_t *xt; u32 tmp; @@ -1452,7 +1447,7 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, /* query the CPU clock frequency */ static u32 -si_pmu1_cpuclk0(si_t *sih, struct osl_info *osh, chipcregs_t *cc) +si_pmu1_cpuclk0(si_t *sih, chipcregs_t *cc) { u32 tmp, m1div; #ifdef BCMDBG @@ -1485,7 +1480,7 @@ si_pmu1_cpuclk0(si_t *sih, struct osl_info *osh, chipcregs_t *cc) (tmp & PMU1_PLL0_PC3_NDIV_FRAC_MASK) >> PMU1_PLL0_PC3_NDIV_FRAC_SHIFT; - fref = si_pmu1_alpclk0(sih, osh, cc) / 1000; + fref = si_pmu1_alpclk0(sih, cc) / 1000; fvco = (fref * ndiv_int) << 8; fvco += (fref * (ndiv_frac >> 12)) >> 4; @@ -1506,7 +1501,7 @@ si_pmu1_cpuclk0(si_t *sih, struct osl_info *osh, chipcregs_t *cc) } /* initialize PLL */ -void si_pmu_pll_init(si_t *sih, struct osl_info *osh, uint xtalfreq) +void si_pmu_pll_init(si_t *sih, uint xtalfreq) { chipcregs_t *cc; uint origidx; @@ -1525,7 +1520,7 @@ void si_pmu_pll_init(si_t *sih, struct osl_info *osh, uint xtalfreq) case BCM4329_CHIP_ID: if (xtalfreq == 0) xtalfreq = 38400; - si_pmu1_pllinit0(sih, osh, cc, xtalfreq); + si_pmu1_pllinit0(sih, cc, xtalfreq); break; case BCM4313_CHIP_ID: case BCM43224_CHIP_ID: @@ -1541,7 +1536,7 @@ void si_pmu_pll_init(si_t *sih, struct osl_info *osh, uint xtalfreq) case BCM4319_CHIP_ID: case BCM4336_CHIP_ID: case BCM4330_CHIP_ID: - si_pmu1_pllinit0(sih, osh, cc, xtalfreq); + si_pmu1_pllinit0(sih, cc, xtalfreq); break; default: PMU_MSG(("No PLL init done for chip %s rev %d pmurev %d\n", @@ -1559,7 +1554,7 @@ void si_pmu_pll_init(si_t *sih, struct osl_info *osh, uint xtalfreq) } /* query alp/xtal clock frequency */ -u32 si_pmu_alp_clock(si_t *sih, struct osl_info *osh) +u32 si_pmu_alp_clock(si_t *sih) { chipcregs_t *cc; uint origidx; @@ -1597,7 +1592,7 @@ u32 si_pmu_alp_clock(si_t *sih, struct osl_info *osh) case BCM4336_CHIP_ID: case BCM4330_CHIP_ID: - clock = si_pmu1_alpclk0(sih, osh, cc); + clock = si_pmu1_alpclk0(sih, cc); break; case BCM5356_CHIP_ID: /* always 25Mhz */ @@ -1620,8 +1615,7 @@ u32 si_pmu_alp_clock(si_t *sih, struct osl_info *osh) * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc. */ static u32 -si_pmu5_clock(si_t *sih, struct osl_info *osh, chipcregs_t *cc, uint pll0, - uint m) { +si_pmu5_clock(si_t *sih, chipcregs_t *cc, uint pll0, uint m) { u32 tmp, div, ndiv, p1, p2, fc; if ((pll0 & 3) || (pll0 > PMU4716_MAINPLL_PLL0)) { @@ -1658,7 +1652,7 @@ si_pmu5_clock(si_t *sih, struct osl_info *osh, chipcregs_t *cc, uint pll0, ndiv = (tmp & PMU5_PLL_NDIV_MASK) >> PMU5_PLL_NDIV_SHIFT; /* Do calculation in Mhz */ - fc = si_pmu_alp_clock(sih, osh) / 1000000; + fc = si_pmu_alp_clock(sih) / 1000000; fc = (p1 * ndiv * fc) / p2; PMU_NONE(("%s: p1=%d, p2=%d, ndiv=%d(0x%x), m%d=%d; fc=%d, clock=%d\n", @@ -1672,7 +1666,7 @@ si_pmu5_clock(si_t *sih, struct osl_info *osh, chipcregs_t *cc, uint pll0, /* For designs that feed the same clock to both backplane * and CPU just return the CPU clock speed. */ -u32 si_pmu_si_clock(si_t *sih, struct osl_info *osh) +u32 si_pmu_si_clock(si_t *sih) { chipcregs_t *cc; uint origidx; @@ -1701,19 +1695,19 @@ u32 si_pmu_si_clock(si_t *sih, struct osl_info *osh) case BCM4748_CHIP_ID: case BCM47162_CHIP_ID: clock = - si_pmu5_clock(sih, osh, cc, PMU4716_MAINPLL_PLL0, + si_pmu5_clock(sih, cc, PMU4716_MAINPLL_PLL0, PMU5_MAINPLL_SI); break; case BCM4329_CHIP_ID: if (sih->chiprev == 0) clock = 38400 * 1000; else - clock = si_pmu1_cpuclk0(sih, osh, cc); + clock = si_pmu1_cpuclk0(sih, cc); break; case BCM4319_CHIP_ID: case BCM4336_CHIP_ID: case BCM4330_CHIP_ID: - clock = si_pmu1_cpuclk0(sih, osh, cc); + clock = si_pmu1_cpuclk0(sih, cc); break; case BCM4313_CHIP_ID: /* 80MHz backplane clock */ @@ -1729,12 +1723,12 @@ u32 si_pmu_si_clock(si_t *sih, struct osl_info *osh) break; case BCM5356_CHIP_ID: clock = - si_pmu5_clock(sih, osh, cc, PMU5356_MAINPLL_PLL0, + si_pmu5_clock(sih, cc, PMU5356_MAINPLL_PLL0, PMU5_MAINPLL_SI); break; case BCM5357_CHIP_ID: clock = - si_pmu5_clock(sih, osh, cc, PMU5357_MAINPLL_PLL0, + si_pmu5_clock(sih, cc, PMU5357_MAINPLL_PLL0, PMU5_MAINPLL_SI); break; default: @@ -1751,7 +1745,7 @@ u32 si_pmu_si_clock(si_t *sih, struct osl_info *osh) } /* query CPU clock frequency */ -u32 si_pmu_cpu_clock(si_t *sih, struct osl_info *osh) +u32 si_pmu_cpu_clock(si_t *sih) { chipcregs_t *cc; uint origidx; @@ -1784,18 +1778,18 @@ u32 si_pmu_cpu_clock(si_t *sih, struct osl_info *osh) cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); - clock = si_pmu5_clock(sih, osh, cc, pll, PMU5_MAINPLL_CPU); + clock = si_pmu5_clock(sih, cc, pll, PMU5_MAINPLL_CPU); /* Return to original core */ si_setcoreidx(sih, origidx); } else - clock = si_pmu_si_clock(sih, osh); + clock = si_pmu_si_clock(sih); return clock; } /* query memory clock frequency */ -u32 si_pmu_mem_clock(si_t *sih, struct osl_info *osh) +u32 si_pmu_mem_clock(si_t *sih) { chipcregs_t *cc; uint origidx; @@ -1828,12 +1822,12 @@ u32 si_pmu_mem_clock(si_t *sih, struct osl_info *osh) cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); - clock = si_pmu5_clock(sih, osh, cc, pll, PMU5_MAINPLL_MEM); + clock = si_pmu5_clock(sih, cc, pll, PMU5_MAINPLL_MEM); /* Return to original core */ si_setcoreidx(sih, origidx); } else { - clock = si_pmu_si_clock(sih, osh); + clock = si_pmu_si_clock(sih); } return clock; @@ -1844,7 +1838,7 @@ u32 si_pmu_mem_clock(si_t *sih, struct osl_info *osh) static u32 ilpcycles_per_sec; -u32 si_pmu_ilp_clock(si_t *sih, struct osl_info *osh) +u32 si_pmu_ilp_clock(si_t *sih) { if (ISSIM_ENAB(sih)) return ILP_CLOCK; @@ -1908,8 +1902,7 @@ static const sdiod_drive_str_t sdiod_drive_strength_tab3[] = { #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) void -si_sdiod_drive_strength_init(si_t *sih, struct osl_info *osh, - u32 drivestrength) { +si_sdiod_drive_strength_init(si_t *sih, u32 drivestrength) { chipcregs_t *cc; uint origidx, intr_val = 0; sdiod_drive_str_t *str_tab = NULL; @@ -1979,7 +1972,7 @@ si_sdiod_drive_strength_init(si_t *sih, struct osl_info *osh, } /* initialize PMU */ -void si_pmu_init(si_t *sih, struct osl_info *osh) +void si_pmu_init(si_t *sih) { chipcregs_t *cc; uint origidx; @@ -2011,8 +2004,7 @@ void si_pmu_init(si_t *sih, struct osl_info *osh) /* Return up time in ILP cycles for the given resource. */ static uint -si_pmu_res_uptime(si_t *sih, struct osl_info *osh, chipcregs_t *cc, - u8 rsrc) { +si_pmu_res_uptime(si_t *sih, chipcregs_t *cc, u8 rsrc) { u32 deps; uint up, i, dup, dmax; u32 min_mask = 0, max_mask = 0; @@ -2022,11 +2014,11 @@ si_pmu_res_uptime(si_t *sih, struct osl_info *osh, chipcregs_t *cc, up = (R_REG(&cc->res_updn_timer) >> 8) & 0xff; /* direct dependancies of resource 'rsrc' */ - deps = si_pmu_res_deps(sih, osh, cc, PMURES_BIT(rsrc), false); + deps = si_pmu_res_deps(sih, cc, PMURES_BIT(rsrc), false); for (i = 0; i <= PMURES_MAX_RESNUM; i++) { if (!(deps & PMURES_BIT(i))) continue; - deps &= ~si_pmu_res_deps(sih, osh, cc, PMURES_BIT(i), true); + deps &= ~si_pmu_res_deps(sih, cc, PMURES_BIT(i), true); } si_pmu_res_masks(sih, &min_mask, &max_mask); deps &= ~min_mask; @@ -2036,7 +2028,7 @@ si_pmu_res_uptime(si_t *sih, struct osl_info *osh, chipcregs_t *cc, for (i = 0; i <= PMURES_MAX_RESNUM; i++) { if (!(deps & PMURES_BIT(i))) continue; - dup = si_pmu_res_uptime(sih, osh, cc, (u8) i); + dup = si_pmu_res_uptime(sih, cc, (u8) i); if (dmax < dup) dmax = dup; } @@ -2048,7 +2040,7 @@ si_pmu_res_uptime(si_t *sih, struct osl_info *osh, chipcregs_t *cc, /* Return dependancies (direct or all/indirect) for the given resources */ static u32 -si_pmu_res_deps(si_t *sih, struct osl_info *osh, chipcregs_t *cc, u32 rsrcs, +si_pmu_res_deps(si_t *sih, chipcregs_t *cc, u32 rsrcs, bool all) { u32 deps = 0; @@ -2063,12 +2055,12 @@ si_pmu_res_deps(si_t *sih, struct osl_info *osh, chipcregs_t *cc, u32 rsrcs, return !all ? deps : (deps ? (deps | - si_pmu_res_deps(sih, osh, cc, deps, + si_pmu_res_deps(sih, cc, deps, true)) : 0); } /* power up/down OTP through PMU resources */ -void si_pmu_otp_power(si_t *sih, struct osl_info *osh, bool on) +void si_pmu_otp_power(si_t *sih, bool on) { chipcregs_t *cc; uint origidx; @@ -2108,7 +2100,7 @@ void si_pmu_otp_power(si_t *sih, struct osl_info *osh, bool on) u32 otps; /* Figure out the dependancies (exclude min_res_mask) */ - u32 deps = si_pmu_res_deps(sih, osh, cc, rsrcs, true); + u32 deps = si_pmu_res_deps(sih, cc, rsrcs, true); u32 min_mask = 0, max_mask = 0; si_pmu_res_masks(sih, &min_mask, &max_mask); deps &= ~min_mask; @@ -2138,7 +2130,7 @@ void si_pmu_otp_power(si_t *sih, struct osl_info *osh, bool on) si_setcoreidx(sih, origidx); } -void si_pmu_rcal(si_t *sih, struct osl_info *osh) +void si_pmu_rcal(si_t *sih) { chipcregs_t *cc; uint origidx; @@ -2217,7 +2209,7 @@ void si_pmu_rcal(si_t *sih, struct osl_info *osh) si_setcoreidx(sih, origidx); } -void si_pmu_spuravoid(si_t *sih, struct osl_info *osh, u8 spuravoid) +void si_pmu_spuravoid(si_t *sih, u8 spuravoid) { chipcregs_t *cc; uint origidx, intr_val; @@ -2240,7 +2232,7 @@ void si_pmu_spuravoid(si_t *sih, struct osl_info *osh, u8 spuravoid) } /* update the pll changes */ - si_pmu_spuravoid_pllupdate(sih, cc, osh, spuravoid); + si_pmu_spuravoid_pllupdate(sih, cc, spuravoid); /* enable HT back on */ if (sih->chip == BCM4336_CHIP_ID) { @@ -2254,8 +2246,7 @@ void si_pmu_spuravoid(si_t *sih, struct osl_info *osh, u8 spuravoid) } static void -si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, struct osl_info *osh, - u8 spuravoid) +si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, u8 spuravoid) { u32 tmp = 0; u8 phypll_offset = 0; @@ -2450,7 +2441,7 @@ si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, struct osl_info *osh, W_REG(&cc->pmucontrol, tmp); } -bool si_pmu_is_otp_powered(si_t *sih, struct osl_info *osh) +bool si_pmu_is_otp_powered(si_t *sih) { uint idx; chipcregs_t *cc; @@ -2500,7 +2491,7 @@ bool si_pmu_is_otp_powered(si_t *sih, struct osl_info *osh) return st; } -void si_pmu_sprom_enable(si_t *sih, struct osl_info *osh, bool enable) +void si_pmu_sprom_enable(si_t *sih, bool enable) { chipcregs_t *cc; uint origidx; @@ -2515,7 +2506,7 @@ void si_pmu_sprom_enable(si_t *sih, struct osl_info *osh, bool enable) } /* initialize PMU chip controls and other chip level stuff */ -void si_pmu_chip_init(si_t *sih, struct osl_info *osh) +void si_pmu_chip_init(si_t *sih) { uint origidx; @@ -2527,7 +2518,7 @@ void si_pmu_chip_init(si_t *sih, struct osl_info *osh) #endif /* CHIPC_UART_ALWAYS_ON */ /* Gate off SPROM clock and chip select signals */ - si_pmu_sprom_enable(sih, osh, false); + si_pmu_sprom_enable(sih, false); /* Remember original core */ origidx = si_coreidx(sih); @@ -2537,26 +2528,26 @@ void si_pmu_chip_init(si_t *sih, struct osl_info *osh) } /* initialize PMU switch/regulators */ -void si_pmu_swreg_init(si_t *sih, struct osl_info *osh) +void si_pmu_swreg_init(si_t *sih) { ASSERT(sih->cccaps & CC_CAP_PMU); switch (sih->chip) { case BCM4336_CHIP_ID: /* Reduce CLDO PWM output voltage to 1.2V */ - si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CLDO_PWM, 0xe); + si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_PWM, 0xe); /* Reduce CLDO BURST output voltage to 1.2V */ - si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CLDO_BURST, + si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_BURST, 0xe); /* Reduce LNLDO1 output voltage to 1.2V */ - si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_LNLDO1, 0xe); + si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_LNLDO1, 0xe); if (sih->chiprev == 0) si_pmu_regcontrol(sih, 2, 0x400000, 0x400000); break; case BCM4330_CHIP_ID: /* CBUCK Voltage is 1.8 by default and set that to 1.5 */ - si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_PWM, 0); + si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CBUCK_PWM, 0); break; default: break; @@ -2581,8 +2572,7 @@ void si_pmu_radio_enable(si_t *sih, bool enable) /* Wait for a particular clock level to be on the backplane */ u32 -si_pmu_waitforclk_on_backplane(si_t *sih, struct osl_info *osh, u32 clk, - u32 delay) +si_pmu_waitforclk_on_backplane(si_t *sih, u32 clk, u32 delay) { chipcregs_t *cc; uint origidx; @@ -2610,7 +2600,7 @@ si_pmu_waitforclk_on_backplane(si_t *sih, struct osl_info *osh, u32 clk, #define EXT_ILP_HZ 32768 -u32 si_pmu_measure_alpclk(si_t *sih, struct osl_info *osh) +u32 si_pmu_measure_alpclk(si_t *sih) { chipcregs_t *cc; uint origidx; diff --git a/drivers/staging/brcm80211/util/nicpci.c b/drivers/staging/brcm80211/util/nicpci.c index c8f08d88870f..b5e79ac30b09 100644 --- a/drivers/staging/brcm80211/util/nicpci.c +++ b/drivers/staging/brcm80211/util/nicpci.c @@ -37,7 +37,6 @@ typedef struct { si_t *sih; /* System interconnect handle */ struct pci_dev *dev; - struct osl_info *osh; /* OSL handle */ u8 pciecap_lcreg_offset; /* PCIE capability LCreg offset in the config space */ bool pcie_pr42767; u8 pcie_polarity; @@ -81,7 +80,7 @@ static bool pcicore_pmecap(pcicore_info_t *pi); /* Initialize the PCI core. It's caller's responsibility to make sure that this is done * only once */ -void *pcicore_init(si_t *sih, struct osl_info *osh, void *regs) +void *pcicore_init(si_t *sih, void *pdev, void *regs) { pcicore_info_t *pi; @@ -95,8 +94,7 @@ void *pcicore_init(si_t *sih, struct osl_info *osh, void *regs) } pi->sih = sih; - pi->osh = osh; - pi->dev = osh->pdev; + pi->dev = pdev; if (sih->buscoretype == PCIE_CORE_ID) { u8 cap_ptr; @@ -185,7 +183,7 @@ pcicore_find_pci_capability(void *dev, u8 req_cap_id, /* ***** Register Access API */ uint -pcie_readreg(struct osl_info *osh, sbpcieregs_t *pcieregs, uint addrtype, +pcie_readreg(sbpcieregs_t *pcieregs, uint addrtype, uint offset) { uint retval = 0xFFFFFFFF; @@ -212,7 +210,7 @@ pcie_readreg(struct osl_info *osh, sbpcieregs_t *pcieregs, uint addrtype, } uint -pcie_writereg(struct osl_info *osh, sbpcieregs_t *pcieregs, uint addrtype, +pcie_writereg(sbpcieregs_t *pcieregs, uint addrtype, uint offset, uint val) { ASSERT(pcieregs != NULL); @@ -369,19 +367,18 @@ static void pcie_extendL1timer(pcicore_info_t *pi, bool extend) { u32 w; si_t *sih = pi->sih; - struct osl_info *osh = pi->osh; sbpcieregs_t *pcieregs = pi->regs.pcieregs; if (!PCIE_PUB(sih) || sih->buscorerev < 7) return; - w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG); + w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG); if (extend) w |= PCIE_ASPMTIMER_EXTEND; else w &= ~PCIE_ASPMTIMER_EXTEND; - pcie_writereg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w); - w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG); + pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w); + w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG); } /* centralized clkreq control policy */ @@ -434,7 +431,7 @@ static void pcie_war_polarity(pcicore_info_t *pi) if (pi->pcie_polarity != 0) return; - w = pcie_readreg(pi->osh, pi->regs.pcieregs, PCIE_PCIEREGS, + w = pcie_readreg(pi->regs.pcieregs, PCIE_PCIEREGS, PCIE_PLP_STATUSREG); /* Detect the current polarity at attach and force that polarity and @@ -553,22 +550,21 @@ static void pcie_war_noplldown(pcicore_info_t *pi) static void pcie_war_pci_setup(pcicore_info_t *pi) { si_t *sih = pi->sih; - struct osl_info *osh = pi->osh; sbpcieregs_t *pcieregs = pi->regs.pcieregs; u32 w; if ((sih->buscorerev == 0) || (sih->buscorerev == 1)) { - w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, + w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG); w |= 0x8; - pcie_writereg(osh, pcieregs, PCIE_PCIEREGS, + pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG, w); } if (sih->buscorerev == 1) { - w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG); + w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG); w |= (0x40); - pcie_writereg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w); + pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w); } if (sih->buscorerev == 0) { @@ -577,11 +573,11 @@ static void pcie_war_pci_setup(pcicore_info_t *pi) pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466); } else if (PCIE_ASPM(sih)) { /* Change the L1 threshold for better performance */ - w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, + w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG); w &= ~(PCIE_L1THRESHOLDTIME_MASK); w |= (PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT); - pcie_writereg(osh, pcieregs, PCIE_PCIEREGS, + pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w); pcie_war_serdes(pi); @@ -818,11 +814,10 @@ pcicore_pciereg(void *pch, u32 offset, u32 mask, u32 val, uint type) u32 reg_val = 0; pcicore_info_t *pi = (pcicore_info_t *) pch; sbpcieregs_t *pcieregs = pi->regs.pcieregs; - struct osl_info *osh = pi->osh; if (mask) { PCI_ERROR(("PCIEREG: 0x%x writeval 0x%x\n", offset, val)); - pcie_writereg(osh, pcieregs, type, offset, val); + pcie_writereg(pcieregs, type, offset, val); } /* Should not read register 0x154 */ @@ -830,7 +825,7 @@ pcicore_pciereg(void *pch, u32 offset, u32 mask, u32 val, uint type) && type == PCIE_PCIEREGS) return reg_val; - reg_val = pcie_readreg(osh, pcieregs, type, offset); + reg_val = pcie_readreg(pcieregs, type, offset); PCI_ERROR(("PCIEREG: 0x%x readval is 0x%x\n", offset, reg_val)); return reg_val; diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index 1357302ffb87..d8d8f829b320 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -55,8 +55,8 @@ #endif /* local prototypes */ -static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, - void *regs, uint bustype, void *sdh, char **vars, +static si_info_t *si_doattach(si_info_t *sii, uint devid, void *regs, + uint bustype, void *sdh, char **vars, uint *varsz); static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh); @@ -83,7 +83,7 @@ static u32 si_gpioreservation; * vars - pointer to a pointer area for "environment" variables * varsz - pointer to int to return the size of the vars */ -si_t *si_attach(uint devid, struct osl_info *osh, void *regs, uint bustype, +si_t *si_attach(uint devid, void *regs, uint bustype, void *sdh, char **vars, uint *varsz) { si_info_t *sii; @@ -95,7 +95,7 @@ si_t *si_attach(uint devid, struct osl_info *osh, void *regs, uint bustype, return NULL; } - if (si_doattach(sii, devid, osh, regs, bustype, sdh, vars, varsz) == + if (si_doattach(sii, devid, regs, bustype, sdh, vars, varsz) == NULL) { kfree(sii); return NULL; @@ -287,7 +287,7 @@ static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, if (SI_FAST(sii)) { if (!sii->pch) { sii->pch = (void *)pcicore_init( - &sii->pub, sii->osh, + &sii->pub, sii->pbus, (void *)PCIEREGS(sii)); if (sii->pch == NULL) return false; @@ -366,7 +366,7 @@ static __used void si_nvram_process(si_info_t *sii, char *pvars) /* this is will make Sonics calls directly, since Sonics is no longer supported in the Si abstraction */ /* this has been customized for the bcm 4329 ONLY */ #ifdef BCMSDIO -static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, +static si_info_t *si_doattach(si_info_t *sii, uint devid, void *regs, uint bustype, void *pbus, char **vars, uint *varsz) { @@ -386,7 +386,6 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, sii->curmap = regs; sii->pbus = pbus; - sii->osh = osh; /* find Chipcommon address */ cc = (chipcregs_t *) sii->curmap; @@ -466,15 +465,15 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, /* PMU specific initializations */ if (PMUCTL_ENAB(sih)) { u32 xtalfreq; - si_pmu_init(sih, sii->osh); - si_pmu_chip_init(sih, sii->osh); + si_pmu_init(sih); + si_pmu_chip_init(sih); xtalfreq = getintvar(pvars, "xtalfreq"); /* If xtalfreq var not available, try to measure it */ if (xtalfreq == 0) - xtalfreq = si_pmu_measure_alpclk(sih, sii->osh); - si_pmu_pll_init(sih, sii->osh, xtalfreq); - si_pmu_res_init(sih, sii->osh); - si_pmu_swreg_init(sih, sii->osh); + xtalfreq = si_pmu_measure_alpclk(sih); + si_pmu_pll_init(sih, xtalfreq); + si_pmu_res_init(sih); + si_pmu_swreg_init(sih); } /* setup the GPIO based LED powersave register */ @@ -496,7 +495,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, } #else /* BCMSDIO */ -static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, +static si_info_t *si_doattach(si_info_t *sii, uint devid, void *regs, uint bustype, void *pbus, char **vars, uint *varsz) { @@ -516,7 +515,6 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, sii->curmap = regs; sii->pbus = pbus; - sii->osh = osh; /* check to see if we are a si core mimic'ing a pci core */ if (bustype == PCI_BUS) { @@ -609,7 +607,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, /* Init nvram from sprom/otp if they exist */ if (srom_var_init - (&sii->pub, bustype, regs, sii->osh, vars, varsz)) { + (&sii->pub, bustype, regs, vars, varsz)) { SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n")); goto exit; } @@ -625,15 +623,15 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, /* PMU specific initializations */ if (PMUCTL_ENAB(sih)) { u32 xtalfreq; - si_pmu_init(sih, sii->osh); - si_pmu_chip_init(sih, sii->osh); + si_pmu_init(sih); + si_pmu_chip_init(sih); xtalfreq = getintvar(pvars, "xtalfreq"); /* If xtalfreq var not available, try to measure it */ if (xtalfreq == 0) - xtalfreq = si_pmu_measure_alpclk(sih, sii->osh); - si_pmu_pll_init(sih, sii->osh, xtalfreq); - si_pmu_res_init(sih, sii->osh); - si_pmu_swreg_init(sih, sii->osh); + xtalfreq = si_pmu_measure_alpclk(sih); + si_pmu_pll_init(sih, xtalfreq); + si_pmu_res_init(sih); + si_pmu_swreg_init(sih); } /* setup the GPIO based LED powersave register */ @@ -726,14 +724,6 @@ void si_detach(si_t *sih) kfree(sii); } -struct osl_info *si_osh(si_t *sih) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - return sii->osh; -} - /* register driver interrupt disabling and restoring callback functions */ void si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn, @@ -993,7 +983,7 @@ void si_core_reset(si_t *sih, u32 bits, u32 resetbits) u32 si_alp_clock(si_t *sih) { if (PMUCTL_ENAB(sih)) - return si_pmu_alp_clock(sih, si_osh(sih)); + return si_pmu_alp_clock(sih); return ALP_CLOCK; } @@ -1001,7 +991,7 @@ u32 si_alp_clock(si_t *sih) u32 si_ilp_clock(si_t *sih) { if (PMUCTL_ENAB(sih)) - return si_pmu_ilp_clock(sih, si_osh(sih)); + return si_pmu_ilp_clock(sih); return ILP_CLOCK; } @@ -1219,7 +1209,7 @@ u16 si_clkctl_fast_pwrup_delay(si_t *sih) sii = SI_INFO(sih); if (PMUCTL_ENAB(sih)) { INTR_OFF(sii, intr_val); - fpdelay = si_pmu_fast_pwrup_delay(sih, sii->osh); + fpdelay = si_pmu_fast_pwrup_delay(sih); INTR_RESTORE(sii, intr_val); return fpdelay; } @@ -1461,7 +1451,7 @@ int si_devpath(si_t *sih, char *path, int size) slen = snprintf(path, (size_t) size, "sb/%u/", si_coreidx(sih)); break; case PCI_BUS: - ASSERT((SI_INFO(sih))->osh != NULL); + ASSERT((SI_INFO(sih))->pbus != NULL); slen = snprintf(path, (size_t) size, "pci/%u/%u/", ((struct pci_dev *)((SI_INFO(sih))->pbus))->bus->number, PCI_SLOT( @@ -1927,7 +1917,7 @@ bool si_deviceremoved(si_t *sih) switch (sih->bustype) { case PCI_BUS: - ASSERT(sii->osh != NULL); + ASSERT(sii->pbus != NULL); pci_read_config_dword(sii->pbus, PCI_CFG_VID, &w); if ((w & 0xFFFF) != VENDOR_BROADCOM) return true; @@ -2004,14 +1994,14 @@ bool si_is_otp_disabled(si_t *sih) bool si_is_otp_powered(si_t *sih) { if (PMUCTL_ENAB(sih)) - return si_pmu_is_otp_powered(sih, si_osh(sih)); + return si_pmu_is_otp_powered(sih); return true; } void si_otp_power(si_t *sih, bool on) { if (PMUCTL_ENAB(sih)) - si_pmu_otp_power(sih, si_osh(sih), on); + si_pmu_otp_power(sih, on); udelay(1000); } -- cgit v1.2.3 From d769f4ce8738d1b56080d16716f645910d02eebf Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 1 Mar 2011 10:56:56 +0100 Subject: staging: brcm80211: change prototype for wlc_antsel_attach wlc_antsel_attach was called with four parameters but actually three parameters were already provided in the first parameter. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_antsel.c | 13 ++++++------- drivers/staging/brcm80211/brcmsmac/wlc_antsel.h | 9 ++++----- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 2 +- 3 files changed, 11 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c index 0a52989313ed..5b195ed63768 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c @@ -94,20 +94,19 @@ const u8 mimo_2x3_div_antselid_tbl[16] = { 0, 0, 0, 0, 0, 0, 0, 0 /* pat to antselid */ }; -struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc, - struct osl_info *osh, - struct wlc_pub *pub, - struct wlc_hw_info *wlc_hw) { +struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc) +{ struct antsel_info *asi; asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC); if (!asi) { - WL_ERROR("wl%d: wlc_antsel_attach: out of mem\n", pub->unit); + WL_ERROR("wl%d: wlc_antsel_attach: out of mem\n", + wlc->pub->unit); return NULL; } asi->wlc = wlc; - asi->pub = pub; + asi->pub = wlc->pub; asi->antsel_type = ANTSEL_NA; asi->antsel_avail = false; asi->antsel_antswitch = (u8) getintvar(asi->pub->vars, "antswitch"); @@ -150,7 +149,7 @@ struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc, } /* Set the antenna selection type for the low driver */ - wlc_bmac_antsel_type_set(wlc_hw, asi->antsel_type); + wlc_bmac_antsel_type_set(wlc->hw, asi->antsel_type); /* Init (auto/manual) antenna selection */ wlc_antsel_init_cfg(asi, &asi->antcfg_11n, true); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.h b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.h index 8875b5848665..2470c73fc4ed 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.h @@ -16,10 +16,8 @@ #ifndef _wlc_antsel_h_ #define _wlc_antsel_h_ -extern struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc, - struct osl_info *osh, - struct wlc_pub *pub, - struct wlc_hw_info *wlc_hw); + +extern struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc); extern void wlc_antsel_detach(struct antsel_info *asi); extern void wlc_antsel_init(struct antsel_info *asi); extern void wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, @@ -27,4 +25,5 @@ extern void wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, u8 id, u8 fbid, u8 *antcfg, u8 *fbantcfg); extern u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel); -#endif /* _wlc_antsel_h_ */ + +#endif /* _wlc_antsel_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index c00051bcf9a7..aefef8e29c5c 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -1692,7 +1692,7 @@ static uint wlc_attach_module(struct wlc_info *wlc) uint unit; unit = wlc->pub->unit; - wlc->asi = wlc_antsel_attach(wlc, wlc->osh, wlc->pub, wlc->hw); + wlc->asi = wlc_antsel_attach(wlc); if (wlc->asi == NULL) { WL_ERROR("wl%d: wlc_attach: wlc_antsel_attach failed\n", unit); err = 44; -- cgit v1.2.3 From 8d1dc20e8d689c7e6a0a4d2c94e36a99d5793ecb Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 1 Mar 2011 13:23:27 -0800 Subject: Revert "TPM: Long default timeout fix" This reverts commit c4ff4b829ef9e6353c0b133b7adb564a68054979. Ted Ts'o reports: "TPM is working for me so I can log into employer's network in 2.6.37. It broke when I tried 2.6.38-rc6, with the following relevant lines from my dmesg: [ 11.081627] tpm_tis 00:0b: 1.2 TPM (device-id 0x0, rev-id 78) [ 25.734114] tpm_tis 00:0b: Operation Timed out [ 78.040949] tpm_tis 00:0b: Operation Timed out This caused me to get suspicious, especially since the _other_ TPM commit in 2.6.38 had already been reverted, so I tried reverting commit c4ff4b829e: "TPM: Long default timeout fix". With this commit reverted, my TPM on my Lenovo T410 is once again working." Requested-and-tested-by: Theodore Ts'o Acked-by: Rajiv Andrade Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 36e0fa161c2b..1f46f1cd9225 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -364,14 +364,12 @@ unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, tpm_protected_ordinal_duration[ordinal & TPM_PROTECTED_ORDINAL_MASK]; - if (duration_idx != TPM_UNDEFINED) { + if (duration_idx != TPM_UNDEFINED) duration = chip->vendor.duration[duration_idx]; - /* if duration is 0, it's because chip->vendor.duration wasn't */ - /* filled yet, so we set the lowest timeout just to give enough */ - /* time for tpm_get_timeouts() to succeed */ - return (duration <= 0 ? HZ : duration); - } else + if (duration <= 0) return 2 * 60 * HZ; + else + return duration; } EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration); -- cgit v1.2.3 From 2fbd6b37bf35073113d1adb71cdf801330fab01e Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Tue, 1 Mar 2011 23:15:25 +0300 Subject: brcm80211: use proper ieee80211 routines removed the following defines as a side effect: - FC_SUBTYPE_ANY_QOS - FC_KIND_MASK - FC_PROBE_REQ - FC_PROBE_RESP - FC_BEACON - FC_PS_POLL - FC_RTS - FC_CTS also fixed possible bug when the CPU byte ordered fc was passed into ieee80211_is_data and ieee80211_is_mgmt Signed-off-by: Stanislav Fomichev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 7 +-- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 77 ++++++++++------------- drivers/staging/brcm80211/include/proto/802.11.h | 11 ---- 3 files changed, 37 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index 05e99e5369bd..0162ba4fb02f 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -632,17 +632,16 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, * test whether need to break or change the epoch */ if (count == 0) { - u16 fc; mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT); /* refill the bits since might be a retx mpdu */ mcl |= TXC_STARTMSDU; rts = (struct ieee80211_rts *)&txh->rts_frame; - fc = le16_to_cpu(rts->frame_control); - if ((fc & FC_KIND_MASK) == FC_RTS) { + + if (ieee80211_is_rts(rts->frame_control)) { mcl |= TXC_SENDRTS; use_rts = true; } - if ((fc & FC_KIND_MASK) == FC_CTS) { + if (ieee80211_is_cts(rts->frame_control)) { mcl |= TXC_SENDCTS; use_cts = true; } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c index aefef8e29c5c..2772cce78dc0 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c @@ -5189,15 +5189,12 @@ wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, void *pkt; struct scb *scb = &global_scb; struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data); - u16 type, fc; ASSERT(sdu); - fc = le16_to_cpu(d11_header->frame_control); - type = (fc & IEEE80211_FCTL_FTYPE); - /* 802.11 standard requires management traffic to go at highest priority */ - prio = (type == IEEE80211_FTYPE_DATA ? sdu->priority : MAXPRIO); + prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority : + MAXPRIO; fifo = prio2fifo[prio]; ASSERT((uint) skb_headroom(sdu) >= TXOFF); @@ -5731,7 +5728,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN]; struct osl_info *osh; int len, phylen, rts_phylen; - u16 fc, type, frameid, mch, phyctl, xfts, mainrates; + u16 frameid, mch, phyctl, xfts, mainrates; u16 seq = 0, mcl = 0, status = 0; ratespec_t rspec[2] = { WLC_RATE_1M, WLC_RATE_1M }, rts_rspec[2] = { WLC_RATE_1M, WLC_RATE_1M}; @@ -5768,11 +5765,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* locate 802.11 MAC header */ h = (struct ieee80211_hdr *)(p->data); - fc = le16_to_cpu(h->frame_control); - type = (fc & IEEE80211_FCTL_FTYPE); - - qos = (type == IEEE80211_FTYPE_DATA && - FC_SUBTYPE_ANY_QOS(fc)); + qos = ieee80211_is_data_qos(h->frame_control); /* compute length of frame in bytes for use in PLCP computations */ len = pkttotlen(p); @@ -5824,7 +5817,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, frameid |= queue & TXFID_QUEUE_MASK; /* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */ - if (SCB_PS(scb) || ((fc & FC_KIND_MASK) == FC_BEACON)) + if (SCB_PS(scb) || ieee80211_is_beacon(h->frame_control)) mcl |= TXC_IGNOREPMQ; ASSERT(hw->max_rates <= IEEE80211_TX_MAX_RATES); @@ -6029,7 +6022,8 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, txrate[1]->count = 0; /* (2) PROTECTION, may change rspec */ - if ((ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) && + if ((ieee80211_is_data(h->frame_control) || + ieee80211_is_mgmt(h->frame_control)) && (phylen > wlc->RTSThresh) && !is_multicast_ether_addr(h->addr1)) use_rts = true; @@ -6051,7 +6045,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, plcp[0]; /* DUR field for main rate */ - if ((fc != FC_PS_POLL) && + if (!ieee80211_is_pspoll(h->frame_control) && !is_multicast_ether_addr(h->addr1) && !use_rifs) { durid = wlc_compute_frame_dur(wlc, rspec[0], preamble_type[0], @@ -6068,7 +6062,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, } /* DUR field for fallback rate */ - if (fc == FC_PS_POLL) + if (ieee80211_is_pspoll(h->frame_control)) txh->FragDurFallback = h->duration_id; else if (is_multicast_ether_addr(h->addr1) || use_rifs) txh->FragDurFallback = 0; @@ -6199,10 +6193,14 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, txh->RTSDurFallback = cpu_to_le16(durid); if (use_cts) { - rts->frame_control = cpu_to_le16(FC_CTS); + rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | + IEEE80211_STYPE_CTS); + memcpy(&rts->ra, &h->addr2, ETH_ALEN); } else { - rts->frame_control = cpu_to_le16((u16) FC_RTS); + rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | + IEEE80211_STYPE_RTS); + memcpy(&rts->ra, &h->addr1, 2 * ETH_ALEN); } @@ -6578,7 +6576,6 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) uint totlen, supr_status; bool lastframe; struct ieee80211_hdr *h; - u16 fc; u16 mcl; struct ieee80211_tx_info *tx_info; struct ieee80211_tx_rate *txrate; @@ -6633,7 +6630,6 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) tx_info = IEEE80211_SKB_CB(p); h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); - fc = le16_to_cpu(h->frame_control); scb = (struct scb *)tx_info->control.sta->drv_priv; @@ -6662,7 +6658,7 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) tx_rts_count = (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT; - lastframe = (fc & IEEE80211_FCTL_MOREFRAGS) == 0; + lastframe = !ieee80211_has_morefrags(h->frame_control); if (!lastframe) { WL_ERROR("Not last frame!\n"); @@ -7024,7 +7020,6 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) d11rxhdr_t *rxh; struct ieee80211_hdr *h; struct osl_info *osh; - u16 fc; uint len; bool is_amsdu; @@ -7076,9 +7071,7 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) } /* check received pkt has at least frame control field */ - if (len >= D11_PHY_HDR_LEN + sizeof(h->frame_control)) { - fc = le16_to_cpu(h->frame_control); - } else { + if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control)) { wlc->pub->_cnt->rxrunt++; goto toss; } @@ -7088,8 +7081,9 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) /* explicitly test bad src address to avoid sending bad deauth */ if (!is_amsdu) { /* CTS and ACK CTL frames are w/o a2 */ - if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA || - (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { + + if (ieee80211_is_data(h->frame_control) || + ieee80211_is_mgmt(h->frame_control)) { if ((is_zero_ether_addr(h->addr2) || is_multicast_ether_addr(h->addr2))) { WL_ERROR("wl%d: %s: dropping a frame with " @@ -7103,10 +7097,8 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) } /* due to sheer numbers, toss out probe reqs for now */ - if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { - if ((fc & FC_KIND_MASK) == FC_PROBE_REQ) - goto toss; - } + if (ieee80211_is_probe_req(h->frame_control)) + goto toss; if (is_amsdu) { WL_ERROR("%s: is_amsdu causing toss\n", __func__); @@ -7659,7 +7651,7 @@ wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec, * and included up to, but not including, the 4 byte FCS. */ static void -wlc_bcn_prb_template(struct wlc_info *wlc, uint type, ratespec_t bcn_rspec, +wlc_bcn_prb_template(struct wlc_info *wlc, u16 type, ratespec_t bcn_rspec, wlc_bsscfg_t *cfg, u16 *buf, int *len) { static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; @@ -7668,9 +7660,10 @@ wlc_bcn_prb_template(struct wlc_info *wlc, uint type, ratespec_t bcn_rspec, int hdr_len, body_len; ASSERT(*len >= 142); - ASSERT(type == FC_BEACON || type == FC_PROBE_RESP); + ASSERT(type == IEEE80211_STYPE_BEACON || + type == IEEE80211_STYPE_PROBE_RESP); - if (MBSS_BCN_ENAB(cfg) && type == FC_BEACON) + if (MBSS_BCN_ENAB(cfg) && type == IEEE80211_STYPE_BEACON) hdr_len = DOT11_MAC_HDR_LEN; else hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN; @@ -7684,7 +7677,7 @@ wlc_bcn_prb_template(struct wlc_info *wlc, uint type, ratespec_t bcn_rspec, plcp = (cck_phy_hdr_t *) buf; /* PLCP for Probe Response frames are filled in from core's rate table */ - if (type == FC_BEACON && !MBSS_BCN_ENAB(cfg)) { + if (type == IEEE80211_STYPE_BEACON && !MBSS_BCN_ENAB(cfg)) { /* fill in PLCP */ wlc_compute_plcp(wlc, bcn_rspec, (DOT11_MAC_HDR_LEN + body_len + FCS_LEN), @@ -7696,17 +7689,17 @@ wlc_bcn_prb_template(struct wlc_info *wlc, uint type, ratespec_t bcn_rspec, if (!SOFTBCN_ENAB(cfg)) wlc_beacon_phytxctl_txant_upd(wlc, bcn_rspec); - if (MBSS_BCN_ENAB(cfg) && type == FC_BEACON) + if (MBSS_BCN_ENAB(cfg) && type == IEEE80211_STYPE_BEACON) h = (struct ieee80211_mgmt *)&plcp[0]; else h = (struct ieee80211_mgmt *)&plcp[1]; /* fill in 802.11 header */ - h->frame_control = cpu_to_le16((u16) type); + h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type); /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */ /* A1 filled in by MAC for prb resp, broadcast for bcn */ - if (type == FC_BEACON) + if (type == IEEE80211_STYPE_BEACON) memcpy(&h->da, ðer_bcast, ETH_ALEN); memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN); memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN); @@ -7771,8 +7764,8 @@ void wlc_bss_update_beacon(struct wlc_info *wlc, wlc_bsscfg_t *cfg) true)); /* update the template and ucode shm */ - wlc_bcn_prb_template(wlc, FC_BEACON, wlc->bcn_rspec, cfg, bcn, - &len); + wlc_bcn_prb_template(wlc, IEEE80211_STYPE_BEACON, + wlc->bcn_rspec, cfg, bcn, &len); wlc_write_hw_bcntemplates(wlc, bcn, len, false); } } @@ -7831,8 +7824,8 @@ wlc_bss_update_probe_resp(struct wlc_info *wlc, wlc_bsscfg_t *cfg, bool suspend) if (!MBSS_PRB_ENAB(cfg)) { /* create the probe response template */ - wlc_bcn_prb_template(wlc, FC_PROBE_RESP, 0, cfg, prb_resp, - &len); + wlc_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0, cfg, + prb_resp, &len); if (suspend) wlc_suspend_mac_and_wait(wlc); @@ -7870,7 +7863,6 @@ int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) d11txh_t *txh; struct ieee80211_hdr *h; struct scb *scb; - u16 fc; osh = wlc->osh; @@ -7879,7 +7871,6 @@ int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) ASSERT(txh); h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); ASSERT(h); - fc = le16_to_cpu(h->frame_control); /* get the pkt queue info. This was put at wlc_sendctl or wlc_send for PDU */ fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK; diff --git a/drivers/staging/brcm80211/include/proto/802.11.h b/drivers/staging/brcm80211/include/proto/802.11.h index 913cb547731b..5cdfc7a6e80c 100644 --- a/drivers/staging/brcm80211/include/proto/802.11.h +++ b/drivers/staging/brcm80211/include/proto/802.11.h @@ -116,17 +116,6 @@ typedef struct wme_param_ie wme_param_ie_t; #define SEQNUM_MAX 0x1000 #define FRAGNUM_MASK 0xF -#define FC_SUBTYPE_ANY_QOS(s) ((((fc) & IEEE80211_FCTL_STYPE & (1<<7))) != 0) - -#define FC_KIND_MASK (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE) - -#define FC_PROBE_REQ (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ) -#define FC_PROBE_RESP (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP) -#define FC_BEACON (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON) -#define FC_PS_POLL (IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL) -#define FC_RTS (IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS) -#define FC_CTS (IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS) - #define TLV_LEN_OFF 1 #define TLV_HDR_LEN 2 #define TLV_BODY_OFF 2 -- cgit v1.2.3 From 6170f51b19efd0e8c9758fe5f4cc3d751b5e5d8e Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Tue, 1 Mar 2011 23:15:26 +0300 Subject: brcm80211: remove unused TLV defines Signed-off-by: Stanislav Fomichev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/proto/802.11.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/proto/802.11.h b/drivers/staging/brcm80211/include/proto/802.11.h index 5cdfc7a6e80c..374125d770b9 100644 --- a/drivers/staging/brcm80211/include/proto/802.11.h +++ b/drivers/staging/brcm80211/include/proto/802.11.h @@ -116,10 +116,6 @@ typedef struct wme_param_ie wme_param_ie_t; #define SEQNUM_MAX 0x1000 #define FRAGNUM_MASK 0xF -#define TLV_LEN_OFF 1 -#define TLV_HDR_LEN 2 -#define TLV_BODY_OFF 2 - #define DOT11_MNG_RSN_ID 48 #define DOT11_MNG_WPA_ID 221 #define DOT11_MNG_VS_ID 221 -- cgit v1.2.3 From 420d44daa7aa1cc847e9e527f0a27a9ce61768ca Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 1 Mar 2011 14:19:23 -0800 Subject: ipv4: Make final arg to ip_route_output_flow to be boolean "can_sleep" Since that is what the current vague "flags" argument means. Signed-off-by: David S. Miller --- drivers/infiniband/hw/cxgb3/iwch_cm.c | 2 +- drivers/infiniband/hw/cxgb4/cm.c | 2 +- drivers/scsi/cxgbi/libcxgbi.c | 2 +- include/net/route.h | 6 +++--- net/dccp/ipv4.c | 2 +- net/ipv4/af_inet.c | 2 +- net/ipv4/inet_connection_sock.c | 2 +- net/ipv4/ip_output.c | 2 +- net/ipv4/raw.c | 2 +- net/ipv4/route.c | 6 +++--- net/ipv4/udp.c | 2 +- net/l2tp/l2tp_ip.c | 2 +- 12 files changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index d02dcc6e5963..c7f776c8b2b8 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c @@ -354,7 +354,7 @@ static struct rtable *find_route(struct t3cdev *dev, __be32 local_ip, } }; - if (ip_route_output_flow(&init_net, &rt, &fl, NULL, 0)) + if (ip_route_output_flow(&init_net, &rt, &fl, NULL, false)) return NULL; return rt; } diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 8b00e6c46f01..5542c994338d 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -331,7 +331,7 @@ static struct rtable *find_route(struct c4iw_dev *dev, __be32 local_ip, } }; - if (ip_route_output_flow(&init_net, &rt, &fl, NULL, 0)) + if (ip_route_output_flow(&init_net, &rt, &fl, NULL, false)) return NULL; return rt; } diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index d2ad3d676724..fabca75ac2f2 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c @@ -470,7 +470,7 @@ static struct rtable *find_route_ipv4(__be32 saddr, __be32 daddr, } }; - if (ip_route_output_flow(&init_net, &rt, &fl, NULL, 0)) + if (ip_route_output_flow(&init_net, &rt, &fl, NULL, false)) return NULL; return rt; diff --git a/include/net/route.h b/include/net/route.h index 5e0826d1c0e0..6de4333d6002 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -120,7 +120,7 @@ extern void rt_cache_flush(struct net *net, int how); extern void rt_cache_flush_batch(struct net *net); extern int __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp); extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp); -extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, int flags); +extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, bool can_sleep); extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, u8 tos, struct net_device *devin, bool noref); @@ -196,7 +196,7 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst, *rp = NULL; } security_sk_classify_flow(sk, &fl); - return ip_route_output_flow(net, rp, &fl, sk, can_sleep ? 1 : 0); + return ip_route_output_flow(net, rp, &fl, sk, can_sleep); } static inline int ip_route_newports(struct rtable **rp, u8 protocol, @@ -220,7 +220,7 @@ static inline int ip_route_newports(struct rtable **rp, u8 protocol, ip_rt_put(*rp); *rp = NULL; security_sk_classify_flow(sk, &fl); - return ip_route_output_flow(sock_net(sk), rp, &fl, sk, 0); + return ip_route_output_flow(sock_net(sk), rp, &fl, sk, false); } return 0; } diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 8372d5c571a0..3d4b82f6adfd 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -475,7 +475,7 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk, }; security_skb_classify_flow(skb, &fl); - if (ip_route_output_flow(net, &rt, &fl, sk, 0)) { + if (ip_route_output_flow(net, &rt, &fl, sk, false)) { IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); return NULL; } diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index d16687db9713..7d90fe0ee5a6 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1174,7 +1174,7 @@ int inet_sk_rebuild_header(struct sock *sk) }; security_sk_classify_flow(sk, &fl); - err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk, 0); + err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk, false); } if (!err) sk_setup_caps(sk, &rt->dst); diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 97e5fb765265..0caeb69de4b1 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -369,7 +369,7 @@ struct dst_entry *inet_csk_route_req(struct sock *sk, struct net *net = sock_net(sk); security_req_classify_flow(req, &fl); - if (ip_route_output_flow(net, &rt, &fl, sk, 0)) + if (ip_route_output_flow(net, &rt, &fl, sk, false)) goto no_route; if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) goto route_err; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 460308c35028..e6905c562fb7 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -355,7 +355,7 @@ int ip_queue_xmit(struct sk_buff *skb) * itself out. */ security_sk_classify_flow(sk, &fl); - if (ip_route_output_flow(sock_net(sk), &rt, &fl, sk, 0)) + if (ip_route_output_flow(sock_net(sk), &rt, &fl, sk, false)) goto no_route; } sk_setup_caps(sk, &rt->dst); diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 6390ba299b3d..e1857658964d 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -563,7 +563,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, } security_sk_classify_flow(sk, &fl); - err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk, 1); + err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk, true); } if (err) goto done; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 52b077d45208..1ac3ecaf36e8 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2720,7 +2720,7 @@ static int ipv4_dst_blackhole(struct net *net, struct rtable **rp, struct flowi } int ip_route_output_flow(struct net *net, struct rtable **rp, struct flowi *flp, - struct sock *sk, int flags) + struct sock *sk, bool can_sleep) { int err; @@ -2733,7 +2733,7 @@ int ip_route_output_flow(struct net *net, struct rtable **rp, struct flowi *flp, if (!flp->fl4_dst) flp->fl4_dst = (*rp)->rt_dst; err = __xfrm_lookup(net, (struct dst_entry **)rp, flp, sk, - flags ? XFRM_LOOKUP_WAIT : 0); + can_sleep ? XFRM_LOOKUP_WAIT : 0); if (err == -EREMOTE) err = ipv4_dst_blackhole(net, rp, flp); @@ -2746,7 +2746,7 @@ EXPORT_SYMBOL_GPL(ip_route_output_flow); int ip_route_output_key(struct net *net, struct rtable **rp, struct flowi *flp) { - return ip_route_output_flow(net, rp, flp, NULL, 0); + return ip_route_output_flow(net, rp, flp, NULL, false); } EXPORT_SYMBOL(ip_route_output_key); diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 8155d6eda376..790187b5c308 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -920,7 +920,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, struct net *net = sock_net(sk); security_sk_classify_flow(sk, &fl); - err = ip_route_output_flow(net, &rt, &fl, sk, 1); + err = ip_route_output_flow(net, &rt, &fl, sk, true); if (err) { if (err == -ENETUNREACH) IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 28e876a6b1dd..7744a8e4b4c6 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -489,7 +489,7 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m * itself out. */ security_sk_classify_flow(sk, &fl); - if (ip_route_output_flow(sock_net(sk), &rt, &fl, sk, 0)) + if (ip_route_output_flow(sock_net(sk), &rt, &fl, sk, false)) goto no_route; } sk_setup_caps(sk, &rt->dst); -- cgit v1.2.3 From 273447b352e69c327efdecfd6e1d6fe3edbdcd14 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 1 Mar 2011 14:27:04 -0800 Subject: ipv4: Kill can_sleep arg to ip_route_output_flow() This boolean state is now available in the flow flags. Signed-off-by: David S. Miller --- drivers/infiniband/hw/cxgb3/iwch_cm.c | 2 +- drivers/infiniband/hw/cxgb4/cm.c | 2 +- drivers/scsi/cxgbi/libcxgbi.c | 2 +- include/net/route.h | 6 +++--- net/dccp/ipv4.c | 2 +- net/ipv4/af_inet.c | 2 +- net/ipv4/inet_connection_sock.c | 2 +- net/ipv4/ip_output.c | 2 +- net/ipv4/raw.c | 2 +- net/ipv4/route.c | 7 ++++--- net/ipv4/udp.c | 2 +- net/l2tp/l2tp_ip.c | 2 +- 12 files changed, 17 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index c7f776c8b2b8..e654285aa6ba 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c @@ -354,7 +354,7 @@ static struct rtable *find_route(struct t3cdev *dev, __be32 local_ip, } }; - if (ip_route_output_flow(&init_net, &rt, &fl, NULL, false)) + if (ip_route_output_flow(&init_net, &rt, &fl, NULL)) return NULL; return rt; } diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 5542c994338d..7e0484f18db5 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -331,7 +331,7 @@ static struct rtable *find_route(struct c4iw_dev *dev, __be32 local_ip, } }; - if (ip_route_output_flow(&init_net, &rt, &fl, NULL, false)) + if (ip_route_output_flow(&init_net, &rt, &fl, NULL)) return NULL; return rt; } diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index fabca75ac2f2..261aa817bdd5 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c @@ -470,7 +470,7 @@ static struct rtable *find_route_ipv4(__be32 saddr, __be32 daddr, } }; - if (ip_route_output_flow(&init_net, &rt, &fl, NULL, false)) + if (ip_route_output_flow(&init_net, &rt, &fl, NULL)) return NULL; return rt; diff --git a/include/net/route.h b/include/net/route.h index 1be5c05a0905..923e670586d4 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -120,7 +120,7 @@ extern void rt_cache_flush(struct net *net, int how); extern void rt_cache_flush_batch(struct net *net); extern int __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp); extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp); -extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, bool can_sleep); +extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk); extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, u8 tos, struct net_device *devin, bool noref); @@ -198,7 +198,7 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst, *rp = NULL; } security_sk_classify_flow(sk, &fl); - return ip_route_output_flow(net, rp, &fl, sk, can_sleep); + return ip_route_output_flow(net, rp, &fl, sk); } static inline int ip_route_newports(struct rtable **rp, u8 protocol, @@ -222,7 +222,7 @@ static inline int ip_route_newports(struct rtable **rp, u8 protocol, ip_rt_put(*rp); *rp = NULL; security_sk_classify_flow(sk, &fl); - return ip_route_output_flow(sock_net(sk), rp, &fl, sk, false); + return ip_route_output_flow(sock_net(sk), rp, &fl, sk); } return 0; } diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 3d4b82f6adfd..a8ff95502081 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -475,7 +475,7 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk, }; security_skb_classify_flow(skb, &fl); - if (ip_route_output_flow(net, &rt, &fl, sk, false)) { + if (ip_route_output_flow(net, &rt, &fl, sk)) { IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); return NULL; } diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 7d90fe0ee5a6..44513bb8ac2e 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1174,7 +1174,7 @@ int inet_sk_rebuild_header(struct sock *sk) }; security_sk_classify_flow(sk, &fl); - err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk, false); + err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk); } if (!err) sk_setup_caps(sk, &rt->dst); diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 0caeb69de4b1..7f85d4aec26a 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -369,7 +369,7 @@ struct dst_entry *inet_csk_route_req(struct sock *sk, struct net *net = sock_net(sk); security_req_classify_flow(req, &fl); - if (ip_route_output_flow(net, &rt, &fl, sk, false)) + if (ip_route_output_flow(net, &rt, &fl, sk)) goto no_route; if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) goto route_err; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index e6905c562fb7..68dbe2d93d9d 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -355,7 +355,7 @@ int ip_queue_xmit(struct sk_buff *skb) * itself out. */ security_sk_classify_flow(sk, &fl); - if (ip_route_output_flow(sock_net(sk), &rt, &fl, sk, false)) + if (ip_route_output_flow(sock_net(sk), &rt, &fl, sk)) goto no_route; } sk_setup_caps(sk, &rt->dst); diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index e8e8613bcbcc..d7a2d1eaec09 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -564,7 +564,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, } security_sk_classify_flow(sk, &fl); - err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk, true); + err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk); } if (err) goto done; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 1ac3ecaf36e8..78462658fccb 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2720,7 +2720,7 @@ static int ipv4_dst_blackhole(struct net *net, struct rtable **rp, struct flowi } int ip_route_output_flow(struct net *net, struct rtable **rp, struct flowi *flp, - struct sock *sk, bool can_sleep) + struct sock *sk) { int err; @@ -2733,7 +2733,8 @@ int ip_route_output_flow(struct net *net, struct rtable **rp, struct flowi *flp, if (!flp->fl4_dst) flp->fl4_dst = (*rp)->rt_dst; err = __xfrm_lookup(net, (struct dst_entry **)rp, flp, sk, - can_sleep ? XFRM_LOOKUP_WAIT : 0); + ((flp->flags & FLOWI_FLAG_CAN_SLEEP) ? + XFRM_LOOKUP_WAIT : 0)); if (err == -EREMOTE) err = ipv4_dst_blackhole(net, rp, flp); @@ -2746,7 +2747,7 @@ EXPORT_SYMBOL_GPL(ip_route_output_flow); int ip_route_output_key(struct net *net, struct rtable **rp, struct flowi *flp) { - return ip_route_output_flow(net, rp, flp, NULL, false); + return ip_route_output_flow(net, rp, flp, NULL); } EXPORT_SYMBOL(ip_route_output_key); diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index c6bcc93debd5..ed9a5b7bee53 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -922,7 +922,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, struct net *net = sock_net(sk); security_sk_classify_flow(sk, &fl); - err = ip_route_output_flow(net, &rt, &fl, sk, true); + err = ip_route_output_flow(net, &rt, &fl, sk); if (err) { if (err == -ENETUNREACH) IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 7744a8e4b4c6..5381cebe516d 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -489,7 +489,7 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m * itself out. */ security_sk_classify_flow(sk, &fl); - if (ip_route_output_flow(sock_net(sk), &rt, &fl, sk, false)) + if (ip_route_output_flow(sock_net(sk), &rt, &fl, sk)) goto no_route; } sk_setup_caps(sk, &rt->dst); -- cgit v1.2.3 From 5edc341313a188d94cde7ef87ac31647cea8601a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 25 Jan 2011 22:08:05 +0100 Subject: drivers: remove extraneous includes of smp_lock.h These were missed the last time I cleaned this up globally, because of code moving around or new code getting merged. Signed-off-by: Arnd Bergmann --- drivers/scsi/megaraid/megaraid_sas_fp.c | 1 - drivers/scsi/megaraid/megaraid_sas_fusion.c | 1 - drivers/staging/easycap/easycap_ioctl.c | 1 - drivers/target/target_core_device.c | 1 - drivers/target/target_core_fabric_lib.c | 1 - drivers/target/target_core_file.c | 1 - drivers/target/target_core_hba.c | 1 - drivers/target/target_core_iblock.c | 1 - drivers/target/target_core_pscsi.c | 1 - drivers/target/target_core_rd.c | 1 - drivers/target/target_core_tpg.c | 1 - drivers/target/target_core_transport.c | 1 - drivers/tty/n_hdlc.c | 1 - drivers/tty/n_r3964.c | 1 - drivers/tty/pty.c | 1 - drivers/tty/tty_io.c | 1 - drivers/tty/tty_ldisc.c | 2 -- drivers/tty/vt/selection.c | 1 - drivers/tty/vt/vc_screen.c | 1 - drivers/tty/vt/vt.c | 1 - drivers/tty/vt/vt_ioctl.c | 1 - 21 files changed, 22 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index 53fa96ae2b3e..8fe3a45794fc 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index c1e09d5a6196..d6e2a663b165 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 447953a4e80c..c1a0c9c90a6c 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -25,7 +25,6 @@ */ /*****************************************************************************/ -#include #include "easycap.h" #include "easycap_debug.h" #include "easycap_standard.h" diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 5da051a07fa3..350ed401544e 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c index 26285644e4de..a3c695adabec 100644 --- a/drivers/target/target_core_fabric_lib.c +++ b/drivers/target/target_core_fabric_lib.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 0aaca885668f..190ca8ac2498 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include diff --git a/drivers/target/target_core_hba.c b/drivers/target/target_core_hba.c index 4bbe8208b241..73f7d6d81b4c 100644 --- a/drivers/target/target_core_hba.c +++ b/drivers/target/target_core_hba.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 67f0c09983c8..3df570db0e4f 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index f2a08477a68c..5a9d2ba4b609 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index 979aebf20019..8dc6d74c1d40 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index c26f67467623..5ec745fed931 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 236e22d8cfae..121445f21c71 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index 52fc0c9a6364..cea56033b34c 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -97,7 +97,6 @@ #include #include #include -#include #include /* used in new tty drivers */ #include /* used in new tty drivers */ #include diff --git a/drivers/tty/n_r3964.c b/drivers/tty/n_r3964.c index 88dda0c45ee0..5c6c31459a2f 100644 --- a/drivers/tty/n_r3964.c +++ b/drivers/tty/n_r3964.c @@ -57,7 +57,6 @@ #include #include #include -#include #include #include #include /* used in new tty drivers */ diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 923a48585501..2310cb7282ff 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 0065da4b11c1..cf73d5bd0dce 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -90,7 +90,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 4214d58276f7..70808adae334 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -34,8 +34,6 @@ #include #include -#include /* For the moment */ - #include #include diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index c956ed6c83a3..adf0ad2a8851 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c @@ -26,7 +26,6 @@ #include #include #include -#include /* Don't take this from : 011-015 on the screen aren't spaces */ #define isspace(c) ((c) == ' ') diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index a672ed192d33..95e05dfc437c 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 147ede3423df..2178efcec1b5 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -89,7 +89,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 1235ebda6e1c..fd4c9376f875 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3 From 6927faf30920b8c03dfa007e732642a1f1f20089 Mon Sep 17 00:00:00 2001 From: Jan Niehusmann Date: Tue, 1 Mar 2011 23:24:16 +0100 Subject: drm/i915: fix memory corruption with GM965 and >4GB RAM On a Thinkpad x61s, I noticed some memory corruption when plugging/unplugging the external VGA connection. The symptoms are that 4 bytes at the beginning of a page get overwritten by zeroes. The address of the corruption varies when rebooting the machine, but stays constant while it's running (so it's possible to repeatedly write some data and then corrupt it again by plugging the cable). Further investigation revealed that the corrupted address is (dev_priv->status_page_dmah->busaddr & 0xffffffff), ie. the beginning of the hardware status page of the i965 graphics card, cut to 32 bits. So it seems that for some memory access, the hardware uses only 32 bit addressing. If the hardware status page is located >4GB, this corrupts unrelated memory. Signed-off-by: Jan Niehusmann Acked-by: Daniel Vetter Signed-off-by: Chris Wilson Cc: stable@kernel.org --- drivers/gpu/drm/i915/i915_dma.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 17bd766f2081..e33d9be7df3b 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1895,6 +1895,17 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (IS_GEN2(dev)) dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); + /* 965GM sometimes incorrectly writes to hardware status page (HWS) + * using 32bit addressing, overwriting memory if HWS is located + * above 4GB. + * + * The documentation also mentions an issue with undefined + * behaviour if any general state is accessed within a page above 4GB, + * which also needs to be handled carefully. + */ + if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) + dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32)); + mmio_bar = IS_GEN2(dev) ? 1 : 0; dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, 0); if (!dev_priv->regs) { -- cgit v1.2.3 From 8f5bc2abfd4240b1f55425a3d36b6e6c391bc148 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 1 Mar 2011 17:41:10 +0100 Subject: [CPUFREQ] fix BUG on cpufreq policy init failure cpufreq_register_driver sets cpufreq_driver to a structure owned (and placed) in the caller's memory. If cpufreq policy fails in its ->init function, sysdev_driver_register returns nonzero in cpufreq_register_driver. Now, cpufreq_register_driver returns an error without setting cpufreq_driver back to NULL. Usually cpufreq policy modules are unloaded because they propagate the error to the module init function and return that. So a later access to any member of cpufreq_driver causes bugs like: BUG: unable to handle kernel paging request at ffffffffa00270a0 IP: [] cpufreq_cpu_get+0x53/0xe0 PGD 1805067 PUD 1809063 PMD 1c3f90067 PTE 0 Oops: 0000 [#1] SMP last sysfs file: /sys/devices/virtual/net/tun0/statistics/collisions CPU 0 Modules linked in: ... Pid: 5677, comm: thunderbird-bin Tainted: G W 2.6.38-rc4-mm1_64+ #1389 To be filled by O.E.M./To Be Filled By O.E.M. RIP: 0010:[] [] cpufreq_cpu_get+0x53/0xe0 RSP: 0018:ffff8801aec37d98 EFLAGS: 00010086 RAX: 0000000000000202 RBX: 0000000000000000 RCX: 0000000000000001 RDX: ffffffffa00270a0 RSI: 0000000000001000 RDI: ffffffff8199ece8 ... Call Trace: [] cpufreq_quick_get+0x10/0x30 [] show_cpuinfo+0x2ab/0x300 [] seq_read+0xf2/0x3f0 [] ? __strncpy_from_user+0x33/0x60 [] proc_reg_read+0x6d/0xa0 [] vfs_read+0xc3/0x180 [] sys_read+0x4c/0x90 [] system_call_fastpath+0x16/0x1b ... It's all cause by weird fail path handling in cpufreq_register_driver. To fix that, shuffle the code to do proper handling with gotos. Signed-off-by: Jiri Slaby Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 1109f6848a43..5cb4d09919d6 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1919,8 +1919,10 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) ret = sysdev_driver_register(&cpu_sysdev_class, &cpufreq_sysdev_driver); + if (ret) + goto err_null_driver; - if ((!ret) && !(cpufreq_driver->flags & CPUFREQ_STICKY)) { + if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) { int i; ret = -ENODEV; @@ -1935,21 +1937,22 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) if (ret) { dprintk("no CPU initialized for driver %s\n", driver_data->name); - sysdev_driver_unregister(&cpu_sysdev_class, - &cpufreq_sysdev_driver); - - spin_lock_irqsave(&cpufreq_driver_lock, flags); - cpufreq_driver = NULL; - spin_unlock_irqrestore(&cpufreq_driver_lock, flags); + goto err_sysdev_unreg; } } - if (!ret) { - register_hotcpu_notifier(&cpufreq_cpu_notifier); - dprintk("driver %s up and running\n", driver_data->name); - cpufreq_debug_enable_ratelimit(); - } + register_hotcpu_notifier(&cpufreq_cpu_notifier); + dprintk("driver %s up and running\n", driver_data->name); + cpufreq_debug_enable_ratelimit(); + return 0; +err_sysdev_unreg: + sysdev_driver_unregister(&cpu_sysdev_class, + &cpufreq_sysdev_driver); +err_null_driver: + spin_lock_irqsave(&cpufreq_driver_lock, flags); + cpufreq_driver = NULL; + spin_unlock_irqrestore(&cpufreq_driver_lock, flags); return ret; } EXPORT_SYMBOL_GPL(cpufreq_register_driver); -- cgit v1.2.3 From eb0e85e36b971ec31610eda7e3ff5c11c1c44785 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 24 Feb 2011 19:30:37 +0100 Subject: libata: fix hotplug for drivers which don't implement LPM ata_eh_analyze_serror() suppresses hotplug notifications if LPM is being used because LPM generates spurious hotplug events. It compared whether link->lpm_policy was different from ATA_LPM_MAX_POWER to determine whether LPM is enabled; however, this is incorrect as for drivers which don't implement LPM, lpm_policy is always ATA_LPM_UNKNOWN. This disabled hotplug detection for all drivers which don't implement LPM. Fix it by comparing whether lpm_policy is greater than ATA_LPM_MAX_POWER. Signed-off-by: Tejun Heo Cc: stable@kernel.org Signed-off-by: Jeff Garzik --- drivers/ata/libata-eh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 17a637877d03..e16850e8d2f8 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1618,7 +1618,7 @@ static void ata_eh_analyze_serror(struct ata_link *link) * host links. For disabled PMP links, only N bit is * considered as X bit is left at 1 for link plugging. */ - if (link->lpm_policy != ATA_LPM_MAX_POWER) + if (link->lpm_policy > ATA_LPM_MAX_POWER) hotplug_mask = 0; /* hotplug doesn't work w/ LPM */ else if (!(link->flags & ATA_LFLAG_DISABLED) || ata_is_host_link(link)) hotplug_mask = SERR_PHYRDY_CHG | SERR_DEV_XCHG; -- cgit v1.2.3 From 238c9cf9ea88bbbb9fd0f60c2cc9511c10b4585c Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 23 Jan 2011 08:28:33 -0600 Subject: libata: plumb sas port scan into standard libata paths The function ata_sas_port_init() has always really done its own thing. However, as a precursor to moving to the libata new eh, it has to be properly using the standard libata scan paths. This means separating the current libata scan paths into pieces which can be shared with libsas and pieces which cant (really just the async call and the host scan). Signed-off-by: James Bottomley Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 46 ++++++++++++++++++++++------------------------ drivers/ata/libata-scsi.c | 2 +- drivers/ata/libata.h | 1 + 3 files changed, 24 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index d4e52e214859..7d3c71a3750a 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5887,21 +5887,9 @@ void ata_host_init(struct ata_host *host, struct device *dev, host->ops = ops; } - -static void async_port_probe(void *data, async_cookie_t cookie) +int ata_port_probe(struct ata_port *ap) { - int rc; - struct ata_port *ap = data; - - /* - * If we're not allowed to scan this host in parallel, - * we need to wait until all previous scans have completed - * before going further. - * Jeff Garzik says this is only within a controller, so we - * don't need to wait for port 0, only for later ports. - */ - if (!(ap->host->flags & ATA_HOST_PARALLEL_SCAN) && ap->port_no != 0) - async_synchronize_cookie(cookie); + int rc = 0; /* probe */ if (ap->ops->error_handler) { @@ -5927,23 +5915,33 @@ static void async_port_probe(void *data, async_cookie_t cookie) DPRINTK("ata%u: bus probe begin\n", ap->print_id); rc = ata_bus_probe(ap); DPRINTK("ata%u: bus probe end\n", ap->print_id); - - if (rc) { - /* FIXME: do something useful here? - * Current libata behavior will - * tear down everything when - * the module is removed - * or the h/w is unplugged. - */ - } } + return rc; +} + + +static void async_port_probe(void *data, async_cookie_t cookie) +{ + struct ata_port *ap = data; + + /* + * If we're not allowed to scan this host in parallel, + * we need to wait until all previous scans have completed + * before going further. + * Jeff Garzik says this is only within a controller, so we + * don't need to wait for port 0, only for later ports. + */ + if (!(ap->host->flags & ATA_HOST_PARALLEL_SCAN) && ap->port_no != 0) + async_synchronize_cookie(cookie); + + (void)ata_port_probe(ap); /* in order to keep device order, we need to synchronize at this point */ async_synchronize_cookie(cookie); ata_scsi_scan_host(ap, 1); - } + /** * ata_host_register - register initialized ATA host * @host: ATA host to register diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 600f6353ecf8..e6ce765534ac 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3821,7 +3821,7 @@ int ata_sas_port_init(struct ata_port *ap) if (!rc) { ap->print_id = ata_print_id++; - rc = ata_bus_probe(ap); + rc = ata_port_probe(ap); } return rc; diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index a9be110dbf51..773de97988a2 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -103,6 +103,7 @@ extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg); extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); extern struct ata_port *ata_port_alloc(struct ata_host *host); extern const char *sata_spd_string(unsigned int spd); +extern int ata_port_probe(struct ata_port *ap); /* libata-acpi.c */ #ifdef CONFIG_ATA_ACPI -- cgit v1.2.3 From a29b5dad46ee4168c8fc18e47dabbde49790527b Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 23 Jan 2011 08:30:00 -0600 Subject: libata: fix locking for sas paths For historical reasons, libsas uses the scsi host lock as the ata port lock, and libata always uses the ata host. For the old eh, this was largely irrelevant since the two locks were never mixed inside the code. However, the new eh has a case where it nests acquisition of the host lock inside the port lock (this does look rather deadlock prone). Obviously this would be an instant deadlock if the port lock were the host lock, so switch the libsas paths to use the ata host lock as well. Signed-off-by: James Bottomley Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index e6ce765534ac..c11675f34b93 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3759,7 +3759,7 @@ struct ata_port *ata_sas_port_alloc(struct ata_host *host, return NULL; ap->port_no = 0; - ap->lock = shost->host_lock; + ap->lock = &host->lock; ap->pio_mask = port_info->pio_mask; ap->mwdma_mask = port_info->mwdma_mask; ap->udma_mask = port_info->udma_mask; -- cgit v1.2.3 From c34aeebc06e8bdde93e8c8f40d9903b1aaab63c6 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 23 Jan 2011 08:31:14 -0600 Subject: libata: fix eh locking The SCSI host eh_cmd_q should be protected by the host lock (not the port lock). This probably doesn't matter that much at the moment, since we try to serialise the add and eh pieces, but it might matter in future for more convenient error handling. Plus this switches libata to the standard eh pattern where you lock, remove from the cmd queue to a local list and unlock and then operate on the local list. Signed-off-by: James Bottomley Signed-off-by: Jeff Garzik --- drivers/ata/libata-eh.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index e16850e8d2f8..073b88156b3c 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -589,9 +589,14 @@ void ata_scsi_error(struct Scsi_Host *host) struct ata_port *ap = ata_shost_to_port(host); int i; unsigned long flags; + LIST_HEAD(eh_work_q); DPRINTK("ENTER\n"); + spin_lock_irqsave(host->host_lock, flags); + list_splice_init(&host->eh_cmd_q, &eh_work_q); + spin_unlock_irqrestore(host->host_lock, flags); + /* make sure sff pio task is not running */ ata_sff_flush_pio_task(ap); @@ -627,7 +632,7 @@ void ata_scsi_error(struct Scsi_Host *host) if (ap->ops->lost_interrupt) ap->ops->lost_interrupt(ap); - list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) { + list_for_each_entry_safe(scmd, tmp, &eh_work_q, eh_entry) { struct ata_queued_cmd *qc; for (i = 0; i < ATA_MAX_QUEUE; i++) { @@ -762,7 +767,7 @@ void ata_scsi_error(struct Scsi_Host *host) } /* finish or retry handled scmd's and clean up */ - WARN_ON(host->host_failed || !list_empty(&host->eh_cmd_q)); + WARN_ON(host->host_failed || !list_empty(&eh_work_q)); scsi_eh_flush_done_q(&ap->eh_done_q); -- cgit v1.2.3 From 0e0b494ca8c54a7297d0cc549405091019b3b77e Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 23 Jan 2011 09:42:50 -0600 Subject: libata: separate error handler into usable components Right at the moment, the libata error handler is incredibly monolithic. This makes it impossible to use from composite drivers like libsas and ipr which have to handle error themselves in the first instance. The essence of the change is to split the monolithic error handler into two components: one which handles a queue of ata commands for processing and the other which handles the back end of readying a port. This allows the upper error handler fine grained control in calling libsas functions (and making sure they only get called for ATA commands whose lower errors have been fixed up). Signed-off-by: James Bottomley Signed-off-by: Jeff Garzik --- drivers/ata/libata-eh.c | 53 ++++++++++++++++++++++++++++++++++++++++--------- include/linux/libata.h | 2 ++ 2 files changed, 46 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 073b88156b3c..df3f3140c9c7 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -587,7 +587,6 @@ static void ata_eh_unload(struct ata_port *ap) void ata_scsi_error(struct Scsi_Host *host) { struct ata_port *ap = ata_shost_to_port(host); - int i; unsigned long flags; LIST_HEAD(eh_work_q); @@ -597,6 +596,34 @@ void ata_scsi_error(struct Scsi_Host *host) list_splice_init(&host->eh_cmd_q, &eh_work_q); spin_unlock_irqrestore(host->host_lock, flags); + ata_scsi_cmd_error_handler(host, ap, &eh_work_q); + + /* If we timed raced normal completion and there is nothing to + recover nr_timedout == 0 why exactly are we doing error recovery ? */ + ata_scsi_port_error_handler(host, ap); + + /* finish or retry handled scmd's and clean up */ + WARN_ON(host->host_failed || !list_empty(&eh_work_q)); + + DPRINTK("EXIT\n"); +} + +/** + * ata_scsi_cmd_error_handler - error callback for a list of commands + * @host: scsi host containing the port + * @ap: ATA port within the host + * @eh_work_q: list of commands to process + * + * process the given list of commands and return those finished to the + * ap->eh_done_q. This function is the first part of the libata error + * handler which processes a given list of failed commands. + */ +void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, + struct list_head *eh_work_q) +{ + int i; + unsigned long flags; + /* make sure sff pio task is not running */ ata_sff_flush_pio_task(ap); @@ -632,7 +659,7 @@ void ata_scsi_error(struct Scsi_Host *host) if (ap->ops->lost_interrupt) ap->ops->lost_interrupt(ap); - list_for_each_entry_safe(scmd, tmp, &eh_work_q, eh_entry) { + list_for_each_entry_safe(scmd, tmp, eh_work_q, eh_entry) { struct ata_queued_cmd *qc; for (i = 0; i < ATA_MAX_QUEUE; i++) { @@ -676,8 +703,20 @@ void ata_scsi_error(struct Scsi_Host *host) } else spin_unlock_wait(ap->lock); - /* If we timed raced normal completion and there is nothing to - recover nr_timedout == 0 why exactly are we doing error recovery ? */ +} +EXPORT_SYMBOL(ata_scsi_cmd_error_handler); + +/** + * ata_scsi_port_error_handler - recover the port after the commands + * @host: SCSI host containing the port + * @ap: the ATA port + * + * Handle the recovery of the port @ap after all the commands + * have been recovered. + */ +void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap) +{ + unsigned long flags; /* invoke error handler */ if (ap->ops->error_handler) { @@ -766,9 +805,6 @@ void ata_scsi_error(struct Scsi_Host *host) ap->ops->eng_timeout(ap); } - /* finish or retry handled scmd's and clean up */ - WARN_ON(host->host_failed || !list_empty(&eh_work_q)); - scsi_eh_flush_done_q(&ap->eh_done_q); /* clean up */ @@ -789,9 +825,8 @@ void ata_scsi_error(struct Scsi_Host *host) wake_up_all(&ap->eh_wait_q); spin_unlock_irqrestore(ap->lock, flags); - - DPRINTK("EXIT\n"); } +EXPORT_SYMBOL_GPL(ata_scsi_port_error_handler); /** * ata_port_wait_eh - Wait for the currently pending EH to complete diff --git a/include/linux/libata.h b/include/linux/libata.h index c9c5d7ad1a2b..9739317c707a 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1050,6 +1050,8 @@ extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth, int reason); extern struct ata_device *ata_dev_pair(struct ata_device *adev); extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev); +extern void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap); +extern void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, struct list_head *eh_q); extern int ata_cable_40wire(struct ata_port *ap); extern int ata_cable_80wire(struct ata_port *ap); -- cgit v1.2.3 From 00dd4998a60599d98b4d6635820a1fbeafa5b021 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 23 Jan 2011 09:44:12 -0600 Subject: libsas: convert to libata new error handler The conversion is quite complex given that the libata new error handler has to be hooked into the current libsas timeout and error handling. The way this is done is to process all the failed commands via libsas first, but if they have no underlying sas task (and they're on a sata device) assume they are destined for the libata error handler and send them accordingly. Finally, activate the port recovery of the libata error handler for each port known to the host. This is somewhat suboptimal, since that port may not need recovering, but given the current architecture of the libata error handler, it's the only way; and the spurious activation is harmless. Signed-off-by: James Bottomley Signed-off-by: Jeff Garzik --- drivers/scsi/libsas/sas_ata.c | 87 ++++++++++++++++++++++++++++++++++--- drivers/scsi/libsas/sas_scsi_host.c | 14 +++++- include/scsi/sas_ata.h | 22 ++++++++++ 3 files changed, 115 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index e1a395b438ee..8f56d5fbf6ec 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -238,37 +238,43 @@ static bool sas_ata_qc_fill_rtf(struct ata_queued_cmd *qc) return true; } -static void sas_ata_phy_reset(struct ata_port *ap) +static int sas_ata_hard_reset(struct ata_link *link, unsigned int *class, + unsigned long deadline) { + struct ata_port *ap = link->ap; struct domain_device *dev = ap->private_data; struct sas_internal *i = to_sas_internal(dev->port->ha->core.shost->transportt); int res = TMF_RESP_FUNC_FAILED; + int ret = 0; if (i->dft->lldd_I_T_nexus_reset) res = i->dft->lldd_I_T_nexus_reset(dev); - if (res != TMF_RESP_FUNC_COMPLETE) + if (res != TMF_RESP_FUNC_COMPLETE) { SAS_DPRINTK("%s: Unable to reset I T nexus?\n", __func__); + ret = -EAGAIN; + } switch (dev->sata_dev.command_set) { case ATA_COMMAND_SET: SAS_DPRINTK("%s: Found ATA device.\n", __func__); - ap->link.device[0].class = ATA_DEV_ATA; + *class = ATA_DEV_ATA; break; case ATAPI_COMMAND_SET: SAS_DPRINTK("%s: Found ATAPI device.\n", __func__); - ap->link.device[0].class = ATA_DEV_ATAPI; + *class = ATA_DEV_ATAPI; break; default: SAS_DPRINTK("%s: Unknown SATA command set: %d.\n", __func__, dev->sata_dev.command_set); - ap->link.device[0].class = ATA_DEV_UNKNOWN; + *class = ATA_DEV_UNKNOWN; break; } ap->cbl = ATA_CBL_SATA; + return ret; } static void sas_ata_post_internal(struct ata_queued_cmd *qc) @@ -349,7 +355,11 @@ static int sas_ata_scr_read(struct ata_link *link, unsigned int sc_reg_in, } static struct ata_port_operations sas_sata_ops = { - .phy_reset = sas_ata_phy_reset, + .prereset = ata_std_prereset, + .softreset = NULL, + .hardreset = sas_ata_hard_reset, + .postreset = ata_std_postreset, + .error_handler = ata_std_error_handler, .post_internal_cmd = sas_ata_post_internal, .qc_defer = ata_std_qc_defer, .qc_prep = ata_noop_qc_prep, @@ -781,3 +791,68 @@ int sas_discover_sata(struct domain_device *dev) return res; } + +void sas_ata_strategy_handler(struct Scsi_Host *shost) +{ + struct scsi_device *sdev; + + shost_for_each_device(sdev, shost) { + struct domain_device *ddev = sdev_to_domain_dev(sdev); + struct ata_port *ap = ddev->sata_dev.ap; + + if (!dev_is_sata(ddev)) + continue; + + ata_port_printk(ap, KERN_DEBUG, "sas eh calling libata port error handler"); + ata_scsi_port_error_handler(shost, ap); + } +} + +int sas_ata_timed_out(struct scsi_cmnd *cmd, struct sas_task *task, + enum blk_eh_timer_return *rtn) +{ + struct domain_device *ddev = cmd_to_domain_dev(cmd); + + if (!dev_is_sata(ddev) || task) + return 0; + + /* we're a sata device with no task, so this must be a libata + * eh timeout. Ideally should hook into libata timeout + * handling, but there's no point, it just wants to activate + * the eh thread */ + *rtn = BLK_EH_NOT_HANDLED; + return 1; +} + +int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, + struct list_head *done_q) +{ + int rtn = 0; + struct scsi_cmnd *cmd, *n; + struct ata_port *ap; + + do { + LIST_HEAD(sata_q); + + ap = NULL; + + list_for_each_entry_safe(cmd, n, work_q, eh_entry) { + struct domain_device *ddev = cmd_to_domain_dev(cmd); + + if (!dev_is_sata(ddev) || TO_SAS_TASK(cmd)) + continue; + if(ap && ap != ddev->sata_dev.ap) + continue; + ap = ddev->sata_dev.ap; + rtn = 1; + list_move(&cmd->eh_entry, &sata_q); + } + + if (!list_empty(&sata_q)) { + ata_port_printk(ap, KERN_DEBUG,"sas eh calling libata cmd error handler\n"); + ata_scsi_cmd_error_handler(shost, ap, &sata_q); + } + } while (ap); + + return rtn; +} diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 9a7aaf5f1311..67758ea8eb7f 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -663,11 +663,16 @@ void sas_scsi_recover_host(struct Scsi_Host *shost) * scsi_unjam_host does, but we skip scsi_eh_abort_cmds because any * command we see here has no sas_task and is thus unknown to the HA. */ - if (!scsi_eh_get_sense(&eh_work_q, &ha->eh_done_q)) - scsi_eh_ready_devs(shost, &eh_work_q, &ha->eh_done_q); + if (!sas_ata_eh(shost, &eh_work_q, &ha->eh_done_q)) + if (!scsi_eh_get_sense(&eh_work_q, &ha->eh_done_q)) + scsi_eh_ready_devs(shost, &eh_work_q, &ha->eh_done_q); out: + /* now link into libata eh --- if we have any ata devices */ + sas_ata_strategy_handler(shost); + scsi_eh_flush_done_q(&ha->eh_done_q); + SAS_DPRINTK("--- Exit %s\n", __func__); return; } @@ -676,6 +681,11 @@ enum blk_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd) { struct sas_task *task = TO_SAS_TASK(cmd); unsigned long flags; + enum blk_eh_timer_return rtn; + + if (sas_ata_timed_out(cmd, task, &rtn)) + return rtn; + if (!task) { cmd->request->timeout /= 2; diff --git a/include/scsi/sas_ata.h b/include/scsi/sas_ata.h index c583193ae929..9c159f74c6d0 100644 --- a/include/scsi/sas_ata.h +++ b/include/scsi/sas_ata.h @@ -39,6 +39,11 @@ int sas_ata_init_host_and_port(struct domain_device *found_dev, struct scsi_target *starget); void sas_ata_task_abort(struct sas_task *task); +void sas_ata_strategy_handler(struct Scsi_Host *shost); +int sas_ata_timed_out(struct scsi_cmnd *cmd, struct sas_task *task, + enum blk_eh_timer_return *rtn); +int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, + struct list_head *done_q); #else @@ -55,6 +60,23 @@ static inline int sas_ata_init_host_and_port(struct domain_device *found_dev, static inline void sas_ata_task_abort(struct sas_task *task) { } + +static inline void sas_ata_strategy_handler(struct Scsi_Host *shost) +{ +} + +static inline int sas_ata_timed_out(struct scsi_cmnd *cmd, + struct sas_task *task, + enum blk_eh_timer_return *rtn) +{ + return 0; +} +static inline int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, + struct list_head *done_q) +{ + return 0; +} + #endif #endif /* _SAS_ATA_H_ */ -- cgit v1.2.3 From 4fca377f7488095ab04035e2bfe5c59873c22382 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 15 Feb 2011 01:13:24 -0500 Subject: [libata] trivial: trim trailing whitespace for drivers/ata/*.[ch] --- drivers/ata/ata_generic.c | 2 +- drivers/ata/ata_piix.c | 2 +- drivers/ata/libata-core.c | 10 +++++----- drivers/ata/libata-sff.c | 2 +- drivers/ata/pata_hpt3x3.c | 2 +- drivers/ata/pata_it821x.c | 4 ++-- drivers/ata/pata_marvell.c | 2 +- drivers/ata/pata_ninja32.c | 2 +- drivers/ata/pata_pcmcia.c | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index 6981f7680a00..721d38bfa339 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c @@ -237,7 +237,7 @@ static struct pci_device_id ata_generic[] = { #endif /* Intel, IDE class device */ { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, - PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, + PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, .driver_data = ATA_GEN_INTEL_IDER }, /* Must come last. If you add entries adjust this table appropriately */ { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL), diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 6cb14ca8ee85..cdec4ab3b159 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -230,7 +230,7 @@ static const struct pci_device_id piix_pci_tbl[] = { { 0x8086, 0x2850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, /* SATA ports */ - + /* 82801EB (ICH5) */ { 0x8086, 0x24d1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata }, /* 82801EB (ICH5) */ diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 7d3c71a3750a..b91e19cab102 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4210,7 +4210,7 @@ static int glob_match (const char *text, const char *pattern) return 0; /* End of both strings: match */ return 1; /* No match */ } - + static unsigned long ata_dev_blacklisted(const struct ata_device *dev) { unsigned char model_num[ATA_ID_PROD_LEN + 1]; @@ -5479,7 +5479,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host) ap = kzalloc(sizeof(*ap), GFP_KERNEL); if (!ap) return NULL; - + ap->pflags |= ATA_PFLAG_INITIALIZING; ap->lock = &host->lock; ap->print_id = -1; @@ -5923,7 +5923,7 @@ int ata_port_probe(struct ata_port *ap) static void async_port_probe(void *data, async_cookie_t cookie) { struct ata_port *ap = data; - + /* * If we're not allowed to scan this host in parallel, * we need to wait until all previous scans have completed @@ -5981,7 +5981,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) for (i = 0; i < host->n_ports; i++) host->ports[i]->print_id = ata_print_id++; - + /* Create associated sysfs transport objects */ for (i = 0; i < host->n_ports; i++) { rc = ata_tport_add(host->dev,host->ports[i]); @@ -6469,7 +6469,7 @@ static int __init ata_init(void) ata_sff_exit(); rc = -ENOMEM; goto err_out; - } + } printk(KERN_DEBUG "libata version " DRV_VERSION " loaded.\n"); return 0; diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index af6141bb1ba3..e75a02d61a8f 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -1336,7 +1336,7 @@ static void ata_sff_pio_task(struct work_struct *work) u8 status; int poll_next; - BUG_ON(ap->sff_pio_task_link == NULL); + BUG_ON(ap->sff_pio_task_link == NULL); /* qc can be NULL if timeout occurred */ qc = ata_qc_from_tag(ap, link->active_tag); if (!qc) { diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c index b63d5e2d4628..24d7df81546b 100644 --- a/drivers/ata/pata_hpt3x3.c +++ b/drivers/ata/pata_hpt3x3.c @@ -151,7 +151,7 @@ static struct ata_port_operations hpt3x3_port_ops = { .check_atapi_dma= hpt3x3_atapi_dma, .freeze = hpt3x3_freeze, #endif - + }; /** diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index aa0e0c51cc08..2d15f2548a10 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -616,7 +616,7 @@ static void it821x_display_disk(int n, u8 *buf) if (buf[52] > 4) /* No Disk */ return; - ata_id_c_string((u16 *)buf, id, 0, 41); + ata_id_c_string((u16 *)buf, id, 0, 41); if (buf[51]) { mode = ffs(buf[51]); @@ -910,7 +910,7 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) rc = pcim_enable_device(pdev); if (rc) return rc; - + if (pdev->vendor == PCI_VENDOR_ID_RDC) { /* Deal with Vortex86SX */ if (pdev->revision == 0x11) diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c index dd38083dcbeb..75a6a0c0094f 100644 --- a/drivers/ata/pata_marvell.c +++ b/drivers/ata/pata_marvell.c @@ -38,7 +38,7 @@ static int marvell_pata_active(struct pci_dev *pdev) /* We don't yet know how to do this for other devices */ if (pdev->device != 0x6145) - return 1; + return 1; barp = pci_iomap(pdev, 5, 0x10); if (barp == NULL) diff --git a/drivers/ata/pata_ninja32.c b/drivers/ata/pata_ninja32.c index cc50bd09aa26..e277a142138c 100644 --- a/drivers/ata/pata_ninja32.c +++ b/drivers/ata/pata_ninja32.c @@ -165,7 +165,7 @@ static int ninja32_reinit_one(struct pci_dev *pdev) return rc; ninja32_program(host->iomap[0]); ata_host_resume(host); - return 0; + return 0; } #endif diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 806292160b3f..29af660d968b 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c @@ -124,7 +124,7 @@ static unsigned int ata_data_xfer_8bit(struct ata_device *dev, * reset will recover the device. * */ - + static void pcmcia_8bit_drain_fifo(struct ata_queued_cmd *qc) { int count; -- cgit v1.2.3 From b83a4c397952a0c05b5468c0403a32e87bb35fef Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Tue, 25 Jan 2011 19:27:35 +0300 Subject: sata_dwc_460ex: use ATA_PIO4 Somehow the driver was committed with a bare number for the PIO mask, instead of ATA_PIO4... Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/sata_dwc_460ex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index 6cf57c5c2b5f..d5d01254c210 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c @@ -1582,7 +1582,7 @@ static const struct ata_port_info sata_dwc_port_info[] = { { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | ATA_FLAG_NCQ, - .pio_mask = 0x1f, /* pio 0-4 */ + .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, .port_ops = &sata_dwc_ops, }, -- cgit v1.2.3 From c211962dc12d609effbf00a2c5c6fc38cc1dbc54 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 28 Jan 2011 21:55:55 +0300 Subject: sata_dwc_460ex: fix compilation errors/warnings Fix the following compilation errors/warnings: drivers/ata/sata_dwc_460ex.c:43:1: warning: "DRV_NAME" redefined In file included from drivers/ata/sata_dwc_460ex.c:38: drivers/ata/libata.h:31:1: warning: this is the location of the previous definition drivers/ata/sata_dwc_460ex.c:44:1: warning: "DRV_VERSION" redefined drivers/ata/libata.h:32:1: warning: this is the location of the previous definition drivers/ata/sata_dwc_460ex.c: In function `sata_dwc_exec_command_by_tag': drivers/ata/sata_dwc_460ex.c:1356: warning: passing argument 1 of `ata_get_cmd_descript' makes integer from pointer without a cast drivers/ata/sata_dwc_460ex.c: In function `sata_dwc_qc_issue': drivers/ata/sata_dwc_460ex.c:1476: warning: `err' is used uninitialized in this function drivers/ata/sata_dwc_460ex.c:1465: note: `err' was declared here drivers/ata/sata_dwc_460ex.c: In function `sata_dwc_qc_issue': drivers/ata/sata_dwc_460ex.c:1493: warning: passing argument 1 of `ata_get_cmd_descript' makes integer from pointer without a cast drivers/ata/sata_dwc_460ex.c: In function `sata_dwc_qc_prep': drivers/ata/sata_dwc_460ex.c:1537: error: `tag' undeclared (first use in this function) drivers/ata/sata_dwc_460ex.c:1537: error: (Each undeclared identifier is reported only once drivers/ata/sata_dwc_460ex.c:1537: error: for each function it appears in.) NB: error only happens if DEBUG_NCQ macro is defined... Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/sata_dwc_460ex.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index d5d01254c210..9d78f9b78f41 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c @@ -40,8 +40,11 @@ #include #include +/* These two are defined in "libata.h" */ +#undef DRV_NAME +#undef DRV_VERSION #define DRV_NAME "sata-dwc" -#define DRV_VERSION "1.0" +#define DRV_VERSION "1.1" /* SATA DMA driver Globals */ #define DMA_NUM_CHANS 1 @@ -1354,7 +1357,7 @@ static void sata_dwc_exec_command_by_tag(struct ata_port *ap, struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); dev_dbg(ap->dev, "%s cmd(0x%02x): %s tag=%d\n", __func__, tf->command, - ata_get_cmd_descript(tf), tag); + ata_get_cmd_descript(tf->command), tag); spin_lock_irqsave(&ap->host->lock, flags); hsdevp->cmd_issued[tag] = cmd_issued; @@ -1462,7 +1465,6 @@ static void sata_dwc_qc_prep_by_tag(struct ata_queued_cmd *qc, u8 tag) int dma_chan; struct sata_dwc_device *hsdev = HSDEV_FROM_AP(ap); struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); - int err; dev_dbg(ap->dev, "%s: port=%d dma dir=%s n_elem=%d\n", __func__, ap->port_no, ata_get_cmd_descript(qc->dma_dir), @@ -1474,7 +1476,7 @@ static void sata_dwc_qc_prep_by_tag(struct ata_queued_cmd *qc, u8 tag) dmadr), qc->dma_dir); if (dma_chan < 0) { dev_err(ap->dev, "%s: dma_dwc_xfer_setup returns err %d\n", - __func__, err); + __func__, dma_chan); return; } hsdevp->dma_chan[tag] = dma_chan; @@ -1491,7 +1493,7 @@ static unsigned int sata_dwc_qc_issue(struct ata_queued_cmd *qc) dev_info(ap->dev, "%s ap id=%d cmd(0x%02x)=%s qc tag=%d " "prot=%s ap active_tag=0x%08x ap sactive=0x%08x\n", __func__, ap->print_id, qc->tf.command, - ata_get_cmd_descript(&qc->tf), + ata_get_cmd_descript(qc->tf.command), qc->tag, ata_get_cmd_descript(qc->tf.protocol), ap->link.active_tag, ap->link.sactive); #endif @@ -1533,7 +1535,7 @@ static void sata_dwc_qc_prep(struct ata_queued_cmd *qc) #ifdef DEBUG_NCQ if (qc->tag > 0) dev_info(qc->ap->dev, "%s: qc->tag=%d ap->active_tag=0x%08x\n", - __func__, tag, qc->ap->link.active_tag); + __func__, qc->tag, qc->ap->link.active_tag); return ; #endif -- cgit v1.2.3 From d285e8bfe9d1a196e26b798cc04f8c5ebc60c856 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 28 Jan 2011 21:58:54 +0300 Subject: sata_dwc_460ex: fix return value of dma_dwc_xfer_setup() The caller expects this function to return the DMA channel number on success, while it returns 0... Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/sata_dwc_460ex.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index 9d78f9b78f41..34fc1372d72d 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c @@ -44,7 +44,7 @@ #undef DRV_NAME #undef DRV_VERSION #define DRV_NAME "sata-dwc" -#define DRV_VERSION "1.1" +#define DRV_VERSION "1.2" /* SATA DMA driver Globals */ #define DMA_NUM_CHANS 1 @@ -718,7 +718,7 @@ static int dma_dwc_xfer_setup(struct scatterlist *sg, int num_elems, /* Program the CTL register with src enable / dst enable */ out_le32(&(host_pvt.sata_dma_regs->chan_regs[dma_ch].ctl.low), DMA_CTL_LLP_SRCEN | DMA_CTL_LLP_DSTEN); - return 0; + return dma_ch; } /* -- cgit v1.2.3 From 84b47e3b16f8a5bb416cd55774d679ebbdb19072 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 28 Jan 2011 22:01:01 +0300 Subject: sata_dwc_460ex: fix misuse of ata_get_cmd_descript() The driver erroneously uses ata_get_cmd_descript() not only for printing out the ATA commands but also the protocol and DMA direction enums. Add functions for properly printing those out... Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/sata_dwc_460ex.c | 56 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index 34fc1372d72d..843af13606e1 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c @@ -44,7 +44,7 @@ #undef DRV_NAME #undef DRV_VERSION #define DRV_NAME "sata-dwc" -#define DRV_VERSION "1.2" +#define DRV_VERSION "1.3" /* SATA DMA driver Globals */ #define DMA_NUM_CHANS 1 @@ -336,11 +336,47 @@ static int dma_dwc_xfer_setup(struct scatterlist *sg, int num_elems, void __iomem *addr, int dir); static void dma_dwc_xfer_start(int dma_ch); +static const char *get_prot_descript(u8 protocol) +{ + switch ((enum ata_tf_protocols)protocol) { + case ATA_PROT_NODATA: + return "ATA no data"; + case ATA_PROT_PIO: + return "ATA PIO"; + case ATA_PROT_DMA: + return "ATA DMA"; + case ATA_PROT_NCQ: + return "ATA NCQ"; + case ATAPI_PROT_NODATA: + return "ATAPI no data"; + case ATAPI_PROT_PIO: + return "ATAPI PIO"; + case ATAPI_PROT_DMA: + return "ATAPI DMA"; + default: + return "unknown"; + } +} + +static const char *get_dma_dir_descript(int dma_dir) +{ + switch ((enum dma_data_direction)dma_dir) { + case DMA_BIDIRECTIONAL: + return "bidirectional"; + case DMA_TO_DEVICE: + return "to device"; + case DMA_FROM_DEVICE: + return "from device"; + default: + return "none"; + } +} + static void sata_dwc_tf_dump(struct ata_taskfile *tf) { dev_vdbg(host_pvt.dwc_dev, "taskfile cmd: 0x%02x protocol: %s flags:" - "0x%lx device: %x\n", tf->command, ata_get_cmd_descript\ - (tf->protocol), tf->flags, tf->device); + "0x%lx device: %x\n", tf->command, + get_prot_descript(tf->protocol), tf->flags, tf->device); dev_vdbg(host_pvt.dwc_dev, "feature: 0x%02x nsect: 0x%x lbal: 0x%x " "lbam: 0x%x lbah: 0x%x\n", tf->feature, tf->nsect, tf->lbal, tf->lbam, tf->lbah); @@ -970,7 +1006,7 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance) } dev_dbg(ap->dev, "%s non-NCQ cmd interrupt, protocol: %s\n", - __func__, ata_get_cmd_descript(qc->tf.protocol)); + __func__, get_prot_descript(qc->tf.protocol)); DRVSTILLBUSY: if (ata_is_dma(qc->tf.protocol)) { /* @@ -1060,7 +1096,7 @@ DRVSTILLBUSY: /* Process completed command */ dev_dbg(ap->dev, "%s NCQ command, protocol: %s\n", __func__, - ata_get_cmd_descript(qc->tf.protocol)); + get_prot_descript(qc->tf.protocol)); if (ata_is_dma(qc->tf.protocol)) { host_pvt.dma_interrupt_count++; if (hsdevp->dma_pending[tag] == \ @@ -1145,8 +1181,8 @@ static void sata_dwc_dma_xfer_complete(struct ata_port *ap, u32 check_status) if (tag > 0) { dev_info(ap->dev, "%s tag=%u cmd=0x%02x dma dir=%s proto=%s " "dmacr=0x%08x\n", __func__, qc->tag, qc->tf.command, - ata_get_cmd_descript(qc->dma_dir), - ata_get_cmd_descript(qc->tf.protocol), + get_dma_dir_descript(qc->dma_dir), + get_prot_descript(qc->tf.protocol), in_le32(&(hsdev->sata_dwc_regs->dmacr))); } #endif @@ -1416,7 +1452,7 @@ static void sata_dwc_bmdma_start_by_tag(struct ata_queued_cmd *qc, u8 tag) dev_dbg(ap->dev, "%s qc=%p tag: %x cmd: 0x%02x dma_dir: %s " "start_dma? %x\n", __func__, qc, tag, qc->tf.command, - ata_get_cmd_descript(qc->dma_dir), start_dma); + get_dma_dir_descript(qc->dma_dir), start_dma); sata_dwc_tf_dump(&(qc->tf)); if (start_dma) { @@ -1467,7 +1503,7 @@ static void sata_dwc_qc_prep_by_tag(struct ata_queued_cmd *qc, u8 tag) struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); dev_dbg(ap->dev, "%s: port=%d dma dir=%s n_elem=%d\n", - __func__, ap->port_no, ata_get_cmd_descript(qc->dma_dir), + __func__, ap->port_no, get_dma_dir_descript(qc->dma_dir), qc->n_elem); dma_chan = dma_dwc_xfer_setup(sg, qc->n_elem, hsdevp->llit[tag], @@ -1494,7 +1530,7 @@ static unsigned int sata_dwc_qc_issue(struct ata_queued_cmd *qc) "prot=%s ap active_tag=0x%08x ap sactive=0x%08x\n", __func__, ap->print_id, qc->tf.command, ata_get_cmd_descript(qc->tf.command), - qc->tag, ata_get_cmd_descript(qc->tf.protocol), + qc->tag, get_prot_descript(qc->tf.protocol), ap->link.active_tag, ap->link.sactive); #endif -- cgit v1.2.3 From 14080fa65516d15bc284c77a5dde31621a61e2bc Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 28 Jan 2011 22:02:09 +0300 Subject: sata_dwc_460ex: add debugging options The driver makes use of the two options (CONFIG_SATA_DWC_[V]DEBUG) to enable the debug output but they both are absent in drivers/ata/Kconfig... Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/Kconfig | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index c2328aed0836..8a1fc396f055 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -202,6 +202,18 @@ config SATA_DWC If unsure, say N. +config SATA_DWC_DEBUG + bool "Debugging driver version" + depends on SATA_DWC + help + This option enables debugging output in the driver. + +config SATA_DWC_VDEBUG + bool "Verbose debug output" + depends on SATA_DWC_DEBUG + help + This option enables the taskfile dumping and NCQ debugging. + config SATA_MV tristate "Marvell SATA support" help -- cgit v1.2.3 From 0f2e0330a85d351b0300583da1e335690c86bdd7 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 21 Jan 2011 20:32:01 +0300 Subject: ipr/sas_ata: use mode mask macros from Commit 14bdef982caeda19afe34010482867c18217c641 ([libata] convert drivers to use ata.h mode mask defines) didn't convert these two libata driver outside drivers/ata/... Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/scsi/ipr.c | 6 +++--- drivers/scsi/libsas/sas_ata.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 9c5c8be72231..081d14a326fe 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -6221,9 +6221,9 @@ static struct ata_port_operations ipr_sata_ops = { static struct ata_port_info sata_port_info = { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA, - .pio_mask = 0x10, /* pio4 */ - .mwdma_mask = 0x07, - .udma_mask = 0x7f, /* udma0-6 */ + .pio_mask = ATA_PIO4_ONLY, + .mwdma_mask = ATA_MWDMA2, + .udma_mask = ATA_UDMA6, .port_ops = &ipr_sata_ops }; diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 8f56d5fbf6ec..fc6bdc51a047 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -374,8 +374,8 @@ static struct ata_port_operations sas_sata_ops = { static struct ata_port_info sata_port_info = { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | ATA_FLAG_NCQ, - .pio_mask = 0x1f, /* PIO0-4 */ - .mwdma_mask = 0x07, /* MWDMA0-2 */ + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, .port_ops = &sas_sata_ops }; -- cgit v1.2.3 From c10f97b9d8df818e51e6073be1b96454630595c1 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 4 Feb 2011 22:03:34 +0300 Subject: libata: remove ATA_FLAG_{SRST|SATA_RESET} These flags are marked as obsolete and the checks for them have been removed by commit 294440887b32c58d220fb54b73b7a58079b78f20 (libata-sff: kill unused ata_bus_reset()), so I think it's time to finally get rid of them... Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/pata_acpi.c | 2 +- drivers/ata/pata_sis.c | 2 +- drivers/ata/sata_sx4.c | 4 ++-- drivers/scsi/ipr.c | 4 ++-- drivers/scsi/libsas/sas_ata.c | 4 ++-- include/linux/libata.h | 2 -- 6 files changed, 8 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c index c8d47034d5e9..91949d997555 100644 --- a/drivers/ata/pata_acpi.c +++ b/drivers/ata/pata_acpi.c @@ -245,7 +245,7 @@ static struct ata_port_operations pacpi_ops = { static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id) { static const struct ata_port_info info = { - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index 60cea13cccce..c04abc393fc5 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c @@ -593,7 +593,7 @@ static const struct ata_port_info sis_info133 = { .port_ops = &sis_133_ops, }; const struct ata_port_info sis_info133_for_sata = { - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = ATA_PIO4, /* No MWDMA */ .udma_mask = ATA_UDMA6, diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index bedd5188e5b0..76384d077b2d 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c @@ -274,8 +274,8 @@ static const struct ata_port_info pdc_port_info[] = { /* board_20621 */ { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_SRST | ATA_FLAG_MMIO | - ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING, + ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI | + ATA_FLAG_PIO_POLLING, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 081d14a326fe..6443ce7c41ae 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -6219,8 +6219,8 @@ static struct ata_port_operations ipr_sata_ops = { }; static struct ata_port_info sata_port_info = { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_SATA_RESET | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA, + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | + ATA_FLAG_PIO_DMA, .pio_mask = ATA_PIO4_ONLY, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index fc6bdc51a047..996dbda47141 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -372,8 +372,8 @@ static struct ata_port_operations sas_sata_ops = { }; static struct ata_port_info sata_port_info = { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_SATA_RESET | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | ATA_FLAG_NCQ, + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | + ATA_FLAG_PIO_DMA | ATA_FLAG_NCQ, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, diff --git a/include/linux/libata.h b/include/linux/libata.h index 9739317c707a..51ec439f75ad 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -181,8 +181,6 @@ enum { ATA_FLAG_SATA = (1 << 1), ATA_FLAG_NO_LEGACY = (1 << 2), /* no legacy mode check */ ATA_FLAG_MMIO = (1 << 3), /* use MMIO, not PIO */ - ATA_FLAG_SRST = (1 << 4), /* (obsolete) use ATA SRST, not E.D.D. */ - ATA_FLAG_SATA_RESET = (1 << 5), /* (obsolete) use COMRESET */ ATA_FLAG_NO_ATAPI = (1 << 6), /* No ATAPI support */ ATA_FLAG_PIO_DMA = (1 << 7), /* PIO cmds via DMA */ ATA_FLAG_PIO_LBA48 = (1 << 8), /* Host DMA engine is LBA28 only */ -- cgit v1.2.3 From 3696df309971b3427cb9cb039138a1732a865a0b Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 4 Feb 2011 22:04:17 +0300 Subject: libata: remove ATA_FLAG_MMIO Commit 0d5ff566779f894ca9937231a181eb31e4adff0e (libata: convert to iomap) removed all checks of ATA_FLAG_MMIO but neglected to remove the flag itself. Do it now, at last... Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 2 +- drivers/ata/ahci.h | 2 +- drivers/ata/libata-acpi.c | 3 +-- drivers/ata/pata_at32.c | 2 +- drivers/ata/pata_bf54x.c | 1 - drivers/ata/pata_ixp4xx_cf.c | 2 +- drivers/ata/pata_macio.c | 3 +-- drivers/ata/pata_octeon_cf.c | 4 ++-- drivers/ata/pata_palmld.c | 2 +- drivers/ata/pata_pdc2027x.c | 6 ++---- drivers/ata/pata_pxa.c | 1 - drivers/ata/pata_rb532_cf.c | 2 +- drivers/ata/pata_samsung_cf.c | 1 - drivers/ata/pata_scc.c | 2 +- drivers/ata/pdc_adma.c | 3 +-- drivers/ata/sata_dwc_460ex.c | 2 +- drivers/ata/sata_fsl.c | 4 ++-- drivers/ata/sata_mv.c | 2 +- drivers/ata/sata_nv.c | 2 +- drivers/ata/sata_promise.c | 1 - drivers/ata/sata_qstor.c | 2 +- drivers/ata/sata_sil.c | 3 +-- drivers/ata/sata_sil24.c | 6 +++--- drivers/ata/sata_svw.c | 10 ++++------ drivers/ata/sata_sx4.c | 3 +-- drivers/ata/sata_vsc.c | 3 +-- drivers/scsi/ipr.c | 3 +-- drivers/scsi/libsas/sas_ata.c | 4 ++-- include/linux/libata.h | 1 - 29 files changed, 33 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index b8d96ce37fc9..3a0435181f77 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -176,7 +176,7 @@ static const struct ata_port_info ahci_port_info[] = { AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_MSI | AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP), .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA, + ATA_FLAG_PIO_DMA, .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 3e606c34f57b..9a323417907e 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -214,7 +214,7 @@ enum { /* ap->flags bits */ AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | + ATA_FLAG_PIO_DMA | ATA_FLAG_ACPI_SATA | ATA_FLAG_AN | ATA_FLAG_LPM, diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 8b5ea399a4f4..a791b8ce6294 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -660,8 +660,7 @@ static int ata_acpi_filter_tf(struct ata_device *dev, * @dev: target ATA device * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7) * - * Outputs ATA taskfile to standard ATA host controller using MMIO - * or PIO as indicated by the ATA_FLAG_MMIO flag. + * Outputs ATA taskfile to standard ATA host controller. * Writes the control, feature, nsect, lbal, lbam, and lbah registers. * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect, * hob_lbal, hob_lbam, and hob_lbah. diff --git a/drivers/ata/pata_at32.c b/drivers/ata/pata_at32.c index 66ce6a526f27..36f189c7ee8c 100644 --- a/drivers/ata/pata_at32.c +++ b/drivers/ata/pata_at32.c @@ -194,7 +194,7 @@ static int __init pata_at32_init_one(struct device *dev, /* Setup ATA bindings */ ap->ops = &at32_port_ops; ap->pio_mask = PIO_MASK; - ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_SLAVE_POSS; + ap->flags |= ATA_FLAG_SLAVE_POSS; /* * Since all 8-bit taskfile transfers has to go on the lower diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index 7aed5c792597..1086cacf3cf5 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c @@ -1455,7 +1455,6 @@ static struct ata_port_operations bfin_pata_ops = { static struct ata_port_info bfin_port_info[] = { { .flags = ATA_FLAG_SLAVE_POSS - | ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY, .pio_mask = ATA_PIO4, .mwdma_mask = 0, diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index ba54b089f98c..783ec4fc1119 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -177,7 +177,7 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev) ap->ops = &ixp4xx_port_ops; ap->pio_mask = ATA_PIO4; - ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI; + ap->flags |= ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI; ixp4xx_setup_port(ap, data, cs0->start, cs1->start); diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index 75b49d01780b..7f7b883c008e 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c @@ -1053,8 +1053,7 @@ static int __devinit pata_macio_common_init(struct pata_macio_priv *priv, /* Allocate libata host for 1 port */ memset(&pinfo, 0, sizeof(struct ata_port_info)); pmac_macio_calc_timing_masks(priv, &pinfo); - pinfo.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_MMIO | - ATA_FLAG_NO_LEGACY; + pinfo.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY; pinfo.port_ops = &pata_macio_ops; pinfo.private_data = priv; diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index fa1b95a9a7ff..18703e2e51c6 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -848,8 +848,8 @@ static int __devinit octeon_cf_probe(struct platform_device *pdev) cf_port->ap = ap; ap->ops = &octeon_cf_ops; ap->pio_mask = ATA_PIO6; - ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY - | ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING; + ap->flags |= ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI + | ATA_FLAG_PIO_POLLING; base = cs0 + ocd->base_region_bias; if (!ocd->is16bit) { diff --git a/drivers/ata/pata_palmld.c b/drivers/ata/pata_palmld.c index 11fb4ccc74b4..462a5fcebab9 100644 --- a/drivers/ata/pata_palmld.c +++ b/drivers/ata/pata_palmld.c @@ -85,7 +85,7 @@ static __devinit int palmld_pata_probe(struct platform_device *pdev) ap = host->ports[0]; ap->ops = &palmld_port_ops; ap->pio_mask = ATA_PIO4; - ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_PIO_POLLING; + ap->flags |= ATA_FLAG_NO_LEGACY | ATA_FLAG_PIO_POLLING; /* memory mapping voodoo */ ap->ioaddr.cmd_addr = mem + 0x10; diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index b18351122525..57ef92ce1a5c 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c @@ -150,8 +150,7 @@ static struct ata_port_operations pdc2027x_pata133_ops = { static struct ata_port_info pdc2027x_port_info[] = { /* PDC_UDMA_100 */ { - .flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS | - ATA_FLAG_MMIO, + .flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA5, @@ -159,8 +158,7 @@ static struct ata_port_info pdc2027x_port_info[] = { }, /* PDC_UDMA_133 */ { - .flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS | - ATA_FLAG_MMIO, + .flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, diff --git a/drivers/ata/pata_pxa.c b/drivers/ata/pata_pxa.c index 1898c6ed4b4e..b4ede40f8ae1 100644 --- a/drivers/ata/pata_pxa.c +++ b/drivers/ata/pata_pxa.c @@ -292,7 +292,6 @@ static int __devinit pxa_ata_probe(struct platform_device *pdev) ap->ops = &pxa_ata_port_ops; ap->pio_mask = ATA_PIO4; ap->mwdma_mask = ATA_MWDMA2; - ap->flags = ATA_FLAG_MMIO; ap->ioaddr.cmd_addr = devm_ioremap(&pdev->dev, cmd_res->start, resource_size(cmd_res)); diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c index 0ffd631000b7..0365a5d714f6 100644 --- a/drivers/ata/pata_rb532_cf.c +++ b/drivers/ata/pata_rb532_cf.c @@ -91,7 +91,7 @@ static void rb532_pata_setup_ports(struct ata_host *ah) ap->ops = &rb532_pata_port_ops; ap->pio_mask = ATA_PIO4; - ap->flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO; + ap->flags = ATA_FLAG_NO_LEGACY; ap->ioaddr.cmd_addr = info->iobase + RB500_CF_REG_BASE; ap->ioaddr.ctl_addr = info->iobase + RB500_CF_REG_CTRL; diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c index 8a51d673e5b2..c446ae6055a3 100644 --- a/drivers/ata/pata_samsung_cf.c +++ b/drivers/ata/pata_samsung_cf.c @@ -531,7 +531,6 @@ static int __init pata_s3c_probe(struct platform_device *pdev) } ap = host->ports[0]; - ap->flags |= ATA_FLAG_MMIO; ap->pio_mask = ATA_PIO4; if (cpu_type == TYPE_S3C64XX) { diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 093715c3273a..5eb050086f38 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -959,7 +959,7 @@ static struct ata_port_operations scc_pata_ops = { static struct ata_port_info scc_port_info[] = { { - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY, + .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY, .pio_mask = ATA_PIO4, /* No MWDMA */ .udma_mask = ATA_UDMA6, diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c index adbe0426c8f0..384f202fbdec 100644 --- a/drivers/ata/pdc_adma.c +++ b/drivers/ata/pdc_adma.c @@ -167,8 +167,7 @@ static struct ata_port_info adma_port_info[] = { /* board_1841_idx */ { .flags = ATA_FLAG_SLAVE_POSS | - ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | - ATA_FLAG_PIO_POLLING, + ATA_FLAG_NO_LEGACY | ATA_FLAG_PIO_POLLING, .pio_mask = ATA_PIO4_ONLY, .udma_mask = ATA_UDMA4, .port_ops = &adma_ata_ops, diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index 843af13606e1..8c37b0e7fad8 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c @@ -1619,7 +1619,7 @@ static struct ata_port_operations sata_dwc_ops = { static const struct ata_port_info sata_dwc_port_info[] = { { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_NCQ, + ATA_FLAG_NCQ, .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, .port_ops = &sata_dwc_ops, diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index b0214d00d50b..1d70cf714275 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -34,8 +34,8 @@ enum { SATA_FSL_MAX_PRD_DIRECT = 16, /* Direct PRDT entries */ SATA_FSL_HOST_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | - ATA_FLAG_PMP | ATA_FLAG_NCQ | ATA_FLAG_AN), + ATA_FLAG_PIO_DMA | ATA_FLAG_PMP | + ATA_FLAG_NCQ | ATA_FLAG_AN), SATA_FSL_MAX_CMDS = SATA_FSL_QUEUE_DEPTH, SATA_FSL_CMD_HDR_SIZE = 16, /* 4 DWORDS */ diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index bf74a36d3cc3..a2193fc52763 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -161,7 +161,7 @@ enum { MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */ MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING, + ATA_FLAG_PIO_POLLING, MV_GEN_I_FLAGS = MV_COMMON_FLAGS | ATA_FLAG_NO_ATAPI, diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 7254e255fd78..cca96e89339d 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -567,7 +567,7 @@ static const struct ata_port_info nv_port_info[] = { /* ADMA */ { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_NCQ, + ATA_FLAG_NCQ, .pio_mask = NV_PIO_MASK, .mwdma_mask = NV_MWDMA_MASK, .udma_mask = NV_UDMA_MASK, diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index f03ad48273ff..b0cba3cd9361 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -135,7 +135,6 @@ enum { PDC_RESET = (1 << 11), /* HDMA reset */ PDC_COMMON_FLAGS = ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING, /* ap->flags bits */ diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index daeebf19a6a9..5e30a7994391 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c @@ -156,7 +156,7 @@ static const struct ata_port_info qs_port_info[] = { /* board_2068_idx */ { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING, + ATA_FLAG_PIO_POLLING, .pio_mask = ATA_PIO4_ONLY, .udma_mask = ATA_UDMA6, .port_ops = &qs_ata_ops, diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index 3a4f84219719..0742d3d968e0 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c @@ -61,8 +61,7 @@ enum { SIL_FLAG_RERR_ON_DMA_ACT = (1 << 29), SIL_FLAG_MOD15WRITE = (1 << 30), - SIL_DFL_PORT_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO, + SIL_DFL_PORT_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, /* * Controller IDs diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index af41c6fd1254..1ad7b94f0b38 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -245,9 +245,9 @@ enum { /* host flags */ SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | - ATA_FLAG_NCQ | ATA_FLAG_ACPI_SATA | - ATA_FLAG_AN | ATA_FLAG_PMP, + ATA_FLAG_PIO_DMA | ATA_FLAG_NCQ | + ATA_FLAG_ACPI_SATA | ATA_FLAG_AN | + ATA_FLAG_PMP, SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */ IRQ_STAT_4PORTS = 0xf, diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 7d9db4aaf07e..adc913a35189 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -360,7 +360,7 @@ static const struct ata_port_info k2_port_info[] = { /* chip_svw4 */ { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA, + K2_FLAG_NO_ATAPI_DMA, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, @@ -369,8 +369,7 @@ static const struct ata_port_info k2_port_info[] = { /* chip_svw8 */ { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA | - K2_FLAG_SATA_8_PORTS, + K2_FLAG_NO_ATAPI_DMA | K2_FLAG_SATA_8_PORTS, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, @@ -379,7 +378,7 @@ static const struct ata_port_info k2_port_info[] = { /* chip_svw42 */ { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | K2_FLAG_BAR_POS_3, + K2_FLAG_BAR_POS_3, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, @@ -387,8 +386,7 @@ static const struct ata_port_info k2_port_info[] = { }, /* chip_svw43 */ { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO, + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index 76384d077b2d..d58e656bef70 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c @@ -274,8 +274,7 @@ static const struct ata_port_info pdc_port_info[] = { /* board_20621 */ { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI | - ATA_FLAG_PIO_POLLING, + ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c index e079cf29ed5d..192bdc7d8f6e 100644 --- a/drivers/ata/sata_vsc.c +++ b/drivers/ata/sata_vsc.c @@ -340,8 +340,7 @@ static int __devinit vsc_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static const struct ata_port_info pi = { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO, + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 6443ce7c41ae..e437c8ae9d41 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -6219,8 +6219,7 @@ static struct ata_port_operations ipr_sata_ops = { }; static struct ata_port_info sata_port_info = { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | - ATA_FLAG_PIO_DMA, + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_PIO_DMA, .pio_mask = ATA_PIO4_ONLY, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 996dbda47141..7538b6ffb3fe 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -372,8 +372,8 @@ static struct ata_port_operations sas_sata_ops = { }; static struct ata_port_info sata_port_info = { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | - ATA_FLAG_PIO_DMA | ATA_FLAG_NCQ, + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_PIO_DMA | + ATA_FLAG_NCQ, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, diff --git a/include/linux/libata.h b/include/linux/libata.h index 51ec439f75ad..0c3d9e144891 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -180,7 +180,6 @@ enum { /* (doesn't imply presence) */ ATA_FLAG_SATA = (1 << 1), ATA_FLAG_NO_LEGACY = (1 << 2), /* no legacy mode check */ - ATA_FLAG_MMIO = (1 << 3), /* use MMIO, not PIO */ ATA_FLAG_NO_ATAPI = (1 << 6), /* No ATAPI support */ ATA_FLAG_PIO_DMA = (1 << 7), /* PIO cmds via DMA */ ATA_FLAG_PIO_LBA48 = (1 << 8), /* Host DMA engine is LBA28 only */ -- cgit v1.2.3 From 9cbe056f6c467e7395d5aec39aceec47812eb98e Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 4 Feb 2011 22:05:48 +0300 Subject: libata: remove ATA_FLAG_NO_LEGACY All checks of ATA_FLAG_NO_LEGACY have been removed by the commits c791c30670ea61f19eec390124128bf278e854fe ([libata] minor PCI IDE probe fixes and cleanups) and f0d36efdc624beb3d9e29b9ab9e9537bf0f25d5b (libata: update libata core layer to use devres), so I think it's time to finally get rid of this flag... Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 3 +-- drivers/ata/ahci.h | 3 +-- drivers/ata/pata_bf54x.c | 3 +-- drivers/ata/pata_ixp4xx_cf.c | 2 +- drivers/ata/pata_macio.c | 2 +- drivers/ata/pata_octeon_cf.c | 3 +-- drivers/ata/pata_palmld.c | 2 +- drivers/ata/pata_pdc2027x.c | 4 ++-- drivers/ata/pata_rb532_cf.c | 1 - drivers/ata/pata_scc.c | 2 +- drivers/ata/pdc_adma.c | 3 +-- drivers/ata/sata_dwc_460ex.c | 3 +-- drivers/ata/sata_fsl.c | 5 ++--- drivers/ata/sata_mv.c | 3 +-- drivers/ata/sata_nv.c | 14 ++++++-------- drivers/ata/sata_promise.c | 3 +-- drivers/ata/sata_qstor.c | 3 +-- drivers/ata/sata_sil.c | 2 +- drivers/ata/sata_sil24.c | 7 +++---- drivers/ata/sata_sis.c | 2 +- drivers/ata/sata_svw.c | 12 +++++------- drivers/ata/sata_sx4.c | 4 ++-- drivers/ata/sata_uli.c | 3 +-- drivers/ata/sata_via.c | 9 ++++----- drivers/ata/sata_vsc.c | 2 +- drivers/scsi/ipr.c | 2 +- drivers/scsi/libsas/sas_ata.c | 3 +-- include/linux/libata.h | 1 - 28 files changed, 43 insertions(+), 63 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 3a0435181f77..6856d877a69b 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -175,8 +175,7 @@ static const struct ata_port_info ahci_port_info[] = { { AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_MSI | AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP), - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_PIO_DMA, + .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA, .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 9a323417907e..fd75844fb009 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -213,8 +213,7 @@ enum { /* ap->flags bits */ - AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_PIO_DMA | + AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA | ATA_FLAG_ACPI_SATA | ATA_FLAG_AN | ATA_FLAG_LPM, diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index 1086cacf3cf5..e0b58b8dfe6f 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c @@ -1454,8 +1454,7 @@ static struct ata_port_operations bfin_pata_ops = { static struct ata_port_info bfin_port_info[] = { { - .flags = ATA_FLAG_SLAVE_POSS - | ATA_FLAG_NO_LEGACY, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = ATA_PIO4, .mwdma_mask = 0, .udma_mask = 0, diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index 783ec4fc1119..5253b271b3fe 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -177,7 +177,7 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev) ap->ops = &ixp4xx_port_ops; ap->pio_mask = ATA_PIO4; - ap->flags |= ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI; + ap->flags |= ATA_FLAG_NO_ATAPI; ixp4xx_setup_port(ap, data, cs0->start, cs1->start); diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index 7f7b883c008e..46f589edccdb 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c @@ -1053,7 +1053,7 @@ static int __devinit pata_macio_common_init(struct pata_macio_priv *priv, /* Allocate libata host for 1 port */ memset(&pinfo, 0, sizeof(struct ata_port_info)); pmac_macio_calc_timing_masks(priv, &pinfo); - pinfo.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY; + pinfo.flags = ATA_FLAG_SLAVE_POSS; pinfo.port_ops = &pata_macio_ops; pinfo.private_data = priv; diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index 18703e2e51c6..220ddc90608f 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -848,8 +848,7 @@ static int __devinit octeon_cf_probe(struct platform_device *pdev) cf_port->ap = ap; ap->ops = &octeon_cf_ops; ap->pio_mask = ATA_PIO6; - ap->flags |= ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI - | ATA_FLAG_PIO_POLLING; + ap->flags |= ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING; base = cs0 + ocd->base_region_bias; if (!ocd->is16bit) { diff --git a/drivers/ata/pata_palmld.c b/drivers/ata/pata_palmld.c index 462a5fcebab9..a2a73d953840 100644 --- a/drivers/ata/pata_palmld.c +++ b/drivers/ata/pata_palmld.c @@ -85,7 +85,7 @@ static __devinit int palmld_pata_probe(struct platform_device *pdev) ap = host->ports[0]; ap->ops = &palmld_port_ops; ap->pio_mask = ATA_PIO4; - ap->flags |= ATA_FLAG_NO_LEGACY | ATA_FLAG_PIO_POLLING; + ap->flags |= ATA_FLAG_PIO_POLLING; /* memory mapping voodoo */ ap->ioaddr.cmd_addr = mem + 0x10; diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index 57ef92ce1a5c..9765ace16921 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c @@ -150,7 +150,7 @@ static struct ata_port_operations pdc2027x_pata133_ops = { static struct ata_port_info pdc2027x_port_info[] = { /* PDC_UDMA_100 */ { - .flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA5, @@ -158,7 +158,7 @@ static struct ata_port_info pdc2027x_port_info[] = { }, /* PDC_UDMA_133 */ { - .flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c index 0365a5d714f6..baeaf938d55b 100644 --- a/drivers/ata/pata_rb532_cf.c +++ b/drivers/ata/pata_rb532_cf.c @@ -91,7 +91,6 @@ static void rb532_pata_setup_ports(struct ata_host *ah) ap->ops = &rb532_pata_port_ops; ap->pio_mask = ATA_PIO4; - ap->flags = ATA_FLAG_NO_LEGACY; ap->ioaddr.cmd_addr = info->iobase + RB500_CF_REG_BASE; ap->ioaddr.ctl_addr = info->iobase + RB500_CF_REG_CTRL; diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 5eb050086f38..88ea9b677b47 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -959,7 +959,7 @@ static struct ata_port_operations scc_pata_ops = { static struct ata_port_info scc_port_info[] = { { - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = ATA_PIO4, /* No MWDMA */ .udma_mask = ATA_UDMA6, diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c index 384f202fbdec..1111712b3d7d 100644 --- a/drivers/ata/pdc_adma.c +++ b/drivers/ata/pdc_adma.c @@ -166,8 +166,7 @@ static struct ata_port_operations adma_ata_ops = { static struct ata_port_info adma_port_info[] = { /* board_1841_idx */ { - .flags = ATA_FLAG_SLAVE_POSS | - ATA_FLAG_NO_LEGACY | ATA_FLAG_PIO_POLLING, + .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_POLLING, .pio_mask = ATA_PIO4_ONLY, .udma_mask = ATA_UDMA4, .port_ops = &adma_ata_ops, diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index 8c37b0e7fad8..712ab5a4922e 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c @@ -1618,8 +1618,7 @@ static struct ata_port_operations sata_dwc_ops = { static const struct ata_port_info sata_dwc_port_info[] = { { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_NCQ, + .flags = ATA_FLAG_SATA | ATA_FLAG_NCQ, .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, .port_ops = &sata_dwc_ops, diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 1d70cf714275..beef37134a04 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -33,9 +33,8 @@ enum { SATA_FSL_MAX_PRD_USABLE = SATA_FSL_MAX_PRD - 1, SATA_FSL_MAX_PRD_DIRECT = 16, /* Direct PRDT entries */ - SATA_FSL_HOST_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_PIO_DMA | ATA_FLAG_PMP | - ATA_FLAG_NCQ | ATA_FLAG_AN), + SATA_FSL_HOST_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_PIO_DMA | + ATA_FLAG_PMP | ATA_FLAG_NCQ | ATA_FLAG_AN), SATA_FSL_MAX_CMDS = SATA_FSL_QUEUE_DEPTH, SATA_FSL_CMD_HDR_SIZE = 16, /* 4 DWORDS */ diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index a2193fc52763..cd40651e9b72 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -160,8 +160,7 @@ enum { /* Host Flags */ MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */ - MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_PIO_POLLING, + MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_PIO_POLLING, MV_GEN_I_FLAGS = MV_COMMON_FLAGS | ATA_FLAG_NO_ATAPI, diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index cca96e89339d..42344e3c686d 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -539,7 +539,7 @@ struct nv_pi_priv { static const struct ata_port_info nv_port_info[] = { /* generic */ { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .flags = ATA_FLAG_SATA, .pio_mask = NV_PIO_MASK, .mwdma_mask = NV_MWDMA_MASK, .udma_mask = NV_UDMA_MASK, @@ -548,7 +548,7 @@ static const struct ata_port_info nv_port_info[] = { }, /* nforce2/3 */ { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .flags = ATA_FLAG_SATA, .pio_mask = NV_PIO_MASK, .mwdma_mask = NV_MWDMA_MASK, .udma_mask = NV_UDMA_MASK, @@ -557,7 +557,7 @@ static const struct ata_port_info nv_port_info[] = { }, /* ck804 */ { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .flags = ATA_FLAG_SATA, .pio_mask = NV_PIO_MASK, .mwdma_mask = NV_MWDMA_MASK, .udma_mask = NV_UDMA_MASK, @@ -566,8 +566,7 @@ static const struct ata_port_info nv_port_info[] = { }, /* ADMA */ { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_NCQ, + .flags = ATA_FLAG_SATA | ATA_FLAG_NCQ, .pio_mask = NV_PIO_MASK, .mwdma_mask = NV_MWDMA_MASK, .udma_mask = NV_UDMA_MASK, @@ -576,7 +575,7 @@ static const struct ata_port_info nv_port_info[] = { }, /* MCP5x */ { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .flags = ATA_FLAG_SATA, .pio_mask = NV_PIO_MASK, .mwdma_mask = NV_MWDMA_MASK, .udma_mask = NV_UDMA_MASK, @@ -585,8 +584,7 @@ static const struct ata_port_info nv_port_info[] = { }, /* SWNCQ */ { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_NCQ, + .flags = ATA_FLAG_SATA | ATA_FLAG_NCQ, .pio_mask = NV_PIO_MASK, .mwdma_mask = NV_MWDMA_MASK, .udma_mask = NV_UDMA_MASK, diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index b0cba3cd9361..a004b1e0ea6d 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -134,8 +134,7 @@ enum { PDC_IRQ_DISABLE = (1 << 10), PDC_RESET = (1 << 11), /* HDMA reset */ - PDC_COMMON_FLAGS = ATA_FLAG_NO_LEGACY | - ATA_FLAG_PIO_POLLING, + PDC_COMMON_FLAGS = ATA_FLAG_PIO_POLLING, /* ap->flags bits */ PDC_FLAG_GEN_II = (1 << 24), diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index 5e30a7994391..c5603265fa58 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c @@ -155,8 +155,7 @@ static struct ata_port_operations qs_ata_ops = { static const struct ata_port_info qs_port_info[] = { /* board_2068_idx */ { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_PIO_POLLING, + .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_POLLING, .pio_mask = ATA_PIO4_ONLY, .udma_mask = ATA_UDMA6, .port_ops = &qs_ata_ops, diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index 0742d3d968e0..b42edaaf3a53 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c @@ -61,7 +61,7 @@ enum { SIL_FLAG_RERR_ON_DMA_ACT = (1 << 29), SIL_FLAG_MOD15WRITE = (1 << 30), - SIL_DFL_PORT_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + SIL_DFL_PORT_FLAGS = ATA_FLAG_SATA, /* * Controller IDs diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 1ad7b94f0b38..06c564e55051 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -244,10 +244,9 @@ enum { BID_SIL3131 = 2, /* host flags */ - SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_PIO_DMA | ATA_FLAG_NCQ | - ATA_FLAG_ACPI_SATA | ATA_FLAG_AN | - ATA_FLAG_PMP, + SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA | + ATA_FLAG_NCQ | ATA_FLAG_ACPI_SATA | + ATA_FLAG_AN | ATA_FLAG_PMP, SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */ IRQ_STAT_4PORTS = 0xf, diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index 2bfe3ae03976..cdcc13e9cf51 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c @@ -96,7 +96,7 @@ static struct ata_port_operations sis_ops = { }; static const struct ata_port_info sis_port_info = { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .flags = ATA_FLAG_SATA, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index adc913a35189..35eabcf34568 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -359,8 +359,7 @@ static struct ata_port_operations k2_sata_ops = { static const struct ata_port_info k2_port_info[] = { /* chip_svw4 */ { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - K2_FLAG_NO_ATAPI_DMA, + .flags = ATA_FLAG_SATA | K2_FLAG_NO_ATAPI_DMA, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, @@ -368,8 +367,8 @@ static const struct ata_port_info k2_port_info[] = { }, /* chip_svw8 */ { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - K2_FLAG_NO_ATAPI_DMA | K2_FLAG_SATA_8_PORTS, + .flags = ATA_FLAG_SATA | K2_FLAG_NO_ATAPI_DMA | + K2_FLAG_SATA_8_PORTS, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, @@ -377,8 +376,7 @@ static const struct ata_port_info k2_port_info[] = { }, /* chip_svw42 */ { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - K2_FLAG_BAR_POS_3, + .flags = ATA_FLAG_SATA | K2_FLAG_BAR_POS_3, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, @@ -386,7 +384,7 @@ static const struct ata_port_info k2_port_info[] = { }, /* chip_svw43 */ { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .flags = ATA_FLAG_SATA, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index d58e656bef70..8fd3b7252bda 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c @@ -273,8 +273,8 @@ static struct ata_port_operations pdc_20621_ops = { static const struct ata_port_info pdc_port_info[] = { /* board_20621 */ { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING, + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_ATAPI | + ATA_FLAG_PIO_POLLING, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c index b8578c32d344..235be717a713 100644 --- a/drivers/ata/sata_uli.c +++ b/drivers/ata/sata_uli.c @@ -88,8 +88,7 @@ static struct ata_port_operations uli_ops = { }; static const struct ata_port_info uli_port_info = { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_IGN_SIMPLEX, + .flags = ATA_FLAG_SATA | ATA_FLAG_IGN_SIMPLEX, .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, .port_ops = &uli_ops, diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 8b677bbf2d37..21242c5709a0 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -148,7 +148,7 @@ static struct ata_port_operations vt8251_ops = { }; static const struct ata_port_info vt6420_port_info = { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .flags = ATA_FLAG_SATA, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, @@ -156,7 +156,7 @@ static const struct ata_port_info vt6420_port_info = { }; static struct ata_port_info vt6421_sport_info = { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .flags = ATA_FLAG_SATA, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, @@ -164,7 +164,7 @@ static struct ata_port_info vt6421_sport_info = { }; static struct ata_port_info vt6421_pport_info = { - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = ATA_PIO4, /* No MWDMA */ .udma_mask = ATA_UDMA6, @@ -172,8 +172,7 @@ static struct ata_port_info vt6421_pport_info = { }; static struct ata_port_info vt8251_port_info = { - .flags = ATA_FLAG_SATA | ATA_FLAG_SLAVE_POSS | - ATA_FLAG_NO_LEGACY, + .flags = ATA_FLAG_SATA | ATA_FLAG_SLAVE_POSS, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c index 192bdc7d8f6e..7c987371136e 100644 --- a/drivers/ata/sata_vsc.c +++ b/drivers/ata/sata_vsc.c @@ -340,7 +340,7 @@ static int __devinit vsc_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static const struct ata_port_info pi = { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .flags = ATA_FLAG_SATA, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index e437c8ae9d41..d841e98a8bd5 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -6219,7 +6219,7 @@ static struct ata_port_operations ipr_sata_ops = { }; static struct ata_port_info sata_port_info = { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_PIO_DMA, + .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA, .pio_mask = ATA_PIO4_ONLY, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 7538b6ffb3fe..4d3b704ede1c 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -372,8 +372,7 @@ static struct ata_port_operations sas_sata_ops = { }; static struct ata_port_info sata_port_info = { - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_PIO_DMA | - ATA_FLAG_NCQ, + .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA | ATA_FLAG_NCQ, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, diff --git a/include/linux/libata.h b/include/linux/libata.h index 0c3d9e144891..26d80479c75f 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -179,7 +179,6 @@ enum { ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */ /* (doesn't imply presence) */ ATA_FLAG_SATA = (1 << 1), - ATA_FLAG_NO_LEGACY = (1 << 2), /* no legacy mode check */ ATA_FLAG_NO_ATAPI = (1 << 6), /* No ATAPI support */ ATA_FLAG_PIO_DMA = (1 << 7), /* PIO cmds via DMA */ ATA_FLAG_PIO_LBA48 = (1 << 8), /* Host DMA engine is LBA28 only */ -- cgit v1.2.3 From 1a0f6b7ecdcd810f8991ea26c95d93ff965e8f41 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 4 Feb 2011 22:08:22 +0300 Subject: libata: remove ATA_FLAG_LPM Commit 6b7ae9545ad9875a289f4191c0216b473e313cb9 (libata: reimplement link power management) removed the check of ATA_FLAG_LPM but neglected to remove the flag itself. Do it now... Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/ahci.h | 3 +-- include/linux/libata.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index fd75844fb009..ccaf08122058 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -214,8 +214,7 @@ enum { /* ap->flags bits */ AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA | - ATA_FLAG_ACPI_SATA | ATA_FLAG_AN | - ATA_FLAG_LPM, + ATA_FLAG_ACPI_SATA | ATA_FLAG_AN, ICH_MAP = 0x90, /* ICH MAP register */ diff --git a/include/linux/libata.h b/include/linux/libata.h index 26d80479c75f..71333aa39532 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -194,7 +194,6 @@ enum { ATA_FLAG_ACPI_SATA = (1 << 17), /* need native SATA ACPI layout */ ATA_FLAG_AN = (1 << 18), /* controller supports AN */ ATA_FLAG_PMP = (1 << 19), /* controller supports PMP */ - ATA_FLAG_LPM = (1 << 20), /* driver can handle LPM */ ATA_FLAG_EM = (1 << 21), /* driver supports enclosure * management */ ATA_FLAG_SW_ACTIVITY = (1 << 22), /* driver supports sw activity -- cgit v1.2.3 From 467b41c688c79d1b5e076fbdf082f9cd5d6a000c Mon Sep 17 00:00:00 2001 From: Per Jessen Date: Tue, 8 Feb 2011 13:54:32 +0100 Subject: ahci: recognize Marvell 88se9125 PCIe SATA 6.0 Gb/s controller Recognize Marvell 88SE9125 PCIe SATA 6.0 Gb/s controller. Signed-off-by: Per Jessen Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 6856d877a69b..256d2b72cd1c 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -382,6 +382,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { .class = PCI_CLASS_STORAGE_SATA_AHCI, .class_mask = 0xffffff, .driver_data = board_ahci_yes_fbs }, /* 88se9128 */ + { PCI_DEVICE(0x1b4b, 0x9125), + .driver_data = board_ahci_yes_fbs }, /* 88se9125 */ /* Promise */ { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ -- cgit v1.2.3 From 0a85b4827e9960295fbf4ca0f32bb357693cc5f7 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sat, 22 Jan 2011 02:08:30 +0100 Subject: mfd: Fix ASIC3 build with GENERIC_HARDIRQS_NO_DEPRECATED Signed-off-by: Lennert Buytenhek Signed-off-by: Samuel Ortiz --- drivers/mfd/asic3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 6a1f94042612..c45e6305b26f 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -143,9 +143,9 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) unsigned long flags; struct asic3 *asic; - desc->chip->ack(irq); + desc->irq_data.chip->irq_ack(&desc->irq_data); - asic = desc->handler_data; + asic = get_irq_data(irq); for (iter = 0 ; iter < MAX_ASIC_ISR_LOOPS; iter++) { u32 status; -- cgit v1.2.3 From 9063f1f15eec35e5fd608879cef8be5728f2d12a Mon Sep 17 00:00:00 2001 From: Jochen Friedrich Date: Wed, 26 Jan 2011 11:30:01 +0100 Subject: mfd: Fix NULL pointer due to non-initialized ucb1x00-ts absinfo Call input_set_abs_params instead of manually setting absbit only. This fixes this oops: Unable to handle kernel NULL pointer dereference at virtual address 00000024 Internal error: Oops: 41b67017 [#1] CPU: 0 Not tainted (2.6.37 #4) pc : [] lr : [<00000000>] psr: 20000093 sp : c19e5f30 ip : c19e5e6c fp : c19e5f58 r10: 00000000 r9 : c19e4000 r8 : 00000003 r7 : 000001e4 r6 : 00000001 r5 : c1854400 r4 : 00000003 r3 : 00000018 r2 : 00000018 r1 : 00000018 r0 : c185447c Flags: nzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel Control: c1b6717f Table: c1b6717f DAC: 00000017 Stack: (0xc19e5f30 to 0xc19e6000) 5f20: 00000003 00000003 c1854400 00000013 5f40: 00000001 000001e4 000001c5 c19e5f80 c19e5f5c c016d5e8 c016cf5c 000001e4 5f60: c1854400 c18b5860 00000000 00000171 000001e4 c19e5fc4 c19e5f84 c01559a4 5f80: c016d584 c18b5868 00000000 c1bb5c40 c0035afc c18b5868 c18b5868 c1a55d54 5fa0: c18b5860 c0155750 00000013 00000000 00000000 00000000 c19e5ff4 c19e5fc8 5fc0: c0050174 c015575c 00000000 c18b5860 00000000 c19e5fd4 c19e5fd4 c1a55d54 5fe0: c00500f0 c003b464 00000000 c19e5ff8 c003b464 c00500fc 04000400 04000400 Backtrace: Function entered at [] from [] Function entered at [] from [] r8:000001e4 r7:00000171 r6:00000000 r5:c18b5860 r4:c1854400 Function entered at [] from [] Function entered at [] from [] r6:c003b464 r5:c00500f0 r4:c1a55d54 Code: e59520fc e1a03286 e0433186 e0822003 (e592000c) >>PC; c016d1fc <===== Trace; c016cf50 Trace; c016d5e8 Trace; c016d578 Trace; c01559a4 Trace; c0155750 Trace; c0050174 Trace; c00500f0 Trace; c003b464 Signed-off-by: Jochen Friedrich CC: stable@kernel.org Signed-off-by: Samuel Ortiz --- drivers/mfd/ucb1x00-ts.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c index 000cb414a78a..92b85e28a15e 100644 --- a/drivers/mfd/ucb1x00-ts.c +++ b/drivers/mfd/ucb1x00-ts.c @@ -385,12 +385,18 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev) idev->close = ucb1x00_ts_close; __set_bit(EV_ABS, idev->evbit); - __set_bit(ABS_X, idev->absbit); - __set_bit(ABS_Y, idev->absbit); - __set_bit(ABS_PRESSURE, idev->absbit); input_set_drvdata(idev, ts); + ucb1x00_adc_enable(ts->ucb); + ts->x_res = ucb1x00_ts_read_xres(ts); + ts->y_res = ucb1x00_ts_read_yres(ts); + ucb1x00_adc_disable(ts->ucb); + + input_set_abs_params(idev, ABS_X, 0, ts->x_res, 0, 0); + input_set_abs_params(idev, ABS_Y, 0, ts->y_res, 0, 0); + input_set_abs_params(idev, ABS_PRESSURE, 0, 0, 0, 0); + err = input_register_device(idev); if (err) goto fail; -- cgit v1.2.3 From 73ee6524d55444dc80c691ff8602e08940df3d47 Mon Sep 17 00:00:00 2001 From: "Manjunathappa, Prakash" Date: Thu, 27 Jan 2011 18:58:36 +0530 Subject: mfd: Fix DaVinci voice codec device name Fix the device name in DaVinci Voice Codec MFD driver to load davinci-vcif and cq93vc codec client drivers. Signed-off-by: Manjunathappa, Prakash Acked-by: Liam Girdwood Signed-off-by: Samuel Ortiz --- drivers/mfd/davinci_voicecodec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c index 33c923d215c7..fdd8a1b8bc67 100644 --- a/drivers/mfd/davinci_voicecodec.c +++ b/drivers/mfd/davinci_voicecodec.c @@ -118,12 +118,12 @@ static int __init davinci_vc_probe(struct platform_device *pdev) /* Voice codec interface client */ cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL]; - cell->name = "davinci_vcif"; + cell->name = "davinci-vcif"; cell->driver_data = davinci_vc; /* Voice codec CQ93VC client */ cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL]; - cell->name = "cq93vc"; + cell->name = "cq93vc-codec"; cell->driver_data = davinci_vc; ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, -- cgit v1.2.3 From 77bd70e9009eab6dbdef3ee08afe87ab26df8dac Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 4 Feb 2011 14:57:43 +0000 Subject: mfd: Don't suspend WM8994 if the CODEC is not suspended ASoC supports keeping the audio subsysetm active over suspend in order to support use cases such as audio passthrough from a cellular modem with the main CPU suspended. Ensure that we don't power down the CODEC when this is happening by checking to see if VMID is up and skipping suspend and resume when it is. If the CODEC has suspended then it'll turn VMID off before the core suspend() gets called. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/wm8994-core.c | 18 ++++++++++++++++++ include/linux/mfd/wm8994/core.h | 1 + 2 files changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index 41233c7fa581..f4016a075fd6 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c @@ -246,6 +246,16 @@ static int wm8994_suspend(struct device *dev) struct wm8994 *wm8994 = dev_get_drvdata(dev); int ret; + /* Don't actually go through with the suspend if the CODEC is + * still active (eg, for audio passthrough from CP. */ + ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_1); + if (ret < 0) { + dev_err(dev, "Failed to read power status: %d\n", ret); + } else if (ret & WM8994_VMID_SEL_MASK) { + dev_dbg(dev, "CODEC still active, ignoring suspend\n"); + return 0; + } + /* GPIO configuration state is saved here since we may be configuring * the GPIO alternate functions even if we're not using the gpiolib * driver for them. @@ -261,6 +271,8 @@ static int wm8994_suspend(struct device *dev) if (ret < 0) dev_err(dev, "Failed to save LDO registers: %d\n", ret); + wm8994->suspended = true; + ret = regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies); if (ret != 0) { @@ -276,6 +288,10 @@ static int wm8994_resume(struct device *dev) struct wm8994 *wm8994 = dev_get_drvdata(dev); int ret; + /* We may have lied to the PM core about suspending */ + if (!wm8994->suspended) + return 0; + ret = regulator_bulk_enable(wm8994->num_supplies, wm8994->supplies); if (ret != 0) { @@ -298,6 +314,8 @@ static int wm8994_resume(struct device *dev) if (ret < 0) dev_err(dev, "Failed to restore GPIO registers: %d\n", ret); + wm8994->suspended = false; + return 0; } #endif diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h index 3fd36845ca45..ef4f0b6083a3 100644 --- a/include/linux/mfd/wm8994/core.h +++ b/include/linux/mfd/wm8994/core.h @@ -71,6 +71,7 @@ struct wm8994 { u16 irq_masks_cache[WM8994_NUM_IRQ_REGS]; /* Used over suspend/resume */ + bool suspended; u16 ldo_regs[WM8994_NUM_LDO_REGS]; u16 gpio_regs[WM8994_NUM_GPIO_REGS]; -- cgit v1.2.3 From 4b57018dcd6418e18c08088c89f123da8a7bfc45 Mon Sep 17 00:00:00 2001 From: "vwadekar@nvidia.com" Date: Thu, 24 Feb 2011 10:18:13 +0530 Subject: mfd: Avoid tps6586x burst writes tps6586 does not support burst writes. i2c writes have to be 1 byte at a time. Cc: stable@kernel.org Signed-off-by: Varun Wadekar Signed-off-by: Samuel Ortiz --- drivers/mfd/tps6586x.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index 627cf577b16d..e9018d1394ee 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c @@ -150,12 +150,12 @@ static inline int __tps6586x_write(struct i2c_client *client, static inline int __tps6586x_writes(struct i2c_client *client, int reg, int len, uint8_t *val) { - int ret; + int ret, i; - ret = i2c_smbus_write_i2c_block_data(client, reg, len, val); - if (ret < 0) { - dev_err(&client->dev, "failed writings to 0x%02x\n", reg); - return ret; + for (i = 0; i < len; i++) { + ret = __tps6586x_write(client, reg + i, *(val + i)); + if (ret < 0) + return ret; } return 0; -- cgit v1.2.3 From 2db1badfa5d100dd9f7c7a716911250a735cf2e8 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 24 Feb 2011 16:11:42 +0000 Subject: e1000: fix sparse warning Sparse complains because the e1000 driver is calling ioread on a pointer not tagged as __iomem. Signed-off-by: Stephen Hemminger Reviewed-by: Jesse Brandeburg Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000/e1000_osdep.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h index 55c1711f1688..33e7c45a4fe4 100644 --- a/drivers/net/e1000/e1000_osdep.h +++ b/drivers/net/e1000/e1000_osdep.h @@ -42,7 +42,8 @@ #define GBE_CONFIG_RAM_BASE \ ((unsigned int)(CONFIG_RAM_BASE + GBE_CONFIG_OFFSET)) -#define GBE_CONFIG_BASE_VIRT phys_to_virt(GBE_CONFIG_RAM_BASE) +#define GBE_CONFIG_BASE_VIRT \ + ((void __iomem *)phys_to_virt(GBE_CONFIG_RAM_BASE)) #define GBE_CONFIG_FLASH_WRITE(base, offset, count, data) \ (iowrite16_rep(base + offset, data, count)) -- cgit v1.2.3 From 9dc441f3c5a9ea1b9888ce15b1ccb3f30a79e323 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Thu, 17 Feb 2011 18:47:48 +0000 Subject: igb: fix sparse warning Reported-by: Stephen Hemminger Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/igbvf/vf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/igbvf/vf.c b/drivers/net/igbvf/vf.c index 74486a8b009a..af3822f9ea9a 100644 --- a/drivers/net/igbvf/vf.c +++ b/drivers/net/igbvf/vf.c @@ -220,7 +220,7 @@ static u32 e1000_hash_mc_addr_vf(struct e1000_hw *hw, u8 *mc_addr) * The parameter rar_count will usually be hw->mac.rar_entry_count * unless there are workarounds that change this. **/ -void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, +static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, u8 *mc_addr_list, u32 mc_addr_count, u32 rar_used_count, u32 rar_count) { -- cgit v1.2.3 From 4def99bbfd46e05c5e03b5b282cb4ee30e27ff19 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 2 Feb 2011 09:30:36 +0000 Subject: e1000e: disable broken PHY wakeup for ICH10 LOMs, use MAC wakeup instead When support for 82577/82578 was added[1] in 2.6.31, PHY wakeup was in- advertently enabled (even though it does not function properly) on ICH10 LOMs. This patch makes it so that the ICH10 LOMs use MAC wakeup instead as was done with the initial support for those devices (i.e. 82567LM-3, 82567LF-3 and 82567V-4). [1] commit a4f58f5455ba0efda36fb33c37074922d1527a10 Reported-by: Aurelien Jarno Cc: Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/netdev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 3fa110ddb041..2e5022849f18 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -5967,7 +5967,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, /* APME bit in EEPROM is mapped to WUC.APME */ eeprom_data = er32(WUC); eeprom_apme_mask = E1000_WUC_APME; - if (eeprom_data & E1000_WUC_PHY_WAKE) + if ((hw->mac.type > e1000_ich10lan) && + (eeprom_data & E1000_WUC_PHY_WAKE)) adapter->flags2 |= FLAG2_HAS_PHY_WAKEUP; } else if (adapter->flags & FLAG_APME_IN_CTRL3) { if (adapter->flags & FLAG_APME_CHECK_PORT_B && -- cgit v1.2.3 From 1654e7411a1ad4999fe7890ef51d2a2bbb1fcf76 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 2 Mar 2011 08:48:05 -0500 Subject: block: add @force_kblockd to __blk_run_queue() __blk_run_queue() automatically either calls q->request_fn() directly or schedules kblockd depending on whether the function is recursed. blk-flush implementation needs to be able to explicitly choose kblockd. Add @force_kblockd. All the current users are converted to specify %false for the parameter and this patch doesn't introduce any behavior change. stable: This is prerequisite for fixing ide oops caused by the new blk-flush implementation. Signed-off-by: Tejun Heo Cc: Jan Beulich Cc: James Bottomley Cc: stable@kernel.org Signed-off-by: Jens Axboe --- block/blk-core.c | 11 ++++++----- block/blk-flush.c | 2 +- block/cfq-iosched.c | 6 +++--- block/elevator.c | 4 ++-- drivers/scsi/scsi_lib.c | 2 +- drivers/scsi/scsi_transport_fc.c | 2 +- include/linux/blkdev.h | 2 +- 7 files changed, 15 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/block/blk-core.c b/block/blk-core.c index 792ece276160..518dd423a5fe 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -352,7 +352,7 @@ void blk_start_queue(struct request_queue *q) WARN_ON(!irqs_disabled()); queue_flag_clear(QUEUE_FLAG_STOPPED, q); - __blk_run_queue(q); + __blk_run_queue(q, false); } EXPORT_SYMBOL(blk_start_queue); @@ -403,13 +403,14 @@ EXPORT_SYMBOL(blk_sync_queue); /** * __blk_run_queue - run a single device queue * @q: The queue to run + * @force_kblockd: Don't run @q->request_fn directly. Use kblockd. * * Description: * See @blk_run_queue. This variant must be called with the queue lock * held and interrupts disabled. * */ -void __blk_run_queue(struct request_queue *q) +void __blk_run_queue(struct request_queue *q, bool force_kblockd) { blk_remove_plug(q); @@ -423,7 +424,7 @@ void __blk_run_queue(struct request_queue *q) * Only recurse once to avoid overrunning the stack, let the unplug * handling reinvoke the handler shortly if we already got there. */ - if (!queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) { + if (!force_kblockd && !queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) { q->request_fn(q); queue_flag_clear(QUEUE_FLAG_REENTER, q); } else { @@ -446,7 +447,7 @@ void blk_run_queue(struct request_queue *q) unsigned long flags; spin_lock_irqsave(q->queue_lock, flags); - __blk_run_queue(q); + __blk_run_queue(q, false); spin_unlock_irqrestore(q->queue_lock, flags); } EXPORT_SYMBOL(blk_run_queue); @@ -1053,7 +1054,7 @@ void blk_insert_request(struct request_queue *q, struct request *rq, drive_stat_acct(rq, 1); __elv_add_request(q, rq, where, 0); - __blk_run_queue(q); + __blk_run_queue(q, false); spin_unlock_irqrestore(q->queue_lock, flags); } EXPORT_SYMBOL(blk_insert_request); diff --git a/block/blk-flush.c b/block/blk-flush.c index 54b123d6563e..56adaa8d55cd 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -69,7 +69,7 @@ static void blk_flush_complete_seq_end_io(struct request_queue *q, * queue. Kick the queue in those cases. */ if (was_empty && next_rq) - __blk_run_queue(q); + __blk_run_queue(q, false); } static void pre_flush_end_io(struct request *rq, int error) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 7be4c7959625..ea83a4f0c27d 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -3355,7 +3355,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, cfqd->busy_queues > 1) { cfq_del_timer(cfqd, cfqq); cfq_clear_cfqq_wait_request(cfqq); - __blk_run_queue(cfqd->queue); + __blk_run_queue(cfqd->queue, false); } else { cfq_blkiocg_update_idle_time_stats( &cfqq->cfqg->blkg); @@ -3370,7 +3370,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, * this new queue is RT and the current one is BE */ cfq_preempt_queue(cfqd, cfqq); - __blk_run_queue(cfqd->queue); + __blk_run_queue(cfqd->queue, false); } } @@ -3731,7 +3731,7 @@ static void cfq_kick_queue(struct work_struct *work) struct request_queue *q = cfqd->queue; spin_lock_irq(q->queue_lock); - __blk_run_queue(cfqd->queue); + __blk_run_queue(cfqd->queue, false); spin_unlock_irq(q->queue_lock); } diff --git a/block/elevator.c b/block/elevator.c index 2569512830d3..236e93c1f46c 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -602,7 +602,7 @@ void elv_quiesce_start(struct request_queue *q) */ elv_drain_elevator(q); while (q->rq.elvpriv) { - __blk_run_queue(q); + __blk_run_queue(q, false); spin_unlock_irq(q->queue_lock); msleep(10); spin_lock_irq(q->queue_lock); @@ -651,7 +651,7 @@ void elv_insert(struct request_queue *q, struct request *rq, int where) * with anything. There's no point in delaying queue * processing. */ - __blk_run_queue(q); + __blk_run_queue(q, false); break; case ELEVATOR_INSERT_SORT: diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 9045c52abd25..fb2bb35c62cb 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -443,7 +443,7 @@ static void scsi_run_queue(struct request_queue *q) &sdev->request_queue->queue_flags); if (flagset) queue_flag_set(QUEUE_FLAG_REENTER, sdev->request_queue); - __blk_run_queue(sdev->request_queue); + __blk_run_queue(sdev->request_queue, false); if (flagset) queue_flag_clear(QUEUE_FLAG_REENTER, sdev->request_queue); spin_unlock(sdev->request_queue->queue_lock); diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 998c01be3234..5c3ccfc6b622 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -3829,7 +3829,7 @@ fc_bsg_goose_queue(struct fc_rport *rport) !test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags); if (flagset) queue_flag_set(QUEUE_FLAG_REENTER, rport->rqst_q); - __blk_run_queue(rport->rqst_q); + __blk_run_queue(rport->rqst_q, false); if (flagset) queue_flag_clear(QUEUE_FLAG_REENTER, rport->rqst_q); spin_unlock_irqrestore(rport->rqst_q->queue_lock, flags); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index dd8cd0f47e3a..d5063e1b5555 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -699,7 +699,7 @@ extern void blk_start_queue(struct request_queue *q); extern void blk_stop_queue(struct request_queue *q); extern void blk_sync_queue(struct request_queue *q); extern void __blk_stop_queue(struct request_queue *q); -extern void __blk_run_queue(struct request_queue *); +extern void __blk_run_queue(struct request_queue *q, bool force_kblockd); extern void blk_run_queue(struct request_queue *); extern int blk_rq_map_user(struct request_queue *, struct request *, struct rq_map_data *, void __user *, unsigned long, -- cgit v1.2.3 From 0a91be40ed67ca72a81cfd842d5c2604ff1a54a4 Mon Sep 17 00:00:00 2001 From: Antti Seppälä Date: Sun, 13 Feb 2011 07:29:15 -0300 Subject: [media] Fix sysfs rc protocol lookup for rc-5-sz MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the current matching rules the lookup for rc protocol named rc-5-sz matches with "rc-5" before finding "rc-5-sz". Thus one is able to never enable/disable the rc-5-sz protocol via sysfs. Fix the lookup to require an exact match which allows the manipulation of sz protocol. Signed-off-by: Antti Seppälä Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/rc-main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 72be8a02118c..e5b29a4c691e 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -844,7 +844,7 @@ static ssize_t store_protocols(struct device *device, count++; } else { for (i = 0; i < ARRAY_SIZE(proto_names); i++) { - if (!strncasecmp(tmp, proto_names[i].name, strlen(proto_names[i].name))) { + if (!strcasecmp(tmp, proto_names[i].name)) { tmp += strlen(proto_names[i].name); mask = proto_names[i].type; break; -- cgit v1.2.3 From e192a7cf0effe7680264a5bc35c0ad1bdcdc921c Mon Sep 17 00:00:00 2001 From: Olivier Grenie Date: Fri, 14 Jan 2011 13:58:59 -0300 Subject: [media] DiB7000M: add pid filtering This patch adds the pid filtering for the dib7000M demod. It also corrects the pid filtering for the dib7700 based board. It should prevent an oops, when using dib7700p based board. References: https://bugzilla.novell.com/show_bug.cgi?id=644807 Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher Tested-by: Pavel SKARKA Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 21 +++++++++++++++++++-- drivers/media/dvb/frontends/dib7000m.c | 19 +++++++++++++++++++ drivers/media/dvb/frontends/dib7000m.h | 15 +++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index defd83964ce2..193cdb77b76a 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -870,6 +870,23 @@ static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap) return 0; } +static int stk7700p_pid_filter(struct dvb_usb_adapter *adapter, int index, + u16 pid, int onoff) +{ + struct dib0700_state *st = adapter->dev->priv; + if (st->is_dib7000pc) + return dib7000p_pid_filter(adapter->fe, index, pid, onoff); + return dib7000m_pid_filter(adapter->fe, index, pid, onoff); +} + +static int stk7700p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) +{ + struct dib0700_state *st = adapter->dev->priv; + if (st->is_dib7000pc) + return dib7000p_pid_filter_ctrl(adapter->fe, onoff); + return dib7000m_pid_filter_ctrl(adapter->fe, onoff); +} + static int stk70x0p_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) { return dib7000p_pid_filter(adapter->fe, index, pid, onoff); @@ -1875,8 +1892,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { { .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, - .pid_filter = stk70x0p_pid_filter, - .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, + .pid_filter = stk7700p_pid_filter, + .pid_filter_ctrl = stk7700p_pid_filter_ctrl, .frontend_attach = stk7700p_frontend_attach, .tuner_attach = stk7700p_tuner_attach, diff --git a/drivers/media/dvb/frontends/dib7000m.c b/drivers/media/dvb/frontends/dib7000m.c index c7f5ccf54aa5..289a79837f24 100644 --- a/drivers/media/dvb/frontends/dib7000m.c +++ b/drivers/media/dvb/frontends/dib7000m.c @@ -1285,6 +1285,25 @@ struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *demod, enum di } EXPORT_SYMBOL(dib7000m_get_i2c_master); +int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) +{ + struct dib7000m_state *state = fe->demodulator_priv; + u16 val = dib7000m_read_word(state, 294 + state->reg_offs) & 0xffef; + val |= (onoff & 0x1) << 4; + dprintk("PID filter enabled %d", onoff); + return dib7000m_write_word(state, 294 + state->reg_offs, val); +} +EXPORT_SYMBOL(dib7000m_pid_filter_ctrl); + +int dib7000m_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) +{ + struct dib7000m_state *state = fe->demodulator_priv; + dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff); + return dib7000m_write_word(state, 300 + state->reg_offs + id, + onoff ? (1 << 13) | pid : 0); +} +EXPORT_SYMBOL(dib7000m_pid_filter); + #if 0 /* used with some prototype boards */ int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, diff --git a/drivers/media/dvb/frontends/dib7000m.h b/drivers/media/dvb/frontends/dib7000m.h index 113819ce9f0d..81fcf2241c64 100644 --- a/drivers/media/dvb/frontends/dib7000m.h +++ b/drivers/media/dvb/frontends/dib7000m.h @@ -46,6 +46,8 @@ extern struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap, extern struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); +extern int dib7000m_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff); +extern int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff); #else static inline struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap, @@ -63,6 +65,19 @@ struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *demod, printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } +static inline int dib7000m_pid_filter(struct dvb_frontend *fe, u8 id, + u16 pid, u8 onoff) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} + +static inline int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, + uint8_t onoff) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return -ENODEV; +} #endif /* TODO -- cgit v1.2.3 From 67914b5c400d6c213f9e56d7547a2038ab5c06f4 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 13 Feb 2011 21:52:50 -0300 Subject: [media] cx23885: Revert "Check for slave nack on all transactions" This reverts commit 44835f197bf1e3f57464f23dfb239fef06cf89be. With the CX23885 hardware I2C master, checking for I2C slave ACK/NAK is not valid when the I2C_EXTEND or I2C_NOSTOP bits are set. Revert the commit that checks for I2C slave ACK/NAK on all transactions, so that XC5000 tuners work with the CX23885 again. Thanks go to Mark Zimmerman for reporting and bisecting this problem. Bisected-by: Mark Zimmerman Reported-by: Mark Zimmerman Signed-off-by: Andy Walls Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-i2c.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c index ed3d8f55029b..1007f80bd7c1 100644 --- a/drivers/media/video/cx23885/cx23885-i2c.c +++ b/drivers/media/video/cx23885/cx23885-i2c.c @@ -122,10 +122,6 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, if (!i2c_wait_done(i2c_adap)) goto eio; - if (!i2c_slave_did_ack(i2c_adap)) { - retval = -ENXIO; - goto err; - } if (i2c_debug) { printk(" addr << 1, msg->buf[0]); if (!(ctrl & I2C_NOSTOP)) @@ -209,10 +205,6 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, if (!i2c_wait_done(i2c_adap)) goto eio; - if (cnt == 0 && !i2c_slave_did_ack(i2c_adap)) { - retval = -ENXIO; - goto err; - } msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff; if (i2c_debug) { dprintk(1, " %02x", msg->buf[cnt]); -- cgit v1.2.3 From 593110d143f85d1aca227685edd571f137388b24 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 13 Feb 2011 22:01:38 -0300 Subject: [media] cx23885: Remove unused 'err:' labels to quiet compiler warning The previous revert-commit, that affected cx23885-i2c.c, left some unused labels that the compiler griped about. Clean them up. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-i2c.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c index 1007f80bd7c1..307ff543c254 100644 --- a/drivers/media/video/cx23885/cx23885-i2c.c +++ b/drivers/media/video/cx23885/cx23885-i2c.c @@ -154,7 +154,6 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, eio: retval = -EIO; - err: if (i2c_debug) printk(KERN_ERR " ERR: %d\n", retval); return retval; @@ -216,7 +215,6 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, eio: retval = -EIO; - err: if (i2c_debug) printk(KERN_ERR " ERR: %d\n", retval); return retval; -- cgit v1.2.3 From 1e6406b8f0dc1ae7d7c39c9e1ac6ca78e016ebfb Mon Sep 17 00:00:00 2001 From: Sven Barth Date: Sun, 13 Feb 2011 22:09:43 -0300 Subject: [media] cx25840: fix probing of cx2583x chips Fix the probing of cx2583x chips, because two controls were clustered that are not created for these chips. This regression was introduced in 2.6.36. Signed-off-by: Sven Barth Signed-off-by: Andy Walls Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx25840/cx25840-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 6fc09dd41b9d..35796e035247 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -2015,7 +2015,8 @@ static int cx25840_probe(struct i2c_client *client, kfree(state); return err; } - v4l2_ctrl_cluster(2, &state->volume); + if (!is_cx2583x(state)) + v4l2_ctrl_cluster(2, &state->volume); v4l2_ctrl_handler_setup(&state->hdl); if (client->dev.platform_data) { -- cgit v1.2.3 From d213ad08362909ab50fbd6568fcc9fd568268d29 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 26 Feb 2011 01:56:34 -0300 Subject: [media] ivtv: Fix corrective action taken upon DMA ERR interrupt to avoid hang After upgrading the kernel from stock Ubuntu 7.10 to 10.04, with no hardware changes, I started getting the dreaded DMA TIMEOUT errors, followed by inability to encode until the machine was rebooted. I came across a post from Andy in March (http://www.gossamer-threads.com/lists/ivtv/users/40943#40943) where he speculates that perhaps the corrective actions being taken after a DMA ERROR are not sufficient to recover the situation. After some testing I suspect that this is indeed the case, and that in fact the corrective action may be what hangs the card's DMA engine, rather than the original error. Specifically these DMA ERROR IRQs seem to present with two different values in the IVTV_REG_DMASTATUS register: 0x11 and 0x13. The current corrective action is to clear that status register back to 0x01 or 0x03, and then issue the next DMA request. In the case of a 0x13 this seems to result in a minor glitch in the encoded stream due to the failed transfer that was not retried, but otherwise things continue OK. In the case of a 0x11 the card's DMA write engine is never heard from again, and a DMA TIMEOUT follows shortly after. 0x11 is the killer. I suspect that the two cases need to be handled differently. The difference is in bit 1 (0x02), which is set when the error is about to be successfully recovered, and clear when things are about to go bad. Bit 1 of DMASTATUS is described differently in different places either as a positive "write finished", or an inverted "write busy". If we take the first definition, then when an error arises with state 0x11, it means that the write did not complete. It makes sense to start a new transfer, as in the current code. But if we take the second definition, then 0x11 means "an error but the write engine is still busy". Trying to feed it a new transfer in this situation might not be a good idea. As an experiment, I added code to ignore the DMA ERROR IRQ if DMASTATUS is 0x11. I.e., don't start a new transfer, don't clear our flags, etc. The hope was that the card would complete the transfer and issue a ENC DMA COMPLETE, either successfully or with an error condition there. However the card still hung. The only remaining corrective action being taken with a 0x11 status was then the write back to the status register to clear the error, i.e. DMASTATUS = DMASTATUS & ~3. This would have the effect of clearing the error bit 4, while leaving the lower bits indicating DMA write busy. Strangely enough, removing this write to the status register solved the problem! If the DMA ERROR IRQ with DMASTATUS=0x11 is completely ignored, with no corrective action at all, then the card will complete the transfer and issue a new IRQ. If the status register is written to when it has the value 0x11, then the DMA engine hangs. Perhaps it's illegal to write to DMASTATUS while the read or write busy bit is set? At any rate, it appears that the current corrective action is indeed making things worse rather than better. I put together a patch that modifies ivtv_irq_dma_err to do the following: - Don't write back to IVTV_REG_DMASTATUS. - If write-busy is asserted, leave the card alone. Just extend the timeout slightly. - If write-busy is de-asserted, retry the current transfer. This has completely fixed my DMA TIMEOUT woes. DMA ERR events still occur, but now they seem to be correctly handled. 0x11 events no longer hang the card, and 0x13 events no longer result in a glitch in the stream, as the failed transfer is retried. I'm happy. I've inlined the patch below in case it is of interest. As described above, I have a theory about why it works (based on a different interpretation of bit 1 of DMASTATUS), but I can't guarantee that my theory is correct. There may be another explanation, or it may be a fluke. Maybe ignoring that IRQ entirely would be equally effective? Maybe the status register read/writeback sequence is race condition if the card changes it in the mean time? Also as I am using a PVR-150 only, I have not been able to test it on other cards, which may be especially relevant for 350s that support concurrent decoding. Hopefully the patch does not break the DMA READ path. Mike [awalls@md.metrocast.net: Modified patch to add a verbose comment, make minor brace reformats, and clear the error flags in the IVTV_REG_DMASTATUS iff both read and write DMA were not in progress. Mike's conjecture about a race condition with the writeback is correct; it can confuse the DMA engine.] [Comment and analysis from the ML post by Michael ] Signed-off-by: Andy Walls Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-irq.c | 58 ++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c index 9b4faf009196..9c29e964d400 100644 --- a/drivers/media/video/ivtv/ivtv-irq.c +++ b/drivers/media/video/ivtv/ivtv-irq.c @@ -628,22 +628,66 @@ static void ivtv_irq_enc_pio_complete(struct ivtv *itv) static void ivtv_irq_dma_err(struct ivtv *itv) { u32 data[CX2341X_MBOX_MAX_DATA]; + u32 status; del_timer(&itv->dma_timer); + ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data); + status = read_reg(IVTV_REG_DMASTATUS); IVTV_DEBUG_WARN("DMA ERROR %08x %08x %08x %d\n", data[0], data[1], - read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream); - write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS); + status, itv->cur_dma_stream); + /* + * We do *not* write back to the IVTV_REG_DMASTATUS register to + * clear the error status, if either the encoder write (0x02) or + * decoder read (0x01) bus master DMA operation do not indicate + * completed. We can race with the DMA engine, which may have + * transitioned to completed status *after* we read the register. + * Setting a IVTV_REG_DMASTATUS flag back to "busy" status, after the + * DMA engine has completed, will cause the DMA engine to stop working. + */ + status &= 0x3; + if (status == 0x3) + write_reg(status, IVTV_REG_DMASTATUS); + if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) && itv->cur_dma_stream >= 0 && itv->cur_dma_stream < IVTV_MAX_STREAMS) { struct ivtv_stream *s = &itv->streams[itv->cur_dma_stream]; - /* retry */ - if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) + if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) { + /* retry */ + /* + * FIXME - handle cases of DMA error similar to + * encoder below, except conditioned on status & 0x1 + */ ivtv_dma_dec_start(s); - else - ivtv_dma_enc_start(s); - return; + return; + } else { + if ((status & 0x2) == 0) { + /* + * CX2341x Bus Master DMA write is ongoing. + * Reset the timer and let it complete. + */ + itv->dma_timer.expires = + jiffies + msecs_to_jiffies(600); + add_timer(&itv->dma_timer); + return; + } + + if (itv->dma_retries < 3) { + /* + * CX2341x Bus Master DMA write has ended. + * Retry the write, starting with the first + * xfer segment. Just retrying the current + * segment is not sufficient. + */ + s->sg_processed = 0; + itv->dma_retries++; + ivtv_dma_enc_start_xfer(s); + return; + } + /* Too many retries, give up on this one */ + } + } if (test_bit(IVTV_F_I_UDMA, &itv->i_flags)) { ivtv_udma_start(itv); -- cgit v1.2.3 From e3bfeabbf5ba5da7f6cc5d53a83cb7765220c619 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Sat, 26 Feb 2011 02:44:38 -0300 Subject: [media] cx18: Add support for Hauppauge HVR-1600 models with s5h1411 The newest variants of the HVR-1600 have an s5h1411/tda18271 for the digital frontend. Add support for these boards. Thanks to Hauppauge Computer Works for providing sample hardware. [awalls@md.metrocast.net: Changed an additional log message to clarify for the end user that the driver is defaulting to an original HVR-1600 for unknown model numbers.] Signed-off-by: Devin Heitmueller Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-cards.c | 50 +++++++++++++++++++++++++++++++++- drivers/media/video/cx18/cx18-driver.c | 25 +++++++++++++++-- drivers/media/video/cx18/cx18-driver.h | 3 +- drivers/media/video/cx18/cx18-dvb.c | 38 ++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index 87177733cf92..68ad1963f421 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c @@ -95,6 +95,53 @@ static const struct cx18_card cx18_card_hvr1600_esmt = { .i2c = &cx18_i2c_std, }; +static const struct cx18_card cx18_card_hvr1600_s5h1411 = { + .type = CX18_CARD_HVR_1600_S5H1411, + .name = "Hauppauge HVR-1600", + .comment = "Simultaneous Digital and Analog TV capture supported\n", + .v4l2_capabilities = CX18_CAP_ENCODER, + .hw_audio_ctrl = CX18_HW_418_AV, + .hw_muxer = CX18_HW_CS5345, + .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER | + CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL | + CX18_HW_Z8F0811_IR_HAUP, + .video_inputs = { + { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 }, + { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 }, + { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 }, + { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 }, + { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 }, + }, + .audio_inputs = { + { CX18_CARD_INPUT_AUD_TUNER, + CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, + { CX18_CARD_INPUT_LINE_IN1, + CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 }, + { CX18_CARD_INPUT_LINE_IN2, + CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 }, + }, + .radio_input = { CX18_CARD_INPUT_AUD_TUNER, + CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 }, + .ddr = { + /* ESMT M13S128324A-5B memory */ + .chip_config = 0x003, + .refresh = 0x30c, + .timing1 = 0x44220e82, + .timing2 = 0x08, + .tune_lane = 0, + .initial_emrs = 0, + }, + .gpio_init.initial_value = 0x3001, + .gpio_init.direction = 0x3001, + .gpio_i2c_slave_reset = { + .active_lo_mask = 0x3001, + .msecs_asserted = 10, + .msecs_recovery = 40, + .ir_reset_mask = 0x0001, + }, + .i2c = &cx18_i2c_std, +}; + static const struct cx18_card cx18_card_hvr1600_samsung = { .type = CX18_CARD_HVR_1600_SAMSUNG, .name = "Hauppauge HVR-1600 (Preproduction)", @@ -523,7 +570,8 @@ static const struct cx18_card *cx18_card_list[] = { &cx18_card_toshiba_qosmio_dvbt, &cx18_card_leadtek_pvr2100, &cx18_card_leadtek_dvr3100h, - &cx18_card_gotview_dvd3 + &cx18_card_gotview_dvd3, + &cx18_card_hvr1600_s5h1411 }; const struct cx18_card *cx18_get_card(u16 index) diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 944af8adbe0c..b1c3cbd92743 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -157,6 +157,7 @@ MODULE_PARM_DESC(cardtype, "\t\t\t 7 = Leadtek WinFast PVR2100\n" "\t\t\t 8 = Leadtek WinFast DVR3100 H\n" "\t\t\t 9 = GoTView PCI DVD3 Hybrid\n" + "\t\t\t 10 = Hauppauge HVR 1600 (S5H1411)\n" "\t\t\t 0 = Autodetect (default)\n" "\t\t\t-1 = Ignore this card\n\t\t"); MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60"); @@ -337,6 +338,7 @@ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv) switch (cx->card->type) { case CX18_CARD_HVR_1600_ESMT: case CX18_CARD_HVR_1600_SAMSUNG: + case CX18_CARD_HVR_1600_S5H1411: tveeprom_hauppauge_analog(&c, tv, eedata); break; case CX18_CARD_YUAN_MPC718: @@ -365,7 +367,25 @@ static void cx18_process_eeprom(struct cx18 *cx) from the model number. Use the cardtype module option if you have one of these preproduction models. */ switch (tv.model) { - case 74000 ... 74999: + case 74301: /* Retail models */ + case 74321: + case 74351: /* OEM models */ + case 74361: + /* Digital side is s5h1411/tda18271 */ + cx->card = cx18_get_card(CX18_CARD_HVR_1600_S5H1411); + break; + case 74021: /* Retail models */ + case 74031: + case 74041: + case 74141: + case 74541: /* OEM models */ + case 74551: + case 74591: + case 74651: + case 74691: + case 74751: + case 74891: + /* Digital side is s5h1409/mxl5005s */ cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); break; case 0x718: @@ -377,7 +397,8 @@ static void cx18_process_eeprom(struct cx18 *cx) CX18_ERR("Invalid EEPROM\n"); return; default: - CX18_ERR("Unknown model %d, defaulting to HVR-1600\n", tv.model); + CX18_ERR("Unknown model %d, defaulting to original HVR-1600 " + "(cardtype=1)\n", tv.model); cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); break; } diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index 306caac6d3fc..f736679d2517 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -85,7 +85,8 @@ #define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */ #define CX18_CARD_LEADTEK_DVR3100H 7 /* Leadtek WinFast DVR3100 H */ #define CX18_CARD_GOTVIEW_PCI_DVD3 8 /* GoTView PCI DVD3 Hybrid */ -#define CX18_CARD_LAST 8 +#define CX18_CARD_HVR_1600_S5H1411 9 /* Hauppauge HVR 1600 s5h1411/tda18271*/ +#define CX18_CARD_LAST 9 #define CX18_ENC_STREAM_TYPE_MPG 0 #define CX18_ENC_STREAM_TYPE_TS 1 diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c index f0381d62518d..f41922bd4020 100644 --- a/drivers/media/video/cx18/cx18-dvb.c +++ b/drivers/media/video/cx18/cx18-dvb.c @@ -29,6 +29,8 @@ #include "cx18-gpio.h" #include "s5h1409.h" #include "mxl5005s.h" +#include "s5h1411.h" +#include "tda18271.h" #include "zl10353.h" #include @@ -76,6 +78,32 @@ static struct s5h1409_config hauppauge_hvr1600_config = { .hvr1600_opt = S5H1409_HVR1600_OPTIMIZE }; +/* + * CX18_CARD_HVR_1600_S5H1411 + */ +static struct s5h1411_config hcw_s5h1411_config = { + .output_mode = S5H1411_SERIAL_OUTPUT, + .gpio = S5H1411_GPIO_OFF, + .vsb_if = S5H1411_IF_44000, + .qam_if = S5H1411_IF_4000, + .inversion = S5H1411_INVERSION_ON, + .status_mode = S5H1411_DEMODLOCKING, + .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, +}; + +static struct tda18271_std_map hauppauge_tda18271_std_map = { + .atsc_6 = { .if_freq = 5380, .agc_mode = 3, .std = 3, + .if_lvl = 6, .rfagc_top = 0x37 }, + .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0, + .if_lvl = 6, .rfagc_top = 0x37 }, +}; + +static struct tda18271_config hauppauge_tda18271_config = { + .std_map = &hauppauge_tda18271_std_map, + .gate = TDA18271_GATE_DIGITAL, + .output_opt = TDA18271_OUTPUT_LT_OFF, +}; + /* * CX18_CARD_LEADTEK_DVR3100H */ @@ -244,6 +272,7 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) switch (cx->card->type) { case CX18_CARD_HVR_1600_ESMT: case CX18_CARD_HVR_1600_SAMSUNG: + case CX18_CARD_HVR_1600_S5H1411: v = cx18_read_reg(cx, CX18_REG_DMUX_NUM_PORT_0_CONTROL); v |= 0x00400000; /* Serial Mode */ v |= 0x00002000; /* Data Length - Byte */ @@ -455,6 +484,15 @@ static int dvb_register(struct cx18_stream *stream) ret = 0; } break; + case CX18_CARD_HVR_1600_S5H1411: + dvb->fe = dvb_attach(s5h1411_attach, + &hcw_s5h1411_config, + &cx->i2c_adap[0]); + if (dvb->fe != NULL) + dvb_attach(tda18271_attach, dvb->fe, + 0x60, &cx->i2c_adap[0], + &hauppauge_tda18271_config); + break; case CX18_CARD_LEADTEK_DVR3100H: dvb->fe = dvb_attach(zl10353_attach, &leadtek_dvr3100h_demod, -- cgit v1.2.3 From 3198ed161c9be9bbd15bb2e9c22561248cac6e6a Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Tue, 1 Mar 2011 12:38:02 -0300 Subject: [media] nuvoton-cir: fix wake from suspend The CIR Wake FIFO is 67 bytes long, but the stock remote appears to only populate 65 of them. Limit comparison to 65 bytes, and wake from suspend works a whole lot better (it wasn't working at all for most folks). Fix based on comparison with the old lirc_wb677 driver from Nuvoton, debugging and testing done by Dave Treacy by way of the lirc mailing list. Reported-by: Dave Treacy Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/nuvoton-cir.c | 5 +++-- drivers/media/rc/nuvoton-cir.h | 7 +++++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 273d9d674792..d4d64492a057 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -385,8 +385,9 @@ static void nvt_cir_regs_init(struct nvt_dev *nvt) static void nvt_cir_wake_regs_init(struct nvt_dev *nvt) { - /* set number of bytes needed for wake key comparison (default 67) */ - nvt_cir_wake_reg_write(nvt, CIR_WAKE_FIFO_LEN, CIR_WAKE_FIFO_CMP_DEEP); + /* set number of bytes needed for wake from s3 (default 65) */ + nvt_cir_wake_reg_write(nvt, CIR_WAKE_FIFO_CMP_BYTES, + CIR_WAKE_FIFO_CMP_DEEP); /* set tolerance/variance allowed per byte during wake compare */ nvt_cir_wake_reg_write(nvt, CIR_WAKE_CMP_TOLERANCE, diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h index 1df82351cb03..048135eea702 100644 --- a/drivers/media/rc/nuvoton-cir.h +++ b/drivers/media/rc/nuvoton-cir.h @@ -305,8 +305,11 @@ struct nvt_dev { #define CIR_WAKE_IRFIFOSTS_RX_EMPTY 0x20 #define CIR_WAKE_IRFIFOSTS_RX_FULL 0x10 -/* CIR Wake FIFO buffer is 67 bytes long */ -#define CIR_WAKE_FIFO_LEN 67 +/* + * The CIR Wake FIFO buffer is 67 bytes long, but the stock remote wakes + * the system comparing only 65 bytes (fails with this set to 67) + */ +#define CIR_WAKE_FIFO_CMP_BYTES 65 /* CIR Wake byte comparison tolerance */ #define CIR_WAKE_CMP_TOLERANCE 5 -- cgit v1.2.3 From a6994eb0a706bf36bcb3b5f7e439c5b76c31cfe5 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Tue, 1 Mar 2011 12:38:28 -0300 Subject: [media] mceusb: don't claim multifunction device non-IR parts There's a Realtek combo card reader and IR receiver device with multiple usb interfaces on it. The mceusb driver is incorrectly grabbing all of them. This change should make it bind to only interface 2 (patch based on lsusb output on the linux-media list from Lucian Muresan). Tested regression-free with the six mceusb devices I have myself. Reported-by: Patrick Boettcher Reported-by: Lucian Muresan Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/mceusb.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 6df0a4980645..e4f8eac7f717 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -148,6 +148,7 @@ enum mceusb_model_type { MCE_GEN2_TX_INV, POLARIS_EVK, CX_HYBRID_TV, + MULTIFUNCTION, }; struct mceusb_model { @@ -155,9 +156,10 @@ struct mceusb_model { u32 mce_gen2:1; u32 mce_gen3:1; u32 tx_mask_normal:1; - u32 is_polaris:1; u32 no_tx:1; + int ir_intfnum; + const char *rc_map; /* Allow specify a per-board map */ const char *name; /* per-board name */ }; @@ -179,7 +181,6 @@ static const struct mceusb_model mceusb_model[] = { .tx_mask_normal = 1, }, [POLARIS_EVK] = { - .is_polaris = 1, /* * In fact, the EVK is shipped without * remotes, but we should have something handy, @@ -189,10 +190,13 @@ static const struct mceusb_model mceusb_model[] = { .name = "Conexant Hybrid TV (cx231xx) MCE IR", }, [CX_HYBRID_TV] = { - .is_polaris = 1, .no_tx = 1, /* tx isn't wired up at all */ .name = "Conexant Hybrid TV (cx231xx) MCE IR", }, + [MULTIFUNCTION] = { + .mce_gen2 = 1, + .ir_intfnum = 2, + }, }; static struct usb_device_id mceusb_dev_table[] = { @@ -216,8 +220,9 @@ static struct usb_device_id mceusb_dev_table[] = { { USB_DEVICE(VENDOR_PHILIPS, 0x206c) }, /* Philips/Spinel plus IR transceiver for ASUS */ { USB_DEVICE(VENDOR_PHILIPS, 0x2088) }, - /* Realtek MCE IR Receiver */ - { USB_DEVICE(VENDOR_REALTEK, 0x0161) }, + /* Realtek MCE IR Receiver and card reader */ + { USB_DEVICE(VENDOR_REALTEK, 0x0161), + .driver_info = MULTIFUNCTION }, /* SMK/Toshiba G83C0004D410 */ { USB_DEVICE(VENDOR_SMK, 0x031d), .driver_info = MCE_GEN2_TX_INV }, @@ -1101,7 +1106,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, bool is_gen3; bool is_microsoft_gen1; bool tx_mask_normal; - bool is_polaris; + int ir_intfnum; dev_dbg(&intf->dev, "%s called\n", __func__); @@ -1110,13 +1115,11 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, is_gen3 = mceusb_model[model].mce_gen3; is_microsoft_gen1 = mceusb_model[model].mce_gen1; tx_mask_normal = mceusb_model[model].tx_mask_normal; - is_polaris = mceusb_model[model].is_polaris; + ir_intfnum = mceusb_model[model].ir_intfnum; - if (is_polaris) { - /* Interface 0 is IR */ - if (idesc->desc.bInterfaceNumber) - return -ENODEV; - } + /* There are multi-function devices with non-IR interfaces */ + if (idesc->desc.bInterfaceNumber != ir_intfnum) + return -ENODEV; /* step through the endpoints to find first bulk in and out endpoint */ for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { -- cgit v1.2.3 From 89a8969afa300c202066c23cc5cc9e42eb81967c Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Tue, 1 Mar 2011 12:38:48 -0300 Subject: [media] tda829x: fix regression in probe functions In commit 567aba0b7997dad5fe3fb4aeb174ee9018df8c5b, the probe address for tda8290_probe and tda8295_probe was hard-coded to 0x4b, which is the default i2c address for those devices, but its possible for the device to be at an alternate address, 0x42, which is the case for the HVR-1950. If we probe the wrong address, probe fails and we have a non-working device. We have the actual address passed into the function by way of i2c_props, we just need to use it. Also fix up some copy/paste comment issues and streamline debug spew a touch. Verified to restore my HVR-1950 to full working order. Special thanks to Ken Bass for reporting the issue in the first place, and to both he and Gary Buhrmaster for aiding in debugging and analysis of the problem. Reported-by: Ken Bass Tested-by: Jarod Wilson Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda8290.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c index bc6a67768af1..8c4852114eeb 100644 --- a/drivers/media/common/tuners/tda8290.c +++ b/drivers/media/common/tuners/tda8290.c @@ -658,13 +658,13 @@ static int tda8290_probe(struct tuner_i2c_props *i2c_props) #define TDA8290_ID 0x89 u8 reg = 0x1f, id; struct i2c_msg msg_read[] = { - { .addr = 0x4b, .flags = 0, .len = 1, .buf = ® }, - { .addr = 0x4b, .flags = I2C_M_RD, .len = 1, .buf = &id }, + { .addr = i2c_props->addr, .flags = 0, .len = 1, .buf = ® }, + { .addr = i2c_props->addr, .flags = I2C_M_RD, .len = 1, .buf = &id }, }; /* detect tda8290 */ if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) { - printk(KERN_WARNING "%s: tda8290 couldn't read register 0x%02x\n", + printk(KERN_WARNING "%s: couldn't read register 0x%02x\n", __func__, reg); return -ENODEV; } @@ -685,13 +685,13 @@ static int tda8295_probe(struct tuner_i2c_props *i2c_props) #define TDA8295C2_ID 0x8b u8 reg = 0x2f, id; struct i2c_msg msg_read[] = { - { .addr = 0x4b, .flags = 0, .len = 1, .buf = ® }, - { .addr = 0x4b, .flags = I2C_M_RD, .len = 1, .buf = &id }, + { .addr = i2c_props->addr, .flags = 0, .len = 1, .buf = ® }, + { .addr = i2c_props->addr, .flags = I2C_M_RD, .len = 1, .buf = &id }, }; - /* detect tda8290 */ + /* detect tda8295 */ if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) { - printk(KERN_WARNING "%s: tda8290 couldn't read register 0x%02x\n", + printk(KERN_WARNING "%s: couldn't read register 0x%02x\n", __func__, reg); return -ENODEV; } -- cgit v1.2.3 From 337fc720d85b98a71b1ff6e3a5449a24a7c33cfe Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 14 Feb 2011 11:40:09 +0100 Subject: of: Add missing of_address.h to xilinx ehci driver Build log: In file included from drivers/usb/host/ehci-hcd.c:1208: drivers/usb/host/ehci-xilinx-of.c: In function 'ehci_hcd_xilinx_of_probe': drivers/usb/host/ehci-xilinx-of.c:168: error: implicit declaration of function 'of_address_to_resource' Signed-off-by: John Williams Signed-off-by: Michal Simek Acked-by: Greg Kroah-Hartman Signed-off-by: Grant Likely --- drivers/usb/host/ehci-xilinx-of.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index e8f4f36fdf0b..a6f21b891f68 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c @@ -29,6 +29,7 @@ #include #include +#include /** * ehci_xilinx_of_setup - Initialize the device for ehci_reset() -- cgit v1.2.3 From a74ea43df1afc68f265c0ac2cb64031d855ae97b Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Wed, 23 Feb 2011 22:38:22 -0800 Subject: of/promtree: allow DT device matching by fixing 'name' brokenness (v5) Commit e2f2a93b, "of/promtree: add package-to-path support to pdt" changed dp->name from using the 'name' property to using package-to-path. This fixed /proc/device-tree creation by eliminating conflicts between names (the 'name' property provides names like 'battery', whereas package-to-path provides names like '/foo/bar/battery@0', which we stripped to 'battery@0'). However, it also breaks of_device_id table matching. The fix that we _really_ wanted was to keep dp->name based upon the name property ('battery'), but based dp->full_name upon package-to-path ('battery@0'). This patch does just that. This changes all users (except SPARC) of promtree to use the full result from package-to-path for full_name, rather than stripping the directory out. In practice, the strings end up being exactly the same; this change saves time, code, and memory. SPARC continues to use the existing build_path_component() code. v2: combine two patches and revert of_pdt_node_name to original version v3: use dp->phandle instead of passing around node v4: warn/bail out for non-sparc archs if pkg2path is not set v5: split of_pdt_build_full_name into sparc & non-sparc versions v6: Pass NULL to pkg2path before buf gets assigned. Drop check for pkg2path hook on each and every node. v7: Don't BUG() when unable to get the full_path; create a known-unique name instead. Signed-off-by: Andres Salomon Signed-off-by: Grant Likely --- drivers/of/pdt.c | 112 +++++++++++++++++++++---------------------------------- 1 file changed, 42 insertions(+), 70 deletions(-) (limited to 'drivers') diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c index 28295d0a50f6..4d87b5dc9284 100644 --- a/drivers/of/pdt.c +++ b/drivers/of/pdt.c @@ -36,19 +36,55 @@ unsigned int of_pdt_unique_id __initdata; (p)->unique_id = of_pdt_unique_id++; \ } while (0) -static inline const char *of_pdt_node_name(struct device_node *dp) +static char * __init of_pdt_build_full_name(struct device_node *dp) { - return dp->path_component_name; + int len, ourlen, plen; + char *n; + + dp->path_component_name = build_path_component(dp); + + plen = strlen(dp->parent->full_name); + ourlen = strlen(dp->path_component_name); + len = ourlen + plen + 2; + + n = prom_early_alloc(len); + strcpy(n, dp->parent->full_name); + if (!of_node_is_root(dp->parent)) { + strcpy(n + plen, "/"); + plen++; + } + strcpy(n + plen, dp->path_component_name); + + return n; } -#else +#else /* CONFIG_SPARC */ static inline void of_pdt_incr_unique_id(void *p) { } static inline void irq_trans_init(struct device_node *dp) { } -static inline const char *of_pdt_node_name(struct device_node *dp) +static char * __init of_pdt_build_full_name(struct device_node *dp) { - return dp->name; + static int failsafe_id = 0; /* for generating unique names on failure */ + char *buf; + int len; + + if (of_pdt_prom_ops->pkg2path(dp->phandle, NULL, 0, &len)) + goto failsafe; + + buf = prom_early_alloc(len + 1); + if (of_pdt_prom_ops->pkg2path(dp->phandle, buf, len, &len)) + goto failsafe; + return buf; + + failsafe: + buf = prom_early_alloc(strlen(dp->parent->full_name) + + strlen(dp->name) + 16); + sprintf(buf, "%s/%s@unknown%i", + of_node_is_root(dp->parent) ? "" : dp->parent->full_name, + dp->name, failsafe_id++); + pr_err("%s: pkg2path failed; assigning %s\n", __func__, buf); + return buf; } #endif /* !CONFIG_SPARC */ @@ -132,47 +168,6 @@ static char * __init of_pdt_get_one_property(phandle node, const char *name) return buf; } -static char * __init of_pdt_try_pkg2path(phandle node) -{ - char *res, *buf = NULL; - int len; - - if (!of_pdt_prom_ops->pkg2path) - return NULL; - - if (of_pdt_prom_ops->pkg2path(node, buf, 0, &len)) - return NULL; - buf = prom_early_alloc(len + 1); - if (of_pdt_prom_ops->pkg2path(node, buf, len, &len)) { - pr_err("%s: package-to-path failed\n", __func__); - return NULL; - } - - res = strrchr(buf, '/'); - if (!res) { - pr_err("%s: couldn't find / in %s\n", __func__, buf); - return NULL; - } - return res+1; -} - -/* - * When fetching the node's name, first try using package-to-path; if - * that fails (either because the arch hasn't supplied a PROM callback, - * or some other random failure), fall back to just looking at the node's - * 'name' property. - */ -static char * __init of_pdt_build_name(phandle node) -{ - char *buf; - - buf = of_pdt_try_pkg2path(node); - if (!buf) - buf = of_pdt_get_one_property(node, "name"); - - return buf; -} - static struct device_node * __init of_pdt_create_node(phandle node, struct device_node *parent) { @@ -187,7 +182,7 @@ static struct device_node * __init of_pdt_create_node(phandle node, kref_init(&dp->kref); - dp->name = of_pdt_build_name(node); + dp->name = of_pdt_get_one_property(node, "name"); dp->type = of_pdt_get_one_property(node, "device_type"); dp->phandle = node; @@ -198,26 +193,6 @@ static struct device_node * __init of_pdt_create_node(phandle node, return dp; } -static char * __init of_pdt_build_full_name(struct device_node *dp) -{ - int len, ourlen, plen; - char *n; - - plen = strlen(dp->parent->full_name); - ourlen = strlen(of_pdt_node_name(dp)); - len = ourlen + plen + 2; - - n = prom_early_alloc(len); - strcpy(n, dp->parent->full_name); - if (!of_node_is_root(dp->parent)) { - strcpy(n + plen, "/"); - plen++; - } - strcpy(n + plen, of_pdt_node_name(dp)); - - return n; -} - static struct device_node * __init of_pdt_build_tree(struct device_node *parent, phandle node, struct device_node ***nextp) @@ -240,9 +215,6 @@ static struct device_node * __init of_pdt_build_tree(struct device_node *parent, *(*nextp) = dp; *nextp = &dp->allnext; -#if defined(CONFIG_SPARC) - dp->path_component_name = build_path_component(dp); -#endif dp->full_name = of_pdt_build_full_name(dp); dp->child = of_pdt_build_tree(dp, -- cgit v1.2.3 From f9cfbe943c05df341930befb272902230c4087fc Mon Sep 17 00:00:00 2001 From: Philip Worrall Date: Wed, 2 Mar 2011 14:34:39 +0000 Subject: Staging: vt6656: Ensure power.c uses proper tabbing. Cleanup power.c to use proper tabbing as per coding standards. Signed-off-by: Philip Worrall Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/power.c | 416 ++++++++++++++++++++--------------------- 1 file changed, 201 insertions(+), 215 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c index e8c1b35e8128..d85145ff18c5 100644 --- a/drivers/staging/vt6656/power.c +++ b/drivers/staging/vt6656/power.c @@ -53,7 +53,7 @@ /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Functions --------------------------*/ /*--------------------- Export Variables --------------------------*/ @@ -73,61 +73,64 @@ static int msglevel =MSG_LEVEL_INFO; void PSvEnablePowerSaving(void *hDeviceContext, WORD wListenInterval) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - WORD wAID = pMgmt->wCurrAID | BIT14 | BIT15; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + WORD wAID = pMgmt->wCurrAID | BIT14 | BIT15; - /* set period of power up before TBTT */ - MACvWriteWord(pDevice, MAC_REG_PWBT, C_PWBT); + /* set period of power up before TBTT */ + MACvWriteWord(pDevice, MAC_REG_PWBT, C_PWBT); - if (pDevice->eOPMode != OP_MODE_ADHOC) { - /* set AID */ - MACvWriteWord(pDevice, MAC_REG_AIDATIM, wAID); - } else { - // set ATIM Window - //MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow); - } + if (pDevice->eOPMode != OP_MODE_ADHOC) { + /* set AID */ + MACvWriteWord(pDevice, MAC_REG_AIDATIM, wAID); + } else { + // set ATIM Window + //MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow); + } - //Warren:06-18-2004,the sequence must follow PSEN->AUTOSLEEP->GO2DOZE - // enable power saving hw function - MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_PSEN); - // Set AutoSleep - MACvRegBitsOn(pDevice, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); + //Warren:06-18-2004,the sequence must follow PSEN->AUTOSLEEP->GO2DOZE + // enable power saving hw function + MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_PSEN); - //Warren:MUST turn on this once before turn on AUTOSLEEP ,or the AUTOSLEEP doesn't work - MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_GO2DOZE); + // Set AutoSleep + MACvRegBitsOn(pDevice, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); + //Warren:MUST turn on this once before turn on AUTOSLEEP ,or the AUTOSLEEP doesn't work + MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_GO2DOZE); - if (wListenInterval >= 2) { + if (wListenInterval >= 2) { - // clear always listen beacon - MACvRegBitsOff(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN); - // first time set listen next beacon - MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN); + // clear always listen beacon + MACvRegBitsOff(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN); - pMgmt->wCountToWakeUp = wListenInterval; + // first time set listen next beacon + MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN); - } - else { + pMgmt->wCountToWakeUp = wListenInterval; - // always listen beacon - MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN); - pMgmt->wCountToWakeUp = 0; + } else { - } + // always listen beacon + MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN); - pDevice->bEnablePSMode = TRUE; + pMgmt->wCountToWakeUp = 0; + } + + pDevice->bEnablePSMode = TRUE; + + if (pDevice->eOPMode == OP_MODE_ADHOC) { - if (pDevice->eOPMode == OP_MODE_ADHOC) { /* bMgrPrepareBeaconToSend((void *) pDevice, pMgmt); */ - } - // We don't send null pkt in ad hoc mode since beacon will handle this. - else if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) { - PSbSendNullPacket(pDevice); - } - pDevice->bPWBitOn = TRUE; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable... \n"); - return; + + } + // We don't send null pkt in ad hoc mode since beacon will handle this. + else if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) { + PSbSendNullPacket(pDevice); + } + + pDevice->bPWBitOn = TRUE; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable... \n"); + return; } /*+ @@ -142,32 +145,26 @@ void PSvEnablePowerSaving(void *hDeviceContext, void PSvDisablePowerSaving(void *hDeviceContext) { - PSDevice pDevice = (PSDevice)hDeviceContext; -// PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSDevice pDevice = (PSDevice)hDeviceContext; + //PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + // disable power saving hw function + CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_DISABLE_PS, 0, + 0, 0, NULL); - // disable power saving hw function - CONTROLnsRequestOut(pDevice, - MESSAGE_TYPE_DISABLE_PS, - 0, - 0, - 0, - NULL - ); + //clear AutoSleep + MACvRegBitsOff(pDevice, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); - //clear AutoSleep - MACvRegBitsOff(pDevice, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); + // set always listen beacon + MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN); + pDevice->bEnablePSMode = FALSE; - // set always listen beacon - MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN); + if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) { + PSbSendNullPacket(pDevice); + } - pDevice->bEnablePSMode = FALSE; - - if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) { - PSbSendNullPacket(pDevice); - } - pDevice->bPWBitOn = FALSE; - return; + pDevice->bPWBitOn = FALSE; + return; } /*+ @@ -184,46 +181,47 @@ BOOL PSbConsiderPowerDown(void *hDeviceContext, BOOL bCheckRxDMA, BOOL bCheckCountToWakeUp) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - BYTE byData; - - - // check if already in Doze mode - ControlvReadByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PSCTL, &byData); - if ( (byData & PSCTL_PS) != 0 ) - return TRUE; - - if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { - // check if in TIM wake period - if (pMgmt->bInTIMWake) - return FALSE; - } - - // check scan state - if (pDevice->bCmdRunning) - return FALSE; - - //Tx Burst - if ( pDevice->bPSModeTxBurst ) - return FALSE; - - // Froce PSEN on - MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_PSEN); - - if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { - if (bCheckCountToWakeUp && - (pMgmt->wCountToWakeUp == 0 || pMgmt->wCountToWakeUp == 1)) { - return FALSE; - } - } - - pDevice->bPSRxBeacon = TRUE; - // no Tx, no Rx isr, now go to Doze - MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_GO2DOZE); - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Go to Doze ZZZZZZZZZZZZZZZ\n"); - return TRUE; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + BYTE byData; + + // check if already in Doze mode + ControlvReadByte(pDevice, MESSAGE_REQUEST_MACREG, + MAC_REG_PSCTL, &byData); + + if ( (byData & PSCTL_PS) != 0 ) + return TRUE; + + if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { + // check if in TIM wake period + if (pMgmt->bInTIMWake) + return FALSE; + } + + // check scan state + if (pDevice->bCmdRunning) + return FALSE; + + //Tx Burst + if ( pDevice->bPSModeTxBurst ) + return FALSE; + + // Froce PSEN on + MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_PSEN); + + if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { + if (bCheckCountToWakeUp && (pMgmt->wCountToWakeUp == 0 + || pMgmt->wCountToWakeUp == 1)) { + return FALSE; + } + } + + pDevice->bPSRxBeacon = TRUE; + + // no Tx, no Rx isr, now go to Doze + MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_GO2DOZE); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Go to Doze ZZZZZZZZZZZZZZZ\n"); + return TRUE; } /*+ @@ -238,34 +236,33 @@ BOOL PSbConsiderPowerDown(void *hDeviceContext, void PSvSendPSPOLL(void *hDeviceContext) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - PSTxMgmtPacket pTxPacket = NULL; - - - memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_HDR_ADDR2_LEN); - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool; - pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket)); - pTxPacket->p80211Header->sA2.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_CTL) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PSPOLL) | - WLAN_SET_FC_PWRMGT(0) - )); - pTxPacket->p80211Header->sA2.wDurationID = pMgmt->wCurrAID | BIT14 | BIT15; - memcpy(pTxPacket->p80211Header->sA2.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); - memcpy(pTxPacket->p80211Header->sA2.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - pTxPacket->cbMPDULen = WLAN_HDR_ADDR2_LEN; - pTxPacket->cbPayloadLen = 0; - // send the frame - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet failed..\n"); - } - else { -// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet success..\n"); - }; - - return; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + PSTxMgmtPacket pTxPacket = NULL; + + memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_HDR_ADDR2_LEN); + pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool; + pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket)); + pTxPacket->p80211Header->sA2.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_CTL) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PSPOLL) | + WLAN_SET_FC_PWRMGT(0) + )); + + pTxPacket->p80211Header->sA2.wDurationID = pMgmt->wCurrAID | BIT14 | BIT15; + memcpy(pTxPacket->p80211Header->sA2.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); + memcpy(pTxPacket->p80211Header->sA2.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); + pTxPacket->cbMPDULen = WLAN_HDR_ADDR2_LEN; + pTxPacket->cbPayloadLen = 0; + + // send the frame + if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet failed..\n"); + } else { + // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet success..\n"); + }; + return; } /*+ @@ -280,63 +277,57 @@ void PSvSendPSPOLL(void *hDeviceContext) BOOL PSbSendNullPacket(void *hDeviceContext) { - PSDevice pDevice = (PSDevice)hDeviceContext; - PSTxMgmtPacket pTxPacket = NULL; - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - - - - if (pDevice->bLinkPass == FALSE) { - return FALSE; - } - - if ((pDevice->bEnablePSMode == FALSE) && - (pDevice->fTxDataInSleep == FALSE)){ - return FALSE; - } - - memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN); - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool; - pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket)); - - if (pDevice->bEnablePSMode) { - - pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) | - WLAN_SET_FC_PWRMGT(1) - )); - } - else { - pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) | - WLAN_SET_FC_PWRMGT(0) - )); - } - - if(pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { - pTxPacket->p80211Header->sA3.wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_TODS(1)); - } - - memcpy(pTxPacket->p80211Header->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); - memcpy(pTxPacket->p80211Header->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - memcpy(pTxPacket->p80211Header->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - pTxPacket->cbMPDULen = WLAN_HDR_ADDR3_LEN; - pTxPacket->cbPayloadLen = 0; - // send the frame - if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet failed !\n"); - return FALSE; - } - else { -// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet success....\n"); - } - - - return TRUE ; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSTxMgmtPacket pTxPacket = NULL; + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + + if (pDevice->bLinkPass == FALSE) { + return FALSE; + } + + if ((pDevice->bEnablePSMode == FALSE) && + (pDevice->fTxDataInSleep == FALSE)){ + return FALSE; + } + + memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN); + pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool; + pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket)); + + if (pDevice->bEnablePSMode) { + pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) | + WLAN_SET_FC_PWRMGT(1) + )); + } else { + pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16( + ( + WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) | + WLAN_SET_FC_PWRMGT(0) + )); + } + + if(pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { + pTxPacket->p80211Header->sA3.wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_TODS(1)); + } + + memcpy(pTxPacket->p80211Header->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); + memcpy(pTxPacket->p80211Header->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); + memcpy(pTxPacket->p80211Header->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + pTxPacket->cbMPDULen = WLAN_HDR_ADDR3_LEN; + pTxPacket->cbPayloadLen = 0; + // send the frame + if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet failed !\n"); + return FALSE; + } else { + // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet success....\n"); + } + + return TRUE ; } /*+ @@ -351,32 +342,27 @@ BOOL PSbSendNullPacket(void *hDeviceContext) BOOL PSbIsNextTBTTWakeUp(void *hDeviceContext) { - - PSDevice pDevice = (PSDevice)hDeviceContext; - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - BOOL bWakeUp = FALSE; - - if (pMgmt->wListenInterval >= 2) { - if (pMgmt->wCountToWakeUp == 0) { - pMgmt->wCountToWakeUp = pMgmt->wListenInterval; - } - - pMgmt->wCountToWakeUp --; - - if (pMgmt->wCountToWakeUp == 1) { - - // Turn on wake up to listen next beacon - MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN); - pDevice->bPSRxBeacon = FALSE; - bWakeUp = TRUE; - - } else if ( !pDevice->bPSRxBeacon ) { - //Listen until RxBeacon - MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN); - } - - } - - return bWakeUp; + PSDevice pDevice = (PSDevice)hDeviceContext; + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + BOOL bWakeUp = FALSE; + + if (pMgmt->wListenInterval >= 2) { + if (pMgmt->wCountToWakeUp == 0) { + pMgmt->wCountToWakeUp = pMgmt->wListenInterval; + } + + pMgmt->wCountToWakeUp --; + + if (pMgmt->wCountToWakeUp == 1) { + // Turn on wake up to listen next beacon + MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN); + pDevice->bPSRxBeacon = FALSE; + bWakeUp = TRUE; + } else if ( !pDevice->bPSRxBeacon ) { + //Listen until RxBeacon + MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN); + } + } + return bWakeUp; } -- cgit v1.2.3 From 7404eab294f3275233ceaa592e029bf41601ab78 Mon Sep 17 00:00:00 2001 From: Philip Worrall Date: Wed, 2 Mar 2011 14:34:40 +0000 Subject: Staging: vt6656: Use C89 comments in power.c Reformat the comments in power.c to use the C89 commenting style instead of the C99 commenting style. Signed-off-by: Philip Worrall Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/power.c | 76 +++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c index d85145ff18c5..fefd8e4e8a30 100644 --- a/drivers/staging/vt6656/power.c +++ b/drivers/staging/vt6656/power.c @@ -60,7 +60,7 @@ static int msglevel = MSG_LEVEL_INFO; /*--------------------- Export Functions --------------------------*/ -/*+ +/* * * Routine Description: * Enable hw power saving functions @@ -68,7 +68,7 @@ static int msglevel = MSG_LEVEL_INFO; * Return Value: * None. * --*/ + */ void PSvEnablePowerSaving(void *hDeviceContext, WORD wListenInterval) @@ -84,33 +84,33 @@ void PSvEnablePowerSaving(void *hDeviceContext, /* set AID */ MACvWriteWord(pDevice, MAC_REG_AIDATIM, wAID); } else { - // set ATIM Window - //MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow); + /* set ATIM Window */ + /* MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow); */ } - //Warren:06-18-2004,the sequence must follow PSEN->AUTOSLEEP->GO2DOZE - // enable power saving hw function + /* Warren:06-18-2004,the sequence must follow PSEN->AUTOSLEEP->GO2DOZE */ + /* enable power saving hw function */ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_PSEN); - // Set AutoSleep + /* Set AutoSleep */ MACvRegBitsOn(pDevice, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); - //Warren:MUST turn on this once before turn on AUTOSLEEP ,or the AUTOSLEEP doesn't work + /* Warren:MUST turn on this once before turn on AUTOSLEEP ,or the AUTOSLEEP doesn't work */ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_GO2DOZE); if (wListenInterval >= 2) { - // clear always listen beacon + /* clear always listen beacon */ MACvRegBitsOff(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN); - // first time set listen next beacon + /* first time set listen next beacon */ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN); pMgmt->wCountToWakeUp = wListenInterval; } else { - // always listen beacon + /* always listen beacon */ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN); pMgmt->wCountToWakeUp = 0; @@ -123,7 +123,7 @@ void PSvEnablePowerSaving(void *hDeviceContext, /* bMgrPrepareBeaconToSend((void *) pDevice, pMgmt); */ } - // We don't send null pkt in ad hoc mode since beacon will handle this. + /* We don't send null pkt in ad hoc mode since beacon will handle this. */ else if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) { PSbSendNullPacket(pDevice); } @@ -133,7 +133,7 @@ void PSvEnablePowerSaving(void *hDeviceContext, return; } -/*+ +/* * * Routine Description: * Disable hw power saving functions @@ -141,21 +141,21 @@ void PSvEnablePowerSaving(void *hDeviceContext, * Return Value: * None. * --*/ + */ void PSvDisablePowerSaving(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; - //PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + /* PSMgmtObject pMgmt = &(pDevice->sMgmtObj); */ - // disable power saving hw function + /* disable power saving hw function */ CONTROLnsRequestOut(pDevice, MESSAGE_TYPE_DISABLE_PS, 0, 0, 0, NULL); - //clear AutoSleep + /* clear AutoSleep */ MACvRegBitsOff(pDevice, MAC_REG_PSCFG, PSCFG_AUTOSLEEP); - // set always listen beacon + /* set always listen beacon */ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN); pDevice->bEnablePSMode = FALSE; @@ -167,7 +167,7 @@ void PSvDisablePowerSaving(void *hDeviceContext) return; } -/*+ +/* * * Routine Description: * Consider to power down when no more packets to tx or rx. @@ -175,7 +175,7 @@ void PSvDisablePowerSaving(void *hDeviceContext) * Return Value: * TRUE, if power down success * FALSE, if fail --*/ + */ BOOL PSbConsiderPowerDown(void *hDeviceContext, BOOL bCheckRxDMA, @@ -185,7 +185,7 @@ BOOL PSbConsiderPowerDown(void *hDeviceContext, PSMgmtObject pMgmt = &(pDevice->sMgmtObj); BYTE byData; - // check if already in Doze mode + /* check if already in Doze mode */ ControlvReadByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PSCTL, &byData); @@ -193,20 +193,20 @@ BOOL PSbConsiderPowerDown(void *hDeviceContext, return TRUE; if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { - // check if in TIM wake period + /* check if in TIM wake period */ if (pMgmt->bInTIMWake) return FALSE; } - // check scan state + /* check scan state */ if (pDevice->bCmdRunning) return FALSE; - //Tx Burst + /* Tx Burst */ if ( pDevice->bPSModeTxBurst ) return FALSE; - // Froce PSEN on + /* Froce PSEN on */ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_PSEN); if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { @@ -218,13 +218,13 @@ BOOL PSbConsiderPowerDown(void *hDeviceContext, pDevice->bPSRxBeacon = TRUE; - // no Tx, no Rx isr, now go to Doze + /* no Tx, no Rx isr, now go to Doze */ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_GO2DOZE); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Go to Doze ZZZZZZZZZZZZZZZ\n"); return TRUE; } -/*+ +/* * * Routine Description: * Send PS-POLL packet @@ -232,7 +232,7 @@ BOOL PSbConsiderPowerDown(void *hDeviceContext, * Return Value: * None. * --*/ + */ void PSvSendPSPOLL(void *hDeviceContext) { @@ -256,16 +256,16 @@ void PSvSendPSPOLL(void *hDeviceContext) pTxPacket->cbMPDULen = WLAN_HDR_ADDR2_LEN; pTxPacket->cbPayloadLen = 0; - // send the frame + /* send the frame */ if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet failed..\n"); } else { - // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet success..\n"); + /* DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet success..\n"); */ }; return; } -/*+ +/* * * Routine Description: * Send NULL packet to AP for notification power state of STA @@ -273,7 +273,7 @@ void PSvSendPSPOLL(void *hDeviceContext) * Return Value: * None. * --*/ + */ BOOL PSbSendNullPacket(void *hDeviceContext) { @@ -319,18 +319,18 @@ BOOL PSbSendNullPacket(void *hDeviceContext) memcpy(pTxPacket->p80211Header->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); pTxPacket->cbMPDULen = WLAN_HDR_ADDR3_LEN; pTxPacket->cbPayloadLen = 0; - // send the frame + /* send the frame */ if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet failed !\n"); return FALSE; } else { - // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet success....\n"); + /* DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet success....\n"); */ } return TRUE ; } -/*+ +/* * * Routine Description: * Check if Next TBTT must wake up @@ -338,7 +338,7 @@ BOOL PSbSendNullPacket(void *hDeviceContext) * Return Value: * None. * --*/ + */ BOOL PSbIsNextTBTTWakeUp(void *hDeviceContext) { @@ -354,12 +354,12 @@ BOOL PSbIsNextTBTTWakeUp(void *hDeviceContext) pMgmt->wCountToWakeUp --; if (pMgmt->wCountToWakeUp == 1) { - // Turn on wake up to listen next beacon + /* Turn on wake up to listen next beacon */ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN); pDevice->bPSRxBeacon = FALSE; bWakeUp = TRUE; } else if ( !pDevice->bPSRxBeacon ) { - //Listen until RxBeacon + /* Listen until RxBeacon */ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN); } } -- cgit v1.2.3 From 036dba14d56fd3d43bab452625ec967c3f886fa4 Mon Sep 17 00:00:00 2001 From: Philip Worrall Date: Wed, 2 Mar 2011 14:34:41 +0000 Subject: Staging: vt6656: Clean up unneccessary braces in power.c Clean up some unnecessary braces for conditional statements where a single statement will do. Signed-off-by: Philip Worrall Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/power.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c index fefd8e4e8a30..942f371eaf67 100644 --- a/drivers/staging/vt6656/power.c +++ b/drivers/staging/vt6656/power.c @@ -159,9 +159,8 @@ void PSvDisablePowerSaving(void *hDeviceContext) MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN); pDevice->bEnablePSMode = FALSE; - if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) { + if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) PSbSendNullPacket(pDevice); - } pDevice->bPWBitOn = FALSE; return; @@ -281,12 +280,11 @@ BOOL PSbSendNullPacket(void *hDeviceContext) PSTxMgmtPacket pTxPacket = NULL; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - if (pDevice->bLinkPass == FALSE) { + if (pDevice->bLinkPass == FALSE) return FALSE; - } if ((pDevice->bEnablePSMode == FALSE) && - (pDevice->fTxDataInSleep == FALSE)){ + (pDevice->fTxDataInSleep == FALSE)) { return FALSE; } @@ -310,9 +308,8 @@ BOOL PSbSendNullPacket(void *hDeviceContext) )); } - if(pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { + if(pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) pTxPacket->p80211Header->sA3.wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_TODS(1)); - } memcpy(pTxPacket->p80211Header->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); memcpy(pTxPacket->p80211Header->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); @@ -347,9 +344,8 @@ BOOL PSbIsNextTBTTWakeUp(void *hDeviceContext) BOOL bWakeUp = FALSE; if (pMgmt->wListenInterval >= 2) { - if (pMgmt->wCountToWakeUp == 0) { + if (pMgmt->wCountToWakeUp == 0) pMgmt->wCountToWakeUp = pMgmt->wListenInterval; - } pMgmt->wCountToWakeUp --; -- cgit v1.2.3 From e25b75ec83ec1d76690a9f26d457d2af945119d2 Mon Sep 17 00:00:00 2001 From: Philip Worrall Date: Wed, 2 Mar 2011 14:34:42 +0000 Subject: Staging: vt6656: Clean up return from sending power state notifications Clean up power.c so that unnecessary final return statements are not used when sending power state notifications to the access point. Signed-off-by: Philip Worrall Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/power.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c index 942f371eaf67..2cdfa39ed9f9 100644 --- a/drivers/staging/vt6656/power.c +++ b/drivers/staging/vt6656/power.c @@ -130,7 +130,6 @@ void PSvEnablePowerSaving(void *hDeviceContext, pDevice->bPWBitOn = TRUE; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable... \n"); - return; } /* @@ -163,7 +162,6 @@ void PSvDisablePowerSaving(void *hDeviceContext) PSbSendNullPacket(pDevice); pDevice->bPWBitOn = FALSE; - return; } /* @@ -255,13 +253,10 @@ void PSvSendPSPOLL(void *hDeviceContext) pTxPacket->cbMPDULen = WLAN_HDR_ADDR2_LEN; pTxPacket->cbPayloadLen = 0; - /* send the frame */ + /* log failure if sending failed */ if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet failed..\n"); - } else { - /* DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet success..\n"); */ - }; - return; + } } /* @@ -316,15 +311,12 @@ BOOL PSbSendNullPacket(void *hDeviceContext) memcpy(pTxPacket->p80211Header->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); pTxPacket->cbMPDULen = WLAN_HDR_ADDR3_LEN; pTxPacket->cbPayloadLen = 0; - /* send the frame */ + /* log error if sending failed */ if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet failed !\n"); return FALSE; - } else { - /* DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet success....\n"); */ } - - return TRUE ; + return TRUE; } /* -- cgit v1.2.3 From c5b0b5fcdbde44cba6f5069d58aeffae4eec2572 Mon Sep 17 00:00:00 2001 From: Philip Worrall Date: Wed, 2 Mar 2011 14:34:43 +0000 Subject: Staging: vt6656: Clean up spaces around parenthesized expressions Clean up a number of places where unneeded spaces are used around expressions. Signed-off-by: Philip Worrall Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/power.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c index 2cdfa39ed9f9..44dd18954aef 100644 --- a/drivers/staging/vt6656/power.c +++ b/drivers/staging/vt6656/power.c @@ -129,7 +129,7 @@ void PSvEnablePowerSaving(void *hDeviceContext, } pDevice->bPWBitOn = TRUE; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable... \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable...\n"); } /* @@ -186,7 +186,7 @@ BOOL PSbConsiderPowerDown(void *hDeviceContext, ControlvReadByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PSCTL, &byData); - if ( (byData & PSCTL_PS) != 0 ) + if ((byData & PSCTL_PS) != 0) return TRUE; if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { @@ -200,7 +200,7 @@ BOOL PSbConsiderPowerDown(void *hDeviceContext, return FALSE; /* Tx Burst */ - if ( pDevice->bPSModeTxBurst ) + if (pDevice->bPSModeTxBurst) return FALSE; /* Froce PSEN on */ @@ -303,7 +303,7 @@ BOOL PSbSendNullPacket(void *hDeviceContext) )); } - if(pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) + if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) pTxPacket->p80211Header->sA3.wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_TODS(1)); memcpy(pTxPacket->p80211Header->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); @@ -339,14 +339,14 @@ BOOL PSbIsNextTBTTWakeUp(void *hDeviceContext) if (pMgmt->wCountToWakeUp == 0) pMgmt->wCountToWakeUp = pMgmt->wListenInterval; - pMgmt->wCountToWakeUp --; + pMgmt->wCountToWakeUp--; if (pMgmt->wCountToWakeUp == 1) { /* Turn on wake up to listen next beacon */ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN); pDevice->bPSRxBeacon = FALSE; bWakeUp = TRUE; - } else if ( !pDevice->bPSRxBeacon ) { + } else if (!pDevice->bPSRxBeacon) { /* Listen until RxBeacon */ MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN); } -- cgit v1.2.3 From b898cf21ad8cbe7506127b3fa68bcae33273b171 Mon Sep 17 00:00:00 2001 From: Philip Worrall Date: Wed, 2 Mar 2011 17:36:35 +0000 Subject: Staging: vt6656: Ensure power.c uses proper tabbing. Simplify setting of power state in power.c when sending power state notifications to the access point. Signed-off-by: Philip Worrall Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/power.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c index 44dd18954aef..bd9c55c8ef96 100644 --- a/drivers/staging/vt6656/power.c +++ b/drivers/staging/vt6656/power.c @@ -274,6 +274,7 @@ BOOL PSbSendNullPacket(void *hDeviceContext) PSDevice pDevice = (PSDevice)hDeviceContext; PSTxMgmtPacket pTxPacket = NULL; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + u16 flags = 0; if (pDevice->bLinkPass == FALSE) return FALSE; @@ -287,21 +288,15 @@ BOOL PSbSendNullPacket(void *hDeviceContext) pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool; pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket)); - if (pDevice->bEnablePSMode) { - pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) | - WLAN_SET_FC_PWRMGT(1) - )); - } else { - pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16( - ( - WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) | - WLAN_SET_FC_PWRMGT(0) - )); - } + flags = WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL); + + if (pDevice->bEnablePSMode) + flags |= WLAN_SET_FC_PWRMGT(1); + else + flags |= WLAN_SET_FC_PWRMGT(0); + + pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16(flags); if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) pTxPacket->p80211Header->sA3.wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_TODS(1)); -- cgit v1.2.3 From 8c81161615feb8c666c675ec7a660dc9b011683f Mon Sep 17 00:00:00 2001 From: Philip Worrall Date: Wed, 2 Mar 2011 14:34:45 +0000 Subject: Staging: vt6656: Clean up switching to power saving mode. When switching to power saving mode we only need to notify the receiver when in infrastructure mode. Signed-off-by: Philip Worrall Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/power.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c index bd9c55c8ef96..b3136773b5da 100644 --- a/drivers/staging/vt6656/power.c +++ b/drivers/staging/vt6656/power.c @@ -118,15 +118,9 @@ void PSvEnablePowerSaving(void *hDeviceContext, pDevice->bEnablePSMode = TRUE; - if (pDevice->eOPMode == OP_MODE_ADHOC) { - - /* bMgrPrepareBeaconToSend((void *) pDevice, pMgmt); */ - - } /* We don't send null pkt in ad hoc mode since beacon will handle this. */ - else if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) { + if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) PSbSendNullPacket(pDevice); - } pDevice->bPWBitOn = TRUE; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable...\n"); -- cgit v1.2.3 From 9720b4bc76a83807c68e00c62bfba575251bb73e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 2 Mar 2011 00:13:05 +0100 Subject: staging/usbip: convert to kthread usbip has its own infrastructure for managing kernel threads, similar to kthread. By changing it to use the standard functions, we can simplify the code and get rid of one of the last BKL users at the same time. Includes changes suggested by Max Vozeler. Signed-off-by: Arnd Bergmann Cc: Greg Kroah-Hartman Cc: Takahiro Hirofuchi Cc: Max Vozeler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/Kconfig | 2 +- drivers/staging/usbip/stub.h | 4 +- drivers/staging/usbip/stub_dev.c | 12 ++-- drivers/staging/usbip/stub_rx.c | 13 ++--- drivers/staging/usbip/stub_tx.c | 17 +++--- drivers/staging/usbip/usbip_common.c | 105 ----------------------------------- drivers/staging/usbip/usbip_common.h | 20 +------ drivers/staging/usbip/usbip_event.c | 38 +++++-------- drivers/staging/usbip/vhci.h | 4 +- drivers/staging/usbip/vhci_hcd.c | 10 +++- drivers/staging/usbip/vhci_rx.c | 16 ++---- drivers/staging/usbip/vhci_sysfs.c | 9 +-- drivers/staging/usbip/vhci_tx.c | 17 +++--- 13 files changed, 64 insertions(+), 203 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/Kconfig b/drivers/staging/usbip/Kconfig index b11ec379b5c2..2c1d10acb8b5 100644 --- a/drivers/staging/usbip/Kconfig +++ b/drivers/staging/usbip/Kconfig @@ -1,6 +1,6 @@ config USB_IP_COMMON tristate "USB IP support (EXPERIMENTAL)" - depends on USB && NET && EXPERIMENTAL && BKL + depends on USB && NET && EXPERIMENTAL default N ---help--- This enables pushing USB packets over IP to allow remote diff --git a/drivers/staging/usbip/stub.h b/drivers/staging/usbip/stub.h index d73267961ef4..6004fcdbc1a4 100644 --- a/drivers/staging/usbip/stub.h +++ b/drivers/staging/usbip/stub.h @@ -95,13 +95,13 @@ extern struct kmem_cache *stub_priv_cache; /* stub_tx.c */ void stub_complete(struct urb *); -void stub_tx_loop(struct usbip_task *); +int stub_tx_loop(void *data); /* stub_dev.c */ extern struct usb_driver stub_driver; /* stub_rx.c */ -void stub_rx_loop(struct usbip_task *); +int stub_rx_loop(void *data); void stub_enqueue_ret_unlink(struct stub_device *, __u32, __u32); /* stub_main.c */ diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c index a7ce51cc8909..8214c353d9f5 100644 --- a/drivers/staging/usbip/stub_dev.c +++ b/drivers/staging/usbip/stub_dev.c @@ -18,6 +18,7 @@ */ #include +#include #include "usbip_common.h" #include "stub.h" @@ -138,7 +139,8 @@ static ssize_t store_sockfd(struct device *dev, struct device_attribute *attr, spin_unlock(&sdev->ud.lock); - usbip_start_threads(&sdev->ud); + sdev->ud.tcp_rx = kthread_run(stub_rx_loop, &sdev->ud, "stub_rx"); + sdev->ud.tcp_tx = kthread_run(stub_tx_loop, &sdev->ud, "stub_tx"); spin_lock(&sdev->ud.lock); sdev->ud.status = SDEV_ST_USED; @@ -218,7 +220,8 @@ static void stub_shutdown_connection(struct usbip_device *ud) } /* 1. stop threads */ - usbip_stop_threads(ud); + kthread_stop(ud->tcp_rx); + kthread_stop(ud->tcp_tx); /* 2. close the socket */ /* @@ -336,9 +339,6 @@ static struct stub_device *stub_device_alloc(struct usb_device *udev, */ sdev->devid = (busnum << 16) | devnum; - usbip_task_init(&sdev->ud.tcp_rx, "stub_rx", stub_rx_loop); - usbip_task_init(&sdev->ud.tcp_tx, "stub_tx", stub_tx_loop); - sdev->ud.side = USBIP_STUB; sdev->ud.status = SDEV_ST_AVAILABLE; /* sdev->ud.lock = SPIN_LOCK_UNLOCKED; */ @@ -543,7 +543,7 @@ static void stub_disconnect(struct usb_interface *interface) stub_remove_files(&interface->dev); /*If usb reset called from event handler*/ - if (busid_priv->sdev->ud.eh.thread == current) { + if (busid_priv->sdev->ud.eh == current) { busid_priv->interf_count--; return; } diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c index ae6ac82754a4..6445f12cb4fd 100644 --- a/drivers/staging/usbip/stub_rx.c +++ b/drivers/staging/usbip/stub_rx.c @@ -18,6 +18,7 @@ */ #include +#include #include "usbip_common.h" #include "stub.h" @@ -616,19 +617,15 @@ static void stub_rx_pdu(struct usbip_device *ud) } -void stub_rx_loop(struct usbip_task *ut) +int stub_rx_loop(void *data) { - struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_rx); - - while (1) { - if (signal_pending(current)) { - usbip_dbg_stub_rx("signal caught!\n"); - break; - } + struct usbip_device *ud = data; + while (!kthread_should_stop()) { if (usbip_event_happened(ud)) break; stub_rx_pdu(ud); } + return 0; } diff --git a/drivers/staging/usbip/stub_tx.c b/drivers/staging/usbip/stub_tx.c index d7136e2c86fa..5523f25998e6 100644 --- a/drivers/staging/usbip/stub_tx.c +++ b/drivers/staging/usbip/stub_tx.c @@ -18,6 +18,7 @@ */ #include +#include #include "usbip_common.h" #include "stub.h" @@ -333,17 +334,12 @@ static int stub_send_ret_unlink(struct stub_device *sdev) /*-------------------------------------------------------------------------*/ -void stub_tx_loop(struct usbip_task *ut) +int stub_tx_loop(void *data) { - struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx); + struct usbip_device *ud = data; struct stub_device *sdev = container_of(ud, struct stub_device, ud); - while (1) { - if (signal_pending(current)) { - usbip_dbg_stub_tx("signal catched\n"); - break; - } - + while (!kthread_should_stop()) { if (usbip_event_happened(ud)) break; @@ -369,6 +365,9 @@ void stub_tx_loop(struct usbip_task *ut) wait_event_interruptible(sdev->tx_waitq, (!list_empty(&sdev->priv_tx) || - !list_empty(&sdev->unlink_tx))); + !list_empty(&sdev->unlink_tx) || + kthread_should_stop())); } + + return 0; } diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c index 210ef16bab8d..337abc48f714 100644 --- a/drivers/staging/usbip/usbip_common.c +++ b/drivers/staging/usbip/usbip_common.c @@ -18,7 +18,6 @@ */ #include -#include #include #include #include @@ -349,110 +348,6 @@ void usbip_dump_header(struct usbip_header *pdu) } EXPORT_SYMBOL_GPL(usbip_dump_header); - -/*-------------------------------------------------------------------------*/ -/* thread routines */ - -int usbip_thread(void *param) -{ - struct usbip_task *ut = param; - - if (!ut) - return -EINVAL; - - lock_kernel(); - daemonize(ut->name); - allow_signal(SIGKILL); - ut->thread = current; - unlock_kernel(); - - /* srv.rb must wait for rx_thread starting */ - complete(&ut->thread_done); - - /* start of while loop */ - ut->loop_ops(ut); - - /* end of loop */ - ut->thread = NULL; - - complete_and_exit(&ut->thread_done, 0); -} - -static void stop_rx_thread(struct usbip_device *ud) -{ - if (ud->tcp_rx.thread != NULL) { - send_sig(SIGKILL, ud->tcp_rx.thread, 1); - wait_for_completion(&ud->tcp_rx.thread_done); - usbip_udbg("rx_thread for ud %p has finished\n", ud); - } -} - -static void stop_tx_thread(struct usbip_device *ud) -{ - if (ud->tcp_tx.thread != NULL) { - send_sig(SIGKILL, ud->tcp_tx.thread, 1); - wait_for_completion(&ud->tcp_tx.thread_done); - usbip_udbg("tx_thread for ud %p has finished\n", ud); - } -} - -int usbip_start_threads(struct usbip_device *ud) -{ - /* - * threads are invoked per one device (per one connection). - */ - struct task_struct *th; - int err = 0; - - th = kthread_run(usbip_thread, (void *)&ud->tcp_rx, "usbip"); - if (IS_ERR(th)) { - printk(KERN_WARNING - "Unable to start control thread\n"); - err = PTR_ERR(th); - goto ust_exit; - } - - th = kthread_run(usbip_thread, (void *)&ud->tcp_tx, "usbip"); - if (IS_ERR(th)) { - printk(KERN_WARNING - "Unable to start control thread\n"); - err = PTR_ERR(th); - goto tx_thread_err; - } - - /* confirm threads are starting */ - wait_for_completion(&ud->tcp_rx.thread_done); - wait_for_completion(&ud->tcp_tx.thread_done); - - return 0; - -tx_thread_err: - stop_rx_thread(ud); - -ust_exit: - return err; -} -EXPORT_SYMBOL_GPL(usbip_start_threads); - -void usbip_stop_threads(struct usbip_device *ud) -{ - /* kill threads related to this sdev, if v.c. exists */ - stop_rx_thread(ud); - stop_tx_thread(ud); -} -EXPORT_SYMBOL_GPL(usbip_stop_threads); - -void usbip_task_init(struct usbip_task *ut, char *name, - void (*loop_ops)(struct usbip_task *)) -{ - ut->thread = NULL; - init_completion(&ut->thread_done); - ut->name = name; - ut->loop_ops = loop_ops; -} -EXPORT_SYMBOL_GPL(usbip_task_init); - - /*-------------------------------------------------------------------------*/ /* socket routines */ diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h index d280e234e067..9f809c315d92 100644 --- a/drivers/staging/usbip/usbip_common.h +++ b/drivers/staging/usbip/usbip_common.h @@ -307,13 +307,6 @@ void usbip_dump_header(struct usbip_header *pdu); struct usbip_device; -struct usbip_task { - struct task_struct *thread; - struct completion thread_done; - char *name; - void (*loop_ops)(struct usbip_task *); -}; - enum usbip_side { USBIP_VHCI, USBIP_STUB, @@ -346,8 +339,8 @@ struct usbip_device { struct socket *tcp_socket; - struct usbip_task tcp_rx; - struct usbip_task tcp_tx; + struct task_struct *tcp_rx; + struct task_struct *tcp_tx; /* event handler */ #define USBIP_EH_SHUTDOWN (1 << 0) @@ -367,7 +360,7 @@ struct usbip_device { #define VDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE) unsigned long event; - struct usbip_task eh; + struct task_struct *eh; wait_queue_head_t eh_waitq; struct eh_ops { @@ -378,13 +371,6 @@ struct usbip_device { }; -void usbip_task_init(struct usbip_task *ut, char *, - void (*loop_ops)(struct usbip_task *)); - -int usbip_start_threads(struct usbip_device *ud); -void usbip_stop_threads(struct usbip_device *ud); -int usbip_thread(void *param); - void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd, int pack); diff --git a/drivers/staging/usbip/usbip_event.c b/drivers/staging/usbip/usbip_event.c index af3832b03e4b..f4b287ef71d0 100644 --- a/drivers/staging/usbip/usbip_event.c +++ b/drivers/staging/usbip/usbip_event.c @@ -62,55 +62,43 @@ static int event_handler(struct usbip_device *ud) return 0; } -static void event_handler_loop(struct usbip_task *ut) +static int event_handler_loop(void *data) { - struct usbip_device *ud = container_of(ut, struct usbip_device, eh); + struct usbip_device *ud = data; - while (1) { - if (signal_pending(current)) { - usbip_dbg_eh("signal catched!\n"); - break; - } + while (!kthread_should_stop()) { + wait_event_interruptible(ud->eh_waitq, + usbip_event_happened(ud) || + kthread_should_stop()); + usbip_dbg_eh("wakeup\n"); if (event_handler(ud) < 0) break; - - wait_event_interruptible(ud->eh_waitq, - usbip_event_happened(ud)); - usbip_dbg_eh("wakeup\n"); } + return 0; } int usbip_start_eh(struct usbip_device *ud) { - struct usbip_task *eh = &ud->eh; - struct task_struct *th; - init_waitqueue_head(&ud->eh_waitq); ud->event = 0; - usbip_task_init(eh, "usbip_eh", event_handler_loop); - - th = kthread_run(usbip_thread, (void *)eh, "usbip"); - if (IS_ERR(th)) { + ud->eh = kthread_run(event_handler_loop, ud, "usbip_eh"); + if (IS_ERR(ud->eh)) { printk(KERN_WARNING "Unable to start control thread\n"); - return PTR_ERR(th); + return PTR_ERR(ud->eh); } - - wait_for_completion(&eh->thread_done); return 0; } EXPORT_SYMBOL_GPL(usbip_start_eh); void usbip_stop_eh(struct usbip_device *ud) { - struct usbip_task *eh = &ud->eh; - - if (eh->thread == current) + if (ud->eh == current) return; /* do not wait for myself */ - wait_for_completion(&eh->thread_done); + kthread_stop(ud->eh); usbip_dbg_eh("usbip_eh has finished\n"); } EXPORT_SYMBOL_GPL(usbip_stop_eh); diff --git a/drivers/staging/usbip/vhci.h b/drivers/staging/usbip/vhci.h index afc3b1a71881..d3f1e5f8a960 100644 --- a/drivers/staging/usbip/vhci.h +++ b/drivers/staging/usbip/vhci.h @@ -113,8 +113,8 @@ extern struct attribute_group dev_attr_group; /* vhci_hcd.c */ void rh_port_connect(int rhport, enum usb_device_speed speed); void rh_port_disconnect(int rhport); -void vhci_rx_loop(struct usbip_task *ut); -void vhci_tx_loop(struct usbip_task *ut); +int vhci_rx_loop(void *data); +int vhci_tx_loop(void *data); struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum); diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index a35fe61268de..36ae9fbd20a6 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -18,6 +18,7 @@ */ #include +#include #include "usbip_common.h" #include "vhci.h" @@ -874,7 +875,10 @@ static void vhci_shutdown_connection(struct usbip_device *ud) kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR); } - usbip_stop_threads(&vdev->ud); + /* kill threads related to this sdev, if v.c. exists */ + kthread_stop(vdev->ud.tcp_rx); + kthread_stop(vdev->ud.tcp_tx); + usbip_uinfo("stop threads\n"); /* active connection is closed */ @@ -945,8 +949,8 @@ static void vhci_device_init(struct vhci_device *vdev) { memset(vdev, 0, sizeof(*vdev)); - usbip_task_init(&vdev->ud.tcp_rx, "vhci_rx", vhci_rx_loop); - usbip_task_init(&vdev->ud.tcp_tx, "vhci_tx", vhci_tx_loop); + vdev->ud.tcp_rx = kthread_create(vhci_rx_loop, &vdev->ud, "vhci_rx"); + vdev->ud.tcp_tx = kthread_create(vhci_tx_loop, &vdev->ud, "vhci_tx"); vdev->ud.side = USBIP_VHCI; vdev->ud.status = VDEV_ST_NULL; diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c index bf6991470941..09bf2355934b 100644 --- a/drivers/staging/usbip/vhci_rx.c +++ b/drivers/staging/usbip/vhci_rx.c @@ -18,6 +18,7 @@ */ #include +#include #include "usbip_common.h" #include "vhci.h" @@ -269,22 +270,17 @@ static void vhci_rx_pdu(struct usbip_device *ud) /*-------------------------------------------------------------------------*/ -void vhci_rx_loop(struct usbip_task *ut) +int vhci_rx_loop(void *data) { - struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_rx); - - - while (1) { - if (signal_pending(current)) { - usbip_dbg_vhci_rx("signal catched!\n"); - break; - } + struct usbip_device *ud = data; + while (!kthread_should_stop()) { if (usbip_event_happened(ud)) break; vhci_rx_pdu(ud); } -} + return 0; +} diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c index f6e34e03c8e4..3f2459f30415 100644 --- a/drivers/staging/usbip/vhci_sysfs.c +++ b/drivers/staging/usbip/vhci_sysfs.c @@ -220,16 +220,13 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, vdev->ud.tcp_socket = socket; vdev->ud.status = VDEV_ST_NOTASSIGNED; + wake_up_process(vdev->ud.tcp_rx); + wake_up_process(vdev->ud.tcp_tx); + spin_unlock(&vdev->ud.lock); spin_unlock(&the_controller->lock); /* end the lock */ - /* - * this function will sleep, so should be out of the lock. but, it's ok - * because we already marked vdev as being used. really? - */ - usbip_start_threads(&vdev->ud); - rh_port_connect(rhport, speed); return count; diff --git a/drivers/staging/usbip/vhci_tx.c b/drivers/staging/usbip/vhci_tx.c index e1c1f716a1c2..d9ab49d67697 100644 --- a/drivers/staging/usbip/vhci_tx.c +++ b/drivers/staging/usbip/vhci_tx.c @@ -18,6 +18,7 @@ */ #include +#include #include "usbip_common.h" #include "vhci.h" @@ -215,17 +216,12 @@ static int vhci_send_cmd_unlink(struct vhci_device *vdev) /*-------------------------------------------------------------------------*/ -void vhci_tx_loop(struct usbip_task *ut) +int vhci_tx_loop(void *data) { - struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx); + struct usbip_device *ud = data; struct vhci_device *vdev = container_of(ud, struct vhci_device, ud); - while (1) { - if (signal_pending(current)) { - usbip_uinfo("vhci_tx signal catched\n"); - break; - } - + while (!kthread_should_stop()) { if (vhci_send_cmd_submit(vdev) < 0) break; @@ -234,8 +230,11 @@ void vhci_tx_loop(struct usbip_task *ut) wait_event_interruptible(vdev->waitq_tx, (!list_empty(&vdev->priv_tx) || - !list_empty(&vdev->unlink_tx))); + !list_empty(&vdev->unlink_tx) || + kthread_should_stop())); usbip_dbg_vhci_tx("pending urbs ?, now wake up\n"); } + + return 0; } -- cgit v1.2.3 From 83aa3c7bf3f04a04e92637de979c6de19160aa7f Mon Sep 17 00:00:00 2001 From: Jonathan Neuschäfer Date: Tue, 1 Mar 2011 23:58:54 +0100 Subject: staging: echo: fix a typo ("overflow") MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonathan Neuschäfer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/echo/echo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/echo/echo.c b/drivers/staging/echo/echo.c index 58c4e907e44d..3c188d5f1d9f 100644 --- a/drivers/staging/echo/echo.c +++ b/drivers/staging/echo/echo.c @@ -544,7 +544,7 @@ int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx) * Just random numbers rolled off very vaguely * Hoth-like. DR: This noise doesn't sound * quite right to me - I suspect there are some - * overlfow issues in the filtering as it's too + * overflow issues in the filtering as it's too * "crackly". * TODO: debug this, maybe just play noise at * high level or look at spectrum. -- cgit v1.2.3 From 7ae92624969bdee951b64f638898ac9f96646558 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 2 Mar 2011 09:08:43 +0100 Subject: staging: brcm80211: changed module wlc_mac80211 to wlc_main The source and include file for the wlc_mac80211 module has been renamed to wlc_main and subsequently the include statement in other source files. This module provides the main interface towards wl_mac80211 module. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/Makefile | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_alloc.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_antsel.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_channel.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c | 8509 --------------------- drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h | 967 --- drivers/staging/brcm80211/brcmsmac/wlc_main.c | 8509 +++++++++++++++++++++ drivers/staging/brcm80211/brcmsmac/wlc_main.h | 967 +++ drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_stf.c | 2 +- 12 files changed, 9484 insertions(+), 9484 deletions(-) delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c delete mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_main.c create mode 100644 drivers/staging/brcm80211/brcmsmac/wlc_main.h (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/Makefile b/drivers/staging/brcm80211/brcmsmac/Makefile index 315f1ae9de0f..b0d3e074e400 100644 --- a/drivers/staging/brcm80211/brcmsmac/Makefile +++ b/drivers/staging/brcm80211/brcmsmac/Makefile @@ -36,7 +36,7 @@ BRCMSMAC_OFILES := \ wlc_antsel.o \ wlc_bmac.o \ wlc_channel.o \ - wlc_mac80211.o \ + wlc_main.o \ wlc_phy_shim.o \ wlc_rate.o \ wlc_stf.o \ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c index fecafc3958e2..0b6c6e72bdd0 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c @@ -35,7 +35,7 @@ #include "wlc_bsscfg.h" #include "phy/wlc_phy_hal.h" #include "wlc_channel.h" -#include "wlc_mac80211.h" +#include "wlc_main.h" static struct wlc_bsscfg *wlc_bsscfg_malloc(uint unit); static void wlc_bsscfg_mfree(struct wlc_bsscfg *cfg); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index 0162ba4fb02f..e9cdb05e531b 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -37,7 +37,7 @@ #include "wl_dbg.h" #include "wlc_bsscfg.h" #include "wlc_channel.h" -#include "wlc_mac80211.h" +#include "wlc_main.h" #include "wlc_ampdu.h" /* diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c index 5b195ed63768..33e3bdff61bc 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c @@ -38,7 +38,7 @@ #include "wlc_bmac.h" #include "wlc_channel.h" #include "wlc_bsscfg.h" -#include "wlc_mac80211.h" +#include "wlc_main.h" #include "wl_export.h" #include "wlc_phy_shim.h" #include "wlc_antsel.h" diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index b6e49f7af063..71f8a2234801 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -49,7 +49,7 @@ #include "phy/wlc_phy_hal.h" #include "wlc_channel.h" #include "wlc_bsscfg.h" -#include "wlc_mac80211.h" +#include "wlc_main.h" #include "wl_export.h" #include "wl_ucode.h" #include "wlc_antsel.h" diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c index 71731a4618c6..49b1ea6b7ea8 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c @@ -37,7 +37,7 @@ #include "wlc_rate.h" #include "wlc_channel.h" #include "wlc_bsscfg.h" -#include "wlc_mac80211.h" +#include "wlc_main.h" #include "wlc_stf.h" #include "wl_dbg.h" diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c deleted file mode 100644 index 2772cce78dc0..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.c +++ /dev/null @@ -1,8509 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "d11.h" -#include "wlc_types.h" -#include "wlc_cfg.h" -#include "wlc_rate.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "wlc_key.h" -#include "wlc_bsscfg.h" -#include "phy/wlc_phy_hal.h" -#include "wlc_channel.h" -#include "wlc_mac80211.h" -#include "wlc_bmac.h" -#include "wlc_phy_hal.h" -#include "wlc_phy_shim.h" -#include "wlc_antsel.h" -#include "wlc_stf.h" -#include "wlc_ampdu.h" -#include "wl_export.h" -#include "wlc_alloc.h" -#include "wl_dbg.h" - -/* - * Disable statistics counting for WME - */ -#define WLCNTSET(a, b) -#define WLCNTINCR(a) -#define WLCNTADD(a, b) - -/* - * WPA(2) definitions - */ -#define RSN_CAP_4_REPLAY_CNTRS 2 -#define RSN_CAP_16_REPLAY_CNTRS 3 - -#define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS -#define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS - -/* - * Indication for txflowcontrol that all priority bits in - * TXQ_STOP_FOR_PRIOFC_MASK are to be considered. - */ -#define ALLPRIO -1 - -/* - * buffer length needed for wlc_format_ssid - * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. - */ -#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) - -#define TIMER_INTERVAL_WATCHDOG 1000 /* watchdog timer, in unit of ms */ -#define TIMER_INTERVAL_RADIOCHK 800 /* radio monitor timer, in unit of ms */ - -#ifndef WLC_MPC_MAX_DELAYCNT -#define WLC_MPC_MAX_DELAYCNT 10 /* Max MPC timeout, in unit of watchdog */ -#endif -#define WLC_MPC_MIN_DELAYCNT 1 /* Min MPC timeout, in unit of watchdog */ -#define WLC_MPC_THRESHOLD 3 /* MPC count threshold level */ - -#define BEACON_INTERVAL_DEFAULT 100 /* beacon interval, in unit of 1024TU */ -#define DTIM_INTERVAL_DEFAULT 3 /* DTIM interval, in unit of beacon interval */ - -/* Scale down delays to accommodate QT slow speed */ -#define BEACON_INTERVAL_DEF_QT 20 /* beacon interval, in unit of 1024TU */ -#define DTIM_INTERVAL_DEF_QT 1 /* DTIM interval, in unit of beacon interval */ - -#define TBTT_ALIGN_LEEWAY_US 100 /* min leeway before first TBTT in us */ - -/* - * driver maintains internal 'tick'(wlc->pub->now) which increments in 1s OS timer(soft - * watchdog) it is not a wall clock and won't increment when driver is in "down" state - * this low resolution driver tick can be used for maintenance tasks such as phy - * calibration and scb update - */ - -/* watchdog trigger mode: OSL timer or TBTT */ -#define WLC_WATCHDOG_TBTT(wlc) \ - (wlc->stas_associated > 0 && wlc->PM != PM_OFF && wlc->pub->align_wd_tbtt) - -/* To inform the ucode of the last mcast frame posted so that it can clear moredata bit */ -#define BCMCFID(wlc, fid) wlc_bmac_write_shm((wlc)->hw, M_BCMC_FID, (fid)) - -#define WLC_WAR16165(wlc) (wlc->pub->sih->bustype == PCI_BUS && \ - (!AP_ENAB(wlc->pub)) && (wlc->war16165)) - -/* debug/trace */ -uint wl_msg_level = -#if defined(BCMDBG) - WL_ERROR_VAL; -#else - 0; -#endif /* BCMDBG */ - -/* Find basic rate for a given rate */ -#define WLC_BASIC_RATE(wlc, rspec) (IS_MCS(rspec) ? \ - (wlc)->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK].leg_ofdm] : \ - (wlc)->band->basic_rate[rspec & RSPEC_RATE_MASK]) - -#define FRAMETYPE(r, mimoframe) (IS_MCS(r) ? mimoframe : (IS_CCK(r) ? FT_CCK : FT_OFDM)) - -#define RFDISABLE_DEFAULT 10000000 /* rfdisable delay timer 500 ms, runs of ALP clock */ - -#define WLC_TEMPSENSE_PERIOD 10 /* 10 second timeout */ - -#define SCAN_IN_PROGRESS(x) 0 - -#define EPI_VERSION_NUM 0x054b0b00 - -#ifdef BCMDBG -/* pointer to most recently allocated wl/wlc */ -static struct wlc_info *wlc_info_dbg = (struct wlc_info *) (NULL); -#endif - -/* IOVar table */ - -/* Parameter IDs, for use only internally to wlc -- in the wlc_iovars - * table and by the wlc_doiovar() function. No ordering is imposed: - * the table is keyed by name, and the function uses a switch. - */ -enum { - IOV_MPC = 1, - IOV_RTSTHRESH, - IOV_QTXPOWER, - IOV_BCN_LI_BCN, /* Beacon listen interval in # of beacons */ - IOV_LAST /* In case of a need to check max ID number */ -}; - -const bcm_iovar_t wlc_iovars[] = { - {"mpc", IOV_MPC, (0), IOVT_BOOL, 0}, - {"rtsthresh", IOV_RTSTHRESH, (IOVF_WHL), IOVT_UINT16, 0}, - {"qtxpower", IOV_QTXPOWER, (IOVF_WHL), IOVT_UINT32, 0}, - {"bcn_li_bcn", IOV_BCN_LI_BCN, (0), IOVT_UINT8, 0}, - {NULL, 0, 0, 0, 0} -}; - -const u8 prio2fifo[NUMPRIO] = { - TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */ - TX_AC_BK_FIFO, /* 1 BK AC_BK Background */ - TX_AC_BK_FIFO, /* 2 -- AC_BK Background */ - TX_AC_BE_FIFO, /* 3 EE AC_BE Best Effort */ - TX_AC_VI_FIFO, /* 4 CL AC_VI Video */ - TX_AC_VI_FIFO, /* 5 VI AC_VI Video */ - TX_AC_VO_FIFO, /* 6 VO AC_VO Voice */ - TX_AC_VO_FIFO /* 7 NC AC_VO Voice */ -}; - -/* precedences numbers for wlc queues. These are twice as may levels as - * 802.1D priorities. - * Odd numbers are used for HI priority traffic at same precedence levels - * These constants are used ONLY by wlc_prio2prec_map. Do not use them elsewhere. - */ -#define _WLC_PREC_NONE 0 /* None = - */ -#define _WLC_PREC_BK 2 /* BK - Background */ -#define _WLC_PREC_BE 4 /* BE - Best-effort */ -#define _WLC_PREC_EE 6 /* EE - Excellent-effort */ -#define _WLC_PREC_CL 8 /* CL - Controlled Load */ -#define _WLC_PREC_VI 10 /* Vi - Video */ -#define _WLC_PREC_VO 12 /* Vo - Voice */ -#define _WLC_PREC_NC 14 /* NC - Network Control */ - -/* 802.1D Priority to precedence queue mapping */ -const u8 wlc_prio2prec_map[] = { - _WLC_PREC_BE, /* 0 BE - Best-effort */ - _WLC_PREC_BK, /* 1 BK - Background */ - _WLC_PREC_NONE, /* 2 None = - */ - _WLC_PREC_EE, /* 3 EE - Excellent-effort */ - _WLC_PREC_CL, /* 4 CL - Controlled Load */ - _WLC_PREC_VI, /* 5 Vi - Video */ - _WLC_PREC_VO, /* 6 Vo - Voice */ - _WLC_PREC_NC, /* 7 NC - Network Control */ -}; - -/* Sanity check for tx_prec_map and fifo synchup - * Either there are some packets pending for the fifo, else if fifo is empty then - * all the corresponding precmap bits should be set - */ -#define WLC_TX_FIFO_CHECK(wlc, fifo) (TXPKTPENDGET((wlc), (fifo)) || \ - (TXPKTPENDGET((wlc), (fifo)) == 0 && \ - ((wlc)->tx_prec_map & (wlc)->fifo2prec_map[(fifo)]) == \ - (wlc)->fifo2prec_map[(fifo)])) - -/* TX FIFO number to WME/802.1E Access Category */ -const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE }; - -/* WME/802.1E Access Category to TX FIFO number */ -static const u8 wme_ac2fifo[] = { 1, 0, 2, 3 }; - -static bool in_send_q = false; - -/* Shared memory location index for various AC params */ -#define wme_shmemacindex(ac) wme_ac2fifo[ac] - -#ifdef BCMDBG -static const char *fifo_names[] = { - "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; -#else -static const char fifo_names[6][0]; -#endif - -static const u8 acbitmap2maxprio[] = { - PRIO_8021D_BE, PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_BK, - PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, - PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, - PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO -}; - -/* currently the best mechanism for determining SIFS is the band in use */ -#define SIFS(band) ((band)->bandtype == WLC_BAND_5G ? APHY_SIFS_TIME : BPHY_SIFS_TIME); - -/* value for # replay counters currently supported */ -#define WLC_REPLAY_CNTRS_VALUE WPA_CAP_16_REPLAY_CNTRS - -/* local prototypes */ -static u16 BCMFASTPATH wlc_d11hdrs_mac80211(struct wlc_info *wlc, - struct ieee80211_hw *hw, - struct sk_buff *p, - struct scb *scb, uint frag, - uint nfrags, uint queue, - uint next_frag_len, - wsec_key_t *key, - ratespec_t rspec_override); - -static void wlc_ctrupd_cache(u16 cur_stat, u16 *macstat_snapshot, u32 *macstat); -static void wlc_bss_default_init(struct wlc_info *wlc); -static void wlc_ucode_mac_upd(struct wlc_info *wlc); -static ratespec_t mac80211_wlc_set_nrate(struct wlc_info *wlc, - struct wlcband *cur_band, u32 int_val); -static void wlc_tx_prec_map_init(struct wlc_info *wlc); -static void wlc_watchdog(void *arg); -static void wlc_watchdog_by_timer(void *arg); -static u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate); -static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg); -static int wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, - const bcm_iovar_t *vi); -static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc); - -/* send and receive */ -static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc, - struct osl_info *osh); -static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh, - struct wlc_txq_info *qi); -static void wlc_txflowcontrol_signal(struct wlc_info *wlc, - struct wlc_txq_info *qi, - bool on, int prio); -static void wlc_txflowcontrol_reset(struct wlc_info *wlc); -static u16 wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, - uint length); -static void wlc_compute_cck_plcp(ratespec_t rate, uint length, u8 *plcp); -static void wlc_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp); -static void wlc_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp); -static u16 wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, - u8 preamble_type, uint next_frag_len); -static void wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, - d11rxhdr_t *rxh, struct sk_buff *p); -static uint wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t rate, - u8 preamble_type, uint dur); -static uint wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rate, - u8 preamble_type); -static uint wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rate, - u8 preamble_type); -/* interrupt, up/down, band */ -static void wlc_setband(struct wlc_info *wlc, uint bandunit); -static chanspec_t wlc_init_chanspec(struct wlc_info *wlc); -static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec); -static void wlc_bsinit(struct wlc_info *wlc); -static int wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, - bool writeToShm); -static void wlc_radio_hwdisable_upd(struct wlc_info *wlc); -static bool wlc_radio_monitor_start(struct wlc_info *wlc); -static void wlc_radio_timer(void *arg); -static void wlc_radio_enable(struct wlc_info *wlc); -static void wlc_radio_upd(struct wlc_info *wlc); - -/* scan, association, BSS */ -static uint wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rate, - u8 preamble_type); -static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap); -static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val); -static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val); -static void wlc_war16165(struct wlc_info *wlc, bool tx); - -static void wlc_wme_retries_write(struct wlc_info *wlc); -static bool wlc_attach_stf_ant_init(struct wlc_info *wlc); -static uint wlc_attach_module(struct wlc_info *wlc); -static void wlc_detach_module(struct wlc_info *wlc); -static void wlc_timers_deinit(struct wlc_info *wlc); -static void wlc_down_led_upd(struct wlc_info *wlc); -static uint wlc_down_del_timer(struct wlc_info *wlc); -static void wlc_ofdm_rateset_war(struct wlc_info *wlc); -static int _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, - struct wlc_if *wlcif); - -#if defined(BCMDBG) -void wlc_get_rcmta(struct wlc_info *wlc, int idx, u8 *addr) -{ - d11regs_t *regs = wlc->regs; - u32 v32; - struct osl_info *osh; - - WL_TRACE("wl%d: %s\n", WLCWLUNIT(wlc), __func__); - - osh = wlc->osh; - - W_REG(®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); - (void)R_REG(®s->objaddr); - v32 = R_REG(®s->objdata); - addr[0] = (u8) v32; - addr[1] = (u8) (v32 >> 8); - addr[2] = (u8) (v32 >> 16); - addr[3] = (u8) (v32 >> 24); - W_REG(®s->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1))); - (void)R_REG(®s->objaddr); - v32 = R_REG(®s->objdata); - addr[4] = (u8) v32; - addr[5] = (u8) (v32 >> 8); -} -#endif /* defined(BCMDBG) */ - -/* keep the chip awake if needed */ -bool wlc_stay_awake(struct wlc_info *wlc) -{ - return true; -} - -/* conditions under which the PM bit should be set in outgoing frames and STAY_AWAKE is meaningful - */ -bool wlc_ps_allowed(struct wlc_info *wlc) -{ - int idx; - wlc_bsscfg_t *cfg; - - /* disallow PS when one of the following global conditions meets */ - if (!wlc->pub->associated || !wlc->PMenabled || wlc->PM_override) - return false; - - /* disallow PS when one of these meets when not scanning */ - if (!wlc->PMblocked) { - if (AP_ACTIVE(wlc) || wlc->monitor) - return false; - } - - FOREACH_AS_STA(wlc, idx, cfg) { - /* disallow PS when one of the following bsscfg specific conditions meets */ - if (!cfg->BSS || !WLC_PORTOPEN(cfg)) - return false; - - if (!cfg->dtim_programmed) - return false; - } - - return true; -} - -void wlc_reset(struct wlc_info *wlc) -{ - WL_TRACE("wl%d: wlc_reset\n", wlc->pub->unit); - - wlc->check_for_unaligned_tbtt = false; - - /* slurp up hw mac counters before core reset */ - wlc_statsupd(wlc); - - /* reset our snapshot of macstat counters */ - memset((char *)wlc->core->macstat_snapshot, 0, - sizeof(macstat_t)); - - wlc_bmac_reset(wlc->hw); - wlc_ampdu_reset(wlc->ampdu); - wlc->txretried = 0; - -} - -void wlc_fatal_error(struct wlc_info *wlc) -{ - WL_ERROR("wl%d: fatal error, reinitializing\n", wlc->pub->unit); - wl_init(wlc->wl); -} - -/* Return the channel the driver should initialize during wlc_init. - * the channel may have to be changed from the currently configured channel - * if other configurations are in conflict (bandlocked, 11n mode disabled, - * invalid channel for current country, etc.) - */ -static chanspec_t wlc_init_chanspec(struct wlc_info *wlc) -{ - chanspec_t chanspec = - 1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE | - WL_CHANSPEC_BAND_2G; - - /* make sure the channel is on the supported band if we are band-restricted */ - if (wlc->bandlocked || NBANDS(wlc) == 1) { - ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit); - } - ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec)); - return chanspec; -} - -struct scb global_scb; - -static void wlc_init_scb(struct wlc_info *wlc, struct scb *scb) -{ - int i; - scb->flags = SCB_WMECAP | SCB_HTCAP; - for (i = 0; i < NUMPRIO; i++) - scb->seqnum[i] = 0; -} - -void wlc_init(struct wlc_info *wlc) -{ - d11regs_t *regs; - chanspec_t chanspec; - int i; - wlc_bsscfg_t *bsscfg; - bool mute = false; - - WL_TRACE("wl%d: wlc_init\n", wlc->pub->unit); - - regs = wlc->regs; - - /* This will happen if a big-hammer was executed. In that case, we want to go back - * to the channel that we were on and not new channel - */ - if (wlc->pub->associated) - chanspec = wlc->home_chanspec; - else - chanspec = wlc_init_chanspec(wlc); - - wlc_bmac_init(wlc->hw, chanspec, mute); - - wlc->seckeys = wlc_bmac_read_shm(wlc->hw, M_SECRXKEYS_PTR) * 2; - if (wlc->machwcap & MCAP_TKIPMIC) - wlc->tkmickeys = - wlc_bmac_read_shm(wlc->hw, M_TKMICKEYS_PTR) * 2; - - /* update beacon listen interval */ - wlc_bcn_li_upd(wlc); - wlc->bcn_wait_prd = - (u8) (wlc_bmac_read_shm(wlc->hw, M_NOSLPZNATDTIM) >> 10); - ASSERT(wlc->bcn_wait_prd > 0); - - /* the world is new again, so is our reported rate */ - wlc_reprate_init(wlc); - - /* write ethernet address to core */ - FOREACH_BSS(wlc, i, bsscfg) { - wlc_set_mac(bsscfg); - wlc_set_bssid(bsscfg); - } - - /* Update tsf_cfprep if associated and up */ - if (wlc->pub->associated) { - FOREACH_BSS(wlc, i, bsscfg) { - if (bsscfg->up) { - u32 bi; - - /* get beacon period and convert to uS */ - bi = bsscfg->current_bss->beacon_period << 10; - /* - * update since init path would reset - * to default value - */ - W_REG(®s->tsf_cfprep, - (bi << CFPREP_CBI_SHIFT)); - - /* Update maccontrol PM related bits */ - wlc_set_ps_ctrl(wlc); - - break; - } - } - } - - wlc_key_hw_init_all(wlc); - - wlc_bandinit_ordered(wlc, chanspec); - - wlc_init_scb(wlc, &global_scb); - - /* init probe response timeout */ - wlc_write_shm(wlc, M_PRS_MAXTIME, wlc->prb_resp_timeout); - - /* init max burst txop (framebursting) */ - wlc_write_shm(wlc, M_MBURST_TXOP, - (wlc-> - _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP)); - - /* initialize maximum allowed duty cycle */ - wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true); - wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true); - - /* Update some shared memory locations related to max AMPDU size allowed to received */ - wlc_ampdu_shm_upd(wlc->ampdu); - - /* band-specific inits */ - wlc_bsinit(wlc); - - /* Enable EDCF mode (while the MAC is suspended) */ - if (EDCF_ENAB(wlc->pub)) { - OR_REG(®s->ifs_ctl, IFS_USEEDCF); - wlc_edcf_setparams(wlc->cfg, false); - } - - /* Init precedence maps for empty FIFOs */ - wlc_tx_prec_map_init(wlc); - - /* read the ucode version if we have not yet done so */ - if (wlc->ucode_rev == 0) { - wlc->ucode_rev = - wlc_read_shm(wlc, M_BOM_REV_MAJOR) << NBITS(u16); - wlc->ucode_rev |= wlc_read_shm(wlc, M_BOM_REV_MINOR); - } - - /* ..now really unleash hell (allow the MAC out of suspend) */ - wlc_enable_mac(wlc); - - /* clear tx flow control */ - wlc_txflowcontrol_reset(wlc); - - /* clear tx data fifo suspends */ - wlc->tx_suspended = false; - - /* enable the RF Disable Delay timer */ - W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT); - - /* initialize mpc delay */ - wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; - - /* - * Initialize WME parameters; if they haven't been set by some other - * mechanism (IOVar, etc) then read them from the hardware. - */ - if (WLC_WME_RETRY_SHORT_GET(wlc, 0) == 0) { /* Uninitialized; read from HW */ - int ac; - - ASSERT(wlc->clk); - for (ac = 0; ac < AC_COUNT; ac++) { - wlc->wme_retries[ac] = - wlc_read_shm(wlc, M_AC_TXLMT_ADDR(ac)); - } - } -} - -void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc) -{ - wlc->bcnmisc_monitor = promisc; - wlc_mac_bcn_promisc(wlc); -} - -void wlc_mac_bcn_promisc(struct wlc_info *wlc) -{ - if ((AP_ENAB(wlc->pub) && (N_ENAB(wlc->pub) || wlc->band->gmode)) || - wlc->bcnmisc_ibss || wlc->bcnmisc_scan || wlc->bcnmisc_monitor) - wlc_mctrl(wlc, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC); - else - wlc_mctrl(wlc, MCTL_BCNS_PROMISC, 0); -} - -/* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */ -void wlc_mac_promisc(struct wlc_info *wlc) -{ - u32 promisc_bits = 0; - - /* promiscuous mode just sets MCTL_PROMISC - * Note: APs get all BSS traffic without the need to set the MCTL_PROMISC bit - * since all BSS data traffic is directed at the AP - */ - if (PROMISC_ENAB(wlc->pub) && !AP_ENAB(wlc->pub) && !wlc->wet) - promisc_bits |= MCTL_PROMISC; - - /* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL - * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is - * handled in wlc_mac_bcn_promisc() - */ - if (MONITOR_ENAB(wlc)) - promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL; - - wlc_mctrl(wlc, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits); -} - -/* check if hps and wake states of sw and hw are in sync */ -bool wlc_ps_check(struct wlc_info *wlc) -{ - bool res = true; - bool hps, wake; - bool wake_ok; - - if (!AP_ACTIVE(wlc)) { - u32 tmp; - tmp = R_REG(&wlc->regs->maccontrol); - - /* - * If deviceremoved is detected, then don't take any action as - * this can be called in any context. Assume that caller will - * take care of the condition. This is just to avoid assert - */ - if (tmp == 0xffffffff) { - WL_ERROR("wl%d: %s: dead chip\n", - wlc->pub->unit, __func__); - return DEVICEREMOVED(wlc); - } - - hps = PS_ALLOWED(wlc); - - if (hps != ((tmp & MCTL_HPS) != 0)) { - int idx; - wlc_bsscfg_t *cfg; - WL_ERROR("wl%d: hps not sync, sw %d, maccontrol 0x%x\n", - wlc->pub->unit, hps, tmp); - FOREACH_BSS(wlc, idx, cfg) { - if (!BSSCFG_STA(cfg)) - continue; - } - - res = false; - } - /* For a monolithic build the wake check can be exact since it looks at wake - * override bits. The MCTL_WAKE bit should match the 'wake' value. - */ - wake = STAY_AWAKE(wlc) || wlc->hw->wake_override; - wake_ok = (wake == ((tmp & MCTL_WAKE) != 0)); - if (hps && !wake_ok) { - WL_ERROR("wl%d: wake not sync, sw %d maccontrol 0x%x\n", - wlc->pub->unit, wake, tmp); - res = false; - } - } - ASSERT(res); - return res; -} - -/* push sw hps and wake state through hardware */ -void wlc_set_ps_ctrl(struct wlc_info *wlc) -{ - u32 v1, v2; - bool hps, wake; - bool awake_before; - - hps = PS_ALLOWED(wlc); - wake = hps ? (STAY_AWAKE(wlc)) : true; - - WL_TRACE("wl%d: wlc_set_ps_ctrl: hps %d wake %d\n", - wlc->pub->unit, hps, wake); - - v1 = R_REG(&wlc->regs->maccontrol); - v2 = 0; - if (hps) - v2 |= MCTL_HPS; - if (wake) - v2 |= MCTL_WAKE; - - wlc_mctrl(wlc, MCTL_WAKE | MCTL_HPS, v2); - - awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0)); - - if (wake && !awake_before) - wlc_bmac_wait_for_wake(wlc->hw); - -} - -/* - * Write this BSS config's MAC address to core. - * Updates RXE match engine. - */ -int wlc_set_mac(wlc_bsscfg_t *cfg) -{ - int err = 0; - struct wlc_info *wlc = cfg->wlc; - - if (cfg == wlc->cfg) { - /* enter the MAC addr into the RXE match registers */ - wlc_set_addrmatch(wlc, RCM_MAC_OFFSET, cfg->cur_etheraddr); - } - - wlc_ampdu_macaddr_upd(wlc); - - return err; -} - -/* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl). - * Updates RXE match engine. - */ -void wlc_set_bssid(wlc_bsscfg_t *cfg) -{ - struct wlc_info *wlc = cfg->wlc; - - /* if primary config, we need to update BSSID in RXE match registers */ - if (cfg == wlc->cfg) { - wlc_set_addrmatch(wlc, RCM_BSSID_OFFSET, cfg->BSSID); - } -#ifdef SUPPORT_HWKEYS - else if (BSSCFG_STA(cfg) && cfg->BSS) { - wlc_rcmta_add_bssid(wlc, cfg); - } -#endif -} - -/* - * Suspend the the MAC and update the slot timing - * for standard 11b/g (20us slots) or shortslot 11g (9us slots). - */ -void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot) -{ - int idx; - wlc_bsscfg_t *cfg; - - ASSERT(wlc->band->gmode); - - /* use the override if it is set */ - if (wlc->shortslot_override != WLC_SHORTSLOT_AUTO) - shortslot = (wlc->shortslot_override == WLC_SHORTSLOT_ON); - - if (wlc->shortslot == shortslot) - return; - - wlc->shortslot = shortslot; - - /* update the capability based on current shortslot mode */ - FOREACH_BSS(wlc, idx, cfg) { - if (!cfg->associated) - continue; - cfg->current_bss->capability &= - ~WLAN_CAPABILITY_SHORT_SLOT_TIME; - if (wlc->shortslot) - cfg->current_bss->capability |= - WLAN_CAPABILITY_SHORT_SLOT_TIME; - } - - wlc_bmac_set_shortslot(wlc->hw, shortslot); -} - -static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc) -{ - u8 local; - s16 local_max; - - local = WLC_TXPWR_MAX; - if (wlc->pub->associated && - (wf_chspec_ctlchan(wlc->chanspec) == - wf_chspec_ctlchan(wlc->home_chanspec))) { - - /* get the local power constraint if we are on the AP's - * channel [802.11h, 7.3.2.13] - */ - /* Clamp the value between 0 and WLC_TXPWR_MAX w/o overflowing the target */ - local_max = - (wlc->txpwr_local_max - - wlc->txpwr_local_constraint) * WLC_TXPWR_DB_FACTOR; - if (local_max > 0 && local_max < WLC_TXPWR_MAX) - return (u8) local_max; - if (local_max < 0) - return 0; - } - - return local; -} - -/* propagate home chanspec to all bsscfgs in case bsscfg->current_bss->chanspec is referenced */ -void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec) -{ - if (wlc->home_chanspec != chanspec) { - int idx; - wlc_bsscfg_t *cfg; - - wlc->home_chanspec = chanspec; - - FOREACH_BSS(wlc, idx, cfg) { - if (!cfg->associated) - continue; - - cfg->current_bss->chanspec = chanspec; - } - - } -} - -static void wlc_set_phy_chanspec(struct wlc_info *wlc, chanspec_t chanspec) -{ - /* Save our copy of the chanspec */ - wlc->chanspec = chanspec; - - /* Set the chanspec and power limits for this locale after computing - * any 11h local tx power constraints. - */ - wlc_channel_set_chanspec(wlc->cmi, chanspec, - wlc_local_constraint_qdbm(wlc)); - - if (wlc->stf->ss_algosel_auto) - wlc_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel, - chanspec); - - wlc_stf_ss_update(wlc, wlc->band); - -} - -void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec) -{ - uint bandunit; - bool switchband = false; - chanspec_t old_chanspec = wlc->chanspec; - - if (!wlc_valid_chanspec_db(wlc->cmi, chanspec)) { - WL_ERROR("wl%d: %s: Bad channel %d\n", - wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); - ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec)); - return; - } - - /* Switch bands if necessary */ - if (NBANDS(wlc) > 1) { - bandunit = CHSPEC_WLCBANDUNIT(chanspec); - if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) { - switchband = true; - if (wlc->bandlocked) { - WL_ERROR("wl%d: %s: chspec %d band is locked!\n", - wlc->pub->unit, __func__, - CHSPEC_CHANNEL(chanspec)); - return; - } - /* BMAC_NOTE: should the setband call come after the wlc_bmac_chanspec() ? - * if the setband updates (wlc_bsinit) use low level calls to inspect and - * set state, the state inspected may be from the wrong band, or the - * following wlc_bmac_set_chanspec() may undo the work. - */ - wlc_setband(wlc, bandunit); - } - } - - ASSERT(N_ENAB(wlc->pub) || !CHSPEC_IS40(chanspec)); - - /* sync up phy/radio chanspec */ - wlc_set_phy_chanspec(wlc, chanspec); - - /* init antenna selection */ - if (CHSPEC_WLC_BW(old_chanspec) != CHSPEC_WLC_BW(chanspec)) { - wlc_antsel_init(wlc->asi); - - /* Fix the hardware rateset based on bw. - * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz - */ - wlc_rateset_bw_mcs_filter(&wlc->band->hw_rateset, - wlc->band-> - mimo_cap_40 ? CHSPEC_WLC_BW(chanspec) - : 0); - } - - /* update some mac configuration since chanspec changed */ - wlc_ucode_mac_upd(wlc); -} - -#if defined(BCMDBG) -static int wlc_get_current_txpwr(struct wlc_info *wlc, void *pwr, uint len) -{ - txpwr_limits_t txpwr; - tx_power_t power; - tx_power_legacy_t *old_power = NULL; - int r, c; - uint qdbm; - bool override; - - if (len == sizeof(tx_power_legacy_t)) - old_power = (tx_power_legacy_t *) pwr; - else if (len < sizeof(tx_power_t)) - return BCME_BUFTOOSHORT; - - memset(&power, 0, sizeof(tx_power_t)); - - power.chanspec = WLC_BAND_PI_RADIO_CHANSPEC; - if (wlc->pub->associated) - power.local_chanspec = wlc->home_chanspec; - - /* Return the user target tx power limits for the various rates. Note wlc_phy.c's - * public interface only implements getting and setting a single value for all of - * rates, so we need to fill the array ourselves. - */ - wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override); - for (r = 0; r < WL_TX_POWER_RATES; r++) { - power.user_limit[r] = (u8) qdbm; - } - - power.local_max = wlc->txpwr_local_max * WLC_TXPWR_DB_FACTOR; - power.local_constraint = - wlc->txpwr_local_constraint * WLC_TXPWR_DB_FACTOR; - - power.antgain[0] = wlc->bandstate[BAND_2G_INDEX]->antgain; - power.antgain[1] = wlc->bandstate[BAND_5G_INDEX]->antgain; - - wlc_channel_reg_limits(wlc->cmi, power.chanspec, &txpwr); - -#if WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK -#error "WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK" -#endif - - /* CCK tx power limits */ - for (c = 0, r = WL_TX_POWER_CCK_FIRST; c < WL_TX_POWER_CCK_NUM; - c++, r++) - power.reg_limit[r] = txpwr.cck[c]; - -#if WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM -#error "WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM" -#endif - - /* 20 MHz OFDM SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM_FIRST; c < WL_TX_POWER_OFDM_NUM; - c++, r++) - power.reg_limit[r] = txpwr.ofdm[c]; - - if (WLC_PHY_11N_CAP(wlc->band)) { - - /* 20 MHz OFDM CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM20_CDD_FIRST; - c < WL_TX_POWER_OFDM_NUM; c++, r++) - power.reg_limit[r] = txpwr.ofdm_cdd[c]; - - /* 40 MHz OFDM SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM40_SISO_FIRST; - c < WL_TX_POWER_OFDM_NUM; c++, r++) - power.reg_limit[r] = txpwr.ofdm_40_siso[c]; - - /* 40 MHz OFDM CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM40_CDD_FIRST; - c < WL_TX_POWER_OFDM_NUM; c++, r++) - power.reg_limit[r] = txpwr.ofdm_40_cdd[c]; - -#if WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM -#error "WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM" -#endif - - /* 20MHz MCS0-7 SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_SISO_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_siso[c]; - - /* 20MHz MCS0-7 CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_CDD_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_cdd[c]; - - /* 20MHz MCS0-7 STBC tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_STBC_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_stbc[c]; - - /* 40MHz MCS0-7 SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_SISO_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_siso[c]; - - /* 40MHz MCS0-7 CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_CDD_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_cdd[c]; - - /* 40MHz MCS0-7 STBC tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_STBC_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_stbc[c]; - -#if WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM -#error "WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM" -#endif - - /* 20MHz MCS8-15 SDM tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_SDM_FIRST; - c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_mimo[c]; - - /* 40MHz MCS8-15 SDM tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_SDM_FIRST; - c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_mimo[c]; - - /* MCS 32 */ - power.reg_limit[WL_TX_POWER_MCS_32] = txpwr.mcs32; - } - - wlc_phy_txpower_get_current(wlc->band->pi, &power, - CHSPEC_CHANNEL(power.chanspec)); - - /* copy the tx_power_t struct to the return buffer, - * or convert to a tx_power_legacy_t struct - */ - if (!old_power) { - memcpy(pwr, &power, sizeof(tx_power_t)); - } else { - int band_idx = CHSPEC_IS2G(power.chanspec) ? 0 : 1; - - memset(old_power, 0, sizeof(tx_power_legacy_t)); - - old_power->txpwr_local_max = power.local_max; - old_power->txpwr_local_constraint = power.local_constraint; - if (CHSPEC_IS2G(power.chanspec)) { - old_power->txpwr_chan_reg_max = txpwr.cck[0]; - old_power->txpwr_est_Pout[band_idx] = - power.est_Pout_cck; - old_power->txpwr_est_Pout_gofdm = power.est_Pout[0]; - } else { - old_power->txpwr_chan_reg_max = txpwr.ofdm[0]; - old_power->txpwr_est_Pout[band_idx] = power.est_Pout[0]; - } - old_power->txpwr_antgain[0] = power.antgain[0]; - old_power->txpwr_antgain[1] = power.antgain[1]; - - for (r = 0; r < NUM_PWRCTRL_RATES; r++) { - old_power->txpwr_band_max[r] = power.user_limit[r]; - old_power->txpwr_limit[r] = power.reg_limit[r]; - old_power->txpwr_target[band_idx][r] = power.target[r]; - if (CHSPEC_IS2G(power.chanspec)) - old_power->txpwr_bphy_cck_max[r] = - power.board_limit[r]; - else - old_power->txpwr_aphy_max[r] = - power.board_limit[r]; - } - } - - return 0; -} -#endif /* defined(BCMDBG) */ - -static u32 wlc_watchdog_backup_bi(struct wlc_info *wlc) -{ - u32 bi; - bi = 2 * wlc->cfg->current_bss->dtim_period * - wlc->cfg->current_bss->beacon_period; - if (wlc->bcn_li_dtim) - bi *= wlc->bcn_li_dtim; - else if (wlc->bcn_li_bcn) - /* recalculate bi based on bcn_li_bcn */ - bi = 2 * wlc->bcn_li_bcn * wlc->cfg->current_bss->beacon_period; - - if (bi < 2 * TIMER_INTERVAL_WATCHDOG) - bi = 2 * TIMER_INTERVAL_WATCHDOG; - return bi; -} - -/* Change to run the watchdog either from a periodic timer or from tbtt handler. - * Call watchdog from tbtt handler if tbtt is true, watchdog timer otherwise. - */ -void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt) -{ - /* make sure changing watchdog driver is allowed */ - if (!wlc->pub->up || !wlc->pub->align_wd_tbtt) - return; - if (!tbtt && wlc->WDarmed) { - wl_del_timer(wlc->wl, wlc->wdtimer); - wlc->WDarmed = false; - } - - /* stop watchdog timer and use tbtt interrupt to drive watchdog */ - if (tbtt && wlc->WDarmed) { - wl_del_timer(wlc->wl, wlc->wdtimer); - wlc->WDarmed = false; - wlc->WDlast = OSL_SYSUPTIME(); - } - /* arm watchdog timer and drive the watchdog there */ - else if (!tbtt && !wlc->WDarmed) { - wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, - true); - wlc->WDarmed = true; - } - if (tbtt && !wlc->WDarmed) { - wl_add_timer(wlc->wl, wlc->wdtimer, wlc_watchdog_backup_bi(wlc), - true); - wlc->WDarmed = true; - } -} - -ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, wlc_rateset_t *rs) -{ - ratespec_t lowest_basic_rspec; - uint i; - - /* Use the lowest basic rate */ - lowest_basic_rspec = rs->rates[0] & RATE_MASK; - for (i = 0; i < rs->count; i++) { - if (rs->rates[i] & WLC_RATE_FLAG) { - lowest_basic_rspec = rs->rates[i] & RATE_MASK; - break; - } - } -#if NCONF - /* pick siso/cdd as default for OFDM (note no basic rate MCSs are supported yet) */ - if (IS_OFDM(lowest_basic_rspec)) { - lowest_basic_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT); - } -#endif - - return lowest_basic_rspec; -} - -/* This function changes the phytxctl for beacon based on current beacon ratespec AND txant - * setting as per this table: - * ratespec CCK ant = wlc->stf->txant - * OFDM ant = 3 - */ -void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, ratespec_t bcn_rspec) -{ - u16 phyctl; - u16 phytxant = wlc->stf->phytxant; - u16 mask = PHY_TXC_ANT_MASK; - - /* for non-siso rates or default setting, use the available chains */ - if (WLC_PHY_11N_CAP(wlc->band)) { - phytxant = wlc_stf_phytxchain_sel(wlc, bcn_rspec); - } - - phyctl = wlc_read_shm(wlc, M_BCN_PCTLWD); - phyctl = (phyctl & ~mask) | phytxant; - wlc_write_shm(wlc, M_BCN_PCTLWD, phyctl); -} - -/* centralized protection config change function to simplify debugging, no consistency checking - * this should be called only on changes to avoid overhead in periodic function -*/ -void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val) -{ - WL_TRACE("wlc_protection_upd: idx %d, val %d\n", idx, val); - - switch (idx) { - case WLC_PROT_G_SPEC: - wlc->protection->_g = (bool) val; - break; - case WLC_PROT_G_OVR: - wlc->protection->g_override = (s8) val; - break; - case WLC_PROT_G_USER: - wlc->protection->gmode_user = (u8) val; - break; - case WLC_PROT_OVERLAP: - wlc->protection->overlap = (s8) val; - break; - case WLC_PROT_N_USER: - wlc->protection->nmode_user = (s8) val; - break; - case WLC_PROT_N_CFG: - wlc->protection->n_cfg = (s8) val; - break; - case WLC_PROT_N_CFG_OVR: - wlc->protection->n_cfg_override = (s8) val; - break; - case WLC_PROT_N_NONGF: - wlc->protection->nongf = (bool) val; - break; - case WLC_PROT_N_NONGF_OVR: - wlc->protection->nongf_override = (s8) val; - break; - case WLC_PROT_N_PAM_OVR: - wlc->protection->n_pam_override = (s8) val; - break; - case WLC_PROT_N_OBSS: - wlc->protection->n_obss = (bool) val; - break; - - default: - ASSERT(0); - break; - } - -} - -static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val) -{ - wlc->ht_cap.cap_info &= ~(IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_SGI_40); - wlc->ht_cap.cap_info |= (val & WLC_N_SGI_20) ? - IEEE80211_HT_CAP_SGI_20 : 0; - wlc->ht_cap.cap_info |= (val & WLC_N_SGI_40) ? - IEEE80211_HT_CAP_SGI_40 : 0; - - if (wlc->pub->up) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - } -} - -static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val) -{ - wlc->stf->ldpc = val; - - wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_LDPC_CODING; - if (wlc->stf->ldpc != OFF) - wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_LDPC_CODING; - - if (wlc->pub->up) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - wlc_phy_ldpc_override_set(wlc->band->pi, (val ? true : false)); - } -} - -/* - * ucode, hwmac update - * Channel dependent updates for ucode and hw - */ -static void wlc_ucode_mac_upd(struct wlc_info *wlc) -{ - /* enable or disable any active IBSSs depending on whether or not - * we are on the home channel - */ - if (wlc->home_chanspec == WLC_BAND_PI_RADIO_CHANSPEC) { - if (wlc->pub->associated) { - /* BMAC_NOTE: This is something that should be fixed in ucode inits. - * I think that the ucode inits set up the bcn templates and shm values - * with a bogus beacon. This should not be done in the inits. If ucode needs - * to set up a beacon for testing, the test routines should write it down, - * not expect the inits to populate a bogus beacon. - */ - if (WLC_PHY_11N_CAP(wlc->band)) { - wlc_write_shm(wlc, M_BCN_TXTSF_OFFSET, - wlc->band->bcntsfoff); - } - } - } else { - /* disable an active IBSS if we are not on the home channel */ - } - - /* update the various promisc bits */ - wlc_mac_bcn_promisc(wlc); - wlc_mac_promisc(wlc); -} - -static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec) -{ - wlc_rateset_t default_rateset; - uint parkband; - uint i, band_order[2]; - - WL_TRACE("wl%d: wlc_bandinit_ordered\n", wlc->pub->unit); - /* - * We might have been bandlocked during down and the chip power-cycled (hibernate). - * figure out the right band to park on - */ - if (wlc->bandlocked || NBANDS(wlc) == 1) { - ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit); - - parkband = wlc->band->bandunit; /* updated in wlc_bandlock() */ - band_order[0] = band_order[1] = parkband; - } else { - /* park on the band of the specified chanspec */ - parkband = CHSPEC_WLCBANDUNIT(chanspec); - - /* order so that parkband initialize last */ - band_order[0] = parkband ^ 1; - band_order[1] = parkband; - } - - /* make each band operational, software state init */ - for (i = 0; i < NBANDS(wlc); i++) { - uint j = band_order[i]; - - wlc->band = wlc->bandstate[j]; - - wlc_default_rateset(wlc, &default_rateset); - - /* fill in hw_rate */ - wlc_rateset_filter(&default_rateset, &wlc->band->hw_rateset, - false, WLC_RATES_CCK_OFDM, RATE_MASK, - (bool) N_ENAB(wlc->pub)); - - /* init basic rate lookup */ - wlc_rate_lookup_init(wlc, &default_rateset); - } - - /* sync up phy/radio chanspec */ - wlc_set_phy_chanspec(wlc, chanspec); -} - -/* band-specific init */ -static void WLBANDINITFN(wlc_bsinit) (struct wlc_info *wlc) -{ - WL_TRACE("wl%d: wlc_bsinit: bandunit %d\n", - wlc->pub->unit, wlc->band->bandunit); - - /* write ucode ACK/CTS rate table */ - wlc_set_ratetable(wlc); - - /* update some band specific mac configuration */ - wlc_ucode_mac_upd(wlc); - - /* init antenna selection */ - wlc_antsel_init(wlc->asi); - -} - -/* switch to and initialize new band */ -static void WLBANDINITFN(wlc_setband) (struct wlc_info *wlc, uint bandunit) -{ - int idx; - wlc_bsscfg_t *cfg; - - ASSERT(NBANDS(wlc) > 1); - ASSERT(!wlc->bandlocked); - ASSERT(bandunit != wlc->band->bandunit || wlc->bandinit_pending); - - wlc->band = wlc->bandstate[bandunit]; - - if (!wlc->pub->up) - return; - - /* wait for at least one beacon before entering sleeping state */ - wlc->PMawakebcn = true; - FOREACH_AS_STA(wlc, idx, cfg) - cfg->PMawakebcn = true; - wlc_set_ps_ctrl(wlc); - - /* band-specific initializations */ - wlc_bsinit(wlc); -} - -/* Initialize a WME Parameter Info Element with default STA parameters from WMM Spec, Table 12 */ -void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe) -{ - static const wme_param_ie_t stadef = { - WME_OUI, - WME_TYPE, - WME_SUBTYPE_PARAM_IE, - WME_VER, - 0, - 0, - { - {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA, - cpu_to_le16(EDCF_AC_BE_TXOP_STA)}, - {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA, - cpu_to_le16(EDCF_AC_BK_TXOP_STA)}, - {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA, - cpu_to_le16(EDCF_AC_VI_TXOP_STA)}, - {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA, - cpu_to_le16(EDCF_AC_VO_TXOP_STA)} - } - }; - - ASSERT(sizeof(*pe) == WME_PARAM_IE_LEN); - memcpy(pe, &stadef, sizeof(*pe)); -} - -void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend) -{ - int i; - shm_acparams_t acp_shm; - u16 *shm_entry; - struct ieee80211_tx_queue_params *params = arg; - - ASSERT(wlc); - - /* Only apply params if the core is out of reset and has clocks */ - if (!wlc->clk) { - WL_ERROR("wl%d: %s : no-clock\n", wlc->pub->unit, __func__); - return; - } - - /* - * AP uses AC params from wme_param_ie_ap. - * AP advertises AC params from wme_param_ie. - * STA uses AC params from wme_param_ie. - */ - - wlc->wme_admctl = 0; - - do { - memset((char *)&acp_shm, 0, sizeof(shm_acparams_t)); - /* find out which ac this set of params applies to */ - ASSERT(aci < AC_COUNT); - /* set the admission control policy for this AC */ - /* wlc->wme_admctl |= 1 << aci; *//* should be set ?? seems like off by default */ - - /* fill in shm ac params struct */ - acp_shm.txop = le16_to_cpu(params->txop); - /* convert from units of 32us to us for ucode */ - wlc->edcf_txop[aci & 0x3] = acp_shm.txop = - EDCF_TXOP2USEC(acp_shm.txop); - acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK); - - if (aci == AC_VI && acp_shm.txop == 0 - && acp_shm.aifs < EDCF_AIFSN_MAX) - acp_shm.aifs++; - - if (acp_shm.aifs < EDCF_AIFSN_MIN - || acp_shm.aifs > EDCF_AIFSN_MAX) { - WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n", - wlc->pub->unit, acp_shm.aifs); - continue; - } - - acp_shm.cwmin = params->cw_min; - acp_shm.cwmax = params->cw_max; - acp_shm.cwcur = acp_shm.cwmin; - acp_shm.bslots = - R_REG(&wlc->regs->tsf_random) & acp_shm.cwcur; - acp_shm.reggap = acp_shm.bslots + acp_shm.aifs; - /* Indicate the new params to the ucode */ - acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO + - wme_shmemacindex(aci) * - M_EDCF_QLEN + - M_EDCF_STATUS_OFF)); - acp_shm.status |= WME_STATUS_NEWAC; - - /* Fill in shm acparam table */ - shm_entry = (u16 *) &acp_shm; - for (i = 0; i < (int)sizeof(shm_acparams_t); i += 2) - wlc_write_shm(wlc, - M_EDCF_QINFO + - wme_shmemacindex(aci) * M_EDCF_QLEN + i, - *shm_entry++); - - } while (0); - - if (suspend) - wlc_suspend_mac_and_wait(wlc); - - if (suspend) - wlc_enable_mac(wlc); - -} - -void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend) -{ - struct wlc_info *wlc = cfg->wlc; - uint aci, i, j; - edcf_acparam_t *edcf_acp; - shm_acparams_t acp_shm; - u16 *shm_entry; - - ASSERT(cfg); - ASSERT(wlc); - - /* Only apply params if the core is out of reset and has clocks */ - if (!wlc->clk) - return; - - /* - * AP uses AC params from wme_param_ie_ap. - * AP advertises AC params from wme_param_ie. - * STA uses AC params from wme_param_ie. - */ - - edcf_acp = (edcf_acparam_t *) &wlc->wme_param_ie.acparam[0]; - - wlc->wme_admctl = 0; - - for (i = 0; i < AC_COUNT; i++, edcf_acp++) { - memset((char *)&acp_shm, 0, sizeof(shm_acparams_t)); - /* find out which ac this set of params applies to */ - aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT; - ASSERT(aci < AC_COUNT); - /* set the admission control policy for this AC */ - if (edcf_acp->ACI & EDCF_ACM_MASK) { - wlc->wme_admctl |= 1 << aci; - } - - /* fill in shm ac params struct */ - acp_shm.txop = le16_to_cpu(edcf_acp->TXOP); - /* convert from units of 32us to us for ucode */ - wlc->edcf_txop[aci] = acp_shm.txop = - EDCF_TXOP2USEC(acp_shm.txop); - acp_shm.aifs = (edcf_acp->ACI & EDCF_AIFSN_MASK); - - if (aci == AC_VI && acp_shm.txop == 0 - && acp_shm.aifs < EDCF_AIFSN_MAX) - acp_shm.aifs++; - - if (acp_shm.aifs < EDCF_AIFSN_MIN - || acp_shm.aifs > EDCF_AIFSN_MAX) { - WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n", - wlc->pub->unit, acp_shm.aifs); - continue; - } - - /* CWmin = 2^(ECWmin) - 1 */ - acp_shm.cwmin = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK); - /* CWmax = 2^(ECWmax) - 1 */ - acp_shm.cwmax = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK) - >> EDCF_ECWMAX_SHIFT); - acp_shm.cwcur = acp_shm.cwmin; - acp_shm.bslots = - R_REG(&wlc->regs->tsf_random) & acp_shm.cwcur; - acp_shm.reggap = acp_shm.bslots + acp_shm.aifs; - /* Indicate the new params to the ucode */ - acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO + - wme_shmemacindex(aci) * - M_EDCF_QLEN + - M_EDCF_STATUS_OFF)); - acp_shm.status |= WME_STATUS_NEWAC; - - /* Fill in shm acparam table */ - shm_entry = (u16 *) &acp_shm; - for (j = 0; j < (int)sizeof(shm_acparams_t); j += 2) - wlc_write_shm(wlc, - M_EDCF_QINFO + - wme_shmemacindex(aci) * M_EDCF_QLEN + j, - *shm_entry++); - } - - if (suspend) - wlc_suspend_mac_and_wait(wlc); - - if (AP_ENAB(wlc->pub) && WME_ENAB(wlc->pub)) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, false); - } - - if (suspend) - wlc_enable_mac(wlc); - -} - -bool wlc_timers_init(struct wlc_info *wlc, int unit) -{ - wlc->wdtimer = wl_init_timer(wlc->wl, wlc_watchdog_by_timer, - wlc, "watchdog"); - if (!wlc->wdtimer) { - WL_ERROR("wl%d: wl_init_timer for wdtimer failed\n", unit); - goto fail; - } - - wlc->radio_timer = wl_init_timer(wlc->wl, wlc_radio_timer, - wlc, "radio"); - if (!wlc->radio_timer) { - WL_ERROR("wl%d: wl_init_timer for radio_timer failed\n", unit); - goto fail; - } - - return true; - - fail: - return false; -} - -/* - * Initialize wlc_info default values ... - * may get overrides later in this function - */ -void wlc_info_init(struct wlc_info *wlc, int unit) -{ - int i; - /* Assume the device is there until proven otherwise */ - wlc->device_present = true; - - /* set default power output percentage to 100 percent */ - wlc->txpwr_percent = 100; - - /* Save our copy of the chanspec */ - wlc->chanspec = CH20MHZ_CHSPEC(1); - - /* initialize CCK preamble mode to unassociated state */ - wlc->shortpreamble = false; - - wlc->legacy_probe = true; - - /* various 802.11g modes */ - wlc->shortslot = false; - wlc->shortslot_override = WLC_SHORTSLOT_AUTO; - - wlc->barker_overlap_control = true; - wlc->barker_preamble = WLC_BARKER_SHORT_ALLOWED; - wlc->txburst_limit_override = AUTO; - - wlc_protection_upd(wlc, WLC_PROT_G_OVR, WLC_PROTECTION_AUTO); - wlc_protection_upd(wlc, WLC_PROT_G_SPEC, false); - - wlc_protection_upd(wlc, WLC_PROT_N_CFG_OVR, WLC_PROTECTION_AUTO); - wlc_protection_upd(wlc, WLC_PROT_N_CFG, WLC_N_PROTECTION_OFF); - wlc_protection_upd(wlc, WLC_PROT_N_NONGF_OVR, WLC_PROTECTION_AUTO); - wlc_protection_upd(wlc, WLC_PROT_N_NONGF, false); - wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR, AUTO); - - wlc_protection_upd(wlc, WLC_PROT_OVERLAP, WLC_PROTECTION_CTL_OVERLAP); - - /* 802.11g draft 4.0 NonERP elt advertisement */ - wlc->include_legacy_erp = true; - - wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF; - wlc->stf->txant = ANT_TX_DEF; - - wlc->prb_resp_timeout = WLC_PRB_RESP_TIMEOUT; - - wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN; - for (i = 0; i < NFIFO; i++) - wlc->fragthresh[i] = DOT11_DEFAULT_FRAG_LEN; - wlc->RTSThresh = DOT11_DEFAULT_RTS_LEN; - - /* default rate fallback retry limits */ - wlc->SFBL = RETRY_SHORT_FB; - wlc->LFBL = RETRY_LONG_FB; - - /* default mac retry limits */ - wlc->SRL = RETRY_SHORT_DEF; - wlc->LRL = RETRY_LONG_DEF; - - /* init PM state */ - wlc->PM = PM_OFF; /* User's setting of PM mode through IOCTL */ - wlc->PM_override = false; /* Prevents from going to PM if our AP is 'ill' */ - wlc->PMenabled = false; /* Current PM state */ - wlc->PMpending = false; /* Tracks whether STA indicated PM in the last attempt */ - wlc->PMblocked = false; /* To allow blocking going into PM during RM and scans */ - - /* In WMM Auto mode, PM is allowed if association is a UAPSD association */ - wlc->WME_PM_blocked = false; - - /* Init wme queuing method */ - wlc->wme_prec_queuing = false; - - /* Overrides for the core to stay awake under zillion conditions Look for STAY_AWAKE */ - wlc->wake = false; - /* Are we waiting for a response to PS-Poll that we sent */ - wlc->PSpoll = false; - - /* APSD defaults */ - wlc->wme_apsd = true; - wlc->apsd_sta_usp = false; - wlc->apsd_trigger_timeout = 0; /* disable the trigger timer */ - wlc->apsd_trigger_ac = AC_BITMAP_ALL; - - /* Set flag to indicate that hw keys should be used when available. */ - wlc->wsec_swkeys = false; - - /* init the 4 static WEP default keys */ - for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) { - wlc->wsec_keys[i] = wlc->wsec_def_keys[i]; - wlc->wsec_keys[i]->idx = (u8) i; - } - - wlc->_regulatory_domain = false; /* 802.11d */ - - /* WME QoS mode is Auto by default */ - wlc->pub->_wme = AUTO; - -#ifdef BCMSDIODEV_ENABLED - wlc->pub->_priofc = true; /* enable priority flow control for sdio dongle */ -#endif - - wlc->pub->_ampdu = AMPDU_AGG_HOST; - wlc->pub->bcmerror = 0; - wlc->ibss_allowed = true; - wlc->ibss_coalesce_allowed = true; - wlc->pub->_coex = ON; - - /* initialize mpc delay */ - wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; - - wlc->pr80838_war = true; -} - -static bool wlc_state_bmac_sync(struct wlc_info *wlc) -{ - wlc_bmac_state_t state_bmac; - - if (wlc_bmac_state_get(wlc->hw, &state_bmac) != 0) - return false; - - wlc->machwcap = state_bmac.machwcap; - wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR, - (s8) state_bmac.preamble_ovr); - - return true; -} - -static uint wlc_attach_module(struct wlc_info *wlc) -{ - uint err = 0; - uint unit; - unit = wlc->pub->unit; - - wlc->asi = wlc_antsel_attach(wlc); - if (wlc->asi == NULL) { - WL_ERROR("wl%d: wlc_attach: wlc_antsel_attach failed\n", unit); - err = 44; - goto fail; - } - - wlc->ampdu = wlc_ampdu_attach(wlc); - if (wlc->ampdu == NULL) { - WL_ERROR("wl%d: wlc_attach: wlc_ampdu_attach failed\n", unit); - err = 50; - goto fail; - } - - if ((wlc_stf_attach(wlc) != 0)) { - WL_ERROR("wl%d: wlc_attach: wlc_stf_attach failed\n", unit); - err = 68; - goto fail; - } - fail: - return err; -} - -struct wlc_pub *wlc_pub(void *wlc) -{ - return ((struct wlc_info *) wlc)->pub; -} - -#define CHIP_SUPPORTS_11N(wlc) 1 - -/* - * The common driver entry routine. Error codes should be unique - */ -void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, - struct osl_info *osh, void *regsva, uint bustype, - void *btparam, uint *perr) -{ - struct wlc_info *wlc; - uint err = 0; - uint j; - struct wlc_pub *pub; - struct wlc_txq_info *qi; - uint n_disabled; - - WL_NONE("wl%d: %s: vendor 0x%x device 0x%x\n", - unit, __func__, vendor, device); - - ASSERT(WSEC_MAX_RCMTA_KEYS <= WSEC_MAX_KEYS); - ASSERT(WSEC_MAX_DEFAULT_KEYS == WLC_DEFAULT_KEYS); - - /* some code depends on packed structures */ - ASSERT(sizeof(struct ethhdr) == ETH_HLEN); - ASSERT(sizeof(d11regs_t) == SI_CORE_SIZE); - ASSERT(sizeof(ofdm_phy_hdr_t) == D11_PHY_HDR_LEN); - ASSERT(sizeof(cck_phy_hdr_t) == D11_PHY_HDR_LEN); - ASSERT(sizeof(d11txh_t) == D11_TXH_LEN); - ASSERT(sizeof(d11rxhdr_t) == RXHDR_LEN); - ASSERT(sizeof(struct ieee80211_hdr) == DOT11_A4_HDR_LEN); - ASSERT(sizeof(struct ieee80211_rts) == DOT11_RTS_LEN); - ASSERT(sizeof(tx_status_t) == TXSTATUS_LEN); - ASSERT(sizeof(struct ieee80211_ht_cap) == HT_CAP_IE_LEN); -#ifdef BRCM_FULLMAC - ASSERT(offsetof(wl_scan_params_t, channel_list) == - WL_SCAN_PARAMS_FIXED_SIZE); -#endif - ASSERT(IS_ALIGNED(offsetof(wsec_key_t, data), sizeof(u32))); - ASSERT(ISPOWEROF2(MA_WINDOW_SZ)); - - ASSERT(sizeof(wlc_d11rxhdr_t) <= WL_HWRXOFF); - - /* - * Number of replay counters value used in WPA IE must match # rxivs - * supported in wsec_key_t struct. See 802.11i/D3.0 sect. 7.3.2.17 - * 'RSN Information Element' figure 8 for this mapping. - */ - ASSERT((WPA_CAP_16_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE - && 16 == WLC_NUMRXIVS) - || (WPA_CAP_4_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE - && 4 == WLC_NUMRXIVS)); - - /* allocate struct wlc_info state and its substructures */ - wlc = (struct wlc_info *) wlc_attach_malloc(unit, &err, device); - if (wlc == NULL) - goto fail; - wlc->osh = osh; - pub = wlc->pub; - -#if defined(BCMDBG) - wlc_info_dbg = wlc; -#endif - - wlc->band = wlc->bandstate[0]; - wlc->core = wlc->corestate; - wlc->wl = wl; - pub->unit = unit; - pub->osh = osh; - wlc->btparam = btparam; - pub->_piomode = piomode; - wlc->bandinit_pending = false; - /* By default restrict TKIP associations from 11n STA's */ - wlc->ht_wsec_restriction = WLC_HT_TKIP_RESTRICT; - - /* populate struct wlc_info with default values */ - wlc_info_init(wlc, unit); - - /* update sta/ap related parameters */ - wlc_ap_upd(wlc); - - /* 11n_disable nvram */ - n_disabled = getintvar(pub->vars, "11n_disable"); - - /* register a module (to handle iovars) */ - wlc_module_register(wlc->pub, wlc_iovars, "wlc_iovars", wlc, - wlc_doiovar, NULL, NULL); - - /* low level attach steps(all hw accesses go inside, no more in rest of the attach) */ - err = wlc_bmac_attach(wlc, vendor, device, unit, piomode, osh, regsva, - bustype, btparam); - if (err) - goto fail; - - /* for some states, due to different info pointer(e,g, wlc, wlc_hw) or master/slave split, - * HIGH driver(both monolithic and HIGH_ONLY) needs to sync states FROM BMAC portion driver - */ - if (!wlc_state_bmac_sync(wlc)) { - err = 20; - goto fail; - } - - pub->phy_11ncapable = WLC_PHY_11N_CAP(wlc->band); - - /* propagate *vars* from BMAC driver to high driver */ - wlc_bmac_copyfrom_vars(wlc->hw, &pub->vars, &wlc->vars_size); - - - /* set maximum allowed duty cycle */ - wlc->tx_duty_cycle_ofdm = - (u16) getintvar(pub->vars, "tx_duty_cycle_ofdm"); - wlc->tx_duty_cycle_cck = - (u16) getintvar(pub->vars, "tx_duty_cycle_cck"); - - wlc_stf_phy_chain_calc(wlc); - - /* txchain 1: txant 0, txchain 2: txant 1 */ - if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1)) - wlc->stf->txant = wlc->stf->hw_txchain - 1; - - /* push to BMAC driver */ - wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain, - wlc->stf->hw_rxchain); - - /* pull up some info resulting from the low attach */ - { - int i; - for (i = 0; i < NFIFO; i++) - wlc->core->txavail[i] = wlc->hw->txavail[i]; - } - - wlc_bmac_hw_etheraddr(wlc->hw, wlc->perm_etheraddr); - - memcpy(&pub->cur_etheraddr, &wlc->perm_etheraddr, ETH_ALEN); - - for (j = 0; j < NBANDS(wlc); j++) { - /* Use band 1 for single band 11a */ - if (IS_SINGLEBAND_5G(wlc->deviceid)) - j = BAND_5G_INDEX; - - wlc->band = wlc->bandstate[j]; - - if (!wlc_attach_stf_ant_init(wlc)) { - err = 24; - goto fail; - } - - /* default contention windows size limits */ - wlc->band->CWmin = APHY_CWMIN; - wlc->band->CWmax = PHY_CWMAX; - - /* init gmode value */ - if (BAND_2G(wlc->band->bandtype)) { - wlc->band->gmode = GMODE_AUTO; - wlc_protection_upd(wlc, WLC_PROT_G_USER, - wlc->band->gmode); - } - - /* init _n_enab supported mode */ - if (WLC_PHY_11N_CAP(wlc->band) && CHIP_SUPPORTS_11N(wlc)) { - if (n_disabled & WLFEATURE_DISABLE_11N) { - pub->_n_enab = OFF; - wlc_protection_upd(wlc, WLC_PROT_N_USER, OFF); - } else { - pub->_n_enab = SUPPORT_11N; - wlc_protection_upd(wlc, WLC_PROT_N_USER, - ((pub->_n_enab == - SUPPORT_11N) ? WL_11N_2x2 : - WL_11N_3x3)); - } - } - - /* init per-band default rateset, depend on band->gmode */ - wlc_default_rateset(wlc, &wlc->band->defrateset); - - /* fill in hw_rateset (used early by WLC_SET_RATESET) */ - wlc_rateset_filter(&wlc->band->defrateset, - &wlc->band->hw_rateset, false, - WLC_RATES_CCK_OFDM, RATE_MASK, - (bool) N_ENAB(wlc->pub)); - } - - /* update antenna config due to wlc->stf->txant/txchain/ant_rx_ovr change */ - wlc_stf_phy_txant_upd(wlc); - - /* attach each modules */ - err = wlc_attach_module(wlc); - if (err != 0) - goto fail; - - if (!wlc_timers_init(wlc, unit)) { - WL_ERROR("wl%d: %s: wlc_init_timer failed\n", unit, __func__); - err = 32; - goto fail; - } - - /* depend on rateset, gmode */ - wlc->cmi = wlc_channel_mgr_attach(wlc); - if (!wlc->cmi) { - WL_ERROR("wl%d: %s: wlc_channel_mgr_attach failed\n", - unit, __func__); - err = 33; - goto fail; - } - - /* init default when all parameters are ready, i.e. ->rateset */ - wlc_bss_default_init(wlc); - - /* - * Complete the wlc default state initializations.. - */ - - /* allocate our initial queue */ - qi = wlc_txq_alloc(wlc, osh); - if (qi == NULL) { - WL_ERROR("wl%d: %s: failed to malloc tx queue\n", - unit, __func__); - err = 100; - goto fail; - } - wlc->active_queue = qi; - - wlc->bsscfg[0] = wlc->cfg; - wlc->cfg->_idx = 0; - wlc->cfg->wlc = wlc; - pub->txmaxpkts = MAXTXPKTS; - - pub->_cnt->version = WL_CNT_T_VERSION; - pub->_cnt->length = sizeof(struct wl_cnt); - - WLCNTSET(pub->_wme_cnt->version, WL_WME_CNT_VERSION); - WLCNTSET(pub->_wme_cnt->length, sizeof(wl_wme_cnt_t)); - - wlc_wme_initparams_sta(wlc, &wlc->wme_param_ie); - - wlc->mimoft = FT_HT; - wlc->ht_cap.cap_info = HT_CAP; - if (HT_ENAB(wlc->pub)) - wlc->stf->ldpc = AUTO; - - wlc->mimo_40txbw = AUTO; - wlc->ofdm_40txbw = AUTO; - wlc->cck_40txbw = AUTO; - wlc_update_mimo_band_bwcap(wlc, WLC_N_BW_20IN2G_40IN5G); - - /* Enable setting the RIFS Mode bit by default in HT Info IE */ - wlc->rifs_advert = AUTO; - - /* Set default values of SGI */ - if (WLC_SGI_CAP_PHY(wlc)) { - wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40)); - wlc->sgi_tx = AUTO; - } else if (WLCISSSLPNPHY(wlc->band)) { - wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40)); - wlc->sgi_tx = AUTO; - } else { - wlc_ht_update_sgi_rx(wlc, 0); - wlc->sgi_tx = OFF; - } - - /* *******nvram 11n config overrides Start ********* */ - - /* apply the sgi override from nvram conf */ - if (n_disabled & WLFEATURE_DISABLE_11N_SGI_TX) - wlc->sgi_tx = OFF; - - if (n_disabled & WLFEATURE_DISABLE_11N_SGI_RX) - wlc_ht_update_sgi_rx(wlc, 0); - - /* apply the stbc override from nvram conf */ - if (n_disabled & WLFEATURE_DISABLE_11N_STBC_TX) { - wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF; - wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF; - wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC; - } - if (n_disabled & WLFEATURE_DISABLE_11N_STBC_RX) - wlc_stf_stbc_rx_set(wlc, HT_CAP_RX_STBC_NO); - - /* apply the GF override from nvram conf */ - if (n_disabled & WLFEATURE_DISABLE_11N_GF) - wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_GRN_FLD; - - /* initialize radio_mpc_disable according to wlc->mpc */ - wlc_radio_mpc_upd(wlc); - - if ((wlc->pub->sih->chip) == BCM43235_CHIP_ID) { - if ((getintvar(wlc->pub->vars, "aa2g") == 7) || - (getintvar(wlc->pub->vars, "aa5g") == 7)) { - wlc_bmac_antsel_set(wlc->hw, 1); - } - } else { - wlc_bmac_antsel_set(wlc->hw, wlc->asi->antsel_avail); - } - - if (perr) - *perr = 0; - - return (void *)wlc; - - fail: - WL_ERROR("wl%d: %s: failed with err %d\n", unit, __func__, err); - if (wlc) - wlc_detach(wlc); - - if (perr) - *perr = err; - return NULL; -} - -static void wlc_attach_antgain_init(struct wlc_info *wlc) -{ - uint unit; - unit = wlc->pub->unit; - - if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) { - /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */ - wlc->band->antgain = 8; - } else if (wlc->band->antgain == -1) { - WL_ERROR("wl%d: %s: Invalid antennas available in srom, using 2dB\n", - unit, __func__); - wlc->band->antgain = 8; - } else { - s8 gain, fract; - /* Older sroms specified gain in whole dbm only. In order - * be able to specify qdbm granularity and remain backward compatible - * the whole dbms are now encoded in only low 6 bits and remaining qdbms - * are encoded in the hi 2 bits. 6 bit signed number ranges from - * -32 - 31. Examples: 0x1 = 1 db, - * 0xc1 = 1.75 db (1 + 3 quarters), - * 0x3f = -1 (-1 + 0 quarters), - * 0x7f = -.75 (-1 in low 6 bits + 1 quarters in hi 2 bits) = -3 qdbm. - * 0xbf = -.50 (-1 in low 6 bits + 2 quarters in hi 2 bits) = -2 qdbm. - */ - gain = wlc->band->antgain & 0x3f; - gain <<= 2; /* Sign extend */ - gain >>= 2; - fract = (wlc->band->antgain & 0xc0) >> 6; - wlc->band->antgain = 4 * gain + fract; - } -} - -static bool wlc_attach_stf_ant_init(struct wlc_info *wlc) -{ - int aa; - uint unit; - char *vars; - int bandtype; - - unit = wlc->pub->unit; - vars = wlc->pub->vars; - bandtype = wlc->band->bandtype; - - /* get antennas available */ - aa = (s8) getintvar(vars, (BAND_5G(bandtype) ? "aa5g" : "aa2g")); - if (aa == 0) - aa = (s8) getintvar(vars, - (BAND_5G(bandtype) ? "aa1" : "aa0")); - if ((aa < 1) || (aa > 15)) { - WL_ERROR("wl%d: %s: Invalid antennas available in srom (0x%x), using 3\n", - unit, __func__, aa); - aa = 3; - } - - /* reset the defaults if we have a single antenna */ - if (aa == 1) { - wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_0; - wlc->stf->txant = ANT_TX_FORCE_0; - } else if (aa == 2) { - wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_1; - wlc->stf->txant = ANT_TX_FORCE_1; - } else { - } - - /* Compute Antenna Gain */ - wlc->band->antgain = - (s8) getintvar(vars, (BAND_5G(bandtype) ? "ag1" : "ag0")); - wlc_attach_antgain_init(wlc); - - return true; -} - - -static void wlc_timers_deinit(struct wlc_info *wlc) -{ - /* free timer state */ - if (wlc->wdtimer) { - wl_free_timer(wlc->wl, wlc->wdtimer); - wlc->wdtimer = NULL; - } - if (wlc->radio_timer) { - wl_free_timer(wlc->wl, wlc->radio_timer); - wlc->radio_timer = NULL; - } -} - -static void wlc_detach_module(struct wlc_info *wlc) -{ - if (wlc->asi) { - wlc_antsel_detach(wlc->asi); - wlc->asi = NULL; - } - - if (wlc->ampdu) { - wlc_ampdu_detach(wlc->ampdu); - wlc->ampdu = NULL; - } - - wlc_stf_detach(wlc); -} - -/* - * Return a count of the number of driver callbacks still pending. - * - * General policy is that wlc_detach can only dealloc/free software states. It can NOT - * touch hardware registers since the d11core may be in reset and clock may not be available. - * One exception is sb register access, which is possible if crystal is turned on - * After "down" state, driver should avoid software timer with the exception of radio_monitor. - */ -uint wlc_detach(struct wlc_info *wlc) -{ - uint i; - uint callbacks = 0; - - if (wlc == NULL) - return 0; - - WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__); - - ASSERT(!wlc->pub->up); - - callbacks += wlc_bmac_detach(wlc); - - /* delete software timers */ - if (!wlc_radio_monitor_stop(wlc)) - callbacks++; - - wlc_channel_mgr_detach(wlc->cmi); - - wlc_timers_deinit(wlc); - - wlc_detach_module(wlc); - - /* free other state */ - - -#ifdef BCMDBG - if (wlc->country_ie_override) { - kfree(wlc->country_ie_override); - wlc->country_ie_override = NULL; - } -#endif /* BCMDBG */ - - { - /* free dumpcb list */ - struct dumpcb_s *prev, *ptr; - prev = ptr = wlc->dumpcb_head; - while (ptr) { - ptr = prev->next; - kfree(prev); - prev = ptr; - } - wlc->dumpcb_head = NULL; - } - - /* Detach from iovar manager */ - wlc_module_unregister(wlc->pub, "wlc_iovars", wlc); - - while (wlc->tx_queues != NULL) { - wlc_txq_free(wlc, wlc->osh, wlc->tx_queues); - } - - /* - * consistency check: wlc_module_register/wlc_module_unregister calls - * should match therefore nothing should be left here. - */ - for (i = 0; i < WLC_MAXMODULES; i++) - ASSERT(wlc->modulecb[i].name[0] == '\0'); - - wlc_detach_mfree(wlc); - return callbacks; -} - -/* update state that depends on the current value of "ap" */ -void wlc_ap_upd(struct wlc_info *wlc) -{ - if (AP_ENAB(wlc->pub)) - wlc->PLCPHdr_override = WLC_PLCP_AUTO; /* AP: short not allowed, but not enforced */ - else - wlc->PLCPHdr_override = WLC_PLCP_SHORT; /* STA-BSS; short capable */ - - /* disable vlan_mode on AP since some legacy STAs cannot rx tagged pkts */ - wlc->vlan_mode = AP_ENAB(wlc->pub) ? OFF : AUTO; - - /* fixup mpc */ - wlc->mpc = true; -} - -/* read hwdisable state and propagate to wlc flag */ -static void wlc_radio_hwdisable_upd(struct wlc_info *wlc) -{ - if (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO || wlc->pub->hw_off) - return; - - if (wlc_bmac_radio_read_hwdisabled(wlc->hw)) { - mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); - } else { - mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); - } -} - -/* return true if Minimum Power Consumption should be entered, false otherwise */ -bool wlc_is_non_delay_mpc(struct wlc_info *wlc) -{ - return false; -} - -bool wlc_ismpc(struct wlc_info *wlc) -{ - return (wlc->mpc_delay_off == 0) && (wlc_is_non_delay_mpc(wlc)); -} - -void wlc_radio_mpc_upd(struct wlc_info *wlc) -{ - bool mpc_radio, radio_state; - - /* - * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled - * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio - * monitor also when WL_RADIO_MPC_DISABLE is the only reason that - * the radio is going down. - */ - if (!wlc->mpc) { - if (!wlc->pub->radio_disabled) - return; - mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); - wlc_radio_upd(wlc); - if (!wlc->pub->radio_disabled) - wlc_radio_monitor_stop(wlc); - return; - } - - /* - * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in wlc->pub->radio_disabled - * to go ON, always call radio_upd synchronously - * to go OFF, postpone radio_upd to later when context is safe(e.g. watchdog) - */ - radio_state = - (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF : - ON); - mpc_radio = (wlc_ismpc(wlc) == true) ? OFF : ON; - - if (radio_state == ON && mpc_radio == OFF) - wlc->mpc_delay_off = wlc->mpc_dlycnt; - else if (radio_state == OFF && mpc_radio == ON) { - mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); - wlc_radio_upd(wlc); - if (wlc->mpc_offcnt < WLC_MPC_THRESHOLD) { - wlc->mpc_dlycnt = WLC_MPC_MAX_DELAYCNT; - } else - wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; - wlc->mpc_dur += OSL_SYSUPTIME() - wlc->mpc_laston_ts; - } - /* Below logic is meant to capture the transition from mpc off to mpc on for reasons - * other than wlc->mpc_delay_off keeping the mpc off. In that case reset - * wlc->mpc_delay_off to wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off - */ - if ((wlc->prev_non_delay_mpc == false) && - (wlc_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off) { - wlc->mpc_delay_off = wlc->mpc_dlycnt; - } - wlc->prev_non_delay_mpc = wlc_is_non_delay_mpc(wlc); -} - -/* - * centralized radio disable/enable function, - * invoke radio enable/disable after updating hwradio status - */ -static void wlc_radio_upd(struct wlc_info *wlc) -{ - if (wlc->pub->radio_disabled) { - wlc_radio_disable(wlc); - } else { - wlc_radio_enable(wlc); - } -} - -/* maintain LED behavior in down state */ -static void wlc_down_led_upd(struct wlc_info *wlc) -{ - ASSERT(!wlc->pub->up); - - /* maintain LEDs while in down state, turn on sbclk if not available yet */ - /* turn on sbclk if necessary */ - if (!AP_ENAB(wlc->pub)) { - wlc_pllreq(wlc, true, WLC_PLLREQ_FLIP); - - wlc_pllreq(wlc, false, WLC_PLLREQ_FLIP); - } -} - -/* update hwradio status and return it */ -bool wlc_check_radio_disabled(struct wlc_info *wlc) -{ - wlc_radio_hwdisable_upd(wlc); - - return mboolisset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE) ? true : false; -} - -void wlc_radio_disable(struct wlc_info *wlc) -{ - if (!wlc->pub->up) { - wlc_down_led_upd(wlc); - return; - } - - wlc_radio_monitor_start(wlc); - wl_down(wlc->wl); -} - -static void wlc_radio_enable(struct wlc_info *wlc) -{ - if (wlc->pub->up) - return; - - if (DEVICEREMOVED(wlc)) - return; - - if (!wlc->down_override) { /* imposed by wl down/out ioctl */ - wl_up(wlc->wl); - } -} - -/* periodical query hw radio button while driver is "down" */ -static void wlc_radio_timer(void *arg) -{ - struct wlc_info *wlc = (struct wlc_info *) arg; - - if (DEVICEREMOVED(wlc)) { - WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); - wl_down(wlc->wl); - return; - } - - /* cap mpc off count */ - if (wlc->mpc_offcnt < WLC_MPC_MAX_DELAYCNT) - wlc->mpc_offcnt++; - - /* validate all the reasons driver could be down and running this radio_timer */ - ASSERT(wlc->pub->radio_disabled || wlc->down_override); - wlc_radio_hwdisable_upd(wlc); - wlc_radio_upd(wlc); -} - -static bool wlc_radio_monitor_start(struct wlc_info *wlc) -{ - /* Don't start the timer if HWRADIO feature is disabled */ - if (wlc->radio_monitor || (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO)) - return true; - - wlc->radio_monitor = true; - wlc_pllreq(wlc, true, WLC_PLLREQ_RADIO_MON); - wl_add_timer(wlc->wl, wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true); - return true; -} - -bool wlc_radio_monitor_stop(struct wlc_info *wlc) -{ - if (!wlc->radio_monitor) - return true; - - ASSERT((wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO) != - WL_SWFL_NOHWRADIO); - - wlc->radio_monitor = false; - wlc_pllreq(wlc, false, WLC_PLLREQ_RADIO_MON); - return wl_del_timer(wlc->wl, wlc->radio_timer); -} - -/* bring the driver down, but don't reset hardware */ -void wlc_out(struct wlc_info *wlc) -{ - wlc_bmac_set_noreset(wlc->hw, true); - wlc_radio_upd(wlc); - wl_down(wlc->wl); - wlc_bmac_set_noreset(wlc->hw, false); - - /* core clk is true in BMAC driver due to noreset, need to mirror it in HIGH */ - wlc->clk = true; - - /* This will make sure that when 'up' is done - * after 'out' it'll restore hardware (especially gpios) - */ - wlc->pub->hw_up = false; -} - -#if defined(BCMDBG) -/* Verify the sanity of wlc->tx_prec_map. This can be done only by making sure that - * if there is no packet pending for the FIFO, then the corresponding prec bits should be set - * in prec_map. Of course, ignore this rule when block_datafifo is set - */ -static bool wlc_tx_prec_map_verify(struct wlc_info *wlc) -{ - /* For non-WME, both fifos have overlapping prec_map. So it's an error only if both - * fail the check. - */ - if (!EDCF_ENAB(wlc->pub)) { - if (!(WLC_TX_FIFO_CHECK(wlc, TX_DATA_FIFO) || - WLC_TX_FIFO_CHECK(wlc, TX_CTL_FIFO))) - return false; - else - return true; - } - - return WLC_TX_FIFO_CHECK(wlc, TX_AC_BK_FIFO) - && WLC_TX_FIFO_CHECK(wlc, TX_AC_BE_FIFO) - && WLC_TX_FIFO_CHECK(wlc, TX_AC_VI_FIFO) - && WLC_TX_FIFO_CHECK(wlc, TX_AC_VO_FIFO); -} -#endif /* BCMDBG */ - -static void wlc_watchdog_by_timer(void *arg) -{ - struct wlc_info *wlc = (struct wlc_info *) arg; - wlc_watchdog(arg); - if (WLC_WATCHDOG_TBTT(wlc)) { - /* set to normal osl watchdog period */ - wl_del_timer(wlc->wl, wlc->wdtimer); - wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, - true); - } -} - -/* common watchdog code */ -static void wlc_watchdog(void *arg) -{ - struct wlc_info *wlc = (struct wlc_info *) arg; - int i; - wlc_bsscfg_t *cfg; - - WL_TRACE("wl%d: wlc_watchdog\n", wlc->pub->unit); - - if (!wlc->pub->up) - return; - - if (DEVICEREMOVED(wlc)) { - WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); - wl_down(wlc->wl); - return; - } - - /* increment second count */ - wlc->pub->now++; - - /* delay radio disable */ - if (wlc->mpc_delay_off) { - if (--wlc->mpc_delay_off == 0) { - mboolset(wlc->pub->radio_disabled, - WL_RADIO_MPC_DISABLE); - if (wlc->mpc && wlc_ismpc(wlc)) - wlc->mpc_offcnt = 0; - wlc->mpc_laston_ts = OSL_SYSUPTIME(); - } - } - - /* mpc sync */ - wlc_radio_mpc_upd(wlc); - /* radio sync: sw/hw/mpc --> radio_disable/radio_enable */ - wlc_radio_hwdisable_upd(wlc); - wlc_radio_upd(wlc); - /* if ismpc, driver should be in down state if up/down is allowed */ - if (wlc->mpc && wlc_ismpc(wlc)) - ASSERT(!wlc->pub->up); - /* if radio is disable, driver may be down, quit here */ - if (wlc->pub->radio_disabled) - return; - - wlc_bmac_watchdog(wlc); - - /* occasionally sample mac stat counters to detect 16-bit counter wrap */ - if ((wlc->pub->now % SW_TIMER_MAC_STAT_UPD) == 0) - wlc_statsupd(wlc); - - /* Manage TKIP countermeasures timers */ - FOREACH_BSS(wlc, i, cfg) { - if (cfg->tk_cm_dt) { - cfg->tk_cm_dt--; - } - if (cfg->tk_cm_bt) { - cfg->tk_cm_bt--; - } - } - - /* Call any registered watchdog handlers */ - for (i = 0; i < WLC_MAXMODULES; i++) { - if (wlc->modulecb[i].watchdog_fn) - wlc->modulecb[i].watchdog_fn(wlc->modulecb[i].hdl); - } - - if (WLCISNPHY(wlc->band) && !wlc->pub->tempsense_disable && - ((wlc->pub->now - wlc->tempsense_lasttime) >= - WLC_TEMPSENSE_PERIOD)) { - wlc->tempsense_lasttime = wlc->pub->now; - wlc_tempsense_upd(wlc); - } - /* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */ - ASSERT(wlc_bmac_taclear(wlc->hw, true)); - - /* Verify that tx_prec_map and fifos are in sync to avoid lock ups */ - ASSERT(wlc_tx_prec_map_verify(wlc)); - - ASSERT(wlc_ps_check(wlc)); -} - -/* make interface operational */ -int wlc_up(struct wlc_info *wlc) -{ - WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__); - - /* HW is turned off so don't try to access it */ - if (wlc->pub->hw_off || DEVICEREMOVED(wlc)) - return BCME_RADIOOFF; - - if (!wlc->pub->hw_up) { - wlc_bmac_hw_up(wlc->hw); - wlc->pub->hw_up = true; - } - - if ((wlc->pub->boardflags & BFL_FEM) - && (wlc->pub->sih->chip == BCM4313_CHIP_ID)) { - if (wlc->pub->boardrev >= 0x1250 - && (wlc->pub->boardflags & BFL_FEM_BT)) { - wlc_mhf(wlc, MHF5, MHF5_4313_GPIOCTRL, - MHF5_4313_GPIOCTRL, WLC_BAND_ALL); - } else { - wlc_mhf(wlc, MHF4, MHF4_EXTPA_ENABLE, MHF4_EXTPA_ENABLE, - WLC_BAND_ALL); - } - } - - /* - * Need to read the hwradio status here to cover the case where the system - * is loaded with the hw radio disabled. We do not want to bring the driver up in this case. - * if radio is disabled, abort up, lower power, start radio timer and return 0(for NDIS) - * don't call radio_update to avoid looping wlc_up. - * - * wlc_bmac_up_prep() returns either 0 or BCME_RADIOOFF only - */ - if (!wlc->pub->radio_disabled) { - int status = wlc_bmac_up_prep(wlc->hw); - if (status == BCME_RADIOOFF) { - if (!mboolisset - (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) { - int idx; - wlc_bsscfg_t *bsscfg; - mboolset(wlc->pub->radio_disabled, - WL_RADIO_HW_DISABLE); - - FOREACH_BSS(wlc, idx, bsscfg) { - if (!BSSCFG_STA(bsscfg) - || !bsscfg->enable || !bsscfg->BSS) - continue; - WL_ERROR("wl%d.%d: wlc_up: rfdisable -> " "wlc_bsscfg_disable()\n", - wlc->pub->unit, idx); - } - } - } else - ASSERT(!status); - } - - if (wlc->pub->radio_disabled) { - wlc_radio_monitor_start(wlc); - return 0; - } - - /* wlc_bmac_up_prep has done wlc_corereset(). so clk is on, set it */ - wlc->clk = true; - - wlc_radio_monitor_stop(wlc); - - /* Set EDCF hostflags */ - if (EDCF_ENAB(wlc->pub)) { - wlc_mhf(wlc, MHF1, MHF1_EDCF, MHF1_EDCF, WLC_BAND_ALL); - } else { - wlc_mhf(wlc, MHF1, MHF1_EDCF, 0, WLC_BAND_ALL); - } - - if (WLC_WAR16165(wlc)) - wlc_mhf(wlc, MHF2, MHF2_PCISLOWCLKWAR, MHF2_PCISLOWCLKWAR, - WLC_BAND_ALL); - - wl_init(wlc->wl); - wlc->pub->up = true; - - if (wlc->bandinit_pending) { - wlc_suspend_mac_and_wait(wlc); - wlc_set_chanspec(wlc, wlc->default_bss->chanspec); - wlc->bandinit_pending = false; - wlc_enable_mac(wlc); - } - - wlc_bmac_up_finish(wlc->hw); - - /* other software states up after ISR is running */ - /* start APs that were to be brought up but are not up yet */ - /* if (AP_ENAB(wlc->pub)) wlc_restart_ap(wlc->ap); */ - - /* Program the TX wme params with the current settings */ - wlc_wme_retries_write(wlc); - - /* start one second watchdog timer */ - ASSERT(!wlc->WDarmed); - wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true); - wlc->WDarmed = true; - - /* ensure antenna config is up to date */ - wlc_stf_phy_txant_upd(wlc); - /* ensure LDPC config is in sync */ - wlc_ht_update_ldpc(wlc, wlc->stf->ldpc); - - return 0; -} - -/* Initialize the base precedence map for dequeueing from txq based on WME settings */ -static void wlc_tx_prec_map_init(struct wlc_info *wlc) -{ - wlc->tx_prec_map = WLC_PREC_BMP_ALL; - memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16)); - - /* For non-WME, both fifos have overlapping MAXPRIO. So just disable all precedences - * if either is full. - */ - if (!EDCF_ENAB(wlc->pub)) { - wlc->fifo2prec_map[TX_DATA_FIFO] = WLC_PREC_BMP_ALL; - wlc->fifo2prec_map[TX_CTL_FIFO] = WLC_PREC_BMP_ALL; - } else { - wlc->fifo2prec_map[TX_AC_BK_FIFO] = WLC_PREC_BMP_AC_BK; - wlc->fifo2prec_map[TX_AC_BE_FIFO] = WLC_PREC_BMP_AC_BE; - wlc->fifo2prec_map[TX_AC_VI_FIFO] = WLC_PREC_BMP_AC_VI; - wlc->fifo2prec_map[TX_AC_VO_FIFO] = WLC_PREC_BMP_AC_VO; - } -} - -static uint wlc_down_del_timer(struct wlc_info *wlc) -{ - uint callbacks = 0; - - return callbacks; -} - -/* - * Mark the interface nonoperational, stop the software mechanisms, - * disable the hardware, free any transient buffer state. - * Return a count of the number of driver callbacks still pending. - */ -uint wlc_down(struct wlc_info *wlc) -{ - - uint callbacks = 0; - int i; - bool dev_gone = false; - struct wlc_txq_info *qi; - - WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__); - - /* check if we are already in the going down path */ - if (wlc->going_down) { - WL_ERROR("wl%d: %s: Driver going down so return\n", - wlc->pub->unit, __func__); - return 0; - } - if (!wlc->pub->up) - return callbacks; - - /* in between, mpc could try to bring down again.. */ - wlc->going_down = true; - - callbacks += wlc_bmac_down_prep(wlc->hw); - - dev_gone = DEVICEREMOVED(wlc); - - /* Call any registered down handlers */ - for (i = 0; i < WLC_MAXMODULES; i++) { - if (wlc->modulecb[i].down_fn) - callbacks += - wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl); - } - - /* cancel the watchdog timer */ - if (wlc->WDarmed) { - if (!wl_del_timer(wlc->wl, wlc->wdtimer)) - callbacks++; - wlc->WDarmed = false; - } - /* cancel all other timers */ - callbacks += wlc_down_del_timer(wlc); - - /* interrupt must have been blocked */ - ASSERT((wlc->macintmask == 0) || !wlc->pub->up); - - wlc->pub->up = false; - - wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL); - - /* clear txq flow control */ - wlc_txflowcontrol_reset(wlc); - - /* flush tx queues */ - for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { - pktq_flush(wlc->osh, &qi->q, true, NULL, 0); - ASSERT(pktq_empty(&qi->q)); - } - - callbacks += wlc_bmac_down_finish(wlc->hw); - - /* wlc_bmac_down_finish has done wlc_coredisable(). so clk is off */ - wlc->clk = false; - - - /* Verify all packets are flushed from the driver */ - if (wlc->osh->pktalloced != 0) { - WL_ERROR("%d packets not freed at wlc_down!!!!!!\n", - wlc->osh->pktalloced); - } -#ifdef BCMDBG - /* Since all the packets should have been freed, - * all callbacks should have been called - */ - for (i = 1; i <= wlc->pub->tunables->maxpktcb; i++) - ASSERT(wlc->pkt_callback[i].fn == NULL); -#endif - wlc->going_down = false; - return callbacks; -} - -/* Set the current gmode configuration */ -int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) -{ - int ret = 0; - uint i; - wlc_rateset_t rs; - /* Default to 54g Auto */ - s8 shortslot = WLC_SHORTSLOT_AUTO; /* Advertise and use shortslot (-1/0/1 Auto/Off/On) */ - bool shortslot_restrict = false; /* Restrict association to stations that support shortslot - */ - bool ignore_bcns = true; /* Ignore legacy beacons on the same channel */ - bool ofdm_basic = false; /* Make 6, 12, and 24 basic rates */ - int preamble = WLC_PLCP_LONG; /* Advertise and use short preambles (-1/0/1 Auto/Off/On) */ - bool preamble_restrict = false; /* Restrict association to stations that support short - * preambles - */ - struct wlcband *band; - - /* if N-support is enabled, allow Gmode set as long as requested - * Gmode is not GMODE_LEGACY_B - */ - if (N_ENAB(wlc->pub) && gmode == GMODE_LEGACY_B) - return BCME_UNSUPPORTED; - - /* verify that we are dealing with 2G band and grab the band pointer */ - if (wlc->band->bandtype == WLC_BAND_2G) - band = wlc->band; - else if ((NBANDS(wlc) > 1) && - (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == WLC_BAND_2G)) - band = wlc->bandstate[OTHERBANDUNIT(wlc)]; - else - return BCME_BADBAND; - - /* Legacy or bust when no OFDM is supported by regulatory */ - if ((wlc_channel_locale_flags_in_band(wlc->cmi, band->bandunit) & - WLC_NO_OFDM) && (gmode != GMODE_LEGACY_B)) - return BCME_RANGE; - - /* update configuration value */ - if (config == true) - wlc_protection_upd(wlc, WLC_PROT_G_USER, gmode); - - /* Clear supported rates filter */ - memset(&wlc->sup_rates_override, 0, sizeof(wlc_rateset_t)); - - /* Clear rateset override */ - memset(&rs, 0, sizeof(wlc_rateset_t)); - - switch (gmode) { - case GMODE_LEGACY_B: - shortslot = WLC_SHORTSLOT_OFF; - wlc_rateset_copy(&gphy_legacy_rates, &rs); - - break; - - case GMODE_LRS: - if (AP_ENAB(wlc->pub)) - wlc_rateset_copy(&cck_rates, &wlc->sup_rates_override); - break; - - case GMODE_AUTO: - /* Accept defaults */ - break; - - case GMODE_ONLY: - ofdm_basic = true; - preamble = WLC_PLCP_SHORT; - preamble_restrict = true; - break; - - case GMODE_PERFORMANCE: - if (AP_ENAB(wlc->pub)) /* Put all rates into the Supported Rates element */ - wlc_rateset_copy(&cck_ofdm_rates, - &wlc->sup_rates_override); - - shortslot = WLC_SHORTSLOT_ON; - shortslot_restrict = true; - ofdm_basic = true; - preamble = WLC_PLCP_SHORT; - preamble_restrict = true; - break; - - default: - /* Error */ - WL_ERROR("wl%d: %s: invalid gmode %d\n", - wlc->pub->unit, __func__, gmode); - return BCME_UNSUPPORTED; - } - - /* - * If we are switching to gmode == GMODE_LEGACY_B, - * clean up rate info that may refer to OFDM rates. - */ - if ((gmode == GMODE_LEGACY_B) && (band->gmode != GMODE_LEGACY_B)) { - band->gmode = gmode; - if (band->rspec_override && !IS_CCK(band->rspec_override)) { - band->rspec_override = 0; - wlc_reprate_init(wlc); - } - if (band->mrspec_override && !IS_CCK(band->mrspec_override)) { - band->mrspec_override = 0; - } - } - - band->gmode = gmode; - - wlc->ignore_bcns = ignore_bcns; - - wlc->shortslot_override = shortslot; - - if (AP_ENAB(wlc->pub)) { - /* wlc->ap->shortslot_restrict = shortslot_restrict; */ - wlc->PLCPHdr_override = - (preamble != - WLC_PLCP_LONG) ? WLC_PLCP_SHORT : WLC_PLCP_AUTO; - } - - if ((AP_ENAB(wlc->pub) && preamble != WLC_PLCP_LONG) - || preamble == WLC_PLCP_SHORT) - wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE; - else - wlc->default_bss->capability &= ~WLAN_CAPABILITY_SHORT_PREAMBLE; - - /* Update shortslot capability bit for AP and IBSS */ - if ((AP_ENAB(wlc->pub) && shortslot == WLC_SHORTSLOT_AUTO) || - shortslot == WLC_SHORTSLOT_ON) - wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_SLOT_TIME; - else - wlc->default_bss->capability &= - ~WLAN_CAPABILITY_SHORT_SLOT_TIME; - - /* Use the default 11g rateset */ - if (!rs.count) - wlc_rateset_copy(&cck_ofdm_rates, &rs); - - if (ofdm_basic) { - for (i = 0; i < rs.count; i++) { - if (rs.rates[i] == WLC_RATE_6M - || rs.rates[i] == WLC_RATE_12M - || rs.rates[i] == WLC_RATE_24M) - rs.rates[i] |= WLC_RATE_FLAG; - } - } - - /* Set default bss rateset */ - wlc->default_bss->rateset.count = rs.count; - memcpy(wlc->default_bss->rateset.rates, rs.rates, - sizeof(wlc->default_bss->rateset.rates)); - - return ret; -} - -static int wlc_nmode_validate(struct wlc_info *wlc, s32 nmode) -{ - int err = 0; - - switch (nmode) { - - case OFF: - break; - - case AUTO: - case WL_11N_2x2: - case WL_11N_3x3: - if (!(WLC_PHY_11N_CAP(wlc->band))) - err = BCME_BADBAND; - break; - - default: - err = BCME_RANGE; - break; - } - - return err; -} - -int wlc_set_nmode(struct wlc_info *wlc, s32 nmode) -{ - uint i; - int err; - - err = wlc_nmode_validate(wlc, nmode); - ASSERT(err == 0); - if (err) - return err; - - switch (nmode) { - case OFF: - wlc->pub->_n_enab = OFF; - wlc->default_bss->flags &= ~WLC_BSS_HT; - /* delete the mcs rates from the default and hw ratesets */ - wlc_rateset_mcs_clear(&wlc->default_bss->rateset); - for (i = 0; i < NBANDS(wlc); i++) { - memset(wlc->bandstate[i]->hw_rateset.mcs, 0, - MCSSET_LEN); - if (IS_MCS(wlc->band->rspec_override)) { - wlc->bandstate[i]->rspec_override = 0; - wlc_reprate_init(wlc); - } - if (IS_MCS(wlc->band->mrspec_override)) - wlc->bandstate[i]->mrspec_override = 0; - } - break; - - case AUTO: - if (wlc->stf->txstreams == WL_11N_3x3) - nmode = WL_11N_3x3; - else - nmode = WL_11N_2x2; - case WL_11N_2x2: - case WL_11N_3x3: - ASSERT(WLC_PHY_11N_CAP(wlc->band)); - /* force GMODE_AUTO if NMODE is ON */ - wlc_set_gmode(wlc, GMODE_AUTO, true); - if (nmode == WL_11N_3x3) - wlc->pub->_n_enab = SUPPORT_HT; - else - wlc->pub->_n_enab = SUPPORT_11N; - wlc->default_bss->flags |= WLC_BSS_HT; - /* add the mcs rates to the default and hw ratesets */ - wlc_rateset_mcs_build(&wlc->default_bss->rateset, - wlc->stf->txstreams); - for (i = 0; i < NBANDS(wlc); i++) - memcpy(wlc->bandstate[i]->hw_rateset.mcs, - wlc->default_bss->rateset.mcs, MCSSET_LEN); - break; - - default: - ASSERT(0); - break; - } - - return err; -} - -static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg) -{ - wlc_rateset_t rs, new; - uint bandunit; - - memcpy(&rs, rs_arg, sizeof(wlc_rateset_t)); - - /* check for bad count value */ - if ((rs.count == 0) || (rs.count > WLC_NUMRATES)) - return BCME_BADRATESET; - - /* try the current band */ - bandunit = wlc->band->bandunit; - memcpy(&new, &rs, sizeof(wlc_rateset_t)); - if (wlc_rate_hwrs_filter_sort_validate - (&new, &wlc->bandstate[bandunit]->hw_rateset, true, - wlc->stf->txstreams)) - goto good; - - /* try the other band */ - if (IS_MBAND_UNLOCKED(wlc)) { - bandunit = OTHERBANDUNIT(wlc); - memcpy(&new, &rs, sizeof(wlc_rateset_t)); - if (wlc_rate_hwrs_filter_sort_validate(&new, - &wlc-> - bandstate[bandunit]-> - hw_rateset, true, - wlc->stf->txstreams)) - goto good; - } - - return BCME_ERROR; - - good: - /* apply new rateset */ - memcpy(&wlc->default_bss->rateset, &new, sizeof(wlc_rateset_t)); - memcpy(&wlc->bandstate[bandunit]->defrateset, &new, - sizeof(wlc_rateset_t)); - return 0; -} - -/* simplified integer set interface for common ioctl handler */ -int wlc_set(struct wlc_info *wlc, int cmd, int arg) -{ - return wlc_ioctl(wlc, cmd, (void *)&arg, sizeof(arg), NULL); -} - -/* simplified integer get interface for common ioctl handler */ -int wlc_get(struct wlc_info *wlc, int cmd, int *arg) -{ - return wlc_ioctl(wlc, cmd, arg, sizeof(int), NULL); -} - -static void wlc_ofdm_rateset_war(struct wlc_info *wlc) -{ - u8 r; - bool war = false; - - if (wlc->cfg->associated) - r = wlc->cfg->current_bss->rateset.rates[0]; - else - r = wlc->default_bss->rateset.rates[0]; - - wlc_phy_ofdm_rateset_war(wlc->band->pi, war); - - return; -} - -int -wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, - struct wlc_if *wlcif) -{ - return _wlc_ioctl(wlc, cmd, arg, len, wlcif); -} - -/* common ioctl handler. return: 0=ok, -1=error, positive=particular error */ -static int -_wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, - struct wlc_if *wlcif) -{ - int val, *pval; - bool bool_val; - int bcmerror; - d11regs_t *regs; - uint i; - struct scb *nextscb; - bool ta_ok; - uint band; - rw_reg_t *r; - wlc_bsscfg_t *bsscfg; - struct osl_info *osh; - wlc_bss_info_t *current_bss; - - /* update bsscfg pointer */ - bsscfg = NULL; /* XXX: Hack bsscfg to be size one and use this globally */ - current_bss = NULL; - - /* initialize the following to get rid of compiler warning */ - nextscb = NULL; - ta_ok = false; - band = 0; - r = NULL; - - /* If the device is turned off, then it's not "removed" */ - if (!wlc->pub->hw_off && DEVICEREMOVED(wlc)) { - WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); - wl_down(wlc->wl); - return BCME_ERROR; - } - - ASSERT(!(wlc->pub->hw_off && wlc->pub->up)); - - /* default argument is generic integer */ - pval = arg ? (int *)arg:NULL; - - /* This will prevent the misaligned access */ - if (pval && (u32) len >= sizeof(val)) - memcpy(&val, pval, sizeof(val)); - else - val = 0; - - /* bool conversion to avoid duplication below */ - bool_val = val != 0; - - if (cmd != WLC_SET_CHANNEL) - WL_NONE("WLC_IOCTL: cmd %d val 0x%x (%d) len %d\n", - cmd, (uint)val, val, len); - - bcmerror = 0; - regs = wlc->regs; - osh = wlc->osh; - - /* A few commands don't need any arguments; all the others do. */ - switch (cmd) { - case WLC_UP: - case WLC_OUT: - case WLC_DOWN: - case WLC_DISASSOC: - case WLC_RESTART: - case WLC_REBOOT: - case WLC_START_CHANNEL_QA: - case WLC_INIT: - break; - - default: - if ((arg == NULL) || (len <= 0)) { - WL_ERROR("wl%d: %s: Command %d needs arguments\n", - wlc->pub->unit, __func__, cmd); - bcmerror = BCME_BADARG; - goto done; - } - } - - switch (cmd) { - -#if defined(BCMDBG) - case WLC_GET_MSGLEVEL: - *pval = wl_msg_level; - break; - - case WLC_SET_MSGLEVEL: - wl_msg_level = val; - break; -#endif - - case WLC_GET_INSTANCE: - *pval = wlc->pub->unit; - break; - - case WLC_GET_CHANNEL:{ - channel_info_t *ci = (channel_info_t *) arg; - - ASSERT(len > (int)sizeof(ci)); - - ci->hw_channel = - CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC); - ci->target_channel = - CHSPEC_CHANNEL(wlc->default_bss->chanspec); - ci->scan_channel = 0; - - break; - } - - case WLC_SET_CHANNEL:{ - chanspec_t chspec = CH20MHZ_CHSPEC(val); - - if (val < 0 || val > MAXCHANNEL) { - bcmerror = BCME_OUTOFRANGECHAN; - break; - } - - if (!wlc_valid_chanspec_db(wlc->cmi, chspec)) { - bcmerror = BCME_BADCHAN; - break; - } - - if (!wlc->pub->up && IS_MBAND_UNLOCKED(wlc)) { - if (wlc->band->bandunit != - CHSPEC_WLCBANDUNIT(chspec)) - wlc->bandinit_pending = true; - else - wlc->bandinit_pending = false; - } - - wlc->default_bss->chanspec = chspec; - /* wlc_BSSinit() will sanitize the rateset before using it.. */ - if (wlc->pub->up && - (WLC_BAND_PI_RADIO_CHANSPEC != chspec)) { - wlc_set_home_chanspec(wlc, chspec); - wlc_suspend_mac_and_wait(wlc); - wlc_set_chanspec(wlc, chspec); - wlc_enable_mac(wlc); - } - break; - } - -#if defined(BCMDBG) - case WLC_GET_UCFLAGS: - if (!wlc->pub->up) { - bcmerror = BCME_NOTUP; - break; - } - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (val >= MHFMAX) { - bcmerror = BCME_RANGE; - break; - } - - *pval = wlc_bmac_mhf_get(wlc->hw, (u8) val, WLC_BAND_AUTO); - break; - - case WLC_SET_UCFLAGS: - if (!wlc->pub->up) { - bcmerror = BCME_NOTUP; - break; - } - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - i = (u16) val; - if (i >= MHFMAX) { - bcmerror = BCME_RANGE; - break; - } - - wlc_mhf(wlc, (u8) i, 0xffff, (u16) (val >> NBITS(u16)), - WLC_BAND_AUTO); - break; - - case WLC_GET_SHMEM: - ta_ok = true; - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (val & 1) { - bcmerror = BCME_BADADDR; - break; - } - - *pval = wlc_read_shm(wlc, (u16) val); - break; - - case WLC_SET_SHMEM: - ta_ok = true; - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (val & 1) { - bcmerror = BCME_BADADDR; - break; - } - - wlc_write_shm(wlc, (u16) val, - (u16) (val >> NBITS(u16))); - break; - - case WLC_R_REG: /* MAC registers */ - ta_ok = true; - r = (rw_reg_t *) arg; - band = WLC_BAND_AUTO; - - if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - if (len >= (int)sizeof(rw_reg_t)) - band = r->band; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if ((r->byteoff + r->size) > sizeof(d11regs_t)) { - bcmerror = BCME_BADADDR; - break; - } - if (r->size == sizeof(u32)) - r->val = - R_REG((u32 *)((unsigned char *)(unsigned long)regs + - r->byteoff)); - else if (r->size == sizeof(u16)) - r->val = - R_REG((u16 *)((unsigned char *)(unsigned long)regs + - r->byteoff)); - else - bcmerror = BCME_BADADDR; - break; - - case WLC_W_REG: - ta_ok = true; - r = (rw_reg_t *) arg; - band = WLC_BAND_AUTO; - - if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - if (len >= (int)sizeof(rw_reg_t)) - band = r->band; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (r->byteoff + r->size > sizeof(d11regs_t)) { - bcmerror = BCME_BADADDR; - break; - } - if (r->size == sizeof(u32)) - W_REG((u32 *)((unsigned char *)(unsigned long) regs + - r->byteoff), r->val); - else if (r->size == sizeof(u16)) - W_REG((u16 *)((unsigned char *)(unsigned long) regs + - r->byteoff), r->val); - else - bcmerror = BCME_BADADDR; - break; -#endif /* BCMDBG */ - - case WLC_GET_TXANT: - *pval = wlc->stf->txant; - break; - - case WLC_SET_TXANT: - bcmerror = wlc_stf_ant_txant_validate(wlc, (s8) val); - if (bcmerror < 0) - break; - - wlc->stf->txant = (s8) val; - - /* if down, we are done */ - if (!wlc->pub->up) - break; - - wlc_suspend_mac_and_wait(wlc); - - wlc_stf_phy_txant_upd(wlc); - wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec); - - wlc_enable_mac(wlc); - - break; - - case WLC_GET_ANTDIV:{ - u8 phy_antdiv; - - /* return configured value if core is down */ - if (!wlc->pub->up) { - *pval = wlc->stf->ant_rx_ovr; - - } else { - if (wlc_phy_ant_rxdiv_get - (wlc->band->pi, &phy_antdiv)) - *pval = (int)phy_antdiv; - else - *pval = (int)wlc->stf->ant_rx_ovr; - } - - break; - } - case WLC_SET_ANTDIV: - /* values are -1=driver default, 0=force0, 1=force1, 2=start1, 3=start0 */ - if ((val < -1) || (val > 3)) { - bcmerror = BCME_RANGE; - break; - } - - if (val == -1) - val = ANT_RX_DIV_DEF; - - wlc->stf->ant_rx_ovr = (u8) val; - wlc_phy_ant_rxdiv_set(wlc->band->pi, (u8) val); - break; - - case WLC_GET_RX_ANT:{ /* get latest used rx antenna */ - u16 rxstatus; - - if (!wlc->pub->up) { - bcmerror = BCME_NOTUP; - break; - } - - rxstatus = R_REG(&wlc->regs->phyrxstatus0); - if (rxstatus == 0xdead || rxstatus == (u16) -1) { - bcmerror = BCME_ERROR; - break; - } - *pval = (rxstatus & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; - break; - } - -#if defined(BCMDBG) - case WLC_GET_UCANTDIV: - if (!wlc->clk) { - bcmerror = BCME_NOCLK; - break; - } - - *pval = - (wlc_bmac_mhf_get(wlc->hw, MHF1, WLC_BAND_AUTO) & - MHF1_ANTDIV); - break; - - case WLC_SET_UCANTDIV:{ - if (!wlc->pub->up) { - bcmerror = BCME_NOTUP; - break; - } - - /* if multiband, band must be locked */ - if (IS_MBAND_UNLOCKED(wlc)) { - bcmerror = BCME_NOTBANDLOCKED; - break; - } - - wlc_mhf(wlc, MHF1, MHF1_ANTDIV, - (val ? MHF1_ANTDIV : 0), WLC_BAND_AUTO); - break; - } -#endif /* defined(BCMDBG) */ - - case WLC_GET_SRL: - *pval = wlc->SRL; - break; - - case WLC_SET_SRL: - if (val >= 1 && val <= RETRY_SHORT_MAX) { - int ac; - wlc->SRL = (u16) val; - - wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); - - for (ac = 0; ac < AC_COUNT; ac++) { - WLC_WME_RETRY_SHORT_SET(wlc, ac, wlc->SRL); - } - wlc_wme_retries_write(wlc); - } else - bcmerror = BCME_RANGE; - break; - - case WLC_GET_LRL: - *pval = wlc->LRL; - break; - - case WLC_SET_LRL: - if (val >= 1 && val <= 255) { - int ac; - wlc->LRL = (u16) val; - - wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); - - for (ac = 0; ac < AC_COUNT; ac++) { - WLC_WME_RETRY_LONG_SET(wlc, ac, wlc->LRL); - } - wlc_wme_retries_write(wlc); - } else - bcmerror = BCME_RANGE; - break; - - case WLC_GET_CWMIN: - *pval = wlc->band->CWmin; - break; - - case WLC_SET_CWMIN: - if (!wlc->clk) { - bcmerror = BCME_NOCLK; - break; - } - - if (val >= 1 && val <= 255) { - wlc_set_cwmin(wlc, (u16) val); - } else - bcmerror = BCME_RANGE; - break; - - case WLC_GET_CWMAX: - *pval = wlc->band->CWmax; - break; - - case WLC_SET_CWMAX: - if (!wlc->clk) { - bcmerror = BCME_NOCLK; - break; - } - - if (val >= 255 && val <= 2047) { - wlc_set_cwmax(wlc, (u16) val); - } else - bcmerror = BCME_RANGE; - break; - - case WLC_GET_RADIO: /* use mask if don't want to expose some internal bits */ - *pval = wlc->pub->radio_disabled; - break; - - case WLC_SET_RADIO:{ /* 32 bits input, higher 16 bits are mask, lower 16 bits are value to - * set - */ - u16 radiomask, radioval; - uint validbits = - WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE; - mbool new = 0; - - radiomask = (val & 0xffff0000) >> 16; - radioval = val & 0x0000ffff; - - if ((radiomask == 0) || (radiomask & ~validbits) - || (radioval & ~validbits) - || ((radioval & ~radiomask) != 0)) { - WL_ERROR("SET_RADIO with wrong bits 0x%x\n", - val); - bcmerror = BCME_RANGE; - break; - } - - new = - (wlc->pub->radio_disabled & ~radiomask) | radioval; - wlc->pub->radio_disabled = new; - - wlc_radio_hwdisable_upd(wlc); - wlc_radio_upd(wlc); - break; - } - - case WLC_GET_PHYTYPE: - *pval = WLC_PHYTYPE(wlc->band->phytype); - break; - -#if defined(BCMDBG) - case WLC_GET_KEY: - if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc))) { - wl_wsec_key_t key; - - wsec_key_t *src_key = wlc->wsec_keys[val]; - - if (len < (int)sizeof(key)) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - memset((char *)&key, 0, sizeof(key)); - if (src_key) { - key.index = src_key->id; - key.len = src_key->len; - memcpy(key.data, src_key->data, key.len); - key.algo = src_key->algo; - if (WSEC_SOFTKEY(wlc, src_key, bsscfg)) - key.flags |= WL_SOFT_KEY; - if (src_key->flags & WSEC_PRIMARY_KEY) - key.flags |= WL_PRIMARY_KEY; - - memcpy(key.ea, src_key->ea, ETH_ALEN); - } - - memcpy(arg, &key, sizeof(key)); - } else - bcmerror = BCME_BADKEYIDX; - break; -#endif /* defined(BCMDBG) */ - - case WLC_SET_KEY: - bcmerror = - wlc_iovar_op(wlc, "wsec_key", NULL, 0, arg, len, IOV_SET, - wlcif); - break; - - case WLC_GET_KEY_SEQ:{ - wsec_key_t *key; - - if (len < DOT11_WPA_KEY_RSC_LEN) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - /* Return the key's tx iv as an EAPOL sequence counter. - * This will be used to supply the RSC value to a supplicant. - * The format is 8 bytes, with least significant in seq[0]. - */ - - key = WSEC_KEY(wlc, val); - if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc)) && - (key != NULL)) { - u8 seq[DOT11_WPA_KEY_RSC_LEN]; - u16 lo; - u32 hi; - /* group keys in WPA-NONE (IBSS only, AES and TKIP) use a global TXIV */ - if ((bsscfg->WPA_auth & WPA_AUTH_NONE) && - is_zero_ether_addr(key->ea)) { - lo = bsscfg->wpa_none_txiv.lo; - hi = bsscfg->wpa_none_txiv.hi; - } else { - lo = key->txiv.lo; - hi = key->txiv.hi; - } - - /* format the buffer, low to high */ - seq[0] = lo & 0xff; - seq[1] = (lo >> 8) & 0xff; - seq[2] = hi & 0xff; - seq[3] = (hi >> 8) & 0xff; - seq[4] = (hi >> 16) & 0xff; - seq[5] = (hi >> 24) & 0xff; - seq[6] = 0; - seq[7] = 0; - - memcpy(arg, seq, sizeof(seq)); - } else { - bcmerror = BCME_BADKEYIDX; - } - break; - } - - case WLC_GET_CURR_RATESET:{ - wl_rateset_t *ret_rs = (wl_rateset_t *) arg; - wlc_rateset_t *rs; - - if (bsscfg->associated) - rs = ¤t_bss->rateset; - else - rs = &wlc->default_bss->rateset; - - if (len < (int)(rs->count + sizeof(rs->count))) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - /* Copy only legacy rateset section */ - ret_rs->count = rs->count; - memcpy(&ret_rs->rates, &rs->rates, rs->count); - break; - } - - case WLC_GET_RATESET:{ - wlc_rateset_t rs; - wl_rateset_t *ret_rs = (wl_rateset_t *) arg; - - memset(&rs, 0, sizeof(wlc_rateset_t)); - wlc_default_rateset(wlc, (wlc_rateset_t *) &rs); - - if (len < (int)(rs.count + sizeof(rs.count))) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - /* Copy only legacy rateset section */ - ret_rs->count = rs.count; - memcpy(&ret_rs->rates, &rs.rates, rs.count); - break; - } - - case WLC_SET_RATESET:{ - wlc_rateset_t rs; - wl_rateset_t *in_rs = (wl_rateset_t *) arg; - - if (len < (int)(in_rs->count + sizeof(in_rs->count))) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - if (in_rs->count > WLC_NUMRATES) { - bcmerror = BCME_BUFTOOLONG; - break; - } - - memset(&rs, 0, sizeof(wlc_rateset_t)); - - /* Copy only legacy rateset section */ - rs.count = in_rs->count; - memcpy(&rs.rates, &in_rs->rates, rs.count); - - /* merge rateset coming in with the current mcsset */ - if (N_ENAB(wlc->pub)) { - if (bsscfg->associated) - memcpy(rs.mcs, - ¤t_bss->rateset.mcs[0], - MCSSET_LEN); - else - memcpy(rs.mcs, - &wlc->default_bss->rateset.mcs[0], - MCSSET_LEN); - } - - bcmerror = wlc_set_rateset(wlc, &rs); - - if (!bcmerror) - wlc_ofdm_rateset_war(wlc); - - break; - } - - case WLC_GET_BCNPRD: - if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated) - *pval = current_bss->beacon_period; - else - *pval = wlc->default_bss->beacon_period; - break; - - case WLC_SET_BCNPRD: - /* range [1, 0xffff] */ - if (val >= DOT11_MIN_BEACON_PERIOD - && val <= DOT11_MAX_BEACON_PERIOD) { - wlc->default_bss->beacon_period = (u16) val; - } else - bcmerror = BCME_RANGE; - break; - - case WLC_GET_DTIMPRD: - if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated) - *pval = current_bss->dtim_period; - else - *pval = wlc->default_bss->dtim_period; - break; - - case WLC_SET_DTIMPRD: - /* range [1, 0xff] */ - if (val >= DOT11_MIN_DTIM_PERIOD - && val <= DOT11_MAX_DTIM_PERIOD) { - wlc->default_bss->dtim_period = (u8) val; - } else - bcmerror = BCME_RANGE; - break; - -#ifdef SUPPORT_PS - case WLC_GET_PM: - *pval = wlc->PM; - break; - - case WLC_SET_PM: - if ((val >= PM_OFF) && (val <= PM_MAX)) { - wlc->PM = (u8) val; - if (wlc->pub->up) { - } - /* Change watchdog driver to align watchdog with tbtt if possible */ - wlc_watchdog_upd(wlc, PS_ALLOWED(wlc)); - } else - bcmerror = BCME_ERROR; - break; -#endif /* SUPPORT_PS */ - -#ifdef SUPPORT_PS -#ifdef BCMDBG - case WLC_GET_WAKE: - if (AP_ENAB(wlc->pub)) { - bcmerror = BCME_NOTSTA; - break; - } - *pval = wlc->wake; - break; - - case WLC_SET_WAKE: - if (AP_ENAB(wlc->pub)) { - bcmerror = BCME_NOTSTA; - break; - } - - wlc->wake = val ? true : false; - - /* if down, we're done */ - if (!wlc->pub->up) - break; - - /* apply to the mac */ - wlc_set_ps_ctrl(wlc); - break; -#endif /* BCMDBG */ -#endif /* SUPPORT_PS */ - - case WLC_GET_REVINFO: - bcmerror = wlc_get_revision_info(wlc, arg, (uint) len); - break; - - case WLC_GET_AP: - *pval = (int)AP_ENAB(wlc->pub); - break; - - case WLC_GET_ATIM: - if (bsscfg->associated) - *pval = (int)current_bss->atim_window; - else - *pval = (int)wlc->default_bss->atim_window; - break; - - case WLC_SET_ATIM: - wlc->default_bss->atim_window = (u32) val; - break; - - case WLC_GET_PKTCNTS:{ - get_pktcnt_t *pktcnt = (get_pktcnt_t *) pval; - wlc_statsupd(wlc); - pktcnt->rx_good_pkt = wlc->pub->_cnt->rxframe; - pktcnt->rx_bad_pkt = wlc->pub->_cnt->rxerror; - pktcnt->tx_good_pkt = - wlc->pub->_cnt->txfrmsnt; - pktcnt->tx_bad_pkt = - wlc->pub->_cnt->txerror + - wlc->pub->_cnt->txfail; - if (len >= (int)sizeof(get_pktcnt_t)) { - /* Be backward compatible - only if buffer is large enough */ - pktcnt->rx_ocast_good_pkt = - wlc->pub->_cnt->rxmfrmocast; - } - break; - } - -#ifdef SUPPORT_HWKEY - case WLC_GET_WSEC: - bcmerror = - wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_GET, - wlcif); - break; - - case WLC_SET_WSEC: - bcmerror = - wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_SET, - wlcif); - break; - - case WLC_GET_WPA_AUTH: - *pval = (int)bsscfg->WPA_auth; - break; - - case WLC_SET_WPA_AUTH: - /* change of WPA_Auth modifies the PS_ALLOWED state */ - if (BSSCFG_STA(bsscfg)) { - bsscfg->WPA_auth = (u16) val; - } else - bsscfg->WPA_auth = (u16) val; - break; -#endif /* SUPPORT_HWKEY */ - - case WLC_GET_BANDLIST: - /* count of number of bands, followed by each band type */ - *pval++ = NBANDS(wlc); - *pval++ = wlc->band->bandtype; - if (NBANDS(wlc) > 1) - *pval++ = wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype; - break; - - case WLC_GET_BAND: - *pval = wlc->bandlocked ? wlc->band->bandtype : WLC_BAND_AUTO; - break; - - case WLC_GET_PHYLIST: - { - unsigned char *cp = arg; - if (len < 3) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - - if (WLCISNPHY(wlc->band)) { - *cp++ = 'n'; - } else if (WLCISLCNPHY(wlc->band)) { - *cp++ = 'c'; - } else if (WLCISSSLPNPHY(wlc->band)) { - *cp++ = 's'; - } - *cp = '\0'; - break; - } - - case WLC_GET_SHORTSLOT: - *pval = wlc->shortslot; - break; - - case WLC_GET_SHORTSLOT_OVERRIDE: - *pval = wlc->shortslot_override; - break; - - case WLC_SET_SHORTSLOT_OVERRIDE: - if ((val != WLC_SHORTSLOT_AUTO) && - (val != WLC_SHORTSLOT_OFF) && (val != WLC_SHORTSLOT_ON)) { - bcmerror = BCME_RANGE; - break; - } - - wlc->shortslot_override = (s8) val; - - /* shortslot is an 11g feature, so no more work if we are - * currently on the 5G band - */ - if (BAND_5G(wlc->band->bandtype)) - break; - - if (wlc->pub->up && wlc->pub->associated) { - /* let watchdog or beacon processing update shortslot */ - } else if (wlc->pub->up) { - /* unassociated shortslot is off */ - wlc_switch_shortslot(wlc, false); - } else { - /* driver is down, so just update the wlc_info value */ - if (wlc->shortslot_override == WLC_SHORTSLOT_AUTO) { - wlc->shortslot = false; - } else { - wlc->shortslot = - (wlc->shortslot_override == - WLC_SHORTSLOT_ON); - } - } - - break; - - case WLC_GET_LEGACY_ERP: - *pval = wlc->include_legacy_erp; - break; - - case WLC_SET_LEGACY_ERP: - if (wlc->include_legacy_erp == bool_val) - break; - - wlc->include_legacy_erp = bool_val; - - if (AP_ENAB(wlc->pub) && wlc->clk) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - } - break; - - case WLC_GET_GMODE: - if (wlc->band->bandtype == WLC_BAND_2G) - *pval = wlc->band->gmode; - else if (NBANDS(wlc) > 1) - *pval = wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode; - break; - - case WLC_SET_GMODE: - if (!wlc->pub->associated) - bcmerror = wlc_set_gmode(wlc, (u8) val, true); - else { - bcmerror = BCME_ASSOCIATED; - break; - } - break; - - case WLC_GET_GMODE_PROTECTION: - *pval = wlc->protection->_g; - break; - - case WLC_GET_PROTECTION_CONTROL: - *pval = wlc->protection->overlap; - break; - - case WLC_SET_PROTECTION_CONTROL: - if ((val != WLC_PROTECTION_CTL_OFF) && - (val != WLC_PROTECTION_CTL_LOCAL) && - (val != WLC_PROTECTION_CTL_OVERLAP)) { - bcmerror = BCME_RANGE; - break; - } - - wlc_protection_upd(wlc, WLC_PROT_OVERLAP, (s8) val); - - /* Current g_protection will sync up to the specified control alg in watchdog - * if the driver is up and associated. - * If the driver is down or not associated, the control setting has no effect. - */ - break; - - case WLC_GET_GMODE_PROTECTION_OVERRIDE: - *pval = wlc->protection->g_override; - break; - - case WLC_SET_GMODE_PROTECTION_OVERRIDE: - if ((val != WLC_PROTECTION_AUTO) && - (val != WLC_PROTECTION_OFF) && (val != WLC_PROTECTION_ON)) { - bcmerror = BCME_RANGE; - break; - } - - wlc_protection_upd(wlc, WLC_PROT_G_OVR, (s8) val); - - break; - - case WLC_SET_SUP_RATESET_OVERRIDE:{ - wlc_rateset_t rs, new; - - /* copyin */ - if (len < (int)sizeof(wlc_rateset_t)) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - memcpy(&rs, arg, sizeof(wlc_rateset_t)); - - /* check for bad count value */ - if (rs.count > WLC_NUMRATES) { - bcmerror = BCME_BADRATESET; /* invalid rateset */ - break; - } - - /* this command is only appropriate for gmode operation */ - if (!(wlc->band->gmode || - ((NBANDS(wlc) > 1) - && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) { - bcmerror = BCME_BADBAND; /* gmode only command when not in gmode */ - break; - } - - /* check for an empty rateset to clear the override */ - if (rs.count == 0) { - memset(&wlc->sup_rates_override, 0, - sizeof(wlc_rateset_t)); - break; - } - - /* validate rateset by comparing pre and post sorted against 11g hw rates */ - wlc_rateset_filter(&rs, &new, false, WLC_RATES_CCK_OFDM, - RATE_MASK, BSS_N_ENAB(wlc, bsscfg)); - wlc_rate_hwrs_filter_sort_validate(&new, - &cck_ofdm_rates, - false, - wlc->stf->txstreams); - if (rs.count != new.count) { - bcmerror = BCME_BADRATESET; /* invalid rateset */ - break; - } - - /* apply new rateset to the override */ - memcpy(&wlc->sup_rates_override, &new, - sizeof(wlc_rateset_t)); - - /* update bcn and probe resp if needed */ - if (wlc->pub->up && AP_ENAB(wlc->pub) - && wlc->pub->associated) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - } - break; - } - - case WLC_GET_SUP_RATESET_OVERRIDE: - /* this command is only appropriate for gmode operation */ - if (!(wlc->band->gmode || - ((NBANDS(wlc) > 1) - && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) { - bcmerror = BCME_BADBAND; /* gmode only command when not in gmode */ - break; - } - if (len < (int)sizeof(wlc_rateset_t)) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - memcpy(arg, &wlc->sup_rates_override, sizeof(wlc_rateset_t)); - - break; - - case WLC_GET_PRB_RESP_TIMEOUT: - *pval = wlc->prb_resp_timeout; - break; - - case WLC_SET_PRB_RESP_TIMEOUT: - if (wlc->pub->up) { - bcmerror = BCME_NOTDOWN; - break; - } - if (val < 0 || val >= 0xFFFF) { - bcmerror = BCME_RANGE; /* bad value */ - break; - } - wlc->prb_resp_timeout = (u16) val; - break; - - case WLC_GET_KEY_PRIMARY:{ - wsec_key_t *key; - - /* treat the 'val' parm as the key id */ - key = WSEC_BSS_DEFAULT_KEY(bsscfg); - if (key != NULL) { - *pval = key->id == val ? true : false; - } else { - bcmerror = BCME_BADKEYIDX; - } - break; - } - - case WLC_SET_KEY_PRIMARY:{ - wsec_key_t *key, *old_key; - - bcmerror = BCME_BADKEYIDX; - - /* treat the 'val' parm as the key id */ - for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) { - key = bsscfg->bss_def_keys[i]; - if (key != NULL && key->id == val) { - old_key = WSEC_BSS_DEFAULT_KEY(bsscfg); - if (old_key != NULL) - old_key->flags &= - ~WSEC_PRIMARY_KEY; - key->flags |= WSEC_PRIMARY_KEY; - bsscfg->wsec_index = i; - bcmerror = BCME_OK; - } - } - break; - } - -#ifdef BCMDBG - case WLC_INIT: - wl_init(wlc->wl); - break; -#endif - - case WLC_SET_VAR: - case WLC_GET_VAR:{ - char *name; - /* validate the name value */ - name = (char *)arg; - for (i = 0; i < (uint) len && *name != '\0'; - i++, name++) - ; - - if (i == (uint) len) { - bcmerror = BCME_BUFTOOSHORT; - break; - } - i++; /* include the null in the string length */ - - if (cmd == WLC_GET_VAR) { - bcmerror = - wlc_iovar_op(wlc, arg, - (void *)((s8 *) arg + i), - len - i, arg, len, IOV_GET, - wlcif); - } else - bcmerror = - wlc_iovar_op(wlc, arg, NULL, 0, - (void *)((s8 *) arg + i), - len - i, IOV_SET, wlcif); - - break; - } - - case WLC_SET_WSEC_PMK: - bcmerror = BCME_UNSUPPORTED; - break; - -#if defined(BCMDBG) - case WLC_CURRENT_PWR: - if (!wlc->pub->up) - bcmerror = BCME_NOTUP; - else - bcmerror = wlc_get_current_txpwr(wlc, arg, len); - break; -#endif - - case WLC_LAST: - WL_ERROR("%s: WLC_LAST\n", __func__); - } - done: - - if (bcmerror) { - if (VALID_BCMERROR(bcmerror)) - wlc->pub->bcmerror = bcmerror; - else { - bcmerror = 0; - } - - } - /* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */ - /* In hw_off condition, IOCTLs that reach here are deemed safe but taclear would - * certainly result in getting -1 for register reads. So skip ta_clear altogether - */ - if (!(wlc->pub->hw_off)) - ASSERT(wlc_bmac_taclear(wlc->hw, ta_ok) || !ta_ok); - - return bcmerror; -} - -#if defined(BCMDBG) -/* consolidated register access ioctl error checking */ -int wlc_iocregchk(struct wlc_info *wlc, uint band) -{ - /* if band is specified, it must be the current band */ - if ((band != WLC_BAND_AUTO) && (band != (uint) wlc->band->bandtype)) - return BCME_BADBAND; - - /* if multiband and band is not specified, band must be locked */ - if ((band == WLC_BAND_AUTO) && IS_MBAND_UNLOCKED(wlc)) - return BCME_NOTBANDLOCKED; - - /* must have core clocks */ - if (!wlc->clk) - return BCME_NOCLK; - - return 0; -} -#endif /* defined(BCMDBG) */ - -#if defined(BCMDBG) -/* For some ioctls, make sure that the pi pointer matches the current phy */ -int wlc_iocpichk(struct wlc_info *wlc, uint phytype) -{ - if (wlc->band->phytype != phytype) - return BCME_BADBAND; - return 0; -} -#endif - -/* Look up the given var name in the given table */ -static const bcm_iovar_t *wlc_iovar_lookup(const bcm_iovar_t *table, - const char *name) -{ - const bcm_iovar_t *vi; - const char *lookup_name; - - /* skip any ':' delimited option prefixes */ - lookup_name = strrchr(name, ':'); - if (lookup_name != NULL) - lookup_name++; - else - lookup_name = name; - - ASSERT(table != NULL); - - for (vi = table; vi->name; vi++) { - if (!strcmp(vi->name, lookup_name)) - return vi; - } - /* ran to end of table */ - - return NULL; /* var name not found */ -} - -/* simplified integer get interface for common WLC_GET_VAR ioctl handler */ -int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg) -{ - return wlc_iovar_op(wlc, name, NULL, 0, arg, sizeof(s32), IOV_GET, - NULL); -} - -/* simplified integer set interface for common WLC_SET_VAR ioctl handler */ -int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg) -{ - return wlc_iovar_op(wlc, name, NULL, 0, (void *)&arg, sizeof(arg), - IOV_SET, NULL); -} - -/* simplified s8 get interface for common WLC_GET_VAR ioctl handler */ -int wlc_iovar_gets8(struct wlc_info *wlc, const char *name, s8 *arg) -{ - int iovar_int; - int err; - - err = - wlc_iovar_op(wlc, name, NULL, 0, &iovar_int, sizeof(iovar_int), - IOV_GET, NULL); - if (!err) - *arg = (s8) iovar_int; - - return err; -} - -/* - * register iovar table, watchdog and down handlers. - * calling function must keep 'iovars' until wlc_module_unregister is called. - * 'iovar' must have the last entry's name field being NULL as terminator. - */ -int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, - const char *name, void *hdl, iovar_fn_t i_fn, - watchdog_fn_t w_fn, down_fn_t d_fn) -{ - struct wlc_info *wlc = (struct wlc_info *) pub->wlc; - int i; - - ASSERT(name != NULL); - ASSERT(i_fn != NULL || w_fn != NULL || d_fn != NULL); - - /* find an empty entry and just add, no duplication check! */ - for (i = 0; i < WLC_MAXMODULES; i++) { - if (wlc->modulecb[i].name[0] == '\0') { - strncpy(wlc->modulecb[i].name, name, - sizeof(wlc->modulecb[i].name) - 1); - wlc->modulecb[i].iovars = iovars; - wlc->modulecb[i].hdl = hdl; - wlc->modulecb[i].iovar_fn = i_fn; - wlc->modulecb[i].watchdog_fn = w_fn; - wlc->modulecb[i].down_fn = d_fn; - return 0; - } - } - - /* it is time to increase the capacity */ - ASSERT(i < WLC_MAXMODULES); - return BCME_NORESOURCE; -} - -/* unregister module callbacks */ -int wlc_module_unregister(struct wlc_pub *pub, const char *name, void *hdl) -{ - struct wlc_info *wlc = (struct wlc_info *) pub->wlc; - int i; - - if (wlc == NULL) - return BCME_NOTFOUND; - - ASSERT(name != NULL); - - for (i = 0; i < WLC_MAXMODULES; i++) { - if (!strcmp(wlc->modulecb[i].name, name) && - (wlc->modulecb[i].hdl == hdl)) { - memset(&wlc->modulecb[i], 0, sizeof(struct modulecb)); - return 0; - } - } - - /* table not found! */ - return BCME_NOTFOUND; -} - -/* Write WME tunable parameters for retransmit/max rate from wlc struct to ucode */ -static void wlc_wme_retries_write(struct wlc_info *wlc) -{ - int ac; - - /* Need clock to do this */ - if (!wlc->clk) - return; - - for (ac = 0; ac < AC_COUNT; ac++) { - wlc_write_shm(wlc, M_AC_TXLMT_ADDR(ac), wlc->wme_retries[ac]); - } -} - -/* Get or set an iovar. The params/p_len pair specifies any additional - * qualifying parameters (e.g. an "element index") for a get, while the - * arg/len pair is the buffer for the value to be set or retrieved. - * Operation (get/set) is specified by the last argument. - * interface context provided by wlcif - * - * All pointers may point into the same buffer. - */ -int -wlc_iovar_op(struct wlc_info *wlc, const char *name, - void *params, int p_len, void *arg, int len, - bool set, struct wlc_if *wlcif) -{ - int err = 0; - int val_size; - const bcm_iovar_t *vi = NULL; - u32 actionid; - int i; - - ASSERT(name != NULL); - - ASSERT(len >= 0); - - /* Get MUST have return space */ - ASSERT(set || (arg && len)); - - ASSERT(!(wlc->pub->hw_off && wlc->pub->up)); - - /* Set does NOT take qualifiers */ - ASSERT(!set || (!params && !p_len)); - - if (!set && (len == sizeof(int)) && - !(IS_ALIGNED((unsigned long)(arg), (uint) sizeof(int)))) { - WL_ERROR("wl%d: %s unaligned get ptr for %s\n", - wlc->pub->unit, __func__, name); - ASSERT(0); - } - - /* find the given iovar name */ - for (i = 0; i < WLC_MAXMODULES; i++) { - if (!wlc->modulecb[i].iovars) - continue; - vi = wlc_iovar_lookup(wlc->modulecb[i].iovars, name); - if (vi) - break; - } - /* iovar name not found */ - if (i >= WLC_MAXMODULES) { - err = BCME_UNSUPPORTED; - goto exit; - } - - /* set up 'params' pointer in case this is a set command so that - * the convenience int and bool code can be common to set and get - */ - if (params == NULL) { - params = arg; - p_len = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - /* all other types are integer sized */ - val_size = sizeof(int); - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - - /* Do the actual parameter implementation */ - err = wlc->modulecb[i].iovar_fn(wlc->modulecb[i].hdl, vi, actionid, - name, params, p_len, arg, len, val_size, - wlcif); - - exit: - return err; -} - -int -wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, void *arg, int len, - bool set) -{ - struct wlc_info *wlc = (struct wlc_info *) pub->wlc; - int err = 0; - s32 int_val = 0; - - /* check generic condition flags */ - if (set) { - if (((vi->flags & IOVF_SET_DOWN) && wlc->pub->up) || - ((vi->flags & IOVF_SET_UP) && !wlc->pub->up)) { - err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP); - } else if ((vi->flags & IOVF_SET_BAND) - && IS_MBAND_UNLOCKED(wlc)) { - err = BCME_NOTBANDLOCKED; - } else if ((vi->flags & IOVF_SET_CLK) && !wlc->clk) { - err = BCME_NOCLK; - } - } else { - if (((vi->flags & IOVF_GET_DOWN) && wlc->pub->up) || - ((vi->flags & IOVF_GET_UP) && !wlc->pub->up)) { - err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP); - } else if ((vi->flags & IOVF_GET_BAND) - && IS_MBAND_UNLOCKED(wlc)) { - err = BCME_NOTBANDLOCKED; - } else if ((vi->flags & IOVF_GET_CLK) && !wlc->clk) { - err = BCME_NOCLK; - } - } - - if (err) - goto exit; - - /* length check on io buf */ - err = bcm_iovar_lencheck(vi, arg, len, set); - if (err) - goto exit; - - /* On set, check value ranges for integer types */ - if (set) { - switch (vi->type) { - case IOVT_BOOL: - case IOVT_INT8: - case IOVT_INT16: - case IOVT_INT32: - case IOVT_UINT8: - case IOVT_UINT16: - case IOVT_UINT32: - memcpy(&int_val, arg, sizeof(int)); - err = wlc_iovar_rangecheck(wlc, int_val, vi); - break; - } - } - exit: - return err; -} - -/* handler for iovar table wlc_iovars */ -/* - * IMPLEMENTATION NOTE: In order to avoid checking for get/set in each - * iovar case, the switch statement maps the iovar id into separate get - * and set values. If you add a new iovar to the switch you MUST use - * IOV_GVAL and/or IOV_SVAL in the case labels to avoid conflict with - * another case. - * Please use params for additional qualifying parameters. - */ -int -wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, - const char *name, void *params, uint p_len, void *arg, int len, - int val_size, struct wlc_if *wlcif) -{ - struct wlc_info *wlc = hdl; - wlc_bsscfg_t *bsscfg; - int err = 0; - s32 int_val = 0; - s32 int_val2 = 0; - s32 *ret_int_ptr; - bool bool_val; - bool bool_val2; - wlc_bss_info_t *current_bss; - - WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__); - - bsscfg = NULL; - current_bss = NULL; - - err = wlc_iovar_check(wlc->pub, vi, arg, len, IOV_ISSET(actionid)); - if (err != 0) - return err; - - /* convenience int and bool vals for first 8 bytes of buffer */ - if (p_len >= (int)sizeof(int_val)) - memcpy(&int_val, params, sizeof(int_val)); - - if (p_len >= (int)sizeof(int_val) * 2) - memcpy(&int_val2, - (void *)((unsigned long)params + sizeof(int_val)), - sizeof(int_val)); - - /* convenience int ptr for 4-byte gets (requires int aligned arg) */ - ret_int_ptr = (s32 *) arg; - - bool_val = (int_val != 0) ? true : false; - bool_val2 = (int_val2 != 0) ? true : false; - - WL_TRACE("wl%d: %s: id %d\n", - wlc->pub->unit, __func__, IOV_ID(actionid)); - /* Do the actual parameter implementation */ - switch (actionid) { - case IOV_SVAL(IOV_RTSTHRESH): - wlc->RTSThresh = int_val; - break; - - case IOV_GVAL(IOV_QTXPOWER):{ - uint qdbm; - bool override; - - err = wlc_phy_txpower_get(wlc->band->pi, &qdbm, - &override); - if (err != BCME_OK) - return err; - - /* Return qdbm units */ - *ret_int_ptr = - qdbm | (override ? WL_TXPWR_OVERRIDE : 0); - break; - } - - /* As long as override is false, this only sets the *user* targets. - User can twiddle this all he wants with no harm. - wlc_phy_txpower_set() explicitly sets override to false if - not internal or test. - */ - case IOV_SVAL(IOV_QTXPOWER):{ - u8 qdbm; - bool override; - - /* Remove override bit and clip to max qdbm value */ - qdbm = (u8)min_t(u32, (int_val & ~WL_TXPWR_OVERRIDE), 0xff); - /* Extract override setting */ - override = (int_val & WL_TXPWR_OVERRIDE) ? true : false; - err = - wlc_phy_txpower_set(wlc->band->pi, qdbm, override); - break; - } - - case IOV_GVAL(IOV_MPC): - *ret_int_ptr = (s32) wlc->mpc; - break; - - case IOV_SVAL(IOV_MPC): - wlc->mpc = bool_val; - wlc_radio_mpc_upd(wlc); - - break; - - case IOV_GVAL(IOV_BCN_LI_BCN): - *ret_int_ptr = wlc->bcn_li_bcn; - break; - - case IOV_SVAL(IOV_BCN_LI_BCN): - wlc->bcn_li_bcn = (u8) int_val; - if (wlc->pub->up) - wlc_bcn_li_upd(wlc); - break; - - default: - WL_ERROR("wl%d: %s: unsupported\n", wlc->pub->unit, __func__); - err = BCME_UNSUPPORTED; - break; - } - - goto exit; /* avoid unused label warning */ - - exit: - return err; -} - -static int -wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, const bcm_iovar_t *vi) -{ - int err = 0; - u32 min_val = 0; - u32 max_val = 0; - - /* Only ranged integers are checked */ - switch (vi->type) { - case IOVT_INT32: - max_val |= 0x7fffffff; - /* fall through */ - case IOVT_INT16: - max_val |= 0x00007fff; - /* fall through */ - case IOVT_INT8: - max_val |= 0x0000007f; - min_val = ~max_val; - if (vi->flags & IOVF_NTRL) - min_val = 1; - else if (vi->flags & IOVF_WHL) - min_val = 0; - /* Signed values are checked against max_val and min_val */ - if ((s32) val < (s32) min_val - || (s32) val > (s32) max_val) - err = BCME_RANGE; - break; - - case IOVT_UINT32: - max_val |= 0xffffffff; - /* fall through */ - case IOVT_UINT16: - max_val |= 0x0000ffff; - /* fall through */ - case IOVT_UINT8: - max_val |= 0x000000ff; - if (vi->flags & IOVF_NTRL) - min_val = 1; - if ((val < min_val) || (val > max_val)) - err = BCME_RANGE; - break; - } - - return err; -} - -#ifdef BCMDBG -static const char *supr_reason[] = { - "None", "PMQ Entry", "Flush request", - "Previous frag failure", "Channel mismatch", - "Lifetime Expiry", "Underflow" -}; - -static void wlc_print_txs_status(u16 s) -{ - printk(KERN_DEBUG "[15:12] %d frame attempts\n", - (s & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT); - printk(KERN_DEBUG " [11:8] %d rts attempts\n", - (s & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT); - printk(KERN_DEBUG " [7] %d PM mode indicated\n", - ((s & TX_STATUS_PMINDCTD) ? 1 : 0)); - printk(KERN_DEBUG " [6] %d intermediate status\n", - ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0)); - printk(KERN_DEBUG " [5] %d AMPDU\n", - (s & TX_STATUS_AMPDU) ? 1 : 0); - printk(KERN_DEBUG " [4:2] %d Frame Suppressed Reason (%s)\n", - ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT), - supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]); - printk(KERN_DEBUG " [1] %d acked\n", - ((s & TX_STATUS_ACK_RCV) ? 1 : 0)); -} -#endif /* BCMDBG */ - -void wlc_print_txstatus(tx_status_t *txs) -{ -#if defined(BCMDBG) - u16 s = txs->status; - u16 ackphyrxsh = txs->ackphyrxsh; - - printk(KERN_DEBUG "\ntxpkt (MPDU) Complete\n"); - - printk(KERN_DEBUG "FrameID: %04x ", txs->frameid); - printk(KERN_DEBUG "TxStatus: %04x", s); - printk(KERN_DEBUG "\n"); - - wlc_print_txs_status(s); - - printk(KERN_DEBUG "LastTxTime: %04x ", txs->lasttxtime); - printk(KERN_DEBUG "Seq: %04x ", txs->sequence); - printk(KERN_DEBUG "PHYTxStatus: %04x ", txs->phyerr); - printk(KERN_DEBUG "RxAckRSSI: %04x ", - (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT); - printk(KERN_DEBUG "RxAckSQ: %04x", - (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); - printk(KERN_DEBUG "\n"); -#endif /* defined(BCMDBG) */ -} - -static void -wlc_ctrupd_cache(u16 cur_stat, u16 *macstat_snapshot, u32 *macstat) -{ - u16 v; - u16 delta; - - v = le16_to_cpu(cur_stat); - delta = (u16)(v - *macstat_snapshot); - - if (delta != 0) { - *macstat += delta; - *macstat_snapshot = v; - } -} - -#define MACSTATUPD(name) \ - wlc_ctrupd_cache(macstats.name, &wlc->core->macstat_snapshot->name, &wlc->pub->_cnt->name) - -void wlc_statsupd(struct wlc_info *wlc) -{ - int i; - macstat_t macstats; -#ifdef BCMDBG - u16 delta; - u16 rxf0ovfl; - u16 txfunfl[NFIFO]; -#endif /* BCMDBG */ - - /* if driver down, make no sense to update stats */ - if (!wlc->pub->up) - return; - -#ifdef BCMDBG - /* save last rx fifo 0 overflow count */ - rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl; - - /* save last tx fifo underflow count */ - for (i = 0; i < NFIFO; i++) - txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i]; -#endif /* BCMDBG */ - - /* Read mac stats from contiguous shared memory */ - wlc_bmac_copyfrom_shm(wlc->hw, M_UCODE_MACSTAT, - &macstats, sizeof(macstat_t)); - - /* update mac stats */ - MACSTATUPD(txallfrm); - MACSTATUPD(txrtsfrm); - MACSTATUPD(txctsfrm); - MACSTATUPD(txackfrm); - MACSTATUPD(txdnlfrm); - MACSTATUPD(txbcnfrm); - for (i = 0; i < NFIFO; i++) - MACSTATUPD(txfunfl[i]); - MACSTATUPD(txtplunfl); - MACSTATUPD(txphyerr); - MACSTATUPD(rxfrmtoolong); - MACSTATUPD(rxfrmtooshrt); - MACSTATUPD(rxinvmachdr); - MACSTATUPD(rxbadfcs); - MACSTATUPD(rxbadplcp); - MACSTATUPD(rxcrsglitch); - MACSTATUPD(rxstrt); - MACSTATUPD(rxdfrmucastmbss); - MACSTATUPD(rxmfrmucastmbss); - MACSTATUPD(rxcfrmucast); - MACSTATUPD(rxrtsucast); - MACSTATUPD(rxctsucast); - MACSTATUPD(rxackucast); - MACSTATUPD(rxdfrmocast); - MACSTATUPD(rxmfrmocast); - MACSTATUPD(rxcfrmocast); - MACSTATUPD(rxrtsocast); - MACSTATUPD(rxctsocast); - MACSTATUPD(rxdfrmmcast); - MACSTATUPD(rxmfrmmcast); - MACSTATUPD(rxcfrmmcast); - MACSTATUPD(rxbeaconmbss); - MACSTATUPD(rxdfrmucastobss); - MACSTATUPD(rxbeaconobss); - MACSTATUPD(rxrsptmout); - MACSTATUPD(bcntxcancl); - MACSTATUPD(rxf0ovfl); - MACSTATUPD(rxf1ovfl); - MACSTATUPD(rxf2ovfl); - MACSTATUPD(txsfovfl); - MACSTATUPD(pmqovfl); - MACSTATUPD(rxcgprqfrm); - MACSTATUPD(rxcgprsqovfl); - MACSTATUPD(txcgprsfail); - MACSTATUPD(txcgprssuc); - MACSTATUPD(prs_timeout); - MACSTATUPD(rxnack); - MACSTATUPD(frmscons); - MACSTATUPD(txnack); - MACSTATUPD(txglitch_nack); - MACSTATUPD(txburst); - MACSTATUPD(phywatchdog); - MACSTATUPD(pktengrxducast); - MACSTATUPD(pktengrxdmcast); - -#ifdef BCMDBG - /* check for rx fifo 0 overflow */ - delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); - if (delta) - WL_ERROR("wl%d: %u rx fifo 0 overflows!\n", - wlc->pub->unit, delta); - - /* check for tx fifo underflows */ - for (i = 0; i < NFIFO; i++) { - delta = - (u16) (wlc->core->macstat_snapshot->txfunfl[i] - - txfunfl[i]); - if (delta) - WL_ERROR("wl%d: %u tx fifo %d underflows!\n", - wlc->pub->unit, delta, i); - } -#endif /* BCMDBG */ - - /* dot11 counter update */ - - WLCNTSET(wlc->pub->_cnt->txrts, - (wlc->pub->_cnt->rxctsucast - - wlc->pub->_cnt->d11cnt_txrts_off)); - WLCNTSET(wlc->pub->_cnt->rxcrc, - (wlc->pub->_cnt->rxbadfcs - wlc->pub->_cnt->d11cnt_rxcrc_off)); - WLCNTSET(wlc->pub->_cnt->txnocts, - ((wlc->pub->_cnt->txrtsfrm - wlc->pub->_cnt->rxctsucast) - - wlc->pub->_cnt->d11cnt_txnocts_off)); - - /* merge counters from dma module */ - for (i = 0; i < NFIFO; i++) { - if (wlc->hw->di[i]) { - WLCNTADD(wlc->pub->_cnt->txnobuf, - (wlc->hw->di[i])->txnobuf); - WLCNTADD(wlc->pub->_cnt->rxnobuf, - (wlc->hw->di[i])->rxnobuf); - WLCNTADD(wlc->pub->_cnt->rxgiant, - (wlc->hw->di[i])->rxgiants); - dma_counterreset(wlc->hw->di[i]); - } - } - - /* - * Aggregate transmit and receive errors that probably resulted - * in the loss of a frame are computed on the fly. - */ - WLCNTSET(wlc->pub->_cnt->txerror, - wlc->pub->_cnt->txnobuf + wlc->pub->_cnt->txnoassoc + - wlc->pub->_cnt->txuflo + wlc->pub->_cnt->txrunt + - wlc->pub->_cnt->dmade + wlc->pub->_cnt->dmada + - wlc->pub->_cnt->dmape); - WLCNTSET(wlc->pub->_cnt->rxerror, - wlc->pub->_cnt->rxoflo + wlc->pub->_cnt->rxnobuf + - wlc->pub->_cnt->rxfragerr + wlc->pub->_cnt->rxrunt + - wlc->pub->_cnt->rxgiant + wlc->pub->_cnt->rxnoscb + - wlc->pub->_cnt->rxbadsrcmac); - for (i = 0; i < NFIFO; i++) - wlc->pub->_cnt->rxerror += wlc->pub->_cnt->rxuflo[i]; -} - -bool wlc_chipmatch(u16 vendor, u16 device) -{ - if (vendor != VENDOR_BROADCOM) { - WL_ERROR("wlc_chipmatch: unknown vendor id %04x\n", vendor); - return false; - } - - if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID)) - return true; - - if (device == BCM4313_D11N2G_ID) - return true; - if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID)) - return true; - - WL_ERROR("wlc_chipmatch: unknown device id %04x\n", device); - return false; -} - -#if defined(BCMDBG) -void wlc_print_txdesc(d11txh_t *txh) -{ - u16 mtcl = le16_to_cpu(txh->MacTxControlLow); - u16 mtch = le16_to_cpu(txh->MacTxControlHigh); - u16 mfc = le16_to_cpu(txh->MacFrameControl); - u16 tfest = le16_to_cpu(txh->TxFesTimeNormal); - u16 ptcw = le16_to_cpu(txh->PhyTxControlWord); - u16 ptcw_1 = le16_to_cpu(txh->PhyTxControlWord_1); - u16 ptcw_1_Fbr = le16_to_cpu(txh->PhyTxControlWord_1_Fbr); - u16 ptcw_1_Rts = le16_to_cpu(txh->PhyTxControlWord_1_Rts); - u16 ptcw_1_FbrRts = le16_to_cpu(txh->PhyTxControlWord_1_FbrRts); - u16 mainrates = le16_to_cpu(txh->MainRates); - u16 xtraft = le16_to_cpu(txh->XtraFrameTypes); - u8 *iv = txh->IV; - u8 *ra = txh->TxFrameRA; - u16 tfestfb = le16_to_cpu(txh->TxFesTimeFallback); - u8 *rtspfb = txh->RTSPLCPFallback; - u16 rtsdfb = le16_to_cpu(txh->RTSDurFallback); - u8 *fragpfb = txh->FragPLCPFallback; - u16 fragdfb = le16_to_cpu(txh->FragDurFallback); - u16 mmodelen = le16_to_cpu(txh->MModeLen); - u16 mmodefbrlen = le16_to_cpu(txh->MModeFbrLen); - u16 tfid = le16_to_cpu(txh->TxFrameID); - u16 txs = le16_to_cpu(txh->TxStatus); - u16 mnmpdu = le16_to_cpu(txh->MaxNMpdus); - u16 mabyte = le16_to_cpu(txh->MaxABytes_MRT); - u16 mabyte_f = le16_to_cpu(txh->MaxABytes_FBR); - u16 mmbyte = le16_to_cpu(txh->MinMBytes); - - u8 *rtsph = txh->RTSPhyHeader; - struct ieee80211_rts rts = txh->rts_frame; - char hexbuf[256]; - - /* add plcp header along with txh descriptor */ - prhex("Raw TxDesc + plcp header", (unsigned char *) txh, sizeof(d11txh_t) + 48); - - printk(KERN_DEBUG "TxCtlLow: %04x ", mtcl); - printk(KERN_DEBUG "TxCtlHigh: %04x ", mtch); - printk(KERN_DEBUG "FC: %04x ", mfc); - printk(KERN_DEBUG "FES Time: %04x\n", tfest); - printk(KERN_DEBUG "PhyCtl: %04x%s ", ptcw, - (ptcw & PHY_TXC_SHORT_HDR) ? " short" : ""); - printk(KERN_DEBUG "PhyCtl_1: %04x ", ptcw_1); - printk(KERN_DEBUG "PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr); - printk(KERN_DEBUG "PhyCtl_1_Rts: %04x ", ptcw_1_Rts); - printk(KERN_DEBUG "PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts); - printk(KERN_DEBUG "MainRates: %04x ", mainrates); - printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft); - printk(KERN_DEBUG "\n"); - - bcm_format_hex(hexbuf, iv, sizeof(txh->IV)); - printk(KERN_DEBUG "SecIV: %s\n", hexbuf); - bcm_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA)); - printk(KERN_DEBUG "RA: %s\n", hexbuf); - - printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb); - bcm_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback)); - printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf); - printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb); - bcm_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback)); - printk(KERN_DEBUG "PLCP: %s ", hexbuf); - printk(KERN_DEBUG "DUR: %04x", fragdfb); - printk(KERN_DEBUG "\n"); - - printk(KERN_DEBUG "MModeLen: %04x ", mmodelen); - printk(KERN_DEBUG "MModeFbrLen: %04x\n", mmodefbrlen); - - printk(KERN_DEBUG "FrameID: %04x\n", tfid); - printk(KERN_DEBUG "TxStatus: %04x\n", txs); - - printk(KERN_DEBUG "MaxNumMpdu: %04x\n", mnmpdu); - printk(KERN_DEBUG "MaxAggbyte: %04x\n", mabyte); - printk(KERN_DEBUG "MaxAggbyte_fb: %04x\n", mabyte_f); - printk(KERN_DEBUG "MinByte: %04x\n", mmbyte); - - bcm_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader)); - printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf); - bcm_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame)); - printk(KERN_DEBUG "RTS Frame: %s", hexbuf); - printk(KERN_DEBUG "\n"); -} -#endif /* defined(BCMDBG) */ - -#if defined(BCMDBG) -void wlc_print_rxh(d11rxhdr_t *rxh) -{ - u16 len = rxh->RxFrameSize; - u16 phystatus_0 = rxh->PhyRxStatus_0; - u16 phystatus_1 = rxh->PhyRxStatus_1; - u16 phystatus_2 = rxh->PhyRxStatus_2; - u16 phystatus_3 = rxh->PhyRxStatus_3; - u16 macstatus1 = rxh->RxStatus1; - u16 macstatus2 = rxh->RxStatus2; - char flagstr[64]; - char lenbuf[20]; - static const bcm_bit_desc_t macstat_flags[] = { - {RXS_FCSERR, "FCSErr"}, - {RXS_RESPFRAMETX, "Reply"}, - {RXS_PBPRES, "PADDING"}, - {RXS_DECATMPT, "DeCr"}, - {RXS_DECERR, "DeCrErr"}, - {RXS_BCNSENT, "Bcn"}, - {0, NULL} - }; - - prhex("Raw RxDesc", (unsigned char *) rxh, sizeof(d11rxhdr_t)); - - bcm_format_flags(macstat_flags, macstatus1, flagstr, 64); - - snprintf(lenbuf, sizeof(lenbuf), "0x%x", len); - - printk(KERN_DEBUG "RxFrameSize: %6s (%d)%s\n", lenbuf, len, - (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : ""); - printk(KERN_DEBUG "RxPHYStatus: %04x %04x %04x %04x\n", - phystatus_0, phystatus_1, phystatus_2, phystatus_3); - printk(KERN_DEBUG "RxMACStatus: %x %s\n", macstatus1, flagstr); - printk(KERN_DEBUG "RXMACaggtype: %x\n", - (macstatus2 & RXS_AGGTYPE_MASK)); - printk(KERN_DEBUG "RxTSFTime: %04x\n", rxh->RxTSFTime); -} -#endif /* defined(BCMDBG) */ - -#if defined(BCMDBG) -int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len) -{ - uint i, c; - char *p = buf; - char *endp = buf + SSID_FMT_BUF_LEN; - - if (ssid_len > IEEE80211_MAX_SSID_LEN) - ssid_len = IEEE80211_MAX_SSID_LEN; - - for (i = 0; i < ssid_len; i++) { - c = (uint) ssid[i]; - if (c == '\\') { - *p++ = '\\'; - *p++ = '\\'; - } else if (isprint((unsigned char) c)) { - *p++ = (char)c; - } else { - p += snprintf(p, (endp - p), "\\x%02X", c); - } - } - *p = '\0'; - ASSERT(p < endp); - - return (int)(p - buf); -} -#endif /* defined(BCMDBG) */ - -static u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate) -{ - return wlc_bmac_rate_shm_offset(wlc->hw, rate); -} - -/* Callback for device removed */ - -/* - * Attempts to queue a packet onto a multiple-precedence queue, - * if necessary evicting a lower precedence packet from the queue. - * - * 'prec' is the precedence number that has already been mapped - * from the packet priority. - * - * Returns true if packet consumed (queued), false if not. - */ -bool BCMFASTPATH -wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, int prec) -{ - return wlc_prec_enq_head(wlc, q, pkt, prec, false); -} - -bool BCMFASTPATH -wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, - int prec, bool head) -{ - struct sk_buff *p; - int eprec = -1; /* precedence to evict from */ - - /* Determine precedence from which to evict packet, if any */ - if (pktq_pfull(q, prec)) - eprec = prec; - else if (pktq_full(q)) { - p = pktq_peek_tail(q, &eprec); - ASSERT(p != NULL); - if (eprec > prec) { - WL_ERROR("%s: Failing: eprec %d > prec %d\n", - __func__, eprec, prec); - return false; - } - } - - /* Evict if needed */ - if (eprec >= 0) { - bool discard_oldest; - - /* Detect queueing to unconfigured precedence */ - ASSERT(!pktq_pempty(q, eprec)); - - discard_oldest = AC_BITMAP_TST(wlc->wme_dp, eprec); - - /* Refuse newer packet unless configured to discard oldest */ - if (eprec == prec && !discard_oldest) { - WL_ERROR("%s: No where to go, prec == %d\n", - __func__, prec); - return false; - } - - /* Evict packet according to discard policy */ - p = discard_oldest ? pktq_pdeq(q, eprec) : pktq_pdeq_tail(q, - eprec); - ASSERT(p != NULL); - - /* Increment wme stats */ - if (WME_ENAB(wlc->pub)) { - WLCNTINCR(wlc->pub->_wme_cnt-> - tx_failed[WME_PRIO2AC(p->priority)].packets); - WLCNTADD(wlc->pub->_wme_cnt-> - tx_failed[WME_PRIO2AC(p->priority)].bytes, - pkttotlen(p)); - } - pkt_buf_free_skb(wlc->osh, p, true); - wlc->pub->_cnt->txnobuf++; - } - - /* Enqueue */ - if (head) - p = pktq_penq_head(q, prec, pkt); - else - p = pktq_penq(q, prec, pkt); - ASSERT(p != NULL); - - return true; -} - -void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, - uint prec) -{ - struct wlc_info *wlc = (struct wlc_info *) ctx; - struct wlc_txq_info *qi = wlc->active_queue; /* Check me */ - struct pktq *q = &qi->q; - int prio; - - prio = sdu->priority; - - ASSERT(pktq_max(q) >= wlc->pub->tunables->datahiwat); - - if (!wlc_prec_enq(wlc, q, sdu, prec)) { - if (!EDCF_ENAB(wlc->pub) - || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) - WL_ERROR("wl%d: wlc_txq_enq: txq overflow\n", - wlc->pub->unit); - - /* ASSERT(9 == 8); *//* XXX we might hit this condtion in case packet flooding from mac80211 stack */ - pkt_buf_free_skb(wlc->osh, sdu, true); - wlc->pub->_cnt->txnobuf++; - } - - /* Check if flow control needs to be turned on after enqueuing the packet - * Don't turn on flow control if EDCF is enabled. Driver would make the decision on what - * to drop instead of relying on stack to make the right decision - */ - if (!EDCF_ENAB(wlc->pub) - || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) { - if (pktq_len(q) >= wlc->pub->tunables->datahiwat) { - wlc_txflowcontrol(wlc, qi, ON, ALLPRIO); - } - } else if (wlc->pub->_priofc) { - if (pktq_plen(q, wlc_prio2prec_map[prio]) >= - wlc->pub->tunables->datahiwat) { - wlc_txflowcontrol(wlc, qi, ON, prio); - } - } -} - -bool BCMFASTPATH -wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, - struct ieee80211_hw *hw) -{ - u8 prio; - uint fifo; - void *pkt; - struct scb *scb = &global_scb; - struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data); - - ASSERT(sdu); - - /* 802.11 standard requires management traffic to go at highest priority */ - prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority : - MAXPRIO; - fifo = prio2fifo[prio]; - - ASSERT((uint) skb_headroom(sdu) >= TXOFF); - ASSERT(!(sdu->next)); - ASSERT(!(sdu->prev)); - ASSERT(fifo < NFIFO); - - pkt = sdu; - if (unlikely - (wlc_d11hdrs_mac80211(wlc, hw, pkt, scb, 0, 1, fifo, 0, NULL, 0))) - return -EINVAL; - wlc_txq_enq(wlc, scb, pkt, WLC_PRIO_TO_PREC(prio)); - wlc_send_q(wlc, wlc->active_queue); - - wlc->pub->_cnt->ieee_tx++; - return 0; -} - -void BCMFASTPATH wlc_send_q(struct wlc_info *wlc, struct wlc_txq_info *qi) -{ - struct sk_buff *pkt[DOT11_MAXNUMFRAGS]; - int prec; - u16 prec_map; - int err = 0, i, count; - uint fifo; - struct pktq *q = &qi->q; - struct ieee80211_tx_info *tx_info; - - /* only do work for the active queue */ - if (qi != wlc->active_queue) - return; - - if (in_send_q) - return; - else - in_send_q = true; - - prec_map = wlc->tx_prec_map; - - /* Send all the enq'd pkts that we can. - * Dequeue packets with precedence with empty HW fifo only - */ - while (prec_map && (pkt[0] = pktq_mdeq(q, prec_map, &prec))) { - tx_info = IEEE80211_SKB_CB(pkt[0]); - if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { - err = wlc_sendampdu(wlc->ampdu, qi, pkt, prec); - } else { - count = 1; - err = wlc_prep_pdu(wlc, pkt[0], &fifo); - if (!err) { - for (i = 0; i < count; i++) { - wlc_txfifo(wlc, fifo, pkt[i], true, 1); - } - } - } - - if (err == BCME_BUSY) { - pktq_penq_head(q, prec, pkt[0]); - /* If send failed due to any other reason than a change in - * HW FIFO condition, quit. Otherwise, read the new prec_map! - */ - if (prec_map == wlc->tx_prec_map) - break; - prec_map = wlc->tx_prec_map; - } - } - - /* Check if flow control needs to be turned off after sending the packet */ - if (!EDCF_ENAB(wlc->pub) - || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) { - if (wlc_txflowcontrol_prio_isset(wlc, qi, ALLPRIO) - && (pktq_len(q) < wlc->pub->tunables->datahiwat / 2)) { - wlc_txflowcontrol(wlc, qi, OFF, ALLPRIO); - } - } else if (wlc->pub->_priofc) { - int prio; - for (prio = MAXPRIO; prio >= 0; prio--) { - if (wlc_txflowcontrol_prio_isset(wlc, qi, prio) && - (pktq_plen(q, wlc_prio2prec_map[prio]) < - wlc->pub->tunables->datahiwat / 2)) { - wlc_txflowcontrol(wlc, qi, OFF, prio); - } - } - } - in_send_q = false; -} - -/* - * bcmc_fid_generate: - * Generate frame ID for a BCMC packet. The frag field is not used - * for MC frames so is used as part of the sequence number. - */ -static inline u16 -bcmc_fid_generate(struct wlc_info *wlc, wlc_bsscfg_t *bsscfg, d11txh_t *txh) -{ - u16 frameid; - - frameid = le16_to_cpu(txh->TxFrameID) & ~(TXFID_SEQ_MASK | - TXFID_QUEUE_MASK); - frameid |= - (((wlc-> - mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) | - TX_BCMC_FIFO; - - return frameid; -} - -void BCMFASTPATH -wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit, - s8 txpktpend) -{ - u16 frameid = INVALIDFID; - d11txh_t *txh; - - ASSERT(fifo < NFIFO); - txh = (d11txh_t *) (p->data); - - /* When a BC/MC frame is being committed to the BCMC fifo via DMA (NOT PIO), update - * ucode or BSS info as appropriate. - */ - if (fifo == TX_BCMC_FIFO) { - frameid = le16_to_cpu(txh->TxFrameID); - - } - - if (WLC_WAR16165(wlc)) - wlc_war16165(wlc, true); - - - /* Bump up pending count for if not using rpc. If rpc is used, this will be handled - * in wlc_bmac_txfifo() - */ - if (commit) { - TXPKTPENDINC(wlc, fifo, txpktpend); - WL_TRACE("wlc_txfifo, pktpend inc %d to %d\n", - txpktpend, TXPKTPENDGET(wlc, fifo)); - } - - /* Commit BCMC sequence number in the SHM frame ID location */ - if (frameid != INVALIDFID) - BCMCFID(wlc, frameid); - - if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) { - WL_ERROR("wlc_txfifo: fatal, toss frames !!!\n"); - } -} - -static u16 -wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, uint length) -{ - u16 usec = 0; - uint mac_rate = RSPEC2RATE(rspec); - uint nsyms; - - if (IS_MCS(rspec)) { - /* not supported yet */ - ASSERT(0); - } else if (IS_OFDM(rspec)) { - /* nsyms = Ceiling(Nbits / (Nbits/sym)) - * - * Nbits = length * 8 - * Nbits/sym = Mbps * 4 = mac_rate * 2 - */ - nsyms = CEIL((length * 8), (mac_rate * 2)); - - /* usec = symbols * usec/symbol */ - usec = (u16) (nsyms * APHY_SYMBOL_TIME); - return usec; - } else { - switch (mac_rate) { - case WLC_RATE_1M: - usec = length << 3; - break; - case WLC_RATE_2M: - usec = length << 2; - break; - case WLC_RATE_5M5: - usec = (length << 4) / 11; - break; - case WLC_RATE_11M: - usec = (length << 3) / 11; - break; - default: - WL_ERROR("wl%d: wlc_compute_airtime: unsupported rspec 0x%x\n", - wlc->pub->unit, rspec); - ASSERT((const char *)"Bad phy_rate" == NULL); - break; - } - } - - return usec; -} - -void BCMFASTPATH -wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rspec, uint length, u8 *plcp) -{ - if (IS_MCS(rspec)) { - wlc_compute_mimo_plcp(rspec, length, plcp); - } else if (IS_OFDM(rspec)) { - wlc_compute_ofdm_plcp(rspec, length, plcp); - } else { - wlc_compute_cck_plcp(rspec, length, plcp); - } - return; -} - -/* Rate: 802.11 rate code, length: PSDU length in octets */ -static void wlc_compute_mimo_plcp(ratespec_t rspec, uint length, u8 *plcp) -{ - u8 mcs = (u8) (rspec & RSPEC_RATE_MASK); - ASSERT(IS_MCS(rspec)); - plcp[0] = mcs; - if (RSPEC_IS40MHZ(rspec) || (mcs == 32)) - plcp[0] |= MIMO_PLCP_40MHZ; - WLC_SET_MIMO_PLCP_LEN(plcp, length); - plcp[3] = RSPEC_MIMOPLCP3(rspec); /* rspec already holds this byte */ - plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */ - plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */ - plcp[5] = 0; -} - -/* Rate: 802.11 rate code, length: PSDU length in octets */ -static void BCMFASTPATH -wlc_compute_ofdm_plcp(ratespec_t rspec, u32 length, u8 *plcp) -{ - u8 rate_signal; - u32 tmp = 0; - int rate = RSPEC2RATE(rspec); - - ASSERT(IS_OFDM(rspec)); - - /* encode rate per 802.11a-1999 sec 17.3.4.1, with lsb transmitted first */ - rate_signal = rate_info[rate] & RATE_MASK; - ASSERT(rate_signal != 0); - - memset(plcp, 0, D11_PHY_HDR_LEN); - D11A_PHY_HDR_SRATE((ofdm_phy_hdr_t *) plcp, rate_signal); - - tmp = (length & 0xfff) << 5; - plcp[2] |= (tmp >> 16) & 0xff; - plcp[1] |= (tmp >> 8) & 0xff; - plcp[0] |= tmp & 0xff; - - return; -} - -/* - * Compute PLCP, but only requires actual rate and length of pkt. - * Rate is given in the driver standard multiple of 500 kbps. - * le is set for 11 Mbps rate if necessary. - * Broken out for PRQ. - */ - -static void wlc_cck_plcp_set(int rate_500, uint length, u8 *plcp) -{ - u16 usec = 0; - u8 le = 0; - - switch (rate_500) { - case WLC_RATE_1M: - usec = length << 3; - break; - case WLC_RATE_2M: - usec = length << 2; - break; - case WLC_RATE_5M5: - usec = (length << 4) / 11; - if ((length << 4) - (usec * 11) > 0) - usec++; - break; - case WLC_RATE_11M: - usec = (length << 3) / 11; - if ((length << 3) - (usec * 11) > 0) { - usec++; - if ((usec * 11) - (length << 3) >= 8) - le = D11B_PLCP_SIGNAL_LE; - } - break; - - default: - WL_ERROR("wlc_cck_plcp_set: unsupported rate %d\n", rate_500); - rate_500 = WLC_RATE_1M; - usec = length << 3; - break; - } - /* PLCP signal byte */ - plcp[0] = rate_500 * 5; /* r (500kbps) * 5 == r (100kbps) */ - /* PLCP service byte */ - plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED); - /* PLCP length u16, little endian */ - plcp[2] = usec & 0xff; - plcp[3] = (usec >> 8) & 0xff; - /* PLCP CRC16 */ - plcp[4] = 0; - plcp[5] = 0; -} - -/* Rate: 802.11 rate code, length: PSDU length in octets */ -static void wlc_compute_cck_plcp(ratespec_t rspec, uint length, u8 *plcp) -{ - int rate = RSPEC2RATE(rspec); - - ASSERT(IS_CCK(rspec)); - - wlc_cck_plcp_set(rate, length, plcp); -} - -/* wlc_compute_frame_dur() - * - * Calculate the 802.11 MAC header DUR field for MPDU - * DUR for a single frame = 1 SIFS + 1 ACK - * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time - * - * rate MPDU rate in unit of 500kbps - * next_frag_len next MPDU length in bytes - * preamble_type use short/GF or long/MM PLCP header - */ -static u16 BCMFASTPATH -wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type, - uint next_frag_len) -{ - u16 dur, sifs; - - sifs = SIFS(wlc->band); - - dur = sifs; - dur += (u16) wlc_calc_ack_time(wlc, rate, preamble_type); - - if (next_frag_len) { - /* Double the current DUR to get 2 SIFS + 2 ACKs */ - dur *= 2; - /* add another SIFS and the frag time */ - dur += sifs; - dur += - (u16) wlc_calc_frame_time(wlc, rate, preamble_type, - next_frag_len); - } - return dur; -} - -/* wlc_compute_rtscts_dur() - * - * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame - * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK - * DUR for CTS-TO-SELF w/ frame = 2 SIFS + next frame time + 1 ACK - * - * cts cts-to-self or rts/cts - * rts_rate rts or cts rate in unit of 500kbps - * rate next MPDU rate in unit of 500kbps - * frame_len next MPDU frame length in bytes - */ -u16 BCMFASTPATH -wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, ratespec_t rts_rate, - ratespec_t frame_rate, u8 rts_preamble_type, - u8 frame_preamble_type, uint frame_len, bool ba) -{ - u16 dur, sifs; - - sifs = SIFS(wlc->band); - - if (!cts_only) { /* RTS/CTS */ - dur = 3 * sifs; - dur += - (u16) wlc_calc_cts_time(wlc, rts_rate, - rts_preamble_type); - } else { /* CTS-TO-SELF */ - dur = 2 * sifs; - } - - dur += - (u16) wlc_calc_frame_time(wlc, frame_rate, frame_preamble_type, - frame_len); - if (ba) - dur += - (u16) wlc_calc_ba_time(wlc, frame_rate, - WLC_SHORT_PREAMBLE); - else - dur += - (u16) wlc_calc_ack_time(wlc, frame_rate, - frame_preamble_type); - return dur; -} - -static bool wlc_phy_rspec_check(struct wlc_info *wlc, u16 bw, ratespec_t rspec) -{ - if (IS_MCS(rspec)) { - uint mcs = rspec & RSPEC_RATE_MASK; - - if (mcs < 8) { - ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM); - } else if ((mcs >= 8) && (mcs <= 23)) { - ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SDM); - } else if (mcs == 32) { - ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM); - ASSERT(bw == PHY_TXC1_BW_40MHZ_DUP); - } - } else if (IS_OFDM(rspec)) { - ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_STBC); - } else { - ASSERT(IS_CCK(rspec)); - - ASSERT((bw == PHY_TXC1_BW_20MHZ) - || (bw == PHY_TXC1_BW_20MHZ_UP)); - ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SISO); - } - - return true; -} - -u16 BCMFASTPATH wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec) -{ - u16 phyctl1 = 0; - u16 bw; - - if (WLCISLCNPHY(wlc->band)) { - bw = PHY_TXC1_BW_20MHZ; - } else { - bw = RSPEC_GET_BW(rspec); - /* 10Mhz is not supported yet */ - if (bw < PHY_TXC1_BW_20MHZ) { - WL_ERROR("wlc_phytxctl1_calc: bw %d is not supported yet, set to 20L\n", - bw); - bw = PHY_TXC1_BW_20MHZ; - } - - wlc_phy_rspec_check(wlc, bw, rspec); - } - - if (IS_MCS(rspec)) { - uint mcs = rspec & RSPEC_RATE_MASK; - - /* bw, stf, coding-type is part of RSPEC_PHYTXBYTE2 returns */ - phyctl1 = RSPEC_PHYTXBYTE2(rspec); - /* set the upper byte of phyctl1 */ - phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8); - } else if (IS_CCK(rspec) && !WLCISLCNPHY(wlc->band) - && !WLCISSSLPNPHY(wlc->band)) { - /* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */ - /* Eventually MIMOPHY would also be converted to this format */ - /* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */ - phyctl1 = (bw | (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT)); - } else { /* legacy OFDM/CCK */ - s16 phycfg; - /* get the phyctl byte from rate phycfg table */ - phycfg = wlc_rate_legacy_phyctl(RSPEC2RATE(rspec)); - if (phycfg == -1) { - WL_ERROR("wlc_phytxctl1_calc: wrong legacy OFDM/CCK rate\n"); - ASSERT(0); - phycfg = 0; - } - /* set the upper byte of phyctl1 */ - phyctl1 = - (bw | (phycfg << 8) | - (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT)); - } - -#ifdef BCMDBG - /* phy clock must support 40Mhz if tx descriptor uses it */ - if ((phyctl1 & PHY_TXC1_BW_MASK) >= PHY_TXC1_BW_40MHZ) { - ASSERT(CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ); - ASSERT(wlc->chanspec == wlc_phy_chanspec_get(wlc->band->pi)); - } -#endif /* BCMDBG */ - return phyctl1; -} - -ratespec_t BCMFASTPATH -wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, bool use_rspec, - u16 mimo_ctlchbw) -{ - ratespec_t rts_rspec = 0; - - if (use_rspec) { - /* use frame rate as rts rate */ - rts_rspec = rspec; - - } else if (wlc->band->gmode && wlc->protection->_g && !IS_CCK(rspec)) { - /* Use 11Mbps as the g protection RTS target rate and fallback. - * Use the WLC_BASIC_RATE() lookup to find the best basic rate under the - * target in case 11 Mbps is not Basic. - * 6 and 9 Mbps are not usually selected by rate selection, but even - * if the OFDM rate we are protecting is 6 or 9 Mbps, 11 is more robust. - */ - rts_rspec = WLC_BASIC_RATE(wlc, WLC_RATE_11M); - } else { - /* calculate RTS rate and fallback rate based on the frame rate - * RTS must be sent at a basic rate since it is a - * control frame, sec 9.6 of 802.11 spec - */ - rts_rspec = WLC_BASIC_RATE(wlc, rspec); - } - - if (WLC_PHY_11N_CAP(wlc->band)) { - /* set rts txbw to correct side band */ - rts_rspec &= ~RSPEC_BW_MASK; - - /* if rspec/rspec_fallback is 40MHz, then send RTS on both 20MHz channel - * (DUP), otherwise send RTS on control channel - */ - if (RSPEC_IS40MHZ(rspec) && !IS_CCK(rts_rspec)) - rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT); - else - rts_rspec |= (mimo_ctlchbw << RSPEC_BW_SHIFT); - - /* pick siso/cdd as default for ofdm */ - if (IS_OFDM(rts_rspec)) { - rts_rspec &= ~RSPEC_STF_MASK; - rts_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT); - } - } - return rts_rspec; -} - -/* - * Add d11txh_t, cck_phy_hdr_t. - * - * 'p' data must start with 802.11 MAC header - * 'p' must allow enough bytes of local headers to be "pushed" onto the packet - * - * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes) - * - */ -static u16 BCMFASTPATH -wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, - struct sk_buff *p, struct scb *scb, uint frag, - uint nfrags, uint queue, uint next_frag_len, - wsec_key_t *key, ratespec_t rspec_override) -{ - struct ieee80211_hdr *h; - d11txh_t *txh; - u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN]; - struct osl_info *osh; - int len, phylen, rts_phylen; - u16 frameid, mch, phyctl, xfts, mainrates; - u16 seq = 0, mcl = 0, status = 0; - ratespec_t rspec[2] = { WLC_RATE_1M, WLC_RATE_1M }, rts_rspec[2] = { - WLC_RATE_1M, WLC_RATE_1M}; - bool use_rts = false; - bool use_cts = false; - bool use_rifs = false; - bool short_preamble[2] = { false, false }; - u8 preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE }; - u8 rts_preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE }; - u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN]; - struct ieee80211_rts *rts = NULL; - bool qos; - uint ac; - u32 rate_val[2]; - bool hwtkmic = false; - u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; -#define ANTCFG_NONE 0xFF - u8 antcfg = ANTCFG_NONE; - u8 fbantcfg = ANTCFG_NONE; - uint phyctl1_stf = 0; - u16 durid = 0; - struct ieee80211_tx_rate *txrate[2]; - int k; - struct ieee80211_tx_info *tx_info; - bool is_mcs[2]; - u16 mimo_txbw; - u8 mimo_preamble_type; - - frameid = 0; - - ASSERT(queue < NFIFO); - - osh = wlc->osh; - - /* locate 802.11 MAC header */ - h = (struct ieee80211_hdr *)(p->data); - qos = ieee80211_is_data_qos(h->frame_control); - - /* compute length of frame in bytes for use in PLCP computations */ - len = pkttotlen(p); - phylen = len + FCS_LEN; - - /* If WEP enabled, add room in phylen for the additional bytes of - * ICV which MAC generates. We do NOT add the additional bytes to - * the packet itself, thus phylen = packet length + ICV_LEN + FCS_LEN - * in this case - */ - if (key) { - phylen += key->icv_len; - } - - /* Get tx_info */ - tx_info = IEEE80211_SKB_CB(p); - ASSERT(tx_info); - - /* add PLCP */ - plcp = skb_push(p, D11_PHY_HDR_LEN); - - /* add Broadcom tx descriptor header */ - txh = (d11txh_t *) skb_push(p, D11_TXH_LEN); - memset(txh, 0, D11_TXH_LEN); - - /* setup frameid */ - if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { - /* non-AP STA should never use BCMC queue */ - ASSERT(queue != TX_BCMC_FIFO); - if (queue == TX_BCMC_FIFO) { - WL_ERROR("wl%d: %s: ASSERT queue == TX_BCMC!\n", - WLCWLUNIT(wlc), __func__); - frameid = bcmc_fid_generate(wlc, NULL, txh); - } else { - /* Increment the counter for first fragment */ - if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) { - SCB_SEQNUM(scb, p->priority)++; - } - - /* extract fragment number from frame first */ - seq = le16_to_cpu(seq) & FRAGNUM_MASK; - seq |= (SCB_SEQNUM(scb, p->priority) << SEQNUM_SHIFT); - h->seq_ctrl = cpu_to_le16(seq); - - frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) | - (queue & TXFID_QUEUE_MASK); - } - } - frameid |= queue & TXFID_QUEUE_MASK; - - /* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */ - if (SCB_PS(scb) || ieee80211_is_beacon(h->frame_control)) - mcl |= TXC_IGNOREPMQ; - - ASSERT(hw->max_rates <= IEEE80211_TX_MAX_RATES); - ASSERT(hw->max_rates == 2); - - txrate[0] = tx_info->control.rates; - txrate[1] = txrate[0] + 1; - - ASSERT(txrate[0]->idx >= 0); - /* if rate control algorithm didn't give us a fallback rate, use the primary rate */ - if (txrate[1]->idx < 0) { - txrate[1] = txrate[0]; - } - - for (k = 0; k < hw->max_rates; k++) { - is_mcs[k] = - txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false; - if (!is_mcs[k]) { - ASSERT(!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)); - if ((txrate[k]->idx >= 0) - && (txrate[k]->idx < - hw->wiphy->bands[tx_info->band]->n_bitrates)) { - rate_val[k] = - hw->wiphy->bands[tx_info->band]-> - bitrates[txrate[k]->idx].hw_value; - short_preamble[k] = - txrate[k]-> - flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ? - true : false; - } else { - ASSERT((txrate[k]->idx >= 0) && - (txrate[k]->idx < - hw->wiphy->bands[tx_info->band]-> - n_bitrates)); - rate_val[k] = WLC_RATE_1M; - } - } else { - rate_val[k] = txrate[k]->idx; - } - /* Currently only support same setting for primay and fallback rates. - * Unify flags for each rate into a single value for the frame - */ - use_rts |= - txrate[k]-> - flags & IEEE80211_TX_RC_USE_RTS_CTS ? true : false; - use_cts |= - txrate[k]-> - flags & IEEE80211_TX_RC_USE_CTS_PROTECT ? true : false; - - if (is_mcs[k]) - rate_val[k] |= NRATE_MCS_INUSE; - - rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band, rate_val[k]); - - /* (1) RATE: determine and validate primary rate and fallback rates */ - if (!RSPEC_ACTIVE(rspec[k])) { - ASSERT(RSPEC_ACTIVE(rspec[k])); - rspec[k] = WLC_RATE_1M; - } else { - if (!is_multicast_ether_addr(h->addr1)) { - /* set tx antenna config */ - wlc_antsel_antcfg_get(wlc->asi, false, false, 0, - 0, &antcfg, &fbantcfg); - } - } - } - - phyctl1_stf = wlc->stf->ss_opmode; - - if (N_ENAB(wlc->pub)) { - for (k = 0; k < hw->max_rates; k++) { - /* apply siso/cdd to single stream mcs's or ofdm if rspec is auto selected */ - if (((IS_MCS(rspec[k]) && - IS_SINGLE_STREAM(rspec[k] & RSPEC_RATE_MASK)) || - IS_OFDM(rspec[k])) - && ((rspec[k] & RSPEC_OVERRIDE_MCS_ONLY) - || !(rspec[k] & RSPEC_OVERRIDE))) { - rspec[k] &= ~(RSPEC_STF_MASK | RSPEC_STC_MASK); - - /* For SISO MCS use STBC if possible */ - if (IS_MCS(rspec[k]) - && WLC_STF_SS_STBC_TX(wlc, scb)) { - u8 stc; - - ASSERT(WLC_STBC_CAP_PHY(wlc)); - stc = 1; /* Nss for single stream is always 1 */ - rspec[k] |= - (PHY_TXC1_MODE_STBC << - RSPEC_STF_SHIFT) | (stc << - RSPEC_STC_SHIFT); - } else - rspec[k] |= - (phyctl1_stf << RSPEC_STF_SHIFT); - } - - /* Is the phy configured to use 40MHZ frames? If so then pick the desired txbw */ - if (CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ) { - /* default txbw is 20in40 SB */ - mimo_ctlchbw = mimo_txbw = - CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC) - ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; - - if (IS_MCS(rspec[k])) { - /* mcs 32 must be 40b/w DUP */ - if ((rspec[k] & RSPEC_RATE_MASK) == 32) { - mimo_txbw = - PHY_TXC1_BW_40MHZ_DUP; - /* use override */ - } else if (wlc->mimo_40txbw != AUTO) - mimo_txbw = wlc->mimo_40txbw; - /* else check if dst is using 40 Mhz */ - else if (scb->flags & SCB_IS40) - mimo_txbw = PHY_TXC1_BW_40MHZ; - } else if (IS_OFDM(rspec[k])) { - if (wlc->ofdm_40txbw != AUTO) - mimo_txbw = wlc->ofdm_40txbw; - } else { - ASSERT(IS_CCK(rspec[k])); - if (wlc->cck_40txbw != AUTO) - mimo_txbw = wlc->cck_40txbw; - } - } else { - /* mcs32 is 40 b/w only. - * This is possible for probe packets on a STA during SCAN - */ - if ((rspec[k] & RSPEC_RATE_MASK) == 32) { - /* mcs 0 */ - rspec[k] = RSPEC_MIMORATE; - } - mimo_txbw = PHY_TXC1_BW_20MHZ; - } - - /* Set channel width */ - rspec[k] &= ~RSPEC_BW_MASK; - if ((k == 0) || ((k > 0) && IS_MCS(rspec[k]))) - rspec[k] |= (mimo_txbw << RSPEC_BW_SHIFT); - else - rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT); - - /* Set Short GI */ -#ifdef NOSGIYET - if (IS_MCS(rspec[k]) - && (txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI)) - rspec[k] |= RSPEC_SHORT_GI; - else if (!(txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI)) - rspec[k] &= ~RSPEC_SHORT_GI; -#else - rspec[k] &= ~RSPEC_SHORT_GI; -#endif - - mimo_preamble_type = WLC_MM_PREAMBLE; - if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD) - mimo_preamble_type = WLC_GF_PREAMBLE; - - if ((txrate[k]->flags & IEEE80211_TX_RC_MCS) - && (!IS_MCS(rspec[k]))) { - WL_ERROR("wl%d: %s: IEEE80211_TX_RC_MCS != IS_MCS(rspec)\n", - WLCWLUNIT(wlc), __func__); - ASSERT(0 && "Rate mismatch"); - } - - if (IS_MCS(rspec[k])) { - preamble_type[k] = mimo_preamble_type; - - /* if SGI is selected, then forced mm for single stream */ - if ((rspec[k] & RSPEC_SHORT_GI) - && IS_SINGLE_STREAM(rspec[k] & - RSPEC_RATE_MASK)) { - preamble_type[k] = WLC_MM_PREAMBLE; - } - } - - /* mimo bw field MUST now be valid in the rspec (it affects duration calculations) */ - ASSERT(VALID_RATE_DBG(wlc, rspec[0])); - - /* should be better conditionalized */ - if (!IS_MCS(rspec[0]) - && (tx_info->control.rates[0]. - flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)) - preamble_type[k] = WLC_SHORT_PREAMBLE; - - ASSERT(!IS_MCS(rspec[0]) - || WLC_IS_MIMO_PREAMBLE(preamble_type[k])); - } - } else { - for (k = 0; k < hw->max_rates; k++) { - /* Set ctrlchbw as 20Mhz */ - ASSERT(!IS_MCS(rspec[k])); - rspec[k] &= ~RSPEC_BW_MASK; - rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT); - - /* for nphy, stf of ofdm frames must follow policies */ - if (WLCISNPHY(wlc->band) && IS_OFDM(rspec[k])) { - rspec[k] &= ~RSPEC_STF_MASK; - rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT; - } - } - } - - /* Reset these for use with AMPDU's */ - txrate[0]->count = 0; - txrate[1]->count = 0; - - /* (2) PROTECTION, may change rspec */ - if ((ieee80211_is_data(h->frame_control) || - ieee80211_is_mgmt(h->frame_control)) && - (phylen > wlc->RTSThresh) && !is_multicast_ether_addr(h->addr1)) - use_rts = true; - - /* (3) PLCP: determine PLCP header and MAC duration, fill d11txh_t */ - wlc_compute_plcp(wlc, rspec[0], phylen, plcp); - wlc_compute_plcp(wlc, rspec[1], phylen, plcp_fallback); - memcpy(&txh->FragPLCPFallback, - plcp_fallback, sizeof(txh->FragPLCPFallback)); - - /* Length field now put in CCK FBR CRC field */ - if (IS_CCK(rspec[1])) { - txh->FragPLCPFallback[4] = phylen & 0xff; - txh->FragPLCPFallback[5] = (phylen & 0xff00) >> 8; - } - - /* MIMO-RATE: need validation ?? */ - mainrates = - IS_OFDM(rspec[0]) ? D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) plcp) : - plcp[0]; - - /* DUR field for main rate */ - if (!ieee80211_is_pspoll(h->frame_control) && - !is_multicast_ether_addr(h->addr1) && !use_rifs) { - durid = - wlc_compute_frame_dur(wlc, rspec[0], preamble_type[0], - next_frag_len); - h->duration_id = cpu_to_le16(durid); - } else if (use_rifs) { - /* NAV protect to end of next max packet size */ - durid = - (u16) wlc_calc_frame_time(wlc, rspec[0], - preamble_type[0], - DOT11_MAX_FRAG_LEN); - durid += RIFS_11N_TIME; - h->duration_id = cpu_to_le16(durid); - } - - /* DUR field for fallback rate */ - if (ieee80211_is_pspoll(h->frame_control)) - txh->FragDurFallback = h->duration_id; - else if (is_multicast_ether_addr(h->addr1) || use_rifs) - txh->FragDurFallback = 0; - else { - durid = wlc_compute_frame_dur(wlc, rspec[1], - preamble_type[1], next_frag_len); - txh->FragDurFallback = cpu_to_le16(durid); - } - - /* (4) MAC-HDR: MacTxControlLow */ - if (frag == 0) - mcl |= TXC_STARTMSDU; - - if (!is_multicast_ether_addr(h->addr1)) - mcl |= TXC_IMMEDACK; - - if (BAND_5G(wlc->band->bandtype)) - mcl |= TXC_FREQBAND_5G; - - if (CHSPEC_IS40(WLC_BAND_PI_RADIO_CHANSPEC)) - mcl |= TXC_BW_40; - - /* set AMIC bit if using hardware TKIP MIC */ - if (hwtkmic) - mcl |= TXC_AMIC; - - txh->MacTxControlLow = cpu_to_le16(mcl); - - /* MacTxControlHigh */ - mch = 0; - - /* Set fallback rate preamble type */ - if ((preamble_type[1] == WLC_SHORT_PREAMBLE) || - (preamble_type[1] == WLC_GF_PREAMBLE)) { - ASSERT((preamble_type[1] == WLC_GF_PREAMBLE) || - (!IS_MCS(rspec[1]))); - if (RSPEC2RATE(rspec[1]) != WLC_RATE_1M) - mch |= TXC_PREAMBLE_DATA_FB_SHORT; - } - - /* MacFrameControl */ - memcpy(&txh->MacFrameControl, &h->frame_control, sizeof(u16)); - txh->TxFesTimeNormal = cpu_to_le16(0); - - txh->TxFesTimeFallback = cpu_to_le16(0); - - /* TxFrameRA */ - memcpy(&txh->TxFrameRA, &h->addr1, ETH_ALEN); - - /* TxFrameID */ - txh->TxFrameID = cpu_to_le16(frameid); - - /* TxStatus, Note the case of recreating the first frag of a suppressed frame - * then we may need to reset the retry cnt's via the status reg - */ - txh->TxStatus = cpu_to_le16(status); - - /* extra fields for ucode AMPDU aggregation, the new fields are added to - * the END of previous structure so that it's compatible in driver. - */ - txh->MaxNMpdus = cpu_to_le16(0); - txh->MaxABytes_MRT = cpu_to_le16(0); - txh->MaxABytes_FBR = cpu_to_le16(0); - txh->MinMBytes = cpu_to_le16(0); - - /* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration, furnish d11txh_t */ - /* RTS PLCP header and RTS frame */ - if (use_rts || use_cts) { - if (use_rts && use_cts) - use_cts = false; - - for (k = 0; k < 2; k++) { - rts_rspec[k] = wlc_rspec_to_rts_rspec(wlc, rspec[k], - false, - mimo_ctlchbw); - } - - if (!IS_OFDM(rts_rspec[0]) && - !((RSPEC2RATE(rts_rspec[0]) == WLC_RATE_1M) || - (wlc->PLCPHdr_override == WLC_PLCP_LONG))) { - rts_preamble_type[0] = WLC_SHORT_PREAMBLE; - mch |= TXC_PREAMBLE_RTS_MAIN_SHORT; - } - - if (!IS_OFDM(rts_rspec[1]) && - !((RSPEC2RATE(rts_rspec[1]) == WLC_RATE_1M) || - (wlc->PLCPHdr_override == WLC_PLCP_LONG))) { - rts_preamble_type[1] = WLC_SHORT_PREAMBLE; - mch |= TXC_PREAMBLE_RTS_FB_SHORT; - } - - /* RTS/CTS additions to MacTxControlLow */ - if (use_cts) { - txh->MacTxControlLow |= cpu_to_le16(TXC_SENDCTS); - } else { - txh->MacTxControlLow |= cpu_to_le16(TXC_SENDRTS); - txh->MacTxControlLow |= cpu_to_le16(TXC_LONGFRAME); - } - - /* RTS PLCP header */ - ASSERT(IS_ALIGNED((unsigned long)txh->RTSPhyHeader, sizeof(u16))); - rts_plcp = txh->RTSPhyHeader; - if (use_cts) - rts_phylen = DOT11_CTS_LEN + FCS_LEN; - else - rts_phylen = DOT11_RTS_LEN + FCS_LEN; - - wlc_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp); - - /* fallback rate version of RTS PLCP header */ - wlc_compute_plcp(wlc, rts_rspec[1], rts_phylen, - rts_plcp_fallback); - memcpy(&txh->RTSPLCPFallback, rts_plcp_fallback, - sizeof(txh->RTSPLCPFallback)); - - /* RTS frame fields... */ - rts = (struct ieee80211_rts *)&txh->rts_frame; - - durid = wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec[0], - rspec[0], rts_preamble_type[0], - preamble_type[0], phylen, false); - rts->duration = cpu_to_le16(durid); - /* fallback rate version of RTS DUR field */ - durid = wlc_compute_rtscts_dur(wlc, use_cts, - rts_rspec[1], rspec[1], - rts_preamble_type[1], - preamble_type[1], phylen, false); - txh->RTSDurFallback = cpu_to_le16(durid); - - if (use_cts) { - rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | - IEEE80211_STYPE_CTS); - - memcpy(&rts->ra, &h->addr2, ETH_ALEN); - } else { - rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | - IEEE80211_STYPE_RTS); - - memcpy(&rts->ra, &h->addr1, 2 * ETH_ALEN); - } - - /* mainrate - * low 8 bits: main frag rate/mcs, - * high 8 bits: rts/cts rate/mcs - */ - mainrates |= (IS_OFDM(rts_rspec[0]) ? - D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) rts_plcp) : - rts_plcp[0]) << 8; - } else { - memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN); - memset((char *)&txh->rts_frame, 0, - sizeof(struct ieee80211_rts)); - memset((char *)txh->RTSPLCPFallback, 0, - sizeof(txh->RTSPLCPFallback)); - txh->RTSDurFallback = 0; - } - -#ifdef SUPPORT_40MHZ - /* add null delimiter count */ - if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && IS_MCS(rspec)) { - txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = - wlc_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen); - } -#endif - - /* Now that RTS/RTS FB preamble types are updated, write the final value */ - txh->MacTxControlHigh = cpu_to_le16(mch); - - /* MainRates (both the rts and frag plcp rates have been calculated now) */ - txh->MainRates = cpu_to_le16(mainrates); - - /* XtraFrameTypes */ - xfts = FRAMETYPE(rspec[1], wlc->mimoft); - xfts |= (FRAMETYPE(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT); - xfts |= (FRAMETYPE(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT); - xfts |= - CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC) << XFTS_CHANNEL_SHIFT; - txh->XtraFrameTypes = cpu_to_le16(xfts); - - /* PhyTxControlWord */ - phyctl = FRAMETYPE(rspec[0], wlc->mimoft); - if ((preamble_type[0] == WLC_SHORT_PREAMBLE) || - (preamble_type[0] == WLC_GF_PREAMBLE)) { - ASSERT((preamble_type[0] == WLC_GF_PREAMBLE) - || !IS_MCS(rspec[0])); - if (RSPEC2RATE(rspec[0]) != WLC_RATE_1M) - phyctl |= PHY_TXC_SHORT_HDR; - wlc->pub->_cnt->txprshort++; - } - - /* phytxant is properly bit shifted */ - phyctl |= wlc_stf_d11hdrs_phyctl_txant(wlc, rspec[0]); - txh->PhyTxControlWord = cpu_to_le16(phyctl); - - /* PhyTxControlWord_1 */ - if (WLC_PHY_11N_CAP(wlc->band)) { - u16 phyctl1 = 0; - - phyctl1 = wlc_phytxctl1_calc(wlc, rspec[0]); - txh->PhyTxControlWord_1 = cpu_to_le16(phyctl1); - phyctl1 = wlc_phytxctl1_calc(wlc, rspec[1]); - txh->PhyTxControlWord_1_Fbr = cpu_to_le16(phyctl1); - - if (use_rts || use_cts) { - phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[0]); - txh->PhyTxControlWord_1_Rts = cpu_to_le16(phyctl1); - phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[1]); - txh->PhyTxControlWord_1_FbrRts = cpu_to_le16(phyctl1); - } - - /* - * For mcs frames, if mixedmode(overloaded with long preamble) is going to be set, - * fill in non-zero MModeLen and/or MModeFbrLen - * it will be unnecessary if they are separated - */ - if (IS_MCS(rspec[0]) && (preamble_type[0] == WLC_MM_PREAMBLE)) { - u16 mmodelen = - wlc_calc_lsig_len(wlc, rspec[0], phylen); - txh->MModeLen = cpu_to_le16(mmodelen); - } - - if (IS_MCS(rspec[1]) && (preamble_type[1] == WLC_MM_PREAMBLE)) { - u16 mmodefbrlen = - wlc_calc_lsig_len(wlc, rspec[1], phylen); - txh->MModeFbrLen = cpu_to_le16(mmodefbrlen); - } - } - - if (IS_MCS(rspec[0])) - ASSERT(IS_MCS(rspec[1])); - - ASSERT(!IS_MCS(rspec[0]) || - ((preamble_type[0] == WLC_MM_PREAMBLE) == (txh->MModeLen != 0))); - ASSERT(!IS_MCS(rspec[1]) || - ((preamble_type[1] == WLC_MM_PREAMBLE) == - (txh->MModeFbrLen != 0))); - - ac = wme_fifo2ac[queue]; - if (SCB_WME(scb) && qos && wlc->edcf_txop[ac]) { - uint frag_dur, dur, dur_fallback; - - ASSERT(!is_multicast_ether_addr(h->addr1)); - - /* WME: Update TXOP threshold */ - if ((!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) && (frag == 0)) { - frag_dur = - wlc_calc_frame_time(wlc, rspec[0], preamble_type[0], - phylen); - - if (rts) { - /* 1 RTS or CTS-to-self frame */ - dur = - wlc_calc_cts_time(wlc, rts_rspec[0], - rts_preamble_type[0]); - dur_fallback = - wlc_calc_cts_time(wlc, rts_rspec[1], - rts_preamble_type[1]); - /* (SIFS + CTS) + SIFS + frame + SIFS + ACK */ - dur += le16_to_cpu(rts->duration); - dur_fallback += - le16_to_cpu(txh->RTSDurFallback); - } else if (use_rifs) { - dur = frag_dur; - dur_fallback = 0; - } else { - /* frame + SIFS + ACK */ - dur = frag_dur; - dur += - wlc_compute_frame_dur(wlc, rspec[0], - preamble_type[0], 0); - - dur_fallback = - wlc_calc_frame_time(wlc, rspec[1], - preamble_type[1], - phylen); - dur_fallback += - wlc_compute_frame_dur(wlc, rspec[1], - preamble_type[1], 0); - } - /* NEED to set TxFesTimeNormal (hard) */ - txh->TxFesTimeNormal = cpu_to_le16((u16) dur); - /* NEED to set fallback rate version of TxFesTimeNormal (hard) */ - txh->TxFesTimeFallback = - cpu_to_le16((u16) dur_fallback); - - /* update txop byte threshold (txop minus intraframe overhead) */ - if (wlc->edcf_txop[ac] >= (dur - frag_dur)) { - { - uint newfragthresh; - - newfragthresh = - wlc_calc_frame_len(wlc, rspec[0], - preamble_type[0], - (wlc-> - edcf_txop[ac] - - (dur - - frag_dur))); - /* range bound the fragthreshold */ - if (newfragthresh < DOT11_MIN_FRAG_LEN) - newfragthresh = - DOT11_MIN_FRAG_LEN; - else if (newfragthresh > - wlc->usr_fragthresh) - newfragthresh = - wlc->usr_fragthresh; - /* update the fragthresh and do txc update */ - if (wlc->fragthresh[queue] != - (u16) newfragthresh) { - wlc->fragthresh[queue] = - (u16) newfragthresh; - } - } - } else - WL_ERROR("wl%d: %s txop invalid for rate %d\n", - wlc->pub->unit, fifo_names[queue], - RSPEC2RATE(rspec[0])); - - if (dur > wlc->edcf_txop[ac]) - WL_ERROR("wl%d: %s: %s txop exceeded phylen %d/%d dur %d/%d\n", - wlc->pub->unit, __func__, - fifo_names[queue], - phylen, wlc->fragthresh[queue], - dur, wlc->edcf_txop[ac]); - } - } - - return 0; -} - -void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs) -{ - wlc_bsscfg_t *cfg = wlc->cfg; - - wlc->pub->_cnt->tbtt++; - - if (BSSCFG_STA(cfg)) { - /* run watchdog here if the watchdog timer is not armed */ - if (WLC_WATCHDOG_TBTT(wlc)) { - u32 cur, delta; - if (wlc->WDarmed) { - wl_del_timer(wlc->wl, wlc->wdtimer); - wlc->WDarmed = false; - } - - cur = OSL_SYSUPTIME(); - delta = cur > wlc->WDlast ? cur - wlc->WDlast : - (u32) ~0 - wlc->WDlast + cur + 1; - if (delta >= TIMER_INTERVAL_WATCHDOG) { - wlc_watchdog((void *)wlc); - wlc->WDlast = cur; - } - - wl_add_timer(wlc->wl, wlc->wdtimer, - wlc_watchdog_backup_bi(wlc), true); - wlc->WDarmed = true; - } - } - - if (!cfg->BSS) { - /* DirFrmQ is now valid...defer setting until end of ATIM window */ - wlc->qvalid |= MCMD_DIRFRMQVAL; - } -} - -/* GP timer is a freerunning 32 bit counter, decrements at 1 us rate */ -void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us) -{ - W_REG(&wlc->regs->gptimer, us); -} - -void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc) -{ - W_REG(&wlc->regs->gptimer, 0); -} - -static void wlc_hwtimer_gptimer_cb(struct wlc_info *wlc) -{ - /* when interrupt is generated, the counter is loaded with last value - * written and continue to decrement. So it has to be cleaned first - */ - W_REG(&wlc->regs->gptimer, 0); -} - -/* - * This fn has all the high level dpc processing from wlc_dpc. - * POLICY: no macinstatus change, no bounding loop. - * All dpc bounding should be handled in BMAC dpc, like txstatus and rxint - */ -void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus) -{ - d11regs_t *regs = wlc->regs; -#ifdef BCMDBG - char flagstr[128]; - static const bcm_bit_desc_t int_flags[] = { - {MI_MACSSPNDD, "MACSSPNDD"}, - {MI_BCNTPL, "BCNTPL"}, - {MI_TBTT, "TBTT"}, - {MI_BCNSUCCESS, "BCNSUCCESS"}, - {MI_BCNCANCLD, "BCNCANCLD"}, - {MI_ATIMWINEND, "ATIMWINEND"}, - {MI_PMQ, "PMQ"}, - {MI_NSPECGEN_0, "NSPECGEN_0"}, - {MI_NSPECGEN_1, "NSPECGEN_1"}, - {MI_MACTXERR, "MACTXERR"}, - {MI_NSPECGEN_3, "NSPECGEN_3"}, - {MI_PHYTXERR, "PHYTXERR"}, - {MI_PME, "PME"}, - {MI_GP0, "GP0"}, - {MI_GP1, "GP1"}, - {MI_DMAINT, "DMAINT"}, - {MI_TXSTOP, "TXSTOP"}, - {MI_CCA, "CCA"}, - {MI_BG_NOISE, "BG_NOISE"}, - {MI_DTIM_TBTT, "DTIM_TBTT"}, - {MI_PRQ, "PRQ"}, - {MI_PWRUP, "PWRUP"}, - {MI_RFDISABLE, "RFDISABLE"}, - {MI_TFS, "TFS"}, - {MI_PHYCHANGED, "PHYCHANGED"}, - {MI_TO, "TO"}, - {0, NULL} - }; - - if (macintstatus & ~(MI_TBTT | MI_TXSTOP)) { - bcm_format_flags(int_flags, macintstatus, flagstr, - sizeof(flagstr)); - WL_TRACE("wl%d: macintstatus 0x%x %s\n", - wlc->pub->unit, macintstatus, flagstr); - } -#endif /* BCMDBG */ - - if (macintstatus & MI_PRQ) { - /* Process probe request FIFO */ - ASSERT(0 && "PRQ Interrupt in non-MBSS"); - } - - /* TBTT indication */ - /* ucode only gives either TBTT or DTIM_TBTT, not both */ - if (macintstatus & (MI_TBTT | MI_DTIM_TBTT)) - wlc_tbtt(wlc, regs); - - if (macintstatus & MI_GP0) { - WL_ERROR("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", - wlc->pub->unit, wlc->pub->now); - - printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", - __func__, wlc->pub->sih->chip, - wlc->pub->sih->chiprev); - - wlc->pub->_cnt->psmwds++; - - /* big hammer */ - wl_init(wlc->wl); - } - - /* gptimer timeout */ - if (macintstatus & MI_TO) { - wlc_hwtimer_gptimer_cb(wlc); - } - - if (macintstatus & MI_RFDISABLE) { - WL_ERROR("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n", - wlc->pub->unit, - R_REG(®s->phydebug) & PDBG_RFD); - /* delay the cleanup to wl_down in IBSS case */ - if ((R_REG(®s->phydebug) & PDBG_RFD)) { - int idx; - wlc_bsscfg_t *bsscfg; - FOREACH_BSS(wlc, idx, bsscfg) { - if (!BSSCFG_STA(bsscfg) || !bsscfg->enable - || !bsscfg->BSS) - continue; - WL_ERROR("wl%d: wlc_dpc: rfdisable -> wlc_bsscfg_disable()\n", - wlc->pub->unit); - } - } - } - - /* send any enq'd tx packets. Just makes sure to jump start tx */ - if (!pktq_empty(&wlc->active_queue->q)) - wlc_send_q(wlc, wlc->active_queue); - - ASSERT(wlc_ps_check(wlc)); -} - -static void wlc_war16165(struct wlc_info *wlc, bool tx) -{ - if (tx) { - /* the post-increment is used in STAY_AWAKE macro */ - if (wlc->txpend16165war++ == 0) - wlc_set_ps_ctrl(wlc); - } else { - wlc->txpend16165war--; - if (wlc->txpend16165war == 0) - wlc_set_ps_ctrl(wlc); - } -} - -/* process an individual tx_status_t */ -/* WLC_HIGH_API */ -bool BCMFASTPATH -wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) -{ - struct sk_buff *p; - uint queue; - d11txh_t *txh; - struct scb *scb = NULL; - bool free_pdu; - struct osl_info *osh; - int tx_rts, tx_frame_count, tx_rts_count; - uint totlen, supr_status; - bool lastframe; - struct ieee80211_hdr *h; - u16 mcl; - struct ieee80211_tx_info *tx_info; - struct ieee80211_tx_rate *txrate; - int i; - - (void)(frm_tx2); /* Compiler reference to avoid unused variable warning */ - - /* discard intermediate indications for ucode with one legitimate case: - * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent - * tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts - * transmission count) - */ - if (!(txs->status & TX_STATUS_AMPDU) - && (txs->status & TX_STATUS_INTERMEDIATE)) { - WLCNTADD(wlc->pub->_cnt->txnoack, - ((txs-> - status & TX_STATUS_FRM_RTX_MASK) >> - TX_STATUS_FRM_RTX_SHIFT)); - WL_ERROR("%s: INTERMEDIATE but not AMPDU\n", __func__); - return false; - } - - osh = wlc->osh; - queue = txs->frameid & TXFID_QUEUE_MASK; - ASSERT(queue < NFIFO); - if (queue >= NFIFO) { - p = NULL; - goto fatal; - } - - p = GETNEXTTXP(wlc, queue); - if (WLC_WAR16165(wlc)) - wlc_war16165(wlc, false); - if (p == NULL) - goto fatal; - - txh = (d11txh_t *) (p->data); - mcl = le16_to_cpu(txh->MacTxControlLow); - - if (txs->phyerr) { - if (WL_ERROR_ON()) { - WL_ERROR("phyerr 0x%x, rate 0x%x\n", - txs->phyerr, txh->MainRates); - wlc_print_txdesc(txh); - } - wlc_print_txstatus(txs); - } - - ASSERT(txs->frameid == cpu_to_le16(txh->TxFrameID)); - if (txs->frameid != cpu_to_le16(txh->TxFrameID)) - goto fatal; - - tx_info = IEEE80211_SKB_CB(p); - h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); - - scb = (struct scb *)tx_info->control.sta->drv_priv; - - if (N_ENAB(wlc->pub)) { - u8 *plcp = (u8 *) (txh + 1); - if (PLCP3_ISSGI(plcp[3])) - wlc->pub->_cnt->txmpdu_sgi++; - if (PLCP3_ISSTBC(plcp[3])) - wlc->pub->_cnt->txmpdu_stbc++; - } - - if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { - ASSERT((mcl & TXC_AMPDU_MASK) != TXC_AMPDU_NONE); - wlc_ampdu_dotxstatus(wlc->ampdu, scb, p, txs); - return false; - } - - supr_status = txs->status & TX_STATUS_SUPR_MASK; - if (supr_status == TX_STATUS_SUPR_BADCH) - WL_NONE("%s: Pkt tx suppressed, possibly channel %d\n", - __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec)); - - tx_rts = cpu_to_le16(txh->MacTxControlLow) & TXC_SENDRTS; - tx_frame_count = - (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT; - tx_rts_count = - (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT; - - lastframe = !ieee80211_has_morefrags(h->frame_control); - - if (!lastframe) { - WL_ERROR("Not last frame!\n"); - } else { - u16 sfbl, lfbl; - ieee80211_tx_info_clear_status(tx_info); - if (queue < AC_COUNT) { - sfbl = WLC_WME_RETRY_SFB_GET(wlc, wme_fifo2ac[queue]); - lfbl = WLC_WME_RETRY_LFB_GET(wlc, wme_fifo2ac[queue]); - } else { - sfbl = wlc->SFBL; - lfbl = wlc->LFBL; - } - - txrate = tx_info->status.rates; - /* FIXME: this should use a combination of sfbl, lfbl depending on frame length and RTS setting */ - if ((tx_frame_count > sfbl) && (txrate[1].idx >= 0)) { - /* rate selection requested a fallback rate and we used it */ - txrate->count = lfbl; - txrate[1].count = tx_frame_count - lfbl; - } else { - /* rate selection did not request fallback rate, or we didn't need it */ - txrate->count = tx_frame_count; - /* rc80211_minstrel.c:minstrel_tx_status() expects unused rates to be marked with idx = -1 */ - txrate[1].idx = -1; - txrate[1].count = 0; - } - - /* clear the rest of the rates */ - for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) { - txrate[i].idx = -1; - txrate[i].count = 0; - } - - if (txs->status & TX_STATUS_ACK_RCV) - tx_info->flags |= IEEE80211_TX_STAT_ACK; - } - - totlen = pkttotlen(p); - free_pdu = true; - - wlc_txfifo_complete(wlc, queue, 1); - - if (lastframe) { - p->next = NULL; - p->prev = NULL; - wlc->txretried = 0; - /* remove PLCP & Broadcom tx descriptor header */ - skb_pull(p, D11_PHY_HDR_LEN); - skb_pull(p, D11_TXH_LEN); - ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); - wlc->pub->_cnt->ieee_tx_status++; - } else { - WL_ERROR("%s: Not last frame => not calling tx_status\n", - __func__); - } - - return false; - - fatal: - ASSERT(0); - if (p) - pkt_buf_free_skb(osh, p, true); - - return true; - -} - -void BCMFASTPATH -wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend) -{ - TXPKTPENDDEC(wlc, fifo, txpktpend); - WL_TRACE("wlc_txfifo_complete, pktpend dec %d to %d\n", - txpktpend, TXPKTPENDGET(wlc, fifo)); - - /* There is more room; mark precedences related to this FIFO sendable */ - WLC_TX_FIFO_ENAB(wlc, fifo); - ASSERT(TXPKTPENDGET(wlc, fifo) >= 0); - - if (!TXPKTPENDTOT(wlc)) { - if (wlc->block_datafifo & DATA_BLOCK_TX_SUPR) - wlc_bsscfg_tx_check(wlc); - } - - /* Clear MHF2_TXBCMC_NOW flag if BCMC fifo has drained */ - if (AP_ENAB(wlc->pub) && - wlc->bcmcfifo_drain && !TXPKTPENDGET(wlc, TX_BCMC_FIFO)) { - wlc->bcmcfifo_drain = false; - wlc_mhf(wlc, MHF2, MHF2_TXBCMC_NOW, 0, WLC_BAND_AUTO); - } - - /* figure out which bsscfg is being worked on... */ -} - -/* Given the beacon interval in kus, and a 64 bit TSF in us, - * return the offset (in us) of the TSF from the last TBTT - */ -u32 wlc_calc_tbtt_offset(u32 bp, u32 tsf_h, u32 tsf_l) -{ - u32 k, btklo, btkhi, offset; - - /* TBTT is always an even multiple of the beacon_interval, - * so the TBTT less than or equal to the beacon timestamp is - * the beacon timestamp minus the beacon timestamp modulo - * the beacon interval. - * - * TBTT = BT - (BT % BIu) - * = (BTk - (BTk % BP)) * 2^10 - * - * BT = beacon timestamp (usec, 64bits) - * BTk = beacon timestamp (Kusec, 54bits) - * BP = beacon interval (Kusec, 16bits) - * BIu = BP * 2^10 = beacon interval (usec, 26bits) - * - * To keep the calculations in u32s, the modulo operation - * on the high part of BT needs to be done in parts using the - * relations: - * X*Y mod Z = ((X mod Z) * (Y mod Z)) mod Z - * and - * (X + Y) mod Z = ((X mod Z) + (Y mod Z)) mod Z - * - * So, if BTk[n] = u16 n [0,3] of BTk. - * BTk % BP = SUM((BTk[n] * 2^16n) % BP , 0<=n<4) % BP - * and the SUM term can be broken down: - * (BTk[n] * 2^16n) % BP - * (BTk[n] * (2^16n % BP)) % BP - * - * Create a set of power of 2 mod BP constants: - * K[n] = 2^(16n) % BP - * = (K[n-1] * 2^16) % BP - * K[2] = 2^32 % BP = ((2^16 % BP) * 2^16) % BP - * - * BTk % BP = BTk[0-1] % BP + - * (BTk[2] * K[2]) % BP + - * (BTk[3] * K[3]) % BP - * - * Since K[n] < 2^16 and BTk[n] is < 2^16, then BTk[n] * K[n] < 2^32 - */ - - /* BTk = BT >> 10, btklo = BTk[0-3], bkthi = BTk[4-6] */ - btklo = (tsf_h << 22) | (tsf_l >> 10); - btkhi = tsf_h >> 10; - - /* offset = BTk % BP */ - offset = btklo % bp; - - /* K[2] = ((2^16 % BP) * 2^16) % BP */ - k = (u32) (1 << 16) % bp; - k = (u32) (k * 1 << 16) % (u32) bp; - - /* offset += (BTk[2] * K[2]) % BP */ - offset += ((btkhi & 0xffff) * k) % bp; - - /* BTk[3] */ - btkhi = btkhi >> 16; - - /* k[3] = (K[2] * 2^16) % BP */ - k = (k << 16) % bp; - - /* offset += (BTk[3] * K[3]) % BP */ - offset += ((btkhi & 0xffff) * k) % bp; - - offset = offset % bp; - - /* convert offset from kus to us by shifting up 10 bits and - * add in the low 10 bits of tsf that we ignored - */ - offset = (offset << 10) + (tsf_l & 0x3FF); - - return offset; -} - -/* Update beacon listen interval in shared memory */ -void wlc_bcn_li_upd(struct wlc_info *wlc) -{ - if (AP_ENAB(wlc->pub)) - return; - - /* wake up every DTIM is the default */ - if (wlc->bcn_li_dtim == 1) - wlc_write_shm(wlc, M_BCN_LI, 0); - else - wlc_write_shm(wlc, M_BCN_LI, - (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn); -} - -static void -prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, - struct ieee80211_rx_status *rx_status) -{ - u32 tsf_l, tsf_h; - wlc_d11rxhdr_t *wlc_rxh = (wlc_d11rxhdr_t *) rxh; - int preamble; - int channel; - ratespec_t rspec; - unsigned char *plcp; - - wlc_read_tsf(wlc, &tsf_l, &tsf_h); /* mactime */ - rx_status->mactime = tsf_h; - rx_status->mactime <<= 32; - rx_status->mactime |= tsf_l; - rx_status->flag |= RX_FLAG_TSFT; - - channel = WLC_CHAN_CHANNEL(rxh->RxChan); - - /* XXX Channel/badn needs to be filtered against whether we are single/dual band card */ - if (channel > 14) { - rx_status->band = IEEE80211_BAND_5GHZ; - rx_status->freq = ieee80211_ofdm_chan_to_freq( - WF_CHAN_FACTOR_5_G/2, channel); - - } else { - rx_status->band = IEEE80211_BAND_2GHZ; - rx_status->freq = ieee80211_dsss_chan_to_freq(channel); - } - - rx_status->signal = wlc_rxh->rssi; /* signal */ - - /* noise */ - /* qual */ - rx_status->antenna = (rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; /* ant */ - - plcp = p->data; - - rspec = wlc_compute_rspec(rxh, plcp); - if (IS_MCS(rspec)) { - rx_status->rate_idx = rspec & RSPEC_RATE_MASK; - rx_status->flag |= RX_FLAG_HT; - if (RSPEC_IS40MHZ(rspec)) - rx_status->flag |= RX_FLAG_40MHZ; - } else { - switch (RSPEC2RATE(rspec)) { - case WLC_RATE_1M: - rx_status->rate_idx = 0; - break; - case WLC_RATE_2M: - rx_status->rate_idx = 1; - break; - case WLC_RATE_5M5: - rx_status->rate_idx = 2; - break; - case WLC_RATE_11M: - rx_status->rate_idx = 3; - break; - case WLC_RATE_6M: - rx_status->rate_idx = 4; - break; - case WLC_RATE_9M: - rx_status->rate_idx = 5; - break; - case WLC_RATE_12M: - rx_status->rate_idx = 6; - break; - case WLC_RATE_18M: - rx_status->rate_idx = 7; - break; - case WLC_RATE_24M: - rx_status->rate_idx = 8; - break; - case WLC_RATE_36M: - rx_status->rate_idx = 9; - break; - case WLC_RATE_48M: - rx_status->rate_idx = 10; - break; - case WLC_RATE_54M: - rx_status->rate_idx = 11; - break; - default: - WL_ERROR("%s: Unknown rate\n", __func__); - } - - /* Determine short preamble and rate_idx */ - preamble = 0; - if (IS_CCK(rspec)) { - if (rxh->PhyRxStatus_0 & PRXS0_SHORTH) - WL_ERROR("Short CCK\n"); - rx_status->flag |= RX_FLAG_SHORTPRE; - } else if (IS_OFDM(rspec)) { - rx_status->flag |= RX_FLAG_SHORTPRE; - } else { - WL_ERROR("%s: Unknown modulation\n", __func__); - } - } - - if (PLCP3_ISSGI(plcp[3])) - rx_status->flag |= RX_FLAG_SHORT_GI; - - if (rxh->RxStatus1 & RXS_DECERR) { - rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC; - WL_ERROR("%s: RX_FLAG_FAILED_PLCP_CRC\n", __func__); - } - if (rxh->RxStatus1 & RXS_FCSERR) { - rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; - WL_ERROR("%s: RX_FLAG_FAILED_FCS_CRC\n", __func__); - } -} - -static void -wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, d11rxhdr_t *rxh, - struct sk_buff *p) -{ - int len_mpdu; - struct ieee80211_rx_status rx_status; -#if defined(BCMDBG) - struct sk_buff *skb = p; -#endif /* BCMDBG */ - /* Todo: - * Cache plcp for first MPDU of AMPD and use chacched version for INTERMEDIATE. - * Test for INTERMEDIATE like so: - * if (!(plcp[0] | plcp[1] | plcp[2])) - */ - - memset(&rx_status, 0, sizeof(rx_status)); - prep_mac80211_status(wlc, rxh, p, &rx_status); - - /* mac header+body length, exclude CRC and plcp header */ - len_mpdu = p->len - D11_PHY_HDR_LEN - FCS_LEN; - skb_pull(p, D11_PHY_HDR_LEN); - __skb_trim(p, len_mpdu); - - ASSERT(!(p->next)); - ASSERT(!(p->prev)); - - ASSERT(IS_ALIGNED((unsigned long)skb->data, 2)); - - memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status)); - ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p); - - wlc->pub->_cnt->ieee_rx++; - osh->pktalloced--; - return; -} - -void wlc_bss_list_free(struct wlc_info *wlc, struct wlc_bss_list *bss_list) -{ - uint index; - - if (!bss_list) { - WL_ERROR("%s: Attempting to free NULL list\n", __func__); - return; - } - /* inspect all BSS descriptor */ - for (index = 0; index < bss_list->count; index++) { - kfree(bss_list->ptrs[index]); - bss_list->ptrs[index] = NULL; - } - bss_list->count = 0; -} - -/* Process received frames */ -/* - * Return true if more frames need to be processed. false otherwise. - * Param 'bound' indicates max. # frames to process before break out. - */ -/* WLC_HIGH_API */ -void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) -{ - d11rxhdr_t *rxh; - struct ieee80211_hdr *h; - struct osl_info *osh; - uint len; - bool is_amsdu; - - WL_TRACE("wl%d: wlc_recv\n", wlc->pub->unit); - - osh = wlc->osh; - - /* frame starts with rxhdr */ - rxh = (d11rxhdr_t *) (p->data); - - /* strip off rxhdr */ - skb_pull(p, wlc->hwrxoff); - - /* fixup rx header endianness */ - rxh->RxFrameSize = le16_to_cpu(rxh->RxFrameSize); - rxh->PhyRxStatus_0 = le16_to_cpu(rxh->PhyRxStatus_0); - rxh->PhyRxStatus_1 = le16_to_cpu(rxh->PhyRxStatus_1); - rxh->PhyRxStatus_2 = le16_to_cpu(rxh->PhyRxStatus_2); - rxh->PhyRxStatus_3 = le16_to_cpu(rxh->PhyRxStatus_3); - rxh->PhyRxStatus_4 = le16_to_cpu(rxh->PhyRxStatus_4); - rxh->PhyRxStatus_5 = le16_to_cpu(rxh->PhyRxStatus_5); - rxh->RxStatus1 = le16_to_cpu(rxh->RxStatus1); - rxh->RxStatus2 = le16_to_cpu(rxh->RxStatus2); - rxh->RxTSFTime = le16_to_cpu(rxh->RxTSFTime); - rxh->RxChan = le16_to_cpu(rxh->RxChan); - - /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ - if (rxh->RxStatus1 & RXS_PBPRES) { - if (p->len < 2) { - wlc->pub->_cnt->rxrunt++; - WL_ERROR("wl%d: wlc_recv: rcvd runt of len %d\n", - wlc->pub->unit, p->len); - goto toss; - } - skb_pull(p, 2); - } - - h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN); - len = p->len; - - if (rxh->RxStatus1 & RXS_FCSERR) { - if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) { - WL_ERROR("FCSERR while scanning******* - tossing\n"); - goto toss; - } else { - WL_ERROR("RCSERR!!!\n"); - goto toss; - } - } - - /* check received pkt has at least frame control field */ - if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control)) { - wlc->pub->_cnt->rxrunt++; - goto toss; - } - - is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK; - - /* explicitly test bad src address to avoid sending bad deauth */ - if (!is_amsdu) { - /* CTS and ACK CTL frames are w/o a2 */ - - if (ieee80211_is_data(h->frame_control) || - ieee80211_is_mgmt(h->frame_control)) { - if ((is_zero_ether_addr(h->addr2) || - is_multicast_ether_addr(h->addr2))) { - WL_ERROR("wl%d: %s: dropping a frame with " - "invalid src mac address, a2: %pM\n", - wlc->pub->unit, __func__, h->addr2); - wlc->pub->_cnt->rxbadsrcmac++; - goto toss; - } - wlc->pub->_cnt->rxfrag++; - } - } - - /* due to sheer numbers, toss out probe reqs for now */ - if (ieee80211_is_probe_req(h->frame_control)) - goto toss; - - if (is_amsdu) { - WL_ERROR("%s: is_amsdu causing toss\n", __func__); - goto toss; - } - - wlc_recvctl(wlc, osh, rxh, p); - return; - - toss: - pkt_buf_free_skb(osh, p, false); -} - -/* calculate frame duration for Mixed-mode L-SIG spoofing, return - * number of bytes goes in the length field - * - * Formula given by HT PHY Spec v 1.13 - * len = 3(nsyms + nstream + 3) - 3 - */ -u16 BCMFASTPATH -wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, uint mac_len) -{ - uint nsyms, len = 0, kNdps; - - WL_TRACE("wl%d: wlc_calc_lsig_len: rate %d, len%d\n", - wlc->pub->unit, RSPEC2RATE(ratespec), mac_len); - - if (IS_MCS(ratespec)) { - uint mcs = ratespec & RSPEC_RATE_MASK; - /* MCS_TXS(mcs) returns num tx streams - 1 */ - int tot_streams = (MCS_TXS(mcs) + 1) + RSPEC_STC(ratespec); - - ASSERT(WLC_PHY_11N_CAP(wlc->band)); - /* the payload duration calculation matches that of regular ofdm */ - /* 1000Ndbps = kbps * 4 */ - kNdps = - MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec), - RSPEC_ISSGI(ratespec)) * 4; - - if (RSPEC_STC(ratespec) == 0) - /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ - nsyms = - CEIL((APHY_SERVICE_NBITS + 8 * mac_len + - APHY_TAIL_NBITS) * 1000, kNdps); - else - /* STBC needs to have even number of symbols */ - nsyms = - 2 * - CEIL((APHY_SERVICE_NBITS + 8 * mac_len + - APHY_TAIL_NBITS) * 1000, 2 * kNdps); - - nsyms += (tot_streams + 3); /* (+3) account for HT-SIG(2) and HT-STF(1) */ - /* 3 bytes/symbol @ legacy 6Mbps rate */ - len = (3 * nsyms) - 3; /* (-3) excluding service bits and tail bits */ - } - - return (u16) len; -} - -/* calculate frame duration of a given rate and length, return time in usec unit */ -uint BCMFASTPATH -wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, - uint mac_len) -{ - uint nsyms, dur = 0, Ndps, kNdps; - uint rate = RSPEC2RATE(ratespec); - - if (rate == 0) { - ASSERT(0); - WL_ERROR("wl%d: WAR: using rate of 1 mbps\n", wlc->pub->unit); - rate = WLC_RATE_1M; - } - - WL_TRACE("wl%d: wlc_calc_frame_time: rspec 0x%x, preamble_type %d, len%d\n", - wlc->pub->unit, ratespec, preamble_type, mac_len); - - if (IS_MCS(ratespec)) { - uint mcs = ratespec & RSPEC_RATE_MASK; - int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec); - ASSERT(WLC_PHY_11N_CAP(wlc->band)); - ASSERT(WLC_IS_MIMO_PREAMBLE(preamble_type)); - - dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT); - if (preamble_type == WLC_MM_PREAMBLE) - dur += PREN_MM_EXT; - /* 1000Ndbps = kbps * 4 */ - kNdps = - MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec), - RSPEC_ISSGI(ratespec)) * 4; - - if (RSPEC_STC(ratespec) == 0) - /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ - nsyms = - CEIL((APHY_SERVICE_NBITS + 8 * mac_len + - APHY_TAIL_NBITS) * 1000, kNdps); - else - /* STBC needs to have even number of symbols */ - nsyms = - 2 * - CEIL((APHY_SERVICE_NBITS + 8 * mac_len + - APHY_TAIL_NBITS) * 1000, 2 * kNdps); - - dur += APHY_SYMBOL_TIME * nsyms; - if (BAND_2G(wlc->band->bandtype)) - dur += DOT11_OFDM_SIGNAL_EXTENSION; - } else if (IS_OFDM(rate)) { - dur = APHY_PREAMBLE_TIME; - dur += APHY_SIGNAL_TIME; - /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */ - Ndps = rate * 2; - /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ - nsyms = - CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS), - Ndps); - dur += APHY_SYMBOL_TIME * nsyms; - if (BAND_2G(wlc->band->bandtype)) - dur += DOT11_OFDM_SIGNAL_EXTENSION; - } else { - /* calc # bits * 2 so factor of 2 in rate (1/2 mbps) will divide out */ - mac_len = mac_len * 8 * 2; - /* calc ceiling of bits/rate = microseconds of air time */ - dur = (mac_len + rate - 1) / rate; - if (preamble_type & WLC_SHORT_PREAMBLE) - dur += BPHY_PLCP_SHORT_TIME; - else - dur += BPHY_PLCP_TIME; - } - return dur; -} - -/* The opposite of wlc_calc_frame_time */ -static uint -wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, - uint dur) -{ - uint nsyms, mac_len, Ndps, kNdps; - uint rate = RSPEC2RATE(ratespec); - - WL_TRACE("wl%d: wlc_calc_frame_len: rspec 0x%x, preamble_type %d, dur %d\n", - wlc->pub->unit, ratespec, preamble_type, dur); - - if (IS_MCS(ratespec)) { - uint mcs = ratespec & RSPEC_RATE_MASK; - int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec); - ASSERT(WLC_PHY_11N_CAP(wlc->band)); - dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT); - /* payload calculation matches that of regular ofdm */ - if (BAND_2G(wlc->band->bandtype)) - dur -= DOT11_OFDM_SIGNAL_EXTENSION; - /* kNdbps = kbps * 4 */ - kNdps = - MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec), - RSPEC_ISSGI(ratespec)) * 4; - nsyms = dur / APHY_SYMBOL_TIME; - mac_len = - ((nsyms * kNdps) - - ((APHY_SERVICE_NBITS + APHY_TAIL_NBITS) * 1000)) / 8000; - } else if (IS_OFDM(ratespec)) { - dur -= APHY_PREAMBLE_TIME; - dur -= APHY_SIGNAL_TIME; - /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */ - Ndps = rate * 2; - nsyms = dur / APHY_SYMBOL_TIME; - mac_len = - ((nsyms * Ndps) - - (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8; - } else { - if (preamble_type & WLC_SHORT_PREAMBLE) - dur -= BPHY_PLCP_SHORT_TIME; - else - dur -= BPHY_PLCP_TIME; - mac_len = dur * rate; - /* divide out factor of 2 in rate (1/2 mbps) */ - mac_len = mac_len / 8 / 2; - } - return mac_len; -} - -static uint -wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) -{ - WL_TRACE("wl%d: wlc_calc_ba_time: rspec 0x%x, preamble_type %d\n", - wlc->pub->unit, rspec, preamble_type); - /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than - * or equal to the rate of the immediately previous frame in the FES - */ - rspec = WLC_BASIC_RATE(wlc, rspec); - ASSERT(VALID_RATE_DBG(wlc, rspec)); - - /* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */ - return wlc_calc_frame_time(wlc, rspec, preamble_type, - (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN + - FCS_LEN)); -} - -static uint BCMFASTPATH -wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) -{ - uint dur = 0; - - WL_TRACE("wl%d: wlc_calc_ack_time: rspec 0x%x, preamble_type %d\n", - wlc->pub->unit, rspec, preamble_type); - /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than - * or equal to the rate of the immediately previous frame in the FES - */ - rspec = WLC_BASIC_RATE(wlc, rspec); - ASSERT(VALID_RATE_DBG(wlc, rspec)); - - /* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */ - dur = - wlc_calc_frame_time(wlc, rspec, preamble_type, - (DOT11_ACK_LEN + FCS_LEN)); - return dur; -} - -static uint -wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) -{ - WL_TRACE("wl%d: wlc_calc_cts_time: ratespec 0x%x, preamble_type %d\n", - wlc->pub->unit, rspec, preamble_type); - return wlc_calc_ack_time(wlc, rspec, preamble_type); -} - -/* derive wlc->band->basic_rate[] table from 'rateset' */ -void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset) -{ - u8 rate; - u8 mandatory; - u8 cck_basic = 0; - u8 ofdm_basic = 0; - u8 *br = wlc->band->basic_rate; - uint i; - - /* incoming rates are in 500kbps units as in 802.11 Supported Rates */ - memset(br, 0, WLC_MAXRATE + 1); - - /* For each basic rate in the rates list, make an entry in the - * best basic lookup. - */ - for (i = 0; i < rateset->count; i++) { - /* only make an entry for a basic rate */ - if (!(rateset->rates[i] & WLC_RATE_FLAG)) - continue; - - /* mask off basic bit */ - rate = (rateset->rates[i] & RATE_MASK); - - if (rate > WLC_MAXRATE) { - WL_ERROR("wlc_rate_lookup_init: invalid rate 0x%X in rate set\n", - rateset->rates[i]); - continue; - } - - br[rate] = rate; - } - - /* The rate lookup table now has non-zero entries for each - * basic rate, equal to the basic rate: br[basicN] = basicN - * - * To look up the best basic rate corresponding to any - * particular rate, code can use the basic_rate table - * like this - * - * basic_rate = wlc->band->basic_rate[tx_rate] - * - * Make sure there is a best basic rate entry for - * every rate by walking up the table from low rates - * to high, filling in holes in the lookup table - */ - - for (i = 0; i < wlc->band->hw_rateset.count; i++) { - rate = wlc->band->hw_rateset.rates[i]; - ASSERT(rate <= WLC_MAXRATE); - - if (br[rate] != 0) { - /* This rate is a basic rate. - * Keep track of the best basic rate so far by - * modulation type. - */ - if (IS_OFDM(rate)) - ofdm_basic = rate; - else - cck_basic = rate; - - continue; - } - - /* This rate is not a basic rate so figure out the - * best basic rate less than this rate and fill in - * the hole in the table - */ - - br[rate] = IS_OFDM(rate) ? ofdm_basic : cck_basic; - - if (br[rate] != 0) - continue; - - if (IS_OFDM(rate)) { - /* In 11g and 11a, the OFDM mandatory rates are 6, 12, and 24 Mbps */ - if (rate >= WLC_RATE_24M) - mandatory = WLC_RATE_24M; - else if (rate >= WLC_RATE_12M) - mandatory = WLC_RATE_12M; - else - mandatory = WLC_RATE_6M; - } else { - /* In 11b, all the CCK rates are mandatory 1 - 11 Mbps */ - mandatory = rate; - } - - br[rate] = mandatory; - } -} - -static void wlc_write_rate_shm(struct wlc_info *wlc, u8 rate, u8 basic_rate) -{ - u8 phy_rate, index; - u8 basic_phy_rate, basic_index; - u16 dir_table, basic_table; - u16 basic_ptr; - - /* Shared memory address for the table we are reading */ - dir_table = IS_OFDM(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B; - - /* Shared memory address for the table we are writing */ - basic_table = IS_OFDM(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B; - - /* - * for a given rate, the LS-nibble of the PLCP SIGNAL field is - * the index into the rate table. - */ - phy_rate = rate_info[rate] & RATE_MASK; - basic_phy_rate = rate_info[basic_rate] & RATE_MASK; - index = phy_rate & 0xf; - basic_index = basic_phy_rate & 0xf; - - /* Find the SHM pointer to the ACK rate entry by looking in the - * Direct-map Table - */ - basic_ptr = wlc_read_shm(wlc, (dir_table + basic_index * 2)); - - /* Update the SHM BSS-basic-rate-set mapping table with the pointer - * to the correct basic rate for the given incoming rate - */ - wlc_write_shm(wlc, (basic_table + index * 2), basic_ptr); -} - -static const wlc_rateset_t *wlc_rateset_get_hwrs(struct wlc_info *wlc) -{ - const wlc_rateset_t *rs_dflt; - - if (WLC_PHY_11N_CAP(wlc->band)) { - if (BAND_5G(wlc->band->bandtype)) - rs_dflt = &ofdm_mimo_rates; - else - rs_dflt = &cck_ofdm_mimo_rates; - } else if (wlc->band->gmode) - rs_dflt = &cck_ofdm_rates; - else - rs_dflt = &cck_rates; - - return rs_dflt; -} - -void wlc_set_ratetable(struct wlc_info *wlc) -{ - const wlc_rateset_t *rs_dflt; - wlc_rateset_t rs; - u8 rate, basic_rate; - uint i; - - rs_dflt = wlc_rateset_get_hwrs(wlc); - ASSERT(rs_dflt != NULL); - - wlc_rateset_copy(rs_dflt, &rs); - wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams); - - /* walk the phy rate table and update SHM basic rate lookup table */ - for (i = 0; i < rs.count; i++) { - rate = rs.rates[i] & RATE_MASK; - - /* for a given rate WLC_BASIC_RATE returns the rate at - * which a response ACK/CTS should be sent. - */ - basic_rate = WLC_BASIC_RATE(wlc, rate); - if (basic_rate == 0) { - /* This should only happen if we are using a - * restricted rateset. - */ - basic_rate = rs.rates[0] & RATE_MASK; - } - - wlc_write_rate_shm(wlc, rate, basic_rate); - } -} - -/* - * Return true if the specified rate is supported by the specified band. - * WLC_BAND_AUTO indicates the current band. - */ -bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rspec, int band, - bool verbose) -{ - wlc_rateset_t *hw_rateset; - uint i; - - if ((band == WLC_BAND_AUTO) || (band == wlc->band->bandtype)) { - hw_rateset = &wlc->band->hw_rateset; - } else if (NBANDS(wlc) > 1) { - hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset; - } else { - /* other band specified and we are a single band device */ - return false; - } - - /* check if this is a mimo rate */ - if (IS_MCS(rspec)) { - if (!VALID_MCS((rspec & RSPEC_RATE_MASK))) - goto error; - - return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK)); - } - - for (i = 0; i < hw_rateset->count; i++) - if (hw_rateset->rates[i] == RSPEC2RATE(rspec)) - return true; - error: - if (verbose) { - WL_ERROR("wl%d: wlc_valid_rate: rate spec 0x%x not in hw_rateset\n", - wlc->pub->unit, rspec); - } - - return false; -} - -static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap) -{ - uint i; - struct wlcband *band; - - for (i = 0; i < NBANDS(wlc); i++) { - if (IS_SINGLEBAND_5G(wlc->deviceid)) - i = BAND_5G_INDEX; - band = wlc->bandstate[i]; - if (band->bandtype == WLC_BAND_5G) { - if ((bwcap == WLC_N_BW_40ALL) - || (bwcap == WLC_N_BW_20IN2G_40IN5G)) - band->mimo_cap_40 = true; - else - band->mimo_cap_40 = false; - } else { - ASSERT(band->bandtype == WLC_BAND_2G); - if (bwcap == WLC_N_BW_40ALL) - band->mimo_cap_40 = true; - else - band->mimo_cap_40 = false; - } - } - - wlc->mimo_band_bwcap = bwcap; -} - -void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len) -{ - const wlc_rateset_t *rs_dflt; - wlc_rateset_t rs; - u8 rate; - u16 entry_ptr; - u8 plcp[D11_PHY_HDR_LEN]; - u16 dur, sifs; - uint i; - - sifs = SIFS(wlc->band); - - rs_dflt = wlc_rateset_get_hwrs(wlc); - ASSERT(rs_dflt != NULL); - - wlc_rateset_copy(rs_dflt, &rs); - wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams); - - /* walk the phy rate table and update MAC core SHM basic rate table entries */ - for (i = 0; i < rs.count; i++) { - rate = rs.rates[i] & RATE_MASK; - - entry_ptr = wlc_rate_shm_offset(wlc, rate); - - /* Calculate the Probe Response PLCP for the given rate */ - wlc_compute_plcp(wlc, rate, frame_len, plcp); - - /* Calculate the duration of the Probe Response frame plus SIFS for the MAC */ - dur = - (u16) wlc_calc_frame_time(wlc, rate, WLC_LONG_PREAMBLE, - frame_len); - dur += sifs; - - /* Update the SHM Rate Table entry Probe Response values */ - wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS, - (u16) (plcp[0] + (plcp[1] << 8))); - wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS + 2, - (u16) (plcp[2] + (plcp[3] << 8))); - wlc_write_shm(wlc, entry_ptr + M_RT_PRS_DUR_POS, dur); - } -} - -u16 -wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec, - bool short_preamble, bool phydelay) -{ - uint bcntsfoff = 0; - - if (IS_MCS(rspec)) { - WL_ERROR("wl%d: recd beacon with mcs rate; rspec 0x%x\n", - wlc->pub->unit, rspec); - } else if (IS_OFDM(rspec)) { - /* tx delay from MAC through phy to air (2.1 usec) + - * phy header time (preamble + PLCP SIGNAL == 20 usec) + - * PLCP SERVICE + MAC header time (SERVICE + FC + DUR + A1 + A2 + A3 + SEQ == 26 - * bytes at beacon rate) - */ - bcntsfoff += phydelay ? D11A_PHY_TX_DELAY : 0; - bcntsfoff += APHY_PREAMBLE_TIME + APHY_SIGNAL_TIME; - bcntsfoff += - wlc_compute_airtime(wlc, rspec, - APHY_SERVICE_NBITS / 8 + - DOT11_MAC_HDR_LEN); - } else { - /* tx delay from MAC through phy to air (3.4 usec) + - * phy header time (long preamble + PLCP == 192 usec) + - * MAC header time (FC + DUR + A1 + A2 + A3 + SEQ == 24 bytes at beacon rate) - */ - bcntsfoff += phydelay ? D11B_PHY_TX_DELAY : 0; - bcntsfoff += - short_preamble ? D11B_PHY_SPREHDR_TIME : - D11B_PHY_LPREHDR_TIME; - bcntsfoff += wlc_compute_airtime(wlc, rspec, DOT11_MAC_HDR_LEN); - } - return (u16) (bcntsfoff); -} - -/* Max buffering needed for beacon template/prb resp template is 142 bytes. - * - * PLCP header is 6 bytes. - * 802.11 A3 header is 24 bytes. - * Max beacon frame body template length is 112 bytes. - * Max probe resp frame body template length is 110 bytes. - * - * *len on input contains the max length of the packet available. - * - * The *len value is set to the number of bytes in buf used, and starts with the PLCP - * and included up to, but not including, the 4 byte FCS. - */ -static void -wlc_bcn_prb_template(struct wlc_info *wlc, u16 type, ratespec_t bcn_rspec, - wlc_bsscfg_t *cfg, u16 *buf, int *len) -{ - static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; - cck_phy_hdr_t *plcp; - struct ieee80211_mgmt *h; - int hdr_len, body_len; - - ASSERT(*len >= 142); - ASSERT(type == IEEE80211_STYPE_BEACON || - type == IEEE80211_STYPE_PROBE_RESP); - - if (MBSS_BCN_ENAB(cfg) && type == IEEE80211_STYPE_BEACON) - hdr_len = DOT11_MAC_HDR_LEN; - else - hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN; - body_len = *len - hdr_len; /* calc buffer size provided for frame body */ - - *len = hdr_len + body_len; /* return actual size */ - - /* format PHY and MAC headers */ - memset((char *)buf, 0, hdr_len); - - plcp = (cck_phy_hdr_t *) buf; - - /* PLCP for Probe Response frames are filled in from core's rate table */ - if (type == IEEE80211_STYPE_BEACON && !MBSS_BCN_ENAB(cfg)) { - /* fill in PLCP */ - wlc_compute_plcp(wlc, bcn_rspec, - (DOT11_MAC_HDR_LEN + body_len + FCS_LEN), - (u8 *) plcp); - - } - /* "Regular" and 16 MBSS but not for 4 MBSS */ - /* Update the phytxctl for the beacon based on the rspec */ - if (!SOFTBCN_ENAB(cfg)) - wlc_beacon_phytxctl_txant_upd(wlc, bcn_rspec); - - if (MBSS_BCN_ENAB(cfg) && type == IEEE80211_STYPE_BEACON) - h = (struct ieee80211_mgmt *)&plcp[0]; - else - h = (struct ieee80211_mgmt *)&plcp[1]; - - /* fill in 802.11 header */ - h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type); - - /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */ - /* A1 filled in by MAC for prb resp, broadcast for bcn */ - if (type == IEEE80211_STYPE_BEACON) - memcpy(&h->da, ðer_bcast, ETH_ALEN); - memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN); - memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN); - - /* SEQ filled in by MAC */ - - return; -} - -int wlc_get_header_len() -{ - return TXOFF; -} - -/* Update a beacon for a particular BSS - * For MBSS, this updates the software template and sets "latest" to the index of the - * template updated. - * Otherwise, it updates the hardware template. - */ -void wlc_bss_update_beacon(struct wlc_info *wlc, wlc_bsscfg_t *cfg) -{ - int len = BCN_TMPL_LEN; - - /* Clear the soft intmask */ - wlc->defmacintmask &= ~MI_BCNTPL; - - if (!cfg->up) { /* Only allow updates on an UP bss */ - return; - } - - /* Optimize: Some of if/else could be combined */ - if (!MBSS_BCN_ENAB(cfg) && HWBCN_ENAB(cfg)) { - /* Hardware beaconing for this config */ - u16 bcn[BCN_TMPL_LEN / 2]; - u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD; - d11regs_t *regs = wlc->regs; - struct osl_info *osh = NULL; - - osh = wlc->osh; - - /* Check if both templates are in use, if so sched. an interrupt - * that will call back into this routine - */ - if ((R_REG(®s->maccommand) & both_valid) == both_valid) { - /* clear any previous status */ - W_REG(®s->macintstatus, MI_BCNTPL); - } - /* Check that after scheduling the interrupt both of the - * templates are still busy. if not clear the int. & remask - */ - if ((R_REG(®s->maccommand) & both_valid) == both_valid) { - wlc->defmacintmask |= MI_BCNTPL; - return; - } - - wlc->bcn_rspec = - wlc_lowest_basic_rspec(wlc, &cfg->current_bss->rateset); - ASSERT(wlc_valid_rate - (wlc, wlc->bcn_rspec, - CHSPEC_IS2G(cfg->current_bss-> - chanspec) ? WLC_BAND_2G : WLC_BAND_5G, - true)); - - /* update the template and ucode shm */ - wlc_bcn_prb_template(wlc, IEEE80211_STYPE_BEACON, - wlc->bcn_rspec, cfg, bcn, &len); - wlc_write_hw_bcntemplates(wlc, bcn, len, false); - } -} - -/* - * Update all beacons for the system. - */ -void wlc_update_beacon(struct wlc_info *wlc) -{ - int idx; - wlc_bsscfg_t *bsscfg; - - /* update AP or IBSS beacons */ - FOREACH_BSS(wlc, idx, bsscfg) { - if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS)) - wlc_bss_update_beacon(wlc, bsscfg); - } -} - -/* Write ssid into shared memory */ -void wlc_shm_ssid_upd(struct wlc_info *wlc, wlc_bsscfg_t *cfg) -{ - u8 *ssidptr = cfg->SSID; - u16 base = M_SSID; - u8 ssidbuf[IEEE80211_MAX_SSID_LEN]; - - /* padding the ssid with zero and copy it into shm */ - memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN); - memcpy(ssidbuf, ssidptr, cfg->SSID_len); - - wlc_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN); - - if (!MBSS_BCN_ENAB(cfg)) - wlc_write_shm(wlc, M_SSIDLEN, (u16) cfg->SSID_len); -} - -void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend) -{ - int idx; - wlc_bsscfg_t *bsscfg; - - /* update AP or IBSS probe responses */ - FOREACH_BSS(wlc, idx, bsscfg) { - if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS)) - wlc_bss_update_probe_resp(wlc, bsscfg, suspend); - } -} - -void -wlc_bss_update_probe_resp(struct wlc_info *wlc, wlc_bsscfg_t *cfg, bool suspend) -{ - u16 prb_resp[BCN_TMPL_LEN / 2]; - int len = BCN_TMPL_LEN; - - /* write the probe response to hardware, or save in the config structure */ - if (!MBSS_PRB_ENAB(cfg)) { - - /* create the probe response template */ - wlc_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0, cfg, - prb_resp, &len); - - if (suspend) - wlc_suspend_mac_and_wait(wlc); - - /* write the probe response into the template region */ - wlc_bmac_write_template_ram(wlc->hw, T_PRS_TPL_BASE, - (len + 3) & ~3, prb_resp); - - /* write the length of the probe response frame (+PLCP/-FCS) */ - wlc_write_shm(wlc, M_PRB_RESP_FRM_LEN, (u16) len); - - /* write the SSID and SSID length */ - wlc_shm_ssid_upd(wlc, cfg); - - /* - * Write PLCP headers and durations for probe response frames at all rates. - * Use the actual frame length covered by the PLCP header for the call to - * wlc_mod_prb_rsp_rate_table() by subtracting the PLCP len and adding the FCS. - */ - len += (-D11_PHY_HDR_LEN + FCS_LEN); - wlc_mod_prb_rsp_rate_table(wlc, (u16) len); - - if (suspend) - wlc_enable_mac(wlc); - } else { /* Generating probe resp in sw; update local template */ - ASSERT(0 && "No software probe response support without MBSS"); - } -} - -/* prepares pdu for transmission. returns BCM error codes */ -int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) -{ - struct osl_info *osh; - uint fifo; - d11txh_t *txh; - struct ieee80211_hdr *h; - struct scb *scb; - - osh = wlc->osh; - - ASSERT(pdu); - txh = (d11txh_t *) (pdu->data); - ASSERT(txh); - h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); - ASSERT(h); - - /* get the pkt queue info. This was put at wlc_sendctl or wlc_send for PDU */ - fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK; - - scb = NULL; - - *fifop = fifo; - - /* return if insufficient dma resources */ - if (TXAVAIL(wlc, fifo) < MAX_DMA_SEGS) { - /* Mark precedences related to this FIFO, unsendable */ - WLC_TX_FIFO_CLEAR(wlc, fifo); - return BCME_BUSY; - } - - if (!ieee80211_is_data(txh->MacFrameControl)) - wlc->pub->_cnt->txctl++; - - return 0; -} - -/* init tx reported rate mechanism */ -void wlc_reprate_init(struct wlc_info *wlc) -{ - int i; - wlc_bsscfg_t *bsscfg; - - FOREACH_BSS(wlc, i, bsscfg) { - wlc_bsscfg_reprate_init(bsscfg); - } -} - -/* per bsscfg init tx reported rate mechanism */ -void wlc_bsscfg_reprate_init(wlc_bsscfg_t *bsscfg) -{ - bsscfg->txrspecidx = 0; - memset((char *)bsscfg->txrspec, 0, sizeof(bsscfg->txrspec)); -} - -/* Retrieve a consolidated set of revision information, - * typically for the WLC_GET_REVINFO ioctl - */ -int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len) -{ - wlc_rev_info_t *rinfo = (wlc_rev_info_t *) buf; - - if (len < WL_REV_INFO_LEGACY_LENGTH) - return BCME_BUFTOOSHORT; - - rinfo->vendorid = wlc->vendorid; - rinfo->deviceid = wlc->deviceid; - rinfo->radiorev = (wlc->band->radiorev << IDCODE_REV_SHIFT) | - (wlc->band->radioid << IDCODE_ID_SHIFT); - rinfo->chiprev = wlc->pub->sih->chiprev; - rinfo->corerev = wlc->pub->corerev; - rinfo->boardid = wlc->pub->sih->boardtype; - rinfo->boardvendor = wlc->pub->sih->boardvendor; - rinfo->boardrev = wlc->pub->boardrev; - rinfo->ucoderev = wlc->ucode_rev; - rinfo->driverrev = EPI_VERSION_NUM; - rinfo->bus = wlc->pub->sih->bustype; - rinfo->chipnum = wlc->pub->sih->chip; - - if (len >= (offsetof(wlc_rev_info_t, chippkg))) { - rinfo->phytype = wlc->band->phytype; - rinfo->phyrev = wlc->band->phyrev; - rinfo->anarev = 0; /* obsolete stuff, suppress */ - } - - if (len >= sizeof(*rinfo)) { - rinfo->chippkg = wlc->pub->sih->chippkg; - } - - return BCME_OK; -} - -void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs) -{ - wlc_rateset_default(rs, NULL, wlc->band->phytype, wlc->band->bandtype, - false, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub), - CHSPEC_WLC_BW(wlc->default_bss->chanspec), - wlc->stf->txstreams); -} - -static void wlc_bss_default_init(struct wlc_info *wlc) -{ - chanspec_t chanspec; - struct wlcband *band; - wlc_bss_info_t *bi = wlc->default_bss; - - /* init default and target BSS with some sane initial values */ - memset((char *)(bi), 0, sizeof(wlc_bss_info_t)); - bi->beacon_period = ISSIM_ENAB(wlc->pub->sih) ? BEACON_INTERVAL_DEF_QT : - BEACON_INTERVAL_DEFAULT; - bi->dtim_period = ISSIM_ENAB(wlc->pub->sih) ? DTIM_INTERVAL_DEF_QT : - DTIM_INTERVAL_DEFAULT; - - /* fill the default channel as the first valid channel - * starting from the 2G channels - */ - chanspec = CH20MHZ_CHSPEC(1); - ASSERT(chanspec != INVCHANSPEC); - - wlc->home_chanspec = bi->chanspec = chanspec; - - /* find the band of our default channel */ - band = wlc->band; - if (NBANDS(wlc) > 1 && band->bandunit != CHSPEC_WLCBANDUNIT(chanspec)) - band = wlc->bandstate[OTHERBANDUNIT(wlc)]; - - /* init bss rates to the band specific default rate set */ - wlc_rateset_default(&bi->rateset, NULL, band->phytype, band->bandtype, - false, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub), - CHSPEC_WLC_BW(chanspec), wlc->stf->txstreams); - - if (N_ENAB(wlc->pub)) - bi->flags |= WLC_BSS_HT; -} - -void -wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, u32 b_low) -{ - if (b_low > *a_low) { - /* low half needs a carry */ - b_high += 1; - } - *a_low -= b_low; - *a_high -= b_high; -} - -static ratespec_t -mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, - u32 int_val) -{ - u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT; - u8 rate = int_val & NRATE_RATE_MASK; - ratespec_t rspec; - bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE); - bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT); - bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY) - == NRATE_OVERRIDE_MCS_ONLY); - int bcmerror = 0; - - if (!ismcs) { - return (ratespec_t) rate; - } - - /* validate the combination of rate/mcs/stf is allowed */ - if (N_ENAB(wlc->pub) && ismcs) { - /* mcs only allowed when nmode */ - if (stf > PHY_TXC1_MODE_SDM) { - WL_ERROR("wl%d: %s: Invalid stf\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - - /* mcs 32 is a special case, DUP mode 40 only */ - if (rate == 32) { - if (!CHSPEC_IS40(wlc->home_chanspec) || - ((stf != PHY_TXC1_MODE_SISO) - && (stf != PHY_TXC1_MODE_CDD))) { - WL_ERROR("wl%d: %s: Invalid mcs 32\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - /* mcs > 7 must use stf SDM */ - } else if (rate > HIGHEST_SINGLE_STREAM_MCS) { - /* mcs > 7 must use stf SDM */ - if (stf != PHY_TXC1_MODE_SDM) { - WL_TRACE("wl%d: %s: enabling SDM mode for mcs %d\n", - WLCWLUNIT(wlc), __func__, rate); - stf = PHY_TXC1_MODE_SDM; - } - } else { - /* MCS 0-7 may use SISO, CDD, and for phy_rev >= 3 STBC */ - if ((stf > PHY_TXC1_MODE_STBC) || - (!WLC_STBC_CAP_PHY(wlc) - && (stf == PHY_TXC1_MODE_STBC))) { - WL_ERROR("wl%d: %s: Invalid STBC\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - } - } else if (IS_OFDM(rate)) { - if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) { - WL_ERROR("wl%d: %s: Invalid OFDM\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - } else if (IS_CCK(rate)) { - if ((cur_band->bandtype != WLC_BAND_2G) - || (stf != PHY_TXC1_MODE_SISO)) { - WL_ERROR("wl%d: %s: Invalid CCK\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - } else { - WL_ERROR("wl%d: %s: Unknown rate type\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - /* make sure multiple antennae are available for non-siso rates */ - if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) { - WL_ERROR("wl%d: %s: SISO antenna but !SISO request\n", - WLCWLUNIT(wlc), __func__); - bcmerror = BCME_RANGE; - goto done; - } - - rspec = rate; - if (ismcs) { - rspec |= RSPEC_MIMORATE; - /* For STBC populate the STC field of the ratespec */ - if (stf == PHY_TXC1_MODE_STBC) { - u8 stc; - stc = 1; /* Nss for single stream is always 1 */ - rspec |= (stc << RSPEC_STC_SHIFT); - } - } - - rspec |= (stf << RSPEC_STF_SHIFT); - - if (override_mcs_only) - rspec |= RSPEC_OVERRIDE_MCS_ONLY; - - if (issgi) - rspec |= RSPEC_SHORT_GI; - - if ((rate != 0) - && !wlc_valid_rate(wlc, rspec, cur_band->bandtype, true)) { - return rate; - } - - return rspec; - done: - WL_ERROR("Hoark\n"); - return rate; -} - -/* formula: IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */ -static int -wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, - bool writeToShm) -{ - int idle_busy_ratio_x_16 = 0; - uint offset = - isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM : - M_TX_IDLE_BUSY_RATIO_X_16_CCK; - if (duty_cycle > 100 || duty_cycle < 0) { - WL_ERROR("wl%d: duty cycle value off limit\n", wlc->pub->unit); - return BCME_RANGE; - } - if (duty_cycle) - idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle; - /* Only write to shared memory when wl is up */ - if (writeToShm) - wlc_write_shm(wlc, offset, (u16) idle_busy_ratio_x_16); - - if (isOFDM) - wlc->tx_duty_cycle_ofdm = (u16) duty_cycle; - else - wlc->tx_duty_cycle_cck = (u16) duty_cycle; - - return BCME_OK; -} - -/* Read a single u16 from shared memory. - * SHM 'offset' needs to be an even address - */ -u16 wlc_read_shm(struct wlc_info *wlc, uint offset) -{ - return wlc_bmac_read_shm(wlc->hw, offset); -} - -/* Write a single u16 to shared memory. - * SHM 'offset' needs to be an even address - */ -void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v) -{ - wlc_bmac_write_shm(wlc->hw, offset, v); -} - -/* Set a range of shared memory to a value. - * SHM 'offset' needs to be an even address and - * Range length 'len' must be an even number of bytes - */ -void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len) -{ - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) - return; - - wlc_bmac_set_shm(wlc->hw, offset, v, len); -} - -/* Copy a buffer to shared memory. - * SHM 'offset' needs to be an even address and - * Buffer length 'len' must be an even number of bytes - */ -void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, int len) -{ - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) - return; - wlc_bmac_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL); - -} - -/* Copy from shared memory to a buffer. - * SHM 'offset' needs to be an even address and - * Buffer length 'len' must be an even number of bytes - */ -void wlc_copyfrom_shm(struct wlc_info *wlc, uint offset, void *buf, int len) -{ - /* offset and len need to be even */ - ASSERT((offset & 1) == 0); - ASSERT((len & 1) == 0); - - if (len <= 0) - return; - - wlc_bmac_copyfrom_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL); -} - -/* wrapper BMAC functions to for HIGH driver access */ -void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val) -{ - wlc_bmac_mctrl(wlc->hw, mask, val); -} - -void wlc_corereset(struct wlc_info *wlc, u32 flags) -{ - wlc_bmac_corereset(wlc->hw, flags); -} - -void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val, int bands) -{ - wlc_bmac_mhf(wlc->hw, idx, mask, val, bands); -} - -u16 wlc_mhf_get(struct wlc_info *wlc, u8 idx, int bands) -{ - return wlc_bmac_mhf_get(wlc->hw, idx, bands); -} - -int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks) -{ - return wlc_bmac_xmtfifo_sz_get(wlc->hw, fifo, blocks); -} - -void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len, - void *buf) -{ - wlc_bmac_write_template_ram(wlc->hw, offset, len, buf); -} - -void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len, - bool both) -{ - wlc_bmac_write_hw_bcntemplates(wlc->hw, bcn, len, both); -} - -void -wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, - const u8 *addr) -{ - wlc_bmac_set_addrmatch(wlc->hw, match_reg_offset, addr); - if (match_reg_offset == RCM_BSSID_OFFSET) - memcpy(wlc->cfg->BSSID, addr, ETH_ALEN); -} - -void wlc_set_rcmta(struct wlc_info *wlc, int idx, const u8 *addr) -{ - wlc_bmac_set_rcmta(wlc->hw, idx, addr); -} - -void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, u32 *tsf_h_ptr) -{ - wlc_bmac_read_tsf(wlc->hw, tsf_l_ptr, tsf_h_ptr); -} - -void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin) -{ - wlc->band->CWmin = newmin; - wlc_bmac_set_cwmin(wlc->hw, newmin); -} - -void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax) -{ - wlc->band->CWmax = newmax; - wlc_bmac_set_cwmax(wlc->hw, newmax); -} - -void wlc_fifoerrors(struct wlc_info *wlc) -{ - - wlc_bmac_fifoerrors(wlc->hw); -} - -/* Search mem rw utilities */ - -void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit) -{ - wlc_bmac_pllreq(wlc->hw, set, req_bit); -} - -void wlc_reset_bmac_done(struct wlc_info *wlc) -{ -} - -void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode) -{ - wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_SM_PS; - wlc->ht_cap.cap_info |= (mimops_mode << IEEE80211_HT_CAP_SM_PS_SHIFT); - - if (AP_ENAB(wlc->pub) && wlc->clk) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - } -} - -/* check for the particular priority flow control bit being set */ -bool -wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, struct wlc_txq_info *q, - int prio) -{ - uint prio_mask; - - if (prio == ALLPRIO) { - prio_mask = TXQ_STOP_FOR_PRIOFC_MASK; - } else { - ASSERT(prio >= 0 && prio <= MAXPRIO); - prio_mask = NBITVAL(prio); - } - - return (q->stopped & prio_mask) == prio_mask; -} - -/* propogate the flow control to all interfaces using the given tx queue */ -void wlc_txflowcontrol(struct wlc_info *wlc, struct wlc_txq_info *qi, - bool on, int prio) -{ - uint prio_bits; - uint cur_bits; - - WL_TRACE("%s: flow control kicks in\n", __func__); - - if (prio == ALLPRIO) { - prio_bits = TXQ_STOP_FOR_PRIOFC_MASK; - } else { - ASSERT(prio >= 0 && prio <= MAXPRIO); - prio_bits = NBITVAL(prio); - } - - cur_bits = qi->stopped & prio_bits; - - /* Check for the case of no change and return early - * Otherwise update the bit and continue - */ - if (on) { - if (cur_bits == prio_bits) { - return; - } - mboolset(qi->stopped, prio_bits); - } else { - if (cur_bits == 0) { - return; - } - mboolclr(qi->stopped, prio_bits); - } - - /* If there is a flow control override we will not change the external - * flow control state. - */ - if (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK) { - return; - } - - wlc_txflowcontrol_signal(wlc, qi, on, prio); -} - -void -wlc_txflowcontrol_override(struct wlc_info *wlc, struct wlc_txq_info *qi, - bool on, uint override) -{ - uint prev_override; - - ASSERT(override != 0); - ASSERT((override & TXQ_STOP_FOR_PRIOFC_MASK) == 0); - - prev_override = (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK); - - /* Update the flow control bits and do an early return if there is - * no change in the external flow control state. - */ - if (on) { - mboolset(qi->stopped, override); - /* if there was a previous override bit on, then setting this - * makes no difference. - */ - if (prev_override) { - return; - } - - wlc_txflowcontrol_signal(wlc, qi, ON, ALLPRIO); - } else { - mboolclr(qi->stopped, override); - /* clearing an override bit will only make a difference for - * flow control if it was the only bit set. For any other - * override setting, just return - */ - if (prev_override != override) { - return; - } - - if (qi->stopped == 0) { - wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); - } else { - int prio; - - for (prio = MAXPRIO; prio >= 0; prio--) { - if (!mboolisset(qi->stopped, NBITVAL(prio))) - wlc_txflowcontrol_signal(wlc, qi, OFF, - prio); - } - } - } -} - -static void wlc_txflowcontrol_reset(struct wlc_info *wlc) -{ - struct wlc_txq_info *qi; - - for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { - if (qi->stopped) { - wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); - qi->stopped = 0; - } - } -} - -static void -wlc_txflowcontrol_signal(struct wlc_info *wlc, struct wlc_txq_info *qi, bool on, - int prio) -{ - struct wlc_if *wlcif; - - for (wlcif = wlc->wlcif_list; wlcif != NULL; wlcif = wlcif->next) { - if (wlcif->qi == qi && wlcif->flags & WLC_IF_LINKED) - wl_txflowcontrol(wlc->wl, wlcif->wlif, on, prio); - } -} - -static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc, - struct osl_info *osh) -{ - struct wlc_txq_info *qi, *p; - - qi = wlc_calloc(wlc->pub->unit, sizeof(struct wlc_txq_info)); - if (qi != NULL) { - /* - * Have enough room for control packets along with HI watermark - * Also, add room to txq for total psq packets if all the SCBs - * leave PS mode. The watermark for flowcontrol to OS packets - * will remain the same - */ - pktq_init(&qi->q, WLC_PREC_COUNT, - (2 * wlc->pub->tunables->datahiwat) + PKTQ_LEN_DEFAULT - + wlc->pub->psq_pkts_total); - - /* add this queue to the the global list */ - p = wlc->tx_queues; - if (p == NULL) { - wlc->tx_queues = qi; - } else { - while (p->next != NULL) - p = p->next; - p->next = qi; - } - } - return qi; -} - -static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh, - struct wlc_txq_info *qi) -{ - struct wlc_txq_info *p; - - if (qi == NULL) - return; - - /* remove the queue from the linked list */ - p = wlc->tx_queues; - if (p == qi) - wlc->tx_queues = p->next; - else { - while (p != NULL && p->next != qi) - p = p->next; - ASSERT(p->next == qi); - if (p != NULL) - p->next = p->next->next; - } - - kfree(qi); -} - -/* - * Flag 'scan in progress' to withold dynamic phy calibration - */ -void wlc_scan_start(struct wlc_info *wlc) -{ - wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true); -} - -void wlc_scan_stop(struct wlc_info *wlc) -{ - wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false); -} - -void wlc_associate_upd(struct wlc_info *wlc, bool state) -{ - wlc->pub->associated = state; - wlc->cfg->associated = state; -} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h deleted file mode 100644 index f65be0ed1c1a..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/wlc_mac80211.h +++ /dev/null @@ -1,967 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_h_ -#define _wlc_h_ - -#define MA_WINDOW_SZ 8 /* moving average window size */ -#define WL_HWRXOFF 38 /* chip rx buffer offset */ -#define INVCHANNEL 255 /* invalid channel */ -#define MAXCOREREV 28 /* max # supported core revisions (0 .. MAXCOREREV - 1) */ -#define WLC_MAXMODULES 22 /* max # wlc_module_register() calls */ - -#define WLC_BITSCNT(x) bcm_bitcount((u8 *)&(x), sizeof(u8)) - -/* Maximum wait time for a MAC suspend */ -#define WLC_MAX_MAC_SUSPEND 83000 /* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */ - -/* Probe Response timeout - responses for probe requests older that this are tossed, zero to disable - */ -#define WLC_PRB_RESP_TIMEOUT 0 /* Disable probe response timeout */ - -/* transmit buffer max headroom for protocol headers */ -#define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN) - -/* For managing scan result lists */ -struct wlc_bss_list { - uint count; - bool beacon; /* set for beacon, cleared for probe response */ - wlc_bss_info_t *ptrs[MAXBSS]; -}; - -#define SW_TIMER_MAC_STAT_UPD 30 /* periodic MAC stats update */ - -/* Double check that unsupported cores are not enabled */ -#if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV) -#error "Configuration for D11CONF includes unsupported versions." -#endif /* Bad versions */ - -#define VALID_COREREV(corerev) CONF_HAS(D11CONF, corerev) - -/* values for shortslot_override */ -#define WLC_SHORTSLOT_AUTO -1 /* Driver will manage Shortslot setting */ -#define WLC_SHORTSLOT_OFF 0 /* Turn off short slot */ -#define WLC_SHORTSLOT_ON 1 /* Turn on short slot */ - -/* value for short/long and mixmode/greenfield preamble */ - -#define WLC_LONG_PREAMBLE (0) -#define WLC_SHORT_PREAMBLE (1 << 0) -#define WLC_GF_PREAMBLE (1 << 1) -#define WLC_MM_PREAMBLE (1 << 2) -#define WLC_IS_MIMO_PREAMBLE(_pre) (((_pre) == WLC_GF_PREAMBLE) || ((_pre) == WLC_MM_PREAMBLE)) - -/* values for barker_preamble */ -#define WLC_BARKER_SHORT_ALLOWED 0 /* Short pre-amble allowed */ - -/* A fifo is full. Clear precedences related to that FIFO */ -#define WLC_TX_FIFO_CLEAR(wlc, fifo) ((wlc)->tx_prec_map &= ~(wlc)->fifo2prec_map[fifo]) - -/* Fifo is NOT full. Enable precedences for that FIFO */ -#define WLC_TX_FIFO_ENAB(wlc, fifo) ((wlc)->tx_prec_map |= (wlc)->fifo2prec_map[fifo]) - -/* TxFrameID */ -/* seq and frag bits: SEQNUM_SHIFT, FRAGNUM_MASK (802.11.h) */ -/* rate epoch bits: TXFID_RATE_SHIFT, TXFID_RATE_MASK ((wlc_rate.c) */ -#define TXFID_QUEUE_MASK 0x0007 /* Bits 0-2 */ -#define TXFID_SEQ_MASK 0x7FE0 /* Bits 5-15 */ -#define TXFID_SEQ_SHIFT 5 /* Number of bit shifts */ -#define TXFID_RATE_PROBE_MASK 0x8000 /* Bit 15 for rate probe */ -#define TXFID_RATE_MASK 0x0018 /* Mask for bits 3 and 4 */ -#define TXFID_RATE_SHIFT 3 /* Shift 3 bits for rate mask */ - -/* promote boardrev */ -#define BOARDREV_PROMOTABLE 0xFF /* from */ -#define BOARDREV_PROMOTED 1 /* to */ - -/* if wpa is in use then portopen is true when the group key is plumbed otherwise it is always true - */ -#define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) -#define WLC_SW_KEYS(wlc, bsscfg) ((((wlc)->wsec_swkeys) || \ - ((bsscfg)->wsec & WSEC_SWFLAG))) - -#define WLC_PORTOPEN(cfg) \ - (((cfg)->WPA_auth != WPA_AUTH_DISABLED && WSEC_ENABLED((cfg)->wsec)) ? \ - (cfg)->wsec_portopen : true) - -#define PS_ALLOWED(wlc) wlc_ps_allowed(wlc) -#define STAY_AWAKE(wlc) wlc_stay_awake(wlc) - -#define DATA_BLOCK_TX_SUPR (1 << 4) - -/* 802.1D Priority to TX FIFO number for wme */ -extern const u8 prio2fifo[]; - -/* Ucode MCTL_WAKE override bits */ -#define WLC_WAKE_OVERRIDE_CLKCTL 0x01 -#define WLC_WAKE_OVERRIDE_PHYREG 0x02 -#define WLC_WAKE_OVERRIDE_MACSUSPEND 0x04 -#define WLC_WAKE_OVERRIDE_TXFIFO 0x08 -#define WLC_WAKE_OVERRIDE_FORCEFAST 0x10 - -/* stuff pulled in from wlc.c */ - -/* Interrupt bit error summary. Don't include I_RU: we refill DMA at other - * times; and if we run out, constant I_RU interrupts may cause lockup. We - * will still get error counts from rx0ovfl. - */ -#define I_ERRORS (I_PC | I_PD | I_DE | I_RO | I_XU) -/* default software intmasks */ -#define DEF_RXINTMASK (I_RI) /* enable rx int on rxfifo only */ -#define DEF_MACINTMASK (MI_TXSTOP | MI_TBTT | MI_ATIMWINEND | MI_PMQ | \ - MI_PHYTXERR | MI_DMAINT | MI_TFS | MI_BG_NOISE | \ - MI_CCA | MI_TO | MI_GP0 | MI_RFDISABLE | MI_PWRUP) - -#define RETRY_SHORT_DEF 7 /* Default Short retry Limit */ -#define RETRY_SHORT_MAX 255 /* Maximum Short retry Limit */ -#define RETRY_LONG_DEF 4 /* Default Long retry count */ -#define RETRY_SHORT_FB 3 /* Short retry count for fallback rate */ -#define RETRY_LONG_FB 2 /* Long retry count for fallback rate */ - -#define MAXTXPKTS 6 /* max # pkts pending */ - -/* frameburst */ -#define MAXTXFRAMEBURST 8 /* vanilla xpress mode: max frames/burst */ -#define MAXFRAMEBURST_TXOP 10000 /* Frameburst TXOP in usec */ - -/* Per-AC retry limit register definitions; uses bcmdefs.h bitfield macros */ -#define EDCF_SHORT_S 0 -#define EDCF_SFB_S 4 -#define EDCF_LONG_S 8 -#define EDCF_LFB_S 12 -#define EDCF_SHORT_M BITFIELD_MASK(4) -#define EDCF_SFB_M BITFIELD_MASK(4) -#define EDCF_LONG_M BITFIELD_MASK(4) -#define EDCF_LFB_M BITFIELD_MASK(4) - -#define WLC_WME_RETRY_SHORT_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_SHORT) -#define WLC_WME_RETRY_SFB_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_SFB) -#define WLC_WME_RETRY_LONG_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_LONG) -#define WLC_WME_RETRY_LFB_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_LFB) - -#define WLC_WME_RETRY_SHORT_SET(wlc, ac, val) \ - (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SHORT, val)) -#define WLC_WME_RETRY_SFB_SET(wlc, ac, val) \ - (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SFB, val)) -#define WLC_WME_RETRY_LONG_SET(wlc, ac, val) \ - (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LONG, val)) -#define WLC_WME_RETRY_LFB_SET(wlc, ac, val) \ - (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LFB, val)) - -/* PLL requests */ -#define WLC_PLLREQ_SHARED 0x1 /* pll is shared on old chips */ -#define WLC_PLLREQ_RADIO_MON 0x2 /* hold pll for radio monitor register checking */ -#define WLC_PLLREQ_FLIP 0x4 /* hold/release pll for some short operation */ - -/* Do we support this rate? */ -#define VALID_RATE_DBG(wlc, rspec) wlc_valid_rate(wlc, rspec, WLC_BAND_AUTO, true) - -/* - * Macros to check if AP or STA is active. - * AP Active means more than just configured: driver and BSS are "up"; - * that is, we are beaconing/responding as an AP (aps_associated). - * STA Active similarly means the driver is up and a configured STA BSS - * is up: either associated (stas_associated) or trying. - * - * Macro definitions vary as per AP/STA ifdefs, allowing references to - * ifdef'd structure fields and constant values (0) for optimization. - * Make sure to enclose blocks of code such that any routines they - * reference can also be unused and optimized out by the linker. - */ -/* NOTE: References structure fields defined in wlc.h */ -#define AP_ACTIVE(wlc) (0) - -/* - * Detect Card removed. - * Even checking an sbconfig register read will not false trigger when the core is in reset. - * it breaks CF address mechanism. Accessing gphy phyversion will cause SB error if aphy - * is in reset on 4306B0-DB. Need a simple accessible reg with fixed 0/1 pattern - * (some platforms return all 0). - * If clocks are present, call the sb routine which will figure out if the device is removed. - */ -#define DEVICEREMOVED(wlc) \ - ((wlc->hw->clk) ? \ - ((R_REG(&wlc->hw->regs->maccontrol) & \ - (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN) : \ - (si_deviceremoved(wlc->hw->sih))) - -#define WLCWLUNIT(wlc) ((wlc)->pub->unit) - -struct wlc_protection { - bool _g; /* use g spec protection, driver internal */ - s8 g_override; /* override for use of g spec protection */ - u8 gmode_user; /* user config gmode, operating band->gmode is different */ - s8 overlap; /* Overlap BSS/IBSS protection for both 11g and 11n */ - s8 nmode_user; /* user config nmode, operating pub->nmode is different */ - s8 n_cfg; /* use OFDM protection on MIMO frames */ - s8 n_cfg_override; /* override for use of N protection */ - bool nongf; /* non-GF present protection */ - s8 nongf_override; /* override for use of GF protection */ - s8 n_pam_override; /* override for preamble: MM or GF */ - bool n_obss; /* indicated OBSS Non-HT STA present */ - - uint longpre_detect_timeout; /* #sec until long preamble bcns gone */ - uint barker_detect_timeout; /* #sec until bcns signaling Barker long preamble */ - /* only is gone */ - uint ofdm_ibss_timeout; /* #sec until ofdm IBSS beacons gone */ - uint ofdm_ovlp_timeout; /* #sec until ofdm overlapping BSS bcns gone */ - uint nonerp_ibss_timeout; /* #sec until nonerp IBSS beacons gone */ - uint nonerp_ovlp_timeout; /* #sec until nonerp overlapping BSS bcns gone */ - uint g_ibss_timeout; /* #sec until bcns signaling Use_Protection gone */ - uint n_ibss_timeout; /* #sec until bcns signaling Use_OFDM_Protection gone */ - uint ht20in40_ovlp_timeout; /* #sec until 20MHz overlapping OPMODE gone */ - uint ht20in40_ibss_timeout; /* #sec until 20MHz-only HT station bcns gone */ - uint non_gf_ibss_timeout; /* #sec until non-GF bcns gone */ -}; - -/* anything affects the single/dual streams/antenna operation */ -struct wlc_stf { - u8 hw_txchain; /* HW txchain bitmap cfg */ - u8 txchain; /* txchain bitmap being used */ - u8 txstreams; /* number of txchains being used */ - - u8 hw_rxchain; /* HW rxchain bitmap cfg */ - u8 rxchain; /* rxchain bitmap being used */ - u8 rxstreams; /* number of rxchains being used */ - - u8 ant_rx_ovr; /* rx antenna override */ - s8 txant; /* userTx antenna setting */ - u16 phytxant; /* phyTx antenna setting in txheader */ - - u8 ss_opmode; /* singlestream Operational mode, 0:siso; 1:cdd */ - bool ss_algosel_auto; /* if true, use wlc->stf->ss_algo_channel; */ - /* else use wlc->band->stf->ss_mode_band; */ - u16 ss_algo_channel; /* ss based on per-channel algo: 0: SISO, 1: CDD 2: STBC */ - u8 no_cddstbc; /* stf override, 1: no CDD (or STBC) allowed */ - - u8 rxchain_restore_delay; /* delay time to restore default rxchain */ - - s8 ldpc; /* AUTO/ON/OFF ldpc cap supported */ - u8 txcore[MAX_STREAMS_SUPPORTED + 1]; /* bitmap of selected core for each Nsts */ - s8 spatial_policy; -}; - -#define WLC_STF_SS_STBC_TX(wlc, scb) \ - (((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) || \ - (SCB_STBC_CAP((scb)) && \ - (wlc)->band->band_stf_stbc_tx == AUTO && \ - isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC)))) - -#define WLC_STBC_CAP_PHY(wlc) (WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3)) - -#define WLC_SGI_CAP_PHY(wlc) ((WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3)) || \ - WLCISLCNPHY(wlc->band)) - -#define WLC_CHAN_PHYTYPE(x) (((x) & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT) -#define WLC_CHAN_CHANNEL(x) (((x) & RXS_CHAN_ID_MASK) >> RXS_CHAN_ID_SHIFT) -#define WLC_RX_CHANNEL(rxh) (WLC_CHAN_CHANNEL((rxh)->RxChan)) - -/* wlc_bss_info flag bit values */ -#define WLC_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */ - -/* Flags used in wlc_txq_info.stopped */ -#define TXQ_STOP_FOR_PRIOFC_MASK 0x000000FF /* per prio flow control bits */ -#define TXQ_STOP_FOR_PKT_DRAIN 0x00000100 /* stop txq enqueue for packet drain */ -#define TXQ_STOP_FOR_AMPDU_FLOW_CNTRL 0x00000200 /* stop txq enqueue for ampdu flow control */ - -#define WLC_HT_WEP_RESTRICT 0x01 /* restrict HT with WEP */ -#define WLC_HT_TKIP_RESTRICT 0x02 /* restrict HT with TKIP */ - -/* - * core state (mac) - */ -struct wlccore { - uint coreidx; /* # sb enumerated core */ - - /* fifo */ - uint *txavail[NFIFO]; /* # tx descriptors available */ - s16 txpktpend[NFIFO]; /* tx admission control */ - - macstat_t *macstat_snapshot; /* mac hw prev read values */ -}; - -/* - * band state (phy+ana+radio) - */ -struct wlcband { - int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */ - uint bandunit; /* bandstate[] index */ - - u16 phytype; /* phytype */ - u16 phyrev; - u16 radioid; - u16 radiorev; - wlc_phy_t *pi; /* pointer to phy specific information */ - bool abgphy_encore; - - u8 gmode; /* currently active gmode (see wlioctl.h) */ - - struct scb *hwrs_scb; /* permanent scb for hw rateset */ - - wlc_rateset_t defrateset; /* band-specific copy of default_bss.rateset */ - - ratespec_t rspec_override; /* 802.11 rate override */ - ratespec_t mrspec_override; /* multicast rate override */ - u8 band_stf_ss_mode; /* Configured STF type, 0:siso; 1:cdd */ - s8 band_stf_stbc_tx; /* STBC TX 0:off; 1:force on; -1:auto */ - wlc_rateset_t hw_rateset; /* rates supported by chip (phy-specific) */ - u8 basic_rate[WLC_MAXRATE + 1]; /* basic rates indexed by rate */ - bool mimo_cap_40; /* 40 MHz cap enabled on this band */ - s8 antgain; /* antenna gain from srom */ - - u16 CWmin; /* The minimum size of contention window, in unit of aSlotTime */ - u16 CWmax; /* The maximum size of contention window, in unit of aSlotTime */ - u16 bcntsfoff; /* beacon tsf offset */ -}; - -/* tx completion callback takes 3 args */ -typedef void (*pkcb_fn_t) (struct wlc_info *wlc, uint txstatus, void *arg); - -struct pkt_cb { - pkcb_fn_t fn; /* function to call when tx frame completes */ - void *arg; /* void arg for fn */ - u8 nextidx; /* index of next call back if threading */ - bool entered; /* recursion check */ -}; - -/* module control blocks */ -struct modulecb { - char name[32]; /* module name : NULL indicates empty array member */ - const bcm_iovar_t *iovars; /* iovar table */ - void *hdl; /* handle passed when handler 'doiovar' is called */ - watchdog_fn_t watchdog_fn; /* watchdog handler */ - iovar_fn_t iovar_fn; /* iovar handler */ - down_fn_t down_fn; /* down handler. Note: the int returned - * by the down function is a count of the - * number of timers that could not be - * freed. - */ -}; - -/* dump control blocks */ -struct dumpcb_s { - const char *name; /* dump name */ - dump_fn_t dump_fn; /* 'wl dump' handler */ - void *dump_fn_arg; - struct dumpcb_s *next; -}; - -/* virtual interface */ -struct wlc_if { - struct wlc_if *next; - u8 type; /* WLC_IFTYPE_BSS or WLC_IFTYPE_WDS */ - u8 index; /* assigned in wl_add_if(), index of the wlif if any, - * not necessarily corresponding to bsscfg._idx or - * AID2PVBMAP(scb). - */ - u8 flags; /* flags for the interface */ - struct wl_if *wlif; /* pointer to wlif */ - struct wlc_txq_info *qi; /* pointer to associated tx queue */ - union { - struct scb *scb; /* pointer to scb if WLC_IFTYPE_WDS */ - struct wlc_bsscfg *bsscfg; /* pointer to bsscfg if WLC_IFTYPE_BSS */ - } u; -}; - -/* flags for the interface */ -#define WLC_IF_LINKED 0x02 /* this interface is linked to a wl_if */ - -struct wlc_hwband { - int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */ - uint bandunit; /* bandstate[] index */ - u16 mhfs[MHFMAX]; /* MHF array shadow */ - u8 bandhw_stf_ss_mode; /* HW configured STF type, 0:siso; 1:cdd */ - u16 CWmin; - u16 CWmax; - u32 core_flags; - - u16 phytype; /* phytype */ - u16 phyrev; - u16 radioid; - u16 radiorev; - wlc_phy_t *pi; /* pointer to phy specific information */ - bool abgphy_encore; -}; - -struct wlc_hw_info { - struct osl_info *osh; /* pointer to os handle */ - bool _piomode; /* true if pio mode */ - struct wlc_info *wlc; - - /* fifo */ - struct hnddma_pub *di[NFIFO]; /* hnddma handles, per fifo */ - - uint unit; /* device instance number */ - - /* version info */ - u16 vendorid; /* PCI vendor id */ - u16 deviceid; /* PCI device id */ - uint corerev; /* core revision */ - u8 sromrev; /* version # of the srom */ - u16 boardrev; /* version # of particular board */ - u32 boardflags; /* Board specific flags from srom */ - u32 boardflags2; /* More board flags if sromrev >= 4 */ - u32 machwcap; /* MAC capabilities */ - u32 machwcap_backup; /* backup of machwcap */ - u16 ucode_dbgsel; /* dbgsel for ucode debug(config gpio) */ - - si_t *sih; /* SB handle (cookie for siutils calls) */ - char *vars; /* "environment" name=value */ - uint vars_size; /* size of vars, free vars on detach */ - d11regs_t *regs; /* pointer to device registers */ - void *physhim; /* phy shim layer handler */ - void *phy_sh; /* pointer to shared phy state */ - struct wlc_hwband *band;/* pointer to active per-band state */ - struct wlc_hwband *bandstate[MAXBANDS];/* band state per phy/radio */ - u16 bmac_phytxant; /* cache of high phytxant state */ - bool shortslot; /* currently using 11g ShortSlot timing */ - u16 SRL; /* 802.11 dot11ShortRetryLimit */ - u16 LRL; /* 802.11 dot11LongRetryLimit */ - u16 SFBL; /* Short Frame Rate Fallback Limit */ - u16 LFBL; /* Long Frame Rate Fallback Limit */ - - bool up; /* d11 hardware up and running */ - uint now; /* # elapsed seconds */ - uint _nbands; /* # bands supported */ - chanspec_t chanspec; /* bmac chanspec shadow */ - - uint *txavail[NFIFO]; /* # tx descriptors available */ - u16 *xmtfifo_sz; /* fifo size in 256B for each xmt fifo */ - - mbool pllreq; /* pll requests to keep PLL on */ - - u8 suspended_fifos; /* Which TX fifo to remain awake for */ - u32 maccontrol; /* Cached value of maccontrol */ - uint mac_suspend_depth; /* current depth of mac_suspend levels */ - u32 wake_override; /* Various conditions to force MAC to WAKE mode */ - u32 mute_override; /* Prevent ucode from sending beacons */ - u8 etheraddr[ETH_ALEN]; /* currently configured ethernet address */ - u32 led_gpio_mask; /* LED GPIO Mask */ - bool noreset; /* true= do not reset hw, used by WLC_OUT */ - bool forcefastclk; /* true if the h/w is forcing the use of fast clk */ - bool clk; /* core is out of reset and has clock */ - bool sbclk; /* sb has clock */ - struct bmac_pmq *bmac_pmq; /* bmac PM states derived from ucode PMQ */ - bool phyclk; /* phy is out of reset and has clock */ - bool dma_lpbk; /* core is in DMA loopback */ - - bool ucode_loaded; /* true after ucode downloaded */ - - - u8 hw_stf_ss_opmode; /* STF single stream operation mode */ - u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic - * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board - */ - u32 antsel_avail; /* - * put struct antsel_info here if more info is - * needed - */ -}; - -/* TX Queue information - * - * Each flow of traffic out of the device has a TX Queue with independent - * flow control. Several interfaces may be associated with a single TX Queue - * if they belong to the same flow of traffic from the device. For multi-channel - * operation there are independent TX Queues for each channel. - */ -struct wlc_txq_info { - struct wlc_txq_info *next; - struct pktq q; - uint stopped; /* tx flow control bits */ -}; - -/* - * Principal common (os-independent) software data structure. - */ -struct wlc_info { - struct wlc_pub *pub; /* pointer to wlc public state */ - struct osl_info *osh; /* pointer to os handle */ - struct wl_info *wl; /* pointer to os-specific private state */ - d11regs_t *regs; /* pointer to device registers */ - - struct wlc_hw_info *hw; /* HW related state used primarily by BMAC */ - - /* clock */ - int clkreq_override; /* setting for clkreq for PCIE : Auto, 0, 1 */ - u16 fastpwrup_dly; /* time in us needed to bring up d11 fast clock */ - - /* interrupt */ - u32 macintstatus; /* bit channel between isr and dpc */ - u32 macintmask; /* sw runtime master macintmask value */ - u32 defmacintmask; /* default "on" macintmask value */ - - /* up and down */ - bool device_present; /* (removable) device is present */ - - bool clk; /* core is out of reset and has clock */ - - /* multiband */ - struct wlccore *core; /* pointer to active io core */ - struct wlcband *band; /* pointer to active per-band state */ - struct wlccore *corestate; /* per-core state (one per hw core) */ - /* per-band state (one per phy/radio): */ - struct wlcband *bandstate[MAXBANDS]; - - bool war16165; /* PCI slow clock 16165 war flag */ - - bool tx_suspended; /* data fifos need to remain suspended */ - - uint txpend16165war; - - /* packet queue */ - uint qvalid; /* DirFrmQValid and BcMcFrmQValid */ - - /* Regulatory power limits */ - s8 txpwr_local_max; /* regulatory local txpwr max */ - u8 txpwr_local_constraint; /* local power contraint in dB */ - - - struct ampdu_info *ampdu; /* ampdu module handler */ - struct antsel_info *asi; /* antsel module handler */ - wlc_cm_info_t *cmi; /* channel manager module handler */ - - void *btparam; /* bus type specific cookie */ - - uint vars_size; /* size of vars, free vars on detach */ - - u16 vendorid; /* PCI vendor id */ - u16 deviceid; /* PCI device id */ - uint ucode_rev; /* microcode revision */ - - u32 machwcap; /* MAC capabilities, BMAC shadow */ - - u8 perm_etheraddr[ETH_ALEN]; /* original sprom local ethernet address */ - - bool bandlocked; /* disable auto multi-band switching */ - bool bandinit_pending; /* track band init in auto band */ - - bool radio_monitor; /* radio timer is running */ - bool down_override; /* true=down */ - bool going_down; /* down path intermediate variable */ - - bool mpc; /* enable minimum power consumption */ - u8 mpc_dlycnt; /* # of watchdog cnt before turn disable radio */ - u8 mpc_offcnt; /* # of watchdog cnt that radio is disabled */ - u8 mpc_delay_off; /* delay radio disable by # of watchdog cnt */ - u8 prev_non_delay_mpc; /* prev state wlc_is_non_delay_mpc */ - - /* timer */ - struct wl_timer *wdtimer; /* timer for watchdog routine */ - uint fast_timer; /* Periodic timeout for 'fast' timer */ - uint slow_timer; /* Periodic timeout for 'slow' timer */ - uint glacial_timer; /* Periodic timeout for 'glacial' timer */ - uint phycal_mlo; /* last time measurelow calibration was done */ - uint phycal_txpower; /* last time txpower calibration was done */ - - struct wl_timer *radio_timer; /* timer for hw radio button monitor routine */ - struct wl_timer *pspoll_timer; /* periodic pspoll timer */ - - /* promiscuous */ - bool monitor; /* monitor (MPDU sniffing) mode */ - bool bcnmisc_ibss; /* bcns promisc mode override for IBSS */ - bool bcnmisc_scan; /* bcns promisc mode override for scan */ - bool bcnmisc_monitor; /* bcns promisc mode override for monitor */ - - u8 bcn_wait_prd; /* max waiting period (for beacon) in 1024TU */ - - /* driver feature */ - bool _rifs; /* enable per-packet rifs */ - s32 rifs_advert; /* RIFS mode advertisement */ - s8 sgi_tx; /* sgi tx */ - bool wet; /* true if wireless ethernet bridging mode */ - - /* AP-STA synchronization, power save */ - bool check_for_unaligned_tbtt; /* check unaligned tbtt flag */ - bool PM_override; /* no power-save flag, override PM(user input) */ - bool PMenabled; /* current power-management state (CAM or PS) */ - bool PMpending; /* waiting for tx status with PM indicated set */ - bool PMblocked; /* block any PSPolling in PS mode, used to buffer - * AP traffic, also used to indicate in progress - * of scan, rm, etc. off home channel activity. - */ - bool PSpoll; /* whether there is an outstanding PS-Poll frame */ - u8 PM; /* power-management mode (CAM, PS or FASTPS) */ - bool PMawakebcn; /* bcn recvd during current waking state */ - - bool WME_PM_blocked; /* Can STA go to PM when in WME Auto mode */ - bool wake; /* host-specified PS-mode sleep state */ - u8 pspoll_prd; /* pspoll interval in milliseconds */ - u8 bcn_li_bcn; /* beacon listen interval in # beacons */ - u8 bcn_li_dtim; /* beacon listen interval in # dtims */ - - bool WDarmed; /* watchdog timer is armed */ - u32 WDlast; /* last time wlc_watchdog() was called */ - - /* WME */ - ac_bitmap_t wme_dp; /* Discard (oldest first) policy per AC */ - bool wme_apsd; /* enable Advanced Power Save Delivery */ - ac_bitmap_t wme_admctl; /* bit i set if AC i under admission control */ - u16 edcf_txop[AC_COUNT]; /* current txop for each ac */ - wme_param_ie_t wme_param_ie; /* WME parameter info element, which on STA - * contains parameters in use locally, and on - * AP contains parameters advertised to STA - * in beacons and assoc responses. - */ - bool wme_prec_queuing; /* enable/disable non-wme STA prec queuing */ - u16 wme_retries[AC_COUNT]; /* per-AC retry limits */ - - int vlan_mode; /* OK to use 802.1Q Tags (ON, OFF, AUTO) */ - u16 tx_prec_map; /* Precedence map based on HW FIFO space */ - u16 fifo2prec_map[NFIFO]; /* pointer to fifo2_prec map based on WME */ - - /* BSS Configurations */ - wlc_bsscfg_t *bsscfg[WLC_MAXBSSCFG]; /* set of BSS configurations, idx 0 is default and - * always valid - */ - wlc_bsscfg_t *cfg; /* the primary bsscfg (can be AP or STA) */ - u8 stas_associated; /* count of ASSOCIATED STA bsscfgs */ - u8 aps_associated; /* count of UP AP bsscfgs */ - u8 block_datafifo; /* prohibit posting frames to data fifos */ - bool bcmcfifo_drain; /* TX_BCMC_FIFO is set to drain */ - - /* tx queue */ - struct wlc_txq_info *tx_queues; /* common TX Queue list */ - - /* security */ - wsec_key_t *wsec_keys[WSEC_MAX_KEYS]; /* dynamic key storage */ - wsec_key_t *wsec_def_keys[WLC_DEFAULT_KEYS]; /* default key storage */ - bool wsec_swkeys; /* indicates that all keys should be - * treated as sw keys (used for debugging) - */ - struct modulecb *modulecb; - struct dumpcb_s *dumpcb_head; - - u8 mimoft; /* SIGN or 11N */ - u8 mimo_band_bwcap; /* bw cap per band type */ - s8 txburst_limit_override; /* tx burst limit override */ - u16 txburst_limit; /* tx burst limit value */ - s8 cck_40txbw; /* 11N, cck tx b/w override when in 40MHZ mode */ - s8 ofdm_40txbw; /* 11N, ofdm tx b/w override when in 40MHZ mode */ - s8 mimo_40txbw; /* 11N, mimo tx b/w override when in 40MHZ mode */ - /* HT CAP IE being advertised by this node: */ - struct ieee80211_ht_cap ht_cap; - - uint seckeys; /* 54 key table shm address */ - uint tkmickeys; /* 12 TKIP MIC key table shm address */ - - wlc_bss_info_t *default_bss; /* configured BSS parameters */ - - u16 AID; /* association ID */ - u16 counter; /* per-sdu monotonically increasing counter */ - u16 mc_fid_counter; /* BC/MC FIFO frame ID counter */ - - bool ibss_allowed; /* false, all IBSS will be ignored during a scan - * and the driver will not allow the creation of - * an IBSS network - */ - bool ibss_coalesce_allowed; - - char country_default[WLC_CNTRY_BUF_SZ]; /* saved country for leaving 802.11d - * auto-country mode - */ - char autocountry_default[WLC_CNTRY_BUF_SZ]; /* initial country for 802.11d - * auto-country mode - */ -#ifdef BCMDBG - bcm_tlv_t *country_ie_override; /* debug override of announced Country IE */ -#endif - - u16 prb_resp_timeout; /* do not send prb resp if request older than this, - * 0 = disable - */ - - wlc_rateset_t sup_rates_override; /* use only these rates in 11g supported rates if - * specifed - */ - - chanspec_t home_chanspec; /* shared home chanspec */ - - /* PHY parameters */ - chanspec_t chanspec; /* target operational channel */ - u16 usr_fragthresh; /* user configured fragmentation threshold */ - u16 fragthresh[NFIFO]; /* per-fifo fragmentation thresholds */ - u16 RTSThresh; /* 802.11 dot11RTSThreshold */ - u16 SRL; /* 802.11 dot11ShortRetryLimit */ - u16 LRL; /* 802.11 dot11LongRetryLimit */ - u16 SFBL; /* Short Frame Rate Fallback Limit */ - u16 LFBL; /* Long Frame Rate Fallback Limit */ - - /* network config */ - bool shortpreamble; /* currently operating with CCK ShortPreambles */ - bool shortslot; /* currently using 11g ShortSlot timing */ - s8 barker_preamble; /* current Barker Preamble Mode */ - s8 shortslot_override; /* 11g ShortSlot override */ - bool include_legacy_erp; /* include Legacy ERP info elt ID 47 as well as g ID 42 */ - bool barker_overlap_control; /* true: be aware of overlapping BSSs for barker */ - bool ignore_bcns; /* override: ignore non shortslot bcns in a 11g network */ - bool legacy_probe; /* restricts probe requests to CCK rates */ - - struct wlc_protection *protection; - s8 PLCPHdr_override; /* 802.11b Preamble Type override */ - - struct wlc_stf *stf; - - struct pkt_cb *pkt_callback; /* tx completion callback handlers */ - - u32 txretried; /* tx retried number in one msdu */ - - ratespec_t bcn_rspec; /* save bcn ratespec purpose */ - - bool apsd_sta_usp; /* Unscheduled Service Period in progress on STA */ - struct wl_timer *apsd_trigger_timer; /* timer for wme apsd trigger frames */ - u32 apsd_trigger_timeout; /* timeout value for apsd_trigger_timer (in ms) - * 0 == disable - */ - ac_bitmap_t apsd_trigger_ac; /* Permissible Access Category in which APSD Null - * Trigger frames can be send - */ - u8 htphy_membership; /* HT PHY membership */ - - bool _regulatory_domain; /* 802.11d enabled? */ - - u8 mimops_PM; - - u8 txpwr_percent; /* power output percentage */ - - u8 ht_wsec_restriction; /* the restriction of HT with TKIP or WEP */ - - uint tempsense_lasttime; - - u16 tx_duty_cycle_ofdm; /* maximum allowed duty cycle for OFDM */ - u16 tx_duty_cycle_cck; /* maximum allowed duty cycle for CCK */ - - u16 next_bsscfg_ID; - - struct wlc_if *wlcif_list; /* linked list of wlc_if structs */ - struct wlc_txq_info *active_queue; /* txq for the currently active - * transmit context - */ - u32 mpc_dur; /* total time (ms) in mpc mode except for the - * portion since radio is turned off last time - */ - u32 mpc_laston_ts; /* timestamp (ms) when radio is turned off last - * time - */ - bool pr80838_war; - uint hwrxoff; -}; - -/* antsel module specific state */ -struct antsel_info { - struct wlc_info *wlc; /* pointer to main wlc structure */ - struct wlc_pub *pub; /* pointer to public fn */ - u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic - * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board - */ - u8 antsel_antswitch; /* board level antenna switch type */ - bool antsel_avail; /* Ant selection availability (SROM based) */ - wlc_antselcfg_t antcfg_11n; /* antenna configuration */ - wlc_antselcfg_t antcfg_cur; /* current antenna config (auto) */ -}; - -#define CHANNEL_BANDUNIT(wlc, ch) (((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX) -#define OTHERBANDUNIT(wlc) ((uint)((wlc)->band->bandunit ? BAND_2G_INDEX : BAND_5G_INDEX)) - -#define IS_MBAND_UNLOCKED(wlc) \ - ((NBANDS(wlc) > 1) && !(wlc)->bandlocked) - -#define WLC_BAND_PI_RADIO_CHANSPEC wlc_phy_chanspec_get(wlc->band->pi) - -/* sum the individual fifo tx pending packet counts */ -#define TXPKTPENDTOT(wlc) ((wlc)->core->txpktpend[0] + (wlc)->core->txpktpend[1] + \ - (wlc)->core->txpktpend[2] + (wlc)->core->txpktpend[3]) -#define TXPKTPENDGET(wlc, fifo) ((wlc)->core->txpktpend[(fifo)]) -#define TXPKTPENDINC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] += (val)) -#define TXPKTPENDDEC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] -= (val)) -#define TXPKTPENDCLR(wlc, fifo) ((wlc)->core->txpktpend[(fifo)] = 0) -#define TXAVAIL(wlc, fifo) (*(wlc)->core->txavail[(fifo)]) -#define GETNEXTTXP(wlc, _queue) \ - dma_getnexttxp((wlc)->hw->di[(_queue)], HNDDMA_RANGE_TRANSMITTED) - -#define WLC_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \ - ((len1 == len2) && !memcmp(ssid1, ssid2, len1)) - -extern void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus); -extern void wlc_fatal_error(struct wlc_info *wlc); -extern void wlc_bmac_rpc_watchdog(struct wlc_info *wlc); -extern void wlc_recv(struct wlc_info *wlc, struct sk_buff *p); -extern bool wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2); -extern void wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, - bool commit, s8 txpktpend); -extern void wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend); -extern void wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, - uint prec); -extern void wlc_info_init(struct wlc_info *wlc, int unit); -extern void wlc_print_txstatus(tx_status_t *txs); -extern int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks); -extern void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len, - void *buf); -extern void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len, - bool both); -#if defined(BCMDBG) -extern void wlc_get_rcmta(struct wlc_info *wlc, int idx, - u8 *addr); -#endif -extern void wlc_set_rcmta(struct wlc_info *wlc, int idx, - const u8 *addr); -extern void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, - u32 *tsf_h_ptr); -extern void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin); -extern void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax); -extern void wlc_fifoerrors(struct wlc_info *wlc); -extern void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit); -extern void wlc_reset_bmac_done(struct wlc_info *wlc); -extern void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us); -extern void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc); - -#if defined(BCMDBG) -extern void wlc_print_rxh(d11rxhdr_t *rxh); -extern void wlc_print_hdrs(struct wlc_info *wlc, const char *prefix, u8 *frame, - d11txh_t *txh, d11rxhdr_t *rxh, uint len); -extern void wlc_print_txdesc(d11txh_t *txh); -#else -#define wlc_print_txdesc(a) -#endif -#if defined(BCMDBG) -extern void wlc_print_dot11_mac_hdr(u8 *buf, int len); -#endif - -extern void wlc_setxband(struct wlc_hw_info *wlc_hw, uint bandunit); -extern void wlc_coredisable(struct wlc_hw_info *wlc_hw); - -extern bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rate, int band, - bool verbose); -extern void wlc_ap_upd(struct wlc_info *wlc); - -/* helper functions */ -extern void wlc_shm_ssid_upd(struct wlc_info *wlc, wlc_bsscfg_t *cfg); -extern int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config); - -extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc); -extern void wlc_mac_bcn_promisc(struct wlc_info *wlc); -extern void wlc_mac_promisc(struct wlc_info *wlc); -extern void wlc_txflowcontrol(struct wlc_info *wlc, struct wlc_txq_info *qi, - bool on, int prio); -extern void wlc_txflowcontrol_override(struct wlc_info *wlc, - struct wlc_txq_info *qi, - bool on, uint override); -extern bool wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, - struct wlc_txq_info *qi, int prio); -extern void wlc_send_q(struct wlc_info *wlc, struct wlc_txq_info *qi); -extern int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifo); - -extern u16 wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, - uint mac_len); -extern ratespec_t wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, - bool use_rspec, u16 mimo_ctlchbw); -extern u16 wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, - ratespec_t rts_rate, ratespec_t frame_rate, - u8 rts_preamble_type, - u8 frame_preamble_type, uint frame_len, - bool ba); - -extern void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs); - -#if defined(BCMDBG) -extern void wlc_dump_ie(struct wlc_info *wlc, bcm_tlv_t *ie, - struct bcmstrbuf *b); -#endif - -extern bool wlc_ps_check(struct wlc_info *wlc); -extern void wlc_reprate_init(struct wlc_info *wlc); -extern void wlc_bsscfg_reprate_init(wlc_bsscfg_t *bsscfg); -extern void wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, - u32 b_low); -extern u32 wlc_calc_tbtt_offset(u32 bi, u32 tsf_h, u32 tsf_l); - -/* Shared memory access */ -extern void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v); -extern u16 wlc_read_shm(struct wlc_info *wlc, uint offset); -extern void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len); -extern void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, - int len); -extern void wlc_copyfrom_shm(struct wlc_info *wlc, uint offset, void *buf, - int len); - -extern void wlc_update_beacon(struct wlc_info *wlc); -extern void wlc_bss_update_beacon(struct wlc_info *wlc, - struct wlc_bsscfg *bsscfg); - -extern void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend); -extern void wlc_bss_update_probe_resp(struct wlc_info *wlc, wlc_bsscfg_t *cfg, - bool suspend); - -extern bool wlc_ismpc(struct wlc_info *wlc); -extern bool wlc_is_non_delay_mpc(struct wlc_info *wlc); -extern void wlc_radio_mpc_upd(struct wlc_info *wlc); -extern bool wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, - int prec); -extern bool wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, - struct sk_buff *pkt, int prec, bool head); -extern u16 wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec); -extern void wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rate, uint length, - u8 *plcp); -extern uint wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, - u8 preamble_type, uint mac_len); - -extern void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec); - -extern bool wlc_timers_init(struct wlc_info *wlc, int unit); - -extern const bcm_iovar_t wlc_iovars[]; - -extern int wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, - const char *name, void *params, uint p_len, void *arg, - int len, int val_size, struct wlc_if *wlcif); - -#if defined(BCMDBG) -extern void wlc_print_ies(struct wlc_info *wlc, u8 *ies, uint ies_len); -#endif - -extern int wlc_set_nmode(struct wlc_info *wlc, s32 nmode); -extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode); -extern void wlc_mimops_action_ht_send(struct wlc_info *wlc, - wlc_bsscfg_t *bsscfg, u8 mimops_mode); - -extern void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot); -extern void wlc_set_bssid(wlc_bsscfg_t *cfg); -extern void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend); - -extern void wlc_set_ratetable(struct wlc_info *wlc); -extern int wlc_set_mac(wlc_bsscfg_t *cfg); -extern void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, - ratespec_t bcn_rate); -extern void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len); -extern ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, - wlc_rateset_t *rs); -extern u16 wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec, - bool short_preamble, bool phydelay); -extern void wlc_radio_disable(struct wlc_info *wlc); -extern void wlc_bcn_li_upd(struct wlc_info *wlc); - -extern int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len); -extern void wlc_out(struct wlc_info *wlc); -extern void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec); -extern void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt); -extern bool wlc_ps_allowed(struct wlc_info *wlc); -extern bool wlc_stay_awake(struct wlc_info *wlc); -extern void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe); - -extern void wlc_bss_list_free(struct wlc_info *wlc, - struct wlc_bss_list *bss_list); -extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode); -#endif /* _wlc_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c new file mode 100644 index 000000000000..87391bad4fea --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c @@ -0,0 +1,8509 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "d11.h" +#include "wlc_types.h" +#include "wlc_cfg.h" +#include "wlc_rate.h" +#include "wlc_scb.h" +#include "wlc_pub.h" +#include "wlc_key.h" +#include "wlc_bsscfg.h" +#include "phy/wlc_phy_hal.h" +#include "wlc_channel.h" +#include "wlc_main.h" +#include "wlc_bmac.h" +#include "wlc_phy_hal.h" +#include "wlc_phy_shim.h" +#include "wlc_antsel.h" +#include "wlc_stf.h" +#include "wlc_ampdu.h" +#include "wl_export.h" +#include "wlc_alloc.h" +#include "wl_dbg.h" + +/* + * Disable statistics counting for WME + */ +#define WLCNTSET(a, b) +#define WLCNTINCR(a) +#define WLCNTADD(a, b) + +/* + * WPA(2) definitions + */ +#define RSN_CAP_4_REPLAY_CNTRS 2 +#define RSN_CAP_16_REPLAY_CNTRS 3 + +#define WPA_CAP_4_REPLAY_CNTRS RSN_CAP_4_REPLAY_CNTRS +#define WPA_CAP_16_REPLAY_CNTRS RSN_CAP_16_REPLAY_CNTRS + +/* + * Indication for txflowcontrol that all priority bits in + * TXQ_STOP_FOR_PRIOFC_MASK are to be considered. + */ +#define ALLPRIO -1 + +/* + * buffer length needed for wlc_format_ssid + * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. + */ +#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) + +#define TIMER_INTERVAL_WATCHDOG 1000 /* watchdog timer, in unit of ms */ +#define TIMER_INTERVAL_RADIOCHK 800 /* radio monitor timer, in unit of ms */ + +#ifndef WLC_MPC_MAX_DELAYCNT +#define WLC_MPC_MAX_DELAYCNT 10 /* Max MPC timeout, in unit of watchdog */ +#endif +#define WLC_MPC_MIN_DELAYCNT 1 /* Min MPC timeout, in unit of watchdog */ +#define WLC_MPC_THRESHOLD 3 /* MPC count threshold level */ + +#define BEACON_INTERVAL_DEFAULT 100 /* beacon interval, in unit of 1024TU */ +#define DTIM_INTERVAL_DEFAULT 3 /* DTIM interval, in unit of beacon interval */ + +/* Scale down delays to accommodate QT slow speed */ +#define BEACON_INTERVAL_DEF_QT 20 /* beacon interval, in unit of 1024TU */ +#define DTIM_INTERVAL_DEF_QT 1 /* DTIM interval, in unit of beacon interval */ + +#define TBTT_ALIGN_LEEWAY_US 100 /* min leeway before first TBTT in us */ + +/* + * driver maintains internal 'tick'(wlc->pub->now) which increments in 1s OS timer(soft + * watchdog) it is not a wall clock and won't increment when driver is in "down" state + * this low resolution driver tick can be used for maintenance tasks such as phy + * calibration and scb update + */ + +/* watchdog trigger mode: OSL timer or TBTT */ +#define WLC_WATCHDOG_TBTT(wlc) \ + (wlc->stas_associated > 0 && wlc->PM != PM_OFF && wlc->pub->align_wd_tbtt) + +/* To inform the ucode of the last mcast frame posted so that it can clear moredata bit */ +#define BCMCFID(wlc, fid) wlc_bmac_write_shm((wlc)->hw, M_BCMC_FID, (fid)) + +#define WLC_WAR16165(wlc) (wlc->pub->sih->bustype == PCI_BUS && \ + (!AP_ENAB(wlc->pub)) && (wlc->war16165)) + +/* debug/trace */ +uint wl_msg_level = +#if defined(BCMDBG) + WL_ERROR_VAL; +#else + 0; +#endif /* BCMDBG */ + +/* Find basic rate for a given rate */ +#define WLC_BASIC_RATE(wlc, rspec) (IS_MCS(rspec) ? \ + (wlc)->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK].leg_ofdm] : \ + (wlc)->band->basic_rate[rspec & RSPEC_RATE_MASK]) + +#define FRAMETYPE(r, mimoframe) (IS_MCS(r) ? mimoframe : (IS_CCK(r) ? FT_CCK : FT_OFDM)) + +#define RFDISABLE_DEFAULT 10000000 /* rfdisable delay timer 500 ms, runs of ALP clock */ + +#define WLC_TEMPSENSE_PERIOD 10 /* 10 second timeout */ + +#define SCAN_IN_PROGRESS(x) 0 + +#define EPI_VERSION_NUM 0x054b0b00 + +#ifdef BCMDBG +/* pointer to most recently allocated wl/wlc */ +static struct wlc_info *wlc_info_dbg = (struct wlc_info *) (NULL); +#endif + +/* IOVar table */ + +/* Parameter IDs, for use only internally to wlc -- in the wlc_iovars + * table and by the wlc_doiovar() function. No ordering is imposed: + * the table is keyed by name, and the function uses a switch. + */ +enum { + IOV_MPC = 1, + IOV_RTSTHRESH, + IOV_QTXPOWER, + IOV_BCN_LI_BCN, /* Beacon listen interval in # of beacons */ + IOV_LAST /* In case of a need to check max ID number */ +}; + +const bcm_iovar_t wlc_iovars[] = { + {"mpc", IOV_MPC, (0), IOVT_BOOL, 0}, + {"rtsthresh", IOV_RTSTHRESH, (IOVF_WHL), IOVT_UINT16, 0}, + {"qtxpower", IOV_QTXPOWER, (IOVF_WHL), IOVT_UINT32, 0}, + {"bcn_li_bcn", IOV_BCN_LI_BCN, (0), IOVT_UINT8, 0}, + {NULL, 0, 0, 0, 0} +}; + +const u8 prio2fifo[NUMPRIO] = { + TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */ + TX_AC_BK_FIFO, /* 1 BK AC_BK Background */ + TX_AC_BK_FIFO, /* 2 -- AC_BK Background */ + TX_AC_BE_FIFO, /* 3 EE AC_BE Best Effort */ + TX_AC_VI_FIFO, /* 4 CL AC_VI Video */ + TX_AC_VI_FIFO, /* 5 VI AC_VI Video */ + TX_AC_VO_FIFO, /* 6 VO AC_VO Voice */ + TX_AC_VO_FIFO /* 7 NC AC_VO Voice */ +}; + +/* precedences numbers for wlc queues. These are twice as may levels as + * 802.1D priorities. + * Odd numbers are used for HI priority traffic at same precedence levels + * These constants are used ONLY by wlc_prio2prec_map. Do not use them elsewhere. + */ +#define _WLC_PREC_NONE 0 /* None = - */ +#define _WLC_PREC_BK 2 /* BK - Background */ +#define _WLC_PREC_BE 4 /* BE - Best-effort */ +#define _WLC_PREC_EE 6 /* EE - Excellent-effort */ +#define _WLC_PREC_CL 8 /* CL - Controlled Load */ +#define _WLC_PREC_VI 10 /* Vi - Video */ +#define _WLC_PREC_VO 12 /* Vo - Voice */ +#define _WLC_PREC_NC 14 /* NC - Network Control */ + +/* 802.1D Priority to precedence queue mapping */ +const u8 wlc_prio2prec_map[] = { + _WLC_PREC_BE, /* 0 BE - Best-effort */ + _WLC_PREC_BK, /* 1 BK - Background */ + _WLC_PREC_NONE, /* 2 None = - */ + _WLC_PREC_EE, /* 3 EE - Excellent-effort */ + _WLC_PREC_CL, /* 4 CL - Controlled Load */ + _WLC_PREC_VI, /* 5 Vi - Video */ + _WLC_PREC_VO, /* 6 Vo - Voice */ + _WLC_PREC_NC, /* 7 NC - Network Control */ +}; + +/* Sanity check for tx_prec_map and fifo synchup + * Either there are some packets pending for the fifo, else if fifo is empty then + * all the corresponding precmap bits should be set + */ +#define WLC_TX_FIFO_CHECK(wlc, fifo) (TXPKTPENDGET((wlc), (fifo)) || \ + (TXPKTPENDGET((wlc), (fifo)) == 0 && \ + ((wlc)->tx_prec_map & (wlc)->fifo2prec_map[(fifo)]) == \ + (wlc)->fifo2prec_map[(fifo)])) + +/* TX FIFO number to WME/802.1E Access Category */ +const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE }; + +/* WME/802.1E Access Category to TX FIFO number */ +static const u8 wme_ac2fifo[] = { 1, 0, 2, 3 }; + +static bool in_send_q = false; + +/* Shared memory location index for various AC params */ +#define wme_shmemacindex(ac) wme_ac2fifo[ac] + +#ifdef BCMDBG +static const char *fifo_names[] = { + "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; +#else +static const char fifo_names[6][0]; +#endif + +static const u8 acbitmap2maxprio[] = { + PRIO_8021D_BE, PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_BK, + PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, + PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, + PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO +}; + +/* currently the best mechanism for determining SIFS is the band in use */ +#define SIFS(band) ((band)->bandtype == WLC_BAND_5G ? APHY_SIFS_TIME : BPHY_SIFS_TIME); + +/* value for # replay counters currently supported */ +#define WLC_REPLAY_CNTRS_VALUE WPA_CAP_16_REPLAY_CNTRS + +/* local prototypes */ +static u16 BCMFASTPATH wlc_d11hdrs_mac80211(struct wlc_info *wlc, + struct ieee80211_hw *hw, + struct sk_buff *p, + struct scb *scb, uint frag, + uint nfrags, uint queue, + uint next_frag_len, + wsec_key_t *key, + ratespec_t rspec_override); + +static void wlc_ctrupd_cache(u16 cur_stat, u16 *macstat_snapshot, u32 *macstat); +static void wlc_bss_default_init(struct wlc_info *wlc); +static void wlc_ucode_mac_upd(struct wlc_info *wlc); +static ratespec_t mac80211_wlc_set_nrate(struct wlc_info *wlc, + struct wlcband *cur_band, u32 int_val); +static void wlc_tx_prec_map_init(struct wlc_info *wlc); +static void wlc_watchdog(void *arg); +static void wlc_watchdog_by_timer(void *arg); +static u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate); +static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg); +static int wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, + const bcm_iovar_t *vi); +static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc); + +/* send and receive */ +static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc, + struct osl_info *osh); +static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh, + struct wlc_txq_info *qi); +static void wlc_txflowcontrol_signal(struct wlc_info *wlc, + struct wlc_txq_info *qi, + bool on, int prio); +static void wlc_txflowcontrol_reset(struct wlc_info *wlc); +static u16 wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, + uint length); +static void wlc_compute_cck_plcp(ratespec_t rate, uint length, u8 *plcp); +static void wlc_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp); +static void wlc_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp); +static u16 wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, + u8 preamble_type, uint next_frag_len); +static void wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, + d11rxhdr_t *rxh, struct sk_buff *p); +static uint wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t rate, + u8 preamble_type, uint dur); +static uint wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rate, + u8 preamble_type); +static uint wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rate, + u8 preamble_type); +/* interrupt, up/down, band */ +static void wlc_setband(struct wlc_info *wlc, uint bandunit); +static chanspec_t wlc_init_chanspec(struct wlc_info *wlc); +static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec); +static void wlc_bsinit(struct wlc_info *wlc); +static int wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, + bool writeToShm); +static void wlc_radio_hwdisable_upd(struct wlc_info *wlc); +static bool wlc_radio_monitor_start(struct wlc_info *wlc); +static void wlc_radio_timer(void *arg); +static void wlc_radio_enable(struct wlc_info *wlc); +static void wlc_radio_upd(struct wlc_info *wlc); + +/* scan, association, BSS */ +static uint wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rate, + u8 preamble_type); +static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap); +static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val); +static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val); +static void wlc_war16165(struct wlc_info *wlc, bool tx); + +static void wlc_wme_retries_write(struct wlc_info *wlc); +static bool wlc_attach_stf_ant_init(struct wlc_info *wlc); +static uint wlc_attach_module(struct wlc_info *wlc); +static void wlc_detach_module(struct wlc_info *wlc); +static void wlc_timers_deinit(struct wlc_info *wlc); +static void wlc_down_led_upd(struct wlc_info *wlc); +static uint wlc_down_del_timer(struct wlc_info *wlc); +static void wlc_ofdm_rateset_war(struct wlc_info *wlc); +static int _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, + struct wlc_if *wlcif); + +#if defined(BCMDBG) +void wlc_get_rcmta(struct wlc_info *wlc, int idx, u8 *addr) +{ + d11regs_t *regs = wlc->regs; + u32 v32; + struct osl_info *osh; + + WL_TRACE("wl%d: %s\n", WLCWLUNIT(wlc), __func__); + + osh = wlc->osh; + + W_REG(®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); + (void)R_REG(®s->objaddr); + v32 = R_REG(®s->objdata); + addr[0] = (u8) v32; + addr[1] = (u8) (v32 >> 8); + addr[2] = (u8) (v32 >> 16); + addr[3] = (u8) (v32 >> 24); + W_REG(®s->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1))); + (void)R_REG(®s->objaddr); + v32 = R_REG(®s->objdata); + addr[4] = (u8) v32; + addr[5] = (u8) (v32 >> 8); +} +#endif /* defined(BCMDBG) */ + +/* keep the chip awake if needed */ +bool wlc_stay_awake(struct wlc_info *wlc) +{ + return true; +} + +/* conditions under which the PM bit should be set in outgoing frames and STAY_AWAKE is meaningful + */ +bool wlc_ps_allowed(struct wlc_info *wlc) +{ + int idx; + wlc_bsscfg_t *cfg; + + /* disallow PS when one of the following global conditions meets */ + if (!wlc->pub->associated || !wlc->PMenabled || wlc->PM_override) + return false; + + /* disallow PS when one of these meets when not scanning */ + if (!wlc->PMblocked) { + if (AP_ACTIVE(wlc) || wlc->monitor) + return false; + } + + FOREACH_AS_STA(wlc, idx, cfg) { + /* disallow PS when one of the following bsscfg specific conditions meets */ + if (!cfg->BSS || !WLC_PORTOPEN(cfg)) + return false; + + if (!cfg->dtim_programmed) + return false; + } + + return true; +} + +void wlc_reset(struct wlc_info *wlc) +{ + WL_TRACE("wl%d: wlc_reset\n", wlc->pub->unit); + + wlc->check_for_unaligned_tbtt = false; + + /* slurp up hw mac counters before core reset */ + wlc_statsupd(wlc); + + /* reset our snapshot of macstat counters */ + memset((char *)wlc->core->macstat_snapshot, 0, + sizeof(macstat_t)); + + wlc_bmac_reset(wlc->hw); + wlc_ampdu_reset(wlc->ampdu); + wlc->txretried = 0; + +} + +void wlc_fatal_error(struct wlc_info *wlc) +{ + WL_ERROR("wl%d: fatal error, reinitializing\n", wlc->pub->unit); + wl_init(wlc->wl); +} + +/* Return the channel the driver should initialize during wlc_init. + * the channel may have to be changed from the currently configured channel + * if other configurations are in conflict (bandlocked, 11n mode disabled, + * invalid channel for current country, etc.) + */ +static chanspec_t wlc_init_chanspec(struct wlc_info *wlc) +{ + chanspec_t chanspec = + 1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE | + WL_CHANSPEC_BAND_2G; + + /* make sure the channel is on the supported band if we are band-restricted */ + if (wlc->bandlocked || NBANDS(wlc) == 1) { + ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit); + } + ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec)); + return chanspec; +} + +struct scb global_scb; + +static void wlc_init_scb(struct wlc_info *wlc, struct scb *scb) +{ + int i; + scb->flags = SCB_WMECAP | SCB_HTCAP; + for (i = 0; i < NUMPRIO; i++) + scb->seqnum[i] = 0; +} + +void wlc_init(struct wlc_info *wlc) +{ + d11regs_t *regs; + chanspec_t chanspec; + int i; + wlc_bsscfg_t *bsscfg; + bool mute = false; + + WL_TRACE("wl%d: wlc_init\n", wlc->pub->unit); + + regs = wlc->regs; + + /* This will happen if a big-hammer was executed. In that case, we want to go back + * to the channel that we were on and not new channel + */ + if (wlc->pub->associated) + chanspec = wlc->home_chanspec; + else + chanspec = wlc_init_chanspec(wlc); + + wlc_bmac_init(wlc->hw, chanspec, mute); + + wlc->seckeys = wlc_bmac_read_shm(wlc->hw, M_SECRXKEYS_PTR) * 2; + if (wlc->machwcap & MCAP_TKIPMIC) + wlc->tkmickeys = + wlc_bmac_read_shm(wlc->hw, M_TKMICKEYS_PTR) * 2; + + /* update beacon listen interval */ + wlc_bcn_li_upd(wlc); + wlc->bcn_wait_prd = + (u8) (wlc_bmac_read_shm(wlc->hw, M_NOSLPZNATDTIM) >> 10); + ASSERT(wlc->bcn_wait_prd > 0); + + /* the world is new again, so is our reported rate */ + wlc_reprate_init(wlc); + + /* write ethernet address to core */ + FOREACH_BSS(wlc, i, bsscfg) { + wlc_set_mac(bsscfg); + wlc_set_bssid(bsscfg); + } + + /* Update tsf_cfprep if associated and up */ + if (wlc->pub->associated) { + FOREACH_BSS(wlc, i, bsscfg) { + if (bsscfg->up) { + u32 bi; + + /* get beacon period and convert to uS */ + bi = bsscfg->current_bss->beacon_period << 10; + /* + * update since init path would reset + * to default value + */ + W_REG(®s->tsf_cfprep, + (bi << CFPREP_CBI_SHIFT)); + + /* Update maccontrol PM related bits */ + wlc_set_ps_ctrl(wlc); + + break; + } + } + } + + wlc_key_hw_init_all(wlc); + + wlc_bandinit_ordered(wlc, chanspec); + + wlc_init_scb(wlc, &global_scb); + + /* init probe response timeout */ + wlc_write_shm(wlc, M_PRS_MAXTIME, wlc->prb_resp_timeout); + + /* init max burst txop (framebursting) */ + wlc_write_shm(wlc, M_MBURST_TXOP, + (wlc-> + _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP)); + + /* initialize maximum allowed duty cycle */ + wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true); + wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true); + + /* Update some shared memory locations related to max AMPDU size allowed to received */ + wlc_ampdu_shm_upd(wlc->ampdu); + + /* band-specific inits */ + wlc_bsinit(wlc); + + /* Enable EDCF mode (while the MAC is suspended) */ + if (EDCF_ENAB(wlc->pub)) { + OR_REG(®s->ifs_ctl, IFS_USEEDCF); + wlc_edcf_setparams(wlc->cfg, false); + } + + /* Init precedence maps for empty FIFOs */ + wlc_tx_prec_map_init(wlc); + + /* read the ucode version if we have not yet done so */ + if (wlc->ucode_rev == 0) { + wlc->ucode_rev = + wlc_read_shm(wlc, M_BOM_REV_MAJOR) << NBITS(u16); + wlc->ucode_rev |= wlc_read_shm(wlc, M_BOM_REV_MINOR); + } + + /* ..now really unleash hell (allow the MAC out of suspend) */ + wlc_enable_mac(wlc); + + /* clear tx flow control */ + wlc_txflowcontrol_reset(wlc); + + /* clear tx data fifo suspends */ + wlc->tx_suspended = false; + + /* enable the RF Disable Delay timer */ + W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT); + + /* initialize mpc delay */ + wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; + + /* + * Initialize WME parameters; if they haven't been set by some other + * mechanism (IOVar, etc) then read them from the hardware. + */ + if (WLC_WME_RETRY_SHORT_GET(wlc, 0) == 0) { /* Uninitialized; read from HW */ + int ac; + + ASSERT(wlc->clk); + for (ac = 0; ac < AC_COUNT; ac++) { + wlc->wme_retries[ac] = + wlc_read_shm(wlc, M_AC_TXLMT_ADDR(ac)); + } + } +} + +void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc) +{ + wlc->bcnmisc_monitor = promisc; + wlc_mac_bcn_promisc(wlc); +} + +void wlc_mac_bcn_promisc(struct wlc_info *wlc) +{ + if ((AP_ENAB(wlc->pub) && (N_ENAB(wlc->pub) || wlc->band->gmode)) || + wlc->bcnmisc_ibss || wlc->bcnmisc_scan || wlc->bcnmisc_monitor) + wlc_mctrl(wlc, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC); + else + wlc_mctrl(wlc, MCTL_BCNS_PROMISC, 0); +} + +/* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */ +void wlc_mac_promisc(struct wlc_info *wlc) +{ + u32 promisc_bits = 0; + + /* promiscuous mode just sets MCTL_PROMISC + * Note: APs get all BSS traffic without the need to set the MCTL_PROMISC bit + * since all BSS data traffic is directed at the AP + */ + if (PROMISC_ENAB(wlc->pub) && !AP_ENAB(wlc->pub) && !wlc->wet) + promisc_bits |= MCTL_PROMISC; + + /* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL + * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is + * handled in wlc_mac_bcn_promisc() + */ + if (MONITOR_ENAB(wlc)) + promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL; + + wlc_mctrl(wlc, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits); +} + +/* check if hps and wake states of sw and hw are in sync */ +bool wlc_ps_check(struct wlc_info *wlc) +{ + bool res = true; + bool hps, wake; + bool wake_ok; + + if (!AP_ACTIVE(wlc)) { + u32 tmp; + tmp = R_REG(&wlc->regs->maccontrol); + + /* + * If deviceremoved is detected, then don't take any action as + * this can be called in any context. Assume that caller will + * take care of the condition. This is just to avoid assert + */ + if (tmp == 0xffffffff) { + WL_ERROR("wl%d: %s: dead chip\n", + wlc->pub->unit, __func__); + return DEVICEREMOVED(wlc); + } + + hps = PS_ALLOWED(wlc); + + if (hps != ((tmp & MCTL_HPS) != 0)) { + int idx; + wlc_bsscfg_t *cfg; + WL_ERROR("wl%d: hps not sync, sw %d, maccontrol 0x%x\n", + wlc->pub->unit, hps, tmp); + FOREACH_BSS(wlc, idx, cfg) { + if (!BSSCFG_STA(cfg)) + continue; + } + + res = false; + } + /* For a monolithic build the wake check can be exact since it looks at wake + * override bits. The MCTL_WAKE bit should match the 'wake' value. + */ + wake = STAY_AWAKE(wlc) || wlc->hw->wake_override; + wake_ok = (wake == ((tmp & MCTL_WAKE) != 0)); + if (hps && !wake_ok) { + WL_ERROR("wl%d: wake not sync, sw %d maccontrol 0x%x\n", + wlc->pub->unit, wake, tmp); + res = false; + } + } + ASSERT(res); + return res; +} + +/* push sw hps and wake state through hardware */ +void wlc_set_ps_ctrl(struct wlc_info *wlc) +{ + u32 v1, v2; + bool hps, wake; + bool awake_before; + + hps = PS_ALLOWED(wlc); + wake = hps ? (STAY_AWAKE(wlc)) : true; + + WL_TRACE("wl%d: wlc_set_ps_ctrl: hps %d wake %d\n", + wlc->pub->unit, hps, wake); + + v1 = R_REG(&wlc->regs->maccontrol); + v2 = 0; + if (hps) + v2 |= MCTL_HPS; + if (wake) + v2 |= MCTL_WAKE; + + wlc_mctrl(wlc, MCTL_WAKE | MCTL_HPS, v2); + + awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0)); + + if (wake && !awake_before) + wlc_bmac_wait_for_wake(wlc->hw); + +} + +/* + * Write this BSS config's MAC address to core. + * Updates RXE match engine. + */ +int wlc_set_mac(wlc_bsscfg_t *cfg) +{ + int err = 0; + struct wlc_info *wlc = cfg->wlc; + + if (cfg == wlc->cfg) { + /* enter the MAC addr into the RXE match registers */ + wlc_set_addrmatch(wlc, RCM_MAC_OFFSET, cfg->cur_etheraddr); + } + + wlc_ampdu_macaddr_upd(wlc); + + return err; +} + +/* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl). + * Updates RXE match engine. + */ +void wlc_set_bssid(wlc_bsscfg_t *cfg) +{ + struct wlc_info *wlc = cfg->wlc; + + /* if primary config, we need to update BSSID in RXE match registers */ + if (cfg == wlc->cfg) { + wlc_set_addrmatch(wlc, RCM_BSSID_OFFSET, cfg->BSSID); + } +#ifdef SUPPORT_HWKEYS + else if (BSSCFG_STA(cfg) && cfg->BSS) { + wlc_rcmta_add_bssid(wlc, cfg); + } +#endif +} + +/* + * Suspend the the MAC and update the slot timing + * for standard 11b/g (20us slots) or shortslot 11g (9us slots). + */ +void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot) +{ + int idx; + wlc_bsscfg_t *cfg; + + ASSERT(wlc->band->gmode); + + /* use the override if it is set */ + if (wlc->shortslot_override != WLC_SHORTSLOT_AUTO) + shortslot = (wlc->shortslot_override == WLC_SHORTSLOT_ON); + + if (wlc->shortslot == shortslot) + return; + + wlc->shortslot = shortslot; + + /* update the capability based on current shortslot mode */ + FOREACH_BSS(wlc, idx, cfg) { + if (!cfg->associated) + continue; + cfg->current_bss->capability &= + ~WLAN_CAPABILITY_SHORT_SLOT_TIME; + if (wlc->shortslot) + cfg->current_bss->capability |= + WLAN_CAPABILITY_SHORT_SLOT_TIME; + } + + wlc_bmac_set_shortslot(wlc->hw, shortslot); +} + +static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc) +{ + u8 local; + s16 local_max; + + local = WLC_TXPWR_MAX; + if (wlc->pub->associated && + (wf_chspec_ctlchan(wlc->chanspec) == + wf_chspec_ctlchan(wlc->home_chanspec))) { + + /* get the local power constraint if we are on the AP's + * channel [802.11h, 7.3.2.13] + */ + /* Clamp the value between 0 and WLC_TXPWR_MAX w/o overflowing the target */ + local_max = + (wlc->txpwr_local_max - + wlc->txpwr_local_constraint) * WLC_TXPWR_DB_FACTOR; + if (local_max > 0 && local_max < WLC_TXPWR_MAX) + return (u8) local_max; + if (local_max < 0) + return 0; + } + + return local; +} + +/* propagate home chanspec to all bsscfgs in case bsscfg->current_bss->chanspec is referenced */ +void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec) +{ + if (wlc->home_chanspec != chanspec) { + int idx; + wlc_bsscfg_t *cfg; + + wlc->home_chanspec = chanspec; + + FOREACH_BSS(wlc, idx, cfg) { + if (!cfg->associated) + continue; + + cfg->current_bss->chanspec = chanspec; + } + + } +} + +static void wlc_set_phy_chanspec(struct wlc_info *wlc, chanspec_t chanspec) +{ + /* Save our copy of the chanspec */ + wlc->chanspec = chanspec; + + /* Set the chanspec and power limits for this locale after computing + * any 11h local tx power constraints. + */ + wlc_channel_set_chanspec(wlc->cmi, chanspec, + wlc_local_constraint_qdbm(wlc)); + + if (wlc->stf->ss_algosel_auto) + wlc_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel, + chanspec); + + wlc_stf_ss_update(wlc, wlc->band); + +} + +void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec) +{ + uint bandunit; + bool switchband = false; + chanspec_t old_chanspec = wlc->chanspec; + + if (!wlc_valid_chanspec_db(wlc->cmi, chanspec)) { + WL_ERROR("wl%d: %s: Bad channel %d\n", + wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); + ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec)); + return; + } + + /* Switch bands if necessary */ + if (NBANDS(wlc) > 1) { + bandunit = CHSPEC_WLCBANDUNIT(chanspec); + if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) { + switchband = true; + if (wlc->bandlocked) { + WL_ERROR("wl%d: %s: chspec %d band is locked!\n", + wlc->pub->unit, __func__, + CHSPEC_CHANNEL(chanspec)); + return; + } + /* BMAC_NOTE: should the setband call come after the wlc_bmac_chanspec() ? + * if the setband updates (wlc_bsinit) use low level calls to inspect and + * set state, the state inspected may be from the wrong band, or the + * following wlc_bmac_set_chanspec() may undo the work. + */ + wlc_setband(wlc, bandunit); + } + } + + ASSERT(N_ENAB(wlc->pub) || !CHSPEC_IS40(chanspec)); + + /* sync up phy/radio chanspec */ + wlc_set_phy_chanspec(wlc, chanspec); + + /* init antenna selection */ + if (CHSPEC_WLC_BW(old_chanspec) != CHSPEC_WLC_BW(chanspec)) { + wlc_antsel_init(wlc->asi); + + /* Fix the hardware rateset based on bw. + * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz + */ + wlc_rateset_bw_mcs_filter(&wlc->band->hw_rateset, + wlc->band-> + mimo_cap_40 ? CHSPEC_WLC_BW(chanspec) + : 0); + } + + /* update some mac configuration since chanspec changed */ + wlc_ucode_mac_upd(wlc); +} + +#if defined(BCMDBG) +static int wlc_get_current_txpwr(struct wlc_info *wlc, void *pwr, uint len) +{ + txpwr_limits_t txpwr; + tx_power_t power; + tx_power_legacy_t *old_power = NULL; + int r, c; + uint qdbm; + bool override; + + if (len == sizeof(tx_power_legacy_t)) + old_power = (tx_power_legacy_t *) pwr; + else if (len < sizeof(tx_power_t)) + return BCME_BUFTOOSHORT; + + memset(&power, 0, sizeof(tx_power_t)); + + power.chanspec = WLC_BAND_PI_RADIO_CHANSPEC; + if (wlc->pub->associated) + power.local_chanspec = wlc->home_chanspec; + + /* Return the user target tx power limits for the various rates. Note wlc_phy.c's + * public interface only implements getting and setting a single value for all of + * rates, so we need to fill the array ourselves. + */ + wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override); + for (r = 0; r < WL_TX_POWER_RATES; r++) { + power.user_limit[r] = (u8) qdbm; + } + + power.local_max = wlc->txpwr_local_max * WLC_TXPWR_DB_FACTOR; + power.local_constraint = + wlc->txpwr_local_constraint * WLC_TXPWR_DB_FACTOR; + + power.antgain[0] = wlc->bandstate[BAND_2G_INDEX]->antgain; + power.antgain[1] = wlc->bandstate[BAND_5G_INDEX]->antgain; + + wlc_channel_reg_limits(wlc->cmi, power.chanspec, &txpwr); + +#if WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK +#error "WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK" +#endif + + /* CCK tx power limits */ + for (c = 0, r = WL_TX_POWER_CCK_FIRST; c < WL_TX_POWER_CCK_NUM; + c++, r++) + power.reg_limit[r] = txpwr.cck[c]; + +#if WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM +#error "WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM" +#endif + + /* 20 MHz OFDM SISO tx power limits */ + for (c = 0, r = WL_TX_POWER_OFDM_FIRST; c < WL_TX_POWER_OFDM_NUM; + c++, r++) + power.reg_limit[r] = txpwr.ofdm[c]; + + if (WLC_PHY_11N_CAP(wlc->band)) { + + /* 20 MHz OFDM CDD tx power limits */ + for (c = 0, r = WL_TX_POWER_OFDM20_CDD_FIRST; + c < WL_TX_POWER_OFDM_NUM; c++, r++) + power.reg_limit[r] = txpwr.ofdm_cdd[c]; + + /* 40 MHz OFDM SISO tx power limits */ + for (c = 0, r = WL_TX_POWER_OFDM40_SISO_FIRST; + c < WL_TX_POWER_OFDM_NUM; c++, r++) + power.reg_limit[r] = txpwr.ofdm_40_siso[c]; + + /* 40 MHz OFDM CDD tx power limits */ + for (c = 0, r = WL_TX_POWER_OFDM40_CDD_FIRST; + c < WL_TX_POWER_OFDM_NUM; c++, r++) + power.reg_limit[r] = txpwr.ofdm_40_cdd[c]; + +#if WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM +#error "WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM" +#endif + + /* 20MHz MCS0-7 SISO tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS20_SISO_FIRST; + c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_20_siso[c]; + + /* 20MHz MCS0-7 CDD tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS20_CDD_FIRST; + c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_20_cdd[c]; + + /* 20MHz MCS0-7 STBC tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS20_STBC_FIRST; + c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_20_stbc[c]; + + /* 40MHz MCS0-7 SISO tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS40_SISO_FIRST; + c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_40_siso[c]; + + /* 40MHz MCS0-7 CDD tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS40_CDD_FIRST; + c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_40_cdd[c]; + + /* 40MHz MCS0-7 STBC tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS40_STBC_FIRST; + c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_40_stbc[c]; + +#if WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM +#error "WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM" +#endif + + /* 20MHz MCS8-15 SDM tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS20_SDM_FIRST; + c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_20_mimo[c]; + + /* 40MHz MCS8-15 SDM tx power limits */ + for (c = 0, r = WL_TX_POWER_MCS40_SDM_FIRST; + c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++) + power.reg_limit[r] = txpwr.mcs_40_mimo[c]; + + /* MCS 32 */ + power.reg_limit[WL_TX_POWER_MCS_32] = txpwr.mcs32; + } + + wlc_phy_txpower_get_current(wlc->band->pi, &power, + CHSPEC_CHANNEL(power.chanspec)); + + /* copy the tx_power_t struct to the return buffer, + * or convert to a tx_power_legacy_t struct + */ + if (!old_power) { + memcpy(pwr, &power, sizeof(tx_power_t)); + } else { + int band_idx = CHSPEC_IS2G(power.chanspec) ? 0 : 1; + + memset(old_power, 0, sizeof(tx_power_legacy_t)); + + old_power->txpwr_local_max = power.local_max; + old_power->txpwr_local_constraint = power.local_constraint; + if (CHSPEC_IS2G(power.chanspec)) { + old_power->txpwr_chan_reg_max = txpwr.cck[0]; + old_power->txpwr_est_Pout[band_idx] = + power.est_Pout_cck; + old_power->txpwr_est_Pout_gofdm = power.est_Pout[0]; + } else { + old_power->txpwr_chan_reg_max = txpwr.ofdm[0]; + old_power->txpwr_est_Pout[band_idx] = power.est_Pout[0]; + } + old_power->txpwr_antgain[0] = power.antgain[0]; + old_power->txpwr_antgain[1] = power.antgain[1]; + + for (r = 0; r < NUM_PWRCTRL_RATES; r++) { + old_power->txpwr_band_max[r] = power.user_limit[r]; + old_power->txpwr_limit[r] = power.reg_limit[r]; + old_power->txpwr_target[band_idx][r] = power.target[r]; + if (CHSPEC_IS2G(power.chanspec)) + old_power->txpwr_bphy_cck_max[r] = + power.board_limit[r]; + else + old_power->txpwr_aphy_max[r] = + power.board_limit[r]; + } + } + + return 0; +} +#endif /* defined(BCMDBG) */ + +static u32 wlc_watchdog_backup_bi(struct wlc_info *wlc) +{ + u32 bi; + bi = 2 * wlc->cfg->current_bss->dtim_period * + wlc->cfg->current_bss->beacon_period; + if (wlc->bcn_li_dtim) + bi *= wlc->bcn_li_dtim; + else if (wlc->bcn_li_bcn) + /* recalculate bi based on bcn_li_bcn */ + bi = 2 * wlc->bcn_li_bcn * wlc->cfg->current_bss->beacon_period; + + if (bi < 2 * TIMER_INTERVAL_WATCHDOG) + bi = 2 * TIMER_INTERVAL_WATCHDOG; + return bi; +} + +/* Change to run the watchdog either from a periodic timer or from tbtt handler. + * Call watchdog from tbtt handler if tbtt is true, watchdog timer otherwise. + */ +void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt) +{ + /* make sure changing watchdog driver is allowed */ + if (!wlc->pub->up || !wlc->pub->align_wd_tbtt) + return; + if (!tbtt && wlc->WDarmed) { + wl_del_timer(wlc->wl, wlc->wdtimer); + wlc->WDarmed = false; + } + + /* stop watchdog timer and use tbtt interrupt to drive watchdog */ + if (tbtt && wlc->WDarmed) { + wl_del_timer(wlc->wl, wlc->wdtimer); + wlc->WDarmed = false; + wlc->WDlast = OSL_SYSUPTIME(); + } + /* arm watchdog timer and drive the watchdog there */ + else if (!tbtt && !wlc->WDarmed) { + wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, + true); + wlc->WDarmed = true; + } + if (tbtt && !wlc->WDarmed) { + wl_add_timer(wlc->wl, wlc->wdtimer, wlc_watchdog_backup_bi(wlc), + true); + wlc->WDarmed = true; + } +} + +ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, wlc_rateset_t *rs) +{ + ratespec_t lowest_basic_rspec; + uint i; + + /* Use the lowest basic rate */ + lowest_basic_rspec = rs->rates[0] & RATE_MASK; + for (i = 0; i < rs->count; i++) { + if (rs->rates[i] & WLC_RATE_FLAG) { + lowest_basic_rspec = rs->rates[i] & RATE_MASK; + break; + } + } +#if NCONF + /* pick siso/cdd as default for OFDM (note no basic rate MCSs are supported yet) */ + if (IS_OFDM(lowest_basic_rspec)) { + lowest_basic_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT); + } +#endif + + return lowest_basic_rspec; +} + +/* This function changes the phytxctl for beacon based on current beacon ratespec AND txant + * setting as per this table: + * ratespec CCK ant = wlc->stf->txant + * OFDM ant = 3 + */ +void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, ratespec_t bcn_rspec) +{ + u16 phyctl; + u16 phytxant = wlc->stf->phytxant; + u16 mask = PHY_TXC_ANT_MASK; + + /* for non-siso rates or default setting, use the available chains */ + if (WLC_PHY_11N_CAP(wlc->band)) { + phytxant = wlc_stf_phytxchain_sel(wlc, bcn_rspec); + } + + phyctl = wlc_read_shm(wlc, M_BCN_PCTLWD); + phyctl = (phyctl & ~mask) | phytxant; + wlc_write_shm(wlc, M_BCN_PCTLWD, phyctl); +} + +/* centralized protection config change function to simplify debugging, no consistency checking + * this should be called only on changes to avoid overhead in periodic function +*/ +void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val) +{ + WL_TRACE("wlc_protection_upd: idx %d, val %d\n", idx, val); + + switch (idx) { + case WLC_PROT_G_SPEC: + wlc->protection->_g = (bool) val; + break; + case WLC_PROT_G_OVR: + wlc->protection->g_override = (s8) val; + break; + case WLC_PROT_G_USER: + wlc->protection->gmode_user = (u8) val; + break; + case WLC_PROT_OVERLAP: + wlc->protection->overlap = (s8) val; + break; + case WLC_PROT_N_USER: + wlc->protection->nmode_user = (s8) val; + break; + case WLC_PROT_N_CFG: + wlc->protection->n_cfg = (s8) val; + break; + case WLC_PROT_N_CFG_OVR: + wlc->protection->n_cfg_override = (s8) val; + break; + case WLC_PROT_N_NONGF: + wlc->protection->nongf = (bool) val; + break; + case WLC_PROT_N_NONGF_OVR: + wlc->protection->nongf_override = (s8) val; + break; + case WLC_PROT_N_PAM_OVR: + wlc->protection->n_pam_override = (s8) val; + break; + case WLC_PROT_N_OBSS: + wlc->protection->n_obss = (bool) val; + break; + + default: + ASSERT(0); + break; + } + +} + +static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val) +{ + wlc->ht_cap.cap_info &= ~(IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_SGI_40); + wlc->ht_cap.cap_info |= (val & WLC_N_SGI_20) ? + IEEE80211_HT_CAP_SGI_20 : 0; + wlc->ht_cap.cap_info |= (val & WLC_N_SGI_40) ? + IEEE80211_HT_CAP_SGI_40 : 0; + + if (wlc->pub->up) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, true); + } +} + +static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val) +{ + wlc->stf->ldpc = val; + + wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_LDPC_CODING; + if (wlc->stf->ldpc != OFF) + wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_LDPC_CODING; + + if (wlc->pub->up) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, true); + wlc_phy_ldpc_override_set(wlc->band->pi, (val ? true : false)); + } +} + +/* + * ucode, hwmac update + * Channel dependent updates for ucode and hw + */ +static void wlc_ucode_mac_upd(struct wlc_info *wlc) +{ + /* enable or disable any active IBSSs depending on whether or not + * we are on the home channel + */ + if (wlc->home_chanspec == WLC_BAND_PI_RADIO_CHANSPEC) { + if (wlc->pub->associated) { + /* BMAC_NOTE: This is something that should be fixed in ucode inits. + * I think that the ucode inits set up the bcn templates and shm values + * with a bogus beacon. This should not be done in the inits. If ucode needs + * to set up a beacon for testing, the test routines should write it down, + * not expect the inits to populate a bogus beacon. + */ + if (WLC_PHY_11N_CAP(wlc->band)) { + wlc_write_shm(wlc, M_BCN_TXTSF_OFFSET, + wlc->band->bcntsfoff); + } + } + } else { + /* disable an active IBSS if we are not on the home channel */ + } + + /* update the various promisc bits */ + wlc_mac_bcn_promisc(wlc); + wlc_mac_promisc(wlc); +} + +static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec) +{ + wlc_rateset_t default_rateset; + uint parkband; + uint i, band_order[2]; + + WL_TRACE("wl%d: wlc_bandinit_ordered\n", wlc->pub->unit); + /* + * We might have been bandlocked during down and the chip power-cycled (hibernate). + * figure out the right band to park on + */ + if (wlc->bandlocked || NBANDS(wlc) == 1) { + ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit); + + parkband = wlc->band->bandunit; /* updated in wlc_bandlock() */ + band_order[0] = band_order[1] = parkband; + } else { + /* park on the band of the specified chanspec */ + parkband = CHSPEC_WLCBANDUNIT(chanspec); + + /* order so that parkband initialize last */ + band_order[0] = parkband ^ 1; + band_order[1] = parkband; + } + + /* make each band operational, software state init */ + for (i = 0; i < NBANDS(wlc); i++) { + uint j = band_order[i]; + + wlc->band = wlc->bandstate[j]; + + wlc_default_rateset(wlc, &default_rateset); + + /* fill in hw_rate */ + wlc_rateset_filter(&default_rateset, &wlc->band->hw_rateset, + false, WLC_RATES_CCK_OFDM, RATE_MASK, + (bool) N_ENAB(wlc->pub)); + + /* init basic rate lookup */ + wlc_rate_lookup_init(wlc, &default_rateset); + } + + /* sync up phy/radio chanspec */ + wlc_set_phy_chanspec(wlc, chanspec); +} + +/* band-specific init */ +static void WLBANDINITFN(wlc_bsinit) (struct wlc_info *wlc) +{ + WL_TRACE("wl%d: wlc_bsinit: bandunit %d\n", + wlc->pub->unit, wlc->band->bandunit); + + /* write ucode ACK/CTS rate table */ + wlc_set_ratetable(wlc); + + /* update some band specific mac configuration */ + wlc_ucode_mac_upd(wlc); + + /* init antenna selection */ + wlc_antsel_init(wlc->asi); + +} + +/* switch to and initialize new band */ +static void WLBANDINITFN(wlc_setband) (struct wlc_info *wlc, uint bandunit) +{ + int idx; + wlc_bsscfg_t *cfg; + + ASSERT(NBANDS(wlc) > 1); + ASSERT(!wlc->bandlocked); + ASSERT(bandunit != wlc->band->bandunit || wlc->bandinit_pending); + + wlc->band = wlc->bandstate[bandunit]; + + if (!wlc->pub->up) + return; + + /* wait for at least one beacon before entering sleeping state */ + wlc->PMawakebcn = true; + FOREACH_AS_STA(wlc, idx, cfg) + cfg->PMawakebcn = true; + wlc_set_ps_ctrl(wlc); + + /* band-specific initializations */ + wlc_bsinit(wlc); +} + +/* Initialize a WME Parameter Info Element with default STA parameters from WMM Spec, Table 12 */ +void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe) +{ + static const wme_param_ie_t stadef = { + WME_OUI, + WME_TYPE, + WME_SUBTYPE_PARAM_IE, + WME_VER, + 0, + 0, + { + {EDCF_AC_BE_ACI_STA, EDCF_AC_BE_ECW_STA, + cpu_to_le16(EDCF_AC_BE_TXOP_STA)}, + {EDCF_AC_BK_ACI_STA, EDCF_AC_BK_ECW_STA, + cpu_to_le16(EDCF_AC_BK_TXOP_STA)}, + {EDCF_AC_VI_ACI_STA, EDCF_AC_VI_ECW_STA, + cpu_to_le16(EDCF_AC_VI_TXOP_STA)}, + {EDCF_AC_VO_ACI_STA, EDCF_AC_VO_ECW_STA, + cpu_to_le16(EDCF_AC_VO_TXOP_STA)} + } + }; + + ASSERT(sizeof(*pe) == WME_PARAM_IE_LEN); + memcpy(pe, &stadef, sizeof(*pe)); +} + +void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend) +{ + int i; + shm_acparams_t acp_shm; + u16 *shm_entry; + struct ieee80211_tx_queue_params *params = arg; + + ASSERT(wlc); + + /* Only apply params if the core is out of reset and has clocks */ + if (!wlc->clk) { + WL_ERROR("wl%d: %s : no-clock\n", wlc->pub->unit, __func__); + return; + } + + /* + * AP uses AC params from wme_param_ie_ap. + * AP advertises AC params from wme_param_ie. + * STA uses AC params from wme_param_ie. + */ + + wlc->wme_admctl = 0; + + do { + memset((char *)&acp_shm, 0, sizeof(shm_acparams_t)); + /* find out which ac this set of params applies to */ + ASSERT(aci < AC_COUNT); + /* set the admission control policy for this AC */ + /* wlc->wme_admctl |= 1 << aci; *//* should be set ?? seems like off by default */ + + /* fill in shm ac params struct */ + acp_shm.txop = le16_to_cpu(params->txop); + /* convert from units of 32us to us for ucode */ + wlc->edcf_txop[aci & 0x3] = acp_shm.txop = + EDCF_TXOP2USEC(acp_shm.txop); + acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK); + + if (aci == AC_VI && acp_shm.txop == 0 + && acp_shm.aifs < EDCF_AIFSN_MAX) + acp_shm.aifs++; + + if (acp_shm.aifs < EDCF_AIFSN_MIN + || acp_shm.aifs > EDCF_AIFSN_MAX) { + WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n", + wlc->pub->unit, acp_shm.aifs); + continue; + } + + acp_shm.cwmin = params->cw_min; + acp_shm.cwmax = params->cw_max; + acp_shm.cwcur = acp_shm.cwmin; + acp_shm.bslots = + R_REG(&wlc->regs->tsf_random) & acp_shm.cwcur; + acp_shm.reggap = acp_shm.bslots + acp_shm.aifs; + /* Indicate the new params to the ucode */ + acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO + + wme_shmemacindex(aci) * + M_EDCF_QLEN + + M_EDCF_STATUS_OFF)); + acp_shm.status |= WME_STATUS_NEWAC; + + /* Fill in shm acparam table */ + shm_entry = (u16 *) &acp_shm; + for (i = 0; i < (int)sizeof(shm_acparams_t); i += 2) + wlc_write_shm(wlc, + M_EDCF_QINFO + + wme_shmemacindex(aci) * M_EDCF_QLEN + i, + *shm_entry++); + + } while (0); + + if (suspend) + wlc_suspend_mac_and_wait(wlc); + + if (suspend) + wlc_enable_mac(wlc); + +} + +void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend) +{ + struct wlc_info *wlc = cfg->wlc; + uint aci, i, j; + edcf_acparam_t *edcf_acp; + shm_acparams_t acp_shm; + u16 *shm_entry; + + ASSERT(cfg); + ASSERT(wlc); + + /* Only apply params if the core is out of reset and has clocks */ + if (!wlc->clk) + return; + + /* + * AP uses AC params from wme_param_ie_ap. + * AP advertises AC params from wme_param_ie. + * STA uses AC params from wme_param_ie. + */ + + edcf_acp = (edcf_acparam_t *) &wlc->wme_param_ie.acparam[0]; + + wlc->wme_admctl = 0; + + for (i = 0; i < AC_COUNT; i++, edcf_acp++) { + memset((char *)&acp_shm, 0, sizeof(shm_acparams_t)); + /* find out which ac this set of params applies to */ + aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT; + ASSERT(aci < AC_COUNT); + /* set the admission control policy for this AC */ + if (edcf_acp->ACI & EDCF_ACM_MASK) { + wlc->wme_admctl |= 1 << aci; + } + + /* fill in shm ac params struct */ + acp_shm.txop = le16_to_cpu(edcf_acp->TXOP); + /* convert from units of 32us to us for ucode */ + wlc->edcf_txop[aci] = acp_shm.txop = + EDCF_TXOP2USEC(acp_shm.txop); + acp_shm.aifs = (edcf_acp->ACI & EDCF_AIFSN_MASK); + + if (aci == AC_VI && acp_shm.txop == 0 + && acp_shm.aifs < EDCF_AIFSN_MAX) + acp_shm.aifs++; + + if (acp_shm.aifs < EDCF_AIFSN_MIN + || acp_shm.aifs > EDCF_AIFSN_MAX) { + WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n", + wlc->pub->unit, acp_shm.aifs); + continue; + } + + /* CWmin = 2^(ECWmin) - 1 */ + acp_shm.cwmin = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK); + /* CWmax = 2^(ECWmax) - 1 */ + acp_shm.cwmax = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK) + >> EDCF_ECWMAX_SHIFT); + acp_shm.cwcur = acp_shm.cwmin; + acp_shm.bslots = + R_REG(&wlc->regs->tsf_random) & acp_shm.cwcur; + acp_shm.reggap = acp_shm.bslots + acp_shm.aifs; + /* Indicate the new params to the ucode */ + acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO + + wme_shmemacindex(aci) * + M_EDCF_QLEN + + M_EDCF_STATUS_OFF)); + acp_shm.status |= WME_STATUS_NEWAC; + + /* Fill in shm acparam table */ + shm_entry = (u16 *) &acp_shm; + for (j = 0; j < (int)sizeof(shm_acparams_t); j += 2) + wlc_write_shm(wlc, + M_EDCF_QINFO + + wme_shmemacindex(aci) * M_EDCF_QLEN + j, + *shm_entry++); + } + + if (suspend) + wlc_suspend_mac_and_wait(wlc); + + if (AP_ENAB(wlc->pub) && WME_ENAB(wlc->pub)) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, false); + } + + if (suspend) + wlc_enable_mac(wlc); + +} + +bool wlc_timers_init(struct wlc_info *wlc, int unit) +{ + wlc->wdtimer = wl_init_timer(wlc->wl, wlc_watchdog_by_timer, + wlc, "watchdog"); + if (!wlc->wdtimer) { + WL_ERROR("wl%d: wl_init_timer for wdtimer failed\n", unit); + goto fail; + } + + wlc->radio_timer = wl_init_timer(wlc->wl, wlc_radio_timer, + wlc, "radio"); + if (!wlc->radio_timer) { + WL_ERROR("wl%d: wl_init_timer for radio_timer failed\n", unit); + goto fail; + } + + return true; + + fail: + return false; +} + +/* + * Initialize wlc_info default values ... + * may get overrides later in this function + */ +void wlc_info_init(struct wlc_info *wlc, int unit) +{ + int i; + /* Assume the device is there until proven otherwise */ + wlc->device_present = true; + + /* set default power output percentage to 100 percent */ + wlc->txpwr_percent = 100; + + /* Save our copy of the chanspec */ + wlc->chanspec = CH20MHZ_CHSPEC(1); + + /* initialize CCK preamble mode to unassociated state */ + wlc->shortpreamble = false; + + wlc->legacy_probe = true; + + /* various 802.11g modes */ + wlc->shortslot = false; + wlc->shortslot_override = WLC_SHORTSLOT_AUTO; + + wlc->barker_overlap_control = true; + wlc->barker_preamble = WLC_BARKER_SHORT_ALLOWED; + wlc->txburst_limit_override = AUTO; + + wlc_protection_upd(wlc, WLC_PROT_G_OVR, WLC_PROTECTION_AUTO); + wlc_protection_upd(wlc, WLC_PROT_G_SPEC, false); + + wlc_protection_upd(wlc, WLC_PROT_N_CFG_OVR, WLC_PROTECTION_AUTO); + wlc_protection_upd(wlc, WLC_PROT_N_CFG, WLC_N_PROTECTION_OFF); + wlc_protection_upd(wlc, WLC_PROT_N_NONGF_OVR, WLC_PROTECTION_AUTO); + wlc_protection_upd(wlc, WLC_PROT_N_NONGF, false); + wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR, AUTO); + + wlc_protection_upd(wlc, WLC_PROT_OVERLAP, WLC_PROTECTION_CTL_OVERLAP); + + /* 802.11g draft 4.0 NonERP elt advertisement */ + wlc->include_legacy_erp = true; + + wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF; + wlc->stf->txant = ANT_TX_DEF; + + wlc->prb_resp_timeout = WLC_PRB_RESP_TIMEOUT; + + wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN; + for (i = 0; i < NFIFO; i++) + wlc->fragthresh[i] = DOT11_DEFAULT_FRAG_LEN; + wlc->RTSThresh = DOT11_DEFAULT_RTS_LEN; + + /* default rate fallback retry limits */ + wlc->SFBL = RETRY_SHORT_FB; + wlc->LFBL = RETRY_LONG_FB; + + /* default mac retry limits */ + wlc->SRL = RETRY_SHORT_DEF; + wlc->LRL = RETRY_LONG_DEF; + + /* init PM state */ + wlc->PM = PM_OFF; /* User's setting of PM mode through IOCTL */ + wlc->PM_override = false; /* Prevents from going to PM if our AP is 'ill' */ + wlc->PMenabled = false; /* Current PM state */ + wlc->PMpending = false; /* Tracks whether STA indicated PM in the last attempt */ + wlc->PMblocked = false; /* To allow blocking going into PM during RM and scans */ + + /* In WMM Auto mode, PM is allowed if association is a UAPSD association */ + wlc->WME_PM_blocked = false; + + /* Init wme queuing method */ + wlc->wme_prec_queuing = false; + + /* Overrides for the core to stay awake under zillion conditions Look for STAY_AWAKE */ + wlc->wake = false; + /* Are we waiting for a response to PS-Poll that we sent */ + wlc->PSpoll = false; + + /* APSD defaults */ + wlc->wme_apsd = true; + wlc->apsd_sta_usp = false; + wlc->apsd_trigger_timeout = 0; /* disable the trigger timer */ + wlc->apsd_trigger_ac = AC_BITMAP_ALL; + + /* Set flag to indicate that hw keys should be used when available. */ + wlc->wsec_swkeys = false; + + /* init the 4 static WEP default keys */ + for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) { + wlc->wsec_keys[i] = wlc->wsec_def_keys[i]; + wlc->wsec_keys[i]->idx = (u8) i; + } + + wlc->_regulatory_domain = false; /* 802.11d */ + + /* WME QoS mode is Auto by default */ + wlc->pub->_wme = AUTO; + +#ifdef BCMSDIODEV_ENABLED + wlc->pub->_priofc = true; /* enable priority flow control for sdio dongle */ +#endif + + wlc->pub->_ampdu = AMPDU_AGG_HOST; + wlc->pub->bcmerror = 0; + wlc->ibss_allowed = true; + wlc->ibss_coalesce_allowed = true; + wlc->pub->_coex = ON; + + /* initialize mpc delay */ + wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; + + wlc->pr80838_war = true; +} + +static bool wlc_state_bmac_sync(struct wlc_info *wlc) +{ + wlc_bmac_state_t state_bmac; + + if (wlc_bmac_state_get(wlc->hw, &state_bmac) != 0) + return false; + + wlc->machwcap = state_bmac.machwcap; + wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR, + (s8) state_bmac.preamble_ovr); + + return true; +} + +static uint wlc_attach_module(struct wlc_info *wlc) +{ + uint err = 0; + uint unit; + unit = wlc->pub->unit; + + wlc->asi = wlc_antsel_attach(wlc); + if (wlc->asi == NULL) { + WL_ERROR("wl%d: wlc_attach: wlc_antsel_attach failed\n", unit); + err = 44; + goto fail; + } + + wlc->ampdu = wlc_ampdu_attach(wlc); + if (wlc->ampdu == NULL) { + WL_ERROR("wl%d: wlc_attach: wlc_ampdu_attach failed\n", unit); + err = 50; + goto fail; + } + + if ((wlc_stf_attach(wlc) != 0)) { + WL_ERROR("wl%d: wlc_attach: wlc_stf_attach failed\n", unit); + err = 68; + goto fail; + } + fail: + return err; +} + +struct wlc_pub *wlc_pub(void *wlc) +{ + return ((struct wlc_info *) wlc)->pub; +} + +#define CHIP_SUPPORTS_11N(wlc) 1 + +/* + * The common driver entry routine. Error codes should be unique + */ +void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, + struct osl_info *osh, void *regsva, uint bustype, + void *btparam, uint *perr) +{ + struct wlc_info *wlc; + uint err = 0; + uint j; + struct wlc_pub *pub; + struct wlc_txq_info *qi; + uint n_disabled; + + WL_NONE("wl%d: %s: vendor 0x%x device 0x%x\n", + unit, __func__, vendor, device); + + ASSERT(WSEC_MAX_RCMTA_KEYS <= WSEC_MAX_KEYS); + ASSERT(WSEC_MAX_DEFAULT_KEYS == WLC_DEFAULT_KEYS); + + /* some code depends on packed structures */ + ASSERT(sizeof(struct ethhdr) == ETH_HLEN); + ASSERT(sizeof(d11regs_t) == SI_CORE_SIZE); + ASSERT(sizeof(ofdm_phy_hdr_t) == D11_PHY_HDR_LEN); + ASSERT(sizeof(cck_phy_hdr_t) == D11_PHY_HDR_LEN); + ASSERT(sizeof(d11txh_t) == D11_TXH_LEN); + ASSERT(sizeof(d11rxhdr_t) == RXHDR_LEN); + ASSERT(sizeof(struct ieee80211_hdr) == DOT11_A4_HDR_LEN); + ASSERT(sizeof(struct ieee80211_rts) == DOT11_RTS_LEN); + ASSERT(sizeof(tx_status_t) == TXSTATUS_LEN); + ASSERT(sizeof(struct ieee80211_ht_cap) == HT_CAP_IE_LEN); +#ifdef BRCM_FULLMAC + ASSERT(offsetof(wl_scan_params_t, channel_list) == + WL_SCAN_PARAMS_FIXED_SIZE); +#endif + ASSERT(IS_ALIGNED(offsetof(wsec_key_t, data), sizeof(u32))); + ASSERT(ISPOWEROF2(MA_WINDOW_SZ)); + + ASSERT(sizeof(wlc_d11rxhdr_t) <= WL_HWRXOFF); + + /* + * Number of replay counters value used in WPA IE must match # rxivs + * supported in wsec_key_t struct. See 802.11i/D3.0 sect. 7.3.2.17 + * 'RSN Information Element' figure 8 for this mapping. + */ + ASSERT((WPA_CAP_16_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE + && 16 == WLC_NUMRXIVS) + || (WPA_CAP_4_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE + && 4 == WLC_NUMRXIVS)); + + /* allocate struct wlc_info state and its substructures */ + wlc = (struct wlc_info *) wlc_attach_malloc(unit, &err, device); + if (wlc == NULL) + goto fail; + wlc->osh = osh; + pub = wlc->pub; + +#if defined(BCMDBG) + wlc_info_dbg = wlc; +#endif + + wlc->band = wlc->bandstate[0]; + wlc->core = wlc->corestate; + wlc->wl = wl; + pub->unit = unit; + pub->osh = osh; + wlc->btparam = btparam; + pub->_piomode = piomode; + wlc->bandinit_pending = false; + /* By default restrict TKIP associations from 11n STA's */ + wlc->ht_wsec_restriction = WLC_HT_TKIP_RESTRICT; + + /* populate struct wlc_info with default values */ + wlc_info_init(wlc, unit); + + /* update sta/ap related parameters */ + wlc_ap_upd(wlc); + + /* 11n_disable nvram */ + n_disabled = getintvar(pub->vars, "11n_disable"); + + /* register a module (to handle iovars) */ + wlc_module_register(wlc->pub, wlc_iovars, "wlc_iovars", wlc, + wlc_doiovar, NULL, NULL); + + /* low level attach steps(all hw accesses go inside, no more in rest of the attach) */ + err = wlc_bmac_attach(wlc, vendor, device, unit, piomode, osh, regsva, + bustype, btparam); + if (err) + goto fail; + + /* for some states, due to different info pointer(e,g, wlc, wlc_hw) or master/slave split, + * HIGH driver(both monolithic and HIGH_ONLY) needs to sync states FROM BMAC portion driver + */ + if (!wlc_state_bmac_sync(wlc)) { + err = 20; + goto fail; + } + + pub->phy_11ncapable = WLC_PHY_11N_CAP(wlc->band); + + /* propagate *vars* from BMAC driver to high driver */ + wlc_bmac_copyfrom_vars(wlc->hw, &pub->vars, &wlc->vars_size); + + + /* set maximum allowed duty cycle */ + wlc->tx_duty_cycle_ofdm = + (u16) getintvar(pub->vars, "tx_duty_cycle_ofdm"); + wlc->tx_duty_cycle_cck = + (u16) getintvar(pub->vars, "tx_duty_cycle_cck"); + + wlc_stf_phy_chain_calc(wlc); + + /* txchain 1: txant 0, txchain 2: txant 1 */ + if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1)) + wlc->stf->txant = wlc->stf->hw_txchain - 1; + + /* push to BMAC driver */ + wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain, + wlc->stf->hw_rxchain); + + /* pull up some info resulting from the low attach */ + { + int i; + for (i = 0; i < NFIFO; i++) + wlc->core->txavail[i] = wlc->hw->txavail[i]; + } + + wlc_bmac_hw_etheraddr(wlc->hw, wlc->perm_etheraddr); + + memcpy(&pub->cur_etheraddr, &wlc->perm_etheraddr, ETH_ALEN); + + for (j = 0; j < NBANDS(wlc); j++) { + /* Use band 1 for single band 11a */ + if (IS_SINGLEBAND_5G(wlc->deviceid)) + j = BAND_5G_INDEX; + + wlc->band = wlc->bandstate[j]; + + if (!wlc_attach_stf_ant_init(wlc)) { + err = 24; + goto fail; + } + + /* default contention windows size limits */ + wlc->band->CWmin = APHY_CWMIN; + wlc->band->CWmax = PHY_CWMAX; + + /* init gmode value */ + if (BAND_2G(wlc->band->bandtype)) { + wlc->band->gmode = GMODE_AUTO; + wlc_protection_upd(wlc, WLC_PROT_G_USER, + wlc->band->gmode); + } + + /* init _n_enab supported mode */ + if (WLC_PHY_11N_CAP(wlc->band) && CHIP_SUPPORTS_11N(wlc)) { + if (n_disabled & WLFEATURE_DISABLE_11N) { + pub->_n_enab = OFF; + wlc_protection_upd(wlc, WLC_PROT_N_USER, OFF); + } else { + pub->_n_enab = SUPPORT_11N; + wlc_protection_upd(wlc, WLC_PROT_N_USER, + ((pub->_n_enab == + SUPPORT_11N) ? WL_11N_2x2 : + WL_11N_3x3)); + } + } + + /* init per-band default rateset, depend on band->gmode */ + wlc_default_rateset(wlc, &wlc->band->defrateset); + + /* fill in hw_rateset (used early by WLC_SET_RATESET) */ + wlc_rateset_filter(&wlc->band->defrateset, + &wlc->band->hw_rateset, false, + WLC_RATES_CCK_OFDM, RATE_MASK, + (bool) N_ENAB(wlc->pub)); + } + + /* update antenna config due to wlc->stf->txant/txchain/ant_rx_ovr change */ + wlc_stf_phy_txant_upd(wlc); + + /* attach each modules */ + err = wlc_attach_module(wlc); + if (err != 0) + goto fail; + + if (!wlc_timers_init(wlc, unit)) { + WL_ERROR("wl%d: %s: wlc_init_timer failed\n", unit, __func__); + err = 32; + goto fail; + } + + /* depend on rateset, gmode */ + wlc->cmi = wlc_channel_mgr_attach(wlc); + if (!wlc->cmi) { + WL_ERROR("wl%d: %s: wlc_channel_mgr_attach failed\n", + unit, __func__); + err = 33; + goto fail; + } + + /* init default when all parameters are ready, i.e. ->rateset */ + wlc_bss_default_init(wlc); + + /* + * Complete the wlc default state initializations.. + */ + + /* allocate our initial queue */ + qi = wlc_txq_alloc(wlc, osh); + if (qi == NULL) { + WL_ERROR("wl%d: %s: failed to malloc tx queue\n", + unit, __func__); + err = 100; + goto fail; + } + wlc->active_queue = qi; + + wlc->bsscfg[0] = wlc->cfg; + wlc->cfg->_idx = 0; + wlc->cfg->wlc = wlc; + pub->txmaxpkts = MAXTXPKTS; + + pub->_cnt->version = WL_CNT_T_VERSION; + pub->_cnt->length = sizeof(struct wl_cnt); + + WLCNTSET(pub->_wme_cnt->version, WL_WME_CNT_VERSION); + WLCNTSET(pub->_wme_cnt->length, sizeof(wl_wme_cnt_t)); + + wlc_wme_initparams_sta(wlc, &wlc->wme_param_ie); + + wlc->mimoft = FT_HT; + wlc->ht_cap.cap_info = HT_CAP; + if (HT_ENAB(wlc->pub)) + wlc->stf->ldpc = AUTO; + + wlc->mimo_40txbw = AUTO; + wlc->ofdm_40txbw = AUTO; + wlc->cck_40txbw = AUTO; + wlc_update_mimo_band_bwcap(wlc, WLC_N_BW_20IN2G_40IN5G); + + /* Enable setting the RIFS Mode bit by default in HT Info IE */ + wlc->rifs_advert = AUTO; + + /* Set default values of SGI */ + if (WLC_SGI_CAP_PHY(wlc)) { + wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40)); + wlc->sgi_tx = AUTO; + } else if (WLCISSSLPNPHY(wlc->band)) { + wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40)); + wlc->sgi_tx = AUTO; + } else { + wlc_ht_update_sgi_rx(wlc, 0); + wlc->sgi_tx = OFF; + } + + /* *******nvram 11n config overrides Start ********* */ + + /* apply the sgi override from nvram conf */ + if (n_disabled & WLFEATURE_DISABLE_11N_SGI_TX) + wlc->sgi_tx = OFF; + + if (n_disabled & WLFEATURE_DISABLE_11N_SGI_RX) + wlc_ht_update_sgi_rx(wlc, 0); + + /* apply the stbc override from nvram conf */ + if (n_disabled & WLFEATURE_DISABLE_11N_STBC_TX) { + wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF; + wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF; + wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC; + } + if (n_disabled & WLFEATURE_DISABLE_11N_STBC_RX) + wlc_stf_stbc_rx_set(wlc, HT_CAP_RX_STBC_NO); + + /* apply the GF override from nvram conf */ + if (n_disabled & WLFEATURE_DISABLE_11N_GF) + wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_GRN_FLD; + + /* initialize radio_mpc_disable according to wlc->mpc */ + wlc_radio_mpc_upd(wlc); + + if ((wlc->pub->sih->chip) == BCM43235_CHIP_ID) { + if ((getintvar(wlc->pub->vars, "aa2g") == 7) || + (getintvar(wlc->pub->vars, "aa5g") == 7)) { + wlc_bmac_antsel_set(wlc->hw, 1); + } + } else { + wlc_bmac_antsel_set(wlc->hw, wlc->asi->antsel_avail); + } + + if (perr) + *perr = 0; + + return (void *)wlc; + + fail: + WL_ERROR("wl%d: %s: failed with err %d\n", unit, __func__, err); + if (wlc) + wlc_detach(wlc); + + if (perr) + *perr = err; + return NULL; +} + +static void wlc_attach_antgain_init(struct wlc_info *wlc) +{ + uint unit; + unit = wlc->pub->unit; + + if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) { + /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */ + wlc->band->antgain = 8; + } else if (wlc->band->antgain == -1) { + WL_ERROR("wl%d: %s: Invalid antennas available in srom, using 2dB\n", + unit, __func__); + wlc->band->antgain = 8; + } else { + s8 gain, fract; + /* Older sroms specified gain in whole dbm only. In order + * be able to specify qdbm granularity and remain backward compatible + * the whole dbms are now encoded in only low 6 bits and remaining qdbms + * are encoded in the hi 2 bits. 6 bit signed number ranges from + * -32 - 31. Examples: 0x1 = 1 db, + * 0xc1 = 1.75 db (1 + 3 quarters), + * 0x3f = -1 (-1 + 0 quarters), + * 0x7f = -.75 (-1 in low 6 bits + 1 quarters in hi 2 bits) = -3 qdbm. + * 0xbf = -.50 (-1 in low 6 bits + 2 quarters in hi 2 bits) = -2 qdbm. + */ + gain = wlc->band->antgain & 0x3f; + gain <<= 2; /* Sign extend */ + gain >>= 2; + fract = (wlc->band->antgain & 0xc0) >> 6; + wlc->band->antgain = 4 * gain + fract; + } +} + +static bool wlc_attach_stf_ant_init(struct wlc_info *wlc) +{ + int aa; + uint unit; + char *vars; + int bandtype; + + unit = wlc->pub->unit; + vars = wlc->pub->vars; + bandtype = wlc->band->bandtype; + + /* get antennas available */ + aa = (s8) getintvar(vars, (BAND_5G(bandtype) ? "aa5g" : "aa2g")); + if (aa == 0) + aa = (s8) getintvar(vars, + (BAND_5G(bandtype) ? "aa1" : "aa0")); + if ((aa < 1) || (aa > 15)) { + WL_ERROR("wl%d: %s: Invalid antennas available in srom (0x%x), using 3\n", + unit, __func__, aa); + aa = 3; + } + + /* reset the defaults if we have a single antenna */ + if (aa == 1) { + wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_0; + wlc->stf->txant = ANT_TX_FORCE_0; + } else if (aa == 2) { + wlc->stf->ant_rx_ovr = ANT_RX_DIV_FORCE_1; + wlc->stf->txant = ANT_TX_FORCE_1; + } else { + } + + /* Compute Antenna Gain */ + wlc->band->antgain = + (s8) getintvar(vars, (BAND_5G(bandtype) ? "ag1" : "ag0")); + wlc_attach_antgain_init(wlc); + + return true; +} + + +static void wlc_timers_deinit(struct wlc_info *wlc) +{ + /* free timer state */ + if (wlc->wdtimer) { + wl_free_timer(wlc->wl, wlc->wdtimer); + wlc->wdtimer = NULL; + } + if (wlc->radio_timer) { + wl_free_timer(wlc->wl, wlc->radio_timer); + wlc->radio_timer = NULL; + } +} + +static void wlc_detach_module(struct wlc_info *wlc) +{ + if (wlc->asi) { + wlc_antsel_detach(wlc->asi); + wlc->asi = NULL; + } + + if (wlc->ampdu) { + wlc_ampdu_detach(wlc->ampdu); + wlc->ampdu = NULL; + } + + wlc_stf_detach(wlc); +} + +/* + * Return a count of the number of driver callbacks still pending. + * + * General policy is that wlc_detach can only dealloc/free software states. It can NOT + * touch hardware registers since the d11core may be in reset and clock may not be available. + * One exception is sb register access, which is possible if crystal is turned on + * After "down" state, driver should avoid software timer with the exception of radio_monitor. + */ +uint wlc_detach(struct wlc_info *wlc) +{ + uint i; + uint callbacks = 0; + + if (wlc == NULL) + return 0; + + WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__); + + ASSERT(!wlc->pub->up); + + callbacks += wlc_bmac_detach(wlc); + + /* delete software timers */ + if (!wlc_radio_monitor_stop(wlc)) + callbacks++; + + wlc_channel_mgr_detach(wlc->cmi); + + wlc_timers_deinit(wlc); + + wlc_detach_module(wlc); + + /* free other state */ + + +#ifdef BCMDBG + if (wlc->country_ie_override) { + kfree(wlc->country_ie_override); + wlc->country_ie_override = NULL; + } +#endif /* BCMDBG */ + + { + /* free dumpcb list */ + struct dumpcb_s *prev, *ptr; + prev = ptr = wlc->dumpcb_head; + while (ptr) { + ptr = prev->next; + kfree(prev); + prev = ptr; + } + wlc->dumpcb_head = NULL; + } + + /* Detach from iovar manager */ + wlc_module_unregister(wlc->pub, "wlc_iovars", wlc); + + while (wlc->tx_queues != NULL) { + wlc_txq_free(wlc, wlc->osh, wlc->tx_queues); + } + + /* + * consistency check: wlc_module_register/wlc_module_unregister calls + * should match therefore nothing should be left here. + */ + for (i = 0; i < WLC_MAXMODULES; i++) + ASSERT(wlc->modulecb[i].name[0] == '\0'); + + wlc_detach_mfree(wlc); + return callbacks; +} + +/* update state that depends on the current value of "ap" */ +void wlc_ap_upd(struct wlc_info *wlc) +{ + if (AP_ENAB(wlc->pub)) + wlc->PLCPHdr_override = WLC_PLCP_AUTO; /* AP: short not allowed, but not enforced */ + else + wlc->PLCPHdr_override = WLC_PLCP_SHORT; /* STA-BSS; short capable */ + + /* disable vlan_mode on AP since some legacy STAs cannot rx tagged pkts */ + wlc->vlan_mode = AP_ENAB(wlc->pub) ? OFF : AUTO; + + /* fixup mpc */ + wlc->mpc = true; +} + +/* read hwdisable state and propagate to wlc flag */ +static void wlc_radio_hwdisable_upd(struct wlc_info *wlc) +{ + if (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO || wlc->pub->hw_off) + return; + + if (wlc_bmac_radio_read_hwdisabled(wlc->hw)) { + mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); + } else { + mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); + } +} + +/* return true if Minimum Power Consumption should be entered, false otherwise */ +bool wlc_is_non_delay_mpc(struct wlc_info *wlc) +{ + return false; +} + +bool wlc_ismpc(struct wlc_info *wlc) +{ + return (wlc->mpc_delay_off == 0) && (wlc_is_non_delay_mpc(wlc)); +} + +void wlc_radio_mpc_upd(struct wlc_info *wlc) +{ + bool mpc_radio, radio_state; + + /* + * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled + * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio + * monitor also when WL_RADIO_MPC_DISABLE is the only reason that + * the radio is going down. + */ + if (!wlc->mpc) { + if (!wlc->pub->radio_disabled) + return; + mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); + wlc_radio_upd(wlc); + if (!wlc->pub->radio_disabled) + wlc_radio_monitor_stop(wlc); + return; + } + + /* + * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in wlc->pub->radio_disabled + * to go ON, always call radio_upd synchronously + * to go OFF, postpone radio_upd to later when context is safe(e.g. watchdog) + */ + radio_state = + (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF : + ON); + mpc_radio = (wlc_ismpc(wlc) == true) ? OFF : ON; + + if (radio_state == ON && mpc_radio == OFF) + wlc->mpc_delay_off = wlc->mpc_dlycnt; + else if (radio_state == OFF && mpc_radio == ON) { + mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); + wlc_radio_upd(wlc); + if (wlc->mpc_offcnt < WLC_MPC_THRESHOLD) { + wlc->mpc_dlycnt = WLC_MPC_MAX_DELAYCNT; + } else + wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; + wlc->mpc_dur += OSL_SYSUPTIME() - wlc->mpc_laston_ts; + } + /* Below logic is meant to capture the transition from mpc off to mpc on for reasons + * other than wlc->mpc_delay_off keeping the mpc off. In that case reset + * wlc->mpc_delay_off to wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off + */ + if ((wlc->prev_non_delay_mpc == false) && + (wlc_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off) { + wlc->mpc_delay_off = wlc->mpc_dlycnt; + } + wlc->prev_non_delay_mpc = wlc_is_non_delay_mpc(wlc); +} + +/* + * centralized radio disable/enable function, + * invoke radio enable/disable after updating hwradio status + */ +static void wlc_radio_upd(struct wlc_info *wlc) +{ + if (wlc->pub->radio_disabled) { + wlc_radio_disable(wlc); + } else { + wlc_radio_enable(wlc); + } +} + +/* maintain LED behavior in down state */ +static void wlc_down_led_upd(struct wlc_info *wlc) +{ + ASSERT(!wlc->pub->up); + + /* maintain LEDs while in down state, turn on sbclk if not available yet */ + /* turn on sbclk if necessary */ + if (!AP_ENAB(wlc->pub)) { + wlc_pllreq(wlc, true, WLC_PLLREQ_FLIP); + + wlc_pllreq(wlc, false, WLC_PLLREQ_FLIP); + } +} + +/* update hwradio status and return it */ +bool wlc_check_radio_disabled(struct wlc_info *wlc) +{ + wlc_radio_hwdisable_upd(wlc); + + return mboolisset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE) ? true : false; +} + +void wlc_radio_disable(struct wlc_info *wlc) +{ + if (!wlc->pub->up) { + wlc_down_led_upd(wlc); + return; + } + + wlc_radio_monitor_start(wlc); + wl_down(wlc->wl); +} + +static void wlc_radio_enable(struct wlc_info *wlc) +{ + if (wlc->pub->up) + return; + + if (DEVICEREMOVED(wlc)) + return; + + if (!wlc->down_override) { /* imposed by wl down/out ioctl */ + wl_up(wlc->wl); + } +} + +/* periodical query hw radio button while driver is "down" */ +static void wlc_radio_timer(void *arg) +{ + struct wlc_info *wlc = (struct wlc_info *) arg; + + if (DEVICEREMOVED(wlc)) { + WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); + wl_down(wlc->wl); + return; + } + + /* cap mpc off count */ + if (wlc->mpc_offcnt < WLC_MPC_MAX_DELAYCNT) + wlc->mpc_offcnt++; + + /* validate all the reasons driver could be down and running this radio_timer */ + ASSERT(wlc->pub->radio_disabled || wlc->down_override); + wlc_radio_hwdisable_upd(wlc); + wlc_radio_upd(wlc); +} + +static bool wlc_radio_monitor_start(struct wlc_info *wlc) +{ + /* Don't start the timer if HWRADIO feature is disabled */ + if (wlc->radio_monitor || (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO)) + return true; + + wlc->radio_monitor = true; + wlc_pllreq(wlc, true, WLC_PLLREQ_RADIO_MON); + wl_add_timer(wlc->wl, wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true); + return true; +} + +bool wlc_radio_monitor_stop(struct wlc_info *wlc) +{ + if (!wlc->radio_monitor) + return true; + + ASSERT((wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO) != + WL_SWFL_NOHWRADIO); + + wlc->radio_monitor = false; + wlc_pllreq(wlc, false, WLC_PLLREQ_RADIO_MON); + return wl_del_timer(wlc->wl, wlc->radio_timer); +} + +/* bring the driver down, but don't reset hardware */ +void wlc_out(struct wlc_info *wlc) +{ + wlc_bmac_set_noreset(wlc->hw, true); + wlc_radio_upd(wlc); + wl_down(wlc->wl); + wlc_bmac_set_noreset(wlc->hw, false); + + /* core clk is true in BMAC driver due to noreset, need to mirror it in HIGH */ + wlc->clk = true; + + /* This will make sure that when 'up' is done + * after 'out' it'll restore hardware (especially gpios) + */ + wlc->pub->hw_up = false; +} + +#if defined(BCMDBG) +/* Verify the sanity of wlc->tx_prec_map. This can be done only by making sure that + * if there is no packet pending for the FIFO, then the corresponding prec bits should be set + * in prec_map. Of course, ignore this rule when block_datafifo is set + */ +static bool wlc_tx_prec_map_verify(struct wlc_info *wlc) +{ + /* For non-WME, both fifos have overlapping prec_map. So it's an error only if both + * fail the check. + */ + if (!EDCF_ENAB(wlc->pub)) { + if (!(WLC_TX_FIFO_CHECK(wlc, TX_DATA_FIFO) || + WLC_TX_FIFO_CHECK(wlc, TX_CTL_FIFO))) + return false; + else + return true; + } + + return WLC_TX_FIFO_CHECK(wlc, TX_AC_BK_FIFO) + && WLC_TX_FIFO_CHECK(wlc, TX_AC_BE_FIFO) + && WLC_TX_FIFO_CHECK(wlc, TX_AC_VI_FIFO) + && WLC_TX_FIFO_CHECK(wlc, TX_AC_VO_FIFO); +} +#endif /* BCMDBG */ + +static void wlc_watchdog_by_timer(void *arg) +{ + struct wlc_info *wlc = (struct wlc_info *) arg; + wlc_watchdog(arg); + if (WLC_WATCHDOG_TBTT(wlc)) { + /* set to normal osl watchdog period */ + wl_del_timer(wlc->wl, wlc->wdtimer); + wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, + true); + } +} + +/* common watchdog code */ +static void wlc_watchdog(void *arg) +{ + struct wlc_info *wlc = (struct wlc_info *) arg; + int i; + wlc_bsscfg_t *cfg; + + WL_TRACE("wl%d: wlc_watchdog\n", wlc->pub->unit); + + if (!wlc->pub->up) + return; + + if (DEVICEREMOVED(wlc)) { + WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); + wl_down(wlc->wl); + return; + } + + /* increment second count */ + wlc->pub->now++; + + /* delay radio disable */ + if (wlc->mpc_delay_off) { + if (--wlc->mpc_delay_off == 0) { + mboolset(wlc->pub->radio_disabled, + WL_RADIO_MPC_DISABLE); + if (wlc->mpc && wlc_ismpc(wlc)) + wlc->mpc_offcnt = 0; + wlc->mpc_laston_ts = OSL_SYSUPTIME(); + } + } + + /* mpc sync */ + wlc_radio_mpc_upd(wlc); + /* radio sync: sw/hw/mpc --> radio_disable/radio_enable */ + wlc_radio_hwdisable_upd(wlc); + wlc_radio_upd(wlc); + /* if ismpc, driver should be in down state if up/down is allowed */ + if (wlc->mpc && wlc_ismpc(wlc)) + ASSERT(!wlc->pub->up); + /* if radio is disable, driver may be down, quit here */ + if (wlc->pub->radio_disabled) + return; + + wlc_bmac_watchdog(wlc); + + /* occasionally sample mac stat counters to detect 16-bit counter wrap */ + if ((wlc->pub->now % SW_TIMER_MAC_STAT_UPD) == 0) + wlc_statsupd(wlc); + + /* Manage TKIP countermeasures timers */ + FOREACH_BSS(wlc, i, cfg) { + if (cfg->tk_cm_dt) { + cfg->tk_cm_dt--; + } + if (cfg->tk_cm_bt) { + cfg->tk_cm_bt--; + } + } + + /* Call any registered watchdog handlers */ + for (i = 0; i < WLC_MAXMODULES; i++) { + if (wlc->modulecb[i].watchdog_fn) + wlc->modulecb[i].watchdog_fn(wlc->modulecb[i].hdl); + } + + if (WLCISNPHY(wlc->band) && !wlc->pub->tempsense_disable && + ((wlc->pub->now - wlc->tempsense_lasttime) >= + WLC_TEMPSENSE_PERIOD)) { + wlc->tempsense_lasttime = wlc->pub->now; + wlc_tempsense_upd(wlc); + } + /* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */ + ASSERT(wlc_bmac_taclear(wlc->hw, true)); + + /* Verify that tx_prec_map and fifos are in sync to avoid lock ups */ + ASSERT(wlc_tx_prec_map_verify(wlc)); + + ASSERT(wlc_ps_check(wlc)); +} + +/* make interface operational */ +int wlc_up(struct wlc_info *wlc) +{ + WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__); + + /* HW is turned off so don't try to access it */ + if (wlc->pub->hw_off || DEVICEREMOVED(wlc)) + return BCME_RADIOOFF; + + if (!wlc->pub->hw_up) { + wlc_bmac_hw_up(wlc->hw); + wlc->pub->hw_up = true; + } + + if ((wlc->pub->boardflags & BFL_FEM) + && (wlc->pub->sih->chip == BCM4313_CHIP_ID)) { + if (wlc->pub->boardrev >= 0x1250 + && (wlc->pub->boardflags & BFL_FEM_BT)) { + wlc_mhf(wlc, MHF5, MHF5_4313_GPIOCTRL, + MHF5_4313_GPIOCTRL, WLC_BAND_ALL); + } else { + wlc_mhf(wlc, MHF4, MHF4_EXTPA_ENABLE, MHF4_EXTPA_ENABLE, + WLC_BAND_ALL); + } + } + + /* + * Need to read the hwradio status here to cover the case where the system + * is loaded with the hw radio disabled. We do not want to bring the driver up in this case. + * if radio is disabled, abort up, lower power, start radio timer and return 0(for NDIS) + * don't call radio_update to avoid looping wlc_up. + * + * wlc_bmac_up_prep() returns either 0 or BCME_RADIOOFF only + */ + if (!wlc->pub->radio_disabled) { + int status = wlc_bmac_up_prep(wlc->hw); + if (status == BCME_RADIOOFF) { + if (!mboolisset + (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) { + int idx; + wlc_bsscfg_t *bsscfg; + mboolset(wlc->pub->radio_disabled, + WL_RADIO_HW_DISABLE); + + FOREACH_BSS(wlc, idx, bsscfg) { + if (!BSSCFG_STA(bsscfg) + || !bsscfg->enable || !bsscfg->BSS) + continue; + WL_ERROR("wl%d.%d: wlc_up: rfdisable -> " "wlc_bsscfg_disable()\n", + wlc->pub->unit, idx); + } + } + } else + ASSERT(!status); + } + + if (wlc->pub->radio_disabled) { + wlc_radio_monitor_start(wlc); + return 0; + } + + /* wlc_bmac_up_prep has done wlc_corereset(). so clk is on, set it */ + wlc->clk = true; + + wlc_radio_monitor_stop(wlc); + + /* Set EDCF hostflags */ + if (EDCF_ENAB(wlc->pub)) { + wlc_mhf(wlc, MHF1, MHF1_EDCF, MHF1_EDCF, WLC_BAND_ALL); + } else { + wlc_mhf(wlc, MHF1, MHF1_EDCF, 0, WLC_BAND_ALL); + } + + if (WLC_WAR16165(wlc)) + wlc_mhf(wlc, MHF2, MHF2_PCISLOWCLKWAR, MHF2_PCISLOWCLKWAR, + WLC_BAND_ALL); + + wl_init(wlc->wl); + wlc->pub->up = true; + + if (wlc->bandinit_pending) { + wlc_suspend_mac_and_wait(wlc); + wlc_set_chanspec(wlc, wlc->default_bss->chanspec); + wlc->bandinit_pending = false; + wlc_enable_mac(wlc); + } + + wlc_bmac_up_finish(wlc->hw); + + /* other software states up after ISR is running */ + /* start APs that were to be brought up but are not up yet */ + /* if (AP_ENAB(wlc->pub)) wlc_restart_ap(wlc->ap); */ + + /* Program the TX wme params with the current settings */ + wlc_wme_retries_write(wlc); + + /* start one second watchdog timer */ + ASSERT(!wlc->WDarmed); + wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true); + wlc->WDarmed = true; + + /* ensure antenna config is up to date */ + wlc_stf_phy_txant_upd(wlc); + /* ensure LDPC config is in sync */ + wlc_ht_update_ldpc(wlc, wlc->stf->ldpc); + + return 0; +} + +/* Initialize the base precedence map for dequeueing from txq based on WME settings */ +static void wlc_tx_prec_map_init(struct wlc_info *wlc) +{ + wlc->tx_prec_map = WLC_PREC_BMP_ALL; + memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16)); + + /* For non-WME, both fifos have overlapping MAXPRIO. So just disable all precedences + * if either is full. + */ + if (!EDCF_ENAB(wlc->pub)) { + wlc->fifo2prec_map[TX_DATA_FIFO] = WLC_PREC_BMP_ALL; + wlc->fifo2prec_map[TX_CTL_FIFO] = WLC_PREC_BMP_ALL; + } else { + wlc->fifo2prec_map[TX_AC_BK_FIFO] = WLC_PREC_BMP_AC_BK; + wlc->fifo2prec_map[TX_AC_BE_FIFO] = WLC_PREC_BMP_AC_BE; + wlc->fifo2prec_map[TX_AC_VI_FIFO] = WLC_PREC_BMP_AC_VI; + wlc->fifo2prec_map[TX_AC_VO_FIFO] = WLC_PREC_BMP_AC_VO; + } +} + +static uint wlc_down_del_timer(struct wlc_info *wlc) +{ + uint callbacks = 0; + + return callbacks; +} + +/* + * Mark the interface nonoperational, stop the software mechanisms, + * disable the hardware, free any transient buffer state. + * Return a count of the number of driver callbacks still pending. + */ +uint wlc_down(struct wlc_info *wlc) +{ + + uint callbacks = 0; + int i; + bool dev_gone = false; + struct wlc_txq_info *qi; + + WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__); + + /* check if we are already in the going down path */ + if (wlc->going_down) { + WL_ERROR("wl%d: %s: Driver going down so return\n", + wlc->pub->unit, __func__); + return 0; + } + if (!wlc->pub->up) + return callbacks; + + /* in between, mpc could try to bring down again.. */ + wlc->going_down = true; + + callbacks += wlc_bmac_down_prep(wlc->hw); + + dev_gone = DEVICEREMOVED(wlc); + + /* Call any registered down handlers */ + for (i = 0; i < WLC_MAXMODULES; i++) { + if (wlc->modulecb[i].down_fn) + callbacks += + wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl); + } + + /* cancel the watchdog timer */ + if (wlc->WDarmed) { + if (!wl_del_timer(wlc->wl, wlc->wdtimer)) + callbacks++; + wlc->WDarmed = false; + } + /* cancel all other timers */ + callbacks += wlc_down_del_timer(wlc); + + /* interrupt must have been blocked */ + ASSERT((wlc->macintmask == 0) || !wlc->pub->up); + + wlc->pub->up = false; + + wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL); + + /* clear txq flow control */ + wlc_txflowcontrol_reset(wlc); + + /* flush tx queues */ + for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { + pktq_flush(wlc->osh, &qi->q, true, NULL, 0); + ASSERT(pktq_empty(&qi->q)); + } + + callbacks += wlc_bmac_down_finish(wlc->hw); + + /* wlc_bmac_down_finish has done wlc_coredisable(). so clk is off */ + wlc->clk = false; + + + /* Verify all packets are flushed from the driver */ + if (wlc->osh->pktalloced != 0) { + WL_ERROR("%d packets not freed at wlc_down!!!!!!\n", + wlc->osh->pktalloced); + } +#ifdef BCMDBG + /* Since all the packets should have been freed, + * all callbacks should have been called + */ + for (i = 1; i <= wlc->pub->tunables->maxpktcb; i++) + ASSERT(wlc->pkt_callback[i].fn == NULL); +#endif + wlc->going_down = false; + return callbacks; +} + +/* Set the current gmode configuration */ +int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) +{ + int ret = 0; + uint i; + wlc_rateset_t rs; + /* Default to 54g Auto */ + s8 shortslot = WLC_SHORTSLOT_AUTO; /* Advertise and use shortslot (-1/0/1 Auto/Off/On) */ + bool shortslot_restrict = false; /* Restrict association to stations that support shortslot + */ + bool ignore_bcns = true; /* Ignore legacy beacons on the same channel */ + bool ofdm_basic = false; /* Make 6, 12, and 24 basic rates */ + int preamble = WLC_PLCP_LONG; /* Advertise and use short preambles (-1/0/1 Auto/Off/On) */ + bool preamble_restrict = false; /* Restrict association to stations that support short + * preambles + */ + struct wlcband *band; + + /* if N-support is enabled, allow Gmode set as long as requested + * Gmode is not GMODE_LEGACY_B + */ + if (N_ENAB(wlc->pub) && gmode == GMODE_LEGACY_B) + return BCME_UNSUPPORTED; + + /* verify that we are dealing with 2G band and grab the band pointer */ + if (wlc->band->bandtype == WLC_BAND_2G) + band = wlc->band; + else if ((NBANDS(wlc) > 1) && + (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == WLC_BAND_2G)) + band = wlc->bandstate[OTHERBANDUNIT(wlc)]; + else + return BCME_BADBAND; + + /* Legacy or bust when no OFDM is supported by regulatory */ + if ((wlc_channel_locale_flags_in_band(wlc->cmi, band->bandunit) & + WLC_NO_OFDM) && (gmode != GMODE_LEGACY_B)) + return BCME_RANGE; + + /* update configuration value */ + if (config == true) + wlc_protection_upd(wlc, WLC_PROT_G_USER, gmode); + + /* Clear supported rates filter */ + memset(&wlc->sup_rates_override, 0, sizeof(wlc_rateset_t)); + + /* Clear rateset override */ + memset(&rs, 0, sizeof(wlc_rateset_t)); + + switch (gmode) { + case GMODE_LEGACY_B: + shortslot = WLC_SHORTSLOT_OFF; + wlc_rateset_copy(&gphy_legacy_rates, &rs); + + break; + + case GMODE_LRS: + if (AP_ENAB(wlc->pub)) + wlc_rateset_copy(&cck_rates, &wlc->sup_rates_override); + break; + + case GMODE_AUTO: + /* Accept defaults */ + break; + + case GMODE_ONLY: + ofdm_basic = true; + preamble = WLC_PLCP_SHORT; + preamble_restrict = true; + break; + + case GMODE_PERFORMANCE: + if (AP_ENAB(wlc->pub)) /* Put all rates into the Supported Rates element */ + wlc_rateset_copy(&cck_ofdm_rates, + &wlc->sup_rates_override); + + shortslot = WLC_SHORTSLOT_ON; + shortslot_restrict = true; + ofdm_basic = true; + preamble = WLC_PLCP_SHORT; + preamble_restrict = true; + break; + + default: + /* Error */ + WL_ERROR("wl%d: %s: invalid gmode %d\n", + wlc->pub->unit, __func__, gmode); + return BCME_UNSUPPORTED; + } + + /* + * If we are switching to gmode == GMODE_LEGACY_B, + * clean up rate info that may refer to OFDM rates. + */ + if ((gmode == GMODE_LEGACY_B) && (band->gmode != GMODE_LEGACY_B)) { + band->gmode = gmode; + if (band->rspec_override && !IS_CCK(band->rspec_override)) { + band->rspec_override = 0; + wlc_reprate_init(wlc); + } + if (band->mrspec_override && !IS_CCK(band->mrspec_override)) { + band->mrspec_override = 0; + } + } + + band->gmode = gmode; + + wlc->ignore_bcns = ignore_bcns; + + wlc->shortslot_override = shortslot; + + if (AP_ENAB(wlc->pub)) { + /* wlc->ap->shortslot_restrict = shortslot_restrict; */ + wlc->PLCPHdr_override = + (preamble != + WLC_PLCP_LONG) ? WLC_PLCP_SHORT : WLC_PLCP_AUTO; + } + + if ((AP_ENAB(wlc->pub) && preamble != WLC_PLCP_LONG) + || preamble == WLC_PLCP_SHORT) + wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE; + else + wlc->default_bss->capability &= ~WLAN_CAPABILITY_SHORT_PREAMBLE; + + /* Update shortslot capability bit for AP and IBSS */ + if ((AP_ENAB(wlc->pub) && shortslot == WLC_SHORTSLOT_AUTO) || + shortslot == WLC_SHORTSLOT_ON) + wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_SLOT_TIME; + else + wlc->default_bss->capability &= + ~WLAN_CAPABILITY_SHORT_SLOT_TIME; + + /* Use the default 11g rateset */ + if (!rs.count) + wlc_rateset_copy(&cck_ofdm_rates, &rs); + + if (ofdm_basic) { + for (i = 0; i < rs.count; i++) { + if (rs.rates[i] == WLC_RATE_6M + || rs.rates[i] == WLC_RATE_12M + || rs.rates[i] == WLC_RATE_24M) + rs.rates[i] |= WLC_RATE_FLAG; + } + } + + /* Set default bss rateset */ + wlc->default_bss->rateset.count = rs.count; + memcpy(wlc->default_bss->rateset.rates, rs.rates, + sizeof(wlc->default_bss->rateset.rates)); + + return ret; +} + +static int wlc_nmode_validate(struct wlc_info *wlc, s32 nmode) +{ + int err = 0; + + switch (nmode) { + + case OFF: + break; + + case AUTO: + case WL_11N_2x2: + case WL_11N_3x3: + if (!(WLC_PHY_11N_CAP(wlc->band))) + err = BCME_BADBAND; + break; + + default: + err = BCME_RANGE; + break; + } + + return err; +} + +int wlc_set_nmode(struct wlc_info *wlc, s32 nmode) +{ + uint i; + int err; + + err = wlc_nmode_validate(wlc, nmode); + ASSERT(err == 0); + if (err) + return err; + + switch (nmode) { + case OFF: + wlc->pub->_n_enab = OFF; + wlc->default_bss->flags &= ~WLC_BSS_HT; + /* delete the mcs rates from the default and hw ratesets */ + wlc_rateset_mcs_clear(&wlc->default_bss->rateset); + for (i = 0; i < NBANDS(wlc); i++) { + memset(wlc->bandstate[i]->hw_rateset.mcs, 0, + MCSSET_LEN); + if (IS_MCS(wlc->band->rspec_override)) { + wlc->bandstate[i]->rspec_override = 0; + wlc_reprate_init(wlc); + } + if (IS_MCS(wlc->band->mrspec_override)) + wlc->bandstate[i]->mrspec_override = 0; + } + break; + + case AUTO: + if (wlc->stf->txstreams == WL_11N_3x3) + nmode = WL_11N_3x3; + else + nmode = WL_11N_2x2; + case WL_11N_2x2: + case WL_11N_3x3: + ASSERT(WLC_PHY_11N_CAP(wlc->band)); + /* force GMODE_AUTO if NMODE is ON */ + wlc_set_gmode(wlc, GMODE_AUTO, true); + if (nmode == WL_11N_3x3) + wlc->pub->_n_enab = SUPPORT_HT; + else + wlc->pub->_n_enab = SUPPORT_11N; + wlc->default_bss->flags |= WLC_BSS_HT; + /* add the mcs rates to the default and hw ratesets */ + wlc_rateset_mcs_build(&wlc->default_bss->rateset, + wlc->stf->txstreams); + for (i = 0; i < NBANDS(wlc); i++) + memcpy(wlc->bandstate[i]->hw_rateset.mcs, + wlc->default_bss->rateset.mcs, MCSSET_LEN); + break; + + default: + ASSERT(0); + break; + } + + return err; +} + +static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg) +{ + wlc_rateset_t rs, new; + uint bandunit; + + memcpy(&rs, rs_arg, sizeof(wlc_rateset_t)); + + /* check for bad count value */ + if ((rs.count == 0) || (rs.count > WLC_NUMRATES)) + return BCME_BADRATESET; + + /* try the current band */ + bandunit = wlc->band->bandunit; + memcpy(&new, &rs, sizeof(wlc_rateset_t)); + if (wlc_rate_hwrs_filter_sort_validate + (&new, &wlc->bandstate[bandunit]->hw_rateset, true, + wlc->stf->txstreams)) + goto good; + + /* try the other band */ + if (IS_MBAND_UNLOCKED(wlc)) { + bandunit = OTHERBANDUNIT(wlc); + memcpy(&new, &rs, sizeof(wlc_rateset_t)); + if (wlc_rate_hwrs_filter_sort_validate(&new, + &wlc-> + bandstate[bandunit]-> + hw_rateset, true, + wlc->stf->txstreams)) + goto good; + } + + return BCME_ERROR; + + good: + /* apply new rateset */ + memcpy(&wlc->default_bss->rateset, &new, sizeof(wlc_rateset_t)); + memcpy(&wlc->bandstate[bandunit]->defrateset, &new, + sizeof(wlc_rateset_t)); + return 0; +} + +/* simplified integer set interface for common ioctl handler */ +int wlc_set(struct wlc_info *wlc, int cmd, int arg) +{ + return wlc_ioctl(wlc, cmd, (void *)&arg, sizeof(arg), NULL); +} + +/* simplified integer get interface for common ioctl handler */ +int wlc_get(struct wlc_info *wlc, int cmd, int *arg) +{ + return wlc_ioctl(wlc, cmd, arg, sizeof(int), NULL); +} + +static void wlc_ofdm_rateset_war(struct wlc_info *wlc) +{ + u8 r; + bool war = false; + + if (wlc->cfg->associated) + r = wlc->cfg->current_bss->rateset.rates[0]; + else + r = wlc->default_bss->rateset.rates[0]; + + wlc_phy_ofdm_rateset_war(wlc->band->pi, war); + + return; +} + +int +wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, + struct wlc_if *wlcif) +{ + return _wlc_ioctl(wlc, cmd, arg, len, wlcif); +} + +/* common ioctl handler. return: 0=ok, -1=error, positive=particular error */ +static int +_wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, + struct wlc_if *wlcif) +{ + int val, *pval; + bool bool_val; + int bcmerror; + d11regs_t *regs; + uint i; + struct scb *nextscb; + bool ta_ok; + uint band; + rw_reg_t *r; + wlc_bsscfg_t *bsscfg; + struct osl_info *osh; + wlc_bss_info_t *current_bss; + + /* update bsscfg pointer */ + bsscfg = NULL; /* XXX: Hack bsscfg to be size one and use this globally */ + current_bss = NULL; + + /* initialize the following to get rid of compiler warning */ + nextscb = NULL; + ta_ok = false; + band = 0; + r = NULL; + + /* If the device is turned off, then it's not "removed" */ + if (!wlc->pub->hw_off && DEVICEREMOVED(wlc)) { + WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); + wl_down(wlc->wl); + return BCME_ERROR; + } + + ASSERT(!(wlc->pub->hw_off && wlc->pub->up)); + + /* default argument is generic integer */ + pval = arg ? (int *)arg:NULL; + + /* This will prevent the misaligned access */ + if (pval && (u32) len >= sizeof(val)) + memcpy(&val, pval, sizeof(val)); + else + val = 0; + + /* bool conversion to avoid duplication below */ + bool_val = val != 0; + + if (cmd != WLC_SET_CHANNEL) + WL_NONE("WLC_IOCTL: cmd %d val 0x%x (%d) len %d\n", + cmd, (uint)val, val, len); + + bcmerror = 0; + regs = wlc->regs; + osh = wlc->osh; + + /* A few commands don't need any arguments; all the others do. */ + switch (cmd) { + case WLC_UP: + case WLC_OUT: + case WLC_DOWN: + case WLC_DISASSOC: + case WLC_RESTART: + case WLC_REBOOT: + case WLC_START_CHANNEL_QA: + case WLC_INIT: + break; + + default: + if ((arg == NULL) || (len <= 0)) { + WL_ERROR("wl%d: %s: Command %d needs arguments\n", + wlc->pub->unit, __func__, cmd); + bcmerror = BCME_BADARG; + goto done; + } + } + + switch (cmd) { + +#if defined(BCMDBG) + case WLC_GET_MSGLEVEL: + *pval = wl_msg_level; + break; + + case WLC_SET_MSGLEVEL: + wl_msg_level = val; + break; +#endif + + case WLC_GET_INSTANCE: + *pval = wlc->pub->unit; + break; + + case WLC_GET_CHANNEL:{ + channel_info_t *ci = (channel_info_t *) arg; + + ASSERT(len > (int)sizeof(ci)); + + ci->hw_channel = + CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC); + ci->target_channel = + CHSPEC_CHANNEL(wlc->default_bss->chanspec); + ci->scan_channel = 0; + + break; + } + + case WLC_SET_CHANNEL:{ + chanspec_t chspec = CH20MHZ_CHSPEC(val); + + if (val < 0 || val > MAXCHANNEL) { + bcmerror = BCME_OUTOFRANGECHAN; + break; + } + + if (!wlc_valid_chanspec_db(wlc->cmi, chspec)) { + bcmerror = BCME_BADCHAN; + break; + } + + if (!wlc->pub->up && IS_MBAND_UNLOCKED(wlc)) { + if (wlc->band->bandunit != + CHSPEC_WLCBANDUNIT(chspec)) + wlc->bandinit_pending = true; + else + wlc->bandinit_pending = false; + } + + wlc->default_bss->chanspec = chspec; + /* wlc_BSSinit() will sanitize the rateset before using it.. */ + if (wlc->pub->up && + (WLC_BAND_PI_RADIO_CHANSPEC != chspec)) { + wlc_set_home_chanspec(wlc, chspec); + wlc_suspend_mac_and_wait(wlc); + wlc_set_chanspec(wlc, chspec); + wlc_enable_mac(wlc); + } + break; + } + +#if defined(BCMDBG) + case WLC_GET_UCFLAGS: + if (!wlc->pub->up) { + bcmerror = BCME_NOTUP; + break; + } + + /* optional band is stored in the second integer of incoming buffer */ + band = + (len < + (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; + + /* bcmerror checking */ + bcmerror = wlc_iocregchk(wlc, band); + if (bcmerror) + break; + + if (val >= MHFMAX) { + bcmerror = BCME_RANGE; + break; + } + + *pval = wlc_bmac_mhf_get(wlc->hw, (u8) val, WLC_BAND_AUTO); + break; + + case WLC_SET_UCFLAGS: + if (!wlc->pub->up) { + bcmerror = BCME_NOTUP; + break; + } + + /* optional band is stored in the second integer of incoming buffer */ + band = + (len < + (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; + + /* bcmerror checking */ + bcmerror = wlc_iocregchk(wlc, band); + if (bcmerror) + break; + + i = (u16) val; + if (i >= MHFMAX) { + bcmerror = BCME_RANGE; + break; + } + + wlc_mhf(wlc, (u8) i, 0xffff, (u16) (val >> NBITS(u16)), + WLC_BAND_AUTO); + break; + + case WLC_GET_SHMEM: + ta_ok = true; + + /* optional band is stored in the second integer of incoming buffer */ + band = + (len < + (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; + + /* bcmerror checking */ + bcmerror = wlc_iocregchk(wlc, band); + if (bcmerror) + break; + + if (val & 1) { + bcmerror = BCME_BADADDR; + break; + } + + *pval = wlc_read_shm(wlc, (u16) val); + break; + + case WLC_SET_SHMEM: + ta_ok = true; + + /* optional band is stored in the second integer of incoming buffer */ + band = + (len < + (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; + + /* bcmerror checking */ + bcmerror = wlc_iocregchk(wlc, band); + if (bcmerror) + break; + + if (val & 1) { + bcmerror = BCME_BADADDR; + break; + } + + wlc_write_shm(wlc, (u16) val, + (u16) (val >> NBITS(u16))); + break; + + case WLC_R_REG: /* MAC registers */ + ta_ok = true; + r = (rw_reg_t *) arg; + band = WLC_BAND_AUTO; + + if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + if (len >= (int)sizeof(rw_reg_t)) + band = r->band; + + /* bcmerror checking */ + bcmerror = wlc_iocregchk(wlc, band); + if (bcmerror) + break; + + if ((r->byteoff + r->size) > sizeof(d11regs_t)) { + bcmerror = BCME_BADADDR; + break; + } + if (r->size == sizeof(u32)) + r->val = + R_REG((u32 *)((unsigned char *)(unsigned long)regs + + r->byteoff)); + else if (r->size == sizeof(u16)) + r->val = + R_REG((u16 *)((unsigned char *)(unsigned long)regs + + r->byteoff)); + else + bcmerror = BCME_BADADDR; + break; + + case WLC_W_REG: + ta_ok = true; + r = (rw_reg_t *) arg; + band = WLC_BAND_AUTO; + + if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + if (len >= (int)sizeof(rw_reg_t)) + band = r->band; + + /* bcmerror checking */ + bcmerror = wlc_iocregchk(wlc, band); + if (bcmerror) + break; + + if (r->byteoff + r->size > sizeof(d11regs_t)) { + bcmerror = BCME_BADADDR; + break; + } + if (r->size == sizeof(u32)) + W_REG((u32 *)((unsigned char *)(unsigned long) regs + + r->byteoff), r->val); + else if (r->size == sizeof(u16)) + W_REG((u16 *)((unsigned char *)(unsigned long) regs + + r->byteoff), r->val); + else + bcmerror = BCME_BADADDR; + break; +#endif /* BCMDBG */ + + case WLC_GET_TXANT: + *pval = wlc->stf->txant; + break; + + case WLC_SET_TXANT: + bcmerror = wlc_stf_ant_txant_validate(wlc, (s8) val); + if (bcmerror < 0) + break; + + wlc->stf->txant = (s8) val; + + /* if down, we are done */ + if (!wlc->pub->up) + break; + + wlc_suspend_mac_and_wait(wlc); + + wlc_stf_phy_txant_upd(wlc); + wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec); + + wlc_enable_mac(wlc); + + break; + + case WLC_GET_ANTDIV:{ + u8 phy_antdiv; + + /* return configured value if core is down */ + if (!wlc->pub->up) { + *pval = wlc->stf->ant_rx_ovr; + + } else { + if (wlc_phy_ant_rxdiv_get + (wlc->band->pi, &phy_antdiv)) + *pval = (int)phy_antdiv; + else + *pval = (int)wlc->stf->ant_rx_ovr; + } + + break; + } + case WLC_SET_ANTDIV: + /* values are -1=driver default, 0=force0, 1=force1, 2=start1, 3=start0 */ + if ((val < -1) || (val > 3)) { + bcmerror = BCME_RANGE; + break; + } + + if (val == -1) + val = ANT_RX_DIV_DEF; + + wlc->stf->ant_rx_ovr = (u8) val; + wlc_phy_ant_rxdiv_set(wlc->band->pi, (u8) val); + break; + + case WLC_GET_RX_ANT:{ /* get latest used rx antenna */ + u16 rxstatus; + + if (!wlc->pub->up) { + bcmerror = BCME_NOTUP; + break; + } + + rxstatus = R_REG(&wlc->regs->phyrxstatus0); + if (rxstatus == 0xdead || rxstatus == (u16) -1) { + bcmerror = BCME_ERROR; + break; + } + *pval = (rxstatus & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; + break; + } + +#if defined(BCMDBG) + case WLC_GET_UCANTDIV: + if (!wlc->clk) { + bcmerror = BCME_NOCLK; + break; + } + + *pval = + (wlc_bmac_mhf_get(wlc->hw, MHF1, WLC_BAND_AUTO) & + MHF1_ANTDIV); + break; + + case WLC_SET_UCANTDIV:{ + if (!wlc->pub->up) { + bcmerror = BCME_NOTUP; + break; + } + + /* if multiband, band must be locked */ + if (IS_MBAND_UNLOCKED(wlc)) { + bcmerror = BCME_NOTBANDLOCKED; + break; + } + + wlc_mhf(wlc, MHF1, MHF1_ANTDIV, + (val ? MHF1_ANTDIV : 0), WLC_BAND_AUTO); + break; + } +#endif /* defined(BCMDBG) */ + + case WLC_GET_SRL: + *pval = wlc->SRL; + break; + + case WLC_SET_SRL: + if (val >= 1 && val <= RETRY_SHORT_MAX) { + int ac; + wlc->SRL = (u16) val; + + wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); + + for (ac = 0; ac < AC_COUNT; ac++) { + WLC_WME_RETRY_SHORT_SET(wlc, ac, wlc->SRL); + } + wlc_wme_retries_write(wlc); + } else + bcmerror = BCME_RANGE; + break; + + case WLC_GET_LRL: + *pval = wlc->LRL; + break; + + case WLC_SET_LRL: + if (val >= 1 && val <= 255) { + int ac; + wlc->LRL = (u16) val; + + wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); + + for (ac = 0; ac < AC_COUNT; ac++) { + WLC_WME_RETRY_LONG_SET(wlc, ac, wlc->LRL); + } + wlc_wme_retries_write(wlc); + } else + bcmerror = BCME_RANGE; + break; + + case WLC_GET_CWMIN: + *pval = wlc->band->CWmin; + break; + + case WLC_SET_CWMIN: + if (!wlc->clk) { + bcmerror = BCME_NOCLK; + break; + } + + if (val >= 1 && val <= 255) { + wlc_set_cwmin(wlc, (u16) val); + } else + bcmerror = BCME_RANGE; + break; + + case WLC_GET_CWMAX: + *pval = wlc->band->CWmax; + break; + + case WLC_SET_CWMAX: + if (!wlc->clk) { + bcmerror = BCME_NOCLK; + break; + } + + if (val >= 255 && val <= 2047) { + wlc_set_cwmax(wlc, (u16) val); + } else + bcmerror = BCME_RANGE; + break; + + case WLC_GET_RADIO: /* use mask if don't want to expose some internal bits */ + *pval = wlc->pub->radio_disabled; + break; + + case WLC_SET_RADIO:{ /* 32 bits input, higher 16 bits are mask, lower 16 bits are value to + * set + */ + u16 radiomask, radioval; + uint validbits = + WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE; + mbool new = 0; + + radiomask = (val & 0xffff0000) >> 16; + radioval = val & 0x0000ffff; + + if ((radiomask == 0) || (radiomask & ~validbits) + || (radioval & ~validbits) + || ((radioval & ~radiomask) != 0)) { + WL_ERROR("SET_RADIO with wrong bits 0x%x\n", + val); + bcmerror = BCME_RANGE; + break; + } + + new = + (wlc->pub->radio_disabled & ~radiomask) | radioval; + wlc->pub->radio_disabled = new; + + wlc_radio_hwdisable_upd(wlc); + wlc_radio_upd(wlc); + break; + } + + case WLC_GET_PHYTYPE: + *pval = WLC_PHYTYPE(wlc->band->phytype); + break; + +#if defined(BCMDBG) + case WLC_GET_KEY: + if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc))) { + wl_wsec_key_t key; + + wsec_key_t *src_key = wlc->wsec_keys[val]; + + if (len < (int)sizeof(key)) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + memset((char *)&key, 0, sizeof(key)); + if (src_key) { + key.index = src_key->id; + key.len = src_key->len; + memcpy(key.data, src_key->data, key.len); + key.algo = src_key->algo; + if (WSEC_SOFTKEY(wlc, src_key, bsscfg)) + key.flags |= WL_SOFT_KEY; + if (src_key->flags & WSEC_PRIMARY_KEY) + key.flags |= WL_PRIMARY_KEY; + + memcpy(key.ea, src_key->ea, ETH_ALEN); + } + + memcpy(arg, &key, sizeof(key)); + } else + bcmerror = BCME_BADKEYIDX; + break; +#endif /* defined(BCMDBG) */ + + case WLC_SET_KEY: + bcmerror = + wlc_iovar_op(wlc, "wsec_key", NULL, 0, arg, len, IOV_SET, + wlcif); + break; + + case WLC_GET_KEY_SEQ:{ + wsec_key_t *key; + + if (len < DOT11_WPA_KEY_RSC_LEN) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + /* Return the key's tx iv as an EAPOL sequence counter. + * This will be used to supply the RSC value to a supplicant. + * The format is 8 bytes, with least significant in seq[0]. + */ + + key = WSEC_KEY(wlc, val); + if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc)) && + (key != NULL)) { + u8 seq[DOT11_WPA_KEY_RSC_LEN]; + u16 lo; + u32 hi; + /* group keys in WPA-NONE (IBSS only, AES and TKIP) use a global TXIV */ + if ((bsscfg->WPA_auth & WPA_AUTH_NONE) && + is_zero_ether_addr(key->ea)) { + lo = bsscfg->wpa_none_txiv.lo; + hi = bsscfg->wpa_none_txiv.hi; + } else { + lo = key->txiv.lo; + hi = key->txiv.hi; + } + + /* format the buffer, low to high */ + seq[0] = lo & 0xff; + seq[1] = (lo >> 8) & 0xff; + seq[2] = hi & 0xff; + seq[3] = (hi >> 8) & 0xff; + seq[4] = (hi >> 16) & 0xff; + seq[5] = (hi >> 24) & 0xff; + seq[6] = 0; + seq[7] = 0; + + memcpy(arg, seq, sizeof(seq)); + } else { + bcmerror = BCME_BADKEYIDX; + } + break; + } + + case WLC_GET_CURR_RATESET:{ + wl_rateset_t *ret_rs = (wl_rateset_t *) arg; + wlc_rateset_t *rs; + + if (bsscfg->associated) + rs = ¤t_bss->rateset; + else + rs = &wlc->default_bss->rateset; + + if (len < (int)(rs->count + sizeof(rs->count))) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + /* Copy only legacy rateset section */ + ret_rs->count = rs->count; + memcpy(&ret_rs->rates, &rs->rates, rs->count); + break; + } + + case WLC_GET_RATESET:{ + wlc_rateset_t rs; + wl_rateset_t *ret_rs = (wl_rateset_t *) arg; + + memset(&rs, 0, sizeof(wlc_rateset_t)); + wlc_default_rateset(wlc, (wlc_rateset_t *) &rs); + + if (len < (int)(rs.count + sizeof(rs.count))) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + /* Copy only legacy rateset section */ + ret_rs->count = rs.count; + memcpy(&ret_rs->rates, &rs.rates, rs.count); + break; + } + + case WLC_SET_RATESET:{ + wlc_rateset_t rs; + wl_rateset_t *in_rs = (wl_rateset_t *) arg; + + if (len < (int)(in_rs->count + sizeof(in_rs->count))) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + if (in_rs->count > WLC_NUMRATES) { + bcmerror = BCME_BUFTOOLONG; + break; + } + + memset(&rs, 0, sizeof(wlc_rateset_t)); + + /* Copy only legacy rateset section */ + rs.count = in_rs->count; + memcpy(&rs.rates, &in_rs->rates, rs.count); + + /* merge rateset coming in with the current mcsset */ + if (N_ENAB(wlc->pub)) { + if (bsscfg->associated) + memcpy(rs.mcs, + ¤t_bss->rateset.mcs[0], + MCSSET_LEN); + else + memcpy(rs.mcs, + &wlc->default_bss->rateset.mcs[0], + MCSSET_LEN); + } + + bcmerror = wlc_set_rateset(wlc, &rs); + + if (!bcmerror) + wlc_ofdm_rateset_war(wlc); + + break; + } + + case WLC_GET_BCNPRD: + if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated) + *pval = current_bss->beacon_period; + else + *pval = wlc->default_bss->beacon_period; + break; + + case WLC_SET_BCNPRD: + /* range [1, 0xffff] */ + if (val >= DOT11_MIN_BEACON_PERIOD + && val <= DOT11_MAX_BEACON_PERIOD) { + wlc->default_bss->beacon_period = (u16) val; + } else + bcmerror = BCME_RANGE; + break; + + case WLC_GET_DTIMPRD: + if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated) + *pval = current_bss->dtim_period; + else + *pval = wlc->default_bss->dtim_period; + break; + + case WLC_SET_DTIMPRD: + /* range [1, 0xff] */ + if (val >= DOT11_MIN_DTIM_PERIOD + && val <= DOT11_MAX_DTIM_PERIOD) { + wlc->default_bss->dtim_period = (u8) val; + } else + bcmerror = BCME_RANGE; + break; + +#ifdef SUPPORT_PS + case WLC_GET_PM: + *pval = wlc->PM; + break; + + case WLC_SET_PM: + if ((val >= PM_OFF) && (val <= PM_MAX)) { + wlc->PM = (u8) val; + if (wlc->pub->up) { + } + /* Change watchdog driver to align watchdog with tbtt if possible */ + wlc_watchdog_upd(wlc, PS_ALLOWED(wlc)); + } else + bcmerror = BCME_ERROR; + break; +#endif /* SUPPORT_PS */ + +#ifdef SUPPORT_PS +#ifdef BCMDBG + case WLC_GET_WAKE: + if (AP_ENAB(wlc->pub)) { + bcmerror = BCME_NOTSTA; + break; + } + *pval = wlc->wake; + break; + + case WLC_SET_WAKE: + if (AP_ENAB(wlc->pub)) { + bcmerror = BCME_NOTSTA; + break; + } + + wlc->wake = val ? true : false; + + /* if down, we're done */ + if (!wlc->pub->up) + break; + + /* apply to the mac */ + wlc_set_ps_ctrl(wlc); + break; +#endif /* BCMDBG */ +#endif /* SUPPORT_PS */ + + case WLC_GET_REVINFO: + bcmerror = wlc_get_revision_info(wlc, arg, (uint) len); + break; + + case WLC_GET_AP: + *pval = (int)AP_ENAB(wlc->pub); + break; + + case WLC_GET_ATIM: + if (bsscfg->associated) + *pval = (int)current_bss->atim_window; + else + *pval = (int)wlc->default_bss->atim_window; + break; + + case WLC_SET_ATIM: + wlc->default_bss->atim_window = (u32) val; + break; + + case WLC_GET_PKTCNTS:{ + get_pktcnt_t *pktcnt = (get_pktcnt_t *) pval; + wlc_statsupd(wlc); + pktcnt->rx_good_pkt = wlc->pub->_cnt->rxframe; + pktcnt->rx_bad_pkt = wlc->pub->_cnt->rxerror; + pktcnt->tx_good_pkt = + wlc->pub->_cnt->txfrmsnt; + pktcnt->tx_bad_pkt = + wlc->pub->_cnt->txerror + + wlc->pub->_cnt->txfail; + if (len >= (int)sizeof(get_pktcnt_t)) { + /* Be backward compatible - only if buffer is large enough */ + pktcnt->rx_ocast_good_pkt = + wlc->pub->_cnt->rxmfrmocast; + } + break; + } + +#ifdef SUPPORT_HWKEY + case WLC_GET_WSEC: + bcmerror = + wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_GET, + wlcif); + break; + + case WLC_SET_WSEC: + bcmerror = + wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_SET, + wlcif); + break; + + case WLC_GET_WPA_AUTH: + *pval = (int)bsscfg->WPA_auth; + break; + + case WLC_SET_WPA_AUTH: + /* change of WPA_Auth modifies the PS_ALLOWED state */ + if (BSSCFG_STA(bsscfg)) { + bsscfg->WPA_auth = (u16) val; + } else + bsscfg->WPA_auth = (u16) val; + break; +#endif /* SUPPORT_HWKEY */ + + case WLC_GET_BANDLIST: + /* count of number of bands, followed by each band type */ + *pval++ = NBANDS(wlc); + *pval++ = wlc->band->bandtype; + if (NBANDS(wlc) > 1) + *pval++ = wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype; + break; + + case WLC_GET_BAND: + *pval = wlc->bandlocked ? wlc->band->bandtype : WLC_BAND_AUTO; + break; + + case WLC_GET_PHYLIST: + { + unsigned char *cp = arg; + if (len < 3) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + + if (WLCISNPHY(wlc->band)) { + *cp++ = 'n'; + } else if (WLCISLCNPHY(wlc->band)) { + *cp++ = 'c'; + } else if (WLCISSSLPNPHY(wlc->band)) { + *cp++ = 's'; + } + *cp = '\0'; + break; + } + + case WLC_GET_SHORTSLOT: + *pval = wlc->shortslot; + break; + + case WLC_GET_SHORTSLOT_OVERRIDE: + *pval = wlc->shortslot_override; + break; + + case WLC_SET_SHORTSLOT_OVERRIDE: + if ((val != WLC_SHORTSLOT_AUTO) && + (val != WLC_SHORTSLOT_OFF) && (val != WLC_SHORTSLOT_ON)) { + bcmerror = BCME_RANGE; + break; + } + + wlc->shortslot_override = (s8) val; + + /* shortslot is an 11g feature, so no more work if we are + * currently on the 5G band + */ + if (BAND_5G(wlc->band->bandtype)) + break; + + if (wlc->pub->up && wlc->pub->associated) { + /* let watchdog or beacon processing update shortslot */ + } else if (wlc->pub->up) { + /* unassociated shortslot is off */ + wlc_switch_shortslot(wlc, false); + } else { + /* driver is down, so just update the wlc_info value */ + if (wlc->shortslot_override == WLC_SHORTSLOT_AUTO) { + wlc->shortslot = false; + } else { + wlc->shortslot = + (wlc->shortslot_override == + WLC_SHORTSLOT_ON); + } + } + + break; + + case WLC_GET_LEGACY_ERP: + *pval = wlc->include_legacy_erp; + break; + + case WLC_SET_LEGACY_ERP: + if (wlc->include_legacy_erp == bool_val) + break; + + wlc->include_legacy_erp = bool_val; + + if (AP_ENAB(wlc->pub) && wlc->clk) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, true); + } + break; + + case WLC_GET_GMODE: + if (wlc->band->bandtype == WLC_BAND_2G) + *pval = wlc->band->gmode; + else if (NBANDS(wlc) > 1) + *pval = wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode; + break; + + case WLC_SET_GMODE: + if (!wlc->pub->associated) + bcmerror = wlc_set_gmode(wlc, (u8) val, true); + else { + bcmerror = BCME_ASSOCIATED; + break; + } + break; + + case WLC_GET_GMODE_PROTECTION: + *pval = wlc->protection->_g; + break; + + case WLC_GET_PROTECTION_CONTROL: + *pval = wlc->protection->overlap; + break; + + case WLC_SET_PROTECTION_CONTROL: + if ((val != WLC_PROTECTION_CTL_OFF) && + (val != WLC_PROTECTION_CTL_LOCAL) && + (val != WLC_PROTECTION_CTL_OVERLAP)) { + bcmerror = BCME_RANGE; + break; + } + + wlc_protection_upd(wlc, WLC_PROT_OVERLAP, (s8) val); + + /* Current g_protection will sync up to the specified control alg in watchdog + * if the driver is up and associated. + * If the driver is down or not associated, the control setting has no effect. + */ + break; + + case WLC_GET_GMODE_PROTECTION_OVERRIDE: + *pval = wlc->protection->g_override; + break; + + case WLC_SET_GMODE_PROTECTION_OVERRIDE: + if ((val != WLC_PROTECTION_AUTO) && + (val != WLC_PROTECTION_OFF) && (val != WLC_PROTECTION_ON)) { + bcmerror = BCME_RANGE; + break; + } + + wlc_protection_upd(wlc, WLC_PROT_G_OVR, (s8) val); + + break; + + case WLC_SET_SUP_RATESET_OVERRIDE:{ + wlc_rateset_t rs, new; + + /* copyin */ + if (len < (int)sizeof(wlc_rateset_t)) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + memcpy(&rs, arg, sizeof(wlc_rateset_t)); + + /* check for bad count value */ + if (rs.count > WLC_NUMRATES) { + bcmerror = BCME_BADRATESET; /* invalid rateset */ + break; + } + + /* this command is only appropriate for gmode operation */ + if (!(wlc->band->gmode || + ((NBANDS(wlc) > 1) + && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) { + bcmerror = BCME_BADBAND; /* gmode only command when not in gmode */ + break; + } + + /* check for an empty rateset to clear the override */ + if (rs.count == 0) { + memset(&wlc->sup_rates_override, 0, + sizeof(wlc_rateset_t)); + break; + } + + /* validate rateset by comparing pre and post sorted against 11g hw rates */ + wlc_rateset_filter(&rs, &new, false, WLC_RATES_CCK_OFDM, + RATE_MASK, BSS_N_ENAB(wlc, bsscfg)); + wlc_rate_hwrs_filter_sort_validate(&new, + &cck_ofdm_rates, + false, + wlc->stf->txstreams); + if (rs.count != new.count) { + bcmerror = BCME_BADRATESET; /* invalid rateset */ + break; + } + + /* apply new rateset to the override */ + memcpy(&wlc->sup_rates_override, &new, + sizeof(wlc_rateset_t)); + + /* update bcn and probe resp if needed */ + if (wlc->pub->up && AP_ENAB(wlc->pub) + && wlc->pub->associated) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, true); + } + break; + } + + case WLC_GET_SUP_RATESET_OVERRIDE: + /* this command is only appropriate for gmode operation */ + if (!(wlc->band->gmode || + ((NBANDS(wlc) > 1) + && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) { + bcmerror = BCME_BADBAND; /* gmode only command when not in gmode */ + break; + } + if (len < (int)sizeof(wlc_rateset_t)) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + memcpy(arg, &wlc->sup_rates_override, sizeof(wlc_rateset_t)); + + break; + + case WLC_GET_PRB_RESP_TIMEOUT: + *pval = wlc->prb_resp_timeout; + break; + + case WLC_SET_PRB_RESP_TIMEOUT: + if (wlc->pub->up) { + bcmerror = BCME_NOTDOWN; + break; + } + if (val < 0 || val >= 0xFFFF) { + bcmerror = BCME_RANGE; /* bad value */ + break; + } + wlc->prb_resp_timeout = (u16) val; + break; + + case WLC_GET_KEY_PRIMARY:{ + wsec_key_t *key; + + /* treat the 'val' parm as the key id */ + key = WSEC_BSS_DEFAULT_KEY(bsscfg); + if (key != NULL) { + *pval = key->id == val ? true : false; + } else { + bcmerror = BCME_BADKEYIDX; + } + break; + } + + case WLC_SET_KEY_PRIMARY:{ + wsec_key_t *key, *old_key; + + bcmerror = BCME_BADKEYIDX; + + /* treat the 'val' parm as the key id */ + for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) { + key = bsscfg->bss_def_keys[i]; + if (key != NULL && key->id == val) { + old_key = WSEC_BSS_DEFAULT_KEY(bsscfg); + if (old_key != NULL) + old_key->flags &= + ~WSEC_PRIMARY_KEY; + key->flags |= WSEC_PRIMARY_KEY; + bsscfg->wsec_index = i; + bcmerror = BCME_OK; + } + } + break; + } + +#ifdef BCMDBG + case WLC_INIT: + wl_init(wlc->wl); + break; +#endif + + case WLC_SET_VAR: + case WLC_GET_VAR:{ + char *name; + /* validate the name value */ + name = (char *)arg; + for (i = 0; i < (uint) len && *name != '\0'; + i++, name++) + ; + + if (i == (uint) len) { + bcmerror = BCME_BUFTOOSHORT; + break; + } + i++; /* include the null in the string length */ + + if (cmd == WLC_GET_VAR) { + bcmerror = + wlc_iovar_op(wlc, arg, + (void *)((s8 *) arg + i), + len - i, arg, len, IOV_GET, + wlcif); + } else + bcmerror = + wlc_iovar_op(wlc, arg, NULL, 0, + (void *)((s8 *) arg + i), + len - i, IOV_SET, wlcif); + + break; + } + + case WLC_SET_WSEC_PMK: + bcmerror = BCME_UNSUPPORTED; + break; + +#if defined(BCMDBG) + case WLC_CURRENT_PWR: + if (!wlc->pub->up) + bcmerror = BCME_NOTUP; + else + bcmerror = wlc_get_current_txpwr(wlc, arg, len); + break; +#endif + + case WLC_LAST: + WL_ERROR("%s: WLC_LAST\n", __func__); + } + done: + + if (bcmerror) { + if (VALID_BCMERROR(bcmerror)) + wlc->pub->bcmerror = bcmerror; + else { + bcmerror = 0; + } + + } + /* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */ + /* In hw_off condition, IOCTLs that reach here are deemed safe but taclear would + * certainly result in getting -1 for register reads. So skip ta_clear altogether + */ + if (!(wlc->pub->hw_off)) + ASSERT(wlc_bmac_taclear(wlc->hw, ta_ok) || !ta_ok); + + return bcmerror; +} + +#if defined(BCMDBG) +/* consolidated register access ioctl error checking */ +int wlc_iocregchk(struct wlc_info *wlc, uint band) +{ + /* if band is specified, it must be the current band */ + if ((band != WLC_BAND_AUTO) && (band != (uint) wlc->band->bandtype)) + return BCME_BADBAND; + + /* if multiband and band is not specified, band must be locked */ + if ((band == WLC_BAND_AUTO) && IS_MBAND_UNLOCKED(wlc)) + return BCME_NOTBANDLOCKED; + + /* must have core clocks */ + if (!wlc->clk) + return BCME_NOCLK; + + return 0; +} +#endif /* defined(BCMDBG) */ + +#if defined(BCMDBG) +/* For some ioctls, make sure that the pi pointer matches the current phy */ +int wlc_iocpichk(struct wlc_info *wlc, uint phytype) +{ + if (wlc->band->phytype != phytype) + return BCME_BADBAND; + return 0; +} +#endif + +/* Look up the given var name in the given table */ +static const bcm_iovar_t *wlc_iovar_lookup(const bcm_iovar_t *table, + const char *name) +{ + const bcm_iovar_t *vi; + const char *lookup_name; + + /* skip any ':' delimited option prefixes */ + lookup_name = strrchr(name, ':'); + if (lookup_name != NULL) + lookup_name++; + else + lookup_name = name; + + ASSERT(table != NULL); + + for (vi = table; vi->name; vi++) { + if (!strcmp(vi->name, lookup_name)) + return vi; + } + /* ran to end of table */ + + return NULL; /* var name not found */ +} + +/* simplified integer get interface for common WLC_GET_VAR ioctl handler */ +int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg) +{ + return wlc_iovar_op(wlc, name, NULL, 0, arg, sizeof(s32), IOV_GET, + NULL); +} + +/* simplified integer set interface for common WLC_SET_VAR ioctl handler */ +int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg) +{ + return wlc_iovar_op(wlc, name, NULL, 0, (void *)&arg, sizeof(arg), + IOV_SET, NULL); +} + +/* simplified s8 get interface for common WLC_GET_VAR ioctl handler */ +int wlc_iovar_gets8(struct wlc_info *wlc, const char *name, s8 *arg) +{ + int iovar_int; + int err; + + err = + wlc_iovar_op(wlc, name, NULL, 0, &iovar_int, sizeof(iovar_int), + IOV_GET, NULL); + if (!err) + *arg = (s8) iovar_int; + + return err; +} + +/* + * register iovar table, watchdog and down handlers. + * calling function must keep 'iovars' until wlc_module_unregister is called. + * 'iovar' must have the last entry's name field being NULL as terminator. + */ +int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, + const char *name, void *hdl, iovar_fn_t i_fn, + watchdog_fn_t w_fn, down_fn_t d_fn) +{ + struct wlc_info *wlc = (struct wlc_info *) pub->wlc; + int i; + + ASSERT(name != NULL); + ASSERT(i_fn != NULL || w_fn != NULL || d_fn != NULL); + + /* find an empty entry and just add, no duplication check! */ + for (i = 0; i < WLC_MAXMODULES; i++) { + if (wlc->modulecb[i].name[0] == '\0') { + strncpy(wlc->modulecb[i].name, name, + sizeof(wlc->modulecb[i].name) - 1); + wlc->modulecb[i].iovars = iovars; + wlc->modulecb[i].hdl = hdl; + wlc->modulecb[i].iovar_fn = i_fn; + wlc->modulecb[i].watchdog_fn = w_fn; + wlc->modulecb[i].down_fn = d_fn; + return 0; + } + } + + /* it is time to increase the capacity */ + ASSERT(i < WLC_MAXMODULES); + return BCME_NORESOURCE; +} + +/* unregister module callbacks */ +int wlc_module_unregister(struct wlc_pub *pub, const char *name, void *hdl) +{ + struct wlc_info *wlc = (struct wlc_info *) pub->wlc; + int i; + + if (wlc == NULL) + return BCME_NOTFOUND; + + ASSERT(name != NULL); + + for (i = 0; i < WLC_MAXMODULES; i++) { + if (!strcmp(wlc->modulecb[i].name, name) && + (wlc->modulecb[i].hdl == hdl)) { + memset(&wlc->modulecb[i], 0, sizeof(struct modulecb)); + return 0; + } + } + + /* table not found! */ + return BCME_NOTFOUND; +} + +/* Write WME tunable parameters for retransmit/max rate from wlc struct to ucode */ +static void wlc_wme_retries_write(struct wlc_info *wlc) +{ + int ac; + + /* Need clock to do this */ + if (!wlc->clk) + return; + + for (ac = 0; ac < AC_COUNT; ac++) { + wlc_write_shm(wlc, M_AC_TXLMT_ADDR(ac), wlc->wme_retries[ac]); + } +} + +/* Get or set an iovar. The params/p_len pair specifies any additional + * qualifying parameters (e.g. an "element index") for a get, while the + * arg/len pair is the buffer for the value to be set or retrieved. + * Operation (get/set) is specified by the last argument. + * interface context provided by wlcif + * + * All pointers may point into the same buffer. + */ +int +wlc_iovar_op(struct wlc_info *wlc, const char *name, + void *params, int p_len, void *arg, int len, + bool set, struct wlc_if *wlcif) +{ + int err = 0; + int val_size; + const bcm_iovar_t *vi = NULL; + u32 actionid; + int i; + + ASSERT(name != NULL); + + ASSERT(len >= 0); + + /* Get MUST have return space */ + ASSERT(set || (arg && len)); + + ASSERT(!(wlc->pub->hw_off && wlc->pub->up)); + + /* Set does NOT take qualifiers */ + ASSERT(!set || (!params && !p_len)); + + if (!set && (len == sizeof(int)) && + !(IS_ALIGNED((unsigned long)(arg), (uint) sizeof(int)))) { + WL_ERROR("wl%d: %s unaligned get ptr for %s\n", + wlc->pub->unit, __func__, name); + ASSERT(0); + } + + /* find the given iovar name */ + for (i = 0; i < WLC_MAXMODULES; i++) { + if (!wlc->modulecb[i].iovars) + continue; + vi = wlc_iovar_lookup(wlc->modulecb[i].iovars, name); + if (vi) + break; + } + /* iovar name not found */ + if (i >= WLC_MAXMODULES) { + err = BCME_UNSUPPORTED; + goto exit; + } + + /* set up 'params' pointer in case this is a set command so that + * the convenience int and bool code can be common to set and get + */ + if (params == NULL) { + params = arg; + p_len = len; + } + + if (vi->type == IOVT_VOID) + val_size = 0; + else if (vi->type == IOVT_BUFFER) + val_size = len; + else + /* all other types are integer sized */ + val_size = sizeof(int); + + actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); + + /* Do the actual parameter implementation */ + err = wlc->modulecb[i].iovar_fn(wlc->modulecb[i].hdl, vi, actionid, + name, params, p_len, arg, len, val_size, + wlcif); + + exit: + return err; +} + +int +wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, void *arg, int len, + bool set) +{ + struct wlc_info *wlc = (struct wlc_info *) pub->wlc; + int err = 0; + s32 int_val = 0; + + /* check generic condition flags */ + if (set) { + if (((vi->flags & IOVF_SET_DOWN) && wlc->pub->up) || + ((vi->flags & IOVF_SET_UP) && !wlc->pub->up)) { + err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP); + } else if ((vi->flags & IOVF_SET_BAND) + && IS_MBAND_UNLOCKED(wlc)) { + err = BCME_NOTBANDLOCKED; + } else if ((vi->flags & IOVF_SET_CLK) && !wlc->clk) { + err = BCME_NOCLK; + } + } else { + if (((vi->flags & IOVF_GET_DOWN) && wlc->pub->up) || + ((vi->flags & IOVF_GET_UP) && !wlc->pub->up)) { + err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP); + } else if ((vi->flags & IOVF_GET_BAND) + && IS_MBAND_UNLOCKED(wlc)) { + err = BCME_NOTBANDLOCKED; + } else if ((vi->flags & IOVF_GET_CLK) && !wlc->clk) { + err = BCME_NOCLK; + } + } + + if (err) + goto exit; + + /* length check on io buf */ + err = bcm_iovar_lencheck(vi, arg, len, set); + if (err) + goto exit; + + /* On set, check value ranges for integer types */ + if (set) { + switch (vi->type) { + case IOVT_BOOL: + case IOVT_INT8: + case IOVT_INT16: + case IOVT_INT32: + case IOVT_UINT8: + case IOVT_UINT16: + case IOVT_UINT32: + memcpy(&int_val, arg, sizeof(int)); + err = wlc_iovar_rangecheck(wlc, int_val, vi); + break; + } + } + exit: + return err; +} + +/* handler for iovar table wlc_iovars */ +/* + * IMPLEMENTATION NOTE: In order to avoid checking for get/set in each + * iovar case, the switch statement maps the iovar id into separate get + * and set values. If you add a new iovar to the switch you MUST use + * IOV_GVAL and/or IOV_SVAL in the case labels to avoid conflict with + * another case. + * Please use params for additional qualifying parameters. + */ +int +wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, + const char *name, void *params, uint p_len, void *arg, int len, + int val_size, struct wlc_if *wlcif) +{ + struct wlc_info *wlc = hdl; + wlc_bsscfg_t *bsscfg; + int err = 0; + s32 int_val = 0; + s32 int_val2 = 0; + s32 *ret_int_ptr; + bool bool_val; + bool bool_val2; + wlc_bss_info_t *current_bss; + + WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__); + + bsscfg = NULL; + current_bss = NULL; + + err = wlc_iovar_check(wlc->pub, vi, arg, len, IOV_ISSET(actionid)); + if (err != 0) + return err; + + /* convenience int and bool vals for first 8 bytes of buffer */ + if (p_len >= (int)sizeof(int_val)) + memcpy(&int_val, params, sizeof(int_val)); + + if (p_len >= (int)sizeof(int_val) * 2) + memcpy(&int_val2, + (void *)((unsigned long)params + sizeof(int_val)), + sizeof(int_val)); + + /* convenience int ptr for 4-byte gets (requires int aligned arg) */ + ret_int_ptr = (s32 *) arg; + + bool_val = (int_val != 0) ? true : false; + bool_val2 = (int_val2 != 0) ? true : false; + + WL_TRACE("wl%d: %s: id %d\n", + wlc->pub->unit, __func__, IOV_ID(actionid)); + /* Do the actual parameter implementation */ + switch (actionid) { + case IOV_SVAL(IOV_RTSTHRESH): + wlc->RTSThresh = int_val; + break; + + case IOV_GVAL(IOV_QTXPOWER):{ + uint qdbm; + bool override; + + err = wlc_phy_txpower_get(wlc->band->pi, &qdbm, + &override); + if (err != BCME_OK) + return err; + + /* Return qdbm units */ + *ret_int_ptr = + qdbm | (override ? WL_TXPWR_OVERRIDE : 0); + break; + } + + /* As long as override is false, this only sets the *user* targets. + User can twiddle this all he wants with no harm. + wlc_phy_txpower_set() explicitly sets override to false if + not internal or test. + */ + case IOV_SVAL(IOV_QTXPOWER):{ + u8 qdbm; + bool override; + + /* Remove override bit and clip to max qdbm value */ + qdbm = (u8)min_t(u32, (int_val & ~WL_TXPWR_OVERRIDE), 0xff); + /* Extract override setting */ + override = (int_val & WL_TXPWR_OVERRIDE) ? true : false; + err = + wlc_phy_txpower_set(wlc->band->pi, qdbm, override); + break; + } + + case IOV_GVAL(IOV_MPC): + *ret_int_ptr = (s32) wlc->mpc; + break; + + case IOV_SVAL(IOV_MPC): + wlc->mpc = bool_val; + wlc_radio_mpc_upd(wlc); + + break; + + case IOV_GVAL(IOV_BCN_LI_BCN): + *ret_int_ptr = wlc->bcn_li_bcn; + break; + + case IOV_SVAL(IOV_BCN_LI_BCN): + wlc->bcn_li_bcn = (u8) int_val; + if (wlc->pub->up) + wlc_bcn_li_upd(wlc); + break; + + default: + WL_ERROR("wl%d: %s: unsupported\n", wlc->pub->unit, __func__); + err = BCME_UNSUPPORTED; + break; + } + + goto exit; /* avoid unused label warning */ + + exit: + return err; +} + +static int +wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, const bcm_iovar_t *vi) +{ + int err = 0; + u32 min_val = 0; + u32 max_val = 0; + + /* Only ranged integers are checked */ + switch (vi->type) { + case IOVT_INT32: + max_val |= 0x7fffffff; + /* fall through */ + case IOVT_INT16: + max_val |= 0x00007fff; + /* fall through */ + case IOVT_INT8: + max_val |= 0x0000007f; + min_val = ~max_val; + if (vi->flags & IOVF_NTRL) + min_val = 1; + else if (vi->flags & IOVF_WHL) + min_val = 0; + /* Signed values are checked against max_val and min_val */ + if ((s32) val < (s32) min_val + || (s32) val > (s32) max_val) + err = BCME_RANGE; + break; + + case IOVT_UINT32: + max_val |= 0xffffffff; + /* fall through */ + case IOVT_UINT16: + max_val |= 0x0000ffff; + /* fall through */ + case IOVT_UINT8: + max_val |= 0x000000ff; + if (vi->flags & IOVF_NTRL) + min_val = 1; + if ((val < min_val) || (val > max_val)) + err = BCME_RANGE; + break; + } + + return err; +} + +#ifdef BCMDBG +static const char *supr_reason[] = { + "None", "PMQ Entry", "Flush request", + "Previous frag failure", "Channel mismatch", + "Lifetime Expiry", "Underflow" +}; + +static void wlc_print_txs_status(u16 s) +{ + printk(KERN_DEBUG "[15:12] %d frame attempts\n", + (s & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT); + printk(KERN_DEBUG " [11:8] %d rts attempts\n", + (s & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT); + printk(KERN_DEBUG " [7] %d PM mode indicated\n", + ((s & TX_STATUS_PMINDCTD) ? 1 : 0)); + printk(KERN_DEBUG " [6] %d intermediate status\n", + ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0)); + printk(KERN_DEBUG " [5] %d AMPDU\n", + (s & TX_STATUS_AMPDU) ? 1 : 0); + printk(KERN_DEBUG " [4:2] %d Frame Suppressed Reason (%s)\n", + ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT), + supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]); + printk(KERN_DEBUG " [1] %d acked\n", + ((s & TX_STATUS_ACK_RCV) ? 1 : 0)); +} +#endif /* BCMDBG */ + +void wlc_print_txstatus(tx_status_t *txs) +{ +#if defined(BCMDBG) + u16 s = txs->status; + u16 ackphyrxsh = txs->ackphyrxsh; + + printk(KERN_DEBUG "\ntxpkt (MPDU) Complete\n"); + + printk(KERN_DEBUG "FrameID: %04x ", txs->frameid); + printk(KERN_DEBUG "TxStatus: %04x", s); + printk(KERN_DEBUG "\n"); + + wlc_print_txs_status(s); + + printk(KERN_DEBUG "LastTxTime: %04x ", txs->lasttxtime); + printk(KERN_DEBUG "Seq: %04x ", txs->sequence); + printk(KERN_DEBUG "PHYTxStatus: %04x ", txs->phyerr); + printk(KERN_DEBUG "RxAckRSSI: %04x ", + (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT); + printk(KERN_DEBUG "RxAckSQ: %04x", + (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); + printk(KERN_DEBUG "\n"); +#endif /* defined(BCMDBG) */ +} + +static void +wlc_ctrupd_cache(u16 cur_stat, u16 *macstat_snapshot, u32 *macstat) +{ + u16 v; + u16 delta; + + v = le16_to_cpu(cur_stat); + delta = (u16)(v - *macstat_snapshot); + + if (delta != 0) { + *macstat += delta; + *macstat_snapshot = v; + } +} + +#define MACSTATUPD(name) \ + wlc_ctrupd_cache(macstats.name, &wlc->core->macstat_snapshot->name, &wlc->pub->_cnt->name) + +void wlc_statsupd(struct wlc_info *wlc) +{ + int i; + macstat_t macstats; +#ifdef BCMDBG + u16 delta; + u16 rxf0ovfl; + u16 txfunfl[NFIFO]; +#endif /* BCMDBG */ + + /* if driver down, make no sense to update stats */ + if (!wlc->pub->up) + return; + +#ifdef BCMDBG + /* save last rx fifo 0 overflow count */ + rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl; + + /* save last tx fifo underflow count */ + for (i = 0; i < NFIFO; i++) + txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i]; +#endif /* BCMDBG */ + + /* Read mac stats from contiguous shared memory */ + wlc_bmac_copyfrom_shm(wlc->hw, M_UCODE_MACSTAT, + &macstats, sizeof(macstat_t)); + + /* update mac stats */ + MACSTATUPD(txallfrm); + MACSTATUPD(txrtsfrm); + MACSTATUPD(txctsfrm); + MACSTATUPD(txackfrm); + MACSTATUPD(txdnlfrm); + MACSTATUPD(txbcnfrm); + for (i = 0; i < NFIFO; i++) + MACSTATUPD(txfunfl[i]); + MACSTATUPD(txtplunfl); + MACSTATUPD(txphyerr); + MACSTATUPD(rxfrmtoolong); + MACSTATUPD(rxfrmtooshrt); + MACSTATUPD(rxinvmachdr); + MACSTATUPD(rxbadfcs); + MACSTATUPD(rxbadplcp); + MACSTATUPD(rxcrsglitch); + MACSTATUPD(rxstrt); + MACSTATUPD(rxdfrmucastmbss); + MACSTATUPD(rxmfrmucastmbss); + MACSTATUPD(rxcfrmucast); + MACSTATUPD(rxrtsucast); + MACSTATUPD(rxctsucast); + MACSTATUPD(rxackucast); + MACSTATUPD(rxdfrmocast); + MACSTATUPD(rxmfrmocast); + MACSTATUPD(rxcfrmocast); + MACSTATUPD(rxrtsocast); + MACSTATUPD(rxctsocast); + MACSTATUPD(rxdfrmmcast); + MACSTATUPD(rxmfrmmcast); + MACSTATUPD(rxcfrmmcast); + MACSTATUPD(rxbeaconmbss); + MACSTATUPD(rxdfrmucastobss); + MACSTATUPD(rxbeaconobss); + MACSTATUPD(rxrsptmout); + MACSTATUPD(bcntxcancl); + MACSTATUPD(rxf0ovfl); + MACSTATUPD(rxf1ovfl); + MACSTATUPD(rxf2ovfl); + MACSTATUPD(txsfovfl); + MACSTATUPD(pmqovfl); + MACSTATUPD(rxcgprqfrm); + MACSTATUPD(rxcgprsqovfl); + MACSTATUPD(txcgprsfail); + MACSTATUPD(txcgprssuc); + MACSTATUPD(prs_timeout); + MACSTATUPD(rxnack); + MACSTATUPD(frmscons); + MACSTATUPD(txnack); + MACSTATUPD(txglitch_nack); + MACSTATUPD(txburst); + MACSTATUPD(phywatchdog); + MACSTATUPD(pktengrxducast); + MACSTATUPD(pktengrxdmcast); + +#ifdef BCMDBG + /* check for rx fifo 0 overflow */ + delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); + if (delta) + WL_ERROR("wl%d: %u rx fifo 0 overflows!\n", + wlc->pub->unit, delta); + + /* check for tx fifo underflows */ + for (i = 0; i < NFIFO; i++) { + delta = + (u16) (wlc->core->macstat_snapshot->txfunfl[i] - + txfunfl[i]); + if (delta) + WL_ERROR("wl%d: %u tx fifo %d underflows!\n", + wlc->pub->unit, delta, i); + } +#endif /* BCMDBG */ + + /* dot11 counter update */ + + WLCNTSET(wlc->pub->_cnt->txrts, + (wlc->pub->_cnt->rxctsucast - + wlc->pub->_cnt->d11cnt_txrts_off)); + WLCNTSET(wlc->pub->_cnt->rxcrc, + (wlc->pub->_cnt->rxbadfcs - wlc->pub->_cnt->d11cnt_rxcrc_off)); + WLCNTSET(wlc->pub->_cnt->txnocts, + ((wlc->pub->_cnt->txrtsfrm - wlc->pub->_cnt->rxctsucast) - + wlc->pub->_cnt->d11cnt_txnocts_off)); + + /* merge counters from dma module */ + for (i = 0; i < NFIFO; i++) { + if (wlc->hw->di[i]) { + WLCNTADD(wlc->pub->_cnt->txnobuf, + (wlc->hw->di[i])->txnobuf); + WLCNTADD(wlc->pub->_cnt->rxnobuf, + (wlc->hw->di[i])->rxnobuf); + WLCNTADD(wlc->pub->_cnt->rxgiant, + (wlc->hw->di[i])->rxgiants); + dma_counterreset(wlc->hw->di[i]); + } + } + + /* + * Aggregate transmit and receive errors that probably resulted + * in the loss of a frame are computed on the fly. + */ + WLCNTSET(wlc->pub->_cnt->txerror, + wlc->pub->_cnt->txnobuf + wlc->pub->_cnt->txnoassoc + + wlc->pub->_cnt->txuflo + wlc->pub->_cnt->txrunt + + wlc->pub->_cnt->dmade + wlc->pub->_cnt->dmada + + wlc->pub->_cnt->dmape); + WLCNTSET(wlc->pub->_cnt->rxerror, + wlc->pub->_cnt->rxoflo + wlc->pub->_cnt->rxnobuf + + wlc->pub->_cnt->rxfragerr + wlc->pub->_cnt->rxrunt + + wlc->pub->_cnt->rxgiant + wlc->pub->_cnt->rxnoscb + + wlc->pub->_cnt->rxbadsrcmac); + for (i = 0; i < NFIFO; i++) + wlc->pub->_cnt->rxerror += wlc->pub->_cnt->rxuflo[i]; +} + +bool wlc_chipmatch(u16 vendor, u16 device) +{ + if (vendor != VENDOR_BROADCOM) { + WL_ERROR("wlc_chipmatch: unknown vendor id %04x\n", vendor); + return false; + } + + if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID)) + return true; + + if (device == BCM4313_D11N2G_ID) + return true; + if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID)) + return true; + + WL_ERROR("wlc_chipmatch: unknown device id %04x\n", device); + return false; +} + +#if defined(BCMDBG) +void wlc_print_txdesc(d11txh_t *txh) +{ + u16 mtcl = le16_to_cpu(txh->MacTxControlLow); + u16 mtch = le16_to_cpu(txh->MacTxControlHigh); + u16 mfc = le16_to_cpu(txh->MacFrameControl); + u16 tfest = le16_to_cpu(txh->TxFesTimeNormal); + u16 ptcw = le16_to_cpu(txh->PhyTxControlWord); + u16 ptcw_1 = le16_to_cpu(txh->PhyTxControlWord_1); + u16 ptcw_1_Fbr = le16_to_cpu(txh->PhyTxControlWord_1_Fbr); + u16 ptcw_1_Rts = le16_to_cpu(txh->PhyTxControlWord_1_Rts); + u16 ptcw_1_FbrRts = le16_to_cpu(txh->PhyTxControlWord_1_FbrRts); + u16 mainrates = le16_to_cpu(txh->MainRates); + u16 xtraft = le16_to_cpu(txh->XtraFrameTypes); + u8 *iv = txh->IV; + u8 *ra = txh->TxFrameRA; + u16 tfestfb = le16_to_cpu(txh->TxFesTimeFallback); + u8 *rtspfb = txh->RTSPLCPFallback; + u16 rtsdfb = le16_to_cpu(txh->RTSDurFallback); + u8 *fragpfb = txh->FragPLCPFallback; + u16 fragdfb = le16_to_cpu(txh->FragDurFallback); + u16 mmodelen = le16_to_cpu(txh->MModeLen); + u16 mmodefbrlen = le16_to_cpu(txh->MModeFbrLen); + u16 tfid = le16_to_cpu(txh->TxFrameID); + u16 txs = le16_to_cpu(txh->TxStatus); + u16 mnmpdu = le16_to_cpu(txh->MaxNMpdus); + u16 mabyte = le16_to_cpu(txh->MaxABytes_MRT); + u16 mabyte_f = le16_to_cpu(txh->MaxABytes_FBR); + u16 mmbyte = le16_to_cpu(txh->MinMBytes); + + u8 *rtsph = txh->RTSPhyHeader; + struct ieee80211_rts rts = txh->rts_frame; + char hexbuf[256]; + + /* add plcp header along with txh descriptor */ + prhex("Raw TxDesc + plcp header", (unsigned char *) txh, sizeof(d11txh_t) + 48); + + printk(KERN_DEBUG "TxCtlLow: %04x ", mtcl); + printk(KERN_DEBUG "TxCtlHigh: %04x ", mtch); + printk(KERN_DEBUG "FC: %04x ", mfc); + printk(KERN_DEBUG "FES Time: %04x\n", tfest); + printk(KERN_DEBUG "PhyCtl: %04x%s ", ptcw, + (ptcw & PHY_TXC_SHORT_HDR) ? " short" : ""); + printk(KERN_DEBUG "PhyCtl_1: %04x ", ptcw_1); + printk(KERN_DEBUG "PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr); + printk(KERN_DEBUG "PhyCtl_1_Rts: %04x ", ptcw_1_Rts); + printk(KERN_DEBUG "PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts); + printk(KERN_DEBUG "MainRates: %04x ", mainrates); + printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft); + printk(KERN_DEBUG "\n"); + + bcm_format_hex(hexbuf, iv, sizeof(txh->IV)); + printk(KERN_DEBUG "SecIV: %s\n", hexbuf); + bcm_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA)); + printk(KERN_DEBUG "RA: %s\n", hexbuf); + + printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb); + bcm_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback)); + printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf); + printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb); + bcm_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback)); + printk(KERN_DEBUG "PLCP: %s ", hexbuf); + printk(KERN_DEBUG "DUR: %04x", fragdfb); + printk(KERN_DEBUG "\n"); + + printk(KERN_DEBUG "MModeLen: %04x ", mmodelen); + printk(KERN_DEBUG "MModeFbrLen: %04x\n", mmodefbrlen); + + printk(KERN_DEBUG "FrameID: %04x\n", tfid); + printk(KERN_DEBUG "TxStatus: %04x\n", txs); + + printk(KERN_DEBUG "MaxNumMpdu: %04x\n", mnmpdu); + printk(KERN_DEBUG "MaxAggbyte: %04x\n", mabyte); + printk(KERN_DEBUG "MaxAggbyte_fb: %04x\n", mabyte_f); + printk(KERN_DEBUG "MinByte: %04x\n", mmbyte); + + bcm_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader)); + printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf); + bcm_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame)); + printk(KERN_DEBUG "RTS Frame: %s", hexbuf); + printk(KERN_DEBUG "\n"); +} +#endif /* defined(BCMDBG) */ + +#if defined(BCMDBG) +void wlc_print_rxh(d11rxhdr_t *rxh) +{ + u16 len = rxh->RxFrameSize; + u16 phystatus_0 = rxh->PhyRxStatus_0; + u16 phystatus_1 = rxh->PhyRxStatus_1; + u16 phystatus_2 = rxh->PhyRxStatus_2; + u16 phystatus_3 = rxh->PhyRxStatus_3; + u16 macstatus1 = rxh->RxStatus1; + u16 macstatus2 = rxh->RxStatus2; + char flagstr[64]; + char lenbuf[20]; + static const bcm_bit_desc_t macstat_flags[] = { + {RXS_FCSERR, "FCSErr"}, + {RXS_RESPFRAMETX, "Reply"}, + {RXS_PBPRES, "PADDING"}, + {RXS_DECATMPT, "DeCr"}, + {RXS_DECERR, "DeCrErr"}, + {RXS_BCNSENT, "Bcn"}, + {0, NULL} + }; + + prhex("Raw RxDesc", (unsigned char *) rxh, sizeof(d11rxhdr_t)); + + bcm_format_flags(macstat_flags, macstatus1, flagstr, 64); + + snprintf(lenbuf, sizeof(lenbuf), "0x%x", len); + + printk(KERN_DEBUG "RxFrameSize: %6s (%d)%s\n", lenbuf, len, + (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : ""); + printk(KERN_DEBUG "RxPHYStatus: %04x %04x %04x %04x\n", + phystatus_0, phystatus_1, phystatus_2, phystatus_3); + printk(KERN_DEBUG "RxMACStatus: %x %s\n", macstatus1, flagstr); + printk(KERN_DEBUG "RXMACaggtype: %x\n", + (macstatus2 & RXS_AGGTYPE_MASK)); + printk(KERN_DEBUG "RxTSFTime: %04x\n", rxh->RxTSFTime); +} +#endif /* defined(BCMDBG) */ + +#if defined(BCMDBG) +int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len) +{ + uint i, c; + char *p = buf; + char *endp = buf + SSID_FMT_BUF_LEN; + + if (ssid_len > IEEE80211_MAX_SSID_LEN) + ssid_len = IEEE80211_MAX_SSID_LEN; + + for (i = 0; i < ssid_len; i++) { + c = (uint) ssid[i]; + if (c == '\\') { + *p++ = '\\'; + *p++ = '\\'; + } else if (isprint((unsigned char) c)) { + *p++ = (char)c; + } else { + p += snprintf(p, (endp - p), "\\x%02X", c); + } + } + *p = '\0'; + ASSERT(p < endp); + + return (int)(p - buf); +} +#endif /* defined(BCMDBG) */ + +static u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate) +{ + return wlc_bmac_rate_shm_offset(wlc->hw, rate); +} + +/* Callback for device removed */ + +/* + * Attempts to queue a packet onto a multiple-precedence queue, + * if necessary evicting a lower precedence packet from the queue. + * + * 'prec' is the precedence number that has already been mapped + * from the packet priority. + * + * Returns true if packet consumed (queued), false if not. + */ +bool BCMFASTPATH +wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, int prec) +{ + return wlc_prec_enq_head(wlc, q, pkt, prec, false); +} + +bool BCMFASTPATH +wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, + int prec, bool head) +{ + struct sk_buff *p; + int eprec = -1; /* precedence to evict from */ + + /* Determine precedence from which to evict packet, if any */ + if (pktq_pfull(q, prec)) + eprec = prec; + else if (pktq_full(q)) { + p = pktq_peek_tail(q, &eprec); + ASSERT(p != NULL); + if (eprec > prec) { + WL_ERROR("%s: Failing: eprec %d > prec %d\n", + __func__, eprec, prec); + return false; + } + } + + /* Evict if needed */ + if (eprec >= 0) { + bool discard_oldest; + + /* Detect queueing to unconfigured precedence */ + ASSERT(!pktq_pempty(q, eprec)); + + discard_oldest = AC_BITMAP_TST(wlc->wme_dp, eprec); + + /* Refuse newer packet unless configured to discard oldest */ + if (eprec == prec && !discard_oldest) { + WL_ERROR("%s: No where to go, prec == %d\n", + __func__, prec); + return false; + } + + /* Evict packet according to discard policy */ + p = discard_oldest ? pktq_pdeq(q, eprec) : pktq_pdeq_tail(q, + eprec); + ASSERT(p != NULL); + + /* Increment wme stats */ + if (WME_ENAB(wlc->pub)) { + WLCNTINCR(wlc->pub->_wme_cnt-> + tx_failed[WME_PRIO2AC(p->priority)].packets); + WLCNTADD(wlc->pub->_wme_cnt-> + tx_failed[WME_PRIO2AC(p->priority)].bytes, + pkttotlen(p)); + } + pkt_buf_free_skb(wlc->osh, p, true); + wlc->pub->_cnt->txnobuf++; + } + + /* Enqueue */ + if (head) + p = pktq_penq_head(q, prec, pkt); + else + p = pktq_penq(q, prec, pkt); + ASSERT(p != NULL); + + return true; +} + +void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, + uint prec) +{ + struct wlc_info *wlc = (struct wlc_info *) ctx; + struct wlc_txq_info *qi = wlc->active_queue; /* Check me */ + struct pktq *q = &qi->q; + int prio; + + prio = sdu->priority; + + ASSERT(pktq_max(q) >= wlc->pub->tunables->datahiwat); + + if (!wlc_prec_enq(wlc, q, sdu, prec)) { + if (!EDCF_ENAB(wlc->pub) + || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) + WL_ERROR("wl%d: wlc_txq_enq: txq overflow\n", + wlc->pub->unit); + + /* ASSERT(9 == 8); *//* XXX we might hit this condtion in case packet flooding from mac80211 stack */ + pkt_buf_free_skb(wlc->osh, sdu, true); + wlc->pub->_cnt->txnobuf++; + } + + /* Check if flow control needs to be turned on after enqueuing the packet + * Don't turn on flow control if EDCF is enabled. Driver would make the decision on what + * to drop instead of relying on stack to make the right decision + */ + if (!EDCF_ENAB(wlc->pub) + || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) { + if (pktq_len(q) >= wlc->pub->tunables->datahiwat) { + wlc_txflowcontrol(wlc, qi, ON, ALLPRIO); + } + } else if (wlc->pub->_priofc) { + if (pktq_plen(q, wlc_prio2prec_map[prio]) >= + wlc->pub->tunables->datahiwat) { + wlc_txflowcontrol(wlc, qi, ON, prio); + } + } +} + +bool BCMFASTPATH +wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, + struct ieee80211_hw *hw) +{ + u8 prio; + uint fifo; + void *pkt; + struct scb *scb = &global_scb; + struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data); + + ASSERT(sdu); + + /* 802.11 standard requires management traffic to go at highest priority */ + prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority : + MAXPRIO; + fifo = prio2fifo[prio]; + + ASSERT((uint) skb_headroom(sdu) >= TXOFF); + ASSERT(!(sdu->next)); + ASSERT(!(sdu->prev)); + ASSERT(fifo < NFIFO); + + pkt = sdu; + if (unlikely + (wlc_d11hdrs_mac80211(wlc, hw, pkt, scb, 0, 1, fifo, 0, NULL, 0))) + return -EINVAL; + wlc_txq_enq(wlc, scb, pkt, WLC_PRIO_TO_PREC(prio)); + wlc_send_q(wlc, wlc->active_queue); + + wlc->pub->_cnt->ieee_tx++; + return 0; +} + +void BCMFASTPATH wlc_send_q(struct wlc_info *wlc, struct wlc_txq_info *qi) +{ + struct sk_buff *pkt[DOT11_MAXNUMFRAGS]; + int prec; + u16 prec_map; + int err = 0, i, count; + uint fifo; + struct pktq *q = &qi->q; + struct ieee80211_tx_info *tx_info; + + /* only do work for the active queue */ + if (qi != wlc->active_queue) + return; + + if (in_send_q) + return; + else + in_send_q = true; + + prec_map = wlc->tx_prec_map; + + /* Send all the enq'd pkts that we can. + * Dequeue packets with precedence with empty HW fifo only + */ + while (prec_map && (pkt[0] = pktq_mdeq(q, prec_map, &prec))) { + tx_info = IEEE80211_SKB_CB(pkt[0]); + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { + err = wlc_sendampdu(wlc->ampdu, qi, pkt, prec); + } else { + count = 1; + err = wlc_prep_pdu(wlc, pkt[0], &fifo); + if (!err) { + for (i = 0; i < count; i++) { + wlc_txfifo(wlc, fifo, pkt[i], true, 1); + } + } + } + + if (err == BCME_BUSY) { + pktq_penq_head(q, prec, pkt[0]); + /* If send failed due to any other reason than a change in + * HW FIFO condition, quit. Otherwise, read the new prec_map! + */ + if (prec_map == wlc->tx_prec_map) + break; + prec_map = wlc->tx_prec_map; + } + } + + /* Check if flow control needs to be turned off after sending the packet */ + if (!EDCF_ENAB(wlc->pub) + || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) { + if (wlc_txflowcontrol_prio_isset(wlc, qi, ALLPRIO) + && (pktq_len(q) < wlc->pub->tunables->datahiwat / 2)) { + wlc_txflowcontrol(wlc, qi, OFF, ALLPRIO); + } + } else if (wlc->pub->_priofc) { + int prio; + for (prio = MAXPRIO; prio >= 0; prio--) { + if (wlc_txflowcontrol_prio_isset(wlc, qi, prio) && + (pktq_plen(q, wlc_prio2prec_map[prio]) < + wlc->pub->tunables->datahiwat / 2)) { + wlc_txflowcontrol(wlc, qi, OFF, prio); + } + } + } + in_send_q = false; +} + +/* + * bcmc_fid_generate: + * Generate frame ID for a BCMC packet. The frag field is not used + * for MC frames so is used as part of the sequence number. + */ +static inline u16 +bcmc_fid_generate(struct wlc_info *wlc, wlc_bsscfg_t *bsscfg, d11txh_t *txh) +{ + u16 frameid; + + frameid = le16_to_cpu(txh->TxFrameID) & ~(TXFID_SEQ_MASK | + TXFID_QUEUE_MASK); + frameid |= + (((wlc-> + mc_fid_counter++) << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) | + TX_BCMC_FIFO; + + return frameid; +} + +void BCMFASTPATH +wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit, + s8 txpktpend) +{ + u16 frameid = INVALIDFID; + d11txh_t *txh; + + ASSERT(fifo < NFIFO); + txh = (d11txh_t *) (p->data); + + /* When a BC/MC frame is being committed to the BCMC fifo via DMA (NOT PIO), update + * ucode or BSS info as appropriate. + */ + if (fifo == TX_BCMC_FIFO) { + frameid = le16_to_cpu(txh->TxFrameID); + + } + + if (WLC_WAR16165(wlc)) + wlc_war16165(wlc, true); + + + /* Bump up pending count for if not using rpc. If rpc is used, this will be handled + * in wlc_bmac_txfifo() + */ + if (commit) { + TXPKTPENDINC(wlc, fifo, txpktpend); + WL_TRACE("wlc_txfifo, pktpend inc %d to %d\n", + txpktpend, TXPKTPENDGET(wlc, fifo)); + } + + /* Commit BCMC sequence number in the SHM frame ID location */ + if (frameid != INVALIDFID) + BCMCFID(wlc, frameid); + + if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) { + WL_ERROR("wlc_txfifo: fatal, toss frames !!!\n"); + } +} + +static u16 +wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, uint length) +{ + u16 usec = 0; + uint mac_rate = RSPEC2RATE(rspec); + uint nsyms; + + if (IS_MCS(rspec)) { + /* not supported yet */ + ASSERT(0); + } else if (IS_OFDM(rspec)) { + /* nsyms = Ceiling(Nbits / (Nbits/sym)) + * + * Nbits = length * 8 + * Nbits/sym = Mbps * 4 = mac_rate * 2 + */ + nsyms = CEIL((length * 8), (mac_rate * 2)); + + /* usec = symbols * usec/symbol */ + usec = (u16) (nsyms * APHY_SYMBOL_TIME); + return usec; + } else { + switch (mac_rate) { + case WLC_RATE_1M: + usec = length << 3; + break; + case WLC_RATE_2M: + usec = length << 2; + break; + case WLC_RATE_5M5: + usec = (length << 4) / 11; + break; + case WLC_RATE_11M: + usec = (length << 3) / 11; + break; + default: + WL_ERROR("wl%d: wlc_compute_airtime: unsupported rspec 0x%x\n", + wlc->pub->unit, rspec); + ASSERT((const char *)"Bad phy_rate" == NULL); + break; + } + } + + return usec; +} + +void BCMFASTPATH +wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rspec, uint length, u8 *plcp) +{ + if (IS_MCS(rspec)) { + wlc_compute_mimo_plcp(rspec, length, plcp); + } else if (IS_OFDM(rspec)) { + wlc_compute_ofdm_plcp(rspec, length, plcp); + } else { + wlc_compute_cck_plcp(rspec, length, plcp); + } + return; +} + +/* Rate: 802.11 rate code, length: PSDU length in octets */ +static void wlc_compute_mimo_plcp(ratespec_t rspec, uint length, u8 *plcp) +{ + u8 mcs = (u8) (rspec & RSPEC_RATE_MASK); + ASSERT(IS_MCS(rspec)); + plcp[0] = mcs; + if (RSPEC_IS40MHZ(rspec) || (mcs == 32)) + plcp[0] |= MIMO_PLCP_40MHZ; + WLC_SET_MIMO_PLCP_LEN(plcp, length); + plcp[3] = RSPEC_MIMOPLCP3(rspec); /* rspec already holds this byte */ + plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */ + plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */ + plcp[5] = 0; +} + +/* Rate: 802.11 rate code, length: PSDU length in octets */ +static void BCMFASTPATH +wlc_compute_ofdm_plcp(ratespec_t rspec, u32 length, u8 *plcp) +{ + u8 rate_signal; + u32 tmp = 0; + int rate = RSPEC2RATE(rspec); + + ASSERT(IS_OFDM(rspec)); + + /* encode rate per 802.11a-1999 sec 17.3.4.1, with lsb transmitted first */ + rate_signal = rate_info[rate] & RATE_MASK; + ASSERT(rate_signal != 0); + + memset(plcp, 0, D11_PHY_HDR_LEN); + D11A_PHY_HDR_SRATE((ofdm_phy_hdr_t *) plcp, rate_signal); + + tmp = (length & 0xfff) << 5; + plcp[2] |= (tmp >> 16) & 0xff; + plcp[1] |= (tmp >> 8) & 0xff; + plcp[0] |= tmp & 0xff; + + return; +} + +/* + * Compute PLCP, but only requires actual rate and length of pkt. + * Rate is given in the driver standard multiple of 500 kbps. + * le is set for 11 Mbps rate if necessary. + * Broken out for PRQ. + */ + +static void wlc_cck_plcp_set(int rate_500, uint length, u8 *plcp) +{ + u16 usec = 0; + u8 le = 0; + + switch (rate_500) { + case WLC_RATE_1M: + usec = length << 3; + break; + case WLC_RATE_2M: + usec = length << 2; + break; + case WLC_RATE_5M5: + usec = (length << 4) / 11; + if ((length << 4) - (usec * 11) > 0) + usec++; + break; + case WLC_RATE_11M: + usec = (length << 3) / 11; + if ((length << 3) - (usec * 11) > 0) { + usec++; + if ((usec * 11) - (length << 3) >= 8) + le = D11B_PLCP_SIGNAL_LE; + } + break; + + default: + WL_ERROR("wlc_cck_plcp_set: unsupported rate %d\n", rate_500); + rate_500 = WLC_RATE_1M; + usec = length << 3; + break; + } + /* PLCP signal byte */ + plcp[0] = rate_500 * 5; /* r (500kbps) * 5 == r (100kbps) */ + /* PLCP service byte */ + plcp[1] = (u8) (le | D11B_PLCP_SIGNAL_LOCKED); + /* PLCP length u16, little endian */ + plcp[2] = usec & 0xff; + plcp[3] = (usec >> 8) & 0xff; + /* PLCP CRC16 */ + plcp[4] = 0; + plcp[5] = 0; +} + +/* Rate: 802.11 rate code, length: PSDU length in octets */ +static void wlc_compute_cck_plcp(ratespec_t rspec, uint length, u8 *plcp) +{ + int rate = RSPEC2RATE(rspec); + + ASSERT(IS_CCK(rspec)); + + wlc_cck_plcp_set(rate, length, plcp); +} + +/* wlc_compute_frame_dur() + * + * Calculate the 802.11 MAC header DUR field for MPDU + * DUR for a single frame = 1 SIFS + 1 ACK + * DUR for a frame with following frags = 3 SIFS + 2 ACK + next frag time + * + * rate MPDU rate in unit of 500kbps + * next_frag_len next MPDU length in bytes + * preamble_type use short/GF or long/MM PLCP header + */ +static u16 BCMFASTPATH +wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type, + uint next_frag_len) +{ + u16 dur, sifs; + + sifs = SIFS(wlc->band); + + dur = sifs; + dur += (u16) wlc_calc_ack_time(wlc, rate, preamble_type); + + if (next_frag_len) { + /* Double the current DUR to get 2 SIFS + 2 ACKs */ + dur *= 2; + /* add another SIFS and the frag time */ + dur += sifs; + dur += + (u16) wlc_calc_frame_time(wlc, rate, preamble_type, + next_frag_len); + } + return dur; +} + +/* wlc_compute_rtscts_dur() + * + * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame + * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK + * DUR for CTS-TO-SELF w/ frame = 2 SIFS + next frame time + 1 ACK + * + * cts cts-to-self or rts/cts + * rts_rate rts or cts rate in unit of 500kbps + * rate next MPDU rate in unit of 500kbps + * frame_len next MPDU frame length in bytes + */ +u16 BCMFASTPATH +wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, ratespec_t rts_rate, + ratespec_t frame_rate, u8 rts_preamble_type, + u8 frame_preamble_type, uint frame_len, bool ba) +{ + u16 dur, sifs; + + sifs = SIFS(wlc->band); + + if (!cts_only) { /* RTS/CTS */ + dur = 3 * sifs; + dur += + (u16) wlc_calc_cts_time(wlc, rts_rate, + rts_preamble_type); + } else { /* CTS-TO-SELF */ + dur = 2 * sifs; + } + + dur += + (u16) wlc_calc_frame_time(wlc, frame_rate, frame_preamble_type, + frame_len); + if (ba) + dur += + (u16) wlc_calc_ba_time(wlc, frame_rate, + WLC_SHORT_PREAMBLE); + else + dur += + (u16) wlc_calc_ack_time(wlc, frame_rate, + frame_preamble_type); + return dur; +} + +static bool wlc_phy_rspec_check(struct wlc_info *wlc, u16 bw, ratespec_t rspec) +{ + if (IS_MCS(rspec)) { + uint mcs = rspec & RSPEC_RATE_MASK; + + if (mcs < 8) { + ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM); + } else if ((mcs >= 8) && (mcs <= 23)) { + ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SDM); + } else if (mcs == 32) { + ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM); + ASSERT(bw == PHY_TXC1_BW_40MHZ_DUP); + } + } else if (IS_OFDM(rspec)) { + ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_STBC); + } else { + ASSERT(IS_CCK(rspec)); + + ASSERT((bw == PHY_TXC1_BW_20MHZ) + || (bw == PHY_TXC1_BW_20MHZ_UP)); + ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SISO); + } + + return true; +} + +u16 BCMFASTPATH wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec) +{ + u16 phyctl1 = 0; + u16 bw; + + if (WLCISLCNPHY(wlc->band)) { + bw = PHY_TXC1_BW_20MHZ; + } else { + bw = RSPEC_GET_BW(rspec); + /* 10Mhz is not supported yet */ + if (bw < PHY_TXC1_BW_20MHZ) { + WL_ERROR("wlc_phytxctl1_calc: bw %d is not supported yet, set to 20L\n", + bw); + bw = PHY_TXC1_BW_20MHZ; + } + + wlc_phy_rspec_check(wlc, bw, rspec); + } + + if (IS_MCS(rspec)) { + uint mcs = rspec & RSPEC_RATE_MASK; + + /* bw, stf, coding-type is part of RSPEC_PHYTXBYTE2 returns */ + phyctl1 = RSPEC_PHYTXBYTE2(rspec); + /* set the upper byte of phyctl1 */ + phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8); + } else if (IS_CCK(rspec) && !WLCISLCNPHY(wlc->band) + && !WLCISSSLPNPHY(wlc->band)) { + /* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */ + /* Eventually MIMOPHY would also be converted to this format */ + /* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */ + phyctl1 = (bw | (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT)); + } else { /* legacy OFDM/CCK */ + s16 phycfg; + /* get the phyctl byte from rate phycfg table */ + phycfg = wlc_rate_legacy_phyctl(RSPEC2RATE(rspec)); + if (phycfg == -1) { + WL_ERROR("wlc_phytxctl1_calc: wrong legacy OFDM/CCK rate\n"); + ASSERT(0); + phycfg = 0; + } + /* set the upper byte of phyctl1 */ + phyctl1 = + (bw | (phycfg << 8) | + (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT)); + } + +#ifdef BCMDBG + /* phy clock must support 40Mhz if tx descriptor uses it */ + if ((phyctl1 & PHY_TXC1_BW_MASK) >= PHY_TXC1_BW_40MHZ) { + ASSERT(CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ); + ASSERT(wlc->chanspec == wlc_phy_chanspec_get(wlc->band->pi)); + } +#endif /* BCMDBG */ + return phyctl1; +} + +ratespec_t BCMFASTPATH +wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, bool use_rspec, + u16 mimo_ctlchbw) +{ + ratespec_t rts_rspec = 0; + + if (use_rspec) { + /* use frame rate as rts rate */ + rts_rspec = rspec; + + } else if (wlc->band->gmode && wlc->protection->_g && !IS_CCK(rspec)) { + /* Use 11Mbps as the g protection RTS target rate and fallback. + * Use the WLC_BASIC_RATE() lookup to find the best basic rate under the + * target in case 11 Mbps is not Basic. + * 6 and 9 Mbps are not usually selected by rate selection, but even + * if the OFDM rate we are protecting is 6 or 9 Mbps, 11 is more robust. + */ + rts_rspec = WLC_BASIC_RATE(wlc, WLC_RATE_11M); + } else { + /* calculate RTS rate and fallback rate based on the frame rate + * RTS must be sent at a basic rate since it is a + * control frame, sec 9.6 of 802.11 spec + */ + rts_rspec = WLC_BASIC_RATE(wlc, rspec); + } + + if (WLC_PHY_11N_CAP(wlc->band)) { + /* set rts txbw to correct side band */ + rts_rspec &= ~RSPEC_BW_MASK; + + /* if rspec/rspec_fallback is 40MHz, then send RTS on both 20MHz channel + * (DUP), otherwise send RTS on control channel + */ + if (RSPEC_IS40MHZ(rspec) && !IS_CCK(rts_rspec)) + rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT); + else + rts_rspec |= (mimo_ctlchbw << RSPEC_BW_SHIFT); + + /* pick siso/cdd as default for ofdm */ + if (IS_OFDM(rts_rspec)) { + rts_rspec &= ~RSPEC_STF_MASK; + rts_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT); + } + } + return rts_rspec; +} + +/* + * Add d11txh_t, cck_phy_hdr_t. + * + * 'p' data must start with 802.11 MAC header + * 'p' must allow enough bytes of local headers to be "pushed" onto the packet + * + * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes) + * + */ +static u16 BCMFASTPATH +wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, + struct sk_buff *p, struct scb *scb, uint frag, + uint nfrags, uint queue, uint next_frag_len, + wsec_key_t *key, ratespec_t rspec_override) +{ + struct ieee80211_hdr *h; + d11txh_t *txh; + u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN]; + struct osl_info *osh; + int len, phylen, rts_phylen; + u16 frameid, mch, phyctl, xfts, mainrates; + u16 seq = 0, mcl = 0, status = 0; + ratespec_t rspec[2] = { WLC_RATE_1M, WLC_RATE_1M }, rts_rspec[2] = { + WLC_RATE_1M, WLC_RATE_1M}; + bool use_rts = false; + bool use_cts = false; + bool use_rifs = false; + bool short_preamble[2] = { false, false }; + u8 preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE }; + u8 rts_preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE }; + u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN]; + struct ieee80211_rts *rts = NULL; + bool qos; + uint ac; + u32 rate_val[2]; + bool hwtkmic = false; + u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; +#define ANTCFG_NONE 0xFF + u8 antcfg = ANTCFG_NONE; + u8 fbantcfg = ANTCFG_NONE; + uint phyctl1_stf = 0; + u16 durid = 0; + struct ieee80211_tx_rate *txrate[2]; + int k; + struct ieee80211_tx_info *tx_info; + bool is_mcs[2]; + u16 mimo_txbw; + u8 mimo_preamble_type; + + frameid = 0; + + ASSERT(queue < NFIFO); + + osh = wlc->osh; + + /* locate 802.11 MAC header */ + h = (struct ieee80211_hdr *)(p->data); + qos = ieee80211_is_data_qos(h->frame_control); + + /* compute length of frame in bytes for use in PLCP computations */ + len = pkttotlen(p); + phylen = len + FCS_LEN; + + /* If WEP enabled, add room in phylen for the additional bytes of + * ICV which MAC generates. We do NOT add the additional bytes to + * the packet itself, thus phylen = packet length + ICV_LEN + FCS_LEN + * in this case + */ + if (key) { + phylen += key->icv_len; + } + + /* Get tx_info */ + tx_info = IEEE80211_SKB_CB(p); + ASSERT(tx_info); + + /* add PLCP */ + plcp = skb_push(p, D11_PHY_HDR_LEN); + + /* add Broadcom tx descriptor header */ + txh = (d11txh_t *) skb_push(p, D11_TXH_LEN); + memset(txh, 0, D11_TXH_LEN); + + /* setup frameid */ + if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { + /* non-AP STA should never use BCMC queue */ + ASSERT(queue != TX_BCMC_FIFO); + if (queue == TX_BCMC_FIFO) { + WL_ERROR("wl%d: %s: ASSERT queue == TX_BCMC!\n", + WLCWLUNIT(wlc), __func__); + frameid = bcmc_fid_generate(wlc, NULL, txh); + } else { + /* Increment the counter for first fragment */ + if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) { + SCB_SEQNUM(scb, p->priority)++; + } + + /* extract fragment number from frame first */ + seq = le16_to_cpu(seq) & FRAGNUM_MASK; + seq |= (SCB_SEQNUM(scb, p->priority) << SEQNUM_SHIFT); + h->seq_ctrl = cpu_to_le16(seq); + + frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) | + (queue & TXFID_QUEUE_MASK); + } + } + frameid |= queue & TXFID_QUEUE_MASK; + + /* set the ignpmq bit for all pkts tx'd in PS mode and for beacons */ + if (SCB_PS(scb) || ieee80211_is_beacon(h->frame_control)) + mcl |= TXC_IGNOREPMQ; + + ASSERT(hw->max_rates <= IEEE80211_TX_MAX_RATES); + ASSERT(hw->max_rates == 2); + + txrate[0] = tx_info->control.rates; + txrate[1] = txrate[0] + 1; + + ASSERT(txrate[0]->idx >= 0); + /* if rate control algorithm didn't give us a fallback rate, use the primary rate */ + if (txrate[1]->idx < 0) { + txrate[1] = txrate[0]; + } + + for (k = 0; k < hw->max_rates; k++) { + is_mcs[k] = + txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false; + if (!is_mcs[k]) { + ASSERT(!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)); + if ((txrate[k]->idx >= 0) + && (txrate[k]->idx < + hw->wiphy->bands[tx_info->band]->n_bitrates)) { + rate_val[k] = + hw->wiphy->bands[tx_info->band]-> + bitrates[txrate[k]->idx].hw_value; + short_preamble[k] = + txrate[k]-> + flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ? + true : false; + } else { + ASSERT((txrate[k]->idx >= 0) && + (txrate[k]->idx < + hw->wiphy->bands[tx_info->band]-> + n_bitrates)); + rate_val[k] = WLC_RATE_1M; + } + } else { + rate_val[k] = txrate[k]->idx; + } + /* Currently only support same setting for primay and fallback rates. + * Unify flags for each rate into a single value for the frame + */ + use_rts |= + txrate[k]-> + flags & IEEE80211_TX_RC_USE_RTS_CTS ? true : false; + use_cts |= + txrate[k]-> + flags & IEEE80211_TX_RC_USE_CTS_PROTECT ? true : false; + + if (is_mcs[k]) + rate_val[k] |= NRATE_MCS_INUSE; + + rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band, rate_val[k]); + + /* (1) RATE: determine and validate primary rate and fallback rates */ + if (!RSPEC_ACTIVE(rspec[k])) { + ASSERT(RSPEC_ACTIVE(rspec[k])); + rspec[k] = WLC_RATE_1M; + } else { + if (!is_multicast_ether_addr(h->addr1)) { + /* set tx antenna config */ + wlc_antsel_antcfg_get(wlc->asi, false, false, 0, + 0, &antcfg, &fbantcfg); + } + } + } + + phyctl1_stf = wlc->stf->ss_opmode; + + if (N_ENAB(wlc->pub)) { + for (k = 0; k < hw->max_rates; k++) { + /* apply siso/cdd to single stream mcs's or ofdm if rspec is auto selected */ + if (((IS_MCS(rspec[k]) && + IS_SINGLE_STREAM(rspec[k] & RSPEC_RATE_MASK)) || + IS_OFDM(rspec[k])) + && ((rspec[k] & RSPEC_OVERRIDE_MCS_ONLY) + || !(rspec[k] & RSPEC_OVERRIDE))) { + rspec[k] &= ~(RSPEC_STF_MASK | RSPEC_STC_MASK); + + /* For SISO MCS use STBC if possible */ + if (IS_MCS(rspec[k]) + && WLC_STF_SS_STBC_TX(wlc, scb)) { + u8 stc; + + ASSERT(WLC_STBC_CAP_PHY(wlc)); + stc = 1; /* Nss for single stream is always 1 */ + rspec[k] |= + (PHY_TXC1_MODE_STBC << + RSPEC_STF_SHIFT) | (stc << + RSPEC_STC_SHIFT); + } else + rspec[k] |= + (phyctl1_stf << RSPEC_STF_SHIFT); + } + + /* Is the phy configured to use 40MHZ frames? If so then pick the desired txbw */ + if (CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ) { + /* default txbw is 20in40 SB */ + mimo_ctlchbw = mimo_txbw = + CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC) + ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; + + if (IS_MCS(rspec[k])) { + /* mcs 32 must be 40b/w DUP */ + if ((rspec[k] & RSPEC_RATE_MASK) == 32) { + mimo_txbw = + PHY_TXC1_BW_40MHZ_DUP; + /* use override */ + } else if (wlc->mimo_40txbw != AUTO) + mimo_txbw = wlc->mimo_40txbw; + /* else check if dst is using 40 Mhz */ + else if (scb->flags & SCB_IS40) + mimo_txbw = PHY_TXC1_BW_40MHZ; + } else if (IS_OFDM(rspec[k])) { + if (wlc->ofdm_40txbw != AUTO) + mimo_txbw = wlc->ofdm_40txbw; + } else { + ASSERT(IS_CCK(rspec[k])); + if (wlc->cck_40txbw != AUTO) + mimo_txbw = wlc->cck_40txbw; + } + } else { + /* mcs32 is 40 b/w only. + * This is possible for probe packets on a STA during SCAN + */ + if ((rspec[k] & RSPEC_RATE_MASK) == 32) { + /* mcs 0 */ + rspec[k] = RSPEC_MIMORATE; + } + mimo_txbw = PHY_TXC1_BW_20MHZ; + } + + /* Set channel width */ + rspec[k] &= ~RSPEC_BW_MASK; + if ((k == 0) || ((k > 0) && IS_MCS(rspec[k]))) + rspec[k] |= (mimo_txbw << RSPEC_BW_SHIFT); + else + rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT); + + /* Set Short GI */ +#ifdef NOSGIYET + if (IS_MCS(rspec[k]) + && (txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI)) + rspec[k] |= RSPEC_SHORT_GI; + else if (!(txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI)) + rspec[k] &= ~RSPEC_SHORT_GI; +#else + rspec[k] &= ~RSPEC_SHORT_GI; +#endif + + mimo_preamble_type = WLC_MM_PREAMBLE; + if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD) + mimo_preamble_type = WLC_GF_PREAMBLE; + + if ((txrate[k]->flags & IEEE80211_TX_RC_MCS) + && (!IS_MCS(rspec[k]))) { + WL_ERROR("wl%d: %s: IEEE80211_TX_RC_MCS != IS_MCS(rspec)\n", + WLCWLUNIT(wlc), __func__); + ASSERT(0 && "Rate mismatch"); + } + + if (IS_MCS(rspec[k])) { + preamble_type[k] = mimo_preamble_type; + + /* if SGI is selected, then forced mm for single stream */ + if ((rspec[k] & RSPEC_SHORT_GI) + && IS_SINGLE_STREAM(rspec[k] & + RSPEC_RATE_MASK)) { + preamble_type[k] = WLC_MM_PREAMBLE; + } + } + + /* mimo bw field MUST now be valid in the rspec (it affects duration calculations) */ + ASSERT(VALID_RATE_DBG(wlc, rspec[0])); + + /* should be better conditionalized */ + if (!IS_MCS(rspec[0]) + && (tx_info->control.rates[0]. + flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)) + preamble_type[k] = WLC_SHORT_PREAMBLE; + + ASSERT(!IS_MCS(rspec[0]) + || WLC_IS_MIMO_PREAMBLE(preamble_type[k])); + } + } else { + for (k = 0; k < hw->max_rates; k++) { + /* Set ctrlchbw as 20Mhz */ + ASSERT(!IS_MCS(rspec[k])); + rspec[k] &= ~RSPEC_BW_MASK; + rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT); + + /* for nphy, stf of ofdm frames must follow policies */ + if (WLCISNPHY(wlc->band) && IS_OFDM(rspec[k])) { + rspec[k] &= ~RSPEC_STF_MASK; + rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT; + } + } + } + + /* Reset these for use with AMPDU's */ + txrate[0]->count = 0; + txrate[1]->count = 0; + + /* (2) PROTECTION, may change rspec */ + if ((ieee80211_is_data(h->frame_control) || + ieee80211_is_mgmt(h->frame_control)) && + (phylen > wlc->RTSThresh) && !is_multicast_ether_addr(h->addr1)) + use_rts = true; + + /* (3) PLCP: determine PLCP header and MAC duration, fill d11txh_t */ + wlc_compute_plcp(wlc, rspec[0], phylen, plcp); + wlc_compute_plcp(wlc, rspec[1], phylen, plcp_fallback); + memcpy(&txh->FragPLCPFallback, + plcp_fallback, sizeof(txh->FragPLCPFallback)); + + /* Length field now put in CCK FBR CRC field */ + if (IS_CCK(rspec[1])) { + txh->FragPLCPFallback[4] = phylen & 0xff; + txh->FragPLCPFallback[5] = (phylen & 0xff00) >> 8; + } + + /* MIMO-RATE: need validation ?? */ + mainrates = + IS_OFDM(rspec[0]) ? D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) plcp) : + plcp[0]; + + /* DUR field for main rate */ + if (!ieee80211_is_pspoll(h->frame_control) && + !is_multicast_ether_addr(h->addr1) && !use_rifs) { + durid = + wlc_compute_frame_dur(wlc, rspec[0], preamble_type[0], + next_frag_len); + h->duration_id = cpu_to_le16(durid); + } else if (use_rifs) { + /* NAV protect to end of next max packet size */ + durid = + (u16) wlc_calc_frame_time(wlc, rspec[0], + preamble_type[0], + DOT11_MAX_FRAG_LEN); + durid += RIFS_11N_TIME; + h->duration_id = cpu_to_le16(durid); + } + + /* DUR field for fallback rate */ + if (ieee80211_is_pspoll(h->frame_control)) + txh->FragDurFallback = h->duration_id; + else if (is_multicast_ether_addr(h->addr1) || use_rifs) + txh->FragDurFallback = 0; + else { + durid = wlc_compute_frame_dur(wlc, rspec[1], + preamble_type[1], next_frag_len); + txh->FragDurFallback = cpu_to_le16(durid); + } + + /* (4) MAC-HDR: MacTxControlLow */ + if (frag == 0) + mcl |= TXC_STARTMSDU; + + if (!is_multicast_ether_addr(h->addr1)) + mcl |= TXC_IMMEDACK; + + if (BAND_5G(wlc->band->bandtype)) + mcl |= TXC_FREQBAND_5G; + + if (CHSPEC_IS40(WLC_BAND_PI_RADIO_CHANSPEC)) + mcl |= TXC_BW_40; + + /* set AMIC bit if using hardware TKIP MIC */ + if (hwtkmic) + mcl |= TXC_AMIC; + + txh->MacTxControlLow = cpu_to_le16(mcl); + + /* MacTxControlHigh */ + mch = 0; + + /* Set fallback rate preamble type */ + if ((preamble_type[1] == WLC_SHORT_PREAMBLE) || + (preamble_type[1] == WLC_GF_PREAMBLE)) { + ASSERT((preamble_type[1] == WLC_GF_PREAMBLE) || + (!IS_MCS(rspec[1]))); + if (RSPEC2RATE(rspec[1]) != WLC_RATE_1M) + mch |= TXC_PREAMBLE_DATA_FB_SHORT; + } + + /* MacFrameControl */ + memcpy(&txh->MacFrameControl, &h->frame_control, sizeof(u16)); + txh->TxFesTimeNormal = cpu_to_le16(0); + + txh->TxFesTimeFallback = cpu_to_le16(0); + + /* TxFrameRA */ + memcpy(&txh->TxFrameRA, &h->addr1, ETH_ALEN); + + /* TxFrameID */ + txh->TxFrameID = cpu_to_le16(frameid); + + /* TxStatus, Note the case of recreating the first frag of a suppressed frame + * then we may need to reset the retry cnt's via the status reg + */ + txh->TxStatus = cpu_to_le16(status); + + /* extra fields for ucode AMPDU aggregation, the new fields are added to + * the END of previous structure so that it's compatible in driver. + */ + txh->MaxNMpdus = cpu_to_le16(0); + txh->MaxABytes_MRT = cpu_to_le16(0); + txh->MaxABytes_FBR = cpu_to_le16(0); + txh->MinMBytes = cpu_to_le16(0); + + /* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration, furnish d11txh_t */ + /* RTS PLCP header and RTS frame */ + if (use_rts || use_cts) { + if (use_rts && use_cts) + use_cts = false; + + for (k = 0; k < 2; k++) { + rts_rspec[k] = wlc_rspec_to_rts_rspec(wlc, rspec[k], + false, + mimo_ctlchbw); + } + + if (!IS_OFDM(rts_rspec[0]) && + !((RSPEC2RATE(rts_rspec[0]) == WLC_RATE_1M) || + (wlc->PLCPHdr_override == WLC_PLCP_LONG))) { + rts_preamble_type[0] = WLC_SHORT_PREAMBLE; + mch |= TXC_PREAMBLE_RTS_MAIN_SHORT; + } + + if (!IS_OFDM(rts_rspec[1]) && + !((RSPEC2RATE(rts_rspec[1]) == WLC_RATE_1M) || + (wlc->PLCPHdr_override == WLC_PLCP_LONG))) { + rts_preamble_type[1] = WLC_SHORT_PREAMBLE; + mch |= TXC_PREAMBLE_RTS_FB_SHORT; + } + + /* RTS/CTS additions to MacTxControlLow */ + if (use_cts) { + txh->MacTxControlLow |= cpu_to_le16(TXC_SENDCTS); + } else { + txh->MacTxControlLow |= cpu_to_le16(TXC_SENDRTS); + txh->MacTxControlLow |= cpu_to_le16(TXC_LONGFRAME); + } + + /* RTS PLCP header */ + ASSERT(IS_ALIGNED((unsigned long)txh->RTSPhyHeader, sizeof(u16))); + rts_plcp = txh->RTSPhyHeader; + if (use_cts) + rts_phylen = DOT11_CTS_LEN + FCS_LEN; + else + rts_phylen = DOT11_RTS_LEN + FCS_LEN; + + wlc_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp); + + /* fallback rate version of RTS PLCP header */ + wlc_compute_plcp(wlc, rts_rspec[1], rts_phylen, + rts_plcp_fallback); + memcpy(&txh->RTSPLCPFallback, rts_plcp_fallback, + sizeof(txh->RTSPLCPFallback)); + + /* RTS frame fields... */ + rts = (struct ieee80211_rts *)&txh->rts_frame; + + durid = wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec[0], + rspec[0], rts_preamble_type[0], + preamble_type[0], phylen, false); + rts->duration = cpu_to_le16(durid); + /* fallback rate version of RTS DUR field */ + durid = wlc_compute_rtscts_dur(wlc, use_cts, + rts_rspec[1], rspec[1], + rts_preamble_type[1], + preamble_type[1], phylen, false); + txh->RTSDurFallback = cpu_to_le16(durid); + + if (use_cts) { + rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | + IEEE80211_STYPE_CTS); + + memcpy(&rts->ra, &h->addr2, ETH_ALEN); + } else { + rts->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | + IEEE80211_STYPE_RTS); + + memcpy(&rts->ra, &h->addr1, 2 * ETH_ALEN); + } + + /* mainrate + * low 8 bits: main frag rate/mcs, + * high 8 bits: rts/cts rate/mcs + */ + mainrates |= (IS_OFDM(rts_rspec[0]) ? + D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) rts_plcp) : + rts_plcp[0]) << 8; + } else { + memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN); + memset((char *)&txh->rts_frame, 0, + sizeof(struct ieee80211_rts)); + memset((char *)txh->RTSPLCPFallback, 0, + sizeof(txh->RTSPLCPFallback)); + txh->RTSDurFallback = 0; + } + +#ifdef SUPPORT_40MHZ + /* add null delimiter count */ + if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && IS_MCS(rspec)) { + txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = + wlc_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen); + } +#endif + + /* Now that RTS/RTS FB preamble types are updated, write the final value */ + txh->MacTxControlHigh = cpu_to_le16(mch); + + /* MainRates (both the rts and frag plcp rates have been calculated now) */ + txh->MainRates = cpu_to_le16(mainrates); + + /* XtraFrameTypes */ + xfts = FRAMETYPE(rspec[1], wlc->mimoft); + xfts |= (FRAMETYPE(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT); + xfts |= (FRAMETYPE(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT); + xfts |= + CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC) << XFTS_CHANNEL_SHIFT; + txh->XtraFrameTypes = cpu_to_le16(xfts); + + /* PhyTxControlWord */ + phyctl = FRAMETYPE(rspec[0], wlc->mimoft); + if ((preamble_type[0] == WLC_SHORT_PREAMBLE) || + (preamble_type[0] == WLC_GF_PREAMBLE)) { + ASSERT((preamble_type[0] == WLC_GF_PREAMBLE) + || !IS_MCS(rspec[0])); + if (RSPEC2RATE(rspec[0]) != WLC_RATE_1M) + phyctl |= PHY_TXC_SHORT_HDR; + wlc->pub->_cnt->txprshort++; + } + + /* phytxant is properly bit shifted */ + phyctl |= wlc_stf_d11hdrs_phyctl_txant(wlc, rspec[0]); + txh->PhyTxControlWord = cpu_to_le16(phyctl); + + /* PhyTxControlWord_1 */ + if (WLC_PHY_11N_CAP(wlc->band)) { + u16 phyctl1 = 0; + + phyctl1 = wlc_phytxctl1_calc(wlc, rspec[0]); + txh->PhyTxControlWord_1 = cpu_to_le16(phyctl1); + phyctl1 = wlc_phytxctl1_calc(wlc, rspec[1]); + txh->PhyTxControlWord_1_Fbr = cpu_to_le16(phyctl1); + + if (use_rts || use_cts) { + phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[0]); + txh->PhyTxControlWord_1_Rts = cpu_to_le16(phyctl1); + phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[1]); + txh->PhyTxControlWord_1_FbrRts = cpu_to_le16(phyctl1); + } + + /* + * For mcs frames, if mixedmode(overloaded with long preamble) is going to be set, + * fill in non-zero MModeLen and/or MModeFbrLen + * it will be unnecessary if they are separated + */ + if (IS_MCS(rspec[0]) && (preamble_type[0] == WLC_MM_PREAMBLE)) { + u16 mmodelen = + wlc_calc_lsig_len(wlc, rspec[0], phylen); + txh->MModeLen = cpu_to_le16(mmodelen); + } + + if (IS_MCS(rspec[1]) && (preamble_type[1] == WLC_MM_PREAMBLE)) { + u16 mmodefbrlen = + wlc_calc_lsig_len(wlc, rspec[1], phylen); + txh->MModeFbrLen = cpu_to_le16(mmodefbrlen); + } + } + + if (IS_MCS(rspec[0])) + ASSERT(IS_MCS(rspec[1])); + + ASSERT(!IS_MCS(rspec[0]) || + ((preamble_type[0] == WLC_MM_PREAMBLE) == (txh->MModeLen != 0))); + ASSERT(!IS_MCS(rspec[1]) || + ((preamble_type[1] == WLC_MM_PREAMBLE) == + (txh->MModeFbrLen != 0))); + + ac = wme_fifo2ac[queue]; + if (SCB_WME(scb) && qos && wlc->edcf_txop[ac]) { + uint frag_dur, dur, dur_fallback; + + ASSERT(!is_multicast_ether_addr(h->addr1)); + + /* WME: Update TXOP threshold */ + if ((!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) && (frag == 0)) { + frag_dur = + wlc_calc_frame_time(wlc, rspec[0], preamble_type[0], + phylen); + + if (rts) { + /* 1 RTS or CTS-to-self frame */ + dur = + wlc_calc_cts_time(wlc, rts_rspec[0], + rts_preamble_type[0]); + dur_fallback = + wlc_calc_cts_time(wlc, rts_rspec[1], + rts_preamble_type[1]); + /* (SIFS + CTS) + SIFS + frame + SIFS + ACK */ + dur += le16_to_cpu(rts->duration); + dur_fallback += + le16_to_cpu(txh->RTSDurFallback); + } else if (use_rifs) { + dur = frag_dur; + dur_fallback = 0; + } else { + /* frame + SIFS + ACK */ + dur = frag_dur; + dur += + wlc_compute_frame_dur(wlc, rspec[0], + preamble_type[0], 0); + + dur_fallback = + wlc_calc_frame_time(wlc, rspec[1], + preamble_type[1], + phylen); + dur_fallback += + wlc_compute_frame_dur(wlc, rspec[1], + preamble_type[1], 0); + } + /* NEED to set TxFesTimeNormal (hard) */ + txh->TxFesTimeNormal = cpu_to_le16((u16) dur); + /* NEED to set fallback rate version of TxFesTimeNormal (hard) */ + txh->TxFesTimeFallback = + cpu_to_le16((u16) dur_fallback); + + /* update txop byte threshold (txop minus intraframe overhead) */ + if (wlc->edcf_txop[ac] >= (dur - frag_dur)) { + { + uint newfragthresh; + + newfragthresh = + wlc_calc_frame_len(wlc, rspec[0], + preamble_type[0], + (wlc-> + edcf_txop[ac] - + (dur - + frag_dur))); + /* range bound the fragthreshold */ + if (newfragthresh < DOT11_MIN_FRAG_LEN) + newfragthresh = + DOT11_MIN_FRAG_LEN; + else if (newfragthresh > + wlc->usr_fragthresh) + newfragthresh = + wlc->usr_fragthresh; + /* update the fragthresh and do txc update */ + if (wlc->fragthresh[queue] != + (u16) newfragthresh) { + wlc->fragthresh[queue] = + (u16) newfragthresh; + } + } + } else + WL_ERROR("wl%d: %s txop invalid for rate %d\n", + wlc->pub->unit, fifo_names[queue], + RSPEC2RATE(rspec[0])); + + if (dur > wlc->edcf_txop[ac]) + WL_ERROR("wl%d: %s: %s txop exceeded phylen %d/%d dur %d/%d\n", + wlc->pub->unit, __func__, + fifo_names[queue], + phylen, wlc->fragthresh[queue], + dur, wlc->edcf_txop[ac]); + } + } + + return 0; +} + +void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs) +{ + wlc_bsscfg_t *cfg = wlc->cfg; + + wlc->pub->_cnt->tbtt++; + + if (BSSCFG_STA(cfg)) { + /* run watchdog here if the watchdog timer is not armed */ + if (WLC_WATCHDOG_TBTT(wlc)) { + u32 cur, delta; + if (wlc->WDarmed) { + wl_del_timer(wlc->wl, wlc->wdtimer); + wlc->WDarmed = false; + } + + cur = OSL_SYSUPTIME(); + delta = cur > wlc->WDlast ? cur - wlc->WDlast : + (u32) ~0 - wlc->WDlast + cur + 1; + if (delta >= TIMER_INTERVAL_WATCHDOG) { + wlc_watchdog((void *)wlc); + wlc->WDlast = cur; + } + + wl_add_timer(wlc->wl, wlc->wdtimer, + wlc_watchdog_backup_bi(wlc), true); + wlc->WDarmed = true; + } + } + + if (!cfg->BSS) { + /* DirFrmQ is now valid...defer setting until end of ATIM window */ + wlc->qvalid |= MCMD_DIRFRMQVAL; + } +} + +/* GP timer is a freerunning 32 bit counter, decrements at 1 us rate */ +void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us) +{ + W_REG(&wlc->regs->gptimer, us); +} + +void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc) +{ + W_REG(&wlc->regs->gptimer, 0); +} + +static void wlc_hwtimer_gptimer_cb(struct wlc_info *wlc) +{ + /* when interrupt is generated, the counter is loaded with last value + * written and continue to decrement. So it has to be cleaned first + */ + W_REG(&wlc->regs->gptimer, 0); +} + +/* + * This fn has all the high level dpc processing from wlc_dpc. + * POLICY: no macinstatus change, no bounding loop. + * All dpc bounding should be handled in BMAC dpc, like txstatus and rxint + */ +void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus) +{ + d11regs_t *regs = wlc->regs; +#ifdef BCMDBG + char flagstr[128]; + static const bcm_bit_desc_t int_flags[] = { + {MI_MACSSPNDD, "MACSSPNDD"}, + {MI_BCNTPL, "BCNTPL"}, + {MI_TBTT, "TBTT"}, + {MI_BCNSUCCESS, "BCNSUCCESS"}, + {MI_BCNCANCLD, "BCNCANCLD"}, + {MI_ATIMWINEND, "ATIMWINEND"}, + {MI_PMQ, "PMQ"}, + {MI_NSPECGEN_0, "NSPECGEN_0"}, + {MI_NSPECGEN_1, "NSPECGEN_1"}, + {MI_MACTXERR, "MACTXERR"}, + {MI_NSPECGEN_3, "NSPECGEN_3"}, + {MI_PHYTXERR, "PHYTXERR"}, + {MI_PME, "PME"}, + {MI_GP0, "GP0"}, + {MI_GP1, "GP1"}, + {MI_DMAINT, "DMAINT"}, + {MI_TXSTOP, "TXSTOP"}, + {MI_CCA, "CCA"}, + {MI_BG_NOISE, "BG_NOISE"}, + {MI_DTIM_TBTT, "DTIM_TBTT"}, + {MI_PRQ, "PRQ"}, + {MI_PWRUP, "PWRUP"}, + {MI_RFDISABLE, "RFDISABLE"}, + {MI_TFS, "TFS"}, + {MI_PHYCHANGED, "PHYCHANGED"}, + {MI_TO, "TO"}, + {0, NULL} + }; + + if (macintstatus & ~(MI_TBTT | MI_TXSTOP)) { + bcm_format_flags(int_flags, macintstatus, flagstr, + sizeof(flagstr)); + WL_TRACE("wl%d: macintstatus 0x%x %s\n", + wlc->pub->unit, macintstatus, flagstr); + } +#endif /* BCMDBG */ + + if (macintstatus & MI_PRQ) { + /* Process probe request FIFO */ + ASSERT(0 && "PRQ Interrupt in non-MBSS"); + } + + /* TBTT indication */ + /* ucode only gives either TBTT or DTIM_TBTT, not both */ + if (macintstatus & (MI_TBTT | MI_DTIM_TBTT)) + wlc_tbtt(wlc, regs); + + if (macintstatus & MI_GP0) { + WL_ERROR("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", + wlc->pub->unit, wlc->pub->now); + + printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", + __func__, wlc->pub->sih->chip, + wlc->pub->sih->chiprev); + + wlc->pub->_cnt->psmwds++; + + /* big hammer */ + wl_init(wlc->wl); + } + + /* gptimer timeout */ + if (macintstatus & MI_TO) { + wlc_hwtimer_gptimer_cb(wlc); + } + + if (macintstatus & MI_RFDISABLE) { + WL_ERROR("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n", + wlc->pub->unit, + R_REG(®s->phydebug) & PDBG_RFD); + /* delay the cleanup to wl_down in IBSS case */ + if ((R_REG(®s->phydebug) & PDBG_RFD)) { + int idx; + wlc_bsscfg_t *bsscfg; + FOREACH_BSS(wlc, idx, bsscfg) { + if (!BSSCFG_STA(bsscfg) || !bsscfg->enable + || !bsscfg->BSS) + continue; + WL_ERROR("wl%d: wlc_dpc: rfdisable -> wlc_bsscfg_disable()\n", + wlc->pub->unit); + } + } + } + + /* send any enq'd tx packets. Just makes sure to jump start tx */ + if (!pktq_empty(&wlc->active_queue->q)) + wlc_send_q(wlc, wlc->active_queue); + + ASSERT(wlc_ps_check(wlc)); +} + +static void wlc_war16165(struct wlc_info *wlc, bool tx) +{ + if (tx) { + /* the post-increment is used in STAY_AWAKE macro */ + if (wlc->txpend16165war++ == 0) + wlc_set_ps_ctrl(wlc); + } else { + wlc->txpend16165war--; + if (wlc->txpend16165war == 0) + wlc_set_ps_ctrl(wlc); + } +} + +/* process an individual tx_status_t */ +/* WLC_HIGH_API */ +bool BCMFASTPATH +wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) +{ + struct sk_buff *p; + uint queue; + d11txh_t *txh; + struct scb *scb = NULL; + bool free_pdu; + struct osl_info *osh; + int tx_rts, tx_frame_count, tx_rts_count; + uint totlen, supr_status; + bool lastframe; + struct ieee80211_hdr *h; + u16 mcl; + struct ieee80211_tx_info *tx_info; + struct ieee80211_tx_rate *txrate; + int i; + + (void)(frm_tx2); /* Compiler reference to avoid unused variable warning */ + + /* discard intermediate indications for ucode with one legitimate case: + * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent + * tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts + * transmission count) + */ + if (!(txs->status & TX_STATUS_AMPDU) + && (txs->status & TX_STATUS_INTERMEDIATE)) { + WLCNTADD(wlc->pub->_cnt->txnoack, + ((txs-> + status & TX_STATUS_FRM_RTX_MASK) >> + TX_STATUS_FRM_RTX_SHIFT)); + WL_ERROR("%s: INTERMEDIATE but not AMPDU\n", __func__); + return false; + } + + osh = wlc->osh; + queue = txs->frameid & TXFID_QUEUE_MASK; + ASSERT(queue < NFIFO); + if (queue >= NFIFO) { + p = NULL; + goto fatal; + } + + p = GETNEXTTXP(wlc, queue); + if (WLC_WAR16165(wlc)) + wlc_war16165(wlc, false); + if (p == NULL) + goto fatal; + + txh = (d11txh_t *) (p->data); + mcl = le16_to_cpu(txh->MacTxControlLow); + + if (txs->phyerr) { + if (WL_ERROR_ON()) { + WL_ERROR("phyerr 0x%x, rate 0x%x\n", + txs->phyerr, txh->MainRates); + wlc_print_txdesc(txh); + } + wlc_print_txstatus(txs); + } + + ASSERT(txs->frameid == cpu_to_le16(txh->TxFrameID)); + if (txs->frameid != cpu_to_le16(txh->TxFrameID)) + goto fatal; + + tx_info = IEEE80211_SKB_CB(p); + h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); + + scb = (struct scb *)tx_info->control.sta->drv_priv; + + if (N_ENAB(wlc->pub)) { + u8 *plcp = (u8 *) (txh + 1); + if (PLCP3_ISSGI(plcp[3])) + wlc->pub->_cnt->txmpdu_sgi++; + if (PLCP3_ISSTBC(plcp[3])) + wlc->pub->_cnt->txmpdu_stbc++; + } + + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { + ASSERT((mcl & TXC_AMPDU_MASK) != TXC_AMPDU_NONE); + wlc_ampdu_dotxstatus(wlc->ampdu, scb, p, txs); + return false; + } + + supr_status = txs->status & TX_STATUS_SUPR_MASK; + if (supr_status == TX_STATUS_SUPR_BADCH) + WL_NONE("%s: Pkt tx suppressed, possibly channel %d\n", + __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec)); + + tx_rts = cpu_to_le16(txh->MacTxControlLow) & TXC_SENDRTS; + tx_frame_count = + (txs->status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT; + tx_rts_count = + (txs->status & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT; + + lastframe = !ieee80211_has_morefrags(h->frame_control); + + if (!lastframe) { + WL_ERROR("Not last frame!\n"); + } else { + u16 sfbl, lfbl; + ieee80211_tx_info_clear_status(tx_info); + if (queue < AC_COUNT) { + sfbl = WLC_WME_RETRY_SFB_GET(wlc, wme_fifo2ac[queue]); + lfbl = WLC_WME_RETRY_LFB_GET(wlc, wme_fifo2ac[queue]); + } else { + sfbl = wlc->SFBL; + lfbl = wlc->LFBL; + } + + txrate = tx_info->status.rates; + /* FIXME: this should use a combination of sfbl, lfbl depending on frame length and RTS setting */ + if ((tx_frame_count > sfbl) && (txrate[1].idx >= 0)) { + /* rate selection requested a fallback rate and we used it */ + txrate->count = lfbl; + txrate[1].count = tx_frame_count - lfbl; + } else { + /* rate selection did not request fallback rate, or we didn't need it */ + txrate->count = tx_frame_count; + /* rc80211_minstrel.c:minstrel_tx_status() expects unused rates to be marked with idx = -1 */ + txrate[1].idx = -1; + txrate[1].count = 0; + } + + /* clear the rest of the rates */ + for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) { + txrate[i].idx = -1; + txrate[i].count = 0; + } + + if (txs->status & TX_STATUS_ACK_RCV) + tx_info->flags |= IEEE80211_TX_STAT_ACK; + } + + totlen = pkttotlen(p); + free_pdu = true; + + wlc_txfifo_complete(wlc, queue, 1); + + if (lastframe) { + p->next = NULL; + p->prev = NULL; + wlc->txretried = 0; + /* remove PLCP & Broadcom tx descriptor header */ + skb_pull(p, D11_PHY_HDR_LEN); + skb_pull(p, D11_TXH_LEN); + ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); + wlc->pub->_cnt->ieee_tx_status++; + } else { + WL_ERROR("%s: Not last frame => not calling tx_status\n", + __func__); + } + + return false; + + fatal: + ASSERT(0); + if (p) + pkt_buf_free_skb(osh, p, true); + + return true; + +} + +void BCMFASTPATH +wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend) +{ + TXPKTPENDDEC(wlc, fifo, txpktpend); + WL_TRACE("wlc_txfifo_complete, pktpend dec %d to %d\n", + txpktpend, TXPKTPENDGET(wlc, fifo)); + + /* There is more room; mark precedences related to this FIFO sendable */ + WLC_TX_FIFO_ENAB(wlc, fifo); + ASSERT(TXPKTPENDGET(wlc, fifo) >= 0); + + if (!TXPKTPENDTOT(wlc)) { + if (wlc->block_datafifo & DATA_BLOCK_TX_SUPR) + wlc_bsscfg_tx_check(wlc); + } + + /* Clear MHF2_TXBCMC_NOW flag if BCMC fifo has drained */ + if (AP_ENAB(wlc->pub) && + wlc->bcmcfifo_drain && !TXPKTPENDGET(wlc, TX_BCMC_FIFO)) { + wlc->bcmcfifo_drain = false; + wlc_mhf(wlc, MHF2, MHF2_TXBCMC_NOW, 0, WLC_BAND_AUTO); + } + + /* figure out which bsscfg is being worked on... */ +} + +/* Given the beacon interval in kus, and a 64 bit TSF in us, + * return the offset (in us) of the TSF from the last TBTT + */ +u32 wlc_calc_tbtt_offset(u32 bp, u32 tsf_h, u32 tsf_l) +{ + u32 k, btklo, btkhi, offset; + + /* TBTT is always an even multiple of the beacon_interval, + * so the TBTT less than or equal to the beacon timestamp is + * the beacon timestamp minus the beacon timestamp modulo + * the beacon interval. + * + * TBTT = BT - (BT % BIu) + * = (BTk - (BTk % BP)) * 2^10 + * + * BT = beacon timestamp (usec, 64bits) + * BTk = beacon timestamp (Kusec, 54bits) + * BP = beacon interval (Kusec, 16bits) + * BIu = BP * 2^10 = beacon interval (usec, 26bits) + * + * To keep the calculations in u32s, the modulo operation + * on the high part of BT needs to be done in parts using the + * relations: + * X*Y mod Z = ((X mod Z) * (Y mod Z)) mod Z + * and + * (X + Y) mod Z = ((X mod Z) + (Y mod Z)) mod Z + * + * So, if BTk[n] = u16 n [0,3] of BTk. + * BTk % BP = SUM((BTk[n] * 2^16n) % BP , 0<=n<4) % BP + * and the SUM term can be broken down: + * (BTk[n] * 2^16n) % BP + * (BTk[n] * (2^16n % BP)) % BP + * + * Create a set of power of 2 mod BP constants: + * K[n] = 2^(16n) % BP + * = (K[n-1] * 2^16) % BP + * K[2] = 2^32 % BP = ((2^16 % BP) * 2^16) % BP + * + * BTk % BP = BTk[0-1] % BP + + * (BTk[2] * K[2]) % BP + + * (BTk[3] * K[3]) % BP + * + * Since K[n] < 2^16 and BTk[n] is < 2^16, then BTk[n] * K[n] < 2^32 + */ + + /* BTk = BT >> 10, btklo = BTk[0-3], bkthi = BTk[4-6] */ + btklo = (tsf_h << 22) | (tsf_l >> 10); + btkhi = tsf_h >> 10; + + /* offset = BTk % BP */ + offset = btklo % bp; + + /* K[2] = ((2^16 % BP) * 2^16) % BP */ + k = (u32) (1 << 16) % bp; + k = (u32) (k * 1 << 16) % (u32) bp; + + /* offset += (BTk[2] * K[2]) % BP */ + offset += ((btkhi & 0xffff) * k) % bp; + + /* BTk[3] */ + btkhi = btkhi >> 16; + + /* k[3] = (K[2] * 2^16) % BP */ + k = (k << 16) % bp; + + /* offset += (BTk[3] * K[3]) % BP */ + offset += ((btkhi & 0xffff) * k) % bp; + + offset = offset % bp; + + /* convert offset from kus to us by shifting up 10 bits and + * add in the low 10 bits of tsf that we ignored + */ + offset = (offset << 10) + (tsf_l & 0x3FF); + + return offset; +} + +/* Update beacon listen interval in shared memory */ +void wlc_bcn_li_upd(struct wlc_info *wlc) +{ + if (AP_ENAB(wlc->pub)) + return; + + /* wake up every DTIM is the default */ + if (wlc->bcn_li_dtim == 1) + wlc_write_shm(wlc, M_BCN_LI, 0); + else + wlc_write_shm(wlc, M_BCN_LI, + (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn); +} + +static void +prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, + struct ieee80211_rx_status *rx_status) +{ + u32 tsf_l, tsf_h; + wlc_d11rxhdr_t *wlc_rxh = (wlc_d11rxhdr_t *) rxh; + int preamble; + int channel; + ratespec_t rspec; + unsigned char *plcp; + + wlc_read_tsf(wlc, &tsf_l, &tsf_h); /* mactime */ + rx_status->mactime = tsf_h; + rx_status->mactime <<= 32; + rx_status->mactime |= tsf_l; + rx_status->flag |= RX_FLAG_TSFT; + + channel = WLC_CHAN_CHANNEL(rxh->RxChan); + + /* XXX Channel/badn needs to be filtered against whether we are single/dual band card */ + if (channel > 14) { + rx_status->band = IEEE80211_BAND_5GHZ; + rx_status->freq = ieee80211_ofdm_chan_to_freq( + WF_CHAN_FACTOR_5_G/2, channel); + + } else { + rx_status->band = IEEE80211_BAND_2GHZ; + rx_status->freq = ieee80211_dsss_chan_to_freq(channel); + } + + rx_status->signal = wlc_rxh->rssi; /* signal */ + + /* noise */ + /* qual */ + rx_status->antenna = (rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; /* ant */ + + plcp = p->data; + + rspec = wlc_compute_rspec(rxh, plcp); + if (IS_MCS(rspec)) { + rx_status->rate_idx = rspec & RSPEC_RATE_MASK; + rx_status->flag |= RX_FLAG_HT; + if (RSPEC_IS40MHZ(rspec)) + rx_status->flag |= RX_FLAG_40MHZ; + } else { + switch (RSPEC2RATE(rspec)) { + case WLC_RATE_1M: + rx_status->rate_idx = 0; + break; + case WLC_RATE_2M: + rx_status->rate_idx = 1; + break; + case WLC_RATE_5M5: + rx_status->rate_idx = 2; + break; + case WLC_RATE_11M: + rx_status->rate_idx = 3; + break; + case WLC_RATE_6M: + rx_status->rate_idx = 4; + break; + case WLC_RATE_9M: + rx_status->rate_idx = 5; + break; + case WLC_RATE_12M: + rx_status->rate_idx = 6; + break; + case WLC_RATE_18M: + rx_status->rate_idx = 7; + break; + case WLC_RATE_24M: + rx_status->rate_idx = 8; + break; + case WLC_RATE_36M: + rx_status->rate_idx = 9; + break; + case WLC_RATE_48M: + rx_status->rate_idx = 10; + break; + case WLC_RATE_54M: + rx_status->rate_idx = 11; + break; + default: + WL_ERROR("%s: Unknown rate\n", __func__); + } + + /* Determine short preamble and rate_idx */ + preamble = 0; + if (IS_CCK(rspec)) { + if (rxh->PhyRxStatus_0 & PRXS0_SHORTH) + WL_ERROR("Short CCK\n"); + rx_status->flag |= RX_FLAG_SHORTPRE; + } else if (IS_OFDM(rspec)) { + rx_status->flag |= RX_FLAG_SHORTPRE; + } else { + WL_ERROR("%s: Unknown modulation\n", __func__); + } + } + + if (PLCP3_ISSGI(plcp[3])) + rx_status->flag |= RX_FLAG_SHORT_GI; + + if (rxh->RxStatus1 & RXS_DECERR) { + rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC; + WL_ERROR("%s: RX_FLAG_FAILED_PLCP_CRC\n", __func__); + } + if (rxh->RxStatus1 & RXS_FCSERR) { + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + WL_ERROR("%s: RX_FLAG_FAILED_FCS_CRC\n", __func__); + } +} + +static void +wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, d11rxhdr_t *rxh, + struct sk_buff *p) +{ + int len_mpdu; + struct ieee80211_rx_status rx_status; +#if defined(BCMDBG) + struct sk_buff *skb = p; +#endif /* BCMDBG */ + /* Todo: + * Cache plcp for first MPDU of AMPD and use chacched version for INTERMEDIATE. + * Test for INTERMEDIATE like so: + * if (!(plcp[0] | plcp[1] | plcp[2])) + */ + + memset(&rx_status, 0, sizeof(rx_status)); + prep_mac80211_status(wlc, rxh, p, &rx_status); + + /* mac header+body length, exclude CRC and plcp header */ + len_mpdu = p->len - D11_PHY_HDR_LEN - FCS_LEN; + skb_pull(p, D11_PHY_HDR_LEN); + __skb_trim(p, len_mpdu); + + ASSERT(!(p->next)); + ASSERT(!(p->prev)); + + ASSERT(IS_ALIGNED((unsigned long)skb->data, 2)); + + memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status)); + ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p); + + wlc->pub->_cnt->ieee_rx++; + osh->pktalloced--; + return; +} + +void wlc_bss_list_free(struct wlc_info *wlc, struct wlc_bss_list *bss_list) +{ + uint index; + + if (!bss_list) { + WL_ERROR("%s: Attempting to free NULL list\n", __func__); + return; + } + /* inspect all BSS descriptor */ + for (index = 0; index < bss_list->count; index++) { + kfree(bss_list->ptrs[index]); + bss_list->ptrs[index] = NULL; + } + bss_list->count = 0; +} + +/* Process received frames */ +/* + * Return true if more frames need to be processed. false otherwise. + * Param 'bound' indicates max. # frames to process before break out. + */ +/* WLC_HIGH_API */ +void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) +{ + d11rxhdr_t *rxh; + struct ieee80211_hdr *h; + struct osl_info *osh; + uint len; + bool is_amsdu; + + WL_TRACE("wl%d: wlc_recv\n", wlc->pub->unit); + + osh = wlc->osh; + + /* frame starts with rxhdr */ + rxh = (d11rxhdr_t *) (p->data); + + /* strip off rxhdr */ + skb_pull(p, wlc->hwrxoff); + + /* fixup rx header endianness */ + rxh->RxFrameSize = le16_to_cpu(rxh->RxFrameSize); + rxh->PhyRxStatus_0 = le16_to_cpu(rxh->PhyRxStatus_0); + rxh->PhyRxStatus_1 = le16_to_cpu(rxh->PhyRxStatus_1); + rxh->PhyRxStatus_2 = le16_to_cpu(rxh->PhyRxStatus_2); + rxh->PhyRxStatus_3 = le16_to_cpu(rxh->PhyRxStatus_3); + rxh->PhyRxStatus_4 = le16_to_cpu(rxh->PhyRxStatus_4); + rxh->PhyRxStatus_5 = le16_to_cpu(rxh->PhyRxStatus_5); + rxh->RxStatus1 = le16_to_cpu(rxh->RxStatus1); + rxh->RxStatus2 = le16_to_cpu(rxh->RxStatus2); + rxh->RxTSFTime = le16_to_cpu(rxh->RxTSFTime); + rxh->RxChan = le16_to_cpu(rxh->RxChan); + + /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ + if (rxh->RxStatus1 & RXS_PBPRES) { + if (p->len < 2) { + wlc->pub->_cnt->rxrunt++; + WL_ERROR("wl%d: wlc_recv: rcvd runt of len %d\n", + wlc->pub->unit, p->len); + goto toss; + } + skb_pull(p, 2); + } + + h = (struct ieee80211_hdr *)(p->data + D11_PHY_HDR_LEN); + len = p->len; + + if (rxh->RxStatus1 & RXS_FCSERR) { + if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) { + WL_ERROR("FCSERR while scanning******* - tossing\n"); + goto toss; + } else { + WL_ERROR("RCSERR!!!\n"); + goto toss; + } + } + + /* check received pkt has at least frame control field */ + if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control)) { + wlc->pub->_cnt->rxrunt++; + goto toss; + } + + is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK; + + /* explicitly test bad src address to avoid sending bad deauth */ + if (!is_amsdu) { + /* CTS and ACK CTL frames are w/o a2 */ + + if (ieee80211_is_data(h->frame_control) || + ieee80211_is_mgmt(h->frame_control)) { + if ((is_zero_ether_addr(h->addr2) || + is_multicast_ether_addr(h->addr2))) { + WL_ERROR("wl%d: %s: dropping a frame with " + "invalid src mac address, a2: %pM\n", + wlc->pub->unit, __func__, h->addr2); + wlc->pub->_cnt->rxbadsrcmac++; + goto toss; + } + wlc->pub->_cnt->rxfrag++; + } + } + + /* due to sheer numbers, toss out probe reqs for now */ + if (ieee80211_is_probe_req(h->frame_control)) + goto toss; + + if (is_amsdu) { + WL_ERROR("%s: is_amsdu causing toss\n", __func__); + goto toss; + } + + wlc_recvctl(wlc, osh, rxh, p); + return; + + toss: + pkt_buf_free_skb(osh, p, false); +} + +/* calculate frame duration for Mixed-mode L-SIG spoofing, return + * number of bytes goes in the length field + * + * Formula given by HT PHY Spec v 1.13 + * len = 3(nsyms + nstream + 3) - 3 + */ +u16 BCMFASTPATH +wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, uint mac_len) +{ + uint nsyms, len = 0, kNdps; + + WL_TRACE("wl%d: wlc_calc_lsig_len: rate %d, len%d\n", + wlc->pub->unit, RSPEC2RATE(ratespec), mac_len); + + if (IS_MCS(ratespec)) { + uint mcs = ratespec & RSPEC_RATE_MASK; + /* MCS_TXS(mcs) returns num tx streams - 1 */ + int tot_streams = (MCS_TXS(mcs) + 1) + RSPEC_STC(ratespec); + + ASSERT(WLC_PHY_11N_CAP(wlc->band)); + /* the payload duration calculation matches that of regular ofdm */ + /* 1000Ndbps = kbps * 4 */ + kNdps = + MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec), + RSPEC_ISSGI(ratespec)) * 4; + + if (RSPEC_STC(ratespec) == 0) + /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ + nsyms = + CEIL((APHY_SERVICE_NBITS + 8 * mac_len + + APHY_TAIL_NBITS) * 1000, kNdps); + else + /* STBC needs to have even number of symbols */ + nsyms = + 2 * + CEIL((APHY_SERVICE_NBITS + 8 * mac_len + + APHY_TAIL_NBITS) * 1000, 2 * kNdps); + + nsyms += (tot_streams + 3); /* (+3) account for HT-SIG(2) and HT-STF(1) */ + /* 3 bytes/symbol @ legacy 6Mbps rate */ + len = (3 * nsyms) - 3; /* (-3) excluding service bits and tail bits */ + } + + return (u16) len; +} + +/* calculate frame duration of a given rate and length, return time in usec unit */ +uint BCMFASTPATH +wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, + uint mac_len) +{ + uint nsyms, dur = 0, Ndps, kNdps; + uint rate = RSPEC2RATE(ratespec); + + if (rate == 0) { + ASSERT(0); + WL_ERROR("wl%d: WAR: using rate of 1 mbps\n", wlc->pub->unit); + rate = WLC_RATE_1M; + } + + WL_TRACE("wl%d: wlc_calc_frame_time: rspec 0x%x, preamble_type %d, len%d\n", + wlc->pub->unit, ratespec, preamble_type, mac_len); + + if (IS_MCS(ratespec)) { + uint mcs = ratespec & RSPEC_RATE_MASK; + int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec); + ASSERT(WLC_PHY_11N_CAP(wlc->band)); + ASSERT(WLC_IS_MIMO_PREAMBLE(preamble_type)); + + dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT); + if (preamble_type == WLC_MM_PREAMBLE) + dur += PREN_MM_EXT; + /* 1000Ndbps = kbps * 4 */ + kNdps = + MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec), + RSPEC_ISSGI(ratespec)) * 4; + + if (RSPEC_STC(ratespec) == 0) + /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ + nsyms = + CEIL((APHY_SERVICE_NBITS + 8 * mac_len + + APHY_TAIL_NBITS) * 1000, kNdps); + else + /* STBC needs to have even number of symbols */ + nsyms = + 2 * + CEIL((APHY_SERVICE_NBITS + 8 * mac_len + + APHY_TAIL_NBITS) * 1000, 2 * kNdps); + + dur += APHY_SYMBOL_TIME * nsyms; + if (BAND_2G(wlc->band->bandtype)) + dur += DOT11_OFDM_SIGNAL_EXTENSION; + } else if (IS_OFDM(rate)) { + dur = APHY_PREAMBLE_TIME; + dur += APHY_SIGNAL_TIME; + /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */ + Ndps = rate * 2; + /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ + nsyms = + CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS), + Ndps); + dur += APHY_SYMBOL_TIME * nsyms; + if (BAND_2G(wlc->band->bandtype)) + dur += DOT11_OFDM_SIGNAL_EXTENSION; + } else { + /* calc # bits * 2 so factor of 2 in rate (1/2 mbps) will divide out */ + mac_len = mac_len * 8 * 2; + /* calc ceiling of bits/rate = microseconds of air time */ + dur = (mac_len + rate - 1) / rate; + if (preamble_type & WLC_SHORT_PREAMBLE) + dur += BPHY_PLCP_SHORT_TIME; + else + dur += BPHY_PLCP_TIME; + } + return dur; +} + +/* The opposite of wlc_calc_frame_time */ +static uint +wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, + uint dur) +{ + uint nsyms, mac_len, Ndps, kNdps; + uint rate = RSPEC2RATE(ratespec); + + WL_TRACE("wl%d: wlc_calc_frame_len: rspec 0x%x, preamble_type %d, dur %d\n", + wlc->pub->unit, ratespec, preamble_type, dur); + + if (IS_MCS(ratespec)) { + uint mcs = ratespec & RSPEC_RATE_MASK; + int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec); + ASSERT(WLC_PHY_11N_CAP(wlc->band)); + dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT); + /* payload calculation matches that of regular ofdm */ + if (BAND_2G(wlc->band->bandtype)) + dur -= DOT11_OFDM_SIGNAL_EXTENSION; + /* kNdbps = kbps * 4 */ + kNdps = + MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec), + RSPEC_ISSGI(ratespec)) * 4; + nsyms = dur / APHY_SYMBOL_TIME; + mac_len = + ((nsyms * kNdps) - + ((APHY_SERVICE_NBITS + APHY_TAIL_NBITS) * 1000)) / 8000; + } else if (IS_OFDM(ratespec)) { + dur -= APHY_PREAMBLE_TIME; + dur -= APHY_SIGNAL_TIME; + /* Ndbps = Mbps * 4 = rate(500Kbps) * 2 */ + Ndps = rate * 2; + nsyms = dur / APHY_SYMBOL_TIME; + mac_len = + ((nsyms * Ndps) - + (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8; + } else { + if (preamble_type & WLC_SHORT_PREAMBLE) + dur -= BPHY_PLCP_SHORT_TIME; + else + dur -= BPHY_PLCP_TIME; + mac_len = dur * rate; + /* divide out factor of 2 in rate (1/2 mbps) */ + mac_len = mac_len / 8 / 2; + } + return mac_len; +} + +static uint +wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) +{ + WL_TRACE("wl%d: wlc_calc_ba_time: rspec 0x%x, preamble_type %d\n", + wlc->pub->unit, rspec, preamble_type); + /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than + * or equal to the rate of the immediately previous frame in the FES + */ + rspec = WLC_BASIC_RATE(wlc, rspec); + ASSERT(VALID_RATE_DBG(wlc, rspec)); + + /* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */ + return wlc_calc_frame_time(wlc, rspec, preamble_type, + (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN + + FCS_LEN)); +} + +static uint BCMFASTPATH +wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) +{ + uint dur = 0; + + WL_TRACE("wl%d: wlc_calc_ack_time: rspec 0x%x, preamble_type %d\n", + wlc->pub->unit, rspec, preamble_type); + /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than + * or equal to the rate of the immediately previous frame in the FES + */ + rspec = WLC_BASIC_RATE(wlc, rspec); + ASSERT(VALID_RATE_DBG(wlc, rspec)); + + /* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */ + dur = + wlc_calc_frame_time(wlc, rspec, preamble_type, + (DOT11_ACK_LEN + FCS_LEN)); + return dur; +} + +static uint +wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) +{ + WL_TRACE("wl%d: wlc_calc_cts_time: ratespec 0x%x, preamble_type %d\n", + wlc->pub->unit, rspec, preamble_type); + return wlc_calc_ack_time(wlc, rspec, preamble_type); +} + +/* derive wlc->band->basic_rate[] table from 'rateset' */ +void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset) +{ + u8 rate; + u8 mandatory; + u8 cck_basic = 0; + u8 ofdm_basic = 0; + u8 *br = wlc->band->basic_rate; + uint i; + + /* incoming rates are in 500kbps units as in 802.11 Supported Rates */ + memset(br, 0, WLC_MAXRATE + 1); + + /* For each basic rate in the rates list, make an entry in the + * best basic lookup. + */ + for (i = 0; i < rateset->count; i++) { + /* only make an entry for a basic rate */ + if (!(rateset->rates[i] & WLC_RATE_FLAG)) + continue; + + /* mask off basic bit */ + rate = (rateset->rates[i] & RATE_MASK); + + if (rate > WLC_MAXRATE) { + WL_ERROR("wlc_rate_lookup_init: invalid rate 0x%X in rate set\n", + rateset->rates[i]); + continue; + } + + br[rate] = rate; + } + + /* The rate lookup table now has non-zero entries for each + * basic rate, equal to the basic rate: br[basicN] = basicN + * + * To look up the best basic rate corresponding to any + * particular rate, code can use the basic_rate table + * like this + * + * basic_rate = wlc->band->basic_rate[tx_rate] + * + * Make sure there is a best basic rate entry for + * every rate by walking up the table from low rates + * to high, filling in holes in the lookup table + */ + + for (i = 0; i < wlc->band->hw_rateset.count; i++) { + rate = wlc->band->hw_rateset.rates[i]; + ASSERT(rate <= WLC_MAXRATE); + + if (br[rate] != 0) { + /* This rate is a basic rate. + * Keep track of the best basic rate so far by + * modulation type. + */ + if (IS_OFDM(rate)) + ofdm_basic = rate; + else + cck_basic = rate; + + continue; + } + + /* This rate is not a basic rate so figure out the + * best basic rate less than this rate and fill in + * the hole in the table + */ + + br[rate] = IS_OFDM(rate) ? ofdm_basic : cck_basic; + + if (br[rate] != 0) + continue; + + if (IS_OFDM(rate)) { + /* In 11g and 11a, the OFDM mandatory rates are 6, 12, and 24 Mbps */ + if (rate >= WLC_RATE_24M) + mandatory = WLC_RATE_24M; + else if (rate >= WLC_RATE_12M) + mandatory = WLC_RATE_12M; + else + mandatory = WLC_RATE_6M; + } else { + /* In 11b, all the CCK rates are mandatory 1 - 11 Mbps */ + mandatory = rate; + } + + br[rate] = mandatory; + } +} + +static void wlc_write_rate_shm(struct wlc_info *wlc, u8 rate, u8 basic_rate) +{ + u8 phy_rate, index; + u8 basic_phy_rate, basic_index; + u16 dir_table, basic_table; + u16 basic_ptr; + + /* Shared memory address for the table we are reading */ + dir_table = IS_OFDM(basic_rate) ? M_RT_DIRMAP_A : M_RT_DIRMAP_B; + + /* Shared memory address for the table we are writing */ + basic_table = IS_OFDM(rate) ? M_RT_BBRSMAP_A : M_RT_BBRSMAP_B; + + /* + * for a given rate, the LS-nibble of the PLCP SIGNAL field is + * the index into the rate table. + */ + phy_rate = rate_info[rate] & RATE_MASK; + basic_phy_rate = rate_info[basic_rate] & RATE_MASK; + index = phy_rate & 0xf; + basic_index = basic_phy_rate & 0xf; + + /* Find the SHM pointer to the ACK rate entry by looking in the + * Direct-map Table + */ + basic_ptr = wlc_read_shm(wlc, (dir_table + basic_index * 2)); + + /* Update the SHM BSS-basic-rate-set mapping table with the pointer + * to the correct basic rate for the given incoming rate + */ + wlc_write_shm(wlc, (basic_table + index * 2), basic_ptr); +} + +static const wlc_rateset_t *wlc_rateset_get_hwrs(struct wlc_info *wlc) +{ + const wlc_rateset_t *rs_dflt; + + if (WLC_PHY_11N_CAP(wlc->band)) { + if (BAND_5G(wlc->band->bandtype)) + rs_dflt = &ofdm_mimo_rates; + else + rs_dflt = &cck_ofdm_mimo_rates; + } else if (wlc->band->gmode) + rs_dflt = &cck_ofdm_rates; + else + rs_dflt = &cck_rates; + + return rs_dflt; +} + +void wlc_set_ratetable(struct wlc_info *wlc) +{ + const wlc_rateset_t *rs_dflt; + wlc_rateset_t rs; + u8 rate, basic_rate; + uint i; + + rs_dflt = wlc_rateset_get_hwrs(wlc); + ASSERT(rs_dflt != NULL); + + wlc_rateset_copy(rs_dflt, &rs); + wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams); + + /* walk the phy rate table and update SHM basic rate lookup table */ + for (i = 0; i < rs.count; i++) { + rate = rs.rates[i] & RATE_MASK; + + /* for a given rate WLC_BASIC_RATE returns the rate at + * which a response ACK/CTS should be sent. + */ + basic_rate = WLC_BASIC_RATE(wlc, rate); + if (basic_rate == 0) { + /* This should only happen if we are using a + * restricted rateset. + */ + basic_rate = rs.rates[0] & RATE_MASK; + } + + wlc_write_rate_shm(wlc, rate, basic_rate); + } +} + +/* + * Return true if the specified rate is supported by the specified band. + * WLC_BAND_AUTO indicates the current band. + */ +bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rspec, int band, + bool verbose) +{ + wlc_rateset_t *hw_rateset; + uint i; + + if ((band == WLC_BAND_AUTO) || (band == wlc->band->bandtype)) { + hw_rateset = &wlc->band->hw_rateset; + } else if (NBANDS(wlc) > 1) { + hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset; + } else { + /* other band specified and we are a single band device */ + return false; + } + + /* check if this is a mimo rate */ + if (IS_MCS(rspec)) { + if (!VALID_MCS((rspec & RSPEC_RATE_MASK))) + goto error; + + return isset(hw_rateset->mcs, (rspec & RSPEC_RATE_MASK)); + } + + for (i = 0; i < hw_rateset->count; i++) + if (hw_rateset->rates[i] == RSPEC2RATE(rspec)) + return true; + error: + if (verbose) { + WL_ERROR("wl%d: wlc_valid_rate: rate spec 0x%x not in hw_rateset\n", + wlc->pub->unit, rspec); + } + + return false; +} + +static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap) +{ + uint i; + struct wlcband *band; + + for (i = 0; i < NBANDS(wlc); i++) { + if (IS_SINGLEBAND_5G(wlc->deviceid)) + i = BAND_5G_INDEX; + band = wlc->bandstate[i]; + if (band->bandtype == WLC_BAND_5G) { + if ((bwcap == WLC_N_BW_40ALL) + || (bwcap == WLC_N_BW_20IN2G_40IN5G)) + band->mimo_cap_40 = true; + else + band->mimo_cap_40 = false; + } else { + ASSERT(band->bandtype == WLC_BAND_2G); + if (bwcap == WLC_N_BW_40ALL) + band->mimo_cap_40 = true; + else + band->mimo_cap_40 = false; + } + } + + wlc->mimo_band_bwcap = bwcap; +} + +void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len) +{ + const wlc_rateset_t *rs_dflt; + wlc_rateset_t rs; + u8 rate; + u16 entry_ptr; + u8 plcp[D11_PHY_HDR_LEN]; + u16 dur, sifs; + uint i; + + sifs = SIFS(wlc->band); + + rs_dflt = wlc_rateset_get_hwrs(wlc); + ASSERT(rs_dflt != NULL); + + wlc_rateset_copy(rs_dflt, &rs); + wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams); + + /* walk the phy rate table and update MAC core SHM basic rate table entries */ + for (i = 0; i < rs.count; i++) { + rate = rs.rates[i] & RATE_MASK; + + entry_ptr = wlc_rate_shm_offset(wlc, rate); + + /* Calculate the Probe Response PLCP for the given rate */ + wlc_compute_plcp(wlc, rate, frame_len, plcp); + + /* Calculate the duration of the Probe Response frame plus SIFS for the MAC */ + dur = + (u16) wlc_calc_frame_time(wlc, rate, WLC_LONG_PREAMBLE, + frame_len); + dur += sifs; + + /* Update the SHM Rate Table entry Probe Response values */ + wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS, + (u16) (plcp[0] + (plcp[1] << 8))); + wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS + 2, + (u16) (plcp[2] + (plcp[3] << 8))); + wlc_write_shm(wlc, entry_ptr + M_RT_PRS_DUR_POS, dur); + } +} + +u16 +wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec, + bool short_preamble, bool phydelay) +{ + uint bcntsfoff = 0; + + if (IS_MCS(rspec)) { + WL_ERROR("wl%d: recd beacon with mcs rate; rspec 0x%x\n", + wlc->pub->unit, rspec); + } else if (IS_OFDM(rspec)) { + /* tx delay from MAC through phy to air (2.1 usec) + + * phy header time (preamble + PLCP SIGNAL == 20 usec) + + * PLCP SERVICE + MAC header time (SERVICE + FC + DUR + A1 + A2 + A3 + SEQ == 26 + * bytes at beacon rate) + */ + bcntsfoff += phydelay ? D11A_PHY_TX_DELAY : 0; + bcntsfoff += APHY_PREAMBLE_TIME + APHY_SIGNAL_TIME; + bcntsfoff += + wlc_compute_airtime(wlc, rspec, + APHY_SERVICE_NBITS / 8 + + DOT11_MAC_HDR_LEN); + } else { + /* tx delay from MAC through phy to air (3.4 usec) + + * phy header time (long preamble + PLCP == 192 usec) + + * MAC header time (FC + DUR + A1 + A2 + A3 + SEQ == 24 bytes at beacon rate) + */ + bcntsfoff += phydelay ? D11B_PHY_TX_DELAY : 0; + bcntsfoff += + short_preamble ? D11B_PHY_SPREHDR_TIME : + D11B_PHY_LPREHDR_TIME; + bcntsfoff += wlc_compute_airtime(wlc, rspec, DOT11_MAC_HDR_LEN); + } + return (u16) (bcntsfoff); +} + +/* Max buffering needed for beacon template/prb resp template is 142 bytes. + * + * PLCP header is 6 bytes. + * 802.11 A3 header is 24 bytes. + * Max beacon frame body template length is 112 bytes. + * Max probe resp frame body template length is 110 bytes. + * + * *len on input contains the max length of the packet available. + * + * The *len value is set to the number of bytes in buf used, and starts with the PLCP + * and included up to, but not including, the 4 byte FCS. + */ +static void +wlc_bcn_prb_template(struct wlc_info *wlc, u16 type, ratespec_t bcn_rspec, + wlc_bsscfg_t *cfg, u16 *buf, int *len) +{ + static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; + cck_phy_hdr_t *plcp; + struct ieee80211_mgmt *h; + int hdr_len, body_len; + + ASSERT(*len >= 142); + ASSERT(type == IEEE80211_STYPE_BEACON || + type == IEEE80211_STYPE_PROBE_RESP); + + if (MBSS_BCN_ENAB(cfg) && type == IEEE80211_STYPE_BEACON) + hdr_len = DOT11_MAC_HDR_LEN; + else + hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN; + body_len = *len - hdr_len; /* calc buffer size provided for frame body */ + + *len = hdr_len + body_len; /* return actual size */ + + /* format PHY and MAC headers */ + memset((char *)buf, 0, hdr_len); + + plcp = (cck_phy_hdr_t *) buf; + + /* PLCP for Probe Response frames are filled in from core's rate table */ + if (type == IEEE80211_STYPE_BEACON && !MBSS_BCN_ENAB(cfg)) { + /* fill in PLCP */ + wlc_compute_plcp(wlc, bcn_rspec, + (DOT11_MAC_HDR_LEN + body_len + FCS_LEN), + (u8 *) plcp); + + } + /* "Regular" and 16 MBSS but not for 4 MBSS */ + /* Update the phytxctl for the beacon based on the rspec */ + if (!SOFTBCN_ENAB(cfg)) + wlc_beacon_phytxctl_txant_upd(wlc, bcn_rspec); + + if (MBSS_BCN_ENAB(cfg) && type == IEEE80211_STYPE_BEACON) + h = (struct ieee80211_mgmt *)&plcp[0]; + else + h = (struct ieee80211_mgmt *)&plcp[1]; + + /* fill in 802.11 header */ + h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type); + + /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */ + /* A1 filled in by MAC for prb resp, broadcast for bcn */ + if (type == IEEE80211_STYPE_BEACON) + memcpy(&h->da, ðer_bcast, ETH_ALEN); + memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN); + memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN); + + /* SEQ filled in by MAC */ + + return; +} + +int wlc_get_header_len() +{ + return TXOFF; +} + +/* Update a beacon for a particular BSS + * For MBSS, this updates the software template and sets "latest" to the index of the + * template updated. + * Otherwise, it updates the hardware template. + */ +void wlc_bss_update_beacon(struct wlc_info *wlc, wlc_bsscfg_t *cfg) +{ + int len = BCN_TMPL_LEN; + + /* Clear the soft intmask */ + wlc->defmacintmask &= ~MI_BCNTPL; + + if (!cfg->up) { /* Only allow updates on an UP bss */ + return; + } + + /* Optimize: Some of if/else could be combined */ + if (!MBSS_BCN_ENAB(cfg) && HWBCN_ENAB(cfg)) { + /* Hardware beaconing for this config */ + u16 bcn[BCN_TMPL_LEN / 2]; + u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD; + d11regs_t *regs = wlc->regs; + struct osl_info *osh = NULL; + + osh = wlc->osh; + + /* Check if both templates are in use, if so sched. an interrupt + * that will call back into this routine + */ + if ((R_REG(®s->maccommand) & both_valid) == both_valid) { + /* clear any previous status */ + W_REG(®s->macintstatus, MI_BCNTPL); + } + /* Check that after scheduling the interrupt both of the + * templates are still busy. if not clear the int. & remask + */ + if ((R_REG(®s->maccommand) & both_valid) == both_valid) { + wlc->defmacintmask |= MI_BCNTPL; + return; + } + + wlc->bcn_rspec = + wlc_lowest_basic_rspec(wlc, &cfg->current_bss->rateset); + ASSERT(wlc_valid_rate + (wlc, wlc->bcn_rspec, + CHSPEC_IS2G(cfg->current_bss-> + chanspec) ? WLC_BAND_2G : WLC_BAND_5G, + true)); + + /* update the template and ucode shm */ + wlc_bcn_prb_template(wlc, IEEE80211_STYPE_BEACON, + wlc->bcn_rspec, cfg, bcn, &len); + wlc_write_hw_bcntemplates(wlc, bcn, len, false); + } +} + +/* + * Update all beacons for the system. + */ +void wlc_update_beacon(struct wlc_info *wlc) +{ + int idx; + wlc_bsscfg_t *bsscfg; + + /* update AP or IBSS beacons */ + FOREACH_BSS(wlc, idx, bsscfg) { + if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS)) + wlc_bss_update_beacon(wlc, bsscfg); + } +} + +/* Write ssid into shared memory */ +void wlc_shm_ssid_upd(struct wlc_info *wlc, wlc_bsscfg_t *cfg) +{ + u8 *ssidptr = cfg->SSID; + u16 base = M_SSID; + u8 ssidbuf[IEEE80211_MAX_SSID_LEN]; + + /* padding the ssid with zero and copy it into shm */ + memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN); + memcpy(ssidbuf, ssidptr, cfg->SSID_len); + + wlc_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN); + + if (!MBSS_BCN_ENAB(cfg)) + wlc_write_shm(wlc, M_SSIDLEN, (u16) cfg->SSID_len); +} + +void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend) +{ + int idx; + wlc_bsscfg_t *bsscfg; + + /* update AP or IBSS probe responses */ + FOREACH_BSS(wlc, idx, bsscfg) { + if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS)) + wlc_bss_update_probe_resp(wlc, bsscfg, suspend); + } +} + +void +wlc_bss_update_probe_resp(struct wlc_info *wlc, wlc_bsscfg_t *cfg, bool suspend) +{ + u16 prb_resp[BCN_TMPL_LEN / 2]; + int len = BCN_TMPL_LEN; + + /* write the probe response to hardware, or save in the config structure */ + if (!MBSS_PRB_ENAB(cfg)) { + + /* create the probe response template */ + wlc_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0, cfg, + prb_resp, &len); + + if (suspend) + wlc_suspend_mac_and_wait(wlc); + + /* write the probe response into the template region */ + wlc_bmac_write_template_ram(wlc->hw, T_PRS_TPL_BASE, + (len + 3) & ~3, prb_resp); + + /* write the length of the probe response frame (+PLCP/-FCS) */ + wlc_write_shm(wlc, M_PRB_RESP_FRM_LEN, (u16) len); + + /* write the SSID and SSID length */ + wlc_shm_ssid_upd(wlc, cfg); + + /* + * Write PLCP headers and durations for probe response frames at all rates. + * Use the actual frame length covered by the PLCP header for the call to + * wlc_mod_prb_rsp_rate_table() by subtracting the PLCP len and adding the FCS. + */ + len += (-D11_PHY_HDR_LEN + FCS_LEN); + wlc_mod_prb_rsp_rate_table(wlc, (u16) len); + + if (suspend) + wlc_enable_mac(wlc); + } else { /* Generating probe resp in sw; update local template */ + ASSERT(0 && "No software probe response support without MBSS"); + } +} + +/* prepares pdu for transmission. returns BCM error codes */ +int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) +{ + struct osl_info *osh; + uint fifo; + d11txh_t *txh; + struct ieee80211_hdr *h; + struct scb *scb; + + osh = wlc->osh; + + ASSERT(pdu); + txh = (d11txh_t *) (pdu->data); + ASSERT(txh); + h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); + ASSERT(h); + + /* get the pkt queue info. This was put at wlc_sendctl or wlc_send for PDU */ + fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK; + + scb = NULL; + + *fifop = fifo; + + /* return if insufficient dma resources */ + if (TXAVAIL(wlc, fifo) < MAX_DMA_SEGS) { + /* Mark precedences related to this FIFO, unsendable */ + WLC_TX_FIFO_CLEAR(wlc, fifo); + return BCME_BUSY; + } + + if (!ieee80211_is_data(txh->MacFrameControl)) + wlc->pub->_cnt->txctl++; + + return 0; +} + +/* init tx reported rate mechanism */ +void wlc_reprate_init(struct wlc_info *wlc) +{ + int i; + wlc_bsscfg_t *bsscfg; + + FOREACH_BSS(wlc, i, bsscfg) { + wlc_bsscfg_reprate_init(bsscfg); + } +} + +/* per bsscfg init tx reported rate mechanism */ +void wlc_bsscfg_reprate_init(wlc_bsscfg_t *bsscfg) +{ + bsscfg->txrspecidx = 0; + memset((char *)bsscfg->txrspec, 0, sizeof(bsscfg->txrspec)); +} + +/* Retrieve a consolidated set of revision information, + * typically for the WLC_GET_REVINFO ioctl + */ +int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len) +{ + wlc_rev_info_t *rinfo = (wlc_rev_info_t *) buf; + + if (len < WL_REV_INFO_LEGACY_LENGTH) + return BCME_BUFTOOSHORT; + + rinfo->vendorid = wlc->vendorid; + rinfo->deviceid = wlc->deviceid; + rinfo->radiorev = (wlc->band->radiorev << IDCODE_REV_SHIFT) | + (wlc->band->radioid << IDCODE_ID_SHIFT); + rinfo->chiprev = wlc->pub->sih->chiprev; + rinfo->corerev = wlc->pub->corerev; + rinfo->boardid = wlc->pub->sih->boardtype; + rinfo->boardvendor = wlc->pub->sih->boardvendor; + rinfo->boardrev = wlc->pub->boardrev; + rinfo->ucoderev = wlc->ucode_rev; + rinfo->driverrev = EPI_VERSION_NUM; + rinfo->bus = wlc->pub->sih->bustype; + rinfo->chipnum = wlc->pub->sih->chip; + + if (len >= (offsetof(wlc_rev_info_t, chippkg))) { + rinfo->phytype = wlc->band->phytype; + rinfo->phyrev = wlc->band->phyrev; + rinfo->anarev = 0; /* obsolete stuff, suppress */ + } + + if (len >= sizeof(*rinfo)) { + rinfo->chippkg = wlc->pub->sih->chippkg; + } + + return BCME_OK; +} + +void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs) +{ + wlc_rateset_default(rs, NULL, wlc->band->phytype, wlc->band->bandtype, + false, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub), + CHSPEC_WLC_BW(wlc->default_bss->chanspec), + wlc->stf->txstreams); +} + +static void wlc_bss_default_init(struct wlc_info *wlc) +{ + chanspec_t chanspec; + struct wlcband *band; + wlc_bss_info_t *bi = wlc->default_bss; + + /* init default and target BSS with some sane initial values */ + memset((char *)(bi), 0, sizeof(wlc_bss_info_t)); + bi->beacon_period = ISSIM_ENAB(wlc->pub->sih) ? BEACON_INTERVAL_DEF_QT : + BEACON_INTERVAL_DEFAULT; + bi->dtim_period = ISSIM_ENAB(wlc->pub->sih) ? DTIM_INTERVAL_DEF_QT : + DTIM_INTERVAL_DEFAULT; + + /* fill the default channel as the first valid channel + * starting from the 2G channels + */ + chanspec = CH20MHZ_CHSPEC(1); + ASSERT(chanspec != INVCHANSPEC); + + wlc->home_chanspec = bi->chanspec = chanspec; + + /* find the band of our default channel */ + band = wlc->band; + if (NBANDS(wlc) > 1 && band->bandunit != CHSPEC_WLCBANDUNIT(chanspec)) + band = wlc->bandstate[OTHERBANDUNIT(wlc)]; + + /* init bss rates to the band specific default rate set */ + wlc_rateset_default(&bi->rateset, NULL, band->phytype, band->bandtype, + false, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub), + CHSPEC_WLC_BW(chanspec), wlc->stf->txstreams); + + if (N_ENAB(wlc->pub)) + bi->flags |= WLC_BSS_HT; +} + +void +wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, u32 b_low) +{ + if (b_low > *a_low) { + /* low half needs a carry */ + b_high += 1; + } + *a_low -= b_low; + *a_high -= b_high; +} + +static ratespec_t +mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, + u32 int_val) +{ + u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT; + u8 rate = int_val & NRATE_RATE_MASK; + ratespec_t rspec; + bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE); + bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT); + bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY) + == NRATE_OVERRIDE_MCS_ONLY); + int bcmerror = 0; + + if (!ismcs) { + return (ratespec_t) rate; + } + + /* validate the combination of rate/mcs/stf is allowed */ + if (N_ENAB(wlc->pub) && ismcs) { + /* mcs only allowed when nmode */ + if (stf > PHY_TXC1_MODE_SDM) { + WL_ERROR("wl%d: %s: Invalid stf\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + + /* mcs 32 is a special case, DUP mode 40 only */ + if (rate == 32) { + if (!CHSPEC_IS40(wlc->home_chanspec) || + ((stf != PHY_TXC1_MODE_SISO) + && (stf != PHY_TXC1_MODE_CDD))) { + WL_ERROR("wl%d: %s: Invalid mcs 32\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + /* mcs > 7 must use stf SDM */ + } else if (rate > HIGHEST_SINGLE_STREAM_MCS) { + /* mcs > 7 must use stf SDM */ + if (stf != PHY_TXC1_MODE_SDM) { + WL_TRACE("wl%d: %s: enabling SDM mode for mcs %d\n", + WLCWLUNIT(wlc), __func__, rate); + stf = PHY_TXC1_MODE_SDM; + } + } else { + /* MCS 0-7 may use SISO, CDD, and for phy_rev >= 3 STBC */ + if ((stf > PHY_TXC1_MODE_STBC) || + (!WLC_STBC_CAP_PHY(wlc) + && (stf == PHY_TXC1_MODE_STBC))) { + WL_ERROR("wl%d: %s: Invalid STBC\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + } + } else if (IS_OFDM(rate)) { + if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) { + WL_ERROR("wl%d: %s: Invalid OFDM\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + } else if (IS_CCK(rate)) { + if ((cur_band->bandtype != WLC_BAND_2G) + || (stf != PHY_TXC1_MODE_SISO)) { + WL_ERROR("wl%d: %s: Invalid CCK\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + } else { + WL_ERROR("wl%d: %s: Unknown rate type\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + /* make sure multiple antennae are available for non-siso rates */ + if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) { + WL_ERROR("wl%d: %s: SISO antenna but !SISO request\n", + WLCWLUNIT(wlc), __func__); + bcmerror = BCME_RANGE; + goto done; + } + + rspec = rate; + if (ismcs) { + rspec |= RSPEC_MIMORATE; + /* For STBC populate the STC field of the ratespec */ + if (stf == PHY_TXC1_MODE_STBC) { + u8 stc; + stc = 1; /* Nss for single stream is always 1 */ + rspec |= (stc << RSPEC_STC_SHIFT); + } + } + + rspec |= (stf << RSPEC_STF_SHIFT); + + if (override_mcs_only) + rspec |= RSPEC_OVERRIDE_MCS_ONLY; + + if (issgi) + rspec |= RSPEC_SHORT_GI; + + if ((rate != 0) + && !wlc_valid_rate(wlc, rspec, cur_band->bandtype, true)) { + return rate; + } + + return rspec; + done: + WL_ERROR("Hoark\n"); + return rate; +} + +/* formula: IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */ +static int +wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, + bool writeToShm) +{ + int idle_busy_ratio_x_16 = 0; + uint offset = + isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM : + M_TX_IDLE_BUSY_RATIO_X_16_CCK; + if (duty_cycle > 100 || duty_cycle < 0) { + WL_ERROR("wl%d: duty cycle value off limit\n", wlc->pub->unit); + return BCME_RANGE; + } + if (duty_cycle) + idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle; + /* Only write to shared memory when wl is up */ + if (writeToShm) + wlc_write_shm(wlc, offset, (u16) idle_busy_ratio_x_16); + + if (isOFDM) + wlc->tx_duty_cycle_ofdm = (u16) duty_cycle; + else + wlc->tx_duty_cycle_cck = (u16) duty_cycle; + + return BCME_OK; +} + +/* Read a single u16 from shared memory. + * SHM 'offset' needs to be an even address + */ +u16 wlc_read_shm(struct wlc_info *wlc, uint offset) +{ + return wlc_bmac_read_shm(wlc->hw, offset); +} + +/* Write a single u16 to shared memory. + * SHM 'offset' needs to be an even address + */ +void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v) +{ + wlc_bmac_write_shm(wlc->hw, offset, v); +} + +/* Set a range of shared memory to a value. + * SHM 'offset' needs to be an even address and + * Range length 'len' must be an even number of bytes + */ +void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len) +{ + /* offset and len need to be even */ + ASSERT((offset & 1) == 0); + ASSERT((len & 1) == 0); + + if (len <= 0) + return; + + wlc_bmac_set_shm(wlc->hw, offset, v, len); +} + +/* Copy a buffer to shared memory. + * SHM 'offset' needs to be an even address and + * Buffer length 'len' must be an even number of bytes + */ +void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, int len) +{ + /* offset and len need to be even */ + ASSERT((offset & 1) == 0); + ASSERT((len & 1) == 0); + + if (len <= 0) + return; + wlc_bmac_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL); + +} + +/* Copy from shared memory to a buffer. + * SHM 'offset' needs to be an even address and + * Buffer length 'len' must be an even number of bytes + */ +void wlc_copyfrom_shm(struct wlc_info *wlc, uint offset, void *buf, int len) +{ + /* offset and len need to be even */ + ASSERT((offset & 1) == 0); + ASSERT((len & 1) == 0); + + if (len <= 0) + return; + + wlc_bmac_copyfrom_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL); +} + +/* wrapper BMAC functions to for HIGH driver access */ +void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val) +{ + wlc_bmac_mctrl(wlc->hw, mask, val); +} + +void wlc_corereset(struct wlc_info *wlc, u32 flags) +{ + wlc_bmac_corereset(wlc->hw, flags); +} + +void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val, int bands) +{ + wlc_bmac_mhf(wlc->hw, idx, mask, val, bands); +} + +u16 wlc_mhf_get(struct wlc_info *wlc, u8 idx, int bands) +{ + return wlc_bmac_mhf_get(wlc->hw, idx, bands); +} + +int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks) +{ + return wlc_bmac_xmtfifo_sz_get(wlc->hw, fifo, blocks); +} + +void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len, + void *buf) +{ + wlc_bmac_write_template_ram(wlc->hw, offset, len, buf); +} + +void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len, + bool both) +{ + wlc_bmac_write_hw_bcntemplates(wlc->hw, bcn, len, both); +} + +void +wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, + const u8 *addr) +{ + wlc_bmac_set_addrmatch(wlc->hw, match_reg_offset, addr); + if (match_reg_offset == RCM_BSSID_OFFSET) + memcpy(wlc->cfg->BSSID, addr, ETH_ALEN); +} + +void wlc_set_rcmta(struct wlc_info *wlc, int idx, const u8 *addr) +{ + wlc_bmac_set_rcmta(wlc->hw, idx, addr); +} + +void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, u32 *tsf_h_ptr) +{ + wlc_bmac_read_tsf(wlc->hw, tsf_l_ptr, tsf_h_ptr); +} + +void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin) +{ + wlc->band->CWmin = newmin; + wlc_bmac_set_cwmin(wlc->hw, newmin); +} + +void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax) +{ + wlc->band->CWmax = newmax; + wlc_bmac_set_cwmax(wlc->hw, newmax); +} + +void wlc_fifoerrors(struct wlc_info *wlc) +{ + + wlc_bmac_fifoerrors(wlc->hw); +} + +/* Search mem rw utilities */ + +void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit) +{ + wlc_bmac_pllreq(wlc->hw, set, req_bit); +} + +void wlc_reset_bmac_done(struct wlc_info *wlc) +{ +} + +void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode) +{ + wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_SM_PS; + wlc->ht_cap.cap_info |= (mimops_mode << IEEE80211_HT_CAP_SM_PS_SHIFT); + + if (AP_ENAB(wlc->pub) && wlc->clk) { + wlc_update_beacon(wlc); + wlc_update_probe_resp(wlc, true); + } +} + +/* check for the particular priority flow control bit being set */ +bool +wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, struct wlc_txq_info *q, + int prio) +{ + uint prio_mask; + + if (prio == ALLPRIO) { + prio_mask = TXQ_STOP_FOR_PRIOFC_MASK; + } else { + ASSERT(prio >= 0 && prio <= MAXPRIO); + prio_mask = NBITVAL(prio); + } + + return (q->stopped & prio_mask) == prio_mask; +} + +/* propogate the flow control to all interfaces using the given tx queue */ +void wlc_txflowcontrol(struct wlc_info *wlc, struct wlc_txq_info *qi, + bool on, int prio) +{ + uint prio_bits; + uint cur_bits; + + WL_TRACE("%s: flow control kicks in\n", __func__); + + if (prio == ALLPRIO) { + prio_bits = TXQ_STOP_FOR_PRIOFC_MASK; + } else { + ASSERT(prio >= 0 && prio <= MAXPRIO); + prio_bits = NBITVAL(prio); + } + + cur_bits = qi->stopped & prio_bits; + + /* Check for the case of no change and return early + * Otherwise update the bit and continue + */ + if (on) { + if (cur_bits == prio_bits) { + return; + } + mboolset(qi->stopped, prio_bits); + } else { + if (cur_bits == 0) { + return; + } + mboolclr(qi->stopped, prio_bits); + } + + /* If there is a flow control override we will not change the external + * flow control state. + */ + if (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK) { + return; + } + + wlc_txflowcontrol_signal(wlc, qi, on, prio); +} + +void +wlc_txflowcontrol_override(struct wlc_info *wlc, struct wlc_txq_info *qi, + bool on, uint override) +{ + uint prev_override; + + ASSERT(override != 0); + ASSERT((override & TXQ_STOP_FOR_PRIOFC_MASK) == 0); + + prev_override = (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK); + + /* Update the flow control bits and do an early return if there is + * no change in the external flow control state. + */ + if (on) { + mboolset(qi->stopped, override); + /* if there was a previous override bit on, then setting this + * makes no difference. + */ + if (prev_override) { + return; + } + + wlc_txflowcontrol_signal(wlc, qi, ON, ALLPRIO); + } else { + mboolclr(qi->stopped, override); + /* clearing an override bit will only make a difference for + * flow control if it was the only bit set. For any other + * override setting, just return + */ + if (prev_override != override) { + return; + } + + if (qi->stopped == 0) { + wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); + } else { + int prio; + + for (prio = MAXPRIO; prio >= 0; prio--) { + if (!mboolisset(qi->stopped, NBITVAL(prio))) + wlc_txflowcontrol_signal(wlc, qi, OFF, + prio); + } + } + } +} + +static void wlc_txflowcontrol_reset(struct wlc_info *wlc) +{ + struct wlc_txq_info *qi; + + for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { + if (qi->stopped) { + wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); + qi->stopped = 0; + } + } +} + +static void +wlc_txflowcontrol_signal(struct wlc_info *wlc, struct wlc_txq_info *qi, bool on, + int prio) +{ + struct wlc_if *wlcif; + + for (wlcif = wlc->wlcif_list; wlcif != NULL; wlcif = wlcif->next) { + if (wlcif->qi == qi && wlcif->flags & WLC_IF_LINKED) + wl_txflowcontrol(wlc->wl, wlcif->wlif, on, prio); + } +} + +static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc, + struct osl_info *osh) +{ + struct wlc_txq_info *qi, *p; + + qi = wlc_calloc(wlc->pub->unit, sizeof(struct wlc_txq_info)); + if (qi != NULL) { + /* + * Have enough room for control packets along with HI watermark + * Also, add room to txq for total psq packets if all the SCBs + * leave PS mode. The watermark for flowcontrol to OS packets + * will remain the same + */ + pktq_init(&qi->q, WLC_PREC_COUNT, + (2 * wlc->pub->tunables->datahiwat) + PKTQ_LEN_DEFAULT + + wlc->pub->psq_pkts_total); + + /* add this queue to the the global list */ + p = wlc->tx_queues; + if (p == NULL) { + wlc->tx_queues = qi; + } else { + while (p->next != NULL) + p = p->next; + p->next = qi; + } + } + return qi; +} + +static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh, + struct wlc_txq_info *qi) +{ + struct wlc_txq_info *p; + + if (qi == NULL) + return; + + /* remove the queue from the linked list */ + p = wlc->tx_queues; + if (p == qi) + wlc->tx_queues = p->next; + else { + while (p != NULL && p->next != qi) + p = p->next; + ASSERT(p->next == qi); + if (p != NULL) + p->next = p->next->next; + } + + kfree(qi); +} + +/* + * Flag 'scan in progress' to withold dynamic phy calibration + */ +void wlc_scan_start(struct wlc_info *wlc) +{ + wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true); +} + +void wlc_scan_stop(struct wlc_info *wlc) +{ + wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false); +} + +void wlc_associate_upd(struct wlc_info *wlc, bool state) +{ + wlc->pub->associated = state; + wlc->cfg->associated = state; +} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.h b/drivers/staging/brcm80211/brcmsmac/wlc_main.h new file mode 100644 index 000000000000..f65be0ed1c1a --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.h @@ -0,0 +1,967 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _wlc_h_ +#define _wlc_h_ + +#define MA_WINDOW_SZ 8 /* moving average window size */ +#define WL_HWRXOFF 38 /* chip rx buffer offset */ +#define INVCHANNEL 255 /* invalid channel */ +#define MAXCOREREV 28 /* max # supported core revisions (0 .. MAXCOREREV - 1) */ +#define WLC_MAXMODULES 22 /* max # wlc_module_register() calls */ + +#define WLC_BITSCNT(x) bcm_bitcount((u8 *)&(x), sizeof(u8)) + +/* Maximum wait time for a MAC suspend */ +#define WLC_MAX_MAC_SUSPEND 83000 /* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */ + +/* Probe Response timeout - responses for probe requests older that this are tossed, zero to disable + */ +#define WLC_PRB_RESP_TIMEOUT 0 /* Disable probe response timeout */ + +/* transmit buffer max headroom for protocol headers */ +#define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN) + +/* For managing scan result lists */ +struct wlc_bss_list { + uint count; + bool beacon; /* set for beacon, cleared for probe response */ + wlc_bss_info_t *ptrs[MAXBSS]; +}; + +#define SW_TIMER_MAC_STAT_UPD 30 /* periodic MAC stats update */ + +/* Double check that unsupported cores are not enabled */ +#if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV) +#error "Configuration for D11CONF includes unsupported versions." +#endif /* Bad versions */ + +#define VALID_COREREV(corerev) CONF_HAS(D11CONF, corerev) + +/* values for shortslot_override */ +#define WLC_SHORTSLOT_AUTO -1 /* Driver will manage Shortslot setting */ +#define WLC_SHORTSLOT_OFF 0 /* Turn off short slot */ +#define WLC_SHORTSLOT_ON 1 /* Turn on short slot */ + +/* value for short/long and mixmode/greenfield preamble */ + +#define WLC_LONG_PREAMBLE (0) +#define WLC_SHORT_PREAMBLE (1 << 0) +#define WLC_GF_PREAMBLE (1 << 1) +#define WLC_MM_PREAMBLE (1 << 2) +#define WLC_IS_MIMO_PREAMBLE(_pre) (((_pre) == WLC_GF_PREAMBLE) || ((_pre) == WLC_MM_PREAMBLE)) + +/* values for barker_preamble */ +#define WLC_BARKER_SHORT_ALLOWED 0 /* Short pre-amble allowed */ + +/* A fifo is full. Clear precedences related to that FIFO */ +#define WLC_TX_FIFO_CLEAR(wlc, fifo) ((wlc)->tx_prec_map &= ~(wlc)->fifo2prec_map[fifo]) + +/* Fifo is NOT full. Enable precedences for that FIFO */ +#define WLC_TX_FIFO_ENAB(wlc, fifo) ((wlc)->tx_prec_map |= (wlc)->fifo2prec_map[fifo]) + +/* TxFrameID */ +/* seq and frag bits: SEQNUM_SHIFT, FRAGNUM_MASK (802.11.h) */ +/* rate epoch bits: TXFID_RATE_SHIFT, TXFID_RATE_MASK ((wlc_rate.c) */ +#define TXFID_QUEUE_MASK 0x0007 /* Bits 0-2 */ +#define TXFID_SEQ_MASK 0x7FE0 /* Bits 5-15 */ +#define TXFID_SEQ_SHIFT 5 /* Number of bit shifts */ +#define TXFID_RATE_PROBE_MASK 0x8000 /* Bit 15 for rate probe */ +#define TXFID_RATE_MASK 0x0018 /* Mask for bits 3 and 4 */ +#define TXFID_RATE_SHIFT 3 /* Shift 3 bits for rate mask */ + +/* promote boardrev */ +#define BOARDREV_PROMOTABLE 0xFF /* from */ +#define BOARDREV_PROMOTED 1 /* to */ + +/* if wpa is in use then portopen is true when the group key is plumbed otherwise it is always true + */ +#define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) +#define WLC_SW_KEYS(wlc, bsscfg) ((((wlc)->wsec_swkeys) || \ + ((bsscfg)->wsec & WSEC_SWFLAG))) + +#define WLC_PORTOPEN(cfg) \ + (((cfg)->WPA_auth != WPA_AUTH_DISABLED && WSEC_ENABLED((cfg)->wsec)) ? \ + (cfg)->wsec_portopen : true) + +#define PS_ALLOWED(wlc) wlc_ps_allowed(wlc) +#define STAY_AWAKE(wlc) wlc_stay_awake(wlc) + +#define DATA_BLOCK_TX_SUPR (1 << 4) + +/* 802.1D Priority to TX FIFO number for wme */ +extern const u8 prio2fifo[]; + +/* Ucode MCTL_WAKE override bits */ +#define WLC_WAKE_OVERRIDE_CLKCTL 0x01 +#define WLC_WAKE_OVERRIDE_PHYREG 0x02 +#define WLC_WAKE_OVERRIDE_MACSUSPEND 0x04 +#define WLC_WAKE_OVERRIDE_TXFIFO 0x08 +#define WLC_WAKE_OVERRIDE_FORCEFAST 0x10 + +/* stuff pulled in from wlc.c */ + +/* Interrupt bit error summary. Don't include I_RU: we refill DMA at other + * times; and if we run out, constant I_RU interrupts may cause lockup. We + * will still get error counts from rx0ovfl. + */ +#define I_ERRORS (I_PC | I_PD | I_DE | I_RO | I_XU) +/* default software intmasks */ +#define DEF_RXINTMASK (I_RI) /* enable rx int on rxfifo only */ +#define DEF_MACINTMASK (MI_TXSTOP | MI_TBTT | MI_ATIMWINEND | MI_PMQ | \ + MI_PHYTXERR | MI_DMAINT | MI_TFS | MI_BG_NOISE | \ + MI_CCA | MI_TO | MI_GP0 | MI_RFDISABLE | MI_PWRUP) + +#define RETRY_SHORT_DEF 7 /* Default Short retry Limit */ +#define RETRY_SHORT_MAX 255 /* Maximum Short retry Limit */ +#define RETRY_LONG_DEF 4 /* Default Long retry count */ +#define RETRY_SHORT_FB 3 /* Short retry count for fallback rate */ +#define RETRY_LONG_FB 2 /* Long retry count for fallback rate */ + +#define MAXTXPKTS 6 /* max # pkts pending */ + +/* frameburst */ +#define MAXTXFRAMEBURST 8 /* vanilla xpress mode: max frames/burst */ +#define MAXFRAMEBURST_TXOP 10000 /* Frameburst TXOP in usec */ + +/* Per-AC retry limit register definitions; uses bcmdefs.h bitfield macros */ +#define EDCF_SHORT_S 0 +#define EDCF_SFB_S 4 +#define EDCF_LONG_S 8 +#define EDCF_LFB_S 12 +#define EDCF_SHORT_M BITFIELD_MASK(4) +#define EDCF_SFB_M BITFIELD_MASK(4) +#define EDCF_LONG_M BITFIELD_MASK(4) +#define EDCF_LFB_M BITFIELD_MASK(4) + +#define WLC_WME_RETRY_SHORT_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_SHORT) +#define WLC_WME_RETRY_SFB_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_SFB) +#define WLC_WME_RETRY_LONG_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_LONG) +#define WLC_WME_RETRY_LFB_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_LFB) + +#define WLC_WME_RETRY_SHORT_SET(wlc, ac, val) \ + (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SHORT, val)) +#define WLC_WME_RETRY_SFB_SET(wlc, ac, val) \ + (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SFB, val)) +#define WLC_WME_RETRY_LONG_SET(wlc, ac, val) \ + (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LONG, val)) +#define WLC_WME_RETRY_LFB_SET(wlc, ac, val) \ + (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LFB, val)) + +/* PLL requests */ +#define WLC_PLLREQ_SHARED 0x1 /* pll is shared on old chips */ +#define WLC_PLLREQ_RADIO_MON 0x2 /* hold pll for radio monitor register checking */ +#define WLC_PLLREQ_FLIP 0x4 /* hold/release pll for some short operation */ + +/* Do we support this rate? */ +#define VALID_RATE_DBG(wlc, rspec) wlc_valid_rate(wlc, rspec, WLC_BAND_AUTO, true) + +/* + * Macros to check if AP or STA is active. + * AP Active means more than just configured: driver and BSS are "up"; + * that is, we are beaconing/responding as an AP (aps_associated). + * STA Active similarly means the driver is up and a configured STA BSS + * is up: either associated (stas_associated) or trying. + * + * Macro definitions vary as per AP/STA ifdefs, allowing references to + * ifdef'd structure fields and constant values (0) for optimization. + * Make sure to enclose blocks of code such that any routines they + * reference can also be unused and optimized out by the linker. + */ +/* NOTE: References structure fields defined in wlc.h */ +#define AP_ACTIVE(wlc) (0) + +/* + * Detect Card removed. + * Even checking an sbconfig register read will not false trigger when the core is in reset. + * it breaks CF address mechanism. Accessing gphy phyversion will cause SB error if aphy + * is in reset on 4306B0-DB. Need a simple accessible reg with fixed 0/1 pattern + * (some platforms return all 0). + * If clocks are present, call the sb routine which will figure out if the device is removed. + */ +#define DEVICEREMOVED(wlc) \ + ((wlc->hw->clk) ? \ + ((R_REG(&wlc->hw->regs->maccontrol) & \ + (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN) : \ + (si_deviceremoved(wlc->hw->sih))) + +#define WLCWLUNIT(wlc) ((wlc)->pub->unit) + +struct wlc_protection { + bool _g; /* use g spec protection, driver internal */ + s8 g_override; /* override for use of g spec protection */ + u8 gmode_user; /* user config gmode, operating band->gmode is different */ + s8 overlap; /* Overlap BSS/IBSS protection for both 11g and 11n */ + s8 nmode_user; /* user config nmode, operating pub->nmode is different */ + s8 n_cfg; /* use OFDM protection on MIMO frames */ + s8 n_cfg_override; /* override for use of N protection */ + bool nongf; /* non-GF present protection */ + s8 nongf_override; /* override for use of GF protection */ + s8 n_pam_override; /* override for preamble: MM or GF */ + bool n_obss; /* indicated OBSS Non-HT STA present */ + + uint longpre_detect_timeout; /* #sec until long preamble bcns gone */ + uint barker_detect_timeout; /* #sec until bcns signaling Barker long preamble */ + /* only is gone */ + uint ofdm_ibss_timeout; /* #sec until ofdm IBSS beacons gone */ + uint ofdm_ovlp_timeout; /* #sec until ofdm overlapping BSS bcns gone */ + uint nonerp_ibss_timeout; /* #sec until nonerp IBSS beacons gone */ + uint nonerp_ovlp_timeout; /* #sec until nonerp overlapping BSS bcns gone */ + uint g_ibss_timeout; /* #sec until bcns signaling Use_Protection gone */ + uint n_ibss_timeout; /* #sec until bcns signaling Use_OFDM_Protection gone */ + uint ht20in40_ovlp_timeout; /* #sec until 20MHz overlapping OPMODE gone */ + uint ht20in40_ibss_timeout; /* #sec until 20MHz-only HT station bcns gone */ + uint non_gf_ibss_timeout; /* #sec until non-GF bcns gone */ +}; + +/* anything affects the single/dual streams/antenna operation */ +struct wlc_stf { + u8 hw_txchain; /* HW txchain bitmap cfg */ + u8 txchain; /* txchain bitmap being used */ + u8 txstreams; /* number of txchains being used */ + + u8 hw_rxchain; /* HW rxchain bitmap cfg */ + u8 rxchain; /* rxchain bitmap being used */ + u8 rxstreams; /* number of rxchains being used */ + + u8 ant_rx_ovr; /* rx antenna override */ + s8 txant; /* userTx antenna setting */ + u16 phytxant; /* phyTx antenna setting in txheader */ + + u8 ss_opmode; /* singlestream Operational mode, 0:siso; 1:cdd */ + bool ss_algosel_auto; /* if true, use wlc->stf->ss_algo_channel; */ + /* else use wlc->band->stf->ss_mode_band; */ + u16 ss_algo_channel; /* ss based on per-channel algo: 0: SISO, 1: CDD 2: STBC */ + u8 no_cddstbc; /* stf override, 1: no CDD (or STBC) allowed */ + + u8 rxchain_restore_delay; /* delay time to restore default rxchain */ + + s8 ldpc; /* AUTO/ON/OFF ldpc cap supported */ + u8 txcore[MAX_STREAMS_SUPPORTED + 1]; /* bitmap of selected core for each Nsts */ + s8 spatial_policy; +}; + +#define WLC_STF_SS_STBC_TX(wlc, scb) \ + (((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) || \ + (SCB_STBC_CAP((scb)) && \ + (wlc)->band->band_stf_stbc_tx == AUTO && \ + isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC)))) + +#define WLC_STBC_CAP_PHY(wlc) (WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3)) + +#define WLC_SGI_CAP_PHY(wlc) ((WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3)) || \ + WLCISLCNPHY(wlc->band)) + +#define WLC_CHAN_PHYTYPE(x) (((x) & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT) +#define WLC_CHAN_CHANNEL(x) (((x) & RXS_CHAN_ID_MASK) >> RXS_CHAN_ID_SHIFT) +#define WLC_RX_CHANNEL(rxh) (WLC_CHAN_CHANNEL((rxh)->RxChan)) + +/* wlc_bss_info flag bit values */ +#define WLC_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */ + +/* Flags used in wlc_txq_info.stopped */ +#define TXQ_STOP_FOR_PRIOFC_MASK 0x000000FF /* per prio flow control bits */ +#define TXQ_STOP_FOR_PKT_DRAIN 0x00000100 /* stop txq enqueue for packet drain */ +#define TXQ_STOP_FOR_AMPDU_FLOW_CNTRL 0x00000200 /* stop txq enqueue for ampdu flow control */ + +#define WLC_HT_WEP_RESTRICT 0x01 /* restrict HT with WEP */ +#define WLC_HT_TKIP_RESTRICT 0x02 /* restrict HT with TKIP */ + +/* + * core state (mac) + */ +struct wlccore { + uint coreidx; /* # sb enumerated core */ + + /* fifo */ + uint *txavail[NFIFO]; /* # tx descriptors available */ + s16 txpktpend[NFIFO]; /* tx admission control */ + + macstat_t *macstat_snapshot; /* mac hw prev read values */ +}; + +/* + * band state (phy+ana+radio) + */ +struct wlcband { + int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */ + uint bandunit; /* bandstate[] index */ + + u16 phytype; /* phytype */ + u16 phyrev; + u16 radioid; + u16 radiorev; + wlc_phy_t *pi; /* pointer to phy specific information */ + bool abgphy_encore; + + u8 gmode; /* currently active gmode (see wlioctl.h) */ + + struct scb *hwrs_scb; /* permanent scb for hw rateset */ + + wlc_rateset_t defrateset; /* band-specific copy of default_bss.rateset */ + + ratespec_t rspec_override; /* 802.11 rate override */ + ratespec_t mrspec_override; /* multicast rate override */ + u8 band_stf_ss_mode; /* Configured STF type, 0:siso; 1:cdd */ + s8 band_stf_stbc_tx; /* STBC TX 0:off; 1:force on; -1:auto */ + wlc_rateset_t hw_rateset; /* rates supported by chip (phy-specific) */ + u8 basic_rate[WLC_MAXRATE + 1]; /* basic rates indexed by rate */ + bool mimo_cap_40; /* 40 MHz cap enabled on this band */ + s8 antgain; /* antenna gain from srom */ + + u16 CWmin; /* The minimum size of contention window, in unit of aSlotTime */ + u16 CWmax; /* The maximum size of contention window, in unit of aSlotTime */ + u16 bcntsfoff; /* beacon tsf offset */ +}; + +/* tx completion callback takes 3 args */ +typedef void (*pkcb_fn_t) (struct wlc_info *wlc, uint txstatus, void *arg); + +struct pkt_cb { + pkcb_fn_t fn; /* function to call when tx frame completes */ + void *arg; /* void arg for fn */ + u8 nextidx; /* index of next call back if threading */ + bool entered; /* recursion check */ +}; + +/* module control blocks */ +struct modulecb { + char name[32]; /* module name : NULL indicates empty array member */ + const bcm_iovar_t *iovars; /* iovar table */ + void *hdl; /* handle passed when handler 'doiovar' is called */ + watchdog_fn_t watchdog_fn; /* watchdog handler */ + iovar_fn_t iovar_fn; /* iovar handler */ + down_fn_t down_fn; /* down handler. Note: the int returned + * by the down function is a count of the + * number of timers that could not be + * freed. + */ +}; + +/* dump control blocks */ +struct dumpcb_s { + const char *name; /* dump name */ + dump_fn_t dump_fn; /* 'wl dump' handler */ + void *dump_fn_arg; + struct dumpcb_s *next; +}; + +/* virtual interface */ +struct wlc_if { + struct wlc_if *next; + u8 type; /* WLC_IFTYPE_BSS or WLC_IFTYPE_WDS */ + u8 index; /* assigned in wl_add_if(), index of the wlif if any, + * not necessarily corresponding to bsscfg._idx or + * AID2PVBMAP(scb). + */ + u8 flags; /* flags for the interface */ + struct wl_if *wlif; /* pointer to wlif */ + struct wlc_txq_info *qi; /* pointer to associated tx queue */ + union { + struct scb *scb; /* pointer to scb if WLC_IFTYPE_WDS */ + struct wlc_bsscfg *bsscfg; /* pointer to bsscfg if WLC_IFTYPE_BSS */ + } u; +}; + +/* flags for the interface */ +#define WLC_IF_LINKED 0x02 /* this interface is linked to a wl_if */ + +struct wlc_hwband { + int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */ + uint bandunit; /* bandstate[] index */ + u16 mhfs[MHFMAX]; /* MHF array shadow */ + u8 bandhw_stf_ss_mode; /* HW configured STF type, 0:siso; 1:cdd */ + u16 CWmin; + u16 CWmax; + u32 core_flags; + + u16 phytype; /* phytype */ + u16 phyrev; + u16 radioid; + u16 radiorev; + wlc_phy_t *pi; /* pointer to phy specific information */ + bool abgphy_encore; +}; + +struct wlc_hw_info { + struct osl_info *osh; /* pointer to os handle */ + bool _piomode; /* true if pio mode */ + struct wlc_info *wlc; + + /* fifo */ + struct hnddma_pub *di[NFIFO]; /* hnddma handles, per fifo */ + + uint unit; /* device instance number */ + + /* version info */ + u16 vendorid; /* PCI vendor id */ + u16 deviceid; /* PCI device id */ + uint corerev; /* core revision */ + u8 sromrev; /* version # of the srom */ + u16 boardrev; /* version # of particular board */ + u32 boardflags; /* Board specific flags from srom */ + u32 boardflags2; /* More board flags if sromrev >= 4 */ + u32 machwcap; /* MAC capabilities */ + u32 machwcap_backup; /* backup of machwcap */ + u16 ucode_dbgsel; /* dbgsel for ucode debug(config gpio) */ + + si_t *sih; /* SB handle (cookie for siutils calls) */ + char *vars; /* "environment" name=value */ + uint vars_size; /* size of vars, free vars on detach */ + d11regs_t *regs; /* pointer to device registers */ + void *physhim; /* phy shim layer handler */ + void *phy_sh; /* pointer to shared phy state */ + struct wlc_hwband *band;/* pointer to active per-band state */ + struct wlc_hwband *bandstate[MAXBANDS];/* band state per phy/radio */ + u16 bmac_phytxant; /* cache of high phytxant state */ + bool shortslot; /* currently using 11g ShortSlot timing */ + u16 SRL; /* 802.11 dot11ShortRetryLimit */ + u16 LRL; /* 802.11 dot11LongRetryLimit */ + u16 SFBL; /* Short Frame Rate Fallback Limit */ + u16 LFBL; /* Long Frame Rate Fallback Limit */ + + bool up; /* d11 hardware up and running */ + uint now; /* # elapsed seconds */ + uint _nbands; /* # bands supported */ + chanspec_t chanspec; /* bmac chanspec shadow */ + + uint *txavail[NFIFO]; /* # tx descriptors available */ + u16 *xmtfifo_sz; /* fifo size in 256B for each xmt fifo */ + + mbool pllreq; /* pll requests to keep PLL on */ + + u8 suspended_fifos; /* Which TX fifo to remain awake for */ + u32 maccontrol; /* Cached value of maccontrol */ + uint mac_suspend_depth; /* current depth of mac_suspend levels */ + u32 wake_override; /* Various conditions to force MAC to WAKE mode */ + u32 mute_override; /* Prevent ucode from sending beacons */ + u8 etheraddr[ETH_ALEN]; /* currently configured ethernet address */ + u32 led_gpio_mask; /* LED GPIO Mask */ + bool noreset; /* true= do not reset hw, used by WLC_OUT */ + bool forcefastclk; /* true if the h/w is forcing the use of fast clk */ + bool clk; /* core is out of reset and has clock */ + bool sbclk; /* sb has clock */ + struct bmac_pmq *bmac_pmq; /* bmac PM states derived from ucode PMQ */ + bool phyclk; /* phy is out of reset and has clock */ + bool dma_lpbk; /* core is in DMA loopback */ + + bool ucode_loaded; /* true after ucode downloaded */ + + + u8 hw_stf_ss_opmode; /* STF single stream operation mode */ + u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic + * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board + */ + u32 antsel_avail; /* + * put struct antsel_info here if more info is + * needed + */ +}; + +/* TX Queue information + * + * Each flow of traffic out of the device has a TX Queue with independent + * flow control. Several interfaces may be associated with a single TX Queue + * if they belong to the same flow of traffic from the device. For multi-channel + * operation there are independent TX Queues for each channel. + */ +struct wlc_txq_info { + struct wlc_txq_info *next; + struct pktq q; + uint stopped; /* tx flow control bits */ +}; + +/* + * Principal common (os-independent) software data structure. + */ +struct wlc_info { + struct wlc_pub *pub; /* pointer to wlc public state */ + struct osl_info *osh; /* pointer to os handle */ + struct wl_info *wl; /* pointer to os-specific private state */ + d11regs_t *regs; /* pointer to device registers */ + + struct wlc_hw_info *hw; /* HW related state used primarily by BMAC */ + + /* clock */ + int clkreq_override; /* setting for clkreq for PCIE : Auto, 0, 1 */ + u16 fastpwrup_dly; /* time in us needed to bring up d11 fast clock */ + + /* interrupt */ + u32 macintstatus; /* bit channel between isr and dpc */ + u32 macintmask; /* sw runtime master macintmask value */ + u32 defmacintmask; /* default "on" macintmask value */ + + /* up and down */ + bool device_present; /* (removable) device is present */ + + bool clk; /* core is out of reset and has clock */ + + /* multiband */ + struct wlccore *core; /* pointer to active io core */ + struct wlcband *band; /* pointer to active per-band state */ + struct wlccore *corestate; /* per-core state (one per hw core) */ + /* per-band state (one per phy/radio): */ + struct wlcband *bandstate[MAXBANDS]; + + bool war16165; /* PCI slow clock 16165 war flag */ + + bool tx_suspended; /* data fifos need to remain suspended */ + + uint txpend16165war; + + /* packet queue */ + uint qvalid; /* DirFrmQValid and BcMcFrmQValid */ + + /* Regulatory power limits */ + s8 txpwr_local_max; /* regulatory local txpwr max */ + u8 txpwr_local_constraint; /* local power contraint in dB */ + + + struct ampdu_info *ampdu; /* ampdu module handler */ + struct antsel_info *asi; /* antsel module handler */ + wlc_cm_info_t *cmi; /* channel manager module handler */ + + void *btparam; /* bus type specific cookie */ + + uint vars_size; /* size of vars, free vars on detach */ + + u16 vendorid; /* PCI vendor id */ + u16 deviceid; /* PCI device id */ + uint ucode_rev; /* microcode revision */ + + u32 machwcap; /* MAC capabilities, BMAC shadow */ + + u8 perm_etheraddr[ETH_ALEN]; /* original sprom local ethernet address */ + + bool bandlocked; /* disable auto multi-band switching */ + bool bandinit_pending; /* track band init in auto band */ + + bool radio_monitor; /* radio timer is running */ + bool down_override; /* true=down */ + bool going_down; /* down path intermediate variable */ + + bool mpc; /* enable minimum power consumption */ + u8 mpc_dlycnt; /* # of watchdog cnt before turn disable radio */ + u8 mpc_offcnt; /* # of watchdog cnt that radio is disabled */ + u8 mpc_delay_off; /* delay radio disable by # of watchdog cnt */ + u8 prev_non_delay_mpc; /* prev state wlc_is_non_delay_mpc */ + + /* timer */ + struct wl_timer *wdtimer; /* timer for watchdog routine */ + uint fast_timer; /* Periodic timeout for 'fast' timer */ + uint slow_timer; /* Periodic timeout for 'slow' timer */ + uint glacial_timer; /* Periodic timeout for 'glacial' timer */ + uint phycal_mlo; /* last time measurelow calibration was done */ + uint phycal_txpower; /* last time txpower calibration was done */ + + struct wl_timer *radio_timer; /* timer for hw radio button monitor routine */ + struct wl_timer *pspoll_timer; /* periodic pspoll timer */ + + /* promiscuous */ + bool monitor; /* monitor (MPDU sniffing) mode */ + bool bcnmisc_ibss; /* bcns promisc mode override for IBSS */ + bool bcnmisc_scan; /* bcns promisc mode override for scan */ + bool bcnmisc_monitor; /* bcns promisc mode override for monitor */ + + u8 bcn_wait_prd; /* max waiting period (for beacon) in 1024TU */ + + /* driver feature */ + bool _rifs; /* enable per-packet rifs */ + s32 rifs_advert; /* RIFS mode advertisement */ + s8 sgi_tx; /* sgi tx */ + bool wet; /* true if wireless ethernet bridging mode */ + + /* AP-STA synchronization, power save */ + bool check_for_unaligned_tbtt; /* check unaligned tbtt flag */ + bool PM_override; /* no power-save flag, override PM(user input) */ + bool PMenabled; /* current power-management state (CAM or PS) */ + bool PMpending; /* waiting for tx status with PM indicated set */ + bool PMblocked; /* block any PSPolling in PS mode, used to buffer + * AP traffic, also used to indicate in progress + * of scan, rm, etc. off home channel activity. + */ + bool PSpoll; /* whether there is an outstanding PS-Poll frame */ + u8 PM; /* power-management mode (CAM, PS or FASTPS) */ + bool PMawakebcn; /* bcn recvd during current waking state */ + + bool WME_PM_blocked; /* Can STA go to PM when in WME Auto mode */ + bool wake; /* host-specified PS-mode sleep state */ + u8 pspoll_prd; /* pspoll interval in milliseconds */ + u8 bcn_li_bcn; /* beacon listen interval in # beacons */ + u8 bcn_li_dtim; /* beacon listen interval in # dtims */ + + bool WDarmed; /* watchdog timer is armed */ + u32 WDlast; /* last time wlc_watchdog() was called */ + + /* WME */ + ac_bitmap_t wme_dp; /* Discard (oldest first) policy per AC */ + bool wme_apsd; /* enable Advanced Power Save Delivery */ + ac_bitmap_t wme_admctl; /* bit i set if AC i under admission control */ + u16 edcf_txop[AC_COUNT]; /* current txop for each ac */ + wme_param_ie_t wme_param_ie; /* WME parameter info element, which on STA + * contains parameters in use locally, and on + * AP contains parameters advertised to STA + * in beacons and assoc responses. + */ + bool wme_prec_queuing; /* enable/disable non-wme STA prec queuing */ + u16 wme_retries[AC_COUNT]; /* per-AC retry limits */ + + int vlan_mode; /* OK to use 802.1Q Tags (ON, OFF, AUTO) */ + u16 tx_prec_map; /* Precedence map based on HW FIFO space */ + u16 fifo2prec_map[NFIFO]; /* pointer to fifo2_prec map based on WME */ + + /* BSS Configurations */ + wlc_bsscfg_t *bsscfg[WLC_MAXBSSCFG]; /* set of BSS configurations, idx 0 is default and + * always valid + */ + wlc_bsscfg_t *cfg; /* the primary bsscfg (can be AP or STA) */ + u8 stas_associated; /* count of ASSOCIATED STA bsscfgs */ + u8 aps_associated; /* count of UP AP bsscfgs */ + u8 block_datafifo; /* prohibit posting frames to data fifos */ + bool bcmcfifo_drain; /* TX_BCMC_FIFO is set to drain */ + + /* tx queue */ + struct wlc_txq_info *tx_queues; /* common TX Queue list */ + + /* security */ + wsec_key_t *wsec_keys[WSEC_MAX_KEYS]; /* dynamic key storage */ + wsec_key_t *wsec_def_keys[WLC_DEFAULT_KEYS]; /* default key storage */ + bool wsec_swkeys; /* indicates that all keys should be + * treated as sw keys (used for debugging) + */ + struct modulecb *modulecb; + struct dumpcb_s *dumpcb_head; + + u8 mimoft; /* SIGN or 11N */ + u8 mimo_band_bwcap; /* bw cap per band type */ + s8 txburst_limit_override; /* tx burst limit override */ + u16 txburst_limit; /* tx burst limit value */ + s8 cck_40txbw; /* 11N, cck tx b/w override when in 40MHZ mode */ + s8 ofdm_40txbw; /* 11N, ofdm tx b/w override when in 40MHZ mode */ + s8 mimo_40txbw; /* 11N, mimo tx b/w override when in 40MHZ mode */ + /* HT CAP IE being advertised by this node: */ + struct ieee80211_ht_cap ht_cap; + + uint seckeys; /* 54 key table shm address */ + uint tkmickeys; /* 12 TKIP MIC key table shm address */ + + wlc_bss_info_t *default_bss; /* configured BSS parameters */ + + u16 AID; /* association ID */ + u16 counter; /* per-sdu monotonically increasing counter */ + u16 mc_fid_counter; /* BC/MC FIFO frame ID counter */ + + bool ibss_allowed; /* false, all IBSS will be ignored during a scan + * and the driver will not allow the creation of + * an IBSS network + */ + bool ibss_coalesce_allowed; + + char country_default[WLC_CNTRY_BUF_SZ]; /* saved country for leaving 802.11d + * auto-country mode + */ + char autocountry_default[WLC_CNTRY_BUF_SZ]; /* initial country for 802.11d + * auto-country mode + */ +#ifdef BCMDBG + bcm_tlv_t *country_ie_override; /* debug override of announced Country IE */ +#endif + + u16 prb_resp_timeout; /* do not send prb resp if request older than this, + * 0 = disable + */ + + wlc_rateset_t sup_rates_override; /* use only these rates in 11g supported rates if + * specifed + */ + + chanspec_t home_chanspec; /* shared home chanspec */ + + /* PHY parameters */ + chanspec_t chanspec; /* target operational channel */ + u16 usr_fragthresh; /* user configured fragmentation threshold */ + u16 fragthresh[NFIFO]; /* per-fifo fragmentation thresholds */ + u16 RTSThresh; /* 802.11 dot11RTSThreshold */ + u16 SRL; /* 802.11 dot11ShortRetryLimit */ + u16 LRL; /* 802.11 dot11LongRetryLimit */ + u16 SFBL; /* Short Frame Rate Fallback Limit */ + u16 LFBL; /* Long Frame Rate Fallback Limit */ + + /* network config */ + bool shortpreamble; /* currently operating with CCK ShortPreambles */ + bool shortslot; /* currently using 11g ShortSlot timing */ + s8 barker_preamble; /* current Barker Preamble Mode */ + s8 shortslot_override; /* 11g ShortSlot override */ + bool include_legacy_erp; /* include Legacy ERP info elt ID 47 as well as g ID 42 */ + bool barker_overlap_control; /* true: be aware of overlapping BSSs for barker */ + bool ignore_bcns; /* override: ignore non shortslot bcns in a 11g network */ + bool legacy_probe; /* restricts probe requests to CCK rates */ + + struct wlc_protection *protection; + s8 PLCPHdr_override; /* 802.11b Preamble Type override */ + + struct wlc_stf *stf; + + struct pkt_cb *pkt_callback; /* tx completion callback handlers */ + + u32 txretried; /* tx retried number in one msdu */ + + ratespec_t bcn_rspec; /* save bcn ratespec purpose */ + + bool apsd_sta_usp; /* Unscheduled Service Period in progress on STA */ + struct wl_timer *apsd_trigger_timer; /* timer for wme apsd trigger frames */ + u32 apsd_trigger_timeout; /* timeout value for apsd_trigger_timer (in ms) + * 0 == disable + */ + ac_bitmap_t apsd_trigger_ac; /* Permissible Access Category in which APSD Null + * Trigger frames can be send + */ + u8 htphy_membership; /* HT PHY membership */ + + bool _regulatory_domain; /* 802.11d enabled? */ + + u8 mimops_PM; + + u8 txpwr_percent; /* power output percentage */ + + u8 ht_wsec_restriction; /* the restriction of HT with TKIP or WEP */ + + uint tempsense_lasttime; + + u16 tx_duty_cycle_ofdm; /* maximum allowed duty cycle for OFDM */ + u16 tx_duty_cycle_cck; /* maximum allowed duty cycle for CCK */ + + u16 next_bsscfg_ID; + + struct wlc_if *wlcif_list; /* linked list of wlc_if structs */ + struct wlc_txq_info *active_queue; /* txq for the currently active + * transmit context + */ + u32 mpc_dur; /* total time (ms) in mpc mode except for the + * portion since radio is turned off last time + */ + u32 mpc_laston_ts; /* timestamp (ms) when radio is turned off last + * time + */ + bool pr80838_war; + uint hwrxoff; +}; + +/* antsel module specific state */ +struct antsel_info { + struct wlc_info *wlc; /* pointer to main wlc structure */ + struct wlc_pub *pub; /* pointer to public fn */ + u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic + * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board + */ + u8 antsel_antswitch; /* board level antenna switch type */ + bool antsel_avail; /* Ant selection availability (SROM based) */ + wlc_antselcfg_t antcfg_11n; /* antenna configuration */ + wlc_antselcfg_t antcfg_cur; /* current antenna config (auto) */ +}; + +#define CHANNEL_BANDUNIT(wlc, ch) (((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX) +#define OTHERBANDUNIT(wlc) ((uint)((wlc)->band->bandunit ? BAND_2G_INDEX : BAND_5G_INDEX)) + +#define IS_MBAND_UNLOCKED(wlc) \ + ((NBANDS(wlc) > 1) && !(wlc)->bandlocked) + +#define WLC_BAND_PI_RADIO_CHANSPEC wlc_phy_chanspec_get(wlc->band->pi) + +/* sum the individual fifo tx pending packet counts */ +#define TXPKTPENDTOT(wlc) ((wlc)->core->txpktpend[0] + (wlc)->core->txpktpend[1] + \ + (wlc)->core->txpktpend[2] + (wlc)->core->txpktpend[3]) +#define TXPKTPENDGET(wlc, fifo) ((wlc)->core->txpktpend[(fifo)]) +#define TXPKTPENDINC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] += (val)) +#define TXPKTPENDDEC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] -= (val)) +#define TXPKTPENDCLR(wlc, fifo) ((wlc)->core->txpktpend[(fifo)] = 0) +#define TXAVAIL(wlc, fifo) (*(wlc)->core->txavail[(fifo)]) +#define GETNEXTTXP(wlc, _queue) \ + dma_getnexttxp((wlc)->hw->di[(_queue)], HNDDMA_RANGE_TRANSMITTED) + +#define WLC_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \ + ((len1 == len2) && !memcmp(ssid1, ssid2, len1)) + +extern void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus); +extern void wlc_fatal_error(struct wlc_info *wlc); +extern void wlc_bmac_rpc_watchdog(struct wlc_info *wlc); +extern void wlc_recv(struct wlc_info *wlc, struct sk_buff *p); +extern bool wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2); +extern void wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, + bool commit, s8 txpktpend); +extern void wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend); +extern void wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, + uint prec); +extern void wlc_info_init(struct wlc_info *wlc, int unit); +extern void wlc_print_txstatus(tx_status_t *txs); +extern int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks); +extern void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len, + void *buf); +extern void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len, + bool both); +#if defined(BCMDBG) +extern void wlc_get_rcmta(struct wlc_info *wlc, int idx, + u8 *addr); +#endif +extern void wlc_set_rcmta(struct wlc_info *wlc, int idx, + const u8 *addr); +extern void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, + u32 *tsf_h_ptr); +extern void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin); +extern void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax); +extern void wlc_fifoerrors(struct wlc_info *wlc); +extern void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit); +extern void wlc_reset_bmac_done(struct wlc_info *wlc); +extern void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us); +extern void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc); + +#if defined(BCMDBG) +extern void wlc_print_rxh(d11rxhdr_t *rxh); +extern void wlc_print_hdrs(struct wlc_info *wlc, const char *prefix, u8 *frame, + d11txh_t *txh, d11rxhdr_t *rxh, uint len); +extern void wlc_print_txdesc(d11txh_t *txh); +#else +#define wlc_print_txdesc(a) +#endif +#if defined(BCMDBG) +extern void wlc_print_dot11_mac_hdr(u8 *buf, int len); +#endif + +extern void wlc_setxband(struct wlc_hw_info *wlc_hw, uint bandunit); +extern void wlc_coredisable(struct wlc_hw_info *wlc_hw); + +extern bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rate, int band, + bool verbose); +extern void wlc_ap_upd(struct wlc_info *wlc); + +/* helper functions */ +extern void wlc_shm_ssid_upd(struct wlc_info *wlc, wlc_bsscfg_t *cfg); +extern int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config); + +extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc); +extern void wlc_mac_bcn_promisc(struct wlc_info *wlc); +extern void wlc_mac_promisc(struct wlc_info *wlc); +extern void wlc_txflowcontrol(struct wlc_info *wlc, struct wlc_txq_info *qi, + bool on, int prio); +extern void wlc_txflowcontrol_override(struct wlc_info *wlc, + struct wlc_txq_info *qi, + bool on, uint override); +extern bool wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, + struct wlc_txq_info *qi, int prio); +extern void wlc_send_q(struct wlc_info *wlc, struct wlc_txq_info *qi); +extern int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifo); + +extern u16 wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, + uint mac_len); +extern ratespec_t wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, + bool use_rspec, u16 mimo_ctlchbw); +extern u16 wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, + ratespec_t rts_rate, ratespec_t frame_rate, + u8 rts_preamble_type, + u8 frame_preamble_type, uint frame_len, + bool ba); + +extern void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs); + +#if defined(BCMDBG) +extern void wlc_dump_ie(struct wlc_info *wlc, bcm_tlv_t *ie, + struct bcmstrbuf *b); +#endif + +extern bool wlc_ps_check(struct wlc_info *wlc); +extern void wlc_reprate_init(struct wlc_info *wlc); +extern void wlc_bsscfg_reprate_init(wlc_bsscfg_t *bsscfg); +extern void wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, + u32 b_low); +extern u32 wlc_calc_tbtt_offset(u32 bi, u32 tsf_h, u32 tsf_l); + +/* Shared memory access */ +extern void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v); +extern u16 wlc_read_shm(struct wlc_info *wlc, uint offset); +extern void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len); +extern void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, + int len); +extern void wlc_copyfrom_shm(struct wlc_info *wlc, uint offset, void *buf, + int len); + +extern void wlc_update_beacon(struct wlc_info *wlc); +extern void wlc_bss_update_beacon(struct wlc_info *wlc, + struct wlc_bsscfg *bsscfg); + +extern void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend); +extern void wlc_bss_update_probe_resp(struct wlc_info *wlc, wlc_bsscfg_t *cfg, + bool suspend); + +extern bool wlc_ismpc(struct wlc_info *wlc); +extern bool wlc_is_non_delay_mpc(struct wlc_info *wlc); +extern void wlc_radio_mpc_upd(struct wlc_info *wlc); +extern bool wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, + int prec); +extern bool wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, + struct sk_buff *pkt, int prec, bool head); +extern u16 wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec); +extern void wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rate, uint length, + u8 *plcp); +extern uint wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, + u8 preamble_type, uint mac_len); + +extern void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec); + +extern bool wlc_timers_init(struct wlc_info *wlc, int unit); + +extern const bcm_iovar_t wlc_iovars[]; + +extern int wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, + const char *name, void *params, uint p_len, void *arg, + int len, int val_size, struct wlc_if *wlcif); + +#if defined(BCMDBG) +extern void wlc_print_ies(struct wlc_info *wlc, u8 *ies, uint ies_len); +#endif + +extern int wlc_set_nmode(struct wlc_info *wlc, s32 nmode); +extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode); +extern void wlc_mimops_action_ht_send(struct wlc_info *wlc, + wlc_bsscfg_t *bsscfg, u8 mimops_mode); + +extern void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot); +extern void wlc_set_bssid(wlc_bsscfg_t *cfg); +extern void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend); + +extern void wlc_set_ratetable(struct wlc_info *wlc); +extern int wlc_set_mac(wlc_bsscfg_t *cfg); +extern void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, + ratespec_t bcn_rate); +extern void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len); +extern ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, + wlc_rateset_t *rs); +extern u16 wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec, + bool short_preamble, bool phydelay); +extern void wlc_radio_disable(struct wlc_info *wlc); +extern void wlc_bcn_li_upd(struct wlc_info *wlc); + +extern int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len); +extern void wlc_out(struct wlc_info *wlc); +extern void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec); +extern void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt); +extern bool wlc_ps_allowed(struct wlc_info *wlc); +extern bool wlc_stay_awake(struct wlc_info *wlc); +extern void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe); + +extern void wlc_bss_list_free(struct wlc_info *wlc, + struct wlc_bss_list *bss_list); +extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode); +#endif /* _wlc_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c index 95aafddcc95d..e867bf72cb41 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c @@ -54,7 +54,7 @@ #include "wlc_phy_hal.h" #include "wl_export.h" #include "wlc_bsscfg.h" -#include "wlc_mac80211.h" +#include "wlc_main.h" #include "wlc_phy_shim.h" /* PHY SHIM module specific state */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c index 9e27be9d49f9..75aeb280eb99 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c @@ -38,7 +38,7 @@ #include "phy/wlc_phy_hal.h" #include "wlc_channel.h" #include "wlc_bsscfg.h" -#include "wlc_mac80211.h" +#include "wlc_main.h" #include "wl_export.h" #include "wlc_bmac.h" #include "wlc_stf.h" -- cgit v1.2.3 From e343d3ea73e97b339ecb1d39f1cdd306da24a175 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 2 Mar 2011 17:01:37 +0100 Subject: staging: brcm80211: replace simple_strtoul with strict_strtoul By checkpatch recommendation using strict_strtoul now. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 28 ++++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 6059e4cc3aa1..6ce5172557f6 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -1293,18 +1293,22 @@ static int __init wl_module_init(void) wl_msg_level = msglevel; else { char *var = getvar(NULL, "wl_msglevel"); - if (var) - wl_msg_level = simple_strtoul(var, NULL, 0); - } - { - extern u32 phyhal_msg_level; - - if (phymsglevel != 0xdeadbeef) - phyhal_msg_level = phymsglevel; - else { - char *var = getvar(NULL, "phy_msglevel"); - if (var) - phyhal_msg_level = simple_strtoul(var, NULL, 0); + if (var) { + unsigned long value; + + (void)strict_strtoul(var, 0, &value); + wl_msg_level = value; + } + } + if (phymsglevel != 0xdeadbeef) + phyhal_msg_level = phymsglevel; + else { + char *var = getvar(NULL, "phy_msglevel"); + if (var) { + unsigned long value; + + (void)strict_strtoul(var, 0, &value); + phyhal_msg_level = value; } } #endif /* BCMDBG */ -- cgit v1.2.3 From b23dd4fe42b455af5c6e20966b7d6959fa8352ea Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 2 Mar 2011 14:31:35 -0800 Subject: ipv4: Make output route lookup return rtable directly. Instead of on the stack. Signed-off-by: David S. Miller --- drivers/infiniband/core/addr.c | 7 ++- drivers/infiniband/hw/cxgb3/iwch_cm.c | 3 +- drivers/infiniband/hw/cxgb4/cm.c | 3 +- drivers/infiniband/hw/nes/nes_cm.c | 3 +- drivers/net/bonding/bond_main.c | 6 +- drivers/net/cnic.c | 7 ++- drivers/net/pptp.c | 8 +-- drivers/scsi/cxgbi/libcxgbi.c | 3 +- include/net/route.h | 58 ++++++++++---------- net/atm/clip.c | 6 +- net/bridge/br_netfilter.c | 9 +-- net/dccp/ipv4.c | 27 ++++----- net/ipv4/af_inet.c | 30 +++++----- net/ipv4/arp.c | 19 +++---- net/ipv4/datagram.c | 11 ++-- net/ipv4/icmp.c | 19 ++++--- net/ipv4/igmp.c | 16 ++++-- net/ipv4/inet_connection_sock.c | 3 +- net/ipv4/ip_gre.c | 11 ++-- net/ipv4/ip_output.c | 6 +- net/ipv4/ipip.c | 7 ++- net/ipv4/ipmr.c | 8 +-- net/ipv4/netfilter.c | 12 +++- net/ipv4/raw.c | 8 ++- net/ipv4/route.c | 100 +++++++++++++++++----------------- net/ipv4/syncookies.c | 3 +- net/ipv4/tcp_ipv4.c | 28 +++++----- net/ipv4/udp.c | 5 +- net/ipv4/xfrm4_policy.c | 12 ++-- net/ipv6/ip6_tunnel.c | 11 ++-- net/ipv6/sit.c | 8 ++- net/l2tp/l2tp_ip.c | 8 ++- net/netfilter/ipvs/ip_vs_xmit.c | 9 ++- net/netfilter/xt_TEE.c | 3 +- net/rxrpc/ar-peer.c | 7 +-- net/sctp/protocol.c | 7 ++- 36 files changed, 267 insertions(+), 224 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 8aba0ba57de5..2d749937a969 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -193,10 +193,11 @@ static int addr4_resolve(struct sockaddr_in *src_in, fl.nl_u.ip4_u.saddr = src_ip; fl.oif = addr->bound_dev_if; - ret = ip_route_output_key(&init_net, &rt, &fl); - if (ret) + rt = ip_route_output_key(&init_net, &fl); + if (IS_ERR(rt)) { + ret = PTR_ERR(rt); goto out; - + } src_in->sin_family = AF_INET; src_in->sin_addr.s_addr = rt->rt_src; diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index e654285aa6ba..e0ccbc53fbcc 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c @@ -354,7 +354,8 @@ static struct rtable *find_route(struct t3cdev *dev, __be32 local_ip, } }; - if (ip_route_output_flow(&init_net, &rt, &fl, NULL)) + rt = ip_route_output_flow(&init_net, &fl, NULL); + if (IS_ERR(rt)) return NULL; return rt; } diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 7e0484f18db5..77b0eef2aad9 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -331,7 +331,8 @@ static struct rtable *find_route(struct c4iw_dev *dev, __be32 local_ip, } }; - if (ip_route_output_flow(&init_net, &rt, &fl, NULL)) + rt = ip_route_output_flow(&init_net, &fl, NULL); + if (IS_ERR(rt)) return NULL; return rt; } diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index ec3aa11c36cb..e81599cb1fe6 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -1112,7 +1112,8 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi memset(&fl, 0, sizeof fl); fl.nl_u.ip4_u.daddr = htonl(dst_ip); - if (ip_route_output_key(&init_net, &rt, &fl)) { + rt = ip_route_output_key(&init_net, &fl); + if (IS_ERR(rt)) { printk(KERN_ERR "%s: ip_route_output_key failed for 0x%08X\n", __func__, dst_ip); return rc; diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 584f97b73060..0592e6da15a6 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2681,7 +2681,7 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op, __be32 dest_ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) { - int i, vlan_id, rv; + int i, vlan_id; __be32 *targets = bond->params.arp_targets; struct vlan_entry *vlan; struct net_device *vlan_dev; @@ -2708,8 +2708,8 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) fl.fl4_dst = targets[i]; fl.fl4_tos = RTO_ONLINK; - rv = ip_route_output_key(dev_net(bond->dev), &rt, &fl); - if (rv) { + rt = ip_route_output_key(dev_net(bond->dev), &fl); + if (IS_ERR(rt)) { if (net_ratelimit()) { pr_warning("%s: no route to arp_ip_target %pI4\n", bond->dev->name, &fl.fl4_dst); diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 5274de3e1bb9..25f08880ae0f 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -3397,9 +3397,12 @@ static int cnic_get_v4_route(struct sockaddr_in *dst_addr, memset(&fl, 0, sizeof(fl)); fl.nl_u.ip4_u.daddr = dst_addr->sin_addr.s_addr; - err = ip_route_output_key(&init_net, &rt, &fl); - if (!err) + rt = ip_route_output_key(&init_net, &fl); + err = 0; + if (!IS_ERR(rt)) *dst = &rt->dst; + else + err = PTR_ERR(rt); return err; #else return -ENETUNREACH; diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c index 164cfad6ce79..1af549c89d51 100644 --- a/drivers/net/pptp.c +++ b/drivers/net/pptp.c @@ -175,7 +175,6 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) struct pptp_opt *opt = &po->proto.pptp; struct pptp_gre_header *hdr; unsigned int header_len = sizeof(*hdr); - int err = 0; int islcp; int len; unsigned char *data; @@ -198,8 +197,8 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) .saddr = opt->src_addr.sin_addr.s_addr, .tos = RT_TOS(0) } }, .proto = IPPROTO_GRE }; - err = ip_route_output_key(&init_net, &rt, &fl); - if (err) + rt = ip_route_output_key(&init_net, &fl); + if (IS_ERR(rt)) goto tx_error; } tdev = rt->dst.dev; @@ -477,7 +476,8 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr, .tos = RT_CONN_FLAGS(sk) } }, .proto = IPPROTO_GRE }; security_sk_classify_flow(sk, &fl); - if (ip_route_output_key(&init_net, &rt, &fl)) { + rt = ip_route_output_key(&init_net, &fl); + if (IS_ERR(rt)) { error = -EHOSTUNREACH; goto end; } diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index 261aa817bdd5..889199aa1f5b 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c @@ -470,7 +470,8 @@ static struct rtable *find_route_ipv4(__be32 saddr, __be32 daddr, } }; - if (ip_route_output_flow(&init_net, &rt, &fl, NULL)) + rt = ip_route_output_flow(&init_net, &fl, NULL); + if (IS_ERR(rt)) return NULL; return rt; diff --git a/include/net/route.h b/include/net/route.h index 707cfc8eccdc..088a1867348f 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -118,9 +118,10 @@ extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw, __be32 src, struct net_device *dev); extern void rt_cache_flush(struct net *net, int how); extern void rt_cache_flush_batch(struct net *net); -extern int __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp); -extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp); -extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk); +extern struct rtable *__ip_route_output_key(struct net *, const struct flowi *flp); +extern struct rtable *ip_route_output_key(struct net *, struct flowi *flp); +extern struct rtable *ip_route_output_flow(struct net *, struct flowi *flp, + struct sock *sk); extern struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig); extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, @@ -166,10 +167,10 @@ static inline char rt_tos2priority(u8 tos) return ip_tos2prio[IPTOS_TOS(tos)>>1]; } -static inline int ip_route_connect(struct rtable **rp, __be32 dst, - __be32 src, u32 tos, int oif, u8 protocol, - __be16 sport, __be16 dport, struct sock *sk, - bool can_sleep) +static inline struct rtable *ip_route_connect(__be32 dst, __be32 src, u32 tos, + int oif, u8 protocol, + __be16 sport, __be16 dport, + struct sock *sk, bool can_sleep) { struct flowi fl = { .oif = oif, .mark = sk->sk_mark, @@ -179,8 +180,8 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst, .proto = protocol, .fl_ip_sport = sport, .fl_ip_dport = dport }; - int err; struct net *net = sock_net(sk); + struct rtable *rt; if (inet_sk(sk)->transparent) fl.flags |= FLOWI_FLAG_ANYSRC; @@ -190,29 +191,29 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst, fl.flags |= FLOWI_FLAG_CAN_SLEEP; if (!dst || !src) { - err = __ip_route_output_key(net, rp, &fl); - if (err) - return err; - fl.fl4_dst = (*rp)->rt_dst; - fl.fl4_src = (*rp)->rt_src; - ip_rt_put(*rp); - *rp = NULL; + rt = __ip_route_output_key(net, &fl); + if (IS_ERR(rt)) + return rt; + fl.fl4_dst = rt->rt_dst; + fl.fl4_src = rt->rt_src; + ip_rt_put(rt); } security_sk_classify_flow(sk, &fl); - return ip_route_output_flow(net, rp, &fl, sk); + return ip_route_output_flow(net, &fl, sk); } -static inline int ip_route_newports(struct rtable **rp, u8 protocol, - __be16 orig_sport, __be16 orig_dport, - __be16 sport, __be16 dport, struct sock *sk) +static inline struct rtable *ip_route_newports(struct rtable *rt, + u8 protocol, __be16 orig_sport, + __be16 orig_dport, __be16 sport, + __be16 dport, struct sock *sk) { if (sport != orig_sport || dport != orig_dport) { - struct flowi fl = { .oif = (*rp)->fl.oif, - .mark = (*rp)->fl.mark, - .fl4_dst = (*rp)->fl.fl4_dst, - .fl4_src = (*rp)->fl.fl4_src, - .fl4_tos = (*rp)->fl.fl4_tos, - .proto = (*rp)->fl.proto, + struct flowi fl = { .oif = rt->fl.oif, + .mark = rt->fl.mark, + .fl4_dst = rt->fl.fl4_dst, + .fl4_src = rt->fl.fl4_src, + .fl4_tos = rt->fl.fl4_tos, + .proto = rt->fl.proto, .fl_ip_sport = sport, .fl_ip_dport = dport }; @@ -220,12 +221,11 @@ static inline int ip_route_newports(struct rtable **rp, u8 protocol, fl.flags |= FLOWI_FLAG_ANYSRC; if (protocol == IPPROTO_TCP) fl.flags |= FLOWI_FLAG_PRECOW_METRICS; - ip_rt_put(*rp); - *rp = NULL; + ip_rt_put(rt); security_sk_classify_flow(sk, &fl); - return ip_route_output_flow(sock_net(sk), rp, &fl, sk); + return ip_route_output_flow(sock_net(sk), &fl, sk); } - return 0; + return rt; } extern void rt_bind_peer(struct rtable *rt, int create); diff --git a/net/atm/clip.c b/net/atm/clip.c index d257da50fcfb..810a1294eddb 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c @@ -520,9 +520,9 @@ static int clip_setentry(struct atm_vcc *vcc, __be32 ip) unlink_clip_vcc(clip_vcc); return 0; } - error = ip_route_output_key(&init_net, &rt, &fl); - if (error) - return error; + rt = ip_route_output_key(&init_net, &fl); + if (IS_ERR(rt)) + return PTR_ERR(rt); neigh = __neigh_lookup(&clip_tbl, &ip, rt->dst.dev, 1); ip_rt_put(rt); if (!neigh) diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 4b5b66d07bba..45b57b173f70 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -428,14 +428,15 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb) if (err != -EHOSTUNREACH || !in_dev || IN_DEV_FORWARD(in_dev)) goto free_skb; - if (!ip_route_output_key(dev_net(dev), &rt, &fl)) { + rt = ip_route_output_key(dev_net(dev), &fl); + if (!IS_ERR(rt)) { /* - Bridged-and-DNAT'ed traffic doesn't * require ip_forwarding. */ - if (((struct dst_entry *)rt)->dev == dev) { - skb_dst_set(skb, (struct dst_entry *)rt); + if (rt->dst.dev == dev) { + skb_dst_set(skb, &rt->dst); goto bridged_dnat; } - dst_release((struct dst_entry *)rt); + ip_rt_put(rt); } free_skb: kfree_skb(skb); diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index a8ff95502081..7882377bc62e 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -46,7 +46,6 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) __be16 orig_sport, orig_dport; struct rtable *rt; __be32 daddr, nexthop; - int tmp; int err; dp->dccps_role = DCCP_ROLE_CLIENT; @@ -66,12 +65,12 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) orig_sport = inet->inet_sport; orig_dport = usin->sin_port; - tmp = ip_route_connect(&rt, nexthop, inet->inet_saddr, - RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, - IPPROTO_DCCP, - orig_sport, orig_dport, sk, true); - if (tmp < 0) - return tmp; + rt = ip_route_connect(nexthop, inet->inet_saddr, + RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, + IPPROTO_DCCP, + orig_sport, orig_dport, sk, true); + if (IS_ERR(rt)) + return PTR_ERR(rt); if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) { ip_rt_put(rt); @@ -102,12 +101,13 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) if (err != 0) goto failure; - err = ip_route_newports(&rt, IPPROTO_DCCP, - orig_sport, orig_dport, - inet->inet_sport, inet->inet_dport, sk); - if (err != 0) + rt = ip_route_newports(rt, IPPROTO_DCCP, + orig_sport, orig_dport, + inet->inet_sport, inet->inet_dport, sk); + if (IS_ERR(rt)) { + rt = NULL; goto failure; - + } /* OK, now commit destination to socket. */ sk_setup_caps(sk, &rt->dst); @@ -475,7 +475,8 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk, }; security_skb_classify_flow(skb, &fl); - if (ip_route_output_flow(net, &rt, &fl, sk)) { + rt = ip_route_output_flow(net, &fl, sk); + if (IS_ERR(rt)) { IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); return NULL; } diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 44513bb8ac2e..35a502055018 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1101,23 +1101,20 @@ int sysctl_ip_dynaddr __read_mostly; static int inet_sk_reselect_saddr(struct sock *sk) { struct inet_sock *inet = inet_sk(sk); - int err; - struct rtable *rt; __be32 old_saddr = inet->inet_saddr; - __be32 new_saddr; __be32 daddr = inet->inet_daddr; + struct rtable *rt; + __be32 new_saddr; if (inet->opt && inet->opt->srr) daddr = inet->opt->faddr; /* Query new route. */ - err = ip_route_connect(&rt, daddr, 0, - RT_CONN_FLAGS(sk), - sk->sk_bound_dev_if, - sk->sk_protocol, - inet->inet_sport, inet->inet_dport, sk, false); - if (err) - return err; + rt = ip_route_connect(daddr, 0, RT_CONN_FLAGS(sk), + sk->sk_bound_dev_if, sk->sk_protocol, + inet->inet_sport, inet->inet_dport, sk, false); + if (IS_ERR(rt)) + return PTR_ERR(rt); sk_setup_caps(sk, &rt->dst); @@ -1160,7 +1157,7 @@ int inet_sk_rebuild_header(struct sock *sk) daddr = inet->inet_daddr; if (inet->opt && inet->opt->srr) daddr = inet->opt->faddr; -{ + { struct flowi fl = { .oif = sk->sk_bound_dev_if, .mark = sk->sk_mark, @@ -1174,11 +1171,14 @@ int inet_sk_rebuild_header(struct sock *sk) }; security_sk_classify_flow(sk, &fl); - err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk); -} - if (!err) + rt = ip_route_output_flow(sock_net(sk), &fl, sk); + } + if (!IS_ERR(rt)) { + err = 0; sk_setup_caps(sk, &rt->dst); - else { + } else { + err = PTR_ERR(rt); + /* Routing failed... */ sk->sk_route_caps = 0; /* diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 7927589813b5..fa9988da1da4 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -440,7 +440,8 @@ static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev) /*unsigned long now; */ struct net *net = dev_net(dev); - if (ip_route_output_key(net, &rt, &fl) < 0) + rt = ip_route_output_key(net, &fl); + if (IS_ERR(rt)) return 1; if (rt->dst.dev != dev) { NET_INC_STATS_BH(net, LINUX_MIB_ARPFILTER); @@ -1063,10 +1064,10 @@ static int arp_req_set(struct net *net, struct arpreq *r, if (dev == NULL) { struct flowi fl = { .fl4_dst = ip, .fl4_tos = RTO_ONLINK }; - struct rtable *rt; - err = ip_route_output_key(net, &rt, &fl); - if (err != 0) - return err; + struct rtable *rt = ip_route_output_key(net, &fl); + + if (IS_ERR(rt)) + return PTR_ERR(rt); dev = rt->dst.dev; ip_rt_put(rt); if (!dev) @@ -1177,7 +1178,6 @@ static int arp_req_delete_public(struct net *net, struct arpreq *r, static int arp_req_delete(struct net *net, struct arpreq *r, struct net_device *dev) { - int err; __be32 ip; if (r->arp_flags & ATF_PUBL) @@ -1187,10 +1187,9 @@ static int arp_req_delete(struct net *net, struct arpreq *r, if (dev == NULL) { struct flowi fl = { .fl4_dst = ip, .fl4_tos = RTO_ONLINK }; - struct rtable *rt; - err = ip_route_output_key(net, &rt, &fl); - if (err != 0) - return err; + struct rtable *rt = ip_route_output_key(net, &fl); + if (IS_ERR(rt)) + return PTR_ERR(rt); dev = rt->dst.dev; ip_rt_put(rt); if (!dev) diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c index eaee1edd2dd7..85bd24ca4f6d 100644 --- a/net/ipv4/datagram.c +++ b/net/ipv4/datagram.c @@ -46,11 +46,12 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) if (!saddr) saddr = inet->mc_addr; } - err = ip_route_connect(&rt, usin->sin_addr.s_addr, saddr, - RT_CONN_FLAGS(sk), oif, - sk->sk_protocol, - inet->inet_sport, usin->sin_port, sk, true); - if (err) { + rt = ip_route_connect(usin->sin_addr.s_addr, saddr, + RT_CONN_FLAGS(sk), oif, + sk->sk_protocol, + inet->inet_sport, usin->sin_port, sk, true); + if (IS_ERR(rt)) { + err = PTR_ERR(rt); if (err == -ENETUNREACH) IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); return err; diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index c23bd8cdeee0..994a785d98f9 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -358,7 +358,8 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) .fl4_tos = RT_TOS(ip_hdr(skb)->tos), .proto = IPPROTO_ICMP }; security_skb_classify_flow(skb, &fl); - if (ip_route_output_key(net, &rt, &fl)) + rt = ip_route_output_key(net, &fl); + if (IS_ERR(rt)) goto out_unlock; } if (icmpv4_xrlim_allow(net, rt, icmp_param->data.icmph.type, @@ -388,9 +389,9 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in, int err; security_skb_classify_flow(skb_in, &fl); - err = __ip_route_output_key(net, &rt, &fl); - if (err) - return ERR_PTR(err); + rt = __ip_route_output_key(net, &fl); + if (IS_ERR(rt)) + return rt; /* No need to clone since we're just using its address. */ rt2 = rt; @@ -412,15 +413,19 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in, goto relookup_failed; if (inet_addr_type(net, fl.fl4_src) == RTN_LOCAL) { - err = __ip_route_output_key(net, &rt2, &fl); + rt2 = __ip_route_output_key(net, &fl); + if (IS_ERR(rt2)) + err = PTR_ERR(rt2); } else { struct flowi fl2 = {}; unsigned long orefdst; fl2.fl4_dst = fl.fl4_src; - err = ip_route_output_key(net, &rt2, &fl2); - if (err) + rt2 = ip_route_output_key(net, &fl2); + if (IS_ERR(rt2)) { + err = PTR_ERR(rt2); goto relookup_failed; + } /* Ugh! */ orefdst = skb_in->_skb_refdst; /* save old refdst */ err = ip_route_input(skb_in, fl.fl4_dst, fl.fl4_src, diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index e0e77e297de3..44ba9068b72f 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -325,7 +325,8 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) struct flowi fl = { .oif = dev->ifindex, .fl4_dst = IGMPV3_ALL_MCR, .proto = IPPROTO_IGMP }; - if (ip_route_output_key(net, &rt, &fl)) { + rt = ip_route_output_key(net, &fl); + if (IS_ERR(rt)) { kfree_skb(skb); return NULL; } @@ -670,7 +671,8 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, struct flowi fl = { .oif = dev->ifindex, .fl4_dst = dst, .proto = IPPROTO_IGMP }; - if (ip_route_output_key(net, &rt, &fl)) + rt = ip_route_output_key(net, &fl); + if (IS_ERR(rt)) return -1; } if (rt->rt_src == 0) { @@ -1440,7 +1442,6 @@ void ip_mc_destroy_dev(struct in_device *in_dev) static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr) { struct flowi fl = { .fl4_dst = imr->imr_multiaddr.s_addr }; - struct rtable *rt; struct net_device *dev = NULL; struct in_device *idev = NULL; @@ -1454,9 +1455,12 @@ static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr) return NULL; } - if (!dev && !ip_route_output_key(net, &rt, &fl)) { - dev = rt->dst.dev; - ip_rt_put(rt); + if (!dev) { + struct rtable *rt = ip_route_output_key(net, &fl); + if (!IS_ERR(rt)) { + dev = rt->dst.dev; + ip_rt_put(rt); + } } if (dev) { imr->imr_ifindex = dev->ifindex; diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 7f85d4aec26a..e4e301a61c5b 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -369,7 +369,8 @@ struct dst_entry *inet_csk_route_req(struct sock *sk, struct net *net = sock_net(sk); security_req_classify_flow(req, &fl); - if (ip_route_output_flow(net, &rt, &fl, sk)) + rt = ip_route_output_flow(net, &fl, sk); + if (IS_ERR(rt)) goto no_route; if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) goto route_err; diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 6613edfac28c..f9af98dd7561 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -778,7 +778,8 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev .proto = IPPROTO_GRE, .fl_gre_key = tunnel->parms.o_key }; - if (ip_route_output_key(dev_net(dev), &rt, &fl)) { + rt = ip_route_output_key(dev_net(dev), &fl); + if (IS_ERR(rt)) { dev->stats.tx_carrier_errors++; goto tx_error; } @@ -953,9 +954,9 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev) .proto = IPPROTO_GRE, .fl_gre_key = tunnel->parms.o_key }; - struct rtable *rt; + struct rtable *rt = ip_route_output_key(dev_net(dev), &fl); - if (!ip_route_output_key(dev_net(dev), &rt, &fl)) { + if (!IS_ERR(rt)) { tdev = rt->dst.dev; ip_rt_put(rt); } @@ -1215,9 +1216,9 @@ static int ipgre_open(struct net_device *dev) .proto = IPPROTO_GRE, .fl_gre_key = t->parms.o_key }; - struct rtable *rt; + struct rtable *rt = ip_route_output_key(dev_net(dev), &fl); - if (ip_route_output_key(dev_net(dev), &rt, &fl)) + if (IS_ERR(rt)) return -EADDRNOTAVAIL; dev = rt->dst.dev; ip_rt_put(rt); diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 33316b3534ca..171f483b21d5 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -355,7 +355,8 @@ int ip_queue_xmit(struct sk_buff *skb) * itself out. */ security_sk_classify_flow(sk, &fl); - if (ip_route_output_flow(sock_net(sk), &rt, &fl, sk)) + rt = ip_route_output_flow(sock_net(sk), &fl, sk); + if (IS_ERR(rt)) goto no_route; } sk_setup_caps(sk, &rt->dst); @@ -1489,7 +1490,8 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar .proto = sk->sk_protocol, .flags = ip_reply_arg_flowi_flags(arg) }; security_skb_classify_flow(skb, &fl); - if (ip_route_output_key(sock_net(sk), &rt, &fl)) + rt = ip_route_output_key(sock_net(sk), &fl); + if (IS_ERR(rt)) return; } diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 988f52fba54a..e1e17576baa6 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -469,7 +469,8 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) .proto = IPPROTO_IPIP }; - if (ip_route_output_key(dev_net(dev), &rt, &fl)) { + rt = ip_route_output_key(dev_net(dev), &fl); + if (IS_ERR(rt)) { dev->stats.tx_carrier_errors++; goto tx_error_icmp; } @@ -590,9 +591,9 @@ static void ipip_tunnel_bind_dev(struct net_device *dev) .fl4_tos = RT_TOS(iph->tos), .proto = IPPROTO_IPIP }; - struct rtable *rt; + struct rtable *rt = ip_route_output_key(dev_net(dev), &fl); - if (!ip_route_output_key(dev_net(dev), &rt, &fl)) { + if (!IS_ERR(rt)) { tdev = rt->dst.dev; ip_rt_put(rt); } diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 8b65a12654e7..26ca2f2d37ce 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -1618,8 +1618,8 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, .fl4_tos = RT_TOS(iph->tos), .proto = IPPROTO_IPIP }; - - if (ip_route_output_key(net, &rt, &fl)) + rt = ip_route_output_key(net, &fl); + if (IS_ERR(rt)) goto out_free; encap = sizeof(struct iphdr); } else { @@ -1629,8 +1629,8 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, .fl4_tos = RT_TOS(iph->tos), .proto = IPPROTO_IPIP }; - - if (ip_route_output_key(net, &rt, &fl)) + rt = ip_route_output_key(net, &fl); + if (IS_ERR(rt)) goto out_free; } diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index 9770bb427952..67bf709180de 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c @@ -38,7 +38,8 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; fl.mark = skb->mark; fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; - if (ip_route_output_key(net, &rt, &fl) != 0) + rt = ip_route_output_key(net, &fl); + if (IS_ERR(rt)) return -1; /* Drop old route. */ @@ -48,7 +49,8 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) /* non-local src, find valid iif to satisfy * rp-filter when calling ip_route_input. */ fl.fl4_dst = iph->saddr; - if (ip_route_output_key(net, &rt, &fl) != 0) + rt = ip_route_output_key(net, &fl); + if (IS_ERR(rt)) return -1; orefdst = skb->_skb_refdst; @@ -221,7 +223,11 @@ static __sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook, static int nf_ip_route(struct dst_entry **dst, struct flowi *fl) { - return ip_route_output_key(&init_net, (struct rtable **)dst, fl); + struct rtable *rt = ip_route_output_key(&init_net, fl); + if (IS_ERR(rt)) + return PTR_ERR(rt); + *dst = &rt->dst; + return 0; } static const struct nf_afinfo nf_ip_afinfo = { diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index d7a2d1eaec09..467d570d087a 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -564,10 +564,12 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, } security_sk_classify_flow(sk, &fl); - err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk); + rt = ip_route_output_flow(sock_net(sk), &fl, sk); + if (IS_ERR(rt)) { + err = PTR_ERR(rt); + goto done; + } } - if (err) - goto done; err = -EACCES; if (rt->rt_flags & RTCF_BROADCAST && !sock_flag(sk, SOCK_BROADCAST)) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 63d37004ee66..5090e956f6b8 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1014,8 +1014,8 @@ static int slow_chain_length(const struct rtable *head) return length >> FRACT_BITS; } -static int rt_intern_hash(unsigned hash, struct rtable *rt, - struct rtable **rp, struct sk_buff *skb, int ifindex) +static struct rtable *rt_intern_hash(unsigned hash, struct rtable *rt, + struct sk_buff *skb, int ifindex) { struct rtable *rth, *cand; struct rtable __rcu **rthp, **candp; @@ -1056,7 +1056,7 @@ restart: printk(KERN_WARNING "Neighbour table failure & not caching routes.\n"); ip_rt_put(rt); - return err; + return ERR_PTR(err); } } @@ -1093,11 +1093,9 @@ restart: spin_unlock_bh(rt_hash_lock_addr(hash)); rt_drop(rt); - if (rp) - *rp = rth; - else + if (skb) skb_dst_set(skb, &rth->dst); - return 0; + return rth; } if (!atomic_read(&rth->dst.__refcnt)) { @@ -1154,7 +1152,7 @@ restart: if (err != -ENOBUFS) { rt_drop(rt); - return err; + return ERR_PTR(err); } /* Neighbour tables are full and nothing @@ -1175,7 +1173,7 @@ restart: if (net_ratelimit()) printk(KERN_WARNING "ipv4: Neighbour table overflow.\n"); rt_drop(rt); - return -ENOBUFS; + return ERR_PTR(-ENOBUFS); } } @@ -1201,11 +1199,9 @@ restart: spin_unlock_bh(rt_hash_lock_addr(hash)); skip_hashing: - if (rp) - *rp = rt; - else + if (skb) skb_dst_set(skb, &rt->dst); - return 0; + return rt; } static atomic_t __rt_peer_genid = ATOMIC_INIT(0); @@ -1896,7 +1892,10 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, RT_CACHE_STAT_INC(in_slow_mc); hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); - return rt_intern_hash(hash, rth, NULL, skb, dev->ifindex); + rth = rt_intern_hash(hash, rth, skb, dev->ifindex); + err = 0; + if (IS_ERR(rth)) + err = PTR_ERR(rth); e_nobufs: return -ENOBUFS; @@ -2051,7 +2050,10 @@ static int ip_mkroute_input(struct sk_buff *skb, /* put it into the cache */ hash = rt_hash(daddr, saddr, fl->iif, rt_genid(dev_net(rth->dst.dev))); - return rt_intern_hash(hash, rth, NULL, skb, fl->iif); + rth = rt_intern_hash(hash, rth, skb, fl->iif); + if (IS_ERR(rth)) + return PTR_ERR(rth); + return 0; } /* @@ -2194,7 +2196,10 @@ local_input: } rth->rt_type = res.type; hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); - err = rt_intern_hash(hash, rth, NULL, skb, fl.iif); + rth = rt_intern_hash(hash, rth, skb, fl.iif); + err = 0; + if (IS_ERR(rth)) + err = PTR_ERR(rth); goto out; no_route: @@ -2422,8 +2427,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res, * called with rcu_read_lock(); */ -static int ip_route_output_slow(struct net *net, struct rtable **rp, - const struct flowi *oldflp) +static struct rtable *ip_route_output_slow(struct net *net, + const struct flowi *oldflp) { u32 tos = RT_FL_TOS(oldflp); struct flowi fl = { .fl4_dst = oldflp->fl4_dst, @@ -2438,8 +2443,6 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, unsigned int flags = 0; struct net_device *dev_out = NULL; struct rtable *rth; - int err; - res.fi = NULL; #ifdef CONFIG_IP_MULTIPLE_TABLES @@ -2448,7 +2451,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, rcu_read_lock(); if (oldflp->fl4_src) { - err = -EINVAL; + rth = ERR_PTR(-EINVAL); if (ipv4_is_multicast(oldflp->fl4_src) || ipv4_is_lbcast(oldflp->fl4_src) || ipv4_is_zeronet(oldflp->fl4_src)) @@ -2499,13 +2502,13 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, if (oldflp->oif) { dev_out = dev_get_by_index_rcu(net, oldflp->oif); - err = -ENODEV; + rth = ERR_PTR(-ENODEV); if (dev_out == NULL) goto out; /* RACE: Check return value of inet_select_addr instead. */ if (!(dev_out->flags & IFF_UP) || !__in_dev_get_rcu(dev_out)) { - err = -ENETUNREACH; + rth = ERR_PTR(-ENETUNREACH); goto out; } if (ipv4_is_local_multicast(oldflp->fl4_dst) || @@ -2563,7 +2566,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, res.type = RTN_UNICAST; goto make_route; } - err = -ENETUNREACH; + rth = ERR_PTR(-ENETUNREACH); goto out; } @@ -2598,23 +2601,20 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, make_route: rth = __mkroute_output(&res, &fl, oldflp, dev_out, flags); - if (IS_ERR(rth)) - err = PTR_ERR(rth); - else { + if (!IS_ERR(rth)) { unsigned int hash; hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif, rt_genid(dev_net(dev_out))); - err = rt_intern_hash(hash, rth, rp, NULL, oldflp->oif); + rth = rt_intern_hash(hash, rth, NULL, oldflp->oif); } out: rcu_read_unlock(); - return err; + return rth; } -int __ip_route_output_key(struct net *net, struct rtable **rp, - const struct flowi *flp) +struct rtable *__ip_route_output_key(struct net *net, const struct flowi *flp) { struct rtable *rth; unsigned int hash; @@ -2639,15 +2639,14 @@ int __ip_route_output_key(struct net *net, struct rtable **rp, dst_use(&rth->dst, jiffies); RT_CACHE_STAT_INC(out_hit); rcu_read_unlock_bh(); - *rp = rth; - return 0; + return rth; } RT_CACHE_STAT_INC(out_hlist_search); } rcu_read_unlock_bh(); slow_output: - return ip_route_output_slow(net, rp, flp); + return ip_route_output_slow(net, flp); } EXPORT_SYMBOL_GPL(__ip_route_output_key); @@ -2717,34 +2716,29 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or return rt ? &rt->dst : ERR_PTR(-ENOMEM); } -int ip_route_output_flow(struct net *net, struct rtable **rp, struct flowi *flp, - struct sock *sk) +struct rtable *ip_route_output_flow(struct net *net, struct flowi *flp, + struct sock *sk) { - int err; + struct rtable *rt = __ip_route_output_key(net, flp); - if ((err = __ip_route_output_key(net, rp, flp)) != 0) - return err; + if (IS_ERR(rt)) + return rt; if (flp->proto) { if (!flp->fl4_src) - flp->fl4_src = (*rp)->rt_src; + flp->fl4_src = rt->rt_src; if (!flp->fl4_dst) - flp->fl4_dst = (*rp)->rt_dst; - *rp = (struct rtable *) xfrm_lookup(net, &(*rp)->dst, flp, sk, 0); - if (IS_ERR(*rp)) { - err = PTR_ERR(*rp); - *rp = NULL; - return err; - } + flp->fl4_dst = rt->rt_dst; + rt = (struct rtable *) xfrm_lookup(net, &rt->dst, flp, sk, 0); } - return 0; + return rt; } EXPORT_SYMBOL_GPL(ip_route_output_flow); -int ip_route_output_key(struct net *net, struct rtable **rp, struct flowi *flp) +struct rtable *ip_route_output_key(struct net *net, struct flowi *flp) { - return ip_route_output_flow(net, rp, flp, NULL); + return ip_route_output_flow(net, flp, NULL); } EXPORT_SYMBOL(ip_route_output_key); @@ -2915,7 +2909,11 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void .oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0, .mark = mark, }; - err = ip_route_output_key(net, &rt, &fl); + rt = ip_route_output_key(net, &fl); + + err = 0; + if (IS_ERR(rt)) + err = PTR_ERR(rt); } if (err) diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 47519205a014..0ad6ddf638a7 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -355,7 +355,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, .fl_ip_sport = th->dest, .fl_ip_dport = th->source }; security_req_classify_flow(req, &fl); - if (ip_route_output_key(sock_net(sk), &rt, &fl)) { + rt = ip_route_output_key(sock_net(sk), &fl); + if (IS_ERR(rt)) { reqsk_free(req); goto out; } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 05bc6d9455fc..f7e6c2c2d2bb 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -152,7 +152,6 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) __be16 orig_sport, orig_dport; struct rtable *rt; __be32 daddr, nexthop; - int tmp; int err; if (addr_len < sizeof(struct sockaddr_in)) @@ -170,14 +169,15 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) orig_sport = inet->inet_sport; orig_dport = usin->sin_port; - tmp = ip_route_connect(&rt, nexthop, inet->inet_saddr, - RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, - IPPROTO_TCP, - orig_sport, orig_dport, sk, true); - if (tmp < 0) { - if (tmp == -ENETUNREACH) + rt = ip_route_connect(nexthop, inet->inet_saddr, + RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, + IPPROTO_TCP, + orig_sport, orig_dport, sk, true); + if (IS_ERR(rt)) { + err = PTR_ERR(rt); + if (err == -ENETUNREACH) IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); - return tmp; + return err; } if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) { @@ -236,12 +236,14 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) if (err) goto failure; - err = ip_route_newports(&rt, IPPROTO_TCP, - orig_sport, orig_dport, - inet->inet_sport, inet->inet_dport, sk); - if (err) + rt = ip_route_newports(rt, IPPROTO_TCP, + orig_sport, orig_dport, + inet->inet_sport, inet->inet_dport, sk); + if (IS_ERR(rt)) { + err = PTR_ERR(rt); + rt = NULL; goto failure; - + } /* OK, now commit destination to socket. */ sk->sk_gso_type = SKB_GSO_TCPV4; sk_setup_caps(sk, &rt->dst); diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index ed9a5b7bee53..95e0c2c194a1 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -922,8 +922,9 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, struct net *net = sock_net(sk); security_sk_classify_flow(sk, &fl); - err = ip_route_output_flow(net, &rt, &fl, sk); - if (err) { + rt = ip_route_output_flow(net, &fl, sk); + if (IS_ERR(rt)) { + err = PTR_ERR(rt); if (err == -ENETUNREACH) IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); goto out; diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 5f0f058dc376..45b821480427 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -26,18 +26,16 @@ static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos, .fl4_dst = daddr->a4, .fl4_tos = tos, }; - struct dst_entry *dst; struct rtable *rt; - int err; if (saddr) fl.fl4_src = saddr->a4; - err = __ip_route_output_key(net, &rt, &fl); - dst = &rt->dst; - if (err) - dst = ERR_PTR(err); - return dst; + rt = __ip_route_output_key(net, &fl); + if (!IS_ERR(rt)) + return &rt->dst; + + return ERR_CAST(rt); } static int xfrm4_get_saddr(struct net *net, diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index da43038ae18e..02730ef26b0f 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -581,7 +581,8 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, fl.fl4_dst = eiph->saddr; fl.fl4_tos = RT_TOS(eiph->tos); fl.proto = IPPROTO_IPIP; - if (ip_route_output_key(dev_net(skb->dev), &rt, &fl)) + rt = ip_route_output_key(dev_net(skb->dev), &fl); + if (IS_ERR(rt)) goto out; skb2->dev = rt->dst.dev; @@ -593,12 +594,14 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, fl.fl4_dst = eiph->daddr; fl.fl4_src = eiph->saddr; fl.fl4_tos = eiph->tos; - if (ip_route_output_key(dev_net(skb->dev), &rt, &fl) || + rt = ip_route_output_key(dev_net(skb->dev), &fl); + if (IS_ERR(rt) || rt->dst.dev->type != ARPHRD_TUNNEL) { - ip_rt_put(rt); + if (!IS_ERR(rt)) + ip_rt_put(rt); goto out; } - skb_dst_set(skb2, (struct dst_entry *)rt); + skb_dst_set(skb2, &rt->dst); } else { ip_rt_put(rt); if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index b1599a345c10..b8c8adbd7cf6 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -738,7 +738,8 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, .fl4_tos = RT_TOS(tos), .oif = tunnel->parms.link, .proto = IPPROTO_IPV6 }; - if (ip_route_output_key(dev_net(dev), &rt, &fl)) { + rt = ip_route_output_key(dev_net(dev), &fl); + if (IS_ERR(rt)) { dev->stats.tx_carrier_errors++; goto tx_error_icmp; } @@ -862,8 +863,9 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev) .fl4_tos = RT_TOS(iph->tos), .oif = tunnel->parms.link, .proto = IPPROTO_IPV6 }; - struct rtable *rt; - if (!ip_route_output_key(dev_net(dev), &rt, &fl)) { + struct rtable *rt = ip_route_output_key(dev_net(dev), &fl); + + if (!IS_ERR(rt)) { tdev = rt->dst.dev; ip_rt_put(rt); } diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 5381cebe516d..2a698ff89db6 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -320,11 +320,12 @@ static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len if (ipv4_is_multicast(lsa->l2tp_addr.s_addr)) goto out; - rc = ip_route_connect(&rt, lsa->l2tp_addr.s_addr, saddr, + rt = ip_route_connect(lsa->l2tp_addr.s_addr, saddr, RT_CONN_FLAGS(sk), oif, IPPROTO_L2TP, 0, 0, sk, true); - if (rc) { + if (IS_ERR(rt)) { + rc = PTR_ERR(rt); if (rc == -ENETUNREACH) IP_INC_STATS_BH(&init_net, IPSTATS_MIB_OUTNOROUTES); goto out; @@ -489,7 +490,8 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m * itself out. */ security_sk_classify_flow(sk, &fl); - if (ip_route_output_flow(sock_net(sk), &rt, &fl, sk)) + rt = ip_route_output_flow(sock_net(sk), &fl, sk); + if (IS_ERR(rt)) goto no_route; } sk_setup_caps(sk, &rt->dst); diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 6264219f0a42..878f6dd9dbad 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -103,7 +103,8 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest, .fl4_tos = rtos, }; - if (ip_route_output_key(net, &rt, &fl)) { + rt = ip_route_output_key(net, &fl); + if (IS_ERR(rt)) { spin_unlock(&dest->dst_lock); IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n", &dest->addr.ip); @@ -121,7 +122,8 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest, .fl4_tos = rtos, }; - if (ip_route_output_key(net, &rt, &fl)) { + rt = ip_route_output_key(net, &fl); + if (IS_ERR(rt)) { IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n", &daddr); return NULL; @@ -180,7 +182,8 @@ __ip_vs_reroute_locally(struct sk_buff *skb) .mark = skb->mark, }; - if (ip_route_output_key(net, &rt, &fl)) + rt = ip_route_output_key(net, &fl); + if (IS_ERR(rt)) return 0; if (!(rt->rt_flags & RTCF_LOCAL)) { ip_rt_put(rt); diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c index 5128a6c4cb2c..624725b5286f 100644 --- a/net/netfilter/xt_TEE.c +++ b/net/netfilter/xt_TEE.c @@ -73,7 +73,8 @@ tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info) fl.fl4_dst = info->gw.ip; fl.fl4_tos = RT_TOS(iph->tos); fl.fl4_scope = RT_SCOPE_UNIVERSE; - if (ip_route_output_key(net, &rt, &fl) != 0) + rt = ip_route_output_key(net, &fl); + if (IS_ERR(rt)) return false; skb_dst_drop(skb); diff --git a/net/rxrpc/ar-peer.c b/net/rxrpc/ar-peer.c index a53fb25a64ed..3620c569275f 100644 --- a/net/rxrpc/ar-peer.c +++ b/net/rxrpc/ar-peer.c @@ -37,7 +37,6 @@ static void rxrpc_assess_MTU_size(struct rxrpc_peer *peer) { struct rtable *rt; struct flowi fl; - int ret; peer->if_mtu = 1500; @@ -58,9 +57,9 @@ static void rxrpc_assess_MTU_size(struct rxrpc_peer *peer) BUG(); } - ret = ip_route_output_key(&init_net, &rt, &fl); - if (ret < 0) { - _leave(" [route err %d]", ret); + rt = ip_route_output_key(&init_net, &fl); + if (IS_ERR(rt)) { + _leave(" [route err %ld]", PTR_ERR(rt)); return; } diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index e58f9476f29c..4e55e6c49ec9 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -491,9 +491,9 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ", __func__, &fl.fl4_dst, &fl.fl4_src); - if (!ip_route_output_key(&init_net, &rt, &fl)) { + rt = ip_route_output_key(&init_net, &fl); + if (!IS_ERR(rt)) dst = &rt->dst; - } /* If there is no association or if a source address is passed, no * more validation is required. @@ -535,7 +535,8 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, (AF_INET == laddr->a.sa.sa_family)) { fl.fl4_src = laddr->a.v4.sin_addr.s_addr; fl.fl_ip_sport = laddr->a.v4.sin_port; - if (!ip_route_output_key(&init_net, &rt, &fl)) { + rt = ip_route_output_key(&init_net, &fl); + if (!IS_ERR(rt)) { dst = &rt->dst; goto out_unlock; } -- cgit v1.2.3 From 107c3f4d42adc9af393019b795dd2177fbe9e465 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 2 Mar 2011 13:00:49 +0000 Subject: cnic: Prevent status block race conditions with hardware The status block index is used to acknowledge interrupt events and must be read before checking for the interrupt events, so we need to add rmb() to guarantee that. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 7ff170cbc7dc..b0d9e4ab6467 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -2760,6 +2760,8 @@ static u32 cnic_service_bnx2_queues(struct cnic_dev *dev) u32 status_idx = (u16) *cp->kcq1.status_idx_ptr; int kcqe_cnt; + /* status block index must be read before reading other fields */ + rmb(); cp->kwq_con_idx = *cp->kwq_con_idx_ptr; while ((kcqe_cnt = cnic_get_kcqes(dev, &cp->kcq1))) { @@ -2770,6 +2772,8 @@ static u32 cnic_service_bnx2_queues(struct cnic_dev *dev) barrier(); if (status_idx != *cp->kcq1.status_idx_ptr) { status_idx = (u16) *cp->kcq1.status_idx_ptr; + /* status block index must be read first */ + rmb(); cp->kwq_con_idx = *cp->kwq_con_idx_ptr; } else break; @@ -2888,6 +2892,8 @@ static u32 cnic_service_bnx2x_kcq(struct cnic_dev *dev, struct kcq_info *info) u32 last_status = *info->status_idx_ptr; int kcqe_cnt; + /* status block index must be read before reading the KCQ */ + rmb(); while ((kcqe_cnt = cnic_get_kcqes(dev, info))) { service_kcqes(dev, kcqe_cnt); @@ -2898,6 +2904,8 @@ static u32 cnic_service_bnx2x_kcq(struct cnic_dev *dev, struct kcq_info *info) break; last_status = *info->status_idx_ptr; + /* status block index must be read before reading the KCQ */ + rmb(); } return last_status; } -- cgit v1.2.3 From 0197b087ed6384760656f1e4a620a3e92d8dc0b0 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 2 Mar 2011 13:00:50 +0000 Subject: cnic: Fix lost interrupt on bnx2x We service 2 queues (kcq1 and kcq2) in cnic_service_bnx2x_bh(). If the status block index has changed when servicing the kcq2, we must go back and check kcq1. The latest status block index will be used to acknowledge the interrupt, and without looping back to check kcq1, we may miss events on kcq1. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index b0d9e4ab6467..302be4aa69d6 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -2914,26 +2914,35 @@ static void cnic_service_bnx2x_bh(unsigned long data) { struct cnic_dev *dev = (struct cnic_dev *) data; struct cnic_local *cp = dev->cnic_priv; - u32 status_idx; + u32 status_idx, new_status_idx; if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags))) return; - status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq1); + while (1) { + status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq1); - CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx + MAX_KCQ_IDX); + CNIC_WR16(dev, cp->kcq1.io_addr, + cp->kcq1.sw_prod_idx + MAX_KCQ_IDX); - if (BNX2X_CHIP_IS_E2(cp->chip_id)) { - status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq2); + if (!BNX2X_CHIP_IS_E2(cp->chip_id)) { + cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID, + status_idx, IGU_INT_ENABLE, 1); + break; + } + + new_status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq2); + + if (new_status_idx != status_idx) + continue; CNIC_WR16(dev, cp->kcq2.io_addr, cp->kcq2.sw_prod_idx + MAX_KCQ_IDX); cnic_ack_igu_sb(dev, cp->bnx2x_igu_sb_id, IGU_SEG_ACCESS_DEF, status_idx, IGU_INT_ENABLE, 1); - } else { - cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID, - status_idx, IGU_INT_ENABLE, 1); + + break; } } -- cgit v1.2.3 From 810acd19a4cd1e29d910f8a7eea8bcc168de00cd Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 2 Mar 2011 21:18:37 +0100 Subject: staging: brcm80211: remove struct osl_info usage from wlc_bmac Getting rid of osl concept taking small steps. This commit removes it from wlc_bmac.c. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 54 ++------------------------- drivers/staging/brcm80211/brcmsmac/wlc_bmac.h | 4 +- drivers/staging/brcm80211/brcmsmac/wlc_main.c | 7 +++- drivers/staging/brcm80211/brcmsmac/wlc_main.h | 1 - 4 files changed, 10 insertions(+), 56 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 71f8a2234801..6ec0ab799802 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -185,10 +185,8 @@ void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot) static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw, bool shortslot) { - struct osl_info *osh; d11regs_t *regs; - osh = wlc_hw->osh; regs = wlc_hw->regs; if (shortslot) { @@ -533,7 +531,7 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) if (wlc_hw->di[0] == 0) { /* Init FIFOs */ uint addrwidth; int dma_attach_err = 0; - struct osl_info *osh = wlc_hw->osh; + struct osl_info *osh = wlc->osh; /* Find out the DMA addressing capability and let OS know * All the channels within one DMA core have 'common-minimum' same @@ -640,8 +638,7 @@ static void wlc_bmac_detach_dmapio(struct wlc_hw_info *wlc_hw) * put the whole chip in reset(driver down state), no clock */ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, - bool piomode, struct osl_info *osh, void *regsva, - uint bustype, void *btparam) + bool piomode, void *regsva, uint bustype, void *btparam) { struct wlc_hw_info *wlc_hw; d11regs_t *regs; @@ -662,7 +659,6 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc_hw = wlc->hw; wlc_hw->wlc = wlc; wlc_hw->unit = unit; - wlc_hw->osh = osh; wlc_hw->band = wlc_hw->bandstate[0]; wlc_hw->_piomode = piomode; @@ -809,7 +805,7 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, } /* pass all the parameters to wlc_phy_shared_attach in one struct */ - sha_params.osh = osh; + sha_params.osh = wlc->osh; sha_params.sih = wlc_hw->sih; sha_params.physhim = wlc_hw->physhim; sha_params.unit = unit; @@ -1610,7 +1606,6 @@ wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, volatile u16 *objdata16 = (volatile u16 *)®s->objdata; u32 mac_hm; u16 mac_l; - struct osl_info *osh; WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); @@ -1619,8 +1614,6 @@ wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, (addr[1] << 8) | addr[0]; mac_l = (addr[5] << 8) | addr[4]; - osh = wlc_hw->osh; - W_REG(®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); (void)R_REG(®s->objaddr); W_REG(®s->objdata, mac_hm); @@ -1640,7 +1633,6 @@ wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset, u16 mac_l; u16 mac_m; u16 mac_h; - struct osl_info *osh; WL_TRACE("wl%d: wlc_bmac_set_addrmatch\n", wlc_hw->unit); @@ -1651,8 +1643,6 @@ wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset, mac_m = addr[2] | (addr[3] << 8); mac_h = addr[4] | (addr[5] << 8); - osh = wlc_hw->osh; - /* enter the MAC addr into the RXE match registers */ W_REG(®s->rcm_ctl, RCM_INC_DATA | match_reg_offset); W_REG(®s->rcm_mat_data, mac_l); @@ -1671,12 +1661,9 @@ wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, int len, #ifdef IL_BIGENDIAN volatile u16 *dptr = NULL; #endif /* IL_BIGENDIAN */ - struct osl_info *osh; - WL_TRACE("wl%d: wlc_bmac_write_template_ram\n", wlc_hw->unit); regs = wlc_hw->regs; - osh = wlc_hw->osh; ASSERT(IS_ALIGNED(offset, sizeof(u32))); ASSERT(IS_ALIGNED(len, sizeof(u32))); @@ -1707,9 +1694,6 @@ wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, int len, void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin) { - struct osl_info *osh; - - osh = wlc_hw->osh; wlc_hw->band->CWmin = newmin; W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMIN); @@ -1719,9 +1703,6 @@ void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin) void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax) { - struct osl_info *osh; - - osh = wlc_hw->osh; wlc_hw->band->CWmax = newmax; W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMAX); @@ -2281,13 +2262,10 @@ static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw) u16 txfifo_startblk = TXFIFO_START_BLK, txfifo_endblk; u16 txfifo_def, txfifo_def1; u16 txfifo_cmd; - struct osl_info *osh; /* tx fifos start at TXFIFO_START_BLK from the Base address */ txfifo_startblk = TXFIFO_START_BLK; - osh = wlc_hw->osh; - /* sequence of operations: reset fifo, set fifo size, reset fifo */ for (fifo_nu = 0; fifo_nu < NFIFO; fifo_nu++) { @@ -2340,12 +2318,10 @@ static void wlc_coreinit(struct wlc_info *wlc) uint bcnint_us; uint i = 0; bool fifosz_fixup = false; - struct osl_info *osh; int err = 0; u16 buf[NFIFO]; regs = wlc_hw->regs; - osh = wlc_hw->osh; WL_TRACE("wl%d: wlc_coreinit\n", wlc_hw->unit); @@ -2524,9 +2500,7 @@ static void wlc_coreinit(struct wlc_info *wlc) void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode) { d11regs_t *regs; - struct osl_info *osh; regs = wlc_hw->regs; - osh = wlc_hw->osh; if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || (wlc_hw->sih->chip == BCM43225_CHIP_ID)) { @@ -2557,10 +2531,8 @@ static void wlc_gpio_init(struct wlc_info *wlc) struct wlc_hw_info *wlc_hw = wlc->hw; d11regs_t *regs; u32 gc, gm; - struct osl_info *osh; regs = wlc_hw->regs; - osh = wlc_hw->osh; /* use GPIO select 0 to get all gpio signals from the gpio out reg */ wlc_bmac_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0); @@ -2647,13 +2619,10 @@ static void wlc_ucode_download(struct wlc_hw_info *wlc_hw) static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[], const uint nbytes) { - struct osl_info *osh; d11regs_t *regs = wlc_hw->regs; uint i; uint count; - osh = wlc_hw->osh; - WL_TRACE("wl%d: wlc_ucode_write\n", wlc_hw->unit); ASSERT(IS_ALIGNED(nbytes, sizeof(u32))); @@ -2670,12 +2639,10 @@ static void wlc_write_inits(struct wlc_hw_info *wlc_hw, const struct d11init *inits) { int i; - struct osl_info *osh; volatile u8 *base; WL_TRACE("wl%d: wlc_write_inits\n", wlc_hw->unit); - osh = wlc_hw->osh; base = (volatile u8 *)wlc_hw->regs; for (i = 0; inits[i].addr != 0xffff; i++) { @@ -2996,9 +2963,6 @@ static inline u32 wlc_intstatus(struct wlc_info *wlc, bool in_isr) struct wlc_hw_info *wlc_hw = wlc->hw; d11regs_t *regs = wlc_hw->regs; u32 macintstatus; - struct osl_info *osh; - - osh = wlc_hw->osh; /* macintstatus includes a DMA interrupt summary bit */ macintstatus = R_REG(®s->macintstatus); @@ -3130,7 +3094,6 @@ wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal) bool morepending = false; struct wlc_info *wlc = wlc_hw->wlc; d11regs_t *regs; - struct osl_info *osh; tx_status_t txstatus, *txs; u32 s1, s2; uint n = 0; @@ -3144,7 +3107,6 @@ wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal) txs = &txstatus; regs = wlc_hw->regs; - osh = wlc_hw->osh; while (!(*fatal) && (s1 = R_REG(®s->frmtxstatus)) & TXS_V) { @@ -3187,7 +3149,6 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) struct wlc_hw_info *wlc_hw = wlc->hw; d11regs_t *regs = wlc_hw->regs; u32 mc, mi; - struct osl_info *osh; WL_TRACE("wl%d: wlc_suspend_mac_and_wait: bandunit %d\n", wlc_hw->unit, wlc_hw->band->bandunit); @@ -3199,8 +3160,6 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) if (wlc_hw->mac_suspend_depth > 1) return; - osh = wlc_hw->osh; - /* force the core awake */ wlc_ucode_wake_override_set(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND); @@ -3254,7 +3213,6 @@ void wlc_enable_mac(struct wlc_info *wlc) struct wlc_hw_info *wlc_hw = wlc->hw; d11regs_t *regs = wlc_hw->regs; u32 mc, mi; - struct osl_info *osh; WL_TRACE("wl%d: wlc_enable_mac: bandunit %d\n", wlc_hw->unit, wlc->band->bandunit); @@ -3267,8 +3225,6 @@ void wlc_enable_mac(struct wlc_info *wlc) if (wlc_hw->mac_suspend_depth > 0) return; - osh = wlc_hw->osh; - mc = R_REG(®s->maccontrol); ASSERT(!(mc & MCTL_PSM_JMP_0)); ASSERT(!(mc & MCTL_EN_MAC)); @@ -3380,12 +3336,10 @@ static bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) { d11regs_t *regs; u32 w, val; - struct osl_info *osh; WL_TRACE("wl%d: validate_chip_access\n", wlc_hw->unit); regs = wlc_hw->regs; - osh = wlc_hw->osh; /* Validate dchip register access */ @@ -3445,14 +3399,12 @@ static bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on) { d11regs_t *regs; - struct osl_info *osh; u32 tmp; WL_TRACE("wl%d: wlc_bmac_core_phypll_ctl\n", wlc_hw->unit); tmp = 0; regs = wlc_hw->regs; - osh = wlc_hw->osh; if (on) { if ((wlc_hw->sih->chip == BCM4313_CHIP_ID)) { diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h index 21c9747a53dd..9c2c658d05ab 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h @@ -80,8 +80,8 @@ enum { }; extern int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, - uint unit, bool piomode, struct osl_info *osh, - void *regsva, uint bustype, void *btparam); + uint unit, bool piomode, void *regsva, uint bustype, + void *btparam); extern int wlc_bmac_detach(struct wlc_info *wlc); extern void wlc_bmac_watchdog(void *arg); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c index 87391bad4fea..eae6bd6f3bfc 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c @@ -1807,8 +1807,11 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, wlc_module_register(wlc->pub, wlc_iovars, "wlc_iovars", wlc, wlc_doiovar, NULL, NULL); - /* low level attach steps(all hw accesses go inside, no more in rest of the attach) */ - err = wlc_bmac_attach(wlc, vendor, device, unit, piomode, osh, regsva, + /* + * low level attach steps(all hw accesses go + * inside, no more in rest of the attach) + */ + err = wlc_bmac_attach(wlc, vendor, device, unit, piomode, regsva, bustype, btparam); if (err) goto fail; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.h b/drivers/staging/brcm80211/brcmsmac/wlc_main.h index f65be0ed1c1a..b2b52d297502 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.h @@ -397,7 +397,6 @@ struct wlc_hwband { }; struct wlc_hw_info { - struct osl_info *osh; /* pointer to os handle */ bool _piomode; /* true if pio mode */ struct wlc_info *wlc; -- cgit v1.2.3 From 5508d82488694e3d427345d624687a3fa9fb9a88 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 2 Mar 2011 21:18:38 +0100 Subject: staging: brcm80211: remove struct osl_info usage from phy sources Getting rid of osl concept taking small steps. This commit removes it from source files in brcm80211/brcmsmac/phy directory. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- .../staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c | 22 ---------------------- .../staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h | 1 - .../staging/brcm80211/brcmsmac/phy/wlc_phy_int.h | 1 - drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 1 - 4 files changed, 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c index 35b43677d213..bb49a0cd0b08 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c @@ -275,13 +275,9 @@ u16 read_radio_reg(phy_info_t *pi, u16 addr) void write_radio_reg(phy_info_t *pi, u16 addr, u16 val) { - struct osl_info *osh; - if (NORADIO_ENAB(pi->pubpi)) return; - osh = pi->sh->osh; - if ((D11REV_GE(pi->sh->corerev, 24)) || (D11REV_IS(pi->sh->corerev, 22) && (pi->pubpi.phy_type != PHY_TYPE_SSN))) { @@ -408,10 +404,8 @@ static bool wlc_phy_war41476(phy_info_t *pi) u16 read_phy_reg(phy_info_t *pi, u16 addr) { - struct osl_info *osh; d11regs_t *regs; - osh = pi->sh->osh; regs = pi->regs; W_REG(®s->phyregaddr, addr); @@ -429,10 +423,8 @@ u16 read_phy_reg(phy_info_t *pi, u16 addr) void write_phy_reg(phy_info_t *pi, u16 addr, u16 val) { - struct osl_info *osh; d11regs_t *regs; - osh = pi->sh->osh; regs = pi->regs; #ifdef __mips__ @@ -455,10 +447,8 @@ void write_phy_reg(phy_info_t *pi, u16 addr, u16 val) void and_phy_reg(phy_info_t *pi, u16 addr, u16 val) { - struct osl_info *osh; d11regs_t *regs; - osh = pi->sh->osh; regs = pi->regs; W_REG(®s->phyregaddr, addr); @@ -476,10 +466,8 @@ void and_phy_reg(phy_info_t *pi, u16 addr, u16 val) void or_phy_reg(phy_info_t *pi, u16 addr, u16 val) { - struct osl_info *osh; d11regs_t *regs; - osh = pi->sh->osh; regs = pi->regs; W_REG(®s->phyregaddr, addr); @@ -497,10 +485,8 @@ void or_phy_reg(phy_info_t *pi, u16 addr, u16 val) void mod_phy_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val) { - struct osl_info *osh; d11regs_t *regs; - osh = pi->sh->osh; regs = pi->regs; W_REG(®s->phyregaddr, addr); @@ -563,7 +549,6 @@ shared_phy_t *wlc_phy_shared_attach(shared_phy_params_t *shp) return NULL; } - sh->osh = shp->osh; sh->sih = shp->sih; sh->physhim = shp->physhim; sh->unit = shp->unit; @@ -594,11 +579,7 @@ shared_phy_t *wlc_phy_shared_attach(shared_phy_params_t *shp) void wlc_phy_shared_detach(shared_phy_t *phy_sh) { - struct osl_info *osh; - if (phy_sh) { - osh = phy_sh->osh; - if (phy_sh->phy_head) { ASSERT(!phy_sh->phy_head); } @@ -612,9 +593,6 @@ wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, char *vars u32 sflags = 0; uint phyversion; int i; - struct osl_info *osh; - - osh = sh->osh; if (D11REV_IS(sh->corerev, 4)) sflags = SISF_2G_PHY | SISF_5G_PHY; diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h index 514e15e00283..bf962d5b339a 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h @@ -125,7 +125,6 @@ struct phy_pub; typedef struct phy_pub wlc_phy_t; typedef struct shared_phy_params { - void *osh; si_t *sih; void *physhim; uint unit; diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h index 0530b1ddb3ca..6e12a95c7360 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h @@ -527,7 +527,6 @@ typedef struct { struct shared_phy { struct phy_info *phy_head; uint unit; - struct osl_info *osh; si_t *sih; void *physhim; uint corerev; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index 6ec0ab799802..ca12d2602799 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -805,7 +805,6 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, } /* pass all the parameters to wlc_phy_shared_attach in one struct */ - sha_params.osh = wlc->osh; sha_params.sih = wlc_hw->sih; sha_params.physhim = wlc_hw->physhim; sha_params.unit = unit; -- cgit v1.2.3 From 228a00f8dcd34fdead86c8b4d31552e69ab9b9e4 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 2 Mar 2011 21:18:39 +0100 Subject: staging: brcm80211: remove osl_info usage in wlc_main and wl_mac80211 Getting rid of osl concept taking small steps. This commit removes it from wlc_main.c and wl_mac80211.c. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 5 +-- drivers/staging/brcm80211/brcmsmac/wlc_main.c | 50 ++++++------------------ 2 files changed, 14 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 6ce5172557f6..2b2d1c21dffc 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -1350,7 +1350,6 @@ module_exit(wl_module_exit); static void wl_free(struct wl_info *wl) { struct wl_timer *t, *next; - struct osl_info *osh; ASSERT(wl); /* free ucode data */ @@ -1389,8 +1388,6 @@ static void wl_free(struct wl_info *wl) kfree(t); } - osh = wl->osh; - /* * unregister_netdev() calls get_stats() which may read chip registers * so we cannot unmap the chip registers until after calling unregister_netdev() . @@ -1402,7 +1399,7 @@ static void wl_free(struct wl_info *wl) wl->regsva = NULL; - osl_detach(osh); + osl_detach(wl->osh); } /* diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c index eae6bd6f3bfc..3a53d5b76e9d 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c @@ -267,9 +267,8 @@ static int wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc); /* send and receive */ -static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc, - struct osl_info *osh); -static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh, +static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc); +static void wlc_txq_free(struct wlc_info *wlc, struct wlc_txq_info *qi); static void wlc_txflowcontrol_signal(struct wlc_info *wlc, struct wlc_txq_info *qi, @@ -282,7 +281,7 @@ static void wlc_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp); static void wlc_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp); static u16 wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type, uint next_frag_len); -static void wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, +static void wlc_recvctl(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p); static uint wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type, uint dur); @@ -327,12 +326,9 @@ void wlc_get_rcmta(struct wlc_info *wlc, int idx, u8 *addr) { d11regs_t *regs = wlc->regs; u32 v32; - struct osl_info *osh; WL_TRACE("wl%d: %s\n", WLCWLUNIT(wlc), __func__); - osh = wlc->osh; - W_REG(®s->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2))); (void)R_REG(®s->objaddr); v32 = R_REG(®s->objdata); @@ -1935,7 +1931,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, */ /* allocate our initial queue */ - qi = wlc_txq_alloc(wlc, osh); + qi = wlc_txq_alloc(wlc); if (qi == NULL) { WL_ERROR("wl%d: %s: failed to malloc tx queue\n", unit, __func__); @@ -2189,9 +2185,8 @@ uint wlc_detach(struct wlc_info *wlc) /* Detach from iovar manager */ wlc_module_unregister(wlc->pub, "wlc_iovars", wlc); - while (wlc->tx_queues != NULL) { - wlc_txq_free(wlc, wlc->osh, wlc->tx_queues); - } + while (wlc->tx_queues != NULL) + wlc_txq_free(wlc, wlc->tx_queues); /* * consistency check: wlc_module_register/wlc_module_unregister calls @@ -3081,7 +3076,6 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, uint band; rw_reg_t *r; wlc_bsscfg_t *bsscfg; - struct osl_info *osh; wlc_bss_info_t *current_bss; /* update bsscfg pointer */ @@ -3121,7 +3115,6 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, bcmerror = 0; regs = wlc->regs; - osh = wlc->osh; /* A few commands don't need any arguments; all the others do. */ switch (cmd) { @@ -5729,7 +5722,6 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, struct ieee80211_hdr *h; d11txh_t *txh; u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN]; - struct osl_info *osh; int len, phylen, rts_phylen; u16 frameid, mch, phyctl, xfts, mainrates; u16 seq = 0, mcl = 0, status = 0; @@ -5764,8 +5756,6 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, ASSERT(queue < NFIFO); - osh = wlc->osh; - /* locate 802.11 MAC header */ h = (struct ieee80211_hdr *)(p->data); qos = ieee80211_is_data_qos(h->frame_control); @@ -6574,7 +6564,6 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) d11txh_t *txh; struct scb *scb = NULL; bool free_pdu; - struct osl_info *osh; int tx_rts, tx_frame_count, tx_rts_count; uint totlen, supr_status; bool lastframe; @@ -6601,7 +6590,6 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) return false; } - osh = wlc->osh; queue = txs->frameid & TXFID_QUEUE_MASK; ASSERT(queue < NFIFO); if (queue >= NFIFO) { @@ -6724,7 +6712,7 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) fatal: ASSERT(0); if (p) - pkt_buf_free_skb(osh, p, true); + pkt_buf_free_skb(wlc->osh, p, true); return true; @@ -6961,8 +6949,7 @@ prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, } static void -wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, d11rxhdr_t *rxh, - struct sk_buff *p) +wlc_recvctl(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p) { int len_mpdu; struct ieee80211_rx_status rx_status; @@ -6992,7 +6979,7 @@ wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, d11rxhdr_t *rxh, ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p); wlc->pub->_cnt->ieee_rx++; - osh->pktalloced--; + wlc->osh->pktalloced--; return; } @@ -7022,14 +7009,11 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) { d11rxhdr_t *rxh; struct ieee80211_hdr *h; - struct osl_info *osh; uint len; bool is_amsdu; WL_TRACE("wl%d: wlc_recv\n", wlc->pub->unit); - osh = wlc->osh; - /* frame starts with rxhdr */ rxh = (d11rxhdr_t *) (p->data); @@ -7108,11 +7092,11 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) goto toss; } - wlc_recvctl(wlc, osh, rxh, p); + wlc_recvctl(wlc, rxh, p); return; toss: - pkt_buf_free_skb(osh, p, false); + pkt_buf_free_skb(wlc->osh, p, false); } /* calculate frame duration for Mixed-mode L-SIG spoofing, return @@ -7739,9 +7723,6 @@ void wlc_bss_update_beacon(struct wlc_info *wlc, wlc_bsscfg_t *cfg) u16 bcn[BCN_TMPL_LEN / 2]; u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD; d11regs_t *regs = wlc->regs; - struct osl_info *osh = NULL; - - osh = wlc->osh; /* Check if both templates are in use, if so sched. an interrupt * that will call back into this routine @@ -7861,14 +7842,11 @@ wlc_bss_update_probe_resp(struct wlc_info *wlc, wlc_bsscfg_t *cfg, bool suspend) /* prepares pdu for transmission. returns BCM error codes */ int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) { - struct osl_info *osh; uint fifo; d11txh_t *txh; struct ieee80211_hdr *h; struct scb *scb; - osh = wlc->osh; - ASSERT(pdu); txh = (d11txh_t *) (pdu->data); ASSERT(txh); @@ -8439,8 +8417,7 @@ wlc_txflowcontrol_signal(struct wlc_info *wlc, struct wlc_txq_info *qi, bool on, } } -static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc, - struct osl_info *osh) +static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc) { struct wlc_txq_info *qi, *p; @@ -8469,8 +8446,7 @@ static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc, return qi; } -static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh, - struct wlc_txq_info *qi) +static void wlc_txq_free(struct wlc_info *wlc, struct wlc_txq_info *qi) { struct wlc_txq_info *p; -- cgit v1.2.3 From 9d7326f97ee5abf0e20548a2d3ed94d5a4fddd0c Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 2 Mar 2011 21:18:40 +0100 Subject: staging: brcm80211: move frameid initialization in wlc_d11hdrs_mac80211 Minor esthetical change to do initialization immediately at declaration. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c index 3a53d5b76e9d..9224961f6836 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c @@ -5723,8 +5723,8 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, d11txh_t *txh; u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN]; int len, phylen, rts_phylen; - u16 frameid, mch, phyctl, xfts, mainrates; - u16 seq = 0, mcl = 0, status = 0; + u16 mch, phyctl, xfts, mainrates; + u16 seq = 0, mcl = 0, status = 0, frameid = 0; ratespec_t rspec[2] = { WLC_RATE_1M, WLC_RATE_1M }, rts_rspec[2] = { WLC_RATE_1M, WLC_RATE_1M}; bool use_rts = false; @@ -5752,8 +5752,6 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, u16 mimo_txbw; u8 mimo_preamble_type; - frameid = 0; - ASSERT(queue < NFIFO); /* locate 802.11 MAC header */ -- cgit v1.2.3 From 377c8981b48ba42987ed783753c5226f3346f521 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 2 Mar 2011 21:18:41 +0100 Subject: staging: brcm80211: remove function prototypes from wl_export.h The include file wl_export.h contained several function prototypes (and one macro defintion) that were not used or implemented within the driver. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_export.h | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_export.h b/drivers/staging/brcm80211/brcmsmac/wl_export.h index 03585745c49c..9ff760f4c865 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_export.h +++ b/drivers/staging/brcm80211/brcmsmac/wl_export.h @@ -43,19 +43,4 @@ extern void wl_add_timer(struct wl_info *wl, struct wl_timer *timer, uint ms, int periodic); extern bool wl_del_timer(struct wl_info *wl, struct wl_timer *timer); -extern uint wl_buf_to_pktcopy(struct osl_info *osh, void *p, unsigned char *buf, - int len, uint offset); -extern void *wl_get_pktbuffer(struct osl_info *osh, int len); -extern int wl_set_pktlen(struct osl_info *osh, void *p, int len); - -#define wl_sort_bsslist(a, b) false - -extern int wl_tkip_miccheck(struct wl_info *wl, void *p, int hdr_len, - bool group_key, int id); -extern int wl_tkip_micadd(struct wl_info *wl, void *p, int hdr_len); -extern int wl_tkip_encrypt(struct wl_info *wl, void *p, int hdr_len); -extern int wl_tkip_decrypt(struct wl_info *wl, void *p, int hdr_len, - bool group_key); -extern void wl_tkip_printstats(struct wl_info *wl, bool group_key); -extern int wl_tkip_keyset(struct wl_info *wl, wsec_key_t *key); #endif /* _wl_export_h_ */ -- cgit v1.2.3 From 8da4a3a03430b9be293f6a427197261de330956a Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 2 Mar 2011 21:18:42 +0100 Subject: staging: brcm80211: removed struct osl_info usage from fullmac driver Several occurrences in fullmac using struct osl_info could be removed. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdbus.h | 2 +- drivers/staging/brcm80211/brcmfmac/bcmsdh.c | 6 +-- drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c | 4 +- drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 2 +- drivers/staging/brcm80211/brcmfmac/dhd_bus.h | 2 +- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 2 +- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 54 ++++++++++------------- drivers/staging/brcm80211/include/bcmsdh.h | 2 +- 8 files changed, 33 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h b/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h index b020a301341f..99e075b484fb 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h @@ -47,7 +47,7 @@ typedef void (*sdioh_cb_fn_t) (void *); * cfghdl points to the starting address of pci device mapped memory */ extern sdioh_info_t *sdioh_attach(struct osl_info *osh, void *cfghdl, uint irq); -extern SDIOH_API_RC sdioh_detach(struct osl_info *osh, sdioh_info_t *si); +extern SDIOH_API_RC sdioh_detach(sdioh_info_t *si); extern SDIOH_API_RC sdioh_interrupt_register(sdioh_info_t *si, sdioh_cb_fn_t fn, void *argh); extern SDIOH_API_RC sdioh_interrupt_deregister(sdioh_info_t *si); diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c index 77e65e4297a1..22c8f8dc55ef 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c @@ -71,7 +71,7 @@ bcmsdh_info_t *bcmsdh_attach(struct osl_info *osh, void *cfghdl, bcmsdh->sdioh = sdioh_attach(osh, cfghdl, irq); if (!bcmsdh->sdioh) { - bcmsdh_detach(osh, bcmsdh); + bcmsdh_detach(bcmsdh); return NULL; } @@ -85,13 +85,13 @@ bcmsdh_info_t *bcmsdh_attach(struct osl_info *osh, void *cfghdl, return bcmsdh; } -int bcmsdh_detach(struct osl_info *osh, void *sdh) +int bcmsdh_detach(void *sdh) { bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; if (bcmsdh != NULL) { if (bcmsdh->sdioh) { - sdioh_detach(osh, bcmsdh->sdioh); + sdioh_detach(bcmsdh->sdioh); bcmsdh->sdioh = NULL; } kfree(bcmsdh); diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c index deb5f46542ae..1d2d79080eb3 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c @@ -232,7 +232,7 @@ int bcmsdh_probe(struct device *dev) err: if (sdhc) { if (sdhc->sdh) - bcmsdh_detach(sdhc->osh, sdhc->sdh); + bcmsdh_detach(sdhc->sdh); kfree(sdhc); } if (osh) @@ -250,7 +250,7 @@ int bcmsdh_remove(struct device *dev) sdhc = sdhcinfo; drvinfo.detach(sdhc->ch); - bcmsdh_detach(sdhc->osh, sdhc->sdh); + bcmsdh_detach(sdhc->sdh); /* find the SDIO Host Controller state for this pdev and take it out from the list */ for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) { diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 4409443c69de..9b5075e5bfb1 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -174,7 +174,7 @@ extern sdioh_info_t *sdioh_attach(struct osl_info *osh, void *bar0, uint irq) return sd; } -extern SDIOH_API_RC sdioh_detach(struct osl_info *osh, sdioh_info_t *sd) +extern SDIOH_API_RC sdioh_detach(sdioh_info_t *sd) { sd_trace(("%s\n", __func__)); diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_bus.h b/drivers/staging/brcm80211/brcmfmac/dhd_bus.h index cd0d5400bf07..065f1aeb6ca9 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd_bus.h @@ -27,7 +27,7 @@ extern void dhd_bus_unregister(void); /* Download firmware image and nvram image */ extern bool dhd_bus_download_firmware(struct dhd_bus *bus, - struct osl_info *osh, char *fw_path, char *nv_path); + char *fw_path, char *nv_path); /* Stop bus module: clear pending frames, disable data flow */ extern void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex); diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 3efc17a0a4e0..50415101e4c7 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -2125,7 +2125,7 @@ int dhd_bus_start(dhd_pub_t *dhdp) /* try to download image and nvram to the dongle */ if (dhd->pub.busstate == DHD_BUS_DOWN) { - if (!(dhd_bus_download_firmware(dhd->pub.bus, dhd->pub.osh, + if (!(dhd_bus_download_firmware(dhd->pub.bus, fw_path, nv_path))) { DHD_ERROR(("%s: dhdsdio_probe_download failed. " "firmware = %s nvram = %s\n", diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 32551a24b4be..e85d2d216734 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -437,15 +437,14 @@ static int dhdsdio_mem_dump(dhd_bus_t *bus); static int dhdsdio_download_state(dhd_bus_t *bus, bool enter); static void dhdsdio_release(dhd_bus_t *bus, struct osl_info *osh); -static void dhdsdio_release_malloc(dhd_bus_t *bus, struct osl_info *osh); +static void dhdsdio_release_malloc(dhd_bus_t *bus); static void dhdsdio_disconnect(void *ptr); static bool dhdsdio_chipmatch(u16 chipid); -static bool dhdsdio_probe_attach(dhd_bus_t *bus, struct osl_info *osh, - void *sdh, void *regsva, u16 devid); -static bool dhdsdio_probe_malloc(dhd_bus_t *bus, struct osl_info *osh, - void *sdh); -static bool dhdsdio_probe_init(dhd_bus_t *bus, struct osl_info *osh, void *sdh); -static void dhdsdio_release_dongle(dhd_bus_t *bus, struct osl_info * osh); +static bool dhdsdio_probe_attach(dhd_bus_t *bus, void *sdh, + void *regsva, u16 devid); +static bool dhdsdio_probe_malloc(dhd_bus_t *bus, void *sdh); +static bool dhdsdio_probe_init(dhd_bus_t *bus, void *sdh); +static void dhdsdio_release_dongle(dhd_bus_t *bus); static uint process_nvram_vars(char *varbuf, uint len); @@ -459,8 +458,7 @@ static int dhd_bcmsdh_send_buf(dhd_bus_t *bus, u32 addr, uint fn, struct sk_buff *pkt, bcmsdh_cmplt_fn_t complete, void *handle); -static bool dhdsdio_download_firmware(struct dhd_bus *bus, struct osl_info *osh, - void *sdh); +static bool dhdsdio_download_firmware(struct dhd_bus *bus, void *sdh); static int _dhdsdio_download_firmware(struct dhd_bus *bus); static int dhdsdio_download_code_file(struct dhd_bus *bus, char *image_path); @@ -5172,7 +5170,7 @@ static void *dhdsdio_probe(u16 venid, u16 devid, u16 bus_no, else use locally malloced rxbuf */ /* attempt to attach to the dongle */ - if (!(dhdsdio_probe_attach(bus, osh, sdh, regsva, devid))) { + if (!(dhdsdio_probe_attach(bus, sdh, regsva, devid))) { DHD_ERROR(("%s: dhdsdio_probe_attach failed\n", __func__)); goto fail; } @@ -5185,12 +5183,12 @@ static void *dhdsdio_probe(u16 venid, u16 devid, u16 bus_no, } /* Allocate buffers */ - if (!(dhdsdio_probe_malloc(bus, osh, sdh))) { + if (!(dhdsdio_probe_malloc(bus, sdh))) { DHD_ERROR(("%s: dhdsdio_probe_malloc failed\n", __func__)); goto fail; } - if (!(dhdsdio_probe_init(bus, osh, sdh))) { + if (!(dhdsdio_probe_init(bus, sdh))) { DHD_ERROR(("%s: dhdsdio_probe_init failed\n", __func__)); goto fail; } @@ -5231,8 +5229,7 @@ fail: } static bool -dhdsdio_probe_attach(struct dhd_bus *bus, struct osl_info *osh, void *sdh, - void *regsva, u16 devid) +dhdsdio_probe_attach(struct dhd_bus *bus, void *sdh, void *regsva, u16 devid) { u8 clkctl = 0; int err = 0; @@ -5389,8 +5386,7 @@ fail: return false; } -static bool dhdsdio_probe_malloc(dhd_bus_t *bus, struct osl_info *osh, - void *sdh) +static bool dhdsdio_probe_malloc(dhd_bus_t *bus, void *sdh) { DHD_TRACE(("%s: Enter\n", __func__)); @@ -5431,7 +5427,7 @@ fail: return false; } -static bool dhdsdio_probe_init(dhd_bus_t *bus, struct osl_info *osh, void *sdh) +static bool dhdsdio_probe_init(dhd_bus_t *bus, void *sdh) { s32 fnum; @@ -5508,20 +5504,19 @@ static bool dhdsdio_probe_init(dhd_bus_t *bus, struct osl_info *osh, void *sdh) } bool -dhd_bus_download_firmware(struct dhd_bus *bus, struct osl_info *osh, - char *fw_path, char *nv_path) +dhd_bus_download_firmware(struct dhd_bus *bus, char *fw_path, char *nv_path) { bool ret; bus->fw_path = fw_path; bus->nv_path = nv_path; - ret = dhdsdio_download_firmware(bus, osh, bus->sdh); + ret = dhdsdio_download_firmware(bus, bus->sdh); return ret; } static bool -dhdsdio_download_firmware(struct dhd_bus *bus, struct osl_info *osh, void *sdh) +dhdsdio_download_firmware(struct dhd_bus *bus, void *sdh) { bool ret; @@ -5541,21 +5536,19 @@ static void dhdsdio_release(dhd_bus_t *bus, struct osl_info *osh) DHD_TRACE(("%s: Enter\n", __func__)); if (bus) { - ASSERT(osh); - /* De-register interrupt handler */ bcmsdh_intr_disable(bus->sdh); bcmsdh_intr_dereg(bus->sdh); if (bus->dhd) { - dhdsdio_release_dongle(bus, osh); + dhdsdio_release_dongle(bus); dhd_detach(bus->dhd); bus->dhd = NULL; } - dhdsdio_release_malloc(bus, osh); + dhdsdio_release_malloc(bus); kfree(bus); } @@ -5566,7 +5559,7 @@ static void dhdsdio_release(dhd_bus_t *bus, struct osl_info *osh) DHD_TRACE(("%s: Disconnected\n", __func__)); } -static void dhdsdio_release_malloc(dhd_bus_t *bus, struct osl_info *osh) +static void dhdsdio_release_malloc(dhd_bus_t *bus) { DHD_TRACE(("%s: Enter\n", __func__)); @@ -5585,7 +5578,7 @@ static void dhdsdio_release_malloc(dhd_bus_t *bus, struct osl_info *osh) } } -static void dhdsdio_release_dongle(dhd_bus_t *bus, struct osl_info *osh) +static void dhdsdio_release_dongle(dhd_bus_t *bus) { DHD_TRACE(("%s: Enter\n", __func__)); @@ -6057,7 +6050,7 @@ int dhd_bus_devreset(dhd_pub_t *dhdp, u8 flag) /* Clean tx/rx buffer pointers, detach from the dongle */ - dhdsdio_release_dongle(bus, bus->dhd->osh); + dhdsdio_release_dongle(bus); bus->dhd->dongle_reset = true; bus->dhd->up = false; @@ -6077,14 +6070,13 @@ int dhd_bus_devreset(dhd_pub_t *dhdp, u8 flag) bcmsdh_reset(bus->sdh); /* Attempt to re-attach & download */ - if (dhdsdio_probe_attach(bus, bus->dhd->osh, bus->sdh, + if (dhdsdio_probe_attach(bus, bus->sdh, (u32 *) SI_ENUM_BASE, bus->cl_devid)) { /* Attempt to download binary to the dongle */ if (dhdsdio_probe_init - (bus, bus->dhd->osh, bus->sdh) + (bus, bus->sdh) && dhdsdio_download_firmware(bus, - bus->dhd->osh, bus->sdh)) { /* Re-init bus, enable F2 transfer */ diff --git a/drivers/staging/brcm80211/include/bcmsdh.h b/drivers/staging/brcm80211/include/bcmsdh.h index 96c629267f14..d27d1cbb7f79 100644 --- a/drivers/staging/brcm80211/include/bcmsdh.h +++ b/drivers/staging/brcm80211/include/bcmsdh.h @@ -53,7 +53,7 @@ extern bcmsdh_info_t *bcmsdh_attach(struct osl_info *osh, void *cfghdl, void **regsva, uint irq); /* Detach - freeup resources allocated in attach */ -extern int bcmsdh_detach(struct osl_info *osh, void *sdh); +extern int bcmsdh_detach(void *sdh); /* Query if SD device interrupts are enabled */ extern bool bcmsdh_intr_query(void *sdh); -- cgit v1.2.3 From 4fe9042fe05a828293f693405f14b3f6a7898866 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 2 Mar 2011 21:18:43 +0100 Subject: staging: brcm80211: remove unused attributes from struct osl_info Getting rid of the whole osl concept soon this removes most fields in struct osl_info. Turned out hnddma.c was still using it so this was fixed and now it gets pointer to bus device from si_info which it only needs in the attach function for this purpose so reference to it does not need to be kept. Two unused functions referencing the removed fields in linux_osl.c also were removed. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/osl.h | 3 --- drivers/staging/brcm80211/include/siutils.h | 2 +- drivers/staging/brcm80211/util/hnddma.c | 4 +-- drivers/staging/brcm80211/util/linux_osl.c | 38 ----------------------------- 4 files changed, 2 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index 51619629b584..02faf30372a3 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -20,10 +20,7 @@ /* osl handle type forward declaration */ struct osl_info { uint pktalloced; /* Number of allocated packet buffers */ - bool mmbus; /* Bus supports memory-mapped registers */ uint magic; - void *pdev; - uint bustype; }; typedef struct osl_dmainfo osldma_t; diff --git a/drivers/staging/brcm80211/include/siutils.h b/drivers/staging/brcm80211/include/siutils.h index f84057ed6b71..a95e9255b47c 100644 --- a/drivers/staging/brcm80211/include/siutils.h +++ b/drivers/staging/brcm80211/include/siutils.h @@ -249,7 +249,7 @@ typedef struct si_info { u32 oob_router; /* oob router registers for axi */ } si_info_t; -#define SI_INFO(sih) (si_info_t *)sih +#define SI_INFO(sih) ((si_info_t *)(sih)) #define GOODCOREADDR(x, b) (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \ IS_ALIGNED((x), SI_CORE_SIZE)) diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index b7bc84d62c38..01d4b274520b 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -82,7 +82,6 @@ typedef struct dma_info { struct osl_info *osh; /* os handle */ void *pbus; /* bus handle */ - si_t *sih; /* sb handle */ bool dma64; /* this dma engine is operating in 64-bit mode */ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ @@ -338,8 +337,7 @@ struct hnddma_pub *dma_attach(struct osl_info *osh, char *name, si_t *sih, di->name[MAXNAMEL - 1] = '\0'; di->osh = osh; - di->sih = sih; - di->pbus = osh->pdev; + di->pbus = ((struct si_info *)sih)->pbus; /* save tunables */ di->ntxd = (u16) ntxd; diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index 99e449603a9f..70c35e9d31a8 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -43,29 +43,7 @@ struct osl_info *osl_attach(void *pdev, uint bustype) ASSERT(osh); memset(osh, 0, sizeof(struct osl_info)); - osh->magic = OS_HANDLE_MAGIC; - osh->pdev = pdev; - osh->bustype = bustype; - - switch (bustype) { - case PCI_BUS: - case SI_BUS: - case PCMCIA_BUS: - osh->mmbus = true; - break; - case JTAG_BUS: - case SDIO_BUS: - case USB_BUS: - case SPI_BUS: - case RPC_BUS: - osh->mmbus = false; - break; - default: - ASSERT(false); - break; - } - return osh; } @@ -78,22 +56,6 @@ void osl_detach(struct osl_info *osh) kfree(osh); } -/* return bus # for the pci device pointed by osh->pdev */ -uint osl_pci_bus(struct osl_info *osh) -{ - ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); - - return ((struct pci_dev *)osh->pdev)->bus->number; -} - -/* return slot # for the pci device pointed by osh->pdev */ -uint osl_pci_slot(struct osl_info *osh) -{ - ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); - - return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn); -} - #if defined(BCMDBG_ASSERT) void osl_assert(char *exp, char *file, int line) { -- cgit v1.2.3 From 278d927d660b1652cf9a1425b0ce20a385ea9cff Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 2 Mar 2011 21:18:44 +0100 Subject: staging: brcm80211: cleanup declaration in osl.h Several declarations and macro definitions in osl.h are still needed and therefore moved to bcmutils.h or hnddma.h. The osl_assert function is moved to bcmutils.c accordingly. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c | 2 +- drivers/staging/brcm80211/include/bcmutils.h | 132 +++++++++++++++++++- drivers/staging/brcm80211/include/hnddma.h | 5 + drivers/staging/brcm80211/include/osl.h | 142 ---------------------- drivers/staging/brcm80211/util/bcmutils.c | 54 +++++++- drivers/staging/brcm80211/util/linux_osl.c | 51 -------- 6 files changed, 189 insertions(+), 197 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c index 1d2d79080eb3..6292f4f843d7 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c @@ -28,11 +28,11 @@ #include #include #include +#include #if defined(OOB_INTR_ONLY) #include extern void dhdsdio_isr(void *args); -#include #include #include #endif /* defined(OOB_INTR_ONLY) */ diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h index 358bbbf27e01..0aa7c6f32a03 100644 --- a/drivers/staging/brcm80211/include/bcmutils.h +++ b/drivers/staging/brcm80211/include/bcmutils.h @@ -359,7 +359,137 @@ extern struct sk_buff *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); #define REG_MAP(pa, size) (void *)(0) #endif -/* Register operations */ +extern u32 g_assert_type; + +#if defined(BCMDBG_ASSERT) +#define ASSERT(exp) \ + do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0) +extern void osl_assert(char *exp, char *file, int line); +#else +#define ASSERT(exp) do {} while (0) +#endif /* defined(BCMDBG_ASSERT) */ + +/* register access macros */ +#if defined(BCMSDIO) +#ifdef BRCM_FULLMAC +#include +#endif +#define OSL_WRITE_REG(r, v) \ + (bcmsdh_reg_write(NULL, (unsigned long)(r), sizeof(*(r)), (v))) +#define OSL_READ_REG(r) \ + (bcmsdh_reg_read(NULL, (unsigned long)(r), sizeof(*(r)))) +#endif + +#if defined(BCMSDIO) +#define SELECT_BUS_WRITE(mmap_op, bus_op) bus_op +#define SELECT_BUS_READ(mmap_op, bus_op) bus_op +#else +#define SELECT_BUS_WRITE(mmap_op, bus_op) mmap_op +#define SELECT_BUS_READ(mmap_op, bus_op) mmap_op +#endif + +/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ +#define PKTBUFSZ 2048 + +#define OSL_SYSUPTIME() ((u32)jiffies * (1000 / HZ)) +#ifdef BRCM_FULLMAC +#include /* for vsn/printf's */ +#include /* for mem*, str* */ +#endif +/* bcopy's: Linux kernel doesn't provide these (anymore) */ +#define bcopy(src, dst, len) memcpy((dst), (src), (len)) + +/* register access macros */ +#ifndef IL_BIGENDIAN +#ifndef __mips__ +#define R_REG(r) (\ + SELECT_BUS_READ(sizeof(*(r)) == sizeof(u8) ? \ + readb((volatile u8*)(r)) : \ + sizeof(*(r)) == sizeof(u16) ? readw((volatile u16*)(r)) : \ + readl((volatile u32*)(r)), OSL_READ_REG(r)) \ +) +#else /* __mips__ */ +#define R_REG(r) (\ + SELECT_BUS_READ( \ + ({ \ + __typeof(*(r)) __osl_v; \ + __asm__ __volatile__("sync"); \ + switch (sizeof(*(r))) { \ + case sizeof(u8): \ + __osl_v = readb((volatile u8*)(r)); \ + break; \ + case sizeof(u16): \ + __osl_v = readw((volatile u16*)(r)); \ + break; \ + case sizeof(u32): \ + __osl_v = \ + readl((volatile u32*)(r)); \ + break; \ + } \ + __asm__ __volatile__("sync"); \ + __osl_v; \ + }), \ + ({ \ + __typeof(*(r)) __osl_v; \ + __asm__ __volatile__("sync"); \ + __osl_v = OSL_READ_REG(r); \ + __asm__ __volatile__("sync"); \ + __osl_v; \ + })) \ +) +#endif /* __mips__ */ + +#define W_REG(r, v) do { \ + SELECT_BUS_WRITE( \ + switch (sizeof(*(r))) { \ + case sizeof(u8): \ + writeb((u8)(v), (volatile u8*)(r)); break; \ + case sizeof(u16): \ + writew((u16)(v), (volatile u16*)(r)); break; \ + case sizeof(u32): \ + writel((u32)(v), (volatile u32*)(r)); break; \ + }, \ + (OSL_WRITE_REG(r, v))); \ + } while (0) +#else /* IL_BIGENDIAN */ +#define R_REG(r) (\ + SELECT_BUS_READ( \ + ({ \ + __typeof(*(r)) __osl_v; \ + switch (sizeof(*(r))) { \ + case sizeof(u8): \ + __osl_v = \ + readb((volatile u8*)((r)^3)); \ + break; \ + case sizeof(u16): \ + __osl_v = \ + readw((volatile u16*)((r)^2)); \ + break; \ + case sizeof(u32): \ + __osl_v = readl((volatile u32*)(r)); \ + break; \ + } \ + __osl_v; \ + }), \ + OSL_READ_REG(r)) \ +) +#define W_REG(r, v) do { \ + SELECT_BUS_WRITE( \ + switch (sizeof(*(r))) { \ + case sizeof(u8): \ + writeb((u8)(v), \ + (volatile u8*)((r)^3)); break; \ + case sizeof(u16): \ + writew((u16)(v), \ + (volatile u16*)((r)^2)); break; \ + case sizeof(u32): \ + writel((u32)(v), \ + (volatile u32*)(r)); break; \ + }, \ + (OSL_WRITE_REG(r, v))); \ + } while (0) +#endif /* IL_BIGENDIAN */ + #define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) #define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) diff --git a/drivers/staging/brcm80211/include/hnddma.h b/drivers/staging/brcm80211/include/hnddma.h index 17fa166f3968..363898359d08 100644 --- a/drivers/staging/brcm80211/include/hnddma.h +++ b/drivers/staging/brcm80211/include/hnddma.h @@ -22,6 +22,11 @@ struct hnddma_pub; #endif /* _hnddma_pub_ */ +/* map/unmap direction */ +#define DMA_TX 1 /* TX direction for DMA */ +#define DMA_RX 2 /* RX direction for DMA */ +#define BUS_SWAP32(v) (v) + /* range param for dma_getnexttxp() and dma_txreclaim */ typedef enum txd_range { HNDDMA_RANGE_ALL = 1, diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index 02faf30372a3..e48c7ba9af12 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -29,146 +29,4 @@ typedef struct osl_dmainfo osldma_t; extern struct osl_info *osl_attach(void *pdev, uint bustype); extern void osl_detach(struct osl_info *osh); -extern u32 g_assert_type; - -#if defined(BCMDBG_ASSERT) -#define ASSERT(exp) \ - do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0) -extern void osl_assert(char *exp, char *file, int line); -#else -#define ASSERT(exp) do {} while (0) -#endif /* defined(BCMDBG_ASSERT) */ - -/* PCI device bus # and slot # */ -#define OSL_PCI_BUS(osh) osl_pci_bus(osh) -#define OSL_PCI_SLOT(osh) osl_pci_slot(osh) -extern uint osl_pci_bus(struct osl_info *osh); -extern uint osl_pci_slot(struct osl_info *osh); - -#define BUS_SWAP32(v) (v) - -/* map/unmap direction */ -#define DMA_TX 1 /* TX direction for DMA */ -#define DMA_RX 2 /* RX direction for DMA */ - -/* register access macros */ -#if defined(BCMSDIO) -#ifdef BRCM_FULLMAC -#include -#endif -#define OSL_WRITE_REG(r, v) \ - (bcmsdh_reg_write(NULL, (unsigned long)(r), sizeof(*(r)), (v))) -#define OSL_READ_REG(r) \ - (bcmsdh_reg_read(NULL, (unsigned long)(r), sizeof(*(r)))) -#endif - -#if defined(BCMSDIO) -#define SELECT_BUS_WRITE(mmap_op, bus_op) bus_op -#define SELECT_BUS_READ(mmap_op, bus_op) bus_op -#else -#define SELECT_BUS_WRITE(mmap_op, bus_op) mmap_op -#define SELECT_BUS_READ(mmap_op, bus_op) mmap_op -#endif - -/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ -#define PKTBUFSZ 2048 - -#define OSL_SYSUPTIME() ((u32)jiffies * (1000 / HZ)) -#ifdef BRCM_FULLMAC -#include /* for vsn/printf's */ -#include /* for mem*, str* */ -#endif - -/* register access macros */ -#ifndef IL_BIGENDIAN -#ifndef __mips__ -#define R_REG(r) (\ - SELECT_BUS_READ(sizeof(*(r)) == sizeof(u8) ? \ - readb((volatile u8*)(r)) : \ - sizeof(*(r)) == sizeof(u16) ? readw((volatile u16*)(r)) : \ - readl((volatile u32*)(r)), OSL_READ_REG(r)) \ -) -#else /* __mips__ */ -#define R_REG(r) (\ - SELECT_BUS_READ( \ - ({ \ - __typeof(*(r)) __osl_v; \ - __asm__ __volatile__("sync"); \ - switch (sizeof(*(r))) { \ - case sizeof(u8): \ - __osl_v = readb((volatile u8*)(r)); \ - break; \ - case sizeof(u16): \ - __osl_v = readw((volatile u16*)(r)); \ - break; \ - case sizeof(u32): \ - __osl_v = \ - readl((volatile u32*)(r)); \ - break; \ - } \ - __asm__ __volatile__("sync"); \ - __osl_v; \ - }), \ - ({ \ - __typeof(*(r)) __osl_v; \ - __asm__ __volatile__("sync"); \ - __osl_v = OSL_READ_REG(r); \ - __asm__ __volatile__("sync"); \ - __osl_v; \ - })) \ -) -#endif /* __mips__ */ - -#define W_REG(r, v) do { \ - SELECT_BUS_WRITE( \ - switch (sizeof(*(r))) { \ - case sizeof(u8): \ - writeb((u8)(v), (volatile u8*)(r)); break; \ - case sizeof(u16): \ - writew((u16)(v), (volatile u16*)(r)); break; \ - case sizeof(u32): \ - writel((u32)(v), (volatile u32*)(r)); break; \ - }, \ - (OSL_WRITE_REG(r, v))); \ - } while (0) -#else /* IL_BIGENDIAN */ -#define R_REG(r) (\ - SELECT_BUS_READ( \ - ({ \ - __typeof(*(r)) __osl_v; \ - switch (sizeof(*(r))) { \ - case sizeof(u8): \ - __osl_v = \ - readb((volatile u8*)((r)^3)); \ - break; \ - case sizeof(u16): \ - __osl_v = \ - readw((volatile u16*)((r)^2)); \ - break; \ - case sizeof(u32): \ - __osl_v = readl((volatile u32*)(r)); \ - break; \ - } \ - __osl_v; \ - }), \ - OSL_READ_REG(r)) \ -) -#define W_REG(r, v) do { \ - SELECT_BUS_WRITE( \ - switch (sizeof(*(r))) { \ - case sizeof(u8): \ - writeb((u8)(v), \ - (volatile u8*)((r)^3)); break; \ - case sizeof(u16): \ - writew((u16)(v), \ - (volatile u16*)((r)^2)); break; \ - case sizeof(u32): \ - writel((u32)(v), \ - (volatile u32*)(r)); break; \ - }, \ - (OSL_WRITE_REG(r, v))); \ - } while (0) -#endif /* IL_BIGENDIAN */ - - #endif /* _osl_h_ */ diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index e31151b9dbeb..d066ed7d373f 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -17,11 +17,12 @@ #include #include #include -#include -#include #include #include #include +#include +#include +#include #include #include #include @@ -29,6 +30,9 @@ #include #include +/* Global ASSERT type flag */ +u32 g_assert_type; + struct sk_buff *BCMFASTPATH pkt_buf_get_skb(struct osl_info *osh, uint len) { struct sk_buff *skb; @@ -1091,3 +1095,49 @@ int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...) return r; } +#if defined(BCMDBG_ASSERT) +void osl_assert(char *exp, char *file, int line) +{ + char tempbuf[256]; + char *basename; + + basename = strrchr(file, '/'); + /* skip the '/' */ + if (basename) + basename++; + + if (!basename) + basename = file; + + snprintf(tempbuf, 256, + "assertion \"%s\" failed: file \"%s\", line %d\n", exp, + basename, line); + + /* + * Print assert message and give it time to + * be written to /var/log/messages + */ + if (!in_interrupt()) { + const int delay = 3; + printk(KERN_ERR "%s", tempbuf); + printk(KERN_ERR "panic in %d seconds\n", delay); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(delay * HZ); + } + + switch (g_assert_type) { + case 0: + panic(KERN_ERR "%s", tempbuf); + break; + case 1: + printk(KERN_ERR "%s", tempbuf); + BUG(); + break; + case 2: + printk(KERN_ERR "%s", tempbuf); + break; + default: + break; + } +} +#endif /* defined(BCMDBG_ASSERT) */ diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index 70c35e9d31a8..2f76aaf73570 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -32,9 +32,6 @@ #define OS_HANDLE_MAGIC 0x1234abcd /* Magic # to recognise osh */ #define BCM_MEM_FILENAME_LEN 24 /* Mem. filename length */ -/* Global ASSERT type flag */ -u32 g_assert_type; - struct osl_info *osl_attach(void *pdev, uint bustype) { struct osl_info *osh; @@ -55,51 +52,3 @@ void osl_detach(struct osl_info *osh) ASSERT(osh->magic == OS_HANDLE_MAGIC); kfree(osh); } - -#if defined(BCMDBG_ASSERT) -void osl_assert(char *exp, char *file, int line) -{ - char tempbuf[256]; - char *basename; - - basename = strrchr(file, '/'); - /* skip the '/' */ - if (basename) - basename++; - - if (!basename) - basename = file; - -#ifdef BCMDBG_ASSERT - snprintf(tempbuf, 256, - "assertion \"%s\" failed: file \"%s\", line %d\n", exp, - basename, line); - - /* Print assert message and give it time to be written to /var/log/messages */ - if (!in_interrupt()) { - const int delay = 3; - printk(KERN_ERR "%s", tempbuf); - printk(KERN_ERR "panic in %d seconds\n", delay); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(delay * HZ); - } - - switch (g_assert_type) { - case 0: - panic(KERN_ERR "%s", tempbuf); - break; - case 1: - printk(KERN_ERR "%s", tempbuf); - BUG(); - break; - case 2: - printk(KERN_ERR "%s", tempbuf); - break; - default: - break; - } -#endif /* BCMDBG_ASSERT */ - -} -#endif /* defined(BCMDBG_ASSERT) */ - -- cgit v1.2.3 From 3c4d93d42df252cb35f8f2cdec1671b14c685ca4 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 2 Mar 2011 21:18:45 +0100 Subject: staging: brcm80211: remove of type definition osldma_t The usage of variable of this type is not required so its use has been removed from the driver. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/osl.h | 3 --- drivers/staging/brcm80211/util/hnddma.c | 10 ++++------ 2 files changed, 4 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index e48c7ba9af12..24b114d6ca96 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -23,9 +23,6 @@ struct osl_info { uint magic; }; -typedef struct osl_dmainfo osldma_t; - - extern struct osl_info *osl_attach(void *pdev, uint bustype); extern void osl_detach(struct osl_info *osh); diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 01d4b274520b..e773b9bdc3b8 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -101,7 +101,6 @@ typedef struct dma_info { u16 txin; /* index of next descriptor to reclaim */ u16 txout; /* index of next descriptor to post */ void **txp; /* pointer to parallel array of pointers to packets */ - osldma_t *tx_dmah; /* DMA TX descriptor ring handle */ hnddma_seg_map_t *txp_dmah; /* DMA MAP meta-data handle */ dmaaddr_t txdpa; /* Aligned physical address of descriptor ring */ dmaaddr_t txdpaorig; /* Original physical address of descriptor ring */ @@ -116,7 +115,6 @@ typedef struct dma_info { u16 rxin; /* index of next descriptor to reclaim */ u16 rxout; /* index of next descriptor to post */ void **rxp; /* pointer to parallel array of pointers to packets */ - osldma_t *rx_dmah; /* DMA RX descriptor ring handle */ hnddma_seg_map_t *rxp_dmah; /* DMA MAP meta-data handle */ dmaaddr_t rxdpa; /* Aligned physical address of descriptor ring */ dmaaddr_t rxdpaorig; /* Original physical address of descriptor ring */ @@ -203,7 +201,7 @@ static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags); static u8 dma_align_sizetobits(uint size); static void *dma_ringalloc(dma_info_t *di, u32 boundary, uint size, u16 *alignbits, uint *alloced, - dmaaddr_t *descpa, osldma_t **dmah); + dmaaddr_t *descpa); /* Prototypes for 64-bit routines */ static bool dma64_alloc(dma_info_t *di, uint direction); @@ -1088,7 +1086,7 @@ u8 dma_align_sizetobits(uint size) */ static void *dma_ringalloc(dma_info_t *di, u32 boundary, uint size, u16 *alignbits, uint *alloced, - dmaaddr_t *descpa, osldma_t **dmah) + dmaaddr_t *descpa) { void *va; u32 desc_strtaddr; @@ -1229,7 +1227,7 @@ static bool dma64_alloc(dma_info_t *di, uint direction) if (direction == DMA_TX) { va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, - &alloced, &di->txdpaorig, &di->tx_dmah); + &alloced, &di->txdpaorig); if (va == NULL) { DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name)); return false; @@ -1247,7 +1245,7 @@ static bool dma64_alloc(dma_info_t *di, uint direction) ASSERT(IS_ALIGNED((unsigned long)di->txd64, align)); } else { va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, - &alloced, &di->rxdpaorig, &di->rx_dmah); + &alloced, &di->rxdpaorig); if (va == NULL) { DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name)); return false; -- cgit v1.2.3 From a30825a3c121a4bb4dd84a9522c875fb27172d9d Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 2 Mar 2011 21:18:46 +0100 Subject: staging: brcm80211: remove counting of allocated sk_buff packets The function pkt_buf_get_skb and pkt_buf_free_skb were using struct osl_info field pktalloced to maintain counter of buffers in use in the driver. It was decided to remove this facility. The prototypes of these functions have been modified and the calling code adapted. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 8 ++-- drivers/staging/brcm80211/brcmfmac/dhd_common.c | 2 +- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 10 ----- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 47 +++++++++++------------ drivers/staging/brcm80211/brcmsmac/wlc_main.c | 20 ++++------ drivers/staging/brcm80211/include/bcmutils.h | 5 +-- drivers/staging/brcm80211/util/bcmutils.c | 12 ++---- drivers/staging/brcm80211/util/hnddma.c | 10 ++--- 8 files changed, 46 insertions(+), 68 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 9b5075e5bfb1..ef75219968fc 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -1038,7 +1038,7 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, if (pkt == NULL) { sd_data(("%s: Creating new %s Packet, len=%d\n", __func__, write ? "TX" : "RX", buflen_u)); - mypkt = pkt_buf_get_skb(sd->osh, buflen_u); + mypkt = pkt_buf_get_skb(buflen_u); if (!mypkt) { sd_err(("%s: pkt_buf_get_skb failed: len %d\n", __func__, buflen_u)); @@ -1056,7 +1056,7 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, if (!write) memcpy(buffer, mypkt->data, buflen_u); - pkt_buf_free_skb(sd->osh, mypkt, write ? true : false); + pkt_buf_free_skb(mypkt); } else if (((u32) (pkt->data) & DMA_ALIGN_MASK) != 0) { /* Case 2: We have a packet, but it is unaligned. */ @@ -1065,7 +1065,7 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, sd_data(("%s: Creating aligned %s Packet, len=%d\n", __func__, write ? "TX" : "RX", pkt->len)); - mypkt = pkt_buf_get_skb(sd->osh, pkt->len); + mypkt = pkt_buf_get_skb(pkt->len); if (!mypkt) { sd_err(("%s: pkt_buf_get_skb failed: len %d\n", __func__, pkt->len)); @@ -1083,7 +1083,7 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, if (!write) memcpy(pkt->data, mypkt->data, mypkt->len); - pkt_buf_free_skb(sd->osh, mypkt, write ? true : false); + pkt_buf_free_skb(mypkt); } else { /* case 3: We have a packet and it is aligned. */ sd_data(("%s: Aligned %s Packet, direct DMA\n", diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index 2d4a4b3bafeb..a80a5c3170fd 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -347,7 +347,7 @@ bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, struct sk_buff *pkt, ASSERT(p); } - pkt_buf_free_skb(dhdp->osh, p, true); + pkt_buf_free_skb(p); } /* Enqueue */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 50415101e4c7..cd14b125d962 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -1049,11 +1049,6 @@ int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf) static inline void * osl_pkt_frmnative(struct osl_info *osh, struct sk_buff *skb) { - struct sk_buff *nskb; - - for (nskb = skb; nskb; nskb = nskb->next) - osh->pktalloced++; - return (void *)skb; } #define PKTFRMNATIVE(osh, skb) \ @@ -1062,11 +1057,6 @@ osl_pkt_frmnative(struct osl_info *osh, struct sk_buff *skb) static inline struct sk_buff * osl_pkt_tonative(struct osl_info *osh, void *pkt) { - struct sk_buff *nskb; - - for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) - osh->pktalloced--; - return (struct sk_buff *)pkt; } #define PKTTONATIVE(osh, pkt) \ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index e85d2d216734..cd5c083f4726 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -141,7 +141,7 @@ * bufpool was present for gspi bus. */ #define PKTFREE2() if ((bus->bus != SPI_BUS) || bus->usebufpool) \ - pkt_buf_free_skb(bus->dhd->osh, pkt, false); + pkt_buf_free_skb(pkt); /* * Conversion of 802.1D priority to precedence level @@ -939,7 +939,7 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, DHD_INFO(("%s: insufficient headroom %d for %d pad\n", __func__, skb_headroom(pkt), pad)); bus->dhd->tx_realloc++; - new = pkt_buf_get_skb(osh, (pkt->len + DHD_SDALIGN)); + new = pkt_buf_get_skb(pkt->len + DHD_SDALIGN); if (!new) { DHD_ERROR(("%s: couldn't allocate new %d-byte " "packet\n", @@ -951,7 +951,7 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, PKTALIGN(osh, new, pkt->len, DHD_SDALIGN); memcpy(new->data, pkt->data, pkt->len); if (free_pkt) - pkt_buf_free_skb(osh, pkt, true); + pkt_buf_free_skb(pkt); /* free the pkt if canned one is not used */ free_pkt = true; pkt = new; @@ -1065,7 +1065,7 @@ done: dhd_os_sdlock(bus->dhd); if (free_pkt) - pkt_buf_free_skb(osh, pkt, true); + pkt_buf_free_skb(pkt); return ret; } @@ -1116,7 +1116,7 @@ int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *pkt) if (dhd_prec_enq(bus->dhd, &bus->txq, pkt, prec) == false) { skb_pull(pkt, SDPCM_HDRLEN); dhd_txcomplete(bus->dhd, pkt, false); - pkt_buf_free_skb(osh, pkt, true); + pkt_buf_free_skb(pkt); DHD_ERROR(("%s: out of bus->txq !!!\n", __func__)); ret = BCME_NORESOURCE; } else { @@ -2886,10 +2886,10 @@ void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex) /* Clear any held glomming stuff */ if (bus->glomd) - pkt_buf_free_skb(osh, bus->glomd, false); + pkt_buf_free_skb(bus->glomd); if (bus->glom) - pkt_buf_free_skb(osh, bus->glom, false); + pkt_buf_free_skb(bus->glom); bus->glom = bus->glomd = NULL; @@ -3188,7 +3188,6 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) u16 sublen, check; struct sk_buff *pfirst, *plast, *pnext, *save_pfirst; - struct osl_info *osh = bus->dhd->osh; int errcode; u8 chan, seq, doff, sfdoff; @@ -3244,7 +3243,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) } /* Allocate/chain packet for next subframe */ - pnext = pkt_buf_get_skb(osh, sublen + DHD_SDALIGN); + pnext = pkt_buf_get_skb(sublen + DHD_SDALIGN); if (pnext == NULL) { DHD_ERROR(("%s: pkt_buf_get_skb failed, num %d len %d\n", __func__, num, sublen)); @@ -3280,13 +3279,13 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) pfirst = pnext = NULL; } else { if (pfirst) - pkt_buf_free_skb(osh, pfirst, false); + pkt_buf_free_skb(pfirst); bus->glom = NULL; num = 0; } /* Done with descriptor packet */ - pkt_buf_free_skb(osh, bus->glomd, false); + pkt_buf_free_skb(bus->glomd); bus->glomd = NULL; bus->nextlen = 0; @@ -3355,7 +3354,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) bus->glomerr = 0; dhdsdio_rxfail(bus, true, false); dhd_os_sdlock_rxq(bus->dhd); - pkt_buf_free_skb(osh, bus->glom, false); + pkt_buf_free_skb(bus->glom); dhd_os_sdunlock_rxq(bus->dhd); bus->rxglomfail++; bus->glom = NULL; @@ -3484,7 +3483,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) bus->glomerr = 0; dhdsdio_rxfail(bus, true, false); dhd_os_sdlock_rxq(bus->dhd); - pkt_buf_free_skb(osh, bus->glom, false); + pkt_buf_free_skb(bus->glom); dhd_os_sdunlock_rxq(bus->dhd); bus->rxglomfail++; bus->glom = NULL; @@ -3532,7 +3531,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) skb_pull(pfirst, doff); if (pfirst->len == 0) { - pkt_buf_free_skb(bus->dhd->osh, pfirst, false); + pkt_buf_free_skb(pfirst); if (plast) { plast->next = pnext; } else { @@ -3545,7 +3544,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) DHD_ERROR(("%s: rx protocol error\n", __func__)); bus->dhd->rx_errors++; - pkt_buf_free_skb(osh, pfirst, false); + pkt_buf_free_skb(pfirst); if (plast) { plast->next = pnext; } else { @@ -3589,7 +3588,6 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) /* Return true if there may be more frames to read */ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) { - struct osl_info *osh = bus->dhd->osh; bcmsdh_info_t *sdh = bus->sdh; u16 len, check; /* Extracted hardware header fields */ @@ -3684,7 +3682,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) */ /* Allocate a packet buffer */ dhd_os_sdlock_rxq(bus->dhd); - pkt = pkt_buf_get_skb(osh, rdlen + DHD_SDALIGN); + pkt = pkt_buf_get_skb(rdlen + DHD_SDALIGN); if (!pkt) { if (bus->bus == SPI_BUS) { bus->usebufpool = false; @@ -3757,7 +3755,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) if (sdret < 0) { DHD_ERROR(("%s (nextlen): read %d bytes failed: %d\n", __func__, rdlen, sdret)); - pkt_buf_free_skb(bus->dhd->osh, pkt, false); + pkt_buf_free_skb(pkt); bus->dhd->rx_errors++; dhd_os_sdunlock_rxq(bus->dhd); /* Force retry w/normal header read. @@ -3905,8 +3903,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) doff); if (bus->usebufpool) { dhd_os_sdlock_rxq(bus->dhd); - pkt_buf_free_skb(bus->dhd->osh, pkt, - false); + pkt_buf_free_skb(pkt); dhd_os_sdunlock_rxq(bus->dhd); } continue; @@ -4095,7 +4092,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) } dhd_os_sdlock_rxq(bus->dhd); - pkt = pkt_buf_get_skb(osh, (rdlen + firstread + DHD_SDALIGN)); + pkt = pkt_buf_get_skb(rdlen + firstread + DHD_SDALIGN); if (!pkt) { /* Give up on data, request rtx of events */ DHD_ERROR(("%s: pkt_buf_get_skb failed: rdlen %d chan %d\n", @@ -4131,7 +4128,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) ? "data" : "test")), sdret)); dhd_os_sdlock_rxq(bus->dhd); - pkt_buf_free_skb(bus->dhd->osh, pkt, false); + pkt_buf_free_skb(pkt); dhd_os_sdunlock_rxq(bus->dhd); bus->dhd->rx_errors++; dhdsdio_rxfail(bus, true, RETRYCHAN(chan)); @@ -4184,13 +4181,13 @@ deliver: if (pkt->len == 0) { dhd_os_sdlock_rxq(bus->dhd); - pkt_buf_free_skb(bus->dhd->osh, pkt, false); + pkt_buf_free_skb(pkt); dhd_os_sdunlock_rxq(bus->dhd); continue; } else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pkt) != 0) { DHD_ERROR(("%s: rx protocol error\n", __func__)); dhd_os_sdlock_rxq(bus->dhd); - pkt_buf_free_skb(bus->dhd->osh, pkt, false); + pkt_buf_free_skb(pkt); dhd_os_sdunlock_rxq(bus->dhd); bus->dhd->rx_errors++; continue; @@ -5012,7 +5009,7 @@ extern int dhd_bus_console_in(dhd_pub_t *dhdp, unsigned char *msg, uint msglen) /* Bump dongle by sending an empty event pkt. * sdpcm_sendup (RX) checks for virtual console input. */ - pkt = pkt_buf_get_skb(bus->dhd->osh, 4 + SDPCM_RESERVE); + pkt = pkt_buf_get_skb(4 + SDPCM_RESERVE); if ((pkt != NULL) && bus->clkstate == CLK_AVAIL) dhdsdio_txpkt(bus, pkt, SDPCM_EVENT_CHANNEL, true); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c index 9224961f6836..ace2000fd08a 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c @@ -2734,12 +2734,6 @@ uint wlc_down(struct wlc_info *wlc) /* wlc_bmac_down_finish has done wlc_coredisable(). so clk is off */ wlc->clk = false; - - /* Verify all packets are flushed from the driver */ - if (wlc->osh->pktalloced != 0) { - WL_ERROR("%d packets not freed at wlc_down!!!!!!\n", - wlc->osh->pktalloced); - } #ifdef BCMDBG /* Since all the packets should have been freed, * all callbacks should have been called @@ -5122,7 +5116,7 @@ wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, tx_failed[WME_PRIO2AC(p->priority)].bytes, pkttotlen(p)); } - pkt_buf_free_skb(wlc->osh, p, true); + pkt_buf_free_skb(p); wlc->pub->_cnt->txnobuf++; } @@ -5154,8 +5148,11 @@ void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, WL_ERROR("wl%d: wlc_txq_enq: txq overflow\n", wlc->pub->unit); - /* ASSERT(9 == 8); *//* XXX we might hit this condtion in case packet flooding from mac80211 stack */ - pkt_buf_free_skb(wlc->osh, sdu, true); + /* + * XXX we might hit this condtion in case + * packet flooding from mac80211 stack + */ + pkt_buf_free_skb(sdu); wlc->pub->_cnt->txnobuf++; } @@ -6710,7 +6707,7 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) fatal: ASSERT(0); if (p) - pkt_buf_free_skb(wlc->osh, p, true); + pkt_buf_free_skb(p); return true; @@ -6977,7 +6974,6 @@ wlc_recvctl(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p) ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p); wlc->pub->_cnt->ieee_rx++; - wlc->osh->pktalloced--; return; } @@ -7094,7 +7090,7 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) return; toss: - pkt_buf_free_skb(wlc->osh, p, false); + pkt_buf_free_skb(p); } /* calculate frame duration for Mixed-mode L-SIG spoofing, return diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h index 0aa7c6f32a03..0f1363414b97 100644 --- a/drivers/staging/brcm80211/include/bcmutils.h +++ b/drivers/staging/brcm80211/include/bcmutils.h @@ -95,9 +95,8 @@ extern struct sk_buff *pktq_pdeq(struct pktq *pq, int prec); extern struct sk_buff *pktq_pdeq_tail(struct pktq *pq, int prec); /* packet primitives */ -extern struct sk_buff *pkt_buf_get_skb(struct osl_info *osh, uint len); -extern void pkt_buf_free_skb(struct osl_info *osh, - struct sk_buff *skb, bool send); +extern struct sk_buff *pkt_buf_get_skb(uint len); +extern void pkt_buf_free_skb(struct sk_buff *skb); /* Empty the queue at particular precedence level */ #ifdef BRCM_FULLMAC diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index d066ed7d373f..5bb4770e56fc 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -33,7 +33,7 @@ /* Global ASSERT type flag */ u32 g_assert_type; -struct sk_buff *BCMFASTPATH pkt_buf_get_skb(struct osl_info *osh, uint len) +struct sk_buff *BCMFASTPATH pkt_buf_get_skb(uint len) { struct sk_buff *skb; @@ -41,16 +41,13 @@ struct sk_buff *BCMFASTPATH pkt_buf_get_skb(struct osl_info *osh, uint len) if (skb) { skb_put(skb, len); skb->priority = 0; - - osh->pktalloced++; } return skb; } /* Free the driver packet. Free the tag if present */ -void BCMFASTPATH pkt_buf_free_skb(struct osl_info *osh, - struct sk_buff *skb, bool send) +void BCMFASTPATH pkt_buf_free_skb(struct sk_buff *skb) { struct sk_buff *nskb; int nest = 0; @@ -73,7 +70,6 @@ void BCMFASTPATH pkt_buf_free_skb(struct osl_info *osh, */ dev_kfree_skb(skb); - osh->pktalloced--; nest++; skb = nskb; } @@ -245,7 +241,7 @@ void pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, bool dir) while (p) { q->head = p->prev; p->prev = NULL; - pkt_buf_free_skb(osh, p, dir); + pkt_buf_free_skb(p); q->len--; pq->len--; p = q->head; @@ -279,7 +275,7 @@ pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, bool dir, else prev->prev = p->prev; p->prev = NULL; - pkt_buf_free_skb(osh, p, dir); + pkt_buf_free_skb(p); q->len--; pq->len--; p = (head ? q->head : prev->prev); diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index e773b9bdc3b8..c82de146f624 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -804,7 +804,7 @@ static void *BCMFASTPATH _dma_rx(dma_info_t *di) if ((di->hnddma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); - pkt_buf_free_skb(di->osh, head, false); + pkt_buf_free_skb(head); di->hnddma.rxgiants++; goto next_frame; } @@ -852,7 +852,7 @@ static bool BCMFASTPATH _dma_rxfill(dma_info_t *di) size to be allocated */ - p = pkt_buf_get_skb(di->osh, di->rxbufsize + extra_offset); + p = pkt_buf_get_skb(di->rxbufsize + extra_offset); if (p == NULL) { DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", @@ -953,7 +953,7 @@ static void _dma_rxreclaim(dma_info_t *di) DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); while ((p = _dma_getnextrxp(di, true))) - pkt_buf_free_skb(di->osh, p, false); + pkt_buf_free_skb(p); } static void *BCMFASTPATH _dma_getnextrxp(dma_info_t *di, bool forceall) @@ -1194,7 +1194,7 @@ static void BCMFASTPATH dma64_txreclaim(dma_info_t *di, txd_range_t range) while ((p = dma64_getnexttxp(di, range))) { /* For unframed data, we don't have any packets to free */ if (!(di->hnddma.dmactrlflags & DMA_CTRL_UNFRAMED)) - pkt_buf_free_skb(di->osh, p, true); + pkt_buf_free_skb(p); } } @@ -1544,7 +1544,7 @@ static int BCMFASTPATH dma64_txfast(dma_info_t *di, struct sk_buff *p0, outoftxd: DMA_ERROR(("%s: dma_txfast: out of txds !!!\n", di->name)); - pkt_buf_free_skb(di->osh, p0, true); + pkt_buf_free_skb(p0); di->hnddma.txavail = 0; di->hnddma.txnobuf++; return -1; -- cgit v1.2.3 From 537ebbbef024c662aa0a350cfc6d5ff45211244c Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 2 Mar 2011 21:18:47 +0100 Subject: staging: brcm80211: remove struct osl_info from function prototypes A couple of functions with struct osl_info do not use this parameter so it is removed from the function prototypes. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 8 ++++---- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 3 +-- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_main.c | 2 +- drivers/staging/brcm80211/include/bcmutils.h | 8 ++++---- drivers/staging/brcm80211/util/bcmutils.c | 12 ++++++------ 6 files changed, 17 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index cd14b125d962..4962650b0cfc 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -1047,20 +1047,20 @@ int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf) } static inline void * -osl_pkt_frmnative(struct osl_info *osh, struct sk_buff *skb) +osl_pkt_frmnative(struct sk_buff *skb) { return (void *)skb; } #define PKTFRMNATIVE(osh, skb) \ - osl_pkt_frmnative((osh), (struct sk_buff *)(skb)) + osl_pkt_frmnative((struct sk_buff *)(skb)) static inline struct sk_buff * -osl_pkt_tonative(struct osl_info *osh, void *pkt) +osl_pkt_tonative(void *pkt) { return (struct sk_buff *)pkt; } #define PKTTONATIVE(osh, pkt) \ - osl_pkt_tonative((osh), (pkt)) + osl_pkt_tonative((pkt)) static int dhd_start_xmit(struct sk_buff *skb, struct net_device *net) { diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index cd5c083f4726..060a5e0b1519 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -2832,7 +2832,6 @@ exit: void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex) { - struct osl_info *osh = bus->dhd->osh; u32 local_hostintmask; u8 saveclk; uint retries; @@ -2882,7 +2881,7 @@ void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex) dhdsdio_clkctl(bus, CLK_SDONLY, false); /* Clear the data packet queues */ - pktq_flush(osh, &bus->txq, true); + pktq_flush(&bus->txq, true); /* Clear any held glomming stuff */ if (bus->glomd) diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index e9cdb05e531b..c0166480cc8b 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -1195,7 +1195,7 @@ ampdu_cleanup_tid_ini(struct ampdu_info *ampdu, scb_ampdu_t *scb_ampdu, u8 tid, ASSERT(ini == &scb_ampdu->ini[ini->tid]); /* free all buffered tx packets */ - pktq_pflush(ampdu->wlc->osh, &scb_ampdu->txq, ini->tid, true, NULL, 0); + pktq_pflush(&scb_ampdu->txq, ini->tid, true, NULL, 0); } /* initialize the initiator code for tid */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c index ace2000fd08a..e046727c58e4 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c @@ -2725,7 +2725,7 @@ uint wlc_down(struct wlc_info *wlc) /* flush tx queues */ for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { - pktq_flush(wlc->osh, &qi->q, true, NULL, 0); + pktq_flush(&qi->q, true, NULL, 0); ASSERT(pktq_empty(&qi->q)); } diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h index 0f1363414b97..fc2a2a910129 100644 --- a/drivers/staging/brcm80211/include/bcmutils.h +++ b/drivers/staging/brcm80211/include/bcmutils.h @@ -100,10 +100,10 @@ extern void pkt_buf_free_skb(struct sk_buff *skb); /* Empty the queue at particular precedence level */ #ifdef BRCM_FULLMAC - extern void pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, + extern void pktq_pflush(struct pktq *pq, int prec, bool dir); #else - extern void pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, + extern void pktq_pflush(struct pktq *pq, int prec, bool dir, ifpkt_cb_t fn, int arg); #endif /* BRCM_FULLMAC */ @@ -131,9 +131,9 @@ extern struct sk_buff *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); /* prec_out may be NULL if caller is not interested in return value */ extern struct sk_buff *pktq_peek_tail(struct pktq *pq, int *prec_out); #ifdef BRCM_FULLMAC - extern void pktq_flush(struct osl_info *osh, struct pktq *pq, bool dir); + extern void pktq_flush(struct pktq *pq, bool dir); #else - extern void pktq_flush(struct osl_info *osh, struct pktq *pq, bool dir, + extern void pktq_flush(struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg); #endif diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index 5bb4770e56fc..00e5c4922b80 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -231,7 +231,7 @@ struct sk_buff *BCMFASTPATH pktq_pdeq_tail(struct pktq *pq, int prec) } #ifdef BRCM_FULLMAC -void pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, bool dir) +void pktq_pflush(struct pktq *pq, int prec, bool dir) { struct pktq_prec *q; struct sk_buff *p; @@ -250,16 +250,16 @@ void pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, bool dir) q->tail = NULL; } -void pktq_flush(struct osl_info *osh, struct pktq *pq, bool dir) +void pktq_flush(struct pktq *pq, bool dir) { int prec; for (prec = 0; prec < pq->num_prec; prec++) - pktq_pflush(osh, pq, prec, dir); + pktq_pflush(pq, prec, dir); ASSERT(pq->len == 0); } #else /* !BRCM_FULLMAC */ void -pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, bool dir, +pktq_pflush(struct pktq *pq, int prec, bool dir, ifpkt_cb_t fn, int arg) { struct pktq_prec *q; @@ -291,12 +291,12 @@ pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, bool dir, } } -void pktq_flush(struct osl_info *osh, struct pktq *pq, bool dir, +void pktq_flush(struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg) { int prec; for (prec = 0; prec < pq->num_prec; prec++) - pktq_pflush(osh, pq, prec, dir, fn, arg); + pktq_pflush(pq, prec, dir, fn, arg); if (fn == NULL) ASSERT(pq->len == 0); } -- cgit v1.2.3 From 3c9d4c3749a712fa370289b54f40b157c336c8f3 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 2 Mar 2011 21:18:48 +0100 Subject: staging: brcm80211: remove struct osl_info from driver sources The struct osl_info was being used only in attach functions but previous changes make the entire usage of this structure obsolete. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdbus.h | 2 +- drivers/staging/brcm80211/brcmfmac/bcmsdh.c | 7 +-- drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c | 21 ++----- drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 3 +- drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h | 4 +- drivers/staging/brcm80211/brcmfmac/dhd.h | 7 +-- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 14 +---- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 68 ++++++++--------------- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 10 ++-- drivers/staging/brcm80211/brcmsmac/wlc_main.c | 5 +- drivers/staging/brcm80211/brcmsmac/wlc_main.h | 1 - drivers/staging/brcm80211/brcmsmac/wlc_pub.h | 5 +- drivers/staging/brcm80211/include/bcmsdh.h | 6 +- drivers/staging/brcm80211/include/hnddma.h | 3 +- drivers/staging/brcm80211/include/siutils.h | 6 +- drivers/staging/brcm80211/util/hnddma.c | 8 +-- 17 files changed, 52 insertions(+), 120 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h b/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h index 99e075b484fb..53c32915acc9 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h @@ -46,7 +46,7 @@ typedef void (*sdioh_cb_fn_t) (void *); * The handler shall be provided by all subsequent calls. No local cache * cfghdl points to the starting address of pci device mapped memory */ -extern sdioh_info_t *sdioh_attach(struct osl_info *osh, void *cfghdl, uint irq); +extern sdioh_info_t *sdioh_attach(void *cfghdl, uint irq); extern SDIOH_API_RC sdioh_detach(sdioh_info_t *si); extern SDIOH_API_RC sdioh_interrupt_register(sdioh_info_t *si, sdioh_cb_fn_t fn, void *argh); diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c index 22c8f8dc55ef..6180f6418f8a 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c @@ -38,7 +38,6 @@ struct bcmsdh_info { bool init_success; /* underlying driver successfully attached */ void *sdioh; /* handler for sdioh */ u32 vendevid; /* Target Vendor and Device ID on SD bus */ - struct osl_info *osh; bool regfail; /* Save status of last reg_read/reg_write call */ u32 sbwad; /* Save backplane window address */ @@ -55,8 +54,7 @@ void bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable) } #endif -bcmsdh_info_t *bcmsdh_attach(struct osl_info *osh, void *cfghdl, - void **regsva, uint irq) +bcmsdh_info_t *bcmsdh_attach(void *cfghdl, void **regsva, uint irq) { bcmsdh_info_t *bcmsdh; @@ -69,13 +67,12 @@ bcmsdh_info_t *bcmsdh_attach(struct osl_info *osh, void *cfghdl, /* save the handler locally */ l_bcmsdh = bcmsdh; - bcmsdh->sdioh = sdioh_attach(osh, cfghdl, irq); + bcmsdh->sdioh = sdioh_attach(cfghdl, irq); if (!bcmsdh->sdioh) { bcmsdh_detach(bcmsdh); return NULL; } - bcmsdh->osh = osh; bcmsdh->init_success = true; *regsva = (u32 *) SI_ENUM_BASE; diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c index 6292f4f843d7..6842e730ed5e 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c @@ -56,7 +56,6 @@ struct bcmsdh_hc { #else struct pci_dev *dev; /* pci device handle */ #endif /* BCMPLATFORM_BUS */ - struct osl_info *osh; void *regs; /* SDIO Host Controller address */ bcmsdh_info_t *sdh; /* SDIO Host Controller handle */ void *ch; @@ -142,7 +141,6 @@ static #endif /* BCMLXSDMMC */ int bcmsdh_probe(struct device *dev) { - struct osl_info *osh = NULL; bcmsdh_hc_t *sdhc = NULL; unsigned long regs = 0; bcmsdh_info_t *sdh = NULL; @@ -177,28 +175,21 @@ int bcmsdh_probe(struct device *dev) } #endif /* defined(OOB_INTR_ONLY) */ /* allocate SDIO Host Controller state info */ - osh = osl_attach(dev, PCI_BUS); - if (!osh) { - SDLX_MSG(("%s: osl_attach failed\n", __func__)); - goto err; - } sdhc = kzalloc(sizeof(bcmsdh_hc_t), GFP_ATOMIC); if (!sdhc) { SDLX_MSG(("%s: out of memory\n", __func__)); goto err; } - sdhc->osh = osh; - sdhc->dev = (void *)dev; #ifdef BCMLXSDMMC - sdh = bcmsdh_attach(osh, (void *)0, (void **)®s, irq); + sdh = bcmsdh_attach((void *)0, (void **)®s, irq); if (!sdh) { SDLX_MSG(("%s: bcmsdh_attach failed\n", __func__)); goto err; } #else - sdh = bcmsdh_attach(osh, (void *)r->start, (void **)®s, irq); + sdh = bcmsdh_attach((void *)r->start, (void **)®s, irq); if (!sdh) { SDLX_MSG(("%s: bcmsdh_attach failed\n", __func__)); goto err; @@ -220,7 +211,7 @@ int bcmsdh_probe(struct device *dev) /* try to attach to the target device */ sdhc->ch = drvinfo.attach((vendevid >> 16), (vendevid & 0xFFFF), - 0, 0, 0, 0, (void *)regs, NULL, sdh); + 0, 0, 0, 0, (void *)regs, sdh); if (!sdhc->ch) { SDLX_MSG(("%s: device attach failed\n", __func__)); goto err; @@ -235,8 +226,7 @@ err: bcmsdh_detach(sdhc->sdh); kfree(sdhc); } - if (osh) - osl_detach(osh); + return -ENODEV; } @@ -246,7 +236,6 @@ static int bcmsdh_remove(struct device *dev) { bcmsdh_hc_t *sdhc, *prev; - struct osl_info *osh; sdhc = sdhcinfo; drvinfo.detach(sdhc->ch); @@ -269,9 +258,7 @@ int bcmsdh_remove(struct device *dev) } /* release SDIO Host Controller info */ - osh = sdhc->osh; kfree(sdhc); - osl_detach(osh); #if !defined(BCMLXSDMMC) dev_set_drvdata(dev, NULL); diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index ef75219968fc..e69b77f04c43 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -111,7 +111,7 @@ static int sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd) /* * Public entry points & extern's */ -extern sdioh_info_t *sdioh_attach(struct osl_info *osh, void *bar0, uint irq) +sdioh_info_t *sdioh_attach(void *bar0, uint irq) { sdioh_info_t *sd; int err_ret; @@ -128,7 +128,6 @@ extern sdioh_info_t *sdioh_attach(struct osl_info *osh, void *bar0, uint irq) sd_err(("sdioh_attach: out of memory\n")); return NULL; } - sd->osh = osh; if (sdioh_sdmmc_osinit(sd) != 0) { sd_err(("%s:sdioh_sdmmc_osinit() failed\n", __func__)); kfree(sd); diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h index 50470f6c92fa..3ef42b318493 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h @@ -118,8 +118,8 @@ extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd); */ /* Register mapping routines */ -extern u32 *sdioh_sdmmc_reg_map(struct osl_info *osh, s32 addr, int size); -extern void sdioh_sdmmc_reg_unmap(struct osl_info *osh, s32 addr, int size); +extern u32 *sdioh_sdmmc_reg_map(s32 addr, int size); +extern void sdioh_sdmmc_reg_unmap(s32 addr, int size); /* Interrupt (de)registration routines */ extern int sdioh_sdmmc_register_irq(sdioh_info_t *sd, uint irq); diff --git a/drivers/staging/brcm80211/brcmfmac/dhd.h b/drivers/staging/brcm80211/brcmfmac/dhd.h index a78b20a0cc79..60cf78213a07 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd.h @@ -52,7 +52,6 @@ enum dhd_bus_state { /* Common structure for module and instance linkage */ typedef struct dhd_pub { /* Linkage ponters */ - struct osl_info *osh; /* OSL handle */ struct dhd_bus *bus; /* Bus module handle */ struct dhd_prot *prot; /* Protocol module handle */ struct dhd_info *info; /* Info module handle */ @@ -213,16 +212,12 @@ typedef struct dhd_if_event { * Exported from dhd OS modules (dhd_linux/dhd_ndis) */ -/* To allow osl_attach/detach calls from os-independent modules */ -struct osl_info *dhd_osl_attach(void *pdev, uint bustype); -void dhd_osl_detach(struct osl_info *osh); - /* Indication from bus module regarding presence/insertion of dongle. * Return dhd_pub_t pointer, used as handle to OS module in later calls. * Returned structure should have bus and prot pointers filled in. * bus_hdrlen specifies required headroom for bus module header. */ -extern dhd_pub_t *dhd_attach(struct osl_info *osh, struct dhd_bus *bus, +extern dhd_pub_t *dhd_attach(struct dhd_bus *bus, uint bus_hdrlen); extern int dhd_net_attach(dhd_pub_t *dhdp, int idx); diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 4962650b0cfc..870f3bebe1d5 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -1858,16 +1858,6 @@ static int dhd_open(struct net_device *net) return ret; } -struct osl_info *dhd_osl_attach(void *pdev, uint bustype) -{ - return osl_attach(pdev, bustype); -} - -void dhd_osl_detach(struct osl_info *osh) -{ - osl_detach(osh); -} - int dhd_add_if(dhd_info_t *dhd, int ifidx, void *handle, char *name, u8 *mac_addr, u32 flags, u8 bssidx) @@ -1921,8 +1911,7 @@ void dhd_del_if(dhd_info_t *dhd, int ifidx) up(&dhd->sysioc_sem); } -dhd_pub_t *dhd_attach(struct osl_info *osh, struct dhd_bus *bus, - uint bus_hdrlen) +dhd_pub_t *dhd_attach(struct dhd_bus *bus, uint bus_hdrlen) { dhd_info_t *dhd = NULL; struct net_device *net; @@ -1955,7 +1944,6 @@ dhd_pub_t *dhd_attach(struct osl_info *osh, struct dhd_bus *bus, * Save the dhd_info into the priv */ memcpy(netdev_priv(net), &dhd, sizeof(dhd)); - dhd->pub.osh = osh; /* Set network interface name if it was provided as module parameter */ if (iface_name[0]) { diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 060a5e0b1519..bb62576ea88f 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -362,7 +362,7 @@ extern void bcmsdh_enable_hw_oob_intr(void *sdh, bool enable); #if defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD) #error OOB_INTR_ONLY is NOT working with SDIO_ISR_THREAD #endif /* defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD) */ -#define PKTALIGN(_osh, _p, _len, _align) \ +#define PKTALIGN(_p, _len, _align) \ do { \ uint datalign; \ datalign = (unsigned long)((_p)->data); \ @@ -436,7 +436,7 @@ static int dhdsdio_mem_dump(dhd_bus_t *bus); #endif /* DHD_DEBUG */ static int dhdsdio_download_state(dhd_bus_t *bus, bool enter); -static void dhdsdio_release(dhd_bus_t *bus, struct osl_info *osh); +static void dhdsdio_release(dhd_bus_t *bus); static void dhdsdio_release_malloc(dhd_bus_t *bus); static void dhdsdio_disconnect(void *ptr); static bool dhdsdio_chipmatch(u16 chipid); @@ -911,7 +911,6 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, bool free_pkt) { int ret; - struct osl_info *osh; u8 *frame; u16 len, pad = 0; u32 swheader; @@ -923,7 +922,6 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, DHD_TRACE(("%s: Enter\n", __func__)); sdh = bus->sdh; - osh = bus->dhd->osh; if (bus->dhd->dongle_reset) { ret = BCME_NOTREADY; @@ -948,7 +946,7 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, goto done; } - PKTALIGN(osh, new, pkt->len, DHD_SDALIGN); + PKTALIGN(new, pkt->len, DHD_SDALIGN); memcpy(new->data, pkt->data, pkt->len); if (free_pkt) pkt_buf_free_skb(pkt); @@ -1073,12 +1071,10 @@ done: int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *pkt) { int ret = BCME_ERROR; - struct osl_info *osh; uint datalen, prec; DHD_TRACE(("%s: Enter\n", __func__)); - osh = bus->dhd->osh; datalen = pkt->len; #ifdef SDTEST @@ -2484,9 +2480,6 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, __func__, bool_val, bus->dhd->dongle_reset, bus->dhd->busstate)); - ASSERT(bus->dhd->osh); - /* ASSERT(bus->cl_devid); */ - dhd_bus_devreset(bus->dhd, (u8) bool_val); break; @@ -3259,7 +3252,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) } /* Adhere to start alignment requirements */ - PKTALIGN(osh, pnext, sublen, DHD_SDALIGN); + PKTALIGN(pnext, sublen, DHD_SDALIGN); } /* If all allocations succeeded, save packet chain @@ -3739,7 +3732,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) bus->usebufpool = true; ASSERT(!(pkt->prev)); - PKTALIGN(osh, pkt, rdlen, DHD_SDALIGN); + PKTALIGN(pkt, rdlen, DHD_SDALIGN); rxbuf = (u8 *) (pkt->data); /* Read the entire frame */ sdret = @@ -4108,7 +4101,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) /* Leave room for what we already read, and align remainder */ ASSERT(firstread < pkt->len); skb_pull(pkt, firstread); - PKTALIGN(osh, pkt, rdlen, DHD_SDALIGN); + PKTALIGN(pkt, rdlen, DHD_SDALIGN); /* Read the remaining frame data */ sdret = @@ -4635,7 +4628,6 @@ static void dhdsdio_pktgen(dhd_bus_t *bus) u8 *data; uint pktcount; uint fillbyte; - struct osl_info *osh = bus->dhd->osh; u16 len; /* Display current count if appropriate */ @@ -4663,14 +4655,14 @@ static void dhdsdio_pktgen(dhd_bus_t *bus) /* Allocate an appropriate-sized packet */ len = bus->pktgen_len; - pkt = pkt_buf_get_skb(osh, + pkt = pkt_buf_get_skb( (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN), true); if (!pkt) { DHD_ERROR(("%s: pkt_buf_get_skb failed!\n", __func__)); break; } - PKTALIGN(osh, pkt, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), + PKTALIGN(pkt, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN); data = (u8 *) (pkt->data) + SDPCM_HDRLEN; @@ -4694,7 +4686,7 @@ static void dhdsdio_pktgen(dhd_bus_t *bus) default: DHD_ERROR(("Unrecognized pktgen mode %d\n", bus->pktgen_mode)); - pkt_buf_free_skb(osh, pkt, true); + pkt_buf_free_skb(pkt, true); bus->pktgen_count = 0; return; } @@ -4740,16 +4732,15 @@ static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start) { struct sk_buff *pkt; u8 *data; - struct osl_info *osh = bus->dhd->osh; /* Allocate the packet */ - pkt = pkt_buf_get_skb(osh, SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN, + pkt = pkt_buf_get_skb(SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN, true); if (!pkt) { DHD_ERROR(("%s: pkt_buf_get_skb failed!\n", __func__)); return; } - PKTALIGN(osh, pkt, (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN); + PKTALIGN(pkt, (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN); data = (u8 *) (pkt->data) + SDPCM_HDRLEN; /* Fill in the test header */ @@ -4765,7 +4756,6 @@ static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start) static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) { - struct osl_info *osh = bus->dhd->osh; u8 *data; uint pktlen; @@ -4779,7 +4769,7 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) if (pktlen < SDPCM_TEST_HDRLEN) { DHD_ERROR(("dhdsdio_restrcv: toss runt frame, pktlen %d\n", pktlen)); - pkt_buf_free_skb(osh, pkt, false); + pkt_buf_free_skb(pkt, false); return; } @@ -4797,7 +4787,7 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) DHD_ERROR(("dhdsdio_testrcv: frame length mismatch, " "pktlen %d seq %d" " cmd %d extra %d len %d\n", pktlen, seq, cmd, extra, len)); - pkt_buf_free_skb(osh, pkt, false); + pkt_buf_free_skb(pkt, false); return; } } @@ -4812,14 +4802,14 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) bus->pktgen_sent++; } else { bus->pktgen_fail++; - pkt_buf_free_skb(osh, pkt, false); + pkt_buf_free_skb(pkt, false); } bus->pktgen_rcvd++; break; case SDPCM_TEST_ECHORSP: if (bus->ext_loop) { - pkt_buf_free_skb(osh, pkt, false); + pkt_buf_free_skb(pkt, false); bus->pktgen_rcvd++; break; } @@ -4832,12 +4822,12 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) break; } } - pkt_buf_free_skb(osh, pkt, false); + pkt_buf_free_skb(pkt, false); bus->pktgen_rcvd++; break; case SDPCM_TEST_DISCARD: - pkt_buf_free_skb(osh, pkt, false); + pkt_buf_free_skb(pkt, false); bus->pktgen_rcvd++; break; @@ -4847,7 +4837,7 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) DHD_INFO(("dhdsdio_testrcv: unsupported or unknown command, " "pktlen %d seq %d" " cmd %d extra %d len %d\n", pktlen, seq, cmd, extra, len)); - pkt_buf_free_skb(osh, pkt, false); + pkt_buf_free_skb(pkt, false); break; } @@ -5066,7 +5056,7 @@ static bool dhdsdio_chipmatch(u16 chipid) static void *dhdsdio_probe(u16 venid, u16 devid, u16 bus_no, u16 slot, u16 func, uint bustype, void *regsva, - struct osl_info *osh, void *sdh) + void *sdh) { int ret; dhd_bus_t *bus; @@ -5143,15 +5133,6 @@ static void *dhdsdio_probe(u16 venid, u16 devid, u16 bus_no, return NULL; } - if (osh == NULL) { - /* Ask the OS interface part for an OSL handle */ - osh = dhd_osl_attach(sdh, DHD_BUS); - if (!osh) { - DHD_ERROR(("%s: osl_attach failed!\n", __func__)); - return NULL; - } - } - /* Allocate private bus interface state */ bus = kzalloc(sizeof(dhd_bus_t), GFP_ATOMIC); if (!bus) { @@ -5172,7 +5153,7 @@ static void *dhdsdio_probe(u16 venid, u16 devid, u16 bus_no, } /* Attach to the dhd/OS/network interface */ - bus->dhd = dhd_attach(osh, bus, SDPCM_RESERVE); + bus->dhd = dhd_attach(bus, SDPCM_RESERVE); if (!bus->dhd) { DHD_ERROR(("%s: dhd_attach failed\n", __func__)); goto fail; @@ -5220,7 +5201,7 @@ static void *dhdsdio_probe(u16 venid, u16 devid, u16 bus_no, return bus; fail: - dhdsdio_release(bus, osh); + dhdsdio_release(bus); return NULL; } @@ -5527,7 +5508,7 @@ dhdsdio_download_firmware(struct dhd_bus *bus, void *sdh) } /* Detach and free everything */ -static void dhdsdio_release(dhd_bus_t *bus, struct osl_info *osh) +static void dhdsdio_release(dhd_bus_t *bus) { DHD_TRACE(("%s: Enter\n", __func__)); @@ -5549,9 +5530,6 @@ static void dhdsdio_release(dhd_bus_t *bus, struct osl_info *osh) kfree(bus); } - if (osh) - dhd_osl_detach(osh); - DHD_TRACE(("%s: Disconnected\n", __func__)); } @@ -5604,7 +5582,7 @@ static void dhdsdio_disconnect(void *ptr) if (bus) { ASSERT(bus->dhd); - dhdsdio_release(bus, bus->dhd->osh); + dhdsdio_release(bus); } DHD_TRACE(("%s: Disconnected\n", __func__)); diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 2b2d1c21dffc..9fdd7755b590 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -790,7 +790,7 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, } /* common load-time initialization */ - wl->wlc = wlc_attach((void *)wl, vendor, device, unit, wl->piomode, osh, + wl->wlc = wlc_attach((void *)wl, vendor, device, unit, wl->piomode, wl->regsva, wl->bcm_bustype, btparam, &err); wl_release_fw(wl); if (!wl->wlc) { diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index ca12d2602799..e419da54be1a 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -531,8 +531,6 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) if (wlc_hw->di[0] == 0) { /* Init FIFOs */ uint addrwidth; int dma_attach_err = 0; - struct osl_info *osh = wlc->osh; - /* Find out the DMA addressing capability and let OS know * All the channels within one DMA core have 'common-minimum' same * capability @@ -553,7 +551,7 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) */ ASSERT(TX_AC_BK_FIFO == 0); ASSERT(RX_FIFO == 0); - wlc_hw->di[0] = dma_attach(osh, name, wlc_hw->sih, + wlc_hw->di[0] = dma_attach(name, wlc_hw->sih, (wme ? DMAREG(wlc_hw, DMA_TX, 0) : NULL), DMAREG(wlc_hw, DMA_RX, 0), (wme ? tune->ntxd : 0), tune->nrxd, @@ -569,7 +567,7 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) */ ASSERT(TX_AC_BE_FIFO == 1); ASSERT(TX_DATA_FIFO == 1); - wlc_hw->di[1] = dma_attach(osh, name, wlc_hw->sih, + wlc_hw->di[1] = dma_attach(name, wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 1), NULL, tune->ntxd, 0, 0, -1, 0, 0, &wl_msg_level); @@ -581,7 +579,7 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) * RX: UNUSED */ ASSERT(TX_AC_VI_FIFO == 2); - wlc_hw->di[2] = dma_attach(osh, name, wlc_hw->sih, + wlc_hw->di[2] = dma_attach(name, wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 2), NULL, tune->ntxd, 0, 0, -1, 0, 0, &wl_msg_level); @@ -593,7 +591,7 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) */ ASSERT(TX_AC_VO_FIFO == 3); ASSERT(TX_CTL_FIFO == 3); - wlc_hw->di[3] = dma_attach(osh, name, wlc_hw->sih, + wlc_hw->di[3] = dma_attach(name, wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 3), NULL, tune->ntxd, 0, 0, -1, 0, 0, &wl_msg_level); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c index e046727c58e4..4527fe2dac6e 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c @@ -1722,8 +1722,7 @@ struct wlc_pub *wlc_pub(void *wlc) * The common driver entry routine. Error codes should be unique */ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, - struct osl_info *osh, void *regsva, uint bustype, - void *btparam, uint *perr) + void *regsva, uint bustype, void *btparam, uint *perr) { struct wlc_info *wlc; uint err = 0; @@ -1772,7 +1771,6 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, wlc = (struct wlc_info *) wlc_attach_malloc(unit, &err, device); if (wlc == NULL) goto fail; - wlc->osh = osh; pub = wlc->pub; #if defined(BCMDBG) @@ -1783,7 +1781,6 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, wlc->core = wlc->corestate; wlc->wl = wl; pub->unit = unit; - pub->osh = osh; wlc->btparam = btparam; pub->_piomode = piomode; wlc->bandinit_pending = false; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.h b/drivers/staging/brcm80211/brcmsmac/wlc_main.h index b2b52d297502..7c5d7e1df07c 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.h @@ -488,7 +488,6 @@ struct wlc_txq_info { */ struct wlc_info { struct wlc_pub *pub; /* pointer to wlc public state */ - struct osl_info *osh; /* pointer to os handle */ struct wl_info *wl; /* pointer to os-specific private state */ d11regs_t *regs; /* pointer to device registers */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h index 0cd98910987a..5536f5111f48 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h @@ -241,7 +241,6 @@ struct wlc_pub { uint mac80211_state; uint unit; /* device instance number */ uint corerev; /* core revision */ - struct osl_info *osh; /* pointer to os handle */ si_t *sih; /* SB handle (cookie for siutils calls) */ char *vars; /* "environment" name=value */ bool up; /* interface up and running */ @@ -480,8 +479,8 @@ extern const u8 wme_fifo2ac[]; /* common functions for every port */ extern void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, - bool piomode, struct osl_info *osh, void *regsva, - uint bustype, void *btparam, uint *perr); + bool piomode, void *regsva, uint bustype, void *btparam, + uint *perr); extern uint wlc_detach(struct wlc_info *wlc); extern int wlc_up(struct wlc_info *wlc); extern uint wlc_down(struct wlc_info *wlc); diff --git a/drivers/staging/brcm80211/include/bcmsdh.h b/drivers/staging/brcm80211/include/bcmsdh.h index d27d1cbb7f79..3b57dc13b1de 100644 --- a/drivers/staging/brcm80211/include/bcmsdh.h +++ b/drivers/staging/brcm80211/include/bcmsdh.h @@ -49,8 +49,7 @@ typedef void (*bcmsdh_cb_fn_t) (void *); * implementation may maintain a single "default" handle (e.g. the first or * most recent one) to enable single-instance implementations to pass NULL. */ -extern bcmsdh_info_t *bcmsdh_attach(struct osl_info *osh, void *cfghdl, - void **regsva, uint irq); +extern bcmsdh_info_t *bcmsdh_attach(void *cfghdl, void **regsva, uint irq); /* Detach - freeup resources allocated in attach */ extern int bcmsdh_detach(void *sdh); @@ -183,8 +182,7 @@ extern void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh); typedef struct { /* attach to device */ void *(*attach) (u16 vend_id, u16 dev_id, u16 bus, u16 slot, - u16 func, uint bustype, void *regsva, - struct osl_info *osh, void *param); + u16 func, uint bustype, void *regsva, void *param); /* detach from device */ void (*detach) (void *ch); } bcmsdh_driver_t; diff --git a/drivers/staging/brcm80211/include/hnddma.h b/drivers/staging/brcm80211/include/hnddma.h index 363898359d08..121768eccfea 100644 --- a/drivers/staging/brcm80211/include/hnddma.h +++ b/drivers/staging/brcm80211/include/hnddma.h @@ -148,8 +148,7 @@ struct hnddma_pub { uint txnobuf; /* tx out of dma descriptors */ }; -extern struct hnddma_pub *dma_attach(struct osl_info *osh, char *name, - si_t *sih, +extern struct hnddma_pub *dma_attach(char *name, si_t *sih, void *dmaregstx, void *dmaregsrx, uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, uint nrxpost, uint rxoffset, uint *msg_level); diff --git a/drivers/staging/brcm80211/include/siutils.h b/drivers/staging/brcm80211/include/siutils.h index a95e9255b47c..101e9a4f807d 100644 --- a/drivers/staging/brcm80211/include/siutils.h +++ b/drivers/staging/brcm80211/include/siutils.h @@ -328,9 +328,9 @@ extern void si_epa_4313war(si_t *sih); char *si_getnvramflvar(si_t *sih, const char *name); /* AMBA Interconnect exported externs */ -extern si_t *ai_attach(uint pcidev, struct osl_info *osh, void *regs, - uint bustype, void *sdh, char **vars, uint *varsz); -extern si_t *ai_kattach(struct osl_info *osh); +extern si_t *ai_attach(uint pcidev, void *regs, uint bustype, + void *sdh, char **vars, uint *varsz); +extern si_t *ai_kattach(void); extern void ai_scan(si_t *sih, void *regs, uint devid); extern uint ai_flag(si_t *sih); diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index c82de146f624..5508147ba965 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -80,7 +80,6 @@ typedef struct dma_info { uint *msg_level; /* message level pointer */ char name[MAXNAMEL]; /* callers name for diag msgs */ - struct osl_info *osh; /* os handle */ void *pbus; /* bus handle */ bool dma64; /* this dma engine is operating in 64-bit mode */ @@ -276,7 +275,7 @@ const di_fcn_t dma64proc = { 39 }; -struct hnddma_pub *dma_attach(struct osl_info *osh, char *name, si_t *sih, +struct hnddma_pub *dma_attach(char *name, si_t *sih, void *dmaregstx, void *dmaregsrx, uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, uint nrxpost, uint rxoffset, uint *msg_level) @@ -324,9 +323,9 @@ struct hnddma_pub *dma_attach(struct osl_info *osh, char *name, si_t *sih, di->hnddma.di_fn->ctrlflags(&di->hnddma, DMA_CTRL_ROC | DMA_CTRL_PEN, 0); - DMA_TRACE(("%s: dma_attach: %s osh %p flags 0x%x ntxd %d nrxd %d " + DMA_TRACE(("%s: dma_attach: %s flags 0x%x ntxd %d nrxd %d " "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d " - "dmaregstx %p dmaregsrx %p\n", name, "DMA64", osh, + "dmaregstx %p dmaregsrx %p\n", name, "DMA64", di->hnddma.dmactrlflags, ntxd, nrxd, rxbufsize, rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx)); @@ -334,7 +333,6 @@ struct hnddma_pub *dma_attach(struct osl_info *osh, char *name, si_t *sih, strncpy(di->name, name, MAXNAMEL); di->name[MAXNAMEL - 1] = '\0'; - di->osh = osh; di->pbus = ((struct si_info *)sih)->pbus; /* save tunables */ -- cgit v1.2.3 From 9cceab99d7038b69093fd0142f644224c040a6bb Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 2 Mar 2011 21:18:49 +0100 Subject: staging: brcm80211: remove osl source files from driver The whole need for the OSL concept has been removed from the driver. This is the final commit removing the source file and include file from the driver repository. All include statements of osl.h have been removed from the other source files. Reviewed-by: Brett Rudley Reviewed-by: Henry Ptasinski Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/Makefile | 1 - drivers/staging/brcm80211/brcmfmac/bcmsdh.c | 1 - drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c | 1 - drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 1 - .../brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c | 1 - drivers/staging/brcm80211/brcmfmac/dhd_cdc.c | 1 - drivers/staging/brcm80211/brcmfmac/dhd_common.c | 1 - .../staging/brcm80211/brcmfmac/dhd_custom_gpio.c | 1 - drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 1 - drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 1 - drivers/staging/brcm80211/brcmfmac/linux_osl.c | 1 - drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 1 - drivers/staging/brcm80211/brcmfmac/wl_iw.c | 1 - drivers/staging/brcm80211/brcmsmac/Makefile | 1 - .../staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c | 1 - .../staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c | 1 - drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c | 1 - .../brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c | 1 - .../staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c | 1 - drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 9 ---- drivers/staging/brcm80211/brcmsmac/wl_mac80211.h | 1 - drivers/staging/brcm80211/brcmsmac/wlc_alloc.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_antsel.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_channel.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_main.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_rate.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_stf.c | 1 - drivers/staging/brcm80211/include/osl.h | 29 ------------ drivers/staging/brcm80211/util/aiutils.c | 1 - drivers/staging/brcm80211/util/bcmotp.c | 1 - drivers/staging/brcm80211/util/bcmsrom.c | 1 - drivers/staging/brcm80211/util/bcmutils.c | 1 - drivers/staging/brcm80211/util/bcmwifi.c | 1 - drivers/staging/brcm80211/util/hnddma.c | 1 - drivers/staging/brcm80211/util/hndpmu.c | 1 - drivers/staging/brcm80211/util/linux_osl.c | 54 ---------------------- drivers/staging/brcm80211/util/nicpci.c | 1 - drivers/staging/brcm80211/util/nvram/nvram_ro.c | 1 - drivers/staging/brcm80211/util/sbutils.c | 1 - drivers/staging/brcm80211/util/siutils.c | 1 - 43 files changed, 132 deletions(-) delete mode 100644 drivers/staging/brcm80211/brcmfmac/linux_osl.c delete mode 100644 drivers/staging/brcm80211/include/osl.h delete mode 100644 drivers/staging/brcm80211/util/linux_osl.c (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/Makefile b/drivers/staging/brcm80211/brcmfmac/Makefile index 040f4a72dad8..ac5a7d4ba806 100644 --- a/drivers/staging/brcm80211/brcmfmac/Makefile +++ b/drivers/staging/brcm80211/brcmfmac/Makefile @@ -52,7 +52,6 @@ DHDOFILES = \ bcmsdh_linux.o \ bcmsdh_sdmmc.o \ bcmsdh_sdmmc_linux.o \ - linux_osl.o \ aiutils.o \ siutils.o \ sbutils.o \ diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c index 6180f6418f8a..473f57d9f00b 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c index 6842e730ed5e..e3556ff43bb9 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c @@ -24,7 +24,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index e69b77f04c43..65313fa0cf4a 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include /* SDIO Device and Protocol Specs */ #include /* SDIO Host Controller Specification */ diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c index ceaa47490680..d738d4da5443 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c @@ -17,7 +17,6 @@ #include /* request_irq() */ #include #include -#include #include #include /* SDIO Specs */ #include /* bcmsdh to/from specific controller APIs */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c index 6c0620c9742f..8398fa4c0340 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index a80a5c3170fd..64d88c20354e 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c b/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c index 1a7a93981bff..cbfa1c1b7059 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c @@ -15,7 +15,6 @@ */ #include -#include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 870f3bebe1d5..ab8e688d9620 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index bb62576ea88f..971d40689098 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #ifdef BCMEMBEDIMAGE diff --git a/drivers/staging/brcm80211/brcmfmac/linux_osl.c b/drivers/staging/brcm80211/brcmfmac/linux_osl.c deleted file mode 100644 index a4d338dc94a3..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/linux_osl.c +++ /dev/null @@ -1 +0,0 @@ -#include "../util/linux_osl.c" diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index fc920787cdaa..1291124272f3 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -16,7 +16,6 @@ #include #include -#include #include diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index f82c10ef8bad..4d16644544ae 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/Makefile b/drivers/staging/brcm80211/brcmsmac/Makefile index b0d3e074e400..c4aafe5cf7f5 100644 --- a/drivers/staging/brcm80211/brcmsmac/Makefile +++ b/drivers/staging/brcm80211/brcmsmac/Makefile @@ -45,7 +45,6 @@ BRCMSMAC_OFILES := \ phy/wlc_phy_n.o \ phy/wlc_phytbl_lcn.o \ phy/wlc_phytbl_n.o \ - ../util/linux_osl.o \ ../util/aiutils.o \ ../util/siutils.o \ ../util/bcmutils.o \ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c index bb49a0cd0b08..fc810e342df8 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c index 825bf767a2d5..a5a7bb82ab42 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c index e51d303c83f5..a38587309ccc 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c index e962902d7228..81c59b05482a 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c @@ -16,7 +16,6 @@ #include #include -#include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c index 3dbce71f83ab..742df997a3b1 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c @@ -17,7 +17,6 @@ #include #include -#include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 9fdd7755b590..d70ed3d990d6 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -27,7 +27,6 @@ #include #include -#include #include #include #include @@ -729,7 +728,6 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, uint bustype, void *btparam, uint irq) { struct wl_info *wl; - struct osl_info *osh; int unit, err; unsigned long base_addr; @@ -744,15 +742,11 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, return NULL; } - osh = osl_attach(btparam, bustype); - ASSERT(osh); - /* allocate private info */ hw = pci_get_drvdata(btparam); /* btparam == pdev */ wl = hw->priv; ASSERT(wl); - wl->osh = osh; atomic_set(&wl->callbacks, 0); /* setup the bottom half handler */ @@ -1397,9 +1391,6 @@ static void wl_free(struct wl_info *wl) iounmap((void *)wl->regsva); } wl->regsva = NULL; - - - osl_detach(wl->osh); } /* diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h index a4bed8bd629e..f3198ccd5f58 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h @@ -51,7 +51,6 @@ struct wl_firmware { struct wl_info { struct wlc_pub *pub; /* pointer to public wlc state */ void *wlc; /* pointer to private common os-independent data */ - struct osl_info *osh; /* pointer to os handler */ u32 magic; int irq; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c index 0b6c6e72bdd0..07684967d87c 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index c0166480cc8b..7f8790d9b817 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c index 33e3bdff61bc..566be8689478 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index e419da54be1a..b85194dd57ce 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -22,7 +22,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c index 49b1ea6b7ea8..d43948f1c643 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c index 4527fe2dac6e..cb1e1428cd87 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c index e867bf72cb41..1ac659769c57 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c @@ -26,7 +26,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c index 863f18f86ece..0cfa36023cf1 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c @@ -18,7 +18,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c index 75aeb280eb99..a6f6e5c649c7 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h deleted file mode 100644 index 24b114d6ca96..000000000000 --- a/drivers/staging/brcm80211/include/osl.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _osl_h_ -#define _osl_h_ - -/* osl handle type forward declaration */ -struct osl_info { - uint pktalloced; /* Number of allocated packet buffers */ - uint magic; -}; - -extern struct osl_info *osl_attach(void *pdev, uint bustype); -extern void osl_detach(struct osl_info *osh); - -#endif /* _osl_h_ */ diff --git a/drivers/staging/brcm80211/util/aiutils.c b/drivers/staging/brcm80211/util/aiutils.c index 917989774520..570869032d88 100644 --- a/drivers/staging/brcm80211/util/aiutils.c +++ b/drivers/staging/brcm80211/util/aiutils.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/util/bcmotp.c b/drivers/staging/brcm80211/util/bcmotp.c index e763a0de7989..b080345397f0 100644 --- a/drivers/staging/brcm80211/util/bcmotp.c +++ b/drivers/staging/brcm80211/util/bcmotp.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index 11b5c0861f00..7373603b6646 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index 00e5c4922b80..fb0bcccfda44 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/util/bcmwifi.c b/drivers/staging/brcm80211/util/bcmwifi.c index 3d3e5eaddefe..d82c2b29816d 100644 --- a/drivers/staging/brcm80211/util/bcmwifi.c +++ b/drivers/staging/brcm80211/util/bcmwifi.c @@ -15,7 +15,6 @@ */ #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 5508147ba965..60afd06297e8 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/util/hndpmu.c b/drivers/staging/brcm80211/util/hndpmu.c index 911374955d63..59e3ede89fe7 100644 --- a/drivers/staging/brcm80211/util/hndpmu.c +++ b/drivers/staging/brcm80211/util/hndpmu.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c deleted file mode 100644 index 2f76aaf73570..000000000000 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#ifdef mips -#include -#endif /* mips */ -#include -#include -#include -#include -#include -#include -#include -#include - - -#define OS_HANDLE_MAGIC 0x1234abcd /* Magic # to recognise osh */ -#define BCM_MEM_FILENAME_LEN 24 /* Mem. filename length */ - -struct osl_info *osl_attach(void *pdev, uint bustype) -{ - struct osl_info *osh; - - osh = kmalloc(sizeof(struct osl_info), GFP_ATOMIC); - ASSERT(osh); - - memset(osh, 0, sizeof(struct osl_info)); - osh->magic = OS_HANDLE_MAGIC; - return osh; -} - -void osl_detach(struct osl_info *osh) -{ - if (osh == NULL) - return; - - ASSERT(osh->magic == OS_HANDLE_MAGIC); - kfree(osh); -} diff --git a/drivers/staging/brcm80211/util/nicpci.c b/drivers/staging/brcm80211/util/nicpci.c index b5e79ac30b09..a1fb2f08984d 100644 --- a/drivers/staging/brcm80211/util/nicpci.c +++ b/drivers/staging/brcm80211/util/nicpci.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/util/nvram/nvram_ro.c b/drivers/staging/brcm80211/util/nvram/nvram_ro.c index a5e8c4daaa15..a697ff10ef36 100644 --- a/drivers/staging/brcm80211/util/nvram/nvram_ro.c +++ b/drivers/staging/brcm80211/util/nvram/nvram_ro.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/util/sbutils.c b/drivers/staging/brcm80211/util/sbutils.c index 75381e4d6da7..21dde8e508dd 100644 --- a/drivers/staging/brcm80211/util/sbutils.c +++ b/drivers/staging/brcm80211/util/sbutils.c @@ -19,7 +19,6 @@ #ifdef BRCM_FULLMAC #include #endif -#include #include #include #include diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index d8d8f829b320..ed168ceba5f0 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From 962f3ffa927f2e777a4193843c45ffa6e52ff4b6 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Wed, 2 Mar 2011 20:35:28 +0900 Subject: wusb: fix find_first_zero_bit() return value check In wusb_cluster_id_get(), if no zero bits exist in wusb_cluster_id_table, find_first_zero_bit() returns CLUSTER_IDS. But it is impossible to detect that the bitmap is full because there is an off-by-one error in the return value check. It will cause unexpected memory access by setting bit out of wusb_cluster_id_table bitmap, and caller will get wrong cluster id. Signed-off-by: Akinobu Mita Cc: linux-usb@vger.kernel.org Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/wusbcore/wusbhc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/wusbcore/wusbhc.c b/drivers/usb/wusbcore/wusbhc.c index 2054d4ee9774..0faca16df765 100644 --- a/drivers/usb/wusbcore/wusbhc.c +++ b/drivers/usb/wusbcore/wusbhc.c @@ -320,7 +320,7 @@ u8 wusb_cluster_id_get(void) u8 id; spin_lock(&wusb_cluster_ids_lock); id = find_first_zero_bit(wusb_cluster_id_table, CLUSTER_IDS); - if (id > CLUSTER_IDS) { + if (id >= CLUSTER_IDS) { id = 0; goto out; } -- cgit v1.2.3 From 45d1b7ae205e39e95ec65747f8871661aaa105e4 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 1 Mar 2011 22:40:57 -0800 Subject: usb-gadget: fix warning in ethernet Driver was taking max() of a size_t and u32 which causes complaint about comparison of different types. Stumbled on this accidently in my config, never used. Signed-off-by: Stephen Hemminger Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/u_ether.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 1eda968b5644..2ac1d2147325 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c @@ -241,7 +241,7 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags) size -= size % out->maxpacket; if (dev->port_usb->is_fixed) - size = max(size, dev->port_usb->fixed_out_len); + size = max_t(size_t, size, dev->port_usb->fixed_out_len); skb = alloc_skb(size + NET_IP_ALIGN, gfp_flags); if (skb == NULL) { -- cgit v1.2.3 From 5af9a6eb376bf7a9da738a56c01206e6d7e4a1b1 Mon Sep 17 00:00:00 2001 From: Huzaifa Sidhpurwala Date: Wed, 2 Mar 2011 11:17:49 +0530 Subject: USB: Remove delay_t unused variable from sierra_ms.c driver initialisation code trivial patch to remove unused delay_t varible Signed-off-by: Huzaifa Sidhpurwala Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/sierra_ms.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/sierra_ms.c b/drivers/usb/storage/sierra_ms.c index ceba512f84d0..1deca07c8265 100644 --- a/drivers/usb/storage/sierra_ms.c +++ b/drivers/usb/storage/sierra_ms.c @@ -126,13 +126,11 @@ static DEVICE_ATTR(truinst, S_IRUGO, show_truinst, NULL); int sierra_ms_init(struct us_data *us) { int result, retries; - signed long delay_t; struct swoc_info *swocInfo; struct usb_device *udev; struct Scsi_Host *sh; struct scsi_device *sd; - delay_t = 2; retries = 3; result = 0; udev = us->pusb_dev; -- cgit v1.2.3 From 2cd5bb29a42f305c5749571c8cd693fbe69cc28d Mon Sep 17 00:00:00 2001 From: Huzaifa Sidhpurwala Date: Wed, 2 Mar 2011 11:53:00 +0530 Subject: USB: Remove unused is_iso from fsl_udc_core.c is_iso variable is not used anywhere, remove it Signed-off-by: Huzaifa Sidhpurwala Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_udc_core.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 4c55eda4bd20..912cb8e63fe3 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -766,7 +766,6 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) struct fsl_req *req = container_of(_req, struct fsl_req, req); struct fsl_udc *udc; unsigned long flags; - int is_iso = 0; /* catch various bogus parameters */ if (!_req || !req->req.complete || !req->req.buf @@ -781,7 +780,6 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { if (req->req.length > ep->ep.maxpacket) return -EMSGSIZE; - is_iso = 1; } udc = ep->udc; -- cgit v1.2.3 From e4738e29bef8ed9bdd8a0606d0561557b4547649 Mon Sep 17 00:00:00 2001 From: Huzaifa Sidhpurwala Date: Wed, 2 Mar 2011 11:59:26 +0530 Subject: USB: Remove unused timeout from io_edgeport.c timeout variable is not used anywhere in int write_cmd_usb, remove it Signed-off-by: Huzaifa Sidhpurwala Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/io_edgeport.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 3b246d93cf22..76e3e502c23d 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -2343,7 +2343,6 @@ static int write_cmd_usb(struct edgeport_port *edge_port, usb_get_serial_data(edge_port->port->serial); int status = 0; struct urb *urb; - int timeout; usb_serial_debug_data(debug, &edge_port->port->dev, __func__, length, buffer); @@ -2376,8 +2375,6 @@ static int write_cmd_usb(struct edgeport_port *edge_port, return status; } - /* wait for command to finish */ - timeout = COMMAND_TIMEOUT; #if 0 wait_event(&edge_port->wait_command, !edge_port->commandPending); -- cgit v1.2.3 From 76e63665c338069085c4e0ca1b2093dc26258d7a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 20:15:14 -0500 Subject: Staging: hv: enable mouse driver to build But we disable it from automatically loading as that would be bad. This way people can build it easier and start cleaning it up, as it needs it. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Kconfig | 2 +- drivers/staging/hv/hv_mouse_drv.c | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/Kconfig b/drivers/staging/hv/Kconfig index 2985f0cd2916..d41f380d188f 100644 --- a/drivers/staging/hv/Kconfig +++ b/drivers/staging/hv/Kconfig @@ -38,7 +38,7 @@ config HYPERV_UTILS config HYPERV_MOUSE tristate "Microsoft Hyper-V mouse driver" - depends on HID && BROKEN + depends on HID default HYPERV help Select this option to enable the Hyper-V mouse driver. diff --git a/drivers/staging/hv/hv_mouse_drv.c b/drivers/staging/hv/hv_mouse_drv.c index 09f7d05f1495..760d21f6c195 100644 --- a/drivers/staging/hv/hv_mouse_drv.c +++ b/drivers/staging/hv/hv_mouse_drv.c @@ -316,6 +316,13 @@ static void __exit mousevsc_exit(void) mousevsc_drv_exit(); } +/* + * We don't want to automatically load this driver just yet, it's quite + * broken. It's safe if you want to load it yourself manually, but + * don't inflict it on unsuspecting users, that's just mean. + */ +#if 0 + /* * We use a PCI table to determine if we should autoload this driver This is * needed by distro tools to determine if the hyperv drivers should be @@ -327,6 +334,7 @@ const static struct pci_device_id microsoft_hv_pci_table[] = { { 0 } }; MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table); +#endif MODULE_LICENSE("GPL"); MODULE_VERSION(HV_DRV_VERSION); -- cgit v1.2.3 From e8290f9f73f9a53fbeffd8de8e30cafb41475ae2 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 20:19:05 -0500 Subject: Staging: hv: hv_mouse_drv.c: minor coding style cleanups Knock off some of the simple coding style issues in this file Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse_drv.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse_drv.c b/drivers/staging/hv/hv_mouse_drv.c index 760d21f6c195..55fc8c107cd4 100644 --- a/drivers/staging/hv/hv_mouse_drv.c +++ b/drivers/staging/hv/hv_mouse_drv.c @@ -33,7 +33,6 @@ #include #include -//#include "osd.h" #include "hv_api.h" #include "logging.h" #include "version_info.h" @@ -152,9 +151,8 @@ int mousevsc_remove(struct device *device) input_dev_ctx->connected = 0; } - if (!mousevsc_drv_obj->Base.dev_rm) { + if (!mousevsc_drv_obj->Base.dev_rm) return -1; - } /* * Call to the vsc driver to let it know that the device @@ -238,8 +236,6 @@ int mousevsc_drv_init(int (*pfn_drv_init)(struct hv_driver *pfn_drv_init)) struct mousevsc_drv_obj *input_drv_obj = &g_mousevsc_drv.drv_obj; struct driver_context *drv_ctx = &g_mousevsc_drv.drv_ctx; -// vmbus_get_interface(&input_drv_obj->Base.VmbusChannelInterface); - input_drv_obj->OnDeviceInfo = mousevsc_deviceinfo_callback; input_drv_obj->OnInputReport = mousevsc_inputreport_callback; input_drv_obj->OnReportDescriptor = mousevsc_reportdesc_callback; @@ -281,7 +277,9 @@ void mousevsc_drv_exit(void) current_dev = NULL; /* Get the device */ - ret = driver_for_each_device(&drv_ctx->driver, NULL, (void *)¤t_dev, mousevsc_drv_exit_cb); + ret = driver_for_each_device(&drv_ctx->driver, NULL, + (void *)¤t_dev, + mousevsc_drv_exit_cb); if (ret) printk(KERN_ERR "Can't find mouse device!\n"); -- cgit v1.2.3 From 16ecf02095bbd7f69539844dc15038359e4a29d3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 20:23:33 -0500 Subject: Staging: hv: mouse_vsc.c: fix brace coding style issues Minor brace coding style issue cleanups. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/mouse_vsc.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/mouse_vsc.c b/drivers/staging/hv/mouse_vsc.c index 6c8d0afb0b0f..9eb0b34af3c0 100644 --- a/drivers/staging/hv/mouse_vsc.c +++ b/drivers/staging/hv/mouse_vsc.c @@ -43,16 +43,14 @@ #include "vmbus_hid_protocol.h" -enum pipe_prot_msg_type -{ +enum pipe_prot_msg_type { PipeMessageInvalid = 0, PipeMessageData, PipeMessageMaximum }; -struct pipe_prt_msg -{ +struct pipe_prt_msg { enum pipe_prot_msg_type PacketType; u32 DataSize; char Data[1]; @@ -447,8 +445,7 @@ MousevscOnDeviceRemove(struct hv_device *Device) * * so that outstanding requests can be completed. */ - while (inputDevice->NumOutstandingRequests) - { + while (inputDevice->NumOutstandingRequests) { pr_info("waiting for %d requests to complete...", inputDevice->NumOutstandingRequests); udelay(100); @@ -497,9 +494,9 @@ MousevscOnSendCompletion(struct hv_device *Device, request = (void*)(unsigned long *) Packet->trans_id; - if (request == &inputDevice->ProtocolReq) - { - + if (request == &inputDevice->ProtocolReq) { + /* FIXME */ + /* Shouldn't we be doing something here? */ } PutInputDevice(Device); @@ -577,14 +574,12 @@ MousevscOnReceiveDeviceInfo( return; Cleanup: - if (InputDevice->HidDesc) - { + if (InputDevice->HidDesc) { kfree(InputDevice->HidDesc); InputDevice->HidDesc = NULL; } - if (InputDevice->ReportDesc) - { + if (InputDevice->ReportDesc) { kfree(InputDevice->ReportDesc); InputDevice->ReportDesc = NULL; } @@ -603,8 +598,7 @@ MousevscOnReceiveInputReport( { struct mousevsc_drv_obj *inputDriver; - if (!InputDevice->bInitializeComplete) - { + if (!InputDevice->bInitializeComplete) { pr_info("Initialization incomplete...ignoring InputReport msg"); return; } @@ -624,8 +618,7 @@ MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet) struct mousevsc_dev *inputDevice; inputDevice = MustGetInputDevice(Device); - if (!inputDevice) - { + if (!inputDevice) { pr_err("unable to get input device...device being destroyed?"); return; } @@ -700,8 +693,7 @@ void MousevscOnChannelCallback(void *Context) if (bytesRecvd > 0) { desc = (struct vmpacket_descriptor *)buffer; - switch (desc->type) - { + switch (desc->type) { case VM_PKT_COMP: MousevscOnSendCompletion(device, desc); -- cgit v1.2.3 From 6a5bfc17c31db88fc0afc70eabee1d68e60226fb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 20:31:05 -0500 Subject: Staging: hv: mouse_vsc: fix space coding style issues Lots of minor space cleanups to resolve coding style warnings and errors. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/mouse_vsc.c | 46 ++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/mouse_vsc.c b/drivers/staging/hv/mouse_vsc.c index 9eb0b34af3c0..659f118e4f3c 100644 --- a/drivers/staging/hv/mouse_vsc.c +++ b/drivers/staging/hv/mouse_vsc.c @@ -77,7 +77,7 @@ struct mousevsc_dev { /* 0 indicates the device is being destroyed */ atomic_t RefCount; int NumOutstandingRequests; - unsigned char bInitializeComplete; + unsigned char bInitializeComplete; struct mousevsc_prt_msg ProtocolReq; struct mousevsc_prt_msg ProtocolResp; /* Synchronize the request/response if needed */ @@ -97,7 +97,7 @@ struct mousevsc_dev { /* * Globals */ -static const char* gDriverName = "mousevsc"; +static const char *gDriverName = "mousevsc"; /* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */ static const struct hv_guid gMousevscDeviceType = { @@ -151,11 +151,11 @@ static inline void FreeInputDevice(struct mousevsc_dev *Device) /* * Get the inputdevice object if exists and its refcount > 1 */ -static inline struct mousevsc_dev* GetInputDevice(struct hv_device *Device) +static inline struct mousevsc_dev *GetInputDevice(struct hv_device *Device) { struct mousevsc_dev *inputDevice; - inputDevice = (struct mousevsc_dev*)Device->ext; + inputDevice = (struct mousevsc_dev *)Device->ext; // printk(KERN_ERR "-------------------------> REFCOUNT = %d", // inputDevice->RefCount); @@ -171,11 +171,11 @@ static inline struct mousevsc_dev* GetInputDevice(struct hv_device *Device) /* * Get the inputdevice object iff exists and its refcount > 0 */ -static inline struct mousevsc_dev* MustGetInputDevice(struct hv_device *Device) +static inline struct mousevsc_dev *MustGetInputDevice(struct hv_device *Device) { struct mousevsc_dev *inputDevice; - inputDevice = (struct mousevsc_dev*)Device->ext; + inputDevice = (struct mousevsc_dev *)Device->ext; if (inputDevice && atomic_read(&inputDevice->RefCount)) atomic_inc(&inputDevice->RefCount); @@ -189,7 +189,7 @@ static inline void PutInputDevice(struct hv_device *Device) { struct mousevsc_dev *inputDevice; - inputDevice = (struct mousevsc_dev*)Device->ext; + inputDevice = (struct mousevsc_dev *)Device->ext; atomic_dec(&inputDevice->RefCount); } @@ -197,11 +197,11 @@ static inline void PutInputDevice(struct hv_device *Device) /* * Drop ref count to 1 to effectively disable GetInputDevice() */ -static inline struct mousevsc_dev* ReleaseInputDevice(struct hv_device *Device) +static inline struct mousevsc_dev *ReleaseInputDevice(struct hv_device *Device) { struct mousevsc_dev *inputDevice; - inputDevice = (struct mousevsc_dev*)Device->ext; + inputDevice = (struct mousevsc_dev *)Device->ext; /* Busy wait until the ref drop to 2, then set it to 1 */ while (atomic_cmpxchg(&inputDevice->RefCount, 2, 1) != 2) @@ -213,11 +213,11 @@ static inline struct mousevsc_dev* ReleaseInputDevice(struct hv_device *Device) /* * Drop ref count to 0. No one can use InputDevice object. */ -static inline struct mousevsc_dev* FinalReleaseInputDevice(struct hv_device *Device) +static inline struct mousevsc_dev *FinalReleaseInputDevice(struct hv_device *Device) { struct mousevsc_dev *inputDevice; - inputDevice = (struct mousevsc_dev*)Device->ext; + inputDevice = (struct mousevsc_dev *)Device->ext; /* Busy wait until the ref drop to 1, then set it to 0 */ while (atomic_cmpxchg(&inputDevice->RefCount, 1, 0) != 1) @@ -335,7 +335,7 @@ Cleanup: int MousevscConnectToVsp(struct hv_device *Device) { - int ret=0; + int ret = 0; struct mousevsc_dev *inputDevice; struct mousevsc_prt_msg *request; struct mousevsc_prt_msg *response; @@ -374,7 +374,7 @@ MousevscConnectToVsp(struct hv_device *Device) (unsigned long)request, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - if ( ret != 0) { + if (ret != 0) { pr_err("unable to send SYNTHHID_PROTOCOL_REQUEST"); goto Cleanup; } @@ -431,7 +431,7 @@ int MousevscOnDeviceRemove(struct hv_device *Device) { struct mousevsc_dev *inputDevice; - int ret=0; + int ret = 0; pr_info("disabling input device (%p)...", Device->ext); @@ -492,7 +492,7 @@ MousevscOnSendCompletion(struct hv_device *Device, return; } - request = (void*)(unsigned long *) Packet->trans_id; + request = (void *)(unsigned long *)Packet->trans_id; if (request == &inputDevice->ProtocolReq) { /* FIXME */ @@ -504,9 +504,8 @@ MousevscOnSendCompletion(struct hv_device *Device, void MousevscOnReceiveDeviceInfo( - struct mousevsc_dev* InputDevice, - SYNTHHID_DEVICE_INFO* DeviceInfo - ) + struct mousevsc_dev *InputDevice, + SYNTHHID_DEVICE_INFO *DeviceInfo) { int ret = 0; struct hid_descriptor *desc; @@ -592,9 +591,8 @@ Cleanup: void MousevscOnReceiveInputReport( - struct mousevsc_dev* InputDevice, - SYNTHHID_INPUT_REPORT *InputReport - ) + struct mousevsc_dev *InputDevice, + SYNTHHID_INPUT_REPORT *InputReport) { struct mousevsc_drv_obj *inputDriver; @@ -632,7 +630,7 @@ MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet) return ; } - hidMsg = (SYNTHHID_MESSAGE*)&pipeMsg->Data[0]; + hidMsg = (SYNTHHID_MESSAGE *)&pipeMsg->Data[0]; switch (hidMsg->Header.Type) { case SynthHidProtocolResponse: @@ -649,11 +647,11 @@ MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet) * hid desc and report desc */ MousevscOnReceiveDeviceInfo(inputDevice, - (SYNTHHID_DEVICE_INFO*)&pipeMsg->Data[0]); + (SYNTHHID_DEVICE_INFO *)&pipeMsg->Data[0]); break; case SynthHidInputReport: MousevscOnReceiveInputReport(inputDevice, - (SYNTHHID_INPUT_REPORT*)&pipeMsg->Data[0]); + (SYNTHHID_INPUT_REPORT *)&pipeMsg->Data[0]); break; default: -- cgit v1.2.3 From e1f1a0e682bf739f7d2189495265fb3b01f8e85a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 17:33:26 -0800 Subject: Staging: hv: mouse_vsc: fix comment coding style Also mark this as a nice FIXME as we shouldn't ever care about the value of an atomic variable, which makes me seriously doubt the validity of this reference counting code. Odds are it can be ripped out completly, or at the very least, converted to using a kref. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/mouse_vsc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/mouse_vsc.c b/drivers/staging/hv/mouse_vsc.c index 659f118e4f3c..b75066d15ebb 100644 --- a/drivers/staging/hv/mouse_vsc.c +++ b/drivers/staging/hv/mouse_vsc.c @@ -157,8 +157,14 @@ static inline struct mousevsc_dev *GetInputDevice(struct hv_device *Device) inputDevice = (struct mousevsc_dev *)Device->ext; -// printk(KERN_ERR "-------------------------> REFCOUNT = %d", -// inputDevice->RefCount); +/* + * FIXME + * This sure isn't a valid thing to print for debugging, no matter + * what the intention is... + * + * printk(KERN_ERR "-------------------------> REFCOUNT = %d", + * inputDevice->RefCount); + */ if (inputDevice && atomic_read(&inputDevice->RefCount) > 1) atomic_inc(&inputDevice->RefCount); -- cgit v1.2.3 From 9dccaa63c706fb3a74ec90450b9dcaef0941828b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 17:42:50 -0800 Subject: Staging: hv: hv_mouse: delete mouse_vsc.c Move the mouse_vsc.c file into hv_mouse_drv.c as it makes no sense to have two files here, as we don't have to worry about the "closed vs. open" split that this code was originally written for. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Makefile | 2 +- drivers/staging/hv/hv_mouse_drv.c | 719 ++++++++++++++++++++++++++++++++++++ drivers/staging/hv/mouse_vsc.c | 759 -------------------------------------- 3 files changed, 720 insertions(+), 760 deletions(-) delete mode 100644 drivers/staging/hv/mouse_vsc.c (limited to 'drivers') diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index 0a7af4709c37..1290980ba89f 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -12,4 +12,4 @@ hv_storvsc-y := storvsc_drv.o storvsc.o hv_blkvsc-y := blkvsc_drv.o blkvsc.o hv_netvsc-y := netvsc_drv.o netvsc.o rndis_filter.o hv_utils-y := hv_util.o hv_kvp.o -hv_mouse-objs := hv_mouse_drv.o mouse_vsc.o +hv_mouse-objs := hv_mouse_drv.o diff --git a/drivers/staging/hv/hv_mouse_drv.c b/drivers/staging/hv/hv_mouse_drv.c index 55fc8c107cd4..fb3299a06887 100644 --- a/drivers/staging/hv/hv_mouse_drv.c +++ b/drivers/staging/hv/hv_mouse_drv.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include #include @@ -37,10 +39,727 @@ #include "logging.h" #include "version_info.h" #include "vmbus.h" +#include "vmbus_api.h" #include "mousevsc_api.h" +#include "channel.h" +#include "vmbus_packet_format.h" +#include "vmbus_hid_protocol.h" #define NBITS(x) (((x)/BITS_PER_LONG)+1) +enum pipe_prot_msg_type { + PipeMessageInvalid = 0, + PipeMessageData, + PipeMessageMaximum +}; + + +struct pipe_prt_msg { + enum pipe_prot_msg_type PacketType; + u32 DataSize; + char Data[1]; +}; + +/* + * Data types + */ +struct mousevsc_prt_msg { + enum pipe_prot_msg_type PacketType; + u32 DataSize; + union { + SYNTHHID_PROTOCOL_REQUEST Request; + SYNTHHID_PROTOCOL_RESPONSE Response; + SYNTHHID_DEVICE_INFO_ACK Ack; + } u; +}; + +/* + * Represents an mousevsc device + */ +struct mousevsc_dev { + struct hv_device *Device; + /* 0 indicates the device is being destroyed */ + atomic_t RefCount; + int NumOutstandingRequests; + unsigned char bInitializeComplete; + struct mousevsc_prt_msg ProtocolReq; + struct mousevsc_prt_msg ProtocolResp; + /* Synchronize the request/response if needed */ + wait_queue_head_t ProtocolWaitEvent; + wait_queue_head_t DeviceInfoWaitEvent; + int protocol_wait_condition; + int device_wait_condition; + int DeviceInfoStatus; + + struct hid_descriptor *HidDesc; + unsigned char *ReportDesc; + u32 ReportDescSize; + struct input_dev_info DeviceAttr; +}; + + +/* + * Globals + */ +static const char *gDriverName = "mousevsc"; + +/* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */ +static const struct hv_guid gMousevscDeviceType = { + .data = {0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c, + 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A} +}; + +/* + * Internal routines + */ +static int MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo); + +static int MousevscOnDeviceRemove(struct hv_device *Device); + +static void MousevscOnCleanup(struct hv_driver *Device); + +static void MousevscOnChannelCallback(void *Context); + +static int MousevscConnectToVsp(struct hv_device *Device); + +static void MousevscOnReceive(struct hv_device *Device, + struct vmpacket_descriptor *Packet); + +static inline struct mousevsc_dev *AllocInputDevice(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + + inputDevice = kzalloc(sizeof(struct mousevsc_dev), GFP_KERNEL); + + if (!inputDevice) + return NULL; + + /* + * Set to 2 to allow both inbound and outbound traffics + * (ie GetInputDevice() and MustGetInputDevice()) to proceed. + */ + atomic_cmpxchg(&inputDevice->RefCount, 0, 2); + + inputDevice->Device = Device; + Device->ext = inputDevice; + + return inputDevice; +} + +static inline void FreeInputDevice(struct mousevsc_dev *Device) +{ + WARN_ON(atomic_read(&Device->RefCount) == 0); + kfree(Device); +} + +/* + * Get the inputdevice object if exists and its refcount > 1 + */ +static inline struct mousevsc_dev *GetInputDevice(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + + inputDevice = (struct mousevsc_dev *)Device->ext; + +/* + * FIXME + * This sure isn't a valid thing to print for debugging, no matter + * what the intention is... + * + * printk(KERN_ERR "-------------------------> REFCOUNT = %d", + * inputDevice->RefCount); + */ + + if (inputDevice && atomic_read(&inputDevice->RefCount) > 1) + atomic_inc(&inputDevice->RefCount); + else + inputDevice = NULL; + + return inputDevice; +} + +/* + * Get the inputdevice object iff exists and its refcount > 0 + */ +static inline struct mousevsc_dev *MustGetInputDevice(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + + inputDevice = (struct mousevsc_dev *)Device->ext; + + if (inputDevice && atomic_read(&inputDevice->RefCount)) + atomic_inc(&inputDevice->RefCount); + else + inputDevice = NULL; + + return inputDevice; +} + +static inline void PutInputDevice(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + + inputDevice = (struct mousevsc_dev *)Device->ext; + + atomic_dec(&inputDevice->RefCount); +} + +/* + * Drop ref count to 1 to effectively disable GetInputDevice() + */ +static inline struct mousevsc_dev *ReleaseInputDevice(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + + inputDevice = (struct mousevsc_dev *)Device->ext; + + /* Busy wait until the ref drop to 2, then set it to 1 */ + while (atomic_cmpxchg(&inputDevice->RefCount, 2, 1) != 2) + udelay(100); + + return inputDevice; +} + +/* + * Drop ref count to 0. No one can use InputDevice object. + */ +static inline struct mousevsc_dev *FinalReleaseInputDevice(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + + inputDevice = (struct mousevsc_dev *)Device->ext; + + /* Busy wait until the ref drop to 1, then set it to 0 */ + while (atomic_cmpxchg(&inputDevice->RefCount, 1, 0) != 1) + udelay(100); + + Device->ext = NULL; + return inputDevice; +} + +/* + * + * Name: + * MousevscInitialize() + * + * Description: + * Main entry point + * + */ +int mouse_vsc_initialize(struct hv_driver *Driver) +{ + struct mousevsc_drv_obj *inputDriver = + (struct mousevsc_drv_obj *)Driver; + int ret = 0; + + Driver->name = gDriverName; + memcpy(&Driver->dev_type, &gMousevscDeviceType, + sizeof(struct hv_guid)); + + /* Setup the dispatch table */ + inputDriver->Base.dev_add = MousevscOnDeviceAdd; + inputDriver->Base.dev_rm = MousevscOnDeviceRemove; + inputDriver->Base.cleanup = MousevscOnCleanup; + + inputDriver->OnOpen = NULL; + inputDriver->OnClose = NULL; + + return ret; +} + +/* + * + * Name: + * MousevscOnDeviceAdd() + * + * Description: + * Callback when the device belonging to this driver is added + * + */ +int +MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) +{ + int ret = 0; + struct mousevsc_dev *inputDevice; + struct mousevsc_drv_obj *inputDriver; + struct input_dev_info deviceInfo; + + inputDevice = AllocInputDevice(Device); + + if (!inputDevice) { + ret = -1; + goto Cleanup; + } + + inputDevice->bInitializeComplete = false; + + /* Open the channel */ + ret = vmbus_open(Device->channel, + INPUTVSC_SEND_RING_BUFFER_SIZE, + INPUTVSC_RECV_RING_BUFFER_SIZE, + NULL, + 0, + MousevscOnChannelCallback, + Device + ); + + if (ret != 0) { + pr_err("unable to open channel: %d", ret); + return -1; + } + + pr_info("InputVsc channel open: %d", ret); + + ret = MousevscConnectToVsp(Device); + + if (ret != 0) { + pr_err("unable to connect channel: %d", ret); + + vmbus_close(Device->channel); + return ret; + } + + inputDriver = (struct mousevsc_drv_obj *)inputDevice->Device->drv; + + deviceInfo.VendorID = inputDevice->DeviceAttr.VendorID; + deviceInfo.ProductID = inputDevice->DeviceAttr.ProductID; + deviceInfo.VersionNumber = inputDevice->DeviceAttr.VersionNumber; + strcpy(deviceInfo.Name, "Microsoft Vmbus HID-compliant Mouse"); + + /* Send the device info back up */ + inputDriver->OnDeviceInfo(Device, &deviceInfo); + + /* Send the report desc back up */ + /* workaround SA-167 */ + if (inputDevice->ReportDesc[14] == 0x25) + inputDevice->ReportDesc[14] = 0x29; + + inputDriver->OnReportDescriptor(Device, inputDevice->ReportDesc, inputDevice->ReportDescSize); + + inputDevice->bInitializeComplete = true; + +Cleanup: + return ret; +} + +int +MousevscConnectToVsp(struct hv_device *Device) +{ + int ret = 0; + struct mousevsc_dev *inputDevice; + struct mousevsc_prt_msg *request; + struct mousevsc_prt_msg *response; + + inputDevice = GetInputDevice(Device); + + if (!inputDevice) { + pr_err("unable to get input device...device being destroyed?"); + return -1; + } + + init_waitqueue_head(&inputDevice->ProtocolWaitEvent); + init_waitqueue_head(&inputDevice->DeviceInfoWaitEvent); + + request = &inputDevice->ProtocolReq; + + /* + * Now, initiate the vsc/vsp initialization protocol on the open channel + */ + memset(request, sizeof(struct mousevsc_prt_msg), 0); + + request->PacketType = PipeMessageData; + request->DataSize = sizeof(SYNTHHID_PROTOCOL_REQUEST); + + request->u.Request.Header.Type = SynthHidProtocolRequest; + request->u.Request.Header.Size = sizeof(unsigned long); + request->u.Request.VersionRequested.AsDWord = + SYNTHHID_INPUT_VERSION_DWORD; + + pr_info("SYNTHHID_PROTOCOL_REQUEST..."); + + ret = vmbus_sendpacket(Device->channel, request, + sizeof(struct pipe_prt_msg) - + sizeof(unsigned char) + + sizeof(SYNTHHID_PROTOCOL_REQUEST), + (unsigned long)request, + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if (ret != 0) { + pr_err("unable to send SYNTHHID_PROTOCOL_REQUEST"); + goto Cleanup; + } + + inputDevice->protocol_wait_condition = 0; + wait_event_timeout(inputDevice->ProtocolWaitEvent, inputDevice->protocol_wait_condition, msecs_to_jiffies(1000)); + if (inputDevice->protocol_wait_condition == 0) { + ret = -ETIMEDOUT; + goto Cleanup; + } + + response = &inputDevice->ProtocolResp; + + if (!response->u.Response.Approved) { + pr_err("SYNTHHID_PROTOCOL_REQUEST failed (version %d)", + SYNTHHID_INPUT_VERSION_DWORD); + ret = -1; + goto Cleanup; + } + + inputDevice->device_wait_condition = 0; + wait_event_timeout(inputDevice->DeviceInfoWaitEvent, inputDevice->device_wait_condition, msecs_to_jiffies(1000)); + if (inputDevice->device_wait_condition == 0) { + ret = -ETIMEDOUT; + goto Cleanup; + } + + /* + * We should have gotten the device attr, hid desc and report + * desc at this point + */ + if (!inputDevice->DeviceInfoStatus) + pr_info("**** input channel up and running!! ****"); + else + ret = -1; + +Cleanup: + PutInputDevice(Device); + + return ret; +} + + +/* + * + * Name: + * MousevscOnDeviceRemove() + * + * Description: + * Callback when the our device is being removed + * + */ +int +MousevscOnDeviceRemove(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + int ret = 0; + + pr_info("disabling input device (%p)...", + Device->ext); + + inputDevice = ReleaseInputDevice(Device); + + + /* + * At this point, all outbound traffic should be disable. We only + * allow inbound traffic (responses) to proceed + * + * so that outstanding requests can be completed. + */ + while (inputDevice->NumOutstandingRequests) { + pr_info("waiting for %d requests to complete...", inputDevice->NumOutstandingRequests); + + udelay(100); + } + + pr_info("removing input device (%p)...", Device->ext); + + inputDevice = FinalReleaseInputDevice(Device); + + pr_info("input device (%p) safe to remove", inputDevice); + + /* Close the channel */ + vmbus_close(Device->channel); + + FreeInputDevice(inputDevice); + + return ret; +} + + +/* + * + * Name: + * MousevscOnCleanup() + * + * Description: + * Perform any cleanup when the driver is removed + */ +static void MousevscOnCleanup(struct hv_driver *drv) +{ +} + + +static void +MousevscOnSendCompletion(struct hv_device *Device, + struct vmpacket_descriptor *Packet) +{ + struct mousevsc_dev *inputDevice; + void *request; + + inputDevice = MustGetInputDevice(Device); + if (!inputDevice) { + pr_err("unable to get input device...device being destroyed?"); + return; + } + + request = (void *)(unsigned long *)Packet->trans_id; + + if (request == &inputDevice->ProtocolReq) { + /* FIXME */ + /* Shouldn't we be doing something here? */ + } + + PutInputDevice(Device); +} + +void +MousevscOnReceiveDeviceInfo( + struct mousevsc_dev *InputDevice, + SYNTHHID_DEVICE_INFO *DeviceInfo) +{ + int ret = 0; + struct hid_descriptor *desc; + struct mousevsc_prt_msg ack; + + /* Assume success for now */ + InputDevice->DeviceInfoStatus = 0; + + /* Save the device attr */ + memcpy(&InputDevice->DeviceAttr, &DeviceInfo->HidDeviceAttributes, sizeof(struct input_dev_info)); + + /* Save the hid desc */ + desc = (struct hid_descriptor *)DeviceInfo->HidDescriptorInformation; + WARN_ON(desc->bLength > 0); + + InputDevice->HidDesc = kzalloc(desc->bLength, GFP_KERNEL); + + if (!InputDevice->HidDesc) { + pr_err("unable to allocate hid descriptor - size %d", desc->bLength); + goto Cleanup; + } + + memcpy(InputDevice->HidDesc, desc, desc->bLength); + + /* Save the report desc */ + InputDevice->ReportDescSize = desc->desc[0].wDescriptorLength; + InputDevice->ReportDesc = kzalloc(InputDevice->ReportDescSize, + GFP_KERNEL); + + if (!InputDevice->ReportDesc) { + pr_err("unable to allocate report descriptor - size %d", + InputDevice->ReportDescSize); + goto Cleanup; + } + + memcpy(InputDevice->ReportDesc, + ((unsigned char *)desc) + desc->bLength, + desc->desc[0].wDescriptorLength); + + /* Send the ack */ + memset(&ack, sizeof(struct mousevsc_prt_msg), 0); + + ack.PacketType = PipeMessageData; + ack.DataSize = sizeof(SYNTHHID_DEVICE_INFO_ACK); + + ack.u.Ack.Header.Type = SynthHidInitialDeviceInfoAck; + ack.u.Ack.Header.Size = 1; + ack.u.Ack.Reserved = 0; + + ret = vmbus_sendpacket(InputDevice->Device->channel, + &ack, + sizeof(struct pipe_prt_msg) - sizeof(unsigned char) + sizeof(SYNTHHID_DEVICE_INFO_ACK), + (unsigned long)&ack, + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if (ret != 0) { + pr_err("unable to send SYNTHHID_DEVICE_INFO_ACK - ret %d", + ret); + goto Cleanup; + } + + InputDevice->device_wait_condition = 1; + wake_up(&InputDevice->DeviceInfoWaitEvent); + + return; + +Cleanup: + if (InputDevice->HidDesc) { + kfree(InputDevice->HidDesc); + InputDevice->HidDesc = NULL; + } + + if (InputDevice->ReportDesc) { + kfree(InputDevice->ReportDesc); + InputDevice->ReportDesc = NULL; + } + + InputDevice->DeviceInfoStatus = -1; + InputDevice->device_wait_condition = 1; + wake_up(&InputDevice->DeviceInfoWaitEvent); +} + + +void +MousevscOnReceiveInputReport( + struct mousevsc_dev *InputDevice, + SYNTHHID_INPUT_REPORT *InputReport) +{ + struct mousevsc_drv_obj *inputDriver; + + if (!InputDevice->bInitializeComplete) { + pr_info("Initialization incomplete...ignoring InputReport msg"); + return; + } + + inputDriver = (struct mousevsc_drv_obj *)InputDevice->Device->drv; + + inputDriver->OnInputReport(InputDevice->Device, + InputReport->ReportBuffer, + InputReport->Header.Size); +} + +void +MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet) +{ + struct pipe_prt_msg *pipeMsg; + SYNTHHID_MESSAGE *hidMsg; + struct mousevsc_dev *inputDevice; + + inputDevice = MustGetInputDevice(Device); + if (!inputDevice) { + pr_err("unable to get input device...device being destroyed?"); + return; + } + + pipeMsg = (struct pipe_prt_msg *)((unsigned long)Packet + (Packet->offset8 << 3)); + + if (pipeMsg->PacketType != PipeMessageData) { + pr_err("unknown pipe msg type - type %d len %d", + pipeMsg->PacketType, pipeMsg->DataSize); + PutInputDevice(Device); + return ; + } + + hidMsg = (SYNTHHID_MESSAGE *)&pipeMsg->Data[0]; + + switch (hidMsg->Header.Type) { + case SynthHidProtocolResponse: + memcpy(&inputDevice->ProtocolResp, pipeMsg, pipeMsg->DataSize+sizeof(struct pipe_prt_msg) - sizeof(unsigned char)); + inputDevice->protocol_wait_condition = 1; + wake_up(&inputDevice->ProtocolWaitEvent); + break; + + case SynthHidInitialDeviceInfo: + WARN_ON(pipeMsg->DataSize >= sizeof(struct input_dev_info)); + + /* + * Parse out the device info into device attr, + * hid desc and report desc + */ + MousevscOnReceiveDeviceInfo(inputDevice, + (SYNTHHID_DEVICE_INFO *)&pipeMsg->Data[0]); + break; + case SynthHidInputReport: + MousevscOnReceiveInputReport(inputDevice, + (SYNTHHID_INPUT_REPORT *)&pipeMsg->Data[0]); + + break; + default: + pr_err("unsupported hid msg type - type %d len %d", + hidMsg->Header.Type, hidMsg->Header.Size); + break; + } + + PutInputDevice(Device); +} + +void MousevscOnChannelCallback(void *Context) +{ + const int packetSize = 0x100; + int ret = 0; + struct hv_device *device = (struct hv_device *)Context; + struct mousevsc_dev *inputDevice; + + u32 bytesRecvd; + u64 requestId; + unsigned char packet[packetSize]; + struct vmpacket_descriptor *desc; + unsigned char *buffer = packet; + int bufferlen = packetSize; + + inputDevice = MustGetInputDevice(device); + + if (!inputDevice) { + pr_err("unable to get input device...device being destroyed?"); + return; + } + + do { + ret = vmbus_recvpacket_raw(device->channel, buffer, bufferlen, &bytesRecvd, &requestId); + + if (ret == 0) { + if (bytesRecvd > 0) { + desc = (struct vmpacket_descriptor *)buffer; + + switch (desc->type) { + case VM_PKT_COMP: + MousevscOnSendCompletion(device, + desc); + break; + + case VM_PKT_DATA_INBAND: + MousevscOnReceive(device, desc); + break; + + default: + pr_err("unhandled packet type %d, tid %llx len %d\n", + desc->type, + requestId, + bytesRecvd); + break; + } + + /* reset */ + if (bufferlen > packetSize) { + kfree(buffer); + + buffer = packet; + bufferlen = packetSize; + } + } else { + /* + * pr_debug("nothing else to read..."); + * reset + */ + if (bufferlen > packetSize) { + kfree(buffer); + + buffer = packet; + bufferlen = packetSize; + } + break; + } + } else if (ret == -2) { + /* Handle large packet */ + bufferlen = bytesRecvd; + buffer = kzalloc(bytesRecvd, GFP_KERNEL); + + if (buffer == NULL) { + buffer = packet; + bufferlen = packetSize; + + /* Try again next time around */ + pr_err("unable to allocate buffer of size %d!", + bytesRecvd); + break; + } + } + } while (1); + + PutInputDevice(device); + + return; +} /* * Data types diff --git a/drivers/staging/hv/mouse_vsc.c b/drivers/staging/hv/mouse_vsc.c deleted file mode 100644 index b75066d15ebb..000000000000 --- a/drivers/staging/hv/mouse_vsc.c +++ /dev/null @@ -1,759 +0,0 @@ -/* - * Copyright 2009 Citrix Systems, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * For clarity, the licensor of this program does not intend that a - * "derivative work" include code which compiles header information from - * this program. - * - * This code has been modified from its original by - * Hank Janssen - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "hv_api.h" -#include "vmbus.h" -#include "vmbus_api.h" -#include "channel.h" -#include "logging.h" - -#include "mousevsc_api.h" -#include "vmbus_packet_format.h" -#include "vmbus_hid_protocol.h" - - -enum pipe_prot_msg_type { - PipeMessageInvalid = 0, - PipeMessageData, - PipeMessageMaximum -}; - - -struct pipe_prt_msg { - enum pipe_prot_msg_type PacketType; - u32 DataSize; - char Data[1]; -}; - -/* - * Data types - */ -struct mousevsc_prt_msg { - enum pipe_prot_msg_type PacketType; - u32 DataSize; - union { - SYNTHHID_PROTOCOL_REQUEST Request; - SYNTHHID_PROTOCOL_RESPONSE Response; - SYNTHHID_DEVICE_INFO_ACK Ack; - } u; -}; - -/* - * Represents an mousevsc device - */ -struct mousevsc_dev { - struct hv_device *Device; - /* 0 indicates the device is being destroyed */ - atomic_t RefCount; - int NumOutstandingRequests; - unsigned char bInitializeComplete; - struct mousevsc_prt_msg ProtocolReq; - struct mousevsc_prt_msg ProtocolResp; - /* Synchronize the request/response if needed */ - wait_queue_head_t ProtocolWaitEvent; - wait_queue_head_t DeviceInfoWaitEvent; - int protocol_wait_condition; - int device_wait_condition; - int DeviceInfoStatus; - - struct hid_descriptor *HidDesc; - unsigned char *ReportDesc; - u32 ReportDescSize; - struct input_dev_info DeviceAttr; -}; - - -/* - * Globals - */ -static const char *gDriverName = "mousevsc"; - -/* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */ -static const struct hv_guid gMousevscDeviceType = { - .data = {0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c, - 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A} -}; - -/* - * Internal routines - */ -static int MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo); - -static int MousevscOnDeviceRemove(struct hv_device *Device); - -static void MousevscOnCleanup(struct hv_driver *Device); - -static void MousevscOnChannelCallback(void *Context); - -static int MousevscConnectToVsp(struct hv_device *Device); - -static void MousevscOnReceive(struct hv_device *Device, - struct vmpacket_descriptor *Packet); - -static inline struct mousevsc_dev *AllocInputDevice(struct hv_device *Device) -{ - struct mousevsc_dev *inputDevice; - - inputDevice = kzalloc(sizeof(struct mousevsc_dev), GFP_KERNEL); - - if (!inputDevice) - return NULL; - - /* - * Set to 2 to allow both inbound and outbound traffics - * (ie GetInputDevice() and MustGetInputDevice()) to proceed. - */ - atomic_cmpxchg(&inputDevice->RefCount, 0, 2); - - inputDevice->Device = Device; - Device->ext = inputDevice; - - return inputDevice; -} - -static inline void FreeInputDevice(struct mousevsc_dev *Device) -{ - WARN_ON(atomic_read(&Device->RefCount) == 0); - kfree(Device); -} - -/* - * Get the inputdevice object if exists and its refcount > 1 - */ -static inline struct mousevsc_dev *GetInputDevice(struct hv_device *Device) -{ - struct mousevsc_dev *inputDevice; - - inputDevice = (struct mousevsc_dev *)Device->ext; - -/* - * FIXME - * This sure isn't a valid thing to print for debugging, no matter - * what the intention is... - * - * printk(KERN_ERR "-------------------------> REFCOUNT = %d", - * inputDevice->RefCount); - */ - - if (inputDevice && atomic_read(&inputDevice->RefCount) > 1) - atomic_inc(&inputDevice->RefCount); - else - inputDevice = NULL; - - return inputDevice; -} - -/* - * Get the inputdevice object iff exists and its refcount > 0 - */ -static inline struct mousevsc_dev *MustGetInputDevice(struct hv_device *Device) -{ - struct mousevsc_dev *inputDevice; - - inputDevice = (struct mousevsc_dev *)Device->ext; - - if (inputDevice && atomic_read(&inputDevice->RefCount)) - atomic_inc(&inputDevice->RefCount); - else - inputDevice = NULL; - - return inputDevice; -} - -static inline void PutInputDevice(struct hv_device *Device) -{ - struct mousevsc_dev *inputDevice; - - inputDevice = (struct mousevsc_dev *)Device->ext; - - atomic_dec(&inputDevice->RefCount); -} - -/* - * Drop ref count to 1 to effectively disable GetInputDevice() - */ -static inline struct mousevsc_dev *ReleaseInputDevice(struct hv_device *Device) -{ - struct mousevsc_dev *inputDevice; - - inputDevice = (struct mousevsc_dev *)Device->ext; - - /* Busy wait until the ref drop to 2, then set it to 1 */ - while (atomic_cmpxchg(&inputDevice->RefCount, 2, 1) != 2) - udelay(100); - - return inputDevice; -} - -/* - * Drop ref count to 0. No one can use InputDevice object. - */ -static inline struct mousevsc_dev *FinalReleaseInputDevice(struct hv_device *Device) -{ - struct mousevsc_dev *inputDevice; - - inputDevice = (struct mousevsc_dev *)Device->ext; - - /* Busy wait until the ref drop to 1, then set it to 0 */ - while (atomic_cmpxchg(&inputDevice->RefCount, 1, 0) != 1) - udelay(100); - - Device->ext = NULL; - return inputDevice; -} - -/* - * - * Name: - * MousevscInitialize() - * - * Description: - * Main entry point - * - */ -int mouse_vsc_initialize(struct hv_driver *Driver) -{ - struct mousevsc_drv_obj *inputDriver = - (struct mousevsc_drv_obj *)Driver; - int ret = 0; - - Driver->name = gDriverName; - memcpy(&Driver->dev_type, &gMousevscDeviceType, - sizeof(struct hv_guid)); - - /* Setup the dispatch table */ - inputDriver->Base.dev_add = MousevscOnDeviceAdd; - inputDriver->Base.dev_rm = MousevscOnDeviceRemove; - inputDriver->Base.cleanup = MousevscOnCleanup; - - inputDriver->OnOpen = NULL; - inputDriver->OnClose = NULL; - - return ret; -} - -/* - * - * Name: - * MousevscOnDeviceAdd() - * - * Description: - * Callback when the device belonging to this driver is added - * - */ -int -MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) -{ - int ret = 0; - struct mousevsc_dev *inputDevice; - struct mousevsc_drv_obj *inputDriver; - struct input_dev_info deviceInfo; - - inputDevice = AllocInputDevice(Device); - - if (!inputDevice) { - ret = -1; - goto Cleanup; - } - - inputDevice->bInitializeComplete = false; - - /* Open the channel */ - ret = vmbus_open(Device->channel, - INPUTVSC_SEND_RING_BUFFER_SIZE, - INPUTVSC_RECV_RING_BUFFER_SIZE, - NULL, - 0, - MousevscOnChannelCallback, - Device - ); - - if (ret != 0) { - pr_err("unable to open channel: %d", ret); - return -1; - } - - pr_info("InputVsc channel open: %d", ret); - - ret = MousevscConnectToVsp(Device); - - if (ret != 0) { - pr_err("unable to connect channel: %d", ret); - - vmbus_close(Device->channel); - return ret; - } - - inputDriver = (struct mousevsc_drv_obj *)inputDevice->Device->drv; - - deviceInfo.VendorID = inputDevice->DeviceAttr.VendorID; - deviceInfo.ProductID = inputDevice->DeviceAttr.ProductID; - deviceInfo.VersionNumber = inputDevice->DeviceAttr.VersionNumber; - strcpy(deviceInfo.Name, "Microsoft Vmbus HID-compliant Mouse"); - - /* Send the device info back up */ - inputDriver->OnDeviceInfo(Device, &deviceInfo); - - /* Send the report desc back up */ - /* workaround SA-167 */ - if (inputDevice->ReportDesc[14] == 0x25) - inputDevice->ReportDesc[14] = 0x29; - - inputDriver->OnReportDescriptor(Device, inputDevice->ReportDesc, inputDevice->ReportDescSize); - - inputDevice->bInitializeComplete = true; - -Cleanup: - return ret; -} - -int -MousevscConnectToVsp(struct hv_device *Device) -{ - int ret = 0; - struct mousevsc_dev *inputDevice; - struct mousevsc_prt_msg *request; - struct mousevsc_prt_msg *response; - - inputDevice = GetInputDevice(Device); - - if (!inputDevice) { - pr_err("unable to get input device...device being destroyed?"); - return -1; - } - - init_waitqueue_head(&inputDevice->ProtocolWaitEvent); - init_waitqueue_head(&inputDevice->DeviceInfoWaitEvent); - - request = &inputDevice->ProtocolReq; - - /* - * Now, initiate the vsc/vsp initialization protocol on the open channel - */ - memset(request, sizeof(struct mousevsc_prt_msg), 0); - - request->PacketType = PipeMessageData; - request->DataSize = sizeof(SYNTHHID_PROTOCOL_REQUEST); - - request->u.Request.Header.Type = SynthHidProtocolRequest; - request->u.Request.Header.Size = sizeof(unsigned long); - request->u.Request.VersionRequested.AsDWord = - SYNTHHID_INPUT_VERSION_DWORD; - - pr_info("SYNTHHID_PROTOCOL_REQUEST..."); - - ret = vmbus_sendpacket(Device->channel, request, - sizeof(struct pipe_prt_msg) - - sizeof(unsigned char) + - sizeof(SYNTHHID_PROTOCOL_REQUEST), - (unsigned long)request, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - if (ret != 0) { - pr_err("unable to send SYNTHHID_PROTOCOL_REQUEST"); - goto Cleanup; - } - - inputDevice->protocol_wait_condition = 0; - wait_event_timeout(inputDevice->ProtocolWaitEvent, inputDevice->protocol_wait_condition, msecs_to_jiffies(1000)); - if (inputDevice->protocol_wait_condition == 0) { - ret = -ETIMEDOUT; - goto Cleanup; - } - - response = &inputDevice->ProtocolResp; - - if (!response->u.Response.Approved) { - pr_err("SYNTHHID_PROTOCOL_REQUEST failed (version %d)", - SYNTHHID_INPUT_VERSION_DWORD); - ret = -1; - goto Cleanup; - } - - inputDevice->device_wait_condition = 0; - wait_event_timeout(inputDevice->DeviceInfoWaitEvent, inputDevice->device_wait_condition, msecs_to_jiffies(1000)); - if (inputDevice->device_wait_condition == 0) { - ret = -ETIMEDOUT; - goto Cleanup; - } - - /* - * We should have gotten the device attr, hid desc and report - * desc at this point - */ - if (!inputDevice->DeviceInfoStatus) - pr_info("**** input channel up and running!! ****"); - else - ret = -1; - -Cleanup: - PutInputDevice(Device); - - return ret; -} - - -/* - * - * Name: - * MousevscOnDeviceRemove() - * - * Description: - * Callback when the our device is being removed - * - */ -int -MousevscOnDeviceRemove(struct hv_device *Device) -{ - struct mousevsc_dev *inputDevice; - int ret = 0; - - pr_info("disabling input device (%p)...", - Device->ext); - - inputDevice = ReleaseInputDevice(Device); - - - /* - * At this point, all outbound traffic should be disable. We only - * allow inbound traffic (responses) to proceed - * - * so that outstanding requests can be completed. - */ - while (inputDevice->NumOutstandingRequests) { - pr_info("waiting for %d requests to complete...", inputDevice->NumOutstandingRequests); - - udelay(100); - } - - pr_info("removing input device (%p)...", Device->ext); - - inputDevice = FinalReleaseInputDevice(Device); - - pr_info("input device (%p) safe to remove", inputDevice); - - /* Close the channel */ - vmbus_close(Device->channel); - - FreeInputDevice(inputDevice); - - return ret; -} - - -/* - * - * Name: - * MousevscOnCleanup() - * - * Description: - * Perform any cleanup when the driver is removed - */ -static void MousevscOnCleanup(struct hv_driver *drv) -{ -} - - -static void -MousevscOnSendCompletion(struct hv_device *Device, - struct vmpacket_descriptor *Packet) -{ - struct mousevsc_dev *inputDevice; - void *request; - - inputDevice = MustGetInputDevice(Device); - if (!inputDevice) { - pr_err("unable to get input device...device being destroyed?"); - return; - } - - request = (void *)(unsigned long *)Packet->trans_id; - - if (request == &inputDevice->ProtocolReq) { - /* FIXME */ - /* Shouldn't we be doing something here? */ - } - - PutInputDevice(Device); -} - -void -MousevscOnReceiveDeviceInfo( - struct mousevsc_dev *InputDevice, - SYNTHHID_DEVICE_INFO *DeviceInfo) -{ - int ret = 0; - struct hid_descriptor *desc; - struct mousevsc_prt_msg ack; - - /* Assume success for now */ - InputDevice->DeviceInfoStatus = 0; - - /* Save the device attr */ - memcpy(&InputDevice->DeviceAttr, &DeviceInfo->HidDeviceAttributes, sizeof(struct input_dev_info)); - - /* Save the hid desc */ - desc = (struct hid_descriptor *)DeviceInfo->HidDescriptorInformation; - WARN_ON(desc->bLength > 0); - - InputDevice->HidDesc = kzalloc(desc->bLength, GFP_KERNEL); - - if (!InputDevice->HidDesc) { - pr_err("unable to allocate hid descriptor - size %d", desc->bLength); - goto Cleanup; - } - - memcpy(InputDevice->HidDesc, desc, desc->bLength); - - /* Save the report desc */ - InputDevice->ReportDescSize = desc->desc[0].wDescriptorLength; - InputDevice->ReportDesc = kzalloc(InputDevice->ReportDescSize, - GFP_KERNEL); - - if (!InputDevice->ReportDesc) { - pr_err("unable to allocate report descriptor - size %d", - InputDevice->ReportDescSize); - goto Cleanup; - } - - memcpy(InputDevice->ReportDesc, - ((unsigned char *)desc) + desc->bLength, - desc->desc[0].wDescriptorLength); - - /* Send the ack */ - memset(&ack, sizeof(struct mousevsc_prt_msg), 0); - - ack.PacketType = PipeMessageData; - ack.DataSize = sizeof(SYNTHHID_DEVICE_INFO_ACK); - - ack.u.Ack.Header.Type = SynthHidInitialDeviceInfoAck; - ack.u.Ack.Header.Size = 1; - ack.u.Ack.Reserved = 0; - - ret = vmbus_sendpacket(InputDevice->Device->channel, - &ack, - sizeof(struct pipe_prt_msg) - sizeof(unsigned char) + sizeof(SYNTHHID_DEVICE_INFO_ACK), - (unsigned long)&ack, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - if (ret != 0) { - pr_err("unable to send SYNTHHID_DEVICE_INFO_ACK - ret %d", - ret); - goto Cleanup; - } - - InputDevice->device_wait_condition = 1; - wake_up(&InputDevice->DeviceInfoWaitEvent); - - return; - -Cleanup: - if (InputDevice->HidDesc) { - kfree(InputDevice->HidDesc); - InputDevice->HidDesc = NULL; - } - - if (InputDevice->ReportDesc) { - kfree(InputDevice->ReportDesc); - InputDevice->ReportDesc = NULL; - } - - InputDevice->DeviceInfoStatus = -1; - InputDevice->device_wait_condition = 1; - wake_up(&InputDevice->DeviceInfoWaitEvent); -} - - -void -MousevscOnReceiveInputReport( - struct mousevsc_dev *InputDevice, - SYNTHHID_INPUT_REPORT *InputReport) -{ - struct mousevsc_drv_obj *inputDriver; - - if (!InputDevice->bInitializeComplete) { - pr_info("Initialization incomplete...ignoring InputReport msg"); - return; - } - - inputDriver = (struct mousevsc_drv_obj *)InputDevice->Device->drv; - - inputDriver->OnInputReport(InputDevice->Device, - InputReport->ReportBuffer, - InputReport->Header.Size); -} - -void -MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet) -{ - struct pipe_prt_msg *pipeMsg; - SYNTHHID_MESSAGE *hidMsg; - struct mousevsc_dev *inputDevice; - - inputDevice = MustGetInputDevice(Device); - if (!inputDevice) { - pr_err("unable to get input device...device being destroyed?"); - return; - } - - pipeMsg = (struct pipe_prt_msg *)((unsigned long)Packet + (Packet->offset8 << 3)); - - if (pipeMsg->PacketType != PipeMessageData) { - pr_err("unknown pipe msg type - type %d len %d", - pipeMsg->PacketType, pipeMsg->DataSize); - PutInputDevice(Device); - return ; - } - - hidMsg = (SYNTHHID_MESSAGE *)&pipeMsg->Data[0]; - - switch (hidMsg->Header.Type) { - case SynthHidProtocolResponse: - memcpy(&inputDevice->ProtocolResp, pipeMsg, pipeMsg->DataSize+sizeof(struct pipe_prt_msg) - sizeof(unsigned char)); - inputDevice->protocol_wait_condition = 1; - wake_up(&inputDevice->ProtocolWaitEvent); - break; - - case SynthHidInitialDeviceInfo: - WARN_ON(pipeMsg->DataSize >= sizeof(struct input_dev_info)); - - /* - * Parse out the device info into device attr, - * hid desc and report desc - */ - MousevscOnReceiveDeviceInfo(inputDevice, - (SYNTHHID_DEVICE_INFO *)&pipeMsg->Data[0]); - break; - case SynthHidInputReport: - MousevscOnReceiveInputReport(inputDevice, - (SYNTHHID_INPUT_REPORT *)&pipeMsg->Data[0]); - - break; - default: - pr_err("unsupported hid msg type - type %d len %d", - hidMsg->Header.Type, hidMsg->Header.Size); - break; - } - - PutInputDevice(Device); -} - -void MousevscOnChannelCallback(void *Context) -{ - const int packetSize = 0x100; - int ret = 0; - struct hv_device *device = (struct hv_device *)Context; - struct mousevsc_dev *inputDevice; - - u32 bytesRecvd; - u64 requestId; - unsigned char packet[packetSize]; - struct vmpacket_descriptor *desc; - unsigned char *buffer = packet; - int bufferlen = packetSize; - - inputDevice = MustGetInputDevice(device); - - if (!inputDevice) { - pr_err("unable to get input device...device being destroyed?"); - return; - } - - do { - ret = vmbus_recvpacket_raw(device->channel, buffer, bufferlen, &bytesRecvd, &requestId); - - if (ret == 0) { - if (bytesRecvd > 0) { - desc = (struct vmpacket_descriptor *)buffer; - - switch (desc->type) { - case VM_PKT_COMP: - MousevscOnSendCompletion(device, - desc); - break; - - case VM_PKT_DATA_INBAND: - MousevscOnReceive(device, desc); - break; - - default: - pr_err("unhandled packet type %d, tid %llx len %d\n", - desc->type, - requestId, - bytesRecvd); - break; - } - - /* reset */ - if (bufferlen > packetSize) { - kfree(buffer); - - buffer = packet; - bufferlen = packetSize; - } - } else { - /* - * pr_debug("nothing else to read..."); - * reset - */ - if (bufferlen > packetSize) { - kfree(buffer); - - buffer = packet; - bufferlen = packetSize; - } - break; - } - } else if (ret == -2) { - /* Handle large packet */ - bufferlen = bytesRecvd; - buffer = kzalloc(bytesRecvd, GFP_KERNEL); - - if (buffer == NULL) { - buffer = packet; - bufferlen = packetSize; - - /* Try again next time around */ - pr_err("unable to allocate buffer of size %d!", - bytesRecvd); - break; - } - } - } while (1); - - PutInputDevice(device); - - return; -} - -- cgit v1.2.3 From 8fd16ff35c97f3bd0ec8ff25f0f86a95e638d9ad Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 17:46:00 -0800 Subject: Staging: hv: hv_mouse: rename hv_mouse_drv.c As there's only one file for this driver, just name it the same as the end module name, saving one build/link step and making it simpler in the end. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Makefile | 1 - drivers/staging/hv/hv_mouse.c | 1060 +++++++++++++++++++++++++++++++++++++ drivers/staging/hv/hv_mouse_drv.c | 1060 ------------------------------------- 3 files changed, 1060 insertions(+), 1061 deletions(-) create mode 100644 drivers/staging/hv/hv_mouse.c delete mode 100644 drivers/staging/hv/hv_mouse_drv.c (limited to 'drivers') diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index 1290980ba89f..abeb2f7ef4e2 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -12,4 +12,3 @@ hv_storvsc-y := storvsc_drv.o storvsc.o hv_blkvsc-y := blkvsc_drv.o blkvsc.o hv_netvsc-y := netvsc_drv.o netvsc.o rndis_filter.o hv_utils-y := hv_util.o hv_kvp.o -hv_mouse-objs := hv_mouse_drv.o diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c new file mode 100644 index 000000000000..fb3299a06887 --- /dev/null +++ b/drivers/staging/hv/hv_mouse.c @@ -0,0 +1,1060 @@ +/* + * Copyright 2009 Citrix Systems, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * For clarity, the licensor of this program does not intend that a + * "derivative work" include code which compiles header information from + * this program. + * + * This code has been modified from its original by + * Hank Janssen + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hv_api.h" +#include "logging.h" +#include "version_info.h" +#include "vmbus.h" +#include "vmbus_api.h" +#include "mousevsc_api.h" +#include "channel.h" +#include "vmbus_packet_format.h" +#include "vmbus_hid_protocol.h" + +#define NBITS(x) (((x)/BITS_PER_LONG)+1) + +enum pipe_prot_msg_type { + PipeMessageInvalid = 0, + PipeMessageData, + PipeMessageMaximum +}; + + +struct pipe_prt_msg { + enum pipe_prot_msg_type PacketType; + u32 DataSize; + char Data[1]; +}; + +/* + * Data types + */ +struct mousevsc_prt_msg { + enum pipe_prot_msg_type PacketType; + u32 DataSize; + union { + SYNTHHID_PROTOCOL_REQUEST Request; + SYNTHHID_PROTOCOL_RESPONSE Response; + SYNTHHID_DEVICE_INFO_ACK Ack; + } u; +}; + +/* + * Represents an mousevsc device + */ +struct mousevsc_dev { + struct hv_device *Device; + /* 0 indicates the device is being destroyed */ + atomic_t RefCount; + int NumOutstandingRequests; + unsigned char bInitializeComplete; + struct mousevsc_prt_msg ProtocolReq; + struct mousevsc_prt_msg ProtocolResp; + /* Synchronize the request/response if needed */ + wait_queue_head_t ProtocolWaitEvent; + wait_queue_head_t DeviceInfoWaitEvent; + int protocol_wait_condition; + int device_wait_condition; + int DeviceInfoStatus; + + struct hid_descriptor *HidDesc; + unsigned char *ReportDesc; + u32 ReportDescSize; + struct input_dev_info DeviceAttr; +}; + + +/* + * Globals + */ +static const char *gDriverName = "mousevsc"; + +/* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */ +static const struct hv_guid gMousevscDeviceType = { + .data = {0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c, + 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A} +}; + +/* + * Internal routines + */ +static int MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo); + +static int MousevscOnDeviceRemove(struct hv_device *Device); + +static void MousevscOnCleanup(struct hv_driver *Device); + +static void MousevscOnChannelCallback(void *Context); + +static int MousevscConnectToVsp(struct hv_device *Device); + +static void MousevscOnReceive(struct hv_device *Device, + struct vmpacket_descriptor *Packet); + +static inline struct mousevsc_dev *AllocInputDevice(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + + inputDevice = kzalloc(sizeof(struct mousevsc_dev), GFP_KERNEL); + + if (!inputDevice) + return NULL; + + /* + * Set to 2 to allow both inbound and outbound traffics + * (ie GetInputDevice() and MustGetInputDevice()) to proceed. + */ + atomic_cmpxchg(&inputDevice->RefCount, 0, 2); + + inputDevice->Device = Device; + Device->ext = inputDevice; + + return inputDevice; +} + +static inline void FreeInputDevice(struct mousevsc_dev *Device) +{ + WARN_ON(atomic_read(&Device->RefCount) == 0); + kfree(Device); +} + +/* + * Get the inputdevice object if exists and its refcount > 1 + */ +static inline struct mousevsc_dev *GetInputDevice(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + + inputDevice = (struct mousevsc_dev *)Device->ext; + +/* + * FIXME + * This sure isn't a valid thing to print for debugging, no matter + * what the intention is... + * + * printk(KERN_ERR "-------------------------> REFCOUNT = %d", + * inputDevice->RefCount); + */ + + if (inputDevice && atomic_read(&inputDevice->RefCount) > 1) + atomic_inc(&inputDevice->RefCount); + else + inputDevice = NULL; + + return inputDevice; +} + +/* + * Get the inputdevice object iff exists and its refcount > 0 + */ +static inline struct mousevsc_dev *MustGetInputDevice(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + + inputDevice = (struct mousevsc_dev *)Device->ext; + + if (inputDevice && atomic_read(&inputDevice->RefCount)) + atomic_inc(&inputDevice->RefCount); + else + inputDevice = NULL; + + return inputDevice; +} + +static inline void PutInputDevice(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + + inputDevice = (struct mousevsc_dev *)Device->ext; + + atomic_dec(&inputDevice->RefCount); +} + +/* + * Drop ref count to 1 to effectively disable GetInputDevice() + */ +static inline struct mousevsc_dev *ReleaseInputDevice(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + + inputDevice = (struct mousevsc_dev *)Device->ext; + + /* Busy wait until the ref drop to 2, then set it to 1 */ + while (atomic_cmpxchg(&inputDevice->RefCount, 2, 1) != 2) + udelay(100); + + return inputDevice; +} + +/* + * Drop ref count to 0. No one can use InputDevice object. + */ +static inline struct mousevsc_dev *FinalReleaseInputDevice(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + + inputDevice = (struct mousevsc_dev *)Device->ext; + + /* Busy wait until the ref drop to 1, then set it to 0 */ + while (atomic_cmpxchg(&inputDevice->RefCount, 1, 0) != 1) + udelay(100); + + Device->ext = NULL; + return inputDevice; +} + +/* + * + * Name: + * MousevscInitialize() + * + * Description: + * Main entry point + * + */ +int mouse_vsc_initialize(struct hv_driver *Driver) +{ + struct mousevsc_drv_obj *inputDriver = + (struct mousevsc_drv_obj *)Driver; + int ret = 0; + + Driver->name = gDriverName; + memcpy(&Driver->dev_type, &gMousevscDeviceType, + sizeof(struct hv_guid)); + + /* Setup the dispatch table */ + inputDriver->Base.dev_add = MousevscOnDeviceAdd; + inputDriver->Base.dev_rm = MousevscOnDeviceRemove; + inputDriver->Base.cleanup = MousevscOnCleanup; + + inputDriver->OnOpen = NULL; + inputDriver->OnClose = NULL; + + return ret; +} + +/* + * + * Name: + * MousevscOnDeviceAdd() + * + * Description: + * Callback when the device belonging to this driver is added + * + */ +int +MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) +{ + int ret = 0; + struct mousevsc_dev *inputDevice; + struct mousevsc_drv_obj *inputDriver; + struct input_dev_info deviceInfo; + + inputDevice = AllocInputDevice(Device); + + if (!inputDevice) { + ret = -1; + goto Cleanup; + } + + inputDevice->bInitializeComplete = false; + + /* Open the channel */ + ret = vmbus_open(Device->channel, + INPUTVSC_SEND_RING_BUFFER_SIZE, + INPUTVSC_RECV_RING_BUFFER_SIZE, + NULL, + 0, + MousevscOnChannelCallback, + Device + ); + + if (ret != 0) { + pr_err("unable to open channel: %d", ret); + return -1; + } + + pr_info("InputVsc channel open: %d", ret); + + ret = MousevscConnectToVsp(Device); + + if (ret != 0) { + pr_err("unable to connect channel: %d", ret); + + vmbus_close(Device->channel); + return ret; + } + + inputDriver = (struct mousevsc_drv_obj *)inputDevice->Device->drv; + + deviceInfo.VendorID = inputDevice->DeviceAttr.VendorID; + deviceInfo.ProductID = inputDevice->DeviceAttr.ProductID; + deviceInfo.VersionNumber = inputDevice->DeviceAttr.VersionNumber; + strcpy(deviceInfo.Name, "Microsoft Vmbus HID-compliant Mouse"); + + /* Send the device info back up */ + inputDriver->OnDeviceInfo(Device, &deviceInfo); + + /* Send the report desc back up */ + /* workaround SA-167 */ + if (inputDevice->ReportDesc[14] == 0x25) + inputDevice->ReportDesc[14] = 0x29; + + inputDriver->OnReportDescriptor(Device, inputDevice->ReportDesc, inputDevice->ReportDescSize); + + inputDevice->bInitializeComplete = true; + +Cleanup: + return ret; +} + +int +MousevscConnectToVsp(struct hv_device *Device) +{ + int ret = 0; + struct mousevsc_dev *inputDevice; + struct mousevsc_prt_msg *request; + struct mousevsc_prt_msg *response; + + inputDevice = GetInputDevice(Device); + + if (!inputDevice) { + pr_err("unable to get input device...device being destroyed?"); + return -1; + } + + init_waitqueue_head(&inputDevice->ProtocolWaitEvent); + init_waitqueue_head(&inputDevice->DeviceInfoWaitEvent); + + request = &inputDevice->ProtocolReq; + + /* + * Now, initiate the vsc/vsp initialization protocol on the open channel + */ + memset(request, sizeof(struct mousevsc_prt_msg), 0); + + request->PacketType = PipeMessageData; + request->DataSize = sizeof(SYNTHHID_PROTOCOL_REQUEST); + + request->u.Request.Header.Type = SynthHidProtocolRequest; + request->u.Request.Header.Size = sizeof(unsigned long); + request->u.Request.VersionRequested.AsDWord = + SYNTHHID_INPUT_VERSION_DWORD; + + pr_info("SYNTHHID_PROTOCOL_REQUEST..."); + + ret = vmbus_sendpacket(Device->channel, request, + sizeof(struct pipe_prt_msg) - + sizeof(unsigned char) + + sizeof(SYNTHHID_PROTOCOL_REQUEST), + (unsigned long)request, + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if (ret != 0) { + pr_err("unable to send SYNTHHID_PROTOCOL_REQUEST"); + goto Cleanup; + } + + inputDevice->protocol_wait_condition = 0; + wait_event_timeout(inputDevice->ProtocolWaitEvent, inputDevice->protocol_wait_condition, msecs_to_jiffies(1000)); + if (inputDevice->protocol_wait_condition == 0) { + ret = -ETIMEDOUT; + goto Cleanup; + } + + response = &inputDevice->ProtocolResp; + + if (!response->u.Response.Approved) { + pr_err("SYNTHHID_PROTOCOL_REQUEST failed (version %d)", + SYNTHHID_INPUT_VERSION_DWORD); + ret = -1; + goto Cleanup; + } + + inputDevice->device_wait_condition = 0; + wait_event_timeout(inputDevice->DeviceInfoWaitEvent, inputDevice->device_wait_condition, msecs_to_jiffies(1000)); + if (inputDevice->device_wait_condition == 0) { + ret = -ETIMEDOUT; + goto Cleanup; + } + + /* + * We should have gotten the device attr, hid desc and report + * desc at this point + */ + if (!inputDevice->DeviceInfoStatus) + pr_info("**** input channel up and running!! ****"); + else + ret = -1; + +Cleanup: + PutInputDevice(Device); + + return ret; +} + + +/* + * + * Name: + * MousevscOnDeviceRemove() + * + * Description: + * Callback when the our device is being removed + * + */ +int +MousevscOnDeviceRemove(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + int ret = 0; + + pr_info("disabling input device (%p)...", + Device->ext); + + inputDevice = ReleaseInputDevice(Device); + + + /* + * At this point, all outbound traffic should be disable. We only + * allow inbound traffic (responses) to proceed + * + * so that outstanding requests can be completed. + */ + while (inputDevice->NumOutstandingRequests) { + pr_info("waiting for %d requests to complete...", inputDevice->NumOutstandingRequests); + + udelay(100); + } + + pr_info("removing input device (%p)...", Device->ext); + + inputDevice = FinalReleaseInputDevice(Device); + + pr_info("input device (%p) safe to remove", inputDevice); + + /* Close the channel */ + vmbus_close(Device->channel); + + FreeInputDevice(inputDevice); + + return ret; +} + + +/* + * + * Name: + * MousevscOnCleanup() + * + * Description: + * Perform any cleanup when the driver is removed + */ +static void MousevscOnCleanup(struct hv_driver *drv) +{ +} + + +static void +MousevscOnSendCompletion(struct hv_device *Device, + struct vmpacket_descriptor *Packet) +{ + struct mousevsc_dev *inputDevice; + void *request; + + inputDevice = MustGetInputDevice(Device); + if (!inputDevice) { + pr_err("unable to get input device...device being destroyed?"); + return; + } + + request = (void *)(unsigned long *)Packet->trans_id; + + if (request == &inputDevice->ProtocolReq) { + /* FIXME */ + /* Shouldn't we be doing something here? */ + } + + PutInputDevice(Device); +} + +void +MousevscOnReceiveDeviceInfo( + struct mousevsc_dev *InputDevice, + SYNTHHID_DEVICE_INFO *DeviceInfo) +{ + int ret = 0; + struct hid_descriptor *desc; + struct mousevsc_prt_msg ack; + + /* Assume success for now */ + InputDevice->DeviceInfoStatus = 0; + + /* Save the device attr */ + memcpy(&InputDevice->DeviceAttr, &DeviceInfo->HidDeviceAttributes, sizeof(struct input_dev_info)); + + /* Save the hid desc */ + desc = (struct hid_descriptor *)DeviceInfo->HidDescriptorInformation; + WARN_ON(desc->bLength > 0); + + InputDevice->HidDesc = kzalloc(desc->bLength, GFP_KERNEL); + + if (!InputDevice->HidDesc) { + pr_err("unable to allocate hid descriptor - size %d", desc->bLength); + goto Cleanup; + } + + memcpy(InputDevice->HidDesc, desc, desc->bLength); + + /* Save the report desc */ + InputDevice->ReportDescSize = desc->desc[0].wDescriptorLength; + InputDevice->ReportDesc = kzalloc(InputDevice->ReportDescSize, + GFP_KERNEL); + + if (!InputDevice->ReportDesc) { + pr_err("unable to allocate report descriptor - size %d", + InputDevice->ReportDescSize); + goto Cleanup; + } + + memcpy(InputDevice->ReportDesc, + ((unsigned char *)desc) + desc->bLength, + desc->desc[0].wDescriptorLength); + + /* Send the ack */ + memset(&ack, sizeof(struct mousevsc_prt_msg), 0); + + ack.PacketType = PipeMessageData; + ack.DataSize = sizeof(SYNTHHID_DEVICE_INFO_ACK); + + ack.u.Ack.Header.Type = SynthHidInitialDeviceInfoAck; + ack.u.Ack.Header.Size = 1; + ack.u.Ack.Reserved = 0; + + ret = vmbus_sendpacket(InputDevice->Device->channel, + &ack, + sizeof(struct pipe_prt_msg) - sizeof(unsigned char) + sizeof(SYNTHHID_DEVICE_INFO_ACK), + (unsigned long)&ack, + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if (ret != 0) { + pr_err("unable to send SYNTHHID_DEVICE_INFO_ACK - ret %d", + ret); + goto Cleanup; + } + + InputDevice->device_wait_condition = 1; + wake_up(&InputDevice->DeviceInfoWaitEvent); + + return; + +Cleanup: + if (InputDevice->HidDesc) { + kfree(InputDevice->HidDesc); + InputDevice->HidDesc = NULL; + } + + if (InputDevice->ReportDesc) { + kfree(InputDevice->ReportDesc); + InputDevice->ReportDesc = NULL; + } + + InputDevice->DeviceInfoStatus = -1; + InputDevice->device_wait_condition = 1; + wake_up(&InputDevice->DeviceInfoWaitEvent); +} + + +void +MousevscOnReceiveInputReport( + struct mousevsc_dev *InputDevice, + SYNTHHID_INPUT_REPORT *InputReport) +{ + struct mousevsc_drv_obj *inputDriver; + + if (!InputDevice->bInitializeComplete) { + pr_info("Initialization incomplete...ignoring InputReport msg"); + return; + } + + inputDriver = (struct mousevsc_drv_obj *)InputDevice->Device->drv; + + inputDriver->OnInputReport(InputDevice->Device, + InputReport->ReportBuffer, + InputReport->Header.Size); +} + +void +MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet) +{ + struct pipe_prt_msg *pipeMsg; + SYNTHHID_MESSAGE *hidMsg; + struct mousevsc_dev *inputDevice; + + inputDevice = MustGetInputDevice(Device); + if (!inputDevice) { + pr_err("unable to get input device...device being destroyed?"); + return; + } + + pipeMsg = (struct pipe_prt_msg *)((unsigned long)Packet + (Packet->offset8 << 3)); + + if (pipeMsg->PacketType != PipeMessageData) { + pr_err("unknown pipe msg type - type %d len %d", + pipeMsg->PacketType, pipeMsg->DataSize); + PutInputDevice(Device); + return ; + } + + hidMsg = (SYNTHHID_MESSAGE *)&pipeMsg->Data[0]; + + switch (hidMsg->Header.Type) { + case SynthHidProtocolResponse: + memcpy(&inputDevice->ProtocolResp, pipeMsg, pipeMsg->DataSize+sizeof(struct pipe_prt_msg) - sizeof(unsigned char)); + inputDevice->protocol_wait_condition = 1; + wake_up(&inputDevice->ProtocolWaitEvent); + break; + + case SynthHidInitialDeviceInfo: + WARN_ON(pipeMsg->DataSize >= sizeof(struct input_dev_info)); + + /* + * Parse out the device info into device attr, + * hid desc and report desc + */ + MousevscOnReceiveDeviceInfo(inputDevice, + (SYNTHHID_DEVICE_INFO *)&pipeMsg->Data[0]); + break; + case SynthHidInputReport: + MousevscOnReceiveInputReport(inputDevice, + (SYNTHHID_INPUT_REPORT *)&pipeMsg->Data[0]); + + break; + default: + pr_err("unsupported hid msg type - type %d len %d", + hidMsg->Header.Type, hidMsg->Header.Size); + break; + } + + PutInputDevice(Device); +} + +void MousevscOnChannelCallback(void *Context) +{ + const int packetSize = 0x100; + int ret = 0; + struct hv_device *device = (struct hv_device *)Context; + struct mousevsc_dev *inputDevice; + + u32 bytesRecvd; + u64 requestId; + unsigned char packet[packetSize]; + struct vmpacket_descriptor *desc; + unsigned char *buffer = packet; + int bufferlen = packetSize; + + inputDevice = MustGetInputDevice(device); + + if (!inputDevice) { + pr_err("unable to get input device...device being destroyed?"); + return; + } + + do { + ret = vmbus_recvpacket_raw(device->channel, buffer, bufferlen, &bytesRecvd, &requestId); + + if (ret == 0) { + if (bytesRecvd > 0) { + desc = (struct vmpacket_descriptor *)buffer; + + switch (desc->type) { + case VM_PKT_COMP: + MousevscOnSendCompletion(device, + desc); + break; + + case VM_PKT_DATA_INBAND: + MousevscOnReceive(device, desc); + break; + + default: + pr_err("unhandled packet type %d, tid %llx len %d\n", + desc->type, + requestId, + bytesRecvd); + break; + } + + /* reset */ + if (bufferlen > packetSize) { + kfree(buffer); + + buffer = packet; + bufferlen = packetSize; + } + } else { + /* + * pr_debug("nothing else to read..."); + * reset + */ + if (bufferlen > packetSize) { + kfree(buffer); + + buffer = packet; + bufferlen = packetSize; + } + break; + } + } else if (ret == -2) { + /* Handle large packet */ + bufferlen = bytesRecvd; + buffer = kzalloc(bytesRecvd, GFP_KERNEL); + + if (buffer == NULL) { + buffer = packet; + bufferlen = packetSize; + + /* Try again next time around */ + pr_err("unable to allocate buffer of size %d!", + bytesRecvd); + break; + } + } + } while (1); + + PutInputDevice(device); + + return; +} + +/* + * Data types + */ +struct input_device_context { + struct vm_device *device_ctx; + struct hid_device *hid_device; + struct input_dev_info device_info; + int connected; +}; + +struct mousevsc_driver_context { + struct driver_context drv_ctx; + struct mousevsc_drv_obj drv_obj; +}; + +static struct mousevsc_driver_context g_mousevsc_drv; + +void mousevsc_deviceinfo_callback(struct hv_device *dev, + struct input_dev_info *info) +{ + struct vm_device *device_ctx = to_vm_device(dev); + struct input_device_context *input_device_ctx = + dev_get_drvdata(&device_ctx->device); + + memcpy(&input_device_ctx->device_info, info, + sizeof(struct input_dev_info)); + + DPRINT_INFO(INPUTVSC_DRV, "mousevsc_deviceinfo_callback()"); +} + +void mousevsc_inputreport_callback(struct hv_device *dev, void *packet, u32 len) +{ + int ret = 0; + + struct vm_device *device_ctx = to_vm_device(dev); + struct input_device_context *input_dev_ctx = + dev_get_drvdata(&device_ctx->device); + + ret = hid_input_report(input_dev_ctx->hid_device, + HID_INPUT_REPORT, packet, len, 1); + + DPRINT_DBG(INPUTVSC_DRV, "hid_input_report (ret %d)", ret); +} + +int mousevsc_hid_open(struct hid_device *hid) +{ + return 0; +} + +void mousevsc_hid_close(struct hid_device *hid) +{ +} + +int mousevsc_probe(struct device *device) +{ + int ret = 0; + + struct driver_context *driver_ctx = + driver_to_driver_context(device->driver); + struct mousevsc_driver_context *mousevsc_drv_ctx = + (struct mousevsc_driver_context *)driver_ctx; + struct mousevsc_drv_obj *mousevsc_drv_obj = &mousevsc_drv_ctx->drv_obj; + + struct vm_device *device_ctx = device_to_vm_device(device); + struct hv_device *device_obj = &device_ctx->device_obj; + struct input_device_context *input_dev_ctx; + + input_dev_ctx = kmalloc(sizeof(struct input_device_context), + GFP_KERNEL); + + dev_set_drvdata(device, input_dev_ctx); + + /* Call to the vsc driver to add the device */ + ret = mousevsc_drv_obj->Base.dev_add(device_obj, NULL); + + if (ret != 0) { + DPRINT_ERR(INPUTVSC_DRV, "unable to add input vsc device"); + + return -1; + } + + return 0; +} + + +int mousevsc_remove(struct device *device) +{ + int ret = 0; + + struct driver_context *driver_ctx = + driver_to_driver_context(device->driver); + struct mousevsc_driver_context *mousevsc_drv_ctx = + (struct mousevsc_driver_context *)driver_ctx; + struct mousevsc_drv_obj *mousevsc_drv_obj = &mousevsc_drv_ctx->drv_obj; + + struct vm_device *device_ctx = device_to_vm_device(device); + struct hv_device *device_obj = &device_ctx->device_obj; + struct input_device_context *input_dev_ctx; + + input_dev_ctx = kmalloc(sizeof(struct input_device_context), + GFP_KERNEL); + + dev_set_drvdata(device, input_dev_ctx); + + if (input_dev_ctx->connected) { + hidinput_disconnect(input_dev_ctx->hid_device); + input_dev_ctx->connected = 0; + } + + if (!mousevsc_drv_obj->Base.dev_rm) + return -1; + + /* + * Call to the vsc driver to let it know that the device + * is being removed + */ + ret = mousevsc_drv_obj->Base.dev_rm(device_obj); + + if (ret != 0) { + DPRINT_ERR(INPUTVSC_DRV, + "unable to remove vsc device (ret %d)", ret); + } + + kfree(input_dev_ctx); + + return ret; +} + +void mousevsc_reportdesc_callback(struct hv_device *dev, void *packet, u32 len) +{ + struct vm_device *device_ctx = to_vm_device(dev); + struct input_device_context *input_device_ctx = + dev_get_drvdata(&device_ctx->device); + struct hid_device *hid_dev; + + /* hid_debug = -1; */ + hid_dev = kmalloc(sizeof(struct hid_device), GFP_KERNEL); + + if (hid_parse_report(hid_dev, packet, len)) { + DPRINT_INFO(INPUTVSC_DRV, "Unable to call hd_parse_report"); + return; + } + + if (hid_dev) { + DPRINT_INFO(INPUTVSC_DRV, "hid_device created"); + + hid_dev->ll_driver->open = mousevsc_hid_open; + hid_dev->ll_driver->close = mousevsc_hid_close; + + hid_dev->bus = 0x06; /* BUS_VIRTUAL */ + hid_dev->vendor = input_device_ctx->device_info.VendorID; + hid_dev->product = input_device_ctx->device_info.ProductID; + hid_dev->version = input_device_ctx->device_info.VersionNumber; + hid_dev->dev = device_ctx->device; + + sprintf(hid_dev->name, "%s", + input_device_ctx->device_info.Name); + + /* + * HJ Do we want to call it with a 0 + */ + if (!hidinput_connect(hid_dev, 0)) { + hid_dev->claimed |= HID_CLAIMED_INPUT; + + input_device_ctx->connected = 1; + + DPRINT_INFO(INPUTVSC_DRV, + "HID device claimed by input\n"); + } + + if (!hid_dev->claimed) { + DPRINT_ERR(INPUTVSC_DRV, + "HID device not claimed by " + "input or hiddev\n"); + } + + input_device_ctx->hid_device = hid_dev; + } + + kfree(hid_dev); +} + +/* + * + * Name: mousevsc_drv_init() + * + * Desc: Driver initialization. + */ +int mousevsc_drv_init(int (*pfn_drv_init)(struct hv_driver *pfn_drv_init)) +{ + int ret = 0; + struct mousevsc_drv_obj *input_drv_obj = &g_mousevsc_drv.drv_obj; + struct driver_context *drv_ctx = &g_mousevsc_drv.drv_ctx; + + input_drv_obj->OnDeviceInfo = mousevsc_deviceinfo_callback; + input_drv_obj->OnInputReport = mousevsc_inputreport_callback; + input_drv_obj->OnReportDescriptor = mousevsc_reportdesc_callback; + + /* Callback to client driver to complete the initialization */ + pfn_drv_init(&input_drv_obj->Base); + + drv_ctx->driver.name = input_drv_obj->Base.name; + memcpy(&drv_ctx->class_id, &input_drv_obj->Base.dev_type, + sizeof(struct hv_guid)); + + drv_ctx->probe = mousevsc_probe; + drv_ctx->remove = mousevsc_remove; + + /* The driver belongs to vmbus */ + vmbus_child_driver_register(drv_ctx); + + return ret; +} + + +int mousevsc_drv_exit_cb(struct device *dev, void *data) +{ + struct device **curr = (struct device **)data; + *curr = dev; + + return 1; +} + +void mousevsc_drv_exit(void) +{ + struct mousevsc_drv_obj *mousevsc_drv_obj = &g_mousevsc_drv.drv_obj; + struct driver_context *drv_ctx = &g_mousevsc_drv.drv_ctx; + int ret; + + struct device *current_dev = NULL; + + while (1) { + current_dev = NULL; + + /* Get the device */ + ret = driver_for_each_device(&drv_ctx->driver, NULL, + (void *)¤t_dev, + mousevsc_drv_exit_cb); + if (ret) + printk(KERN_ERR "Can't find mouse device!\n"); + + if (current_dev == NULL) + break; + + /* Initiate removal from the top-down */ + device_unregister(current_dev); + } + + if (mousevsc_drv_obj->Base.cleanup) + mousevsc_drv_obj->Base.cleanup(&mousevsc_drv_obj->Base); + + vmbus_child_driver_unregister(drv_ctx); + + return; +} + +static int __init mousevsc_init(void) +{ + int ret; + + DPRINT_INFO(INPUTVSC_DRV, "Hyper-V Mouse driver initializing."); + + ret = mousevsc_drv_init(mouse_vsc_initialize); + + return ret; +} + +static void __exit mousevsc_exit(void) +{ + mousevsc_drv_exit(); +} + +/* + * We don't want to automatically load this driver just yet, it's quite + * broken. It's safe if you want to load it yourself manually, but + * don't inflict it on unsuspecting users, that's just mean. + */ +#if 0 + +/* + * We use a PCI table to determine if we should autoload this driver This is + * needed by distro tools to determine if the hyperv drivers should be + * installed and/or configured. We don't do anything else with the table, but + * it needs to be present. + */ +const static struct pci_device_id microsoft_hv_pci_table[] = { + { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */ + { 0 } +}; +MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table); +#endif + +MODULE_LICENSE("GPL"); +MODULE_VERSION(HV_DRV_VERSION); +module_init(mousevsc_init); +module_exit(mousevsc_exit); + diff --git a/drivers/staging/hv/hv_mouse_drv.c b/drivers/staging/hv/hv_mouse_drv.c deleted file mode 100644 index fb3299a06887..000000000000 --- a/drivers/staging/hv/hv_mouse_drv.c +++ /dev/null @@ -1,1060 +0,0 @@ -/* - * Copyright 2009 Citrix Systems, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * For clarity, the licensor of this program does not intend that a - * "derivative work" include code which compiles header information from - * this program. - * - * This code has been modified from its original by - * Hank Janssen - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "hv_api.h" -#include "logging.h" -#include "version_info.h" -#include "vmbus.h" -#include "vmbus_api.h" -#include "mousevsc_api.h" -#include "channel.h" -#include "vmbus_packet_format.h" -#include "vmbus_hid_protocol.h" - -#define NBITS(x) (((x)/BITS_PER_LONG)+1) - -enum pipe_prot_msg_type { - PipeMessageInvalid = 0, - PipeMessageData, - PipeMessageMaximum -}; - - -struct pipe_prt_msg { - enum pipe_prot_msg_type PacketType; - u32 DataSize; - char Data[1]; -}; - -/* - * Data types - */ -struct mousevsc_prt_msg { - enum pipe_prot_msg_type PacketType; - u32 DataSize; - union { - SYNTHHID_PROTOCOL_REQUEST Request; - SYNTHHID_PROTOCOL_RESPONSE Response; - SYNTHHID_DEVICE_INFO_ACK Ack; - } u; -}; - -/* - * Represents an mousevsc device - */ -struct mousevsc_dev { - struct hv_device *Device; - /* 0 indicates the device is being destroyed */ - atomic_t RefCount; - int NumOutstandingRequests; - unsigned char bInitializeComplete; - struct mousevsc_prt_msg ProtocolReq; - struct mousevsc_prt_msg ProtocolResp; - /* Synchronize the request/response if needed */ - wait_queue_head_t ProtocolWaitEvent; - wait_queue_head_t DeviceInfoWaitEvent; - int protocol_wait_condition; - int device_wait_condition; - int DeviceInfoStatus; - - struct hid_descriptor *HidDesc; - unsigned char *ReportDesc; - u32 ReportDescSize; - struct input_dev_info DeviceAttr; -}; - - -/* - * Globals - */ -static const char *gDriverName = "mousevsc"; - -/* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */ -static const struct hv_guid gMousevscDeviceType = { - .data = {0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c, - 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A} -}; - -/* - * Internal routines - */ -static int MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo); - -static int MousevscOnDeviceRemove(struct hv_device *Device); - -static void MousevscOnCleanup(struct hv_driver *Device); - -static void MousevscOnChannelCallback(void *Context); - -static int MousevscConnectToVsp(struct hv_device *Device); - -static void MousevscOnReceive(struct hv_device *Device, - struct vmpacket_descriptor *Packet); - -static inline struct mousevsc_dev *AllocInputDevice(struct hv_device *Device) -{ - struct mousevsc_dev *inputDevice; - - inputDevice = kzalloc(sizeof(struct mousevsc_dev), GFP_KERNEL); - - if (!inputDevice) - return NULL; - - /* - * Set to 2 to allow both inbound and outbound traffics - * (ie GetInputDevice() and MustGetInputDevice()) to proceed. - */ - atomic_cmpxchg(&inputDevice->RefCount, 0, 2); - - inputDevice->Device = Device; - Device->ext = inputDevice; - - return inputDevice; -} - -static inline void FreeInputDevice(struct mousevsc_dev *Device) -{ - WARN_ON(atomic_read(&Device->RefCount) == 0); - kfree(Device); -} - -/* - * Get the inputdevice object if exists and its refcount > 1 - */ -static inline struct mousevsc_dev *GetInputDevice(struct hv_device *Device) -{ - struct mousevsc_dev *inputDevice; - - inputDevice = (struct mousevsc_dev *)Device->ext; - -/* - * FIXME - * This sure isn't a valid thing to print for debugging, no matter - * what the intention is... - * - * printk(KERN_ERR "-------------------------> REFCOUNT = %d", - * inputDevice->RefCount); - */ - - if (inputDevice && atomic_read(&inputDevice->RefCount) > 1) - atomic_inc(&inputDevice->RefCount); - else - inputDevice = NULL; - - return inputDevice; -} - -/* - * Get the inputdevice object iff exists and its refcount > 0 - */ -static inline struct mousevsc_dev *MustGetInputDevice(struct hv_device *Device) -{ - struct mousevsc_dev *inputDevice; - - inputDevice = (struct mousevsc_dev *)Device->ext; - - if (inputDevice && atomic_read(&inputDevice->RefCount)) - atomic_inc(&inputDevice->RefCount); - else - inputDevice = NULL; - - return inputDevice; -} - -static inline void PutInputDevice(struct hv_device *Device) -{ - struct mousevsc_dev *inputDevice; - - inputDevice = (struct mousevsc_dev *)Device->ext; - - atomic_dec(&inputDevice->RefCount); -} - -/* - * Drop ref count to 1 to effectively disable GetInputDevice() - */ -static inline struct mousevsc_dev *ReleaseInputDevice(struct hv_device *Device) -{ - struct mousevsc_dev *inputDevice; - - inputDevice = (struct mousevsc_dev *)Device->ext; - - /* Busy wait until the ref drop to 2, then set it to 1 */ - while (atomic_cmpxchg(&inputDevice->RefCount, 2, 1) != 2) - udelay(100); - - return inputDevice; -} - -/* - * Drop ref count to 0. No one can use InputDevice object. - */ -static inline struct mousevsc_dev *FinalReleaseInputDevice(struct hv_device *Device) -{ - struct mousevsc_dev *inputDevice; - - inputDevice = (struct mousevsc_dev *)Device->ext; - - /* Busy wait until the ref drop to 1, then set it to 0 */ - while (atomic_cmpxchg(&inputDevice->RefCount, 1, 0) != 1) - udelay(100); - - Device->ext = NULL; - return inputDevice; -} - -/* - * - * Name: - * MousevscInitialize() - * - * Description: - * Main entry point - * - */ -int mouse_vsc_initialize(struct hv_driver *Driver) -{ - struct mousevsc_drv_obj *inputDriver = - (struct mousevsc_drv_obj *)Driver; - int ret = 0; - - Driver->name = gDriverName; - memcpy(&Driver->dev_type, &gMousevscDeviceType, - sizeof(struct hv_guid)); - - /* Setup the dispatch table */ - inputDriver->Base.dev_add = MousevscOnDeviceAdd; - inputDriver->Base.dev_rm = MousevscOnDeviceRemove; - inputDriver->Base.cleanup = MousevscOnCleanup; - - inputDriver->OnOpen = NULL; - inputDriver->OnClose = NULL; - - return ret; -} - -/* - * - * Name: - * MousevscOnDeviceAdd() - * - * Description: - * Callback when the device belonging to this driver is added - * - */ -int -MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) -{ - int ret = 0; - struct mousevsc_dev *inputDevice; - struct mousevsc_drv_obj *inputDriver; - struct input_dev_info deviceInfo; - - inputDevice = AllocInputDevice(Device); - - if (!inputDevice) { - ret = -1; - goto Cleanup; - } - - inputDevice->bInitializeComplete = false; - - /* Open the channel */ - ret = vmbus_open(Device->channel, - INPUTVSC_SEND_RING_BUFFER_SIZE, - INPUTVSC_RECV_RING_BUFFER_SIZE, - NULL, - 0, - MousevscOnChannelCallback, - Device - ); - - if (ret != 0) { - pr_err("unable to open channel: %d", ret); - return -1; - } - - pr_info("InputVsc channel open: %d", ret); - - ret = MousevscConnectToVsp(Device); - - if (ret != 0) { - pr_err("unable to connect channel: %d", ret); - - vmbus_close(Device->channel); - return ret; - } - - inputDriver = (struct mousevsc_drv_obj *)inputDevice->Device->drv; - - deviceInfo.VendorID = inputDevice->DeviceAttr.VendorID; - deviceInfo.ProductID = inputDevice->DeviceAttr.ProductID; - deviceInfo.VersionNumber = inputDevice->DeviceAttr.VersionNumber; - strcpy(deviceInfo.Name, "Microsoft Vmbus HID-compliant Mouse"); - - /* Send the device info back up */ - inputDriver->OnDeviceInfo(Device, &deviceInfo); - - /* Send the report desc back up */ - /* workaround SA-167 */ - if (inputDevice->ReportDesc[14] == 0x25) - inputDevice->ReportDesc[14] = 0x29; - - inputDriver->OnReportDescriptor(Device, inputDevice->ReportDesc, inputDevice->ReportDescSize); - - inputDevice->bInitializeComplete = true; - -Cleanup: - return ret; -} - -int -MousevscConnectToVsp(struct hv_device *Device) -{ - int ret = 0; - struct mousevsc_dev *inputDevice; - struct mousevsc_prt_msg *request; - struct mousevsc_prt_msg *response; - - inputDevice = GetInputDevice(Device); - - if (!inputDevice) { - pr_err("unable to get input device...device being destroyed?"); - return -1; - } - - init_waitqueue_head(&inputDevice->ProtocolWaitEvent); - init_waitqueue_head(&inputDevice->DeviceInfoWaitEvent); - - request = &inputDevice->ProtocolReq; - - /* - * Now, initiate the vsc/vsp initialization protocol on the open channel - */ - memset(request, sizeof(struct mousevsc_prt_msg), 0); - - request->PacketType = PipeMessageData; - request->DataSize = sizeof(SYNTHHID_PROTOCOL_REQUEST); - - request->u.Request.Header.Type = SynthHidProtocolRequest; - request->u.Request.Header.Size = sizeof(unsigned long); - request->u.Request.VersionRequested.AsDWord = - SYNTHHID_INPUT_VERSION_DWORD; - - pr_info("SYNTHHID_PROTOCOL_REQUEST..."); - - ret = vmbus_sendpacket(Device->channel, request, - sizeof(struct pipe_prt_msg) - - sizeof(unsigned char) + - sizeof(SYNTHHID_PROTOCOL_REQUEST), - (unsigned long)request, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - if (ret != 0) { - pr_err("unable to send SYNTHHID_PROTOCOL_REQUEST"); - goto Cleanup; - } - - inputDevice->protocol_wait_condition = 0; - wait_event_timeout(inputDevice->ProtocolWaitEvent, inputDevice->protocol_wait_condition, msecs_to_jiffies(1000)); - if (inputDevice->protocol_wait_condition == 0) { - ret = -ETIMEDOUT; - goto Cleanup; - } - - response = &inputDevice->ProtocolResp; - - if (!response->u.Response.Approved) { - pr_err("SYNTHHID_PROTOCOL_REQUEST failed (version %d)", - SYNTHHID_INPUT_VERSION_DWORD); - ret = -1; - goto Cleanup; - } - - inputDevice->device_wait_condition = 0; - wait_event_timeout(inputDevice->DeviceInfoWaitEvent, inputDevice->device_wait_condition, msecs_to_jiffies(1000)); - if (inputDevice->device_wait_condition == 0) { - ret = -ETIMEDOUT; - goto Cleanup; - } - - /* - * We should have gotten the device attr, hid desc and report - * desc at this point - */ - if (!inputDevice->DeviceInfoStatus) - pr_info("**** input channel up and running!! ****"); - else - ret = -1; - -Cleanup: - PutInputDevice(Device); - - return ret; -} - - -/* - * - * Name: - * MousevscOnDeviceRemove() - * - * Description: - * Callback when the our device is being removed - * - */ -int -MousevscOnDeviceRemove(struct hv_device *Device) -{ - struct mousevsc_dev *inputDevice; - int ret = 0; - - pr_info("disabling input device (%p)...", - Device->ext); - - inputDevice = ReleaseInputDevice(Device); - - - /* - * At this point, all outbound traffic should be disable. We only - * allow inbound traffic (responses) to proceed - * - * so that outstanding requests can be completed. - */ - while (inputDevice->NumOutstandingRequests) { - pr_info("waiting for %d requests to complete...", inputDevice->NumOutstandingRequests); - - udelay(100); - } - - pr_info("removing input device (%p)...", Device->ext); - - inputDevice = FinalReleaseInputDevice(Device); - - pr_info("input device (%p) safe to remove", inputDevice); - - /* Close the channel */ - vmbus_close(Device->channel); - - FreeInputDevice(inputDevice); - - return ret; -} - - -/* - * - * Name: - * MousevscOnCleanup() - * - * Description: - * Perform any cleanup when the driver is removed - */ -static void MousevscOnCleanup(struct hv_driver *drv) -{ -} - - -static void -MousevscOnSendCompletion(struct hv_device *Device, - struct vmpacket_descriptor *Packet) -{ - struct mousevsc_dev *inputDevice; - void *request; - - inputDevice = MustGetInputDevice(Device); - if (!inputDevice) { - pr_err("unable to get input device...device being destroyed?"); - return; - } - - request = (void *)(unsigned long *)Packet->trans_id; - - if (request == &inputDevice->ProtocolReq) { - /* FIXME */ - /* Shouldn't we be doing something here? */ - } - - PutInputDevice(Device); -} - -void -MousevscOnReceiveDeviceInfo( - struct mousevsc_dev *InputDevice, - SYNTHHID_DEVICE_INFO *DeviceInfo) -{ - int ret = 0; - struct hid_descriptor *desc; - struct mousevsc_prt_msg ack; - - /* Assume success for now */ - InputDevice->DeviceInfoStatus = 0; - - /* Save the device attr */ - memcpy(&InputDevice->DeviceAttr, &DeviceInfo->HidDeviceAttributes, sizeof(struct input_dev_info)); - - /* Save the hid desc */ - desc = (struct hid_descriptor *)DeviceInfo->HidDescriptorInformation; - WARN_ON(desc->bLength > 0); - - InputDevice->HidDesc = kzalloc(desc->bLength, GFP_KERNEL); - - if (!InputDevice->HidDesc) { - pr_err("unable to allocate hid descriptor - size %d", desc->bLength); - goto Cleanup; - } - - memcpy(InputDevice->HidDesc, desc, desc->bLength); - - /* Save the report desc */ - InputDevice->ReportDescSize = desc->desc[0].wDescriptorLength; - InputDevice->ReportDesc = kzalloc(InputDevice->ReportDescSize, - GFP_KERNEL); - - if (!InputDevice->ReportDesc) { - pr_err("unable to allocate report descriptor - size %d", - InputDevice->ReportDescSize); - goto Cleanup; - } - - memcpy(InputDevice->ReportDesc, - ((unsigned char *)desc) + desc->bLength, - desc->desc[0].wDescriptorLength); - - /* Send the ack */ - memset(&ack, sizeof(struct mousevsc_prt_msg), 0); - - ack.PacketType = PipeMessageData; - ack.DataSize = sizeof(SYNTHHID_DEVICE_INFO_ACK); - - ack.u.Ack.Header.Type = SynthHidInitialDeviceInfoAck; - ack.u.Ack.Header.Size = 1; - ack.u.Ack.Reserved = 0; - - ret = vmbus_sendpacket(InputDevice->Device->channel, - &ack, - sizeof(struct pipe_prt_msg) - sizeof(unsigned char) + sizeof(SYNTHHID_DEVICE_INFO_ACK), - (unsigned long)&ack, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - if (ret != 0) { - pr_err("unable to send SYNTHHID_DEVICE_INFO_ACK - ret %d", - ret); - goto Cleanup; - } - - InputDevice->device_wait_condition = 1; - wake_up(&InputDevice->DeviceInfoWaitEvent); - - return; - -Cleanup: - if (InputDevice->HidDesc) { - kfree(InputDevice->HidDesc); - InputDevice->HidDesc = NULL; - } - - if (InputDevice->ReportDesc) { - kfree(InputDevice->ReportDesc); - InputDevice->ReportDesc = NULL; - } - - InputDevice->DeviceInfoStatus = -1; - InputDevice->device_wait_condition = 1; - wake_up(&InputDevice->DeviceInfoWaitEvent); -} - - -void -MousevscOnReceiveInputReport( - struct mousevsc_dev *InputDevice, - SYNTHHID_INPUT_REPORT *InputReport) -{ - struct mousevsc_drv_obj *inputDriver; - - if (!InputDevice->bInitializeComplete) { - pr_info("Initialization incomplete...ignoring InputReport msg"); - return; - } - - inputDriver = (struct mousevsc_drv_obj *)InputDevice->Device->drv; - - inputDriver->OnInputReport(InputDevice->Device, - InputReport->ReportBuffer, - InputReport->Header.Size); -} - -void -MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet) -{ - struct pipe_prt_msg *pipeMsg; - SYNTHHID_MESSAGE *hidMsg; - struct mousevsc_dev *inputDevice; - - inputDevice = MustGetInputDevice(Device); - if (!inputDevice) { - pr_err("unable to get input device...device being destroyed?"); - return; - } - - pipeMsg = (struct pipe_prt_msg *)((unsigned long)Packet + (Packet->offset8 << 3)); - - if (pipeMsg->PacketType != PipeMessageData) { - pr_err("unknown pipe msg type - type %d len %d", - pipeMsg->PacketType, pipeMsg->DataSize); - PutInputDevice(Device); - return ; - } - - hidMsg = (SYNTHHID_MESSAGE *)&pipeMsg->Data[0]; - - switch (hidMsg->Header.Type) { - case SynthHidProtocolResponse: - memcpy(&inputDevice->ProtocolResp, pipeMsg, pipeMsg->DataSize+sizeof(struct pipe_prt_msg) - sizeof(unsigned char)); - inputDevice->protocol_wait_condition = 1; - wake_up(&inputDevice->ProtocolWaitEvent); - break; - - case SynthHidInitialDeviceInfo: - WARN_ON(pipeMsg->DataSize >= sizeof(struct input_dev_info)); - - /* - * Parse out the device info into device attr, - * hid desc and report desc - */ - MousevscOnReceiveDeviceInfo(inputDevice, - (SYNTHHID_DEVICE_INFO *)&pipeMsg->Data[0]); - break; - case SynthHidInputReport: - MousevscOnReceiveInputReport(inputDevice, - (SYNTHHID_INPUT_REPORT *)&pipeMsg->Data[0]); - - break; - default: - pr_err("unsupported hid msg type - type %d len %d", - hidMsg->Header.Type, hidMsg->Header.Size); - break; - } - - PutInputDevice(Device); -} - -void MousevscOnChannelCallback(void *Context) -{ - const int packetSize = 0x100; - int ret = 0; - struct hv_device *device = (struct hv_device *)Context; - struct mousevsc_dev *inputDevice; - - u32 bytesRecvd; - u64 requestId; - unsigned char packet[packetSize]; - struct vmpacket_descriptor *desc; - unsigned char *buffer = packet; - int bufferlen = packetSize; - - inputDevice = MustGetInputDevice(device); - - if (!inputDevice) { - pr_err("unable to get input device...device being destroyed?"); - return; - } - - do { - ret = vmbus_recvpacket_raw(device->channel, buffer, bufferlen, &bytesRecvd, &requestId); - - if (ret == 0) { - if (bytesRecvd > 0) { - desc = (struct vmpacket_descriptor *)buffer; - - switch (desc->type) { - case VM_PKT_COMP: - MousevscOnSendCompletion(device, - desc); - break; - - case VM_PKT_DATA_INBAND: - MousevscOnReceive(device, desc); - break; - - default: - pr_err("unhandled packet type %d, tid %llx len %d\n", - desc->type, - requestId, - bytesRecvd); - break; - } - - /* reset */ - if (bufferlen > packetSize) { - kfree(buffer); - - buffer = packet; - bufferlen = packetSize; - } - } else { - /* - * pr_debug("nothing else to read..."); - * reset - */ - if (bufferlen > packetSize) { - kfree(buffer); - - buffer = packet; - bufferlen = packetSize; - } - break; - } - } else if (ret == -2) { - /* Handle large packet */ - bufferlen = bytesRecvd; - buffer = kzalloc(bytesRecvd, GFP_KERNEL); - - if (buffer == NULL) { - buffer = packet; - bufferlen = packetSize; - - /* Try again next time around */ - pr_err("unable to allocate buffer of size %d!", - bytesRecvd); - break; - } - } - } while (1); - - PutInputDevice(device); - - return; -} - -/* - * Data types - */ -struct input_device_context { - struct vm_device *device_ctx; - struct hid_device *hid_device; - struct input_dev_info device_info; - int connected; -}; - -struct mousevsc_driver_context { - struct driver_context drv_ctx; - struct mousevsc_drv_obj drv_obj; -}; - -static struct mousevsc_driver_context g_mousevsc_drv; - -void mousevsc_deviceinfo_callback(struct hv_device *dev, - struct input_dev_info *info) -{ - struct vm_device *device_ctx = to_vm_device(dev); - struct input_device_context *input_device_ctx = - dev_get_drvdata(&device_ctx->device); - - memcpy(&input_device_ctx->device_info, info, - sizeof(struct input_dev_info)); - - DPRINT_INFO(INPUTVSC_DRV, "mousevsc_deviceinfo_callback()"); -} - -void mousevsc_inputreport_callback(struct hv_device *dev, void *packet, u32 len) -{ - int ret = 0; - - struct vm_device *device_ctx = to_vm_device(dev); - struct input_device_context *input_dev_ctx = - dev_get_drvdata(&device_ctx->device); - - ret = hid_input_report(input_dev_ctx->hid_device, - HID_INPUT_REPORT, packet, len, 1); - - DPRINT_DBG(INPUTVSC_DRV, "hid_input_report (ret %d)", ret); -} - -int mousevsc_hid_open(struct hid_device *hid) -{ - return 0; -} - -void mousevsc_hid_close(struct hid_device *hid) -{ -} - -int mousevsc_probe(struct device *device) -{ - int ret = 0; - - struct driver_context *driver_ctx = - driver_to_driver_context(device->driver); - struct mousevsc_driver_context *mousevsc_drv_ctx = - (struct mousevsc_driver_context *)driver_ctx; - struct mousevsc_drv_obj *mousevsc_drv_obj = &mousevsc_drv_ctx->drv_obj; - - struct vm_device *device_ctx = device_to_vm_device(device); - struct hv_device *device_obj = &device_ctx->device_obj; - struct input_device_context *input_dev_ctx; - - input_dev_ctx = kmalloc(sizeof(struct input_device_context), - GFP_KERNEL); - - dev_set_drvdata(device, input_dev_ctx); - - /* Call to the vsc driver to add the device */ - ret = mousevsc_drv_obj->Base.dev_add(device_obj, NULL); - - if (ret != 0) { - DPRINT_ERR(INPUTVSC_DRV, "unable to add input vsc device"); - - return -1; - } - - return 0; -} - - -int mousevsc_remove(struct device *device) -{ - int ret = 0; - - struct driver_context *driver_ctx = - driver_to_driver_context(device->driver); - struct mousevsc_driver_context *mousevsc_drv_ctx = - (struct mousevsc_driver_context *)driver_ctx; - struct mousevsc_drv_obj *mousevsc_drv_obj = &mousevsc_drv_ctx->drv_obj; - - struct vm_device *device_ctx = device_to_vm_device(device); - struct hv_device *device_obj = &device_ctx->device_obj; - struct input_device_context *input_dev_ctx; - - input_dev_ctx = kmalloc(sizeof(struct input_device_context), - GFP_KERNEL); - - dev_set_drvdata(device, input_dev_ctx); - - if (input_dev_ctx->connected) { - hidinput_disconnect(input_dev_ctx->hid_device); - input_dev_ctx->connected = 0; - } - - if (!mousevsc_drv_obj->Base.dev_rm) - return -1; - - /* - * Call to the vsc driver to let it know that the device - * is being removed - */ - ret = mousevsc_drv_obj->Base.dev_rm(device_obj); - - if (ret != 0) { - DPRINT_ERR(INPUTVSC_DRV, - "unable to remove vsc device (ret %d)", ret); - } - - kfree(input_dev_ctx); - - return ret; -} - -void mousevsc_reportdesc_callback(struct hv_device *dev, void *packet, u32 len) -{ - struct vm_device *device_ctx = to_vm_device(dev); - struct input_device_context *input_device_ctx = - dev_get_drvdata(&device_ctx->device); - struct hid_device *hid_dev; - - /* hid_debug = -1; */ - hid_dev = kmalloc(sizeof(struct hid_device), GFP_KERNEL); - - if (hid_parse_report(hid_dev, packet, len)) { - DPRINT_INFO(INPUTVSC_DRV, "Unable to call hd_parse_report"); - return; - } - - if (hid_dev) { - DPRINT_INFO(INPUTVSC_DRV, "hid_device created"); - - hid_dev->ll_driver->open = mousevsc_hid_open; - hid_dev->ll_driver->close = mousevsc_hid_close; - - hid_dev->bus = 0x06; /* BUS_VIRTUAL */ - hid_dev->vendor = input_device_ctx->device_info.VendorID; - hid_dev->product = input_device_ctx->device_info.ProductID; - hid_dev->version = input_device_ctx->device_info.VersionNumber; - hid_dev->dev = device_ctx->device; - - sprintf(hid_dev->name, "%s", - input_device_ctx->device_info.Name); - - /* - * HJ Do we want to call it with a 0 - */ - if (!hidinput_connect(hid_dev, 0)) { - hid_dev->claimed |= HID_CLAIMED_INPUT; - - input_device_ctx->connected = 1; - - DPRINT_INFO(INPUTVSC_DRV, - "HID device claimed by input\n"); - } - - if (!hid_dev->claimed) { - DPRINT_ERR(INPUTVSC_DRV, - "HID device not claimed by " - "input or hiddev\n"); - } - - input_device_ctx->hid_device = hid_dev; - } - - kfree(hid_dev); -} - -/* - * - * Name: mousevsc_drv_init() - * - * Desc: Driver initialization. - */ -int mousevsc_drv_init(int (*pfn_drv_init)(struct hv_driver *pfn_drv_init)) -{ - int ret = 0; - struct mousevsc_drv_obj *input_drv_obj = &g_mousevsc_drv.drv_obj; - struct driver_context *drv_ctx = &g_mousevsc_drv.drv_ctx; - - input_drv_obj->OnDeviceInfo = mousevsc_deviceinfo_callback; - input_drv_obj->OnInputReport = mousevsc_inputreport_callback; - input_drv_obj->OnReportDescriptor = mousevsc_reportdesc_callback; - - /* Callback to client driver to complete the initialization */ - pfn_drv_init(&input_drv_obj->Base); - - drv_ctx->driver.name = input_drv_obj->Base.name; - memcpy(&drv_ctx->class_id, &input_drv_obj->Base.dev_type, - sizeof(struct hv_guid)); - - drv_ctx->probe = mousevsc_probe; - drv_ctx->remove = mousevsc_remove; - - /* The driver belongs to vmbus */ - vmbus_child_driver_register(drv_ctx); - - return ret; -} - - -int mousevsc_drv_exit_cb(struct device *dev, void *data) -{ - struct device **curr = (struct device **)data; - *curr = dev; - - return 1; -} - -void mousevsc_drv_exit(void) -{ - struct mousevsc_drv_obj *mousevsc_drv_obj = &g_mousevsc_drv.drv_obj; - struct driver_context *drv_ctx = &g_mousevsc_drv.drv_ctx; - int ret; - - struct device *current_dev = NULL; - - while (1) { - current_dev = NULL; - - /* Get the device */ - ret = driver_for_each_device(&drv_ctx->driver, NULL, - (void *)¤t_dev, - mousevsc_drv_exit_cb); - if (ret) - printk(KERN_ERR "Can't find mouse device!\n"); - - if (current_dev == NULL) - break; - - /* Initiate removal from the top-down */ - device_unregister(current_dev); - } - - if (mousevsc_drv_obj->Base.cleanup) - mousevsc_drv_obj->Base.cleanup(&mousevsc_drv_obj->Base); - - vmbus_child_driver_unregister(drv_ctx); - - return; -} - -static int __init mousevsc_init(void) -{ - int ret; - - DPRINT_INFO(INPUTVSC_DRV, "Hyper-V Mouse driver initializing."); - - ret = mousevsc_drv_init(mouse_vsc_initialize); - - return ret; -} - -static void __exit mousevsc_exit(void) -{ - mousevsc_drv_exit(); -} - -/* - * We don't want to automatically load this driver just yet, it's quite - * broken. It's safe if you want to load it yourself manually, but - * don't inflict it on unsuspecting users, that's just mean. - */ -#if 0 - -/* - * We use a PCI table to determine if we should autoload this driver This is - * needed by distro tools to determine if the hyperv drivers should be - * installed and/or configured. We don't do anything else with the table, but - * it needs to be present. - */ -const static struct pci_device_id microsoft_hv_pci_table[] = { - { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */ - { 0 } -}; -MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table); -#endif - -MODULE_LICENSE("GPL"); -MODULE_VERSION(HV_DRV_VERSION); -module_init(mousevsc_init); -module_exit(mousevsc_exit); - -- cgit v1.2.3 From 9b9f93da1fdb133a2de88c22670d6c39b3634eb5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 17:49:30 -0800 Subject: Staging: hv: hv_mouse: fix up copyright and license header Use the proper license header from the other hv drivers and remove the nonsense about derivative works, as it's rubbish. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index fb3299a06887..32fad7344321 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -1,27 +1,16 @@ /* - * Copyright 2009 Citrix Systems, Inc. + * Copyright (c) 2009, Citrix Systems, Inc. + * Copyright (c) 2010, Microsoft Corporation. + * Copyright (c) 2011, Novell Inc. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * For clarity, the licensor of this program does not intend that a - * "derivative work" include code which compiles header information from - * this program. - * - * This code has been modified from its original by - * Hank Janssen + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. */ #include #include -- cgit v1.2.3 From fa003500ec7a057e555a1c80d68865d00fa8142c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 17:53:58 -0800 Subject: Staging: hv: delete vmbus_hid_protocol.h The .h file is not needed as only one .c file uses it, so just move it into that file. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 88 ++++++++++++++++++++++- drivers/staging/hv/vmbus_hid_protocol.h | 120 -------------------------------- 2 files changed, 87 insertions(+), 121 deletions(-) delete mode 100644 drivers/staging/hv/vmbus_hid_protocol.h (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 32fad7344321..b62409d22ce5 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -32,7 +32,93 @@ #include "mousevsc_api.h" #include "channel.h" #include "vmbus_packet_format.h" -#include "vmbus_hid_protocol.h" + + +/* The maximum size of a synthetic input message. */ +#define SYNTHHID_MAX_INPUT_REPORT_SIZE 16 + +/* + * Current version + * + * History: + * Beta, RC < 2008/1/22 1,0 + * RC > 2008/1/22 2,0 + */ +#define SYNTHHID_INPUT_VERSION_MAJOR 2 +#define SYNTHHID_INPUT_VERSION_MINOR 0 +#define SYNTHHID_INPUT_VERSION_DWORD (SYNTHHID_INPUT_VERSION_MINOR | \ + (SYNTHHID_INPUT_VERSION_MAJOR << 16)) + + +#pragma pack(push,1) +/* + * Message types in the synthetic input protocol + */ +enum synthhid_msg_type { + SynthHidProtocolRequest, + SynthHidProtocolResponse, + SynthHidInitialDeviceInfo, + SynthHidInitialDeviceInfoAck, + SynthHidInputReport, + SynthHidMax +}; + +/* + * Basic message structures. + */ +typedef struct { + enum synthhid_msg_type Type; /* Type of the enclosed message */ + u32 Size; /* Size of the enclosed message + * (size of the data payload) + */ +} SYNTHHID_MESSAGE_HEADER, *PSYNTHHID_MESSAGE_HEADER; + +typedef struct { + SYNTHHID_MESSAGE_HEADER Header; + char Data[1]; /* Enclosed message */ +} SYNTHHID_MESSAGE, *PSYNTHHID_MESSAGE; + +typedef union { + struct { + u16 Minor; + u16 Major; + }; + + u32 AsDWord; +} SYNTHHID_VERSION, *PSYNTHHID_VERSION; + +/* + * Protocol messages + */ +typedef struct { + SYNTHHID_MESSAGE_HEADER Header; + SYNTHHID_VERSION VersionRequested; +} SYNTHHID_PROTOCOL_REQUEST, *PSYNTHHID_PROTOCOL_REQUEST; + +typedef struct { + SYNTHHID_MESSAGE_HEADER Header; + SYNTHHID_VERSION VersionRequested; + unsigned char Approved; +} SYNTHHID_PROTOCOL_RESPONSE, *PSYNTHHID_PROTOCOL_RESPONSE; + +typedef struct { + SYNTHHID_MESSAGE_HEADER Header; + struct input_dev_info HidDeviceAttributes; + unsigned char HidDescriptorInformation[1]; +} SYNTHHID_DEVICE_INFO, *PSYNTHHID_DEVICE_INFO; + +typedef struct { + SYNTHHID_MESSAGE_HEADER Header; + unsigned char Reserved; +} SYNTHHID_DEVICE_INFO_ACK, *PSYNTHHID_DEVICE_INFO_ACK; + +typedef struct { + SYNTHHID_MESSAGE_HEADER Header; + char ReportBuffer[1]; +} SYNTHHID_INPUT_REPORT, *PSYNTHHID_INPUT_REPORT; + +#pragma pack(pop) + #define NBITS(x) (((x)/BITS_PER_LONG)+1) diff --git a/drivers/staging/hv/vmbus_hid_protocol.h b/drivers/staging/hv/vmbus_hid_protocol.h deleted file mode 100644 index 65f3001e6202..000000000000 --- a/drivers/staging/hv/vmbus_hid_protocol.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Hank Janssen - */ -#ifndef _VMBUS_HID_PROTOCOL_ -#define _VMBUS_HID_PROTOCOL_ - -/* The maximum size of a synthetic input message. */ -#define SYNTHHID_MAX_INPUT_REPORT_SIZE 16 - -/* - * Current version - * - * History: - * Beta, RC < 2008/1/22 1,0 - * RC > 2008/1/22 2,0 - */ -#define SYNTHHID_INPUT_VERSION_MAJOR 2 -#define SYNTHHID_INPUT_VERSION_MINOR 0 -#define SYNTHHID_INPUT_VERSION_DWORD (SYNTHHID_INPUT_VERSION_MINOR | \ - (SYNTHHID_INPUT_VERSION_MAJOR << 16)) - - -#pragma pack(push,1) - -/* - * Message types in the synthetic input protocol - */ -enum synthhid_msg_type -{ - SynthHidProtocolRequest, - SynthHidProtocolResponse, - SynthHidInitialDeviceInfo, - SynthHidInitialDeviceInfoAck, - SynthHidInputReport, - SynthHidMax -}; - - -/* - * Basic message structures. - */ -typedef struct -{ - enum synthhid_msg_type Type; /* Type of the enclosed message */ - u32 Size; /* Size of the enclosed message - * (size of the data payload) - */ -} SYNTHHID_MESSAGE_HEADER, *PSYNTHHID_MESSAGE_HEADER; - -typedef struct -{ - SYNTHHID_MESSAGE_HEADER Header; - char Data[1]; /* Enclosed message */ -} SYNTHHID_MESSAGE, *PSYNTHHID_MESSAGE; - -typedef union -{ - struct { - u16 Minor; - u16 Major; - }; - - u32 AsDWord; -} SYNTHHID_VERSION, *PSYNTHHID_VERSION; - -/* - * Protocol messages - */ -typedef struct -{ - SYNTHHID_MESSAGE_HEADER Header; - SYNTHHID_VERSION VersionRequested; -} SYNTHHID_PROTOCOL_REQUEST, *PSYNTHHID_PROTOCOL_REQUEST; - -typedef struct -{ - SYNTHHID_MESSAGE_HEADER Header; - SYNTHHID_VERSION VersionRequested; - unsigned char Approved; -} SYNTHHID_PROTOCOL_RESPONSE, *PSYNTHHID_PROTOCOL_RESPONSE; - -typedef struct -{ - SYNTHHID_MESSAGE_HEADER Header; - struct input_dev_info HidDeviceAttributes; - unsigned char HidDescriptorInformation[1]; -} SYNTHHID_DEVICE_INFO, *PSYNTHHID_DEVICE_INFO; - -typedef struct -{ - SYNTHHID_MESSAGE_HEADER Header; - unsigned char Reserved; -} SYNTHHID_DEVICE_INFO_ACK, *PSYNTHHID_DEVICE_INFO_ACK; - -typedef struct -{ - SYNTHHID_MESSAGE_HEADER Header; - char ReportBuffer[1]; -} SYNTHHID_INPUT_REPORT, *PSYNTHHID_INPUT_REPORT; - -#pragma pack(pop) - -#endif /* _VMBUS_HID_PROTOCOL_ */ - -- cgit v1.2.3 From 94fcc88868e4068d3fe9aa0d719a380bfa44a0a0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 17:57:51 -0800 Subject: Staging: hv: delete mousevsc_api.h This file is only used by one .c file (hv_mouse.c) so just move the whole thing into that file. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 37 +++++++++++++++++++- drivers/staging/hv/mousevsc_api.h | 73 --------------------------------------- 2 files changed, 36 insertions(+), 74 deletions(-) delete mode 100644 drivers/staging/hv/mousevsc_api.h (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index b62409d22ce5..3fb5ee800812 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -29,11 +29,44 @@ #include "version_info.h" #include "vmbus.h" #include "vmbus_api.h" -#include "mousevsc_api.h" #include "channel.h" #include "vmbus_packet_format.h" +/* + * Data types + */ +struct input_dev_info { + unsigned short VendorID; + unsigned short ProductID; + unsigned short VersionNumber; + char Name[128]; +}; + +/* Represents the input vsc driver */ +struct mousevsc_drv_obj { + struct hv_driver Base; // Must be the first field + /* + * This is set by the caller to allow us to callback when + * we receive a packet from the "wire" + */ + void (*OnDeviceInfo)(struct hv_device *dev, + struct input_dev_info* info); + void (*OnInputReport)(struct hv_device *dev, void* packet, u32 len); + void (*OnReportDescriptor)(struct hv_device *dev, + void* packet, u32 len); + /* Specific to this driver */ + int (*OnOpen)(struct hv_device *Device); + int (*OnClose)(struct hv_device *Device); + void *Context; +}; + + +/* + * Interface + */ +int mouse_vsc_initialize(struct hv_driver *drv); + /* The maximum size of a synthetic input message. */ #define SYNTHHID_MAX_INPUT_REPORT_SIZE 16 @@ -119,6 +152,8 @@ typedef struct { #pragma pack(pop) +#define INPUTVSC_SEND_RING_BUFFER_SIZE 10*PAGE_SIZE +#define INPUTVSC_RECV_RING_BUFFER_SIZE 10*PAGE_SIZE #define NBITS(x) (((x)/BITS_PER_LONG)+1) diff --git a/drivers/staging/hv/mousevsc_api.h b/drivers/staging/hv/mousevsc_api.h deleted file mode 100644 index f3610867143d..000000000000 --- a/drivers/staging/hv/mousevsc_api.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2009 Citrix Systems, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * For clarity, the licensor of this program does not intend that a - * "derivative work" include code which compiles header information from - * this program. - * - * This code has been modified from its original by - * Hank Janssen - * - */ - -#ifndef _INPUTVSC_API_H_ -#define _INPUTVSC_API_H_ - -#include "vmbus_api.h" - -/* - * Defines - */ -#define INPUTVSC_SEND_RING_BUFFER_SIZE 10*PAGE_SIZE -#define INPUTVSC_RECV_RING_BUFFER_SIZE 10*PAGE_SIZE - - -/* - * Data types - */ -struct input_dev_info { - unsigned short VendorID; - unsigned short ProductID; - unsigned short VersionNumber; - char Name[128]; -}; - -/* Represents the input vsc driver */ -struct mousevsc_drv_obj { - struct hv_driver Base; // Must be the first field - /* - * This is set by the caller to allow us to callback when - * we receive a packet from the "wire" - */ - void (*OnDeviceInfo)(struct hv_device *dev, - struct input_dev_info* info); - void (*OnInputReport)(struct hv_device *dev, void* packet, u32 len); - void (*OnReportDescriptor)(struct hv_device *dev, - void* packet, u32 len); - /* Specific to this driver */ - int (*OnOpen)(struct hv_device *Device); - int (*OnClose)(struct hv_device *Device); - void *Context; -}; - - -/* - * Interface - */ -int mouse_vsc_initialize(struct hv_driver *drv); - -#endif // _INPUTVSC_API_H_ -- cgit v1.2.3 From e6f83b78ec7d8a6201caf0e190d1317aaf24b299 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 18:21:01 -0800 Subject: Staging: hv: hv_mouse: remove typedefs Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 89 ++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 3fb5ee800812..b438b0310770 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -99,56 +99,56 @@ enum synthhid_msg_type { /* * Basic message structures. */ -typedef struct { +struct synthhid_msg_hdr { enum synthhid_msg_type Type; /* Type of the enclosed message */ u32 Size; /* Size of the enclosed message * (size of the data payload) */ -} SYNTHHID_MESSAGE_HEADER, *PSYNTHHID_MESSAGE_HEADER; +}; -typedef struct { - SYNTHHID_MESSAGE_HEADER Header; +struct synthhid_msg { + struct synthhid_msg_hdr Header; char Data[1]; /* Enclosed message */ -} SYNTHHID_MESSAGE, *PSYNTHHID_MESSAGE; +}; -typedef union { +union synthhid_version { struct { u16 Minor; u16 Major; }; u32 AsDWord; -} SYNTHHID_VERSION, *PSYNTHHID_VERSION; +}; /* * Protocol messages */ -typedef struct { - SYNTHHID_MESSAGE_HEADER Header; - SYNTHHID_VERSION VersionRequested; -} SYNTHHID_PROTOCOL_REQUEST, *PSYNTHHID_PROTOCOL_REQUEST; - -typedef struct { - SYNTHHID_MESSAGE_HEADER Header; - SYNTHHID_VERSION VersionRequested; - unsigned char Approved; -} SYNTHHID_PROTOCOL_RESPONSE, *PSYNTHHID_PROTOCOL_RESPONSE; - -typedef struct { - SYNTHHID_MESSAGE_HEADER Header; +struct synthhid_protocol_request { + struct synthhid_msg_hdr Header; + union synthhid_version VersionRequested; +}; + +struct synthhid_protocol_response { + struct synthhid_msg_hdr Header; + union synthhid_version VersionRequested; + unsigned char Approved; +}; + +struct synthhid_device_info { + struct synthhid_msg_hdr Header; struct input_dev_info HidDeviceAttributes; unsigned char HidDescriptorInformation[1]; -} SYNTHHID_DEVICE_INFO, *PSYNTHHID_DEVICE_INFO; +}; -typedef struct { - SYNTHHID_MESSAGE_HEADER Header; +struct synthhid_device_info_ack { + struct synthhid_msg_hdr Header; unsigned char Reserved; -} SYNTHHID_DEVICE_INFO_ACK, *PSYNTHHID_DEVICE_INFO_ACK; +}; -typedef struct { - SYNTHHID_MESSAGE_HEADER Header; +struct synthhid_input_report { + struct synthhid_msg_hdr Header; char ReportBuffer[1]; -} SYNTHHID_INPUT_REPORT, *PSYNTHHID_INPUT_REPORT; +}; #pragma pack(pop) @@ -177,9 +177,9 @@ struct mousevsc_prt_msg { enum pipe_prot_msg_type PacketType; u32 DataSize; union { - SYNTHHID_PROTOCOL_REQUEST Request; - SYNTHHID_PROTOCOL_RESPONSE Response; - SYNTHHID_DEVICE_INFO_ACK Ack; + struct synthhid_protocol_request Request; + struct synthhid_protocol_response Response; + struct synthhid_device_info_ack Ack; } u; }; @@ -478,24 +478,24 @@ MousevscConnectToVsp(struct hv_device *Device) memset(request, sizeof(struct mousevsc_prt_msg), 0); request->PacketType = PipeMessageData; - request->DataSize = sizeof(SYNTHHID_PROTOCOL_REQUEST); + request->DataSize = sizeof(struct synthhid_protocol_request); request->u.Request.Header.Type = SynthHidProtocolRequest; request->u.Request.Header.Size = sizeof(unsigned long); request->u.Request.VersionRequested.AsDWord = SYNTHHID_INPUT_VERSION_DWORD; - pr_info("SYNTHHID_PROTOCOL_REQUEST..."); + pr_info("synthhid protocol request..."); ret = vmbus_sendpacket(Device->channel, request, sizeof(struct pipe_prt_msg) - sizeof(unsigned char) + - sizeof(SYNTHHID_PROTOCOL_REQUEST), + sizeof(struct synthhid_protocol_request), (unsigned long)request, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { - pr_err("unable to send SYNTHHID_PROTOCOL_REQUEST"); + pr_err("unable to send synthhid protocol request."); goto Cleanup; } @@ -509,7 +509,7 @@ MousevscConnectToVsp(struct hv_device *Device) response = &inputDevice->ProtocolResp; if (!response->u.Response.Approved) { - pr_err("SYNTHHID_PROTOCOL_REQUEST failed (version %d)", + pr_err("synthhid protocol request failed (version %d)", SYNTHHID_INPUT_VERSION_DWORD); ret = -1; goto Cleanup; @@ -625,7 +625,7 @@ MousevscOnSendCompletion(struct hv_device *Device, void MousevscOnReceiveDeviceInfo( struct mousevsc_dev *InputDevice, - SYNTHHID_DEVICE_INFO *DeviceInfo) + struct synthhid_device_info *DeviceInfo) { int ret = 0; struct hid_descriptor *desc; @@ -669,7 +669,7 @@ MousevscOnReceiveDeviceInfo( memset(&ack, sizeof(struct mousevsc_prt_msg), 0); ack.PacketType = PipeMessageData; - ack.DataSize = sizeof(SYNTHHID_DEVICE_INFO_ACK); + ack.DataSize = sizeof(struct synthhid_device_info_ack); ack.u.Ack.Header.Type = SynthHidInitialDeviceInfoAck; ack.u.Ack.Header.Size = 1; @@ -677,12 +677,13 @@ MousevscOnReceiveDeviceInfo( ret = vmbus_sendpacket(InputDevice->Device->channel, &ack, - sizeof(struct pipe_prt_msg) - sizeof(unsigned char) + sizeof(SYNTHHID_DEVICE_INFO_ACK), + sizeof(struct pipe_prt_msg) - sizeof(unsigned char) + + sizeof(struct synthhid_device_info_ack), (unsigned long)&ack, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { - pr_err("unable to send SYNTHHID_DEVICE_INFO_ACK - ret %d", + pr_err("unable to send synthhid device info ack - ret %d", ret); goto Cleanup; } @@ -712,7 +713,7 @@ Cleanup: void MousevscOnReceiveInputReport( struct mousevsc_dev *InputDevice, - SYNTHHID_INPUT_REPORT *InputReport) + struct synthhid_input_report *InputReport) { struct mousevsc_drv_obj *inputDriver; @@ -732,7 +733,7 @@ void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet) { struct pipe_prt_msg *pipeMsg; - SYNTHHID_MESSAGE *hidMsg; + struct synthhid_msg *hidMsg; struct mousevsc_dev *inputDevice; inputDevice = MustGetInputDevice(Device); @@ -750,7 +751,7 @@ MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet) return ; } - hidMsg = (SYNTHHID_MESSAGE *)&pipeMsg->Data[0]; + hidMsg = (struct synthhid_msg *)&pipeMsg->Data[0]; switch (hidMsg->Header.Type) { case SynthHidProtocolResponse: @@ -767,11 +768,11 @@ MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet) * hid desc and report desc */ MousevscOnReceiveDeviceInfo(inputDevice, - (SYNTHHID_DEVICE_INFO *)&pipeMsg->Data[0]); + (struct synthhid_device_info *)&pipeMsg->Data[0]); break; case SynthHidInputReport: MousevscOnReceiveInputReport(inputDevice, - (SYNTHHID_INPUT_REPORT *)&pipeMsg->Data[0]); + (struct synthhid_input_report *)&pipeMsg->Data[0]); break; default: -- cgit v1.2.3 From 7ced4810f9a86bb0324568052c6bf27292512b43 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 18:28:52 -0800 Subject: Staging: hv: hv_mouse: unwind the initialization process a bit This unwinds the init call sequence a bit, as we don't need a callback pointer for a function that is already in this file. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 71 ++++++++++++------------------------------- 1 file changed, 20 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index b438b0310770..5fc14a23b33e 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -62,11 +62,6 @@ struct mousevsc_drv_obj { }; -/* - * Interface - */ -int mouse_vsc_initialize(struct hv_driver *drv); - /* The maximum size of a synthetic input message. */ #define SYNTHHID_MAX_INPUT_REPORT_SIZE 16 @@ -347,16 +342,7 @@ static inline struct mousevsc_dev *FinalReleaseInputDevice(struct hv_device *Dev return inputDevice; } -/* - * - * Name: - * MousevscInitialize() - * - * Description: - * Main entry point - * - */ -int mouse_vsc_initialize(struct hv_driver *Driver) +static int mouse_vsc_initialize(struct hv_driver *Driver) { struct mousevsc_drv_obj *inputDriver = (struct mousevsc_drv_obj *)Driver; @@ -1054,39 +1040,6 @@ void mousevsc_reportdesc_callback(struct hv_device *dev, void *packet, u32 len) kfree(hid_dev); } -/* - * - * Name: mousevsc_drv_init() - * - * Desc: Driver initialization. - */ -int mousevsc_drv_init(int (*pfn_drv_init)(struct hv_driver *pfn_drv_init)) -{ - int ret = 0; - struct mousevsc_drv_obj *input_drv_obj = &g_mousevsc_drv.drv_obj; - struct driver_context *drv_ctx = &g_mousevsc_drv.drv_ctx; - - input_drv_obj->OnDeviceInfo = mousevsc_deviceinfo_callback; - input_drv_obj->OnInputReport = mousevsc_inputreport_callback; - input_drv_obj->OnReportDescriptor = mousevsc_reportdesc_callback; - - /* Callback to client driver to complete the initialization */ - pfn_drv_init(&input_drv_obj->Base); - - drv_ctx->driver.name = input_drv_obj->Base.name; - memcpy(&drv_ctx->class_id, &input_drv_obj->Base.dev_type, - sizeof(struct hv_guid)); - - drv_ctx->probe = mousevsc_probe; - drv_ctx->remove = mousevsc_remove; - - /* The driver belongs to vmbus */ - vmbus_child_driver_register(drv_ctx); - - return ret; -} - - int mousevsc_drv_exit_cb(struct device *dev, void *data) { struct device **curr = (struct device **)data; @@ -1130,13 +1083,29 @@ void mousevsc_drv_exit(void) static int __init mousevsc_init(void) { - int ret; + struct mousevsc_drv_obj *input_drv_obj = &g_mousevsc_drv.drv_obj; + struct driver_context *drv_ctx = &g_mousevsc_drv.drv_ctx; DPRINT_INFO(INPUTVSC_DRV, "Hyper-V Mouse driver initializing."); - ret = mousevsc_drv_init(mouse_vsc_initialize); + input_drv_obj->OnDeviceInfo = mousevsc_deviceinfo_callback; + input_drv_obj->OnInputReport = mousevsc_inputreport_callback; + input_drv_obj->OnReportDescriptor = mousevsc_reportdesc_callback; - return ret; + /* Callback to client driver to complete the initialization */ + mouse_vsc_initialize(&input_drv_obj->Base); + + drv_ctx->driver.name = input_drv_obj->Base.name; + memcpy(&drv_ctx->class_id, &input_drv_obj->Base.dev_type, + sizeof(struct hv_guid)); + + drv_ctx->probe = mousevsc_probe; + drv_ctx->remove = mousevsc_remove; + + /* The driver belongs to vmbus */ + vmbus_child_driver_register(drv_ctx); + + return 0; } static void __exit mousevsc_exit(void) -- cgit v1.2.3 From 4f143134c12293217e6c8d68d0018780199f6d3c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 18:38:31 -0800 Subject: Staging: hv: hv_mouse.c: remove struct mousevsc_drv_obj function callbacks They aren't needed at all either because they are never called (OnOpen, OnClose), or because we can just call the real function instead as it's never set to anything else. Just another step in unwinding the callback mess... Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 48 +++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 5fc14a23b33e..15b4399130da 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -44,21 +44,9 @@ struct input_dev_info { }; /* Represents the input vsc driver */ +/* FIXME - can be removed entirely */ struct mousevsc_drv_obj { - struct hv_driver Base; // Must be the first field - /* - * This is set by the caller to allow us to callback when - * we receive a packet from the "wire" - */ - void (*OnDeviceInfo)(struct hv_device *dev, - struct input_dev_info* info); - void (*OnInputReport)(struct hv_device *dev, void* packet, u32 len); - void (*OnReportDescriptor)(struct hv_device *dev, - void* packet, u32 len); - /* Specific to this driver */ - int (*OnOpen)(struct hv_device *Device); - int (*OnClose)(struct hv_device *Device); - void *Context; + struct hv_driver Base; }; @@ -230,6 +218,10 @@ static int MousevscConnectToVsp(struct hv_device *Device); static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet); +static void deviceinfo_callback(struct hv_device *dev, struct input_dev_info *info); +static void inputreport_callback(struct hv_device *dev, void *packet, u32 len); +static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len); + static inline struct mousevsc_dev *AllocInputDevice(struct hv_device *Device) { struct mousevsc_dev *inputDevice; @@ -357,9 +349,6 @@ static int mouse_vsc_initialize(struct hv_driver *Driver) inputDriver->Base.dev_rm = MousevscOnDeviceRemove; inputDriver->Base.cleanup = MousevscOnCleanup; - inputDriver->OnOpen = NULL; - inputDriver->OnClose = NULL; - return ret; } @@ -423,14 +412,15 @@ MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) strcpy(deviceInfo.Name, "Microsoft Vmbus HID-compliant Mouse"); /* Send the device info back up */ - inputDriver->OnDeviceInfo(Device, &deviceInfo); + deviceinfo_callback(Device, &deviceInfo); /* Send the report desc back up */ /* workaround SA-167 */ if (inputDevice->ReportDesc[14] == 0x25) inputDevice->ReportDesc[14] = 0x29; - inputDriver->OnReportDescriptor(Device, inputDevice->ReportDesc, inputDevice->ReportDescSize); + reportdesc_callback(Device, inputDevice->ReportDesc, + inputDevice->ReportDescSize); inputDevice->bInitializeComplete = true; @@ -710,9 +700,9 @@ MousevscOnReceiveInputReport( inputDriver = (struct mousevsc_drv_obj *)InputDevice->Device->drv; - inputDriver->OnInputReport(InputDevice->Device, - InputReport->ReportBuffer, - InputReport->Header.Size); + inputreport_callback(InputDevice->Device, + InputReport->ReportBuffer, + InputReport->Header.Size); } void @@ -875,8 +865,8 @@ struct mousevsc_driver_context { static struct mousevsc_driver_context g_mousevsc_drv; -void mousevsc_deviceinfo_callback(struct hv_device *dev, - struct input_dev_info *info) +static void deviceinfo_callback(struct hv_device *dev, + struct input_dev_info *info) { struct vm_device *device_ctx = to_vm_device(dev); struct input_device_context *input_device_ctx = @@ -885,10 +875,10 @@ void mousevsc_deviceinfo_callback(struct hv_device *dev, memcpy(&input_device_ctx->device_info, info, sizeof(struct input_dev_info)); - DPRINT_INFO(INPUTVSC_DRV, "mousevsc_deviceinfo_callback()"); + DPRINT_INFO(INPUTVSC_DRV, "%s", __func__); } -void mousevsc_inputreport_callback(struct hv_device *dev, void *packet, u32 len) +static void inputreport_callback(struct hv_device *dev, void *packet, u32 len) { int ret = 0; @@ -986,7 +976,7 @@ int mousevsc_remove(struct device *device) return ret; } -void mousevsc_reportdesc_callback(struct hv_device *dev, void *packet, u32 len) +static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len) { struct vm_device *device_ctx = to_vm_device(dev); struct input_device_context *input_device_ctx = @@ -1088,10 +1078,6 @@ static int __init mousevsc_init(void) DPRINT_INFO(INPUTVSC_DRV, "Hyper-V Mouse driver initializing."); - input_drv_obj->OnDeviceInfo = mousevsc_deviceinfo_callback; - input_drv_obj->OnInputReport = mousevsc_inputreport_callback; - input_drv_obj->OnReportDescriptor = mousevsc_reportdesc_callback; - /* Callback to client driver to complete the initialization */ mouse_vsc_initialize(&input_drv_obj->Base); -- cgit v1.2.3 From 037b653aae18147af152cc31d3c4c0cd072ffea9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 18:40:16 -0800 Subject: Staging: hv: hv_mouse: remove inline function markings They are totally useless here, so remove them. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 15b4399130da..2e9e70ab93ce 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -222,7 +222,7 @@ static void deviceinfo_callback(struct hv_device *dev, struct input_dev_info *in static void inputreport_callback(struct hv_device *dev, void *packet, u32 len); static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len); -static inline struct mousevsc_dev *AllocInputDevice(struct hv_device *Device) +static struct mousevsc_dev *AllocInputDevice(struct hv_device *Device) { struct mousevsc_dev *inputDevice; @@ -243,7 +243,7 @@ static inline struct mousevsc_dev *AllocInputDevice(struct hv_device *Device) return inputDevice; } -static inline void FreeInputDevice(struct mousevsc_dev *Device) +static void FreeInputDevice(struct mousevsc_dev *Device) { WARN_ON(atomic_read(&Device->RefCount) == 0); kfree(Device); @@ -252,7 +252,7 @@ static inline void FreeInputDevice(struct mousevsc_dev *Device) /* * Get the inputdevice object if exists and its refcount > 1 */ -static inline struct mousevsc_dev *GetInputDevice(struct hv_device *Device) +static struct mousevsc_dev *GetInputDevice(struct hv_device *Device) { struct mousevsc_dev *inputDevice; @@ -278,7 +278,7 @@ static inline struct mousevsc_dev *GetInputDevice(struct hv_device *Device) /* * Get the inputdevice object iff exists and its refcount > 0 */ -static inline struct mousevsc_dev *MustGetInputDevice(struct hv_device *Device) +static struct mousevsc_dev *MustGetInputDevice(struct hv_device *Device) { struct mousevsc_dev *inputDevice; @@ -292,7 +292,7 @@ static inline struct mousevsc_dev *MustGetInputDevice(struct hv_device *Device) return inputDevice; } -static inline void PutInputDevice(struct hv_device *Device) +static void PutInputDevice(struct hv_device *Device) { struct mousevsc_dev *inputDevice; @@ -304,7 +304,7 @@ static inline void PutInputDevice(struct hv_device *Device) /* * Drop ref count to 1 to effectively disable GetInputDevice() */ -static inline struct mousevsc_dev *ReleaseInputDevice(struct hv_device *Device) +static struct mousevsc_dev *ReleaseInputDevice(struct hv_device *Device) { struct mousevsc_dev *inputDevice; @@ -320,7 +320,7 @@ static inline struct mousevsc_dev *ReleaseInputDevice(struct hv_device *Device) /* * Drop ref count to 0. No one can use InputDevice object. */ -static inline struct mousevsc_dev *FinalReleaseInputDevice(struct hv_device *Device) +static struct mousevsc_dev *FinalReleaseInputDevice(struct hv_device *Device) { struct mousevsc_dev *inputDevice; -- cgit v1.2.3 From ac2c9033d65c7b139c99c9ecd2f374f04ea5820a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 18:50:15 -0800 Subject: Staging: hv: hv_mouse: reorder functions to remove forward declarations This removes almost all forward declarations and makes all functions static, as there should not be any global functions in this module at all. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 497 +++++++++++++++++++----------------------- 1 file changed, 221 insertions(+), 276 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 2e9e70ab93ce..5ab2b934c9ef 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -202,19 +202,6 @@ static const struct hv_guid gMousevscDeviceType = { 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A} }; -/* - * Internal routines - */ -static int MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo); - -static int MousevscOnDeviceRemove(struct hv_device *Device); - -static void MousevscOnCleanup(struct hv_driver *Device); - -static void MousevscOnChannelCallback(void *Context); - -static int MousevscConnectToVsp(struct hv_device *Device); - static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet); @@ -334,250 +321,7 @@ static struct mousevsc_dev *FinalReleaseInputDevice(struct hv_device *Device) return inputDevice; } -static int mouse_vsc_initialize(struct hv_driver *Driver) -{ - struct mousevsc_drv_obj *inputDriver = - (struct mousevsc_drv_obj *)Driver; - int ret = 0; - - Driver->name = gDriverName; - memcpy(&Driver->dev_type, &gMousevscDeviceType, - sizeof(struct hv_guid)); - - /* Setup the dispatch table */ - inputDriver->Base.dev_add = MousevscOnDeviceAdd; - inputDriver->Base.dev_rm = MousevscOnDeviceRemove; - inputDriver->Base.cleanup = MousevscOnCleanup; - - return ret; -} - -/* - * - * Name: - * MousevscOnDeviceAdd() - * - * Description: - * Callback when the device belonging to this driver is added - * - */ -int -MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) -{ - int ret = 0; - struct mousevsc_dev *inputDevice; - struct mousevsc_drv_obj *inputDriver; - struct input_dev_info deviceInfo; - - inputDevice = AllocInputDevice(Device); - - if (!inputDevice) { - ret = -1; - goto Cleanup; - } - - inputDevice->bInitializeComplete = false; - - /* Open the channel */ - ret = vmbus_open(Device->channel, - INPUTVSC_SEND_RING_BUFFER_SIZE, - INPUTVSC_RECV_RING_BUFFER_SIZE, - NULL, - 0, - MousevscOnChannelCallback, - Device - ); - - if (ret != 0) { - pr_err("unable to open channel: %d", ret); - return -1; - } - - pr_info("InputVsc channel open: %d", ret); - - ret = MousevscConnectToVsp(Device); - - if (ret != 0) { - pr_err("unable to connect channel: %d", ret); - - vmbus_close(Device->channel); - return ret; - } - - inputDriver = (struct mousevsc_drv_obj *)inputDevice->Device->drv; - - deviceInfo.VendorID = inputDevice->DeviceAttr.VendorID; - deviceInfo.ProductID = inputDevice->DeviceAttr.ProductID; - deviceInfo.VersionNumber = inputDevice->DeviceAttr.VersionNumber; - strcpy(deviceInfo.Name, "Microsoft Vmbus HID-compliant Mouse"); - - /* Send the device info back up */ - deviceinfo_callback(Device, &deviceInfo); - - /* Send the report desc back up */ - /* workaround SA-167 */ - if (inputDevice->ReportDesc[14] == 0x25) - inputDevice->ReportDesc[14] = 0x29; - - reportdesc_callback(Device, inputDevice->ReportDesc, - inputDevice->ReportDescSize); - - inputDevice->bInitializeComplete = true; - -Cleanup: - return ret; -} - -int -MousevscConnectToVsp(struct hv_device *Device) -{ - int ret = 0; - struct mousevsc_dev *inputDevice; - struct mousevsc_prt_msg *request; - struct mousevsc_prt_msg *response; - - inputDevice = GetInputDevice(Device); - - if (!inputDevice) { - pr_err("unable to get input device...device being destroyed?"); - return -1; - } - - init_waitqueue_head(&inputDevice->ProtocolWaitEvent); - init_waitqueue_head(&inputDevice->DeviceInfoWaitEvent); - - request = &inputDevice->ProtocolReq; - - /* - * Now, initiate the vsc/vsp initialization protocol on the open channel - */ - memset(request, sizeof(struct mousevsc_prt_msg), 0); - - request->PacketType = PipeMessageData; - request->DataSize = sizeof(struct synthhid_protocol_request); - - request->u.Request.Header.Type = SynthHidProtocolRequest; - request->u.Request.Header.Size = sizeof(unsigned long); - request->u.Request.VersionRequested.AsDWord = - SYNTHHID_INPUT_VERSION_DWORD; - - pr_info("synthhid protocol request..."); - - ret = vmbus_sendpacket(Device->channel, request, - sizeof(struct pipe_prt_msg) - - sizeof(unsigned char) + - sizeof(struct synthhid_protocol_request), - (unsigned long)request, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - if (ret != 0) { - pr_err("unable to send synthhid protocol request."); - goto Cleanup; - } - - inputDevice->protocol_wait_condition = 0; - wait_event_timeout(inputDevice->ProtocolWaitEvent, inputDevice->protocol_wait_condition, msecs_to_jiffies(1000)); - if (inputDevice->protocol_wait_condition == 0) { - ret = -ETIMEDOUT; - goto Cleanup; - } - - response = &inputDevice->ProtocolResp; - - if (!response->u.Response.Approved) { - pr_err("synthhid protocol request failed (version %d)", - SYNTHHID_INPUT_VERSION_DWORD); - ret = -1; - goto Cleanup; - } - - inputDevice->device_wait_condition = 0; - wait_event_timeout(inputDevice->DeviceInfoWaitEvent, inputDevice->device_wait_condition, msecs_to_jiffies(1000)); - if (inputDevice->device_wait_condition == 0) { - ret = -ETIMEDOUT; - goto Cleanup; - } - - /* - * We should have gotten the device attr, hid desc and report - * desc at this point - */ - if (!inputDevice->DeviceInfoStatus) - pr_info("**** input channel up and running!! ****"); - else - ret = -1; - -Cleanup: - PutInputDevice(Device); - - return ret; -} - - -/* - * - * Name: - * MousevscOnDeviceRemove() - * - * Description: - * Callback when the our device is being removed - * - */ -int -MousevscOnDeviceRemove(struct hv_device *Device) -{ - struct mousevsc_dev *inputDevice; - int ret = 0; - - pr_info("disabling input device (%p)...", - Device->ext); - - inputDevice = ReleaseInputDevice(Device); - - - /* - * At this point, all outbound traffic should be disable. We only - * allow inbound traffic (responses) to proceed - * - * so that outstanding requests can be completed. - */ - while (inputDevice->NumOutstandingRequests) { - pr_info("waiting for %d requests to complete...", inputDevice->NumOutstandingRequests); - - udelay(100); - } - - pr_info("removing input device (%p)...", Device->ext); - - inputDevice = FinalReleaseInputDevice(Device); - - pr_info("input device (%p) safe to remove", inputDevice); - - /* Close the channel */ - vmbus_close(Device->channel); - - FreeInputDevice(inputDevice); - - return ret; -} - - -/* - * - * Name: - * MousevscOnCleanup() - * - * Description: - * Perform any cleanup when the driver is removed - */ -static void MousevscOnCleanup(struct hv_driver *drv) -{ -} - - -static void -MousevscOnSendCompletion(struct hv_device *Device, - struct vmpacket_descriptor *Packet) +static void MousevscOnSendCompletion(struct hv_device *Device, struct vmpacket_descriptor *Packet) { struct mousevsc_dev *inputDevice; void *request; @@ -598,10 +342,7 @@ MousevscOnSendCompletion(struct hv_device *Device, PutInputDevice(Device); } -void -MousevscOnReceiveDeviceInfo( - struct mousevsc_dev *InputDevice, - struct synthhid_device_info *DeviceInfo) +static void MousevscOnReceiveDeviceInfo(struct mousevsc_dev *InputDevice, struct synthhid_device_info *DeviceInfo) { int ret = 0; struct hid_descriptor *desc; @@ -685,11 +426,7 @@ Cleanup: wake_up(&InputDevice->DeviceInfoWaitEvent); } - -void -MousevscOnReceiveInputReport( - struct mousevsc_dev *InputDevice, - struct synthhid_input_report *InputReport) +static void MousevscOnReceiveInputReport(struct mousevsc_dev *InputDevice, struct synthhid_input_report *InputReport) { struct mousevsc_drv_obj *inputDriver; @@ -705,8 +442,7 @@ MousevscOnReceiveInputReport( InputReport->Header.Size); } -void -MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet) +static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet) { struct pipe_prt_msg *pipeMsg; struct synthhid_msg *hidMsg; @@ -760,7 +496,7 @@ MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet) PutInputDevice(Device); } -void MousevscOnChannelCallback(void *Context) +static void MousevscOnChannelCallback(void *Context) { const int packetSize = 0x100; int ret = 0; @@ -848,6 +584,197 @@ void MousevscOnChannelCallback(void *Context) return; } +static int MousevscConnectToVsp(struct hv_device *Device) +{ + int ret = 0; + struct mousevsc_dev *inputDevice; + struct mousevsc_prt_msg *request; + struct mousevsc_prt_msg *response; + + inputDevice = GetInputDevice(Device); + + if (!inputDevice) { + pr_err("unable to get input device...device being destroyed?"); + return -1; + } + + init_waitqueue_head(&inputDevice->ProtocolWaitEvent); + init_waitqueue_head(&inputDevice->DeviceInfoWaitEvent); + + request = &inputDevice->ProtocolReq; + + /* + * Now, initiate the vsc/vsp initialization protocol on the open channel + */ + memset(request, sizeof(struct mousevsc_prt_msg), 0); + + request->PacketType = PipeMessageData; + request->DataSize = sizeof(struct synthhid_protocol_request); + + request->u.Request.Header.Type = SynthHidProtocolRequest; + request->u.Request.Header.Size = sizeof(unsigned long); + request->u.Request.VersionRequested.AsDWord = + SYNTHHID_INPUT_VERSION_DWORD; + + pr_info("synthhid protocol request..."); + + ret = vmbus_sendpacket(Device->channel, request, + sizeof(struct pipe_prt_msg) - + sizeof(unsigned char) + + sizeof(struct synthhid_protocol_request), + (unsigned long)request, + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if (ret != 0) { + pr_err("unable to send synthhid protocol request."); + goto Cleanup; + } + + inputDevice->protocol_wait_condition = 0; + wait_event_timeout(inputDevice->ProtocolWaitEvent, inputDevice->protocol_wait_condition, msecs_to_jiffies(1000)); + if (inputDevice->protocol_wait_condition == 0) { + ret = -ETIMEDOUT; + goto Cleanup; + } + + response = &inputDevice->ProtocolResp; + + if (!response->u.Response.Approved) { + pr_err("synthhid protocol request failed (version %d)", + SYNTHHID_INPUT_VERSION_DWORD); + ret = -1; + goto Cleanup; + } + + inputDevice->device_wait_condition = 0; + wait_event_timeout(inputDevice->DeviceInfoWaitEvent, inputDevice->device_wait_condition, msecs_to_jiffies(1000)); + if (inputDevice->device_wait_condition == 0) { + ret = -ETIMEDOUT; + goto Cleanup; + } + + /* + * We should have gotten the device attr, hid desc and report + * desc at this point + */ + if (!inputDevice->DeviceInfoStatus) + pr_info("**** input channel up and running!! ****"); + else + ret = -1; + +Cleanup: + PutInputDevice(Device); + + return ret; +} + +static int MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) +{ + int ret = 0; + struct mousevsc_dev *inputDevice; + struct mousevsc_drv_obj *inputDriver; + struct input_dev_info deviceInfo; + + inputDevice = AllocInputDevice(Device); + + if (!inputDevice) { + ret = -1; + goto Cleanup; + } + + inputDevice->bInitializeComplete = false; + + /* Open the channel */ + ret = vmbus_open(Device->channel, + INPUTVSC_SEND_RING_BUFFER_SIZE, + INPUTVSC_RECV_RING_BUFFER_SIZE, + NULL, + 0, + MousevscOnChannelCallback, + Device + ); + + if (ret != 0) { + pr_err("unable to open channel: %d", ret); + return -1; + } + + pr_info("InputVsc channel open: %d", ret); + + ret = MousevscConnectToVsp(Device); + + if (ret != 0) { + pr_err("unable to connect channel: %d", ret); + + vmbus_close(Device->channel); + return ret; + } + + inputDriver = (struct mousevsc_drv_obj *)inputDevice->Device->drv; + + deviceInfo.VendorID = inputDevice->DeviceAttr.VendorID; + deviceInfo.ProductID = inputDevice->DeviceAttr.ProductID; + deviceInfo.VersionNumber = inputDevice->DeviceAttr.VersionNumber; + strcpy(deviceInfo.Name, "Microsoft Vmbus HID-compliant Mouse"); + + /* Send the device info back up */ + deviceinfo_callback(Device, &deviceInfo); + + /* Send the report desc back up */ + /* workaround SA-167 */ + if (inputDevice->ReportDesc[14] == 0x25) + inputDevice->ReportDesc[14] = 0x29; + + reportdesc_callback(Device, inputDevice->ReportDesc, + inputDevice->ReportDescSize); + + inputDevice->bInitializeComplete = true; + +Cleanup: + return ret; +} + +static int MousevscOnDeviceRemove(struct hv_device *Device) +{ + struct mousevsc_dev *inputDevice; + int ret = 0; + + pr_info("disabling input device (%p)...", + Device->ext); + + inputDevice = ReleaseInputDevice(Device); + + + /* + * At this point, all outbound traffic should be disable. We only + * allow inbound traffic (responses) to proceed + * + * so that outstanding requests can be completed. + */ + while (inputDevice->NumOutstandingRequests) { + pr_info("waiting for %d requests to complete...", inputDevice->NumOutstandingRequests); + + udelay(100); + } + + pr_info("removing input device (%p)...", Device->ext); + + inputDevice = FinalReleaseInputDevice(Device); + + pr_info("input device (%p) safe to remove", inputDevice); + + /* Close the channel */ + vmbus_close(Device->channel); + + FreeInputDevice(inputDevice); + + return ret; +} + +static void MousevscOnCleanup(struct hv_driver *drv) +{ +} + /* * Data types */ @@ -892,16 +819,16 @@ static void inputreport_callback(struct hv_device *dev, void *packet, u32 len) DPRINT_DBG(INPUTVSC_DRV, "hid_input_report (ret %d)", ret); } -int mousevsc_hid_open(struct hid_device *hid) +static int mousevsc_hid_open(struct hid_device *hid) { return 0; } -void mousevsc_hid_close(struct hid_device *hid) +static void mousevsc_hid_close(struct hid_device *hid) { } -int mousevsc_probe(struct device *device) +static int mousevsc_probe(struct device *device) { int ret = 0; @@ -932,8 +859,7 @@ int mousevsc_probe(struct device *device) return 0; } - -int mousevsc_remove(struct device *device) +static int mousevsc_remove(struct device *device) { int ret = 0; @@ -1030,7 +956,7 @@ static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len) kfree(hid_dev); } -int mousevsc_drv_exit_cb(struct device *dev, void *data) +static int mousevsc_drv_exit_cb(struct device *dev, void *data) { struct device **curr = (struct device **)data; *curr = dev; @@ -1038,7 +964,7 @@ int mousevsc_drv_exit_cb(struct device *dev, void *data) return 1; } -void mousevsc_drv_exit(void) +static void mousevsc_drv_exit(void) { struct mousevsc_drv_obj *mousevsc_drv_obj = &g_mousevsc_drv.drv_obj; struct driver_context *drv_ctx = &g_mousevsc_drv.drv_ctx; @@ -1071,6 +997,25 @@ void mousevsc_drv_exit(void) return; } +static int mouse_vsc_initialize(struct hv_driver *Driver) +{ + struct mousevsc_drv_obj *inputDriver = + (struct mousevsc_drv_obj *)Driver; + int ret = 0; + + Driver->name = gDriverName; + memcpy(&Driver->dev_type, &gMousevscDeviceType, + sizeof(struct hv_guid)); + + /* Setup the dispatch table */ + inputDriver->Base.dev_add = MousevscOnDeviceAdd; + inputDriver->Base.dev_rm = MousevscOnDeviceRemove; + inputDriver->Base.cleanup = MousevscOnCleanup; + + return ret; +} + + static int __init mousevsc_init(void) { struct mousevsc_drv_obj *input_drv_obj = &g_mousevsc_drv.drv_obj; -- cgit v1.2.3 From 0f88ea5ba24f56bc0915d60bf9c859fb8952e62c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 18:57:04 -0800 Subject: Staging: hv: hv_mouse: fix up input device info structure Make the name "hv_" specific as it's not an input layer structure we are dealing with here. Also rename the fields to be not CamelCase. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 45 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 5ab2b934c9ef..7a14cb056e22 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -36,11 +36,11 @@ /* * Data types */ -struct input_dev_info { - unsigned short VendorID; - unsigned short ProductID; - unsigned short VersionNumber; - char Name[128]; +struct hv_input_dev_info { + unsigned short vendor; + unsigned short product; + unsigned short version; + char name[128]; }; /* Represents the input vsc driver */ @@ -119,7 +119,7 @@ struct synthhid_protocol_response { struct synthhid_device_info { struct synthhid_msg_hdr Header; - struct input_dev_info HidDeviceAttributes; + struct hv_input_dev_info HidDeviceAttributes; unsigned char HidDescriptorInformation[1]; }; @@ -187,7 +187,7 @@ struct mousevsc_dev { struct hid_descriptor *HidDesc; unsigned char *ReportDesc; u32 ReportDescSize; - struct input_dev_info DeviceAttr; + struct hv_input_dev_info DeviceAttr; }; @@ -205,7 +205,7 @@ static const struct hv_guid gMousevscDeviceType = { static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet); -static void deviceinfo_callback(struct hv_device *dev, struct input_dev_info *info); +static void deviceinfo_callback(struct hv_device *dev, struct hv_input_dev_info *info); static void inputreport_callback(struct hv_device *dev, void *packet, u32 len); static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len); @@ -352,7 +352,7 @@ static void MousevscOnReceiveDeviceInfo(struct mousevsc_dev *InputDevice, struct InputDevice->DeviceInfoStatus = 0; /* Save the device attr */ - memcpy(&InputDevice->DeviceAttr, &DeviceInfo->HidDeviceAttributes, sizeof(struct input_dev_info)); + memcpy(&InputDevice->DeviceAttr, &DeviceInfo->HidDeviceAttributes, sizeof(struct hv_input_dev_info)); /* Save the hid desc */ desc = (struct hid_descriptor *)DeviceInfo->HidDescriptorInformation; @@ -473,7 +473,7 @@ static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descript break; case SynthHidInitialDeviceInfo: - WARN_ON(pipeMsg->DataSize >= sizeof(struct input_dev_info)); + WARN_ON(pipeMsg->DataSize >= sizeof(struct hv_input_dev_info)); /* * Parse out the device info into device attr, @@ -673,7 +673,7 @@ static int MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) int ret = 0; struct mousevsc_dev *inputDevice; struct mousevsc_drv_obj *inputDriver; - struct input_dev_info deviceInfo; + struct hv_input_dev_info deviceInfo; inputDevice = AllocInputDevice(Device); @@ -712,10 +712,10 @@ static int MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) inputDriver = (struct mousevsc_drv_obj *)inputDevice->Device->drv; - deviceInfo.VendorID = inputDevice->DeviceAttr.VendorID; - deviceInfo.ProductID = inputDevice->DeviceAttr.ProductID; - deviceInfo.VersionNumber = inputDevice->DeviceAttr.VersionNumber; - strcpy(deviceInfo.Name, "Microsoft Vmbus HID-compliant Mouse"); + deviceInfo.vendor = inputDevice->DeviceAttr.vendor; + deviceInfo.product = inputDevice->DeviceAttr.product; + deviceInfo.version = inputDevice->DeviceAttr.version; + strcpy(deviceInfo.name, "Microsoft Vmbus HID-compliant Mouse"); /* Send the device info back up */ deviceinfo_callback(Device, &deviceInfo); @@ -781,7 +781,7 @@ static void MousevscOnCleanup(struct hv_driver *drv) struct input_device_context { struct vm_device *device_ctx; struct hid_device *hid_device; - struct input_dev_info device_info; + struct hv_input_dev_info device_info; int connected; }; @@ -792,15 +792,14 @@ struct mousevsc_driver_context { static struct mousevsc_driver_context g_mousevsc_drv; -static void deviceinfo_callback(struct hv_device *dev, - struct input_dev_info *info) +static void deviceinfo_callback(struct hv_device *dev, struct hv_input_dev_info *info) { struct vm_device *device_ctx = to_vm_device(dev); struct input_device_context *input_device_ctx = dev_get_drvdata(&device_ctx->device); memcpy(&input_device_ctx->device_info, info, - sizeof(struct input_dev_info)); + sizeof(struct hv_input_dev_info)); DPRINT_INFO(INPUTVSC_DRV, "%s", __func__); } @@ -924,13 +923,13 @@ static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len) hid_dev->ll_driver->close = mousevsc_hid_close; hid_dev->bus = 0x06; /* BUS_VIRTUAL */ - hid_dev->vendor = input_device_ctx->device_info.VendorID; - hid_dev->product = input_device_ctx->device_info.ProductID; - hid_dev->version = input_device_ctx->device_info.VersionNumber; + hid_dev->vendor = input_device_ctx->device_info.vendor; + hid_dev->product = input_device_ctx->device_info.product; + hid_dev->version = input_device_ctx->device_info.version; hid_dev->dev = device_ctx->device; sprintf(hid_dev->name, "%s", - input_device_ctx->device_info.Name); + input_device_ctx->device_info.name); /* * HJ Do we want to call it with a 0 -- cgit v1.2.3 From c9246c9022095d278082cae4e82312e69453769e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 18:58:35 -0800 Subject: Staging: hv: hv_mouse: use proper input define for bus type The code was so close, the bus type was in a comment, so go all the way and actually use the define here. It's as if the original author was so afraid of license issues if they referenced a define in the processed code but they felt safe to keep it in a comment. Chicken. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 7a14cb056e22..3773ba87dba4 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -922,7 +922,7 @@ static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len) hid_dev->ll_driver->open = mousevsc_hid_open; hid_dev->ll_driver->close = mousevsc_hid_close; - hid_dev->bus = 0x06; /* BUS_VIRTUAL */ + hid_dev->bus = BUS_VIRTUAL; hid_dev->vendor = input_device_ctx->device_info.vendor; hid_dev->product = input_device_ctx->device_info.product; hid_dev->version = input_device_ctx->device_info.version; -- cgit v1.2.3 From 32ad38f7d529c31566533bb9433b8d1bf1a04ec1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 19:01:49 -0800 Subject: Staging: hv: hv_mouse.c: clean up struct synthhid_msg_hdr Use non-CamelCase names for this structure. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 3773ba87dba4..5ee1e56e6f29 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -83,10 +83,8 @@ enum synthhid_msg_type { * Basic message structures. */ struct synthhid_msg_hdr { - enum synthhid_msg_type Type; /* Type of the enclosed message */ - u32 Size; /* Size of the enclosed message - * (size of the data payload) - */ + enum synthhid_msg_type type; + u32 size; }; struct synthhid_msg { @@ -388,8 +386,8 @@ static void MousevscOnReceiveDeviceInfo(struct mousevsc_dev *InputDevice, struct ack.PacketType = PipeMessageData; ack.DataSize = sizeof(struct synthhid_device_info_ack); - ack.u.Ack.Header.Type = SynthHidInitialDeviceInfoAck; - ack.u.Ack.Header.Size = 1; + ack.u.Ack.Header.type = SynthHidInitialDeviceInfoAck; + ack.u.Ack.Header.size = 1; ack.u.Ack.Reserved = 0; ret = vmbus_sendpacket(InputDevice->Device->channel, @@ -439,7 +437,7 @@ static void MousevscOnReceiveInputReport(struct mousevsc_dev *InputDevice, struc inputreport_callback(InputDevice->Device, InputReport->ReportBuffer, - InputReport->Header.Size); + InputReport->Header.size); } static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet) @@ -465,7 +463,7 @@ static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descript hidMsg = (struct synthhid_msg *)&pipeMsg->Data[0]; - switch (hidMsg->Header.Type) { + switch (hidMsg->Header.type) { case SynthHidProtocolResponse: memcpy(&inputDevice->ProtocolResp, pipeMsg, pipeMsg->DataSize+sizeof(struct pipe_prt_msg) - sizeof(unsigned char)); inputDevice->protocol_wait_condition = 1; @@ -489,7 +487,7 @@ static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descript break; default: pr_err("unsupported hid msg type - type %d len %d", - hidMsg->Header.Type, hidMsg->Header.Size); + hidMsg->Header.type, hidMsg->Header.size); break; } @@ -611,8 +609,8 @@ static int MousevscConnectToVsp(struct hv_device *Device) request->PacketType = PipeMessageData; request->DataSize = sizeof(struct synthhid_protocol_request); - request->u.Request.Header.Type = SynthHidProtocolRequest; - request->u.Request.Header.Size = sizeof(unsigned long); + request->u.Request.Header.type = SynthHidProtocolRequest; + request->u.Request.Header.size = sizeof(unsigned long); request->u.Request.VersionRequested.AsDWord = SYNTHHID_INPUT_VERSION_DWORD; -- cgit v1.2.3 From 0ce815d54e55611e1567e17c08f57d1b2e0ab0d9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 19:04:09 -0800 Subject: Staging: hv: hv_mouse: fix camelcase use of struct synthhid_msg_hdr s/Header/header/g for this structure when it is used in the file. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 5ee1e56e6f29..b7e75e023cd8 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -88,7 +88,7 @@ struct synthhid_msg_hdr { }; struct synthhid_msg { - struct synthhid_msg_hdr Header; + struct synthhid_msg_hdr header; char Data[1]; /* Enclosed message */ }; @@ -105,29 +105,29 @@ union synthhid_version { * Protocol messages */ struct synthhid_protocol_request { - struct synthhid_msg_hdr Header; + struct synthhid_msg_hdr header; union synthhid_version VersionRequested; }; struct synthhid_protocol_response { - struct synthhid_msg_hdr Header; + struct synthhid_msg_hdr header; union synthhid_version VersionRequested; unsigned char Approved; }; struct synthhid_device_info { - struct synthhid_msg_hdr Header; + struct synthhid_msg_hdr header; struct hv_input_dev_info HidDeviceAttributes; unsigned char HidDescriptorInformation[1]; }; struct synthhid_device_info_ack { - struct synthhid_msg_hdr Header; + struct synthhid_msg_hdr header; unsigned char Reserved; }; struct synthhid_input_report { - struct synthhid_msg_hdr Header; + struct synthhid_msg_hdr header; char ReportBuffer[1]; }; @@ -386,8 +386,8 @@ static void MousevscOnReceiveDeviceInfo(struct mousevsc_dev *InputDevice, struct ack.PacketType = PipeMessageData; ack.DataSize = sizeof(struct synthhid_device_info_ack); - ack.u.Ack.Header.type = SynthHidInitialDeviceInfoAck; - ack.u.Ack.Header.size = 1; + ack.u.Ack.header.type = SynthHidInitialDeviceInfoAck; + ack.u.Ack.header.size = 1; ack.u.Ack.Reserved = 0; ret = vmbus_sendpacket(InputDevice->Device->channel, @@ -437,7 +437,7 @@ static void MousevscOnReceiveInputReport(struct mousevsc_dev *InputDevice, struc inputreport_callback(InputDevice->Device, InputReport->ReportBuffer, - InputReport->Header.size); + InputReport->header.size); } static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet) @@ -463,7 +463,7 @@ static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descript hidMsg = (struct synthhid_msg *)&pipeMsg->Data[0]; - switch (hidMsg->Header.type) { + switch (hidMsg->header.type) { case SynthHidProtocolResponse: memcpy(&inputDevice->ProtocolResp, pipeMsg, pipeMsg->DataSize+sizeof(struct pipe_prt_msg) - sizeof(unsigned char)); inputDevice->protocol_wait_condition = 1; @@ -487,7 +487,7 @@ static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descript break; default: pr_err("unsupported hid msg type - type %d len %d", - hidMsg->Header.type, hidMsg->Header.size); + hidMsg->header.type, hidMsg->header.size); break; } @@ -609,8 +609,8 @@ static int MousevscConnectToVsp(struct hv_device *Device) request->PacketType = PipeMessageData; request->DataSize = sizeof(struct synthhid_protocol_request); - request->u.Request.Header.type = SynthHidProtocolRequest; - request->u.Request.Header.size = sizeof(unsigned long); + request->u.Request.header.type = SynthHidProtocolRequest; + request->u.Request.header.size = sizeof(unsigned long); request->u.Request.VersionRequested.AsDWord = SYNTHHID_INPUT_VERSION_DWORD; -- cgit v1.2.3 From c4e68fa9537cb8190ba542a93558730783e49cdf Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 19:08:05 -0800 Subject: Staging: hv: hv_mouse: fix build warning The trans_id variable (u64) was being incorrectly cast to a unsigned long * when it should have just been unsigned long. Fun with pointers, what a fricken mess, we need some real type safety for these types of fields somehow... Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index b7e75e023cd8..49c0ad710816 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -330,7 +330,7 @@ static void MousevscOnSendCompletion(struct hv_device *Device, struct vmpacket_d return; } - request = (void *)(unsigned long *)Packet->trans_id; + request = (void *)(unsigned long)Packet->trans_id; if (request == &inputDevice->ProtocolReq) { /* FIXME */ -- cgit v1.2.3 From cb2535ad49972ab2ef3c872958bcd20b9532a308 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 19:11:49 -0800 Subject: Staging: hv: hv_mouse: change camelcase for struct synthhid_msg Turns out no one references the data field of this structure, so I wonder if it's really even needed at all. All this is used for is the type of the message here, so this structure might be able to be dropped entirely in the future. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 49c0ad710816..a80a15973cca 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -89,7 +89,7 @@ struct synthhid_msg_hdr { struct synthhid_msg { struct synthhid_msg_hdr header; - char Data[1]; /* Enclosed message */ + char data[1]; /* Enclosed message */ }; union synthhid_version { -- cgit v1.2.3 From 480c28df902b5dd5947950aef39d167b5668d3fe Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 19:18:34 -0800 Subject: Staging: hv: hv_mouse: clean up version structure usage Turns out no one uses the major or minor fields, but hey, we'll keep them around just to make people feel happy... Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index a80a15973cca..0f0caf0097fa 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -60,10 +60,10 @@ struct mousevsc_drv_obj { * Beta, RC < 2008/1/22 1,0 * RC > 2008/1/22 2,0 */ -#define SYNTHHID_INPUT_VERSION_MAJOR 2 -#define SYNTHHID_INPUT_VERSION_MINOR 0 -#define SYNTHHID_INPUT_VERSION_DWORD (SYNTHHID_INPUT_VERSION_MINOR | \ - (SYNTHHID_INPUT_VERSION_MAJOR << 16)) +#define SYNTHHID_INPUT_VERSION_MAJOR 2 +#define SYNTHHID_INPUT_VERSION_MINOR 0 +#define SYNTHHID_INPUT_VERSION (SYNTHHID_INPUT_VERSION_MINOR | \ + (SYNTHHID_INPUT_VERSION_MAJOR << 16)) #pragma pack(push,1) @@ -94,11 +94,10 @@ struct synthhid_msg { union synthhid_version { struct { - u16 Minor; - u16 Major; + u16 minor_version; + u16 major_version; }; - - u32 AsDWord; + u32 version; }; /* @@ -106,12 +105,12 @@ union synthhid_version { */ struct synthhid_protocol_request { struct synthhid_msg_hdr header; - union synthhid_version VersionRequested; + union synthhid_version version_requested; }; struct synthhid_protocol_response { struct synthhid_msg_hdr header; - union synthhid_version VersionRequested; + union synthhid_version version_requested; unsigned char Approved; }; @@ -611,8 +610,7 @@ static int MousevscConnectToVsp(struct hv_device *Device) request->u.Request.header.type = SynthHidProtocolRequest; request->u.Request.header.size = sizeof(unsigned long); - request->u.Request.VersionRequested.AsDWord = - SYNTHHID_INPUT_VERSION_DWORD; + request->u.Request.version_requested.version = SYNTHHID_INPUT_VERSION; pr_info("synthhid protocol request..."); @@ -639,7 +637,7 @@ static int MousevscConnectToVsp(struct hv_device *Device) if (!response->u.Response.Approved) { pr_err("synthhid protocol request failed (version %d)", - SYNTHHID_INPUT_VERSION_DWORD); + SYNTHHID_INPUT_VERSION); ret = -1; goto Cleanup; } -- cgit v1.2.3 From 325eae14448a7ce5e2410f61901fd740e6e93f7d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 19:19:58 -0800 Subject: Staging: hv: hv_mouse: clean up camelcase in struct synthhid_protocol_response Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 0f0caf0097fa..98242cffe203 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -111,7 +111,7 @@ struct synthhid_protocol_request { struct synthhid_protocol_response { struct synthhid_msg_hdr header; union synthhid_version version_requested; - unsigned char Approved; + unsigned char approved; }; struct synthhid_device_info { @@ -635,7 +635,7 @@ static int MousevscConnectToVsp(struct hv_device *Device) response = &inputDevice->ProtocolResp; - if (!response->u.Response.Approved) { + if (!response->u.Response.approved) { pr_err("synthhid protocol request failed (version %d)", SYNTHHID_INPUT_VERSION); ret = -1; -- cgit v1.2.3 From 98ad91ed32f6d9327b630f11315a40097e7897b2 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 19:24:05 -0800 Subject: Staging: hv: hv_mouse: clean up camelcase when using struct hv_input_dev_info I think there's a callback we can remove that uses this variable in the future as well, but that's for another patch... Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 98242cffe203..2ed67d93aed5 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -116,7 +116,7 @@ struct synthhid_protocol_response { struct synthhid_device_info { struct synthhid_msg_hdr header; - struct hv_input_dev_info HidDeviceAttributes; + struct hv_input_dev_info hid_dev_info; unsigned char HidDescriptorInformation[1]; }; @@ -184,7 +184,7 @@ struct mousevsc_dev { struct hid_descriptor *HidDesc; unsigned char *ReportDesc; u32 ReportDescSize; - struct hv_input_dev_info DeviceAttr; + struct hv_input_dev_info hid_dev_info; }; @@ -349,7 +349,7 @@ static void MousevscOnReceiveDeviceInfo(struct mousevsc_dev *InputDevice, struct InputDevice->DeviceInfoStatus = 0; /* Save the device attr */ - memcpy(&InputDevice->DeviceAttr, &DeviceInfo->HidDeviceAttributes, sizeof(struct hv_input_dev_info)); + memcpy(&InputDevice->hid_dev_info, &DeviceInfo->hid_dev_info, sizeof(struct hv_input_dev_info)); /* Save the hid desc */ desc = (struct hid_descriptor *)DeviceInfo->HidDescriptorInformation; @@ -669,7 +669,7 @@ static int MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) int ret = 0; struct mousevsc_dev *inputDevice; struct mousevsc_drv_obj *inputDriver; - struct hv_input_dev_info deviceInfo; + struct hv_input_dev_info dev_info; inputDevice = AllocInputDevice(Device); @@ -708,13 +708,13 @@ static int MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) inputDriver = (struct mousevsc_drv_obj *)inputDevice->Device->drv; - deviceInfo.vendor = inputDevice->DeviceAttr.vendor; - deviceInfo.product = inputDevice->DeviceAttr.product; - deviceInfo.version = inputDevice->DeviceAttr.version; - strcpy(deviceInfo.name, "Microsoft Vmbus HID-compliant Mouse"); + dev_info.vendor = inputDevice->hid_dev_info.vendor; + dev_info.product = inputDevice->hid_dev_info.product; + dev_info.version = inputDevice->hid_dev_info.version; + strcpy(dev_info.name, "Microsoft Vmbus HID-compliant Mouse"); /* Send the device info back up */ - deviceinfo_callback(Device, &deviceInfo); + deviceinfo_callback(Device, &dev_info); /* Send the report desc back up */ /* workaround SA-167 */ -- cgit v1.2.3 From 18bc44e333f9f278328eab851f27d1169d623efb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 19:27:17 -0800 Subject: Staging: hv: hv_mouse: use a real struct hid_descriptor The data coming from the vmbus is really a hid descriptor, so use that structure instead of having to mess around with a character array and pointer fun. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 2ed67d93aed5..90badf69e88a 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -117,7 +117,7 @@ struct synthhid_protocol_response { struct synthhid_device_info { struct synthhid_msg_hdr header; struct hv_input_dev_info hid_dev_info; - unsigned char HidDescriptorInformation[1]; + struct hid_descriptor hid_descriptor; }; struct synthhid_device_info_ack { @@ -352,7 +352,7 @@ static void MousevscOnReceiveDeviceInfo(struct mousevsc_dev *InputDevice, struct memcpy(&InputDevice->hid_dev_info, &DeviceInfo->hid_dev_info, sizeof(struct hv_input_dev_info)); /* Save the hid desc */ - desc = (struct hid_descriptor *)DeviceInfo->HidDescriptorInformation; + desc = &DeviceInfo->hid_descriptor; WARN_ON(desc->bLength > 0); InputDevice->HidDesc = kzalloc(desc->bLength, GFP_KERNEL); -- cgit v1.2.3 From 6ed10de1242f4044dabc1c115e84bbead2863524 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 19:29:42 -0800 Subject: Staging: hv: hv_mouse: fix camelcase in struct synthhid_device_info_ack Just one field to fix up, s/Reserved/reserved/g Odd that we have to set the reserved field to 0 when we send the message, that would imply that it really isn't "reserved"... Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 90badf69e88a..2dab7a20b57d 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -122,7 +122,7 @@ struct synthhid_device_info { struct synthhid_device_info_ack { struct synthhid_msg_hdr header; - unsigned char Reserved; + unsigned char reserved; }; struct synthhid_input_report { @@ -387,7 +387,7 @@ static void MousevscOnReceiveDeviceInfo(struct mousevsc_dev *InputDevice, struct ack.u.Ack.header.type = SynthHidInitialDeviceInfoAck; ack.u.Ack.header.size = 1; - ack.u.Ack.Reserved = 0; + ack.u.Ack.reserved = 0; ret = vmbus_sendpacket(InputDevice->Device->channel, &ack, -- cgit v1.2.3 From e93eff9cf4fd9d051d775972ef93c25e2df5dc1c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 19:31:39 -0800 Subject: Staging: hv: hv_mouse: clean up camelcase in struct synthhid_input_report Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 2dab7a20b57d..816f4b42b8eb 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -127,7 +127,7 @@ struct synthhid_device_info_ack { struct synthhid_input_report { struct synthhid_msg_hdr header; - char ReportBuffer[1]; + char buffer[1]; }; #pragma pack(pop) @@ -435,7 +435,7 @@ static void MousevscOnReceiveInputReport(struct mousevsc_dev *InputDevice, struc inputDriver = (struct mousevsc_drv_obj *)InputDevice->Device->drv; inputreport_callback(InputDevice->Device, - InputReport->ReportBuffer, + InputReport->buffer, InputReport->header.size); } -- cgit v1.2.3 From d7fa1a4629cd94e249b1556f58030174601ddbc4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 19:33:17 -0800 Subject: Staging: hv: hv_mouse: use an anonymous union for struct mousevsc_prt_msg Much nicer than having an ugly 'u.' in the structure usage, welcome to the 2000's... Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 816f4b42b8eb..b8760da1ebe7 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -160,7 +160,7 @@ struct mousevsc_prt_msg { struct synthhid_protocol_request Request; struct synthhid_protocol_response Response; struct synthhid_device_info_ack Ack; - } u; + }; }; /* @@ -385,9 +385,9 @@ static void MousevscOnReceiveDeviceInfo(struct mousevsc_dev *InputDevice, struct ack.PacketType = PipeMessageData; ack.DataSize = sizeof(struct synthhid_device_info_ack); - ack.u.Ack.header.type = SynthHidInitialDeviceInfoAck; - ack.u.Ack.header.size = 1; - ack.u.Ack.reserved = 0; + ack.Ack.header.type = SynthHidInitialDeviceInfoAck; + ack.Ack.header.size = 1; + ack.Ack.reserved = 0; ret = vmbus_sendpacket(InputDevice->Device->channel, &ack, @@ -608,9 +608,9 @@ static int MousevscConnectToVsp(struct hv_device *Device) request->PacketType = PipeMessageData; request->DataSize = sizeof(struct synthhid_protocol_request); - request->u.Request.header.type = SynthHidProtocolRequest; - request->u.Request.header.size = sizeof(unsigned long); - request->u.Request.version_requested.version = SYNTHHID_INPUT_VERSION; + request->Request.header.type = SynthHidProtocolRequest; + request->Request.header.size = sizeof(unsigned long); + request->Request.version_requested.version = SYNTHHID_INPUT_VERSION; pr_info("synthhid protocol request..."); @@ -635,7 +635,7 @@ static int MousevscConnectToVsp(struct hv_device *Device) response = &inputDevice->ProtocolResp; - if (!response->u.Response.approved) { + if (!response->Response.approved) { pr_err("synthhid protocol request failed (version %d)", SYNTHHID_INPUT_VERSION); ret = -1; -- cgit v1.2.3 From 2012d40dbda6f87537535bad38ccd84f8805de9e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 19:36:15 -0800 Subject: Staging: hv: hv_mouse: fix up camelcase use for enum pipe_prot_msg_type in structures It's a type, so call it that. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index b8760da1ebe7..d8945bb61272 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -145,7 +145,7 @@ enum pipe_prot_msg_type { struct pipe_prt_msg { - enum pipe_prot_msg_type PacketType; + enum pipe_prot_msg_type type; u32 DataSize; char Data[1]; }; @@ -154,7 +154,7 @@ struct pipe_prt_msg { * Data types */ struct mousevsc_prt_msg { - enum pipe_prot_msg_type PacketType; + enum pipe_prot_msg_type type; u32 DataSize; union { struct synthhid_protocol_request Request; @@ -382,7 +382,7 @@ static void MousevscOnReceiveDeviceInfo(struct mousevsc_dev *InputDevice, struct /* Send the ack */ memset(&ack, sizeof(struct mousevsc_prt_msg), 0); - ack.PacketType = PipeMessageData; + ack.type = PipeMessageData; ack.DataSize = sizeof(struct synthhid_device_info_ack); ack.Ack.header.type = SynthHidInitialDeviceInfoAck; @@ -453,9 +453,9 @@ static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descript pipeMsg = (struct pipe_prt_msg *)((unsigned long)Packet + (Packet->offset8 << 3)); - if (pipeMsg->PacketType != PipeMessageData) { + if (pipeMsg->type != PipeMessageData) { pr_err("unknown pipe msg type - type %d len %d", - pipeMsg->PacketType, pipeMsg->DataSize); + pipeMsg->type, pipeMsg->DataSize); PutInputDevice(Device); return ; } @@ -605,7 +605,7 @@ static int MousevscConnectToVsp(struct hv_device *Device) */ memset(request, sizeof(struct mousevsc_prt_msg), 0); - request->PacketType = PipeMessageData; + request->type = PipeMessageData; request->DataSize = sizeof(struct synthhid_protocol_request); request->Request.header.type = SynthHidProtocolRequest; -- cgit v1.2.3 From 9877fa4445b907b8aa271783e3e5ee99a143b65c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 19:38:29 -0800 Subject: Staging: hv: hv_mouse: fix up pipe size field name Make it not camelcase. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index d8945bb61272..5bee3ffb831d 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -146,7 +146,7 @@ enum pipe_prot_msg_type { struct pipe_prt_msg { enum pipe_prot_msg_type type; - u32 DataSize; + u32 size; char Data[1]; }; @@ -155,7 +155,7 @@ struct pipe_prt_msg { */ struct mousevsc_prt_msg { enum pipe_prot_msg_type type; - u32 DataSize; + u32 size; union { struct synthhid_protocol_request Request; struct synthhid_protocol_response Response; @@ -383,7 +383,7 @@ static void MousevscOnReceiveDeviceInfo(struct mousevsc_dev *InputDevice, struct memset(&ack, sizeof(struct mousevsc_prt_msg), 0); ack.type = PipeMessageData; - ack.DataSize = sizeof(struct synthhid_device_info_ack); + ack.size = sizeof(struct synthhid_device_info_ack); ack.Ack.header.type = SynthHidInitialDeviceInfoAck; ack.Ack.header.size = 1; @@ -455,7 +455,7 @@ static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descript if (pipeMsg->type != PipeMessageData) { pr_err("unknown pipe msg type - type %d len %d", - pipeMsg->type, pipeMsg->DataSize); + pipeMsg->type, pipeMsg->size); PutInputDevice(Device); return ; } @@ -464,13 +464,15 @@ static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descript switch (hidMsg->header.type) { case SynthHidProtocolResponse: - memcpy(&inputDevice->ProtocolResp, pipeMsg, pipeMsg->DataSize+sizeof(struct pipe_prt_msg) - sizeof(unsigned char)); + memcpy(&inputDevice->ProtocolResp, pipeMsg, + pipeMsg->size + sizeof(struct pipe_prt_msg) - + sizeof(unsigned char)); inputDevice->protocol_wait_condition = 1; wake_up(&inputDevice->ProtocolWaitEvent); break; case SynthHidInitialDeviceInfo: - WARN_ON(pipeMsg->DataSize >= sizeof(struct hv_input_dev_info)); + WARN_ON(pipeMsg->size >= sizeof(struct hv_input_dev_info)); /* * Parse out the device info into device attr, @@ -606,7 +608,7 @@ static int MousevscConnectToVsp(struct hv_device *Device) memset(request, sizeof(struct mousevsc_prt_msg), 0); request->type = PipeMessageData; - request->DataSize = sizeof(struct synthhid_protocol_request); + request->size = sizeof(struct synthhid_protocol_request); request->Request.header.type = SynthHidProtocolRequest; request->Request.header.size = sizeof(unsigned long); -- cgit v1.2.3 From e7de0adf89c2f8a36f839b9dfc98b91239f5a3d5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 19:39:48 -0800 Subject: Staging: hv: hv_mouse: fix up camelcase usage in struct pipe_prt_msg Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 5bee3ffb831d..95e9e68d7441 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -147,7 +147,7 @@ enum pipe_prot_msg_type { struct pipe_prt_msg { enum pipe_prot_msg_type type; u32 size; - char Data[1]; + char data[1]; }; /* @@ -460,7 +460,7 @@ static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descript return ; } - hidMsg = (struct synthhid_msg *)&pipeMsg->Data[0]; + hidMsg = (struct synthhid_msg *)&pipeMsg->data[0]; switch (hidMsg->header.type) { case SynthHidProtocolResponse: @@ -479,11 +479,11 @@ static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descript * hid desc and report desc */ MousevscOnReceiveDeviceInfo(inputDevice, - (struct synthhid_device_info *)&pipeMsg->Data[0]); + (struct synthhid_device_info *)&pipeMsg->data[0]); break; case SynthHidInputReport: MousevscOnReceiveInputReport(inputDevice, - (struct synthhid_input_report *)&pipeMsg->Data[0]); + (struct synthhid_input_report *)&pipeMsg->data[0]); break; default: -- cgit v1.2.3 From 5ff9b906c45bcb17dbf7922205dd95f9ca189a88 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 19:41:00 -0800 Subject: Staging: hv: hv_mouse: fix up camelcase fields in struct mousevsc_prt_msg Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 95e9e68d7441..0b10312ebe1d 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -157,9 +157,9 @@ struct mousevsc_prt_msg { enum pipe_prot_msg_type type; u32 size; union { - struct synthhid_protocol_request Request; - struct synthhid_protocol_response Response; - struct synthhid_device_info_ack Ack; + struct synthhid_protocol_request request; + struct synthhid_protocol_response response; + struct synthhid_device_info_ack ack; }; }; @@ -385,9 +385,9 @@ static void MousevscOnReceiveDeviceInfo(struct mousevsc_dev *InputDevice, struct ack.type = PipeMessageData; ack.size = sizeof(struct synthhid_device_info_ack); - ack.Ack.header.type = SynthHidInitialDeviceInfoAck; - ack.Ack.header.size = 1; - ack.Ack.reserved = 0; + ack.ack.header.type = SynthHidInitialDeviceInfoAck; + ack.ack.header.size = 1; + ack.ack.reserved = 0; ret = vmbus_sendpacket(InputDevice->Device->channel, &ack, @@ -610,9 +610,9 @@ static int MousevscConnectToVsp(struct hv_device *Device) request->type = PipeMessageData; request->size = sizeof(struct synthhid_protocol_request); - request->Request.header.type = SynthHidProtocolRequest; - request->Request.header.size = sizeof(unsigned long); - request->Request.version_requested.version = SYNTHHID_INPUT_VERSION; + request->request.header.type = SynthHidProtocolRequest; + request->request.header.size = sizeof(unsigned long); + request->request.version_requested.version = SYNTHHID_INPUT_VERSION; pr_info("synthhid protocol request..."); @@ -637,7 +637,7 @@ static int MousevscConnectToVsp(struct hv_device *Device) response = &inputDevice->ProtocolResp; - if (!response->Response.approved) { + if (!response->response.approved) { pr_err("synthhid protocol request failed (version %d)", SYNTHHID_INPUT_VERSION); ret = -1; -- cgit v1.2.3 From 92d40b769f2a98e949b6653d757c758e0a945baf Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 19:42:19 -0800 Subject: Staging: hv: hv_mouse: get rid of hungarian notation for name of the module And, it's not even a global, so the original creator got the Hungarian notation wrong! {sigh} Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 0b10312ebe1d..a3a4f28e4803 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -188,10 +188,7 @@ struct mousevsc_dev { }; -/* - * Globals - */ -static const char *gDriverName = "mousevsc"; +static const char *driver_name = "mousevsc"; /* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */ static const struct hv_guid gMousevscDeviceType = { @@ -1000,7 +997,7 @@ static int mouse_vsc_initialize(struct hv_driver *Driver) (struct mousevsc_drv_obj *)Driver; int ret = 0; - Driver->name = gDriverName; + Driver->name = driver_name; memcpy(&Driver->dev_type, &gMousevscDeviceType, sizeof(struct hv_guid)); -- cgit v1.2.3 From df7ed924e5f5b15828c803d666fbc260c504687a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 19:44:13 -0800 Subject: Staging: hv: hv_mouse: fix up guid variable name It wasn't a global either, yet it was called one for some reason... Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index a3a4f28e4803..8ae1eab2fb0a 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -191,7 +191,7 @@ struct mousevsc_dev { static const char *driver_name = "mousevsc"; /* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */ -static const struct hv_guid gMousevscDeviceType = { +static const struct hv_guid mouse_guid = { .data = {0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c, 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A} }; @@ -998,7 +998,7 @@ static int mouse_vsc_initialize(struct hv_driver *Driver) int ret = 0; Driver->name = driver_name; - memcpy(&Driver->dev_type, &gMousevscDeviceType, + memcpy(&Driver->dev_type, &mouse_guid, sizeof(struct hv_guid)); /* Setup the dispatch table */ -- cgit v1.2.3 From 8590a03125d8dde3993bbc7e7d13c9193f8dfd74 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 2 Mar 2011 19:45:17 -0800 Subject: Staging: hv: hv_mouse: remove unneeded function forward declaration When the code moved around earlier, this function declaration should have been removed but it wasn't. Resolve that. Cc: Hank Janssen Cc: K. Y. Srinivasan Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 8ae1eab2fb0a..1aaaef4695e3 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -196,9 +196,6 @@ static const struct hv_guid mouse_guid = { 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A} }; -static void MousevscOnReceive(struct hv_device *Device, - struct vmpacket_descriptor *Packet); - static void deviceinfo_callback(struct hv_device *dev, struct hv_input_dev_info *info); static void inputreport_callback(struct hv_device *dev, void *packet, u32 len); static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len); -- cgit v1.2.3 From 1558310d4942427f4fd19e8ae26ca0878ab10879 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Mon, 28 Feb 2011 17:34:15 +0000 Subject: cxgb{3,4}*: improve Kconfig dependencies - Remove the dependency of cxgb4 and cxgb4vf on INET. cxgb3 really depends on INET, keep it but add it directly to the driver's Kconfig entry. - Make the iSCSI drivers cxgb3i and cxgb4i available in the SCSI menu without requiring any options in the net driver menu to be enabled first. Add needed selects so the iSCSI drivers can build their corresponding net drivers. - Remove CHELSIO_T*_DEPENDS. Signed-off-by: Dimitris Michailidis Acked-by: Jan Beulich Signed-off-by: David S. Miller --- drivers/net/Kconfig | 21 +++------------------ drivers/scsi/cxgbi/cxgb3i/Kconfig | 4 +++- drivers/scsi/cxgbi/cxgb4i/Kconfig | 4 +++- 3 files changed, 9 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index f4b39274308a..6e09d5fea221 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2595,14 +2595,9 @@ config CHELSIO_T1_1G Enables support for Chelsio's gigabit Ethernet PCI cards. If you are using only 10G cards say 'N' here. -config CHELSIO_T3_DEPENDS - tristate - depends on PCI && INET - default y - config CHELSIO_T3 tristate "Chelsio Communications T3 10Gb Ethernet support" - depends on CHELSIO_T3_DEPENDS + depends on PCI && INET select FW_LOADER select MDIO help @@ -2620,14 +2615,9 @@ config CHELSIO_T3 To compile this driver as a module, choose M here: the module will be called cxgb3. -config CHELSIO_T4_DEPENDS - tristate - depends on PCI && INET - default y - config CHELSIO_T4 tristate "Chelsio Communications T4 Ethernet support" - depends on CHELSIO_T4_DEPENDS + depends on PCI select FW_LOADER select MDIO help @@ -2645,14 +2635,9 @@ config CHELSIO_T4 To compile this driver as a module choose M here; the module will be called cxgb4. -config CHELSIO_T4VF_DEPENDS - tristate - depends on PCI && INET - default y - config CHELSIO_T4VF tristate "Chelsio Communications T4 Virtual Function Ethernet support" - depends on CHELSIO_T4VF_DEPENDS + depends on PCI help This driver supports Chelsio T4-based gigabit and 10Gb Ethernet adapters with PCI-E SR-IOV Virtual Functions. diff --git a/drivers/scsi/cxgbi/cxgb3i/Kconfig b/drivers/scsi/cxgbi/cxgb3i/Kconfig index 5cf4e9831f1b..11dff23f7838 100644 --- a/drivers/scsi/cxgbi/cxgb3i/Kconfig +++ b/drivers/scsi/cxgbi/cxgb3i/Kconfig @@ -1,6 +1,8 @@ config SCSI_CXGB3_ISCSI tristate "Chelsio T3 iSCSI support" - depends on CHELSIO_T3_DEPENDS + depends on PCI && INET + select NETDEVICES + select NETDEV_10000 select CHELSIO_T3 select SCSI_ISCSI_ATTRS ---help--- diff --git a/drivers/scsi/cxgbi/cxgb4i/Kconfig b/drivers/scsi/cxgbi/cxgb4i/Kconfig index bb94b39b17b3..d5302c27f377 100644 --- a/drivers/scsi/cxgbi/cxgb4i/Kconfig +++ b/drivers/scsi/cxgbi/cxgb4i/Kconfig @@ -1,6 +1,8 @@ config SCSI_CXGB4_ISCSI tristate "Chelsio T4 iSCSI support" - depends on CHELSIO_T4_DEPENDS + depends on PCI && INET + select NETDEVICES + select NETDEV_10000 select CHELSIO_T4 select SCSI_ISCSI_ATTRS ---help--- -- cgit v1.2.3 From 9b082d734a938b951ed4b9b5a850ae3513d4a7e3 Mon Sep 17 00:00:00 2001 From: Stefan Assmann Date: Thu, 24 Feb 2011 20:03:31 +0000 Subject: igb: warn if max_vfs limit is exceeded Currently there's no warning printed when max_vfs > 7 is specified with igb and the maximum of 7 is silently enforced. This patch prints a warning and informs the user of the actions taken. Signed-off-by: Stefan Assmann Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/igb/igb_main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 579dbba5f9e4..eef380af0537 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -2291,7 +2291,12 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter) switch (hw->mac.type) { case e1000_82576: case e1000_i350: - adapter->vfs_allocated_count = (max_vfs > 7) ? 7 : max_vfs; + if (max_vfs > 7) { + dev_warn(&pdev->dev, + "Maximum of 7 VFs per PF, using max\n"); + adapter->vfs_allocated_count = 7; + } else + adapter->vfs_allocated_count = max_vfs; break; default: break; -- cgit v1.2.3 From 93ed835928f3100c95e0408df0543f35d03f7c23 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Thu, 24 Feb 2011 03:12:15 +0000 Subject: igb: Fix reg pattern test in ethtool for i350 devices This fixes the reg_pattern_test so that the test does not fail on i350 parts. Signed-off-by: Carolyn Wyborny Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/igb/igb_ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index a70e16bcfa7e..16bbd4922bc3 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -1070,7 +1070,7 @@ static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data, {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; for (pat = 0; pat < ARRAY_SIZE(_test); pat++) { wr32(reg, (_test[pat] & write)); - val = rd32(reg); + val = rd32(reg) & mask; if (val != (_test[pat] & write & mask)) { dev_err(&adapter->pdev->dev, "pattern test reg %04X " "failed: got 0x%08X expected 0x%08X\n", -- cgit v1.2.3 From 3b668a77bad7f03c3df28971760a3883a395ce55 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Wed, 2 Mar 2011 01:11:26 +0000 Subject: igb: Fix strncpy calls to be safe per source code review tools This fix changes the remaining calls to strncpy that have not yet been changed to use the "sizeof(buf) - 1" syntax rather than just a number for buffer size. Signed-off-by: Carolyn Wyborny Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/igb/igb_ethtool.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index 16bbd4922bc3..61f7849cb5a7 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -727,8 +727,9 @@ static void igb_get_drvinfo(struct net_device *netdev, char firmware_version[32]; u16 eeprom_data; - strncpy(drvinfo->driver, igb_driver_name, 32); - strncpy(drvinfo->version, igb_driver_version, 32); + strncpy(drvinfo->driver, igb_driver_name, sizeof(drvinfo->driver) - 1); + strncpy(drvinfo->version, igb_driver_version, + sizeof(drvinfo->version) - 1); /* EEPROM image version # is reported as firmware version # for * 82575 controllers */ @@ -738,8 +739,10 @@ static void igb_get_drvinfo(struct net_device *netdev, (eeprom_data & 0x0FF0) >> 4, eeprom_data & 0x000F); - strncpy(drvinfo->fw_version, firmware_version, 32); - strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); + strncpy(drvinfo->fw_version, firmware_version, + sizeof(drvinfo->fw_version) - 1); + strncpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info) - 1); drvinfo->n_stats = IGB_STATS_LEN; drvinfo->testinfo_len = IGB_TEST_LEN; drvinfo->regdump_len = igb_get_regs_len(netdev); -- cgit v1.2.3 From c82a538e4ff101faae030273243d3b0a0a9e335d Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Fri, 25 Feb 2011 03:34:18 +0000 Subject: ixgbevf: Fix Compiler Warnings Fix Compiler warnings of variables that are initialized but not used. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher --- drivers/net/ixgbevf/ixgbevf_main.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 1e735a14091c..82768812552d 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -178,8 +178,6 @@ static inline bool ixgbevf_check_tx_hang(struct ixgbevf_adapter *adapter, tx_ring->tx_buffer_info[eop].time_stamp && time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ)) { /* detected Tx unit hang */ - union ixgbe_adv_tx_desc *tx_desc; - tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop); printk(KERN_ERR "Detected Tx Unit Hang\n" " Tx Queue <%d>\n" " TDH, TDT <%x>, <%x>\n" @@ -334,7 +332,6 @@ static void ixgbevf_receive_skb(struct ixgbevf_q_vector *q_vector, struct ixgbevf_adapter *adapter = q_vector->adapter; bool is_vlan = (status & IXGBE_RXD_STAT_VP); u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan); - int ret; if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) { if (adapter->vlgrp && is_vlan) @@ -345,9 +342,9 @@ static void ixgbevf_receive_skb(struct ixgbevf_q_vector *q_vector, napi_gro_receive(&q_vector->napi, skb); } else { if (adapter->vlgrp && is_vlan) - ret = vlan_hwaccel_rx(skb, adapter->vlgrp, tag); + vlan_hwaccel_rx(skb, adapter->vlgrp, tag); else - ret = netif_rx(skb); + netif_rx(skb); } } @@ -3287,8 +3284,6 @@ static const struct net_device_ops ixgbe_netdev_ops = { static void ixgbevf_assign_netdev_ops(struct net_device *dev) { - struct ixgbevf_adapter *adapter; - adapter = netdev_priv(dev); dev->netdev_ops = &ixgbe_netdev_ops; ixgbevf_set_ethtool_ops(dev); dev->watchdog_timeo = 5 * HZ; -- cgit v1.2.3 From 888be1a1e148a5a600050d455f73370f51f26d59 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Tue, 8 Feb 2011 09:48:32 +0000 Subject: ixgbe: cleanup wake on LAN defines This change just cleans up a few defines in ixgbe_type.h related to wake on LAN. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_type.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index ab65d13969fd..18780d070145 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -91,7 +91,7 @@ /* General Receive Control */ #define IXGBE_GRC_MNG 0x00000001 /* Manageability Enable */ -#define IXGBE_GRC_APME 0x00000002 /* Advanced Power Management Enable */ +#define IXGBE_GRC_APME 0x00000002 /* APM enabled in EEPROM */ #define IXGBE_VPDDIAG0 0x10204 #define IXGBE_VPDDIAG1 0x10208 @@ -342,7 +342,7 @@ /* Wake Up Control */ #define IXGBE_WUC_PME_EN 0x00000002 /* PME Enable */ #define IXGBE_WUC_PME_STATUS 0x00000004 /* PME Status */ -#define IXGBE_WUC_ADVD3WUC 0x00000010 /* D3Cold wake up cap. enable*/ +#define IXGBE_WUC_WKEN 0x00000010 /* Enable PE_WAKE_N pin assertion */ /* Wake Up Filter Control */ #define IXGBE_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */ -- cgit v1.2.3 From dbf893ee85369debaa05b3c222a40c8ac5273a06 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Tue, 8 Feb 2011 09:42:41 +0000 Subject: ixgbe: cleanup logic related to HW semaphores This change cleans up much of the logic related to the hardware semaphores on the adapters. There were a number of issues with timings that needed to be addressed. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_common.c | 42 +++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index ebbda7d15254..345c32eab4a5 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -603,7 +603,6 @@ s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data) ixgbe_shift_out_eeprom_bits(hw, data, 16); ixgbe_standby_eeprom(hw); - msleep(hw->eeprom.semaphore_delay); /* Done with writing - release the EEPROM */ ixgbe_release_eeprom(hw); } @@ -747,7 +746,7 @@ s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg) static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw) { s32 status = 0; - u32 eec = 0; + u32 eec; u32 i; if (ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != 0) @@ -776,15 +775,15 @@ static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw) ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); status = IXGBE_ERR_EEPROM; } - } - /* Setup EEPROM for Read/Write */ - if (status == 0) { - /* Clear CS and SK */ - eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK); - IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); - IXGBE_WRITE_FLUSH(hw); - udelay(1); + /* Setup EEPROM for Read/Write */ + if (status == 0) { + /* Clear CS and SK */ + eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK); + IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); + IXGBE_WRITE_FLUSH(hw); + udelay(1); + } } return status; } @@ -798,13 +797,10 @@ static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw) static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw) { s32 status = IXGBE_ERR_EEPROM; - u32 timeout; + u32 timeout = 2000; u32 i; u32 swsm; - /* Set timeout value based on size of EEPROM */ - timeout = hw->eeprom.word_size + 1; - /* Get SMBI software semaphore between device drivers first */ for (i = 0; i < timeout; i++) { /* @@ -816,7 +812,7 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw) status = 0; break; } - msleep(1); + udelay(50); } /* Now get the semaphore between SW/FW through the SWESMBI bit */ @@ -844,11 +840,14 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw) * was not granted because we don't have access to the EEPROM */ if (i >= timeout) { - hw_dbg(hw, "Driver can't access the Eeprom - Semaphore " + hw_dbg(hw, "SWESMBI Software EEPROM semaphore " "not granted.\n"); ixgbe_release_eeprom_semaphore(hw); status = IXGBE_ERR_EEPROM; } + } else { + hw_dbg(hw, "Software semaphore SMBI between device drivers " + "not granted.\n"); } return status; @@ -1081,10 +1080,13 @@ static void ixgbe_release_eeprom(struct ixgbe_hw *hw) IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + + /* Delay before attempt to obtain semaphore again to allow FW access */ + msleep(hw->eeprom.semaphore_delay); } /** - * ixgbe_calc_eeprom_checksum - Calculates and returns the checksum + * ixgbe_calc_eeprom_checksum_generic - Calculates and returns the checksum * @hw: pointer to hardware structure **/ u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw) @@ -2206,6 +2208,10 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) s32 timeout = 200; while (timeout) { + /* + * SW EEPROM semaphore bit is used for access to all + * SW_FW_SYNC/GSSR bits (not just EEPROM) + */ if (ixgbe_get_eeprom_semaphore(hw)) return IXGBE_ERR_SWFW_SYNC; @@ -2223,7 +2229,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) } if (!timeout) { - hw_dbg(hw, "Driver can't access resource, GSSR timeout.\n"); + hw_dbg(hw, "Driver can't access resource, SW_FW_SYNC timeout.\n"); return IXGBE_ERR_SWFW_SYNC; } -- cgit v1.2.3 From 894ff7cf0e0cf7596f9b0d3c30e32c87f8df2784 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 15 Feb 2011 02:12:05 +0000 Subject: ixgbe: balance free_irq calls with request_irq calls We were incorrectly freeing IRQs that we had not requested. This change corrects that by making certain we only free q_vectors that we have requested IRQs for. Signed-off-by: Alexander Duyck Tested-by: Ross Brattain Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index f0d0c5aad2b4..588661ba2b9b 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2597,6 +2597,11 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter) i--; for (; i >= 0; i--) { + /* free only the irqs that were actually requested */ + if (!adapter->q_vector[i]->rxr_count && + !adapter->q_vector[i]->txr_count) + continue; + free_irq(adapter->msix_entries[i].vector, adapter->q_vector[i]); } -- cgit v1.2.3 From 21cc5b4f7eb7b6de90588331b7d0edb246502f46 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 12 Feb 2011 10:52:07 +0000 Subject: ixgbe: set media type for 82599 T3 LOM The media type was not being set for the 82599 T3 LAN on motherboard. This change corrects that. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82599.c | 50 ++++++++++++++++++++++++++++++++--------- drivers/net/ixgbe/ixgbe_main.c | 2 +- drivers/net/ixgbe/ixgbe_type.h | 1 + 3 files changed, 42 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index a21f5817685b..b45a491ac2e1 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -329,11 +329,14 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw) enum ixgbe_media_type media_type; /* Detect if there is a copper PHY attached. */ - if (hw->phy.type == ixgbe_phy_cu_unknown || - hw->phy.type == ixgbe_phy_tn || - hw->phy.type == ixgbe_phy_aq) { + switch (hw->phy.type) { + case ixgbe_phy_cu_unknown: + case ixgbe_phy_tn: + case ixgbe_phy_aq: media_type = ixgbe_media_type_copper; goto out; + default: + break; } switch (hw->device_id) { @@ -354,6 +357,9 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw) case IXGBE_DEV_ID_82599_CX4: media_type = ixgbe_media_type_cx4; break; + case IXGBE_DEV_ID_82599_T3_LOM: + media_type = ixgbe_media_type_copper; + break; default: media_type = ixgbe_media_type_unknown; break; @@ -1733,13 +1739,34 @@ static s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw) * @hw: pointer to hardware structure * * Determines the physical layer module found on the current adapter. + * If PHY already detected, maintains current PHY type in hw struct, + * otherwise executes the PHY detection routine. **/ -static s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw) +s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw) { s32 status = IXGBE_ERR_PHY_ADDR_INVALID; + + /* Detect PHY if not unknown - returns success if already detected. */ status = ixgbe_identify_phy_generic(hw); - if (status != 0) - status = ixgbe_identify_sfp_module_generic(hw); + if (status != 0) { + /* 82599 10GBASE-T requires an external PHY */ + if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper) + goto out; + else + status = ixgbe_identify_sfp_module_generic(hw); + } + + /* Set PHY type none if no PHY detected */ + if (hw->phy.type == ixgbe_phy_unknown) { + hw->phy.type = ixgbe_phy_none; + status = 0; + } + + /* Return error if SFP module has been detected but is not supported */ + if (hw->phy.type == ixgbe_phy_sfp_unsupported) + status = IXGBE_ERR_SFP_NOT_SUPPORTED; + +out: return status; } @@ -1763,11 +1790,12 @@ static u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw) hw->phy.ops.identify(hw); - if (hw->phy.type == ixgbe_phy_tn || - hw->phy.type == ixgbe_phy_aq || - hw->phy.type == ixgbe_phy_cu_unknown) { + switch (hw->phy.type) { + case ixgbe_phy_tn: + case ixgbe_phy_aq: + case ixgbe_phy_cu_unknown: hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD, - &ext_ability); + &ext_ability); if (ext_ability & MDIO_PMA_EXTABLE_10GBT) physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; if (ext_ability & MDIO_PMA_EXTABLE_1000BT) @@ -1775,6 +1803,8 @@ static u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw) if (ext_ability & MDIO_PMA_EXTABLE_100BTX) physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; goto out; + default: + break; } switch (autoc & IXGBE_AUTOC_LMS_MASK) { diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 588661ba2b9b..987771968cbb 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3889,7 +3889,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) * If we're not hot-pluggable SFP+, we just need to configure link * and bring it up. */ - if (hw->phy.type == ixgbe_phy_unknown) + if (hw->phy.type == ixgbe_phy_none) schedule_work(&adapter->sfp_config_module_task); /* enable transmits */ diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 18780d070145..af5ad406ef12 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -2242,6 +2242,7 @@ enum ixgbe_mac_type { enum ixgbe_phy_type { ixgbe_phy_unknown = 0, + ixgbe_phy_none, ixgbe_phy_tn, ixgbe_phy_aq, ixgbe_phy_cu_unknown, -- cgit v1.2.3 From a4297dc2f49d46d5452a948210be44442236e685 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Mon, 14 Feb 2011 08:45:13 +0000 Subject: ixgbe: Add ability to double reset on failure to clear master enable Double resets are required for recovery from certain error conditions. Between resets, it is necessary to stall to allow time for any pending HW events to complete. We use 1usec since that is what is needed for ixgbe_disable_pcie_master(). The second reset then clears out any effects of those events. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82598.c | 21 +++++++++++++----- drivers/net/ixgbe/ixgbe_82599.c | 20 ++++++++++++----- drivers/net/ixgbe/ixgbe_common.c | 47 +++++++++++++++++++++++++++++++++++----- drivers/net/ixgbe/ixgbe_type.h | 4 ++++ drivers/net/ixgbe/ixgbe_x540.c | 20 ++++++++++++----- 5 files changed, 90 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index d0f1d9d2c416..291b1e6f85c9 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -770,7 +770,6 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) else if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT) goto no_phy_reset; - hw->phy.ops.reset(hw); } @@ -779,12 +778,9 @@ no_phy_reset: * Prevent the PCI-E bus from from hanging by disabling PCI-E master * access and verify no pending requests before reset */ - status = ixgbe_disable_pcie_master(hw); - if (status != 0) { - status = IXGBE_ERR_MASTER_REQUESTS_PENDING; - hw_dbg(hw, "PCI-E Master disable polling has failed.\n"); - } + ixgbe_disable_pcie_master(hw); +mac_reset_top: /* * Issue global reset to the MAC. This needs to be a SW reset. * If link reset is used, it might reset the MAC when mng is using it @@ -805,6 +801,19 @@ no_phy_reset: hw_dbg(hw, "Reset polling failed to complete.\n"); } + /* + * Double resets are required for recovery from certain error + * conditions. Between resets, it is necessary to stall to allow time + * for any pending HW events to complete. We use 1usec since that is + * what is needed for ixgbe_disable_pcie_master(). The second reset + * then clears out any effects of those events. + */ + if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { + hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; + udelay(1); + goto mac_reset_top; + } + msleep(50); gheccr = IXGBE_READ_REG(hw, IXGBE_GHECCR); diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index b45a491ac2e1..126a06fa2a12 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -904,12 +904,9 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) * Prevent the PCI-E bus from from hanging by disabling PCI-E master * access and verify no pending requests before reset */ - status = ixgbe_disable_pcie_master(hw); - if (status != 0) { - status = IXGBE_ERR_MASTER_REQUESTS_PENDING; - hw_dbg(hw, "PCI-E Master disable polling has failed.\n"); - } + ixgbe_disable_pcie_master(hw); +mac_reset_top: /* * Issue global reset to the MAC. This needs to be a SW reset. * If link reset is used, it might reset the MAC when mng is using it @@ -930,6 +927,19 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) hw_dbg(hw, "Reset polling failed to complete.\n"); } + /* + * Double resets are required for recovery from certain error + * conditions. Between resets, it is necessary to stall to allow time + * for any pending HW events to complete. We use 1usec since that is + * what is needed for ixgbe_disable_pcie_master(). The second reset + * then clears out any effects of those events. + */ + if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { + hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; + udelay(1); + goto mac_reset_top; + } + msleep(50); /* diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 345c32eab4a5..6d87c7491d10 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -454,8 +454,7 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw) * Prevent the PCI-E bus from from hanging by disabling PCI-E master * access and verify no pending requests */ - if (ixgbe_disable_pcie_master(hw) != 0) - hw_dbg(hw, "PCI-E Master disable polling has failed.\n"); + ixgbe_disable_pcie_master(hw); return 0; } @@ -2161,10 +2160,16 @@ out: **/ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) { + struct ixgbe_adapter *adapter = hw->back; u32 i; u32 reg_val; u32 number_of_queues; - s32 status = IXGBE_ERR_MASTER_REQUESTS_PENDING; + s32 status = 0; + u16 dev_status = 0; + + /* Just jump out if bus mastering is already disabled */ + if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) + goto out; /* Disable the receive unit by stopping each queue */ number_of_queues = hw->mac.max_rx_queues; @@ -2181,13 +2186,43 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) IXGBE_WRITE_REG(hw, IXGBE_CTRL, reg_val); for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { - if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) { - status = 0; + if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) + goto check_device_status; + udelay(100); + } + + hw_dbg(hw, "GIO Master Disable bit didn't clear - requesting resets\n"); + status = IXGBE_ERR_MASTER_REQUESTS_PENDING; + + /* + * Before proceeding, make sure that the PCIe block does not have + * transactions pending. + */ +check_device_status: + for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { + pci_read_config_word(adapter->pdev, IXGBE_PCI_DEVICE_STATUS, + &dev_status); + if (!(dev_status & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING)) break; - } udelay(100); } + if (i == IXGBE_PCI_MASTER_DISABLE_TIMEOUT) + hw_dbg(hw, "PCIe transaction pending bit also did not clear.\n"); + else + goto out; + + /* + * Two consecutive resets are required via CTRL.RST per datasheet + * 5.2.5.3.2 Master Disable. We set a flag to inform the reset routine + * of this need. The first reset prevents new master requests from + * being issued by our device. We then must wait 1usec for any + * remaining completions from the PCIe bus to trickle in, and then reset + * again to clear out any effects they may have had on our device. + */ + hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; + +out: return status; } diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index af5ad406ef12..5ede03c84a5e 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -1614,6 +1614,8 @@ #define IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN 0x1 /* Alt. WWN base exists */ /* PCI Bus Info */ +#define IXGBE_PCI_DEVICE_STATUS 0xAA +#define IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING 0x0020 #define IXGBE_PCI_LINK_STATUS 0xB2 #define IXGBE_PCI_DEVICE_CONTROL2 0xC8 #define IXGBE_PCI_LINK_WIDTH 0x3F0 @@ -2557,6 +2559,7 @@ struct ixgbe_eeprom_info { u16 address_bits; }; +#define IXGBE_FLAGS_DOUBLE_RESET_REQUIRED 0x01 struct ixgbe_mac_info { struct ixgbe_mac_operations ops; enum ixgbe_mac_type type; @@ -2579,6 +2582,7 @@ struct ixgbe_mac_info { u32 orig_autoc2; bool orig_link_settings_stored; bool autotry_restart; + u8 flags; }; struct ixgbe_phy_info { diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index f2518b01067d..a6f06d59a64a 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -110,12 +110,9 @@ static s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) * Prevent the PCI-E bus from from hanging by disabling PCI-E master * access and verify no pending requests before reset */ - status = ixgbe_disable_pcie_master(hw); - if (status != 0) { - status = IXGBE_ERR_MASTER_REQUESTS_PENDING; - hw_dbg(hw, "PCI-E Master disable polling has failed.\n"); - } + ixgbe_disable_pcie_master(hw); +mac_reset_top: /* * Issue global reset to the MAC. Needs to be SW reset if link is up. * If link reset is used when link is up, it might reset the PHY when @@ -148,6 +145,19 @@ static s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) hw_dbg(hw, "Reset polling failed to complete.\n"); } + /* + * Double resets are required for recovery from certain error + * conditions. Between resets, it is necessary to stall to allow time + * for any pending HW events to complete. We use 1usec since that is + * what is needed for ixgbe_disable_pcie_master(). The second reset + * then clears out any effects of those events. + */ + if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { + hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; + udelay(1); + goto mac_reset_top; + } + /* Clear PF Reset Done bit so PF/VF Mail Ops can work */ ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD; -- cgit v1.2.3 From 76d97dd4c44c6847029ae9021fe0d880cad90d33 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Wed, 16 Feb 2011 10:14:00 +0000 Subject: ixgbe: cleanup code in ixgbe_identify_sfp_module_generic This change cleans up several issues in ixgbe_identify_sfp_module_generic including whitespace, redundant code, I2C EEPROM reads without exception handling, and an if/elseif/else without braces. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_phy.c | 149 ++++++++++++++++++++++++++---------------- 1 file changed, 94 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index 8f7123e8fc0a..f8a60ca87500 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -556,11 +556,10 @@ out: } /** - * ixgbe_identify_sfp_module_generic - Identifies SFP module and assigns - * the PHY type. + * ixgbe_identify_sfp_module_generic - Identifies SFP modules * @hw: pointer to hardware structure * - * Searches for and indentifies the SFP module. Assings appropriate PHY type. + * Searches for and identifies the SFP module and assigns appropriate PHY type. **/ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) { @@ -581,41 +580,62 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) goto out; } - status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER, + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_IDENTIFIER, &identifier); - if (status == IXGBE_ERR_SFP_NOT_PRESENT || status == IXGBE_ERR_I2C) { - status = IXGBE_ERR_SFP_NOT_PRESENT; - hw->phy.sfp_type = ixgbe_sfp_type_not_present; - if (hw->phy.type != ixgbe_phy_nl) { - hw->phy.id = 0; - hw->phy.type = ixgbe_phy_unknown; - } - goto out; - } + if (status == IXGBE_ERR_SWFW_SYNC || + status == IXGBE_ERR_I2C || + status == IXGBE_ERR_SFP_NOT_PRESENT) + goto err_read_i2c_eeprom; - if (identifier == IXGBE_SFF_IDENTIFIER_SFP) { - hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_1GBE_COMP_CODES, - &comp_codes_1g); - hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_10GBE_COMP_CODES, - &comp_codes_10g); - hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_CABLE_TECHNOLOGY, - &cable_tech); - - /* ID Module - * ========= - * 0 SFP_DA_CU - * 1 SFP_SR - * 2 SFP_LR - * 3 SFP_DA_CORE0 - 82599-specific - * 4 SFP_DA_CORE1 - 82599-specific - * 5 SFP_SR/LR_CORE0 - 82599-specific - * 6 SFP_SR/LR_CORE1 - 82599-specific - * 7 SFP_act_lmt_DA_CORE0 - 82599-specific - * 8 SFP_act_lmt_DA_CORE1 - 82599-specific - * 9 SFP_1g_cu_CORE0 - 82599-specific - * 10 SFP_1g_cu_CORE1 - 82599-specific - */ + /* LAN ID is needed for sfp_type determination */ + hw->mac.ops.set_lan_id(hw); + + if (identifier != IXGBE_SFF_IDENTIFIER_SFP) { + hw->phy.type = ixgbe_phy_sfp_unsupported; + status = IXGBE_ERR_SFP_NOT_SUPPORTED; + } else { + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_1GBE_COMP_CODES, + &comp_codes_1g); + + if (status == IXGBE_ERR_SWFW_SYNC || + status == IXGBE_ERR_I2C || + status == IXGBE_ERR_SFP_NOT_PRESENT) + goto err_read_i2c_eeprom; + + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_10GBE_COMP_CODES, + &comp_codes_10g); + + if (status == IXGBE_ERR_SWFW_SYNC || + status == IXGBE_ERR_I2C || + status == IXGBE_ERR_SFP_NOT_PRESENT) + goto err_read_i2c_eeprom; + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_CABLE_TECHNOLOGY, + &cable_tech); + + if (status == IXGBE_ERR_SWFW_SYNC || + status == IXGBE_ERR_I2C || + status == IXGBE_ERR_SFP_NOT_PRESENT) + goto err_read_i2c_eeprom; + + /* ID Module + * ========= + * 0 SFP_DA_CU + * 1 SFP_SR + * 2 SFP_LR + * 3 SFP_DA_CORE0 - 82599-specific + * 4 SFP_DA_CORE1 - 82599-specific + * 5 SFP_SR/LR_CORE0 - 82599-specific + * 6 SFP_SR/LR_CORE1 - 82599-specific + * 7 SFP_act_lmt_DA_CORE0 - 82599-specific + * 8 SFP_act_lmt_DA_CORE1 - 82599-specific + * 9 SFP_1g_cu_CORE0 - 82599-specific + * 10 SFP_1g_cu_CORE1 - 82599-specific + */ if (hw->mac.type == ixgbe_mac_82598EB) { if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) hw->phy.sfp_type = ixgbe_sfp_type_da_cu; @@ -647,31 +667,27 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) ixgbe_sfp_type_da_act_lmt_core1; } else { hw->phy.sfp_type = - ixgbe_sfp_type_unknown; + ixgbe_sfp_type_unknown; } - } else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE) - if (hw->bus.lan_id == 0) - hw->phy.sfp_type = - ixgbe_sfp_type_srlr_core0; - else - hw->phy.sfp_type = - ixgbe_sfp_type_srlr_core1; - else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE) + } else if (comp_codes_10g & + (IXGBE_SFF_10GBASESR_CAPABLE | + IXGBE_SFF_10GBASELR_CAPABLE)) { if (hw->bus.lan_id == 0) hw->phy.sfp_type = ixgbe_sfp_type_srlr_core0; else hw->phy.sfp_type = ixgbe_sfp_type_srlr_core1; - else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE) + } else if (comp_codes_1g & IXGBE_SFF_1GBASET_CAPABLE) { if (hw->bus.lan_id == 0) hw->phy.sfp_type = ixgbe_sfp_type_1g_cu_core0; else hw->phy.sfp_type = ixgbe_sfp_type_1g_cu_core1; - else + } else { hw->phy.sfp_type = ixgbe_sfp_type_unknown; + } } if (hw->phy.sfp_type != stored_sfp_type) @@ -688,16 +704,33 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) /* Determine PHY vendor */ if (hw->phy.type != ixgbe_phy_nl) { hw->phy.id = identifier; - hw->phy.ops.read_i2c_eeprom(hw, + status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_VENDOR_OUI_BYTE0, &oui_bytes[0]); - hw->phy.ops.read_i2c_eeprom(hw, + + if (status == IXGBE_ERR_SWFW_SYNC || + status == IXGBE_ERR_I2C || + status == IXGBE_ERR_SFP_NOT_PRESENT) + goto err_read_i2c_eeprom; + + status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_VENDOR_OUI_BYTE1, &oui_bytes[1]); - hw->phy.ops.read_i2c_eeprom(hw, + + if (status == IXGBE_ERR_SWFW_SYNC || + status == IXGBE_ERR_I2C || + status == IXGBE_ERR_SFP_NOT_PRESENT) + goto err_read_i2c_eeprom; + + status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_VENDOR_OUI_BYTE2, &oui_bytes[2]); + if (status == IXGBE_ERR_SWFW_SYNC || + status == IXGBE_ERR_I2C || + status == IXGBE_ERR_SFP_NOT_PRESENT) + goto err_read_i2c_eeprom; + vendor_oui = ((oui_bytes[0] << IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT) | (oui_bytes[1] << IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT) | @@ -707,7 +740,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) case IXGBE_SFF_VENDOR_OUI_TYCO: if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) hw->phy.type = - ixgbe_phy_sfp_passive_tyco; + ixgbe_phy_sfp_passive_tyco; break; case IXGBE_SFF_VENDOR_OUI_FTL: if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) @@ -724,7 +757,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) default: if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) hw->phy.type = - ixgbe_phy_sfp_passive_unknown; + ixgbe_phy_sfp_passive_unknown; else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE) hw->phy.type = ixgbe_phy_sfp_active_unknown; @@ -734,7 +767,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) } } - /* All passive DA cables are supported */ + /* Allow any DA cable vendor */ if (cable_tech & (IXGBE_SFF_DA_PASSIVE_CABLE | IXGBE_SFF_DA_ACTIVE_CABLE)) { status = 0; @@ -776,12 +809,18 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) out: return status; + +err_read_i2c_eeprom: + hw->phy.sfp_type = ixgbe_sfp_type_not_present; + if (hw->phy.type != ixgbe_phy_nl) { + hw->phy.id = 0; + hw->phy.type = ixgbe_phy_unknown; + } + return IXGBE_ERR_SFP_NOT_PRESENT; } /** - * ixgbe_get_sfp_init_sequence_offsets - Checks the MAC's EEPROM to see - * if it supports a given SFP+ module type, if so it returns the offsets to the - * phy init sequence block. + * ixgbe_get_sfp_init_sequence_offsets - Provides offset of PHY init sequence * @hw: pointer to hardware structure * @list_offset: offset to the SFP ID list * @data_offset: offset to the SFP data block -- cgit v1.2.3 From 48de36c5656113ce6cfe4207da2f90f46917e53d Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Wed, 16 Feb 2011 01:38:08 +0000 Subject: ixgbe: Check link wants report current link state Currently check link reports the link state as down, if at any time the link had previously gone down since the last time the LINKS register was read. This does not accurately reflect the function of the check link call, which should be to return the CURRENT link state. Code now reads the LINKS registers twice, once to clear the previous and again to get the current value. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_common.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 6d87c7491d10..7e3bb559f42d 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -2769,10 +2769,19 @@ s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw) s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *link_up, bool link_up_wait_to_complete) { - u32 links_reg; + u32 links_reg, links_orig; u32 i; + /* clear the old state */ + links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS); + links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); + + if (links_orig != links_reg) { + hw_dbg(hw, "LINKS changed from %08X to %08X\n", + links_orig, links_reg); + } + if (link_up_wait_to_complete) { for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { if (links_reg & IXGBE_LINKS_UP) { -- cgit v1.2.3 From 1783575c1a11f726130522b851737cddda4c14c0 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Wed, 16 Feb 2011 01:38:13 +0000 Subject: ixgbe: add polling test to end of PHY reset Some PHYs require that we poll the reset bit and wait for it to clear before continuing initialization. As such we should add this check to the end of the ixgbe_reset_phy_generic routine. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_phy.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index f8a60ca87500..ebd6e4492a3f 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -138,17 +138,51 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) **/ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw) { + u32 i; + u16 ctrl = 0; + s32 status = 0; + + if (hw->phy.type == ixgbe_phy_unknown) + status = ixgbe_identify_phy_generic(hw); + + if (status != 0 || hw->phy.type == ixgbe_phy_none) + goto out; + /* Don't reset PHY if it's shut down due to overtemp. */ if (!hw->phy.reset_if_overtemp && (IXGBE_ERR_OVERTEMP == hw->phy.ops.check_overtemp(hw))) - return 0; + goto out; /* * Perform soft PHY reset to the PHY_XS. * This will cause a soft reset to the PHY */ - return hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, - MDIO_CTRL1_RESET); + hw->phy.ops.write_reg(hw, MDIO_CTRL1, + MDIO_MMD_PHYXS, + MDIO_CTRL1_RESET); + + /* + * Poll for reset bit to self-clear indicating reset is complete. + * Some PHYs could take up to 3 seconds to complete and need about + * 1.7 usec delay after the reset is complete. + */ + for (i = 0; i < 30; i++) { + msleep(100); + hw->phy.ops.read_reg(hw, MDIO_CTRL1, + MDIO_MMD_PHYXS, &ctrl); + if (!(ctrl & MDIO_CTRL1_RESET)) { + udelay(2); + break; + } + } + + if (ctrl & MDIO_CTRL1_RESET) { + status = IXGBE_ERR_RESET_FAILED; + hw_dbg(hw, "PHY reset polling failed to complete.\n"); + } + +out: + return status; } /** -- cgit v1.2.3 From 26d6899ba775ed056bd73107e3f4427ff9247f75 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Thu, 17 Feb 2011 11:34:53 +0000 Subject: ixgbe: Fill out PCIe speed and width enums with values This patch fills in the values for bus speed and width of the ixgbe_bus_speed and ixgbe_bus_width enums. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_type.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 5ede03c84a5e..a737b1310619 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -2333,25 +2333,25 @@ enum ixgbe_bus_type { /* PCI bus speeds */ enum ixgbe_bus_speed { ixgbe_bus_speed_unknown = 0, - ixgbe_bus_speed_33, - ixgbe_bus_speed_66, - ixgbe_bus_speed_100, - ixgbe_bus_speed_120, - ixgbe_bus_speed_133, - ixgbe_bus_speed_2500, - ixgbe_bus_speed_5000, + ixgbe_bus_speed_33 = 33, + ixgbe_bus_speed_66 = 66, + ixgbe_bus_speed_100 = 100, + ixgbe_bus_speed_120 = 120, + ixgbe_bus_speed_133 = 133, + ixgbe_bus_speed_2500 = 2500, + ixgbe_bus_speed_5000 = 5000, ixgbe_bus_speed_reserved }; /* PCI bus widths */ enum ixgbe_bus_width { ixgbe_bus_width_unknown = 0, - ixgbe_bus_width_pcie_x1, - ixgbe_bus_width_pcie_x2, + ixgbe_bus_width_pcie_x1 = 1, + ixgbe_bus_width_pcie_x2 = 2, ixgbe_bus_width_pcie_x4 = 4, ixgbe_bus_width_pcie_x8 = 8, - ixgbe_bus_width_32, - ixgbe_bus_width_64, + ixgbe_bus_width_32 = 32, + ixgbe_bus_width_64 = 64, ixgbe_bus_width_reserved }; -- cgit v1.2.3 From c700f4e6f55c42c9aeacf365bd178f97625e00df Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Thu, 17 Feb 2011 11:34:58 +0000 Subject: ixgbe: Bounds checking for set_rar, clear_rar, set_vmdq, clear_vmdq This change makes it so that out of bounds requests to these calls will now return IXGBE_ERR_INVALID_ARGUMENT instead of returning 0. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82598.c | 24 ++++-- drivers/net/ixgbe/ixgbe_common.c | 153 ++++++++++++++++++++------------------- drivers/net/ixgbe/ixgbe_type.h | 1 - 3 files changed, 95 insertions(+), 83 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 291b1e6f85c9..bff7011f919f 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -858,6 +858,13 @@ reset_hw_out: static s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq) { u32 rar_high; + u32 rar_entries = hw->mac.num_rar_entries; + + /* Make sure we are using a valid rar index range */ + if (rar >= rar_entries) { + hw_dbg(hw, "RAR index %d is out of range.\n", rar); + return IXGBE_ERR_INVALID_ARGUMENT; + } rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); rar_high &= ~IXGBE_RAH_VIND_MASK; @@ -877,14 +884,17 @@ static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq) u32 rar_high; u32 rar_entries = hw->mac.num_rar_entries; - if (rar < rar_entries) { - rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); - if (rar_high & IXGBE_RAH_VIND_MASK) { - rar_high &= ~IXGBE_RAH_VIND_MASK; - IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high); - } - } else { + + /* Make sure we are using a valid rar index range */ + if (rar >= rar_entries) { hw_dbg(hw, "RAR index %d is out of range.\n", rar); + return IXGBE_ERR_INVALID_ARGUMENT; + } + + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); + if (rar_high & IXGBE_RAH_VIND_MASK) { + rar_high &= ~IXGBE_RAH_VIND_MASK; + IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high); } return 0; diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 7e3bb559f42d..882a35092024 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -1239,37 +1239,37 @@ s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, u32 rar_low, rar_high; u32 rar_entries = hw->mac.num_rar_entries; + /* Make sure we are using a valid rar index range */ + if (index >= rar_entries) { + hw_dbg(hw, "RAR index %d is out of range.\n", index); + return IXGBE_ERR_INVALID_ARGUMENT; + } + /* setup VMDq pool selection before this RAR gets enabled */ hw->mac.ops.set_vmdq(hw, index, vmdq); - /* Make sure we are using a valid rar index range */ - if (index < rar_entries) { - /* - * HW expects these in little endian so we reverse the byte - * order from network order (big endian) to little endian - */ - rar_low = ((u32)addr[0] | - ((u32)addr[1] << 8) | - ((u32)addr[2] << 16) | - ((u32)addr[3] << 24)); - /* - * Some parts put the VMDq setting in the extra RAH bits, - * so save everything except the lower 16 bits that hold part - * of the address and the address valid bit. - */ - rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); - rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV); - rar_high |= ((u32)addr[4] | ((u32)addr[5] << 8)); + /* + * HW expects these in little endian so we reverse the byte + * order from network order (big endian) to little endian + */ + rar_low = ((u32)addr[0] | + ((u32)addr[1] << 8) | + ((u32)addr[2] << 16) | + ((u32)addr[3] << 24)); + /* + * Some parts put the VMDq setting in the extra RAH bits, + * so save everything except the lower 16 bits that hold part + * of the address and the address valid bit. + */ + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); + rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV); + rar_high |= ((u32)addr[4] | ((u32)addr[5] << 8)); - if (enable_addr != 0) - rar_high |= IXGBE_RAH_AV; + if (enable_addr != 0) + rar_high |= IXGBE_RAH_AV; - IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low); - IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); - } else { - hw_dbg(hw, "RAR index %d is out of range.\n", index); - return IXGBE_ERR_RAR_INDEX; - } + IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low); + IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); return 0; } @@ -1287,22 +1287,22 @@ s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index) u32 rar_entries = hw->mac.num_rar_entries; /* Make sure we are using a valid rar index range */ - if (index < rar_entries) { - /* - * Some parts put the VMDq setting in the extra RAH bits, - * so save everything except the lower 16 bits that hold part - * of the address and the address valid bit. - */ - rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); - rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV); - - IXGBE_WRITE_REG(hw, IXGBE_RAL(index), 0); - IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); - } else { + if (index >= rar_entries) { hw_dbg(hw, "RAR index %d is out of range.\n", index); - return IXGBE_ERR_RAR_INDEX; + return IXGBE_ERR_INVALID_ARGUMENT; } + /* + * Some parts put the VMDq setting in the extra RAH bits, + * so save everything except the lower 16 bits that hold part + * of the address and the address valid bit. + */ + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); + rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV); + + IXGBE_WRITE_REG(hw, IXGBE_RAL(index), 0); + IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); + /* clear VMDq pool/queue selection for this RAR */ hw->mac.ops.clear_vmdq(hw, index, IXGBE_CLEAR_VMDQ_ALL); @@ -2468,37 +2468,38 @@ s32 ixgbe_clear_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq) u32 mpsar_lo, mpsar_hi; u32 rar_entries = hw->mac.num_rar_entries; - if (rar < rar_entries) { - mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); - mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); + /* Make sure we are using a valid rar index range */ + if (rar >= rar_entries) { + hw_dbg(hw, "RAR index %d is out of range.\n", rar); + return IXGBE_ERR_INVALID_ARGUMENT; + } - if (!mpsar_lo && !mpsar_hi) - goto done; + mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); + mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); - if (vmdq == IXGBE_CLEAR_VMDQ_ALL) { - if (mpsar_lo) { - IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0); - mpsar_lo = 0; - } - if (mpsar_hi) { - IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0); - mpsar_hi = 0; - } - } else if (vmdq < 32) { - mpsar_lo &= ~(1 << vmdq); - IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo); - } else { - mpsar_hi &= ~(1 << (vmdq - 32)); - IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi); - } + if (!mpsar_lo && !mpsar_hi) + goto done; - /* was that the last pool using this rar? */ - if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0) - hw->mac.ops.clear_rar(hw, rar); + if (vmdq == IXGBE_CLEAR_VMDQ_ALL) { + if (mpsar_lo) { + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0); + mpsar_lo = 0; + } + if (mpsar_hi) { + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0); + mpsar_hi = 0; + } + } else if (vmdq < 32) { + mpsar_lo &= ~(1 << vmdq); + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo); } else { - hw_dbg(hw, "RAR index %d is out of range.\n", rar); + mpsar_hi &= ~(1 << (vmdq - 32)); + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi); } + /* was that the last pool using this rar? */ + if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0) + hw->mac.ops.clear_rar(hw, rar); done: return 0; } @@ -2514,18 +2515,20 @@ s32 ixgbe_set_vmdq_generic(struct ixgbe_hw *hw, u32 rar, u32 vmdq) u32 mpsar; u32 rar_entries = hw->mac.num_rar_entries; - if (rar < rar_entries) { - if (vmdq < 32) { - mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); - mpsar |= 1 << vmdq; - IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar); - } else { - mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); - mpsar |= 1 << (vmdq - 32); - IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar); - } - } else { + /* Make sure we are using a valid rar index range */ + if (rar >= rar_entries) { hw_dbg(hw, "RAR index %d is out of range.\n", rar); + return IXGBE_ERR_INVALID_ARGUMENT; + } + + if (vmdq < 32) { + mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); + mpsar |= 1 << vmdq; + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar); + } else { + mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); + mpsar |= 1 << (vmdq - 32); + IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar); } return 0; } diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index a737b1310619..b1ae185ae516 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -2689,7 +2689,6 @@ struct ixgbe_info { #define IXGBE_ERR_EEPROM_VERSION -24 #define IXGBE_ERR_NO_SPACE -25 #define IXGBE_ERR_OVERTEMP -26 -#define IXGBE_ERR_RAR_INDEX -27 #define IXGBE_ERR_SFP_SETUP_NOT_COMPLETE -30 #define IXGBE_ERR_PBA_SECTION -31 #define IXGBE_ERR_INVALID_ARGUMENT -32 -- cgit v1.2.3 From b60c5dd31b053d008110a80aa4089d64cee60e8f Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Fri, 18 Feb 2011 19:29:46 +0000 Subject: ixgbe: cleanup X540 PHY reset function pointer The X540 PHY reset pointer isn't currently used which is a good thing as it wouldn't work as implemented. On top of that the X540 firmware is written with the assumption that is does not need to be reset for proper initialization so it's not needed. I'm just assigning the pointer at NULL as the current implementation is rather misleading. Signed-off-by: Don Skidmore Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_x540.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index a6f06d59a64a..3229398630f6 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -712,7 +712,7 @@ static struct ixgbe_phy_operations phy_ops_X540 = { .identify = &ixgbe_identify_phy_generic, .identify_sfp = &ixgbe_identify_sfp_module_generic, .init = NULL, - .reset = &ixgbe_reset_phy_generic, + .reset = NULL, .read_reg = &ixgbe_read_phy_reg_generic, .write_reg = &ixgbe_write_phy_reg_generic, .setup_link = &ixgbe_setup_phy_link_generic, -- cgit v1.2.3 From 80960ab040dd6b3a82bfb2db9b1aaf5d6ccffbb7 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Fri, 18 Feb 2011 08:58:27 +0000 Subject: ixgbe: rework ixgbe MTA handling to not drop packets This change modifies the ixgbe drivers so that it will not drop the multicast filters while updating them. Instead it uses an intermediate table to store the filter and then writes that filter to the hardware. Based on original patch from Dave Boutcher Signed-off-by: Emil Tantilov Reported-by: Dave Boutcher Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_common.c | 68 ++++++---------------------------------- drivers/net/ixgbe/ixgbe_type.h | 3 +- 2 files changed, 11 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 882a35092024..b94634f41689 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -46,8 +46,6 @@ static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); static void ixgbe_release_eeprom(struct ixgbe_hw *hw); -static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index); -static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index); static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr); static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq); static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num); @@ -1309,38 +1307,6 @@ s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index) return 0; } -/** - * ixgbe_enable_rar - Enable Rx address register - * @hw: pointer to hardware structure - * @index: index into the RAR table - * - * Enables the select receive address register. - **/ -static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index) -{ - u32 rar_high; - - rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); - rar_high |= IXGBE_RAH_AV; - IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); -} - -/** - * ixgbe_disable_rar - Disable Rx address register - * @hw: pointer to hardware structure - * @index: index into the RAR table - * - * Disables the select receive address register. - **/ -static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index) -{ - u32 rar_high; - - rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); - rar_high &= (~IXGBE_RAH_AV); - IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); -} - /** * ixgbe_init_rx_addrs_generic - Initializes receive address filters. * @hw: pointer to hardware structure @@ -1387,7 +1353,6 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw) } /* Clear the MTA */ - hw->addr_ctrl.mc_addr_in_rar_count = 0; hw->addr_ctrl.mta_in_use = 0; IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); @@ -1421,8 +1386,7 @@ static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) * else put the controller into promiscuous mode */ if (hw->addr_ctrl.rar_used_count < rar_entries) { - rar = hw->addr_ctrl.rar_used_count - - hw->addr_ctrl.mc_addr_in_rar_count; + rar = hw->addr_ctrl.rar_used_count; hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); hw_dbg(hw, "Added a secondary address to RAR[%d]\n", rar); hw->addr_ctrl.rar_used_count++; @@ -1551,7 +1515,6 @@ static void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr) u32 vector; u32 vector_bit; u32 vector_reg; - u32 mta_reg; hw->addr_ctrl.mta_in_use++; @@ -1569,9 +1532,7 @@ static void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr) */ vector_reg = (vector >> 5) & 0x7F; vector_bit = vector & 0x1F; - mta_reg = IXGBE_READ_REG(hw, IXGBE_MTA(vector_reg)); - mta_reg |= (1 << vector_bit); - IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg); + hw->mac.mta_shadow[vector_reg] |= (1 << vector_bit); } /** @@ -1597,18 +1558,21 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, hw->addr_ctrl.num_mc_addrs = netdev_mc_count(netdev); hw->addr_ctrl.mta_in_use = 0; - /* Clear the MTA */ + /* Clear mta_shadow */ hw_dbg(hw, " Clearing MTA\n"); - for (i = 0; i < hw->mac.mcft_size; i++) - IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0); + memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow)); - /* Add the new addresses */ + /* Update mta shadow */ netdev_for_each_mc_addr(ha, netdev) { hw_dbg(hw, " Adding the multicast addresses:\n"); ixgbe_set_mta(hw, ha->addr); } /* Enable mta */ + for (i = 0; i < hw->mac.mcft_size; i++) + IXGBE_WRITE_REG_ARRAY(hw, IXGBE_MTA(0), i, + hw->mac.mta_shadow[i]); + if (hw->addr_ctrl.mta_in_use > 0) IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type); @@ -1625,15 +1589,8 @@ s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, **/ s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw) { - u32 i; - u32 rar_entries = hw->mac.num_rar_entries; struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; - if (a->mc_addr_in_rar_count > 0) - for (i = (rar_entries - a->mc_addr_in_rar_count); - i < rar_entries; i++) - ixgbe_enable_rar(hw, i); - if (a->mta_in_use > 0) IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type); @@ -1649,15 +1606,8 @@ s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw) **/ s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw) { - u32 i; - u32 rar_entries = hw->mac.num_rar_entries; struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; - if (a->mc_addr_in_rar_count > 0) - for (i = (rar_entries - a->mc_addr_in_rar_count); - i < rar_entries; i++) - ixgbe_disable_rar(hw, i); - if (a->mta_in_use > 0) IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index b1ae185ae516..f6d0d4d98dd4 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -2358,7 +2358,6 @@ enum ixgbe_bus_width { struct ixgbe_addr_filter_info { u32 num_mc_addrs; u32 rar_used_count; - u32 mc_addr_in_rar_count; u32 mta_in_use; u32 overflow_promisc; bool uc_set_promisc; @@ -2570,6 +2569,8 @@ struct ixgbe_mac_info { u16 wwnn_prefix; /* prefix for World Wide Port Name (WWPN) */ u16 wwpn_prefix; +#define IXGBE_MAX_MTA 128 + u32 mta_shadow[IXGBE_MAX_MTA]; s32 mc_filter_type; u32 mcft_size; u32 vft_size; -- cgit v1.2.3 From 79d5892521144d455114e4820eb30fec802b9c39 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 19 Feb 2011 08:43:34 +0000 Subject: ixgbe: Drop unused code for setting up unicast addresses This change removes the unused code that was setting up the uc_addr_list. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82598.c | 1 - drivers/net/ixgbe/ixgbe_82599.c | 1 - drivers/net/ixgbe/ixgbe_common.c | 99 ---------------------------------------- drivers/net/ixgbe/ixgbe_common.h | 2 - drivers/net/ixgbe/ixgbe_type.h | 1 - drivers/net/ixgbe/ixgbe_x540.c | 1 - 6 files changed, 105 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index bff7011f919f..a5b83b775b6c 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -1198,7 +1198,6 @@ static struct ixgbe_mac_operations mac_ops_82598 = { .set_vmdq = &ixgbe_set_vmdq_82598, .clear_vmdq = &ixgbe_clear_vmdq_82598, .init_rx_addrs = &ixgbe_init_rx_addrs_generic, - .update_uc_addr_list = &ixgbe_update_uc_addr_list_generic, .update_mc_addr_list = &ixgbe_update_mc_addr_list_generic, .enable_mc = &ixgbe_enable_mc_generic, .disable_mc = &ixgbe_disable_mc_generic, diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 126a06fa2a12..69d345b1ecf4 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -2035,7 +2035,6 @@ static struct ixgbe_mac_operations mac_ops_82599 = { .set_vmdq = &ixgbe_set_vmdq_generic, .clear_vmdq = &ixgbe_clear_vmdq_generic, .init_rx_addrs = &ixgbe_init_rx_addrs_generic, - .update_uc_addr_list = &ixgbe_update_uc_addr_list_generic, .update_mc_addr_list = &ixgbe_update_mc_addr_list_generic, .enable_mc = &ixgbe_enable_mc_generic, .disable_mc = &ixgbe_disable_mc_generic, diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index b94634f41689..4fa195e88f3e 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -47,7 +47,6 @@ static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); static void ixgbe_release_eeprom(struct ixgbe_hw *hw); static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr); -static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq); static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num); /** @@ -1366,104 +1365,6 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw) return 0; } -/** - * ixgbe_add_uc_addr - Adds a secondary unicast address. - * @hw: pointer to hardware structure - * @addr: new address - * - * Adds it to unused receive address register or goes into promiscuous mode. - **/ -static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) -{ - u32 rar_entries = hw->mac.num_rar_entries; - u32 rar; - - hw_dbg(hw, " UC Addr = %.2X %.2X %.2X %.2X %.2X %.2X\n", - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); - - /* - * Place this address in the RAR if there is room, - * else put the controller into promiscuous mode - */ - if (hw->addr_ctrl.rar_used_count < rar_entries) { - rar = hw->addr_ctrl.rar_used_count; - hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); - hw_dbg(hw, "Added a secondary address to RAR[%d]\n", rar); - hw->addr_ctrl.rar_used_count++; - } else { - hw->addr_ctrl.overflow_promisc++; - } - - hw_dbg(hw, "ixgbe_add_uc_addr Complete\n"); -} - -/** - * ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses - * @hw: pointer to hardware structure - * @netdev: pointer to net device structure - * - * The given list replaces any existing list. Clears the secondary addrs from - * receive address registers. Uses unused receive address registers for the - * first secondary addresses, and falls back to promiscuous mode as needed. - * - * Drivers using secondary unicast addresses must set user_set_promisc when - * manually putting the device into promiscuous mode. - **/ -s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, - struct net_device *netdev) -{ - u32 i; - u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc; - u32 uc_addr_in_use; - u32 fctrl; - struct netdev_hw_addr *ha; - - /* - * Clear accounting of old secondary address list, - * don't count RAR[0] - */ - uc_addr_in_use = hw->addr_ctrl.rar_used_count - 1; - hw->addr_ctrl.rar_used_count -= uc_addr_in_use; - hw->addr_ctrl.overflow_promisc = 0; - - /* Zero out the other receive addresses */ - hw_dbg(hw, "Clearing RAR[1-%d]\n", uc_addr_in_use + 1); - for (i = 0; i < uc_addr_in_use; i++) { - IXGBE_WRITE_REG(hw, IXGBE_RAL(1+i), 0); - IXGBE_WRITE_REG(hw, IXGBE_RAH(1+i), 0); - } - - /* Add the new addresses */ - netdev_for_each_uc_addr(ha, netdev) { - hw_dbg(hw, " Adding the secondary addresses:\n"); - ixgbe_add_uc_addr(hw, ha->addr, 0); - } - - if (hw->addr_ctrl.overflow_promisc) { - /* enable promisc if not already in overflow or set by user */ - if (!old_promisc_setting && !hw->addr_ctrl.user_set_promisc) { - hw_dbg(hw, " Entering address overflow promisc mode\n"); - fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); - fctrl |= IXGBE_FCTRL_UPE; - IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); - hw->addr_ctrl.uc_set_promisc = true; - } - } else { - /* only disable if set by overflow, not by user */ - if ((old_promisc_setting && hw->addr_ctrl.uc_set_promisc) && - !(hw->addr_ctrl.user_set_promisc)) { - hw_dbg(hw, " Leaving address overflow promisc mode\n"); - fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); - fctrl &= ~IXGBE_FCTRL_UPE; - IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); - hw->addr_ctrl.uc_set_promisc = false; - } - } - - hw_dbg(hw, "ixgbe_update_uc_addr_list_generic Complete\n"); - return 0; -} - /** * ixgbe_mta_vector - Determines bit-vector in multicast table to set * @hw: pointer to hardware structure diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h index 90cceb4a6317..90ac6095c1ca 100644 --- a/drivers/net/ixgbe/ixgbe_common.h +++ b/drivers/net/ixgbe/ixgbe_common.h @@ -63,8 +63,6 @@ s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index); s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw); s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, struct net_device *netdev); -s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, - struct net_device *netdev); s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw); s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw); s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval); diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index f6d0d4d98dd4..8e0a2130f42d 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -2517,7 +2517,6 @@ struct ixgbe_mac_operations { s32 (*set_vmdq)(struct ixgbe_hw *, u32, u32); s32 (*clear_vmdq)(struct ixgbe_hw *, u32, u32); s32 (*init_rx_addrs)(struct ixgbe_hw *); - s32 (*update_uc_addr_list)(struct ixgbe_hw *, struct net_device *); s32 (*update_mc_addr_list)(struct ixgbe_hw *, struct net_device *); s32 (*enable_mc)(struct ixgbe_hw *); s32 (*disable_mc)(struct ixgbe_hw *); diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index 3229398630f6..fbc0a8bab396 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -686,7 +686,6 @@ static struct ixgbe_mac_operations mac_ops_X540 = { .set_vmdq = &ixgbe_set_vmdq_generic, .clear_vmdq = &ixgbe_clear_vmdq_generic, .init_rx_addrs = &ixgbe_init_rx_addrs_generic, - .update_uc_addr_list = &ixgbe_update_uc_addr_list_generic, .update_mc_addr_list = &ixgbe_update_mc_addr_list_generic, .enable_mc = &ixgbe_enable_mc_generic, .disable_mc = &ixgbe_disable_mc_generic, -- cgit v1.2.3 From 63d778df6d817ea69cadd701abbfa1c491623b50 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 19 Feb 2011 08:43:39 +0000 Subject: ixgbe: Specific check for 100 Full link speed This patch specifically checks for 100 Full link speed instead of assuming we are linked at 100 if not linked at 10G and 1G. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_common.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 4fa195e88f3e..a12f7c73e27d 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -2658,10 +2658,13 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, IXGBE_LINKS_SPEED_10G_82599) *speed = IXGBE_LINK_SPEED_10GB_FULL; else if ((links_reg & IXGBE_LINKS_SPEED_82599) == - IXGBE_LINKS_SPEED_1G_82599) + IXGBE_LINKS_SPEED_1G_82599) *speed = IXGBE_LINK_SPEED_1GB_FULL; - else + else if ((links_reg & IXGBE_LINKS_SPEED_82599) == + IXGBE_LINKS_SPEED_100_82599) *speed = IXGBE_LINK_SPEED_100_FULL; + else + *speed = IXGBE_LINK_SPEED_UNKNOWN; /* if link is down, zero out the current_mode */ if (*link_up == false) { -- cgit v1.2.3 From 8c7bea32c4ebe02dbb574a49db418036da177326 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 19 Feb 2011 08:43:44 +0000 Subject: ixgbe: Numerous whitespace / formatting cleanups This patch contains a number of whitespace and formatting cleanups. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82598.c | 7 ++----- drivers/net/ixgbe/ixgbe_82599.c | 19 +++++++++---------- drivers/net/ixgbe/ixgbe_common.c | 7 ++++--- 3 files changed, 15 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index a5b83b775b6c..8f5e347ac003 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -627,7 +627,6 @@ out: return 0; } - /** * ixgbe_setup_mac_link_82598 - Set MAC link speed * @hw: pointer to hardware structure @@ -698,7 +697,6 @@ static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw, /* Setup the PHY according to input speed */ status = hw->phy.ops.setup_link_speed(hw, speed, autoneg, autoneg_wait_to_complete); - /* Set up MAC */ ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete); @@ -1013,13 +1011,12 @@ static s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val) } /** - * ixgbe_read_i2c_eeprom_82598 - Read 8 bit EEPROM word of an SFP+ module - * over I2C interface through an intermediate phy. + * ixgbe_read_i2c_eeprom_82598 - Reads 8 bit word over I2C interface. * @hw: pointer to hardware structure * @byte_offset: EEPROM byte offset to read * @eeprom_data: value read * - * Performs byte read operation to SFP module's EEPROM over I2C interface. + * Performs 8 byte read operation to SFP module's EEPROM over I2C interface. **/ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, u8 *eeprom_data) diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 69d345b1ecf4..5e2edcd1244d 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -417,14 +417,14 @@ static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, return status; } - /** - * ixgbe_disable_tx_laser_multispeed_fiber - Disable Tx laser - * @hw: pointer to hardware structure - * - * The base drivers may require better control over SFP+ module - * PHY states. This includes selectively shutting down the Tx - * laser on the PHY, effectively halting physical link. - **/ +/** + * ixgbe_disable_tx_laser_multispeed_fiber - Disable Tx laser + * @hw: pointer to hardware structure + * + * The base drivers may require better control over SFP+ module + * PHY states. This includes selectively shutting down the Tx + * laser on the PHY, effectively halting physical link. + **/ static void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) { u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); @@ -542,7 +542,6 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, * Section 73.10.2, we may have to wait up to 500ms if KR is * attempted. 82599 uses the same timing for 10g SFI. */ - for (i = 0; i < 5; i++) { /* Wait for the link partner to also set speed */ msleep(100); @@ -767,7 +766,6 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, else orig_autoc = autoc; - if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR || link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN || link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) { @@ -1926,6 +1924,7 @@ static s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval) if (secrxreg & IXGBE_SECRXSTAT_SECRX_RDY) break; else + /* Use interrupt-safe sleep just in case */ udelay(10); } diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index a12f7c73e27d..33f568cff060 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -1188,7 +1188,7 @@ s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw) if (status == 0) { checksum = hw->eeprom.ops.calc_checksum(hw); status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM, - checksum); + checksum); } else { hw_dbg(hw, "EEPROM read failed\n"); } @@ -1555,7 +1555,9 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num) * 2: Tx flow control is enabled (we can send pause frames but * we do not support receiving pause frames). * 3: Both Rx and Tx flow control (symmetric) are enabled. +#ifdef CONFIG_DCB * 4: Priority Flow Control is enabled. +#endif * other: Invalid. */ switch (hw->fc.current_mode) { @@ -2392,7 +2394,6 @@ s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw) { int i; - for (i = 0; i < 128; i++) IXGBE_WRITE_REG(hw, IXGBE_UTA(i), 0); @@ -2621,7 +2622,7 @@ s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw) * Reads the links register to determine if link is up and the current speed **/ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, - bool *link_up, bool link_up_wait_to_complete) + bool *link_up, bool link_up_wait_to_complete) { u32 links_reg, links_orig; u32 i; -- cgit v1.2.3 From 278675d855e03e111ca84fec6eb7d5569e56c394 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 19 Feb 2011 08:43:49 +0000 Subject: ixgbe: store permanent address before initializing Rx addresses We were reading the address after it had been initialized and this results in the permanent address on the system being changed. This change corrects that by storing the address before we re-initialize it. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82598.c | 6 +++--- drivers/net/ixgbe/ixgbe_82599.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 8f5e347ac003..8f6205ef4a97 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -831,15 +831,15 @@ mac_reset_top: IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc); } + /* Store the permanent mac address */ + hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); + /* * Store MAC address from RAR0, clear receive address registers, and * clear the multicast table */ hw->mac.ops.init_rx_addrs(hw); - /* Store the permanent mac address */ - hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); - reset_hw_out: if (phy_status) status = phy_status; diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 5e2edcd1244d..3d40e68b1b89 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -965,6 +965,9 @@ mac_reset_top: } } + /* Store the permanent mac address */ + hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); + /* * Store MAC address from RAR0, clear receive address registers, and * clear the multicast table. Also reset num_rar_entries to 128, @@ -973,9 +976,6 @@ mac_reset_top: hw->mac.num_rar_entries = 128; hw->mac.ops.init_rx_addrs(hw); - /* Store the permanent mac address */ - hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); - /* Store the permanent SAN mac address */ hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr); -- cgit v1.2.3 From 75f19c3c5eeb67d37ce96e0ea78dc0beb485a723 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 19 Feb 2011 08:43:55 +0000 Subject: ixgbe: cleanup handling of I2C interface to PHY The I2C interface was not being correctly locked down per port. As such this can lead to race conditions that can cause issues. This patch cleans up the handling to make certain we are not experiencing racy I2C access. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_phy.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index ebd6e4492a3f..16b5f499b6b8 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -858,6 +858,9 @@ err_read_i2c_eeprom: * @hw: pointer to hardware structure * @list_offset: offset to the SFP ID list * @data_offset: offset to the SFP data block + * + * Checks the MAC's EEPROM to see if it supports a given SFP+ module type, if + * so it returns the offsets to the phy init sequence block. **/ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, u16 *list_offset, @@ -972,11 +975,22 @@ s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, u8 *data) { s32 status = 0; - u32 max_retry = 1; + u32 max_retry = 10; u32 retry = 0; + u16 swfw_mask = 0; bool nack = 1; + if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1) + swfw_mask = IXGBE_GSSR_PHY1_SM; + else + swfw_mask = IXGBE_GSSR_PHY0_SM; + do { + if (ixgbe_acquire_swfw_sync(hw, swfw_mask) != 0) { + status = IXGBE_ERR_SWFW_SYNC; + goto read_byte_out; + } + ixgbe_i2c_start(hw); /* Device Address and write indication */ @@ -1019,6 +1033,8 @@ s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, break; fail: + ixgbe_release_swfw_sync(hw, swfw_mask); + msleep(100); ixgbe_i2c_bus_clear(hw); retry++; if (retry < max_retry) @@ -1028,6 +1044,9 @@ fail: } while (retry < max_retry); + ixgbe_release_swfw_sync(hw, swfw_mask); + +read_byte_out: return status; } @@ -1046,6 +1065,17 @@ s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, s32 status = 0; u32 max_retry = 1; u32 retry = 0; + u16 swfw_mask = 0; + + if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1) + swfw_mask = IXGBE_GSSR_PHY1_SM; + else + swfw_mask = IXGBE_GSSR_PHY0_SM; + + if (ixgbe_acquire_swfw_sync(hw, swfw_mask) != 0) { + status = IXGBE_ERR_SWFW_SYNC; + goto write_byte_out; + } do { ixgbe_i2c_start(hw); @@ -1086,6 +1116,9 @@ fail: hw_dbg(hw, "I2C byte write error.\n"); } while (retry < max_retry); + ixgbe_release_swfw_sync(hw, swfw_mask); + +write_byte_out: return status; } @@ -1404,6 +1437,8 @@ static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw) u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL); u32 i; + ixgbe_i2c_start(hw); + ixgbe_set_i2c_data(hw, &i2cctl, 1); for (i = 0; i < 9; i++) { @@ -1418,6 +1453,8 @@ static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw) udelay(IXGBE_I2C_T_LOW); } + ixgbe_i2c_start(hw); + /* Put the i2c bus back to default state */ ixgbe_i2c_stop(hw); } -- cgit v1.2.3 From 93cb38dc185f31159d1be70ffcc46802312fa537 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Tue, 1 Mar 2011 04:37:15 +0000 Subject: ixgbe: X540 Cleanup Clean up commented out include file and use #define instead of hard coded value for number of RAR entries. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_x540.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index fbc0a8bab396..11cb136c0150 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -31,7 +31,6 @@ #include "ixgbe.h" #include "ixgbe_phy.h" -//#include "ixgbe_mbx.h" #define IXGBE_X540_MAX_TX_QUEUES 128 #define IXGBE_X540_MAX_RX_QUEUES 128 @@ -201,7 +200,7 @@ mac_reset_top: * clear the multicast table. Also reset num_rar_entries to 128, * since we modify this value when programming the SAN MAC address. */ - hw->mac.num_rar_entries = 128; + hw->mac.num_rar_entries = IXGBE_X540_MAX_TX_QUEUES; hw->mac.ops.init_rx_addrs(hw); /* Store the permanent mac address */ -- cgit v1.2.3 From 5e655105e3e19d746f9e95c514b014c11c3d1b6a Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Fri, 25 Feb 2011 01:58:04 +0000 Subject: ixgbe: add function pointer for semaphore function The X540 devices grabs semaphores differently than 82599 and 82598 devices do. They do however also grab them in allot of the same functions. So I'm adding a new MAC operation function pointer to allow us to use the correct function based on our MAC type. I'm also changing all the semaphore calls to use this new function pointer. Signed-off-by: Don Skidmore Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82598.c | 2 ++ drivers/net/ixgbe/ixgbe_82599.c | 6 +++++- drivers/net/ixgbe/ixgbe_common.c | 4 ++-- drivers/net/ixgbe/ixgbe_phy.c | 8 ++++---- drivers/net/ixgbe/ixgbe_type.h | 2 ++ drivers/net/ixgbe/ixgbe_x540.c | 6 ++++-- 6 files changed, 19 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 8f6205ef4a97..2da629a30531 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -1201,6 +1201,8 @@ static struct ixgbe_mac_operations mac_ops_82598 = { .clear_vfta = &ixgbe_clear_vfta_82598, .set_vfta = &ixgbe_set_vfta_82598, .fc_enable = &ixgbe_fc_enable_82598, + .acquire_swfw_sync = &ixgbe_acquire_swfw_sync, + .release_swfw_sync = &ixgbe_release_swfw_sync, }; static struct ixgbe_eeprom_operations eeprom_ops_82598 = { diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 3d40e68b1b89..8f7c6bd341f6 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -112,7 +112,8 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw) goto setup_sfp_out; /* PHY config will finish before releasing the semaphore */ - ret_val = ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM); + ret_val = hw->mac.ops.acquire_swfw_sync(hw, + IXGBE_GSSR_MAC_CSR_SM); if (ret_val != 0) { ret_val = IXGBE_ERR_SWFW_SYNC; goto setup_sfp_out; @@ -2044,6 +2045,9 @@ static struct ixgbe_mac_operations mac_ops_82599 = { .setup_sfp = &ixgbe_setup_sfp_modules_82599, .set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing, .set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing, + .acquire_swfw_sync = &ixgbe_acquire_swfw_sync, + .release_swfw_sync = &ixgbe_release_swfw_sync, + }; static struct ixgbe_eeprom_operations eeprom_ops_82599 = { diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 33f568cff060..bd14ea4d9570 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -745,7 +745,7 @@ static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw) u32 eec; u32 i; - if (ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != 0) + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != 0) status = IXGBE_ERR_SWFW_SYNC; if (status == 0) { @@ -768,7 +768,7 @@ static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw) IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); hw_dbg(hw, "Could not acquire EEPROM grant\n"); - ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); status = IXGBE_ERR_EEPROM; } diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index 16b5f499b6b8..f4569e8f375d 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -205,7 +205,7 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, else gssr = IXGBE_GSSR_PHY0_SM; - if (ixgbe_acquire_swfw_sync(hw, gssr) != 0) + if (hw->mac.ops.acquire_swfw_sync(hw, gssr) != 0) status = IXGBE_ERR_SWFW_SYNC; if (status == 0) { @@ -277,7 +277,7 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, } } - ixgbe_release_swfw_sync(hw, gssr); + hw->mac.ops.release_swfw_sync(hw, gssr); } return status; @@ -303,7 +303,7 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, else gssr = IXGBE_GSSR_PHY0_SM; - if (ixgbe_acquire_swfw_sync(hw, gssr) != 0) + if (hw->mac.ops.acquire_swfw_sync(hw, gssr) != 0) status = IXGBE_ERR_SWFW_SYNC; if (status == 0) { @@ -370,7 +370,7 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, } } - ixgbe_release_swfw_sync(hw, gssr); + hw->mac.ops.release_swfw_sync(hw, gssr); } return status; diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 8e0a2130f42d..e940f23a6441 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -2495,6 +2495,8 @@ struct ixgbe_mac_operations { s32 (*write_analog_reg8)(struct ixgbe_hw*, u32, u8); s32 (*setup_sfp)(struct ixgbe_hw *); s32 (*enable_rx_dma)(struct ixgbe_hw *, u32); + s32 (*acquire_swfw_sync)(struct ixgbe_hw *, u16); + void (*release_swfw_sync)(struct ixgbe_hw *, u16); /* Link */ void (*disable_tx_laser)(struct ixgbe_hw *); diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index 11cb136c0150..eb047736c4cb 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -287,7 +287,7 @@ static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data) { s32 status; - if (ixgbe_acquire_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM) == 0) + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) status = ixgbe_read_eerd_generic(hw, offset, data); else status = IXGBE_ERR_SWFW_SYNC; @@ -320,7 +320,7 @@ static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data) (data << IXGBE_EEPROM_RW_REG_DATA) | IXGBE_EEPROM_RW_REG_START; - if (ixgbe_acquire_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM) == 0) { + if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) { status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE); if (status != 0) { hw_dbg(hw, "Eeprom write EEWR timed out\n"); @@ -695,6 +695,8 @@ static struct ixgbe_mac_operations mac_ops_X540 = { .setup_sfp = NULL, .set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing, .set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing, + .acquire_swfw_sync = &ixgbe_acquire_swfw_sync_X540, + .release_swfw_sync = &ixgbe_release_swfw_sync_X540, }; static struct ixgbe_eeprom_operations eeprom_ops_X540 = { -- cgit v1.2.3 From a52055e055f5b551c0814c4381e43b204f9db777 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Wed, 23 Feb 2011 09:58:39 +0000 Subject: ixgbe: cleanup copyright string for 2011 Updating the copyrights for 2011 as well as make the ixgbe_copyright string a constant. Signed-off-by: Don Skidmore Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 2 +- drivers/net/ixgbe/ixgbe_82598.c | 2 +- drivers/net/ixgbe/ixgbe_82599.c | 2 +- drivers/net/ixgbe/ixgbe_common.c | 2 +- drivers/net/ixgbe/ixgbe_common.h | 2 +- drivers/net/ixgbe/ixgbe_dcb.c | 2 +- drivers/net/ixgbe/ixgbe_dcb.h | 2 +- drivers/net/ixgbe/ixgbe_dcb_82598.c | 2 +- drivers/net/ixgbe/ixgbe_dcb_82598.h | 2 +- drivers/net/ixgbe/ixgbe_dcb_82599.c | 2 +- drivers/net/ixgbe/ixgbe_dcb_82599.h | 2 +- drivers/net/ixgbe/ixgbe_dcb_nl.c | 2 +- drivers/net/ixgbe/ixgbe_ethtool.c | 2 +- drivers/net/ixgbe/ixgbe_fcoe.c | 2 +- drivers/net/ixgbe/ixgbe_fcoe.h | 2 +- drivers/net/ixgbe/ixgbe_main.c | 5 +++-- drivers/net/ixgbe/ixgbe_mbx.c | 2 +- drivers/net/ixgbe/ixgbe_mbx.h | 2 +- drivers/net/ixgbe/ixgbe_phy.c | 2 +- drivers/net/ixgbe/ixgbe_phy.h | 2 +- drivers/net/ixgbe/ixgbe_sriov.c | 2 +- drivers/net/ixgbe/ixgbe_sriov.h | 2 +- drivers/net/ixgbe/ixgbe_type.h | 2 +- drivers/net/ixgbe/ixgbe_x540.c | 2 +- 24 files changed, 26 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 12769b58c2e7..b60b81bc2b15 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 2da629a30531..fc41329399be 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 8f7c6bd341f6..5ef968a10d42 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index bd14ea4d9570..a7fb2e00f766 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h index 90ac6095c1ca..508f635fc2ca 100644 --- a/drivers/net/ixgbe/ixgbe_common.h +++ b/drivers/net/ixgbe/ixgbe_common.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c index 13c962efbfc9..c2ee6fcb4e91 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.c +++ b/drivers/net/ixgbe/ixgbe_dcb.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_dcb.h b/drivers/net/ixgbe/ixgbe_dcb.h index e5935114815e..515bc27477f6 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.h +++ b/drivers/net/ixgbe/ixgbe_dcb.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c index 2965edcdac7b..c97cf9160dc0 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.h b/drivers/net/ixgbe/ixgbe_dcb_82598.h index 0d2a758effce..1e9750c2b46b 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.h +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c index b0d97a98c84d..beaa1c1c1e67 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.h b/drivers/net/ixgbe/ixgbe_dcb_82599.h index 5b0ca85614d1..0b39ab4ffc70 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.h +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index a977df3fe81b..d7f0024014b1 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 309272f8f103..83511c022926 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index c54a88274d51..27203c87ea14 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h index 65cc8fb14fe7..02a00d2415d9 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.h +++ b/drivers/net/ixgbe/ixgbe_fcoe.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 987771968cbb..32231ffe0717 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -54,7 +54,8 @@ static const char ixgbe_driver_string[] = #define DRV_VERSION "3.2.9-k2" const char ixgbe_driver_version[] = DRV_VERSION; -static char ixgbe_copyright[] = "Copyright (c) 1999-2010 Intel Corporation."; +static const char ixgbe_copyright[] = + "Copyright (c) 1999-2011 Intel Corporation."; static const struct ixgbe_info *ixgbe_info_tbl[] = { [board_82598] = &ixgbe_82598_info, diff --git a/drivers/net/ixgbe/ixgbe_mbx.c b/drivers/net/ixgbe/ixgbe_mbx.c index f215c4c296c4..2acacfa5e375 100644 --- a/drivers/net/ixgbe/ixgbe_mbx.c +++ b/drivers/net/ixgbe/ixgbe_mbx.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_mbx.h b/drivers/net/ixgbe/ixgbe_mbx.h index ada0ce32a7a6..fe6ea81dc7f8 100644 --- a/drivers/net/ixgbe/ixgbe_mbx.h +++ b/drivers/net/ixgbe/ixgbe_mbx.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index f4569e8f375d..197230b2d1ac 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h index e2c6b7eac641..2327baf04426 100644 --- a/drivers/net/ixgbe/ixgbe_phy.h +++ b/drivers/net/ixgbe/ixgbe_phy.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c index fb4868d0a32d..58c9b45989ff 100644 --- a/drivers/net/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ixgbe/ixgbe_sriov.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_sriov.h b/drivers/net/ixgbe/ixgbe_sriov.h index 49dc14debef7..e7dd029d576a 100644 --- a/drivers/net/ixgbe/ixgbe_sriov.h +++ b/drivers/net/ixgbe/ixgbe_sriov.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index e940f23a6441..013751db5fc0 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index eb047736c4cb..2e3a2b4fa8b2 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2011 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, -- cgit v1.2.3 From a4e36e60a6f62db6282e718cc228bde1a4e31eba Mon Sep 17 00:00:00 2001 From: "Arnaud Patard (Rtp)" Date: Mon, 28 Feb 2011 10:15:59 -0300 Subject: [media] mantis_pci: remove asm/pgtable.h include mantis_pci.c is including asm/pgtable.h and it's leading to a build failure on arm. It has been noticed here : https://buildd.debian.org/fetch.cgi?pkg=linux-2.6&arch=armel&ver=2.6.38~rc6-1~experimental.1&stamp=1298430952&file=log&as=raw As this header doesn't seem to be used, I'm removing it. I've build tested it with arm and x86. Signed-off-by: Arnaud Patard Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/mantis/mantis_pci.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/mantis/mantis_pci.c b/drivers/media/dvb/mantis/mantis_pci.c index 59feeb84aec7..10a432a79d00 100644 --- a/drivers/media/dvb/mantis/mantis_pci.c +++ b/drivers/media/dvb/mantis/mantis_pci.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From f62c317c1f7f67c249ee9254e55a02fad0d0f86b Mon Sep 17 00:00:00 2001 From: Sebastien Jan Date: Wed, 23 Feb 2011 14:25:16 +0100 Subject: wl12xx: fix the path to the wl12xx firmwares In the linux-firmware git tree, the firmwares and the NVS are inside the ti-connectivity directory. Fix the filenames that the driver looks for accordingly. [Fixed commit message and merged with the latest changes. -- Luca] Signed-off-by: Sebastien Jan Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl12xx.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 338acc9f60b3..7132bc7dd2cf 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -130,10 +130,10 @@ extern u32 wl12xx_debug_level; -#define WL1271_FW_NAME "wl1271-fw-2.bin" -#define WL1271_AP_FW_NAME "wl1271-fw-ap.bin" +#define WL1271_FW_NAME "ti-connectivity/wl1271-fw-2.bin" +#define WL1271_AP_FW_NAME "ti-connectivity/wl1271-fw-ap.bin" -#define WL1271_NVS_NAME "wl1271-nvs.bin" +#define WL1271_NVS_NAME "ti-connectivity/wl1271-nvs.bin" #define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) #define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff)) -- cgit v1.2.3 From 11251e7e5c7c5411d1f77dbc7f9bfa2c23626749 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Mon, 28 Feb 2011 00:13:58 +0200 Subject: wl12xx: Don't rely on runtime PM for toggling power Runtime PM might not always be enabled. Even if it is enabled in the running kernel, it can still be temporarily disabled, for instance during suspend. Runtime PM is opportunistic in nature, and should not be relied on for toggling power. In case the interface is removed and re-added while runtime PM is disabled, the FW will fail to boot, as it is mandatory to toggle power between boots. For instance, this can happen during suspend in case one of the devices fails to suspend before the MMC host suspends, but after mac80211 was suspended. The interface will be removed and reactivated without toggling the power. Fix this by calling mmc_power_save_host/mmc_power_restore_host in wl1271_sdio_power_on/off functions. It will toggle the power to the chip even if runtime PM is disabled. The runtime PM functions should still be called to make sure runtime PM does not opportunistically power the chip off (e.g. after resuming from system suspend). Signed-off-by: Ido Yariv Signed-off-by: Ohad Ben-Cohen Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/sdio.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index d5e874825069..f27e91502631 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -163,11 +164,16 @@ static int wl1271_sdio_power_on(struct wl1271 *wl) struct sdio_func *func = wl_to_func(wl); int ret; - /* Power up the card */ + /* Make sure the card will not be powered off by runtime PM */ ret = pm_runtime_get_sync(&func->dev); if (ret < 0) goto out; + /* Runtime PM might be disabled, so power up the card manually */ + ret = mmc_power_restore_host(func->card->host); + if (ret < 0) + goto out; + sdio_claim_host(func); sdio_enable_func(func); sdio_release_host(func); @@ -179,12 +185,18 @@ out: static int wl1271_sdio_power_off(struct wl1271 *wl) { struct sdio_func *func = wl_to_func(wl); + int ret; sdio_claim_host(func); sdio_disable_func(func); sdio_release_host(func); - /* Power down the card */ + /* Runtime PM might be disabled, so power off the card manually */ + ret = mmc_power_save_host(func->card->host); + if (ret < 0) + return ret; + + /* Let runtime PM know the card is powered off */ return pm_runtime_put_sync(&func->dev); } -- cgit v1.2.3 From 50e9f746f63c9b881f2ca4a35dbdfd34b1a8a215 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Mon, 28 Feb 2011 00:16:13 +0200 Subject: wl12xx: Remove private headers in wl1271_tx_reset Frames in the tx_frames array include extra private headers, which must be removed before passing the skbs to ieee80211_tx_status. Fix this by removing any private headers in wl1271_tx_reset, similar to how this is done in wl1271_tx_complete_packet. Signed-off-by: Ido Yariv Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/tx.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index ac60d577319f..37d354ddd58e 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -687,16 +687,30 @@ void wl1271_tx_reset(struct wl1271 *wl) */ wl1271_handle_tx_low_watermark(wl); - for (i = 0; i < ACX_TX_DESCRIPTORS; i++) - if (wl->tx_frames[i] != NULL) { - skb = wl->tx_frames[i]; - wl1271_free_tx_id(wl, i); - wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); - info = IEEE80211_SKB_CB(skb); - info->status.rates[0].idx = -1; - info->status.rates[0].count = 0; - ieee80211_tx_status(wl->hw, skb); + for (i = 0; i < ACX_TX_DESCRIPTORS; i++) { + if (wl->tx_frames[i] == NULL) + continue; + + skb = wl->tx_frames[i]; + wl1271_free_tx_id(wl, i); + wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); + + /* Remove private headers before passing the skb to mac80211 */ + info = IEEE80211_SKB_CB(skb); + skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); + if (info->control.hw_key && + info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { + int hdrlen = ieee80211_get_hdrlen_from_skb(skb); + memmove(skb->data + WL1271_TKIP_IV_SPACE, skb->data, + hdrlen); + skb_pull(skb, WL1271_TKIP_IV_SPACE); } + + info->status.rates[0].idx = -1; + info->status.rates[0].count = 0; + + ieee80211_tx_status(wl->hw, skb); + } } #define WL1271_TX_FLUSH_TIMEOUT 500000 -- cgit v1.2.3 From 8aad24642a7c06832a75f1d20e8e3112b4fbd815 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Tue, 1 Mar 2011 15:14:38 +0200 Subject: wl12xx: Reorder data handling in irq_work The FW has a limited amount of memory for holding frames. In case it runs out of memory reserved for RX frames, it'll have no other choice but to drop packets received from the AP. Thus, it is important to handle RX data interrupts as soon as possible, before handling anything else. In addition, since there are enough TX descriptors to go around, it is better to first send TX frames, and only then handle TX completions. Fix this by changing the order of function calls in wl1271_irq_work. Signed-off-by: Ido Yariv Signed-off-by: Ohad Ben-Cohen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 947491a1d9cc..65e8a0cc92d0 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -685,10 +685,7 @@ static void wl1271_irq_work(struct work_struct *work) if (intr & WL1271_ACX_INTR_DATA) { wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); - /* check for tx results */ - if (wl->fw_status->common.tx_results_counter != - (wl->tx_results_count & 0xff)) - wl1271_tx_complete(wl); + wl1271_rx(wl, &wl->fw_status->common); /* Check if any tx blocks were freed */ if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && @@ -700,7 +697,10 @@ static void wl1271_irq_work(struct work_struct *work) wl1271_tx_work_locked(wl); } - wl1271_rx(wl, &wl->fw_status->common); + /* check for tx results */ + if (wl->fw_status->common.tx_results_counter != + (wl->tx_results_count & 0xff)) + wl1271_tx_complete(wl); } if (intr & WL1271_ACX_INTR_EVENT_A) { -- cgit v1.2.3 From 606ea9fa0b2c01ffafb6beae92ea8e2b1473520b Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Tue, 1 Mar 2011 15:14:39 +0200 Subject: wl12xx: Do end-of-transactions transfers only if needed On newer hardware revisions, there is no need to write the host's counter at the end of a RX transaction. The same applies to writing the number of packets at the end of a TX transaction. It is generally a good idea to avoid unnecessary SDIO/SPI transfers. Throughput and CPU usage are improved when avoiding these. Send the host's RX counter and the TX packet count only if needed, based on the hardware revision. [Changed WL12XX_QUIRK_END_OF_TRANSACTION to use BIT(0) -- Luca] Signed-off-by: Ido Yariv Signed-off-by: Ohad Ben-Cohen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/boot.c | 3 +++ drivers/net/wireless/wl12xx/boot.h | 5 +++++ drivers/net/wireless/wl12xx/main.c | 1 + drivers/net/wireless/wl12xx/rx.c | 8 +++++++- drivers/net/wireless/wl12xx/tx.c | 10 ++++++++-- drivers/net/wireless/wl12xx/wl12xx.h | 8 ++++++++ 6 files changed, 32 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index 1ffbad67d2d8..6934dffd5174 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c @@ -488,6 +488,9 @@ static void wl1271_boot_hw_version(struct wl1271 *wl) fuse = (fuse & PG_VER_MASK) >> PG_VER_OFFSET; wl->hw_pg_ver = (s8)fuse; + + if (((wl->hw_pg_ver & PG_MAJOR_VER_MASK) >> PG_MAJOR_VER_OFFSET) < 3) + wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION; } /* uploads NVS and firmware */ diff --git a/drivers/net/wireless/wl12xx/boot.h b/drivers/net/wireless/wl12xx/boot.h index d67dcffa31eb..17229b86fc71 100644 --- a/drivers/net/wireless/wl12xx/boot.h +++ b/drivers/net/wireless/wl12xx/boot.h @@ -59,6 +59,11 @@ struct wl1271_static_data { #define PG_VER_MASK 0x3c #define PG_VER_OFFSET 2 +#define PG_MAJOR_VER_MASK 0x3 +#define PG_MAJOR_VER_OFFSET 0x0 +#define PG_MINOR_VER_MASK 0xc +#define PG_MINOR_VER_OFFSET 0x2 + #define CMD_MBOX_ADDRESS 0x407B4 #define POLARITY_LOW BIT(1) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 65e8a0cc92d0..ba34ac3a440d 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -3404,6 +3404,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void) wl->last_tx_hlid = 0; wl->ap_ps_map = 0; wl->ap_fw_ps_map = 0; + wl->quirks = 0; memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); for (i = 0; i < ACX_TX_DESCRIPTORS; i++) diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c index 3d13d7a83ea1..4e7a3b311321 100644 --- a/drivers/net/wireless/wl12xx/rx.c +++ b/drivers/net/wireless/wl12xx/rx.c @@ -198,7 +198,13 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status) pkt_offset += pkt_length; } } - wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); + + /* + * Write the driver's packet counter to the FW. This is only required + * for older hardware revisions + */ + if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION) + wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); } void wl1271_set_default_filters(struct wl1271 *wl) diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 37d354ddd58e..455954edf83e 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -506,8 +506,14 @@ out_ack: sent_packets = true; } if (sent_packets) { - /* interrupt the firmware with the new packets */ - wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count); + /* + * Interrupt the firmware with the new packets. This is only + * required for older hardware revisions + */ + if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION) + wl1271_write32(wl, WL1271_HOST_WR_ACCESS, + wl->tx_packets_count); + wl1271_handle_tx_low_watermark(wl); } diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 7132bc7dd2cf..ea1eee7895cf 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -535,6 +535,9 @@ struct wl1271 { /* AP-mode - a bitmap of links currently in PS mode in mac80211 */ unsigned long ap_ps_map; + + /* Quirks of specific hardware revisions */ + unsigned int quirks; }; struct wl1271_station { @@ -562,4 +565,9 @@ int wl1271_plt_stop(struct wl1271 *wl); #define HW_BG_RATES_MASK 0xffff #define HW_HT_RATES_OFFSET 16 +/* Quirks */ + +/* Each RX/TX transaction requires an end-of-transaction transfer */ +#define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0) + #endif -- cgit v1.2.3 From 393fb560d328cc06e6a5c7b7473901ad724f82e7 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Tue, 1 Mar 2011 15:14:40 +0200 Subject: wl12xx: Change claiming of the SDIO bus The SDIO bus is claimed and released for each SDIO transaction. In addition to the few CPU cycles it takes to claim and release the bus, it may also cause undesired side effects such as the MMC host stopping its internal clocks. Since only the wl12xx_sdio driver drives this SDIO card, it is safe to claim the SDIO host once (on power on), and release it only when turning the power off. This patch was inspired by Juuso Oikarinen's (juuso.oikarinen@nokia.com) patch "wl12xx: Change claiming of the (SDIO) bus". Signed-off-by: Ido Yariv Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/sdio.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index f27e91502631..61fdc9e981bd 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -107,8 +107,6 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, int ret; struct sdio_func *func = wl_to_func(wl); - sdio_claim_host(func); - if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x", @@ -124,8 +122,6 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); } - sdio_release_host(func); - if (ret) wl1271_error("sdio read failed (%d)", ret); } @@ -136,8 +132,6 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, int ret; struct sdio_func *func = wl_to_func(wl); - sdio_claim_host(func); - if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x", @@ -153,8 +147,6 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, ret = sdio_memcpy_toio(func, addr, buf, len); } - sdio_release_host(func); - if (ret) wl1271_error("sdio write failed (%d)", ret); } @@ -176,7 +168,6 @@ static int wl1271_sdio_power_on(struct wl1271 *wl) sdio_claim_host(func); sdio_enable_func(func); - sdio_release_host(func); out: return ret; @@ -187,7 +178,6 @@ static int wl1271_sdio_power_off(struct wl1271 *wl) struct sdio_func *func = wl_to_func(wl); int ret; - sdio_claim_host(func); sdio_disable_func(func); sdio_release_host(func); -- cgit v1.2.3 From a620865edf62ea2d024bbfe62162244473badfcb Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Tue, 1 Mar 2011 15:14:41 +0200 Subject: wl12xx: Switch to a threaded interrupt handler To achieve maximal throughput, it is very important to react to interrupts as soon as possible. Currently the interrupt handler wakes up a worker for handling interrupts in process context. A cleaner and more efficient design would be to request a threaded interrupt handler. This handler's priority is very high, and can do blocking operations such as SDIO/SPI transactions. Some work can be deferred, mostly calls to mac80211 APIs (ieee80211_rx_ni and ieee80211_tx_status). By deferring such work to a different worker, we can keep the irq handler thread more I/O responsive. In addition, on multi-core systems the two threads can be scheduled on different cores, which will improve overall performance. The use of WL1271_FLAG_IRQ_PENDING & WL1271_FLAG_IRQ_RUNNING was changed. For simplicity, always query the FW for more pending interrupts. Since there are relatively long bursts of interrupts, the extra FW status read overhead is negligible. In addition, this enables registering the IRQ handler with the ONESHOT option. Signed-off-by: Ido Yariv Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/debugfs.c | 2 +- drivers/net/wireless/wl12xx/io.h | 1 + drivers/net/wireless/wl12xx/main.c | 127 +++++++++++++++++++++------------- drivers/net/wireless/wl12xx/ps.c | 6 +- drivers/net/wireless/wl12xx/ps.h | 2 +- drivers/net/wireless/wl12xx/rx.c | 3 +- drivers/net/wireless/wl12xx/sdio.c | 16 ++--- drivers/net/wireless/wl12xx/spi.c | 19 ++--- drivers/net/wireless/wl12xx/tx.c | 5 +- drivers/net/wireless/wl12xx/wl12xx.h | 13 +++- 10 files changed, 113 insertions(+), 81 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index bebfa28a171a..8e75b09723b9 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c @@ -99,7 +99,7 @@ static void wl1271_debugfs_update_stats(struct wl1271 *wl) mutex_lock(&wl->mutex); - ret = wl1271_ps_elp_wakeup(wl, false); + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out; diff --git a/drivers/net/wireless/wl12xx/io.h b/drivers/net/wireless/wl12xx/io.h index 844b32b170bb..c1aac8292089 100644 --- a/drivers/net/wireless/wl12xx/io.h +++ b/drivers/net/wireless/wl12xx/io.h @@ -168,5 +168,6 @@ void wl1271_unregister_hw(struct wl1271 *wl); int wl1271_init_ieee80211(struct wl1271 *wl); struct ieee80211_hw *wl1271_alloc_hw(void); int wl1271_free_hw(struct wl1271 *wl); +irqreturn_t wl1271_irq(int irq, void *data); #endif diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index ba34ac3a440d..f408c5a84cc9 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -374,7 +374,7 @@ static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) goto out; - ret = wl1271_ps_elp_wakeup(wl, false); + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out; @@ -635,16 +635,39 @@ static void wl1271_fw_status(struct wl1271 *wl, (s64)le32_to_cpu(status->fw_localtime); } -#define WL1271_IRQ_MAX_LOOPS 10 +static void wl1271_flush_deferred_work(struct wl1271 *wl) +{ + struct sk_buff *skb; + + /* Pass all received frames to the network stack */ + while ((skb = skb_dequeue(&wl->deferred_rx_queue))) + ieee80211_rx_ni(wl->hw, skb); + + /* Return sent skbs to the network stack */ + while ((skb = skb_dequeue(&wl->deferred_tx_queue))) + ieee80211_tx_status(wl->hw, skb); +} + +static void wl1271_netstack_work(struct work_struct *work) +{ + struct wl1271 *wl = + container_of(work, struct wl1271, netstack_work); + + do { + wl1271_flush_deferred_work(wl); + } while (skb_queue_len(&wl->deferred_rx_queue)); +} -static void wl1271_irq_work(struct work_struct *work) +#define WL1271_IRQ_MAX_LOOPS 256 + +irqreturn_t wl1271_irq(int irq, void *cookie) { int ret; u32 intr; int loopcount = WL1271_IRQ_MAX_LOOPS; - unsigned long flags; - struct wl1271 *wl = - container_of(work, struct wl1271, irq_work); + struct wl1271 *wl = (struct wl1271 *)cookie; + bool done = false; + unsigned int defer_count; mutex_lock(&wl->mutex); @@ -653,26 +676,27 @@ static void wl1271_irq_work(struct work_struct *work) if (unlikely(wl->state == WL1271_STATE_OFF)) goto out; - ret = wl1271_ps_elp_wakeup(wl, true); + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out; - spin_lock_irqsave(&wl->wl_lock, flags); - while (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags) && loopcount) { - clear_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); - spin_unlock_irqrestore(&wl->wl_lock, flags); - loopcount--; + while (!done && loopcount--) { + /* + * In order to avoid a race with the hardirq, clear the flag + * before acknowledging the chip. Since the mutex is held, + * wl1271_ps_elp_wakeup cannot be called concurrently. + */ + clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); + smp_mb__after_clear_bit(); wl1271_fw_status(wl, wl->fw_status); intr = le32_to_cpu(wl->fw_status->common.intr); + intr &= WL1271_INTR_MASK; if (!intr) { - wl1271_debug(DEBUG_IRQ, "Zero interrupt received."); - spin_lock_irqsave(&wl->wl_lock, flags); + done = true; continue; } - intr &= WL1271_INTR_MASK; - if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) { wl1271_error("watchdog interrupt received! " "starting recovery."); @@ -682,7 +706,7 @@ static void wl1271_irq_work(struct work_struct *work) goto out; } - if (intr & WL1271_ACX_INTR_DATA) { + if (likely(intr & WL1271_ACX_INTR_DATA)) { wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); wl1271_rx(wl, &wl->fw_status->common); @@ -701,6 +725,12 @@ static void wl1271_irq_work(struct work_struct *work) if (wl->fw_status->common.tx_results_counter != (wl->tx_results_count & 0xff)) wl1271_tx_complete(wl); + + /* Make sure the deferred queues don't get too long */ + defer_count = skb_queue_len(&wl->deferred_tx_queue) + + skb_queue_len(&wl->deferred_rx_queue); + if (defer_count > WL1271_DEFERRED_QUEUE_LIMIT) + wl1271_flush_deferred_work(wl); } if (intr & WL1271_ACX_INTR_EVENT_A) { @@ -719,21 +749,16 @@ static void wl1271_irq_work(struct work_struct *work) if (intr & WL1271_ACX_INTR_HW_AVAILABLE) wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE"); - - spin_lock_irqsave(&wl->wl_lock, flags); } - if (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags)) - ieee80211_queue_work(wl->hw, &wl->irq_work); - else - clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); - spin_unlock_irqrestore(&wl->wl_lock, flags); - wl1271_ps_elp_sleep(wl); out: mutex_unlock(&wl->mutex); + + return IRQ_HANDLED; } +EXPORT_SYMBOL_GPL(wl1271_irq); static int wl1271_fetch_firmware(struct wl1271 *wl) { @@ -974,7 +999,6 @@ int wl1271_plt_start(struct wl1271 *wl) goto out; irq_disable: - wl1271_disable_interrupts(wl); mutex_unlock(&wl->mutex); /* Unlocking the mutex in the middle of handling is inherently unsafe. In this case we deem it safe to do, @@ -983,7 +1007,9 @@ irq_disable: work function will not do anything.) Also, any other possible concurrent operations will fail due to the current state, hence the wl1271 struct should be safe. */ - cancel_work_sync(&wl->irq_work); + wl1271_disable_interrupts(wl); + wl1271_flush_deferred_work(wl); + cancel_work_sync(&wl->netstack_work); mutex_lock(&wl->mutex); power_off: wl1271_power_off(wl); @@ -1010,14 +1036,15 @@ int __wl1271_plt_stop(struct wl1271 *wl) goto out; } - wl1271_disable_interrupts(wl); wl1271_power_off(wl); wl->state = WL1271_STATE_OFF; wl->rx_counter = 0; mutex_unlock(&wl->mutex); - cancel_work_sync(&wl->irq_work); + wl1271_disable_interrupts(wl); + wl1271_flush_deferred_work(wl); + cancel_work_sync(&wl->netstack_work); cancel_work_sync(&wl->recovery_work); mutex_lock(&wl->mutex); out: @@ -1169,7 +1196,6 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, break; irq_disable: - wl1271_disable_interrupts(wl); mutex_unlock(&wl->mutex); /* Unlocking the mutex in the middle of handling is inherently unsafe. In this case we deem it safe to do, @@ -1178,7 +1204,9 @@ irq_disable: work function will not do anything.) Also, any other possible concurrent operations will fail due to the current state, hence the wl1271 struct should be safe. */ - cancel_work_sync(&wl->irq_work); + wl1271_disable_interrupts(wl); + wl1271_flush_deferred_work(wl); + cancel_work_sync(&wl->netstack_work); mutex_lock(&wl->mutex); power_off: wl1271_power_off(wl); @@ -1244,12 +1272,12 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl) wl->state = WL1271_STATE_OFF; - wl1271_disable_interrupts(wl); - mutex_unlock(&wl->mutex); + wl1271_disable_interrupts(wl); + wl1271_flush_deferred_work(wl); cancel_delayed_work_sync(&wl->scan_complete_work); - cancel_work_sync(&wl->irq_work); + cancel_work_sync(&wl->netstack_work); cancel_work_sync(&wl->tx_work); cancel_delayed_work_sync(&wl->pspoll_work); cancel_delayed_work_sync(&wl->elp_work); @@ -1525,7 +1553,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); - ret = wl1271_ps_elp_wakeup(wl, false); + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out; @@ -1681,7 +1709,7 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw, if (unlikely(wl->state == WL1271_STATE_OFF)) goto out; - ret = wl1271_ps_elp_wakeup(wl, false); + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out; @@ -1910,7 +1938,7 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, goto out_unlock; } - ret = wl1271_ps_elp_wakeup(wl, false); + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out_unlock; @@ -2013,7 +2041,7 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, goto out; } - ret = wl1271_ps_elp_wakeup(wl, false); + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out; @@ -2039,7 +2067,7 @@ static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) goto out; } - ret = wl1271_ps_elp_wakeup(wl, false); + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out; @@ -2067,7 +2095,7 @@ static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) goto out; } - ret = wl1271_ps_elp_wakeup(wl, false); + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out; @@ -2546,7 +2574,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, if (unlikely(wl->state == WL1271_STATE_OFF)) goto out; - ret = wl1271_ps_elp_wakeup(wl, false); + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out; @@ -2601,7 +2629,7 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue, conf_tid->apsd_conf[0] = 0; conf_tid->apsd_conf[1] = 0; } else { - ret = wl1271_ps_elp_wakeup(wl, false); + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out; @@ -2647,7 +2675,7 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw) if (unlikely(wl->state == WL1271_STATE_OFF)) goto out; - ret = wl1271_ps_elp_wakeup(wl, false); + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out; @@ -2736,7 +2764,7 @@ static int wl1271_op_sta_add(struct ieee80211_hw *hw, if (ret < 0) goto out; - ret = wl1271_ps_elp_wakeup(wl, false); + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out_free_sta; @@ -2779,7 +2807,7 @@ static int wl1271_op_sta_remove(struct ieee80211_hw *hw, if (WARN_ON(!test_bit(id, wl->ap_hlid_map))) goto out; - ret = wl1271_ps_elp_wakeup(wl, false); + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out; @@ -2812,7 +2840,7 @@ int wl1271_op_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, goto out; } - ret = wl1271_ps_elp_wakeup(wl, false); + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out; @@ -3176,7 +3204,7 @@ static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev, if (wl->state == WL1271_STATE_OFF) goto out; - ret = wl1271_ps_elp_wakeup(wl, false); + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out; @@ -3376,9 +3404,12 @@ struct ieee80211_hw *wl1271_alloc_hw(void) for (j = 0; j < AP_MAX_LINKS; j++) skb_queue_head_init(&wl->links[j].tx_queue[i]); + skb_queue_head_init(&wl->deferred_rx_queue); + skb_queue_head_init(&wl->deferred_tx_queue); + INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work); - INIT_WORK(&wl->irq_work, wl1271_irq_work); + INIT_WORK(&wl->netstack_work, wl1271_netstack_work); INIT_WORK(&wl->tx_work, wl1271_tx_work); INIT_WORK(&wl->recovery_work, wl1271_recovery_work); INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index 5c347b1bd17f..971f13e792da 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c @@ -69,7 +69,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl) } } -int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake) +int wl1271_ps_elp_wakeup(struct wl1271 *wl) { DECLARE_COMPLETION_ONSTACK(compl); unsigned long flags; @@ -87,7 +87,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake) * the completion variable in one entity. */ spin_lock_irqsave(&wl->wl_lock, flags); - if (work_pending(&wl->irq_work) || chip_awake) + if (test_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) pending = true; else wl->elp_compl = &compl; @@ -149,7 +149,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, case STATION_ACTIVE_MODE: default: wl1271_debug(DEBUG_PSM, "leaving psm"); - ret = wl1271_ps_elp_wakeup(wl, false); + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) return ret; diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/wl12xx/ps.h index fc1f4c193593..c41bd0a711bc 100644 --- a/drivers/net/wireless/wl12xx/ps.h +++ b/drivers/net/wireless/wl12xx/ps.h @@ -30,7 +30,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, u32 rates, bool send); void wl1271_ps_elp_sleep(struct wl1271 *wl); -int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake); +int wl1271_ps_elp_wakeup(struct wl1271 *wl); void wl1271_elp_work(struct work_struct *work); void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues); void wl1271_ps_link_end(struct wl1271 *wl, u8 hlid); diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c index 4e7a3b311321..919b59f00301 100644 --- a/drivers/net/wireless/wl12xx/rx.c +++ b/drivers/net/wireless/wl12xx/rx.c @@ -129,7 +129,8 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) skb_trim(skb, skb->len - desc->pad_len); - ieee80211_rx_ni(wl->hw, skb); + skb_queue_tail(&wl->deferred_rx_queue, skb); + ieee80211_queue_work(wl->hw, &wl->netstack_work); return 0; } diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 61fdc9e981bd..b66abb5ebcf3 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -61,7 +61,7 @@ static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl) return &(wl_to_func(wl)->dev); } -static irqreturn_t wl1271_irq(int irq, void *cookie) +static irqreturn_t wl1271_hardirq(int irq, void *cookie) { struct wl1271 *wl = cookie; unsigned long flags; @@ -70,17 +70,14 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) /* complete the ELP completion */ spin_lock_irqsave(&wl->wl_lock, flags); + set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); if (wl->elp_compl) { complete(wl->elp_compl); wl->elp_compl = NULL; } - - if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) - ieee80211_queue_work(wl->hw, &wl->irq_work); - set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); spin_unlock_irqrestore(&wl->wl_lock, flags); - return IRQ_HANDLED; + return IRQ_WAKE_THREAD; } static void wl1271_sdio_disable_interrupts(struct wl1271 *wl) @@ -243,14 +240,14 @@ static int __devinit wl1271_probe(struct sdio_func *func, wl->irq = wlan_data->irq; wl->ref_clock = wlan_data->board_ref_clock; - ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); + ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, + IRQF_TRIGGER_RISING, + DRIVER_NAME, wl); if (ret < 0) { wl1271_error("request_irq() failed: %d", ret); goto out_free; } - set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); - disable_irq(wl->irq); ret = wl1271_init_ieee80211(wl); @@ -273,7 +270,6 @@ static int __devinit wl1271_probe(struct sdio_func *func, out_irq: free_irq(wl->irq, wl); - out_free: wl1271_free_hw(wl); diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c index 0132dad756c4..df5a00f103ea 100644 --- a/drivers/net/wireless/wl12xx/spi.c +++ b/drivers/net/wireless/wl12xx/spi.c @@ -320,28 +320,23 @@ static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf, spi_sync(wl_to_spi(wl), &m); } -static irqreturn_t wl1271_irq(int irq, void *cookie) +static irqreturn_t wl1271_hardirq(int irq, void *cookie) { - struct wl1271 *wl; + struct wl1271 *wl = cookie; unsigned long flags; wl1271_debug(DEBUG_IRQ, "IRQ"); - wl = cookie; - /* complete the ELP completion */ spin_lock_irqsave(&wl->wl_lock, flags); + set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); if (wl->elp_compl) { complete(wl->elp_compl); wl->elp_compl = NULL; } - - if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) - ieee80211_queue_work(wl->hw, &wl->irq_work); - set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); spin_unlock_irqrestore(&wl->wl_lock, flags); - return IRQ_HANDLED; + return IRQ_WAKE_THREAD; } static int wl1271_spi_set_power(struct wl1271 *wl, bool enable) @@ -413,14 +408,14 @@ static int __devinit wl1271_probe(struct spi_device *spi) goto out_free; } - ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); + ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, + IRQF_TRIGGER_RISING, + DRIVER_NAME, wl); if (ret < 0) { wl1271_error("request_irq() failed: %d", ret); goto out_free; } - set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); - disable_irq(wl->irq); ret = wl1271_init_ieee80211(wl); diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 455954edf83e..5e9ef7d53e7e 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -464,7 +464,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl) while ((skb = wl1271_skb_dequeue(wl))) { if (!woken_up) { - ret = wl1271_ps_elp_wakeup(wl, false); + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out_ack; woken_up = true; @@ -589,7 +589,8 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, result->rate_class_index, result->status); /* return the packet to the stack */ - ieee80211_tx_status(wl->hw, skb); + skb_queue_tail(&wl->deferred_tx_queue, skb); + ieee80211_queue_work(wl->hw, &wl->netstack_work); wl1271_free_tx_id(wl, result->id); } diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index ea1eee7895cf..e395c0c4ebbd 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -320,7 +320,6 @@ enum wl12xx_flags { WL1271_FLAG_IN_ELP, WL1271_FLAG_PSM, WL1271_FLAG_PSM_REQUESTED, - WL1271_FLAG_IRQ_PENDING, WL1271_FLAG_IRQ_RUNNING, WL1271_FLAG_IDLE, WL1271_FLAG_IDLE_REQUESTED, @@ -404,6 +403,12 @@ struct wl1271 { struct sk_buff_head tx_queue[NUM_TX_QUEUES]; int tx_queue_count; + /* Frames received, not handled yet by mac80211 */ + struct sk_buff_head deferred_rx_queue; + + /* Frames sent, not returned yet to mac80211 */ + struct sk_buff_head deferred_tx_queue; + struct work_struct tx_work; /* Pending TX frames */ @@ -424,8 +429,8 @@ struct wl1271 { /* Intermediate buffer, used for packet aggregation */ u8 *aggr_buf; - /* The target interrupt mask */ - struct work_struct irq_work; + /* Network stack work */ + struct work_struct netstack_work; /* Hardware recovery work */ struct work_struct recovery_work; @@ -556,6 +561,8 @@ int wl1271_plt_stop(struct wl1271 *wl); #define WL1271_TX_QUEUE_LOW_WATERMARK 10 #define WL1271_TX_QUEUE_HIGH_WATERMARK 25 +#define WL1271_DEFERRED_QUEUE_LIMIT 64 + /* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power on in case is has been shut down shortly before */ #define WL1271_PRE_POWER_ON_SLEEP 20 /* in milliseconds */ -- cgit v1.2.3 From 2da69b890f47852dc368136375f49a5d24e2d9a1 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Tue, 1 Mar 2011 15:14:42 +0200 Subject: wl12xx: Switch to level trigger interrupts The interrupt of the wl12xx is a level interrupt in nature, since the interrupt line is not auto-reset. However, since resetting the interrupt requires bus transactions, this cannot be done from an interrupt context. Thus, requesting a level interrupt would require to disable the irq and re-enable it after the HW is acknowledged. Since we now request a threaded irq, this can also be done by specifying the IRQF_ONESHOT flag. Triggering on an edge can be problematic in some platforms, if the sampling frequency is not sufficient for detecting very frequent interrupts. In case an interrupt is missed, the driver will hang as the interrupt line will stay high until it is acknowledged by the driver, which will never happen. Fix this by requesting a level triggered interrupt, with the IRQF_ONESHOT flag. Signed-off-by: Ido Yariv Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/sdio.c | 2 +- drivers/net/wireless/wl12xx/spi.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index b66abb5ebcf3..5b9dbeafec06 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -241,7 +241,7 @@ static int __devinit wl1271_probe(struct sdio_func *func, wl->ref_clock = wlan_data->board_ref_clock; ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, - IRQF_TRIGGER_RISING, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, DRIVER_NAME, wl); if (ret < 0) { wl1271_error("request_irq() failed: %d", ret); diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c index df5a00f103ea..18cf01719ae0 100644 --- a/drivers/net/wireless/wl12xx/spi.c +++ b/drivers/net/wireless/wl12xx/spi.c @@ -409,7 +409,7 @@ static int __devinit wl1271_probe(struct spi_device *spi) } ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, - IRQF_TRIGGER_RISING, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, DRIVER_NAME, wl); if (ret < 0) { wl1271_error("request_irq() failed: %d", ret); -- cgit v1.2.3 From b07d4037051318d47c055384ef887535a0ed2d1e Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Tue, 1 Mar 2011 15:14:43 +0200 Subject: wl12xx: Avoid redundant TX work TX might be handled in the threaded IRQ handler, in which case, TX work might be scheduled just to discover it has nothing to do. Save a few context switches by cancelling redundant TX work in case TX is about to be handled in the threaded IRQ handler. Also, avoid scheduling TX work from wl1271_op_tx if not needed. Signed-off-by: Ido Yariv Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 32 +++++++++++++++++++++++++++----- drivers/net/wireless/wl12xx/wl12xx.h | 1 + 2 files changed, 28 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index f408c5a84cc9..2679abcf5a05 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -668,6 +668,11 @@ irqreturn_t wl1271_irq(int irq, void *cookie) struct wl1271 *wl = (struct wl1271 *)cookie; bool done = false; unsigned int defer_count; + unsigned long flags; + + /* TX might be handled here, avoid redundant work */ + set_bit(WL1271_FLAG_TX_PENDING, &wl->flags); + cancel_work_sync(&wl->tx_work); mutex_lock(&wl->mutex); @@ -712,13 +717,17 @@ irqreturn_t wl1271_irq(int irq, void *cookie) wl1271_rx(wl, &wl->fw_status->common); /* Check if any tx blocks were freed */ + spin_lock_irqsave(&wl->wl_lock, flags); if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && wl->tx_queue_count) { + spin_unlock_irqrestore(&wl->wl_lock, flags); /* * In order to avoid starvation of the TX path, * call the work function directly. */ wl1271_tx_work_locked(wl); + } else { + spin_unlock_irqrestore(&wl->wl_lock, flags); } /* check for tx results */ @@ -754,6 +763,14 @@ irqreturn_t wl1271_irq(int irq, void *cookie) wl1271_ps_elp_sleep(wl); out: + spin_lock_irqsave(&wl->wl_lock, flags); + /* In case TX was not handled here, queue TX work */ + clear_bit(WL1271_FLAG_TX_PENDING, &wl->flags); + if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && + wl->tx_queue_count) + ieee80211_queue_work(wl->hw, &wl->tx_work); + spin_unlock_irqrestore(&wl->wl_lock, flags); + mutex_unlock(&wl->mutex); return IRQ_HANDLED; @@ -1068,7 +1085,13 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) int q; u8 hlid = 0; + q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); + + if (wl->bss_type == BSS_TYPE_AP_BSS) + hlid = wl1271_tx_get_hlid(skb); + spin_lock_irqsave(&wl->wl_lock, flags); + wl->tx_queue_count++; /* @@ -1081,12 +1104,8 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); } - spin_unlock_irqrestore(&wl->wl_lock, flags); - /* queue the packet */ - q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); if (wl->bss_type == BSS_TYPE_AP_BSS) { - hlid = wl1271_tx_get_hlid(skb); wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d", hlid, q); skb_queue_tail(&wl->links[hlid].tx_queue[q], skb); } else { @@ -1098,8 +1117,11 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * before that, the tx_work will not be initialized! */ - if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags)) + if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && + !test_bit(WL1271_FLAG_TX_PENDING, &wl->flags)) ieee80211_queue_work(wl->hw, &wl->tx_work); + + spin_unlock_irqrestore(&wl->wl_lock, flags); } static struct notifier_block wl1271_dev_notifier = { diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index e395c0c4ebbd..86be83e25ec5 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -317,6 +317,7 @@ enum wl12xx_flags { WL1271_FLAG_JOINED, WL1271_FLAG_GPIO_POWER, WL1271_FLAG_TX_QUEUE_STOPPED, + WL1271_FLAG_TX_PENDING, WL1271_FLAG_IN_ELP, WL1271_FLAG_PSM, WL1271_FLAG_PSM_REQUESTED, -- cgit v1.2.3 From b16d4b6864e5bd7e5a6e5987f896003175235bca Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Tue, 1 Mar 2011 15:14:44 +0200 Subject: wl12xx: Modify requested number of memory blocks Tests have shown that the requested number of memory blocks is sub-optimal. Slightly modify the requested number of memory blocks for TX. Signed-off-by: Ido Yariv Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 2679abcf5a05..8b3c8d196b03 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -304,7 +304,7 @@ static struct conf_drv_settings default_conf = { .rx_block_num = 70, .tx_min_block_num = 40, .dynamic_memory = 0, - .min_req_tx_blocks = 104, + .min_req_tx_blocks = 100, .min_req_rx_blocks = 22, .tx_min = 27, } -- cgit v1.2.3 From 24225b37bd78d3e2edaa1a39316c54786adaa465 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 1 Mar 2011 12:27:26 +0200 Subject: wl12xx: wakeup chip from ELP during scan Commands are sometimes sent to FW on scan completion. Make sure the chip is awake to receive them. Sending commands while the chip is in ELP can cause SDIO read errors and/or crash the FW. Signed-off-by: Arik Nemtsov Signed-off-by: Ido Yariv Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/cmd.c | 1 + drivers/net/wireless/wl12xx/scan.c | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 97ffd7aa57a8..f0aa7ab97bf7 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -63,6 +63,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, cmd->status = 0; WARN_ON(len % 4 != 0); + WARN_ON(test_bit(WL1271_FLAG_IN_ELP, &wl->flags)); wl1271_write(wl, wl->cmd_box_addr, buf, len, false); diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index 6f897b9d90ca..420653a2859c 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c @@ -27,6 +27,7 @@ #include "cmd.h" #include "scan.h" #include "acx.h" +#include "ps.h" void wl1271_scan_complete_work(struct work_struct *work) { @@ -40,10 +41,11 @@ void wl1271_scan_complete_work(struct work_struct *work) mutex_lock(&wl->mutex); - if (wl->scan.state == WL1271_SCAN_STATE_IDLE) { - mutex_unlock(&wl->mutex); - return; - } + if (wl->state == WL1271_STATE_OFF) + goto out; + + if (wl->scan.state == WL1271_SCAN_STATE_IDLE) + goto out; wl->scan.state = WL1271_SCAN_STATE_IDLE; kfree(wl->scan.scanned_ch); @@ -52,13 +54,19 @@ void wl1271_scan_complete_work(struct work_struct *work) ieee80211_scan_completed(wl->hw, false); /* restore hardware connection monitoring template */ - if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) - wl1271_cmd_build_ap_probe_req(wl, wl->probereq); + if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) { + if (wl1271_ps_elp_wakeup(wl) == 0) { + wl1271_cmd_build_ap_probe_req(wl, wl->probereq); + wl1271_ps_elp_sleep(wl); + } + } if (wl->scan.failed) { wl1271_info("Scan completed due to error."); ieee80211_queue_work(wl->hw, &wl->recovery_work); } + +out: mutex_unlock(&wl->mutex); } -- cgit v1.2.3 From 95a776107a131823c87147dff083696d8814c1b3 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Wed, 2 Mar 2011 10:46:46 +0100 Subject: wl12xx: Correctly set up protection if non-GF STAs are present Set the gf_protection bit when calling ACX_HT_BSS_OPERATION according to the GF bit passed by mac80211 in ht_operation_mode. [Added a proper commit message -- Luca] Signed-off-by: Helmut Schaa Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index 3badc6bb7866..a3db755ceeda 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -1361,7 +1361,8 @@ int wl1271_acx_set_ht_information(struct wl1271 *wl, acx->ht_protection = (u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION); acx->rifs_mode = 0; - acx->gf_protection = 0; + acx->gf_protection = + !!(ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); acx->ht_tx_burst_limit = 0; acx->dual_cts_protection = 0; -- cgit v1.2.3 From fea41cc9b1af5f65fecf4013ad62284e6ae3a78c Mon Sep 17 00:00:00 2001 From: "Fry, Donald H" Date: Fri, 25 Feb 2011 09:43:20 -0800 Subject: iwlagn: Support new 1000 microcode. iwlagn: Support new 1000 microcode. New iwlwifi-1000 microcode requires driver support for API version 5. (There is no version 4) Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index ba78bc8a259f..507cab45f15b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -49,7 +49,7 @@ #include "iwl-agn-debugfs.h" /* Highest firmware API version supported */ -#define IWL1000_UCODE_API_MAX 3 +#define IWL1000_UCODE_API_MAX 5 #define IWL100_UCODE_API_MAX 5 /* Lowest firmware API version supported */ -- cgit v1.2.3 From 6eaa412f2753d98566b777836a98c6e7f672a3bb Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 18 Jan 2011 20:09:41 -0500 Subject: xen: Mark all initial reserved pages for the balloon as INVALID_P2M_ENTRY. With this patch, we diligently set regions that will be used by the balloon driver to be INVALID_P2M_ENTRY and under the ownership of the balloon driver. We are OK using the __set_phys_to_machine as we do not expect to be allocating any P2M middle or entries pages. The set_phys_to_machine has the side-effect of potentially allocating new pages and we do not want that at this stage. We can do this because xen_build_mfn_list_list will have already allocated all such pages up to xen_max_p2m_pfn. We also move the check for auto translated physmap down the stack so it is present in __set_phys_to_machine. [v2: Rebased with mmu->p2m code split] Reviewed-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/include/asm/xen/page.h | 1 + arch/x86/xen/mmu.c | 2 +- arch/x86/xen/p2m.c | 9 ++++----- arch/x86/xen/setup.c | 7 ++++++- drivers/xen/balloon.c | 2 +- 5 files changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h index f25bdf238a33..8ea977277c55 100644 --- a/arch/x86/include/asm/xen/page.h +++ b/arch/x86/include/asm/xen/page.h @@ -41,6 +41,7 @@ extern unsigned int machine_to_phys_order; extern unsigned long get_phys_to_machine(unsigned long pfn); extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn); +extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); extern int m2p_add_override(unsigned long mfn, struct page *page); extern int m2p_remove_override(struct page *page); diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 5e92b61ad574..0180ae88307b 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -2074,7 +2074,7 @@ static void xen_zap_pfn_range(unsigned long vaddr, unsigned int order, in_frames[i] = virt_to_mfn(vaddr); MULTI_update_va_mapping(mcs.mc, vaddr, VOID_PTE, 0); - set_phys_to_machine(virt_to_pfn(vaddr), INVALID_P2M_ENTRY); + __set_phys_to_machine(virt_to_pfn(vaddr), INVALID_P2M_ENTRY); if (out_frames) out_frames[i] = virt_to_pfn(vaddr); diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index ddc81a06edb9..df4e36775339 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c @@ -365,6 +365,10 @@ bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn) { unsigned topidx, mididx, idx; + if (unlikely(xen_feature(XENFEAT_auto_translated_physmap))) { + BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY); + return true; + } if (unlikely(pfn >= MAX_P2M_PFN)) { BUG_ON(mfn != INVALID_P2M_ENTRY); return true; @@ -384,11 +388,6 @@ bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn) bool set_phys_to_machine(unsigned long pfn, unsigned long mfn) { - if (unlikely(xen_feature(XENFEAT_auto_translated_physmap))) { - BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY); - return true; - } - if (unlikely(!__set_phys_to_machine(pfn, mfn))) { if (!alloc_p2m(pfn)) return false; diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index b5a7f928234b..7201800e55a4 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -52,6 +52,8 @@ phys_addr_t xen_extra_mem_start, xen_extra_mem_size; static __init void xen_add_extra_mem(unsigned long pages) { + unsigned long pfn; + u64 size = (u64)pages * PAGE_SIZE; u64 extra_start = xen_extra_mem_start + xen_extra_mem_size; @@ -66,6 +68,9 @@ static __init void xen_add_extra_mem(unsigned long pages) xen_extra_mem_size += size; xen_max_p2m_pfn = PFN_DOWN(extra_start + size); + + for (pfn = PFN_DOWN(extra_start); pfn <= xen_max_p2m_pfn; pfn++) + __set_phys_to_machine(pfn, INVALID_P2M_ENTRY); } static unsigned long __init xen_release_chunk(phys_addr_t start_addr, @@ -104,7 +109,7 @@ static unsigned long __init xen_release_chunk(phys_addr_t start_addr, WARN(ret != 1, "Failed to release memory %lx-%lx err=%d\n", start, end, ret); if (ret == 1) { - set_phys_to_machine(pfn, INVALID_P2M_ENTRY); + __set_phys_to_machine(pfn, INVALID_P2M_ENTRY); len++; } } diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 43f9f02c7db0..b1661cd416b0 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -296,7 +296,7 @@ static int decrease_reservation(unsigned long nr_pages) /* No more mappings: invalidate P2M and add to balloon. */ for (i = 0; i < nr_pages; i++) { pfn = mfn_to_pfn(frame_list[i]); - set_phys_to_machine(pfn, INVALID_P2M_ENTRY); + __set_phys_to_machine(pfn, INVALID_P2M_ENTRY); balloon_append(pfn_to_page(pfn)); } -- cgit v1.2.3 From fd51469fb68b987032e46297e0a4fe9020063c20 Mon Sep 17 00:00:00 2001 From: Petr Uzel Date: Thu, 3 Mar 2011 11:48:50 -0500 Subject: block: kill loop_mutex Following steps lead to deadlock in kernel: dd if=/dev/zero of=img bs=512 count=1000 losetup -f img mkfs.ext2 /dev/loop0 mount -t ext2 -o loop /dev/loop0 mnt umount mnt/ Stacktrace: [] irq_exit+0x36/0x59 [] smp_apic_timer_interrupt+0x6b/0x75 [] apic_timer_interrupt+0x31/0x38 [] mutex_spin_on_owner+0x54/0x5b [] lo_release+0x12/0x67 [loop] [] __blkdev_put+0x7c/0x10c [] fput+0xd5/0x1aa [] loop_clr_fd+0x1a9/0x1b1 [loop] [] lo_release+0x39/0x67 [loop] [] __blkdev_put+0x7c/0x10c [] deactivate_locked_super+0x17/0x36 [] sys_umount+0x27e/0x2a5 [] sys_oldumount+0xb/0xe [] sysenter_do_call+0x12/0x26 [] 0xffffffff Regression since 2a48fc0ab24241755dc9, which introduced the private loop_mutex as part of the BKL removal process. As per [1], the mutex can be safely removed. [1] http://www.gossamer-threads.com/lists/linux/kernel/1341930 Addresses: https://bugzilla.novell.com/show_bug.cgi?id=669394 Addresses: https://bugzilla.kernel.org/show_bug.cgi?id=29172 Signed-off-by: Petr Uzel Cc: stable@kernel.org Reviewed-by: Nikanth Karthikesan Acked-by: Arnd Bergmann Signed-off-by: Jens Axboe --- drivers/block/loop.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 49e6a545eb63..dbf31ec9114d 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -78,7 +78,6 @@ #include -static DEFINE_MUTEX(loop_mutex); static LIST_HEAD(loop_devices); static DEFINE_MUTEX(loop_devices_mutex); @@ -1501,11 +1500,9 @@ static int lo_open(struct block_device *bdev, fmode_t mode) { struct loop_device *lo = bdev->bd_disk->private_data; - mutex_lock(&loop_mutex); mutex_lock(&lo->lo_ctl_mutex); lo->lo_refcnt++; mutex_unlock(&lo->lo_ctl_mutex); - mutex_unlock(&loop_mutex); return 0; } @@ -1515,7 +1512,6 @@ static int lo_release(struct gendisk *disk, fmode_t mode) struct loop_device *lo = disk->private_data; int err; - mutex_lock(&loop_mutex); mutex_lock(&lo->lo_ctl_mutex); if (--lo->lo_refcnt) @@ -1540,7 +1536,6 @@ static int lo_release(struct gendisk *disk, fmode_t mode) out: mutex_unlock(&lo->lo_ctl_mutex); out_unlocked: - mutex_unlock(&loop_mutex); return 0; } -- cgit v1.2.3 From 0c0db0355bc070b4c623622248d3f577642536b9 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 3 Mar 2011 17:56:05 +0100 Subject: [S390] xpram: remove __initdata attribute from module parameters The module parameter 'devs' and 'sizes' are marked as __initdata. The memory for the parameters are freed after module_init completed. This can lead to kernel crashes in param_free_charp. Remove the __initdata attribute to fix the problem. Signed-off-by: Martin Schwidefsky --- drivers/s390/block/xpram.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index c881a14fa5dd..1f6a4d894e73 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c @@ -62,8 +62,8 @@ static int xpram_devs; /* * Parameter parsing functions. */ -static int __initdata devs = XPRAM_DEVS; -static char __initdata *sizes[XPRAM_MAX_DEVS]; +static int devs = XPRAM_DEVS; +static char *sizes[XPRAM_MAX_DEVS]; module_param(devs, int, 0); module_param_array(sizes, charp, NULL, 0); -- cgit v1.2.3 From b652277b09d3d030cb074cc6a98ba80b34244c03 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 3 Mar 2011 17:56:06 +0100 Subject: [S390] keyboard: integer underflow bug The "ct" variable should be an unsigned int. Both struct kbdiacrs ->kb_cnt and struct kbd_data ->accent_table_size are unsigned ints. Making it signed causes a problem in KBDIACRUC because the user could set the signed bit and cause a buffer overflow. Cc: Signed-off-by: Dan Carpenter Signed-off-by: Martin Schwidefsky --- drivers/s390/char/keyboard.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c index 8cd58e412b5e..5ad44daef73b 100644 --- a/drivers/s390/char/keyboard.c +++ b/drivers/s390/char/keyboard.c @@ -460,7 +460,8 @@ kbd_ioctl(struct kbd_data *kbd, struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp; - int ct, perm; + unsigned int ct; + int perm; argp = (void __user *)arg; -- cgit v1.2.3 From 0c2bd9b24e73287aa4ee87844c847205e0da8a9b Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 3 Mar 2011 17:56:07 +0100 Subject: [S390] tape: deadlock on system work queue The 34xx and 3590 tape driver uses the system work queue to defer work from the interrupt function to process context, e.g. a medium sense after an unsolicited interrupt. The tape commands started by the work handler need to be asynchronous, otherwise a deadlock on the system work queue can occur. Signed-off-by: Martin Schwidefsky --- drivers/s390/char/tape.h | 8 +++++ drivers/s390/char/tape_34xx.c | 59 ++++++++++++++++++++---------- drivers/s390/char/tape_3590.c | 83 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 116 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index 7a242f073632..267b54e8ff5a 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h @@ -280,6 +280,14 @@ tape_do_io_free(struct tape_device *device, struct tape_request *request) return rc; } +static inline void +tape_do_io_async_free(struct tape_device *device, struct tape_request *request) +{ + request->callback = (void *) tape_free_request; + request->callback_data = NULL; + tape_do_io_async(device, request); +} + extern int tape_oper_handler(int irq, int status); extern void tape_noper_handler(int irq, int status); extern int tape_open(struct tape_device *); diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index c17f35b6136a..c26511171ffe 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c @@ -53,23 +53,11 @@ static void tape_34xx_delete_sbid_from(struct tape_device *, int); * Medium sense for 34xx tapes. There is no 'real' medium sense call. * So we just do a normal sense. */ -static int -tape_34xx_medium_sense(struct tape_device *device) +static void __tape_34xx_medium_sense(struct tape_request *request) { - struct tape_request *request; - unsigned char *sense; - int rc; - - request = tape_alloc_request(1, 32); - if (IS_ERR(request)) { - DBF_EXCEPTION(6, "MSEN fail\n"); - return PTR_ERR(request); - } - - request->op = TO_MSEN; - tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata); + struct tape_device *device = request->device; + unsigned char *sense; - rc = tape_do_io_interruptible(device, request); if (request->rc == 0) { sense = request->cpdata; @@ -88,15 +76,47 @@ tape_34xx_medium_sense(struct tape_device *device) device->tape_generic_status |= GMT_WR_PROT(~0); else device->tape_generic_status &= ~GMT_WR_PROT(~0); - } else { + } else DBF_EVENT(4, "tape_34xx: medium sense failed with rc=%d\n", request->rc); - } tape_free_request(request); +} + +static int tape_34xx_medium_sense(struct tape_device *device) +{ + struct tape_request *request; + int rc; + + request = tape_alloc_request(1, 32); + if (IS_ERR(request)) { + DBF_EXCEPTION(6, "MSEN fail\n"); + return PTR_ERR(request); + } + request->op = TO_MSEN; + tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata); + rc = tape_do_io_interruptible(device, request); + __tape_34xx_medium_sense(request); return rc; } +static void tape_34xx_medium_sense_async(struct tape_device *device) +{ + struct tape_request *request; + + request = tape_alloc_request(1, 32); + if (IS_ERR(request)) { + DBF_EXCEPTION(6, "MSEN fail\n"); + return; + } + + request->op = TO_MSEN; + tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata); + request->callback = (void *) __tape_34xx_medium_sense; + request->callback_data = NULL; + tape_do_io_async(device, request); +} + struct tape_34xx_work { struct tape_device *device; enum tape_op op; @@ -109,6 +129,9 @@ struct tape_34xx_work { * is inserted but cannot call tape_do_io* from an interrupt context. * Maybe that's useful for other actions we want to start from the * interrupt handler. + * Note: the work handler is called by the system work queue. The tape + * commands started by the handler need to be asynchrounous, otherwise + * a deadlock can occur e.g. in case of a deferred cc=1 (see __tape_do_irq). */ static void tape_34xx_work_handler(struct work_struct *work) @@ -119,7 +142,7 @@ tape_34xx_work_handler(struct work_struct *work) switch(p->op) { case TO_MSEN: - tape_34xx_medium_sense(device); + tape_34xx_medium_sense_async(device); break; default: DBF_EVENT(3, "T34XX: internal error: unknown work\n"); diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index fbe361fcd2c0..de2e99e0a71b 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c @@ -329,17 +329,17 @@ out: /* * Enable encryption */ -static int tape_3592_enable_crypt(struct tape_device *device) +static struct tape_request *__tape_3592_enable_crypt(struct tape_device *device) { struct tape_request *request; char *data; DBF_EVENT(6, "tape_3592_enable_crypt\n"); if (!crypt_supported(device)) - return -ENOSYS; + return ERR_PTR(-ENOSYS); request = tape_alloc_request(2, 72); if (IS_ERR(request)) - return PTR_ERR(request); + return request; data = request->cpdata; memset(data,0,72); @@ -354,23 +354,42 @@ static int tape_3592_enable_crypt(struct tape_device *device) request->op = TO_CRYPT_ON; tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data); tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36); + return request; +} + +static int tape_3592_enable_crypt(struct tape_device *device) +{ + struct tape_request *request; + + request = __tape_3592_enable_crypt(device); + if (IS_ERR(request)) + return PTR_ERR(request); return tape_do_io_free(device, request); } +static void tape_3592_enable_crypt_async(struct tape_device *device) +{ + struct tape_request *request; + + request = __tape_3592_enable_crypt(device); + if (!IS_ERR(request)) + tape_do_io_async_free(device, request); +} + /* * Disable encryption */ -static int tape_3592_disable_crypt(struct tape_device *device) +static struct tape_request *__tape_3592_disable_crypt(struct tape_device *device) { struct tape_request *request; char *data; DBF_EVENT(6, "tape_3592_disable_crypt\n"); if (!crypt_supported(device)) - return -ENOSYS; + return ERR_PTR(-ENOSYS); request = tape_alloc_request(2, 72); if (IS_ERR(request)) - return PTR_ERR(request); + return request; data = request->cpdata; memset(data,0,72); @@ -383,9 +402,28 @@ static int tape_3592_disable_crypt(struct tape_device *device) tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data); tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36); + return request; +} + +static int tape_3592_disable_crypt(struct tape_device *device) +{ + struct tape_request *request; + + request = __tape_3592_disable_crypt(device); + if (IS_ERR(request)) + return PTR_ERR(request); return tape_do_io_free(device, request); } +static void tape_3592_disable_crypt_async(struct tape_device *device) +{ + struct tape_request *request; + + request = __tape_3592_disable_crypt(device); + if (!IS_ERR(request)) + tape_do_io_async_free(device, request); +} + /* * IOCTL: Set encryption status */ @@ -457,8 +495,7 @@ tape_3590_ioctl(struct tape_device *device, unsigned int cmd, unsigned long arg) /* * SENSE Medium: Get Sense data about medium state */ -static int -tape_3590_sense_medium(struct tape_device *device) +static int tape_3590_sense_medium(struct tape_device *device) { struct tape_request *request; @@ -470,6 +507,18 @@ tape_3590_sense_medium(struct tape_device *device) return tape_do_io_free(device, request); } +static void tape_3590_sense_medium_async(struct tape_device *device) +{ + struct tape_request *request; + + request = tape_alloc_request(1, 128); + if (IS_ERR(request)) + return; + request->op = TO_MSEN; + tape_ccw_end(request->cpaddr, MEDIUM_SENSE, 128, request->cpdata); + tape_do_io_async_free(device, request); +} + /* * MTTELL: Tell block. Return the number of block relative to current file. */ @@ -546,15 +595,14 @@ tape_3590_read_opposite(struct tape_device *device, * 2. The attention msg is written to the "read subsystem data" buffer. * In this case we probably should print it to the console. */ -static int -tape_3590_read_attmsg(struct tape_device *device) +static void tape_3590_read_attmsg_async(struct tape_device *device) { struct tape_request *request; char *buf; request = tape_alloc_request(3, 4096); if (IS_ERR(request)) - return PTR_ERR(request); + return; request->op = TO_READ_ATTMSG; buf = request->cpdata; buf[0] = PREP_RD_SS_DATA; @@ -562,12 +610,15 @@ tape_3590_read_attmsg(struct tape_device *device) tape_ccw_cc(request->cpaddr, PERFORM_SS_FUNC, 12, buf); tape_ccw_cc(request->cpaddr + 1, READ_SS_DATA, 4096 - 12, buf + 12); tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL); - return tape_do_io_free(device, request); + tape_do_io_async_free(device, request); } /* * These functions are used to schedule follow-up actions from within an * interrupt context (like unsolicited interrupts). + * Note: the work handler is called by the system work queue. The tape + * commands started by the handler need to be asynchrounous, otherwise + * a deadlock can occur e.g. in case of a deferred cc=1 (see __tape_do_irq). */ struct work_handler_data { struct tape_device *device; @@ -583,16 +634,16 @@ tape_3590_work_handler(struct work_struct *work) switch (p->op) { case TO_MSEN: - tape_3590_sense_medium(p->device); + tape_3590_sense_medium_async(p->device); break; case TO_READ_ATTMSG: - tape_3590_read_attmsg(p->device); + tape_3590_read_attmsg_async(p->device); break; case TO_CRYPT_ON: - tape_3592_enable_crypt(p->device); + tape_3592_enable_crypt_async(p->device); break; case TO_CRYPT_OFF: - tape_3592_disable_crypt(p->device); + tape_3592_disable_crypt_async(p->device); break; default: DBF_EVENT(3, "T3590: work handler undefined for " -- cgit v1.2.3 From cbf6aa89fc52c5253ee141d53eeb73147eb37ac0 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 11 Jan 2011 17:20:14 +0000 Subject: xen:events: move find_unbound_irq inside CONFIG_PCI_MSI The only caller is xen_allocate_pirq_msi which is also under this ifdef so this fixes: drivers/xen/events.c:377: warning: 'find_unbound_pirq' defined but not used when CONFIG_PCI_MSI=n Signed-off-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk Cc: Stefano Stabellini Cc: Jeremy Fitzhardinge --- drivers/xen/events.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 74681478100a..1ae775742325 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -387,23 +387,6 @@ static int get_nr_hw_irqs(void) return ret; } -static int find_unbound_pirq(int type) -{ - int rc, i; - struct physdev_get_free_pirq op_get_free_pirq; - op_get_free_pirq.type = type; - - rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_free_pirq, &op_get_free_pirq); - if (!rc) - return op_get_free_pirq.pirq; - - for (i = 0; i < nr_irqs; i++) { - if (pirq_to_irq[i] < 0) - return i; - } - return -1; -} - static int find_unbound_irq(void) { struct irq_data *data; @@ -677,6 +660,23 @@ out: #include #include "../pci/msi.h" +static int find_unbound_pirq(int type) +{ + int rc, i; + struct physdev_get_free_pirq op_get_free_pirq; + op_get_free_pirq.type = type; + + rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_free_pirq, &op_get_free_pirq); + if (!rc) + return op_get_free_pirq.pirq; + + for (i = 0; i < nr_irqs; i++) { + if (pirq_to_irq[i] < 0) + return i; + } + return -1; +} + void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc) { spin_lock(&irq_mapping_update_lock); -- cgit v1.2.3 From c9df1ce585e3bb5a2f101c1d87381b285a9f962f Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 11 Jan 2011 17:20:15 +0000 Subject: xen: events: add xen_allocate_irq_{dynamic, gsi} and xen_free_irq This is neater than open-coded calls to irq_alloc_desc_at and irq_free_desc. No intended behavioural change. Note that we previously were not checking the return value of irq_alloc_desc_at which would be failing for GSI Signed-off-by: Konrad Rzeszutek Wilk Cc: Stefano Stabellini Cc: Jeremy Fitzhardinge --- drivers/xen/events.c | 53 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 1ae775742325..81a53eb6cd1d 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -387,7 +387,7 @@ static int get_nr_hw_irqs(void) return ret; } -static int find_unbound_irq(void) +static int xen_allocate_irq_dynamic(void) { struct irq_data *data; int irq, res; @@ -436,6 +436,30 @@ static bool identity_mapped_irq(unsigned irq) return irq < get_nr_hw_irqs(); } +static int xen_allocate_irq_gsi(unsigned gsi) +{ + int irq; + + if (!identity_mapped_irq(gsi) && + (xen_initial_domain() || !xen_pv_domain())) + return xen_allocate_irq_dynamic(); + + /* Legacy IRQ descriptors are already allocated by the arch. */ + if (gsi < NR_IRQS_LEGACY) + return gsi; + + irq = irq_alloc_desc_at(gsi, -1); + if (irq < 0) + panic("Unable to allocate to IRQ%d (%d)\n", gsi, irq); + + return irq; +} + +static void xen_free_irq(unsigned irq) +{ + irq_free_desc(irq); +} + static void pirq_unmask_notify(int irq) { struct physdev_eoi eoi = { .irq = pirq_from_irq(irq) }; @@ -621,14 +645,7 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name) goto out; /* XXX need refcount? */ } - /* If we are a PV guest, we don't have GSIs (no ACPI passed). Therefore - * we are using the !xen_initial_domain() to drop in the function.*/ - if (identity_mapped_irq(gsi) || (!xen_initial_domain() && - xen_pv_domain())) { - irq = gsi; - irq_alloc_desc_at(irq, -1); - } else - irq = find_unbound_irq(); + irq = xen_allocate_irq_gsi(gsi); set_irq_chip_and_handler_name(irq, &xen_pirq_chip, handle_level_irq, name); @@ -641,7 +658,7 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name) * this in the priv domain. */ if (xen_initial_domain() && HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op)) { - irq_free_desc(irq); + xen_free_irq(irq); irq = -ENOSPC; goto out; } @@ -682,7 +699,7 @@ void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc) spin_lock(&irq_mapping_update_lock); if (alloc & XEN_ALLOC_IRQ) { - *irq = find_unbound_irq(); + *irq = xen_allocate_irq_dynamic(); if (*irq == -1) goto out; } @@ -732,7 +749,7 @@ int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type) spin_lock(&irq_mapping_update_lock); - irq = find_unbound_irq(); + irq = xen_allocate_irq_dynamic(); if (irq == -1) goto out; @@ -741,7 +758,7 @@ int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type) if (rc) { printk(KERN_WARNING "xen map irq failed %d\n", rc); - irq_free_desc(irq); + xen_free_irq(irq); irq = -1; goto out; @@ -783,7 +800,7 @@ int xen_destroy_irq(int irq) } irq_info[irq] = mk_unbound_info(); - irq_free_desc(irq); + xen_free_irq(irq); out: spin_unlock(&irq_mapping_update_lock); @@ -814,7 +831,7 @@ int bind_evtchn_to_irq(unsigned int evtchn) irq = evtchn_to_irq[evtchn]; if (irq == -1) { - irq = find_unbound_irq(); + irq = xen_allocate_irq_dynamic(); set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, handle_fasteoi_irq, "event"); @@ -839,7 +856,7 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu) irq = per_cpu(ipi_to_irq, cpu)[ipi]; if (irq == -1) { - irq = find_unbound_irq(); + irq = xen_allocate_irq_dynamic(); if (irq < 0) goto out; @@ -875,7 +892,7 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu) irq = per_cpu(virq_to_irq, cpu)[virq]; if (irq == -1) { - irq = find_unbound_irq(); + irq = xen_allocate_irq_dynamic(); set_irq_chip_and_handler_name(irq, &xen_percpu_chip, handle_percpu_irq, "virq"); @@ -934,7 +951,7 @@ static void unbind_from_irq(unsigned int irq) if (irq_info[irq].type != IRQT_UNBOUND) { irq_info[irq] = mk_unbound_info(); - irq_free_desc(irq); + xen_free_irq(irq); } spin_unlock(&irq_mapping_update_lock); -- cgit v1.2.3 From 89911501f3aae44a43984793341a3bf1f4c583c2 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 3 Mar 2011 11:57:44 -0500 Subject: xen: events: allocate GSIs and dynamic IRQs from separate IRQ ranges. There are three cases which we need to care about, PV guest, PV domain 0 and HVM guest. The PV guest case is simple since it has no access to ACPI or real APICs and therefore has no GSIs therefore we simply dynamically allocate all IRQs. The potentially interesting case here is PIRQ type event channels associated with passed through PCI devices. However even in this case the guest has no direct interaction with the physical GSI since that happens in the PCI backend. The PV domain 0 and HVM guest cases are actually the same. In domain 0 case the kernel sees the host ACPI and GSIs (although it only sees the APIC indirectly via the hypervisor) and in the HVM guest case it sees the virtualised ACPI and emulated APICs. In these cases we start allocating dynamic IRQs at nr_irqs_gsi so that they cannot clash with any GSI. Currently xen_allocate_irq_dynamic starts at nr_irqs and works backwards looking for a free IRQ in order to (try and) avoid clashing with GSIs used in domain 0 and in HVM guests. This change avoids that although we retain the behaviour of allowing dynamic IRQs to encroach on the GSI range if no suitable IRQs are available since a future IRQ clash is deemed preferable to failure right now. Signed-off-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk Cc: Stefano Stabellini Cc: Jeremy Fitzhardinge --- drivers/xen/events.c | 77 ++++++++++++++++++---------------------------------- 1 file changed, 27 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 81a53eb6cd1d..06f2e61de691 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -376,72 +376,49 @@ static void unmask_evtchn(int port) put_cpu(); } -static int get_nr_hw_irqs(void) +static int xen_allocate_irq_dynamic(void) { - int ret = 1; + int first = 0; + int irq; #ifdef CONFIG_X86_IO_APIC - ret = get_nr_irqs_gsi(); + /* + * For an HVM guest or domain 0 which see "real" (emulated or + * actual repectively) GSIs we allocate dynamic IRQs + * e.g. those corresponding to event channels or MSIs + * etc. from the range above those "real" GSIs to avoid + * collisions. + */ + if (xen_initial_domain() || xen_hvm_domain()) + first = get_nr_irqs_gsi(); #endif - return ret; -} +retry: + irq = irq_alloc_desc_from(first, -1); -static int xen_allocate_irq_dynamic(void) -{ - struct irq_data *data; - int irq, res; - int bottom = get_nr_hw_irqs(); - int top = nr_irqs-1; - - if (bottom == nr_irqs) - goto no_irqs; - - /* This loop starts from the top of IRQ space and goes down. - * We need this b/c if we have a PCI device in a Xen PV guest - * we do not have an IO-APIC (though the backend might have them) - * mapped in. To not have a collision of physical IRQs with the Xen - * event channels start at the top of the IRQ space for virtual IRQs. - */ - for (irq = top; irq > bottom; irq--) { - data = irq_get_irq_data(irq); - /* only 15->0 have init'd desc; handle irq > 16 */ - if (!data) - break; - if (data->chip == &no_irq_chip) - break; - if (data->chip != &xen_dynamic_chip) - continue; - if (irq_info[irq].type == IRQT_UNBOUND) - return irq; + if (irq == -ENOMEM && first > NR_IRQS_LEGACY) { + printk(KERN_ERR "Out of dynamic IRQ space and eating into GSI space. You should increase nr_irqs\n"); + first = max(NR_IRQS_LEGACY, first - NR_IRQS_LEGACY); + goto retry; } - if (irq == bottom) - goto no_irqs; - - res = irq_alloc_desc_at(irq, -1); - - if (WARN_ON(res != irq)) - return -1; + if (irq < 0) + panic("No available IRQ to bind to: increase nr_irqs!\n"); return irq; - -no_irqs: - panic("No available IRQ to bind to: increase nr_irqs!\n"); -} - -static bool identity_mapped_irq(unsigned irq) -{ - /* identity map all the hardware irqs */ - return irq < get_nr_hw_irqs(); } static int xen_allocate_irq_gsi(unsigned gsi) { int irq; - if (!identity_mapped_irq(gsi) && - (xen_initial_domain() || !xen_pv_domain())) + /* + * A PV guest has no concept of a GSI (since it has no ACPI + * nor access to/knowledge of the physical APICs). Therefore + * all IRQs are dynamically allocated from the entire IRQ + * space. + */ + if (xen_pv_domain() && !xen_initial_domain()) return xen_allocate_irq_dynamic(); /* Legacy IRQ descriptors are already allocated by the arch. */ -- cgit v1.2.3 From 7214610475b2847a81478d96e4d3ba0bbe49598c Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 3 Feb 2011 09:49:35 +0000 Subject: xen: events: do not free legacy IRQs c514d00c8057 "xen: events: add xen_allocate_irq_{dynamic, gsi} and xen_free_irq" correctly avoids reallocating legacy IRQs (which are managed by the arch core) but erroneously did not prevent them being freed. Signed-off-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/events.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 06f2e61de691..accb37ad0944 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -434,6 +434,10 @@ static int xen_allocate_irq_gsi(unsigned gsi) static void xen_free_irq(unsigned irq) { + /* Legacy IRQ descriptors are managed by the arch. */ + if (irq < NR_IRQS_LEGACY) + return; + irq_free_desc(irq); } -- cgit v1.2.3 From 149f256f8ca690c28dd8aa9fb8bcdaf2e93b1e1c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 5 Feb 2011 20:08:52 +0000 Subject: xen: Remove stale irq_chip.end irq_chip.end got obsolete with the removal of __do_IRQ() Signed-off-by: Thomas Gleixner Acked-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/events.c | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index accb37ad0944..c8826b5142c4 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -555,23 +555,6 @@ static void ack_pirq(unsigned int irq) } } -static void end_pirq(unsigned int irq) -{ - int evtchn = evtchn_from_irq(irq); - struct irq_desc *desc = irq_to_desc(irq); - - if (WARN_ON(!desc)) - return; - - if ((desc->status & (IRQ_DISABLED|IRQ_PENDING)) == - (IRQ_DISABLED|IRQ_PENDING)) { - shutdown_pirq(irq); - } else if (VALID_EVTCHN(evtchn)) { - unmask_evtchn(evtchn); - pirq_unmask_notify(irq); - } -} - static int find_irq_by_gsi(unsigned gsi) { int irq; @@ -1508,7 +1491,6 @@ static struct irq_chip xen_pirq_chip __read_mostly = { .mask = disable_pirq, .ack = ack_pirq, - .end = end_pirq, .set_affinity = set_affinity_irq, -- cgit v1.2.3 From c9e265e030537167c94cbed190826f02e3887f4d Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 5 Feb 2011 20:08:54 +0000 Subject: xen: Switch to new irq_chip functions Convert Xen to the new irq_chip functions. Brings us closer to enable CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED Signed-off-by: Thomas Gleixner Acked-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/events.c | 95 ++++++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index c8826b5142c4..cf1712fb1c46 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -277,7 +277,7 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) BUG_ON(irq == -1); #ifdef CONFIG_SMP - cpumask_copy(irq_to_desc(irq)->affinity, cpumask_of(cpu)); + cpumask_copy(irq_to_desc(irq)->irq_data.affinity, cpumask_of(cpu)); #endif clear_bit(chn, cpu_evtchn_mask(cpu_from_irq(irq))); @@ -294,7 +294,7 @@ static void init_evtchn_cpu_bindings(void) /* By default all event channels notify CPU#0. */ for_each_irq_desc(i, desc) { - cpumask_copy(desc->affinity, cpumask_of(0)); + cpumask_copy(desc->irq_data.affinity, cpumask_of(0)); } #endif @@ -474,7 +474,7 @@ static bool probing_irq(int irq) return desc && desc->action == NULL; } -static unsigned int startup_pirq(unsigned int irq) +static unsigned int __startup_pirq(unsigned int irq) { struct evtchn_bind_pirq bind_pirq; struct irq_info *info = info_for_irq(irq); @@ -512,9 +512,15 @@ out: return 0; } -static void shutdown_pirq(unsigned int irq) +static unsigned int startup_pirq(struct irq_data *data) +{ + return __startup_pirq(data->irq); +} + +static void shutdown_pirq(struct irq_data *data) { struct evtchn_close close; + unsigned int irq = data->irq; struct irq_info *info = info_for_irq(irq); int evtchn = evtchn_from_irq(irq); @@ -534,20 +540,20 @@ static void shutdown_pirq(unsigned int irq) info->evtchn = 0; } -static void enable_pirq(unsigned int irq) +static void enable_pirq(struct irq_data *data) { - startup_pirq(irq); + startup_pirq(data); } -static void disable_pirq(unsigned int irq) +static void disable_pirq(struct irq_data *data) { } -static void ack_pirq(unsigned int irq) +static void ack_pirq(struct irq_data *data) { - int evtchn = evtchn_from_irq(irq); + int evtchn = evtchn_from_irq(data->irq); - move_native_irq(irq); + irq_move_irq(data); if (VALID_EVTCHN(evtchn)) { mask_evtchn(evtchn); @@ -1215,11 +1221,12 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) return 0; } -static int set_affinity_irq(unsigned irq, const struct cpumask *dest) +static int set_affinity_irq(struct irq_data *data, const struct cpumask *dest, + bool force) { unsigned tcpu = cpumask_first(dest); - return rebind_irq_to_cpu(irq, tcpu); + return rebind_irq_to_cpu(data->irq, tcpu); } int resend_irq_on_evtchn(unsigned int irq) @@ -1238,35 +1245,35 @@ int resend_irq_on_evtchn(unsigned int irq) return 1; } -static void enable_dynirq(unsigned int irq) +static void enable_dynirq(struct irq_data *data) { - int evtchn = evtchn_from_irq(irq); + int evtchn = evtchn_from_irq(data->irq); if (VALID_EVTCHN(evtchn)) unmask_evtchn(evtchn); } -static void disable_dynirq(unsigned int irq) +static void disable_dynirq(struct irq_data *data) { - int evtchn = evtchn_from_irq(irq); + int evtchn = evtchn_from_irq(data->irq); if (VALID_EVTCHN(evtchn)) mask_evtchn(evtchn); } -static void ack_dynirq(unsigned int irq) +static void ack_dynirq(struct irq_data *data) { - int evtchn = evtchn_from_irq(irq); + int evtchn = evtchn_from_irq(data->irq); - move_masked_irq(irq); + move_masked_irq(data->irq); if (VALID_EVTCHN(evtchn)) unmask_evtchn(evtchn); } -static int retrigger_dynirq(unsigned int irq) +static int retrigger_dynirq(struct irq_data *data) { - int evtchn = evtchn_from_irq(irq); + int evtchn = evtchn_from_irq(data->irq); struct shared_info *sh = HYPERVISOR_shared_info; int ret = 0; @@ -1315,7 +1322,7 @@ static void restore_cpu_pirqs(void) printk(KERN_DEBUG "xen: --> irq=%d, pirq=%d\n", irq, map_irq.pirq); - startup_pirq(irq); + __startup_pirq(irq); } } @@ -1467,44 +1474,44 @@ void xen_irq_resume(void) } static struct irq_chip xen_dynamic_chip __read_mostly = { - .name = "xen-dyn", + .name = "xen-dyn", - .disable = disable_dynirq, - .mask = disable_dynirq, - .unmask = enable_dynirq, + .irq_disable = disable_dynirq, + .irq_mask = disable_dynirq, + .irq_unmask = enable_dynirq, - .eoi = ack_dynirq, - .set_affinity = set_affinity_irq, - .retrigger = retrigger_dynirq, + .irq_eoi = ack_dynirq, + .irq_set_affinity = set_affinity_irq, + .irq_retrigger = retrigger_dynirq, }; static struct irq_chip xen_pirq_chip __read_mostly = { - .name = "xen-pirq", + .name = "xen-pirq", - .startup = startup_pirq, - .shutdown = shutdown_pirq, + .irq_startup = startup_pirq, + .irq_shutdown = shutdown_pirq, - .enable = enable_pirq, - .unmask = enable_pirq, + .irq_enable = enable_pirq, + .irq_unmask = enable_pirq, - .disable = disable_pirq, - .mask = disable_pirq, + .irq_disable = disable_pirq, + .irq_mask = disable_pirq, - .ack = ack_pirq, + .irq_ack = ack_pirq, - .set_affinity = set_affinity_irq, + .irq_set_affinity = set_affinity_irq, - .retrigger = retrigger_dynirq, + .irq_retrigger = retrigger_dynirq, }; static struct irq_chip xen_percpu_chip __read_mostly = { - .name = "xen-percpu", + .name = "xen-percpu", - .disable = disable_dynirq, - .mask = disable_dynirq, - .unmask = enable_dynirq, + .irq_disable = disable_dynirq, + .irq_mask = disable_dynirq, + .irq_unmask = enable_dynirq, - .ack = ack_dynirq, + .irq_ack = ack_dynirq, }; int xen_set_callback_via(uint64_t via) -- cgit v1.2.3 From aa673c1cb3a66d0b37595251c4e8bb688efc8726 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Mon, 7 Feb 2011 11:08:39 +0000 Subject: xen: Fix compile error introduced by "switch to new irq_chip functions" drivers/xen/events.c: In function 'ack_pirq': drivers/xen/events.c:568: error: implicit declaration of function 'irq_move_irq' Signed-off-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index cf1712fb1c46..5aa422a3c3cd 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -553,7 +553,7 @@ static void ack_pirq(struct irq_data *data) { int evtchn = evtchn_from_irq(data->irq); - irq_move_irq(data); + move_native_irq(data->irq); if (VALID_EVTCHN(evtchn)) { mask_evtchn(evtchn); -- cgit v1.2.3 From 676dc3cf5bc36a9e129a3ad8fe3bd7b2ebf20f5d Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 5 Feb 2011 20:08:59 +0000 Subject: xen: Use IRQF_FORCE_RESUME Mark the IRQF_NO_SUSPEND interrupts IRQF_FORCE_RESUME and remove the extra walk through the interrupt descriptors. Signed-off-by: Thomas Gleixner Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/events.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 5aa422a3c3cd..975e90fa6d5a 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -977,7 +977,7 @@ int bind_ipi_to_irqhandler(enum ipi_vector ipi, if (irq < 0) return irq; - irqflags |= IRQF_NO_SUSPEND; + irqflags |= IRQF_NO_SUSPEND | IRQF_FORCE_RESUME; retval = request_irq(irq, handler, irqflags, devname, dev_id); if (retval != 0) { unbind_from_irq(irq); @@ -1433,7 +1433,6 @@ void xen_poll_irq(int irq) void xen_irq_resume(void) { unsigned int cpu, irq, evtchn; - struct irq_desc *desc; init_evtchn_cpu_bindings(); @@ -1453,23 +1452,6 @@ void xen_irq_resume(void) restore_cpu_ipis(cpu); } - /* - * Unmask any IRQF_NO_SUSPEND IRQs which are enabled. These - * are not handled by the IRQ core. - */ - for_each_irq_desc(irq, desc) { - if (!desc->action || !(desc->action->flags & IRQF_NO_SUSPEND)) - continue; - if (desc->status & IRQ_DISABLED) - continue; - - evtchn = evtchn_from_irq(irq); - if (evtchn == -1) - continue; - - unmask_evtchn(evtchn); - } - restore_cpu_pirqs(); } -- cgit v1.2.3 From 1aa0b51a033d4a1ec6d29d06487e053398afa21b Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Thu, 17 Feb 2011 11:23:58 -0500 Subject: xen/irq: Cleanup up the pirq_to_irq for DomU PV PCI passthrough guests as well. We only did this for PV guests that are xen_initial_domain() but there is not reason not to do this for other cases. The other case is only exercised when you pass in a PCI device to a PV guest _and_ the device in question. Reviewed-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/events.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 975e90fa6d5a..89987a7bf26f 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -766,8 +766,9 @@ int xen_destroy_irq(int irq) printk(KERN_WARNING "unmap irq failed %d\n", rc); goto out; } - pirq_to_irq[info->u.pirq.pirq] = -1; } + pirq_to_irq[info->u.pirq.pirq] = -1; + irq_info[irq] = mk_unbound_info(); xen_free_irq(irq); -- cgit v1.2.3 From f8f79a5dbeb59a13a3f8101b24cbe19ec6e92d07 Mon Sep 17 00:00:00 2001 From: "Fry, Donald H" Date: Fri, 25 Feb 2011 09:44:48 -0800 Subject: iwlagn: report correct temperature for WiFi/BT devices. The temperature reported by 'cat /sys/class/net/wlan?/device/temperature' is incorrect for devices with BT capability. Report the value from the correct statistics structure. Tested with 130, 100, 6205 and 5300. Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index fd142bee9189..87a9fd8e41eb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -533,9 +533,10 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) void iwlagn_temperature(struct iwl_priv *priv) { - /* store temperature from statistics (in Celsius) */ - priv->temperature = - le32_to_cpu(priv->_agn.statistics.general.common.temperature); + /* store temperature from correct statistics (in Celsius) */ + priv->temperature = le32_to_cpu((iwl_bt_statistics(priv)) ? + priv->_agn.statistics_bt.general.common.temperature : + priv->_agn.statistics.general.common.temperature); iwl_tt_handler(priv); } -- cgit v1.2.3 From ba04c7c93bbcb48ce880cf75b6e9dffcd79d4c7b Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 22 Feb 2011 02:00:11 +0000 Subject: r8169: disable ASPM For some time is known that ASPM is causing troubles on r8169, i.e. make device randomly stop working without any errors in dmesg. Currently Tomi Leppikangas reports that system with r8169 device hangs with MCE errors when ASPM is enabled: https://bugzilla.redhat.com/show_bug.cgi?id=642861#c4 Lets disable ASPM for r8169 devices at all, to avoid problems with r8169 PCIe devices at least for some users. Reported-by: Tomi Leppikangas Cc: stable@kernel.org Signed-off-by: Stanislaw Gruszka Signed-off-by: David S. Miller --- drivers/net/r8169.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index ef2133b16f8c..7ffdb80adf40 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -3020,6 +3021,11 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) mii->reg_num_mask = 0x1f; mii->supports_gmii = !!(cfg->features & RTL_FEATURE_GMII); + /* disable ASPM completely as that cause random device stop working + * problems as well as full system hangs for some PCIe devices users */ + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | + PCIE_LINK_STATE_CLKPM); + /* enable device (incl. PCI PM wakeup and hotplug setup) */ rc = pci_enable_device(pdev); if (rc < 0) { -- cgit v1.2.3 From 8d77c036b57cf813d838f859e11b6a188acdb1fb Mon Sep 17 00:00:00 2001 From: Po-Yu Chuang Date: Mon, 28 Feb 2011 20:48:49 +0000 Subject: net: add Faraday FTMAC100 10/100 Ethernet driver FTMAC100 Ethernet Media Access Controller supports 10/100 Mbps and MII. This driver has been working on some ARM/NDS32 SoC's including Faraday A320 and Andes AG101. Signed-off-by: Po-Yu Chuang Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/Kconfig | 9 + drivers/net/Makefile | 1 + drivers/net/ftmac100.c | 1196 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/ftmac100.h | 180 ++++++++ 4 files changed, 1386 insertions(+) create mode 100644 drivers/net/ftmac100.c create mode 100644 drivers/net/ftmac100.h (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 6e09d5fea221..fba89ae2926b 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2008,6 +2008,15 @@ config BCM63XX_ENET This driver supports the ethernet MACs in the Broadcom 63xx MIPS chipset family (BCM63XX). +config FTMAC100 + tristate "Faraday FTMAC100 10/100 Ethernet support" + depends on ARM + select MII + help + This driver supports the FTMAC100 10/100 Ethernet controller + from Faraday. It is used on Faraday A320, Andes AG101 and some + other ARM/NDS32 SoC's. + source "drivers/net/fs_enet/Kconfig" source "drivers/net/octeon/Kconfig" diff --git a/drivers/net/Makefile b/drivers/net/Makefile index b90738d13994..7c2171179f97 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -147,6 +147,7 @@ obj-$(CONFIG_FORCEDETH) += forcedeth.o obj-$(CONFIG_NE_H8300) += ne-h8300.o 8390.o obj-$(CONFIG_AX88796) += ax88796.o obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o +obj-$(CONFIG_FTMAC100) += ftmac100.o obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o diff --git a/drivers/net/ftmac100.c b/drivers/net/ftmac100.c new file mode 100644 index 000000000000..df70368bf317 --- /dev/null +++ b/drivers/net/ftmac100.c @@ -0,0 +1,1196 @@ +/* + * Faraday FTMAC100 10/100 Ethernet + * + * (C) Copyright 2009-2011 Faraday Technology + * Po-Yu Chuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ftmac100.h" + +#define DRV_NAME "ftmac100" +#define DRV_VERSION "0.2" + +#define RX_QUEUE_ENTRIES 128 /* must be power of 2 */ +#define TX_QUEUE_ENTRIES 16 /* must be power of 2 */ + +#define MAX_PKT_SIZE 1518 +#define RX_BUF_SIZE 2044 /* must be smaller than 0x7ff */ + +#if MAX_PKT_SIZE > 0x7ff +#error invalid MAX_PKT_SIZE +#endif + +#if RX_BUF_SIZE > 0x7ff || RX_BUF_SIZE > PAGE_SIZE +#error invalid RX_BUF_SIZE +#endif + +/****************************************************************************** + * private data + *****************************************************************************/ +struct ftmac100_descs { + struct ftmac100_rxdes rxdes[RX_QUEUE_ENTRIES]; + struct ftmac100_txdes txdes[TX_QUEUE_ENTRIES]; +}; + +struct ftmac100 { + struct resource *res; + void __iomem *base; + int irq; + + struct ftmac100_descs *descs; + dma_addr_t descs_dma_addr; + + unsigned int rx_pointer; + unsigned int tx_clean_pointer; + unsigned int tx_pointer; + unsigned int tx_pending; + + spinlock_t tx_lock; + + struct net_device *netdev; + struct device *dev; + struct napi_struct napi; + + struct mii_if_info mii; +}; + +static int ftmac100_alloc_rx_page(struct ftmac100 *priv, struct ftmac100_rxdes *rxdes); + +/****************************************************************************** + * internal functions (hardware register access) + *****************************************************************************/ +#define INT_MASK_ALL_ENABLED (FTMAC100_INT_RPKT_FINISH | \ + FTMAC100_INT_NORXBUF | \ + FTMAC100_INT_XPKT_OK | \ + FTMAC100_INT_XPKT_LOST | \ + FTMAC100_INT_RPKT_LOST | \ + FTMAC100_INT_AHB_ERR | \ + FTMAC100_INT_PHYSTS_CHG) + +#define INT_MASK_ALL_DISABLED 0 + +static void ftmac100_enable_all_int(struct ftmac100 *priv) +{ + iowrite32(INT_MASK_ALL_ENABLED, priv->base + FTMAC100_OFFSET_IMR); +} + +static void ftmac100_disable_all_int(struct ftmac100 *priv) +{ + iowrite32(INT_MASK_ALL_DISABLED, priv->base + FTMAC100_OFFSET_IMR); +} + +static void ftmac100_set_rx_ring_base(struct ftmac100 *priv, dma_addr_t addr) +{ + iowrite32(addr, priv->base + FTMAC100_OFFSET_RXR_BADR); +} + +static void ftmac100_set_tx_ring_base(struct ftmac100 *priv, dma_addr_t addr) +{ + iowrite32(addr, priv->base + FTMAC100_OFFSET_TXR_BADR); +} + +static void ftmac100_txdma_start_polling(struct ftmac100 *priv) +{ + iowrite32(1, priv->base + FTMAC100_OFFSET_TXPD); +} + +static int ftmac100_reset(struct ftmac100 *priv) +{ + struct net_device *netdev = priv->netdev; + int i; + + /* NOTE: reset clears all registers */ + iowrite32(FTMAC100_MACCR_SW_RST, priv->base + FTMAC100_OFFSET_MACCR); + + for (i = 0; i < 5; i++) { + unsigned int maccr; + + maccr = ioread32(priv->base + FTMAC100_OFFSET_MACCR); + if (!(maccr & FTMAC100_MACCR_SW_RST)) { + /* + * FTMAC100_MACCR_SW_RST cleared does not indicate + * that hardware reset completed (what the f*ck). + * We still need to wait for a while. + */ + usleep_range(500, 1000); + return 0; + } + + usleep_range(1000, 10000); + } + + netdev_err(netdev, "software reset failed\n"); + return -EIO; +} + +static void ftmac100_set_mac(struct ftmac100 *priv, const unsigned char *mac) +{ + unsigned int maddr = mac[0] << 8 | mac[1]; + unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5]; + + iowrite32(maddr, priv->base + FTMAC100_OFFSET_MAC_MADR); + iowrite32(laddr, priv->base + FTMAC100_OFFSET_MAC_LADR); +} + +#define MACCR_ENABLE_ALL (FTMAC100_MACCR_XMT_EN | \ + FTMAC100_MACCR_RCV_EN | \ + FTMAC100_MACCR_XDMA_EN | \ + FTMAC100_MACCR_RDMA_EN | \ + FTMAC100_MACCR_CRC_APD | \ + FTMAC100_MACCR_FULLDUP | \ + FTMAC100_MACCR_RX_RUNT | \ + FTMAC100_MACCR_RX_BROADPKT) + +static int ftmac100_start_hw(struct ftmac100 *priv) +{ + struct net_device *netdev = priv->netdev; + + if (ftmac100_reset(priv)) + return -EIO; + + /* setup ring buffer base registers */ + ftmac100_set_rx_ring_base(priv, + priv->descs_dma_addr + + offsetof(struct ftmac100_descs, rxdes)); + ftmac100_set_tx_ring_base(priv, + priv->descs_dma_addr + + offsetof(struct ftmac100_descs, txdes)); + + iowrite32(FTMAC100_APTC_RXPOLL_CNT(1), priv->base + FTMAC100_OFFSET_APTC); + + ftmac100_set_mac(priv, netdev->dev_addr); + + iowrite32(MACCR_ENABLE_ALL, priv->base + FTMAC100_OFFSET_MACCR); + return 0; +} + +static void ftmac100_stop_hw(struct ftmac100 *priv) +{ + iowrite32(0, priv->base + FTMAC100_OFFSET_MACCR); +} + +/****************************************************************************** + * internal functions (receive descriptor) + *****************************************************************************/ +static bool ftmac100_rxdes_first_segment(struct ftmac100_rxdes *rxdes) +{ + return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_FRS); +} + +static bool ftmac100_rxdes_last_segment(struct ftmac100_rxdes *rxdes) +{ + return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_LRS); +} + +static bool ftmac100_rxdes_owned_by_dma(struct ftmac100_rxdes *rxdes) +{ + return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RXDMA_OWN); +} + +static void ftmac100_rxdes_set_dma_own(struct ftmac100_rxdes *rxdes) +{ + /* clear status bits */ + rxdes->rxdes0 = cpu_to_le32(FTMAC100_RXDES0_RXDMA_OWN); +} + +static bool ftmac100_rxdes_rx_error(struct ftmac100_rxdes *rxdes) +{ + return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RX_ERR); +} + +static bool ftmac100_rxdes_crc_error(struct ftmac100_rxdes *rxdes) +{ + return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_CRC_ERR); +} + +static bool ftmac100_rxdes_frame_too_long(struct ftmac100_rxdes *rxdes) +{ + return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_FTL); +} + +static bool ftmac100_rxdes_runt(struct ftmac100_rxdes *rxdes) +{ + return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RUNT); +} + +static bool ftmac100_rxdes_odd_nibble(struct ftmac100_rxdes *rxdes) +{ + return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RX_ODD_NB); +} + +static unsigned int ftmac100_rxdes_frame_length(struct ftmac100_rxdes *rxdes) +{ + return le32_to_cpu(rxdes->rxdes0) & FTMAC100_RXDES0_RFL; +} + +static bool ftmac100_rxdes_multicast(struct ftmac100_rxdes *rxdes) +{ + return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_MULTICAST); +} + +static void ftmac100_rxdes_set_buffer_size(struct ftmac100_rxdes *rxdes, + unsigned int size) +{ + rxdes->rxdes1 &= cpu_to_le32(FTMAC100_RXDES1_EDORR); + rxdes->rxdes1 |= cpu_to_le32(FTMAC100_RXDES1_RXBUF_SIZE(size)); +} + +static void ftmac100_rxdes_set_end_of_ring(struct ftmac100_rxdes *rxdes) +{ + rxdes->rxdes1 |= cpu_to_le32(FTMAC100_RXDES1_EDORR); +} + +static void ftmac100_rxdes_set_dma_addr(struct ftmac100_rxdes *rxdes, + dma_addr_t addr) +{ + rxdes->rxdes2 = cpu_to_le32(addr); +} + +static dma_addr_t ftmac100_rxdes_get_dma_addr(struct ftmac100_rxdes *rxdes) +{ + return le32_to_cpu(rxdes->rxdes2); +} + +/* + * rxdes3 is not used by hardware. We use it to keep track of page. + * Since hardware does not touch it, we can skip cpu_to_le32()/le32_to_cpu(). + */ +static void ftmac100_rxdes_set_page(struct ftmac100_rxdes *rxdes, struct page *page) +{ + rxdes->rxdes3 = (unsigned int)page; +} + +static struct page *ftmac100_rxdes_get_page(struct ftmac100_rxdes *rxdes) +{ + return (struct page *)rxdes->rxdes3; +} + +/****************************************************************************** + * internal functions (receive) + *****************************************************************************/ +static int ftmac100_next_rx_pointer(int pointer) +{ + return (pointer + 1) & (RX_QUEUE_ENTRIES - 1); +} + +static void ftmac100_rx_pointer_advance(struct ftmac100 *priv) +{ + priv->rx_pointer = ftmac100_next_rx_pointer(priv->rx_pointer); +} + +static struct ftmac100_rxdes *ftmac100_current_rxdes(struct ftmac100 *priv) +{ + return &priv->descs->rxdes[priv->rx_pointer]; +} + +static struct ftmac100_rxdes * +ftmac100_rx_locate_first_segment(struct ftmac100 *priv) +{ + struct ftmac100_rxdes *rxdes = ftmac100_current_rxdes(priv); + + while (!ftmac100_rxdes_owned_by_dma(rxdes)) { + if (ftmac100_rxdes_first_segment(rxdes)) + return rxdes; + + ftmac100_rxdes_set_dma_own(rxdes); + ftmac100_rx_pointer_advance(priv); + rxdes = ftmac100_current_rxdes(priv); + } + + return NULL; +} + +static bool ftmac100_rx_packet_error(struct ftmac100 *priv, + struct ftmac100_rxdes *rxdes) +{ + struct net_device *netdev = priv->netdev; + bool error = false; + + if (unlikely(ftmac100_rxdes_rx_error(rxdes))) { + if (net_ratelimit()) + netdev_info(netdev, "rx err\n"); + + netdev->stats.rx_errors++; + error = true; + } + + if (unlikely(ftmac100_rxdes_crc_error(rxdes))) { + if (net_ratelimit()) + netdev_info(netdev, "rx crc err\n"); + + netdev->stats.rx_crc_errors++; + error = true; + } + + if (unlikely(ftmac100_rxdes_frame_too_long(rxdes))) { + if (net_ratelimit()) + netdev_info(netdev, "rx frame too long\n"); + + netdev->stats.rx_length_errors++; + error = true; + } else if (unlikely(ftmac100_rxdes_runt(rxdes))) { + if (net_ratelimit()) + netdev_info(netdev, "rx runt\n"); + + netdev->stats.rx_length_errors++; + error = true; + } else if (unlikely(ftmac100_rxdes_odd_nibble(rxdes))) { + if (net_ratelimit()) + netdev_info(netdev, "rx odd nibble\n"); + + netdev->stats.rx_length_errors++; + error = true; + } + + return error; +} + +static void ftmac100_rx_drop_packet(struct ftmac100 *priv) +{ + struct net_device *netdev = priv->netdev; + struct ftmac100_rxdes *rxdes = ftmac100_current_rxdes(priv); + bool done = false; + + if (net_ratelimit()) + netdev_dbg(netdev, "drop packet %p\n", rxdes); + + do { + if (ftmac100_rxdes_last_segment(rxdes)) + done = true; + + ftmac100_rxdes_set_dma_own(rxdes); + ftmac100_rx_pointer_advance(priv); + rxdes = ftmac100_current_rxdes(priv); + } while (!done && !ftmac100_rxdes_owned_by_dma(rxdes)); + + netdev->stats.rx_dropped++; +} + +static bool ftmac100_rx_packet(struct ftmac100 *priv, int *processed) +{ + struct net_device *netdev = priv->netdev; + struct ftmac100_rxdes *rxdes; + struct sk_buff *skb; + struct page *page; + dma_addr_t map; + int length; + + rxdes = ftmac100_rx_locate_first_segment(priv); + if (!rxdes) + return false; + + if (unlikely(ftmac100_rx_packet_error(priv, rxdes))) { + ftmac100_rx_drop_packet(priv); + return true; + } + + /* + * It is impossible to get multi-segment packets + * because we always provide big enough receive buffers. + */ + if (unlikely(!ftmac100_rxdes_last_segment(rxdes))) + BUG(); + + /* start processing */ + skb = netdev_alloc_skb_ip_align(netdev, 128); + if (unlikely(!skb)) { + if (net_ratelimit()) + netdev_err(netdev, "rx skb alloc failed\n"); + + ftmac100_rx_drop_packet(priv); + return true; + } + + if (unlikely(ftmac100_rxdes_multicast(rxdes))) + netdev->stats.multicast++; + + map = ftmac100_rxdes_get_dma_addr(rxdes); + dma_unmap_page(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE); + + length = ftmac100_rxdes_frame_length(rxdes); + page = ftmac100_rxdes_get_page(rxdes); + skb_fill_page_desc(skb, 0, page, 0, length); + skb->len += length; + skb->data_len += length; + skb->truesize += length; + __pskb_pull_tail(skb, min(length, 64)); + + ftmac100_alloc_rx_page(priv, rxdes); + + ftmac100_rx_pointer_advance(priv); + + skb->protocol = eth_type_trans(skb, netdev); + + netdev->stats.rx_packets++; + netdev->stats.rx_bytes += skb->len; + + /* push packet to protocol stack */ + netif_receive_skb(skb); + + (*processed)++; + return true; +} + +/****************************************************************************** + * internal functions (transmit descriptor) + *****************************************************************************/ +static void ftmac100_txdes_reset(struct ftmac100_txdes *txdes) +{ + /* clear all except end of ring bit */ + txdes->txdes0 = 0; + txdes->txdes1 &= cpu_to_le32(FTMAC100_TXDES1_EDOTR); + txdes->txdes2 = 0; + txdes->txdes3 = 0; +} + +static bool ftmac100_txdes_owned_by_dma(struct ftmac100_txdes *txdes) +{ + return txdes->txdes0 & cpu_to_le32(FTMAC100_TXDES0_TXDMA_OWN); +} + +static void ftmac100_txdes_set_dma_own(struct ftmac100_txdes *txdes) +{ + /* + * Make sure dma own bit will not be set before any other + * descriptor fields. + */ + wmb(); + txdes->txdes0 |= cpu_to_le32(FTMAC100_TXDES0_TXDMA_OWN); +} + +static bool ftmac100_txdes_excessive_collision(struct ftmac100_txdes *txdes) +{ + return txdes->txdes0 & cpu_to_le32(FTMAC100_TXDES0_TXPKT_EXSCOL); +} + +static bool ftmac100_txdes_late_collision(struct ftmac100_txdes *txdes) +{ + return txdes->txdes0 & cpu_to_le32(FTMAC100_TXDES0_TXPKT_LATECOL); +} + +static void ftmac100_txdes_set_end_of_ring(struct ftmac100_txdes *txdes) +{ + txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_EDOTR); +} + +static void ftmac100_txdes_set_first_segment(struct ftmac100_txdes *txdes) +{ + txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_FTS); +} + +static void ftmac100_txdes_set_last_segment(struct ftmac100_txdes *txdes) +{ + txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_LTS); +} + +static void ftmac100_txdes_set_txint(struct ftmac100_txdes *txdes) +{ + txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_TXIC); +} + +static void ftmac100_txdes_set_buffer_size(struct ftmac100_txdes *txdes, + unsigned int len) +{ + txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_TXBUF_SIZE(len)); +} + +static void ftmac100_txdes_set_dma_addr(struct ftmac100_txdes *txdes, + dma_addr_t addr) +{ + txdes->txdes2 = cpu_to_le32(addr); +} + +static dma_addr_t ftmac100_txdes_get_dma_addr(struct ftmac100_txdes *txdes) +{ + return le32_to_cpu(txdes->txdes2); +} + +/* + * txdes3 is not used by hardware. We use it to keep track of socket buffer. + * Since hardware does not touch it, we can skip cpu_to_le32()/le32_to_cpu(). + */ +static void ftmac100_txdes_set_skb(struct ftmac100_txdes *txdes, struct sk_buff *skb) +{ + txdes->txdes3 = (unsigned int)skb; +} + +static struct sk_buff *ftmac100_txdes_get_skb(struct ftmac100_txdes *txdes) +{ + return (struct sk_buff *)txdes->txdes3; +} + +/****************************************************************************** + * internal functions (transmit) + *****************************************************************************/ +static int ftmac100_next_tx_pointer(int pointer) +{ + return (pointer + 1) & (TX_QUEUE_ENTRIES - 1); +} + +static void ftmac100_tx_pointer_advance(struct ftmac100 *priv) +{ + priv->tx_pointer = ftmac100_next_tx_pointer(priv->tx_pointer); +} + +static void ftmac100_tx_clean_pointer_advance(struct ftmac100 *priv) +{ + priv->tx_clean_pointer = ftmac100_next_tx_pointer(priv->tx_clean_pointer); +} + +static struct ftmac100_txdes *ftmac100_current_txdes(struct ftmac100 *priv) +{ + return &priv->descs->txdes[priv->tx_pointer]; +} + +static struct ftmac100_txdes *ftmac100_current_clean_txdes(struct ftmac100 *priv) +{ + return &priv->descs->txdes[priv->tx_clean_pointer]; +} + +static bool ftmac100_tx_complete_packet(struct ftmac100 *priv) +{ + struct net_device *netdev = priv->netdev; + struct ftmac100_txdes *txdes; + struct sk_buff *skb; + dma_addr_t map; + + if (priv->tx_pending == 0) + return false; + + txdes = ftmac100_current_clean_txdes(priv); + + if (ftmac100_txdes_owned_by_dma(txdes)) + return false; + + skb = ftmac100_txdes_get_skb(txdes); + map = ftmac100_txdes_get_dma_addr(txdes); + + if (unlikely(ftmac100_txdes_excessive_collision(txdes) || + ftmac100_txdes_late_collision(txdes))) { + /* + * packet transmitted to ethernet lost due to late collision + * or excessive collision + */ + netdev->stats.tx_aborted_errors++; + } else { + netdev->stats.tx_packets++; + netdev->stats.tx_bytes += skb->len; + } + + dma_unmap_single(priv->dev, map, skb_headlen(skb), DMA_TO_DEVICE); + dev_kfree_skb(skb); + + ftmac100_txdes_reset(txdes); + + ftmac100_tx_clean_pointer_advance(priv); + + spin_lock(&priv->tx_lock); + priv->tx_pending--; + spin_unlock(&priv->tx_lock); + netif_wake_queue(netdev); + + return true; +} + +static void ftmac100_tx_complete(struct ftmac100 *priv) +{ + while (ftmac100_tx_complete_packet(priv)) + ; +} + +static int ftmac100_xmit(struct ftmac100 *priv, struct sk_buff *skb, + dma_addr_t map) +{ + struct net_device *netdev = priv->netdev; + struct ftmac100_txdes *txdes; + unsigned int len = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len; + + txdes = ftmac100_current_txdes(priv); + ftmac100_tx_pointer_advance(priv); + + /* setup TX descriptor */ + ftmac100_txdes_set_skb(txdes, skb); + ftmac100_txdes_set_dma_addr(txdes, map); + + ftmac100_txdes_set_first_segment(txdes); + ftmac100_txdes_set_last_segment(txdes); + ftmac100_txdes_set_txint(txdes); + ftmac100_txdes_set_buffer_size(txdes, len); + + spin_lock(&priv->tx_lock); + priv->tx_pending++; + if (priv->tx_pending == TX_QUEUE_ENTRIES) + netif_stop_queue(netdev); + + /* start transmit */ + ftmac100_txdes_set_dma_own(txdes); + spin_unlock(&priv->tx_lock); + + ftmac100_txdma_start_polling(priv); + return NETDEV_TX_OK; +} + +/****************************************************************************** + * internal functions (buffer) + *****************************************************************************/ +static int ftmac100_alloc_rx_page(struct ftmac100 *priv, struct ftmac100_rxdes *rxdes) +{ + struct net_device *netdev = priv->netdev; + struct page *page; + dma_addr_t map; + + page = alloc_page(GFP_KERNEL); + if (!page) { + if (net_ratelimit()) + netdev_err(netdev, "failed to allocate rx page\n"); + return -ENOMEM; + } + + map = dma_map_page(priv->dev, page, 0, RX_BUF_SIZE, DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(priv->dev, map))) { + if (net_ratelimit()) + netdev_err(netdev, "failed to map rx page\n"); + __free_page(page); + return -ENOMEM; + } + + ftmac100_rxdes_set_page(rxdes, page); + ftmac100_rxdes_set_dma_addr(rxdes, map); + ftmac100_rxdes_set_buffer_size(rxdes, RX_BUF_SIZE); + ftmac100_rxdes_set_dma_own(rxdes); + return 0; +} + +static void ftmac100_free_buffers(struct ftmac100 *priv) +{ + int i; + + for (i = 0; i < RX_QUEUE_ENTRIES; i++) { + struct ftmac100_rxdes *rxdes = &priv->descs->rxdes[i]; + struct page *page = ftmac100_rxdes_get_page(rxdes); + dma_addr_t map = ftmac100_rxdes_get_dma_addr(rxdes); + + if (!page) + continue; + + dma_unmap_page(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE); + __free_page(page); + } + + for (i = 0; i < TX_QUEUE_ENTRIES; i++) { + struct ftmac100_txdes *txdes = &priv->descs->txdes[i]; + struct sk_buff *skb = ftmac100_txdes_get_skb(txdes); + dma_addr_t map = ftmac100_txdes_get_dma_addr(txdes); + + if (!skb) + continue; + + dma_unmap_single(priv->dev, map, skb_headlen(skb), DMA_TO_DEVICE); + dev_kfree_skb(skb); + } + + dma_free_coherent(priv->dev, sizeof(struct ftmac100_descs), + priv->descs, priv->descs_dma_addr); +} + +static int ftmac100_alloc_buffers(struct ftmac100 *priv) +{ + int i; + + priv->descs = dma_alloc_coherent(priv->dev, sizeof(struct ftmac100_descs), + &priv->descs_dma_addr, GFP_KERNEL); + if (!priv->descs) + return -ENOMEM; + + memset(priv->descs, 0, sizeof(struct ftmac100_descs)); + + /* initialize RX ring */ + ftmac100_rxdes_set_end_of_ring(&priv->descs->rxdes[RX_QUEUE_ENTRIES - 1]); + + for (i = 0; i < RX_QUEUE_ENTRIES; i++) { + struct ftmac100_rxdes *rxdes = &priv->descs->rxdes[i]; + + if (ftmac100_alloc_rx_page(priv, rxdes)) + goto err; + } + + /* initialize TX ring */ + ftmac100_txdes_set_end_of_ring(&priv->descs->txdes[TX_QUEUE_ENTRIES - 1]); + return 0; + +err: + ftmac100_free_buffers(priv); + return -ENOMEM; +} + +/****************************************************************************** + * struct mii_if_info functions + *****************************************************************************/ +static int ftmac100_mdio_read(struct net_device *netdev, int phy_id, int reg) +{ + struct ftmac100 *priv = netdev_priv(netdev); + unsigned int phycr; + int i; + + phycr = FTMAC100_PHYCR_PHYAD(phy_id) | + FTMAC100_PHYCR_REGAD(reg) | + FTMAC100_PHYCR_MIIRD; + + iowrite32(phycr, priv->base + FTMAC100_OFFSET_PHYCR); + + for (i = 0; i < 10; i++) { + phycr = ioread32(priv->base + FTMAC100_OFFSET_PHYCR); + + if ((phycr & FTMAC100_PHYCR_MIIRD) == 0) + return phycr & FTMAC100_PHYCR_MIIRDATA; + + usleep_range(100, 1000); + } + + netdev_err(netdev, "mdio read timed out\n"); + return 0; +} + +static void ftmac100_mdio_write(struct net_device *netdev, int phy_id, int reg, + int data) +{ + struct ftmac100 *priv = netdev_priv(netdev); + unsigned int phycr; + int i; + + phycr = FTMAC100_PHYCR_PHYAD(phy_id) | + FTMAC100_PHYCR_REGAD(reg) | + FTMAC100_PHYCR_MIIWR; + + data = FTMAC100_PHYWDATA_MIIWDATA(data); + + iowrite32(data, priv->base + FTMAC100_OFFSET_PHYWDATA); + iowrite32(phycr, priv->base + FTMAC100_OFFSET_PHYCR); + + for (i = 0; i < 10; i++) { + phycr = ioread32(priv->base + FTMAC100_OFFSET_PHYCR); + + if ((phycr & FTMAC100_PHYCR_MIIWR) == 0) + return; + + usleep_range(100, 1000); + } + + netdev_err(netdev, "mdio write timed out\n"); +} + +/****************************************************************************** + * struct ethtool_ops functions + *****************************************************************************/ +static void ftmac100_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *info) +{ + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + strcpy(info->bus_info, dev_name(&netdev->dev)); +} + +static int ftmac100_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) +{ + struct ftmac100 *priv = netdev_priv(netdev); + return mii_ethtool_gset(&priv->mii, cmd); +} + +static int ftmac100_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd) +{ + struct ftmac100 *priv = netdev_priv(netdev); + return mii_ethtool_sset(&priv->mii, cmd); +} + +static int ftmac100_nway_reset(struct net_device *netdev) +{ + struct ftmac100 *priv = netdev_priv(netdev); + return mii_nway_restart(&priv->mii); +} + +static u32 ftmac100_get_link(struct net_device *netdev) +{ + struct ftmac100 *priv = netdev_priv(netdev); + return mii_link_ok(&priv->mii); +} + +static const struct ethtool_ops ftmac100_ethtool_ops = { + .set_settings = ftmac100_set_settings, + .get_settings = ftmac100_get_settings, + .get_drvinfo = ftmac100_get_drvinfo, + .nway_reset = ftmac100_nway_reset, + .get_link = ftmac100_get_link, +}; + +/****************************************************************************** + * interrupt handler + *****************************************************************************/ +static irqreturn_t ftmac100_interrupt(int irq, void *dev_id) +{ + struct net_device *netdev = dev_id; + struct ftmac100 *priv = netdev_priv(netdev); + + if (likely(netif_running(netdev))) { + /* Disable interrupts for polling */ + ftmac100_disable_all_int(priv); + napi_schedule(&priv->napi); + } + + return IRQ_HANDLED; +} + +/****************************************************************************** + * struct napi_struct functions + *****************************************************************************/ +static int ftmac100_poll(struct napi_struct *napi, int budget) +{ + struct ftmac100 *priv = container_of(napi, struct ftmac100, napi); + struct net_device *netdev = priv->netdev; + unsigned int status; + bool completed = true; + int rx = 0; + + status = ioread32(priv->base + FTMAC100_OFFSET_ISR); + + if (status & (FTMAC100_INT_RPKT_FINISH | FTMAC100_INT_NORXBUF)) { + /* + * FTMAC100_INT_RPKT_FINISH: + * RX DMA has received packets into RX buffer successfully + * + * FTMAC100_INT_NORXBUF: + * RX buffer unavailable + */ + bool retry; + + do { + retry = ftmac100_rx_packet(priv, &rx); + } while (retry && rx < budget); + + if (retry && rx == budget) + completed = false; + } + + if (status & (FTMAC100_INT_XPKT_OK | FTMAC100_INT_XPKT_LOST)) { + /* + * FTMAC100_INT_XPKT_OK: + * packet transmitted to ethernet successfully + * + * FTMAC100_INT_XPKT_LOST: + * packet transmitted to ethernet lost due to late + * collision or excessive collision + */ + ftmac100_tx_complete(priv); + } + + if (status & (FTMAC100_INT_NORXBUF | FTMAC100_INT_RPKT_LOST | + FTMAC100_INT_AHB_ERR | FTMAC100_INT_PHYSTS_CHG)) { + if (net_ratelimit()) + netdev_info(netdev, "[ISR] = 0x%x: %s%s%s%s\n", status, + status & FTMAC100_INT_NORXBUF ? "NORXBUF " : "", + status & FTMAC100_INT_RPKT_LOST ? "RPKT_LOST " : "", + status & FTMAC100_INT_AHB_ERR ? "AHB_ERR " : "", + status & FTMAC100_INT_PHYSTS_CHG ? "PHYSTS_CHG" : ""); + + if (status & FTMAC100_INT_NORXBUF) { + /* RX buffer unavailable */ + netdev->stats.rx_over_errors++; + } + + if (status & FTMAC100_INT_RPKT_LOST) { + /* received packet lost due to RX FIFO full */ + netdev->stats.rx_fifo_errors++; + } + + if (status & FTMAC100_INT_PHYSTS_CHG) { + /* PHY link status change */ + mii_check_link(&priv->mii); + } + } + + if (completed) { + /* stop polling */ + napi_complete(napi); + ftmac100_enable_all_int(priv); + } + + return rx; +} + +/****************************************************************************** + * struct net_device_ops functions + *****************************************************************************/ +static int ftmac100_open(struct net_device *netdev) +{ + struct ftmac100 *priv = netdev_priv(netdev); + int err; + + err = ftmac100_alloc_buffers(priv); + if (err) { + netdev_err(netdev, "failed to allocate buffers\n"); + goto err_alloc; + } + + err = request_irq(priv->irq, ftmac100_interrupt, 0, netdev->name, netdev); + if (err) { + netdev_err(netdev, "failed to request irq %d\n", priv->irq); + goto err_irq; + } + + priv->rx_pointer = 0; + priv->tx_clean_pointer = 0; + priv->tx_pointer = 0; + priv->tx_pending = 0; + + err = ftmac100_start_hw(priv); + if (err) + goto err_hw; + + napi_enable(&priv->napi); + netif_start_queue(netdev); + + ftmac100_enable_all_int(priv); + + return 0; + +err_hw: + free_irq(priv->irq, netdev); +err_irq: + ftmac100_free_buffers(priv); +err_alloc: + return err; +} + +static int ftmac100_stop(struct net_device *netdev) +{ + struct ftmac100 *priv = netdev_priv(netdev); + + ftmac100_disable_all_int(priv); + netif_stop_queue(netdev); + napi_disable(&priv->napi); + ftmac100_stop_hw(priv); + free_irq(priv->irq, netdev); + ftmac100_free_buffers(priv); + + return 0; +} + +static int ftmac100_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev) +{ + struct ftmac100 *priv = netdev_priv(netdev); + dma_addr_t map; + + if (unlikely(skb->len > MAX_PKT_SIZE)) { + if (net_ratelimit()) + netdev_dbg(netdev, "tx packet too big\n"); + + netdev->stats.tx_dropped++; + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + + map = dma_map_single(priv->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(priv->dev, map))) { + /* drop packet */ + if (net_ratelimit()) + netdev_err(netdev, "map socket buffer failed\n"); + + netdev->stats.tx_dropped++; + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + + return ftmac100_xmit(priv, skb, map); +} + +/* optional */ +static int ftmac100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) +{ + struct ftmac100 *priv = netdev_priv(netdev); + struct mii_ioctl_data *data = if_mii(ifr); + + return generic_mii_ioctl(&priv->mii, data, cmd, NULL); +} + +static const struct net_device_ops ftmac100_netdev_ops = { + .ndo_open = ftmac100_open, + .ndo_stop = ftmac100_stop, + .ndo_start_xmit = ftmac100_hard_start_xmit, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, + .ndo_do_ioctl = ftmac100_do_ioctl, +}; + +/****************************************************************************** + * struct platform_driver functions + *****************************************************************************/ +static int ftmac100_probe(struct platform_device *pdev) +{ + struct resource *res; + int irq; + struct net_device *netdev; + struct ftmac100 *priv; + int err; + + if (!pdev) + return -ENODEV; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENXIO; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + /* setup net_device */ + netdev = alloc_etherdev(sizeof(*priv)); + if (!netdev) { + err = -ENOMEM; + goto err_alloc_etherdev; + } + + SET_NETDEV_DEV(netdev, &pdev->dev); + SET_ETHTOOL_OPS(netdev, &ftmac100_ethtool_ops); + netdev->netdev_ops = &ftmac100_netdev_ops; + + platform_set_drvdata(pdev, netdev); + + /* setup private data */ + priv = netdev_priv(netdev); + priv->netdev = netdev; + priv->dev = &pdev->dev; + + spin_lock_init(&priv->tx_lock); + + /* initialize NAPI */ + netif_napi_add(netdev, &priv->napi, ftmac100_poll, 64); + + /* map io memory */ + priv->res = request_mem_region(res->start, resource_size(res), + dev_name(&pdev->dev)); + if (!priv->res) { + dev_err(&pdev->dev, "Could not reserve memory region\n"); + err = -ENOMEM; + goto err_req_mem; + } + + priv->base = ioremap(res->start, res->end - res->start); + if (!priv->base) { + dev_err(&pdev->dev, "Failed to ioremap ethernet registers\n"); + err = -EIO; + goto err_ioremap; + } + + priv->irq = irq; + + /* initialize struct mii_if_info */ + priv->mii.phy_id = 0; + priv->mii.phy_id_mask = 0x1f; + priv->mii.reg_num_mask = 0x1f; + priv->mii.dev = netdev; + priv->mii.mdio_read = ftmac100_mdio_read; + priv->mii.mdio_write = ftmac100_mdio_write; + + /* register network device */ + err = register_netdev(netdev); + if (err) { + dev_err(&pdev->dev, "Failed to register netdev\n"); + goto err_register_netdev; + } + + netdev_info(netdev, "irq %d, mapped at %p\n", priv->irq, priv->base); + + if (!is_valid_ether_addr(netdev->dev_addr)) { + random_ether_addr(netdev->dev_addr); + netdev_info(netdev, "generated random MAC address %pM\n", + netdev->dev_addr); + } + + return 0; + +err_register_netdev: + iounmap(priv->base); +err_ioremap: + release_resource(priv->res); +err_req_mem: + netif_napi_del(&priv->napi); + platform_set_drvdata(pdev, NULL); + free_netdev(netdev); +err_alloc_etherdev: + return err; +} + +static int __exit ftmac100_remove(struct platform_device *pdev) +{ + struct net_device *netdev; + struct ftmac100 *priv; + + netdev = platform_get_drvdata(pdev); + priv = netdev_priv(netdev); + + unregister_netdev(netdev); + + iounmap(priv->base); + release_resource(priv->res); + + netif_napi_del(&priv->napi); + platform_set_drvdata(pdev, NULL); + free_netdev(netdev); + return 0; +} + +static struct platform_driver ftmac100_driver = { + .probe = ftmac100_probe, + .remove = __exit_p(ftmac100_remove), + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + +/****************************************************************************** + * initialization / finalization + *****************************************************************************/ +static int __init ftmac100_init(void) +{ + pr_info("Loading version " DRV_VERSION " ...\n"); + return platform_driver_register(&ftmac100_driver); +} + +static void __exit ftmac100_exit(void) +{ + platform_driver_unregister(&ftmac100_driver); +} + +module_init(ftmac100_init); +module_exit(ftmac100_exit); + +MODULE_AUTHOR("Po-Yu Chuang "); +MODULE_DESCRIPTION("FTMAC100 driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/ftmac100.h b/drivers/net/ftmac100.h new file mode 100644 index 000000000000..46a0c47b1ee1 --- /dev/null +++ b/drivers/net/ftmac100.h @@ -0,0 +1,180 @@ +/* + * Faraday FTMAC100 10/100 Ethernet + * + * (C) Copyright 2009-2011 Faraday Technology + * Po-Yu Chuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __FTMAC100_H +#define __FTMAC100_H + +#define FTMAC100_OFFSET_ISR 0x00 +#define FTMAC100_OFFSET_IMR 0x04 +#define FTMAC100_OFFSET_MAC_MADR 0x08 +#define FTMAC100_OFFSET_MAC_LADR 0x0c +#define FTMAC100_OFFSET_MAHT0 0x10 +#define FTMAC100_OFFSET_MAHT1 0x14 +#define FTMAC100_OFFSET_TXPD 0x18 +#define FTMAC100_OFFSET_RXPD 0x1c +#define FTMAC100_OFFSET_TXR_BADR 0x20 +#define FTMAC100_OFFSET_RXR_BADR 0x24 +#define FTMAC100_OFFSET_ITC 0x28 +#define FTMAC100_OFFSET_APTC 0x2c +#define FTMAC100_OFFSET_DBLAC 0x30 +#define FTMAC100_OFFSET_MACCR 0x88 +#define FTMAC100_OFFSET_MACSR 0x8c +#define FTMAC100_OFFSET_PHYCR 0x90 +#define FTMAC100_OFFSET_PHYWDATA 0x94 +#define FTMAC100_OFFSET_FCR 0x98 +#define FTMAC100_OFFSET_BPR 0x9c +#define FTMAC100_OFFSET_TS 0xc4 +#define FTMAC100_OFFSET_DMAFIFOS 0xc8 +#define FTMAC100_OFFSET_TM 0xcc +#define FTMAC100_OFFSET_TX_MCOL_SCOL 0xd4 +#define FTMAC100_OFFSET_RPF_AEP 0xd8 +#define FTMAC100_OFFSET_XM_PG 0xdc +#define FTMAC100_OFFSET_RUNT_TLCC 0xe0 +#define FTMAC100_OFFSET_CRCER_FTL 0xe4 +#define FTMAC100_OFFSET_RLC_RCC 0xe8 +#define FTMAC100_OFFSET_BROC 0xec +#define FTMAC100_OFFSET_MULCA 0xf0 +#define FTMAC100_OFFSET_RP 0xf4 +#define FTMAC100_OFFSET_XP 0xf8 + +/* + * Interrupt status register & interrupt mask register + */ +#define FTMAC100_INT_RPKT_FINISH (1 << 0) +#define FTMAC100_INT_NORXBUF (1 << 1) +#define FTMAC100_INT_XPKT_FINISH (1 << 2) +#define FTMAC100_INT_NOTXBUF (1 << 3) +#define FTMAC100_INT_XPKT_OK (1 << 4) +#define FTMAC100_INT_XPKT_LOST (1 << 5) +#define FTMAC100_INT_RPKT_SAV (1 << 6) +#define FTMAC100_INT_RPKT_LOST (1 << 7) +#define FTMAC100_INT_AHB_ERR (1 << 8) +#define FTMAC100_INT_PHYSTS_CHG (1 << 9) + +/* + * Interrupt timer control register + */ +#define FTMAC100_ITC_RXINT_CNT(x) (((x) & 0xf) << 0) +#define FTMAC100_ITC_RXINT_THR(x) (((x) & 0x7) << 4) +#define FTMAC100_ITC_RXINT_TIME_SEL (1 << 7) +#define FTMAC100_ITC_TXINT_CNT(x) (((x) & 0xf) << 8) +#define FTMAC100_ITC_TXINT_THR(x) (((x) & 0x7) << 12) +#define FTMAC100_ITC_TXINT_TIME_SEL (1 << 15) + +/* + * Automatic polling timer control register + */ +#define FTMAC100_APTC_RXPOLL_CNT(x) (((x) & 0xf) << 0) +#define FTMAC100_APTC_RXPOLL_TIME_SEL (1 << 4) +#define FTMAC100_APTC_TXPOLL_CNT(x) (((x) & 0xf) << 8) +#define FTMAC100_APTC_TXPOLL_TIME_SEL (1 << 12) + +/* + * DMA burst length and arbitration control register + */ +#define FTMAC100_DBLAC_INCR4_EN (1 << 0) +#define FTMAC100_DBLAC_INCR8_EN (1 << 1) +#define FTMAC100_DBLAC_INCR16_EN (1 << 2) +#define FTMAC100_DBLAC_RXFIFO_LTHR(x) (((x) & 0x7) << 3) +#define FTMAC100_DBLAC_RXFIFO_HTHR(x) (((x) & 0x7) << 6) +#define FTMAC100_DBLAC_RX_THR_EN (1 << 9) + +/* + * MAC control register + */ +#define FTMAC100_MACCR_XDMA_EN (1 << 0) +#define FTMAC100_MACCR_RDMA_EN (1 << 1) +#define FTMAC100_MACCR_SW_RST (1 << 2) +#define FTMAC100_MACCR_LOOP_EN (1 << 3) +#define FTMAC100_MACCR_CRC_DIS (1 << 4) +#define FTMAC100_MACCR_XMT_EN (1 << 5) +#define FTMAC100_MACCR_ENRX_IN_HALFTX (1 << 6) +#define FTMAC100_MACCR_RCV_EN (1 << 8) +#define FTMAC100_MACCR_HT_MULTI_EN (1 << 9) +#define FTMAC100_MACCR_RX_RUNT (1 << 10) +#define FTMAC100_MACCR_RX_FTL (1 << 11) +#define FTMAC100_MACCR_RCV_ALL (1 << 12) +#define FTMAC100_MACCR_CRC_APD (1 << 14) +#define FTMAC100_MACCR_FULLDUP (1 << 15) +#define FTMAC100_MACCR_RX_MULTIPKT (1 << 16) +#define FTMAC100_MACCR_RX_BROADPKT (1 << 17) + +/* + * PHY control register + */ +#define FTMAC100_PHYCR_MIIRDATA 0xffff +#define FTMAC100_PHYCR_PHYAD(x) (((x) & 0x1f) << 16) +#define FTMAC100_PHYCR_REGAD(x) (((x) & 0x1f) << 21) +#define FTMAC100_PHYCR_MIIRD (1 << 26) +#define FTMAC100_PHYCR_MIIWR (1 << 27) + +/* + * PHY write data register + */ +#define FTMAC100_PHYWDATA_MIIWDATA(x) ((x) & 0xffff) + +/* + * Transmit descriptor, aligned to 16 bytes + */ +struct ftmac100_txdes { + unsigned int txdes0; + unsigned int txdes1; + unsigned int txdes2; /* TXBUF_BADR */ + unsigned int txdes3; /* not used by HW */ +} __attribute__ ((aligned(16))); + +#define FTMAC100_TXDES0_TXPKT_LATECOL (1 << 0) +#define FTMAC100_TXDES0_TXPKT_EXSCOL (1 << 1) +#define FTMAC100_TXDES0_TXDMA_OWN (1 << 31) + +#define FTMAC100_TXDES1_TXBUF_SIZE(x) ((x) & 0x7ff) +#define FTMAC100_TXDES1_LTS (1 << 27) +#define FTMAC100_TXDES1_FTS (1 << 28) +#define FTMAC100_TXDES1_TX2FIC (1 << 29) +#define FTMAC100_TXDES1_TXIC (1 << 30) +#define FTMAC100_TXDES1_EDOTR (1 << 31) + +/* + * Receive descriptor, aligned to 16 bytes + */ +struct ftmac100_rxdes { + unsigned int rxdes0; + unsigned int rxdes1; + unsigned int rxdes2; /* RXBUF_BADR */ + unsigned int rxdes3; /* not used by HW */ +} __attribute__ ((aligned(16))); + +#define FTMAC100_RXDES0_RFL 0x7ff +#define FTMAC100_RXDES0_MULTICAST (1 << 16) +#define FTMAC100_RXDES0_BROADCAST (1 << 17) +#define FTMAC100_RXDES0_RX_ERR (1 << 18) +#define FTMAC100_RXDES0_CRC_ERR (1 << 19) +#define FTMAC100_RXDES0_FTL (1 << 20) +#define FTMAC100_RXDES0_RUNT (1 << 21) +#define FTMAC100_RXDES0_RX_ODD_NB (1 << 22) +#define FTMAC100_RXDES0_LRS (1 << 28) +#define FTMAC100_RXDES0_FRS (1 << 29) +#define FTMAC100_RXDES0_RXDMA_OWN (1 << 31) + +#define FTMAC100_RXDES1_RXBUF_SIZE(x) ((x) & 0x7ff) +#define FTMAC100_RXDES1_EDORR (1 << 31) + +#endif /* __FTMAC100_H */ -- cgit v1.2.3 From 6b8a66ee919e40111e3d257b2c22b5773e34ead1 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 2 Mar 2011 07:18:10 +0000 Subject: tun: Convert logging messages to pr_ and tun_debug Use the current logging forms with pr_fmt. Convert DBG macro to tun_debug, use netdev_printk as well. Add printf verification when TUN_DEBUG not defined. Miscellaneous comment typo fix. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/tun.c | 83 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 55786a0efc41..f5e9ac00a07b 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -34,6 +34,8 @@ * Modifications for 2.3.99-pre5 kernel. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #define DRV_NAME "tun" #define DRV_VERSION "1.6" #define DRV_DESCRIPTION "Universal TUN/TAP device driver" @@ -76,11 +78,27 @@ #ifdef TUN_DEBUG static int debug; -#define DBG if(tun->debug)printk -#define DBG1 if(debug==2)printk +#define tun_debug(level, tun, fmt, args...) \ +do { \ + if (tun->debug) \ + netdev_printk(level, tun->dev, fmt, ##args); \ +} while (0) +#define DBG1(level, fmt, args...) \ +do { \ + if (debug == 2) \ + printk(level fmt, ##args); \ +} while (0) #else -#define DBG( a... ) -#define DBG1( a... ) +#define tun_debug(level, tun, fmt, args...) \ +do { \ + if (0) \ + netdev_printk(level, tun->dev, fmt, ##args); \ +} while (0) +#define DBG1(level, fmt, args...) \ +do { \ + if (0) \ + printk(level fmt, ##args); \ +} while (0) #endif #define FLT_EXACT_COUNT 8 @@ -205,7 +223,7 @@ static void tun_put(struct tun_struct *tun) tun_detach(tfile->tun); } -/* TAP filterting */ +/* TAP filtering */ static void addr_hash_set(u32 *mask, const u8 *addr) { int n = ether_crc(ETH_ALEN, addr) >> 26; @@ -360,7 +378,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) { struct tun_struct *tun = netdev_priv(dev); - DBG(KERN_INFO "%s: tun_net_xmit %d\n", tun->dev->name, skb->len); + tun_debug(KERN_INFO, tun, "tun_net_xmit %d\n", skb->len); /* Drop packet if interface is not attached */ if (!tun->tfile) @@ -499,7 +517,7 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait) sk = tun->socket.sk; - DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name); + tun_debug(KERN_INFO, tun, "tun_chr_poll\n"); poll_wait(file, &tun->wq.wait, wait); @@ -690,7 +708,7 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv, if (!tun) return -EBADFD; - DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count); + tun_debug(KERN_INFO, tun, "tun_chr_write %ld\n", count); result = tun_get_user(tun, iv, iov_length(iv, count), file->f_flags & O_NONBLOCK); @@ -739,7 +757,7 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun, else if (sinfo->gso_type & SKB_GSO_UDP) gso.gso_type = VIRTIO_NET_HDR_GSO_UDP; else { - printk(KERN_ERR "tun: unexpected GSO type: " + pr_err("unexpected GSO type: " "0x%x, gso_size %d, hdr_len %d\n", sinfo->gso_type, gso.gso_size, gso.hdr_len); @@ -786,7 +804,7 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct sk_buff *skb; ssize_t ret = 0; - DBG(KERN_INFO "%s: tun_chr_read\n", tun->dev->name); + tun_debug(KERN_INFO, tun, "tun_chr_read\n"); add_wait_queue(&tun->wq.wait, &wait); while (len) { @@ -1083,7 +1101,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) if (device_create_file(&tun->dev->dev, &dev_attr_tun_flags) || device_create_file(&tun->dev->dev, &dev_attr_owner) || device_create_file(&tun->dev->dev, &dev_attr_group)) - printk(KERN_ERR "Failed to create tun sysfs files\n"); + pr_err("Failed to create tun sysfs files\n"); sk->sk_destruct = tun_sock_destruct; @@ -1092,7 +1110,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) goto failed; } - DBG(KERN_INFO "%s: tun_set_iff\n", tun->dev->name); + tun_debug(KERN_INFO, tun, "tun_set_iff\n"); if (ifr->ifr_flags & IFF_NO_PI) tun->flags |= TUN_NO_PI; @@ -1129,7 +1147,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) static int tun_get_iff(struct net *net, struct tun_struct *tun, struct ifreq *ifr) { - DBG(KERN_INFO "%s: tun_get_iff\n", tun->dev->name); + tun_debug(KERN_INFO, tun, "tun_get_iff\n"); strcpy(ifr->ifr_name, tun->dev->name); @@ -1229,7 +1247,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, if (!tun) goto unlock; - DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd); + tun_debug(KERN_INFO, tun, "tun_chr_ioctl cmd %d\n", cmd); ret = 0; switch (cmd) { @@ -1249,8 +1267,8 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, else tun->flags &= ~TUN_NOCHECKSUM; - DBG(KERN_INFO "%s: checksum %s\n", - tun->dev->name, arg ? "disabled" : "enabled"); + tun_debug(KERN_INFO, tun, "checksum %s\n", + arg ? "disabled" : "enabled"); break; case TUNSETPERSIST: @@ -1260,33 +1278,34 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, else tun->flags &= ~TUN_PERSIST; - DBG(KERN_INFO "%s: persist %s\n", - tun->dev->name, arg ? "enabled" : "disabled"); + tun_debug(KERN_INFO, tun, "persist %s\n", + arg ? "enabled" : "disabled"); break; case TUNSETOWNER: /* Set owner of the device */ tun->owner = (uid_t) arg; - DBG(KERN_INFO "%s: owner set to %d\n", tun->dev->name, tun->owner); + tun_debug(KERN_INFO, tun, "owner set to %d\n", tun->owner); break; case TUNSETGROUP: /* Set group of the device */ tun->group= (gid_t) arg; - DBG(KERN_INFO "%s: group set to %d\n", tun->dev->name, tun->group); + tun_debug(KERN_INFO, tun, "group set to %d\n", tun->group); break; case TUNSETLINK: /* Only allow setting the type when the interface is down */ if (tun->dev->flags & IFF_UP) { - DBG(KERN_INFO "%s: Linktype set failed because interface is up\n", - tun->dev->name); + tun_debug(KERN_INFO, tun, + "Linktype set failed because interface is up\n"); ret = -EBUSY; } else { tun->dev->type = (int) arg; - DBG(KERN_INFO "%s: linktype set to %d\n", tun->dev->name, tun->dev->type); + tun_debug(KERN_INFO, tun, "linktype set to %d\n", + tun->dev->type); ret = 0; } break; @@ -1318,8 +1337,8 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, case SIOCSIFHWADDR: /* Set hw address */ - DBG(KERN_DEBUG "%s: set hw address: %pM\n", - tun->dev->name, ifr.ifr_hwaddr.sa_data); + tun_debug(KERN_DEBUG, tun, "set hw address: %pM\n", + ifr.ifr_hwaddr.sa_data); ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr); break; @@ -1433,7 +1452,7 @@ static int tun_chr_fasync(int fd, struct file *file, int on) if (!tun) return -EBADFD; - DBG(KERN_INFO "%s: tun_chr_fasync %d\n", tun->dev->name, on); + tun_debug(KERN_INFO, tun, "tun_chr_fasync %d\n", on); if ((ret = fasync_helper(fd, file, on, &tun->fasync)) < 0) goto out; @@ -1455,7 +1474,7 @@ static int tun_chr_open(struct inode *inode, struct file * file) { struct tun_file *tfile; - DBG1(KERN_INFO "tunX: tun_chr_open\n"); + DBG1(KERN_INFO, "tunX: tun_chr_open\n"); tfile = kmalloc(sizeof(*tfile), GFP_KERNEL); if (!tfile) @@ -1476,7 +1495,7 @@ static int tun_chr_close(struct inode *inode, struct file *file) if (tun) { struct net_device *dev = tun->dev; - DBG(KERN_INFO "%s: tun_chr_close\n", dev->name); + tun_debug(KERN_INFO, tun, "tun_chr_close\n"); __tun_detach(tun); @@ -1607,18 +1626,18 @@ static int __init tun_init(void) { int ret = 0; - printk(KERN_INFO "tun: %s, %s\n", DRV_DESCRIPTION, DRV_VERSION); - printk(KERN_INFO "tun: %s\n", DRV_COPYRIGHT); + pr_info("%s, %s\n", DRV_DESCRIPTION, DRV_VERSION); + pr_info("%s\n", DRV_COPYRIGHT); ret = rtnl_link_register(&tun_link_ops); if (ret) { - printk(KERN_ERR "tun: Can't register link_ops\n"); + pr_err("Can't register link_ops\n"); goto err_linkops; } ret = misc_register(&tun_miscdev); if (ret) { - printk(KERN_ERR "tun: Can't register misc device %d\n", TUN_MINOR); + pr_err("Can't register misc device %d\n", TUN_MINOR); goto err_misc; } return 0; -- cgit v1.2.3 From 1829b086d175ba07a01ff6934fd51a59bc9be4ce Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 1 Mar 2011 05:48:12 +0000 Subject: benet: use GFP_KERNEL allocations when possible Extend be_alloc_pages() with a gfp parameter, so that we use GFP_KERNEL allocations instead of GFP_ATOMIC when not running in softirq context. Signed-off-by: Eric Dumazet Acked-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 0bdccb10aac5..ef66dc61e6ea 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1169,20 +1169,20 @@ static inline void be_rx_compl_reset(struct be_eth_rx_compl *rxcp) rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] = 0; } -static inline struct page *be_alloc_pages(u32 size) +static inline struct page *be_alloc_pages(u32 size, gfp_t gfp) { - gfp_t alloc_flags = GFP_ATOMIC; u32 order = get_order(size); + if (order > 0) - alloc_flags |= __GFP_COMP; - return alloc_pages(alloc_flags, order); + gfp |= __GFP_COMP; + return alloc_pages(gfp, order); } /* * Allocate a page, split it to fragments of size rx_frag_size and post as * receive buffers to BE */ -static void be_post_rx_frags(struct be_rx_obj *rxo) +static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp) { struct be_adapter *adapter = rxo->adapter; struct be_rx_page_info *page_info_tbl = rxo->page_info_tbl; @@ -1196,7 +1196,7 @@ static void be_post_rx_frags(struct be_rx_obj *rxo) page_info = &rxo->page_info_tbl[rxq->head]; for (posted = 0; posted < MAX_RX_POST && !page_info->page; posted++) { if (!pagep) { - pagep = be_alloc_pages(adapter->big_page_size); + pagep = be_alloc_pages(adapter->big_page_size, gfp); if (unlikely(!pagep)) { rxo->stats.rx_post_fail++; break; @@ -1753,7 +1753,7 @@ static int be_poll_rx(struct napi_struct *napi, int budget) /* Refill the queue */ if (atomic_read(&rxo->q.used) < RX_FRAGS_REFILL_WM) - be_post_rx_frags(rxo); + be_post_rx_frags(rxo, GFP_ATOMIC); /* All consumed */ if (work_done < budget) { @@ -1890,7 +1890,7 @@ static void be_worker(struct work_struct *work) if (rxo->rx_post_starved) { rxo->rx_post_starved = false; - be_post_rx_frags(rxo); + be_post_rx_frags(rxo, GFP_KERNEL); } } if (!adapter->ue_detected && !lancer_chip(adapter)) @@ -2138,7 +2138,7 @@ static int be_open(struct net_device *netdev) u16 link_speed; for_all_rx_queues(adapter, rxo, i) { - be_post_rx_frags(rxo); + be_post_rx_frags(rxo, GFP_KERNEL); napi_enable(&rxo->rx_eq.napi); } napi_enable(&tx_eq->napi); -- cgit v1.2.3 From a576cd8700271273a572976df4f06db44a0652f3 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 1 Mar 2011 06:56:32 +0000 Subject: tlan: Remove changelog As it isn't necessary nor really useful any longer. Signed-off-by: Joe Perches Acked-by: Sakari Ailus Signed-off-by: David S. Miller --- drivers/net/tlan.c | 145 ----------------------------------------------------- 1 file changed, 145 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index e48a80885343..7721e6cf96f8 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -25,151 +25,6 @@ * Microchip Technology, 24C01A/02A/04A Data Sheet * available in PDF format from www.microchip.com * - * Change History - * - * Tigran Aivazian : TLan_PciProbe() now uses - * new PCI BIOS interface. - * Alan Cox : - * Fixed the out of memory - * handling. - * - * Torben Mathiasen New Maintainer! - * - * v1.1 Dec 20, 1999 - Removed linux version checking - * Patch from Tigran Aivazian. - * - v1.1 includes Alan's SMP updates. - * - We still have problems on SMP though, - * but I'm looking into that. - * - * v1.2 Jan 02, 2000 - Hopefully fixed the SMP deadlock. - * - Removed dependency of HZ being 100. - * - We now allow higher priority timers to - * overwrite timers like TLAN_TIMER_ACTIVITY - * Patch from John Cagle . - * - Fixed a few compiler warnings. - * - * v1.3 Feb 04, 2000 - Fixed the remaining HZ issues. - * - Removed call to pci_present(). - * - Removed SA_INTERRUPT flag from irq handler. - * - Added __init and __initdata to reduce resisdent - * code size. - * - Driver now uses module_init/module_exit. - * - Rewrote init_module and tlan_probe to - * share a lot more code. We now use tlan_probe - * with builtin and module driver. - * - Driver ported to new net API. - * - tlan.txt has been reworked to reflect current - * driver (almost) - * - Other minor stuff - * - * v1.4 Feb 10, 2000 - Updated with more changes required after Dave's - * network cleanup in 2.3.43pre7 (Tigran & myself) - * - Minor stuff. - * - * v1.5 March 22, 2000 - Fixed another timer bug that would hang the - * driver if no cable/link were present. - * - Cosmetic changes. - * - TODO: Port completely to new PCI/DMA API - * Auto-Neg fallback. - * - * v1.6 April 04, 2000 - Fixed driver support for kernel-parameters. - * Haven't tested it though, as the kernel support - * is currently broken (2.3.99p4p3). - * - Updated tlan.txt accordingly. - * - Adjusted minimum/maximum frame length. - * - There is now a TLAN website up at - * http://hp.sourceforge.net/ - * - * v1.7 April 07, 2000 - Started to implement custom ioctls. Driver now - * reports PHY information when used with Donald - * Beckers userspace MII diagnostics utility. - * - * v1.8 April 23, 2000 - Fixed support for forced speed/duplex settings. - * - Added link information to Auto-Neg and forced - * modes. When NIC operates with auto-neg the driver - * will report Link speed & duplex modes as well as - * link partner abilities. When forced link is used, - * the driver will report status of the established - * link. - * Please read tlan.txt for additional information. - * - Removed call to check_region(), and used - * return value of request_region() instead. - * - * v1.8a May 28, 2000 - Minor updates. - * - * v1.9 July 25, 2000 - Fixed a few remaining Full-Duplex issues. - * - Updated with timer fixes from Andrew Morton. - * - Fixed module race in TLan_Open. - * - Added routine to monitor PHY status. - * - Added activity led support for Proliant devices. - * - * v1.10 Aug 30, 2000 - Added support for EISA based tlan controllers - * like the Compaq NetFlex3/E. - * - Rewrote tlan_probe to better handle multiple - * bus probes. Probing and device setup is now - * done through TLan_Probe and TLan_init_one. Actual - * hardware probe is done with kernel API and - * TLan_EisaProbe. - * - Adjusted debug information for probing. - * - Fixed bug that would cause general debug - * information to be printed after driver removal. - * - Added transmit timeout handling. - * - Fixed OOM return values in tlan_probe. - * - Fixed possible mem leak in tlan_exit - * (now tlan_remove_one). - * - Fixed timer bug in TLan_phyMonitor. - * - This driver version is alpha quality, please - * send me any bug issues you may encounter. - * - * v1.11 Aug 31, 2000 - Do not try to register irq 0 if no irq line was - * set for EISA cards. - * - Added support for NetFlex3/E with nibble-rate - * 10Base-T PHY. This is untestet as I haven't got - * one of these cards. - * - Fixed timer being added twice. - * - Disabled PhyMonitoring by default as this is - * work in progress. Define MONITOR to enable it. - * - Now we don't display link info with PHYs that - * doesn't support it (level1). - * - Incresed tx_timeout beacuse of auto-neg. - * - Adjusted timers for forced speeds. - * - * v1.12 Oct 12, 2000 - Minor fixes (memleak, init, etc.) - * - * v1.13 Nov 28, 2000 - Stop flooding console with auto-neg issues - * when link can't be established. - * - Added the bbuf option as a kernel parameter. - * - Fixed ioaddr probe bug. - * - Fixed stupid deadlock with MII interrupts. - * - Added support for speed/duplex selection with - * multiple nics. - * - Added partly fix for TX Channel lockup with - * TLAN v1.0 silicon. This needs to be investigated - * further. - * - * v1.14 Dec 16, 2000 - Added support for servicing multiple frames per. - * interrupt. Thanks goes to - * Adam Keys - * Denis Beaudoin - * for providing the patch. - * - Fixed auto-neg output when using multiple - * adapters. - * - Converted to use new taskq interface. - * - * v1.14a Jan 6, 2001 - Minor adjustments (spinlocks, etc.) - * - * Samuel Chessman New Maintainer! - * - * v1.15 Apr 4, 2002 - Correct operation when aui=1 to be - * 10T half duplex no loopback - * Thanks to Gunnar Eikman - * - * Sakari Ailus : - * - * v1.15a Dec 15 2008 - Remove bbuf support, it doesn't work anyway. - * v1.16 Jan 6 2011 - Make checkpatch.pl happy. - * v1.17 Jan 6 2011 - Add suspend/resume support. - * ******************************************************************************/ #include -- cgit v1.2.3 From 50624aab5304cb8167ead32af46ac9de54e6e8ad Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 1 Mar 2011 06:56:33 +0000 Subject: tlan: Use pr_fmt, pr_ and netdev_ Neatening and standardization to the current logging mechanisms. Miscellaneous speen/speed typo correction. Signed-off-by: Joe Perches Acked-by: Sakari Ailus Signed-off-by: David S. Miller --- drivers/net/tlan.c | 164 +++++++++++++++++++++++++---------------------------- 1 file changed, 77 insertions(+), 87 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index 7721e6cf96f8..ace6404e2fac 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -27,6 +27,8 @@ * ******************************************************************************/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -59,7 +61,7 @@ module_param_array(speed, int, NULL, 0); MODULE_PARM_DESC(aui, "ThunderLAN use AUI port(s) (0-1)"); MODULE_PARM_DESC(duplex, "ThunderLAN duplex setting(s) (0-default, 1-half, 2-full)"); -MODULE_PARM_DESC(speed, "ThunderLAN port speen setting(s) (0,10,100)"); +MODULE_PARM_DESC(speed, "ThunderLAN port speed setting(s) (0,10,100)"); MODULE_AUTHOR("Maintainer: Samuel Chessman "); MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters"); @@ -397,7 +399,7 @@ static int __init tlan_probe(void) { int rc = -ENODEV; - printk(KERN_INFO "%s", tlan_banner); + pr_info("%s", tlan_banner); TLAN_DBG(TLAN_DEBUG_PROBE, "Starting PCI Probe....\n"); @@ -406,16 +408,16 @@ static int __init tlan_probe(void) rc = pci_register_driver(&tlan_driver); if (rc != 0) { - printk(KERN_ERR "TLAN: Could not register pci driver.\n"); + pr_err("Could not register pci driver\n"); goto err_out_pci_free; } TLAN_DBG(TLAN_DEBUG_PROBE, "Starting EISA Probe....\n"); tlan_eisa_probe(); - printk(KERN_INFO "TLAN: %d device%s installed, PCI: %d EISA: %d\n", - tlan_devices_installed, tlan_devices_installed == 1 ? "" : "s", - tlan_have_pci, tlan_have_eisa); + pr_info("%d device%s installed, PCI: %d EISA: %d\n", + tlan_devices_installed, tlan_devices_installed == 1 ? "" : "s", + tlan_have_pci, tlan_have_eisa); if (tlan_devices_installed == 0) { rc = -ENODEV; @@ -474,7 +476,7 @@ static int __devinit tlan_probe1(struct pci_dev *pdev, rc = pci_request_regions(pdev, tlan_signature); if (rc) { - printk(KERN_ERR "TLAN: Could not reserve IO regions\n"); + pr_err("Could not reserve IO regions\n"); goto err_out; } } @@ -482,7 +484,7 @@ static int __devinit tlan_probe1(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(struct tlan_priv)); if (dev == NULL) { - printk(KERN_ERR "TLAN: Could not allocate memory for device.\n"); + pr_err("Could not allocate memory for device\n"); rc = -ENOMEM; goto err_out_regions; } @@ -501,8 +503,7 @@ static int __devinit tlan_probe1(struct pci_dev *pdev, rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (rc) { - printk(KERN_ERR - "TLAN: No suitable PCI mapping available.\n"); + pr_err("No suitable PCI mapping available\n"); goto err_out_free_dev; } @@ -516,7 +517,7 @@ static int __devinit tlan_probe1(struct pci_dev *pdev, } } if (!pci_io_base) { - printk(KERN_ERR "TLAN: No IO mappings available\n"); + pr_err("No IO mappings available\n"); rc = -EIO; goto err_out_free_dev; } @@ -572,13 +573,13 @@ static int __devinit tlan_probe1(struct pci_dev *pdev, rc = tlan_init(dev); if (rc) { - printk(KERN_ERR "TLAN: Could not set up device.\n"); + pr_err("Could not set up device\n"); goto err_out_free_dev; } rc = register_netdev(dev); if (rc) { - printk(KERN_ERR "TLAN: Could not register device.\n"); + pr_err("Could not register device\n"); goto err_out_uninit; } @@ -595,12 +596,11 @@ static int __devinit tlan_probe1(struct pci_dev *pdev, tlan_have_eisa++; } - printk(KERN_INFO "TLAN: %s irq=%2d, io=%04x, %s, Rev. %d\n", - dev->name, - (int) dev->irq, - (int) dev->base_addr, - priv->adapter->device_label, - priv->adapter_rev); + netdev_info(dev, "irq=%2d, io=%04x, %s, Rev. %d\n", + (int)dev->irq, + (int)dev->base_addr, + priv->adapter->device_label, + priv->adapter_rev); return 0; err_out_uninit: @@ -716,7 +716,7 @@ static void __init tlan_eisa_probe(void) } if (debug == 0x10) - printk(KERN_INFO "Found one\n"); + pr_info("Found one\n"); /* Get irq from board */ @@ -745,12 +745,12 @@ static void __init tlan_eisa_probe(void) out: if (debug == 0x10) - printk(KERN_INFO "None found\n"); + pr_info("None found\n"); continue; out2: if (debug == 0x10) - printk(KERN_INFO "Card found but it is not enabled, skipping\n"); + pr_info("Card found but it is not enabled, skipping\n"); continue; } @@ -818,8 +818,7 @@ static int tlan_init(struct net_device *dev) priv->dma_size = dma_size; if (priv->dma_storage == NULL) { - printk(KERN_ERR - "TLAN: Could not allocate lists and buffers for %s.\n", + pr_err("Could not allocate lists and buffers for %s\n", dev->name); return -ENOMEM; } @@ -837,9 +836,8 @@ static int tlan_init(struct net_device *dev) (u8) priv->adapter->addr_ofs + i, (u8 *) &dev->dev_addr[i]); if (err) { - printk(KERN_ERR "TLAN: %s: Error reading MAC from eeprom: %d\n", - dev->name, - err); + pr_err("%s: Error reading MAC from eeprom: %d\n", + dev->name, err); } dev->addr_len = 6; @@ -883,8 +881,8 @@ static int tlan_open(struct net_device *dev) dev->name, dev); if (err) { - pr_err("TLAN: Cannot open %s because IRQ %d is already in use.\n", - dev->name, dev->irq); + netdev_err(dev, "Cannot open because IRQ %d is already in use\n", + dev->irq); return err; } @@ -1367,8 +1365,8 @@ static u32 tlan_handle_tx_eof(struct net_device *dev, u16 host_int) } if (!ack) - printk(KERN_INFO - "TLAN: Received interrupt for uncompleted TX frame.\n"); + netdev_info(dev, + "Received interrupt for uncompleted TX frame\n"); if (eoc) { TLAN_DBG(TLAN_DEBUG_TX, @@ -1522,8 +1520,8 @@ drop_and_reuse: } if (!ack) - printk(KERN_INFO - "TLAN: Received interrupt for uncompleted RX frame.\n"); + netdev_info(dev, + "Received interrupt for uncompleted RX frame\n"); if (eoc) { @@ -1579,7 +1577,7 @@ drop_and_reuse: static u32 tlan_handle_dummy(struct net_device *dev, u16 host_int) { - pr_info("TLAN: Test interrupt on %s.\n", dev->name); + netdev_info(dev, "Test interrupt\n"); return 1; } @@ -1673,7 +1671,7 @@ static u32 tlan_handle_status_check(struct net_device *dev, u16 host_int) if (host_int & TLAN_HI_IV_MASK) { netif_stop_queue(dev); error = inl(dev->base_addr + TLAN_CH_PARM); - pr_info("TLAN: %s: Adaptor Error = 0x%x\n", dev->name, error); + netdev_info(dev, "Adaptor Error = 0x%x\n", error); tlan_read_and_clear_stats(dev, TLAN_RECORD); outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD); @@ -1914,7 +1912,7 @@ static void tlan_reset_lists(struct net_device *dev) list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER; skb = netdev_alloc_skb_ip_align(dev, TLAN_MAX_FRAME_SIZE + 5); if (!skb) { - pr_err("TLAN: out of memory for received data.\n"); + netdev_err(dev, "Out of memory for received data\n"); break; } @@ -1998,13 +1996,13 @@ static void tlan_print_dio(u16 io_base) u32 data0, data1; int i; - pr_info("TLAN: Contents of internal registers for io base 0x%04hx.\n", - io_base); - pr_info("TLAN: Off. +0 +4\n"); + pr_info("Contents of internal registers for io base 0x%04hx\n", + io_base); + pr_info("Off. +0 +4\n"); for (i = 0; i < 0x4C; i += 8) { data0 = tlan_dio_read32(io_base, i); data1 = tlan_dio_read32(io_base, i + 0x4); - pr_info("TLAN: 0x%02x 0x%08x 0x%08x\n", i, data0, data1); + pr_info("0x%02x 0x%08x 0x%08x\n", i, data0, data1); } } @@ -2033,14 +2031,14 @@ static void tlan_print_list(struct tlan_list *list, char *type, int num) { int i; - pr_info("TLAN: %s List %d at %p\n", type, num, list); - pr_info("TLAN: Forward = 0x%08x\n", list->forward); - pr_info("TLAN: CSTAT = 0x%04hx\n", list->c_stat); - pr_info("TLAN: Frame Size = 0x%04hx\n", list->frame_size); + pr_info("%s List %d at %p\n", type, num, list); + pr_info(" Forward = 0x%08x\n", list->forward); + pr_info(" CSTAT = 0x%04hx\n", list->c_stat); + pr_info(" Frame Size = 0x%04hx\n", list->frame_size); /* for (i = 0; i < 10; i++) { */ for (i = 0; i < 2; i++) { - pr_info("TLAN: Buffer[%d].count, addr = 0x%08x, 0x%08x\n", - i, list->buffer[i].count, list->buffer[i].address); + pr_info(" Buffer[%d].count, addr = 0x%08x, 0x%08x\n", + i, list->buffer[i].count, list->buffer[i].address); } } @@ -2255,7 +2253,7 @@ tlan_finish_reset(struct net_device *dev) if ((priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) || (priv->aui)) { status = MII_GS_LINK; - pr_info("TLAN: %s: Link forced.\n", dev->name); + netdev_info(dev, "Link forced\n"); } else { tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status); udelay(1000); @@ -2267,24 +2265,21 @@ tlan_finish_reset(struct net_device *dev) tlan_mii_read_reg(dev, phy, MII_AN_LPA, &partner); tlan_mii_read_reg(dev, phy, TLAN_TLPHY_PAR, &tlphy_par); - pr_info("TLAN: %s: Link active with ", dev->name); - if (!(tlphy_par & TLAN_PHY_AN_EN_STAT)) { - pr_info("forced 10%sMbps %s-Duplex\n", - tlphy_par & TLAN_PHY_SPEED_100 - ? "" : "0", - tlphy_par & TLAN_PHY_DUPLEX_FULL - ? "Full" : "Half"); - } else { - pr_info("Autonegotiation enabled, at 10%sMbps %s-Duplex\n", - tlphy_par & TLAN_PHY_SPEED_100 - ? "" : "0", - tlphy_par & TLAN_PHY_DUPLEX_FULL - ? "Full" : "half"); - pr_info("TLAN: Partner capability: "); - for (i = 5; i <= 10; i++) - if (partner & (1<base_addr, TLAN_LED_REG, @@ -2296,7 +2291,7 @@ tlan_finish_reset(struct net_device *dev) tlan_set_timer(dev, (10*HZ), TLAN_TIMER_LINK_BEAT); #endif } else if (status & MII_GS_LINK) { - pr_info("TLAN: %s: Link active\n", dev->name); + netdev_info(dev, "Link active\n"); tlan_dio_write8(dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK); } @@ -2322,8 +2317,7 @@ tlan_finish_reset(struct net_device *dev) outl(TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD); netif_carrier_on(dev); } else { - pr_info("TLAN: %s: Link inactive, will retry in 10 secs...\n", - dev->name); + netdev_info(dev, "Link inactive, will retry in 10 secs...\n"); tlan_set_timer(dev, (10*HZ), TLAN_TIMER_FINISH_RESET); return; } @@ -2407,23 +2401,20 @@ static void tlan_phy_print(struct net_device *dev) phy = priv->phy[priv->phy_num]; if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) { - pr_info("TLAN: Device %s, Unmanaged PHY.\n", dev->name); + netdev_info(dev, "Unmanaged PHY\n"); } else if (phy <= TLAN_PHY_MAX_ADDR) { - pr_info("TLAN: Device %s, PHY 0x%02x.\n", dev->name, phy); - pr_info("TLAN: Off. +0 +1 +2 +3\n"); + netdev_info(dev, "PHY 0x%02x\n", phy); + pr_info(" Off. +0 +1 +2 +3\n"); for (i = 0; i < 0x20; i += 4) { - pr_info("TLAN: 0x%02x", i); tlan_mii_read_reg(dev, phy, i, &data0); - printk(" 0x%04hx", data0); tlan_mii_read_reg(dev, phy, i + 1, &data1); - printk(" 0x%04hx", data1); tlan_mii_read_reg(dev, phy, i + 2, &data2); - printk(" 0x%04hx", data2); tlan_mii_read_reg(dev, phy, i + 3, &data3); - printk(" 0x%04hx\n", data3); + pr_info(" 0x%02x 0x%04hx 0x%04hx 0x%04hx 0x%04hx\n", + i, data0, data1, data2, data3); } } else { - pr_info("TLAN: Device %s, Invalid PHY.\n", dev->name); + netdev_info(dev, "Invalid PHY\n"); } } @@ -2490,7 +2481,7 @@ static void tlan_phy_detect(struct net_device *dev) else if (priv->phy[0] != TLAN_PHY_NONE) priv->phy_num = 0; else - pr_info("TLAN: Cannot initialize device, no PHY was found!\n"); + netdev_info(dev, "Cannot initialize device, no PHY was found!\n"); } @@ -2618,8 +2609,7 @@ static void tlan_phy_start_link(struct net_device *dev) * but the card need additional time to start AN. * .5 sec should be plenty extra. */ - pr_info("TLAN: %s: Starting autonegotiation.\n", - dev->name); + netdev_info(dev, "Starting autonegotiation\n"); tlan_set_timer(dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN); return; } @@ -2682,16 +2672,16 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev) * more time. Perhaps we should fail after a while. */ if (!priv->neg_be_verbose++) { - pr_info("TLAN: Giving autonegotiation more time.\n"); - pr_info("TLAN: Please check that your adapter has\n"); - pr_info("TLAN: been properly connected to a HUB or Switch.\n"); - pr_info("TLAN: Trying to establish link in the background...\n"); + pr_info("Giving autonegotiation more time.\n"); + pr_info("Please check that your adapter has\n"); + pr_info("been properly connected to a HUB or Switch.\n"); + pr_info("Trying to establish link in the background...\n"); } tlan_set_timer(dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN); return; } - pr_info("TLAN: %s: Autonegotiation complete.\n", dev->name); + netdev_info(dev, "Autonegotiation complete\n"); tlan_mii_read_reg(dev, phy, MII_AN_ADV, &an_adv); tlan_mii_read_reg(dev, phy, MII_AN_LPA, &an_lpa); mode = an_adv & an_lpa & 0x03E0; @@ -2716,11 +2706,11 @@ static void tlan_phy_finish_auto_neg(struct net_device *dev) (an_adv & an_lpa & 0x0040)) { tlan_mii_write_reg(dev, phy, MII_GEN_CTL, MII_GC_AUTOENB | MII_GC_DUPLEX); - pr_info("TLAN: Starting internal PHY with FULL-DUPLEX\n"); + netdev_info(dev, "Starting internal PHY with FULL-DUPLEX\n"); } else { tlan_mii_write_reg(dev, phy, MII_GEN_CTL, MII_GC_AUTOENB); - pr_info("TLAN: Starting internal PHY with HALF-DUPLEX\n"); + netdev_info(dev, "Starting internal PHY with HALF-DUPLEX\n"); } } -- cgit v1.2.3 From 7542db8b1cb88ab15a85893d1dfb886e22b568e8 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 2 Mar 2011 17:50:35 +0000 Subject: mv643xx_eth: Use netdev_ and pr_ Use the current logging styles. Signed-off-by: Joe Perches Acked-by: Lennert Buytenhek Signed-off-by: David S. Miller --- drivers/net/mv643xx_eth.c | 74 +++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 02076e16542a..34425b94452f 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -35,6 +35,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -627,9 +629,8 @@ err: if ((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) != (RX_FIRST_DESC | RX_LAST_DESC)) { if (net_ratelimit()) - dev_printk(KERN_ERR, &mp->dev->dev, - "received packet spanning " - "multiple descriptors\n"); + netdev_err(mp->dev, + "received packet spanning multiple descriptors\n"); } if (cmd_sts & ERROR_SUMMARY) @@ -868,15 +869,14 @@ static netdev_tx_t mv643xx_eth_xmit(struct sk_buff *skb, struct net_device *dev) if (has_tiny_unaligned_frags(skb) && __skb_linearize(skb)) { txq->tx_dropped++; - dev_printk(KERN_DEBUG, &dev->dev, - "failed to linearize skb with tiny " - "unaligned fragment\n"); + netdev_printk(KERN_DEBUG, dev, + "failed to linearize skb with tiny unaligned fragment\n"); return NETDEV_TX_BUSY; } if (txq->tx_ring_size - txq->tx_desc_count < MAX_SKB_FRAGS + 1) { if (net_ratelimit()) - dev_printk(KERN_ERR, &dev->dev, "tx queue full?!\n"); + netdev_err(dev, "tx queue full?!\n"); kfree_skb(skb); return NETDEV_TX_OK; } @@ -959,7 +959,7 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force) skb = __skb_dequeue(&txq->tx_skb); if (cmd_sts & ERROR_SUMMARY) { - dev_printk(KERN_INFO, &mp->dev->dev, "tx error\n"); + netdev_info(mp->dev, "tx error\n"); mp->dev->stats.tx_errors++; } @@ -1122,20 +1122,20 @@ static int smi_bus_read(struct mii_bus *bus, int addr, int reg) int ret; if (smi_wait_ready(msp)) { - printk(KERN_WARNING "mv643xx_eth: SMI bus busy timeout\n"); + pr_warn("SMI bus busy timeout\n"); return -ETIMEDOUT; } writel(SMI_OPCODE_READ | (reg << 21) | (addr << 16), smi_reg); if (smi_wait_ready(msp)) { - printk(KERN_WARNING "mv643xx_eth: SMI bus busy timeout\n"); + pr_warn("SMI bus busy timeout\n"); return -ETIMEDOUT; } ret = readl(smi_reg); if (!(ret & SMI_READ_VALID)) { - printk(KERN_WARNING "mv643xx_eth: SMI bus read not valid\n"); + pr_warn("SMI bus read not valid\n"); return -ENODEV; } @@ -1148,7 +1148,7 @@ static int smi_bus_write(struct mii_bus *bus, int addr, int reg, u16 val) void __iomem *smi_reg = msp->base + SMI_REG; if (smi_wait_ready(msp)) { - printk(KERN_WARNING "mv643xx_eth: SMI bus busy timeout\n"); + pr_warn("SMI bus busy timeout\n"); return -ETIMEDOUT; } @@ -1156,7 +1156,7 @@ static int smi_bus_write(struct mii_bus *bus, int addr, int reg, u16 val) (addr << 16) | (val & 0xffff), smi_reg); if (smi_wait_ready(msp)) { - printk(KERN_WARNING "mv643xx_eth: SMI bus busy timeout\n"); + pr_warn("SMI bus busy timeout\n"); return -ETIMEDOUT; } @@ -1566,9 +1566,8 @@ mv643xx_eth_set_ringparam(struct net_device *dev, struct ethtool_ringparam *er) if (netif_running(dev)) { mv643xx_eth_stop(dev); if (mv643xx_eth_open(dev)) { - dev_printk(KERN_ERR, &dev->dev, - "fatal error on re-opening device after " - "ring param change\n"); + netdev_err(dev, + "fatal error on re-opening device after ring param change\n"); return -ENOMEM; } } @@ -1874,7 +1873,7 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index) } if (rxq->rx_desc_area == NULL) { - dev_printk(KERN_ERR, &mp->dev->dev, + netdev_err(mp->dev, "can't allocate rx ring (%d bytes)\n", size); goto out; } @@ -1884,8 +1883,7 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index) rxq->rx_skb = kmalloc(rxq->rx_ring_size * sizeof(*rxq->rx_skb), GFP_KERNEL); if (rxq->rx_skb == NULL) { - dev_printk(KERN_ERR, &mp->dev->dev, - "can't allocate rx skb ring\n"); + netdev_err(mp->dev, "can't allocate rx skb ring\n"); goto out_free; } @@ -1944,8 +1942,7 @@ static void rxq_deinit(struct rx_queue *rxq) } if (rxq->rx_desc_count) { - dev_printk(KERN_ERR, &mp->dev->dev, - "error freeing rx ring -- %d skbs stuck\n", + netdev_err(mp->dev, "error freeing rx ring -- %d skbs stuck\n", rxq->rx_desc_count); } @@ -1987,7 +1984,7 @@ static int txq_init(struct mv643xx_eth_private *mp, int index) } if (txq->tx_desc_area == NULL) { - dev_printk(KERN_ERR, &mp->dev->dev, + netdev_err(mp->dev, "can't allocate tx ring (%d bytes)\n", size); return -ENOMEM; } @@ -2093,7 +2090,7 @@ static void handle_link_event(struct mv643xx_eth_private *mp) if (netif_carrier_ok(dev)) { int i; - printk(KERN_INFO "%s: link down\n", dev->name); + netdev_info(dev, "link down\n"); netif_carrier_off(dev); @@ -2124,10 +2121,8 @@ static void handle_link_event(struct mv643xx_eth_private *mp) duplex = (port_status & FULL_DUPLEX) ? 1 : 0; fc = (port_status & FLOW_CONTROL_ENABLED) ? 1 : 0; - printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex, " - "flow control %sabled\n", dev->name, - speed, duplex ? "full" : "half", - fc ? "en" : "dis"); + netdev_info(dev, "link up, %d Mb/s, %s duplex, flow control %sabled\n", + speed, duplex ? "full" : "half", fc ? "en" : "dis"); if (!netif_carrier_ok(dev)) netif_carrier_on(dev); @@ -2337,7 +2332,7 @@ static int mv643xx_eth_open(struct net_device *dev) err = request_irq(dev->irq, mv643xx_eth_irq, IRQF_SHARED, dev->name, dev); if (err) { - dev_printk(KERN_ERR, &dev->dev, "can't assign irq\n"); + netdev_err(dev, "can't assign irq\n"); return -EAGAIN; } @@ -2483,9 +2478,8 @@ static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu) */ mv643xx_eth_stop(dev); if (mv643xx_eth_open(dev)) { - dev_printk(KERN_ERR, &dev->dev, - "fatal error on re-opening device after " - "MTU change\n"); + netdev_err(dev, + "fatal error on re-opening device after MTU change\n"); } return 0; @@ -2508,7 +2502,7 @@ static void mv643xx_eth_tx_timeout(struct net_device *dev) { struct mv643xx_eth_private *mp = netdev_priv(dev); - dev_printk(KERN_INFO, &dev->dev, "tx timeout\n"); + netdev_info(dev, "tx timeout\n"); schedule_work(&mp->tx_timeout_task); } @@ -2603,8 +2597,8 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev) int ret; if (!mv643xx_eth_version_printed++) - printk(KERN_NOTICE "MV-643xx 10/100/1000 ethernet " - "driver version %s\n", mv643xx_eth_driver_version); + pr_notice("MV-643xx 10/100/1000 ethernet driver version %s\n", + mv643xx_eth_driver_version); ret = -EINVAL; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -2871,14 +2865,12 @@ static int mv643xx_eth_probe(struct platform_device *pdev) pd = pdev->dev.platform_data; if (pd == NULL) { - dev_printk(KERN_ERR, &pdev->dev, - "no mv643xx_eth_platform_data\n"); + dev_err(&pdev->dev, "no mv643xx_eth_platform_data\n"); return -ENODEV; } if (pd->shared == NULL) { - dev_printk(KERN_ERR, &pdev->dev, - "no mv643xx_eth_platform_data->shared\n"); + dev_err(&pdev->dev, "no mv643xx_eth_platform_data->shared\n"); return -ENODEV; } @@ -2957,11 +2949,11 @@ static int mv643xx_eth_probe(struct platform_device *pdev) if (err) goto out; - dev_printk(KERN_NOTICE, &dev->dev, "port %d with MAC address %pM\n", - mp->port_num, dev->dev_addr); + netdev_notice(dev, "port %d with MAC address %pM\n", + mp->port_num, dev->dev_addr); if (mp->tx_desc_sram_size > 0) - dev_printk(KERN_NOTICE, &dev->dev, "configured with sram\n"); + netdev_notice(dev, "configured with sram\n"); return 0; -- cgit v1.2.3 From 967faf3b718e887301adb1636c2295f03d3c694f Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 3 Mar 2011 12:55:08 -0800 Subject: mii: Convert printks to netdev_info Add a bit more data to the output. Convert string speeds to integer. Object size reduced a tiny bit. $ size drivers/net/mii.o* text data bss dec hex filename 4155 56 1000 5211 145b drivers/net/mii.o.new 4184 56 1000 5240 1478 drivers/net/mii.o.old Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/mii.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/mii.c b/drivers/net/mii.c index 210b2b164b30..0a6c6a2e7550 100644 --- a/drivers/net/mii.c +++ b/drivers/net/mii.c @@ -354,7 +354,7 @@ unsigned int mii_check_media (struct mii_if_info *mii, if (!new_carrier) { netif_carrier_off(mii->dev); if (ok_to_print) - printk(KERN_INFO "%s: link down\n", mii->dev->name); + netdev_info(mii->dev, "link down\n"); return 0; /* duplex did not change */ } @@ -381,12 +381,12 @@ unsigned int mii_check_media (struct mii_if_info *mii, duplex = 1; if (ok_to_print) - printk(KERN_INFO "%s: link up, %sMbps, %s-duplex, lpa 0x%04X\n", - mii->dev->name, - lpa2 & (LPA_1000FULL | LPA_1000HALF) ? "1000" : - media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? "100" : "10", - duplex ? "full" : "half", - lpa); + netdev_info(mii->dev, "link up, %uMbps, %s-duplex, lpa 0x%04X\n", + lpa2 & (LPA_1000FULL | LPA_1000HALF) ? 1000 : + media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? + 100 : 10, + duplex ? "full" : "half", + lpa); if ((init_media) || (mii->full_duplex != duplex)) { mii->full_duplex = duplex; -- cgit v1.2.3 From 63f97425166a1a16279c1a5720e9dfcb2c12ad1b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 3 Mar 2011 13:30:20 -0800 Subject: eql: Convert printks to pr_ and netdev_ Add pr_fmt. Removed trailing "\n" from version, add back via pr_info("%s\n", version); Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/eql.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eql.c b/drivers/net/eql.c index 0cb1cf9cf4b0..a59cf961a436 100644 --- a/drivers/net/eql.c +++ b/drivers/net/eql.c @@ -111,6 +111,8 @@ * Sorry, I had to rewrite most of this for 2.5.x -DaveM */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -162,7 +164,7 @@ static void eql_timer(unsigned long param) } static const char version[] __initconst = - "Equalizer2002: Simon Janes (simon@ncm.com) and David S. Miller (davem@redhat.com)\n"; + "Equalizer2002: Simon Janes (simon@ncm.com) and David S. Miller (davem@redhat.com)"; static const struct net_device_ops eql_netdev_ops = { .ndo_open = eql_open, @@ -204,8 +206,8 @@ static int eql_open(struct net_device *dev) equalizer_t *eql = netdev_priv(dev); /* XXX We should force this off automatically for the user. */ - printk(KERN_INFO "%s: remember to turn off Van-Jacobson compression on " - "your slave devices.\n", dev->name); + netdev_info(dev, + "remember to turn off Van-Jacobson compression on your slave devices\n"); BUG_ON(!list_empty(&eql->queue.all_slaves)); @@ -591,7 +593,7 @@ static int __init eql_init_module(void) { int err; - printk(version); + pr_info("%s\n", version); dev_eql = alloc_netdev(sizeof(equalizer_t), "eql", eql_setup); if (!dev_eql) -- cgit v1.2.3 From 01a16b21d6adf992aa863186c3c4e561a57c1714 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Thu, 3 Mar 2011 13:32:07 -0800 Subject: netlink: kill eff_cap from struct netlink_skb_parms Netlink message processing in the kernel is synchronous these days, capabilities can be checked directly in security_netlink_recv() from the current process. Signed-off-by: Patrick McHardy Reviewed-by: James Morris [chrisw: update to include pohmelfs and uvesafb] Signed-off-by: Chris Wright Signed-off-by: David S. Miller --- drivers/block/drbd/drbd_nl.c | 2 +- drivers/md/dm-log-userspace-transfer.c | 2 +- drivers/staging/pohmelfs/config.c | 2 +- drivers/video/uvesafb.c | 2 +- include/linux/netlink.h | 1 - net/netlink/af_netlink.c | 6 ------ security/commoncap.c | 3 +-- 7 files changed, 5 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 8cbfaa687d72..fe81c851ca88 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -2177,7 +2177,7 @@ static void drbd_connector_callback(struct cn_msg *req, struct netlink_skb_parms return; } - if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN)) { + if (!cap_raised(current_cap(), CAP_SYS_ADMIN)) { retcode = ERR_PERM; goto fail; } diff --git a/drivers/md/dm-log-userspace-transfer.c b/drivers/md/dm-log-userspace-transfer.c index 049eaf12aaab..1f23e048f077 100644 --- a/drivers/md/dm-log-userspace-transfer.c +++ b/drivers/md/dm-log-userspace-transfer.c @@ -134,7 +134,7 @@ static void cn_ulog_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) { struct dm_ulog_request *tfr = (struct dm_ulog_request *)(msg + 1); - if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN)) + if (!cap_raised(current_cap(), CAP_SYS_ADMIN)) return; spin_lock(&receiving_list_lock); diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c index 89279ba1b737..39413b7d387d 100644 --- a/drivers/staging/pohmelfs/config.c +++ b/drivers/staging/pohmelfs/config.c @@ -525,7 +525,7 @@ static void pohmelfs_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *n { int err; - if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN)) + if (!cap_raised(current_cap(), CAP_SYS_ADMIN)) return; switch (msg->flags) { diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c index 52ec0959d462..5180a215d781 100644 --- a/drivers/video/uvesafb.c +++ b/drivers/video/uvesafb.c @@ -73,7 +73,7 @@ static void uvesafb_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *ns struct uvesafb_task *utask; struct uvesafb_ktask *task; - if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN)) + if (!cap_raised(current_cap(), CAP_SYS_ADMIN)) return; if (msg->seq >= UVESAFB_TASKS_MAX) diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 66823b862022..4c4ac3f3ce5a 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -160,7 +160,6 @@ struct netlink_skb_parms { struct ucred creds; /* Skb credentials */ __u32 pid; __u32 dst_group; - kernel_cap_t eff_cap; }; #define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb)) diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 97ecd923d7ee..a808fb1e877d 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1364,12 +1364,6 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, NETLINK_CB(skb).dst_group = dst_group; memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); - /* What can I do? Netlink is asynchronous, so that - we will have to save current capabilities to - check them, when this message will be delivered - to corresponding kernel module. --ANK (980802) - */ - err = -EFAULT; if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { kfree_skb(skb); diff --git a/security/commoncap.c b/security/commoncap.c index 64c2ed9c9015..a83e607d91c3 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -52,13 +52,12 @@ static void warn_setuid_and_fcaps_mixed(const char *fname) int cap_netlink_send(struct sock *sk, struct sk_buff *skb) { - NETLINK_CB(skb).eff_cap = current_cap(); return 0; } int cap_netlink_recv(struct sk_buff *skb, int cap) { - if (!cap_raised(NETLINK_CB(skb).eff_cap, cap)) + if (!cap_raised(current_cap(), cap)) return -EPERM; return 0; } -- cgit v1.2.3 From 73412c3854c877e5f37ad944ee8977addde4d35a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 4 Mar 2011 09:58:36 +1000 Subject: drm/nouveau: allocate kernel's notifier object at end of block The nv30/nv40 3d driver is about to start using DMA_FENCE from the 3D object which, it turns out, doesn't like its DMA object to not be aligned to a 4KiB boundary. Signed-off-by: Ben Skeggs Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nouveau_dma.c | 3 ++- drivers/gpu/drm/nouveau/nouveau_drv.h | 3 ++- drivers/gpu/drm/nouveau/nouveau_notifier.c | 11 +++++++---- 3 files changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index 65699bfaaaea..b368ed74aad7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -83,7 +83,8 @@ nouveau_dma_init(struct nouveau_channel *chan) return ret; /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */ - ret = nouveau_notifier_alloc(chan, NvNotify0, 32, &chan->m2mf_ntfy); + ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfd0, 0x1000, + &chan->m2mf_ntfy); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 9821fcacc3d2..982d70b12722 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -852,7 +852,8 @@ extern const struct ttm_mem_type_manager_func nouveau_vram_manager; extern int nouveau_notifier_init_channel(struct nouveau_channel *); extern void nouveau_notifier_takedown_channel(struct nouveau_channel *); extern int nouveau_notifier_alloc(struct nouveau_channel *, uint32_t handle, - int cout, uint32_t *offset); + int cout, uint32_t start, uint32_t end, + uint32_t *offset); extern int nouveau_notifier_offset(struct nouveau_gpuobj *, uint32_t *); extern int nouveau_ioctl_notifier_alloc(struct drm_device *, void *data, struct drm_file *); diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index fe29d604b820..5ea167623a82 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c @@ -96,7 +96,8 @@ nouveau_notifier_gpuobj_dtor(struct drm_device *dev, int nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, - int size, uint32_t *b_offset) + int size, uint32_t start, uint32_t end, + uint32_t *b_offset) { struct drm_device *dev = chan->dev; struct nouveau_gpuobj *nobj = NULL; @@ -104,9 +105,10 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, uint32_t offset; int target, ret; - mem = drm_mm_search_free(&chan->notifier_heap, size, 0, 0); + mem = drm_mm_search_free_in_range(&chan->notifier_heap, size, 0, + start, end, 0); if (mem) - mem = drm_mm_get_block(mem, size, 0); + mem = drm_mm_get_block_range(mem, size, 0, start, end); if (!mem) { NV_ERROR(dev, "Channel %d notifier block full\n", chan->id); return -ENOMEM; @@ -177,7 +179,8 @@ nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, if (IS_ERR(chan)) return PTR_ERR(chan); - ret = nouveau_notifier_alloc(chan, na->handle, na->size, &na->offset); + ret = nouveau_notifier_alloc(chan, na->handle, na->size, 0, 0x1000, + &na->offset); nouveau_channel_put(&chan); return ret; } -- cgit v1.2.3 From 65f0b417dee94f779ce9b77102b7d73c93723b39 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 22 Feb 2011 17:26:10 +0000 Subject: sfc: Use write-combining to reduce TX latency Based on work by Neil Turton and Kieran Mansley . The BIU has now been verified to handle 3- and 4-dword writes within a single 128-bit register correctly. This means we can enable write- combining and only insert write barriers between writes to distinct registers. This has been observed to save about 0.5 us when pushing a TX descriptor to an empty TX queue. Signed-off-by: Ben Hutchings --- drivers/net/sfc/efx.c | 4 ++-- drivers/net/sfc/io.h | 13 +++++++++---- drivers/net/sfc/mcdi.c | 9 +++++---- 3 files changed, 16 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index d563049859a8..b8bd936374f2 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -1104,8 +1104,8 @@ static int efx_init_io(struct efx_nic *efx) rc = -EIO; goto fail3; } - efx->membase = ioremap_nocache(efx->membase_phys, - efx->type->mem_map_size); + efx->membase = ioremap_wc(efx->membase_phys, + efx->type->mem_map_size); if (!efx->membase) { netif_err(efx, probe, efx->net_dev, "could not map memory BAR at %llx+%x\n", diff --git a/drivers/net/sfc/io.h b/drivers/net/sfc/io.h index dc45110b2456..d9d8c2ef1074 100644 --- a/drivers/net/sfc/io.h +++ b/drivers/net/sfc/io.h @@ -48,9 +48,9 @@ * replacing the low 96 bits with zero does not affect functionality. * - If the host writes to the last dword address of such a register * (i.e. the high 32 bits) the underlying register will always be - * written. If the collector does not hold values for the low 96 - * bits of the register, they will be written as zero. Writing to - * the last qword does not have this effect and must not be done. + * written. If the collector and the current write together do not + * provide values for all 128 bits of the register, the low 96 bits + * will be written as zero. * - If the host writes to the address of any other part of such a * register while the collector already holds values for some other * register, the write is discarded and the collector maintains its @@ -103,6 +103,7 @@ static inline void efx_writeo(struct efx_nic *efx, efx_oword_t *value, _efx_writed(efx, value->u32[2], reg + 8); _efx_writed(efx, value->u32[3], reg + 12); #endif + wmb(); mmiowb(); spin_unlock_irqrestore(&efx->biu_lock, flags); } @@ -125,6 +126,7 @@ static inline void efx_sram_writeq(struct efx_nic *efx, void __iomem *membase, __raw_writel((__force u32)value->u32[0], membase + addr); __raw_writel((__force u32)value->u32[1], membase + addr + 4); #endif + wmb(); mmiowb(); spin_unlock_irqrestore(&efx->biu_lock, flags); } @@ -139,6 +141,7 @@ static inline void efx_writed(struct efx_nic *efx, efx_dword_t *value, /* No lock required */ _efx_writed(efx, value->u32[0], reg); + wmb(); } /* Read a 128-bit CSR, locking as appropriate. */ @@ -237,12 +240,14 @@ static inline void _efx_writeo_page(struct efx_nic *efx, efx_oword_t *value, #ifdef EFX_USE_QWORD_IO _efx_writeq(efx, value->u64[0], reg + 0); + _efx_writeq(efx, value->u64[1], reg + 8); #else _efx_writed(efx, value->u32[0], reg + 0); _efx_writed(efx, value->u32[1], reg + 4); -#endif _efx_writed(efx, value->u32[2], reg + 8); _efx_writed(efx, value->u32[3], reg + 12); +#endif + wmb(); } #define efx_writeo_page(efx, value, reg, page) \ _efx_writeo_page(efx, value, \ diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c index 8bba8955f310..5e118f0d2479 100644 --- a/drivers/net/sfc/mcdi.c +++ b/drivers/net/sfc/mcdi.c @@ -94,14 +94,15 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd, efx_writed(efx, &hdr, pdu); - for (i = 0; i < inlen; i += 4) + for (i = 0; i < inlen; i += 4) { _efx_writed(efx, *((__le32 *)(inbuf + i)), pdu + 4 + i); - - /* Ensure the payload is written out before the header */ - wmb(); + /* use wmb() within loop to inhibit write combining */ + wmb(); + } /* ring the doorbell with a distinctive value */ _efx_writed(efx, (__force __le32) 0x45789abc, doorbell); + wmb(); } static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen) -- cgit v1.2.3 From 1ffe4dd126bcad84f0701ca271a7f10494d0c2c8 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 1 Mar 2011 13:53:02 -0500 Subject: rtlwifi: usb parts should depend on CONFIG_USB ERROR: "usb_unanchor_urb" [drivers/net/wireless/rtlwifi/rtlwifi.ko] undefined! ERROR: "usb_control_msg" [drivers/net/wireless/rtlwifi/rtlwifi.ko] undefined! ERROR: "usb_submit_urb" [drivers/net/wireless/rtlwifi/rtlwifi.ko] undefined! ERROR: "usb_get_dev" [drivers/net/wireless/rtlwifi/rtlwifi.ko] undefined! ERROR: "usb_kill_anchored_urbs" [drivers/net/wireless/rtlwifi/rtlwifi.ko] undefined! ERROR: "usb_put_dev" [drivers/net/wireless/rtlwifi/rtlwifi.ko] undefined! ERROR: "usb_free_urb" [drivers/net/wireless/rtlwifi/rtlwifi.ko] undefined! ERROR: "usb_anchor_urb" [drivers/net/wireless/rtlwifi/rtlwifi.ko] undefined! ERROR: "usb_alloc_urb" [drivers/net/wireless/rtlwifi/rtlwifi.ko] undefined! make[2]: *** [__modpost] Error 1 make[1]: *** [modules] Error 2 make: *** [sub-make] Error 2 The USB-part of rtlwifi should depend on CONFIG_USB. This also corrects the existing check for CONFIG_PCI to build pci.o. Reported-by: Geert Uytterhoeven Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/Makefile | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile index 9192fd583413..ec9393f24799 100644 --- a/drivers/net/wireless/rtlwifi/Makefile +++ b/drivers/net/wireless/rtlwifi/Makefile @@ -7,15 +7,18 @@ rtlwifi-objs := \ efuse.o \ ps.o \ rc.o \ - regd.o \ - usb.o + regd.o rtl8192c_common-objs += \ -ifeq ($(CONFIG_PCI),y) +ifneq ($(CONFIG_PCI),) rtlwifi-objs += pci.o endif +ifneq ($(CONFIG_USB),) +rtlwifi-objs += usb.o +endif + obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c/ obj-$(CONFIG_RTL8192CE) += rtl8192ce/ obj-$(CONFIG_RTL8192CU) += rtl8192cu/ -- cgit v1.2.3 From 6410db593e8c1b2b79a2f18554310d6da9415584 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 28 Feb 2011 23:36:09 -0600 Subject: rtl8187: Change rate-control feedback The driver for the RTL8187L chips returns IEEE80211_TX_STAT_ACK for all packets, even if the maximum number of retries was exhausted. In addition it fails to setup max_rates in the ieee80211_hw struct, This behavior may be responsible for the problems noted in Bug 14168. As the bug is very old, testers have not been found, and I do not have the case where the indicated signal is less than -70 dBm. Signed-off-by: Larry Finger Acked-by: Hin-Tak Leung Cc: Stable Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187/dev.c | 25 ++++++++++++++++++++----- drivers/net/wireless/rtl818x/rtl8187/rtl8187.h | 2 ++ 2 files changed, 22 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index c5a5e788f25f..1e0be14d10d4 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c @@ -869,23 +869,35 @@ static void rtl8187_work(struct work_struct *work) /* The RTL8187 returns the retry count through register 0xFFFA. In * addition, it appears to be a cumulative retry count, not the * value for the current TX packet. When multiple TX entries are - * queued, the retry count will be valid for the last one in the queue. - * The "error" should not matter for purposes of rate setting. */ + * waiting in the queue, the retry count will be the total for all. + * The "error" may matter for purposes of rate setting, but there is + * no other choice with this hardware. + */ struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv, work.work); struct ieee80211_tx_info *info; struct ieee80211_hw *dev = priv->dev; static u16 retry; u16 tmp; + u16 avg_retry; + int length; mutex_lock(&priv->conf_mutex); tmp = rtl818x_ioread16(priv, (__le16 *)0xFFFA); + length = skb_queue_len(&priv->b_tx_status.queue); + if (unlikely(!length)) + length = 1; + if (unlikely(tmp < retry)) + tmp = retry; + avg_retry = (tmp - retry) / length; while (skb_queue_len(&priv->b_tx_status.queue) > 0) { struct sk_buff *old_skb; old_skb = skb_dequeue(&priv->b_tx_status.queue); info = IEEE80211_SKB_CB(old_skb); - info->status.rates[0].count = tmp - retry + 1; + info->status.rates[0].count = avg_retry + 1; + if (info->status.rates[0].count > RETRY_COUNT) + info->flags &= ~IEEE80211_TX_STAT_ACK; ieee80211_tx_status_irqsafe(dev, old_skb); } retry = tmp; @@ -931,8 +943,8 @@ static int rtl8187_start(struct ieee80211_hw *dev) rtl818x_iowrite32(priv, &priv->map->TX_CONF, RTL818X_TX_CONF_HW_SEQNUM | RTL818X_TX_CONF_DISREQQSIZE | - (7 << 8 /* short retry limit */) | - (7 << 0 /* long retry limit */) | + (RETRY_COUNT << 8 /* short retry limit */) | + (RETRY_COUNT << 0 /* long retry limit */) | (7 << 21 /* MAX TX DMA */)); rtl8187_init_urbs(dev); rtl8187b_init_status_urb(dev); @@ -1376,6 +1388,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_RX_INCLUDES_FCS; + /* Initialize rate-control variables */ + dev->max_rates = 1; + dev->max_rate_tries = RETRY_COUNT; eeprom.data = dev; eeprom.register_read = rtl8187_eeprom_register_read; diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h index 0d7b1423f77b..f1cc90751dbf 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h +++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h @@ -35,6 +35,8 @@ #define RFKILL_MASK_8187_89_97 0x2 #define RFKILL_MASK_8198 0x4 +#define RETRY_COUNT 7 + struct rtl8187_rx_info { struct urb *urb; struct ieee80211_hw *dev; -- cgit v1.2.3 From 582d00641b03efa892b3d2cfe6b45c1fe6d422a1 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 1 Mar 2011 05:30:55 -0800 Subject: ath9k: Add a debugfs interface to dump chip registers //ieee80211/phyX/ath9k/regdump is the interface to dump the registers. Signed-off-by: Felix Fietkau Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 54 ++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 5cfcf8c235a4..d404aa0ac76a 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -15,6 +15,7 @@ */ #include +#include #include #include "ath9k.h" @@ -30,6 +31,19 @@ static int ath9k_debugfs_open(struct inode *inode, struct file *file) return 0; } +static ssize_t ath9k_debugfs_read_buf(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + u8 *buf = file->private_data; + return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); +} + +static int ath9k_debugfs_release_buf(struct inode *inode, struct file *file) +{ + vfree(file->private_data); + return 0; +} + #ifdef CONFIG_ATH_DEBUG static ssize_t read_file_debug(struct file *file, char __user *user_buf, @@ -1027,6 +1041,42 @@ static const struct file_operations fops_regval = { .llseek = default_llseek, }; +#define REGDUMP_LINE_SIZE 20 + +static int open_file_regdump(struct inode *inode, struct file *file) +{ + struct ath_softc *sc = inode->i_private; + unsigned int len = 0; + u8 *buf; + int i; + unsigned long num_regs, regdump_len, max_reg_offset; + + max_reg_offset = AR_SREV_9300_20_OR_LATER(sc->sc_ah) ? 0x16bd4 : 0xb500; + num_regs = max_reg_offset / 4 + 1; + regdump_len = num_regs * REGDUMP_LINE_SIZE + 1; + buf = vmalloc(regdump_len); + if (!buf) + return -ENOMEM; + + ath9k_ps_wakeup(sc); + for (i = 0; i < num_regs; i++) + len += scnprintf(buf + len, regdump_len - len, + "0x%06x 0x%08x\n", i << 2, REG_READ(sc->sc_ah, i << 2)); + ath9k_ps_restore(sc); + + file->private_data = buf; + + return 0; +} + +static const struct file_operations fops_regdump = { + .open = open_file_regdump, + .read = ath9k_debugfs_read_buf, + .release = ath9k_debugfs_release_buf, + .owner = THIS_MODULE, + .llseek = default_llseek,/* read accesses f_pos */ +}; + int ath9k_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); @@ -1091,6 +1141,10 @@ int ath9k_init_debug(struct ath_hw *ah) sc->debug.debugfs_phy, &ah->config.cwm_ignore_extcca)) goto err; + if (!debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, + sc, &fops_regdump)) + goto err; + sc->debug.regidx = 0; return 0; err: -- cgit v1.2.3 From b06af7a57de42707fee6eec784ee507960cc9131 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 1 Mar 2011 08:59:36 -0800 Subject: ath9k_hw: Read noise floor only for available chains for AR9003 Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 37 +++++++++++++++-------------- 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 8d60f4f09acc..eb250d6b8038 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -1020,28 +1020,29 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, static void ar9003_hw_do_getnf(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]) { - int16_t nf; - - nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR); - nfarray[0] = sign_extend32(nf, 8); - - nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR); - nfarray[1] = sign_extend32(nf, 8); +#define AR_PHY_CH_MINCCA_PWR 0x1FF00000 +#define AR_PHY_CH_MINCCA_PWR_S 20 +#define AR_PHY_CH_EXT_MINCCA_PWR 0x01FF0000 +#define AR_PHY_CH_EXT_MINCCA_PWR_S 16 - nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR); - nfarray[2] = sign_extend32(nf, 8); - - if (!IS_CHAN_HT40(ah->curchan)) - return; + int16_t nf; + int i; - nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); - nfarray[3] = sign_extend32(nf, 8); + for (i = 0; i < AR9300_MAX_CHAINS; i++) { + if (ah->rxchainmask & BIT(i)) { + nf = MS(REG_READ(ah, ah->nf_regs[i]), + AR_PHY_CH_MINCCA_PWR); + nfarray[i] = sign_extend32(nf, 8); - nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR); - nfarray[4] = sign_extend32(nf, 8); + if (IS_CHAN_HT40(ah->curchan)) { + u8 ext_idx = AR9300_MAX_CHAINS + i; - nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR); - nfarray[5] = sign_extend32(nf, 8); + nf = MS(REG_READ(ah, ah->nf_regs[ext_idx]), + AR_PHY_CH_EXT_MINCCA_PWR); + nfarray[ext_idx] = sign_extend32(nf, 8); + } + } + } } static void ar9003_hw_set_nf_limits(struct ath_hw *ah) -- cgit v1.2.3 From 0f4091b9af7151cf510bcf9160e970982c883101 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 1 Mar 2011 21:40:39 +0100 Subject: b43: N-PHY: rev3+: correct switching analog core MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 9f5a3c993239..6c9aa5a5850a 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -3878,10 +3878,14 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, } } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/Anacore */ static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on) { - b43_phy_write(dev, B43_NPHY_AFECTL_OVER, - on ? 0 : 0x7FFF); + u16 val = on ? 0 : 0x7FFF; + + if (dev->phy.rev >= 3) + b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, val); + b43_phy_write(dev, B43_NPHY_AFECTL_OVER, val); } static int b43_nphy_op_switch_channel(struct b43_wldev *dev, -- cgit v1.2.3 From 9838985162935a9db12962403808d43f3d225952 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 1 Mar 2011 21:40:40 +0100 Subject: b43: N-PHY: rev3+: add tables with gain ctl workarounds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/tables_nphy.c | 103 +++++++++++++++++++++++++++++++++ drivers/net/wireless/b43/tables_nphy.h | 25 ++++++++ 2 files changed, 128 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index c42b2acea24e..2de483b3d3ba 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -2709,6 +2709,79 @@ const struct nphy_rf_control_override_rev3 tbl_rf_control_override_rev3[] = { { 0x00C0, 6, 0xE7, 0xF9, 0xEC, 0xFB } /* field == 0x4000 (fls 15) */ }; +struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_workaround[2][3] = { + { /* 2GHz */ + { /* PHY rev 3 */ + { 7, 11, 16, 23 }, + { -5, 6, 10, 14 }, + { 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA }, + { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + 0x627E, + { 0x613F, 0x613F, 0x613F, 0x613F }, + 0x107E, 0x0066, 0x0074, + 0x18, 0x18, 0x18, + 0x020D, 0x5, + }, + { /* PHY rev 4 */ + { 8, 12, 17, 25 }, + { -5, 6, 10, 14 }, + { 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA }, + { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + 0x527E, + { 0x513F, 0x513F, 0x513F, 0x513F }, + 0x007E, 0x0066, 0x0074, + 0x18, 0x18, 0x18, + 0x01A1, 0x5, + }, + { /* PHY rev 5+ */ + { 9, 13, 18, 26 }, + { -3, 7, 11, 16 }, + { 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA, 0xA }, + { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + 0x427E, /* invalid for external LNA! */ + { 0x413F, 0x413F, 0x413F, 0x413F }, /* invalid for external LNA! */ + 0x1076, 0x0066, 0x106A, + 0xC, 0xC, 0xC, + 0x01D0, 0x5, + }, + }, + { /* 5GHz */ + { /* PHY rev 3 */ + { 7, 11, 17, 23 }, + { -6, 2, 6, 10 }, + { 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 }, + { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }, + 0x52DE, + { 0x516F, 0x516F, 0x516F, 0x516F }, + 0x00DE, 0x00CA, 0x00CC, + 0x1E, 0x1E, 0x1E, + 0x01A1, 25, + }, + { /* PHY rev 4 */ + { 8, 12, 18, 23 }, + { -5, 2, 6, 10 }, + { 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD }, + { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }, + 0x629E, + { 0x614F, 0x614F, 0x614F, 0x614F }, + 0x029E, 0x1084, 0x0086, + 0x24, 0x24, 0x24, + 0x0107, 25, + }, + { /* PHY rev 5+ */ + { 6, 10, 16, 21 }, + { -7, 0, 4, 8 }, + { 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD, 0xD }, + { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }, + 0x729E, + { 0x714F, 0x714F, 0x714F, 0x714F }, + 0x029E, 0x2084, 0x2086, + 0x24, 0x24, 0x24, + 0x00A9, 25, + }, + }, +}; + static inline void assert_ntab_array_sizes(void) { #undef check @@ -2957,3 +3030,33 @@ void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev) /* Volatile tables */ /* TODO */ } + +struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( + struct b43_wldev *dev, bool ghz5, bool ext_lna) +{ + struct nphy_gain_ctl_workaround_entry *e; + u8 phy_idx; + + B43_WARN_ON(dev->phy.rev < 3); + if (dev->phy.rev >= 5) + phy_idx = 2; + else if (dev->phy.rev == 4) + phy_idx = 1; + else + phy_idx = 0; + + e = &nphy_gain_ctl_workaround[ghz5][phy_idx]; + + /* Only one entry differs for external LNA, so instead making whole + * table 2 times bigger, hack is here + */ + if (!ghz5 && dev->phy.rev >= 5 && ext_lna) { + e->rfseq_init[0] &= 0x0FFF; + e->rfseq_init[1] &= 0x0FFF; + e->rfseq_init[2] &= 0x0FFF; + e->rfseq_init[3] &= 0x0FFF; + e->init_gain &= 0x0FFF; + } + + return e; +} diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 016a480b2dc6..18569367ce43 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h @@ -35,6 +35,31 @@ struct nphy_rf_control_override_rev3 { u8 val_addr1; }; +struct nphy_gain_ctl_workaround_entry { + s8 lna1_gain[4]; + s8 lna2_gain[4]; + u8 gain_db[10]; + u8 gain_bits[10]; + + u16 init_gain; + u16 rfseq_init[4]; + + u16 cliphi_gain; + u16 clipmd_gain; + u16 cliplo_gain; + + u16 crsmin; + u16 crsminl; + u16 crsminu; + + u16 nbclip; + u16 wlclip; +}; + +/* Get entry with workaround values for gain ctl. Does not return NULL. */ +struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( + struct b43_wldev *dev, bool ghz5, bool ext_lna); + /* Get the NPHY Channel Switch Table entry for a channel. * Returns NULL on failure to find an entry. */ const struct b43_nphy_channeltab_entry_rev2 * -- cgit v1.2.3 From ba9a6214539df3e647d8259b101dbc60216ecc31 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 1 Mar 2011 21:40:41 +0100 Subject: b43: N-PHY: rev3+: implement gain ctl workarounds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 171 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 162 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 6c9aa5a5850a..8a00f9a95dbb 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1168,23 +1168,98 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev) static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) { struct b43_phy_n *nphy = dev->phy.n; + struct ssb_sprom *sprom = &(dev->dev->bus->sprom); + + /* PHY rev 0, 1, 2 */ u8 i, j; u8 code; u16 tmp; + u8 rfseq_events[3] = { 6, 8, 7 }; + u8 rfseq_delays[3] = { 10, 30, 1 }; - /* TODO: for PHY >= 3 - s8 *lna1_gain, *lna2_gain; - u8 *gain_db, *gain_bits; - u16 *rfseq_init; + /* PHY rev >= 3 */ + bool ghz5; + bool ext_lna; + u16 rssi_gain; + struct nphy_gain_ctl_workaround_entry *e; u8 lpf_gain[6] = { 0x00, 0x06, 0x0C, 0x12, 0x12, 0x12 }; u8 lpf_bits[6] = { 0, 1, 2, 3, 3, 3 }; - */ - - u8 rfseq_events[3] = { 6, 8, 7 }; - u8 rfseq_delays[3] = { 10, 30, 1 }; if (dev->phy.rev >= 3) { - /* TODO */ + /* Prepare values */ + ghz5 = b43_phy_read(dev, B43_NPHY_BANDCTL) + & B43_NPHY_BANDCTL_5GHZ; + ext_lna = sprom->boardflags_lo & B43_BFL_EXTLNA; + e = b43_nphy_get_gain_ctl_workaround_ent(dev, ghz5, ext_lna); + if (ghz5 && dev->phy.rev >= 5) + rssi_gain = 0x90; + else + rssi_gain = 0x50; + + b43_phy_set(dev, B43_NPHY_RXCTL, 0x0040); + + /* Set Clip 2 detect */ + b43_phy_set(dev, B43_NPHY_C1_CGAINI, + B43_NPHY_C1_CGAINI_CL2DETECT); + b43_phy_set(dev, B43_NPHY_C2_CGAINI, + B43_NPHY_C2_CGAINI_CL2DETECT); + + b43_radio_write(dev, B2056_RX0 | B2056_RX_BIASPOLE_LNAG1_IDAC, + 0x17); + b43_radio_write(dev, B2056_RX1 | B2056_RX_BIASPOLE_LNAG1_IDAC, + 0x17); + b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAG2_IDAC, 0xF0); + b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAG2_IDAC, 0xF0); + b43_radio_write(dev, B2056_RX0 | B2056_RX_RSSI_POLE, 0x00); + b43_radio_write(dev, B2056_RX1 | B2056_RX_RSSI_POLE, 0x00); + b43_radio_write(dev, B2056_RX0 | B2056_RX_RSSI_GAIN, + rssi_gain); + b43_radio_write(dev, B2056_RX1 | B2056_RX_RSSI_GAIN, + rssi_gain); + b43_radio_write(dev, B2056_RX0 | B2056_RX_BIASPOLE_LNAA1_IDAC, + 0x17); + b43_radio_write(dev, B2056_RX1 | B2056_RX_BIASPOLE_LNAA1_IDAC, + 0x17); + b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAA2_IDAC, 0xFF); + b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAA2_IDAC, 0xFF); + + b43_ntab_write_bulk(dev, B43_NTAB8(0, 8), 4, e->lna1_gain); + b43_ntab_write_bulk(dev, B43_NTAB8(1, 8), 4, e->lna1_gain); + b43_ntab_write_bulk(dev, B43_NTAB8(0, 16), 4, e->lna2_gain); + b43_ntab_write_bulk(dev, B43_NTAB8(1, 16), 4, e->lna2_gain); + b43_ntab_write_bulk(dev, B43_NTAB8(0, 32), 10, e->gain_db); + b43_ntab_write_bulk(dev, B43_NTAB8(1, 32), 10, e->gain_db); + b43_ntab_write_bulk(dev, B43_NTAB8(2, 32), 10, e->gain_bits); + b43_ntab_write_bulk(dev, B43_NTAB8(3, 32), 10, e->gain_bits); + b43_ntab_write_bulk(dev, B43_NTAB8(0, 0x40), 6, lpf_gain); + b43_ntab_write_bulk(dev, B43_NTAB8(1, 0x40), 6, lpf_gain); + b43_ntab_write_bulk(dev, B43_NTAB8(2, 0x40), 6, lpf_bits); + b43_ntab_write_bulk(dev, B43_NTAB8(3, 0x40), 6, lpf_bits); + + b43_phy_write(dev, B43_NPHY_C1_INITGAIN, e->init_gain); + b43_phy_write(dev, 0x2A7, e->init_gain); + b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x106), 2, + e->rfseq_init); + b43_phy_write(dev, B43_NPHY_C1_INITGAIN, e->init_gain); + + /* TODO: check defines. Do not match variables names */ + b43_phy_write(dev, B43_NPHY_C1_CLIP1_MEDGAIN, e->cliphi_gain); + b43_phy_write(dev, 0x2A9, e->cliphi_gain); + b43_phy_write(dev, B43_NPHY_C1_CLIP2_GAIN, e->clipmd_gain); + b43_phy_write(dev, 0x2AB, e->clipmd_gain); + b43_phy_write(dev, B43_NPHY_C2_CLIP1_HIGAIN, e->cliplo_gain); + b43_phy_write(dev, 0x2AD, e->cliplo_gain); + + b43_phy_maskset(dev, 0x27D, 0xFF00, e->crsmin); + b43_phy_maskset(dev, 0x280, 0xFF00, e->crsminl); + b43_phy_maskset(dev, 0x283, 0xFF00, e->crsminu); + b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, e->nbclip); + b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, e->nbclip); + b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES, + ~B43_NPHY_C1_CLIPWBTHRES_CLIP2, e->wlclip); + b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES, + ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, e->wlclip); + b43_phy_write(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C); } else { /* Set Clip 2 detect */ b43_phy_set(dev, B43_NPHY_C1_CGAINI, @@ -1308,6 +1383,9 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 }; u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 }; + u16 tmp16; + u32 tmp32; + if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) b43_nphy_classifier(dev, 1, 0); else @@ -1320,7 +1398,82 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); if (dev->phy.rev >= 3) { + tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0)); + tmp32 &= 0xffffff; + b43_ntab_write(dev, B43_NTAB32(30, 0), tmp32); + + b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x0125); + b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x01B3); + b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x0105); + b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x016E); + b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0x00CD); + b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x0020); + + b43_phy_write(dev, B43_NPHY_C2_CLIP1_MEDGAIN, 0x000C); + b43_phy_write(dev, 0x2AE, 0x000C); + + /* TODO */ + + tmp16 = (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) ? + 0x2 : 0x9C40; + b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, tmp16); + + b43_phy_maskset(dev, 0x294, 0xF0FF, 0x0700); + + b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D); + b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D); + + b43_nphy_gain_ctrl_workarounds(dev); + + b43_ntab_write(dev, B43_NTAB32(8, 0), 2); + b43_ntab_write(dev, B43_NTAB32(8, 16), 2); + /* TODO */ + + b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_MAST_BIAS, 0x00); + b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_MAST_BIAS, 0x00); + b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_MAIN, 0x06); + b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_MAIN, 0x06); + b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_AUX, 0x07); + b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_AUX, 0x07); + b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_LOB_BIAS, 0x88); + b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_LOB_BIAS, 0x88); + b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXG_CMFB_IDAC, 0x00); + b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXG_CMFB_IDAC, 0x00); + + /* N PHY WAR TX Chain Update with hw_phytxchain as argument */ + + if ((bus->sprom.boardflags2_lo & B43_BFL2_APLL_WAR && + b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) || + (bus->sprom.boardflags2_lo & B43_BFL2_GPLL_WAR && + b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) + tmp32 = 0x00088888; + else + tmp32 = 0x88888888; + b43_ntab_write(dev, B43_NTAB32(30, 1), tmp32); + b43_ntab_write(dev, B43_NTAB32(30, 2), tmp32); + b43_ntab_write(dev, B43_NTAB32(30, 3), tmp32); + + if (dev->phy.rev == 4 && + b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { + b43_radio_write(dev, B2056_TX0 | B2056_TX_GMBB_IDAC, + 0x70); + b43_radio_write(dev, B2056_TX1 | B2056_TX_GMBB_IDAC, + 0x70); + } + + b43_phy_write(dev, 0x224, 0x039C); + b43_phy_write(dev, 0x225, 0x0357); + b43_phy_write(dev, 0x226, 0x0317); + b43_phy_write(dev, 0x227, 0x02D7); + b43_phy_write(dev, 0x228, 0x039C); + b43_phy_write(dev, 0x229, 0x0357); + b43_phy_write(dev, 0x22A, 0x0317); + b43_phy_write(dev, 0x22B, 0x02D7); + b43_phy_write(dev, 0x22C, 0x039C); + b43_phy_write(dev, 0x22D, 0x0357); + b43_phy_write(dev, 0x22E, 0x0317); + b43_phy_write(dev, 0x22F, 0x02D7); } else { if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ && nphy->band5g_pwrgain) { -- cgit v1.2.3 From adde5882bc6c21de7ee80ee15dfd58c7e9a472ac Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Thu, 3 Mar 2011 11:46:45 +0100 Subject: rt2x00: fix whitespace damage in the rt2800 specific code The rt2800 specific code contains a lots of whitespace damage caused by the commit 'rt2x00: Add support for RT5390 chip'. This patch fixes those whitespace errors. Signed-off-by: Gabor Juhos Acked-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 40 +- drivers/net/wireless/rt2x00/rt2800lib.c | 693 ++++++++++++++++---------------- drivers/net/wireless/rt2x00/rt2800pci.c | 14 +- 3 files changed, 378 insertions(+), 369 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 6f4a2432c021..70b9abbdeb9e 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -66,7 +66,7 @@ #define RF3320 0x000b #define RF3322 0x000c #define RF3853 0x000d -#define RF5390 0x5390 +#define RF5390 0x5390 /* * Chipset revisions. @@ -79,7 +79,7 @@ #define REV_RT3071E 0x0211 #define REV_RT3090E 0x0211 #define REV_RT3390E 0x0211 -#define REV_RT5390F 0x0502 +#define REV_RT5390F 0x0502 /* * Signal information. @@ -126,9 +126,9 @@ /* * AUX_CTRL: Aux/PCI-E related configuration */ -#define AUX_CTRL 0x10c -#define AUX_CTRL_WAKE_PCIE_EN FIELD32(0x00000002) -#define AUX_CTRL_FORCE_PCIE_CLK FIELD32(0x00000400) +#define AUX_CTRL 0x10c +#define AUX_CTRL_WAKE_PCIE_EN FIELD32(0x00000002) +#define AUX_CTRL_FORCE_PCIE_CLK FIELD32(0x00000400) /* * OPT_14: Unknown register used by rt3xxx devices. @@ -464,7 +464,7 @@ */ #define RF_CSR_CFG 0x0500 #define RF_CSR_CFG_DATA FIELD32(0x000000ff) -#define RF_CSR_CFG_REGNUM FIELD32(0x00003f00) +#define RF_CSR_CFG_REGNUM FIELD32(0x00003f00) #define RF_CSR_CFG_WRITE FIELD32(0x00010000) #define RF_CSR_CFG_BUSY FIELD32(0x00020000) @@ -1746,13 +1746,13 @@ struct mac_iveiv_entry { */ #define BBP4_TX_BF FIELD8(0x01) #define BBP4_BANDWIDTH FIELD8(0x18) -#define BBP4_MAC_IF_CTRL FIELD8(0x40) +#define BBP4_MAC_IF_CTRL FIELD8(0x40) /* * BBP 109 */ -#define BBP109_TX0_POWER FIELD8(0x0f) -#define BBP109_TX1_POWER FIELD8(0xf0) +#define BBP109_TX0_POWER FIELD8(0x0f) +#define BBP109_TX1_POWER FIELD8(0xf0) /* * BBP 138: Unknown @@ -1765,7 +1765,7 @@ struct mac_iveiv_entry { /* * BBP 152: Rx Ant */ -#define BBP152_RX_DEFAULT_ANT FIELD8(0x80) +#define BBP152_RX_DEFAULT_ANT FIELD8(0x80) /* * RFCSR registers @@ -1776,7 +1776,7 @@ struct mac_iveiv_entry { * RFCSR 1: */ #define RFCSR1_RF_BLOCK_EN FIELD8(0x01) -#define RFCSR1_PLL_PD FIELD8(0x02) +#define RFCSR1_PLL_PD FIELD8(0x02) #define RFCSR1_RX0_PD FIELD8(0x04) #define RFCSR1_TX0_PD FIELD8(0x08) #define RFCSR1_RX1_PD FIELD8(0x10) @@ -1785,7 +1785,7 @@ struct mac_iveiv_entry { /* * RFCSR 2: */ -#define RFCSR2_RESCAL_EN FIELD8(0x80) +#define RFCSR2_RESCAL_EN FIELD8(0x80) /* * RFCSR 6: @@ -1801,7 +1801,7 @@ struct mac_iveiv_entry { /* * RFCSR 11: */ -#define RFCSR11_R FIELD8(0x03) +#define RFCSR11_R FIELD8(0x03) /* * RFCSR 12: @@ -1857,9 +1857,9 @@ struct mac_iveiv_entry { /* * RFCSR 30: */ -#define RFCSR30_TX_H20M FIELD8(0x02) -#define RFCSR30_RX_H20M FIELD8(0x04) -#define RFCSR30_RX_VCM FIELD8(0x18) +#define RFCSR30_TX_H20M FIELD8(0x02) +#define RFCSR30_RX_H20M FIELD8(0x04) +#define RFCSR30_RX_VCM FIELD8(0x18) #define RFCSR30_RF_CALIBRATION FIELD8(0x80) /* @@ -1871,17 +1871,17 @@ struct mac_iveiv_entry { /* * RFCSR 38: */ -#define RFCSR38_RX_LO1_EN FIELD8(0x20) +#define RFCSR38_RX_LO1_EN FIELD8(0x20) /* * RFCSR 39: */ -#define RFCSR39_RX_LO2_EN FIELD8(0x80) +#define RFCSR39_RX_LO2_EN FIELD8(0x80) /* * RFCSR 49: */ -#define RFCSR49_TX FIELD8(0x3f) +#define RFCSR49_TX FIELD8(0x3f) /* * RF registers @@ -1918,7 +1918,7 @@ struct mac_iveiv_entry { /* * Chip ID */ -#define EEPROM_CHIP_ID 0x0000 +#define EEPROM_CHIP_ID 0x0000 /* * EEPROM Version diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 3da78bf0ca26..dbee3f12d636 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -400,15 +400,15 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, if (rt2800_wait_csr_ready(rt2x00dev)) return -EBUSY; - if (rt2x00_is_pci(rt2x00dev)) { - if (rt2x00_rt(rt2x00dev, RT5390)) { - rt2800_register_read(rt2x00dev, AUX_CTRL, ®); - rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); - rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); - rt2800_register_write(rt2x00dev, AUX_CTRL, reg); - } + if (rt2x00_is_pci(rt2x00dev)) { + if (rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_register_read(rt2x00dev, AUX_CTRL, ®); + rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); + rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); + rt2800_register_write(rt2x00dev, AUX_CTRL, reg); + } rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); - } + } /* * Disable DMA, will be reenabled later when enabling @@ -1585,92 +1585,98 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, #define RT5390_FREQ_OFFSET_BOUND 0x5f static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, - struct ieee80211_conf *conf, - struct rf_channel *rf, - struct channel_info *info) -{ - u8 rfcsr; - u16 eeprom; - - rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); - rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); - rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR11_R, rf->rf2); - rt2800_rfcsr_write(rt2x00dev, 11, rfcsr); - - rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr); - if (info->default_power1 > RT5390_POWER_BOUND) - rt2x00_set_field8(&rfcsr, RFCSR49_TX, RT5390_POWER_BOUND); - else - rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); - rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); - - rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); - rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1); - rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); - rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); - rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); - - rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); - if (rt2x00dev->freq_offset > RT5390_FREQ_OFFSET_BOUND) - rt2x00_set_field8(&rfcsr, RFCSR17_CODE, RT5390_FREQ_OFFSET_BOUND); - else - rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); - rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); - - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); - if (rf->channel <= 14) { - int idx = rf->channel-1; - - if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) { - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { - /* r55/r59 value array of channel 1~14 */ - static const char r55_bt_rev[] = {0x83, 0x83, - 0x83, 0x73, 0x73, 0x63, 0x53, 0x53, - 0x53, 0x43, 0x43, 0x43, 0x43, 0x43}; - static const char r59_bt_rev[] = {0x0e, 0x0e, - 0x0e, 0x0e, 0x0e, 0x0b, 0x0a, 0x09, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07}; - - rt2800_rfcsr_write(rt2x00dev, 55, r55_bt_rev[idx]); - rt2800_rfcsr_write(rt2x00dev, 59, r59_bt_rev[idx]); - } else { - static const char r59_bt[] = {0x8b, 0x8b, 0x8b, - 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x89, - 0x88, 0x88, 0x86, 0x85, 0x84}; - - rt2800_rfcsr_write(rt2x00dev, 59, r59_bt[idx]); - } - } else { - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { - static const char r55_nonbt_rev[] = {0x23, 0x23, - 0x23, 0x23, 0x13, 0x13, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}; - static const char r59_nonbt_rev[] = {0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x06, 0x05, 0x04, 0x04}; - - rt2800_rfcsr_write(rt2x00dev, 55, r55_nonbt_rev[idx]); - rt2800_rfcsr_write(rt2x00dev, 59, r59_nonbt_rev[idx]); - } else if (rt2x00_rt(rt2x00dev, RT5390)) { - static const char r59_non_bt[] = {0x8f, 0x8f, - 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, - 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86}; - - rt2800_rfcsr_write(rt2x00dev, 59, r59_non_bt[idx]); - } - } - } - - rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0); - rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0); - rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); - - rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); - rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); + struct ieee80211_conf *conf, + struct rf_channel *rf, + struct channel_info *info) +{ + u8 rfcsr; + u16 eeprom; + + rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); + rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); + rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR11_R, rf->rf2); + rt2800_rfcsr_write(rt2x00dev, 11, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr); + if (info->default_power1 > RT5390_POWER_BOUND) + rt2x00_set_field8(&rfcsr, RFCSR49_TX, RT5390_POWER_BOUND); + else + rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); + rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); + rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1); + rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); + rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); + rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); + if (rt2x00dev->freq_offset > RT5390_FREQ_OFFSET_BOUND) + rt2x00_set_field8(&rfcsr, RFCSR17_CODE, + RT5390_FREQ_OFFSET_BOUND); + else + rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); + rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); + + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); + if (rf->channel <= 14) { + int idx = rf->channel-1; + + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) { + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { + /* r55/r59 value array of channel 1~14 */ + static const char r55_bt_rev[] = {0x83, 0x83, + 0x83, 0x73, 0x73, 0x63, 0x53, 0x53, + 0x53, 0x43, 0x43, 0x43, 0x43, 0x43}; + static const char r59_bt_rev[] = {0x0e, 0x0e, + 0x0e, 0x0e, 0x0e, 0x0b, 0x0a, 0x09, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07}; + + rt2800_rfcsr_write(rt2x00dev, 55, + r55_bt_rev[idx]); + rt2800_rfcsr_write(rt2x00dev, 59, + r59_bt_rev[idx]); + } else { + static const char r59_bt[] = {0x8b, 0x8b, 0x8b, + 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x89, + 0x88, 0x88, 0x86, 0x85, 0x84}; + + rt2800_rfcsr_write(rt2x00dev, 59, r59_bt[idx]); + } + } else { + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { + static const char r55_nonbt_rev[] = {0x23, 0x23, + 0x23, 0x23, 0x13, 0x13, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}; + static const char r59_nonbt_rev[] = {0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x06, 0x05, 0x04, 0x04}; + + rt2800_rfcsr_write(rt2x00dev, 55, + r55_nonbt_rev[idx]); + rt2800_rfcsr_write(rt2x00dev, 59, + r59_nonbt_rev[idx]); + } else if (rt2x00_rt(rt2x00dev, RT5390)) { + static const char r59_non_bt[] = {0x8f, 0x8f, + 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, + 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86}; + + rt2800_rfcsr_write(rt2x00dev, 59, + r59_non_bt[idx]); + } + } + } + + rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0); + rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); + rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); } static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, @@ -1697,8 +1703,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2x00_rf(rt2x00dev, RF3052) || rt2x00_rf(rt2x00dev, RF3320)) rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); - else if (rt2x00_rf(rt2x00dev, RF5390)) - rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); + else if (rt2x00_rf(rt2x00dev, RF5390)) + rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); else rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); @@ -1711,14 +1717,15 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2800_bbp_write(rt2x00dev, 86, 0); if (rf->channel <= 14) { - if (!rt2x00_rt(rt2x00dev, RT5390)) { - if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) { - rt2800_bbp_write(rt2x00dev, 82, 0x62); - rt2800_bbp_write(rt2x00dev, 75, 0x46); - } else { - rt2800_bbp_write(rt2x00dev, 82, 0x84); - rt2800_bbp_write(rt2x00dev, 75, 0x50); - } + if (!rt2x00_rt(rt2x00dev, RT5390)) { + if (test_bit(CONFIG_EXTERNAL_LNA_BG, + &rt2x00dev->flags)) { + rt2800_bbp_write(rt2x00dev, 82, 0x62); + rt2800_bbp_write(rt2x00dev, 75, 0x46); + } else { + rt2800_bbp_write(rt2x00dev, 82, 0x84); + rt2800_bbp_write(rt2x00dev, 75, 0x50); + } } } else { rt2800_bbp_write(rt2x00dev, 82, 0xf2); @@ -2097,8 +2104,8 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev) if (rt2x00_rt(rt2x00dev, RT3070) || rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090) || - rt2x00_rt(rt2x00dev, RT3390) || - rt2x00_rt(rt2x00dev, RT5390)) + rt2x00_rt(rt2x00dev, RT3390) || + rt2x00_rt(rt2x00dev, RT5390)) return 0x1c + (2 * rt2x00dev->lna_gain); else return 0x2e + rt2x00dev->lna_gain; @@ -2230,10 +2237,10 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x0000001f); - } else if (rt2x00_rt(rt2x00dev, RT5390)) { - rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); - rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); - rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); + } else if (rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); + rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); + rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); } else { rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); @@ -2609,31 +2616,31 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_wait_bbp_ready(rt2x00dev))) return -EACCES; - if (rt2x00_rt(rt2x00dev, RT5390)) { - rt2800_bbp_read(rt2x00dev, 4, &value); - rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1); - rt2800_bbp_write(rt2x00dev, 4, value); - } + if (rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_bbp_read(rt2x00dev, 4, &value); + rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1); + rt2800_bbp_write(rt2x00dev, 4, value); + } - if (rt2800_is_305x_soc(rt2x00dev) || - rt2x00_rt(rt2x00dev, RT5390)) + if (rt2800_is_305x_soc(rt2x00dev) || + rt2x00_rt(rt2x00dev, RT5390)) rt2800_bbp_write(rt2x00dev, 31, 0x08); rt2800_bbp_write(rt2x00dev, 65, 0x2c); rt2800_bbp_write(rt2x00dev, 66, 0x38); - if (rt2x00_rt(rt2x00dev, RT5390)) - rt2800_bbp_write(rt2x00dev, 68, 0x0b); + if (rt2x00_rt(rt2x00dev, RT5390)) + rt2800_bbp_write(rt2x00dev, 68, 0x0b); if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) { rt2800_bbp_write(rt2x00dev, 69, 0x16); rt2800_bbp_write(rt2x00dev, 73, 0x12); - } else if (rt2x00_rt(rt2x00dev, RT5390)) { - rt2800_bbp_write(rt2x00dev, 69, 0x12); - rt2800_bbp_write(rt2x00dev, 73, 0x13); - rt2800_bbp_write(rt2x00dev, 75, 0x46); - rt2800_bbp_write(rt2x00dev, 76, 0x28); - rt2800_bbp_write(rt2x00dev, 77, 0x59); + } else if (rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_bbp_write(rt2x00dev, 69, 0x12); + rt2800_bbp_write(rt2x00dev, 73, 0x13); + rt2800_bbp_write(rt2x00dev, 75, 0x46); + rt2800_bbp_write(rt2x00dev, 76, 0x28); + rt2800_bbp_write(rt2x00dev, 77, 0x59); } else { rt2800_bbp_write(rt2x00dev, 69, 0x12); rt2800_bbp_write(rt2x00dev, 73, 0x10); @@ -2644,8 +2651,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) if (rt2x00_rt(rt2x00dev, RT3070) || rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090) || - rt2x00_rt(rt2x00dev, RT3390) || - rt2x00_rt(rt2x00dev, RT5390)) { + rt2x00_rt(rt2x00dev, RT3390) || + rt2x00_rt(rt2x00dev, RT5390)) { rt2800_bbp_write(rt2x00dev, 79, 0x13); rt2800_bbp_write(rt2x00dev, 80, 0x05); rt2800_bbp_write(rt2x00dev, 81, 0x33); @@ -2657,62 +2664,62 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) } rt2800_bbp_write(rt2x00dev, 82, 0x62); - if (rt2x00_rt(rt2x00dev, RT5390)) - rt2800_bbp_write(rt2x00dev, 83, 0x7a); - else - rt2800_bbp_write(rt2x00dev, 83, 0x6a); + if (rt2x00_rt(rt2x00dev, RT5390)) + rt2800_bbp_write(rt2x00dev, 83, 0x7a); + else + rt2800_bbp_write(rt2x00dev, 83, 0x6a); if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D)) rt2800_bbp_write(rt2x00dev, 84, 0x19); - else if (rt2x00_rt(rt2x00dev, RT5390)) - rt2800_bbp_write(rt2x00dev, 84, 0x9a); + else if (rt2x00_rt(rt2x00dev, RT5390)) + rt2800_bbp_write(rt2x00dev, 84, 0x9a); else rt2800_bbp_write(rt2x00dev, 84, 0x99); - if (rt2x00_rt(rt2x00dev, RT5390)) - rt2800_bbp_write(rt2x00dev, 86, 0x38); - else - rt2800_bbp_write(rt2x00dev, 86, 0x00); + if (rt2x00_rt(rt2x00dev, RT5390)) + rt2800_bbp_write(rt2x00dev, 86, 0x38); + else + rt2800_bbp_write(rt2x00dev, 86, 0x00); rt2800_bbp_write(rt2x00dev, 91, 0x04); - if (rt2x00_rt(rt2x00dev, RT5390)) - rt2800_bbp_write(rt2x00dev, 92, 0x02); - else - rt2800_bbp_write(rt2x00dev, 92, 0x00); + if (rt2x00_rt(rt2x00dev, RT5390)) + rt2800_bbp_write(rt2x00dev, 92, 0x02); + else + rt2800_bbp_write(rt2x00dev, 92, 0x00); if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) || rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) || rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) || rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) || - rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5390) || rt2800_is_305x_soc(rt2x00dev)) rt2800_bbp_write(rt2x00dev, 103, 0xc0); else rt2800_bbp_write(rt2x00dev, 103, 0x00); - if (rt2x00_rt(rt2x00dev, RT5390)) - rt2800_bbp_write(rt2x00dev, 104, 0x92); + if (rt2x00_rt(rt2x00dev, RT5390)) + rt2800_bbp_write(rt2x00dev, 104, 0x92); if (rt2800_is_305x_soc(rt2x00dev)) rt2800_bbp_write(rt2x00dev, 105, 0x01); - else if (rt2x00_rt(rt2x00dev, RT5390)) - rt2800_bbp_write(rt2x00dev, 105, 0x3c); + else if (rt2x00_rt(rt2x00dev, RT5390)) + rt2800_bbp_write(rt2x00dev, 105, 0x3c); else rt2800_bbp_write(rt2x00dev, 105, 0x05); - if (rt2x00_rt(rt2x00dev, RT5390)) - rt2800_bbp_write(rt2x00dev, 106, 0x03); - else - rt2800_bbp_write(rt2x00dev, 106, 0x35); + if (rt2x00_rt(rt2x00dev, RT5390)) + rt2800_bbp_write(rt2x00dev, 106, 0x03); + else + rt2800_bbp_write(rt2x00dev, 106, 0x35); - if (rt2x00_rt(rt2x00dev, RT5390)) - rt2800_bbp_write(rt2x00dev, 128, 0x12); + if (rt2x00_rt(rt2x00dev, RT5390)) + rt2800_bbp_write(rt2x00dev, 128, 0x12); if (rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090) || - rt2x00_rt(rt2x00dev, RT3390) || - rt2x00_rt(rt2x00dev, RT5390)) { + rt2x00_rt(rt2x00dev, RT3390) || + rt2x00_rt(rt2x00dev, RT5390)) { rt2800_bbp_read(rt2x00dev, 138, &value); rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); @@ -2724,41 +2731,42 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 138, value); } - if (rt2x00_rt(rt2x00dev, RT5390)) { - int ant, div_mode; - - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); - div_mode = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_ANT_DIVERSITY); - ant = (div_mode == 3) ? 1 : 0; - - /* check if this is a Bluetooth combo card */ - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); - if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) { - u32 reg; - - rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); - rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT3, 0); - rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT6, 0); - rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, 0); - rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT6, 0); - if (ant == 0) - rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, 1); - else if (ant == 1) - rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT6, 1); - rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); - } - - rt2800_bbp_read(rt2x00dev, 152, &value); - if (ant == 0) - rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1); - else - rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0); - rt2800_bbp_write(rt2x00dev, 152, value); - - /* Init frequency calibration */ - rt2800_bbp_write(rt2x00dev, 142, 1); - rt2800_bbp_write(rt2x00dev, 143, 57); - } + if (rt2x00_rt(rt2x00dev, RT5390)) { + int ant, div_mode; + + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); + div_mode = rt2x00_get_field16(eeprom, + EEPROM_NIC_CONF1_ANT_DIVERSITY); + ant = (div_mode == 3) ? 1 : 0; + + /* check if this is a Bluetooth combo card */ + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) { + u32 reg; + + rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); + rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT3, 0); + rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT6, 0); + rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, 0); + rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT6, 0); + if (ant == 0) + rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, 1); + else if (ant == 1) + rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT6, 1); + rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); + } + + rt2800_bbp_read(rt2x00dev, 152, &value); + if (ant == 0) + rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1); + else + rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0); + rt2800_bbp_write(rt2x00dev, 152, value); + + /* Init frequency calibration */ + rt2800_bbp_write(rt2x00dev, 142, 1); + rt2800_bbp_write(rt2x00dev, 143, 57); + } for (i = 0; i < EEPROM_BBP_SIZE; i++) { rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); @@ -2848,28 +2856,28 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) !rt2x00_rt(rt2x00dev, RT3071) && !rt2x00_rt(rt2x00dev, RT3090) && !rt2x00_rt(rt2x00dev, RT3390) && - !rt2x00_rt(rt2x00dev, RT5390) && + !rt2x00_rt(rt2x00dev, RT5390) && !rt2800_is_305x_soc(rt2x00dev)) return 0; /* * Init RF calibration. */ - if (rt2x00_rt(rt2x00dev, RT5390)) { - rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1); - rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); - msleep(1); - rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0); - rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); - } else { - rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); - rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); - msleep(1); - rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0); - rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); - } + if (rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1); + rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); + msleep(1); + rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0); + rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); + } else { + rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + msleep(1); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + } if (rt2x00_rt(rt2x00dev, RT3070) || rt2x00_rt(rt2x00dev, RT3071) || @@ -2960,87 +2968,87 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 30, 0x00); rt2800_rfcsr_write(rt2x00dev, 31, 0x00); return 0; - } else if (rt2x00_rt(rt2x00dev, RT5390)) { - rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); - rt2800_rfcsr_write(rt2x00dev, 2, 0x80); - rt2800_rfcsr_write(rt2x00dev, 3, 0x88); - rt2800_rfcsr_write(rt2x00dev, 5, 0x10); - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) - rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); - else - rt2800_rfcsr_write(rt2x00dev, 6, 0xa0); - rt2800_rfcsr_write(rt2x00dev, 7, 0x00); - rt2800_rfcsr_write(rt2x00dev, 10, 0x53); - rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); - rt2800_rfcsr_write(rt2x00dev, 12, 0xc6); - rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); - rt2800_rfcsr_write(rt2x00dev, 14, 0x00); - rt2800_rfcsr_write(rt2x00dev, 15, 0x00); - rt2800_rfcsr_write(rt2x00dev, 16, 0x00); - rt2800_rfcsr_write(rt2x00dev, 18, 0x03); - rt2800_rfcsr_write(rt2x00dev, 19, 0x00); - - rt2800_rfcsr_write(rt2x00dev, 20, 0x00); - rt2800_rfcsr_write(rt2x00dev, 21, 0x00); - rt2800_rfcsr_write(rt2x00dev, 22, 0x20); - rt2800_rfcsr_write(rt2x00dev, 23, 0x00); - rt2800_rfcsr_write(rt2x00dev, 24, 0x00); - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) - rt2800_rfcsr_write(rt2x00dev, 25, 0x80); - else - rt2800_rfcsr_write(rt2x00dev, 25, 0xc0); - rt2800_rfcsr_write(rt2x00dev, 26, 0x00); - rt2800_rfcsr_write(rt2x00dev, 27, 0x09); - rt2800_rfcsr_write(rt2x00dev, 28, 0x00); - rt2800_rfcsr_write(rt2x00dev, 29, 0x10); - - rt2800_rfcsr_write(rt2x00dev, 30, 0x00); - rt2800_rfcsr_write(rt2x00dev, 31, 0x80); - rt2800_rfcsr_write(rt2x00dev, 32, 0x80); - rt2800_rfcsr_write(rt2x00dev, 33, 0x00); - rt2800_rfcsr_write(rt2x00dev, 34, 0x07); - rt2800_rfcsr_write(rt2x00dev, 35, 0x12); - rt2800_rfcsr_write(rt2x00dev, 36, 0x00); - rt2800_rfcsr_write(rt2x00dev, 37, 0x08); - rt2800_rfcsr_write(rt2x00dev, 38, 0x85); - rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); - - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) - rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); - else - rt2800_rfcsr_write(rt2x00dev, 40, 0x4b); - rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); - rt2800_rfcsr_write(rt2x00dev, 42, 0xd2); - rt2800_rfcsr_write(rt2x00dev, 43, 0x9a); - rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); - rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) - rt2800_rfcsr_write(rt2x00dev, 46, 0x73); - else - rt2800_rfcsr_write(rt2x00dev, 46, 0x7b); - rt2800_rfcsr_write(rt2x00dev, 47, 0x00); - rt2800_rfcsr_write(rt2x00dev, 48, 0x10); - rt2800_rfcsr_write(rt2x00dev, 49, 0x94); - - rt2800_rfcsr_write(rt2x00dev, 52, 0x38); - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) - rt2800_rfcsr_write(rt2x00dev, 53, 0x00); - else - rt2800_rfcsr_write(rt2x00dev, 53, 0x84); - rt2800_rfcsr_write(rt2x00dev, 54, 0x78); - rt2800_rfcsr_write(rt2x00dev, 55, 0x44); - rt2800_rfcsr_write(rt2x00dev, 56, 0x22); - rt2800_rfcsr_write(rt2x00dev, 57, 0x80); - rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); - rt2800_rfcsr_write(rt2x00dev, 59, 0x63); - - rt2800_rfcsr_write(rt2x00dev, 60, 0x45); - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) - rt2800_rfcsr_write(rt2x00dev, 61, 0xd1); - else - rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); - rt2800_rfcsr_write(rt2x00dev, 62, 0x00); - rt2800_rfcsr_write(rt2x00dev, 63, 0x00); + } else if (rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); + rt2800_rfcsr_write(rt2x00dev, 2, 0x80); + rt2800_rfcsr_write(rt2x00dev, 3, 0x88); + rt2800_rfcsr_write(rt2x00dev, 5, 0x10); + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) + rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); + else + rt2800_rfcsr_write(rt2x00dev, 6, 0xa0); + rt2800_rfcsr_write(rt2x00dev, 7, 0x00); + rt2800_rfcsr_write(rt2x00dev, 10, 0x53); + rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); + rt2800_rfcsr_write(rt2x00dev, 12, 0xc6); + rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); + rt2800_rfcsr_write(rt2x00dev, 14, 0x00); + rt2800_rfcsr_write(rt2x00dev, 15, 0x00); + rt2800_rfcsr_write(rt2x00dev, 16, 0x00); + rt2800_rfcsr_write(rt2x00dev, 18, 0x03); + rt2800_rfcsr_write(rt2x00dev, 19, 0x00); + + rt2800_rfcsr_write(rt2x00dev, 20, 0x00); + rt2800_rfcsr_write(rt2x00dev, 21, 0x00); + rt2800_rfcsr_write(rt2x00dev, 22, 0x20); + rt2800_rfcsr_write(rt2x00dev, 23, 0x00); + rt2800_rfcsr_write(rt2x00dev, 24, 0x00); + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) + rt2800_rfcsr_write(rt2x00dev, 25, 0x80); + else + rt2800_rfcsr_write(rt2x00dev, 25, 0xc0); + rt2800_rfcsr_write(rt2x00dev, 26, 0x00); + rt2800_rfcsr_write(rt2x00dev, 27, 0x09); + rt2800_rfcsr_write(rt2x00dev, 28, 0x00); + rt2800_rfcsr_write(rt2x00dev, 29, 0x10); + + rt2800_rfcsr_write(rt2x00dev, 30, 0x00); + rt2800_rfcsr_write(rt2x00dev, 31, 0x80); + rt2800_rfcsr_write(rt2x00dev, 32, 0x80); + rt2800_rfcsr_write(rt2x00dev, 33, 0x00); + rt2800_rfcsr_write(rt2x00dev, 34, 0x07); + rt2800_rfcsr_write(rt2x00dev, 35, 0x12); + rt2800_rfcsr_write(rt2x00dev, 36, 0x00); + rt2800_rfcsr_write(rt2x00dev, 37, 0x08); + rt2800_rfcsr_write(rt2x00dev, 38, 0x85); + rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); + + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) + rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); + else + rt2800_rfcsr_write(rt2x00dev, 40, 0x4b); + rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); + rt2800_rfcsr_write(rt2x00dev, 42, 0xd2); + rt2800_rfcsr_write(rt2x00dev, 43, 0x9a); + rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); + rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) + rt2800_rfcsr_write(rt2x00dev, 46, 0x73); + else + rt2800_rfcsr_write(rt2x00dev, 46, 0x7b); + rt2800_rfcsr_write(rt2x00dev, 47, 0x00); + rt2800_rfcsr_write(rt2x00dev, 48, 0x10); + rt2800_rfcsr_write(rt2x00dev, 49, 0x94); + + rt2800_rfcsr_write(rt2x00dev, 52, 0x38); + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) + rt2800_rfcsr_write(rt2x00dev, 53, 0x00); + else + rt2800_rfcsr_write(rt2x00dev, 53, 0x84); + rt2800_rfcsr_write(rt2x00dev, 54, 0x78); + rt2800_rfcsr_write(rt2x00dev, 55, 0x44); + rt2800_rfcsr_write(rt2x00dev, 56, 0x22); + rt2800_rfcsr_write(rt2x00dev, 57, 0x80); + rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); + rt2800_rfcsr_write(rt2x00dev, 59, 0x63); + + rt2800_rfcsr_write(rt2x00dev, 60, 0x45); + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) + rt2800_rfcsr_write(rt2x00dev, 61, 0xd1); + else + rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); + rt2800_rfcsr_write(rt2x00dev, 62, 0x00); + rt2800_rfcsr_write(rt2x00dev, 63, 0x00); } if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { @@ -3094,23 +3102,23 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x15); } - if (!rt2x00_rt(rt2x00dev, RT5390)) { - /* - * Set back to initial state - */ - rt2800_bbp_write(rt2x00dev, 24, 0); + if (!rt2x00_rt(rt2x00dev, RT5390)) { + /* + * Set back to initial state + */ + rt2800_bbp_write(rt2x00dev, 24, 0); - rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0); - rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); + rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0); + rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); - /* - * Set BBP back to BW20 - */ - rt2800_bbp_read(rt2x00dev, 4, &bbp); - rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0); - rt2800_bbp_write(rt2x00dev, 4, bbp); - } + /* + * Set BBP back to BW20 + */ + rt2800_bbp_read(rt2x00dev, 4, &bbp); + rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0); + rt2800_bbp_write(rt2x00dev, 4, bbp); + } if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) || rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || @@ -3122,23 +3130,24 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, OPT_14_CSR_BIT0, 1); rt2800_register_write(rt2x00dev, OPT_14_CSR, reg); - if (!rt2x00_rt(rt2x00dev, RT5390)) { - rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0); - if (rt2x00_rt(rt2x00dev, RT3070) || - rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || - rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || - rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { - if (!test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) - rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); - } - rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom); - if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1) - rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN, - rt2x00_get_field16(eeprom, - EEPROM_TXMIXER_GAIN_BG_VAL)); - rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); - } + if (!rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0); + if (rt2x00_rt(rt2x00dev, RT3070) || + rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || + rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || + rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { + if (!test_bit(CONFIG_EXTERNAL_LNA_BG, + &rt2x00dev->flags)) + rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); + } + rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom); + if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1) + rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN, + rt2x00_get_field16(eeprom, + EEPROM_TXMIXER_GAIN_BG_VAL)); + rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); + } if (rt2x00_rt(rt2x00dev, RT3090)) { rt2800_bbp_read(rt2x00dev, 138, &bbp); @@ -3189,19 +3198,19 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 27, rfcsr); } - if (rt2x00_rt(rt2x00dev, RT5390)) { - rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0); - rt2800_rfcsr_write(rt2x00dev, 38, rfcsr); + if (rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0); + rt2800_rfcsr_write(rt2x00dev, 38, rfcsr); - rt2800_rfcsr_read(rt2x00dev, 39, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR39_RX_LO2_EN, 0); - rt2800_rfcsr_write(rt2x00dev, 39, rfcsr); + rt2800_rfcsr_read(rt2x00dev, 39, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR39_RX_LO2_EN, 0); + rt2800_rfcsr_write(rt2x00dev, 39, rfcsr); - rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR30_RX_VCM, 2); - rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); - } + rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_RX_VCM, 2); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + } return 0; } @@ -3467,15 +3476,15 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); /* - * Identify RF chipset by EEPROM value - * RT28xx/RT30xx: defined in "EEPROM_NIC_CONF0_RF_TYPE" field - * RT53xx: defined in "EEPROM_CHIP_ID" field + * Identify RF chipset by EEPROM value + * RT28xx/RT30xx: defined in "EEPROM_NIC_CONF0_RF_TYPE" field + * RT53xx: defined in "EEPROM_CHIP_ID" field */ rt2800_register_read(rt2x00dev, MAC_CSR0, ®); - if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390) - rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &value); - else - value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); + if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390) + rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &value); + else + value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET), value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); @@ -3487,8 +3496,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) !rt2x00_rt(rt2x00dev, RT3071) && !rt2x00_rt(rt2x00dev, RT3090) && !rt2x00_rt(rt2x00dev, RT3390) && - !rt2x00_rt(rt2x00dev, RT3572) && - !rt2x00_rt(rt2x00dev, RT5390)) { + !rt2x00_rt(rt2x00dev, RT3572) && + !rt2x00_rt(rt2x00dev, RT5390)) { ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); return -ENODEV; } @@ -3502,8 +3511,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) !rt2x00_rf(rt2x00dev, RF3021) && !rt2x00_rf(rt2x00dev, RF3022) && !rt2x00_rf(rt2x00dev, RF3052) && - !rt2x00_rf(rt2x00dev, RF3320) && - !rt2x00_rf(rt2x00dev, RF5390)) { + !rt2x00_rf(rt2x00dev, RF3320) && + !rt2x00_rf(rt2x00dev, RF5390)) { ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); return -ENODEV; } @@ -3800,8 +3809,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) rt2x00_rf(rt2x00dev, RF2020) || rt2x00_rf(rt2x00dev, RF3021) || rt2x00_rf(rt2x00dev, RF3022) || - rt2x00_rf(rt2x00dev, RF3320) || - rt2x00_rf(rt2x00dev, RF5390)) { + rt2x00_rf(rt2x00dev, RF3320) || + rt2x00_rf(rt2x00dev, RF5390)) { spec->num_channels = 14; spec->channels = rf_vals_3x; } else if (rt2x00_rf(rt2x00dev, RF3052)) { diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 38605e9fe427..6c634c3a2e01 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -493,12 +493,12 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); - if (rt2x00_rt(rt2x00dev, RT5390)) { - rt2800_register_read(rt2x00dev, AUX_CTRL, ®); - rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); - rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); - rt2800_register_write(rt2x00dev, AUX_CTRL, reg); - } + if (rt2x00_rt(rt2x00dev, RT5390)) { + rt2800_register_read(rt2x00dev, AUX_CTRL, ®); + rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); + rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); + rt2800_register_write(rt2x00dev, AUX_CTRL, reg); + } rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); @@ -1135,7 +1135,7 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { { PCI_DEVICE(0x1814, 0x3593), PCI_DEVICE_DATA(&rt2800pci_ops) }, #endif #ifdef CONFIG_RT2800PCI_RT53XX - { PCI_DEVICE(0x1814, 0x5390), PCI_DEVICE_DATA(&rt2800pci_ops) }, + { PCI_DEVICE(0x1814, 0x5390), PCI_DEVICE_DATA(&rt2800pci_ops) }, #endif { 0, } }; -- cgit v1.2.3 From 11f818e0eb50864c7e6f8af38d8f8822f992906a Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 3 Mar 2011 19:38:55 +0100 Subject: rt2x00: Optimize calls to rt2x00queue_get_queue In some cases (tx path for example) we don't need to check for non-tx queues in rt2x00queue_get_queue. Hence, introduce a new method rt2x00queue_get_tx_queue that is only valid for tx queues and use it in places where only tx queues are valid. Furthermore, this new method is quite short and as such can be inlined to avoid the function call overhead. This only converts the txdone functions of drivers that don't use an ATIM queue and the generic tx path. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 4 ++-- drivers/net/wireless/rt2x00/rt2800pci.c | 2 +- drivers/net/wireless/rt2x00/rt2x00.h | 17 +++++++++++++++++ drivers/net/wireless/rt2x00/rt2x00mac.c | 4 ++-- drivers/net/wireless/rt2x00/rt61pci.c | 4 ++-- drivers/net/wireless/rt2x00/rt73usb.c | 2 +- 6 files changed, 25 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index dbee3f12d636..76ced6dcee05 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -751,7 +751,7 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev) if (pid >= QID_RX) continue; - queue = rt2x00queue_get_queue(rt2x00dev, pid); + queue = rt2x00queue_get_tx_queue(rt2x00dev, pid); if (unlikely(!queue)) continue; @@ -3974,7 +3974,7 @@ int rt2800_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, if (queue_idx >= 4) return 0; - queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); + queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); /* Update WMM TXOP register */ offset = WMM_TXOP0_CFG + (sizeof(u32) * (!!(queue_idx & 2))); diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 6c634c3a2e01..5b53d005559b 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -736,7 +736,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) break; } - queue = rt2x00queue_get_queue(rt2x00dev, qid); + queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); if (unlikely(queue == NULL)) { /* * The queue is NULL, this shouldn't happen. Stop diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 19453d23e90d..2f5d8de5ef14 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1062,6 +1062,23 @@ void rt2x00queue_map_txskb(struct queue_entry *entry); */ void rt2x00queue_unmap_skb(struct queue_entry *entry); +/** + * rt2x00queue_get_tx_queue - Convert tx queue index to queue pointer + * @rt2x00dev: Pointer to &struct rt2x00_dev. + * @queue: rt2x00 queue index (see &enum data_queue_qid). + * + * Returns NULL for non tx queues. + */ +static inline struct data_queue * +rt2x00queue_get_tx_queue(struct rt2x00_dev *rt2x00dev, + const enum data_queue_qid queue) +{ + if (queue < rt2x00dev->ops->tx_queues && rt2x00dev->tx) + return &rt2x00dev->tx[queue]; + + return NULL; +} + /** * rt2x00queue_get_queue - Convert queue index to queue pointer * @rt2x00dev: Pointer to &struct rt2x00_dev. diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index c2c35838c2f3..7714198b9d3e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -122,7 +122,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) queue = rt2x00queue_get_queue(rt2x00dev, QID_ATIM); else - queue = rt2x00queue_get_queue(rt2x00dev, qid); + queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); if (unlikely(!queue)) { ERROR(rt2x00dev, "Attempt to send packet over invalid queue %d.\n" @@ -692,7 +692,7 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, struct rt2x00_dev *rt2x00dev = hw->priv; struct data_queue *queue; - queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); + queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); if (unlikely(!queue)) return -EINVAL; diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 927a4a3e0eeb..2ed845b1ea3c 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2190,7 +2190,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) * queue identication number. */ type = rt2x00_get_field32(reg, STA_CSR4_PID_TYPE); - queue = rt2x00queue_get_queue(rt2x00dev, type); + queue = rt2x00queue_get_tx_queue(rt2x00dev, type); if (unlikely(!queue)) continue; @@ -2917,7 +2917,7 @@ static int rt61pci_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, if (queue_idx >= 4) return 0; - queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); + queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); /* Update WMM TXOP register */ offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2))); diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 6e9981a1dd7f..a799c262c1db 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2247,7 +2247,7 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, if (queue_idx >= 4) return 0; - queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); + queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); /* Update WMM TXOP register */ offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2))); -- cgit v1.2.3 From 87443e875c8ad1f0c25b1255bdeb88de934e151e Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 3 Mar 2011 19:39:27 +0100 Subject: rt2x00: Make use of unlikely during tx status processing These conditions are unlikely to happen, tell the compiler. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 5b53d005559b..046a7b7d1241 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -726,7 +726,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) while (kfifo_get(&rt2x00dev->txstatus_fifo, &status)) { qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE); - if (qid >= QID_RX) { + if (unlikely(qid >= QID_RX)) { /* * Unknown queue, this shouldn't happen. Just drop * this tx status. @@ -747,7 +747,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) break; } - if (rt2x00queue_empty(queue)) { + if (unlikely(rt2x00queue_empty(queue))) { /* * The queue is empty. Stop processing here * and drop the tx status. -- cgit v1.2.3 From c262e08b79204f57aba1f180d6ebdb5ea9db01dd Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 3 Mar 2011 19:39:56 +0100 Subject: rt2x00: Remove useless NULL check Since tx_info->control.vif was already accessed before it cant't be NULL here. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index bf9bba356280..b32ca31de7e8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -221,8 +221,7 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); unsigned long irqflags; - if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) || - unlikely(!tx_info->control.vif)) + if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)) return; /* -- cgit v1.2.3 From 5356d963304638735b4b53dfbded7a1c4ae0818d Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 3 Mar 2011 19:40:33 +0100 Subject: rt2x00: Add unlikely macro to special case tx status handling This special case shouldn't happen very often. Only if a frame that is not intended to be aggregated ends up in an AMPDU _and_ was intended to be sent at a different MCS rate as the aggregate. Hence, using unlikely is justified. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 76ced6dcee05..ad90c86810d7 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -681,7 +681,7 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status) * confuse the rate control algortihm by providing clearly wrong * data. */ - if (aggr == 1 && ampdu == 0 && real_mcs != mcs) { + if (unlikely(aggr == 1 && ampdu == 0 && real_mcs != mcs)) { skbdesc->tx_rate_idx = real_mcs; mcs = real_mcs; } -- cgit v1.2.3 From 208f19dceeeebcae2f9fb8f88953e2f66949b0f0 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 3 Mar 2011 19:41:03 +0100 Subject: rt2x00: Use unlikely for unexpected error condition in rt2x00_mac_tx rt2x00queue_write_tx_frame is unlikely to fail. Tell the compiler. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 7714198b9d3e..aeee6e920d98 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -149,7 +149,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) goto exit_fail; } - if (rt2x00queue_write_tx_frame(queue, skb, false)) + if (unlikely(rt2x00queue_write_tx_frame(queue, skb, false))) goto exit_fail; if (rt2x00queue_threshold(queue)) -- cgit v1.2.3 From 7fe7ee77765161217f60ec9facabd9d2b38d98fe Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 3 Mar 2011 19:42:01 +0100 Subject: rt2x00: Generate sw sequence numbers only for devices that need it Newer devices like rt2800* own a hardware sequence counter and thus don't need to use a software sequence counter at all. Add a new driver flag to shortcut the software sequence number generation on devices that don't need it. rt61pci, rt73usb and rt2800* seem to make use of a hw sequence counter while rt2400pci and rt2500* need to do it in software. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 1 + drivers/net/wireless/rt2x00/rt2500pci.c | 1 + drivers/net/wireless/rt2x00/rt2500usb.c | 1 + drivers/net/wireless/rt2x00/rt2x00.h | 1 + drivers/net/wireless/rt2x00/rt2x00queue.c | 11 +++++++---- 5 files changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 2725f3c4442e..d38acf4b65e1 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1641,6 +1641,7 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) */ __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); + __set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags); /* * Set the rssi offset. diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 3ef1fb4185c0..b00e4d483c58 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1959,6 +1959,7 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) */ __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); + __set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags); /* * Set the rssi offset. diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 01f385d5846c..b71df29436e7 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1795,6 +1795,7 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) __set_bit(DRIVER_REQUIRE_COPY_IV, &rt2x00dev->flags); } __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags); + __set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags); /* * Set the rssi offset. diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 2f5d8de5ef14..9067c917c659 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -662,6 +662,7 @@ enum rt2x00_flags { DRIVER_REQUIRE_L2PAD, DRIVER_REQUIRE_TXSTATUS_FIFO, DRIVER_REQUIRE_TASKLET_CONTEXT, + DRIVER_REQUIRE_SW_SEQNO, /* * Driver features diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index b32ca31de7e8..eebb564ee4da 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -224,10 +224,14 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)) return; + __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); + + if (!test_bit(DRIVER_REQUIRE_SW_SEQNO, &entry->queue->rt2x00dev->flags)) + return; + /* - * Hardware should insert sequence counter. - * FIXME: We insert a software sequence counter first for - * hardware that doesn't support hardware sequence counting. + * The hardware is not able to insert a sequence number. Assign a + * software generated one here. * * This is wrong because beacons are not getting sequence * numbers assigned properly. @@ -245,7 +249,6 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, spin_unlock_irqrestore(&intf->seqlock, irqflags); - __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); } static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry, -- cgit v1.2.3 From 26a1d07f4176099a7b6f45009dad054e6ad5b7e4 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 3 Mar 2011 19:42:35 +0100 Subject: rt2x00: Optimize TX descriptor handling HT and no-HT rt2x00 devices use a partly different TX descriptor. Optimize the tx desciptor memory layout by putting the PLCP and HT substructs into a union and introduce a new driver flag to decide which TX desciptor format is used by the device. This saves us the expensive PLCP calculation fOr HT devices and the HT descriptor setup on no-HT devices. Acked-by: Gertjan van Wingerde Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 10 ++++++---- drivers/net/wireless/rt2x00/rt2500pci.c | 10 ++++++---- drivers/net/wireless/rt2x00/rt2500usb.c | 10 ++++++---- drivers/net/wireless/rt2x00/rt2800lib.c | 11 ++++++----- drivers/net/wireless/rt2x00/rt2800pci.c | 1 + drivers/net/wireless/rt2x00/rt2800usb.c | 1 + drivers/net/wireless/rt2x00/rt2x00.h | 1 + drivers/net/wireless/rt2x00/rt2x00ht.c | 20 ++++++++++---------- drivers/net/wireless/rt2x00/rt2x00queue.c | 23 +++++++++++++---------- drivers/net/wireless/rt2x00/rt2x00queue.h | 27 +++++++++++++++++---------- drivers/net/wireless/rt2x00/rt61pci.c | 10 ++++++---- drivers/net/wireless/rt2x00/rt73usb.c | 10 ++++++---- 12 files changed, 79 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index d38acf4b65e1..60d75962b805 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1131,19 +1131,21 @@ static void rt2400pci_write_tx_desc(struct queue_entry *entry, rt2x00_desc_write(txd, 2, word); rt2x00_desc_read(txd, 3, &word); - rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->signal); + rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->u.plcp.signal); rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_REGNUM, 5); rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_BUSY, 1); - rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->service); + rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->u.plcp.service); rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_REGNUM, 6); rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_BUSY, 1); rt2x00_desc_write(txd, 3, word); rt2x00_desc_read(txd, 4, &word); - rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW, txdesc->length_low); + rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW, + txdesc->u.plcp.length_low); rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_REGNUM, 8); rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_BUSY, 1); - rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH, txdesc->length_high); + rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH, + txdesc->u.plcp.length_high); rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_REGNUM, 7); rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_BUSY, 1); rt2x00_desc_write(txd, 4, word); diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index b00e4d483c58..53ff64e19648 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1287,10 +1287,12 @@ static void rt2500pci_write_tx_desc(struct queue_entry *entry, rt2x00_desc_write(txd, 2, word); rt2x00_desc_read(txd, 3, &word); - rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->signal); - rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->service); - rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW, txdesc->length_low); - rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH, txdesc->length_high); + rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->u.plcp.signal); + rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->u.plcp.service); + rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW, + txdesc->u.plcp.length_low); + rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH, + txdesc->u.plcp.length_high); rt2x00_desc_write(txd, 3, word); rt2x00_desc_read(txd, 10, &word); diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index b71df29436e7..ed5bc9c6224f 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1114,10 +1114,12 @@ static void rt2500usb_write_tx_desc(struct queue_entry *entry, rt2x00_desc_write(txd, 1, word); rt2x00_desc_read(txd, 2, &word); - rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); - rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); - rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); - rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); + rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->u.plcp.signal); + rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->u.plcp.service); + rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, + txdesc->u.plcp.length_low); + rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, + txdesc->u.plcp.length_high); rt2x00_desc_write(txd, 2, word); if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index ad90c86810d7..553d4d01a439 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -472,14 +472,15 @@ void rt2800_write_tx_data(struct queue_entry *entry, test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); rt2x00_set_field32(&word, TXWI_W0_AMPDU, test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags)); - rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, txdesc->mpdu_density); - rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->txop); - rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->mcs); + rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, + txdesc->u.ht.mpdu_density); + rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->u.ht.txop); + rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->u.ht.mcs); rt2x00_set_field32(&word, TXWI_W0_BW, test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags)); rt2x00_set_field32(&word, TXWI_W0_SHORT_GI, test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags)); - rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->stbc); + rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->u.ht.stbc); rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode); rt2x00_desc_write(txwi, 0, word); @@ -488,7 +489,7 @@ void rt2800_write_tx_data(struct queue_entry *entry, test_bit(ENTRY_TXD_ACK, &txdesc->flags)); rt2x00_set_field32(&word, TXWI_W1_NSEQ, test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags)); - rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size); + rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->u.ht.ba_size); rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID, test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ? txdesc->key_idx : 0xff); diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 046a7b7d1241..49ea189c9821 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -979,6 +979,7 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) if (!modparam_nohwcrypt) __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); + __set_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags); /* * Set the rssi offset. diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 5d91561e0de7..f1a92144996f 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -565,6 +565,7 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); __set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags); + __set_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags); /* * Set the rssi offset. diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 9067c917c659..81a0f8bed6ae 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -663,6 +663,7 @@ enum rt2x00_flags { DRIVER_REQUIRE_TXSTATUS_FIFO, DRIVER_REQUIRE_TASKLET_CONTEXT, DRIVER_REQUIRE_SW_SEQNO, + DRIVER_REQUIRE_HT_TX_DESC, /* * Driver features diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c index 03d9579da681..78a0e7386a78 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c @@ -38,12 +38,12 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; if (tx_info->control.sta) - txdesc->mpdu_density = + txdesc->u.ht.mpdu_density = tx_info->control.sta->ht_cap.ampdu_density; - txdesc->ba_size = 7; /* FIXME: What value is needed? */ + txdesc->u.ht.ba_size = 7; /* FIXME: What value is needed? */ - txdesc->stbc = + txdesc->u.ht.stbc = (tx_info->flags & IEEE80211_TX_CTL_STBC) >> IEEE80211_TX_CTL_STBC_SHIFT; /* @@ -51,22 +51,22 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, * mcs rate to be used */ if (txrate->flags & IEEE80211_TX_RC_MCS) { - txdesc->mcs = txrate->idx; + txdesc->u.ht.mcs = txrate->idx; /* * MIMO PS should be set to 1 for STA's using dynamic SM PS * when using more then one tx stream (>MCS7). */ - if (tx_info->control.sta && txdesc->mcs > 7 && + if (tx_info->control.sta && txdesc->u.ht.mcs > 7 && ((tx_info->control.sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> IEEE80211_HT_CAP_SM_PS_SHIFT) == WLAN_HT_CAP_SM_PS_DYNAMIC) __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags); } else { - txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs); + txdesc->u.ht.mcs = rt2x00_get_rate_mcs(hwrate->mcs); if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) - txdesc->mcs |= 0x08; + txdesc->u.ht.mcs |= 0x08; } /* @@ -105,11 +105,11 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, * for frames not transmitted with TXOP_HTTXOP */ if (ieee80211_is_mgmt(hdr->frame_control)) - txdesc->txop = TXOP_BACKOFF; + txdesc->u.ht.txop = TXOP_BACKOFF; else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)) - txdesc->txop = TXOP_SIFS; + txdesc->u.ht.txop = TXOP_SIFS; else - txdesc->txop = TXOP_HTTXOP; + txdesc->u.ht.txop = TXOP_HTTXOP; } u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index eebb564ee4da..7816c1c39d6e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -270,12 +270,12 @@ static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry, * PLCP setup * Length calculation depends on OFDM/CCK rate. */ - txdesc->signal = hwrate->plcp; - txdesc->service = 0x04; + txdesc->u.plcp.signal = hwrate->plcp; + txdesc->u.plcp.service = 0x04; if (hwrate->flags & DEV_RATE_OFDM) { - txdesc->length_high = (data_length >> 6) & 0x3f; - txdesc->length_low = data_length & 0x3f; + txdesc->u.plcp.length_high = (data_length >> 6) & 0x3f; + txdesc->u.plcp.length_low = data_length & 0x3f; } else { /* * Convert length to microseconds. @@ -290,18 +290,18 @@ static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry, * Check if we need to set the Length Extension */ if (hwrate->bitrate == 110 && residual <= 30) - txdesc->service |= 0x80; + txdesc->u.plcp.service |= 0x80; } - txdesc->length_high = (duration >> 8) & 0xff; - txdesc->length_low = duration & 0xff; + txdesc->u.plcp.length_high = (duration >> 8) & 0xff; + txdesc->u.plcp.length_low = duration & 0xff; /* * When preamble is enabled we should set the * preamble bit for the signal. */ if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) - txdesc->signal |= 0x08; + txdesc->u.plcp.signal |= 0x08; } } @@ -397,9 +397,12 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, * Apply TX descriptor handling by components */ rt2x00crypto_create_tx_descriptor(entry, txdesc); - rt2x00ht_create_tx_descriptor(entry, txdesc, hwrate); rt2x00queue_create_tx_descriptor_seq(entry, txdesc); - rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate); + + if (test_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags)) + rt2x00ht_create_tx_descriptor(entry, txdesc, hwrate); + else + rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate); } static int rt2x00queue_write_tx_data(struct queue_entry *entry, diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index fab8e2687f29..330552046440 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -305,20 +305,27 @@ struct txentry_desc { u16 length; u16 header_length; - u16 length_high; - u16 length_low; - u16 signal; - u16 service; - - u16 mcs; - u16 stbc; - u16 ba_size; + union { + struct { + u16 length_high; + u16 length_low; + u16 signal; + u16 service; + } plcp; + + struct { + u16 mcs; + u16 stbc; + u16 ba_size; + u16 mpdu_density; + short txop; + } ht; + } u; + u16 rate_mode; - u16 mpdu_density; short retry_limit; short ifs; - short txop; enum cipher cipher; u16 key_idx; diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 2ed845b1ea3c..c01b811a50d5 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1898,10 +1898,12 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry, rt2x00_desc_write(txd, 1, word); rt2x00_desc_read(txd, 2, &word); - rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); - rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); - rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); - rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); + rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->u.plcp.signal); + rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->u.plcp.service); + rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, + txdesc->u.plcp.length_low); + rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, + txdesc->u.plcp.length_high); rt2x00_desc_write(txd, 2, word); if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index a799c262c1db..a4c9a3e20ec4 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1499,10 +1499,12 @@ static void rt73usb_write_tx_desc(struct queue_entry *entry, rt2x00_desc_write(txd, 1, word); rt2x00_desc_read(txd, 2, &word); - rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); - rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); - rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); - rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); + rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->u.plcp.signal); + rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->u.plcp.service); + rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, + txdesc->u.plcp.length_low); + rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, + txdesc->u.plcp.length_high); rt2x00_desc_write(txd, 2, word); if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { -- cgit v1.2.3 From fe107a5234de1f1576df466b2ea8d01868f6ee77 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Thu, 3 Mar 2011 19:42:58 +0100 Subject: rt2x00: Optimize TX descriptor memory layout Some fields only need to be u8 and for ifs and txop we can use the already available enums. Acked-by: Gertjan van Wingerde Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 330552046440..3fa2406af700 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -315,17 +315,17 @@ struct txentry_desc { struct { u16 mcs; - u16 stbc; - u16 ba_size; - u16 mpdu_density; - short txop; + u8 stbc; + u8 ba_size; + u8 mpdu_density; + enum txop txop; } ht; } u; u16 rate_mode; short retry_limit; - short ifs; + enum ifs ifs; enum cipher cipher; u16 key_idx; -- cgit v1.2.3 From 2517794b702cf62bb049e57c0825fc4573f8a6a3 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 3 Mar 2011 19:43:25 +0100 Subject: rt2x00: Move TX descriptor field "ifs" into plcp substruct "ifs" is only used by no-HT devices. Move it into the plcp substruct and fill in the value only for no-HT devices. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 2 +- drivers/net/wireless/rt2x00/rt2500pci.c | 2 +- drivers/net/wireless/rt2x00/rt2500usb.c | 2 +- drivers/net/wireless/rt2x00/rt2x00queue.c | 20 +++++++++++--------- drivers/net/wireless/rt2x00/rt2x00queue.h | 2 +- drivers/net/wireless/rt2x00/rt61pci.c | 2 +- drivers/net/wireless/rt2x00/rt73usb.c | 2 +- 7 files changed, 17 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 60d75962b805..9016c00f2946 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1166,7 +1166,7 @@ static void rt2400pci_write_tx_desc(struct queue_entry *entry, test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_RTS, test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)); - rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); + rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->u.plcp.ifs); rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); rt2x00_desc_write(txd, 0, word); diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 53ff64e19648..0fbc18cb7304 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1317,7 +1317,7 @@ static void rt2500pci_write_tx_desc(struct queue_entry *entry, rt2x00_set_field32(&word, TXD_W0_OFDM, (txdesc->rate_mode == RATE_MODE_OFDM)); rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); - rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); + rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->u.plcp.ifs); rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length); diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index ed5bc9c6224f..979fe6596a2d 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1100,7 +1100,7 @@ static void rt2500usb_write_tx_desc(struct queue_entry *entry, (txdesc->rate_mode == RATE_MODE_OFDM)); rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); - rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); + rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->u.plcp.ifs); rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length); rt2x00_set_field32(&word, TXD_W0_CIPHER, !!txdesc->cipher); rt2x00_set_field32(&word, TXD_W0_KEY_ID, txdesc->key_idx); diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 7816c1c39d6e..6300cf309872 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -262,6 +262,16 @@ static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry, unsigned int duration; unsigned int residual; + /* + * Determine with what IFS priority this frame should be send. + * Set ifs to IFS_SIFS when the this is not the first fragment, + * or this fragment came after RTS/CTS. + */ + if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)) + txdesc->u.plcp.ifs = IFS_BACKOFF; + else + txdesc->u.plcp.ifs = IFS_SIFS; + /* Data length + CRC + Crypto overhead (IV/EIV/ICV/MIC) */ data_length = entry->skb->len + 4; data_length += rt2x00crypto_tx_overhead(rt2x00dev, entry->skb); @@ -373,17 +383,9 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, ieee80211_is_probe_resp(hdr->frame_control)) __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags); - /* - * Determine with what IFS priority this frame should be send. - * Set ifs to IFS_SIFS when the this is not the first fragment, - * or this fragment came after RTS/CTS. - */ if ((tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) && - !test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) { + !test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) __set_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags); - txdesc->ifs = IFS_BACKOFF; - } else - txdesc->ifs = IFS_SIFS; /* * Determine rate modulation. diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 3fa2406af700..7f8528da03e4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -311,6 +311,7 @@ struct txentry_desc { u16 length_low; u16 signal; u16 service; + enum ifs ifs; } plcp; struct { @@ -325,7 +326,6 @@ struct txentry_desc { u16 rate_mode; short retry_limit; - enum ifs ifs; enum cipher cipher; u16 key_idx; diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index c01b811a50d5..a014c64f4275 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1948,7 +1948,7 @@ static void rt61pci_write_tx_desc(struct queue_entry *entry, test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_OFDM, (txdesc->rate_mode == RATE_MODE_OFDM)); - rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); + rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->u.plcp.ifs); rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index a4c9a3e20ec4..02f1148c577e 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1474,7 +1474,7 @@ static void rt73usb_write_tx_desc(struct queue_entry *entry, test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_OFDM, (txdesc->rate_mode == RATE_MODE_OFDM)); - rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); + rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->u.plcp.ifs); rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, -- cgit v1.2.3 From 55b585e29095ce64900b6192aadf399fa007161e Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 3 Mar 2011 19:43:49 +0100 Subject: rt2x00: Don't call ieee80211_get_tx_rate for MCS rates ieee80211_get_tx_rate is not valid for HT rates. Hence, restructure the TX desciptor creation to be aware of MCS rates. The generic TX desciptor creation now cares about the rate_mode (CCK, OFDM, MCS, GF). As a result, ieee80211_get_tx_rate gets only called for legacy rates. Acked-by: Gertjan van Wingerde Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00ht.c | 8 -------- drivers/net/wireless/rt2x00/rt2x00queue.c | 22 +++++++++++++++------- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c index 78a0e7386a78..ae1219dffaae 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c @@ -77,14 +77,6 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, !(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags); - /* - * Determine HT Mix/Greenfield rate mode - */ - if (txrate->flags & IEEE80211_TX_RC_MCS) - txdesc->rate_mode = RATE_MODE_HT_MIX; - if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) - txdesc->rate_mode = RATE_MODE_HT_GREENFIELD; - /* * Set 40Mhz mode if necessary (for legacy rates this will * duplicate the frame to both channels). diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 6300cf309872..f06b5c797492 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -321,9 +321,9 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; - struct ieee80211_rate *rate = - ieee80211_get_tx_rate(rt2x00dev->hw, tx_info); - const struct rt2x00_rate *hwrate; + struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; + struct ieee80211_rate *rate; + const struct rt2x00_rate *hwrate = NULL; memset(txdesc, 0, sizeof(*txdesc)); @@ -390,10 +390,18 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, /* * Determine rate modulation. */ - hwrate = rt2x00_get_rate(rate->hw_value); - txdesc->rate_mode = RATE_MODE_CCK; - if (hwrate->flags & DEV_RATE_OFDM) - txdesc->rate_mode = RATE_MODE_OFDM; + if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) + txdesc->rate_mode = RATE_MODE_HT_GREENFIELD; + else if (txrate->flags & IEEE80211_TX_RC_MCS) + txdesc->rate_mode = RATE_MODE_HT_MIX; + else { + rate = ieee80211_get_tx_rate(rt2x00dev->hw, tx_info); + hwrate = rt2x00_get_rate(rate->hw_value); + if (hwrate->flags & DEV_RATE_OFDM) + txdesc->rate_mode = RATE_MODE_OFDM; + else + txdesc->rate_mode = RATE_MODE_CCK; + } /* * Apply TX descriptor handling by components -- cgit v1.2.3 From 4df10c8c1353e5db781a9a781cc585698b24f30d Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 3 Mar 2011 19:44:10 +0100 Subject: rt2x00: Use an enum instead of u16 for the rate_mode TX descriptor field This makes the code less error-prone. Acked-by: Gertjan van Wingerde Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 7f8528da03e4..0c8b0c699679 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -323,7 +323,7 @@ struct txentry_desc { } ht; } u; - u16 rate_mode; + enum rate_modulation rate_mode; short retry_limit; -- cgit v1.2.3 From 1ed3811c33d525be1c657261db1713f294c40c60 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 3 Mar 2011 19:44:33 +0100 Subject: rt2x00: Fix rt2800 key assignment in multi bssid setups When setting up multiple BSSIDs in AP mode on an rt2800pci device we previously used the STAs AID to select an appropriate key slot. But since the AID is per VIF we can end up with two STAs having the same AID and thus using the same key index. This resulted in one STA overwriting the key information of another STA. Fix this by simply searching for the next unused entry in the pairwise key table. Also bring the key table init in sync with deleting keys by initializing the key table entries to 0 instead of 1. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 43 +++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 553d4d01a439..2ee6cebb9b25 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1101,27 +1101,44 @@ int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev, } EXPORT_SYMBOL_GPL(rt2800_config_shared_key); +static inline int rt2800_find_pairwise_keyslot(struct rt2x00_dev *rt2x00dev) +{ + int idx; + u32 offset, reg; + + /* + * Search for the first free pairwise key entry and return the + * corresponding index. + * + * Make sure the WCID starts _after_ the last possible shared key + * entry (>32). + * + * Since parts of the pairwise key table might be shared with + * the beacon frame buffers 6 & 7 we should only write into the + * first 222 entries. + */ + for (idx = 33; idx <= 222; idx++) { + offset = MAC_WCID_ATTR_ENTRY(idx); + rt2800_register_read(rt2x00dev, offset, ®); + if (!reg) + return idx; + } + return -1; +} + int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_crypto *crypto, struct ieee80211_key_conf *key) { struct hw_key_entry key_entry; u32 offset; + int idx; if (crypto->cmd == SET_KEY) { - /* - * 1 pairwise key is possible per AID, this means that the AID - * equals our hw_key_idx. Make sure the WCID starts _after_ the - * last possible shared key entry. - * - * Since parts of the pairwise key table might be shared with - * the beacon frame buffers 6 & 7 we should only write into the - * first 222 entries. - */ - if (crypto->aid > (222 - 32)) + idx = rt2800_find_pairwise_keyslot(rt2x00dev); + if (idx < 0) return -ENOSPC; - - key->hw_key_idx = 32 + crypto->aid; + key->hw_key_idx = idx; memcpy(key_entry.key, crypto->key, sizeof(key_entry.key)); @@ -2458,7 +2475,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i), wcid, sizeof(wcid)); - rt2800_register_write(rt2x00dev, MAC_WCID_ATTR_ENTRY(i), 1); + rt2800_register_write(rt2x00dev, MAC_WCID_ATTR_ENTRY(i), 0); rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0); } -- cgit v1.2.3 From 567108ebd352f21640c536ea3b39584f9e7c28f8 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 3 Mar 2011 19:44:53 +0100 Subject: rt2x00: Remove now unused crypto.aid field Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 1 - drivers/net/wireless/rt2x00/rt2x00mac.c | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 81a0f8bed6ae..c28ee07fad9f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -467,7 +467,6 @@ struct rt2x00lib_crypto { const u8 *address; u32 bssidx; - u32 aid; u8 key[16]; u8 tx_mic[8]; diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index aeee6e920d98..778b6d9cd686 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -518,11 +518,9 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, crypto.cmd = cmd; - if (sta) { - /* some drivers need the AID */ - crypto.aid = sta->aid; + if (sta) crypto.address = sta->addr; - } else + else crypto.address = bcast_addr; if (crypto.cipher == CIPHER_TKIP) -- cgit v1.2.3 From 0aa13b2e06fbb8327c7acb4ccf684b2b65c302ce Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 3 Mar 2011 19:45:16 +0100 Subject: rt2x00: Revise irqmask locking for PCI devices The PCI device irqmask is locked by a spin_lock. Currently spin_lock_irqsave is used everywhere. To reduce the locking overhead replace spin_lock_irqsave in hard irq context with spin_lock and in soft irq context with spin_lock_irq. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 15 ++++++--------- drivers/net/wireless/rt2x00/rt2500pci.c | 15 ++++++--------- drivers/net/wireless/rt2x00/rt2800pci.c | 10 ++++------ drivers/net/wireless/rt2x00/rt61pci.c | 15 ++++++--------- 4 files changed, 22 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 9016c00f2946..80f4988adf80 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1317,27 +1317,25 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, static void rt2400pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, struct rt2x00_field32 irq_field) { - unsigned long flags; u32 reg; /* * Enable a single interrupt. The interrupt mask register * access needs locking. */ - spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); + spin_lock_irq(&rt2x00dev->irqmask_lock); rt2x00pci_register_read(rt2x00dev, CSR8, ®); rt2x00_set_field32(®, irq_field, 0); rt2x00pci_register_write(rt2x00dev, CSR8, reg); - spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + spin_unlock_irq(&rt2x00dev->irqmask_lock); } static void rt2400pci_txstatus_tasklet(unsigned long data) { struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; u32 reg; - unsigned long flags; /* * Handle all tx queues. @@ -1349,7 +1347,7 @@ static void rt2400pci_txstatus_tasklet(unsigned long data) /* * Enable all TXDONE interrupts again. */ - spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); + spin_lock_irq(&rt2x00dev->irqmask_lock); rt2x00pci_register_read(rt2x00dev, CSR8, ®); rt2x00_set_field32(®, CSR8_TXDONE_TXRING, 0); @@ -1357,7 +1355,7 @@ static void rt2400pci_txstatus_tasklet(unsigned long data) rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, 0); rt2x00pci_register_write(rt2x00dev, CSR8, reg); - spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + spin_unlock_irq(&rt2x00dev->irqmask_lock); } static void rt2400pci_tbtt_tasklet(unsigned long data) @@ -1378,7 +1376,6 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) { struct rt2x00_dev *rt2x00dev = dev_instance; u32 reg, mask; - unsigned long flags; /* * Get the interrupt sources & saved to local variable. @@ -1420,13 +1417,13 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) * Disable all interrupts for which a tasklet was scheduled right now, * the tasklet will reenable the appropriate interrupts. */ - spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); + spin_lock(&rt2x00dev->irqmask_lock); rt2x00pci_register_read(rt2x00dev, CSR8, ®); reg |= mask; rt2x00pci_register_write(rt2x00dev, CSR8, reg); - spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + spin_unlock(&rt2x00dev->irqmask_lock); diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 0fbc18cb7304..635f80466540 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1449,27 +1449,25 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, static void rt2500pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, struct rt2x00_field32 irq_field) { - unsigned long flags; u32 reg; /* * Enable a single interrupt. The interrupt mask register * access needs locking. */ - spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); + spin_lock_irq(&rt2x00dev->irqmask_lock); rt2x00pci_register_read(rt2x00dev, CSR8, ®); rt2x00_set_field32(®, irq_field, 0); rt2x00pci_register_write(rt2x00dev, CSR8, reg); - spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + spin_unlock_irq(&rt2x00dev->irqmask_lock); } static void rt2500pci_txstatus_tasklet(unsigned long data) { struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; u32 reg; - unsigned long flags; /* * Handle all tx queues. @@ -1481,7 +1479,7 @@ static void rt2500pci_txstatus_tasklet(unsigned long data) /* * Enable all TXDONE interrupts again. */ - spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); + spin_lock_irq(&rt2x00dev->irqmask_lock); rt2x00pci_register_read(rt2x00dev, CSR8, ®); rt2x00_set_field32(®, CSR8_TXDONE_TXRING, 0); @@ -1489,7 +1487,7 @@ static void rt2500pci_txstatus_tasklet(unsigned long data) rt2x00_set_field32(®, CSR8_TXDONE_PRIORING, 0); rt2x00pci_register_write(rt2x00dev, CSR8, reg); - spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + spin_unlock_irq(&rt2x00dev->irqmask_lock); } static void rt2500pci_tbtt_tasklet(unsigned long data) @@ -1510,7 +1508,6 @@ static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) { struct rt2x00_dev *rt2x00dev = dev_instance; u32 reg, mask; - unsigned long flags; /* * Get the interrupt sources & saved to local variable. @@ -1552,13 +1549,13 @@ static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) * Disable all interrupts for which a tasklet was scheduled right now, * the tasklet will reenable the appropriate interrupts. */ - spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); + spin_lock(&rt2x00dev->irqmask_lock); rt2x00pci_register_read(rt2x00dev, CSR8, ®); reg |= mask; rt2x00pci_register_write(rt2x00dev, CSR8, reg); - spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + spin_unlock(&rt2x00dev->irqmask_lock); return IRQ_HANDLED; } diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 49ea189c9821..b58484a80b7c 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -765,18 +765,17 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) static void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, struct rt2x00_field32 irq_field) { - unsigned long flags; u32 reg; /* * Enable a single interrupt. The interrupt mask register * access needs locking. */ - spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); + spin_lock_irq(&rt2x00dev->irqmask_lock); rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); rt2x00_set_field32(®, irq_field, 1); rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); - spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + spin_unlock_irq(&rt2x00dev->irqmask_lock); } static void rt2800pci_txstatus_tasklet(unsigned long data) @@ -862,7 +861,6 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) { struct rt2x00_dev *rt2x00dev = dev_instance; u32 reg, mask; - unsigned long flags; /* Read status and ACK all interrupts */ rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, ®); @@ -905,11 +903,11 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) * Disable all interrupts for which a tasklet was scheduled right now, * the tasklet will reenable the appropriate interrupts. */ - spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); + spin_lock(&rt2x00dev->irqmask_lock); rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); reg &= mask; rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); - spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + spin_unlock(&rt2x00dev->irqmask_lock); return IRQ_HANDLED; } diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index a014c64f4275..77e8113b91e1 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2263,39 +2263,37 @@ static void rt61pci_wakeup(struct rt2x00_dev *rt2x00dev) static void rt61pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, struct rt2x00_field32 irq_field) { - unsigned long flags; u32 reg; /* * Enable a single interrupt. The interrupt mask register * access needs locking. */ - spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); + spin_lock_irq(&rt2x00dev->irqmask_lock); rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); rt2x00_set_field32(®, irq_field, 0); rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); - spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + spin_unlock_irq(&rt2x00dev->irqmask_lock); } static void rt61pci_enable_mcu_interrupt(struct rt2x00_dev *rt2x00dev, struct rt2x00_field32 irq_field) { - unsigned long flags; u32 reg; /* * Enable a single MCU interrupt. The interrupt mask register * access needs locking. */ - spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); + spin_lock_irq(&rt2x00dev->irqmask_lock); rt2x00pci_register_read(rt2x00dev, MCU_INT_MASK_CSR, ®); rt2x00_set_field32(®, irq_field, 0); rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); - spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + spin_unlock_irq(&rt2x00dev->irqmask_lock); } static void rt61pci_txstatus_tasklet(unsigned long data) @@ -2333,7 +2331,6 @@ static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) struct rt2x00_dev *rt2x00dev = dev_instance; u32 reg_mcu, mask_mcu; u32 reg, mask; - unsigned long flags; /* * Get the interrupt sources & saved to local variable. @@ -2378,7 +2375,7 @@ static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) * Disable all interrupts for which a tasklet was scheduled right now, * the tasklet will reenable the appropriate interrupts. */ - spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); + spin_lock(&rt2x00dev->irqmask_lock); rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); reg |= mask; @@ -2388,7 +2385,7 @@ static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) reg |= mask_mcu; rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); - spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + spin_unlock(&rt2x00dev->irqmask_lock); return IRQ_HANDLED; } -- cgit v1.2.3 From 3736fe5808577f9d3a31a565ef4e78ceae250c98 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 3 Mar 2011 19:45:39 +0100 Subject: rt2x00: Fix comment in rt2800pci We don't use interrupt threads anymore. Fix the comment. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index b58484a80b7c..808073aa9dcc 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -835,7 +835,7 @@ static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) * * Furthermore we don't disable the TX_FIFO_STATUS * interrupt here but leave it enabled so that the TX_STA_FIFO - * can also be read while the interrupt thread gets executed. + * can also be read while the tx status tasklet gets executed. * * Since we have only one producer and one consumer we don't * need to lock the kfifo. -- cgit v1.2.3 From e74df4a7562da56a7e4dbf41ff167b2f44e84a50 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Thu, 3 Mar 2011 19:46:09 +0100 Subject: rt2x00: Don't treat ATIM queue as second beacon queue. Current code for the atim queue is strange, as it is considered in the rt2x00_dev structure as a second beacon queue. Normalize this by letting the atim queue have its own struct data_queue pointer in the rt2x00_dev structure. Signed-off-by: Gertjan van Wingerde Acked-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 6 +++--- drivers/net/wireless/rt2x00/rt2500pci.c | 6 +++--- drivers/net/wireless/rt2x00/rt2x00.h | 5 ++--- drivers/net/wireless/rt2x00/rt2x00queue.c | 19 ++++++++----------- 4 files changed, 16 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 80f4988adf80..d78d39e4730a 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -779,7 +779,7 @@ static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); - rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->bcn[1].limit); + rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->atim->limit); rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); @@ -795,13 +795,13 @@ static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) entry_priv->desc_dma); rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); - entry_priv = rt2x00dev->bcn[1].entries[0].priv_data; + entry_priv = rt2x00dev->atim->entries[0].priv_data; rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, entry_priv->desc_dma); rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); - entry_priv = rt2x00dev->bcn[0].entries[0].priv_data; + entry_priv = rt2x00dev->bcn->entries[0].priv_data; rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, entry_priv->desc_dma); diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 635f80466540..3fb09151c918 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -865,7 +865,7 @@ static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev) rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); - rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->bcn[1].limit); + rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->atim->limit); rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); @@ -881,13 +881,13 @@ static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev) entry_priv->desc_dma); rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); - entry_priv = rt2x00dev->bcn[1].entries[0].priv_data; + entry_priv = rt2x00dev->atim->entries[0].priv_data; rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, entry_priv->desc_dma); rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); - entry_priv = rt2x00dev->bcn[0].entries[0].priv_data; + entry_priv = rt2x00dev->bcn->entries[0].priv_data; rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, entry_priv->desc_dma); diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index c28ee07fad9f..65636a7eba16 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -887,14 +887,13 @@ struct rt2x00_dev { struct work_struct txdone_work; /* - * Data queue arrays for RX, TX and Beacon. - * The Beacon array also contains the Atim queue - * if that is supported by the device. + * Data queue arrays for RX, TX, Beacon and ATIM. */ unsigned int data_queues; struct data_queue *rx; struct data_queue *tx; struct data_queue *bcn; + struct data_queue *atim; /* * Firmware image. diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index f06b5c797492..fcaacc6dc0f1 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -708,21 +708,17 @@ EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry); struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, const enum data_queue_qid queue) { - int atim = test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); - if (queue == QID_RX) return rt2x00dev->rx; if (queue < rt2x00dev->ops->tx_queues && rt2x00dev->tx) return &rt2x00dev->tx[queue]; - if (!rt2x00dev->bcn) - return NULL; - if (queue == QID_BEACON) - return &rt2x00dev->bcn[0]; - else if (queue == QID_ATIM && atim) - return &rt2x00dev->bcn[1]; + return rt2x00dev->bcn; + + if (queue == QID_ATIM) + return rt2x00dev->atim; return NULL; } @@ -1103,7 +1099,7 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) goto exit; if (test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) { - status = rt2x00queue_alloc_entries(&rt2x00dev->bcn[1], + status = rt2x00queue_alloc_entries(rt2x00dev->atim, rt2x00dev->ops->atim); if (status) goto exit; @@ -1177,6 +1173,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) rt2x00dev->rx = queue; rt2x00dev->tx = &queue[1]; rt2x00dev->bcn = &queue[1 + rt2x00dev->ops->tx_queues]; + rt2x00dev->atim = req_atim ? &queue[2 + rt2x00dev->ops->tx_queues] : NULL; /* * Initialize queue parameters. @@ -1193,9 +1190,9 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) tx_queue_for_each(rt2x00dev, queue) rt2x00queue_init(rt2x00dev, queue, qid++); - rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[0], QID_BEACON); + rt2x00queue_init(rt2x00dev, rt2x00dev->bcn, QID_BEACON); if (req_atim) - rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[1], QID_ATIM); + rt2x00queue_init(rt2x00dev, rt2x00dev->atim, QID_ATIM); return 0; } -- cgit v1.2.3 From 61c6e4893f3070b6473ca4ec3176c7471d44278b Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Thu, 3 Mar 2011 19:46:29 +0100 Subject: rt2x00: Include ATIM queue support in rt2x00queue_get_tx_queue. The ATIM queue is considered to be a TX queue by the drivers that support the queue. Therefore include support for the ATIM queue to the rt2x00queue_get_tx_queue function so that the drivers that support the ATIM queue can also use that function. Add the support in such a way that drivers that do not support the ATIM queue are not penalized in their efficiency. Signed-off-by: Gertjan van Wingerde Acked-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 2 +- drivers/net/wireless/rt2x00/rt2500pci.c | 2 +- drivers/net/wireless/rt2x00/rt2x00.h | 3 +++ drivers/net/wireless/rt2x00/rt2x00mac.c | 8 ++++---- 4 files changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index d78d39e4730a..329f3283697b 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1278,7 +1278,7 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry, static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const enum data_queue_qid queue_idx) { - struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); + struct data_queue *queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); struct queue_entry_priv_pci *entry_priv; struct queue_entry *entry; struct txdone_entry_desc txdesc; diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 3fb09151c918..5cd6575b6358 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1410,7 +1410,7 @@ static void rt2500pci_fill_rxdone(struct queue_entry *entry, static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const enum data_queue_qid queue_idx) { - struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); + struct data_queue *queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx); struct queue_entry_priv_pci *entry_priv; struct queue_entry *entry; struct txdone_entry_desc txdesc; diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 65636a7eba16..6a88c56b43ff 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1076,6 +1076,9 @@ rt2x00queue_get_tx_queue(struct rt2x00_dev *rt2x00dev, if (queue < rt2x00dev->ops->tx_queues && rt2x00dev->tx) return &rt2x00dev->tx[queue]; + if (queue == QID_ATIM) + return rt2x00dev->atim; + return NULL; } diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 778b6d9cd686..72345787fea6 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -116,13 +116,13 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) goto exit_fail; /* - * Determine which queue to put packet on. + * Use the ATIM queue if appropriate and present. */ if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM && test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) - queue = rt2x00queue_get_queue(rt2x00dev, QID_ATIM); - else - queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); + qid = QID_ATIM; + + queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); if (unlikely(!queue)) { ERROR(rt2x00dev, "Attempt to send packet over invalid queue %d.\n" -- cgit v1.2.3 From a24408307e930e21912e82c125648400041d66fb Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Thu, 3 Mar 2011 19:46:55 +0100 Subject: rt2x00: Optimize getting the beacon queue structure. In the spirit of optimizing the code to get the queue structure of TX queues, also optimize the code to get beacon queues. We can simply use the bcn queue field of the rt2x00_dev structure instead of using the rt2x00queue_get_queue function. Signed-off-by: Gertjan van Wingerde Acked-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500pci.c | 2 +- drivers/net/wireless/rt2x00/rt2x00mac.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 5cd6575b6358..58277878889e 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -293,7 +293,7 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00intf_conf *conf, const unsigned int flags) { - struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, QID_BEACON); + struct data_queue *queue = rt2x00dev->bcn; unsigned int bcn_preload; u32 reg; diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 72345787fea6..661c6baad2b9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -190,7 +190,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, { struct rt2x00_dev *rt2x00dev = hw->priv; struct rt2x00_intf *intf = vif_to_intf(vif); - struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, QID_BEACON); + struct data_queue *queue = rt2x00dev->bcn; struct queue_entry *entry = NULL; unsigned int i; -- cgit v1.2.3 From 557d99a26945e21992f693787334143d0355f60a Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Thu, 3 Mar 2011 19:47:21 +0100 Subject: rt2x00: Remove unused rt2x00queue_get_queue function. Now that all accesses to the data_queue structures is done via the specialized rt2x00queue_get_tx_queue function or via direct accesses, there is no need for the rt2x00queue_get_queue function anymore, so remove it. Signed-off-by: Gertjan van Wingerde Acked-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 8 -------- drivers/net/wireless/rt2x00/rt2x00queue.c | 19 ------------------- 2 files changed, 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 6a88c56b43ff..a3940d7300a4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1082,14 +1082,6 @@ rt2x00queue_get_tx_queue(struct rt2x00_dev *rt2x00dev, return NULL; } -/** - * rt2x00queue_get_queue - Convert queue index to queue pointer - * @rt2x00dev: Pointer to &struct rt2x00_dev. - * @queue: rt2x00 queue index (see &enum data_queue_qid). - */ -struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid queue); - /** * rt2x00queue_get_entry - Get queue entry where the given index points to. * @queue: Pointer to &struct data_queue from where we obtain the entry. diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index fcaacc6dc0f1..4b3c70eeef1f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -705,25 +705,6 @@ void rt2x00queue_for_each_entry(struct data_queue *queue, } EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry); -struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid queue) -{ - if (queue == QID_RX) - return rt2x00dev->rx; - - if (queue < rt2x00dev->ops->tx_queues && rt2x00dev->tx) - return &rt2x00dev->tx[queue]; - - if (queue == QID_BEACON) - return rt2x00dev->bcn; - - if (queue == QID_ATIM) - return rt2x00dev->atim; - - return NULL; -} -EXPORT_SYMBOL_GPL(rt2x00queue_get_queue); - struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, enum queue_index index) { -- cgit v1.2.3 From db7889cda3571bfd0d3a3fc79ca0cd16bb321ff2 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Thu, 3 Mar 2011 16:25:59 -0800 Subject: ath9k: Fix txq memory address printing in debugfs. No use printing addresses of pointers, just print the pointers themselves. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index d404aa0ac76a..8df5a92a20f1 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -562,10 +562,10 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, PR("hw-tx-proc-desc: ", txprocdesc); len += snprintf(buf + len, size - len, "%s%11p%11p%10p%10p\n", "txq-memory-address:", - &(sc->tx.txq_map[WME_AC_BE]), - &(sc->tx.txq_map[WME_AC_BK]), - &(sc->tx.txq_map[WME_AC_VI]), - &(sc->tx.txq_map[WME_AC_VO])); + sc->tx.txq_map[WME_AC_BE], + sc->tx.txq_map[WME_AC_BK], + sc->tx.txq_map[WME_AC_VI], + sc->tx.txq_map[WME_AC_VO]); if (len >= size) goto done; -- cgit v1.2.3 From 466a19a003f3b45a755bc85f967c21da947f9a00 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 4 Mar 2011 17:51:49 +0100 Subject: iwlwifi: move rx handlers code to iwl-rx.c Put generic rx_handlers (except iwlagn_rx_reply_compressed_ba) to iwl-rx.c . Make functions static and change prefix from iwlagn_ to iwl_ . Beautify iwl_setup_rx_handlers and do some other minor coding style changes. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 235 ------------- drivers/net/wireless/iwlwifi/iwl-agn.c | 176 ---------- drivers/net/wireless/iwlwifi/iwl-agn.h | 13 +- drivers/net/wireless/iwlwifi/iwl-core.c | 63 ---- drivers/net/wireless/iwlwifi/iwl-core.h | 18 +- drivers/net/wireless/iwlwifi/iwl-rx.c | 523 +++++++++++++++++++++++++++-- 6 files changed, 500 insertions(+), 528 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 87a9fd8e41eb..25fccf9a3001 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -995,241 +995,6 @@ int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band) return -1; } -/* Calc max signal level (dBm) among 3 possible receivers */ -static inline int iwlagn_calc_rssi(struct iwl_priv *priv, - struct iwl_rx_phy_res *rx_resp) -{ - return priv->cfg->ops->utils->calc_rssi(priv, rx_resp); -} - -static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) -{ - u32 decrypt_out = 0; - - if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) == - RX_RES_STATUS_STATION_FOUND) - decrypt_out |= (RX_RES_STATUS_STATION_FOUND | - RX_RES_STATUS_NO_STATION_INFO_MISMATCH); - - decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK); - - /* packet was not encrypted */ - if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) == - RX_RES_STATUS_SEC_TYPE_NONE) - return decrypt_out; - - /* packet was encrypted with unknown alg */ - if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) == - RX_RES_STATUS_SEC_TYPE_ERR) - return decrypt_out; - - /* decryption was not done in HW */ - if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) != - RX_MPDU_RES_STATUS_DEC_DONE_MSK) - return decrypt_out; - - switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) { - - case RX_RES_STATUS_SEC_TYPE_CCMP: - /* alg is CCM: check MIC only */ - if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK)) - /* Bad MIC */ - decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC; - else - decrypt_out |= RX_RES_STATUS_DECRYPT_OK; - - break; - - case RX_RES_STATUS_SEC_TYPE_TKIP: - if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) { - /* Bad TTAK */ - decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK; - break; - } - /* fall through if TTAK OK */ - default: - if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK)) - decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC; - else - decrypt_out |= RX_RES_STATUS_DECRYPT_OK; - break; - } - - IWL_DEBUG_RX(priv, "decrypt_in:0x%x decrypt_out = 0x%x\n", - decrypt_in, decrypt_out); - - return decrypt_out; -} - -static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, - struct ieee80211_hdr *hdr, - u16 len, - u32 ampdu_status, - struct iwl_rx_mem_buffer *rxb, - struct ieee80211_rx_status *stats) -{ - struct sk_buff *skb; - __le16 fc = hdr->frame_control; - - /* We only process data packets if the interface is open */ - if (unlikely(!priv->is_open)) { - IWL_DEBUG_DROP_LIMIT(priv, - "Dropping packet while interface is not open.\n"); - return; - } - - /* In case of HW accelerated crypto and bad decryption, drop */ - if (!priv->cfg->mod_params->sw_crypto && - iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats)) - return; - - skb = dev_alloc_skb(128); - if (!skb) { - IWL_ERR(priv, "dev_alloc_skb failed\n"); - return; - } - - skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); - - iwl_update_stats(priv, false, fc, len); - memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); - - ieee80211_rx(priv->hw, skb); - priv->alloc_rxb_page--; - rxb->page = NULL; -} - -/* Called for REPLY_RX (legacy ABG frames), or - * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ -void iwlagn_rx_reply_rx(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct ieee80211_hdr *header; - struct ieee80211_rx_status rx_status; - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_rx_phy_res *phy_res; - __le32 rx_pkt_status; - struct iwl_rx_mpdu_res_start *amsdu; - u32 len; - u32 ampdu_status; - u32 rate_n_flags; - - /** - * REPLY_RX and REPLY_RX_MPDU_CMD are handled differently. - * REPLY_RX: physical layer info is in this buffer - * REPLY_RX_MPDU_CMD: physical layer info was sent in separate - * command and cached in priv->last_phy_res - * - * Here we set up local variables depending on which command is - * received. - */ - if (pkt->hdr.cmd == REPLY_RX) { - phy_res = (struct iwl_rx_phy_res *)pkt->u.raw; - header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res) - + phy_res->cfg_phy_cnt); - - len = le16_to_cpu(phy_res->byte_count); - rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) + - phy_res->cfg_phy_cnt + len); - ampdu_status = le32_to_cpu(rx_pkt_status); - } else { - if (!priv->_agn.last_phy_res_valid) { - IWL_ERR(priv, "MPDU frame without cached PHY data\n"); - return; - } - phy_res = &priv->_agn.last_phy_res; - amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw; - header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu)); - len = le16_to_cpu(amsdu->byte_count); - rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len); - ampdu_status = iwlagn_translate_rx_status(priv, - le32_to_cpu(rx_pkt_status)); - } - - if ((unlikely(phy_res->cfg_phy_cnt > 20))) { - IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n", - phy_res->cfg_phy_cnt); - return; - } - - if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) || - !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) { - IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n", - le32_to_cpu(rx_pkt_status)); - return; - } - - /* This will be used in several places later */ - rate_n_flags = le32_to_cpu(phy_res->rate_n_flags); - - /* rx_status carries information about the packet to mac80211 */ - rx_status.mactime = le64_to_cpu(phy_res->timestamp); - rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? - IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; - rx_status.freq = - ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel), - rx_status.band); - rx_status.rate_idx = - iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band); - rx_status.flag = 0; - - /* TSF isn't reliable. In order to allow smooth user experience, - * this W/A doesn't propagate it to the mac80211 */ - /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/ - - priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp); - - /* Find max signal strength (dBm) among 3 antenna/receiver chains */ - rx_status.signal = iwlagn_calc_rssi(priv, phy_res); - - iwl_dbg_log_rx_data_frame(priv, len, header); - IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n", - rx_status.signal, (unsigned long long)rx_status.mactime); - - /* - * "antenna number" - * - * It seems that the antenna field in the phy flags value - * is actually a bit field. This is undefined by radiotap, - * it wants an actual antenna number but I always get "7" - * for most legacy frames I receive indicating that the - * same frame was received on all three RX chains. - * - * I think this field should be removed in favor of a - * new 802.11n radiotap field "RX chains" that is defined - * as a bitmask. - */ - rx_status.antenna = - (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK) - >> RX_RES_PHY_FLAGS_ANTENNA_POS; - - /* set the preamble flag if appropriate */ - if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK) - rx_status.flag |= RX_FLAG_SHORTPRE; - - /* Set up the HT phy flags */ - if (rate_n_flags & RATE_MCS_HT_MSK) - rx_status.flag |= RX_FLAG_HT; - if (rate_n_flags & RATE_MCS_HT40_MSK) - rx_status.flag |= RX_FLAG_40MHZ; - if (rate_n_flags & RATE_MCS_SGI_MSK) - rx_status.flag |= RX_FLAG_SHORT_GI; - - iwlagn_pass_packet_to_mac80211(priv, header, len, ampdu_status, - rxb, &rx_status); -} - -/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). - * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ -void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - priv->_agn.last_phy_res_valid = true; - memcpy(&priv->_agn.last_phy_res, pkt->u.raw, - sizeof(struct iwl_rx_phy_res)); -} - static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, struct ieee80211_vif *vif, enum ieee80211_band band, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c96d4ad5def0..6b6f2d88be16 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -424,60 +424,6 @@ int iwl_hw_tx_queue_init(struct iwl_priv *priv, return 0; } -/****************************************************************************** - * - * Generic RX handler implementations - * - ******************************************************************************/ -static void iwl_rx_reply_alive(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_alive_resp *palive; - struct delayed_work *pwork; - - palive = &pkt->u.alive_frame; - - IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision " - "0x%01X 0x%01X\n", - palive->is_valid, palive->ver_type, - palive->ver_subtype); - - if (palive->ver_subtype == INITIALIZE_SUBTYPE) { - IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); - memcpy(&priv->card_alive_init, - &pkt->u.alive_frame, - sizeof(struct iwl_init_alive_resp)); - pwork = &priv->init_alive_start; - } else { - IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); - memcpy(&priv->card_alive, &pkt->u.alive_frame, - sizeof(struct iwl_alive_resp)); - pwork = &priv->alive_start; - } - - /* We delay the ALIVE response by 5ms to - * give the HW RF Kill time to activate... */ - if (palive->is_valid == UCODE_VALID_OK) - queue_delayed_work(priv->workqueue, pwork, - msecs_to_jiffies(5)); - else { - IWL_WARN(priv, "%s uCode did not respond OK.\n", - (palive->ver_subtype == INITIALIZE_SUBTYPE) ? - "init" : "runtime"); - /* - * If fail to load init uCode, - * let's try to load the init uCode again. - * We should not get into this situation, but if it - * does happen, we should not move on and loading "runtime" - * without proper calibrate the device. - */ - if (palive->ver_subtype == INITIALIZE_SUBTYPE) - priv->ucode_type = UCODE_NONE; - queue_work(priv->workqueue, &priv->restart); - } -} - static void iwl_bg_beacon_update(struct work_struct *work) { struct iwl_priv *priv = @@ -712,83 +658,6 @@ static void iwl_bg_ucode_trace(unsigned long data) } } -static void iwlagn_rx_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw; -#ifdef CONFIG_IWLWIFI_DEBUG - u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status); - u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); - - IWL_DEBUG_RX(priv, "beacon status %#x, retries:%d ibssmgr:%d " - "tsf:0x%.8x%.8x rate:%d\n", - status & TX_STATUS_MSK, - beacon->beacon_notify_hdr.failure_frame, - le32_to_cpu(beacon->ibss_mgr_status), - le32_to_cpu(beacon->high_tsf), - le32_to_cpu(beacon->low_tsf), rate); -#endif - - priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); - - if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) - queue_work(priv->workqueue, &priv->beacon_update); -} - -/* Handle notification from uCode that card's power state is changing - * due to software, hardware, or critical temperature RFKILL */ -static void iwl_rx_card_state_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); - unsigned long status = priv->status; - - IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n", - (flags & HW_CARD_DISABLED) ? "Kill" : "On", - (flags & SW_CARD_DISABLED) ? "Kill" : "On", - (flags & CT_CARD_DISABLED) ? - "Reached" : "Not reached"); - - if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | - CT_CARD_DISABLED)) { - - iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, - CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); - - iwl_write_direct32(priv, HBUS_TARG_MBX_C, - HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); - - if (!(flags & RXON_CARD_DISABLED)) { - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, - CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); - iwl_write_direct32(priv, HBUS_TARG_MBX_C, - HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); - } - if (flags & CT_CARD_DISABLED) - iwl_tt_enter_ct_kill(priv); - } - if (!(flags & CT_CARD_DISABLED)) - iwl_tt_exit_ct_kill(priv); - - if (flags & HW_CARD_DISABLED) - set_bit(STATUS_RF_KILL_HW, &priv->status); - else - clear_bit(STATUS_RF_KILL_HW, &priv->status); - - - if (!(flags & RXON_CARD_DISABLED)) - iwl_scan_cancel(priv); - - if ((test_bit(STATUS_RF_KILL_HW, &status) != - test_bit(STATUS_RF_KILL_HW, &priv->status))) - wiphy_rfkill_set_hw_state(priv->hw->wiphy, - test_bit(STATUS_RF_KILL_HW, &priv->status)); - else - wake_up_interruptible(&priv->wait_command_queue); -} - static void iwl_bg_tx_flush(struct work_struct *work) { struct iwl_priv *priv = @@ -807,51 +676,6 @@ static void iwl_bg_tx_flush(struct work_struct *work) } } -/** - * iwl_setup_rx_handlers - Initialize Rx handler callbacks - * - * Setup the RX handlers for each of the reply types sent from the uCode - * to the host. - * - * This function chains into the hardware specific files for them to setup - * any hardware specific handlers as well. - */ -static void iwl_setup_rx_handlers(struct iwl_priv *priv) -{ - priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive; - priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; - priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; - priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] = - iwl_rx_spectrum_measure_notif; - priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; - priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = - iwl_rx_pm_debug_statistics_notif; - priv->rx_handlers[BEACON_NOTIFICATION] = iwlagn_rx_beacon_notif; - - /* - * The same handler is used for both the REPLY to a discrete - * statistics request from the host as well as for the periodic - * statistics notifications (after received beacons) from the uCode. - */ - priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics; - priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; - - iwl_setup_rx_scan_handlers(priv); - - /* status change handler */ - priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl_rx_card_state_notif; - - priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] = - iwl_rx_missed_beacon_notif; - /* Rx handlers */ - priv->rx_handlers[REPLY_RX_PHY_CMD] = iwlagn_rx_reply_rx_phy; - priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwlagn_rx_reply_rx; - /* block ack */ - priv->rx_handlers[REPLY_COMPRESSED_BA] = iwlagn_rx_reply_compressed_ba; - /* Set up hardware specific Rx handlers */ - priv->cfg->ops->lib->rx_handler_setup(priv); -} - /** * iwl_rx_handle - Main entry function for receiving responses from uCode * diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index b5a169be48e2..20f8e4188994 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -190,10 +190,7 @@ void iwlagn_rx_replenish_now(struct iwl_priv *priv); void iwlagn_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq); int iwlagn_rxq_stop(struct iwl_priv *priv); int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); -void iwlagn_rx_reply_rx(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); -void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); +void iwl_setup_rx_handlers(struct iwl_priv *priv); /* tx */ void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); @@ -243,14 +240,6 @@ static inline bool iwl_is_tx_success(u32 status) u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid); -/* rx */ -void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); -void iwl_rx_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); -void iwl_reply_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); - /* scan */ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); void iwlagn_post_scan(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 4bd342060254..6c30fa652e27 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -869,33 +869,6 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) } } -void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_csa_notification *csa = &(pkt->u.csa_notif); - /* - * MULTI-FIXME - * See iwl_mac_channel_switch. - */ - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - struct iwl_rxon_cmd *rxon = (void *)&ctx->active; - - if (priv->switch_rxon.switch_in_progress) { - if (!le32_to_cpu(csa->status) && - (csa->channel == priv->switch_rxon.channel)) { - rxon->channel = csa->channel; - ctx->staging.channel = csa->channel; - IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", - le16_to_cpu(csa->channel)); - iwl_chswitch_done(priv, true); - } else { - IWL_ERR(priv, "CSA notif (fail) : channel %d\n", - le16_to_cpu(csa->channel)); - iwl_chswitch_done(priv, false); - } - } -} - #ifdef CONFIG_IWLWIFI_DEBUG void iwl_print_rx_config_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx) @@ -1245,42 +1218,6 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) &statistics_cmd); } -void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ -#ifdef CONFIG_IWLWIFI_DEBUG - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif); - IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", - sleep->pm_sleep_mode, sleep->pm_wakeup_src); -#endif -} - -void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; - IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " - "notification for %s:\n", len, - get_cmd_string(pkt->hdr.cmd)); - iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len); -} - -void iwl_rx_reply_error(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - - IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " - "seq 0x%04X ser 0x%08X\n", - le32_to_cpu(pkt->u.err_resp.error_type), - get_cmd_string(pkt->u.err_resp.cmd_id), - pkt->u.err_resp.cmd_id, - le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num), - le32_to_cpu(pkt->u.err_resp.error_info)); -} - void iwl_clear_isr_stats(struct iwl_priv *priv) { memset(&priv->isr_stats, 0, sizeof(priv->isr_stats)); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index d47f3a87fce4..af47750f8985 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -441,10 +441,6 @@ bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, void iwl_connection_init_rx_config(struct iwl_priv *priv, struct iwl_rxon_context *ctx); void iwl_set_rate(struct iwl_priv *priv); -int iwl_set_decrypted_flag(struct iwl_priv *priv, - struct ieee80211_hdr *hdr, - u32 decrypt_res, - struct ieee80211_rx_status *stats); void iwl_irq_handle_error(struct iwl_priv *priv); int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); @@ -493,15 +489,6 @@ static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx, { } #endif -/***************************************************** - * RX handlers. - * **************************************************/ -void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); -void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); -void iwl_rx_reply_error(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); /***************************************************** * RX @@ -513,11 +500,8 @@ void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q); int iwl_rx_queue_space(const struct iwl_rx_queue *q); void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); -/* Handlers */ -void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); + void iwl_chswitch_done(struct iwl_priv *priv, bool is_success); -void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); /* TX helpers */ diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 566e2d979ce3..8dc129499b90 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -38,7 +38,14 @@ #include "iwl-io.h" #include "iwl-helpers.h" #include "iwl-agn-calib.h" -/************************** RX-FUNCTIONS ****************************/ +#include "iwl-agn.h" + +/****************************************************************************** + * + * RX path functions + * + ******************************************************************************/ + /* * Rx theory of operation * @@ -211,7 +218,104 @@ err_bd: return -ENOMEM; } -void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, +/****************************************************************************** + * + * Generic RX handler implementations + * + ******************************************************************************/ + +static void iwl_rx_reply_alive(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_alive_resp *palive; + struct delayed_work *pwork; + + palive = &pkt->u.alive_frame; + + IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision " + "0x%01X 0x%01X\n", + palive->is_valid, palive->ver_type, + palive->ver_subtype); + + if (palive->ver_subtype == INITIALIZE_SUBTYPE) { + IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); + memcpy(&priv->card_alive_init, + &pkt->u.alive_frame, + sizeof(struct iwl_init_alive_resp)); + pwork = &priv->init_alive_start; + } else { + IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); + memcpy(&priv->card_alive, &pkt->u.alive_frame, + sizeof(struct iwl_alive_resp)); + pwork = &priv->alive_start; + } + + /* We delay the ALIVE response by 5ms to + * give the HW RF Kill time to activate... */ + if (palive->is_valid == UCODE_VALID_OK) + queue_delayed_work(priv->workqueue, pwork, + msecs_to_jiffies(5)); + else { + IWL_WARN(priv, "%s uCode did not respond OK.\n", + (palive->ver_subtype == INITIALIZE_SUBTYPE) ? + "init" : "runtime"); + /* + * If fail to load init uCode, + * let's try to load the init uCode again. + * We should not get into this situation, but if it + * does happen, we should not move on and loading "runtime" + * without proper calibrate the device. + */ + if (palive->ver_subtype == INITIALIZE_SUBTYPE) + priv->ucode_type = UCODE_NONE; + queue_work(priv->workqueue, &priv->restart); + } +} + +static void iwl_rx_reply_error(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + + IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " + "seq 0x%04X ser 0x%08X\n", + le32_to_cpu(pkt->u.err_resp.error_type), + get_cmd_string(pkt->u.err_resp.cmd_id), + pkt->u.err_resp.cmd_id, + le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num), + le32_to_cpu(pkt->u.err_resp.error_info)); +} + +static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_csa_notification *csa = &(pkt->u.csa_notif); + /* + * MULTI-FIXME + * See iwl_mac_channel_switch. + */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + struct iwl_rxon_cmd *rxon = (void *)&ctx->active; + + if (priv->switch_rxon.switch_in_progress) { + if (!le32_to_cpu(csa->status) && + (csa->channel == priv->switch_rxon.channel)) { + rxon->channel = csa->channel; + ctx->staging.channel = csa->channel; + IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", + le16_to_cpu(csa->channel)); + iwl_chswitch_done(priv, true); + } else { + IWL_ERR(priv, "CSA notif (fail) : channel %d\n", + le16_to_cpu(csa->channel)); + iwl_chswitch_done(priv, false); + } + } +} + + +static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -227,6 +331,52 @@ void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, priv->measurement_status |= MEASUREMENT_READY; } +static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ +#ifdef CONFIG_IWLWIFI_DEBUG + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif); + IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", + sleep->pm_sleep_mode, sleep->pm_wakeup_src); +#endif +} + +static void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; + IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " + "notification for %s:\n", len, + get_cmd_string(pkt->hdr.cmd)); + iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len); +} + +static void iwl_rx_beacon_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw; +#ifdef CONFIG_IWLWIFI_DEBUG + u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status); + u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); + + IWL_DEBUG_RX(priv, "beacon status %#x, retries:%d ibssmgr:%d " + "tsf:0x%.8x%.8x rate:%d\n", + status & TX_STATUS_MSK, + beacon->beacon_notify_hdr.failure_frame, + le32_to_cpu(beacon->ibss_mgr_status), + le32_to_cpu(beacon->high_tsf), + le32_to_cpu(beacon->low_tsf), rate); +#endif + + priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); + + if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) + queue_work(priv->workqueue, &priv->beacon_update); +} + /* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */ #define ACK_CNT_RATIO (50) #define BA_TIMEOUT_CNT (5) @@ -298,7 +448,8 @@ static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt * When the plcp error is exceeding the thresholds, reset the radio * to improve the throughput. */ -static bool iwl_good_plcp_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt) +static bool iwl_good_plcp_health(struct iwl_priv *priv, + struct iwl_rx_packet *pkt) { bool rc = true; int combined_plcp_delta; @@ -378,7 +529,8 @@ static bool iwl_good_plcp_health(struct iwl_priv *priv, struct iwl_rx_packet *pk return rc; } -static void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt) +static void iwl_recover_from_statistics(struct iwl_priv *priv, + struct iwl_rx_packet *pkt) { const struct iwl_mod_params *mod_params = priv->cfg->mod_params; @@ -442,7 +594,6 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv) last_rx_noise); } -#ifdef CONFIG_IWLWIFI_DEBUGFS /* * based on the assumption of all statistics counter are in DWORD * FIXME: This function is for debugging, do not deal with @@ -451,6 +602,7 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv) static void iwl_accumulative_statistics(struct iwl_priv *priv, __le32 *stats) { +#ifdef CONFIG_IWLWIFI_DEBUGFS int i, size; __le32 *prev_stats; u32 *accum_stats; @@ -498,14 +650,13 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv, accum_tx->tx_power.ant_a = tx->tx_power.ant_a; accum_tx->tx_power.ant_b = tx->tx_power.ant_b; accum_tx->tx_power.ant_c = tx->tx_power.ant_c; -} #endif +} -#define REG_RECALIB_PERIOD (60) - -void iwl_rx_statistics(struct iwl_priv *priv, +static void iwl_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { + const int reg_recalib_period = 60; int change; struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -522,10 +673,8 @@ void iwl_rx_statistics(struct iwl_priv *priv, STATISTICS_REPLY_FLG_HT40_MODE_MSK) != (pkt->u.stats_bt.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK))); -#ifdef CONFIG_IWLWIFI_DEBUGFS - iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt); -#endif + iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt); } else { IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", @@ -539,10 +688,8 @@ void iwl_rx_statistics(struct iwl_priv *priv, STATISTICS_REPLY_FLG_HT40_MODE_MSK) != (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK))); -#ifdef CONFIG_IWLWIFI_DEBUGFS - iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); -#endif + iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); } iwl_recover_from_statistics(priv, pkt); @@ -557,11 +704,11 @@ void iwl_rx_statistics(struct iwl_priv *priv, set_bit(STATUS_STATISTICS, &priv->status); /* Reschedule the statistics timer to occur in - * REG_RECALIB_PERIOD seconds to ensure we get a + * reg_recalib_period seconds to ensure we get a * thermal update even if the uCode doesn't give * us one */ mod_timer(&priv->statistics_periodic, jiffies + - msecs_to_jiffies(REG_RECALIB_PERIOD * 1000)); + msecs_to_jiffies(reg_recalib_period * 1000)); if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { @@ -572,8 +719,8 @@ void iwl_rx_statistics(struct iwl_priv *priv, priv->cfg->ops->lib->temp_ops.temperature(priv); } -void iwl_reply_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl_rx_reply_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -597,8 +744,61 @@ void iwl_reply_statistics(struct iwl_priv *priv, iwl_rx_statistics(priv, rxb); } -void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +/* Handle notification from uCode that card's power state is changing + * due to software, hardware, or critical temperature RFKILL */ +static void iwl_rx_card_state_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); + unsigned long status = priv->status; + + IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n", + (flags & HW_CARD_DISABLED) ? "Kill" : "On", + (flags & SW_CARD_DISABLED) ? "Kill" : "On", + (flags & CT_CARD_DISABLED) ? + "Reached" : "Not reached"); + + if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | + CT_CARD_DISABLED)) { + + iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, + CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); + + iwl_write_direct32(priv, HBUS_TARG_MBX_C, + HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); + + if (!(flags & RXON_CARD_DISABLED)) { + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, + CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); + iwl_write_direct32(priv, HBUS_TARG_MBX_C, + HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); + } + if (flags & CT_CARD_DISABLED) + iwl_tt_enter_ct_kill(priv); + } + if (!(flags & CT_CARD_DISABLED)) + iwl_tt_exit_ct_kill(priv); + + if (flags & HW_CARD_DISABLED) + set_bit(STATUS_RF_KILL_HW, &priv->status); + else + clear_bit(STATUS_RF_KILL_HW, &priv->status); + + + if (!(flags & RXON_CARD_DISABLED)) + iwl_scan_cancel(priv); + + if ((test_bit(STATUS_RF_KILL_HW, &status) != + test_bit(STATUS_RF_KILL_HW, &priv->status))) + wiphy_rfkill_set_hw_state(priv->hw->wiphy, + test_bit(STATUS_RF_KILL_HW, &priv->status)); + else + wake_up_interruptible(&priv->wait_command_queue); +} + +static void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -618,13 +818,25 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, } } +/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). + * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ +static void iwl_rx_reply_rx_phy(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + + priv->_agn.last_phy_res_valid = true; + memcpy(&priv->_agn.last_phy_res, pkt->u.raw, + sizeof(struct iwl_rx_phy_res)); +} + /* * returns non-zero if packet should be dropped */ -int iwl_set_decrypted_flag(struct iwl_priv *priv, - struct ieee80211_hdr *hdr, - u32 decrypt_res, - struct ieee80211_rx_status *stats) +static int iwl_set_decrypted_flag(struct iwl_priv *priv, + struct ieee80211_hdr *hdr, + u32 decrypt_res, + struct ieee80211_rx_status *stats) { u16 fc = le16_to_cpu(hdr->frame_control); @@ -669,3 +881,264 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv, } return 0; } + +static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, + struct ieee80211_hdr *hdr, + u16 len, + u32 ampdu_status, + struct iwl_rx_mem_buffer *rxb, + struct ieee80211_rx_status *stats) +{ + struct sk_buff *skb; + __le16 fc = hdr->frame_control; + + /* We only process data packets if the interface is open */ + if (unlikely(!priv->is_open)) { + IWL_DEBUG_DROP_LIMIT(priv, + "Dropping packet while interface is not open.\n"); + return; + } + + /* In case of HW accelerated crypto and bad decryption, drop */ + if (!priv->cfg->mod_params->sw_crypto && + iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats)) + return; + + skb = dev_alloc_skb(128); + if (!skb) { + IWL_ERR(priv, "dev_alloc_skb failed\n"); + return; + } + + skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); + + iwl_update_stats(priv, false, fc, len); + memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); + + ieee80211_rx(priv->hw, skb); + priv->alloc_rxb_page--; + rxb->page = NULL; +} + +static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) +{ + u32 decrypt_out = 0; + + if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) == + RX_RES_STATUS_STATION_FOUND) + decrypt_out |= (RX_RES_STATUS_STATION_FOUND | + RX_RES_STATUS_NO_STATION_INFO_MISMATCH); + + decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK); + + /* packet was not encrypted */ + if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) == + RX_RES_STATUS_SEC_TYPE_NONE) + return decrypt_out; + + /* packet was encrypted with unknown alg */ + if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) == + RX_RES_STATUS_SEC_TYPE_ERR) + return decrypt_out; + + /* decryption was not done in HW */ + if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) != + RX_MPDU_RES_STATUS_DEC_DONE_MSK) + return decrypt_out; + + switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) { + + case RX_RES_STATUS_SEC_TYPE_CCMP: + /* alg is CCM: check MIC only */ + if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK)) + /* Bad MIC */ + decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC; + else + decrypt_out |= RX_RES_STATUS_DECRYPT_OK; + + break; + + case RX_RES_STATUS_SEC_TYPE_TKIP: + if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) { + /* Bad TTAK */ + decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK; + break; + } + /* fall through if TTAK OK */ + default: + if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK)) + decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC; + else + decrypt_out |= RX_RES_STATUS_DECRYPT_OK; + break; + } + + IWL_DEBUG_RX(priv, "decrypt_in:0x%x decrypt_out = 0x%x\n", + decrypt_in, decrypt_out); + + return decrypt_out; +} + +/* Called for REPLY_RX (legacy ABG frames), or + * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ +static void iwl_rx_reply_rx(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct ieee80211_hdr *header; + struct ieee80211_rx_status rx_status; + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_rx_phy_res *phy_res; + __le32 rx_pkt_status; + struct iwl_rx_mpdu_res_start *amsdu; + u32 len; + u32 ampdu_status; + u32 rate_n_flags; + + /** + * REPLY_RX and REPLY_RX_MPDU_CMD are handled differently. + * REPLY_RX: physical layer info is in this buffer + * REPLY_RX_MPDU_CMD: physical layer info was sent in separate + * command and cached in priv->last_phy_res + * + * Here we set up local variables depending on which command is + * received. + */ + if (pkt->hdr.cmd == REPLY_RX) { + phy_res = (struct iwl_rx_phy_res *)pkt->u.raw; + header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res) + + phy_res->cfg_phy_cnt); + + len = le16_to_cpu(phy_res->byte_count); + rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) + + phy_res->cfg_phy_cnt + len); + ampdu_status = le32_to_cpu(rx_pkt_status); + } else { + if (!priv->_agn.last_phy_res_valid) { + IWL_ERR(priv, "MPDU frame without cached PHY data\n"); + return; + } + phy_res = &priv->_agn.last_phy_res; + amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw; + header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu)); + len = le16_to_cpu(amsdu->byte_count); + rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len); + ampdu_status = iwl_translate_rx_status(priv, + le32_to_cpu(rx_pkt_status)); + } + + if ((unlikely(phy_res->cfg_phy_cnt > 20))) { + IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n", + phy_res->cfg_phy_cnt); + return; + } + + if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) || + !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) { + IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n", + le32_to_cpu(rx_pkt_status)); + return; + } + + /* This will be used in several places later */ + rate_n_flags = le32_to_cpu(phy_res->rate_n_flags); + + /* rx_status carries information about the packet to mac80211 */ + rx_status.mactime = le64_to_cpu(phy_res->timestamp); + rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? + IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; + rx_status.freq = + ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel), + rx_status.band); + rx_status.rate_idx = + iwlagn_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band); + rx_status.flag = 0; + + /* TSF isn't reliable. In order to allow smooth user experience, + * this W/A doesn't propagate it to the mac80211 */ + /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/ + + priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp); + + /* Find max signal strength (dBm) among 3 antenna/receiver chains */ + rx_status.signal = priv->cfg->ops->utils->calc_rssi(priv, phy_res); + + iwl_dbg_log_rx_data_frame(priv, len, header); + IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n", + rx_status.signal, (unsigned long long)rx_status.mactime); + + /* + * "antenna number" + * + * It seems that the antenna field in the phy flags value + * is actually a bit field. This is undefined by radiotap, + * it wants an actual antenna number but I always get "7" + * for most legacy frames I receive indicating that the + * same frame was received on all three RX chains. + * + * I think this field should be removed in favor of a + * new 802.11n radiotap field "RX chains" that is defined + * as a bitmask. + */ + rx_status.antenna = + (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK) + >> RX_RES_PHY_FLAGS_ANTENNA_POS; + + /* set the preamble flag if appropriate */ + if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK) + rx_status.flag |= RX_FLAG_SHORTPRE; + + /* Set up the HT phy flags */ + if (rate_n_flags & RATE_MCS_HT_MSK) + rx_status.flag |= RX_FLAG_HT; + if (rate_n_flags & RATE_MCS_HT40_MSK) + rx_status.flag |= RX_FLAG_40MHZ; + if (rate_n_flags & RATE_MCS_SGI_MSK) + rx_status.flag |= RX_FLAG_SHORT_GI; + + iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status, + rxb, &rx_status); +} + +/** + * iwl_setup_rx_handlers - Initialize Rx handler callbacks + * + * Setup the RX handlers for each of the reply types sent from the uCode + * to the host. + */ +void iwl_setup_rx_handlers(struct iwl_priv *priv) +{ + void (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); + + handlers = priv->rx_handlers; + + handlers[REPLY_ALIVE] = iwl_rx_reply_alive; + handlers[REPLY_ERROR] = iwl_rx_reply_error; + handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; + handlers[SPECTRUM_MEASURE_NOTIFICATION] = iwl_rx_spectrum_measure_notif; + handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; + handlers[PM_DEBUG_STATISTIC_NOTIFIC] = iwl_rx_pm_debug_statistics_notif; + handlers[BEACON_NOTIFICATION] = iwl_rx_beacon_notif; + + /* + * The same handler is used for both the REPLY to a discrete + * statistics request from the host as well as for the periodic + * statistics notifications (after received beacons) from the uCode. + */ + handlers[REPLY_STATISTICS_CMD] = iwl_rx_reply_statistics; + handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; + + iwl_setup_rx_scan_handlers(priv); + + handlers[CARD_STATE_NOTIFICATION] = iwl_rx_card_state_notif; + handlers[MISSED_BEACONS_NOTIFICATION] = iwl_rx_missed_beacon_notif; + + /* Rx handlers */ + handlers[REPLY_RX_PHY_CMD] = iwl_rx_reply_rx_phy; + handlers[REPLY_RX_MPDU_CMD] = iwl_rx_reply_rx; + + /* block ack */ + handlers[REPLY_COMPRESSED_BA] = iwlagn_rx_reply_compressed_ba; + + /* Set up hardware specific Rx handlers */ + priv->cfg->ops->lib->rx_handler_setup(priv); +} -- cgit v1.2.3 From 6198c387b25b528fd89a48bf67f0402d828ffa18 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 4 Mar 2011 17:51:50 +0100 Subject: iwlwifi: cleanup iwl_good_plcp_health Make iwl_good_plcp_health code easiest to read. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-rx.c | 115 +++++++++++++--------------------- 1 file changed, 45 insertions(+), 70 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 8dc129499b90..a70f1eb08e5c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -451,82 +451,57 @@ static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt static bool iwl_good_plcp_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt) { - bool rc = true; - int combined_plcp_delta; - unsigned int plcp_msec; - unsigned long plcp_received_jiffies; + unsigned int msecs; + unsigned long stamp; + int delta; + int threshold = priv->cfg->base_params->plcp_delta_threshold; - if (priv->cfg->base_params->plcp_delta_threshold == - IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { + if (threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); - return rc; + return true; } - /* - * check for plcp_err and trigger radio reset if it exceeds - * the plcp error threshold plcp_delta. - */ - plcp_received_jiffies = jiffies; - plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - - (long) priv->plcp_jiffies); - priv->plcp_jiffies = plcp_received_jiffies; - /* - * check to make sure plcp_msec is not 0 to prevent division - * by zero. - */ - if (plcp_msec) { - struct statistics_rx_phy *ofdm; - struct statistics_rx_ht_phy *ofdm_ht; - - if (iwl_bt_statistics(priv)) { - ofdm = &pkt->u.stats_bt.rx.ofdm; - ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht; - combined_plcp_delta = - (le32_to_cpu(ofdm->plcp_err) - - le32_to_cpu(priv->_agn.statistics_bt. - rx.ofdm.plcp_err)) + - (le32_to_cpu(ofdm_ht->plcp_err) - - le32_to_cpu(priv->_agn.statistics_bt. - rx.ofdm_ht.plcp_err)); - } else { - ofdm = &pkt->u.stats.rx.ofdm; - ofdm_ht = &pkt->u.stats.rx.ofdm_ht; - combined_plcp_delta = - (le32_to_cpu(ofdm->plcp_err) - - le32_to_cpu(priv->_agn.statistics. - rx.ofdm.plcp_err)) + - (le32_to_cpu(ofdm_ht->plcp_err) - - le32_to_cpu(priv->_agn.statistics. - rx.ofdm_ht.plcp_err)); - } + stamp = jiffies; + msecs = jiffies_to_msecs(stamp - priv->plcp_jiffies); + priv->plcp_jiffies = stamp; - if ((combined_plcp_delta > 0) && - ((combined_plcp_delta * 100) / plcp_msec) > - priv->cfg->base_params->plcp_delta_threshold) { - /* - * if plcp_err exceed the threshold, - * the following data is printed in csv format: - * Text: plcp_err exceeded %d, - * Received ofdm.plcp_err, - * Current ofdm.plcp_err, - * Received ofdm_ht.plcp_err, - * Current ofdm_ht.plcp_err, - * combined_plcp_delta, - * plcp_msec - */ - IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " - "%u, %u, %u, %u, %d, %u mSecs\n", - priv->cfg->base_params->plcp_delta_threshold, - le32_to_cpu(ofdm->plcp_err), - le32_to_cpu(ofdm->plcp_err), - le32_to_cpu(ofdm_ht->plcp_err), - le32_to_cpu(ofdm_ht->plcp_err), - combined_plcp_delta, plcp_msec); - - rc = false; - } + if (msecs == 0) + return true; + + if (iwl_bt_statistics(priv)) { + struct statistics_rx_bt *cur, *old; + + cur = &pkt->u.stats_bt.rx; + old = &priv->_agn.statistics_bt.rx; + + delta = le32_to_cpu(cur->ofdm.plcp_err) - + le32_to_cpu(old->ofdm.plcp_err) + + le32_to_cpu(cur->ofdm_ht.plcp_err) - + le32_to_cpu(old->ofdm_ht.plcp_err); + } else { + struct statistics_rx *cur, *old; + + cur = &pkt->u.stats.rx; + old = &priv->_agn.statistics.rx; + + delta = le32_to_cpu(cur->ofdm.plcp_err) - + le32_to_cpu(old->ofdm.plcp_err) + + le32_to_cpu(cur->ofdm_ht.plcp_err) - + le32_to_cpu(old->ofdm_ht.plcp_err); } - return rc; + + /* Can be negative if firmware reseted statistics */ + if (delta <= 0) + return true; + + if ((delta * 100 / msecs) > threshold) { + IWL_DEBUG_RADIO(priv, + "plcp health threshold %u delta %d msecs %u\n", + threshold, delta, msecs); + return false; + } + + return true; } static void iwl_recover_from_statistics(struct iwl_priv *priv, -- cgit v1.2.3 From 410f2bb30d27252cc55a5f41668de60de62e5dc8 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 4 Mar 2011 17:51:51 +0100 Subject: iwlwifi: avoid too frequent recover from statistics Usually H/W generate statistics notify once per about 100ms, but sometimes we can receive notify in shorter time, even 2 ms. This can be problem for plcp health and ack health checking. I.e. with 2 plcp errors happens randomly in 2 ms duration, we exceed plcp delta threshold equal to 100 (2*100/2). Also checking ack's in short time, can results not necessary false positive and firmware reset, for example when channel is noised and we do not receive ACKs frames or when remote device does not send ACKs at the moment. Patch change code to do statistic check and possible recovery only if 99ms elapsed from last check. Forced delay should assure we have good statistic data to estimate hardware state. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 ++ drivers/net/wireless/iwlwifi/iwl-dev.h | 4 +-- drivers/net/wireless/iwlwifi/iwl-rx.c | 46 +++++++++++++++++++--------------- 3 files changed, 30 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 6b6f2d88be16..19bb567d1c52 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3737,6 +3737,8 @@ static int iwl_init_drv(struct iwl_priv *priv) priv->force_reset[IWL_FW_RESET].reset_duration = IWL_DELAY_NEXT_FORCE_FW_RELOAD; + priv->rx_statistics_jiffies = jiffies; + /* Choose which receivers/antennas to use */ if (priv->cfg->ops->hcmd->set_rxon_chain) priv->cfg->ops->hcmd->set_rxon_chain(priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 58165c769cf1..6a41deba6863 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1261,8 +1261,8 @@ struct iwl_priv { /* track IBSS manager (last beacon) status */ u32 ibss_manager; - /* storing the jiffies when the plcp error rate is received */ - unsigned long plcp_jiffies; + /* jiffies when last recovery from statistics was performed */ + unsigned long rx_statistics_jiffies; /* force reset */ struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET]; diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index a70f1eb08e5c..7dc2d39e5cd6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -449,10 +449,8 @@ static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt * to improve the throughput. */ static bool iwl_good_plcp_health(struct iwl_priv *priv, - struct iwl_rx_packet *pkt) + struct iwl_rx_packet *pkt, unsigned int msecs) { - unsigned int msecs; - unsigned long stamp; int delta; int threshold = priv->cfg->base_params->plcp_delta_threshold; @@ -461,13 +459,6 @@ static bool iwl_good_plcp_health(struct iwl_priv *priv, return true; } - stamp = jiffies; - msecs = jiffies_to_msecs(stamp - priv->plcp_jiffies); - priv->plcp_jiffies = stamp; - - if (msecs == 0) - return true; - if (iwl_bt_statistics(priv)) { struct statistics_rx_bt *cur, *old; @@ -508,9 +499,21 @@ static void iwl_recover_from_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt) { const struct iwl_mod_params *mod_params = priv->cfg->mod_params; + unsigned int msecs; + unsigned long stamp; - if (test_bit(STATUS_EXIT_PENDING, &priv->status) || - !iwl_is_any_associated(priv)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + stamp = jiffies; + msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies); + + /* Only gather statistics and update time stamp when not associated */ + if (!iwl_is_any_associated(priv)) + goto out; + + /* Do not check/recover when do not have enough statistics data */ + if (msecs < 99) return; if (mod_params->ack_check && !iwl_good_ack_health(priv, pkt)) { @@ -519,8 +522,18 @@ static void iwl_recover_from_statistics(struct iwl_priv *priv, return; } - if (mod_params->plcp_check && !iwl_good_plcp_health(priv, pkt)) + if (mod_params->plcp_check && !iwl_good_plcp_health(priv, pkt, msecs)) iwl_force_reset(priv, IWL_RF_RESET, false); + +out: + if (iwl_bt_statistics(priv)) + memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt, + sizeof(priv->_agn.statistics_bt)); + else + memcpy(&priv->_agn.statistics, &pkt->u.stats, + sizeof(priv->_agn.statistics)); + + priv->rx_statistics_jiffies = stamp; } /* Calculate noise level, based on measurements during network silence just @@ -669,13 +682,6 @@ static void iwl_rx_statistics(struct iwl_priv *priv, iwl_recover_from_statistics(priv, pkt); - if (iwl_bt_statistics(priv)) - memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt, - sizeof(priv->_agn.statistics_bt)); - else - memcpy(&priv->_agn.statistics, &pkt->u.stats, - sizeof(priv->_agn.statistics)); - set_bit(STATUS_STATISTICS, &priv->status); /* Reschedule the statistics timer to occur in -- cgit v1.2.3 From 2ec38a0359e227c01080dcd670a0368c61ccd9ce Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 4 Mar 2011 17:36:19 -0800 Subject: drivers/rtc/rtc-s3c.c: fix prototype for s3c_rtc_setaie() Fix s3c_rtc_setaie() prototype to eliminate the following compile warning: drivers/rtc/rtc-s3c.c:383: warning: initialization from incompatible pointer type (akpm: the rtc_class_ops.alarm_irq_enable() handler is being passed two arguments where it expects just one, presumably with undesired effects) Signed-off-by: Axel Lin Cc: Alessandro Zummo Cc: Ben Dooks Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-s3c.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index cf953ecbfca9..b80fa2882408 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -77,18 +77,20 @@ static irqreturn_t s3c_rtc_tickirq(int irq, void *id) } /* Update control registers */ -static void s3c_rtc_setaie(int to) +static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) { unsigned int tmp; - pr_debug("%s: aie=%d\n", __func__, to); + pr_debug("%s: aie=%d\n", __func__, enabled); tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; - if (to) + if (enabled) tmp |= S3C2410_RTCALM_ALMEN; writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); + + return 0; } static int s3c_rtc_setpie(struct device *dev, int enabled) @@ -308,7 +310,7 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) writeb(alrm_en, base + S3C2410_RTCALM); - s3c_rtc_setaie(alrm->enabled); + s3c_rtc_setaie(dev, alrm->enabled); return 0; } @@ -440,7 +442,7 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev) rtc_device_unregister(rtc); s3c_rtc_setpie(&dev->dev, 0); - s3c_rtc_setaie(0); + s3c_rtc_setaie(&dev->dev, 0); clk_disable(rtc_clk); clk_put(rtc_clk); -- cgit v1.2.3 From 97e419a082461f8a3a0818834eb88ad41219a1da Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 4 Mar 2011 17:36:22 -0800 Subject: drivers/misc/bmp085.c: add MODULE_DEVICE_TABLE The device table is required to load modules based on modaliases. Signed-off-by: Axel Lin Cc: Shubhrajyoti D Cc: Christoph Mair Cc: Jonathan Cameron Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/bmp085.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/misc/bmp085.c b/drivers/misc/bmp085.c index 63ee4c1a5315..b6e1c9a6679e 100644 --- a/drivers/misc/bmp085.c +++ b/drivers/misc/bmp085.c @@ -449,6 +449,7 @@ static const struct i2c_device_id bmp085_id[] = { { "bmp085", 0 }, { } }; +MODULE_DEVICE_TABLE(i2c, bmp085_id); static struct i2c_driver bmp085_driver = { .driver = { -- cgit v1.2.3 From 95b90afec301f050f72740e8696f7cce8a37db5a Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 4 Mar 2011 17:36:23 -0800 Subject: pps: make pps_gen_parport depend on BROKEN This driver causes hard lockups, when the active clock soure is jiffies. The reason is that it loops with interrupts disabled waiting for a timestamp to be reached by polling getnstimeofday(). Though with a jiffies clocksource, when that code runs on the same CPU which is responsible for updating jiffies, then we loop in circles for ever simply because the timer interrupt cannot update jiffies. So both UP and SMP can be affected. There is no easy fix for that problem so make it depend on BROKEN for now. Signed-off-by: Thomas Gleixner Cc: Alexander Gordeev Cc: Rodolfo Giometti Cc: john stultz Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pps/generators/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pps/generators/Kconfig b/drivers/pps/generators/Kconfig index f3a73dd77660..e4c4f3dc0728 100644 --- a/drivers/pps/generators/Kconfig +++ b/drivers/pps/generators/Kconfig @@ -6,7 +6,7 @@ comment "PPS generators support" config PPS_GENERATOR_PARPORT tristate "Parallel port PPS signal generator" - depends on PARPORT + depends on PARPORT && BROKEN help If you say yes here you get support for a PPS signal generator which utilizes STROBE pin of a parallel port to send PPS signals. It uses -- cgit v1.2.3 From 9dab51daef2e4a0d18d7824e23fcb64a2a86481d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 4 Mar 2011 17:36:27 -0800 Subject: drivers/video/backlight/ltv350qv.c: fix a memory leak Signed-off-by: Axel Lin Cc: Haavard Skinnemoen Cc: Richard Purdie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/ltv350qv.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c index 8010aaeb5adb..dd0e84a9bd2f 100644 --- a/drivers/video/backlight/ltv350qv.c +++ b/drivers/video/backlight/ltv350qv.c @@ -239,11 +239,15 @@ static int __devinit ltv350qv_probe(struct spi_device *spi) lcd->spi = spi; lcd->power = FB_BLANK_POWERDOWN; lcd->buffer = kzalloc(8, GFP_KERNEL); + if (!lcd->buffer) { + ret = -ENOMEM; + goto out_free_lcd; + } ld = lcd_device_register("ltv350qv", &spi->dev, lcd, <v_ops); if (IS_ERR(ld)) { ret = PTR_ERR(ld); - goto out_free_lcd; + goto out_free_buffer; } lcd->ld = ld; @@ -257,6 +261,8 @@ static int __devinit ltv350qv_probe(struct spi_device *spi) out_unregister: lcd_device_unregister(ld); +out_free_buffer: + kfree(lcd->buffer); out_free_lcd: kfree(lcd); return ret; @@ -268,6 +274,7 @@ static int __devexit ltv350qv_remove(struct spi_device *spi) ltv350qv_power(lcd, FB_BLANK_POWERDOWN); lcd_device_unregister(lcd->ld); + kfree(lcd->buffer); kfree(lcd); return 0; -- cgit v1.2.3 From 5a5e4443150713347a7a7e4d0880b343348f5811 Mon Sep 17 00:00:00 2001 From: Hayes Wang Date: Tue, 22 Feb 2011 17:26:21 +0800 Subject: r8169: support the new chips for RTL8105E. Signed-off-by: Hayes Wang Acked-by: Francois Romieu --- drivers/net/r8169.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index de94489cf96e..2543edd9a2cc 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -36,6 +36,7 @@ #define FIRMWARE_8168D_1 "rtl_nic/rtl8168d-1.fw" #define FIRMWARE_8168D_2 "rtl_nic/rtl8168d-2.fw" +#define FIRMWARE_8105E_1 "rtl_nic/rtl8105e-1.fw" #ifdef RTL8169_DEBUG #define assert(expr) \ @@ -123,6 +124,8 @@ enum mac_version { RTL_GIGA_MAC_VER_26 = 0x1a, // 8168D RTL_GIGA_MAC_VER_27 = 0x1b, // 8168DP RTL_GIGA_MAC_VER_28 = 0x1c, // 8168DP + RTL_GIGA_MAC_VER_29 = 0x1d, // 8105E + RTL_GIGA_MAC_VER_30 = 0x1e, // 8105E }; #define _R(NAME,MAC,MASK) \ @@ -160,7 +163,9 @@ static const struct { _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_25, 0xff7e1880), // PCI-E _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_26, 0xff7e1880), // PCI-E _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_27, 0xff7e1880), // PCI-E - _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_28, 0xff7e1880) // PCI-E + _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_28, 0xff7e1880), // PCI-E + _R("RTL8105e", RTL_GIGA_MAC_VER_29, 0xff7e1880), // PCI-E + _R("RTL8105e", RTL_GIGA_MAC_VER_30, 0xff7e1880) // PCI-E }; #undef _R @@ -267,9 +272,15 @@ enum rtl8168_8101_registers { #define EPHYAR_REG_MASK 0x1f #define EPHYAR_REG_SHIFT 16 #define EPHYAR_DATA_MASK 0xffff + DLLPR = 0xd0, +#define PM_SWITCH (1 << 6) DBG_REG = 0xd1, #define FIX_NAK_1 (1 << 4) #define FIX_NAK_2 (1 << 3) + TWSI = 0xd2, + MCU = 0xd3, +#define EN_NDP (1 << 3) +#define EN_OOB_RESET (1 << 2) EFUSEAR = 0xdc, #define EFUSEAR_FLAG 0x80000000 #define EFUSEAR_WRITE_CMD 0x80000000 @@ -568,6 +579,7 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(RTL8169_VERSION); MODULE_FIRMWARE(FIRMWARE_8168D_1); MODULE_FIRMWARE(FIRMWARE_8168D_2); +MODULE_FIRMWARE(FIRMWARE_8105E_1); static int rtl8169_open(struct net_device *dev); static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, @@ -1145,7 +1157,9 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, (tp->mac_version != RTL_GIGA_MAC_VER_13) && (tp->mac_version != RTL_GIGA_MAC_VER_14) && (tp->mac_version != RTL_GIGA_MAC_VER_15) && - (tp->mac_version != RTL_GIGA_MAC_VER_16)) { + (tp->mac_version != RTL_GIGA_MAC_VER_16) && + (tp->mac_version != RTL_GIGA_MAC_VER_29) && + (tp->mac_version != RTL_GIGA_MAC_VER_30)) { giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF; } else { netif_info(tp, link, dev, @@ -1547,6 +1561,9 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, { 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 }, /* 8101 family. */ + { 0x7cf00000, 0x40a00000, RTL_GIGA_MAC_VER_30 }, + { 0x7cf00000, 0x40900000, RTL_GIGA_MAC_VER_29 }, + { 0x7c800000, 0x40800000, RTL_GIGA_MAC_VER_30 }, { 0x7cf00000, 0x34a00000, RTL_GIGA_MAC_VER_09 }, { 0x7cf00000, 0x24a00000, RTL_GIGA_MAC_VER_09 }, { 0x7cf00000, 0x34900000, RTL_GIGA_MAC_VER_08 }, @@ -2423,6 +2440,33 @@ static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); } +static void rtl8105e_hw_phy_config(struct rtl8169_private *tp) +{ + static const struct phy_reg phy_reg_init[] = { + { 0x1f, 0x0005 }, + { 0x1a, 0x0000 }, + { 0x1f, 0x0000 }, + + { 0x1f, 0x0004 }, + { 0x1c, 0x0000 }, + { 0x1f, 0x0000 }, + + { 0x1f, 0x0001 }, + { 0x15, 0x7701 }, + { 0x1f, 0x0000 } + }; + + /* Disable ALDPS before ram code */ + rtl_writephy(tp, 0x1f, 0x0000); + rtl_writephy(tp, 0x18, 0x0310); + msleep(100); + + if (rtl_apply_firmware(tp, FIRMWARE_8105E_1) < 0) + netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); + + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); +} + static void rtl_hw_phy_config(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -2490,6 +2534,10 @@ static void rtl_hw_phy_config(struct net_device *dev) case RTL_GIGA_MAC_VER_28: rtl8168d_4_hw_phy_config(tp); break; + case RTL_GIGA_MAC_VER_29: + case RTL_GIGA_MAC_VER_30: + rtl8105e_hw_phy_config(tp); + break; default: break; @@ -2928,6 +2976,8 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_09: case RTL_GIGA_MAC_VER_10: case RTL_GIGA_MAC_VER_16: + case RTL_GIGA_MAC_VER_29: + case RTL_GIGA_MAC_VER_30: ops->down = r810x_pll_power_down; ops->up = r810x_pll_power_up; break; @@ -3890,6 +3940,37 @@ static void rtl_hw_start_8102e_3(void __iomem *ioaddr, struct pci_dev *pdev) rtl_ephy_write(ioaddr, 0x03, 0xc2f9); } +static void rtl_hw_start_8105e_1(void __iomem *ioaddr, struct pci_dev *pdev) +{ + static const struct ephy_info e_info_8105e_1[] = { + { 0x07, 0, 0x4000 }, + { 0x19, 0, 0x0200 }, + { 0x19, 0, 0x0020 }, + { 0x1e, 0, 0x2000 }, + { 0x03, 0, 0x0001 }, + { 0x19, 0, 0x0100 }, + { 0x19, 0, 0x0004 }, + { 0x0a, 0, 0x0020 } + }; + + /* Force LAN exit from ASPM if Rx/Tx are not idel */ + RTL_W32(FuncEvent, RTL_R32(FuncEvent) | 0x002800); + + /* disable Early Tally Counter */ + RTL_W32(FuncEvent, RTL_R32(FuncEvent) & ~0x010000); + + RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET); + RTL_W8(DLLPR, RTL_R8(DLLPR) | PM_SWITCH); + + rtl_ephy_init(ioaddr, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1)); +} + +static void rtl_hw_start_8105e_2(void __iomem *ioaddr, struct pci_dev *pdev) +{ + rtl_hw_start_8105e_1(ioaddr, pdev); + rtl_ephy_write(ioaddr, 0x1e, rtl_ephy_read(ioaddr, 0x1e) | 0x8000); +} + static void rtl_hw_start_8101(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -3918,6 +3999,13 @@ static void rtl_hw_start_8101(struct net_device *dev) case RTL_GIGA_MAC_VER_09: rtl_hw_start_8102e_2(ioaddr, pdev); break; + + case RTL_GIGA_MAC_VER_29: + rtl_hw_start_8105e_1(ioaddr, pdev); + break; + case RTL_GIGA_MAC_VER_30: + rtl_hw_start_8105e_2(ioaddr, pdev); + break; } RTL_W8(Cfg9346, Cfg9346_Unlock); -- cgit v1.2.3 From 54405cde762408b00a445466a40da4f7f33a8479 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 6 Jan 2011 21:55:13 +0100 Subject: r8169: support control of advertising. This allows "ethtool advertise" to control the speed and duplex features the device offers the switch. Signed-off-by: Oliver Neukum Signed-off-by: Francois Romieu --- drivers/net/r8169.c | 54 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 2543edd9a2cc..d842d00d7abd 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -551,7 +551,7 @@ struct rtl8169_private { void (*up)(struct rtl8169_private *); } pll_power_ops; - int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex); + int (*set_speed)(struct net_device *, u8 aneg, u16 sp, u8 dpx, u32 adv); int (*get_settings)(struct net_device *, struct ethtool_cmd *); void (*phy_reset_enable)(struct rtl8169_private *tp); void (*hw_start)(struct net_device *); @@ -1108,7 +1108,7 @@ static int rtl8169_get_regs_len(struct net_device *dev) } static int rtl8169_set_speed_tbi(struct net_device *dev, - u8 autoneg, u16 speed, u8 duplex) + u8 autoneg, u16 speed, u8 duplex, u32 ignored) { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; @@ -1131,10 +1131,11 @@ static int rtl8169_set_speed_tbi(struct net_device *dev, } static int rtl8169_set_speed_xmii(struct net_device *dev, - u8 autoneg, u16 speed, u8 duplex) + u8 autoneg, u16 speed, u8 duplex, u32 adv) { struct rtl8169_private *tp = netdev_priv(dev); int giga_ctrl, bmcr; + int rc = -EINVAL; rtl_writephy(tp, 0x1f, 0x0000); @@ -1142,8 +1143,18 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, int auto_nego; auto_nego = rtl_readphy(tp, MII_ADVERTISE); - auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL | - ADVERTISE_100HALF | ADVERTISE_100FULL); + auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL | + ADVERTISE_100HALF | ADVERTISE_100FULL); + + if (adv & ADVERTISED_10baseT_Half) + auto_nego |= ADVERTISE_10HALF; + if (adv & ADVERTISED_10baseT_Full) + auto_nego |= ADVERTISE_10FULL; + if (adv & ADVERTISED_100baseT_Half) + auto_nego |= ADVERTISE_100HALF; + if (adv & ADVERTISED_100baseT_Full) + auto_nego |= ADVERTISE_100FULL; + auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; giga_ctrl = rtl_readphy(tp, MII_CTRL1000); @@ -1160,10 +1171,15 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, (tp->mac_version != RTL_GIGA_MAC_VER_16) && (tp->mac_version != RTL_GIGA_MAC_VER_29) && (tp->mac_version != RTL_GIGA_MAC_VER_30)) { - giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF; - } else { + if (adv & ADVERTISED_1000baseT_Half) + giga_ctrl |= ADVERTISE_1000HALF; + if (adv & ADVERTISED_1000baseT_Full) + giga_ctrl |= ADVERTISE_1000FULL; + } else if (adv & (ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full)) { netif_info(tp, link, dev, "PHY does not support 1000Mbps\n"); + goto out; } bmcr = BMCR_ANENABLE | BMCR_ANRESTART; @@ -1178,7 +1194,7 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, else if (speed == SPEED_100) bmcr = BMCR_SPEED100; else - return -EINVAL; + goto out; if (duplex == DUPLEX_FULL) bmcr |= BMCR_FULLDPLX; @@ -1199,16 +1215,18 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, } } - return 0; + rc = 0; +out: + return rc; } static int rtl8169_set_speed(struct net_device *dev, - u8 autoneg, u16 speed, u8 duplex) + u8 autoneg, u16 speed, u8 duplex, u32 advertising) { struct rtl8169_private *tp = netdev_priv(dev); int ret; - ret = tp->set_speed(dev, autoneg, speed, duplex); + ret = tp->set_speed(dev, autoneg, speed, duplex, advertising); if (netif_running(dev) && (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)) mod_timer(&tp->timer, jiffies + RTL8169_PHY_TIMEOUT); @@ -1223,7 +1241,8 @@ static int rtl8169_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) int ret; spin_lock_irqsave(&tp->lock, flags); - ret = rtl8169_set_speed(dev, cmd->autoneg, cmd->speed, cmd->duplex); + ret = rtl8169_set_speed(dev, + cmd->autoneg, cmd->speed, cmd->duplex, cmd->advertising); spin_unlock_irqrestore(&tp->lock, flags); return ret; @@ -2669,11 +2688,12 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp) rtl8169_phy_reset(dev, tp); - /* - * rtl8169_set_speed_xmii takes good care of the Fast Ethernet - * only 8101. Don't panic. - */ - rtl8169_set_speed(dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL); + rtl8169_set_speed(dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL, + ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | + tp->mii.supports_gmii ? + ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full : 0); if (RTL_R8(PHYstatus) & TBI_Enable) netif_info(tp, link, dev, "TBI auto-negotiating\n"); -- cgit v1.2.3 From 7a8fc77b3744e26ce1249d9ccb23e356d6010679 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Tue, 1 Mar 2011 17:18:33 +0100 Subject: r8169: convert to new VLAN model. Signed-off-by: Francois Romieu Reviewed-by: Jesse Gross --- drivers/net/Kconfig | 9 ----- drivers/net/r8169.c | 110 +++++++++++++++++++++++----------------------------- 2 files changed, 49 insertions(+), 70 deletions(-) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index f4b39274308a..8d0d16f93571 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2236,15 +2236,6 @@ config R8169 To compile this driver as a module, choose M here: the module will be called r8169. This is recommended. -config R8169_VLAN - bool "VLAN support" - depends on R8169 && VLAN_8021Q - ---help--- - Say Y here for the r8169 driver to support the functions required - by the kernel 802.1Q code. - - If in doubt, say Y. - config SB1250_MAC tristate "SB1250 Gigabit Ethernet support" depends on SIBYTE_SB1xxx_SOC diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index d842d00d7abd..52e20d5c8e17 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -537,9 +537,6 @@ struct rtl8169_private { u16 napi_event; u16 intr_mask; int phy_1000_ctrl_reg; -#ifdef CONFIG_R8169_VLAN - struct vlan_group *vlgrp; -#endif struct mdio_ops { void (*write)(void __iomem *, int, int); @@ -1276,8 +1273,6 @@ static int rtl8169_set_rx_csum(struct net_device *dev, u32 data) return 0; } -#ifdef CONFIG_R8169_VLAN - static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp, struct sk_buff *skb) { @@ -1285,64 +1280,37 @@ static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp, TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00; } -static void rtl8169_vlan_rx_register(struct net_device *dev, - struct vlan_group *grp) +#define NETIF_F_HW_VLAN_TX_RX (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX) + +static void rtl8169_vlan_mode(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; unsigned long flags; spin_lock_irqsave(&tp->lock, flags); - tp->vlgrp = grp; - /* - * Do not disable RxVlan on 8110SCd. - */ - if (tp->vlgrp || (tp->mac_version == RTL_GIGA_MAC_VER_05)) + if (dev->features & NETIF_F_HW_VLAN_RX) tp->cp_cmd |= RxVlan; else tp->cp_cmd &= ~RxVlan; RTL_W16(CPlusCmd, tp->cp_cmd); + /* PCI commit */ RTL_R16(CPlusCmd); spin_unlock_irqrestore(&tp->lock, flags); + + dev->vlan_features = dev->features &~ NETIF_F_HW_VLAN_TX_RX; } -static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc, - struct sk_buff *skb, int polling) +static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb) { u32 opts2 = le32_to_cpu(desc->opts2); - struct vlan_group *vlgrp = tp->vlgrp; - int ret; - if (vlgrp && (opts2 & RxVlanTag)) { - u16 vtag = swab16(opts2 & 0xffff); + if (opts2 & RxVlanTag) + __vlan_hwaccel_put_tag(skb, swab16(opts2 & 0xffff)); - if (likely(polling)) - vlan_gro_receive(&tp->napi, vlgrp, vtag, skb); - else - __vlan_hwaccel_rx(skb, vlgrp, vtag, polling); - ret = 0; - } else - ret = -1; desc->opts2 = 0; - return ret; -} - -#else /* !CONFIG_R8169_VLAN */ - -static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp, - struct sk_buff *skb) -{ - return 0; -} - -static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc, - struct sk_buff *skb, int polling) -{ - return -1; } -#endif - static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd) { struct rtl8169_private *tp = netdev_priv(dev); @@ -1513,6 +1481,28 @@ static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data) } } +static int rtl8169_set_flags(struct net_device *dev, u32 data) +{ + struct rtl8169_private *tp = netdev_priv(dev); + unsigned long old_feat = dev->features; + int rc; + + if ((tp->mac_version == RTL_GIGA_MAC_VER_05) && + !(data & ETH_FLAG_RXVLAN)) { + netif_info(tp, drv, dev, "8110SCd requires hardware Rx VLAN\n"); + return -EINVAL; + } + + rc = ethtool_op_set_flags(dev, data, ETH_FLAG_TXVLAN | ETH_FLAG_RXVLAN); + if (rc) + return rc; + + if ((old_feat ^ dev->features) & NETIF_F_HW_VLAN_RX) + rtl8169_vlan_mode(dev); + + return 0; +} + static const struct ethtool_ops rtl8169_ethtool_ops = { .get_drvinfo = rtl8169_get_drvinfo, .get_regs_len = rtl8169_get_regs_len, @@ -1532,6 +1522,8 @@ static const struct ethtool_ops rtl8169_ethtool_ops = { .get_strings = rtl8169_get_strings, .get_sset_count = rtl8169_get_sset_count, .get_ethtool_stats = rtl8169_get_ethtool_stats, + .set_flags = rtl8169_set_flags, + .get_flags = ethtool_op_get_flags, }; static void rtl8169_get_mac_version(struct rtl8169_private *tp, @@ -2849,9 +2841,6 @@ static const struct net_device_ops rtl8169_netdev_ops = { .ndo_set_mac_address = rtl_set_mac_address, .ndo_do_ioctl = rtl8169_ioctl, .ndo_set_multicast_list = rtl_set_rx_mode, -#ifdef CONFIG_R8169_VLAN - .ndo_vlan_rx_register = rtl8169_vlan_rx_register, -#endif #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = rtl8169_netpoll, #endif @@ -3145,6 +3134,13 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) /* Identify chip attached to board */ rtl8169_get_mac_version(tp, ioaddr); + /* + * Pretend we are using VLANs; This bypasses a nasty bug where + * Interrupts stop flowing on high load on 8110SCd controllers. + */ + if (tp->mac_version == RTL_GIGA_MAC_VER_05) + tp->cp_cmd |= RxVlan; + rtl_init_mdio_ops(tp); rtl_init_pll_power_ops(tp); @@ -3213,10 +3209,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT); -#ifdef CONFIG_R8169_VLAN - dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; -#endif - dev->features |= NETIF_F_GRO; + dev->features |= NETIF_F_HW_VLAN_TX_RX | NETIF_F_GRO; tp->intr_mask = 0xffff; tp->hw_start = cfg->hw_start; @@ -3334,12 +3327,7 @@ static int rtl8169_open(struct net_device *dev) rtl8169_init_phy(dev, tp); - /* - * Pretend we are using VLANs; This bypasses a nasty bug where - * Interrupts stop flowing on high load on 8110SCd controllers. - */ - if (tp->mac_version == RTL_GIGA_MAC_VER_05) - RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | RxVlan); + rtl8169_vlan_mode(dev); rtl_pll_power_up(tp); @@ -4689,12 +4677,12 @@ static int rtl8169_rx_interrupt(struct net_device *dev, skb_put(skb, pkt_size); skb->protocol = eth_type_trans(skb, dev); - if (rtl8169_rx_vlan_skb(tp, desc, skb, polling) < 0) { - if (likely(polling)) - napi_gro_receive(&tp->napi, skb); - else - netif_rx(skb); - } + rtl8169_rx_vlan_tag(desc, skb); + + if (likely(polling)) + napi_gro_receive(&tp->napi, skb); + else + netif_rx(skb); dev->stats.rx_bytes += pkt_size; dev->stats.rx_packets++; -- cgit v1.2.3 From 60d9f461a20ba59219fdcdc30cbf8e3a4ad3f625 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sun, 23 Jan 2011 00:21:11 +0100 Subject: appletalk: remove the BKL This changes appletalk to use lock_sock instead of lock_kernel for serialization. I tried to make sure that we don't hold the socket lock during sleeping functions, but I did not try to prove whether the locks are necessary in the first place. Compile-tested only. Signed-off-by: Arnd Bergmann Acked-by: David S. Miller Cc: Arnaldo Carvalho de Melo Cc: David Miller Cc: netdev@vger.kernel.org --- drivers/net/appletalk/Kconfig | 1 - net/appletalk/ddp.c | 40 ++++++++++++++++------------------------ 2 files changed, 16 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/appletalk/Kconfig b/drivers/net/appletalk/Kconfig index 0b376a990972..f5a89164e779 100644 --- a/drivers/net/appletalk/Kconfig +++ b/drivers/net/appletalk/Kconfig @@ -3,7 +3,6 @@ # config ATALK tristate "Appletalk protocol support" - depends on BKL # waiting to be removed from net/appletalk/ddp.c select LLC ---help--- AppleTalk is the protocol that Apple computers can use to communicate diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index c410b93fda2e..3d4f4b043406 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -54,7 +54,6 @@ #include #include #include -#include #include /* For TIOCOUTQ/INQ */ #include #include @@ -1052,13 +1051,13 @@ static int atalk_release(struct socket *sock) { struct sock *sk = sock->sk; - lock_kernel(); + lock_sock(sk); if (sk) { sock_orphan(sk); sock->sk = NULL; atalk_destroy_socket(sk); } - unlock_kernel(); + release_sock(sk); return 0; } @@ -1143,7 +1142,7 @@ static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) if (addr->sat_family != AF_APPLETALK) return -EAFNOSUPPORT; - lock_kernel(); + lock_sock(sk); if (addr->sat_addr.s_net == htons(ATADDR_ANYNET)) { struct atalk_addr *ap = atalk_find_primary(); @@ -1179,7 +1178,7 @@ static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) sock_reset_flag(sk, SOCK_ZAPPED); err = 0; out: - unlock_kernel(); + release_sock(sk); return err; } @@ -1215,7 +1214,7 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr, #endif } - lock_kernel(); + lock_sock(sk); err = -EBUSY; if (sock_flag(sk, SOCK_ZAPPED)) if (atalk_autobind(sk) < 0) @@ -1233,7 +1232,7 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr, sk->sk_state = TCP_ESTABLISHED; err = 0; out: - unlock_kernel(); + release_sock(sk); return err; } @@ -1249,7 +1248,7 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr, struct atalk_sock *at = at_sk(sk); int err; - lock_kernel(); + lock_sock(sk); err = -ENOBUFS; if (sock_flag(sk, SOCK_ZAPPED)) if (atalk_autobind(sk) < 0) @@ -1277,17 +1276,7 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr, memcpy(uaddr, &sat, sizeof(sat)); out: - unlock_kernel(); - return err; -} - -static unsigned int atalk_poll(struct file *file, struct socket *sock, - poll_table *wait) -{ - int err; - lock_kernel(); - err = datagram_poll(file, sock, wait); - unlock_kernel(); + release_sock(sk); return err; } @@ -1596,7 +1585,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr if (len > DDP_MAXSZ) return -EMSGSIZE; - lock_kernel(); + lock_sock(sk); if (usat) { err = -EBUSY; if (sock_flag(sk, SOCK_ZAPPED)) @@ -1651,7 +1640,9 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr sk, size, dev->name); size += dev->hard_header_len; + release_sock(sk); skb = sock_alloc_send_skb(sk, size, (flags & MSG_DONTWAIT), &err); + lock_sock(sk); if (!skb) goto out; @@ -1738,7 +1729,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr SOCK_DEBUG(sk, "SK %p: Done write (%Zd).\n", sk, len); out: - unlock_kernel(); + release_sock(sk); return err ? : len; } @@ -1753,9 +1744,10 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr int err = 0; struct sk_buff *skb; - lock_kernel(); skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &err); + lock_sock(sk); + if (!skb) goto out; @@ -1787,7 +1779,7 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr skb_free_datagram(sk, skb); /* Free the datagram. */ out: - unlock_kernel(); + release_sock(sk); return err ? : copied; } @@ -1887,7 +1879,7 @@ static const struct proto_ops atalk_dgram_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = atalk_getname, - .poll = atalk_poll, + .poll = datagram_poll, .ioctl = atalk_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = atalk_compat_ioctl, -- cgit v1.2.3 From 0ee537abbd10a9abf11e1c22ee32a68e8c12ed4a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 6 Mar 2011 09:03:16 +0000 Subject: Revert "drm/i915: fix corruptions on i8xx due to relaxed fencing" This reverts commit c2e0eb167070a6e9dcb49c84c13c79a30d672431. As it turns out, userspace already depends upon being able to enable tiling on existing bo which it promises to be large enough for its purposes i.e. it will not access beyond the end of the last full-tile row. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=35016 Reported-and-tested-by: Kamal Mostafa Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem_tiling.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 79a04fde69b5..22a32b9932c5 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -184,7 +184,7 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) static bool i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) { - int tile_width, tile_height; + int tile_width; /* Linear is always fine */ if (tiling_mode == I915_TILING_NONE) @@ -215,20 +215,6 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) } } - if (IS_GEN2(dev) || - (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))) - tile_height = 32; - else - tile_height = 8; - /* i8xx is strange: It has 2 interleaved rows of tiles, so needs an even - * number of tile rows. */ - if (IS_GEN2(dev)) - tile_height *= 2; - - /* Size needs to be aligned to a full tile row */ - if (size & (tile_height * stride - 1)) - return false; - /* 965+ just needs multiples of tile width */ if (INTEL_INFO(dev)->gen >= 4) { if (stride & (tile_width - 1)) -- cgit v1.2.3 From 91355834646328e7edc6bd25176ae44bcd7386c7 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 4 Mar 2011 19:22:40 +0000 Subject: drm/i915: Do not overflow the MMADDR write FIFO Whilst the GT is powered down (rc6), writes to MMADDR are placed in a FIFO by the System Agent. This is a limited resource, only 64 entries, of which 20 are reserved for Display and PCH writes, and so we must take care not to queue up too many writes. To avoid this, there is counter which we can poll to ensure there are sufficient free entries in the fifo. "Issuing a write to a full FIFO is not supported; at worst it could result in corruption or a system hang." Reported-and-Tested-by: Matt Turner Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=34056 Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 4 ++-- drivers/gpu/drm/i915/i915_drv.c | 14 ++++++++++++-- drivers/gpu/drm/i915/i915_drv.h | 20 +++++++++++++++----- drivers/gpu/drm/i915/i915_reg.h | 2 ++ drivers/gpu/drm/i915/intel_display.c | 8 ++++---- drivers/gpu/drm/i915/intel_ringbuffer.h | 13 +++++++------ 6 files changed, 42 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 3601466c5502..4ff9b6cc973f 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -865,7 +865,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) int max_freq; /* RPSTAT1 is in the GT power well */ - __gen6_force_wake_get(dev_priv); + __gen6_gt_force_wake_get(dev_priv); seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status); seq_printf(m, "RPSTAT1: 0x%08x\n", I915_READ(GEN6_RPSTAT1)); @@ -888,7 +888,7 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n", max_freq * 100); - __gen6_force_wake_put(dev_priv); + __gen6_gt_force_wake_put(dev_priv); } else { seq_printf(m, "no P-state info available\n"); } diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 0ad533f06af9..37d672a116db 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -254,7 +254,7 @@ void intel_detect_pch (struct drm_device *dev) } } -void __gen6_force_wake_get(struct drm_i915_private *dev_priv) +void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) { int count; @@ -270,12 +270,22 @@ void __gen6_force_wake_get(struct drm_i915_private *dev_priv) udelay(10); } -void __gen6_force_wake_put(struct drm_i915_private *dev_priv) +void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) { I915_WRITE_NOTRACE(FORCEWAKE, 0); POSTING_READ(FORCEWAKE); } +void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) +{ + int loop = 500; + u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); + while (fifo < 20 && loop--) { + udelay(10); + fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); + } +} + static int i915_drm_freeze(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 65dfe81d0035..549c046b4ecc 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1353,22 +1353,32 @@ __i915_write(64, q) * must be set to prevent GT core from power down and stale values being * returned. */ -void __gen6_force_wake_get(struct drm_i915_private *dev_priv); -void __gen6_force_wake_put (struct drm_i915_private *dev_priv); -static inline u32 i915_safe_read(struct drm_i915_private *dev_priv, u32 reg) +void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv); +void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv); +void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv); + +static inline u32 i915_gt_read(struct drm_i915_private *dev_priv, u32 reg) { u32 val; if (dev_priv->info->gen >= 6) { - __gen6_force_wake_get(dev_priv); + __gen6_gt_force_wake_get(dev_priv); val = I915_READ(reg); - __gen6_force_wake_put(dev_priv); + __gen6_gt_force_wake_put(dev_priv); } else val = I915_READ(reg); return val; } +static inline void i915_gt_write(struct drm_i915_private *dev_priv, + u32 reg, u32 val) +{ + if (dev_priv->info->gen >= 6) + __gen6_gt_wait_for_fifo(dev_priv); + I915_WRITE(reg, val); +} + static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg, u64 val, int len) { diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 729d4233b763..3e6f486f4605 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3261,6 +3261,8 @@ #define FORCEWAKE 0xA18C #define FORCEWAKE_ACK 0x130090 +#define GT_FIFO_FREE_ENTRIES 0x120008 + #define GEN6_RPNSWREQ 0xA008 #define GEN6_TURBO_DISABLE (1<<31) #define GEN6_FREQUENCY(x) ((x)<<25) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e79b25bbee6c..49fb54fd9a18 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1219,7 +1219,7 @@ static void sandybridge_blit_fbc_update(struct drm_device *dev) u32 blt_ecoskpd; /* Make sure blitter notifies FBC of writes */ - __gen6_force_wake_get(dev_priv); + __gen6_gt_force_wake_get(dev_priv); blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD); blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY << GEN6_BLITTER_LOCK_SHIFT; @@ -1230,7 +1230,7 @@ static void sandybridge_blit_fbc_update(struct drm_device *dev) GEN6_BLITTER_LOCK_SHIFT); I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd); POSTING_READ(GEN6_BLITTER_ECOSKPD); - __gen6_force_wake_put(dev_priv); + __gen6_gt_force_wake_put(dev_priv); } static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) @@ -6282,7 +6282,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) * userspace... */ I915_WRITE(GEN6_RC_STATE, 0); - __gen6_force_wake_get(dev_priv); + __gen6_gt_force_wake_get(dev_priv); /* disable the counters and set deterministic thresholds */ I915_WRITE(GEN6_RC_CONTROL, 0); @@ -6380,7 +6380,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) /* enable all PM interrupts */ I915_WRITE(GEN6_PMINTRMSK, 0); - __gen6_force_wake_put(dev_priv); + __gen6_gt_force_wake_put(dev_priv); } void intel_enable_clock_gating(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 6d6fde85a636..34306865a5df 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -14,22 +14,23 @@ struct intel_hw_status_page { struct drm_i915_gem_object *obj; }; -#define I915_RING_READ(reg) i915_safe_read(dev_priv, reg) +#define I915_RING_READ(reg) i915_gt_read(dev_priv, reg) +#define I915_RING_WRITE(reg, val) i915_gt_write(dev_priv, reg, val) #define I915_READ_TAIL(ring) I915_RING_READ(RING_TAIL((ring)->mmio_base)) -#define I915_WRITE_TAIL(ring, val) I915_WRITE(RING_TAIL((ring)->mmio_base), val) +#define I915_WRITE_TAIL(ring, val) I915_RING_WRITE(RING_TAIL((ring)->mmio_base), val) #define I915_READ_START(ring) I915_RING_READ(RING_START((ring)->mmio_base)) -#define I915_WRITE_START(ring, val) I915_WRITE(RING_START((ring)->mmio_base), val) +#define I915_WRITE_START(ring, val) I915_RING_WRITE(RING_START((ring)->mmio_base), val) #define I915_READ_HEAD(ring) I915_RING_READ(RING_HEAD((ring)->mmio_base)) -#define I915_WRITE_HEAD(ring, val) I915_WRITE(RING_HEAD((ring)->mmio_base), val) +#define I915_WRITE_HEAD(ring, val) I915_RING_WRITE(RING_HEAD((ring)->mmio_base), val) #define I915_READ_CTL(ring) I915_RING_READ(RING_CTL((ring)->mmio_base)) -#define I915_WRITE_CTL(ring, val) I915_WRITE(RING_CTL((ring)->mmio_base), val) +#define I915_WRITE_CTL(ring, val) I915_RING_WRITE(RING_CTL((ring)->mmio_base), val) -#define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val) #define I915_READ_IMR(ring) I915_RING_READ(RING_IMR((ring)->mmio_base)) +#define I915_WRITE_IMR(ring, val) I915_RING_WRITE(RING_IMR((ring)->mmio_base), val) #define I915_READ_NOPID(ring) I915_RING_READ(RING_NOPID((ring)->mmio_base)) #define I915_READ_SYNC_0(ring) I915_RING_READ(RING_SYNC_0((ring)->mmio_base)) -- cgit v1.2.3 From d7a62cd0332115d4c7c4689abea0d889a30d8349 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Fri, 4 Mar 2011 14:04:33 +1030 Subject: virtio: console: Don't access vqs if device was unplugged If a virtio-console device gets unplugged while a port is open, a subsequent close() call on the port accesses vqs to free up buffers. This can lead to a crash. The buffers are already freed up as a result of the call to unplug_ports() from virtcons_remove(). The fix is to simply not access vq information if port->portdev is NULL. Reported-by: juzhang CC: stable@kernel.org Signed-off-by: Amit Shah Signed-off-by: Rusty Russell Signed-off-by: Linus Torvalds --- drivers/char/virtio_console.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 490393186338..84b164d1eb2b 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -388,6 +388,10 @@ static void discard_port_data(struct port *port) unsigned int len; int ret; + if (!port->portdev) { + /* Device has been unplugged. vqs are already gone. */ + return; + } vq = port->in_vq; if (port->inbuf) buf = port->inbuf; @@ -470,6 +474,10 @@ static void reclaim_consumed_buffers(struct port *port) void *buf; unsigned int len; + if (!port->portdev) { + /* Device has been unplugged. vqs are already gone. */ + return; + } while ((buf = virtqueue_get_buf(port->out_vq, &len))) { kfree(buf); port->outvq_full = false; -- cgit v1.2.3 From c4154f25c85a44c8ff331c3d28e8d9d2f710a553 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 6 Mar 2011 10:49:25 +0000 Subject: bnx2x: fix non-pmf device load flow Remove port MAX BW configuration from non-pmf functions, which caused reconfigure of HW according to 10G (fake) link. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 032ae184b605..469ca60195c4 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -2092,8 +2092,9 @@ static void bnx2x_cmng_fns_init(struct bnx2x *bp, u8 read_cfg, u8 cmng_type) bnx2x_calc_vn_weight_sum(bp); /* calculate and set min-max rate for each vn */ - for (vn = VN_0; vn < E1HVN_MAX; vn++) - bnx2x_init_vn_minmax(bp, vn); + if (bp->port.pmf) + for (vn = VN_0; vn < E1HVN_MAX; vn++) + bnx2x_init_vn_minmax(bp, vn); /* always enable rate shaping and fairness */ bp->cmng.flags.cmng_enables |= -- cgit v1.2.3 From 9fdc3e9566b3ae691aefc3aa7b8dca6cac32c95e Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 6 Mar 2011 10:49:15 +0000 Subject: bnx2x: fix link notification Report link to OS and other PFs after HW is fully reconfigured according to new link parameters. (Affected only Multi Function modes). Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 469ca60195c4..aa032339e321 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -2163,13 +2163,6 @@ static void bnx2x_link_attn(struct bnx2x *bp) bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP); } - /* indicate link status only if link status actually changed */ - if (prev_link_status != bp->link_vars.link_status) - bnx2x_link_report(bp); - - if (IS_MF(bp)) - bnx2x_link_sync_notify(bp); - if (bp->link_vars.link_up && bp->link_vars.line_speed) { int cmng_fns = bnx2x_get_cmng_fns_mode(bp); @@ -2181,6 +2174,13 @@ static void bnx2x_link_attn(struct bnx2x *bp) DP(NETIF_MSG_IFUP, "single function mode without fairness\n"); } + + if (IS_MF(bp)) + bnx2x_link_sync_notify(bp); + + /* indicate link status only if link status actually changed */ + if (prev_link_status != bp->link_vars.link_status) + bnx2x_link_report(bp); } void bnx2x__link_status_update(struct bnx2x *bp) -- cgit v1.2.3 From e3835b99333eb3ac7222f6fc0af5cae46074ac49 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 6 Mar 2011 10:50:44 +0000 Subject: bnx2x: (NPAR) prevent HW access in D3 state Changing speed setting in NPAR requires HW access, this patch delays the access to D0 state when performed in D3. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 1 + drivers/net/bnx2x/bnx2x_cmn.c | 22 ++++++++++++++++++++++ drivers/net/bnx2x/bnx2x_cmn.h | 9 +++++++++ drivers/net/bnx2x/bnx2x_ethtool.c | 18 ++++++++---------- 4 files changed, 40 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 7897d114b290..2ac4e3c597fa 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1211,6 +1211,7 @@ struct bnx2x { /* DCBX Negotation results */ struct dcbx_features dcbx_local_feat; u32 dcbx_error; + u32 pending_max; }; /** diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 93798129061b..a71b32940533 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -996,6 +996,23 @@ void bnx2x_free_skbs(struct bnx2x *bp) bnx2x_free_rx_skbs(bp); } +void bnx2x_update_max_mf_config(struct bnx2x *bp, u32 value) +{ + /* load old values */ + u32 mf_cfg = bp->mf_config[BP_VN(bp)]; + + if (value != bnx2x_extract_max_cfg(bp, mf_cfg)) { + /* leave all but MAX value */ + mf_cfg &= ~FUNC_MF_CFG_MAX_BW_MASK; + + /* set new MAX value */ + mf_cfg |= (value << FUNC_MF_CFG_MAX_BW_SHIFT) + & FUNC_MF_CFG_MAX_BW_MASK; + + bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, mf_cfg); + } +} + static void bnx2x_free_msix_irqs(struct bnx2x *bp) { int i, offset = 1; @@ -1464,6 +1481,11 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bnx2x_set_eth_mac(bp, 1); + if (bp->pending_max) { + bnx2x_update_max_mf_config(bp, bp->pending_max); + bp->pending_max = 0; + } + if (bp->port.pmf) bnx2x_initial_phy_init(bp, load_mode); diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 326ba44b3ded..85ea7f26b51f 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -341,6 +341,15 @@ void bnx2x_dcbx_init(struct bnx2x *bp); */ int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state); +/** + * Updates MAX part of MF configuration in HW + * (if required) + * + * @param bp + * @param value + */ +void bnx2x_update_max_mf_config(struct bnx2x *bp, u32 value); + /* dev_close main block */ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode); diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index ef2919987a10..7e92f9d0dcfd 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -238,7 +238,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) speed |= (cmd->speed_hi << 16); if (IS_MF_SI(bp)) { - u32 param = 0, part; + u32 part; u32 line_speed = bp->link_vars.line_speed; /* use 10G if no link detected */ @@ -251,24 +251,22 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) REQ_BC_VER_4_SET_MF_BW); return -EINVAL; } + part = (speed * 100) / line_speed; + if (line_speed < speed || !part) { BNX2X_DEV_INFO("Speed setting should be in a range " "from 1%% to 100%% " "of actual line speed\n"); return -EINVAL; } - /* load old values */ - param = bp->mf_config[BP_VN(bp)]; - /* leave only MIN value */ - param &= FUNC_MF_CFG_MIN_BW_MASK; - - /* set new MAX value */ - param |= (part << FUNC_MF_CFG_MAX_BW_SHIFT) - & FUNC_MF_CFG_MAX_BW_MASK; + if (bp->state != BNX2X_STATE_OPEN) + /* store value for following "load" */ + bp->pending_max = part; + else + bnx2x_update_max_mf_config(bp, part); - bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, param); return 0; } -- cgit v1.2.3 From 9b3de1ef1ba0aa1129a9f857f07a6a97d954c6fd Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Sun, 6 Mar 2011 10:51:37 +0000 Subject: bnx2x: fix MaxBW configuration Increase resolution of MaxBW algorithm to suit Min Bandwidth configuration. Signed-off-by: Dmitry Kravkov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 2ac4e3c597fa..8849699c66c4 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1617,8 +1617,8 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, /* CMNG constants, as derived from system spec calculations */ /* default MIN rate in case VNIC min rate is configured to zero - 100Mbps */ #define DEF_MIN_RATE 100 -/* resolution of the rate shaping timer - 100 usec */ -#define RS_PERIODIC_TIMEOUT_USEC 100 +/* resolution of the rate shaping timer - 400 usec */ +#define RS_PERIODIC_TIMEOUT_USEC 400 /* number of bytes in single QM arbitration cycle - * coefficient for calculating the fairness timer */ #define QM_ARB_BYTES 160000 -- cgit v1.2.3 From 120bdaa47cdd1ca37ce938c888bb08e33e6181a8 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Fri, 4 Mar 2011 19:02:24 +0530 Subject: i2c-omap: Program I2C_WE on OMAP4 to enable i2c wakeup For the I2C module to be wakeup capable, programming I2C_WE register (which was skipped for OMAP4430) is needed even on OMAP4. This fixes i2c controller timeouts which were seen recently with the static dependency being cleared between MPU and L4PER clockdomains. Signed-off-by: Rajendra Nayak [ben-linux@fluff.org: re-flowed description] Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-omap.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 829a2a1029f7..58a58c7eaa17 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -378,9 +378,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) * REVISIT: Some wkup sources might not be needed. */ dev->westate = OMAP_I2C_WE_ALL; - if (dev->rev < OMAP_I2C_REV_ON_4430) - omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, - dev->westate); + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate); } } omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); -- cgit v1.2.3 From a1656b9090f7008d2941c314f5a64724bea2ae37 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 4 Mar 2011 18:48:03 +0000 Subject: drm/i915: Disable GPU semaphores by default Andi Kleen narrowed his GPU hangs on his Sugar Bay (SNB desktop) rev 09 down to the use of GPU semaphores, and we already know that they appear broken up to Huron River (mobile) rev 08. (I'm optimistic that disabling GPU semaphores is simply hiding another bug by the latency and side-effects of the additional device interaction it introduces...) However, use of semaphores is a massive performance improvement... Only as long as the system remains stable. Enable at your peril. Reported-by: Andi Kleen Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=33921 Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.c | 3 +++ drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 4 ++-- 3 files changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 37d672a116db..22ec066adae6 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -46,6 +46,9 @@ module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); unsigned int i915_powersave = 1; module_param_named(powersave, i915_powersave, int, 0600); +unsigned int i915_semaphores = 0; +module_param_named(semaphores, i915_semaphores, int, 0600); + unsigned int i915_enable_rc6 = 0; module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 549c046b4ecc..d023b9b33d60 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -956,6 +956,7 @@ extern struct drm_ioctl_desc i915_ioctls[]; extern int i915_max_ioctl; extern unsigned int i915_fbpercrtc; extern unsigned int i915_powersave; +extern unsigned int i915_semaphores; extern unsigned int i915_lvds_downclock; extern unsigned int i915_panel_use_ssc; extern unsigned int i915_enable_rc6; diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index d2f445e825f2..50ab1614571c 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -772,8 +772,8 @@ i915_gem_execbuffer_sync_rings(struct drm_i915_gem_object *obj, if (from == NULL || to == from) return 0; - /* XXX gpu semaphores are currently causing hard hangs on SNB mobile */ - if (INTEL_INFO(obj->base.dev)->gen < 6 || IS_MOBILE(obj->base.dev)) + /* XXX gpu semaphores are implicated in various hard hangs on SNB */ + if (INTEL_INFO(obj->base.dev)->gen < 6 || !i915_semaphores) return i915_gem_object_wait_rendering(obj, true); idx = intel_ring_sync_index(from, to); -- cgit v1.2.3 From 467cffba85791cdfce38c124d75bd578f4bb8625 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 7 Mar 2011 10:42:03 +0000 Subject: drm/i915: Rebind the buffer if its alignment constraints changes with tiling Early gen3 and gen2 chipset do not have the relaxed per-surface tiling constraints of the later chipsets, so we need to check that the GTT alignment is correct for the new tiling. If it is not, we need to rebind. Reported-by: Daniel Vetter Reviewed-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 3 +++ drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/i915_gem_tiling.c | 21 +++++++++++++++++---- 3 files changed, 21 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d023b9b33d60..456f40484838 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1178,6 +1178,9 @@ void i915_gem_detach_phys_object(struct drm_device *dev, void i915_gem_free_all_phys_object(struct drm_device *dev); void i915_gem_release(struct drm_device *dev, struct drm_file *file); +uint32_t +i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj); + /* i915_gem_gtt.c */ void i915_gem_restore_gtt_mappings(struct drm_device *dev); int __must_check i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index cf4f74c7c6fb..36e66cc5225e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1398,7 +1398,7 @@ i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj) * Return the required GTT alignment for an object, only taking into account * unfenced tiled surface requirements. */ -static uint32_t +uint32_t i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj) { struct drm_device *dev = obj->base.dev; diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 22a32b9932c5..d64843e18df2 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -349,14 +349,27 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, (obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end && i915_gem_object_fence_ok(obj, args->tiling_mode)); - obj->tiling_changed = true; - obj->tiling_mode = args->tiling_mode; - obj->stride = args->stride; + /* Rebind if we need a change of alignment */ + if (!obj->map_and_fenceable) { + u32 unfenced_alignment = + i915_gem_get_unfenced_gtt_alignment(obj); + if (obj->gtt_offset & (unfenced_alignment - 1)) + ret = i915_gem_object_unbind(obj); + } + + if (ret == 0) { + obj->tiling_changed = true; + obj->tiling_mode = args->tiling_mode; + obj->stride = args->stride; + } } + /* we have to maintain this existing ABI... */ + args->stride = obj->stride; + args->tiling_mode = obj->tiling_mode; drm_gem_object_unreference(&obj->base); mutex_unlock(&dev->struct_mutex); - return 0; + return ret; } /** -- cgit v1.2.3 From e4b0b32aa1c0dd7ae6340833dd6b19de46409a88 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Thu, 3 Mar 2011 14:39:05 -0800 Subject: ath5k: Put hardware in PROMISC mode if there is more than 1 stations. It seems ath5k has issues receiving broadcast packets (ARPs) when using multiple STA interfaces associated with multiple APs. This patch ensures the NIC is always in PROMISC mode if there are more than 1 stations associated. Signed-off-by: Ben Greear Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 52 ++++++++++++--------------- drivers/net/wireless/ath/ath5k/base.h | 13 +++++++ drivers/net/wireless/ath/ath5k/mac80211-ops.c | 19 ++++++++-- 3 files changed, 53 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 91411e9b4b68..e6ff62e60a79 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -442,19 +442,9 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) return ath5k_reset(sc, chan, true); } -struct ath_vif_iter_data { - const u8 *hw_macaddr; - u8 mask[ETH_ALEN]; - u8 active_mac[ETH_ALEN]; /* first active MAC */ - bool need_set_hw_addr; - bool found_active; - bool any_assoc; - enum nl80211_iftype opmode; -}; - -static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) +void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { - struct ath_vif_iter_data *iter_data = data; + struct ath5k_vif_iter_data *iter_data = data; int i; struct ath5k_vif *avf = (void *)vif->drv_priv; @@ -484,9 +474,12 @@ static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) */ if (avf->opmode == NL80211_IFTYPE_AP) iter_data->opmode = NL80211_IFTYPE_AP; - else + else { + if (avf->opmode == NL80211_IFTYPE_STATION) + iter_data->n_stas++; if (iter_data->opmode == NL80211_IFTYPE_UNSPECIFIED) iter_data->opmode = avf->opmode; + } } void @@ -494,7 +487,8 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, struct ieee80211_vif *vif) { struct ath_common *common = ath5k_hw_common(sc->ah); - struct ath_vif_iter_data iter_data; + struct ath5k_vif_iter_data iter_data; + u32 rfilt; /* * Use the hardware MAC address as reference, the hardware uses it @@ -505,12 +499,13 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, iter_data.found_active = false; iter_data.need_set_hw_addr = true; iter_data.opmode = NL80211_IFTYPE_UNSPECIFIED; + iter_data.n_stas = 0; if (vif) - ath_vif_iter(&iter_data, vif->addr, vif); + ath5k_vif_iter(&iter_data, vif->addr, vif); /* Get list of all active MAC addresses */ - ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter, + ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter, &iter_data); memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN); @@ -528,20 +523,19 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, if (ath5k_hw_hasbssidmask(sc->ah)) ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); -} -void -ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif) -{ - struct ath5k_hw *ah = sc->ah; - u32 rfilt; + /* Set up RX Filter */ + if (iter_data.n_stas > 1) { + /* If you have multiple STA interfaces connected to + * different APs, ARPs are not received (most of the time?) + * Enabling PROMISC appears to fix that probem. + */ + sc->filter_flags |= AR5K_RX_FILTER_PROM; + } - /* configure rx filter */ rfilt = sc->filter_flags; - ath5k_hw_set_rx_filter(ah, rfilt); + ath5k_hw_set_rx_filter(sc->ah, rfilt); ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); - - ath5k_update_bssid_mask_and_opmode(sc, vif); } static inline int @@ -1117,7 +1111,7 @@ ath5k_rx_start(struct ath5k_softc *sc) spin_unlock_bh(&sc->rxbuflock); ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ - ath5k_mode_setup(sc, NULL); /* set filters, etc. */ + ath5k_update_bssid_mask_and_opmode(sc, NULL); /* set filters, etc. */ ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ return 0; @@ -2923,13 +2917,13 @@ ath5k_deinit_softc(struct ath5k_softc *sc) bool ath_any_vif_assoc(struct ath5k_softc *sc) { - struct ath_vif_iter_data iter_data; + struct ath5k_vif_iter_data iter_data; iter_data.hw_macaddr = NULL; iter_data.any_assoc = false; iter_data.need_set_hw_addr = false; iter_data.found_active = true; - ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter, + ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter, &iter_data); return iter_data.any_assoc; } diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 8f919dca95f1..8d1df1fa2351 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -259,6 +259,19 @@ struct ath5k_softc { struct survey_info survey; /* collected survey info */ }; +struct ath5k_vif_iter_data { + const u8 *hw_macaddr; + u8 mask[ETH_ALEN]; + u8 active_mac[ETH_ALEN]; /* first active MAC */ + bool need_set_hw_addr; + bool found_active; + bool any_assoc; + enum nl80211_iftype opmode; + int n_stas; +}; +void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif); + + #define ath5k_hw_hasbssidmask(_ah) \ (ath5k_hw_get_capability(_ah, AR5K_CAP_BSSIDMASK, 0, NULL) == 0) #define ath5k_hw_hasveol(_ah) \ diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 1fbe3c0b9f08..c9b0b676adda 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -158,8 +158,7 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) memcpy(&avf->lladdr, vif->addr, ETH_ALEN); - ath5k_mode_setup(sc, vif); - + ath5k_update_bssid_mask_and_opmode(sc, vif); ret = 0; end: mutex_unlock(&sc->lock); @@ -381,6 +380,7 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, struct ath5k_softc *sc = hw->priv; struct ath5k_hw *ah = sc->ah; u32 mfilt[2], rfilt; + struct ath5k_vif_iter_data iter_data; /* to count STA interfaces */ mutex_lock(&sc->lock); @@ -454,6 +454,21 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, break; } + iter_data.hw_macaddr = NULL; + iter_data.n_stas = 0; + iter_data.need_set_hw_addr = false; + ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter, + &iter_data); + + /* Set up RX Filter */ + if (iter_data.n_stas > 1) { + /* If you have multiple STA interfaces connected to + * different APs, ARPs are not received (most of the time?) + * Enabling PROMISC appears to fix that probem. + */ + rfilt |= AR5K_RX_FILTER_PROM; + } + /* Set filters */ ath5k_hw_set_rx_filter(ah, rfilt); -- cgit v1.2.3 From 9ac4793359f374e4e9ec6a71b65677096c024acd Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Mon, 7 Mar 2011 15:18:11 +0800 Subject: wireless:ath: use resource_size() help function Signed-off-by: Shan Wei Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ahb.c | 2 +- drivers/net/wireless/ath/ath9k/ahb.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index ae84b86c3bf2..82324e98efef 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -93,7 +93,7 @@ static int ath_ahb_probe(struct platform_device *pdev) goto err_out; } - mem = ioremap_nocache(res->start, res->end - res->start + 1); + mem = ioremap_nocache(res->start, resource_size(res)); if (mem == NULL) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 993672105963..9cb0efa9b4c0 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c @@ -75,7 +75,7 @@ static int ath_ahb_probe(struct platform_device *pdev) goto err_out; } - mem = ioremap_nocache(res->start, res->end - res->start + 1); + mem = ioremap_nocache(res->start, resource_size(res)); if (mem == NULL) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; -- cgit v1.2.3 From 118253ca46262342b87909927fec6214fa4a06a4 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 7 Mar 2011 09:22:24 +0100 Subject: iwlwifi: fix iwl-rx.c compilation My commit 466a19a003f3b45a755bc85f967c21da947f9a00 "iwlwifi: move rx handlers code to iwl-rx.c" breaks compilation on 32 bits. Fix that. Reported-by: Guy, Wey-Yi Reported-by: Daniel Halperin Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-rx.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 7dc2d39e5cd6..6f9a2fa04763 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include "iwl-eeprom.h" -- cgit v1.2.3 From ea29cae9d701d3f57d401e6c295244bcc26fab8e Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Mon, 7 Mar 2011 13:31:24 +0100 Subject: p54spi: Update kconfig help text This updates the p54spi Kconfig help text. The driver works well on n8x0, so remove the words "experimental" and "untested". Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/net/wireless/p54/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/Kconfig b/drivers/net/wireless/p54/Kconfig index 25f965ffc889..0ec55b50798e 100644 --- a/drivers/net/wireless/p54/Kconfig +++ b/drivers/net/wireless/p54/Kconfig @@ -43,9 +43,8 @@ config P54_SPI tristate "Prism54 SPI (stlc45xx) support" depends on P54_COMMON && SPI_MASTER && GENERIC_HARDIRQS ---help--- - This driver is for stlc4550 or stlc4560 based wireless chips. - This driver is experimental, untested and will probably only work on - Nokia's N800/N810 Portable Internet Tablet. + This driver is for stlc4550 or stlc4560 based wireless chips + such as Nokia's N800/N810 Portable Internet Tablet. If you choose to build a module, it'll be called p54spi. -- cgit v1.2.3 From 2a6672f2c425e6d1da2ef7f3169e417cd1f5a6cd Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 7 Mar 2011 15:09:19 +0100 Subject: b43: trivial: update B43_PHY_N description (PHY support) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index 47033f6a1c2b..480595f04411 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig @@ -92,7 +92,7 @@ config B43_PHY_N ---help--- Support for the N-PHY. - This enables support for devices with N-PHY revision up to 2. + This enables support for devices with N-PHY. Say N if you expect high stability and performance. Saying Y will not affect other devices support and may provide support for basic needs. -- cgit v1.2.3 From 8d971e98a7be749445ac6eb9eb37b116f1a6d3c0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 7 Mar 2011 12:03:07 -0800 Subject: Staging: tty: fix build with epca.c driver I forgot to move the digi*.h files from drivers/char/ to drivers/staging/tty/ Thanks to Randy for pointing out the issue. Reported-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/char/digi1.h | 100 ------------------------------ drivers/char/digiFep1.h | 136 ----------------------------------------- drivers/char/digiPCI.h | 42 ------------- drivers/staging/tty/digi1.h | 100 ++++++++++++++++++++++++++++++ drivers/staging/tty/digiFep1.h | 136 +++++++++++++++++++++++++++++++++++++++++ drivers/staging/tty/digiPCI.h | 42 +++++++++++++ 6 files changed, 278 insertions(+), 278 deletions(-) delete mode 100644 drivers/char/digi1.h delete mode 100644 drivers/char/digiFep1.h delete mode 100644 drivers/char/digiPCI.h create mode 100644 drivers/staging/tty/digi1.h create mode 100644 drivers/staging/tty/digiFep1.h create mode 100644 drivers/staging/tty/digiPCI.h (limited to 'drivers') diff --git a/drivers/char/digi1.h b/drivers/char/digi1.h deleted file mode 100644 index 94d4eab5d3ca..000000000000 --- a/drivers/char/digi1.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Definitions for DigiBoard ditty(1) command. */ - -#if !defined(TIOCMODG) -#define TIOCMODG (('d'<<8) | 250) /* get modem ctrl state */ -#define TIOCMODS (('d'<<8) | 251) /* set modem ctrl state */ -#endif - -#if !defined(TIOCMSET) -#define TIOCMSET (('d'<<8) | 252) /* set modem ctrl state */ -#define TIOCMGET (('d'<<8) | 253) /* set modem ctrl state */ -#endif - -#if !defined(TIOCMBIC) -#define TIOCMBIC (('d'<<8) | 254) /* set modem ctrl state */ -#define TIOCMBIS (('d'<<8) | 255) /* set modem ctrl state */ -#endif - -#if !defined(TIOCSDTR) -#define TIOCSDTR (('e'<<8) | 0) /* set DTR */ -#define TIOCCDTR (('e'<<8) | 1) /* clear DTR */ -#endif - -/************************************************************************ - * Ioctl command arguments for DIGI parameters. - ************************************************************************/ -#define DIGI_GETA (('e'<<8) | 94) /* Read params */ - -#define DIGI_SETA (('e'<<8) | 95) /* Set params */ -#define DIGI_SETAW (('e'<<8) | 96) /* Drain & set params */ -#define DIGI_SETAF (('e'<<8) | 97) /* Drain, flush & set params */ - -#define DIGI_GETFLOW (('e'<<8) | 99) /* Get startc/stopc flow */ - /* control characters */ -#define DIGI_SETFLOW (('e'<<8) | 100) /* Set startc/stopc flow */ - /* control characters */ -#define DIGI_GETAFLOW (('e'<<8) | 101) /* Get Aux. startc/stopc */ - /* flow control chars */ -#define DIGI_SETAFLOW (('e'<<8) | 102) /* Set Aux. startc/stopc */ - /* flow control chars */ - -#define DIGI_GETINFO (('e'<<8) | 103) /* Fill in digi_info */ -#define DIGI_POLLER (('e'<<8) | 104) /* Turn on/off poller */ -#define DIGI_INIT (('e'<<8) | 105) /* Allow things to run. */ - -struct digiflow_struct -{ - unsigned char startc; /* flow cntl start char */ - unsigned char stopc; /* flow cntl stop char */ -}; - -typedef struct digiflow_struct digiflow_t; - - -/************************************************************************ - * Values for digi_flags - ************************************************************************/ -#define DIGI_IXON 0x0001 /* Handle IXON in the FEP */ -#define DIGI_FAST 0x0002 /* Fast baud rates */ -#define RTSPACE 0x0004 /* RTS input flow control */ -#define CTSPACE 0x0008 /* CTS output flow control */ -#define DSRPACE 0x0010 /* DSR output flow control */ -#define DCDPACE 0x0020 /* DCD output flow control */ -#define DTRPACE 0x0040 /* DTR input flow control */ -#define DIGI_FORCEDCD 0x0100 /* Force carrier */ -#define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */ -#define DIGI_AIXON 0x0400 /* Aux flow control in fep */ - - -/************************************************************************ - * Values for digiDload - ************************************************************************/ -#define NORMAL 0 -#define PCI_CTL 1 - -#define SIZE8 0 -#define SIZE16 1 -#define SIZE32 2 - -/************************************************************************ - * Structure used with ioctl commands for DIGI parameters. - ************************************************************************/ -struct digi_struct -{ - unsigned short digi_flags; /* Flags (see above) */ -}; - -typedef struct digi_struct digi_t; - -struct digi_info -{ - unsigned long board; /* Which board is this ? */ - unsigned char status; /* Alive or dead */ - unsigned char type; /* see epca.h */ - unsigned char subtype; /* For future XEM, XR, etc ... */ - unsigned short numports; /* Number of ports configured */ - unsigned char *port; /* I/O Address */ - unsigned char *membase; /* DPR Address */ - unsigned char *version; /* For future ... */ - unsigned short windowData; /* For future ... */ -} ; diff --git a/drivers/char/digiFep1.h b/drivers/char/digiFep1.h deleted file mode 100644 index 3c1f1922c798..000000000000 --- a/drivers/char/digiFep1.h +++ /dev/null @@ -1,136 +0,0 @@ - -#define CSTART 0x400L -#define CMAX 0x800L -#define ISTART 0x800L -#define IMAX 0xC00L -#define CIN 0xD10L -#define GLOBAL 0xD10L -#define EIN 0xD18L -#define FEPSTAT 0xD20L -#define CHANSTRUCT 0x1000L -#define RXTXBUF 0x4000L - - -struct global_data -{ - u16 cin; - u16 cout; - u16 cstart; - u16 cmax; - u16 ein; - u16 eout; - u16 istart; - u16 imax; -}; - - -struct board_chan -{ - u32 filler1; - u32 filler2; - u16 tseg; - u16 tin; - u16 tout; - u16 tmax; - - u16 rseg; - u16 rin; - u16 rout; - u16 rmax; - - u16 tlow; - u16 rlow; - u16 rhigh; - u16 incr; - - u16 etime; - u16 edelay; - unchar *dev; - - u16 iflag; - u16 oflag; - u16 cflag; - u16 gmask; - - u16 col; - u16 delay; - u16 imask; - u16 tflush; - - u32 filler3; - u32 filler4; - u32 filler5; - u32 filler6; - - u8 num; - u8 ract; - u8 bstat; - u8 tbusy; - u8 iempty; - u8 ilow; - u8 idata; - u8 eflag; - - u8 tflag; - u8 rflag; - u8 xmask; - u8 xval; - u8 mstat; - u8 mchange; - u8 mint; - u8 lstat; - - u8 mtran; - u8 orun; - u8 startca; - u8 stopca; - u8 startc; - u8 stopc; - u8 vnext; - u8 hflow; - - u8 fillc; - u8 ochar; - u8 omask; - - u8 filler7; - u8 filler8[28]; -}; - - -#define SRXLWATER 0xE0 -#define SRXHWATER 0xE1 -#define STOUT 0xE2 -#define PAUSETX 0xE3 -#define RESUMETX 0xE4 -#define SAUXONOFFC 0xE6 -#define SENDBREAK 0xE8 -#define SETMODEM 0xE9 -#define SETIFLAGS 0xEA -#define SONOFFC 0xEB -#define STXLWATER 0xEC -#define PAUSERX 0xEE -#define RESUMERX 0xEF -#define SETBUFFER 0xF2 -#define SETCOOKED 0xF3 -#define SETHFLOW 0xF4 -#define SETCTRLFLAGS 0xF5 -#define SETVNEXT 0xF6 - - - -#define BREAK_IND 0x01 -#define LOWTX_IND 0x02 -#define EMPTYTX_IND 0x04 -#define DATA_IND 0x08 -#define MODEMCHG_IND 0x20 - -#define FEP_HUPCL 0002000 -#if 0 -#define RTS 0x02 -#define CD 0x08 -#define DSR 0x10 -#define CTS 0x20 -#define RI 0x40 -#define DTR 0x80 -#endif diff --git a/drivers/char/digiPCI.h b/drivers/char/digiPCI.h deleted file mode 100644 index 6ca7819e5069..000000000000 --- a/drivers/char/digiPCI.h +++ /dev/null @@ -1,42 +0,0 @@ -/************************************************************************* - * Defines and structure definitions for PCI BIOS Interface - *************************************************************************/ -#define PCIMAX 32 /* maximum number of PCI boards */ - - -#define PCI_VENDOR_DIGI 0x114F -#define PCI_DEVICE_EPC 0x0002 -#define PCI_DEVICE_RIGHTSWITCH 0x0003 /* For testing */ -#define PCI_DEVICE_XEM 0x0004 -#define PCI_DEVICE_XR 0x0005 -#define PCI_DEVICE_CX 0x0006 -#define PCI_DEVICE_XRJ 0x0009 /* Jupiter boards with */ -#define PCI_DEVICE_EPCJ 0x000a /* PLX 9060 chip for PCI */ - - -/* - * On the PCI boards, there is no IO space allocated - * The I/O registers will be in the first 3 bytes of the - * upper 2MB of the 4MB memory space. The board memory - * will be mapped into the low 2MB of the 4MB memory space - */ - -/* Potential location of PCI Bios from E0000 to FFFFF*/ -#define PCI_BIOS_SIZE 0x00020000 - -/* Size of Memory and I/O for PCI (4MB) */ -#define PCI_RAM_SIZE 0x00400000 - -/* Size of Memory (2MB) */ -#define PCI_MEM_SIZE 0x00200000 - -/* Offset of I/0 in Memory (2MB) */ -#define PCI_IO_OFFSET 0x00200000 - -#define MEMOUTB(basemem, pnum, setmemval) *(caddr_t)((basemem) + ( PCI_IO_OFFSET | pnum << 4 | pnum )) = (setmemval) -#define MEMINB(basemem, pnum) *(caddr_t)((basemem) + (PCI_IO_OFFSET | pnum << 4 | pnum )) /* for PCI I/O */ - - - - - diff --git a/drivers/staging/tty/digi1.h b/drivers/staging/tty/digi1.h new file mode 100644 index 000000000000..94d4eab5d3ca --- /dev/null +++ b/drivers/staging/tty/digi1.h @@ -0,0 +1,100 @@ +/* Definitions for DigiBoard ditty(1) command. */ + +#if !defined(TIOCMODG) +#define TIOCMODG (('d'<<8) | 250) /* get modem ctrl state */ +#define TIOCMODS (('d'<<8) | 251) /* set modem ctrl state */ +#endif + +#if !defined(TIOCMSET) +#define TIOCMSET (('d'<<8) | 252) /* set modem ctrl state */ +#define TIOCMGET (('d'<<8) | 253) /* set modem ctrl state */ +#endif + +#if !defined(TIOCMBIC) +#define TIOCMBIC (('d'<<8) | 254) /* set modem ctrl state */ +#define TIOCMBIS (('d'<<8) | 255) /* set modem ctrl state */ +#endif + +#if !defined(TIOCSDTR) +#define TIOCSDTR (('e'<<8) | 0) /* set DTR */ +#define TIOCCDTR (('e'<<8) | 1) /* clear DTR */ +#endif + +/************************************************************************ + * Ioctl command arguments for DIGI parameters. + ************************************************************************/ +#define DIGI_GETA (('e'<<8) | 94) /* Read params */ + +#define DIGI_SETA (('e'<<8) | 95) /* Set params */ +#define DIGI_SETAW (('e'<<8) | 96) /* Drain & set params */ +#define DIGI_SETAF (('e'<<8) | 97) /* Drain, flush & set params */ + +#define DIGI_GETFLOW (('e'<<8) | 99) /* Get startc/stopc flow */ + /* control characters */ +#define DIGI_SETFLOW (('e'<<8) | 100) /* Set startc/stopc flow */ + /* control characters */ +#define DIGI_GETAFLOW (('e'<<8) | 101) /* Get Aux. startc/stopc */ + /* flow control chars */ +#define DIGI_SETAFLOW (('e'<<8) | 102) /* Set Aux. startc/stopc */ + /* flow control chars */ + +#define DIGI_GETINFO (('e'<<8) | 103) /* Fill in digi_info */ +#define DIGI_POLLER (('e'<<8) | 104) /* Turn on/off poller */ +#define DIGI_INIT (('e'<<8) | 105) /* Allow things to run. */ + +struct digiflow_struct +{ + unsigned char startc; /* flow cntl start char */ + unsigned char stopc; /* flow cntl stop char */ +}; + +typedef struct digiflow_struct digiflow_t; + + +/************************************************************************ + * Values for digi_flags + ************************************************************************/ +#define DIGI_IXON 0x0001 /* Handle IXON in the FEP */ +#define DIGI_FAST 0x0002 /* Fast baud rates */ +#define RTSPACE 0x0004 /* RTS input flow control */ +#define CTSPACE 0x0008 /* CTS output flow control */ +#define DSRPACE 0x0010 /* DSR output flow control */ +#define DCDPACE 0x0020 /* DCD output flow control */ +#define DTRPACE 0x0040 /* DTR input flow control */ +#define DIGI_FORCEDCD 0x0100 /* Force carrier */ +#define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */ +#define DIGI_AIXON 0x0400 /* Aux flow control in fep */ + + +/************************************************************************ + * Values for digiDload + ************************************************************************/ +#define NORMAL 0 +#define PCI_CTL 1 + +#define SIZE8 0 +#define SIZE16 1 +#define SIZE32 2 + +/************************************************************************ + * Structure used with ioctl commands for DIGI parameters. + ************************************************************************/ +struct digi_struct +{ + unsigned short digi_flags; /* Flags (see above) */ +}; + +typedef struct digi_struct digi_t; + +struct digi_info +{ + unsigned long board; /* Which board is this ? */ + unsigned char status; /* Alive or dead */ + unsigned char type; /* see epca.h */ + unsigned char subtype; /* For future XEM, XR, etc ... */ + unsigned short numports; /* Number of ports configured */ + unsigned char *port; /* I/O Address */ + unsigned char *membase; /* DPR Address */ + unsigned char *version; /* For future ... */ + unsigned short windowData; /* For future ... */ +} ; diff --git a/drivers/staging/tty/digiFep1.h b/drivers/staging/tty/digiFep1.h new file mode 100644 index 000000000000..3c1f1922c798 --- /dev/null +++ b/drivers/staging/tty/digiFep1.h @@ -0,0 +1,136 @@ + +#define CSTART 0x400L +#define CMAX 0x800L +#define ISTART 0x800L +#define IMAX 0xC00L +#define CIN 0xD10L +#define GLOBAL 0xD10L +#define EIN 0xD18L +#define FEPSTAT 0xD20L +#define CHANSTRUCT 0x1000L +#define RXTXBUF 0x4000L + + +struct global_data +{ + u16 cin; + u16 cout; + u16 cstart; + u16 cmax; + u16 ein; + u16 eout; + u16 istart; + u16 imax; +}; + + +struct board_chan +{ + u32 filler1; + u32 filler2; + u16 tseg; + u16 tin; + u16 tout; + u16 tmax; + + u16 rseg; + u16 rin; + u16 rout; + u16 rmax; + + u16 tlow; + u16 rlow; + u16 rhigh; + u16 incr; + + u16 etime; + u16 edelay; + unchar *dev; + + u16 iflag; + u16 oflag; + u16 cflag; + u16 gmask; + + u16 col; + u16 delay; + u16 imask; + u16 tflush; + + u32 filler3; + u32 filler4; + u32 filler5; + u32 filler6; + + u8 num; + u8 ract; + u8 bstat; + u8 tbusy; + u8 iempty; + u8 ilow; + u8 idata; + u8 eflag; + + u8 tflag; + u8 rflag; + u8 xmask; + u8 xval; + u8 mstat; + u8 mchange; + u8 mint; + u8 lstat; + + u8 mtran; + u8 orun; + u8 startca; + u8 stopca; + u8 startc; + u8 stopc; + u8 vnext; + u8 hflow; + + u8 fillc; + u8 ochar; + u8 omask; + + u8 filler7; + u8 filler8[28]; +}; + + +#define SRXLWATER 0xE0 +#define SRXHWATER 0xE1 +#define STOUT 0xE2 +#define PAUSETX 0xE3 +#define RESUMETX 0xE4 +#define SAUXONOFFC 0xE6 +#define SENDBREAK 0xE8 +#define SETMODEM 0xE9 +#define SETIFLAGS 0xEA +#define SONOFFC 0xEB +#define STXLWATER 0xEC +#define PAUSERX 0xEE +#define RESUMERX 0xEF +#define SETBUFFER 0xF2 +#define SETCOOKED 0xF3 +#define SETHFLOW 0xF4 +#define SETCTRLFLAGS 0xF5 +#define SETVNEXT 0xF6 + + + +#define BREAK_IND 0x01 +#define LOWTX_IND 0x02 +#define EMPTYTX_IND 0x04 +#define DATA_IND 0x08 +#define MODEMCHG_IND 0x20 + +#define FEP_HUPCL 0002000 +#if 0 +#define RTS 0x02 +#define CD 0x08 +#define DSR 0x10 +#define CTS 0x20 +#define RI 0x40 +#define DTR 0x80 +#endif diff --git a/drivers/staging/tty/digiPCI.h b/drivers/staging/tty/digiPCI.h new file mode 100644 index 000000000000..6ca7819e5069 --- /dev/null +++ b/drivers/staging/tty/digiPCI.h @@ -0,0 +1,42 @@ +/************************************************************************* + * Defines and structure definitions for PCI BIOS Interface + *************************************************************************/ +#define PCIMAX 32 /* maximum number of PCI boards */ + + +#define PCI_VENDOR_DIGI 0x114F +#define PCI_DEVICE_EPC 0x0002 +#define PCI_DEVICE_RIGHTSWITCH 0x0003 /* For testing */ +#define PCI_DEVICE_XEM 0x0004 +#define PCI_DEVICE_XR 0x0005 +#define PCI_DEVICE_CX 0x0006 +#define PCI_DEVICE_XRJ 0x0009 /* Jupiter boards with */ +#define PCI_DEVICE_EPCJ 0x000a /* PLX 9060 chip for PCI */ + + +/* + * On the PCI boards, there is no IO space allocated + * The I/O registers will be in the first 3 bytes of the + * upper 2MB of the 4MB memory space. The board memory + * will be mapped into the low 2MB of the 4MB memory space + */ + +/* Potential location of PCI Bios from E0000 to FFFFF*/ +#define PCI_BIOS_SIZE 0x00020000 + +/* Size of Memory and I/O for PCI (4MB) */ +#define PCI_RAM_SIZE 0x00400000 + +/* Size of Memory (2MB) */ +#define PCI_MEM_SIZE 0x00200000 + +/* Offset of I/0 in Memory (2MB) */ +#define PCI_IO_OFFSET 0x00200000 + +#define MEMOUTB(basemem, pnum, setmemval) *(caddr_t)((basemem) + ( PCI_IO_OFFSET | pnum << 4 | pnum )) = (setmemval) +#define MEMINB(basemem, pnum) *(caddr_t)((basemem) + (PCI_IO_OFFSET | pnum << 4 | pnum )) /* for PCI I/O */ + + + + + -- cgit v1.2.3 From b71dc8873427bb5bf0ce31b968c3f219a1d6d014 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 3 Mar 2011 18:38:22 +0100 Subject: tty: move cd1865.h to drivers/staging/tty/ The file is required by the specialix driver, which was moved to drivers/staging/. Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/char/cd1865.h | 263 ------------------------------------------- drivers/staging/tty/cd1865.h | 263 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 263 insertions(+), 263 deletions(-) delete mode 100644 drivers/char/cd1865.h create mode 100644 drivers/staging/tty/cd1865.h (limited to 'drivers') diff --git a/drivers/char/cd1865.h b/drivers/char/cd1865.h deleted file mode 100644 index 9940966e7a1d..000000000000 --- a/drivers/char/cd1865.h +++ /dev/null @@ -1,263 +0,0 @@ -/* - * linux/drivers/char/cd1865.h -- Definitions relating to the CD1865 - * for the Specialix IO8+ multiport serial driver. - * - * Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl) - * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) - * - * Specialix pays for the development and support of this driver. - * Please DO contact io8-linux@specialix.co.uk if you require - * support. - * - * This driver was developped in the BitWizard linux device - * driver service. If you require a linux device driver for your - * product, please contact devices@BitWizard.nl for a quote. - * - */ - -/* - * Definitions for Driving CD180/CD1864/CD1865 based eightport serial cards. - */ - - -/* Values of choice for Interrupt ACKs */ -/* These values are "obligatory" if you use the register based - * interrupt acknowledgements. See page 99-101 of V2.0 of the CD1865 - * databook */ -#define SX_ACK_MINT 0x75 /* goes to PILR1 */ -#define SX_ACK_TINT 0x76 /* goes to PILR2 */ -#define SX_ACK_RINT 0x77 /* goes to PILR3 */ - -/* Chip ID (is used when chips ar daisy chained.) */ -#define SX_ID 0x10 - -/* Definitions for Cirrus Logic CL-CD186x 8-port async mux chip */ - -#define CD186x_NCH 8 /* Total number of channels */ -#define CD186x_TPC 16 /* Ticks per character */ -#define CD186x_NFIFO 8 /* TX FIFO size */ - - -/* Global registers */ - -#define CD186x_GIVR 0x40 /* Global Interrupt Vector Register */ -#define CD186x_GICR 0x41 /* Global Interrupting Channel Register */ -#define CD186x_PILR1 0x61 /* Priority Interrupt Level Register 1 */ -#define CD186x_PILR2 0x62 /* Priority Interrupt Level Register 2 */ -#define CD186x_PILR3 0x63 /* Priority Interrupt Level Register 3 */ -#define CD186x_CAR 0x64 /* Channel Access Register */ -#define CD186x_SRSR 0x65 /* Channel Access Register */ -#define CD186x_GFRCR 0x6b /* Global Firmware Revision Code Register */ -#define CD186x_PPRH 0x70 /* Prescaler Period Register High */ -#define CD186x_PPRL 0x71 /* Prescaler Period Register Low */ -#define CD186x_RDR 0x78 /* Receiver Data Register */ -#define CD186x_RCSR 0x7a /* Receiver Character Status Register */ -#define CD186x_TDR 0x7b /* Transmit Data Register */ -#define CD186x_EOIR 0x7f /* End of Interrupt Register */ -#define CD186x_MRAR 0x75 /* Modem Request Acknowledge register */ -#define CD186x_TRAR 0x76 /* Transmit Request Acknowledge register */ -#define CD186x_RRAR 0x77 /* Receive Request Acknowledge register */ -#define CD186x_SRCR 0x66 /* Service Request Configuration register */ - -/* Channel Registers */ - -#define CD186x_CCR 0x01 /* Channel Command Register */ -#define CD186x_IER 0x02 /* Interrupt Enable Register */ -#define CD186x_COR1 0x03 /* Channel Option Register 1 */ -#define CD186x_COR2 0x04 /* Channel Option Register 2 */ -#define CD186x_COR3 0x05 /* Channel Option Register 3 */ -#define CD186x_CCSR 0x06 /* Channel Control Status Register */ -#define CD186x_RDCR 0x07 /* Receive Data Count Register */ -#define CD186x_SCHR1 0x09 /* Special Character Register 1 */ -#define CD186x_SCHR2 0x0a /* Special Character Register 2 */ -#define CD186x_SCHR3 0x0b /* Special Character Register 3 */ -#define CD186x_SCHR4 0x0c /* Special Character Register 4 */ -#define CD186x_MCOR1 0x10 /* Modem Change Option 1 Register */ -#define CD186x_MCOR2 0x11 /* Modem Change Option 2 Register */ -#define CD186x_MCR 0x12 /* Modem Change Register */ -#define CD186x_RTPR 0x18 /* Receive Timeout Period Register */ -#define CD186x_MSVR 0x28 /* Modem Signal Value Register */ -#define CD186x_MSVRTS 0x29 /* Modem Signal Value Register */ -#define CD186x_MSVDTR 0x2a /* Modem Signal Value Register */ -#define CD186x_RBPRH 0x31 /* Receive Baud Rate Period Register High */ -#define CD186x_RBPRL 0x32 /* Receive Baud Rate Period Register Low */ -#define CD186x_TBPRH 0x39 /* Transmit Baud Rate Period Register High */ -#define CD186x_TBPRL 0x3a /* Transmit Baud Rate Period Register Low */ - - -/* Global Interrupt Vector Register (R/W) */ - -#define GIVR_ITMASK 0x07 /* Interrupt type mask */ -#define GIVR_IT_MODEM 0x01 /* Modem Signal Change Interrupt */ -#define GIVR_IT_TX 0x02 /* Transmit Data Interrupt */ -#define GIVR_IT_RCV 0x03 /* Receive Good Data Interrupt */ -#define GIVR_IT_REXC 0x07 /* Receive Exception Interrupt */ - - -/* Global Interrupt Channel Register (R/W) */ - -#define GICR_CHAN 0x1c /* Channel Number Mask */ -#define GICR_CHAN_OFF 2 /* Channel Number shift */ - - -/* Channel Address Register (R/W) */ - -#define CAR_CHAN 0x07 /* Channel Number Mask */ -#define CAR_A7 0x08 /* A7 Address Extension (unused) */ - - -/* Receive Character Status Register (R/O) */ - -#define RCSR_TOUT 0x80 /* Rx Timeout */ -#define RCSR_SCDET 0x70 /* Special Character Detected Mask */ -#define RCSR_NO_SC 0x00 /* No Special Characters Detected */ -#define RCSR_SC_1 0x10 /* Special Char 1 (or 1 & 3) Detected */ -#define RCSR_SC_2 0x20 /* Special Char 2 (or 2 & 4) Detected */ -#define RCSR_SC_3 0x30 /* Special Char 3 Detected */ -#define RCSR_SC_4 0x40 /* Special Char 4 Detected */ -#define RCSR_BREAK 0x08 /* Break has been detected */ -#define RCSR_PE 0x04 /* Parity Error */ -#define RCSR_FE 0x02 /* Frame Error */ -#define RCSR_OE 0x01 /* Overrun Error */ - - -/* Channel Command Register (R/W) (commands in groups can be OR-ed) */ - -#define CCR_HARDRESET 0x81 /* Reset the chip */ - -#define CCR_SOFTRESET 0x80 /* Soft Channel Reset */ - -#define CCR_CORCHG1 0x42 /* Channel Option Register 1 Changed */ -#define CCR_CORCHG2 0x44 /* Channel Option Register 2 Changed */ -#define CCR_CORCHG3 0x48 /* Channel Option Register 3 Changed */ - -#define CCR_SSCH1 0x21 /* Send Special Character 1 */ - -#define CCR_SSCH2 0x22 /* Send Special Character 2 */ - -#define CCR_SSCH3 0x23 /* Send Special Character 3 */ - -#define CCR_SSCH4 0x24 /* Send Special Character 4 */ - -#define CCR_TXEN 0x18 /* Enable Transmitter */ -#define CCR_RXEN 0x12 /* Enable Receiver */ - -#define CCR_TXDIS 0x14 /* Disable Transmitter */ -#define CCR_RXDIS 0x11 /* Disable Receiver */ - - -/* Interrupt Enable Register (R/W) */ - -#define IER_DSR 0x80 /* Enable interrupt on DSR change */ -#define IER_CD 0x40 /* Enable interrupt on CD change */ -#define IER_CTS 0x20 /* Enable interrupt on CTS change */ -#define IER_RXD 0x10 /* Enable interrupt on Receive Data */ -#define IER_RXSC 0x08 /* Enable interrupt on Receive Spec. Char */ -#define IER_TXRDY 0x04 /* Enable interrupt on TX FIFO empty */ -#define IER_TXEMPTY 0x02 /* Enable interrupt on TX completely empty */ -#define IER_RET 0x01 /* Enable interrupt on RX Exc. Timeout */ - - -/* Channel Option Register 1 (R/W) */ - -#define COR1_ODDP 0x80 /* Odd Parity */ -#define COR1_PARMODE 0x60 /* Parity Mode mask */ -#define COR1_NOPAR 0x00 /* No Parity */ -#define COR1_FORCEPAR 0x20 /* Force Parity */ -#define COR1_NORMPAR 0x40 /* Normal Parity */ -#define COR1_IGNORE 0x10 /* Ignore Parity on RX */ -#define COR1_STOPBITS 0x0c /* Number of Stop Bits */ -#define COR1_1SB 0x00 /* 1 Stop Bit */ -#define COR1_15SB 0x04 /* 1.5 Stop Bits */ -#define COR1_2SB 0x08 /* 2 Stop Bits */ -#define COR1_CHARLEN 0x03 /* Character Length */ -#define COR1_5BITS 0x00 /* 5 bits */ -#define COR1_6BITS 0x01 /* 6 bits */ -#define COR1_7BITS 0x02 /* 7 bits */ -#define COR1_8BITS 0x03 /* 8 bits */ - - -/* Channel Option Register 2 (R/W) */ - -#define COR2_IXM 0x80 /* Implied XON mode */ -#define COR2_TXIBE 0x40 /* Enable In-Band (XON/XOFF) Flow Control */ -#define COR2_ETC 0x20 /* Embedded Tx Commands Enable */ -#define COR2_LLM 0x10 /* Local Loopback Mode */ -#define COR2_RLM 0x08 /* Remote Loopback Mode */ -#define COR2_RTSAO 0x04 /* RTS Automatic Output Enable */ -#define COR2_CTSAE 0x02 /* CTS Automatic Enable */ -#define COR2_DSRAE 0x01 /* DSR Automatic Enable */ - - -/* Channel Option Register 3 (R/W) */ - -#define COR3_XONCH 0x80 /* XON is a pair of characters (1 & 3) */ -#define COR3_XOFFCH 0x40 /* XOFF is a pair of characters (2 & 4) */ -#define COR3_FCT 0x20 /* Flow-Control Transparency Mode */ -#define COR3_SCDE 0x10 /* Special Character Detection Enable */ -#define COR3_RXTH 0x0f /* RX FIFO Threshold value (1-8) */ - - -/* Channel Control Status Register (R/O) */ - -#define CCSR_RXEN 0x80 /* Receiver Enabled */ -#define CCSR_RXFLOFF 0x40 /* Receive Flow Off (XOFF was sent) */ -#define CCSR_RXFLON 0x20 /* Receive Flow On (XON was sent) */ -#define CCSR_TXEN 0x08 /* Transmitter Enabled */ -#define CCSR_TXFLOFF 0x04 /* Transmit Flow Off (got XOFF) */ -#define CCSR_TXFLON 0x02 /* Transmit Flow On (got XON) */ - - -/* Modem Change Option Register 1 (R/W) */ - -#define MCOR1_DSRZD 0x80 /* Detect 0->1 transition of DSR */ -#define MCOR1_CDZD 0x40 /* Detect 0->1 transition of CD */ -#define MCOR1_CTSZD 0x20 /* Detect 0->1 transition of CTS */ -#define MCOR1_DTRTH 0x0f /* Auto DTR flow control Threshold (1-8) */ -#define MCOR1_NODTRFC 0x0 /* Automatic DTR flow control disabled */ - - -/* Modem Change Option Register 2 (R/W) */ - -#define MCOR2_DSROD 0x80 /* Detect 1->0 transition of DSR */ -#define MCOR2_CDOD 0x40 /* Detect 1->0 transition of CD */ -#define MCOR2_CTSOD 0x20 /* Detect 1->0 transition of CTS */ - -/* Modem Change Register (R/W) */ - -#define MCR_DSRCHG 0x80 /* DSR Changed */ -#define MCR_CDCHG 0x40 /* CD Changed */ -#define MCR_CTSCHG 0x20 /* CTS Changed */ - - -/* Modem Signal Value Register (R/W) */ - -#define MSVR_DSR 0x80 /* Current state of DSR input */ -#define MSVR_CD 0x40 /* Current state of CD input */ -#define MSVR_CTS 0x20 /* Current state of CTS input */ -#define MSVR_DTR 0x02 /* Current state of DTR output */ -#define MSVR_RTS 0x01 /* Current state of RTS output */ - - -/* Escape characters */ - -#define CD186x_C_ESC 0x00 /* Escape character */ -#define CD186x_C_SBRK 0x81 /* Start sending BREAK */ -#define CD186x_C_DELAY 0x82 /* Delay output */ -#define CD186x_C_EBRK 0x83 /* Stop sending BREAK */ - -#define SRSR_RREQint 0x10 /* This chip wants "rec" serviced */ -#define SRSR_TREQint 0x04 /* This chip wants "transmit" serviced */ -#define SRSR_MREQint 0x01 /* This chip wants "mdm change" serviced */ - - - -#define SRCR_PKGTYPE 0x80 -#define SRCR_REGACKEN 0x40 -#define SRCR_DAISYEN 0x20 -#define SRCR_GLOBPRI 0x10 -#define SRCR_UNFAIR 0x08 -#define SRCR_AUTOPRI 0x02 -#define SRCR_PRISEL 0x01 - - diff --git a/drivers/staging/tty/cd1865.h b/drivers/staging/tty/cd1865.h new file mode 100644 index 000000000000..9940966e7a1d --- /dev/null +++ b/drivers/staging/tty/cd1865.h @@ -0,0 +1,263 @@ +/* + * linux/drivers/char/cd1865.h -- Definitions relating to the CD1865 + * for the Specialix IO8+ multiport serial driver. + * + * Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl) + * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) + * + * Specialix pays for the development and support of this driver. + * Please DO contact io8-linux@specialix.co.uk if you require + * support. + * + * This driver was developped in the BitWizard linux device + * driver service. If you require a linux device driver for your + * product, please contact devices@BitWizard.nl for a quote. + * + */ + +/* + * Definitions for Driving CD180/CD1864/CD1865 based eightport serial cards. + */ + + +/* Values of choice for Interrupt ACKs */ +/* These values are "obligatory" if you use the register based + * interrupt acknowledgements. See page 99-101 of V2.0 of the CD1865 + * databook */ +#define SX_ACK_MINT 0x75 /* goes to PILR1 */ +#define SX_ACK_TINT 0x76 /* goes to PILR2 */ +#define SX_ACK_RINT 0x77 /* goes to PILR3 */ + +/* Chip ID (is used when chips ar daisy chained.) */ +#define SX_ID 0x10 + +/* Definitions for Cirrus Logic CL-CD186x 8-port async mux chip */ + +#define CD186x_NCH 8 /* Total number of channels */ +#define CD186x_TPC 16 /* Ticks per character */ +#define CD186x_NFIFO 8 /* TX FIFO size */ + + +/* Global registers */ + +#define CD186x_GIVR 0x40 /* Global Interrupt Vector Register */ +#define CD186x_GICR 0x41 /* Global Interrupting Channel Register */ +#define CD186x_PILR1 0x61 /* Priority Interrupt Level Register 1 */ +#define CD186x_PILR2 0x62 /* Priority Interrupt Level Register 2 */ +#define CD186x_PILR3 0x63 /* Priority Interrupt Level Register 3 */ +#define CD186x_CAR 0x64 /* Channel Access Register */ +#define CD186x_SRSR 0x65 /* Channel Access Register */ +#define CD186x_GFRCR 0x6b /* Global Firmware Revision Code Register */ +#define CD186x_PPRH 0x70 /* Prescaler Period Register High */ +#define CD186x_PPRL 0x71 /* Prescaler Period Register Low */ +#define CD186x_RDR 0x78 /* Receiver Data Register */ +#define CD186x_RCSR 0x7a /* Receiver Character Status Register */ +#define CD186x_TDR 0x7b /* Transmit Data Register */ +#define CD186x_EOIR 0x7f /* End of Interrupt Register */ +#define CD186x_MRAR 0x75 /* Modem Request Acknowledge register */ +#define CD186x_TRAR 0x76 /* Transmit Request Acknowledge register */ +#define CD186x_RRAR 0x77 /* Receive Request Acknowledge register */ +#define CD186x_SRCR 0x66 /* Service Request Configuration register */ + +/* Channel Registers */ + +#define CD186x_CCR 0x01 /* Channel Command Register */ +#define CD186x_IER 0x02 /* Interrupt Enable Register */ +#define CD186x_COR1 0x03 /* Channel Option Register 1 */ +#define CD186x_COR2 0x04 /* Channel Option Register 2 */ +#define CD186x_COR3 0x05 /* Channel Option Register 3 */ +#define CD186x_CCSR 0x06 /* Channel Control Status Register */ +#define CD186x_RDCR 0x07 /* Receive Data Count Register */ +#define CD186x_SCHR1 0x09 /* Special Character Register 1 */ +#define CD186x_SCHR2 0x0a /* Special Character Register 2 */ +#define CD186x_SCHR3 0x0b /* Special Character Register 3 */ +#define CD186x_SCHR4 0x0c /* Special Character Register 4 */ +#define CD186x_MCOR1 0x10 /* Modem Change Option 1 Register */ +#define CD186x_MCOR2 0x11 /* Modem Change Option 2 Register */ +#define CD186x_MCR 0x12 /* Modem Change Register */ +#define CD186x_RTPR 0x18 /* Receive Timeout Period Register */ +#define CD186x_MSVR 0x28 /* Modem Signal Value Register */ +#define CD186x_MSVRTS 0x29 /* Modem Signal Value Register */ +#define CD186x_MSVDTR 0x2a /* Modem Signal Value Register */ +#define CD186x_RBPRH 0x31 /* Receive Baud Rate Period Register High */ +#define CD186x_RBPRL 0x32 /* Receive Baud Rate Period Register Low */ +#define CD186x_TBPRH 0x39 /* Transmit Baud Rate Period Register High */ +#define CD186x_TBPRL 0x3a /* Transmit Baud Rate Period Register Low */ + + +/* Global Interrupt Vector Register (R/W) */ + +#define GIVR_ITMASK 0x07 /* Interrupt type mask */ +#define GIVR_IT_MODEM 0x01 /* Modem Signal Change Interrupt */ +#define GIVR_IT_TX 0x02 /* Transmit Data Interrupt */ +#define GIVR_IT_RCV 0x03 /* Receive Good Data Interrupt */ +#define GIVR_IT_REXC 0x07 /* Receive Exception Interrupt */ + + +/* Global Interrupt Channel Register (R/W) */ + +#define GICR_CHAN 0x1c /* Channel Number Mask */ +#define GICR_CHAN_OFF 2 /* Channel Number shift */ + + +/* Channel Address Register (R/W) */ + +#define CAR_CHAN 0x07 /* Channel Number Mask */ +#define CAR_A7 0x08 /* A7 Address Extension (unused) */ + + +/* Receive Character Status Register (R/O) */ + +#define RCSR_TOUT 0x80 /* Rx Timeout */ +#define RCSR_SCDET 0x70 /* Special Character Detected Mask */ +#define RCSR_NO_SC 0x00 /* No Special Characters Detected */ +#define RCSR_SC_1 0x10 /* Special Char 1 (or 1 & 3) Detected */ +#define RCSR_SC_2 0x20 /* Special Char 2 (or 2 & 4) Detected */ +#define RCSR_SC_3 0x30 /* Special Char 3 Detected */ +#define RCSR_SC_4 0x40 /* Special Char 4 Detected */ +#define RCSR_BREAK 0x08 /* Break has been detected */ +#define RCSR_PE 0x04 /* Parity Error */ +#define RCSR_FE 0x02 /* Frame Error */ +#define RCSR_OE 0x01 /* Overrun Error */ + + +/* Channel Command Register (R/W) (commands in groups can be OR-ed) */ + +#define CCR_HARDRESET 0x81 /* Reset the chip */ + +#define CCR_SOFTRESET 0x80 /* Soft Channel Reset */ + +#define CCR_CORCHG1 0x42 /* Channel Option Register 1 Changed */ +#define CCR_CORCHG2 0x44 /* Channel Option Register 2 Changed */ +#define CCR_CORCHG3 0x48 /* Channel Option Register 3 Changed */ + +#define CCR_SSCH1 0x21 /* Send Special Character 1 */ + +#define CCR_SSCH2 0x22 /* Send Special Character 2 */ + +#define CCR_SSCH3 0x23 /* Send Special Character 3 */ + +#define CCR_SSCH4 0x24 /* Send Special Character 4 */ + +#define CCR_TXEN 0x18 /* Enable Transmitter */ +#define CCR_RXEN 0x12 /* Enable Receiver */ + +#define CCR_TXDIS 0x14 /* Disable Transmitter */ +#define CCR_RXDIS 0x11 /* Disable Receiver */ + + +/* Interrupt Enable Register (R/W) */ + +#define IER_DSR 0x80 /* Enable interrupt on DSR change */ +#define IER_CD 0x40 /* Enable interrupt on CD change */ +#define IER_CTS 0x20 /* Enable interrupt on CTS change */ +#define IER_RXD 0x10 /* Enable interrupt on Receive Data */ +#define IER_RXSC 0x08 /* Enable interrupt on Receive Spec. Char */ +#define IER_TXRDY 0x04 /* Enable interrupt on TX FIFO empty */ +#define IER_TXEMPTY 0x02 /* Enable interrupt on TX completely empty */ +#define IER_RET 0x01 /* Enable interrupt on RX Exc. Timeout */ + + +/* Channel Option Register 1 (R/W) */ + +#define COR1_ODDP 0x80 /* Odd Parity */ +#define COR1_PARMODE 0x60 /* Parity Mode mask */ +#define COR1_NOPAR 0x00 /* No Parity */ +#define COR1_FORCEPAR 0x20 /* Force Parity */ +#define COR1_NORMPAR 0x40 /* Normal Parity */ +#define COR1_IGNORE 0x10 /* Ignore Parity on RX */ +#define COR1_STOPBITS 0x0c /* Number of Stop Bits */ +#define COR1_1SB 0x00 /* 1 Stop Bit */ +#define COR1_15SB 0x04 /* 1.5 Stop Bits */ +#define COR1_2SB 0x08 /* 2 Stop Bits */ +#define COR1_CHARLEN 0x03 /* Character Length */ +#define COR1_5BITS 0x00 /* 5 bits */ +#define COR1_6BITS 0x01 /* 6 bits */ +#define COR1_7BITS 0x02 /* 7 bits */ +#define COR1_8BITS 0x03 /* 8 bits */ + + +/* Channel Option Register 2 (R/W) */ + +#define COR2_IXM 0x80 /* Implied XON mode */ +#define COR2_TXIBE 0x40 /* Enable In-Band (XON/XOFF) Flow Control */ +#define COR2_ETC 0x20 /* Embedded Tx Commands Enable */ +#define COR2_LLM 0x10 /* Local Loopback Mode */ +#define COR2_RLM 0x08 /* Remote Loopback Mode */ +#define COR2_RTSAO 0x04 /* RTS Automatic Output Enable */ +#define COR2_CTSAE 0x02 /* CTS Automatic Enable */ +#define COR2_DSRAE 0x01 /* DSR Automatic Enable */ + + +/* Channel Option Register 3 (R/W) */ + +#define COR3_XONCH 0x80 /* XON is a pair of characters (1 & 3) */ +#define COR3_XOFFCH 0x40 /* XOFF is a pair of characters (2 & 4) */ +#define COR3_FCT 0x20 /* Flow-Control Transparency Mode */ +#define COR3_SCDE 0x10 /* Special Character Detection Enable */ +#define COR3_RXTH 0x0f /* RX FIFO Threshold value (1-8) */ + + +/* Channel Control Status Register (R/O) */ + +#define CCSR_RXEN 0x80 /* Receiver Enabled */ +#define CCSR_RXFLOFF 0x40 /* Receive Flow Off (XOFF was sent) */ +#define CCSR_RXFLON 0x20 /* Receive Flow On (XON was sent) */ +#define CCSR_TXEN 0x08 /* Transmitter Enabled */ +#define CCSR_TXFLOFF 0x04 /* Transmit Flow Off (got XOFF) */ +#define CCSR_TXFLON 0x02 /* Transmit Flow On (got XON) */ + + +/* Modem Change Option Register 1 (R/W) */ + +#define MCOR1_DSRZD 0x80 /* Detect 0->1 transition of DSR */ +#define MCOR1_CDZD 0x40 /* Detect 0->1 transition of CD */ +#define MCOR1_CTSZD 0x20 /* Detect 0->1 transition of CTS */ +#define MCOR1_DTRTH 0x0f /* Auto DTR flow control Threshold (1-8) */ +#define MCOR1_NODTRFC 0x0 /* Automatic DTR flow control disabled */ + + +/* Modem Change Option Register 2 (R/W) */ + +#define MCOR2_DSROD 0x80 /* Detect 1->0 transition of DSR */ +#define MCOR2_CDOD 0x40 /* Detect 1->0 transition of CD */ +#define MCOR2_CTSOD 0x20 /* Detect 1->0 transition of CTS */ + +/* Modem Change Register (R/W) */ + +#define MCR_DSRCHG 0x80 /* DSR Changed */ +#define MCR_CDCHG 0x40 /* CD Changed */ +#define MCR_CTSCHG 0x20 /* CTS Changed */ + + +/* Modem Signal Value Register (R/W) */ + +#define MSVR_DSR 0x80 /* Current state of DSR input */ +#define MSVR_CD 0x40 /* Current state of CD input */ +#define MSVR_CTS 0x20 /* Current state of CTS input */ +#define MSVR_DTR 0x02 /* Current state of DTR output */ +#define MSVR_RTS 0x01 /* Current state of RTS output */ + + +/* Escape characters */ + +#define CD186x_C_ESC 0x00 /* Escape character */ +#define CD186x_C_SBRK 0x81 /* Start sending BREAK */ +#define CD186x_C_DELAY 0x82 /* Delay output */ +#define CD186x_C_EBRK 0x83 /* Stop sending BREAK */ + +#define SRSR_RREQint 0x10 /* This chip wants "rec" serviced */ +#define SRSR_TREQint 0x04 /* This chip wants "transmit" serviced */ +#define SRSR_MREQint 0x01 /* This chip wants "mdm change" serviced */ + + + +#define SRCR_PKGTYPE 0x80 +#define SRCR_REGACKEN 0x40 +#define SRCR_DAISYEN 0x20 +#define SRCR_GLOBPRI 0x10 +#define SRCR_UNFAIR 0x08 +#define SRCR_AUTOPRI 0x02 +#define SRCR_PRISEL 0x01 + + -- cgit v1.2.3 From 00bff392c81e4fb1901e5160fdd5afdb2546a6ab Mon Sep 17 00:00:00 2001 From: Xiaotian Feng Date: Thu, 3 Mar 2011 18:08:24 +0800 Subject: tty_audit: fix tty_audit_add_data live lock on audit disabled The current tty_audit_add_data code: do { size_t run; run = N_TTY_BUF_SIZE - buf->valid; if (run > size) run = size; memcpy(buf->data + buf->valid, data, run); buf->valid += run; data += run; size -= run; if (buf->valid == N_TTY_BUF_SIZE) tty_audit_buf_push_current(buf); } while (size != 0); If the current buffer is full, kernel will then call tty_audit_buf_push_current to empty the buffer. But if we disabled audit at the same time, tty_audit_buf_push() returns immediately if audit_enabled is zero. Without emptying the buffer. With obvious effect on tty_audit_add_data() that ends up spinning in that loop, copying 0 bytes at each iteration and attempting to push each time without any effect. Holding the lock all along. Suggested-by: Alexander Viro Signed-off-by: Xiaotian Feng Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_audit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c index f64582b0f623..7c5866920622 100644 --- a/drivers/tty/tty_audit.c +++ b/drivers/tty/tty_audit.c @@ -95,8 +95,10 @@ static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid, { if (buf->valid == 0) return; - if (audit_enabled == 0) + if (audit_enabled == 0) { + buf->valid = 0; return; + } tty_audit_log("tty", tsk, loginuid, sessionid, buf->major, buf->minor, buf->data, buf->valid); buf->valid = 0; -- cgit v1.2.3 From 550462378515a82279e07f12e2c105f617f112f8 Mon Sep 17 00:00:00 2001 From: Mayank Rana Date: Mon, 7 Mar 2011 10:28:42 +0530 Subject: serial: msm_serial_hs: Add MSM high speed UART driver This driver supports UART-DM HW on MSM platforms. It uses the on chip DMA to drive data transfers and has optional support for UART power management independent of Linux suspend/resume and wakeup from Rx. The driver was originally developed by Google. It is functionally equivalent to the version available at: http://android.git.kernel.org/?p=kernel/experimental.git the differences being: 1) Remove wakelocks and change unsupported DMA API. 2) Replace clock selection register codes by macros. 3) Fix checkpatch errors and add inline documentation. 4) Add runtime PM hooks for active power state transitions. 5) Handle error path and cleanup resources if required. CC: Nick Pelly Signed-off-by: Sankalp Bose Signed-off-by: Mayank Rana Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 12 + drivers/tty/serial/Makefile | 1 + drivers/tty/serial/msm_serial_hs.c | 1880 +++++++++++++++++++++++++++ include/linux/platform_data/msm_serial_hs.h | 49 + 4 files changed, 1942 insertions(+) create mode 100644 drivers/tty/serial/msm_serial_hs.c create mode 100644 include/linux/platform_data/msm_serial_hs.h (limited to 'drivers') diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 90d939a4ee5d..d9ccbf825095 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1319,6 +1319,18 @@ config SERIAL_MSM_CONSOLE depends on SERIAL_MSM=y select SERIAL_CORE_CONSOLE +config SERIAL_MSM_HS + tristate "MSM UART High Speed: Serial Driver" + depends on ARCH_MSM + select SERIAL_CORE + help + If you have a machine based on MSM family of SoCs, you + can enable its onboard high speed serial port by enabling + this option. + + Choose M here to compile it as a module. The module will be + called msm_serial_hs. + config SERIAL_VT8500 bool "VIA VT8500 on-chip serial port support" depends on ARM && ARCH_VT8500 diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 0c6aefb55acf..d94dc005c8a6 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -76,6 +76,7 @@ obj-$(CONFIG_SERIAL_SGI_IOC3) += ioc3_serial.o obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o obj-$(CONFIG_SERIAL_MSM) += msm_serial.o +obj-$(CONFIG_SERIAL_MSM_HS) += msm_serial_hs.o obj-$(CONFIG_SERIAL_NETX) += netx-serial.o obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c new file mode 100644 index 000000000000..2e7fc9cee9cc --- /dev/null +++ b/drivers/tty/serial/msm_serial_hs.c @@ -0,0 +1,1880 @@ +/* + * MSM 7k/8k High speed uart driver + * + * Copyright (c) 2007-2011, Code Aurora Forum. All rights reserved. + * Copyright (c) 2008 Google Inc. + * Modified: Nick Pelly + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * Has optional support for uart power management independent of linux + * suspend/resume: + * + * RX wakeup. + * UART wakeup can be triggered by RX activity (using a wakeup GPIO on the + * UART RX pin). This should only be used if there is not a wakeup + * GPIO on the UART CTS, and the first RX byte is known (for example, with the + * Bluetooth Texas Instruments HCILL protocol), since the first RX byte will + * always be lost. RTS will be asserted even while the UART is off in this mode + * of operation. See msm_serial_hs_platform_data.rx_wakeup_irq. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +/* HSUART Registers */ +#define UARTDM_MR1_ADDR 0x0 +#define UARTDM_MR2_ADDR 0x4 + +/* Data Mover result codes */ +#define RSLT_FIFO_CNTR_BMSK (0xE << 28) +#define RSLT_VLD BIT(1) + +/* write only register */ +#define UARTDM_CSR_ADDR 0x8 +#define UARTDM_CSR_115200 0xFF +#define UARTDM_CSR_57600 0xEE +#define UARTDM_CSR_38400 0xDD +#define UARTDM_CSR_28800 0xCC +#define UARTDM_CSR_19200 0xBB +#define UARTDM_CSR_14400 0xAA +#define UARTDM_CSR_9600 0x99 +#define UARTDM_CSR_7200 0x88 +#define UARTDM_CSR_4800 0x77 +#define UARTDM_CSR_3600 0x66 +#define UARTDM_CSR_2400 0x55 +#define UARTDM_CSR_1200 0x44 +#define UARTDM_CSR_600 0x33 +#define UARTDM_CSR_300 0x22 +#define UARTDM_CSR_150 0x11 +#define UARTDM_CSR_75 0x00 + +/* write only register */ +#define UARTDM_TF_ADDR 0x70 +#define UARTDM_TF2_ADDR 0x74 +#define UARTDM_TF3_ADDR 0x78 +#define UARTDM_TF4_ADDR 0x7C + +/* write only register */ +#define UARTDM_CR_ADDR 0x10 +#define UARTDM_IMR_ADDR 0x14 + +#define UARTDM_IPR_ADDR 0x18 +#define UARTDM_TFWR_ADDR 0x1c +#define UARTDM_RFWR_ADDR 0x20 +#define UARTDM_HCR_ADDR 0x24 +#define UARTDM_DMRX_ADDR 0x34 +#define UARTDM_IRDA_ADDR 0x38 +#define UARTDM_DMEN_ADDR 0x3c + +/* UART_DM_NO_CHARS_FOR_TX */ +#define UARTDM_NCF_TX_ADDR 0x40 + +#define UARTDM_BADR_ADDR 0x44 + +#define UARTDM_SIM_CFG_ADDR 0x80 +/* Read Only register */ +#define UARTDM_SR_ADDR 0x8 + +/* Read Only register */ +#define UARTDM_RF_ADDR 0x70 +#define UARTDM_RF2_ADDR 0x74 +#define UARTDM_RF3_ADDR 0x78 +#define UARTDM_RF4_ADDR 0x7C + +/* Read Only register */ +#define UARTDM_MISR_ADDR 0x10 + +/* Read Only register */ +#define UARTDM_ISR_ADDR 0x14 +#define UARTDM_RX_TOTAL_SNAP_ADDR 0x38 + +#define UARTDM_RXFS_ADDR 0x50 + +/* Register field Mask Mapping */ +#define UARTDM_SR_PAR_FRAME_BMSK BIT(5) +#define UARTDM_SR_OVERRUN_BMSK BIT(4) +#define UARTDM_SR_TXEMT_BMSK BIT(3) +#define UARTDM_SR_TXRDY_BMSK BIT(2) +#define UARTDM_SR_RXRDY_BMSK BIT(0) + +#define UARTDM_CR_TX_DISABLE_BMSK BIT(3) +#define UARTDM_CR_RX_DISABLE_BMSK BIT(1) +#define UARTDM_CR_TX_EN_BMSK BIT(2) +#define UARTDM_CR_RX_EN_BMSK BIT(0) + +/* UARTDM_CR channel_comman bit value (register field is bits 8:4) */ +#define RESET_RX 0x10 +#define RESET_TX 0x20 +#define RESET_ERROR_STATUS 0x30 +#define RESET_BREAK_INT 0x40 +#define START_BREAK 0x50 +#define STOP_BREAK 0x60 +#define RESET_CTS 0x70 +#define RESET_STALE_INT 0x80 +#define RFR_LOW 0xD0 +#define RFR_HIGH 0xE0 +#define CR_PROTECTION_EN 0x100 +#define STALE_EVENT_ENABLE 0x500 +#define STALE_EVENT_DISABLE 0x600 +#define FORCE_STALE_EVENT 0x400 +#define CLEAR_TX_READY 0x300 +#define RESET_TX_ERROR 0x800 +#define RESET_TX_DONE 0x810 + +#define UARTDM_MR1_AUTO_RFR_LEVEL1_BMSK 0xffffff00 +#define UARTDM_MR1_AUTO_RFR_LEVEL0_BMSK 0x3f +#define UARTDM_MR1_CTS_CTL_BMSK 0x40 +#define UARTDM_MR1_RX_RDY_CTL_BMSK 0x80 + +#define UARTDM_MR2_ERROR_MODE_BMSK 0x40 +#define UARTDM_MR2_BITS_PER_CHAR_BMSK 0x30 + +/* bits per character configuration */ +#define FIVE_BPC (0 << 4) +#define SIX_BPC (1 << 4) +#define SEVEN_BPC (2 << 4) +#define EIGHT_BPC (3 << 4) + +#define UARTDM_MR2_STOP_BIT_LEN_BMSK 0xc +#define STOP_BIT_ONE (1 << 2) +#define STOP_BIT_TWO (3 << 2) + +#define UARTDM_MR2_PARITY_MODE_BMSK 0x3 + +/* Parity configuration */ +#define NO_PARITY 0x0 +#define EVEN_PARITY 0x1 +#define ODD_PARITY 0x2 +#define SPACE_PARITY 0x3 + +#define UARTDM_IPR_STALE_TIMEOUT_MSB_BMSK 0xffffff80 +#define UARTDM_IPR_STALE_LSB_BMSK 0x1f + +/* These can be used for both ISR and IMR register */ +#define UARTDM_ISR_TX_READY_BMSK BIT(7) +#define UARTDM_ISR_CURRENT_CTS_BMSK BIT(6) +#define UARTDM_ISR_DELTA_CTS_BMSK BIT(5) +#define UARTDM_ISR_RXLEV_BMSK BIT(4) +#define UARTDM_ISR_RXSTALE_BMSK BIT(3) +#define UARTDM_ISR_RXBREAK_BMSK BIT(2) +#define UARTDM_ISR_RXHUNT_BMSK BIT(1) +#define UARTDM_ISR_TXLEV_BMSK BIT(0) + +/* Field definitions for UART_DM_DMEN*/ +#define UARTDM_TX_DM_EN_BMSK 0x1 +#define UARTDM_RX_DM_EN_BMSK 0x2 + +#define UART_FIFOSIZE 64 +#define UARTCLK 7372800 + +/* Rx DMA request states */ +enum flush_reason { + FLUSH_NONE, + FLUSH_DATA_READY, + FLUSH_DATA_INVALID, /* values after this indicate invalid data */ + FLUSH_IGNORE = FLUSH_DATA_INVALID, + FLUSH_STOP, + FLUSH_SHUTDOWN, +}; + +/* UART clock states */ +enum msm_hs_clk_states_e { + MSM_HS_CLK_PORT_OFF, /* port not in use */ + MSM_HS_CLK_OFF, /* clock disabled */ + MSM_HS_CLK_REQUEST_OFF, /* disable after TX and RX flushed */ + MSM_HS_CLK_ON, /* clock enabled */ +}; + +/* Track the forced RXSTALE flush during clock off sequence. + * These states are only valid during MSM_HS_CLK_REQUEST_OFF */ +enum msm_hs_clk_req_off_state_e { + CLK_REQ_OFF_START, + CLK_REQ_OFF_RXSTALE_ISSUED, + CLK_REQ_OFF_FLUSH_ISSUED, + CLK_REQ_OFF_RXSTALE_FLUSHED, +}; + +/** + * struct msm_hs_tx + * @tx_ready_int_en: ok to dma more tx? + * @dma_in_flight: tx dma in progress + * @xfer: top level DMA command pointer structure + * @command_ptr: third level command struct pointer + * @command_ptr_ptr: second level command list struct pointer + * @mapped_cmd_ptr: DMA view of third level command struct + * @mapped_cmd_ptr_ptr: DMA view of second level command list struct + * @tx_count: number of bytes to transfer in DMA transfer + * @dma_base: DMA view of UART xmit buffer + * + * This structure describes a single Tx DMA transaction. MSM DMA + * commands have two levels of indirection. The top level command + * ptr points to a list of command ptr which in turn points to a + * single DMA 'command'. In our case each Tx transaction consists + * of a single second level pointer pointing to a 'box type' command. + */ +struct msm_hs_tx { + unsigned int tx_ready_int_en; + unsigned int dma_in_flight; + struct msm_dmov_cmd xfer; + dmov_box *command_ptr; + u32 *command_ptr_ptr; + dma_addr_t mapped_cmd_ptr; + dma_addr_t mapped_cmd_ptr_ptr; + int tx_count; + dma_addr_t dma_base; +}; + +/** + * struct msm_hs_rx + * @flush: Rx DMA request state + * @xfer: top level DMA command pointer structure + * @cmdptr_dmaaddr: DMA view of second level command structure + * @command_ptr: third level DMA command pointer structure + * @command_ptr_ptr: second level DMA command list pointer + * @mapped_cmd_ptr: DMA view of the third level command structure + * @wait: wait for DMA completion before shutdown + * @buffer: destination buffer for RX DMA + * @rbuffer: DMA view of buffer + * @pool: dma pool out of which coherent rx buffer is allocated + * @tty_work: private work-queue for tty flip buffer push task + * + * This structure describes a single Rx DMA transaction. Rx DMA + * transactions use box mode DMA commands. + */ +struct msm_hs_rx { + enum flush_reason flush; + struct msm_dmov_cmd xfer; + dma_addr_t cmdptr_dmaaddr; + dmov_box *command_ptr; + u32 *command_ptr_ptr; + dma_addr_t mapped_cmd_ptr; + wait_queue_head_t wait; + dma_addr_t rbuffer; + unsigned char *buffer; + struct dma_pool *pool; + struct work_struct tty_work; +}; + +/** + * struct msm_hs_rx_wakeup + * @irq: IRQ line to be configured as interrupt source on Rx activity + * @ignore: boolean value. 1 = ignore the wakeup interrupt + * @rx_to_inject: extra character to be inserted to Rx tty on wakeup + * @inject_rx: 1 = insert rx_to_inject. 0 = do not insert extra character + * + * This is an optional structure required for UART Rx GPIO IRQ based + * wakeup from low power state. UART wakeup can be triggered by RX activity + * (using a wakeup GPIO on the UART RX pin). This should only be used if + * there is not a wakeup GPIO on the UART CTS, and the first RX byte is + * known (eg., with the Bluetooth Texas Instruments HCILL protocol), + * since the first RX byte will always be lost. RTS will be asserted even + * while the UART is clocked off in this mode of operation. + */ +struct msm_hs_rx_wakeup { + int irq; /* < 0 indicates low power wakeup disabled */ + unsigned char ignore; + unsigned char inject_rx; + char rx_to_inject; +}; + +/** + * struct msm_hs_port + * @uport: embedded uart port structure + * @imr_reg: shadow value of UARTDM_IMR + * @clk: uart input clock handle + * @tx: Tx transaction related data structure + * @rx: Rx transaction related data structure + * @dma_tx_channel: Tx DMA command channel + * @dma_rx_channel Rx DMA command channel + * @dma_tx_crci: Tx channel rate control interface number + * @dma_rx_crci: Rx channel rate control interface number + * @clk_off_timer: Timer to poll DMA event completion before clock off + * @clk_off_delay: clk_off_timer poll interval + * @clk_state: overall clock state + * @clk_req_off_state: post flush clock states + * @rx_wakeup: optional rx_wakeup feature related data + * @exit_lpm_cb: optional callback to exit low power mode + * + * Low level serial port structure. + */ +struct msm_hs_port { + struct uart_port uport; + unsigned long imr_reg; + struct clk *clk; + struct msm_hs_tx tx; + struct msm_hs_rx rx; + + int dma_tx_channel; + int dma_rx_channel; + int dma_tx_crci; + int dma_rx_crci; + + struct hrtimer clk_off_timer; + ktime_t clk_off_delay; + enum msm_hs_clk_states_e clk_state; + enum msm_hs_clk_req_off_state_e clk_req_off_state; + + struct msm_hs_rx_wakeup rx_wakeup; + void (*exit_lpm_cb)(struct uart_port *); +}; + +#define MSM_UARTDM_BURST_SIZE 16 /* DM burst size (in bytes) */ +#define UARTDM_TX_BUF_SIZE UART_XMIT_SIZE +#define UARTDM_RX_BUF_SIZE 512 + +#define UARTDM_NR 2 + +static struct msm_hs_port q_uart_port[UARTDM_NR]; +static struct platform_driver msm_serial_hs_platform_driver; +static struct uart_driver msm_hs_driver; +static struct uart_ops msm_hs_ops; +static struct workqueue_struct *msm_hs_workqueue; + +#define UARTDM_TO_MSM(uart_port) \ + container_of((uart_port), struct msm_hs_port, uport) + +static unsigned int use_low_power_rx_wakeup(struct msm_hs_port + *msm_uport) +{ + return (msm_uport->rx_wakeup.irq >= 0); +} + +static unsigned int msm_hs_read(struct uart_port *uport, + unsigned int offset) +{ + return ioread32(uport->membase + offset); +} + +static void msm_hs_write(struct uart_port *uport, unsigned int offset, + unsigned int value) +{ + iowrite32(value, uport->membase + offset); +} + +static void msm_hs_release_port(struct uart_port *port) +{ + iounmap(port->membase); +} + +static int msm_hs_request_port(struct uart_port *port) +{ + port->membase = ioremap(port->mapbase, PAGE_SIZE); + if (unlikely(!port->membase)) + return -ENOMEM; + + /* configure the CR Protection to Enable */ + msm_hs_write(port, UARTDM_CR_ADDR, CR_PROTECTION_EN); + return 0; +} + +static int __devexit msm_hs_remove(struct platform_device *pdev) +{ + + struct msm_hs_port *msm_uport; + struct device *dev; + + if (pdev->id < 0 || pdev->id >= UARTDM_NR) { + printk(KERN_ERR "Invalid plaform device ID = %d\n", pdev->id); + return -EINVAL; + } + + msm_uport = &q_uart_port[pdev->id]; + dev = msm_uport->uport.dev; + + dma_unmap_single(dev, msm_uport->rx.mapped_cmd_ptr, sizeof(dmov_box), + DMA_TO_DEVICE); + dma_pool_free(msm_uport->rx.pool, msm_uport->rx.buffer, + msm_uport->rx.rbuffer); + dma_pool_destroy(msm_uport->rx.pool); + + dma_unmap_single(dev, msm_uport->rx.cmdptr_dmaaddr, sizeof(u32 *), + DMA_TO_DEVICE); + dma_unmap_single(dev, msm_uport->tx.mapped_cmd_ptr_ptr, sizeof(u32 *), + DMA_TO_DEVICE); + dma_unmap_single(dev, msm_uport->tx.mapped_cmd_ptr, sizeof(dmov_box), + DMA_TO_DEVICE); + + uart_remove_one_port(&msm_hs_driver, &msm_uport->uport); + clk_put(msm_uport->clk); + + /* Free the tx resources */ + kfree(msm_uport->tx.command_ptr); + kfree(msm_uport->tx.command_ptr_ptr); + + /* Free the rx resources */ + kfree(msm_uport->rx.command_ptr); + kfree(msm_uport->rx.command_ptr_ptr); + + iounmap(msm_uport->uport.membase); + + return 0; +} + +static int msm_hs_init_clk_locked(struct uart_port *uport) +{ + int ret; + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + + ret = clk_enable(msm_uport->clk); + if (ret) { + printk(KERN_ERR "Error could not turn on UART clk\n"); + return ret; + } + + /* Set up the MREG/NREG/DREG/MNDREG */ + ret = clk_set_rate(msm_uport->clk, uport->uartclk); + if (ret) { + printk(KERN_WARNING "Error setting clock rate on UART\n"); + clk_disable(msm_uport->clk); + return ret; + } + + msm_uport->clk_state = MSM_HS_CLK_ON; + return 0; +} + +/* Enable and Disable clocks (Used for power management) */ +static void msm_hs_pm(struct uart_port *uport, unsigned int state, + unsigned int oldstate) +{ + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + + if (use_low_power_rx_wakeup(msm_uport) || + msm_uport->exit_lpm_cb) + return; /* ignore linux PM states, + use msm_hs_request_clock API */ + + switch (state) { + case 0: + clk_enable(msm_uport->clk); + break; + case 3: + clk_disable(msm_uport->clk); + break; + default: + dev_err(uport->dev, "msm_serial: Unknown PM state %d\n", + state); + } +} + +/* + * programs the UARTDM_CSR register with correct bit rates + * + * Interrupts should be disabled before we are called, as + * we modify Set Baud rate + * Set receive stale interrupt level, dependant on Bit Rate + * Goal is to have around 8 ms before indicate stale. + * roundup (((Bit Rate * .008) / 10) + 1 + */ +static void msm_hs_set_bps_locked(struct uart_port *uport, + unsigned int bps) +{ + unsigned long rxstale; + unsigned long data; + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + + switch (bps) { + case 300: + msm_hs_write(uport, UARTDM_CSR_ADDR, UARTDM_CSR_75); + rxstale = 1; + break; + case 600: + msm_hs_write(uport, UARTDM_CSR_ADDR, UARTDM_CSR_150); + rxstale = 1; + break; + case 1200: + msm_hs_write(uport, UARTDM_CSR_ADDR, UARTDM_CSR_300); + rxstale = 1; + break; + case 2400: + msm_hs_write(uport, UARTDM_CSR_ADDR, UARTDM_CSR_600); + rxstale = 1; + break; + case 4800: + msm_hs_write(uport, UARTDM_CSR_ADDR, UARTDM_CSR_1200); + rxstale = 1; + break; + case 9600: + msm_hs_write(uport, UARTDM_CSR_ADDR, UARTDM_CSR_2400); + rxstale = 2; + break; + case 14400: + msm_hs_write(uport, UARTDM_CSR_ADDR, UARTDM_CSR_3600); + rxstale = 3; + break; + case 19200: + msm_hs_write(uport, UARTDM_CSR_ADDR, UARTDM_CSR_4800); + rxstale = 4; + break; + case 28800: + msm_hs_write(uport, UARTDM_CSR_ADDR, UARTDM_CSR_7200); + rxstale = 6; + break; + case 38400: + msm_hs_write(uport, UARTDM_CSR_ADDR, UARTDM_CSR_9600); + rxstale = 8; + break; + case 57600: + msm_hs_write(uport, UARTDM_CSR_ADDR, UARTDM_CSR_14400); + rxstale = 16; + break; + case 76800: + msm_hs_write(uport, UARTDM_CSR_ADDR, UARTDM_CSR_19200); + rxstale = 16; + break; + case 115200: + msm_hs_write(uport, UARTDM_CSR_ADDR, UARTDM_CSR_28800); + rxstale = 31; + break; + case 230400: + msm_hs_write(uport, UARTDM_CSR_ADDR, UARTDM_CSR_57600); + rxstale = 31; + break; + case 460800: + msm_hs_write(uport, UARTDM_CSR_ADDR, UARTDM_CSR_115200); + rxstale = 31; + break; + case 4000000: + case 3686400: + case 3200000: + case 3500000: + case 3000000: + case 2500000: + case 1500000: + case 1152000: + case 1000000: + case 921600: + msm_hs_write(uport, UARTDM_CSR_ADDR, UARTDM_CSR_115200); + rxstale = 31; + break; + default: + msm_hs_write(uport, UARTDM_CSR_ADDR, UARTDM_CSR_2400); + /* default to 9600 */ + bps = 9600; + rxstale = 2; + break; + } + if (bps > 460800) + uport->uartclk = bps * 16; + else + uport->uartclk = UARTCLK; + + if (clk_set_rate(msm_uport->clk, uport->uartclk)) { + printk(KERN_WARNING "Error setting clock rate on UART\n"); + return; + } + + data = rxstale & UARTDM_IPR_STALE_LSB_BMSK; + data |= UARTDM_IPR_STALE_TIMEOUT_MSB_BMSK & (rxstale << 2); + + msm_hs_write(uport, UARTDM_IPR_ADDR, data); +} + +/* + * termios : new ktermios + * oldtermios: old ktermios previous setting + * + * Configure the serial port + */ +static void msm_hs_set_termios(struct uart_port *uport, + struct ktermios *termios, + struct ktermios *oldtermios) +{ + unsigned int bps; + unsigned long data; + unsigned long flags; + unsigned int c_cflag = termios->c_cflag; + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + + spin_lock_irqsave(&uport->lock, flags); + clk_enable(msm_uport->clk); + + /* 300 is the minimum baud support by the driver */ + bps = uart_get_baud_rate(uport, termios, oldtermios, 200, 4000000); + + /* Temporary remapping 200 BAUD to 3.2 mbps */ + if (bps == 200) + bps = 3200000; + + msm_hs_set_bps_locked(uport, bps); + + data = msm_hs_read(uport, UARTDM_MR2_ADDR); + data &= ~UARTDM_MR2_PARITY_MODE_BMSK; + /* set parity */ + if (PARENB == (c_cflag & PARENB)) { + if (PARODD == (c_cflag & PARODD)) + data |= ODD_PARITY; + else if (CMSPAR == (c_cflag & CMSPAR)) + data |= SPACE_PARITY; + else + data |= EVEN_PARITY; + } + + /* Set bits per char */ + data &= ~UARTDM_MR2_BITS_PER_CHAR_BMSK; + + switch (c_cflag & CSIZE) { + case CS5: + data |= FIVE_BPC; + break; + case CS6: + data |= SIX_BPC; + break; + case CS7: + data |= SEVEN_BPC; + break; + default: + data |= EIGHT_BPC; + break; + } + /* stop bits */ + if (c_cflag & CSTOPB) { + data |= STOP_BIT_TWO; + } else { + /* otherwise 1 stop bit */ + data |= STOP_BIT_ONE; + } + data |= UARTDM_MR2_ERROR_MODE_BMSK; + /* write parity/bits per char/stop bit configuration */ + msm_hs_write(uport, UARTDM_MR2_ADDR, data); + + /* Configure HW flow control */ + data = msm_hs_read(uport, UARTDM_MR1_ADDR); + + data &= ~(UARTDM_MR1_CTS_CTL_BMSK | UARTDM_MR1_RX_RDY_CTL_BMSK); + + if (c_cflag & CRTSCTS) { + data |= UARTDM_MR1_CTS_CTL_BMSK; + data |= UARTDM_MR1_RX_RDY_CTL_BMSK; + } + + msm_hs_write(uport, UARTDM_MR1_ADDR, data); + + uport->ignore_status_mask = termios->c_iflag & INPCK; + uport->ignore_status_mask |= termios->c_iflag & IGNPAR; + uport->read_status_mask = (termios->c_cflag & CREAD); + + msm_hs_write(uport, UARTDM_IMR_ADDR, 0); + + /* Set Transmit software time out */ + uart_update_timeout(uport, c_cflag, bps); + + msm_hs_write(uport, UARTDM_CR_ADDR, RESET_RX); + msm_hs_write(uport, UARTDM_CR_ADDR, RESET_TX); + + if (msm_uport->rx.flush == FLUSH_NONE) { + msm_uport->rx.flush = FLUSH_IGNORE; + msm_dmov_stop_cmd(msm_uport->dma_rx_channel, NULL, 1); + } + + msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg); + + clk_disable(msm_uport->clk); + spin_unlock_irqrestore(&uport->lock, flags); +} + +/* + * Standard API, Transmitter + * Any character in the transmit shift register is sent + */ +static unsigned int msm_hs_tx_empty(struct uart_port *uport) +{ + unsigned int data; + unsigned int ret = 0; + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + + clk_enable(msm_uport->clk); + + data = msm_hs_read(uport, UARTDM_SR_ADDR); + if (data & UARTDM_SR_TXEMT_BMSK) + ret = TIOCSER_TEMT; + + clk_disable(msm_uport->clk); + + return ret; +} + +/* + * Standard API, Stop transmitter. + * Any character in the transmit shift register is sent as + * well as the current data mover transfer . + */ +static void msm_hs_stop_tx_locked(struct uart_port *uport) +{ + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + + msm_uport->tx.tx_ready_int_en = 0; +} + +/* + * Standard API, Stop receiver as soon as possible. + * + * Function immediately terminates the operation of the + * channel receiver and any incoming characters are lost. None + * of the receiver status bits are affected by this command and + * characters that are already in the receive FIFO there. + */ +static void msm_hs_stop_rx_locked(struct uart_port *uport) +{ + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + unsigned int data; + + clk_enable(msm_uport->clk); + + /* disable dlink */ + data = msm_hs_read(uport, UARTDM_DMEN_ADDR); + data &= ~UARTDM_RX_DM_EN_BMSK; + msm_hs_write(uport, UARTDM_DMEN_ADDR, data); + + /* Disable the receiver */ + if (msm_uport->rx.flush == FLUSH_NONE) + msm_dmov_stop_cmd(msm_uport->dma_rx_channel, NULL, 1); + + if (msm_uport->rx.flush != FLUSH_SHUTDOWN) + msm_uport->rx.flush = FLUSH_STOP; + + clk_disable(msm_uport->clk); +} + +/* Transmit the next chunk of data */ +static void msm_hs_submit_tx_locked(struct uart_port *uport) +{ + int left; + int tx_count; + dma_addr_t src_addr; + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + struct msm_hs_tx *tx = &msm_uport->tx; + struct circ_buf *tx_buf = &msm_uport->uport.state->xmit; + + if (uart_circ_empty(tx_buf) || uport->state->port.tty->stopped) { + msm_hs_stop_tx_locked(uport); + return; + } + + tx->dma_in_flight = 1; + + tx_count = uart_circ_chars_pending(tx_buf); + + if (UARTDM_TX_BUF_SIZE < tx_count) + tx_count = UARTDM_TX_BUF_SIZE; + + left = UART_XMIT_SIZE - tx_buf->tail; + + if (tx_count > left) + tx_count = left; + + src_addr = tx->dma_base + tx_buf->tail; + dma_sync_single_for_device(uport->dev, src_addr, tx_count, + DMA_TO_DEVICE); + + tx->command_ptr->num_rows = (((tx_count + 15) >> 4) << 16) | + ((tx_count + 15) >> 4); + tx->command_ptr->src_row_addr = src_addr; + + dma_sync_single_for_device(uport->dev, tx->mapped_cmd_ptr, + sizeof(dmov_box), DMA_TO_DEVICE); + + *tx->command_ptr_ptr = CMD_PTR_LP | DMOV_CMD_ADDR(tx->mapped_cmd_ptr); + + dma_sync_single_for_device(uport->dev, tx->mapped_cmd_ptr_ptr, + sizeof(u32 *), DMA_TO_DEVICE); + + /* Save tx_count to use in Callback */ + tx->tx_count = tx_count; + msm_hs_write(uport, UARTDM_NCF_TX_ADDR, tx_count); + + /* Disable the tx_ready interrupt */ + msm_uport->imr_reg &= ~UARTDM_ISR_TX_READY_BMSK; + msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg); + msm_dmov_enqueue_cmd(msm_uport->dma_tx_channel, &tx->xfer); +} + +/* Start to receive the next chunk of data */ +static void msm_hs_start_rx_locked(struct uart_port *uport) +{ + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + + msm_hs_write(uport, UARTDM_CR_ADDR, RESET_STALE_INT); + msm_hs_write(uport, UARTDM_DMRX_ADDR, UARTDM_RX_BUF_SIZE); + msm_hs_write(uport, UARTDM_CR_ADDR, STALE_EVENT_ENABLE); + msm_uport->imr_reg |= UARTDM_ISR_RXLEV_BMSK; + msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg); + + msm_uport->rx.flush = FLUSH_NONE; + msm_dmov_enqueue_cmd(msm_uport->dma_rx_channel, &msm_uport->rx.xfer); + + /* might have finished RX and be ready to clock off */ + hrtimer_start(&msm_uport->clk_off_timer, msm_uport->clk_off_delay, + HRTIMER_MODE_REL); +} + +/* Enable the transmitter Interrupt */ +static void msm_hs_start_tx_locked(struct uart_port *uport) +{ + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + + clk_enable(msm_uport->clk); + + if (msm_uport->exit_lpm_cb) + msm_uport->exit_lpm_cb(uport); + + if (msm_uport->tx.tx_ready_int_en == 0) { + msm_uport->tx.tx_ready_int_en = 1; + msm_hs_submit_tx_locked(uport); + } + + clk_disable(msm_uport->clk); +} + +/* + * This routine is called when we are done with a DMA transfer + * + * This routine is registered with Data mover when we set + * up a Data Mover transfer. It is called from Data mover ISR + * when the DMA transfer is done. + */ +static void msm_hs_dmov_tx_callback(struct msm_dmov_cmd *cmd_ptr, + unsigned int result, + struct msm_dmov_errdata *err) +{ + unsigned long flags; + struct msm_hs_port *msm_uport; + + /* DMA did not finish properly */ + WARN_ON((((result & RSLT_FIFO_CNTR_BMSK) >> 28) == 1) && + !(result & RSLT_VLD)); + + msm_uport = container_of(cmd_ptr, struct msm_hs_port, tx.xfer); + + spin_lock_irqsave(&msm_uport->uport.lock, flags); + clk_enable(msm_uport->clk); + + msm_uport->imr_reg |= UARTDM_ISR_TX_READY_BMSK; + msm_hs_write(&msm_uport->uport, UARTDM_IMR_ADDR, msm_uport->imr_reg); + + clk_disable(msm_uport->clk); + spin_unlock_irqrestore(&msm_uport->uport.lock, flags); +} + +/* + * This routine is called when we are done with a DMA transfer or the + * a flush has been sent to the data mover driver. + * + * This routine is registered with Data mover when we set up a Data Mover + * transfer. It is called from Data mover ISR when the DMA transfer is done. + */ +static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, + unsigned int result, + struct msm_dmov_errdata *err) +{ + int retval; + int rx_count; + unsigned long status; + unsigned int error_f = 0; + unsigned long flags; + unsigned int flush; + struct tty_struct *tty; + struct uart_port *uport; + struct msm_hs_port *msm_uport; + + msm_uport = container_of(cmd_ptr, struct msm_hs_port, rx.xfer); + uport = &msm_uport->uport; + + spin_lock_irqsave(&uport->lock, flags); + clk_enable(msm_uport->clk); + + tty = uport->state->port.tty; + + msm_hs_write(uport, UARTDM_CR_ADDR, STALE_EVENT_DISABLE); + + status = msm_hs_read(uport, UARTDM_SR_ADDR); + + /* overflow is not connect to data in a FIFO */ + if (unlikely((status & UARTDM_SR_OVERRUN_BMSK) && + (uport->read_status_mask & CREAD))) { + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + uport->icount.buf_overrun++; + error_f = 1; + } + + if (!(uport->ignore_status_mask & INPCK)) + status = status & ~(UARTDM_SR_PAR_FRAME_BMSK); + + if (unlikely(status & UARTDM_SR_PAR_FRAME_BMSK)) { + /* Can not tell difference between parity & frame error */ + uport->icount.parity++; + error_f = 1; + if (uport->ignore_status_mask & IGNPAR) + tty_insert_flip_char(tty, 0, TTY_PARITY); + } + + if (error_f) + msm_hs_write(uport, UARTDM_CR_ADDR, RESET_ERROR_STATUS); + + if (msm_uport->clk_req_off_state == CLK_REQ_OFF_FLUSH_ISSUED) + msm_uport->clk_req_off_state = CLK_REQ_OFF_RXSTALE_FLUSHED; + + flush = msm_uport->rx.flush; + if (flush == FLUSH_IGNORE) + msm_hs_start_rx_locked(uport); + if (flush == FLUSH_STOP) + msm_uport->rx.flush = FLUSH_SHUTDOWN; + if (flush >= FLUSH_DATA_INVALID) + goto out; + + rx_count = msm_hs_read(uport, UARTDM_RX_TOTAL_SNAP_ADDR); + + if (0 != (uport->read_status_mask & CREAD)) { + retval = tty_insert_flip_string(tty, msm_uport->rx.buffer, + rx_count); + BUG_ON(retval != rx_count); + } + + msm_hs_start_rx_locked(uport); + +out: + clk_disable(msm_uport->clk); + + spin_unlock_irqrestore(&uport->lock, flags); + + if (flush < FLUSH_DATA_INVALID) + queue_work(msm_hs_workqueue, &msm_uport->rx.tty_work); +} + +static void msm_hs_tty_flip_buffer_work(struct work_struct *work) +{ + struct msm_hs_port *msm_uport = + container_of(work, struct msm_hs_port, rx.tty_work); + struct tty_struct *tty = msm_uport->uport.state->port.tty; + + tty_flip_buffer_push(tty); +} + +/* + * Standard API, Current states of modem control inputs + * + * Since CTS can be handled entirely by HARDWARE we always + * indicate clear to send and count on the TX FIFO to block when + * it fills up. + * + * - TIOCM_DCD + * - TIOCM_CTS + * - TIOCM_DSR + * - TIOCM_RI + * (Unsupported) DCD and DSR will return them high. RI will return low. + */ +static unsigned int msm_hs_get_mctrl_locked(struct uart_port *uport) +{ + return TIOCM_DSR | TIOCM_CAR | TIOCM_CTS; +} + +/* + * True enables UART auto RFR, which indicates we are ready for data if the RX + * buffer is not full. False disables auto RFR, and deasserts RFR to indicate + * we are not ready for data. Must be called with UART clock on. + */ +static void set_rfr_locked(struct uart_port *uport, int auto_rfr) +{ + unsigned int data; + + data = msm_hs_read(uport, UARTDM_MR1_ADDR); + + if (auto_rfr) { + /* enable auto ready-for-receiving */ + data |= UARTDM_MR1_RX_RDY_CTL_BMSK; + msm_hs_write(uport, UARTDM_MR1_ADDR, data); + } else { + /* disable auto ready-for-receiving */ + data &= ~UARTDM_MR1_RX_RDY_CTL_BMSK; + msm_hs_write(uport, UARTDM_MR1_ADDR, data); + /* RFR is active low, set high */ + msm_hs_write(uport, UARTDM_CR_ADDR, RFR_HIGH); + } +} + +/* + * Standard API, used to set or clear RFR + */ +static void msm_hs_set_mctrl_locked(struct uart_port *uport, + unsigned int mctrl) +{ + unsigned int auto_rfr; + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + + clk_enable(msm_uport->clk); + + auto_rfr = TIOCM_RTS & mctrl ? 1 : 0; + set_rfr_locked(uport, auto_rfr); + + clk_disable(msm_uport->clk); +} + +/* Standard API, Enable modem status (CTS) interrupt */ +static void msm_hs_enable_ms_locked(struct uart_port *uport) +{ + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + + clk_enable(msm_uport->clk); + + /* Enable DELTA_CTS Interrupt */ + msm_uport->imr_reg |= UARTDM_ISR_DELTA_CTS_BMSK; + msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg); + + clk_disable(msm_uport->clk); + +} + +/* + * Standard API, Break Signal + * + * Control the transmission of a break signal. ctl eq 0 => break + * signal terminate ctl ne 0 => start break signal + */ +static void msm_hs_break_ctl(struct uart_port *uport, int ctl) +{ + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + + clk_enable(msm_uport->clk); + msm_hs_write(uport, UARTDM_CR_ADDR, ctl ? START_BREAK : STOP_BREAK); + clk_disable(msm_uport->clk); +} + +static void msm_hs_config_port(struct uart_port *uport, int cfg_flags) +{ + unsigned long flags; + + spin_lock_irqsave(&uport->lock, flags); + if (cfg_flags & UART_CONFIG_TYPE) { + uport->type = PORT_MSM; + msm_hs_request_port(uport); + } + spin_unlock_irqrestore(&uport->lock, flags); +} + +/* Handle CTS changes (Called from interrupt handler) */ +static void msm_hs_handle_delta_cts(struct uart_port *uport) +{ + unsigned long flags; + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + + spin_lock_irqsave(&uport->lock, flags); + clk_enable(msm_uport->clk); + + /* clear interrupt */ + msm_hs_write(uport, UARTDM_CR_ADDR, RESET_CTS); + uport->icount.cts++; + + clk_disable(msm_uport->clk); + spin_unlock_irqrestore(&uport->lock, flags); + + /* clear the IOCTL TIOCMIWAIT if called */ + wake_up_interruptible(&uport->state->port.delta_msr_wait); +} + +/* check if the TX path is flushed, and if so clock off + * returns 0 did not clock off, need to retry (still sending final byte) + * -1 did not clock off, do not retry + * 1 if we clocked off + */ +static int msm_hs_check_clock_off_locked(struct uart_port *uport) +{ + unsigned long sr_status; + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + struct circ_buf *tx_buf = &uport->state->xmit; + + /* Cancel if tx tty buffer is not empty, dma is in flight, + * or tx fifo is not empty, or rx fifo is not empty */ + if (msm_uport->clk_state != MSM_HS_CLK_REQUEST_OFF || + !uart_circ_empty(tx_buf) || msm_uport->tx.dma_in_flight || + (msm_uport->imr_reg & UARTDM_ISR_TXLEV_BMSK) || + !(msm_uport->imr_reg & UARTDM_ISR_RXLEV_BMSK)) { + return -1; + } + + /* Make sure the uart is finished with the last byte */ + sr_status = msm_hs_read(uport, UARTDM_SR_ADDR); + if (!(sr_status & UARTDM_SR_TXEMT_BMSK)) + return 0; /* retry */ + + /* Make sure forced RXSTALE flush complete */ + switch (msm_uport->clk_req_off_state) { + case CLK_REQ_OFF_START: + msm_uport->clk_req_off_state = CLK_REQ_OFF_RXSTALE_ISSUED; + msm_hs_write(uport, UARTDM_CR_ADDR, FORCE_STALE_EVENT); + return 0; /* RXSTALE flush not complete - retry */ + case CLK_REQ_OFF_RXSTALE_ISSUED: + case CLK_REQ_OFF_FLUSH_ISSUED: + return 0; /* RXSTALE flush not complete - retry */ + case CLK_REQ_OFF_RXSTALE_FLUSHED: + break; /* continue */ + } + + if (msm_uport->rx.flush != FLUSH_SHUTDOWN) { + if (msm_uport->rx.flush == FLUSH_NONE) + msm_hs_stop_rx_locked(uport); + return 0; /* come back later to really clock off */ + } + + /* we really want to clock off */ + clk_disable(msm_uport->clk); + msm_uport->clk_state = MSM_HS_CLK_OFF; + + if (use_low_power_rx_wakeup(msm_uport)) { + msm_uport->rx_wakeup.ignore = 1; + enable_irq(msm_uport->rx_wakeup.irq); + } + return 1; +} + +static enum hrtimer_restart msm_hs_clk_off_retry(struct hrtimer *timer) +{ + unsigned long flags; + int ret = HRTIMER_NORESTART; + struct msm_hs_port *msm_uport = container_of(timer, struct msm_hs_port, + clk_off_timer); + struct uart_port *uport = &msm_uport->uport; + + spin_lock_irqsave(&uport->lock, flags); + + if (!msm_hs_check_clock_off_locked(uport)) { + hrtimer_forward_now(timer, msm_uport->clk_off_delay); + ret = HRTIMER_RESTART; + } + + spin_unlock_irqrestore(&uport->lock, flags); + + return ret; +} + +static irqreturn_t msm_hs_isr(int irq, void *dev) +{ + unsigned long flags; + unsigned long isr_status; + struct msm_hs_port *msm_uport = dev; + struct uart_port *uport = &msm_uport->uport; + struct circ_buf *tx_buf = &uport->state->xmit; + struct msm_hs_tx *tx = &msm_uport->tx; + struct msm_hs_rx *rx = &msm_uport->rx; + + spin_lock_irqsave(&uport->lock, flags); + + isr_status = msm_hs_read(uport, UARTDM_MISR_ADDR); + + /* Uart RX starting */ + if (isr_status & UARTDM_ISR_RXLEV_BMSK) { + msm_uport->imr_reg &= ~UARTDM_ISR_RXLEV_BMSK; + msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg); + } + /* Stale rx interrupt */ + if (isr_status & UARTDM_ISR_RXSTALE_BMSK) { + msm_hs_write(uport, UARTDM_CR_ADDR, STALE_EVENT_DISABLE); + msm_hs_write(uport, UARTDM_CR_ADDR, RESET_STALE_INT); + + if (msm_uport->clk_req_off_state == CLK_REQ_OFF_RXSTALE_ISSUED) + msm_uport->clk_req_off_state = + CLK_REQ_OFF_FLUSH_ISSUED; + if (rx->flush == FLUSH_NONE) { + rx->flush = FLUSH_DATA_READY; + msm_dmov_stop_cmd(msm_uport->dma_rx_channel, NULL, 1); + } + } + /* tx ready interrupt */ + if (isr_status & UARTDM_ISR_TX_READY_BMSK) { + /* Clear TX Ready */ + msm_hs_write(uport, UARTDM_CR_ADDR, CLEAR_TX_READY); + + if (msm_uport->clk_state == MSM_HS_CLK_REQUEST_OFF) { + msm_uport->imr_reg |= UARTDM_ISR_TXLEV_BMSK; + msm_hs_write(uport, UARTDM_IMR_ADDR, + msm_uport->imr_reg); + } + + /* Complete DMA TX transactions and submit new transactions */ + tx_buf->tail = (tx_buf->tail + tx->tx_count) & ~UART_XMIT_SIZE; + + tx->dma_in_flight = 0; + + uport->icount.tx += tx->tx_count; + if (tx->tx_ready_int_en) + msm_hs_submit_tx_locked(uport); + + if (uart_circ_chars_pending(tx_buf) < WAKEUP_CHARS) + uart_write_wakeup(uport); + } + if (isr_status & UARTDM_ISR_TXLEV_BMSK) { + /* TX FIFO is empty */ + msm_uport->imr_reg &= ~UARTDM_ISR_TXLEV_BMSK; + msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg); + if (!msm_hs_check_clock_off_locked(uport)) + hrtimer_start(&msm_uport->clk_off_timer, + msm_uport->clk_off_delay, + HRTIMER_MODE_REL); + } + + /* Change in CTS interrupt */ + if (isr_status & UARTDM_ISR_DELTA_CTS_BMSK) + msm_hs_handle_delta_cts(uport); + + spin_unlock_irqrestore(&uport->lock, flags); + + return IRQ_HANDLED; +} + +void msm_hs_request_clock_off_locked(struct uart_port *uport) +{ + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + + if (msm_uport->clk_state == MSM_HS_CLK_ON) { + msm_uport->clk_state = MSM_HS_CLK_REQUEST_OFF; + msm_uport->clk_req_off_state = CLK_REQ_OFF_START; + if (!use_low_power_rx_wakeup(msm_uport)) + set_rfr_locked(uport, 0); + msm_uport->imr_reg |= UARTDM_ISR_TXLEV_BMSK; + msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg); + } +} + +/** + * msm_hs_request_clock_off - request to (i.e. asynchronously) turn off uart + * clock once pending TX is flushed and Rx DMA command is terminated. + * @uport: uart_port structure for the device instance. + * + * This functions puts the device into a partially active low power mode. It + * waits to complete all pending tx transactions, flushes ongoing Rx DMA + * command and terminates UART side Rx transaction, puts UART HW in non DMA + * mode and then clocks off the device. A client calls this when no UART + * data is expected. msm_request_clock_on() must be called before any further + * UART can be sent or received. + */ +void msm_hs_request_clock_off(struct uart_port *uport) +{ + unsigned long flags; + + spin_lock_irqsave(&uport->lock, flags); + msm_hs_request_clock_off_locked(uport); + spin_unlock_irqrestore(&uport->lock, flags); +} + +void msm_hs_request_clock_on_locked(struct uart_port *uport) +{ + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + unsigned int data; + + switch (msm_uport->clk_state) { + case MSM_HS_CLK_OFF: + clk_enable(msm_uport->clk); + disable_irq_nosync(msm_uport->rx_wakeup.irq); + /* fall-through */ + case MSM_HS_CLK_REQUEST_OFF: + if (msm_uport->rx.flush == FLUSH_STOP || + msm_uport->rx.flush == FLUSH_SHUTDOWN) { + msm_hs_write(uport, UARTDM_CR_ADDR, RESET_RX); + data = msm_hs_read(uport, UARTDM_DMEN_ADDR); + data |= UARTDM_RX_DM_EN_BMSK; + msm_hs_write(uport, UARTDM_DMEN_ADDR, data); + } + hrtimer_try_to_cancel(&msm_uport->clk_off_timer); + if (msm_uport->rx.flush == FLUSH_SHUTDOWN) + msm_hs_start_rx_locked(uport); + if (!use_low_power_rx_wakeup(msm_uport)) + set_rfr_locked(uport, 1); + if (msm_uport->rx.flush == FLUSH_STOP) + msm_uport->rx.flush = FLUSH_IGNORE; + msm_uport->clk_state = MSM_HS_CLK_ON; + break; + case MSM_HS_CLK_ON: + break; + case MSM_HS_CLK_PORT_OFF: + break; + } +} + +/** + * msm_hs_request_clock_on - Switch the device from partially active low + * power mode to fully active (i.e. clock on) mode. + * @uport: uart_port structure for the device. + * + * This function switches on the input clock, puts UART HW into DMA mode + * and enqueues an Rx DMA command if the device was in partially active + * mode. It has no effect if called with the device in inactive state. + */ +void msm_hs_request_clock_on(struct uart_port *uport) +{ + unsigned long flags; + + spin_lock_irqsave(&uport->lock, flags); + msm_hs_request_clock_on_locked(uport); + spin_unlock_irqrestore(&uport->lock, flags); +} + +static irqreturn_t msm_hs_rx_wakeup_isr(int irq, void *dev) +{ + unsigned int wakeup = 0; + unsigned long flags; + struct msm_hs_port *msm_uport = dev; + struct uart_port *uport = &msm_uport->uport; + struct tty_struct *tty = NULL; + + spin_lock_irqsave(&uport->lock, flags); + if (msm_uport->clk_state == MSM_HS_CLK_OFF) { + /* ignore the first irq - it is a pending irq that occured + * before enable_irq() */ + if (msm_uport->rx_wakeup.ignore) + msm_uport->rx_wakeup.ignore = 0; + else + wakeup = 1; + } + + if (wakeup) { + /* the uart was clocked off during an rx, wake up and + * optionally inject char into tty rx */ + msm_hs_request_clock_on_locked(uport); + if (msm_uport->rx_wakeup.inject_rx) { + tty = uport->state->port.tty; + tty_insert_flip_char(tty, + msm_uport->rx_wakeup.rx_to_inject, + TTY_NORMAL); + queue_work(msm_hs_workqueue, &msm_uport->rx.tty_work); + } + } + + spin_unlock_irqrestore(&uport->lock, flags); + + return IRQ_HANDLED; +} + +static const char *msm_hs_type(struct uart_port *port) +{ + return (port->type == PORT_MSM) ? "MSM_HS_UART" : NULL; +} + +/* Called when port is opened */ +static int msm_hs_startup(struct uart_port *uport) +{ + int ret; + int rfr_level; + unsigned long flags; + unsigned int data; + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + struct circ_buf *tx_buf = &uport->state->xmit; + struct msm_hs_tx *tx = &msm_uport->tx; + struct msm_hs_rx *rx = &msm_uport->rx; + + rfr_level = uport->fifosize; + if (rfr_level > 16) + rfr_level -= 16; + + tx->dma_base = dma_map_single(uport->dev, tx_buf->buf, UART_XMIT_SIZE, + DMA_TO_DEVICE); + + /* do not let tty layer execute RX in global workqueue, use a + * dedicated workqueue managed by this driver */ + uport->state->port.tty->low_latency = 1; + + /* turn on uart clk */ + ret = msm_hs_init_clk_locked(uport); + if (unlikely(ret)) { + printk(KERN_ERR "Turning uartclk failed!\n"); + goto err_msm_hs_init_clk; + } + + /* Set auto RFR Level */ + data = msm_hs_read(uport, UARTDM_MR1_ADDR); + data &= ~UARTDM_MR1_AUTO_RFR_LEVEL1_BMSK; + data &= ~UARTDM_MR1_AUTO_RFR_LEVEL0_BMSK; + data |= (UARTDM_MR1_AUTO_RFR_LEVEL1_BMSK & (rfr_level << 2)); + data |= (UARTDM_MR1_AUTO_RFR_LEVEL0_BMSK & rfr_level); + msm_hs_write(uport, UARTDM_MR1_ADDR, data); + + /* Make sure RXSTALE count is non-zero */ + data = msm_hs_read(uport, UARTDM_IPR_ADDR); + if (!data) { + data |= 0x1f & UARTDM_IPR_STALE_LSB_BMSK; + msm_hs_write(uport, UARTDM_IPR_ADDR, data); + } + + /* Enable Data Mover Mode */ + data = UARTDM_TX_DM_EN_BMSK | UARTDM_RX_DM_EN_BMSK; + msm_hs_write(uport, UARTDM_DMEN_ADDR, data); + + /* Reset TX */ + msm_hs_write(uport, UARTDM_CR_ADDR, RESET_TX); + msm_hs_write(uport, UARTDM_CR_ADDR, RESET_RX); + msm_hs_write(uport, UARTDM_CR_ADDR, RESET_ERROR_STATUS); + msm_hs_write(uport, UARTDM_CR_ADDR, RESET_BREAK_INT); + msm_hs_write(uport, UARTDM_CR_ADDR, RESET_STALE_INT); + msm_hs_write(uport, UARTDM_CR_ADDR, RESET_CTS); + msm_hs_write(uport, UARTDM_CR_ADDR, RFR_LOW); + /* Turn on Uart Receiver */ + msm_hs_write(uport, UARTDM_CR_ADDR, UARTDM_CR_RX_EN_BMSK); + + /* Turn on Uart Transmitter */ + msm_hs_write(uport, UARTDM_CR_ADDR, UARTDM_CR_TX_EN_BMSK); + + /* Initialize the tx */ + tx->tx_ready_int_en = 0; + tx->dma_in_flight = 0; + + tx->xfer.complete_func = msm_hs_dmov_tx_callback; + tx->xfer.execute_func = NULL; + + tx->command_ptr->cmd = CMD_LC | + CMD_DST_CRCI(msm_uport->dma_tx_crci) | CMD_MODE_BOX; + + tx->command_ptr->src_dst_len = (MSM_UARTDM_BURST_SIZE << 16) + | (MSM_UARTDM_BURST_SIZE); + + tx->command_ptr->row_offset = (MSM_UARTDM_BURST_SIZE << 16); + + tx->command_ptr->dst_row_addr = + msm_uport->uport.mapbase + UARTDM_TF_ADDR; + + + /* Turn on Uart Receive */ + rx->xfer.complete_func = msm_hs_dmov_rx_callback; + rx->xfer.execute_func = NULL; + + rx->command_ptr->cmd = CMD_LC | + CMD_SRC_CRCI(msm_uport->dma_rx_crci) | CMD_MODE_BOX; + + rx->command_ptr->src_dst_len = (MSM_UARTDM_BURST_SIZE << 16) + | (MSM_UARTDM_BURST_SIZE); + rx->command_ptr->row_offset = MSM_UARTDM_BURST_SIZE; + rx->command_ptr->src_row_addr = uport->mapbase + UARTDM_RF_ADDR; + + + msm_uport->imr_reg |= UARTDM_ISR_RXSTALE_BMSK; + /* Enable reading the current CTS, no harm even if CTS is ignored */ + msm_uport->imr_reg |= UARTDM_ISR_CURRENT_CTS_BMSK; + + msm_hs_write(uport, UARTDM_TFWR_ADDR, 0); /* TXLEV on empty TX fifo */ + + + ret = request_irq(uport->irq, msm_hs_isr, IRQF_TRIGGER_HIGH, + "msm_hs_uart", msm_uport); + if (unlikely(ret)) { + printk(KERN_ERR "Request msm_hs_uart IRQ failed!\n"); + goto err_request_irq; + } + if (use_low_power_rx_wakeup(msm_uport)) { + ret = request_irq(msm_uport->rx_wakeup.irq, + msm_hs_rx_wakeup_isr, + IRQF_TRIGGER_FALLING, + "msm_hs_rx_wakeup", msm_uport); + if (unlikely(ret)) { + printk(KERN_ERR "Request msm_hs_rx_wakeup IRQ failed!\n"); + free_irq(uport->irq, msm_uport); + goto err_request_irq; + } + disable_irq(msm_uport->rx_wakeup.irq); + } + + spin_lock_irqsave(&uport->lock, flags); + + msm_hs_write(uport, UARTDM_RFWR_ADDR, 0); + msm_hs_start_rx_locked(uport); + + spin_unlock_irqrestore(&uport->lock, flags); + ret = pm_runtime_set_active(uport->dev); + if (ret) + dev_err(uport->dev, "set active error:%d\n", ret); + pm_runtime_enable(uport->dev); + + return 0; + +err_request_irq: +err_msm_hs_init_clk: + dma_unmap_single(uport->dev, tx->dma_base, + UART_XMIT_SIZE, DMA_TO_DEVICE); + return ret; +} + +/* Initialize tx and rx data structures */ +static int __devinit uartdm_init_port(struct uart_port *uport) +{ + int ret = 0; + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + struct msm_hs_tx *tx = &msm_uport->tx; + struct msm_hs_rx *rx = &msm_uport->rx; + + /* Allocate the command pointer. Needs to be 64 bit aligned */ + tx->command_ptr = kmalloc(sizeof(dmov_box), GFP_KERNEL | __GFP_DMA); + if (!tx->command_ptr) + return -ENOMEM; + + tx->command_ptr_ptr = kmalloc(sizeof(u32 *), GFP_KERNEL | __GFP_DMA); + if (!tx->command_ptr_ptr) { + ret = -ENOMEM; + goto err_tx_command_ptr_ptr; + } + + tx->mapped_cmd_ptr = dma_map_single(uport->dev, tx->command_ptr, + sizeof(dmov_box), DMA_TO_DEVICE); + tx->mapped_cmd_ptr_ptr = dma_map_single(uport->dev, + tx->command_ptr_ptr, + sizeof(u32 *), DMA_TO_DEVICE); + tx->xfer.cmdptr = DMOV_CMD_ADDR(tx->mapped_cmd_ptr_ptr); + + init_waitqueue_head(&rx->wait); + + rx->pool = dma_pool_create("rx_buffer_pool", uport->dev, + UARTDM_RX_BUF_SIZE, 16, 0); + if (!rx->pool) { + pr_err("%s(): cannot allocate rx_buffer_pool", __func__); + ret = -ENOMEM; + goto err_dma_pool_create; + } + + rx->buffer = dma_pool_alloc(rx->pool, GFP_KERNEL, &rx->rbuffer); + if (!rx->buffer) { + pr_err("%s(): cannot allocate rx->buffer", __func__); + ret = -ENOMEM; + goto err_dma_pool_alloc; + } + + /* Allocate the command pointer. Needs to be 64 bit aligned */ + rx->command_ptr = kmalloc(sizeof(dmov_box), GFP_KERNEL | __GFP_DMA); + if (!rx->command_ptr) { + pr_err("%s(): cannot allocate rx->command_ptr", __func__); + ret = -ENOMEM; + goto err_rx_command_ptr; + } + + rx->command_ptr_ptr = kmalloc(sizeof(u32 *), GFP_KERNEL | __GFP_DMA); + if (!rx->command_ptr_ptr) { + pr_err("%s(): cannot allocate rx->command_ptr_ptr", __func__); + ret = -ENOMEM; + goto err_rx_command_ptr_ptr; + } + + rx->command_ptr->num_rows = ((UARTDM_RX_BUF_SIZE >> 4) << 16) | + (UARTDM_RX_BUF_SIZE >> 4); + + rx->command_ptr->dst_row_addr = rx->rbuffer; + + rx->mapped_cmd_ptr = dma_map_single(uport->dev, rx->command_ptr, + sizeof(dmov_box), DMA_TO_DEVICE); + + *rx->command_ptr_ptr = CMD_PTR_LP | DMOV_CMD_ADDR(rx->mapped_cmd_ptr); + + rx->cmdptr_dmaaddr = dma_map_single(uport->dev, rx->command_ptr_ptr, + sizeof(u32 *), DMA_TO_DEVICE); + rx->xfer.cmdptr = DMOV_CMD_ADDR(rx->cmdptr_dmaaddr); + + INIT_WORK(&rx->tty_work, msm_hs_tty_flip_buffer_work); + + return ret; + +err_rx_command_ptr_ptr: + kfree(rx->command_ptr); +err_rx_command_ptr: + dma_pool_free(msm_uport->rx.pool, msm_uport->rx.buffer, + msm_uport->rx.rbuffer); +err_dma_pool_alloc: + dma_pool_destroy(msm_uport->rx.pool); +err_dma_pool_create: + dma_unmap_single(uport->dev, msm_uport->tx.mapped_cmd_ptr_ptr, + sizeof(u32 *), DMA_TO_DEVICE); + dma_unmap_single(uport->dev, msm_uport->tx.mapped_cmd_ptr, + sizeof(dmov_box), DMA_TO_DEVICE); + kfree(msm_uport->tx.command_ptr_ptr); +err_tx_command_ptr_ptr: + kfree(msm_uport->tx.command_ptr); + return ret; +} + +static int __devinit msm_hs_probe(struct platform_device *pdev) +{ + int ret; + struct uart_port *uport; + struct msm_hs_port *msm_uport; + struct resource *resource; + const struct msm_serial_hs_platform_data *pdata = + pdev->dev.platform_data; + + if (pdev->id < 0 || pdev->id >= UARTDM_NR) { + printk(KERN_ERR "Invalid plaform device ID = %d\n", pdev->id); + return -EINVAL; + } + + msm_uport = &q_uart_port[pdev->id]; + uport = &msm_uport->uport; + + uport->dev = &pdev->dev; + + resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (unlikely(!resource)) + return -ENXIO; + + uport->mapbase = resource->start; + uport->irq = platform_get_irq(pdev, 0); + if (unlikely(uport->irq < 0)) + return -ENXIO; + + if (unlikely(set_irq_wake(uport->irq, 1))) + return -ENXIO; + + if (pdata == NULL || pdata->rx_wakeup_irq < 0) + msm_uport->rx_wakeup.irq = -1; + else { + msm_uport->rx_wakeup.irq = pdata->rx_wakeup_irq; + msm_uport->rx_wakeup.ignore = 1; + msm_uport->rx_wakeup.inject_rx = pdata->inject_rx_on_wakeup; + msm_uport->rx_wakeup.rx_to_inject = pdata->rx_to_inject; + + if (unlikely(msm_uport->rx_wakeup.irq < 0)) + return -ENXIO; + + if (unlikely(set_irq_wake(msm_uport->rx_wakeup.irq, 1))) + return -ENXIO; + } + + if (pdata == NULL) + msm_uport->exit_lpm_cb = NULL; + else + msm_uport->exit_lpm_cb = pdata->exit_lpm_cb; + + resource = platform_get_resource_byname(pdev, IORESOURCE_DMA, + "uartdm_channels"); + if (unlikely(!resource)) + return -ENXIO; + + msm_uport->dma_tx_channel = resource->start; + msm_uport->dma_rx_channel = resource->end; + + resource = platform_get_resource_byname(pdev, IORESOURCE_DMA, + "uartdm_crci"); + if (unlikely(!resource)) + return -ENXIO; + + msm_uport->dma_tx_crci = resource->start; + msm_uport->dma_rx_crci = resource->end; + + uport->iotype = UPIO_MEM; + uport->fifosize = UART_FIFOSIZE; + uport->ops = &msm_hs_ops; + uport->flags = UPF_BOOT_AUTOCONF; + uport->uartclk = UARTCLK; + msm_uport->imr_reg = 0x0; + msm_uport->clk = clk_get(&pdev->dev, "uartdm_clk"); + if (IS_ERR(msm_uport->clk)) + return PTR_ERR(msm_uport->clk); + + ret = uartdm_init_port(uport); + if (unlikely(ret)) + return ret; + + msm_uport->clk_state = MSM_HS_CLK_PORT_OFF; + hrtimer_init(&msm_uport->clk_off_timer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); + msm_uport->clk_off_timer.function = msm_hs_clk_off_retry; + msm_uport->clk_off_delay = ktime_set(0, 1000000); /* 1ms */ + + uport->line = pdev->id; + return uart_add_one_port(&msm_hs_driver, uport); +} + +static int __init msm_serial_hs_init(void) +{ + int ret, i; + + /* Init all UARTS as non-configured */ + for (i = 0; i < UARTDM_NR; i++) + q_uart_port[i].uport.type = PORT_UNKNOWN; + + msm_hs_workqueue = create_singlethread_workqueue("msm_serial_hs"); + if (unlikely(!msm_hs_workqueue)) + return -ENOMEM; + + ret = uart_register_driver(&msm_hs_driver); + if (unlikely(ret)) { + printk(KERN_ERR "%s failed to load\n", __func__); + goto err_uart_register_driver; + } + + ret = platform_driver_register(&msm_serial_hs_platform_driver); + if (ret) { + printk(KERN_ERR "%s failed to load\n", __func__); + goto err_platform_driver_register; + } + + return ret; + +err_platform_driver_register: + uart_unregister_driver(&msm_hs_driver); +err_uart_register_driver: + destroy_workqueue(msm_hs_workqueue); + return ret; +} +module_init(msm_serial_hs_init); + +/* + * Called by the upper layer when port is closed. + * - Disables the port + * - Unhook the ISR + */ +static void msm_hs_shutdown(struct uart_port *uport) +{ + unsigned long flags; + struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); + + BUG_ON(msm_uport->rx.flush < FLUSH_STOP); + + spin_lock_irqsave(&uport->lock, flags); + clk_enable(msm_uport->clk); + + /* Disable the transmitter */ + msm_hs_write(uport, UARTDM_CR_ADDR, UARTDM_CR_TX_DISABLE_BMSK); + /* Disable the receiver */ + msm_hs_write(uport, UARTDM_CR_ADDR, UARTDM_CR_RX_DISABLE_BMSK); + + pm_runtime_disable(uport->dev); + pm_runtime_set_suspended(uport->dev); + + /* Free the interrupt */ + free_irq(uport->irq, msm_uport); + if (use_low_power_rx_wakeup(msm_uport)) + free_irq(msm_uport->rx_wakeup.irq, msm_uport); + + msm_uport->imr_reg = 0; + msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg); + + wait_event(msm_uport->rx.wait, msm_uport->rx.flush == FLUSH_SHUTDOWN); + + clk_disable(msm_uport->clk); /* to balance local clk_enable() */ + if (msm_uport->clk_state != MSM_HS_CLK_OFF) + clk_disable(msm_uport->clk); /* to balance clk_state */ + msm_uport->clk_state = MSM_HS_CLK_PORT_OFF; + + dma_unmap_single(uport->dev, msm_uport->tx.dma_base, + UART_XMIT_SIZE, DMA_TO_DEVICE); + + spin_unlock_irqrestore(&uport->lock, flags); + + if (cancel_work_sync(&msm_uport->rx.tty_work)) + msm_hs_tty_flip_buffer_work(&msm_uport->rx.tty_work); +} + +static void __exit msm_serial_hs_exit(void) +{ + flush_workqueue(msm_hs_workqueue); + destroy_workqueue(msm_hs_workqueue); + platform_driver_unregister(&msm_serial_hs_platform_driver); + uart_unregister_driver(&msm_hs_driver); +} +module_exit(msm_serial_hs_exit); + +#ifdef CONFIG_PM_RUNTIME +static int msm_hs_runtime_idle(struct device *dev) +{ + /* + * returning success from idle results in runtime suspend to be + * called + */ + return 0; +} + +static int msm_hs_runtime_resume(struct device *dev) +{ + struct platform_device *pdev = container_of(dev, struct + platform_device, dev); + struct msm_hs_port *msm_uport = &q_uart_port[pdev->id]; + + msm_hs_request_clock_on(&msm_uport->uport); + return 0; +} + +static int msm_hs_runtime_suspend(struct device *dev) +{ + struct platform_device *pdev = container_of(dev, struct + platform_device, dev); + struct msm_hs_port *msm_uport = &q_uart_port[pdev->id]; + + msm_hs_request_clock_off(&msm_uport->uport); + return 0; +} +#else +#define msm_hs_runtime_idle NULL +#define msm_hs_runtime_resume NULL +#define msm_hs_runtime_suspend NULL +#endif + +static const struct dev_pm_ops msm_hs_dev_pm_ops = { + .runtime_suspend = msm_hs_runtime_suspend, + .runtime_resume = msm_hs_runtime_resume, + .runtime_idle = msm_hs_runtime_idle, +}; + +static struct platform_driver msm_serial_hs_platform_driver = { + .probe = msm_hs_probe, + .remove = __devexit_p(msm_hs_remove), + .driver = { + .name = "msm_serial_hs", + .owner = THIS_MODULE, + .pm = &msm_hs_dev_pm_ops, + }, +}; + +static struct uart_driver msm_hs_driver = { + .owner = THIS_MODULE, + .driver_name = "msm_serial_hs", + .dev_name = "ttyHS", + .nr = UARTDM_NR, + .cons = 0, +}; + +static struct uart_ops msm_hs_ops = { + .tx_empty = msm_hs_tx_empty, + .set_mctrl = msm_hs_set_mctrl_locked, + .get_mctrl = msm_hs_get_mctrl_locked, + .stop_tx = msm_hs_stop_tx_locked, + .start_tx = msm_hs_start_tx_locked, + .stop_rx = msm_hs_stop_rx_locked, + .enable_ms = msm_hs_enable_ms_locked, + .break_ctl = msm_hs_break_ctl, + .startup = msm_hs_startup, + .shutdown = msm_hs_shutdown, + .set_termios = msm_hs_set_termios, + .pm = msm_hs_pm, + .type = msm_hs_type, + .config_port = msm_hs_config_port, + .release_port = msm_hs_release_port, + .request_port = msm_hs_request_port, +}; + +MODULE_DESCRIPTION("High Speed UART Driver for the MSM chipset"); +MODULE_VERSION("1.2"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/platform_data/msm_serial_hs.h b/include/linux/platform_data/msm_serial_hs.h new file mode 100644 index 000000000000..98a2046f8b31 --- /dev/null +++ b/include/linux/platform_data/msm_serial_hs.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2008 Google, Inc. + * Author: Nick Pelly + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_ARCH_MSM_SERIAL_HS_H +#define __ASM_ARCH_MSM_SERIAL_HS_H + +#include + +/* API to request the uart clock off or on for low power management + * Clients should call request_clock_off() when no uart data is expected, + * and must call request_clock_on() before any further uart data can be + * received. */ +extern void msm_hs_request_clock_off(struct uart_port *uport); +extern void msm_hs_request_clock_on(struct uart_port *uport); + +/** + * struct msm_serial_hs_platform_data + * @rx_wakeup_irq: Rx activity irq + * @rx_to_inject: extra character to be inserted to Rx tty on wakeup + * @inject_rx: 1 = insert rx_to_inject. 0 = do not insert extra character + * @exit_lpm_cb: function called before every Tx transaction + * + * This is an optional structure required for UART Rx GPIO IRQ based + * wakeup from low power state. UART wakeup can be triggered by RX activity + * (using a wakeup GPIO on the UART RX pin). This should only be used if + * there is not a wakeup GPIO on the UART CTS, and the first RX byte is + * known (eg., with the Bluetooth Texas Instruments HCILL protocol), + * since the first RX byte will always be lost. RTS will be asserted even + * while the UART is clocked off in this mode of operation. + */ +struct msm_serial_hs_platform_data { + int rx_wakeup_irq; + unsigned char inject_rx_on_wakeup; + char rx_to_inject; + void (*exit_lpm_cb)(struct uart_port *); +}; + +#endif -- cgit v1.2.3 From 9b37596a2e860404503a3f2a6513db60c296bfdc Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 7 Mar 2011 11:11:52 -0500 Subject: USB: move usbcore away from hcd->state The hcd->state variable is a disaster. It's not clearly owned by either usbcore or the host controller drivers, and they both change it from time to time, potentially stepping on each other's toes. It's not protected by any locks. And there's no mechanism to prevent it from going through an invalid transition. This patch (as1451) takes a first step toward fixing these problems. As it turns out, usbcore uses hcd->state for essentially only two things: checking whether the controller's root hub is running and checking whether the controller has died. Therefore the patch adds two new atomic bitflags to the hcd structure, to store these pieces of information. The new flags are used only by usbcore, and a private spinlock prevents invalid combinations (a dead controller's root hub cannot be running). The patch does not change the places where usbcore sets hcd->state, since HCDs may depend on them. Furthermore, there is one place in usb_hcd_irq() where usbcore still must use hcd->state: An HCD's interrupt handler can implicitly indicate that the controller died by setting hcd->state to HC_STATE_HALT. Nevertheless, the new code is a big improvement over the current code. The patch makes one other change. The hcd_bus_suspend() and hcd_bus_resume() routines now check first whether the host controller has died; if it has then they return immediately without calling the HCD's bus_suspend or bus_resume methods. This fixes the major problem reported in Bugzilla #29902: The system fails to suspend after a host controller dies during system resume. Signed-off-by: Alan Stern Tested-by: Alex Terekhov CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd-pci.c | 13 +++++------ drivers/usb/core/hcd.c | 55 ++++++++++++++++++++++++++++++++++------------ include/linux/usb/hcd.h | 4 ++++ 3 files changed, 51 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index f71e8e307e0f..d37088591d9a 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -363,8 +363,7 @@ static int check_root_hub_suspended(struct device *dev) struct pci_dev *pci_dev = to_pci_dev(dev); struct usb_hcd *hcd = pci_get_drvdata(pci_dev); - if (!(hcd->state == HC_STATE_SUSPENDED || - hcd->state == HC_STATE_HALT)) { + if (HCD_RH_RUNNING(hcd)) { dev_warn(dev, "Root hub is not suspended\n"); return -EBUSY; } @@ -386,7 +385,7 @@ static int suspend_common(struct device *dev, bool do_wakeup) if (retval) return retval; - if (hcd->driver->pci_suspend) { + if (hcd->driver->pci_suspend && !HCD_DEAD(hcd)) { /* Optimization: Don't suspend if a root-hub wakeup is * pending and it would cause the HCD to wake up anyway. */ @@ -427,7 +426,7 @@ static int resume_common(struct device *dev, int event) struct usb_hcd *hcd = pci_get_drvdata(pci_dev); int retval; - if (hcd->state != HC_STATE_SUSPENDED) { + if (HCD_RH_RUNNING(hcd)) { dev_dbg(dev, "can't resume, not suspended!\n"); return 0; } @@ -442,7 +441,7 @@ static int resume_common(struct device *dev, int event) clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); - if (hcd->driver->pci_resume) { + if (hcd->driver->pci_resume && !HCD_DEAD(hcd)) { if (event != PM_EVENT_AUTO_RESUME) wait_for_companions(pci_dev, hcd); @@ -475,10 +474,10 @@ static int hcd_pci_suspend_noirq(struct device *dev) pci_save_state(pci_dev); - /* If the root hub is HALTed rather than SUSPENDed, + /* If the root hub is dead rather than suspended, * disallow remote wakeup. */ - if (hcd->state == HC_STATE_HALT) + if (HCD_DEAD(hcd)) device_set_wakeup_enable(dev, 0); dev_dbg(dev, "wakeup: %d\n", device_may_wakeup(dev)); diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 24765fd6cf12..e7d0c4571bbe 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -983,7 +983,7 @@ static int register_root_hub(struct usb_hcd *hcd) spin_unlock_irq (&hcd_root_hub_lock); /* Did the HC die before the root hub was registered? */ - if (hcd->state == HC_STATE_HALT) + if (HCD_DEAD(hcd) || hcd->state == HC_STATE_HALT) usb_hc_died (hcd); /* This time clean up */ } @@ -1089,13 +1089,10 @@ int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb) * Check the host controller's state and add the URB to the * endpoint's queue. */ - switch (hcd->state) { - case HC_STATE_RUNNING: - case HC_STATE_RESUMING: + if (HCD_RH_RUNNING(hcd)) { urb->unlinked = 0; list_add_tail(&urb->urb_list, &urb->ep->urb_list); - break; - default: + } else { rc = -ESHUTDOWN; goto done; } @@ -1931,7 +1928,7 @@ int usb_hcd_get_frame_number (struct usb_device *udev) { struct usb_hcd *hcd = bus_to_hcd(udev->bus); - if (!HC_IS_RUNNING (hcd->state)) + if (!HCD_RH_RUNNING(hcd)) return -ESHUTDOWN; return hcd->driver->get_frame_number (hcd); } @@ -1948,9 +1945,15 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg) dev_dbg(&rhdev->dev, "bus %s%s\n", (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "suspend"); + if (HCD_DEAD(hcd)) { + dev_dbg(&rhdev->dev, "skipped %s of dead bus\n", "suspend"); + return 0; + } + if (!hcd->driver->bus_suspend) { status = -ENOENT; } else { + clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); hcd->state = HC_STATE_QUIESCING; status = hcd->driver->bus_suspend(hcd); } @@ -1958,7 +1961,12 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg) usb_set_device_state(rhdev, USB_STATE_SUSPENDED); hcd->state = HC_STATE_SUSPENDED; } else { - hcd->state = old_state; + spin_lock_irq(&hcd_root_hub_lock); + if (!HCD_DEAD(hcd)) { + set_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); + hcd->state = old_state; + } + spin_unlock_irq(&hcd_root_hub_lock); dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", "suspend", status); } @@ -1973,9 +1981,13 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) dev_dbg(&rhdev->dev, "usb %s%s\n", (msg.event & PM_EVENT_AUTO ? "auto-" : ""), "resume"); + if (HCD_DEAD(hcd)) { + dev_dbg(&rhdev->dev, "skipped %s of dead bus\n", "resume"); + return 0; + } if (!hcd->driver->bus_resume) return -ENOENT; - if (hcd->state == HC_STATE_RUNNING) + if (HCD_RH_RUNNING(hcd)) return 0; hcd->state = HC_STATE_RESUMING; @@ -1984,10 +1996,15 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) if (status == 0) { /* TRSMRCY = 10 msec */ msleep(10); - usb_set_device_state(rhdev, rhdev->actconfig - ? USB_STATE_CONFIGURED - : USB_STATE_ADDRESS); - hcd->state = HC_STATE_RUNNING; + spin_lock_irq(&hcd_root_hub_lock); + if (!HCD_DEAD(hcd)) { + usb_set_device_state(rhdev, rhdev->actconfig + ? USB_STATE_CONFIGURED + : USB_STATE_ADDRESS); + set_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); + hcd->state = HC_STATE_RUNNING; + } + spin_unlock_irq(&hcd_root_hub_lock); } else { hcd->state = old_state; dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", @@ -2098,7 +2115,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd) */ local_irq_save(flags); - if (unlikely(hcd->state == HC_STATE_HALT || !HCD_HW_ACCESSIBLE(hcd))) { + if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd))) { rc = IRQ_NONE; } else if (hcd->driver->irq(hcd) == IRQ_NONE) { rc = IRQ_NONE; @@ -2132,6 +2149,8 @@ void usb_hc_died (struct usb_hcd *hcd) dev_err (hcd->self.controller, "HC died; cleaning up\n"); spin_lock_irqsave (&hcd_root_hub_lock, flags); + clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); + set_bit(HCD_FLAG_DEAD, &hcd->flags); if (hcd->rh_registered) { clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); @@ -2274,6 +2293,12 @@ int usb_add_hcd(struct usb_hcd *hcd, */ device_init_wakeup(&rhdev->dev, 1); + /* HCD_FLAG_RH_RUNNING doesn't matter until the root hub is + * registered. But since the controller can die at any time, + * let's initialize the flag before touching the hardware. + */ + set_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); + /* "reset" is misnamed; its role is now one-time init. the controller * should already have been reset (and boot firmware kicked off etc). */ @@ -2341,6 +2366,7 @@ int usb_add_hcd(struct usb_hcd *hcd, return retval; error_create_attr_group: + clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); if (HC_IS_RUNNING(hcd->state)) hcd->state = HC_STATE_QUIESCING; spin_lock_irq(&hcd_root_hub_lock); @@ -2393,6 +2419,7 @@ void usb_remove_hcd(struct usb_hcd *hcd) usb_get_dev(rhdev); sysfs_remove_group(&rhdev->dev.kobj, &usb_bus_attr_group); + clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags); if (HC_IS_RUNNING (hcd->state)) hcd->state = HC_STATE_QUIESCING; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 9cfba4f2457b..8b65068c6af9 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -99,6 +99,8 @@ struct usb_hcd { #define HCD_FLAG_POLL_RH 2 /* poll for rh status? */ #define HCD_FLAG_POLL_PENDING 3 /* status has changed? */ #define HCD_FLAG_WAKEUP_PENDING 4 /* root hub is resuming? */ +#define HCD_FLAG_RH_RUNNING 5 /* root hub is running? */ +#define HCD_FLAG_DEAD 6 /* controller has died? */ /* The flags can be tested using these macros; they are likely to * be slightly faster than test_bit(). @@ -108,6 +110,8 @@ struct usb_hcd { #define HCD_POLL_RH(hcd) ((hcd)->flags & (1U << HCD_FLAG_POLL_RH)) #define HCD_POLL_PENDING(hcd) ((hcd)->flags & (1U << HCD_FLAG_POLL_PENDING)) #define HCD_WAKEUP_PENDING(hcd) ((hcd)->flags & (1U << HCD_FLAG_WAKEUP_PENDING)) +#define HCD_RH_RUNNING(hcd) ((hcd)->flags & (1U << HCD_FLAG_RH_RUNNING)) +#define HCD_DEAD(hcd) ((hcd)->flags & (1U << HCD_FLAG_DEAD)) /* Flags that get set only during HCD registration or removal. */ unsigned rh_registered:1;/* is root hub registered? */ -- cgit v1.2.3 From d3cf2a8d4ddd121dbf4ad48c995648af04e0cfbf Mon Sep 17 00:00:00 2001 From: Arvid Brodin Date: Mon, 7 Mar 2011 15:36:21 +0100 Subject: usb/isp1760: Fix crash when unplugging bug This fixes a problem with my previous patch series where there's a great risk that the kernel will crash when unplugging interrupt devices from the USB port. These lines must have got missing when I rebased the patches from the older kernel I was working with to 2.6.37 and 2.6-next: This fixes a bug where the kernel may crash if you unplug a USB device that has active interrupt transfers. Signed-off-by: Arvid Brodin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp1760-hcd.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index d2b674ace0be..c7c1e0aa0b8e 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -1624,14 +1624,14 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) ptd_write(hcd->regs, reg_base, i, &ptd); - qtd = ints->qtd; + qtd = ints[i].qtd; qh = ints[i].qh; free_mem(hcd, qtd); qtd = clean_up_qtdlist(qtd, qh); - ints->qh = NULL; - ints->qtd = NULL; + ints[i].qh = NULL; + ints[i].qtd = NULL; isp1760_urb_done(hcd, urb); if (qtd) @@ -1655,7 +1655,6 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) if (!qtd) break; } - ints++; } spin_unlock_irqrestore(&priv->lock, flags); -- cgit v1.2.3 From dfb2130c453c2c6d36b5e0f39eca289cbdbb631d Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Fri, 4 Mar 2011 22:45:02 +0530 Subject: USB: Rename "msm72k_otg.c" to "msm_otg.c" This driver is used across all MSM SoCs. Hence give a generic name. All Functions and strutures are also using "msm_otg" as prefix. Signed-off-by: Pavankumar Kondeti Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/Kconfig | 2 +- drivers/usb/host/Kconfig | 2 +- drivers/usb/otg/Kconfig | 2 +- drivers/usb/otg/Makefile | 2 +- drivers/usb/otg/msm72k_otg.c | 1124 ----------------------------------------- drivers/usb/otg/msm_otg.c | 1124 +++++++++++++++++++++++++++++++++++++++++ include/linux/usb/msm_hsusb.h | 2 +- 7 files changed, 1129 insertions(+), 1129 deletions(-) delete mode 100644 drivers/usb/otg/msm72k_otg.c create mode 100644 drivers/usb/otg/msm_otg.c (limited to 'drivers') diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 99ed91c7cdc6..bfde50e20b30 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -552,7 +552,7 @@ config USB_GADGET_CI13XXX_MSM boolean "MIPS USB CI13xxx for MSM" depends on ARCH_MSM select USB_GADGET_DUALSPEED - select USB_MSM_OTG_72K + select USB_MSM_OTG help MSM SoC has chipidea USB controller. This driver uses ci13xxx_udc core. diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 9116d30bcdac..b5a908eacb82 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -156,7 +156,7 @@ config USB_EHCI_MSM bool "Support for MSM on-chip EHCI USB controller" depends on USB_EHCI_HCD && ARCH_MSM select USB_EHCI_ROOT_HUB_TT - select USB_MSM_OTG_72K + select USB_MSM_OTG ---help--- Enables support for the USB Host controller present on the Qualcomm chipsets. Root Hub has inbuilt TT. diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig index 9ffc8237fb4b..ceb24fee2eac 100644 --- a/drivers/usb/otg/Kconfig +++ b/drivers/usb/otg/Kconfig @@ -93,7 +93,7 @@ config USB_LANGWELL_OTG To compile this driver as a module, choose M here: the module will be called langwell_otg. -config USB_MSM_OTG_72K +config USB_MSM_OTG tristate "OTG support for Qualcomm on-chip USB controller" depends on (USB || USB_GADGET) && ARCH_MSM select USB_OTG_UTILS diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile index a520e715cfd6..e516894260bf 100644 --- a/drivers/usb/otg/Makefile +++ b/drivers/usb/otg/Makefile @@ -16,5 +16,5 @@ obj-$(CONFIG_TWL6030_USB) += twl6030-usb.o obj-$(CONFIG_USB_LANGWELL_OTG) += langwell_otg.o obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o obj-$(CONFIG_USB_ULPI) += ulpi.o -obj-$(CONFIG_USB_MSM_OTG_72K) += msm72k_otg.o +obj-$(CONFIG_USB_MSM_OTG) += msm_otg.o obj-$(CONFIG_AB8500_USB) += ab8500-usb.o diff --git a/drivers/usb/otg/msm72k_otg.c b/drivers/usb/otg/msm72k_otg.c deleted file mode 100644 index 296598628b85..000000000000 --- a/drivers/usb/otg/msm72k_otg.c +++ /dev/null @@ -1,1124 +0,0 @@ -/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#define MSM_USB_BASE (motg->regs) -#define DRIVER_NAME "msm_otg" - -#define ULPI_IO_TIMEOUT_USEC (10 * 1000) -static int ulpi_read(struct otg_transceiver *otg, u32 reg) -{ - struct msm_otg *motg = container_of(otg, struct msm_otg, otg); - int cnt = 0; - - /* initiate read operation */ - writel(ULPI_RUN | ULPI_READ | ULPI_ADDR(reg), - USB_ULPI_VIEWPORT); - - /* wait for completion */ - while (cnt < ULPI_IO_TIMEOUT_USEC) { - if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN)) - break; - udelay(1); - cnt++; - } - - if (cnt >= ULPI_IO_TIMEOUT_USEC) { - dev_err(otg->dev, "ulpi_read: timeout %08x\n", - readl(USB_ULPI_VIEWPORT)); - return -ETIMEDOUT; - } - return ULPI_DATA_READ(readl(USB_ULPI_VIEWPORT)); -} - -static int ulpi_write(struct otg_transceiver *otg, u32 val, u32 reg) -{ - struct msm_otg *motg = container_of(otg, struct msm_otg, otg); - int cnt = 0; - - /* initiate write operation */ - writel(ULPI_RUN | ULPI_WRITE | - ULPI_ADDR(reg) | ULPI_DATA(val), - USB_ULPI_VIEWPORT); - - /* wait for completion */ - while (cnt < ULPI_IO_TIMEOUT_USEC) { - if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN)) - break; - udelay(1); - cnt++; - } - - if (cnt >= ULPI_IO_TIMEOUT_USEC) { - dev_err(otg->dev, "ulpi_write: timeout\n"); - return -ETIMEDOUT; - } - return 0; -} - -static struct otg_io_access_ops msm_otg_io_ops = { - .read = ulpi_read, - .write = ulpi_write, -}; - -static void ulpi_init(struct msm_otg *motg) -{ - struct msm_otg_platform_data *pdata = motg->pdata; - int *seq = pdata->phy_init_seq; - - if (!seq) - return; - - while (seq[0] >= 0) { - dev_vdbg(motg->otg.dev, "ulpi: write 0x%02x to 0x%02x\n", - seq[0], seq[1]); - ulpi_write(&motg->otg, seq[0], seq[1]); - seq += 2; - } -} - -static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) -{ - int ret; - - if (assert) { - ret = clk_reset(motg->clk, CLK_RESET_ASSERT); - if (ret) - dev_err(motg->otg.dev, "usb hs_clk assert failed\n"); - } else { - ret = clk_reset(motg->clk, CLK_RESET_DEASSERT); - if (ret) - dev_err(motg->otg.dev, "usb hs_clk deassert failed\n"); - } - return ret; -} - -static int msm_otg_phy_clk_reset(struct msm_otg *motg) -{ - int ret; - - ret = clk_reset(motg->phy_reset_clk, CLK_RESET_ASSERT); - if (ret) { - dev_err(motg->otg.dev, "usb phy clk assert failed\n"); - return ret; - } - usleep_range(10000, 12000); - ret = clk_reset(motg->phy_reset_clk, CLK_RESET_DEASSERT); - if (ret) - dev_err(motg->otg.dev, "usb phy clk deassert failed\n"); - return ret; -} - -static int msm_otg_phy_reset(struct msm_otg *motg) -{ - u32 val; - int ret; - int retries; - - ret = msm_otg_link_clk_reset(motg, 1); - if (ret) - return ret; - ret = msm_otg_phy_clk_reset(motg); - if (ret) - return ret; - ret = msm_otg_link_clk_reset(motg, 0); - if (ret) - return ret; - - val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK; - writel(val | PORTSC_PTS_ULPI, USB_PORTSC); - - for (retries = 3; retries > 0; retries--) { - ret = ulpi_write(&motg->otg, ULPI_FUNC_CTRL_SUSPENDM, - ULPI_CLR(ULPI_FUNC_CTRL)); - if (!ret) - break; - ret = msm_otg_phy_clk_reset(motg); - if (ret) - return ret; - } - if (!retries) - return -ETIMEDOUT; - - /* This reset calibrates the phy, if the above write succeeded */ - ret = msm_otg_phy_clk_reset(motg); - if (ret) - return ret; - - for (retries = 3; retries > 0; retries--) { - ret = ulpi_read(&motg->otg, ULPI_DEBUG); - if (ret != -ETIMEDOUT) - break; - ret = msm_otg_phy_clk_reset(motg); - if (ret) - return ret; - } - if (!retries) - return -ETIMEDOUT; - - dev_info(motg->otg.dev, "phy_reset: success\n"); - return 0; -} - -#define LINK_RESET_TIMEOUT_USEC (250 * 1000) -static int msm_otg_reset(struct otg_transceiver *otg) -{ - struct msm_otg *motg = container_of(otg, struct msm_otg, otg); - struct msm_otg_platform_data *pdata = motg->pdata; - int cnt = 0; - int ret; - u32 val = 0; - u32 ulpi_val = 0; - - ret = msm_otg_phy_reset(motg); - if (ret) { - dev_err(otg->dev, "phy_reset failed\n"); - return ret; - } - - ulpi_init(motg); - - writel(USBCMD_RESET, USB_USBCMD); - while (cnt < LINK_RESET_TIMEOUT_USEC) { - if (!(readl(USB_USBCMD) & USBCMD_RESET)) - break; - udelay(1); - cnt++; - } - if (cnt >= LINK_RESET_TIMEOUT_USEC) - return -ETIMEDOUT; - - /* select ULPI phy */ - writel(0x80000000, USB_PORTSC); - - msleep(100); - - writel(0x0, USB_AHBBURST); - writel(0x00, USB_AHBMODE); - - if (pdata->otg_control == OTG_PHY_CONTROL) { - val = readl(USB_OTGSC); - if (pdata->mode == USB_OTG) { - ulpi_val = ULPI_INT_IDGRD | ULPI_INT_SESS_VALID; - val |= OTGSC_IDIE | OTGSC_BSVIE; - } else if (pdata->mode == USB_PERIPHERAL) { - ulpi_val = ULPI_INT_SESS_VALID; - val |= OTGSC_BSVIE; - } - writel(val, USB_OTGSC); - ulpi_write(otg, ulpi_val, ULPI_USB_INT_EN_RISE); - ulpi_write(otg, ulpi_val, ULPI_USB_INT_EN_FALL); - } - - return 0; -} - -#define PHY_SUSPEND_TIMEOUT_USEC (500 * 1000) -#define PHY_RESUME_TIMEOUT_USEC (100 * 1000) - -#ifdef CONFIG_PM_SLEEP -static int msm_otg_suspend(struct msm_otg *motg) -{ - struct otg_transceiver *otg = &motg->otg; - struct usb_bus *bus = otg->host; - struct msm_otg_platform_data *pdata = motg->pdata; - int cnt = 0; - - if (atomic_read(&motg->in_lpm)) - return 0; - - disable_irq(motg->irq); - /* - * Interrupt Latch Register auto-clear feature is not present - * in all PHY versions. Latch register is clear on read type. - * Clear latch register to avoid spurious wakeup from - * low power mode (LPM). - */ - ulpi_read(otg, 0x14); - - /* - * PHY comparators are disabled when PHY enters into low power - * mode (LPM). Keep PHY comparators ON in LPM only when we expect - * VBUS/Id notifications from USB PHY. Otherwise turn off USB - * PHY comparators. This save significant amount of power. - */ - if (pdata->otg_control == OTG_PHY_CONTROL) - ulpi_write(otg, 0x01, 0x30); - - /* - * PLL is not turned off when PHY enters into low power mode (LPM). - * Disable PLL for maximum power savings. - */ - ulpi_write(otg, 0x08, 0x09); - - /* - * PHY may take some time or even fail to enter into low power - * mode (LPM). Hence poll for 500 msec and reset the PHY and link - * in failure case. - */ - writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC); - while (cnt < PHY_SUSPEND_TIMEOUT_USEC) { - if (readl(USB_PORTSC) & PORTSC_PHCD) - break; - udelay(1); - cnt++; - } - - if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) { - dev_err(otg->dev, "Unable to suspend PHY\n"); - msm_otg_reset(otg); - enable_irq(motg->irq); - return -ETIMEDOUT; - } - - /* - * PHY has capability to generate interrupt asynchronously in low - * power mode (LPM). This interrupt is level triggered. So USB IRQ - * line must be disabled till async interrupt enable bit is cleared - * in USBCMD register. Assert STP (ULPI interface STOP signal) to - * block data communication from PHY. - */ - writel(readl(USB_USBCMD) | ASYNC_INTR_CTRL | ULPI_STP_CTRL, USB_USBCMD); - - clk_disable(motg->pclk); - clk_disable(motg->clk); - if (motg->core_clk) - clk_disable(motg->core_clk); - - if (device_may_wakeup(otg->dev)) - enable_irq_wake(motg->irq); - if (bus) - clear_bit(HCD_FLAG_HW_ACCESSIBLE, &(bus_to_hcd(bus))->flags); - - atomic_set(&motg->in_lpm, 1); - enable_irq(motg->irq); - - dev_info(otg->dev, "USB in low power mode\n"); - - return 0; -} - -static int msm_otg_resume(struct msm_otg *motg) -{ - struct otg_transceiver *otg = &motg->otg; - struct usb_bus *bus = otg->host; - int cnt = 0; - unsigned temp; - - if (!atomic_read(&motg->in_lpm)) - return 0; - - clk_enable(motg->pclk); - clk_enable(motg->clk); - if (motg->core_clk) - clk_enable(motg->core_clk); - - temp = readl(USB_USBCMD); - temp &= ~ASYNC_INTR_CTRL; - temp &= ~ULPI_STP_CTRL; - writel(temp, USB_USBCMD); - - /* - * PHY comes out of low power mode (LPM) in case of wakeup - * from asynchronous interrupt. - */ - if (!(readl(USB_PORTSC) & PORTSC_PHCD)) - goto skip_phy_resume; - - writel(readl(USB_PORTSC) & ~PORTSC_PHCD, USB_PORTSC); - while (cnt < PHY_RESUME_TIMEOUT_USEC) { - if (!(readl(USB_PORTSC) & PORTSC_PHCD)) - break; - udelay(1); - cnt++; - } - - if (cnt >= PHY_RESUME_TIMEOUT_USEC) { - /* - * This is a fatal error. Reset the link and - * PHY. USB state can not be restored. Re-insertion - * of USB cable is the only way to get USB working. - */ - dev_err(otg->dev, "Unable to resume USB." - "Re-plugin the cable\n"); - msm_otg_reset(otg); - } - -skip_phy_resume: - if (device_may_wakeup(otg->dev)) - disable_irq_wake(motg->irq); - if (bus) - set_bit(HCD_FLAG_HW_ACCESSIBLE, &(bus_to_hcd(bus))->flags); - - if (motg->async_int) { - motg->async_int = 0; - pm_runtime_put(otg->dev); - enable_irq(motg->irq); - } - - atomic_set(&motg->in_lpm, 0); - - dev_info(otg->dev, "USB exited from low power mode\n"); - - return 0; -} -#endif - -static void msm_otg_start_host(struct otg_transceiver *otg, int on) -{ - struct msm_otg *motg = container_of(otg, struct msm_otg, otg); - struct msm_otg_platform_data *pdata = motg->pdata; - struct usb_hcd *hcd; - - if (!otg->host) - return; - - hcd = bus_to_hcd(otg->host); - - if (on) { - dev_dbg(otg->dev, "host on\n"); - - if (pdata->vbus_power) - pdata->vbus_power(1); - /* - * Some boards have a switch cotrolled by gpio - * to enable/disable internal HUB. Enable internal - * HUB before kicking the host. - */ - if (pdata->setup_gpio) - pdata->setup_gpio(OTG_STATE_A_HOST); -#ifdef CONFIG_USB - usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); -#endif - } else { - dev_dbg(otg->dev, "host off\n"); - -#ifdef CONFIG_USB - usb_remove_hcd(hcd); -#endif - if (pdata->setup_gpio) - pdata->setup_gpio(OTG_STATE_UNDEFINED); - if (pdata->vbus_power) - pdata->vbus_power(0); - } -} - -static int msm_otg_set_host(struct otg_transceiver *otg, struct usb_bus *host) -{ - struct msm_otg *motg = container_of(otg, struct msm_otg, otg); - struct usb_hcd *hcd; - - /* - * Fail host registration if this board can support - * only peripheral configuration. - */ - if (motg->pdata->mode == USB_PERIPHERAL) { - dev_info(otg->dev, "Host mode is not supported\n"); - return -ENODEV; - } - - if (!host) { - if (otg->state == OTG_STATE_A_HOST) { - pm_runtime_get_sync(otg->dev); - msm_otg_start_host(otg, 0); - otg->host = NULL; - otg->state = OTG_STATE_UNDEFINED; - schedule_work(&motg->sm_work); - } else { - otg->host = NULL; - } - - return 0; - } - - hcd = bus_to_hcd(host); - hcd->power_budget = motg->pdata->power_budget; - - otg->host = host; - dev_dbg(otg->dev, "host driver registered w/ tranceiver\n"); - - /* - * Kick the state machine work, if peripheral is not supported - * or peripheral is already registered with us. - */ - if (motg->pdata->mode == USB_HOST || otg->gadget) { - pm_runtime_get_sync(otg->dev); - schedule_work(&motg->sm_work); - } - - return 0; -} - -static void msm_otg_start_peripheral(struct otg_transceiver *otg, int on) -{ - struct msm_otg *motg = container_of(otg, struct msm_otg, otg); - struct msm_otg_platform_data *pdata = motg->pdata; - - if (!otg->gadget) - return; - - if (on) { - dev_dbg(otg->dev, "gadget on\n"); - /* - * Some boards have a switch cotrolled by gpio - * to enable/disable internal HUB. Disable internal - * HUB before kicking the gadget. - */ - if (pdata->setup_gpio) - pdata->setup_gpio(OTG_STATE_B_PERIPHERAL); - usb_gadget_vbus_connect(otg->gadget); - } else { - dev_dbg(otg->dev, "gadget off\n"); - usb_gadget_vbus_disconnect(otg->gadget); - if (pdata->setup_gpio) - pdata->setup_gpio(OTG_STATE_UNDEFINED); - } - -} - -static int msm_otg_set_peripheral(struct otg_transceiver *otg, - struct usb_gadget *gadget) -{ - struct msm_otg *motg = container_of(otg, struct msm_otg, otg); - - /* - * Fail peripheral registration if this board can support - * only host configuration. - */ - if (motg->pdata->mode == USB_HOST) { - dev_info(otg->dev, "Peripheral mode is not supported\n"); - return -ENODEV; - } - - if (!gadget) { - if (otg->state == OTG_STATE_B_PERIPHERAL) { - pm_runtime_get_sync(otg->dev); - msm_otg_start_peripheral(otg, 0); - otg->gadget = NULL; - otg->state = OTG_STATE_UNDEFINED; - schedule_work(&motg->sm_work); - } else { - otg->gadget = NULL; - } - - return 0; - } - otg->gadget = gadget; - dev_dbg(otg->dev, "peripheral driver registered w/ tranceiver\n"); - - /* - * Kick the state machine work, if host is not supported - * or host is already registered with us. - */ - if (motg->pdata->mode == USB_PERIPHERAL || otg->host) { - pm_runtime_get_sync(otg->dev); - schedule_work(&motg->sm_work); - } - - return 0; -} - -/* - * We support OTG, Peripheral only and Host only configurations. In case - * of OTG, mode switch (host-->peripheral/peripheral-->host) can happen - * via Id pin status or user request (debugfs). Id/BSV interrupts are not - * enabled when switch is controlled by user and default mode is supplied - * by board file, which can be changed by userspace later. - */ -static void msm_otg_init_sm(struct msm_otg *motg) -{ - struct msm_otg_platform_data *pdata = motg->pdata; - u32 otgsc = readl(USB_OTGSC); - - switch (pdata->mode) { - case USB_OTG: - if (pdata->otg_control == OTG_PHY_CONTROL) { - if (otgsc & OTGSC_ID) - set_bit(ID, &motg->inputs); - else - clear_bit(ID, &motg->inputs); - - if (otgsc & OTGSC_BSV) - set_bit(B_SESS_VLD, &motg->inputs); - else - clear_bit(B_SESS_VLD, &motg->inputs); - } else if (pdata->otg_control == OTG_USER_CONTROL) { - if (pdata->default_mode == USB_HOST) { - clear_bit(ID, &motg->inputs); - } else if (pdata->default_mode == USB_PERIPHERAL) { - set_bit(ID, &motg->inputs); - set_bit(B_SESS_VLD, &motg->inputs); - } else { - set_bit(ID, &motg->inputs); - clear_bit(B_SESS_VLD, &motg->inputs); - } - } - break; - case USB_HOST: - clear_bit(ID, &motg->inputs); - break; - case USB_PERIPHERAL: - set_bit(ID, &motg->inputs); - if (otgsc & OTGSC_BSV) - set_bit(B_SESS_VLD, &motg->inputs); - else - clear_bit(B_SESS_VLD, &motg->inputs); - break; - default: - break; - } -} - -static void msm_otg_sm_work(struct work_struct *w) -{ - struct msm_otg *motg = container_of(w, struct msm_otg, sm_work); - struct otg_transceiver *otg = &motg->otg; - - switch (otg->state) { - case OTG_STATE_UNDEFINED: - dev_dbg(otg->dev, "OTG_STATE_UNDEFINED state\n"); - msm_otg_reset(otg); - msm_otg_init_sm(motg); - otg->state = OTG_STATE_B_IDLE; - /* FALL THROUGH */ - case OTG_STATE_B_IDLE: - dev_dbg(otg->dev, "OTG_STATE_B_IDLE state\n"); - if (!test_bit(ID, &motg->inputs) && otg->host) { - /* disable BSV bit */ - writel(readl(USB_OTGSC) & ~OTGSC_BSVIE, USB_OTGSC); - msm_otg_start_host(otg, 1); - otg->state = OTG_STATE_A_HOST; - } else if (test_bit(B_SESS_VLD, &motg->inputs) && otg->gadget) { - msm_otg_start_peripheral(otg, 1); - otg->state = OTG_STATE_B_PERIPHERAL; - } - pm_runtime_put_sync(otg->dev); - break; - case OTG_STATE_B_PERIPHERAL: - dev_dbg(otg->dev, "OTG_STATE_B_PERIPHERAL state\n"); - if (!test_bit(B_SESS_VLD, &motg->inputs) || - !test_bit(ID, &motg->inputs)) { - msm_otg_start_peripheral(otg, 0); - otg->state = OTG_STATE_B_IDLE; - msm_otg_reset(otg); - schedule_work(w); - } - break; - case OTG_STATE_A_HOST: - dev_dbg(otg->dev, "OTG_STATE_A_HOST state\n"); - if (test_bit(ID, &motg->inputs)) { - msm_otg_start_host(otg, 0); - otg->state = OTG_STATE_B_IDLE; - msm_otg_reset(otg); - schedule_work(w); - } - break; - default: - break; - } -} - -static irqreturn_t msm_otg_irq(int irq, void *data) -{ - struct msm_otg *motg = data; - struct otg_transceiver *otg = &motg->otg; - u32 otgsc = 0; - - if (atomic_read(&motg->in_lpm)) { - disable_irq_nosync(irq); - motg->async_int = 1; - pm_runtime_get(otg->dev); - return IRQ_HANDLED; - } - - otgsc = readl(USB_OTGSC); - if (!(otgsc & (OTGSC_IDIS | OTGSC_BSVIS))) - return IRQ_NONE; - - if ((otgsc & OTGSC_IDIS) && (otgsc & OTGSC_IDIE)) { - if (otgsc & OTGSC_ID) - set_bit(ID, &motg->inputs); - else - clear_bit(ID, &motg->inputs); - dev_dbg(otg->dev, "ID set/clear\n"); - pm_runtime_get_noresume(otg->dev); - } else if ((otgsc & OTGSC_BSVIS) && (otgsc & OTGSC_BSVIE)) { - if (otgsc & OTGSC_BSV) - set_bit(B_SESS_VLD, &motg->inputs); - else - clear_bit(B_SESS_VLD, &motg->inputs); - dev_dbg(otg->dev, "BSV set/clear\n"); - pm_runtime_get_noresume(otg->dev); - } - - writel(otgsc, USB_OTGSC); - schedule_work(&motg->sm_work); - return IRQ_HANDLED; -} - -static int msm_otg_mode_show(struct seq_file *s, void *unused) -{ - struct msm_otg *motg = s->private; - struct otg_transceiver *otg = &motg->otg; - - switch (otg->state) { - case OTG_STATE_A_HOST: - seq_printf(s, "host\n"); - break; - case OTG_STATE_B_PERIPHERAL: - seq_printf(s, "peripheral\n"); - break; - default: - seq_printf(s, "none\n"); - break; - } - - return 0; -} - -static int msm_otg_mode_open(struct inode *inode, struct file *file) -{ - return single_open(file, msm_otg_mode_show, inode->i_private); -} - -static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, - size_t count, loff_t *ppos) -{ - struct seq_file *s = file->private_data; - struct msm_otg *motg = s->private; - char buf[16]; - struct otg_transceiver *otg = &motg->otg; - int status = count; - enum usb_mode_type req_mode; - - memset(buf, 0x00, sizeof(buf)); - - if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) { - status = -EFAULT; - goto out; - } - - if (!strncmp(buf, "host", 4)) { - req_mode = USB_HOST; - } else if (!strncmp(buf, "peripheral", 10)) { - req_mode = USB_PERIPHERAL; - } else if (!strncmp(buf, "none", 4)) { - req_mode = USB_NONE; - } else { - status = -EINVAL; - goto out; - } - - switch (req_mode) { - case USB_NONE: - switch (otg->state) { - case OTG_STATE_A_HOST: - case OTG_STATE_B_PERIPHERAL: - set_bit(ID, &motg->inputs); - clear_bit(B_SESS_VLD, &motg->inputs); - break; - default: - goto out; - } - break; - case USB_PERIPHERAL: - switch (otg->state) { - case OTG_STATE_B_IDLE: - case OTG_STATE_A_HOST: - set_bit(ID, &motg->inputs); - set_bit(B_SESS_VLD, &motg->inputs); - break; - default: - goto out; - } - break; - case USB_HOST: - switch (otg->state) { - case OTG_STATE_B_IDLE: - case OTG_STATE_B_PERIPHERAL: - clear_bit(ID, &motg->inputs); - break; - default: - goto out; - } - break; - default: - goto out; - } - - pm_runtime_get_sync(otg->dev); - schedule_work(&motg->sm_work); -out: - return status; -} - -const struct file_operations msm_otg_mode_fops = { - .open = msm_otg_mode_open, - .read = seq_read, - .write = msm_otg_mode_write, - .llseek = seq_lseek, - .release = single_release, -}; - -static struct dentry *msm_otg_dbg_root; -static struct dentry *msm_otg_dbg_mode; - -static int msm_otg_debugfs_init(struct msm_otg *motg) -{ - msm_otg_dbg_root = debugfs_create_dir("msm_otg", NULL); - - if (!msm_otg_dbg_root || IS_ERR(msm_otg_dbg_root)) - return -ENODEV; - - msm_otg_dbg_mode = debugfs_create_file("mode", S_IRUGO | S_IWUSR, - msm_otg_dbg_root, motg, &msm_otg_mode_fops); - if (!msm_otg_dbg_mode) { - debugfs_remove(msm_otg_dbg_root); - msm_otg_dbg_root = NULL; - return -ENODEV; - } - - return 0; -} - -static void msm_otg_debugfs_cleanup(void) -{ - debugfs_remove(msm_otg_dbg_mode); - debugfs_remove(msm_otg_dbg_root); -} - -static int __init msm_otg_probe(struct platform_device *pdev) -{ - int ret = 0; - struct resource *res; - struct msm_otg *motg; - struct otg_transceiver *otg; - - dev_info(&pdev->dev, "msm_otg probe\n"); - if (!pdev->dev.platform_data) { - dev_err(&pdev->dev, "No platform data given. Bailing out\n"); - return -ENODEV; - } - - motg = kzalloc(sizeof(struct msm_otg), GFP_KERNEL); - if (!motg) { - dev_err(&pdev->dev, "unable to allocate msm_otg\n"); - return -ENOMEM; - } - - motg->pdata = pdev->dev.platform_data; - otg = &motg->otg; - otg->dev = &pdev->dev; - - motg->phy_reset_clk = clk_get(&pdev->dev, "usb_phy_clk"); - if (IS_ERR(motg->phy_reset_clk)) { - dev_err(&pdev->dev, "failed to get usb_phy_clk\n"); - ret = PTR_ERR(motg->phy_reset_clk); - goto free_motg; - } - - motg->clk = clk_get(&pdev->dev, "usb_hs_clk"); - if (IS_ERR(motg->clk)) { - dev_err(&pdev->dev, "failed to get usb_hs_clk\n"); - ret = PTR_ERR(motg->clk); - goto put_phy_reset_clk; - } - - motg->pclk = clk_get(&pdev->dev, "usb_hs_pclk"); - if (IS_ERR(motg->pclk)) { - dev_err(&pdev->dev, "failed to get usb_hs_pclk\n"); - ret = PTR_ERR(motg->pclk); - goto put_clk; - } - - /* - * USB core clock is not present on all MSM chips. This - * clock is introduced to remove the dependency on AXI - * bus frequency. - */ - motg->core_clk = clk_get(&pdev->dev, "usb_hs_core_clk"); - if (IS_ERR(motg->core_clk)) - motg->core_clk = NULL; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "failed to get platform resource mem\n"); - ret = -ENODEV; - goto put_core_clk; - } - - motg->regs = ioremap(res->start, resource_size(res)); - if (!motg->regs) { - dev_err(&pdev->dev, "ioremap failed\n"); - ret = -ENOMEM; - goto put_core_clk; - } - dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs); - - motg->irq = platform_get_irq(pdev, 0); - if (!motg->irq) { - dev_err(&pdev->dev, "platform_get_irq failed\n"); - ret = -ENODEV; - goto free_regs; - } - - clk_enable(motg->clk); - clk_enable(motg->pclk); - if (motg->core_clk) - clk_enable(motg->core_clk); - - writel(0, USB_USBINTR); - writel(0, USB_OTGSC); - - INIT_WORK(&motg->sm_work, msm_otg_sm_work); - ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED, - "msm_otg", motg); - if (ret) { - dev_err(&pdev->dev, "request irq failed\n"); - goto disable_clks; - } - - otg->init = msm_otg_reset; - otg->set_host = msm_otg_set_host; - otg->set_peripheral = msm_otg_set_peripheral; - - otg->io_ops = &msm_otg_io_ops; - - ret = otg_set_transceiver(&motg->otg); - if (ret) { - dev_err(&pdev->dev, "otg_set_transceiver failed\n"); - goto free_irq; - } - - platform_set_drvdata(pdev, motg); - device_init_wakeup(&pdev->dev, 1); - - if (motg->pdata->mode == USB_OTG && - motg->pdata->otg_control == OTG_USER_CONTROL) { - ret = msm_otg_debugfs_init(motg); - if (ret) - dev_dbg(&pdev->dev, "mode debugfs file is" - "not available\n"); - } - - pm_runtime_set_active(&pdev->dev); - pm_runtime_enable(&pdev->dev); - - return 0; -free_irq: - free_irq(motg->irq, motg); -disable_clks: - clk_disable(motg->pclk); - clk_disable(motg->clk); -free_regs: - iounmap(motg->regs); -put_core_clk: - if (motg->core_clk) - clk_put(motg->core_clk); - clk_put(motg->pclk); -put_clk: - clk_put(motg->clk); -put_phy_reset_clk: - clk_put(motg->phy_reset_clk); -free_motg: - kfree(motg); - return ret; -} - -static int __devexit msm_otg_remove(struct platform_device *pdev) -{ - struct msm_otg *motg = platform_get_drvdata(pdev); - struct otg_transceiver *otg = &motg->otg; - int cnt = 0; - - if (otg->host || otg->gadget) - return -EBUSY; - - msm_otg_debugfs_cleanup(); - cancel_work_sync(&motg->sm_work); - - pm_runtime_resume(&pdev->dev); - - device_init_wakeup(&pdev->dev, 0); - pm_runtime_disable(&pdev->dev); - - otg_set_transceiver(NULL); - free_irq(motg->irq, motg); - - /* - * Put PHY in low power mode. - */ - ulpi_read(otg, 0x14); - ulpi_write(otg, 0x08, 0x09); - - writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC); - while (cnt < PHY_SUSPEND_TIMEOUT_USEC) { - if (readl(USB_PORTSC) & PORTSC_PHCD) - break; - udelay(1); - cnt++; - } - if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) - dev_err(otg->dev, "Unable to suspend PHY\n"); - - clk_disable(motg->pclk); - clk_disable(motg->clk); - if (motg->core_clk) - clk_disable(motg->core_clk); - - iounmap(motg->regs); - pm_runtime_set_suspended(&pdev->dev); - - clk_put(motg->phy_reset_clk); - clk_put(motg->pclk); - clk_put(motg->clk); - if (motg->core_clk) - clk_put(motg->core_clk); - - kfree(motg); - - return 0; -} - -#ifdef CONFIG_PM_RUNTIME -static int msm_otg_runtime_idle(struct device *dev) -{ - struct msm_otg *motg = dev_get_drvdata(dev); - struct otg_transceiver *otg = &motg->otg; - - dev_dbg(dev, "OTG runtime idle\n"); - - /* - * It is observed some times that a spurious interrupt - * comes when PHY is put into LPM immediately after PHY reset. - * This 1 sec delay also prevents entering into LPM immediately - * after asynchronous interrupt. - */ - if (otg->state != OTG_STATE_UNDEFINED) - pm_schedule_suspend(dev, 1000); - - return -EAGAIN; -} - -static int msm_otg_runtime_suspend(struct device *dev) -{ - struct msm_otg *motg = dev_get_drvdata(dev); - - dev_dbg(dev, "OTG runtime suspend\n"); - return msm_otg_suspend(motg); -} - -static int msm_otg_runtime_resume(struct device *dev) -{ - struct msm_otg *motg = dev_get_drvdata(dev); - - dev_dbg(dev, "OTG runtime resume\n"); - return msm_otg_resume(motg); -} -#endif - -#ifdef CONFIG_PM_SLEEP -static int msm_otg_pm_suspend(struct device *dev) -{ - struct msm_otg *motg = dev_get_drvdata(dev); - - dev_dbg(dev, "OTG PM suspend\n"); - return msm_otg_suspend(motg); -} - -static int msm_otg_pm_resume(struct device *dev) -{ - struct msm_otg *motg = dev_get_drvdata(dev); - int ret; - - dev_dbg(dev, "OTG PM resume\n"); - - ret = msm_otg_resume(motg); - if (ret) - return ret; - - /* - * Runtime PM Documentation recommends bringing the - * device to full powered state upon resume. - */ - pm_runtime_disable(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - - return 0; -} -#endif - -#ifdef CONFIG_PM -static const struct dev_pm_ops msm_otg_dev_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(msm_otg_pm_suspend, msm_otg_pm_resume) - SET_RUNTIME_PM_OPS(msm_otg_runtime_suspend, msm_otg_runtime_resume, - msm_otg_runtime_idle) -}; -#endif - -static struct platform_driver msm_otg_driver = { - .remove = __devexit_p(msm_otg_remove), - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, -#ifdef CONFIG_PM - .pm = &msm_otg_dev_pm_ops, -#endif - }, -}; - -static int __init msm_otg_init(void) -{ - return platform_driver_probe(&msm_otg_driver, msm_otg_probe); -} - -static void __exit msm_otg_exit(void) -{ - platform_driver_unregister(&msm_otg_driver); -} - -module_init(msm_otg_init); -module_exit(msm_otg_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("MSM USB transceiver driver"); diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c new file mode 100644 index 000000000000..296598628b85 --- /dev/null +++ b/drivers/usb/otg/msm_otg.c @@ -0,0 +1,1124 @@ +/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MSM_USB_BASE (motg->regs) +#define DRIVER_NAME "msm_otg" + +#define ULPI_IO_TIMEOUT_USEC (10 * 1000) +static int ulpi_read(struct otg_transceiver *otg, u32 reg) +{ + struct msm_otg *motg = container_of(otg, struct msm_otg, otg); + int cnt = 0; + + /* initiate read operation */ + writel(ULPI_RUN | ULPI_READ | ULPI_ADDR(reg), + USB_ULPI_VIEWPORT); + + /* wait for completion */ + while (cnt < ULPI_IO_TIMEOUT_USEC) { + if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN)) + break; + udelay(1); + cnt++; + } + + if (cnt >= ULPI_IO_TIMEOUT_USEC) { + dev_err(otg->dev, "ulpi_read: timeout %08x\n", + readl(USB_ULPI_VIEWPORT)); + return -ETIMEDOUT; + } + return ULPI_DATA_READ(readl(USB_ULPI_VIEWPORT)); +} + +static int ulpi_write(struct otg_transceiver *otg, u32 val, u32 reg) +{ + struct msm_otg *motg = container_of(otg, struct msm_otg, otg); + int cnt = 0; + + /* initiate write operation */ + writel(ULPI_RUN | ULPI_WRITE | + ULPI_ADDR(reg) | ULPI_DATA(val), + USB_ULPI_VIEWPORT); + + /* wait for completion */ + while (cnt < ULPI_IO_TIMEOUT_USEC) { + if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN)) + break; + udelay(1); + cnt++; + } + + if (cnt >= ULPI_IO_TIMEOUT_USEC) { + dev_err(otg->dev, "ulpi_write: timeout\n"); + return -ETIMEDOUT; + } + return 0; +} + +static struct otg_io_access_ops msm_otg_io_ops = { + .read = ulpi_read, + .write = ulpi_write, +}; + +static void ulpi_init(struct msm_otg *motg) +{ + struct msm_otg_platform_data *pdata = motg->pdata; + int *seq = pdata->phy_init_seq; + + if (!seq) + return; + + while (seq[0] >= 0) { + dev_vdbg(motg->otg.dev, "ulpi: write 0x%02x to 0x%02x\n", + seq[0], seq[1]); + ulpi_write(&motg->otg, seq[0], seq[1]); + seq += 2; + } +} + +static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) +{ + int ret; + + if (assert) { + ret = clk_reset(motg->clk, CLK_RESET_ASSERT); + if (ret) + dev_err(motg->otg.dev, "usb hs_clk assert failed\n"); + } else { + ret = clk_reset(motg->clk, CLK_RESET_DEASSERT); + if (ret) + dev_err(motg->otg.dev, "usb hs_clk deassert failed\n"); + } + return ret; +} + +static int msm_otg_phy_clk_reset(struct msm_otg *motg) +{ + int ret; + + ret = clk_reset(motg->phy_reset_clk, CLK_RESET_ASSERT); + if (ret) { + dev_err(motg->otg.dev, "usb phy clk assert failed\n"); + return ret; + } + usleep_range(10000, 12000); + ret = clk_reset(motg->phy_reset_clk, CLK_RESET_DEASSERT); + if (ret) + dev_err(motg->otg.dev, "usb phy clk deassert failed\n"); + return ret; +} + +static int msm_otg_phy_reset(struct msm_otg *motg) +{ + u32 val; + int ret; + int retries; + + ret = msm_otg_link_clk_reset(motg, 1); + if (ret) + return ret; + ret = msm_otg_phy_clk_reset(motg); + if (ret) + return ret; + ret = msm_otg_link_clk_reset(motg, 0); + if (ret) + return ret; + + val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK; + writel(val | PORTSC_PTS_ULPI, USB_PORTSC); + + for (retries = 3; retries > 0; retries--) { + ret = ulpi_write(&motg->otg, ULPI_FUNC_CTRL_SUSPENDM, + ULPI_CLR(ULPI_FUNC_CTRL)); + if (!ret) + break; + ret = msm_otg_phy_clk_reset(motg); + if (ret) + return ret; + } + if (!retries) + return -ETIMEDOUT; + + /* This reset calibrates the phy, if the above write succeeded */ + ret = msm_otg_phy_clk_reset(motg); + if (ret) + return ret; + + for (retries = 3; retries > 0; retries--) { + ret = ulpi_read(&motg->otg, ULPI_DEBUG); + if (ret != -ETIMEDOUT) + break; + ret = msm_otg_phy_clk_reset(motg); + if (ret) + return ret; + } + if (!retries) + return -ETIMEDOUT; + + dev_info(motg->otg.dev, "phy_reset: success\n"); + return 0; +} + +#define LINK_RESET_TIMEOUT_USEC (250 * 1000) +static int msm_otg_reset(struct otg_transceiver *otg) +{ + struct msm_otg *motg = container_of(otg, struct msm_otg, otg); + struct msm_otg_platform_data *pdata = motg->pdata; + int cnt = 0; + int ret; + u32 val = 0; + u32 ulpi_val = 0; + + ret = msm_otg_phy_reset(motg); + if (ret) { + dev_err(otg->dev, "phy_reset failed\n"); + return ret; + } + + ulpi_init(motg); + + writel(USBCMD_RESET, USB_USBCMD); + while (cnt < LINK_RESET_TIMEOUT_USEC) { + if (!(readl(USB_USBCMD) & USBCMD_RESET)) + break; + udelay(1); + cnt++; + } + if (cnt >= LINK_RESET_TIMEOUT_USEC) + return -ETIMEDOUT; + + /* select ULPI phy */ + writel(0x80000000, USB_PORTSC); + + msleep(100); + + writel(0x0, USB_AHBBURST); + writel(0x00, USB_AHBMODE); + + if (pdata->otg_control == OTG_PHY_CONTROL) { + val = readl(USB_OTGSC); + if (pdata->mode == USB_OTG) { + ulpi_val = ULPI_INT_IDGRD | ULPI_INT_SESS_VALID; + val |= OTGSC_IDIE | OTGSC_BSVIE; + } else if (pdata->mode == USB_PERIPHERAL) { + ulpi_val = ULPI_INT_SESS_VALID; + val |= OTGSC_BSVIE; + } + writel(val, USB_OTGSC); + ulpi_write(otg, ulpi_val, ULPI_USB_INT_EN_RISE); + ulpi_write(otg, ulpi_val, ULPI_USB_INT_EN_FALL); + } + + return 0; +} + +#define PHY_SUSPEND_TIMEOUT_USEC (500 * 1000) +#define PHY_RESUME_TIMEOUT_USEC (100 * 1000) + +#ifdef CONFIG_PM_SLEEP +static int msm_otg_suspend(struct msm_otg *motg) +{ + struct otg_transceiver *otg = &motg->otg; + struct usb_bus *bus = otg->host; + struct msm_otg_platform_data *pdata = motg->pdata; + int cnt = 0; + + if (atomic_read(&motg->in_lpm)) + return 0; + + disable_irq(motg->irq); + /* + * Interrupt Latch Register auto-clear feature is not present + * in all PHY versions. Latch register is clear on read type. + * Clear latch register to avoid spurious wakeup from + * low power mode (LPM). + */ + ulpi_read(otg, 0x14); + + /* + * PHY comparators are disabled when PHY enters into low power + * mode (LPM). Keep PHY comparators ON in LPM only when we expect + * VBUS/Id notifications from USB PHY. Otherwise turn off USB + * PHY comparators. This save significant amount of power. + */ + if (pdata->otg_control == OTG_PHY_CONTROL) + ulpi_write(otg, 0x01, 0x30); + + /* + * PLL is not turned off when PHY enters into low power mode (LPM). + * Disable PLL for maximum power savings. + */ + ulpi_write(otg, 0x08, 0x09); + + /* + * PHY may take some time or even fail to enter into low power + * mode (LPM). Hence poll for 500 msec and reset the PHY and link + * in failure case. + */ + writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC); + while (cnt < PHY_SUSPEND_TIMEOUT_USEC) { + if (readl(USB_PORTSC) & PORTSC_PHCD) + break; + udelay(1); + cnt++; + } + + if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) { + dev_err(otg->dev, "Unable to suspend PHY\n"); + msm_otg_reset(otg); + enable_irq(motg->irq); + return -ETIMEDOUT; + } + + /* + * PHY has capability to generate interrupt asynchronously in low + * power mode (LPM). This interrupt is level triggered. So USB IRQ + * line must be disabled till async interrupt enable bit is cleared + * in USBCMD register. Assert STP (ULPI interface STOP signal) to + * block data communication from PHY. + */ + writel(readl(USB_USBCMD) | ASYNC_INTR_CTRL | ULPI_STP_CTRL, USB_USBCMD); + + clk_disable(motg->pclk); + clk_disable(motg->clk); + if (motg->core_clk) + clk_disable(motg->core_clk); + + if (device_may_wakeup(otg->dev)) + enable_irq_wake(motg->irq); + if (bus) + clear_bit(HCD_FLAG_HW_ACCESSIBLE, &(bus_to_hcd(bus))->flags); + + atomic_set(&motg->in_lpm, 1); + enable_irq(motg->irq); + + dev_info(otg->dev, "USB in low power mode\n"); + + return 0; +} + +static int msm_otg_resume(struct msm_otg *motg) +{ + struct otg_transceiver *otg = &motg->otg; + struct usb_bus *bus = otg->host; + int cnt = 0; + unsigned temp; + + if (!atomic_read(&motg->in_lpm)) + return 0; + + clk_enable(motg->pclk); + clk_enable(motg->clk); + if (motg->core_clk) + clk_enable(motg->core_clk); + + temp = readl(USB_USBCMD); + temp &= ~ASYNC_INTR_CTRL; + temp &= ~ULPI_STP_CTRL; + writel(temp, USB_USBCMD); + + /* + * PHY comes out of low power mode (LPM) in case of wakeup + * from asynchronous interrupt. + */ + if (!(readl(USB_PORTSC) & PORTSC_PHCD)) + goto skip_phy_resume; + + writel(readl(USB_PORTSC) & ~PORTSC_PHCD, USB_PORTSC); + while (cnt < PHY_RESUME_TIMEOUT_USEC) { + if (!(readl(USB_PORTSC) & PORTSC_PHCD)) + break; + udelay(1); + cnt++; + } + + if (cnt >= PHY_RESUME_TIMEOUT_USEC) { + /* + * This is a fatal error. Reset the link and + * PHY. USB state can not be restored. Re-insertion + * of USB cable is the only way to get USB working. + */ + dev_err(otg->dev, "Unable to resume USB." + "Re-plugin the cable\n"); + msm_otg_reset(otg); + } + +skip_phy_resume: + if (device_may_wakeup(otg->dev)) + disable_irq_wake(motg->irq); + if (bus) + set_bit(HCD_FLAG_HW_ACCESSIBLE, &(bus_to_hcd(bus))->flags); + + if (motg->async_int) { + motg->async_int = 0; + pm_runtime_put(otg->dev); + enable_irq(motg->irq); + } + + atomic_set(&motg->in_lpm, 0); + + dev_info(otg->dev, "USB exited from low power mode\n"); + + return 0; +} +#endif + +static void msm_otg_start_host(struct otg_transceiver *otg, int on) +{ + struct msm_otg *motg = container_of(otg, struct msm_otg, otg); + struct msm_otg_platform_data *pdata = motg->pdata; + struct usb_hcd *hcd; + + if (!otg->host) + return; + + hcd = bus_to_hcd(otg->host); + + if (on) { + dev_dbg(otg->dev, "host on\n"); + + if (pdata->vbus_power) + pdata->vbus_power(1); + /* + * Some boards have a switch cotrolled by gpio + * to enable/disable internal HUB. Enable internal + * HUB before kicking the host. + */ + if (pdata->setup_gpio) + pdata->setup_gpio(OTG_STATE_A_HOST); +#ifdef CONFIG_USB + usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); +#endif + } else { + dev_dbg(otg->dev, "host off\n"); + +#ifdef CONFIG_USB + usb_remove_hcd(hcd); +#endif + if (pdata->setup_gpio) + pdata->setup_gpio(OTG_STATE_UNDEFINED); + if (pdata->vbus_power) + pdata->vbus_power(0); + } +} + +static int msm_otg_set_host(struct otg_transceiver *otg, struct usb_bus *host) +{ + struct msm_otg *motg = container_of(otg, struct msm_otg, otg); + struct usb_hcd *hcd; + + /* + * Fail host registration if this board can support + * only peripheral configuration. + */ + if (motg->pdata->mode == USB_PERIPHERAL) { + dev_info(otg->dev, "Host mode is not supported\n"); + return -ENODEV; + } + + if (!host) { + if (otg->state == OTG_STATE_A_HOST) { + pm_runtime_get_sync(otg->dev); + msm_otg_start_host(otg, 0); + otg->host = NULL; + otg->state = OTG_STATE_UNDEFINED; + schedule_work(&motg->sm_work); + } else { + otg->host = NULL; + } + + return 0; + } + + hcd = bus_to_hcd(host); + hcd->power_budget = motg->pdata->power_budget; + + otg->host = host; + dev_dbg(otg->dev, "host driver registered w/ tranceiver\n"); + + /* + * Kick the state machine work, if peripheral is not supported + * or peripheral is already registered with us. + */ + if (motg->pdata->mode == USB_HOST || otg->gadget) { + pm_runtime_get_sync(otg->dev); + schedule_work(&motg->sm_work); + } + + return 0; +} + +static void msm_otg_start_peripheral(struct otg_transceiver *otg, int on) +{ + struct msm_otg *motg = container_of(otg, struct msm_otg, otg); + struct msm_otg_platform_data *pdata = motg->pdata; + + if (!otg->gadget) + return; + + if (on) { + dev_dbg(otg->dev, "gadget on\n"); + /* + * Some boards have a switch cotrolled by gpio + * to enable/disable internal HUB. Disable internal + * HUB before kicking the gadget. + */ + if (pdata->setup_gpio) + pdata->setup_gpio(OTG_STATE_B_PERIPHERAL); + usb_gadget_vbus_connect(otg->gadget); + } else { + dev_dbg(otg->dev, "gadget off\n"); + usb_gadget_vbus_disconnect(otg->gadget); + if (pdata->setup_gpio) + pdata->setup_gpio(OTG_STATE_UNDEFINED); + } + +} + +static int msm_otg_set_peripheral(struct otg_transceiver *otg, + struct usb_gadget *gadget) +{ + struct msm_otg *motg = container_of(otg, struct msm_otg, otg); + + /* + * Fail peripheral registration if this board can support + * only host configuration. + */ + if (motg->pdata->mode == USB_HOST) { + dev_info(otg->dev, "Peripheral mode is not supported\n"); + return -ENODEV; + } + + if (!gadget) { + if (otg->state == OTG_STATE_B_PERIPHERAL) { + pm_runtime_get_sync(otg->dev); + msm_otg_start_peripheral(otg, 0); + otg->gadget = NULL; + otg->state = OTG_STATE_UNDEFINED; + schedule_work(&motg->sm_work); + } else { + otg->gadget = NULL; + } + + return 0; + } + otg->gadget = gadget; + dev_dbg(otg->dev, "peripheral driver registered w/ tranceiver\n"); + + /* + * Kick the state machine work, if host is not supported + * or host is already registered with us. + */ + if (motg->pdata->mode == USB_PERIPHERAL || otg->host) { + pm_runtime_get_sync(otg->dev); + schedule_work(&motg->sm_work); + } + + return 0; +} + +/* + * We support OTG, Peripheral only and Host only configurations. In case + * of OTG, mode switch (host-->peripheral/peripheral-->host) can happen + * via Id pin status or user request (debugfs). Id/BSV interrupts are not + * enabled when switch is controlled by user and default mode is supplied + * by board file, which can be changed by userspace later. + */ +static void msm_otg_init_sm(struct msm_otg *motg) +{ + struct msm_otg_platform_data *pdata = motg->pdata; + u32 otgsc = readl(USB_OTGSC); + + switch (pdata->mode) { + case USB_OTG: + if (pdata->otg_control == OTG_PHY_CONTROL) { + if (otgsc & OTGSC_ID) + set_bit(ID, &motg->inputs); + else + clear_bit(ID, &motg->inputs); + + if (otgsc & OTGSC_BSV) + set_bit(B_SESS_VLD, &motg->inputs); + else + clear_bit(B_SESS_VLD, &motg->inputs); + } else if (pdata->otg_control == OTG_USER_CONTROL) { + if (pdata->default_mode == USB_HOST) { + clear_bit(ID, &motg->inputs); + } else if (pdata->default_mode == USB_PERIPHERAL) { + set_bit(ID, &motg->inputs); + set_bit(B_SESS_VLD, &motg->inputs); + } else { + set_bit(ID, &motg->inputs); + clear_bit(B_SESS_VLD, &motg->inputs); + } + } + break; + case USB_HOST: + clear_bit(ID, &motg->inputs); + break; + case USB_PERIPHERAL: + set_bit(ID, &motg->inputs); + if (otgsc & OTGSC_BSV) + set_bit(B_SESS_VLD, &motg->inputs); + else + clear_bit(B_SESS_VLD, &motg->inputs); + break; + default: + break; + } +} + +static void msm_otg_sm_work(struct work_struct *w) +{ + struct msm_otg *motg = container_of(w, struct msm_otg, sm_work); + struct otg_transceiver *otg = &motg->otg; + + switch (otg->state) { + case OTG_STATE_UNDEFINED: + dev_dbg(otg->dev, "OTG_STATE_UNDEFINED state\n"); + msm_otg_reset(otg); + msm_otg_init_sm(motg); + otg->state = OTG_STATE_B_IDLE; + /* FALL THROUGH */ + case OTG_STATE_B_IDLE: + dev_dbg(otg->dev, "OTG_STATE_B_IDLE state\n"); + if (!test_bit(ID, &motg->inputs) && otg->host) { + /* disable BSV bit */ + writel(readl(USB_OTGSC) & ~OTGSC_BSVIE, USB_OTGSC); + msm_otg_start_host(otg, 1); + otg->state = OTG_STATE_A_HOST; + } else if (test_bit(B_SESS_VLD, &motg->inputs) && otg->gadget) { + msm_otg_start_peripheral(otg, 1); + otg->state = OTG_STATE_B_PERIPHERAL; + } + pm_runtime_put_sync(otg->dev); + break; + case OTG_STATE_B_PERIPHERAL: + dev_dbg(otg->dev, "OTG_STATE_B_PERIPHERAL state\n"); + if (!test_bit(B_SESS_VLD, &motg->inputs) || + !test_bit(ID, &motg->inputs)) { + msm_otg_start_peripheral(otg, 0); + otg->state = OTG_STATE_B_IDLE; + msm_otg_reset(otg); + schedule_work(w); + } + break; + case OTG_STATE_A_HOST: + dev_dbg(otg->dev, "OTG_STATE_A_HOST state\n"); + if (test_bit(ID, &motg->inputs)) { + msm_otg_start_host(otg, 0); + otg->state = OTG_STATE_B_IDLE; + msm_otg_reset(otg); + schedule_work(w); + } + break; + default: + break; + } +} + +static irqreturn_t msm_otg_irq(int irq, void *data) +{ + struct msm_otg *motg = data; + struct otg_transceiver *otg = &motg->otg; + u32 otgsc = 0; + + if (atomic_read(&motg->in_lpm)) { + disable_irq_nosync(irq); + motg->async_int = 1; + pm_runtime_get(otg->dev); + return IRQ_HANDLED; + } + + otgsc = readl(USB_OTGSC); + if (!(otgsc & (OTGSC_IDIS | OTGSC_BSVIS))) + return IRQ_NONE; + + if ((otgsc & OTGSC_IDIS) && (otgsc & OTGSC_IDIE)) { + if (otgsc & OTGSC_ID) + set_bit(ID, &motg->inputs); + else + clear_bit(ID, &motg->inputs); + dev_dbg(otg->dev, "ID set/clear\n"); + pm_runtime_get_noresume(otg->dev); + } else if ((otgsc & OTGSC_BSVIS) && (otgsc & OTGSC_BSVIE)) { + if (otgsc & OTGSC_BSV) + set_bit(B_SESS_VLD, &motg->inputs); + else + clear_bit(B_SESS_VLD, &motg->inputs); + dev_dbg(otg->dev, "BSV set/clear\n"); + pm_runtime_get_noresume(otg->dev); + } + + writel(otgsc, USB_OTGSC); + schedule_work(&motg->sm_work); + return IRQ_HANDLED; +} + +static int msm_otg_mode_show(struct seq_file *s, void *unused) +{ + struct msm_otg *motg = s->private; + struct otg_transceiver *otg = &motg->otg; + + switch (otg->state) { + case OTG_STATE_A_HOST: + seq_printf(s, "host\n"); + break; + case OTG_STATE_B_PERIPHERAL: + seq_printf(s, "peripheral\n"); + break; + default: + seq_printf(s, "none\n"); + break; + } + + return 0; +} + +static int msm_otg_mode_open(struct inode *inode, struct file *file) +{ + return single_open(file, msm_otg_mode_show, inode->i_private); +} + +static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + struct msm_otg *motg = s->private; + char buf[16]; + struct otg_transceiver *otg = &motg->otg; + int status = count; + enum usb_mode_type req_mode; + + memset(buf, 0x00, sizeof(buf)); + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) { + status = -EFAULT; + goto out; + } + + if (!strncmp(buf, "host", 4)) { + req_mode = USB_HOST; + } else if (!strncmp(buf, "peripheral", 10)) { + req_mode = USB_PERIPHERAL; + } else if (!strncmp(buf, "none", 4)) { + req_mode = USB_NONE; + } else { + status = -EINVAL; + goto out; + } + + switch (req_mode) { + case USB_NONE: + switch (otg->state) { + case OTG_STATE_A_HOST: + case OTG_STATE_B_PERIPHERAL: + set_bit(ID, &motg->inputs); + clear_bit(B_SESS_VLD, &motg->inputs); + break; + default: + goto out; + } + break; + case USB_PERIPHERAL: + switch (otg->state) { + case OTG_STATE_B_IDLE: + case OTG_STATE_A_HOST: + set_bit(ID, &motg->inputs); + set_bit(B_SESS_VLD, &motg->inputs); + break; + default: + goto out; + } + break; + case USB_HOST: + switch (otg->state) { + case OTG_STATE_B_IDLE: + case OTG_STATE_B_PERIPHERAL: + clear_bit(ID, &motg->inputs); + break; + default: + goto out; + } + break; + default: + goto out; + } + + pm_runtime_get_sync(otg->dev); + schedule_work(&motg->sm_work); +out: + return status; +} + +const struct file_operations msm_otg_mode_fops = { + .open = msm_otg_mode_open, + .read = seq_read, + .write = msm_otg_mode_write, + .llseek = seq_lseek, + .release = single_release, +}; + +static struct dentry *msm_otg_dbg_root; +static struct dentry *msm_otg_dbg_mode; + +static int msm_otg_debugfs_init(struct msm_otg *motg) +{ + msm_otg_dbg_root = debugfs_create_dir("msm_otg", NULL); + + if (!msm_otg_dbg_root || IS_ERR(msm_otg_dbg_root)) + return -ENODEV; + + msm_otg_dbg_mode = debugfs_create_file("mode", S_IRUGO | S_IWUSR, + msm_otg_dbg_root, motg, &msm_otg_mode_fops); + if (!msm_otg_dbg_mode) { + debugfs_remove(msm_otg_dbg_root); + msm_otg_dbg_root = NULL; + return -ENODEV; + } + + return 0; +} + +static void msm_otg_debugfs_cleanup(void) +{ + debugfs_remove(msm_otg_dbg_mode); + debugfs_remove(msm_otg_dbg_root); +} + +static int __init msm_otg_probe(struct platform_device *pdev) +{ + int ret = 0; + struct resource *res; + struct msm_otg *motg; + struct otg_transceiver *otg; + + dev_info(&pdev->dev, "msm_otg probe\n"); + if (!pdev->dev.platform_data) { + dev_err(&pdev->dev, "No platform data given. Bailing out\n"); + return -ENODEV; + } + + motg = kzalloc(sizeof(struct msm_otg), GFP_KERNEL); + if (!motg) { + dev_err(&pdev->dev, "unable to allocate msm_otg\n"); + return -ENOMEM; + } + + motg->pdata = pdev->dev.platform_data; + otg = &motg->otg; + otg->dev = &pdev->dev; + + motg->phy_reset_clk = clk_get(&pdev->dev, "usb_phy_clk"); + if (IS_ERR(motg->phy_reset_clk)) { + dev_err(&pdev->dev, "failed to get usb_phy_clk\n"); + ret = PTR_ERR(motg->phy_reset_clk); + goto free_motg; + } + + motg->clk = clk_get(&pdev->dev, "usb_hs_clk"); + if (IS_ERR(motg->clk)) { + dev_err(&pdev->dev, "failed to get usb_hs_clk\n"); + ret = PTR_ERR(motg->clk); + goto put_phy_reset_clk; + } + + motg->pclk = clk_get(&pdev->dev, "usb_hs_pclk"); + if (IS_ERR(motg->pclk)) { + dev_err(&pdev->dev, "failed to get usb_hs_pclk\n"); + ret = PTR_ERR(motg->pclk); + goto put_clk; + } + + /* + * USB core clock is not present on all MSM chips. This + * clock is introduced to remove the dependency on AXI + * bus frequency. + */ + motg->core_clk = clk_get(&pdev->dev, "usb_hs_core_clk"); + if (IS_ERR(motg->core_clk)) + motg->core_clk = NULL; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "failed to get platform resource mem\n"); + ret = -ENODEV; + goto put_core_clk; + } + + motg->regs = ioremap(res->start, resource_size(res)); + if (!motg->regs) { + dev_err(&pdev->dev, "ioremap failed\n"); + ret = -ENOMEM; + goto put_core_clk; + } + dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs); + + motg->irq = platform_get_irq(pdev, 0); + if (!motg->irq) { + dev_err(&pdev->dev, "platform_get_irq failed\n"); + ret = -ENODEV; + goto free_regs; + } + + clk_enable(motg->clk); + clk_enable(motg->pclk); + if (motg->core_clk) + clk_enable(motg->core_clk); + + writel(0, USB_USBINTR); + writel(0, USB_OTGSC); + + INIT_WORK(&motg->sm_work, msm_otg_sm_work); + ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED, + "msm_otg", motg); + if (ret) { + dev_err(&pdev->dev, "request irq failed\n"); + goto disable_clks; + } + + otg->init = msm_otg_reset; + otg->set_host = msm_otg_set_host; + otg->set_peripheral = msm_otg_set_peripheral; + + otg->io_ops = &msm_otg_io_ops; + + ret = otg_set_transceiver(&motg->otg); + if (ret) { + dev_err(&pdev->dev, "otg_set_transceiver failed\n"); + goto free_irq; + } + + platform_set_drvdata(pdev, motg); + device_init_wakeup(&pdev->dev, 1); + + if (motg->pdata->mode == USB_OTG && + motg->pdata->otg_control == OTG_USER_CONTROL) { + ret = msm_otg_debugfs_init(motg); + if (ret) + dev_dbg(&pdev->dev, "mode debugfs file is" + "not available\n"); + } + + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + + return 0; +free_irq: + free_irq(motg->irq, motg); +disable_clks: + clk_disable(motg->pclk); + clk_disable(motg->clk); +free_regs: + iounmap(motg->regs); +put_core_clk: + if (motg->core_clk) + clk_put(motg->core_clk); + clk_put(motg->pclk); +put_clk: + clk_put(motg->clk); +put_phy_reset_clk: + clk_put(motg->phy_reset_clk); +free_motg: + kfree(motg); + return ret; +} + +static int __devexit msm_otg_remove(struct platform_device *pdev) +{ + struct msm_otg *motg = platform_get_drvdata(pdev); + struct otg_transceiver *otg = &motg->otg; + int cnt = 0; + + if (otg->host || otg->gadget) + return -EBUSY; + + msm_otg_debugfs_cleanup(); + cancel_work_sync(&motg->sm_work); + + pm_runtime_resume(&pdev->dev); + + device_init_wakeup(&pdev->dev, 0); + pm_runtime_disable(&pdev->dev); + + otg_set_transceiver(NULL); + free_irq(motg->irq, motg); + + /* + * Put PHY in low power mode. + */ + ulpi_read(otg, 0x14); + ulpi_write(otg, 0x08, 0x09); + + writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC); + while (cnt < PHY_SUSPEND_TIMEOUT_USEC) { + if (readl(USB_PORTSC) & PORTSC_PHCD) + break; + udelay(1); + cnt++; + } + if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) + dev_err(otg->dev, "Unable to suspend PHY\n"); + + clk_disable(motg->pclk); + clk_disable(motg->clk); + if (motg->core_clk) + clk_disable(motg->core_clk); + + iounmap(motg->regs); + pm_runtime_set_suspended(&pdev->dev); + + clk_put(motg->phy_reset_clk); + clk_put(motg->pclk); + clk_put(motg->clk); + if (motg->core_clk) + clk_put(motg->core_clk); + + kfree(motg); + + return 0; +} + +#ifdef CONFIG_PM_RUNTIME +static int msm_otg_runtime_idle(struct device *dev) +{ + struct msm_otg *motg = dev_get_drvdata(dev); + struct otg_transceiver *otg = &motg->otg; + + dev_dbg(dev, "OTG runtime idle\n"); + + /* + * It is observed some times that a spurious interrupt + * comes when PHY is put into LPM immediately after PHY reset. + * This 1 sec delay also prevents entering into LPM immediately + * after asynchronous interrupt. + */ + if (otg->state != OTG_STATE_UNDEFINED) + pm_schedule_suspend(dev, 1000); + + return -EAGAIN; +} + +static int msm_otg_runtime_suspend(struct device *dev) +{ + struct msm_otg *motg = dev_get_drvdata(dev); + + dev_dbg(dev, "OTG runtime suspend\n"); + return msm_otg_suspend(motg); +} + +static int msm_otg_runtime_resume(struct device *dev) +{ + struct msm_otg *motg = dev_get_drvdata(dev); + + dev_dbg(dev, "OTG runtime resume\n"); + return msm_otg_resume(motg); +} +#endif + +#ifdef CONFIG_PM_SLEEP +static int msm_otg_pm_suspend(struct device *dev) +{ + struct msm_otg *motg = dev_get_drvdata(dev); + + dev_dbg(dev, "OTG PM suspend\n"); + return msm_otg_suspend(motg); +} + +static int msm_otg_pm_resume(struct device *dev) +{ + struct msm_otg *motg = dev_get_drvdata(dev); + int ret; + + dev_dbg(dev, "OTG PM resume\n"); + + ret = msm_otg_resume(motg); + if (ret) + return ret; + + /* + * Runtime PM Documentation recommends bringing the + * device to full powered state upon resume. + */ + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + return 0; +} +#endif + +#ifdef CONFIG_PM +static const struct dev_pm_ops msm_otg_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(msm_otg_pm_suspend, msm_otg_pm_resume) + SET_RUNTIME_PM_OPS(msm_otg_runtime_suspend, msm_otg_runtime_resume, + msm_otg_runtime_idle) +}; +#endif + +static struct platform_driver msm_otg_driver = { + .remove = __devexit_p(msm_otg_remove), + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &msm_otg_dev_pm_ops, +#endif + }, +}; + +static int __init msm_otg_init(void) +{ + return platform_driver_probe(&msm_otg_driver, msm_otg_probe); +} + +static void __exit msm_otg_exit(void) +{ + platform_driver_unregister(&msm_otg_driver); +} + +module_init(msm_otg_init); +module_exit(msm_otg_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("MSM USB transceiver driver"); diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h index 3675e03b1539..3657403eac18 100644 --- a/include/linux/usb/msm_hsusb.h +++ b/include/linux/usb/msm_hsusb.h @@ -55,7 +55,7 @@ enum otg_control_type { /** * struct msm_otg_platform_data - platform device data - * for msm72k_otg driver. + * for msm_otg driver. * @phy_init_seq: PHY configuration sequence. val, reg pairs * terminated by -1. * @vbus_power: VBUS power on/off routine. -- cgit v1.2.3 From fa417c369b48a8f7acaf9aba1ff94b0969b0cb7e Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Thu, 3 Mar 2011 21:10:05 +0300 Subject: USB: OHCI: use pci_dev->revision Commit ab1666c1364a209e6141d7c14e47a42b5f00eca2 (USB: quirk PLL power down mode) added code that reads the revision ID from the PCI configuration register while it's stored by PCI subsystem in the 'revision' field of 'struct pci_dev'... Signed-off-by: Sergei Shtylyov Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 9816a2870d00..d84d6f0314f9 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -151,7 +151,7 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); struct pci_dev *amd_smbus_dev; - u8 rev = 0; + u8 rev; if (usb_amd_find_chipset_info()) ohci->flags |= OHCI_QUIRK_AMD_PLL; @@ -161,7 +161,7 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd) if (!amd_smbus_dev) return 0; - pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev); + rev = amd_smbus_dev->revision; /* SB800 needs pre-fetch fix */ if ((rev >= 0x40) && (rev <= 0x4f)) { -- cgit v1.2.3 From a74022a55e44fe2044ac3660452cafecb300aece Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 7 Mar 2011 08:41:59 +0100 Subject: USB: s3c2410_udc: Add common implementation for GPIO controlled pullups Currently all boards using the s3c2410_udc driver use a GPIO to control the state of the pullup, as a result the same code is reimplemented in each board file. This patch adds support for using a GPIO to control the pullup state to the udc driver, so the boards can use a common implementation. Signed-off-by: Lars-Peter Clausen Signed-off-by: Greg Kroah-Hartman --- arch/arm/plat-s3c24xx/include/plat/udc.h | 4 +++ drivers/usb/gadget/s3c2410_udc.c | 60 +++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/arch/arm/plat-s3c24xx/include/plat/udc.h b/arch/arm/plat-s3c24xx/include/plat/udc.h index 546bb4008f49..80457c6414aa 100644 --- a/arch/arm/plat-s3c24xx/include/plat/udc.h +++ b/arch/arm/plat-s3c24xx/include/plat/udc.h @@ -27,6 +27,10 @@ enum s3c2410_udc_cmd_e { struct s3c2410_udc_mach_info { void (*udc_command)(enum s3c2410_udc_cmd_e); void (*vbus_draw)(unsigned int ma); + + unsigned int pullup_pin; + unsigned int pullup_pin_inverted; + unsigned int vbus_pin; unsigned char vbus_pin_inverted; }; diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index 2b025200a69a..6d8b04061d5d 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -1481,7 +1481,9 @@ static int s3c2410_udc_set_pullup(struct s3c2410_udc *udc, int is_on) { dprintk(DEBUG_NORMAL, "%s()\n", __func__); - if (udc_info && udc_info->udc_command) { + if (udc_info && (udc_info->udc_command || + gpio_is_valid(udc_info->pullup_pin))) { + if (is_on) s3c2410_udc_enable(udc); else { @@ -1558,6 +1560,32 @@ static const struct usb_gadget_ops s3c2410_ops = { .vbus_draw = s3c2410_vbus_draw, }; +static void s3c2410_udc_command(enum s3c2410_udc_cmd_e cmd) +{ + if (!udc_info) + return; + + if (udc_info->udc_command) { + udc_info->udc_command(S3C2410_UDC_P_DISABLE); + } else if (gpio_is_valid(udc_info->pullup_pin)) { + int value; + + switch (cmd) { + case S3C2410_UDC_P_ENABLE: + value = 1; + break; + case S3C2410_UDC_P_DISABLE: + value = 0; + break; + default: + return; + } + value ^= udc_info->pullup_pin_inverted; + + gpio_set_value(udc_info->pullup_pin, value); + } +} + /*------------------------- gadget driver handling---------------------------*/ /* * s3c2410_udc_disable @@ -1579,8 +1607,7 @@ static void s3c2410_udc_disable(struct s3c2410_udc *dev) udc_write(0x1F, S3C2410_UDC_EP_INT_REG); /* Good bye, cruel world */ - if (udc_info && udc_info->udc_command) - udc_info->udc_command(S3C2410_UDC_P_DISABLE); + s3c2410_udc_command(S3C2410_UDC_P_DISABLE); /* Set speed to unknown */ dev->gadget.speed = USB_SPEED_UNKNOWN; @@ -1641,8 +1668,7 @@ static void s3c2410_udc_enable(struct s3c2410_udc *dev) udc_write(S3C2410_UDC_INT_EP0, S3C2410_UDC_EP_INT_EN_REG); /* time to say "hello, world" */ - if (udc_info && udc_info->udc_command) - udc_info->udc_command(S3C2410_UDC_P_ENABLE); + s3c2410_udc_command(S3C2410_UDC_P_ENABLE); } /* @@ -1917,6 +1943,17 @@ static int s3c2410_udc_probe(struct platform_device *pdev) udc->vbus = 1; } + if (udc_info && !udc_info->udc_command && + gpio_is_valid(udc_info->pullup_pin)) { + + retval = gpio_request_one(udc_info->pullup_pin, + udc_info->vbus_pin_inverted ? + GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW, + "udc pullup"); + if (retval) + goto err_vbus_irq; + } + if (s3c2410_udc_debugfs_root) { udc->regs_info = debugfs_create_file("registers", S_IRUGO, s3c2410_udc_debugfs_root, @@ -1929,6 +1966,9 @@ static int s3c2410_udc_probe(struct platform_device *pdev) return 0; +err_vbus_irq: + if (udc_info && udc_info->vbus_pin > 0) + free_irq(gpio_to_irq(udc_info->vbus_pin), udc); err_gpio_claim: if (udc_info && udc_info->vbus_pin > 0) gpio_free(udc_info->vbus_pin); @@ -1956,6 +1996,10 @@ static int s3c2410_udc_remove(struct platform_device *pdev) debugfs_remove(udc->regs_info); + if (udc_info && !udc_info->udc_command && + gpio_is_valid(udc_info->pullup_pin)) + gpio_free(udc_info->pullup_pin); + if (udc_info && udc_info->vbus_pin > 0) { irq = gpio_to_irq(udc_info->vbus_pin); free_irq(irq, udc); @@ -1987,16 +2031,14 @@ static int s3c2410_udc_remove(struct platform_device *pdev) #ifdef CONFIG_PM static int s3c2410_udc_suspend(struct platform_device *pdev, pm_message_t message) { - if (udc_info && udc_info->udc_command) - udc_info->udc_command(S3C2410_UDC_P_DISABLE); + s3c2410_udc_command(S3C2410_UDC_P_DISABLE); return 0; } static int s3c2410_udc_resume(struct platform_device *pdev) { - if (udc_info && udc_info->udc_command) - udc_info->udc_command(S3C2410_UDC_P_ENABLE); + s3c2410_udc_command(S3C2410_UDC_P_ENABLE); return 0; } -- cgit v1.2.3 From f277e65e7a2d360189f760baca42f3ca2f62dd7a Mon Sep 17 00:00:00 2001 From: Göran Weinholt Date: Wed, 2 Mar 2011 04:07:21 +0000 Subject: net/smsc911x.c: Set the VLAN1 register to fix VLAN MTU problem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The smsc911x driver would drop frames longer than 1518 bytes, which is a problem for networks with VLAN tagging. The VLAN1 tag register is used to increase the legal frame size to 1522 when a VLAN tag is identified. Signed-off-by: Göran Weinholt Signed-off-by: David S. Miller --- drivers/net/smsc911x.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 64bfdae5956f..d70bde95460b 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -1178,6 +1178,11 @@ static int smsc911x_open(struct net_device *dev) smsc911x_reg_write(pdata, HW_CFG, 0x00050000); smsc911x_reg_write(pdata, AFC_CFG, 0x006E3740); + /* Increase the legal frame size of VLAN tagged frames to 1522 bytes */ + spin_lock_irq(&pdata->mac_lock); + smsc911x_mac_write(pdata, VLAN1, ETH_P_8021Q); + spin_unlock_irq(&pdata->mac_lock); + /* Make sure EEPROM has finished loading before setting GPIO_CFG */ timeout = 50; while ((smsc911x_reg_read(pdata, E2P_CMD) & E2P_CMD_EPC_BUSY_) && -- cgit v1.2.3 From ef1b287169cd3d1e428c8ed8222e0bbf733d5dbb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 7 Mar 2011 17:18:03 +1000 Subject: drm/nouveau: fix regression causing ttm to not be able to evict vram TTM assumes an error condition from man->func->get_node() means that something went horribly wrong, and causes it to bail. The driver is supposed to return 0, and leave mm_node == NULL to signal that it couldn't allocate any memory. Signed-off-by: Ben Skeggs Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nouveau_mem.c | 6 ++++-- drivers/gpu/drm/nouveau/nouveau_mm.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 26347b7cd872..b0fb9bdcddb7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -725,8 +725,10 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, ret = vram->get(dev, mem->num_pages << PAGE_SHIFT, mem->page_alignment << PAGE_SHIFT, size_nc, (nvbo->tile_flags >> 8) & 0xff, &node); - if (ret) - return ret; + if (ret) { + mem->mm_node = NULL; + return (ret == -ENOSPC) ? 0 : ret; + } node->page_shift = 12; if (nvbo->vma.node) diff --git a/drivers/gpu/drm/nouveau/nouveau_mm.c b/drivers/gpu/drm/nouveau/nouveau_mm.c index 8844b50c3e54..7609756b6faf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mm.c +++ b/drivers/gpu/drm/nouveau/nouveau_mm.c @@ -123,7 +123,7 @@ nouveau_mm_get(struct nouveau_mm *rmm, int type, u32 size, u32 size_nc, return 0; } - return -ENOMEM; + return -ENOSPC; } int -- cgit v1.2.3 From 6f70a4c3d19e8e8e1047a4dbf0ca910fed39f619 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 7 Mar 2011 17:18:04 +1000 Subject: drm/nv50-nvc0: prevent multiple vm/bar flushes occuring simultanenously The per-vm mutex doesn't prevent this completely, a flush coming from the BAR VM could potentially happen at the same time as one for the channel VM. Not to mention that if/when we get per-client/channel VM, this will happen far more frequently. Signed-off-by: Ben Skeggs Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nv50_instmem.c | 8 ++++++++ drivers/gpu/drm/nouveau/nv50_vm.c | 4 ++++ 2 files changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index ea0041810ae3..e57caa2a00e3 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -403,16 +403,24 @@ nv50_instmem_unmap(struct nouveau_gpuobj *gpuobj) void nv50_instmem_flush(struct drm_device *dev) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + + spin_lock(&dev_priv->ramin_lock); nv_wr32(dev, 0x00330c, 0x00000001); if (!nv_wait(dev, 0x00330c, 0x00000002, 0x00000000)) NV_ERROR(dev, "PRAMIN flush timeout\n"); + spin_unlock(&dev_priv->ramin_lock); } void nv84_instmem_flush(struct drm_device *dev) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + + spin_lock(&dev_priv->ramin_lock); nv_wr32(dev, 0x070000, 0x00000001); if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000)) NV_ERROR(dev, "PRAMIN flush timeout\n"); + spin_unlock(&dev_priv->ramin_lock); } diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c index 459ff08241e5..6144156f255a 100644 --- a/drivers/gpu/drm/nouveau/nv50_vm.c +++ b/drivers/gpu/drm/nouveau/nv50_vm.c @@ -169,7 +169,11 @@ nv50_vm_flush(struct nouveau_vm *vm) void nv50_vm_flush_engine(struct drm_device *dev, int engine) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + + spin_lock(&dev_priv->ramin_lock); nv_wr32(dev, 0x100c80, (engine << 16) | 1); if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000)) NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); + spin_unlock(&dev_priv->ramin_lock); } -- cgit v1.2.3 From f1a304e7941cc76353363a139cbb6a4b1ca7c737 Mon Sep 17 00:00:00 2001 From: Pratheesh Gangadhar Date: Sat, 5 Mar 2011 04:30:17 +0530 Subject: UIO: add PRUSS UIO driver support This patch implements PRUSS (Programmable Real-time Unit Sub System) UIO driver which exports SOC resources associated with PRUSS like I/O, memories and IRQs to user space. PRUSS is dual 32-bit RISC processors which is efficient in performing embedded tasks that require manipulation of packed memory mapped data structures and handling system events that have tight real time constraints. This driver is currently supported on Texas Instruments DA850, AM18xx and OMAP-L138 devices. For example, PRUSS runs firmware for real-time critical industrial communication data link layer and communicates with application stack running in user space via shared memory and IRQs. Signed-off-by: Pratheesh Gangadhar Reviewed-by: Thomas Gleixner Reviewed-by: Arnd Bergmann Signed-off-by: Hans J. Koch Signed-off-by: Greg Kroah-Hartman --- drivers/uio/Kconfig | 17 +++ drivers/uio/Makefile | 1 + drivers/uio/uio_pruss.c | 247 ++++++++++++++++++++++++++++++++ include/linux/platform_data/uio_pruss.h | 25 ++++ 4 files changed, 290 insertions(+) create mode 100644 drivers/uio/uio_pruss.c create mode 100644 include/linux/platform_data/uio_pruss.h (limited to 'drivers') diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig index bb440792a1b7..6f3ea9bbc818 100644 --- a/drivers/uio/Kconfig +++ b/drivers/uio/Kconfig @@ -94,4 +94,21 @@ config UIO_NETX To compile this driver as a module, choose M here; the module will be called uio_netx. +config UIO_PRUSS + tristate "Texas Instruments PRUSS driver" + depends on ARCH_DAVINCI_DA850 + help + PRUSS driver for OMAPL138/DA850/AM18XX devices + PRUSS driver requires user space components, examples and user space + driver is available from below SVN repo - you may use anonymous login + + https://gforge.ti.com/gf/project/pru_sw/ + + More info on API is available at below wiki + + http://processors.wiki.ti.com/index.php/PRU_Linux_Application_Loader + + To compile this driver as a module, choose M here: the module + will be called uio_pruss. + endif diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile index 18fd818c5b97..d4dd9a5552f8 100644 --- a/drivers/uio/Makefile +++ b/drivers/uio/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_UIO_AEC) += uio_aec.o obj-$(CONFIG_UIO_SERCOS3) += uio_sercos3.o obj-$(CONFIG_UIO_PCI_GENERIC) += uio_pci_generic.o obj-$(CONFIG_UIO_NETX) += uio_netx.o +obj-$(CONFIG_UIO_PRUSS) += uio_pruss.o diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c new file mode 100644 index 000000000000..daf6e77de2b1 --- /dev/null +++ b/drivers/uio/uio_pruss.c @@ -0,0 +1,247 @@ +/* + * Programmable Real-Time Unit Sub System (PRUSS) UIO driver (uio_pruss) + * + * This driver exports PRUSS host event out interrupts and PRUSS, L3 RAM, + * and DDR RAM to user space for applications interacting with PRUSS firmware + * + * Copyright (C) 2010-11 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "pruss_uio" +#define DRV_VERSION "1.0" + +static int sram_pool_sz = SZ_16K; +module_param(sram_pool_sz, int, 0); +MODULE_PARM_DESC(sram_pool_sz, "sram pool size to allocate "); + +static int extram_pool_sz = SZ_256K; +module_param(extram_pool_sz, int, 0); +MODULE_PARM_DESC(extram_pool_sz, "external ram pool size to allocate"); + +/* + * Host event IRQ numbers from PRUSS - PRUSS can generate upto 8 interrupt + * events to AINTC of ARM host processor - which can be used for IPC b/w PRUSS + * firmware and user space application, async notification from PRU firmware + * to user space application + * 3 PRU_EVTOUT0 + * 4 PRU_EVTOUT1 + * 5 PRU_EVTOUT2 + * 6 PRU_EVTOUT3 + * 7 PRU_EVTOUT4 + * 8 PRU_EVTOUT5 + * 9 PRU_EVTOUT6 + * 10 PRU_EVTOUT7 +*/ +#define MAX_PRUSS_EVT 8 + +#define PINTC_HIDISR 0x0038 +#define PINTC_HIPIR 0x0900 +#define HIPIR_NOPEND 0x80000000 +#define PINTC_HIER 0x1500 + +struct uio_pruss_dev { + struct uio_info *info; + struct clk *pruss_clk; + dma_addr_t sram_paddr; + dma_addr_t ddr_paddr; + void __iomem *prussio_vaddr; + void *sram_vaddr; + void *ddr_vaddr; + unsigned int hostirq_start; + unsigned int pintc_base; +}; + +static irqreturn_t pruss_handler(int irq, struct uio_info *info) +{ + struct uio_pruss_dev *gdev = info->priv; + int intr_bit = (irq - gdev->hostirq_start + 2); + int val, intr_mask = (1 << intr_bit); + void __iomem *base = gdev->prussio_vaddr + gdev->pintc_base; + void __iomem *intren_reg = base + PINTC_HIER; + void __iomem *intrdis_reg = base + PINTC_HIDISR; + void __iomem *intrstat_reg = base + PINTC_HIPIR + (intr_bit << 2); + + val = ioread32(intren_reg); + /* Is interrupt enabled and active ? */ + if (!(val & intr_mask) && (ioread32(intrstat_reg) & HIPIR_NOPEND)) + return IRQ_NONE; + /* Disable interrupt */ + iowrite32(intr_bit, intrdis_reg); + return IRQ_HANDLED; +} + +static void pruss_cleanup(struct platform_device *dev, + struct uio_pruss_dev *gdev) +{ + int cnt; + struct uio_info *p = gdev->info; + + for (cnt = 0; cnt < MAX_PRUSS_EVT; cnt++, p++) { + uio_unregister_device(p); + kfree(p->name); + } + iounmap(gdev->prussio_vaddr); + if (gdev->ddr_vaddr) { + dma_free_coherent(&dev->dev, extram_pool_sz, gdev->ddr_vaddr, + gdev->ddr_paddr); + } + if (gdev->sram_vaddr) + sram_free(gdev->sram_vaddr, sram_pool_sz); + kfree(gdev->info); + clk_put(gdev->pruss_clk); + kfree(gdev); +} + +static int __devinit pruss_probe(struct platform_device *dev) +{ + struct uio_info *p; + struct uio_pruss_dev *gdev; + struct resource *regs_prussio; + int ret = -ENODEV, cnt = 0, len; + struct uio_pruss_pdata *pdata = dev->dev.platform_data; + + gdev = kzalloc(sizeof(struct uio_pruss_dev), GFP_KERNEL); + if (!gdev) + return -ENOMEM; + + gdev->info = kzalloc(sizeof(*p) * MAX_PRUSS_EVT, GFP_KERNEL); + if (!gdev->info) { + kfree(gdev); + return -ENOMEM; + } + /* Power on PRU in case its not done as part of boot-loader */ + gdev->pruss_clk = clk_get(&dev->dev, "pruss"); + if (IS_ERR(gdev->pruss_clk)) { + dev_err(&dev->dev, "Failed to get clock\n"); + kfree(gdev->info); + kfree(gdev); + ret = PTR_ERR(gdev->pruss_clk); + return ret; + } else { + clk_enable(gdev->pruss_clk); + } + + regs_prussio = platform_get_resource(dev, IORESOURCE_MEM, 0); + if (!regs_prussio) { + dev_err(&dev->dev, "No PRUSS I/O resource specified\n"); + goto out_free; + } + + if (!regs_prussio->start) { + dev_err(&dev->dev, "Invalid memory resource\n"); + goto out_free; + } + + gdev->sram_vaddr = sram_alloc(sram_pool_sz, &(gdev->sram_paddr)); + if (!gdev->sram_vaddr) { + dev_err(&dev->dev, "Could not allocate SRAM pool\n"); + goto out_free; + } + + gdev->ddr_vaddr = dma_alloc_coherent(&dev->dev, extram_pool_sz, + &(gdev->ddr_paddr), GFP_KERNEL | GFP_DMA); + if (!gdev->ddr_vaddr) { + dev_err(&dev->dev, "Could not allocate external memory\n"); + goto out_free; + } + + len = resource_size(regs_prussio); + gdev->prussio_vaddr = ioremap(regs_prussio->start, len); + if (!gdev->prussio_vaddr) { + dev_err(&dev->dev, "Can't remap PRUSS I/O address range\n"); + goto out_free; + } + + gdev->pintc_base = pdata->pintc_base; + gdev->hostirq_start = platform_get_irq(dev, 0); + + for (cnt = 0, p = gdev->info; cnt < MAX_PRUSS_EVT; cnt++, p++) { + p->mem[0].addr = regs_prussio->start; + p->mem[0].size = resource_size(regs_prussio); + p->mem[0].memtype = UIO_MEM_PHYS; + + p->mem[1].addr = gdev->sram_paddr; + p->mem[1].size = sram_pool_sz; + p->mem[1].memtype = UIO_MEM_PHYS; + + p->mem[2].addr = gdev->ddr_paddr; + p->mem[2].size = extram_pool_sz; + p->mem[2].memtype = UIO_MEM_PHYS; + + p->name = kasprintf(GFP_KERNEL, "pruss_evt%d", cnt); + p->version = DRV_VERSION; + + /* Register PRUSS IRQ lines */ + p->irq = gdev->hostirq_start + cnt; + p->handler = pruss_handler; + p->priv = gdev; + + ret = uio_register_device(&dev->dev, p); + if (ret < 0) + goto out_free; + } + + platform_set_drvdata(dev, gdev); + return 0; + +out_free: + pruss_cleanup(dev, gdev); + return ret; +} + +static int __devexit pruss_remove(struct platform_device *dev) +{ + struct uio_pruss_dev *gdev = platform_get_drvdata(dev); + + pruss_cleanup(dev, gdev); + platform_set_drvdata(dev, NULL); + return 0; +} + +static struct platform_driver pruss_driver = { + .probe = pruss_probe, + .remove = __devexit_p(pruss_remove), + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init pruss_init_module(void) +{ + return platform_driver_register(&pruss_driver); +} + +module_init(pruss_init_module); + +static void __exit pruss_exit_module(void) +{ + platform_driver_unregister(&pruss_driver); +} + +module_exit(pruss_exit_module); + +MODULE_LICENSE("GPL v2"); +MODULE_VERSION(DRV_VERSION); +MODULE_AUTHOR("Amit Chatterjee "); +MODULE_AUTHOR("Pratheesh Gangadhar "); diff --git a/include/linux/platform_data/uio_pruss.h b/include/linux/platform_data/uio_pruss.h new file mode 100644 index 000000000000..f39140aabc6f --- /dev/null +++ b/include/linux/platform_data/uio_pruss.h @@ -0,0 +1,25 @@ +/* + * include/linux/platform_data/uio_pruss.h + * + * Platform data for uio_pruss driver + * + * Copyright (C) 2010-11 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _UIO_PRUSS_H_ +#define _UIO_PRUSS_H_ + +/* To configure the PRUSS INTC base offset for UIO driver */ +struct uio_pruss_pdata { + u32 pintc_base; +}; +#endif /* _UIO_PRUSS_H_ */ -- cgit v1.2.3 From 5d884b97c5143f0d4097cefefbf9f7f755fd54fa Mon Sep 17 00:00:00 2001 From: Thomas Viehweger Date: Wed, 2 Mar 2011 23:00:20 +0100 Subject: staging: lirc: fix for "lirc_dev: lirc_register_driver: driver pointer must be not NULL!" Unable to load the module lirc_parallel without the attached patch. Signed-off-by: Thomas Viehweger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lirc/lirc_parallel.c | 72 ++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lirc/lirc_parallel.c b/drivers/staging/lirc/lirc_parallel.c index 2f668a8a0c41..832522c290cb 100644 --- a/drivers/staging/lirc/lirc_parallel.c +++ b/drivers/staging/lirc/lirc_parallel.c @@ -42,6 +42,7 @@ #include #include +#include #include #include @@ -580,6 +581,40 @@ static struct lirc_driver driver = { .owner = THIS_MODULE, }; +static struct platform_device *lirc_parallel_dev; + +static int __devinit lirc_parallel_probe(struct platform_device *dev) +{ + return 0; +} + +static int __devexit lirc_parallel_remove(struct platform_device *dev) +{ + return 0; +} + +static int lirc_parallel_suspend(struct platform_device *dev, + pm_message_t state) +{ + return 0; +} + +static int lirc_parallel_resume(struct platform_device *dev) +{ + return 0; +} + +static struct platform_driver lirc_parallel_driver = { + .probe = lirc_parallel_probe, + .remove = __devexit_p(lirc_parallel_remove), + .suspend = lirc_parallel_suspend, + .resume = lirc_parallel_resume, + .driver = { + .name = LIRC_DRIVER_NAME, + .owner = THIS_MODULE, + }, +}; + static int pf(void *handle); static void kf(void *handle); @@ -608,11 +643,30 @@ static void kf(void *handle) static int __init lirc_parallel_init(void) { + int result; + + result = platform_driver_register(&lirc_parallel_driver); + if (result) { + printk("platform_driver_register returned %d\n", result); + return result; + } + + lirc_parallel_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0); + if (!lirc_parallel_dev) { + result = -ENOMEM; + goto exit_driver_unregister; + } + + result = platform_device_add(lirc_parallel_dev); + if (result) + goto exit_device_put; + pport = parport_find_base(io); if (pport == NULL) { printk(KERN_NOTICE "%s: no port at %x found\n", LIRC_DRIVER_NAME, io); - return -ENXIO; + result = -ENXIO; + goto exit_device_put; } ppdevice = parport_register_device(pport, LIRC_DRIVER_NAME, pf, kf, irq_handler, 0, NULL); @@ -620,7 +674,8 @@ static int __init lirc_parallel_init(void) if (ppdevice == NULL) { printk(KERN_NOTICE "%s: parport_register_device() failed\n", LIRC_DRIVER_NAME); - return -ENXIO; + result = -ENXIO; + goto exit_device_put; } if (parport_claim(ppdevice) != 0) goto skip_init; @@ -638,7 +693,8 @@ static int __init lirc_parallel_init(void) is_claimed = 0; parport_release(pport); parport_unregister_device(ppdevice); - return -EIO; + result = -EIO; + goto exit_device_put; } #endif @@ -649,16 +705,24 @@ static int __init lirc_parallel_init(void) is_claimed = 0; parport_release(ppdevice); skip_init: + driver.dev = &lirc_parallel_dev->dev; driver.minor = lirc_register_driver(&driver); if (driver.minor < 0) { printk(KERN_NOTICE "%s: register_chrdev() failed\n", LIRC_DRIVER_NAME); parport_unregister_device(ppdevice); - return -EIO; + result = -EIO; + goto exit_device_put; } printk(KERN_INFO "%s: installed using port 0x%04x irq %d\n", LIRC_DRIVER_NAME, io, irq); return 0; + +exit_device_put: + platform_device_put(lirc_parallel_dev); +exit_driver_unregister: + platform_driver_unregister(&lirc_parallel_driver); + return result; } static void __exit lirc_parallel_exit(void) -- cgit v1.2.3 From 817368f19af206d382be1347165f1bb2817a666a Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Thu, 3 Mar 2011 00:26:35 +0200 Subject: staging: xgifb: remove private ioctls Drop the badly defined and broken private ioctl interface. Since the driver is in staging, and some of the ioctls are clearly unsafe or not even working, it's unlikely that there are any users. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main.h | 9 -- drivers/staging/xgifb/XGI_main_26.c | 178 ------------------------------------ drivers/staging/xgifb/XGIfb.h | 72 --------------- 3 files changed, 259 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index eb0f79aeb380..37f77ee459ca 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -794,9 +794,6 @@ static int XGIfb_blank(int blank, struct vm_area_struct *vma); */ -static int XGIfb_ioctl(struct fb_info *info, unsigned int cmd, - unsigned long arg); - /* extern int XGIfb_mode_rate_to_dclock(VB_DEVICE_INFO *XGI_Pr, struct xgi_hw_device_info *HwDeviceExtension, @@ -826,18 +823,12 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, static void XGIfb_pre_setmode(void); static void XGIfb_post_setmode(void); -static unsigned char XGIfb_CheckVBRetrace(void); -static unsigned char XGIfbcheckvretracecrt2(void); -static unsigned char XGIfbcheckvretracecrt1(void); -static unsigned char XGIfb_bridgeisslave(void); - struct XGI_memreq { unsigned long offset; unsigned long size; }; /* XGI-specific Export functions */ -void XGI_dispinfo(struct ap_data *rec); void XGI_malloc(struct XGI_memreq *req); void XGI_free(unsigned long base); diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index c569d9744e81..faf7106b3558 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -982,61 +982,6 @@ static void XGIfb_search_tvstd(const char *name) } } -static unsigned char XGIfb_bridgeisslave(void) -{ - unsigned char usScratchP1_00; - - if (xgi_video_info.hasVB == HASVB_NONE) - return 0; - - inXGIIDXREG(XGIPART1, 0x00, usScratchP1_00); - if ((usScratchP1_00 & 0x50) == 0x10) - return 1; - else - return 0; -} - -static unsigned char XGIfbcheckvretracecrt1(void) -{ - unsigned char temp; - - inXGIIDXREG(XGICR, 0x17, temp); - if (!(temp & 0x80)) - return 0; - - inXGIIDXREG(XGISR, 0x1f, temp); - if (temp & 0xc0) - return 0; - - if (inXGIREG(XGIINPSTAT) & 0x08) - return 1; - else - return 0; -} - -static unsigned char XGIfbcheckvretracecrt2(void) -{ - unsigned char temp; - if (xgi_video_info.hasVB == HASVB_NONE) - return 0; - inXGIIDXREG(XGIPART1, 0x30, temp); - if (temp & 0x02) - return 0; - else - return 1; -} - -static unsigned char XGIfb_CheckVBRetrace(void) -{ - if (xgi_video_info.disp_state & DISPTYPE_DISP2) { - if (XGIfb_bridgeisslave()) - return XGIfbcheckvretracecrt1(); - else - return XGIfbcheckvretracecrt2(); - } - return XGIfbcheckvretracecrt1(); -} - /* ----------- FBDev related routines for all series ----------- */ static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var) @@ -1280,26 +1225,6 @@ static int XGIfb_pan_var(struct fb_var_screeninfo *var) } #endif -void XGI_dispinfo(struct ap_data *rec) -{ - rec->minfo.bpp = xgi_video_info.video_bpp; - rec->minfo.xres = xgi_video_info.video_width; - rec->minfo.yres = xgi_video_info.video_height; - rec->minfo.v_xres = xgi_video_info.video_vwidth; - rec->minfo.v_yres = xgi_video_info.video_vheight; - rec->minfo.org_x = xgi_video_info.org_x; - rec->minfo.org_y = xgi_video_info.org_y; - rec->minfo.vrate = xgi_video_info.refresh_rate; - rec->iobase = xgi_video_info.vga_base - 0x30; - rec->mem_size = xgi_video_info.video_size; - rec->disp_state = xgi_video_info.disp_state; - rec->version = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL; - rec->hasVB = xgi_video_info.hasVB; - rec->TV_type = xgi_video_info.TV_type; - rec->TV_plug = xgi_video_info.TV_plug; - rec->chip = xgi_video_info.chip; -} - static int XGIfb_open(struct fb_info *info, int user) { return 0; @@ -1574,108 +1499,6 @@ static int XGIfb_blank(int blank, struct fb_info *info) return 0; } -static int XGIfb_ioctl(struct fb_info *info, unsigned int cmd, - unsigned long arg) -{ - DEBUGPRN("inside ioctl"); - switch (cmd) { - case FBIO_ALLOC: - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - XGI_malloc((struct XGI_memreq *) arg); - break; - case FBIO_FREE: - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - XGI_free(*(unsigned long *) arg); - break; - case FBIOGET_HWCINFO: { - unsigned long *hwc_offset = (unsigned long *) arg; - - if (XGIfb_caps & HW_CURSOR_CAP) - *hwc_offset - = XGIfb_hwcursor_vbase - - (unsigned long) xgi_video_info.video_vbase; - else - *hwc_offset = 0; - - break; - } - case FBIOPUT_MODEINFO: { - struct mode_info *x = (struct mode_info *) arg; - - xgi_video_info.video_bpp = x->bpp; - xgi_video_info.video_width = x->xres; - xgi_video_info.video_height = x->yres; - xgi_video_info.video_vwidth = x->v_xres; - xgi_video_info.video_vheight = x->v_yres; - xgi_video_info.org_x = x->org_x; - xgi_video_info.org_y = x->org_y; - xgi_video_info.refresh_rate = x->vrate; - xgi_video_info.video_linelength = xgi_video_info.video_vwidth - * (xgi_video_info.video_bpp >> 3); - switch (xgi_video_info.video_bpp) { - case 8: - xgi_video_info.DstColor = 0x0000; - xgi_video_info.XGI310_AccelDepth = 0x00000000; - xgi_video_info.video_cmap_len = 256; - break; - case 16: - xgi_video_info.DstColor = 0x8000; - xgi_video_info.XGI310_AccelDepth = 0x00010000; - xgi_video_info.video_cmap_len = 16; - break; - case 32: - xgi_video_info.DstColor = 0xC000; - xgi_video_info.XGI310_AccelDepth = 0x00020000; - xgi_video_info.video_cmap_len = 16; - break; - default: - xgi_video_info.video_cmap_len = 16; - printk(KERN_ERR "XGIfb: Unsupported accel depth %d", xgi_video_info.video_bpp); - break; - } - - break; - } - case FBIOGET_DISPINFO: - XGI_dispinfo((struct ap_data *) arg); - break; - case XGIFB_GET_INFO: /* TW: New for communication with X driver */ - { - struct XGIfb_info *x = (struct XGIfb_info *) arg; - - /* x->XGIfb_id = XGIFB_ID; */ - x->XGIfb_version = VER_MAJOR; - x->XGIfb_revision = VER_MINOR; - x->XGIfb_patchlevel = VER_LEVEL; - x->chip_id = xgi_video_info.chip_id; - x->memory = xgi_video_info.video_size / 1024; - x->heapstart = xgi_video_info.heapstart / 1024; - x->fbvidmode = XGIfb_mode_no; - x->XGIfb_caps = XGIfb_caps; - x->XGIfb_tqlen = 512; /* yet unused */ - x->XGIfb_pcibus = xgi_video_info.pcibus; - x->XGIfb_pcislot = xgi_video_info.pcislot; - x->XGIfb_pcifunc = xgi_video_info.pcifunc; - x->XGIfb_lcdpdc = XGIfb_detectedpdc; - x->XGIfb_lcda = XGIfb_detectedlcda; - break; - } - case XGIFB_GET_VBRSTATUS: { - unsigned long *vbrstatus = (unsigned long *) arg; - if (XGIfb_CheckVBRetrace()) - *vbrstatus = 1; - else - *vbrstatus = 0; - } - default: - return -EINVAL; - } DEBUGPRN("end of ioctl"); - return 0; - -} - /* ----------- FBDev related routines for all series ---------- */ static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con, @@ -1738,7 +1561,6 @@ static struct fb_ops XGIfb_ops = { .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_ioctl = XGIfb_ioctl, /* .fb_mmap = XGIfb_mmap, */ }; diff --git a/drivers/staging/xgifb/XGIfb.h b/drivers/staging/xgifb/XGIfb.h index 8e59e15281b7..d6c3139f72e6 100644 --- a/drivers/staging/xgifb/XGIfb.h +++ b/drivers/staging/xgifb/XGIfb.h @@ -64,36 +64,6 @@ enum xgi_tvtype { TVMODE_TOTAL }; - -struct XGIfb_info { - unsigned long XGIfb_id; - int chip_id; /* PCI ID of detected chip */ - int memory; /* video memory in KB which XGIfb manages */ - int heapstart; /* heap start (= XGIfb "mem" argument) in KB */ - unsigned char fbvidmode; /* current XGIfb mode */ - - unsigned char XGIfb_version; - unsigned char XGIfb_revision; - unsigned char XGIfb_patchlevel; - - unsigned char XGIfb_caps; /* XGIfb capabilities */ - - int XGIfb_tqlen; /* turbo queue length (in KB) */ - - unsigned int XGIfb_pcibus; /* The card's PCI ID */ - unsigned int XGIfb_pcislot; - unsigned int XGIfb_pcifunc; - - unsigned char XGIfb_lcdpdc; /* PanelDelayCompensation */ - - unsigned char XGIfb_lcda; /* Detected status of LCDA for low res/text modes */ - - char reserved[235]; /* for future use */ -}; - - - - enum xgi_tv_plug { /* vicki@030226 */ // TVPLUG_Legacy = 0, // TVPLUG_COMPOSITE, @@ -112,48 +82,6 @@ enum xgi_tv_plug { /* vicki@030226 */ TVPLUG_TOTAL }; - -struct mode_info { - int bpp; - int xres; - int yres; - int v_xres; - int v_yres; - int org_x; - int org_y; - unsigned int vrate; -}; - -struct ap_data { - struct mode_info minfo; - unsigned long iobase; - unsigned int mem_size; - unsigned long disp_state; - enum XGI_CHIP_TYPE chip; - unsigned char hasVB; - enum xgi_tvtype TV_type; - enum xgi_tv_plug TV_plug; - unsigned long version; - char reserved[256]; -}; - - - -/* If changing this, vgatypes.h must also be changed (for X driver) */ - - -/* - * NOTE! The ioctl types used to be "size_t" by mistake, but were - * really meant to be __u32. Changed to "__u32" even though that - * changes the value on 64-bit architectures, because the value - * (with a 4-byte size) is also hardwired in vgatypes.h for user - * space exports. So "__u32" is actually more compatible, duh! - */ -#define XGIFB_GET_INFO _IOR('n',0xF8,__u32) -#define XGIFB_GET_VBRSTATUS _IOR('n',0xF9,__u32) - - - struct video_info{ int chip_id; unsigned int video_size; -- cgit v1.2.3 From a90f36206f0af9d6e2378a5f9c02dea081a04ae5 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 3 Mar 2011 00:10:48 +0200 Subject: staging/easycap: more style fixing in easycap_main.c mostly indentation fixes and some line over 80 characters fixes Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_main.c | 133 ++++++++++++++------------------- 1 file changed, 57 insertions(+), 76 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index e33c3cb7b397..83aa6ee0dcd7 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -1147,20 +1147,17 @@ int easycap_dqbuf(struct easycap *peasycap, int mode) if (mode) return -EAGAIN; - JOM(8, "first wait on wq_video, " - "%i=field_read %i=field_fill\n", - peasycap->field_read, peasycap->field_fill); + JOM(8, "first wait on wq_video, %i=field_read %i=field_fill\n", + peasycap->field_read, peasycap->field_fill); if (0 != (wait_event_interruptible(peasycap->wq_video, (peasycap->video_idle || peasycap->video_eof || ((peasycap->field_read != peasycap->field_fill) && - (0 == (0xFF00 & peasycap->field_buffer - [peasycap->field_read][0].kount)) && - (ifield == (0x00FF & peasycap->field_buffer - [peasycap->field_read][0].kount))))))) { + (0 == (0xFF00 & peasycap->field_buffer[peasycap->field_read][0].kount)) && + (ifield == (0x00FF & peasycap->field_buffer[peasycap->field_read][0].kount))))))) { SAM("aborted by signal\n"); return -EIO; - } + } if (peasycap->video_idle) { JOM(8, "%i=peasycap->video_idle returning -EAGAIN\n", peasycap->video_idle); @@ -1191,7 +1188,7 @@ int easycap_dqbuf(struct easycap *peasycap, int mode) JOM(8, "returning -EIO\n"); return -EIO; } - miss++; + miss++; } JOM(8, "first awakening on wq_video after %i waits\n", miss); @@ -1209,10 +1206,8 @@ int easycap_dqbuf(struct easycap *peasycap, int mode) ifield = 1; miss = 0; while ((peasycap->field_read == peasycap->field_fill) || - (0 != (0xFF00 & peasycap->field_buffer - [peasycap->field_read][0].kount)) || - (ifield != (0x00FF & peasycap->field_buffer - [peasycap->field_read][0].kount))) { + (0 != (0xFF00 & peasycap->field_buffer[peasycap->field_read][0].kount)) || + (ifield != (0x00FF & peasycap->field_buffer[peasycap->field_read][0].kount))) { if (mode) return -EAGAIN; @@ -1221,11 +1216,8 @@ int easycap_dqbuf(struct easycap *peasycap, int mode) if (0 != (wait_event_interruptible(peasycap->wq_video, (peasycap->video_idle || peasycap->video_eof || ((peasycap->field_read != peasycap->field_fill) && - (0 == (0xFF00 & peasycap->field_buffer - [peasycap->field_read][0].kount)) && - (ifield == (0x00FF & peasycap->field_buffer - [peasycap->field_read][0]. - kount))))))) { + (0 == (0xFF00 & peasycap->field_buffer[peasycap->field_read][0].kount)) && + (ifield == (0x00FF & peasycap->field_buffer[peasycap->field_read][0].kount))))))) { SAM("aborted by signal\n"); return -EIO; } @@ -1236,7 +1228,7 @@ int easycap_dqbuf(struct easycap *peasycap, int mode) } if (peasycap->video_eof) { JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof); - #if defined(PERSEVERE) +#if defined(PERSEVERE) if (1 == peasycap->status) { JOM(8, "persevering ...\n"); peasycap->video_eof = 0; @@ -1252,14 +1244,14 @@ int easycap_dqbuf(struct easycap *peasycap, int mode) JOM(8, " ... OK ... returning -EAGAIN\n"); return -EAGAIN; } - #endif /*PERSEVERE*/ +#endif /*PERSEVERE*/ peasycap->video_eof = 1; peasycap->audio_eof = 1; kill_video_urbs(peasycap); JOM(8, "returning -EIO\n"); return -EIO; } - miss++; + miss++; } JOM(8, "second awakening on wq_video after %i waits\n", miss); @@ -1271,11 +1263,12 @@ int easycap_dqbuf(struct easycap *peasycap, int mode) * WASTE THIS FRAME */ /*---------------------------------------------------------------------------*/ - if (0 != peasycap->skip) { + if (peasycap->skip) { peasycap->skipped++; if (peasycap->skip != peasycap->skipped) return peasycap->skip - peasycap->skipped; - peasycap->skipped = 0; + else + peasycap->skipped = 0; } /*---------------------------------------------------------------------------*/ peasycap->frame_read = peasycap->frame_fill; @@ -1432,22 +1425,17 @@ field2frame(struct easycap *peasycap) * CAUSE BREAKAGE. BEWARE. */ rad2 = rad + bytesperpixel - 1; - much = ((((2 * - rad2)/bytesperpixel)/2) * 2); - rump = ((bytesperpixel * - much) / 2) - rad; + much = ((((2 * rad2)/bytesperpixel)/2) * 2); + rump = ((bytesperpixel * much) / 2) - rad; more = rad; - } + } mask = (u8)rump; margin = 0; if (much == rex) { mask |= 0x04; - if ((mex + 1) < FIELD_BUFFER_SIZE/ - PAGE_SIZE) { - margin = *((u8 *)(peasycap-> - field_buffer - [kex][mex + 1].pgo)); - } else + if ((mex + 1) < FIELD_BUFFER_SIZE / PAGE_SIZE) + margin = *((u8 *)(peasycap->field_buffer[kex][mex + 1].pgo)); + else mask |= 0x08; } } else { @@ -1471,20 +1459,16 @@ field2frame(struct easycap *peasycap) SAM("ERROR: redaub() failed\n"); return -EFAULT; } - if (much % 4) { - if (isuy) - isuy = false; - else - isuy = true; - } + if (much % 4) + isuy = !isuy; + over -= much; cz += much; pex += much; rex -= much; if (!rex) { mex++; pex = peasycap->field_buffer[kex][mex].pgo; rex = PAGE_SIZE; - if (peasycap->field_buffer[kex][mex].input != - (0x08|peasycap->input)) + if (peasycap->field_buffer[kex][mex].input != (0x08|peasycap->input)) badinput = true; } pad += more; @@ -1554,22 +1538,17 @@ field2frame(struct easycap *peasycap) * BEWARE. */ rad2 = rad + bytesperpixel - 1; - much = ((((2 * rad2)/bytesperpixel)/2) - * 4); - rump = ((bytesperpixel * - much) / 4) - rad; + much = ((((2 * rad2) / bytesperpixel) / 2) * 4); + rump = ((bytesperpixel * much) / 4) - rad; more = rad; } mask = (u8)rump; margin = 0; if (much == rex) { mask |= 0x04; - if ((mex + 1) < FIELD_BUFFER_SIZE/ - PAGE_SIZE) { - margin = *((u8 *)(peasycap-> - field_buffer - [kex][mex + 1].pgo)); - } else + if ((mex + 1) < FIELD_BUFFER_SIZE / PAGE_SIZE) + margin = *((u8 *)(peasycap->field_buffer[kex][mex + 1].pgo)); + else mask |= 0x08; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -3815,18 +3794,19 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, JOM(4, ".... each occupying contiguous memory pages\n"); for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { - pbuf = (void *)__get_free_pages(GFP_KERNEL, VIDEO_ISOC_ORDER); + pbuf = (void *)__get_free_pages(GFP_KERNEL, + VIDEO_ISOC_ORDER); if (NULL == pbuf) { SAM("ERROR: Could not allocate isoc video buffer " "%i\n", k); return -ENOMEM; } else peasycap->allocation_video_page += - ((unsigned int)(0x01 << VIDEO_ISOC_ORDER)); + BIT(VIDEO_ISOC_ORDER); peasycap->video_isoc_buffer[k].pgo = pbuf; - peasycap->video_isoc_buffer[k].pto = pbuf + - peasycap->video_isoc_buffer_size; + peasycap->video_isoc_buffer[k].pto = + pbuf + peasycap->video_isoc_buffer_size; peasycap->video_isoc_buffer[k].kount = k; } JOM(4, "allocation of isoc video buffers done: %i pages\n", @@ -4052,24 +4032,25 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, peasycap->ilk |= 0x02; SAM("audio hardware is microphone\n"); peasycap->microphone = true; - peasycap->audio_pages_per_fragment = PAGES_PER_AUDIO_FRAGMENT; + peasycap->audio_pages_per_fragment = + PAGES_PER_AUDIO_FRAGMENT; } else if (256 == peasycap->audio_isoc_maxframesize) { peasycap->ilk &= ~0x02; SAM("audio hardware is AC'97\n"); peasycap->microphone = false; - peasycap->audio_pages_per_fragment = PAGES_PER_AUDIO_FRAGMENT; + peasycap->audio_pages_per_fragment = + PAGES_PER_AUDIO_FRAGMENT; } else { SAM("hardware is unidentified:\n"); SAM("%i=audio_isoc_maxframesize\n", - peasycap->audio_isoc_maxframesize); + peasycap->audio_isoc_maxframesize); return -ENOENT; } peasycap->audio_bytes_per_fragment = - peasycap->audio_pages_per_fragment * - PAGE_SIZE ; + peasycap->audio_pages_per_fragment * PAGE_SIZE; peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY * - peasycap->audio_pages_per_fragment); + peasycap->audio_pages_per_fragment); JOM(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY); JOM(4, "%6i=audio_pages_per_fragment\n", @@ -4159,18 +4140,20 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, #endif /* CONFIG_EASYCAP_OSS */ /*---------------------------------------------------------------------------*/ JOM(4, "allocating %i isoc audio buffers of size %i\n", - AUDIO_ISOC_BUFFER_MANY, peasycap->audio_isoc_buffer_size); + AUDIO_ISOC_BUFFER_MANY, + peasycap->audio_isoc_buffer_size); JOM(4, ".... each occupying contiguous memory pages\n"); for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { - pbuf = (void *)__get_free_pages(GFP_KERNEL, AUDIO_ISOC_ORDER); + pbuf = (void *)__get_free_pages(GFP_KERNEL, + AUDIO_ISOC_ORDER); if (NULL == pbuf) { SAM("ERROR: Could not allocate isoc audio buffer " "%i\n", k); return -ENOMEM; } else peasycap->allocation_audio_page += - ((unsigned int)(0x01 << AUDIO_ISOC_ORDER)); + BIT(AUDIO_ISOC_ORDER); peasycap->audio_isoc_buffer[k].pgo = pbuf; peasycap->audio_isoc_buffer[k].pto = pbuf + @@ -4185,15 +4168,15 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, /*---------------------------------------------------------------------------*/ JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY); JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n", - peasycap->audio_isoc_framesperdesc); + peasycap->audio_isoc_framesperdesc); JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n", - peasycap->audio_isoc_maxframesize); + peasycap->audio_isoc_maxframesize); JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n", - peasycap->audio_isoc_buffer_size); + peasycap->audio_isoc_buffer_size); for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc, - GFP_KERNEL); + GFP_KERNEL); if (NULL == purb) { SAM("ERROR: usb_alloc_urb returned NULL for buffer " "%i\n", k); @@ -4230,7 +4213,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, JOM(4, " purb->transfer_buffer = " "peasycap->audio_isoc_buffer[.].pgo;\n"); JOM(4, " purb->transfer_buffer_length = %i;\n", - peasycap->audio_isoc_buffer_size); + peasycap->audio_isoc_buffer_size); #ifdef CONFIG_EASYCAP_OSS JOM(4, " purb->complete = easyoss_complete;\n"); #else /* CONFIG_EASYCAP_OSS */ @@ -4244,9 +4227,9 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, peasycap->audio_isoc_framesperdesc); JOM(4, " {\n"); JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n", - peasycap->audio_isoc_maxframesize); + peasycap->audio_isoc_maxframesize); JOM(4, " purb->iso_frame_desc[j].length = %i;\n", - peasycap->audio_isoc_maxframesize); + peasycap->audio_isoc_maxframesize); JOM(4, " }\n"); } @@ -4418,8 +4401,7 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) if (NULL != peasycap->purb_video_head) { JOM(4, "killing video urbs\n"); m = 0; - list_for_each(plist_head, (peasycap->purb_video_head)) - { + list_for_each(plist_head, peasycap->purb_video_head) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); if (NULL != pdata_urb) { @@ -4438,8 +4420,7 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) if (NULL != peasycap->purb_audio_head) { JOM(4, "killing audio urbs\n"); m = 0; - list_for_each(plist_head, - (peasycap->purb_audio_head)) { + list_for_each(plist_head, peasycap->purb_audio_head) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); if (NULL != pdata_urb) { -- cgit v1.2.3 From 27d683ab79a408a6a48cb01a200af9abf82cca5a Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 3 Mar 2011 00:10:49 +0200 Subject: staging/easycap: replace if(true == var) with if (var) 's/(true == \([^ ]\+\))/(\1)/g' Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_ioctl.c | 14 ++--- drivers/staging/easycap/easycap_low.c | 8 +-- drivers/staging/easycap/easycap_main.c | 98 ++++++++++++++--------------- drivers/staging/easycap/easycap_sound.c | 2 +- drivers/staging/easycap/easycap_sound_oss.c | 16 ++--- 5 files changed, 69 insertions(+), 69 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 8d8d07fd244d..c2f5a78f6db4 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -330,7 +330,7 @@ int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id) JOM(8, "SAA register 0x%02X changed " "from 0x%02X to 0x%02X\n", reg, itwas, isnow); } - if (true == resubmit) + if (resubmit) submit_video_urbs(peasycap); return 0; } @@ -548,7 +548,7 @@ int adjust_format(struct easycap *peasycap, peasycap->offerfields = true; else peasycap->offerfields = false; - if (true == peasycap->decimatepixel) + if (peasycap->decimatepixel) multiplier = 2; else multiplier = 1; @@ -1439,7 +1439,7 @@ long easycap_unlocked_ioctl(struct file *file, int mute; JOM(8, "user requests mute %i\n", v4l2_control.value); - if (true == v4l2_control.value) + if (v4l2_control.value) mute = 1; else mute = 0; @@ -1560,7 +1560,7 @@ long easycap_unlocked_ioctl(struct file *file, v4l2_frmsizeenum.type = (u32) V4L2_FRMSIZE_TYPE_DISCRETE; - if (true == peasycap->ntsc) { + if (peasycap->ntsc) { switch (index) { case 0: { v4l2_frmsizeenum.discrete.width = 640; @@ -1690,7 +1690,7 @@ long easycap_unlocked_ioctl(struct file *file, if (peasycap->fps) denominator = peasycap->fps; else { - if (true == peasycap->ntsc) + if (peasycap->ntsc) denominator = 30; else denominator = 25; @@ -2265,7 +2265,7 @@ long easycap_unlocked_ioctl(struct file *file, v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v4l2_buffer.bytesused = peasycap->frame_buffer_used; v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE; - if (true == peasycap->offerfields) + if (peasycap->offerfields) v4l2_buffer.field = V4L2_FIELD_BOTTOM; else v4l2_buffer.field = V4L2_FIELD_NONE; @@ -2399,7 +2399,7 @@ long easycap_unlocked_ioctl(struct file *file, pv4l2_streamparm->parm.capture.timeperframe. denominator = peasycap->fps; } else { - if (true == peasycap->ntsc) { + if (peasycap->ntsc) { pv4l2_streamparm->parm.capture.timeperframe. denominator = 30; } else { diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index 1f914b428c84..96270e052f36 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -388,7 +388,7 @@ int setup_stk(struct usb_device *p, bool ntsc) if (NULL == p) return -ENODEV; i0 = 0; - if (true == ntsc) { + if (ntsc) { while (0xFFF != stk1160configNTSC[i0].reg) { SET(p, stk1160configNTSC[i0].reg, stk1160configNTSC[i0].set); @@ -414,7 +414,7 @@ int setup_saa(struct usb_device *p, bool ntsc) if (NULL == p) return -ENODEV; i0 = 0; - if (true == ntsc) { + if (ntsc) { while (0xFF != saa7113configNTSC[i0].reg) { ir = write_saa(p, saa7113configNTSC[i0].reg, saa7113configNTSC[i0].set); @@ -552,7 +552,7 @@ int check_saa(struct usb_device *p, bool ntsc) return -ENODEV; i0 = 0; rc = 0; - if (true == ntsc) { + if (ntsc) { while (0xFF != saa7113configNTSC[i0].reg) { if (0x0F == saa7113configNTSC[i0].reg) { i0++; @@ -663,7 +663,7 @@ int check_stk(struct usb_device *p, bool ntsc) if (NULL == p) return -ENODEV; i0 = 0; - if (true == ntsc) { + if (ntsc) { while (0xFFF != stk1160configNTSC[i0].reg) { if (0x000 == stk1160configNTSC[i0].reg) { i0++; continue; diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 83aa6ee0dcd7..7f59b948ded9 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -247,7 +247,7 @@ static int reset(struct easycap *peasycap) rate = ready_saa(peasycap->pusb_device); if (0 > rate) { JOM(8, "not ready to capture after %i ms ...\n", PATIENCE); - if (true == peasycap->ntsc) { + if (peasycap->ntsc) { JOM(8, "... trying PAL ...\n"); ntsc = false; } else { JOM(8, "... trying NTSC ...\n"); ntsc = true; @@ -566,7 +566,7 @@ newinput(struct easycap *peasycap, int input) SAM("ERROR: start_100() rc = %i\n", rc); return -EFAULT; } - if (true == resubmit) + if (resubmit) submit_video_urbs(peasycap); peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1; @@ -1335,7 +1335,7 @@ field2frame(struct easycap *peasycap) peasycap->field_buffer[peasycap->field_read][0].input, peasycap->field_read, peasycap->frame_fill); JOM(8, "===== %i=bytesperpixel\n", peasycap->bytesperpixel); - if (true == peasycap->offerfields) + if (peasycap->offerfields) JOM(8, "===== offerfields\n"); /*---------------------------------------------------------------------------*/ @@ -1368,7 +1368,7 @@ field2frame(struct easycap *peasycap) SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel); return -EFAULT; } - if (true == decimatepixel) + if (decimatepixel) multiplier = 2; else multiplier = 1; @@ -1385,7 +1385,7 @@ field2frame(struct easycap *peasycap) pad = peasycap->frame_buffer[kad][0].pgo; rad = PAGE_SIZE; odd = !!(peasycap->field_buffer[kex][0].kount); - if ((true == odd) && (false == decimatepixel)) { + if (odd && (false == decimatepixel)) { JOM(8, "initial skipping %4i bytes p.%4i\n", w3/multiplier, mad); pad += (w3 / multiplier); rad -= (w3 / multiplier); @@ -1445,7 +1445,7 @@ field2frame(struct easycap *peasycap) } if (rump) caches++; - if (true == badinput) { + if (badinput) { JOM(8, "ERROR: 0x%02X=->field_buffer" "[%i][%i].input, " "0x%02X=(0x08|->input)\n", @@ -1561,7 +1561,7 @@ field2frame(struct easycap *peasycap) if (rump) caches++; - if (true == badinput) { + if (badinput) { JOM(8, "ERROR: 0x%02X=->field_buffer" "[%i][%i].input, " "0x%02X=(0x08|->input)\n", @@ -1663,7 +1663,7 @@ field2frame(struct easycap *peasycap) JOM(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2, c3); JOM(8, "===== field2frame(): %i=mad %i=rad\n", mad, rad); - if (true == odd) + if (odd) JOM(8, "+++++ field2frame(): frame buffer %i is full\n", kad); if (peasycap->field_read == peasycap->field_fill) @@ -1819,7 +1819,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, p2 = (u8 *)pex; pz = p2 + much; pr = p3 + more; last = false; p2++; - if (true == isuy) + if (isuy) u = *(p2 - 1); else v = *(p2 - 1); @@ -1884,9 +1884,9 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, else last = false; y = *p2; - if ((true == last) && (0x0C & mask)) { + if (last && (0x0C & mask)) { if (0x04 & mask) { - if (true == isuy) + if (isuy) v = margin; else u = margin; @@ -1894,7 +1894,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, if (0x08 & mask) ; } else { - if (true == isuy) + if (isuy) v = *(p2 + 1); else u = *(p2 + 1); @@ -1910,7 +1910,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, b = (255 < tmp) ? 255 : ((0 > tmp) ? 0 : (u8)tmp); - if ((true == last) && rump) { + if (last && rump) { pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { @@ -1937,7 +1937,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, *(p3 + 2) = b; } p2 += 2; - if (true == isuy) + if (isuy) isuy = false; else isuy = true; @@ -1952,9 +1952,9 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, else last = false; y = *p2; - if ((true == last) && (0x0C & mask)) { + if (last && (0x0C & mask)) { if (0x04 & mask) { - if (true == isuy) + if (isuy) v = margin; else u = margin; @@ -1963,7 +1963,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, if (0x08 & mask) ; } else { - if (true == isuy) + if (isuy) v = *(p2 + 1); else u = *(p2 + 1); @@ -1979,7 +1979,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, b = (255 < tmp) ? 255 : ((0 > tmp) ? 0 : (u8)tmp); - if ((true == last) && rump) { + if (last && rump) { pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { @@ -2006,7 +2006,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, *(p3 + 2) = r; } p2 += 2; - if (true == isuy) + if (isuy) isuy = false; else isuy = true; @@ -2023,9 +2023,9 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, else last = false; y = *p2; - if ((true == last) && (0x0C & mask)) { + if (last && (0x0C & mask)) { if (0x04 & mask) { - if (true == isuy) + if (isuy) v = margin; else u = margin; @@ -2033,13 +2033,13 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, if (0x08 & mask) ; } else { - if (true == isuy) + if (isuy) v = *(p2 + 1); else u = *(p2 + 1); } - if (true == isuy) { + if (isuy) { tmp = ay[(int)y] + rv[(int)v]; r = (255 < tmp) ? 255 : ((0 > tmp) ? 0 : (u8)tmp); @@ -2051,7 +2051,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, b = (255 < tmp) ? 255 : ((0 > tmp) ? 0 : (u8)tmp); - if ((true == last) && rump) { + if (last && rump) { pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { @@ -2094,9 +2094,9 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, else last = false; y = *p2; - if ((true == last) && (0x0C & mask)) { + if (last && (0x0C & mask)) { if (0x04 & mask) { - if (true == isuy) + if (isuy) v = margin; else u = margin; @@ -2104,13 +2104,13 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, if (0x08 & mask) ; } else { - if (true == isuy) + if (isuy) v = *(p2 + 1); else u = *(p2 + 1); } - if (true == isuy) { + if (isuy) { tmp = ay[(int)y] + rv[(int)v]; r = (255 < tmp) ? 255 : ((0 > tmp) ? @@ -2123,7 +2123,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, b = (255 < tmp) ? 255 : ((0 > tmp) ? 0 : (u8)tmp); - if ((true == last) && rump) { + if (last && rump) { pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { @@ -2173,9 +2173,9 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, else last = false; y = *p2; - if ((true == last) && (0x0C & mask)) { + if (last && (0x0C & mask)) { if (0x04 & mask) { - if (true == isuy) + if (isuy) v = margin; else u = margin; @@ -2183,7 +2183,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, if (0x08 & mask) ; } else { - if (true == isuy) + if (isuy) v = *(p2 + 1); else u = *(p2 + 1); @@ -2199,7 +2199,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, b = (255 < tmp) ? 255 : ((0 > tmp) ? 0 : (u8)tmp); - if ((true == last) && rump) { + if (last && rump) { pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { @@ -2236,7 +2236,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, *(p3 + 3) = 0; } p2 += 2; - if (true == isuy) + if (isuy) isuy = false; else isuy = true; @@ -2253,9 +2253,9 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, else last = false; y = *p2; - if ((true == last) && (0x0C & mask)) { + if (last && (0x0C & mask)) { if (0x04 & mask) { - if (true == isuy) + if (isuy) v = margin; else u = margin; @@ -2263,7 +2263,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, if (0x08 & mask) ; } else { - if (true == isuy) + if (isuy) v = *(p2 + 1); else u = *(p2 + 1); @@ -2279,7 +2279,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, b = (255 < tmp) ? 255 : ((0 > tmp) ? 0 : (u8)tmp); - if ((true == last) && rump) { + if (last && rump) { pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { @@ -2315,7 +2315,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, *(p3 + 3) = 0; } p2 += 2; - if (true == isuy) + if (isuy) isuy = false; else isuy = true; @@ -2334,9 +2334,9 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, else last = false; y = *p2; - if ((true == last) && (0x0C & mask)) { + if (last && (0x0C & mask)) { if (0x04 & mask) { - if (true == isuy) + if (isuy) v = margin; else u = margin; @@ -2344,13 +2344,13 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, if (0x08 & mask) ; } else { - if (true == isuy) + if (isuy) v = *(p2 + 1); else u = *(p2 + 1); } - if (true == isuy) { + if (isuy) { tmp = ay[(int)y] + rv[(int)v]; r = (255 < tmp) ? 255 : ((0 > tmp) ? @@ -2363,7 +2363,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, b = (255 < tmp) ? 255 : ((0 > tmp) ? 0 : (u8)tmp); - if ((true == last) && rump) { + if (last && rump) { pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { @@ -2418,9 +2418,9 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, else last = false; y = *p2; - if ((true == last) && (0x0C & mask)) { + if (last && (0x0C & mask)) { if (0x04 & mask) { - if (true == isuy) + if (isuy) v = margin; else u = margin; @@ -2428,13 +2428,13 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, if (0x08 & mask) ; } else { - if (true == isuy) + if (isuy) v = *(p2 + 1); else u = *(p2 + 1); } - if (true == isuy) { + if (isuy) { tmp = ay[(int)y] + rv[(int)v]; r = (255 < tmp) ? 255 : ((0 > tmp) ? 0 : (u8)tmp); @@ -2446,7 +2446,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, b = (255 < tmp) ? 255 : ((0 > tmp) ? 0 : (u8)tmp); - if ((true == last) && rump) { + if (last && rump) { pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index 86b9ae0366d0..8fc2f16387df 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -598,7 +598,7 @@ int easycap_alsa_probe(struct easycap *peasycap) } peasycap->alsa_hardware = alsa_hardware; - if (true == peasycap->microphone) { + if (peasycap->microphone) { peasycap->alsa_hardware.rates = SNDRV_PCM_RATE_32000; peasycap->alsa_hardware.rate_min = 32000; peasycap->alsa_hardware.rate_max = 32000; diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c index e36f341ae118..71776fc0dc3c 100644 --- a/drivers/staging/easycap/easycap_sound_oss.c +++ b/drivers/staging/easycap/easycap_sound_oss.c @@ -734,12 +734,12 @@ static long easyoss_unlocked_ioctl(struct file *file, JOM(8, "SNDCTL_DSP_GETCAPS\n"); #ifdef UPSAMPLE - if (true == peasycap->microphone) + if (peasycap->microphone) caps = 0x04400000; else caps = 0x04400000; #else - if (true == peasycap->microphone) + if (peasycap->microphone) caps = 0x02400000; else caps = 0x04400000; @@ -783,12 +783,12 @@ static long easyoss_unlocked_ioctl(struct file *file, JOM(8, "........... %i=incoming\n", incoming); #ifdef UPSAMPLE - if (true == peasycap->microphone) + if (peasycap->microphone) outgoing = AFMT_S16_LE; else outgoing = AFMT_S16_LE; #else - if (true == peasycap->microphone) + if (peasycap->microphone) outgoing = AFMT_S16_LE; else outgoing = AFMT_S16_LE; @@ -817,12 +817,12 @@ static long easyoss_unlocked_ioctl(struct file *file, JOM(8, "........... %i=incoming\n", incoming); #ifdef UPSAMPLE - if (true == peasycap->microphone) + if (peasycap->microphone) incoming = 1; else incoming = 1; #else - if (true == peasycap->microphone) + if (peasycap->microphone) incoming = 0; else incoming = 1; @@ -844,12 +844,12 @@ static long easyoss_unlocked_ioctl(struct file *file, JOM(8, "........... %i=incoming\n", incoming); #ifdef UPSAMPLE - if (true == peasycap->microphone) + if (peasycap->microphone) incoming = 32000; else incoming = 48000; #else - if (true == peasycap->microphone) + if (peasycap->microphone) incoming = 8000; else incoming = 48000; -- cgit v1.2.3 From febd32bcfd09aeb543b229fd2896814a26d74d20 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 3 Mar 2011 00:10:50 +0200 Subject: staging/easycap: replace if(false == var) with if (!var) 's/(false == \([^ ]\+\))/(!\1)/g' Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_main.c | 30 ++++++++++++++--------------- drivers/staging/easycap/easycap_sound.c | 2 +- drivers/staging/easycap/easycap_sound_oss.c | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 7f59b948ded9..5c092503f39b 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -1385,7 +1385,7 @@ field2frame(struct easycap *peasycap) pad = peasycap->frame_buffer[kad][0].pgo; rad = PAGE_SIZE; odd = !!(peasycap->field_buffer[kex][0].kount); - if (odd && (false == decimatepixel)) { + if (odd && (!decimatepixel)) { JOM(8, "initial skipping %4i bytes p.%4i\n", w3/multiplier, mad); pad += (w3 / multiplier); rad -= (w3 / multiplier); @@ -1400,7 +1400,7 @@ field2frame(struct easycap *peasycap) * READ w2 BYTES FROM FIELD BUFFER, * WRITE w3 BYTES TO FRAME BUFFER */ - if (false == decimatepixel) { + if (!decimatepixel) { over = w2; do { much = over; more = 0; @@ -1489,7 +1489,7 @@ field2frame(struct easycap *peasycap) * UNLESS IT IS THE LAST LINE OF AN ODD FRAME */ /*---------------------------------------------------------------------------*/ - if ((false == odd) || (cz != wz)) { + if (!odd || (cz != wz)) { over = w3; do { if (!rad) { @@ -1514,7 +1514,7 @@ field2frame(struct easycap *peasycap) * WRITE w3 / 2 BYTES TO FRAME BUFFER */ /*---------------------------------------------------------------------------*/ - } else if (false == odd) { + } else if (!odd) { over = w2; do { much = over; more = 0; margin = 0; mask = 0x00; @@ -1641,12 +1641,12 @@ field2frame(struct easycap *peasycap) SAM("ERROR: discrepancy %i in bytes read\n", c2 - cz); c3 = (mad + 1)*PAGE_SIZE - rad; - if (false == decimatepixel) { + if (!decimatepixel) { if (bytesperpixel * cz != c3) SAM("ERROR: discrepancy %i in bytes written\n", c3 - (bytesperpixel * cz)); } else { - if (false == odd) { + if (!odd) { if (bytesperpixel * cz != (4 * c3)) SAM("ERROR: discrepancy %i in bytes written\n", @@ -1830,9 +1830,9 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, /*---------------------------------------------------------------------------*/ switch (bytesperpixel) { case 2: { - if (false == decimatepixel) { + if (!decimatepixel) { memcpy(pad, pex, (size_t)much); - if (false == byteswaporder) { + if (!byteswaporder) { /* UYVY */ return 0; } else { @@ -1847,7 +1847,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, return 0; } } else { - if (false == byteswaporder) { + if (!byteswaporder) { /* UYVY DECIMATED */ p2 = (u8 *)pex; p3 = (u8 *)pad; pz = p2 + much; while (pz > p2) { @@ -1875,8 +1875,8 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, } case 3: { - if (false == decimatepixel) { - if (false == byteswaporder) { + if (!decimatepixel) { + if (!byteswaporder) { /* RGB */ while (pz > p2) { if (pr <= (p3 + bytesperpixel)) @@ -2015,7 +2015,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, } return 0; } else { - if (false == byteswaporder) { + if (!byteswaporder) { /* RGB DECIMATED */ while (pz > p2) { if (pr <= (p3 + bytesperpixel)) @@ -2164,8 +2164,8 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, } case 4: { - if (false == decimatepixel) { - if (false == byteswaporder) { + if (!decimatepixel) { + if (!byteswaporder) { /* RGBA */ while (pz > p2) { if (pr <= (p3 + bytesperpixel)) @@ -2324,7 +2324,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, } return 0; } else { - if (false == byteswaporder) { + if (!byteswaporder) { /* * RGBA DECIMATED */ diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index 8fc2f16387df..d0ef7af8151e 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -177,7 +177,7 @@ easycap_alsa_complete(struct urb *purb) peasycap->dma_next = fragment_bytes; JOM(8, "wrapped dma buffer\n"); } - if (false == peasycap->microphone) { + if (!peasycap->microphone) { if (much > more) much = more; memcpy(prt->dma_area + diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c index 71776fc0dc3c..3e033edc8ede 100644 --- a/drivers/staging/easycap/easycap_sound_oss.c +++ b/drivers/staging/easycap/easycap_sound_oss.c @@ -178,7 +178,7 @@ easyoss_complete(struct urb *purb) much = PAGE_SIZE - (int)(paudio_buffer->pto - paudio_buffer->pgo); - if (false == peasycap->microphone) { + if (!peasycap->microphone) { if (much > more) much = more; -- cgit v1.2.3 From 6888393c43c95a40d551989e89cbf572423619e6 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 3 Mar 2011 00:10:51 +0200 Subject: staging/easycap: convert comparison to NULL into boolean convert if (NULL != ptr) to if (ptr) convert if (NULL == ptr) to if (!ptr) Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_ioctl.c | 52 ++++----- drivers/staging/easycap/easycap_low.c | 48 ++++----- drivers/staging/easycap/easycap_main.c | 162 ++++++++++++++-------------- drivers/staging/easycap/easycap_sound.c | 80 +++++++------- drivers/staging/easycap/easycap_sound_oss.c | 48 ++++----- drivers/staging/easycap/easycap_testcard.c | 2 +- 6 files changed, 196 insertions(+), 196 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index c2f5a78f6db4..64e7ecd4169f 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -48,11 +48,11 @@ int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id) unsigned int itwas, isnow; bool resubmit; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -370,7 +370,7 @@ int adjust_format(struct easycap *peasycap, u32 uc; bool resubmit; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } @@ -379,7 +379,7 @@ int adjust_format(struct easycap *peasycap, return -EBUSY; } p = peasycap->pusb_device; - if (NULL == p) { + if (!p) { SAM("ERROR: peaycap->pusb_device is NULL\n"); return -EFAULT; } @@ -491,7 +491,7 @@ int adjust_format(struct easycap *peasycap, return peasycap->format_offset; } } - if (NULL == peasycap_best_format) { + if (!peasycap_best_format) { SAM("MISTAKE: peasycap_best_format is NULL"); return -EINVAL; } @@ -632,11 +632,11 @@ int adjust_brightness(struct easycap *peasycap, int value) unsigned int mood; int i1, k; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -689,11 +689,11 @@ int adjust_contrast(struct easycap *peasycap, int value) unsigned int mood; int i1, k; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -747,11 +747,11 @@ int adjust_saturation(struct easycap *peasycap, int value) unsigned int mood; int i1, k; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -805,11 +805,11 @@ int adjust_hue(struct easycap *peasycap, int value) unsigned int mood; int i1, i2, k; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -859,11 +859,11 @@ int adjust_volume(struct easycap *peasycap, int value) s8 mood; int i1; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -916,11 +916,11 @@ static int adjust_mute(struct easycap *peasycap, int value) { int i1; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -958,12 +958,12 @@ long easycap_unlocked_ioctl(struct file *file, struct usb_device *p; int kd; - if (NULL == file) { + if (!file) { SAY("ERROR: file is NULL\n"); return -ERESTARTSYS; } peasycap = file->private_data; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -1; } @@ -972,7 +972,7 @@ long easycap_unlocked_ioctl(struct file *file, return -EFAULT; } p = peasycap->pusb_device; - if (NULL == p) { + if (!p) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -993,13 +993,13 @@ long easycap_unlocked_ioctl(struct file *file, /*---------------------------------------------------------------------------*/ if (kd != isdongle(peasycap)) return -ERESTARTSYS; - if (NULL == file) { + if (!file) { SAY("ERROR: file is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; } peasycap = file->private_data; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; @@ -1010,7 +1010,7 @@ long easycap_unlocked_ioctl(struct file *file, return -EFAULT; } p = peasycap->pusb_device; - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; @@ -2325,7 +2325,7 @@ long easycap_unlocked_ioctl(struct file *file, peasycap->isequence = 0; for (i = 0; i < 180; i++) peasycap->merit[i] = 0; - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -2341,7 +2341,7 @@ long easycap_unlocked_ioctl(struct file *file, case VIDIOC_STREAMOFF: { JOM(8, "VIDIOC_STREAMOFF\n"); - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; @@ -2362,7 +2362,7 @@ long easycap_unlocked_ioctl(struct file *file, wake_up_interruptible(&(peasycap->wq_audio)); #else - if (NULL != peasycap->psubstream) + if (peasycap->psubstream) snd_pcm_period_elapsed(peasycap->psubstream); #endif /* CONFIG_EASYCAP_OSS */ /*---------------------------------------------------------------------------*/ diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index 96270e052f36..403415ee191d 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -330,7 +330,7 @@ int confirm_resolution(struct usb_device *p) { u8 get0, get1, get2, get3, get4, get5, get6, get7; - if (NULL == p) + if (!p) return -ENODEV; GET(p, 0x0110, &get0); GET(p, 0x0111, &get1); @@ -371,7 +371,7 @@ int confirm_stream(struct usb_device *p) u16 get2; u8 igot; - if (NULL == p) + if (!p) return -ENODEV; GET(p, 0x0100, &igot); get2 = 0x80 & igot; if (0x80 == get2) @@ -385,7 +385,7 @@ int setup_stk(struct usb_device *p, bool ntsc) { int i0; - if (NULL == p) + if (!p) return -ENODEV; i0 = 0; if (ntsc) { @@ -411,7 +411,7 @@ int setup_saa(struct usb_device *p, bool ntsc) { int i0, ir; - if (NULL == p) + if (!p) return -ENODEV; i0 = 0; if (ntsc) { @@ -434,7 +434,7 @@ int write_000(struct usb_device *p, u16 set2, u16 set0) { u8 igot0, igot2; - if (NULL == p) + if (!p) return -ENODEV; GET(p, 0x0002, &igot2); GET(p, 0x0000, &igot0); @@ -445,7 +445,7 @@ int write_000(struct usb_device *p, u16 set2, u16 set0) /****************************************************************************/ int write_saa(struct usb_device *p, u16 reg0, u16 set0) { - if (NULL == p) + if (!p) return -ENODEV; SET(p, 0x200, 0x00); SET(p, 0x204, reg0); @@ -470,7 +470,7 @@ write_vt(struct usb_device *p, u16 reg0, u16 set0) u16 got502, got503; u16 set502, set503; - if (NULL == p) + if (!p) return -ENODEV; SET(p, 0x0504, reg0); SET(p, 0x0500, 0x008B); @@ -506,7 +506,7 @@ int read_vt(struct usb_device *p, u16 reg0) u8 igot; u16 got502, got503; - if (NULL == p) + if (!p) return -ENODEV; SET(p, 0x0504, reg0); SET(p, 0x0500, 0x008B); @@ -527,7 +527,7 @@ int read_vt(struct usb_device *p, u16 reg0) /*--------------------------------------------------------------------------*/ int write_300(struct usb_device *p) { - if (NULL == p) + if (!p) return -ENODEV; SET(p, 0x300, 0x0012); SET(p, 0x350, 0x002D); @@ -548,7 +548,7 @@ int check_saa(struct usb_device *p, bool ntsc) { int i0, ir, rc; - if (NULL == p) + if (!p) return -ENODEV; i0 = 0; rc = 0; @@ -597,7 +597,7 @@ int merit_saa(struct usb_device *p) { int rc; - if (NULL == p) + if (!p) return -ENODEV; rc = read_saa(p, 0x1F); return ((0 > rc) || (0x02 & rc)) ? 1 : 0; @@ -615,7 +615,7 @@ int ready_saa(struct usb_device *p) * 3 FOR NON-INTERLACED 60 Hz */ /*--------------------------------------------------------------------------*/ - if (NULL == p) + if (!p) return -ENODEV; j = 0; while (max > j) { @@ -660,7 +660,7 @@ int check_stk(struct usb_device *p, bool ntsc) { int i0, ir; - if (NULL == p) + if (!p) return -ENODEV; i0 = 0; if (ntsc) { @@ -731,7 +731,7 @@ int read_saa(struct usb_device *p, u16 reg0) { u8 igot; - if (NULL == p) + if (!p) return -ENODEV; SET(p, 0x208, reg0); SET(p, 0x200, 0x20); @@ -746,7 +746,7 @@ int read_stk(struct usb_device *p, u32 reg0) { u8 igot; - if (NULL == p) + if (!p) return -ENODEV; igot = 0; GET(p, reg0, &igot); @@ -776,7 +776,7 @@ select_input(struct usb_device *p, int input, int mode) { int ir; - if (NULL == p) + if (!p) return -ENODEV; stop_100(p); switch (input) { @@ -879,7 +879,7 @@ int set_resolution(struct usb_device *p, { u16 u0x0111, u0x0113, u0x0115, u0x0117; - if (NULL == p) + if (!p) return -ENODEV; u0x0111 = ((0xFF00 & set0) >> 8); u0x0113 = ((0xFF00 & set1) >> 8); @@ -903,7 +903,7 @@ int start_100(struct usb_device *p) u16 get116, get117, get0; u8 igot116, igot117, igot; - if (NULL == p) + if (!p) return -ENODEV; GET(p, 0x0116, &igot116); get116 = igot116; @@ -927,7 +927,7 @@ int stop_100(struct usb_device *p) u16 get0; u8 igot; - if (NULL == p) + if (!p) return -ENODEV; GET(p, 0x0100, &igot); get0 = igot; @@ -947,7 +947,7 @@ int wait_i2c(struct usb_device *p) const int max = 2; int k; - if (NULL == p) + if (!p) return -ENODEV; for (k = 0; k < max; k++) { @@ -1000,11 +1000,11 @@ audio_setup(struct easycap *peasycap) const u16 index = 0x0301; const u16 length = 1; - if (NULL == peasycap) + if (!peasycap) return -EFAULT; pusb_device = peasycap->pusb_device; - if (NULL == pusb_device) + if (!pusb_device) return -ENODEV; JOM(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n", @@ -1143,7 +1143,7 @@ int audio_gainset(struct usb_device *pusb_device, s8 loud) u8 tmp; u16 mute; - if (NULL == pusb_device) + if (!pusb_device) return -ENODEV; if (0 > loud) loud = 0; @@ -1209,7 +1209,7 @@ int audio_gainget(struct usb_device *pusb_device) { int igot; - if (NULL == pusb_device) + if (!pusb_device) return -ENODEV; igot = read_vt(pusb_device, 0x001C); if (0 > igot) diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 5c092503f39b..d4d58e4bfe78 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -128,7 +128,7 @@ const char *strerror(int err) int isdongle(struct easycap *peasycap) { int k; - if (NULL == peasycap) + if (!peasycap) return -2; for (k = 0; k < DONGLE_MANY; k++) { if (easycapdc60_dongle[k].peasycap == peasycap) { @@ -154,7 +154,7 @@ static int easycap_open(struct inode *inode, struct file *file) /*---------------------------------------------------------------------------*/ #ifndef EASYCAP_IS_VIDEODEV_CLIENT - if (NULL == inode) { + if (!inode) { SAY("ERROR: inode is NULL.\n"); return -EFAULT; } @@ -167,13 +167,13 @@ static int easycap_open(struct inode *inode, struct file *file) /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #else pvideo_device = video_devdata(file); - if (NULL == pvideo_device) { + if (!pvideo_device) { SAY("ERROR: pvideo_device is NULL.\n"); return -EFAULT; } peasycap = (struct easycap *)video_get_drvdata(pvideo_device); #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } @@ -181,7 +181,7 @@ static int easycap_open(struct inode *inode, struct file *file) SAY("ERROR: bad peasycap: %p\n", peasycap); return -EFAULT; } - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } else { @@ -224,7 +224,7 @@ static int reset(struct easycap *peasycap) bool ntsc, other; int fmtidx; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } @@ -406,7 +406,7 @@ newinput(struct easycap *peasycap, int input) int inputnow, video_idlenow, audio_idlenow; bool resubmit; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } @@ -437,7 +437,7 @@ newinput(struct easycap *peasycap, int input) resubmit = false; } /*---------------------------------------------------------------------------*/ - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -ENODEV; } @@ -550,7 +550,7 @@ newinput(struct easycap *peasycap, int input) return -ENOENT; } /*---------------------------------------------------------------------------*/ - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -ENODEV; } @@ -585,16 +585,16 @@ int submit_video_urbs(struct easycap *peasycap) int j, isbad, nospc, m, rc; int isbuf; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } - if (NULL == peasycap->purb_video_head) { + if (!peasycap->purb_video_head) { SAY("ERROR: peasycap->urb_video_head uninitialized\n"); return -EFAULT; } - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAY("ERROR: peasycap->pusb_device is NULL\n"); return -ENODEV; } @@ -656,9 +656,9 @@ int submit_video_urbs(struct easycap *peasycap) list_for_each(plist_head, (peasycap->purb_video_head)) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (NULL != pdata_urb) { + if (pdata_urb) { purb = pdata_urb->purb; - if (NULL != purb) + if (purb) usb_kill_urb(purb); } } @@ -679,7 +679,7 @@ int kill_video_urbs(struct easycap *peasycap) struct list_head *plist_head; struct data_urb *pdata_urb; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } @@ -717,7 +717,7 @@ static int easycap_release(struct inode *inode, struct file *file) peasycap = file->private_data; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL.\n"); SAY("ending unsuccessfully\n"); return -EFAULT; @@ -750,7 +750,7 @@ static int videodev_release(struct video_device *pvideo_device) struct easycap *peasycap; peasycap = video_get_drvdata(pvideo_device); - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); SAY("ending unsuccessfully\n"); return -EFAULT; @@ -793,7 +793,7 @@ static void easycap_delete(struct kref *pkref) int registered_video, registered_audio; peasycap = container_of(pkref, struct easycap, kref); - if (NULL == peasycap) { + if (!peasycap) { SAM("ERROR: peasycap is NULL: cannot perform deletions\n"); return; } @@ -807,16 +807,16 @@ static void easycap_delete(struct kref *pkref) * FREE VIDEO. */ /*---------------------------------------------------------------------------*/ - if (NULL != peasycap->purb_video_head) { + if (peasycap->purb_video_head) { JOM(4, "freeing video urbs\n"); m = 0; list_for_each(plist_head, (peasycap->purb_video_head)) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (NULL == pdata_urb) { + if (!pdata_urb) { JOM(4, "ERROR: pdata_urb is NULL\n"); } else { - if (NULL != pdata_urb->purb) { + if (pdata_urb->purb) { usb_free_urb(pdata_urb->purb); pdata_urb->purb = NULL; peasycap->allocation_video_urb -= 1; @@ -866,7 +866,7 @@ static void easycap_delete(struct kref *pkref) gone = 0; for (k = 0; k < FIELD_BUFFER_MANY; k++) { for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { - if (NULL != peasycap->field_buffer[k][m].pgo) { + if (peasycap->field_buffer[k][m].pgo) { free_page((unsigned long) peasycap->field_buffer[k][m].pgo); peasycap->field_buffer[k][m].pgo = NULL; @@ -881,7 +881,7 @@ static void easycap_delete(struct kref *pkref) gone = 0; for (k = 0; k < FRAME_BUFFER_MANY; k++) { for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { - if (NULL != peasycap->frame_buffer[k][m].pgo) { + if (peasycap->frame_buffer[k][m].pgo) { free_page((unsigned long) peasycap->frame_buffer[k][m].pgo); peasycap->frame_buffer[k][m].pgo = NULL; @@ -896,16 +896,16 @@ static void easycap_delete(struct kref *pkref) * FREE AUDIO. */ /*---------------------------------------------------------------------------*/ - if (NULL != peasycap->purb_audio_head) { + if (peasycap->purb_audio_head) { JOM(4, "freeing audio urbs\n"); m = 0; list_for_each(plist_head, (peasycap->purb_audio_head)) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (NULL == pdata_urb) + if (!pdata_urb) JOM(4, "ERROR: pdata_urb is NULL\n"); else { - if (NULL != pdata_urb->purb) { + if (pdata_urb->purb) { usb_free_urb(pdata_urb->purb); pdata_urb->purb = NULL; peasycap->allocation_audio_urb -= 1; @@ -937,7 +937,7 @@ static void easycap_delete(struct kref *pkref) JOM(4, "freeing audio isoc buffers.\n"); m = 0; for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { - if (NULL != peasycap->audio_isoc_buffer[k].pgo) { + if (peasycap->audio_isoc_buffer[k].pgo) { free_pages((unsigned long) (peasycap->audio_isoc_buffer[k].pgo), AUDIO_ISOC_ORDER); @@ -954,7 +954,7 @@ static void easycap_delete(struct kref *pkref) JOM(4, "freeing audio buffers.\n"); gone = 0; for (k = 0; k < peasycap->audio_buffer_page_many; k++) { - if (NULL != peasycap->audio_buffer[k].pgo) { + if (peasycap->audio_buffer[k].pgo) { free_page((unsigned long)peasycap->audio_buffer[k].pgo); peasycap->audio_buffer[k].pgo = NULL; peasycap->allocation_audio_page -= 1; @@ -1013,12 +1013,12 @@ static unsigned int easycap_poll(struct file *file, poll_table *wait) if (NULL == ((poll_table *)wait)) JOT(8, "WARNING: poll table pointer is NULL ... continuing\n"); - if (NULL == file) { + if (!file) { SAY("ERROR: file pointer is NULL\n"); return -ERESTARTSYS; } peasycap = file->private_data; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } @@ -1026,7 +1026,7 @@ static unsigned int easycap_poll(struct file *file, poll_table *wait) SAY("ERROR: bad peasycap: %p\n", peasycap); return -EFAULT; } - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAY("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -1045,13 +1045,13 @@ static unsigned int easycap_poll(struct file *file, poll_table *wait) */ if (kd != isdongle(peasycap)) return -ERESTARTSYS; - if (NULL == file) { + if (!file) { SAY("ERROR: file is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; } peasycap = file->private_data; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; @@ -1061,7 +1061,7 @@ static unsigned int easycap_poll(struct file *file, poll_table *wait) mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; } - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; @@ -1093,11 +1093,11 @@ int easycap_dqbuf(struct easycap *peasycap, int mode) int input, ifield, miss, rc; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAY("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -1321,7 +1321,7 @@ field2frame(struct easycap *peasycap) u8 mask, margin; bool odd, isuy, decimatepixel, offerfields, badinput; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } @@ -1789,7 +1789,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, JOM(8, "lookup tables are prepared\n"); } pcache = peasycap->pcache; - if (NULL == pcache) + if (!pcache) pcache = &peasycap->cache[0]; /*---------------------------------------------------------------------------*/ /* @@ -2511,7 +2511,7 @@ static void easycap_vma_open(struct vm_area_struct *pvma) struct easycap *peasycap; peasycap = pvma->vm_private_data; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return; } @@ -2529,7 +2529,7 @@ static void easycap_vma_close(struct vm_area_struct *pvma) struct easycap *peasycap; peasycap = pvma->vm_private_data; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return; } @@ -2551,11 +2551,11 @@ static int easycap_vma_fault(struct vm_area_struct *pvma, struct vm_fault *pvmf) retcode = VM_FAULT_NOPAGE; - if (NULL == pvma) { + if (!pvma) { SAY("pvma is NULL\n"); return retcode; } - if (NULL == pvmf) { + if (!pvmf) { SAY("pvmf is NULL\n"); return retcode; } @@ -2577,24 +2577,24 @@ static int easycap_vma_fault(struct vm_area_struct *pvma, struct vm_fault *pvmf) return retcode; } peasycap = pvma->vm_private_data; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return retcode; } /*---------------------------------------------------------------------------*/ pbuf = peasycap->frame_buffer[k][m].pgo; - if (NULL == pbuf) { + if (!pbuf) { SAM("ERROR: pbuf is NULL\n"); return retcode; } page = virt_to_page(pbuf); - if (NULL == page) { + if (!page) { SAM("ERROR: page is NULL\n"); return retcode; } get_page(page); /*---------------------------------------------------------------------------*/ - if (NULL == page) { + if (!page) { SAM("ERROR: page is NULL after get_page(page)\n"); } else { pvmf->page = page; @@ -2615,7 +2615,7 @@ static int easycap_mmap(struct file *file, struct vm_area_struct *pvma) pvma->vm_ops = &easycap_vm_ops; pvma->vm_flags |= VM_RESERVED; - if (NULL != file) + if (file) pvma->vm_private_data = file->private_data; easycap_vma_open(pvma); return 0; @@ -2658,12 +2658,12 @@ static void easycap_complete(struct urb *purb) int framestatus, framelength, frameactual, frameoffset; u8 *pu; - if (NULL == purb) { + if (!purb) { SAY("ERROR: easycap_complete(): purb is NULL\n"); return; } peasycap = purb->context; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: easycap_complete(): peasycap is NULL\n"); return; } @@ -3089,12 +3089,12 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, JOT(4, "bNumConfigurations=%i\n", pusb_device->descriptor.bNumConfigurations); /*---------------------------------------------------------------------------*/ pusb_host_interface = pusb_interface->cur_altsetting; - if (NULL == pusb_host_interface) { + if (!pusb_host_interface) { SAY("ERROR: pusb_host_interface is NULL\n"); return -EFAULT; } pusb_interface_descriptor = &(pusb_host_interface->desc); - if (NULL == pusb_interface_descriptor) { + if (!pusb_interface_descriptor) { SAY("ERROR: pusb_interface_descriptor is NULL\n"); return -EFAULT; } @@ -3128,7 +3128,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, /*---------------------------------------------------------------------------*/ if (0 == bInterfaceNumber) { peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL); - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: Could not allocate peasycap\n"); return -ENOMEM; } @@ -3166,7 +3166,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, */ /*---------------------------------------------------------------------------*/ for (ndong = 0; ndong < DONGLE_MANY; ndong++) { - if ((NULL == easycapdc60_dongle[ndong].peasycap) && + if ((!easycapdc60_dongle[ndong].peasycap) && (!mutex_is_locked(&easycapdc60_dongle [ndong].mutex_video)) && (!mutex_is_locked(&easycapdc60_dongle @@ -3346,7 +3346,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, bInterfaceNumber); return -ENODEV; } - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL when probing interface %i\n", bInterfaceNumber); return -ENODEV; @@ -3362,7 +3362,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, /*---------------------------------------------------------------------------*/ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { pv4l2_device = usb_get_intfdata(pusb_interface); - if (NULL == pv4l2_device) { + if (!pv4l2_device) { SAY("ERROR: pv4l2_device is NULL\n"); return -ENODEV; } @@ -3413,12 +3413,12 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, for (i = 0; i < pusb_interface->num_altsetting; i++) { pusb_host_interface = &(pusb_interface->altsetting[i]); - if (NULL == pusb_host_interface) { + if (!pusb_host_interface) { SAM("ERROR: pusb_host_interface is NULL\n"); return -EFAULT; } pusb_interface_descriptor = &(pusb_host_interface->desc); - if (NULL == pusb_interface_descriptor) { + if (!pusb_interface_descriptor) { SAM("ERROR: pusb_interface_descriptor is NULL\n"); return -EFAULT; } @@ -3453,7 +3453,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, /*---------------------------------------------------------------------------*/ for (j = 0; j < pusb_interface_descriptor->bNumEndpoints; j++) { pepd = &(pusb_host_interface->endpoint[j].desc); - if (NULL == pepd) { + if (!pepd) { SAM("ERROR: pepd is NULL.\n"); SAM("...... skipping\n"); continue; @@ -3733,12 +3733,12 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, for (k = 0; k < FRAME_BUFFER_MANY; k++) { for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { - if (NULL != peasycap->frame_buffer[k][m].pgo) + if (peasycap->frame_buffer[k][m].pgo) SAM("attempting to reallocate frame " " buffers\n"); else { pbuf = (void *)__get_free_page(GFP_KERNEL); - if (NULL == pbuf) { + if (!pbuf) { SAM("ERROR: Could not allocate frame " "buffer %i page %i\n", k, m); return -ENOMEM; @@ -3763,12 +3763,12 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, for (k = 0; k < FIELD_BUFFER_MANY; k++) { for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { - if (NULL != peasycap->field_buffer[k][m].pgo) { + if (peasycap->field_buffer[k][m].pgo) { SAM("ERROR: attempting to reallocate " "field buffers\n"); } else { pbuf = (void *) __get_free_page(GFP_KERNEL); - if (NULL == pbuf) { + if (!pbuf) { SAM("ERROR: Could not allocate field" " buffer %i page %i\n", k, m); return -ENOMEM; @@ -3796,7 +3796,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { pbuf = (void *)__get_free_pages(GFP_KERNEL, VIDEO_ISOC_ORDER); - if (NULL == pbuf) { + if (!pbuf) { SAM("ERROR: Could not allocate isoc video buffer " "%i\n", k); return -ENOMEM; @@ -3827,7 +3827,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc, GFP_KERNEL); - if (NULL == purb) { + if (!purb) { SAM("ERROR: usb_alloc_urb returned NULL for buffer " "%i\n", k); return -ENOMEM; @@ -3835,7 +3835,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, peasycap->allocation_video_urb += 1; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); - if (NULL == pdata_urb) { + if (!pdata_urb) { SAM("ERROR: Could not allocate struct data_urb.\n"); return -ENOMEM; } else @@ -4118,11 +4118,11 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, peasycap->audio_buffer_page_many); for (k = 0; k < peasycap->audio_buffer_page_many; k++) { - if (NULL != peasycap->audio_buffer[k].pgo) { + if (peasycap->audio_buffer[k].pgo) { SAM("ERROR: attempting to reallocate audio buffers\n"); } else { pbuf = (void *) __get_free_page(GFP_KERNEL); - if (NULL == pbuf) { + if (!pbuf) { SAM("ERROR: Could not allocate audio " "buffer page %i\n", k); return -ENOMEM; @@ -4147,7 +4147,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { pbuf = (void *)__get_free_pages(GFP_KERNEL, AUDIO_ISOC_ORDER); - if (NULL == pbuf) { + if (!pbuf) { SAM("ERROR: Could not allocate isoc audio buffer " "%i\n", k); return -ENOMEM; @@ -4177,7 +4177,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc, GFP_KERNEL); - if (NULL == purb) { + if (!purb) { SAM("ERROR: usb_alloc_urb returned NULL for buffer " "%i\n", k); return -ENOMEM; @@ -4185,7 +4185,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, peasycap->allocation_audio_urb += 1 ; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); - if (NULL == pdata_urb) { + if (!pdata_urb) { SAM("ERROR: Could not allocate struct data_urb.\n"); return -ENOMEM; } @@ -4339,12 +4339,12 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) JOT(4, "\n"); pusb_host_interface = pusb_interface->cur_altsetting; - if (NULL == pusb_host_interface) { + if (!pusb_host_interface) { JOT(4, "ERROR: pusb_host_interface is NULL\n"); return; } pusb_interface_descriptor = &(pusb_host_interface->desc); - if (NULL == pusb_interface_descriptor) { + if (!pusb_interface_descriptor) { JOT(4, "ERROR: pusb_interface_descriptor is NULL\n"); return; } @@ -4356,7 +4356,7 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) return; peasycap = usb_get_intfdata(pusb_interface); - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return; } @@ -4372,7 +4372,7 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) /*---------------------------------------------------------------------------*/ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { pv4l2_device = usb_get_intfdata(pusb_interface); - if (NULL == pv4l2_device) { + if (!pv4l2_device) { SAY("ERROR: pv4l2_device is NULL\n"); return; } @@ -4398,14 +4398,14 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) /*---------------------------------------------------------------------------*/ switch (bInterfaceNumber) { case 0: { - if (NULL != peasycap->purb_video_head) { + if (peasycap->purb_video_head) { JOM(4, "killing video urbs\n"); m = 0; list_for_each(plist_head, peasycap->purb_video_head) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (NULL != pdata_urb) { - if (NULL != pdata_urb->purb) { + if (pdata_urb) { + if (pdata_urb->purb) { usb_kill_urb(pdata_urb->purb); m++; } @@ -4417,14 +4417,14 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) } /*---------------------------------------------------------------------------*/ case 2: { - if (NULL != peasycap->purb_audio_head) { + if (peasycap->purb_audio_head) { JOM(4, "killing audio urbs\n"); m = 0; list_for_each(plist_head, peasycap->purb_audio_head) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (NULL != pdata_urb) { - if (NULL != pdata_urb->purb) { + if (pdata_urb) { + if (pdata_urb->purb) { usb_kill_urb(pdata_urb->purb); m++; } @@ -4464,7 +4464,7 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) } /*---------------------------------------------------------------------------*/ #ifndef EASYCAP_IS_VIDEODEV_CLIENT - if (NULL == peasycap) { + if (!peasycap) { SAM("ERROR: peasycap has become NULL\n"); } else { usb_deregister_dev(pusb_interface, &easycap_class); diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index d0ef7af8151e..5829e26969d5 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -83,12 +83,12 @@ easycap_alsa_complete(struct urb *purb) JOT(16, "\n"); - if (NULL == purb) { + if (!purb) { SAY("ERROR: purb is NULL\n"); return; } peasycap = purb->context; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return; } @@ -105,10 +105,10 @@ easycap_alsa_complete(struct urb *purb) } /*---------------------------------------------------------------------------*/ pss = peasycap->psubstream; - if (NULL == pss) + if (!pss) goto resubmit; prt = pss->runtime; - if (NULL == prt) + if (!prt) goto resubmit; dma_bytes = (int)prt->dma_bytes; if (0 == dma_bytes) @@ -294,23 +294,23 @@ static int easycap_alsa_open(struct snd_pcm_substream *pss) struct easycap *peasycap; JOT(4, "\n"); - if (NULL == pss) { + if (!pss) { SAY("ERROR: pss is NULL\n"); return -EFAULT; } psnd_pcm = pss->pcm; - if (NULL == psnd_pcm) { + if (!psnd_pcm) { SAY("ERROR: psnd_pcm is NULL\n"); return -EFAULT; } psnd_card = psnd_pcm->card; - if (NULL == psnd_card) { + if (!psnd_card) { SAY("ERROR: psnd_card is NULL\n"); return -EFAULT; } peasycap = psnd_card->private_data; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } @@ -322,7 +322,7 @@ static int easycap_alsa_open(struct snd_pcm_substream *pss) SAM("ERROR: bad peasycap->psnd_card\n"); return -EFAULT; } - if (NULL != peasycap->psubstream) { + if (peasycap->psubstream) { SAM("ERROR: bad peasycap->psubstream\n"); return -EFAULT; } @@ -345,12 +345,12 @@ static int easycap_alsa_close(struct snd_pcm_substream *pss) struct easycap *peasycap; JOT(4, "\n"); - if (NULL == pss) { + if (!pss) { SAY("ERROR: pss is NULL\n"); return -EFAULT; } peasycap = snd_pcm_substream_chip(pss); - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } @@ -369,12 +369,12 @@ static int easycap_alsa_vmalloc(struct snd_pcm_substream *pss, size_t sz) struct snd_pcm_runtime *prt; JOT(4, "\n"); - if (NULL == pss) { + if (!pss) { SAY("ERROR: pss is NULL\n"); return -EFAULT; } prt = pss->runtime; - if (NULL == prt) { + if (!prt) { SAY("ERROR: substream.runtime is NULL\n"); return -EFAULT; } @@ -384,7 +384,7 @@ static int easycap_alsa_vmalloc(struct snd_pcm_substream *pss, size_t sz) vfree(prt->dma_area); } prt->dma_area = vmalloc(sz); - if (NULL == prt->dma_area) + if (!prt->dma_area) return -ENOMEM; prt->dma_bytes = sz; return 0; @@ -396,7 +396,7 @@ static int easycap_alsa_hw_params(struct snd_pcm_substream *pss, int rc; JOT(4, "%i\n", (params_buffer_bytes(phw))); - if (NULL == pss) { + if (!pss) { SAY("ERROR: pss is NULL\n"); return -EFAULT; } @@ -411,16 +411,16 @@ static int easycap_alsa_hw_free(struct snd_pcm_substream *pss) struct snd_pcm_runtime *prt; JOT(4, "\n"); - if (NULL == pss) { + if (!pss) { SAY("ERROR: pss is NULL\n"); return -EFAULT; } prt = pss->runtime; - if (NULL == prt) { + if (!prt) { SAY("ERROR: substream.runtime is NULL\n"); return -EFAULT; } - if (NULL != prt->dma_area) { + if (prt->dma_area) { JOT(8, "prt->dma_area = %p\n", prt->dma_area); vfree(prt->dma_area); prt->dma_area = NULL; @@ -435,13 +435,13 @@ static int easycap_alsa_prepare(struct snd_pcm_substream *pss) struct snd_pcm_runtime *prt; JOT(4, "\n"); - if (NULL == pss) { + if (!pss) { SAY("ERROR: pss is NULL\n"); return -EFAULT; } prt = pss->runtime; peasycap = snd_pcm_substream_chip(pss); - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } @@ -483,12 +483,12 @@ static int easycap_alsa_trigger(struct snd_pcm_substream *pss, int cmd) JOT(4, "%i=cmd cf %i=START %i=STOP\n", cmd, SNDRV_PCM_TRIGGER_START, SNDRV_PCM_TRIGGER_STOP); - if (NULL == pss) { + if (!pss) { SAY("ERROR: pss is NULL\n"); return -EFAULT; } peasycap = snd_pcm_substream_chip(pss); - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } @@ -518,12 +518,12 @@ static snd_pcm_uframes_t easycap_alsa_pointer(struct snd_pcm_substream *pss) snd_pcm_uframes_t offset; JOT(16, "\n"); - if (NULL == pss) { + if (!pss) { SAY("ERROR: pss is NULL\n"); return -EFAULT; } peasycap = snd_pcm_substream_chip(pss); - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } @@ -584,7 +584,7 @@ int easycap_alsa_probe(struct easycap *peasycap) struct snd_card *psnd_card; struct snd_pcm *psnd_pcm; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -ENODEV; } @@ -669,11 +669,11 @@ easycap_sound_setup(struct easycap *peasycap) JOM(4, "starting initialization\n"); - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL.\n"); return -EFAULT; } - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -ENODEV; } @@ -682,12 +682,12 @@ easycap_sound_setup(struct easycap *peasycap) rc = audio_setup(peasycap); JOM(8, "audio_setup() returned %i\n", rc); - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device has become NULL\n"); return -ENODEV; } /*---------------------------------------------------------------------------*/ - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device has become NULL\n"); return -ENODEV; } @@ -725,15 +725,15 @@ submit_audio_urbs(struct easycap *peasycap) int j, isbad, nospc, m, rc; int isbuf; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } - if (NULL == peasycap->purb_audio_head) { + if (!peasycap->purb_audio_head) { SAM("ERROR: peasycap->urb_audio_head uninitialized\n"); return -EFAULT; } - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -751,9 +751,9 @@ submit_audio_urbs(struct easycap *peasycap) m = 0; list_for_each(plist_head, (peasycap->purb_audio_head)) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (NULL != pdata_urb) { + if (pdata_urb) { purb = pdata_urb->purb; - if (NULL != purb) { + if (purb) { isbuf = pdata_urb->isbuf; purb->interval = 1; @@ -801,9 +801,9 @@ submit_audio_urbs(struct easycap *peasycap) JOM(4, "attempting cleanup instead of submitting\n"); list_for_each(plist_head, (peasycap->purb_audio_head)) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (NULL != pdata_urb) { + if (pdata_urb) { purb = pdata_urb->purb; - if (NULL != purb) + if (purb) usb_kill_urb(purb); } } @@ -830,19 +830,19 @@ kill_audio_urbs(struct easycap *peasycap) struct list_head *plist_head; struct data_urb *pdata_urb; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } if (peasycap->audio_isoc_streaming) { - if (NULL != peasycap->purb_audio_head) { + if (peasycap->purb_audio_head) { peasycap->audio_isoc_streaming = 0; JOM(4, "killing audio urbs\n"); m = 0; list_for_each(plist_head, (peasycap->purb_audio_head)) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (NULL != pdata_urb) { - if (NULL != pdata_urb->purb) { + if (pdata_urb) { + if (pdata_urb->purb) { usb_kill_urb(pdata_urb->purb); m++; } diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c index 3e033edc8ede..d3980a62a163 100644 --- a/drivers/staging/easycap/easycap_sound_oss.c +++ b/drivers/staging/easycap/easycap_sound_oss.c @@ -63,12 +63,12 @@ easyoss_complete(struct urb *purb) JOT(16, "\n"); - if (NULL == purb) { + if (!purb) { SAY("ERROR: purb is NULL\n"); return; } peasycap = purb->context; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return; } @@ -288,13 +288,13 @@ static int easyoss_open(struct inode *inode, struct file *file) subminor = iminor(inode); pusb_interface = usb_find_interface(&easycap_usb_driver, subminor); - if (NULL == pusb_interface) { + if (!pusb_interface) { SAY("ERROR: pusb_interface is NULL\n"); SAY("ending unsuccessfully\n"); return -1; } peasycap = usb_get_intfdata(pusb_interface); - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); SAY("ending unsuccessfully\n"); return -1; @@ -311,7 +311,7 @@ static int easyoss_open(struct inode *inode, struct file *file) /*---------------------------------------------------------------------------*/ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { pv4l2_device = usb_get_intfdata(pusb_interface); - if (NULL == pv4l2_device) { + if (!pv4l2_device) { SAY("ERROR: pv4l2_device is NULL\n"); return -EFAULT; } @@ -343,7 +343,7 @@ static int easyoss_release(struct inode *inode, struct file *file) JOT(4, "begins\n"); peasycap = file->private_data; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL.\n"); return -EFAULT; } @@ -385,12 +385,12 @@ static ssize_t easyoss_read(struct file *file, char __user *puserspacebuffer, JOT(8, "%5zd=kount %5lld=*poff\n", kount, *poff); - if (NULL == file) { + if (!file) { SAY("ERROR: file is NULL\n"); return -ERESTARTSYS; } peasycap = file->private_data; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR in easyoss_read(): peasycap is NULL\n"); return -EFAULT; } @@ -398,7 +398,7 @@ static ssize_t easyoss_read(struct file *file, char __user *puserspacebuffer, SAY("ERROR: bad peasycap: %p\n", peasycap); return -EFAULT; } - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAY("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -418,13 +418,13 @@ static ssize_t easyoss_read(struct file *file, char __user *puserspacebuffer, */ if (kd != isdongle(peasycap)) return -ERESTARTSYS; - if (NULL == file) { + if (!file) { SAY("ERROR: file is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; } peasycap = file->private_data; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; @@ -434,7 +434,7 @@ static ssize_t easyoss_read(struct file *file, char __user *puserspacebuffer, mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; } - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; @@ -459,7 +459,7 @@ static ssize_t easyoss_read(struct file *file, char __user *puserspacebuffer, return -EFAULT; } pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; - if (NULL == pdata_buffer) { + if (!pdata_buffer) { SAM("ERROR: pdata_buffer is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; @@ -510,12 +510,12 @@ static ssize_t easyoss_read(struct file *file, char __user *puserspacebuffer, szret = (size_t)0; fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment); while (fragment == (peasycap->audio_read / peasycap->audio_pages_per_fragment)) { - if (NULL == pdata_buffer->pgo) { + if (!pdata_buffer->pgo) { SAM("ERROR: pdata_buffer->pgo is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } - if (NULL == pdata_buffer->pto) { + if (!pdata_buffer->pto) { SAM("ERROR: pdata_buffer->pto is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; @@ -543,17 +543,17 @@ static ssize_t easyoss_read(struct file *file, char __user *puserspacebuffer, return -EFAULT; } pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; - if (NULL == pdata_buffer) { + if (!pdata_buffer) { SAM("ERROR: pdata_buffer is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } - if (NULL == pdata_buffer->pgo) { + if (!pdata_buffer->pgo) { SAM("ERROR: pdata_buffer->pgo is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; } - if (NULL == pdata_buffer->pto) { + if (!pdata_buffer->pto) { SAM("ERROR: pdata_buffer->pto is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -EFAULT; @@ -662,12 +662,12 @@ static long easyoss_unlocked_ioctl(struct file *file, struct usb_device *p; int kd; - if (NULL == file) { + if (!file) { SAY("ERROR: file is NULL\n"); return -ERESTARTSYS; } peasycap = file->private_data; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL.\n"); return -EFAULT; } @@ -676,7 +676,7 @@ static long easyoss_unlocked_ioctl(struct file *file, return -EFAULT; } p = peasycap->pusb_device; - if (NULL == p) { + if (!p) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -696,13 +696,13 @@ static long easyoss_unlocked_ioctl(struct file *file, */ if (kd != isdongle(peasycap)) return -ERESTARTSYS; - if (NULL == file) { + if (!file) { SAY("ERROR: file is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; } peasycap = file->private_data; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; @@ -713,7 +713,7 @@ static long easyoss_unlocked_ioctl(struct file *file, return -EFAULT; } p = peasycap->pusb_device; - if (NULL == peasycap->pusb_device) { + if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); return -ERESTARTSYS; diff --git a/drivers/staging/easycap/easycap_testcard.c b/drivers/staging/easycap/easycap_testcard.c index 9db26af34441..0f71470ace39 100644 --- a/drivers/staging/easycap/easycap_testcard.c +++ b/drivers/staging/easycap/easycap_testcard.c @@ -39,7 +39,7 @@ easycap_testcard(struct easycap *peasycap, int field) unsigned char bfbar[TESTCARD_BYTESPERLINE / 8], *p1, *p2; struct data_buffer *pfield_buffer; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return; } -- cgit v1.2.3 From 22a55690c124e89cd7dcad301cc8f43dd9c4aa0a Mon Sep 17 00:00:00 2001 From: Jonathan Neuschäfer Date: Thu, 3 Mar 2011 14:25:07 +0100 Subject: staging: keucr: remove unused typedef VOID MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonathan Neuschäfer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/keucr/common.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/keucr/common.h b/drivers/staging/keucr/common.h index 8693c54f76d0..f2be04577895 100644 --- a/drivers/staging/keucr/common.h +++ b/drivers/staging/keucr/common.h @@ -1,7 +1,6 @@ #ifndef COMMON_INCD #define COMMON_INCD -typedef void VOID; typedef u8 BOOLEAN; typedef u8 BYTE; typedef u8 *PBYTE; -- cgit v1.2.3 From 2145cff54f512907a4c4fa906f957fa62406e558 Mon Sep 17 00:00:00 2001 From: Jonathan Neuschäfer Date: Thu, 3 Mar 2011 14:25:08 +0100 Subject: staging: keucr: use kernel byteorder functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonathan Neuschäfer Reviewed-by: Jack Stone Signed-off-by: Greg Kroah-Hartman --- drivers/staging/keucr/TODO | 1 - drivers/staging/keucr/common.h | 12 ------------ drivers/staging/keucr/ms.c | 28 +++++++++++++++------------- 3 files changed, 15 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/keucr/TODO b/drivers/staging/keucr/TODO index 179b7fe05de2..1c48e40e2b2c 100644 --- a/drivers/staging/keucr/TODO +++ b/drivers/staging/keucr/TODO @@ -6,7 +6,6 @@ TODO: be merged into the drivers/usb/storage/ directory and infrastructure instead. - review by the USB developer community - - common.h: use kernel swap, le, & be functions - smcommon.h & smilsub.c: use kernel hweight8(), hweight16() Please send any patches for this driver to Al Cho and diff --git a/drivers/staging/keucr/common.h b/drivers/staging/keucr/common.h index f2be04577895..b87dc7a8901d 100644 --- a/drivers/staging/keucr/common.h +++ b/drivers/staging/keucr/common.h @@ -9,17 +9,5 @@ typedef u16 *PWORD; typedef u32 DWORD; typedef u32 *PDWORD; -#define swapWORD(w) ((((unsigned short)(w) << 8) & 0xff00) | \ - (((unsigned short)(w) >> 8) & 0x00ff)) -#define swapDWORD(dw) ((((unsigned long)(dw) << 24) & 0xff000000) | \ - (((unsigned long)(dw) << 8) & 0x00ff0000) | \ - (((unsigned long)(dw) >> 8) & 0x0000ff00) | \ - (((unsigned long)(dw) >> 24) & 0x000000ff)) - -#define LittleEndianWORD(w) (w) -#define LittleEndianDWORD(dw) (dw) -#define BigEndianWORD(w) swapWORD(w) -#define BigEndianDWORD(dw) swapDWORD(dw) - #endif diff --git a/drivers/staging/keucr/ms.c b/drivers/staging/keucr/ms.c index 452ea8f54f67..48496e4da42b 100644 --- a/drivers/staging/keucr/ms.c +++ b/drivers/staging/keucr/ms.c @@ -1,4 +1,6 @@ #include +#include + #include "usb.h" #include "scsiglue.h" #include "transport.h" @@ -166,8 +168,8 @@ int MS_CardInit(struct us_data *us) continue; if (((extdat.mngflg & MS_REG_MNG_SYSFLG) == MS_REG_MNG_SYSFLG_USER) || - (BigEndianWORD(((MemStickBootBlockPage0 *)PageBuffer0)->header.wBlockID) != MS_BOOT_BLOCK_ID) || - (BigEndianWORD(((MemStickBootBlockPage0 *)PageBuffer0)->header.wFormatVersion) != MS_BOOT_BLOCK_FORMAT_VERSION) || + (be16_to_cpu(((MemStickBootBlockPage0 *)PageBuffer0)->header.wBlockID) != MS_BOOT_BLOCK_ID) || + (be16_to_cpu(((MemStickBootBlockPage0 *)PageBuffer0)->header.wFormatVersion) != MS_BOOT_BLOCK_FORMAT_VERSION) || (((MemStickBootBlockPage0 *)PageBuffer0)->header.bNumberOfDataEntry != MS_BOOT_BLOCK_DATA_ENTRIES)) continue; @@ -266,7 +268,7 @@ int MS_LibCheckDisableBlock(struct us_data *us, WORD PhyBlock) MS_ReaderReadPage(us, PhyBlock, 1, (DWORD *)PageBuf, &extdat); do { - blk = BigEndianWORD(PageBuf[index]); + blk = be16_to_cpu(PageBuf[index]); if (blk == MS_LB_NOT_USED) break; if (blk == us->MS_Lib.Log2PhyMap[0]) @@ -355,7 +357,7 @@ int MS_LibProcessBootBlock(struct us_data *us, WORD PhyBlock, BYTE *PageData) SysInfo= &(((MemStickBootBlockPage0 *)PageData)->sysinf); if ((SysInfo->bMsClass != MS_SYSINF_MSCLASS_TYPE_1) || - (BigEndianWORD(SysInfo->wPageSize) != MS_SYSINF_PAGE_SIZE) || + (be16_to_cpu(SysInfo->wPageSize) != MS_SYSINF_PAGE_SIZE) || ((SysInfo->bSecuritySupport & MS_SYSINF_SECURITY) == MS_SYSINF_SECURITY_SUPPORT) || (SysInfo->bReserved1 != MS_SYSINF_RESERVED1) || (SysInfo->bReserved2 != MS_SYSINF_RESERVED2) || @@ -376,12 +378,12 @@ int MS_LibProcessBootBlock(struct us_data *us, WORD PhyBlock, BYTE *PageData) goto exit; } - us->MS_Lib.blockSize = BigEndianWORD(SysInfo->wBlockSize); - us->MS_Lib.NumberOfPhyBlock = BigEndianWORD(SysInfo->wBlockNumber); - us->MS_Lib.NumberOfLogBlock = BigEndianWORD(SysInfo->wTotalBlockNumber)- 2; + us->MS_Lib.blockSize = be16_to_cpu(SysInfo->wBlockSize); + us->MS_Lib.NumberOfPhyBlock = be16_to_cpu(SysInfo->wBlockNumber); + us->MS_Lib.NumberOfLogBlock = be16_to_cpu(SysInfo->wTotalBlockNumber) - 2; us->MS_Lib.PagesPerBlock = us->MS_Lib.blockSize * SIZE_OF_KIRO / MS_BYTES_PER_PAGE; us->MS_Lib.NumberOfSegment = us->MS_Lib.NumberOfPhyBlock / MS_PHYSICAL_BLOCKS_PER_SEGMENT; - us->MS_Model = BigEndianWORD(SysInfo->wMemorySize); + us->MS_Model = be16_to_cpu(SysInfo->wMemorySize); if (MS_LibAllocLogicalMap(us)) //Allocate to all number of logicalblock and physicalblock goto exit; @@ -394,10 +396,10 @@ int MS_LibProcessBootBlock(struct us_data *us, WORD PhyBlock, BYTE *PageData) { DWORD EntryOffset, EntrySize; - if ((EntryOffset = BigEndianDWORD(SysEntry->entry[i].dwStart)) == 0xffffff) + if ((EntryOffset = be32_to_cpu(SysEntry->entry[i].dwStart)) == 0xffffff) continue; - if ((EntrySize = BigEndianDWORD(SysEntry->entry[i].dwSize)) == 0) + if ((EntrySize = be32_to_cpu(SysEntry->entry[i].dwSize)) == 0) continue; if (EntryOffset + MS_BYTES_PER_PAGE + EntrySize > us->MS_Lib.blockSize * (DWORD)SIZE_OF_KIRO) @@ -429,7 +431,7 @@ int MS_LibProcessBootBlock(struct us_data *us, WORD PhyBlock, BYTE *PageData) PrevPageNumber = PageNumber; } - if ((phyblk = BigEndianWORD(*(WORD *)(PageBuffer + (EntryOffset % MS_BYTES_PER_PAGE)))) < 0x0fff) + if ((phyblk = be16_to_cpu(*(WORD *)(PageBuffer + (EntryOffset % MS_BYTES_PER_PAGE)))) < 0x0fff) MS_LibSetInitialErrorBlock(us, phyblk); EntryOffset += 2; @@ -455,10 +457,10 @@ int MS_LibProcessBootBlock(struct us_data *us, WORD PhyBlock, BYTE *PageData) } idi = &((MemStickBootBlockCIS_IDI *)(PageBuffer + (EntryOffset % MS_BYTES_PER_PAGE)))->idi.idi; - if (LittleEndianWORD(idi->wIDIgeneralConfiguration) != MS_IDI_GENERAL_CONF) + if (le16_to_cpu(idi->wIDIgeneralConfiguration) != MS_IDI_GENERAL_CONF) goto exit; - us->MS_Lib.BytesPerSector = LittleEndianWORD(idi->wIDIbytesPerSector); + us->MS_Lib.BytesPerSector = le16_to_cpu(idi->wIDIbytesPerSector); if (us->MS_Lib.BytesPerSector != MS_BYTES_PER_PAGE) goto exit; } -- cgit v1.2.3 From 487e873dd3f8d7ede7635896e19376ef78157721 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 3 Mar 2011 12:38:04 +0000 Subject: staging: gma500: Resync the patch queue with GregKH's space cleanup. Remove all sorts of bits we can get rid of. We are now a very simple KMS driver relying on the stolen memory for our framebuffer base (which is for the moment hardcoded). To support multiple frame buffers and some accel bits we will need some kind of memory allocator, possibly a minimal use of GEM. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_bl.c | 10 +- drivers/staging/gma500/psb_drm.h | 507 ++++++----------------------- drivers/staging/gma500/psb_drv.c | 55 +--- drivers/staging/gma500/psb_drv.h | 1 - drivers/staging/gma500/psb_intel_bios.c | 2 +- drivers/staging/gma500/psb_intel_bios.h | 2 +- drivers/staging/gma500/psb_intel_reg.h | 551 ++++++++++++++------------------ drivers/staging/gma500/psb_irq.c | 4 +- drivers/staging/gma500/psb_powermgmt.c | 5 - 9 files changed, 365 insertions(+), 772 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/gma500/psb_bl.c b/drivers/staging/gma500/psb_bl.c index 52edb43c9206..70c17b352f9f 100644 --- a/drivers/staging/gma500/psb_bl.c +++ b/drivers/staging/gma500/psb_bl.c @@ -1,5 +1,5 @@ /* - * psb backlight using HAL + * psb backlight interface * * Copyright (c) 2009, Intel Corporation. * @@ -73,6 +73,8 @@ int psb_get_brightness(struct backlight_device *bd) DRM_DEBUG_DRIVER("brightness = 0x%x\n", psb_brightness); /* return locally cached var instead of HW read (due to DPST etc.) */ + /* FIXME: ideally return actual value in case firmware fiddled with + it */ return psb_brightness; } @@ -83,7 +85,7 @@ static const struct backlight_ops psb_ops = { static int device_backlight_init(struct drm_device *dev) { - unsigned long CoreClock; + unsigned long core_clock; /* u32 bl_max_freq; */ /* unsigned long value; */ u16 bl_max_freq; @@ -102,9 +104,9 @@ static int device_backlight_init(struct drm_device *dev) blc_brightnesscmd = dev_priv->lvds_bl->brightnesscmd; blc_type = dev_priv->lvds_bl->type; - CoreClock = dev_priv->core_freq; + core_clock = dev_priv->core_freq; - value = (CoreClock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT; + value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT; value *= blc_pwm_precision_factor; value /= bl_max_freq; value /= blc_pwm_precision_factor; diff --git a/drivers/staging/gma500/psb_drm.h b/drivers/staging/gma500/psb_drm.h index ef5fcd03b346..fb9b4245bada 100644 --- a/drivers/staging/gma500/psb_drm.h +++ b/drivers/staging/gma500/psb_drm.h @@ -31,17 +31,6 @@ #include "psb_ttm_fence_user.h" #include "psb_ttm_placement_user.h" -/* - * Menlow/MRST graphics driver package version - * a.b.c.xxxx - * a - Product Family: 5 - Linux - * b - Major Release Version: 0 - non-Gallium (Unbuntu); - * 1 - Gallium (Moblin2) - * c - Hotfix Release - * xxxx - Graphics internal build # - */ -#define PSB_PACKAGE_VERSION "5.3.0.32L.0036" - #define DRM_PSB_SAREA_MAJOR 0 #define DRM_PSB_SAREA_MINOR 2 #define PSB_FIXED_SHIFT 16 @@ -52,24 +41,24 @@ * Public memory types. */ -#define DRM_PSB_MEM_MMU TTM_PL_PRIV1 -#define DRM_PSB_FLAG_MEM_MMU TTM_PL_FLAG_PRIV1 +#define DRM_PSB_MEM_MMU TTM_PL_PRIV1 +#define DRM_PSB_FLAG_MEM_MMU TTM_PL_FLAG_PRIV1 #define TTM_PL_CI TTM_PL_PRIV0 #define TTM_PL_FLAG_CI TTM_PL_FLAG_PRIV0 -#define TTM_PL_RAR TTM_PL_PRIV2 -#define TTM_PL_FLAG_RAR TTM_PL_FLAG_PRIV2 +#define TTM_PL_RAR TTM_PL_PRIV2 +#define TTM_PL_FLAG_RAR TTM_PL_FLAG_PRIV2 -typedef int32_t psb_fixed; -typedef uint32_t psb_ufixed; +typedef s32 psb_fixed; +typedef u32 psb_ufixed; -static inline int32_t psb_int_to_fixed(int a) +static inline s32 psb_int_to_fixed(int a) { return a * (1 << PSB_FIXED_SHIFT); } -static inline uint32_t psb_unsigned_to_ufixed(unsigned int a) +static inline u32 psb_unsigned_to_ufixed(unsigned int a) { return a << PSB_FIXED_SHIFT; } @@ -82,13 +71,13 @@ typedef enum { } drm_cmd_status_t; struct drm_psb_scanout { - uint32_t buffer_id; /* DRM buffer object ID */ - uint32_t rotation; /* Rotation as in RR_rotation definitions */ - uint32_t stride; /* Buffer stride in bytes */ - uint32_t depth; /* Buffer depth in bits (NOT) bpp */ - uint32_t width; /* Buffer width in pixels */ - uint32_t height; /* Buffer height in lines */ - int32_t transform[3][3]; /* Buffer composite transform */ + u32 buffer_id; /* DRM buffer object ID */ + u32 rotation; /* Rotation as in RR_rotation definitions */ + u32 stride; /* Buffer stride in bytes */ + u32 depth; /* Buffer depth in bits (NOT) bpp */ + u32 width; /* Buffer width in pixels */ + u32 height; /* Buffer height in lines */ + s32 transform[3][3]; /* Buffer composite transform */ /* (scaling, rot, reflect) */ }; @@ -101,14 +90,14 @@ struct drm_psb_scanout { struct drm_psb_sarea { /* Track changes of this data structure */ - uint32_t major; - uint32_t minor; + u32 major; + u32 minor; /* Last context to touch part of hw */ - uint32_t ctx_owners[DRM_PSB_SAREA_OWNERS]; + u32 ctx_owners[DRM_PSB_SAREA_OWNERS]; /* Definition of front- and rotated buffers */ - uint32_t num_scanouts; + u32 num_scanouts; struct drm_psb_scanout scanouts[DRM_PSB_SAREA_SCANOUTS]; int planeA_x; @@ -120,7 +109,7 @@ struct drm_psb_sarea { int planeB_w; int planeB_h; /* Number of active scanouts */ - uint32_t num_active_scanouts; + u32 num_active_scanouts; }; #define PSB_RELOC_MAGIC 0x67676767 @@ -134,16 +123,16 @@ struct drm_psb_sarea { */ struct drm_psb_reloc { - uint32_t reloc_op; - uint32_t where; /* offset in destination buffer */ - uint32_t buffer; /* Buffer reloc applies to */ - uint32_t mask; /* Destination format: */ - uint32_t shift; /* Destination format: */ - uint32_t pre_add; /* Destination format: */ - uint32_t background; /* Destination add */ - uint32_t dst_buffer; /* Destination buffer. Index into buffer_list */ - uint32_t arg0; /* Reloc-op dependant */ - uint32_t arg1; + u32 reloc_op; + u32 where; /* offset in destination buffer */ + u32 buffer; /* Buffer reloc applies to */ + u32 mask; /* Destination format: */ + u32 shift; /* Destination format: */ + u32 pre_add; /* Destination format: */ + u32 background; /* Destination add */ + u32 dst_buffer; /* Destination buffer. Index into buffer_list */ + u32 arg0; /* Reloc-op dependant */ + u32 arg1; }; @@ -174,12 +163,12 @@ struct drm_psb_reloc { #define PSB_FEEDBACK_OP_VISTEST (1 << 0) struct drm_psb_extension_rep { - int32_t exists; - uint32_t driver_ioctl_offset; - uint32_t sarea_offset; - uint32_t major; - uint32_t minor; - uint32_t pl; + s32 exists; + u32 driver_ioctl_offset; + u32 sarea_offset; + u32 major; + u32 minor; + u32 pl; }; #define DRM_PSB_EXT_NAME_LEN 128 @@ -190,20 +179,20 @@ union drm_psb_extension_arg { }; struct psb_validate_req { - uint64_t set_flags; - uint64_t clear_flags; - uint64_t next; - uint64_t presumed_gpu_offset; - uint32_t buffer_handle; - uint32_t presumed_flags; - uint32_t group; - uint32_t pad64; + u64 set_flags; + u64 clear_flags; + u64 next; + u64 presumed_gpu_offset; + u32 buffer_handle; + u32 presumed_flags; + u32 group; + u32 pad64; }; struct psb_validate_rep { - uint64_t gpu_offset; - uint32_t placement; - uint32_t fence_type_mask; + u64 gpu_offset; + u32 placement; + u32 fence_type_mask; }; #define PSB_USE_PRESUMED (1 << 0) @@ -221,102 +210,24 @@ struct psb_validate_arg { #define DRM_PSB_FENCE_NO_USER (1 << 0) struct psb_ttm_fence_rep { - uint32_t handle; - uint32_t fence_class; - uint32_t fence_type; - uint32_t signaled_types; - uint32_t error; + u32 handle; + u32 fence_class; + u32 fence_type; + u32 signaled_types; + u32 error; }; -typedef struct drm_psb_cmdbuf_arg { - uint64_t buffer_list; /* List of buffers to validate */ - uint64_t clip_rects; /* See i915 counterpart */ - uint64_t scene_arg; - uint64_t fence_arg; - - uint32_t ta_flags; - - uint32_t ta_handle; /* TA reg-value pairs */ - uint32_t ta_offset; - uint32_t ta_size; - - uint32_t oom_handle; - uint32_t oom_offset; - uint32_t oom_size; - - uint32_t cmdbuf_handle; /* 2D Command buffer object or, */ - uint32_t cmdbuf_offset; /* rasterizer reg-value pairs */ - uint32_t cmdbuf_size; - - uint32_t reloc_handle; /* Reloc buffer object */ - uint32_t reloc_offset; - uint32_t num_relocs; - - int32_t damage; /* Damage front buffer with cliprects */ - /* Not implemented yet */ - uint32_t fence_flags; - uint32_t engine; - - /* - * Feedback; - */ - - uint32_t feedback_ops; - uint32_t feedback_handle; - uint32_t feedback_offset; - uint32_t feedback_breakpoints; - uint32_t feedback_size; -} drm_psb_cmdbuf_arg_t; - -typedef struct drm_psb_pageflip_arg { - uint32_t flip_offset; - uint32_t stride; -} drm_psb_pageflip_arg_t; - -typedef enum { - LNC_VIDEO_DEVICE_INFO, - LNC_VIDEO_GETPARAM_RAR_INFO, - LNC_VIDEO_GETPARAM_CI_INFO, - LNC_VIDEO_GETPARAM_RAR_HANDLER_OFFSET, - LNC_VIDEO_FRAME_SKIP, - IMG_VIDEO_DECODE_STATUS, - IMG_VIDEO_NEW_CONTEXT, - IMG_VIDEO_RM_CONTEXT, - IMG_VIDEO_MB_ERROR -} lnc_getparam_key_t; - -struct drm_lnc_video_getparam_arg { - lnc_getparam_key_t key; - uint64_t arg; /* argument pointer */ - uint64_t value; /* feed back pointer */ -}; - - /* * Feedback components: */ -/* - * Vistest component. The number of these in the feedback buffer - * equals the number of vistest breakpoints + 1. - * This is currently the only feedback component. - */ - -struct drm_psb_vistest { - uint32_t vt[8]; -}; - struct drm_psb_sizes_arg { - uint32_t ta_mem_size; - uint32_t mmu_size; - uint32_t pds_size; - uint32_t rastgeom_size; - uint32_t tt_size; - uint32_t vram_size; -}; - -struct drm_psb_hist_status_arg { - uint32_t buf[32]; + u32 ta_mem_size; + u32 mmu_size; + u32 pds_size; + u32 rastgeom_size; + u32 tt_size; + u32 vram_size; }; struct drm_psb_dpst_lut_arg { @@ -324,194 +235,6 @@ struct drm_psb_dpst_lut_arg { int output_id; }; -struct mrst_timing_info { - uint16_t pixel_clock; - uint8_t hactive_lo; - uint8_t hblank_lo; - uint8_t hblank_hi:4; - uint8_t hactive_hi:4; - uint8_t vactive_lo; - uint8_t vblank_lo; - uint8_t vblank_hi:4; - uint8_t vactive_hi:4; - uint8_t hsync_offset_lo; - uint8_t hsync_pulse_width_lo; - uint8_t vsync_pulse_width_lo:4; - uint8_t vsync_offset_lo:4; - uint8_t vsync_pulse_width_hi:2; - uint8_t vsync_offset_hi:2; - uint8_t hsync_pulse_width_hi:2; - uint8_t hsync_offset_hi:2; - uint8_t width_mm_lo; - uint8_t height_mm_lo; - uint8_t height_mm_hi:4; - uint8_t width_mm_hi:4; - uint8_t hborder; - uint8_t vborder; - uint8_t unknown0:1; - uint8_t hsync_positive:1; - uint8_t vsync_positive:1; - uint8_t separate_sync:2; - uint8_t stereo:1; - uint8_t unknown6:1; - uint8_t interlaced:1; -} __attribute__((packed)); - -struct gct_r10_timing_info { - uint16_t pixel_clock; - uint32_t hactive_lo:8; - uint32_t hactive_hi:4; - uint32_t hblank_lo:8; - uint32_t hblank_hi:4; - uint32_t hsync_offset_lo:8; - uint16_t hsync_offset_hi:2; - uint16_t hsync_pulse_width_lo:8; - uint16_t hsync_pulse_width_hi:2; - uint16_t hsync_positive:1; - uint16_t rsvd_1:3; - uint8_t vactive_lo:8; - uint16_t vactive_hi:4; - uint16_t vblank_lo:8; - uint16_t vblank_hi:4; - uint16_t vsync_offset_lo:4; - uint16_t vsync_offset_hi:2; - uint16_t vsync_pulse_width_lo:4; - uint16_t vsync_pulse_width_hi:2; - uint16_t vsync_positive:1; - uint16_t rsvd_2:3; -} __attribute__((packed)); - -struct mrst_panel_descriptor_v1{ - uint32_t Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */ - /* 0x61190 if MIPI */ - uint32_t Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/ - uint32_t Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/ - uint32_t Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 dword */ - /* Register 0x61210 */ - struct mrst_timing_info DTD;/*18 bytes, Standard definition */ - uint16_t Panel_Backlight_Inverter_Descriptor;/* 16 bits, as follows */ - /* Bit 0, Frequency, 15 bits,0 - 32767Hz */ - /* Bit 15, Polarity, 1 bit, 0: Normal, 1: Inverted */ - uint16_t Panel_MIPI_Display_Descriptor; - /*16 bits, Defined as follows: */ - /* if MIPI, 0x0000 if LVDS */ - /* Bit 0, Type, 2 bits, */ - /* 0: Type-1, */ - /* 1: Type-2, */ - /* 2: Type-3, */ - /* 3: Type-4 */ - /* Bit 2, Pixel Format, 4 bits */ - /* Bit0: 16bpp (not supported in LNC), */ - /* Bit1: 18bpp loosely packed, */ - /* Bit2: 18bpp packed, */ - /* Bit3: 24bpp */ - /* Bit 6, Reserved, 2 bits, 00b */ - /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */ - /* Bit 14, Reserved, 2 bits, 00b */ -} __attribute__ ((packed)); - -struct mrst_panel_descriptor_v2{ - uint32_t Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */ - /* 0x61190 if MIPI */ - uint32_t Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/ - uint32_t Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/ - uint8_t Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 byte */ - /* Register 0x61210 */ - struct mrst_timing_info DTD;/*18 bytes, Standard definition */ - uint16_t Panel_Backlight_Inverter_Descriptor;/*16 bits, as follows*/ - /*Bit 0, Frequency, 16 bits, 0 - 32767Hz*/ - uint8_t Panel_Initial_Brightness;/* [7:0] 0 - 100% */ - /*Bit 7, Polarity, 1 bit,0: Normal, 1: Inverted*/ - uint16_t Panel_MIPI_Display_Descriptor; - /*16 bits, Defined as follows: */ - /* if MIPI, 0x0000 if LVDS */ - /* Bit 0, Type, 2 bits, */ - /* 0: Type-1, */ - /* 1: Type-2, */ - /* 2: Type-3, */ - /* 3: Type-4 */ - /* Bit 2, Pixel Format, 4 bits */ - /* Bit0: 16bpp (not supported in LNC), */ - /* Bit1: 18bpp loosely packed, */ - /* Bit2: 18bpp packed, */ - /* Bit3: 24bpp */ - /* Bit 6, Reserved, 2 bits, 00b */ - /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */ - /* Bit 14, Reserved, 2 bits, 00b */ -} __attribute__ ((packed)); - -union mrst_panel_rx{ - struct{ - uint16_t NumberOfLanes:2; /*Num of Lanes, 2 bits,0 = 1 lane,*/ - /* 1 = 2 lanes, 2 = 3 lanes, 3 = 4 lanes. */ - uint16_t MaxLaneFreq:3; /* 0: 100MHz, 1: 200MHz, 2: 300MHz, */ - /*3: 400MHz, 4: 500MHz, 5: 600MHz, 6: 700MHz, 7: 800MHz.*/ - uint16_t SupportedVideoTransferMode:2; /*0: Non-burst only */ - /* 1: Burst and non-burst */ - /* 2/3: Reserved */ - uint16_t HSClkBehavior:1; /*0: Continuous, 1: Non-continuous*/ - uint16_t DuoDisplaySupport:1; /*1 bit,0: No, 1: Yes*/ - uint16_t ECC_ChecksumCapabilities:1;/*1 bit,0: No, 1: Yes*/ - uint16_t BidirectionalCommunication:1;/*1 bit,0: No, 1: Yes */ - uint16_t Rsvd:5;/*5 bits,00000b */ - } panelrx; - uint16_t panel_receiver; -} __attribute__ ((packed)); - -struct gct_ioctl_arg{ - uint8_t bpi; /* boot panel index, number of panel used during boot */ - uint8_t pt; /* panel type, 4 bit field, 0=lvds, 1=mipi */ - struct mrst_timing_info DTD; /* timing info for the selected panel */ - uint32_t Panel_Port_Control; - uint32_t PP_On_Sequencing;/*1 dword,Register 0x61208,*/ - uint32_t PP_Off_Sequencing;/*1 dword,Register 0x6120C,*/ - uint32_t PP_Cycle_Delay; - uint16_t Panel_Backlight_Inverter_Descriptor; - uint16_t Panel_MIPI_Display_Descriptor; -} __attribute__ ((packed)); - -struct mrst_vbt{ - char Signature[4]; /*4 bytes,"$GCT" */ - uint8_t Revision; /*1 byte */ - uint8_t Size; /*1 byte */ - uint8_t Checksum; /*1 byte,Calculated*/ - void *mrst_gct; -} __attribute__ ((packed)); - -struct mrst_gct_v1{ /* expect this table to change per customer request*/ - union{ /*8 bits,Defined as follows: */ - struct{ - uint8_t PanelType:4; /*4 bits, Bit field for panels*/ - /* 0 - 3: 0 = LVDS, 1 = MIPI*/ - /*2 bits,Specifies which of the*/ - uint8_t BootPanelIndex:2; - /* 4 panels to use by default*/ - uint8_t BootMIPI_DSI_RxIndex:2;/*Specifies which of*/ - /* the 4 MIPI DSI receivers to use*/ - } PD; - uint8_t PanelDescriptor; - }; - struct mrst_panel_descriptor_v1 panel[4];/*panel descrs,38 bytes each*/ - union mrst_panel_rx panelrx[4]; /* panel receivers*/ -} __attribute__ ((packed)); - -struct mrst_gct_v2{ /* expect this table to change per customer request*/ - union{ /*8 bits,Defined as follows: */ - struct{ - uint8_t PanelType:4; /*4 bits, Bit field for panels*/ - /* 0 - 3: 0 = LVDS, 1 = MIPI*/ - /*2 bits,Specifies which of the*/ - uint8_t BootPanelIndex:2; - /* 4 panels to use by default*/ - uint8_t BootMIPI_DSI_RxIndex:2;/*Specifies which of*/ - /* the 4 MIPI DSI receivers to use*/ - } PD; - uint8_t PanelDescriptor; - }; - struct mrst_panel_descriptor_v2 panel[4];/*panel descrs,38 bytes each*/ - union mrst_panel_rx panelrx[4]; /* panel receivers*/ -} __attribute__ ((packed)); - #define PSB_DC_CRTC_SAVE 0x01 #define PSB_DC_CRTC_RESTORE 0x02 #define PSB_DC_OUTPUT_SAVE 0x04 @@ -520,20 +243,20 @@ struct mrst_gct_v2{ /* expect this table to change per customer request*/ #define PSB_DC_OUTPUT_MASK 0x0C struct drm_psb_dc_state_arg { - uint32_t flags; - uint32_t obj_id; + u32 flags; + u32 obj_id; }; struct drm_psb_mode_operation_arg { - uint32_t obj_id; - uint16_t operation; + u32 obj_id; + u16 operation; struct drm_mode_modeinfo mode; void *data; }; struct drm_psb_stolen_memory_arg { - uint32_t base; - uint32_t size; + u32 base; + u32 size; }; /*Display Register Bits*/ @@ -556,64 +279,64 @@ struct drm_psb_stolen_memory_arg { #define OVC_REGRWBITS_OGAM_ALL (1 << 3) struct drm_psb_register_rw_arg { - uint32_t b_force_hw_on; + u32 b_force_hw_on; - uint32_t display_read_mask; - uint32_t display_write_mask; + u32 display_read_mask; + u32 display_write_mask; struct { - uint32_t pfit_controls; - uint32_t pfit_autoscale_ratios; - uint32_t pfit_programmed_scale_ratios; - uint32_t pipeasrc; - uint32_t pipebsrc; - uint32_t vtotal_a; - uint32_t vtotal_b; + u32 pfit_controls; + u32 pfit_autoscale_ratios; + u32 pfit_programmed_scale_ratios; + u32 pipeasrc; + u32 pipebsrc; + u32 vtotal_a; + u32 vtotal_b; } display; - uint32_t overlay_read_mask; - uint32_t overlay_write_mask; + u32 overlay_read_mask; + u32 overlay_write_mask; struct { - uint32_t OVADD; - uint32_t OGAMC0; - uint32_t OGAMC1; - uint32_t OGAMC2; - uint32_t OGAMC3; - uint32_t OGAMC4; - uint32_t OGAMC5; - uint32_t IEP_ENABLED; - uint32_t IEP_BLE_MINMAX; - uint32_t IEP_BSSCC_CONTROL; - uint32_t b_wait_vblank; + u32 OVADD; + u32 OGAMC0; + u32 OGAMC1; + u32 OGAMC2; + u32 OGAMC3; + u32 OGAMC4; + u32 OGAMC5; + u32 IEP_ENABLED; + u32 IEP_BLE_MINMAX; + u32 IEP_BSSCC_CONTROL; + u32 b_wait_vblank; } overlay; - uint32_t sprite_enable_mask; - uint32_t sprite_disable_mask; + u32 sprite_enable_mask; + u32 sprite_disable_mask; struct { - uint32_t dspa_control; - uint32_t dspa_key_value; - uint32_t dspa_key_mask; - uint32_t dspc_control; - uint32_t dspc_stride; - uint32_t dspc_position; - uint32_t dspc_linear_offset; - uint32_t dspc_size; - uint32_t dspc_surface; + u32 dspa_control; + u32 dspa_key_value; + u32 dspa_key_mask; + u32 dspc_control; + u32 dspc_stride; + u32 dspc_position; + u32 dspc_linear_offset; + u32 dspc_size; + u32 dspc_surface; } sprite; - uint32_t subpicture_enable_mask; - uint32_t subpicture_disable_mask; + u32 subpicture_enable_mask; + u32 subpicture_disable_mask; }; struct psb_gtt_mapping_arg { void *hKernelMemInfo; - uint32_t offset_pages; + u32 offset_pages; }; struct drm_psb_getpageaddrs_arg { - uint32_t handle; + u32 handle; unsigned long *page_addrs; unsigned long gtt_offset; }; @@ -659,38 +382,16 @@ struct drm_psb_getpageaddrs_arg { #define DRM_PVR_RESERVED6 0x1E #define DRM_PSB_GET_PIPE_FROM_CRTC_ID 0x1F -#define DRM_PSB_DPU_QUERY 0x20 -#define DRM_PSB_DPU_DSR_ON 0x21 -#define DRM_PSB_DPU_DSR_OFF 0x22 - -#define DRM_PSB_DSR_ENABLE 0xfffffffe -#define DRM_PSB_DSR_DISABLE 0xffffffff - -struct psb_drm_dpu_rect { - int x, y; - int width, height; -}; - -struct drm_psb_drv_dsr_off_arg { - int screen; - struct psb_drm_dpu_rect damage_rect; -}; - - -struct drm_psb_dev_info_arg { - uint32_t num_use_attribute_registers; -}; -#define DRM_PSB_DEVINFO 0x01 #define PSB_MODE_OPERATION_MODE_VALID 0x01 #define PSB_MODE_OPERATION_SET_DC_BASE 0x02 struct drm_psb_get_pipe_from_crtc_id_arg { /** ID of CRTC being requested **/ - uint32_t crtc_id; + u32 crtc_id; /** pipe of requested CRTC **/ - uint32_t pipe; + u32 pipe; }; #endif diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index 2b410af91dfa..090d9a2e60bf 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -33,14 +33,13 @@ #include #include #include +#include int drm_psb_debug; static int drm_psb_trap_pagefaults; int drm_psb_disable_vsync = 1; int drm_psb_no_fb; -int drm_psb_force_pipeb; -int drm_idle_check_interval = 5; int gfxrtdelay = 2 * 1000; static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent); @@ -57,7 +56,6 @@ MODULE_PARM_DESC(hdmi_edid, "EDID info for HDMI monitor"); module_param_named(debug, drm_psb_debug, int, 0600); module_param_named(no_fb, drm_psb_no_fb, int, 0600); module_param_named(trap_pagefaults, drm_psb_trap_pagefaults, int, 0600); -module_param_named(force_pipeb, drm_psb_force_pipeb, int, 0600); module_param_named(rtpm, gfxrtdelay, int, 0600); @@ -108,12 +106,6 @@ MODULE_DEVICE_TABLE(pci, pciidlist); #define DRM_IOCTL_PSB_GETPAGEADDRS \ DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_GETPAGEADDRS,\ struct drm_psb_getpageaddrs_arg) -#define DRM_IOCTL_PSB_HIST_ENABLE \ - DRM_IOWR(DRM_PSB_HIST_ENABLE + DRM_COMMAND_BASE, \ - uint32_t) -#define DRM_IOCTL_PSB_HIST_STATUS \ - DRM_IOWR(DRM_PSB_HIST_STATUS + DRM_COMMAND_BASE, \ - struct drm_psb_hist_status_arg) #define DRM_IOCTL_PSB_UPDATE_GUARD \ DRM_IOWR(DRM_PSB_UPDATE_GUARD + DRM_COMMAND_BASE, \ uint32_t) @@ -133,15 +125,9 @@ MODULE_DEVICE_TABLE(pci, pciidlist); /* * TTM execbuf extension. */ -#define DRM_PSB_CMDBUF (DRM_PSB_DPU_DSR_OFF + 1) - -#define DRM_PSB_SCENE_UNREF (DRM_PSB_CMDBUF + 1) -#define DRM_IOCTL_PSB_CMDBUF \ - DRM_IOW(DRM_PSB_CMDBUF + DRM_COMMAND_BASE, \ - struct drm_psb_cmdbuf_arg) -#define DRM_IOCTL_PSB_SCENE_UNREF \ - DRM_IOW(DRM_PSB_SCENE_UNREF + DRM_COMMAND_BASE, \ - struct drm_psb_scene) + +#define DRM_PSB_CMDBUF 0x23 +#define DRM_PSB_SCENE_UNREF 0x24 #define DRM_IOCTL_PSB_KMS_OFF DRM_IO(DRM_PSB_KMS_OFF + DRM_COMMAND_BASE) #define DRM_IOCTL_PSB_KMS_ON DRM_IO(DRM_PSB_KMS_ON + DRM_COMMAND_BASE) /* @@ -168,8 +154,6 @@ MODULE_DEVICE_TABLE(pci, pciidlist); #define DRM_PSB_TTM_FENCE_UNREF (TTM_FENCE_UNREF + DRM_PSB_FENCE_OFFSET) #define DRM_PSB_FLIP (DRM_PSB_TTM_FENCE_UNREF + 1) /*20*/ -/* PSB video extension */ -#define DRM_LNC_VIDEO_GETPARAM (DRM_PSB_FLIP + 1) #define DRM_IOCTL_PSB_TTM_PL_CREATE \ DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_CREATE,\ @@ -201,12 +185,6 @@ MODULE_DEVICE_TABLE(pci, pciidlist); #define DRM_IOCTL_PSB_TTM_FENCE_UNREF \ DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_FENCE_UNREF, \ struct ttm_fence_unref_arg) -#define DRM_IOCTL_PSB_FLIP \ - DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_FLIP, \ - struct drm_psb_pageflip_arg) -#define DRM_IOCTL_LNC_VIDEO_GETPARAM \ - DRM_IOWR(DRM_COMMAND_BASE + DRM_LNC_VIDEO_GETPARAM, \ - struct drm_lnc_video_getparam_arg) static int psb_vt_leave_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); @@ -268,9 +246,6 @@ static struct drm_ioctl_desc psb_ioctls[] = { PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST_BL, psb_dpst_bl_ioctl, DRM_AUTH), PSB_IOCTL_DEF(DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID, psb_intel_get_pipe_from_crtc_id, 0), - /*to be removed later*/ - /*PSB_IOCTL_DEF(DRM_IOCTL_PSB_SCENE_UNREF, drm_psb_scene_unref_ioctl, - DRM_AUTH),*/ PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_CREATE, psb_pl_create_ioctl, DRM_AUTH), @@ -392,15 +367,6 @@ static void psb_get_core_freq(struct drm_device *dev) #define FB_SKU_100 0 #define FB_SKU_100L 1 #define FB_SKU_83 2 -#if 1 /* FIXME remove it after PO */ -#define FB_GFX_CLK_DIVIDE_MASK (BIT20|BIT21|BIT22) -#define FB_GFX_CLK_DIVIDE_SHIFT 20 -#define FB_VED_CLK_DIVIDE_MASK (BIT23|BIT24) -#define FB_VED_CLK_DIVIDE_SHIFT 23 -#define FB_VEC_CLK_DIVIDE_MASK (BIT25|BIT26) -#define FB_VEC_CLK_DIVIDE_SHIFT 25 -#endif /* FIXME remove it after PO */ - bool mid_get_pci_revID(struct drm_psb_private *dev_priv) { @@ -596,7 +562,7 @@ static int psb_driver_unload(struct drm_device *dev) dev->dev_private = NULL; /*destory VBT data*/ - psb_intel_destory_bios(dev); + psb_intel_destroy_bios(dev); } ospm_power_uninit(); @@ -615,10 +581,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) int ret = -ENOMEM; uint32_t tt_pages; - DRM_INFO("psb - %s\n", PSB_PACKAGE_VERSION); - - DRM_INFO("Run drivers on Poulsbo platform!\n"); - dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); if (dev_priv == NULL) return -ENOMEM; @@ -774,11 +736,8 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) if (ret) return ret; - /** - * Init lid switch timer. - * NOTE: must do this after psb_intel_opregion_init - * and psb_backlight_init - */ +/* igd_opregion_init(&dev_priv->opregion_dev); */ + acpi_video_register(); if (dev_priv->lid_state) psb_lid_timer_init(dev_priv); diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index f7c976299adc..29a36056d664 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -368,7 +368,6 @@ struct drm_psb_private { unsigned long chipset; - struct drm_psb_dev_info_arg dev_info; struct drm_psb_uopt uopt; struct psb_gtt *pg; diff --git a/drivers/staging/gma500/psb_intel_bios.c b/drivers/staging/gma500/psb_intel_bios.c index 83d8e9359f2f..f5bcd119b87d 100644 --- a/drivers/staging/gma500/psb_intel_bios.c +++ b/drivers/staging/gma500/psb_intel_bios.c @@ -273,7 +273,7 @@ bool psb_intel_init_bios(struct drm_device *dev) /** * Destory and free VBT data */ -void psb_intel_destory_bios(struct drm_device *dev) +void psb_intel_destroy_bios(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; struct drm_display_mode *sdvo_lvds_vbt_mode = diff --git a/drivers/staging/gma500/psb_intel_bios.h b/drivers/staging/gma500/psb_intel_bios.h index ad30a6842529..70f1bf018183 100644 --- a/drivers/staging/gma500/psb_intel_bios.h +++ b/drivers/staging/gma500/psb_intel_bios.h @@ -304,7 +304,7 @@ struct bdb_sdvo_lvds_options { extern bool psb_intel_init_bios(struct drm_device *dev); -extern void psb_intel_destory_bios(struct drm_device *dev); +extern void psb_intel_destroy_bios(struct drm_device *dev); /* * Driver<->VBIOS interaction occurs through scratch bits in diff --git a/drivers/staging/gma500/psb_intel_reg.h b/drivers/staging/gma500/psb_intel_reg.h index 0c323c026f85..1c283140bccc 100644 --- a/drivers/staging/gma500/psb_intel_reg.h +++ b/drivers/staging/gma500/psb_intel_reg.h @@ -22,7 +22,7 @@ #define BLC_PWM_CTL_C 0x62254 #define BLC_PWM_CTL2_C 0x62250 #define BACKLIGHT_MODULATION_FREQ_SHIFT (17) -/** +/* * This is the most significant 15 bits of the number of backlight cycles in a * complete cycle of the modulated backlight control. * @@ -30,7 +30,7 @@ */ #define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) #define BLM_LEGACY_MODE (1 << 16) -/** +/* * This is the number of cycles out of the backlight modulation cycle for which * the backlight is on. * @@ -86,7 +86,7 @@ #define PP_STATUS 0x61200 # define PP_ON (1 << 31) -/** +/* * Indicates that all dependencies of the panel are on: * * - PLL enabled @@ -143,12 +143,12 @@ # define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ # define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ # define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ -/** +/* * The i830 generation, in DAC/serial mode, defines p1 as two plus this * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set. */ # define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 -/** +/* * The i830 generation, in LVDS mode, defines P1 as the bit number set within * this field (only one bit may be set). */ @@ -173,33 +173,33 @@ # define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT) # define DISPLAY_RATE_SELECT_FPA1 (1 << 8) -/** +/* * SDVO multiplier for 945G/GM. Not used on 965. * - * \sa DPLL_MD_UDI_MULTIPLIER_MASK + * DPLL_MD_UDI_MULTIPLIER_MASK */ # define SDVO_MULTIPLIER_MASK 0x000000ff # define SDVO_MULTIPLIER_SHIFT_HIRES 4 # define SDVO_MULTIPLIER_SHIFT_VGA 0 -/** @defgroup DPLL_MD - * @{ +/* + * PLL_MD */ -/** Pipe A SDVO/UDI clock multiplier/divider register for G965. */ +/* Pipe A SDVO/UDI clock multiplier/divider register for G965. */ #define DPLL_A_MD 0x0601c -/** Pipe B SDVO/UDI clock multiplier/divider register for G965. */ +/* Pipe B SDVO/UDI clock multiplier/divider register for G965. */ #define DPLL_B_MD 0x06020 -/** +/* * UDI pixel divider, controlling how many pixels are stuffed into a packet. * * Value is pixels minus 1. Must be set to 1 pixel for SDVO. */ # define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000 # define DPLL_MD_UDI_DIVIDER_SHIFT 24 -/** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */ +/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */ # define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000 # define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16 -/** +/* * SDVO/UDI pixel multiplier. * * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus @@ -218,13 +218,13 @@ */ # define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00 # define DPLL_MD_UDI_MULTIPLIER_SHIFT 8 -/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. +/* + * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. * This best be set to the default value (3) or the CRT won't work. No, * I don't entirely understand what this does... */ # define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f # define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 -/** @} */ #define DPLL_TEST 0x606c # define DPLLB_TEST_SDVO_DIV_1 (0 << 22) @@ -295,7 +295,7 @@ * * Programmed value is multiplier - 1, up to 5x. * - * \sa DPLL_MD_UDI_MULTIPLIER_MASK + * DPLL_MD_UDI_MULTIPLIER_MASK */ #define SDVO_PORT_MULTIPLY_MASK (7 << 23) #define SDVO_PORT_MULTIPLY_SHIFT 23 @@ -310,35 +310,32 @@ #define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14)) #define SDVOC_PRESERVE_MASK (1 << 17) -/** @defgroup LVDS - * @{ - */ -/** +/* * This register controls the LVDS output enable, pipe selection, and data * format selection. * * All of the clock/data pairs are force powered down by power sequencing. */ #define LVDS 0x61180 -/** +/* * Enables the LVDS port. This bit must be set before DPLLs are enabled, as * the DPLL semantics change when the LVDS is assigned to that pipe. */ # define LVDS_PORT_EN (1 << 31) -/** Selects pipe B for LVDS data. Must be set on pre-965. */ +/* Selects pipe B for LVDS data. Must be set on pre-965. */ # define LVDS_PIPEB_SELECT (1 << 30) -/** Turns on border drawing to allow centered display. */ +/* Turns on border drawing to allow centered display. */ # define LVDS_BORDER_EN (1 << 15) -/** +/* * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per * pixel. */ # define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) # define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) # define LVDS_A0A2_CLKA_POWER_UP (3 << 8) -/** +/* * Controls the A3 data pair, which contains the additional LSBs for 24 bit * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be * on. @@ -346,15 +343,14 @@ # define LVDS_A3_POWER_MASK (3 << 6) # define LVDS_A3_POWER_DOWN (0 << 6) # define LVDS_A3_POWER_UP (3 << 6) -/** +/* * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP * is set. */ # define LVDS_CLKB_POWER_MASK (3 << 4) # define LVDS_CLKB_POWER_DOWN (0 << 4) # define LVDS_CLKB_POWER_UP (3 << 4) - -/** +/* * Controls the B0-B3 data pairs. This must be set to match the DPLL p2 * setting for whether we are in dual-channel mode. The B3 pair will * additionally only be powered up when LVDS_A3_POWER_UP is set. @@ -419,8 +415,8 @@ #define PIPE_HDMI_AUDIO_UNDERRUN (1UL<<26) #define PIPE_HDMI_AUDIO_BUFFER_DONE (1UL<<27) #define PIPE_HDMI_AUDIO_INT_MASK (PIPE_HDMI_AUDIO_UNDERRUN | PIPE_HDMI_AUDIO_BUFFER_DONE) -#define PIPE_EVENT_MASK (BIT29|BIT28|BIT27|BIT26|BIT24|BIT23|BIT22|BIT21|BIT20|BIT16) -#define PIPE_VBLANK_MASK (BIT25|BIT24|BIT18|BIT17) +#define PIPE_EVENT_MASK ((1 << 29)|(1 << 28)|(1 << 27)|(1 << 26)|(1 << 24)|(1 << 23)|(1 << 22)|(1 << 21)|(1 << 20)|(1 << 16)) +#define PIPE_VBLANK_MASK ((1 << 25)|(1 << 24)|(1 << 18)|(1 << 17)) #define HISTOGRAM_INT_CONTROL 0x61268 #define HISTOGRAM_BIN_DATA 0X61264 #define HISTOGRAM_LOGIC_CONTROL 0x61260 @@ -567,7 +563,7 @@ struct dpst_guardband { #define OV_C_OFFSET 0x08000 #define OV_OVADD 0x30000 #define OV_DOVASTA 0x30008 -# define OV_PIPE_SELECT (BIT6|BIT7) +# define OV_PIPE_SELECT ((1 << 6)|(1 << 7)) # define OV_PIPE_SELECT_POS 6 # define OV_PIPE_A 0 # define OV_PIPE_C 1 @@ -629,40 +625,6 @@ struct dpst_guardband { #define PALETTE_B 0x0a800 #define PALETTE_C 0x0ac00 -#define IS_I830(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82830_CGC) -#define IS_845G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82845G_IG) -#define IS_I85X(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82855GM_IG) -#define IS_I855(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82855GM_IG) -#define IS_I865G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82865_IG) - - -/* || dev->pci_device == PCI_DEVICE_ID_INTELPCI_CHIP_E7221_G) */ -#define IS_I915G(dev) (dev->pci_device == PCI_DEVICE_ID_INTEL_82915G_IG) -#define IS_I915GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82915GM_IG) -#define IS_I945G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945G_IG) -#define IS_I945GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945GM_IG) - -#define IS_I965G(dev) ((dev)->pci_device == 0x2972 || \ - (dev)->pci_device == 0x2982 || \ - (dev)->pci_device == 0x2992 || \ - (dev)->pci_device == 0x29A2 || \ - (dev)->pci_device == 0x2A02 || \ - (dev)->pci_device == 0x2A12) - -#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02) - -#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \ - (dev)->pci_device == 0x29B2 || \ - (dev)->pci_device == 0x29D2) - -#define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \ - IS_I945GM(dev) || IS_I965G(dev) || IS_POULSBO(dev) || \ - IS_MRST(dev)) - -#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ - IS_I945GM(dev) || IS_I965GM(dev) || \ - IS_POULSBO(dev) || IS_MRST(dev)) - /* Cursor A & B regs */ #define CURACNTR 0x70080 #define CURSOR_MODE_DISABLE 0x00 @@ -707,7 +669,9 @@ struct dpst_guardband { #define MDFLD_DPLL_DIV1 0x0f04c #define MRST_PERF_MODE 0x020f4 -/* MEDFIELD HDMI registers */ +/* + * MEDFIELD HDMI registers + */ #define HDMIPHYMISCCTL 0x61134 # define HDMI_PHY_POWER_DOWN 0x7f #define HDMIB_CONTROL 0x61140 @@ -724,7 +688,7 @@ struct dpst_guardband { #define MIPI 0x61190 #define MIPI_C 0x62190 # define MIPI_PORT_EN (1 << 31) -/** Turns on border drawing to allow centered display. */ +/* Turns on border drawing to allow centered display. */ # define SEL_FLOPPED_HSTX (1 << 23) # define PASS_FROM_SPHY_TO_AFE (1 << 16) # define MIPI_BORDER_EN (1 << 15) @@ -756,47 +720,13 @@ struct dpst_guardband { /* * Moorestown registers. */ -/*=========================================================================== -; General Constants -;--------------------------------------------------------------------------*/ -#define BIT0 0x00000001 -#define BIT1 0x00000002 -#define BIT2 0x00000004 -#define BIT3 0x00000008 -#define BIT4 0x00000010 -#define BIT5 0x00000020 -#define BIT6 0x00000040 -#define BIT7 0x00000080 -#define BIT8 0x00000100 -#define BIT9 0x00000200 -#define BIT10 0x00000400 -#define BIT11 0x00000800 -#define BIT12 0x00001000 -#define BIT13 0x00002000 -#define BIT14 0x00004000 -#define BIT15 0x00008000 -#define BIT16 0x00010000 -#define BIT17 0x00020000 -#define BIT18 0x00040000 -#define BIT19 0x00080000 -#define BIT20 0x00100000 -#define BIT21 0x00200000 -#define BIT22 0x00400000 -#define BIT23 0x00800000 -#define BIT24 0x01000000 -#define BIT25 0x02000000 -#define BIT26 0x04000000 -#define BIT27 0x08000000 -#define BIT28 0x10000000 -#define BIT29 0x20000000 -#define BIT30 0x40000000 -#define BIT31 0x80000000 -/*=========================================================================== -; MIPI IP registers -;--------------------------------------------------------------------------*/ + +/* + * MIPI IP registers + */ #define MIPIC_REG_OFFSET 0x800 #define DEVICE_READY_REG 0xb000 -#define LP_OUTPUT_HOLD BIT16 +#define LP_OUTPUT_HOLD (1 << 16) #define EXIT_ULPS_DEV_READY 0x3 #define LP_OUTPUT_HOLD_RELEASE 0x810000 # define ENTERING_ULPS (2 << 1) @@ -804,33 +734,33 @@ struct dpst_guardband { # define ULPS_MASK (3 << 1) # define BUS_POSSESSION (1 << 3) #define INTR_STAT_REG 0xb004 -#define RX_SOT_ERROR BIT0 -#define RX_SOT_SYNC_ERROR BIT1 -#define RX_ESCAPE_MODE_ENTRY_ERROR BIT3 -#define RX_LP_TX_SYNC_ERROR BIT4 -#define RX_HS_RECEIVE_TIMEOUT_ERROR BIT5 -#define RX_FALSE_CONTROL_ERROR BIT6 -#define RX_ECC_SINGLE_BIT_ERROR BIT7 -#define RX_ECC_MULTI_BIT_ERROR BIT8 -#define RX_CHECKSUM_ERROR BIT9 -#define RX_DSI_DATA_TYPE_NOT_RECOGNIZED BIT10 -#define RX_DSI_VC_ID_INVALID BIT11 -#define TX_FALSE_CONTROL_ERROR BIT12 -#define TX_ECC_SINGLE_BIT_ERROR BIT13 -#define TX_ECC_MULTI_BIT_ERROR BIT14 -#define TX_CHECKSUM_ERROR BIT15 -#define TX_DSI_DATA_TYPE_NOT_RECOGNIZED BIT16 -#define TX_DSI_VC_ID_INVALID BIT17 -#define HIGH_CONTENTION BIT18 -#define LOW_CONTENTION BIT19 -#define DPI_FIFO_UNDER_RUN BIT20 -#define HS_TX_TIMEOUT BIT21 -#define LP_RX_TIMEOUT BIT22 -#define TURN_AROUND_ACK_TIMEOUT BIT23 -#define ACK_WITH_NO_ERROR BIT24 -#define HS_GENERIC_WR_FIFO_FULL BIT27 -#define LP_GENERIC_WR_FIFO_FULL BIT28 -#define SPL_PKT_SENT BIT30 +#define RX_SOT_ERROR (1 << 0) +#define RX_SOT_SYNC_ERROR (1 << 1) +#define RX_ESCAPE_MODE_ENTRY_ERROR (1 << 3) +#define RX_LP_TX_SYNC_ERROR (1 << 4) +#define RX_HS_RECEIVE_TIMEOUT_ERROR (1 << 5) +#define RX_FALSE_CONTROL_ERROR (1 << 6) +#define RX_ECC_SINGLE_BIT_ERROR (1 << 7) +#define RX_ECC_MULTI_BIT_ERROR (1 << 8) +#define RX_CHECKSUM_ERROR (1 << 9) +#define RX_DSI_DATA_TYPE_NOT_RECOGNIZED (1 << 10) +#define RX_DSI_VC_ID_INVALID (1 << 11) +#define TX_FALSE_CONTROL_ERROR (1 << 12) +#define TX_ECC_SINGLE_BIT_ERROR (1 << 13) +#define TX_ECC_MULTI_BIT_ERROR (1 << 14) +#define TX_CHECKSUM_ERROR (1 << 15) +#define TX_DSI_DATA_TYPE_NOT_RECOGNIZED (1 << 16) +#define TX_DSI_VC_ID_INVALID (1 << 17) +#define HIGH_CONTENTION (1 << 18) +#define LOW_CONTENTION (1 << 19) +#define DPI_FIFO_UNDER_RUN (1 << 20) +#define HS_TX_TIMEOUT (1 << 21) +#define LP_RX_TIMEOUT (1 << 22) +#define TURN_AROUND_ACK_TIMEOUT (1 << 23) +#define ACK_WITH_NO_ERROR (1 << 24) +#define HS_GENERIC_WR_FIFO_FULL (1 << 27) +#define LP_GENERIC_WR_FIFO_FULL (1 << 28) +#define SPL_PKT_SENT (1 << 30) #define INTR_EN_REG 0xb008 #define DSI_FUNC_PRG_REG 0xb00c #define DPI_CHANNEL_NUMBER_POS 0x03 @@ -873,22 +803,22 @@ struct dpst_guardband { #define VERT_FRONT_PORCH_COUNT_REG 0xb040 #define HIGH_LOW_SWITCH_COUNT_REG 0xb044 #define DPI_CONTROL_REG 0xb048 -#define DPI_SHUT_DOWN BIT0 -#define DPI_TURN_ON BIT1 -#define DPI_COLOR_MODE_ON BIT2 -#define DPI_COLOR_MODE_OFF BIT3 -#define DPI_BACK_LIGHT_ON BIT4 -#define DPI_BACK_LIGHT_OFF BIT5 -#define DPI_LP BIT6 +#define DPI_SHUT_DOWN (1 << 0) +#define DPI_TURN_ON (1 << 1) +#define DPI_COLOR_MODE_ON (1 << 2) +#define DPI_COLOR_MODE_OFF (1 << 3) +#define DPI_BACK_LIGHT_ON (1 << 4) +#define DPI_BACK_LIGHT_OFF (1 << 5) +#define DPI_LP (1 << 6) #define DPI_DATA_REG 0xb04c #define DPI_BACK_LIGHT_ON_DATA 0x07 #define DPI_BACK_LIGHT_OFF_DATA 0x17 #define INIT_COUNT_REG 0xb050 #define MAX_RET_PAK_REG 0xb054 #define VIDEO_FMT_REG 0xb058 -#define COMPLETE_LAST_PCKT BIT2 +#define COMPLETE_LAST_PCKT (1 << 2) #define EOT_DISABLE_REG 0xb05c -#define ENABLE_CLOCK_STOPPING BIT1 +#define ENABLE_CLOCK_STOPPING (1 << 1) #define LP_BYTECLK_REG 0xb060 #define LP_GEN_DATA_REG 0xb064 #define HS_GEN_DATA_REG 0xb068 @@ -899,30 +829,31 @@ struct dpst_guardband { #define WORD_COUNTS_POS 0x8 #define MCS_PARAMETER_POS 0x10 #define GEN_FIFO_STAT_REG 0xb074 -#define HS_DATA_FIFO_FULL BIT0 -#define HS_DATA_FIFO_HALF_EMPTY BIT1 -#define HS_DATA_FIFO_EMPTY BIT2 -#define LP_DATA_FIFO_FULL BIT8 -#define LP_DATA_FIFO_HALF_EMPTY BIT9 -#define LP_DATA_FIFO_EMPTY BIT10 -#define HS_CTRL_FIFO_FULL BIT16 -#define HS_CTRL_FIFO_HALF_EMPTY BIT17 -#define HS_CTRL_FIFO_EMPTY BIT18 -#define LP_CTRL_FIFO_FULL BIT24 -#define LP_CTRL_FIFO_HALF_EMPTY BIT25 -#define LP_CTRL_FIFO_EMPTY BIT26 -#define DBI_FIFO_EMPTY BIT27 -#define DPI_FIFO_EMPTY BIT28 +#define HS_DATA_FIFO_FULL (1 << 0) +#define HS_DATA_FIFO_HALF_EMPTY (1 << 1) +#define HS_DATA_FIFO_EMPTY (1 << 2) +#define LP_DATA_FIFO_FULL (1 << 8) +#define LP_DATA_FIFO_HALF_EMPTY (1 << 9) +#define LP_DATA_FIFO_EMPTY (1 << 10) +#define HS_CTRL_FIFO_FULL (1 << 16) +#define HS_CTRL_FIFO_HALF_EMPTY (1 << 17) +#define HS_CTRL_FIFO_EMPTY (1 << 18) +#define LP_CTRL_FIFO_FULL (1 << 24) +#define LP_CTRL_FIFO_HALF_EMPTY (1 << 25) +#define LP_CTRL_FIFO_EMPTY (1 << 26) +#define DBI_FIFO_EMPTY (1 << 27) +#define DPI_FIFO_EMPTY (1 << 28) #define HS_LS_DBI_ENABLE_REG 0xb078 #define TXCLKESC_REG 0xb07c #define DPHY_PARAM_REG 0xb080 #define DBI_BW_CTRL_REG 0xb084 #define CLK_LANE_SWT_REG 0xb088 -/*=========================================================================== -; MIPI Adapter registers -;--------------------------------------------------------------------------*/ + +/* + * MIPI Adapter registers + */ #define MIPI_CONTROL_REG 0xb104 -#define MIPI_2X_CLOCK_BITS (BIT0 | BIT1) +#define MIPI_2X_CLOCK_BITS ((1 << 0) | (1 << 1)) #define MIPI_DATA_ADDRESS_REG 0xb108 #define MIPI_DATA_LENGTH_REG 0xb10C #define MIPI_COMMAND_ADDRESS_REG 0xb110 @@ -938,75 +869,76 @@ struct dpst_guardband { #define MIPI_READ_DATA_VALID_REG 0xb138 /* DBI COMMANDS */ #define soft_reset 0x01 -/* ************************************************************************* *\ -The display module performs a software reset. -Registers are written with their SW Reset default values. -\* ************************************************************************* */ +/* + * The display module performs a software reset. + * Registers are written with their SW Reset default values. + */ #define get_power_mode 0x0a -/* ************************************************************************* *\ -The display module returns the current power mode -\* ************************************************************************* */ +/* + * The display module returns the current power mode + */ #define get_address_mode 0x0b -/* ************************************************************************* *\ -The display module returns the current status. -\* ************************************************************************* */ +/* + * The display module returns the current status. + */ #define get_pixel_format 0x0c -/* ************************************************************************* *\ -This command gets the pixel format for the RGB image data -used by the interface. -\* ************************************************************************* */ +/* + * This command gets the pixel format for the RGB image data + * used by the interface. + */ #define get_display_mode 0x0d -/* ************************************************************************* *\ -The display module returns the Display Image Mode status. -\* ************************************************************************* */ +/* + * The display module returns the Display Image Mode status. + */ #define get_signal_mode 0x0e -/* ************************************************************************* *\ -The display module returns the Display Signal Mode. -\* ************************************************************************* */ +/* + * The display module returns the Display Signal Mode. + */ #define get_diagnostic_result 0x0f -/* ************************************************************************* *\ -The display module returns the self-diagnostic results following -a Sleep Out command. -\* ************************************************************************* */ +/* + * The display module returns the self-diagnostic results following + * a Sleep Out command. + */ #define enter_sleep_mode 0x10 -/* ************************************************************************* *\ -This command causes the display module to enter the Sleep mode. -In this mode, all unnecessary blocks inside the display module are disabled -except interface communication. This is the lowest power mode -the display module supports. -\* ************************************************************************* */ +/* + * This command causes the display module to enter the Sleep mode. + * In this mode, all unnecessary blocks inside the display module are + * disabled except interface communication. This is the lowest power + * mode the display module supports. + */ #define exit_sleep_mode 0x11 -/* ************************************************************************* *\ -This command causes the display module to exit Sleep mode. -All blocks inside the display module are enabled. -\* ************************************************************************* */ +/* + * This command causes the display module to exit Sleep mode. + * All blocks inside the display module are enabled. + */ #define enter_partial_mode 0x12 -/* ************************************************************************* *\ -This command causes the display module to enter the Partial Display Mode. -The Partial Display Mode window is described by the set_partial_area command. -\* ************************************************************************* */ +/* + * This command causes the display module to enter the Partial Display + * Mode. The Partial Display Mode window is described by the + * set_partial_area command. + */ #define enter_normal_mode 0x13 -/* ************************************************************************* *\ -This command causes the display module to enter the Normal mode. -Normal Mode is defined as Partial Display mode and Scroll mode are off -\* ************************************************************************* */ +/* + * This command causes the display module to enter the Normal mode. + * Normal Mode is defined as Partial Display mode and Scroll mode are off + */ #define exit_invert_mode 0x20 -/* ************************************************************************* *\ -This command causes the display module to stop inverting the image data on -the display device. The frame memory contents remain unchanged. -No status bits are changed. -\* ************************************************************************* */ +/* + * This command causes the display module to stop inverting the image + * data on the display device. The frame memory contents remain unchanged. + * No status bits are changed. + */ #define enter_invert_mode 0x21 -/* ************************************************************************* *\ -This command causes the display module to invert the image data only on -the display device. The frame memory contents remain unchanged. -No status bits are changed. -\* ************************************************************************* */ +/* + * This command causes the display module to invert the image data only on + * the display device. The frame memory contents remain unchanged. + * No status bits are changed. + */ #define set_gamma_curve 0x26 -/* ************************************************************************* *\ -This command selects the desired gamma curve for the display device. -Four fixed gamma curves are defined in section DCS spec. -\* ************************************************************************* */ +/* + * This command selects the desired gamma curve for the display device. + * Four fixed gamma curves are defined in section DCS spec. + */ #define set_display_off 0x28 /* ************************************************************************* *\ This command causes the display module to stop displaying the image data @@ -1020,77 +952,80 @@ on the display device. The frame memory contents remain unchanged. No status bits are changed. \* ************************************************************************* */ #define set_column_address 0x2a -/* ************************************************************************* *\ -This command defines the column extent of the frame memory accessed by the -hostprocessor with the read_memory_continue and write_memory_continue commands. -No status bits are changed. -\* ************************************************************************* */ +/* + * This command defines the column extent of the frame memory accessed by + * the hostprocessor with the read_memory_continue and + * write_memory_continue commands. + * No status bits are changed. + */ #define set_page_addr 0x2b -/* ************************************************************************* *\ -This command defines the page extent of the frame memory accessed by the host -processor with the write_memory_continue and read_memory_continue command. -No status bits are changed. -\* ************************************************************************* */ +/* + * This command defines the page extent of the frame memory accessed by + * the host processor with the write_memory_continue and + * read_memory_continue command. + * No status bits are changed. + */ #define write_mem_start 0x2c -/* ************************************************************************* *\ -This command transfers image data from the host processor to the display -module s frame memory starting at the pixel location specified by -preceding set_column_address and set_page_address commands. -\* ************************************************************************* */ +/* + * This command transfers image data from the host processor to the + * display module s frame memory starting at the pixel location specified + * by preceding set_column_address and set_page_address commands. + */ #define set_partial_area 0x30 -/* ************************************************************************* *\ -This command defines the Partial Display mode s display area. -There are two parameters associated with -this command, the first defines the Start Row (SR) and the second the End Row -(ER). SR and ER refer to the Frame Memory Line Pointer. -\* ************************************************************************* */ +/* + * This command defines the Partial Display mode s display area. + * There are two parameters associated with this command, the first + * defines the Start Row (SR) and the second the End Row (ER). SR and ER + * refer to the Frame Memory Line Pointer. + */ #define set_scroll_area 0x33 -/* ************************************************************************* *\ -This command defines the display modules Vertical Scrolling Area. -\* ************************************************************************* */ +/* + * This command defines the display modules Vertical Scrolling Area. + */ #define set_tear_off 0x34 -/* ************************************************************************* *\ -This command turns off the display modules Tearing Effect output signal on -the TE signal line. -\* ************************************************************************* */ +/* + * This command turns off the display modules Tearing Effect output + * signal on the TE signal line. + */ #define set_tear_on 0x35 -/* ************************************************************************* *\ -This command turns on the display modules Tearing Effect output signal -on the TE signal line. -\* ************************************************************************* */ +/* + * This command turns on the display modules Tearing Effect output signal + * on the TE signal line. + */ #define set_address_mode 0x36 -/* ************************************************************************* *\ -This command sets the data order for transfers from the host processor to -display modules frame memory,bits B[7:5] and B3, and from the display -modules frame memory to the display device, bits B[2:0] and B4. -\* ************************************************************************* */ +/* + * This command sets the data order for transfers from the host processor + * to display modules frame memory,bits B[7:5] and B3, and from the + * display modules frame memory to the display device, bits B[2:0] and B4. + */ #define set_scroll_start 0x37 -/* ************************************************************************* *\ -This command sets the start of the vertical scrolling area in the frame memory. -The vertical scrolling area is fully defined when this command is used with -the set_scroll_area command The set_scroll_start command has one parameter, -the Vertical Scroll Pointer. The VSP defines the line in the frame memory -that is written to the display device as the first line of the vertical -scroll area. -\* ************************************************************************* */ +/* + * This command sets the start of the vertical scrolling area in the frame + * memory. The vertical scrolling area is fully defined when this command + * is used with the set_scroll_area command The set_scroll_start command + * has one parameter, the Vertical Scroll Pointer. The VSP defines the + * line in the frame memory that is written to the display device as the + * first line of the vertical scroll area. + */ #define exit_idle_mode 0x38 -/* ************************************************************************* *\ -This command causes the display module to exit Idle mode. -\* ************************************************************************* */ +/* + * This command causes the display module to exit Idle mode. + */ #define enter_idle_mode 0x39 -/* ************************************************************************* *\ -This command causes the display module to enter Idle Mode. -In Idle Mode, color expression is reduced. Colors are shown on the display -device using the MSB of each of the R, G and B color components in the frame -memory -\* ************************************************************************* */ +/* + * This command causes the display module to enter Idle Mode. + * In Idle Mode, color expression is reduced. Colors are shown on the + * display device using the MSB of each of the R, G and B color + * components in the frame memory + */ #define set_pixel_format 0x3a -/* ************************************************************************* *\ -This command sets the pixel format for the RGB image data used by the interface. -Bits D[6:4] DPI Pixel Format Definition -Bits D[2:0] DBI Pixel Format Definition -Bits D7 and D3 are not used. -\* ************************************************************************* */ +/* + * This command sets the pixel format for the RGB image data used by the + * interface. + * Bits D[6:4] DPI Pixel Format Definition + * Bits D[2:0] DBI Pixel Format Definition + * Bits D7 and D3 are not used. + */ #define DCS_PIXEL_FORMAT_3bbp 0x1 #define DCS_PIXEL_FORMAT_8bbp 0x2 #define DCS_PIXEL_FORMAT_12bbp 0x3 @@ -1098,24 +1033,25 @@ Bits D7 and D3 are not used. #define DCS_PIXEL_FORMAT_18bbp 0x6 #define DCS_PIXEL_FORMAT_24bbp 0x7 #define write_mem_cont 0x3c -/* ************************************************************************* *\ -This command transfers image data from the host processor to the display -module's frame memory continuing from the pixel location following the -previous write_memory_continue or write_memory_start command. -\* ************************************************************************* */ +/* + * This command transfers image data from the host processor to the + * display module's frame memory continuing from the pixel location + * following the previous write_memory_continue or write_memory_start + * command. + */ #define set_tear_scanline 0x44 -/* ************************************************************************* *\ -This command turns on the display modules Tearing Effect output signal on the -TE signal line when the display module reaches line N. -\* ************************************************************************* */ +/* + * This command turns on the display modules Tearing Effect output signal + * on the TE signal line when the display module reaches line N. + */ #define get_scanline 0x45 -/* ************************************************************************* *\ -The display module returns the current scanline, N, used to update the -display device. The total number of scanlines on a display device is -defined as VSYNC + VBP + VACT + VFP.The first scanline is defined as -the first line of V Sync and is denoted as Line 0. -When in Sleep Mode, the value returned by get_scanline is undefined. -\* ************************************************************************* */ +/* + * The display module returns the current scanline, N, used to update the + * display device. The total number of scanlines on a display device is + * defined as VSYNC + VBP + VACT + VFP.The first scanline is defined as + * the first line of V Sync and is denoted as Line 0. + * When in Sleep Mode, the value returned by get_scanline is undefined. + */ /* MCS or Generic COMMANDS */ /* MCS/generic data type */ @@ -1131,7 +1067,7 @@ When in Sleep Mode, the value returned by get_scanline is undefined. #define MCS_READ 0x06 /* MCS read, no parameters */ #define MCS_LONG_WRITE 0x39 /* MCS long write */ /* MCS/generic commands */ -/*****TPO MCS**********/ +/* TPO MCS */ #define write_display_profile 0x50 #define write_display_brightness 0x51 #define write_ctrl_display 0x53 @@ -1143,19 +1079,19 @@ When in Sleep Mode, the value returned by get_scanline is undefined. #define write_gamma_setting 0x58 #define write_cabc_min_bright 0x5e #define write_kbbc_profile 0x60 -/*****TMD MCS**************/ +/* TMD MCS */ #define tmd_write_display_brightness 0x8c -/* ************************************************************************* *\ -This command is used to control ambient light, panel backlight brightness and -gamma settings. -\* ************************************************************************* */ -#define BRIGHT_CNTL_BLOCK_ON BIT5 -#define AMBIENT_LIGHT_SENSE_ON BIT4 -#define DISPLAY_DIMMING_ON BIT3 -#define BACKLIGHT_ON BIT2 -#define DISPLAY_BRIGHTNESS_AUTO BIT1 -#define GAMMA_AUTO BIT0 +/* + * This command is used to control ambient light, panel backlight + * brightness and gamma settings. + */ +#define BRIGHT_CNTL_BLOCK_ON (1 << 5) +#define AMBIENT_LIGHT_SENSE_ON (1 << 4) +#define DISPLAY_DIMMING_ON (1 << 3) +#define BACKLIGHT_ON (1 << 2) +#define DISPLAY_BRIGHTNESS_AUTO (1 << 1) +#define GAMMA_AUTO (1 << 0) /* DCS Interface Pixel Formats */ #define DCS_PIXEL_FORMAT_3BPP 0x1 @@ -1190,8 +1126,9 @@ gamma settings. * byte alignment */ #define DBI_CB_TIME_OUT 0xFFFF -#define GEN_FB_TIME_OUT 2000 -#define ALIGNMENT_32BYTE_MASK (~(BIT0|BIT1|BIT2|BIT3|BIT4)) + +#define GEN_FB_TIME_OUT 2000 +#define ALIGNMENT_32BYTE_MASK (~((1 << 0)|(1 << 1)|(1 << 2)|(1 << 3)|(1 << 4))) #define SKU_83 0x01 #define SKU_100 0x02 #define SKU_100L 0x04 diff --git a/drivers/staging/gma500/psb_irq.c b/drivers/staging/gma500/psb_irq.c index ce7dbf4e555c..4597c8824721 100644 --- a/drivers/staging/gma500/psb_irq.c +++ b/drivers/staging/gma500/psb_irq.c @@ -422,9 +422,9 @@ void psb_irq_turn_on_dpst(struct drm_device *dev) if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) { - PSB_WVDC32(BIT31, HISTOGRAM_LOGIC_CONTROL); + PSB_WVDC32(1 << 31, HISTOGRAM_LOGIC_CONTROL); hist_reg = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL); - PSB_WVDC32(BIT31, HISTOGRAM_INT_CONTROL); + PSB_WVDC32(1 << 31, HISTOGRAM_INT_CONTROL); hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL); PSB_WVDC32(0x80010100, PWM_CONTROL_LOGIC); diff --git a/drivers/staging/gma500/psb_powermgmt.c b/drivers/staging/gma500/psb_powermgmt.c index 39fa66a5f5d4..7deb1ba82545 100644 --- a/drivers/staging/gma500/psb_powermgmt.c +++ b/drivers/staging/gma500/psb_powermgmt.c @@ -287,11 +287,6 @@ static void ospm_suspend_pci(struct pci_dev *pdev) printk(KERN_ALERT "ospm_suspend_pci\n"); #endif -#ifdef CONFIG_MDFD_GL3 - // Power off GL3 after all GFX sub-systems are powered off. - ospm_power_island_down(OSPM_GL3_CACHE_ISLAND); -#endif - pci_save_state(pdev); pci_read_config_dword(pdev, 0x5C, &bsm); dev_priv->saveBSM = bsm; -- cgit v1.2.3 From bc54f3393c0563a00c13d2b58aca23ae153bdd3b Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 3 Mar 2011 12:38:17 +0000 Subject: staging: gma500: fix build errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch will fix following compilation error: drivers/staging/gma500/psb_drv.c:1635: error: unknown field ‘pci_driver’ specified in initializer drivers/staging/gma500/psb_drv.c:1636: error: unknown field ‘name’ specified in initializer drivers/staging/gma500/psb_drv.c:1636: warning: initialization from incompatible pointer type drivers/staging/gma500/psb_drv.c:1637: error: unknown field ‘id_table’ specified in initializer drivers/staging/gma500/psb_drv.c:1637: warning: excess elements in union initializer drivers/staging/gma500/psb_drv.c:1637: warning: (near initialization for ‘driver.kdriver’) drivers/staging/gma500/psb_drv.c:1638: error: unknown field ‘resume’ specified in initializer drivers/staging/gma500/psb_drv.c:1638: warning: excess elements in union initializer drivers/staging/gma500/psb_drv.c:1638: warning: (near initialization for ‘driver.kdriver’) drivers/staging/gma500/psb_drv.c:1639: error: unknown field ‘suspend’ specified in initializer drivers/staging/gma500/psb_drv.c:1639: warning: excess elements in union initializer drivers/staging/gma500/psb_drv.c:1639: warning: (near initialization for ‘driver.kdriver’) drivers/staging/gma500/psb_drv.c:1640: error: unknown field ‘probe’ specified in initializer drivers/staging/gma500/psb_drv.c:1640: warning: excess elements in union initializer drivers/staging/gma500/psb_drv.c:1640: warning: (near initialization for ‘driver.kdriver’) drivers/staging/gma500/psb_drv.c:1641: error: unknown field ‘remove’ specified in initializer drivers/staging/gma500/psb_drv.c:1641: warning: excess elements in union initializer drivers/staging/gma500/psb_drv.c:1641: warning: (near initialization for ‘driver.kdriver’) drivers/staging/gma500/psb_drv.c:1643: error: unknown field ‘driver’ specified in initializer drivers/staging/gma500/psb_drv.c:1643: warning: excess elements in union initializer drivers/staging/gma500/psb_drv.c:1643: warning: (near initialization for ‘driver.kdriver’) drivers/staging/gma500/psb_drv.c: In function ‘psb_init’: drivers/staging/gma500/psb_drv.c:1664: error: implicit declaration of function ‘drm_init’ drivers/staging/gma500/psb_drv.c: In function ‘psb_exit’: drivers/staging/gma500/psb_drv.c:1669: error: implicit declaration of function ‘drm_exit’ Signed-off-by: Marek Belisko Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gma500/psb_drv.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index 090d9a2e60bf..44cd095d2862 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -1601,17 +1601,6 @@ static struct drm_driver driver = { .fasync = drm_fasync, .read = drm_read, }, - .pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - .resume = ospm_power_resume, - .suspend = ospm_power_suspend, - .probe = psb_probe, - .remove = psb_remove, -#ifdef CONFIG_PM - .driver.pm = &psb_pm_ops, -#endif - }, .name = DRIVER_NAME, .desc = DRIVER_DESC, .date = PSB_DRM_DRIVER_DATE, @@ -1620,6 +1609,18 @@ static struct drm_driver driver = { .patchlevel = PSB_DRM_DRIVER_PATCHLEVEL }; +static struct pci_driver psb_pci_driver = { + .name = DRIVER_NAME, + .id_table = pciidlist, + .resume = ospm_power_resume, + .suspend = ospm_power_suspend, + .probe = psb_probe, + .remove = psb_remove, +#ifdef CONFIG_PM + .driver.pm = &psb_pm_ops, +#endif +}; + static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { /* MLD Added this from Inaky's patch */ @@ -1630,12 +1631,12 @@ static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) static int __init psb_init(void) { - return drm_init(&driver); + return drm_pci_init(&driver, &psb_pci_driver); } static void __exit psb_exit(void) { - drm_exit(&driver); + drm_pci_exit(&driver, &psb_pci_driver); } late_initcall(psb_init); -- cgit v1.2.3 From 2cb61ea25b49049f9281007f8b534e5d384ebba5 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:40:30 +0900 Subject: staging: rtl8192e: Add a spinlock around SetRFPowerState8190 Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8190_rtl8256.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index 8b182089b046..40a169df5123 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -327,8 +327,11 @@ SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); bool bResult = true; - if(priv->SetRFPowerStateInProgress == true) - return false; + spin_lock(&priv->ps_lock); + if (priv->SetRFPowerStateInProgress) { + bResult = false; + goto out; + } priv->SetRFPowerStateInProgress = true; switch( eRFPowerState ) @@ -345,8 +348,8 @@ SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) */ if (!NicIFEnableNIC(dev)) { RT_TRACE(COMP_ERR, "%s(): NicIFEnableNIC failed\n",__FUNCTION__); - priv->SetRFPowerStateInProgress = false; - return false; + bResult = false; + goto out; } RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); @@ -424,7 +427,9 @@ SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) priv->ieee80211->eRFPowerState = eRFPowerState; } +out: priv->SetRFPowerStateInProgress = false; + spin_unlock(&priv->ps_lock); return bResult; } -- cgit v1.2.3 From fea84ba0f982a57598a92cd806904395f1b8839f Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:40:41 +0900 Subject: staging: rtl8192e: Remove SetRFPowerStateInProgress Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8190_rtl8256.c | 6 ------ drivers/staging/rtl8192e/r8192E.h | 1 - drivers/staging/rtl8192e/r8192E_core.c | 1 - 3 files changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index 40a169df5123..0b6c7f9786fb 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -328,11 +328,6 @@ SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) bool bResult = true; spin_lock(&priv->ps_lock); - if (priv->SetRFPowerStateInProgress) { - bResult = false; - goto out; - } - priv->SetRFPowerStateInProgress = true; switch( eRFPowerState ) { @@ -428,7 +423,6 @@ SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) } out: - priv->SetRFPowerStateInProgress = false; spin_unlock(&priv->ps_lock); return bResult; } diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 220f2b11424e..0c20fae493dd 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1011,7 +1011,6 @@ typedef struct r8192_priv bool bHwRadioOff; //by amy for ps bool RFChangeInProgress; // RF Chnage in progress, by Bruce, 2007-10-30 - bool SetRFPowerStateInProgress; RT_OP_MODE OpMode; //by amy for reset_count u32 reset_count; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 8f68ac07b567..ec68f948cb5d 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1986,7 +1986,6 @@ static void rtl8192_init_priv_variable(struct net_device* dev) priv->ieee80211->RfOffReason = 0; priv->RFChangeInProgress = false; priv->bHwRfOffAction = 0; - priv->SetRFPowerStateInProgress = false; priv->ieee80211->PowerSaveControl.bInactivePs = true; priv->ieee80211->PowerSaveControl.bIPSModeBackup = false; -- cgit v1.2.3 From 0903602e2c2f796d63ef7b73e2888c6d13899140 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:40:52 +0900 Subject: staging: rtl8192e: Remove SetRFPowerState Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8190_rtl8256.c | 40 ++++++-------------------------- 1 file changed, 7 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index 0b6c7f9786fb..00eaecd72ca5 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -329,6 +329,12 @@ SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) spin_lock(&priv->ps_lock); + if (eRFPowerState == priv->ieee80211->eRFPowerState && + priv->bHwRfOffAction == 0) { + bResult = false; + goto out; + } + switch( eRFPowerState ) { case eRfOn: @@ -429,39 +435,7 @@ out: -// -// Description: -// Change RF power state. -// -// Assumption: -// This function must be executed in re-schdulable context, -// ie. PASSIVE_LEVEL. -// -// 050823, by rcnjko. -// -static bool -SetRFPowerState( - struct net_device* dev, - RT_RF_POWER_STATE eRFPowerState - ) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - bool bResult = false; - - RT_TRACE(COMP_RF,"---------> SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState); - if(eRFPowerState == priv->ieee80211->eRFPowerState && priv->bHwRfOffAction == 0) - { - RT_TRACE(COMP_POWER, "<--------- SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState); - return bResult; - } - - bResult = SetRFPowerState8190(dev, eRFPowerState); - - RT_TRACE(COMP_POWER, "<--------- SetRFPowerState(): bResult(%d)\n", bResult); - return bResult; -} static void MgntDisconnectIBSS( @@ -749,7 +723,7 @@ MgntActSet_RF_State( { RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->ieee80211->RfOffReason); // Config HW to the specified mode. - SetRFPowerState(dev, StateToSet); + SetRFPowerState8190(dev, StateToSet); } else { -- cgit v1.2.3 From 09f143791cc88bdbff0f1f8f2a6a747da896601b Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:41:02 +0900 Subject: staging: rtl8192e: Use single spinlock in MgntActSet_RF_State Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8190_rtl8256.c | 41 ++------------------------------ drivers/staging/rtl8192e/r8192E.h | 1 - drivers/staging/rtl8192e/r8192E_core.c | 24 ------------------- 3 files changed, 2 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index 00eaecd72ca5..9513af9268cb 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -638,45 +638,10 @@ MgntActSet_RF_State( bool bActionAllowed = false; bool bConnectBySSID = false; RT_RF_POWER_STATE rtState; - u16 RFWaitCounter = 0; - RT_TRACE(COMP_POWER, "===>MgntActSet_RF_State(): StateToSet(%d)\n",StateToSet); - - //1// - //1//<1>Prevent the race condition of RF state change. - //1// - // Only one thread can change the RF state at one time, and others should wait to be executed. By Bruce, 2007-11-28. - - while(true) - { - spin_lock(&priv->rf_ps_lock); - if(priv->RFChangeInProgress) - { - spin_unlock(&priv->rf_ps_lock); - RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): RF Change in progress! Wait to set..StateToSet(%d).\n", StateToSet); - // Set RF after the previous action is done. - while(priv->RFChangeInProgress) - { - RFWaitCounter ++; - RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Wait 1 ms (%d times)...\n", RFWaitCounter); - udelay(1000); // 1 ms + RT_TRACE(COMP_POWER, "===>MgntActSet_RF_State(): StateToSet(%d)\n",StateToSet); - // Wait too long, return FALSE to avoid to be stuck here. - if(RFWaitCounter > 100) - { - RT_TRACE(COMP_ERR, "MgntActSet_RF_State(): Wait too logn to set RF\n"); - // TODO: Reset RF state? - return false; - } - } - } - else - { - priv->RFChangeInProgress = true; - spin_unlock(&priv->rf_ps_lock); - break; - } - } + spin_lock(&priv->rf_ps_lock); rtState = priv->ieee80211->eRFPowerState; @@ -731,8 +696,6 @@ MgntActSet_RF_State( } // Release RF spinlock - spin_lock(&priv->rf_ps_lock); - priv->RFChangeInProgress = false; spin_unlock(&priv->rf_ps_lock); RT_TRACE(COMP_POWER, "<===MgntActSet_RF_State()\n"); diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 0c20fae493dd..4278091a9b15 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1010,7 +1010,6 @@ typedef struct r8192_priv //by amy for gpio bool bHwRadioOff; //by amy for ps - bool RFChangeInProgress; // RF Chnage in progress, by Bruce, 2007-10-30 RT_OP_MODE OpMode; //by amy for reset_count u32 reset_count; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index ec68f948cb5d..0c88a2592e56 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1849,17 +1849,6 @@ static short rtl8192_is_tx_queue_empty(struct net_device *dev) static void rtl8192_hw_sleep_down(struct net_device *dev) { - struct r8192_priv *priv = ieee80211_priv(dev); - - spin_lock(&priv->rf_ps_lock); - if (priv->RFChangeInProgress) { - spin_unlock(&priv->rf_ps_lock); - RT_TRACE(COMP_RF, "rtl8192_hw_sleep_down(): RF Change in progress!\n"); - printk("rtl8192_hw_sleep_down(): RF Change in progress!\n"); - return; - } - spin_unlock(&priv->rf_ps_lock); - MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS); } @@ -1874,18 +1863,6 @@ static void rtl8192_hw_sleep_wq (struct work_struct *work) static void rtl8192_hw_wakeup(struct net_device* dev) { - struct r8192_priv *priv = ieee80211_priv(dev); - - spin_lock(&priv->rf_ps_lock); - if (priv->RFChangeInProgress) { - spin_unlock(&priv->rf_ps_lock); - RT_TRACE(COMP_RF, "rtl8192_hw_wakeup(): RF Change in progress!\n"); - printk("rtl8192_hw_wakeup(): RF Change in progress! schedule wake up task again\n"); - queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->hw_wakeup_wq,MSECS(10));//PowerSave is not supported if kernel version is below 2.6.20 - return; - } - spin_unlock(&priv->rf_ps_lock); - MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS); } @@ -1984,7 +1961,6 @@ static void rtl8192_init_priv_variable(struct net_device* dev) priv->force_reset = false; //added by amy for power save priv->ieee80211->RfOffReason = 0; - priv->RFChangeInProgress = false; priv->bHwRfOffAction = 0; priv->ieee80211->PowerSaveControl.bInactivePs = true; priv->ieee80211->PowerSaveControl.bIPSModeBackup = false; -- cgit v1.2.3 From 0d65112ac0f083c77514c9e83958860d542b1d1a Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:41:12 +0900 Subject: staging: rtl8192e: Remove unnecessary ps_lock Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8190_rtl8256.c | 3 --- drivers/staging/rtl8192e/r8192E.h | 1 - drivers/staging/rtl8192e/r8192E_core.c | 9 ++------- 3 files changed, 2 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index 9513af9268cb..0838bec7b682 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -327,8 +327,6 @@ SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); bool bResult = true; - spin_lock(&priv->ps_lock); - if (eRFPowerState == priv->ieee80211->eRFPowerState && priv->bHwRfOffAction == 0) { bResult = false; @@ -429,7 +427,6 @@ SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) } out: - spin_unlock(&priv->ps_lock); return bResult; } diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 4278091a9b15..9b93ed9a5750 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -808,7 +808,6 @@ typedef struct r8192_priv spinlock_t irq_th_lock; spinlock_t rf_ps_lock; struct mutex mutex; - spinlock_t ps_lock; short chan; short sens; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 0c88a2592e56..cc20e5d7f5af 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1883,8 +1883,6 @@ static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl) u32 tmp; u32 rb = jiffies; - spin_lock(&priv->ps_lock); - // Writing HW register with 0 equals to disable // the timer, that is not really what we want // @@ -1897,14 +1895,14 @@ static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl) if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME)) ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) { printk("too short to sleep::%x, %x, %lx\n",tl, rb, MSECS(MIN_SLEEP_TIME)); - goto out_unlock; + return; } if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))|| ((tl < rb) && (tl>MSECS(69)) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))|| ((tlMSECS(MAX_SLEEP_TIME)))) { printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME)); - goto out_unlock; + return; } tmp = (tl>rb)?(tl-rb):(rb-tl); @@ -1913,8 +1911,6 @@ static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl) queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0); -out_unlock: - spin_unlock(&priv->ps_lock); } static void rtl8192_init_priv_variable(struct net_device* dev) @@ -2043,7 +2039,6 @@ static void rtl8192_init_priv_lock(struct r8192_priv* priv) { spin_lock_init(&priv->irq_th_lock); spin_lock_init(&priv->rf_ps_lock); - spin_lock_init(&priv->ps_lock); sema_init(&priv->wx_sem,1); sema_init(&priv->rf_sem,1); mutex_init(&priv->mutex); -- cgit v1.2.3 From 477dfe7069ba8458f7ffe25c5ffcb91e70407bba Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:41:25 +0900 Subject: staging: rtl8192e: Remove pointless hw_sleep_wq Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 1 - drivers/staging/rtl8192e/r8192E_core.c | 14 +------------- 2 files changed, 1 insertion(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index 9a5f788d97ce..8501c4aced6f 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -2268,7 +2268,6 @@ struct ieee80211_device { struct delayed_work associate_retry_wq; struct delayed_work start_ibss_wq; struct delayed_work hw_wakeup_wq; - struct delayed_work hw_sleep_wq; struct work_struct wx_sync_scan_wq; struct workqueue_struct *wq; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index cc20e5d7f5af..2897ac251737 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1852,15 +1852,6 @@ static void rtl8192_hw_sleep_down(struct net_device *dev) MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS); } -static void rtl8192_hw_sleep_wq (struct work_struct *work) -{ - struct delayed_work *dwork = container_of(work,struct delayed_work,work); - struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq); - struct net_device *dev = ieee->dev; - - rtl8192_hw_sleep_down(dev); -} - static void rtl8192_hw_wakeup(struct net_device* dev) { MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS); @@ -1909,8 +1900,7 @@ static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl) queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq,tmp); - queue_delayed_work(priv->ieee80211->wq, - (void *)&priv->ieee80211->hw_sleep_wq,0); + rtl8192_hw_sleep_down(dev); } static void rtl8192_init_priv_variable(struct net_device* dev) @@ -2063,7 +2053,6 @@ static void rtl8192_init_priv_task(struct net_device* dev) INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon); INIT_WORK(&priv->qos_activate, rtl8192_qos_activate); INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq, rtl8192_hw_wakeup_wq); - INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq, rtl8192_hw_sleep_wq); tasklet_init(&priv->irq_rx_tasklet, rtl8192_irq_rx_tasklet, (unsigned long) priv); @@ -4802,7 +4791,6 @@ static void rtl8192_cancel_deferred_work(struct r8192_priv* priv) cancel_delayed_work(&priv->watch_dog_wq); cancel_delayed_work(&priv->update_beacon_wq); cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq); - cancel_delayed_work(&priv->ieee80211->hw_sleep_wq); cancel_delayed_work(&priv->gpio_change_rf_wq); cancel_work_sync(&priv->reset_wq); cancel_work_sync(&priv->qos_activate); -- cgit v1.2.3 From 4559854d2db145e5c9a7c217f058e7bad706c097 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:41:35 +0900 Subject: staging: rtl8192e: Move eRFPowerState to r8192e_priv struct Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 1 - drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c | 11 ----------- drivers/staging/rtl8192e/r8190_rtl8256.c | 10 +++++----- drivers/staging/rtl8192e/r8192E.h | 2 ++ drivers/staging/rtl8192e/r8192E_core.c | 18 +++++++++--------- drivers/staging/rtl8192e/r8192E_wx.c | 6 +++--- drivers/staging/rtl8192e/r819xE_phy.c | 4 ++-- 7 files changed, 21 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index 8501c4aced6f..8d2b5758d32f 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -1988,7 +1988,6 @@ struct ieee80211_device { RT_PS_MODE dot11PowerSaveMode; // Power save mode configured. bool actscanning; bool beinretry; - RT_RF_POWER_STATE eRFPowerState; RT_RF_CHANGE_SOURCE RfOffReason; bool is_set_key; //11n spec related I wonder if These info structure need to be moved out of ieee80211_device diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index 2640a4f2e81f..012256c0fc52 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -1420,17 +1420,6 @@ void ieee80211_associate_procedure_wq(struct work_struct *work) printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel); HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); -#ifdef ENABLE_IPS - if(ieee->eRFPowerState == eRfOff) - { - if(ieee->ieee80211_ips_leave_wq != NULL) - ieee->ieee80211_ips_leave_wq(ieee->dev); - - up(&ieee->wx_sem); - return; - } -#endif - ieee->associate_seq = 1; ieee80211_associate_step1(ieee); diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index 0838bec7b682..14d62bfc3455 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -327,7 +327,7 @@ SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); bool bResult = true; - if (eRFPowerState == priv->ieee80211->eRFPowerState && + if (eRFPowerState == priv->eRFPowerState && priv->bHwRfOffAction == 0) { bResult = false; goto out; @@ -338,7 +338,7 @@ SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) case eRfOn: // turn on RF - if ((priv->ieee80211->eRFPowerState == eRfOff) && + if ((priv->eRFPowerState == eRfOff) && RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) { /* @@ -384,7 +384,7 @@ SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) case eRfSleep: // HW setting had been configured with deeper mode. - if(priv->ieee80211->eRFPowerState == eRfOff) + if(priv->eRFPowerState == eRfOff) break; r8192e_drain_tx_queues(priv); @@ -423,7 +423,7 @@ SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) if(bResult) { // Update current RF state variable. - priv->ieee80211->eRFPowerState = eRFPowerState; + priv->eRFPowerState = eRFPowerState; } out: @@ -640,7 +640,7 @@ MgntActSet_RF_State( spin_lock(&priv->rf_ps_lock); - rtState = priv->ieee80211->eRFPowerState; + rtState = priv->eRFPowerState; switch(StateToSet) { diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 9b93ed9a5750..59cdfc7cce5c 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -37,6 +37,7 @@ #include #include #include +#include "ieee80211/rtl819x_HT.h" #include "ieee80211/ieee80211.h" @@ -929,6 +930,7 @@ typedef struct r8192_priv char CCKPresentAttentuation_difference; char CCKPresentAttentuation; // Use to calculate PWBD. + RT_RF_POWER_STATE eRFPowerState; u8 bCckHighPower; long undecorated_smoothed_pwdb; long undecorated_smoothed_cck_adc_pwdb[4]; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 2897ac251737..5e25353dbc53 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -2847,7 +2847,7 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) else { RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): RF-ON \n",__FUNCTION__); - priv->ieee80211->eRFPowerState = eRfOn; + priv->eRFPowerState = eRfOn; priv->ieee80211->RfOffReason = 0; } } @@ -3059,7 +3059,7 @@ rtl819x_ifcheck_resetornot(struct net_device *dev) RESET_TYPE RxResetType = RESET_TYPE_NORESET; RT_RF_POWER_STATE rfState; - rfState = priv->ieee80211->eRFPowerState; + rfState = priv->eRFPowerState; if( rfState != eRfOff && /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/ @@ -3218,7 +3218,7 @@ IPSEnter(struct net_device *dev) if (pPSC->bInactivePs) { - rtState = priv->ieee80211->eRFPowerState; + rtState = priv->eRFPowerState; // // Added by Bruce, 2007-12-25. // Do not enter IPS in the following conditions: @@ -3253,7 +3253,7 @@ IPSLeave(struct net_device *dev) if (pPSC->bInactivePs) { - rtState = priv->ieee80211->eRFPowerState; + rtState = priv->eRFPowerState; if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS) { RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n"); @@ -3278,7 +3278,7 @@ void ieee80211_ips_leave_wq(struct net_device *dev) { struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); RT_RF_POWER_STATE rtState; - rtState = priv->ieee80211->eRFPowerState; + rtState = priv->eRFPowerState; if(priv->ieee80211->PowerSaveControl.bInactivePs){ if(rtState == eRfOff){ @@ -3345,7 +3345,7 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) #ifdef ENABLE_IPS if(ieee->actscanning == false){ if((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == IEEE80211_NOLINK) && - (ieee->eRFPowerState == eRfOn)&&!ieee->is_set_key && + (priv->eRFPowerState == eRfOn) && !ieee->is_set_key && (!ieee->proto_stoppping) && !ieee->wx_set_enc){ if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){ IPSEnter(dev); @@ -3408,7 +3408,7 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum); if((TotalRxBcnNum+TotalRxDataNum) == 0) { - if( ieee->eRFPowerState == eRfOff) + if (priv->eRFPowerState == eRfOff) RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__); printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__); // Dot11d_Reset(dev); @@ -3478,7 +3478,7 @@ static int _rtl8192_up(struct net_device *dev) } RT_TRACE(COMP_INIT, "start adapter finished\n"); - if(priv->ieee80211->eRFPowerState!=eRfOn) + if (priv->eRFPowerState != eRfOn) MgntActSet_RF_State(dev, eRfOn, priv->ieee80211->RfOffReason); if(priv->ieee80211->state != IEEE80211_LINKED) @@ -5045,7 +5045,7 @@ void setKey( struct net_device *dev, #ifdef ENABLE_IPS struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); RT_RF_POWER_STATE rtState; - rtState = priv->ieee80211->eRFPowerState; + rtState = priv->eRFPowerState; if(priv->ieee80211->PowerSaveControl.bInactivePs){ if(rtState == eRfOff){ if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS) diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c index bd89bb04955e..280a1b720c34 100644 --- a/drivers/staging/rtl8192e/r8192E_wx.c +++ b/drivers/staging/rtl8192e/r8192E_wx.c @@ -215,7 +215,7 @@ static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a, if (priv->bHwRadioOff) return 0; - rtState = priv->ieee80211->eRFPowerState; + rtState = priv->eRFPowerState; down(&priv->wx_sem); #ifdef ENABLE_IPS if(wrqu->mode == IW_MODE_ADHOC){ @@ -384,7 +384,7 @@ static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a, if (priv->bHwRadioOff) return 0; - rtState = priv->ieee80211->eRFPowerState; + rtState = priv->eRFPowerState; if(!priv->up) return -ENETDOWN; if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true) @@ -475,7 +475,7 @@ static int r8192_wx_set_essid(struct net_device *dev, if (priv->bHwRadioOff) return 0; - rtState = priv->ieee80211->eRFPowerState; + rtState = priv->eRFPowerState; down(&priv->wx_sem); #ifdef ENABLE_IPS diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c index f4d220ad322a..44e1123797c4 100644 --- a/drivers/staging/rtl8192e/r819xE_phy.c +++ b/drivers/staging/rtl8192e/r819xE_phy.c @@ -810,7 +810,7 @@ void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) return; - if(priv->ieee80211->eRFPowerState != eRfOn && !priv->being_init_adapter) + if (priv->eRFPowerState != eRfOn && !priv->being_init_adapter) return; //down(&priv->rf_sem); @@ -859,7 +859,7 @@ u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u3 struct r8192_priv *priv = ieee80211_priv(dev); if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) return 0; - if(priv->ieee80211->eRFPowerState != eRfOn && !priv->being_init_adapter) + if (priv->eRFPowerState != eRfOn && !priv->being_init_adapter) return 0; down(&priv->rf_sem); if (priv->Rf_Mode == RF_OP_By_FW) -- cgit v1.2.3 From 181d1dff582a10c0af2adf9f5f06ac17dbdeae8a Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:41:53 +0900 Subject: staging: rtl8192e: Move RfOffReason to r8192e_priv struct Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 1 - drivers/staging/rtl8192e/r8190_rtl8256.c | 18 +++++++++--------- drivers/staging/rtl8192e/r8192E.h | 1 + drivers/staging/rtl8192e/r8192E_core.c | 24 ++++++++++++------------ drivers/staging/rtl8192e/r8192E_wx.c | 4 ++-- 5 files changed, 24 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index 8d2b5758d32f..f0627b1fd964 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -1988,7 +1988,6 @@ struct ieee80211_device { RT_PS_MODE dot11PowerSaveMode; // Power save mode configured. bool actscanning; bool beinretry; - RT_RF_CHANGE_SOURCE RfOffReason; bool is_set_key; //11n spec related I wonder if These info structure need to be moved out of ieee80211_device diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index 14d62bfc3455..ed45bcdb8367 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -645,11 +645,11 @@ MgntActSet_RF_State( switch(StateToSet) { case eRfOn: - priv->ieee80211->RfOffReason &= (~ChangeSource); + priv->RfOffReason &= (~ChangeSource); - if(! priv->ieee80211->RfOffReason) + if (!priv->RfOffReason) { - priv->ieee80211->RfOffReason = 0; + priv->RfOffReason = 0; bActionAllowed = true; @@ -659,37 +659,37 @@ MgntActSet_RF_State( } } else - RT_TRACE(COMP_POWER, "MgntActSet_RF_State - eRfon reject pMgntInfo->RfOffReason= 0x%x, ChangeSource=0x%X\n", priv->ieee80211->RfOffReason, ChangeSource); + RT_TRACE(COMP_POWER, "MgntActSet_RF_State - eRfon reject pMgntInfo->RfOffReason= 0x%x, ChangeSource=0x%X\n", priv->RfOffReason, ChangeSource); break; case eRfOff: - if (priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS) + if (priv->RfOffReason > RF_CHANGE_BY_IPS) { // Disconnect to current BSS when radio off. Asked by QuanTa. MgntDisconnect(dev, disas_lv_ss); } - priv->ieee80211->RfOffReason |= ChangeSource; + priv->RfOffReason |= ChangeSource; bActionAllowed = true; break; case eRfSleep: - priv->ieee80211->RfOffReason |= ChangeSource; + priv->RfOffReason |= ChangeSource; bActionAllowed = true; break; } if (bActionAllowed) { - RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->ieee80211->RfOffReason); + RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->RfOffReason); // Config HW to the specified mode. SetRFPowerState8190(dev, StateToSet); } else { - RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n", StateToSet, ChangeSource, priv->ieee80211->RfOffReason); + RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n", StateToSet, ChangeSource, priv->RfOffReason); } // Release RF spinlock diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 59cdfc7cce5c..a5c85e5e972e 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -931,6 +931,7 @@ typedef struct r8192_priv char CCKPresentAttentuation; // Use to calculate PWBD. RT_RF_POWER_STATE eRFPowerState; + RT_RF_CHANGE_SOURCE RfOffReason; u8 bCckHighPower; long undecorated_smoothed_pwdb; long undecorated_smoothed_cck_adc_pwdb[4]; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 5e25353dbc53..9b40168cd2dd 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1946,7 +1946,7 @@ static void rtl8192_init_priv_variable(struct net_device* dev) priv->bDisableNormalResetCheck = false; priv->force_reset = false; //added by amy for power save - priv->ieee80211->RfOffReason = 0; + priv->RfOffReason = 0; priv->bHwRfOffAction = 0; priv->ieee80211->PowerSaveControl.bInactivePs = true; priv->ieee80211->PowerSaveControl.bIPSModeBackup = false; @@ -2834,21 +2834,21 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) #ifdef ENABLE_IPS { - if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS) + if(priv->RfOffReason > RF_CHANGE_BY_PS) { // H/W or S/W RF OFF before sleep. - RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d)\n", __FUNCTION__,priv->ieee80211->RfOffReason); - MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason); + RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d)\n", __FUNCTION__,priv->RfOffReason); + MgntActSet_RF_State(dev, eRfOff, priv->RfOffReason); } - else if(priv->ieee80211->RfOffReason >= RF_CHANGE_BY_IPS) + else if(priv->RfOffReason >= RF_CHANGE_BY_IPS) { // H/W or S/W RF OFF before sleep. - RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d)\n", __FUNCTION__,priv->ieee80211->RfOffReason); - MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason); + RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d)\n", __FUNCTION__, priv->RfOffReason); + MgntActSet_RF_State(dev, eRfOff, priv->RfOffReason); } else { RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): RF-ON \n",__FUNCTION__); priv->eRFPowerState = eRfOn; - priv->ieee80211->RfOffReason = 0; + priv->RfOffReason = 0; } } #endif @@ -3254,7 +3254,7 @@ IPSLeave(struct net_device *dev) if (pPSC->bInactivePs) { rtState = priv->eRFPowerState; - if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS) + if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->RfOffReason <= RF_CHANGE_BY_IPS) { RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n"); pPSC->eInactivePowerState = eRfOn; @@ -3282,7 +3282,7 @@ void ieee80211_ips_leave_wq(struct net_device *dev) if(priv->ieee80211->PowerSaveControl.bInactivePs){ if(rtState == eRfOff){ - if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS) + if(priv->RfOffReason > RF_CHANGE_BY_IPS) { RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__); return; @@ -3479,7 +3479,7 @@ static int _rtl8192_up(struct net_device *dev) RT_TRACE(COMP_INIT, "start adapter finished\n"); if (priv->eRFPowerState != eRfOn) - MgntActSet_RF_State(dev, eRfOn, priv->ieee80211->RfOffReason); + MgntActSet_RF_State(dev, eRfOn, priv->RfOffReason); if(priv->ieee80211->state != IEEE80211_LINKED) ieee80211_softmac_start_protocol(priv->ieee80211); @@ -5048,7 +5048,7 @@ void setKey( struct net_device *dev, rtState = priv->eRFPowerState; if(priv->ieee80211->PowerSaveControl.bInactivePs){ if(rtState == eRfOff){ - if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS) + if(priv->RfOffReason > RF_CHANGE_BY_IPS) { RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__); //up(&priv->wx_sem); diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c index 280a1b720c34..cf6e231d5600 100644 --- a/drivers/staging/rtl8192e/r8192E_wx.c +++ b/drivers/staging/rtl8192e/r8192E_wx.c @@ -222,7 +222,7 @@ static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a, if(priv->ieee80211->PowerSaveControl.bInactivePs){ if(rtState == eRfOff){ - if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS) + if(priv->RfOffReason > RF_CHANGE_BY_IPS) { RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__); up(&priv->wx_sem); @@ -408,7 +408,7 @@ static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a, if(priv->ieee80211->state != IEEE80211_LINKED){ if(priv->ieee80211->PowerSaveControl.bInactivePs){ if(rtState == eRfOff){ - if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS) + if(priv->RfOffReason > RF_CHANGE_BY_IPS) { RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__); up(&priv->wx_sem); -- cgit v1.2.3 From 8e0af57d9eb893a27e35d09e29d89b974a5d375d Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:44:28 +0900 Subject: staging: rtl8192e: Move definition of RT_RF_CHANGE_SOURCE Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 7 ------- drivers/staging/rtl8192e/r8192E.h | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index f0627b1fd964..8ebedd0be775 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -1825,13 +1825,6 @@ typedef struct _RT_POWER_SAVE_CONTROL }RT_POWER_SAVE_CONTROL,*PRT_POWER_SAVE_CONTROL; -typedef u32 RT_RF_CHANGE_SOURCE; -#define RF_CHANGE_BY_SW BIT31 -#define RF_CHANGE_BY_HW BIT30 -#define RF_CHANGE_BY_PS BIT29 -#define RF_CHANGE_BY_IPS BIT28 -#define RF_CHANGE_BY_INIT 0 // Do not change the RFOff reason. Defined by Bruce, 2008-01-17. - #ifdef ENABLE_DOT11D typedef enum { diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index a5c85e5e972e..6a6d09578d4b 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -192,6 +192,13 @@ do { if(rt_global_debug_component & component) \ #define EEPROM_Default_LegacyHTTxPowerDiff 0x4 #define IEEE80211_WATCH_DOG_TIME 2000 +typedef u32 RT_RF_CHANGE_SOURCE; +#define RF_CHANGE_BY_SW BIT31 +#define RF_CHANGE_BY_HW BIT30 +#define RF_CHANGE_BY_PS BIT29 +#define RF_CHANGE_BY_IPS BIT28 +#define RF_CHANGE_BY_INIT 0 // Do not change the RFOff reason. Defined by Bruce, 2008-01-17. + /* For rtl819x */ typedef struct _tx_desc_819x_pci { //DWORD 0 -- cgit v1.2.3 From 774dee1c1af9dd4994d5055bf2507c9ad72991e3 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:44:37 +0900 Subject: staging: rtl8192e: Move variables to ieee80211 struct Move variables only accessed by the RTL ieee80211 library into its private struct. Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 4 ++-- .../staging/rtl8192e/ieee80211/ieee80211_softmac.c | 27 +++++++++++----------- drivers/staging/rtl8192e/r8192E_core.c | 2 +- 3 files changed, 16 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index 8ebedd0be775..2c5750bfe98e 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -1811,8 +1811,6 @@ typedef struct _RT_POWER_SAVE_CONTROL bool bLeisurePs; u32 PowerProfile; u8 LpsIdleCount; - u8 RegMaxLPSAwakeIntvl; - u8 LPSAwakeIntvl; u32 CurPsLevel; u32 RegRfPsLevel; @@ -2200,6 +2198,8 @@ struct ieee80211_device { /* for PS mode */ unsigned long last_rx_ps_time; + u8 LPSAwakeIntvl; + u8 RegMaxLPSAwakeIntvl; /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */ struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM]; diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index 012256c0fc52..88a9cd1958a8 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -1738,7 +1738,6 @@ short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *ti { int timeout = ieee->ps_timeout; u8 dtim; - PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(ieee->PowerSaveControl)); if(ieee->LPSDelayCnt) { @@ -1767,35 +1766,35 @@ short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *ti if(time_l){ if(ieee->bAwakePktSent == true) { - pPSC->LPSAwakeIntvl = 1;//tx wake one beacon + ieee->LPSAwakeIntvl = 1;//tx wake one beacon } else { u8 MaxPeriod = 1; - if(pPSC->LPSAwakeIntvl == 0) - pPSC->LPSAwakeIntvl = 1; - if(pPSC->RegMaxLPSAwakeIntvl == 0) // Default (0x0 - eFastPs, 0xFF -DTIM, 0xNN - 0xNN * BeaconIntvl) + if(ieee->LPSAwakeIntvl == 0) + ieee->LPSAwakeIntvl = 1; + if(ieee->RegMaxLPSAwakeIntvl == 0) // Default (0x0 - eFastPs, 0xFF -DTIM, 0xNN - 0xNN * BeaconIntvl) MaxPeriod = 1; // 1 Beacon interval - else if(pPSC->RegMaxLPSAwakeIntvl == 0xFF) // DTIM + else if(ieee->RegMaxLPSAwakeIntvl == 0xFF) // DTIM MaxPeriod = ieee->current_network.dtim_period; else - MaxPeriod = pPSC->RegMaxLPSAwakeIntvl; - pPSC->LPSAwakeIntvl = (pPSC->LPSAwakeIntvl >= MaxPeriod) ? MaxPeriod : (pPSC->LPSAwakeIntvl + 1); + MaxPeriod = ieee->RegMaxLPSAwakeIntvl; + ieee->LPSAwakeIntvl = (ieee->LPSAwakeIntvl >= MaxPeriod) ? MaxPeriod : (ieee->LPSAwakeIntvl + 1); } { u8 LPSAwakeIntvl_tmp = 0; u8 period = ieee->current_network.dtim_period; u8 count = ieee->current_network.tim.tim_count; if(count == 0 ) { - if(pPSC->LPSAwakeIntvl > period) - LPSAwakeIntvl_tmp = period + (pPSC->LPSAwakeIntvl - period) -((pPSC->LPSAwakeIntvl-period)%period); + if(ieee->LPSAwakeIntvl > period) + LPSAwakeIntvl_tmp = period + (ieee->LPSAwakeIntvl - period) -((ieee->LPSAwakeIntvl-period)%period); else - LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl; + LPSAwakeIntvl_tmp = ieee->LPSAwakeIntvl; } else { - if(pPSC->LPSAwakeIntvl > ieee->current_network.tim.tim_count) - LPSAwakeIntvl_tmp = count + (pPSC->LPSAwakeIntvl - count) -((pPSC->LPSAwakeIntvl-count)%period); + if(ieee->LPSAwakeIntvl > ieee->current_network.tim.tim_count) + LPSAwakeIntvl_tmp = count + (ieee->LPSAwakeIntvl - count) -((ieee->LPSAwakeIntvl-count)%period); else - LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl; + LPSAwakeIntvl_tmp = ieee->LPSAwakeIntvl; } *time_l = ieee->current_network.last_dtim_sta_time[0] diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 9b40168cd2dd..fbdb5c1a8df6 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1915,7 +1915,7 @@ static void rtl8192_init_priv_variable(struct net_device* dev) pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_ASPM; pPSC->RegRfPsLevel |= RT_RF_LPS_LEVEL_ASPM; pPSC->bLeisurePs = true; - pPSC->RegMaxLPSAwakeIntvl = 5; + priv->ieee80211->RegMaxLPSAwakeIntvl = 5; priv->bHwRadioOff = false; priv->being_init_adapter = false; -- cgit v1.2.3 From 31d664e56bb508aaa00de3952f0746dcd9d18a01 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:44:47 +0900 Subject: staging: rtl8192e: Move PowerSaveControl to r8192e_priv This variable is not used by the ieee80211 library, so move it rtl8192e's private struct. Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 2 +- drivers/staging/rtl8192e/r8190_rtl8256.c | 2 +- drivers/staging/rtl8192e/r8192E.h | 1 + drivers/staging/rtl8192e/r8192E_core.c | 24 ++++++++++++------------ drivers/staging/rtl8192e/r8192E_wx.c | 6 +++--- 5 files changed, 18 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index 2c5750bfe98e..1998a0b4af92 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -2243,7 +2243,7 @@ struct ieee80211_device { //added by amy for AP roaming RT_LINK_DETECT_T LinkDetectInfo; //added by amy for ps - RT_POWER_SAVE_CONTROL PowerSaveControl; + //RT_POWER_SAVE_CONTROL PowerSaveControl; //} /* used if IEEE_SOFTMAC_TX_QUEUE is set */ struct tx_pending_t tx_pending; diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index ed45bcdb8367..b4d45d6fd92e 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -324,7 +324,7 @@ static bool SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) { struct r8192_priv *priv = ieee80211_priv(dev); - PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); + PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; bool bResult = true; if (eRFPowerState == priv->eRFPowerState && diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 6a6d09578d4b..6862bf22a9b1 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -939,6 +939,7 @@ typedef struct r8192_priv // Use to calculate PWBD. RT_RF_POWER_STATE eRFPowerState; RT_RF_CHANGE_SOURCE RfOffReason; + RT_POWER_SAVE_CONTROL PowerSaveControl; u8 bCckHighPower; long undecorated_smoothed_pwdb; long undecorated_smoothed_cck_adc_pwdb[4]; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index fbdb5c1a8df6..fbbede29b030 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1907,7 +1907,7 @@ static void rtl8192_init_priv_variable(struct net_device* dev) { struct r8192_priv *priv = ieee80211_priv(dev); u8 i; - PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); + PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; // Default Halt the NIC if RF is OFF. pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_HALT_NIC; @@ -1948,8 +1948,8 @@ static void rtl8192_init_priv_variable(struct net_device* dev) //added by amy for power save priv->RfOffReason = 0; priv->bHwRfOffAction = 0; - priv->ieee80211->PowerSaveControl.bInactivePs = true; - priv->ieee80211->PowerSaveControl.bIPSModeBackup = false; + priv->PowerSaveControl.bInactivePs = true; + priv->PowerSaveControl.bIPSModeBackup = false; priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL; priv->ieee80211->iw_mode = IW_MODE_INFRA; @@ -3090,7 +3090,7 @@ rtl819x_ifcheck_resetornot(struct net_device *dev) void InactivePsWorkItemCallback(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); - PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); + PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() --------->\n"); // @@ -3163,7 +3163,7 @@ bool MgntActSet_802_11_PowerSaveMode(struct net_device *dev, u8 rtPsMode) void LeisurePSEnter(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); - PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); + PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; if(!((priv->ieee80211->iw_mode == IW_MODE_INFRA) && (priv->ieee80211->state == IEEE80211_LINKED)) || @@ -3193,7 +3193,7 @@ void LeisurePSEnter(struct net_device *dev) void LeisurePSLeave(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); - PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); + PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; if (pPSC->bLeisurePs) { @@ -3213,7 +3213,7 @@ void IPSEnter(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); - PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); + PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; RT_RF_POWER_STATE rtState; if (pPSC->bInactivePs) @@ -3248,7 +3248,7 @@ void IPSLeave(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); - PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); + PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; RT_RF_POWER_STATE rtState; if (pPSC->bInactivePs) @@ -3280,7 +3280,7 @@ void ieee80211_ips_leave_wq(struct net_device *dev) RT_RF_POWER_STATE rtState; rtState = priv->eRFPowerState; - if(priv->ieee80211->PowerSaveControl.bInactivePs){ + if (priv->PowerSaveControl.bInactivePs){ if(rtState == eRfOff){ if(priv->RfOffReason > RF_CHANGE_BY_IPS) { @@ -3347,7 +3347,7 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) if((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == IEEE80211_NOLINK) && (priv->eRFPowerState == eRfOn) && !ieee->is_set_key && (!ieee->proto_stoppping) && !ieee->wx_set_enc){ - if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){ + if (priv->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){ IPSEnter(dev); } } @@ -5046,7 +5046,7 @@ void setKey( struct net_device *dev, struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); RT_RF_POWER_STATE rtState; rtState = priv->eRFPowerState; - if(priv->ieee80211->PowerSaveControl.bInactivePs){ + if (priv->PowerSaveControl.bInactivePs){ if(rtState == eRfOff){ if(priv->RfOffReason > RF_CHANGE_BY_IPS) { @@ -5110,7 +5110,7 @@ bool NicIFEnableNIC(struct net_device* dev) { RT_STATUS init_status = RT_STATUS_SUCCESS; struct r8192_priv* priv = ieee80211_priv(dev); - PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); + PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; //YJ,add,091109 if (priv->up == 0){ diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c index cf6e231d5600..7ce9f6e78307 100644 --- a/drivers/staging/rtl8192e/r8192E_wx.c +++ b/drivers/staging/rtl8192e/r8192E_wx.c @@ -220,7 +220,7 @@ static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a, #ifdef ENABLE_IPS if(wrqu->mode == IW_MODE_ADHOC){ - if(priv->ieee80211->PowerSaveControl.bInactivePs){ + if (priv->PowerSaveControl.bInactivePs) { if(rtState == eRfOff){ if(priv->RfOffReason > RF_CHANGE_BY_IPS) { @@ -406,7 +406,7 @@ static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a, #ifdef ENABLE_IPS priv->ieee80211->actscanning = true; if(priv->ieee80211->state != IEEE80211_LINKED){ - if(priv->ieee80211->PowerSaveControl.bInactivePs){ + if (priv->PowerSaveControl.bInactivePs) { if(rtState == eRfOff){ if(priv->RfOffReason > RF_CHANGE_BY_IPS) { @@ -1017,7 +1017,7 @@ static int r8192_wx_adapter_power_status(struct net_device *dev, { struct r8192_priv *priv = ieee80211_priv(dev); #ifdef ENABLE_LPS - PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl)); + PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; struct ieee80211_device* ieee = priv->ieee80211; #endif down(&priv->wx_sem); -- cgit v1.2.3 From 5aa68752f993b9e411196bbc44a202aadee42de2 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:44:58 +0900 Subject: staging: rtl8192e: Pass r8192_priv to eprom_read Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8180_93cx6.c | 3 +-- drivers/staging/rtl8192e/r8180_93cx6.h | 2 +- drivers/staging/rtl8192e/r8192E_core.c | 22 +++++++++++----------- 3 files changed, 13 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8180_93cx6.c b/drivers/staging/rtl8192e/r8180_93cx6.c index ba4712f482a5..55d4f56dc42e 100644 --- a/drivers/staging/rtl8192e/r8180_93cx6.c +++ b/drivers/staging/rtl8192e/r8180_93cx6.c @@ -82,9 +82,8 @@ static void eprom_send_bits_string(struct r8192_priv *priv, short b[], int len) } -u32 eprom_read(struct net_device *dev, u32 addr) +u32 eprom_read(struct r8192_priv *priv, u32 addr) { - struct r8192_priv *priv = ieee80211_priv(dev); short read_cmd[] = {1, 1, 0}; short addr_str[8]; int i; diff --git a/drivers/staging/rtl8192e/r8180_93cx6.h b/drivers/staging/rtl8192e/r8180_93cx6.h index 4c3f675c6a66..55d20544a9c9 100644 --- a/drivers/staging/rtl8192e/r8180_93cx6.h +++ b/drivers/staging/rtl8192e/r8180_93cx6.h @@ -38,4 +38,4 @@ #define EPROM_TXPW1 0x3d /* Reads a 16 bits word. */ -u32 eprom_read(struct net_device *dev, u32 addr); +u32 eprom_read(struct r8192_priv *priv, u32 addr); diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index fbbede29b030..950089864aae 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -2092,7 +2092,7 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) // TODO: I don't know if we need to apply EF function to EEPROM read function //2 Read EEPROM ID to make sure autoload is success - EEPROMId = eprom_read(dev, 0); + EEPROMId = eprom_read(priv, 0); if( EEPROMId != RTL8190_EEPROM_ID ) { RT_TRACE(COMP_ERR, "EEPROM ID is invalid:%x, %x\n", EEPROMId, RTL8190_EEPROM_ID); @@ -2110,12 +2110,12 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) if(!priv->AutoloadFailFlag) { // VID, PID - priv->eeprom_vid = eprom_read(dev, (EEPROM_VID >> 1)); - priv->eeprom_did = eprom_read(dev, (EEPROM_DID >> 1)); + priv->eeprom_vid = eprom_read(priv, (EEPROM_VID >> 1)); + priv->eeprom_did = eprom_read(priv, (EEPROM_DID >> 1)); - usValue = eprom_read(dev, (u16)(EEPROM_Customer_ID>>1)) >> 8 ; + usValue = eprom_read(priv, (u16)(EEPROM_Customer_ID>>1)) >> 8 ; priv->eeprom_CustomerID = (u8)( usValue & 0xff); - usValue = eprom_read(dev, (EEPROM_ICVersion_ChannelPlan>>1)); + usValue = eprom_read(priv, (EEPROM_ICVersion_ChannelPlan>>1)); priv->eeprom_ChannelPlan = usValue&0xff; IC_Version = ((usValue&0xff00)>>8); @@ -2159,7 +2159,7 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) { for(i = 0; i < 6; i += 2) { - usValue = eprom_read(dev, (u16) ((EEPROM_NODE_ADDRESS_BYTE_0+i)>>1)); + usValue = eprom_read(priv, (u16) ((EEPROM_NODE_ADDRESS_BYTE_0+i)>>1)); *(u16*)(&dev->dev_addr[i]) = usValue; } } else { @@ -2185,7 +2185,7 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) // Read RF-indication and Tx Power gain index diff of legacy to HT OFDM rate. if(!priv->AutoloadFailFlag) { - tempval = (eprom_read(dev, (EEPROM_RFInd_PowerDiff>>1))) & 0xff; + tempval = (eprom_read(priv, (EEPROM_RFInd_PowerDiff>>1))) & 0xff; priv->EEPROMLegacyHTTxPowerDiff = tempval & 0xf; // bit[3:0] if (tempval&0x80) //RF-indication, bit[7] @@ -2203,7 +2203,7 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) // Read ThermalMeter from EEPROM if(!priv->AutoloadFailFlag) { - priv->EEPROMThermalMeter = (u8)(((eprom_read(dev, (EEPROM_ThermalMeter>>1))) & 0xff00)>>8); + priv->EEPROMThermalMeter = (u8)(((eprom_read(priv, (EEPROM_ThermalMeter>>1))) & 0xff00)>>8); } else { @@ -2218,7 +2218,7 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) // Read antenna tx power offset of B/C/D to A and CrystalCap from EEPROM if(!priv->AutoloadFailFlag) { - usValue = eprom_read(dev, (EEPROM_TxPwDiff_CrystalCap>>1)); + usValue = eprom_read(priv, (EEPROM_TxPwDiff_CrystalCap>>1)); priv->EEPROMAntPwDiff = (usValue&0x0fff); priv->EEPROMCrystalCap = (u8)((usValue&0xf000)>>12); } @@ -2237,7 +2237,7 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) { if(!priv->AutoloadFailFlag) { - usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_CCK+i)>>1) ); + usValue = eprom_read(priv, (u16) ((EEPROM_TxPwIndex_CCK+i)>>1) ); } else { @@ -2251,7 +2251,7 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) { if(!priv->AutoloadFailFlag) { - usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_OFDM_24G+i)>>1) ); + usValue = eprom_read(priv, (u16) ((EEPROM_TxPwIndex_OFDM_24G+i)>>1) ); } else { -- cgit v1.2.3 From d9ffa6c2e9752bb3c87995e2d97444c713dbc07f Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:45:08 +0900 Subject: staging: rtl8192e: Pass r8192e_priv to phy functions Phy functions shouldn't be associated with net_device. Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8190_rtl8256.c | 89 +++++----- drivers/staging/rtl8192e/r8190_rtl8256.h | 10 +- drivers/staging/rtl8192e/r8192E_core.c | 40 ++--- drivers/staging/rtl8192e/r8192E_dm.c | 84 ++++----- drivers/staging/rtl8192e/r819xE_phy.c | 284 ++++++++++++++----------------- drivers/staging/rtl8192e/r819xE_phy.h | 32 ++-- 6 files changed, 256 insertions(+), 283 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index b4d45d6fd92e..3cf96aa8d7ce 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -23,15 +23,14 @@ * Return: NONE * Note: 8226 support both 20M and 40 MHz *---------------------------------------------------------------------------*/ -void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth) //20M or 40M +void PHY_SetRF8256Bandwidth(struct r8192_priv *priv, HT_CHANNEL_WIDTH Bandwidth) //20M or 40M { u8 eRFPath; - struct r8192_priv *priv = ieee80211_priv(dev); //for(eRFPath = RF90_PATH_A; eRFPath NumTotalRFPath; eRFPath++) for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) { - if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) + if (!rtl8192_phy_CheckIsLegalRFPath(priv, eRFPath)) continue; switch(Bandwidth) @@ -39,9 +38,9 @@ void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth) case HT_CHANNEL_WIDTH_20: if(priv->card_8192_version == VERSION_8190_BD || priv->card_8192_version == VERSION_8190_BE)// 8256 D-cut, E-cut, xiong: consider it later! { - rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x100); //phy para:1ba - rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3d7); - rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x021); + rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x100); //phy para:1ba + rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3d7); + rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x021); //cosa add for sd3's request 01/23/2008 //rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab); @@ -55,9 +54,9 @@ void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth) case HT_CHANNEL_WIDTH_20_40: if(priv->card_8192_version == VERSION_8190_BD ||priv->card_8192_version == VERSION_8190_BE)// 8256 D-cut, E-cut, xiong: consider it later! { - rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x300); //phy para:3ba - rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3ff); - rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x0e1); + rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x300); //phy para:3ba + rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3ff); + rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x0e1); } else @@ -80,43 +79,43 @@ void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth) * Output: NONE * Return: NONE *---------------------------------------------------------------------------*/ -RT_STATUS PHY_RF8256_Config(struct net_device* dev) +RT_STATUS PHY_RF8256_Config(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); // Initialize general global value // RT_STATUS rtStatus = RT_STATUS_SUCCESS; // TODO: Extend RF_PATH_C and RF_PATH_D in the future priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH; // Config BB and RF - rtStatus = phy_RF8256_Config_ParaFile(dev); + rtStatus = phy_RF8256_Config_ParaFile(priv); return rtStatus; } + /*-------------------------------------------------------------------------- * Overview: Interface to config 8256 * Input: struct net_device* dev * Output: NONE * Return: NONE *---------------------------------------------------------------------------*/ -RT_STATUS phy_RF8256_Config_ParaFile(struct net_device* dev) +RT_STATUS phy_RF8256_Config_ParaFile(struct r8192_priv *priv) { u32 u4RegValue = 0; u8 eRFPath; RT_STATUS rtStatus = RT_STATUS_SUCCESS; BB_REGISTER_DEFINITION_T *pPhyReg; - struct r8192_priv *priv = ieee80211_priv(dev); u32 RegOffSetToBeCheck = 0x3; u32 RegValueToBeCheck = 0x7f1; u32 RF3_Final_Value = 0; u8 ConstRetryTimes = 5, RetryTimes = 5; u8 ret = 0; + //3//----------------------------------------------------------------- //3// <2> Initialize RF //3//----------------------------------------------------------------- for(eRFPath = (RF90_RADIO_PATH_E)RF90_PATH_A; eRFPath NumTotalRFPath; eRFPath++) { - if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) + if (!rtl8192_phy_CheckIsLegalRFPath(priv, eRFPath)) continue; pPhyReg = &priv->PHYRegDef[eRFPath]; @@ -126,29 +125,29 @@ RT_STATUS phy_RF8256_Config_ParaFile(struct net_device* dev) { case RF90_PATH_A: case RF90_PATH_C: - u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV); + u4RegValue = rtl8192_QueryBBReg(priv, pPhyReg->rfintfs, bRFSI_RFENV); break; case RF90_PATH_B : case RF90_PATH_D: - u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16); + u4RegValue = rtl8192_QueryBBReg(priv, pPhyReg->rfintfs, bRFSI_RFENV<<16); break; } /*----Set RF_ENV enable----*/ - rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1); + rtl8192_setBBreg(priv, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1); /*----Set RF_ENV output high----*/ - rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1); + rtl8192_setBBreg(priv, pPhyReg->rfintfo, bRFSI_RFENV, 0x1); /* Set bit number of Address and Data for RF register */ - rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); // Set 0 to 4 bits for Z-serial and set 1 to 6 bits for 8258 - rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); // Set 0 to 12 bits for Z-serial and 8258, and set 1 to 14 bits for ??? + rtl8192_setBBreg(priv, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); // Set 0 to 4 bits for Z-serial and set 1 to 6 bits for 8258 + rtl8192_setBBreg(priv, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); // Set 0 to 12 bits for Z-serial and 8258, and set 1 to 14 bits for ??? - rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E) eRFPath, 0x0, bMask12Bits, 0xbf); + rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E) eRFPath, 0x0, bMask12Bits, 0xbf); /*----Check RF block (for FPGA platform only)----*/ // TODO: this function should be removed on ASIC , Emily 2007.2.2 - rtStatus = rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF, (RF90_RADIO_PATH_E)eRFPath); + rtStatus = rtl8192_phy_checkBBAndRF(priv, HW90_BLOCK_RF, (RF90_RADIO_PATH_E)eRFPath); if(rtStatus!= RT_STATUS_SUCCESS) { RT_TRACE(COMP_ERR, "PHY_RF8256_Config():Check Radio[%d] Fail!!\n", eRFPath); @@ -163,8 +162,8 @@ RT_STATUS phy_RF8256_Config_ParaFile(struct net_device* dev) case RF90_PATH_A: while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0) { - ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath); - RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); + ret = rtl8192_phy_ConfigRFWithHeaderFile(priv,(RF90_RADIO_PATH_E)eRFPath); + RF3_Final_Value = rtl8192_phy_QueryRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); RetryTimes--; } @@ -172,8 +171,8 @@ RT_STATUS phy_RF8256_Config_ParaFile(struct net_device* dev) case RF90_PATH_B: while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0) { - ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath); - RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); + ret = rtl8192_phy_ConfigRFWithHeaderFile(priv,(RF90_RADIO_PATH_E)eRFPath); + RF3_Final_Value = rtl8192_phy_QueryRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); RetryTimes--; } @@ -181,8 +180,8 @@ RT_STATUS phy_RF8256_Config_ParaFile(struct net_device* dev) case RF90_PATH_C: while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0) { - ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath); - RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); + ret = rtl8192_phy_ConfigRFWithHeaderFile(priv,(RF90_RADIO_PATH_E)eRFPath); + RF3_Final_Value = rtl8192_phy_QueryRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); RetryTimes--; } @@ -190,8 +189,8 @@ RT_STATUS phy_RF8256_Config_ParaFile(struct net_device* dev) case RF90_PATH_D: while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0) { - ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath); - RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); + ret = rtl8192_phy_ConfigRFWithHeaderFile(priv,(RF90_RADIO_PATH_E)eRFPath); + RF3_Final_Value = rtl8192_phy_QueryRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); RetryTimes--; } @@ -203,11 +202,11 @@ RT_STATUS phy_RF8256_Config_ParaFile(struct net_device* dev) { case RF90_PATH_A: case RF90_PATH_C: - rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue); + rtl8192_setBBreg(priv, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue); break; case RF90_PATH_B : case RF90_PATH_D: - rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue); + rtl8192_setBBreg(priv, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue); break; } @@ -227,10 +226,9 @@ phy_RF8256_Config_ParaFile_Fail: } -void PHY_SetRF8256CCKTxPower(struct net_device* dev, u8 powerlevel) +void PHY_SetRF8256CCKTxPower(struct r8192_priv *priv, u8 powerlevel) { u32 TxAGC=0; - struct r8192_priv *priv = ieee80211_priv(dev); TxAGC = powerlevel; if(priv->bDynamicTxLowPower == true)//cosa 04282008 for cck long range @@ -242,13 +240,12 @@ void PHY_SetRF8256CCKTxPower(struct net_device* dev, u8 powerlevel) } if(TxAGC > 0x24) TxAGC = 0x24; - rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC); + rtl8192_setBBreg(priv, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC); } -void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel) +void PHY_SetRF8256OFDMTxPower(struct r8192_priv *priv, u8 powerlevel) { - struct r8192_priv *priv = ieee80211_priv(dev); u32 writeVal, powerBase0, powerBase1, writeVal_tmp; u8 index = 0; @@ -290,7 +287,7 @@ void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel) { writeVal = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0; } - rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal); + rtl8192_setBBreg(priv, RegOffset[index], 0x7f7f7f7f, writeVal); } } @@ -356,22 +353,22 @@ SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) write_nic_byte(priv, ANAPAR, 0x37);//160MHz mdelay(1); //enable clock 80/88 MHz - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x1); // 0x880[2] + rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x4, 0x1); // 0x880[2] priv->bHwRfOffAction = 0; //RF-A, RF-B //enable RF-Chip A/B - rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4] + rtl8192_setBBreg(priv, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4] //analog to digital on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] + rtl8192_setBBreg(priv, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] //digital to analog on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x3); // 0x880[4:3] + rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x18, 0x3); // 0x880[4:3] //rx antenna on - rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0] + rtl8192_setBBreg(priv, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0] //rx antenna on - rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0] + rtl8192_setBBreg(priv, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0] //analog to digital part2 on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5] + rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5] } diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.h b/drivers/staging/rtl8192e/r8190_rtl8256.h index d9347fa4615c..e3297ecb37f4 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.h +++ b/drivers/staging/rtl8192e/r8190_rtl8256.h @@ -12,15 +12,15 @@ #define RTL819X_TOTAL_RF_PATH 2 /* for 8192E */ -void PHY_SetRF8256Bandwidth(struct net_device *dev, +void PHY_SetRF8256Bandwidth(struct r8192_priv *priv, HT_CHANNEL_WIDTH Bandwidth); -RT_STATUS PHY_RF8256_Config(struct net_device *dev); +RT_STATUS PHY_RF8256_Config(struct r8192_priv *priv); -RT_STATUS phy_RF8256_Config_ParaFile(struct net_device *dev); +RT_STATUS phy_RF8256_Config_ParaFile(struct r8192_priv *priv); -void PHY_SetRF8256CCKTxPower(struct net_device *dev, u8 powerlevel); -void PHY_SetRF8256OFDMTxPower(struct net_device *dev, u8 powerlevel); +void PHY_SetRF8256CCKTxPower(struct r8192_priv *priv, u8 powerlevel); +void PHY_SetRF8256OFDMTxPower(struct r8192_priv *priv, u8 powerlevel); bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 950089864aae..50480ac3513c 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -752,18 +752,18 @@ void PHY_SetRtl8192eRfOff(struct net_device* dev) struct r8192_priv *priv = ieee80211_priv(dev); //disable RF-Chip A/B - rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0); + rtl8192_setBBreg(priv, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0); //analog to digital off, for power save - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x0); + rtl8192_setBBreg(priv, rFPGA0_AnalogParameter4, 0x300, 0x0); //digital to analog off, for power save - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x0); + rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x18, 0x0); //rx antenna off - rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0); + rtl8192_setBBreg(priv, rOFDM0_TRxPathEnable, 0xf, 0x0); //rx antenna off - rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0); + rtl8192_setBBreg(priv, rOFDM1_TRxPathEnable, 0xf, 0x0); //analog to digital part2 off, for power save - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0); - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x0); + rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x60, 0x0); + rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x4, 0x0); // Analog parameter!!Change bias and Lbus control. write_nic_byte(priv, ANAPAR_FOR_8192PciE, 0x07); @@ -2659,7 +2659,7 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) //3// Initialize BB before MAC //3// RT_TRACE(COMP_INIT, "BB Config Start!\n"); - rtStatus = rtl8192_BBConfig(dev); + rtStatus = rtl8192_BBConfig(priv); if(rtStatus != RT_STATUS_SUCCESS) { RT_TRACE(COMP_ERR, "BB Config failed\n"); @@ -2768,11 +2768,11 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) //2======================================================= // Set PHY related configuration defined in MAC register bank //2======================================================= - rtl8192_phy_configmac(dev); + rtl8192_phy_configmac(priv); if (priv->card_8192_version > (u8) VERSION_8190_BD) { - rtl8192_phy_getTxPower(dev); - rtl8192_phy_setTxPower(dev, priv->chan); + rtl8192_phy_getTxPower(priv); + rtl8192_phy_setTxPower(priv, priv->chan); } //if D or C cut @@ -2811,7 +2811,7 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) if(priv->ResetProgress == RESET_TYPE_NORESET) { RT_TRACE(COMP_INIT, "RF Config Started!\n"); - rtStatus = rtl8192_phy_RFConfig(dev); + rtStatus = rtl8192_phy_RFConfig(priv); if(rtStatus != RT_STATUS_SUCCESS) { RT_TRACE(COMP_ERR, "RF Config failed\n"); @@ -2819,11 +2819,11 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) } RT_TRACE(COMP_INIT, "RF Config Finished!\n"); } - rtl8192_phy_updateInitGain(dev); + rtl8192_phy_updateInitGain(priv); /*---- Set CCK and OFDM Block "ON"----*/ - rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1); - rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1); + rtl8192_setBBreg(priv, rFPGA0_RFMOD, bCCKEn, 0x1); + rtl8192_setBBreg(priv, rFPGA0_RFMOD, bOFDMEn, 0x1); //Enable Led write_nic_byte(priv, 0x87, 0x0); @@ -2864,8 +2864,8 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) if(priv->IC_Cut >= IC_VersionCut_D) { - tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord); - tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord); + tmpRegA = rtl8192_QueryBBReg(priv, rOFDM0_XATxIQImbalance, bMaskDWord); + tmpRegC = rtl8192_QueryBBReg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord); for(i = 0; itxbbgain_table[i].txbbgain_value) @@ -2877,7 +2877,7 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) } } - TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2); + TempCCk = rtl8192_QueryBBReg(priv, rCCK0_TxFilter1, bMaskByte2); for(i=0 ; iieee80211->dev, rfpath)) + if (!rtl8192_phy_CheckIsLegalRFPath(priv, rfpath)) continue; RT_TRACE(COMP_DBG, "pPreviousstats->RxMIMOSignalStrength[rfpath] = %d\n", pprevious_stats->RxMIMOSignalStrength[rfpath]); //Fixed by Jacken 2008-03-20 @@ -4125,7 +4125,7 @@ static void rtl8192_query_rxphystatus( /*2007.08.30 requested by SD3 Jerry */ if (priv->phy_check_reg824 == 0) { - priv->phy_reg824_bit9 = rtl8192_QueryBBReg(priv->ieee80211->dev, rFPGA0_XA_HSSIParameter2, 0x200); + priv->phy_reg824_bit9 = rtl8192_QueryBBReg(priv, rFPGA0_XA_HSSIParameter2, 0x200); priv->phy_check_reg824 = 1; } diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index 330e9d9e2583..22bcc920ef40 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -586,20 +586,20 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) if(priv->rfa_txpowertrackingindex_real > 4) { priv->rfa_txpowertrackingindex_real--; - rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value); + rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value); } priv->rfc_txpowertrackingindex--; if(priv->rfc_txpowertrackingindex_real > 4) { priv->rfc_txpowertrackingindex_real--; - rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value); + rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value); } } else { - rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value); - rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value); + rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value); + rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value); } } else @@ -610,11 +610,11 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) if(priv->rfc_txpowertrackingindex_real > 4) { priv->rfc_txpowertrackingindex_real--; - rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value); + rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value); } } else - rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value); + rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value); } } else @@ -625,15 +625,15 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) { priv->rfa_txpowertrackingindex++; priv->rfa_txpowertrackingindex_real++; - rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value); + rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value); priv->rfc_txpowertrackingindex++; priv->rfc_txpowertrackingindex_real++; - rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value); + rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value); } else { - rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value); - rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value); + rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value); + rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value); } } else @@ -642,10 +642,10 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) { priv->rfc_txpowertrackingindex++; priv->rfc_txpowertrackingindex_real++; - rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value); + rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value); } else - rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value); + rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value); } } if (RF_Type == RF_2T4R) @@ -721,7 +721,7 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev) if(!priv->btxpower_trackingInit) { //Query OFDM default setting - tmpRegA= rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord); + tmpRegA = rtl8192_QueryBBReg(priv, rOFDM0_XATxIQImbalance, bMaskDWord); for(i=0; i 13) return; @@ -817,7 +817,7 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev) if(priv->OFDM_index != tmpOFDMindex) { priv->OFDM_index = tmpOFDMindex; - rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[priv->OFDM_index]); + rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[priv->OFDM_index]); RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n", priv->OFDM_index, OFDMSwingTable[priv->OFDM_index]); } @@ -1014,10 +1014,10 @@ static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev) { //Attention!! You have to wirte all 12bits data to RF, or it may cause RF to crash //actually write reg0x02 bit1=0, then bit1=1. - rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); - rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); - rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); - rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); + rtl8192_phy_SetRFReg(priv, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); + rtl8192_phy_SetRFReg(priv, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); + rtl8192_phy_SetRFReg(priv, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); + rtl8192_phy_SetRFReg(priv, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); TM_Trigger = 1; return; } @@ -1049,40 +1049,40 @@ static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14) TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ; - rtl8192_setBBreg(dev, rCCK0_TxFilter1,bMaskHWord, TempVal); + rtl8192_setBBreg(priv, rCCK0_TxFilter1, bMaskHWord, TempVal); //Write 0xa24 ~ 0xa27 TempVal = 0; TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16 )+ (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24)); - rtl8192_setBBreg(dev, rCCK0_TxFilter2,bMaskDWord, TempVal); + rtl8192_setBBreg(priv, rCCK0_TxFilter2, bMaskDWord, TempVal); //Write 0xa28 0xa29 TempVal = 0; TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ; - rtl8192_setBBreg(dev, rCCK0_DebugPort,bMaskLWord, TempVal); + rtl8192_setBBreg(priv, rCCK0_DebugPort, bMaskLWord, TempVal); } else { TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ; - rtl8192_setBBreg(dev, rCCK0_TxFilter1,bMaskHWord, TempVal); + rtl8192_setBBreg(priv, rCCK0_TxFilter1, bMaskHWord, TempVal); //Write 0xa24 ~ 0xa27 TempVal = 0; TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16 )+ (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24)); - rtl8192_setBBreg(dev, rCCK0_TxFilter2,bMaskDWord, TempVal); + rtl8192_setBBreg(priv, rCCK0_TxFilter2, bMaskDWord, TempVal); //Write 0xa28 0xa29 TempVal = 0; TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ; - rtl8192_setBBreg(dev, rCCK0_DebugPort,bMaskLWord, TempVal); + rtl8192_setBBreg(priv, rCCK0_DebugPort, bMaskLWord, TempVal); } @@ -1099,7 +1099,7 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH //Write 0xa22 0xa23 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8) ; - rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); + rtl8192_setBBreg(priv, rCCK0_TxFilter1, bMaskHWord, TempVal); RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter1, TempVal); //Write 0xa24 ~ 0xa27 @@ -1108,7 +1108,7 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16 )+ (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24); - rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); + rtl8192_setBBreg(priv, rCCK0_TxFilter2, bMaskDWord, TempVal); RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter2, TempVal); //Write 0xa28 0xa29 @@ -1116,7 +1116,7 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ; - rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); + rtl8192_setBBreg(priv, rCCK0_DebugPort, bMaskLWord, TempVal); RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_DebugPort, TempVal); } @@ -1127,7 +1127,7 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH TempVal = CCKSwingTable_Ch14[priv->CCK_index][0] + (CCKSwingTable_Ch14[priv->CCK_index][1]<<8) ; - rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); + rtl8192_setBBreg(priv, rCCK0_TxFilter1, bMaskHWord, TempVal); RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter1, TempVal); //Write 0xa24 ~ 0xa27 @@ -1136,7 +1136,7 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) + (CCKSwingTable_Ch14[priv->CCK_index][4]<<16 )+ (CCKSwingTable_Ch14[priv->CCK_index][5]<<24); - rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); + rtl8192_setBBreg(priv, rCCK0_TxFilter2, bMaskDWord, TempVal); RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter2, TempVal); //Write 0xa28 0xa29 @@ -1144,7 +1144,7 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] + (CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ; - rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); + rtl8192_setBBreg(priv, rCCK0_DebugPort, bMaskLWord, TempVal); RT_TRACE(COMP_POWER_TRACKING,"CCK chnl 14, reg 0x%x = 0x%x\n", rCCK0_DebugPort, TempVal); } @@ -1295,7 +1295,7 @@ static void dm_ctrl_initgain_byrssi_by_driverrssi( if(fw_dig <= 3) // execute several times to make sure the FW Dig is disabled {// FW DIG Off for(i=0; i<3; i++) - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite. + rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite. fw_dig++; dm_digtable.dig_state = DM_STA_DIG_OFF; //fw dig off. } @@ -1332,7 +1332,7 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( dm_digtable.dig_state = DM_STA_DIG_MAX; // Fw DIG On. for(i=0; i<3; i++) - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite. + rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite. dm_digtable.dig_algorithm_switch = 0; } @@ -1367,7 +1367,7 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( dm_digtable.dig_state = DM_STA_DIG_OFF; // 1.1 DIG Off. - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite. + rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite. // 1.2 Set initial gain. write_nic_byte(priv, rOFDM0_XAAGCCore1, 0x17); @@ -1451,7 +1451,7 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x346); // 2.5 DIG On. - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite. + rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite. } @@ -2227,8 +2227,8 @@ static void dm_rxpath_sel_byrssi(struct net_device * dev) //record the enabled rssi threshold DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = tmp_max_rssi+5; //disable the BB Rx path, OFDM - rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<= DM_RxPathSelTable.rf_enable_rssi_th[i]) { //enable the BB Rx path - rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<ieee80211->current_network.channel); - rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel); + rtl8192_phy_setTxPower(priv, priv->ieee80211->current_network.channel); } priv->bLastDTPFlag_High = priv->bDynamicTxHighPower; diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c index 44e1123797c4..e8a8b3424f32 100644 --- a/drivers/staging/rtl8192e/r819xE_phy.c +++ b/drivers/staging/rtl8192e/r819xE_phy.c @@ -564,8 +564,9 @@ static u32 Rtl8192PciERadioD_Array[RadioD_ArrayLength] = { /*************************Define local function prototype**********************/ -static u32 phy_FwRFSerialRead(struct net_device* dev,RF90_RADIO_PATH_E eRFPath,u32 Offset); -static void phy_FwRFSerialWrite(struct net_device* dev,RF90_RADIO_PATH_E eRFPath,u32 Offset,u32 Data); +static u32 phy_FwRFSerialRead(struct r8192_priv *priv, RF90_RADIO_PATH_E eRFPath, u32 Offset); +static void phy_FwRFSerialWrite(struct r8192_priv *priv, RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data); + /*************************Define local function prototype**********************/ /****************************************************************************** *function: This function read BB parameters from Header file we gen, @@ -590,10 +591,9 @@ static u32 rtl8192_CalculateBitShift(u32 dwBitMask) * output: none * return: 0(illegal, false), 1(legal,true) * ***************************************************************************/ -u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath) +u8 rtl8192_phy_CheckIsLegalRFPath(struct r8192_priv *priv, u32 eRFPath) { u8 ret = 1; - struct r8192_priv *priv = ieee80211_priv(dev); if (priv->rf_type == RF_2T4R) ret = 0; @@ -617,9 +617,8 @@ u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath) * return: none * notice: * ****************************************************************************/ -void rtl8192_setBBreg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask, u32 dwData) +void rtl8192_setBBreg(struct r8192_priv *priv, u32 dwRegAddr, u32 dwBitMask, u32 dwData) { - struct r8192_priv *priv = ieee80211_priv(dev); u32 OriginalValue, BitShift, NewValue; if(dwBitMask!= bMaskDWord) @@ -640,9 +639,8 @@ void rtl8192_setBBreg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask, u32 * return: u32 Data //the readback register value * notice: * ****************************************************************************/ -u32 rtl8192_QueryBBReg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask) +u32 rtl8192_QueryBBReg(struct r8192_priv *priv, u32 dwRegAddr, u32 dwBitMask) { - struct r8192_priv *priv = ieee80211_priv(dev); u32 OriginalValue, BitShift; OriginalValue = read_nic_dword(priv, dwRegAddr); @@ -658,9 +656,9 @@ u32 rtl8192_QueryBBReg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask) * return: u32 readback value * notice: There are three types of serial operations:(1) Software serial write.(2)Hardware LSSI-Low Speed Serial Interface.(3)Hardware HSSI-High speed serial write. Driver here need to implement (1) and (2)---need more spec for this information. * ****************************************************************************/ -static u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset) +static u32 rtl8192_phy_RFSerialRead(struct r8192_priv *priv, + RF90_RADIO_PATH_E eRFPath, u32 Offset) { - struct r8192_priv *priv = ieee80211_priv(dev); u32 ret = 0; u32 NewOffset = 0; BB_REGISTER_DEFINITION_T* pPhyReg = &priv->PHYRegDef[eRFPath]; @@ -670,12 +668,12 @@ static u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eR //switch page for 8256 RF IC //analog to digital off, for protection - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] + rtl8192_setBBreg(priv, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] if (Offset >= 31) { priv->RfReg0Value[eRFPath] |= 0x140; //Switch to Reg_Mode2 for Reg 31-45 - rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16) ); + rtl8192_setBBreg(priv, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16) ); //modify offset NewOffset = Offset -30; } @@ -684,7 +682,7 @@ static u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eR priv->RfReg0Value[eRFPath] |= 0x100; priv->RfReg0Value[eRFPath] &= (~0x40); //Switch to Reg_Mode 1 for Reg16-30 - rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16) ); + rtl8192_setBBreg(priv, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16) ); NewOffset = Offset - 15; } @@ -692,30 +690,30 @@ static u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eR NewOffset = Offset; //put desired read addr to LSSI control Register - rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadAddress, NewOffset); + rtl8192_setBBreg(priv, pPhyReg->rfHSSIPara2, bLSSIReadAddress, NewOffset); //Issue a posedge trigger // - rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x0); - rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x1); + rtl8192_setBBreg(priv, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x0); + rtl8192_setBBreg(priv, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x1); // TODO: we should not delay such a long time. Ask help from SD3 msleep(1); - ret = rtl8192_QueryBBReg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData); + ret = rtl8192_QueryBBReg(priv, pPhyReg->rfLSSIReadBack, bLSSIReadBackData); // Switch back to Reg_Mode0; priv->RfReg0Value[eRFPath] &= 0xebf; rtl8192_setBBreg( - dev, + priv, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath] << 16)); //analog to digital on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] + rtl8192_setBBreg(priv, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] return ret; } @@ -740,28 +738,29 @@ static u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eR * Reg_Mode2 1 1 Reg 31 ~ 45(0x1 ~ 0xf) *------------------------------------------------------------------ * ****************************************************************************/ -static void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data) +static void rtl8192_phy_RFSerialWrite(struct r8192_priv *priv, + RF90_RADIO_PATH_E eRFPath, u32 Offset, + u32 Data) { - struct r8192_priv *priv = ieee80211_priv(dev); u32 DataAndAddr = 0, NewOffset = 0; BB_REGISTER_DEFINITION_T *pPhyReg = &priv->PHYRegDef[eRFPath]; Offset &= 0x3f; //analog to digital off, for protection - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] + rtl8192_setBBreg(priv, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] if (Offset >= 31) { priv->RfReg0Value[eRFPath] |= 0x140; - rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath] << 16)); + rtl8192_setBBreg(priv, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath] << 16)); NewOffset = Offset - 30; } else if (Offset >= 16) { priv->RfReg0Value[eRFPath] |= 0x100; priv->RfReg0Value[eRFPath] &= (~0x40); - rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16)); + rtl8192_setBBreg(priv, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16)); NewOffset = Offset - 15; } else @@ -771,7 +770,7 @@ static void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E DataAndAddr = (Data<<16) | (NewOffset&0x3f); // Write Operation - rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr); + rtl8192_setBBreg(priv, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr); if(Offset==0x0) @@ -782,19 +781,18 @@ static void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E { priv->RfReg0Value[eRFPath] &= 0xebf; rtl8192_setBBreg( - dev, + priv, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath] << 16)); } //analog to digital on - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] + rtl8192_setBBreg(priv, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] } /****************************************************************************** *function: This function set specific bits to RF register - * input: net_device dev - * RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D + * input: RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D * u32 RegAddr //target addr to be modified * u32 BitMask //taget bit pos in the addr to be modified * u32 Data //value to be write @@ -802,13 +800,13 @@ static void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E * return: none * notice: * ****************************************************************************/ -void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask, u32 Data) +void rtl8192_phy_SetRFReg(struct r8192_priv *priv, RF90_RADIO_PATH_E eRFPath, + u32 RegAddr, u32 BitMask, u32 Data) { - struct r8192_priv *priv = ieee80211_priv(dev); u32 Original_Value, BitShift, New_Value; // u8 time = 0; - if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) + if (!rtl8192_phy_CheckIsLegalRFPath(priv, eRFPath)) return; if (priv->eRFPowerState != eRfOn && !priv->being_init_adapter) return; @@ -819,13 +817,13 @@ void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 { if (BitMask != bMask12Bits) // RF data is 12 bits only { - Original_Value = phy_FwRFSerialRead(dev, eRFPath, RegAddr); + Original_Value = phy_FwRFSerialRead(priv, eRFPath, RegAddr); BitShift = rtl8192_CalculateBitShift(BitMask); New_Value = (((Original_Value) & (~BitMask)) | (Data<< BitShift)); - phy_FwRFSerialWrite(dev, eRFPath, RegAddr, New_Value); + phy_FwRFSerialWrite(priv, eRFPath, RegAddr, New_Value); }else - phy_FwRFSerialWrite(dev, eRFPath, RegAddr, Data); + phy_FwRFSerialWrite(priv, eRFPath, RegAddr, Data); udelay(200); } @@ -833,13 +831,13 @@ void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 { if (BitMask != bMask12Bits) // RF data is 12 bits only { - Original_Value = rtl8192_phy_RFSerialRead(dev, eRFPath, RegAddr); + Original_Value = rtl8192_phy_RFSerialRead(priv, eRFPath, RegAddr); BitShift = rtl8192_CalculateBitShift(BitMask); New_Value = (((Original_Value) & (~BitMask)) | (Data<< BitShift)); - rtl8192_phy_RFSerialWrite(dev, eRFPath, RegAddr, New_Value); + rtl8192_phy_RFSerialWrite(priv, eRFPath, RegAddr, New_Value); }else - rtl8192_phy_RFSerialWrite(dev, eRFPath, RegAddr, Data); + rtl8192_phy_RFSerialWrite(priv, eRFPath, RegAddr, Data); } //up(&priv->rf_sem); } @@ -853,23 +851,24 @@ void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 * return: u32 Data //the readback register value * notice: * ****************************************************************************/ -u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask) +u32 rtl8192_phy_QueryRFReg(struct r8192_priv *priv, RF90_RADIO_PATH_E eRFPath, + u32 RegAddr, u32 BitMask) { u32 Original_Value, Readback_Value, BitShift; - struct r8192_priv *priv = ieee80211_priv(dev); - if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) + + if (!rtl8192_phy_CheckIsLegalRFPath(priv, eRFPath)) return 0; if (priv->eRFPowerState != eRfOn && !priv->being_init_adapter) return 0; down(&priv->rf_sem); if (priv->Rf_Mode == RF_OP_By_FW) { - Original_Value = phy_FwRFSerialRead(dev, eRFPath, RegAddr); + Original_Value = phy_FwRFSerialRead(priv, eRFPath, RegAddr); udelay(200); } else { - Original_Value = rtl8192_phy_RFSerialRead(dev, eRFPath, RegAddr); + Original_Value = rtl8192_phy_RFSerialRead(priv, eRFPath, RegAddr); } BitShift = rtl8192_CalculateBitShift(BitMask); @@ -886,12 +885,9 @@ u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u3 * return: none * notice: * ***************************************************************************/ -static u32 phy_FwRFSerialRead( - struct net_device* dev, - RF90_RADIO_PATH_E eRFPath, - u32 Offset ) +static u32 phy_FwRFSerialRead(struct r8192_priv *priv, + RF90_RADIO_PATH_E eRFPath, u32 Offset) { - struct r8192_priv *priv = ieee80211_priv(dev); u32 Data = 0; u8 time = 0; //DbgPrint("FW RF CTRL\n\r"); @@ -944,14 +940,9 @@ static u32 phy_FwRFSerialRead( * return: none * notice: * ***************************************************************************/ -static void -phy_FwRFSerialWrite( - struct net_device* dev, - RF90_RADIO_PATH_E eRFPath, - u32 Offset, - u32 Data ) +static void phy_FwRFSerialWrite(struct r8192_priv *priv, + RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data) { - struct r8192_priv *priv = ieee80211_priv(dev); u8 time = 0; //DbgPrint("N FW RF CTRL RF-%d OF%02x DATA=%03x\n\r", eRFPath, Offset, Data); @@ -1002,11 +993,10 @@ phy_FwRFSerialWrite( * notice: BB parameters may change all the time, so please make * sure it has been synced with the newest. * ***************************************************************************/ -void rtl8192_phy_configmac(struct net_device* dev) +void rtl8192_phy_configmac(struct r8192_priv *priv) { u32 dwArrayLen = 0, i = 0; u32* pdwArray = NULL; - struct r8192_priv *priv = ieee80211_priv(dev); #ifdef TO_DO_LIST if(Adapter->bInHctTest) { @@ -1038,7 +1028,7 @@ if(Adapter->bInHctTest) //DbgPrint("ptrArray[i], ptrArray[i+1], ptrArray[i+2] = %x, %x, %x\n", // ptrArray[i], ptrArray[i+1], ptrArray[i+2]); } - rtl8192_setBBreg(dev, pdwArray[i], pdwArray[i+1], pdwArray[i+2]); + rtl8192_setBBreg(priv, pdwArray[i], pdwArray[i+1], pdwArray[i+2]); } } @@ -1051,14 +1041,13 @@ if(Adapter->bInHctTest) * sure it has been synced with the newest. * ***************************************************************************/ -void rtl8192_phyConfigBB(struct net_device* dev, u8 ConfigType) +void rtl8192_phyConfigBB(struct r8192_priv *priv, u8 ConfigType) { int i; //u8 ArrayLength; u32* Rtl819XPHY_REGArray_Table = NULL; u32* Rtl819XAGCTAB_Array_Table = NULL; u16 AGCTAB_ArrayLen, PHY_REGArrayLen = 0; - struct r8192_priv *priv = ieee80211_priv(dev); #ifdef TO_DO_LIST u32 *rtl8192PhyRegArrayTable = NULL, *rtl8192AgcTabArrayTable = NULL; if(Adapter->bInHctTest) @@ -1098,7 +1087,7 @@ void rtl8192_phyConfigBB(struct net_device* dev, u8 ConfigType) { for (i=0; iPHYRegDef[RF90_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 LSBs if read 32-bit from 0x870 priv->PHYRegDef[RF90_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) @@ -1234,9 +1222,10 @@ static void rtl8192_InitBBRFRegDef(struct net_device* dev) * return: return whether BB and RF is ok(0:OK; 1:Fail) * notice: This function may be removed in the ASIC * ***************************************************************************/ -RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath) +RT_STATUS rtl8192_phy_checkBBAndRF(struct r8192_priv *priv, + HW90_BLOCK_E CheckBlock, + RF90_RADIO_PATH_E eRFPath) { - struct r8192_priv *priv = ieee80211_priv(dev); // BB_REGISTER_DEFINITION_T *pPhyReg = &priv->PHYRegDef[eRFPath]; RT_STATUS ret = RT_STATUS_SUCCESS; u32 i, CheckTimes = 4, dwRegRead = 0; @@ -1268,10 +1257,10 @@ RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlo case HW90_BLOCK_RF: WriteData[i] &= 0xfff; - rtl8192_phy_SetRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bMask12Bits, WriteData[i]); + rtl8192_phy_SetRFReg(priv, eRFPath, WriteAddr[HW90_BLOCK_RF], bMask12Bits, WriteData[i]); // TODO: we should not delay for such a long time. Ask SD3 mdelay(10); - dwRegRead = rtl8192_phy_QueryRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bMaskDWord); + dwRegRead = rtl8192_phy_QueryRFReg(priv, eRFPath, WriteAddr[HW90_BLOCK_RF], bMaskDWord); mdelay(10); break; @@ -1304,10 +1293,10 @@ RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlo * notice: Initialization value may change all the time, so please make * sure it has been synced with the newest. * ***************************************************************************/ -static RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device* dev) +static RT_STATUS rtl8192_BB_Config_ParaFile(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); RT_STATUS rtStatus = RT_STATUS_SUCCESS; + u8 bRegValue = 0, eCheckItem = 0; u32 dwRegValue = 0; /************************************** @@ -1326,7 +1315,7 @@ static RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device* dev) // TODO: this function should be removed on ASIC , Emily 2007.2.2 for(eCheckItem=(HW90_BLOCK_E)HW90_BLOCK_PHY0; eCheckItem<=HW90_BLOCK_PHY1; eCheckItem++) { - rtStatus = rtl8192_phy_checkBBAndRF(dev, (HW90_BLOCK_E)eCheckItem, (RF90_RADIO_PATH_E)0); //don't care RF path + rtStatus = rtl8192_phy_checkBBAndRF(priv, (HW90_BLOCK_E)eCheckItem, (RF90_RADIO_PATH_E)0); //don't care RF path if(rtStatus != RT_STATUS_SUCCESS) { RT_TRACE((COMP_ERR | COMP_PHY), "PHY_RF8256_Config():Check PHY%d Fail!!\n", eCheckItem-1); @@ -1334,10 +1323,10 @@ static RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device* dev) } } /*---- Set CCK and OFDM Block "OFF"----*/ - rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn|bOFDMEn, 0x0); + rtl8192_setBBreg(priv, rFPGA0_RFMOD, bCCKEn|bOFDMEn, 0x0); /*----BB Register Initilazation----*/ //==m==>Set PHY REG From Header<==m== - rtl8192_phyConfigBB(dev, BaseBand_Config_PHY_REG); + rtl8192_phyConfigBB(priv, BaseBand_Config_PHY_REG); /*----Set BB reset de-Active----*/ dwRegValue = read_nic_dword(priv, CPU_GEN); @@ -1345,7 +1334,7 @@ static RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device* dev) /*----BB AGC table Initialization----*/ //==m==>Set PHY REG From Header<==m== - rtl8192_phyConfigBB(dev, BaseBand_Config_AGC_TAB); + rtl8192_phyConfigBB(priv, BaseBand_Config_AGC_TAB); if (priv->card_8192_version > VERSION_8190_BD) { @@ -1358,13 +1347,13 @@ static RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device* dev) } else dwRegValue = 0x0; //Antenna gain offset doesn't make sense in RF 1T2R. - rtl8192_setBBreg(dev, rFPGA0_TxGainStage, + rtl8192_setBBreg(priv, rFPGA0_TxGainStage, (bXBTxAGC|bXCTxAGC|bXDTxAGC), dwRegValue); //XSTALLCap dwRegValue = priv->CrystalCap; - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bXtalCap92x, dwRegValue); + rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, bXtalCap92x, dwRegValue); } // Check if the CCK HighPower is turned ON. @@ -1380,12 +1369,12 @@ static RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device* dev) * notice: Initialization value may change all the time, so please make * sure it has been synced with the newest. * ***************************************************************************/ -RT_STATUS rtl8192_BBConfig(struct net_device* dev) +RT_STATUS rtl8192_BBConfig(struct r8192_priv *priv) { - rtl8192_InitBBRFRegDef(dev); + rtl8192_InitBBRFRegDef(priv); //config BB&RF. As hardCode based initialization has not been well //implemented, so use file first.FIXME:should implement it for hardcode? - return rtl8192_BB_Config_ParaFile(dev); + return rtl8192_BB_Config_ParaFile(priv); } /****************************************************************************** @@ -1394,10 +1383,8 @@ RT_STATUS rtl8192_BBConfig(struct net_device* dev) * output: none * return: none * ***************************************************************************/ -void rtl8192_phy_getTxPower(struct net_device* dev) +void rtl8192_phy_getTxPower(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); - priv->MCSTxPowerLevelOriginalOffset[0] = read_nic_dword(priv, rTxAGC_Rate18_06); priv->MCSTxPowerLevelOriginalOffset[1] = @@ -1435,9 +1422,8 @@ void rtl8192_phy_getTxPower(struct net_device* dev) * output: none * return: none * ***************************************************************************/ -void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel) +void rtl8192_phy_setTxPower(struct r8192_priv *priv, u8 channel) { - struct r8192_priv *priv = ieee80211_priv(dev); u8 powerlevel = 0,powerlevelOFDM24G = 0; char ant_pwr_diff; u32 u4RegValue; @@ -1477,7 +1463,7 @@ void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel) priv->AntennaTxPwDiff[1]<<4 | priv->AntennaTxPwDiff[0]); - rtl8192_setBBreg(dev, rFPGA0_TxGainStage, + rtl8192_setBBreg(priv, rFPGA0_TxGainStage, (bXBTxAGC|bXCTxAGC|bXDTxAGC), u4RegValue); } } @@ -1532,8 +1518,8 @@ void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel) pHalData->CurrentCckTxPwrIdx = powerlevel; pHalData->CurrentOfdm24GTxPwrIdx = powerlevelOFDM24G; #endif - PHY_SetRF8256CCKTxPower(dev, powerlevel); //need further implement - PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G); + PHY_SetRF8256CCKTxPower(priv, powerlevel); //need further implement + PHY_SetRF8256OFDMTxPower(priv, powerlevelOFDM24G); } /****************************************************************************** @@ -1542,9 +1528,9 @@ void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel) * output: none * return: only 8256 is supported * ***************************************************************************/ -RT_STATUS rtl8192_phy_RFConfig(struct net_device* dev) +RT_STATUS rtl8192_phy_RFConfig(struct r8192_priv *priv) { - return PHY_RF8256_Config(dev); + return PHY_RF8256_Config(priv); } /****************************************************************************** @@ -1553,7 +1539,7 @@ RT_STATUS rtl8192_phy_RFConfig(struct net_device* dev) * output: none * return: As Windows has not implemented this, wait for complement * ***************************************************************************/ -void rtl8192_phy_updateInitGain(struct net_device* dev) +void rtl8192_phy_updateInitGain(struct r8192_priv *priv) { } @@ -1564,7 +1550,8 @@ void rtl8192_phy_updateInitGain(struct net_device* dev) * return: return code show if RF configuration is successful(0:pass, 1:fail) * Note: Delay may be required for RF configuration * ***************************************************************************/ -u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E eRFPath) +u8 rtl8192_phy_ConfigRFWithHeaderFile(struct r8192_priv *priv, + RF90_RADIO_PATH_E eRFPath) { int i; @@ -1579,7 +1566,7 @@ u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E msleep(100); continue; } - rtl8192_phy_SetRFReg(dev, eRFPath, Rtl819XRadioA_Array[i], bMask12Bits, Rtl819XRadioA_Array[i+1]); + rtl8192_phy_SetRFReg(priv, eRFPath, Rtl819XRadioA_Array[i], bMask12Bits, Rtl819XRadioA_Array[i+1]); //msleep(1); } @@ -1591,7 +1578,7 @@ u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E msleep(100); continue; } - rtl8192_phy_SetRFReg(dev, eRFPath, Rtl819XRadioB_Array[i], bMask12Bits, Rtl819XRadioB_Array[i+1]); + rtl8192_phy_SetRFReg(priv, eRFPath, Rtl819XRadioB_Array[i], bMask12Bits, Rtl819XRadioB_Array[i+1]); //msleep(1); } @@ -1603,7 +1590,7 @@ u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E msleep(100); continue; } - rtl8192_phy_SetRFReg(dev, eRFPath, Rtl819XRadioC_Array[i], bMask12Bits, Rtl819XRadioC_Array[i+1]); + rtl8192_phy_SetRFReg(priv, eRFPath, Rtl819XRadioC_Array[i], bMask12Bits, Rtl819XRadioC_Array[i+1]); //msleep(1); } @@ -1615,7 +1602,7 @@ u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E msleep(100); continue; } - rtl8192_phy_SetRFReg(dev, eRFPath, Rtl819XRadioD_Array[i], bMask12Bits, Rtl819XRadioD_Array[i+1]); + rtl8192_phy_SetRFReg(priv, eRFPath, Rtl819XRadioD_Array[i], bMask12Bits, Rtl819XRadioD_Array[i+1]); //msleep(1); } @@ -1635,14 +1622,13 @@ u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E * return: none * Note: * ***************************************************************************/ -static void rtl8192_SetTxPowerLevel(struct net_device *dev, u8 channel) +static void rtl8192_SetTxPowerLevel(struct r8192_priv *priv, u8 channel) { - struct r8192_priv *priv = ieee80211_priv(dev); u8 powerlevel = priv->TxPowerLevelCCK[channel-1]; u8 powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1]; - PHY_SetRF8256CCKTxPower(dev, powerlevel); - PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G); + PHY_SetRF8256CCKTxPower(priv, powerlevel); + PHY_SetRF8256OFDMTxPower(priv, powerlevelOFDM24G); } /**************************************************************************************** @@ -1701,9 +1687,9 @@ static u8 rtl8192_phy_SetSwChnlCmdArray( * return: true if finished, false otherwise * Note: Wait for simpler function to replace it //wb * ***************************************************************************/ -static u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, u8* stage, u8* step, u32* delay) +static u8 rtl8192_phy_SwChnlStepByStep(struct r8192_priv *priv, u8 channel, + u8* stage, u8* step, u32* delay) { - struct r8192_priv *priv = ieee80211_priv(dev); // PCHANNEL_ACCESS_SETTING pChnlAccessSetting; SwChnlCmd PreCommonCmd[MAX_PRECMD_CNT]; u32 PreCommonCmdCnt; @@ -1792,7 +1778,7 @@ static u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, u8* s { case CmdID_SetTxPowerLevel: if(priv->card_8192_version > (u8)VERSION_8190_BD) //xiong: consider it later! - rtl8192_SetTxPowerLevel(dev,channel); + rtl8192_SetTxPowerLevel(priv, channel); break; case CmdID_WritePortUlong: write_nic_dword(priv, CurrentCmd->Para1, CurrentCmd->Para2); @@ -1805,7 +1791,7 @@ static u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, u8* s break; case CmdID_RF_WriteReg: for(eRFPath = 0; eRFPath NumTotalRFPath; eRFPath++) - rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, CurrentCmd->Para1, bMask12Bits, CurrentCmd->Para2<<7); + rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, CurrentCmd->Para1, bMask12Bits, CurrentCmd->Para2<<7); break; default: break; @@ -1828,12 +1814,11 @@ static u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, u8* s * return: noin * Note: We should not call this function directly * ***************************************************************************/ -static void rtl8192_phy_FinishSwChnlNow(struct net_device *dev, u8 channel) +static void rtl8192_phy_FinishSwChnlNow(struct r8192_priv *priv, u8 channel) { - struct r8192_priv *priv = ieee80211_priv(dev); u32 delay = 0; - while(!rtl8192_phy_SwChnlStepByStep(dev,channel,&priv->SwChnlStage,&priv->SwChnlStep,&delay)) + while (!rtl8192_phy_SwChnlStepByStep(priv, channel, &priv->SwChnlStage, &priv->SwChnlStep, &delay)) { if(delay>0) msleep(delay);//or mdelay? need further consideration @@ -1848,16 +1833,13 @@ static void rtl8192_phy_FinishSwChnlNow(struct net_device *dev, u8 channel) * output: none * return: noin * ***************************************************************************/ -void rtl8192_SwChnl_WorkItem(struct net_device *dev) +void rtl8192_SwChnl_WorkItem(struct r8192_priv *priv) { - - struct r8192_priv *priv = ieee80211_priv(dev); - RT_TRACE(COMP_TRACE, "==> SwChnlCallback819xUsbWorkItem()\n"); RT_TRACE(COMP_TRACE, "=====>--%s(), set chan:%d, priv:%p\n", __FUNCTION__, priv->chan, priv); - rtl8192_phy_FinishSwChnlNow(dev , priv->chan); + rtl8192_phy_FinishSwChnlNow(priv, priv->chan); RT_TRACE(COMP_TRACE, "<== SwChnlCallback819xUsbWorkItem()\n"); } @@ -1916,19 +1898,16 @@ u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel) priv->SwChnlStage=0; priv->SwChnlStep=0; -// schedule_work(&(priv->SwChnlWorkItem)); -// rtl8192_SwChnl_WorkItem(dev); - if(priv->up) { -// queue_work(priv->priv_wq,&(priv->SwChnlWorkItem)); - rtl8192_SwChnl_WorkItem(dev); - } + if (priv->up) + rtl8192_SwChnl_WorkItem(priv); + priv->SwChnlInProgress = false; return true; } -static void CCK_Tx_Power_Track_BW_Switch_TSSI(struct net_device *dev ) +static void CCK_Tx_Power_Track_BW_Switch_TSSI(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); + struct net_device *dev = priv->ieee80211->dev; switch(priv->CurrentChannelBW) { @@ -1987,9 +1966,9 @@ static void CCK_Tx_Power_Track_BW_Switch_TSSI(struct net_device *dev ) } } -static void CCK_Tx_Power_Track_BW_Switch_ThermalMeter(struct net_device *dev) +static void CCK_Tx_Power_Track_BW_Switch_ThermalMeter(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); + struct net_device *dev = priv->ieee80211->dev; if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) priv->bcck_in_ch14 = TRUE; @@ -2016,15 +1995,14 @@ static void CCK_Tx_Power_Track_BW_Switch_ThermalMeter(struct net_device *dev) dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); } -static void CCK_Tx_Power_Track_BW_Switch(struct net_device *dev) +static void CCK_Tx_Power_Track_BW_Switch(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); //if(pHalData->bDcut == TRUE) if(priv->IC_Cut >= IC_VersionCut_D) - CCK_Tx_Power_Track_BW_Switch_TSSI(dev); + CCK_Tx_Power_Track_BW_Switch_TSSI(priv); else - CCK_Tx_Power_Track_BW_Switch_ThermalMeter(dev); + CCK_Tx_Power_Track_BW_Switch_ThermalMeter(priv); } @@ -2039,10 +2017,8 @@ static void CCK_Tx_Power_Track_BW_Switch(struct net_device *dev) * Note: I doubt whether SetBWModeInProgress flag is necessary as we can * test whether current work in the queue or not.//do I? * ***************************************************************************/ -void rtl8192_SetBWModeWorkItem(struct net_device *dev) +void rtl8192_SetBWModeWorkItem(struct r8192_priv *priv) { - - struct r8192_priv *priv = ieee80211_priv(dev); u8 regBwOpMode; RT_TRACE(COMP_SWBW, "==>rtl8192_SetBWModeWorkItem() Switch to %s bandwidth\n", @@ -2081,8 +2057,8 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) { case HT_CHANNEL_WIDTH_20: // Add by Vivi 20071119 - rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0); - rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0); + rtl8192_setBBreg(priv, rFPGA0_RFMOD, bRFMOD, 0x0); + rtl8192_setBBreg(priv, rFPGA1_RFMOD, bRFMOD, 0x0); // rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 1); // Correct the tx power for CCK rate in 20M. Suggest by YN, 20071207 @@ -2096,14 +2072,14 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) write_nic_dword(priv, rCCK0_DebugPort, 0x00000204); } else - CCK_Tx_Power_Track_BW_Switch(dev); + CCK_Tx_Power_Track_BW_Switch(priv); - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 1); + rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x00100000, 1); break; case HT_CHANNEL_WIDTH_20_40: // Add by Vivi 20071119 - rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1); - rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1); + rtl8192_setBBreg(priv, rFPGA0_RFMOD, bRFMOD, 0x1); + rtl8192_setBBreg(priv, rFPGA1_RFMOD, bRFMOD, 0x1); //rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1)); //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 0); //rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC); @@ -2119,14 +2095,14 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) write_nic_dword(priv, rCCK0_DebugPort, 0x00000409); } else - CCK_Tx_Power_Track_BW_Switch(dev); + CCK_Tx_Power_Track_BW_Switch(priv); // Set Control channel to upper or lower. These settings are required only for 40MHz - rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1)); - rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC); + rtl8192_setBBreg(priv, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1)); + rtl8192_setBBreg(priv, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC); - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 0); + rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x00100000, 0); break; default: RT_TRACE(COMP_ERR, "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n" ,priv->CurrentChannelBW); @@ -2136,7 +2112,7 @@ void rtl8192_SetBWModeWorkItem(struct net_device *dev) //Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315 //<3>Set RF related register - PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW); + PHY_SetRF8256Bandwidth(priv, priv->CurrentChannelBW); atomic_dec(&(priv->ieee80211->atm_swbw)); priv->SetBWModeInProgress= false; @@ -2176,7 +2152,7 @@ void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EX //queue_work(priv->priv_wq, &(priv->SetBWModeWorkItem)); // schedule_work(&(priv->SetBWModeWorkItem)); - rtl8192_SetBWModeWorkItem(dev); + rtl8192_SetBWModeWorkItem(priv); } @@ -2198,13 +2174,13 @@ void InitialGain819xPci(struct net_device *dev, u8 Operation) initial_gain = SCAN_RX_INITIAL_GAIN;//pHalData->DefaultInitialGain[0];// BitMask = bMaskByte0; if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // FW DIG OFF - priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, BitMask); - priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, BitMask); - priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, BitMask); - priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, BitMask); + rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x8); // FW DIG OFF + priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(priv, rOFDM0_XAAGCCore1, BitMask); + priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(priv, rOFDM0_XBAGCCore1, BitMask); + priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(priv, rOFDM0_XCAGCCore1, BitMask); + priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(priv, rOFDM0_XDAGCCore1, BitMask); BitMask = bMaskByte2; - priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, BitMask); + priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(priv, rCCK0_CCA, BitMask); RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc50 is %x\n",priv->initgain_backup.xaagccore1); RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc58 is %x\n",priv->initgain_backup.xbagccore1); @@ -2224,14 +2200,14 @@ void InitialGain819xPci(struct net_device *dev, u8 Operation) RT_TRACE(COMP_SCAN, "IG_Restore, restore the initial gain.\n"); BitMask = 0x7f; //Bit0~ Bit6 if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); // FW DIG OFF + rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x8); // FW DIG OFF - rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, BitMask, (u32)priv->initgain_backup.xaagccore1); - rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, BitMask, (u32)priv->initgain_backup.xbagccore1); - rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, BitMask, (u32)priv->initgain_backup.xcagccore1); - rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, BitMask, (u32)priv->initgain_backup.xdagccore1); + rtl8192_setBBreg(priv, rOFDM0_XAAGCCore1, BitMask, (u32)priv->initgain_backup.xaagccore1); + rtl8192_setBBreg(priv, rOFDM0_XBAGCCore1, BitMask, (u32)priv->initgain_backup.xbagccore1); + rtl8192_setBBreg(priv, rOFDM0_XCAGCCore1, BitMask, (u32)priv->initgain_backup.xcagccore1); + rtl8192_setBBreg(priv, rOFDM0_XDAGCCore1, BitMask, (u32)priv->initgain_backup.xdagccore1); BitMask = bMaskByte2; - rtl8192_setBBreg(dev, rCCK0_CCA, BitMask, (u32)priv->initgain_backup.cca); + rtl8192_setBBreg(priv, rCCK0_CCA, BitMask, (u32)priv->initgain_backup.cca); RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc50 is %x\n",priv->initgain_backup.xaagccore1); RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc58 is %x\n",priv->initgain_backup.xbagccore1); @@ -2239,11 +2215,11 @@ void InitialGain819xPci(struct net_device *dev, u8 Operation) RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc68 is %x\n",priv->initgain_backup.xdagccore1); RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xa0a is %x\n",priv->initgain_backup.cca); - rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel); + rtl8192_phy_setTxPower(priv, priv->ieee80211->current_network.channel); if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) - rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); // FW DIG ON + rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x1); // FW DIG ON break; default: RT_TRACE(COMP_SCAN, "Unknown IG Operation.\n"); diff --git a/drivers/staging/rtl8192e/r819xE_phy.h b/drivers/staging/rtl8192e/r819xE_phy.h index c676c3ad0c88..46008eee5126 100644 --- a/drivers/staging/rtl8192e/r819xE_phy.h +++ b/drivers/staging/rtl8192e/r819xE_phy.h @@ -82,39 +82,39 @@ typedef enum _RF90_RADIO_PATH { #define bMaskLWord 0x0000ffff #define bMaskDWord 0xffffffff -u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device *dev, u32 eRFPath); +u8 rtl8192_phy_CheckIsLegalRFPath(struct r8192_priv *priv, u32 eRFPath); -void rtl8192_setBBreg(struct net_device *dev, u32 dwRegAddr, +void rtl8192_setBBreg(struct r8192_priv *priv, u32 dwRegAddr, u32 dwBitMask, u32 dwData); -u32 rtl8192_QueryBBReg(struct net_device *dev, u32 dwRegAddr, +u32 rtl8192_QueryBBReg(struct r8192_priv *priv, u32 dwRegAddr, u32 dwBitMask); -void rtl8192_phy_SetRFReg(struct net_device *dev, +void rtl8192_phy_SetRFReg(struct r8192_priv *priv, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask, u32 Data); -u32 rtl8192_phy_QueryRFReg(struct net_device *dev, +u32 rtl8192_phy_QueryRFReg(struct r8192_priv *priv, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask); -void rtl8192_phy_configmac(struct net_device *dev); +void rtl8192_phy_configmac(struct r8192_priv *priv); -void rtl8192_phyConfigBB(struct net_device *dev, u8 ConfigType); +void rtl8192_phyConfigBB(struct r8192_priv *priv, u8 ConfigType); -RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device *dev, +RT_STATUS rtl8192_phy_checkBBAndRF(struct r8192_priv *priv, HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath); -RT_STATUS rtl8192_BBConfig(struct net_device *dev); +RT_STATUS rtl8192_BBConfig(struct r8192_priv *priv); -void rtl8192_phy_getTxPower(struct net_device *dev); +void rtl8192_phy_getTxPower(struct r8192_priv *priv); -void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel); +void rtl8192_phy_setTxPower(struct r8192_priv *priv, u8 channel); -RT_STATUS rtl8192_phy_RFConfig(struct net_device* dev); +RT_STATUS rtl8192_phy_RFConfig(struct r8192_priv *priv); -void rtl8192_phy_updateInitGain(struct net_device* dev); +void rtl8192_phy_updateInitGain(struct r8192_priv *priv); -u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev, +u8 rtl8192_phy_ConfigRFWithHeaderFile(struct r8192_priv *priv, RF90_RADIO_PATH_E eRFPath); u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel); @@ -122,9 +122,9 @@ u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel); void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); -void rtl8192_SwChnl_WorkItem(struct net_device *dev); +void rtl8192_SwChnl_WorkItem(struct r8192_priv *priv); -void rtl8192_SetBWModeWorkItem(struct net_device *dev); +void rtl8192_SetBWModeWorkItem(struct r8192_priv *priv); void InitialGain819xPci(struct net_device *dev, u8 Operation); -- cgit v1.2.3 From 480ab9dccb9b82ff9fca3118abd65e9f7908a085 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:45:24 +0900 Subject: staging: rtl8192e: Convert more functions to use r8192_priv Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8190_rtl8256.c | 49 ++++++------------ drivers/staging/rtl8192e/r8192E.h | 8 +-- drivers/staging/rtl8192e/r8192E_core.c | 85 +++++++++++++------------------- drivers/staging/rtl8192e/r8192E_wx.c | 2 +- 4 files changed, 56 insertions(+), 88 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index 3cf96aa8d7ce..8861aebe4fe8 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -317,10 +317,9 @@ static void r8192e_drain_tx_queues(struct r8192_priv *priv) } } -static bool -SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) +static bool SetRFPowerState8190(struct r8192_priv *priv, + RT_RF_POWER_STATE eRFPowerState) { - struct r8192_priv *priv = ieee80211_priv(dev); PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; bool bResult = true; @@ -342,7 +341,7 @@ SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) * The current RF state is OFF and the RF OFF level * is halting the NIC, re-initialize the NIC. */ - if (!NicIFEnableNIC(dev)) { + if (!NicIFEnableNIC(priv)) { RT_TRACE(COMP_ERR, "%s(): NicIFEnableNIC failed\n",__FUNCTION__); bResult = false; goto out; @@ -386,7 +385,7 @@ SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) r8192e_drain_tx_queues(priv); - PHY_SetRtl8192eRfOff(dev); + PHY_SetRtl8192eRfOff(priv); break; @@ -401,13 +400,13 @@ SetRFPowerState8190(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) { /* Disable all components. */ - NicIFDisableNIC(dev); + NicIFDisableNIC(priv); RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); } else if (!(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC)) { /* Normal case - IPS should go to this. */ - PHY_SetRtl8192eRfOff(dev); + PHY_SetRtl8192eRfOff(priv); } break; @@ -431,12 +430,8 @@ out: -static void -MgntDisconnectIBSS( - struct net_device* dev -) +static void MgntDisconnectIBSS(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); u8 i; bool bFilterOutNonAssociatedBSSID = false; @@ -498,14 +493,9 @@ MgntDisconnectIBSS( } -static void -MlmeDisassociateRequest( - struct net_device* dev, - u8* asSta, - u8 asRsn - ) +static void MlmeDisassociateRequest(struct r8192_priv *priv, u8 *asSta, + u8 asRsn) { - struct r8192_priv *priv = ieee80211_priv(dev); u8 i; RemovePeerTS(priv->ieee80211, asSta); @@ -557,9 +547,8 @@ MlmeDisassociateRequest( } -static void MgntDisconnectAP(struct net_device *dev, u8 asRsn) +static void MgntDisconnectAP(struct r8192_priv *priv, u8 asRsn) { - struct r8192_priv *priv = ieee80211_priv(dev); bool bFilterOutNonAssociatedBSSID = false; u32 RegRCR, Type; @@ -578,26 +567,20 @@ static void MgntDisconnectAP(struct net_device *dev, u8 asRsn) write_nic_dword(priv, RCR, RegRCR); priv->ReceiveConfig = RegRCR; - MlmeDisassociateRequest(dev, priv->ieee80211->current_network.bssid, asRsn); + MlmeDisassociateRequest(priv, priv->ieee80211->current_network.bssid, asRsn); priv->ieee80211->state = IEEE80211_NOLINK; } -static bool -MgntDisconnect( - struct net_device* dev, - u8 asRsn -) +static bool MgntDisconnect(struct r8192_priv *priv, u8 asRsn) { - struct r8192_priv *priv = ieee80211_priv(dev); - // In adhoc mode, update beacon frame. if( priv->ieee80211->state == IEEE80211_LINKED ) { if( priv->ieee80211->iw_mode == IW_MODE_ADHOC ) { - MgntDisconnectIBSS(dev); + MgntDisconnectIBSS(priv); } if( priv->ieee80211->iw_mode == IW_MODE_INFRA ) { @@ -606,7 +589,7 @@ MgntDisconnect( // e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is // used to handle disassociation related things to AP, e.g. send Disassoc // frame to AP. 2005.01.27, by rcnjko. - MgntDisconnectAP(dev, asRsn); + MgntDisconnectAP(priv, asRsn); } } @@ -665,7 +648,7 @@ MgntActSet_RF_State( if (priv->RfOffReason > RF_CHANGE_BY_IPS) { // Disconnect to current BSS when radio off. Asked by QuanTa. - MgntDisconnect(dev, disas_lv_ss); + MgntDisconnect(priv, disas_lv_ss); } priv->RfOffReason |= ChangeSource; @@ -682,7 +665,7 @@ MgntActSet_RF_State( { RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->RfOffReason); // Config HW to the specified mode. - SetRFPowerState8190(dev, StateToSet); + SetRFPowerState8190(priv, StateToSet); } else { diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 6862bf22a9b1..d04d4cc69006 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1059,7 +1059,7 @@ int rtl8192_down(struct net_device *dev); int rtl8192_up(struct net_device *dev); void rtl8192_commit(struct net_device *dev); void write_phy(struct net_device *dev, u8 adr, u8 data); -void CamResetAllEntry(struct net_device* dev); +void CamResetAllEntry(struct r8192_priv *priv); void EnableHWSecurityConfig8192(struct net_device *dev); void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent ); void dm_cck_txpower_adjust(struct net_device *dev, bool binch14); @@ -1079,8 +1079,8 @@ void LeisurePSEnter(struct net_device *dev); void LeisurePSLeave(struct net_device *dev); #endif -bool NicIFEnableNIC(struct net_device* dev); -bool NicIFDisableNIC(struct net_device* dev); +bool NicIFEnableNIC(struct r8192_priv *priv); +bool NicIFDisableNIC(struct r8192_priv *priv); -void PHY_SetRtl8192eRfOff(struct net_device* dev); +void PHY_SetRtl8192eRfOff(struct r8192_priv *priv); #endif diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 50480ac3513c..0ab40bc15c0a 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -104,7 +104,7 @@ static void rtl8192_irq_tx_tasklet(unsigned long arg); static void rtl8192_prepare_beacon(unsigned long arg); static irqreturn_t rtl8192_interrupt(int irq, void *netdev); static void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb); -static void rtl8192_update_ratr_table(struct net_device* dev); +static void rtl8192_update_ratr_table(struct r8192_priv *priv); static void rtl8192_restart(struct work_struct *work); static void watch_dog_timer_callback(unsigned long data); static int _rtl8192_up(struct net_device *dev); @@ -191,9 +191,8 @@ static inline bool rx_hal_is_cck_rate(prx_fwinfo_819x_pci pdrvinfo) !pdrvinfo->RxHT; } -void CamResetAllEntry(struct net_device *dev) +void CamResetAllEntry(struct r8192_priv* priv) { - struct r8192_priv* priv = ieee80211_priv(dev); write_nic_dword(priv, RWCAM, BIT31|BIT30); } @@ -614,9 +613,8 @@ static void tx_timeout(struct net_device *dev) printk("TXTIMEOUT"); } -static void rtl8192_irq_enable(struct net_device *dev) +static void rtl8192_irq_enable(struct r8192_priv *priv) { - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); u32 mask; mask = IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK | @@ -635,9 +633,8 @@ static void rtl8192_irq_disable(struct net_device *dev) synchronize_irq(dev->irq); } -static void rtl8192_update_msr(struct net_device *dev) +static void rtl8192_update_msr(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); u8 msr; msr = read_nic_byte(priv, MSR); @@ -675,11 +672,9 @@ static void rtl8192_set_chan(struct net_device *dev,short ch) priv->rf_set_chan(dev, priv->chan); } -static void rtl8192_rx_enable(struct net_device *dev) +static void rtl8192_rx_enable(struct r8192_priv *priv) { - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - - write_nic_dword(priv, RDQDA,priv->rx_ring_dma); + write_nic_dword(priv, RDQDA, priv->rx_ring_dma); } /* the TX_DESC_BASE setting is according to the following queue index @@ -694,9 +689,8 @@ static void rtl8192_rx_enable(struct net_device *dev) * BEACON_QUEUE ===> 8 * */ static const u32 TX_DESC_BASE[] = {BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA}; -static void rtl8192_tx_enable(struct net_device *dev) +static void rtl8192_tx_enable(struct r8192_priv *priv) { - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); u32 i; for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) @@ -747,10 +741,8 @@ static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio) ring->desc = NULL; } -void PHY_SetRtl8192eRfOff(struct net_device* dev) +void PHY_SetRtl8192eRfOff(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); - //disable RF-Chip A/B rtl8192_setBBreg(priv, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0); //analog to digital off, for power save @@ -766,7 +758,6 @@ void PHY_SetRtl8192eRfOff(struct net_device* dev) rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x4, 0x0); // Analog parameter!!Change bias and Lbus control. write_nic_byte(priv, ANAPAR_FOR_8192PciE, 0x07); - } static void rtl8192_halt_adapter(struct net_device *dev, bool reset) @@ -799,7 +790,7 @@ static void rtl8192_halt_adapter(struct net_device *dev, bool reset) * prevent RF config race condition. */ if (!priv->ieee80211->bSupportRemoteWakeUp) { - PHY_SetRtl8192eRfOff(dev); + PHY_SetRtl8192eRfOff(priv); ulRegRead = read_nic_dword(priv, CPU_GEN); ulRegRead |= CPU_GEN_SYSTEM_RESET; write_nic_dword(priv,CPU_GEN, ulRegRead); @@ -946,9 +937,8 @@ static void rtl8192_stop_beacon(struct net_device *dev) { } -static void rtl8192_config_rate(struct net_device* dev, u16* rate_config) +static void rtl8192_config_rate(struct r8192_priv *priv, u16* rate_config) { - struct r8192_priv *priv = ieee80211_priv(dev); struct ieee80211_network *net; u8 i=0, basic_rate = 0; net = & priv->ieee80211->current_network; @@ -997,11 +987,11 @@ static void rtl8192_config_rate(struct net_device* dev, u16* rate_config) #define SHORT_SLOT_TIME 9 #define NON_SHORT_SLOT_TIME 20 -static void rtl8192_update_cap(struct net_device* dev, u16 cap) +static void rtl8192_update_cap(struct r8192_priv *priv, u16 cap) { u32 tmp = 0; - struct r8192_priv *priv = ieee80211_priv(dev); struct ieee80211_network *net = &priv->ieee80211->current_network; + priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE; tmp = priv->basic_rate; if (priv->short_preamble) @@ -1023,16 +1013,15 @@ static void rtl8192_update_cap(struct net_device* dev, u16 cap) } -static void rtl8192_net_update(struct net_device *dev) +static void rtl8192_net_update(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); struct ieee80211_network *net; u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf; u16 rate_config = 0; net = &priv->ieee80211->current_network; /* update Basic rate: RR, BRSR */ - rtl8192_config_rate(dev, &rate_config); + rtl8192_config_rate(priv, &rate_config); /* * Select RRSR (in Legacy-OFDM and CCK) @@ -1462,9 +1451,8 @@ err_free_rings: return 1; } -static void rtl8192_pci_resetdescring(struct net_device *dev) +static void rtl8192_pci_resetdescring(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); int i; /* force the rx_idx to the first one */ @@ -1504,8 +1492,8 @@ static void rtl8192_link_change(struct net_device *dev) if (ieee->state == IEEE80211_LINKED) { - rtl8192_net_update(dev); - rtl8192_update_ratr_table(dev); + rtl8192_net_update(priv); + rtl8192_update_ratr_table(priv); //add this as in pure N mode, wep encryption will use software way, but there is no chance to set this as wep will not set group key in wext. WB.2008.07.08 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) @@ -1516,7 +1504,7 @@ static void rtl8192_link_change(struct net_device *dev) write_nic_byte(priv, 0x173, 0); } - rtl8192_update_msr(dev); + rtl8192_update_msr(priv); // 2007/10/16 MH MAC Will update TSF according to all received beacon, so we have // // To set CBSSID bit when link with any AP or STA. @@ -1544,14 +1532,13 @@ static const struct ieee80211_qos_parameters def_qos_parameters = { static void rtl8192_update_beacon(struct work_struct * work) { struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work); - struct net_device *dev = priv->ieee80211->dev; struct ieee80211_device* ieee = priv->ieee80211; struct ieee80211_network* net = &ieee->current_network; if (ieee->pHTInfo->bCurrentHTSupport) HTUpdateSelfAndPeerSetting(ieee, net); ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime; - rtl8192_update_cap(dev, net->capability); + rtl8192_update_cap(priv, net->capability); } /* @@ -1709,15 +1696,14 @@ static int rtl8192_handle_assoc_response(struct net_device *dev, /* updateRATRTabel for MCS only. Basic rate is not implemented. */ -static void rtl8192_update_ratr_table(struct net_device* dev) +static void rtl8192_update_ratr_table(struct r8192_priv* priv) { - struct r8192_priv* priv = ieee80211_priv(dev); struct ieee80211_device* ieee = priv->ieee80211; u8* pMcsRate = ieee->dot11HTOperationalRateSet; u32 ratr_value = 0; u8 rate_index = 0; - rtl8192_config_rate(dev, (u16*)(&ratr_value)); + rtl8192_config_rate(priv, (u16*)(&ratr_value)); ratr_value |= (*(u16*)(pMcsRate)) << 12; switch (ieee->mode) @@ -2518,15 +2504,14 @@ static short rtl8192_init(struct net_device *dev) * not to do all the hw config as its name says * This part need to modified according to the rate set we filtered */ -static void rtl8192_hwconfig(struct net_device* dev) +static void rtl8192_hwconfig(struct r8192_priv *priv) { u32 regRATR = 0, regRRSR = 0; u8 regBwOpMode = 0, regTmp = 0; - struct r8192_priv *priv = ieee80211_priv(dev); // Set RRSR, RATR, and BW_OPMODE registers // - switch(priv->ieee80211->mode) + switch (priv->ieee80211->mode) { case WIRELESS_MODE_B: regBwOpMode = BW_OPMODE_20MHZ; @@ -2604,7 +2589,7 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__); priv->being_init_adapter = true; - rtl8192_pci_resetdescring(dev); + rtl8192_pci_resetdescring(priv); // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W. priv->Rf_Mode = RF_OP_By_SW_3wire; @@ -2697,7 +2682,7 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) udelay(500); } //3Set Hardware(Do nothing now) - rtl8192_hwconfig(dev); + rtl8192_hwconfig(priv); //2======================================================= // Common Setting for all of the FPGA platform. (part 1) //2======================================================= @@ -2725,8 +2710,8 @@ static RT_STATUS rtl8192_adapter_start(struct net_device *dev) NUM_OF_PAGE_IN_FW_QUEUE_BCN<being_init_adapter = false; return rtStatus; @@ -2976,7 +2961,7 @@ static void rtl8192_start_beacon(struct net_device *dev) /* enable the interrupt for ad-hoc process */ - rtl8192_irq_enable(dev); + rtl8192_irq_enable(priv); } static bool HalRxCheckStuck8190Pci(struct net_device *dev) @@ -5106,10 +5091,10 @@ void setKey( struct net_device *dev, RT_TRACE(COMP_SEC,"=========>after set key, usconfig:%x\n", usConfig); } -bool NicIFEnableNIC(struct net_device* dev) +bool NicIFEnableNIC(struct r8192_priv *priv) { RT_STATUS init_status = RT_STATUS_SUCCESS; - struct r8192_priv* priv = ieee80211_priv(dev); + struct net_device *dev = priv->ieee80211->dev; PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; //YJ,add,091109 @@ -5133,16 +5118,16 @@ bool NicIFEnableNIC(struct net_device* dev) //priv->bfirst_init = false; // <3> Enable Interrupt - rtl8192_irq_enable(dev); + rtl8192_irq_enable(priv); priv->bdisable_nic = false; return (init_status == RT_STATUS_SUCCESS); } -bool NicIFDisableNIC(struct net_device* dev) +bool NicIFDisableNIC(struct r8192_priv *priv) { bool status = true; - struct r8192_priv* priv = ieee80211_priv(dev); + struct net_device *dev = priv->ieee80211->dev; u8 tmp_state = 0; // <1> Disable Interrupt diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c index 7ce9f6e78307..cf581c6e4840 100644 --- a/drivers/staging/rtl8192e/r8192E_wx.c +++ b/drivers/staging/rtl8192e/r8192E_wx.c @@ -887,7 +887,7 @@ static int r8192_wx_set_enc_ext(struct net_device *dev, ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01 { ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA; - CamResetAllEntry(dev); + CamResetAllEntry(priv); goto end_hw_sec; } alg = (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg; // as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4; -- cgit v1.2.3 From af59c39d5cbaba5e6c83da94907e02744bd47670 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:45:42 +0900 Subject: staging: rtl8192e: Pass r8192_priv around instead of net_device Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 3 +- drivers/staging/rtl8192e/r8192E_core.c | 178 +++++++++++++++------------------ drivers/staging/rtl8192e/r8192E_wx.c | 2 +- 3 files changed, 82 insertions(+), 101 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index d04d4cc69006..7cbf69be6fe1 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1057,7 +1057,7 @@ void write_nic_dword(struct r8192_priv *priv, int x,u32 y); int rtl8192_down(struct net_device *dev); int rtl8192_up(struct net_device *dev); -void rtl8192_commit(struct net_device *dev); +void rtl8192_commit(struct r8192_priv *priv); void write_phy(struct net_device *dev, u8 adr, u8 data); void CamResetAllEntry(struct r8192_priv *priv); void EnableHWSecurityConfig8192(struct net_device *dev); @@ -1069,7 +1069,6 @@ RT_STATUS cmpk_message_handle_tx(struct net_device *dev, u8* codevirtualaddress, #ifdef ENABLE_IPS void IPSEnter(struct net_device *dev); void IPSLeave(struct net_device *dev); -void InactivePsWorkItemCallback(struct net_device *dev); void IPSLeave_wq(struct work_struct *work); void ieee80211_ips_leave_wq(struct net_device *dev); void ieee80211_ips_leave(struct net_device *dev); diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 0ab40bc15c0a..fb67e5f55f18 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -107,9 +107,9 @@ static void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb); static void rtl8192_update_ratr_table(struct r8192_priv *priv); static void rtl8192_restart(struct work_struct *work); static void watch_dog_timer_callback(unsigned long data); -static int _rtl8192_up(struct net_device *dev); +static int _rtl8192_up(struct r8192_priv *priv); static void rtl8192_cancel_deferred_work(struct r8192_priv* priv); -static short rtl8192_tx(struct net_device *dev, struct sk_buff* skb); +static short rtl8192_tx(struct r8192_priv *priv, struct sk_buff* skb); #ifdef ENABLE_DOT11D @@ -528,9 +528,9 @@ static void rtl8192_proc_module_remove(void) } -static void rtl8192_proc_remove_one(struct net_device *dev) +static void rtl8192_proc_remove_one(struct r8192_priv *priv) { - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + struct net_device *dev = priv->ieee80211->dev; printk("dev name=======> %s\n",dev->name); @@ -545,10 +545,11 @@ static void rtl8192_proc_remove_one(struct net_device *dev) } -static void rtl8192_proc_init_one(struct net_device *dev) +static void rtl8192_proc_init_one(struct r8192_priv *priv) { + struct net_device *dev = priv->ieee80211->dev; struct proc_dir_entry *e; - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + priv->dir_dev = create_proc_entry(dev->name, S_IFDIR | S_IRUGO | S_IXUGO, rtl8192_proc); @@ -625,12 +626,10 @@ static void rtl8192_irq_enable(struct r8192_priv *priv) write_nic_dword(priv, INTA_MASK, mask); } -static void rtl8192_irq_disable(struct net_device *dev) +static void rtl8192_irq_disable(struct r8192_priv *priv) { - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - write_nic_dword(priv, INTA_MASK, 0); - synchronize_irq(dev->irq); + synchronize_irq(priv->irq); } static void rtl8192_update_msr(struct r8192_priv *priv) @@ -700,9 +699,8 @@ static void rtl8192_tx_enable(struct r8192_priv *priv) } -static void rtl8192_free_rx_ring(struct net_device *dev) +static void rtl8192_free_rx_ring(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); int i; for (i = 0; i < priv->rxringcount; i++) { @@ -721,9 +719,8 @@ static void rtl8192_free_rx_ring(struct net_device *dev) priv->rx_ring = NULL; } -static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio) +static void rtl8192_free_tx_ring(struct r8192_priv *priv, unsigned int prio) { - struct r8192_priv *priv = ieee80211_priv(dev); struct rtl8192_tx_ring *ring = &priv->tx_ring[prio]; while (skb_queue_len(&ring->queue)) { @@ -760,9 +757,9 @@ void PHY_SetRtl8192eRfOff(struct r8192_priv *priv) write_nic_byte(priv, ANAPAR_FOR_8192PciE, 0x07); } -static void rtl8192_halt_adapter(struct net_device *dev, bool reset) +static void rtl8192_halt_adapter(struct r8192_priv *priv, bool reset) { - struct r8192_priv *priv = ieee80211_priv(dev); + struct net_device *dev = priv->ieee80211->dev; int i; u8 OpMode; u32 ulRegRead; @@ -848,7 +845,7 @@ static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, memcpy(skb->cb, &dev, sizeof(dev)); skb_push(skb, priv->ieee80211->tx_headroom); - ret = rtl8192_tx(dev, skb); + ret = rtl8192_tx(priv, skb); if (ret != 0) { kfree_skb(skb); } @@ -891,7 +888,7 @@ static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev) tcb_desc->bTxUseDriverAssingedRate = 1; tcb_desc->bTxEnableFwCalcDur = 1; skb_push(skb, priv->ieee80211->tx_headroom); - ret = rtl8192_tx(dev, skb); + ret = rtl8192_tx(priv, skb); if (ret != 0) { kfree_skb(skb); } @@ -901,9 +898,8 @@ static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev) } -static void rtl8192_tx_isr(struct net_device *dev, int prio) +static void rtl8192_tx_isr(struct r8192_priv *priv, int prio) { - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); struct rtl8192_tx_ring *ring = &priv->tx_ring[prio]; while (skb_queue_len(&ring->queue)) { @@ -1203,9 +1199,8 @@ static u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc) * skb->cb will contain all the following information, * priority, morefrag, rate, &dev. */ -static short rtl8192_tx(struct net_device *dev, struct sk_buff* skb) +static short rtl8192_tx(struct r8192_priv *priv, struct sk_buff* skb) { - struct r8192_priv *priv = ieee80211_priv(dev); struct rtl8192_tx_ring *ring; unsigned long flags; cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); @@ -1353,14 +1348,13 @@ static short rtl8192_tx(struct net_device *dev, struct sk_buff* skb) __skb_queue_tail(&ring->queue, skb); pdesc->OWN = 1; spin_unlock_irqrestore(&priv->irq_th_lock, flags); - dev->trans_start = jiffies; + priv->ieee80211->dev->trans_start = jiffies; write_nic_word(priv, TPPoll, 0x01<queue_index); return 0; } -static short rtl8192_alloc_rx_desc_ring(struct net_device *dev) +static short rtl8192_alloc_rx_desc_ring(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); rx_desc_819x_pci *entry = NULL; int i; @@ -1396,10 +1390,9 @@ static short rtl8192_alloc_rx_desc_ring(struct net_device *dev) return 0; } -static int rtl8192_alloc_tx_desc_ring(struct net_device *dev, +static int rtl8192_alloc_tx_desc_ring(struct r8192_priv *priv, unsigned int prio, unsigned int entries) { - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); tx_desc_819x_pci *ring; dma_addr_t dma; int i; @@ -1424,19 +1417,18 @@ static int rtl8192_alloc_tx_desc_ring(struct net_device *dev, return 0; } -static short rtl8192_pci_initdescring(struct net_device *dev) +static short rtl8192_pci_initdescring(struct r8192_priv *priv) { u32 ret; int i; - struct r8192_priv *priv = ieee80211_priv(dev); - ret = rtl8192_alloc_rx_desc_ring(dev); + ret = rtl8192_alloc_rx_desc_ring(priv); if (ret) return ret; /* general process for other queue */ for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) { - ret = rtl8192_alloc_tx_desc_ring(dev, i, priv->txringcount); + ret = rtl8192_alloc_tx_desc_ring(priv, i, priv->txringcount); if (ret) goto err_free_rings; } @@ -1444,10 +1436,10 @@ static short rtl8192_pci_initdescring(struct net_device *dev) return 0; err_free_rings: - rtl8192_free_rx_ring(dev); + rtl8192_free_rx_ring(priv); for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) if (priv->tx_ring[i].desc) - rtl8192_free_tx_ring(dev, i); + rtl8192_free_tx_ring(priv, i); return 1; } @@ -1762,7 +1754,7 @@ static void rtl8192_refresh_supportrate(struct r8192_priv* priv) memset(ieee->Regdot11HTOperationalRateSet, 0, 16); } -static u8 rtl8192_getSupportedWireleeMode(struct net_device *dev) +static u8 rtl8192_getSupportedWireleeMode(void) { return (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B); } @@ -1770,7 +1762,7 @@ static u8 rtl8192_getSupportedWireleeMode(struct net_device *dev) static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode) { struct r8192_priv *priv = ieee80211_priv(dev); - u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev); + u8 bSupportMode = rtl8192_getSupportedWireleeMode(); if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0)) { @@ -1889,9 +1881,8 @@ static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl) rtl8192_hw_sleep_down(dev); } -static void rtl8192_init_priv_variable(struct net_device* dev) +static void rtl8192_init_priv_variable(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); u8 i; PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; @@ -1920,7 +1911,7 @@ static void rtl8192_init_priv_variable(struct net_device* dev) priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD; priv->ieee80211->rate = 110; //11 mbps priv->ieee80211->short_slot = 1; - priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0; + priv->promisc = (priv->ieee80211->dev->flags & IFF_PROMISC) ? 1:0; priv->bcck_in_ch14 = false; priv->CCKPresentAttentuation = 0; priv->rfa_txpowertrackingindex = 0; @@ -2022,10 +2013,8 @@ static void rtl8192_init_priv_lock(struct r8192_priv* priv) /* init tasklet and wait_queue here */ #define DRV_NAME "wlan0" -static void rtl8192_init_priv_task(struct net_device* dev) +static void rtl8192_init_priv_task(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); - priv->priv_wq = create_workqueue(DRV_NAME); #ifdef ENABLE_IPS @@ -2048,10 +2037,9 @@ static void rtl8192_init_priv_task(struct net_device* dev) (unsigned long) priv); } -static void rtl8192_get_eeprom_size(struct net_device* dev) +static void rtl8192_get_eeprom_size(struct r8192_priv *priv) { u16 curCR = 0; - struct r8192_priv *priv = ieee80211_priv(dev); RT_TRACE(COMP_INIT, "===========>%s()\n", __FUNCTION__); curCR = read_nic_dword(priv, EPROM_CMD); RT_TRACE(COMP_INIT, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD, curCR); @@ -2441,9 +2429,8 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) } -static short rtl8192_get_channel_map(struct net_device * dev) +static short rtl8192_get_channel_map(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); #ifdef ENABLE_DOT11D if(priv->ChannelPlan> COUNTRY_CODE_GLOBAL_DOMAIN){ printk("rtl8180_init:Error channel plan! Set to default.\n"); @@ -2474,12 +2461,12 @@ static short rtl8192_init(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); memset(&(priv->stats),0,sizeof(struct Stats)); - rtl8192_init_priv_variable(dev); + rtl8192_init_priv_variable(priv); rtl8192_init_priv_lock(priv); - rtl8192_init_priv_task(dev); - rtl8192_get_eeprom_size(dev); + rtl8192_init_priv_task(priv); + rtl8192_get_eeprom_size(priv); rtl8192_read_eeprom_info(priv); - rtl8192_get_channel_map(dev); + rtl8192_get_channel_map(priv); init_hal_dm(dev); init_timer(&priv->watch_dog_timer); priv->watch_dog_timer.data = (unsigned long)dev; @@ -2491,7 +2478,7 @@ static short rtl8192_init(struct net_device *dev) priv->irq=dev->irq; printk("IRQ %d",dev->irq); } - if(rtl8192_pci_initdescring(dev)!=0){ + if (rtl8192_pci_initdescring(priv) != 0){ printk("Endopoints initialization failed"); return -1; } @@ -2576,9 +2563,9 @@ static void rtl8192_hwconfig(struct r8192_priv *priv) } -static RT_STATUS rtl8192_adapter_start(struct net_device *dev) +static RT_STATUS rtl8192_adapter_start(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); + struct net_device *dev = priv->ieee80211->dev; u32 ulRegRead; RT_STATUS rtStatus = RT_STATUS_SUCCESS; u8 tmpvalue; @@ -2907,7 +2894,7 @@ static void rtl8192_prepare_beacon(unsigned long arg) skb_push(skb, priv->ieee80211->tx_headroom); if(skb){ - rtl8192_tx(priv->ieee80211->dev,skb); + rtl8192_tx(priv, skb); } } @@ -2926,7 +2913,7 @@ static void rtl8192_start_beacon(struct net_device *dev) u16 BcnIFS = 0xf; DMESG("Enabling beacon TX"); - rtl8192_irq_disable(dev); + rtl8192_irq_disable(priv); //rtl8192_beacon_tx_enable(dev); /* ATIM window */ @@ -2964,9 +2951,8 @@ static void rtl8192_start_beacon(struct net_device *dev) rtl8192_irq_enable(priv); } -static bool HalRxCheckStuck8190Pci(struct net_device *dev) +static bool HalRxCheckStuck8190Pci(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); u16 RegRxCounter = read_nic_word(priv, 0x130); bool bStuck = FALSE; @@ -3024,10 +3010,10 @@ static bool HalRxCheckStuck8190Pci(struct net_device *dev) return bStuck; } -static RESET_TYPE RxCheckStuck(struct net_device *dev) +static RESET_TYPE RxCheckStuck(struct r8192_priv *priv) { - if(HalRxCheckStuck8190Pci(dev)) + if(HalRxCheckStuck8190Pci(priv)) { RT_TRACE(COMP_RESET, "RxStuck Condition\n"); return RESET_TYPE_SILENT; @@ -3037,9 +3023,8 @@ static RESET_TYPE RxCheckStuck(struct net_device *dev) } static RESET_TYPE -rtl819x_ifcheck_resetornot(struct net_device *dev) +rtl819x_ifcheck_resetornot(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); RESET_TYPE TxResetType = RESET_TYPE_NORESET; RESET_TYPE RxResetType = RESET_TYPE_NORESET; RT_RF_POWER_STATE rfState; @@ -3058,7 +3043,7 @@ rtl819x_ifcheck_resetornot(struct net_device *dev) // Driver should not check RX stuck in IBSS mode because it is required to // set Check BSSID in order to send beacon, however, if check BSSID is // set, STA cannot hear any packet a all. Emily, 2008.04.12 - RxResetType = RxCheckStuck(dev); + RxResetType = RxCheckStuck(priv); } RT_TRACE(COMP_RESET,"%s(): TxResetType is %d, RxResetType is %d\n",__FUNCTION__,TxResetType,RxResetType); @@ -3072,9 +3057,10 @@ rtl819x_ifcheck_resetornot(struct net_device *dev) } #ifdef ENABLE_IPS -void InactivePsWorkItemCallback(struct net_device *dev) +static void InactivePsWorkItemCallback(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); + struct net_device *dev = priv->ieee80211->dev; + PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() --------->\n"); @@ -3219,7 +3205,7 @@ IPSEnter(struct net_device *dev) RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n"); pPSC->eInactivePowerState = eRfOff; // queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem)); - InactivePsWorkItemCallback(dev); + InactivePsWorkItemCallback(priv); } } } @@ -3243,7 +3229,7 @@ IPSLeave(struct net_device *dev) { RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n"); pPSC->eInactivePowerState = eRfOn; - InactivePsWorkItemCallback(dev); + InactivePsWorkItemCallback(priv); } } } @@ -3315,7 +3301,7 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) { struct delayed_work *dwork = container_of(work,struct delayed_work,work); struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq); - struct net_device *dev = priv->ieee80211->dev; + struct net_device *dev = priv->ieee80211->dev; struct ieee80211_device* ieee = priv->ieee80211; RESET_TYPE ResetType = RESET_TYPE_NORESET; bool bBusyTraffic = false; @@ -3413,7 +3399,7 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) if (priv->watchdog_check_reset_cnt++ >= 3 && !ieee->is_roaming && priv->watchdog_last_time != 1) { - ResetType = rtl819x_ifcheck_resetornot(dev); + ResetType = rtl819x_ifcheck_resetornot(priv); priv->watchdog_check_reset_cnt = 3; } if(!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL) @@ -3446,16 +3432,17 @@ void watch_dog_timer_callback(unsigned long data) } -static int _rtl8192_up(struct net_device *dev) +static int _rtl8192_up(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); RT_STATUS init_status = RT_STATUS_SUCCESS; + struct net_device *dev = priv->ieee80211->dev; + priv->up=1; priv->ieee80211->ieee_up=1; priv->bdisable_nic = false; //YJ,add,091111 RT_TRACE(COMP_INIT, "Bringing up iface\n"); - init_status = rtl8192_adapter_start(dev); + init_status = rtl8192_adapter_start(priv); if(init_status != RT_STATUS_SUCCESS) { RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__); @@ -3498,7 +3485,7 @@ int rtl8192_up(struct net_device *dev) if (priv->up == 1) return -1; - return _rtl8192_up(dev); + return _rtl8192_up(priv); } @@ -3536,14 +3523,14 @@ int rtl8192_down(struct net_device *dev) if (!netif_queue_stopped(dev)) netif_stop_queue(dev); - rtl8192_irq_disable(dev); + rtl8192_irq_disable(priv); rtl8192_cancel_deferred_work(priv); deinit_hal_dm(dev); del_timer_sync(&priv->watch_dog_timer); ieee80211_softmac_stop_protocol(priv->ieee80211,true); - rtl8192_halt_adapter(dev,false); + rtl8192_halt_adapter(priv, false); memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list)); RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__); @@ -3552,28 +3539,25 @@ int rtl8192_down(struct net_device *dev) } -void rtl8192_commit(struct net_device *dev) +void rtl8192_commit(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); - if (priv->up == 0) return ; ieee80211_softmac_stop_protocol(priv->ieee80211,true); - rtl8192_irq_disable(dev); - rtl8192_halt_adapter(dev,true); - _rtl8192_up(dev); + rtl8192_irq_disable(priv); + rtl8192_halt_adapter(priv, true); + _rtl8192_up(priv); } static void rtl8192_restart(struct work_struct *work) { struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq); - struct net_device *dev = priv->ieee80211->dev; down(&priv->wx_sem); - rtl8192_commit(dev); + rtl8192_commit(priv); up(&priv->wx_sem); } @@ -4730,7 +4714,7 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, register_netdev(dev); RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name); - rtl8192_proc_init_one(dev); + rtl8192_proc_init_one(priv); RT_TRACE(COMP_INIT, "Driver probe completed\n"); @@ -4794,7 +4778,7 @@ static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev) priv = ieee80211_priv(dev); - rtl8192_proc_remove_one(dev); + rtl8192_proc_remove_one(priv); rtl8192_down(dev); if (priv->pFirmware) @@ -4805,9 +4789,9 @@ static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev) destroy_workqueue(priv->priv_wq); /* free tx/rx rings */ - rtl8192_free_rx_ring(dev); + rtl8192_free_rx_ring(priv); for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) - rtl8192_free_tx_ring(dev, i); + rtl8192_free_tx_ring(priv, i); if (priv->irq) { printk("Freeing irq %d\n",dev->irq); @@ -4895,26 +4879,26 @@ static irqreturn_t rtl8192_interrupt(int irq, void *netdev) if (inta & IMR_TBDOK) { RT_TRACE(COMP_INTR, "beacon ok interrupt!\n"); - rtl8192_tx_isr(dev, BEACON_QUEUE); + rtl8192_tx_isr(priv, BEACON_QUEUE); priv->stats.txbeaconokint++; } if (inta & IMR_TBDER) { RT_TRACE(COMP_INTR, "beacon ok interrupt!\n"); - rtl8192_tx_isr(dev, BEACON_QUEUE); + rtl8192_tx_isr(priv, BEACON_QUEUE); priv->stats.txbeaconerr++; } if (inta & IMR_MGNTDOK ) { RT_TRACE(COMP_INTR, "Manage ok interrupt!\n"); priv->stats.txmanageokint++; - rtl8192_tx_isr(dev,MGNT_QUEUE); + rtl8192_tx_isr(priv, MGNT_QUEUE); } if (inta & IMR_COMDOK) { priv->stats.txcmdpktokint++; - rtl8192_tx_isr(dev, TXCMD_QUEUE); + rtl8192_tx_isr(priv, TXCMD_QUEUE); } if (inta & IMR_ROK) { @@ -4948,27 +4932,27 @@ static irqreturn_t rtl8192_interrupt(int irq, void *netdev) RT_TRACE(COMP_INTR, "BK Tx OK interrupt!\n"); priv->stats.txbkokint++; priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; - rtl8192_tx_isr(dev, BK_QUEUE); + rtl8192_tx_isr(priv, BK_QUEUE); } if (inta & IMR_BEDOK) { RT_TRACE(COMP_INTR, "BE TX OK interrupt!\n"); priv->stats.txbeokint++; priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; - rtl8192_tx_isr(dev, BE_QUEUE); + rtl8192_tx_isr(priv, BE_QUEUE); } if (inta & IMR_VIDOK) { RT_TRACE(COMP_INTR, "VI TX OK interrupt!\n"); priv->stats.txviokint++; priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; - rtl8192_tx_isr(dev, VI_QUEUE); + rtl8192_tx_isr(priv, VI_QUEUE); } if (inta & IMR_VODOK) { priv->stats.txvookint++; priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; - rtl8192_tx_isr(dev, VO_QUEUE); + rtl8192_tx_isr(priv, VO_QUEUE); } out_unlock: @@ -5094,7 +5078,6 @@ void setKey( struct net_device *dev, bool NicIFEnableNIC(struct r8192_priv *priv) { RT_STATUS init_status = RT_STATUS_SUCCESS; - struct net_device *dev = priv->ieee80211->dev; PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; //YJ,add,091109 @@ -5108,7 +5091,7 @@ bool NicIFEnableNIC(struct r8192_priv *priv) // <2> Enable Adapter //priv->bfirst_init = true; - init_status = rtl8192_adapter_start(dev); + init_status = rtl8192_adapter_start(priv); if (init_status != RT_STATUS_SUCCESS) { RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__); priv->bdisable_nic = false; //YJ,add,091111 @@ -5127,7 +5110,6 @@ bool NicIFEnableNIC(struct r8192_priv *priv) bool NicIFDisableNIC(struct r8192_priv *priv) { bool status = true; - struct net_device *dev = priv->ieee80211->dev; u8 tmp_state = 0; // <1> Disable Interrupt @@ -5138,11 +5120,11 @@ bool NicIFDisableNIC(struct r8192_priv *priv) priv->ieee80211->state = tmp_state; rtl8192_cancel_deferred_work(priv); - rtl8192_irq_disable(dev); + rtl8192_irq_disable(priv); // <2> Stop all timer // <3> Disable Adapter - rtl8192_halt_adapter(dev, false); + rtl8192_halt_adapter(priv, false); // priv->bdisable_nic = true; return status; diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c index cf581c6e4840..57d97adf1259 100644 --- a/drivers/staging/rtl8192e/r8192E_wx.c +++ b/drivers/staging/rtl8192e/r8192E_wx.c @@ -770,7 +770,7 @@ static int r8192_wx_set_retry(struct net_device *dev, * I'm unsure if whole reset is really needed */ - rtl8192_commit(dev); + rtl8192_commit(priv); /* if(priv->up){ rtl8180_rtx_disable(dev); -- cgit v1.2.3 From 4fc2102522838b9933743fe38d22494efb1100da Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:45:54 +0900 Subject: staging: rtl8192e: Remove redundant function declarations Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_dm.c | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index 22bcc920ef40..bd352bad46da 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -38,38 +38,7 @@ dig_t dm_digtable; // For Dynamic Rx Path Selection by Signal Strength DRxPathSel DM_RxPathSelTable; - -/*--------------------Define export function prototype-----------------------*/ -extern void init_hal_dm(struct net_device *dev); -extern void deinit_hal_dm(struct net_device *dev); - -extern void hal_dm_watchdog(struct net_device *dev); - - -extern void init_rate_adaptive(struct net_device *dev); -extern void dm_txpower_trackingcallback(struct work_struct *work); - -extern void dm_cck_txpower_adjust(struct net_device *dev,bool binch14); -extern void dm_restore_dynamic_mechanism_state(struct net_device *dev); -extern void dm_backup_dynamic_mechanism_state(struct net_device *dev); -extern void dm_change_dynamic_initgain_thresh(struct net_device *dev, - u32 dm_type, - u32 dm_value); -extern void DM_ChangeFsyncSetting(struct net_device *dev, - s32 DM_Type, - s32 DM_Value); -extern void dm_force_tx_fw_info(struct net_device *dev, - u32 force_type, - u32 force_value); -extern void dm_init_edca_turbo(struct net_device *dev); -extern void dm_rf_operation_test_callback(unsigned long data); -extern void dm_rf_pathcheck_workitemcallback(struct work_struct *work); -extern void dm_fsync_timer_callback(unsigned long data); -extern void dm_check_fsync(struct net_device *dev); -extern void dm_initialize_txpower_tracking(struct net_device *dev); - -extern void dm_gpio_change_rf_callback(struct work_struct *work); - +void dm_gpio_change_rf_callback(struct work_struct *work); // DM --> Rate Adaptive static void dm_check_rate_adaptive(struct net_device *dev); -- cgit v1.2.3 From 7088dfb69877a07712d56bd9f3d2f48b4e7db30e Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:46:04 +0900 Subject: staging: rtl8192e: Pass r8192_priv around instead of net_device Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 1 - drivers/staging/rtl8192e/r8192E_core.c | 2 +- drivers/staging/rtl8192e/r8192E_dm.c | 330 +++++++++++++-------------------- drivers/staging/rtl8192e/r8192E_dm.h | 7 +- drivers/staging/rtl8192e/r819xE_phy.c | 18 +- 5 files changed, 143 insertions(+), 215 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 7cbf69be6fe1..1b838eea9aa8 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1062,7 +1062,6 @@ void write_phy(struct net_device *dev, u8 adr, u8 data); void CamResetAllEntry(struct r8192_priv *priv); void EnableHWSecurityConfig8192(struct net_device *dev); void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent ); -void dm_cck_txpower_adjust(struct net_device *dev, bool binch14); void firmware_init_param(struct net_device *dev); RT_STATUS cmpk_message_handle_tx(struct net_device *dev, u8* codevirtualaddress, u32 packettype, u32 buffer_len); diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index fb67e5f55f18..6ba1497b34c8 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -2832,7 +2832,7 @@ static RT_STATUS rtl8192_adapter_start(struct r8192_priv *priv) if(priv->ResetProgress == RESET_TYPE_NORESET) { - dm_initialize_txpower_tracking(dev); + dm_initialize_txpower_tracking(priv); if(priv->IC_Cut >= IC_VersionCut_D) { diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index bd352bad46da..208be7f858d3 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -41,54 +41,55 @@ DRxPathSel DM_RxPathSelTable; void dm_gpio_change_rf_callback(struct work_struct *work); // DM --> Rate Adaptive -static void dm_check_rate_adaptive(struct net_device *dev); +static void dm_check_rate_adaptive(struct r8192_priv *priv); // DM --> Bandwidth switch -static void dm_init_bandwidth_autoswitch(struct net_device *dev); -static void dm_bandwidth_autoswitch( struct net_device *dev); +static void dm_init_bandwidth_autoswitch(struct r8192_priv *priv); +static void dm_bandwidth_autoswitch(struct r8192_priv *priv); // DM --> TX power control -static void dm_check_txpower_tracking(struct net_device *dev); +static void dm_check_txpower_tracking(struct r8192_priv *priv); // DM --> Dynamic Init Gain by RSSI -static void dm_dig_init(struct net_device *dev); -static void dm_ctrl_initgain_byrssi(struct net_device *dev); -static void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev); -static void dm_ctrl_initgain_byrssi_by_driverrssi( struct net_device *dev); -static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct net_device *dev); -static void dm_initial_gain(struct net_device *dev); -static void dm_pd_th(struct net_device *dev); -static void dm_cs_ratio(struct net_device *dev); - -static void dm_init_ctstoself(struct net_device *dev); +static void dm_dig_init(struct r8192_priv *priv); +static void dm_ctrl_initgain_byrssi(struct r8192_priv *priv); +static void dm_ctrl_initgain_byrssi_highpwr(struct r8192_priv *priv); +static void dm_ctrl_initgain_byrssi_by_driverrssi(struct r8192_priv *priv); +static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct r8192_priv *priv); +static void dm_initial_gain(struct r8192_priv *priv); +static void dm_pd_th(struct r8192_priv *priv); +static void dm_cs_ratio(struct r8192_priv *priv); + +static void dm_init_ctstoself(struct r8192_priv *priv); // DM --> EDCA turboe mode control -static void dm_check_edca_turbo(struct net_device *dev); +static void dm_check_edca_turbo(struct r8192_priv *priv); +static void dm_init_edca_turbo(struct r8192_priv *priv); // DM --> HW RF control -static void dm_check_rfctrl_gpio(struct net_device *dev); - -// DM --> Check PBC -static void dm_check_pbc_gpio(struct net_device *dev); +static void dm_check_rfctrl_gpio(struct r8192_priv *priv); // DM --> Check current RX RF path state -static void dm_check_rx_path_selection(struct net_device *dev); -static void dm_init_rxpath_selection(struct net_device *dev); -static void dm_rxpath_sel_byrssi(struct net_device *dev); +static void dm_check_rx_path_selection(struct r8192_priv *priv); +static void dm_init_rxpath_selection(struct r8192_priv *priv); +static void dm_rxpath_sel_byrssi(struct r8192_priv *priv); // DM --> Fsync for broadcom ap -static void dm_init_fsync(struct net_device *dev); -static void dm_deInit_fsync(struct net_device *dev); +static void dm_init_fsync(struct r8192_priv *priv); +static void dm_deInit_fsync(struct r8192_priv *priv); -static void dm_check_txrateandretrycount(struct net_device *dev); +static void dm_check_txrateandretrycount(struct r8192_priv *priv); +static void dm_check_fsync(struct r8192_priv *priv); /*---------------------Define of Tx Power Control For Near/Far Range --------*/ //Add by Jacken 2008/02/18 -static void dm_init_dynamic_txpower(struct net_device *dev); -static void dm_dynamic_txpower(struct net_device *dev); +static void dm_init_dynamic_txpower(struct r8192_priv *priv); +static void dm_dynamic_txpower(struct r8192_priv *priv); // DM --> For rate adaptive and DIG, we must send RSSI to firmware -static void dm_send_rssi_tofw(struct net_device *dev); -static void dm_ctstoself(struct net_device *dev); +static void dm_send_rssi_tofw(struct r8192_priv *priv); +static void dm_ctstoself(struct r8192_priv *priv); + +static void dm_fsync_timer_callback(unsigned long data); /* * Prepare SW resource for HW dynamic mechanism. @@ -102,47 +103,48 @@ void init_hal_dm(struct net_device *dev) priv->undecorated_smoothed_pwdb = -1; //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. - dm_init_dynamic_txpower(dev); + dm_init_dynamic_txpower(priv); init_rate_adaptive(dev); //dm_initialize_txpower_tracking(dev); - dm_dig_init(dev); - dm_init_edca_turbo(dev); - dm_init_bandwidth_autoswitch(dev); - dm_init_fsync(dev); - dm_init_rxpath_selection(dev); - dm_init_ctstoself(dev); + dm_dig_init(priv); + dm_init_edca_turbo(priv); + dm_init_bandwidth_autoswitch(priv); + dm_init_fsync(priv); + dm_init_rxpath_selection(priv); + dm_init_ctstoself(priv); INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, dm_gpio_change_rf_callback); } void deinit_hal_dm(struct net_device *dev) { + struct r8192_priv *priv = ieee80211_priv(dev); - dm_deInit_fsync(dev); - + dm_deInit_fsync(priv); } void hal_dm_watchdog(struct net_device *dev) { + struct r8192_priv *priv = ieee80211_priv(dev); + /*Add by amy 2008/05/15 ,porting from windows code.*/ - dm_check_rate_adaptive(dev); - dm_dynamic_txpower(dev); - dm_check_txrateandretrycount(dev); + dm_check_rate_adaptive(priv); + dm_dynamic_txpower(priv); + dm_check_txrateandretrycount(priv); - dm_check_txpower_tracking(dev); + dm_check_txpower_tracking(priv); - dm_ctrl_initgain_byrssi(dev); - dm_check_edca_turbo(dev); - dm_bandwidth_autoswitch(dev); + dm_ctrl_initgain_byrssi(priv); + dm_check_edca_turbo(priv); + dm_bandwidth_autoswitch(priv); - dm_check_rfctrl_gpio(dev); - dm_check_rx_path_selection(dev); - dm_check_fsync(dev); + dm_check_rfctrl_gpio(priv); + dm_check_rx_path_selection(priv); + dm_check_fsync(priv); // Add by amy 2008-05-15 porting from windows code. - dm_check_pbc_gpio(dev); - dm_send_rssi_tofw(dev); - dm_ctstoself(dev); + dm_send_rssi_tofw(priv); + dm_ctstoself(priv); } @@ -198,9 +200,8 @@ void init_rate_adaptive(struct net_device * dev) } -static void dm_check_rate_adaptive(struct net_device * dev) +static void dm_check_rate_adaptive(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo; prate_adaptive pra = (prate_adaptive)&priv->rate_adaptive; u32 currentRATR, targetRATR = 0; @@ -312,7 +313,7 @@ static void dm_check_rate_adaptive(struct net_device * dev) } // For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7. - if(priv->ieee80211->GetHalfNmodeSupportByAPsHandler(dev)) + if(priv->ieee80211->GetHalfNmodeSupportByAPsHandler(priv->ieee80211->dev)) targetRATR &= 0xf00fffff; // @@ -343,10 +344,8 @@ static void dm_check_rate_adaptive(struct net_device * dev) } -static void dm_init_bandwidth_autoswitch(struct net_device * dev) +static void dm_init_bandwidth_autoswitch(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); - priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH; priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW; priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false; @@ -355,10 +354,8 @@ static void dm_init_bandwidth_autoswitch(struct net_device * dev) } -static void dm_bandwidth_autoswitch(struct net_device * dev) +static void dm_bandwidth_autoswitch(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); - if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ||!priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable){ return; }else{ @@ -430,9 +427,9 @@ static const u8 CCKSwingTable_Ch14[CCK_Table_length][8] = { #define Tssi_Report_Value1 0x134 #define Tssi_Report_Value2 0x13e #define FW_Busy_Flag 0x13f -static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) - { - struct r8192_priv *priv = ieee80211_priv(dev); +static void dm_TXPowerTrackingCallback_TSSI(struct r8192_priv *priv) +{ + struct net_device *dev = priv->ieee80211->dev; bool bHighpowerstate, viviflag = FALSE; DCMD_TXCMD_T tx_cmd; u8 powerlevelOFDM24G; @@ -641,15 +638,15 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) { priv->bcck_in_ch14 = TRUE; - dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); + dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); } else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) { priv->bcck_in_ch14 = FALSE; - dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); + dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); } else - dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); + dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); } RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex); RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real); @@ -679,10 +676,9 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) write_nic_byte(priv, Pw_Track_Flag, 0); } -static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev) +static void dm_TXPowerTrackingCallback_ThermalMeter(struct r8192_priv *priv) { #define ThermalMeterVal 9 - struct r8192_priv *priv = ieee80211_priv(dev); u32 tmpRegA, TempCCk; u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval; int i =0, CCKSwingNeedUpdate=0; @@ -781,7 +777,7 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev) if(CCKSwingNeedUpdate) { - dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); + dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); } if(priv->OFDM_index != tmpOFDMindex) { @@ -796,13 +792,12 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev) void dm_txpower_trackingcallback(struct work_struct *work) { struct delayed_work *dwork = container_of(work,struct delayed_work,work); - struct r8192_priv *priv = container_of(dwork,struct r8192_priv,txpower_tracking_wq); - struct net_device *dev = priv->ieee80211->dev; + struct r8192_priv *priv = container_of(dwork,struct r8192_priv,txpower_tracking_wq); if(priv->IC_Cut >= IC_VersionCut_D) - dm_TXPowerTrackingCallback_TSSI(dev); + dm_TXPowerTrackingCallback_TSSI(priv); else - dm_TXPowerTrackingCallback_ThermalMeter(dev); + dm_TXPowerTrackingCallback_ThermalMeter(priv); } @@ -906,10 +901,8 @@ static const ccktxbbgain_struct rtl8192_cck_txbbgain_ch14_table[] = { {{ 0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00 }}, }; -static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev) +static void dm_InitializeTXPowerTracking_TSSI(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); - priv->txbbgain_table = rtl8192_txbbgain_table; priv->cck_txbbgain_table = rtl8192_cck_txbbgain_table; priv->cck_txbbgain_ch14_table = rtl8192_cck_txbbgain_ch14_table; @@ -920,10 +913,8 @@ static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev) } -static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev) +static void dm_InitializeTXPowerTracking_ThermalMeter(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); - // Tx Power tracking by Theremal Meter require Firmware R/W 3-wire. This mechanism // can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w // 3-wire by driver cause RF goes into wrong state. @@ -935,20 +926,17 @@ static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev) priv->btxpower_trackingInit = FALSE; } -void dm_initialize_txpower_tracking(struct net_device *dev) +void dm_initialize_txpower_tracking(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); - if(priv->IC_Cut >= IC_VersionCut_D) - dm_InitializeTXPowerTracking_TSSI(dev); + dm_InitializeTXPowerTracking_TSSI(priv); else - dm_InitializeTXPowerTracking_ThermalMeter(dev); + dm_InitializeTXPowerTracking_ThermalMeter(priv); } -static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev) +static void dm_CheckTXPowerTracking_TSSI(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); static u32 tx_power_track_counter = 0; RT_TRACE(COMP_POWER_TRACKING,"%s()\n",__FUNCTION__); if(read_nic_byte(priv, 0x11e) ==1) @@ -963,9 +951,8 @@ static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev) } } -static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev) +static void dm_CheckTXPowerTracking_ThermalMeter(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); static u8 TM_Trigger=0; if(!priv->btxpower_tracking) @@ -996,21 +983,18 @@ static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev) } } -static void dm_check_txpower_tracking(struct net_device *dev) +static void dm_check_txpower_tracking(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); - if(priv->IC_Cut >= IC_VersionCut_D) - dm_CheckTXPowerTracking_TSSI(dev); + dm_CheckTXPowerTracking_TSSI(priv); else - dm_CheckTXPowerTracking_ThermalMeter(dev); + dm_CheckTXPowerTracking_ThermalMeter(priv); } -static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14) +static void dm_CCKTxPowerAdjust_TSSI(struct r8192_priv *priv, bool bInCH14) { u32 TempVal; - struct r8192_priv *priv = ieee80211_priv(dev); //Write 0xa22 0xa23 TempVal = 0; if(!bInCH14){ @@ -1057,10 +1041,10 @@ static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14) } -static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH14) +static void dm_CCKTxPowerAdjust_ThermalMeter(struct r8192_priv *priv, + bool bInCH14) { u32 TempVal; - struct r8192_priv *priv = ieee80211_priv(dev); TempVal = 0; if(!bInCH14) @@ -1119,14 +1103,12 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH } } -void dm_cck_txpower_adjust(struct net_device *dev, bool binch14) +void dm_cck_txpower_adjust(struct r8192_priv *priv, bool binch14) { - struct r8192_priv *priv = ieee80211_priv(dev); - if(priv->IC_Cut >= IC_VersionCut_D) - dm_CCKTxPowerAdjust_TSSI(dev, binch14); + dm_CCKTxPowerAdjust_TSSI(priv, binch14); else - dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14); + dm_CCKTxPowerAdjust_ThermalMeter(priv, binch14); } @@ -1200,9 +1182,8 @@ void dm_change_dynamic_initgain_thresh(struct net_device *dev, u32 dm_type, u32 /* Set DIG scheme init value. */ -static void dm_dig_init(struct net_device *dev) +static void dm_dig_init(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); /* 2007/10/05 MH Disable DIG scheme now. Not tested. */ dm_digtable.dig_enable_flag = true; dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI; @@ -1236,23 +1217,20 @@ static void dm_dig_init(struct net_device *dev) * gain according to different threshold. BB team provide the * suggested solution. */ -static void dm_ctrl_initgain_byrssi(struct net_device *dev) +static void dm_ctrl_initgain_byrssi(struct r8192_priv *priv) { - if (dm_digtable.dig_enable_flag == false) return; if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) - dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev); + dm_ctrl_initgain_byrssi_by_fwfalse_alarm(priv); else if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) - dm_ctrl_initgain_byrssi_by_driverrssi(dev); + dm_ctrl_initgain_byrssi_by_driverrssi(priv); } -static void dm_ctrl_initgain_byrssi_by_driverrssi( - struct net_device *dev) +static void dm_ctrl_initgain_byrssi_by_driverrssi(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); u8 i; static u8 fw_dig=0; @@ -1277,19 +1255,17 @@ static void dm_ctrl_initgain_byrssi_by_driverrssi( if(dm_digtable.dbg_mode == DM_DBG_OFF) dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb; - dm_initial_gain(dev); - dm_pd_th(dev); - dm_cs_ratio(dev); + dm_initial_gain(priv); + dm_pd_th(priv); + dm_cs_ratio(priv); if(dm_digtable.dig_algorithm_switch) dm_digtable.dig_algorithm_switch = 0; dm_digtable.pre_connect_state = dm_digtable.cur_connect_state; } -static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( - struct net_device *dev) +static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); static u32 reset_cnt = 0; u8 i; @@ -1372,7 +1348,7 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( if (dm_digtable.dig_state == DM_STA_DIG_ON && (priv->reset_count == reset_cnt)) { - dm_ctrl_initgain_byrssi_highpwr(dev); + dm_ctrl_initgain_byrssi_highpwr(priv); return; } else @@ -1424,14 +1400,12 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( } - dm_ctrl_initgain_byrssi_highpwr(dev); + dm_ctrl_initgain_byrssi_highpwr(priv); } -static void dm_ctrl_initgain_byrssi_highpwr( - struct net_device * dev) +static void dm_ctrl_initgain_byrssi_highpwr(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); static u32 reset_cnt_highpwr = 0; // For smooth, we can not change high power DIG state in the range. @@ -1486,10 +1460,8 @@ static void dm_ctrl_initgain_byrssi_highpwr( } -static void dm_initial_gain( - struct net_device * dev) +static void dm_initial_gain(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); u8 initial_gain=0; static u8 initialized=0, force_write=0; static u32 reset_cnt=0; @@ -1552,10 +1524,8 @@ static void dm_initial_gain( } } -static void dm_pd_th( - struct net_device * dev) +static void dm_pd_th(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); static u8 initialized=0, force_write=0; static u32 reset_cnt = 0; @@ -1642,10 +1612,8 @@ static void dm_pd_th( } } -static void dm_cs_ratio( - struct net_device * dev) +static void dm_cs_ratio(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); static u8 initialized=0,force_write=0; static u32 reset_cnt = 0; @@ -1703,19 +1671,16 @@ static void dm_cs_ratio( } } -void dm_init_edca_turbo(struct net_device *dev) +void dm_init_edca_turbo(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); priv->bcurrent_turbo_EDCA = false; priv->ieee80211->bis_any_nonbepkts = false; priv->bis_cur_rdlstate = false; } -static void dm_check_edca_turbo( - struct net_device * dev) +static void dm_check_edca_turbo(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo; //PSTA_QOS pStaQos = pMgntInfo->pStaQos; @@ -1777,7 +1742,7 @@ static void dm_check_edca_turbo( u8 mode = priv->ieee80211->mode; // For Each time updating EDCA parameter, reset EDCA turbo mode status. - dm_init_edca_turbo(dev); + dm_init_edca_turbo(priv); u1bAIFS = qos_parameters->aifs[0] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime; u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[0]))<< AC_PARAM_TXOP_LIMIT_OFFSET)| (((u32)(qos_parameters->cw_max[0]))<< AC_PARAM_ECW_MAX_OFFSET)| @@ -1819,17 +1784,14 @@ dm_CheckEdcaTurbo_EXIT: lastRxOkCnt = priv->stats.rxbytesunicast; } -static void dm_init_ctstoself(struct net_device * dev) +static void dm_init_ctstoself(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev); - priv->ieee80211->bCTSToSelfEnable = TRUE; priv->ieee80211->CTSToSelfTH = CTSToSelfTHVal; } -static void dm_ctstoself(struct net_device *dev) +static void dm_ctstoself(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev); PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo; static unsigned long lastTxOkCnt = 0; static unsigned long lastRxOkCnt = 0; @@ -1868,9 +1830,8 @@ static void dm_ctstoself(struct net_device *dev) /* Copy 8187B template for 9xseries */ -static void dm_check_rfctrl_gpio(struct net_device * dev) +static void dm_check_rfctrl_gpio(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); // Walk around for DTM test, we will not enable HW - radio on/off because r/w // page 1 register before Lextra bus is enabled cause system fails when resuming @@ -1880,11 +1841,6 @@ static void dm_check_rfctrl_gpio(struct net_device * dev) queue_delayed_work(priv->priv_wq,&priv->gpio_change_rf_wq,0); } -/* Check if PBC button is pressed. */ -static void dm_check_pbc_gpio(struct net_device *dev) -{ -} - /* PCI will not support workitem call back HW radio on-off control. */ void dm_gpio_change_rf_callback(struct work_struct *work) { @@ -1930,8 +1886,6 @@ void dm_rf_pathcheck_workitemcallback(struct work_struct *work) { struct delayed_work *dwork = container_of(work,struct delayed_work,work); struct r8192_priv *priv = container_of(dwork,struct r8192_priv,rfpath_check_wq); - struct net_device *dev =priv->ieee80211->dev; - //bool bactually_set = false; u8 rfpath = 0, i; @@ -1950,13 +1904,13 @@ void dm_rf_pathcheck_workitemcallback(struct work_struct *work) if(!DM_RxPathSelTable.Enable) return; - dm_rxpath_sel_byrssi(dev); + dm_rxpath_sel_byrssi(priv); } -static void dm_init_rxpath_selection(struct net_device * dev) +static void dm_init_rxpath_selection(struct r8192_priv *priv) { u8 i; - struct r8192_priv *priv = ieee80211_priv(dev); + DM_RxPathSelTable.Enable = 1; //default enabled DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low; DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH; @@ -1974,9 +1928,8 @@ static void dm_init_rxpath_selection(struct net_device * dev) } } -static void dm_rxpath_sel_byrssi(struct net_device * dev) +static void dm_rxpath_sel_byrssi(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); u8 i, max_rssi_index=0, min_rssi_index=0, sec_rssi_index=0, rf_num=0; u8 tmp_max_rssi=0, tmp_min_rssi=0, tmp_sec_rssi=0; u8 cck_default_Rx=0x2; //RF-C @@ -2237,16 +2190,13 @@ static void dm_rxpath_sel_byrssi(struct net_device * dev) /* * Call a workitem to check current RXRF path and Rx Path selection by RSSI. */ -static void dm_check_rx_path_selection(struct net_device *dev) +static void dm_check_rx_path_selection(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); queue_delayed_work(priv->priv_wq,&priv->rfpath_check_wq,0); } -static void dm_init_fsync (struct net_device *dev) +static void dm_init_fsync(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); - priv->ieee80211->fsync_time_interval = 500; priv->ieee80211->fsync_rate_bitmap = 0x0f000800; priv->ieee80211->fsync_rssi_threshold = 30; @@ -2258,20 +2208,19 @@ static void dm_init_fsync (struct net_device *dev) priv->framesyncMonitor = 1; // current default 0xc38 monitor on init_timer(&priv->fsync_timer); - priv->fsync_timer.data = (unsigned long)dev; + priv->fsync_timer.data = (unsigned long)priv; priv->fsync_timer.function = dm_fsync_timer_callback; } -static void dm_deInit_fsync(struct net_device *dev) +static void dm_deInit_fsync(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); del_timer_sync(&priv->fsync_timer); } -void dm_fsync_timer_callback(unsigned long data) +static void dm_fsync_timer_callback(unsigned long data) { - struct r8192_priv *priv = ieee80211_priv((struct net_device *)data); + struct r8192_priv *priv = (struct r8192_priv *)data; u32 rate_index, rate_count = 0, rate_count_diff=0; bool bSwitchFromCountDiff = false; bool bDoubleTimeInterval = false; @@ -2379,19 +2328,15 @@ void dm_fsync_timer_callback(unsigned long data) RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync); } -static void dm_StartHWFsync(struct net_device *dev) +static void dm_StartHWFsync(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); - RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__); write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c12cf); write_nic_byte(priv, 0xc3b, 0x41); } -static void dm_EndSWFsync(struct net_device *dev) +static void dm_EndSWFsync(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); - RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__); del_timer_sync(&(priv->fsync_timer)); @@ -2410,9 +2355,8 @@ static void dm_EndSWFsync(struct net_device *dev) write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd); } -static void dm_StartSWFsync(struct net_device *dev) +static void dm_StartSWFsync(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); u32 rateIndex; u32 rateBitmap; @@ -2448,21 +2392,18 @@ static void dm_StartSWFsync(struct net_device *dev) write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c12cd); } -static void dm_EndHWFsync(struct net_device *dev) +static void dm_EndHWFsync(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); - RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__); write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd); write_nic_byte(priv, 0xc3b, 0x49); } -void dm_check_fsync(struct net_device *dev) +static void dm_check_fsync(struct r8192_priv *priv) { #define RegC38_Default 0 #define RegC38_NonFsync_Other_AP 1 #define RegC38_Fsync_AP_BCM 2 - struct r8192_priv *priv = ieee80211_priv(dev); //u32 framesyncC34; static u8 reg_c38_State=RegC38_Default; static u32 reset_cnt=0; @@ -2478,12 +2419,12 @@ void dm_check_fsync(struct net_device *dev) switch(priv->ieee80211->fsync_state) { case Default_Fsync: - dm_StartHWFsync(dev); + dm_StartHWFsync(priv); priv->ieee80211->fsync_state = HW_Fsync; break; case SW_Fsync: - dm_EndSWFsync(dev); - dm_StartHWFsync(dev); + dm_EndSWFsync(priv); + dm_StartHWFsync(priv); priv->ieee80211->fsync_state = HW_Fsync; break; case HW_Fsync: @@ -2496,12 +2437,12 @@ void dm_check_fsync(struct net_device *dev) switch(priv->ieee80211->fsync_state) { case Default_Fsync: - dm_StartSWFsync(dev); + dm_StartSWFsync(priv); priv->ieee80211->fsync_state = SW_Fsync; break; case HW_Fsync: - dm_EndHWFsync(dev); - dm_StartSWFsync(dev); + dm_EndHWFsync(priv); + dm_StartSWFsync(priv); priv->ieee80211->fsync_state = SW_Fsync; break; case SW_Fsync: @@ -2525,11 +2466,11 @@ void dm_check_fsync(struct net_device *dev) switch(priv->ieee80211->fsync_state) { case HW_Fsync: - dm_EndHWFsync(dev); + dm_EndHWFsync(priv); priv->ieee80211->fsync_state = Default_Fsync; break; case SW_Fsync: - dm_EndSWFsync(dev); + dm_EndSWFsync(priv); priv->ieee80211->fsync_state = Default_Fsync; break; case Default_Fsync: @@ -2592,10 +2533,8 @@ void dm_check_fsync(struct net_device *dev) * Detect Signal strength to control TX Registry * Tx Power Control For Near/Far Range */ -static void dm_init_dynamic_txpower(struct net_device *dev) +static void dm_init_dynamic_txpower(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); - //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. priv->ieee80211->bdynamic_txpower_enable = true; //Default to enable Tx Power Control priv->bLastDTPFlag_High = false; @@ -2604,9 +2543,8 @@ static void dm_init_dynamic_txpower(struct net_device *dev) priv->bDynamicTxLowPower = false; } -static void dm_dynamic_txpower(struct net_device *dev) +static void dm_dynamic_txpower(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); unsigned int txhipower_threshhold=0; unsigned int txlowpower_threshold=0; if(priv->ieee80211->bdynamic_txpower_enable != true) @@ -2674,20 +2612,18 @@ static void dm_dynamic_txpower(struct net_device *dev) } //added by vivi, for read tx rate and retrycount -static void dm_check_txrateandretrycount(struct net_device * dev) +static void dm_check_txrateandretrycount(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); struct ieee80211_device* ieee = priv->ieee80211; + //for initial tx rate ieee->softmac_stats.last_packet_rate = read_nic_byte(priv ,Initial_Tx_Rate_Reg); //for tx tx retry count ieee->softmac_stats.txretrycount = read_nic_dword(priv, Tx_Retry_Count_Reg); } -static void dm_send_rssi_tofw(struct net_device *dev) +static void dm_send_rssi_tofw(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); - // If we test chariot, we should stop the TX command ? // Because 92E will always silent reset when we send tx command. We use register // 0x1e0(byte) to botify driver. diff --git a/drivers/staging/rtl8192e/r8192E_dm.h b/drivers/staging/rtl8192e/r8192E_dm.h index 2ca9333d8773..16dcb033a9eb 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.h +++ b/drivers/staging/rtl8192e/r8192E_dm.h @@ -219,7 +219,6 @@ void hal_dm_watchdog(struct net_device *dev); void init_rate_adaptive(struct net_device *dev); void dm_txpower_trackingcallback(struct work_struct *work); -void dm_cck_txpower_adjust(struct net_device *dev,bool binch14); void dm_restore_dynamic_mechanism_state(struct net_device *dev); void dm_backup_dynamic_mechanism_state(struct net_device *dev); void dm_change_dynamic_initgain_thresh(struct net_device *dev, u32 dm_type, @@ -227,12 +226,10 @@ void dm_change_dynamic_initgain_thresh(struct net_device *dev, u32 dm_type, void DM_ChangeFsyncSetting(struct net_device *dev, s32 DM_Type, s32 DM_Value); void dm_force_tx_fw_info(struct net_device *dev, u32 force_type, u32 force_value); -void dm_init_edca_turbo(struct net_device *dev); void dm_rf_operation_test_callback(unsigned long data); void dm_rf_pathcheck_workitemcallback(struct work_struct *work); -void dm_fsync_timer_callback(unsigned long data); -void dm_check_fsync(struct net_device *dev); -void dm_initialize_txpower_tracking(struct net_device *dev); +void dm_initialize_txpower_tracking(struct r8192_priv *priv); +void dm_cck_txpower_adjust(struct r8192_priv *priv, bool binch14); #endif /*__R8192UDM_H__ */ diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c index e8a8b3424f32..1688997d3469 100644 --- a/drivers/staging/rtl8192e/r819xE_phy.c +++ b/drivers/staging/rtl8192e/r819xE_phy.c @@ -1907,8 +1907,6 @@ u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel) static void CCK_Tx_Power_Track_BW_Switch_TSSI(struct r8192_priv *priv) { - struct net_device *dev = priv->ieee80211->dev; - switch(priv->CurrentChannelBW) { /* 20 MHz channel*/ @@ -1927,15 +1925,15 @@ static void CCK_Tx_Power_Track_BW_Switch_TSSI(struct r8192_priv *priv) if(priv->ieee80211->current_network.channel== 14 && !priv->bcck_in_ch14) { priv->bcck_in_ch14 = TRUE; - dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); + dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); } else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) { priv->bcck_in_ch14 = FALSE; - dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); + dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); } else - dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); + dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); break; /* 40 MHz channel*/ @@ -1953,23 +1951,21 @@ static void CCK_Tx_Power_Track_BW_Switch_TSSI(struct r8192_priv *priv) if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) { priv->bcck_in_ch14 = TRUE; - dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); + dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); } else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) { priv->bcck_in_ch14 = FALSE; - dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); + dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); } else - dm_cck_txpower_adjust(dev,priv->bcck_in_ch14); + dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); break; } } static void CCK_Tx_Power_Track_BW_Switch_ThermalMeter(struct r8192_priv *priv) { - struct net_device *dev = priv->ieee80211->dev; - if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) priv->bcck_in_ch14 = TRUE; else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) @@ -1992,7 +1988,7 @@ static void CCK_Tx_Power_Track_BW_Switch_ThermalMeter(struct r8192_priv *priv) RT_TRACE(COMP_POWER_TRACKING, "40MHz, CCK_Tx_Power_Track_BW_Switch_ThermalMeter(), CCK_index = %d\n", priv->CCK_index); break; } - dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); + dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); } static void CCK_Tx_Power_Track_BW_Switch(struct r8192_priv *priv) -- cgit v1.2.3 From 262cd816029fb0e6e257c48d86582914a4831d3f Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:46:17 +0900 Subject: staging: rtl8192e: Pass r8192_priv to MgntActSet_RF_State Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8190_rtl8256.c | 9 ++------- drivers/staging/rtl8192e/r8190_rtl8256.h | 6 +++--- drivers/staging/rtl8192e/r8192E_core.c | 16 ++++++++-------- drivers/staging/rtl8192e/r8192E_dm.c | 3 +-- drivers/staging/rtl8192e/r8192_pm.c | 2 +- 5 files changed, 15 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index 8861aebe4fe8..286462cc819c 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -604,14 +604,9 @@ static bool MgntDisconnect(struct r8192_priv *priv, u8 asRsn) // Assumption: // PASSIVE LEVEL. // -bool -MgntActSet_RF_State( - struct net_device* dev, - RT_RF_POWER_STATE StateToSet, - RT_RF_CHANGE_SOURCE ChangeSource - ) +bool MgntActSet_RF_State(struct r8192_priv *priv, RT_RF_POWER_STATE StateToSet, + RT_RF_CHANGE_SOURCE ChangeSource) { - struct r8192_priv *priv = ieee80211_priv(dev); bool bActionAllowed = false; bool bConnectBySSID = false; RT_RF_POWER_STATE rtState; diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.h b/drivers/staging/rtl8192e/r8190_rtl8256.h index e3297ecb37f4..58f92903fca4 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.h +++ b/drivers/staging/rtl8192e/r8190_rtl8256.h @@ -22,8 +22,8 @@ RT_STATUS phy_RF8256_Config_ParaFile(struct r8192_priv *priv); void PHY_SetRF8256CCKTxPower(struct r8192_priv *priv, u8 powerlevel); void PHY_SetRF8256OFDMTxPower(struct r8192_priv *priv, u8 powerlevel); -bool MgntActSet_RF_State(struct net_device *dev, - RT_RF_POWER_STATE StateToSet, - RT_RF_CHANGE_SOURCE ChangeSource); +bool MgntActSet_RF_State(struct r8192_priv *priv, + RT_RF_POWER_STATE StateToSet, + RT_RF_CHANGE_SOURCE ChangeSource); #endif /* RTL8225_H */ diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 6ba1497b34c8..721e81a35bc5 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1827,12 +1827,14 @@ static short rtl8192_is_tx_queue_empty(struct net_device *dev) static void rtl8192_hw_sleep_down(struct net_device *dev) { - MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS); + struct r8192_priv *priv = ieee80211_priv(dev); + MgntActSet_RF_State(priv, eRfSleep, RF_CHANGE_BY_PS); } static void rtl8192_hw_wakeup(struct net_device* dev) { - MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS); + struct r8192_priv *priv = ieee80211_priv(dev); + MgntActSet_RF_State(priv, eRfOn, RF_CHANGE_BY_PS); } static void rtl8192_hw_wakeup_wq (struct work_struct *work) @@ -2809,12 +2811,12 @@ static RT_STATUS rtl8192_adapter_start(struct r8192_priv *priv) if(priv->RfOffReason > RF_CHANGE_BY_PS) { // H/W or S/W RF OFF before sleep. RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d)\n", __FUNCTION__,priv->RfOffReason); - MgntActSet_RF_State(dev, eRfOff, priv->RfOffReason); + MgntActSet_RF_State(priv, eRfOff, priv->RfOffReason); } else if(priv->RfOffReason >= RF_CHANGE_BY_IPS) { // H/W or S/W RF OFF before sleep. RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d)\n", __FUNCTION__, priv->RfOffReason); - MgntActSet_RF_State(dev, eRfOff, priv->RfOffReason); + MgntActSet_RF_State(priv, eRfOff, priv->RfOffReason); } else { @@ -3059,8 +3061,6 @@ rtl819x_ifcheck_resetornot(struct r8192_priv *priv) #ifdef ENABLE_IPS static void InactivePsWorkItemCallback(struct r8192_priv *priv) { - struct net_device *dev = priv->ieee80211->dev; - PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() --------->\n"); @@ -3078,7 +3078,7 @@ static void InactivePsWorkItemCallback(struct r8192_priv *priv) pPSC->eInactivePowerState == eRfOff?"OFF":"ON"); - MgntActSet_RF_State(dev, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS); + MgntActSet_RF_State(priv, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS); // // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20. @@ -3451,7 +3451,7 @@ static int _rtl8192_up(struct r8192_priv *priv) RT_TRACE(COMP_INIT, "start adapter finished\n"); if (priv->eRFPowerState != eRfOn) - MgntActSet_RF_State(dev, eRfOn, priv->RfOffReason); + MgntActSet_RF_State(priv, eRfOn, priv->RfOffReason); if(priv->ieee80211->state != IEEE80211_LINKED) ieee80211_softmac_start_protocol(priv->ieee80211); diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index 208be7f858d3..50e276f8f34b 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -1846,7 +1846,6 @@ void dm_gpio_change_rf_callback(struct work_struct *work) { struct delayed_work *dwork = container_of(work,struct delayed_work,work); struct r8192_priv *priv = container_of(dwork,struct r8192_priv,gpio_change_rf_wq); - struct net_device *dev = priv->ieee80211->dev; u8 tmp1byte; RT_RF_POWER_STATE eRfPowerStateToSet; bool bActuallySet = false; @@ -1873,7 +1872,7 @@ void dm_gpio_change_rf_callback(struct work_struct *work) if (bActuallySet) { priv->bHwRfOffAction = 1; - MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW); + MgntActSet_RF_State(priv, eRfPowerStateToSet, RF_CHANGE_BY_HW); //DrvIFIndicateCurrentPhyStatus(pAdapter); } else { msleep(2000); diff --git a/drivers/staging/rtl8192e/r8192_pm.c b/drivers/staging/rtl8192e/r8192_pm.c index a762c2c188a0..7bcc4a350991 100644 --- a/drivers/staging/rtl8192e/r8192_pm.c +++ b/drivers/staging/rtl8192e/r8192_pm.c @@ -36,7 +36,7 @@ int rtl8192E_suspend (struct pci_dev *pdev, pm_message_t state) // Call MgntActSet_RF_State instead to prevent RF config race condition. if(!priv->ieee80211->bSupportRemoteWakeUp) { - MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT); + MgntActSet_RF_State(priv, eRfOff, RF_CHANGE_BY_INIT); // 2006.11.30. System reset bit ulRegRead = read_nic_dword(priv, CPU_GEN); ulRegRead|=CPU_GEN_SYSTEM_RESET; -- cgit v1.2.3 From c9c0a1e7d9df0bd83458236bd1e084fefab4725d Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:46:32 +0900 Subject: staging: rtl8192e: Delete unused dm_change_dynamic_initgain_thresh Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_dm.c | 70 ------------------------------------ drivers/staging/rtl8192e/r8192E_dm.h | 2 -- 2 files changed, 72 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index 50e276f8f34b..974555bd3c6f 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -1111,76 +1111,6 @@ void dm_cck_txpower_adjust(struct r8192_priv *priv, bool binch14) dm_CCKTxPowerAdjust_ThermalMeter(priv, binch14); } - -void dm_change_dynamic_initgain_thresh(struct net_device *dev, u32 dm_type, u32 dm_value) -{ - if (dm_type == DIG_TYPE_THRESH_HIGH) - { - dm_digtable.rssi_high_thresh = dm_value; - } - else if (dm_type == DIG_TYPE_THRESH_LOW) - { - dm_digtable.rssi_low_thresh = dm_value; - } - else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) - { - dm_digtable.rssi_high_power_highthresh = dm_value; - } - else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) - { - dm_digtable.rssi_high_power_highthresh = dm_value; - } - else if (dm_type == DIG_TYPE_ENABLE) - { - dm_digtable.dig_state = DM_STA_DIG_MAX; - dm_digtable.dig_enable_flag = true; - } - else if (dm_type == DIG_TYPE_DISABLE) - { - dm_digtable.dig_state = DM_STA_DIG_MAX; - dm_digtable.dig_enable_flag = false; - } - else if (dm_type == DIG_TYPE_DBG_MODE) - { - if(dm_value >= DM_DBG_MAX) - dm_value = DM_DBG_OFF; - dm_digtable.dbg_mode = (u8)dm_value; - } - else if (dm_type == DIG_TYPE_RSSI) - { - if(dm_value > 100) - dm_value = 30; - dm_digtable.rssi_val = (long)dm_value; - } - else if (dm_type == DIG_TYPE_ALGORITHM) - { - if (dm_value >= DIG_ALGO_MAX) - dm_value = DIG_ALGO_BY_FALSE_ALARM; - if(dm_digtable.dig_algorithm != (u8)dm_value) - dm_digtable.dig_algorithm_switch = 1; - dm_digtable.dig_algorithm = (u8)dm_value; - } - else if (dm_type == DIG_TYPE_BACKOFF) - { - if(dm_value > 30) - dm_value = 30; - dm_digtable.backoff_val = (u8)dm_value; - } - else if(dm_type == DIG_TYPE_RX_GAIN_MIN) - { - if(dm_value == 0) - dm_value = 0x1; - dm_digtable.rx_gain_range_min = (u8)dm_value; - } - else if(dm_type == DIG_TYPE_RX_GAIN_MAX) - { - if(dm_value > 0x50) - dm_value = 0x50; - dm_digtable.rx_gain_range_max = (u8)dm_value; - } -} - - /* Set DIG scheme init value. */ static void dm_dig_init(struct r8192_priv *priv) { diff --git a/drivers/staging/rtl8192e/r8192E_dm.h b/drivers/staging/rtl8192e/r8192E_dm.h index 16dcb033a9eb..de72a335107d 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.h +++ b/drivers/staging/rtl8192e/r8192E_dm.h @@ -221,8 +221,6 @@ void init_rate_adaptive(struct net_device *dev); void dm_txpower_trackingcallback(struct work_struct *work); void dm_restore_dynamic_mechanism_state(struct net_device *dev); void dm_backup_dynamic_mechanism_state(struct net_device *dev); -void dm_change_dynamic_initgain_thresh(struct net_device *dev, u32 dm_type, - u32 dm_value); void DM_ChangeFsyncSetting(struct net_device *dev, s32 DM_Type, s32 DM_Value); void dm_force_tx_fw_info(struct net_device *dev, u32 force_type, u32 force_value); -- cgit v1.2.3 From 83969021b2133450e9f7b018ae28dd6afb9a10f4 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:46:42 +0900 Subject: staging: rtl8192e: Delete non-existing function declarations Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_dm.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_dm.h b/drivers/staging/rtl8192e/r8192E_dm.h index de72a335107d..306dc367d93c 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.h +++ b/drivers/staging/rtl8192e/r8192E_dm.h @@ -219,12 +219,6 @@ void hal_dm_watchdog(struct net_device *dev); void init_rate_adaptive(struct net_device *dev); void dm_txpower_trackingcallback(struct work_struct *work); -void dm_restore_dynamic_mechanism_state(struct net_device *dev); -void dm_backup_dynamic_mechanism_state(struct net_device *dev); -void DM_ChangeFsyncSetting(struct net_device *dev, s32 DM_Type, s32 DM_Value); -void dm_force_tx_fw_info(struct net_device *dev, u32 force_type, - u32 force_value); -void dm_rf_operation_test_callback(unsigned long data); void dm_rf_pathcheck_workitemcallback(struct work_struct *work); void dm_initialize_txpower_tracking(struct r8192_priv *priv); void dm_cck_txpower_adjust(struct r8192_priv *priv, bool binch14); -- cgit v1.2.3 From 73fdfd7b78bfa8b0735d39be82519e18ad2fdff8 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:47:16 +0900 Subject: staging: rtl8192e: Delete unused members from struct r8192_priv Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 13 ----------- drivers/staging/rtl8192e/r8192E_core.c | 40 ---------------------------------- drivers/staging/rtl8192e/r819xE_phy.c | 2 -- 3 files changed, 55 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 1b838eea9aa8..4571eaf9d0c9 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -801,7 +801,6 @@ typedef struct r8192_priv u8 eeprom_CustomerID; u16 eeprom_ChannelPlan; RT_CUSTOMER_ID CustomerID; - LED_STRATEGY_8190 LedStrategy; u8 IC_Cut; int irq; struct ieee80211_device *ieee80211; @@ -827,13 +826,6 @@ typedef struct r8192_priv int rxringcount; u16 rxbuffersize; - struct sk_buff *rx_skb; - u32 *rxring; - u32 *rxringtail; - dma_addr_t rxringdma; - struct buffer *rxbuffer; - struct buffer *rxbufferhead; - short rx_skb_complete; /* TX stuff */ struct rtl8192_tx_ring tx_ring[MAX_TX_QUEUE_COUNT]; int txringcount; @@ -850,8 +842,6 @@ typedef struct r8192_priv short (*rf_set_sens)(struct net_device *dev,short sens); u8 (*rf_set_chan)(struct net_device *dev,u8 ch); - void (*rf_close)(struct net_device *dev); - void (*rf_init)(struct net_device *dev); short promisc; /* stats */ struct Stats stats; @@ -923,8 +913,6 @@ typedef struct r8192_priv u8 TxPowerLevelOFDM24G_A[14]; // RF-A, OFDM 2.4G channel 1~14 u8 TxPowerLevelOFDM24G_C[14]; // RF-C, OFDM 2.4G channel 1~14 u8 LegacyHTTxPowerDiff; // Legacy to HT rate power diff - u8 TxPowerDiff; - char RF_C_TxPwDiff; // Antenna gain offset, rf-c to rf-a u8 AntennaTxPwDiff[3]; // Antenna gain offset, index 0 for B, 1 for C, and 2 for D u8 CrystalCap; // CrystalCap. u8 ThermalMeter[2]; // ThermalMeter, index 0 for RFIC0, and 1 for RFIC1 @@ -966,7 +954,6 @@ typedef struct r8192_priv //+by amy 080515 for dynamic mechenism //Add by amy Tx Power Control for Near/Far Range 2008/05/15 - bool bdynamic_txpower; //bDynamicTxPower bool bDynamicTxHighPower; // Tx high power state bool bDynamicTxLowPower; // Tx low power state bool bLastDTPFlag_High; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 721e81a35bc5..6ac556ce783a 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1901,7 +1901,6 @@ static void rtl8192_init_priv_variable(struct r8192_priv *priv) priv->txringcount = 64;//32; priv->rxbuffersize = 9100;//2048;//1024; priv->rxringcount = MAX_RX_COUNT;//64; - priv->rx_skb_complete = 1; priv->chan = 1; //set to channel 1 priv->RegWirelessMode = WIRELESS_MODE_AUTO; priv->RegChannelPlan = 0xf; @@ -2380,42 +2379,6 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) if(priv->ChannelPlan > CHANNEL_PLAN_LEN - 1) priv->ChannelPlan = 0; //FCC - switch(priv->CustomerID) - { - case RT_CID_DEFAULT: - priv->LedStrategy = SW_LED_MODE1; - break; - - case RT_CID_819x_CAMEO: - priv->LedStrategy = SW_LED_MODE2; - break; - - case RT_CID_819x_RUNTOP: - priv->LedStrategy = SW_LED_MODE3; - break; - - case RT_CID_819x_Netcore: - priv->LedStrategy = SW_LED_MODE4; - break; - - case RT_CID_Nettronix: - priv->LedStrategy = SW_LED_MODE5; - break; - - case RT_CID_PRONET: - priv->LedStrategy = SW_LED_MODE6; - break; - - case RT_CID_TOSHIBA: //Modify by Jacken 2008/01/31 - // Do nothing. - //break; - - default: - priv->LedStrategy = SW_LED_MODE1; - break; - } - - if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304) priv->ieee80211->bSupportRemoteWakeUp = true; else @@ -2424,10 +2387,7 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan); RT_TRACE(COMP_INIT, "ChannelPlan = %d\n", priv->ChannelPlan); - RT_TRACE(COMP_INIT, "LedStrategy = %d\n", priv->LedStrategy); RT_TRACE(COMP_TRACE, "<==== ReadAdapterInfo\n"); - - return ; } diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c index 1688997d3469..f0975c617759 100644 --- a/drivers/staging/rtl8192e/r819xE_phy.c +++ b/drivers/staging/rtl8192e/r819xE_phy.c @@ -1451,8 +1451,6 @@ void rtl8192_phy_setTxPower(struct r8192_priv *priv, u8 channel) ant_pwr_diff = priv->TxPowerLevelOFDM24G_C[channel-1] -priv->TxPowerLevelOFDM24G_A[channel-1]; ant_pwr_diff &= 0xf; - //DbgPrint(" ant_pwr_diff = 0x%x", (u8)(ant_pwr_diff)); - priv->RF_C_TxPwDiff = ant_pwr_diff; priv->AntennaTxPwDiff[2] = 0;// RF-D, don't care priv->AntennaTxPwDiff[1] = (u8)(ant_pwr_diff);// RF-C -- cgit v1.2.3 From 73aaa501567043f6dca6be662a87fb08388df40f Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:47:29 +0900 Subject: staging: rtl8192e: Move card specific structures out of ieee80211 library header Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 80 -------------------------- drivers/staging/rtl8192e/r8192E.h | 74 ++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 80 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index 1998a0b4af92..7fb2dc6d9683 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -1738,91 +1738,11 @@ typedef enum _RT_PS_MODE eFastPs // Fast power save mode. }RT_PS_MODE; -typedef enum _IPS_CALLBACK_FUNCION -{ - IPS_CALLBACK_NONE = 0, - IPS_CALLBACK_MGNT_LINK_REQUEST = 1, - IPS_CALLBACK_JOIN_REQUEST = 2, -}IPS_CALLBACK_FUNCION; - -typedef enum _RT_JOIN_ACTION{ - RT_JOIN_INFRA = 1, - RT_JOIN_IBSS = 2, - RT_START_IBSS = 3, - RT_NO_ACTION = 4, -}RT_JOIN_ACTION; - typedef struct _IbssParms{ u16 atimWin; }IbssParms, *PIbssParms; #define MAX_NUM_RATES 264 // Max num of support rates element: 8, Max num of ext. support rate: 255. 061122, by rcnjko. -// RF state. -typedef enum _RT_RF_POWER_STATE -{ - eRfOn, - eRfSleep, - eRfOff -}RT_RF_POWER_STATE; - -typedef struct _RT_POWER_SAVE_CONTROL -{ - - // - // Inactive Power Save(IPS) : Disable RF when disconnected - // - bool bInactivePs; - bool bIPSModeBackup; - bool bSwRfProcessing; - RT_RF_POWER_STATE eInactivePowerState; - struct work_struct InactivePsWorkItem; - struct timer_list InactivePsTimer; - - // Return point for join action - IPS_CALLBACK_FUNCION ReturnPoint; - - // Recored Parameters for rescheduled JoinRequest - bool bTmpBssDesc; - RT_JOIN_ACTION tmpJoinAction; - struct ieee80211_network tmpBssDesc; - - // Recored Parameters for rescheduled MgntLinkRequest - bool bTmpScanOnly; - bool bTmpActiveScan; - bool bTmpFilterHiddenAP; - bool bTmpUpdateParms; - u8 tmpSsidBuf[33]; - OCTET_STRING tmpSsid2Scan; - bool bTmpSsid2Scan; - u8 tmpNetworkType; - u8 tmpChannelNumber; - u16 tmpBcnPeriod; - u8 tmpDtimPeriod; - u16 tmpmCap; - OCTET_STRING tmpSuppRateSet; - u8 tmpSuppRateBuf[MAX_NUM_RATES]; - bool bTmpSuppRate; - IbssParms tmpIbpm; - bool bTmpIbpm; - - // - // Leisre Poswer Save : Disable RF if connected but traffic is not busy - // - bool bLeisurePs; - u32 PowerProfile; - u8 LpsIdleCount; - - u32 CurPsLevel; - u32 RegRfPsLevel; - - bool bFwCtrlLPS; - u8 FWCtrlPSMode; - - bool LinkReqInIPSRFOffPgs; - bool BufConnectinfoBefore; - -}RT_POWER_SAVE_CONTROL,*PRT_POWER_SAVE_CONTROL; - #ifdef ENABLE_DOT11D typedef enum { diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 4571eaf9d0c9..2b70d0d4985d 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -199,6 +199,80 @@ typedef u32 RT_RF_CHANGE_SOURCE; #define RF_CHANGE_BY_IPS BIT28 #define RF_CHANGE_BY_INIT 0 // Do not change the RFOff reason. Defined by Bruce, 2008-01-17. +// RF state. +typedef enum _RT_RF_POWER_STATE { + eRfOn, + eRfSleep, + eRfOff +} RT_RF_POWER_STATE; + +typedef enum _RT_JOIN_ACTION { + RT_JOIN_INFRA = 1, + RT_JOIN_IBSS = 2, + RT_START_IBSS = 3, + RT_NO_ACTION = 4, +} RT_JOIN_ACTION; + +typedef enum _IPS_CALLBACK_FUNCION { + IPS_CALLBACK_NONE = 0, + IPS_CALLBACK_MGNT_LINK_REQUEST = 1, + IPS_CALLBACK_JOIN_REQUEST = 2, +} IPS_CALLBACK_FUNCION; + +typedef struct _RT_POWER_SAVE_CONTROL { + /* Inactive Power Save(IPS) : Disable RF when disconnected */ + bool bInactivePs; + bool bIPSModeBackup; + bool bSwRfProcessing; + RT_RF_POWER_STATE eInactivePowerState; + struct work_struct InactivePsWorkItem; + struct timer_list InactivePsTimer; + + /* Return point for join action */ + IPS_CALLBACK_FUNCION ReturnPoint; + + /* Recored Parameters for rescheduled JoinRequest */ + bool bTmpBssDesc; + RT_JOIN_ACTION tmpJoinAction; + struct ieee80211_network tmpBssDesc; + + /* Recored Parameters for rescheduled MgntLinkRequest */ + bool bTmpScanOnly; + bool bTmpActiveScan; + bool bTmpFilterHiddenAP; + bool bTmpUpdateParms; + u8 tmpSsidBuf[33]; + OCTET_STRING tmpSsid2Scan; + bool bTmpSsid2Scan; + u8 tmpNetworkType; + u8 tmpChannelNumber; + u16 tmpBcnPeriod; + u8 tmpDtimPeriod; + u16 tmpmCap; + OCTET_STRING tmpSuppRateSet; + u8 tmpSuppRateBuf[MAX_NUM_RATES]; + bool bTmpSuppRate; + IbssParms tmpIbpm; + bool bTmpIbpm; + + /* + * Leisure Power Save: + * Disable RF if connected but traffic is not busy + */ + bool bLeisurePs; + u32 PowerProfile; + u8 LpsIdleCount; + + u32 CurPsLevel; + u32 RegRfPsLevel; + + bool bFwCtrlLPS; + u8 FWCtrlPSMode; + + bool LinkReqInIPSRFOffPgs; + bool BufConnectinfoBefore; +} RT_POWER_SAVE_CONTROL, *PRT_POWER_SAVE_CONTROL; + /* For rtl819x */ typedef struct _tx_desc_819x_pci { //DWORD 0 -- cgit v1.2.3 From 153775d94899503f5f66baaa9751a43c74d4f371 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 3 Mar 2011 22:47:41 +0900 Subject: staging: rtl8192e: unused Remove dot11PowerSaveMode and RT_PS_MODE Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 9 --------- drivers/staging/rtl8192e/r8192E_core.c | 1 - 2 files changed, 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index 7fb2dc6d9683..75aa69917ccd 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -1730,14 +1730,6 @@ typedef enum _Fsync_State{ SW_Fsync }Fsync_State; -// Power save mode configured. -typedef enum _RT_PS_MODE -{ - eActive, // Active/Continuous access. - eMaxPs, // Max power save mode. - eFastPs // Fast power save mode. -}RT_PS_MODE; - typedef struct _IbssParms{ u16 atimWin; }IbssParms, *PIbssParms; @@ -1896,7 +1888,6 @@ struct ieee80211_device { bool ieee_up; //added by amy bool bSupportRemoteWakeUp; - RT_PS_MODE dot11PowerSaveMode; // Power save mode configured. bool actscanning; bool beinretry; bool is_set_key; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 6ac556ce783a..597c12de71d0 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1953,7 +1953,6 @@ static void rtl8192_init_priv_variable(struct r8192_priv *priv) priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc; priv->ieee80211->tx_headroom = sizeof(TX_FWINFO_8190PCI); priv->ieee80211->qos_support = 1; - priv->ieee80211->dot11PowerSaveMode = 0; priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode; priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response; priv->ieee80211->handle_beacon = rtl8192_handle_beacon; -- cgit v1.2.3 From 41e568d14ec0aca1b2bb19563517aad3b06d6805 Mon Sep 17 00:00:00 2001 From: huajun li Date: Fri, 4 Mar 2011 10:56:18 +0800 Subject: Staging: Merge ENE UB6250 SD card codes from keucr to drivers/usb/storage The usb portion of this driver can now go into drivers/usb/storage. This leaves the non-usb portion of the code still in staging. Signed-off-by: Huajun Li Signed-off-by: Greg Kroah-Hartman --- drivers/staging/keucr/Kconfig | 5 +- drivers/staging/keucr/Makefile | 1 - drivers/staging/keucr/init.c | 122 +---- drivers/staging/keucr/init.h | 773 ----------------------------- drivers/staging/keucr/sdscsi.c | 210 -------- drivers/staging/keucr/transport.c | 3 +- drivers/staging/keucr/transport.h | 3 - drivers/staging/keucr/usb.c | 21 +- drivers/usb/storage/Kconfig | 14 + drivers/usb/storage/Makefile | 2 + drivers/usb/storage/ene_ub6250.c | 807 +++++++++++++++++++++++++++++++ drivers/usb/storage/unusual_ene_ub6250.h | 26 + drivers/usb/storage/usual-tables.c | 1 + 13 files changed, 876 insertions(+), 1112 deletions(-) delete mode 100644 drivers/staging/keucr/sdscsi.c create mode 100644 drivers/usb/storage/ene_ub6250.c create mode 100644 drivers/usb/storage/unusual_ene_ub6250.h (limited to 'drivers') diff --git a/drivers/staging/keucr/Kconfig b/drivers/staging/keucr/Kconfig index b595bdbd4740..e397fad693a7 100644 --- a/drivers/staging/keucr/Kconfig +++ b/drivers/staging/keucr/Kconfig @@ -1,8 +1,9 @@ config USB_ENESTORAGE - tristate "USB ENE card reader support" + tristate "USB ENE SM/MS card reader support" depends on USB && SCSI && m ---help--- - Say Y here if you wish to control a ENE Card reader. + Say Y here if you wish to control a ENE SM/MS Card reader. + To use SD card, please build driver/usb/storage/ums-eneub6250.ko This option depends on 'SCSI' support being enabled, but you probably also need 'SCSI device support: SCSI disk support' diff --git a/drivers/staging/keucr/Makefile b/drivers/staging/keucr/Makefile index 5c19b7b0d3b7..ae928f9cd71a 100644 --- a/drivers/staging/keucr/Makefile +++ b/drivers/staging/keucr/Makefile @@ -7,7 +7,6 @@ keucr-y := \ scsiglue.o \ transport.o \ init.o \ - sdscsi.o \ msscsi.o \ ms.o \ smscsi.o \ diff --git a/drivers/staging/keucr/init.c b/drivers/staging/keucr/init.c index 515e448852a0..5c01f28f0734 100644 --- a/drivers/staging/keucr/init.c +++ b/drivers/staging/keucr/init.c @@ -30,14 +30,6 @@ int ENE_InitMedia(struct us_data *us) } printk(KERN_INFO "MiscReg03 = %x\n", MiscReg03); - if (MiscReg03 & 0x01) { - if (!us->SD_Status.Ready) { - result = ENE_SDInit(us); - if (result != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; - } - } - if (MiscReg03 & 0x02) { if (!us->SM_Status.Ready && !us->MS_Status.Ready) { result = ENE_SMInit(us); @@ -72,69 +64,6 @@ int ENE_Read_BYTE(struct us_data *us, WORD index, void *buf) return result; } -/* - * ENE_SDInit(): - */ -int ENE_SDInit(struct us_data *us) -{ - struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; - int result; - BYTE buf[0x200]; - - printk(KERN_INFO "transport --- ENE_SDInit\n"); - /* SD Init Part-1 */ - result = ENE_LoadBinCode(us, SD_INIT1_PATTERN); - if (result != USB_STOR_XFER_GOOD) { - printk(KERN_ERR "Load SD Init Code Part-1 Fail !!\n"); - return USB_STOR_TRANSPORT_ERROR; - } - - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); - bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcb->Flags = 0x80; - bcb->CDB[0] = 0xF2; - - result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0); - if (result != USB_STOR_XFER_GOOD) { - printk(KERN_ERR "Exection SD Init Code Fail !!\n"); - return USB_STOR_TRANSPORT_ERROR; - } - - /* SD Init Part-2 */ - result = ENE_LoadBinCode(us, SD_INIT2_PATTERN); - if (result != USB_STOR_XFER_GOOD) { - printk(KERN_ERR "Load SD Init Code Part-2 Fail !!\n"); - return USB_STOR_TRANSPORT_ERROR; - } - - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); - bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcb->DataTransferLength = 0x200; - bcb->Flags = 0x80; - bcb->CDB[0] = 0xF1; - - result = ENE_SendScsiCmd(us, FDIR_READ, &buf, 0); - if (result != USB_STOR_XFER_GOOD) { - printk(KERN_ERR "Exection SD Init Code Fail !!\n"); - return USB_STOR_TRANSPORT_ERROR; - } - - us->SD_Status = *(PSD_STATUS)&buf[0]; - if (us->SD_Status.Insert && us->SD_Status.Ready) { - ENE_ReadSDReg(us, (PBYTE)&buf); - printk(KERN_INFO "Insert = %x\n", us->SD_Status.Insert); - printk(KERN_INFO "Ready = %x\n", us->SD_Status.Ready); - printk(KERN_INFO "IsMMC = %x\n", us->SD_Status.IsMMC); - printk(KERN_INFO "HiCapacity = %x\n", us->SD_Status.HiCapacity); - printk(KERN_INFO "HiSpeed = %x\n", us->SD_Status.HiSpeed); - printk(KERN_INFO "WtP = %x\n", us->SD_Status.WtP); - } else { - printk(KERN_ERR "SD Card Not Ready --- %x\n", buf[0]); - return USB_STOR_TRANSPORT_ERROR; - } - return USB_STOR_TRANSPORT_GOOD; -} - /* * ENE_MSInit(): */ @@ -241,38 +170,6 @@ int ENE_SMInit(struct us_data *us) return USB_STOR_TRANSPORT_GOOD; } -/* - * ENE_ReadSDReg() - */ -int ENE_ReadSDReg(struct us_data *us, u8 *RdBuf) -{ - WORD tmpreg; - DWORD reg4b; - - /* printk(KERN_INFO "transport --- ENE_ReadSDReg\n"); */ - reg4b = *(PDWORD)&RdBuf[0x18]; - us->SD_READ_BL_LEN = (BYTE)((reg4b >> 8) & 0x0f); - - tmpreg = (WORD) reg4b; - reg4b = *(PDWORD)(&RdBuf[0x14]); - if (us->SD_Status.HiCapacity && !us->SD_Status.IsMMC) - us->HC_C_SIZE = (reg4b >> 8) & 0x3fffff; - - us->SD_C_SIZE = ((tmpreg & 0x03) << 10) | (WORD)(reg4b >> 22); - us->SD_C_SIZE_MULT = (BYTE)(reg4b >> 7) & 0x07; - if (us->SD_Status.HiCapacity && us->SD_Status.IsMMC) - us->HC_C_SIZE = *(PDWORD)(&RdBuf[0x100]); - - if (us->SD_READ_BL_LEN > SD_BLOCK_LEN) { - us->SD_Block_Mult = - 1 << (us->SD_READ_BL_LEN - SD_BLOCK_LEN); - us->SD_READ_BL_LEN = SD_BLOCK_LEN; - } else { - us->SD_Block_Mult = 1; - } - return USB_STOR_TRANSPORT_GOOD; -} - /* * ENE_LoadBinCode() */ @@ -291,19 +188,6 @@ int ENE_LoadBinCode(struct us_data *us, BYTE flag) if (buf == NULL) return USB_STOR_TRANSPORT_ERROR; switch (flag) { - /* For SD */ - case SD_INIT1_PATTERN: - printk(KERN_INFO "SD_INIT1_PATTERN\n"); - memcpy(buf, SD_Init1, 0x800); - break; - case SD_INIT2_PATTERN: - printk(KERN_INFO "SD_INIT2_PATTERN\n"); - memcpy(buf, SD_Init2, 0x800); - break; - case SD_RW_PATTERN: - printk(KERN_INFO "SD_RW_PATTERN\n"); - memcpy(buf, SD_Rdwr, 0x800); - break; /* For MS */ case MS_INIT_PATTERN: printk(KERN_INFO "MS_INIT_PATTERN\n"); @@ -412,8 +296,9 @@ int ENE_SendScsiCmd(struct us_data *us, BYTE fDir, void *buf, int use_sg) */ if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE)) { residue = min(residue, transfer_length); - scsi_set_resid(us->srb, max(scsi_get_resid(us->srb), - (int) residue)); + if (us->srb) + scsi_set_resid(us->srb, max(scsi_get_resid(us->srb), + (int) residue)); } if (bcs->Status != US_BULK_STAT_OK) @@ -558,4 +443,3 @@ void usb_stor_print_cmd(struct scsi_cmnd *srb) blen = 0; } - diff --git a/drivers/staging/keucr/init.h b/drivers/staging/keucr/init.h index 5223132a6c24..953a31e9d5f0 100644 --- a/drivers/staging/keucr/init.h +++ b/drivers/staging/keucr/init.h @@ -3,779 +3,6 @@ extern DWORD MediaChange; extern int Check_D_MediaFmt(struct us_data *); -BYTE SD_Init1[] = { -0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE1, 0x06, 0x90, -0xFF, 0x23, 0x74, 0x80, 0xF0, 0x90, 0xFF, 0x09, -0xE0, 0x30, 0xE5, 0xFC, 0x90, 0xFF, 0x83, 0xE0, -0xA2, 0xE0, 0x92, 0x14, 0x20, 0x14, 0x0A, 0xC2, -0x0F, 0xD2, 0x10, 0xC2, 0x17, 0xC3, 0x02, 0xE3, -0x13, 0x7F, 0x03, 0x12, 0x2F, 0xCB, 0x7E, 0x00, -0x7F, 0x10, 0x12, 0xE3, 0xFA, 0x90, 0xFE, 0x07, -0xE0, 0x54, 0xBA, 0xF0, 0x75, 0x16, 0x00, 0x75, -0x17, 0x00, 0x90, 0xFE, 0x05, 0x74, 0x80, 0xF0, -0x90, 0xFE, 0x07, 0x74, 0x80, 0xF0, 0x7F, 0x32, -0x7E, 0x00, 0x12, 0xE3, 0xFA, 0x90, 0xFE, 0x05, -0xE0, 0x44, 0x01, 0xF0, 0xE0, 0x44, 0x08, 0xF0, -0x7F, 0x32, 0x7E, 0x00, 0x12, 0xE3, 0xFA, 0x90, -0xFE, 0x05, 0xE0, 0x54, 0xF7, 0xF0, 0x7F, 0x32, -0x7E, 0x00, 0x12, 0xE3, 0xFA, 0x90, 0xFF, 0x81, -0xE0, 0xC2, 0xE3, 0xF0, 0xE0, 0x54, 0xCF, 0x44, -0x20, 0xD2, 0xE3, 0xF0, 0x90, 0xFF, 0x84, 0xE0, -0x54, 0x1F, 0x44, 0x40, 0xF0, 0x90, 0xFE, 0x05, -0xE0, 0xD2, 0xE0, 0xF0, 0xE0, 0x30, 0xE0, 0xF8, -0x90, 0xFE, 0x04, 0xE0, 0x44, 0x06, 0xF0, 0x90, -0xFE, 0x04, 0x30, 0x14, 0x06, 0xE0, 0x70, 0xFA, -0xD3, 0x80, 0x01, 0xC3, 0x90, 0xFE, 0x05, 0xE0, -0x44, 0x30, 0xF0, 0x90, 0xFE, 0x06, 0x74, 0x70, -0xF0, 0x74, 0xFF, 0x90, 0xFE, 0x08, 0xF0, 0x74, -0xFF, 0x90, 0xFE, 0x09, 0xF0, 0x90, 0xFE, 0x04, -0xE0, 0x44, 0x06, 0xF0, 0xE4, 0x90, 0xFE, 0x0C, -0xF0, 0x90, 0xFE, 0x0D, 0xF0, 0x90, 0xFE, 0x0E, -0xF0, 0xC2, 0x12, 0xE4, 0x90, 0xEB, 0xF9, 0xF0, -0x90, 0xEB, 0xFA, 0xF0, 0x90, 0xFF, 0x81, 0xE0, -0x54, 0x8F, 0x44, 0x7F, 0xF0, 0x7F, 0x32, 0x7E, -0x00, 0x12, 0xE3, 0xFA, 0x90, 0xFE, 0x05, 0xE0, -0x54, 0xBF, 0xF0, 0x75, 0xF0, 0xFF, 0xD2, 0x17, -0xC2, 0x13, 0xE5, 0xF0, 0x14, 0xF5, 0xF0, 0x70, -0x03, 0x02, 0xE2, 0xFC, 0x90, 0xFF, 0x83, 0xE0, -0xA2, 0xE0, 0x92, 0x14, 0x20, 0x14, 0x03, 0x02, -0xE2, 0xFC, 0xE4, 0xFE, 0x74, 0xFF, 0xFF, 0x78, -0x00, 0x79, 0x08, 0x12, 0xE3, 0x22, 0x20, 0x13, -0x24, 0x30, 0x17, 0x21, 0x90, 0xFF, 0x83, 0xE0, -0xA2, 0xE0, 0x92, 0x14, 0x20, 0x14, 0x03, 0x02, -0xE2, 0xFC, 0x78, 0x08, 0x79, 0x28, 0x7D, 0xAA, -0x7C, 0x01, 0x7B, 0x00, 0x7A, 0x00, 0x12, 0xE3, -0x22, 0x50, 0x02, 0x21, 0xED, 0x90, 0xFF, 0x83, -0xE0, 0xA2, 0xE0, 0x92, 0x14, 0x20, 0x14, 0x03, -0x02, 0xE2, 0xFC, 0x30, 0x13, 0x02, 0x80, 0x17, -0x78, 0x37, 0x79, 0x50, 0x7A, 0x00, 0x7B, 0x00, -0x7C, 0x00, 0x7D, 0x00, 0x12, 0xE3, 0x22, 0x50, -0x02, 0x80, 0x7A, 0x78, 0x69, 0x80, 0x02, 0x78, -0x01, 0x79, 0x2A, 0x7A, 0x80, 0x30, 0x17, 0x02, -0x7A, 0x40, 0x7B, 0x70, 0x7C, 0x00, 0x7D, 0x00, -0x12, 0xE3, 0x22, 0x50, 0x16, 0x90, 0xFE, 0x04, -0xE0, 0x44, 0x06, 0xF0, 0x90, 0xFE, 0x04, 0x30, -0x14, 0x06, 0xE0, 0x70, 0xFA, 0xD3, 0x80, 0x01, -0xC3, 0x80, 0x4A, 0x90, 0xFE, 0x20, 0xE0, 0x54, -0x00, 0xB4, 0x00, 0x23, 0x90, 0xFE, 0x21, 0xE0, -0x54, 0x00, 0xB4, 0x00, 0x1A, 0x90, 0xFE, 0x22, -0xE0, 0x54, 0x70, 0xB4, 0x70, 0x11, 0x90, 0xFE, -0x23, 0xE0, 0x30, 0xE7, 0x0A, 0x30, 0x17, 0x05, -0x20, 0xE6, 0x02, 0xC2, 0x17, 0x41, 0x02, 0xC3, -0xEF, 0x94, 0x01, 0xFF, 0xEE, 0x94, 0x00, 0xFE, -0xC0, 0x06, 0xC0, 0x07, 0x7F, 0x64, 0x7E, 0x00, -0x12, 0xE3, 0xFA, 0xD0, 0x07, 0xD0, 0x06, 0xEE, -0x4F, 0x60, 0x02, 0x21, 0x4D, 0x7F, 0x64, 0x7E, -0x00, 0x12, 0xE3, 0xFA, 0xB2, 0x17, 0x30, 0x17, -0x07, 0xB2, 0x13, 0x20, 0x13, 0x02, 0x01, 0xFE, -0x21, 0x0C, 0x78, 0x02, 0x79, 0x2D, 0x12, 0xE3, -0x22, 0x50, 0x03, 0x02, 0xE2, 0xFC, 0x7B, 0x0F, -0x7C, 0xFE, 0x7D, 0x20, 0x7E, 0xEA, 0x7F, 0x1A, -0x12, 0xE3, 0xD3, 0x78, 0x03, 0x20, 0x13, 0x02, -0x78, 0x03, 0x79, 0x28, 0x90, 0xEB, 0xFA, 0xE0, -0xFA, 0x90, 0xEB, 0xF9, 0xE0, 0xFB, 0x7C, 0x00, -0x7D, 0x00, 0x12, 0xE3, 0x22, 0x50, 0x03, 0x02, -0xE2, 0xFC, 0x90, 0xFE, 0x22, 0xE0, 0x90, 0xEB, -0xF9, 0xF0, 0x90, 0xFE, 0x23, 0xE0, 0x90, 0xEB, -0xFA, 0xF0, 0x90, 0xFF, 0x81, 0xE0, 0xC2, 0xE3, -0xF0, 0x30, 0x13, 0x11, 0x90, 0xFF, 0x85, 0xE0, -0x54, 0xCF, 0x44, 0x20, 0xF0, 0x90, 0xFF, 0x81, -0x74, 0x94, 0xF0, 0x80, 0x0F, 0x90, 0xFF, 0x85, -0xE0, 0x54, 0xCF, 0x44, 0x30, 0xF0, 0x90, 0xFF, -0x81, 0x74, 0x94, 0xF0, 0x90, 0xFF, 0x81, 0xE0, -0xD2, 0xE3, 0xF0, 0x7F, 0x32, 0x7E, 0x00, 0x12, -0xE3, 0xFA, 0x78, 0x09, 0x79, 0x4D, 0x90, 0xEB, -0xFA, 0xE0, 0xFA, 0x90, 0xEB, 0xF9, 0xE0, 0xFB, -0x7C, 0x00, 0x7D, 0x00, 0x12, 0xE3, 0x22, 0x50, -0x03, 0x02, 0xE2, 0xFC, 0x12, 0xE3, 0x91, 0x78, -0x87, 0x79, 0x50, 0x90, 0xEB, 0xFA, 0xE0, 0xFA, -0x90, 0xEB, 0xF9, 0xE0, 0xFB, 0x7C, 0x00, 0x7D, -0x00, 0x12, 0xE3, 0x22, 0x50, 0x03, 0x02, 0xE2, -0xFC, 0x30, 0x13, 0x09, 0x90, 0xFE, 0x05, 0xE0, -0x54, 0xBF, 0xF0, 0x80, 0x35, 0x78, 0x37, 0x79, -0x50, 0x90, 0xEB, 0xFA, 0xE0, 0xFA, 0x90, 0xEB, -0xF9, 0xE0, 0xFB, 0x7C, 0x00, 0x7D, 0x00, 0x12, -0xE3, 0x22, 0x50, 0x03, 0x02, 0xE2, 0xFC, 0x78, -0x46, 0x79, 0x50, 0x7A, 0x00, 0x7B, 0x00, 0x7C, -0x00, 0x7D, 0x02, 0x12, 0xE3, 0x22, 0x50, 0x03, -0x02, 0xE2, 0xFC, 0x90, 0xFE, 0x05, 0xE0, 0x44, -0x40, 0xF0, 0xD3, 0x22, 0x30, 0x14, 0x14, 0x90, -0xFE, 0x04, 0xE0, 0x44, 0x06, 0xF0, 0x90, 0xFE, -0x04, 0x30, 0x14, 0x06, 0xE0, 0x70, 0xFA, 0xD3, -0x80, 0x01, 0xC3, 0x90, 0xFE, 0xD8, 0x74, 0x01, -0xF0, 0x90, 0xFE, 0xCC, 0xE0, 0x44, 0x80, 0xF0, -0xC3, 0x22, 0xE8, 0x90, 0xFE, 0x15, 0xF0, 0xE9, -0x90, 0xFE, 0x14, 0xF0, 0xED, 0x90, 0xFE, 0x18, -0xF0, 0xEC, 0x90, 0xFE, 0x19, 0xF0, 0xEB, 0x90, -0xFE, 0x1A, 0xF0, 0xEA, 0x90, 0xFE, 0x1B, 0xF0, -0x74, 0xFF, 0x90, 0xFE, 0x10, 0xF0, 0x90, 0xFE, -0x11, 0xF0, 0x90, 0xFE, 0x12, 0xF0, 0xE8, 0x54, -0x80, 0xFE, 0x90, 0xFE, 0x04, 0x74, 0x01, 0xF0, -0x30, 0x14, 0x08, 0x90, 0xFE, 0x10, 0xE0, 0x54, -0x05, 0x60, 0x02, 0xD3, 0x22, 0x90, 0xFE, 0x11, -0xE0, 0x30, 0xE0, 0xEC, 0xBE, 0x80, 0x03, 0x30, -0xE1, 0xE6, 0x90, 0xFE, 0x10, 0xE0, 0x54, 0x05, -0x70, 0xE9, 0xC3, 0x22, 0x30, 0x13, 0x02, 0xC3, -0x22, 0x90, 0xFE, 0x22, 0xE0, 0x70, 0x06, 0x90, -0xFE, 0x23, 0xE0, 0x60, 0x02, 0xD3, 0x22, 0xC3, -0x22, 0x7B, 0x0F, 0x7C, 0xFE, 0x7D, 0x20, 0x7E, -0xEA, 0x7F, 0x29, 0x12, 0xE3, 0xD3, 0x30, 0x13, -0x1B, 0x90, 0xFE, 0x20, 0xE0, 0x54, 0x30, 0x64, -0x30, 0x70, 0x02, 0xD2, 0x11, 0x30, 0x13, 0x0C, -0x90, 0xFE, 0x2E, 0xE0, 0x54, 0x3C, 0x64, 0x10, -0x70, 0x02, 0xD2, 0x12, 0x30, 0x17, 0x03, 0x02, -0xE3, 0xC4, 0x80, 0x03, 0x20, 0x13, 0x00, 0xC2, -0x11, 0x90, 0xFE, 0x13, 0xE0, 0x30, 0xE2, 0x02, -0xD2, 0x11, 0x22, 0xC0, 0x04, 0xC0, 0x05, 0x8E, -0x83, 0x8F, 0x82, 0xEB, 0x60, 0x17, 0xC0, 0x82, -0xC0, 0x83, 0x8C, 0x83, 0x8D, 0x82, 0xE0, 0xA3, -0xAC, 0x83, 0xAD, 0x82, 0xD0, 0x83, 0xD0, 0x82, -0xF0, 0xA3, 0x1B, 0x80, 0xE6, 0xD0, 0x05, 0xD0, -0x04, 0x22, 0x75, 0x8A, 0x00, 0x75, 0x8C, 0xCE, -0xC2, 0x8D, 0x90, 0xEA, 0x65, 0xE4, 0xF0, 0xA3, -0xF0, 0xD2, 0x8C, 0x90, 0xEA, 0x65, 0xE0, 0xFC, -0xA3, 0xE0, 0xFD, 0xEC, 0xC3, 0x9E, 0x40, 0xF3, -0x70, 0x05, 0xED, 0xC3, 0x9F, 0x40, 0xEC, 0xC2, -0x8C, 0x22, 0xF5, 0xD3, 0xE0, 0x64, 0x01, 0x70, -0x02, 0xD2, 0x3F, 0x75, 0x17, 0x00, 0x75, 0x18, -0x00, 0x85, 0x14, 0x19, 0x75, 0x1B, 0x01, 0x12, -0x2F, 0x8C, 0x40, 0x03, 0x02, 0xE4, 0x45, 0x90, -0xEA, 0x49, 0xE5, 0x14, 0xF0, 0x05, 0x14, 0x02, -0xE2, 0xDC, 0xD2, 0x22, 0x90, 0xEA, 0x49, 0xE0, -0x64, 0xFF, 0x70, 0x02, 0x80, 0x02, 0x80, 0x12, -0x90, 0xFE, 0x44, 0x74, 0x02, 0xF0, 0x30, 0x25, -0x04, 0xE0, 0x20, 0xE1, 0xF9, 0x12, 0x2F, 0x9E, -0xC3, 0x22, 0x30, 0x3F, 0x36, 0x74, 0x88, 0x90, -0xEA, 0x44, 0xF0, 0x75, 0x17, 0x00, 0x79, 0x00, -0x7A, 0x00, 0x7B, 0x10, 0x7C, 0x02, 0x7D, 0x02, -0x12, 0x2F, 0xA7, 0x7F, 0x80, 0x12, 0x2F, 0xC5, -0x90, 0xFE, 0x45, 0xE0, 0x54, 0xFE, 0xF0, 0x90, -0xFE, 0x45, 0xE0, 0x44, 0x04, 0xF0, 0x90, 0xFE, -0x44, 0x74, 0x02, 0xF0, 0x30, 0x25, 0x04, 0xE0, -0x20, 0xE1, 0xF9, 0xD3, 0x22, 0x75, 0x8A, 0x00, -0x75, 0x8C, 0xCE, 0xC2, 0x8D, 0x90, 0xEA, 0x65, -0xE4, 0xF0, 0xA3, 0xF0, 0xD2, 0x8C, 0x90, 0xEA, -0x65, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xEC, 0xC3, -0x9E, 0x40, 0xF3, 0x70, 0x05, 0xED, 0xC3, 0x9F, -0x40, 0xEC, 0xC2, 0x8C, 0x22, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x53, 0x44, 0x2D, 0x49, 0x6E, 0x69, 0x74, 0x31, -0x20, 0x20, 0x20, 0x31, 0x30, 0x30, 0x30, 0x31 }; - -BYTE SD_Init2[] = { -0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE1, 0x06, 0x90, -0xFF, 0x23, 0x74, 0x80, 0xF0, 0x90, 0xFF, 0x09, -0xE0, 0x30, 0xE5, 0xFC, 0x90, 0xFF, 0x83, 0xE0, -0xA2, 0xE0, 0x92, 0x14, 0x20, 0x14, 0x0A, 0xC2, -0x0F, 0xD2, 0x10, 0xC2, 0x17, 0xC3, 0x02, 0xE0, -0xA0, 0x20, 0x13, 0x05, 0x12, 0xE3, 0x8D, 0x80, -0x03, 0x12, 0xE1, 0x1F, 0xD2, 0x0F, 0xC2, 0x10, -0xD3, 0x90, 0xF3, 0xFF, 0x75, 0xF0, 0xFF, 0x74, -0x00, 0xA3, 0xF0, 0xD5, 0xF0, 0xFB, 0x7B, 0x0F, -0x7C, 0xEA, 0x7D, 0x29, 0x7E, 0xF4, 0x7F, 0x10, -0x12, 0xE5, 0x5D, 0x90, 0xF4, 0x00, 0xE4, 0xA2, -0x14, 0x92, 0xE0, 0xA2, 0x0F, 0x92, 0xE1, 0xA2, -0x10, 0x92, 0xE2, 0xA2, 0x13, 0x92, 0xE3, 0xA2, -0x17, 0x92, 0xE4, 0xA2, 0x12, 0x92, 0xE5, 0xA2, -0x11, 0x92, 0xE6, 0xF0, 0xF0, 0x74, 0xFF, 0xA3, -0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0xFF, 0x2A, -0x74, 0x02, 0xF0, 0xA3, 0x74, 0x00, 0xF0, 0xD3, -0x22, 0x30, 0x14, 0x14, 0x90, 0xFE, 0x04, 0xE0, -0x44, 0x06, 0xF0, 0x90, 0xFE, 0x04, 0x30, 0x14, -0x06, 0xE0, 0x70, 0xFA, 0xD3, 0x80, 0x01, 0xC3, -0x90, 0xFE, 0xD8, 0x74, 0x01, 0xF0, 0x90, 0xFE, -0xCC, 0xE0, 0x44, 0x80, 0xF0, 0x02, 0xE0, 0x39, -0xE8, 0x90, 0xFE, 0x15, 0xF0, 0xE9, 0x90, 0xFE, -0x14, 0xF0, 0xED, 0x90, 0xFE, 0x18, 0xF0, 0xEC, -0x90, 0xFE, 0x19, 0xF0, 0xEB, 0x90, 0xFE, 0x1A, -0xF0, 0xEA, 0x90, 0xFE, 0x1B, 0xF0, 0x74, 0xFF, -0x90, 0xFE, 0x10, 0xF0, 0x90, 0xFE, 0x11, 0xF0, -0x90, 0xFE, 0x12, 0xF0, 0xE8, 0x54, 0x80, 0xFE, -0x90, 0xFE, 0x04, 0x74, 0x01, 0xF0, 0x30, 0x14, -0x08, 0x90, 0xFE, 0x10, 0xE0, 0x54, 0x05, 0x60, -0x02, 0xD3, 0x22, 0x90, 0xFE, 0x11, 0xE0, 0x30, -0xE0, 0xEC, 0xBE, 0x80, 0x03, 0x30, 0xE1, 0xE6, -0x90, 0xFE, 0x10, 0xE0, 0x54, 0x05, 0x70, 0xE9, -0xC3, 0x22, 0x30, 0x13, 0x02, 0xC3, 0x22, 0x90, -0xFE, 0x22, 0xE0, 0x70, 0x06, 0x90, 0xFE, 0x23, -0xE0, 0x60, 0x02, 0xD3, 0x22, 0xC3, 0x22, 0x20, -0x12, 0x03, 0x02, 0xE3, 0x17, 0x90, 0xFE, 0x1C, -0x74, 0xFF, 0xF0, 0x90, 0xFE, 0x1D, 0x74, 0x01, -0xF0, 0x74, 0x00, 0x90, 0xFE, 0x1E, 0xF0, 0x90, -0xFE, 0x1F, 0xF0, 0x90, 0xFE, 0xCC, 0xE0, 0x54, -0x7F, 0xF0, 0x90, 0xFE, 0x06, 0xE0, 0x54, 0xF0, -0xF0, 0x90, 0xFE, 0xC0, 0x74, 0xF4, 0xF0, 0xA3, -0x74, 0x00, 0xF0, 0x90, 0xFE, 0xC6, 0x74, 0x01, -0xF0, 0xA3, 0x74, 0xFF, 0xF0, 0x90, 0xFE, 0xC5, -0xE4, 0xF0, 0x90, 0xFE, 0xC4, 0x74, 0x04, 0xF0, -0x78, 0x10, 0x79, 0x50, 0x7A, 0x00, 0x7B, 0x00, -0x7C, 0x02, 0x7D, 0x00, 0x12, 0xE0, 0xB0, 0x50, -0x03, 0x02, 0xE3, 0x17, 0x78, 0x08, 0x79, 0xE8, -0x12, 0xE0, 0xB0, 0x50, 0x03, 0x02, 0xE3, 0x17, -0x90, 0xFE, 0xC8, 0xE0, 0xF0, 0x90, 0xFE, 0xC4, -0xE0, 0x44, 0x01, 0xF0, 0x30, 0x14, 0x10, 0x90, -0xFE, 0xC8, 0xE0, 0x64, 0x01, 0x60, 0x11, 0x90, -0xFE, 0x10, 0xE0, 0x54, 0x0A, 0x60, 0xED, 0x90, -0xFE, 0xD8, 0x74, 0x01, 0xF0, 0xC3, 0x80, 0x01, -0xD3, 0x40, 0x03, 0x02, 0xE3, 0x17, 0x20, 0x17, -0x02, 0x80, 0x39, 0xC3, 0x90, 0xF4, 0xD4, 0xE0, -0x90, 0xF5, 0x00, 0xF0, 0x90, 0xEB, 0xF8, 0x94, -0x01, 0xF0, 0x90, 0xF4, 0xD5, 0xE0, 0x90, 0xF5, -0x01, 0xF0, 0x90, 0xEB, 0xF7, 0x94, 0x00, 0xF0, -0x90, 0xF4, 0xD6, 0xE0, 0x90, 0xF5, 0x02, 0xF0, -0x90, 0xEB, 0xF6, 0x94, 0x00, 0xF0, 0x90, 0xF4, -0xD7, 0xE0, 0x90, 0xF5, 0x03, 0xF0, 0x90, 0xEB, -0xF5, 0x94, 0x00, 0xF0, 0x90, 0xF4, 0x00, 0x43, -0x82, 0xC4, 0xE0, 0x54, 0x03, 0xF5, 0x09, 0x90, -0xFE, 0xCC, 0xE0, 0x44, 0x80, 0xF0, 0x90, 0xFE, -0x06, 0xE0, 0x54, 0x3F, 0x44, 0x00, 0xF0, 0x90, -0xFE, 0x04, 0xE0, 0x44, 0x06, 0xF0, 0x90, 0xFE, -0x04, 0x30, 0x14, 0x06, 0xE0, 0x70, 0xFA, 0xD3, -0x80, 0x01, 0xC3, 0x74, 0x03, 0x90, 0xFE, 0x1C, -0xF0, 0x74, 0x00, 0x90, 0xFE, 0x1D, 0xF0, 0x90, -0xFE, 0x1E, 0xF0, 0x90, 0xFE, 0x1F, 0xF0, 0x78, -0x10, 0x79, 0x50, 0x7A, 0x00, 0x7B, 0x00, 0x7C, -0x00, 0x7D, 0x04, 0x12, 0xE0, 0xB0, 0x50, 0x03, -0x02, 0xE3, 0x17, 0x90, 0xFE, 0x07, 0xE0, 0xC2, -0xE6, 0xF0, 0x90, 0xFE, 0x07, 0xE0, 0xD2, 0xE0, -0xF0, 0x90, 0xFE, 0x05, 0xE0, 0xD2, 0xE7, 0xF0, -0x7B, 0x55, 0x7C, 0xAA, 0x7D, 0xAA, 0x7E, 0x55, -0x12, 0xE3, 0x35, 0x50, 0x05, 0x75, 0x08, 0x02, -0x41, 0xB0, 0x90, 0xFE, 0x07, 0xE0, 0x54, 0xBE, -0xF0, 0x90, 0xFE, 0x05, 0xE0, 0x44, 0x40, 0xF0, -0x90, 0xFE, 0x04, 0xE0, 0x44, 0x06, 0xF0, 0x90, -0xFE, 0x04, 0x30, 0x14, 0x06, 0xE0, 0x70, 0xFA, -0xD3, 0x80, 0x01, 0xC3, 0x7B, 0x5A, 0x7C, 0x5A, -0x7D, 0xA5, 0x7E, 0x00, 0x12, 0xE3, 0x35, 0x50, -0x05, 0x75, 0x08, 0x01, 0x41, 0xB0, 0x90, 0xFE, -0x05, 0xE0, 0x54, 0xBF, 0xF0, 0x02, 0xE3, 0x17, -0x90, 0xFE, 0x04, 0xE0, 0x44, 0x06, 0xF0, 0x90, -0xFE, 0x04, 0x30, 0x14, 0x06, 0xE0, 0x70, 0xFA, -0xD3, 0x80, 0x01, 0xC3, 0xE5, 0x08, 0x78, 0x86, -0x79, 0x50, 0x7A, 0x03, 0x7B, 0xB7, 0xFC, 0x7D, -0x00, 0x12, 0xE0, 0xB0, 0x50, 0x03, 0x02, 0xE3, -0x17, 0x78, 0x86, 0x79, 0x50, 0x7A, 0x03, 0x7B, -0xB9, 0x7C, 0x01, 0x7D, 0x00, 0x12, 0xE0, 0xB0, -0x40, 0xBC, 0xE5, 0x09, 0x20, 0xE1, 0x04, 0x74, -0x94, 0x80, 0x02, 0x74, 0x84, 0x90, 0xFF, 0x81, -0xF0, 0x90, 0xFE, 0x07, 0xE0, 0xD2, 0xE6, 0xF0, -0x90, 0xFF, 0x85, 0xE0, 0x54, 0xCF, 0x44, 0x30, -0xF0, 0x90, 0xFF, 0x81, 0xE0, 0xD2, 0xE3, 0xF0, -0x7F, 0x32, 0x7E, 0x00, 0x12, 0xE5, 0x84, 0x90, -0xFE, 0x06, 0xE0, 0x54, 0x3F, 0x44, 0x40, 0xF0, -0x90, 0xFE, 0x04, 0xE0, 0x44, 0x06, 0xF0, 0x90, -0xFE, 0x04, 0x30, 0x14, 0x06, 0xE0, 0x70, 0xFA, -0xD3, 0x80, 0x01, 0xC3, 0x22, 0xC0, 0x05, 0xC0, -0x06, 0x78, 0x13, 0x79, 0x68, 0x12, 0xE0, 0xB0, -0x50, 0x03, 0x02, 0xE3, 0x8B, 0xEB, 0x90, 0xFE, -0x00, 0xF0, 0xEC, 0xF0, 0x90, 0xFE, 0x12, 0xE0, -0x30, 0xE1, 0xF9, 0x90, 0xFE, 0x04, 0xE0, 0x44, -0x06, 0xF0, 0x90, 0xFE, 0x04, 0x30, 0x14, 0x06, -0xE0, 0x70, 0xFA, 0xD3, 0x80, 0x01, 0xC3, 0x78, -0x0E, 0x79, 0xE8, 0x12, 0xE0, 0xB0, 0x50, 0x03, -0x02, 0xE3, 0x8B, 0x90, 0xFE, 0x12, 0xE0, 0x20, -0xE1, 0xF9, 0xD0, 0x06, 0xD0, 0x05, 0x90, 0xFE, -0x00, 0xE0, 0x6D, 0x70, 0x06, 0xE0, 0x6E, 0x70, -0x02, 0xD3, 0x22, 0xC3, 0x22, 0x90, 0xFE, 0x06, -0xE0, 0x54, 0x3F, 0x44, 0x00, 0xF0, 0x90, 0xFE, -0x04, 0xE0, 0x44, 0x06, 0xF0, 0x90, 0xFE, 0x04, -0x30, 0x14, 0x06, 0xE0, 0x70, 0xFA, 0xD3, 0x80, -0x01, 0xC3, 0x74, 0x07, 0x90, 0xFE, 0x1C, 0xF0, -0x74, 0x00, 0x90, 0xFE, 0x1D, 0xF0, 0x90, 0xFE, -0x1E, 0xF0, 0x90, 0xFE, 0x1F, 0xF0, 0x78, 0x10, -0x79, 0x50, 0x7A, 0x00, 0x7B, 0x00, 0x30, 0x17, -0x06, 0x7C, 0x02, 0x7D, 0x00, 0x80, 0x04, 0x7C, -0x00, 0x7D, 0x08, 0x12, 0xE0, 0xB0, 0x50, 0x03, -0x02, 0xE4, 0x39, 0x78, 0x37, 0x79, 0x50, 0x90, -0xEB, 0xFA, 0xE0, 0xFA, 0x90, 0xEB, 0xF9, 0xE0, -0xFB, 0x7C, 0x00, 0x7D, 0x00, 0x12, 0xE0, 0xB0, -0x50, 0x03, 0x02, 0xE4, 0x39, 0x78, 0x73, 0x79, -0xE8, 0x7A, 0x00, 0x7B, 0x00, 0x7C, 0x00, 0x7D, -0x00, 0x12, 0xE0, 0xB0, 0x50, 0x03, 0x02, 0xE4, -0x39, 0x90, 0xFE, 0x12, 0xE0, 0x20, 0xE1, 0xF9, -0x78, 0x08, 0x90, 0xEA, 0x3F, 0xC0, 0x83, 0xC0, -0x82, 0x90, 0xFE, 0x00, 0xE0, 0xD0, 0x82, 0xD0, -0x83, 0xF0, 0xC3, 0xE5, 0x82, 0x24, 0xFF, 0xF5, -0x82, 0xE5, 0x83, 0x34, 0xFF, 0xF5, 0x83, 0xD8, -0xE4, 0x90, 0xEA, 0x3F, 0xE0, 0x54, 0x0F, 0x70, -0x25, 0x90, 0xFE, 0x07, 0xE0, 0xC2, 0xE6, 0xF0, -0x90, 0xFE, 0x06, 0xE0, 0x54, 0x3F, 0x44, 0x40, -0xF0, 0x90, 0xFE, 0x04, 0xE0, 0x44, 0x06, 0xF0, -0x90, 0xFE, 0x04, 0x30, 0x14, 0x06, 0xE0, 0x70, -0xFA, 0xD3, 0x80, 0x01, 0xC3, 0x22, 0x90, 0xFE, -0x06, 0xE0, 0x54, 0x3F, 0x44, 0x40, 0xF0, 0x90, -0xFE, 0x04, 0xE0, 0x44, 0x06, 0xF0, 0x90, 0xFE, -0x04, 0x30, 0x14, 0x06, 0xE0, 0x70, 0xFA, 0xD3, -0x80, 0x01, 0xC3, 0x7E, 0x00, 0x12, 0xE4, 0xBF, -0x40, 0x03, 0x02, 0xE4, 0xBE, 0x7E, 0x80, 0x12, -0xE4, 0xBF, 0x40, 0x03, 0x02, 0xE4, 0xBE, 0x90, -0xFF, 0x81, 0xE0, 0xC2, 0xE3, 0xF0, 0x90, 0xFF, -0x81, 0x74, 0x84, 0xF0, 0x90, 0xFE, 0x07, 0xE0, -0xD2, 0xE6, 0xF0, 0x90, 0xFF, 0x81, 0xE0, 0xD2, -0xE3, 0xF0, 0x90, 0xFE, 0x04, 0xE0, 0x44, 0x06, -0xF0, 0x90, 0xFE, 0x04, 0x30, 0x14, 0x06, 0xE0, -0x70, 0xFA, 0xD3, 0x80, 0x01, 0xC3, 0x22, 0x90, -0xFE, 0x1C, 0x74, 0x3F, 0xF0, 0x90, 0xFE, 0x1D, -0x74, 0x00, 0xF0, 0x74, 0x00, 0x90, 0xFE, 0x1E, -0xF0, 0x90, 0xFE, 0x1F, 0xF0, 0x90, 0xFE, 0xCC, -0xE0, 0x54, 0x7F, 0xF0, 0x90, 0xFE, 0x06, 0xE0, -0x54, 0xF0, 0xF0, 0x90, 0xFE, 0xC0, 0x74, 0xF4, -0xF0, 0xA3, 0x74, 0x00, 0xF0, 0x90, 0xFE, 0xC6, -0x74, 0x00, 0xF0, 0xA3, 0x74, 0x3F, 0xF0, 0x90, -0xFE, 0xC5, 0xE4, 0xF0, 0x90, 0xFE, 0xC4, 0x74, -0x04, 0xF0, 0x78, 0x06, 0x79, 0xE8, 0xAA, 0x06, -0x7B, 0xFF, 0x7C, 0xFF, 0x7D, 0x01, 0x12, 0xE0, -0xB0, 0x50, 0x03, 0x02, 0xE5, 0x5B, 0x90, 0xFE, -0xC8, 0x74, 0x01, 0xF0, 0x90, 0xFE, 0xC4, 0xE0, -0x44, 0x01, 0xF0, 0x30, 0x14, 0x10, 0x90, 0xFE, -0xC8, 0xE0, 0x64, 0x01, 0x60, 0x11, 0x90, 0xFE, -0x10, 0xE0, 0x54, 0x0A, 0x60, 0xED, 0x90, 0xFE, -0xD8, 0x74, 0x01, 0xF0, 0xC3, 0x80, 0x01, 0xD3, -0x40, 0x03, 0x02, 0xE5, 0x5B, 0x90, 0xFE, 0xCC, -0xE0, 0x44, 0x80, 0xF0, 0x90, 0xF4, 0x0D, 0xE0, -0x90, 0xF4, 0x10, 0xE0, 0x64, 0x0F, 0x60, 0x03, -0xD3, 0x80, 0x01, 0xC3, 0x22, 0xC0, 0x04, 0xC0, -0x05, 0x8E, 0x83, 0x8F, 0x82, 0xEB, 0x60, 0x17, -0xC0, 0x82, 0xC0, 0x83, 0x8C, 0x83, 0x8D, 0x82, -0xE0, 0xA3, 0xAC, 0x83, 0xAD, 0x82, 0xD0, 0x83, -0xD0, 0x82, 0xF0, 0xA3, 0x1B, 0x80, 0xE6, 0xD0, -0x05, 0xD0, 0x04, 0x22, 0x75, 0x8A, 0x00, 0x75, -0x8C, 0xCE, 0xC2, 0x8D, 0x90, 0xEA, 0x65, 0xE4, -0xF0, 0xA3, 0xF0, 0xD2, 0x8C, 0x90, 0xEA, 0x65, -0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xEC, 0xC3, 0x9E, -0x40, 0xF3, 0x70, 0x05, 0xED, 0xC3, 0x9F, 0x40, -0xEC, 0xC2, 0x8C, 0x22, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x53, 0x44, 0x2D, 0x49, 0x6E, 0x69, 0x74, 0x32, -0x20, 0x20, 0x20, 0x31, 0x30, 0x30, 0x30, 0x31 }; - -BYTE SD_Rdwr[] = { -0x90, 0xF0, 0x11, 0xE0, 0x90, 0xEB, 0x2A, 0xF0, -0x90, 0xF0, 0x12, 0xE0, 0x90, 0xEB, 0x2B, 0xF0, -0x90, 0xF0, 0x13, 0xE0, 0x90, 0xEB, 0x2C, 0xF0, -0x90, 0xF0, 0x14, 0xE0, 0x90, 0xEB, 0x2D, 0xF0, -0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE0, 0x92, 0x14, -0x30, 0x14, 0x3E, 0x30, 0x0F, 0x3B, 0x90, 0xEB, -0x2A, 0xE0, 0xF5, 0x10, 0xA3, 0xE0, 0xF5, 0x11, -0xA3, 0xE0, 0xF5, 0x12, 0xA3, 0xE0, 0xF5, 0x13, -0xC3, 0xE5, 0x3D, 0x13, 0xF5, 0x14, 0xE5, 0x3E, -0x13, 0xF5, 0x15, 0x85, 0x14, 0x16, 0x85, 0x15, -0x17, 0x90, 0xF0, 0x0C, 0xE0, 0x54, 0x80, 0x70, -0x12, 0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE1, 0x06, -0x90, 0xFF, 0x23, 0x74, 0x80, 0xF0, 0x02, 0xE2, -0x31, 0xC3, 0x22, 0x90, 0xFF, 0x09, 0xE0, 0x30, -0xE1, 0x06, 0x90, 0xFF, 0x23, 0x74, 0x80, 0xF0, -0xE5, 0x15, 0x24, 0xFF, 0x90, 0xFE, 0x1E, 0xF0, -0xE5, 0x14, 0x34, 0xFF, 0x90, 0xFE, 0x1F, 0xF0, -0x90, 0xFE, 0x1C, 0x74, 0xFF, 0xF0, 0x90, 0xFE, -0x1D, 0x74, 0x01, 0xF0, 0x90, 0xFE, 0xCC, 0xE0, -0x54, 0x7F, 0xF0, 0x90, 0xFE, 0x06, 0xE0, 0x54, -0xF0, 0xF0, 0x90, 0xFE, 0xC0, 0x74, 0xF4, 0xF0, -0xA3, 0x74, 0x00, 0xF0, 0x90, 0xFE, 0xC6, 0x74, -0x01, 0xF0, 0xA3, 0x74, 0xFF, 0xF0, 0x90, 0xFE, -0xC5, 0xE4, 0xF0, 0x90, 0xFE, 0xC4, 0x74, 0x04, -0xF0, 0x78, 0x10, 0x79, 0x50, 0x7A, 0x00, 0x7B, -0x00, 0x7C, 0x02, 0x7D, 0x00, 0x12, 0xE3, 0xEA, -0x50, 0x03, 0x02, 0xE1, 0xFA, 0x12, 0xE4, 0x44, -0x50, 0x03, 0x02, 0xE1, 0xFA, 0xAD, 0x13, 0xAC, -0x12, 0xAB, 0x11, 0xAA, 0x10, 0x80, 0x00, 0xE5, -0x15, 0x64, 0x01, 0x45, 0x14, 0x70, 0x0E, 0x78, -0x11, 0x79, 0xE8, 0x12, 0xE3, 0xEA, 0x50, 0x03, -0x02, 0xE1, 0xFA, 0x80, 0x0C, 0x78, 0x12, 0x79, -0xE8, 0x12, 0xE3, 0xEA, 0x50, 0x03, 0x02, 0xE1, -0xFA, 0x12, 0xE4, 0x44, 0x50, 0x03, 0x02, 0xE1, -0xFA, 0x30, 0x14, 0x07, 0x90, 0xFE, 0x12, 0xE0, -0x30, 0xE4, 0xF6, 0x20, 0x14, 0x03, 0x02, 0xE1, -0xFA, 0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE5, 0xFC, -0x90, 0xFE, 0xC8, 0x74, 0x01, 0xF0, 0x90, 0xFE, -0xC4, 0xE0, 0x44, 0x01, 0xF0, 0xC3, 0xE5, 0x17, -0x94, 0x01, 0xF5, 0x17, 0xE5, 0x16, 0x94, 0x00, -0xF5, 0x16, 0x45, 0x17, 0x60, 0x42, 0x30, 0x14, -0x10, 0x90, 0xFE, 0xC8, 0xE0, 0x64, 0x01, 0x60, -0x11, 0x90, 0xFE, 0x10, 0xE0, 0x54, 0x0A, 0x60, -0xED, 0x90, 0xFE, 0xD8, 0x74, 0x01, 0xF0, 0xC3, -0x80, 0x01, 0xD3, 0x40, 0x03, 0x02, 0xE1, 0xFA, -0x90, 0xFF, 0x2A, 0x74, 0x02, 0xF0, 0xA3, 0x74, -0x00, 0xF0, 0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE5, -0xFC, 0x90, 0xFE, 0xC8, 0x74, 0x01, 0xF0, 0x90, -0xFE, 0xC4, 0xE0, 0x44, 0x01, 0xF0, 0x80, 0xAD, -0x30, 0x14, 0x10, 0x90, 0xFE, 0xC8, 0xE0, 0x64, -0x01, 0x60, 0x11, 0x90, 0xFE, 0x10, 0xE0, 0x54, -0x0A, 0x60, 0xED, 0x90, 0xFE, 0xD8, 0x74, 0x01, -0xF0, 0xC3, 0x80, 0x01, 0xD3, 0x40, 0x03, 0x02, -0xE1, 0xFA, 0x90, 0xFF, 0x2A, 0x74, 0x02, 0xF0, -0xA3, 0x74, 0x00, 0xF0, 0xE5, 0x15, 0x64, 0x01, -0x45, 0x14, 0x60, 0x29, 0x90, 0xFF, 0x09, 0xE0, -0x30, 0xE5, 0xFC, 0x78, 0x8C, 0x79, 0x50, 0x12, -0xE3, 0xEA, 0x50, 0x03, 0x02, 0xE1, 0xFA, 0x12, -0xE4, 0x44, 0x50, 0x11, 0x90, 0xFE, 0x22, 0xE0, -0x70, 0x20, 0x90, 0xFE, 0x23, 0xE0, 0x64, 0x80, -0x60, 0x03, 0x02, 0xE1, 0xFA, 0x90, 0xFE, 0xCC, -0xE0, 0x44, 0x80, 0xF0, 0x75, 0x3C, 0x00, 0x75, -0x3D, 0x00, 0x75, 0x3E, 0x00, 0x75, 0x3F, 0x00, -0xD3, 0x22, 0x30, 0x14, 0x14, 0x90, 0xFE, 0x04, -0xE0, 0x44, 0x06, 0xF0, 0x90, 0xFE, 0x04, 0x30, -0x14, 0x06, 0xE0, 0x70, 0xFA, 0xD3, 0x80, 0x01, -0xC3, 0x90, 0xFE, 0xD8, 0x74, 0x01, 0xF0, 0x90, -0xFE, 0xCC, 0xE0, 0x44, 0x80, 0xF0, 0x75, 0x3F, -0x00, 0xC3, 0xE5, 0x17, 0x33, 0xF5, 0x3E, 0xE5, -0x16, 0x33, 0xF5, 0x3D, 0x75, 0x3C, 0x00, 0xC3, -0x22, 0xE5, 0x3E, 0x54, 0x01, 0x45, 0x3F, 0x60, -0x03, 0x02, 0xE0, 0x69, 0xE5, 0x15, 0x24, 0xFF, -0x90, 0xFE, 0x1E, 0xF0, 0xE5, 0x14, 0x34, 0xFF, -0x90, 0xFE, 0x1F, 0xF0, 0x90, 0xFE, 0x1C, 0x74, -0xFF, 0xF0, 0x90, 0xFE, 0x1D, 0x74, 0x01, 0xF0, -0x90, 0xFE, 0x06, 0xE0, 0x54, 0xF0, 0x44, 0x0F, -0xF0, 0x90, 0xFE, 0xC0, 0x74, 0xF0, 0xF0, 0xA3, -0x74, 0x00, 0xF0, 0xE5, 0x4D, 0x24, 0xFF, 0xFF, -0xE5, 0x4C, 0x34, 0xFF, 0x90, 0xFE, 0xC6, 0xF0, -0xA3, 0xEF, 0xF0, 0xE4, 0x90, 0xFE, 0xC5, 0xF0, -0x74, 0x06, 0x90, 0xFE, 0xC4, 0xF0, 0x90, 0xFE, -0xCC, 0xE0, 0x54, 0x7F, 0xF0, 0x78, 0x10, 0x79, -0x50, 0x7A, 0x00, 0x7B, 0x00, 0x7C, 0x02, 0x7D, -0x00, 0x12, 0xE3, 0xEA, 0x50, 0x03, 0x02, 0xE3, -0x9E, 0x12, 0xE4, 0x44, 0x50, 0x03, 0x02, 0xE3, -0x9E, 0xAD, 0x13, 0xAC, 0x12, 0xAB, 0x11, 0xAA, -0x10, 0x80, 0x10, 0x74, 0x00, 0xFD, 0xC3, 0xE5, -0x13, 0x33, 0xFC, 0xE5, 0x12, 0x33, 0xFB, 0xE5, -0x11, 0x33, 0xFA, 0xE5, 0x15, 0x64, 0x01, 0x45, -0x14, 0x70, 0x0E, 0x78, 0x18, 0x79, 0x68, 0x12, -0xE3, 0xEA, 0x50, 0x03, 0x02, 0xE3, 0x9E, 0x80, -0x0C, 0x78, 0x19, 0x79, 0x68, 0x12, 0xE3, 0xEA, -0x50, 0x03, 0x02, 0xE3, 0x9E, 0x12, 0xE4, 0x44, -0x50, 0x03, 0x02, 0xE3, 0x9E, 0x75, 0x1F, 0x01, -0x20, 0x2D, 0x03, 0x75, 0x1F, 0x08, 0xE5, 0x16, -0x45, 0x17, 0x70, 0x03, 0x02, 0xE3, 0x6B, 0x85, -0x1F, 0x1E, 0x30, 0x14, 0x3C, 0x90, 0xFF, 0x09, -0x30, 0x14, 0x04, 0xE0, 0x30, 0xE1, 0xF9, 0x90, -0xFE, 0xC8, 0x74, 0x01, 0xF0, 0x90, 0xFE, 0xC4, -0xE0, 0x44, 0x01, 0xF0, 0x30, 0x14, 0x10, 0x90, -0xFE, 0xC8, 0xE0, 0x64, 0x01, 0x60, 0x11, 0x90, -0xFE, 0x10, 0xE0, 0x54, 0x0A, 0x60, 0xED, 0x90, -0xFE, 0xD8, 0x74, 0x01, 0xF0, 0xC3, 0x80, 0x01, -0xD3, 0x40, 0x03, 0x02, 0xE3, 0x9E, 0x90, 0xFE, -0x12, 0x30, 0x14, 0x2A, 0xE0, 0x30, 0xE1, 0xF9, -0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE1, 0x06, 0x90, -0xFF, 0x23, 0x74, 0x80, 0xF0, 0x15, 0x1E, 0xE5, -0x1E, 0x70, 0xA7, 0xC3, 0xE5, 0x17, 0x94, 0x01, -0xF5, 0x17, 0xE5, 0x16, 0x94, 0x00, 0xF5, 0x16, -0x02, 0xE2, 0xF6, 0x90, 0xFE, 0x12, 0x30, 0x14, -0x2D, 0xE0, 0x20, 0xE4, 0xF9, 0xE5, 0x15, 0x64, -0x01, 0x45, 0x14, 0x60, 0x58, 0x78, 0x8C, 0x79, -0x50, 0x12, 0xE3, 0xEA, 0x50, 0x03, 0x02, 0xE3, -0x9E, 0x12, 0xE4, 0x44, 0x50, 0x03, 0x02, 0xE3, -0x9E, 0x30, 0x14, 0x41, 0x90, 0xFE, 0x12, 0xE0, -0x20, 0xE4, 0xF6, 0x02, 0xE3, 0xD5, 0x30, 0x14, -0x14, 0x90, 0xFE, 0x04, 0xE0, 0x44, 0x06, 0xF0, -0x90, 0xFE, 0x04, 0x30, 0x14, 0x06, 0xE0, 0x70, -0xFA, 0xD3, 0x80, 0x01, 0xC3, 0x90, 0xFE, 0xD8, -0x74, 0x01, 0xF0, 0x90, 0xFE, 0xCC, 0xE0, 0x44, -0x80, 0xF0, 0x75, 0x3F, 0x00, 0xC3, 0xE5, 0x17, -0x33, 0xF5, 0x3E, 0xE5, 0x16, 0x33, 0xF5, 0x3D, -0x75, 0x3C, 0x00, 0xC3, 0x22, 0x90, 0xFE, 0xCC, -0xE0, 0x44, 0x80, 0xF0, 0x75, 0x3C, 0x00, 0x75, -0x3D, 0x00, 0x75, 0x3E, 0x00, 0x75, 0x3F, 0x00, -0xD3, 0x22, 0xE8, 0x90, 0xFE, 0x15, 0xF0, 0xE9, -0x90, 0xFE, 0x14, 0xF0, 0xED, 0x90, 0xFE, 0x18, -0xF0, 0xEC, 0x90, 0xFE, 0x19, 0xF0, 0xEB, 0x90, -0xFE, 0x1A, 0xF0, 0xEA, 0x90, 0xFE, 0x1B, 0xF0, -0x74, 0xFF, 0x90, 0xFE, 0x10, 0xF0, 0x90, 0xFE, -0x11, 0xF0, 0x90, 0xFE, 0x12, 0xF0, 0xE8, 0x54, -0x80, 0xFE, 0x90, 0xFE, 0x04, 0x74, 0x01, 0xF0, -0x30, 0x14, 0x08, 0x90, 0xFE, 0x10, 0xE0, 0x54, -0x05, 0x60, 0x02, 0xD3, 0x22, 0x90, 0xFE, 0x11, -0xE0, 0x30, 0xE0, 0xEC, 0xBE, 0x80, 0x03, 0x30, -0xE1, 0xE6, 0x90, 0xFE, 0x10, 0xE0, 0x54, 0x05, -0x70, 0xE9, 0xC3, 0x22, 0x30, 0x13, 0x02, 0xC3, -0x22, 0x90, 0xFE, 0x22, 0xE0, 0x70, 0x06, 0x90, -0xFE, 0x23, 0xE0, 0x60, 0x02, 0xD3, 0x22, 0xC3, -0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x53, 0x44, 0x2D, 0x52, 0x57, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x31, 0x30, 0x30, 0x30, 0x31 }; BYTE MS_Init[] = { 0x90, 0xF0, 0x15, 0xE0, 0xF5, 0x1C, 0x11, 0x2C, diff --git a/drivers/staging/keucr/sdscsi.c b/drivers/staging/keucr/sdscsi.c deleted file mode 100644 index d646507a3611..000000000000 --- a/drivers/staging/keucr/sdscsi.c +++ /dev/null @@ -1,210 +0,0 @@ -#include -#include -#include - -#include -#include -#include - -#include "usb.h" -#include "scsiglue.h" -#include "transport.h" - -int SD_SCSI_Test_Unit_Ready (struct us_data *us, struct scsi_cmnd *srb); -int SD_SCSI_Inquiry (struct us_data *us, struct scsi_cmnd *srb); -int SD_SCSI_Mode_Sense (struct us_data *us, struct scsi_cmnd *srb); -int SD_SCSI_Start_Stop (struct us_data *us, struct scsi_cmnd *srb); -int SD_SCSI_Read_Capacity (struct us_data *us, struct scsi_cmnd *srb); -int SD_SCSI_Read (struct us_data *us, struct scsi_cmnd *srb); -int SD_SCSI_Write (struct us_data *us, struct scsi_cmnd *srb); - -//----- SD_SCSIIrp() -------------------------------------------------- -int SD_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb) -{ - int result; - - us->SrbStatus = SS_SUCCESS; - switch (srb->cmnd[0]) - { - case TEST_UNIT_READY : result = SD_SCSI_Test_Unit_Ready (us, srb); break; //0x00 - case INQUIRY : result = SD_SCSI_Inquiry (us, srb); break; //0x12 - case MODE_SENSE : result = SD_SCSI_Mode_Sense (us, srb); break; //0x1A -// case START_STOP : result = SD_SCSI_Start_Stop (us, srb); break; //0x1B - case READ_CAPACITY : result = SD_SCSI_Read_Capacity (us, srb); break; //0x25 - case READ_10 : result = SD_SCSI_Read (us, srb); break; //0x28 - case WRITE_10 : result = SD_SCSI_Write (us, srb); break; //0x2A - - default: - us->SrbStatus = SS_ILLEGAL_REQUEST; - result = USB_STOR_TRANSPORT_FAILED; - break; - } - return result; -} - -//----- SD_SCSI_Test_Unit_Ready() -------------------------------------------------- -int SD_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb) -{ - //printk("SD_SCSI_Test_Unit_Ready\n"); - if (us->SD_Status.Insert && us->SD_Status.Ready) - return USB_STOR_TRANSPORT_GOOD; - else - { - ENE_SDInit(us); - return USB_STOR_TRANSPORT_GOOD; - } - - return USB_STOR_TRANSPORT_GOOD; -} - -//----- SD_SCSI_Inquiry() -------------------------------------------------- -int SD_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb) -{ - //printk("SD_SCSI_Inquiry\n"); - BYTE data_ptr[36] = {0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55, 0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30}; - - usb_stor_set_xfer_buf(us, data_ptr, 36, srb, TO_XFER_BUF); - return USB_STOR_TRANSPORT_GOOD; -} - - -//----- SD_SCSI_Mode_Sense() -------------------------------------------------- -int SD_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb) -{ - BYTE mediaNoWP[12] = {0x0b,0x00,0x00,0x08,0x00,0x00,0x71,0xc0,0x00,0x00,0x02,0x00}; - BYTE mediaWP[12] = {0x0b,0x00,0x80,0x08,0x00,0x00,0x71,0xc0,0x00,0x00,0x02,0x00}; - - if (us->SD_Status.WtP) - usb_stor_set_xfer_buf(us, mediaWP, 12, srb, TO_XFER_BUF); - else - usb_stor_set_xfer_buf(us, mediaNoWP, 12, srb, TO_XFER_BUF); - - - return USB_STOR_TRANSPORT_GOOD; -} - -//----- SD_SCSI_Read_Capacity() -------------------------------------------------- -int SD_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb) -{ - unsigned int offset = 0; - struct scatterlist *sg = NULL; - DWORD bl_num; - WORD bl_len; - BYTE buf[8]; - - printk("SD_SCSI_Read_Capacity\n"); - if ( us->SD_Status.HiCapacity ) - { - bl_len = 0x200; - if (us->SD_Status.IsMMC) - bl_num = us->HC_C_SIZE-1; - else - bl_num = (us->HC_C_SIZE + 1) * 1024 - 1; - } - else - { - bl_len = 1<<(us->SD_READ_BL_LEN); - bl_num = us->SD_Block_Mult*(us->SD_C_SIZE+1)*(1<<(us->SD_C_SIZE_MULT+2)) - 1; - } - us->bl_num = bl_num; - printk("bl_len = %x\n", bl_len); - printk("bl_num = %x\n", bl_num); - - //srb->request_bufflen = 8; - buf[0] = (bl_num>>24) & 0xff; - buf[1] = (bl_num>>16) & 0xff; - buf[2] = (bl_num>> 8) & 0xff; - buf[3] = (bl_num>> 0) & 0xff; - buf[4] = (bl_len>>24) & 0xff; - buf[5] = (bl_len>>16) & 0xff; - buf[6] = (bl_len>> 8) & 0xff; - buf[7] = (bl_len>> 0) & 0xff; - - usb_stor_access_xfer_buf(us, buf, 8, srb, &sg, &offset, TO_XFER_BUF); - //usb_stor_set_xfer_buf(us, buf, srb->request_bufflen, srb, TO_XFER_BUF); - - return USB_STOR_TRANSPORT_GOOD; -} - -//----- SD_SCSI_Read() -------------------------------------------------- -int SD_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb) -{ - struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; - int result; - PBYTE Cdb = srb->cmnd; - DWORD bn = ((Cdb[2]<<24) & 0xff000000) | ((Cdb[3]<<16) & 0x00ff0000) | - ((Cdb[4]<< 8) & 0x0000ff00) | ((Cdb[5]<< 0) & 0x000000ff); - WORD blen = ((Cdb[7]<< 8) & 0xff00) | ((Cdb[8]<< 0) & 0x00ff); - DWORD bnByte = bn * 0x200; - DWORD blenByte = blen * 0x200; - - if (bn > us->bl_num) - return USB_STOR_TRANSPORT_ERROR; - - result = ENE_LoadBinCode(us, SD_RW_PATTERN); - if (result != USB_STOR_XFER_GOOD) - { - printk("Load SD RW pattern Fail !!\n"); - return USB_STOR_TRANSPORT_ERROR; - } - - if ( us->SD_Status.HiCapacity ) - bnByte = bn; - - // set up the command wrapper - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); - bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcb->DataTransferLength = blenByte; - bcb->Flags = 0x80; - bcb->CDB[0] = 0xF1; - bcb->CDB[5] = (BYTE)(bnByte); - bcb->CDB[4] = (BYTE)(bnByte>>8); - bcb->CDB[3] = (BYTE)(bnByte>>16); - bcb->CDB[2] = (BYTE)(bnByte>>24); - - result = ENE_SendScsiCmd(us, FDIR_READ, scsi_sglist(srb), 1); - return result; -} - -//----- SD_SCSI_Write() -------------------------------------------------- -int SD_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb) -{ - struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; - int result; - PBYTE Cdb = srb->cmnd; - DWORD bn = ((Cdb[2]<<24) & 0xff000000) | ((Cdb[3]<<16) & 0x00ff0000) | - ((Cdb[4]<< 8) & 0x0000ff00) | ((Cdb[5]<< 0) & 0x000000ff); - WORD blen = ((Cdb[7]<< 8) & 0xff00) | ((Cdb[8]<< 0) & 0x00ff); - DWORD bnByte = bn * 0x200; - DWORD blenByte = blen * 0x200; - - if (bn > us->bl_num) - return USB_STOR_TRANSPORT_ERROR; - - result = ENE_LoadBinCode(us, SD_RW_PATTERN); - if (result != USB_STOR_XFER_GOOD) - { - printk("Load SD RW pattern Fail !!\n"); - return USB_STOR_TRANSPORT_ERROR; - } - - if ( us->SD_Status.HiCapacity ) - bnByte = bn; - - // set up the command wrapper - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); - bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcb->DataTransferLength = blenByte; - bcb->Flags = 0x00; - bcb->CDB[0] = 0xF0; - bcb->CDB[5] = (BYTE)(bnByte); - bcb->CDB[4] = (BYTE)(bnByte>>8); - bcb->CDB[3] = (BYTE)(bnByte>>16); - bcb->CDB[2] = (BYTE)(bnByte>>24); - - result = ENE_SendScsiCmd(us, FDIR_WRITE, scsi_sglist(srb), 1); - return result; -} - - - diff --git a/drivers/staging/keucr/transport.c b/drivers/staging/keucr/transport.c index 111160cce441..a53402f36044 100644 --- a/drivers/staging/keucr/transport.c +++ b/drivers/staging/keucr/transport.c @@ -413,7 +413,7 @@ void ENE_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) usb_stor_print_cmd(srb); /* send the command to the transport layer */ scsi_set_resid(srb, 0); - if ( !(us->SD_Status.Ready || us->MS_Status.Ready || us->SM_Status.Ready) ) + if (!(us->MS_Status.Ready || us->SM_Status.Ready)) result = ENE_InitMedia(us); if (us->Power_IsResum == true) { @@ -421,7 +421,6 @@ void ENE_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) us->Power_IsResum = false; } - if (us->SD_Status.Ready) result = SD_SCSIIrp(us, srb); if (us->MS_Status.Ready) result = MS_SCSIIrp(us, srb); if (us->SM_Status.Ready) result = SM_SCSIIrp(us, srb); diff --git a/drivers/staging/keucr/transport.h b/drivers/staging/keucr/transport.h index ae9b5ee8a0cc..565d98c98454 100644 --- a/drivers/staging/keucr/transport.h +++ b/drivers/staging/keucr/transport.h @@ -92,10 +92,8 @@ extern void usb_stor_set_xfer_buf(struct us_data*, unsigned char *buffer, unsign // ENE scsi function extern void ENE_stor_invoke_transport(struct scsi_cmnd *, struct us_data*); extern int ENE_InitMedia(struct us_data*); -extern int ENE_SDInit(struct us_data*); extern int ENE_MSInit(struct us_data*); extern int ENE_SMInit(struct us_data*); -extern int ENE_ReadSDReg(struct us_data*, u8*); extern int ENE_SendScsiCmd(struct us_data*, BYTE, void*, int); extern int ENE_LoadBinCode(struct us_data*, BYTE); extern int ENE_Read_BYTE(struct us_data*, WORD index, void *buf); @@ -104,7 +102,6 @@ extern int ENE_Write_Data(struct us_data*, void *buf, unsigned int length); extern void BuildSenseBuffer(struct scsi_cmnd *, int); // ENE scsi function -extern int SD_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb); extern int MS_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb); extern int SM_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb); diff --git a/drivers/staging/keucr/usb.c b/drivers/staging/keucr/usb.c index c65b988264cc..8c2332ec4f5c 100644 --- a/drivers/staging/keucr/usb.c +++ b/drivers/staging/keucr/usb.c @@ -74,7 +74,6 @@ int eucr_resume(struct usb_interface *iface) us->Power_IsResum = true; // //us->SD_Status.Ready = 0; //?? - us->SD_Status = *(PSD_STATUS)&tmp; us->MS_Status = *(PMS_STATUS)&tmp; us->SM_Status = *(PSM_STATUS)&tmp; @@ -98,7 +97,6 @@ int eucr_reset_resume(struct usb_interface *iface) us->Power_IsResum = true; // //us->SD_Status.Ready = 0; //?? - us->SD_Status = *(PSD_STATUS)&tmp; us->MS_Status = *(PMS_STATUS)&tmp; us->SM_Status = *(PSM_STATUS)&tmp; return 0; @@ -582,6 +580,7 @@ static int eucr_probe(struct usb_interface *intf, const struct usb_device_id *id struct Scsi_Host *host; struct us_data *us; int result; + BYTE MiscReg03 = 0; struct task_struct *th; printk("usb --- eucr_probe\n"); @@ -647,6 +646,24 @@ static int eucr_probe(struct usb_interface *intf, const struct usb_device_id *id goto BadDevice; } wake_up_process(th); + + /* probe card type */ + result = ENE_Read_BYTE(us, REG_CARD_STATUS, &MiscReg03); + if (result != USB_STOR_XFER_GOOD) { + result = USB_STOR_TRANSPORT_ERROR; + quiesce_and_remove_host(us); + goto BadDevice; + } + + if (!(MiscReg03 & 0x02)) { + result = -ENODEV; + quiesce_and_remove_host(us); + printk(KERN_NOTICE "keucr: The driver only supports SM/MS card.\ + To use SD card, \ + please build driver/usb/storage/ums-eneub6250.ko\n"); + goto BadDevice; + } + return 0; /* We come here if there are any problems */ diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index 49a489e03716..72448bac2ee0 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -198,3 +198,17 @@ config USB_LIBUSUAL options libusual bias="ub" If unsure, say N. + +config USB_STORAGE_ENE_UB6250 + tristate "USB ENE card reader support" + depends on USB && SCSI + ---help--- + Say Y here if you wish to control a ENE SD Card reader. + To use SM/MS card, please build driver/staging/keucr/keucr.ko + + This option depends on 'SCSI' support being enabled, but you + probably also need 'SCSI device support: SCSI disk support' + (BLK_DEV_SD) for most USB storage devices. + + To compile this driver as a module, choose M here: the + module will be called ums-eneub6250. diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index fcf14cdc4a04..3055d1a8010a 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile @@ -25,6 +25,7 @@ endif obj-$(CONFIG_USB_STORAGE_ALAUDA) += ums-alauda.o obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += ums-cypress.o obj-$(CONFIG_USB_STORAGE_DATAFAB) += ums-datafab.o +obj-$(CONFIG_USB_STORAGE_ENE_UB6250) += ums-eneub6250.o obj-$(CONFIG_USB_STORAGE_FREECOM) += ums-freecom.o obj-$(CONFIG_USB_STORAGE_ISD200) += ums-isd200.o obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += ums-jumpshot.o @@ -37,6 +38,7 @@ obj-$(CONFIG_USB_STORAGE_USBAT) += ums-usbat.o ums-alauda-y := alauda.o ums-cypress-y := cypress_atacb.o ums-datafab-y := datafab.o +ums-eneub6250-y := ene_ub6250.o ums-freecom-y := freecom.o ums-isd200-y := isd200.o ums-jumpshot-y := jumpshot.o diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c new file mode 100644 index 000000000000..058c5d5f1c1e --- /dev/null +++ b/drivers/usb/storage/ene_ub6250.c @@ -0,0 +1,807 @@ +/* + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include + +#include +#include + +#include + +#include "usb.h" +#include "transport.h" +#include "protocol.h" +#include "debug.h" + +MODULE_DESCRIPTION("Driver for ENE UB6250 reader"); +MODULE_LICENSE("GPL"); + + +/* + * The table of devices + */ +#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ + vendorName, productName, useProtocol, useTransport, \ + initFunction, flags) \ +{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ + .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } + +struct usb_device_id ene_ub6250_usb_ids[] = { +# include "unusual_ene_ub6250.h" + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, ene_ub6250_usb_ids); + +#undef UNUSUAL_DEV + +/* + * The flags table + */ +#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ + vendor_name, product_name, use_protocol, use_transport, \ + init_function, Flags) \ +{ \ + .vendorName = vendor_name, \ + .productName = product_name, \ + .useProtocol = use_protocol, \ + .useTransport = use_transport, \ + .initFunction = init_function, \ +} + +static struct us_unusual_dev ene_ub6250_unusual_dev_list[] = { +# include "unusual_ene_ub6250.h" + { } /* Terminating entry */ +}; + +#undef UNUSUAL_DEV + + + +/* ENE bin code len */ +#define ENE_BIN_CODE_LEN 0x800 +/* EnE HW Register */ +#define REG_CARD_STATUS 0xFF83 +#define REG_HW_TRAP1 0xFF89 + +/* SRB Status */ +#define SS_SUCCESS 0x00 /* No Sense */ +#define SS_NOT_READY 0x02 +#define SS_MEDIUM_ERR 0x03 +#define SS_HW_ERR 0x04 +#define SS_ILLEGAL_REQUEST 0x05 +#define SS_UNIT_ATTENTION 0x06 + +/* ENE Load FW Pattern */ +#define SD_INIT1_PATTERN 1 +#define SD_INIT2_PATTERN 2 +#define SD_RW_PATTERN 3 +#define MS_INIT_PATTERN 4 +#define MSP_RW_PATTERN 5 +#define MS_RW_PATTERN 6 +#define SM_INIT_PATTERN 7 +#define SM_RW_PATTERN 8 + +#define FDIR_WRITE 0 +#define FDIR_READ 1 + + +struct SD_STATUS { + u8 Insert:1; + u8 Ready:1; + u8 MediaChange:1; + u8 IsMMC:1; + u8 HiCapacity:1; + u8 HiSpeed:1; + u8 WtP:1; + u8 Reserved:1; +}; + +struct MS_STATUS { + u8 Insert:1; + u8 Ready:1; + u8 MediaChange:1; + u8 IsMSPro:1; + u8 IsMSPHG:1; + u8 Reserved1:1; + u8 WtP:1; + u8 Reserved2:1; +}; + +struct SM_STATUS { + u8 Insert:1; + u8 Ready:1; + u8 MediaChange:1; + u8 Reserved:3; + u8 WtP:1; + u8 IsMS:1; +}; + + +/* SD Block Length */ +/* 2^9 = 512 Bytes, The HW maximum read/write data length */ +#define SD_BLOCK_LEN 9 + +struct ene_ub6250_info { + /* for 6250 code */ + struct SD_STATUS SD_Status; + struct MS_STATUS MS_Status; + struct SM_STATUS SM_Status; + + /* ----- SD Control Data ---------------- */ + /*SD_REGISTER SD_Regs; */ + u16 SD_Block_Mult; + u8 SD_READ_BL_LEN; + u16 SD_C_SIZE; + u8 SD_C_SIZE_MULT; + + /* SD/MMC New spec. */ + u8 SD_SPEC_VER; + u8 SD_CSD_VER; + u8 SD20_HIGH_CAPACITY; + u32 HC_C_SIZE; + u8 MMC_SPEC_VER; + u8 MMC_BusWidth; + u8 MMC_HIGH_CAPACITY; + + /*----- MS Control Data ---------------- */ + bool MS_SWWP; + u32 MSP_TotalBlock; + /*MS_LibControl MS_Lib;*/ + bool MS_IsRWPage; + u16 MS_Model; + + /*----- SM Control Data ---------------- */ + u8 SM_DeviceID; + u8 SM_CardID; + + unsigned char *testbuf; + u8 BIN_FLAG; + u32 bl_num; + int SrbStatus; + + /*------Power Managerment ---------------*/ + bool Power_IsResum; +}; + +static int ene_sd_init(struct us_data *us); +static int ene_load_bincode(struct us_data *us, unsigned char flag); + +static void ene_ub6250_info_destructor(void *extra) +{ + if (!extra) + return; +} + +static int ene_send_scsi_cmd(struct us_data *us, u8 fDir, void *buf, int use_sg) +{ + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf; + + int result; + unsigned int residue; + unsigned int cswlen = 0, partial = 0; + unsigned int transfer_length = bcb->DataTransferLength; + + /* US_DEBUGP("transport --- ene_send_scsi_cmd\n"); */ + /* send cmd to out endpoint */ + result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, + bcb, US_BULK_CB_WRAP_LEN, NULL); + if (result != USB_STOR_XFER_GOOD) { + US_DEBUGP("send cmd to out endpoint fail ---\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + if (buf) { + unsigned int pipe = fDir; + + if (fDir == FDIR_READ) + pipe = us->recv_bulk_pipe; + else + pipe = us->send_bulk_pipe; + + /* Bulk */ + if (use_sg) { + result = usb_stor_bulk_srb(us, pipe, us->srb); + } else { + result = usb_stor_bulk_transfer_sg(us, pipe, buf, + transfer_length, 0, &partial); + } + if (result != USB_STOR_XFER_GOOD) { + US_DEBUGP("data transfer fail ---\n"); + return USB_STOR_TRANSPORT_ERROR; + } + } + + /* Get CSW for device status */ + result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, + US_BULK_CS_WRAP_LEN, &cswlen); + + if (result == USB_STOR_XFER_SHORT && cswlen == 0) { + US_DEBUGP("Received 0-length CSW; retrying...\n"); + result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, + bcs, US_BULK_CS_WRAP_LEN, &cswlen); + } + + if (result == USB_STOR_XFER_STALLED) { + /* get the status again */ + US_DEBUGP("Attempting to get CSW (2nd try)...\n"); + result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, + bcs, US_BULK_CS_WRAP_LEN, NULL); + } + + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + /* check bulk status */ + residue = le32_to_cpu(bcs->Residue); + + /* try to compute the actual residue, based on how much data + * was really transferred and what the device tells us */ + if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE)) { + residue = min(residue, transfer_length); + if (us->srb != NULL) + scsi_set_resid(us->srb, max(scsi_get_resid(us->srb), + (int)residue)); + } + + if (bcs->Status != US_BULK_STAT_OK) + return USB_STOR_TRANSPORT_ERROR; + + return USB_STOR_TRANSPORT_GOOD; +} + +static int sd_scsi_test_unit_ready(struct us_data *us, struct scsi_cmnd *srb) +{ + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + if (info->SD_Status.Insert && info->SD_Status.Ready) + return USB_STOR_TRANSPORT_GOOD; + else { + ene_sd_init(us); + return USB_STOR_TRANSPORT_GOOD; + } + + return USB_STOR_TRANSPORT_GOOD; +} + +static int sd_scsi_inquiry(struct us_data *us, struct scsi_cmnd *srb) +{ + unsigned char data_ptr[36] = { + 0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55, + 0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61, + 0x72, 0x64, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30 }; + + usb_stor_set_xfer_buf(data_ptr, 36, srb); + return USB_STOR_TRANSPORT_GOOD; +} + +static int sd_scsi_mode_sense(struct us_data *us, struct scsi_cmnd *srb) +{ + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + unsigned char mediaNoWP[12] = { + 0x0b, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00 }; + unsigned char mediaWP[12] = { + 0x0b, 0x00, 0x80, 0x08, 0x00, 0x00, + 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00 }; + + if (info->SD_Status.WtP) + usb_stor_set_xfer_buf(mediaWP, 12, srb); + else + usb_stor_set_xfer_buf(mediaNoWP, 12, srb); + + + return USB_STOR_TRANSPORT_GOOD; +} + +static int sd_scsi_read_capacity(struct us_data *us, struct scsi_cmnd *srb) +{ + u32 bl_num; + u16 bl_len; + unsigned int offset = 0; + unsigned char buf[8]; + struct scatterlist *sg = NULL; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + US_DEBUGP("sd_scsi_read_capacity\n"); + if (info->SD_Status.HiCapacity) { + bl_len = 0x200; + if (info->SD_Status.IsMMC) + bl_num = info->HC_C_SIZE-1; + else + bl_num = (info->HC_C_SIZE + 1) * 1024 - 1; + } else { + bl_len = 1<<(info->SD_READ_BL_LEN); + bl_num = info->SD_Block_Mult * (info->SD_C_SIZE + 1) + * (1 << (info->SD_C_SIZE_MULT + 2)) - 1; + } + info->bl_num = bl_num; + US_DEBUGP("bl_len = %x\n", bl_len); + US_DEBUGP("bl_num = %x\n", bl_num); + + /*srb->request_bufflen = 8; */ + buf[0] = (bl_num >> 24) & 0xff; + buf[1] = (bl_num >> 16) & 0xff; + buf[2] = (bl_num >> 8) & 0xff; + buf[3] = (bl_num >> 0) & 0xff; + buf[4] = (bl_len >> 24) & 0xff; + buf[5] = (bl_len >> 16) & 0xff; + buf[6] = (bl_len >> 8) & 0xff; + buf[7] = (bl_len >> 0) & 0xff; + + usb_stor_access_xfer_buf(buf, 8, srb, &sg, &offset, TO_XFER_BUF); + + return USB_STOR_TRANSPORT_GOOD; +} + +static int sd_scsi_read(struct us_data *us, struct scsi_cmnd *srb) +{ + int result; + unsigned char *cdb = srb->cmnd; + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + u32 bn = ((cdb[2] << 24) & 0xff000000) | ((cdb[3] << 16) & 0x00ff0000) | + ((cdb[4] << 8) & 0x0000ff00) | ((cdb[5] << 0) & 0x000000ff); + u16 blen = ((cdb[7] << 8) & 0xff00) | ((cdb[8] << 0) & 0x00ff); + u32 bnByte = bn * 0x200; + u32 blenByte = blen * 0x200; + + if (bn > info->bl_num) + return USB_STOR_TRANSPORT_ERROR; + + result = ene_load_bincode(us, SD_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) { + US_DEBUGP("Load SD RW pattern Fail !!\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + if (info->SD_Status.HiCapacity) + bnByte = bn; + + /* set up the command wrapper */ + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = blenByte; + bcb->Flags = 0x80; + bcb->CDB[0] = 0xF1; + bcb->CDB[5] = (unsigned char)(bnByte); + bcb->CDB[4] = (unsigned char)(bnByte>>8); + bcb->CDB[3] = (unsigned char)(bnByte>>16); + bcb->CDB[2] = (unsigned char)(bnByte>>24); + + result = ene_send_scsi_cmd(us, FDIR_READ, scsi_sglist(srb), 1); + return result; +} + +static int sd_scsi_write(struct us_data *us, struct scsi_cmnd *srb) +{ + int result; + unsigned char *cdb = srb->cmnd; + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + u32 bn = ((cdb[2] << 24) & 0xff000000) | ((cdb[3] << 16) & 0x00ff0000) | + ((cdb[4] << 8) & 0x0000ff00) | ((cdb[5] << 0) & 0x000000ff); + u16 blen = ((cdb[7] << 8) & 0xff00) | ((cdb[8] << 0) & 0x00ff); + u32 bnByte = bn * 0x200; + u32 blenByte = blen * 0x200; + + if (bn > info->bl_num) + return USB_STOR_TRANSPORT_ERROR; + + result = ene_load_bincode(us, SD_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) { + US_DEBUGP("Load SD RW pattern Fail !!\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + if (info->SD_Status.HiCapacity) + bnByte = bn; + + /* set up the command wrapper */ + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = blenByte; + bcb->Flags = 0x00; + bcb->CDB[0] = 0xF0; + bcb->CDB[5] = (unsigned char)(bnByte); + bcb->CDB[4] = (unsigned char)(bnByte>>8); + bcb->CDB[3] = (unsigned char)(bnByte>>16); + bcb->CDB[2] = (unsigned char)(bnByte>>24); + + result = ene_send_scsi_cmd(us, FDIR_WRITE, scsi_sglist(srb), 1); + return result; +} + +static int ene_get_card_type(struct us_data *us, u16 index, void *buf) +{ + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + int result; + + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x01; + bcb->Flags = 0x80; + bcb->CDB[0] = 0xED; + bcb->CDB[2] = (unsigned char)(index>>8); + bcb->CDB[3] = (unsigned char)index; + + result = ene_send_scsi_cmd(us, FDIR_READ, buf, 0); + return result; +} + +static int ene_get_card_status(struct us_data *us, u8 *buf) +{ + u16 tmpreg; + u32 reg4b; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + /*US_DEBUGP("transport --- ENE_ReadSDReg\n");*/ + reg4b = *(u32 *)&buf[0x18]; + info->SD_READ_BL_LEN = (u8)((reg4b >> 8) & 0x0f); + + tmpreg = (u16) reg4b; + reg4b = *(u32 *)(&buf[0x14]); + if (info->SD_Status.HiCapacity && !info->SD_Status.IsMMC) + info->HC_C_SIZE = (reg4b >> 8) & 0x3fffff; + + info->SD_C_SIZE = ((tmpreg & 0x03) << 10) | (u16)(reg4b >> 22); + info->SD_C_SIZE_MULT = (u8)(reg4b >> 7) & 0x07; + if (info->SD_Status.HiCapacity && info->SD_Status.IsMMC) + info->HC_C_SIZE = *(u32 *)(&buf[0x100]); + + if (info->SD_READ_BL_LEN > SD_BLOCK_LEN) { + info->SD_Block_Mult = 1 << (info->SD_READ_BL_LEN-SD_BLOCK_LEN); + info->SD_READ_BL_LEN = SD_BLOCK_LEN; + } else { + info->SD_Block_Mult = 1; + } + + return USB_STOR_TRANSPORT_GOOD; +} + +static int ene_load_bincode(struct us_data *us, unsigned char flag) +{ + int err; + char *fw_name = NULL; + unsigned char *buf = NULL; + const struct firmware *sd_fw = NULL; + int result = USB_STOR_TRANSPORT_ERROR; + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + if (info->BIN_FLAG == flag) + return USB_STOR_TRANSPORT_GOOD; + + buf = kmalloc(ENE_BIN_CODE_LEN, GFP_KERNEL); + if (buf == NULL) + return USB_STOR_TRANSPORT_ERROR; + + switch (flag) { + /* For SD */ + case SD_INIT1_PATTERN: + US_DEBUGP("SD_INIT1_PATTERN\n"); + fw_name = "ene-ub6250/sd_init1.bin"; + break; + case SD_INIT2_PATTERN: + US_DEBUGP("SD_INIT2_PATTERN\n"); + fw_name = "ene-ub6250/sd_init2.bin"; + break; + case SD_RW_PATTERN: + US_DEBUGP("SD_RDWR_PATTERN\n"); + fw_name = "ene-ub6250/sd_rdwr.bin"; + break; + default: + US_DEBUGP("----------- Unknown PATTERN ----------\n"); + goto nofw; + } + + err = request_firmware(&sd_fw, fw_name, &us->pusb_dev->dev); + if (err) { + US_DEBUGP("load firmware %s failed\n", fw_name); + goto nofw; + } + buf = kmalloc(sd_fw->size, GFP_KERNEL); + if (buf == NULL) { + US_DEBUGP("Malloc memory for fireware failed!\n"); + goto nofw; + } + memcpy(buf, sd_fw->data, sd_fw->size); + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = sd_fw->size; + bcb->Flags = 0x00; + bcb->CDB[0] = 0xEF; + + result = ene_send_scsi_cmd(us, FDIR_WRITE, buf, 0); + info->BIN_FLAG = flag; + kfree(buf); + +nofw: + if (sd_fw != NULL) { + release_firmware(sd_fw); + sd_fw = NULL; + } + + return result; +} + +static int ene_sd_init(struct us_data *us) +{ + int result; + u8 buf[0x200]; + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + US_DEBUGP("transport --- ENE_SDInit\n"); + /* SD Init Part-1 */ + result = ene_load_bincode(us, SD_INIT1_PATTERN); + if (result != USB_STOR_XFER_GOOD) { + US_DEBUGP("Load SD Init Code Part-1 Fail !!\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->Flags = 0x80; + bcb->CDB[0] = 0xF2; + + result = ene_send_scsi_cmd(us, FDIR_READ, NULL, 0); + if (result != USB_STOR_XFER_GOOD) { + US_DEBUGP("Exection SD Init Code Fail !!\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + /* SD Init Part-2 */ + result = ene_load_bincode(us, SD_INIT2_PATTERN); + if (result != USB_STOR_XFER_GOOD) { + US_DEBUGP("Load SD Init Code Part-2 Fail !!\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x200; + bcb->Flags = 0x80; + bcb->CDB[0] = 0xF1; + + result = ene_send_scsi_cmd(us, FDIR_READ, &buf, 0); + if (result != USB_STOR_XFER_GOOD) { + US_DEBUGP("Exection SD Init Code Fail !!\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + info->SD_Status = *(struct SD_STATUS *)&buf[0]; + if (info->SD_Status.Insert && info->SD_Status.Ready) { + ene_get_card_status(us, (unsigned char *)&buf); + US_DEBUGP("Insert = %x\n", info->SD_Status.Insert); + US_DEBUGP("Ready = %x\n", info->SD_Status.Ready); + US_DEBUGP("IsMMC = %x\n", info->SD_Status.IsMMC); + US_DEBUGP("HiCapacity = %x\n", info->SD_Status.HiCapacity); + US_DEBUGP("HiSpeed = %x\n", info->SD_Status.HiSpeed); + US_DEBUGP("WtP = %x\n", info->SD_Status.WtP); + } else { + US_DEBUGP("SD Card Not Ready --- %x\n", buf[0]); + return USB_STOR_TRANSPORT_ERROR; + } + return USB_STOR_TRANSPORT_GOOD; +} + + +static int ene_init(struct us_data *us) +{ + int result; + u8 misc_reg03 = 0; + struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra); + + result = ene_get_card_type(us, REG_CARD_STATUS, &misc_reg03); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + if (misc_reg03 & 0x01) { + if (!info->SD_Status.Ready) { + result = ene_sd_init(us); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + } + } + + return result; +} + +/*----- sd_scsi_irp() ---------*/ +static int sd_scsi_irp(struct us_data *us, struct scsi_cmnd *srb) +{ + int result; + struct ene_ub6250_info *info = (struct ene_ub6250_info *)us->extra; + + info->SrbStatus = SS_SUCCESS; + switch (srb->cmnd[0]) { + case TEST_UNIT_READY: + result = sd_scsi_test_unit_ready(us, srb); + break; /* 0x00 */ + case INQUIRY: + result = sd_scsi_inquiry(us, srb); + break; /* 0x12 */ + case MODE_SENSE: + result = sd_scsi_mode_sense(us, srb); + break; /* 0x1A */ + /* + case START_STOP: + result = SD_SCSI_Start_Stop(us, srb); + break; //0x1B + */ + case READ_CAPACITY: + result = sd_scsi_read_capacity(us, srb); + break; /* 0x25 */ + case READ_10: + result = sd_scsi_read(us, srb); + break; /* 0x28 */ + case WRITE_10: + result = sd_scsi_write(us, srb); + break; /* 0x2A */ + default: + info->SrbStatus = SS_ILLEGAL_REQUEST; + result = USB_STOR_TRANSPORT_FAILED; + break; + } + return result; +} + +static int ene_transport(struct scsi_cmnd *srb, struct us_data *us) +{ + int result = 0; + struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra); + + /*US_DEBUG(usb_stor_show_command(srb)); */ + scsi_set_resid(srb, 0); + if (unlikely(!info->SD_Status.Ready)) + result = ene_init(us); + else + result = sd_scsi_irp(us, srb); + + return 0; +} + + +static int ene_ub6250_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + int result; + u8 misc_reg03 = 0; + struct us_data *us; + + result = usb_stor_probe1(&us, intf, id, + (id - ene_ub6250_usb_ids) + ene_ub6250_unusual_dev_list); + if (result) + return result; + + /* FIXME: where should the code alloc extra buf ? */ + if (!us->extra) { + us->extra = kzalloc(sizeof(struct ene_ub6250_info), GFP_KERNEL); + if (!us->extra) + return -ENOMEM; + us->extra_destructor = ene_ub6250_info_destructor; + } + + us->transport_name = "ene_ub6250"; + us->transport = ene_transport; + us->max_lun = 0; + + result = usb_stor_probe2(us); + if (result) + return result; + + /* probe card type */ + result = ene_get_card_type(us, REG_CARD_STATUS, &misc_reg03); + if (result != USB_STOR_XFER_GOOD) { + usb_stor_disconnect(intf); + return USB_STOR_TRANSPORT_ERROR; + } + + if (!(misc_reg03 & 0x01)) { + result = -ENODEV; + printk(KERN_NOTICE "ums_eneub6250: The driver only supports SD\ + card. To use SM/MS card, please build driver/stagging/keucr\n"); + usb_stor_disconnect(intf); + } + + return result; +} + + +#ifdef CONFIG_PM + +static int ene_ub6250_resume(struct usb_interface *iface) +{ + u8 tmp = 0; + struct us_data *us = usb_get_intfdata(iface); + struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra); + + mutex_lock(&us->dev_mutex); + + US_DEBUGP("%s\n", __func__); + if (us->suspend_resume_hook) + (us->suspend_resume_hook)(us, US_RESUME); + + mutex_unlock(&us->dev_mutex); + + info->Power_IsResum = true; + /*info->SD_Status.Ready = 0; */ + info->SD_Status = *(struct SD_STATUS *)&tmp; + info->MS_Status = *(struct MS_STATUS *)&tmp; + info->SM_Status = *(struct SM_STATUS *)&tmp; + + return 0; +} + +static int ene_ub6250_reset_resume(struct usb_interface *iface) +{ + u8 tmp = 0; + struct us_data *us = usb_get_intfdata(iface); + struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra); + US_DEBUGP("%s\n", __func__); + /* Report the reset to the SCSI core */ + usb_stor_reset_resume(iface); + + /* FIXME: Notify the subdrivers that they need to reinitialize + * the device */ + info->Power_IsResum = true; + /*info->SD_Status.Ready = 0; */ + info->SD_Status = *(struct SD_STATUS *)&tmp; + info->MS_Status = *(struct MS_STATUS *)&tmp; + info->SM_Status = *(struct SM_STATUS *)&tmp; + + return 0; +} + +#else + +#define ene_ub6250_resume NULL +#define ene_ub6250_reset_resume NULL + +#endif + +static struct usb_driver ene_ub6250_driver = { + .name = "ums_eneub6250", + .probe = ene_ub6250_probe, + .disconnect = usb_stor_disconnect, + .suspend = usb_stor_suspend, + .resume = ene_ub6250_resume, + .reset_resume = ene_ub6250_reset_resume, + .pre_reset = usb_stor_pre_reset, + .post_reset = usb_stor_post_reset, + .id_table = ene_ub6250_usb_ids, + .soft_unbind = 1, +}; + +static int __init ene_ub6250_init(void) +{ + return usb_register(&ene_ub6250_driver); +} + +static void __exit ene_ub6250_exit(void) +{ + usb_deregister(&ene_ub6250_driver); +} + +module_init(ene_ub6250_init); +module_exit(ene_ub6250_exit); diff --git a/drivers/usb/storage/unusual_ene_ub6250.h b/drivers/usb/storage/unusual_ene_ub6250.h new file mode 100644 index 000000000000..5667f5d365c6 --- /dev/null +++ b/drivers/usb/storage/unusual_ene_ub6250.h @@ -0,0 +1,26 @@ +/* + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#if defined(CONFIG_USB_STORAGE_ENE_UB6250) || \ + defined(CONFIG_USB_STORAGE_ENE_UB6250_MODULE) + +UNUSUAL_DEV(0x0cf2, 0x6250, 0x0000, 0x9999, + "ENE", + "ENE UB6250 reader", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, 0), + +#endif /* defined(CONFIG_USB_STORAGE_ENE_UB6250) || ... */ diff --git a/drivers/usb/storage/usual-tables.c b/drivers/usb/storage/usual-tables.c index 468bde7d1971..f0f60b6a2cfa 100644 --- a/drivers/usb/storage/usual-tables.c +++ b/drivers/usb/storage/usual-tables.c @@ -80,6 +80,7 @@ static struct ignore_entry ignore_ids[] = { # include "unusual_alauda.h" # include "unusual_cypress.h" # include "unusual_datafab.h" +# include "unusual_ene_ub6250.h" # include "unusual_freecom.h" # include "unusual_isd200.h" # include "unusual_jumpshot.h" -- cgit v1.2.3 From 1254a459a376962ba771618742af47c8a1b92a6e Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Thu, 3 Mar 2011 16:38:28 -0800 Subject: staging: sep: remove unused ioctls Also remove associated functions, structures, and defines Signed-off-by: Mark Allyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/TODO | 2 - drivers/staging/sep/sep_dev.h | 25 --- drivers/staging/sep/sep_driver.c | 411 +---------------------------------- drivers/staging/sep/sep_driver_api.h | 82 ------- 4 files changed, 1 insertion(+), 519 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/sep/TODO b/drivers/staging/sep/TODO index a89e7d6ad0c9..8f3b878ad8ae 100644 --- a/drivers/staging/sep/TODO +++ b/drivers/staging/sep/TODO @@ -1,6 +1,4 @@ Todo's so far (from Alan Cox) - Check whether it can be plugged into any of the kernel crypto API interfaces - Crypto API 'glue' is still not ready to submit -- Clean up unused ioctls - Needs vendor help -- Clean up unused fields in ioctl structures - Needs vendor help - Clean up un-needed debug prints - Started to work on this diff --git a/drivers/staging/sep/sep_dev.h b/drivers/staging/sep/sep_dev.h index 0ffe68cb7140..696ab0dd2b79 100644 --- a/drivers/staging/sep/sep_dev.h +++ b/drivers/staging/sep/sep_dev.h @@ -69,31 +69,6 @@ struct sep_device { size_t shared_size; void *shared_addr; - /* restricted access region (coherent alloc) */ - dma_addr_t rar_bus; - size_t rar_size; - void *rar_addr; - - /* Firmware regions; cache is at rar for Moorestown and - resident is at rar for Medfield */ - dma_addr_t cache_bus; - size_t cache_size; - void *cache_addr; - - dma_addr_t resident_bus; - size_t resident_size; - void *resident_addr; - - /* sep's scratchpad */ - dma_addr_t dcache_bus; - size_t dcache_size; - void *dcache_addr; - - /* Only used on Medfield */ - dma_addr_t extapp_bus; - size_t extapp_size; - void *extapp_addr; - /* start address of the access to the SEP registers from driver */ dma_addr_t reg_physical_addr; dma_addr_t reg_physical_end; diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index d841289c1faf..71a5fbc041e4 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -76,93 +76,6 @@ static struct sep_device *sep_dev; -/** - * sep_load_firmware - copy firmware cache/resident - * @sep: pointer to struct sep_device we are loading - * - * This functions copies the cache and resident from their source - * location into destination shared memory. - */ -static int sep_load_firmware(struct sep_device *sep) -{ - const struct firmware *fw; - char *cache_name = "cache.image.bin"; - char *res_name = "resident.image.bin"; - char *extapp_name = "extapp.image.bin"; - int error ; - unsigned long work1, work2, work3; - - /* Set addresses and load resident */ - sep->resident_bus = sep->rar_bus; - sep->resident_addr = sep->rar_addr; - - error = request_firmware(&fw, res_name, &sep->pdev->dev); - if (error) { - dev_warn(&sep->pdev->dev, "can't request resident fw\n"); - return error; - } - - memcpy(sep->resident_addr, (void *)fw->data, fw->size); - sep->resident_size = fw->size; - release_firmware(fw); - - dev_dbg(&sep->pdev->dev, "resident bus is %lx\n", - (unsigned long)sep->resident_bus); - - /* Set addresses for dcache (no loading needed) */ - work1 = (unsigned long)sep->resident_bus; - work2 = (unsigned long)sep->resident_size; - work3 = (work1 + work2 + (1024 * 4)) & 0xfffff000; - sep->dcache_bus = (dma_addr_t)work3; - - work1 = (unsigned long)sep->resident_addr; - work2 = (unsigned long)sep->resident_size; - work3 = (work1 + work2 + (1024 * 4)) & 0xfffff000; - sep->dcache_addr = (void *)work3; - - sep->dcache_size = 1024 * 128; - - /* Set addresses and load cache */ - sep->cache_bus = sep->dcache_bus + sep->dcache_size; - sep->cache_addr = sep->dcache_addr + sep->dcache_size; - - error = request_firmware(&fw, cache_name, &sep->pdev->dev); - if (error) { - dev_warn(&sep->pdev->dev, "Unable to request cache firmware\n"); - return error; - } - - memcpy(sep->cache_addr, (void *)fw->data, fw->size); - sep->cache_size = fw->size; - release_firmware(fw); - - dev_dbg(&sep->pdev->dev, "cache bus is %08lx\n", - (unsigned long)sep->cache_bus); - - /* Set addresses and load extapp */ - sep->extapp_bus = sep->cache_bus + (1024 * 370); - sep->extapp_addr = sep->cache_addr + (1024 * 370); - - error = request_firmware(&fw, extapp_name, &sep->pdev->dev); - if (error) { - dev_warn(&sep->pdev->dev, "Unable to request extapp firmware\n"); - return error; - } - - memcpy(sep->extapp_addr, (void *)fw->data, fw->size); - sep->extapp_size = fw->size; - release_firmware(fw); - - dev_dbg(&sep->pdev->dev, "extapp bus is %08llx\n", - (unsigned long long)sep->extapp_bus); - - return error; -} - -MODULE_FIRMWARE("sep/cache.image.bin"); -MODULE_FIRMWARE("sep/resident.image.bin"); -MODULE_FIRMWARE("sep/extapp.image.bin"); - /** * sep_dump_message - dump the message that is pending * @sep: SEP device @@ -2282,58 +2195,6 @@ end_function: } - -/** - * sep_create_sync_dma_tables_handler - create sync DMA tables - * @sep: pointer to struct sep_device - * @arg: pointer to struct bld_syn_tab_struct - * - * Handle the request for creation of the DMA tables for the synchronic - * symmetric operations (AES,DES). Note that all bus addresses that are - * passed to the SEP are in 32 bit format; the SEP is a 32 bit device - */ -static int sep_create_sync_dma_tables_handler(struct sep_device *sep, - unsigned long arg) -{ - int error = 0; - - /* Command arguments */ - struct bld_syn_tab_struct command_args; - - if (copy_from_user(&command_args, (void __user *)arg, - sizeof(struct bld_syn_tab_struct))) { - error = -EFAULT; - goto end_function; - } - - dev_dbg(&sep->pdev->dev, "create dma table handler app_in_address is %08llx\n", - command_args.app_in_address); - dev_dbg(&sep->pdev->dev, "app_out_address is %08llx\n", - command_args.app_out_address); - dev_dbg(&sep->pdev->dev, "data_size is %u\n", - command_args.data_in_size); - dev_dbg(&sep->pdev->dev, "block_size is %u\n", - command_args.block_size); - - /* Validate user parameters */ - if (!command_args.app_in_address) { - error = -EINVAL; - goto end_function; - } - - error = sep_prepare_input_output_dma_table_in_dcb(sep, - (unsigned long)command_args.app_in_address, - (unsigned long)command_args.app_out_address, - command_args.data_in_size, - command_args.block_size, - 0x0, - false, - false); - -end_function: - return error; -} - /** * sep_free_dma_tables_and_dcb - free DMA tables and DCBs * @sep: pointer to struct sep_device @@ -2410,204 +2271,6 @@ static int sep_get_static_pool_addr_handler(struct sep_device *sep) return 0; } -/** - * sep_start_handler - start device - * @sep: pointer to struct sep_device - */ -static int sep_start_handler(struct sep_device *sep) -{ - unsigned long reg_val; - unsigned long error = 0; - - /* Wait in polling for message from SEP */ - do { - reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); - } while (!reg_val); - - /* Check the value */ - if (reg_val == 0x1) - /* Fatal error - read error status from GPRO */ - error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR); - return error; -} - -/** - * ep_check_sum_calc - checksum messages - * @data: buffer to checksum - * @length: buffer size - * - * This function performs a checksum for messages that are sent - * to the SEP. - */ -static u32 sep_check_sum_calc(u8 *data, u32 length) -{ - u32 sum = 0; - u16 *Tdata = (u16 *)data; - - while (length > 1) { - /* This is the inner loop */ - sum += *Tdata++; - length -= 2; - } - - /* Add left-over byte, if any */ - if (length > 0) - sum += *(u8 *)Tdata; - - /* Fold 32-bit sum to 16 bits */ - while (sum>>16) - sum = (sum & 0xffff) + (sum >> 16); - - return ~sum & 0xFFFF; -} - -/** - * sep_init_handler - - * @sep: pointer to struct sep_device - * @arg: parameters from user space application - * - * Handles the request for SEP initialization - * Note that this will go away for Medfield once the SCU - * SEP initialization is complete - * Also note that the message to the SEP has components - * from user space as well as components written by the driver - * This is becuase the portions of the message that pertain to - * physical addresses must be set by the driver after the message - * leaves custody of the user space application for security - * reasons. - */ -static int sep_init_handler(struct sep_device *sep, unsigned long arg) -{ - u32 message_buff[14]; - u32 counter; - int error = 0; - u32 reg_val; - dma_addr_t new_base_addr; - unsigned long addr_hold; - struct init_struct command_args; - - /* Make sure that we have not initialized already */ - reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); - - if (reg_val != 0x2) { - error = SEP_ALREADY_INITIALIZED_ERR; - dev_dbg(&sep->pdev->dev, "init; device already initialized\n"); - goto end_function; - } - - /* Only root can initialize */ - if (!capable(CAP_SYS_ADMIN)) { - error = -EACCES; - goto end_function; - } - - /* Copy in the parameters */ - error = copy_from_user(&command_args, (void __user *)arg, - sizeof(struct init_struct)); - - if (error) { - error = -EFAULT; - goto end_function; - } - - /* Validate parameters */ - if (!command_args.message_addr || !command_args.sep_sram_addr || - command_args.message_size_in_words > 14) { - error = -EINVAL; - goto end_function; - } - - /* Copy in the SEP init message */ - addr_hold = (unsigned long)command_args.message_addr; - error = copy_from_user(message_buff, - (void __user *)addr_hold, - command_args.message_size_in_words*sizeof(u32)); - - if (error) { - error = -EFAULT; - goto end_function; - } - - /* Load resident, cache, and extapp firmware */ - error = sep_load_firmware(sep); - - if (error) { - dev_warn(&sep->pdev->dev, - "init; copy SEP init message failed %x\n", error); - goto end_function; - } - - /* Compute the base address */ - new_base_addr = sep->shared_bus; - - if (sep->resident_bus < new_base_addr) - new_base_addr = sep->resident_bus; - - if (sep->cache_bus < new_base_addr) - new_base_addr = sep->cache_bus; - - if (sep->dcache_bus < new_base_addr) - new_base_addr = sep->dcache_bus; - - /* Put physical addresses in SEP message */ - message_buff[3] = (u32)new_base_addr; - message_buff[4] = (u32)sep->shared_bus; - message_buff[6] = (u32)sep->resident_bus; - message_buff[7] = (u32)sep->cache_bus; - message_buff[8] = (u32)sep->dcache_bus; - - message_buff[command_args.message_size_in_words - 1] = 0x0; - message_buff[command_args.message_size_in_words - 1] = - sep_check_sum_calc((u8 *)message_buff, - command_args.message_size_in_words*sizeof(u32)); - - /* Debug print of message */ - for (counter = 0; counter < command_args.message_size_in_words; - counter++) - dev_dbg(&sep->pdev->dev, "init; SEP message word %d is %x\n", - counter, message_buff[counter]); - - /* Tell the SEP the sram address */ - sep_write_reg(sep, HW_SRAM_ADDR_REG_ADDR, command_args.sep_sram_addr); - - /* Push the message to the SEP */ - for (counter = 0; counter < command_args.message_size_in_words; - counter++) { - sep_write_reg(sep, HW_SRAM_DATA_REG_ADDR, - message_buff[counter]); - sep_wait_sram_write(sep); - } - - /* Signal SEP that message is ready and to init */ - sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x1); - - /* Wait for acknowledge */ - - do { - reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); - } while (!(reg_val & 0xFFFFFFFD)); - - if (reg_val == 0x1) { - dev_warn(&sep->pdev->dev, "init; device int failed\n"); - error = sep_read_reg(sep, 0x8060); - dev_warn(&sep->pdev->dev, "init; sw monitor is %x\n", error); - error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR); - dev_warn(&sep->pdev->dev, "init; error is %x\n", error); - goto end_function; - } - /* Signal SEP to zero the GPR3 */ - sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x10); - - /* Wait for response */ - - do { - reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); - } while (reg_val != 0); - -end_function: - return error; -} - /** * sep_end_transaction_handler - end transaction * @sep: pointer to struct sep_device @@ -2747,30 +2410,6 @@ end_function: return error; } -/** - * sep_realloc_ext_cache_handler - report location of extcache - * @sep: pointer to struct sep_device - * @arg: pointer to user parameters - * - * This function tells the SEP where the extapp is located - */ -static int sep_realloc_ext_cache_handler(struct sep_device *sep, - unsigned long arg) -{ - /* Holds the new ext cache address in the system memory offset */ - u32 *system_addr; - - /* Set value in the SYSTEM MEMORY offset */ - system_addr = (u32 *)(sep->shared_addr + - SEP_DRIVER_SYSTEM_EXT_CACHE_ADDR_OFFSET_IN_BYTES); - - /* Copy the physical address to the System Area for the SEP */ - system_addr[0] = SEP_EXT_CACHE_ADDR_VAL_TOKEN; - system_addr[1] = sep->extapp_bus; - - return 0; -} - /** * sep_ioctl - ioctl api * @filp: pointer to struct file @@ -2810,28 +2449,6 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) /* Allocate data pool */ error = sep_allocate_data_pool_memory_handler(sep, arg); break; - case SEP_IOCCREATESYMDMATABLE: - /* Create DMA table for synhronic operation */ - error = sep_create_sync_dma_tables_handler(sep, arg); - break; - case SEP_IOCFREEDMATABLEDATA: - /* Free the pages */ - error = sep_free_dma_table_data_handler(sep); - break; - case SEP_IOCSEPSTART: - /* Start command to SEP */ - if (sep->pdev->revision == 0) /* Only for old chip */ - error = sep_start_handler(sep); - else - error = -EPERM; /* Not permitted on new chip */ - break; - case SEP_IOCSEPINIT: - /* Init command to SEP */ - if (sep->pdev->revision == 0) /* Only for old chip */ - error = sep_init_handler(sep, arg); - else - error = -EPERM; /* Not permitted on new chip */ - break; case SEP_IOCGETSTATICPOOLADDR: /* Inform the SEP the bus address of the static pool */ error = sep_get_static_pool_addr_handler(sep); @@ -2839,12 +2456,6 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) case SEP_IOCENDTRANSACTION: error = sep_end_transaction_handler(sep); break; - case SEP_IOCREALLOCEXTCACHE: - if (sep->pdev->revision == 0) /* Only for old chip */ - error = sep_realloc_ext_cache_handler(sep, arg); - else - error = -EPERM; /* Not permitted on new chip */ - break; case SEP_IOCRARPREPAREMESSAGE: error = sep_rar_prepare_output_msg_handler(sep, arg); break; @@ -3213,20 +2824,6 @@ static int __devinit sep_probe(struct pci_dev *pdev, goto end_function_error; } - sep->rar_size = FAKE_RAR_SIZE; - sep->rar_addr = dma_alloc_coherent(&sep->pdev->dev, - sep->rar_size, &sep->rar_bus, GFP_KERNEL); - if (sep->rar_addr == NULL) { - dev_warn(&sep->pdev->dev, "can't allocate mfld rar\n"); - error = -ENOMEM; - goto end_function_deallocate_sep_shared_area; - } - - dev_dbg(&sep->pdev->dev, "rar start is %p, phy is %llx," - " size is %zx\n", sep->rar_addr, - (unsigned long long)sep->rar_bus, - sep->rar_size); - /* Clear ICR register */ sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); @@ -3243,7 +2840,7 @@ static int __devinit sep_probe(struct pci_dev *pdev, "sep_driver", sep); if (error) - goto end_function_dealloc_rar; + goto end_function_deallocate_sep_shared_area; /* The new chip requires a shared area reconfigure */ if (sep->pdev->revision == 4) { /* Only for new chip */ @@ -3261,12 +2858,6 @@ static int __devinit sep_probe(struct pci_dev *pdev, end_function_free_irq: free_irq(pdev->irq, sep); -end_function_dealloc_rar: - if (sep->rar_addr) - dma_free_coherent(&sep->pdev->dev, sep->rar_size, - sep->rar_addr, sep->rar_bus); - goto end_function; - end_function_deallocate_sep_shared_area: /* De-allocate shared area */ sep_unmap_and_free_shared_area(sep); diff --git a/drivers/staging/sep/sep_driver_api.h b/drivers/staging/sep/sep_driver_api.h index 0f38d619842e..c3aacfcc8ac6 100644 --- a/drivers/staging/sep/sep_driver_api.h +++ b/drivers/staging/sep/sep_driver_api.h @@ -42,48 +42,6 @@ TYPEDEFS ----------------------------------------------*/ -/* - * Note that several members of these structres are only here - * for campatability with the middleware; they are not used - * by this driver. - * All user space buffer addresses are set to aligned u64 - * in order to ensure compatibility with 64 bit systems - */ - -/* - init command struct; this will go away when SCU does init -*/ -struct init_struct { - /* address that SEP can access for message */ - aligned_u64 message_addr; - - /* message size */ - u32 message_size_in_words; - - /* offset of the init message in the sep sram */ - u32 sep_sram_addr; - - /* -not used- resident size in bytes*/ - u32 unused_resident_size_in_bytes; - - /* -not used- cache size in bytes*/ - u32 unused_cache_size_in_bytes; - - /* -not used- ext cache current address */ - aligned_u64 unused_extcache_addr; - - /* -not used- ext cache size in bytes*/ - u32 unused_extcache_size_in_bytes; -}; - -struct realloc_ext_struct { - /* -not used- current external cache address */ - aligned_u64 unused_ext_cache_addr; - - /* -not used- external cache size in bytes*/ - u32 unused_ext_cache_size_in_bytes; -}; - struct alloc_struct { /* offset from start of shared pool area */ u32 offset; @@ -91,29 +49,6 @@ struct alloc_struct { u32 num_bytes; }; -/* - Note that all app addresses are cast as u32; the sep - middleware sends them as fixed 32 bit words -*/ -struct bld_syn_tab_struct { - /* address value of the data in (user space addr) */ - aligned_u64 app_in_address; - - /* size of data in */ - u32 data_in_size; - - /* address of the data out (user space addr) */ - aligned_u64 app_out_address; - - /* the size of the block of the operation - if needed, - every table will be modulo this parameter */ - u32 block_size; - - /* -not used- distinct user/kernel layout */ - bool isKernelVirtualAddress; - -}; - /* command struct for getting caller id value and address */ struct caller_id_struct { /* pid of the process */ @@ -253,10 +188,6 @@ struct sep_lli_entry { #define SEP_IOCALLOCDATAPOLL \ _IOW(SEP_IOC_MAGIC_NUMBER, 2, struct alloc_struct) -/* create sym dma lli tables */ -#define SEP_IOCCREATESYMDMATABLE \ - _IOW(SEP_IOC_MAGIC_NUMBER, 5, struct bld_syn_tab_struct) - /* free dynamic data aalocated during table creation */ #define SEP_IOCFREEDMATABLEDATA \ _IO(SEP_IOC_MAGIC_NUMBER, 7) @@ -265,23 +196,10 @@ struct sep_lli_entry { #define SEP_IOCGETSTATICPOOLADDR \ _IO(SEP_IOC_MAGIC_NUMBER, 8) -/* start sep command */ -#define SEP_IOCSEPSTART \ - _IO(SEP_IOC_MAGIC_NUMBER, 12) - -/* init sep command */ -#define SEP_IOCSEPINIT \ - _IOW(SEP_IOC_MAGIC_NUMBER, 13, struct init_struct) - /* end transaction command */ #define SEP_IOCENDTRANSACTION \ _IO(SEP_IOC_MAGIC_NUMBER, 15) -/* reallocate external app; unused structure still needed for - * compatability with middleware */ -#define SEP_IOCREALLOCEXTCACHE \ - _IOW(SEP_IOC_MAGIC_NUMBER, 18, struct realloc_ext_struct) - #define SEP_IOCRARPREPAREMESSAGE \ _IOW(SEP_IOC_MAGIC_NUMBER, 20, struct rar_hndl_to_bus_struct) -- cgit v1.2.3 From 2d2322b269c2524996a259024f82c7e318719696 Mon Sep 17 00:00:00 2001 From: wwang Date: Fri, 4 Mar 2011 10:56:36 +0800 Subject: staging: rts_pstor: fix a bug that a greenhouse sd card can't be recognized A greenhouse sd card can't be recognized using rts5209. To fix this bug, these modifications are applied: 1, Move some codes which clear sd internal variables from sd_init_type to sd_prepare_reset. So sd_init_type is useless any more and is removed entirely; 2, If a sd card can't pass sd3.0 mode, the action of tunning phase should be avoided when retrying sd2.0 mode. Signed-off-by: wwang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts_pstor/sd.c | 56 ++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 80b61e69beef..21bfa5755bec 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -1265,6 +1265,7 @@ static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width) sd_card->func_group1_mask &= ~(sd_card->sd_switch_fail); + /* Function Group 1: Access Mode */ for (i = 0; i < 4; i++) { switch ((u8)(chip->sd_speed_prior >> (i*8))) { case SDR104_SUPPORT: @@ -1349,6 +1350,14 @@ static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width) } } + if (!func_to_switch || (func_to_switch == HS_SUPPORT)) { + /* Do not try to switch current limit if the card doesn't + * support UHS mode or we don't want it to support UHS mode + */ + return STATUS_SUCCESS; + } + + /* Function Group 4: Current Limit */ func_to_switch = 0xFF; for (i = 0; i < 4; i++) { @@ -2015,6 +2024,17 @@ static int sd_prepare_reset(struct rtsx_chip *chip) sd_card->sd_clock = CLK_30; } + sd_card->sd_type = 0; + sd_card->seq_mode = 0; + sd_card->sd_data_buf_ready = 0; + sd_card->capacity = 0; + +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status = 0; + sd_card->sd_erase_status = 0; +#endif + + chip->capacity[chip->card2lun[SD_CARD]] = 0; chip->sd_io = 0; retval = sd_set_init_para(chip); @@ -2504,6 +2524,15 @@ SD_UNLOCK_ENTRY: sd_dont_switch = 1; if (!sd_dont_switch) { + if (sd20_mode) { + /* Set sd_switch_fail here, because we needn't + * switch to UHS mode + */ + sd_card->sd_switch_fail = SDR104_SUPPORT_MASK | + DDR50_SUPPORT_MASK | SDR50_SUPPORT_MASK; + } + + /* Check the card whether follow SD1.1 spec or higher */ retval = sd_check_spec(chip, switch_bus_width); if (retval == STATUS_SUCCESS) { retval = sd_switch_function(chip, switch_bus_width); @@ -2546,7 +2575,7 @@ SD_UNLOCK_ENTRY: sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; #endif - if (CHK_SD30_SPEED(sd_card)) { + if (!sd20_mode && CHK_SD30_SPEED(sd_card)) { int read_lba0 = 1; RTSX_WRITE_REG(chip, SD30_DRIVE_SEL, 0x07, chip->sd30_drive_sel_1v8); @@ -3040,28 +3069,6 @@ MMC_UNLOCK_ENTRY: return STATUS_SUCCESS; } -static void sd_init_type(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - - memset(sd_card, 0, sizeof(struct sd_info)); - - sd_card->sd_type = 0; - sd_card->seq_mode = 0; - sd_card->sd_data_buf_ready = 0; - sd_card->capacity = 0; - sd_card->sd_switch_fail = 0; - sd_card->mmc_dont_switch_bus = 0; - sd_card->need_retune = 0; - -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status = 0; - sd_card->sd_erase_status = 0; -#endif - - chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity = 0; -} - int reset_sd_card(struct rtsx_chip *chip) { struct sd_info *sd_card = &(chip->sd_card); @@ -3069,7 +3076,8 @@ int reset_sd_card(struct rtsx_chip *chip) sd_init_reg_addr(chip); - sd_init_type(chip); + memset(sd_card, 0, sizeof(struct sd_info)); + chip->capacity[chip->card2lun[SD_CARD]] = 0; retval = enable_card_clock(chip, SD_CARD); if (retval != STATUS_SUCCESS) { -- cgit v1.2.3 From 9025c0faeefdbffd0b65e155876824e4e8de1723 Mon Sep 17 00:00:00 2001 From: Dowan Kim Date: Fri, 4 Mar 2011 17:47:43 -0800 Subject: staging: brcm80211: FIX for bug that prevents system from entering suspend state The attempt to enter to suspend mode can be hindered when the network interface is disabled. When system enters the suspend mode with the network interface disabled, network layer calls ifdown() followed by cfg80211 layer calling wl_cfg80211_suspend() which is registered as suspend handler for cfg80211 layer. ifdown() call ultimately funnels down to __wl_cfg80211_down() call where WL_STATUS_READY bit is cleared via call to "clear_bit(WL_STATUS_READY, &wl->status)" But CHECK_SYS_UP()checks WL_STATUS_READY bit thinking it's not ready and returns -EIO from suspend handler which intern prevents entering into system suspend state CHECK_SYS_UP() is mainly used in the code path where upper layer would request certain wifi related activity to be performed by the firmware, where this calls helps to make sure our firmware would be in ready state to respond to those requests But in the case of wl_cfg80211_suspend() code path there is no need to check for firmware status for any reason Signed-off-by: Dowan Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 1291124272f3..9e74beb0b64b 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -1977,8 +1977,6 @@ static s32 wl_cfg80211_suspend(struct wiphy *wiphy) struct net_device *ndev = wl_to_ndev(wl); s32 err = 0; - CHECK_SYS_UP(); - set_bit(WL_STATUS_SCAN_ABORTING, &wl->status); wl_term_iscan(wl); if (wl->scan_request) { -- cgit v1.2.3 From 0875abf83df7d74bf9858c125e82835bd1ca349c Mon Sep 17 00:00:00 2001 From: Xiaochen Wang Date: Fri, 4 Mar 2011 13:09:00 +0800 Subject: staging: rtl8187se: check kmalloc return value check kmalloc return value Signed-off-by: Xiaochen Wang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index 652d879509e6..74a3b4c211ad 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -1435,8 +1435,9 @@ static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen) if(*(t++) == MFIE_TYPE_CHALLENGE){ *chlen = *(t++); - *challenge = kmalloc(*chlen, GFP_ATOMIC); - memcpy(*challenge, t, *chlen); + *challenge = kmemdup(t, *chlen, GFP_ATOMIC); + if (!*challenge) + return -ENOMEM; } } -- cgit v1.2.3 From 9603ff50b5d56e6ee64b10116ff640320732f9c8 Mon Sep 17 00:00:00 2001 From: Xiaochen Wang Date: Sun, 6 Mar 2011 22:04:15 +0800 Subject: staging: rtl8192e use kmemdup and check its return value use kmemdup instead of kmalloc and memcpy, and check its return value Signed-off-by: Xiaochen Wang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index 88a9cd1958a8..fc96676bb9ce 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -1564,8 +1564,9 @@ static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen) if(*(t++) == MFIE_TYPE_CHALLENGE){ *chlen = *(t++); - *challenge = kmalloc(*chlen, GFP_ATOMIC); - memcpy(*challenge, t, *chlen); + *challenge = kmemdup(t, *chlen, GFP_ATOMIC); + if (!*challenge) + return -ENOMEM; } } -- cgit v1.2.3 From cd92274093876c57fa4de0f219a552911ef9adc6 Mon Sep 17 00:00:00 2001 From: Xiaochen Wang Date: Sun, 6 Mar 2011 22:24:14 +0800 Subject: staging: rtl8712: check copy_from_user return value Description:return -EFAULT if copy_to_user() fails Signed-off-by: Xiaochen Wang Acked-by: Larry Finger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_ioctl_linux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index 221be81c85eb..4ac17c0bbd59 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -1970,9 +1970,9 @@ static int r871x_wps_start(struct net_device *dev, struct _adapter *padapter = (struct _adapter *)_netdev_priv(dev); struct iw_point *pdata = &wrqu->data; u32 u32wps_start = 0; - unsigned int uintRet = 0; - uintRet = copy_from_user((void *)&u32wps_start, pdata->pointer, 4); + if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4)) + return -EFAULT; if ((padapter->bDriverStopped) || (pdata == NULL)) return -EINVAL; if (u32wps_start == 0) -- cgit v1.2.3 From 4495c15f29a11c41d0a69a6e848307b0db7cc196 Mon Sep 17 00:00:00 2001 From: Xiaochen Wang Date: Sun, 6 Mar 2011 22:53:21 +0800 Subject: staging: rtl8712: check _malloc return value Description: The original check is wrong. Signed-off-by: Xiaochen Wang Acked-by: Larry Finger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_ioctl_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index 4ac17c0bbd59..8ebfdd620ba4 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -958,7 +958,7 @@ static int r871x_wx_set_priv(struct net_device *dev, len = dwrq->length; ext = _malloc(len); - if (!_malloc(len)) + if (!ext) return -ENOMEM; if (copy_from_user(ext, dwrq->pointer, len)) { kfree(ext); -- cgit v1.2.3 From fd49b7879890d0f17c1cb86eb07e449d9c9f0699 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 6 Mar 2011 00:55:20 +0200 Subject: staging/easycap: wait_i2c should be static wait_i2c is only used from easycap_low.c so remove it from the easycap.h and mark it static Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 1 - drivers/staging/easycap/easycap_low.c | 61 +++++++++++++++++------------------ 2 files changed, 30 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index e8ef1a258341..a80d023a8f0b 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -558,7 +558,6 @@ int set_resolution(struct usb_device *, int read_saa(struct usb_device *, u16); int read_stk(struct usb_device *, u32); int write_saa(struct usb_device *, u16, u16); -int wait_i2c(struct usb_device *); int write_000(struct usb_device *, u16, u16); int start_100(struct usb_device *); int stop_100(struct usb_device *); diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index 403415ee191d..8e4e11f12cd7 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -323,7 +323,36 @@ static int regset(struct usb_device *pusb_device, u16 index, u16 value) return rc; } -/*****************************************************************************/ +/*--------------------------------------------------------------------------*/ +/* + * FUNCTION wait_i2c() RETURNS 0 ON SUCCESS +*/ +/*--------------------------------------------------------------------------*/ +static int wait_i2c(struct usb_device *p) +{ + u16 get0; + u8 igot; + const int max = 2; + int k; + + if (!p) + return -ENODEV; + + for (k = 0; k < max; k++) { + GET(p, 0x0201, &igot); get0 = igot; + switch (get0) { + case 0x04: + case 0x01: + return 0; + case 0x00: + msleep(20); + continue; + default: + return get0 - 1; + } + } + return -1; +} /****************************************************************************/ int confirm_resolution(struct usb_device *p) @@ -935,36 +964,6 @@ int stop_100(struct usb_device *p) return 0; } /****************************************************************************/ -/*--------------------------------------------------------------------------*/ -/* - * FUNCTION wait_i2c() RETURNS 0 ON SUCCESS -*/ -/*--------------------------------------------------------------------------*/ -int wait_i2c(struct usb_device *p) -{ - u16 get0; - u8 igot; - const int max = 2; - int k; - - if (!p) - return -ENODEV; - - for (k = 0; k < max; k++) { - GET(p, 0x0201, &igot); get0 = igot; - switch (get0) { - case 0x04: - case 0x01: - return 0; - case 0x00: - msleep(20); - continue; - default: - return get0 - 1; - } - } - return -1; -} /****************************************************************************/ /*****************************************************************************/ int wakeup_device(struct usb_device *pusb_device) -- cgit v1.2.3 From c0b3a8a034c225727a810977aee0ccd72b2d92c9 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 6 Mar 2011 00:55:21 +0200 Subject: staging/easycap: reduce code duplication for ssa stk settings reduce code duplication in register settings instead of if (ntsc) else use cfg = (ntsc) ? configNTSC : configPAL; in addition change while loops to more readable for loops Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_low.c | 173 +++++++++------------------------- 1 file changed, 42 insertions(+), 131 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index 8e4e11f12cd7..0385735ac6df 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -412,24 +412,13 @@ int confirm_stream(struct usb_device *p) /****************************************************************************/ int setup_stk(struct usb_device *p, bool ntsc) { - int i0; - + int i; + const struct stk1160config *cfg; if (!p) return -ENODEV; - i0 = 0; - if (ntsc) { - while (0xFFF != stk1160configNTSC[i0].reg) { - SET(p, stk1160configNTSC[i0].reg, - stk1160configNTSC[i0].set); - i0++; - } - } else { - while (0xFFF != stk1160configPAL[i0].reg) { - SET(p, stk1160configPAL[i0].reg, - stk1160configPAL[i0].set); - i0++; - } - } + cfg = (ntsc) ? stk1160configNTSC : stk1160configPAL; + for (i = 0; cfg[i].reg != 0xFFF; i++) + SET(p, cfg[i].reg, cfg[i].set); write_300(p); @@ -438,24 +427,13 @@ int setup_stk(struct usb_device *p, bool ntsc) /****************************************************************************/ int setup_saa(struct usb_device *p, bool ntsc) { - int i0, ir; - + int i, ir; + const struct saa7113config *cfg; if (!p) return -ENODEV; - i0 = 0; - if (ntsc) { - while (0xFF != saa7113configNTSC[i0].reg) { - ir = write_saa(p, saa7113configNTSC[i0].reg, - saa7113configNTSC[i0].set); - i0++; - } - } else { - while (0xFF != saa7113configPAL[i0].reg) { - ir = write_saa(p, saa7113configPAL[i0].reg, - saa7113configPAL[i0].set); - i0++; - } - } + cfg = (ntsc) ? saa7113configNTSC : saa7113configPAL; + for (i = 0; cfg[i].reg != 0xFF; i++) + ir = write_saa(p, cfg[i].reg, cfg[i].set); return 0; } /****************************************************************************/ @@ -575,51 +553,24 @@ int write_300(struct usb_device *p) /*--------------------------------------------------------------------------*/ int check_saa(struct usb_device *p, bool ntsc) { - int i0, ir, rc; - + int i, ir, rc = 0; + struct saa7113config const *cfg; if (!p) return -ENODEV; - i0 = 0; - rc = 0; - if (ntsc) { - while (0xFF != saa7113configNTSC[i0].reg) { - if (0x0F == saa7113configNTSC[i0].reg) { - i0++; - continue; - } - ir = read_saa(p, saa7113configNTSC[i0].reg); - if (ir != saa7113configNTSC[i0].set) { - SAY("SAA register 0x%02X has 0x%02X, " - "expected 0x%02X\n", - saa7113configNTSC[i0].reg, - ir, saa7113configNTSC[i0].set); + cfg = (ntsc) ? saa7113configNTSC : saa7113configPAL; + for (i = 0; cfg[i].reg != 0xFF; i++) { + if (0x0F == cfg[i].reg) + continue; + ir = read_saa(p, cfg[i].reg); + if (ir != cfg[i].set) { + SAY("SAA register 0x%02X has 0x%02X, expected 0x%02X\n", + cfg[i].reg, ir, cfg[i].set); rc--; - } - i0++; - } - } else { - while (0xFF != saa7113configPAL[i0].reg) { - if (0x0F == saa7113configPAL[i0].reg) { - i0++; - continue; - } - - ir = read_saa(p, saa7113configPAL[i0].reg); - if (ir != saa7113configPAL[i0].set) { - SAY("SAA register 0x%02X has 0x%02X, " - "expected 0x%02X\n", - saa7113configPAL[i0].reg, - ir, saa7113configPAL[i0].set); - rc--; - } - i0++; } } - if (-8 > rc) - return rc; - else - return 0; + + return (rc < -8) ? rc : 0; } /****************************************************************************/ int merit_saa(struct usb_device *p) @@ -687,71 +638,31 @@ int ready_saa(struct usb_device *p) /*--------------------------------------------------------------------------*/ int check_stk(struct usb_device *p, bool ntsc) { - int i0, ir; + int i, ir; + const struct stk1160config *cfg; if (!p) return -ENODEV; - i0 = 0; - if (ntsc) { - while (0xFFF != stk1160configNTSC[i0].reg) { - if (0x000 == stk1160configNTSC[i0].reg) { - i0++; continue; - } - if (0x002 == stk1160configNTSC[i0].reg) { - i0++; continue; - } - ir = read_stk(p, stk1160configNTSC[i0].reg); - if (0x100 == stk1160configNTSC[i0].reg) { - if ((ir != (0xFF & stk1160configNTSC[i0].set)) && - (ir != (0x80 | (0xFF & stk1160configNTSC[i0].set))) && - (0xFFFF != stk1160configNTSC[i0].set)) { - SAY("STK register 0x%03X has 0x%02X, " - "expected 0x%02X\n", - stk1160configNTSC[i0].reg, - ir, stk1160configNTSC[i0].set); - } - i0++; continue; - } - if ((ir != (0xFF & stk1160configNTSC[i0].set)) && - (0xFFFF != stk1160configNTSC[i0].set)) { - SAY("STK register 0x%03X has 0x%02X, " - "expected 0x%02X\n", - stk1160configNTSC[i0].reg, - ir, stk1160configNTSC[i0].set); - } - i0++; - } - } else { - while (0xFFF != stk1160configPAL[i0].reg) { - if (0x000 == stk1160configPAL[i0].reg) { - i0++; continue; - } - if (0x002 == stk1160configPAL[i0].reg) { - i0++; continue; - } - ir = read_stk(p, stk1160configPAL[i0].reg); - if (0x100 == stk1160configPAL[i0].reg) { - if ((ir != (0xFF & stk1160configPAL[i0].set)) && - (ir != (0x80 | (0xFF & - stk1160configPAL[i0].set))) && - (0xFFFF != - stk1160configPAL[i0].set)) { - SAY("STK register 0x%03X has 0x%02X, " - "expected 0x%02X\n", - stk1160configPAL[i0].reg, - ir, stk1160configPAL[i0].set); - } - i0++; continue; - } - if ((ir != (0xFF & stk1160configPAL[i0].set)) && - (0xFFFF != stk1160configPAL[i0].set)) { - SAY("STK register 0x%03X has 0x%02X, " - "expected 0x%02X\n", - stk1160configPAL[i0].reg, - ir, stk1160configPAL[i0].set); + cfg = (ntsc) ? stk1160configNTSC : stk1160configPAL; + + for (i = 0; 0xFFF != cfg[i].reg; i++) { + if (0x000 == cfg[i].reg || 0x002 == cfg[i].reg) + continue; + + + ir = read_stk(p, cfg[i].reg); + if (0x100 == cfg[i].reg) { + if ((ir != (0xFF & cfg[i].set)) && + (ir != (0x80 | (0xFF & cfg[i].set))) && + (0xFFFF != cfg[i].set)) { + SAY("STK reg[0x%03X]=0x%02X expected 0x%02X\n", + cfg[i].reg, ir, cfg[i].set); } - i0++; + continue; } + if ((ir != (0xFF & cfg[i].set)) && (0xFFFF != cfg[i].set)) + SAY("STK register 0x%03X has 0x%02X,expected 0x%02X\n", + cfg[i].reg, ir, cfg[i].set); } return 0; } -- cgit v1.2.3 From cb81fa07f8beaead14ce500a0e43171591a03ea7 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 6 Mar 2011 00:55:22 +0200 Subject: staging/easycap: kill EASYCAP_IS_VIDEODEV_CLIENT compilation conditional remove EASYCAP_IS_VIDEODEV_CLIENT and irrelevant code as the define is always set in the in-kernel driver Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/Makefile | 1 - drivers/staging/easycap/easycap.h | 10 +--- drivers/staging/easycap/easycap_main.c | 93 ----------------------------- drivers/staging/easycap/easycap_sound_oss.c | 8 --- 4 files changed, 1 insertion(+), 111 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/Makefile b/drivers/staging/easycap/Makefile index 1f9331ba4882..b13e9ac473ba 100644 --- a/drivers/staging/easycap/Makefile +++ b/drivers/staging/easycap/Makefile @@ -9,5 +9,4 @@ easycap-$(CONFIG_EASYCAP_OSS) += easycap_sound_oss.o obj-$(CONFIG_EASYCAP) += easycap.o ccflags-y := -Wall -ccflags-y += -DEASYCAP_IS_VIDEODEV_CLIENT diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index a80d023a8f0b..1f94e2389efc 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -29,7 +29,6 @@ * THE FOLLOWING PARAMETERS ARE UNDEFINED: * * EASYCAP_DEBUG - * EASYCAP_IS_VIDEODEV_CLIENT * * IF REQUIRED THEY MUST BE EXTERNALLY DEFINED, FOR EXAMPLE AS COMPILER * OPTIONS. @@ -81,12 +80,8 @@ #include #include #endif /* !CONFIG_EASYCAP_OSS */ -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#ifdef EASYCAP_IS_VIDEODEV_CLIENT #include #include -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ #include #include @@ -295,12 +290,9 @@ struct easycap { int isdongle; int minor; -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#ifdef EASYCAP_IS_VIDEODEV_CLIENT struct video_device video_device; struct v4l2_device v4l2_device; -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + int status; unsigned int audio_pages_per_fragment; unsigned int audio_bytes_per_fragment; diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index d4d58e4bfe78..cee3252ea2d9 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -141,38 +141,19 @@ int isdongle(struct easycap *peasycap) /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ static int easycap_open(struct inode *inode, struct file *file) { - #ifndef EASYCAP_IS_VIDEODEV_CLIENT - struct usb_interface *pusb_interface; - #else struct video_device *pvideo_device; - #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ struct easycap *peasycap; int rc; JOT(4, "\n"); SAY("==========OPEN=========\n"); -/*---------------------------------------------------------------------------*/ -#ifndef EASYCAP_IS_VIDEODEV_CLIENT - if (!inode) { - SAY("ERROR: inode is NULL.\n"); - return -EFAULT; - } - pusb_interface = usb_find_interface(&easycap_usb_driver, iminor(inode)); - if (!pusb_interface) { - SAY("ERROR: pusb_interface is NULL.\n"); - return -EFAULT; - } - peasycap = usb_get_intfdata(pusb_interface); -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#else pvideo_device = video_devdata(file); if (!pvideo_device) { SAY("ERROR: pvideo_device is NULL.\n"); return -EFAULT; } peasycap = (struct easycap *)video_get_drvdata(pvideo_device); -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; @@ -710,41 +691,11 @@ int kill_video_urbs(struct easycap *peasycap) /****************************************************************************/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*--------------------------------------------------------------------------*/ -static int easycap_release(struct inode *inode, struct file *file) -{ -#ifndef EASYCAP_IS_VIDEODEV_CLIENT - struct easycap *peasycap; - - - peasycap = file->private_data; - if (!peasycap) { - SAY("ERROR: peasycap is NULL.\n"); - SAY("ending unsuccessfully\n"); - return -EFAULT; - } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return -EFAULT; - } - if (0 != kill_video_urbs(peasycap)) { - SAM("ERROR: kill_video_urbs() failed\n"); - return -EFAULT; - } - JOM(4, "ending successfully\n"); -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ - - return 0; -} -#ifdef EASYCAP_IS_VIDEODEV_CLIENT static int easycap_open_noinode(struct file *file) { return easycap_open(NULL, file); } -static int easycap_release_noinode(struct file *file) -{ - return easycap_release(NULL, file); -} static int videodev_release(struct video_device *pvideo_device) { struct easycap *peasycap; @@ -766,7 +717,6 @@ static int videodev_release(struct video_device *pvideo_device) JOM(4, "ending successfully\n"); return 0; } -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*****************************************************************************/ /*--------------------------------------------------------------------------*/ @@ -3011,7 +2961,6 @@ static void easycap_complete(struct urb *purb) static const struct file_operations easycap_fops = { .owner = THIS_MODULE, .open = easycap_open, - .release = easycap_release, .unlocked_ioctl = easycap_unlocked_ioctl, .poll = easycap_poll, .mmap = easycap_mmap, @@ -3023,16 +2972,13 @@ static const struct usb_class_driver easycap_class = { .minor_base = USB_SKEL_MINOR_BASE, }; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#ifdef EASYCAP_IS_VIDEODEV_CLIENT static const struct v4l2_file_operations v4l2_fops = { .owner = THIS_MODULE, .open = easycap_open_noinode, - .release = easycap_release_noinode, .unlocked_ioctl = easycap_unlocked_ioctl, .poll = easycap_poll, .mmap = easycap_mmap, }; -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* @@ -3073,11 +3019,7 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, struct easycap_format *peasycap_format; int fmtidx; struct inputset *inputset; -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#ifdef EASYCAP_IS_VIDEODEV_CLIENT struct v4l2_device *pv4l2_device; -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*---------------------------------------------------------------------------*/ /* @@ -3351,7 +3293,6 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, bInterfaceNumber); return -ENODEV; } -#ifdef EASYCAP_IS_VIDEODEV_CLIENT /*---------------------------------------------------------------------------*/ /* * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS @@ -3369,7 +3310,6 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, peasycap = (struct easycap *) container_of(pv4l2_device, struct easycap, v4l2_device); } -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ } /*---------------------------------------------------------------------------*/ if ((USB_CLASS_VIDEO == bInterfaceClass) || @@ -3926,19 +3866,6 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, * THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY. */ /*--------------------------------------------------------------------------*/ -#ifndef EASYCAP_IS_VIDEODEV_CLIENT - if (0 != (usb_register_dev(pusb_interface, &easycap_class))) { - err("Not able to get a minor for this device"); - usb_set_intfdata(pusb_interface, NULL); - return -ENODEV; - } else { - (peasycap->registered_video)++; - SAM("easycap attached to minor #%d\n", pusb_interface->minor); - peasycap->minor = pusb_interface->minor; - break; - } -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#else if (0 != (v4l2_device_register(&(pusb_interface->dev), &(peasycap->v4l2_device)))) { SAM("v4l2_device_register() failed\n"); @@ -3977,7 +3904,6 @@ static int easycap_usb_probe(struct usb_interface *pusb_interface, peasycap->video_device.minor); peasycap->minor = peasycap->video_device.minor; } -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ break; @@ -4330,11 +4256,7 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) struct list_head *plist_head; struct data_urb *pdata_urb; int minor, m, kd; -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#ifdef EASYCAP_IS_VIDEODEV_CLIENT struct v4l2_device *pv4l2_device; -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ JOT(4, "\n"); @@ -4361,8 +4283,6 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) return; } /*---------------------------------------------------------------------------*/ -#ifdef EASYCAP_IS_VIDEODEV_CLIENT -/*---------------------------------------------------------------------------*/ /* * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(), @@ -4379,7 +4299,6 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) peasycap = (struct easycap *) container_of(pv4l2_device, struct easycap, v4l2_device); } -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*---------------------------------------------------------------------------*/ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { @@ -4463,17 +4382,6 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); } /*---------------------------------------------------------------------------*/ -#ifndef EASYCAP_IS_VIDEODEV_CLIENT - if (!peasycap) { - SAM("ERROR: peasycap has become NULL\n"); - } else { - usb_deregister_dev(pusb_interface, &easycap_class); - peasycap->registered_video--; - JOM(4, "intf[%i]: usb_deregister_dev() minor = %i\n", - bInterfaceNumber, minor); - } -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#else if (!peasycap->v4l2_device.name[0]) { SAM("ERROR: peasycap->v4l2_device.name is empty\n"); if (0 <= kd && DONGLE_MANY > kd) @@ -4489,7 +4397,6 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) JOM(4, "intf[%i]: video_unregister_device() minor=%i\n", bInterfaceNumber, minor); peasycap->registered_video--; -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ if (0 <= kd && DONGLE_MANY > kd) { diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c index d3980a62a163..d92baf222765 100644 --- a/drivers/staging/easycap/easycap_sound_oss.c +++ b/drivers/staging/easycap/easycap_sound_oss.c @@ -277,11 +277,7 @@ static int easyoss_open(struct inode *inode, struct file *file) struct usb_interface *pusb_interface; struct easycap *peasycap; int subminor; -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#ifdef EASYCAP_IS_VIDEODEV_CLIENT struct v4l2_device *pv4l2_device; -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ JOT(4, "begins\n"); @@ -300,8 +296,6 @@ static int easyoss_open(struct inode *inode, struct file *file) return -1; } /*---------------------------------------------------------------------------*/ -#ifdef EASYCAP_IS_VIDEODEV_CLIENT -/*---------------------------------------------------------------------------*/ /* * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(), @@ -318,8 +312,6 @@ static int easyoss_open(struct inode *inode, struct file *file) peasycap = container_of(pv4l2_device, struct easycap, v4l2_device); } -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*---------------------------------------------------------------------------*/ if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { SAY("ERROR: bad peasycap: %p\n", peasycap); -- cgit v1.2.3 From 31410596a87a71d677d21c2503b0549ff3df63a4 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 6 Mar 2011 00:55:23 +0200 Subject: staging/easycap: add first level indentation to easycap_settings.c Add first level indentation to easycap_sound_settings with astyle -t8 10 lines over 80 characters were left out for further fix Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_settings.c | 1100 ++++++++++++++-------------- 1 file changed, 560 insertions(+), 540 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_settings.c b/drivers/staging/easycap/easycap_settings.c index 22d69cca549a..aa1f6293f9f2 100644 --- a/drivers/staging/easycap/easycap_settings.c +++ b/drivers/staging/easycap/easycap_settings.c @@ -39,252 +39,255 @@ */ /*---------------------------------------------------------------------------*/ const struct easycap_standard easycap_standard[] = { -{ -.mask = 0x00FF & PAL_BGHIN , -.v4l2_standard = { - .index = PAL_BGHIN, - .id = (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | - V4L2_STD_PAL_I | V4L2_STD_PAL_N), - .name = "PAL_BGHIN", - .frameperiod = {1, 25}, - .framelines = 625, - .reserved = {0, 0, 0, 0} - } -}, + { + .mask = 0x00FF & PAL_BGHIN , + .v4l2_standard = { + .index = PAL_BGHIN, + .id = (V4L2_STD_PAL_B | + V4L2_STD_PAL_G | V4L2_STD_PAL_H | + V4L2_STD_PAL_I | V4L2_STD_PAL_N), + .name = "PAL_BGHIN", + .frameperiod = {1, 25}, + .framelines = 625, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x00FF & NTSC_N_443 , -.v4l2_standard = { - .index = NTSC_N_443, - .id = V4L2_STD_UNKNOWN, - .name = "NTSC_N_443", - .frameperiod = {1, 25}, - .framelines = 480, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x00FF & NTSC_N_443 , + .v4l2_standard = { + .index = NTSC_N_443, + .id = V4L2_STD_UNKNOWN, + .name = "NTSC_N_443", + .frameperiod = {1, 25}, + .framelines = 480, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x00FF & PAL_Nc , -.v4l2_standard = { - .index = PAL_Nc, - .id = V4L2_STD_PAL_Nc, - .name = "PAL_Nc", - .frameperiod = {1, 25}, - .framelines = 625, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x00FF & PAL_Nc , + .v4l2_standard = { + .index = PAL_Nc, + .id = V4L2_STD_PAL_Nc, + .name = "PAL_Nc", + .frameperiod = {1, 25}, + .framelines = 625, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x00FF & NTSC_N , -.v4l2_standard = { - .index = NTSC_N, - .id = V4L2_STD_UNKNOWN, - .name = "NTSC_N", - .frameperiod = {1, 25}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x00FF & NTSC_N , + .v4l2_standard = { + .index = NTSC_N, + .id = V4L2_STD_UNKNOWN, + .name = "NTSC_N", + .frameperiod = {1, 25}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x00FF & SECAM , -.v4l2_standard = { - .index = SECAM, - .id = V4L2_STD_SECAM, - .name = "SECAM", - .frameperiod = {1, 25}, - .framelines = 625, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x00FF & SECAM , + .v4l2_standard = { + .index = SECAM, + .id = V4L2_STD_SECAM, + .name = "SECAM", + .frameperiod = {1, 25}, + .framelines = 625, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x00FF & NTSC_M , -.v4l2_standard = { - .index = NTSC_M, - .id = V4L2_STD_NTSC_M, - .name = "NTSC_M", - .frameperiod = {1, 30}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x00FF & NTSC_M , + .v4l2_standard = { + .index = NTSC_M, + .id = V4L2_STD_NTSC_M, + .name = "NTSC_M", + .frameperiod = {1, 30}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x00FF & NTSC_M_JP , -.v4l2_standard = { - .index = NTSC_M_JP, - .id = V4L2_STD_NTSC_M_JP, - .name = "NTSC_M_JP", - .frameperiod = {1, 30}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x00FF & NTSC_M_JP , + .v4l2_standard = { + .index = NTSC_M_JP, + .id = V4L2_STD_NTSC_M_JP, + .name = "NTSC_M_JP", + .frameperiod = {1, 30}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x00FF & PAL_60 , -.v4l2_standard = { - .index = PAL_60, - .id = V4L2_STD_PAL_60, - .name = "PAL_60", - .frameperiod = {1, 30}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x00FF & PAL_60 , + .v4l2_standard = { + .index = PAL_60, + .id = V4L2_STD_PAL_60, + .name = "PAL_60", + .frameperiod = {1, 30}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x00FF & NTSC_443 , -.v4l2_standard = { - .index = NTSC_443, - .id = V4L2_STD_NTSC_443, - .name = "NTSC_443", - .frameperiod = {1, 30}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x00FF & NTSC_443 , + .v4l2_standard = { + .index = NTSC_443, + .id = V4L2_STD_NTSC_443, + .name = "NTSC_443", + .frameperiod = {1, 30}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x00FF & PAL_M , -.v4l2_standard = { - .index = PAL_M, - .id = V4L2_STD_PAL_M, - .name = "PAL_M", - .frameperiod = {1, 30}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x00FF & PAL_M , + .v4l2_standard = { + .index = PAL_M, + .id = V4L2_STD_PAL_M, + .name = "PAL_M", + .frameperiod = {1, 30}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & PAL_BGHIN_SLOW), -.v4l2_standard = { - .index = PAL_BGHIN_SLOW, - .id = (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | + { + .mask = 0x8000 | (0x00FF & PAL_BGHIN_SLOW), + .v4l2_standard = { + .index = PAL_BGHIN_SLOW, + .id = (V4L2_STD_PAL_B | V4L2_STD_PAL_G | + V4L2_STD_PAL_H | V4L2_STD_PAL_I | V4L2_STD_PAL_N | - (((v4l2_std_id)0x01) << 32)), - .name = "PAL_BGHIN_SLOW", - .frameperiod = {1, 5}, - .framelines = 625, - .reserved = {0, 0, 0, 0} -} -}, + (((v4l2_std_id)0x01) << 32)), + .name = "PAL_BGHIN_SLOW", + .frameperiod = {1, 5}, + .framelines = 625, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & NTSC_N_443_SLOW), -.v4l2_standard = { - .index = NTSC_N_443_SLOW, - .id = (V4L2_STD_UNKNOWN | (((v4l2_std_id)0x11) << 32)), - .name = "NTSC_N_443_SLOW", - .frameperiod = {1, 5}, - .framelines = 480, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x8000 | (0x00FF & NTSC_N_443_SLOW), + .v4l2_standard = { + .index = NTSC_N_443_SLOW, + .id = (V4L2_STD_UNKNOWN | (((v4l2_std_id)0x11) << 32)), + .name = "NTSC_N_443_SLOW", + .frameperiod = {1, 5}, + .framelines = 480, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & PAL_Nc_SLOW), -.v4l2_standard = { - .index = PAL_Nc_SLOW, - .id = (V4L2_STD_PAL_Nc | (((v4l2_std_id)0x01) << 32)), - .name = "PAL_Nc_SLOW", - .frameperiod = {1, 5}, - .framelines = 625, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x8000 | (0x00FF & PAL_Nc_SLOW), + .v4l2_standard = { + .index = PAL_Nc_SLOW, + .id = (V4L2_STD_PAL_Nc | (((v4l2_std_id)0x01) << 32)), + .name = "PAL_Nc_SLOW", + .frameperiod = {1, 5}, + .framelines = 625, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & NTSC_N_SLOW), -.v4l2_standard = { - .index = NTSC_N_SLOW, - .id = (V4L2_STD_UNKNOWN | (((v4l2_std_id)0x21) << 32)), - .name = "NTSC_N_SLOW", - .frameperiod = {1, 5}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x8000 | (0x00FF & NTSC_N_SLOW), + .v4l2_standard = { + .index = NTSC_N_SLOW, + .id = (V4L2_STD_UNKNOWN | (((v4l2_std_id)0x21) << 32)), + .name = "NTSC_N_SLOW", + .frameperiod = {1, 5}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & SECAM_SLOW), -.v4l2_standard = { - .index = SECAM_SLOW, - .id = (V4L2_STD_SECAM | (((v4l2_std_id)0x01) << 32)), - .name = "SECAM_SLOW", - .frameperiod = {1, 5}, - .framelines = 625, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x8000 | (0x00FF & SECAM_SLOW), + .v4l2_standard = { + .index = SECAM_SLOW, + .id = (V4L2_STD_SECAM | (((v4l2_std_id)0x01) << 32)), + .name = "SECAM_SLOW", + .frameperiod = {1, 5}, + .framelines = 625, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & NTSC_M_SLOW), -.v4l2_standard = { - .index = NTSC_M_SLOW, - .id = (V4L2_STD_NTSC_M | (((v4l2_std_id)0x01) << 32)), - .name = "NTSC_M_SLOW", - .frameperiod = {1, 6}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x8000 | (0x00FF & NTSC_M_SLOW), + .v4l2_standard = { + .index = NTSC_M_SLOW, + .id = (V4L2_STD_NTSC_M | (((v4l2_std_id)0x01) << 32)), + .name = "NTSC_M_SLOW", + .frameperiod = {1, 6}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & NTSC_M_JP_SLOW), -.v4l2_standard = { - .index = NTSC_M_JP_SLOW, - .id = (V4L2_STD_NTSC_M_JP | (((v4l2_std_id)0x01) << 32)), - .name = "NTSC_M_JP_SLOW", - .frameperiod = {1, 6}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x8000 | (0x00FF & NTSC_M_JP_SLOW), + .v4l2_standard = { + .index = NTSC_M_JP_SLOW, + .id = (V4L2_STD_NTSC_M_JP | + (((v4l2_std_id)0x01) << 32)), + .name = "NTSC_M_JP_SLOW", + .frameperiod = {1, 6}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & PAL_60_SLOW), -.v4l2_standard = { - .index = PAL_60_SLOW, - .id = (V4L2_STD_PAL_60 | (((v4l2_std_id)0x01) << 32)), - .name = "PAL_60_SLOW", - .frameperiod = {1, 6}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x8000 | (0x00FF & PAL_60_SLOW), + .v4l2_standard = { + .index = PAL_60_SLOW, + .id = (V4L2_STD_PAL_60 | (((v4l2_std_id)0x01) << 32)), + .name = "PAL_60_SLOW", + .frameperiod = {1, 6}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & NTSC_443_SLOW), -.v4l2_standard = { - .index = NTSC_443_SLOW, - .id = (V4L2_STD_NTSC_443 | (((v4l2_std_id)0x01) << 32)), - .name = "NTSC_443_SLOW", - .frameperiod = {1, 6}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x8000 | (0x00FF & NTSC_443_SLOW), + .v4l2_standard = { + .index = NTSC_443_SLOW, + .id = (V4L2_STD_NTSC_443 | (((v4l2_std_id)0x01) << 32)), + .name = "NTSC_443_SLOW", + .frameperiod = {1, 6}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & PAL_M_SLOW), -.v4l2_standard = { - .index = PAL_M_SLOW, - .id = (V4L2_STD_PAL_M | (((v4l2_std_id)0x01) << 32)), - .name = "PAL_M_SLOW", - .frameperiod = {1, 6}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x8000 | (0x00FF & PAL_M_SLOW), + .v4l2_standard = { + .index = PAL_M_SLOW, + .id = (V4L2_STD_PAL_M | (((v4l2_std_id)0x01) << 32)), + .name = "PAL_M_SLOW", + .frameperiod = {1, 6}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0xFFFF -} + { + .mask = 0xFFFF + } }; /*---------------------------------------------------------------------------*/ /* @@ -313,368 +316,385 @@ struct easycap_format easycap_format[1 + SETTINGS_MANY]; int fillin_formats(void) { -int i, j, k, m, n; -u32 width, height, pixelformat, bytesperline, sizeimage; -enum v4l2_field field; -enum v4l2_colorspace colorspace; -u16 mask1, mask2, mask3, mask4; -char name1[32], name2[32], name3[32], name4[32]; -for (i = 0, n = 0; i < STANDARD_MANY; i++) { - mask1 = 0x0000; - switch (i) { - case PAL_BGHIN: { - mask1 = 0x1F & PAL_BGHIN; - strcpy(&name1[0], "PAL_BGHIN"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case SECAM: { - mask1 = 0x1F & SECAM; - strcpy(&name1[0], "SECAM"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case PAL_Nc: { - mask1 = 0x1F & PAL_Nc; - strcpy(&name1[0], "PAL_Nc"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case PAL_60: { - mask1 = 0x1F & PAL_60; - strcpy(&name1[0], "PAL_60"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case PAL_M: { - mask1 = 0x1F & PAL_M; - strcpy(&name1[0], "PAL_M"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case NTSC_M: { - mask1 = 0x1F & NTSC_M; - strcpy(&name1[0], "NTSC_M"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - case NTSC_443: { - mask1 = 0x1F & NTSC_443; - strcpy(&name1[0], "NTSC_443"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - case NTSC_M_JP: { - mask1 = 0x1F & NTSC_M_JP; - strcpy(&name1[0], "NTSC_M_JP"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - case NTSC_N: { - mask1 = 0x1F & NTSC_M; - strcpy(&name1[0], "NTSC_N"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - case NTSC_N_443: { - mask1 = 0x1F & NTSC_N_443; - strcpy(&name1[0], "NTSC_N_443"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - case PAL_BGHIN_SLOW: { - mask1 = 0x001F & PAL_BGHIN_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "PAL_BGHIN_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case SECAM_SLOW: { - mask1 = 0x001F & SECAM_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "SECAM_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case PAL_Nc_SLOW: { - mask1 = 0x001F & PAL_Nc_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "PAL_Nc_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case PAL_60_SLOW: { - mask1 = 0x001F & PAL_60_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "PAL_60_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case PAL_M_SLOW: { - mask1 = 0x001F & PAL_M_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "PAL_M_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case NTSC_M_SLOW: { - mask1 = 0x001F & NTSC_M_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "NTSC_M_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - case NTSC_443_SLOW: { - mask1 = 0x001F & NTSC_443_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "NTSC_443_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - case NTSC_M_JP_SLOW: { - mask1 = 0x001F & NTSC_M_JP_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "NTSC_M_JP_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - case NTSC_N_SLOW: { - mask1 = 0x001F & NTSC_N_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "NTSC_N_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - case NTSC_N_443_SLOW: { - mask1 = 0x001F & NTSC_N_443_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "NTSC_N_443_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - default: - return -1; - } - - for (j = 0; j < RESOLUTION_MANY; j++) { - mask2 = 0x0000; - switch (j) { - case AT_720x576: { - if (0x1 & mask1) - continue; - strcpy(&name2[0], "_AT_720x576"); - width = 720; height = 576; break; - } - case AT_704x576: { - if (0x1 & mask1) - continue; - strcpy(&name2[0], "_AT_704x576"); - width = 704; height = 576; break; - } - case AT_640x480: { - strcpy(&name2[0], "_AT_640x480"); - width = 640; height = 480; break; - } - case AT_720x480: { - if (!(0x1 & mask1)) - continue; - strcpy(&name2[0], "_AT_720x480"); - width = 720; height = 480; break; - } - case AT_360x288: { - if (0x1 & mask1) - continue; - strcpy(&name2[0], "_AT_360x288"); - width = 360; height = 288; mask2 = 0x0800; break; - } - case AT_320x240: { - strcpy(&name2[0], "_AT_320x240"); - width = 320; height = 240; mask2 = 0x0800; break; - } - case AT_360x240: { - if (!(0x1 & mask1)) - continue; - strcpy(&name2[0], "_AT_360x240"); - width = 360; height = 240; mask2 = 0x0800; break; + int i, j, k, m, n; + u32 width, height, pixelformat, bytesperline, sizeimage; + enum v4l2_field field; + enum v4l2_colorspace colorspace; + u16 mask1, mask2, mask3, mask4; + char name1[32], name2[32], name3[32], name4[32]; + for (i = 0, n = 0; i < STANDARD_MANY; i++) { + mask1 = 0x0000; + switch (i) { + case PAL_BGHIN: { + mask1 = 0x1F & PAL_BGHIN; + strcpy(&name1[0], "PAL_BGHIN"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case SECAM: { + mask1 = 0x1F & SECAM; + strcpy(&name1[0], "SECAM"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case PAL_Nc: { + mask1 = 0x1F & PAL_Nc; + strcpy(&name1[0], "PAL_Nc"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case PAL_60: { + mask1 = 0x1F & PAL_60; + strcpy(&name1[0], "PAL_60"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case PAL_M: { + mask1 = 0x1F & PAL_M; + strcpy(&name1[0], "PAL_M"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case NTSC_M: { + mask1 = 0x1F & NTSC_M; + strcpy(&name1[0], "NTSC_M"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_443: { + mask1 = 0x1F & NTSC_443; + strcpy(&name1[0], "NTSC_443"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_M_JP: { + mask1 = 0x1F & NTSC_M_JP; + strcpy(&name1[0], "NTSC_M_JP"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_N: { + mask1 = 0x1F & NTSC_M; + strcpy(&name1[0], "NTSC_N"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_N_443: { + mask1 = 0x1F & NTSC_N_443; + strcpy(&name1[0], "NTSC_N_443"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case PAL_BGHIN_SLOW: { + mask1 = 0x001F & PAL_BGHIN_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "PAL_BGHIN_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case SECAM_SLOW: { + mask1 = 0x001F & SECAM_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "SECAM_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case PAL_Nc_SLOW: { + mask1 = 0x001F & PAL_Nc_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "PAL_Nc_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case PAL_60_SLOW: { + mask1 = 0x001F & PAL_60_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "PAL_60_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case PAL_M_SLOW: { + mask1 = 0x001F & PAL_M_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "PAL_M_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case NTSC_M_SLOW: { + mask1 = 0x001F & NTSC_M_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "NTSC_M_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_443_SLOW: { + mask1 = 0x001F & NTSC_443_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "NTSC_443_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_M_JP_SLOW: { + mask1 = 0x001F & NTSC_M_JP_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "NTSC_M_JP_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_N_SLOW: { + mask1 = 0x001F & NTSC_N_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "NTSC_N_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_N_443_SLOW: { + mask1 = 0x001F & NTSC_N_443_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "NTSC_N_443_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; } default: - return -2; + return -1; } - for (k = 0; k < PIXELFORMAT_MANY; k++) { - mask3 = 0x0000; - switch (k) { - case FMT_UYVY: { - strcpy(&name3[0], "_" __stringify(FMT_UYVY)); - pixelformat = V4L2_PIX_FMT_UYVY; - mask3 |= (0x02 << 5); + for (j = 0; j < RESOLUTION_MANY; j++) { + mask2 = 0x0000; + switch (j) { + case AT_720x576: { + if (0x1 & mask1) + continue; + strcpy(&name2[0], "_AT_720x576"); + width = 720; + height = 576; + break; + } + case AT_704x576: { + if (0x1 & mask1) + continue; + strcpy(&name2[0], "_AT_704x576"); + width = 704; + height = 576; break; } - case FMT_YUY2: { - strcpy(&name3[0], "_" __stringify(FMT_YUY2)); - pixelformat = V4L2_PIX_FMT_YUYV; - mask3 |= (0x02 << 5); - mask3 |= 0x0100; + case AT_640x480: { + strcpy(&name2[0], "_AT_640x480"); + width = 640; + height = 480; break; } - case FMT_RGB24: { - strcpy(&name3[0], "_" __stringify(FMT_RGB24)); - pixelformat = V4L2_PIX_FMT_RGB24; - mask3 |= (0x03 << 5); + case AT_720x480: { + if (!(0x1 & mask1)) + continue; + strcpy(&name2[0], "_AT_720x480"); + width = 720; + height = 480; break; } - case FMT_RGB32: { - strcpy(&name3[0], "_" __stringify(FMT_RGB32)); - pixelformat = V4L2_PIX_FMT_RGB32; - mask3 |= (0x04 << 5); + case AT_360x288: { + if (0x1 & mask1) + continue; + strcpy(&name2[0], "_AT_360x288"); + width = 360; + height = 288; + mask2 = 0x0800; break; } - case FMT_BGR24: { - strcpy(&name3[0], "_" __stringify(FMT_BGR24)); - pixelformat = V4L2_PIX_FMT_BGR24; - mask3 |= (0x03 << 5); - mask3 |= 0x0100; + case AT_320x240: { + strcpy(&name2[0], "_AT_320x240"); + width = 320; + height = 240; + mask2 = 0x0800; break; } - case FMT_BGR32: { - strcpy(&name3[0], "_" __stringify(FMT_BGR32)); - pixelformat = V4L2_PIX_FMT_BGR32; - mask3 |= (0x04 << 5); - mask3 |= 0x0100; + case AT_360x240: { + if (!(0x1 & mask1)) + continue; + strcpy(&name2[0], "_AT_360x240"); + width = 360; + height = 240; + mask2 = 0x0800; break; } default: - return -3; + return -2; } - bytesperline = width * ((mask3 & 0x00F0) >> 4); - sizeimage = bytesperline * height; - for (m = 0; m < INTERLACE_MANY; m++) { - mask4 = 0x0000; - switch (m) { - case FIELD_NONE: { - strcpy(&name4[0], "-n"); - field = V4L2_FIELD_NONE; + for (k = 0; k < PIXELFORMAT_MANY; k++) { + mask3 = 0x0000; + switch (k) { + case FMT_UYVY: { + strcpy(&name3[0], "_" __stringify(FMT_UYVY)); + pixelformat = V4L2_PIX_FMT_UYVY; + mask3 |= (0x02 << 5); + break; + } + case FMT_YUY2: { + strcpy(&name3[0], "_" __stringify(FMT_YUY2)); + pixelformat = V4L2_PIX_FMT_YUYV; + mask3 |= (0x02 << 5); + mask3 |= 0x0100; + break; + } + case FMT_RGB24: { + strcpy(&name3[0], "_" __stringify(FMT_RGB24)); + pixelformat = V4L2_PIX_FMT_RGB24; + mask3 |= (0x03 << 5); break; } - case FIELD_INTERLACED: { - strcpy(&name4[0], "-i"); - mask4 |= 0x1000; - field = V4L2_FIELD_INTERLACED; + case FMT_RGB32: { + strcpy(&name3[0], "_" __stringify(FMT_RGB32)); + pixelformat = V4L2_PIX_FMT_RGB32; + mask3 |= (0x04 << 5); + break; + } + case FMT_BGR24: { + strcpy(&name3[0], "_" __stringify(FMT_BGR24)); + pixelformat = V4L2_PIX_FMT_BGR24; + mask3 |= (0x03 << 5); + mask3 |= 0x0100; + break; + } + case FMT_BGR32: { + strcpy(&name3[0], "_" __stringify(FMT_BGR32)); + pixelformat = V4L2_PIX_FMT_BGR32; + mask3 |= (0x04 << 5); + mask3 |= 0x0100; break; } default: - return -4; + return -3; } - if (SETTINGS_MANY <= n) - return -5; - strcpy(&easycap_format[n].name[0], &name1[0]); - strcat(&easycap_format[n].name[0], &name2[0]); - strcat(&easycap_format[n].name[0], &name3[0]); - strcat(&easycap_format[n].name[0], &name4[0]); - easycap_format[n].mask = + bytesperline = width * ((mask3 & 0x00F0) >> 4); + sizeimage = bytesperline * height; + + for (m = 0; m < INTERLACE_MANY; m++) { + mask4 = 0x0000; + switch (m) { + case FIELD_NONE: { + strcpy(&name4[0], "-n"); + field = V4L2_FIELD_NONE; + break; + } + case FIELD_INTERLACED: { + strcpy(&name4[0], "-i"); + mask4 |= 0x1000; + field = V4L2_FIELD_INTERLACED; + break; + } + default: + return -4; + } + if (SETTINGS_MANY <= n) + return -5; + strcpy(&easycap_format[n].name[0], &name1[0]); + strcat(&easycap_format[n].name[0], &name2[0]); + strcat(&easycap_format[n].name[0], &name3[0]); + strcat(&easycap_format[n].name[0], &name4[0]); + easycap_format[n].mask = mask1 | mask2 | mask3 | mask4; - easycap_format[n].v4l2_format + easycap_format[n].v4l2_format .type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - easycap_format[n].v4l2_format + easycap_format[n].v4l2_format .fmt.pix.width = width; - easycap_format[n].v4l2_format + easycap_format[n].v4l2_format .fmt.pix.height = height; - easycap_format[n].v4l2_format + easycap_format[n].v4l2_format .fmt.pix.pixelformat = pixelformat; - easycap_format[n].v4l2_format + easycap_format[n].v4l2_format .fmt.pix.field = field; - easycap_format[n].v4l2_format + easycap_format[n].v4l2_format .fmt.pix.bytesperline = bytesperline; - easycap_format[n].v4l2_format + easycap_format[n].v4l2_format .fmt.pix.sizeimage = sizeimage; - easycap_format[n].v4l2_format + easycap_format[n].v4l2_format .fmt.pix.colorspace = colorspace; - easycap_format[n].v4l2_format + easycap_format[n].v4l2_format .fmt.pix.priv = 0; - n++; + n++; + } } } } -} -if ((1 + SETTINGS_MANY) <= n) - return -6; -easycap_format[n].mask = 0xFFFF; -return n; + if ((1 + SETTINGS_MANY) <= n) + return -6; + easycap_format[n].mask = 0xFFFF; + return n; } /*---------------------------------------------------------------------------*/ struct v4l2_queryctrl easycap_control[] = {{ -.id = V4L2_CID_BRIGHTNESS, -.type = V4L2_CTRL_TYPE_INTEGER, -.name = "Brightness", -.minimum = 0, -.maximum = 255, -.step = 1, -.default_value = SAA_0A_DEFAULT, -.flags = 0, -.reserved = {0, 0} -}, + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = SAA_0A_DEFAULT, + .flags = 0, + .reserved = {0, 0} + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.id = V4L2_CID_CONTRAST, -.type = V4L2_CTRL_TYPE_INTEGER, -.name = "Contrast", -.minimum = 0, -.maximum = 255, -.step = 1, -.default_value = SAA_0B_DEFAULT + 128, -.flags = 0, -.reserved = {0, 0} -}, + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = SAA_0B_DEFAULT + 128, + .flags = 0, + .reserved = {0, 0} + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.id = V4L2_CID_SATURATION, -.type = V4L2_CTRL_TYPE_INTEGER, -.name = "Saturation", -.minimum = 0, -.maximum = 255, -.step = 1, -.default_value = SAA_0C_DEFAULT + 128, -.flags = 0, -.reserved = {0, 0} -}, + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = SAA_0C_DEFAULT + 128, + .flags = 0, + .reserved = {0, 0} + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.id = V4L2_CID_HUE, -.type = V4L2_CTRL_TYPE_INTEGER, -.name = "Hue", -.minimum = 0, -.maximum = 255, -.step = 1, -.default_value = SAA_0D_DEFAULT + 128, -.flags = 0, -.reserved = {0, 0} -}, + { + .id = V4L2_CID_HUE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Hue", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = SAA_0D_DEFAULT + 128, + .flags = 0, + .reserved = {0, 0} + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.id = V4L2_CID_AUDIO_VOLUME, -.type = V4L2_CTRL_TYPE_INTEGER, -.name = "Volume", -.minimum = 0, -.maximum = 31, -.step = 1, -.default_value = 16, -.flags = 0, -.reserved = {0, 0} -}, + { + .id = V4L2_CID_AUDIO_VOLUME, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Volume", + .minimum = 0, + .maximum = 31, + .step = 1, + .default_value = 16, + .flags = 0, + .reserved = {0, 0} + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.id = V4L2_CID_AUDIO_MUTE, -.type = V4L2_CTRL_TYPE_BOOLEAN, -.name = "Mute", -.default_value = true, -.flags = 0, -.reserved = {0, 0} -}, + { + .id = V4L2_CID_AUDIO_MUTE, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mute", + .default_value = true, + .flags = 0, + .reserved = {0, 0} + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.id = 0xFFFFFFFF -} + { + .id = 0xFFFFFFFF + } }; /*****************************************************************************/ -- cgit v1.2.3 From 07ba111f0d5127d4c830799605e2cd0922611bf5 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 6 Mar 2011 00:55:24 +0200 Subject: staging/easycap: easycap_settings.c don't copy constant strings twice eliminate copying twice a constant string just capture it using const char * pointer piggyback some other style fixes Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_settings.c | 122 ++++++++++++++--------------- 1 file changed, 59 insertions(+), 63 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_settings.c b/drivers/staging/easycap/easycap_settings.c index aa1f6293f9f2..898559dad704 100644 --- a/drivers/staging/easycap/easycap_settings.c +++ b/drivers/staging/easycap/easycap_settings.c @@ -313,145 +313,146 @@ const struct easycap_standard easycap_standard[] = { struct easycap_format easycap_format[1 + SETTINGS_MANY]; -int -fillin_formats(void) +int fillin_formats(void) { + const char *name1, *name2, *name3, *name4; + struct v4l2_format *fmt; int i, j, k, m, n; u32 width, height, pixelformat, bytesperline, sizeimage; + u16 mask1, mask2, mask3, mask4; enum v4l2_field field; enum v4l2_colorspace colorspace; - u16 mask1, mask2, mask3, mask4; - char name1[32], name2[32], name3[32], name4[32]; + for (i = 0, n = 0; i < STANDARD_MANY; i++) { mask1 = 0x0000; switch (i) { case PAL_BGHIN: { mask1 = 0x1F & PAL_BGHIN; - strcpy(&name1[0], "PAL_BGHIN"); + name1 = "PAL_BGHIN"; colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; break; } case SECAM: { mask1 = 0x1F & SECAM; - strcpy(&name1[0], "SECAM"); + name1 = "SECAM"; colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; break; } case PAL_Nc: { mask1 = 0x1F & PAL_Nc; - strcpy(&name1[0], "PAL_Nc"); + name1 = "PAL_Nc"; colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; break; } case PAL_60: { mask1 = 0x1F & PAL_60; - strcpy(&name1[0], "PAL_60"); + name1 = "PAL_60"; colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; break; } case PAL_M: { mask1 = 0x1F & PAL_M; - strcpy(&name1[0], "PAL_M"); + name1 = "PAL_M"; colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; break; } case NTSC_M: { mask1 = 0x1F & NTSC_M; - strcpy(&name1[0], "NTSC_M"); + name1 = "NTSC_M"; colorspace = V4L2_COLORSPACE_470_SYSTEM_M; break; } case NTSC_443: { mask1 = 0x1F & NTSC_443; - strcpy(&name1[0], "NTSC_443"); + name1 = "NTSC_443"; colorspace = V4L2_COLORSPACE_470_SYSTEM_M; break; } case NTSC_M_JP: { mask1 = 0x1F & NTSC_M_JP; - strcpy(&name1[0], "NTSC_M_JP"); + name1 = "NTSC_M_JP"; colorspace = V4L2_COLORSPACE_470_SYSTEM_M; break; } case NTSC_N: { mask1 = 0x1F & NTSC_M; - strcpy(&name1[0], "NTSC_N"); + name1 = "NTSC_N"; colorspace = V4L2_COLORSPACE_470_SYSTEM_M; break; } case NTSC_N_443: { mask1 = 0x1F & NTSC_N_443; - strcpy(&name1[0], "NTSC_N_443"); + name1 = "NTSC_N_443"; colorspace = V4L2_COLORSPACE_470_SYSTEM_M; break; } case PAL_BGHIN_SLOW: { mask1 = 0x001F & PAL_BGHIN_SLOW; mask1 |= 0x0200; - strcpy(&name1[0], "PAL_BGHIN_SLOW"); + name1 = "PAL_BGHIN_SLOW"; colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; break; } case SECAM_SLOW: { mask1 = 0x001F & SECAM_SLOW; mask1 |= 0x0200; - strcpy(&name1[0], "SECAM_SLOW"); + name1 = "SECAM_SLOW"; colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; break; } case PAL_Nc_SLOW: { mask1 = 0x001F & PAL_Nc_SLOW; mask1 |= 0x0200; - strcpy(&name1[0], "PAL_Nc_SLOW"); + name1 = "PAL_Nc_SLOW"; colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; break; } case PAL_60_SLOW: { mask1 = 0x001F & PAL_60_SLOW; mask1 |= 0x0200; - strcpy(&name1[0], "PAL_60_SLOW"); + name1 = "PAL_60_SLOW"; colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; break; } case PAL_M_SLOW: { mask1 = 0x001F & PAL_M_SLOW; mask1 |= 0x0200; - strcpy(&name1[0], "PAL_M_SLOW"); + name1 = "PAL_M_SLOW"; colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; break; } case NTSC_M_SLOW: { mask1 = 0x001F & NTSC_M_SLOW; mask1 |= 0x0200; - strcpy(&name1[0], "NTSC_M_SLOW"); + name1 = "NTSC_M_SLOW"; colorspace = V4L2_COLORSPACE_470_SYSTEM_M; break; } case NTSC_443_SLOW: { mask1 = 0x001F & NTSC_443_SLOW; mask1 |= 0x0200; - strcpy(&name1[0], "NTSC_443_SLOW"); + name1 = "NTSC_443_SLOW"; colorspace = V4L2_COLORSPACE_470_SYSTEM_M; break; } case NTSC_M_JP_SLOW: { mask1 = 0x001F & NTSC_M_JP_SLOW; mask1 |= 0x0200; - strcpy(&name1[0], "NTSC_M_JP_SLOW"); + name1 = "NTSC_M_JP_SLOW"; colorspace = V4L2_COLORSPACE_470_SYSTEM_M; break; } case NTSC_N_SLOW: { mask1 = 0x001F & NTSC_N_SLOW; mask1 |= 0x0200; - strcpy(&name1[0], "NTSC_N_SLOW"); + name1 = "NTSC_N_SLOW"; colorspace = V4L2_COLORSPACE_470_SYSTEM_M; break; } case NTSC_N_443_SLOW: { mask1 = 0x001F & NTSC_N_443_SLOW; mask1 |= 0x0200; - strcpy(&name1[0], "NTSC_N_443_SLOW"); + name1 = "NTSC_N_443_SLOW"; colorspace = V4L2_COLORSPACE_470_SYSTEM_M; break; } @@ -465,7 +466,7 @@ fillin_formats(void) case AT_720x576: { if (0x1 & mask1) continue; - strcpy(&name2[0], "_AT_720x576"); + name2 = "_AT_720x576"; width = 720; height = 576; break; @@ -473,13 +474,13 @@ fillin_formats(void) case AT_704x576: { if (0x1 & mask1) continue; - strcpy(&name2[0], "_AT_704x576"); + name2 = "_AT_704x576"; width = 704; height = 576; break; } case AT_640x480: { - strcpy(&name2[0], "_AT_640x480"); + name2 = "_AT_640x480"; width = 640; height = 480; break; @@ -487,7 +488,7 @@ fillin_formats(void) case AT_720x480: { if (!(0x1 & mask1)) continue; - strcpy(&name2[0], "_AT_720x480"); + name2 = "_AT_720x480"; width = 720; height = 480; break; @@ -495,14 +496,14 @@ fillin_formats(void) case AT_360x288: { if (0x1 & mask1) continue; - strcpy(&name2[0], "_AT_360x288"); + name2 = "_AT_360x288"; width = 360; height = 288; mask2 = 0x0800; break; } case AT_320x240: { - strcpy(&name2[0], "_AT_320x240"); + name2 = "_AT_320x240"; width = 320; height = 240; mask2 = 0x0800; @@ -511,7 +512,7 @@ fillin_formats(void) case AT_360x240: { if (!(0x1 & mask1)) continue; - strcpy(&name2[0], "_AT_360x240"); + name2 = "_AT_360x240"; width = 360; height = 240; mask2 = 0x0800; @@ -525,39 +526,39 @@ fillin_formats(void) mask3 = 0x0000; switch (k) { case FMT_UYVY: { - strcpy(&name3[0], "_" __stringify(FMT_UYVY)); + name3 = __stringify(FMT_UYVY); pixelformat = V4L2_PIX_FMT_UYVY; mask3 |= (0x02 << 5); break; } case FMT_YUY2: { - strcpy(&name3[0], "_" __stringify(FMT_YUY2)); + name3 = __stringify(FMT_YUY2); pixelformat = V4L2_PIX_FMT_YUYV; mask3 |= (0x02 << 5); mask3 |= 0x0100; break; } case FMT_RGB24: { - strcpy(&name3[0], "_" __stringify(FMT_RGB24)); + name3 = __stringify(FMT_RGB24); pixelformat = V4L2_PIX_FMT_RGB24; mask3 |= (0x03 << 5); break; } case FMT_RGB32: { - strcpy(&name3[0], "_" __stringify(FMT_RGB32)); + name3 = __stringify(FMT_RGB32); pixelformat = V4L2_PIX_FMT_RGB32; mask3 |= (0x04 << 5); break; } case FMT_BGR24: { - strcpy(&name3[0], "_" __stringify(FMT_BGR24)); + name3 = __stringify(FMT_BGR24); pixelformat = V4L2_PIX_FMT_BGR24; mask3 |= (0x03 << 5); mask3 |= 0x0100; break; } case FMT_BGR32: { - strcpy(&name3[0], "_" __stringify(FMT_BGR32)); + name3 = __stringify(FMT_BGR32); pixelformat = V4L2_PIX_FMT_BGR32; mask3 |= (0x04 << 5); mask3 |= 0x0100; @@ -573,12 +574,12 @@ fillin_formats(void) mask4 = 0x0000; switch (m) { case FIELD_NONE: { - strcpy(&name4[0], "-n"); + name4 = "-n"; field = V4L2_FIELD_NONE; break; } case FIELD_INTERLACED: { - strcpy(&name4[0], "-i"); + name4 = "-i"; mask4 |= 0x1000; field = V4L2_FIELD_INTERLACED; break; @@ -588,30 +589,25 @@ fillin_formats(void) } if (SETTINGS_MANY <= n) return -5; - strcpy(&easycap_format[n].name[0], &name1[0]); - strcat(&easycap_format[n].name[0], &name2[0]); - strcat(&easycap_format[n].name[0], &name3[0]); - strcat(&easycap_format[n].name[0], &name4[0]); + + strcpy(easycap_format[n].name, name1); + strcat(easycap_format[n].name, name2); + strcat(easycap_format[n].name, "_"); + strcat(easycap_format[n].name, name3); + strcat(easycap_format[n].name, name4); easycap_format[n].mask = mask1 | mask2 | mask3 | mask4; - easycap_format[n].v4l2_format - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - easycap_format[n].v4l2_format - .fmt.pix.width = width; - easycap_format[n].v4l2_format - .fmt.pix.height = height; - easycap_format[n].v4l2_format - .fmt.pix.pixelformat = pixelformat; - easycap_format[n].v4l2_format - .fmt.pix.field = field; - easycap_format[n].v4l2_format - .fmt.pix.bytesperline = bytesperline; - easycap_format[n].v4l2_format - .fmt.pix.sizeimage = sizeimage; - easycap_format[n].v4l2_format - .fmt.pix.colorspace = colorspace; - easycap_format[n].v4l2_format - .fmt.pix.priv = 0; + fmt = &easycap_format[n].v4l2_format; + + fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fmt->fmt.pix.width = width; + fmt->fmt.pix.height = height; + fmt->fmt.pix.pixelformat = pixelformat; + fmt->fmt.pix.field = field; + fmt->fmt.pix.bytesperline = bytesperline; + fmt->fmt.pix.sizeimage = sizeimage; + fmt->fmt.pix.colorspace = colorspace; + fmt->fmt.pix.priv = 0; n++; } } @@ -623,8 +619,8 @@ fillin_formats(void) return n; } /*---------------------------------------------------------------------------*/ -struct v4l2_queryctrl easycap_control[] = -{{ +struct v4l2_queryctrl easycap_control[] = { + { .id = V4L2_CID_BRIGHTNESS, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Brightness", -- cgit v1.2.3 From 5917def58ab9f5848f2d1da835a33a490d0c8c69 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 6 Mar 2011 10:59:03 +0200 Subject: staging/easycap: reduce code nesting in easycap_sound.c Reshuffle error handling to reduce indentation nesting This reduce number of lines exceeding 80 characters from 41 to 15 use: if (error) (return, goto, continue) CODE instead of: if (good) else Cc: Dan Carpenter Cc: Mike Thomas Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_sound.c | 418 ++++++++++++++++---------------- 1 file changed, 205 insertions(+), 213 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index 5829e26969d5..a3402b00a8be 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -142,122 +142,118 @@ easycap_alsa_complete(struct urb *purb) strerror(purb->iso_frame_desc[i].status), purb->iso_frame_desc[i].status); } - if (!purb->iso_frame_desc[i].status) { - more = purb->iso_frame_desc[i].actual_length; - if (!more) - peasycap->audio_mt++; - else { - if (peasycap->audio_mt) { - JOM(12, "%4i empty audio urb frames\n", - peasycap->audio_mt); - peasycap->audio_mt = 0; - } + if (purb->iso_frame_desc[i].status) { + JOM(12, "discarding audio samples because " + "%i=purb->iso_frame_desc[i].status\n", + purb->iso_frame_desc[i].status); + continue; + } + more = purb->iso_frame_desc[i].actual_length; + if (more == 0) { + peasycap->audio_mt++; + continue; + } + if (0 > more) { + SAM("MISTAKE: more is negative\n"); + return; + } - p1 = (u8 *)(purb->transfer_buffer + - purb->iso_frame_desc[i].offset); - - /* - * COPY more BYTES FROM ISOC BUFFER - * TO THE DMA BUFFER, CONVERTING - * 8-BIT MONO TO 16-BIT SIGNED - * LITTLE-ENDIAN SAMPLES IF NECESSARY - */ - while (more) { - if (0 > more) { - SAM("MISTAKE: more is negative\n"); - return; - } - much = dma_bytes - peasycap->dma_fill; - if (0 > much) { - SAM("MISTAKE: much is negative\n"); - return; - } - if (0 == much) { - peasycap->dma_fill = 0; - peasycap->dma_next = fragment_bytes; - JOM(8, "wrapped dma buffer\n"); - } - if (!peasycap->microphone) { - if (much > more) - much = more; - memcpy(prt->dma_area + - peasycap->dma_fill, - p1, much); - p1 += much; - more -= much; - } else { + if (peasycap->audio_mt) { + JOM(12, "%4i empty audio urb frames\n", + peasycap->audio_mt); + peasycap->audio_mt = 0; + } + + p1 = (u8 *)(purb->transfer_buffer + + purb->iso_frame_desc[i].offset); + + /* + * COPY more BYTES FROM ISOC BUFFER + * TO THE DMA BUFFER, CONVERTING + * 8-BIT MONO TO 16-BIT SIGNED + * LITTLE-ENDIAN SAMPLES IF NECESSARY + */ + while (more) { + much = dma_bytes - peasycap->dma_fill; + if (0 > much) { + SAM("MISTAKE: much is negative\n"); + return; + } + if (0 == much) { + peasycap->dma_fill = 0; + peasycap->dma_next = fragment_bytes; + JOM(8, "wrapped dma buffer\n"); + } + if (!peasycap->microphone) { + if (much > more) + much = more; + memcpy(prt->dma_area + peasycap->dma_fill, + p1, much); + p1 += much; + more -= much; + } else { #ifdef UPSAMPLE - if (much % 16) - JOM(8, "MISTAKE? much" - " is not divisible by 16\n"); - if (much > (16 * more)) - much = 16 * - more; - p2 = (u8 *)(prt->dma_area + peasycap->dma_fill); - - for (j = 0; j < (much/16); j++) { - newaudio = ((int) *p1) - 128; - newaudio = 128 * newaudio; - - delta = (newaudio - oldaudio) / 4; - tmp = oldaudio + delta; - - for (k = 0; k < 4; k++) { - *p2 = (0x00FF & tmp); - *(p2 + 1) = (0xFF00 & tmp) >> 8; - p2 += 2; - *p2 = (0x00FF & tmp); - *(p2 + 1) = (0xFF00 & tmp) >> 8; - p2 += 2; - tmp += delta; - } - p1++; - more--; - oldaudio = tmp; - } + if (much % 16) + JOM(8, "MISTAKE? much" + " is not divisible by 16\n"); + if (much > (16 * more)) + much = 16 * more; + p2 = (u8 *)(prt->dma_area + peasycap->dma_fill); + + for (j = 0; j < (much / 16); j++) { + newaudio = ((int) *p1) - 128; + newaudio = 128 * newaudio; + + delta = (newaudio - oldaudio) / 4; + tmp = oldaudio + delta; + + for (k = 0; k < 4; k++) { + *p2 = (0x00FF & tmp); + *(p2 + 1) = (0xFF00 & tmp) >> 8; + p2 += 2; + *p2 = (0x00FF & tmp); + *(p2 + 1) = (0xFF00 & tmp) >> 8; + p2 += 2; + tmp += delta; + } + p1++; + more--; + oldaudio = tmp; + } #else /*!UPSAMPLE*/ - if (much > (2 * more)) - much = 2 * more; - p2 = (u8 *)(prt->dma_area + peasycap->dma_fill); - - for (j = 0; j < (much / 2); j++) { - tmp = ((int) *p1) - 128; - tmp = 128 * tmp; - *p2 = (0x00FF & tmp); - *(p2 + 1) = (0xFF00 & tmp) >> 8; - p1++; - p2 += 2; - more--; - } + if (much > (2 * more)) + much = 2 * more; + p2 = (u8 *)(prt->dma_area + peasycap->dma_fill); + + for (j = 0; j < (much / 2); j++) { + tmp = ((int) *p1) - 128; + tmp = 128 * tmp; + *p2 = (0x00FF & tmp); + *(p2 + 1) = (0xFF00 & tmp) >> 8; + p1++; + p2 += 2; + more--; + } #endif /*UPSAMPLE*/ - } - peasycap->dma_fill += much; - if (peasycap->dma_fill >= peasycap->dma_next) { - isfragment = peasycap->dma_fill / fragment_bytes; - if (0 > isfragment) { - SAM("MISTAKE: isfragment is " - "negative\n"); - return; - } - peasycap->dma_read = (isfragment - 1) * fragment_bytes; - peasycap->dma_next = (isfragment + 1) * fragment_bytes; - if (dma_bytes < peasycap->dma_next) - peasycap->dma_next = fragment_bytes; - - if (0 <= peasycap->dma_read) { - JOM(8, "snd_pcm_period_elap" - "sed(), %i=" - "isfragment\n", - isfragment); - snd_pcm_period_elapsed(pss); - } - } + } + peasycap->dma_fill += much; + if (peasycap->dma_fill >= peasycap->dma_next) { + isfragment = peasycap->dma_fill / fragment_bytes; + if (0 > isfragment) { + SAM("MISTAKE: isfragment is negative\n"); + return; + } + peasycap->dma_read = (isfragment - 1) * fragment_bytes; + peasycap->dma_next = (isfragment + 1) * fragment_bytes; + if (dma_bytes < peasycap->dma_next) + peasycap->dma_next = fragment_bytes; + + if (0 <= peasycap->dma_read) { + JOM(8, "snd_pcm_period_elapsed(), %i=" + "isfragment\n", isfragment); + snd_pcm_period_elapsed(pss); } } - } else { - JOM(12, "discarding audio samples because " - "%i=purb->iso_frame_desc[i].status\n", - purb->iso_frame_desc[i].status); } #ifdef UPSAMPLE @@ -271,18 +267,18 @@ easycap_alsa_complete(struct urb *purb) */ /*---------------------------------------------------------------------------*/ resubmit: - if (peasycap->audio_isoc_streaming) { - rc = usb_submit_urb(purb, GFP_ATOMIC); - if (rc) { - if ((-ENODEV != rc) && (-ENOENT != rc)) { - SAM("ERROR: while %i=audio_idle, " - "usb_submit_urb() failed " - "with rc: -%s :%d\n", peasycap->audio_idle, - strerror(rc), rc); - } - if (0 < peasycap->audio_isoc_streaming) - (peasycap->audio_isoc_streaming)--; + if (peasycap->audio_isoc_streaming == 0) + return; + + rc = usb_submit_urb(purb, GFP_ATOMIC); + if (rc) { + if ((-ENODEV != rc) && (-ENOENT != rc)) { + SAM("ERROR: while %i=audio_idle, usb_submit_urb failed " + "with rc: -%s :%d\n", + peasycap->audio_idle, strerror(rc), rc); } + if (0 < peasycap->audio_isoc_streaming) + peasycap->audio_isoc_streaming--; } return; } @@ -643,10 +639,9 @@ int easycap_alsa_probe(struct easycap *peasycap) SAM("ERROR: Cannot do ALSA snd_card_register()\n"); snd_card_free(psnd_card); return -EFAULT; - } else { - ; - SAM("registered %s\n", &psnd_card->id[0]); } + + SAM("registered %s\n", &psnd_card->id[0]); return 0; } #endif /*! CONFIG_EASYCAP_OSS */ @@ -737,83 +732,79 @@ submit_audio_urbs(struct easycap *peasycap) SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } - if (!peasycap->audio_isoc_streaming) { - JOM(4, "initial submission of all audio urbs\n"); - rc = usb_set_interface(peasycap->pusb_device, - peasycap->audio_interface, - peasycap->audio_altsetting_on); - JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", - peasycap->audio_interface, - peasycap->audio_altsetting_on, rc); - - isbad = 0; - nospc = 0; - m = 0; - list_for_each(plist_head, (peasycap->purb_audio_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (pdata_urb) { - purb = pdata_urb->purb; - if (purb) { - isbuf = pdata_urb->isbuf; - - purb->interval = 1; - purb->dev = peasycap->pusb_device; - purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, - peasycap->audio_endpointnumber); - purb->transfer_flags = URB_ISO_ASAP; - purb->transfer_buffer = peasycap->audio_isoc_buffer[isbuf].pgo; - purb->transfer_buffer_length = peasycap->audio_isoc_buffer_size; + + if (peasycap->audio_isoc_streaming) { + JOM(4, "already streaming audio urbs\n"); + return 0; + } + + JOM(4, "initial submission of all audio urbs\n"); + rc = usb_set_interface(peasycap->pusb_device, + peasycap->audio_interface, + peasycap->audio_altsetting_on); + JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", + peasycap->audio_interface, + peasycap->audio_altsetting_on, rc); + + isbad = 0; + nospc = 0; + m = 0; + list_for_each(plist_head, peasycap->purb_audio_head) { + pdata_urb = list_entry(plist_head, struct data_urb, list_head); + if (pdata_urb && pdata_urb->purb) { + purb = pdata_urb->purb; + isbuf = pdata_urb->isbuf; + + purb->interval = 1; + purb->dev = peasycap->pusb_device; + purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, + peasycap->audio_endpointnumber); + purb->transfer_flags = URB_ISO_ASAP; + purb->transfer_buffer = peasycap->audio_isoc_buffer[isbuf].pgo; + purb->transfer_buffer_length = peasycap->audio_isoc_buffer_size; #ifdef CONFIG_EASYCAP_OSS - purb->complete = easyoss_complete; + purb->complete = easyoss_complete; #else /* CONFIG_EASYCAP_OSS */ - purb->complete = easycap_alsa_complete; + purb->complete = easycap_alsa_complete; #endif /* CONFIG_EASYCAP_OSS */ - purb->context = peasycap; - purb->start_frame = 0; - purb->number_of_packets = peasycap->audio_isoc_framesperdesc; - for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) { - purb->iso_frame_desc[j].offset = j * peasycap->audio_isoc_maxframesize; - purb->iso_frame_desc[j].length = peasycap->audio_isoc_maxframesize; - } + purb->context = peasycap; + purb->start_frame = 0; + purb->number_of_packets = peasycap->audio_isoc_framesperdesc; + for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) { + purb->iso_frame_desc[j].offset = j * peasycap->audio_isoc_maxframesize; + purb->iso_frame_desc[j].length = peasycap->audio_isoc_maxframesize; + } - rc = usb_submit_urb(purb, GFP_KERNEL); - if (rc) { - isbad++; - SAM("ERROR: usb_submit_urb() failed" - " for urb with rc: -%s: %d\n", - strerror(rc), rc); - } else { - m++; - } - } else { - isbad++; - } - } else { + rc = usb_submit_urb(purb, GFP_KERNEL); + if (rc) { isbad++; + SAM("ERROR: usb_submit_urb() failed" + " for urb with rc: -%s: %d\n", + strerror(rc), rc); + } else { + m++; } - } - if (nospc) { - SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc); - SAM("..... possibly inadequate USB bandwidth\n"); - peasycap->audio_eof = 1; - } - if (isbad) { - JOM(4, "attempting cleanup instead of submitting\n"); - list_for_each(plist_head, (peasycap->purb_audio_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (pdata_urb) { - purb = pdata_urb->purb; - if (purb) - usb_kill_urb(purb); - } - } - peasycap->audio_isoc_streaming = 0; } else { - peasycap->audio_isoc_streaming = m; - JOM(4, "submitted %i audio urbs\n", m); + isbad++; } - } else - JOM(4, "already streaming audio urbs\n"); + } + if (nospc) { + SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc); + SAM("..... possibly inadequate USB bandwidth\n"); + peasycap->audio_eof = 1; + } + if (isbad) { + JOM(4, "attempting cleanup instead of submitting\n"); + list_for_each(plist_head, (peasycap->purb_audio_head)) { + pdata_urb = list_entry(plist_head, struct data_urb, list_head); + if (pdata_urb && pdata_urb->purb) + usb_kill_urb(pdata_urb->purb); + } + peasycap->audio_isoc_streaming = 0; + } else { + peasycap->audio_isoc_streaming = m; + JOM(4, "submitted %i audio urbs\n", m); + } return 0; } @@ -834,29 +825,30 @@ kill_audio_urbs(struct easycap *peasycap) SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } - if (peasycap->audio_isoc_streaming) { - if (peasycap->purb_audio_head) { - peasycap->audio_isoc_streaming = 0; - JOM(4, "killing audio urbs\n"); - m = 0; - list_for_each(plist_head, (peasycap->purb_audio_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (pdata_urb) { - if (pdata_urb->purb) { - usb_kill_urb(pdata_urb->purb); - m++; - } - } - } - JOM(4, "%i audio urbs killed\n", m); - } else { - SAM("ERROR: peasycap->purb_audio_head is NULL\n"); - return -EFAULT; - } - } else { + + if (!peasycap->audio_isoc_streaming) { JOM(8, "%i=audio_isoc_streaming, no audio urbs killed\n", peasycap->audio_isoc_streaming); + return 0; + } + + if (!peasycap->purb_audio_head) { + SAM("ERROR: peasycap->purb_audio_head is NULL\n"); + return -EFAULT; } + + peasycap->audio_isoc_streaming = 0; + JOM(4, "killing audio urbs\n"); + m = 0; + list_for_each(plist_head, (peasycap->purb_audio_head)) { + pdata_urb = list_entry(plist_head, struct data_urb, list_head); + if (pdata_urb && pdata_urb->purb) { + usb_kill_urb(pdata_urb->purb); + m++; + } + } + JOM(4, "%i audio urbs killed\n", m); + return 0; } /*****************************************************************************/ -- cgit v1.2.3 From d542f180cd40a571a218e11b640dec27a3f627d0 Mon Sep 17 00:00:00 2001 From: Alberto Mardegan Date: Mon, 7 Mar 2011 19:48:24 +0200 Subject: staging: samsung-laptop: Samsung R410P backlight driver Here's a trivial patch which adds support to the backlight device found in Samsung R410 Plus laptops. Signed-off-by: Alberto Mardegan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index e0b390d45d8d..1813d5b6a5f9 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -570,6 +570,16 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, .callback = dmi_check_cb, }, + { + .ident = "R410 Plus", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "R410P"), + DMI_MATCH(DMI_BOARD_NAME, "R460"), + }, + .callback = dmi_check_cb, + }, { .ident = "R518", .matches = { -- cgit v1.2.3 From 34497913f2936fd43c86b007da7224bb8e77fd15 Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Thu, 3 Mar 2011 17:40:10 -0500 Subject: mmc: sdio: Allow sdio operations in other threads during sdio_add_func() This fixes a bug introduced by 807e8e40673d ("mmc: Fix sd/sdio/mmc initialization frequency retries") that prevented SDIO drivers from performing SDIO commands in their probe routines -- the above patch called mmc_claim_host() before sdio_add_func(), which causes a deadlock if an external SDIO driver calls sdio_claim_host(). Fix tested on an OLPC XO-1.75 with libertas on SDIO. Signed-off-by: Dmitry Shmidt Reviewed-and-Tested-by: Chris Ball Signed-off-by: Chris Ball --- drivers/mmc/core/sdio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 5c4a54d9b6a4..ebc62ad4cc56 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -792,7 +792,6 @@ int mmc_attach_sdio(struct mmc_host *host) */ mmc_release_host(host); err = mmc_add_card(host->card); - mmc_claim_host(host); if (err) goto remove_added; @@ -805,12 +804,12 @@ int mmc_attach_sdio(struct mmc_host *host) goto remove_added; } + mmc_claim_host(host); return 0; remove_added: /* Remove without lock if the device has been added. */ - mmc_release_host(host); mmc_sdio_remove(host); mmc_claim_host(host); remove: -- cgit v1.2.3 From 904777c784eed64f6138b82da592c89bf0d37b9c Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 7 Mar 2011 13:20:57 -0800 Subject: Staging: hv: Use generic device_driver probe function In preparation for moving all the state from struct driver_context to struct hv_driver, eliminate the probe() function from struct driver_context and use generic device_driver probe function. Signed-off-by: K. Y. Srinivasan Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 2 +- drivers/staging/hv/hv_mouse.c | 2 +- drivers/staging/hv/netvsc_drv.c | 2 +- drivers/staging/hv/storvsc_drv.c | 2 +- drivers/staging/hv/vmbus_drv.c | 5 +++-- 5 files changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 36a0adbaa987..0dff55791d26 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -186,7 +186,7 @@ static int blkvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) memcpy(&drv_ctx->class_id, &storvsc_drv_obj->base.dev_type, sizeof(struct hv_guid)); - drv_ctx->probe = blkvsc_probe; + drv_ctx->driver.probe = blkvsc_probe; drv_ctx->remove = blkvsc_remove; drv_ctx->shutdown = blkvsc_shutdown; diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 1aaaef4695e3..4a25f3b8770d 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -1021,7 +1021,7 @@ static int __init mousevsc_init(void) memcpy(&drv_ctx->class_id, &input_drv_obj->Base.dev_type, sizeof(struct hv_guid)); - drv_ctx->probe = mousevsc_probe; + drv_ctx->driver.probe = mousevsc_probe; drv_ctx->remove = mousevsc_remove; /* The driver belongs to vmbus */ diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 03f97404a2de..083f0d348598 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -511,7 +511,7 @@ static int netvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) memcpy(&drv_ctx->class_id, &net_drv_obj->base.dev_type, sizeof(struct hv_guid)); - drv_ctx->probe = netvsc_probe; + drv_ctx->driver.probe = netvsc_probe; drv_ctx->remove = netvsc_remove; /* The driver belongs to vmbus */ diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index a8427ffd162b..3fe4bdb4ec92 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -164,7 +164,7 @@ static int storvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) memcpy(&drv_ctx->class_id, &storvsc_drv_obj->base.dev_type, sizeof(struct hv_guid)); - drv_ctx->probe = storvsc_probe; + drv_ctx->driver.probe = storvsc_probe; drv_ctx->remove = storvsc_remove; /* The driver belongs to vmbus */ diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 459c707afe57..fee2a8f9b4e4 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -919,8 +919,9 @@ static int vmbus_probe(struct device *child_device) device_to_vm_device(child_device); /* Let the specific open-source driver handles the probe if it can */ - if (driver_ctx->probe) { - ret = device_ctx->probe_error = driver_ctx->probe(child_device); + if (driver_ctx->driver.probe) { + ret = device_ctx->probe_error = + driver_ctx->driver.probe(child_device); if (ret != 0) { DPRINT_ERR(VMBUS_DRV, "probe() failed for device %s " "(%p) on driver %s (%d)...", -- cgit v1.2.3 From 94851c343d1f98f866760c96a8956e30b07e579c Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 7 Mar 2011 13:21:47 -0800 Subject: Staging: hv: Use generic device_driver remove function In preparation for moving all the state from struct driver_context to struct hv_driver, eliminate the remove() function from struct driver_context and use generic device_driver remove() function. Signed-off-by: K. Y. Srinivasan Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 2 +- drivers/staging/hv/hv_mouse.c | 2 +- drivers/staging/hv/netvsc_drv.c | 2 +- drivers/staging/hv/storvsc_drv.c | 2 +- drivers/staging/hv/vmbus_drv.c | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 0dff55791d26..3e86a560074e 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -187,7 +187,7 @@ static int blkvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) sizeof(struct hv_guid)); drv_ctx->driver.probe = blkvsc_probe; - drv_ctx->remove = blkvsc_remove; + drv_ctx->driver.remove = blkvsc_remove; drv_ctx->shutdown = blkvsc_shutdown; /* The driver belongs to vmbus */ diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 4a25f3b8770d..6e2a937df4e3 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -1022,7 +1022,7 @@ static int __init mousevsc_init(void) sizeof(struct hv_guid)); drv_ctx->driver.probe = mousevsc_probe; - drv_ctx->remove = mousevsc_remove; + drv_ctx->driver.remove = mousevsc_remove; /* The driver belongs to vmbus */ vmbus_child_driver_register(drv_ctx); diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 083f0d348598..e2013b5e3487 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -512,7 +512,7 @@ static int netvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) sizeof(struct hv_guid)); drv_ctx->driver.probe = netvsc_probe; - drv_ctx->remove = netvsc_remove; + drv_ctx->driver.remove = netvsc_remove; /* The driver belongs to vmbus */ ret = vmbus_child_driver_register(drv_ctx); diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 3fe4bdb4ec92..3855271bda1e 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -165,7 +165,7 @@ static int storvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) sizeof(struct hv_guid)); drv_ctx->driver.probe = storvsc_probe; - drv_ctx->remove = storvsc_remove; + drv_ctx->driver.remove = storvsc_remove; /* The driver belongs to vmbus */ ret = vmbus_child_driver_register(drv_ctx); diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index fee2a8f9b4e4..4df2be04fd14 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -964,8 +964,8 @@ static int vmbus_remove(struct device *child_device) * Let the specific open-source driver handles the removal if * it can */ - if (driver_ctx->remove) { - ret = driver_ctx->remove(child_device); + if (driver_ctx->driver.remove) { + ret = driver_ctx->driver.remove(child_device); } else { DPRINT_ERR(VMBUS_DRV, "remove() method not set for driver - %s", -- cgit v1.2.3 From 38fadc3e1f2ed55544acb75823ba7b2929597f68 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 7 Mar 2011 13:22:20 -0800 Subject: Staging: hv: Use generic device_driver shutdown function In preparation for moving all the state from struct driver_context to struct hv_driver, eliminate the shutdown() function from struct driver_context and use generic device_driver shutdown() function. Signed-off-by: K. Y. Srinivasan Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 2 +- drivers/staging/hv/vmbus_drv.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 3e86a560074e..9ccd5dcc353a 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -188,7 +188,7 @@ static int blkvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) drv_ctx->driver.probe = blkvsc_probe; drv_ctx->driver.remove = blkvsc_remove; - drv_ctx->shutdown = blkvsc_shutdown; + drv_ctx->driver.shutdown = blkvsc_shutdown; /* The driver belongs to vmbus */ ret = vmbus_child_driver_register(drv_ctx); diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 4df2be04fd14..6ef5bee65cac 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -1000,8 +1000,8 @@ static void vmbus_shutdown(struct device *child_device) driver_ctx = driver_to_driver_context(child_device->driver); /* Let the specific open-source driver handles the removal if it can */ - if (driver_ctx->shutdown) - driver_ctx->shutdown(child_device); + if (driver_ctx->driver.shutdown) + driver_ctx->driver.shutdown(child_device); return; } -- cgit v1.2.3 From b9bd2f9b358613fb697c849a5300f890db54fbcf Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 7 Mar 2011 13:23:18 -0800 Subject: Staging: hv: Remove unnecessary function pointers in driver_context Get rid of the unnecessary function pointers for probe(), remove() and shutdown() from struct driver_context. Signed-off-by: K. Y. Srinivasan Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/vmbus.h b/drivers/staging/hv/vmbus.h index 42f2adb99547..8bcfb40a24fa 100644 --- a/drivers/staging/hv/vmbus.h +++ b/drivers/staging/hv/vmbus.h @@ -33,14 +33,6 @@ struct driver_context { struct device_driver driver; - /* - * Use these methods instead of the struct device_driver so 2.6 kernel - * stops complaining - * TODO - fix this! - */ - int (*probe)(struct device *); - int (*remove)(struct device *); - void (*shutdown)(struct device *); }; struct vm_device { -- cgit v1.2.3 From c643269d67236661b44ff3605b77fb6e10925fdd Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 7 Mar 2011 13:23:43 -0800 Subject: Staging: hv: Change the signature for vmbus_child_driver_register In preparation for moving the element driver from the struct driver_context to struct hv_driver, change the signature for the function vmbus_child_driver_register() to take a pointer to struct device_driver. Signed-off-by: K. Y. Srinivasan Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 2 +- drivers/staging/hv/hv_mouse.c | 2 +- drivers/staging/hv/netvsc_drv.c | 2 +- drivers/staging/hv/storvsc_drv.c | 2 +- drivers/staging/hv/vmbus.h | 2 +- drivers/staging/hv/vmbus_drv.c | 11 +++++------ 6 files changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 9ccd5dcc353a..d5e18819c982 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -191,7 +191,7 @@ static int blkvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) drv_ctx->driver.shutdown = blkvsc_shutdown; /* The driver belongs to vmbus */ - ret = vmbus_child_driver_register(drv_ctx); + ret = vmbus_child_driver_register(&drv_ctx->driver); return ret; } diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 6e2a937df4e3..d2290f8908cc 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -1025,7 +1025,7 @@ static int __init mousevsc_init(void) drv_ctx->driver.remove = mousevsc_remove; /* The driver belongs to vmbus */ - vmbus_child_driver_register(drv_ctx); + vmbus_child_driver_register(&drv_ctx->driver); return 0; } diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index e2013b5e3487..a50a9a66558e 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -515,7 +515,7 @@ static int netvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) drv_ctx->driver.remove = netvsc_remove; /* The driver belongs to vmbus */ - ret = vmbus_child_driver_register(drv_ctx); + ret = vmbus_child_driver_register(&drv_ctx->driver); return ret; } diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 3855271bda1e..8ab8df55f02f 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -168,7 +168,7 @@ static int storvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) drv_ctx->driver.remove = storvsc_remove; /* The driver belongs to vmbus */ - ret = vmbus_child_driver_register(drv_ctx); + ret = vmbus_child_driver_register(&drv_ctx->driver); return ret; } diff --git a/drivers/staging/hv/vmbus.h b/drivers/staging/hv/vmbus.h index 8bcfb40a24fa..2295fe2e86a1 100644 --- a/drivers/staging/hv/vmbus.h +++ b/drivers/staging/hv/vmbus.h @@ -61,7 +61,7 @@ static inline struct driver_context *driver_to_driver_context(struct device_driv /* Vmbus interface */ -int vmbus_child_driver_register(struct driver_context *driver_ctx); +int vmbus_child_driver_register(struct device_driver *drv); void vmbus_child_driver_unregister(struct driver_context *driver_ctx); extern struct completion hv_channel_ready; diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 6ef5bee65cac..685376b50d9f 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -617,9 +617,8 @@ static void vmbus_bus_exit(void) /** * vmbus_child_driver_register() - Register a vmbus's child driver - * @driver_ctx: Pointer to driver structure you want to register + * @drv: Pointer to driver structure you want to register * - * @driver_ctx is of type &struct driver_context * * Registers the given driver with Linux through the 'driver_register()' call * And sets up the hyper-v vmbus handling for this driver. @@ -627,17 +626,17 @@ static void vmbus_bus_exit(void) * * Mainly used by Hyper-V drivers. */ -int vmbus_child_driver_register(struct driver_context *driver_ctx) +int vmbus_child_driver_register(struct device_driver *drv) { int ret; DPRINT_INFO(VMBUS_DRV, "child driver (%p) registering - name %s", - driver_ctx, driver_ctx->driver.name); + drv, drv->name); /* The child driver on this vmbus */ - driver_ctx->driver.bus = &vmbus_drv.bus; + drv->bus = &vmbus_drv.bus; - ret = driver_register(&driver_ctx->driver); + ret = driver_register(drv); vmbus_request_offers(); -- cgit v1.2.3 From 06de23f788245414344316b02ccb1e6fdc21bf9a Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 7 Mar 2011 13:24:23 -0800 Subject: Staging: hv: Change the signature for vmbus_child_driver_unregister In preperation for moving the element driver from the struct driver_context to struct hv_driver, change the signature for the function vmbus_child_driver_unregister() to take a pointer to struct device_driver. Signed-off-by: K. Y. Srinivasan Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 2 +- drivers/staging/hv/hv_mouse.c | 2 +- drivers/staging/hv/netvsc_drv.c | 2 +- drivers/staging/hv/storvsc_drv.c | 2 +- drivers/staging/hv/vmbus.h | 2 +- drivers/staging/hv/vmbus_drv.c | 11 +++++------ 6 files changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index d5e18819c982..dee38d5bd3b0 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -233,7 +233,7 @@ static void blkvsc_drv_exit(void) if (storvsc_drv_obj->base.cleanup) storvsc_drv_obj->base.cleanup(&storvsc_drv_obj->base); - vmbus_child_driver_unregister(drv_ctx); + vmbus_child_driver_unregister(&drv_ctx->driver); return; } diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index d2290f8908cc..4ab08ae9f48e 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -983,7 +983,7 @@ static void mousevsc_drv_exit(void) if (mousevsc_drv_obj->Base.cleanup) mousevsc_drv_obj->Base.cleanup(&mousevsc_drv_obj->Base); - vmbus_child_driver_unregister(drv_ctx); + vmbus_child_driver_unregister(&drv_ctx->driver); return; } diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index a50a9a66558e..333586ed99cb 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -489,7 +489,7 @@ static void netvsc_drv_exit(void) if (netvsc_drv_obj->base.cleanup) netvsc_drv_obj->base.cleanup(&netvsc_drv_obj->base); - vmbus_child_driver_unregister(drv_ctx); + vmbus_child_driver_unregister(&drv_ctx->driver); return; } diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 8ab8df55f02f..ced611abff72 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -209,7 +209,7 @@ static void storvsc_drv_exit(void) if (storvsc_drv_obj->base.cleanup) storvsc_drv_obj->base.cleanup(&storvsc_drv_obj->base); - vmbus_child_driver_unregister(drv_ctx); + vmbus_child_driver_unregister(&drv_ctx->driver); return; } diff --git a/drivers/staging/hv/vmbus.h b/drivers/staging/hv/vmbus.h index 2295fe2e86a1..7a5e70858b5f 100644 --- a/drivers/staging/hv/vmbus.h +++ b/drivers/staging/hv/vmbus.h @@ -62,7 +62,7 @@ static inline struct driver_context *driver_to_driver_context(struct device_driv /* Vmbus interface */ int vmbus_child_driver_register(struct device_driver *drv); -void vmbus_child_driver_unregister(struct driver_context *driver_ctx); +void vmbus_child_driver_unregister(struct device_driver *drv); extern struct completion hv_channel_ready; diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 685376b50d9f..1473809ad285 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -646,23 +646,22 @@ EXPORT_SYMBOL(vmbus_child_driver_register); /** * vmbus_child_driver_unregister() - Unregister a vmbus's child driver - * @driver_ctx: Pointer to driver structure you want to un-register + * @drv: Pointer to driver structure you want to un-register * - * @driver_ctx is of type &struct driver_context * * Un-register the given driver with Linux through the 'driver_unregister()' * call. And ungegisters the driver from the Hyper-V vmbus handler. * * Mainly used by Hyper-V drivers. */ -void vmbus_child_driver_unregister(struct driver_context *driver_ctx) +void vmbus_child_driver_unregister(struct device_driver *drv) { DPRINT_INFO(VMBUS_DRV, "child driver (%p) unregistering - name %s", - driver_ctx, driver_ctx->driver.name); + drv, drv->name); - driver_unregister(&driver_ctx->driver); + driver_unregister(drv); - driver_ctx->driver.bus = NULL; + drv->bus = NULL; } EXPORT_SYMBOL(vmbus_child_driver_unregister); -- cgit v1.2.3 From 150f93989ef327698f64527b334a6d2129066704 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 7 Mar 2011 13:32:31 -0800 Subject: Staging: hv: Eliminate driver_context structure We need to move the following elements from struct driver_context: class_id and driver in one step. As part of this operation get rid of the struct driver_context. With this patch we will have consolidated all driver state into one data structure: struct hv_driver. Signed-off-by: K. Y. Srinivasan Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 43 +++++++++++++++++++--------------------- drivers/staging/hv/hv_mouse.c | 32 ++++++++++++++---------------- drivers/staging/hv/netvsc_drv.c | 40 +++++++++++++++++-------------------- drivers/staging/hv/storvsc_drv.c | 41 ++++++++++++++++++-------------------- drivers/staging/hv/vmbus.h | 10 ++-------- drivers/staging/hv/vmbus_api.h | 14 +++++++++++++ drivers/staging/hv/vmbus_drv.c | 41 ++++++++++++++------------------------ 7 files changed, 103 insertions(+), 118 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index dee38d5bd3b0..af0a529e3602 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -117,9 +117,6 @@ struct block_device_context { /* Per driver */ struct blkvsc_driver_context { - /* !! These must be the first 2 fields !! */ - /* FIXME this is a bug! */ - struct driver_context drv_ctx; struct storvsc_driver_object drv_obj; }; @@ -174,24 +171,24 @@ static const struct block_device_operations block_ops = { static int blkvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) { struct storvsc_driver_object *storvsc_drv_obj = &g_blkvsc_drv.drv_obj; - struct driver_context *drv_ctx = &g_blkvsc_drv.drv_ctx; + struct hv_driver *drv = &g_blkvsc_drv.drv_obj.base; int ret; storvsc_drv_obj->ring_buffer_size = blkvsc_ringbuffer_size; + drv->priv = storvsc_drv_obj; + /* Callback to client driver to complete the initialization */ drv_init(&storvsc_drv_obj->base); - drv_ctx->driver.name = storvsc_drv_obj->base.name; - memcpy(&drv_ctx->class_id, &storvsc_drv_obj->base.dev_type, - sizeof(struct hv_guid)); + drv->driver.name = storvsc_drv_obj->base.name; - drv_ctx->driver.probe = blkvsc_probe; - drv_ctx->driver.remove = blkvsc_remove; - drv_ctx->driver.shutdown = blkvsc_shutdown; + drv->driver.probe = blkvsc_probe; + drv->driver.remove = blkvsc_remove; + drv->driver.shutdown = blkvsc_shutdown; /* The driver belongs to vmbus */ - ret = vmbus_child_driver_register(&drv_ctx->driver); + ret = vmbus_child_driver_register(&drv->driver); return ret; } @@ -206,7 +203,7 @@ static int blkvsc_drv_exit_cb(struct device *dev, void *data) static void blkvsc_drv_exit(void) { struct storvsc_driver_object *storvsc_drv_obj = &g_blkvsc_drv.drv_obj; - struct driver_context *drv_ctx = &g_blkvsc_drv.drv_ctx; + struct hv_driver *drv = &g_blkvsc_drv.drv_obj.base; struct device *current_dev; int ret; @@ -214,7 +211,7 @@ static void blkvsc_drv_exit(void) current_dev = NULL; /* Get the device */ - ret = driver_for_each_device(&drv_ctx->driver, NULL, + ret = driver_for_each_device(&drv->driver, NULL, (void *) ¤t_dev, blkvsc_drv_exit_cb); @@ -233,7 +230,7 @@ static void blkvsc_drv_exit(void) if (storvsc_drv_obj->base.cleanup) storvsc_drv_obj->base.cleanup(&storvsc_drv_obj->base); - vmbus_child_driver_unregister(&drv_ctx->driver); + vmbus_child_driver_unregister(&drv->driver); return; } @@ -243,10 +240,10 @@ static void blkvsc_drv_exit(void) */ static int blkvsc_probe(struct device *device) { - struct driver_context *driver_ctx = - driver_to_driver_context(device->driver); + struct hv_driver *drv = + drv_to_hv_drv(device->driver); struct blkvsc_driver_context *blkvsc_drv_ctx = - (struct blkvsc_driver_context *)driver_ctx; + (struct blkvsc_driver_context *)drv->priv; struct storvsc_driver_object *storvsc_drv_obj = &blkvsc_drv_ctx->drv_obj; struct vm_device *device_ctx = device_to_vm_device(device); @@ -728,10 +725,10 @@ static int blkvsc_do_read_capacity16(struct block_device_context *blkdev) */ static int blkvsc_remove(struct device *device) { - struct driver_context *driver_ctx = - driver_to_driver_context(device->driver); + struct hv_driver *drv = + drv_to_hv_drv(device->driver); struct blkvsc_driver_context *blkvsc_drv_ctx = - (struct blkvsc_driver_context *)driver_ctx; + (struct blkvsc_driver_context *)drv->priv; struct storvsc_driver_object *storvsc_drv_obj = &blkvsc_drv_ctx->drv_obj; struct vm_device *device_ctx = device_to_vm_device(device); @@ -851,10 +848,10 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, { struct block_device_context *blkdev = blkvsc_req->dev; struct vm_device *device_ctx = blkdev->device_ctx; - struct driver_context *driver_ctx = - driver_to_driver_context(device_ctx->device.driver); + struct hv_driver *drv = + drv_to_hv_drv(device_ctx->device.driver); struct blkvsc_driver_context *blkvsc_drv_ctx = - (struct blkvsc_driver_context *)driver_ctx; + (struct blkvsc_driver_context *)drv->priv; struct storvsc_driver_object *storvsc_drv_obj = &blkvsc_drv_ctx->drv_obj; struct hv_storvsc_request *storvsc_req; diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 4ab08ae9f48e..f762a8aa35d0 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -778,7 +778,6 @@ struct input_device_context { }; struct mousevsc_driver_context { - struct driver_context drv_ctx; struct mousevsc_drv_obj drv_obj; }; @@ -823,10 +822,10 @@ static int mousevsc_probe(struct device *device) { int ret = 0; - struct driver_context *driver_ctx = - driver_to_driver_context(device->driver); + struct hv_driver *drv = + drv_to_hv_drv(device->driver); struct mousevsc_driver_context *mousevsc_drv_ctx = - (struct mousevsc_driver_context *)driver_ctx; + (struct mousevsc_driver_context *)drv->priv; struct mousevsc_drv_obj *mousevsc_drv_obj = &mousevsc_drv_ctx->drv_obj; struct vm_device *device_ctx = device_to_vm_device(device); @@ -854,10 +853,10 @@ static int mousevsc_remove(struct device *device) { int ret = 0; - struct driver_context *driver_ctx = - driver_to_driver_context(device->driver); + struct hv_driver *drv = + drv_to_hv_drv(device->driver); struct mousevsc_driver_context *mousevsc_drv_ctx = - (struct mousevsc_driver_context *)driver_ctx; + (struct mousevsc_driver_context *)drv->priv; struct mousevsc_drv_obj *mousevsc_drv_obj = &mousevsc_drv_ctx->drv_obj; struct vm_device *device_ctx = device_to_vm_device(device); @@ -958,7 +957,7 @@ static int mousevsc_drv_exit_cb(struct device *dev, void *data) static void mousevsc_drv_exit(void) { struct mousevsc_drv_obj *mousevsc_drv_obj = &g_mousevsc_drv.drv_obj; - struct driver_context *drv_ctx = &g_mousevsc_drv.drv_ctx; + struct hv_driver *drv = &g_mousevsc_drv.drv_obj.Base; int ret; struct device *current_dev = NULL; @@ -967,7 +966,7 @@ static void mousevsc_drv_exit(void) current_dev = NULL; /* Get the device */ - ret = driver_for_each_device(&drv_ctx->driver, NULL, + ret = driver_for_each_device(&drv->driver, NULL, (void *)¤t_dev, mousevsc_drv_exit_cb); if (ret) @@ -983,7 +982,7 @@ static void mousevsc_drv_exit(void) if (mousevsc_drv_obj->Base.cleanup) mousevsc_drv_obj->Base.cleanup(&mousevsc_drv_obj->Base); - vmbus_child_driver_unregister(&drv_ctx->driver); + vmbus_child_driver_unregister(&drv->driver); return; } @@ -1010,22 +1009,21 @@ static int mouse_vsc_initialize(struct hv_driver *Driver) static int __init mousevsc_init(void) { struct mousevsc_drv_obj *input_drv_obj = &g_mousevsc_drv.drv_obj; - struct driver_context *drv_ctx = &g_mousevsc_drv.drv_ctx; + struct hv_driver *drv = &g_mousevsc_drv.drv_obj.Base; DPRINT_INFO(INPUTVSC_DRV, "Hyper-V Mouse driver initializing."); /* Callback to client driver to complete the initialization */ mouse_vsc_initialize(&input_drv_obj->Base); - drv_ctx->driver.name = input_drv_obj->Base.name; - memcpy(&drv_ctx->class_id, &input_drv_obj->Base.dev_type, - sizeof(struct hv_guid)); + drv->driver.name = input_drv_obj->Base.name; + drv->priv = input_drv_obj; - drv_ctx->driver.probe = mousevsc_probe; - drv_ctx->driver.remove = mousevsc_remove; + drv->driver.probe = mousevsc_probe; + drv->driver.remove = mousevsc_remove; /* The driver belongs to vmbus */ - vmbus_child_driver_register(&drv_ctx->driver); + vmbus_child_driver_register(&drv->driver); return 0; } diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 333586ed99cb..fdcc8aab2177 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -49,9 +49,6 @@ struct net_device_context { }; struct netvsc_driver_context { - /* !! These must be the first 2 fields !! */ - /* Which is a bug FIXME! */ - struct driver_context drv_ctx; struct netvsc_driver drv_obj; }; @@ -135,10 +132,10 @@ static void netvsc_xmit_completion(void *context) static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) { struct net_device_context *net_device_ctx = netdev_priv(net); - struct driver_context *driver_ctx = - driver_to_driver_context(net_device_ctx->device_ctx->device.driver); + struct hv_driver *drv = + drv_to_hv_drv(net_device_ctx->device_ctx->device.driver); struct netvsc_driver_context *net_drv_ctx = - (struct netvsc_driver_context *)driver_ctx; + (struct netvsc_driver_context *)drv->priv; struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj; struct hv_netvsc_packet *packet; int ret; @@ -340,10 +337,10 @@ static const struct net_device_ops device_ops = { static int netvsc_probe(struct device *device) { - struct driver_context *driver_ctx = - driver_to_driver_context(device->driver); + struct hv_driver *drv = + drv_to_hv_drv(device->driver); struct netvsc_driver_context *net_drv_ctx = - (struct netvsc_driver_context *)driver_ctx; + (struct netvsc_driver_context *)drv->priv; struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj; struct vm_device *device_ctx = device_to_vm_device(device); struct hv_device *device_obj = &device_ctx->device_obj; @@ -412,10 +409,10 @@ static int netvsc_probe(struct device *device) static int netvsc_remove(struct device *device) { - struct driver_context *driver_ctx = - driver_to_driver_context(device->driver); + struct hv_driver *drv = + drv_to_hv_drv(device->driver); struct netvsc_driver_context *net_drv_ctx = - (struct netvsc_driver_context *)driver_ctx; + (struct netvsc_driver_context *)drv->priv; struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj; struct vm_device *device_ctx = device_to_vm_device(device); struct net_device *net = dev_get_drvdata(&device_ctx->device); @@ -462,7 +459,7 @@ static int netvsc_drv_exit_cb(struct device *dev, void *data) static void netvsc_drv_exit(void) { struct netvsc_driver *netvsc_drv_obj = &g_netvsc_drv.drv_obj; - struct driver_context *drv_ctx = &g_netvsc_drv.drv_ctx; + struct hv_driver *drv = &g_netvsc_drv.drv_obj.base; struct device *current_dev; int ret; @@ -470,7 +467,7 @@ static void netvsc_drv_exit(void) current_dev = NULL; /* Get the device */ - ret = driver_for_each_device(&drv_ctx->driver, NULL, + ret = driver_for_each_device(&drv->driver, NULL, ¤t_dev, netvsc_drv_exit_cb); if (ret) DPRINT_WARN(NETVSC_DRV, @@ -489,7 +486,7 @@ static void netvsc_drv_exit(void) if (netvsc_drv_obj->base.cleanup) netvsc_drv_obj->base.cleanup(&netvsc_drv_obj->base); - vmbus_child_driver_unregister(&drv_ctx->driver); + vmbus_child_driver_unregister(&drv->driver); return; } @@ -497,25 +494,24 @@ static void netvsc_drv_exit(void) static int netvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) { struct netvsc_driver *net_drv_obj = &g_netvsc_drv.drv_obj; - struct driver_context *drv_ctx = &g_netvsc_drv.drv_ctx; + struct hv_driver *drv = &g_netvsc_drv.drv_obj.base; int ret; net_drv_obj->ring_buf_size = ring_size * PAGE_SIZE; net_drv_obj->recv_cb = netvsc_recv_callback; net_drv_obj->link_status_change = netvsc_linkstatus_callback; + drv->priv = net_drv_obj; /* Callback to client driver to complete the initialization */ drv_init(&net_drv_obj->base); - drv_ctx->driver.name = net_drv_obj->base.name; - memcpy(&drv_ctx->class_id, &net_drv_obj->base.dev_type, - sizeof(struct hv_guid)); + drv->driver.name = net_drv_obj->base.name; - drv_ctx->driver.probe = netvsc_probe; - drv_ctx->driver.remove = netvsc_remove; + drv->driver.probe = netvsc_probe; + drv->driver.remove = netvsc_remove; /* The driver belongs to vmbus */ - ret = vmbus_child_driver_register(&drv_ctx->driver); + ret = vmbus_child_driver_register(&drv->driver); return ret; } diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index ced611abff72..33009936a6ea 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -64,9 +64,6 @@ struct storvsc_cmd_request { }; struct storvsc_driver_context { - /* !! These must be the first 2 fields !! */ - /* FIXME this is a bug... */ - struct driver_context drv_ctx; struct storvsc_driver_object drv_obj; }; @@ -138,13 +135,15 @@ static int storvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) { int ret; struct storvsc_driver_object *storvsc_drv_obj = &g_storvsc_drv.drv_obj; - struct driver_context *drv_ctx = &g_storvsc_drv.drv_ctx; + struct hv_driver *drv = &g_storvsc_drv.drv_obj.base; storvsc_drv_obj->ring_buffer_size = storvsc_ringbuffer_size; /* Callback to client driver to complete the initialization */ drv_init(&storvsc_drv_obj->base); + drv->priv = storvsc_drv_obj; + DPRINT_INFO(STORVSC_DRV, "request extension size %u, max outstanding reqs %u", storvsc_drv_obj->request_ext_size, @@ -160,15 +159,13 @@ static int storvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) return -1; } - drv_ctx->driver.name = storvsc_drv_obj->base.name; - memcpy(&drv_ctx->class_id, &storvsc_drv_obj->base.dev_type, - sizeof(struct hv_guid)); + drv->driver.name = storvsc_drv_obj->base.name; - drv_ctx->driver.probe = storvsc_probe; - drv_ctx->driver.remove = storvsc_remove; + drv->driver.probe = storvsc_probe; + drv->driver.remove = storvsc_remove; /* The driver belongs to vmbus */ - ret = vmbus_child_driver_register(&drv_ctx->driver); + ret = vmbus_child_driver_register(&drv->driver); return ret; } @@ -183,7 +180,7 @@ static int storvsc_drv_exit_cb(struct device *dev, void *data) static void storvsc_drv_exit(void) { struct storvsc_driver_object *storvsc_drv_obj = &g_storvsc_drv.drv_obj; - struct driver_context *drv_ctx = &g_storvsc_drv.drv_ctx; + struct hv_driver *drv = &g_storvsc_drv.drv_obj.base; struct device *current_dev = NULL; int ret; @@ -191,7 +188,7 @@ static void storvsc_drv_exit(void) current_dev = NULL; /* Get the device */ - ret = driver_for_each_device(&drv_ctx->driver, NULL, + ret = driver_for_each_device(&drv->driver, NULL, (void *) ¤t_dev, storvsc_drv_exit_cb); @@ -209,7 +206,7 @@ static void storvsc_drv_exit(void) if (storvsc_drv_obj->base.cleanup) storvsc_drv_obj->base.cleanup(&storvsc_drv_obj->base); - vmbus_child_driver_unregister(&drv_ctx->driver); + vmbus_child_driver_unregister(&drv->driver); return; } @@ -219,10 +216,10 @@ static void storvsc_drv_exit(void) static int storvsc_probe(struct device *device) { int ret; - struct driver_context *driver_ctx = - driver_to_driver_context(device->driver); + struct hv_driver *drv = + drv_to_hv_drv(device->driver); struct storvsc_driver_context *storvsc_drv_ctx = - (struct storvsc_driver_context *)driver_ctx; + (struct storvsc_driver_context *)drv->priv; struct storvsc_driver_object *storvsc_drv_obj = &storvsc_drv_ctx->drv_obj; struct vm_device *device_ctx = device_to_vm_device(device); @@ -304,10 +301,10 @@ static int storvsc_probe(struct device *device) static int storvsc_remove(struct device *device) { int ret; - struct driver_context *driver_ctx = - driver_to_driver_context(device->driver); + struct hv_driver *drv = + drv_to_hv_drv(device->driver); struct storvsc_driver_context *storvsc_drv_ctx = - (struct storvsc_driver_context *)driver_ctx; + (struct storvsc_driver_context *)drv->priv; struct storvsc_driver_object *storvsc_drv_obj = &storvsc_drv_ctx->drv_obj; struct vm_device *device_ctx = device_to_vm_device(device); @@ -602,10 +599,10 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, struct host_device_context *host_device_ctx = (struct host_device_context *)scmnd->device->host->hostdata; struct vm_device *device_ctx = host_device_ctx->device_ctx; - struct driver_context *driver_ctx = - driver_to_driver_context(device_ctx->device.driver); + struct hv_driver *drv = + drv_to_hv_drv(device_ctx->device.driver); struct storvsc_driver_context *storvsc_drv_ctx = - (struct storvsc_driver_context *)driver_ctx; + (struct storvsc_driver_context *)drv->priv; struct storvsc_driver_object *storvsc_drv_obj = &storvsc_drv_ctx->drv_obj; struct hv_storvsc_request *request; diff --git a/drivers/staging/hv/vmbus.h b/drivers/staging/hv/vmbus.h index 7a5e70858b5f..a6be405f1568 100644 --- a/drivers/staging/hv/vmbus.h +++ b/drivers/staging/hv/vmbus.h @@ -28,12 +28,6 @@ #include #include "vmbus_api.h" -struct driver_context { - struct hv_guid class_id; - - struct device_driver driver; - -}; struct vm_device { struct work_struct probe_failed_work_item; @@ -54,9 +48,9 @@ static inline struct vm_device *device_to_vm_device(struct device *d) return container_of(d, struct vm_device, device); } -static inline struct driver_context *driver_to_driver_context(struct device_driver *d) +static inline struct hv_driver *drv_to_hv_drv(struct device_driver *d) { - return container_of(d, struct driver_context, driver); + return container_of(d, struct hv_driver, driver); } diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index 635ce22a0334..7f891fb10d3c 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -25,6 +25,8 @@ #ifndef _VMBUS_API_H_ #define _VMBUS_API_H_ +#include + #define MAX_PAGE_BUFFER_COUNT 16 #define MAX_MULTIPAGE_BUFFER_COUNT 32 /* 128K */ @@ -91,6 +93,18 @@ struct hv_driver { /* the device type supported by this driver */ struct hv_guid dev_type; + /* + * Device type specific drivers (net, blk etc.) + * need a mechanism to get a pointer to + * device type specific driver structure given + * a pointer to the base hyperv driver structure. + * The current code solves this problem using + * a hack. Support this need explicitly + */ + void *priv; + + struct device_driver driver; + int (*dev_add)(struct hv_device *device, void *data); int (*dev_rm)(struct hv_device *device); void (*cleanup)(struct hv_driver *driver); diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 1473809ad285..9a9e426f37b9 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -42,11 +42,6 @@ /* Main vmbus driver data structure */ struct vmbus_driver_context { - /* !! These must be the first 2 fields !! */ - /* FIXME, this is a bug */ - /* The driver field is not used in here. Instead, the bus field is */ - /* used to represent the driver */ - struct driver_context drv_ctx; struct hv_driver drv_obj; struct bus_type bus; @@ -861,20 +856,14 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) static int vmbus_match(struct device *device, struct device_driver *driver) { int match = 0; - struct driver_context *driver_ctx = driver_to_driver_context(driver); + struct hv_driver *drv = drv_to_hv_drv(driver); struct vm_device *device_ctx = device_to_vm_device(device); /* We found our driver ? */ - if (memcmp(&device_ctx->class_id, &driver_ctx->class_id, + if (memcmp(&device_ctx->class_id, &drv->dev_type, sizeof(struct hv_guid)) == 0) { - /* - * !! NOTE: The driver_ctx is not a vmbus_drv_ctx. We typecast - * it here to access the struct hv_driver field - */ - struct vmbus_driver_context *vmbus_drv_ctx = - (struct vmbus_driver_context *)driver_ctx; - device_ctx->device_obj.drv = &vmbus_drv_ctx->drv_obj; + device_ctx->device_obj.drv = drv->priv; DPRINT_INFO(VMBUS_DRV, "device object (%p) set to driver object (%p)", &device_ctx->device_obj, @@ -911,15 +900,15 @@ static void vmbus_probe_failed_cb(struct work_struct *context) static int vmbus_probe(struct device *child_device) { int ret = 0; - struct driver_context *driver_ctx = - driver_to_driver_context(child_device->driver); + struct hv_driver *drv = + drv_to_hv_drv(child_device->driver); struct vm_device *device_ctx = device_to_vm_device(child_device); /* Let the specific open-source driver handles the probe if it can */ - if (driver_ctx->driver.probe) { + if (drv->driver.probe) { ret = device_ctx->probe_error = - driver_ctx->driver.probe(child_device); + drv->driver.probe(child_device); if (ret != 0) { DPRINT_ERR(VMBUS_DRV, "probe() failed for device %s " "(%p) on driver %s (%d)...", @@ -944,7 +933,7 @@ static int vmbus_probe(struct device *child_device) static int vmbus_remove(struct device *child_device) { int ret; - struct driver_context *driver_ctx; + struct hv_driver *drv; /* Special case root bus device */ if (child_device->parent == NULL) { @@ -956,14 +945,14 @@ static int vmbus_remove(struct device *child_device) } if (child_device->driver) { - driver_ctx = driver_to_driver_context(child_device->driver); + drv = drv_to_hv_drv(child_device->driver); /* * Let the specific open-source driver handles the removal if * it can */ - if (driver_ctx->driver.remove) { - ret = driver_ctx->driver.remove(child_device); + if (drv->driver.remove) { + ret = drv->driver.remove(child_device); } else { DPRINT_ERR(VMBUS_DRV, "remove() method not set for driver - %s", @@ -980,7 +969,7 @@ static int vmbus_remove(struct device *child_device) */ static void vmbus_shutdown(struct device *child_device) { - struct driver_context *driver_ctx; + struct hv_driver *drv; /* Special case root bus device */ if (child_device->parent == NULL) { @@ -995,11 +984,11 @@ static void vmbus_shutdown(struct device *child_device) if (!child_device->driver) return; - driver_ctx = driver_to_driver_context(child_device->driver); + drv = drv_to_hv_drv(child_device->driver); /* Let the specific open-source driver handles the removal if it can */ - if (driver_ctx->driver.shutdown) - driver_ctx->driver.shutdown(child_device); + if (drv->driver.shutdown) + drv->driver.shutdown(child_device); return; } -- cgit v1.2.3 From 67a5ee2d5e8fde860188f2ba145a724e6f453d42 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 7 Mar 2011 13:32:58 -0800 Subject: Staging: hv: Eliminate blkvsc_driver_context structure With the consolidation of all driver state into one data structure; blkvsc_driver_context structure is not needed; get rid of it. Signed-off-by: K. Y. Srinivasan Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index af0a529e3602..0f9fb05d2347 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -115,10 +115,6 @@ struct block_device_context { int users; }; -/* Per driver */ -struct blkvsc_driver_context { - struct storvsc_driver_object drv_obj; -}; /* Static decl */ static DEFINE_MUTEX(blkvsc_mutex); @@ -153,7 +149,7 @@ module_param(blkvsc_ringbuffer_size, int, S_IRUGO); MODULE_PARM_DESC(ring_size, "Ring buffer size (in bytes)"); /* The one and only one */ -static struct blkvsc_driver_context g_blkvsc_drv; +static struct storvsc_driver_object g_blkvsc_drv; static const struct block_device_operations block_ops = { .owner = THIS_MODULE, @@ -170,8 +166,8 @@ static const struct block_device_operations block_ops = { */ static int blkvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) { - struct storvsc_driver_object *storvsc_drv_obj = &g_blkvsc_drv.drv_obj; - struct hv_driver *drv = &g_blkvsc_drv.drv_obj.base; + struct storvsc_driver_object *storvsc_drv_obj = &g_blkvsc_drv; + struct hv_driver *drv = &g_blkvsc_drv.base; int ret; storvsc_drv_obj->ring_buffer_size = blkvsc_ringbuffer_size; @@ -202,8 +198,8 @@ static int blkvsc_drv_exit_cb(struct device *dev, void *data) static void blkvsc_drv_exit(void) { - struct storvsc_driver_object *storvsc_drv_obj = &g_blkvsc_drv.drv_obj; - struct hv_driver *drv = &g_blkvsc_drv.drv_obj.base; + struct storvsc_driver_object *storvsc_drv_obj = &g_blkvsc_drv; + struct hv_driver *drv = &g_blkvsc_drv.base; struct device *current_dev; int ret; @@ -242,10 +238,8 @@ static int blkvsc_probe(struct device *device) { struct hv_driver *drv = drv_to_hv_drv(device->driver); - struct blkvsc_driver_context *blkvsc_drv_ctx = - (struct blkvsc_driver_context *)drv->priv; struct storvsc_driver_object *storvsc_drv_obj = - &blkvsc_drv_ctx->drv_obj; + drv->priv; struct vm_device *device_ctx = device_to_vm_device(device); struct hv_device *device_obj = &device_ctx->device_obj; @@ -727,10 +721,8 @@ static int blkvsc_remove(struct device *device) { struct hv_driver *drv = drv_to_hv_drv(device->driver); - struct blkvsc_driver_context *blkvsc_drv_ctx = - (struct blkvsc_driver_context *)drv->priv; struct storvsc_driver_object *storvsc_drv_obj = - &blkvsc_drv_ctx->drv_obj; + drv->priv; struct vm_device *device_ctx = device_to_vm_device(device); struct hv_device *device_obj = &device_ctx->device_obj; struct block_device_context *blkdev = dev_get_drvdata(device); @@ -850,10 +842,8 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, struct vm_device *device_ctx = blkdev->device_ctx; struct hv_driver *drv = drv_to_hv_drv(device_ctx->device.driver); - struct blkvsc_driver_context *blkvsc_drv_ctx = - (struct blkvsc_driver_context *)drv->priv; struct storvsc_driver_object *storvsc_drv_obj = - &blkvsc_drv_ctx->drv_obj; + drv->priv; struct hv_storvsc_request *storvsc_req; int ret; -- cgit v1.2.3 From 680eeb15c0c71642b8a1a3a2583aa160cdd6ba7e Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 7 Mar 2011 14:16:46 -0800 Subject: Staging: hv: Eliminate mousevsc_driver_context With the consolidation of all driver state into one data structure; mousevsc_driver_context structure is not needed; get rid of it. Signed-off-by: K. Y. Srinivasan Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index f762a8aa35d0..6c5c00da8e7b 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -777,11 +777,8 @@ struct input_device_context { int connected; }; -struct mousevsc_driver_context { - struct mousevsc_drv_obj drv_obj; -}; -static struct mousevsc_driver_context g_mousevsc_drv; +static struct mousevsc_drv_obj g_mousevsc_drv; static void deviceinfo_callback(struct hv_device *dev, struct hv_input_dev_info *info) { @@ -824,9 +821,7 @@ static int mousevsc_probe(struct device *device) struct hv_driver *drv = drv_to_hv_drv(device->driver); - struct mousevsc_driver_context *mousevsc_drv_ctx = - (struct mousevsc_driver_context *)drv->priv; - struct mousevsc_drv_obj *mousevsc_drv_obj = &mousevsc_drv_ctx->drv_obj; + struct mousevsc_drv_obj *mousevsc_drv_obj = drv->priv; struct vm_device *device_ctx = device_to_vm_device(device); struct hv_device *device_obj = &device_ctx->device_obj; @@ -855,9 +850,7 @@ static int mousevsc_remove(struct device *device) struct hv_driver *drv = drv_to_hv_drv(device->driver); - struct mousevsc_driver_context *mousevsc_drv_ctx = - (struct mousevsc_driver_context *)drv->priv; - struct mousevsc_drv_obj *mousevsc_drv_obj = &mousevsc_drv_ctx->drv_obj; + struct mousevsc_drv_obj *mousevsc_drv_obj = drv->priv; struct vm_device *device_ctx = device_to_vm_device(device); struct hv_device *device_obj = &device_ctx->device_obj; @@ -956,8 +949,8 @@ static int mousevsc_drv_exit_cb(struct device *dev, void *data) static void mousevsc_drv_exit(void) { - struct mousevsc_drv_obj *mousevsc_drv_obj = &g_mousevsc_drv.drv_obj; - struct hv_driver *drv = &g_mousevsc_drv.drv_obj.Base; + struct mousevsc_drv_obj *mousevsc_drv_obj = &g_mousevsc_drv; + struct hv_driver *drv = &g_mousevsc_drv.Base; int ret; struct device *current_dev = NULL; @@ -1008,8 +1001,8 @@ static int mouse_vsc_initialize(struct hv_driver *Driver) static int __init mousevsc_init(void) { - struct mousevsc_drv_obj *input_drv_obj = &g_mousevsc_drv.drv_obj; - struct hv_driver *drv = &g_mousevsc_drv.drv_obj.Base; + struct mousevsc_drv_obj *input_drv_obj = &g_mousevsc_drv; + struct hv_driver *drv = &g_mousevsc_drv.Base; DPRINT_INFO(INPUTVSC_DRV, "Hyper-V Mouse driver initializing."); -- cgit v1.2.3 From d8de5dc6847e9272d3c648e62f6481ac5b200eb6 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 7 Mar 2011 13:33:41 -0800 Subject: Staging: hv: Eliminate netvsc_driver_context With the consolidation of all driver state into one data structure; netvsc_driver_context structure is not needed; get rid of it. Signed-off-by: K. Y. Srinivasan Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/netvsc_drv.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index fdcc8aab2177..f0d258cc5839 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -48,9 +48,6 @@ struct net_device_context { unsigned long avail; }; -struct netvsc_driver_context { - struct netvsc_driver drv_obj; -}; #define PACKET_PAGES_LOWATER 8 /* Need this many pages to handle worst case fragmented packet */ @@ -61,7 +58,7 @@ module_param(ring_size, int, S_IRUGO); MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)"); /* The one and only one */ -static struct netvsc_driver_context g_netvsc_drv; +static struct netvsc_driver g_netvsc_drv; /* no-op so the netdev core doesn't return -EINVAL when modifying the the * multicast address list in SIOCADDMULTI. hv is setup to get all multicast @@ -134,9 +131,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) struct net_device_context *net_device_ctx = netdev_priv(net); struct hv_driver *drv = drv_to_hv_drv(net_device_ctx->device_ctx->device.driver); - struct netvsc_driver_context *net_drv_ctx = - (struct netvsc_driver_context *)drv->priv; - struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj; + struct netvsc_driver *net_drv_obj = drv->priv; struct hv_netvsc_packet *packet; int ret; unsigned int i, num_pages; @@ -339,9 +334,7 @@ static int netvsc_probe(struct device *device) { struct hv_driver *drv = drv_to_hv_drv(device->driver); - struct netvsc_driver_context *net_drv_ctx = - (struct netvsc_driver_context *)drv->priv; - struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj; + struct netvsc_driver *net_drv_obj = drv->priv; struct vm_device *device_ctx = device_to_vm_device(device); struct hv_device *device_obj = &device_ctx->device_obj; struct net_device *net = NULL; @@ -411,9 +404,7 @@ static int netvsc_remove(struct device *device) { struct hv_driver *drv = drv_to_hv_drv(device->driver); - struct netvsc_driver_context *net_drv_ctx = - (struct netvsc_driver_context *)drv->priv; - struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj; + struct netvsc_driver *net_drv_obj = drv->priv; struct vm_device *device_ctx = device_to_vm_device(device); struct net_device *net = dev_get_drvdata(&device_ctx->device); struct hv_device *device_obj = &device_ctx->device_obj; @@ -458,8 +449,8 @@ static int netvsc_drv_exit_cb(struct device *dev, void *data) static void netvsc_drv_exit(void) { - struct netvsc_driver *netvsc_drv_obj = &g_netvsc_drv.drv_obj; - struct hv_driver *drv = &g_netvsc_drv.drv_obj.base; + struct netvsc_driver *netvsc_drv_obj = &g_netvsc_drv; + struct hv_driver *drv = &g_netvsc_drv.base; struct device *current_dev; int ret; @@ -493,8 +484,8 @@ static void netvsc_drv_exit(void) static int netvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) { - struct netvsc_driver *net_drv_obj = &g_netvsc_drv.drv_obj; - struct hv_driver *drv = &g_netvsc_drv.drv_obj.base; + struct netvsc_driver *net_drv_obj = &g_netvsc_drv; + struct hv_driver *drv = &g_netvsc_drv.base; int ret; net_drv_obj->ring_buf_size = ring_size * PAGE_SIZE; -- cgit v1.2.3 From 4af27d7036cfd8403814ca7448474a5c18b8b906 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 7 Mar 2011 13:34:01 -0800 Subject: Staging: hv: Eliminate storvsc_driver_context structure With the consolidation of all driver state into one data structure; storvsc_driver_context structure is not needed; get rid of it. Signed-off-by: K. Y. Srinivasan Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 33009936a6ea..972273461cba 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -63,9 +63,6 @@ struct storvsc_cmd_request { * Which sounds like a very bad design... */ }; -struct storvsc_driver_context { - struct storvsc_driver_object drv_obj; -}; /* Static decl */ static int storvsc_probe(struct device *dev); @@ -97,7 +94,7 @@ module_param(storvsc_ringbuffer_size, int, S_IRUGO); MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); /* The one and only one */ -static struct storvsc_driver_context g_storvsc_drv; +static struct storvsc_driver_object g_storvsc_drv; /* Scsi driver */ static struct scsi_host_template scsi_driver = { @@ -134,8 +131,8 @@ static struct scsi_host_template scsi_driver = { static int storvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) { int ret; - struct storvsc_driver_object *storvsc_drv_obj = &g_storvsc_drv.drv_obj; - struct hv_driver *drv = &g_storvsc_drv.drv_obj.base; + struct storvsc_driver_object *storvsc_drv_obj = &g_storvsc_drv; + struct hv_driver *drv = &g_storvsc_drv.base; storvsc_drv_obj->ring_buffer_size = storvsc_ringbuffer_size; @@ -179,8 +176,8 @@ static int storvsc_drv_exit_cb(struct device *dev, void *data) static void storvsc_drv_exit(void) { - struct storvsc_driver_object *storvsc_drv_obj = &g_storvsc_drv.drv_obj; - struct hv_driver *drv = &g_storvsc_drv.drv_obj.base; + struct storvsc_driver_object *storvsc_drv_obj = &g_storvsc_drv; + struct hv_driver *drv = &g_storvsc_drv.base; struct device *current_dev = NULL; int ret; @@ -218,10 +215,7 @@ static int storvsc_probe(struct device *device) int ret; struct hv_driver *drv = drv_to_hv_drv(device->driver); - struct storvsc_driver_context *storvsc_drv_ctx = - (struct storvsc_driver_context *)drv->priv; - struct storvsc_driver_object *storvsc_drv_obj = - &storvsc_drv_ctx->drv_obj; + struct storvsc_driver_object *storvsc_drv_obj = drv->priv; struct vm_device *device_ctx = device_to_vm_device(device); struct hv_device *device_obj = &device_ctx->device_obj; struct Scsi_Host *host; @@ -303,10 +297,7 @@ static int storvsc_remove(struct device *device) int ret; struct hv_driver *drv = drv_to_hv_drv(device->driver); - struct storvsc_driver_context *storvsc_drv_ctx = - (struct storvsc_driver_context *)drv->priv; - struct storvsc_driver_object *storvsc_drv_obj = - &storvsc_drv_ctx->drv_obj; + struct storvsc_driver_object *storvsc_drv_obj = drv->priv; struct vm_device *device_ctx = device_to_vm_device(device); struct hv_device *device_obj = &device_ctx->device_obj; struct Scsi_Host *host = dev_get_drvdata(device); @@ -601,10 +592,7 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, struct vm_device *device_ctx = host_device_ctx->device_ctx; struct hv_driver *drv = drv_to_hv_drv(device_ctx->device.driver); - struct storvsc_driver_context *storvsc_drv_ctx = - (struct storvsc_driver_context *)drv->priv; - struct storvsc_driver_object *storvsc_drv_obj = - &storvsc_drv_ctx->drv_obj; + struct storvsc_driver_object *storvsc_drv_obj = drv->priv; struct hv_storvsc_request *request; struct storvsc_cmd_request *cmd_request; unsigned int request_size = 0; -- cgit v1.2.3 From a3c7fe9a333516a14b34cf57684e864ecd2145ce Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 7 Mar 2011 13:34:27 -0800 Subject: Staging: hv: Move probe_failed_work_item from vm_device In preparation for consolidating all device related state into struct hv_device, move probe_failed_work_item from vm_device to hv_device. Signed-off-by: K. Y. Srinivasan Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus.h | 1 - drivers/staging/hv/vmbus_api.h | 3 +++ drivers/staging/hv/vmbus_drv.c | 5 +++-- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/vmbus.h b/drivers/staging/hv/vmbus.h index a6be405f1568..a12e9e58d32f 100644 --- a/drivers/staging/hv/vmbus.h +++ b/drivers/staging/hv/vmbus.h @@ -30,7 +30,6 @@ struct vm_device { - struct work_struct probe_failed_work_item; struct hv_guid class_id; struct hv_guid device_id; int probe_error; diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index 7f891fb10d3c..60e40004e28f 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -26,6 +26,7 @@ #define _VMBUS_API_H_ #include +#include #define MAX_PAGE_BUFFER_COUNT 16 #define MAX_MULTIPAGE_BUFFER_COUNT 32 /* 128K */ @@ -117,6 +118,8 @@ struct hv_device { char name[64]; + struct work_struct probe_failed_work_item; + /* the device type id of this device */ struct hv_guid dev_type; diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 9a9e426f37b9..36c4ec8c2f83 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -904,6 +904,7 @@ static int vmbus_probe(struct device *child_device) drv_to_hv_drv(child_device->driver); struct vm_device *device_ctx = device_to_vm_device(child_device); + struct hv_device *dev = &device_ctx->device_obj; /* Let the specific open-source driver handles the probe if it can */ if (drv->driver.probe) { @@ -915,9 +916,9 @@ static int vmbus_probe(struct device *child_device) dev_name(child_device), child_device, child_device->driver->name, ret); - INIT_WORK(&device_ctx->probe_failed_work_item, + INIT_WORK(&dev->probe_failed_work_item, vmbus_probe_failed_cb); - schedule_work(&device_ctx->probe_failed_work_item); + schedule_work(&dev->probe_failed_work_item); } } else { DPRINT_ERR(VMBUS_DRV, "probe() method not set for driver - %s", -- cgit v1.2.3 From 70b0af4f52b3da6aeac2bd03221217beff4746a1 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 7 Mar 2011 13:34:48 -0800 Subject: Staging: hv: Remove probe_error from vm_device In preparation for consolidating all device related state into struct hv_device, move probe_error from vm_device to hv_device. Signed-off-by: K. Y. Srinivasan Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus.h | 1 - drivers/staging/hv/vmbus_api.h | 2 ++ drivers/staging/hv/vmbus_drv.c | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/vmbus.h b/drivers/staging/hv/vmbus.h index a12e9e58d32f..ecd2d2fb47b1 100644 --- a/drivers/staging/hv/vmbus.h +++ b/drivers/staging/hv/vmbus.h @@ -32,7 +32,6 @@ struct vm_device { struct hv_guid class_id; struct hv_guid device_id; - int probe_error; struct hv_device device_obj; struct device device; }; diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index 60e40004e28f..4c5a38e349b6 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -120,6 +120,8 @@ struct hv_device { struct work_struct probe_failed_work_item; + int probe_error; + /* the device type id of this device */ struct hv_guid dev_type; diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 36c4ec8c2f83..0fcf377a24d4 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -742,7 +742,7 @@ int vmbus_child_device_register(struct hv_device *root_device_obj, ret = device_register(&child_device_ctx->device); /* vmbus_probe() error does not get propergate to device_register(). */ - ret = child_device_ctx->probe_error; + ret = child_device_ctx->device_obj.probe_error; if (ret) DPRINT_ERR(VMBUS_DRV, "unable to register child device (%p)", @@ -908,7 +908,7 @@ static int vmbus_probe(struct device *child_device) /* Let the specific open-source driver handles the probe if it can */ if (drv->driver.probe) { - ret = device_ctx->probe_error = + ret = device_ctx->device_obj.probe_error = drv->driver.probe(child_device); if (ret != 0) { DPRINT_ERR(VMBUS_DRV, "probe() failed for device %s " -- cgit v1.2.3 From 65c22791dbc08bd6a793c12c070675e9159e4b5f Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 7 Mar 2011 13:35:10 -0800 Subject: Staging: hv: Get rid of class_id from vm_device Both device abstractions: vm_device and hv_device maintain state to reperesent the device type (and they refer to them by different names - class_id in vm_device and dev_type in hv_device). In preparation for consolidating all device state in struct hv_device; eliminate class_id from struct vm_device. Signed-off-by: K. Y. Srinivasan Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus.h | 1 - drivers/staging/hv/vmbus_drv.c | 60 ++++++++++++++++++++---------------------- 2 files changed, 29 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/vmbus.h b/drivers/staging/hv/vmbus.h index ecd2d2fb47b1..a809f002b9a6 100644 --- a/drivers/staging/hv/vmbus.h +++ b/drivers/staging/hv/vmbus.h @@ -30,7 +30,6 @@ struct vm_device { - struct hv_guid class_id; struct hv_guid device_id; struct hv_device device_obj; struct device device; diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 0fcf377a24d4..d9d138d35e01 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -546,8 +546,6 @@ static int vmbus_bus_init(void) } /* strcpy(dev_ctx->device.bus_id, dev_ctx->device_obj.name); */ dev_set_name(&dev_ctx->device, "vmbus_0_0"); - memcpy(&dev_ctx->class_id, &dev_ctx->device_obj.dev_type, - sizeof(struct hv_guid)); memcpy(&dev_ctx->device_id, &dev_ctx->device_obj.dev_instance, sizeof(struct hv_guid)); @@ -704,7 +702,6 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *type, memcpy(&child_device_obj->dev_instance, instance, sizeof(struct hv_guid)); - memcpy(&child_device_ctx->class_id, type, sizeof(struct hv_guid)); memcpy(&child_device_ctx->device_id, instance, sizeof(struct hv_guid)); return child_device_obj; @@ -785,42 +782,43 @@ void vmbus_child_device_unregister(struct hv_device *device_obj) static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) { struct vm_device *device_ctx = device_to_vm_device(device); + struct hv_device *dev = &device_ctx->device_obj; int ret; DPRINT_INFO(VMBUS_DRV, "generating uevent - VMBUS_DEVICE_CLASS_GUID={" "%02x%02x%02x%02x-%02x%02x-%02x%02x-" "%02x%02x%02x%02x%02x%02x%02x%02x}", - device_ctx->class_id.data[3], device_ctx->class_id.data[2], - device_ctx->class_id.data[1], device_ctx->class_id.data[0], - device_ctx->class_id.data[5], device_ctx->class_id.data[4], - device_ctx->class_id.data[7], device_ctx->class_id.data[6], - device_ctx->class_id.data[8], device_ctx->class_id.data[9], - device_ctx->class_id.data[10], - device_ctx->class_id.data[11], - device_ctx->class_id.data[12], - device_ctx->class_id.data[13], - device_ctx->class_id.data[14], - device_ctx->class_id.data[15]); + dev->dev_type.data[3], dev->dev_type.data[2], + dev->dev_type.data[1], dev->dev_type.data[0], + dev->dev_type.data[5], dev->dev_type.data[4], + dev->dev_type.data[7], dev->dev_type.data[6], + dev->dev_type.data[8], dev->dev_type.data[9], + dev->dev_type.data[10], + dev->dev_type.data[11], + dev->dev_type.data[12], + dev->dev_type.data[13], + dev->dev_type.data[14], + dev->dev_type.data[15]); ret = add_uevent_var(env, "VMBUS_DEVICE_CLASS_GUID={" "%02x%02x%02x%02x-%02x%02x-%02x%02x-" "%02x%02x%02x%02x%02x%02x%02x%02x}", - device_ctx->class_id.data[3], - device_ctx->class_id.data[2], - device_ctx->class_id.data[1], - device_ctx->class_id.data[0], - device_ctx->class_id.data[5], - device_ctx->class_id.data[4], - device_ctx->class_id.data[7], - device_ctx->class_id.data[6], - device_ctx->class_id.data[8], - device_ctx->class_id.data[9], - device_ctx->class_id.data[10], - device_ctx->class_id.data[11], - device_ctx->class_id.data[12], - device_ctx->class_id.data[13], - device_ctx->class_id.data[14], - device_ctx->class_id.data[15]); + dev->dev_type.data[3], + dev->dev_type.data[2], + dev->dev_type.data[1], + dev->dev_type.data[0], + dev->dev_type.data[5], + dev->dev_type.data[4], + dev->dev_type.data[7], + dev->dev_type.data[6], + dev->dev_type.data[8], + dev->dev_type.data[9], + dev->dev_type.data[10], + dev->dev_type.data[11], + dev->dev_type.data[12], + dev->dev_type.data[13], + dev->dev_type.data[14], + dev->dev_type.data[15]); if (ret) return ret; @@ -860,7 +858,7 @@ static int vmbus_match(struct device *device, struct device_driver *driver) struct vm_device *device_ctx = device_to_vm_device(device); /* We found our driver ? */ - if (memcmp(&device_ctx->class_id, &drv->dev_type, + if (memcmp(&device_ctx->device_obj.dev_type, &drv->dev_type, sizeof(struct hv_guid)) == 0) { device_ctx->device_obj.drv = drv->priv; -- cgit v1.2.3 From d5889771a4acd321ad6f1242b3186cf4a47d7d55 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 7 Mar 2011 13:35:30 -0800 Subject: Staging: hv: Eliminate device_id from vm_device Both device abstractions: vm_device and hv_device maintain state to reperesent the device instance (and they refer to them by different names - device_id in vm_device and dev_instance in hv_device). In preparation for consolidating all device state in struct hv_device; eliminate device_id from struct vm_device. Signed-off-by: K. Y. Srinivasan Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus.h | 1 - drivers/staging/hv/vmbus_drv.c | 35 ++++++++++++++++------------------- 2 files changed, 16 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/vmbus.h b/drivers/staging/hv/vmbus.h index a809f002b9a6..ab296bb0b039 100644 --- a/drivers/staging/hv/vmbus.h +++ b/drivers/staging/hv/vmbus.h @@ -30,7 +30,6 @@ struct vm_device { - struct hv_guid device_id; struct hv_device device_obj; struct device device; }; diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index d9d138d35e01..819366221524 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -546,8 +546,6 @@ static int vmbus_bus_init(void) } /* strcpy(dev_ctx->device.bus_id, dev_ctx->device_obj.name); */ dev_set_name(&dev_ctx->device, "vmbus_0_0"); - memcpy(&dev_ctx->device_id, &dev_ctx->device_obj.dev_instance, - sizeof(struct hv_guid)); /* No need to bind a driver to the root device. */ dev_ctx->device.parent = NULL; @@ -702,7 +700,6 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *type, memcpy(&child_device_obj->dev_instance, instance, sizeof(struct hv_guid)); - memcpy(&child_device_ctx->device_id, instance, sizeof(struct hv_guid)); return child_device_obj; } @@ -826,22 +823,22 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) ret = add_uevent_var(env, "VMBUS_DEVICE_DEVICE_GUID={" "%02x%02x%02x%02x-%02x%02x-%02x%02x-" "%02x%02x%02x%02x%02x%02x%02x%02x}", - device_ctx->device_id.data[3], - device_ctx->device_id.data[2], - device_ctx->device_id.data[1], - device_ctx->device_id.data[0], - device_ctx->device_id.data[5], - device_ctx->device_id.data[4], - device_ctx->device_id.data[7], - device_ctx->device_id.data[6], - device_ctx->device_id.data[8], - device_ctx->device_id.data[9], - device_ctx->device_id.data[10], - device_ctx->device_id.data[11], - device_ctx->device_id.data[12], - device_ctx->device_id.data[13], - device_ctx->device_id.data[14], - device_ctx->device_id.data[15]); + dev->dev_instance.data[3], + dev->dev_instance.data[2], + dev->dev_instance.data[1], + dev->dev_instance.data[0], + dev->dev_instance.data[5], + dev->dev_instance.data[4], + dev->dev_instance.data[7], + dev->dev_instance.data[6], + dev->dev_instance.data[8], + dev->dev_instance.data[9], + dev->dev_instance.data[10], + dev->dev_instance.data[11], + dev->dev_instance.data[12], + dev->dev_instance.data[13], + dev->dev_instance.data[14], + dev->dev_instance.data[15]); if (ret) return ret; -- cgit v1.2.3 From 6bad88dac0e648c6978a02c6afb0dc2f4fa484bb Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 7 Mar 2011 13:35:48 -0800 Subject: Staging: hv: Remove the vm_device structure Consolidate all device related state in struct hv_device by moving the device field from struct vm_device to struct hv_device. As part of this, also get rid of struct vm_device since the consolidation is complete. Signed-off-by: K. Y. Srinivasan Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 16 ++++----- drivers/staging/hv/hv_mouse.c | 19 ++++------ drivers/staging/hv/netvsc_drv.c | 24 ++++++------- drivers/staging/hv/storvsc_drv.c | 24 ++++++------- drivers/staging/hv/vmbus.h | 12 ++----- drivers/staging/hv/vmbus_api.h | 2 ++ drivers/staging/hv/vmbus_drv.c | 77 ++++++++++++++++++---------------------- 7 files changed, 73 insertions(+), 101 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 0f9fb05d2347..6e02f1b0c46f 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -95,7 +95,7 @@ struct blkvsc_request { /* Per device structure */ struct block_device_context { /* point back to our device context */ - struct vm_device *device_ctx; + struct hv_device *device_ctx; struct kmem_cache *request_pool; spinlock_t lock; struct gendisk *gd; @@ -240,8 +240,7 @@ static int blkvsc_probe(struct device *device) drv_to_hv_drv(device->driver); struct storvsc_driver_object *storvsc_drv_obj = drv->priv; - struct vm_device *device_ctx = device_to_vm_device(device); - struct hv_device *device_obj = &device_ctx->device_obj; + struct hv_device *device_obj = device_to_hv_device(device); struct block_device_context *blkdev = NULL; struct storvsc_device_info device_info; @@ -273,7 +272,7 @@ static int blkvsc_probe(struct device *device) /* ASSERT(sizeof(struct blkvsc_request_group) <= */ /* sizeof(struct blkvsc_request)); */ - blkdev->request_pool = kmem_cache_create(dev_name(&device_ctx->device), + blkdev->request_pool = kmem_cache_create(dev_name(&device_obj->device), sizeof(struct blkvsc_request) + storvsc_drv_obj->request_ext_size, 0, SLAB_HWCACHE_ALIGN, NULL); @@ -290,7 +289,7 @@ static int blkvsc_probe(struct device *device) goto Cleanup; } - blkdev->device_ctx = device_ctx; + blkdev->device_ctx = device_obj; /* this identified the device 0 or 1 */ blkdev->target = device_info.target_id; /* this identified the ide ctrl 0 or 1 */ @@ -723,8 +722,7 @@ static int blkvsc_remove(struct device *device) drv_to_hv_drv(device->driver); struct storvsc_driver_object *storvsc_drv_obj = drv->priv; - struct vm_device *device_ctx = device_to_vm_device(device); - struct hv_device *device_obj = &device_ctx->device_obj; + struct hv_device *device_obj = device_to_hv_device(device); struct block_device_context *blkdev = dev_get_drvdata(device); unsigned long flags; int ret; @@ -839,7 +837,7 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, void (*request_completion)(struct hv_storvsc_request *)) { struct block_device_context *blkdev = blkvsc_req->dev; - struct vm_device *device_ctx = blkdev->device_ctx; + struct hv_device *device_ctx = blkdev->device_ctx; struct hv_driver *drv = drv_to_hv_drv(device_ctx->device.driver); struct storvsc_driver_object *storvsc_drv_obj = @@ -884,7 +882,7 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, storvsc_req->sense_buffer = blkvsc_req->sense_buffer; storvsc_req->sense_buffer_size = SCSI_SENSE_BUFFERSIZE; - ret = storvsc_drv_obj->on_io_request(&blkdev->device_ctx->device_obj, + ret = storvsc_drv_obj->on_io_request(blkdev->device_ctx, &blkvsc_req->request); if (ret == 0) blkdev->num_outstanding_reqs++; diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 6c5c00da8e7b..8f94f433961f 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -771,7 +771,7 @@ static void MousevscOnCleanup(struct hv_driver *drv) * Data types */ struct input_device_context { - struct vm_device *device_ctx; + struct hv_device *device_ctx; struct hid_device *hid_device; struct hv_input_dev_info device_info; int connected; @@ -782,9 +782,8 @@ static struct mousevsc_drv_obj g_mousevsc_drv; static void deviceinfo_callback(struct hv_device *dev, struct hv_input_dev_info *info) { - struct vm_device *device_ctx = to_vm_device(dev); struct input_device_context *input_device_ctx = - dev_get_drvdata(&device_ctx->device); + dev_get_drvdata(&dev->device); memcpy(&input_device_ctx->device_info, info, sizeof(struct hv_input_dev_info)); @@ -796,9 +795,8 @@ static void inputreport_callback(struct hv_device *dev, void *packet, u32 len) { int ret = 0; - struct vm_device *device_ctx = to_vm_device(dev); struct input_device_context *input_dev_ctx = - dev_get_drvdata(&device_ctx->device); + dev_get_drvdata(&dev->device); ret = hid_input_report(input_dev_ctx->hid_device, HID_INPUT_REPORT, packet, len, 1); @@ -823,8 +821,7 @@ static int mousevsc_probe(struct device *device) drv_to_hv_drv(device->driver); struct mousevsc_drv_obj *mousevsc_drv_obj = drv->priv; - struct vm_device *device_ctx = device_to_vm_device(device); - struct hv_device *device_obj = &device_ctx->device_obj; + struct hv_device *device_obj = device_to_hv_device(device); struct input_device_context *input_dev_ctx; input_dev_ctx = kmalloc(sizeof(struct input_device_context), @@ -852,8 +849,7 @@ static int mousevsc_remove(struct device *device) drv_to_hv_drv(device->driver); struct mousevsc_drv_obj *mousevsc_drv_obj = drv->priv; - struct vm_device *device_ctx = device_to_vm_device(device); - struct hv_device *device_obj = &device_ctx->device_obj; + struct hv_device *device_obj = device_to_hv_device(device); struct input_device_context *input_dev_ctx; input_dev_ctx = kmalloc(sizeof(struct input_device_context), @@ -887,9 +883,8 @@ static int mousevsc_remove(struct device *device) static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len) { - struct vm_device *device_ctx = to_vm_device(dev); struct input_device_context *input_device_ctx = - dev_get_drvdata(&device_ctx->device); + dev_get_drvdata(&dev->device); struct hid_device *hid_dev; /* hid_debug = -1; */ @@ -910,7 +905,7 @@ static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len) hid_dev->vendor = input_device_ctx->device_info.vendor; hid_dev->product = input_device_ctx->device_info.product; hid_dev->version = input_device_ctx->device_info.version; - hid_dev->dev = device_ctx->device; + hid_dev->dev = dev->device; sprintf(hid_dev->name, "%s", input_device_ctx->device_info.name); diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index f0d258cc5839..2d40f5f86b24 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -44,7 +44,7 @@ struct net_device_context { /* point back to our device context */ - struct vm_device *device_ctx; + struct hv_device *device_ctx; unsigned long avail; }; @@ -70,7 +70,7 @@ static void netvsc_set_multicast_list(struct net_device *net) static int netvsc_open(struct net_device *net) { struct net_device_context *net_device_ctx = netdev_priv(net); - struct hv_device *device_obj = &net_device_ctx->device_ctx->device_obj; + struct hv_device *device_obj = net_device_ctx->device_ctx; int ret = 0; if (netif_carrier_ok(net)) { @@ -93,7 +93,7 @@ static int netvsc_open(struct net_device *net) static int netvsc_close(struct net_device *net) { struct net_device_context *net_device_ctx = netdev_priv(net); - struct hv_device *device_obj = &net_device_ctx->device_ctx->device_obj; + struct hv_device *device_obj = net_device_ctx->device_ctx; int ret; netif_stop_queue(net); @@ -190,7 +190,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) packet->completion.send.send_completion_ctx = packet; packet->completion.send.send_completion_tid = (unsigned long)skb; - ret = net_drv_obj->send(&net_device_ctx->device_ctx->device_obj, + ret = net_drv_obj->send(net_device_ctx->device_ctx, packet); if (ret == 0) { net->stats.tx_bytes += skb->len; @@ -218,8 +218,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) static void netvsc_linkstatus_callback(struct hv_device *device_obj, unsigned int status) { - struct vm_device *device_ctx = to_vm_device(device_obj); - struct net_device *net = dev_get_drvdata(&device_ctx->device); + struct net_device *net = dev_get_drvdata(&device_obj->device); if (!net) { DPRINT_ERR(NETVSC_DRV, "got link status but net device " @@ -244,8 +243,7 @@ static void netvsc_linkstatus_callback(struct hv_device *device_obj, static int netvsc_recv_callback(struct hv_device *device_obj, struct hv_netvsc_packet *packet) { - struct vm_device *device_ctx = to_vm_device(device_obj); - struct net_device *net = dev_get_drvdata(&device_ctx->device); + struct net_device *net = dev_get_drvdata(&device_obj->device); struct sk_buff *skb; void *data; int i; @@ -335,8 +333,7 @@ static int netvsc_probe(struct device *device) struct hv_driver *drv = drv_to_hv_drv(device->driver); struct netvsc_driver *net_drv_obj = drv->priv; - struct vm_device *device_ctx = device_to_vm_device(device); - struct hv_device *device_obj = &device_ctx->device_obj; + struct hv_device *device_obj = device_to_hv_device(device); struct net_device *net = NULL; struct net_device_context *net_device_ctx; struct netvsc_device_info device_info; @@ -353,7 +350,7 @@ static int netvsc_probe(struct device *device) netif_carrier_off(net); net_device_ctx = netdev_priv(net); - net_device_ctx->device_ctx = device_ctx; + net_device_ctx->device_ctx = device_obj; net_device_ctx->avail = ring_size; dev_set_drvdata(device, net); @@ -405,9 +402,8 @@ static int netvsc_remove(struct device *device) struct hv_driver *drv = drv_to_hv_drv(device->driver); struct netvsc_driver *net_drv_obj = drv->priv; - struct vm_device *device_ctx = device_to_vm_device(device); - struct net_device *net = dev_get_drvdata(&device_ctx->device); - struct hv_device *device_obj = &device_ctx->device_obj; + struct hv_device *device_obj = device_to_hv_device(device); + struct net_device *net = dev_get_drvdata(&device_obj->device); int ret; if (net == NULL) { diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 972273461cba..e6462a2fe9ab 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -42,7 +42,7 @@ struct host_device_context { /* must be 1st field * FIXME this is a bug */ /* point back to our device context */ - struct vm_device *device_ctx; + struct hv_device *device_ctx; struct kmem_cache *request_pool; unsigned int port; unsigned char path; @@ -216,8 +216,7 @@ static int storvsc_probe(struct device *device) struct hv_driver *drv = drv_to_hv_drv(device->driver); struct storvsc_driver_object *storvsc_drv_obj = drv->priv; - struct vm_device *device_ctx = device_to_vm_device(device); - struct hv_device *device_obj = &device_ctx->device_obj; + struct hv_device *device_obj = device_to_hv_device(device); struct Scsi_Host *host; struct host_device_context *host_device_ctx; struct storvsc_device_info device_info; @@ -238,10 +237,10 @@ static int storvsc_probe(struct device *device) memset(host_device_ctx, 0, sizeof(struct host_device_context)); host_device_ctx->port = host->host_no; - host_device_ctx->device_ctx = device_ctx; + host_device_ctx->device_ctx = device_obj; host_device_ctx->request_pool = - kmem_cache_create(dev_name(&device_ctx->device), + kmem_cache_create(dev_name(&device_obj->device), sizeof(struct storvsc_cmd_request) + storvsc_drv_obj->request_ext_size, 0, SLAB_HWCACHE_ALIGN, NULL); @@ -298,8 +297,7 @@ static int storvsc_remove(struct device *device) struct hv_driver *drv = drv_to_hv_drv(device->driver); struct storvsc_driver_object *storvsc_drv_obj = drv->priv; - struct vm_device *device_ctx = device_to_vm_device(device); - struct hv_device *device_obj = &device_ctx->device_obj; + struct hv_device *device_obj = device_to_hv_device(device); struct Scsi_Host *host = dev_get_drvdata(device); struct host_device_context *host_device_ctx = (struct host_device_context *)host->hostdata; @@ -589,7 +587,7 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, int ret; struct host_device_context *host_device_ctx = (struct host_device_context *)scmnd->device->host->hostdata; - struct vm_device *device_ctx = host_device_ctx->device_ctx; + struct hv_device *device_ctx = host_device_ctx->device_ctx; struct hv_driver *drv = drv_to_hv_drv(device_ctx->device.driver); struct storvsc_driver_object *storvsc_drv_obj = drv->priv; @@ -737,7 +735,7 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, retry_request: /* Invokes the vsc to start an IO */ - ret = storvsc_drv_obj->on_io_request(&device_ctx->device_obj, + ret = storvsc_drv_obj->on_io_request(device_ctx, &cmd_request->request); if (ret == -1) { /* no more space */ @@ -824,18 +822,18 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) int ret; struct host_device_context *host_device_ctx = (struct host_device_context *)scmnd->device->host->hostdata; - struct vm_device *device_ctx = host_device_ctx->device_ctx; + struct hv_device *device_ctx = host_device_ctx->device_ctx; DPRINT_INFO(STORVSC_DRV, "sdev (%p) dev obj (%p) - host resetting...", - scmnd->device, &device_ctx->device_obj); + scmnd->device, device_ctx); /* Invokes the vsc to reset the host/bus */ - ret = stor_vsc_on_host_reset(&device_ctx->device_obj); + ret = stor_vsc_on_host_reset(device_ctx); if (ret != 0) return ret; DPRINT_INFO(STORVSC_DRV, "sdev (%p) dev obj (%p) - host reseted", - scmnd->device, &device_ctx->device_obj); + scmnd->device, device_ctx); return ret; } diff --git a/drivers/staging/hv/vmbus.h b/drivers/staging/hv/vmbus.h index ab296bb0b039..73087f26bec2 100644 --- a/drivers/staging/hv/vmbus.h +++ b/drivers/staging/hv/vmbus.h @@ -29,19 +29,11 @@ #include "vmbus_api.h" -struct vm_device { - struct hv_device device_obj; - struct device device; -}; -static inline struct vm_device *to_vm_device(struct hv_device *d) -{ - return container_of(d, struct vm_device, device_obj); -} -static inline struct vm_device *device_to_vm_device(struct device *d) +static inline struct hv_device *device_to_hv_device(struct device *d) { - return container_of(d, struct vm_device, device); + return container_of(d, struct hv_device, device); } static inline struct hv_driver *drv_to_hv_drv(struct device_driver *d) diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index 4c5a38e349b6..f0d96eba7013 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -128,6 +128,8 @@ struct hv_device { /* the device instance id of this device */ struct hv_guid dev_instance; + struct device device; + struct vmbus_channel *channel; /* Device extension; */ diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 819366221524..159dfdaec0fc 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -49,7 +49,7 @@ struct vmbus_driver_context { struct tasklet_struct event_dpc; /* The bus root device */ - struct vm_device device_ctx; + struct hv_device device_ctx; }; static int vmbus_match(struct device *device, struct device_driver *driver); @@ -349,12 +349,12 @@ static ssize_t vmbus_show_device_attr(struct device *dev, struct device_attribute *dev_attr, char *buf) { - struct vm_device *device_ctx = device_to_vm_device(dev); + struct hv_device *device_ctx = device_to_hv_device(dev); struct hv_device_info device_info; memset(&device_info, 0, sizeof(struct hv_device_info)); - get_channel_info(&device_ctx->device_obj, &device_info); + get_channel_info(device_ctx, &device_info); if (!strcmp(dev_attr->attr.name, "class_id")) { return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-" @@ -459,7 +459,7 @@ static int vmbus_bus_init(void) { struct vmbus_driver_context *vmbus_drv_ctx = &vmbus_drv; struct hv_driver *driver = &vmbus_drv.drv_obj; - struct vm_device *dev_ctx = &vmbus_drv.device_ctx; + struct hv_device *dev_ctx = &vmbus_drv.device_ctx; int ret; unsigned int vector; @@ -530,9 +530,9 @@ static int vmbus_bus_init(void) DPRINT_INFO(VMBUS_DRV, "irq 0x%x vector 0x%x", vmbus_irq, vector); /* Call to bus driver to add the root device */ - memset(dev_ctx, 0, sizeof(struct vm_device)); + memset(dev_ctx, 0, sizeof(struct hv_device)); - ret = driver->dev_add(&dev_ctx->device_obj, &vector); + ret = driver->dev_add(dev_ctx, &vector); if (ret != 0) { DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to add vmbus root device"); @@ -585,11 +585,11 @@ static void vmbus_bus_exit(void) struct hv_driver *driver = &vmbus_drv.drv_obj; struct vmbus_driver_context *vmbus_drv_ctx = &vmbus_drv; - struct vm_device *dev_ctx = &vmbus_drv.device_ctx; + struct hv_device *dev_ctx = &vmbus_drv.device_ctx; /* Remove the root device */ if (driver->dev_rm) - driver->dev_rm(&dev_ctx->device_obj); + driver->dev_rm(dev_ctx); if (driver->cleanup) driver->cleanup(driver); @@ -664,12 +664,11 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *type, struct hv_guid *instance, struct vmbus_channel *channel) { - struct vm_device *child_device_ctx; struct hv_device *child_device_obj; /* Allocate the new child device */ - child_device_ctx = kzalloc(sizeof(struct vm_device), GFP_KERNEL); - if (!child_device_ctx) { + child_device_obj = kzalloc(sizeof(struct hv_device), GFP_KERNEL); + if (!child_device_obj) { DPRINT_ERR(VMBUS_DRV, "unable to allocate device_context for child device"); return NULL; @@ -680,7 +679,7 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *type, "%02x%02x%02x%02x%02x%02x%02x%02x}," "id {%02x%02x%02x%02x-%02x%02x-%02x%02x-" "%02x%02x%02x%02x%02x%02x%02x%02x}", - &child_device_ctx->device, + &child_device_obj->device, type->data[3], type->data[2], type->data[1], type->data[0], type->data[5], type->data[4], type->data[7], type->data[6], type->data[8], type->data[9], type->data[10], type->data[11], @@ -694,7 +693,6 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *type, instance->data[12], instance->data[13], instance->data[14], instance->data[15]); - child_device_obj = &child_device_ctx->device_obj; child_device_obj->channel = channel; memcpy(&child_device_obj->dev_type, type, sizeof(struct hv_guid)); memcpy(&child_device_obj->dev_instance, instance, @@ -711,39 +709,36 @@ int vmbus_child_device_register(struct hv_device *root_device_obj, struct hv_device *child_device_obj) { int ret = 0; - struct vm_device *root_device_ctx = - to_vm_device(root_device_obj); - struct vm_device *child_device_ctx = - to_vm_device(child_device_obj); + static atomic_t device_num = ATOMIC_INIT(0); DPRINT_DBG(VMBUS_DRV, "child device (%p) registering", - child_device_ctx); + child_device_obj); /* Set the device name. Otherwise, device_register() will fail. */ - dev_set_name(&child_device_ctx->device, "vmbus_0_%d", + dev_set_name(&child_device_obj->device, "vmbus_0_%d", atomic_inc_return(&device_num)); /* The new device belongs to this bus */ - child_device_ctx->device.bus = &vmbus_drv.bus; /* device->dev.bus; */ - child_device_ctx->device.parent = &root_device_ctx->device; - child_device_ctx->device.release = vmbus_device_release; + child_device_obj->device.bus = &vmbus_drv.bus; /* device->dev.bus; */ + child_device_obj->device.parent = &root_device_obj->device; + child_device_obj->device.release = vmbus_device_release; /* * Register with the LDM. This will kick off the driver/device * binding...which will eventually call vmbus_match() and vmbus_probe() */ - ret = device_register(&child_device_ctx->device); + ret = device_register(&child_device_obj->device); /* vmbus_probe() error does not get propergate to device_register(). */ - ret = child_device_ctx->device_obj.probe_error; + ret = child_device_obj->probe_error; if (ret) DPRINT_ERR(VMBUS_DRV, "unable to register child device (%p)", - &child_device_ctx->device); + &child_device_obj->device); else DPRINT_INFO(VMBUS_DRV, "child device (%p) registered", - &child_device_ctx->device); + &child_device_obj->device); return ret; } @@ -754,19 +749,18 @@ int vmbus_child_device_register(struct hv_device *root_device_obj, */ void vmbus_child_device_unregister(struct hv_device *device_obj) { - struct vm_device *device_ctx = to_vm_device(device_obj); DPRINT_INFO(VMBUS_DRV, "unregistering child device (%p)", - &device_ctx->device); + &device_obj->device); /* * Kick off the process of unregistering the device. * This will call vmbus_remove() and eventually vmbus_device_release() */ - device_unregister(&device_ctx->device); + device_unregister(&device_obj->device); DPRINT_INFO(VMBUS_DRV, "child device (%p) unregistered", - &device_ctx->device); + &device_obj->device); } /* @@ -778,8 +772,7 @@ void vmbus_child_device_unregister(struct hv_device *device_obj) */ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) { - struct vm_device *device_ctx = device_to_vm_device(device); - struct hv_device *dev = &device_ctx->device_obj; + struct hv_device *dev = device_to_hv_device(device); int ret; DPRINT_INFO(VMBUS_DRV, "generating uevent - VMBUS_DEVICE_CLASS_GUID={" @@ -852,17 +845,17 @@ static int vmbus_match(struct device *device, struct device_driver *driver) { int match = 0; struct hv_driver *drv = drv_to_hv_drv(driver); - struct vm_device *device_ctx = device_to_vm_device(device); + struct hv_device *device_ctx = device_to_hv_device(device); /* We found our driver ? */ - if (memcmp(&device_ctx->device_obj.dev_type, &drv->dev_type, + if (memcmp(&device_ctx->dev_type, &drv->dev_type, sizeof(struct hv_guid)) == 0) { - device_ctx->device_obj.drv = drv->priv; + device_ctx->drv = drv->priv; DPRINT_INFO(VMBUS_DRV, "device object (%p) set to driver object (%p)", - &device_ctx->device_obj, - device_ctx->device_obj.drv); + &device_ctx, + device_ctx->drv); match = 1; } @@ -878,7 +871,7 @@ static int vmbus_match(struct device *device, struct device_driver *driver) */ static void vmbus_probe_failed_cb(struct work_struct *context) { - struct vm_device *device_ctx = (struct vm_device *)context; + struct hv_device *device_ctx = (struct hv_device *)context; /* * Kick off the process of unregistering the device. @@ -897,13 +890,11 @@ static int vmbus_probe(struct device *child_device) int ret = 0; struct hv_driver *drv = drv_to_hv_drv(child_device->driver); - struct vm_device *device_ctx = - device_to_vm_device(child_device); - struct hv_device *dev = &device_ctx->device_obj; + struct hv_device *dev = device_to_hv_device(child_device); /* Let the specific open-source driver handles the probe if it can */ if (drv->driver.probe) { - ret = device_ctx->device_obj.probe_error = + ret = dev->probe_error = drv->driver.probe(child_device); if (ret != 0) { DPRINT_ERR(VMBUS_DRV, "probe() failed for device %s " @@ -1006,7 +997,7 @@ static void vmbus_bus_release(struct device *device) */ static void vmbus_device_release(struct device *device) { - struct vm_device *device_ctx = device_to_vm_device(device); + struct hv_device *device_ctx = device_to_hv_device(device); kfree(device_ctx); -- cgit v1.2.3 From 062ac622e03a8be5f894555ece540d63a54ae8bd Mon Sep 17 00:00:00 2001 From: roel Date: Mon, 7 Mar 2011 18:00:34 +0100 Subject: drm: index i shadowed in 2nd loop Index i was already used in thhe first loop Signed-off-by: Roel Kluin Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_fb_helper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 6977a1ce9d98..f73ef4390db6 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -672,7 +672,7 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) struct drm_crtc_helper_funcs *crtc_funcs; u16 *red, *green, *blue, *transp; struct drm_crtc *crtc; - int i, rc = 0; + int i, j, rc = 0; int start; for (i = 0; i < fb_helper->crtc_count; i++) { @@ -685,7 +685,7 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) transp = cmap->transp; start = cmap->start; - for (i = 0; i < cmap->len; i++) { + for (j = 0; j < cmap->len; j++) { u16 hred, hgreen, hblue, htransp = 0xffff; hred = *red++; -- cgit v1.2.3 From e80d9da651b19a79a1500d6bb808fcbcb39a869d Mon Sep 17 00:00:00 2001 From: Padmanabh Ratnakar Date: Mon, 7 Mar 2011 03:07:58 +0000 Subject: be2net: Remove ERR compl workaround for Lancer Workaround added for Lancer in handling RX ERR completion received when no RX buffers are posted is not needed. Signed-off-by: Padmanabh Ratnakar Signed-off-by: Sathya Perla Signed-off-by: Subramanian Seetharaman Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 4 +--- drivers/net/benet/be_main.c | 31 ++++++++----------------------- 2 files changed, 9 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index ed709a5d07d7..4ac0d72660fe 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -220,9 +220,7 @@ struct be_rx_obj { struct be_rx_stats stats; u8 rss_id; bool rx_post_starved; /* Zero rx frags have been posted to BE */ - u16 last_frag_index; - u16 rsvd; - u32 cache_line_barrier[15]; + u32 cache_line_barrier[16]; }; struct be_drv_stats { diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index ef66dc61e6ea..bf344347b5a6 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -909,17 +909,11 @@ static void be_rx_compl_discard(struct be_adapter *adapter, rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); - /* Skip out-of-buffer compl(lancer) or flush compl(BE) */ - if (likely(rxq_idx != rxo->last_frag_index && num_rcvd != 0)) { - - rxo->last_frag_index = rxq_idx; - - for (i = 0; i < num_rcvd; i++) { - page_info = get_rx_page_info(adapter, rxo, rxq_idx); - put_page(page_info->page); - memset(page_info, 0, sizeof(*page_info)); - index_inc(&rxq_idx, rxq->len); - } + for (i = 0; i < num_rcvd; i++) { + page_info = get_rx_page_info(adapter, rxo, rxq_idx); + put_page(page_info->page); + memset(page_info, 0, sizeof(*page_info)); + index_inc(&rxq_idx, rxq->len); } } @@ -1579,9 +1573,6 @@ static int be_rx_queues_create(struct be_adapter *adapter) adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; for_all_rx_queues(adapter, rxo, i) { rxo->adapter = adapter; - /* Init last_frag_index so that the frag index in the first - * completion will never match */ - rxo->last_frag_index = 0xffff; rxo->rx_eq.max_eqd = BE_MAX_EQD; rxo->rx_eq.enable_aic = true; @@ -1722,7 +1713,7 @@ static int be_poll_rx(struct napi_struct *napi, int budget) struct be_queue_info *rx_cq = &rxo->cq; struct be_eth_rx_compl *rxcp; u32 work_done; - u16 frag_index, num_rcvd; + u16 num_rcvd; u8 err; rxo->stats.rx_polls++; @@ -1732,16 +1723,10 @@ static int be_poll_rx(struct napi_struct *napi, int budget) break; err = AMAP_GET_BITS(struct amap_eth_rx_compl, err, rxcp); - frag_index = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, - rxcp); num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); - - /* Skip out-of-buffer compl(lancer) or flush compl(BE) */ - if (likely(frag_index != rxo->last_frag_index && - num_rcvd != 0)) { - rxo->last_frag_index = frag_index; - + /* Ignore flush completions */ + if (num_rcvd) { if (do_gro(rxo, rxcp, err)) be_rx_compl_process_gro(adapter, rxo, rxcp); else -- cgit v1.2.3 From 19fad86f3b34f52eebc511f6cdb99e82f53aee94 Mon Sep 17 00:00:00 2001 From: Padmanabh Ratnakar Date: Mon, 7 Mar 2011 03:08:16 +0000 Subject: be2net: Checksum field valid only for TCP/UDP L4 checksum field is valid only for TCP/UDP packets in Lancer Signed-off-by: Padmanabh Ratnakar Signed-off-by: Sathya Perla Signed-off-by: Subramanian Seetharaman Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index bf344347b5a6..ac7ae21bd0d1 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -865,14 +865,17 @@ static void be_rx_stats_update(struct be_rx_obj *rxo, static inline bool csum_passed(struct be_eth_rx_compl *rxcp) { - u8 l4_cksm, ipv6, ipcksm; + u8 l4_cksm, ipv6, ipcksm, tcpf, udpf; l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp); ipcksm = AMAP_GET_BITS(struct amap_eth_rx_compl, ipcksm, rxcp); ipv6 = AMAP_GET_BITS(struct amap_eth_rx_compl, ip_version, rxcp); + tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp); + udpf = AMAP_GET_BITS(struct amap_eth_rx_compl, udpf, rxcp); - /* Ignore ipcksm for ipv6 pkts */ - return l4_cksm && (ipcksm || ipv6); + /* L4 checksum is not reliable for non TCP/UDP packets. + * Also ignore ipcksm for ipv6 pkts */ + return (tcpf || udpf) && l4_cksm && (ipcksm || ipv6); } static struct be_rx_page_info * -- cgit v1.2.3 From 37eed1cbbd446dc2808e1bff717010aa978fc0de Mon Sep 17 00:00:00 2001 From: Padmanabh Ratnakar Date: Mon, 7 Mar 2011 03:08:36 +0000 Subject: be2net: Add error recovery during load for Lancer Add error recovery during load for Lancer Signed-off-by: Padmanabh Ratnakar Signed-off-by: Sathya Perla Signed-off-by: Subramanian Seetharaman Signed-off-by: David S. Miller --- drivers/net/benet/be_hw.h | 12 ++++++++++ drivers/net/benet/be_main.c | 56 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) (limited to 'drivers') diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index 3f459f76cd1d..dbe67f353e8f 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h @@ -44,6 +44,18 @@ #define POST_STAGE_BE_RESET 0x3 /* Host wants to reset chip */ #define POST_STAGE_ARMFW_RDY 0xc000 /* FW is done with POST */ + +/* Lancer SLIPORT_CONTROL SLIPORT_STATUS registers */ +#define SLIPORT_STATUS_OFFSET 0x404 +#define SLIPORT_CONTROL_OFFSET 0x408 + +#define SLIPORT_STATUS_ERR_MASK 0x80000000 +#define SLIPORT_STATUS_RN_MASK 0x01000000 +#define SLIPORT_STATUS_RDY_MASK 0x00800000 + + +#define SLI_PORT_CONTROL_IP_MASK 0x08000000 + /********* Memory BAR register ************/ #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc /* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index ac7ae21bd0d1..665a9b7310f6 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2901,6 +2901,54 @@ static int be_dev_family_check(struct be_adapter *adapter) return 0; } +static int lancer_wait_ready(struct be_adapter *adapter) +{ +#define SLIPORT_READY_TIMEOUT 500 + u32 sliport_status; + int status = 0, i; + + for (i = 0; i < SLIPORT_READY_TIMEOUT; i++) { + sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET); + if (sliport_status & SLIPORT_STATUS_RDY_MASK) + break; + + msleep(20); + } + + if (i == SLIPORT_READY_TIMEOUT) + status = -1; + + return status; +} + +static int lancer_test_and_set_rdy_state(struct be_adapter *adapter) +{ + int status; + u32 sliport_status, err, reset_needed; + status = lancer_wait_ready(adapter); + if (!status) { + sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET); + err = sliport_status & SLIPORT_STATUS_ERR_MASK; + reset_needed = sliport_status & SLIPORT_STATUS_RN_MASK; + if (err && reset_needed) { + iowrite32(SLI_PORT_CONTROL_IP_MASK, + adapter->db + SLIPORT_CONTROL_OFFSET); + + /* check adapter has corrected the error */ + status = lancer_wait_ready(adapter); + sliport_status = ioread32(adapter->db + + SLIPORT_STATUS_OFFSET); + sliport_status &= (SLIPORT_STATUS_ERR_MASK | + SLIPORT_STATUS_RN_MASK); + if (status || sliport_status) + status = -1; + } else if (err || reset_needed) { + status = -1; + } + } + return status; +} + static int __devinit be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) { @@ -2950,6 +2998,14 @@ static int __devinit be_probe(struct pci_dev *pdev, if (status) goto free_netdev; + if (lancer_chip(adapter)) { + status = lancer_test_and_set_rdy_state(adapter); + if (status) { + dev_err(&pdev->dev, "Adapter in non recoverable error\n"); + goto free_netdev; + } + } + /* sync up with fw's ready state */ if (be_physfn(adapter)) { status = be_cmd_POST(adapter); -- cgit v1.2.3 From 8b7756ca52b11225395a9fadf9ed200f03983b46 Mon Sep 17 00:00:00 2001 From: Padmanabh Ratnakar Date: Mon, 7 Mar 2011 03:08:52 +0000 Subject: be2net: Change f/w command versions for Lancer Change f/w command versions for Lancer Signed-off-by: Padmanabh Ratnakar Signed-off-by: Sathya Perla Signed-off-by: Subramanian Seetharaman Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.c | 8 +++++++- drivers/net/benet/be_cmds.h | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 1822ecdadc7e..cc3a235475bc 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -726,7 +726,7 @@ int be_cmd_cq_create(struct be_adapter *adapter, req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); if (lancer_chip(adapter)) { - req->hdr.version = 1; + req->hdr.version = 2; req->page_size = 1; /* 1 for 4K */ AMAP_SET_BITS(struct amap_cq_context_lancer, coalescwm, ctxt, coalesce_wm); @@ -862,6 +862,12 @@ int be_cmd_txq_create(struct be_adapter *adapter, be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, OPCODE_ETH_TX_CREATE, sizeof(*req)); + if (lancer_chip(adapter)) { + req->hdr.version = 1; + AMAP_SET_BITS(struct amap_tx_context, if_id, ctxt, + adapter->if_handle); + } + req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); req->ulp_num = BE_ULP1_NUM; req->type = BE_ETH_TX_RING_TYPE_STANDARD; diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 93e5768fc705..5bdaa22dee80 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -430,7 +430,7 @@ struct be_cmd_resp_mcc_create { /* Pseudo amap definition in which each bit of the actual structure is defined * as a byte: used to calculate offset/shift/mask of each field */ struct amap_tx_context { - u8 rsvd0[16]; /* dword 0 */ + u8 if_id[16]; /* dword 0 */ u8 tx_ring_size[4]; /* dword 0 */ u8 rsvd1[26]; /* dword 0 */ u8 pci_func_id[8]; /* dword 1 */ -- cgit v1.2.3 From d8a29d315969b0edbf4a37a1a91c361e222909a2 Mon Sep 17 00:00:00 2001 From: Padmanabh Ratnakar Date: Mon, 7 Mar 2011 03:09:04 +0000 Subject: be2net: Remove TX Queue stop in close Remove TX Queue stop in close Signed-off-by: Padmanabh Ratnakar Signed-off-by: Sathya Perla Signed-off-by: Subramanian Seetharaman Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 665a9b7310f6..68b9d17a0f1a 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2082,7 +2082,6 @@ static int be_close(struct net_device *netdev) be_async_mcc_disable(adapter); - netif_stop_queue(netdev); netif_carrier_off(netdev); adapter->link_up = false; -- cgit v1.2.3 From 63fcb27fdce614ac1b7cc6251bfcb7077f3002b3 Mon Sep 17 00:00:00 2001 From: Padmanabh Ratnakar Date: Mon, 7 Mar 2011 03:09:17 +0000 Subject: be2net: Disarm CQ and EQ to disable interrupt in Lancer For Lancer disable interrupts in close by disarming CQs and EQs. Change the order of calls in be_close to achieve the correct result. Signed-off-by: Padmanabh Ratnakar Signed-off-by: Sathya Perla Signed-off-by: Subramanian Seetharaman Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 68b9d17a0f1a..a7fd833fe7d2 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2088,6 +2088,18 @@ static int be_close(struct net_device *netdev) if (!lancer_chip(adapter)) be_intr_set(adapter, false); + for_all_rx_queues(adapter, rxo, i) + napi_disable(&rxo->rx_eq.napi); + + napi_disable(&tx_eq->napi); + + if (lancer_chip(adapter)) { + be_cq_notify(adapter, adapter->tx_obj.cq.id, false, 0); + be_cq_notify(adapter, adapter->mcc_obj.cq.id, false, 0); + for_all_rx_queues(adapter, rxo, i) + be_cq_notify(adapter, rxo->cq.id, false, 0); + } + if (adapter->msix_enabled) { vec = be_msix_vec_get(adapter, tx_eq); synchronize_irq(vec); @@ -2101,11 +2113,6 @@ static int be_close(struct net_device *netdev) } be_irq_unregister(adapter); - for_all_rx_queues(adapter, rxo, i) - napi_disable(&rxo->rx_eq.napi); - - napi_disable(&tx_eq->napi); - /* Wait for all pending tx completions to arrive so that * all tx skbs are freed. */ -- cgit v1.2.3 From f21b538ced88a39a6dd9ef4e2c5d9aac300f428b Mon Sep 17 00:00:00 2001 From: Padmanabh Ratnakar Date: Mon, 7 Mar 2011 03:09:36 +0000 Subject: be2net: Add multicast filter capability for Lancer Lancer requires multicast capability flag set during IFACE_CREATE for adding multicast filters. Signed-off-by: Padmanabh Ratnakar Signed-off-by: Sathya Perla Signed-off-by: Subramanian Seetharaman Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.h | 3 ++- drivers/net/benet/be_main.c | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index 5bdaa22dee80..b4ac3938b298 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -518,7 +518,8 @@ enum be_if_flags { BE_IF_FLAGS_VLAN = 0x100, BE_IF_FLAGS_MCAST_PROMISCUOUS = 0x200, BE_IF_FLAGS_PASS_L2_ERRORS = 0x400, - BE_IF_FLAGS_PASS_L3L4_ERRORS = 0x800 + BE_IF_FLAGS_PASS_L3L4_ERRORS = 0x800, + BE_IF_FLAGS_MULTICAST = 0x1000 }; /* An RX interface is an object with one or more MAC addresses and diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index a7fd833fe7d2..68f107817326 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2263,7 +2263,9 @@ static int be_setup(struct be_adapter *adapter) int status; u8 mac[ETH_ALEN]; - cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST; + cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | + BE_IF_FLAGS_BROADCAST | + BE_IF_FLAGS_MULTICAST; if (be_physfn(adapter)) { cap_flags |= BE_IF_FLAGS_MCAST_PROMISCUOUS | -- cgit v1.2.3 From cca134fe784a01cf4eb9f0621b0104591b7ddfba Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Wed, 2 Mar 2011 18:26:21 +0000 Subject: bonding: remove the unused dummy functions when net poll controller isn't enabled These two functions are only used when net poll controller is enabled. Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 0592e6da15a6..912b416b7573 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1380,14 +1380,6 @@ static inline void slave_disable_netpoll(struct slave *slave) static void bond_netpoll_cleanup(struct net_device *bond_dev) { } -static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni) -{ - return 0; -} -static struct netpoll_info *bond_netpoll_info(struct bonding *bond) -{ - return NULL; -} #endif /*---------------------------------- IOCTL ----------------------------------*/ -- cgit v1.2.3 From 541ac7c9b30ee2ff84ad87f27e0bc069e143afb5 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Wed, 2 Mar 2011 21:07:14 +0000 Subject: bonding: COW before overwriting the destination MAC address When there is a ptype handler holding a clone of this skb, whose destination MAC addresse is overwritten, the owner of this handler may get a corrupted packet. Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 912b416b7573..7b7ca971672f 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1511,9 +1511,13 @@ static struct sk_buff *bond_handle_frame(struct sk_buff *skb) if (bond_dev->priv_flags & IFF_MASTER_ALB && bond_dev->priv_flags & IFF_BRIDGE_PORT && skb->pkt_type == PACKET_HOST) { - u16 *dest = (u16 *) eth_hdr(skb)->h_dest; - memcpy(dest, bond_dev->dev_addr, ETH_ALEN); + if (unlikely(skb_cow_head(skb, + skb->data - skb_mac_header(skb)))) { + kfree_skb(skb); + return NULL; + } + memcpy(eth_hdr(skb)->h_dest, bond_dev->dev_addr, ETH_ALEN); } return skb; -- cgit v1.2.3 From 06f0c1392c20d708ffae067fdcad604882e19200 Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Fri, 4 Mar 2011 01:23:58 +0000 Subject: s2io: fix uninitialized compile warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/net/s2io.c:7559: warning: ‘tcp_len’ may be used uninitialized in this function Signed-off-by: Shan Wei Signed-off-by: David S. Miller --- drivers/net/s2io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 39c17cecb8b9..2ad6364103ea 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -7556,7 +7556,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) */ skb->ip_summed = CHECKSUM_UNNECESSARY; if (ring_data->lro) { - u32 tcp_len; + u32 tcp_len = 0; u8 *tcp; int ret = 0; -- cgit v1.2.3 From ce3c869283739379134e1a90c37dd1a30b5f31b7 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Fri, 4 Mar 2011 13:49:41 +0000 Subject: drivers/net/macvtap: fix error check 'len' is unsigned of type size_t and can't be negative. Signed-off-by: Nicolas Kaiser Acked-by: Arnd Bergmann Signed-off-by: David S. Miller --- drivers/net/macvtap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 5933621ac3ff..fc27a9926d9e 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -528,8 +528,9 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, vnet_hdr_len = q->vnet_hdr_sz; err = -EINVAL; - if ((len -= vnet_hdr_len) < 0) + if (len < vnet_hdr_len) goto err; + len -= vnet_hdr_len; err = memcpy_fromiovecend((void *)&vnet_hdr, iv, 0, sizeof(vnet_hdr)); -- cgit v1.2.3 From 16d79d7dc98e56d4700054b9b785a92102d8998c Mon Sep 17 00:00:00 2001 From: Nils Carlson Date: Thu, 3 Mar 2011 22:09:11 +0000 Subject: bonding 802.3ad: Fix the state machine locking v2 Changes since v1: * Clarify an unclear comment * Move a (possible) name change to a separate patch The ad_rx_machine, ad_periodic_machine and ad_port_selection_logic functions all inspect and alter common fields within the port structure. Previous to this patch, only the ad_rx_machines were mutexed, and the periodic and port_selection could run unmutexed against an ad_rx_machine trigged by an arriving LACPDU. This patch remedies the situation by protecting all the state machines from concurrency. This is accomplished by locking around all the state machines for a given port, which are executed at regular intervals; and the ad_rx_machine when handling an incoming LACPDU. Signed-off-by: Nils Carlson Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 1024ae158227..de30c8d6301e 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -1025,9 +1025,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) { rx_states_t last_state; - // Lock to prevent 2 instances of this function to run simultaneously(rx interrupt and periodic machine callback) - __get_rx_machine_lock(port); - // keep current State Machine state to compare later if it was changed last_state = port->sm_rx_state; @@ -1133,7 +1130,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) pr_err("%s: An illegal loopback occurred on adapter (%s).\n" "Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n", port->slave->dev->master->name, port->slave->dev->name); - __release_rx_machine_lock(port); return; } __update_selected(lacpdu, port); @@ -1153,7 +1149,6 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) break; } } - __release_rx_machine_lock(port); } /** @@ -2155,6 +2150,12 @@ void bond_3ad_state_machine_handler(struct work_struct *work) goto re_arm; } + /* Lock around state machines to protect data accessed + * by all (e.g., port->sm_vars). ad_rx_machine may run + * concurrently due to incoming LACPDU. + */ + __get_rx_machine_lock(port); + ad_rx_machine(NULL, port); ad_periodic_machine(port); ad_port_selection_logic(port); @@ -2164,6 +2165,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work) // turn off the BEGIN bit, since we already handled it if (port->sm_vars & AD_PORT_BEGIN) port->sm_vars &= ~AD_PORT_BEGIN; + + __release_rx_machine_lock(port); } re_arm: @@ -2200,7 +2203,10 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u case AD_TYPE_LACPDU: pr_debug("Received LACPDU on port %d\n", port->actor_port_number); + /* Protect against concurrent state machines */ + __get_rx_machine_lock(port); ad_rx_machine(lacpdu, port); + __release_rx_machine_lock(port); break; case AD_TYPE_MARKER: -- cgit v1.2.3 From 9ac3524a948cab48137a8b40a4fa8ae1092b0a24 Mon Sep 17 00:00:00 2001 From: Nils Carlson Date: Thu, 3 Mar 2011 22:09:12 +0000 Subject: bonding 802.3ad: Rename rx_machine_lock to state_machine_lock Rename the rx_machine_lock to state_machine_lock as this makes more sense in light of it now protecting all the state machines against concurrency. Signed-off-by: Nils Carlson Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 24 ++++++++++++------------ drivers/net/bonding/bond_3ad.h | 3 ++- 2 files changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index de30c8d6301e..a5d5d0b5b155 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -281,23 +281,23 @@ static inline int __check_agg_selection_timer(struct port *port) } /** - * __get_rx_machine_lock - lock the port's RX machine + * __get_state_machine_lock - lock the port's state machines * @port: the port we're looking at * */ -static inline void __get_rx_machine_lock(struct port *port) +static inline void __get_state_machine_lock(struct port *port) { - spin_lock_bh(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); + spin_lock_bh(&(SLAVE_AD_INFO(port->slave).state_machine_lock)); } /** - * __release_rx_machine_lock - unlock the port's RX machine + * __release_state_machine_lock - unlock the port's state machines * @port: the port we're looking at * */ -static inline void __release_rx_machine_lock(struct port *port) +static inline void __release_state_machine_lock(struct port *port) { - spin_unlock_bh(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); + spin_unlock_bh(&(SLAVE_AD_INFO(port->slave).state_machine_lock)); } /** @@ -388,14 +388,14 @@ static u8 __get_duplex(struct port *port) } /** - * __initialize_port_locks - initialize a port's RX machine spinlock + * __initialize_port_locks - initialize a port's STATE machine spinlock * @port: the port we're looking at * */ static inline void __initialize_port_locks(struct port *port) { // make sure it isn't called twice - spin_lock_init(&(SLAVE_AD_INFO(port->slave).rx_machine_lock)); + spin_lock_init(&(SLAVE_AD_INFO(port->slave).state_machine_lock)); } //conversions @@ -2154,7 +2154,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work) * by all (e.g., port->sm_vars). ad_rx_machine may run * concurrently due to incoming LACPDU. */ - __get_rx_machine_lock(port); + __get_state_machine_lock(port); ad_rx_machine(NULL, port); ad_periodic_machine(port); @@ -2166,7 +2166,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work) if (port->sm_vars & AD_PORT_BEGIN) port->sm_vars &= ~AD_PORT_BEGIN; - __release_rx_machine_lock(port); + __release_state_machine_lock(port); } re_arm: @@ -2204,9 +2204,9 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u pr_debug("Received LACPDU on port %d\n", port->actor_port_number); /* Protect against concurrent state machines */ - __get_rx_machine_lock(port); + __get_state_machine_lock(port); ad_rx_machine(lacpdu, port); - __release_rx_machine_lock(port); + __release_state_machine_lock(port); break; case AD_TYPE_MARKER: diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h index 2c46a154f2c6..b28baff70864 100644 --- a/drivers/net/bonding/bond_3ad.h +++ b/drivers/net/bonding/bond_3ad.h @@ -264,7 +264,8 @@ struct ad_bond_info { struct ad_slave_info { struct aggregator aggregator; // 802.3ad aggregator structure struct port port; // 802.3ad port structure - spinlock_t rx_machine_lock; // To avoid race condition between callback and receive interrupt + spinlock_t state_machine_lock; /* mutex state machines vs. + incoming LACPDU */ u16 id; }; -- cgit v1.2.3 From a1d76e10ae73348997f55efffc977e792d76a2c6 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Mon, 14 Feb 2011 08:19:24 +0000 Subject: e1000e: fix build issue due to undefined reference to crc32_le kernel build fails with: drivers/built-in.o: In function `e1000_lv_jumbo_workaround_ich8lan': (.text+0x3e7a8): undefined reference to `crc32_le' when CONFIG_CRC32 is not set or does not match the CONFIG_E1000E selection. Signed-off-by: Emil Tantilov Reviewed-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 7ce3dd01d6eb..925c25c295f0 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2109,6 +2109,7 @@ config E1000 config E1000E tristate "Intel(R) PRO/1000 PCI-Express Gigabit Ethernet support" depends on PCI && (!SPARC32 || BROKEN) + select CRC32 ---help--- This driver supports the PCI-Express Intel(R) PRO/1000 gigabit ethernet family of adapters. For PCI or PCI-X e1000 adapters, -- cgit v1.2.3 From 0a915b95d67f3bf63121c04aeb4eaebb183feb58 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Sat, 26 Feb 2011 07:42:37 +0000 Subject: igb: Add stats output for OS2BMC feature on i350 devices This patch adds statistics output for OS2BMC feature which is configured by eeprom on capable devices. Signed-off-by: Carolyn Wyborny Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/igb/e1000_defines.h | 1 + drivers/net/igb/e1000_hw.h | 4 ++++ drivers/net/igb/e1000_regs.h | 7 +++++++ drivers/net/igb/igb_ethtool.c | 9 ++++++++- drivers/net/igb/igb_main.c | 9 +++++++++ 5 files changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index ff46c91520af..92e11da25749 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h @@ -110,6 +110,7 @@ /* Management Control */ #define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */ #define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */ +#define E1000_MANC_EN_BMC2OS 0x10000000 /* OSBMC is Enabled or not */ /* Enable Neighbor Discovery Filtering */ #define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */ #define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */ diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h index 281324e85980..eec9ed735588 100644 --- a/drivers/net/igb/e1000_hw.h +++ b/drivers/net/igb/e1000_hw.h @@ -248,6 +248,10 @@ struct e1000_hw_stats { u64 scvpc; u64 hrmpc; u64 doosync; + u64 o2bgptc; + u64 o2bspc; + u64 b2ospc; + u64 b2ogprc; }; struct e1000_phy_stats { diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h index 3a6f8471aea2..61713548c027 100644 --- a/drivers/net/igb/e1000_regs.h +++ b/drivers/net/igb/e1000_regs.h @@ -328,4 +328,11 @@ /* DMA Coalescing registers */ #define E1000_PCIEMISC 0x05BB8 /* PCIE misc config register */ + +/* OS2BMC Registers */ +#define E1000_B2OSPC 0x08FE0 /* BMC2OS packets sent by BMC */ +#define E1000_B2OGPRC 0x04158 /* BMC2OS packets received by host */ +#define E1000_O2BGPTC 0x08FE4 /* OS2BMC packets received by BMC */ +#define E1000_O2BSPC 0x0415C /* OS2BMC packets transmitted by host */ + #endif diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index 61f7849cb5a7..78d420b4b2db 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -86,6 +86,10 @@ static const struct igb_stats igb_gstrings_stats[] = { IGB_STAT("tx_smbus", stats.mgptc), IGB_STAT("rx_smbus", stats.mgprc), IGB_STAT("dropped_smbus", stats.mgpdc), + IGB_STAT("os2bmc_rx_by_bmc", stats.o2bgptc), + IGB_STAT("os2bmc_tx_by_bmc", stats.b2ospc), + IGB_STAT("os2bmc_tx_by_host", stats.o2bspc), + IGB_STAT("os2bmc_rx_by_host", stats.b2ogprc), }; #define IGB_NETDEV_STAT(_net_stat) { \ @@ -603,7 +607,10 @@ static void igb_get_regs(struct net_device *netdev, regs_buff[548] = rd32(E1000_TDFT); regs_buff[549] = rd32(E1000_TDFHS); regs_buff[550] = rd32(E1000_TDFPC); - + regs_buff[551] = adapter->stats.o2bgptc; + regs_buff[552] = adapter->stats.b2ospc; + regs_buff[553] = adapter->stats.o2bspc; + regs_buff[554] = adapter->stats.b2ogprc; } static int igb_get_eeprom_len(struct net_device *netdev) diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index eef380af0537..3666b967846a 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -4560,6 +4560,15 @@ void igb_update_stats(struct igb_adapter *adapter, adapter->stats.mgptc += rd32(E1000_MGTPTC); adapter->stats.mgprc += rd32(E1000_MGTPRC); adapter->stats.mgpdc += rd32(E1000_MGTPDC); + + /* OS2BMC Stats */ + reg = rd32(E1000_MANC); + if (reg & E1000_MANC_EN_BMC2OS) { + adapter->stats.o2bgptc += rd32(E1000_O2BGPTC); + adapter->stats.o2bspc += rd32(E1000_O2BSPC); + adapter->stats.b2ospc += rd32(E1000_B2OSPC); + adapter->stats.b2ogprc += rd32(E1000_B2OGPRC); + } } static irqreturn_t igb_msix_other(int irq, void *data) -- cgit v1.2.3 From 90827996c59135b73e54463dac38710d5ddf1d2a Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Sat, 5 Mar 2011 18:59:20 -0800 Subject: ixgbe: fix missing function pointer conversion In the previous commit: commit 5e655105e3e19d746f9e95c514b014c11c3d1b6a Author: Don Skidmore Date: Fri Feb 25 01:58:04 2011 +0000 ixgbe: add function pointer for semaphore function there was one release of the semaphore function call which did not get converted to a function pointer. Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index a7fb2e00f766..94a56217027c 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -1075,7 +1075,7 @@ static void ixgbe_release_eeprom(struct ixgbe_hw *hw) eec &= ~IXGBE_EEC_REQ; IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); - ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); /* Delay before attempt to obtain semaphore again to allow FW access */ msleep(hw->eeprom.semaphore_delay); -- cgit v1.2.3 From 68a683cf6a5ff09faa366fc1fcf967add0211fe8 Mon Sep 17 00:00:00 2001 From: Yi Zou Date: Tue, 1 Feb 2011 07:22:16 +0000 Subject: ixgbe: add support to FCoE DDP in target mode Add support to the ndo_fcoe_ddp_target() to allow the Intel 82599 device to also provide DDP offload capability when the upper FCoE protocol stack is operating as a target. Signed-off-by: Yi Zou Signed-off-by: Kiran Patil Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 2 + drivers/net/ixgbe/ixgbe_fcoe.c | 86 ++++++++++++++++++++++++++++++++++++------ drivers/net/ixgbe/ixgbe_fcoe.h | 4 ++ drivers/net/ixgbe/ixgbe_main.c | 1 + 4 files changed, 81 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index b60b81bc2b15..1e546fc127d0 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -552,6 +552,8 @@ extern int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, struct sk_buff *skb); extern int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, struct scatterlist *sgl, unsigned int sgc); +extern int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid, + struct scatterlist *sgl, unsigned int sgc); extern int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid); extern int ixgbe_fcoe_enable(struct net_device *netdev); extern int ixgbe_fcoe_disable(struct net_device *netdev); diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 27203c87ea14..00af15a9cdc6 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -135,22 +135,19 @@ out_ddp_put: return len; } + /** - * ixgbe_fcoe_ddp_get - called to set up ddp context + * ixgbe_fcoe_ddp_setup - called to set up ddp context * @netdev: the corresponding net_device * @xid: the exchange id requesting ddp * @sgl: the scatter-gather list for this request * @sgc: the number of scatter-gather items * - * This is the implementation of net_device_ops.ndo_fcoe_ddp_setup - * and is expected to be called from ULD, e.g., FCP layer of libfc - * to set up ddp for the corresponding xid of the given sglist for - * the corresponding I/O. - * * Returns : 1 for success and 0 for no ddp */ -int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, - struct scatterlist *sgl, unsigned int sgc) +static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid, + struct scatterlist *sgl, unsigned int sgc, + int target_mode) { struct ixgbe_adapter *adapter; struct ixgbe_hw *hw; @@ -164,7 +161,7 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, unsigned int lastsize; unsigned int thisoff = 0; unsigned int thislen = 0; - u32 fcbuff, fcdmarw, fcfltrw; + u32 fcbuff, fcdmarw, fcfltrw, fcrxctl; dma_addr_t addr = 0; if (!netdev || !sgl) @@ -275,6 +272,9 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT); fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT); fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT); + /* Set WRCONTX bit to allow DDP for target */ + if (target_mode) + fcbuff |= (IXGBE_FCBUFF_WRCONTX); fcbuff |= (IXGBE_FCBUFF_VALID); fcdmarw = xid; @@ -287,6 +287,16 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, /* program DMA context */ hw = &adapter->hw; spin_lock_bh(&fcoe->lock); + + /* turn on last frame indication for target mode as FCP_RSPtarget is + * supposed to send FCP_RSP when it is done. */ + if (target_mode && !test_bit(__IXGBE_FCOE_TARGET, &fcoe->mode)) { + set_bit(__IXGBE_FCOE_TARGET, &fcoe->mode); + fcrxctl = IXGBE_READ_REG(hw, IXGBE_FCRXCTRL); + fcrxctl |= IXGBE_FCRXCTRL_LASTSEQH; + IXGBE_WRITE_REG(hw, IXGBE_FCRXCTRL, fcrxctl); + } + IXGBE_WRITE_REG(hw, IXGBE_FCPTRL, ddp->udp & DMA_BIT_MASK(32)); IXGBE_WRITE_REG(hw, IXGBE_FCPTRH, (u64)ddp->udp >> 32); IXGBE_WRITE_REG(hw, IXGBE_FCBUFF, fcbuff); @@ -295,6 +305,7 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, IXGBE_WRITE_REG(hw, IXGBE_FCPARAM, 0); IXGBE_WRITE_REG(hw, IXGBE_FCFLT, IXGBE_FCFLT_VALID); IXGBE_WRITE_REG(hw, IXGBE_FCFLTRW, fcfltrw); + spin_unlock_bh(&fcoe->lock); return 1; @@ -308,6 +319,47 @@ out_noddp_unmap: return 0; } +/** + * ixgbe_fcoe_ddp_get - called to set up ddp context in initiator mode + * @netdev: the corresponding net_device + * @xid: the exchange id requesting ddp + * @sgl: the scatter-gather list for this request + * @sgc: the number of scatter-gather items + * + * This is the implementation of net_device_ops.ndo_fcoe_ddp_setup + * and is expected to be called from ULD, e.g., FCP layer of libfc + * to set up ddp for the corresponding xid of the given sglist for + * the corresponding I/O. + * + * Returns : 1 for success and 0 for no ddp + */ +int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, + struct scatterlist *sgl, unsigned int sgc) +{ + return ixgbe_fcoe_ddp_setup(netdev, xid, sgl, sgc, 0); +} + +/** + * ixgbe_fcoe_ddp_target - called to set up ddp context in target mode + * @netdev: the corresponding net_device + * @xid: the exchange id requesting ddp + * @sgl: the scatter-gather list for this request + * @sgc: the number of scatter-gather items + * + * This is the implementation of net_device_ops.ndo_fcoe_ddp_target + * and is expected to be called from ULD, e.g., FCP layer of libfc + * to set up ddp for the corresponding xid of the given sglist for + * the corresponding I/O. The DDP in target mode is a write I/O request + * from the initiator. + * + * Returns : 1 for success and 0 for no ddp + */ +int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid, + struct scatterlist *sgl, unsigned int sgc) +{ + return ixgbe_fcoe_ddp_setup(netdev, xid, sgl, sgc, 1); +} + /** * ixgbe_fcoe_ddp - check ddp status and mark it done * @adapter: ixgbe adapter @@ -331,6 +383,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, struct ixgbe_fcoe *fcoe; struct ixgbe_fcoe_ddp *ddp; struct fc_frame_header *fh; + struct fcoe_crc_eof *crc; if (!ixgbe_rx_is_fcoe(rx_desc)) goto ddp_out; @@ -384,7 +437,18 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, else if (ddp->len) rc = ddp->len; } - + /* In target mode, check the last data frame of the sequence. + * For DDP in target mode, data is already DDPed but the header + * indication of the last data frame ould allow is to tell if we + * got all the data and the ULP can send FCP_RSP back, as this is + * not a full fcoe frame, we fill the trailer here so it won't be + * dropped by the ULP stack. + */ + if ((fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA) && + (fctl & FC_FC_END_SEQ)) { + crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc)); + crc->fcoe_eof = FC_EOF_T; + } ddp_out: return rc; } @@ -840,5 +904,3 @@ int ixgbe_fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type) } return rc; } - - diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h index 02a00d2415d9..5a650a4ace66 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.h +++ b/drivers/net/ixgbe/ixgbe_fcoe.h @@ -52,6 +52,9 @@ /* fcerr */ #define IXGBE_FCERR_BADCRC 0x00100000 +/* FCoE DDP for target mode */ +#define __IXGBE_FCOE_TARGET 1 + struct ixgbe_fcoe_ddp { int len; u32 err; @@ -66,6 +69,7 @@ struct ixgbe_fcoe { u8 tc; u8 up; #endif + unsigned long mode; atomic_t refcnt; spinlock_t lock; struct pci_pool *pool; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 32231ffe0717..5e8c39decca1 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -7019,6 +7019,7 @@ static const struct net_device_ops ixgbe_netdev_ops = { #endif #ifdef IXGBE_FCOE .ndo_fcoe_ddp_setup = ixgbe_fcoe_ddp_get, + .ndo_fcoe_ddp_target = ixgbe_fcoe_ddp_target, .ndo_fcoe_ddp_done = ixgbe_fcoe_ddp_put, .ndo_fcoe_enable = ixgbe_fcoe_enable, .ndo_fcoe_disable = ixgbe_fcoe_disable, -- cgit v1.2.3 From 037c6d0a33453bf025c6d6b21e5a0fabe117a797 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Fri, 25 Feb 2011 07:49:39 +0000 Subject: ixgbe: cleanup PHY init This change cleans up several situations in which we were either stepping over possible errors, or calling initialization routines multiple times. Also includes whitespace fixes where applicable. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82598.c | 31 +++++++--- drivers/net/ixgbe/ixgbe_82599.c | 121 +++++++++++++++++++++++----------------- drivers/net/ixgbe/ixgbe_phy.c | 21 ++++++- 3 files changed, 114 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index fc41329399be..dc977b1c8eab 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -280,10 +280,22 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw) { enum ixgbe_media_type media_type; + /* Detect if there is a copper PHY attached. */ + switch (hw->phy.type) { + case ixgbe_phy_cu_unknown: + case ixgbe_phy_tn: + case ixgbe_phy_aq: + media_type = ixgbe_media_type_copper; + goto out; + default: + break; + } + /* Media type for I82598 is based on device ID */ switch (hw->device_id) { case IXGBE_DEV_ID_82598: case IXGBE_DEV_ID_82598_BX: + /* Default device ID is mezzanine card KX/KX4 */ media_type = ixgbe_media_type_backplane; break; case IXGBE_DEV_ID_82598AF_DUAL_PORT: @@ -306,7 +318,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw) media_type = ixgbe_media_type_unknown; break; } - +out: return media_type; } @@ -632,7 +644,7 @@ out: * @hw: pointer to hardware structure * @speed: new link speed * @autoneg: true if auto-negotiation enabled - * @autoneg_wait_to_complete: true if waiting is needed to complete + * @autoneg_wait_to_complete: true when waiting for completion is needed * * Set the link speed in the AUTOC register and restarts link. **/ @@ -671,7 +683,8 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw, * ixgbe_hw This will write the AUTOC register based on the new * stored values */ - status = ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete); + status = ixgbe_start_mac_link_82598(hw, + autoneg_wait_to_complete); } return status; @@ -1090,10 +1103,12 @@ static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw) /* Copper PHY must be checked before AUTOC LMS to determine correct * physical layer because 10GBase-T PHYs use LMS = KX4/KX */ - if (hw->phy.type == ixgbe_phy_tn || - hw->phy.type == ixgbe_phy_cu_unknown) { - hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD, - &ext_ability); + switch (hw->phy.type) { + case ixgbe_phy_tn: + case ixgbe_phy_aq: + case ixgbe_phy_cu_unknown: + hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, + MDIO_MMD_PMAPMD, &ext_ability); if (ext_ability & MDIO_PMA_EXTABLE_10GBT) physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; if (ext_ability & MDIO_PMA_EXTABLE_1000BT) @@ -1101,6 +1116,8 @@ static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw) if (ext_ability & MDIO_PMA_EXTABLE_100BTX) physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; goto out; + default: + break; } switch (autoc & IXGBE_AUTOC_LMS_MASK) { diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 5ef968a10d42..2f8b9f41714f 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -470,8 +470,6 @@ static void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) **/ static void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) { - hw_dbg(hw, "ixgbe_flap_tx_laser_multispeed_fiber\n"); - if (hw->mac.autotry_restart) { ixgbe_disable_tx_laser_multispeed_fiber(hw); ixgbe_enable_tx_laser_multispeed_fiber(hw); @@ -494,17 +492,21 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, bool autoneg_wait_to_complete) { s32 status = 0; - ixgbe_link_speed phy_link_speed; + ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN; ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN; u32 speedcnt = 0; u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); + u32 i = 0; bool link_up = false; bool negotiation; - int i; /* Mask off requested but non-supported speeds */ - hw->mac.ops.get_link_capabilities(hw, &phy_link_speed, &negotiation); - speed &= phy_link_speed; + status = hw->mac.ops.get_link_capabilities(hw, &link_speed, + &negotiation); + if (status != 0) + return status; + + speed &= link_speed; /* * Try each speed one by one, highest priority first. We do this in @@ -515,9 +517,12 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL; /* If we already have link at this speed, just jump out */ - hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false); + status = hw->mac.ops.check_link(hw, &link_speed, &link_up, + false); + if (status != 0) + return status; - if ((phy_link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up) + if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up) goto out; /* Set the module link speed */ @@ -529,9 +534,9 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, msleep(40); status = ixgbe_setup_mac_link_82599(hw, - IXGBE_LINK_SPEED_10GB_FULL, - autoneg, - autoneg_wait_to_complete); + IXGBE_LINK_SPEED_10GB_FULL, + autoneg, + autoneg_wait_to_complete); if (status != 0) return status; @@ -548,8 +553,11 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, msleep(100); /* If we have link, just jump out */ - hw->mac.ops.check_link(hw, &phy_link_speed, - &link_up, false); + status = hw->mac.ops.check_link(hw, &link_speed, + &link_up, false); + if (status != 0) + return status; + if (link_up) goto out; } @@ -561,9 +569,12 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL; /* If we already have link at this speed, just jump out */ - hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false); + status = hw->mac.ops.check_link(hw, &link_speed, &link_up, + false); + if (status != 0) + return status; - if ((phy_link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up) + if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up) goto out; /* Set the module link speed */ @@ -576,9 +587,9 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, msleep(40); status = ixgbe_setup_mac_link_82599(hw, - IXGBE_LINK_SPEED_1GB_FULL, - autoneg, - autoneg_wait_to_complete); + IXGBE_LINK_SPEED_1GB_FULL, + autoneg, + autoneg_wait_to_complete); if (status != 0) return status; @@ -589,7 +600,11 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, msleep(100); /* If we have link, just jump out */ - hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false); + status = hw->mac.ops.check_link(hw, &link_speed, &link_up, + false); + if (status != 0) + return status; + if (link_up) goto out; } @@ -632,13 +647,10 @@ static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, bool autoneg_wait_to_complete) { s32 status = 0; - ixgbe_link_speed link_speed; + ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN; s32 i, j; bool link_up = false; u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); - struct ixgbe_adapter *adapter = hw->back; - - hw_dbg(hw, "ixgbe_setup_mac_link_smartspeed.\n"); /* Set autoneg_advertised value based on input link speed */ hw->phy.autoneg_advertised = 0; @@ -664,7 +676,7 @@ static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, for (j = 0; j < IXGBE_SMARTSPEED_MAX_RETRIES; j++) { status = ixgbe_setup_mac_link_82599(hw, speed, autoneg, autoneg_wait_to_complete); - if (status) + if (status != 0) goto out; /* @@ -677,8 +689,11 @@ static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, mdelay(100); /* If we have link, just jump out */ - hw->mac.ops.check_link(hw, &link_speed, - &link_up, false); + status = hw->mac.ops.check_link(hw, &link_speed, + &link_up, false); + if (status != 0) + goto out; + if (link_up) goto out; } @@ -696,7 +711,7 @@ static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, hw->phy.smart_speed_active = true; status = ixgbe_setup_mac_link_82599(hw, speed, autoneg, autoneg_wait_to_complete); - if (status) + if (status != 0) goto out; /* @@ -709,8 +724,11 @@ static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, mdelay(100); /* If we have link, just jump out */ - hw->mac.ops.check_link(hw, &link_speed, - &link_up, false); + status = hw->mac.ops.check_link(hw, &link_speed, + &link_up, false); + if (status != 0) + goto out; + if (link_up) goto out; } @@ -722,7 +740,7 @@ static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, out: if (link_up && (link_speed == IXGBE_LINK_SPEED_1GB_FULL)) - e_info(hw, "Smartspeed has downgraded the link speed from " + hw_dbg(hw, "Smartspeed has downgraded the link speed from " "the maximum advertised\n"); return status; } @@ -883,7 +901,7 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) /* PHY ops must be identified and initialized prior to reset */ - /* Init PHY and function pointers, perform SFP setup */ + /* Identify PHY and related function pointers */ status = hw->phy.ops.init(hw); if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) @@ -895,6 +913,9 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) hw->phy.sfp_setup_needed = false; } + if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) + goto reset_hw_out; + /* Reset PHY */ if (hw->phy.reset_disable == false && hw->phy.ops.reset != NULL) hw->phy.ops.reset(hw); @@ -2051,28 +2072,28 @@ static struct ixgbe_mac_operations mac_ops_82599 = { }; static struct ixgbe_eeprom_operations eeprom_ops_82599 = { - .init_params = &ixgbe_init_eeprom_params_generic, - .read = &ixgbe_read_eerd_generic, - .write = &ixgbe_write_eeprom_generic, - .calc_checksum = &ixgbe_calc_eeprom_checksum_generic, - .validate_checksum = &ixgbe_validate_eeprom_checksum_generic, - .update_checksum = &ixgbe_update_eeprom_checksum_generic, + .init_params = &ixgbe_init_eeprom_params_generic, + .read = &ixgbe_read_eerd_generic, + .write = &ixgbe_write_eeprom_generic, + .calc_checksum = &ixgbe_calc_eeprom_checksum_generic, + .validate_checksum = &ixgbe_validate_eeprom_checksum_generic, + .update_checksum = &ixgbe_update_eeprom_checksum_generic, }; static struct ixgbe_phy_operations phy_ops_82599 = { - .identify = &ixgbe_identify_phy_82599, - .identify_sfp = &ixgbe_identify_sfp_module_generic, - .init = &ixgbe_init_phy_ops_82599, - .reset = &ixgbe_reset_phy_generic, - .read_reg = &ixgbe_read_phy_reg_generic, - .write_reg = &ixgbe_write_phy_reg_generic, - .setup_link = &ixgbe_setup_phy_link_generic, - .setup_link_speed = &ixgbe_setup_phy_link_speed_generic, - .read_i2c_byte = &ixgbe_read_i2c_byte_generic, - .write_i2c_byte = &ixgbe_write_i2c_byte_generic, - .read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic, - .write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic, - .check_overtemp = &ixgbe_tn_check_overtemp, + .identify = &ixgbe_identify_phy_82599, + .identify_sfp = &ixgbe_identify_sfp_module_generic, + .init = &ixgbe_init_phy_ops_82599, + .reset = &ixgbe_reset_phy_generic, + .read_reg = &ixgbe_read_phy_reg_generic, + .write_reg = &ixgbe_write_phy_reg_generic, + .setup_link = &ixgbe_setup_phy_link_generic, + .setup_link_speed = &ixgbe_setup_phy_link_speed_generic, + .read_i2c_byte = &ixgbe_read_i2c_byte_generic, + .write_i2c_byte = &ixgbe_write_i2c_byte_generic, + .read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic, + .write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic, + .check_overtemp = &ixgbe_tn_check_overtemp, }; struct ixgbe_info ixgbe_82599_info = { diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index 197230b2d1ac..9190a8fca427 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -57,6 +57,7 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) { s32 status = IXGBE_ERR_PHY_ADDR_INVALID; u32 phy_addr; + u16 ext_ability = 0; if (hw->phy.type == ixgbe_phy_unknown) { for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { @@ -65,12 +66,29 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) ixgbe_get_phy_id(hw); hw->phy.type = ixgbe_get_phy_type_from_id(hw->phy.id); + + if (hw->phy.type == ixgbe_phy_unknown) { + hw->phy.ops.read_reg(hw, + MDIO_PMA_EXTABLE, + MDIO_MMD_PMAPMD, + &ext_ability); + if (ext_ability & + (MDIO_PMA_EXTABLE_10GBT | + MDIO_PMA_EXTABLE_1000BT)) + hw->phy.type = + ixgbe_phy_cu_unknown; + else + hw->phy.type = + ixgbe_phy_generic; + } + status = 0; break; } } /* clear value if nothing found */ - hw->phy.mdio.prtad = 0; + if (status != 0) + hw->phy.mdio.prtad = 0; } else { status = 0; } @@ -823,7 +841,6 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) goto out; } - /* This is guaranteed to be 82599, no need to check for NULL */ hw->mac.ops.get_device_caps(hw, &enforce_sfp); if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) && !((hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0) || -- cgit v1.2.3 From 667c75651025049b39a2b5b83d8fc09a7967cce3 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 26 Feb 2011 06:40:05 +0000 Subject: ixgbe: clear correct counters for flow control on 82599 The 82599 was not correctly having some of it's counters cleared for flow control. This change corrects that. Signed-off-by: Emil Tantilov Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_common.c | 34 +++++++++++++++++++++++++++------- drivers/net/ixgbe/ixgbe_type.h | 2 ++ 2 files changed, 29 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 94a56217027c..85cc30143738 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -136,17 +136,29 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw) IXGBE_READ_REG(hw, IXGBE_MRFC); IXGBE_READ_REG(hw, IXGBE_RLEC); IXGBE_READ_REG(hw, IXGBE_LXONTXC); - IXGBE_READ_REG(hw, IXGBE_LXONRXC); IXGBE_READ_REG(hw, IXGBE_LXOFFTXC); - IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); + if (hw->mac.type >= ixgbe_mac_82599EB) { + IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); + IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); + } else { + IXGBE_READ_REG(hw, IXGBE_LXONRXC); + IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); + } for (i = 0; i < 8; i++) { IXGBE_READ_REG(hw, IXGBE_PXONTXC(i)); - IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i)); - IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); + if (hw->mac.type >= ixgbe_mac_82599EB) { + IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i)); + IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i)); + } else { + IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); + IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); + } } - + if (hw->mac.type >= ixgbe_mac_82599EB) + for (i = 0; i < 8; i++) + IXGBE_READ_REG(hw, IXGBE_PXON2OFFCNT(i)); IXGBE_READ_REG(hw, IXGBE_PRC64); IXGBE_READ_REG(hw, IXGBE_PRC127); IXGBE_READ_REG(hw, IXGBE_PRC255); @@ -184,9 +196,17 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw) IXGBE_READ_REG(hw, IXGBE_BPTC); for (i = 0; i < 16; i++) { IXGBE_READ_REG(hw, IXGBE_QPRC(i)); - IXGBE_READ_REG(hw, IXGBE_QBRC(i)); IXGBE_READ_REG(hw, IXGBE_QPTC(i)); - IXGBE_READ_REG(hw, IXGBE_QBTC(i)); + if (hw->mac.type >= ixgbe_mac_82599EB) { + IXGBE_READ_REG(hw, IXGBE_QBRC_L(i)); + IXGBE_READ_REG(hw, IXGBE_QBRC_H(i)); + IXGBE_READ_REG(hw, IXGBE_QBTC_L(i)); + IXGBE_READ_REG(hw, IXGBE_QBTC_H(i)); + IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); + } else { + IXGBE_READ_REG(hw, IXGBE_QBRC(i)); + IXGBE_READ_REG(hw, IXGBE_QBTC(i)); + } } return 0; diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 013751db5fc0..13a45c7c89d0 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -659,6 +659,8 @@ #define IXGBE_QPTC(_i) (0x06030 + ((_i) * 0x40)) /* 16 of these */ #define IXGBE_QBRC(_i) (0x01034 + ((_i) * 0x40)) /* 16 of these */ #define IXGBE_QBTC(_i) (0x06034 + ((_i) * 0x40)) /* 16 of these */ +#define IXGBE_QBRC_L(_i) (0x01034 + ((_i) * 0x40)) /* 16 of these */ +#define IXGBE_QBRC_H(_i) (0x01038 + ((_i) * 0x40)) /* 16 of these */ #define IXGBE_QPRDC(_i) (0x01430 + ((_i) * 0x40)) /* 16 of these */ #define IXGBE_QBTC_L(_i) (0x08700 + ((_i) * 0x8)) /* 16 of these */ #define IXGBE_QBTC_H(_i) (0x08704 + ((_i) * 0x8)) /* 16 of these */ -- cgit v1.2.3 From a3aeea0ec8d3af854edf7dc983dc8cbe803a43e8 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 26 Feb 2011 06:40:11 +0000 Subject: ixgbe: Add x540 statistic counter definitions Add defines to accumulate and display x540 PHY statistic counters on transmit/receive. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_common.c | 9 +++++++++ drivers/net/ixgbe/ixgbe_type.h | 5 +++++ 2 files changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 85cc30143738..561f666618e4 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -209,6 +209,15 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw) } } + if (hw->mac.type == ixgbe_mac_X540) { + if (hw->phy.id == 0) + hw->phy.ops.identify(hw); + hw->phy.ops.read_reg(hw, 0x3, IXGBE_PCRC8ECL, &i); + hw->phy.ops.read_reg(hw, 0x3, IXGBE_PCRC8ECH, &i); + hw->phy.ops.read_reg(hw, 0x3, IXGBE_LDPCECL, &i); + hw->phy.ops.read_reg(hw, 0x3, IXGBE_LDPCECH, &i); + } + return 0; } diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 13a45c7c89d0..76bf21b8a10d 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -671,6 +671,11 @@ #define IXGBE_FCOEDWRC 0x0242C /* Number of FCoE DWords Received */ #define IXGBE_FCOEPTC 0x08784 /* Number of FCoE Packets Transmitted */ #define IXGBE_FCOEDWTC 0x08788 /* Number of FCoE DWords Transmitted */ +#define IXGBE_PCRC8ECL 0x0E810 +#define IXGBE_PCRC8ECH 0x0E811 +#define IXGBE_PCRC8ECH_MASK 0x1F +#define IXGBE_LDPCECL 0x0E820 +#define IXGBE_LDPCECH 0x0E821 /* Management */ #define IXGBE_MAVTV(_i) (0x05010 + ((_i) * 4)) /* 8 of these (0-7) */ -- cgit v1.2.3 From 0b0c2b31bdf8d6fb5c14ae70894453ac44d64672 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 26 Feb 2011 06:40:16 +0000 Subject: ixgbe: Enable flow control pause parameter auto-negotiation support This patch enables flow control pause parameters auto-negotiation support to 82599 based 10G Base-T, backplane devices and multi-speed fiber optics modules at 1G speed Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82598.c | 7 +- drivers/net/ixgbe/ixgbe_82599.c | 3 + drivers/net/ixgbe/ixgbe_common.c | 460 ++++++++++++++++++++++----------------- drivers/net/ixgbe/ixgbe_main.c | 3 +- drivers/net/ixgbe/ixgbe_phy.h | 4 + drivers/net/ixgbe/ixgbe_type.h | 3 + 6 files changed, 281 insertions(+), 199 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index dc977b1c8eab..ff23907bde0c 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -366,7 +366,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) /* Negotiate the fc mode to use */ ret_val = ixgbe_fc_autoneg(hw); - if (ret_val) + if (ret_val == IXGBE_ERR_FLOW_CONTROL) goto out; /* Disable any previous flow control settings */ @@ -384,10 +384,10 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) * 2: Tx flow control is enabled (we can send pause frames but * we do not support receiving pause frames). * 3: Both Rx and Tx flow control (symmetric) are enabled. - * other: Invalid. #ifdef CONFIG_DCB * 4: Priority Flow Control is enabled. #endif + * other: Invalid. */ switch (hw->fc.current_mode) { case ixgbe_fc_none: @@ -444,9 +444,10 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) reg = (rx_pba_size - hw->fc.low_water) << 6; if (hw->fc.send_xon) reg |= IXGBE_FCRTL_XONE; + IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), reg); - reg = (rx_pba_size - hw->fc.high_water) << 10; + reg = (rx_pba_size - hw->fc.high_water) << 6; reg |= IXGBE_FCRTH_FCEN; IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num), reg); diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 2f8b9f41714f..00aeba385a2f 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -772,6 +772,9 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, /* Check to see if speed passed in is supported. */ hw->mac.ops.get_link_capabilities(hw, &link_capabilities, &autoneg); + if (status != 0) + goto out; + speed &= link_capabilities; if (speed == IXGBE_LINK_SPEED_UNKNOWN) { diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 561f666618e4..7a6a3fbee19f 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -47,6 +47,12 @@ static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); static void ixgbe_release_eeprom(struct ixgbe_hw *hw); static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr); +static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw); +static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw); +static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw); +static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw); +static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, + u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm); static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num); /** @@ -1566,7 +1572,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num) #endif /* CONFIG_DCB */ /* Negotiate the fc mode to use */ ret_val = ixgbe_fc_autoneg(hw); - if (ret_val) + if (ret_val == IXGBE_ERR_FLOW_CONTROL) goto out; /* Disable any previous flow control settings */ @@ -1674,12 +1680,13 @@ out: **/ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw) { - s32 ret_val = 0; + s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; ixgbe_link_speed speed; - u32 pcs_anadv_reg, pcs_lpab_reg, linkstat; - u32 links2, anlp1_reg, autoc_reg, links; bool link_up; + if (hw->fc.disable_fc_autoneg) + goto out; + /* * AN should have completed when the cable was plugged in. * Look for reasons to bail out. Bail out if: @@ -1690,153 +1697,199 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw) * So use link_up_wait_to_complete=false. */ hw->mac.ops.check_link(hw, &speed, &link_up, false); - - if (hw->fc.disable_fc_autoneg || (!link_up)) { - hw->fc.fc_was_autonegged = false; - hw->fc.current_mode = hw->fc.requested_mode; + if (!link_up) { + ret_val = IXGBE_ERR_FLOW_CONTROL; goto out; } - /* - * On backplane, bail out if - * - backplane autoneg was not completed, or if - * - we are 82599 and link partner is not AN enabled - */ - if (hw->phy.media_type == ixgbe_media_type_backplane) { - links = IXGBE_READ_REG(hw, IXGBE_LINKS); - if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) { - hw->fc.fc_was_autonegged = false; - hw->fc.current_mode = hw->fc.requested_mode; - goto out; - } + switch (hw->phy.media_type) { + /* Autoneg flow control on fiber adapters */ + case ixgbe_media_type_fiber: + if (speed == IXGBE_LINK_SPEED_1GB_FULL) + ret_val = ixgbe_fc_autoneg_fiber(hw); + break; - if (hw->mac.type == ixgbe_mac_82599EB) { - links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2); - if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) { - hw->fc.fc_was_autonegged = false; - hw->fc.current_mode = hw->fc.requested_mode; - goto out; - } - } + /* Autoneg flow control on backplane adapters */ + case ixgbe_media_type_backplane: + ret_val = ixgbe_fc_autoneg_backplane(hw); + break; + + /* Autoneg flow control on copper adapters */ + case ixgbe_media_type_copper: + if (ixgbe_device_supports_autoneg_fc(hw) == 0) + ret_val = ixgbe_fc_autoneg_copper(hw); + break; + + default: + break; + } + +out: + if (ret_val == 0) { + hw->fc.fc_was_autonegged = true; + } else { + hw->fc.fc_was_autonegged = false; + hw->fc.current_mode = hw->fc.requested_mode; } + return ret_val; +} + +/** + * ixgbe_fc_autoneg_fiber - Enable flow control on 1 gig fiber + * @hw: pointer to hardware structure + * + * Enable flow control according on 1 gig fiber. + **/ +static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw) +{ + u32 pcs_anadv_reg, pcs_lpab_reg, linkstat; + s32 ret_val; /* * On multispeed fiber at 1g, bail out if * - link is up but AN did not complete, or if * - link is up and AN completed but timed out */ - if (hw->phy.multispeed_fiber && (speed == IXGBE_LINK_SPEED_1GB_FULL)) { - linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); - if (((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) || - ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) { - hw->fc.fc_was_autonegged = false; - hw->fc.current_mode = hw->fc.requested_mode; - goto out; - } + + linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); + if (((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) || + ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) { + ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; + goto out; } + pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); + pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP); + + ret_val = ixgbe_negotiate_fc(hw, pcs_anadv_reg, + pcs_lpab_reg, IXGBE_PCS1GANA_SYM_PAUSE, + IXGBE_PCS1GANA_ASM_PAUSE, + IXGBE_PCS1GANA_SYM_PAUSE, + IXGBE_PCS1GANA_ASM_PAUSE); + +out: + return ret_val; +} + +/** + * ixgbe_fc_autoneg_backplane - Enable flow control IEEE clause 37 + * @hw: pointer to hardware structure + * + * Enable flow control according to IEEE clause 37. + **/ +static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw) +{ + u32 links2, anlp1_reg, autoc_reg, links; + s32 ret_val; + /* - * Bail out on - * - copper or CX4 adapters - * - fiber adapters running at 10gig + * On backplane, bail out if + * - backplane autoneg was not completed, or if + * - we are 82599 and link partner is not AN enabled */ - if ((hw->phy.media_type == ixgbe_media_type_copper) || - (hw->phy.media_type == ixgbe_media_type_cx4) || - ((hw->phy.media_type == ixgbe_media_type_fiber) && - (speed == IXGBE_LINK_SPEED_10GB_FULL))) { + links = IXGBE_READ_REG(hw, IXGBE_LINKS); + if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) { hw->fc.fc_was_autonegged = false; hw->fc.current_mode = hw->fc.requested_mode; + ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; goto out; } + if (hw->mac.type == ixgbe_mac_82599EB) { + links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2); + if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) { + hw->fc.fc_was_autonegged = false; + hw->fc.current_mode = hw->fc.requested_mode; + ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; + goto out; + } + } /* - * Read the AN advertisement and LP ability registers and resolve + * Read the 10g AN autoc and LP ability registers and resolve * local flow control settings accordingly */ - if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && - (hw->phy.media_type != ixgbe_media_type_backplane)) { - pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); - pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP); - if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) && - (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE)) { - /* - * Now we need to check if the user selected Rx ONLY - * of pause frames. In this case, we had to advertise - * FULL flow control because we could not advertise RX - * ONLY. Hence, we must now check to see if we need to - * turn OFF the TRANSMISSION of PAUSE frames. - */ - if (hw->fc.requested_mode == ixgbe_fc_full) { - hw->fc.current_mode = ixgbe_fc_full; - hw_dbg(hw, "Flow Control = FULL.\n"); - } else { - hw->fc.current_mode = ixgbe_fc_rx_pause; - hw_dbg(hw, "Flow Control=RX PAUSE only\n"); - } - } else if (!(pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) && - (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) && - (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) && - (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) { - hw->fc.current_mode = ixgbe_fc_tx_pause; - hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n"); - } else if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) && - (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) && - !(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) && - (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) { - hw->fc.current_mode = ixgbe_fc_rx_pause; - hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n"); - } else { - hw->fc.current_mode = ixgbe_fc_none; - hw_dbg(hw, "Flow Control = NONE.\n"); - } - } + autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); + anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1); - if (hw->phy.media_type == ixgbe_media_type_backplane) { + ret_val = ixgbe_negotiate_fc(hw, autoc_reg, + anlp1_reg, IXGBE_AUTOC_SYM_PAUSE, IXGBE_AUTOC_ASM_PAUSE, + IXGBE_ANLP1_SYM_PAUSE, IXGBE_ANLP1_ASM_PAUSE); + +out: + return ret_val; +} + +/** + * ixgbe_fc_autoneg_copper - Enable flow control IEEE clause 37 + * @hw: pointer to hardware structure + * + * Enable flow control according to IEEE clause 37. + **/ +static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw) +{ + u16 technology_ability_reg = 0; + u16 lp_technology_ability_reg = 0; + + hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE, + MDIO_MMD_AN, + &technology_ability_reg); + hw->phy.ops.read_reg(hw, MDIO_AN_LPA, + MDIO_MMD_AN, + &lp_technology_ability_reg); + + return ixgbe_negotiate_fc(hw, (u32)technology_ability_reg, + (u32)lp_technology_ability_reg, + IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE, + IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE); +} + +/** + * ixgbe_negotiate_fc - Negotiate flow control + * @hw: pointer to hardware structure + * @adv_reg: flow control advertised settings + * @lp_reg: link partner's flow control settings + * @adv_sym: symmetric pause bit in advertisement + * @adv_asm: asymmetric pause bit in advertisement + * @lp_sym: symmetric pause bit in link partner advertisement + * @lp_asm: asymmetric pause bit in link partner advertisement + * + * Find the intersection between advertised settings and link partner's + * advertised settings + **/ +static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, + u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm) +{ + if ((!(adv_reg)) || (!(lp_reg))) + return IXGBE_ERR_FC_NOT_NEGOTIATED; + + if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) { /* - * Read the 10g AN autoc and LP ability registers and resolve - * local flow control settings accordingly + * Now we need to check if the user selected Rx ONLY + * of pause frames. In this case, we had to advertise + * FULL flow control because we could not advertise RX + * ONLY. Hence, we must now check to see if we need to + * turn OFF the TRANSMISSION of PAUSE frames. */ - autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); - anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1); - - if ((autoc_reg & IXGBE_AUTOC_SYM_PAUSE) && - (anlp1_reg & IXGBE_ANLP1_SYM_PAUSE)) { - /* - * Now we need to check if the user selected Rx ONLY - * of pause frames. In this case, we had to advertise - * FULL flow control because we could not advertise RX - * ONLY. Hence, we must now check to see if we need to - * turn OFF the TRANSMISSION of PAUSE frames. - */ - if (hw->fc.requested_mode == ixgbe_fc_full) { - hw->fc.current_mode = ixgbe_fc_full; - hw_dbg(hw, "Flow Control = FULL.\n"); - } else { - hw->fc.current_mode = ixgbe_fc_rx_pause; - hw_dbg(hw, "Flow Control=RX PAUSE only\n"); - } - } else if (!(autoc_reg & IXGBE_AUTOC_SYM_PAUSE) && - (autoc_reg & IXGBE_AUTOC_ASM_PAUSE) && - (anlp1_reg & IXGBE_ANLP1_SYM_PAUSE) && - (anlp1_reg & IXGBE_ANLP1_ASM_PAUSE)) { - hw->fc.current_mode = ixgbe_fc_tx_pause; - hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n"); - } else if ((autoc_reg & IXGBE_AUTOC_SYM_PAUSE) && - (autoc_reg & IXGBE_AUTOC_ASM_PAUSE) && - !(anlp1_reg & IXGBE_ANLP1_SYM_PAUSE) && - (anlp1_reg & IXGBE_ANLP1_ASM_PAUSE)) { - hw->fc.current_mode = ixgbe_fc_rx_pause; - hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n"); + if (hw->fc.requested_mode == ixgbe_fc_full) { + hw->fc.current_mode = ixgbe_fc_full; + hw_dbg(hw, "Flow Control = FULL.\n"); } else { - hw->fc.current_mode = ixgbe_fc_none; - hw_dbg(hw, "Flow Control = NONE.\n"); + hw->fc.current_mode = ixgbe_fc_rx_pause; + hw_dbg(hw, "Flow Control=RX PAUSE frames only\n"); } + } else if (!(adv_reg & adv_sym) && (adv_reg & adv_asm) && + (lp_reg & lp_sym) && (lp_reg & lp_asm)) { + hw->fc.current_mode = ixgbe_fc_tx_pause; + hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n"); + } else if ((adv_reg & adv_sym) && (adv_reg & adv_asm) && + !(lp_reg & lp_sym) && (lp_reg & lp_asm)) { + hw->fc.current_mode = ixgbe_fc_rx_pause; + hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n"); + } else { + hw->fc.current_mode = ixgbe_fc_none; + hw_dbg(hw, "Flow Control = NONE.\n"); } - /* Record that current_mode is the result of a successful autoneg */ - hw->fc.fc_was_autonegged = true; - -out: - return ret_val; + return 0; } /** @@ -1848,7 +1901,8 @@ out: static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) { s32 ret_val = 0; - u32 reg; + u32 reg = 0, reg_bp = 0; + u16 reg_cu = 0; #ifdef CONFIG_DCB if (hw->fc.requested_mode == ixgbe_fc_pfc) { @@ -1856,7 +1910,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) goto out; } -#endif +#endif /* CONFIG_DCB */ /* Validate the packetbuf configuration */ if (packetbuf_num < 0 || packetbuf_num > 7) { hw_dbg(hw, "Invalid packet buffer number [%d], expected range " @@ -1894,11 +1948,26 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) hw->fc.requested_mode = ixgbe_fc_full; /* - * Set up the 1G flow control advertisement registers so the HW will be - * able to do fc autoneg once the cable is plugged in. If we end up - * using 10g instead, this is harmless. + * Set up the 1G and 10G flow control advertisement registers so the + * HW will be able to do fc autoneg once the cable is plugged in. If + * we link at 10G, the 1G advertisement is harmless and vice versa. */ - reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); + + switch (hw->phy.media_type) { + case ixgbe_media_type_fiber: + case ixgbe_media_type_backplane: + reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); + reg_bp = IXGBE_READ_REG(hw, IXGBE_AUTOC); + break; + + case ixgbe_media_type_copper: + hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE, + MDIO_MMD_AN, ®_cu); + break; + + default: + ; + } /* * The possible values of fc.requested_mode are: @@ -1917,6 +1986,11 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) case ixgbe_fc_none: /* Flow control completely disabled by software override. */ reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); + if (hw->phy.media_type == ixgbe_media_type_backplane) + reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE | + IXGBE_AUTOC_ASM_PAUSE); + else if (hw->phy.media_type == ixgbe_media_type_copper) + reg_cu &= ~(IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE); break; case ixgbe_fc_rx_pause: /* @@ -1928,6 +2002,11 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) * disable the adapter's ability to send PAUSE frames. */ reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); + if (hw->phy.media_type == ixgbe_media_type_backplane) + reg_bp |= (IXGBE_AUTOC_SYM_PAUSE | + IXGBE_AUTOC_ASM_PAUSE); + else if (hw->phy.media_type == ixgbe_media_type_copper) + reg_cu |= (IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE); break; case ixgbe_fc_tx_pause: /* @@ -1936,10 +2015,22 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) */ reg |= (IXGBE_PCS1GANA_ASM_PAUSE); reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE); + if (hw->phy.media_type == ixgbe_media_type_backplane) { + reg_bp |= (IXGBE_AUTOC_ASM_PAUSE); + reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE); + } else if (hw->phy.media_type == ixgbe_media_type_copper) { + reg_cu |= (IXGBE_TAF_ASM_PAUSE); + reg_cu &= ~(IXGBE_TAF_SYM_PAUSE); + } break; case ixgbe_fc_full: /* Flow control (both Rx and Tx) is enabled by SW override. */ reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); + if (hw->phy.media_type == ixgbe_media_type_backplane) + reg_bp |= (IXGBE_AUTOC_SYM_PAUSE | + IXGBE_AUTOC_ASM_PAUSE); + else if (hw->phy.media_type == ixgbe_media_type_copper) + reg_cu |= (IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE); break; #ifdef CONFIG_DCB case ixgbe_fc_pfc: @@ -1953,80 +2044,37 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) break; } - IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg); - reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL); - - /* Disable AN timeout */ - if (hw->fc.strict_ieee) - reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN; + if (hw->mac.type != ixgbe_mac_X540) { + /* + * Enable auto-negotiation between the MAC & PHY; + * the MAC will advertise clause 37 flow control. + */ + IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg); + reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL); - IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg); - hw_dbg(hw, "Set up FC; PCS1GLCTL = 0x%08X\n", reg); + /* Disable AN timeout */ + if (hw->fc.strict_ieee) + reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN; - /* - * Set up the 10G flow control advertisement registers so the HW - * can do fc autoneg once the cable is plugged in. If we end up - * using 1g instead, this is harmless. - */ - reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); + IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg); + hw_dbg(hw, "Set up FC; PCS1GLCTL = 0x%08X\n", reg); + } /* - * The possible values of fc.requested_mode are: - * 0: Flow control is completely disabled - * 1: Rx flow control is enabled (we can receive pause frames, - * but not send pause frames). - * 2: Tx flow control is enabled (we can send pause frames but - * we do not support receiving pause frames). - * 3: Both Rx and Tx flow control (symmetric) are enabled. - * other: Invalid. + * AUTOC restart handles negotiation of 1G and 10G on backplane + * and copper. There is no need to set the PCS1GCTL register. + * */ - switch (hw->fc.requested_mode) { - case ixgbe_fc_none: - /* Flow control completely disabled by software override. */ - reg &= ~(IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE); - break; - case ixgbe_fc_rx_pause: - /* - * Rx Flow control is enabled and Tx Flow control is - * disabled by software override. Since there really - * isn't a way to advertise that we are capable of RX - * Pause ONLY, we will advertise that we support both - * symmetric and asymmetric Rx PAUSE. Later, we will - * disable the adapter's ability to send PAUSE frames. - */ - reg |= (IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE); - break; - case ixgbe_fc_tx_pause: - /* - * Tx Flow control is enabled, and Rx Flow control is - * disabled by software override. - */ - reg |= (IXGBE_AUTOC_ASM_PAUSE); - reg &= ~(IXGBE_AUTOC_SYM_PAUSE); - break; - case ixgbe_fc_full: - /* Flow control (both Rx and Tx) is enabled by SW override. */ - reg |= (IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE); - break; -#ifdef CONFIG_DCB - case ixgbe_fc_pfc: - goto out; - break; -#endif /* CONFIG_DCB */ - default: - hw_dbg(hw, "Flow control param set incorrectly\n"); - ret_val = IXGBE_ERR_CONFIG; - goto out; - break; + if (hw->phy.media_type == ixgbe_media_type_backplane) { + reg_bp |= IXGBE_AUTOC_AN_RESTART; + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp); + } else if ((hw->phy.media_type == ixgbe_media_type_copper) && + (ixgbe_device_supports_autoneg_fc(hw) == 0)) { + hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, + MDIO_MMD_AN, reg_cu); } - /* - * AUTOC restart handles negotiation of 1G and 10G. There is - * no need to set the PCS1GCTL register. - */ - reg |= IXGBE_AUTOC_AN_RESTART; - IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg); - hw_dbg(hw, "Set up FC; IXGBE_AUTOC = 0x%08X\n", reg); + hw_dbg(hw, "Set up FC; IXGBE_AUTOC = 0x%08X\n", reg); out: return ret_val; } @@ -2750,6 +2798,28 @@ wwn_prefix_out: return 0; } +/** + * ixgbe_device_supports_autoneg_fc - Check if phy supports autoneg flow + * control + * @hw: pointer to hardware structure + * + * There are several phys that do not support autoneg flow control. This + * function check the device id to see if the associated phy supports + * autoneg flow control. + **/ +static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw) +{ + + switch (hw->device_id) { + case IXGBE_DEV_ID_X540T: + return 0; + case IXGBE_DEV_ID_82599_T3_LOM: + return 0; + default: + return IXGBE_ERR_FC_NOT_SUPPORTED; + } +} + /** * ixgbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing * @hw: pointer to hardware structure diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 5e8c39decca1..5998dc94dd5c 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3775,7 +3775,8 @@ static int ixgbe_non_sfp_link_config(struct ixgbe_hw *hw) if (ret) goto link_cfg_out; - if (hw->mac.ops.get_link_capabilities) + autoneg = hw->phy.autoneg_advertised; + if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) ret = hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation); if (ret) diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h index 2327baf04426..9bf2783d7a74 100644 --- a/drivers/net/ixgbe/ixgbe_phy.h +++ b/drivers/net/ixgbe/ixgbe_phy.h @@ -58,6 +58,10 @@ #define IXGBE_I2C_EEPROM_STATUS_FAIL 0x2 #define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS 0x3 +/* Flow control defines */ +#define IXGBE_TAF_SYM_PAUSE 0x400 +#define IXGBE_TAF_ASM_PAUSE 0x800 + /* Bit-shift macros */ #define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT 24 #define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT 16 diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 76bf21b8a10d..f190a4a8faf4 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -2698,6 +2698,9 @@ struct ixgbe_info { #define IXGBE_ERR_EEPROM_VERSION -24 #define IXGBE_ERR_NO_SPACE -25 #define IXGBE_ERR_OVERTEMP -26 +#define IXGBE_ERR_FC_NOT_NEGOTIATED -27 +#define IXGBE_ERR_FC_NOT_SUPPORTED -28 +#define IXGBE_ERR_FLOW_CONTROL -29 #define IXGBE_ERR_SFP_SETUP_NOT_COMPLETE -30 #define IXGBE_ERR_PBA_SECTION -31 #define IXGBE_ERR_INVALID_ARGUMENT -32 -- cgit v1.2.3 From 77ed18f302a2ef8d7b00ef6e804d23239db12ee1 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Thu, 3 Mar 2011 09:24:56 +0000 Subject: ixgbe: add function description Add description for ixgbe_init_eeprom_params_X540 and whitespace fix. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_x540.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index 2e3a2b4fa8b2..f47e93fe32be 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c @@ -251,8 +251,11 @@ static u32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw) } /** - * ixgbe_init_eeprom_params_X540 - Initialize EEPROM params - * @hw: pointer to hardware structure + * ixgbe_init_eeprom_params_X540 - Initialize EEPROM params + * @hw: pointer to hardware structure + * + * Initializes the EEPROM parameters ixgbe_eeprom_info within the + * ixgbe_hw struct in order to set up EEPROM access. **/ static s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw) { @@ -271,7 +274,7 @@ static s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw) IXGBE_EEPROM_WORD_SIZE_SHIFT); hw_dbg(hw, "Eeprom params: type = %d, size = %d\n", - eeprom->type, eeprom->word_size); + eeprom->type, eeprom->word_size); } return 0; -- cgit v1.2.3 From d7c8a29fc8bd20ba45ec2f52577ed04a988a9500 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Thu, 3 Mar 2011 09:25:02 +0000 Subject: ixgbe: improve logic in ixgbe_init_mbx_params_pf Use if/then instead of an all-inclusive case statement. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_mbx.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_mbx.c b/drivers/net/ixgbe/ixgbe_mbx.c index 2acacfa5e375..3cf8aec50fcd 100644 --- a/drivers/net/ixgbe/ixgbe_mbx.c +++ b/drivers/net/ixgbe/ixgbe_mbx.c @@ -448,23 +448,20 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw) { struct ixgbe_mbx_info *mbx = &hw->mbx; - switch (hw->mac.type) { - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: - mbx->timeout = 0; - mbx->usec_delay = 0; + if (hw->mac.type != ixgbe_mac_82599EB && + hw->mac.type != ixgbe_mac_X540) + return; - mbx->size = IXGBE_VFMAILBOX_SIZE; + mbx->timeout = 0; + mbx->udelay = 0; - mbx->stats.msgs_tx = 0; - mbx->stats.msgs_rx = 0; - mbx->stats.reqs = 0; - mbx->stats.acks = 0; - mbx->stats.rsts = 0; - break; - default: - break; - } + mbx->stats.msgs_tx = 0; + mbx->stats.msgs_rx = 0; + mbx->stats.reqs = 0; + mbx->stats.acks = 0; + mbx->stats.rsts = 0; + + mbx->size = IXGBE_VFMAILBOX_SIZE; } #endif /* CONFIG_PCI_IOV */ -- cgit v1.2.3 From da74cd4a2f64b01c14c4bf7df355a982f1e2ab18 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Thu, 3 Mar 2011 09:25:07 +0000 Subject: ixgbe: fix spelling errors Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 7a6a3fbee19f..bcd952916eb2 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -2162,7 +2162,7 @@ out: * @hw: pointer to hardware structure * @mask: Mask to specify which semaphore to acquire * - * Acquires the SWFW semaphore thought the GSSR register for the specified + * Acquires the SWFW semaphore through the GSSR register for the specified * function (CSR, PHY0, PHY1, EEPROM, Flash) **/ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) @@ -2210,7 +2210,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) * @hw: pointer to hardware structure * @mask: Mask to specify which semaphore to release * - * Releases the SWFW semaphore thought the GSSR register for the specified + * Releases the SWFW semaphore through the GSSR register for the specified * function (CSR, PHY0, PHY1, EEPROM, Flash) **/ void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask) -- cgit v1.2.3 From 2b642ca5e93fa1c977e8c90480a2900149f262be Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Fri, 4 Mar 2011 09:06:10 +0000 Subject: ixgbe: fix setting and reporting of advertised speeds Add the ability to set 100/F on x540. Fix reporting of advertised modes by adding check for phy.autoneg_advertised Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_ethtool.c | 41 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 83511c022926..76380a2b35aa 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -161,29 +161,25 @@ static int ixgbe_get_settings(struct net_device *netdev, } ecmd->advertising = ADVERTISED_Autoneg; - if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) - ecmd->advertising |= ADVERTISED_100baseT_Full; - if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) - ecmd->advertising |= ADVERTISED_10000baseT_Full; - if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) - ecmd->advertising |= ADVERTISED_1000baseT_Full; - /* - * It's possible that phy.autoneg_advertised may not be - * set yet. If so display what the default would be - - * both 1G and 10G supported. - */ - if (!(ecmd->advertising & (ADVERTISED_1000baseT_Full | - ADVERTISED_10000baseT_Full))) + if (hw->phy.autoneg_advertised) { + if (hw->phy.autoneg_advertised & + IXGBE_LINK_SPEED_100_FULL) + ecmd->advertising |= ADVERTISED_100baseT_Full; + if (hw->phy.autoneg_advertised & + IXGBE_LINK_SPEED_10GB_FULL) + ecmd->advertising |= ADVERTISED_10000baseT_Full; + if (hw->phy.autoneg_advertised & + IXGBE_LINK_SPEED_1GB_FULL) + ecmd->advertising |= ADVERTISED_1000baseT_Full; + } else { + /* + * Default advertised modes in case + * phy.autoneg_advertised isn't set. + */ ecmd->advertising |= (ADVERTISED_10000baseT_Full | ADVERTISED_1000baseT_Full); - - switch (hw->mac.type) { - case ixgbe_mac_X540: - if (!(ecmd->advertising & ADVERTISED_100baseT_Full)) - ecmd->advertising |= (ADVERTISED_100baseT_Full); - break; - default: - break; + if (hw->mac.type == ixgbe_mac_X540) + ecmd->advertising |= ADVERTISED_100baseT_Full; } if (hw->phy.media_type == ixgbe_media_type_copper) { @@ -336,6 +332,9 @@ static int ixgbe_set_settings(struct net_device *netdev, if (ecmd->advertising & ADVERTISED_1000baseT_Full) advertised |= IXGBE_LINK_SPEED_1GB_FULL; + if (ecmd->advertising & ADVERTISED_100baseT_Full) + advertised |= IXGBE_LINK_SPEED_100_FULL; + if (old == advertised) return err; /* this sets the link speed and restarts auto-neg */ -- cgit v1.2.3 From 51de69523ffe1c17994dc2f260369f29dfdce71c Mon Sep 17 00:00:00 2001 From: Owen Smith Date: Wed, 22 Dec 2010 15:05:00 +0000 Subject: xen: Union the blkif_request request specific fields Prepare for extending the block device ring to allow request specific fields, by moving the request specific fields for reads, writes and barrier requests to a union member. Acked-by: Jens Axboe Signed-off-by: Owen Smith Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkfront.c | 8 ++++---- include/xen/interface/io/blkif.h | 16 +++++++++++----- 2 files changed, 15 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index d7aa39e349a6..cc4514c9d8a6 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -281,7 +281,7 @@ static int blkif_queue_request(struct request *req) info->shadow[id].request = req; ring_req->id = id; - ring_req->sector_number = (blkif_sector_t)blk_rq_pos(req); + ring_req->u.rw.sector_number = (blkif_sector_t)blk_rq_pos(req); ring_req->handle = info->handle; ring_req->operation = rq_data_dir(req) ? @@ -317,7 +317,7 @@ static int blkif_queue_request(struct request *req) rq_data_dir(req) ); info->shadow[id].frame[i] = mfn_to_pfn(buffer_mfn); - ring_req->seg[i] = + ring_req->u.rw.seg[i] = (struct blkif_request_segment) { .gref = ref, .first_sect = fsect, @@ -615,7 +615,7 @@ static void blkif_completion(struct blk_shadow *s) { int i; for (i = 0; i < s->req.nr_segments; i++) - gnttab_end_foreign_access(s->req.seg[i].gref, 0, 0UL); + gnttab_end_foreign_access(s->req.u.rw.seg[i].gref, 0, 0UL); } static irqreturn_t blkif_interrupt(int irq, void *dev_id) @@ -932,7 +932,7 @@ static int blkif_recover(struct blkfront_info *info) /* Rewrite any grant references invalidated by susp/resume. */ for (j = 0; j < req->nr_segments; j++) gnttab_grant_foreign_access_ref( - req->seg[j].gref, + req->u.rw.seg[j].gref, info->xbdev->otherend_id, pfn_to_mfn(info->shadow[req->id].frame[j]), rq_data_dir(info->shadow[req->id].request)); diff --git a/include/xen/interface/io/blkif.h b/include/xen/interface/io/blkif.h index c2d1fa4dc1ee..e4f743cfa151 100644 --- a/include/xen/interface/io/blkif.h +++ b/include/xen/interface/io/blkif.h @@ -51,11 +51,7 @@ typedef uint64_t blkif_sector_t; */ #define BLKIF_MAX_SEGMENTS_PER_REQUEST 11 -struct blkif_request { - uint8_t operation; /* BLKIF_OP_??? */ - uint8_t nr_segments; /* number of segments */ - blkif_vdev_t handle; /* only for read/write requests */ - uint64_t id; /* private guest value, echoed in resp */ +struct blkif_request_rw { blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ struct blkif_request_segment { grant_ref_t gref; /* reference to I/O buffer frame */ @@ -65,6 +61,16 @@ struct blkif_request { } seg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; }; +struct blkif_request { + uint8_t operation; /* BLKIF_OP_??? */ + uint8_t nr_segments; /* number of segments */ + blkif_vdev_t handle; /* only for read/write requests */ + uint64_t id; /* private guest value, echoed in resp */ + union { + struct blkif_request_rw rw; + } u; +}; + struct blkif_response { uint64_t id; /* copied from request */ uint8_t operation; /* copied from request */ -- cgit v1.2.3 From bad3babace2ee4d1763b4016a662a5c660ab92e9 Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Tue, 8 Mar 2011 23:32:02 +0200 Subject: mmc: fix CONFIG_MMC_UNSAFE_RESUME regression 30201e7f3 ("mmc: skip detection of nonremovable cards on rescan") allowed skipping detection of nonremovable cards on mmc_rescan(). The intention was to only skip detection of hardwired cards that cannot be removed, so make sure this is indeed the case by directly checking for (lack of) MMC_CAP_NONREMOVABLE, instead of using mmc_card_is_removable(), which is overloaded with CONFIG_MMC_UNSAFE_RESUME semantics. The user-visible symptom of the bug this patch fixes is that no "mmc: card XXXX removed" message appears in dmesg when a card is removed and CONFIG_MMC_UNSAFE_RESUME=y. Reported-and-tested-by: Dmitry Shmidt Reported-and-tested-by: Maxim Levitsky Signed-off-by: Ohad Ben-Cohen Signed-off-by: Chris Ball --- drivers/mmc/core/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 6625c057be05..150b5f3cd401 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1529,7 +1529,7 @@ void mmc_rescan(struct work_struct *work) * still present */ if (host->bus_ops && host->bus_ops->detect && !host->bus_dead - && mmc_card_is_removable(host)) + && !(host->caps & MMC_CAP_NONREMOVABLE)) host->bus_ops->detect(host); /* -- cgit v1.2.3 From c60c9c71ade23351d9cd9d1ef96ad007eb4a15ab Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Mon, 7 Mar 2011 00:09:40 +0000 Subject: r6040: fix multicast operations The original code does not work well when the number of mulitcast address to handle is greater than MCAST_MAX. It only enable promiscous mode instead of multicast hash table mode, so the hash table function will not be activated and all multicast frames will be recieved in this condition. This patch fixes the following issues with the r6040 NIC operating in multicast: 1) When the IFF_ALLMULTI flag is set, we should write 0xffff to the NIC hash table registers to make it process multicast traffic. 2) When the number of multicast address to handle is smaller than MCAST_MAX, we should use the NIC multicast registers MID1_{L,M,H}. 3) The hashing of the address was not correct, due to an invalid substraction (15 - (crc & 0x0f)) instead of (crc & 0x0f) and an incorrect crc algorithm (ether_crc_le) instead of (ether_crc). 4) If necessary, we should set HASH_EN flag in MCR0 to enable multicast hash table function. Reported-by: Marc Leclerc Tested-by: Marc Leclerc Signed-off-by: Shawn Lin Signed-off-by: Albert Chen Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/r6040.c | 111 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 27e6f6d43cac..7965ae42eae4 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -69,6 +69,8 @@ /* MAC registers */ #define MCR0 0x00 /* Control register 0 */ +#define MCR0_PROMISC 0x0020 /* Promiscuous mode */ +#define MCR0_HASH_EN 0x0100 /* Enable multicast hash table function */ #define MCR1 0x04 /* Control register 1 */ #define MAC_RST 0x0001 /* Reset the MAC */ #define MBCR 0x08 /* Bus control */ @@ -851,77 +853,92 @@ static void r6040_multicast_list(struct net_device *dev) { struct r6040_private *lp = netdev_priv(dev); void __iomem *ioaddr = lp->base; - u16 *adrp; - u16 reg; unsigned long flags; struct netdev_hw_addr *ha; int i; + u16 *adrp; + u16 hash_table[4] = { 0 }; + + spin_lock_irqsave(&lp->lock, flags); - /* MAC Address */ + /* Keep our MAC Address */ adrp = (u16 *)dev->dev_addr; iowrite16(adrp[0], ioaddr + MID_0L); iowrite16(adrp[1], ioaddr + MID_0M); iowrite16(adrp[2], ioaddr + MID_0H); - /* Promiscous Mode */ - spin_lock_irqsave(&lp->lock, flags); - /* Clear AMCP & PROM bits */ - reg = ioread16(ioaddr) & ~0x0120; - if (dev->flags & IFF_PROMISC) { - reg |= 0x0020; - lp->mcr0 |= 0x0020; - } - /* Too many multicast addresses - * accept all traffic */ - else if ((netdev_mc_count(dev) > MCAST_MAX) || - (dev->flags & IFF_ALLMULTI)) - reg |= 0x0020; + lp->mcr0 = ioread16(ioaddr + MCR0) & ~(MCR0_PROMISC | MCR0_HASH_EN); - iowrite16(reg, ioaddr); - spin_unlock_irqrestore(&lp->lock, flags); + /* Promiscuous mode */ + if (dev->flags & IFF_PROMISC) + lp->mcr0 |= MCR0_PROMISC; - /* Build the hash table */ - if (netdev_mc_count(dev) > MCAST_MAX) { - u16 hash_table[4]; - u32 crc; + /* Enable multicast hash table function to + * receive all multicast packets. */ + else if (dev->flags & IFF_ALLMULTI) { + lp->mcr0 |= MCR0_HASH_EN; - for (i = 0; i < 4; i++) - hash_table[i] = 0; + for (i = 0; i < MCAST_MAX ; i++) { + iowrite16(0, ioaddr + MID_1L + 8 * i); + iowrite16(0, ioaddr + MID_1M + 8 * i); + iowrite16(0, ioaddr + MID_1H + 8 * i); + } + for (i = 0; i < 4; i++) + hash_table[i] = 0xffff; + } + /* Use internal multicast address registers if the number of + * multicast addresses is not greater than MCAST_MAX. */ + else if (netdev_mc_count(dev) <= MCAST_MAX) { + i = 0; netdev_for_each_mc_addr(ha, dev) { - char *addrs = ha->addr; + u16 *adrp = (u16 *) ha->addr; + iowrite16(adrp[0], ioaddr + MID_1L + 8 * i); + iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); + iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); + i++; + } + while (i < MCAST_MAX) { + iowrite16(0, ioaddr + MID_1L + 8 * i); + iowrite16(0, ioaddr + MID_1M + 8 * i); + iowrite16(0, ioaddr + MID_1H + 8 * i); + i++; + } + } + /* Otherwise, Enable multicast hash table function. */ + else { + u32 crc; - if (!(*addrs & 1)) - continue; + lp->mcr0 |= MCR0_HASH_EN; + + for (i = 0; i < MCAST_MAX ; i++) { + iowrite16(0, ioaddr + MID_1L + 8 * i); + iowrite16(0, ioaddr + MID_1M + 8 * i); + iowrite16(0, ioaddr + MID_1H + 8 * i); + } - crc = ether_crc_le(6, addrs); + /* Build multicast hash table */ + netdev_for_each_mc_addr(ha, dev) { + u8 *addrs = ha->addr; + + crc = ether_crc(ETH_ALEN, addrs); crc >>= 26; - hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf)); + hash_table[crc >> 4] |= 1 << (crc & 0xf); } - /* Fill the MAC hash tables with their values */ + } + + iowrite16(lp->mcr0, ioaddr + MCR0); + + /* Fill the MAC hash tables with their values */ + if (lp->mcr0 && MCR0_HASH_EN) { iowrite16(hash_table[0], ioaddr + MAR0); iowrite16(hash_table[1], ioaddr + MAR1); iowrite16(hash_table[2], ioaddr + MAR2); iowrite16(hash_table[3], ioaddr + MAR3); } - /* Multicast Address 1~4 case */ - i = 0; - netdev_for_each_mc_addr(ha, dev) { - if (i >= MCAST_MAX) - break; - adrp = (u16 *) ha->addr; - iowrite16(adrp[0], ioaddr + MID_1L + 8 * i); - iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); - iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); - i++; - } - while (i < MCAST_MAX) { - iowrite16(0xffff, ioaddr + MID_1L + 8 * i); - iowrite16(0xffff, ioaddr + MID_1M + 8 * i); - iowrite16(0xffff, ioaddr + MID_1H + 8 * i); - i++; - } + + spin_unlock_irqrestore(&lp->lock, flags); } static void netdev_get_drvinfo(struct net_device *dev, -- cgit v1.2.3 From 86f99fffffc631b8fa03d07219dc0c67bb65893d Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 7 Mar 2011 00:09:42 +0000 Subject: r6040: bump to version 0.27 and date 23Feb2011 Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/r6040.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 7965ae42eae4..e3ebd90ae651 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -49,8 +49,8 @@ #include #define DRV_NAME "r6040" -#define DRV_VERSION "0.26" -#define DRV_RELDATE "30May2010" +#define DRV_VERSION "0.27" +#define DRV_RELDATE "23Feb2011" /* PHY CHIP Address */ #define PHY1_ADDR 1 /* For MAC1 */ -- cgit v1.2.3 From 5217e8794619ac0a29151f29be20c7d6188303ba Mon Sep 17 00:00:00 2001 From: Andy Gospodarek Date: Tue, 8 Mar 2011 14:26:00 -0800 Subject: ixgbe: fix compile failure in ixgbe_init_mbx_params_pf This commit: commit d7c8a29fc8bd20ba45ec2f52577ed04a988a9500 Author: Emil Tantilov Date: Thu Mar 3 09:25:02 2011 +0000 ixgbe: improve logic in ixgbe_init_mbx_params_pf incorrectly added a line that accessed mbx->udelay. I'm sure the intent was mbx->usec_delay. This patch fixes the compilation error. Signed-off-by: Andy Gospodarek Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_mbx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_mbx.c b/drivers/net/ixgbe/ixgbe_mbx.c index 3cf8aec50fcd..c7ed82eb2539 100644 --- a/drivers/net/ixgbe/ixgbe_mbx.c +++ b/drivers/net/ixgbe/ixgbe_mbx.c @@ -453,7 +453,7 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw) return; mbx->timeout = 0; - mbx->udelay = 0; + mbx->usec_delay = 0; mbx->stats.msgs_tx = 0; mbx->stats.msgs_rx = 0; -- cgit v1.2.3 From 12c383238d675f41e8ecdb8278bfa30c9f2781d4 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 28 Feb 2011 13:52:32 -0700 Subject: i2c-ocores: Fix pointer type mismatch error ocores_i2c_of_probe needs to use a const __be32 type for handing device tree property values. This patch fixed the following build warning: CC drivers/i2c/busses/i2c-ocores.o drivers/i2c/busses/i2c-ocores.c: In function 'ocores_i2c_of_probe': drivers/i2c/busses/i2c-ocores.c:254: warning: assignment discards qualifiers from pointer target type drivers/i2c/busses/i2c-ocores.c:261: warning: assignment discards qualifiers from pointer target type Signed-off-by: Grant Likely Cc: Peter Korsgaard Cc: Ben Dooks Cc: linux-i2c@vger.kernel.org Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-ocores.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index ef3bcb1ce864..61653f079671 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -249,7 +249,7 @@ static struct i2c_adapter ocores_adapter = { static int ocores_i2c_of_probe(struct platform_device* pdev, struct ocores_i2c* i2c) { - __be32* val; + const __be32* val; val = of_get_property(pdev->dev.of_node, "regstep", NULL); if (!val) { -- cgit v1.2.3 From 6dbc2f35ab457770d121d119788fc89c79124734 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 23 Feb 2011 11:11:35 +0100 Subject: i2c-eg20t: include slab.h for memory allocations Fixes (with v2.6.38-rc3/parisc/parisc-allmodconfig): src/drivers/i2c/busses/i2c-eg20t.c:720: error: implicit declaration of function 'kzalloc' src/drivers/i2c/busses/i2c-eg20t.c:790: error: implicit declaration of function 'kfree' Reported-by: Geert Uytterhoeven Signed-off-by: Wolfram Sang Cc: Tomoya MORINAGA Cc: Ben Dooks Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-eg20t.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c index 2e067dd2ee51..50ea1f43bdc1 100644 --- a/drivers/i2c/busses/i2c-eg20t.c +++ b/drivers/i2c/busses/i2c-eg20t.c @@ -29,6 +29,7 @@ #include #include #include +#include #define PCH_EVENT_SET 0 /* I2C Interrupt Event Set Status */ #define PCH_EVENT_NONE 1 /* I2C Interrupt Event Clear Status */ -- cgit v1.2.3 From f44f7f96a20af16f6f12e1c995576d6becf5f57b Mon Sep 17 00:00:00 2001 From: John Stultz Date: Mon, 21 Feb 2011 22:58:51 -0800 Subject: RTC: Initialize kernel state from RTC Mark Brown pointed out a corner case: that RTC alarms should be allowed to be persistent across reboots if the hardware supported it. The rework of the generic layer to virtualize the RTC alarm virtualized much of the alarm handling, and removed the code used to read the alarm time from the hardware. Mark noted if we want the alarm to be persistent across reboots, we need to re-read the alarm value into the virtualized generic layer at boot up, so that the generic layer properly exposes that value. This patch restores much of the earlier removed rtc_read_alarm code and wires it in so that we set the kernel's alarm value to what we find in the hardware at boot time. NOTE: Not all hardware supports persistent RTC alarm state across system reset. rtc-cmos for example will keep the alarm time, but disables the AIE mode irq. Applications should not expect the RTC alarm to be valid after a system reset. We will preserve what we can, to represent the hardware state at boot, but its not guarenteed. Further, in the future, with multiplexed RTC alarms, the soonest alarm to fire may not be the one set via the /dev/rt ioctls. So an application may set the alarm with RTC_ALM_SET, but after a reset find that RTC_ALM_READ returns an earlier time. Again, we preserve what we can, but applications should not expect the RTC alarm state to persist across a system reset. Big thanks to Mark for pointing out the issue! Thanks also to Marcelo for helping think through the solution. CC: Mark Brown CC: Marcelo Roberto Jimenez CC: Thomas Gleixner CC: Alessandro Zummo CC: rtc-linux@googlegroups.com Reported-by: Mark Brown Signed-off-by: John Stultz --- drivers/rtc/class.c | 7 ++ drivers/rtc/interface.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/rtc.h | 1 + 3 files changed, 188 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index c404b61386bf..09b4437b3e61 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -117,6 +117,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, struct module *owner) { struct rtc_device *rtc; + struct rtc_wkalrm alrm; int id, err; if (idr_pre_get(&rtc_idr, GFP_KERNEL) == 0) { @@ -166,6 +167,12 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, rtc->pie_timer.function = rtc_pie_update_irq; rtc->pie_enabled = 0; + /* Check to see if there is an ALARM already set in hw */ + err = __rtc_read_alarm(rtc, &alrm); + + if (!err && !rtc_valid_tm(&alrm.time)) + rtc_set_alarm(rtc, &alrm); + strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); dev_set_name(&rtc->dev, "rtc%d", id); diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index cb2f0728fd70..8ec6b069a7f5 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -116,6 +116,186 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs) } EXPORT_SYMBOL_GPL(rtc_set_mmss); +static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *alarm) +{ + int err; + + err = mutex_lock_interruptible(&rtc->ops_lock); + if (err) + return err; + + if (rtc->ops == NULL) + err = -ENODEV; + else if (!rtc->ops->read_alarm) + err = -EINVAL; + else { + memset(alarm, 0, sizeof(struct rtc_wkalrm)); + err = rtc->ops->read_alarm(rtc->dev.parent, alarm); + } + + mutex_unlock(&rtc->ops_lock); + return err; +} + +int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) +{ + int err; + struct rtc_time before, now; + int first_time = 1; + unsigned long t_now, t_alm; + enum { none, day, month, year } missing = none; + unsigned days; + + /* The lower level RTC driver may return -1 in some fields, + * creating invalid alarm->time values, for reasons like: + * + * - The hardware may not be capable of filling them in; + * many alarms match only on time-of-day fields, not + * day/month/year calendar data. + * + * - Some hardware uses illegal values as "wildcard" match + * values, which non-Linux firmware (like a BIOS) may try + * to set up as e.g. "alarm 15 minutes after each hour". + * Linux uses only oneshot alarms. + * + * When we see that here, we deal with it by using values from + * a current RTC timestamp for any missing (-1) values. The + * RTC driver prevents "periodic alarm" modes. + * + * But this can be racey, because some fields of the RTC timestamp + * may have wrapped in the interval since we read the RTC alarm, + * which would lead to us inserting inconsistent values in place + * of the -1 fields. + * + * Reading the alarm and timestamp in the reverse sequence + * would have the same race condition, and not solve the issue. + * + * So, we must first read the RTC timestamp, + * then read the RTC alarm value, + * and then read a second RTC timestamp. + * + * If any fields of the second timestamp have changed + * when compared with the first timestamp, then we know + * our timestamp may be inconsistent with that used by + * the low-level rtc_read_alarm_internal() function. + * + * So, when the two timestamps disagree, we just loop and do + * the process again to get a fully consistent set of values. + * + * This could all instead be done in the lower level driver, + * but since more than one lower level RTC implementation needs it, + * then it's probably best best to do it here instead of there.. + */ + + /* Get the "before" timestamp */ + err = rtc_read_time(rtc, &before); + if (err < 0) + return err; + do { + if (!first_time) + memcpy(&before, &now, sizeof(struct rtc_time)); + first_time = 0; + + /* get the RTC alarm values, which may be incomplete */ + err = rtc_read_alarm_internal(rtc, alarm); + if (err) + return err; + + /* full-function RTCs won't have such missing fields */ + if (rtc_valid_tm(&alarm->time) == 0) + return 0; + + /* get the "after" timestamp, to detect wrapped fields */ + err = rtc_read_time(rtc, &now); + if (err < 0) + return err; + + /* note that tm_sec is a "don't care" value here: */ + } while ( before.tm_min != now.tm_min + || before.tm_hour != now.tm_hour + || before.tm_mon != now.tm_mon + || before.tm_year != now.tm_year); + + /* Fill in the missing alarm fields using the timestamp; we + * know there's at least one since alarm->time is invalid. + */ + if (alarm->time.tm_sec == -1) + alarm->time.tm_sec = now.tm_sec; + if (alarm->time.tm_min == -1) + alarm->time.tm_min = now.tm_min; + if (alarm->time.tm_hour == -1) + alarm->time.tm_hour = now.tm_hour; + + /* For simplicity, only support date rollover for now */ + if (alarm->time.tm_mday == -1) { + alarm->time.tm_mday = now.tm_mday; + missing = day; + } + if (alarm->time.tm_mon == -1) { + alarm->time.tm_mon = now.tm_mon; + if (missing == none) + missing = month; + } + if (alarm->time.tm_year == -1) { + alarm->time.tm_year = now.tm_year; + if (missing == none) + missing = year; + } + + /* with luck, no rollover is needed */ + rtc_tm_to_time(&now, &t_now); + rtc_tm_to_time(&alarm->time, &t_alm); + if (t_now < t_alm) + goto done; + + switch (missing) { + + /* 24 hour rollover ... if it's now 10am Monday, an alarm that + * that will trigger at 5am will do so at 5am Tuesday, which + * could also be in the next month or year. This is a common + * case, especially for PCs. + */ + case day: + dev_dbg(&rtc->dev, "alarm rollover: %s\n", "day"); + t_alm += 24 * 60 * 60; + rtc_time_to_tm(t_alm, &alarm->time); + break; + + /* Month rollover ... if it's the 31th, an alarm on the 3rd will + * be next month. An alarm matching on the 30th, 29th, or 28th + * may end up in the month after that! Many newer PCs support + * this type of alarm. + */ + case month: + dev_dbg(&rtc->dev, "alarm rollover: %s\n", "month"); + do { + if (alarm->time.tm_mon < 11) + alarm->time.tm_mon++; + else { + alarm->time.tm_mon = 0; + alarm->time.tm_year++; + } + days = rtc_month_days(alarm->time.tm_mon, + alarm->time.tm_year); + } while (days < alarm->time.tm_mday); + break; + + /* Year rollover ... easy except for leap years! */ + case year: + dev_dbg(&rtc->dev, "alarm rollover: %s\n", "year"); + do { + alarm->time.tm_year++; + } while (rtc_valid_tm(&alarm->time) != 0); + break; + + default: + dev_warn(&rtc->dev, "alarm rollover not handled\n"); + } + +done: + return 0; +} + int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) { int err; diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 89c3e5182991..db3832d5f280 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -227,6 +227,7 @@ extern void rtc_device_unregister(struct rtc_device *rtc); extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm); extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm); extern int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs); +int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm); extern int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alrm); extern int rtc_set_alarm(struct rtc_device *rtc, -- cgit v1.2.3 From 80d4bb515b78f38738f3378fd1be6039063ab040 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 3 Feb 2011 11:34:50 -0800 Subject: RTC: Cleanup rtc_class_ops->irq_set_state With PIE mode interrupts now emulated in generic code via an hrtimer, no one calls rtc_class_ops->irq_set_state(), so this patch removes it along with driver implementations. CC: Thomas Gleixner CC: Alessandro Zummo CC: Marcelo Roberto Jimenez CC: rtc-linux@googlegroups.com Signed-off-by: John Stultz --- drivers/rtc/rtc-cmos.c | 20 -------------------- drivers/rtc/rtc-davinci.c | 34 ---------------------------------- drivers/rtc/rtc-mrst.c | 20 -------------------- drivers/rtc/rtc-pl031.c | 34 ---------------------------------- drivers/rtc/rtc-pxa.c | 13 ------------- drivers/rtc/rtc-rx8025.c | 25 ------------------------- drivers/rtc/rtc-s3c.c | 32 -------------------------------- drivers/rtc/rtc-sa1100.c | 18 ------------------ drivers/rtc/rtc-sh.c | 1 - drivers/rtc/rtc-vr41xx.c | 11 ----------- include/linux/rtc.h | 1 - 11 files changed, 209 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index c7ff8df347e7..de632e793d46 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -400,25 +400,6 @@ static int cmos_irq_set_freq(struct device *dev, int freq) return 0; } -static int cmos_irq_set_state(struct device *dev, int enabled) -{ - struct cmos_rtc *cmos = dev_get_drvdata(dev); - unsigned long flags; - - if (!is_valid_irq(cmos->irq)) - return -ENXIO; - - spin_lock_irqsave(&rtc_lock, flags); - - if (enabled) - cmos_irq_enable(cmos, RTC_PIE); - else - cmos_irq_disable(cmos, RTC_PIE); - - spin_unlock_irqrestore(&rtc_lock, flags); - return 0; -} - static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct cmos_rtc *cmos = dev_get_drvdata(dev); @@ -502,7 +483,6 @@ static const struct rtc_class_ops cmos_rtc_ops = { .set_alarm = cmos_set_alarm, .proc = cmos_procfs, .irq_set_freq = cmos_irq_set_freq, - .irq_set_state = cmos_irq_set_state, .alarm_irq_enable = cmos_alarm_irq_enable, .update_irq_enable = cmos_update_irq_enable, }; diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index 34647fc1ee98..92da73d40e13 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c @@ -473,39 +473,6 @@ static int davinci_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) return 0; } -static int davinci_rtc_irq_set_state(struct device *dev, int enabled) -{ - struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev); - unsigned long flags; - u8 rtc_ctrl; - - spin_lock_irqsave(&davinci_rtc_lock, flags); - - rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL); - - if (enabled) { - while (rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL) - & PRTCSS_RTC_CTRL_WDTBUS) - cpu_relax(); - - rtc_ctrl |= PRTCSS_RTC_CTRL_TE; - rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL); - - rtcss_write(davinci_rtc, 0x0, PRTCSS_RTC_CLKC_CNT); - - rtc_ctrl |= PRTCSS_RTC_CTRL_TIEN | - PRTCSS_RTC_CTRL_TMMD | - PRTCSS_RTC_CTRL_TMRFLG; - } else - rtc_ctrl &= ~PRTCSS_RTC_CTRL_TIEN; - - rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL); - - spin_unlock_irqrestore(&davinci_rtc_lock, flags); - - return 0; -} - static int davinci_rtc_irq_set_freq(struct device *dev, int freq) { struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev); @@ -529,7 +496,6 @@ static struct rtc_class_ops davinci_rtc_ops = { .alarm_irq_enable = davinci_rtc_alarm_irq_enable, .read_alarm = davinci_rtc_read_alarm, .set_alarm = davinci_rtc_set_alarm, - .irq_set_state = davinci_rtc_irq_set_state, .irq_set_freq = davinci_rtc_irq_set_freq, }; diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c index 1db62db8469d..4db96fa306fc 100644 --- a/drivers/rtc/rtc-mrst.c +++ b/drivers/rtc/rtc-mrst.c @@ -236,25 +236,6 @@ static int mrst_set_alarm(struct device *dev, struct rtc_wkalrm *t) return 0; } -static int mrst_irq_set_state(struct device *dev, int enabled) -{ - struct mrst_rtc *mrst = dev_get_drvdata(dev); - unsigned long flags; - - if (!mrst->irq) - return -ENXIO; - - spin_lock_irqsave(&rtc_lock, flags); - - if (enabled) - mrst_irq_enable(mrst, RTC_PIE); - else - mrst_irq_disable(mrst, RTC_PIE); - - spin_unlock_irqrestore(&rtc_lock, flags); - return 0; -} - /* Currently, the vRTC doesn't support UIE ON/OFF */ static int mrst_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { @@ -301,7 +282,6 @@ static const struct rtc_class_ops mrst_rtc_ops = { .read_alarm = mrst_read_alarm, .set_alarm = mrst_set_alarm, .proc = mrst_procfs, - .irq_set_state = mrst_irq_set_state, .alarm_irq_enable = mrst_rtc_alarm_irq_enable, }; diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index b7a6690e5b35..0e7c15b24c1c 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c @@ -293,38 +293,6 @@ static int pl031_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) return ret; } -/* Periodic interrupt is only available in ST variants. */ -static int pl031_irq_set_state(struct device *dev, int enabled) -{ - struct pl031_local *ldata = dev_get_drvdata(dev); - - if (enabled == 1) { - /* Clear any pending timer interrupt. */ - writel(RTC_BIT_PI, ldata->base + RTC_ICR); - - writel(readl(ldata->base + RTC_IMSC) | RTC_BIT_PI, - ldata->base + RTC_IMSC); - - /* Now start the timer */ - writel(readl(ldata->base + RTC_TCR) | RTC_TCR_EN, - ldata->base + RTC_TCR); - - } else { - writel(readl(ldata->base + RTC_IMSC) & (~RTC_BIT_PI), - ldata->base + RTC_IMSC); - - /* Also stop the timer */ - writel(readl(ldata->base + RTC_TCR) & (~RTC_TCR_EN), - ldata->base + RTC_TCR); - } - /* Wait at least 1 RTC32 clock cycle to ensure next access - * to RTC_TCR will succeed. - */ - udelay(40); - - return 0; -} - static int pl031_irq_set_freq(struct device *dev, int freq) { struct pl031_local *ldata = dev_get_drvdata(dev); @@ -440,7 +408,6 @@ static struct rtc_class_ops stv1_pl031_ops = { .read_alarm = pl031_read_alarm, .set_alarm = pl031_set_alarm, .alarm_irq_enable = pl031_alarm_irq_enable, - .irq_set_state = pl031_irq_set_state, .irq_set_freq = pl031_irq_set_freq, }; @@ -451,7 +418,6 @@ static struct rtc_class_ops stv2_pl031_ops = { .read_alarm = pl031_stv2_read_alarm, .set_alarm = pl031_stv2_set_alarm, .alarm_irq_enable = pl031_alarm_irq_enable, - .irq_set_state = pl031_irq_set_state, .irq_set_freq = pl031_irq_set_freq, }; diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c index 29e867a1aaa8..b216ae5389c8 100644 --- a/drivers/rtc/rtc-pxa.c +++ b/drivers/rtc/rtc-pxa.c @@ -223,18 +223,6 @@ static int pxa_periodic_irq_set_freq(struct device *dev, int freq) return 0; } -static int pxa_periodic_irq_set_state(struct device *dev, int enabled) -{ - struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); - - if (enabled) - rtsr_set_bits(pxa_rtc, RTSR_PIALE | RTSR_PICE); - else - rtsr_clear_bits(pxa_rtc, RTSR_PIALE | RTSR_PICE); - - return 0; -} - static int pxa_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); @@ -348,7 +336,6 @@ static const struct rtc_class_ops pxa_rtc_ops = { .alarm_irq_enable = pxa_alarm_irq_enable, .update_irq_enable = pxa_update_irq_enable, .proc = pxa_rtc_proc, - .irq_set_state = pxa_periodic_irq_set_state, .irq_set_freq = pxa_periodic_irq_set_freq, }; diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index af32a62e12a8..fde172fb2abe 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c @@ -424,37 +424,12 @@ static int rx8025_alarm_irq_enable(struct device *dev, unsigned int enabled) return 0; } -static int rx8025_irq_set_state(struct device *dev, int enabled) -{ - struct i2c_client *client = to_i2c_client(dev); - struct rx8025_data *rx8025 = i2c_get_clientdata(client); - int ctrl1; - int err; - - if (client->irq <= 0) - return -ENXIO; - - ctrl1 = rx8025->ctrl1 & ~RX8025_BIT_CTRL1_CT; - if (enabled) - ctrl1 |= RX8025_BIT_CTRL1_CT_1HZ; - if (ctrl1 != rx8025->ctrl1) { - rx8025->ctrl1 = ctrl1; - err = rx8025_write_reg(rx8025->client, RX8025_REG_CTRL1, - rx8025->ctrl1); - if (err) - return err; - } - - return 0; -} - static struct rtc_class_ops rx8025_rtc_ops = { .read_time = rx8025_get_time, .set_time = rx8025_set_time, .read_alarm = rx8025_read_alarm, .set_alarm = rx8025_set_alarm, .alarm_irq_enable = rx8025_alarm_irq_enable, - .irq_set_state = rx8025_irq_set_state, }; /* diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index b80fa2882408..80fb7e72f9d9 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -93,37 +93,6 @@ static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) return 0; } -static int s3c_rtc_setpie(struct device *dev, int enabled) -{ - unsigned int tmp; - - pr_debug("%s: pie=%d\n", __func__, enabled); - - spin_lock_irq(&s3c_rtc_pie_lock); - - if (s3c_rtc_cpu_type == TYPE_S3C64XX) { - tmp = readw(s3c_rtc_base + S3C2410_RTCCON); - tmp &= ~S3C64XX_RTCCON_TICEN; - - if (enabled) - tmp |= S3C64XX_RTCCON_TICEN; - - writew(tmp, s3c_rtc_base + S3C2410_RTCCON); - } else { - tmp = readb(s3c_rtc_base + S3C2410_TICNT); - tmp &= ~S3C2410_TICNT_ENABLE; - - if (enabled) - tmp |= S3C2410_TICNT_ENABLE; - - writeb(tmp, s3c_rtc_base + S3C2410_TICNT); - } - - spin_unlock_irq(&s3c_rtc_pie_lock); - - return 0; -} - static int s3c_rtc_setfreq(struct device *dev, int freq) { struct platform_device *pdev = to_platform_device(dev); @@ -380,7 +349,6 @@ static const struct rtc_class_ops s3c_rtcops = { .read_alarm = s3c_rtc_getalarm, .set_alarm = s3c_rtc_setalarm, .irq_set_freq = s3c_rtc_setfreq, - .irq_set_state = s3c_rtc_setpie, .proc = s3c_rtc_proc, .alarm_irq_enable = s3c_rtc_setaie, }; diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 5dfe5ffcb0d3..d47b3fc9830f 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c @@ -171,23 +171,6 @@ static int sa1100_irq_set_freq(struct device *dev, int freq) static int rtc_timer1_count; -static int sa1100_irq_set_state(struct device *dev, int enabled) -{ - spin_lock_irq(&sa1100_rtc_lock); - if (enabled) { - struct rtc_device *rtc = (struct rtc_device *)dev; - - OSMR1 = timer_freq / rtc->irq_freq + OSCR; - OIER |= OIER_E1; - rtc_timer1_count = 1; - } else { - OIER &= ~OIER_E1; - } - spin_unlock_irq(&sa1100_rtc_lock); - - return 0; -} - static inline int sa1100_timer1_retrigger(struct rtc_device *rtc) { unsigned long diff; @@ -410,7 +393,6 @@ static const struct rtc_class_ops sa1100_rtc_ops = { .set_alarm = sa1100_rtc_set_alarm, .proc = sa1100_rtc_proc, .irq_set_freq = sa1100_irq_set_freq, - .irq_set_state = sa1100_irq_set_state, .alarm_irq_enable = sa1100_rtc_alarm_irq_enable, }; diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 93314a9e7fa9..ff50a8bc13f6 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -603,7 +603,6 @@ static struct rtc_class_ops sh_rtc_ops = { .set_time = sh_rtc_set_time, .read_alarm = sh_rtc_read_alarm, .set_alarm = sh_rtc_set_alarm, - .irq_set_state = sh_rtc_irq_set_state, .irq_set_freq = sh_rtc_irq_set_freq, .proc = sh_rtc_proc, .alarm_irq_enable = sh_rtc_alarm_irq_enable, diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index 769190ac6d11..86f14909f9db 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c @@ -227,16 +227,6 @@ static int vr41xx_rtc_irq_set_freq(struct device *dev, int freq) return 0; } -static int vr41xx_rtc_irq_set_state(struct device *dev, int enabled) -{ - if (enabled) - enable_irq(pie_irq); - else - disable_irq(pie_irq); - - return 0; -} - static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { switch (cmd) { @@ -309,7 +299,6 @@ static const struct rtc_class_ops vr41xx_rtc_ops = { .read_alarm = vr41xx_rtc_read_alarm, .set_alarm = vr41xx_rtc_set_alarm, .irq_set_freq = vr41xx_rtc_irq_set_freq, - .irq_set_state = vr41xx_rtc_irq_set_state, }; static int __devinit rtc_probe(struct platform_device *pdev) diff --git a/include/linux/rtc.h b/include/linux/rtc.h index db3832d5f280..0e2063acc260 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -148,7 +148,6 @@ struct rtc_class_ops { int (*set_alarm)(struct device *, struct rtc_wkalrm *); int (*proc)(struct device *, struct seq_file *); int (*set_mmss)(struct device *, unsigned long secs); - int (*irq_set_state)(struct device *, int enabled); int (*irq_set_freq)(struct device *, int freq); int (*read_callback)(struct device *, int data); int (*alarm_irq_enable)(struct device *, unsigned int enabled); -- cgit v1.2.3 From 696160fec162601d06940862b5b3aa4460344c1b Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 3 Feb 2011 12:02:07 -0800 Subject: RTC: Cleanup rtc_class_ops->irq_set_freq() With the generic rtc code now emulating PIE mode irqs via an hrtimer, no one calls the rtc_class_ops->irq_set_freq call. This patch removes the hook and deletes the driver functions if no one else calls them. CC: Thomas Gleixner CC: Alessandro Zummo CC: Marcelo Roberto Jimenez CC: rtc-linux@googlegroups.com Signed-off-by: John Stultz --- drivers/rtc/rtc-cmos.c | 26 -------------------------- drivers/rtc/rtc-davinci.c | 17 ----------------- drivers/rtc/rtc-pl031.c | 21 --------------------- drivers/rtc/rtc-pxa.c | 15 --------------- drivers/rtc/rtc-s3c.c | 1 - drivers/rtc/rtc-sa1100.c | 1 - drivers/rtc/rtc-sh.c | 1 - drivers/rtc/rtc-vr41xx.c | 21 --------------------- include/linux/rtc.h | 2 -- 9 files changed, 105 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index de632e793d46..bdb1f8e2042a 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -375,31 +375,6 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) return 0; } -static int cmos_irq_set_freq(struct device *dev, int freq) -{ - struct cmos_rtc *cmos = dev_get_drvdata(dev); - int f; - unsigned long flags; - - if (!is_valid_irq(cmos->irq)) - return -ENXIO; - - if (!is_power_of_2(freq)) - return -EINVAL; - /* 0 = no irqs; 1 = 2^15 Hz ... 15 = 2^0 Hz */ - f = ffs(freq); - if (f-- > 16) - return -EINVAL; - f = 16 - f; - - spin_lock_irqsave(&rtc_lock, flags); - hpet_set_periodic_freq(freq); - CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT); - spin_unlock_irqrestore(&rtc_lock, flags); - - return 0; -} - static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct cmos_rtc *cmos = dev_get_drvdata(dev); @@ -482,7 +457,6 @@ static const struct rtc_class_ops cmos_rtc_ops = { .read_alarm = cmos_read_alarm, .set_alarm = cmos_set_alarm, .proc = cmos_procfs, - .irq_set_freq = cmos_irq_set_freq, .alarm_irq_enable = cmos_alarm_irq_enable, .update_irq_enable = cmos_update_irq_enable, }; diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index 92da73d40e13..dfd98a235ad1 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c @@ -473,22 +473,6 @@ static int davinci_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) return 0; } -static int davinci_rtc_irq_set_freq(struct device *dev, int freq) -{ - struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev); - unsigned long flags; - u16 tmr_counter = (0x8000 >> (ffs(freq) - 1)); - - spin_lock_irqsave(&davinci_rtc_lock, flags); - - rtcss_write(davinci_rtc, tmr_counter & 0xFF, PRTCSS_RTC_TMR0); - rtcss_write(davinci_rtc, (tmr_counter & 0xFF00) >> 8, PRTCSS_RTC_TMR1); - - spin_unlock_irqrestore(&davinci_rtc_lock, flags); - - return 0; -} - static struct rtc_class_ops davinci_rtc_ops = { .ioctl = davinci_rtc_ioctl, .read_time = davinci_rtc_read_time, @@ -496,7 +480,6 @@ static struct rtc_class_ops davinci_rtc_ops = { .alarm_irq_enable = davinci_rtc_alarm_irq_enable, .read_alarm = davinci_rtc_read_alarm, .set_alarm = davinci_rtc_set_alarm, - .irq_set_freq = davinci_rtc_irq_set_freq, }; static int __init davinci_rtc_probe(struct platform_device *pdev) diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 0e7c15b24c1c..d829ea63c4fb 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c @@ -293,25 +293,6 @@ static int pl031_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) return ret; } -static int pl031_irq_set_freq(struct device *dev, int freq) -{ - struct pl031_local *ldata = dev_get_drvdata(dev); - - /* Cant set timer if it is already enabled */ - if (readl(ldata->base + RTC_TCR) & RTC_TCR_EN) { - dev_err(dev, "can't change frequency while timer enabled\n"); - return -EINVAL; - } - - /* If self start bit in RTC_TCR is set timer will start here, - * but we never set that bit. Instead we start the timer when - * set_state is called with enabled == 1. - */ - writel(RTC_TIMER_FREQ / freq, ldata->base + RTC_TLR); - - return 0; -} - static int pl031_remove(struct amba_device *adev) { struct pl031_local *ldata = dev_get_drvdata(&adev->dev); @@ -408,7 +389,6 @@ static struct rtc_class_ops stv1_pl031_ops = { .read_alarm = pl031_read_alarm, .set_alarm = pl031_set_alarm, .alarm_irq_enable = pl031_alarm_irq_enable, - .irq_set_freq = pl031_irq_set_freq, }; /* And the second ST derivative */ @@ -418,7 +398,6 @@ static struct rtc_class_ops stv2_pl031_ops = { .read_alarm = pl031_stv2_read_alarm, .set_alarm = pl031_stv2_set_alarm, .alarm_irq_enable = pl031_alarm_irq_enable, - .irq_set_freq = pl031_irq_set_freq, }; static struct amba_id pl031_ids[] = { diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c index b216ae5389c8..a1fdc802598a 100644 --- a/drivers/rtc/rtc-pxa.c +++ b/drivers/rtc/rtc-pxa.c @@ -209,20 +209,6 @@ static void pxa_rtc_release(struct device *dev) free_irq(pxa_rtc->irq_1Hz, dev); } -static int pxa_periodic_irq_set_freq(struct device *dev, int freq) -{ - struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); - int period_ms; - - if (freq < 1 || freq > MAXFREQ_PERIODIC) - return -EINVAL; - - period_ms = 1000 / freq; - rtc_writel(pxa_rtc, PIAR, period_ms); - - return 0; -} - static int pxa_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); @@ -336,7 +322,6 @@ static const struct rtc_class_ops pxa_rtc_ops = { .alarm_irq_enable = pxa_alarm_irq_enable, .update_irq_enable = pxa_update_irq_enable, .proc = pxa_rtc_proc, - .irq_set_freq = pxa_periodic_irq_set_freq, }; static int __init pxa_rtc_probe(struct platform_device *pdev) diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 80fb7e72f9d9..714964913e5e 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -348,7 +348,6 @@ static const struct rtc_class_ops s3c_rtcops = { .set_time = s3c_rtc_settime, .read_alarm = s3c_rtc_getalarm, .set_alarm = s3c_rtc_setalarm, - .irq_set_freq = s3c_rtc_setfreq, .proc = s3c_rtc_proc, .alarm_irq_enable = s3c_rtc_setaie, }; diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index d47b3fc9830f..d1a2b0bc3b24 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c @@ -392,7 +392,6 @@ static const struct rtc_class_ops sa1100_rtc_ops = { .read_alarm = sa1100_rtc_read_alarm, .set_alarm = sa1100_rtc_set_alarm, .proc = sa1100_rtc_proc, - .irq_set_freq = sa1100_irq_set_freq, .alarm_irq_enable = sa1100_rtc_alarm_irq_enable, }; diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index ff50a8bc13f6..148544979a54 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -603,7 +603,6 @@ static struct rtc_class_ops sh_rtc_ops = { .set_time = sh_rtc_set_time, .read_alarm = sh_rtc_read_alarm, .set_alarm = sh_rtc_set_alarm, - .irq_set_freq = sh_rtc_irq_set_freq, .proc = sh_rtc_proc, .alarm_irq_enable = sh_rtc_alarm_irq_enable, }; diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index 86f14909f9db..c5698cda366a 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c @@ -207,26 +207,6 @@ static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) return 0; } -static int vr41xx_rtc_irq_set_freq(struct device *dev, int freq) -{ - u64 count; - - if (!is_power_of_2(freq)) - return -EINVAL; - count = RTC_FREQUENCY; - do_div(count, freq); - - spin_lock_irq(&rtc_lock); - - periodic_count = count; - rtc1_write(RTCL1LREG, periodic_count); - rtc1_write(RTCL1HREG, periodic_count >> 16); - - spin_unlock_irq(&rtc_lock); - - return 0; -} - static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { switch (cmd) { @@ -298,7 +278,6 @@ static const struct rtc_class_ops vr41xx_rtc_ops = { .set_time = vr41xx_rtc_set_time, .read_alarm = vr41xx_rtc_read_alarm, .set_alarm = vr41xx_rtc_set_alarm, - .irq_set_freq = vr41xx_rtc_irq_set_freq, }; static int __devinit rtc_probe(struct platform_device *pdev) diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 0e2063acc260..741a51cc4460 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -133,7 +133,6 @@ extern struct class *rtc_class; * The (current) exceptions are mostly filesystem hooks: * - the proc() hook for procfs * - non-ioctl() chardev hooks: open(), release(), read_callback() - * - periodic irq calls: irq_set_state(), irq_set_freq() * * REVISIT those periodic irq calls *do* have ops_lock when they're * issued through ioctl() ... @@ -148,7 +147,6 @@ struct rtc_class_ops { int (*set_alarm)(struct device *, struct rtc_wkalrm *); int (*proc)(struct device *, struct seq_file *); int (*set_mmss)(struct device *, unsigned long secs); - int (*irq_set_freq)(struct device *, int freq); int (*read_callback)(struct device *, int data); int (*alarm_irq_enable)(struct device *, unsigned int enabled); int (*update_irq_enable)(struct device *, unsigned int enabled); -- cgit v1.2.3 From 51ba60c5bb3b0f71bee26404ddc22d8e4109e88a Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 3 Feb 2011 12:13:50 -0800 Subject: RTC: Cleanup rtc_class_ops->update_irq_enable() Now that the generic code handles UIE mode irqs via periodic alarm interrupts, no one calls the rtc_class_ops->update_irq_enable() method anymore. This patch removes the driver hooks and implementations of update_irq_enable if no one else is calling it. CC: Thomas Gleixner CC: Alessandro Zummo CC: Marcelo Roberto Jimenez CC: rtc-linux@googlegroups.com Signed-off-by: John Stultz --- drivers/rtc/rtc-cmos.c | 20 -------------------- drivers/rtc/rtc-ds1511.c | 17 ----------------- drivers/rtc/rtc-ds1553.c | 17 ----------------- drivers/rtc/rtc-ds3232.c | 18 ------------------ drivers/rtc/rtc-jz4740.c | 7 ------- drivers/rtc/rtc-mc13xxx.c | 7 ------- drivers/rtc/rtc-mpc5121.c | 20 -------------------- drivers/rtc/rtc-mxc.c | 7 ------- drivers/rtc/rtc-nuc900.c | 15 --------------- drivers/rtc/rtc-pcap.c | 6 ------ drivers/rtc/rtc-pcf50633.c | 22 +--------------------- drivers/rtc/rtc-pxa.c | 16 ---------------- drivers/rtc/rtc-stmp3xxx.c | 15 --------------- drivers/rtc/rtc-twl.c | 13 ------------- drivers/rtc/rtc-wm831x.c | 16 ---------------- drivers/rtc/rtc-wm8350.c | 21 --------------------- include/linux/rtc.h | 1 - 17 files changed, 1 insertion(+), 237 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index bdb1f8e2042a..dc2a0ba969ce 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -394,25 +394,6 @@ static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled) return 0; } -static int cmos_update_irq_enable(struct device *dev, unsigned int enabled) -{ - struct cmos_rtc *cmos = dev_get_drvdata(dev); - unsigned long flags; - - if (!is_valid_irq(cmos->irq)) - return -EINVAL; - - spin_lock_irqsave(&rtc_lock, flags); - - if (enabled) - cmos_irq_enable(cmos, RTC_UIE); - else - cmos_irq_disable(cmos, RTC_UIE); - - spin_unlock_irqrestore(&rtc_lock, flags); - return 0; -} - #if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE) static int cmos_procfs(struct device *dev, struct seq_file *seq) @@ -458,7 +439,6 @@ static const struct rtc_class_ops cmos_rtc_ops = { .set_alarm = cmos_set_alarm, .proc = cmos_procfs, .alarm_irq_enable = cmos_alarm_irq_enable, - .update_irq_enable = cmos_update_irq_enable, }; /*----------------------------------------------------------------*/ diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 37268e97de49..3fffd708711f 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c @@ -397,29 +397,12 @@ static int ds1511_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) return 0; } -static int ds1511_rtc_update_irq_enable(struct device *dev, - unsigned int enabled) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - - if (pdata->irq <= 0) - return -EINVAL; - if (enabled) - pdata->irqen |= RTC_UF; - else - pdata->irqen &= ~RTC_UF; - ds1511_rtc_update_alarm(pdata); - return 0; -} - static const struct rtc_class_ops ds1511_rtc_ops = { .read_time = ds1511_rtc_read_time, .set_time = ds1511_rtc_set_time, .read_alarm = ds1511_rtc_read_alarm, .set_alarm = ds1511_rtc_set_alarm, .alarm_irq_enable = ds1511_rtc_alarm_irq_enable, - .update_irq_enable = ds1511_rtc_update_irq_enable, }; static ssize_t diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index ff432e2ca275..fee41b97c9e8 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c @@ -227,29 +227,12 @@ static int ds1553_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) return 0; } -static int ds1553_rtc_update_irq_enable(struct device *dev, - unsigned int enabled) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - - if (pdata->irq <= 0) - return -EINVAL; - if (enabled) - pdata->irqen |= RTC_UF; - else - pdata->irqen &= ~RTC_UF; - ds1553_rtc_update_alarm(pdata); - return 0; -} - static const struct rtc_class_ops ds1553_rtc_ops = { .read_time = ds1553_rtc_read_time, .set_time = ds1553_rtc_set_time, .read_alarm = ds1553_rtc_read_alarm, .set_alarm = ds1553_rtc_set_alarm, .alarm_irq_enable = ds1553_rtc_alarm_irq_enable, - .update_irq_enable = ds1553_rtc_update_irq_enable, }; static ssize_t ds1553_nvram_read(struct file *filp, struct kobject *kobj, diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index 950735415a7c..27b7bf672ac6 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c @@ -339,23 +339,6 @@ static int ds3232_alarm_irq_enable(struct device *dev, unsigned int enabled) return 0; } -static int ds3232_update_irq_enable(struct device *dev, unsigned int enabled) -{ - struct i2c_client *client = to_i2c_client(dev); - struct ds3232 *ds3232 = i2c_get_clientdata(client); - - if (client->irq <= 0) - return -EINVAL; - - if (enabled) - ds3232->rtc->irq_data |= RTC_UF; - else - ds3232->rtc->irq_data &= ~RTC_UF; - - ds3232_update_alarm(client); - return 0; -} - static irqreturn_t ds3232_irq(int irq, void *dev_id) { struct i2c_client *client = dev_id; @@ -406,7 +389,6 @@ static const struct rtc_class_ops ds3232_rtc_ops = { .read_alarm = ds3232_read_alarm, .set_alarm = ds3232_set_alarm, .alarm_irq_enable = ds3232_alarm_irq_enable, - .update_irq_enable = ds3232_update_irq_enable, }; static int __devinit ds3232_probe(struct i2c_client *client, diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c index 2e16f72c9056..b6473631d182 100644 --- a/drivers/rtc/rtc-jz4740.c +++ b/drivers/rtc/rtc-jz4740.c @@ -168,12 +168,6 @@ static int jz4740_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) return ret; } -static int jz4740_rtc_update_irq_enable(struct device *dev, unsigned int enable) -{ - struct jz4740_rtc *rtc = dev_get_drvdata(dev); - return jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_1HZ_IRQ, enable); -} - static int jz4740_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) { struct jz4740_rtc *rtc = dev_get_drvdata(dev); @@ -185,7 +179,6 @@ static struct rtc_class_ops jz4740_rtc_ops = { .set_mmss = jz4740_rtc_set_mmss, .read_alarm = jz4740_rtc_read_alarm, .set_alarm = jz4740_rtc_set_alarm, - .update_irq_enable = jz4740_rtc_update_irq_enable, .alarm_irq_enable = jz4740_rtc_alarm_irq_enable, }; diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index 5314b153bfba..c42006469559 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c @@ -282,12 +282,6 @@ static irqreturn_t mc13xxx_rtc_update_handler(int irq, void *dev) return IRQ_HANDLED; } -static int mc13xxx_rtc_update_irq_enable(struct device *dev, - unsigned int enabled) -{ - return mc13xxx_rtc_irq_enable(dev, enabled, MC13XXX_IRQ_1HZ); -} - static int mc13xxx_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { @@ -300,7 +294,6 @@ static const struct rtc_class_ops mc13xxx_rtc_ops = { .read_alarm = mc13xxx_rtc_read_alarm, .set_alarm = mc13xxx_rtc_set_alarm, .alarm_irq_enable = mc13xxx_rtc_alarm_irq_enable, - .update_irq_enable = mc13xxx_rtc_update_irq_enable, }; static irqreturn_t mc13xxx_rtc_reset_handler(int irq, void *dev) diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index dfcdf0901d21..b40c1ff1ebc8 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c @@ -240,32 +240,12 @@ static int mpc5121_rtc_alarm_irq_enable(struct device *dev, return 0; } -static int mpc5121_rtc_update_irq_enable(struct device *dev, - unsigned int enabled) -{ - struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev); - struct mpc5121_rtc_regs __iomem *regs = rtc->regs; - int val; - - val = in_8(®s->int_enable); - - if (enabled) - val = (val & ~0x8) | 0x1; - else - val &= ~0x1; - - out_8(®s->int_enable, val); - - return 0; -} - static const struct rtc_class_ops mpc5121_rtc_ops = { .read_time = mpc5121_rtc_read_time, .set_time = mpc5121_rtc_set_time, .read_alarm = mpc5121_rtc_read_alarm, .set_alarm = mpc5121_rtc_set_alarm, .alarm_irq_enable = mpc5121_rtc_alarm_irq_enable, - .update_irq_enable = mpc5121_rtc_update_irq_enable, }; static int __devinit mpc5121_rtc_probe(struct platform_device *op, diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index 0b06c1e03fd5..826ab64a8fa9 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -274,12 +274,6 @@ static int mxc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) return 0; } -static int mxc_rtc_update_irq_enable(struct device *dev, unsigned int enabled) -{ - mxc_rtc_irq_enable(dev, RTC_1HZ_BIT, enabled); - return 0; -} - /* * This function reads the current RTC time into tm in Gregorian date. */ @@ -368,7 +362,6 @@ static struct rtc_class_ops mxc_rtc_ops = { .read_alarm = mxc_rtc_read_alarm, .set_alarm = mxc_rtc_set_alarm, .alarm_irq_enable = mxc_rtc_alarm_irq_enable, - .update_irq_enable = mxc_rtc_update_irq_enable, }; static int __init mxc_rtc_probe(struct platform_device *pdev) diff --git a/drivers/rtc/rtc-nuc900.c b/drivers/rtc/rtc-nuc900.c index ddb0857e15a4..781068d62f23 100644 --- a/drivers/rtc/rtc-nuc900.c +++ b/drivers/rtc/rtc-nuc900.c @@ -134,20 +134,6 @@ static void nuc900_rtc_bin2bcd(struct device *dev, struct rtc_time *settm, gettm->bcd_hour = bin2bcd(settm->tm_hour) << 16; } -static int nuc900_update_irq_enable(struct device *dev, unsigned int enabled) -{ - struct nuc900_rtc *rtc = dev_get_drvdata(dev); - - if (enabled) - __raw_writel(__raw_readl(rtc->rtc_reg + REG_RTC_RIER)| - (TICKINTENB), rtc->rtc_reg + REG_RTC_RIER); - else - __raw_writel(__raw_readl(rtc->rtc_reg + REG_RTC_RIER)& - (~TICKINTENB), rtc->rtc_reg + REG_RTC_RIER); - - return 0; -} - static int nuc900_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct nuc900_rtc *rtc = dev_get_drvdata(dev); @@ -234,7 +220,6 @@ static struct rtc_class_ops nuc900_rtc_ops = { .read_alarm = nuc900_rtc_read_alarm, .set_alarm = nuc900_rtc_set_alarm, .alarm_irq_enable = nuc900_alarm_irq_enable, - .update_irq_enable = nuc900_update_irq_enable, }; static int __devinit nuc900_rtc_probe(struct platform_device *pdev) diff --git a/drivers/rtc/rtc-pcap.c b/drivers/rtc/rtc-pcap.c index 25c0b3fd44f1..a633abc42896 100644 --- a/drivers/rtc/rtc-pcap.c +++ b/drivers/rtc/rtc-pcap.c @@ -131,18 +131,12 @@ static int pcap_rtc_alarm_irq_enable(struct device *dev, unsigned int en) return pcap_rtc_irq_enable(dev, PCAP_IRQ_TODA, en); } -static int pcap_rtc_update_irq_enable(struct device *dev, unsigned int en) -{ - return pcap_rtc_irq_enable(dev, PCAP_IRQ_1HZ, en); -} - static const struct rtc_class_ops pcap_rtc_ops = { .read_time = pcap_rtc_read_time, .read_alarm = pcap_rtc_read_alarm, .set_alarm = pcap_rtc_set_alarm, .set_mmss = pcap_rtc_set_mmss, .alarm_irq_enable = pcap_rtc_alarm_irq_enable, - .update_irq_enable = pcap_rtc_update_irq_enable, }; static int __devinit pcap_rtc_probe(struct platform_device *pdev) diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c index 16edf94ab42f..f90c574f9d05 100644 --- a/drivers/rtc/rtc-pcf50633.c +++ b/drivers/rtc/rtc-pcf50633.c @@ -106,25 +106,6 @@ pcf50633_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) return 0; } -static int -pcf50633_rtc_update_irq_enable(struct device *dev, unsigned int enabled) -{ - struct pcf50633_rtc *rtc = dev_get_drvdata(dev); - int err; - - if (enabled) - err = pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_SECOND); - else - err = pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_SECOND); - - if (err < 0) - return err; - - rtc->second_enabled = enabled; - - return 0; -} - static int pcf50633_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct pcf50633_rtc *rtc; @@ -262,8 +243,7 @@ static struct rtc_class_ops pcf50633_rtc_ops = { .set_time = pcf50633_rtc_set_time, .read_alarm = pcf50633_rtc_read_alarm, .set_alarm = pcf50633_rtc_set_alarm, - .alarm_irq_enable = pcf50633_rtc_alarm_irq_enable, - .update_irq_enable = pcf50633_rtc_update_irq_enable, + .alarm_irq_enable = pcf50633_rtc_alarm_irq_enable, }; static void pcf50633_rtc_irq(int irq, void *data) diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c index a1fdc802598a..fc9f4991574b 100644 --- a/drivers/rtc/rtc-pxa.c +++ b/drivers/rtc/rtc-pxa.c @@ -224,21 +224,6 @@ static int pxa_alarm_irq_enable(struct device *dev, unsigned int enabled) return 0; } -static int pxa_update_irq_enable(struct device *dev, unsigned int enabled) -{ - struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); - - spin_lock_irq(&pxa_rtc->lock); - - if (enabled) - rtsr_set_bits(pxa_rtc, RTSR_HZE); - else - rtsr_clear_bits(pxa_rtc, RTSR_HZE); - - spin_unlock_irq(&pxa_rtc->lock); - return 0; -} - static int pxa_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); @@ -320,7 +305,6 @@ static const struct rtc_class_ops pxa_rtc_ops = { .read_alarm = pxa_rtc_read_alarm, .set_alarm = pxa_rtc_set_alarm, .alarm_irq_enable = pxa_alarm_irq_enable, - .update_irq_enable = pxa_update_irq_enable, .proc = pxa_rtc_proc, }; diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index 7e7d0c806f2d..572e9534b591 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c @@ -115,19 +115,6 @@ static int stmp3xxx_alarm_irq_enable(struct device *dev, unsigned int enabled) return 0; } -static int stmp3xxx_update_irq_enable(struct device *dev, unsigned int enabled) -{ - struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); - - if (enabled) - stmp3xxx_setl(BM_RTC_CTRL_ONEMSEC_IRQ_EN, - rtc_data->io + HW_RTC_CTRL); - else - stmp3xxx_clearl(BM_RTC_CTRL_ONEMSEC_IRQ_EN, - rtc_data->io + HW_RTC_CTRL); - return 0; -} - static int stmp3xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) { struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); @@ -149,8 +136,6 @@ static int stmp3xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) static struct rtc_class_ops stmp3xxx_rtc_ops = { .alarm_irq_enable = stmp3xxx_alarm_irq_enable, - .update_irq_enable = - stmp3xxx_update_irq_enable, .read_time = stmp3xxx_rtc_gettime, .set_mmss = stmp3xxx_rtc_set_mmss, .read_alarm = stmp3xxx_rtc_read_alarm, diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index ed1b86828124..f9a2799c44d6 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -213,18 +213,6 @@ static int twl_rtc_alarm_irq_enable(struct device *dev, unsigned enabled) return ret; } -static int twl_rtc_update_irq_enable(struct device *dev, unsigned enabled) -{ - int ret; - - if (enabled) - ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M); - else - ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M); - - return ret; -} - /* * Gets current TWL RTC time and date parameters. * @@ -433,7 +421,6 @@ static struct rtc_class_ops twl_rtc_ops = { .read_alarm = twl_rtc_read_alarm, .set_alarm = twl_rtc_set_alarm, .alarm_irq_enable = twl_rtc_alarm_irq_enable, - .update_irq_enable = twl_rtc_update_irq_enable, }; /*----------------------------------------------------------------------*/ diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c index 82931dc65c0b..bdc909bd56da 100644 --- a/drivers/rtc/rtc-wm831x.c +++ b/drivers/rtc/rtc-wm831x.c @@ -315,21 +315,6 @@ static int wm831x_rtc_alarm_irq_enable(struct device *dev, return wm831x_rtc_stop_alarm(wm831x_rtc); } -static int wm831x_rtc_update_irq_enable(struct device *dev, - unsigned int enabled) -{ - struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(dev); - int val; - - if (enabled) - val = 1 << WM831X_RTC_PINT_FREQ_SHIFT; - else - val = 0; - - return wm831x_set_bits(wm831x_rtc->wm831x, WM831X_RTC_CONTROL, - WM831X_RTC_PINT_FREQ_MASK, val); -} - static irqreturn_t wm831x_alm_irq(int irq, void *data) { struct wm831x_rtc *wm831x_rtc = data; @@ -354,7 +339,6 @@ static const struct rtc_class_ops wm831x_rtc_ops = { .read_alarm = wm831x_rtc_readalarm, .set_alarm = wm831x_rtc_setalarm, .alarm_irq_enable = wm831x_rtc_alarm_irq_enable, - .update_irq_enable = wm831x_rtc_update_irq_enable, }; #ifdef CONFIG_PM diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c index 3d0dc76b38af..66421426e404 100644 --- a/drivers/rtc/rtc-wm8350.c +++ b/drivers/rtc/rtc-wm8350.c @@ -302,26 +302,6 @@ static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) return ret; } -static int wm8350_rtc_update_irq_enable(struct device *dev, - unsigned int enabled) -{ - struct wm8350 *wm8350 = dev_get_drvdata(dev); - - /* Suppress duplicate changes since genirq nests enable and - * disable calls. */ - if (enabled == wm8350->rtc.update_enabled) - return 0; - - if (enabled) - wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC); - else - wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); - - wm8350->rtc.update_enabled = enabled; - - return 0; -} - static irqreturn_t wm8350_rtc_alarm_handler(int irq, void *data) { struct wm8350 *wm8350 = data; @@ -357,7 +337,6 @@ static const struct rtc_class_ops wm8350_rtc_ops = { .read_alarm = wm8350_rtc_readalarm, .set_alarm = wm8350_rtc_setalarm, .alarm_irq_enable = wm8350_rtc_alarm_irq_enable, - .update_irq_enable = wm8350_rtc_update_irq_enable, }; #ifdef CONFIG_PM diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 741a51cc4460..2ca7e8a78060 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -149,7 +149,6 @@ struct rtc_class_ops { int (*set_mmss)(struct device *, unsigned long secs); int (*read_callback)(struct device *, int data); int (*alarm_irq_enable)(struct device *, unsigned int enabled); - int (*update_irq_enable)(struct device *, unsigned int enabled); }; #define RTC_DEVICE_NAME_SIZE 20 -- cgit v1.2.3 From e428c6a2772bcf6b022baf7c8267cca3634c0c3e Mon Sep 17 00:00:00 2001 From: John Stultz Date: Fri, 4 Feb 2011 16:16:12 -0800 Subject: RTC: Clean out UIE icotl implementations With the generic RTC rework, the UIE mode irqs are handled in the generic layer, and only hardware specific ioctls get passed down to the rtc driver layer. So this patch removes the UIE mode ioctl handling in the rtc driver layer, which never get used. CC: Thomas Gleixner CC: Alessandro Zummo CC: Marcelo Roberto Jimenez CC: rtc-linux@googlegroups.com Signed-off-by: John Stultz --- drivers/rtc/rtc-at91rm9200.c | 28 ------------------------ drivers/rtc/rtc-at91sam9.c | 28 ------------------------ drivers/rtc/rtc-bfin.c | 27 ----------------------- drivers/rtc/rtc-davinci.c | 4 ---- drivers/rtc/rtc-omap.c | 39 --------------------------------- drivers/rtc/rtc-pl030.c | 6 ----- drivers/rtc/rtc-rs5c372.c | 52 -------------------------------------------- drivers/rtc/rtc-sa1100.c | 19 ---------------- drivers/rtc/rtc-sh.c | 22 ------------------- 9 files changed, 225 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 26d1cf5d19ae..518a76ec71ca 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c @@ -183,33 +183,6 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) return 0; } -/* - * Handle commands from user-space - */ -static int at91_rtc_ioctl(struct device *dev, unsigned int cmd, - unsigned long arg) -{ - int ret = 0; - - pr_debug("%s(): cmd=%08x, arg=%08lx.\n", __func__, cmd, arg); - - /* important: scrub old status before enabling IRQs */ - switch (cmd) { - case RTC_UIE_OFF: /* update off */ - at91_sys_write(AT91_RTC_IDR, AT91_RTC_SECEV); - break; - case RTC_UIE_ON: /* update on */ - at91_sys_write(AT91_RTC_SCCR, AT91_RTC_SECEV); - at91_sys_write(AT91_RTC_IER, AT91_RTC_SECEV); - break; - default: - ret = -ENOIOCTLCMD; - break; - } - - return ret; -} - static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { pr_debug("%s(): cmd=%08x\n", __func__, enabled); @@ -269,7 +242,6 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) } static const struct rtc_class_ops at91_rtc_ops = { - .ioctl = at91_rtc_ioctl, .read_time = at91_rtc_readtime, .set_time = at91_rtc_settime, .read_alarm = at91_rtc_readalarm, diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 5469c52cba3d..a3ad957507dc 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -216,33 +216,6 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) return 0; } -/* - * Handle commands from user-space - */ -static int at91_rtc_ioctl(struct device *dev, unsigned int cmd, - unsigned long arg) -{ - struct sam9_rtc *rtc = dev_get_drvdata(dev); - int ret = 0; - u32 mr = rtt_readl(rtc, MR); - - dev_dbg(dev, "ioctl: cmd=%08x, arg=%08lx, mr %08x\n", cmd, arg, mr); - - switch (cmd) { - case RTC_UIE_OFF: /* update off */ - rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); - break; - case RTC_UIE_ON: /* update on */ - rtt_writel(rtc, MR, mr | AT91_RTT_RTTINCIEN); - break; - default: - ret = -ENOIOCTLCMD; - break; - } - - return ret; -} - static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct sam9_rtc *rtc = dev_get_drvdata(dev); @@ -303,7 +276,6 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc) } static const struct rtc_class_ops at91_rtc_ops = { - .ioctl = at91_rtc_ioctl, .read_time = at91_rtc_readtime, .set_time = at91_rtc_settime, .read_alarm = at91_rtc_readalarm, diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index 17971d93354d..ca9cff85ab8a 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c @@ -240,32 +240,6 @@ static void bfin_rtc_int_set_alarm(struct bfin_rtc *rtc) */ bfin_rtc_int_set(rtc->rtc_alarm.tm_yday == -1 ? RTC_ISTAT_ALARM : RTC_ISTAT_ALARM_DAY); } -static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) -{ - struct bfin_rtc *rtc = dev_get_drvdata(dev); - int ret = 0; - - dev_dbg_stamp(dev); - - bfin_rtc_sync_pending(dev); - - switch (cmd) { - case RTC_UIE_ON: - dev_dbg_stamp(dev); - bfin_rtc_int_set(RTC_ISTAT_SEC); - break; - case RTC_UIE_OFF: - dev_dbg_stamp(dev); - bfin_rtc_int_clear(~RTC_ISTAT_SEC); - break; - - default: - dev_dbg_stamp(dev); - ret = -ENOIOCTLCMD; - } - - return ret; -} static int bfin_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { @@ -358,7 +332,6 @@ static int bfin_rtc_proc(struct device *dev, struct seq_file *seq) } static struct rtc_class_ops bfin_rtc_ops = { - .ioctl = bfin_rtc_ioctl, .read_time = bfin_rtc_read_time, .set_time = bfin_rtc_set_time, .read_alarm = bfin_rtc_read_alarm, diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index dfd98a235ad1..8d46838dff8a 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c @@ -231,10 +231,6 @@ davinci_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) case RTC_WIE_OFF: rtc_ctrl &= ~PRTCSS_RTC_CTRL_WEN; break; - case RTC_UIE_OFF: - case RTC_UIE_ON: - ret = -ENOTTY; - break; default: ret = -ENOIOCTLCMD; } diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index b4dbf3a319b3..de0dd7b1f146 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -135,44 +135,6 @@ static irqreturn_t rtc_irq(int irq, void *rtc) return IRQ_HANDLED; } -#ifdef CONFIG_RTC_INTF_DEV - -static int -omap_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) -{ - u8 reg; - - switch (cmd) { - case RTC_UIE_OFF: - case RTC_UIE_ON: - break; - default: - return -ENOIOCTLCMD; - } - - local_irq_disable(); - rtc_wait_not_busy(); - reg = rtc_read(OMAP_RTC_INTERRUPTS_REG); - switch (cmd) { - /* UIE = Update Interrupt Enable (1/second) */ - case RTC_UIE_OFF: - reg &= ~OMAP_RTC_INTERRUPTS_IT_TIMER; - break; - case RTC_UIE_ON: - reg |= OMAP_RTC_INTERRUPTS_IT_TIMER; - break; - } - rtc_wait_not_busy(); - rtc_write(reg, OMAP_RTC_INTERRUPTS_REG); - local_irq_enable(); - - return 0; -} - -#else -#define omap_rtc_ioctl NULL -#endif - static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { u8 reg; @@ -313,7 +275,6 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) } static struct rtc_class_ops omap_rtc_ops = { - .ioctl = omap_rtc_ioctl, .read_time = omap_rtc_read_time, .set_time = omap_rtc_set_time, .read_alarm = omap_rtc_read_alarm, diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c index bbdb2f02798a..d554368c9f57 100644 --- a/drivers/rtc/rtc-pl030.c +++ b/drivers/rtc/rtc-pl030.c @@ -35,11 +35,6 @@ static irqreturn_t pl030_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static int pl030_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) -{ - return -ENOIOCTLCMD; -} - static int pl030_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct pl030_rtc *rtc = dev_get_drvdata(dev); @@ -96,7 +91,6 @@ static int pl030_set_time(struct device *dev, struct rtc_time *tm) } static const struct rtc_class_ops pl030_ops = { - .ioctl = pl030_ioctl, .read_time = pl030_read_time, .set_time = pl030_set_time, .read_alarm = pl030_read_alarm, diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 6aaa1550e3b1..85c1b848dd72 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -281,57 +281,6 @@ static int rs5c372_rtc_set_time(struct device *dev, struct rtc_time *tm) return rs5c372_set_datetime(to_i2c_client(dev), tm); } -#if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE) - -static int -rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) -{ - struct i2c_client *client = to_i2c_client(dev); - struct rs5c372 *rs5c = i2c_get_clientdata(client); - unsigned char buf; - int status, addr; - - buf = rs5c->regs[RS5C_REG_CTRL1]; - switch (cmd) { - case RTC_UIE_OFF: - case RTC_UIE_ON: - /* some 327a modes use a different IRQ pin for 1Hz irqs */ - if (rs5c->type == rtc_rs5c372a - && (buf & RS5C372A_CTRL1_SL1)) - return -ENOIOCTLCMD; - default: - return -ENOIOCTLCMD; - } - - status = rs5c_get_regs(rs5c); - if (status < 0) - return status; - - addr = RS5C_ADDR(RS5C_REG_CTRL1); - switch (cmd) { - case RTC_UIE_OFF: /* update off */ - buf &= ~RS5C_CTRL1_CT_MASK; - break; - case RTC_UIE_ON: /* update on */ - buf &= ~RS5C_CTRL1_CT_MASK; - buf |= RS5C_CTRL1_CT4; - break; - } - - if (i2c_smbus_write_byte_data(client, addr, buf) < 0) { - printk(KERN_WARNING "%s: can't update alarm\n", - rs5c->rtc->name); - status = -EIO; - } else - rs5c->regs[RS5C_REG_CTRL1] = buf; - - return status; -} - -#else -#define rs5c_rtc_ioctl NULL -#endif - static int rs5c_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { @@ -480,7 +429,6 @@ static int rs5c372_rtc_proc(struct device *dev, struct seq_file *seq) static const struct rtc_class_ops rs5c372_rtc_ops = { .proc = rs5c372_rtc_proc, - .ioctl = rs5c_rtc_ioctl, .read_time = rs5c372_rtc_read_time, .set_time = rs5c372_rtc_set_time, .read_alarm = rs5c_read_alarm, diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index d1a2b0bc3b24..a9189337a2c5 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c @@ -293,24 +293,6 @@ static void sa1100_rtc_release(struct device *dev) } -static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, - unsigned long arg) -{ - switch (cmd) { - case RTC_UIE_OFF: - spin_lock_irq(&sa1100_rtc_lock); - RTSR &= ~RTSR_HZE; - spin_unlock_irq(&sa1100_rtc_lock); - return 0; - case RTC_UIE_ON: - spin_lock_irq(&sa1100_rtc_lock); - RTSR |= RTSR_HZE; - spin_unlock_irq(&sa1100_rtc_lock); - return 0; - } - return -ENOIOCTLCMD; -} - static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { spin_lock_irq(&sa1100_rtc_lock); @@ -386,7 +368,6 @@ static const struct rtc_class_ops sa1100_rtc_ops = { .open = sa1100_rtc_open, .read_callback = sa1100_rtc_read_callback, .release = sa1100_rtc_release, - .ioctl = sa1100_rtc_ioctl, .read_time = sa1100_rtc_read_time, .set_time = sa1100_rtc_set_time, .read_alarm = sa1100_rtc_read_alarm, diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 148544979a54..e55dc1ac83ab 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -344,27 +344,6 @@ static inline void sh_rtc_setcie(struct device *dev, unsigned int enable) spin_unlock_irq(&rtc->lock); } -static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) -{ - struct sh_rtc *rtc = dev_get_drvdata(dev); - unsigned int ret = 0; - - switch (cmd) { - case RTC_UIE_OFF: - rtc->periodic_freq &= ~PF_OXS; - sh_rtc_setcie(dev, 0); - break; - case RTC_UIE_ON: - rtc->periodic_freq |= PF_OXS; - sh_rtc_setcie(dev, 1); - break; - default: - ret = -ENOIOCTLCMD; - } - - return ret; -} - static int sh_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { sh_rtc_setaie(dev, enabled); @@ -598,7 +577,6 @@ static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) } static struct rtc_class_ops sh_rtc_ops = { - .ioctl = sh_rtc_ioctl, .read_time = sh_rtc_read_time, .set_time = sh_rtc_set_time, .read_alarm = sh_rtc_read_alarm, -- cgit v1.2.3 From bca8521c551afcd926bdc8f814ebaefcb8215c57 Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Fri, 11 Feb 2011 11:50:24 -0200 Subject: RTC: Include information about UIE and PIE in RTC driver proc. Generic RTC code is always able to provide the necessary information about update and periodic interrupts. This patch add such information to the proc interface. CC: Thomas Gleixner CC: Alessandro Zummo CC: Marcelo Roberto Jimenez CC: rtc-linux@googlegroups.com Signed-off-by: Marcelo Roberto Jimenez Signed-off-by: John Stultz --- drivers/rtc/rtc-proc.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c index 242bbf86c74a..0a59fda5c09d 100644 --- a/drivers/rtc/rtc-proc.c +++ b/drivers/rtc/rtc-proc.c @@ -69,6 +69,14 @@ static int rtc_proc_show(struct seq_file *seq, void *offset) alrm.enabled ? "yes" : "no"); seq_printf(seq, "alrm_pending\t: %s\n", alrm.pending ? "yes" : "no"); + seq_printf(seq, "update IRQ enabled\t: %s\n", + (rtc->uie_rtctimer.enabled) ? "yes" : "no"); + seq_printf(seq, "periodic IRQ enabled\t: %s\n", + (rtc->pie_enabled) ? "yes" : "no"); + seq_printf(seq, "periodic IRQ frequency\t: %d\n", + rtc->irq_freq); + seq_printf(seq, "max user IRQ frequency\t: %d\n", + rtc->max_user_freq); } seq_printf(seq, "24hr\t\t: yes\n"); -- cgit v1.2.3 From 4cebe7aadc9ee8e7b44857b7aba3a878870cef65 Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Mon, 7 Feb 2011 19:16:06 -0200 Subject: RTC: Remove UIE and PIE information from the sa1100 driver proc. This patch removes the UIE and PIE information that is now being supplied directly in the generic RTC code. CC: Thomas Gleixner CC: Alessandro Zummo CC: Marcelo Roberto Jimenez CC: rtc-linux@googlegroups.com Signed-off-by: Marcelo Roberto Jimenez Signed-off-by: John Stultz --- drivers/rtc/rtc-sa1100.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index a9189337a2c5..41f62ca68dc4 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c @@ -351,15 +351,8 @@ static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) { - struct rtc_device *rtc = (struct rtc_device *)dev; - - seq_printf(seq, "trim/divider\t: 0x%08x\n", (u32) RTTR); - seq_printf(seq, "update_IRQ\t: %s\n", - (RTSR & RTSR_HZE) ? "yes" : "no"); - seq_printf(seq, "periodic_IRQ\t: %s\n", - (OIER & OIER_E1) ? "yes" : "no"); - seq_printf(seq, "periodic_freq\t: %d\n", rtc->irq_freq); - seq_printf(seq, "RTSR\t\t: 0x%08x\n", (u32)RTSR); + seq_printf(seq, "trim/divider\t\t: 0x%08x\n", (u32) RTTR); + seq_printf(seq, "RTSR\t\t\t: 0x%08x\n", (u32)RTSR); return 0; } -- cgit v1.2.3 From a417493ef916b8b6d1782a589766a713c553842e Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Mon, 7 Feb 2011 19:16:07 -0200 Subject: RTC: Fix the cross interrupt issue on rtc-test. The rtc-test driver is meant to provide a test/debug code for the RTC subsystem. The rtc-test driver simulates specific interrupts by echoing to the sys interface. Those were the update, alarm and periodic interrupts. As a side effect of the new implementation, any interrupt generated in the rtc-test driver would trigger the same code path in the generic code, and thus the distinction among interrupts gets lost. This patch preserves the previous behaviour of the rtc-test driver, where e.g. an update interrupt would not trigger an alarm or periodic interrupt, and vice-versa. In real world RTC drivers, this is not an issue, but in the rtc-test driver it may be interesting to distinguish these interrupts for testing purposes. CC: Thomas Gleixner CC: Alessandro Zummo CC: Marcelo Roberto Jimenez CC: rtc-linux@googlegroups.com Signed-off-by: Marcelo Roberto Jimenez Signed-off-by: John Stultz --- drivers/rtc/rtc-test.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index a82d6fe97076..7e96254bd365 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c @@ -78,11 +78,16 @@ static ssize_t test_irq_store(struct device *dev, struct rtc_device *rtc = platform_get_drvdata(plat_dev); retval = count; - if (strncmp(buf, "tick", 4) == 0) + if (strncmp(buf, "tick", 4) == 0 && rtc->pie_enabled) rtc_update_irq(rtc, 1, RTC_PF | RTC_IRQF); - else if (strncmp(buf, "alarm", 5) == 0) - rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF); - else if (strncmp(buf, "update", 6) == 0) + else if (strncmp(buf, "alarm", 5) == 0) { + struct rtc_wkalrm alrm; + int err = rtc_read_alarm(rtc, &alrm); + + if (!err && alrm.enabled) + rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF); + + } else if (strncmp(buf, "update", 6) == 0 && rtc->uie_rtctimer.enabled) rtc_update_irq(rtc, 1, RTC_UF | RTC_IRQF); else retval = -EINVAL; -- cgit v1.2.3 From 416f0e8056f757c119dc3d4fa434a62b65c8272b Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Mon, 7 Feb 2011 19:16:08 -0200 Subject: RTC: sa1100: Update the sa1100 RTC driver. Since PIE interrupts are now emulated, this patch removes the previous code that used the hardware counters. The removal of read_callback() also fixes a wrong user space behaviour of this driver, which was not returning the right value to read(). [john.stultz: Merge fixups] CC: Thomas Gleixner CC: Alessandro Zummo CC: Marcelo Roberto Jimenez CC: rtc-linux@googlegroups.com Signed-off-by: Marcelo Roberto Jimenez Signed-off-by: John Stultz --- drivers/rtc/rtc-sa1100.c | 111 ++--------------------------------------------- 1 file changed, 3 insertions(+), 108 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 41f62ca68dc4..0b40bb88a884 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c @@ -43,7 +43,6 @@ #define RTC_DEF_TRIM 0 static const unsigned long RTC_FREQ = 1024; -static unsigned long timer_freq; static struct rtc_time rtc_alarm; static DEFINE_SPINLOCK(sa1100_rtc_lock); @@ -156,97 +155,11 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static int sa1100_irq_set_freq(struct device *dev, int freq) -{ - if (freq < 1 || freq > timer_freq) { - return -EINVAL; - } else { - struct rtc_device *rtc = (struct rtc_device *)dev; - - rtc->irq_freq = freq; - - return 0; - } -} - -static int rtc_timer1_count; - -static inline int sa1100_timer1_retrigger(struct rtc_device *rtc) -{ - unsigned long diff; - unsigned long period = timer_freq / rtc->irq_freq; - - spin_lock_irq(&sa1100_rtc_lock); - - do { - OSMR1 += period; - diff = OSMR1 - OSCR; - /* If OSCR > OSMR1, diff is a very large number (unsigned - * math). This means we have a lost interrupt. */ - } while (diff > period); - OIER |= OIER_E1; - - spin_unlock_irq(&sa1100_rtc_lock); - - return 0; -} - -static irqreturn_t timer1_interrupt(int irq, void *dev_id) -{ - struct platform_device *pdev = to_platform_device(dev_id); - struct rtc_device *rtc = platform_get_drvdata(pdev); - - /* - * If we match for the first time, rtc_timer1_count will be 1. - * Otherwise, we wrapped around (very unlikely but - * still possible) so compute the amount of missed periods. - * The match reg is updated only when the data is actually retrieved - * to avoid unnecessary interrupts. - */ - OSSR = OSSR_M1; /* clear match on timer1 */ - - rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF); - - if (rtc_timer1_count == 1) - rtc_timer1_count = - (rtc->irq_freq * ((1 << 30) / (timer_freq >> 2))); - - /* retrigger. */ - sa1100_timer1_retrigger(rtc); - - return IRQ_HANDLED; -} - -static int sa1100_rtc_read_callback(struct device *dev, int data) -{ - if (data & RTC_PF) { - struct rtc_device *rtc = (struct rtc_device *)dev; - - /* interpolate missed periods and set match for the next */ - unsigned long period = timer_freq / rtc->irq_freq; - unsigned long oscr = OSCR; - unsigned long osmr1 = OSMR1; - unsigned long missed = (oscr - osmr1)/period; - data += missed << 8; - OSSR = OSSR_M1; /* clear match on timer 1 */ - OSMR1 = osmr1 + (missed + 1)*period; - /* Ensure we didn't miss another match in the mean time. - * Here we compare (match - OSCR) 8 instead of 0 -- - * see comment in pxa_timer_interrupt() for explanation. - */ - while ((signed long)((osmr1 = OSMR1) - OSCR) <= 8) { - data += 0x100; - OSSR = OSSR_M1; /* clear match on timer 1 */ - OSMR1 = osmr1 + period; - } - } - return data; -} - static int sa1100_rtc_open(struct device *dev) { int ret; - struct rtc_device *rtc = (struct rtc_device *)dev; + struct platform_device *plat_dev = to_platform_device(dev); + struct rtc_device *rtc = platform_get_drvdata(plat_dev); ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED, "rtc 1Hz", dev); @@ -260,19 +173,11 @@ static int sa1100_rtc_open(struct device *dev) dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm); goto fail_ai; } - ret = request_irq(IRQ_OST1, timer1_interrupt, IRQF_DISABLED, - "rtc timer", dev); - if (ret) { - dev_err(dev, "IRQ %d already in use.\n", IRQ_OST1); - goto fail_pi; - } rtc->max_user_freq = RTC_FREQ; - sa1100_irq_set_freq(dev, RTC_FREQ); + rtc_irq_set_freq(rtc, NULL, RTC_FREQ); return 0; - fail_pi: - free_irq(IRQ_RTCAlrm, dev); fail_ai: free_irq(IRQ_RTC1Hz, dev); fail_ui: @@ -287,12 +192,10 @@ static void sa1100_rtc_release(struct device *dev) OSSR = OSSR_M1; spin_unlock_irq(&sa1100_rtc_lock); - free_irq(IRQ_OST1, dev); free_irq(IRQ_RTCAlrm, dev); free_irq(IRQ_RTC1Hz, dev); } - static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { spin_lock_irq(&sa1100_rtc_lock); @@ -359,7 +262,6 @@ static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) static const struct rtc_class_ops sa1100_rtc_ops = { .open = sa1100_rtc_open, - .read_callback = sa1100_rtc_read_callback, .release = sa1100_rtc_release, .read_time = sa1100_rtc_read_time, .set_time = sa1100_rtc_set_time, @@ -373,8 +275,6 @@ static int sa1100_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; - timer_freq = get_clock_tick_rate(); - /* * According to the manual we should be able to let RTTR be zero * and then a default diviser for a 32.768KHz clock is used. @@ -400,11 +300,6 @@ static int sa1100_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rtc); - /* Set the irq_freq */ - /*TODO: Find out who is messing with this value after we initialize - * it here.*/ - rtc->irq_freq = RTC_FREQ; - /* Fix for a nasty initialization problem the in SA11xx RTSR register. * See also the comments in sa1100_rtc_interrupt(). * -- cgit v1.2.3 From b9ede5f1dc03f96949dcaa8f8b3483766c047260 Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Tue, 8 Mar 2011 11:02:03 +0800 Subject: mwl8k: use kcalloc instead of kmalloc & memset Use kcalloc or kzalloc rather than the combination of kmalloc and memset. Thanks coccicheck for detecting this. (http://coccinelle.lip6.fr/) Signed-off-by: Shan Wei Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index df5959f36d0b..36952274950e 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -1056,13 +1056,12 @@ static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index) } memset(rxq->rxd, 0, size); - rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL); + rxq->buf = kcalloc(MWL8K_RX_DESCS, sizeof(*rxq->buf), GFP_KERNEL); if (rxq->buf == NULL) { wiphy_err(hw->wiphy, "failed to alloc RX skbuff list\n"); pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma); return -ENOMEM; } - memset(rxq->buf, 0, MWL8K_RX_DESCS * sizeof(*rxq->buf)); for (i = 0; i < MWL8K_RX_DESCS; i++) { int desc_size; @@ -1347,13 +1346,12 @@ static int mwl8k_txq_init(struct ieee80211_hw *hw, int index) } memset(txq->txd, 0, size); - txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL); + txq->skb = kcalloc(MWL8K_TX_DESCS, sizeof(*txq->skb), GFP_KERNEL); if (txq->skb == NULL) { wiphy_err(hw->wiphy, "failed to alloc TX skbuff list\n"); pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma); return -ENOMEM; } - memset(txq->skb, 0, MWL8K_TX_DESCS * sizeof(*txq->skb)); for (i = 0; i < MWL8K_TX_DESCS; i++) { struct mwl8k_tx_desc *tx_desc; -- cgit v1.2.3 From 80751e2b8ffcbbe065e850d943301aa1ab219599 Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Mon, 7 Mar 2011 11:14:23 -0800 Subject: ieee80211: add IEEE80211_COUNTRY_STRING_LEN definition and make use of it in wireless drivers Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/at76c50x-usb.h | 2 +- drivers/net/wireless/ipw2x00/ipw2200.h | 2 +- drivers/net/wireless/libertas/host.h | 2 +- drivers/net/wireless/wl1251/wl12xx_80211.h | 3 +-- drivers/net/wireless/wl12xx/wl12xx_80211.h | 3 +-- include/linux/ieee80211.h | 3 +++ 6 files changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/at76c50x-usb.h b/drivers/net/wireless/at76c50x-usb.h index 4a37447dfc01..f14a65473fe8 100644 --- a/drivers/net/wireless/at76c50x-usb.h +++ b/drivers/net/wireless/at76c50x-usb.h @@ -290,7 +290,7 @@ struct mib_mac_mgmt { u8 res; u8 multi_domain_capability_implemented; u8 multi_domain_capability_enabled; - u8 country_string[3]; + u8 country_string[IEEE80211_COUNTRY_STRING_LEN]; u8 reserved[3]; } __packed; diff --git a/drivers/net/wireless/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h index d7d049c7a4fa..d9e1d9bad581 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.h +++ b/drivers/net/wireless/ipw2x00/ipw2200.h @@ -961,7 +961,7 @@ struct ipw_country_channel_info { struct ipw_country_info { u8 id; u8 length; - u8 country_str[3]; + u8 country_str[IEEE80211_COUNTRY_STRING_LEN]; struct ipw_country_channel_info groups[7]; } __packed; diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h index 5eac1351a021..6cb6935ee4a3 100644 --- a/drivers/net/wireless/libertas/host.h +++ b/drivers/net/wireless/libertas/host.h @@ -387,7 +387,7 @@ struct lbs_offset_value { struct mrvl_ie_domain_param_set { struct mrvl_ie_header header; - u8 country_code[3]; + u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; struct ieee80211_country_ie_triplet triplet[MAX_11D_TRIPLETS]; } __packed; diff --git a/drivers/net/wireless/wl1251/wl12xx_80211.h b/drivers/net/wireless/wl1251/wl12xx_80211.h index 184628027213..1417b1445c3d 100644 --- a/drivers/net/wireless/wl1251/wl12xx_80211.h +++ b/drivers/net/wireless/wl1251/wl12xx_80211.h @@ -54,7 +54,6 @@ /* This really should be 8, but not for our firmware */ #define MAX_SUPPORTED_RATES 32 -#define COUNTRY_STRING_LEN 3 #define MAX_COUNTRY_TRIPLETS 32 /* Headers */ @@ -98,7 +97,7 @@ struct country_triplet { struct wl12xx_ie_country { struct wl12xx_ie_header header; - u8 country_string[COUNTRY_STRING_LEN]; + u8 country_string[IEEE80211_COUNTRY_STRING_LEN]; struct country_triplet triplets[MAX_COUNTRY_TRIPLETS]; } __packed; diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/wl12xx/wl12xx_80211.h index 67dcf8f28cd3..18fe542360f2 100644 --- a/drivers/net/wireless/wl12xx/wl12xx_80211.h +++ b/drivers/net/wireless/wl12xx/wl12xx_80211.h @@ -55,7 +55,6 @@ /* This really should be 8, but not for our firmware */ #define MAX_SUPPORTED_RATES 32 -#define COUNTRY_STRING_LEN 3 #define MAX_COUNTRY_TRIPLETS 32 /* Headers */ @@ -99,7 +98,7 @@ struct country_triplet { struct wl12xx_ie_country { struct wl12xx_ie_header header; - u8 country_string[COUNTRY_STRING_LEN]; + u8 country_string[IEEE80211_COUNTRY_STRING_LEN]; struct country_triplet triplets[MAX_COUNTRY_TRIPLETS]; } __packed; diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 294169e31364..2d1c6117d92c 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1325,6 +1325,9 @@ enum { /* Although the spec says 8 I'm seeing 6 in practice */ #define IEEE80211_COUNTRY_IE_MIN_LEN 6 +/* The Country String field of the element shall be 3 octets in length */ +#define IEEE80211_COUNTRY_STRING_LEN 3 + /* * For regulatory extension stuff see IEEE 802.11-2007 * Annex I (page 1141) and Annex J (page 1147). Also -- cgit v1.2.3 From 23ffaa89df16e55578318cfd852f23dcb37bf37b Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 8 Mar 2011 16:36:00 -0500 Subject: ath5k: restrict AR5K_TX_QUEUE_ID_DATA_MAX to reflect the [0,3] range This just matches reality... Signed-off-by: John W. Linville Acked-by: Bob Copeland --- drivers/net/wireless/ath/ath5k/ath5k.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 0ee54eb333de..8a06dbd39629 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -513,7 +513,7 @@ enum ath5k_tx_queue_id { AR5K_TX_QUEUE_ID_NOQCU_DATA = 0, AR5K_TX_QUEUE_ID_NOQCU_BEACON = 1, AR5K_TX_QUEUE_ID_DATA_MIN = 0, /*IEEE80211_TX_QUEUE_DATA0*/ - AR5K_TX_QUEUE_ID_DATA_MAX = 4, /*IEEE80211_TX_QUEUE_DATA4*/ + AR5K_TX_QUEUE_ID_DATA_MAX = 3, /*IEEE80211_TX_QUEUE_DATA3*/ AR5K_TX_QUEUE_ID_DATA_SVP = 5, /*IEEE80211_TX_QUEUE_SVP - Spectralink Voice Protocol*/ AR5K_TX_QUEUE_ID_CAB = 6, /*IEEE80211_TX_QUEUE_AFTER_BEACON*/ AR5K_TX_QUEUE_ID_BEACON = 7, /*IEEE80211_TX_QUEUE_BEACON*/ -- cgit v1.2.3 From bd33acc3cc525972ac779067e98efb26516c5b94 Mon Sep 17 00:00:00 2001 From: Amerigo Wang Date: Sun, 6 Mar 2011 21:58:46 +0000 Subject: bonding: move procfs code into bond_procfs.c V2: Move #ifdef CONFIG_PROC_FS into bonding.h, as suggested by David. bond_main.c is bloating, separate the procfs code out, move them to bond_procfs.c Signed-off-by: WANG Cong Reviewed-by: Jiri Pirko Signed-off-by: Andy Gospodarek Signed-off-by: David S. Miller --- drivers/net/bonding/Makefile | 3 + drivers/net/bonding/bond_main.c | 302 +------------------------------------- drivers/net/bonding/bond_procfs.c | 275 ++++++++++++++++++++++++++++++++++ drivers/net/bonding/bonding.h | 26 ++++ 4 files changed, 306 insertions(+), 300 deletions(-) create mode 100644 drivers/net/bonding/bond_procfs.c (limited to 'drivers') diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile index 0e2737eac8b7..3c5c014e82b2 100644 --- a/drivers/net/bonding/Makefile +++ b/drivers/net/bonding/Makefile @@ -6,6 +6,9 @@ obj-$(CONFIG_BONDING) += bonding.o bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o bond_debugfs.o +proc-$(CONFIG_PROC_FS) += bond_procfs.o +bonding-objs += $(proc-y) + ipv6-$(subst m,y,$(CONFIG_IPV6)) += bond_ipv6.o bonding-objs += $(ipv6-y) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 7b7ca971672f..68a5ce0a649f 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -65,8 +65,6 @@ #include #include #include -#include -#include #include #include #include @@ -173,9 +171,6 @@ MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link atomic_t netpoll_block_tx = ATOMIC_INIT(0); #endif -static const char * const version = - DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n"; - int bond_net_id __read_mostly; static __be32 arp_target[BOND_MAX_ARP_TARGETS]; @@ -245,7 +240,7 @@ static void bond_uninit(struct net_device *bond_dev); /*---------------------------- General routines -----------------------------*/ -static const char *bond_mode_name(int mode) +const char *bond_mode_name(int mode) { static const char *names[] = { [BOND_MODE_ROUNDROBIN] = "load balancing (round-robin)", @@ -3288,299 +3283,6 @@ out: read_unlock(&bond->lock); } -/*------------------------------ proc/seq_file-------------------------------*/ - -#ifdef CONFIG_PROC_FS - -static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos) - __acquires(RCU) - __acquires(&bond->lock) -{ - struct bonding *bond = seq->private; - loff_t off = 0; - struct slave *slave; - int i; - - /* make sure the bond won't be taken away */ - rcu_read_lock(); - read_lock(&bond->lock); - - if (*pos == 0) - return SEQ_START_TOKEN; - - bond_for_each_slave(bond, slave, i) { - if (++off == *pos) - return slave; - } - - return NULL; -} - -static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos) -{ - struct bonding *bond = seq->private; - struct slave *slave = v; - - ++*pos; - if (v == SEQ_START_TOKEN) - return bond->first_slave; - - slave = slave->next; - - return (slave == bond->first_slave) ? NULL : slave; -} - -static void bond_info_seq_stop(struct seq_file *seq, void *v) - __releases(&bond->lock) - __releases(RCU) -{ - struct bonding *bond = seq->private; - - read_unlock(&bond->lock); - rcu_read_unlock(); -} - -static void bond_info_show_master(struct seq_file *seq) -{ - struct bonding *bond = seq->private; - struct slave *curr; - int i; - - read_lock(&bond->curr_slave_lock); - curr = bond->curr_active_slave; - read_unlock(&bond->curr_slave_lock); - - seq_printf(seq, "Bonding Mode: %s", - bond_mode_name(bond->params.mode)); - - if (bond->params.mode == BOND_MODE_ACTIVEBACKUP && - bond->params.fail_over_mac) - seq_printf(seq, " (fail_over_mac %s)", - fail_over_mac_tbl[bond->params.fail_over_mac].modename); - - seq_printf(seq, "\n"); - - if (bond->params.mode == BOND_MODE_XOR || - bond->params.mode == BOND_MODE_8023AD) { - seq_printf(seq, "Transmit Hash Policy: %s (%d)\n", - xmit_hashtype_tbl[bond->params.xmit_policy].modename, - bond->params.xmit_policy); - } - - if (USES_PRIMARY(bond->params.mode)) { - seq_printf(seq, "Primary Slave: %s", - (bond->primary_slave) ? - bond->primary_slave->dev->name : "None"); - if (bond->primary_slave) - seq_printf(seq, " (primary_reselect %s)", - pri_reselect_tbl[bond->params.primary_reselect].modename); - - seq_printf(seq, "\nCurrently Active Slave: %s\n", - (curr) ? curr->dev->name : "None"); - } - - seq_printf(seq, "MII Status: %s\n", netif_carrier_ok(bond->dev) ? - "up" : "down"); - seq_printf(seq, "MII Polling Interval (ms): %d\n", bond->params.miimon); - seq_printf(seq, "Up Delay (ms): %d\n", - bond->params.updelay * bond->params.miimon); - seq_printf(seq, "Down Delay (ms): %d\n", - bond->params.downdelay * bond->params.miimon); - - - /* ARP information */ - if (bond->params.arp_interval > 0) { - int printed = 0; - seq_printf(seq, "ARP Polling Interval (ms): %d\n", - bond->params.arp_interval); - - seq_printf(seq, "ARP IP target/s (n.n.n.n form):"); - - for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) { - if (!bond->params.arp_targets[i]) - break; - if (printed) - seq_printf(seq, ","); - seq_printf(seq, " %pI4", &bond->params.arp_targets[i]); - printed = 1; - } - seq_printf(seq, "\n"); - } - - if (bond->params.mode == BOND_MODE_8023AD) { - struct ad_info ad_info; - - seq_puts(seq, "\n802.3ad info\n"); - seq_printf(seq, "LACP rate: %s\n", - (bond->params.lacp_fast) ? "fast" : "slow"); - seq_printf(seq, "Aggregator selection policy (ad_select): %s\n", - ad_select_tbl[bond->params.ad_select].modename); - - if (bond_3ad_get_active_agg_info(bond, &ad_info)) { - seq_printf(seq, "bond %s has no active aggregator\n", - bond->dev->name); - } else { - seq_printf(seq, "Active Aggregator Info:\n"); - - seq_printf(seq, "\tAggregator ID: %d\n", - ad_info.aggregator_id); - seq_printf(seq, "\tNumber of ports: %d\n", - ad_info.ports); - seq_printf(seq, "\tActor Key: %d\n", - ad_info.actor_key); - seq_printf(seq, "\tPartner Key: %d\n", - ad_info.partner_key); - seq_printf(seq, "\tPartner Mac Address: %pM\n", - ad_info.partner_system); - } - } -} - -static void bond_info_show_slave(struct seq_file *seq, - const struct slave *slave) -{ - struct bonding *bond = seq->private; - - seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name); - seq_printf(seq, "MII Status: %s\n", - (slave->link == BOND_LINK_UP) ? "up" : "down"); - seq_printf(seq, "Speed: %d Mbps\n", slave->speed); - seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half"); - seq_printf(seq, "Link Failure Count: %u\n", - slave->link_failure_count); - - seq_printf(seq, "Permanent HW addr: %pM\n", slave->perm_hwaddr); - - if (bond->params.mode == BOND_MODE_8023AD) { - const struct aggregator *agg - = SLAVE_AD_INFO(slave).port.aggregator; - - if (agg) - seq_printf(seq, "Aggregator ID: %d\n", - agg->aggregator_identifier); - else - seq_puts(seq, "Aggregator ID: N/A\n"); - } - seq_printf(seq, "Slave queue ID: %d\n", slave->queue_id); -} - -static int bond_info_seq_show(struct seq_file *seq, void *v) -{ - if (v == SEQ_START_TOKEN) { - seq_printf(seq, "%s\n", version); - bond_info_show_master(seq); - } else - bond_info_show_slave(seq, v); - - return 0; -} - -static const struct seq_operations bond_info_seq_ops = { - .start = bond_info_seq_start, - .next = bond_info_seq_next, - .stop = bond_info_seq_stop, - .show = bond_info_seq_show, -}; - -static int bond_info_open(struct inode *inode, struct file *file) -{ - struct seq_file *seq; - struct proc_dir_entry *proc; - int res; - - res = seq_open(file, &bond_info_seq_ops); - if (!res) { - /* recover the pointer buried in proc_dir_entry data */ - seq = file->private_data; - proc = PDE(inode); - seq->private = proc->data; - } - - return res; -} - -static const struct file_operations bond_info_fops = { - .owner = THIS_MODULE, - .open = bond_info_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -static void bond_create_proc_entry(struct bonding *bond) -{ - struct net_device *bond_dev = bond->dev; - struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id); - - if (bn->proc_dir) { - bond->proc_entry = proc_create_data(bond_dev->name, - S_IRUGO, bn->proc_dir, - &bond_info_fops, bond); - if (bond->proc_entry == NULL) - pr_warning("Warning: Cannot create /proc/net/%s/%s\n", - DRV_NAME, bond_dev->name); - else - memcpy(bond->proc_file_name, bond_dev->name, IFNAMSIZ); - } -} - -static void bond_remove_proc_entry(struct bonding *bond) -{ - struct net_device *bond_dev = bond->dev; - struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id); - - if (bn->proc_dir && bond->proc_entry) { - remove_proc_entry(bond->proc_file_name, bn->proc_dir); - memset(bond->proc_file_name, 0, IFNAMSIZ); - bond->proc_entry = NULL; - } -} - -/* Create the bonding directory under /proc/net, if doesn't exist yet. - * Caller must hold rtnl_lock. - */ -static void __net_init bond_create_proc_dir(struct bond_net *bn) -{ - if (!bn->proc_dir) { - bn->proc_dir = proc_mkdir(DRV_NAME, bn->net->proc_net); - if (!bn->proc_dir) - pr_warning("Warning: cannot create /proc/net/%s\n", - DRV_NAME); - } -} - -/* Destroy the bonding directory under /proc/net, if empty. - * Caller must hold rtnl_lock. - */ -static void __net_exit bond_destroy_proc_dir(struct bond_net *bn) -{ - if (bn->proc_dir) { - remove_proc_entry(DRV_NAME, bn->net->proc_net); - bn->proc_dir = NULL; - } -} - -#else /* !CONFIG_PROC_FS */ - -static void bond_create_proc_entry(struct bonding *bond) -{ -} - -static void bond_remove_proc_entry(struct bonding *bond) -{ -} - -static inline void bond_create_proc_dir(struct bond_net *bn) -{ -} - -static inline void bond_destroy_proc_dir(struct bond_net *bn) -{ -} - -#endif /* CONFIG_PROC_FS */ - - /*-------------------------- netdev event handling --------------------------*/ /* @@ -5384,7 +5086,7 @@ static int __init bonding_init(void) int i; int res; - pr_info("%s", version); + pr_info("%s", bond_version); res = bond_check_params(&bonding_defaults); if (res) diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c new file mode 100644 index 000000000000..c32ff55a34c1 --- /dev/null +++ b/drivers/net/bonding/bond_procfs.c @@ -0,0 +1,275 @@ +#include +#include +#include +#include "bonding.h" + + +extern const char *bond_mode_name(int mode); + +static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos) + __acquires(RCU) + __acquires(&bond->lock) +{ + struct bonding *bond = seq->private; + loff_t off = 0; + struct slave *slave; + int i; + + /* make sure the bond won't be taken away */ + rcu_read_lock(); + read_lock(&bond->lock); + + if (*pos == 0) + return SEQ_START_TOKEN; + + bond_for_each_slave(bond, slave, i) { + if (++off == *pos) + return slave; + } + + return NULL; +} + +static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct bonding *bond = seq->private; + struct slave *slave = v; + + ++*pos; + if (v == SEQ_START_TOKEN) + return bond->first_slave; + + slave = slave->next; + + return (slave == bond->first_slave) ? NULL : slave; +} + +static void bond_info_seq_stop(struct seq_file *seq, void *v) + __releases(&bond->lock) + __releases(RCU) +{ + struct bonding *bond = seq->private; + + read_unlock(&bond->lock); + rcu_read_unlock(); +} + +static void bond_info_show_master(struct seq_file *seq) +{ + struct bonding *bond = seq->private; + struct slave *curr; + int i; + + read_lock(&bond->curr_slave_lock); + curr = bond->curr_active_slave; + read_unlock(&bond->curr_slave_lock); + + seq_printf(seq, "Bonding Mode: %s", + bond_mode_name(bond->params.mode)); + + if (bond->params.mode == BOND_MODE_ACTIVEBACKUP && + bond->params.fail_over_mac) + seq_printf(seq, " (fail_over_mac %s)", + fail_over_mac_tbl[bond->params.fail_over_mac].modename); + + seq_printf(seq, "\n"); + + if (bond->params.mode == BOND_MODE_XOR || + bond->params.mode == BOND_MODE_8023AD) { + seq_printf(seq, "Transmit Hash Policy: %s (%d)\n", + xmit_hashtype_tbl[bond->params.xmit_policy].modename, + bond->params.xmit_policy); + } + + if (USES_PRIMARY(bond->params.mode)) { + seq_printf(seq, "Primary Slave: %s", + (bond->primary_slave) ? + bond->primary_slave->dev->name : "None"); + if (bond->primary_slave) + seq_printf(seq, " (primary_reselect %s)", + pri_reselect_tbl[bond->params.primary_reselect].modename); + + seq_printf(seq, "\nCurrently Active Slave: %s\n", + (curr) ? curr->dev->name : "None"); + } + + seq_printf(seq, "MII Status: %s\n", netif_carrier_ok(bond->dev) ? + "up" : "down"); + seq_printf(seq, "MII Polling Interval (ms): %d\n", bond->params.miimon); + seq_printf(seq, "Up Delay (ms): %d\n", + bond->params.updelay * bond->params.miimon); + seq_printf(seq, "Down Delay (ms): %d\n", + bond->params.downdelay * bond->params.miimon); + + + /* ARP information */ + if (bond->params.arp_interval > 0) { + int printed = 0; + seq_printf(seq, "ARP Polling Interval (ms): %d\n", + bond->params.arp_interval); + + seq_printf(seq, "ARP IP target/s (n.n.n.n form):"); + + for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) { + if (!bond->params.arp_targets[i]) + break; + if (printed) + seq_printf(seq, ","); + seq_printf(seq, " %pI4", &bond->params.arp_targets[i]); + printed = 1; + } + seq_printf(seq, "\n"); + } + + if (bond->params.mode == BOND_MODE_8023AD) { + struct ad_info ad_info; + + seq_puts(seq, "\n802.3ad info\n"); + seq_printf(seq, "LACP rate: %s\n", + (bond->params.lacp_fast) ? "fast" : "slow"); + seq_printf(seq, "Aggregator selection policy (ad_select): %s\n", + ad_select_tbl[bond->params.ad_select].modename); + + if (bond_3ad_get_active_agg_info(bond, &ad_info)) { + seq_printf(seq, "bond %s has no active aggregator\n", + bond->dev->name); + } else { + seq_printf(seq, "Active Aggregator Info:\n"); + + seq_printf(seq, "\tAggregator ID: %d\n", + ad_info.aggregator_id); + seq_printf(seq, "\tNumber of ports: %d\n", + ad_info.ports); + seq_printf(seq, "\tActor Key: %d\n", + ad_info.actor_key); + seq_printf(seq, "\tPartner Key: %d\n", + ad_info.partner_key); + seq_printf(seq, "\tPartner Mac Address: %pM\n", + ad_info.partner_system); + } + } +} + +static void bond_info_show_slave(struct seq_file *seq, + const struct slave *slave) +{ + struct bonding *bond = seq->private; + + seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name); + seq_printf(seq, "MII Status: %s\n", + (slave->link == BOND_LINK_UP) ? "up" : "down"); + seq_printf(seq, "Speed: %d Mbps\n", slave->speed); + seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half"); + seq_printf(seq, "Link Failure Count: %u\n", + slave->link_failure_count); + + seq_printf(seq, "Permanent HW addr: %pM\n", slave->perm_hwaddr); + + if (bond->params.mode == BOND_MODE_8023AD) { + const struct aggregator *agg + = SLAVE_AD_INFO(slave).port.aggregator; + + if (agg) + seq_printf(seq, "Aggregator ID: %d\n", + agg->aggregator_identifier); + else + seq_puts(seq, "Aggregator ID: N/A\n"); + } + seq_printf(seq, "Slave queue ID: %d\n", slave->queue_id); +} + +static int bond_info_seq_show(struct seq_file *seq, void *v) +{ + if (v == SEQ_START_TOKEN) { + seq_printf(seq, "%s\n", bond_version); + bond_info_show_master(seq); + } else + bond_info_show_slave(seq, v); + + return 0; +} + +static const struct seq_operations bond_info_seq_ops = { + .start = bond_info_seq_start, + .next = bond_info_seq_next, + .stop = bond_info_seq_stop, + .show = bond_info_seq_show, +}; + +static int bond_info_open(struct inode *inode, struct file *file) +{ + struct seq_file *seq; + struct proc_dir_entry *proc; + int res; + + res = seq_open(file, &bond_info_seq_ops); + if (!res) { + /* recover the pointer buried in proc_dir_entry data */ + seq = file->private_data; + proc = PDE(inode); + seq->private = proc->data; + } + + return res; +} + +static const struct file_operations bond_info_fops = { + .owner = THIS_MODULE, + .open = bond_info_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +void bond_create_proc_entry(struct bonding *bond) +{ + struct net_device *bond_dev = bond->dev; + struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id); + + if (bn->proc_dir) { + bond->proc_entry = proc_create_data(bond_dev->name, + S_IRUGO, bn->proc_dir, + &bond_info_fops, bond); + if (bond->proc_entry == NULL) + pr_warning("Warning: Cannot create /proc/net/%s/%s\n", + DRV_NAME, bond_dev->name); + else + memcpy(bond->proc_file_name, bond_dev->name, IFNAMSIZ); + } +} + +void bond_remove_proc_entry(struct bonding *bond) +{ + struct net_device *bond_dev = bond->dev; + struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id); + + if (bn->proc_dir && bond->proc_entry) { + remove_proc_entry(bond->proc_file_name, bn->proc_dir); + memset(bond->proc_file_name, 0, IFNAMSIZ); + bond->proc_entry = NULL; + } +} + +/* Create the bonding directory under /proc/net, if doesn't exist yet. + * Caller must hold rtnl_lock. + */ +void __net_init bond_create_proc_dir(struct bond_net *bn) +{ + if (!bn->proc_dir) { + bn->proc_dir = proc_mkdir(DRV_NAME, bn->net->proc_net); + if (!bn->proc_dir) + pr_warning("Warning: cannot create /proc/net/%s\n", + DRV_NAME); + } +} + +/* Destroy the bonding directory under /proc/net, if empty. + * Caller must hold rtnl_lock. + */ +void __net_exit bond_destroy_proc_dir(struct bond_net *bn) +{ + if (bn->proc_dir) { + remove_proc_entry(DRV_NAME, bn->net->proc_net); + bn->proc_dir = NULL; + } +} diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index ff4e26980220..c4e2343bb0b7 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -29,6 +29,8 @@ #define DRV_NAME "bonding" #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" +#define bond_version DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n" + #define BOND_MAX_ARP_TARGETS 16 #define IS_UP(dev) \ @@ -414,6 +416,30 @@ struct bond_net { #endif }; +#ifdef CONFIG_PROC_FS +void bond_create_proc_entry(struct bonding *bond); +void bond_remove_proc_entry(struct bonding *bond); +void bond_create_proc_dir(struct bond_net *bn); +void bond_destroy_proc_dir(struct bond_net *bn); +#else +static inline void bond_create_proc_entry(struct bonding *bond) +{ +} + +static inline void bond_remove_proc_entry(struct bonding *bond) +{ +} + +static inline void bond_create_proc_dir(struct bond_net *bn) +{ +} + +static inline void bond_destroy_proc_dir(struct bond_net *bn) +{ +} +#endif + + /* exported from bond_main.c */ extern int bond_net_id; extern const struct bond_parm_tbl bond_lacp_tbl[]; -- cgit v1.2.3 From d406577526a611e6be1f6b1cfeaf094dd95fa439 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 28 Feb 2011 10:16:29 +0100 Subject: watchdog: sbc_fitpc2_wdt, fix crash on systems without DMI_BOARD_NAME Some systems don't provide DMI_BOARD_NAME in their DMI tables. Avoid crash in such situations in fitpc2_wdt_init. The fix is to check if the dmi_get_system_info return value is NULL. The oops: BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] strstr+0x26/0xa0 PGD 3966e067 PUD 39605067 PMD 0 Oops: 0000 [#1] SMP last sysfs file: /sys/devices/system/cpu/cpu1/cache/index2/shared_cpu_map CPU 1 Modules linked in: ... Pid: 1748, comm: modprobe Not tainted 2.6.37-22-default #1 /Bochs RIP: 0010:[] [] strstr+0x26/0xa0 RSP: 0018:ffff88003ad73f18 EFLAGS: 00010206 RAX: 0000000000000000 RBX: 00000000ffffffed RCX: 00000000ffffffff RDX: ffffffffa003f4cc RSI: ffffffffa003f4c2 RDI: 0000000000000000 ... CR2: 0000000000000000 CR3: 000000003b7ac000 CR4: 00000000000006e0 ... Process modprobe (pid: 1748, threadinfo ffff88003ad72000, task ffff88002e6365c0) Stack: ... Call Trace: [] fitpc2_wdt_init+0x1f/0x13c [sbc_fitpc2_wdt] [] do_one_initcall+0x3a/0x170 ... Code: f3 c3 0f 1f 00 80 3e 00 53 48 89 f8 74 1b 48 89 f2 0f 1f 40 00 48 83 c2 01 80 3a 00 75 f7 49 89 d0 48 89 f8 49 29 f0 75 02 5b c3 <80> 3f 00 74 0e 0f 1f 44 00 00 48 83 c0 01 80 38 00 75 f7 49 89 Signed-off-by: Jiri Slaby Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/sbc_fitpc2_wdt.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/sbc_fitpc2_wdt.c b/drivers/watchdog/sbc_fitpc2_wdt.c index c7d67e9a7465..79906255eeb6 100644 --- a/drivers/watchdog/sbc_fitpc2_wdt.c +++ b/drivers/watchdog/sbc_fitpc2_wdt.c @@ -201,11 +201,14 @@ static struct miscdevice fitpc2_wdt_miscdev = { static int __init fitpc2_wdt_init(void) { int err; + const char *brd_name; - if (!strstr(dmi_get_system_info(DMI_BOARD_NAME), "SBC-FITPC2")) + brd_name = dmi_get_system_info(DMI_BOARD_NAME); + + if (!brd_name || !strstr(brd_name, "SBC-FITPC2")) return -ENODEV; - pr_info("%s found\n", dmi_get_system_info(DMI_BOARD_NAME)); + pr_info("%s found\n", brd_name); if (!request_region(COMMAND_PORT, 1, WATCHDOG_NAME)) { pr_err("I/O address 0x%04x already in use\n", COMMAND_PORT); -- cgit v1.2.3 From 1f15318cdae665550746e7fcdfe5ef41bf2360af Mon Sep 17 00:00:00 2001 From: Hao Wu Date: Wed, 9 Mar 2011 12:41:08 +0000 Subject: USB OTG Langwell: use simple IPC command to control VBus power. Direct access to PMIC register is not safe and will impact battery charging. New IPC command supported in SCU FW for VBus power control. USB OTG driver will switch to such commands instead of direct access to PMIC register for safety and SCU FW will handle the actual work after got the request(IPC command). Due to this change, usb driver should wait more time for sync OTGSC with USBCFG by SCU. Update wait time from 2ms to 5ms. Signed-off-by: Hao Wu Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/usb/otg/langwell_otg.c | 48 ++++++++++-------------------------------- 1 file changed, 11 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c index 9fea48264fa2..7f9b8cd4514b 100644 --- a/drivers/usb/otg/langwell_otg.c +++ b/drivers/usb/otg/langwell_otg.c @@ -174,50 +174,24 @@ static int langwell_otg_set_power(struct otg_transceiver *otg, return 0; } -/* A-device drives vbus, controlled through PMIC CHRGCNTL register*/ +/* A-device drives vbus, controlled through IPC commands */ static int langwell_otg_set_vbus(struct otg_transceiver *otg, bool enabled) { struct langwell_otg *lnw = the_transceiver; - u8 r; + u8 sub_id; dev_dbg(lnw->dev, "%s <--- %s\n", __func__, enabled ? "on" : "off"); - /* FIXME: surely we should cache this on the first read. If not use - readv to avoid two transactions */ - if (intel_scu_ipc_ioread8(0x00, &r) < 0) { - dev_dbg(lnw->dev, "Failed to read PMIC register 0xD2"); - return -EBUSY; - } - if ((r & 0x03) != 0x02) { - dev_dbg(lnw->dev, "not NEC PMIC attached\n"); - return -EBUSY; - } - - if (intel_scu_ipc_ioread8(0x20, &r) < 0) { - dev_dbg(lnw->dev, "Failed to read PMIC register 0xD2"); - return -EBUSY; - } - - if ((r & 0x20) == 0) { - dev_dbg(lnw->dev, "no battery attached\n"); - return -EBUSY; - } + if (enabled) + sub_id = 0x8; /* Turn on the VBus */ + else + sub_id = 0x9; /* Turn off the VBus */ - /* Workaround for battery attachment issue */ - if (r == 0x34) { - dev_dbg(lnw->dev, "no battery attached on SH\n"); + if (intel_scu_ipc_simple_command(0xef, sub_id)) { + dev_dbg(lnw->dev, "Failed to set Vbus via IPC commands\n"); return -EBUSY; } - dev_dbg(lnw->dev, "battery attached. 2 reg = %x\n", r); - - /* workaround: FW detect writing 0x20/0xc0 to d4 event. - * this is only for NEC PMIC. - */ - - if (intel_scu_ipc_iowrite8(0xD4, enabled ? 0x20 : 0xC0)) - dev_dbg(lnw->dev, "Failed to write PMIC.\n"); - dev_dbg(lnw->dev, "%s --->\n", __func__); return 0; @@ -394,14 +368,14 @@ static void langwell_otg_phy_low_power(int on) dev_dbg(lnw->dev, "%s <--- done\n", __func__); } -/* After drv vbus, add 2 ms delay to set PHCD */ +/* After drv vbus, add 5 ms delay to set PHCD */ static void langwell_otg_phy_low_power_wait(int on) { struct langwell_otg *lnw = the_transceiver; - dev_dbg(lnw->dev, "add 2ms delay before programing PHCD\n"); + dev_dbg(lnw->dev, "add 5ms delay before programing PHCD\n"); - mdelay(2); + mdelay(5); langwell_otg_phy_low_power(on); } -- cgit v1.2.3 From 7a89e4cb9cdaba92f5fbc509945cf4e3c48db4e2 Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Wed, 9 Mar 2011 09:19:48 +0000 Subject: USB: serial: option: Apply OPTION_BLACKLIST_SENDSETUP also for ZTE MF626 On https://bugs.launchpad.net/ubuntu/+source/linux/+bug/636091, one of the cases reported is a big timeout on option_send_setup, which causes some side effects as tty_lock is held. Looks like some of ZTE MF626 devices also don't like the RTS/DTR setting in option_send_setup, like with 4G XS Stick W14. The reporter confirms which this it solves the long freezes in his system. Signed-off-by: Herton Ronaldo Krzesinski Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 5f46838dfee5..75c7f456eed5 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -652,7 +652,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0028, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0029, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0030, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff, + 0xff, 0xff), .driver_info = (kernel_ulong_t)&four_g_w14_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0032, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0033, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0034, 0xff, 0xff, 0xff) }, -- cgit v1.2.3 From b88ccf6f97ceb3f34cecbb513edc58815707187d Mon Sep 17 00:00:00 2001 From: JF Argentino Date: Wed, 9 Mar 2011 22:13:20 +0100 Subject: USB: serial: ftdi_sio: adding support for OLIMEX ARM-USB-OCD-H Adding support for the OLIMEX ARM-USB-OCD-H JTAG device (id 15ba:002b) based on FTDI FT2232H Signed-off-by: JF Argentino Acked-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 2 ++ drivers/usb/serial/ftdi_sio_ids.h | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 5a446710fb79..a75f9298d88f 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -722,6 +722,8 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) }, { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(FIC_VID, FIC_NEO1973_DEBUG_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(FTDI_VID, FTDI_OOCDLINK_PID), diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 117e8e6f93c6..c543e55bafba 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -730,6 +730,7 @@ /* Olimex */ #define OLIMEX_VID 0x15BA #define OLIMEX_ARM_USB_OCD_PID 0x0003 +#define OLIMEX_ARM_USB_OCD_H_PID 0x002b /* * Telldus Technologies -- cgit v1.2.3 From ed43b47b29bce303f86e1bff69b6f9924f5afcc4 Mon Sep 17 00:00:00 2001 From: Eric Bénard Date: Wed, 9 Mar 2011 19:24:49 +0100 Subject: n_gsm: fix UIH control byte : P bit should be 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * the GSM 07.10 specification says in 5.4.3.1 that 'both stations shall set the P bit to 0' thanks to Alan Cox for finding this explanation in the spec * without this fix, on Telit & Sim.com modems, opening a new DLC randomly fails. Not setting PF bit of the control byte gives a reliable behaviour on these modems. Signed-off-by: Eric Bénard Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 0d90be48463d..176f63256b37 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -1250,8 +1250,7 @@ static void gsm_control_response(struct gsm_mux *gsm, unsigned int command, static void gsm_control_transmit(struct gsm_mux *gsm, struct gsm_control *ctrl) { - struct gsm_msg *msg = gsm_data_alloc(gsm, 0, ctrl->len + 1, - gsm->ftype|PF); + struct gsm_msg *msg = gsm_data_alloc(gsm, 0, ctrl->len + 1, gsm->ftype); if (msg == NULL) return; msg->data[0] = (ctrl->cmd << 1) | 2 | EA; /* command */ -- cgit v1.2.3 From 762bf6dedd7159ea0b6c8150e342b6299e6dd39b Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Wed, 9 Mar 2011 00:38:23 +0900 Subject: staging: rtl8192e: Pass priv to rtl819xE_tx_cmd Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 597c12de71d0..d92a565f6441 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -103,7 +103,7 @@ static void rtl8192_irq_rx_tasklet(unsigned long arg); static void rtl8192_irq_tx_tasklet(unsigned long arg); static void rtl8192_prepare_beacon(unsigned long arg); static irqreturn_t rtl8192_interrupt(int irq, void *netdev); -static void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb); +static void rtl819xE_tx_cmd(struct r8192_priv *priv, struct sk_buff *skb); static void rtl8192_update_ratr_table(struct r8192_priv *priv); static void rtl8192_restart(struct work_struct *work); static void watch_dog_timer_callback(unsigned long data); @@ -879,7 +879,7 @@ static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev) memcpy(skb->cb, &dev, sizeof(dev)); if (queue_index == TXCMD_QUEUE) { - rtl819xE_tx_cmd(dev, skb); + rtl819xE_tx_cmd(priv, skb); ret = 0; return ret; } else { @@ -1050,9 +1050,8 @@ static void rtl8192_net_update(struct r8192_priv *priv) } } -static void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb) +static void rtl819xE_tx_cmd(struct r8192_priv *priv, struct sk_buff *skb) { - struct r8192_priv *priv = ieee80211_priv(dev); struct rtl8192_tx_ring *ring; tx_desc_819x_pci *entry; unsigned int idx; -- cgit v1.2.3 From 9633608f5945629bee9f47190c072fab3ac9b719 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Wed, 9 Mar 2011 00:38:37 +0900 Subject: staging: rtl8192e: Pass priv to TranslateRxSignalStuff819xpci Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index d92a565f6441..f4d76314a0c4 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -4266,14 +4266,13 @@ rtl8192_record_rxdesc_forlateruse( -static void TranslateRxSignalStuff819xpci(struct net_device *dev, +static void TranslateRxSignalStuff819xpci(struct r8192_priv *priv, struct sk_buff *skb, struct ieee80211_rx_stats * pstats, prx_desc_819x_pci pdesc, prx_fwinfo_819x_pci pdrvinfo) { // TODO: We must only check packet for current MAC address. Not finish - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); bool bpacket_match_bssid, bpacket_toself; bool bPacketBeacon=false, bToSelfBA=false; struct ieee80211_hdr_3addr *hdr; @@ -4304,7 +4303,7 @@ static void TranslateRxSignalStuff819xpci(struct net_device *dev, } if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK) { - if((!compare_ether_addr(praddr,dev->dev_addr))) + if (!compare_ether_addr(praddr, priv->ieee80211->dev->dev_addr)) bToSelfBA = true; } @@ -4505,7 +4504,7 @@ static void rtl8192_rx(struct net_device *dev) stats.RxIs40MHzPacket = pDrvInfo->BW; /* ???? */ - TranslateRxSignalStuff819xpci(dev,skb, &stats, pdesc, pDrvInfo); + TranslateRxSignalStuff819xpci(priv, skb, &stats, pdesc, pDrvInfo); /* Rx A-MPDU */ if(pDrvInfo->FirstAGGR==1 || pDrvInfo->PartAggr == 1) -- cgit v1.2.3 From e26174864a565bca76657a7a468bc14465822f7c Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Wed, 9 Mar 2011 00:38:56 +0900 Subject: staging: rtl8192e: Pass priv to UpdateReceivedRateHistogramStatistics8190 Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index f4d76314a0c4..ee1fb007abdc 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -4362,11 +4362,10 @@ static void rtl8192_irq_tx_tasklet(unsigned long arg) /* Record the received data rate */ static void UpdateReceivedRateHistogramStatistics8190( - struct net_device *dev, + struct r8192_priv *priv, struct ieee80211_rx_stats* pstats ) { - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV u32 rateIndex; u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI @@ -4485,7 +4484,7 @@ static void rtl8192_rx(struct net_device *dev) /* it is debug only. It should be disabled in released driver. * 2007.1.11 by Emily * */ - UpdateReceivedRateHistogramStatistics8190(dev, &stats); + UpdateReceivedRateHistogramStatistics8190(priv, &stats); stats.bIsAMPDU = (pDrvInfo->PartAggr==1); stats.bFirstMPDU = (pDrvInfo->PartAggr==1) && (pDrvInfo->FirstAGGR==1); -- cgit v1.2.3 From 58f6b58ee2a53a0836fa6844d07832a101d10ead Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Wed, 9 Mar 2011 00:39:05 +0900 Subject: staging: rtl8192e: Pass priv to IPSLeave Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 2 +- drivers/staging/rtl8192e/r8192E_core.c | 10 ++++------ drivers/staging/rtl8192e/r8192E_wx.c | 12 ++++++------ 3 files changed, 11 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 2b70d0d4985d..9f15e7785e0b 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1128,7 +1128,7 @@ RT_STATUS cmpk_message_handle_tx(struct net_device *dev, u8* codevirtualaddress, #ifdef ENABLE_IPS void IPSEnter(struct net_device *dev); -void IPSLeave(struct net_device *dev); +void IPSLeave(struct r8192_priv *priv); void IPSLeave_wq(struct work_struct *work); void ieee80211_ips_leave_wq(struct net_device *dev); void ieee80211_ips_leave(struct net_device *dev); diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index ee1fb007abdc..785045e8db1e 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -3173,10 +3173,8 @@ IPSEnter(struct net_device *dev) // Leave the inactive power save mode, RF will be on. // 2007.08.17, by shien chang. // -void -IPSLeave(struct net_device *dev) +void IPSLeave(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; RT_RF_POWER_STATE rtState; @@ -3199,7 +3197,7 @@ void IPSLeave_wq(struct work_struct *work) struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); down(&priv->ieee80211->ips_sem); - IPSLeave(dev); + IPSLeave(priv); up(&priv->ieee80211->ips_sem); } @@ -3228,7 +3226,7 @@ void ieee80211_ips_leave(struct net_device *dev) { struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); down(&priv->ieee80211->ips_sem); - IPSLeave(dev); + IPSLeave(priv); up(&priv->ieee80211->ips_sem); } #endif @@ -4981,7 +4979,7 @@ void setKey( struct net_device *dev, } else{ down(&priv->ieee80211->ips_sem); - IPSLeave(dev); + IPSLeave(priv); up(&priv->ieee80211->ips_sem); } } diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c index 57d97adf1259..2d20b9a9a287 100644 --- a/drivers/staging/rtl8192e/r8192E_wx.c +++ b/drivers/staging/rtl8192e/r8192E_wx.c @@ -231,7 +231,7 @@ static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a, else{ RT_TRACE(COMP_ERR, "%s(): IPSLeave\n",__FUNCTION__); down(&priv->ieee80211->ips_sem); - IPSLeave(dev); + IPSLeave(priv); up(&priv->ieee80211->ips_sem); } } @@ -417,7 +417,7 @@ static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a, else{ //RT_TRACE(COMP_PS, "%s(): IPSLeave\n",__FUNCTION__); down(&priv->ieee80211->ips_sem); - IPSLeave(dev); + IPSLeave(priv); up(&priv->ieee80211->ips_sem); } } @@ -480,7 +480,7 @@ static int r8192_wx_set_essid(struct net_device *dev, #ifdef ENABLE_IPS down(&priv->ieee80211->ips_sem); - IPSLeave(dev); + IPSLeave(priv); up(&priv->ieee80211->ips_sem); #endif ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b); @@ -590,7 +590,7 @@ static int r8192_wx_set_wap(struct net_device *dev, #ifdef ENABLE_IPS down(&priv->ieee80211->ips_sem); - IPSLeave(dev); + IPSLeave(priv); up(&priv->ieee80211->ips_sem); #endif ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra); @@ -647,7 +647,7 @@ static int r8192_wx_set_enc(struct net_device *dev, priv->ieee80211->wx_set_enc = 1; #ifdef ENABLE_IPS down(&priv->ieee80211->ips_sem); - IPSLeave(dev); + IPSLeave(priv); up(&priv->ieee80211->ips_sem); #endif @@ -869,7 +869,7 @@ static int r8192_wx_set_enc_ext(struct net_device *dev, #ifdef ENABLE_IPS down(&priv->ieee80211->ips_sem); - IPSLeave(dev); + IPSLeave(priv); up(&priv->ieee80211->ips_sem); #endif -- cgit v1.2.3 From e676ae5886c02a5cc48cace5b8e72d44d6e54ee1 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Wed, 9 Mar 2011 00:39:14 +0900 Subject: staging: rtl8192e: Pass priv to IPSEnter Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 2 +- drivers/staging/rtl8192e/r8192E_core.c | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 9f15e7785e0b..4aefbc3d1fdb 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1127,7 +1127,7 @@ void firmware_init_param(struct net_device *dev); RT_STATUS cmpk_message_handle_tx(struct net_device *dev, u8* codevirtualaddress, u32 packettype, u32 buffer_len); #ifdef ENABLE_IPS -void IPSEnter(struct net_device *dev); +void IPSEnter(struct r8192_priv *priv); void IPSLeave(struct r8192_priv *priv); void IPSLeave_wq(struct work_struct *work); void ieee80211_ips_leave_wq(struct net_device *dev); diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 785045e8db1e..93e9e673919b 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -3138,10 +3138,8 @@ void LeisurePSLeave(struct net_device *dev) /* Enter the inactive power save mode. RF will be off */ -void -IPSEnter(struct net_device *dev) +void IPSEnter(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; RT_RF_POWER_STATE rtState; @@ -3275,7 +3273,7 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) (priv->eRFPowerState == eRfOn) && !ieee->is_set_key && (!ieee->proto_stoppping) && !ieee->wx_set_enc){ if (priv->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){ - IPSEnter(dev); + IPSEnter(priv); } } } -- cgit v1.2.3 From 282fa9f3fb7eaf0b87903ff6267fcd2ae51e314a Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Wed, 9 Mar 2011 00:39:23 +0900 Subject: staging: rtl8192e: Pass priv to EnableHWSecurityConfig8192 Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 2 +- drivers/staging/rtl8192e/r8192E_core.c | 7 +++---- drivers/staging/rtl8192e/r8192E_wx.c | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 4aefbc3d1fdb..26b2e5892e58 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1121,7 +1121,7 @@ int rtl8192_up(struct net_device *dev); void rtl8192_commit(struct r8192_priv *priv); void write_phy(struct net_device *dev, u8 adr, u8 data); void CamResetAllEntry(struct r8192_priv *priv); -void EnableHWSecurityConfig8192(struct net_device *dev); +void EnableHWSecurityConfig8192(struct r8192_priv *priv); void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent ); void firmware_init_param(struct net_device *dev); RT_STATUS cmpk_message_handle_tx(struct net_device *dev, u8* codevirtualaddress, u32 packettype, u32 buffer_len); diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 93e9e673919b..1028d434dd39 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1488,7 +1488,7 @@ static void rtl8192_link_change(struct net_device *dev) //add this as in pure N mode, wep encryption will use software way, but there is no chance to set this as wep will not set group key in wext. WB.2008.07.08 if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) - EnableHWSecurityConfig8192(dev); + EnableHWSecurityConfig8192(priv); } else { @@ -3561,7 +3561,7 @@ static void r8192e_set_hw_key(struct r8192_priv *priv, struct ieee_param *ipw) if (ieee->pairwise_key_type) { memcpy(key, ipw->u.crypt.key, 16); - EnableHWSecurityConfig8192(dev); + EnableHWSecurityConfig8192(priv); /* * We fill both index entry and 4th entry for pairwise * key as in IPW interface, adhoc will only get here, @@ -4913,10 +4913,9 @@ out_unlock: return ret; } -void EnableHWSecurityConfig8192(struct net_device *dev) +void EnableHWSecurityConfig8192(struct r8192_priv *priv) { u8 SECR_value = 0x0; - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); struct ieee80211_device* ieee = priv->ieee80211; SECR_value = SCR_TxEncEnable | SCR_RxDecEnable; diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c index 2d20b9a9a287..b51842bd3faf 100644 --- a/drivers/staging/rtl8192e/r8192E_wx.c +++ b/drivers/staging/rtl8192e/r8192E_wx.c @@ -685,7 +685,7 @@ static int r8192_wx_set_enc(struct net_device *dev, //printk("-------====>length:%d, key_idx:%d, flag:%x\n", wrqu->encoding.length, key_idx, wrqu->encoding.flags); if(wrqu->encoding.length==0x5){ ieee->pairwise_key_type = KEY_TYPE_WEP40; - EnableHWSecurityConfig8192(dev); + EnableHWSecurityConfig8192(priv); setKey( dev, key_idx, //EntryNo key_idx, //KeyIndex @@ -697,7 +697,7 @@ static int r8192_wx_set_enc(struct net_device *dev, else if(wrqu->encoding.length==0xd){ ieee->pairwise_key_type = KEY_TYPE_WEP104; - EnableHWSecurityConfig8192(dev); + EnableHWSecurityConfig8192(priv); setKey( dev, key_idx, //EntryNo key_idx, //KeyIndex @@ -901,7 +901,7 @@ static int r8192_wx_set_enc_ext(struct net_device *dev, if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) ) alg = KEY_TYPE_WEP104; ieee->pairwise_key_type = alg; - EnableHWSecurityConfig8192(dev); + EnableHWSecurityConfig8192(priv); } memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1 -- cgit v1.2.3 From 043dfdd3c10ff39c4e21a605d191bb75f10a508e Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Wed, 9 Mar 2011 00:39:32 +0900 Subject: staging: rtl8192e: Pass priv to SetKey Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 3 ++- drivers/staging/rtl8192e/r8192E_core.c | 20 ++++++---------- drivers/staging/rtl8192e/r8192E_wx.c | 43 +++++++--------------------------- 3 files changed, 17 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 26b2e5892e58..c18705ff8160 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1122,7 +1122,8 @@ void rtl8192_commit(struct r8192_priv *priv); void write_phy(struct net_device *dev, u8 adr, u8 data); void CamResetAllEntry(struct r8192_priv *priv); void EnableHWSecurityConfig8192(struct r8192_priv *priv); -void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent ); +void setKey(struct r8192_priv *priv, u8 EntryNo, u8 KeyIndex, u16 KeyType, + const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent); void firmware_init_param(struct net_device *dev); RT_STATUS cmpk_message_handle_tx(struct net_device *dev, u8* codevirtualaddress, u32 packettype, u32 buffer_len); diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 1028d434dd39..04e6bdc94734 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -3542,7 +3542,6 @@ static int r8192_set_mac_adr(struct net_device *dev, void *mac) static void r8192e_set_hw_key(struct r8192_priv *priv, struct ieee_param *ipw) { struct ieee80211_device *ieee = priv->ieee80211; - struct net_device *dev = priv->ieee80211->dev; u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; u32 key[4]; @@ -3567,13 +3566,13 @@ static void r8192e_set_hw_key(struct r8192_priv *priv, struct ieee_param *ipw) * key as in IPW interface, adhoc will only get here, * so we need index entry for its default key serching! */ - setKey(dev, 4, ipw->u.crypt.idx, + setKey(priv, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key); /* LEAP WEP will never set this. */ if (ieee->auth_mode != 2) - setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, + setKey(priv, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key); } @@ -3596,7 +3595,7 @@ static void r8192e_set_hw_key(struct r8192_priv *priv, struct ieee_param *ipw) ieee->group_key_type = KEY_TYPE_NA; if (ieee->group_key_type) { - setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, + setKey(priv, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->group_key_type, broadcast_addr, 0, key); } } @@ -4950,21 +4949,16 @@ void EnableHWSecurityConfig8192(struct r8192_priv *priv) } #define TOTAL_CAM_ENTRY 32 //#define CAM_CONTENT_COUNT 8 -void setKey( struct net_device *dev, - u8 EntryNo, - u8 KeyIndex, - u16 KeyType, - const u8 *MacAddr, - u8 DefaultKey, - u32 *KeyContent ) +void setKey(struct r8192_priv *priv, u8 EntryNo, u8 KeyIndex, u16 KeyType, + const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent) { u32 TargetCommand = 0; u32 TargetContent = 0; u16 usConfig = 0; u8 i; #ifdef ENABLE_IPS - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); RT_RF_POWER_STATE rtState; + rtState = priv->eRFPowerState; if (priv->PowerSaveControl.bInactivePs){ if(rtState == eRfOff){ @@ -4986,7 +4980,7 @@ void setKey( struct net_device *dev, if (EntryNo >= TOTAL_CAM_ENTRY) RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n"); - RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr); + RT_TRACE(COMP_SEC, "====>to setKey(), priv:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", priv, EntryNo, KeyIndex, KeyType, MacAddr); if (DefaultKey) usConfig |= BIT15 | (KeyType<<2); diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c index b51842bd3faf..f76377602da6 100644 --- a/drivers/staging/rtl8192e/r8192E_wx.c +++ b/drivers/staging/rtl8192e/r8192E_wx.c @@ -686,25 +686,15 @@ static int r8192_wx_set_enc(struct net_device *dev, if(wrqu->encoding.length==0x5){ ieee->pairwise_key_type = KEY_TYPE_WEP40; EnableHWSecurityConfig8192(priv); - setKey( dev, - key_idx, //EntryNo - key_idx, //KeyIndex - KEY_TYPE_WEP40, //KeyType - zero_addr[key_idx], - 0, //DefaultKey - hwkey); //KeyContent + setKey(priv, key_idx, key_idx, KEY_TYPE_WEP40, + zero_addr[key_idx], 0, hwkey); } else if(wrqu->encoding.length==0xd){ ieee->pairwise_key_type = KEY_TYPE_WEP104; EnableHWSecurityConfig8192(priv); - setKey( dev, - key_idx, //EntryNo - key_idx, //KeyIndex - KEY_TYPE_WEP104, //KeyType - zero_addr[key_idx], - 0, //DefaultKey - hwkey); //KeyContent + setKey(priv, key_idx, key_idx, KEY_TYPE_WEP104, + zero_addr[key_idx], 0, hwkey); } else printk("wrong type in WEP, not WEP40 and WEP104\n"); } @@ -909,37 +899,20 @@ static int r8192_wx_set_enc_ext(struct net_device *dev, { if (ext->key_len == 13) ieee->pairwise_key_type = alg = KEY_TYPE_WEP104; - setKey( dev, - idx,//EntryNo - idx, //KeyIndex - alg, //KeyType - zero, //MacAddr - 0, //DefaultKey - key); //KeyContent + setKey(priv, idx, idx, alg, zero, 0, key); } else if (group) { ieee->group_key_type = alg; - setKey( dev, - idx,//EntryNo - idx, //KeyIndex - alg, //KeyType - broadcast_addr, //MacAddr - 0, //DefaultKey - key); //KeyContent + setKey(priv, idx, idx, alg, broadcast_addr, 0, key); } else //pairwise key { if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){ write_nic_byte(priv, 0x173, 1); //fix aes bug } - setKey( dev, - 4,//EntryNo - idx, //KeyIndex - alg, //KeyType - (u8*)ieee->ap_mac_addr, //MacAddr - 0, //DefaultKey - key); //KeyContent + setKey(priv, 4, idx, alg, + (u8*)ieee->ap_mac_addr, 0, key); } -- cgit v1.2.3 From 95a9a6538cbd23532aa711981748b21923db407f Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Wed, 9 Mar 2011 00:39:53 +0900 Subject: staging: rtl8192e: Pass priv to UpdateRxPktTimeStamp8190 Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 04e6bdc94734..9d9ddcc67a4b 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -3703,9 +3703,8 @@ static u8 HwRateToMRate90(bool bIsHT, u8 rate) } /* Record the TSF time stamp when receiving a packet */ -static void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats) +static void UpdateRxPktTimeStamp8190(struct r8192_priv *priv, struct ieee80211_rx_stats *stats) { - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); if(stats->bIsAMPDU && !stats->bFirstMPDU) { stats->mac_time[0] = priv->LastRxDescTSFLow; @@ -4487,7 +4486,7 @@ static void rtl8192_rx(struct net_device *dev) stats.TimeStampLow = pDrvInfo->TSFL; stats.TimeStampHigh = read_nic_dword(priv, TSFR+4); - UpdateRxPktTimeStamp8190(dev, &stats); + UpdateRxPktTimeStamp8190(priv, &stats); // // Get Total offset of MPDU Frame Body -- cgit v1.2.3 From 176e8dc1310ecf430294ac413cd29a6b4d99a6fe Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Wed, 9 Mar 2011 00:40:06 +0900 Subject: staging: rtl8192e: Pass priv to rtl8192_hw_sleep_down Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 9d9ddcc67a4b..f08bb6b94d8a 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1824,9 +1824,8 @@ static short rtl8192_is_tx_queue_empty(struct net_device *dev) return 1; } -static void rtl8192_hw_sleep_down(struct net_device *dev) +static void rtl8192_hw_sleep_down(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); MgntActSet_RF_State(priv, eRfSleep, RF_CHANGE_BY_PS); } @@ -1879,7 +1878,7 @@ static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl) queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq,tmp); - rtl8192_hw_sleep_down(dev); + rtl8192_hw_sleep_down(priv); } static void rtl8192_init_priv_variable(struct r8192_priv *priv) -- cgit v1.2.3 From 7703f04dafd8705b6fa234e784d1a23c4b641f3d Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Wed, 9 Mar 2011 00:40:15 +0900 Subject: staging: rtl8192e: Pass priv to rtl8192_tx_resume Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index f08bb6b94d8a..1c10f16e3fb7 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -4313,10 +4313,10 @@ static void TranslateRxSignalStuff819xpci(struct r8192_priv *priv, } -static void rtl8192_tx_resume(struct net_device *dev) +static void rtl8192_tx_resume(struct r8192_priv *priv) { - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); struct ieee80211_device *ieee = priv->ieee80211; + struct net_device *dev = priv->ieee80211->dev; struct sk_buff *skb; int queue_index; @@ -4350,7 +4350,7 @@ static void rtl8192_irq_tx_tasklet(unsigned long arg) spin_unlock_irqrestore(&priv->irq_th_lock, flags); - rtl8192_tx_resume(dev); + rtl8192_tx_resume(priv); } /* Record the received data rate */ -- cgit v1.2.3 From 679a2494fbe357dc81c97a6097d70e53cd2e5b3f Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Wed, 9 Mar 2011 00:40:24 +0900 Subject: staging: rtl8192e: Pass priv to MgntActSet_802_11_PowerSaveMode Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 1c10f16e3fb7..9bb5bbaef7b1 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -3046,9 +3046,8 @@ static void InactivePsWorkItemCallback(struct r8192_priv *priv) #ifdef ENABLE_LPS /* Change current and default preamble mode. */ -bool MgntActSet_802_11_PowerSaveMode(struct net_device *dev, u8 rtPsMode) +bool MgntActSet_802_11_PowerSaveMode(struct r8192_priv *priv, u8 rtPsMode) { - struct r8192_priv *priv = ieee80211_priv(dev); // Currently, we do not change power save mode on IBSS mode. if(priv->ieee80211->iw_mode == IW_MODE_ADHOC) @@ -3075,7 +3074,7 @@ bool MgntActSet_802_11_PowerSaveMode(struct net_device *dev, u8 rtPsMode) if(priv->ieee80211->sta_sleep != 0 && rtPsMode == IEEE80211_PS_DISABLED) { // Notify the AP we awke. - rtl8192_hw_wakeup(dev); + rtl8192_hw_wakeup(priv->ieee80211->dev); priv->ieee80211->sta_sleep = 0; spin_lock(&priv->ieee80211->mgmt_tx_lock); @@ -3107,7 +3106,7 @@ void LeisurePSEnter(struct net_device *dev) if(priv->ieee80211->ps == IEEE80211_PS_DISABLED) { - MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST); + MgntActSet_802_11_PowerSaveMode(priv, IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST); } } @@ -3128,7 +3127,7 @@ void LeisurePSLeave(struct net_device *dev) if(priv->ieee80211->ps != IEEE80211_PS_DISABLED) { // move to lps_wakecomplete() - MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_DISABLED); + MgntActSet_802_11_PowerSaveMode(priv, IEEE80211_PS_DISABLED); } } -- cgit v1.2.3 From c62fdce2f78b7571e83954bb0aaabdd0e6880a82 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Wed, 9 Mar 2011 00:40:33 +0900 Subject: staging: rtl8192e: Pass priv to rtl8192_init Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 9bb5bbaef7b1..f742eb2628dc 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -2416,9 +2416,10 @@ static short rtl8192_get_channel_map(struct r8192_priv *priv) return 0; } -static short rtl8192_init(struct net_device *dev) +static short rtl8192_init(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); + struct net_device *dev = priv->ieee80211->dev; + memset(&(priv->stats),0,sizeof(struct Stats)); rtl8192_init_priv_variable(priv); rtl8192_init_priv_lock(priv); @@ -4655,7 +4656,7 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, } RT_TRACE(COMP_INIT, "Driver probe completed1\n"); - if(rtl8192_init(dev)!=0){ + if (rtl8192_init(priv)!=0) { RT_TRACE(COMP_ERR, "Initialization failed\n"); goto fail; } -- cgit v1.2.3 From ddd877b2e19de8c73d67b57f9a117b51e8ddfec8 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Wed, 9 Mar 2011 00:40:44 +0900 Subject: staging: rtl8192e: Pass priv to rtl8192_rx Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index f742eb2628dc..a3fcbae8365c 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -4418,9 +4418,8 @@ static void UpdateReceivedRateHistogramStatistics8190( priv->stats.received_rate_histogram[rcvType][rateIndex]++; } -static void rtl8192_rx(struct net_device *dev) +static void rtl8192_rx(struct r8192_priv *priv) { - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); struct ieee80211_hdr_1addr *ieee80211_hdr = NULL; bool unicast_packet = false; struct ieee80211_rx_stats stats = { @@ -4551,7 +4550,7 @@ done: static void rtl8192_irq_rx_tasklet(unsigned long arg) { struct r8192_priv *priv = (struct r8192_priv*) arg; - rtl8192_rx(priv->ieee80211->dev); + rtl8192_rx(priv); /* unmask RDU */ write_nic_dword(priv, INTA_MASK, read_nic_dword(priv, INTA_MASK) | IMR_RDU); } -- cgit v1.2.3 From 1f0e427007d2dc3679faecdf61aaf8673abbb5e8 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Wed, 9 Mar 2011 00:40:56 +0900 Subject: staging: rtl8192e: Pass priv to watch_dog_timer_callback Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index a3fcbae8365c..06b35a234b49 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -2429,7 +2429,7 @@ static short rtl8192_init(struct r8192_priv *priv) rtl8192_get_channel_map(priv); init_hal_dm(dev); init_timer(&priv->watch_dog_timer); - priv->watch_dog_timer.data = (unsigned long)dev; + priv->watch_dog_timer.data = (unsigned long)priv; priv->watch_dog_timer.function = watch_dog_timer_callback; if (request_irq(dev->irq, rtl8192_interrupt, IRQF_SHARED, dev->name, dev)) { printk("Error allocating IRQ %d",dev->irq); @@ -3379,7 +3379,7 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) void watch_dog_timer_callback(unsigned long data) { - struct r8192_priv *priv = ieee80211_priv((struct net_device *) data); + struct r8192_priv *priv = (struct r8192_priv *) data; queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq,0); mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME)); @@ -3409,7 +3409,7 @@ static int _rtl8192_up(struct r8192_priv *priv) if(priv->ieee80211->state != IEEE80211_LINKED) ieee80211_softmac_start_protocol(priv->ieee80211); ieee80211_reset_queue(priv->ieee80211); - watch_dog_timer_callback((unsigned long) dev); + watch_dog_timer_callback((unsigned long) priv); if(!netif_queue_stopped(dev)) netif_start_queue(dev); else -- cgit v1.2.3 From 14f88f1b07e03b064b86ebc9f2f1ed0719dfaa30 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Wed, 9 Mar 2011 16:01:45 +0100 Subject: Staging: IIO: DAC: AD5624R: Update to IIO ABI This driver did not conform with the IIO ABI for such devices. Also the sysfs files that this driver adds were not complete and partially un-documented. Update and document ABI Change License notice, stick to GPL-v2. Fix indention style Add option to specify external reference voltage via the regulator framework. Add mandatory name attribute Add mandatory out_scale attribute Changes since V1: Refine outY_powerdown_mode description Remove bonus white line Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/sysfs-bus-iio | 32 ++++ drivers/staging/iio/dac/ad5624r.h | 89 +++++++-- drivers/staging/iio/dac/ad5624r_spi.c | 241 ++++++++++++++---------- 3 files changed, 251 insertions(+), 111 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio b/drivers/staging/iio/Documentation/sysfs-bus-iio index 8058fcbb87d7..4915aee14d88 100644 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio @@ -271,6 +271,38 @@ Description: where a single output sets the value for multiple channels simultaneously. +What: /sys/bus/iio/devices/deviceX/outY_powerdown_mode +What: /sys/bus/iio/devices/deviceX/out_powerdown_mode +KernelVersion: 2.6.38 +Contact: linux-iio@vger.kernel.org +Description: + Specifies the output powerdown mode. + DAC output stage is disconnected from the amplifier and + 1kohm_to_gnd: connected to ground via an 1kOhm resistor + 100kohm_to_gnd: connected to ground via an 100kOhm resistor + three_state: left floating + For a list of available output power down options read + outX_powerdown_mode_available. If Y is not present the + mode is shared across all outputs. + +What: /sys/bus/iio/devices/deviceX/outY_powerdown_mode_available +What: /sys/bus/iio/devices/deviceX/out_powerdown_mode_available +KernelVersion: 2.6.38 +Contact: linux-iio@vger.kernel.org +Description: + Lists all available output power down modes. + If Y is not present the mode is shared across all outputs. + +What: /sys/bus/iio/devices/deviceX/outY_powerdown +What: /sys/bus/iio/devices/deviceX/out_powerdown +KernelVersion: 2.6.38 +Contact: linux-iio@vger.kernel.org +Description: + Writing 1 causes output Y to enter the power down mode specified + by the corresponding outY_powerdown_mode. Clearing returns to + normal operation. Y may be suppressed if all outputs are + controlled together. + What: /sys/bus/iio/devices/deviceX/deviceX:eventY KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org diff --git a/drivers/staging/iio/dac/ad5624r.h b/drivers/staging/iio/dac/ad5624r.h index ce518be652b7..c16df4ed52ca 100644 --- a/drivers/staging/iio/dac/ad5624r.h +++ b/drivers/staging/iio/dac/ad5624r.h @@ -1,21 +1,80 @@ +/* + * AD5624R SPI DAC driver + * + * Copyright 2010-2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ #ifndef SPI_AD5624R_H_ #define SPI_AD5624R_H_ -#define AD5624R_DAC_CHANNELS 4 +#define AD5624R_DAC_CHANNELS 4 -#define AD5624R_ADDR_DAC0 0x0 -#define AD5624R_ADDR_DAC1 0x1 -#define AD5624R_ADDR_DAC2 0x2 -#define AD5624R_ADDR_DAC3 0x3 -#define AD5624R_ADDR_ALL_DAC 0x7 +#define AD5624R_ADDR_DAC0 0x0 +#define AD5624R_ADDR_DAC1 0x1 +#define AD5624R_ADDR_DAC2 0x2 +#define AD5624R_ADDR_DAC3 0x3 +#define AD5624R_ADDR_ALL_DAC 0x7 -#define AD5624R_CMD_WRITE_INPUT_N 0x0 -#define AD5624R_CMD_UPDATE_DAC_N 0x1 -#define AD5624R_CMD_WRITE_INPUT_N_UPDATE_ALL 0x2 -#define AD5624R_CMD_WRITE_INPUT_N_UPDATE_N 0x3 -#define AD5624R_CMD_POWERDOWN_DAC 0x4 -#define AD5624R_CMD_RESET 0x5 -#define AD5624R_CMD_LDAC_SETUP 0x6 -#define AD5624R_CMD_INTERNAL_REFER_SETUP 0x7 +#define AD5624R_CMD_WRITE_INPUT_N 0x0 +#define AD5624R_CMD_UPDATE_DAC_N 0x1 +#define AD5624R_CMD_WRITE_INPUT_N_UPDATE_ALL 0x2 +#define AD5624R_CMD_WRITE_INPUT_N_UPDATE_N 0x3 +#define AD5624R_CMD_POWERDOWN_DAC 0x4 +#define AD5624R_CMD_RESET 0x5 +#define AD5624R_CMD_LDAC_SETUP 0x6 +#define AD5624R_CMD_INTERNAL_REFER_SETUP 0x7 -#endif +#define AD5624R_LDAC_PWRDN_NONE 0x0 +#define AD5624R_LDAC_PWRDN_1K 0x1 +#define AD5624R_LDAC_PWRDN_100K 0x2 +#define AD5624R_LDAC_PWRDN_3STATE 0x3 + +/** + * struct ad5624r_chip_info - chip specific information + * @bits: accuracy of the DAC in bits + * @int_vref_mv: AD5620/40/60: the internal reference voltage + */ + +struct ad5624r_chip_info { + u8 bits; + u16 int_vref_mv; +}; + +/** + * struct ad5446_state - driver instance specific data + * @indio_dev: the industrial I/O device + * @us: spi_device + * @chip_info: chip model specific constants, available modes etc + * @reg: supply regulator + * @vref_mv: actual reference voltage used + * @pwr_down_mask power down mask + * @pwr_down_mode current power down mode + */ + +struct ad5624r_state { + struct iio_dev *indio_dev; + struct spi_device *us; + const struct ad5624r_chip_info *chip_info; + struct regulator *reg; + unsigned short vref_mv; + unsigned pwr_down_mask; + unsigned pwr_down_mode; +}; + +/** + * ad5624r_supported_device_ids: + * The AD5624/44/64 parts are available in different + * fixed internal reference voltage options. + */ + +enum ad5624r_supported_device_ids { + ID_AD5624R3, + ID_AD5644R3, + ID_AD5664R3, + ID_AD5624R5, + ID_AD5644R5, + ID_AD5664R5, +}; + +#endif /* SPI_AD5624R_H_ */ diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c index 2b1c6dde4fdd..0f97ce02fcdb 100644 --- a/drivers/staging/iio/dac/ad5624r_spi.c +++ b/drivers/staging/iio/dac/ad5624r_spi.c @@ -1,9 +1,9 @@ /* * AD5624R, AD5644R, AD5664R Digital to analog convertors spi driver * - * Copyright 2010 Analog Devices Inc. + * Copyright 2010-2011 Analog Devices Inc. * - * Licensed under the GPL-2 or later. + * Licensed under the GPL-2. */ #include @@ -14,25 +14,38 @@ #include #include #include -#include +#include #include "../iio.h" #include "../sysfs.h" #include "dac.h" #include "ad5624r.h" -/** - * struct ad5624r_state - device related storage - * @indio_dev: associated industrial IO device - * @us: spi device - **/ -struct ad5624r_state { - struct iio_dev *indio_dev; - struct spi_device *us; - int data_len; - int ldac_mode; - int dac_power_mode[AD5624R_DAC_CHANNELS]; - int internal_ref; +static const struct ad5624r_chip_info ad5624r_chip_info_tbl[] = { + [ID_AD5624R3] = { + .bits = 12, + .int_vref_mv = 1250, + }, + [ID_AD5644R3] = { + .bits = 14, + .int_vref_mv = 1250, + }, + [ID_AD5664R3] = { + .bits = 16, + .int_vref_mv = 1250, + }, + [ID_AD5624R5] = { + .bits = 12, + .int_vref_mv = 2500, + }, + [ID_AD5644R5] = { + .bits = 14, + .int_vref_mv = 2500, + }, + [ID_AD5664R5] = { + .bits = 16, + .int_vref_mv = 2500, + }, }; static int ad5624r_spi_write(struct spi_device *spi, @@ -42,11 +55,12 @@ static int ad5624r_spi_write(struct spi_device *spi, u8 msg[3]; /* - * The input shift register is 24 bits wide. The first two bits are don't care bits. - * The next three are the command bits, C2 to C0, followed by the 3-bit DAC address, - * A2 to A0, and then the 16-, 14-, 12-bit data-word. The data-word comprises the 16-, - * 14-, 12-bit input code followed by 0, 2, or 4 don't care bits, for the AD5664R, - * AD5644R, and AD5624R, respectively. + * The input shift register is 24 bits wide. The first two bits are + * don't care bits. The next three are the command bits, C2 to C0, + * followed by the 3-bit DAC address, A2 to A0, and then the + * 16-, 14-, 12-bit data-word. The data-word comprises the 16-, + * 14-, 12-bit input code followed by 0, 2, or 4 don't care bits, + * for the AD5664R, AD5644R, and AD5624R, respectively. */ data = (0 << 22) | (cmd << 19) | (addr << 16) | (val << (16 - len)); msg[0] = data >> 16; @@ -71,40 +85,43 @@ static ssize_t ad5624r_write_dac(struct device *dev, return ret; ret = ad5624r_spi_write(st->us, AD5624R_CMD_WRITE_INPUT_N_UPDATE_N, - this_attr->address, readin, st->data_len); + this_attr->address, readin, + st->chip_info->bits); return ret ? ret : len; } -static ssize_t ad5624r_read_ldac_mode(struct device *dev, +static ssize_t ad5624r_read_powerdown_mode(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ad5624r_state *st = indio_dev->dev_data; - return sprintf(buf, "%x\n", st->ldac_mode); + char mode[][15] = {"", "1kohm_to_gnd", "100kohm_to_gnd", "three_state"}; + + return sprintf(buf, "%s\n", mode[st->pwr_down_mode]); } -static ssize_t ad5624r_write_ldac_mode(struct device *dev, +static ssize_t ad5624r_write_powerdown_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - long readin; - int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ad5624r_state *st = indio_dev->dev_data; + int ret; - ret = strict_strtol(buf, 16, &readin); - if (ret) - return ret; - - ret = ad5624r_spi_write(st->us, AD5624R_CMD_LDAC_SETUP, 0, - readin & 0xF, 16); - st->ldac_mode = readin & 0xF; + if (sysfs_streq(buf, "1kohm_to_gnd")) + st->pwr_down_mode = AD5624R_LDAC_PWRDN_1K; + else if (sysfs_streq(buf, "100kohm_to_gnd")) + st->pwr_down_mode = AD5624R_LDAC_PWRDN_100K; + else if (sysfs_streq(buf, "three_state")) + st->pwr_down_mode = AD5624R_LDAC_PWRDN_3STATE; + else + ret = -EINVAL; return ret ? ret : len; } -static ssize_t ad5624r_read_dac_power_mode(struct device *dev, +static ssize_t ad5624r_read_dac_powerdown(struct device *dev, struct device_attribute *attr, char *buf) { @@ -112,10 +129,11 @@ static ssize_t ad5624r_read_dac_power_mode(struct device *dev, struct ad5624r_state *st = indio_dev->dev_data; struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - return sprintf(buf, "%d\n", st->dac_power_mode[this_attr->address]); + return sprintf(buf, "%d\n", + !!(st->pwr_down_mask & (1 << this_attr->address))); } -static ssize_t ad5624r_write_dac_power_mode(struct device *dev, +static ssize_t ad5624r_write_dac_powerdown(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { @@ -129,80 +147,82 @@ static ssize_t ad5624r_write_dac_power_mode(struct device *dev, if (ret) return ret; - ret = ad5624r_spi_write(st->us, AD5624R_CMD_POWERDOWN_DAC, 0, - ((readin & 0x3) << 4) | - (1 << this_attr->address), 16); + if (readin == 1) + st->pwr_down_mask |= (1 << this_attr->address); + else if (!readin) + st->pwr_down_mask &= ~(1 << this_attr->address); + else + ret = -EINVAL; - st->dac_power_mode[this_attr->address] = readin & 0x3; + ret = ad5624r_spi_write(st->us, AD5624R_CMD_POWERDOWN_DAC, 0, + (st->pwr_down_mode << 4) | + st->pwr_down_mask, 16); return ret ? ret : len; } -static ssize_t ad5624r_read_internal_ref_mode(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t ad5624r_show_scale(struct device *dev, + struct device_attribute *attr, + char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5624r_state *st = indio_dev->dev_data; + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad5624r_state *st = iio_dev_get_devdata(dev_info); + /* Corresponds to Vref / 2^(bits) */ + unsigned int scale_uv = (st->vref_mv * 1000) >> st->chip_info->bits; - return sprintf(buf, "%d\n", st->internal_ref); + return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000); } +static IIO_DEVICE_ATTR(out_scale, S_IRUGO, ad5624r_show_scale, NULL, 0); -static ssize_t ad5624r_write_internal_ref_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t ad5624r_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) { - long readin; - int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5624r_state *st = indio_dev->dev_data; + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad5624r_state *st = iio_dev_get_devdata(dev_info); - ret = strict_strtol(buf, 10, &readin); - if (ret) - return ret; - - ret = ad5624r_spi_write(st->us, AD5624R_CMD_INTERNAL_REFER_SETUP, 0, - !!readin, 16); - - st->internal_ref = !!readin; - - return ret ? ret : len; + return sprintf(buf, "%s\n", spi_get_device_id(st->us)->name); } +static IIO_DEVICE_ATTR(name, S_IRUGO, ad5624r_show_name, NULL, 0); static IIO_DEV_ATTR_OUT_RAW(0, ad5624r_write_dac, AD5624R_ADDR_DAC0); static IIO_DEV_ATTR_OUT_RAW(1, ad5624r_write_dac, AD5624R_ADDR_DAC1); static IIO_DEV_ATTR_OUT_RAW(2, ad5624r_write_dac, AD5624R_ADDR_DAC2); static IIO_DEV_ATTR_OUT_RAW(3, ad5624r_write_dac, AD5624R_ADDR_DAC3); -static IIO_DEVICE_ATTR(ldac_mode, S_IRUGO | S_IWUSR, ad5624r_read_ldac_mode, - ad5624r_write_ldac_mode, 0); -static IIO_DEVICE_ATTR(internal_ref, S_IRUGO | S_IWUSR, - ad5624r_read_internal_ref_mode, - ad5624r_write_internal_ref_mode, 0); +static IIO_DEVICE_ATTR(out_powerdown_mode, S_IRUGO | + S_IWUSR, ad5624r_read_powerdown_mode, + ad5624r_write_powerdown_mode, 0); -#define IIO_DEV_ATTR_DAC_POWER_MODE(_num, _show, _store, _addr) \ - IIO_DEVICE_ATTR(dac_power_mode_##_num, S_IRUGO | S_IWUSR, _show, _store, _addr) +static IIO_CONST_ATTR(out_powerdown_mode_available, + "1kohm_to_gnd 100kohm_to_gnd three_state"); -static IIO_DEV_ATTR_DAC_POWER_MODE(0, ad5624r_read_dac_power_mode, - ad5624r_write_dac_power_mode, 0); -static IIO_DEV_ATTR_DAC_POWER_MODE(1, ad5624r_read_dac_power_mode, - ad5624r_write_dac_power_mode, 1); -static IIO_DEV_ATTR_DAC_POWER_MODE(2, ad5624r_read_dac_power_mode, - ad5624r_write_dac_power_mode, 2); -static IIO_DEV_ATTR_DAC_POWER_MODE(3, ad5624r_read_dac_power_mode, - ad5624r_write_dac_power_mode, 3); +#define IIO_DEV_ATTR_DAC_POWERDOWN(_num, _show, _store, _addr) \ + IIO_DEVICE_ATTR(out##_num##_powerdown, \ + S_IRUGO | S_IWUSR, _show, _store, _addr) + +static IIO_DEV_ATTR_DAC_POWERDOWN(0, ad5624r_read_dac_powerdown, + ad5624r_write_dac_powerdown, 0); +static IIO_DEV_ATTR_DAC_POWERDOWN(1, ad5624r_read_dac_powerdown, + ad5624r_write_dac_powerdown, 1); +static IIO_DEV_ATTR_DAC_POWERDOWN(2, ad5624r_read_dac_powerdown, + ad5624r_write_dac_powerdown, 2); +static IIO_DEV_ATTR_DAC_POWERDOWN(3, ad5624r_read_dac_powerdown, + ad5624r_write_dac_powerdown, 3); static struct attribute *ad5624r_attributes[] = { &iio_dev_attr_out0_raw.dev_attr.attr, &iio_dev_attr_out1_raw.dev_attr.attr, &iio_dev_attr_out2_raw.dev_attr.attr, &iio_dev_attr_out3_raw.dev_attr.attr, - &iio_dev_attr_dac_power_mode_0.dev_attr.attr, - &iio_dev_attr_dac_power_mode_1.dev_attr.attr, - &iio_dev_attr_dac_power_mode_2.dev_attr.attr, - &iio_dev_attr_dac_power_mode_3.dev_attr.attr, - &iio_dev_attr_ldac_mode.dev_attr.attr, - &iio_dev_attr_internal_ref.dev_attr.attr, + &iio_dev_attr_out0_powerdown.dev_attr.attr, + &iio_dev_attr_out1_powerdown.dev_attr.attr, + &iio_dev_attr_out2_powerdown.dev_attr.attr, + &iio_dev_attr_out3_powerdown.dev_attr.attr, + &iio_dev_attr_out_powerdown_mode.dev_attr.attr, + &iio_const_attr_out_powerdown_mode_available.dev_attr.attr, + &iio_dev_attr_out_scale.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, NULL, }; @@ -213,7 +233,7 @@ static const struct attribute_group ad5624r_attribute_group = { static int __devinit ad5624r_probe(struct spi_device *spi) { struct ad5624r_state *st; - int ret = 0; + int ret, voltage_uv = 0; st = kzalloc(sizeof(*st), GFP_KERNEL); if (st == NULL) { @@ -222,18 +242,30 @@ static int __devinit ad5624r_probe(struct spi_device *spi) } spi_set_drvdata(spi, st); - st->data_len = spi_get_device_id(spi)->driver_data; + st->reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + + voltage_uv = regulator_get_voltage(st->reg); + } + + st->chip_info = + &ad5624r_chip_info_tbl[spi_get_device_id(spi)->driver_data]; + + if (voltage_uv) + st->vref_mv = voltage_uv / 1000; + else + st->vref_mv = st->chip_info->int_vref_mv; st->us = spi; st->indio_dev = iio_allocate_device(); if (st->indio_dev == NULL) { ret = -ENOMEM; - goto error_free_st; + goto error_disable_reg; } st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->num_interrupt_lines = 0; - st->indio_dev->event_attrs = NULL; - st->indio_dev->attrs = &ad5624r_attribute_group; st->indio_dev->dev_data = (void *)(st); st->indio_dev->driver_module = THIS_MODULE; @@ -243,14 +275,22 @@ static int __devinit ad5624r_probe(struct spi_device *spi) if (ret) goto error_free_dev; - spi->mode = SPI_MODE_0; - spi_setup(spi); + ret = ad5624r_spi_write(spi, AD5624R_CMD_INTERNAL_REFER_SETUP, 0, + !!voltage_uv, 16); + if (ret) + goto error_free_dev; return 0; error_free_dev: iio_free_device(st->indio_dev); -error_free_st: +error_disable_reg: + if (!IS_ERR(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR(st->reg)) + regulator_put(st->reg); + kfree(st); error_ret: return ret; @@ -261,15 +301,24 @@ static int __devexit ad5624r_remove(struct spi_device *spi) struct ad5624r_state *st = spi_get_drvdata(spi); iio_device_unregister(st->indio_dev); + + if (!IS_ERR(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + kfree(st); return 0; } static const struct spi_device_id ad5624r_id[] = { - {"ad5624r", 12}, - {"ad5644r", 14}, - {"ad5664r", 16}, + {"ad5624r3", ID_AD5624R3}, + {"ad5644r3", ID_AD5644R3}, + {"ad5664r3", ID_AD5664R3}, + {"ad5624r5", ID_AD5624R5}, + {"ad5644r5", ID_AD5644R5}, + {"ad5664r5", ID_AD5664R5}, {} }; -- cgit v1.2.3 From 8b68bb20812ba82460e22942ae22ce45880df232 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 8 Mar 2011 08:55:48 +0100 Subject: Staging: IIO: Documentation: iio_utils: fix channel array generation. The previous implementation flawed, in case some channels are not enabled. The sorted array would then include channel information of disabled channels, And misses the enabled ones, when the count is reached. More troublesome, the loop would not even terminate. The fix is twofold: First we skip channels that are not enabled. Then we use a tested bubble sort algorithm to sort the array. Since we already allocated exactly the number of bytes we need. We can exercise bubble sort on the original memory. In all cases I've seen, the array is already sorted, so this sort terminates immediately. Changes since V1: Fix coding style issues. Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/iio_utils.h | 56 ++++++++++++++++----------- 1 file changed, 33 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index 1b33c040bad7..8095727b3966 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -51,7 +51,7 @@ static int iioutils_break_up_name(const char *full_name, w = working; r = working; - while(*r != '\0') { + while (*r != '\0') { if (!isdigit(*r)) { *w = *r; w++; @@ -242,6 +242,26 @@ error_ret: return ret; } +/** + * bsort_channel_array_by_index() - reorder so that the array is in index order + * + **/ + +inline void bsort_channel_array_by_index(struct iio_channel_info **ci_array, + int cnt) +{ + + struct iio_channel_info temp; + int x, y; + + for (x = 0; x < cnt; x++) + for (y = 0; y < (cnt - 1); y++) + if ((*ci_array)[y].index > (*ci_array)[y+1].index) { + temp = (*ci_array)[y + 1]; + (*ci_array)[y + 1] = (*ci_array)[y]; + (*ci_array)[y] = temp; + } +} /** * build_channel_array() - function to figure out what channels are present @@ -254,7 +274,7 @@ inline int build_channel_array(const char *device_dir, { DIR *dp; FILE *sysfsfp; - int count = 0, temp, i; + int count, temp, i; struct iio_channel_info *current; int ret; const struct dirent *ent; @@ -290,11 +310,10 @@ inline int build_channel_array(const char *device_dir, fscanf(sysfsfp, "%u", &ret); if (ret == 1) (*counter)++; - count++; fclose(sysfsfp); free(filename); } - *ci_array = malloc(sizeof(**ci_array)*count); + *ci_array = malloc(sizeof(**ci_array) * (*counter)); if (*ci_array == NULL) { ret = -ENOMEM; goto error_close_dir; @@ -321,6 +340,13 @@ inline int build_channel_array(const char *device_dir, } fscanf(sysfsfp, "%u", ¤t->enabled); fclose(sysfsfp); + + if (!current->enabled) { + free(filename); + count--; + continue; + } + current->scale = 1.0; current->offset = 0; current->name = strndup(ent->d_name, @@ -375,26 +401,10 @@ inline int build_channel_array(const char *device_dir, current->generic_name); } } - /* reorder so that the array is in index order*/ - current = malloc(sizeof(**ci_array)*(*counter)); - if (current == NULL) { - ret = -ENOMEM; - goto error_cleanup_array; - } + closedir(dp); - count = 0; - temp = 0; - while (count < *counter) - for (i = 0; i < *counter; i++) - if ((*ci_array)[i].index == temp) { - memcpy(¤t[count++], - &(*ci_array)[i], - sizeof(*current)); - temp++; - break; - } - free(*ci_array); - *ci_array = current; + /* reorder so that the array is in index order */ + bsort_channel_array_by_index(ci_array, *counter); return 0; -- cgit v1.2.3 From 00b6fb2e31ac668795857c9609adc11e7964ed5a Mon Sep 17 00:00:00 2001 From: Vinay Sawal Date: Wed, 9 Mar 2011 13:47:35 -0800 Subject: Staging: bcm: Bcmnet: fixed checkpatch script reported issues Fixed all issues reported by checkpatch script on this file. Signed-off-by: Vinay Sawal Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmnet.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index a6ce2396c791..133e146a3dd4 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -8,7 +8,7 @@ static INT bcm_open(struct net_device *dev) if (Adapter->fw_download_done == FALSE) { pr_notice(PFX "%s: link up failed (download in progress)\n", - dev->name); + dev->name); return -EBUSY; } @@ -50,7 +50,7 @@ static u16 bcm_select_queue(struct net_device *dev, struct sk_buff *skb) * Description - This is the main transmit function for our virtual * interface(eth0). It handles the ARP packets. It * clones this packet and then Queue it to a suitable -* Queue. Then calls the transmit_packet(). +* Queue. Then calls the transmit_packet(). * * Parameter - skb - Pointer to the socket buffer structure * dev - Pointer to the virtual net device structure @@ -110,13 +110,13 @@ static netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev) Register other driver entry points with the kernel */ static const struct net_device_ops bcmNetDevOps = { - .ndo_open = bcm_open, - .ndo_stop = bcm_close, - .ndo_start_xmit = bcm_transmit, - .ndo_change_mtu = eth_change_mtu, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, - .ndo_select_queue = bcm_select_queue, + .ndo_open = bcm_open, + .ndo_stop = bcm_close, + .ndo_start_xmit = bcm_transmit, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, + .ndo_select_queue = bcm_select_queue, }; static struct device_type wimax_type = { @@ -138,7 +138,8 @@ static int bcm_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) return 0; } -static void bcm_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +static void bcm_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); PS_INTERFACE_ADAPTER psIntfAdapter = Adapter->pvInterfaceAdapter; @@ -160,14 +161,14 @@ static u32 bcm_get_link(struct net_device *dev) return Adapter->LinkUpStatus; } -static u32 bcm_get_msglevel (struct net_device *dev) +static u32 bcm_get_msglevel(struct net_device *dev) { PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); return Adapter->msg_enable; } -static void bcm_set_msglevel (struct net_device *dev, u32 level) +static void bcm_set_msglevel(struct net_device *dev, u32 level) { PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); @@ -177,7 +178,7 @@ static void bcm_set_msglevel (struct net_device *dev, u32 level) static const struct ethtool_ops bcm_ethtool_ops = { .get_settings = bcm_get_settings, .get_drvinfo = bcm_get_drvinfo, - .get_link = bcm_get_link, + .get_link = bcm_get_link, .get_msglevel = bcm_get_msglevel, .set_msglevel = bcm_set_msglevel, }; @@ -206,7 +207,7 @@ int register_networkdev(PMINI_ADAPTER Adapter) if (result != STATUS_SUCCESS) { dev_err(&udev->dev, PFX "Error in Reading the mac Address: %d", result); - return -EIO; + return -EIO; } result = register_netdev(net); @@ -233,6 +234,6 @@ void unregister_networkdev(PMINI_ADAPTER Adapter) if (netif_msg_probe(Adapter)) dev_info(&udev->dev, PFX "%s: unregister usb-%s%s\n", net->name, xdev->bus->bus_name, xdev->devpath); - + unregister_netdev(Adapter->dev); } -- cgit v1.2.3 From f4a0e6b1354cd0bec6aca405883cc45662511f03 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 9 Mar 2011 03:53:34 +0300 Subject: staging: bcm: optimize kmalloc to kzalloc Use kzalloc rather than kmalloc followed by memset with 0. Found by coccinelle. Signed-off-by: Alexander Beregalov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 4 +--- drivers/staging/bcm/Misc.c | 6 ++---- 2 files changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 3d9055aec97c..867dbf1c9926 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -19,12 +19,10 @@ static int bcm_char_open(struct inode *inode, struct file * filp) PPER_TARANG_DATA pTarang = NULL; Adapter = GET_BCM_ADAPTER(gblpnetdev); - pTarang = (PPER_TARANG_DATA)kmalloc(sizeof(PER_TARANG_DATA), - GFP_KERNEL); + pTarang = kzalloc(sizeof(PER_TARANG_DATA), GFP_KERNEL); if (!pTarang) return -ENOMEM; - memset(pTarang, 0, sizeof(PER_TARANG_DATA)); pTarang->Adapter = Adapter; pTarang->RxCntrlMsgBitMask = 0xFFFFFFFF & ~(1 << 0xB); diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index f585aae9cf8b..d624f35d0551 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -498,13 +498,12 @@ VOID LinkMessage(PMINI_ADAPTER Adapter) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "=====>"); if(Adapter->LinkStatus == SYNC_UP_REQUEST && Adapter->AutoSyncup) { - pstLinkRequest=kmalloc(sizeof(LINK_REQUEST), GFP_ATOMIC); + pstLinkRequest = kzalloc(sizeof(LINK_REQUEST), GFP_ATOMIC); if(!pstLinkRequest) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!"); return; } - memset(pstLinkRequest,0,sizeof(LINK_REQUEST)); //sync up request... Adapter->LinkStatus = WAIT_FOR_SYNC;// current link status BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Requesting For SyncUp..."); @@ -516,13 +515,12 @@ VOID LinkMessage(PMINI_ADAPTER Adapter) } else if(Adapter->LinkStatus == PHY_SYNC_ACHIVED && Adapter->AutoLinkUp) { - pstLinkRequest=kmalloc(sizeof(LINK_REQUEST), GFP_ATOMIC); + pstLinkRequest = kzalloc(sizeof(LINK_REQUEST), GFP_ATOMIC); if(!pstLinkRequest) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Can not allocate memory for Link request!"); return; } - memset(pstLinkRequest,0,sizeof(LINK_REQUEST)); //LINK_UP_REQUEST BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Requesting For LinkUp..."); pstLinkRequest->szData[0]=LINK_UP_REQ_PAYLOAD; -- cgit v1.2.3 From 12d0eb47ddd20cf8f1e8d768b0f8f81984902a60 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 9 Mar 2011 03:53:35 +0300 Subject: staging: brcm80211: optimize kmalloc to kzalloc Use kzalloc rather than kmalloc followed by memset with 0. Found by coccinelle. Signed-off-by: Alexander Beregalov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 4 +--- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 6 ++---- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 9 +++------ drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 4 +--- 4 files changed, 7 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index ab8e688d9620..d473f64bc0df 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -1931,14 +1931,12 @@ dhd_pub_t *dhd_attach(struct dhd_bus *bus, uint bus_hdrlen) } /* Allocate primary dhd_info */ - dhd = kmalloc(sizeof(dhd_info_t), GFP_ATOMIC); + dhd = kzalloc(sizeof(dhd_info_t), GFP_ATOMIC); if (!dhd) { DHD_ERROR(("%s: OOM - alloc dhd_info\n", __func__)); goto fail; } - memset(dhd, 0, sizeof(dhd_info_t)); - /* * Save the dhd_info into the priv */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 971d40689098..b74b3c6ecf8d 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -2528,11 +2528,10 @@ static int dhdsdio_write_vars(dhd_bus_t *bus) varaddr = (bus->ramsize - 4) - varsize; if (bus->vars) { - vbuffer = kmalloc(varsize, GFP_ATOMIC); + vbuffer = kzalloc(varsize, GFP_ATOMIC); if (!vbuffer) return BCME_NOMEM; - memset(vbuffer, 0, varsize); memcpy(vbuffer, bus->vars, bus->varsz); /* Write the vars list */ @@ -5258,13 +5257,12 @@ dhdsdio_probe_attach(struct dhd_bus *bus, void *sdh, void *regsva, u16 devid) udelay(65); for (fn = 0; fn <= numfn; fn++) { - cis[fn] = kmalloc(SBSDIO_CIS_SIZE_LIMIT, GFP_ATOMIC); + cis[fn] = kzalloc(SBSDIO_CIS_SIZE_LIMIT, GFP_ATOMIC); if (!cis[fn]) { DHD_INFO(("dhdsdio_probe: fn %d cis malloc " "failed\n", fn)); break; } - memset(cis[fn], 0, SBSDIO_CIS_SIZE_LIMIT); err = bcmsdh_cis_read(sdh, fn, cis[fn], SBSDIO_CIS_SIZE_LIMIT); diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index 4d16644544ae..b49957fb7586 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -862,10 +862,9 @@ wl_iw_get_aplist(struct net_device *dev, if (!extra) return -EINVAL; - list = kmalloc(buflen, GFP_KERNEL); + list = kzalloc(buflen, GFP_KERNEL); if (!list) return -ENOMEM; - memset(list, 0, buflen); list->buflen = cpu_to_le32(buflen); error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, buflen); if (error) { @@ -3667,11 +3666,10 @@ int wl_iw_attach(struct net_device *dev, void *dhdp) params_size = (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params)); #endif - iscan = kmalloc(sizeof(iscan_info_t), GFP_KERNEL); + iscan = kzalloc(sizeof(iscan_info_t), GFP_KERNEL); if (!iscan) return -ENOMEM; - memset(iscan, 0, sizeof(iscan_info_t)); iscan->iscan_ex_params_p = kmalloc(params_size, GFP_KERNEL); if (!iscan->iscan_ex_params_p) @@ -3705,11 +3703,10 @@ int wl_iw_attach(struct net_device *dev, void *dhdp) priv_dev = dev; MUTEX_LOCK_SOFTAP_SET_INIT(iw->pub); #endif - g_scan = kmalloc(G_SCAN_RESULTS, GFP_KERNEL); + g_scan = kzalloc(G_SCAN_RESULTS, GFP_KERNEL); if (!g_scan) return -ENOMEM; - memset(g_scan, 0, G_SCAN_RESULTS); g_scan_specified_ssid = 0; return 0; diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index d70ed3d990d6..3550551da316 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -1634,14 +1634,12 @@ struct wl_timer *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg), { struct wl_timer *t; - t = kmalloc(sizeof(struct wl_timer), GFP_ATOMIC); + t = kzalloc(sizeof(struct wl_timer), GFP_ATOMIC); if (!t) { WL_ERROR("wl%d: wl_init_timer: out of memory\n", wl->pub->unit); return 0; } - memset(t, 0, sizeof(struct wl_timer)); - init_timer(&t->timer); t->timer.data = (unsigned long) t; t->timer.function = wl_timer; -- cgit v1.2.3 From 1840c15b0a504fed6ee08b475245a964336b76e6 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 9 Mar 2011 03:53:38 +0300 Subject: staging: rts_pstor: optimize kmalloc to kzalloc Use kzalloc rather than kmalloc followed by memset with 0. Found by coccinelle. Signed-off-by: Alexander Beregalov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts_pstor/rtsx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rts_pstor/rtsx.c b/drivers/staging/rts_pstor/rtsx.c index c3f33d1de465..db3470e93fa1 100644 --- a/drivers/staging/rts_pstor/rtsx.c +++ b/drivers/staging/rts_pstor/rtsx.c @@ -931,11 +931,10 @@ static int __devinit rtsx_probe(struct pci_dev *pci, const struct pci_device_id dev = host_to_rtsx(host); memset(dev, 0, sizeof(struct rtsx_dev)); - dev->chip = (struct rtsx_chip *)kmalloc(sizeof(struct rtsx_chip), GFP_KERNEL); + dev->chip = kzalloc(sizeof(struct rtsx_chip), GFP_KERNEL); if (dev->chip == NULL) { goto errout; } - memset(dev->chip, 0, sizeof(struct rtsx_chip)); spin_lock_init(&dev->reg_lock); mutex_init(&(dev->dev_mutex)); -- cgit v1.2.3 From 2f4813163639f9f528c41d98ea52dcc85f8d9781 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 9 Mar 2011 03:53:37 +0300 Subject: staging: ft1000: optimize kmalloc to kzalloc Use kzalloc rather than kmalloc followed by memset with 0. Found by coccinelle. Signed-off-by: Alexander Beregalov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c index 874919cf5965..10af47700efb 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c @@ -120,11 +120,10 @@ static int ft1000_attach(struct pcmcia_device *link) DEBUG(0, "ft1000_cs: ft1000_attach()\n"); - local = kmalloc(sizeof(local_info_t), GFP_KERNEL); + local = kzalloc(sizeof(local_info_t), GFP_KERNEL); if (!local) { return -ENOMEM; } - memset(local, 0, sizeof(local_info_t)); local->link = link; link->priv = local; -- cgit v1.2.3 From fb44022f1865ca4a5fcee4fc26a260b83ca05c06 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 9 Mar 2011 03:53:36 +0300 Subject: staging: spectra: optimize kmalloc to kzalloc Use kzalloc rather than kmalloc followed by memset with 0. Found by coccinelle. Signed-off-by: Alexander Beregalov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/spectra/flash.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/spectra/flash.c b/drivers/staging/spectra/flash.c index f11197b43f7f..a2f820025ae4 100644 --- a/drivers/staging/spectra/flash.c +++ b/drivers/staging/spectra/flash.c @@ -428,10 +428,9 @@ static int allocate_memory(void) DeviceInfo.wPageDataSize; /* Malloc memory for block tables */ - g_pBlockTable = kmalloc(block_table_size, GFP_ATOMIC); + g_pBlockTable = kzalloc(block_table_size, GFP_ATOMIC); if (!g_pBlockTable) goto block_table_fail; - memset(g_pBlockTable, 0, block_table_size); total_bytes += block_table_size; g_pWearCounter = (u8 *)(g_pBlockTable + @@ -447,19 +446,17 @@ static int allocate_memory(void) Cache.array[i].address = NAND_CACHE_INIT_ADDR; Cache.array[i].use_cnt = 0; Cache.array[i].changed = CLEAR; - Cache.array[i].buf = kmalloc(Cache.cache_item_size, - GFP_ATOMIC); + Cache.array[i].buf = kzalloc(Cache.cache_item_size, + GFP_ATOMIC); if (!Cache.array[i].buf) goto cache_item_fail; - memset(Cache.array[i].buf, 0, Cache.cache_item_size); total_bytes += Cache.cache_item_size; } /* Malloc memory for IPF */ - g_pIPF = kmalloc(page_size, GFP_ATOMIC); + g_pIPF = kzalloc(page_size, GFP_ATOMIC); if (!g_pIPF) goto ipf_fail; - memset(g_pIPF, 0, page_size); total_bytes += page_size; /* Malloc memory for data merging during Level2 Cache flush */ @@ -476,10 +473,9 @@ static int allocate_memory(void) total_bytes += block_size; /* Malloc memory for temp buffer */ - g_pTempBuf = kmalloc(Cache.cache_item_size, GFP_ATOMIC); + g_pTempBuf = kzalloc(Cache.cache_item_size, GFP_ATOMIC); if (!g_pTempBuf) goto Temp_buf_fail; - memset(g_pTempBuf, 0, Cache.cache_item_size); total_bytes += Cache.cache_item_size; /* Malloc memory for block table blocks */ @@ -589,10 +585,9 @@ static int allocate_memory(void) total_bytes += block_size; /* Malloc memory for copy of block table used in CDMA mode */ - g_pBTStartingCopy = kmalloc(block_table_size, GFP_ATOMIC); + g_pBTStartingCopy = kzalloc(block_table_size, GFP_ATOMIC); if (!g_pBTStartingCopy) goto bt_starting_copy; - memset(g_pBTStartingCopy, 0, block_table_size); total_bytes += block_table_size; g_pWearCounterCopy = (u8 *)(g_pBTStartingCopy + @@ -608,28 +603,25 @@ static int allocate_memory(void) 5 * DeviceInfo.wDataBlockNum * sizeof(u8); if (DeviceInfo.MLCDevice) mem_size += 5 * DeviceInfo.wDataBlockNum * sizeof(u16); - g_pBlockTableCopies = kmalloc(mem_size, GFP_ATOMIC); + g_pBlockTableCopies = kzalloc(mem_size, GFP_ATOMIC); if (!g_pBlockTableCopies) goto blk_table_copies_fail; - memset(g_pBlockTableCopies, 0, mem_size); total_bytes += mem_size; g_pNextBlockTable = g_pBlockTableCopies; /* Malloc memory for Block Table Delta */ mem_size = MAX_DESCS * sizeof(struct BTableChangesDelta); - g_pBTDelta = kmalloc(mem_size, GFP_ATOMIC); + g_pBTDelta = kzalloc(mem_size, GFP_ATOMIC); if (!g_pBTDelta) goto bt_delta_fail; - memset(g_pBTDelta, 0, mem_size); total_bytes += mem_size; g_pBTDelta_Free = g_pBTDelta; /* Malloc memory for Copy Back Buffers */ for (j = 0; j < COPY_BACK_BUF_NUM; j++) { - cp_back_buf_copies[j] = kmalloc(block_size, GFP_ATOMIC); + cp_back_buf_copies[j] = kzalloc(block_size, GFP_ATOMIC); if (!cp_back_buf_copies[j]) goto cp_back_buf_copies_fail; - memset(cp_back_buf_copies[j], 0, block_size); total_bytes += block_size; } cp_back_buf_idx = 0; -- cgit v1.2.3 From 26a71a40292e3e29e461a2210d9c0c7339427b19 Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Wed, 9 Mar 2011 10:41:25 -0800 Subject: STAGING: brcm80211 fix TX Queue overflow Increase QLEN to avoid TX Queue overflow. iperf testing results in poor throughput and massive reporting of: dhd_bus_txdata: out of bus->txq !!! Also renamed QLEN/et al to reflect usage as TX queue parameters. Tested with "dhd_doflow = true". Signed-off-by: Venkat Rao Signed-off-by: Grant Grundler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index b74b3c6ecf8d..f25e5b301119 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -57,9 +57,9 @@ #define DHDSDIO_MEM_DUMP_FNAME "mem_dump" #endif -#define QLEN 256 /* bulk rx and tx queue lengths */ -#define FCHI (QLEN - 10) -#define FCLOW (FCHI / 2) +#define TXQLEN 2048 /* bulk tx queue length */ +#define TXHI (TXQLEN - 256) /* turn on flow control above TXHI */ +#define TXLOW (TXHI - 256) /* turn off flow control below TXLOW */ #define PRIOMASK 7 #define TXRETRIES 2 /* # of retries for tx frames */ @@ -1119,7 +1119,7 @@ int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *pkt) } dhd_os_sdunlock_txq(bus->dhd); - if ((pktq_len(&bus->txq) >= FCHI) && dhd_doflow) + if ((pktq_len(&bus->txq) >= TXHI) && dhd_doflow) dhd_txflowcontrol(bus->dhd, 0, ON); #ifdef DHD_DEBUG @@ -1218,7 +1218,7 @@ static uint dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes) /* Deflow-control stack if needed */ if (dhd_doflow && dhd->up && (dhd->busstate == DHD_BUS_DATA) && - dhd->txoff && (pktq_len(&bus->txq) < FCLOW)) + dhd->txoff && (pktq_len(&bus->txq) < TXLOW)) dhd_txflowcontrol(dhd, 0, OFF); return cnt; @@ -5343,7 +5343,7 @@ dhdsdio_probe_attach(struct dhd_bus *bus, void *sdh, void *regsva, u16 devid) /* Set core control so an SDIO reset does a backplane reset */ OR_REG(&bus->regs->corecontrol, CC_BPRESEN); - pktq_init(&bus->txq, (PRIOMASK + 1), QLEN); + pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); /* Locate an appropriately-aligned portion of hdrbuf */ bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0], DHD_SDALIGN); -- cgit v1.2.3 From 7c31607e165d5edfa13dea5d329e59f322d4cad2 Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Wed, 9 Mar 2011 15:04:15 -0800 Subject: STAGING: brcm80211 remove dhd_doflow Remove dhd_doflow. iperf result without flow control is unacceptable. Signed-off-by: Grant Grundler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index f25e5b301119..dd2e36749d0a 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -333,7 +333,6 @@ uint dhd_txminmax; #define DONGLE_MIN_MEMSIZE (128 * 1024) int dhd_dongle_memsize; -static bool dhd_doflow; static bool dhd_alignctl; static bool sd1idle; @@ -1119,7 +1118,7 @@ int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *pkt) } dhd_os_sdunlock_txq(bus->dhd); - if ((pktq_len(&bus->txq) >= TXHI) && dhd_doflow) + if (pktq_len(&bus->txq) >= TXHI) dhd_txflowcontrol(bus->dhd, 0, ON); #ifdef DHD_DEBUG @@ -1217,7 +1216,7 @@ static uint dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes) } /* Deflow-control stack if needed */ - if (dhd_doflow && dhd->up && (dhd->busstate == DHD_BUS_DATA) && + if (dhd->up && (dhd->busstate == DHD_BUS_DATA) && dhd->txoff && (pktq_len(&bus->txq) < TXLOW)) dhd_txflowcontrol(dhd, 0, OFF); @@ -5073,7 +5072,6 @@ static void *dhdsdio_probe(u16 venid, u16 devid, u16 bus_no, sd1idle = true; dhd_readahead = true; retrydata = false; - dhd_doflow = false; dhd_dongle_memsize = 0; dhd_txminmax = DHD_TXMINMAX; -- cgit v1.2.3 From 9fe341e834bec1cad92c3f320931d0563674e112 Mon Sep 17 00:00:00 2001 From: wwang Date: Tue, 8 Mar 2011 15:22:14 +0800 Subject: staging: rts_pstor: MSXC card power class 1, Initialize chip->ms_power_class_en in rtsx_init_options; 2, In reset_ms_pro, set different initial value of change_power_class according to chip->ms_power_class_en. Signed-off-by: wwang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts_pstor/ms.c | 14 +++++++++----- drivers/staging/rts_pstor/rtsx.c | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rts_pstor/ms.c b/drivers/staging/rts_pstor/ms.c index c43f9118dca9..810e170894f5 100644 --- a/drivers/staging/rts_pstor/ms.c +++ b/drivers/staging/rts_pstor/ms.c @@ -1099,7 +1099,14 @@ static int reset_ms_pro(struct rtsx_chip *chip) struct ms_info *ms_card = &(chip->ms_card); int retval; #ifdef XC_POWERCLASS - u8 change_power_class = 2; + u8 change_power_class; + + if (chip->ms_power_class_en & 0x02) + change_power_class = 2; + else if (chip->ms_power_class_en & 0x01) + change_power_class = 1; + else + change_power_class = 0; #endif #ifdef XC_POWERCLASS @@ -1128,10 +1135,7 @@ Retry: } if (change_power_class && CHK_MSXC(ms_card)) { - u8 power_class_en = 0x03; - - if (CHECK_PID(chip, 0x5209)) - power_class_en = chip->ms_power_class_en; + u8 power_class_en = chip->ms_power_class_en; RTSX_DEBUGP("power_class_en = 0x%x\n", power_class_en); RTSX_DEBUGP("change_power_class = %d\n", change_power_class); diff --git a/drivers/staging/rts_pstor/rtsx.c b/drivers/staging/rts_pstor/rtsx.c index db3470e93fa1..4514419a5fb8 100644 --- a/drivers/staging/rts_pstor/rtsx.c +++ b/drivers/staging/rts_pstor/rtsx.c @@ -850,6 +850,7 @@ static void rtsx_init_options(struct rtsx_chip *chip) chip->sd_default_rx_phase = 15; chip->pmos_pwr_on_interval = 200; chip->sd_voltage_switch_delay = 1000; + chip->ms_power_class_en = 3; chip->sd_400mA_ocp_thd = 1; chip->sd_800mA_ocp_thd = 5; -- cgit v1.2.3 From df0d5e6055b0230763da7a8975db1a7886442d93 Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Mon, 7 Mar 2011 20:34:30 +0100 Subject: staging/hv: add missing include causing build error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes following build error: In file included from drivers/staging/hv/channel.h:28, from drivers/staging/hv/vmbus_private.h:30, from drivers/staging/hv/hv.c:28: drivers/staging/hv/channel_mgmt.h:234: error: field ‘work’ has incomplete type Signed-off-by: Mariusz Kozlowski Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel_mgmt.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/hv/channel_mgmt.h b/drivers/staging/hv/channel_mgmt.h index 3368bf14e3cd..96f74e2a3c7f 100644 --- a/drivers/staging/hv/channel_mgmt.h +++ b/drivers/staging/hv/channel_mgmt.h @@ -27,6 +27,7 @@ #include #include +#include #include "ring_buffer.h" #include "vmbus_channel_interface.h" #include "vmbus_packet_format.h" -- cgit v1.2.3 From daa484ec96349f2cad6f547517741c74395215ed Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 8 Mar 2011 22:16:06 +0200 Subject: staging: xgifb: delete HW cursor memory allocation HW cursor area is not used in any way. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main.h | 8 -------- drivers/staging/xgifb/XGI_main_26.c | 18 ------------------ 2 files changed, 26 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index 37f77ee459ca..88d15c8394e2 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -66,7 +66,6 @@ MODULE_DEVICE_TABLE(pci, xgifb_pci_table); #define MAX_ROM_SCAN 0x10000 -#define HW_CURSOR_CAP 0x80 #define TURBO_QUEUE_CAP 0x40 #define AGP_CMD_QUEUE_CAP 0x20 #define VM_CMD_QUEUE_CAP 0x10 @@ -80,10 +79,6 @@ MODULE_DEVICE_TABLE(pci, xgifb_pci_table); #define COMMAND_QUEUE_THRESHOLD 0x1F -/* TW */ -#define HW_CURSOR_AREA_SIZE_315 0x4000 /* 16K */ -#define HW_CURSOR_AREA_SIZE_300 0x1000 /* 4K */ - #define OH_ALLOC_SIZE 4000 #define SENTINEL 0x7fffffff @@ -350,7 +345,6 @@ static int enable_dstn = 0; static int XGIfb_ypan = -1; -static int XGIfb_hwcursor_size = 0; static int XGIfb_CRT2_write_enable = 0; static int XGIfb_crt2type = -1; /* TW: CRT2 type (for overriding autodetection) */ @@ -613,8 +607,6 @@ typedef struct _XGI_HEAP { unsigned long max_freesize; } XGI_HEAP; -static unsigned long XGIfb_hwcursor_vbase; - static unsigned long XGIfb_heap_start; static unsigned long XGIfb_heap_end; static unsigned long XGIfb_heap_size; diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index faf7106b3558..3998dd485dfa 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -2122,19 +2122,6 @@ static int XGIfb_heap_init(void) break; } - /* TW: Now reserve memory for the HWCursor. It is always located at the very - top of the videoRAM, right below the TB memory area (if used). */ - if (XGIfb_heap_size >= XGIfb_hwcursor_size) { - XGIfb_heap_end -= XGIfb_hwcursor_size; - XGIfb_heap_size -= XGIfb_hwcursor_size; - XGIfb_hwcursor_vbase = XGIfb_heap_end; - - XGIfb_caps |= HW_CURSOR_CAP; - - DPRINTK("XGIfb: Hardware Cursor start at 0x%lx, size is %dK\n", - XGIfb_heap_end, XGIfb_hwcursor_size/1024); - } - XGIfb_heap.poha_chain = NULL; XGIfb_heap.poh_freelist = NULL; @@ -2772,27 +2759,22 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgi_video_info.chip = XG21; else xgi_video_info.chip = XG20; - XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2; XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315; break; case PCI_DEVICE_ID_XG_40: xgi_video_info.chip = XG40; - XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2; XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315; break; case PCI_DEVICE_ID_XG_41: xgi_video_info.chip = XG41; - XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2; XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315; break; case PCI_DEVICE_ID_XG_42: xgi_video_info.chip = XG42; - XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2; XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315; break; case PCI_DEVICE_ID_XG_27: xgi_video_info.chip = XG27; - XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2; XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315; break; default: -- cgit v1.2.3 From 83a8c24162c2abe158cb6eec4b29a8d8bf0c736c Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 8 Mar 2011 22:16:07 +0200 Subject: staging: xgifb: delete command queue selection/init The driver does not utilize HW command queue in any way, so the code can be dropped. The support for the default mode (MMIO) and AGP have been disabled already anyway. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main.h | 49 --------- drivers/staging/xgifb/XGI_main_26.c | 209 ------------------------------------ 2 files changed, 258 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index 88d15c8394e2..2c55faacc074 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -10,7 +10,6 @@ #include "vb_def.h" //#define LINUXBIOS /* turn this on when compiling for LINUXBIOS */ -#define AGPOFF /* default is turn off AGP */ #define XGIFAIL(x) do { printk(x "\n"); return -EINVAL; } while(0) @@ -66,19 +65,6 @@ MODULE_DEVICE_TABLE(pci, xgifb_pci_table); #define MAX_ROM_SCAN 0x10000 -#define TURBO_QUEUE_CAP 0x40 -#define AGP_CMD_QUEUE_CAP 0x20 -#define VM_CMD_QUEUE_CAP 0x10 -#define MMIO_CMD_QUEUE_CAP 0x08 - - - -/* For 315 series */ - -#define COMMAND_QUEUE_AREA_SIZE 0x80000 /* 512K */ -#define COMMAND_QUEUE_THRESHOLD 0x1F - - #define OH_ALLOC_SIZE 4000 #define SENTINEL 0x7fffffff @@ -190,16 +176,6 @@ MODULE_DEVICE_TABLE(pci, xgifb_pci_table); #define XGI_MEM_MAP_IO_ENABLE 0x01 /* SR20 */ #define XGI_PCI_ADDR_ENABLE 0x80 -#define XGI_AGP_CMDQUEUE_ENABLE 0x80 /* 315/650/740 SR26 */ -#define XGI_VRAM_CMDQUEUE_ENABLE 0x40 -#define XGI_MMIO_CMD_ENABLE 0x20 -#define XGI_CMD_QUEUE_SIZE_512k 0x00 -#define XGI_CMD_QUEUE_SIZE_1M 0x04 -#define XGI_CMD_QUEUE_SIZE_2M 0x08 -#define XGI_CMD_QUEUE_SIZE_4M 0x0C -#define XGI_CMD_QUEUE_RESET 0x01 -#define XGI_CMD_AUTO_CORR 0x02 - #define XGI_SIMULTANEOUS_VIEW_ENABLE 0x01 /* CR30 */ #define XGI_MODE_SELECT_CRT2 0x02 #define XGI_VB_OUTPUT_COMPOSITE 0x04 @@ -350,8 +326,6 @@ static int XGIfb_CRT2_write_enable = 0; static int XGIfb_crt2type = -1; /* TW: CRT2 type (for overriding autodetection) */ static int XGIfb_tvplug = -1; /* PR: Tv plug type (for overriding autodetection) */ -static int XGIfb_queuemode = -1; /* TW: Use MMIO queue mode by default (310/325 series only) */ - static unsigned char XGIfb_detectedpdc = 0; static unsigned char XGIfb_detectedlcda = 0xff; @@ -368,15 +342,6 @@ static struct xgi_hw_device_info XGIhw_ext; /* TW: XGI private structure */ static struct vb_device_info XGI_Pr; -/* card parameters */ -static u8 XGIfb_caps = 0; - -typedef enum _XGI_CMDTYPE { - MMIO_CMD = 0, - AGP_CMD_QUEUE, - VM_CMD_QUEUE, -} XGI_CMDTYPE; - #define MD_XGI300 1 #define MD_XGI315 2 @@ -519,20 +484,6 @@ static const struct _XGI_crt2type { {"\0", -1, -1} }; -/* Queue mode selection for 310 series */ -static const struct _XGI_queuemode { - char name[6]; - int type_no; -} XGI_queuemode[] = { - {"AGP", AGP_CMD_QUEUE}, - {"VRAM", VM_CMD_QUEUE}, - {"MMIO", MMIO_CMD}, - {"agp", AGP_CMD_QUEUE}, - {"vram", VM_CMD_QUEUE}, - {"mmio", MMIO_CMD}, - {"\0", -1} -}; - /* TV standard */ static const struct _XGI_tvtype { char name[6]; diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 3998dd485dfa..08551e94ad54 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -898,24 +898,6 @@ static void XGIfb_search_crt2type(const char *name) printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name); } -static void XGIfb_search_queuemode(const char *name) -{ - int i = 0; - - if (name == NULL) - return; - - while (XGI_queuemode[i].type_no != -1) { - if (!strcmp(name, XGI_queuemode[i].name)) { - XGIfb_queuemode = XGI_queuemode[i].type_no; - break; - } - i++; - } - if (XGIfb_queuemode < 0) - printk(KERN_INFO "XGIfb: Invalid queuemode type: %s\n", name); -} - static u8 XGIfb_search_refresh_rate(unsigned int rate) { u16 xres, yres; @@ -1906,19 +1888,6 @@ void XGI_Sense30x(void) static int XGIfb_heap_init(void) { XGI_OH *poh; - u8 temp = 0; - - int agp_enabled = 1; - u32 agp_size; - unsigned long *cmdq_baseport = NULL; - unsigned long *read_port = NULL; - unsigned long *write_port = NULL; - XGI_CMDTYPE cmd_type; -#ifndef AGPOFF - struct agp_kern_info *agp_info; - struct agp_memory *agp; - u32 agp_phys; -#endif /* TW: The heap start is either set manually using the "mem" parameter, or * defaults as follows: @@ -1950,178 +1919,6 @@ static int XGIfb_heap_init(void) + xgi_video_info.video_size; XGIfb_heap_size = XGIfb_heap_end - XGIfb_heap_start; - /* TW: Now initialize the 310 series' command queue mode. - * On 310/325, there are three queue modes available which - * are chosen by setting bits 7:5 in SR26: - * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep - * track of the queue, the FIFO, command parsing and so - * on. This is the one comparable to the 300 series. - * 2. VRAM queue mode (bit 6, 0x40). In this case, one will - * have to do queue management himself. Register 0x85c4 will - * hold the location of the next free queue slot, 0x85c8 - * is the "queue read pointer" whose way of working is - * unknown to me. Anyway, this mode would require a - * translation of the MMIO commands to some kind of - * accelerator assembly and writing these commands - * to the memory location pointed to by 0x85c4. - * We will not use this, as nobody knows how this - * "assembly" works, and as it would require a complete - * re-write of the accelerator code. - * 3. AGP queue mode (bit 7, 0x80). Works as 2., but keeps the - * queue in AGP memory space. - * - * SR26 bit 4 is called "Bypass H/W queue". - * SR26 bit 1 is called "Enable Command Queue Auto Correction" - * SR26 bit 0 resets the queue - * Size of queue memory is encoded in bits 3:2 like this: - * 00 (0x00) 512K - * 01 (0x04) 1M - * 10 (0x08) 2M - * 11 (0x0C) 4M - * The queue location is to be written to 0x85C0. - * - */ - cmdq_baseport = (unsigned long *) (xgi_video_info.mmio_vbase - + MMIO_QUEUE_PHYBASE); - write_port = (unsigned long *) (xgi_video_info.mmio_vbase - + MMIO_QUEUE_WRITEPORT); - read_port = (unsigned long *) (xgi_video_info.mmio_vbase - + MMIO_QUEUE_READPORT); - - DPRINTK("AGP base: 0x%p, read: 0x%p, write: 0x%p\n", cmdq_baseport, read_port, write_port); - - agp_size = COMMAND_QUEUE_AREA_SIZE; - -#ifndef AGPOFF - if (XGIfb_queuemode == AGP_CMD_QUEUE) { - agp_info = vzalloc(sizeof(*agp_info)); - agp_copy_info(agp_info); - - agp_backend_acquire(); - - agp = agp_allocate_memory(COMMAND_QUEUE_AREA_SIZE / PAGE_SIZE, - AGP_NORMAL_MEMORY); - if (agp == NULL) { - DPRINTK("XGIfb: Allocating AGP buffer failed.\n"); - agp_enabled = 0; - } else { - if (agp_bind_memory(agp, agp->pg_start) != 0) { - DPRINTK("XGIfb: AGP: Failed to bind memory\n"); - /* TODO: Free AGP memory here */ - agp_enabled = 0; - } else { - agp_enable(0); - } - } - } -#else - agp_enabled = 0; -#endif - - /* TW: Now select the queue mode */ - - if ((agp_enabled) && (XGIfb_queuemode == AGP_CMD_QUEUE)) { - cmd_type = AGP_CMD_QUEUE; - printk(KERN_INFO "XGIfb: Using AGP queue mode\n"); - /* } else if (XGIfb_heap_size >= COMMAND_QUEUE_AREA_SIZE) */ - } else if (XGIfb_queuemode == VM_CMD_QUEUE) { - cmd_type = VM_CMD_QUEUE; - printk(KERN_INFO "XGIfb: Using VRAM queue mode\n"); - } else { - printk(KERN_INFO "XGIfb: Using MMIO queue mode\n"); - cmd_type = MMIO_CMD; - } - - switch (agp_size) { - case 0x80000: - temp = XGI_CMD_QUEUE_SIZE_512k; - break; - case 0x100000: - temp = XGI_CMD_QUEUE_SIZE_1M; - break; - case 0x200000: - temp = XGI_CMD_QUEUE_SIZE_2M; - break; - case 0x400000: - temp = XGI_CMD_QUEUE_SIZE_4M; - break; - } - - switch (cmd_type) { - case AGP_CMD_QUEUE: -#ifndef AGPOFF - DPRINTK("XGIfb: AGP buffer base = 0x%lx, offset = 0x%x, size = %dK\n", - agp_info->aper_base, agp->physical, agp_size/1024); - - agp_phys = agp_info->aper_base + agp->physical; - - outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, 0); - outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, XGI_AGP_2X); - - outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD); - - outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET); - - *write_port = *read_port; - - temp |= XGI_AGP_CMDQUEUE_ENABLE; - outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp); - - *cmdq_baseport = agp_phys; - - XGIfb_caps |= AGP_CMD_QUEUE_CAP; -#endif - break; - - case VM_CMD_QUEUE: - XGIfb_heap_end -= COMMAND_QUEUE_AREA_SIZE; - XGIfb_heap_size -= COMMAND_QUEUE_AREA_SIZE; - - outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD); - - outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET); - - *write_port = *read_port; - - temp |= XGI_VRAM_CMDQUEUE_ENABLE; - outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp); - - *cmdq_baseport = xgi_video_info.video_size - COMMAND_QUEUE_AREA_SIZE; - - XGIfb_caps |= VM_CMD_QUEUE_CAP; - - DPRINTK("XGIfb: VM Cmd Queue offset = 0x%lx, size is %dK\n", - *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024); - break; - - default: /* MMIO */ - - /* printk("%s:%d - I'm here\n", __FUNCTION__, __LINE__); */ - /* TW: This previously only wrote XGI_MMIO_CMD_ENABLE - * to IND_XGI_CMDQUEUE_SET. I doubt that this is - * enough. Reserve memory in any way. - */ - /* FIXME XGIfb_heap_end -= COMMAND_QUEUE_AREA_SIZE; */ - /* FIXME XGIfb_heap_size -= COMMAND_QUEUE_AREA_SIZE; */ - /* FIXME */ - /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD); */ - /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET); */ - /* FIXME */ - /* FIXME *write_port = *read_port; */ - /* FIXME */ - /* FIXME *//* TW: Set Auto_Correction bit */ - /* FIXME temp |= (XGI_MMIO_CMD_ENABLE | XGI_CMD_AUTO_CORR); */ - /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp); */ - /* FIXME */ - /* FIXME *cmdq_baseport = xgi_video_info.video_size - COMMAND_QUEUE_AREA_SIZE; */ - /* FIXME */ - /* FIXME XGIfb_caps |= MMIO_CMD_QUEUE_CAP; */ - /* FIXME */ - /* FIXME DPRINTK("XGIfb: MMIO Cmd Queue offset = 0x%lx, size is %dK\n", */ - /* FIXME *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024); */ - break; -} - XGIfb_heap.poha_chain = NULL; XGIfb_heap.poh_freelist = NULL; @@ -2643,8 +2440,6 @@ XGIINITSTATIC int __init XGIfb_setup(char *options) enable_dstn = 1; /* TW: DSTN overrules forcecrt2type */ XGIfb_crt2type = DISPTYPE_LCD; - } else if (!strncmp(this_opt, "queuemode:", 10)) { - XGIfb_search_queuemode(this_opt + 10); } else if (!strncmp(this_opt, "pdc:", 4)) { XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0); if (XGIfb_pdc & ~0x3c) { @@ -2662,10 +2457,6 @@ XGIINITSTATIC int __init XGIfb_setup(char *options) /* printk(KERN_INFO "XGIfb: Invalid option %s\n", this_opt); */ } - /* TW: Acceleration only with MMIO mode */ - if ((XGIfb_queuemode != -1) && (XGIfb_queuemode != MMIO_CMD)) { - XGIfb_ypan = 0; - } /* TW: Panning only with acceleration */ XGIfb_ypan = 0; -- cgit v1.2.3 From 3259bb5a1384c58935f8d95f1dbbab7f51b17e25 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 8 Mar 2011 22:16:08 +0200 Subject: staging: xgifb: delete offscreen memory management The offscreen memory area currently conflicts with the video memory exported to the framebuffer layer. The driver does not utilize offscreen memory, so the functionality can be deleted. The patch also eliminates the one last memory leak when the driver is unloaded. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main.h | 47 ------ drivers/staging/xgifb/XGI_main_26.c | 319 ------------------------------------ drivers/staging/xgifb/XGIfb.h | 1 - 3 files changed, 367 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index 2c55faacc074..b27623a1578d 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -65,9 +65,6 @@ MODULE_DEVICE_TABLE(pci, xgifb_pci_table); #define MAX_ROM_SCAN 0x10000 -#define OH_ALLOC_SIZE 4000 -#define SENTINEL 0x7fffffff - #define SEQ_ADR 0x14 #define SEQ_DATA 0x15 #define DAC_ADR 0x18 @@ -315,7 +312,6 @@ static int XGIfb_userom = 0; /* global flags */ static int XGIfb_registered; static int XGIfb_tvmode = 0; -static int XGIfb_mem = 0; static int XGIfb_pdc = 0; static int enable_dstn = 0; static int XGIfb_ypan = -1; @@ -538,31 +534,6 @@ static const struct _chswtable { { 0, 0, "" , "" } }; -typedef struct _XGI_OH { - struct _XGI_OH *poh_next; - struct _XGI_OH *poh_prev; - unsigned long offset; - unsigned long size; -} XGI_OH; - -typedef struct _XGI_OHALLOC { - struct _XGI_OHALLOC *poha_next; - XGI_OH aoh[1]; -} XGI_OHALLOC; - -typedef struct _XGI_HEAP { - XGI_OH oh_free; - XGI_OH oh_used; - XGI_OH *poh_freelist; - XGI_OHALLOC *poha_chain; - unsigned long max_freesize; -} XGI_HEAP; - -static unsigned long XGIfb_heap_start; -static unsigned long XGIfb_heap_end; -static unsigned long XGIfb_heap_size; -static XGI_HEAP XGIfb_heap; - // Eden Chen static const struct _XGI_TV_filter { u8 filter[9][4]; @@ -766,15 +737,6 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, static void XGIfb_pre_setmode(void); static void XGIfb_post_setmode(void); -struct XGI_memreq { - unsigned long offset; - unsigned long size; -}; - -/* XGI-specific Export functions */ -void XGI_malloc(struct XGI_memreq *req); -void XGI_free(unsigned long base); - /* Internal hardware access routines */ void XGIfb_set_reg4(u16 port, unsigned long data); u32 XGIfb_get_reg3(u16 port); @@ -788,15 +750,6 @@ static void XGIfb_get_VB_type(void); static int XGIfb_has_VB(void); -/* Internal heap routines */ -static int XGIfb_heap_init(void); -static XGI_OH *XGIfb_poh_new_node(void); -static XGI_OH *XGIfb_poh_allocate(unsigned long size); -static void XGIfb_delete_node(XGI_OH *poh); -static void XGIfb_insert_node(XGI_OH *pohList, XGI_OH *poh); -static XGI_OH *XGIfb_poh_free(unsigned long base); -static void XGIfb_free_node(XGI_OH *poh); - /* Internal routines to access PCI configuration space */ unsigned char XGIfb_query_VGA_config_space(struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset, diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 08551e94ad54..aeccdeece6a2 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1495,16 +1495,6 @@ static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con, fix->smem_len = xgi_video_info.video_size; - /* if((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size/1024))) { - if (xgi_video_info.video_size > 0x1000000) { - fix->smem_len = 0xD00000; - } else if (xgi_video_info.video_size > 0x800000) - fix->smem_len = 0x800000; - else - fix->smem_len = 0x400000; - } else - fix->smem_len = XGIfb_mem * 1024; - */ fix->type = video_type; fix->type_aux = 0; if (xgi_video_info.video_bpp == 8) @@ -1883,297 +1873,6 @@ void XGI_Sense30x(void) outXGIIDXREG(XGIPART4, 0x0d, backupP4_0d); } -/* ------------------------ Heap routines -------------------------- */ - -static int XGIfb_heap_init(void) -{ - XGI_OH *poh; - - /* TW: The heap start is either set manually using the "mem" parameter, or - * defaults as follows: - * -) If more than 16MB videoRAM available, let our heap start at 12MB. - * -) If more than 8MB videoRAM available, let our heap start at 8MB. - * -) If 4MB or less is available, let it start at 4MB. - * This is for avoiding a clash with X driver which uses the beginning - * of the videoRAM. To limit size of X framebuffer, use Option MaxXFBMem - * in XF86Config-4. - * The heap start can also be specified by parameter "mem" when starting the XGIfb - * driver. XGIfb mem=1024 lets heap starts at 1MB, etc. - */ - if ((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size / 1024))) { - if (xgi_video_info.video_size > 0x1000000) - xgi_video_info.heapstart = 0xD00000; - else if (xgi_video_info.video_size > 0x800000) - xgi_video_info.heapstart = 0x800000; - else - xgi_video_info.heapstart = 0x400000; - } else { - xgi_video_info.heapstart = XGIfb_mem * 1024; - } - XGIfb_heap_start = (unsigned long) (xgi_video_info.video_vbase - + xgi_video_info.heapstart); - printk(KERN_INFO "XGIfb: Memory heap starting at %dK\n", - (int)(xgi_video_info.heapstart / 1024)); - - XGIfb_heap_end = (unsigned long) xgi_video_info.video_vbase - + xgi_video_info.video_size; - XGIfb_heap_size = XGIfb_heap_end - XGIfb_heap_start; - - XGIfb_heap.poha_chain = NULL; - XGIfb_heap.poh_freelist = NULL; - - poh = XGIfb_poh_new_node(); - - if (poh == NULL) - return 1; - - poh->poh_next = &XGIfb_heap.oh_free; - poh->poh_prev = &XGIfb_heap.oh_free; - poh->size = XGIfb_heap_end - XGIfb_heap_start + 1; - poh->offset = XGIfb_heap_start - (unsigned long) xgi_video_info.video_vbase; - - DPRINTK("XGIfb: Heap start:0x%p, end:0x%p, len=%dk\n", - (char *) XGIfb_heap_start, (char *) XGIfb_heap_end, - (unsigned int) poh->size / 1024); - - DPRINTK("XGIfb: First Node offset:0x%x, size:%dk\n", - (unsigned int) poh->offset, (unsigned int) poh->size / 1024); - - XGIfb_heap.oh_free.poh_next = poh; - XGIfb_heap.oh_free.poh_prev = poh; - XGIfb_heap.oh_free.size = 0; - XGIfb_heap.max_freesize = poh->size; - - XGIfb_heap.oh_used.poh_next = &XGIfb_heap.oh_used; - XGIfb_heap.oh_used.poh_prev = &XGIfb_heap.oh_used; - XGIfb_heap.oh_used.size = SENTINEL; - - return 0; -} - -static XGI_OH *XGIfb_poh_new_node(void) -{ - int i; - unsigned long cOhs; - XGI_OHALLOC *poha; - XGI_OH *poh; - - if (XGIfb_heap.poh_freelist == NULL) { - poha = kmalloc(OH_ALLOC_SIZE, GFP_KERNEL); - if (!poha) - return NULL; - - poha->poha_next = XGIfb_heap.poha_chain; - XGIfb_heap.poha_chain = poha; - - cOhs = (OH_ALLOC_SIZE - sizeof(XGI_OHALLOC)) / sizeof(XGI_OH) - + 1; - - poh = &poha->aoh[0]; - for (i = cOhs - 1; i != 0; i--) { - poh->poh_next = poh + 1; - poh = poh + 1; - } - - poh->poh_next = NULL; - XGIfb_heap.poh_freelist = &poha->aoh[0]; - } - - poh = XGIfb_heap.poh_freelist; - XGIfb_heap.poh_freelist = poh->poh_next; - - return poh; -} - -static XGI_OH *XGIfb_poh_allocate(unsigned long size) -{ - XGI_OH *pohThis; - XGI_OH *pohRoot; - int bAllocated = 0; - - if (size > XGIfb_heap.max_freesize) { - DPRINTK("XGIfb: Can't allocate %dk size on offscreen\n", - (unsigned int) size / 1024); - return NULL; - } - - pohThis = XGIfb_heap.oh_free.poh_next; - - while (pohThis != &XGIfb_heap.oh_free) { - if (size <= pohThis->size) { - bAllocated = 1; - break; - } - pohThis = pohThis->poh_next; - } - - if (!bAllocated) { - DPRINTK("XGIfb: Can't allocate %dk size on offscreen\n", - (unsigned int) size / 1024); - return NULL; - } - - if (size == pohThis->size) { - pohRoot = pohThis; - XGIfb_delete_node(pohThis); - } else { - pohRoot = XGIfb_poh_new_node(); - - if (pohRoot == NULL) - return NULL; - - pohRoot->offset = pohThis->offset; - pohRoot->size = size; - - pohThis->offset += size; - pohThis->size -= size; - } - - XGIfb_heap.max_freesize -= size; - - pohThis = &XGIfb_heap.oh_used; - XGIfb_insert_node(pohThis, pohRoot); - - return pohRoot; -} - -static void XGIfb_delete_node(XGI_OH *poh) -{ - XGI_OH *poh_prev; - XGI_OH *poh_next; - - poh_prev = poh->poh_prev; - poh_next = poh->poh_next; - - poh_prev->poh_next = poh_next; - poh_next->poh_prev = poh_prev; - -} - -static void XGIfb_insert_node(XGI_OH *pohList, XGI_OH *poh) -{ - XGI_OH *pohTemp; - - pohTemp = pohList->poh_next; - - pohList->poh_next = poh; - pohTemp->poh_prev = poh; - - poh->poh_prev = pohList; - poh->poh_next = pohTemp; -} - -static XGI_OH *XGIfb_poh_free(unsigned long base) -{ - XGI_OH *pohThis; - XGI_OH *poh_freed; - XGI_OH *poh_prev; - XGI_OH *poh_next; - unsigned long ulUpper; - unsigned long ulLower; - int foundNode = 0; - - poh_freed = XGIfb_heap.oh_used.poh_next; - - while (poh_freed != &XGIfb_heap.oh_used) { - if (poh_freed->offset == base) { - foundNode = 1; - break; - } - - poh_freed = poh_freed->poh_next; - } - - if (!foundNode) - return NULL; - - XGIfb_heap.max_freesize += poh_freed->size; - - poh_prev = poh_next = NULL; - ulUpper = poh_freed->offset + poh_freed->size; - ulLower = poh_freed->offset; - - pohThis = XGIfb_heap.oh_free.poh_next; - - while (pohThis != &XGIfb_heap.oh_free) { - if (pohThis->offset == ulUpper) - poh_next = pohThis; - else if ((pohThis->offset + pohThis->size) == ulLower) - poh_prev = pohThis; - - pohThis = pohThis->poh_next; - } - - XGIfb_delete_node(poh_freed); - - if (poh_prev && poh_next) { - poh_prev->size += (poh_freed->size + poh_next->size); - XGIfb_delete_node(poh_next); - XGIfb_free_node(poh_freed); - XGIfb_free_node(poh_next); - return poh_prev; - } - - if (poh_prev) { - poh_prev->size += poh_freed->size; - XGIfb_free_node(poh_freed); - return poh_prev; - } - - if (poh_next) { - poh_next->size += poh_freed->size; - poh_next->offset = poh_freed->offset; - XGIfb_free_node(poh_freed); - return poh_next; - } - - XGIfb_insert_node(&XGIfb_heap.oh_free, poh_freed); - - return poh_freed; -} - -static void XGIfb_free_node(XGI_OH *poh) -{ - if (poh == NULL) - return; - - poh->poh_next = XGIfb_heap.poh_freelist; - XGIfb_heap.poh_freelist = poh; - -} - -void XGI_malloc(struct XGI_memreq *req) -{ - XGI_OH *poh; - - poh = XGIfb_poh_allocate(req->size); - - if (poh == NULL) { - req->offset = 0; - req->size = 0; - DPRINTK("XGIfb: Video RAM allocation failed\n"); - } else { - DPRINTK("XGIfb: Video RAM allocation succeeded: 0x%p\n", - (char *) (poh->offset + (unsigned long) xgi_video_info.video_vbase)); - - req->offset = poh->offset; - req->size = poh->size; - } - -} - -void XGI_free(unsigned long base) -{ - XGI_OH *poh; - - poh = XGIfb_poh_free(base); - - if (poh == NULL) { - DPRINTK("XGIfb: XGIfb_poh_free() failed at base 0x%x\n", - (unsigned int) base); - } -} - /* --------------------- SetMode routines ------------------------- */ static void XGIfb_pre_setmode(void) @@ -2434,8 +2133,6 @@ XGIINITSTATIC int __init XGIfb_setup(char *options) XGIfb_search_tvstd(this_opt + 7); } else if (!strncmp(this_opt, "tvstandard:", 11)) { XGIfb_search_tvstd(this_opt + 7); - } else if (!strncmp(this_opt, "mem:", 4)) { - XGIfb_mem = simple_strtoul(this_opt + 4, NULL, 0); } else if (!strncmp(this_opt, "dstn", 4)) { enable_dstn = 1; /* TW: DSTN overrules forcecrt2type */ @@ -2686,9 +2383,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, else printk("Fail\n"); - if (XGIfb_heap_init()) - printk(KERN_WARNING "XGIfb: Failed to initialize offscreen memory heap\n"); - xgi_video_info.mtrr = (unsigned int) 0; if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) { @@ -3074,15 +2768,6 @@ module_param(resetcard, int, 0); module_param(videoram, int, 0); #endif -MODULE_PARM_DESC(mem, - "\nDetermines the beginning of the video memory heap in KB. This heap is used\n" - "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n" - "on the amount of video RAM available. If 8MB of video RAM or less is available,\n" - "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n" - "otherwise at 12288KB. On 315 and Xabre series, the heap size is 32KB by default.\n" - "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n" - "for XFree86 4.x/X.org 6.7 and later.\n"); - MODULE_PARM_DESC(noypan, "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n" "will be performed by redrawing the screen. (default: 0)\n"); @@ -3191,7 +2876,3 @@ module_init(xgifb_init_module); module_exit(xgifb_remove_module); #endif /* /MODULE */ - -EXPORT_SYMBOL(XGI_malloc); -EXPORT_SYMBOL(XGI_free); - diff --git a/drivers/staging/xgifb/XGIfb.h b/drivers/staging/xgifb/XGIfb.h index d6c3139f72e6..7813bbe664ae 100644 --- a/drivers/staging/xgifb/XGIfb.h +++ b/drivers/staging/xgifb/XGIfb.h @@ -92,7 +92,6 @@ struct video_info{ char * mmio_vbase; unsigned long vga_base; unsigned long mtrr; - unsigned long heapstart; int video_bpp; int video_cmap_len; -- cgit v1.2.3 From 66c2458c7943c29a2221896c213ec1d244c64ded Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 8 Mar 2011 22:16:09 +0200 Subject: staging: xgifb: delete unused fields from xgi_hw_device_info Delete unused fields from xgi_hw_device_info. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 4 ---- drivers/staging/xgifb/vgatypes.h | 29 ----------------------------- 2 files changed, 33 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index aeccdeece6a2..fa30a2614b07 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -2287,7 +2287,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, break; } - XGIhw_ext.pDevice = NULL; if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) { XGIhw_ext.pjVirtualRomBase = xgifb_copy_rom(pdev); if (XGIhw_ext.pjVirtualRomBase) @@ -2298,10 +2297,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, XGIhw_ext.pjVirtualRomBase = NULL; printk(KERN_INFO "XGIfb: Video ROM usage disabled\n"); } - XGIhw_ext.pjCustomizedROMImage = NULL; XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space; - /* XGIhw_ext.pQueryNorthBridgeSpace = &XGIfb_query_north_bridge_space; */ - strcpy(XGIhw_ext.szVBIOSVer, "0.84"); if (!XGIvga_enabled) { /* Mapping Max FB Size for 315 Init */ diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h index dacdac3e204c..13c02be38130 100644 --- a/drivers/staging/xgifb/vgatypes.h +++ b/drivers/staging/xgifb/vgatypes.h @@ -4,10 +4,6 @@ #include -#ifndef VBIOS_VER_MAX_LENGTH -#define VBIOS_VER_MAX_LENGTH 5 -#endif - #ifndef XGI_VB_CHIP_TYPE enum XGI_VB_CHIP_TYPE { VB_CHIP_Legacy = 0, @@ -65,10 +61,6 @@ struct xgi_hw_device_info unsigned char *pjVirtualRomBase; /* ROM image */ - unsigned char UseROM; /* Use the ROM image if provided */ - - void *pDevice; - unsigned char *pjVideoMemoryAddress;/* base virtual memory address */ /* of Linear VGA memory */ @@ -76,12 +68,6 @@ struct xgi_hw_device_info unsigned char *pjIOAddress; /* base I/O address of VGA ports (0x3B0) */ - unsigned char *pjCustomizedROMImage; - - unsigned char *pj2ndVideoMemoryAddress; - unsigned long ul2ndVideoMemorySize; - - unsigned char *pj2ndIOAddress; unsigned char jChipType; /* Used to Identify Graphics Chip */ /* defined in the data structure type */ /* "XGI_CHIP_TYPE" */ @@ -92,30 +78,15 @@ struct xgi_hw_device_info /* defined in the data structure type */ /* "XGI_VB_CHIP_TYPE" */ - unsigned char bNewScratch; - unsigned long ulCRT2LCDType; /* defined in the data structure type */ - unsigned long usExternalChip; /* NO VB or other video bridge (other than */ - /* video bridge) */ - unsigned char bIntegratedMMEnabled;/* supporting integration MM enable */ unsigned char bSkipSense; - unsigned char bIsPowerSaving; /* True: XGIInit() is invoked by power management, - otherwise by 2nd adapter's initialzation */ - unsigned char(*pQueryVGAConfigSpace)(struct xgi_hw_device_info *, unsigned long, unsigned long, unsigned long *); - - unsigned char(*pQueryNorthBridgeSpace)(struct xgi_hw_device_info *, - unsigned long, unsigned long, - unsigned long *); - - unsigned char szVBIOSVer[VBIOS_VER_MAX_LENGTH]; - }; /* Addtional IOCTL for communication xgifb <> X driver */ -- cgit v1.2.3 From 600a710b8bb414903a8b7c28e22ca03a60b8191f Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 8 Mar 2011 22:16:10 +0200 Subject: staging: xgifb: delete bSkipSense bSkipSense is always false, thus redundant. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 44 +++++++++++++++++++--------------------- drivers/staging/xgifb/vgatypes.h | 2 -- 2 files changed, 21 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 9a5aa6c9f929..e33259a5e860 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -388,34 +388,32 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) XGINew_SetReg1(pVBInfo->P3d4, 0x83, 0x00); printk("181"); - if (HwDeviceExtension->bSkipSense == 0) { - printk("182"); + printk("182"); - XGI_SenseCRT1(pVBInfo); + XGI_SenseCRT1(pVBInfo); - printk("183"); - /* XGINew_DetectMonitor(HwDeviceExtension); */ - pVBInfo->IF_DEF_CH7007 = 0; - if ((HwDeviceExtension->jChipType == XG21) && (pVBInfo->IF_DEF_CH7007)) { - printk("184"); - XGI_GetSenseStatus(HwDeviceExtension, pVBInfo); /* sense CRT2 */ - printk("185"); + printk("183"); + /* XGINew_DetectMonitor(HwDeviceExtension); */ + pVBInfo->IF_DEF_CH7007 = 0; + if ((HwDeviceExtension->jChipType == XG21) && (pVBInfo->IF_DEF_CH7007)) { + printk("184"); + XGI_GetSenseStatus(HwDeviceExtension, pVBInfo); /* sense CRT2 */ + printk("185"); - } - if (HwDeviceExtension->jChipType == XG21) { - printk("186"); + } + if (HwDeviceExtension->jChipType == XG21) { + printk("186"); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */ - temp = GetXG21FPBits(pVBInfo); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~0x01, temp); - printk("187"); + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */ + temp = GetXG21FPBits(pVBInfo); + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~0x01, temp); + printk("187"); - } - if (HwDeviceExtension->jChipType == XG27) { - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */ - temp = GetXG27FPBits(pVBInfo); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~0x03, temp); - } + } + if (HwDeviceExtension->jChipType == XG27) { + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */ + temp = GetXG27FPBits(pVBInfo); + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~0x03, temp); } printk("19"); diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h index 13c02be38130..c4624ccb02b7 100644 --- a/drivers/staging/xgifb/vgatypes.h +++ b/drivers/staging/xgifb/vgatypes.h @@ -82,8 +82,6 @@ struct xgi_hw_device_info unsigned char bIntegratedMMEnabled;/* supporting integration MM enable */ - unsigned char bSkipSense; - unsigned char(*pQueryVGAConfigSpace)(struct xgi_hw_device_info *, unsigned long, unsigned long, unsigned long *); -- cgit v1.2.3 From dbbc2989a78872922601791983762c207a60f38c Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 8 Mar 2011 22:16:11 +0200 Subject: staging: xgifb: delete bIntegratedMMEnabled bIntegratedMMEnabled is always true, so the field and checks can be eliminated. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 14 -------------- drivers/staging/xgifb/vb_init.c | 3 --- drivers/staging/xgifb/vgatypes.h | 2 -- 3 files changed, 19 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index fa30a2614b07..ce569af3781b 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -2273,20 +2273,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, printk("XGIfb:chipid = %x\n", xgi_video_info.chip); XGIhw_ext.jChipType = xgi_video_info.chip; - switch (xgi_video_info.chip) { - case XG40: - case XG41: - case XG42: - case XG45: - case XG20: - case XG21: - case XG27: - XGIhw_ext.bIntegratedMMEnabled = 1; - break; - default: - break; - } - if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) { XGIhw_ext.pjVirtualRomBase = xgifb_copy_rom(pdev); if (XGIhw_ext.pjVirtualRomBase) diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index e33259a5e860..a16827e3e869 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -152,9 +152,6 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) pVBInfo->ISXPDOS = 0; printk("3"); - if (!HwDeviceExtension->bIntegratedMMEnabled) - return 0; /* alan */ - printk("4"); /* VBIOSVersion[4] = 0x0; */ diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h index c4624ccb02b7..4b87951f4322 100644 --- a/drivers/staging/xgifb/vgatypes.h +++ b/drivers/staging/xgifb/vgatypes.h @@ -80,8 +80,6 @@ struct xgi_hw_device_info unsigned long ulCRT2LCDType; /* defined in the data structure type */ - unsigned char bIntegratedMMEnabled;/* supporting integration MM enable */ - unsigned char(*pQueryVGAConfigSpace)(struct xgi_hw_device_info *, unsigned long, unsigned long, unsigned long *); -- cgit v1.2.3 From 95befb581897a37592a19613859072edf6647be8 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 8 Mar 2011 22:16:12 +0200 Subject: staging: xgifb: delete nomax module parameter The parameter is not used. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index ce569af3781b..ee8017175762 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -2707,7 +2707,6 @@ static int forcecrt1 = -1; static int pdc = -1; static int pdc1 = -1; static int noypan = -1; -static int nomax = -1; static int userom = -1; static int useoem = -1; static char *tvstandard = NULL; @@ -2727,7 +2726,6 @@ MODULE_AUTHOR("XGITECH , Others"); module_param(mem, int, 0); module_param(noypan, int, 0); -module_param(nomax, int, 0); module_param(userom, int, 0); module_param(useoem, int, 0); module_param(mode, charp, 0); @@ -2754,13 +2752,6 @@ MODULE_PARM_DESC(noypan, "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n" "will be performed by redrawing the screen. (default: 0)\n"); -MODULE_PARM_DESC(nomax, - "\nIf y-panning is enabled, xgifb will by default use the entire available video\n" - "memory for the virtual screen in order to optimize scrolling performance. If\n" - "this is set to anything other than 0, xgifb will not do this and thereby\n" - "enable the user to positively specify a virtual Y size of the screen using\n" - "fbset. (default: 0)\n"); - MODULE_PARM_DESC(mode, "\nSelects the desired default display mode in the format XxYxDepth,\n" "eg. 1024x768x16. Other formats supported include XxY-Depth and\n" -- cgit v1.2.3 From 063b9c4b89eac6f6c0b3b40594f48dbac14dd2f8 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 8 Mar 2011 22:16:13 +0200 Subject: staging: xgifb: vb_setmode: make internal functions static Make internal functions static and remove unneeded forward declarations. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 372 ++++++++++++++++++------------------- drivers/staging/xgifb/vb_setmode.h | 4 - 2 files changed, 176 insertions(+), 200 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index fa2cf9625598..0f37c80431b3 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -21,16 +21,11 @@ -unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo); unsigned char XGI_SetCRT2Group301(unsigned short ModeNo, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -unsigned char XGI_BacklightByDrv(struct vb_device_info *pVBInfo); -unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo); -unsigned char XGI_DisableChISLCD(struct vb_device_info *pVBInfo); -unsigned char XGI_EnableChISLCD(struct vb_device_info *pVBInfo); -unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, +static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, unsigned short *i, struct vb_device_info *pVBInfo); @@ -43,10 +38,10 @@ unsigned char XGI_GetLCDInfo(unsigned short ModeNo, unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo); unsigned char XGI_BridgeIsOn(struct vb_device_info *pVBInfo); -unsigned char XGI_GetModePtr(unsigned short ModeNo, +static unsigned char XGI_GetModePtr(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -unsigned short XGI_GetOffset(unsigned short ModeNo, +static unsigned short XGI_GetOffset(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, @@ -58,139 +53,124 @@ unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, unsigned short XGI_GetResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -unsigned short XGI_GetColorDepth(unsigned short ModeNo, +static unsigned short XGI_GetColorDepth(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo); -unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, +static unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo); +static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -void XGI_VBLongWait(struct vb_device_info *pVBInfo); -void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBInfo); -void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -void XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -void XGI_FirePWDEnable(struct vb_device_info *pVBInfo); -void XGI_EnableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -void XGI_DisableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -void XGI_SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBInfo); -void XGI_SetPanelPower(unsigned short tempah, unsigned short tempbl, struct vb_device_info *pVBInfo); -void XGI_EnablePWD(struct vb_device_info *pVBInfo); -void XGI_DisablePWD(struct vb_device_info *pVBInfo); -void XGI_AutoThreshold(struct vb_device_info *pVBInfo); -void XGI_SetTap4Regs(struct vb_device_info *pVBInfo); +static void XGI_VBLongWait(struct vb_device_info *pVBInfo); +static void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBInfo); +static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); +static void XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); +static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); +static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); +static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); +static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); +static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); +static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); +static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); +static void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); +static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); +static void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); +static void XGI_AutoThreshold(struct vb_device_info *pVBInfo); +static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo); void XGI_DisplayOn(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); void XGI_DisplayOff(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); -void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -void XGI_SetXG21LCD(struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex, unsigned short ModeNo); -void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -void XGI_SetXG27LCD(struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex, unsigned short ModeNo); -void XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex); -void XGI_WaitDisply(struct vb_device_info *pVBInfo); +static void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); +static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); +static void XGI_SetXG21LCD(struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex, unsigned short ModeNo); +static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); +static void XGI_SetXG27LCD(struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex, unsigned short ModeNo); +static void XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex); void XGI_SenseCRT1(struct vb_device_info *pVBInfo); -void XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -void XGI_SetMiscRegs(unsigned short StandTableIndex, struct vb_device_info *pVBInfo); -void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, unsigned short StandTableIndex, struct vb_device_info *pVBInfo); -void XGI_SetATTRegs(unsigned short ModeNo, unsigned short StandTableIndex, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -void XGI_SetGRCRegs(unsigned short StandTableIndex, struct vb_device_info *pVBInfo); -void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo); - -void XGI_SetSync(unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo, struct xgi_hw_device_info *HwDeviceExtension); -void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, struct xgi_hw_device_info *HwDeviceExtension); -void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeNo, struct vb_device_info *pVBInfo); -void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -void XGI_SetCRT1FIFO(unsigned short ModeNo, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); - -void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -void XGI_WriteDAC(unsigned short dl, unsigned short ah, unsigned short al, unsigned short dh, struct vb_device_info *pVBInfo); +static void XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); +static void XGI_SetMiscRegs(unsigned short StandTableIndex, struct vb_device_info *pVBInfo); +static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, unsigned short StandTableIndex, struct vb_device_info *pVBInfo); +static void XGI_SetATTRegs(unsigned short ModeNo, unsigned short StandTableIndex, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); +static void XGI_SetGRCRegs(unsigned short StandTableIndex, struct vb_device_info *pVBInfo); +static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo); + +static void XGI_SetSync(unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); +static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo, struct xgi_hw_device_info *HwDeviceExtension); +static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, struct xgi_hw_device_info *HwDeviceExtension); +static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeNo, struct vb_device_info *pVBInfo); +static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); +static void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); +static void XGI_SetCRT1FIFO(unsigned short ModeNo, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); +static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); +static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); + +static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); +static void XGI_WriteDAC(unsigned short dl, unsigned short ah, unsigned short al, unsigned short dh, struct vb_device_info *pVBInfo); /*void XGI_ClearBuffer(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, struct vb_device_info *pVBInfo);*/ -void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -void XGI_GetLVDSResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); +static void XGI_GetLVDSResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); +static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); unsigned short XGI_GetLVDSOEMTableIndex(struct vb_device_info *pVBInfo); -void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); +static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); +static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); void XGI_GetVGAType(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); void XGI_GetVBType(struct vb_device_info *pVBInfo); void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); +static void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); void InitTo330Pointer(unsigned char, struct vb_device_info *pVBInfo); -void XGI_GetLCDSync(unsigned short *HSyncWidth, unsigned short *VSyncWidth, struct vb_device_info *pVBInfo); +static void XGI_GetLCDSync(unsigned short *HSyncWidth, unsigned short *VSyncWidth, struct vb_device_info *pVBInfo); void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -void XGI_OEM310Setting(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -void XGI_SetDelayComp(struct vb_device_info *pVBInfo); -void XGI_SetLCDCap(struct vb_device_info *pVBInfo); -void XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInfo); -void XGI_SetLCDCap_B(unsigned short tempcx, struct vb_device_info *pVBInfo); -void SetSpectrum(struct vb_device_info *pVBInfo); -void XGI_SetAntiFlicker(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo); -void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char* tempcl, +static void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); +static void XGI_OEM310Setting(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); +static void XGI_SetDelayComp(struct vb_device_info *pVBInfo); +static void XGI_SetLCDCap(struct vb_device_info *pVBInfo); +static void XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInfo); +static void XGI_SetLCDCap_B(unsigned short tempcx, struct vb_device_info *pVBInfo); +static void SetSpectrum(struct vb_device_info *pVBInfo); +static void XGI_SetAntiFlicker(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); +static void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); +static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo); +static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); +static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char* tempcl, unsigned char *tempch, struct vb_device_info *pVBInfo); -unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo); void XGI_SetCRT2ModeRegs(unsigned short ModeNo, struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); -void XGI_CloseCRTC(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); -void XGI_OpenCRTC(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); -void XGI_GetRAMDAC2DATA(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); +static void XGI_CloseCRTC(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); +static void XGI_GetRAMDAC2DATA(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); void XGI_UnLockCRT2(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); void XGI_LockCRT2(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); -void XGINew_EnableCRT2(struct vb_device_info *pVBInfo); +static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo); void XGI_LongWait(struct vb_device_info *pVBInfo); -void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1, +static void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); +static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1, struct vb_device_info *pVBInfo); -unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, +static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0, +static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0, unsigned char *di_1, struct vb_device_info *pVBInfo); -unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo); -unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo); -struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx, struct vb_device_info *pVBInfo); +static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo); +static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo); +static struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx, struct vb_device_info *pVBInfo); void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo); void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo); -unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo); -unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo); +static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo); +static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo); void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl, struct vb_device_info *pVBInfo); void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl, struct vb_device_info *pVBInfo); void XGI_XG21SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBInfo); unsigned char XGI_XG21CheckLVDSMode(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo); - -extern void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo); - -/* unsigned short XGINew_flag_clearbuffer; 0: no clear frame buffer 1:clear frame buffer */ - +static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); +static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); +static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo); static unsigned short XGINew_MDA_DAC[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -566,7 +546,7 @@ unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension, return 1; } -void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension, +static void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { @@ -680,7 +660,7 @@ void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension, /* XGI_ClearBuffer(HwDeviceExtension, ModeNo, pVBInfo); */ } -unsigned char XGI_GetModePtr(unsigned short ModeNo, unsigned short ModeIdIndex, +static unsigned char XGI_GetModePtr(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned char index; @@ -707,7 +687,7 @@ unsigned char XGI_SetBIOSData(unsigned short ModeNo, unsigned short ModeIdIndex) } */ -void XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex, +static void XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned char tempah, SRdata; @@ -741,7 +721,7 @@ void XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex, } } -void XGI_SetMiscRegs(unsigned short StandTableIndex, +static void XGI_SetMiscRegs(unsigned short StandTableIndex, struct vb_device_info *pVBInfo) { unsigned char Miscdata; @@ -758,7 +738,7 @@ void XGI_SetMiscRegs(unsigned short StandTableIndex, XGINew_SetReg3(pVBInfo->P3c2, Miscdata); /* Set Misc(3c2) */ } -void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, +static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, unsigned short StandTableIndex, struct vb_device_info *pVBInfo) { unsigned char CRTCdata; @@ -783,7 +763,7 @@ void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, */ } -void XGI_SetATTRegs(unsigned short ModeNo, unsigned short StandTableIndex, +static void XGI_SetATTRegs(unsigned short ModeNo, unsigned short StandTableIndex, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned char ARdata; @@ -823,7 +803,7 @@ void XGI_SetATTRegs(unsigned short ModeNo, unsigned short StandTableIndex, XGINew_SetReg3(pVBInfo->P3c0, 0x20); } -void XGI_SetGRCRegs(unsigned short StandTableIndex, +static void XGI_SetGRCRegs(unsigned short StandTableIndex, struct vb_device_info *pVBInfo) { unsigned char GRdata; @@ -841,7 +821,7 @@ void XGI_SetGRCRegs(unsigned short StandTableIndex, } } -void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo) +static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo) { unsigned short i; @@ -849,7 +829,7 @@ void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo) XGINew_SetReg1(pVBInfo->P3c4, i, 0x00); /* Clear SR0A-SR0E */ } -unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo) +static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo) { XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, 0x20); @@ -983,7 +963,7 @@ unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, return RefreshRateTableIndex + i; /* return (0x01 | (temp1<<1)); */ } -unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, +static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, unsigned short *i, struct vb_device_info *pVBInfo) @@ -1125,7 +1105,7 @@ unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, return 1; } -void XGI_SetSync(unsigned short RefreshRateTableIndex, +static void XGI_SetSync(unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { unsigned short sync, temp; @@ -1137,7 +1117,7 @@ void XGI_SetSync(unsigned short RefreshRateTableIndex, XGINew_SetReg3(pVBInfo->P3c2, temp); /* Set Misc(3c2) */ } -void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo, struct xgi_hw_device_info *HwDeviceExtension) @@ -1168,7 +1148,7 @@ void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, XGINew_SetReg1(pVBInfo->P3d4, 0x14, 0x4F); } -void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, +static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, struct xgi_hw_device_info *HwDeviceExtension) { unsigned char data, data1, pushax; @@ -1231,7 +1211,7 @@ void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, } } -void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeNo, +static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeNo, struct vb_device_info *pVBInfo) { unsigned char data; @@ -1288,7 +1268,7 @@ void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeNo, /* Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F */ /* Description : Set LCD timing */ /* --------------------------------------------------------------------- */ -void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { @@ -1426,7 +1406,7 @@ void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, } } -void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { @@ -1545,7 +1525,7 @@ void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, /* Output : FCLK duty cycle, FCLK delay compensation */ /* Description : All values set zero */ /* --------------------------------------------------------------------- */ -void XGI_SetXG21LCD(struct vb_device_info *pVBInfo, +static void XGI_SetXG21LCD(struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex, unsigned short ModeNo) { unsigned short Data, Temp, b3CC; @@ -1591,7 +1571,7 @@ void XGI_SetXG21LCD(struct vb_device_info *pVBInfo, } } -void XGI_SetXG27LCD(struct vb_device_info *pVBInfo, +static void XGI_SetXG27LCD(struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex, unsigned short ModeNo) { unsigned short Data, Temp, b3CC; @@ -1645,7 +1625,7 @@ void XGI_SetXG27LCD(struct vb_device_info *pVBInfo, /* Output : CRT1 CRTC */ /* Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing */ /* --------------------------------------------------------------------- */ -void XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVBInfo, +static void XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex) { int i, index = -1; @@ -1685,7 +1665,7 @@ void XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVBInfo, } } -void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, +static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) @@ -1772,7 +1752,7 @@ unsigned short XGI_GetResInfo(unsigned short ModeNo, return resindex; } -void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) @@ -1855,7 +1835,7 @@ void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex, XGINew_SetReg1(pVBInfo->P3c4, 0x10, ah); } -void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) @@ -1912,7 +1892,7 @@ void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, } } -void XGI_SetCRT1FIFO(unsigned short ModeNo, +static void XGI_SetCRT1FIFO(unsigned short ModeNo, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { @@ -1948,7 +1928,7 @@ void XGI_SetCRT1FIFO(unsigned short ModeNo, XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */ } -void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, +static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) @@ -2063,7 +2043,7 @@ void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, } -void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, +static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { @@ -2149,7 +2129,7 @@ void XGI_VesaLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, st } */ -void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned short data, data2, time, i, j, k, m, n, o, si, di, bx, dl, al, @@ -2241,7 +2221,7 @@ void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex, } } -void XGI_WriteDAC(unsigned short dl, unsigned short ah, unsigned short al, +static void XGI_WriteDAC(unsigned short dl, unsigned short ah, unsigned short al, unsigned short dh, struct vb_device_info *pVBInfo) { unsigned short temp, bh, bl; @@ -2268,7 +2248,7 @@ void XGI_WriteDAC(unsigned short dl, unsigned short ah, unsigned short al, XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) bl); } -void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { @@ -2288,7 +2268,7 @@ void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex, XGI_SetCRT2ECLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); } -void XGI_GetLVDSResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_GetLVDSResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned short resindex, xres, yres, modeflag; @@ -2337,7 +2317,7 @@ void XGI_GetLVDSResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, pVBInfo->VDE = yres; } -void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { @@ -2392,7 +2372,7 @@ void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, } } -void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) @@ -2507,7 +2487,7 @@ void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, } } -void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { @@ -2802,7 +2782,7 @@ void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, } } -void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { @@ -2831,7 +2811,7 @@ void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex, } } -void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, +static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { unsigned short tempcl, tempch, temp, tempbl, tempax; @@ -3702,7 +3682,7 @@ void XGI_DisplayOff(struct xgi_hw_device_info *pXGIHWDE, XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x20); } -void XGI_WaitDisply(struct vb_device_info *pVBInfo) +static void XGI_WaitDisply(struct vb_device_info *pVBInfo) { while ((XGINew_GetReg2(pVBInfo->P3da) & 0x01)) break; @@ -3860,13 +3840,13 @@ unsigned char XGI_SetCRT2Group301(unsigned short ModeNo, return 1; } -void XGI_AutoThreshold(struct vb_device_info *pVBInfo) +static void XGI_AutoThreshold(struct vb_device_info *pVBInfo) { if (!(pVBInfo->SetFlag & Win9xDOSMode)) XGINew_SetRegOR(pVBInfo->Part1Port, 0x01, 0x40); } -void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBInfo) +static void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBInfo) { unsigned short temp1, temp2; @@ -3876,7 +3856,7 @@ void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBInfo) XGINew_SetRegANDOR(pVBInfo->P3d4, 0x31, temp2, temp1); } -void XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned short xres, yres, modeflag, resindex; @@ -3951,7 +3931,7 @@ void XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, pVBInfo->VDE = yres; } -unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo) +static unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo) { if ((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) && @@ -3961,7 +3941,7 @@ unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo) return 0; } -void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { @@ -4147,7 +4127,7 @@ void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, } } -void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { @@ -4182,7 +4162,7 @@ void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, /* Output : al -> VCLK Index */ /* Description : */ /* --------------------------------------------------------------------- */ -void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1, +static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1, struct vb_device_info *pVBInfo) { unsigned short index; @@ -4207,7 +4187,7 @@ void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1, return; } -unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, +static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { @@ -4364,7 +4344,7 @@ unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, return tempal; } -void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0, +static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0, unsigned char *di_1, struct vb_device_info *pVBInfo) { if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 2007/05/16 */ @@ -4406,7 +4386,7 @@ static void XGI_SetCRT2Offset(unsigned short ModeNo, XGINew_SetReg1(pVBInfo->Part1Port, 0x03, temp); } -unsigned short XGI_GetOffset(unsigned short ModeNo, unsigned short ModeIdIndex, +static unsigned short XGI_GetOffset(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) @@ -4447,7 +4427,7 @@ static void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo) XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04); /* threshold low default 04h */ } -void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) @@ -4472,7 +4452,7 @@ void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, XGINew_SetReg1(pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */ } -void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) @@ -4625,7 +4605,7 @@ void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax); } -void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) @@ -5004,7 +4984,7 @@ void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, return; } -void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) @@ -5451,7 +5431,7 @@ void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, return; } -void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) @@ -5676,7 +5656,7 @@ void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, /* Output : di -> Tap4 Reg. Setting Pointer */ /* Description : */ /* --------------------------------------------------------------------- */ -struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx, +static struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx, struct vb_device_info *pVBInfo) { unsigned short tempax, tempbx, i; @@ -5722,7 +5702,7 @@ struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx, return &Tap4TimingPtr[i]; } -void XGI_SetTap4Regs(struct vb_device_info *pVBInfo) +static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo) { unsigned short i, j; @@ -5752,7 +5732,7 @@ void XGI_SetTap4Regs(struct vb_device_info *pVBInfo) #endif } -void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned short i; @@ -5811,7 +5791,7 @@ void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, return; } /* {end of XGI_SetGroup3} */ -void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) @@ -6014,7 +5994,7 @@ void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, pVBInfo); } -void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned short Pindex, Pdata; @@ -6031,7 +6011,7 @@ void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex, return; } -void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, +static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) @@ -6502,7 +6482,7 @@ void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, return NULL; } -void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo, +static void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) @@ -6651,7 +6631,7 @@ void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo, /* Output : 1 -> Skip backlight control */ /* Description : */ /* --------------------------------------------------------------------- */ -unsigned char XGI_BacklightByDrv(struct vb_device_info *pVBInfo) +static unsigned char XGI_BacklightByDrv(struct vb_device_info *pVBInfo) { unsigned char tempah; @@ -6681,18 +6661,18 @@ void XGI_FirePWDDisable(struct vb_device_info *pVBInfo) /* Output : */ /* Description : Turn on VDD & Backlight : Fire enable procedure */ /* --------------------------------------------------------------------- */ -void XGI_FirePWDEnable(struct vb_device_info *pVBInfo) +static void XGI_FirePWDEnable(struct vb_device_info *pVBInfo) { XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x26, 0x03, 0xFC); } -void XGI_EnableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension, +static void XGI_EnableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { XGINew_SetRegANDOR(pVBInfo->P3d4, 0x63, 0xBF, 0x40); } -void XGI_DisableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension, +static void XGI_DisableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { @@ -6709,7 +6689,7 @@ void XGI_DisableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension, /* : bl : 3 ; T3 : the duration between CPL off and signal off */ /* : bl : 4 ; T4 : the duration signal off and Vdd off */ /* --------------------------------------------------------------------- */ -void XGI_SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBInfo) +static void XGI_SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBInfo) { unsigned short index; @@ -6738,7 +6718,7 @@ void XGI_SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBInfo) /* = 1011b = 0Bh ; Backlight off, Power on */ /* = 1111b = 0Fh ; Backlight off, Power off */ /* --------------------------------------------------------------------- */ -void XGI_SetPanelPower(unsigned short tempah, unsigned short tempbl, +static void XGI_SetPanelPower(unsigned short tempah, unsigned short tempbl, struct vb_device_info *pVBInfo) { if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) @@ -6767,7 +6747,7 @@ static unsigned char XG21GPIODataTransfer(unsigned char ujDate) /* bl[1] : LVDS backlight */ /* bl[0] : LVDS VDD */ /*----------------------------------------------------------------------------*/ -unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo) +static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo) { unsigned char CR4A, temp; @@ -6788,7 +6768,7 @@ unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo) /* bl[1] : LVDS backlight */ /* bl[0] : LVDS VDD */ /*----------------------------------------------------------------------------*/ -unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo) +static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo) { unsigned char CR4A, CRB4, temp; @@ -6984,7 +6964,7 @@ void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo) } -void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned char temp, Miscdata; @@ -7170,7 +7150,7 @@ void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, } /* no shadow case */ -void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned char temp, Miscdata; @@ -7360,7 +7340,7 @@ void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, /* 1: Disable PSC */ /* Description : */ /* --------------------------------------------------------------------- */ -unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo) +static unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo) { unsigned short tempax; @@ -7373,7 +7353,7 @@ unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo) return 0; } -void XGI_EnablePWD(struct vb_device_info *pVBInfo) +static void XGI_EnablePWD(struct vb_device_info *pVBInfo) { unsigned short index, temp; @@ -7391,7 +7371,7 @@ void XGI_EnablePWD(struct vb_device_info *pVBInfo) XGINew_SetRegOR(pVBInfo->Part4Port, 0x27, 0x80); /* enable PWD */ } -void XGI_DisablePWD(struct vb_device_info *pVBInfo) +static void XGI_DisablePWD(struct vb_device_info *pVBInfo) { XGINew_SetRegAND(pVBInfo->Part4Port, 0x27, 0x7F); /* disable PWD */ } @@ -7402,7 +7382,7 @@ void XGI_DisablePWD(struct vb_device_info *pVBInfo) /* Output : 0 -> Not LCD Mode */ /* Description : */ /* --------------------------------------------------------------------- */ -unsigned char XGI_DisableChISLCD(struct vb_device_info *pVBInfo) +static unsigned char XGI_DisableChISLCD(struct vb_device_info *pVBInfo) { unsigned short tempbx, tempah; @@ -7429,7 +7409,7 @@ unsigned char XGI_DisableChISLCD(struct vb_device_info *pVBInfo) /* Output : 0 -> Not LCD mode */ /* Description : */ /* --------------------------------------------------------------------- */ -unsigned char XGI_EnableChISLCD(struct vb_device_info *pVBInfo) +static unsigned char XGI_EnableChISLCD(struct vb_device_info *pVBInfo) { unsigned short tempbx, tempah; @@ -7450,7 +7430,7 @@ unsigned char XGI_EnableChISLCD(struct vb_device_info *pVBInfo) return 0; } -unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo) +static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo) { unsigned char tempal, tempah, tempbl, i; @@ -7477,7 +7457,7 @@ unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo) return i; } -unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo) +static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo) { unsigned short tempah, tempal, tempbl, i; @@ -7509,7 +7489,7 @@ unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo) return i; } -void XGI_GetLCDSync(unsigned short *HSyncWidth, unsigned short *VSyncWidth, +static void XGI_GetLCDSync(unsigned short *HSyncWidth, unsigned short *VSyncWidth, struct vb_device_info *pVBInfo) { unsigned short Index; @@ -7876,7 +7856,7 @@ void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, /* A : Ext750p */ /* B : St750p */ /* --------------------------------------------------------------------- */ -unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo) +static unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo) { unsigned short tempbx = 0; @@ -7902,7 +7882,7 @@ unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo) /* Output : */ /* Description : Customized Param. for 301 */ /* --------------------------------------------------------------------- */ -void XGI_OEM310Setting(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_OEM310Setting(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { if (pVBInfo->SetFlag & Win9xDOSMode) @@ -7925,7 +7905,7 @@ void XGI_OEM310Setting(unsigned short ModeNo, unsigned short ModeIdIndex, } } -void XGI_SetDelayComp(struct vb_device_info *pVBInfo) +static void XGI_SetDelayComp(struct vb_device_info *pVBInfo) { unsigned short index; @@ -7993,7 +7973,7 @@ void XGI_SetDelayComp(struct vb_device_info *pVBInfo) } } -void XGI_SetLCDCap(struct vb_device_info *pVBInfo) +static void XGI_SetLCDCap(struct vb_device_info *pVBInfo) { unsigned short tempcx; @@ -8030,7 +8010,7 @@ void XGI_SetLCDCap(struct vb_device_info *pVBInfo) } } -void XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInfo) +static void XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInfo) { unsigned short temp; @@ -8063,7 +8043,7 @@ void XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInfo) /* Output : */ /* Description : */ /* --------------------------------------------------------------------- */ -void XGI_SetLCDCap_B(unsigned short tempcx, struct vb_device_info *pVBInfo) +static void XGI_SetLCDCap_B(unsigned short tempcx, struct vb_device_info *pVBInfo) { if (tempcx & EnableLCD24bpp) /* 24bits */ XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1A, 0xE0, @@ -8075,7 +8055,7 @@ void XGI_SetLCDCap_B(unsigned short tempcx, struct vb_device_info *pVBInfo) | 0x18)); /* Enable Dither */ } -void SetSpectrum(struct vb_device_info *pVBInfo) +static void SetSpectrum(struct vb_device_info *pVBInfo) { unsigned short index; @@ -8104,7 +8084,7 @@ void SetSpectrum(struct vb_device_info *pVBInfo) /* Output : */ /* Description : Set TV Customized Param. */ /* --------------------------------------------------------------------- */ -void XGI_SetAntiFlicker(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetAntiFlicker(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned short tempbx, index; @@ -8129,7 +8109,7 @@ void XGI_SetAntiFlicker(unsigned short ModeNo, unsigned short ModeIdIndex, XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0x8F, tempah); } -void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned short tempbx, index; @@ -8151,7 +8131,7 @@ void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex, XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x3A, 0x1F, tempah); } -void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo) +static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo) { unsigned short tempbx; @@ -8172,7 +8152,7 @@ void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo) & 0xFF000000) >> 24)); } -void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned short tempbx, index; @@ -8269,7 +8249,7 @@ void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex, /* 1 : 301B/302B/301LV/302LV */ /* Description : */ /* --------------------------------------------------------------------- */ -void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl, +static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl, unsigned char *tempch, struct vb_device_info *pVBInfo) { *tempbx = 0; @@ -8516,7 +8496,7 @@ void XGI_SetCRT2ModeRegs(unsigned short ModeNo, } } -void XGI_CloseCRTC(struct xgi_hw_device_info *HwDeviceExtension, +static void XGI_CloseCRTC(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { unsigned short tempbx; @@ -8535,7 +8515,7 @@ void XGI_OpenCRTC(struct xgi_hw_device_info *HwDeviceExtension, tempbx = 0; } -void XGI_GetRAMDAC2DATA(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_GetRAMDAC2DATA(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { @@ -8592,7 +8572,7 @@ void XGI_GetRAMDAC2DATA(unsigned short ModeNo, unsigned short ModeIdIndex, pVBInfo->VT = tempbx; } -unsigned short XGI_GetColorDepth(unsigned short ModeNo, +static unsigned short XGI_GetColorDepth(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 }; @@ -8628,7 +8608,7 @@ void XGI_LockCRT2(struct xgi_hw_device_info *HwDeviceExtension, } -void XGINew_EnableCRT2(struct vb_device_info *pVBInfo) +static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo) { XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1E, 0xFF, 0x20); } @@ -8667,7 +8647,7 @@ void XGI_LongWait(struct vb_device_info *pVBInfo) } } -void XGI_VBLongWait(struct vb_device_info *pVBInfo) +static void XGI_VBLongWait(struct vb_device_info *pVBInfo) { unsigned short tempal, temp, i, j; return; @@ -8699,7 +8679,7 @@ void XGI_VBLongWait(struct vb_device_info *pVBInfo) return; } -unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo) +static unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo) { unsigned long tempax, tempbx; @@ -8711,7 +8691,7 @@ unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo) return (unsigned short) tempax; } -unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, +static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, diff --git a/drivers/staging/xgifb/vb_setmode.h b/drivers/staging/xgifb/vb_setmode.h index 0dcc29796176..7a2e564b0744 100644 --- a/drivers/staging/xgifb/vb_setmode.h +++ b/drivers/staging/xgifb/vb_setmode.h @@ -17,9 +17,6 @@ extern void XGI_SenseCRT1(struct vb_device_info *); extern void XGI_GetVGAType(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *); extern void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *); extern void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *); -extern void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *); -extern void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *); -extern void XGI_WaitDisply(struct vb_device_info *); extern unsigned short XGI_GetResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); extern unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo) ; @@ -36,7 +33,6 @@ extern void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short temp extern void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl, struct vb_device_info *pVBInfo); extern void XGI_XG21SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBInfo); extern unsigned char XGI_XG21CheckLVDSMode(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -extern void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); extern unsigned short XGI_GetLVDSOEMTableIndex(struct vb_device_info *pVBInfo); #endif -- cgit v1.2.3 From 5e60b97cb1206c95b0acab61e8f107e943b31b62 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 8 Mar 2011 22:16:14 +0200 Subject: staging: xgifb: vb_setmode: include the .h file Include the file's .h file and delete the duplicate declarations from the .c file. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 43 +------------------------------------- 1 file changed, 1 insertion(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 0f37c80431b3..542352449e28 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -11,7 +11,7 @@ #include "vb_struct.h" #include "vb_util.h" #include "vb_table.h" - +#include "vb_setmode.h" #define IndexMask 0xff @@ -21,23 +21,10 @@ -unsigned char XGI_SetCRT2Group301(unsigned short ModeNo, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo); - static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, unsigned short *i, struct vb_device_info *pVBInfo); -unsigned char XGI_SearchModeID(unsigned short ModeNo, - unsigned short *ModeIdIndex, - struct vb_device_info *pVBInfo); -unsigned char XGI_GetLCDInfo(unsigned short ModeNo, - unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo); -unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension, - unsigned short ModeNo); -unsigned char XGI_BridgeIsOn(struct vb_device_info *pVBInfo); static unsigned char XGI_GetModePtr(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); @@ -46,13 +33,6 @@ static unsigned short XGI_GetOffset(unsigned short ModeNo, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, - unsigned short ModeNo, - unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo); -unsigned short XGI_GetResInfo(unsigned short ModeNo, - unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo); static unsigned short XGI_GetColorDepth(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); @@ -79,15 +59,12 @@ static void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo, unsigned sho static void XGI_AutoThreshold(struct vb_device_info *pVBInfo); static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo); -void XGI_DisplayOn(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); -void XGI_DisplayOff(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); static void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); static void XGI_SetXG21LCD(struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex, unsigned short ModeNo); static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); static void XGI_SetXG27LCD(struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex, unsigned short ModeNo); static void XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex); -void XGI_SenseCRT1(struct vb_device_info *pVBInfo); static void XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); static void XGI_SetMiscRegs(unsigned short StandTableIndex, struct vb_device_info *pVBInfo); static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, unsigned short StandTableIndex, struct vb_device_info *pVBInfo); @@ -112,22 +89,14 @@ static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex, static void XGI_GetLVDSResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -unsigned short XGI_GetLVDSOEMTableIndex(struct vb_device_info *pVBInfo); static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -void XGI_GetVGAType(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -void XGI_GetVBType(struct vb_device_info *pVBInfo); -void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); static void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -void InitTo330Pointer(unsigned char, struct vb_device_info *pVBInfo); static void XGI_GetLCDSync(unsigned short *HSyncWidth, unsigned short *VSyncWidth, struct vb_device_info *pVBInfo); -void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); static void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); static void XGI_OEM310Setting(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); static void XGI_SetDelayComp(struct vb_device_info *pVBInfo); @@ -141,13 +110,9 @@ static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo); static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char* tempcl, unsigned char *tempch, struct vb_device_info *pVBInfo); -void XGI_SetCRT2ModeRegs(unsigned short ModeNo, struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); static void XGI_CloseCRTC(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); static void XGI_GetRAMDAC2DATA(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -void XGI_UnLockCRT2(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); -void XGI_LockCRT2(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo); -void XGI_LongWait(struct vb_device_info *pVBInfo); static void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1, struct vb_device_info *pVBInfo); @@ -160,14 +125,8 @@ static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0, static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo); static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo); static struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx, struct vb_device_info *pVBInfo); -void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo); -void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo); static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo); static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo); -void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl, struct vb_device_info *pVBInfo); -void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl, struct vb_device_info *pVBInfo); -void XGI_XG21SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBInfo); -unsigned char XGI_XG21CheckLVDSMode(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo); -- cgit v1.2.3 From eb51a917028351db1174d5f9b43a53e62983fc19 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 8 Mar 2011 22:16:15 +0200 Subject: staging: xgifb: vb_ext: delete redundant declarations Delete redundant declarations. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_ext.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_ext.c b/drivers/staging/xgifb/vb_ext.c index 80c78185a2e2..e1f9188261c4 100644 --- a/drivers/staging/xgifb/vb_ext.c +++ b/drivers/staging/xgifb/vb_ext.c @@ -9,25 +9,12 @@ #include "vb_util.h" #include "vb_setmode.h" #include "vb_ext.h" -extern unsigned char XGI330_SoftSetting; -extern unsigned char XGI330_OutputSelect; -extern unsigned short XGI330_RGBSenseData2; -extern unsigned short XGI330_YCSenseData2; -extern unsigned short XGI330_VideoSenseData2; -void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo); unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo); -unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *, - struct vb_device_info *pVBInfo); unsigned char XGINew_GetLCDDDCInfo( struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -void XGISetDPMS(struct xgi_hw_device_info *pXGIHWDE, - unsigned long VESA_POWER_STATE); unsigned char XGINew_BridgeIsEnable(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); -unsigned char XGINew_Sense(unsigned short tempbx, unsigned short tempcx, - struct vb_device_info *pVBInfo); unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); @@ -35,10 +22,6 @@ unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtension, *********************** Dynamic Sense ************************ *************************************************************/ -void XGI_WaitDisplay(void); -unsigned char XGI_Is301C(struct vb_device_info *); -unsigned char XGI_Is301LV(struct vb_device_info *); - static unsigned char XGINew_Is301B(struct vb_device_info *pVBInfo) { unsigned short flag; -- cgit v1.2.3 From f4dccca54ac8b848fe45a807aac2518bed080458 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 8 Mar 2011 22:16:16 +0200 Subject: staging: xgifb: vb_ext: delete unused functions Delete unused functions. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_ext.c | 437 ----------------------------------------- drivers/staging/xgifb/vb_ext.h | 3 - 2 files changed, 440 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_ext.c b/drivers/staging/xgifb/vb_ext.c index e1f9188261c4..cc78815c8be6 100644 --- a/drivers/staging/xgifb/vb_ext.c +++ b/drivers/staging/xgifb/vb_ext.c @@ -34,28 +34,6 @@ static unsigned char XGINew_Is301B(struct vb_device_info *pVBInfo) return 1; } -unsigned char XGI_Is301C(struct vb_device_info *pVBInfo) -{ - if ((XGINew_GetReg1(pVBInfo->Part4Port, 0x01) & 0xF0) == 0xC0) - return 1; - - if (XGINew_GetReg1(pVBInfo->Part4Port, 0x01) >= 0xD0) { - if (XGINew_GetReg1(pVBInfo->Part4Port, 0x39) == 0xE0) - return 1; - } - - return 0; -} - -unsigned char XGI_Is301LV(struct vb_device_info *pVBInfo) -{ - if (XGINew_GetReg1(pVBInfo->Part4Port, 0x01) >= 0xD0) { - if (XGINew_GetReg1(pVBInfo->Part4Port, 0x39) == 0xFF) - return 1; - } - return 0; -} - unsigned char XGINew_Sense(unsigned short tempbx, unsigned short tempcx, struct vb_device_info *pVBInfo) { unsigned short temp, i, tempch; @@ -80,190 +58,6 @@ unsigned char XGINew_Sense(unsigned short tempbx, unsigned short tempcx, struct return 0; } -void XGISetDPMS(struct xgi_hw_device_info *pXGIHWDE, unsigned long VESA_POWER_STATE) -{ - unsigned short ModeNo, ModeIdIndex; - unsigned char temp; - struct vb_device_info VBINF; - struct vb_device_info *pVBInfo = &VBINF; - pVBInfo->BaseAddr = (unsigned long) pXGIHWDE->pjIOAddress; - pVBInfo->ROMAddr = pXGIHWDE->pjVirtualRomBase; - - pVBInfo->IF_DEF_LVDS = 0; - pVBInfo->IF_DEF_CH7005 = 0; - pVBInfo->IF_DEF_HiVision = 1; - pVBInfo->IF_DEF_LCDA = 1; - pVBInfo->IF_DEF_CH7017 = 0; - pVBInfo->IF_DEF_YPbPr = 1; - pVBInfo->IF_DEF_CRT2Monitor = 0; - pVBInfo->IF_DEF_VideoCapture = 0; - pVBInfo->IF_DEF_ScaleLCD = 0; - pVBInfo->IF_DEF_OEMUtil = 0; - pVBInfo->IF_DEF_PWD = 0; - - InitTo330Pointer(pXGIHWDE->jChipType, pVBInfo); - ReadVBIOSTablData(pXGIHWDE->jChipType, pVBInfo); - - pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14; - pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24; - pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10; - pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e; - pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12; - pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a; - pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16; - pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17; - pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18; - pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19; - pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A; - pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00; - pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04; - pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10; - pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12; - pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14; - pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2; - - if (pXGIHWDE->jChipType == XG27) { - if ((XGINew_GetReg1(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) { - if (XGINew_GetReg1(pVBInfo->P3d4, 0x30) & 0x20) - pVBInfo->IF_DEF_LVDS = 1; - } - } - - if (pVBInfo->IF_DEF_CH7007 == 0) - XGINew_SetModeScratch(pXGIHWDE, pVBInfo); - - XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86); /* 1.Openkey */ - XGI_UnLockCRT2(pXGIHWDE, pVBInfo); - ModeNo = XGINew_GetReg1(pVBInfo->P3d4, 0x34); - XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo); - XGI_GetVGAType(pXGIHWDE, pVBInfo); - - if ((pXGIHWDE->ujVBChipID == VB_CHIP_301) || (pXGIHWDE->ujVBChipID == VB_CHIP_302) || (pVBInfo->IF_DEF_CH7007 == 1)) { - XGI_GetVBType(pVBInfo); - XGI_GetVBInfo(ModeNo, ModeIdIndex, pXGIHWDE, pVBInfo); - XGI_GetTVInfo(ModeNo, ModeIdIndex, pVBInfo); - XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo); - } - - if (VESA_POWER_STATE == 0x00000400) - XGINew_SetReg1(pVBInfo->Part4Port, 0x31, (unsigned char) (XGINew_GetReg1(pVBInfo->Part4Port, 0x31) & 0xFE)); - else - XGINew_SetReg1(pVBInfo->Part4Port, 0x31, (unsigned char) (XGINew_GetReg1(pVBInfo->Part4Port, 0x31) | 0x01)); - - temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x1f); - temp &= 0x3f; - switch (VESA_POWER_STATE) { - case 0x00000000: /* on */ - if ((pXGIHWDE->ujVBChipID == VB_CHIP_301) || (pXGIHWDE->ujVBChipID == VB_CHIP_302)) { - XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char) (temp | 0x00)); - XGI_EnableBridge(pXGIHWDE, pVBInfo); - } else { - if (pXGIHWDE->jChipType == XG21) { - if (pVBInfo->IF_DEF_LVDS == 1) { - XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */ - XGI_XG21SetPanelDelay(2, pVBInfo); - } - } - if (pXGIHWDE->jChipType == XG27) { - if (pVBInfo->IF_DEF_LVDS == 1) { - XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */ - XGI_XG21SetPanelDelay(2, pVBInfo); - } - } - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1F, ~0xC0, 0x00); - XGINew_SetRegAND(pVBInfo->P3c4, 0x01, ~0x20); /* CRT on */ - - if (pXGIHWDE->jChipType == XG21) { - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38); - if (temp & 0xE0) { - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0x80, 0x80); /* DVO ON */ - XGI_SetXG21FPBits(pVBInfo); - XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); /* Enable write GPIOF */ - /* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x48, ~0x20, 0x20); *//* LCD Display ON */ - } - XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */ - XGI_DisplayOn(pXGIHWDE, pVBInfo); - } - if (pXGIHWDE->jChipType == XG27) { - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38); - if (temp & 0xE0) { - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0x80, 0x80); /* DVO ON */ - XGI_SetXG27FPBits(pVBInfo); - XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); /* Enable write GPIOF */ - /* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x48, ~0x20, 0x20); *//* LCD Display ON */ - } - XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */ - XGI_DisplayOn(pXGIHWDE, pVBInfo); - } - } - break; - - case 0x00000100: /* standby */ - if (pXGIHWDE->jChipType >= XG21) - XGI_DisplayOff(pXGIHWDE, pVBInfo); - XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char) (temp | 0x40)); - break; - - case 0x00000200: /* suspend */ - if (pXGIHWDE->jChipType == XG21) { - XGI_DisplayOff(pXGIHWDE, pVBInfo); - XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo); /* LVDS signal off */ - } - if (pXGIHWDE->jChipType == XG27) { - XGI_DisplayOff(pXGIHWDE, pVBInfo); - XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo); /* LVDS signal off */ - } - XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char) (temp | 0x80)); - break; - - case 0x00000400: /* off */ - if ((pXGIHWDE->ujVBChipID == VB_CHIP_301) || (pXGIHWDE->ujVBChipID == VB_CHIP_302)) { - XGINew_SetReg1(pVBInfo->P3c4, 0x1f, (unsigned char) (temp | 0xc0)); - XGI_DisableBridge(pXGIHWDE, pVBInfo); - } else { - if (pXGIHWDE->jChipType == XG21) { - XGI_DisplayOff(pXGIHWDE, pVBInfo); - - XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo); /* LVDS signal off */ - - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38); - if (temp & 0xE0) { - XGINew_SetRegAND(pVBInfo->P3c4, 0x09, ~0x80); /* DVO Off */ - XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); /* Enable write GPIOF */ - /* XGINew_SetRegAND(pVBInfo->P3d4, 0x48, ~0x20); *//* LCD Display OFF */ - } - } - if (pXGIHWDE->jChipType == XG27) { - XGI_DisplayOff(pXGIHWDE, pVBInfo); - - XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo); /* LVDS signal off */ - - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38); - if (temp & 0xE0) - XGINew_SetRegAND(pVBInfo->P3c4, 0x09, ~0x80); /* DVO Off */ - } - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1F, ~0xC0, 0xC0); - XGINew_SetRegOR(pVBInfo->P3c4, 0x01, 0x20); /* CRT Off */ - - if ((pXGIHWDE->jChipType == XG21) && (pVBInfo->IF_DEF_LVDS == 1)) { - XGI_XG21SetPanelDelay(4, pVBInfo); - XGI_XG21BLSignalVDD(0x01, 0x00, pVBInfo); /* LVDS VDD off */ - XGI_XG21SetPanelDelay(5, pVBInfo); - } - if ((pXGIHWDE->jChipType == XG27) && (pVBInfo->IF_DEF_LVDS == 1)) { - XGI_XG21SetPanelDelay(4, pVBInfo); - XGI_XG27BLSignalVDD(0x01, 0x00, pVBInfo); /* LVDS VDD off */ - XGI_XG21SetPanelDelay(5, pVBInfo); - } - } - break; - - default: - break; - } - XGI_LockCRT2(pXGIHWDE, pVBInfo); -} - void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { unsigned short tempax = 0, tempbx, tempcx, temp, P2reg0 = 0, SenseModeNo = 0, @@ -607,234 +401,3 @@ unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtension, str return 0; } } - -/* ---------------------------------------------------------------------------- - * Description: Get Panel support - * O/P : - * BL: Panel ID=81h for no scaler LVDS - * BH: Panel enhanced Mode Count - * CX: Panel H. resolution - * DX: PAnel V. resolution - * ---------------------------------------------------------------------------- - */ -static void XGI_XG21Fun14Sub70(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments) -{ - unsigned short ModeIdIndex; - unsigned short ModeNo; - - unsigned short EModeCount; - unsigned short lvdstableindex; - - lvdstableindex = XGI_GetLVDSOEMTableIndex(pVBInfo); - pBiosArguments->h.bl = 0x81; - pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE; - pBiosArguments->x.dx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE; - EModeCount = 0; - - pBiosArguments->x.ax = 0x0014; - for (ModeIdIndex = 0;; ModeIdIndex++) { - ModeNo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeID; - if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeID == 0xFF) { - pBiosArguments->h.bh = (unsigned char) EModeCount; - return; - } - if (!XGI_XG21CheckLVDSMode(ModeNo, ModeIdIndex, pVBInfo)) - continue; - - EModeCount++; - } -} - -/* ---------------------------------------------------------------------------- - * - * Description: Get Panel mode ID for enhanced mode - * I/P : BH: EModeIndex ( which < Panel enhanced Mode Count ) - * O/P : - * BL: Mode ID - * CX: H. resolution of the assigned by the index - * DX: V. resolution of the assigned by the index - * - * ---------------------------------------------------------------------------- - */ - -static void XGI_XG21Fun14Sub71(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments) -{ - - unsigned short EModeCount; - unsigned short ModeIdIndex, resindex; - unsigned short ModeNo; - unsigned short EModeIndex = pBiosArguments->h.bh; - - EModeCount = 0; - for (ModeIdIndex = 0;; ModeIdIndex++) { - ModeNo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeID; - if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeID == 0xFF) { - pBiosArguments->x.ax = 0x0114; - return; - } - if (!XGI_XG21CheckLVDSMode(ModeNo, ModeIdIndex, pVBInfo)) - continue; - - if (EModeCount == EModeIndex) { - resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); - pBiosArguments->h.bl = (unsigned char) ModeNo; - pBiosArguments->x.cx = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ - pBiosArguments->x.dx = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ - pBiosArguments->x.ax = 0x0014; - } - EModeCount++; - - } - -} - -/* ---------------------------------------------------------------------------- - * - * Description: Validate Panel modes ID support - * I/P : - * BL: ModeID - * O/P : - * CX: H. resolution of the assigned by the index - * DX: V. resolution of the assigned by the index - * - * ---------------------------------------------------------------------------- - */ -static void XGI_XG21Fun14Sub72(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments) -{ - unsigned short ModeIdIndex, resindex; - unsigned short ModeNo; - - ModeNo = pBiosArguments->h.bl; - XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo); - if (!XGI_XG21CheckLVDSMode(ModeNo, ModeIdIndex, pVBInfo)) { - pBiosArguments->x.cx = 0; - pBiosArguments->x.dx = 0; - pBiosArguments->x.ax = 0x0114; - return; - } - resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); - if (ModeNo <= 0x13) { - pBiosArguments->x.cx = pVBInfo->StResInfo[resindex].HTotal; - pBiosArguments->x.dx = pVBInfo->StResInfo[resindex].VTotal; - } else { - pBiosArguments->x.cx = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ - pBiosArguments->x.dx = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ - } - - pBiosArguments->x.ax = 0x0014; - -} - -/* ---------------------------------------------------------------------------- - * - * Description: Get Customized Panel misc. information support - * I/P : Select - * to get panel horizontal timing - * to get panel vertical timing - * to get channel clock parameter - * to get panel misc information - * - * O/P : - * BL: for input Select = 0 ; - * BX: *Value1 = Horizontal total - * CX: *Value2 = Horizontal front porch - * DX: *Value2 = Horizontal sync width - * BL: for input Select = 1 ; - * BX: *Value1 = Vertical total - * CX: *Value2 = Vertical front porch - * DX: *Value2 = Vertical sync width - * BL: for input Select = 2 ; - * BX: Value1 = The first CLK parameter - * CX: Value2 = The second CLK parameter - * BL: for input Select = 4 ; - * BX[15]: *Value1 D[15] VESA V. Polarity - * BX[14]: *Value1 D[14] VESA H. Polarity - * BX[7]: *Value1 D[7] Panel V. Polarity - * BX[6]: *Value1 D[6] Panel H. Polarity - * ---------------------------------------------------------------------------- - */ -static void XGI_XG21Fun14Sub73(struct vb_device_info *pVBInfo, PX86_REGS pBiosArguments) -{ - unsigned char Select; - - unsigned short lvdstableindex; - - lvdstableindex = XGI_GetLVDSOEMTableIndex(pVBInfo); - Select = pBiosArguments->h.bl; - - switch (Select) { - case 0: - pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHT; - pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHFP; - pBiosArguments->x.dx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHSYNC; - break; - case 1: - pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVT; - pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVFP; - pBiosArguments->x.dx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVSYNC; - break; - case 2: - pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1; - pBiosArguments->x.cx = pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2; - break; - case 4: - pBiosArguments->x.bx = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability; - break; - } - - pBiosArguments->x.ax = 0x0014; -} - -void XGI_XG21Fun14(struct xgi_hw_device_info *pXGIHWDE, PX86_REGS pBiosArguments) -{ - struct vb_device_info VBINF; - struct vb_device_info *pVBInfo = &VBINF; - - pVBInfo->IF_DEF_LVDS = 0; - pVBInfo->IF_DEF_CH7005 = 0; - pVBInfo->IF_DEF_HiVision = 1; - pVBInfo->IF_DEF_LCDA = 1; - pVBInfo->IF_DEF_CH7017 = 0; - pVBInfo->IF_DEF_YPbPr = 1; - pVBInfo->IF_DEF_CRT2Monitor = 0; - pVBInfo->IF_DEF_VideoCapture = 0; - pVBInfo->IF_DEF_ScaleLCD = 0; - pVBInfo->IF_DEF_OEMUtil = 0; - pVBInfo->IF_DEF_PWD = 0; - - InitTo330Pointer(pXGIHWDE->jChipType, pVBInfo); - ReadVBIOSTablData(pXGIHWDE->jChipType, pVBInfo); - - pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14; - pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24; - pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10; - pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e; - pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12; - pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a; - pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16; - pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17; - pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18; - pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19; - pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A; - pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00; - pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04; - pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10; - pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12; - pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14; - pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2; - - switch (pBiosArguments->x.ax) { - case 0x1470: - XGI_XG21Fun14Sub70(pVBInfo, pBiosArguments); - break; - case 0x1471: - XGI_XG21Fun14Sub71(pVBInfo, pBiosArguments); - break; - case 0x1472: - XGI_XG21Fun14Sub72(pVBInfo, pBiosArguments); - break; - case 0x1473: - XGI_XG21Fun14Sub73(pVBInfo, pBiosArguments); - break; - } -} diff --git a/drivers/staging/xgifb/vb_ext.h b/drivers/staging/xgifb/vb_ext.h index 5cc4d12c2254..682452549746 100644 --- a/drivers/staging/xgifb/vb_ext.h +++ b/drivers/staging/xgifb/vb_ext.h @@ -21,9 +21,6 @@ typedef union _X86_REGS { struct BYTEREGS h; } X86_REGS, *PX86_REGS; -extern void XGI_XG21Fun14(struct xgi_hw_device_info *pXGIHWDE, PX86_REGS pBiosArguments); -extern void XGISetDPMS(struct xgi_hw_device_info *pXGIHWDE, - unsigned long VESA_POWER_STATE); extern void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); extern void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ; extern void ReadVBIOSTablData(unsigned char ChipType, -- cgit v1.2.3 From 3d5375f470ae9a156f2a40a74f81a28122937da8 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 8 Mar 2011 22:16:17 +0200 Subject: staging: xgifb: vb_ext: make internal functions static Make internal functions static. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_ext.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_ext.c b/drivers/staging/xgifb/vb_ext.c index cc78815c8be6..33a063564efb 100644 --- a/drivers/staging/xgifb/vb_ext.c +++ b/drivers/staging/xgifb/vb_ext.c @@ -9,13 +9,13 @@ #include "vb_util.h" #include "vb_setmode.h" #include "vb_ext.h" -unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo); -unsigned char XGINew_GetLCDDDCInfo( +static unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo); +static unsigned char XGINew_GetLCDDDCInfo( struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -unsigned char XGINew_BridgeIsEnable(struct xgi_hw_device_info *, +static unsigned char XGINew_BridgeIsEnable(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); -unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtension, +static unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); /************************************************************** @@ -34,7 +34,7 @@ static unsigned char XGINew_Is301B(struct vb_device_info *pVBInfo) return 1; } -unsigned char XGINew_Sense(unsigned short tempbx, unsigned short tempcx, struct vb_device_info *pVBInfo) +static unsigned char XGINew_Sense(unsigned short tempbx, unsigned short tempcx, struct vb_device_info *pVBInfo) { unsigned short temp, i, tempch; @@ -214,7 +214,7 @@ unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *HwDeviceExtension, str return temp; } -unsigned char XGINew_GetLCDDDCInfo(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) +static unsigned char XGINew_GetLCDDDCInfo(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { unsigned short temp; @@ -256,7 +256,7 @@ unsigned char XGINew_GetLCDDDCInfo(struct xgi_hw_device_info *HwDeviceExtension, } } -unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo) +static unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo) { unsigned short PanelTypeTable[16] = { SyncNN | PanelRGB18Bit | Panel800x600 | _PanelType00, SyncNN | PanelRGB18Bit @@ -318,7 +318,7 @@ unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo) } } -unsigned char XGINew_BridgeIsEnable(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) +static unsigned char XGINew_BridgeIsEnable(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { unsigned short flag; @@ -334,7 +334,7 @@ unsigned char XGINew_BridgeIsEnable(struct xgi_hw_device_info *HwDeviceExtension return 0; } -unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) +static unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { unsigned short tempbx, tempcx, temp, i, tempch; -- cgit v1.2.3 From 81018f0038269d6957b6cfd0f5d454b48f5369f2 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 8 Mar 2011 22:16:18 +0200 Subject: staging: xgifb: vb_init: delete redundant declarations Delete redundant declarations. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index a16827e3e869..24dc00c2c3e0 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -17,17 +17,6 @@ static unsigned char XGINew_ChannelAB, XGINew_DataBusWidth; -unsigned short XGINew_DRAMType[17][5] = { - {0x0C, 0x0A, 0x02, 0x40, 0x39}, {0x0D, 0x0A, 0x01, 0x40, 0x48}, - {0x0C, 0x09, 0x02, 0x20, 0x35}, {0x0D, 0x09, 0x01, 0x20, 0x44}, - {0x0C, 0x08, 0x02, 0x10, 0x31}, {0x0D, 0x08, 0x01, 0x10, 0x40}, - {0x0C, 0x0A, 0x01, 0x20, 0x34}, {0x0C, 0x09, 0x01, 0x08, 0x32}, - {0x0B, 0x08, 0x02, 0x08, 0x21}, {0x0C, 0x08, 0x01, 0x08, 0x30}, - {0x0A, 0x08, 0x02, 0x04, 0x11}, {0x0B, 0x0A, 0x01, 0x10, 0x28}, - {0x09, 0x08, 0x02, 0x02, 0x01}, {0x0B, 0x09, 0x01, 0x08, 0x24}, - {0x0B, 0x08, 0x01, 0x04, 0x20}, {0x0A, 0x08, 0x01, 0x02, 0x10}, - {0x09, 0x08, 0x01, 0x01, 0x00} }; - static unsigned short XGINew_SDRDRAM_TYPE[13][5] = { { 2, 12, 9, 64, 0x35}, { 1, 13, 9, 64, 0x44}, @@ -73,12 +62,10 @@ void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *, struct vb_device_in void XGINew_SetDRAMSize_310(struct xgi_hw_device_info *, struct vb_device_info *); void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *); void XGINew_SetDRAMModeRegister(struct vb_device_info *); -void XGINew_SetDRAMModeRegister340(struct xgi_hw_device_info *HwDeviceExtension); void XGINew_SetDRAMDefaultRegister340(struct xgi_hw_device_info *HwDeviceExtension, unsigned long, struct vb_device_info *); unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension); int XGINew_DDRSizing340(struct xgi_hw_device_info *, struct vb_device_info *); void XGINew_DisableRefresh(struct xgi_hw_device_info *, struct vb_device_info *) ; @@ -87,19 +74,11 @@ int XGINew_SDRSizing(struct vb_device_info *); int XGINew_DDRSizing(struct vb_device_info *); void XGINew_EnableRefresh(struct xgi_hw_device_info *, struct vb_device_info *); static int XGINew_RAMType; /*int ModeIDOffset,StandTable,CRT1Table,ScreenOffset,REFIndex;*/ -#if 0 -static unsigned long UNIROM; -#endif -unsigned char ChkLFB(struct vb_device_info *); -void XGINew_Delay15us(unsigned long); void SetPowerConsume(struct xgi_hw_device_info *HwDeviceExtension, unsigned long XGI_P3d4Port); void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo); void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo); -void XGINew_SetDRAMModeRegister_XG20(struct xgi_hw_device_info *HwDeviceExtension); -void XGINew_SetDRAMModeRegister_XG27(struct xgi_hw_device_info *HwDeviceExtension); void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ; -void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ; void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ; unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo); void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ; -- cgit v1.2.3 From 2b9edd38230ba99f7faeebf69400cfa612642695 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 8 Mar 2011 22:16:19 +0200 Subject: staging: xgifb: vb_init: delete unused functions Delete unused functions. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 1120 ++------------------------------------- 1 file changed, 53 insertions(+), 1067 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 24dc00c2c3e0..2cf50ddc5b5b 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -17,27 +17,6 @@ static unsigned char XGINew_ChannelAB, XGINew_DataBusWidth; -static unsigned short XGINew_SDRDRAM_TYPE[13][5] = { - { 2, 12, 9, 64, 0x35}, - { 1, 13, 9, 64, 0x44}, - { 2, 12, 8, 32, 0x31}, - { 2, 11, 9, 32, 0x25}, - { 1, 12, 9, 32, 0x34}, - { 1, 13, 8, 32, 0x40}, - { 2, 11, 8, 16, 0x21}, - { 1, 12, 8, 16, 0x30}, - { 1, 11, 9, 16, 0x24}, - { 1, 11, 8, 8, 0x20}, - { 2, 9, 8, 4, 0x01}, - { 1, 10, 8, 4, 0x10}, - { 1, 9, 8, 2, 0x00} }; - -static unsigned short XGINew_DDRDRAM_TYPE[4][5] = { - { 2, 12, 9, 64, 0x35}, - { 2, 12, 8, 32, 0x31}, - { 2, 11, 8, 16, 0x21}, - { 2, 9, 8, 4, 0x01} }; - static unsigned short XGINew_DDRDRAM_TYPE340[4][5] = { { 2, 13, 9, 64, 0x45}, { 2, 12, 9, 32, 0x35}, @@ -59,23 +38,14 @@ static unsigned short XGINew_DDRDRAM_TYPE20[12][5] = { { 2, 12, 8, 4, 0x31} }; void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *, struct vb_device_info *); -void XGINew_SetDRAMSize_310(struct xgi_hw_device_info *, struct vb_device_info *); void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *); -void XGINew_SetDRAMModeRegister(struct vb_device_info *); void XGINew_SetDRAMDefaultRegister340(struct xgi_hw_device_info *HwDeviceExtension, unsigned long, struct vb_device_info *); unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); int XGINew_DDRSizing340(struct xgi_hw_device_info *, struct vb_device_info *); -void XGINew_DisableRefresh(struct xgi_hw_device_info *, struct vb_device_info *) ; -void XGINew_CheckBusWidth_310(struct vb_device_info *) ; -int XGINew_SDRSizing(struct vb_device_info *); -int XGINew_DDRSizing(struct vb_device_info *); -void XGINew_EnableRefresh(struct xgi_hw_device_info *, struct vb_device_info *); static int XGINew_RAMType; /*int ModeIDOffset,StandTable,CRT1Table,ScreenOffset,REFIndex;*/ -void SetPowerConsume(struct xgi_hw_device_info *HwDeviceExtension, - unsigned long XGI_P3d4Port); void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo); void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo); void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ; @@ -502,40 +472,6 @@ unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtensio } } -static unsigned char XGINew_Get310DRAMType(struct vb_device_info *pVBInfo) -{ - unsigned char data; - - /* index = XGINew_GetReg1(pVBInfo->P3c4, 0x1A); */ - /* index &= 07; */ - - if (*pVBInfo->pSoftSetting & SoftDRAMType) - data = *pVBInfo->pSoftSetting & 0x03; - else - data = XGINew_GetReg1(pVBInfo->P3c4, 0x3a) & 0x03; - - return data; -} - -/* -void XGINew_Delay15us(unsigned long ulMicrsoSec) -{ -} -*/ - -static void XGINew_SDR_MRS(struct vb_device_info *pVBInfo) -{ - unsigned short data; - - data = XGINew_GetReg1(pVBInfo->P3c4, 0x16); - data &= 0x3F; /* SR16 D7=0,D6=0 */ - XGINew_SetReg1(pVBInfo->P3c4, 0x16, data); /* enable mode register set(MRS) low */ - /* XGINew_Delay15us(0x100); */ - data |= 0x80; /* SR16 D7=1,D6=0 */ - XGINew_SetReg1(pVBInfo->P3c4, 0x16, data); /* enable mode register set(MRS) high */ - /* XGINew_Delay15us(0x100); */ -} - static void XGINew_DDR1x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBInfo) { XGINew_SetReg1(P3c4, 0x18, 0x01); @@ -566,29 +502,6 @@ static void XGINew_DDR1x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBI XGINew_SetReg1(P3c4, 0x1B, 0x00); } -static void XGINew_DDR2x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBInfo) -{ - XGINew_SetReg1(P3c4, 0x18, 0x00); - XGINew_SetReg1(P3c4, 0x19, 0x20); - XGINew_SetReg1(P3c4, 0x16, 0x00); - XGINew_SetReg1(P3c4, 0x16, 0x80); - DelayUS(60); - XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ - /* XGINew_SetReg1(P3c4 ,0x18 ,0x31); */ - XGINew_SetReg1(P3c4, 0x19, 0x01); - XGINew_SetReg1(P3c4, 0x16, 0x05); - XGINew_SetReg1(P3c4, 0x16, 0x85); - DelayUS(1000); - XGINew_SetReg1(P3c4, 0x1B, 0x03); - DelayUS(500); - /* XGINew_SetReg1(P3c4, 0x18, 0x31); */ - XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ - XGINew_SetReg1(P3c4, 0x19, 0x00); - XGINew_SetReg1(P3c4, 0x16, 0x05); - XGINew_SetReg1(P3c4, 0x16, 0x85); - XGINew_SetReg1(P3c4, 0x1B, 0x00); -} - static void XGINew_DDRII_Bootup_XG27( struct xgi_hw_device_info *HwDeviceExtension, unsigned long P3c4, struct vb_device_info *pVBInfo) @@ -710,79 +623,6 @@ static void XGINew_DDR2_MRS_XG20(struct xgi_hw_device_info *HwDeviceExtension, DelayUS(200); } -#if 0 -static void XGINew_DDR2_MRS_XG27(struct xgi_hw_device_info *HwDeviceExtension, - unsigned long P3c4, struct vb_device_info *pVBInfo) -{ - unsigned long P3d4 = P3c4 + 0x10; - - XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); - XGINew_SetMemoryClock(HwDeviceExtension , pVBInfo); - - XGINew_SetReg1(P3d4, 0x97, 0x11); /* CR97 */ - DelayUS(200); - XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS2 */ - XGINew_SetReg1(P3c4, 0x19, 0x80); - - XGINew_SetReg1(P3c4, 0x16, 0x10); - DelayUS(15); /* 06/11/23 XG27 A0 for CKE enable */ - XGINew_SetReg1(P3c4, 0x16, 0x90); - - XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS3 */ - XGINew_SetReg1(P3c4, 0x19, 0xC0); - - XGINew_SetReg1(P3c4, 0x16, 0x00); - DelayUS(15); /* 06/11/22 XG27 A0 */ - XGINew_SetReg1(P3c4, 0x16, 0x80); - - XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS1 */ - XGINew_SetReg1(P3c4, 0x19, 0x40); - - XGINew_SetReg1(P3c4, 0x16, 0x00); - DelayUS(15); /* 06/11/22 XG27 A0 */ - XGINew_SetReg1(P3c4, 0x16, 0x80); - - XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */ - XGINew_SetReg1(P3c4, 0x19, 0x06); /* [Billy]06/11/22 DLL Reset for XG27 Hynix DRAM */ - - XGINew_SetReg1(P3c4, 0x16, 0x00); - DelayUS(15); /* 06/11/23 XG27 A0 */ - XGINew_SetReg1(P3c4, 0x16, 0x80); - - DelayUS(30); /* 06/11/23 XG27 A0 Start Auto-PreCharge */ - XGINew_SetReg1(P3c4, 0x1B, 0x04); /* SR1B */ - DelayUS(60); - XGINew_SetReg1(P3c4, 0x1B, 0x00); /* SR1B */ - - XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */ - XGINew_SetReg1(P3c4, 0x19, 0x04); /* DLL without Reset for XG27 Hynix DRAM */ - - XGINew_SetReg1(P3c4, 0x16, 0x00); - DelayUS(30); - XGINew_SetReg1(P3c4, 0x16, 0x80); - - XGINew_SetReg1(P3c4, 0x18, 0x80); /* XG27 OCD ON */ - XGINew_SetReg1(P3c4, 0x19, 0x46); - - XGINew_SetReg1(P3c4, 0x16, 0x00); - DelayUS(30); - XGINew_SetReg1(P3c4, 0x16, 0x80); - - XGINew_SetReg1(P3c4, 0x18, 0x00); - XGINew_SetReg1(P3c4, 0x19, 0x40); - - XGINew_SetReg1(P3c4, 0x16, 0x00); - DelayUS(30); - XGINew_SetReg1(P3c4, 0x16, 0x80); - - DelayUS(15); /* Start Auto-PreCharge */ - XGINew_SetReg1(P3c4, 0x1B, 0x04); /* SR1B */ - DelayUS(200); - XGINew_SetReg1(P3c4, 0x1B, 0x03); /* SR1B */ - -} -#endif - static void XGINew_DDR1x_DefaultRegister( struct xgi_hw_device_info *HwDeviceExtension, unsigned long Port, struct vb_device_info *pVBInfo) @@ -833,51 +673,6 @@ static void XGINew_DDR1x_DefaultRegister( } } -#if 0 - -static void XGINew_DDR2x_DefaultRegister( - struct xgi_hw_device_info *HwDeviceExtension, - unsigned long Port, struct vb_device_info *pVBInfo) -{ - unsigned long P3d4 = Port , - P3c4 = Port - 0x10; - - XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo); - - /* 20040906 Hsuan modify CR82, CR85, CR86 for XG42 */ - switch (HwDeviceExtension->jChipType) { - case XG41: - case XG42: - XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ - XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ - XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */ - break; - default: - /* keep following setting sequence, each setting in the same reg insert idle */ - XGINew_SetReg1(P3d4, 0x82, 0x88); - XGINew_SetReg1(P3d4, 0x86, 0x00); - XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */ - XGINew_SetReg1(P3d4, 0x86, 0x88); - XGINew_SetReg1(P3d4, 0x82, 0x77); - XGINew_SetReg1(P3d4, 0x85, 0x00); - XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */ - XGINew_SetReg1(P3d4, 0x85, 0x88); - XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */ - XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ - XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ - } - XGINew_SetReg1(P3d4, 0x97, 0x11); - if (HwDeviceExtension->jChipType == XG42) - XGINew_SetReg1(P3d4, 0x98, 0x01); - else - XGINew_SetReg1(P3d4, 0x98, 0x03); - - XGINew_SetReg1(P3d4, 0x9A, 0x02); - - XGINew_DDR2x_MRS_340(P3c4, pVBInfo); -} -#endif - static void XGINew_DDR2_DefaultRegister( struct xgi_hw_device_info *HwDeviceExtension, unsigned long Port, struct vb_device_info *pVBInfo) @@ -1039,95 +834,6 @@ void XGINew_SetDRAMDefaultRegister340( XGINew_SetReg1(P3c4, 0x1B, pVBInfo->SR15[3][XGINew_RAMType]); /* SR1B */ } -static void XGINew_DDR_MRS(struct vb_device_info *pVBInfo) -{ - unsigned short data; - - volatile unsigned char *pVideoMemory = (unsigned char *) pVBInfo->ROMAddr; - - /* SR16 <- 1F,DF,2F,AF */ - /* yriver modified SR16 <- 0F,DF,0F,AF */ - /* enable DLL of DDR SD/SGRAM , SR16 D4=1 */ - data = pVideoMemory[0xFB]; - /* data = XGINew_GetReg1(pVBInfo->P3c4, 0x16); */ - - data &= 0x0F; - XGINew_SetReg1(pVBInfo->P3c4, 0x16, data); - data |= 0xC0; - XGINew_SetReg1(pVBInfo->P3c4, 0x16, data); - data &= 0x0F; - XGINew_SetReg1(pVBInfo->P3c4, 0x16, data); - data |= 0x80; - XGINew_SetReg1(pVBInfo->P3c4, 0x16, data); - data &= 0x0F; - XGINew_SetReg1(pVBInfo->P3c4, 0x16, data); - data |= 0xD0; - XGINew_SetReg1(pVBInfo->P3c4, 0x16, data); - data &= 0x0F; - XGINew_SetReg1(pVBInfo->P3c4, 0x16, data); - data |= 0xA0; - XGINew_SetReg1(pVBInfo->P3c4, 0x16, data); - /* - else { - data &= 0x0F; - data |= 0x10; - XGINew_SetReg1(pVBInfo->P3c4,0x16,data); - - if (!(pVBInfo->SR15[1][XGINew_RAMType] & 0x10)) { - data &= 0x0F; - } - - data |= 0xC0; - XGINew_SetReg1(pVBInfo->P3c4,0x16,data); - - data &= 0x0F; - data |= 0x20; - XGINew_SetReg1(pVBInfo->P3c4,0x16,data); - if (!(pVBInfo->SR15[1][XGINew_RAMType] & 0x10)) { - data &= 0x0F; - } - - data |= 0x80; - XGINew_SetReg1(pVBInfo->P3c4,0x16,data); - } - */ -} - -/* check if read cache pointer is correct */ - -static void XGINew_VerifyMclk(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned char *pVideoMemory = pVBInfo->FBAddr; - unsigned char i, j; - unsigned short Temp, SR21; - - pVideoMemory[0] = 0xaa; /* alan */ - pVideoMemory[16] = 0x55; /* note: PCI read cache is off */ - - if ((pVideoMemory[0] != 0xaa) || (pVideoMemory[16] != 0x55)) { - for (i = 0, j = 16; i < 2; i++, j += 16) { - SR21 = XGINew_GetReg1(pVBInfo->P3c4, 0x21); - Temp = SR21 & 0xFB; /* disable PCI post write buffer empty gating */ - XGINew_SetReg1(pVBInfo->P3c4, 0x21, Temp); - - Temp = XGINew_GetReg1(pVBInfo->P3c4, 0x3C); - Temp |= 0x01; /* MCLK reset */ - - Temp = XGINew_GetReg1(pVBInfo->P3c4, 0x3C); - Temp &= 0xFE; /* MCLK normal operation */ - - XGINew_SetReg1(pVBInfo->P3c4, 0x21, SR21); - - pVideoMemory[16 + j] = j; - if (pVideoMemory[16 + j] == j) { - pVideoMemory[j] = j; - break; - } - } - } -} - void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { @@ -1150,576 +856,84 @@ void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *HwDeviceExtension, XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20)); /* enable read cache */ } -void XGINew_SetDRAMSize_310(struct xgi_hw_device_info *HwDeviceExtension, +static void XGINew_SetDRAMSizingType(int index, + unsigned short DRAMTYPE_TABLE[][5], struct vb_device_info *pVBInfo) { unsigned short data; - pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase, pVBInfo->FBAddr - = HwDeviceExtension->pjVideoMemoryAddress; -#ifdef XGI301 - /* XGINew_SetReg1(pVBInfo->P3d4, 0x30, 0x40); */ -#endif - -#ifdef XGI302 /* alan,should change value */ - XGINew_SetReg1(pVBInfo->P3d4, 0x30, 0x4D); - XGINew_SetReg1(pVBInfo->P3d4, 0x31, 0xc0); - XGINew_SetReg1(pVBInfo->P3d4, 0x34, 0x3F); -#endif - - XGISetModeNew(HwDeviceExtension, 0x2e); - data = XGINew_GetReg1(pVBInfo->P3c4, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data & 0xDF)); /* disable read cache */ + data = DRAMTYPE_TABLE[index][4]; + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x13, 0x80, data); + DelayUS(15); + /* should delay 50 ns */ +} - data = XGINew_GetReg1(pVBInfo->P3c4, 0x1); - data |= 0x20; - XGINew_SetReg1(pVBInfo->P3c4, 0x01, data); /* Turn OFF Display */ +static unsigned short XGINew_SetDRAMSizeReg(int index, + unsigned short DRAMTYPE_TABLE[][5], + struct vb_device_info *pVBInfo) +{ + unsigned short data = 0, memsize = 0; + int RankSize; + unsigned char ChannelNo; - data = XGINew_GetReg1(pVBInfo->P3c4, 0x16); + RankSize = DRAMTYPE_TABLE[index][3] * XGINew_DataBusWidth / 32; + data = XGINew_GetReg1(pVBInfo->P3c4, 0x13); + data &= 0x80; - XGINew_SetReg1(pVBInfo->P3c4, 0x16, (unsigned short) (data | 0x0F)); /* assume lowest speed DRAM */ + if (data == 0x80) + RankSize *= 2; - XGINew_SetDRAMModeRegister(pVBInfo); - XGINew_DisableRefresh(HwDeviceExtension, pVBInfo); - XGINew_CheckBusWidth_310(pVBInfo); - XGINew_VerifyMclk(HwDeviceExtension, pVBInfo); /* alan 2000/7/3 */ + data = 0; - if (XGINew_Get310DRAMType(pVBInfo) < 2) - XGINew_SDRSizing(pVBInfo); + if (XGINew_ChannelAB == 3) + ChannelNo = 4; else - XGINew_DDRSizing(pVBInfo); - - XGINew_SetReg1(pVBInfo->P3c4, 0x16, pVBInfo->SR15[1][XGINew_RAMType]); /* restore SR16 */ - - XGINew_EnableRefresh(HwDeviceExtension, pVBInfo); - data = XGINew_GetReg1(pVBInfo->P3c4, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20)); /* enable read cache */ -} - -void XGINew_SetDRAMModeRegister340(struct xgi_hw_device_info *HwDeviceExtension) -{ - unsigned char data; - struct vb_device_info VBINF; - struct vb_device_info *pVBInfo = &VBINF; - pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase; - pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; - pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress; - pVBInfo->ISXPDOS = 0; + ChannelNo = XGINew_ChannelAB; - pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14; - pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24; - pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10; - pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e; - pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12; - pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a; - pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16; - pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17; - pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18; - pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19; - pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A; - pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00; - pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04; - pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10; - pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12; - pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14; - pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2; - if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */ - XGI_GetVBType(pVBInfo); /* Run XGI_GetVBType before InitTo330Pointer */ + if (ChannelNo * RankSize <= 256) { + while ((RankSize >>= 1) > 0) + data += 0x10; - InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo); + memsize = data >> 4; - ReadVBIOSTablData(HwDeviceExtension->jChipType, pVBInfo); + /* [2004/03/25] Vicent, Fix DRAM Sizing Error */ + XGINew_SetReg1(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0)); - if (XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) == 0) { - data = (XGINew_GetReg1(pVBInfo->P3c4, 0x39) & 0x02) >> 1; - if (data == 0x01) - XGINew_DDR2x_MRS_340(pVBInfo->P3c4, pVBInfo); - else - XGINew_DDR1x_MRS_340(pVBInfo->P3c4, pVBInfo); - } else { - XGINew_DDR2_MRS_XG20(HwDeviceExtension, pVBInfo->P3c4, pVBInfo); - } - XGINew_SetReg1(pVBInfo->P3c4, 0x1B, 0x03); -} + /* data |= XGINew_ChannelAB << 2; */ + /* data |= (XGINew_DataBusWidth / 64) << 1; */ + /* XGINew_SetReg1(pVBInfo->P3c4, 0x14, data); */ -void XGINew_SetDRAMModeRegister(struct vb_device_info *pVBInfo) -{ - if (XGINew_Get310DRAMType(pVBInfo) < 2) { - XGINew_SDR_MRS(pVBInfo); - } else { - /* SR16 <- 0F,CF,0F,8F */ - XGINew_DDR_MRS(pVBInfo); + /* should delay */ + /* XGINew_SetDRAMModeRegister340(pVBInfo); */ } + return memsize; } -void XGINew_DisableRefresh(struct xgi_hw_device_info *HwDeviceExtension, +static unsigned short XGINew_SetDRAMSize20Reg(int index, + unsigned short DRAMTYPE_TABLE[][5], struct vb_device_info *pVBInfo) { - unsigned short data; + unsigned short data = 0, memsize = 0; + int RankSize; + unsigned char ChannelNo; - data = XGINew_GetReg1(pVBInfo->P3c4, 0x1B); - data &= 0xF8; - XGINew_SetReg1(pVBInfo->P3c4, 0x1B, data); + RankSize = DRAMTYPE_TABLE[index][3] * XGINew_DataBusWidth / 8; + data = XGINew_GetReg1(pVBInfo->P3c4, 0x13); + data &= 0x80; -} + if (data == 0x80) + RankSize *= 2; -void XGINew_EnableRefresh(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ + data = 0; - XGINew_SetReg1(pVBInfo->P3c4, 0x1B, pVBInfo->SR15[3][XGINew_RAMType]); /* SR1B */ + if (XGINew_ChannelAB == 3) + ChannelNo = 4; + else + ChannelNo = XGINew_ChannelAB; -} - -static void XGINew_DisableChannelInterleaving(int index, - unsigned short XGINew_DDRDRAM_TYPE[][5], - struct vb_device_info *pVBInfo) -{ - unsigned short data; - - data = XGINew_GetReg1(pVBInfo->P3c4, 0x15); - data &= 0x1F; - - switch (XGINew_DDRDRAM_TYPE[index][3]) { - case 64: - data |= 0; - break; - case 32: - data |= 0x20; - break; - case 16: - data |= 0x40; - break; - case 4: - data |= 0x60; - break; - default: - break; - } - XGINew_SetReg1(pVBInfo->P3c4, 0x15, data); -} - -static void XGINew_SetDRAMSizingType(int index, - unsigned short DRAMTYPE_TABLE[][5], - struct vb_device_info *pVBInfo) -{ - unsigned short data; - - data = DRAMTYPE_TABLE[index][4]; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x13, 0x80, data); - DelayUS(15); - /* should delay 50 ns */ -} - -void XGINew_CheckBusWidth_310(struct vb_device_info *pVBInfo) -{ - unsigned short data; - volatile unsigned long *pVideoMemory; - - pVideoMemory = (unsigned long *) pVBInfo->FBAddr; - - if (XGINew_Get310DRAMType(pVBInfo) < 2) { - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x00); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x12); - /* should delay */ - XGINew_SDR_MRS(pVBInfo); - - XGINew_ChannelAB = 0; - XGINew_DataBusWidth = 128; - pVideoMemory[0] = 0x01234567L; - pVideoMemory[1] = 0x456789ABL; - pVideoMemory[2] = 0x89ABCDEFL; - pVideoMemory[3] = 0xCDEF0123L; - pVideoMemory[4] = 0x55555555L; - pVideoMemory[5] = 0x55555555L; - pVideoMemory[6] = 0xFFFFFFFFL; - pVideoMemory[7] = 0xFFFFFFFFL; - - if ((pVideoMemory[3] != 0xCDEF0123L) || (pVideoMemory[2] - != 0x89ABCDEFL)) { - /* ChannelA64Bit */ - XGINew_DataBusWidth = 64; - XGINew_ChannelAB = 0; - data = XGINew_GetReg1(pVBInfo->P3c4, 0x14); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, - (unsigned short) (data & 0xFD)); - } - - if ((pVideoMemory[1] != 0x456789ABL) || (pVideoMemory[0] - != 0x01234567L)) { - /* ChannelB64Bit */ - XGINew_DataBusWidth = 64; - XGINew_ChannelAB = 1; - data = XGINew_GetReg1(pVBInfo->P3c4, 0x14); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, - (unsigned short) ((data & 0xFD) | 0x01)); - } - - return; - } else { - /* DDR Dual channel */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x00); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x02); /* Channel A, 64bit */ - /* should delay */ - XGINew_DDR_MRS(pVBInfo); - - XGINew_ChannelAB = 0; - XGINew_DataBusWidth = 64; - pVideoMemory[0] = 0x01234567L; - pVideoMemory[1] = 0x456789ABL; - pVideoMemory[2] = 0x89ABCDEFL; - pVideoMemory[3] = 0xCDEF0123L; - pVideoMemory[4] = 0x55555555L; - pVideoMemory[5] = 0x55555555L; - pVideoMemory[6] = 0xAAAAAAAAL; - pVideoMemory[7] = 0xAAAAAAAAL; - - if (pVideoMemory[1] == 0x456789ABL) { - if (pVideoMemory[0] == 0x01234567L) { - /* Channel A 64bit */ - return; - } - } else { - if (pVideoMemory[0] == 0x01234567L) { - /* Channel A 32bit */ - XGINew_DataBusWidth = 32; - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x00); - return; - } - } - - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x03); /* Channel B, 64bit */ - XGINew_DDR_MRS(pVBInfo); - - XGINew_ChannelAB = 1; - XGINew_DataBusWidth = 64; - pVideoMemory[0] = 0x01234567L; - pVideoMemory[1] = 0x456789ABL; - pVideoMemory[2] = 0x89ABCDEFL; - pVideoMemory[3] = 0xCDEF0123L; - pVideoMemory[4] = 0x55555555L; - pVideoMemory[5] = 0x55555555L; - pVideoMemory[6] = 0xAAAAAAAAL; - pVideoMemory[7] = 0xAAAAAAAAL; - - if (pVideoMemory[1] == 0x456789ABL) { - /* Channel B 64 */ - if (pVideoMemory[0] == 0x01234567L) { - /* Channel B 64bit */ - return; - } else { - /* error */ - } - } else { - if (pVideoMemory[0] == 0x01234567L) { - /* Channel B 32 */ - XGINew_DataBusWidth = 32; - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x01); - } else { - /* error */ - } - } - } -} - -static int XGINew_SetRank(int index, unsigned char RankNo, - unsigned char XGINew_ChannelAB, - unsigned short DRAMTYPE_TABLE[][5], - struct vb_device_info *pVBInfo) -{ - unsigned short data; - int RankSize; - - if ((RankNo == 2) && (DRAMTYPE_TABLE[index][0] == 2)) - return 0; - - RankSize = DRAMTYPE_TABLE[index][3] / 2 * XGINew_DataBusWidth / 32; - - if ((RankNo * RankSize) <= 128) { - data = 0; - - while ((RankSize >>= 1) > 0) - data += 0x10; - - data |= (RankNo - 1) << 2; - data |= (XGINew_DataBusWidth / 64) & 2; - data |= XGINew_ChannelAB; - XGINew_SetReg1(pVBInfo->P3c4, 0x14, data); - /* should delay */ - XGINew_SDR_MRS(pVBInfo); - return 1; - } else { - return 0; - } -} - -static int XGINew_SetDDRChannel(int index, unsigned char ChannelNo, - unsigned char XGINew_ChannelAB, - unsigned short DRAMTYPE_TABLE[][5], - struct vb_device_info *pVBInfo) -{ - unsigned short data; - int RankSize; - - RankSize = DRAMTYPE_TABLE[index][3] / 2 * XGINew_DataBusWidth / 32; - /* RankSize = DRAMTYPE_TABLE[index][3]; */ - if (ChannelNo * RankSize <= 128) { - data = 0; - while ((RankSize >>= 1) > 0) - data += 0x10; - - if (ChannelNo == 2) - data |= 0x0C; - - data |= (XGINew_DataBusWidth / 32) & 2; - data |= XGINew_ChannelAB; - XGINew_SetReg1(pVBInfo->P3c4, 0x14, data); - /* should delay */ - XGINew_DDR_MRS(pVBInfo); - return 1; - } else { - return 0; - } -} - -static int XGINew_CheckColumn(int index, unsigned short DRAMTYPE_TABLE[][5], - struct vb_device_info *pVBInfo) -{ - int i; - unsigned long Increment, Position; - - /* Increment = 1 << (DRAMTYPE_TABLE[index][2] + XGINew_DataBusWidth / 64 + 1); */ - Increment = 1 << (10 + XGINew_DataBusWidth / 64); - - for (i = 0, Position = 0; i < 2; i++) { - *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position; - Position += Increment; - } - - for (i = 0, Position = 0; i < 2; i++) { - /* if ( pVBInfo->FBAddr[ Position ] != Position ) */ - if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position) - return 0; - Position += Increment; - } - return 1; -} - -static int XGINew_CheckBanks(int index, unsigned short DRAMTYPE_TABLE[][5], - struct vb_device_info *pVBInfo) -{ - int i; - unsigned long Increment, Position; - - Increment = 1 << (DRAMTYPE_TABLE[index][2] + XGINew_DataBusWidth / 64 + 2); - - for (i = 0, Position = 0; i < 4; i++) { - /* pVBInfo->FBAddr[Position] = Position; */ - *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position; - Position += Increment; - } - - for (i = 0, Position = 0; i < 4; i++) { - /* if (pVBInfo->FBAddr[Position] != Position) */ - if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position) - return 0; - Position += Increment; - } - return 1; -} - -static int XGINew_CheckRank(int RankNo, int index, - unsigned short DRAMTYPE_TABLE[][5], - struct vb_device_info *pVBInfo) -{ - int i; - unsigned long Increment, Position; - - Increment = 1 << (DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] - + DRAMTYPE_TABLE[index][0] + XGINew_DataBusWidth / 64 - + RankNo); - - for (i = 0, Position = 0; i < 2; i++) { - /* pVBInfo->FBAddr[Position] = Position; */ - /* *((unsigned long *)(pVBInfo->FBAddr)) = Position; */ - *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position; - Position += Increment; - } - - for (i = 0, Position = 0; i < 2; i++) { - /* if (pVBInfo->FBAddr[Position] != Position) */ - /* if ((*(unsigned long *)(pVBInfo->FBAddr)) != Position) */ - if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position) - return 0; - Position += Increment; - } - return 1; -} - -static int XGINew_CheckDDRRank(int RankNo, int index, - unsigned short DRAMTYPE_TABLE[][5], - struct vb_device_info *pVBInfo) -{ - unsigned long Increment, Position; - unsigned short data; - - Increment = 1 << (DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] - + DRAMTYPE_TABLE[index][0] + XGINew_DataBusWidth / 64 - + RankNo); - - Increment += Increment / 2; - - Position = 0; - *((unsigned long *) (pVBInfo->FBAddr + Position + 0)) = 0x01234567; - *((unsigned long *) (pVBInfo->FBAddr + Position + 1)) = 0x456789AB; - *((unsigned long *) (pVBInfo->FBAddr + Position + 2)) = 0x55555555; - *((unsigned long *) (pVBInfo->FBAddr + Position + 3)) = 0x55555555; - *((unsigned long *) (pVBInfo->FBAddr + Position + 4)) = 0xAAAAAAAA; - *((unsigned long *) (pVBInfo->FBAddr + Position + 5)) = 0xAAAAAAAA; - - if ((*(unsigned long *) (pVBInfo->FBAddr + 1)) == 0x456789AB) - return 1; - - if ((*(unsigned long *) (pVBInfo->FBAddr + 0)) == 0x01234567) - return 0; - - data = XGINew_GetReg1(pVBInfo->P3c4, 0x14); - data &= 0xF3; - data |= 0x0E; - XGINew_SetReg1(pVBInfo->P3c4, 0x14, data); - data = XGINew_GetReg1(pVBInfo->P3c4, 0x15); - data += 0x20; - XGINew_SetReg1(pVBInfo->P3c4, 0x15, data); - - return 1; -} - -static int XGINew_CheckRanks(int RankNo, int index, - unsigned short DRAMTYPE_TABLE[][5], - struct vb_device_info *pVBInfo) -{ - int r; - - for (r = RankNo; r >= 1; r--) { - if (!XGINew_CheckRank(r, index, DRAMTYPE_TABLE, pVBInfo)) - return 0; - } - - if (!XGINew_CheckBanks(index, DRAMTYPE_TABLE, pVBInfo)) - return 0; - - if (!XGINew_CheckColumn(index, DRAMTYPE_TABLE, pVBInfo)) - return 0; - - return 1; -} - -static int XGINew_CheckDDRRanks(int RankNo, int index, - unsigned short DRAMTYPE_TABLE[][5], - struct vb_device_info *pVBInfo) -{ - int r; - - for (r = RankNo; r >= 1; r--) { - if (!XGINew_CheckDDRRank(r, index, DRAMTYPE_TABLE, pVBInfo)) - return 0; - } - - if (!XGINew_CheckBanks(index, DRAMTYPE_TABLE, pVBInfo)) - return 0; - - if (!XGINew_CheckColumn(index, DRAMTYPE_TABLE, pVBInfo)) - return 0; - - return 1; -} - -int XGINew_SDRSizing(struct vb_device_info *pVBInfo) -{ - int i; - unsigned char j; - - for (i = 0; i < 13; i++) { - XGINew_SetDRAMSizingType(i, XGINew_SDRDRAM_TYPE, pVBInfo); - - for (j = 2; j > 0; j--) { - if (!XGINew_SetRank(i, (unsigned char) j, XGINew_ChannelAB, XGINew_SDRDRAM_TYPE, pVBInfo)) { - continue; - } else { - if (XGINew_CheckRanks(j, i, XGINew_SDRDRAM_TYPE, pVBInfo)) - return 1; - } - } - } - return 0; -} - -static unsigned short XGINew_SetDRAMSizeReg(int index, - unsigned short DRAMTYPE_TABLE[][5], - struct vb_device_info *pVBInfo) -{ - unsigned short data = 0, memsize = 0; - int RankSize; - unsigned char ChannelNo; - - RankSize = DRAMTYPE_TABLE[index][3] * XGINew_DataBusWidth / 32; - data = XGINew_GetReg1(pVBInfo->P3c4, 0x13); - data &= 0x80; - - if (data == 0x80) - RankSize *= 2; - - data = 0; - - if (XGINew_ChannelAB == 3) - ChannelNo = 4; - else - ChannelNo = XGINew_ChannelAB; - - if (ChannelNo * RankSize <= 256) { - while ((RankSize >>= 1) > 0) - data += 0x10; - - memsize = data >> 4; - - /* [2004/03/25] Vicent, Fix DRAM Sizing Error */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0)); - - /* data |= XGINew_ChannelAB << 2; */ - /* data |= (XGINew_DataBusWidth / 64) << 1; */ - /* XGINew_SetReg1(pVBInfo->P3c4, 0x14, data); */ - - /* should delay */ - /* XGINew_SetDRAMModeRegister340(pVBInfo); */ - } - return memsize; -} - -static unsigned short XGINew_SetDRAMSize20Reg(int index, - unsigned short DRAMTYPE_TABLE[][5], - struct vb_device_info *pVBInfo) -{ - unsigned short data = 0, memsize = 0; - int RankSize; - unsigned char ChannelNo; - - RankSize = DRAMTYPE_TABLE[index][3] * XGINew_DataBusWidth / 8; - data = XGINew_GetReg1(pVBInfo->P3c4, 0x13); - data &= 0x80; - - if (data == 0x80) - RankSize *= 2; - - data = 0; - - if (XGINew_ChannelAB == 3) - ChannelNo = 4; - else - ChannelNo = XGINew_ChannelAB; - - if (ChannelNo * RankSize <= 256) { - while ((RankSize >>= 1) > 0) - data += 0x10; + if (ChannelNo * RankSize <= 256) { + while ((RankSize >>= 1) > 0) + data += 0x10; memsize = data >> 4; @@ -2075,27 +1289,6 @@ int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension, return 0; } -int XGINew_DDRSizing(struct vb_device_info *pVBInfo) -{ - int i; - unsigned char j; - - for (i = 0; i < 4; i++) { - XGINew_SetDRAMSizingType(i, XGINew_DDRDRAM_TYPE, pVBInfo); - XGINew_DisableChannelInterleaving(i, XGINew_DDRDRAM_TYPE, pVBInfo); - for (j = 2; j > 0; j--) { - XGINew_SetDDRChannel(i, j, XGINew_ChannelAB, XGINew_DDRDRAM_TYPE, pVBInfo); - if (!XGINew_SetRank(i, (unsigned char) j, XGINew_ChannelAB, XGINew_DDRDRAM_TYPE, pVBInfo)) { - continue; - } else { - if (XGINew_CheckDDRRanks(j, i, XGINew_DDRDRAM_TYPE, pVBInfo)) - return 1; - } - } - } - return 0; -} - void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { @@ -2121,89 +1314,6 @@ void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, } } -unsigned char ChkLFB(struct vb_device_info *pVBInfo) -{ - if (LFBDRAMTrap & XGINew_GetReg1(pVBInfo->P3d4, 0x78)) - return 1; - else - return 0; -} - -/* --------------------------------------------------------------------- */ -/* input : dx ,valid value : CR or second chip's CR */ -/* */ -/* SetPowerConsume : */ -/* Description: reduce 40/43 power consumption in first chip or */ -/* in second chip, assume CR A1 D[6]="1" in this case */ -/* output : none */ -/* --------------------------------------------------------------------- */ -void SetPowerConsume(struct xgi_hw_device_info *HwDeviceExtension, - unsigned long XGI_P3d4Port) -{ - unsigned long lTemp; - unsigned char bTemp; - - HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension, 0x08, 0, &lTemp); /* Get */ - if ((lTemp & 0xFF) == 0) { - /* set CR58 D[5]=0 D[3]=0 */ - XGINew_SetRegAND(XGI_P3d4Port, 0x58, 0xD7); - bTemp = (unsigned char) XGINew_GetReg1(XGI_P3d4Port, 0xCB); - if (bTemp & 0x20) { - if (!(bTemp & 0x10)) - XGINew_SetRegANDOR(XGI_P3d4Port, 0x58, 0xD7, 0x20); /* CR58 D[5]=1 D[3]=0 */ - else - XGINew_SetRegANDOR(XGI_P3d4Port, 0x58, 0xD7, 0x08); /* CR58 D[5]=0 D[3]=1 */ - - } - - } -} - -#if 0 -static void XGINew_InitVBIOSData(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - - /* unsigned long ROMAddr = (unsigned long) HwDeviceExtension->pjVirtualRomBase; */ - pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase; - pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; - pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress; - pVBInfo->ISXPDOS = 0; - - pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14; - pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24; - pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10; - pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e; - pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12; - pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a; - pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16; - pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17; - pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18; - pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19; - pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A; - pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00; - pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04; - pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10; - pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12; - pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14; - pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2; - if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */ - XGI_GetVBType(pVBInfo); /* Run XGI_GetVBType before InitTo330Pointer */ - - switch (HwDeviceExtension->jChipType) { - case XG40: - case XG41: - case XG42: - case XG20: - case XG21: - default: - InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo); - return; - } - -} -#endif - void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo) { volatile unsigned char *pVideoMemory = (unsigned char *) pVBInfo->ROMAddr; @@ -2324,130 +1434,6 @@ void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo) XGINew_SetReg1(P3c4, 0x1B, 0x00); } -void XGINew_SetDRAMModeRegister_XG20(struct xgi_hw_device_info *HwDeviceExtension) -{ - struct vb_device_info VBINF; - struct vb_device_info *pVBInfo = &VBINF; - pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase; - pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; - pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress; - pVBInfo->ISXPDOS = 0; - - pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14; - pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24; - pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10; - pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e; - pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12; - pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a; - pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16; - pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17; - pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18; - pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19; - pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A; - pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00; - pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04; - pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10; - pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12; - pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14; - pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2; - - InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo); - - ReadVBIOSTablData(HwDeviceExtension->jChipType, pVBInfo); - - if (XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) == 0) - XGINew_DDR1x_MRS_XG20(pVBInfo->P3c4, pVBInfo); - else - XGINew_DDR2_MRS_XG20(HwDeviceExtension, pVBInfo->P3c4, pVBInfo); - - XGINew_SetReg1(pVBInfo->P3c4, 0x1B, 0x03); -} - -void XGINew_SetDRAMModeRegister_XG27( - struct xgi_hw_device_info *HwDeviceExtension) -{ - struct vb_device_info VBINF; - struct vb_device_info *pVBInfo = &VBINF; - pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase; - pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; - pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress; - pVBInfo->ISXPDOS = 0; - - pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14; - pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24; - pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10; - pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e; - pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12; - pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a; - pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16; - pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17; - pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18; - pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19; - pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A; - pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00; - pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04; - pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10; - pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12; - pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14; - pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2; - - InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo); - - ReadVBIOSTablData(HwDeviceExtension->jChipType, pVBInfo); - - if (XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) == 0) - XGINew_DDR1x_MRS_XG20(pVBInfo->P3c4, pVBInfo); - else - /* XGINew_DDR2_MRS_XG27(HwDeviceExtension, pVBInfo->P3c4, pVBInfo); */ - XGINew_DDRII_Bootup_XG27(HwDeviceExtension, pVBInfo->P3c4, pVBInfo); - - /* XGINew_SetReg1(pVBInfo->P3c4, 0x1B, 0x03); */ - XGINew_SetReg1(pVBInfo->P3c4, 0x1B, pVBInfo->SR15[3][XGINew_RAMType]); /* SR1B */ - -} - -/* -void XGINew_SetDRAMModeRegister_XG27(struct xgi_hw_device_info *HwDeviceExtension) -{ - unsigned char data; - struct vb_device_info VBINF; - struct vb_device_info *pVBInfo = &VBINF; - pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase; - pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; - pVBInfo->BaseAddr = HwDeviceExtension->pjIOAddress; - pVBInfo->ISXPDOS = 0; - - pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14; - pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24; - pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10; - pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e; - pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12; - pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a; - pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16; - pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17; - pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18; - pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19; - pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A; - pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00; - pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04; - pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10; - pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12; - pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14; - pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2; - - InitTo330Pointer(HwDeviceExtension->jChipType,pVBInfo); - - ReadVBIOSTablData(HwDeviceExtension->jChipType , pVBInfo); - - if (XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) == 0) - XGINew_DDR1x_MRS_XG20(pVBInfo->P3c4, pVBInfo); - else - XGINew_DDR2_MRS_XG27(HwDeviceExtension, pVBInfo->P3c4, pVBInfo); - - XGINew_SetReg1(pVBInfo->P3c4, 0x1B, 0x03); -} -*/ - void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { -- cgit v1.2.3 From e0cc8a60c4f9352c8281af6eb49f13cf5a7bb476 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 8 Mar 2011 22:16:20 +0200 Subject: staging: xgifb: vb_init: make internal functions static Make some internal functions static. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_ext.h | 3 --- drivers/staging/xgifb/vb_init.c | 51 +++++++++++++++++++++-------------------- 2 files changed, 26 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_ext.h b/drivers/staging/xgifb/vb_ext.h index 682452549746..cabe365579c5 100644 --- a/drivers/staging/xgifb/vb_ext.h +++ b/drivers/staging/xgifb/vb_ext.h @@ -22,9 +22,6 @@ typedef union _X86_REGS { } X86_REGS, *PX86_REGS; extern void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -extern void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ; -extern void ReadVBIOSTablData(unsigned char ChipType, - struct vb_device_info *pVBInfo); extern unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 2cf50ddc5b5b..4bbcff6aedfe 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -37,22 +37,23 @@ static unsigned short XGINew_DDRDRAM_TYPE20[12][5] = { { 2, 12, 9, 8, 0x35}, { 2, 12, 8, 4, 0x31} }; -void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *, struct vb_device_info *); -void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *); -void XGINew_SetDRAMDefaultRegister340(struct xgi_hw_device_info *HwDeviceExtension, +static void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *, struct vb_device_info *); +static void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *); +static void XGINew_SetDRAMDefaultRegister340(struct xgi_hw_device_info *HwDeviceExtension, unsigned long, struct vb_device_info *); -unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension, +static unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -int XGINew_DDRSizing340(struct xgi_hw_device_info *, struct vb_device_info *); +static int XGINew_DDRSizing340(struct xgi_hw_device_info *, struct vb_device_info *); static int XGINew_RAMType; /*int ModeIDOffset,StandTable,CRT1Table,ScreenOffset,REFIndex;*/ -void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo); -void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo); -void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ; -void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ; -unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo); -void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ; -unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo); +static void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo); +static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo); +static void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ; +static void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ; +static unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo); +static void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ; +static unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo); +static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ; static void DelayUS(unsigned long MicroSeconds) { @@ -419,7 +420,7 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) /* ============== alan ====================== */ -unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension, +static unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { unsigned char data, temp; @@ -705,7 +706,7 @@ static void XGINew_DDR2_DefaultRegister( XGINew_DDR2_MRS_XG20(HwDeviceExtension, P3c4, pVBInfo); } -void XGINew_SetDRAMDefaultRegister340( +static void XGINew_SetDRAMDefaultRegister340( struct xgi_hw_device_info *HwDeviceExtension, unsigned long Port, struct vb_device_info *pVBInfo) { @@ -834,7 +835,7 @@ void XGINew_SetDRAMDefaultRegister340( XGINew_SetReg1(P3c4, 0x1B, pVBInfo->SR15[3][XGINew_RAMType]); /* SR1B */ } -void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *HwDeviceExtension, +static void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { unsigned short data; @@ -1246,7 +1247,7 @@ static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, } } -int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension, +static int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { int i; @@ -1289,7 +1290,7 @@ int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension, return 0; } -void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, +static void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { @@ -1314,7 +1315,7 @@ void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, } } -void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo) +static void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo) { volatile unsigned char *pVideoMemory = (unsigned char *) pVBInfo->ROMAddr; unsigned long i; @@ -1404,7 +1405,7 @@ void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo) } } -void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo) +static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo) { XGINew_SetReg1(P3c4, 0x18, 0x01); @@ -1434,7 +1435,7 @@ void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo) XGINew_SetReg1(P3c4, 0x1B, 0x00); } -void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, +static void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { unsigned short tempbx = 0, temp, tempcx, CR3CData; @@ -1482,7 +1483,7 @@ void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, XGINew_SetReg1(pVBInfo->P3d4, 0x3e, ((tempbx & 0xFF00) >> 8)); } -void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, +static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { unsigned short temp, tempcl = 0, tempch = 0, CR31Data, CR38Data; @@ -1564,7 +1565,7 @@ void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, } -void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension, +static void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { unsigned char Temp; @@ -1598,7 +1599,7 @@ void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension, #endif } -void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension, +static void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { unsigned char Temp, bCR4A; @@ -1620,7 +1621,7 @@ void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension, } -unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo) +static unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo) { unsigned char CR38, CR4A, temp; @@ -1639,7 +1640,7 @@ unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo) return temp; } -unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo) +static unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo) { unsigned char CR4A, temp; -- cgit v1.2.3 From c1605f2e3312ca149caf32129e0b25b1e7296f36 Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Wed, 2 Mar 2011 03:59:56 -0600 Subject: drivers:misc: ti-st: fix debugging code debug code in TI-ST driver can be enabled by #defining DEBUG in the first line of the code and in case debugfs is mounted, the 2 entries in /sys/kernel/debug/ti-st/ will also provide useful information. These 2 were broken because of the recent changes to the parsing logic and the registration mechanism of the protocol drivers, this patch fixes them. Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_core.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 1847c477c0c0..486117f72c9f 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -475,9 +475,9 @@ void kim_st_list_protocols(struct st_data_s *st_gdata, void *buf) { seq_printf(buf, "[%d]\nBT=%c\nFM=%c\nGPS=%c\n", st_gdata->protos_registered, - st_gdata->list[ST_BT] != NULL ? 'R' : 'U', - st_gdata->list[ST_FM] != NULL ? 'R' : 'U', - st_gdata->list[ST_GPS] != NULL ? 'R' : 'U'); + st_gdata->list[0x04] != NULL ? 'R' : 'U', + st_gdata->list[0x08] != NULL ? 'R' : 'U', + st_gdata->list[0x09] != NULL ? 'R' : 'U'); } /********************************************************************/ @@ -644,9 +644,6 @@ long st_unregister(struct st_proto_s *proto) long st_write(struct sk_buff *skb) { struct st_data_s *st_gdata; -#ifdef DEBUG - unsigned char chnl_id = ST_MAX_CHANNELS; -#endif long len; st_kim_ref(&st_gdata, 0); @@ -655,14 +652,7 @@ long st_write(struct sk_buff *skb) pr_err("data/tty unavailable to perform write"); return -EINVAL; } -#ifdef DEBUG /* open-up skb to read the 1st byte */ - chnl_id = skb->data[0]; - if (unlikely(st_gdata->list[chnl_id] == NULL)) { - pr_err(" chnl_id %d not registered, and writing? ", - chnl_id); - return -EINVAL; - } -#endif + pr_debug("%d to be written", skb->len); len = skb->len; -- cgit v1.2.3 From bb18bb942a31411954021ad036ca7bace642c3c0 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 9 Mar 2011 16:58:19 +0000 Subject: tg3: Add missed 5719 workaround change Commit 2866d956fe0ad8fc8d8a7c54104ccc879b49406d, entitled "tg3: Expand 5719 workaround" extended a 5719 A0 workaround to all revisions of the chip. There was a change that should have been a part of that patch that was missed. This patch adds the missing piece. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 6be418591df9..6fd5cf055830 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8103,7 +8103,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) /* Program the jumbo buffer descriptor ring control * blocks on those devices that have them. */ - if (tp->pci_chip_rev_id == CHIPREV_ID_5719_A0 || + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) && !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))) { /* Setup replenish threshold. */ -- cgit v1.2.3 From 01c3a3920f9f78866420b2004602944fca45083a Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 9 Mar 2011 16:58:20 +0000 Subject: tg3: Fix NVRAM selftest The tg3 NVRAM selftest actually fails when validating the checksum of the legacy NVRAM format. However, the test still reported success because the last update of the return code was a success from the NVRAM reads. This patch fixes the code so that the error return code defaults to a failure status. Then the patch fixes the reason why the checsum validation failed. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 6fd5cf055830..8f7160812e06 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10487,14 +10487,16 @@ static int tg3_test_nvram(struct tg3 *tp) goto out; } + err = -EIO; + /* Bootstrap checksum at offset 0x10 */ csum = calc_crc((unsigned char *) buf, 0x10); - if (csum != be32_to_cpu(buf[0x10/4])) + if (csum != le32_to_cpu(buf[0x10/4])) goto out; /* Manufacturing block starts at offset 0x74, checksum at 0xfc */ csum = calc_crc((unsigned char *) &buf[0x74/4], 0x88); - if (csum != be32_to_cpu(buf[0xfc/4])) + if (csum != le32_to_cpu(buf[0xfc/4])) goto out; err = 0; -- cgit v1.2.3 From d4894f3ea7375dd9492b5d3d2ecb0b6e4bdb604e Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 9 Mar 2011 16:58:21 +0000 Subject: tg3: Add code to verify RODATA checksum of VPD This patch adds code to verify the checksum stored in the "RV" info keyword of the RODATA VPD section. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 35 +++++++++++++++++++++++++++++++++++ include/linux/pci.h | 1 + 2 files changed, 36 insertions(+) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 8f7160812e06..ffb09795101e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10499,6 +10499,41 @@ static int tg3_test_nvram(struct tg3 *tp) if (csum != le32_to_cpu(buf[0xfc/4])) goto out; + for (i = 0; i < TG3_NVM_VPD_LEN; i += 4) { + /* The data is in little-endian format in NVRAM. + * Use the big-endian read routines to preserve + * the byte order as it exists in NVRAM. + */ + if (tg3_nvram_read_be32(tp, TG3_NVM_VPD_OFF + i, &buf[i/4])) + goto out; + } + + i = pci_vpd_find_tag((u8 *)buf, 0, TG3_NVM_VPD_LEN, + PCI_VPD_LRDT_RO_DATA); + if (i > 0) { + j = pci_vpd_lrdt_size(&((u8 *)buf)[i]); + if (j < 0) + goto out; + + if (i + PCI_VPD_LRDT_TAG_SIZE + j > TG3_NVM_VPD_LEN) + goto out; + + i += PCI_VPD_LRDT_TAG_SIZE; + j = pci_vpd_find_info_keyword((u8 *)buf, i, j, + PCI_VPD_RO_KEYWORD_CHKSUM); + if (j > 0) { + u8 csum8 = 0; + + j += PCI_VPD_INFO_FLD_HDR_SIZE; + + for (i = 0; i <= j; i++) + csum8 += ((u8 *)buf)[i]; + + if (csum8) + goto out; + } + } + err = 0; out: diff --git a/include/linux/pci.h b/include/linux/pci.h index 559d02897075..ff5bccb87136 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1479,6 +1479,7 @@ void pci_request_acs(void); #define PCI_VPD_RO_KEYWORD_PARTNO "PN" #define PCI_VPD_RO_KEYWORD_MFR_ID "MN" #define PCI_VPD_RO_KEYWORD_VENDOR0 "V0" +#define PCI_VPD_RO_KEYWORD_CHKSUM "RV" /** * pci_vpd_lrdt_size - Extracts the Large Resource Data Type length -- cgit v1.2.3 From 4143470c10ab5c2bbd0522efe92935416332c5e8 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 9 Mar 2011 16:58:22 +0000 Subject: tg3: cleanup pci device table vars Commit 895950c2a6565d9eefda4a38b00fa28537e39fcb, entitled "tg3: Use DEFINE_PCI_DEVICE_TABLE" moved two pci device tables into the global address space, but didn't declare them static and didn't prefix them with "tg3_". This patch fixes those problems. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index ffb09795101e..73eacbd5c94f 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -13115,7 +13115,7 @@ static inline u32 tg3_rx_ret_ring_size(struct tg3 *tp) return 512; } -DEFINE_PCI_DEVICE_TABLE(write_reorder_chipsets) = { +static DEFINE_PCI_DEVICE_TABLE(tg3_write_reorder_chipsets) = { { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE) }, { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8385_0) }, @@ -13469,7 +13469,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) * every mailbox register write to force the writes to be * posted to the chip in order. */ - if (pci_dev_present(write_reorder_chipsets) && + if (pci_dev_present(tg3_write_reorder_chipsets) && !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) tp->tg3_flags |= TG3_FLAG_MBOX_WRITE_REORDER; @@ -14225,7 +14225,7 @@ static int __devinit tg3_do_test_dma(struct tg3 *tp, u32 *buf, dma_addr_t buf_dm #define TEST_BUFFER_SIZE 0x2000 -DEFINE_PCI_DEVICE_TABLE(dma_wait_state_chipsets) = { +static DEFINE_PCI_DEVICE_TABLE(tg3_dma_wait_state_chipsets) = { { PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_PCI15) }, { }, }; @@ -14404,7 +14404,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp) * now look for chipsets that are known to expose the * DMA bug without failing the test. */ - if (pci_dev_present(dma_wait_state_chipsets)) { + if (pci_dev_present(tg3_dma_wait_state_chipsets)) { tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK; tp->dma_rwctrl |= DMA_RWCTRL_WRITE_BNDRY_16; } else { -- cgit v1.2.3 From 683644b74783725971e5ff61618bd932c5361c3f Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 9 Mar 2011 16:58:23 +0000 Subject: tg3: Refine VAux decision process In the near future, the VAux switching decision process is going to get more complicated. This patch refines and consolidates the existing algorithm in anticipation of the new scheme. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 73eacbd5c94f..159eb230f1aa 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -2120,7 +2120,7 @@ out: static void tg3_frob_aux_power(struct tg3 *tp) { - struct tg3 *tp_peer = tp; + bool need_vaux = false; /* The GPIOs do something completely different on 57765. */ if ((tp->tg3_flags2 & TG3_FLG2_IS_NIC) == 0 || @@ -2128,23 +2128,32 @@ static void tg3_frob_aux_power(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) return; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) { + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) && + tp->pdev_peer != tp->pdev) { struct net_device *dev_peer; dev_peer = pci_get_drvdata(tp->pdev_peer); + /* remove_one() may have been run on the peer. */ - if (!dev_peer) - tp_peer = tp; - else - tp_peer = netdev_priv(dev_peer); + if (dev_peer) { + struct tg3 *tp_peer = netdev_priv(dev_peer); + + if (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) + return; + + if ((tp_peer->tg3_flags & TG3_FLAG_WOL_ENABLE) || + (tp_peer->tg3_flags & TG3_FLAG_ENABLE_ASF)) + need_vaux = true; + } } - if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 || - (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0 || - (tp_peer->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 || - (tp_peer->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) { + if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) || + (tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) + need_vaux = true; + + if (need_vaux) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | @@ -2174,10 +2183,6 @@ static void tg3_frob_aux_power(struct tg3 *tp) u32 no_gpio2; u32 grc_local_ctrl = 0; - if (tp_peer != tp && - (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) != 0) - return; - /* Workaround to prevent overdrawing Amps. */ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) { @@ -2216,10 +2221,6 @@ static void tg3_frob_aux_power(struct tg3 *tp) } else { if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) { - if (tp_peer != tp && - (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) != 0) - return; - tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | (GRC_LCLCTRL_GPIO_OE1 | GRC_LCLCTRL_GPIO_OUTPUT1), 100); -- cgit v1.2.3 From e256f8a35179f3795a200912b79c369676ecb669 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 9 Mar 2011 16:58:24 +0000 Subject: tg3: Move tg3_init_link_config to tg3_phy_probe This patch moves the function that initializes the link configuration closer to the place where the rest of the phy code is initialized. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 69 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 159eb230f1aa..2c67cc954629 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -12557,12 +12557,45 @@ static u32 __devinit tg3_read_otp_phycfg(struct tg3 *tp) return ((thalf_otp & 0x0000ffff) << 16) | (bhalf_otp >> 16); } +static void __devinit tg3_phy_init_link_config(struct tg3 *tp) +{ + u32 adv = ADVERTISED_Autoneg | + ADVERTISED_Pause; + + if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) + adv |= ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full; + + if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES)) + adv |= ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full | + ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_TP; + else + adv |= ADVERTISED_FIBRE; + + tp->link_config.advertising = adv; + tp->link_config.speed = SPEED_INVALID; + tp->link_config.duplex = DUPLEX_INVALID; + tp->link_config.autoneg = AUTONEG_ENABLE; + tp->link_config.active_speed = SPEED_INVALID; + tp->link_config.active_duplex = DUPLEX_INVALID; + tp->link_config.orig_speed = SPEED_INVALID; + tp->link_config.orig_duplex = DUPLEX_INVALID; + tp->link_config.orig_autoneg = AUTONEG_INVALID; +} + static int __devinit tg3_phy_probe(struct tg3 *tp) { u32 hw_phy_id_1, hw_phy_id_2; u32 hw_phy_id, hw_phy_id_masked; int err; + /* flow control autonegotiation is default behavior */ + tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; + tp->link_config.flowctrl = FLOW_CTRL_TX | FLOW_CTRL_RX; + if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) return tg3_phy_init(tp); @@ -12624,6 +12657,8 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) tp->pci_chip_rev_id != CHIPREV_ID_57765_A0))) tp->phy_flags |= TG3_PHYFLG_EEE_CAP; + tg3_phy_init_link_config(tp); + if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) && !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) && !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { @@ -12679,17 +12714,6 @@ skip_phy_reset: err = tg3_init_5401phy_dsp(tp); } - if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES) - tp->link_config.advertising = - (ADVERTISED_1000baseT_Half | - ADVERTISED_1000baseT_Full | - ADVERTISED_Autoneg | - ADVERTISED_FIBRE); - if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY) - tp->link_config.advertising &= - ~(ADVERTISED_1000baseT_Half | - ADVERTISED_1000baseT_Full); - return err; } @@ -14422,23 +14446,6 @@ out_nofree: return ret; } -static void __devinit tg3_init_link_config(struct tg3 *tp) -{ - tp->link_config.advertising = - (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | - ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full | - ADVERTISED_Autoneg | ADVERTISED_MII); - tp->link_config.speed = SPEED_INVALID; - tp->link_config.duplex = DUPLEX_INVALID; - tp->link_config.autoneg = AUTONEG_ENABLE; - tp->link_config.active_speed = SPEED_INVALID; - tp->link_config.active_duplex = DUPLEX_INVALID; - tp->link_config.orig_speed = SPEED_INVALID; - tp->link_config.orig_duplex = DUPLEX_INVALID; - tp->link_config.orig_autoneg = AUTONEG_INVALID; -} - static void __devinit tg3_init_bufmgr_config(struct tg3 *tp) { if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { @@ -14742,8 +14749,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, goto err_out_free_dev; } - tg3_init_link_config(tp); - tp->rx_pending = TG3_DEF_RX_RING_PENDING; tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING; @@ -14891,10 +14896,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, goto err_out_apeunmap; } - /* flow control autonegotiation is default behavior */ - tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; - tp->link_config.flowctrl = FLOW_CTRL_TX | FLOW_CTRL_RX; - intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW; rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW; sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW; -- cgit v1.2.3 From c5908939b2738bafe1b309bc2465cb9f2e6184c5 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Wed, 9 Mar 2011 16:58:25 +0000 Subject: tg3: Remove 5750 PCI code The 5750 ASIC rev was never released as a PCI device. It only exists as a PCIe device. This patch removes the code that supports the former configuration. Signed-off-by: Matt Carlson Reviewed-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 2c67cc954629..ebec88882c3b 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8193,10 +8193,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) RDMAC_MODE_MBUF_RBD_CRPT_ENAB | RDMAC_MODE_MBUF_SBD_CRPT_ENAB; - /* If statement applies to 5705 and 5750 PCI devices only */ - if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && - tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) || - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && + tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) { if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE && GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { rdmac_mode |= RDMAC_MODE_FIFO_SIZE_128; @@ -8369,17 +8367,14 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) WDMAC_MODE_FIFOURUN_ENAB | WDMAC_MODE_FIFOOREAD_ENAB | WDMAC_MODE_LNGREAD_ENAB); - /* If statement applies to 5705 and 5750 PCI devices only */ - if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && - tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && + tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) { if ((tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) && (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 || tp->pci_chip_rev_id == CHIPREV_ID_5705_A2)) { /* nothing */ } else if (!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) && - !(tp->tg3_flags2 & TG3_FLG2_IS_5788) && - !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) { + !(tp->tg3_flags2 & TG3_FLG2_IS_5788)) { val |= WDMAC_MODE_RX_ACCEL; } } -- cgit v1.2.3 From ae1635b05fae30804061406010914d85d12431ac Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 18 Feb 2011 16:43:27 +0000 Subject: xen: events: do not leak IRQ from xen_allocate_pirq_msi when no pirq available. Cc: Jeremy Fitzhardinge Cc: xen-devel@lists.xensource.com Signed-off-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/events.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 89987a7bf26f..bce303590075 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -676,8 +676,11 @@ void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc) if (alloc & XEN_ALLOC_PIRQ) { *pirq = find_unbound_pirq(MAP_PIRQ_TYPE_MSI); - if (*pirq == -1) + if (*pirq == -1) { + xen_free_irq(*irq); + *irq = -1; goto out; + } } set_irq_chip_and_handler_name(*irq, &xen_pirq_chip, -- cgit v1.2.3 From bb5d079aefa828c292c267ed34ed2282947fa233 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 18 Feb 2011 16:43:28 +0000 Subject: xen: events: drop XEN_ALLOC_IRQ flag to xen_allocate_pirq_msi All callers pass this flag so it is pointless. Signed-off-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/pci/xen.c | 6 +++--- drivers/xen/events.c | 12 +++++------- include/xen/events.h | 5 +---- 3 files changed, 9 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 47c4688dcd48..ca5fa09ca56d 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -101,7 +101,7 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) ((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff); if (xen_irq_from_pirq(pirq) >= 0 && msg.data == XEN_PIRQ_MSI_DATA) { xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ? - "msi-x" : "msi", &irq, &pirq, XEN_ALLOC_IRQ); + "msi-x" : "msi", &irq, &pirq, 0); if (irq < 0) goto error; ret = set_irq_msi(irq, msidesc); @@ -112,7 +112,7 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) return 0; } xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ? - "msi-x" : "msi", &irq, &pirq, (XEN_ALLOC_IRQ | XEN_ALLOC_PIRQ)); + "msi-x" : "msi", &irq, &pirq, 1); if (irq < 0 || pirq < 0) goto error; printk(KERN_DEBUG "xen: msi --> irq=%d, pirq=%d\n", irq, pirq); @@ -160,7 +160,7 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) xen_allocate_pirq_msi( (type == PCI_CAP_ID_MSIX) ? "pcifront-msi-x" : "pcifront-msi", - &irq, &v[i], XEN_ALLOC_IRQ); + &irq, &v[i], 0); if (irq < 0) { ret = -1; goto free; diff --git a/drivers/xen/events.c b/drivers/xen/events.c index bce303590075..36e9adcdebe9 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -664,17 +664,15 @@ static int find_unbound_pirq(int type) return -1; } -void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc) +void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc_pirq) { spin_lock(&irq_mapping_update_lock); - if (alloc & XEN_ALLOC_IRQ) { - *irq = xen_allocate_irq_dynamic(); - if (*irq == -1) - goto out; - } + *irq = xen_allocate_irq_dynamic(); + if (*irq == -1) + goto out; - if (alloc & XEN_ALLOC_PIRQ) { + if (alloc_pirq) { *pirq = find_unbound_pirq(MAP_PIRQ_TYPE_MSI); if (*pirq == -1) { xen_free_irq(*irq); diff --git a/include/xen/events.h b/include/xen/events.h index 00f53ddcc062..8d98861e4d92 100644 --- a/include/xen/events.h +++ b/include/xen/events.h @@ -75,10 +75,7 @@ int xen_allocate_pirq(unsigned gsi, int shareable, char *name); int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name); #ifdef CONFIG_PCI_MSI -/* Allocate an irq and a pirq to be used with MSIs. */ -#define XEN_ALLOC_PIRQ (1 << 0) -#define XEN_ALLOC_IRQ (1 << 1) -void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc_mask); +void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc_pirq); int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type); #endif -- cgit v1.2.3 From 4b41df7f6e0b5684378d9155773c42a4577e8582 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 18 Feb 2011 16:43:29 +0000 Subject: xen: events: return irq from xen_allocate_pirq_msi consistent with other similar functions. Signed-off-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/pci/xen.c | 12 ++++++------ drivers/xen/events.c | 19 +++++++++++-------- include/xen/events.h | 2 +- 3 files changed, 18 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index ca5fa09ca56d..6fd695b06faa 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -100,8 +100,8 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) | ((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff); if (xen_irq_from_pirq(pirq) >= 0 && msg.data == XEN_PIRQ_MSI_DATA) { - xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ? - "msi-x" : "msi", &irq, &pirq, 0); + irq = xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ? + "msi-x" : "msi", &pirq, 0); if (irq < 0) goto error; ret = set_irq_msi(irq, msidesc); @@ -111,8 +111,8 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) " pirq=%d\n", irq, pirq); return 0; } - xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ? - "msi-x" : "msi", &irq, &pirq, 1); + irq = xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ? + "msi-x" : "msi", &pirq, 1); if (irq < 0 || pirq < 0) goto error; printk(KERN_DEBUG "xen: msi --> irq=%d, pirq=%d\n", irq, pirq); @@ -157,10 +157,10 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) goto error; i = 0; list_for_each_entry(msidesc, &dev->msi_list, list) { - xen_allocate_pirq_msi( + irq = xen_allocate_pirq_msi( (type == PCI_CAP_ID_MSIX) ? "pcifront-msi-x" : "pcifront-msi", - &irq, &v[i], 0); + &v[i], 0); if (irq < 0) { ret = -1; goto free; diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 36e9adcdebe9..ed3420df0937 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -664,31 +664,34 @@ static int find_unbound_pirq(int type) return -1; } -void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc_pirq) +int xen_allocate_pirq_msi(char *name, int *pirq, int alloc_pirq) { + int irq; + spin_lock(&irq_mapping_update_lock); - *irq = xen_allocate_irq_dynamic(); - if (*irq == -1) + irq = xen_allocate_irq_dynamic(); + if (irq == -1) goto out; if (alloc_pirq) { *pirq = find_unbound_pirq(MAP_PIRQ_TYPE_MSI); if (*pirq == -1) { - xen_free_irq(*irq); - *irq = -1; + xen_free_irq(irq); + irq = -1; goto out; } } - set_irq_chip_and_handler_name(*irq, &xen_pirq_chip, + set_irq_chip_and_handler_name(irq, &xen_pirq_chip, handle_level_irq, name); - irq_info[*irq] = mk_pirq_info(0, *pirq, 0, 0); - pirq_to_irq[*pirq] = *irq; + irq_info[irq] = mk_pirq_info(0, *pirq, 0, 0); + pirq_to_irq[*pirq] = irq; out: spin_unlock(&irq_mapping_update_lock); + return irq; } int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type) diff --git a/include/xen/events.h b/include/xen/events.h index 8d98861e4d92..f70536af921c 100644 --- a/include/xen/events.h +++ b/include/xen/events.h @@ -75,7 +75,7 @@ int xen_allocate_pirq(unsigned gsi, int shareable, char *name); int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name); #ifdef CONFIG_PCI_MSI -void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc_pirq); +int xen_allocate_pirq_msi(char *name, int *pirq, int alloc_pirq); int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type); #endif -- cgit v1.2.3 From 5cad61a6ba6f4956a218ffbb64cafcc1daefaca0 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 18 Feb 2011 16:43:31 +0000 Subject: xen: events: assume PHYSDEVOP_get_free_pirq exists The find_unbound_pirq is called only from xen_allocate_pirq_msi and only if alloc_pirq is true. The only caller which does this is xen_hvm_setup_msi_irqs. The use of this function is gated, in pci_xen_hvm_init, on XENFEAT_hvm_pirqs. The PHYSDEVOP_get_free_pirq interfaces was added to the hypervisor in 22410:be96f6058c05 while XENFEAT_hvm_pirqs was added a couple of minutes prior in 22409:6663214f06ac. Therefore we do not need to concern ourselves with hypervisors which support XENFEAT_hvm_pirqs but not PHYSDEVOP_get_free_pirq. This eliminates the fallback path in find_unbound_pirq which walks to pirq_to_irq array looking for a free pirq. Unlike the PHYSDEVOP_get_free_pirq interface this fallback only looks up a free pirq but does not reserve it. Removing this fallback will simplify locking in the future. Signed-off-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/events.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index ed3420df0937..c21066fc30be 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -649,19 +649,16 @@ out: static int find_unbound_pirq(int type) { - int rc, i; + int rc; struct physdev_get_free_pirq op_get_free_pirq; - op_get_free_pirq.type = type; + op_get_free_pirq.type = type; rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_free_pirq, &op_get_free_pirq); - if (!rc) - return op_get_free_pirq.pirq; - for (i = 0; i < nr_irqs; i++) { - if (pirq_to_irq[i] < 0) - return i; - } - return -1; + WARN_ONCE(rc == -ENOSYS, + "hypervisor does not support the PHYSDEVOP_get_free_pirq interface\n"); + + return rc ? -1 : op_get_free_pirq.pirq; } int xen_allocate_pirq_msi(char *name, int *pirq, int alloc_pirq) -- cgit v1.2.3 From bf480d952bcf25e8ff7e95d2a23964107513ac51 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 18 Feb 2011 16:43:32 +0000 Subject: xen: events: separate MSI PIRQ allocation from PIRQ binding to IRQ Split the binding aspect of xen_allocate_pirq_msi out into a new xen_bind_pirq_to_irq function. In xen_hvm_setup_msi_irq when allocating a pirq write the MSI message to signal the PIRQ as soon as the pirq is obtained. There is no way to free the pirq back so if the subsequent binding to an IRQ fails we want to ensure that we will reuse the PIRQ next time rather than leak it. Signed-off-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/pci/xen.c | 68 ++++++++++++++++++++-------------------------------- drivers/xen/events.c | 30 +++++++++++------------ include/xen/events.h | 4 +++- 3 files changed, 43 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 0d5087eeced8..93e42152d8d0 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -86,7 +86,7 @@ static void xen_msi_compose_msg(struct pci_dev *pdev, unsigned int pirq, static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) { - int irq, pirq, ret = 0; + int irq, pirq; struct msi_desc *msidesc; struct msi_msg msg; @@ -94,39 +94,32 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) __read_msi_msg(msidesc, &msg); pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) | ((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff); - if (xen_irq_from_pirq(pirq) >= 0 && msg.data == XEN_PIRQ_MSI_DATA) { - irq = xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ? - "msi-x" : "msi", &pirq, 0); - if (irq < 0) + if (msg.data != XEN_PIRQ_MSI_DATA || + xen_irq_from_pirq(pirq) < 0) { + pirq = xen_allocate_pirq_msi(dev, msidesc); + if (pirq < 0) goto error; - ret = set_irq_msi(irq, msidesc); - if (ret < 0) - goto error_while; - printk(KERN_DEBUG "xen: msi already setup: msi --> irq=%d" - " pirq=%d\n", irq, pirq); - return 0; + xen_msi_compose_msg(dev, pirq, &msg); + __write_msi_msg(msidesc, &msg); + dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq); + } else { + dev_dbg(&dev->dev, + "xen: msi already bound to pirq=%d\n", pirq); } - irq = xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ? - "msi-x" : "msi", &pirq, 1); - if (irq < 0 || pirq < 0) + irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq, + (type == PCI_CAP_ID_MSIX) ? + "msi-x" : "msi"); + if (irq < 0) goto error; - printk(KERN_DEBUG "xen: msi --> irq=%d, pirq=%d\n", irq, pirq); - xen_msi_compose_msg(dev, pirq, &msg); - ret = set_irq_msi(irq, msidesc); - if (ret < 0) - goto error_while; - write_msi_msg(irq, &msg); + dev_dbg(&dev->dev, + "xen: msi --> pirq=%d --> irq=%d\n", pirq, irq); } return 0; -error_while: - unbind_from_irqhandler(irq, NULL); error: - if (ret == -ENODEV) - dev_err(&dev->dev, "Xen PCI frontend has not registered" \ - " MSI/MSI-X support!\n"); - - return ret; + dev_err(&dev->dev, + "Xen PCI frontend has not registered MSI/MSI-X support!\n"); + return -ENODEV; } /* @@ -152,28 +145,19 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) goto error; i = 0; list_for_each_entry(msidesc, &dev->msi_list, list) { - irq = xen_allocate_pirq_msi( - (type == PCI_CAP_ID_MSIX) ? - "pcifront-msi-x" : "pcifront-msi", - &v[i], 0); - if (irq < 0) { - ret = -1; + irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], + (type == PCI_CAP_ID_MSIX) ? + "pcifront-msi-x" : + "pcifront-msi"); + if (irq < 0) goto free; - } - ret = set_irq_msi(irq, msidesc); - if (ret) - goto error_while; i++; } kfree(v); return 0; -error_while: - unbind_from_irqhandler(irq, NULL); error: - if (ret == -ENODEV) - dev_err(&dev->dev, "Xen PCI frontend has not registered" \ - " MSI/MSI-X support!\n"); + dev_err(&dev->dev, "Xen PCI frontend has not registered MSI/MSI-X support!\n"); free: kfree(v); return ret; diff --git a/drivers/xen/events.c b/drivers/xen/events.c index c21066fc30be..1033f6284f31 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -647,12 +647,12 @@ out: #include #include "../pci/msi.h" -static int find_unbound_pirq(int type) +int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc) { int rc; struct physdev_get_free_pirq op_get_free_pirq; - op_get_free_pirq.type = type; + op_get_free_pirq.type = MAP_PIRQ_TYPE_MSI; rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_free_pirq, &op_get_free_pirq); WARN_ONCE(rc == -ENOSYS, @@ -661,9 +661,10 @@ static int find_unbound_pirq(int type) return rc ? -1 : op_get_free_pirq.pirq; } -int xen_allocate_pirq_msi(char *name, int *pirq, int alloc_pirq) +int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, + int pirq, const char *name) { - int irq; + int irq, ret; spin_lock(&irq_mapping_update_lock); @@ -671,24 +672,21 @@ int xen_allocate_pirq_msi(char *name, int *pirq, int alloc_pirq) if (irq == -1) goto out; - if (alloc_pirq) { - *pirq = find_unbound_pirq(MAP_PIRQ_TYPE_MSI); - if (*pirq == -1) { - xen_free_irq(irq); - irq = -1; - goto out; - } - } - set_irq_chip_and_handler_name(irq, &xen_pirq_chip, handle_level_irq, name); - irq_info[irq] = mk_pirq_info(0, *pirq, 0, 0); - pirq_to_irq[*pirq] = irq; - + irq_info[irq] = mk_pirq_info(0, pirq, 0, 0); + pirq_to_irq[pirq] = irq; + ret = set_irq_msi(irq, msidesc); + if (ret < 0) + goto error_irq; out: spin_unlock(&irq_mapping_update_lock); return irq; +error_irq: + spin_unlock(&irq_mapping_update_lock); + xen_free_irq(irq); + return -1; } int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type) diff --git a/include/xen/events.h b/include/xen/events.h index f70536af921c..18bf825bac66 100644 --- a/include/xen/events.h +++ b/include/xen/events.h @@ -75,7 +75,9 @@ int xen_allocate_pirq(unsigned gsi, int shareable, char *name); int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name); #ifdef CONFIG_PCI_MSI -int xen_allocate_pirq_msi(char *name, int *pirq, int alloc_pirq); +int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc); +int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, + int pirq, const char *name); int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type); #endif -- cgit v1.2.3 From 8135591e90c81462a6902f6ffa1f1ca021db077a Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 18 Feb 2011 16:43:33 +0000 Subject: xen: events: refactor xen_create_msi_irq slightly Calling PHYSDEVOP_map_pirq earlier simplifies error handling and starts to make the tail end of this function look like xen_bind_pirq_msi_to_irq. Signed-off-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/events.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 1033f6284f31..b54285e27b3b 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -716,6 +716,12 @@ int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type) map_irq.entry_nr = msidesc->msi_attrib.entry_nr; } + rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); + if (rc) { + dev_warn(&dev->dev, "xen map irq failed %d\n", rc); + goto out; + } + spin_lock(&irq_mapping_update_lock); irq = xen_allocate_irq_dynamic(); @@ -723,15 +729,6 @@ int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type) if (irq == -1) goto out; - rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); - if (rc) { - printk(KERN_WARNING "xen map irq failed %d\n", rc); - - xen_free_irq(irq); - - irq = -1; - goto out; - } irq_info[irq] = mk_pirq_info(0, map_irq.pirq, 0, map_irq.index); set_irq_chip_and_handler_name(irq, &xen_pirq_chip, -- cgit v1.2.3 From 2e55288f63343f0810f4f0a3004f78037cfb93d3 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 18 Feb 2011 16:43:34 +0000 Subject: xen: events: update pirq_to_irq in xen_create_msi_irq I don't think this was a deliberate ommision. Makes the tail end of this function look even more like xen_bind_pirq_msi_to_irq. Signed-off-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/events.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index b54285e27b3b..721b393fd8aa 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -730,6 +730,7 @@ int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type) goto out; irq_info[irq] = mk_pirq_info(0, map_irq.pirq, 0, map_irq.index); + pirq_to_irq[map_irq.pirq] = irq; set_irq_chip_and_handler_name(irq, &xen_pirq_chip, handle_level_irq, -- cgit v1.2.3 From f420e010edd84eb2c237fc87b7451e69740fed46 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 18 Feb 2011 16:43:35 +0000 Subject: xen: events: push set_irq_msi down into xen_create_msi_irq Makes the tail end of this function look even more like xen_bind_pirq_msi_to_irq. Signed-off-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/pci/xen.c | 10 +--------- drivers/xen/events.c | 10 +++++++++- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 93e42152d8d0..15fd981d35f1 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -185,23 +185,15 @@ static void xen_teardown_msi_irq(unsigned int irq) #ifdef CONFIG_XEN_DOM0 static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) { - int irq, ret; + int irq; struct msi_desc *msidesc; list_for_each_entry(msidesc, &dev->msi_list, list) { irq = xen_create_msi_irq(dev, msidesc, type); if (irq < 0) return -1; - - ret = set_irq_msi(irq, msidesc); - if (ret) - goto error; } return 0; - -error: - xen_destroy_irq(irq); - return ret; } #endif #endif diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 721b393fd8aa..77ede77a9ee9 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -691,7 +691,7 @@ error_irq: int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type) { - int irq = -1; + int ret, irq = -1; struct physdev_map_pirq map_irq; int rc; int pos; @@ -736,9 +736,17 @@ int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type) handle_level_irq, (type == PCI_CAP_ID_MSIX) ? "msi-x":"msi"); + ret = set_irq_msi(irq, msidesc); + if (ret) + goto out_irq; + out: spin_unlock(&irq_mapping_update_lock); return irq; +out_irq: + spin_unlock(&irq_mapping_update_lock); + xen_free_irq(irq); + return -1; } #endif -- cgit v1.2.3 From ca1d8fe9521fb67c95cfa736c08f4bbbc282b5bd Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 18 Feb 2011 16:43:36 +0000 Subject: xen: events: use xen_bind_pirq_msi_to_irq from xen_create_msi_irq Signed-off-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/pci/xen.c | 4 ++-- drivers/xen/events.c | 36 +++++++----------------------------- include/xen/events.h | 2 +- 3 files changed, 10 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 15fd981d35f1..ffd8c7a2cdbb 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -106,7 +106,7 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) dev_dbg(&dev->dev, "xen: msi already bound to pirq=%d\n", pirq); } - irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq, + irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq, 0, (type == PCI_CAP_ID_MSIX) ? "msi-x" : "msi"); if (irq < 0) @@ -145,7 +145,7 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) goto error; i = 0; list_for_each_entry(msidesc, &dev->msi_list, list) { - irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], + irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], 0, (type == PCI_CAP_ID_MSIX) ? "pcifront-msi-x" : "pcifront-msi"); diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 77ede77a9ee9..34469489087b 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -662,7 +662,7 @@ int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc) } int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, - int pirq, const char *name) + int pirq, int vector, const char *name) { int irq, ret; @@ -675,7 +675,7 @@ int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, set_irq_chip_and_handler_name(irq, &xen_pirq_chip, handle_level_irq, name); - irq_info[irq] = mk_pirq_info(0, pirq, 0, 0); + irq_info[irq] = mk_pirq_info(0, pirq, 0, vector); pirq_to_irq[pirq] = irq; ret = set_irq_msi(irq, msidesc); if (ret < 0) @@ -691,7 +691,6 @@ error_irq: int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type) { - int ret, irq = -1; struct physdev_map_pirq map_irq; int rc; int pos; @@ -719,34 +718,13 @@ int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type) rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); if (rc) { dev_warn(&dev->dev, "xen map irq failed %d\n", rc); - goto out; + return -1; } - spin_lock(&irq_mapping_update_lock); - - irq = xen_allocate_irq_dynamic(); - - if (irq == -1) - goto out; - - irq_info[irq] = mk_pirq_info(0, map_irq.pirq, 0, map_irq.index); - pirq_to_irq[map_irq.pirq] = irq; - - set_irq_chip_and_handler_name(irq, &xen_pirq_chip, - handle_level_irq, - (type == PCI_CAP_ID_MSIX) ? "msi-x":"msi"); - - ret = set_irq_msi(irq, msidesc); - if (ret) - goto out_irq; - -out: - spin_unlock(&irq_mapping_update_lock); - return irq; -out_irq: - spin_unlock(&irq_mapping_update_lock); - xen_free_irq(irq); - return -1; + return xen_bind_pirq_msi_to_irq(dev, msidesc, + map_irq.pirq, map_irq.index, + (type == PCI_CAP_ID_MSIX) ? + "msi-x" : "msi"); } #endif diff --git a/include/xen/events.h b/include/xen/events.h index 18bf825bac66..45c08a0d580a 100644 --- a/include/xen/events.h +++ b/include/xen/events.h @@ -77,7 +77,7 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name); #ifdef CONFIG_PCI_MSI int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc); int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, - int pirq, const char *name); + int pirq, int vector, const char *name); int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type); #endif -- cgit v1.2.3 From 71eef7d1e3d9df760897fdd2cad6949a8bcf1620 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 18 Feb 2011 17:06:55 +0000 Subject: xen: events: remove dom0 specific xen_create_msi_irq The function name does not distinguish it from xen_allocate_pirq_msi (which operates on domU and pvhvm domains rather than dom0). Hoist domain 0 specific functionality up into the only caller leaving functionality common to all guest types in xen_bind_pirq_msi_to_irq. Signed-off-by: Ian Campbell Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/pci/xen.c | 45 ++++++++++++++++++++++++++++++++++++++++----- drivers/xen/events.c | 41 ----------------------------------------- include/xen/events.h | 1 - 3 files changed, 40 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index ffd8c7a2cdbb..8c4085a95ef1 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -185,15 +185,50 @@ static void xen_teardown_msi_irq(unsigned int irq) #ifdef CONFIG_XEN_DOM0 static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) { - int irq; + int ret = 0; struct msi_desc *msidesc; list_for_each_entry(msidesc, &dev->msi_list, list) { - irq = xen_create_msi_irq(dev, msidesc, type); - if (irq < 0) - return -1; + struct physdev_map_pirq map_irq; + + memset(&map_irq, 0, sizeof(map_irq)); + map_irq.domid = DOMID_SELF; + map_irq.type = MAP_PIRQ_TYPE_MSI; + map_irq.index = -1; + map_irq.pirq = -1; + map_irq.bus = dev->bus->number; + map_irq.devfn = dev->devfn; + + if (type == PCI_CAP_ID_MSIX) { + int pos; + u32 table_offset, bir; + + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); + + pci_read_config_dword(dev, pos + PCI_MSIX_TABLE, + &table_offset); + bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); + + map_irq.table_base = pci_resource_start(dev, bir); + map_irq.entry_nr = msidesc->msi_attrib.entry_nr; + } + + ret = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); + if (ret) { + dev_warn(&dev->dev, "xen map irq failed %d\n", ret); + goto out; + } + + ret = xen_bind_pirq_msi_to_irq(dev, msidesc, + map_irq.pirq, map_irq.index, + (type == PCI_CAP_ID_MSIX) ? + "msi-x" : "msi"); + if (ret < 0) + goto out; } - return 0; + ret = 0; +out: + return ret; } #endif #endif diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 34469489087b..6befe6227159 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -644,9 +644,6 @@ out: } #ifdef CONFIG_PCI_MSI -#include -#include "../pci/msi.h" - int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc) { int rc; @@ -688,44 +685,6 @@ error_irq: xen_free_irq(irq); return -1; } - -int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type) -{ - struct physdev_map_pirq map_irq; - int rc; - int pos; - u32 table_offset, bir; - - memset(&map_irq, 0, sizeof(map_irq)); - map_irq.domid = DOMID_SELF; - map_irq.type = MAP_PIRQ_TYPE_MSI; - map_irq.index = -1; - map_irq.pirq = -1; - map_irq.bus = dev->bus->number; - map_irq.devfn = dev->devfn; - - if (type == PCI_CAP_ID_MSIX) { - pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); - - pci_read_config_dword(dev, msix_table_offset_reg(pos), - &table_offset); - bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); - - map_irq.table_base = pci_resource_start(dev, bir); - map_irq.entry_nr = msidesc->msi_attrib.entry_nr; - } - - rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); - if (rc) { - dev_warn(&dev->dev, "xen map irq failed %d\n", rc); - return -1; - } - - return xen_bind_pirq_msi_to_irq(dev, msidesc, - map_irq.pirq, map_irq.index, - (type == PCI_CAP_ID_MSIX) ? - "msi-x" : "msi"); -} #endif int xen_destroy_irq(int irq) diff --git a/include/xen/events.h b/include/xen/events.h index 45c08a0d580a..962da2ced5b4 100644 --- a/include/xen/events.h +++ b/include/xen/events.h @@ -78,7 +78,6 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name); int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc); int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, int pirq, int vector, const char *name); -int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type); #endif /* De-allocates the above mentioned physical interrupt. */ -- cgit v1.2.3 From ba3820ade317ee36e496b9b40d2ec3987dd4aef0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 10 Mar 2011 14:02:12 +0100 Subject: drm/i915: Revive combination mode for backlight control This reverts commit 951f3512dba5bd44cda3e5ee22b4b522e4bb09fb drm/i915: Do not handle backlight combination mode specially since this commit introduced other regressions due to untouched LBPC register, e.g. the backlight dimmed after resume. In addition to the revert, this patch includes a fix for the original issue (weird backlight levels) by removing the wrong bit shift for computing the current backlight level. Also, including typo fixes (lpbc -> lbpc). Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=34524 Acked-by: Indan Zupancic Reviewed-by: Keith Packard Reviewed-by: Jesse Barnes Cc: Signed-off-by: Takashi Iwai Signed-off-by: Linus Torvalds --- drivers/gpu/drm/i915/i915_reg.h | 10 ++++++++++ drivers/gpu/drm/i915/intel_panel.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 3e6f486f4605..2abe240dae58 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1553,7 +1553,17 @@ /* Backlight control */ #define BLC_PWM_CTL 0x61254 +#define BACKLIGHT_MODULATION_FREQ_SHIFT (17) #define BLC_PWM_CTL2 0x61250 /* 965+ only */ +#define BLM_COMBINATION_MODE (1 << 30) +/* + * This is the most significant 15 bits of the number of backlight cycles in a + * complete cycle of the modulated backlight control. + * + * The actual value is this field multiplied by two. + */ +#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) +#define BLM_LEGACY_MODE (1 << 16) /* * This is the number of cycles out of the backlight modulation cycle for which * the backlight is on. diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index d860abeda70f..f8f86e57df22 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -30,6 +30,8 @@ #include "intel_drv.h" +#define PCI_LBPC 0xf4 /* legacy/combination backlight modes */ + void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, struct drm_display_mode *adjusted_mode) @@ -110,6 +112,19 @@ done: dev_priv->pch_pf_size = (width << 16) | height; } +static int is_backlight_combination_mode(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (INTEL_INFO(dev)->gen >= 4) + return I915_READ(BLC_PWM_CTL2) & BLM_COMBINATION_MODE; + + if (IS_GEN2(dev)) + return I915_READ(BLC_PWM_CTL) & BLM_LEGACY_MODE; + + return 0; +} + static u32 i915_read_blc_pwm_ctl(struct drm_i915_private *dev_priv) { u32 val; @@ -166,6 +181,9 @@ u32 intel_panel_get_max_backlight(struct drm_device *dev) if (INTEL_INFO(dev)->gen < 4) max &= ~1; } + + if (is_backlight_combination_mode(dev)) + max *= 0xff; } DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max); @@ -183,6 +201,14 @@ u32 intel_panel_get_backlight(struct drm_device *dev) val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; if (IS_PINEVIEW(dev)) val >>= 1; + + if (is_backlight_combination_mode(dev)){ + u8 lbpc; + + val &= ~1; + pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc); + val *= lbpc; + } } DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val); @@ -205,6 +231,16 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level) if (HAS_PCH_SPLIT(dev)) return intel_pch_panel_set_backlight(dev, level); + + if (is_backlight_combination_mode(dev)){ + u32 max = intel_panel_get_max_backlight(dev); + u8 lbpc; + + lbpc = level * 0xfe / max + 1; + level /= lbpc; + pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc); + } + tmp = I915_READ(BLC_PWM_CTL); if (IS_PINEVIEW(dev)) { tmp &= ~(BACKLIGHT_DUTY_CYCLE_MASK - 1); -- cgit v1.2.3 From 4c418ba9695a24917a1fcfa48f7db3fd76337eb7 Mon Sep 17 00:00:00 2001 From: "Doe, YiCheng" Date: Thu, 10 Mar 2011 14:00:21 -0600 Subject: ipmi: Fix IPMI errors due to timing problems This patch fixes an issue in OpenIPMI module where sometimes an ABORT command is sent after sending an IPMI request to BMC causing the IPMI request to fail. Signed-off-by: YiCheng Doe Signed-off-by: Corey Minyard Acked-by: Tom Mingarelli Tested-by: Andy Cress Tested-by: Mika Lansirine Tested-by: Brian De Wolf Cc: Jean Michel Audet Cc: Jozef Sudelsky Acked-by: Matthew Garrett Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 7855f9f45b8e..62787e30d508 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -900,6 +900,14 @@ static void sender(void *send_info, printk("**Enqueue: %d.%9.9d\n", t.tv_sec, t.tv_usec); #endif + /* + * last_timeout_jiffies is updated here to avoid + * smi_timeout() handler passing very large time_diff + * value to smi_event_handler() that causes + * the send command to abort. + */ + smi_info->last_timeout_jiffies = jiffies; + mod_timer(&smi_info->si_timer, jiffies + SI_TIMEOUT_JIFFIES); if (smi_info->thread) -- cgit v1.2.3 From 75c0fd93c7d42362134e74fd381072a7642fcc3d Mon Sep 17 00:00:00 2001 From: "j223yang@asset.uwaterloo.ca" Date: Thu, 10 Mar 2011 12:36:37 +0000 Subject: ariadne: remove redundant NULL check Simply remove redundant 'dev' NULL check. Signed-off-by: Jinqiu Yang Signed-off-by: David S. Miller --- drivers/net/ariadne.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c index 39214e512452..7ca0eded2561 100644 --- a/drivers/net/ariadne.c +++ b/drivers/net/ariadne.c @@ -425,11 +425,6 @@ static irqreturn_t ariadne_interrupt(int irq, void *data) int csr0, boguscnt; int handled = 0; - if (dev == NULL) { - printk(KERN_WARNING "ariadne_interrupt(): irq for unknown device.\n"); - return IRQ_NONE; - } - lance->RAP = CSR0; /* PCnet-ISA Controller Status */ if (!(lance->RDP & INTR)) /* Check if any interrupt has been */ -- cgit v1.2.3 From fdc315a19a2c33da29dd87d4ca88f4e4407bd42d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 11 Mar 2011 10:04:23 +1000 Subject: drm/radeon: add pageflip hooks for fusion Looks like these got passed over with both being merged at the same time but not quite meeting in the middle. should fix: https://bugs.freedesktop.org/show_bug.cgi?id=34137 along with Michael's phoronix article. Reported-by: Chi-Thanh Christopher Nguyen Article-written-by: Michael Larabel @ phoronix Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_asic.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index e75d63b8e21d..793c5e6026ad 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -834,6 +834,9 @@ static struct radeon_asic sumo_asic = { .pm_finish = &evergreen_pm_finish, .pm_init_profile = &rs780_pm_init_profile, .pm_get_dynpm_state = &r600_pm_get_dynpm_state, + .pre_page_flip = &evergreen_pre_page_flip, + .page_flip = &evergreen_page_flip, + .post_page_flip = &evergreen_post_page_flip, }; static struct radeon_asic btc_asic = { -- cgit v1.2.3 From e2444d92083cc1ceb07487425897d6d51a13e9dd Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Thu, 27 Jan 2011 09:14:18 +0000 Subject: ixgb: convert to new VLAN model Based on a patch from Jesse Gross This switches the ixgb driver to use the new VLAN interfaces. In doing this, it completes the work begun in ae54496f9e8d40c89e5668205c181dccfa9ecda1 allowing the use of hardware VLAN insertion without having a VLAN group configured. CC: Jesse Gross Signed-off-by: Emil Tantilov Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/ixgb/ixgb.h | 2 +- drivers/net/ixgb/ixgb_ethtool.c | 39 +++++++++++++++++++++++++++++ drivers/net/ixgb/ixgb_main.c | 54 +++++++++-------------------------------- 3 files changed, 52 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h index 521c0c732998..8f3df044e81e 100644 --- a/drivers/net/ixgb/ixgb.h +++ b/drivers/net/ixgb/ixgb.h @@ -149,7 +149,7 @@ struct ixgb_desc_ring { struct ixgb_adapter { struct timer_list watchdog_timer; - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; u32 bd_number; u32 rx_buffer_len; u32 part_num; diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c index 43994c199991..cc53aa1541ba 100644 --- a/drivers/net/ixgb/ixgb_ethtool.c +++ b/drivers/net/ixgb/ixgb_ethtool.c @@ -706,6 +706,43 @@ ixgb_get_strings(struct net_device *netdev, u32 stringset, u8 *data) } } +static int ixgb_set_flags(struct net_device *netdev, u32 data) +{ + struct ixgb_adapter *adapter = netdev_priv(netdev); + bool need_reset; + int rc; + + /* + * Tx VLAN insertion does not work per HW design when Rx stripping is + * disabled. Disable txvlan when rxvlan is turned off, and enable + * rxvlan when txvlan is turned on. + */ + if (!(data & ETH_FLAG_RXVLAN) && + (netdev->features & NETIF_F_HW_VLAN_TX)) + data &= ~ETH_FLAG_TXVLAN; + else if (data & ETH_FLAG_TXVLAN) + data |= ETH_FLAG_RXVLAN; + + need_reset = (data & ETH_FLAG_RXVLAN) != + (netdev->features & NETIF_F_HW_VLAN_RX); + + rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_RXVLAN | + ETH_FLAG_TXVLAN); + if (rc) + return rc; + + if (need_reset) { + if (netif_running(netdev)) { + ixgb_down(adapter, true); + ixgb_up(adapter); + ixgb_set_speed_duplex(netdev); + } else + ixgb_reset(adapter); + } + + return 0; +} + static const struct ethtool_ops ixgb_ethtool_ops = { .get_settings = ixgb_get_settings, .set_settings = ixgb_set_settings, @@ -732,6 +769,8 @@ static const struct ethtool_ops ixgb_ethtool_ops = { .phys_id = ixgb_phys_id, .get_sset_count = ixgb_get_sset_count, .get_ethtool_stats = ixgb_get_ethtool_stats, + .get_flags = ethtool_op_get_flags, + .set_flags = ixgb_set_flags, }; void ixgb_set_ethtool_ops(struct net_device *netdev) diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 5639cccb4935..0f681ac2da8d 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -100,8 +100,6 @@ static void ixgb_tx_timeout_task(struct work_struct *work); static void ixgb_vlan_strip_enable(struct ixgb_adapter *adapter); static void ixgb_vlan_strip_disable(struct ixgb_adapter *adapter); -static void ixgb_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp); static void ixgb_vlan_rx_add_vid(struct net_device *netdev, u16 vid); static void ixgb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid); static void ixgb_restore_vlan(struct ixgb_adapter *adapter); @@ -336,7 +334,6 @@ static const struct net_device_ops ixgb_netdev_ops = { .ndo_set_mac_address = ixgb_set_mac, .ndo_change_mtu = ixgb_change_mtu, .ndo_tx_timeout = ixgb_tx_timeout, - .ndo_vlan_rx_register = ixgb_vlan_rx_register, .ndo_vlan_rx_add_vid = ixgb_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = ixgb_vlan_rx_kill_vid, #ifdef CONFIG_NET_POLL_CONTROLLER @@ -1508,7 +1505,7 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev) DESC_NEEDED))) return NETDEV_TX_BUSY; - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { tx_flags |= IXGB_TX_FLAGS_VLAN; vlan_id = vlan_tx_tag_get(skb); } @@ -2049,12 +2046,11 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter, int *work_done, int work_to_do) ixgb_rx_checksum(adapter, rx_desc, skb); skb->protocol = eth_type_trans(skb, netdev); - if (adapter->vlgrp && (status & IXGB_RX_DESC_STATUS_VP)) { - vlan_hwaccel_receive_skb(skb, adapter->vlgrp, - le16_to_cpu(rx_desc->special)); - } else { - netif_receive_skb(skb); - } + if (status & IXGB_RX_DESC_STATUS_VP) + __vlan_hwaccel_put_tag(skb, + le16_to_cpu(rx_desc->special)); + + netif_receive_skb(skb); rxdesc_done: /* clean up descriptor, might be written over by hw */ @@ -2152,20 +2148,6 @@ map_skb: } } -/** - * ixgb_vlan_rx_register - enables or disables vlan tagging/stripping. - * - * @param netdev network interface device structure - * @param grp indicates to enable or disable tagging/stripping - **/ -static void -ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) -{ - struct ixgb_adapter *adapter = netdev_priv(netdev); - - adapter->vlgrp = grp; -} - static void ixgb_vlan_strip_enable(struct ixgb_adapter *adapter) { @@ -2200,6 +2182,7 @@ ixgb_vlan_rx_add_vid(struct net_device *netdev, u16 vid) vfta = IXGB_READ_REG_ARRAY(&adapter->hw, VFTA, index); vfta |= (1 << (vid & 0x1F)); ixgb_write_vfta(&adapter->hw, index, vfta); + set_bit(vid, adapter->active_vlans); } static void @@ -2208,35 +2191,22 @@ ixgb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) struct ixgb_adapter *adapter = netdev_priv(netdev); u32 vfta, index; - ixgb_irq_disable(adapter); - - vlan_group_set_device(adapter->vlgrp, vid, NULL); - - /* don't enable interrupts unless we are UP */ - if (adapter->netdev->flags & IFF_UP) - ixgb_irq_enable(adapter); - /* remove VID from filter table */ index = (vid >> 5) & 0x7F; vfta = IXGB_READ_REG_ARRAY(&adapter->hw, VFTA, index); vfta &= ~(1 << (vid & 0x1F)); ixgb_write_vfta(&adapter->hw, index, vfta); + clear_bit(vid, adapter->active_vlans); } static void ixgb_restore_vlan(struct ixgb_adapter *adapter) { - ixgb_vlan_rx_register(adapter->netdev, adapter->vlgrp); - - if (adapter->vlgrp) { - u16 vid; - for (vid = 0; vid < VLAN_N_VID; vid++) { - if (!vlan_group_get_device(adapter->vlgrp, vid)) - continue; - ixgb_vlan_rx_add_vid(adapter->netdev, vid); - } - } + u16 vid; + + for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) + ixgb_vlan_rx_add_vid(adapter->netdev, vid); } #ifdef CONFIG_NET_POLL_CONTROLLER -- cgit v1.2.3 From 23633b13ff7e1e1380bd2e11c49eb5ddbdf37ea9 Mon Sep 17 00:00:00 2001 From: Lior Levy Date: Wed, 2 Mar 2011 06:42:37 +0000 Subject: ixgbevf: remove Tx hang detection Removed Tx hang detection mechanism from ixgbevf. This mechanism has no affect and can cause false alarm messages in some cases. Especially when VF Tx rate limit is turned on. The same mechanism was removed recently from igbvf. Signed-off-by: Lior Levy Signed-off-by: Jeff Kirsher --- drivers/net/ixgbevf/ixgbevf.h | 1 - drivers/net/ixgbevf/ixgbevf_main.c | 50 -------------------------------------- 2 files changed, 51 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbevf/ixgbevf.h b/drivers/net/ixgbevf/ixgbevf.h index a63efcb2cf1b..b703f60be3b7 100644 --- a/drivers/net/ixgbevf/ixgbevf.h +++ b/drivers/net/ixgbevf/ixgbevf.h @@ -207,7 +207,6 @@ struct ixgbevf_adapter { u64 hw_tso_ctxt; u64 hw_tso6_ctxt; u32 tx_timeout_count; - bool detect_tx_hung; /* RX */ struct ixgbevf_ring *rx_ring; /* One per active queue */ diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 82768812552d..c1fb2c1b540e 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -162,40 +162,6 @@ static void ixgbevf_unmap_and_free_tx_resource(struct ixgbevf_adapter *adapter, /* tx_buffer_info must be completely set up in the transmit path */ } -static inline bool ixgbevf_check_tx_hang(struct ixgbevf_adapter *adapter, - struct ixgbevf_ring *tx_ring, - unsigned int eop) -{ - struct ixgbe_hw *hw = &adapter->hw; - u32 head, tail; - - /* Detect a transmit hang in hardware, this serializes the - * check with the clearing of time_stamp and movement of eop */ - head = readl(hw->hw_addr + tx_ring->head); - tail = readl(hw->hw_addr + tx_ring->tail); - adapter->detect_tx_hung = false; - if ((head != tail) && - tx_ring->tx_buffer_info[eop].time_stamp && - time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ)) { - /* detected Tx unit hang */ - printk(KERN_ERR "Detected Tx Unit Hang\n" - " Tx Queue <%d>\n" - " TDH, TDT <%x>, <%x>\n" - " next_to_use <%x>\n" - " next_to_clean <%x>\n" - "tx_buffer_info[next_to_clean]\n" - " time_stamp <%lx>\n" - " jiffies <%lx>\n", - tx_ring->queue_index, - head, tail, - tx_ring->next_to_use, eop, - tx_ring->tx_buffer_info[eop].time_stamp, jiffies); - return true; - } - - return false; -} - #define IXGBE_MAX_TXD_PWR 14 #define IXGBE_MAX_DATA_PER_TXD (1 << IXGBE_MAX_TXD_PWR) @@ -291,16 +257,6 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_adapter *adapter, #endif } - if (adapter->detect_tx_hung) { - if (ixgbevf_check_tx_hang(adapter, tx_ring, i)) { - /* schedule immediate reset if we believe we hung */ - printk(KERN_INFO - "tx hang %d detected, resetting adapter\n", - adapter->tx_timeout_count + 1); - ixgbevf_tx_timeout(adapter->netdev); - } - } - /* re-arm the interrupt */ if ((count >= tx_ring->work_limit) && (!test_bit(__IXGBEVF_DOWN, &adapter->state))) { @@ -2412,9 +2368,6 @@ static void ixgbevf_watchdog_task(struct work_struct *work) 10 : 1); netif_carrier_on(netdev); netif_tx_wake_all_queues(netdev); - } else { - /* Force detection of hung controller */ - adapter->detect_tx_hung = true; } } else { adapter->link_up = false; @@ -2429,9 +2382,6 @@ static void ixgbevf_watchdog_task(struct work_struct *work) ixgbevf_update_stats(adapter); pf_has_reset: - /* Force detection of hung controller every watchdog period */ - adapter->detect_tx_hung = true; - /* Reset the timer */ if (!test_bit(__IXGBEVF_DOWN, &adapter->state)) mod_timer(&adapter->watchdog_timer, -- cgit v1.2.3 From ef5ab89cf7edc2e2cb996d62201a2b356d5e9286 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Thu, 10 Feb 2011 08:17:21 +0000 Subject: e1000e: use dev_kfree_skb_irq() instead of dev_kfree_skb() Based on a report and patch originally submitted by Prasanna Panchamukhi. Use dev_kfree_skb_irq() in e1000_clean_jumbo_rx_irq() since this latter function is called only in interrupt context. This avoids "Warning: kfree_skb on hard IRQ" messages. Cc: "Prasanna S. Panchamukhi" Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/netdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 455d5a1101ed..c43cdfee6b1b 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -1322,7 +1322,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, /* an error means any chain goes out the window * too */ if (rx_ring->rx_skb_top) - dev_kfree_skb(rx_ring->rx_skb_top); + dev_kfree_skb_irq(rx_ring->rx_skb_top); rx_ring->rx_skb_top = NULL; goto next_desc; } @@ -1395,7 +1395,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, /* eth type trans needs skb->data to point to something */ if (!pskb_may_pull(skb, ETH_HLEN)) { e_err("pskb_may_pull failed.\n"); - dev_kfree_skb(skb); + dev_kfree_skb_irq(skb); goto next_desc; } -- cgit v1.2.3 From d8d5f8aebb857f979fbe9099c9acc2ed486706be Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 25 Feb 2011 07:09:37 +0000 Subject: e1000e: magic number cleanup - ETH_ALEN Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/hw.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index bc0860a598c9..307e1ec22417 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h @@ -812,9 +812,8 @@ struct e1000_nvm_operations { struct e1000_mac_info { struct e1000_mac_operations ops; - - u8 addr[6]; - u8 perm_addr[6]; + u8 addr[ETH_ALEN]; + u8 perm_addr[ETH_ALEN]; enum e1000_mac_type type; -- cgit v1.2.3 From 5661aeb08edcef6799861f92817f593c1fd7b272 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 25 Feb 2011 06:36:25 +0000 Subject: e1000e: extend timeout for ethtool link test diagnostic With some PHYs supported by this driver, link establishment can take a little longer when connected to certain switches. Extend the timeout to reduce the number of false diagnostic failures, and cleanup a code style issue in the same function. Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/ethtool.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index d4e51aa231b9..8e276dc4b848 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -1666,10 +1666,13 @@ static int e1000_link_test(struct e1000_adapter *adapter, u64 *data) } else { hw->mac.ops.check_for_link(hw); if (hw->mac.autoneg) - msleep(4000); + /* + * On some Phy/switch combinations, link establishment + * can take a few seconds more than expected. + */ + msleep(5000); - if (!(er32(STATUS) & - E1000_STATUS_LU)) + if (!(er32(STATUS) & E1000_STATUS_LU)) *data = 1; } return *data; -- cgit v1.2.3 From 1effb45cca29e22e4b2209bb567770b7e20a3a2b Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 25 Feb 2011 06:58:03 +0000 Subject: e1000e: extend EEE LPI timer to prevent dropped link The link can be unexpectedly dropped when the timer for entering EEE low- power-idle quiet state expires too soon. The timer needs to be extended from 196usec to 200usec after every LCD (PHY) reset to prevent this from happening. Signed-off-by: Bruce Allan Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/ich8lan.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 232b42b7f7ce..cf18d65417e6 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -140,6 +140,11 @@ #define I82579_LPI_CTRL PHY_REG(772, 20) #define I82579_LPI_CTRL_ENABLE_MASK 0x6000 +/* EMI Registers */ +#define I82579_EMI_ADDR 0x10 +#define I82579_EMI_DATA 0x11 +#define I82579_LPI_UPDATE_TIMER 0x4805 /* in 40ns units + 40 ns base value */ + /* Strapping Option Register - RO */ #define E1000_STRAP 0x0000C #define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000 @@ -1723,11 +1728,25 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw) /* Configure the LCD with the OEM bits in NVM */ ret_val = e1000_oem_bits_config_ich8lan(hw, true); - /* Ungate automatic PHY configuration on non-managed 82579 */ - if ((hw->mac.type == e1000_pch2lan) && - !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) { - msleep(10); - e1000_gate_hw_phy_config_ich8lan(hw, false); + if (hw->mac.type == e1000_pch2lan) { + /* Ungate automatic PHY configuration on non-managed 82579 */ + if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) { + msleep(10); + e1000_gate_hw_phy_config_ich8lan(hw, false); + } + + /* Set EEE LPI Update Timer to 200usec */ + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + goto out; + ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_ADDR, + I82579_LPI_UPDATE_TIMER); + if (ret_val) + goto release; + ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_DATA, + 0x1387); +release: + hw->phy.ops.release(hw); } out: -- cgit v1.2.3 From 6cc7aaed70c96c3933fbacbad582fc79b7d6e335 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 25 Feb 2011 06:25:18 +0000 Subject: e1000e: do not toggle LANPHYPC value bit when PHY reset is blocked When PHY reset is intentionally blocked on 82577/8/9, do not toggle the LANPHYPC value bit (essentially performing a hard power reset of the device) otherwise the PHY can be put into an unknown state. Cleanup whitespace in the same function. Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/ich8lan.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index cf18d65417e6..9b434c0cbc9f 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -307,9 +307,9 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) * the interconnect to PCIe mode. */ fwsm = er32(FWSM); - if (!(fwsm & E1000_ICH_FWSM_FW_VALID)) { + if (!(fwsm & E1000_ICH_FWSM_FW_VALID) && !e1000_check_reset_block(hw)) { ctrl = er32(CTRL); - ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE; + ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE; ctrl &= ~E1000_CTRL_LANPHYPC_VALUE; ew32(CTRL, ctrl); udelay(10); @@ -336,7 +336,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) goto out; /* Ungate automatic PHY configuration on non-managed 82579 */ - if ((hw->mac.type == e1000_pch2lan) && + if ((hw->mac.type == e1000_pch2lan) && !(fwsm & E1000_ICH_FWSM_FW_VALID)) { msleep(10); e1000_gate_hw_phy_config_ich8lan(hw, false); @@ -371,7 +371,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) case e1000_phy_82579: phy->ops.check_polarity = e1000_check_polarity_82577; phy->ops.force_speed_duplex = - e1000_phy_force_speed_duplex_82577; + e1000_phy_force_speed_duplex_82577; phy->ops.get_cable_length = e1000_get_cable_length_82577; phy->ops.get_info = e1000_get_phy_info_82577; phy->ops.commit = e1000e_phy_sw_reset; -- cgit v1.2.3 From 23e4f061306798dfb1941bd2f399949b705822c6 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 25 Feb 2011 07:44:51 +0000 Subject: e1000e: disable jumbo frames on 82579 when MACsec enabled in EEPROM If/when an OEM enables MACsec in the 82579 EEPROM, disable jumbo frames support in the driver due to an interoperability issue in hardware that prevents jumbo packets from being transmitted or received. Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/defines.h | 1 + drivers/net/e1000e/ich8lan.c | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index 13149983d07e..c516a7440bec 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h @@ -86,6 +86,7 @@ #define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */ #define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */ #define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */ +#define E1000_CTRL_EXT_LSECCK 0x00001000 #define E1000_CTRL_EXT_PHYPDEN 0x00100000 /* Receive Descriptor bit definitions */ diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 9b434c0cbc9f..ce1dbfdca112 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -758,7 +758,13 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) if (rc) return rc; - if (adapter->hw.phy.type == e1000_phy_ife) { + /* + * Disable Jumbo Frame support on parts with Intel 10/100 PHY or + * on parts with MACsec enabled in NVM (reflected in CTRL_EXT). + */ + if ((adapter->hw.phy.type == e1000_phy_ife) || + ((adapter->hw.mac.type >= e1000_pch2lan) && + (!(er32(CTRL_EXT) & E1000_CTRL_EXT_LSECCK)))) { adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES; adapter->max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN; } -- cgit v1.2.3 From 4a29e15515ea56b8ec78ebb77529b1ad5c268bb9 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 4 Mar 2011 09:07:01 +0000 Subject: e1000e: do not suggest the driver supports Wake-on-ARP The driver doesn't support Wake-on-ARP, so don't advertise through ethtool that it does. Cleanup some coding style issues in the same functions. Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/ethtool.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 8e276dc4b848..07f09e96e453 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -1799,8 +1799,7 @@ static void e1000_get_wol(struct net_device *netdev, return; wol->supported = WAKE_UCAST | WAKE_MCAST | - WAKE_BCAST | WAKE_MAGIC | - WAKE_PHY | WAKE_ARP; + WAKE_BCAST | WAKE_MAGIC | WAKE_PHY; /* apply any specific unsupported masks here */ if (adapter->flags & FLAG_NO_WAKE_UCAST) { @@ -1821,19 +1820,16 @@ static void e1000_get_wol(struct net_device *netdev, wol->wolopts |= WAKE_MAGIC; if (adapter->wol & E1000_WUFC_LNKC) wol->wolopts |= WAKE_PHY; - if (adapter->wol & E1000_WUFC_ARP) - wol->wolopts |= WAKE_ARP; } -static int e1000_set_wol(struct net_device *netdev, - struct ethtool_wolinfo *wol) +static int e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) { struct e1000_adapter *adapter = netdev_priv(netdev); if (!(adapter->flags & FLAG_HAS_WOL) || !device_can_wakeup(&adapter->pdev->dev) || (wol->wolopts & ~(WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | - WAKE_MAGIC | WAKE_PHY | WAKE_ARP))) + WAKE_MAGIC | WAKE_PHY))) return -EOPNOTSUPP; /* these settings will always override what we currently have */ @@ -1849,8 +1845,6 @@ static int e1000_set_wol(struct net_device *netdev, adapter->wol |= E1000_WUFC_MAG; if (wol->wolopts & WAKE_PHY) adapter->wol |= E1000_WUFC_LNKC; - if (wol->wolopts & WAKE_ARP) - adapter->wol |= E1000_WUFC_ARP; device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); -- cgit v1.2.3 From 70d279a7e2a6e308530822ba2bf4134cc0f5c091 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Sat, 26 Feb 2011 03:12:19 +0000 Subject: e1000e: bump version number Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/e1000e/netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index c43cdfee6b1b..a74de23a5af4 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -54,7 +54,7 @@ #define DRV_EXTRAVERSION "-k2" -#define DRV_VERSION "1.2.20" DRV_EXTRAVERSION +#define DRV_VERSION "1.3.10" DRV_EXTRAVERSION char e1000e_driver_name[] = "e1000e"; const char e1000e_driver_version[] = DRV_VERSION; -- cgit v1.2.3 From efba2e313ea1b1bd69a7c4659263becf43bb1adc Mon Sep 17 00:00:00 2001 From: Antony Pavlov Date: Fri, 11 Feb 2011 13:00:37 +0300 Subject: mtd: jedec_probe: Change variable name from cfi_p to cfi In the following commit, we'll need to use the CMD() macro in order to fix the initialisation of the sector_erase_cmd field. That requires the local variable to be called 'cfi', so change it first in a simple patch. Signed-off-by: Antony Pavlov Acked-by: Guillaume LECERF Signed-off-by: David Woodhouse CC: stable@kernel.org --- drivers/mtd/chips/jedec_probe.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index d72a5fb2d041..7bedbb96604d 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c @@ -1935,14 +1935,14 @@ static void jedec_reset(u32 base, struct map_info *map, struct cfi_private *cfi) } -static int cfi_jedec_setup(struct cfi_private *p_cfi, int index) +static int cfi_jedec_setup(struct cfi_private *cfi, int index) { int i,num_erase_regions; uint8_t uaddr; - if (! (jedec_table[index].devtypes & p_cfi->device_type)) { + if (!(jedec_table[index].devtypes & cfi->device_type)) { DEBUG(MTD_DEBUG_LEVEL1, "Rejecting potential %s with incompatible %d-bit device type\n", - jedec_table[index].name, 4 * (1<device_type)); + jedec_table[index].name, 4 * (1<device_type)); return 0; } @@ -1950,27 +1950,27 @@ static int cfi_jedec_setup(struct cfi_private *p_cfi, int index) num_erase_regions = jedec_table[index].nr_regions; - p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL); - if (!p_cfi->cfiq) { + cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL); + if (!cfi->cfiq) { //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name); return 0; } - memset(p_cfi->cfiq,0,sizeof(struct cfi_ident)); + memset(cfi->cfiq, 0, sizeof(struct cfi_ident)); - p_cfi->cfiq->P_ID = jedec_table[index].cmd_set; - p_cfi->cfiq->NumEraseRegions = jedec_table[index].nr_regions; - p_cfi->cfiq->DevSize = jedec_table[index].dev_size; - p_cfi->cfi_mode = CFI_MODE_JEDEC; + cfi->cfiq->P_ID = jedec_table[index].cmd_set; + cfi->cfiq->NumEraseRegions = jedec_table[index].nr_regions; + cfi->cfiq->DevSize = jedec_table[index].dev_size; + cfi->cfi_mode = CFI_MODE_JEDEC; for (i=0; icfiq->EraseRegionInfo[i] = jedec_table[index].regions[i]; + cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i]; } - p_cfi->cmdset_priv = NULL; + cfi->cmdset_priv = NULL; /* This may be redundant for some cases, but it doesn't hurt */ - p_cfi->mfr = jedec_table[index].mfr_id; - p_cfi->id = jedec_table[index].dev_id; + cfi->mfr = jedec_table[index].mfr_id; + cfi->id = jedec_table[index].dev_id; uaddr = jedec_table[index].uaddr; @@ -1978,8 +1978,8 @@ static int cfi_jedec_setup(struct cfi_private *p_cfi, int index) our brains explode when we see the datasheets talking about address lines numbered from A-1 to A18. The CFI table has unlock addresses in device-words according to the mode the device is connected in */ - p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1 / p_cfi->device_type; - p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2 / p_cfi->device_type; + cfi->addr_unlock1 = unlock_addrs[uaddr].addr1 / cfi->device_type; + cfi->addr_unlock2 = unlock_addrs[uaddr].addr2 / cfi->device_type; return 1; /* ok */ } -- cgit v1.2.3 From ceabebb2bd2672f709e4454e16bc6042732e2dfe Mon Sep 17 00:00:00 2001 From: Antony Pavlov Date: Fri, 11 Feb 2011 13:00:37 +0300 Subject: mtd: jedec_probe: initialise make sector erase command variable In the commit 08968041bef437ec363623cd3218c2b083537ada (mtd: cfi_cmdset_0002: make sector erase command variable) introdused a field sector_erase_cmd. In the same commit initialisation of cfi->sector_erase_cmd made in cfi_chip_setup() (file drivers/mtd/chips/cfi_probe.c), so the CFI chip has no problem: ... cfi->cfi_mode = CFI_MODE_CFI; cfi->sector_erase_cmd = CMD(0x30); ... But for the JEDEC chips this initialisation is not carried out, so the JEDEC chips have sector_erase_cmd == 0. This patch adds the missing initialisation. Signed-off-by: Antony Pavlov Acked-by: Guillaume LECERF Signed-off-by: David Woodhouse CC: stable@kernel.org --- drivers/mtd/chips/jedec_probe.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index 7bedbb96604d..4e1be51cc122 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c @@ -1935,7 +1935,7 @@ static void jedec_reset(u32 base, struct map_info *map, struct cfi_private *cfi) } -static int cfi_jedec_setup(struct cfi_private *cfi, int index) +static int cfi_jedec_setup(struct map_info *map, struct cfi_private *cfi, int index) { int i,num_erase_regions; uint8_t uaddr; @@ -1962,6 +1962,7 @@ static int cfi_jedec_setup(struct cfi_private *cfi, int index) cfi->cfiq->NumEraseRegions = jedec_table[index].nr_regions; cfi->cfiq->DevSize = jedec_table[index].dev_size; cfi->cfi_mode = CFI_MODE_JEDEC; + cfi->sector_erase_cmd = CMD(0x30); for (i=0; icfiq->EraseRegionInfo[i] = jedec_table[index].regions[i]; @@ -2175,7 +2176,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base, "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n", __func__, cfi->mfr, cfi->id, cfi->addr_unlock1, cfi->addr_unlock2 ); - if (!cfi_jedec_setup(cfi, i)) + if (!cfi_jedec_setup(map, cfi, i)) return 0; goto ok_out; } -- cgit v1.2.3 From ecf3fde07c8dcb92a1bf3fbdfe70905d85cd00e1 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Mon, 7 Feb 2011 17:07:11 +0100 Subject: mtd: fix race in cfi_cmdset_0001 driver As inval_cache_and_wait_for_operation() drop and reclaim the lock to invalidate the cache, some other thread may suspend the operation before reaching the for(;;) loop. Therefore the loop must start with checking the chip->state before reading status from the chip. Signed-off-by: Joakim Tjernlund Acked-by: Michael Cashwell Acked-by: Stefan Bigler Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse Cc: stable@kernel.org --- drivers/mtd/chips/cfi_cmdset_0001.c | 43 +++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index a8c3e1c9b02a..4aaa88f8ab5f 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -1230,10 +1230,32 @@ static int inval_cache_and_wait_for_operation( sleep_time = chip_op_time / 2; for (;;) { + if (chip->state != chip_state) { + /* Someone's suspended the operation: sleep */ + DECLARE_WAITQUEUE(wait, current); + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&chip->wq, &wait); + mutex_unlock(&chip->mutex); + schedule(); + remove_wait_queue(&chip->wq, &wait); + mutex_lock(&chip->mutex); + continue; + } + status = map_read(map, cmd_adr); if (map_word_andequal(map, status, status_OK, status_OK)) break; + if (chip->erase_suspended && chip_state == FL_ERASING) { + /* Erase suspend occured while sleep: reset timeout */ + timeo = reset_timeo; + chip->erase_suspended = 0; + } + if (chip->write_suspended && chip_state == FL_WRITING) { + /* Write suspend occured while sleep: reset timeout */ + timeo = reset_timeo; + chip->write_suspended = 0; + } if (!timeo) { map_write(map, CMD(0x70), cmd_adr); chip->state = FL_STATUS; @@ -1257,27 +1279,6 @@ static int inval_cache_and_wait_for_operation( timeo--; } mutex_lock(&chip->mutex); - - while (chip->state != chip_state) { - /* Someone's suspended the operation: sleep */ - DECLARE_WAITQUEUE(wait, current); - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&chip->wq, &wait); - mutex_unlock(&chip->mutex); - schedule(); - remove_wait_queue(&chip->wq, &wait); - mutex_lock(&chip->mutex); - } - if (chip->erase_suspended && chip_state == FL_ERASING) { - /* Erase suspend occured while sleep: reset timeout */ - timeo = reset_timeo; - chip->erase_suspended = 0; - } - if (chip->write_suspended && chip_state == FL_WRITING) { - /* Write suspend occured while sleep: reset timeout */ - timeo = reset_timeo; - chip->write_suspended = 0; - } } /* Done and happy. */ -- cgit v1.2.3 From 82013d988fc03a1b908b2b0360a1e34f6152fda6 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sat, 8 Jan 2011 15:24:37 +0100 Subject: mtd: amd76xrom: fix oops at boot when resources are not available For some unknown reasons resources needed by amd76xrom driver can be unavailable. And instead of returning an error, the driver keeps going and crash the kernel. This patch fixes the problem by making the driver return -EBUSY if the resources are not available. Commit messages tweaked by Artem. Reported-by: Russell Whitaker Signed-off-by: Stanislaw Gruszka Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse Cc: stable@kernel.org --- drivers/mtd/maps/amd76xrom.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c index 77d64ce19e9f..92de7e3a49a5 100644 --- a/drivers/mtd/maps/amd76xrom.c +++ b/drivers/mtd/maps/amd76xrom.c @@ -151,6 +151,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev, printk(KERN_ERR MOD_NAME " %s(): Unable to register resource %pR - kernel bug?\n", __func__, &window->rsrc); + return -EBUSY; } -- cgit v1.2.3 From bd637f6f22235b4613f9ab6555e8088a455c1ed4 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Sun, 9 Jan 2011 01:25:06 +0200 Subject: mtd: mtd_blkdevs: fix double free on error path This one liner patch fixes double free that will occur if add_mtd_blktrans_dev fails. On failure it frees the input argument, but all its users also free it on error which is natural thing to do. Thus don't free it. All credit for finding that bug belongs to reporters of the bug in the android bugzilla http://code.google.com/p/android/issues/detail?id=13761 Commit message tweaked by Artem. Signed-off-by: Maxim Levitsky Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse Cc: stable@kernel.org --- drivers/mtd/mtd_blkdevs.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index cb20c67995d8..e0a2373bf0e2 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -413,7 +413,6 @@ error3: error2: list_del(&new->list); error1: - kfree(new); return ret; } -- cgit v1.2.3 From c804c733846572ca85c2bba60c7fe6fa024dff18 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 7 Mar 2011 11:04:24 +0800 Subject: mtd: add "platform:" prefix for platform modalias Since 43cc71eed1250755986da4c0f9898f9a635cb3bf (platform: prefix MODALIAS with "platform:"), the platform modalias is prefixed with "platform:". Signed-off-by: Axel Lin Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse Cc: stable@kernel.org --- drivers/mtd/nand/omap2.c | 2 +- drivers/mtd/onenand/generic.c | 2 +- drivers/mtd/onenand/omap2.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 15682ec8530e..28af71c61834 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -968,6 +968,6 @@ static void __exit omap_nand_exit(void) module_init(omap_nand_init); module_exit(omap_nand_exit); -MODULE_ALIAS(DRIVER_NAME); +MODULE_ALIAS("platform:" DRIVER_NAME); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Glue layer for NAND flash on TI OMAP boards"); diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c index e78914938c5c..ac08750748a3 100644 --- a/drivers/mtd/onenand/generic.c +++ b/drivers/mtd/onenand/generic.c @@ -131,7 +131,7 @@ static struct platform_driver generic_onenand_driver = { .remove = __devexit_p(generic_onenand_remove), }; -MODULE_ALIAS(DRIVER_NAME); +MODULE_ALIAS("platform:" DRIVER_NAME); static int __init generic_onenand_init(void) { diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index ac31f461cc1c..c849cacf4b2f 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c @@ -860,7 +860,7 @@ static void __exit omap2_onenand_exit(void) module_init(omap2_onenand_init); module_exit(omap2_onenand_exit); -MODULE_ALIAS(DRIVER_NAME); +MODULE_ALIAS("platform:" DRIVER_NAME); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jarkko Lavinen "); MODULE_DESCRIPTION("Glue layer for OneNAND flash on OMAP2 / OMAP3"); -- cgit v1.2.3 From d0c331aff99ca75f9aa0f794cf68b572d8ec7c5a Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sun, 6 Mar 2011 19:23:36 +0200 Subject: wl1251: remove wl1251_ps_set_elp function wl1251_ps_set_elp() only does acx_sleep_auth call and takes the chip from/to ELP, however all callers of wl1251_ps_set_mode() have already taken the chip out of ELP and puts it back to ELP when they finish. This makes ELP calls (and register writes they result in) superfluous. So remove wl1251_ps_set_elp function and call acx_sleep_auth directly. Signed-off-by: Grazvydas Ignotas Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl1251/ps.c | 37 +++---------------------------------- 1 file changed, 3 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl1251/ps.c b/drivers/net/wireless/wl1251/ps.c index 9ba23ede51bd..842155e65a80 100644 --- a/drivers/net/wireless/wl1251/ps.c +++ b/drivers/net/wireless/wl1251/ps.c @@ -102,38 +102,6 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl) return 0; } -static int wl1251_ps_set_elp(struct wl1251 *wl, bool enable) -{ - int ret; - - if (enable) { - wl1251_debug(DEBUG_PSM, "sleep auth psm/elp"); - - ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP); - if (ret < 0) - return ret; - - wl1251_ps_elp_sleep(wl); - } else { - wl1251_debug(DEBUG_PSM, "sleep auth cam"); - - /* - * When the target is in ELP, we can only - * access the ELP control register. Thus, - * we have to wake the target up before - * changing the power authorization. - */ - - wl1251_ps_elp_wakeup(wl); - - ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_CAM); - if (ret < 0) - return ret; - } - - return 0; -} - int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode) { int ret; @@ -162,7 +130,7 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode) if (ret < 0) return ret; - ret = wl1251_ps_set_elp(wl, true); + ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP); if (ret < 0) return ret; @@ -171,7 +139,8 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode) case STATION_ACTIVE_MODE: default: wl1251_debug(DEBUG_PSM, "leaving psm"); - ret = wl1251_ps_set_elp(wl, false); + + ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_CAM); if (ret < 0) return ret; -- cgit v1.2.3 From 5f6722ee63a45d4ad3412743d161ec54d6c32ccc Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sun, 6 Mar 2011 19:23:37 +0200 Subject: wl1251: fix elp_work race condition While working on PS I've noticed elp_work is kicking rather often, and sometimes the chip is put to sleep before 5ms delay expires. This seems to happen because by the time wl1251_ps_elp_wakeup is called elp_work might still be pending. After wakeup is done, the processing may take some time, during which 5ms might expire and elp_work might get scheduled. In this case, ss soon as 1st thread finishes work and releases the mutex, elp_work will then put the device to sleep without 5ms delay. In addition 1st thread will queue additional elp_work needlessly. Fix this by cancelling work in wl1251_ps_elp_wakeup instead. Signed-off-by: Grazvydas Ignotas Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/wl1251/ps.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl1251/ps.c b/drivers/net/wireless/wl1251/ps.c index 842155e65a80..9cc514703d2a 100644 --- a/drivers/net/wireless/wl1251/ps.c +++ b/drivers/net/wireless/wl1251/ps.c @@ -58,7 +58,6 @@ void wl1251_ps_elp_sleep(struct wl1251 *wl) unsigned long delay; if (wl->psm) { - cancel_delayed_work(&wl->elp_work); delay = msecs_to_jiffies(ELP_ENTRY_DELAY); ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay); } @@ -69,6 +68,9 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl) unsigned long timeout, start; u32 elp_reg; + if (delayed_work_pending(&wl->elp_work)) + cancel_delayed_work(&wl->elp_work); + if (!wl->elp) return 0; -- cgit v1.2.3 From 2e286947f1294239527c11f9f466ddce6466455b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 9 Mar 2011 01:48:12 +0100 Subject: ath9k: remove support for the FIF_PROMISC_IN_BSS filter flag The hardware rx filter flag triggered by FIF_PROMISC_IN_BSS is overly broad and covers even frames with PHY errors. When this flag is enabled, this message shows up frequently during scanning or hardware resets: ath: Could not stop RX, we could be confusing the DMA engine when we start RX up Since promiscuous mode is usually not particularly useful, yet enabled by default by bridging (either used normally in 4-addr mode, or with hacks for various virtualization software), we should sacrifice it for better reliability during normal operation. This patch leaves it enabled if there are active monitor mode interfaces, since it's very useful for debugging. Signed-off-by: Felix Fietkau Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index cb559e345b86..a9c3f4672aa0 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -413,9 +413,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) * mode interface or when in monitor mode. AP mode does not need this * since it receives all in-BSS frames anyway. */ - if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) && - (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) || - (sc->sc_ah->is_monitoring)) + if (sc->sc_ah->is_monitoring) rfilt |= ATH9K_RX_FILTER_PROM; if (sc->rx.rxfilter & FIF_CONTROL) -- cgit v1.2.3 From 7ea1362c5d49c5761ce9fc3a4bbb090813134d03 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Thu, 10 Mar 2011 11:05:41 +0530 Subject: ath9k_hw: Improve idle power consumption for AR9485. Set some GPIO pins to Pull-down mode to save power. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9485_initvals.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index eac4d8526fc1..71cc0a3a29fb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h @@ -667,6 +667,7 @@ static const u32 ar9485_1_0_pcie_phy_clkreq_enable_L1[][2] = { static const u32 ar9485_1_0_soc_preamble[][2] = { /* Addr allmodes */ + {0x00004090, 0x00aa10aa}, {0x000040a4, 0x00a0c9c9}, {0x00007048, 0x00000004}, }; @@ -1708,6 +1709,7 @@ static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = { static const u32 ar9485_1_1_soc_preamble[][2] = { /* Addr allmodes */ {0x00004014, 0xba280400}, + {0x00004090, 0x00aa10aa}, {0x000040a4, 0x00a0c9c9}, {0x00007010, 0x00000022}, {0x00007020, 0x00000000}, -- cgit v1.2.3 From 75e03512455827eb2c09e057578ae23178a93cf8 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Thu, 10 Mar 2011 11:05:42 +0530 Subject: ath9k_hw: Fix PLL initialization for AR9485. Increase the delay to make sure the initialization of pll passes. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 9a3438174f86..338b07502f1a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -701,7 +701,7 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); - udelay(100); + udelay(1000); REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); @@ -713,7 +713,7 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c); - udelay(110); + udelay(1000); } pll = ath9k_hw_compute_pll_control(ah, chan); -- cgit v1.2.3 From 23952ec92850bcdc91b8167fa95ec05dd59a80ea Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Thu, 10 Mar 2011 11:05:43 +0530 Subject: ath9k_hw: Increase the wait count for nf load. Increasing the wait count makes the nf load pass in most of the cases. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/calib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index b4a92a4313f6..8649581fa4dd 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -262,7 +262,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) * since 250us often results in NF load timeout and causes deaf * condition during stress testing 12/12/2009 */ - for (j = 0; j < 1000; j++) { + for (j = 0; j < 10000; j++) { if ((REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0) break; @@ -278,7 +278,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) * here, the baseband nf cal will just be capped by our present * noisefloor until the next calibration timer. */ - if (j == 1000) { + if (j == 10000) { ath_dbg(common, ATH_DBG_ANY, "Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x%x\n", REG_READ(ah, AR_PHY_AGC_CONTROL)); -- cgit v1.2.3 From d89dba7a275f40757d27ba16c8bc6aa424656bbe Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 10 Mar 2011 18:23:26 +0300 Subject: libertas: fix write past end of array in mesh_id_get() defs.meshie.val.mesh_id is 32 chars long. It's not supposed to be NUL terminated. This code puts a terminator on the end to make it easier to print to sysfs. The problem is that if the mesh_id fills the entire buffer the original code puts the terminator one spot past the end. The way the original code was written, there was a check to make sure that maxlen was less than PAGE_SIZE. Since we know that maxlen is at most 34 chars, I just removed the check. Signed-off-by: Dan Carpenter Acked-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/mesh.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index acf3bf63ee33..9d097b9c8005 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c @@ -918,7 +918,6 @@ static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr, char *buf) { struct mrvl_mesh_defaults defs; - int maxlen; int ret; ret = mesh_get_default_parameters(dev, &defs); @@ -931,13 +930,11 @@ static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr, defs.meshie.val.mesh_id_len = IEEE80211_MAX_SSID_LEN; } - /* SSID not null terminated: reserve room for \0 + \n */ - maxlen = defs.meshie.val.mesh_id_len + 2; - maxlen = (PAGE_SIZE > maxlen) ? maxlen : PAGE_SIZE; + memcpy(buf, defs.meshie.val.mesh_id, defs.meshie.val.mesh_id_len); + buf[defs.meshie.val.mesh_id_len] = '\n'; + buf[defs.meshie.val.mesh_id_len + 1] = '\0'; - defs.meshie.val.mesh_id[defs.meshie.val.mesh_id_len] = '\0'; - - return snprintf(buf, maxlen, "%s\n", defs.meshie.val.mesh_id); + return defs.meshie.val.mesh_id_len + 1; } /** -- cgit v1.2.3 From 266af4c745952e9bebf687dd68af58df553cb59d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 10 Mar 2011 20:13:26 -0800 Subject: iwlagn: support off-channel TX Add support to iwlagn for off-channel TX. The microcode API for this is a bit strange in that it uses a hacked-up scan command, so the scan code needs to change quite a bit to accomodate that and be able to send it out. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 135 +++++++++++++++++++++------- drivers/net/wireless/iwlwifi/iwl-agn.c | 87 ++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-commands.h | 8 +- drivers/net/wireless/iwlwifi/iwl-core.h | 6 ++ drivers/net/wireless/iwlwifi/iwl-dev.h | 12 ++- drivers/net/wireless/iwlwifi/iwl-scan.c | 41 +++++---- 6 files changed, 238 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 25fccf9a3001..2003c1d4295f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1115,6 +1115,18 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, return added; } +static int iwl_fill_offch_tx(struct iwl_priv *priv, void *data, size_t maxlen) +{ + struct sk_buff *skb = priv->_agn.offchan_tx_skb; + + if (skb->len < maxlen) + maxlen = skb->len; + + memcpy(data, skb->data, maxlen); + + return maxlen; +} + int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) { struct iwl_host_cmd cmd = { @@ -1157,17 +1169,25 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; scan->quiet_time = IWL_ACTIVE_QUIET_TIME; - if (iwl_is_any_associated(priv)) { + if (priv->scan_type != IWL_SCAN_OFFCH_TX && + iwl_is_any_associated(priv)) { u16 interval = 0; u32 extra; u32 suspend_time = 100; u32 scan_suspend_time = 100; IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); - if (priv->is_internal_short_scan) + switch (priv->scan_type) { + case IWL_SCAN_OFFCH_TX: + WARN_ON(1); + break; + case IWL_SCAN_RADIO_RESET: interval = 0; - else + break; + case IWL_SCAN_NORMAL: interval = vif->bss_conf.beacon_int; + break; + } scan->suspend_time = 0; scan->max_out_time = cpu_to_le32(200 * 1024); @@ -1180,29 +1200,41 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->suspend_time = cpu_to_le32(scan_suspend_time); IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n", scan_suspend_time, interval); + } else if (priv->scan_type == IWL_SCAN_OFFCH_TX) { + scan->suspend_time = 0; + scan->max_out_time = + cpu_to_le32(1024 * priv->_agn.offchan_tx_timeout); } - if (priv->is_internal_short_scan) { + switch (priv->scan_type) { + case IWL_SCAN_RADIO_RESET: IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); - } else if (priv->scan_request->n_ssids) { - int i, p = 0; - IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); - for (i = 0; i < priv->scan_request->n_ssids; i++) { - /* always does wildcard anyway */ - if (!priv->scan_request->ssids[i].ssid_len) - continue; - scan->direct_scan[p].id = WLAN_EID_SSID; - scan->direct_scan[p].len = - priv->scan_request->ssids[i].ssid_len; - memcpy(scan->direct_scan[p].ssid, - priv->scan_request->ssids[i].ssid, - priv->scan_request->ssids[i].ssid_len); - n_probes++; - p++; - } - is_active = true; - } else - IWL_DEBUG_SCAN(priv, "Start passive scan.\n"); + break; + case IWL_SCAN_NORMAL: + if (priv->scan_request->n_ssids) { + int i, p = 0; + IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); + for (i = 0; i < priv->scan_request->n_ssids; i++) { + /* always does wildcard anyway */ + if (!priv->scan_request->ssids[i].ssid_len) + continue; + scan->direct_scan[p].id = WLAN_EID_SSID; + scan->direct_scan[p].len = + priv->scan_request->ssids[i].ssid_len; + memcpy(scan->direct_scan[p].ssid, + priv->scan_request->ssids[i].ssid, + priv->scan_request->ssids[i].ssid_len); + n_probes++; + p++; + } + is_active = true; + } else + IWL_DEBUG_SCAN(priv, "Start passive scan.\n"); + break; + case IWL_SCAN_OFFCH_TX: + IWL_DEBUG_SCAN(priv, "Start offchannel TX scan.\n"); + break; + } scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; scan->tx_cmd.sta_id = ctx->bcast_sta_id; @@ -1300,38 +1332,77 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; scan->rx_chain = cpu_to_le16(rx_chain); - if (!priv->is_internal_short_scan) { + switch (priv->scan_type) { + case IWL_SCAN_NORMAL: cmd_len = iwl_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, vif->addr, priv->scan_request->ie, priv->scan_request->ie_len, IWL_MAX_SCAN_SIZE - sizeof(*scan)); - } else { + break; + case IWL_SCAN_RADIO_RESET: /* use bcast addr, will not be transmitted but must be valid */ cmd_len = iwl_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, iwl_bcast_addr, NULL, 0, IWL_MAX_SCAN_SIZE - sizeof(*scan)); - + break; + case IWL_SCAN_OFFCH_TX: + cmd_len = iwl_fill_offch_tx(priv, scan->data, + IWL_MAX_SCAN_SIZE + - sizeof(*scan) + - sizeof(struct iwl_scan_channel)); + scan->scan_flags |= IWL_SCAN_FLAGS_ACTION_FRAME_TX; + break; + default: + BUG(); } scan->tx_cmd.len = cpu_to_le16(cmd_len); scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | RXON_FILTER_BCON_AWARE_MSK); - if (priv->is_internal_short_scan) { + switch (priv->scan_type) { + case IWL_SCAN_RADIO_RESET: scan->channel_count = iwl_get_single_channel_for_scan(priv, vif, band, - (void *)&scan->data[le16_to_cpu( - scan->tx_cmd.len)]); - } else { + (void *)&scan->data[cmd_len]); + break; + case IWL_SCAN_NORMAL: scan->channel_count = iwl_get_channels_for_scan(priv, vif, band, is_active, n_probes, - (void *)&scan->data[le16_to_cpu( - scan->tx_cmd.len)]); + (void *)&scan->data[cmd_len]); + break; + case IWL_SCAN_OFFCH_TX: { + struct iwl_scan_channel *scan_ch; + + scan->channel_count = 1; + + scan_ch = (void *)&scan->data[cmd_len]; + scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; + scan_ch->channel = + cpu_to_le16(priv->_agn.offchan_tx_chan->hw_value); + scan_ch->active_dwell = + cpu_to_le16(priv->_agn.offchan_tx_timeout); + scan_ch->passive_dwell = 0; + + /* Set txpower levels to defaults */ + scan_ch->dsp_atten = 110; + + /* NOTE: if we were doing 6Mb OFDM for scans we'd use + * power level: + * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3; + */ + if (priv->_agn.offchan_tx_chan->band == IEEE80211_BAND_5GHZ) + scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; + else + scan_ch->tx_gain = ((1 << 5) | (5 << 3)); + } + break; } + if (scan->channel_count == 0) { IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); return -EIO; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 19bb567d1c52..b57fbbf3fb64 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2937,6 +2937,91 @@ static void iwl_bg_rx_replenish(struct work_struct *data) mutex_unlock(&priv->mutex); } +static int iwl_mac_offchannel_tx(struct ieee80211_hw *hw, struct sk_buff *skb, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type, + unsigned int wait) +{ + struct iwl_priv *priv = hw->priv; + int ret; + + /* Not supported if we don't have PAN */ + if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN))) { + ret = -EOPNOTSUPP; + goto free; + } + + /* Not supported on pre-P2P firmware */ + if (!(priv->contexts[IWL_RXON_CTX_PAN].interface_modes & + BIT(NL80211_IFTYPE_P2P_CLIENT))) { + ret = -EOPNOTSUPP; + goto free; + } + + mutex_lock(&priv->mutex); + + if (!priv->contexts[IWL_RXON_CTX_PAN].is_active) { + /* + * If the PAN context is free, use the normal + * way of doing remain-on-channel offload + TX. + */ + ret = 1; + goto out; + } + + /* TODO: queue up if scanning? */ + if (test_bit(STATUS_SCANNING, &priv->status) || + priv->_agn.offchan_tx_skb) { + ret = -EBUSY; + goto out; + } + + /* + * max_scan_ie_len doesn't include the blank SSID or the header, + * so need to add that again here. + */ + if (skb->len > hw->wiphy->max_scan_ie_len + 24 + 2) { + ret = -ENOBUFS; + goto out; + } + + priv->_agn.offchan_tx_skb = skb; + priv->_agn.offchan_tx_timeout = wait; + priv->_agn.offchan_tx_chan = chan; + + ret = iwl_scan_initiate(priv, priv->contexts[IWL_RXON_CTX_PAN].vif, + IWL_SCAN_OFFCH_TX, chan->band); + if (ret) + priv->_agn.offchan_tx_skb = NULL; + out: + mutex_unlock(&priv->mutex); + free: + if (ret < 0) + kfree_skb(skb); + + return ret; +} + +static int iwl_mac_offchannel_tx_cancel_wait(struct ieee80211_hw *hw) +{ + struct iwl_priv *priv = hw->priv; + int ret; + + mutex_lock(&priv->mutex); + + if (!priv->_agn.offchan_tx_skb) + return -EINVAL; + + priv->_agn.offchan_tx_skb = NULL; + + ret = iwl_scan_cancel_timeout(priv, 200); + if (ret) + ret = -EIO; + mutex_unlock(&priv->mutex); + + return ret; +} + /***************************************************************************** * * mac80211 entry point functions @@ -3815,6 +3900,8 @@ struct ieee80211_ops iwlagn_hw_ops = { .tx_last_beacon = iwl_mac_tx_last_beacon, .remain_on_channel = iwl_mac_remain_on_channel, .cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel, + .offchannel_tx = iwl_mac_offchannel_tx, + .offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait, }; static void iwl_hw_detect(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 03cfb74da2bc..ca42ffa63ed7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2964,9 +2964,15 @@ struct iwl3945_scan_cmd { u8 data[0]; } __packed; +enum iwl_scan_flags { + /* BIT(0) currently unused */ + IWL_SCAN_FLAGS_ACTION_FRAME_TX = BIT(1), + /* bits 2-7 reserved */ +}; + struct iwl_scan_cmd { __le16 len; - u8 reserved0; + u8 scan_flags; /* scan flags: see enum iwl_scan_flags */ u8 channel_count; /* # channels in channel list */ __le16 quiet_time; /* dwell only this # millisecs on quiet channel * (only for active scan) */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index af47750f8985..b316d833d9a2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -63,6 +63,8 @@ #ifndef __iwl_core_h__ #define __iwl_core_h__ +#include "iwl-dev.h" + /************************ * forward declarations * ************************/ @@ -551,6 +553,10 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, struct ieee80211_vif *vif); void iwl_setup_scan_deferred_work(struct iwl_priv *priv); void iwl_cancel_scan_deferred_work(struct iwl_priv *priv); +int __must_check iwl_scan_initiate(struct iwl_priv *priv, + struct ieee80211_vif *vif, + enum iwl_scan_type scan_type, + enum ieee80211_band band); /* For faster active scanning, scan will move to the next channel if fewer than * PLCP_QUIET_THRESH packets are heard on this channel within diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 6a41deba6863..68b953f2bdc7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1230,6 +1230,12 @@ struct iwl_rxon_context { } ht; }; +enum iwl_scan_type { + IWL_SCAN_NORMAL, + IWL_SCAN_RADIO_RESET, + IWL_SCAN_OFFCH_TX, +}; + struct iwl_priv { /* ieee device used by generic ieee processing code */ @@ -1290,7 +1296,7 @@ struct iwl_priv { enum ieee80211_band scan_band; struct cfg80211_scan_request *scan_request; struct ieee80211_vif *scan_vif; - bool is_internal_short_scan; + enum iwl_scan_type scan_type; u8 scan_tx_ant[IEEE80211_NUM_BANDS]; u8 mgmt_tx_ant; @@ -1504,6 +1510,10 @@ struct iwl_priv { struct delayed_work hw_roc_work; enum nl80211_channel_type hw_roc_chantype; int hw_roc_duration; + + struct sk_buff *offchan_tx_skb; + int offchan_tx_timeout; + struct ieee80211_channel *offchan_tx_chan; } _agn; #endif }; diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index faa6d34cb658..3a4d9e6b0421 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -101,7 +101,7 @@ static void iwl_complete_scan(struct iwl_priv *priv, bool aborted) ieee80211_scan_completed(priv->hw, aborted); } - priv->is_internal_short_scan = false; + priv->scan_type = IWL_SCAN_NORMAL; priv->scan_vif = NULL; priv->scan_request = NULL; } @@ -339,10 +339,10 @@ void iwl_init_scan_params(struct iwl_priv *priv) priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = ant_idx; } -static int __must_check iwl_scan_initiate(struct iwl_priv *priv, - struct ieee80211_vif *vif, - bool internal, - enum ieee80211_band band) +int __must_check iwl_scan_initiate(struct iwl_priv *priv, + struct ieee80211_vif *vif, + enum iwl_scan_type scan_type, + enum ieee80211_band band) { int ret; @@ -370,17 +370,19 @@ static int __must_check iwl_scan_initiate(struct iwl_priv *priv, } IWL_DEBUG_SCAN(priv, "Starting %sscan...\n", - internal ? "internal short " : ""); + scan_type == IWL_SCAN_NORMAL ? "" : + scan_type == IWL_SCAN_OFFCH_TX ? "offchan TX " : + "internal short "); set_bit(STATUS_SCANNING, &priv->status); - priv->is_internal_short_scan = internal; + priv->scan_type = scan_type; priv->scan_start = jiffies; priv->scan_band = band; ret = priv->cfg->ops->utils->request_scan(priv, vif); if (ret) { clear_bit(STATUS_SCANNING, &priv->status); - priv->is_internal_short_scan = false; + priv->scan_type = IWL_SCAN_NORMAL; return ret; } @@ -405,7 +407,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); if (test_bit(STATUS_SCANNING, &priv->status) && - !priv->is_internal_short_scan) { + priv->scan_type != IWL_SCAN_NORMAL) { IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); ret = -EAGAIN; goto out_unlock; @@ -419,11 +421,11 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, * If an internal scan is in progress, just set * up the scan_request as per above. */ - if (priv->is_internal_short_scan) { + if (priv->scan_type != IWL_SCAN_NORMAL) { IWL_DEBUG_SCAN(priv, "SCAN request during internal scan\n"); ret = 0; } else - ret = iwl_scan_initiate(priv, vif, false, + ret = iwl_scan_initiate(priv, vif, IWL_SCAN_NORMAL, req->channels[0]->band); IWL_DEBUG_MAC80211(priv, "leave\n"); @@ -452,7 +454,7 @@ static void iwl_bg_start_internal_scan(struct work_struct *work) mutex_lock(&priv->mutex); - if (priv->is_internal_short_scan == true) { + if (priv->scan_type == IWL_SCAN_RADIO_RESET) { IWL_DEBUG_SCAN(priv, "Internal scan already in progress\n"); goto unlock; } @@ -462,7 +464,7 @@ static void iwl_bg_start_internal_scan(struct work_struct *work) goto unlock; } - if (iwl_scan_initiate(priv, NULL, true, priv->band)) + if (iwl_scan_initiate(priv, NULL, IWL_SCAN_RADIO_RESET, priv->band)) IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n"); unlock: mutex_unlock(&priv->mutex); @@ -549,8 +551,7 @@ static void iwl_bg_scan_completed(struct work_struct *work) container_of(work, struct iwl_priv, scan_completed); bool aborted; - IWL_DEBUG_SCAN(priv, "Completed %sscan.\n", - priv->is_internal_short_scan ? "internal short " : ""); + IWL_DEBUG_SCAN(priv, "Completed scan.\n"); cancel_delayed_work(&priv->scan_check); @@ -565,7 +566,13 @@ static void iwl_bg_scan_completed(struct work_struct *work) goto out_settings; } - if (priv->is_internal_short_scan && !aborted) { + if (priv->scan_type == IWL_SCAN_OFFCH_TX && priv->_agn.offchan_tx_skb) { + ieee80211_tx_status_irqsafe(priv->hw, + priv->_agn.offchan_tx_skb); + priv->_agn.offchan_tx_skb = NULL; + } + + if (priv->scan_type != IWL_SCAN_NORMAL && !aborted) { int err; /* Check if mac80211 requested scan during our internal scan */ @@ -573,7 +580,7 @@ static void iwl_bg_scan_completed(struct work_struct *work) goto out_complete; /* If so request a new scan */ - err = iwl_scan_initiate(priv, priv->scan_vif, false, + err = iwl_scan_initiate(priv, priv->scan_vif, IWL_SCAN_NORMAL, priv->scan_request->channels[0]->band); if (err) { IWL_DEBUG_SCAN(priv, -- cgit v1.2.3 From 81266baf04ce80b088a7fa0dcf3b9f5e79023dd2 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 7 Mar 2011 16:32:59 -0500 Subject: ath5k: implement ieee80211_ops->{get,set}_ringparam set_ringparam only allows changes to tx ring at this time. Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 3 +- drivers/net/wireless/ath/ath5k/base.h | 1 + drivers/net/wireless/ath/ath5k/mac80211-ops.c | 43 +++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index e6ff62e60a79..4d7f21ee111c 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -943,6 +943,7 @@ ath5k_txq_setup(struct ath5k_softc *sc, spin_lock_init(&txq->lock); txq->setup = true; txq->txq_len = 0; + txq->txq_max = ATH5K_TXQ_LEN_MAX; txq->txq_poll_mark = false; txq->txq_stuck = 0; } @@ -1534,7 +1535,7 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, goto drop_packet; } - if (txq->txq_len >= ATH5K_TXQ_LEN_MAX) + if (txq->txq_len >= txq->txq_max) ieee80211_stop_queue(hw, txq->qnum); spin_lock_irqsave(&sc->txbuflock, flags); diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 8d1df1fa2351..978f1f4ac2f3 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -86,6 +86,7 @@ struct ath5k_txq { spinlock_t lock; /* lock on q and link */ bool setup; int txq_len; /* number of queued buffers */ + int txq_max; /* max allowed num of queued buffers */ bool txq_poll_mark; unsigned int txq_stuck; /* informational counter */ }; diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index c9b0b676adda..9be29b728b1c 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -740,6 +740,47 @@ ath5k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) } +static void ath5k_get_ringparam(struct ieee80211_hw *hw, + u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max) +{ + struct ath5k_softc *sc = hw->priv; + + *tx = sc->txqs[AR5K_TX_QUEUE_ID_DATA_MIN].txq_max; + + *tx_max = ATH5K_TXQ_LEN_MAX; + *rx = *rx_max = ATH_RXBUF; +} + + +static int ath5k_set_ringparam(struct ieee80211_hw *hw, u32 tx, u32 rx) +{ + struct ath5k_softc *sc = hw->priv; + u16 qnum; + + /* only support setting tx ring size for now */ + if (rx != ATH_RXBUF) + return -EINVAL; + + /* restrict tx ring size min/max */ + if (!tx || tx > ATH5K_TXQ_LEN_MAX) + return -EINVAL; + + for (qnum = 0; qnum < ARRAY_SIZE(sc->txqs); qnum++) { + if (!sc->txqs[qnum].setup) + continue; + if (sc->txqs[qnum].qnum < AR5K_TX_QUEUE_ID_DATA_MIN || + sc->txqs[qnum].qnum > AR5K_TX_QUEUE_ID_DATA_MAX) + continue; + + sc->txqs[qnum].txq_max = tx; + if (sc->txqs[qnum].txq_len >= sc->txqs[qnum].txq_max) + ieee80211_stop_queue(hw, sc->txqs[qnum].qnum); + } + + return 0; +} + + const struct ieee80211_ops ath5k_hw_ops = { .tx = ath5k_tx, .start = ath5k_start, @@ -778,4 +819,6 @@ const struct ieee80211_ops ath5k_hw_ops = { /* .napi_poll = not implemented */ .set_antenna = ath5k_set_antenna, .get_antenna = ath5k_get_antenna, + .set_ringparam = ath5k_set_ringparam, + .get_ringparam = ath5k_get_ringparam, }; -- cgit v1.2.3 From 0dfeefbc93e38c3a9bd6d4e579cc5a76d3f13dc2 Mon Sep 17 00:00:00 2001 From: Hubert Feurstein Date: Thu, 10 Mar 2011 10:06:37 +0100 Subject: ehci-atmel: fix section mismatch warning Fix the following section mismatch warning: WARNING: drivers/usb/built-in.o(.data+0x74c): Section mismatch in reference from the variable ehci_atmel_driver to the function .init.text:ehci_atmel_drv_probe() The variable ehci_atmel_driver references the function __init ehci_atmel_drv_probe() If the reference is valid then annotate the variable with __init* or __refdata (see linux/init.h) or name the variable: *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console, Signed-off-by: Hubert Feurstein Signed-off-by: Nicolas Ferre Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-atmel.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index d6a69d514a84..b2ed55cb811d 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -115,7 +115,7 @@ static const struct hc_driver ehci_atmel_hc_driver = { .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, }; -static int __init ehci_atmel_drv_probe(struct platform_device *pdev) +static int __devinit ehci_atmel_drv_probe(struct platform_device *pdev) { struct usb_hcd *hcd; const struct hc_driver *driver = &ehci_atmel_hc_driver; @@ -207,7 +207,7 @@ fail_create_hcd: return retval; } -static int __exit ehci_atmel_drv_remove(struct platform_device *pdev) +static int __devexit ehci_atmel_drv_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); @@ -227,7 +227,7 @@ static int __exit ehci_atmel_drv_remove(struct platform_device *pdev) static struct platform_driver ehci_atmel_driver = { .probe = ehci_atmel_drv_probe, - .remove = __exit_p(ehci_atmel_drv_remove), + .remove = __devexit_p(ehci_atmel_drv_remove), .shutdown = usb_hcd_platform_shutdown, .driver.name = "atmel-ehci", }; -- cgit v1.2.3 From 752d57a8b7b97423bffa3452638aa0fd3c3bb9d1 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Fri, 11 Mar 2011 18:03:52 +0100 Subject: USB: Only treat lasting over-current conditions as errors On a laptop I see these errors on (most) resumes: hub 3-0:1.0: over-current change on port 1 hub 3-0:1.0: over-current change on port 2 Since over-current conditions can disappear quite quickly it's better to downgrade that message to debug level, recheck for an over-current condition a little later and only print and over-current condition error if that condition (still) exists when it's rechecked. Add similar logic to hub over-current changes. (That code is untested, as those changes do not occur on this laptop.) Signed-off-by: Paul Bolle Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 395754edd063..b574f9131b43 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3408,12 +3408,19 @@ static void hub_events(void) } if (portchange & USB_PORT_STAT_C_OVERCURRENT) { - dev_err (hub_dev, - "over-current change on port %d\n", - i); + u16 status = 0; + u16 unused; + + dev_dbg(hub_dev, "over-current change on port " + "%d\n", i); clear_port_feature(hdev, i, USB_PORT_FEAT_C_OVER_CURRENT); + msleep(100); /* Cool down */ hub_power_on(hub, true); + hub_port_status(hub, i, &status, &unused); + if (status & USB_PORT_STAT_OVERCURRENT) + dev_err(hub_dev, "over-current " + "condition on port %d\n", i); } if (portchange & USB_PORT_STAT_C_RESET) { @@ -3445,10 +3452,17 @@ static void hub_events(void) hub->limited_power = 0; } if (hubchange & HUB_CHANGE_OVERCURRENT) { - dev_dbg (hub_dev, "overcurrent change\n"); - msleep(500); /* Cool down */ + u16 status = 0; + u16 unused; + + dev_dbg(hub_dev, "over-current change\n"); clear_hub_feature(hdev, C_HUB_OVER_CURRENT); + msleep(500); /* Cool down */ hub_power_on(hub, true); + hub_hub_status(hub, &status, &unused); + if (status & HUB_STATUS_OVERCURRENT) + dev_err(hub_dev, "over-current " + "condition\n"); } } -- cgit v1.2.3 From d0781383038e983a63843a9a6a067ed781db89c1 Mon Sep 17 00:00:00 2001 From: wangyanqing Date: Fri, 11 Mar 2011 06:24:38 -0800 Subject: USB: serial: ch341: add new id I picked up a new DAK-780EX(professional digitl reverb/mix system), which use CH341T chipset to communication with computer on 3/2011 and the CH341T's vendor code is 1a86 Looking up the CH341T's vendor and product id's I see: 1a86 QinHeng Electronics 5523 CH341 in serial mode, usb to serial port converter CH341T,CH341 are the products of the same company, maybe have some common hardware, and I test the ch341.c works well with CH341T Cc: Linus Torvalds Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ch341.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 7b8815ddf368..14ac87ee9251 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -75,6 +75,7 @@ static int debug; static const struct usb_device_id id_table[] = { { USB_DEVICE(0x4348, 0x5523) }, { USB_DEVICE(0x1a86, 0x7523) }, + { USB_DEVICE(0x1a86, 0x5523) }, { }, }; MODULE_DEVICE_TABLE(usb, id_table); -- cgit v1.2.3 From ee398ba97dd76ed53bed548dec648d918af4004c Mon Sep 17 00:00:00 2001 From: Benoit Goby Date: Wed, 9 Mar 2011 16:28:54 -0800 Subject: usb: otg: Add ulpi viewport access ops Add generic access ops for controllers with a ulpi viewport register (e.g. Chipidea/ARC based controllers). Signed-off-by: Benoit Goby Signed-off-by: Greg Kroah-Hartman --- drivers/usb/otg/Kconfig | 7 ++++ drivers/usb/otg/Makefile | 1 + drivers/usb/otg/ulpi_viewport.c | 80 +++++++++++++++++++++++++++++++++++++++++ include/linux/usb/ulpi.h | 5 +++ 4 files changed, 93 insertions(+) create mode 100644 drivers/usb/otg/ulpi_viewport.c (limited to 'drivers') diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig index ceb24fee2eac..daf3e5f1a0e7 100644 --- a/drivers/usb/otg/Kconfig +++ b/drivers/usb/otg/Kconfig @@ -49,6 +49,13 @@ config USB_ULPI Enable this to support ULPI connected USB OTG transceivers which are likely found on embedded boards. +config USB_ULPI_VIEWPORT + bool + depends on USB_ULPI + help + Provides read/write operations to the ULPI phy register set for + controllers with a viewport register (e.g. Chipidea/ARC controllers). + config TWL4030_USB tristate "TWL4030 USB Transceiver Driver" depends on TWL4030_CORE && REGULATOR_TWL4030 diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile index e516894260bf..e22d917de017 100644 --- a/drivers/usb/otg/Makefile +++ b/drivers/usb/otg/Makefile @@ -16,5 +16,6 @@ obj-$(CONFIG_TWL6030_USB) += twl6030-usb.o obj-$(CONFIG_USB_LANGWELL_OTG) += langwell_otg.o obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o obj-$(CONFIG_USB_ULPI) += ulpi.o +obj-$(CONFIG_USB_ULPI_VIEWPORT) += ulpi_viewport.o obj-$(CONFIG_USB_MSM_OTG) += msm_otg.o obj-$(CONFIG_AB8500_USB) += ab8500-usb.o diff --git a/drivers/usb/otg/ulpi_viewport.c b/drivers/usb/otg/ulpi_viewport.c new file mode 100644 index 000000000000..e9a37f90994f --- /dev/null +++ b/drivers/usb/otg/ulpi_viewport.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include + +#define ULPI_VIEW_WAKEUP (1 << 31) +#define ULPI_VIEW_RUN (1 << 30) +#define ULPI_VIEW_WRITE (1 << 29) +#define ULPI_VIEW_READ (0 << 29) +#define ULPI_VIEW_ADDR(x) (((x) & 0xff) << 16) +#define ULPI_VIEW_DATA_READ(x) (((x) >> 8) & 0xff) +#define ULPI_VIEW_DATA_WRITE(x) ((x) & 0xff) + +static int ulpi_viewport_wait(void __iomem *view, u32 mask) +{ + unsigned long usec = 2000; + + while (usec--) { + if (!(readl(view) & mask)) + return 0; + + udelay(1); + }; + + return -ETIMEDOUT; +} + +static int ulpi_viewport_read(struct otg_transceiver *otg, u32 reg) +{ + int ret; + void __iomem *view = otg->io_priv; + + writel(ULPI_VIEW_WAKEUP | ULPI_VIEW_WRITE, view); + ret = ulpi_viewport_wait(view, ULPI_VIEW_WAKEUP); + if (ret) + return ret; + + writel(ULPI_VIEW_RUN | ULPI_VIEW_READ | ULPI_VIEW_ADDR(reg), view); + ret = ulpi_viewport_wait(view, ULPI_VIEW_RUN); + if (ret) + return ret; + + return ULPI_VIEW_DATA_READ(readl(view)); +} + +static int ulpi_viewport_write(struct otg_transceiver *otg, u32 val, u32 reg) +{ + int ret; + void __iomem *view = otg->io_priv; + + writel(ULPI_VIEW_WAKEUP | ULPI_VIEW_WRITE, view); + ret = ulpi_viewport_wait(view, ULPI_VIEW_WAKEUP); + if (ret) + return ret; + + writel(ULPI_VIEW_RUN | ULPI_VIEW_WRITE | ULPI_VIEW_DATA_WRITE(val) | + ULPI_VIEW_ADDR(reg), view); + + return ulpi_viewport_wait(view, ULPI_VIEW_RUN); +} + +struct otg_io_access_ops ulpi_viewport_access_ops = { + .read = ulpi_viewport_read, + .write = ulpi_viewport_write, +}; diff --git a/include/linux/usb/ulpi.h b/include/linux/usb/ulpi.h index 82b1507f4735..9595796d62ed 100644 --- a/include/linux/usb/ulpi.h +++ b/include/linux/usb/ulpi.h @@ -184,4 +184,9 @@ struct otg_transceiver *otg_ulpi_create(struct otg_io_access_ops *ops, unsigned int flags); +#ifdef CONFIG_USB_ULPI_VIEWPORT +/* access ops for controllers with a viewport register */ +extern struct otg_io_access_ops ulpi_viewport_access_ops; +#endif + #endif /* __LINUX_USB_ULPI_H */ -- cgit v1.2.3 From 79ad3b5add4a683af02d1b51ccb699d1b01f1fbf Mon Sep 17 00:00:00 2001 From: Benoit Goby Date: Wed, 9 Mar 2011 16:28:56 -0800 Subject: usb: host: Add EHCI driver for NVIDIA Tegra SoCs The Tegra 2 SoC has 3 EHCI compatible USB controllers. This patch adds the necessary glue to allow the ehci-hcd driver to work on Tegra 2 SoCs. The platform data is used to configure board-specific phy settings and to configure the operating mode, as one of the ports may be used as a otg port. For additional power saving, the driver supports powering down the phy on bus suspend when it is used, for example, to connect an internal device that use an out-of-band remote wakeup mechanism (e.g. a gpio). Signed-off-by: Benoit Goby Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 8 + drivers/usb/host/ehci-hcd.c | 5 + drivers/usb/host/ehci-tegra.c | 625 ++++++++++++++++++++++++++++++++ include/linux/platform_data/tegra_usb.h | 31 ++ include/linux/usb/ehci_def.h | 4 +- 5 files changed, 672 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/host/ehci-tegra.c create mode 100644 include/linux/platform_data/tegra_usb.h (limited to 'drivers') diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index b5a908eacb82..9483acdf2e9e 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -165,6 +165,14 @@ config USB_EHCI_MSM This driver is not supported on boards like trout which has an external PHY. +config USB_EHCI_TEGRA + boolean "NVIDIA Tegra HCD support" + depends on USB_EHCI_HCD && ARCH_TEGRA + select USB_EHCI_ROOT_HUB_TT + help + This driver enables support for the internal USB Host Controllers + found in NVIDIA Tegra SoCs. The controllers are EHCI compliant. + config USB_EHCI_HCD_PPC_OF bool "EHCI support for PPC USB controller on OF platform bus" depends on USB_EHCI_HCD && PPC_OF diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index cfeb24b3ee09..d30c4e08c137 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1260,6 +1260,11 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_hcd_msp_driver #endif +#ifdef CONFIG_USB_EHCI_TEGRA +#include "ehci-tegra.c" +#define PLATFORM_DRIVER tegra_ehci_driver +#endif + #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ !defined(XILINX_OF_PLATFORM_DRIVER) diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c new file mode 100644 index 000000000000..6202102a6d75 --- /dev/null +++ b/drivers/usb/host/ehci-tegra.c @@ -0,0 +1,625 @@ +/* + * EHCI-compliant USB host controller driver for NVIDIA Tegra SoCs + * + * Copyright (C) 2010 Google, Inc. + * Copyright (C) 2009 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include + +struct tegra_ehci_hcd { + struct ehci_hcd *ehci; + struct tegra_usb_phy *phy; + struct clk *clk; + struct clk *emc_clk; + struct otg_transceiver *transceiver; + int host_resumed; + int bus_suspended; + int port_resuming; + int power_down_on_bus_suspend; + enum tegra_usb_phy_port_speed port_speed; +}; + +static void tegra_ehci_power_up(struct usb_hcd *hcd) +{ + struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); + + clk_enable(tegra->emc_clk); + clk_enable(tegra->clk); + tegra_usb_phy_power_on(tegra->phy); + tegra->host_resumed = 1; +} + +static void tegra_ehci_power_down(struct usb_hcd *hcd) +{ + struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); + + tegra->host_resumed = 0; + tegra_usb_phy_power_off(tegra->phy); + clk_disable(tegra->clk); + clk_disable(tegra->emc_clk); +} + +static int tegra_ehci_hub_control( + struct usb_hcd *hcd, + u16 typeReq, + u16 wValue, + u16 wIndex, + char *buf, + u16 wLength +) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); + u32 __iomem *status_reg; + u32 temp; + unsigned long flags; + int retval = 0; + + status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1]; + + spin_lock_irqsave(&ehci->lock, flags); + + /* + * In ehci_hub_control() for USB_PORT_FEAT_ENABLE clears the other bits + * that are write on clear, by writing back the register read value, so + * USB_PORT_FEAT_ENABLE is handled by masking the set on clear bits + */ + if (typeReq == ClearPortFeature && wValue == USB_PORT_FEAT_ENABLE) { + temp = ehci_readl(ehci, status_reg) & ~PORT_RWC_BITS; + ehci_writel(ehci, temp & ~PORT_PE, status_reg); + goto done; + } + + else if (typeReq == GetPortStatus) { + temp = ehci_readl(ehci, status_reg); + if (tegra->port_resuming && !(temp & PORT_SUSPEND)) { + /* Resume completed, re-enable disconnect detection */ + tegra->port_resuming = 0; + tegra_usb_phy_postresume(tegra->phy); + } + } + + else if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) { + temp = ehci_readl(ehci, status_reg); + if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) { + retval = -EPIPE; + goto done; + } + + temp &= ~PORT_WKCONN_E; + temp |= PORT_WKDISC_E | PORT_WKOC_E; + ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); + + /* + * If a transaction is in progress, there may be a delay in + * suspending the port. Poll until the port is suspended. + */ + if (handshake(ehci, status_reg, PORT_SUSPEND, + PORT_SUSPEND, 5000)) + pr_err("%s: timeout waiting for SUSPEND\n", __func__); + + set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports); + goto done; + } + + /* + * Tegra host controller will time the resume operation to clear the bit + * when the port control state switches to HS or FS Idle. This behavior + * is different from EHCI where the host controller driver is required + * to set this bit to a zero after the resume duration is timed in the + * driver. + */ + else if (typeReq == ClearPortFeature && + wValue == USB_PORT_FEAT_SUSPEND) { + temp = ehci_readl(ehci, status_reg); + if ((temp & PORT_RESET) || !(temp & PORT_PE)) { + retval = -EPIPE; + goto done; + } + + if (!(temp & PORT_SUSPEND)) + goto done; + + /* Disable disconnect detection during port resume */ + tegra_usb_phy_preresume(tegra->phy); + + ehci->reset_done[wIndex-1] = jiffies + msecs_to_jiffies(25); + + temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); + /* start resume signalling */ + ehci_writel(ehci, temp | PORT_RESUME, status_reg); + + spin_unlock_irqrestore(&ehci->lock, flags); + msleep(20); + spin_lock_irqsave(&ehci->lock, flags); + + /* Poll until the controller clears RESUME and SUSPEND */ + if (handshake(ehci, status_reg, PORT_RESUME, 0, 2000)) + pr_err("%s: timeout waiting for RESUME\n", __func__); + if (handshake(ehci, status_reg, PORT_SUSPEND, 0, 2000)) + pr_err("%s: timeout waiting for SUSPEND\n", __func__); + + ehci->reset_done[wIndex-1] = 0; + + tegra->port_resuming = 1; + goto done; + } + + spin_unlock_irqrestore(&ehci->lock, flags); + + /* Handle the hub control events here */ + return ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); +done: + spin_unlock_irqrestore(&ehci->lock, flags); + return retval; +} + +static void tegra_ehci_restart(struct usb_hcd *hcd) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + + ehci_reset(ehci); + + /* setup the frame list and Async q heads */ + ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list); + ehci_writel(ehci, (u32)ehci->async->qh_dma, &ehci->regs->async_next); + /* setup the command register and set the controller in RUN mode */ + ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET); + ehci->command |= CMD_RUN; + ehci_writel(ehci, ehci->command, &ehci->regs->command); + + down_write(&ehci_cf_port_reset_rwsem); + ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); + /* flush posted writes */ + ehci_readl(ehci, &ehci->regs->command); + up_write(&ehci_cf_port_reset_rwsem); +} + +static int tegra_usb_suspend(struct usb_hcd *hcd) +{ + struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); + struct ehci_regs __iomem *hw = tegra->ehci->regs; + unsigned long flags; + + spin_lock_irqsave(&tegra->ehci->lock, flags); + + tegra->port_speed = (readl(&hw->port_status[0]) >> 26) & 0x3; + ehci_halt(tegra->ehci); + clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + + spin_unlock_irqrestore(&tegra->ehci->lock, flags); + + tegra_ehci_power_down(hcd); + return 0; +} + +static int tegra_usb_resume(struct usb_hcd *hcd) +{ + struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + struct ehci_regs __iomem *hw = ehci->regs; + unsigned long val; + + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + tegra_ehci_power_up(hcd); + + if (tegra->port_speed > TEGRA_USB_PHY_PORT_SPEED_HIGH) { + /* Wait for the phy to detect new devices + * before we restart the controller */ + msleep(10); + goto restart; + } + + /* Force the phy to keep data lines in suspend state */ + tegra_ehci_phy_restore_start(tegra->phy, tegra->port_speed); + + /* Enable host mode */ + tdi_reset(ehci); + + /* Enable Port Power */ + val = readl(&hw->port_status[0]); + val |= PORT_POWER; + writel(val, &hw->port_status[0]); + udelay(10); + + /* Check if the phy resume from LP0. When the phy resume from LP0 + * USB register will be reset. */ + if (!readl(&hw->async_next)) { + /* Program the field PTC based on the saved speed mode */ + val = readl(&hw->port_status[0]); + val &= ~PORT_TEST(~0); + if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_HIGH) + val |= PORT_TEST_FORCE; + else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_FULL) + val |= PORT_TEST(6); + else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW) + val |= PORT_TEST(7); + writel(val, &hw->port_status[0]); + udelay(10); + + /* Disable test mode by setting PTC field to NORMAL_OP */ + val = readl(&hw->port_status[0]); + val &= ~PORT_TEST(~0); + writel(val, &hw->port_status[0]); + udelay(10); + } + + /* Poll until CCS is enabled */ + if (handshake(ehci, &hw->port_status[0], PORT_CONNECT, + PORT_CONNECT, 2000)) { + pr_err("%s: timeout waiting for PORT_CONNECT\n", __func__); + goto restart; + } + + /* Poll until PE is enabled */ + if (handshake(ehci, &hw->port_status[0], PORT_PE, + PORT_PE, 2000)) { + pr_err("%s: timeout waiting for USB_PORTSC1_PE\n", __func__); + goto restart; + } + + /* Clear the PCI status, to avoid an interrupt taken upon resume */ + val = readl(&hw->status); + val |= STS_PCD; + writel(val, &hw->status); + + /* Put controller in suspend mode by writing 1 to SUSP bit of PORTSC */ + val = readl(&hw->port_status[0]); + if ((val & PORT_POWER) && (val & PORT_PE)) { + val |= PORT_SUSPEND; + writel(val, &hw->port_status[0]); + + /* Wait until port suspend completes */ + if (handshake(ehci, &hw->port_status[0], PORT_SUSPEND, + PORT_SUSPEND, 1000)) { + pr_err("%s: timeout waiting for PORT_SUSPEND\n", + __func__); + goto restart; + } + } + + tegra_ehci_phy_restore_end(tegra->phy); + return 0; + +restart: + if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH) + tegra_ehci_phy_restore_end(tegra->phy); + + tegra_ehci_restart(hcd); + return 0; +} + +static void tegra_ehci_shutdown(struct usb_hcd *hcd) +{ + struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); + + /* ehci_shutdown touches the USB controller registers, make sure + * controller has clocks to it */ + if (!tegra->host_resumed) + tegra_ehci_power_up(hcd); + + ehci_shutdown(hcd); +} + +static int tegra_ehci_setup(struct usb_hcd *hcd) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + int retval; + + /* EHCI registers start at offset 0x100 */ + ehci->caps = hcd->regs + 0x100; + ehci->regs = hcd->regs + 0x100 + + HC_LENGTH(readl(&ehci->caps->hc_capbase)); + + dbg_hcs_params(ehci, "reset"); + dbg_hcc_params(ehci, "reset"); + + /* cache this readonly data; minimize chip reads */ + ehci->hcs_params = readl(&ehci->caps->hcs_params); + + /* switch to host mode */ + hcd->has_tt = 1; + ehci_reset(ehci); + + retval = ehci_halt(ehci); + if (retval) + return retval; + + /* data structure init */ + retval = ehci_init(hcd); + if (retval) + return retval; + + ehci->sbrn = 0x20; + + ehci_port_power(ehci, 1); + return retval; +} + +#ifdef CONFIG_PM +static int tegra_ehci_bus_suspend(struct usb_hcd *hcd) +{ + struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); + int error_status = 0; + + error_status = ehci_bus_suspend(hcd); + if (!error_status && tegra->power_down_on_bus_suspend) { + tegra_usb_suspend(hcd); + tegra->bus_suspended = 1; + } + + return error_status; +} + +static int tegra_ehci_bus_resume(struct usb_hcd *hcd) +{ + struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); + + if (tegra->bus_suspended && tegra->power_down_on_bus_suspend) { + tegra_usb_resume(hcd); + tegra->bus_suspended = 0; + } + + tegra_usb_phy_preresume(tegra->phy); + tegra->port_resuming = 1; + return ehci_bus_resume(hcd); +} +#endif + +static const struct hc_driver tegra_ehci_hc_driver = { + .description = hcd_name, + .product_desc = "Tegra EHCI Host Controller", + .hcd_priv_size = sizeof(struct ehci_hcd), + + .flags = HCD_USB2 | HCD_MEMORY, + + .reset = tegra_ehci_setup, + .irq = ehci_irq, + + .start = ehci_run, + .stop = ehci_stop, + .shutdown = tegra_ehci_shutdown, + .urb_enqueue = ehci_urb_enqueue, + .urb_dequeue = ehci_urb_dequeue, + .endpoint_disable = ehci_endpoint_disable, + .endpoint_reset = ehci_endpoint_reset, + .get_frame_number = ehci_get_frame, + .hub_status_data = ehci_hub_status_data, + .hub_control = tegra_ehci_hub_control, + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, +#ifdef CONFIG_PM + .bus_suspend = tegra_ehci_bus_suspend, + .bus_resume = tegra_ehci_bus_resume, +#endif + .relinquish_port = ehci_relinquish_port, + .port_handed_over = ehci_port_handed_over, +}; + +static int tegra_ehci_probe(struct platform_device *pdev) +{ + struct resource *res; + struct usb_hcd *hcd; + struct tegra_ehci_hcd *tegra; + struct tegra_ehci_platform_data *pdata; + int err = 0; + int irq; + int instance = pdev->id; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "Platform data missing\n"); + return -EINVAL; + } + + tegra = kzalloc(sizeof(struct tegra_ehci_hcd), GFP_KERNEL); + if (!tegra) + return -ENOMEM; + + hcd = usb_create_hcd(&tegra_ehci_hc_driver, &pdev->dev, + dev_name(&pdev->dev)); + if (!hcd) { + dev_err(&pdev->dev, "Unable to create HCD\n"); + err = -ENOMEM; + goto fail_hcd; + } + + platform_set_drvdata(pdev, tegra); + + tegra->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(tegra->clk)) { + dev_err(&pdev->dev, "Can't get ehci clock\n"); + err = PTR_ERR(tegra->clk); + goto fail_clk; + } + + err = clk_enable(tegra->clk); + if (err) + goto fail_clken; + + tegra->emc_clk = clk_get(&pdev->dev, "emc"); + if (IS_ERR(tegra->emc_clk)) { + dev_err(&pdev->dev, "Can't get emc clock\n"); + err = PTR_ERR(tegra->emc_clk); + goto fail_emc_clk; + } + + clk_enable(tegra->emc_clk); + clk_set_rate(tegra->emc_clk, 400000000); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "Failed to get I/O memory\n"); + err = -ENXIO; + goto fail_io; + } + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); + hcd->regs = ioremap(res->start, resource_size(res)); + if (!hcd->regs) { + dev_err(&pdev->dev, "Failed to remap I/O memory\n"); + err = -ENOMEM; + goto fail_io; + } + + tegra->phy = tegra_usb_phy_open(instance, hcd->regs, pdata->phy_config, + TEGRA_USB_PHY_MODE_HOST); + if (IS_ERR(tegra->phy)) { + dev_err(&pdev->dev, "Failed to open USB phy\n"); + err = -ENXIO; + goto fail_phy; + } + + err = tegra_usb_phy_power_on(tegra->phy); + if (err) { + dev_err(&pdev->dev, "Failed to power on the phy\n"); + goto fail; + } + + tegra->host_resumed = 1; + tegra->power_down_on_bus_suspend = pdata->power_down_on_bus_suspend; + tegra->ehci = hcd_to_ehci(hcd); + + irq = platform_get_irq(pdev, 0); + if (!irq) { + dev_err(&pdev->dev, "Failed to get IRQ\n"); + err = -ENODEV; + goto fail; + } + set_irq_flags(irq, IRQF_VALID); + +#ifdef CONFIG_USB_OTG_UTILS + if (pdata->operating_mode == TEGRA_USB_OTG) { + tegra->transceiver = otg_get_transceiver(); + if (tegra->transceiver) + otg_set_host(tegra->transceiver, &hcd->self); + } +#endif + + err = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); + if (err) { + dev_err(&pdev->dev, "Failed to add USB HCD\n"); + goto fail; + } + + return err; + +fail: +#ifdef CONFIG_USB_OTG_UTILS + if (tegra->transceiver) { + otg_set_host(tegra->transceiver, NULL); + otg_put_transceiver(tegra->transceiver); + } +#endif + tegra_usb_phy_close(tegra->phy); +fail_phy: + iounmap(hcd->regs); +fail_io: + clk_disable(tegra->emc_clk); + clk_put(tegra->emc_clk); +fail_emc_clk: + clk_disable(tegra->clk); +fail_clken: + clk_put(tegra->clk); +fail_clk: + usb_put_hcd(hcd); +fail_hcd: + kfree(tegra); + return err; +} + +#ifdef CONFIG_PM +static int tegra_ehci_resume(struct platform_device *pdev) +{ + struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); + struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); + + if (tegra->bus_suspended) + return 0; + + return tegra_usb_resume(hcd); +} + +static int tegra_ehci_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); + struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); + + if (tegra->bus_suspended) + return 0; + + if (time_before(jiffies, tegra->ehci->next_statechange)) + msleep(10); + + return tegra_usb_suspend(hcd); +} +#endif + +static int tegra_ehci_remove(struct platform_device *pdev) +{ + struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); + struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); + + if (tegra == NULL || hcd == NULL) + return -EINVAL; + +#ifdef CONFIG_USB_OTG_UTILS + if (tegra->transceiver) { + otg_set_host(tegra->transceiver, NULL); + otg_put_transceiver(tegra->transceiver); + } +#endif + + usb_remove_hcd(hcd); + usb_put_hcd(hcd); + + tegra_usb_phy_close(tegra->phy); + iounmap(hcd->regs); + + clk_disable(tegra->clk); + clk_put(tegra->clk); + + clk_disable(tegra->emc_clk); + clk_put(tegra->emc_clk); + + kfree(tegra); + return 0; +} + +static void tegra_ehci_hcd_shutdown(struct platform_device *pdev) +{ + struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); + struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); + + if (hcd->driver->shutdown) + hcd->driver->shutdown(hcd); +} + +static struct platform_driver tegra_ehci_driver = { + .probe = tegra_ehci_probe, + .remove = tegra_ehci_remove, +#ifdef CONFIG_PM + .suspend = tegra_ehci_suspend, + .resume = tegra_ehci_resume, +#endif + .shutdown = tegra_ehci_hcd_shutdown, + .driver = { + .name = "tegra-ehci", + } +}; diff --git a/include/linux/platform_data/tegra_usb.h b/include/linux/platform_data/tegra_usb.h new file mode 100644 index 000000000000..6bca5b569acb --- /dev/null +++ b/include/linux/platform_data/tegra_usb.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2010 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _TEGRA_USB_H_ +#define _TEGRA_USB_H_ + +enum tegra_usb_operating_modes { + TEGRA_USB_DEVICE, + TEGRA_USB_HOST, + TEGRA_USB_OTG, +}; + +struct tegra_ehci_platform_data { + enum tegra_usb_operating_modes operating_mode; + /* power down the phy on bus suspend */ + int power_down_on_bus_suspend; + void *phy_config; +}; + +#endif /* _TEGRA_USB_H_ */ diff --git a/include/linux/usb/ehci_def.h b/include/linux/usb/ehci_def.h index 2e262cb15425..656380245198 100644 --- a/include/linux/usb/ehci_def.h +++ b/include/linux/usb/ehci_def.h @@ -127,7 +127,9 @@ struct ehci_regs { #define PORT_WKDISC_E (1<<21) /* wake on disconnect (enable) */ #define PORT_WKCONN_E (1<<20) /* wake on connect (enable) */ /* 19:16 for port testing */ -#define PORT_TEST_PKT (0x4<<16) /* Port Test Control - packet test */ +#define PORT_TEST(x) (((x)&0xf)<<16) /* Port Test Control */ +#define PORT_TEST_PKT PORT_TEST(0x4) /* Port Test Control - packet test */ +#define PORT_TEST_FORCE PORT_TEST(0x5) /* Port Test Control - force enable */ #define PORT_LED_OFF (0<<14) #define PORT_LED_AMBER (1<<14) #define PORT_LED_GREEN (2<<14) -- cgit v1.2.3 From fbf9865c6d96f4a131092d2018056e86113e5cea Mon Sep 17 00:00:00 2001 From: Robert Morell Date: Wed, 9 Mar 2011 16:28:57 -0800 Subject: USB: ehci: tegra: Align DMA transfers to 32 bytes The Tegra2 USB controller doesn't properly deal with misaligned DMA buffers, causing corruption. This is especially prevalent with USB network adapters, where skbuff alignment is often in the middle of a 4-byte dword. To avoid this, allocate a temporary buffer for the DMA if the provided buffer isn't sufficiently aligned. Signed-off-by: Robert Morell Signed-off-by: Benoit Goby Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-tegra.c | 90 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 6202102a6d75..a516af28c29b 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -23,6 +23,8 @@ #include #include +#define TEGRA_USB_DMA_ALIGN 32 + struct tegra_ehci_hcd { struct ehci_hcd *ehci; struct tegra_usb_phy *phy; @@ -383,6 +385,92 @@ static int tegra_ehci_bus_resume(struct usb_hcd *hcd) } #endif +struct temp_buffer { + void *kmalloc_ptr; + void *old_xfer_buffer; + u8 data[0]; +}; + +static void free_temp_buffer(struct urb *urb) +{ + enum dma_data_direction dir; + struct temp_buffer *temp; + + if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER)) + return; + + dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + + temp = container_of(urb->transfer_buffer, struct temp_buffer, + data); + + if (dir == DMA_FROM_DEVICE) + memcpy(temp->old_xfer_buffer, temp->data, + urb->transfer_buffer_length); + urb->transfer_buffer = temp->old_xfer_buffer; + kfree(temp->kmalloc_ptr); + + urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER; +} + +static int alloc_temp_buffer(struct urb *urb, gfp_t mem_flags) +{ + enum dma_data_direction dir; + struct temp_buffer *temp, *kmalloc_ptr; + size_t kmalloc_size; + + if (urb->num_sgs || urb->sg || + urb->transfer_buffer_length == 0 || + !((uintptr_t)urb->transfer_buffer & (TEGRA_USB_DMA_ALIGN - 1))) + return 0; + + dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + + /* Allocate a buffer with enough padding for alignment */ + kmalloc_size = urb->transfer_buffer_length + + sizeof(struct temp_buffer) + TEGRA_USB_DMA_ALIGN - 1; + + kmalloc_ptr = kmalloc(kmalloc_size, mem_flags); + if (!kmalloc_ptr) + return -ENOMEM; + + /* Position our struct temp_buffer such that data is aligned */ + temp = PTR_ALIGN(kmalloc_ptr + 1, TEGRA_USB_DMA_ALIGN) - 1; + + temp->kmalloc_ptr = kmalloc_ptr; + temp->old_xfer_buffer = urb->transfer_buffer; + if (dir == DMA_TO_DEVICE) + memcpy(temp->data, urb->transfer_buffer, + urb->transfer_buffer_length); + urb->transfer_buffer = temp->data; + + urb->transfer_flags |= URB_ALIGNED_TEMP_BUFFER; + + return 0; +} + +static int tegra_ehci_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, + gfp_t mem_flags) +{ + int ret; + + ret = alloc_temp_buffer(urb, mem_flags); + if (ret) + return ret; + + ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags); + if (ret) + free_temp_buffer(urb); + + return ret; +} + +static void tegra_ehci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) +{ + usb_hcd_unmap_urb_for_dma(hcd, urb); + free_temp_buffer(urb); +} + static const struct hc_driver tegra_ehci_hc_driver = { .description = hcd_name, .product_desc = "Tegra EHCI Host Controller", @@ -398,6 +486,8 @@ static const struct hc_driver tegra_ehci_hc_driver = { .shutdown = tegra_ehci_shutdown, .urb_enqueue = ehci_urb_enqueue, .urb_dequeue = ehci_urb_dequeue, + .map_urb_for_dma = tegra_ehci_map_urb_for_dma, + .unmap_urb_for_dma = tegra_ehci_unmap_urb_for_dma, .endpoint_disable = ehci_endpoint_disable, .endpoint_reset = ehci_endpoint_reset, .get_frame_number = ehci_get_frame, -- cgit v1.2.3 From 8b0fb6f872477dfd218e43b073543e4913b6d785 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 10 Mar 2011 11:31:33 +0300 Subject: USB: ene_ub6250: fix memory leak in ene_load_bincode() "buf" gets allocated twice in a row. It's the second allocation which is correct. The first one should be removed. Signed-off-by: Dan Carpenter Acked-by: huajun li Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/ene_ub6250.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index 058c5d5f1c1e..08e03745e251 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c @@ -491,10 +491,6 @@ static int ene_load_bincode(struct us_data *us, unsigned char flag) if (info->BIN_FLAG == flag) return USB_STOR_TRANSPORT_GOOD; - buf = kmalloc(ENE_BIN_CODE_LEN, GFP_KERNEL); - if (buf == NULL) - return USB_STOR_TRANSPORT_ERROR; - switch (flag) { /* For SD */ case SD_INIT1_PATTERN: -- cgit v1.2.3 From 0074f59b51a2882ce3b8e3922c52f4c547bd56b7 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 10 Mar 2011 16:48:36 -0800 Subject: usb-storage: ene_ub6250 depends on USB_STORAGE Fix ene_ub6250 build: it uses usb_storage driver interfaces, so it should depend on USB_STORAGE. ene_ub6250.c:(.text+0x14ff19): undefined reference to `usb_stor_reset_resume' ene_ub6250.c:(.text+0x14ffb1): undefined reference to `usb_stor_bulk_transfer_buf' ene_ub6250.c:(.text+0x14ffdd): undefined reference to `usb_stor_bulk_srb' ene_ub6250.c:(.text+0x14fff1): undefined reference to `usb_stor_bulk_transfer_sg' ene_ub6250.c:(.text+0x1503dd): undefined reference to `usb_stor_set_xfer_buf' ene_ub6250.c:(.text+0x15048e): undefined reference to `usb_stor_access_xfer_buf' ene_ub6250.c:(.text+0x150723): undefined reference to `usb_stor_probe1' ene_ub6250.c:(.text+0x150795): undefined reference to `usb_stor_probe2' ene_ub6250.c:(.text+0x1507af): undefined reference to `usb_stor_disconnect' drivers/built-in.o:(.data+0x10224): undefined reference to `usb_stor_suspend' drivers/built-in.o:(.data+0x10230): undefined reference to `usb_stor_pre_reset' drivers/built-in.o:(.data+0x10234): undefined reference to `usb_stor_post_reset' Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index 72448bac2ee0..e34f655af02e 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -202,6 +202,7 @@ config USB_LIBUSUAL config USB_STORAGE_ENE_UB6250 tristate "USB ENE card reader support" depends on USB && SCSI + depends on USB_STORAGE ---help--- Say Y here if you wish to control a ENE SD Card reader. To use SM/MS card, please build driver/staging/keucr/keucr.ko -- cgit v1.2.3 From e49c459c33189cfc7cff581d3c2e7f0074835118 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 10 Mar 2011 16:49:56 -0800 Subject: usb-storage: fix menu ordering Move the USB_STORAGE_ENE_UB6250 entry so that it stays under the USB_STORAGE menu. Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/Kconfig | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index e34f655af02e..3e6e3c118438 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -172,6 +172,21 @@ config USB_STORAGE_CYPRESS_ATACB If this driver is compiled as a module, it will be named ums-cypress. +config USB_STORAGE_ENE_UB6250 + tristate "USB ENE card reader support" + depends on USB && SCSI + depends on USB_STORAGE + ---help--- + Say Y here if you wish to control a ENE SD Card reader. + To use SM/MS card, please build driver/staging/keucr/keucr.ko + + This option depends on 'SCSI' support being enabled, but you + probably also need 'SCSI device support: SCSI disk support' + (BLK_DEV_SD) for most USB storage devices. + + To compile this driver as a module, choose M here: the + module will be called ums-eneub6250. + config USB_UAS tristate "USB Attached SCSI" depends on USB && SCSI @@ -198,18 +213,3 @@ config USB_LIBUSUAL options libusual bias="ub" If unsure, say N. - -config USB_STORAGE_ENE_UB6250 - tristate "USB ENE card reader support" - depends on USB && SCSI - depends on USB_STORAGE - ---help--- - Say Y here if you wish to control a ENE SD Card reader. - To use SM/MS card, please build driver/staging/keucr/keucr.ko - - This option depends on 'SCSI' support being enabled, but you - probably also need 'SCSI device support: SCSI disk support' - (BLK_DEV_SD) for most USB storage devices. - - To compile this driver as a module, choose M here: the - module will be called ums-eneub6250. -- cgit v1.2.3 From 7702c36072072427db2166cc6e68bfc52b4209bb Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 10 Mar 2011 18:55:28 -0800 Subject: staging: ath6kl: Cast variable to size_t to avoid compile warning The min() macro does strict type-checking so use min_t() instead to silence a compile warning. Cc: Naveen Singh Signed-off-by: Javier Martinez Canillas Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c index 67e6d5edfa51..55b0633af9ee 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c @@ -360,7 +360,7 @@ int PSSendOps(void *arg) status = 1; goto complete; } - len = min(firmware->size, MAX_BDADDR_FORMAT_LENGTH - 1); + len = min_t(size_t, firmware->size, MAX_BDADDR_FORMAT_LENGTH - 1); memcpy(config_bdaddr, firmware->data, len); config_bdaddr[len] = '\0'; write_bdaddr(hdev,config_bdaddr,BDADDR_TYPE_STRING); -- cgit v1.2.3 From 05209262bcbece611e559a37b90869f667864e0c Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 10 Mar 2011 18:55:29 -0800 Subject: staging: ath6kl: s|A_MEMCPY|memcpy|g for i in $(find ./drivers/staging/ath6kl/ -name \*.[ch]) ; do \ sed -r -i -e "s/A_MEMCPY/memcpy/g" $i; done Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/bmi/src/bmi.c | 74 +++++------ drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 12 +- drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c | 2 +- drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c | 8 +- .../ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c | 2 +- drivers/staging/ath6kl/htc2/htc.c | 4 +- drivers/staging/ath6kl/htc2/htc_recv.c | 6 +- drivers/staging/ath6kl/htc2/htc_services.c | 6 +- drivers/staging/ath6kl/miscdrv/ar3kconfig.c | 2 +- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 56 ++++---- drivers/staging/ath6kl/os/linux/ar6k_pal.c | 2 +- drivers/staging/ath6kl/os/linux/cfg80211.c | 36 ++--- drivers/staging/ath6kl/os/linux/hci_bridge.c | 4 +- .../staging/ath6kl/os/linux/include/osapi_linux.h | 2 - drivers/staging/ath6kl/os/linux/ioctl.c | 30 ++--- drivers/staging/ath6kl/os/linux/netbuf.c | 8 +- drivers/staging/ath6kl/os/linux/wireless_ext.c | 26 ++-- drivers/staging/ath6kl/reorder/rcv_aggr.c | 2 +- drivers/staging/ath6kl/wlan/include/ieee80211.h | 2 +- drivers/staging/ath6kl/wlan/src/wlan_node.c | 2 +- drivers/staging/ath6kl/wmi/wmi.c | 146 ++++++++++----------- 21 files changed, 215 insertions(+), 217 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/bmi/src/bmi.c b/drivers/staging/ath6kl/bmi/src/bmi.c index 49aed8ac2dc2..1e1e6ee6c39c 100644 --- a/drivers/staging/ath6kl/bmi/src/bmi.c +++ b/drivers/staging/ath6kl/bmi/src/bmi.c @@ -231,11 +231,11 @@ BMIReadMemory(HIF_DEVICE *device, { rxlen = (remaining < BMI_DATASZ_MAX) ? remaining : BMI_DATASZ_MAX; offset = 0; - A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); offset += sizeof(cid); - A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); + memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address)); offset += sizeof(address); - A_MEMCPY(&(pBMICmdBuf[offset]), &rxlen, sizeof(rxlen)); + memcpy(&(pBMICmdBuf[offset]), &rxlen, sizeof(rxlen)); offset += sizeof(length); status = bmiBufferSend(device, pBMICmdBuf, offset); @@ -248,7 +248,7 @@ BMIReadMemory(HIF_DEVICE *device, AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); return A_ERROR; } - A_MEMCPY(&buffer[length - remaining], pBMICmdBuf, rxlen); + memcpy(&buffer[length - remaining], pBMICmdBuf, rxlen); remaining -= rxlen; address += rxlen; } @@ -300,13 +300,13 @@ BMIWriteMemory(HIF_DEVICE *device, txlen = (BMI_DATASZ_MAX - header); } offset = 0; - A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); offset += sizeof(cid); - A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); + memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address)); offset += sizeof(address); - A_MEMCPY(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen)); + memcpy(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen)); offset += sizeof(txlen); - A_MEMCPY(&(pBMICmdBuf[offset]), src, txlen); + memcpy(&(pBMICmdBuf[offset]), src, txlen); offset += txlen; status = bmiBufferSend(device, pBMICmdBuf, offset); if (status) { @@ -345,11 +345,11 @@ BMIExecute(HIF_DEVICE *device, cid = BMI_EXECUTE; offset = 0; - A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); offset += sizeof(cid); - A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); + memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address)); offset += sizeof(address); - A_MEMCPY(&(pBMICmdBuf[offset]), param, sizeof(*param)); + memcpy(&(pBMICmdBuf[offset]), param, sizeof(*param)); offset += sizeof(*param); status = bmiBufferSend(device, pBMICmdBuf, offset); if (status) { @@ -363,7 +363,7 @@ BMIExecute(HIF_DEVICE *device, return A_ERROR; } - A_MEMCPY(param, pBMICmdBuf, sizeof(*param)); + memcpy(param, pBMICmdBuf, sizeof(*param)); AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Execute: Exit (param: %d)\n", *param)); return 0; @@ -392,9 +392,9 @@ BMISetAppStart(HIF_DEVICE *device, cid = BMI_SET_APP_START; offset = 0; - A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); offset += sizeof(cid); - A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); + memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address)); offset += sizeof(address); status = bmiBufferSend(device, pBMICmdBuf, offset); if (status) { @@ -430,9 +430,9 @@ BMIReadSOCRegister(HIF_DEVICE *device, cid = BMI_READ_SOC_REGISTER; offset = 0; - A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); offset += sizeof(cid); - A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); + memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address)); offset += sizeof(address); status = bmiBufferSend(device, pBMICmdBuf, offset); @@ -446,7 +446,7 @@ BMIReadSOCRegister(HIF_DEVICE *device, AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); return A_ERROR; } - A_MEMCPY(param, pBMICmdBuf, sizeof(*param)); + memcpy(param, pBMICmdBuf, sizeof(*param)); AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit (value: %d)\n", *param)); return 0; @@ -476,11 +476,11 @@ BMIWriteSOCRegister(HIF_DEVICE *device, cid = BMI_WRITE_SOC_REGISTER; offset = 0; - A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); offset += sizeof(cid); - A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); + memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address)); offset += sizeof(address); - A_MEMCPY(&(pBMICmdBuf[offset]), ¶m, sizeof(param)); + memcpy(&(pBMICmdBuf[offset]), ¶m, sizeof(param)); offset += sizeof(param); status = bmiBufferSend(device, pBMICmdBuf, offset); if (status) { @@ -521,15 +521,15 @@ BMIrompatchInstall(HIF_DEVICE *device, cid = BMI_ROMPATCH_INSTALL; offset = 0; - A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); offset += sizeof(cid); - A_MEMCPY(&(pBMICmdBuf[offset]), &ROM_addr, sizeof(ROM_addr)); + memcpy(&(pBMICmdBuf[offset]), &ROM_addr, sizeof(ROM_addr)); offset += sizeof(ROM_addr); - A_MEMCPY(&(pBMICmdBuf[offset]), &RAM_addr, sizeof(RAM_addr)); + memcpy(&(pBMICmdBuf[offset]), &RAM_addr, sizeof(RAM_addr)); offset += sizeof(RAM_addr); - A_MEMCPY(&(pBMICmdBuf[offset]), &nbytes, sizeof(nbytes)); + memcpy(&(pBMICmdBuf[offset]), &nbytes, sizeof(nbytes)); offset += sizeof(nbytes); - A_MEMCPY(&(pBMICmdBuf[offset]), &do_activate, sizeof(do_activate)); + memcpy(&(pBMICmdBuf[offset]), &do_activate, sizeof(do_activate)); offset += sizeof(do_activate); status = bmiBufferSend(device, pBMICmdBuf, offset); if (status) { @@ -542,7 +542,7 @@ BMIrompatchInstall(HIF_DEVICE *device, AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); return A_ERROR; } - A_MEMCPY(rompatch_id, pBMICmdBuf, sizeof(*rompatch_id)); + memcpy(rompatch_id, pBMICmdBuf, sizeof(*rompatch_id)); AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch Install: (rompatch_id=%d)\n", *rompatch_id)); return 0; @@ -571,9 +571,9 @@ BMIrompatchUninstall(HIF_DEVICE *device, cid = BMI_ROMPATCH_UNINSTALL; offset = 0; - A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); offset += sizeof(cid); - A_MEMCPY(&(pBMICmdBuf[offset]), &rompatch_id, sizeof(rompatch_id)); + memcpy(&(pBMICmdBuf[offset]), &rompatch_id, sizeof(rompatch_id)); offset += sizeof(rompatch_id); status = bmiBufferSend(device, pBMICmdBuf, offset); if (status) { @@ -611,12 +611,12 @@ _BMIrompatchChangeActivation(HIF_DEVICE *device, cid = do_activate ? BMI_ROMPATCH_ACTIVATE : BMI_ROMPATCH_DEACTIVATE; offset = 0; - A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); offset += sizeof(cid); - A_MEMCPY(&(pBMICmdBuf[offset]), &rompatch_count, sizeof(rompatch_count)); + memcpy(&(pBMICmdBuf[offset]), &rompatch_count, sizeof(rompatch_count)); offset += sizeof(rompatch_count); length = rompatch_count * sizeof(*rompatch_list); - A_MEMCPY(&(pBMICmdBuf[offset]), rompatch_list, length); + memcpy(&(pBMICmdBuf[offset]), rompatch_list, length); offset += length; status = bmiBufferSend(device, pBMICmdBuf, offset); if (status) { @@ -676,11 +676,11 @@ BMILZData(HIF_DEVICE *device, txlen = (remaining < (BMI_DATASZ_MAX - header)) ? remaining : (BMI_DATASZ_MAX - header); offset = 0; - A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); offset += sizeof(cid); - A_MEMCPY(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen)); + memcpy(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen)); offset += sizeof(txlen); - A_MEMCPY(&(pBMICmdBuf[offset]), &buffer[length - remaining], txlen); + memcpy(&(pBMICmdBuf[offset]), &buffer[length - remaining], txlen); offset += txlen; status = bmiBufferSend(device, pBMICmdBuf, offset); if (status) { @@ -717,9 +717,9 @@ BMILZStreamStart(HIF_DEVICE *device, cid = BMI_LZ_STREAM_START; offset = 0; - A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); offset += sizeof(cid); - A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address)); + memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address)); offset += sizeof(address); status = bmiBufferSend(device, pBMICmdBuf, offset); if (status) { @@ -972,7 +972,7 @@ BMIFastDownload(HIF_DEVICE *device, u32 address, A_UCHAR *buffer, u32 length) if (unalignedBytes) { /* copy the last word into a zero padded buffer */ - A_MEMCPY(&lastWord, &buffer[lastWordOffset], unalignedBytes); + memcpy(&lastWord, &buffer[lastWordOffset], unalignedBytes); } status = BMILZData(device, buffer, lastWordOffset); diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index ff0480b5254b..cf75c20fc90c 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -254,7 +254,7 @@ int DevEnableInterrupts(AR6K_DEVICE *pDev) COUNTER_INT_STATUS_ENABLE_BIT_SET(AR6K_TARGET_DEBUG_INTR_MASK); /* copy into our temp area */ - A_MEMCPY(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); + memcpy(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); UNLOCK_AR6K(pDev); @@ -287,7 +287,7 @@ int DevDisableInterrupts(AR6K_DEVICE *pDev) pDev->IrqEnableRegisters.error_status_enable = 0; pDev->IrqEnableRegisters.counter_int_status_enable = 0; /* copy into our temp area */ - A_MEMCPY(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); + memcpy(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); UNLOCK_AR6K(pDev); @@ -419,7 +419,7 @@ static int DevDoEnableDisableRecvNormal(AR6K_DEVICE *pDev, bool EnableRecv, bool } /* copy into our temp area */ - A_MEMCPY(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); + memcpy(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); UNLOCK_AR6K(pDev); do { @@ -435,7 +435,7 @@ static int DevDoEnableDisableRecvNormal(AR6K_DEVICE *pDev, bool EnableRecv, bool } /* copy values to write to our async I/O buffer */ - A_MEMCPY(pIOPacket->pBuffer,®s,AR6K_IRQ_ENABLE_REGS_SIZE); + memcpy(pIOPacket->pBuffer,®s,AR6K_IRQ_ENABLE_REGS_SIZE); /* stick in our completion routine when the I/O operation completes */ pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler; @@ -635,10 +635,10 @@ int DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, bool FromDMA) if (FromDMA) { /* from DMA buffer */ - A_MEMCPY(pReq->ScatterList[i].pBuffer, pDMABuffer , length); + memcpy(pReq->ScatterList[i].pBuffer, pDMABuffer , length); } else { /* to DMA buffer */ - A_MEMCPY(pDMABuffer, pReq->ScatterList[i].pBuffer, length); + memcpy(pDMABuffer, pReq->ScatterList[i].pBuffer, length); } pDMABuffer += length; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c index 4517bef4ba8f..bee4850b54fc 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c @@ -752,7 +752,7 @@ void DumpAR6KDevState(AR6K_DEVICE *pDev) LOCK_AR6K(pDev); /* copy into our temp area */ - A_MEMCPY(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); + memcpy(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); UNLOCK_AR6K(pDev); /* load the register table from the device */ diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c index d58e41884720..46bcb275e43a 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c @@ -93,7 +93,7 @@ static int DevGMboxCounterEnableDisable(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE ~(COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER)); } /* copy into our temp area */ - A_MEMCPY(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); + memcpy(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); UNLOCK_AR6K(pDev); @@ -110,7 +110,7 @@ static int DevGMboxCounterEnableDisable(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE } /* copy values to write to our async I/O buffer */ - A_MEMCPY(pIOPacket->pBuffer,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); + memcpy(pIOPacket->pBuffer,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); /* stick in our completion routine when the I/O operation completes */ pIOPacket->Completion = DevGMboxIRQActionAsyncHandler; @@ -216,7 +216,7 @@ int DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool A } /* copy values to write to our async I/O buffer */ - A_MEMCPY(pIOPacket->pBuffer,GMboxIntControl,sizeof(GMboxIntControl)); + memcpy(pIOPacket->pBuffer,GMboxIntControl,sizeof(GMboxIntControl)); /* stick in our completion routine when the I/O operation completes */ pIOPacket->Completion = DevGMboxIRQActionAsyncHandler; @@ -667,7 +667,7 @@ int DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, u8 *pLookAheadBuffer, int *pLoo if (procRegs.gmbox_rx_avail > 0) { int bytes = procRegs.gmbox_rx_avail > maxCopy ? maxCopy : procRegs.gmbox_rx_avail; - A_MEMCPY(pLookAheadBuffer,&procRegs.rx_gmbox_lookahead_alias[0],bytes); + memcpy(pLookAheadBuffer,&procRegs.rx_gmbox_lookahead_alias[0],bytes); *pLookAheadBytes = bytes; } diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c index cddb93993194..177f04dc9674 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c @@ -961,7 +961,7 @@ HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, HCI_TRANSPORT_CONFIG_I break; } - A_MEMCPY(&pProtocol->HCIConfig, pInfo, sizeof(HCI_TRANSPORT_CONFIG_INFO)); + memcpy(&pProtocol->HCIConfig, pInfo, sizeof(HCI_TRANSPORT_CONFIG_INFO)); A_ASSERT(pProtocol->HCIConfig.pHCIPktRecv != NULL); A_ASSERT(pProtocol->HCIConfig.pHCISendComplete != NULL); diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index e7adc45324af..c200cfd339b3 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -130,7 +130,7 @@ HTC_HANDLE HTCCreate(void *hif_handle, HTC_INIT_INFO *pInfo) target->Device.MessagePendingCallback = HTCRecvMessagePendingHandler; target->EpWaitingForBuffers = ENDPOINT_MAX; - A_MEMCPY(&target->HTCInitInfo,pInfo,sizeof(HTC_INIT_INFO)); + memcpy(&target->HTCInitInfo,pInfo,sizeof(HTC_INIT_INFO)); ResetEndpointStates(target); @@ -556,7 +556,7 @@ bool HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, if (sample) { A_ASSERT(pStats != NULL); /* return the stats to the caller */ - A_MEMCPY(pStats, &target->EndPoint[Endpoint].EndPointStats, sizeof(HTC_ENDPOINT_STATS)); + memcpy(pStats, &target->EndPoint[Endpoint].EndPointStats, sizeof(HTC_ENDPOINT_STATS)); } if (clearStats) { diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c index 34454754b8cd..daa6efcf2144 100644 --- a/drivers/staging/ath6kl/htc2/htc_recv.c +++ b/drivers/staging/ath6kl/htc2/htc_recv.c @@ -346,7 +346,7 @@ static int HTCProcessRecvHeader(HTC_TARGET *target, } #ifdef HTC_CAPTURE_LAST_FRAME - A_MEMCPY(target->LastTrailer, (pBuf + HTC_HDR_LENGTH + payloadLen - temp), temp); + memcpy(target->LastTrailer, (pBuf + HTC_HDR_LENGTH + payloadLen - temp), temp); target->LastTrailerLength = temp; #endif /* trim length by trailer bytes */ @@ -372,7 +372,7 @@ static int HTCProcessRecvHeader(HTC_TARGET *target, #endif } else { #ifdef HTC_CAPTURE_LAST_FRAME - A_MEMCPY(&target->LastFrameHdr,pBuf,sizeof(HTC_FRAME_HDR)); + memcpy(&target->LastFrameHdr,pBuf,sizeof(HTC_FRAME_HDR)); #endif if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { if (pPacket->ActualLength > 0) { @@ -1155,7 +1155,7 @@ int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLook } /* on first entry copy the lookaheads into our temp array for processing */ - A_MEMCPY(lookAheads, MsgLookAheads, (sizeof(u32)) * NumLookAheads); + memcpy(lookAheads, MsgLookAheads, (sizeof(u32)) * NumLookAheads); while (true) { diff --git a/drivers/staging/ath6kl/htc2/htc_services.c b/drivers/staging/ath6kl/htc2/htc_services.c index 9ddf32cd2dfe..61a332e856b1 100644 --- a/drivers/staging/ath6kl/htc2/htc_services.c +++ b/drivers/staging/ath6kl/htc2/htc_services.c @@ -83,7 +83,7 @@ int HTCSendSetupComplete(HTC_TARGET *target) setupFlags |= HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV; pSetupCompleteEx->MaxMsgsPerBundledRecv = target->MaxMsgPerBundle; } - A_MEMCPY(&pSetupCompleteEx->SetupFlags, &setupFlags, sizeof(pSetupCompleteEx->SetupFlags)); + memcpy(&pSetupCompleteEx->SetupFlags, &setupFlags, sizeof(pSetupCompleteEx->SetupFlags)); SET_HTC_PACKET_INFO_TX(pSendPacket, NULL, (u8 *)pSetupCompleteEx, @@ -166,7 +166,7 @@ int HTCConnectService(HTC_HANDLE HTCHandle, if ((pConnectReq->pMetaData != NULL) && (pConnectReq->MetaDataLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) { /* copy meta data into message buffer (after header ) */ - A_MEMCPY((u8 *)pConnectMsg + sizeof(HTC_CONNECT_SERVICE_MSG), + memcpy((u8 *)pConnectMsg + sizeof(HTC_CONNECT_SERVICE_MSG), pConnectReq->pMetaData, pConnectReq->MetaDataLength); pConnectMsg->ServiceMetaLength = pConnectReq->MetaDataLength; @@ -224,7 +224,7 @@ int HTCConnectService(HTC_HANDLE HTCHandle, /* caller supplied a buffer and the target responded with data */ int copyLength = min((int)pConnectResp->BufferLength, (int)pResponseMsg->ServiceMetaLength); /* copy the meta data */ - A_MEMCPY(pConnectResp->pMetaData, + memcpy(pConnectResp->pMetaData, ((u8 *)pResponseMsg) + sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG), copyLength); pConnectResp->ActualLength = copyLength; diff --git a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c index 29873ac15892..005b3ba23b4e 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c @@ -153,7 +153,7 @@ int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, opCodeBytes[1] = pHCICommand[HCI_CMD_OPCODE_BYTE_HI_OFFSET]; /* copy HCI command */ - A_MEMCPY(pBuffer + pConfig->pHCIProps->HeadRoom,pHCICommand,CmdLength); + memcpy(pBuffer + pConfig->pHCIProps->HeadRoom,pHCICommand,CmdLength); /* send command */ status = SendHCICommand(pConfig, pBuffer + pConfig->pHCIProps->HeadRoom, diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 21483812ea98..2111e993856a 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -2280,7 +2280,7 @@ ar6000_init_control_info(AR_SOFTC_T *ar) ar->ap_profile_flag = 0; A_NETBUF_QUEUE_INIT(&ar->mcastpsq); - A_MEMCPY(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3); + memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3); ar->ap_wmode = DEF_AP_WMODE_G; ar->ap_dtim_period = DEF_AP_DTIM; ar->ap_beacon_interval = DEF_BEACON_INTERVAL; @@ -2875,7 +2875,7 @@ ar6000_channelList_rx(void *devt, s8 numChan, u16 *chanList) { AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; - A_MEMCPY(ar->arChannelList, chanList, numChan * sizeof (u16)); + memcpy(ar->arChannelList, chanList, numChan * sizeof (u16)); ar->arNumChannels = numChan; wake_up(&arEvent); @@ -2914,7 +2914,7 @@ u8 ar6000_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, u32 *mapNo) A_ASSERT(ar->arNodeNum <= MAX_NODE_NUM); } - A_MEMCPY(ar->arNodeMap[eptMap].macAddress, macHdr->dstMac, IEEE80211_ADDR_LEN); + memcpy(ar->arNodeMap[eptMap].macAddress, macHdr->dstMac, IEEE80211_ADDR_LEN); for (i = ENDPOINT_2; i <= ENDPOINT_5; i ++) { if (!ar->arTxPending[i]) { @@ -3118,7 +3118,7 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) break; } A_NETBUF_PUT(newbuf, len); - A_MEMCPY(A_NETBUF_DATA(newbuf), A_NETBUF_DATA(skb), len); + memcpy(A_NETBUF_DATA(newbuf), A_NETBUF_DATA(skb), len); A_NETBUF_FREE(skb); skb = newbuf; /* fall through and assemble header */ @@ -4239,7 +4239,7 @@ ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, u32 sw_ver, u32 abi_ver) AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; struct net_device *dev = ar->arNetDev; - A_MEMCPY(dev->dev_addr, datap, AR6000_ETH_ADDR_LEN); + memcpy(dev->dev_addr, datap, AR6000_ETH_ADDR_LEN); AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("mac address = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], @@ -4260,8 +4260,8 @@ add_new_sta(AR_SOFTC_T *ar, u8 *mac, u16 aid, u8 *wpaie, { u8 free_slot=aid-1; - A_MEMCPY(ar->sta_list[free_slot].mac, mac, ATH_MAC_LEN); - A_MEMCPY(ar->sta_list[free_slot].wpa_ie, wpaie, ielen); + memcpy(ar->sta_list[free_slot].mac, mac, ATH_MAC_LEN); + memcpy(ar->sta_list[free_slot].wpa_ie, wpaie, ielen); ar->sta_list[free_slot].aid = aid; ar->sta_list[free_slot].keymgmt = keymgmt; ar->sta_list[free_slot].ucipher = ucipher; @@ -4383,7 +4383,7 @@ skip_key: /* Send event to application */ A_MEMZERO(&wrqu, sizeof(wrqu)); - A_MEMCPY(wrqu.addr.sa_data, bssid, ATH_MAC_LEN); + memcpy(wrqu.addr.sa_data, bssid, ATH_MAC_LEN); wireless_send_event(ar->arNetDev, IWEVREGISTERED, &wrqu, NULL); /* In case the queue is stopped when we switch modes, this will * wake it up @@ -4400,7 +4400,7 @@ skip_key: assocInfo); #endif /* ATH6K_CONFIG_CFG80211 */ - A_MEMCPY(ar->arBssid, bssid, sizeof(ar->arBssid)); + memcpy(ar->arBssid, bssid, sizeof(ar->arBssid)); ar->arBssChannel = channel; A_PRINTF("AR6000 connected event on freq %d ", channel); @@ -4543,7 +4543,7 @@ skip_key: reconnect_flag = 0; A_MEMZERO(&wrqu, sizeof(wrqu)); - A_MEMCPY(wrqu.addr.sa_data, bssid, IEEE80211_ADDR_LEN); + memcpy(wrqu.addr.sa_data, bssid, IEEE80211_ADDR_LEN); wrqu.addr.sa_family = ARPHRD_ETHER; wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL); if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable) { @@ -4653,7 +4653,7 @@ ar6000_disconnect_event(AR_SOFTC_T *ar, u8 reason, u8 *bssid, if(!IS_MAC_BCAST(bssid)) { /* Send event to application */ A_MEMZERO(&wrqu, sizeof(wrqu)); - A_MEMCPY(wrqu.addr.sa_data, bssid, ATH_MAC_LEN); + memcpy(wrqu.addr.sa_data, bssid, ATH_MAC_LEN); wireless_send_event(ar->arNetDev, IWEVEXPIRED, &wrqu, NULL); } @@ -4826,7 +4826,7 @@ ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd) */ *((short *)buf) = WMI_HCI_EVENT_EVENTID; buf += sizeof(int); - A_MEMCPY(buf, cmd->buf, cmd->evt_buf_sz); + memcpy(buf, cmd->buf, cmd->evt_buf_sz); if(ar6k_pal_config_g.fpar6k_pal_recv_pkt) { @@ -4880,7 +4880,7 @@ ar6000_neighborReport_event(AR_SOFTC_T *ar, int numAps, WMI_NEIGHBOR_INFO *info) A_MEMZERO(pmkcand, sizeof(struct iw_pmkid_cand)); pmkcand->index = i; pmkcand->flags = info->bssFlags; - A_MEMCPY(pmkcand->bssid.sa_data, info->bssid, ATH_MAC_LEN); + memcpy(pmkcand->bssid.sa_data, info->bssid, ATH_MAC_LEN); wrqu.data.length = sizeof(struct iw_pmkid_cand); wireless_send_event(ar->arNetDev, IWEVPMKIDCAND, &wrqu, (char *)pmkcand); A_FREE(pmkcand); @@ -5302,9 +5302,9 @@ ar6000_bssInfo_event_rx(AR_SOFTC_T *ar, u8 *datap, int len) if ((skb = A_NETBUF_ALLOC_RAW(len)) != NULL) { A_NETBUF_PUT(skb, len); - A_MEMCPY(A_NETBUF_DATA(skb), datap, len); + memcpy(A_NETBUF_DATA(skb), datap, len); skb->dev = ar->arNetDev; - A_MEMCPY(skb_mac_header(skb), A_NETBUF_DATA(skb), 6); + memcpy(skb_mac_header(skb), A_NETBUF_DATA(skb), 6); skb->ip_summed = CHECKSUM_NONE; skb->pkt_type = PACKET_OTHERHOST; skb->protocol = __constant_htons(0x0019); @@ -5468,19 +5468,19 @@ ar6000_btcoex_config_event(struct ar6_softc *ar, u8 *ptr, u32 len) switch (pBtcoexConfig->btProfileType) { case WMI_BTCOEX_BT_PROFILE_SCO: - A_MEMCPY(&pArbtcoexConfig->info.scoConfigCmd, &pBtcoexConfig->info.scoConfigCmd, + memcpy(&pArbtcoexConfig->info.scoConfigCmd, &pBtcoexConfig->info.scoConfigCmd, sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD)); break; case WMI_BTCOEX_BT_PROFILE_A2DP: - A_MEMCPY(&pArbtcoexConfig->info.a2dpConfigCmd, &pBtcoexConfig->info.a2dpConfigCmd, + memcpy(&pArbtcoexConfig->info.a2dpConfigCmd, &pBtcoexConfig->info.a2dpConfigCmd, sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD)); break; case WMI_BTCOEX_BT_PROFILE_ACLCOEX: - A_MEMCPY(&pArbtcoexConfig->info.aclcoexConfig, &pBtcoexConfig->info.aclcoexConfig, + memcpy(&pArbtcoexConfig->info.aclcoexConfig, &pBtcoexConfig->info.aclcoexConfig, sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD)); break; case WMI_BTCOEX_BT_PROFILE_INQUIRY_PAGE: - A_MEMCPY(&pArbtcoexConfig->info.btinquiryPageConfigCmd, &pBtcoexConfig->info.btinquiryPageConfigCmd, + memcpy(&pArbtcoexConfig->info.btinquiryPageConfigCmd, &pBtcoexConfig->info.btinquiryPageConfigCmd, sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD)); break; } @@ -5497,7 +5497,7 @@ ar6000_btcoex_stats_event(struct ar6_softc *ar, u8 *ptr, u32 len) AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 BTCOEX CONFIG EVENT \n")); - A_MEMCPY(&ar->arBtcoexStats, pBtcoexStats, sizeof(WMI_BTCOEX_STATS_EVENT)); + memcpy(&ar->arBtcoexStats, pBtcoexStats, sizeof(WMI_BTCOEX_STATS_EVENT)); if (ar->statsUpdatePending) { ar->statsUpdatePending = false; @@ -5596,8 +5596,8 @@ void ar6000_send_event_to_app(AR_SOFTC_T *ar, u16 eventId, } A_MEMZERO(buf, size); - A_MEMCPY(buf, &eventId, EVENT_ID_LEN); - A_MEMCPY(buf+EVENT_ID_LEN, datap, len); + memcpy(buf, &eventId, EVENT_ID_LEN); + memcpy(buf+EVENT_ID_LEN, datap, len); //AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("event ID = %d,len = %d\n",*(u16 *)buf, size)); A_MEMZERO(&wrqu, sizeof(wrqu)); @@ -5641,8 +5641,8 @@ void ar6000_send_generic_event_to_app(AR_SOFTC_T *ar, u16 eventId, } A_MEMZERO(buf, size); - A_MEMCPY(buf, &eventId, EVENT_ID_LEN); - A_MEMCPY(buf+EVENT_ID_LEN, datap, len); + memcpy(buf, &eventId, EVENT_ID_LEN); + memcpy(buf+EVENT_ID_LEN, datap, len); A_MEMZERO(&wrqu, sizeof(wrqu)); wrqu.data.length = size; @@ -5989,7 +5989,7 @@ void ap_wapi_rekey_event(AR_SOFTC_T *ar, u8 type, u8 *mac) strcpy(buf, "WAPI_REKEY"); buf[10] = type; - A_MEMCPY(&buf[11], mac, ATH_MAC_LEN); + memcpy(&buf[11], mac, ATH_MAC_LEN); A_MEMZERO(&wrqu, sizeof(wrqu)); wrqu.data.length = 10+1+ATH_MAC_LEN; @@ -6121,7 +6121,7 @@ ar6000_ap_mode_profile_commit(struct ar6_softc *ar) A_MEMZERO(&p,sizeof(p)); p.ssidLength = ar->arSsidLen; - A_MEMCPY(p.ssid,ar->arSsid,p.ssidLength); + memcpy(p.ssid,ar->arSsid,p.ssidLength); p.channel = ar->arChannelHint; p.networkType = ar->arNetworkType; @@ -6238,7 +6238,7 @@ ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie A_MEMZERO(wpaie->rsn_ie, IEEE80211_MAX_IE); if(conn) { - A_MEMCPY(wpaie->wpa_ie, conn->wpa_ie, IEEE80211_MAX_IE); + memcpy(wpaie->wpa_ie, conn->wpa_ie, IEEE80211_MAX_IE); } return 0; @@ -6453,7 +6453,7 @@ int ar6000_create_ap_interface(AR_SOFTC_T *ar, char *ap_ifname) arApNetDev = dev; /* Copy the MAC address */ - A_MEMCPY(dev->dev_addr, ar->arNetDev->dev_addr, AR6000_ETH_ADDR_LEN); + memcpy(dev->dev_addr, ar->arNetDev->dev_addr, AR6000_ETH_ADDR_LEN); return 0; } diff --git a/drivers/staging/ath6kl/os/linux/ar6k_pal.c b/drivers/staging/ath6kl/os/linux/ar6k_pal.c index 831b2e3cf9c8..fee7cb945e24 100644 --- a/drivers/staging/ath6kl/os/linux/ar6k_pal.c +++ b/drivers/staging/ath6kl/os/linux/ar6k_pal.c @@ -215,7 +215,7 @@ static int btpal_send_frame(struct sk_buff *skb) bt_cb(txSkb)->pkt_type = bt_cb(skb)->pkt_type; txSkb->dev = (void *)pHciPalInfo->hdev; skb_reserve(txSkb, TX_PACKET_RSV_OFFSET + WMI_MAX_TX_META_SZ + sizeof(WMI_DATA_HDR)); - A_MEMCPY(txSkb->data, skb->data, skb->len); + memcpy(txSkb->data, skb->data, skb->len); skb_put(txSkb,skb->len); /* Add WMI packet type */ osbuf = (void *)txSkb; diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index 20b08c089dfc..415b2535502b 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -324,7 +324,7 @@ ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); ar->arSsidLen = sme->ssid_len; - A_MEMCPY(ar->arSsid, sme->ssid, sme->ssid_len); + memcpy(ar->arSsid, sme->ssid, sme->ssid_len); if(sme->channel){ ar->arChannelHint = sme->channel->center_freq; @@ -333,7 +333,7 @@ ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); if(sme->bssid){ if(A_MEMCMP(&sme->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) { - A_MEMCPY(ar->arReqBssid, sme->bssid, sizeof(ar->arReqBssid)); + memcpy(ar->arReqBssid, sme->bssid, sizeof(ar->arReqBssid)); } } @@ -365,7 +365,7 @@ ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, key = &ar->keys[sme->key_idx]; key->key_len = sme->key_len; - A_MEMCPY(key->key, sme->key, key->key_len); + memcpy(key->key, sme->key, key->key_len); key->cipher = ar->arPairwiseCrypto; ar->arDefTxKeyIndex = sme->key_idx; @@ -493,7 +493,7 @@ ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, u16 channel, if(ptr_ie_buf) { *ptr_ie_buf++ = WLAN_EID_SSID; *ptr_ie_buf++ = ar->arSsidLen; - A_MEMCPY(ptr_ie_buf, ar->arSsid, ar->arSsidLen); + memcpy(ptr_ie_buf, ar->arSsid, ar->arSsidLen); ptr_ie_buf +=ar->arSsidLen; *ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS; @@ -511,11 +511,11 @@ ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, u16 channel, if(WEP_CRYPT == ar->arPairwiseCrypto) { capability |= IEEE80211_CAPINFO_PRIVACY; } - A_MEMCPY(source_mac, ar->arNetDev->dev_addr, ATH_MAC_LEN); + memcpy(source_mac, ar->arNetDev->dev_addr, ATH_MAC_LEN); ptr_ie_buf = ie_buf; } else { capability = *(u16 *)(&assocInfo[beaconIeLen]); - A_MEMCPY(source_mac, bssid, ATH_MAC_LEN); + memcpy(source_mac, bssid, ATH_MAC_LEN); ptr_ie_buf = assocReqIe; ie_buf_len = assocReqLen; } @@ -534,12 +534,12 @@ ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, u16 channel, A_MEMZERO(ieeemgmtbuf, size); mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf; mgmt->frame_control = (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); - A_MEMCPY(mgmt->da, bcast_mac, ATH_MAC_LEN); - A_MEMCPY(mgmt->sa, source_mac, ATH_MAC_LEN); - A_MEMCPY(mgmt->bssid, bssid, ATH_MAC_LEN); + memcpy(mgmt->da, bcast_mac, ATH_MAC_LEN); + memcpy(mgmt->sa, source_mac, ATH_MAC_LEN); + memcpy(mgmt->bssid, bssid, ATH_MAC_LEN); mgmt->u.beacon.beacon_int = beaconInterval; mgmt->u.beacon.capab_info = capability; - A_MEMCPY(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len); + memcpy(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len); ibss_channel = ieee80211_get_channel(ar->wdev->wiphy, (int)channel); @@ -712,10 +712,10 @@ ar6k_cfg80211_scan_node(void *arg, bss_t *ni) cfg80211 needs it, for time being just filling the da, sa and bssid fields alone. */ mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf; - A_MEMCPY(mgmt->da, bcast_mac, ATH_MAC_LEN); - A_MEMCPY(mgmt->sa, ni->ni_macaddr, ATH_MAC_LEN); - A_MEMCPY(mgmt->bssid, ni->ni_macaddr, ATH_MAC_LEN); - A_MEMCPY(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u), + memcpy(mgmt->da, bcast_mac, ATH_MAC_LEN); + memcpy(mgmt->sa, ni->ni_macaddr, ATH_MAC_LEN); + memcpy(mgmt->bssid, ni->ni_macaddr, ATH_MAC_LEN); + memcpy(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u), ni->ni_buf, ni->ni_framelen); freq = cie->ie_chan; @@ -862,9 +862,9 @@ ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, return -EINVAL; key->key_len = params->key_len; - A_MEMCPY(key->key, params->key, key->key_len); + memcpy(key->key, params->key, key->key_len); key->seq_len = params->seq_len; - A_MEMCPY(key->seq, params->seq, key->seq_len); + memcpy(key->seq, params->seq, key->seq_len); key->cipher = params->cipher; } @@ -1307,7 +1307,7 @@ ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, } ar->arSsidLen = ibss_param->ssid_len; - A_MEMCPY(ar->arSsid, ibss_param->ssid, ar->arSsidLen); + memcpy(ar->arSsid, ibss_param->ssid, ar->arSsidLen); if(ibss_param->channel) { ar->arChannelHint = ibss_param->channel->center_freq; @@ -1322,7 +1322,7 @@ ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); if(ibss_param->bssid) { if(A_MEMCMP(&ibss_param->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) { - A_MEMCPY(ar->arReqBssid, ibss_param->bssid, sizeof(ar->arReqBssid)); + memcpy(ar->arReqBssid, ibss_param->bssid, sizeof(ar->arReqBssid)); } } diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index f170382c13a0..db38bbfb2a2d 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -226,7 +226,7 @@ static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle, pHcidevInfo->pHCIDev = HCIHandle; - A_MEMCPY(&pHcidevInfo->HCIProps,pProps,sizeof(*pProps)); + memcpy(&pHcidevInfo->HCIProps,pProps,sizeof(*pProps)); AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE,("HCI ready (hci:0x%lX, headroom:%d, tailroom:%d blockpad:%d) \n", (unsigned long)HCIHandle, @@ -778,7 +778,7 @@ static int bt_send_frame(struct sk_buff *skb) bt_cb(txSkb)->pkt_type = bt_cb(skb)->pkt_type; txSkb->dev = (void *)pHcidevInfo->pBtStackHCIDev; skb_reserve(txSkb, TX_PACKET_RSV_OFFSET + pHcidevInfo->HCIProps.HeadRoom); - A_MEMCPY(txSkb->data, skb->data, skb->len); + memcpy(txSkb->data, skb->data, skb->len); skb_put(txSkb,skb->len); pPacket = AllocHTCStruct(pHcidevInfo); diff --git a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h index 1957de07b714..cdb4195d5df7 100644 --- a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h @@ -76,7 +76,6 @@ #define A_CPU2BE16(x) htons(x) #define A_CPU2BE32(x) htonl(x) -#define A_MEMCPY(dst, src, len) memcpy((u8 *)(dst), (src), (len)) #define A_MEMZERO(addr, len) memset(addr, 0, len) #define A_MEMCMP(addr1, addr2, len) memcmp((addr1), (addr2), (len)) #define A_MALLOC(size) kmalloc((size), GFP_KERNEL) @@ -364,7 +363,6 @@ static inline void *A_ALIGN_TO_CACHE_LINE(void *ptr) { #define PREPACK #define POSTPACK __ATTRIB_PACK -#define A_MEMCPY(dst, src, len) memcpy((dst), (src), (len)) #define A_MEMZERO(addr, len) memset((addr), 0, (len)) #define A_MEMCMP(addr1, addr2, len) memcmp((addr1), (addr2), (len)) #define A_MALLOC(size) malloc(size) diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index 4f30b255fc1a..9a7f920c26b9 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -281,7 +281,7 @@ ar6000_ioctl_set_country(struct net_device *dev, struct ifreq *rq) ar->ap_profile_flag = 1; /* There is a change in profile */ ret = wmi_set_country(ar->arWmi, cmd.countryCode); - A_MEMCPY(ar->ap_country_code, cmd.countryCode, 3); + memcpy(ar->ap_country_code, cmd.countryCode, 3); switch (ret) { case 0: @@ -430,7 +430,7 @@ ar6000_ioctl_set_rssi_threshold(struct net_device *dev, struct ifreq *rq) cmd.weight = rssiParams.weight; cmd.pollTime = rssiParams.pollTime; - A_MEMCPY(ar->rssi_map, &rssiParams.tholds, sizeof(ar->rssi_map)); + memcpy(ar->rssi_map, &rssiParams.tholds, sizeof(ar->rssi_map)); /* * only 6 elements, so use bubble sorting, in ascending order */ @@ -702,8 +702,8 @@ ar6000_ioctl_tcmd_get_rx_report(struct net_device *dev, buf[1] = ar->tcmdRxRssi; buf[2] = ar->tcmdRxcrcErrPkt; buf[3] = ar->tcmdRxsecErrPkt; - A_MEMCPY(((A_UCHAR *)buf)+(4*sizeof(u32)), ar->tcmdRateCnt, sizeof(ar->tcmdRateCnt)); - A_MEMCPY(((A_UCHAR *)buf)+(4*sizeof(u32))+(TCMD_MAX_RATES *sizeof(u16)), ar->tcmdRateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard)); + memcpy(((A_UCHAR *)buf)+(4*sizeof(u32)), ar->tcmdRateCnt, sizeof(ar->tcmdRateCnt)); + memcpy(((A_UCHAR *)buf)+(4*sizeof(u32))+(TCMD_MAX_RATES *sizeof(u16)), ar->tcmdRateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard)); if (!ret && copy_to_user(rq->ifr_data, buf, sizeof(buf))) { ret = -EFAULT; @@ -732,8 +732,8 @@ ar6000_tcmd_rx_report_event(void *devt, u8 *results, int len) ar->tcmdRxReport = 1; A_MEMZERO(ar->tcmdRateCnt, sizeof(ar->tcmdRateCnt)); A_MEMZERO(ar->tcmdRateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard)); - A_MEMCPY(ar->tcmdRateCnt, rx_rep->u.report.rateCnt, sizeof(ar->tcmdRateCnt)); - A_MEMCPY(ar->tcmdRateCntShortGuard, rx_rep->u.report.rateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard)); + memcpy(ar->tcmdRateCnt, rx_rep->u.report.rateCnt, sizeof(ar->tcmdRateCnt)); + memcpy(ar->tcmdRateCntShortGuard, rx_rep->u.report.rateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard)); wake_up(&arEvent); } @@ -1523,7 +1523,7 @@ ar6000_create_acl_data_osbuf(struct net_device *dev, u8 *userdata, void **p_osbu /* Real copy to osbuf */ acl = (HCI_ACL_DATA_PKT *)(datap); - A_MEMCPY(acl, tmp_space, hdr_size); + memcpy(acl, tmp_space, hdr_size); if (a_copy_from_user(acl->data, userdata + hdr_size, acl->data_len)) { ret = A_EFAULT; break; @@ -1770,7 +1770,7 @@ ar6000_ioctl_setkey(AR_SOFTC_T *ar, struct ieee80211req_key *ik) (0 == memcmp(ik->ik_macaddr, bcast_mac, IEEE80211_ADDR_LEN)) ) { keyUsage = GROUP_USAGE; if(ar->arNextMode == AP_NETWORK) { - A_MEMCPY(&ar->ap_mode_bkey, ik, + memcpy(&ar->ap_mode_bkey, ik, sizeof(struct ieee80211req_key)); #ifdef WAPI_ENABLE if(ar->arPairwiseCrypto == WAPI_CRYPT) { @@ -1779,13 +1779,13 @@ ar6000_ioctl_setkey(AR_SOFTC_T *ar, struct ieee80211req_key *ik) #endif } #ifdef USER_KEYS - A_MEMCPY(&ar->user_saved_keys.bcast_ik, ik, + memcpy(&ar->user_saved_keys.bcast_ik, ik, sizeof(struct ieee80211req_key)); #endif } else { keyUsage = PAIRWISE_USAGE; #ifdef USER_KEYS - A_MEMCPY(&ar->user_saved_keys.ucast_ik, ik, + memcpy(&ar->user_saved_keys.ucast_ik, ik, sizeof(struct ieee80211req_key)); #endif #ifdef WAPI_ENABLE @@ -1827,7 +1827,7 @@ ar6000_ioctl_setkey(AR_SOFTC_T *ar, struct ieee80211req_key *ik) A_MEMZERO(ar->arWepKeyList[index].arKey, sizeof(ar->arWepKeyList[index].arKey)); - A_MEMCPY(ar->arWepKeyList[index].arKey, ik->ik_keydata, ik->ik_keylen); + memcpy(ar->arWepKeyList[index].arKey, ik->ik_keydata, ik->ik_keylen); ar->arWepKeyList[index].arKeyLen = ik->ik_keylen; if(ik->ik_flags & IEEE80211_KEY_DEFAULT){ @@ -3133,7 +3133,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ret = -EFAULT; } else { - A_MEMCPY(ar->arReqBssid, adhocBssid.bssid, sizeof(ar->arReqBssid)); + memcpy(ar->arReqBssid, adhocBssid.bssid, sizeof(ar->arReqBssid)); } break; } @@ -4114,7 +4114,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ap_get_sta_t temp; A_MEMZERO(&temp, sizeof(temp)); for(i=0;ista_list[i].mac, ATH_MAC_LEN); + memcpy(temp.sta[i].mac, ar->sta_list[i].mac, ATH_MAC_LEN); temp.sta[i].aid = ar->sta_list[i].aid; temp.sta[i].keymgmt = ar->sta_list[i].keymgmt; temp.sta[i].ucipher = ar->sta_list[i].ucipher; @@ -4526,7 +4526,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_AP_GET_COUNTRY: { WMI_AP_SET_COUNTRY_CMD cty; - A_MEMCPY(cty.countryCode, ar->ap_country_code, 3); + memcpy(cty.countryCode, ar->ap_country_code, 3); if (ar->arWmiReady == false) { ret = -EIO; @@ -4743,7 +4743,7 @@ u8 acl_add_del_mac(WMI_AP_ACL *a, WMI_AP_ACL_MAC_CMD *acl) if((already_avail >= 0) || (free_slot == -1)) return 0; - A_MEMCPY(a->acl_mac[free_slot], acl->mac, ATH_MAC_LEN); + memcpy(a->acl_mac[free_slot], acl->mac, ATH_MAC_LEN); a->index = a->index | (1 << free_slot); acl->index = free_slot; a->wildcard[free_slot] = acl->wildcard; diff --git a/drivers/staging/ath6kl/os/linux/netbuf.c b/drivers/staging/ath6kl/os/linux/netbuf.c index 0a41df03a8b4..63acedf8e3af 100644 --- a/drivers/staging/ath6kl/os/linux/netbuf.c +++ b/drivers/staging/ath6kl/os/linux/netbuf.c @@ -120,7 +120,7 @@ int a_netbuf_push_data(void *bufPtr, char *srcPtr, s32 len) { skb_push((struct sk_buff *) bufPtr, len); - A_MEMCPY(((struct sk_buff *)bufPtr)->data, srcPtr, len); + memcpy(((struct sk_buff *)bufPtr)->data, srcPtr, len); return 0; } @@ -147,7 +147,7 @@ a_netbuf_put_data(void *bufPtr, char *srcPtr, s32 len) char *start = (char*)(((struct sk_buff *)bufPtr)->data + ((struct sk_buff *)bufPtr)->len); skb_put((struct sk_buff *)bufPtr, len); - A_MEMCPY(start, srcPtr, len); + memcpy(start, srcPtr, len); return 0; } @@ -184,7 +184,7 @@ a_netbuf_trim_data(void *bufPtr, char *dstPtr, s32 len) char *start = (char*)(((struct sk_buff *)bufPtr)->data + (((struct sk_buff *)bufPtr)->len - len)); - A_MEMCPY(dstPtr, start, len); + memcpy(dstPtr, start, len); skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len); return 0; @@ -217,7 +217,7 @@ a_netbuf_pull(void *bufPtr, s32 len) int a_netbuf_pull_data(void *bufPtr, char *dstPtr, s32 len) { - A_MEMCPY(dstPtr, ((struct sk_buff *)bufPtr)->data, len); + memcpy(dstPtr, ((struct sk_buff *)bufPtr)->data, len); skb_pull((struct sk_buff *)bufPtr, len); return 0; diff --git a/drivers/staging/ath6kl/os/linux/wireless_ext.c b/drivers/staging/ath6kl/os/linux/wireless_ext.c index baa86633b2a0..8262fde1c6fa 100644 --- a/drivers/staging/ath6kl/os/linux/wireless_ext.c +++ b/drivers/staging/ath6kl/os/linux/wireless_ext.c @@ -112,7 +112,7 @@ ar6000_scan_node(void *arg, bss_t *ni) A_MEMZERO(&iwe, sizeof(iwe)); iwe.cmd = SIOCGIWAP; iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - A_MEMCPY(iwe.u.ap_addr.sa_data, ni->ni_macaddr, 6); + memcpy(iwe.u.ap_addr.sa_data, ni->ni_macaddr, 6); current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); } @@ -506,7 +506,7 @@ ar6000_ioctl_siwessid(struct net_device *dev, /* SSID change for AP network - Will take effect on commit */ if(A_MEMCMP(ar->arSsid,ssid,32) != 0) { ar->arSsidLen = data->length - 1; - A_MEMCPY(ar->arSsid, ssid, ar->arSsidLen); + memcpy(ar->arSsid, ssid, ar->arSsidLen); ar->ap_profile_flag = 1; /* There is a change in profile */ } return 0; @@ -641,7 +641,7 @@ ar6000_ioctl_siwessid(struct net_device *dev, } ar->arSsidLen = data->length - 1; - A_MEMCPY(ar->arSsid, ssid, ar->arSsidLen); + memcpy(ar->arSsid, ssid, ar->arSsidLen); if (ar6000_connect_to_ap(ar)!= 0) { up(&ar->arSem); @@ -675,7 +675,7 @@ ar6000_ioctl_giwessid(struct net_device *dev, data->flags = 1; data->length = ar->arSsidLen; - A_MEMCPY(essid, ar->arSsid, ar->arSsidLen); + memcpy(essid, ar->arSsid, ar->arSsidLen); return 0; } @@ -1080,7 +1080,7 @@ ar6000_ioctl_siwencode(struct net_device *dev, A_MEMZERO(ar->arWepKeyList[index].arKey, sizeof(ar->arWepKeyList[index].arKey)); - A_MEMCPY(ar->arWepKeyList[index].arKey, keybuf, erq->length); + memcpy(ar->arWepKeyList[index].arKey, keybuf, erq->length); ar->arWepKeyList[index].arKeyLen = erq->length; ar->arDot11AuthMode = auth; } else { @@ -1158,14 +1158,14 @@ ar6000_ioctl_giwencode(struct net_device *dev, erq->length = wk->arKeyLen; } if (wk->arKeyLen) { - A_MEMCPY(key, wk->arKey, erq->length); + memcpy(key, wk->arKey, erq->length); } } else { erq->flags &= ~IW_ENCODE_DISABLED; if (ar->user_saved_keys.keyOk) { erq->length = ar->user_saved_keys.ucast_ik.ik_keylen; if (erq->length) { - A_MEMCPY(key, ar->user_saved_keys.ucast_ik.ik_keydata, erq->length); + memcpy(key, ar->user_saved_keys.ucast_ik.ik_keydata, erq->length); } } else { erq->length = 1; // not really printing any key but let iwconfig know enc is on @@ -1616,7 +1616,7 @@ static int ar6000_set_wapi_key(struct net_device *dev, } keyData = (u8 *)(ext + 1); keyLen = erq->length - sizeof(struct iw_encode_ext); - A_MEMCPY(wapiKeyRsc, ext->tx_seq, sizeof(wapiKeyRsc)); + memcpy(wapiKeyRsc, ext->tx_seq, sizeof(wapiKeyRsc)); if (A_MEMCMP(ext->addr.sa_data, broadcastMac, sizeof(broadcastMac)) == 0) { keyUsage |= GROUP_USAGE; @@ -1737,7 +1737,7 @@ ar6000_ioctl_siwencodeext(struct net_device *dev, if (!ar->arConnected) { A_MEMZERO(ar->arWepKeyList[index].arKey, sizeof(ar->arWepKeyList[index].arKey)); - A_MEMCPY(ar->arWepKeyList[index].arKey, keyData, keyLen); + memcpy(ar->arWepKeyList[index].arKey, keyData, keyLen); ar->arWepKeyList[index].arKeyLen = keyLen; return 0; @@ -1778,7 +1778,7 @@ ar6000_ioctl_siwencodeext(struct net_device *dev, } if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { - A_MEMCPY(keyRsc, ext->rx_seq, sizeof(keyRsc)); + memcpy(keyRsc, ext->rx_seq, sizeof(keyRsc)); } else { A_MEMZERO(keyRsc, sizeof(keyRsc)); } @@ -2318,7 +2318,7 @@ ar6000_ioctl_siwap(struct net_device *dev, if (A_MEMCMP(&ap_addr->sa_data, bcast_mac, AR6000_ETH_ADDR_LEN) == 0) { A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); } else { - A_MEMCPY(ar->arReqBssid, &ap_addr->sa_data, sizeof(ar->arReqBssid)); + memcpy(ar->arReqBssid, &ap_addr->sa_data, sizeof(ar->arReqBssid)); } return 0; @@ -2344,7 +2344,7 @@ ar6000_ioctl_giwap(struct net_device *dev, } if (ar->arNetworkType == AP_NETWORK) { - A_MEMCPY(&ap_addr->sa_data, dev->dev_addr, ATH_MAC_LEN); + memcpy(&ap_addr->sa_data, dev->dev_addr, ATH_MAC_LEN); ap_addr->sa_family = ARPHRD_ETHER; return 0; } @@ -2353,7 +2353,7 @@ ar6000_ioctl_giwap(struct net_device *dev, return -EINVAL; } - A_MEMCPY(&ap_addr->sa_data, ar->arBssid, sizeof(ar->arBssid)); + memcpy(&ap_addr->sa_data, ar->arBssid, sizeof(ar->arBssid)); ap_addr->sa_family = ARPHRD_ETHER; return 0; diff --git a/drivers/staging/ath6kl/reorder/rcv_aggr.c b/drivers/staging/ath6kl/reorder/rcv_aggr.c index 5cb4413fbd67..adb85eb0412d 100644 --- a/drivers/staging/ath6kl/reorder/rcv_aggr.c +++ b/drivers/staging/ath6kl/reorder/rcv_aggr.c @@ -397,7 +397,7 @@ aggr_slice_amsdu(AGGR_INFO *p_aggr, RXTID *rxtid, void **osbuf) break; } - A_MEMCPY(A_NETBUF_DATA(new_buf), framep, frame_8023_len); + memcpy(A_NETBUF_DATA(new_buf), framep, frame_8023_len); A_NETBUF_PUT(new_buf, frame_8023_len); if (wmi_dot3_2_dix(new_buf) != 0) { A_PRINTF("dot3_2_dix err..\n"); diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211.h b/drivers/staging/ath6kl/wlan/include/ieee80211.h index 0b5441f6159b..dfad19ac74fd 100644 --- a/drivers/staging/ath6kl/wlan/include/ieee80211.h +++ b/drivers/staging/ath6kl/wlan/include/ieee80211.h @@ -70,7 +70,7 @@ #define IEEE80211_ADDR_EQ(addr1, addr2) \ (A_MEMCMP(addr1, addr2, IEEE80211_ADDR_LEN) == 0) -#define IEEE80211_ADDR_COPY(dst,src) A_MEMCPY(dst,src,IEEE80211_ADDR_LEN) +#define IEEE80211_ADDR_COPY(dst,src) memcpy(dst,src,IEEE80211_ADDR_LEN) #define IEEE80211_KEYBUF_SIZE 16 #define IEEE80211_MICBUF_SIZE (8+8) /* space for both tx and rx */ diff --git a/drivers/staging/ath6kl/wlan/src/wlan_node.c b/drivers/staging/ath6kl/wlan/src/wlan_node.c index d61cb6ea894e..c99a330ac00d 100644 --- a/drivers/staging/ath6kl/wlan/src/wlan_node.c +++ b/drivers/staging/ath6kl/wlan/src/wlan_node.c @@ -116,7 +116,7 @@ wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni, int hash; u32 timeoutValue = 0; - A_MEMCPY(ni->ni_macaddr, macaddr, IEEE80211_ADDR_LEN); + memcpy(ni->ni_macaddr, macaddr, IEEE80211_ADDR_LEN); hash = IEEE80211_NODE_HASH (macaddr); ieee80211_node_initref (ni); /* mark referenced */ diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index acbf6ed3caf8..bf9dd0bd3af3 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -422,8 +422,8 @@ wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf) /* * Save mac fields and length to be inserted later */ - A_MEMCPY(macHdr.dstMac, datap, ATH_MAC_LEN); - A_MEMCPY(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN); + memcpy(macHdr.dstMac, datap, ATH_MAC_LEN); + memcpy(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN); macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR)); @@ -435,7 +435,7 @@ wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf) } datap = A_NETBUF_DATA(osbuf); - A_MEMCPY(datap, &macHdr, sizeof (ATH_MAC_HDR)); + memcpy(datap, &macHdr, sizeof (ATH_MAC_HDR)); llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR)); llcHdr->dsap = 0xAA; @@ -484,7 +484,7 @@ int wmi_meta_add(struct wmi_t *wmip, void *osbuf, u8 *pVersion,void *pTxMetaS) return A_NO_MEMORY; } pV2 = (WMI_TX_META_V2 *)A_NETBUF_DATA(osbuf); - A_MEMCPY(pV2,(WMI_TX_META_V2 *)pTxMetaS,sizeof(WMI_TX_META_V2)); + memcpy(pV2,(WMI_TX_META_V2 *)pTxMetaS,sizeof(WMI_TX_META_V2)); return (0); } #endif @@ -654,8 +654,8 @@ wmi_dot11_hdr_add (struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode) /* * Save mac fields and length to be inserted later */ - A_MEMCPY(macHdr.dstMac, datap, ATH_MAC_LEN); - A_MEMCPY(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN); + memcpy(macHdr.dstMac, datap, ATH_MAC_LEN); + memcpy(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN); macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR)); @@ -730,7 +730,7 @@ wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf) type = pwh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; subtype = pwh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; - A_MEMCPY((u8 *)&wh, datap, sizeof(struct ieee80211_frame)); + memcpy((u8 *)&wh, datap, sizeof(struct ieee80211_frame)); /* strip off the 802.11 hdr*/ if (subtype == IEEE80211_FC0_SUBTYPE_QOS) { @@ -772,7 +772,7 @@ wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf) A_NETBUF_PUSH(osbuf, sizeof(ATH_MAC_HDR)); datap = A_NETBUF_DATA(osbuf); - A_MEMCPY (datap, &macHdr, sizeof(ATH_MAC_HDR)); + memcpy (datap, &macHdr, sizeof(ATH_MAC_HDR)); return 0; } @@ -791,7 +791,7 @@ wmi_dot3_2_dix(void *osbuf) A_ASSERT(osbuf != NULL); datap = A_NETBUF_DATA(osbuf); - A_MEMCPY(&macHdr, datap, sizeof(ATH_MAC_HDR)); + memcpy(&macHdr, datap, sizeof(ATH_MAC_HDR)); llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR)); macHdr.typeOrLen = llcHdr->etherType; @@ -801,7 +801,7 @@ wmi_dot3_2_dix(void *osbuf) datap = A_NETBUF_DATA(osbuf); - A_MEMCPY(datap, &macHdr, sizeof (ATH_MAC_HDR)); + memcpy(datap, &macHdr, sizeof (ATH_MAC_HDR)); return (0); } @@ -999,7 +999,7 @@ wmi_control_rx(struct wmi_t *wmip, void *osbuf) */ WMI_BSS_INFO_HDR2 bih2; WMI_BSS_INFO_HDR *bih; - A_MEMCPY(&bih2, datap, sizeof(WMI_BSS_INFO_HDR2)); + memcpy(&bih2, datap, sizeof(WMI_BSS_INFO_HDR2)); A_NETBUF_PUSH(osbuf, 4); datap = A_NETBUF_DATA(osbuf); @@ -1011,7 +1011,7 @@ wmi_control_rx(struct wmi_t *wmip, void *osbuf) bih->snr = bih2.snr; bih->rssi = bih2.snr - 95; bih->ieMask = bih2.ieMask; - A_MEMCPY(bih->bssid, bih2.bssid, ATH_MAC_LEN); + memcpy(bih->bssid, bih2.bssid, ATH_MAC_LEN); status = wmi_bssInfo_event_rx(wmip, datap, len); A_WMI_SEND_GENERIC_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); @@ -1275,7 +1275,7 @@ wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap, int len) ev->bssid[0], ev->bssid[1], ev->bssid[2], ev->bssid[3], ev->bssid[4], ev->bssid[5])); - A_MEMCPY(wmip->wmi_bssid, ev->bssid, ATH_MAC_LEN); + memcpy(wmip->wmi_bssid, ev->bssid, ATH_MAC_LEN); /* initialize pointer to start of assoc rsp IEs */ pie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen + @@ -1538,7 +1538,7 @@ wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len) /* copy the first 14 bytes such as * time-stamp(8), beacon-interval(2), cap-info(2), ssid-id(1), ssid-len(1). */ - A_MEMCPY(ni_buf, buf, SSID_IE_LEN_INDEX + 1); + memcpy(ni_buf, buf, SSID_IE_LEN_INDEX + 1); ni_buf[SSID_IE_LEN_INDEX] = cached_ssid_len; ni_buf += (SSID_IE_LEN_INDEX + 1); @@ -1547,7 +1547,7 @@ wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len) buf_len -= (SSID_IE_LEN_INDEX + 1); /* copy the cached ssid */ - A_MEMCPY(ni_buf, cached_ssid_buf, cached_ssid_len); + memcpy(ni_buf, cached_ssid_buf, cached_ssid_len); ni_buf += cached_ssid_len; buf += beacon_ssid_len; @@ -1557,10 +1557,10 @@ wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len) buf_len -= (cached_ssid_len - beacon_ssid_len); /* now copy the rest of bytes */ - A_MEMCPY(ni_buf, buf, buf_len); + memcpy(ni_buf, buf, buf_len); } else - A_MEMCPY(bss->ni_buf, buf, len); + memcpy(bss->ni_buf, buf, len); bss->ni_framelen = len; if (wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie) != 0) { @@ -1614,7 +1614,7 @@ wmi_opt_frame_event_rx(struct wmi_t *wmip, u8 *datap, int len) bss->ni_snr = bih->snr; bss->ni_cie.ie_chan = bih->channel; A_ASSERT(bss->ni_buf != NULL); - A_MEMCPY(bss->ni_buf, buf, len); + memcpy(bss->ni_buf, buf, len); wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid); return 0; @@ -2446,7 +2446,7 @@ wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType, if (ssidLength) { - A_MEMCPY(cc->ssid, ssid, ssidLength); + memcpy(cc->ssid, ssid, ssidLength); } cc->ssidLength = ssidLength; @@ -2461,7 +2461,7 @@ wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType, cc->ctrl_flags = ctrl_flags; if (bssid != NULL) { - A_MEMCPY(cc->bssid, bssid, ATH_MAC_LEN); + memcpy(cc->bssid, bssid, ATH_MAC_LEN); } wmip->wmi_pair_crypto_type = pairwiseCrypto; @@ -2490,7 +2490,7 @@ wmi_reconnect_cmd(struct wmi_t *wmip, u8 *bssid, u16 channel) cc->channel = channel; if (bssid != NULL) { - A_MEMCPY(cc->bssid, bssid, ATH_MAC_LEN); + memcpy(cc->bssid, bssid, ATH_MAC_LEN); } return (wmi_cmd_send(wmip, osbuf, WMI_RECONNECT_CMDID, NO_SYNC_WMIFLAG)); @@ -2547,7 +2547,7 @@ wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, sc->forceScanInterval = forceScanInterval; sc->numChannels = numChan; if (numChan) { - A_MEMCPY(sc->channelList, channelList, numChan * sizeof(u16)); + memcpy(sc->channelList, channelList, numChan * sizeof(u16)); } return (wmi_cmd_send(wmip, osbuf, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG)); @@ -2650,7 +2650,7 @@ wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag, cmd->entryIndex = index; cmd->flag = flag; cmd->ssidLength = ssidLength; - A_MEMCPY(cmd->ssid, ssid, ssidLength); + memcpy(cmd->ssid, ssid, ssidLength); return (wmi_cmd_send(wmip, osbuf, WMI_SET_PROBED_SSID_CMDID, NO_SYNC_WMIFLAG)); @@ -2720,7 +2720,7 @@ wmi_associnfo_cmd(struct wmi_t *wmip, u8 ieType, A_MEMZERO(cmd, cmdLen); cmd->ieType = ieType; cmd->bufferSize = ieLen; - A_MEMCPY(cmd->assocInfo, ieInfo, ieLen); + memcpy(cmd->assocInfo, ieInfo, ieLen); return (wmi_cmd_send(wmip, osbuf, WMI_SET_ASSOC_INFO_CMDID, NO_SYNC_WMIFLAG)); @@ -2880,18 +2880,18 @@ wmi_addKey_cmd(struct wmi_t *wmip, u8 keyIndex, CRYPTO_TYPE keyType, cmd->keyType = keyType; cmd->keyUsage = keyUsage; cmd->keyLength = keyLength; - A_MEMCPY(cmd->key, keyMaterial, keyLength); + memcpy(cmd->key, keyMaterial, keyLength); #ifdef WAPI_ENABLE if (NULL != keyRSC && key_op_ctrl != KEY_OP_INIT_WAPIPN) { #else if (NULL != keyRSC) { #endif // WAPI_ENABLE - A_MEMCPY(cmd->keyRSC, keyRSC, sizeof(cmd->keyRSC)); + memcpy(cmd->keyRSC, keyRSC, sizeof(cmd->keyRSC)); } cmd->key_op_ctrl = key_op_ctrl; if(macAddr) { - A_MEMCPY(cmd->key_macaddr,macAddr,IEEE80211_ADDR_LEN); + memcpy(cmd->key_macaddr,macAddr,IEEE80211_ADDR_LEN); } return (wmi_cmd_send(wmip, osbuf, WMI_ADD_CIPHER_KEY_CMDID, sync_flag)); @@ -2912,7 +2912,7 @@ wmi_add_krk_cmd(struct wmi_t *wmip, u8 *krk) cmd = (WMI_ADD_KRK_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(cmd, sizeof(*cmd)); - A_MEMCPY(cmd->krk, krk, WMI_KRK_LEN); + memcpy(cmd->krk, krk, WMI_KRK_LEN); return (wmi_cmd_send(wmip, osbuf, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG)); } @@ -2971,9 +2971,9 @@ wmi_setPmkid_cmd(struct wmi_t *wmip, u8 *bssid, u8 *pmkId, A_NETBUF_PUT(osbuf, sizeof(*cmd)); cmd = (WMI_SET_PMKID_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid)); + memcpy(cmd->bssid, bssid, sizeof(cmd->bssid)); if (set == true) { - A_MEMCPY(cmd->pmkid, pmkId, sizeof(cmd->pmkid)); + memcpy(cmd->pmkid, pmkId, sizeof(cmd->pmkid)); cmd->enable = PMKID_ENABLE; } else { A_MEMZERO(cmd->pmkid, sizeof(cmd->pmkid)); @@ -3045,7 +3045,7 @@ wmi_set_pmkid_list_cmd(struct wmi_t *wmip, cmd->numPMKID = pmkInfo->numPMKID; for (i = 0; i < cmd->numPMKID; i++) { - A_MEMCPY(&cmd->pmkidList[i], &pmkInfo->pmkidList[i], + memcpy(&cmd->pmkidList[i], &pmkInfo->pmkidList[i], WMI_PMKID_LEN); } @@ -3258,7 +3258,7 @@ wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params) cmd = (WMI_CREATE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(cmd, sizeof(*cmd)); - A_MEMCPY(cmd, params, sizeof(*cmd)); + memcpy(cmd, params, sizeof(*cmd)); /* this is an implicitly created Fat pipe */ if ((u32)params->tsid == (u32)WMI_IMPLICIT_PSTREAM) { @@ -3625,7 +3625,7 @@ wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam, cmd->scanParam = scanParam; cmd->phyMode = mode; cmd->numChannels = numChan; - A_MEMCPY(cmd->channelList, channelList, numChan * sizeof(u16)); + memcpy(cmd->channelList, channelList, numChan * sizeof(u16)); return (wmi_cmd_send(wmip, osbuf, WMI_SET_CHANNEL_PARAMS_CMDID, NO_SYNC_WMIFLAG)); @@ -3724,7 +3724,7 @@ wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *ipCmd) A_NETBUF_PUT(osbuf, sizeof(WMI_SET_IP_CMD)); cmd = (WMI_SET_IP_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMCPY(cmd, ipCmd, sizeof(WMI_SET_IP_CMD)); + memcpy(cmd, ipCmd, sizeof(WMI_SET_IP_CMD)); return (wmi_cmd_send(wmip, osbuf, WMI_SET_IP_CMDID, NO_SYNC_WMIFLAG)); @@ -3756,7 +3756,7 @@ wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, cmd = (WMI_SET_HOST_SLEEP_MODE_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(cmd, size); - A_MEMCPY(cmd, hostModeCmd, sizeof(WMI_SET_HOST_SLEEP_MODE_CMD)); + memcpy(cmd, hostModeCmd, sizeof(WMI_SET_HOST_SLEEP_MODE_CMD)); if(hostModeCmd->asleep) { /* @@ -3811,7 +3811,7 @@ wmi_set_wow_mode_cmd(struct wmi_t *wmip, cmd = (WMI_SET_WOW_MODE_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(cmd, size); - A_MEMCPY(cmd, wowModeCmd, sizeof(WMI_SET_WOW_MODE_CMD)); + memcpy(cmd, wowModeCmd, sizeof(WMI_SET_WOW_MODE_CMD)); return (wmi_cmd_send(wmip, osbuf, WMI_SET_WOW_MODE_CMDID, NO_SYNC_WMIFLAG)); @@ -3837,7 +3837,7 @@ wmi_get_wow_list_cmd(struct wmi_t *wmip, cmd = (WMI_GET_WOW_LIST_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(cmd, size); - A_MEMCPY(cmd, wowListCmd, sizeof(WMI_GET_WOW_LIST_CMD)); + memcpy(cmd, wowListCmd, sizeof(WMI_GET_WOW_LIST_CMD)); return (wmi_cmd_send(wmip, osbuf, WMI_GET_WOW_LIST_CMDID, NO_SYNC_WMIFLAG)); @@ -3885,10 +3885,10 @@ int wmi_add_wow_pattern_cmd(struct wmi_t *wmip, cmd->filter_offset = addWowCmd->filter_offset; cmd->filter_size = addWowCmd->filter_size; - A_MEMCPY(cmd->filter, pattern, addWowCmd->filter_size); + memcpy(cmd->filter, pattern, addWowCmd->filter_size); filter_mask = (u8 *)(cmd->filter + cmd->filter_size); - A_MEMCPY(filter_mask, mask, addWowCmd->filter_size); + memcpy(filter_mask, mask, addWowCmd->filter_size); return (wmi_cmd_send(wmip, osbuf, WMI_ADD_WOW_PATTERN_CMDID, @@ -3914,7 +3914,7 @@ wmi_del_wow_pattern_cmd(struct wmi_t *wmip, cmd = (WMI_DEL_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(cmd, size); - A_MEMCPY(cmd, delWowCmd, sizeof(WMI_DEL_WOW_PATTERN_CMD)); + memcpy(cmd, delWowCmd, sizeof(WMI_DEL_WOW_PATTERN_CMD)); return (wmi_cmd_send(wmip, osbuf, WMI_DEL_WOW_PATTERN_CMDID, NO_SYNC_WMIFLAG)); @@ -4026,7 +4026,7 @@ wmi_set_lq_threshold_params(struct wmi_t *wmip, cmd = (WMI_LQ_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(cmd, size); - A_MEMCPY(cmd, lqCmd, sizeof(WMI_LQ_THRESHOLD_PARAMS_CMD)); + memcpy(cmd, lqCmd, sizeof(WMI_LQ_THRESHOLD_PARAMS_CMD)); return (wmi_cmd_send(wmip, osbuf, WMI_LQ_THRESHOLD_PARAMS_CMDID, NO_SYNC_WMIFLAG)); @@ -4129,7 +4129,7 @@ wmi_addBadAp_cmd(struct wmi_t *wmip, u8 apIndex, u8 *bssid) cmd = (WMI_ADD_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf)); cmd->badApIndex = apIndex; - A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid)); + memcpy(cmd->bssid, bssid, sizeof(cmd->bssid)); return (wmi_cmd_send(wmip, osbuf, WMI_ADD_BAD_AP_CMDID, SYNC_BEFORE_WMIFLAG)); } @@ -4244,7 +4244,7 @@ wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p, cmd = (WMI_SET_ROAM_CTRL_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(cmd, size); - A_MEMCPY(cmd, p, size); + memcpy(cmd, p, size); return (wmi_cmd_send(wmip, osbuf, WMI_SET_ROAM_CTRL_CMDID, NO_SYNC_WMIFLAG)); @@ -4276,7 +4276,7 @@ wmi_set_powersave_timers_cmd(struct wmi_t *wmip, cmd = (WMI_POWERSAVE_TIMERS_POLICY_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(cmd, size); - A_MEMCPY(cmd, pCmd, size); + memcpy(cmd, pCmd, size); return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID, NO_SYNC_WMIFLAG)); @@ -4482,7 +4482,7 @@ void wmi_get_current_bssid(struct wmi_t *wmip, u8 *bssid) { if (bssid != NULL) { - A_MEMCPY(bssid, wmip->wmi_bssid, ATH_MAC_LEN); + memcpy(bssid, wmip->wmi_bssid, ATH_MAC_LEN); } } @@ -4530,9 +4530,9 @@ wmi_opt_tx_frame_cmd(struct wmi_t *wmip, cmd->frmType = frmType; cmd->optIEDataLen = optIEDataLen; //cmd->optIEData = (u8 *)((int)cmd + sizeof(*cmd)); - A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid)); - A_MEMCPY(cmd->dstAddr, dstMacAddr, sizeof(cmd->dstAddr)); - A_MEMCPY(&cmd->optIEData[0], optIEData, optIEDataLen); + memcpy(cmd->bssid, bssid, sizeof(cmd->bssid)); + memcpy(cmd->dstAddr, dstMacAddr, sizeof(cmd->dstAddr)); + memcpy(&cmd->optIEData[0], optIEData, optIEDataLen); return (wmi_cmd_send(wmip, osbuf, WMI_OPT_TX_FRAME_CMDID, NO_SYNC_WMIFLAG)); @@ -4858,7 +4858,7 @@ wmi_set_country(struct wmi_t *wmip, A_UCHAR *countryCode) cmd = (WMI_AP_SET_COUNTRY_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(cmd, sizeof(*cmd)); - A_MEMCPY(cmd->countryCode,countryCode,3); + memcpy(cmd->countryCode,countryCode,3); return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_COUNTRY_CMDID, NO_SYNC_WMIFLAG)); @@ -4884,7 +4884,7 @@ wmi_test_cmd(struct wmi_t *wmip, u8 *buf, u32 len) } A_NETBUF_PUT(osbuf, len); data = A_NETBUF_DATA(osbuf); - A_MEMCPY(data, buf, len); + memcpy(data, buf, len); return(wmi_cmd_send(wmip, osbuf, WMI_TEST_CMDID, NO_SYNC_WMIFLAG)); @@ -4972,7 +4972,7 @@ wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd) alloc_cmd = (WMI_SET_BT_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(alloc_cmd, sizeof(*cmd)); - A_MEMCPY(alloc_cmd, cmd, sizeof(*cmd)); + memcpy(alloc_cmd, cmd, sizeof(*cmd)); return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_PARAMS_CMDID, NO_SYNC_WMIFLAG)); @@ -4991,7 +4991,7 @@ wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd) A_NETBUF_PUT(osbuf, sizeof(*cmd)); alloc_cmd = (WMI_SET_BTCOEX_FE_ANT_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(alloc_cmd, sizeof(*cmd)); - A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_FE_ANT_CMD)); + memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_FE_ANT_CMD)); return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_FE_ANT_CMDID, NO_SYNC_WMIFLAG)); @@ -5012,7 +5012,7 @@ wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip, A_NETBUF_PUT(osbuf, sizeof(*cmd)); alloc_cmd = (WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(alloc_cmd, sizeof(*cmd)); - A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD)); + memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD)); A_PRINTF("colocated bt = %d\n", alloc_cmd->btcoexCoLocatedBTdev); return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID, NO_SYNC_WMIFLAG)); @@ -5033,7 +5033,7 @@ wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip, A_NETBUF_PUT(osbuf, sizeof(*cmd)); alloc_cmd = (WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(alloc_cmd, sizeof(*cmd)); - A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD)); + memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD)); return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID, NO_SYNC_WMIFLAG)); @@ -5053,7 +5053,7 @@ wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip, A_NETBUF_PUT(osbuf, sizeof(*cmd)); alloc_cmd = (WMI_SET_BTCOEX_SCO_CONFIG_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(alloc_cmd, sizeof(*cmd)); - A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD)); + memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD)); return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_SCO_CONFIG_CMDID , NO_SYNC_WMIFLAG)); @@ -5073,7 +5073,7 @@ wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip, A_NETBUF_PUT(osbuf, sizeof(*cmd)); alloc_cmd = (WMI_SET_BTCOEX_A2DP_CONFIG_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(alloc_cmd, sizeof(*cmd)); - A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD)); + memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD)); return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_A2DP_CONFIG_CMDID , NO_SYNC_WMIFLAG)); @@ -5093,7 +5093,7 @@ wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip, A_NETBUF_PUT(osbuf, sizeof(*cmd)); alloc_cmd = (WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(alloc_cmd, sizeof(*cmd)); - A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD)); + memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD)); return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID , NO_SYNC_WMIFLAG)); @@ -5112,7 +5112,7 @@ wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd) A_NETBUF_PUT(osbuf, sizeof(*cmd)); alloc_cmd = (WMI_SET_BTCOEX_DEBUG_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(alloc_cmd, sizeof(*cmd)); - A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_DEBUG_CMD)); + memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_DEBUG_CMD)); return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_DEBUG_CMDID , NO_SYNC_WMIFLAG)); @@ -5132,7 +5132,7 @@ wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip, A_NETBUF_PUT(osbuf, sizeof(*cmd)); alloc_cmd = (WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(alloc_cmd, sizeof(*cmd)); - A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD)); + memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD)); return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID , NO_SYNC_WMIFLAG)); @@ -5151,7 +5151,7 @@ wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd) A_NETBUF_PUT(osbuf, sizeof(*cmd)); alloc_cmd = (WMI_GET_BTCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(alloc_cmd, sizeof(*cmd)); - A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_GET_BTCOEX_CONFIG_CMD)); + memcpy(alloc_cmd,cmd,sizeof(WMI_GET_BTCOEX_CONFIG_CMD)); return (wmi_cmd_send(wmip, osbuf, WMI_GET_BTCOEX_CONFIG_CMDID , NO_SYNC_WMIFLAG)); @@ -5225,7 +5225,7 @@ wmi_set_params_cmd(struct wmi_t *wmip, u32 opcode, u32 length, char *buffer) A_MEMZERO(cmd, sizeof(*cmd)); cmd->opcode = opcode; cmd->length = length; - A_MEMCPY(cmd->buffer, buffer, length); + memcpy(cmd->buffer, buffer, length); return (wmi_cmd_send(wmip, osbuf, WMI_SET_PARAMS_CMDID, NO_SYNC_WMIFLAG)); @@ -5324,7 +5324,7 @@ wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType, u8 ieLen, cmd->mgmtFrmType = mgmtFrmType; cmd->ieLen = ieLen; - A_MEMCPY(cmd->ieInfo, ieInfo, ieLen); + memcpy(cmd->ieInfo, ieInfo, ieLen); return (wmi_cmd_send(wmip, osbuf, WMI_SET_APPIE_CMDID, NO_SYNC_WMIFLAG)); } @@ -5344,7 +5344,7 @@ wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, u16 dataLen) data = A_NETBUF_DATA(osbuf); - A_MEMCPY(data, cmd, dataLen); + memcpy(data, cmd, dataLen); return (wmi_cmd_send(wmip, osbuf, WMI_SET_WHALPARAM_CMDID, NO_SYNC_WMIFLAG)); } @@ -5933,7 +5933,7 @@ wmi_send_rssi_threshold_params(struct wmi_t *wmip, cmd = (WMI_RSSI_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(cmd, size); - A_MEMCPY(cmd, rssiCmd, sizeof(WMI_RSSI_THRESHOLD_PARAMS_CMD)); + memcpy(cmd, rssiCmd, sizeof(WMI_RSSI_THRESHOLD_PARAMS_CMD)); return (wmi_cmd_send(wmip, osbuf, WMI_RSSI_THRESHOLD_PARAMS_CMDID, NO_SYNC_WMIFLAG)); @@ -5956,7 +5956,7 @@ wmi_send_snr_threshold_params(struct wmi_t *wmip, A_NETBUF_PUT(osbuf, size); cmd = (WMI_SNR_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(cmd, size); - A_MEMCPY(cmd, snrCmd, sizeof(WMI_SNR_THRESHOLD_PARAMS_CMD)); + memcpy(cmd, snrCmd, sizeof(WMI_SNR_THRESHOLD_PARAMS_CMD)); return (wmi_cmd_send(wmip, osbuf, WMI_SNR_THRESHOLD_PARAMS_CMDID, NO_SYNC_WMIFLAG)); @@ -5977,7 +5977,7 @@ wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_ alloc_cmd = (WMI_SET_TARGET_EVENT_REPORT_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(alloc_cmd, sizeof(*cmd)); - A_MEMCPY(alloc_cmd, cmd, sizeof(*cmd)); + memcpy(alloc_cmd, cmd, sizeof(*cmd)); return (wmi_cmd_send(wmip, osbuf, WMI_SET_TARGET_EVENT_REPORT_CMDID, NO_SYNC_WMIFLAG)); @@ -6089,7 +6089,7 @@ wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p) cm = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(cm, sizeof(*cm)); - A_MEMCPY(cm,p,sizeof(*cm)); + memcpy(cm,p,sizeof(*cm)); return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONFIG_COMMIT_CMDID, NO_SYNC_WMIFLAG)); } @@ -6171,7 +6171,7 @@ wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *acl) A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_MAC_CMD)); a = (WMI_AP_ACL_MAC_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(a, sizeof(*a)); - A_MEMCPY(a,acl,sizeof(*acl)); + memcpy(a,acl,sizeof(*acl)); return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_MAC_LIST_CMDID, NO_SYNC_WMIFLAG)); } @@ -6199,7 +6199,7 @@ wmi_ap_set_mlme(struct wmi_t *wmip, u8 cmd, u8 *mac, u16 reason) A_MEMZERO(mlme, sizeof(*mlme)); mlme->cmd = cmd; - A_MEMCPY(mlme->mac, mac, ATH_MAC_LEN); + memcpy(mlme->mac, mac, ATH_MAC_LEN); mlme->reason = reason; return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_MLME_CMDID, NO_SYNC_WMIFLAG)); @@ -6392,7 +6392,7 @@ wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd) htCap = (WMI_SET_HT_CAP_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(htCap, sizeof(*htCap)); - A_MEMCPY(htCap, cmd, sizeof(*htCap)); + memcpy(htCap, cmd, sizeof(*htCap)); return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_CAP_CMDID, NO_SYNC_WMIFLAG)); @@ -6434,7 +6434,7 @@ wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, u32 *pMaskArray) A_NETBUF_PUT(osbuf, sizeof(*pData)); pData = (WMI_SET_TX_SELECT_RATES_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMCPY(pData, pMaskArray, sizeof(*pData)); + memcpy(pData, pMaskArray, sizeof(*pData)); return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SELECT_RATES_CMDID, NO_SYNC_WMIFLAG)); @@ -6456,7 +6456,7 @@ wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, u16 sz) cmd = (WMI_HCI_CMD *)(A_NETBUF_DATA(osbuf)); cmd->cmd_buf_sz = sz; - A_MEMCPY(cmd->buf, buf, sz); + memcpy(cmd->buf, buf, sz); return (wmi_cmd_send(wmip, osbuf, WMI_HCI_CMD_CMDID, NO_SYNC_WMIFLAG)); } @@ -6604,7 +6604,7 @@ wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk) p = (WMI_SET_PMK_CMD *)(A_NETBUF_DATA(osbuf)); A_MEMZERO(p, sizeof(*p)); - A_MEMCPY(p->pmk, pmk, WMI_PMK_LEN); + memcpy(p->pmk, pmk, WMI_PMK_LEN); return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMK_CMDID, NO_SYNC_WMIFLAG)); } -- cgit v1.2.3 From 395e1cae85283f7bbe767097d78b5e3baa13b131 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 10 Mar 2011 18:55:30 -0800 Subject: staging: ath6kl: s|A_MEMCMP|memcmp|g for i in $(find ./drivers/staging/ath6kl/ -name \*.[ch]) ; do \ sed -r -i -e "s/A_MEMCMP/memcmp/g" $i; done Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/miscdrv/common_drv.c | 4 ++-- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 6 +++--- drivers/staging/ath6kl/os/linux/cfg80211.c | 8 ++++---- drivers/staging/ath6kl/os/linux/include/osapi_linux.h | 2 -- drivers/staging/ath6kl/os/linux/ioctl.c | 6 +++--- drivers/staging/ath6kl/os/linux/wireless_ext.c | 8 ++++---- drivers/staging/ath6kl/wlan/include/ieee80211.h | 2 +- drivers/staging/ath6kl/wlan/src/wlan_node.c | 8 ++++---- 8 files changed, 21 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/miscdrv/common_drv.c b/drivers/staging/ath6kl/miscdrv/common_drv.c index 7a77290da140..a01f5d73203d 100644 --- a/drivers/staging/ath6kl/miscdrv/common_drv.c +++ b/drivers/staging/ath6kl/miscdrv/common_drv.c @@ -877,7 +877,7 @@ static ATH_DEBUG_MODULE_DBG_INFO *FindModule(char *module_name) while (pInfo != NULL) { /* TODO: need to use something other than strlen */ - if (A_MEMCMP(pInfo->ModuleName,module_name,strlen(module_name)) == 0) { + if (memcmp(pInfo->ModuleName,module_name,strlen(module_name)) == 0) { break; } pInfo = pInfo->pNext; @@ -916,7 +916,7 @@ void a_dump_module_debug_info_by_name(char *module_name) return; } - if (A_MEMCMP(module_name,"all",3) == 0) { + if (memcmp(module_name,"all",3) == 0) { /* dump all */ while (pInfo != NULL) { a_dump_module_debug_info(pInfo); diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 2111e993856a..e8277ffce240 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -4291,7 +4291,7 @@ ar6000_connect_event(AR_SOFTC_T *ar, u16 channel, u8 *bssid, if(ar->arNetworkType & AP_NETWORK) { struct net_device *dev = ar->arNetDev; - if(A_MEMCMP(dev->dev_addr, bssid, ATH_MAC_LEN)==0) { + if(memcmp(dev->dev_addr, bssid, ATH_MAC_LEN)==0) { ar->arACS = channel; ik = &ar->ap_mode_bkey; @@ -4605,7 +4605,7 @@ u8 remove_sta(AR_SOFTC_T *ar, u8 *mac, u16 reason) } } else { for(i=0; i < AP_MAX_NUM_STA; i++) { - if(A_MEMCMP(ar->sta_list[i].mac, mac, ATH_MAC_LEN)==0) { + if(memcmp(ar->sta_list[i].mac, mac, ATH_MAC_LEN)==0) { A_PRINTF("DEL STA %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x " " aid=%d REASON=%d\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], ar->sta_list[i].aid, reason); @@ -6281,7 +6281,7 @@ ap_set_wapi_key(struct ar6_softc *ar, void *ikey) KEY_USAGE keyUsage = 0; int status; - if (A_MEMCMP(ik->ik_macaddr, bcast_mac, IEEE80211_ADDR_LEN) == 0) { + if (memcmp(ik->ik_macaddr, bcast_mac, IEEE80211_ADDR_LEN) == 0) { keyUsage = GROUP_USAGE; } else { keyUsage = PAIRWISE_USAGE; diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index 415b2535502b..2edac0723af4 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -305,7 +305,7 @@ ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, if(ar->arConnected == true && ar->arSsidLen == sme->ssid_len && - !A_MEMCMP(ar->arSsid, sme->ssid, ar->arSsidLen)) { + !memcmp(ar->arSsid, sme->ssid, ar->arSsidLen)) { reconnect_flag = true; status = wmi_reconnect_cmd(ar->arWmi, ar->arReqBssid, @@ -318,7 +318,7 @@ ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, } return 0; } else if(ar->arSsidLen == sme->ssid_len && - !A_MEMCMP(ar->arSsid, sme->ssid, ar->arSsidLen)) { + !memcmp(ar->arSsid, sme->ssid, ar->arSsidLen)) { ar6000_disconnect(ar); } @@ -332,7 +332,7 @@ ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); if(sme->bssid){ - if(A_MEMCMP(&sme->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) { + if(memcmp(&sme->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) { memcpy(ar->arReqBssid, sme->bssid, sizeof(ar->arReqBssid)); } } @@ -1321,7 +1321,7 @@ ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); if(ibss_param->bssid) { - if(A_MEMCMP(&ibss_param->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) { + if(memcmp(&ibss_param->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) { memcpy(ar->arReqBssid, ibss_param->bssid, sizeof(ar->arReqBssid)); } } diff --git a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h index cdb4195d5df7..53b500c1835f 100644 --- a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h @@ -77,7 +77,6 @@ #define A_CPU2BE32(x) htonl(x) #define A_MEMZERO(addr, len) memset(addr, 0, len) -#define A_MEMCMP(addr1, addr2, len) memcmp((addr1), (addr2), (len)) #define A_MALLOC(size) kmalloc((size), GFP_KERNEL) #define A_MALLOC_NOWAIT(size) kmalloc((size), GFP_ATOMIC) #define A_FREE(addr) kfree(addr) @@ -364,7 +363,6 @@ static inline void *A_ALIGN_TO_CACHE_LINE(void *ptr) { #define POSTPACK __ATTRIB_PACK #define A_MEMZERO(addr, len) memset((addr), 0, (len)) -#define A_MEMCMP(addr1, addr2, len) memcmp((addr1), (addr2), (len)) #define A_MALLOC(size) malloc(size) #define A_FREE(addr) free(addr) diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index 9a7f920c26b9..a95b7430ad8f 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -555,7 +555,7 @@ ar6000_ioctl_set_badAp(struct net_device *dev, struct ifreq *rq) return -EIO; } - if (A_MEMCMP(cmd.bssid, null_mac, AR6000_ETH_ADDR_LEN) == 0) { + if (memcmp(cmd.bssid, null_mac, AR6000_ETH_ADDR_LEN) == 0) { /* * This is a delete badAP. */ @@ -3127,7 +3127,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) sizeof(adhocBssid))) { ret = -EFAULT; - } else if (A_MEMCMP(adhocBssid.bssid, bcast_mac, + } else if (memcmp(adhocBssid.bssid, bcast_mac, AR6000_ETH_ADDR_LEN) == 0) { ret = -EFAULT; @@ -4714,7 +4714,7 @@ u8 mac_cmp_wild(u8 *mac, u8 *new_mac, u8 wild, u8 new_wild) if((wild & 1<arNextMode == AP_NETWORK) { /* SSID change for AP network - Will take effect on commit */ - if(A_MEMCMP(ar->arSsid,ssid,32) != 0) { + if(memcmp(ar->arSsid,ssid,32) != 0) { ar->arSsidLen = data->length - 1; memcpy(ar->arSsid, ssid, ar->arSsidLen); ar->ap_profile_flag = 1; /* There is a change in profile */ @@ -581,7 +581,7 @@ ar6000_ioctl_siwessid(struct net_device *dev, (!data->flags))) { if ((!data->flags) || - (A_MEMCMP(ar->arSsid, ssid, ar->arSsidLen) != 0) || + (memcmp(ar->arSsid, ssid, ar->arSsidLen) != 0) || (ar->arSsidLen != (data->length - 1))) { /* @@ -1618,7 +1618,7 @@ static int ar6000_set_wapi_key(struct net_device *dev, keyLen = erq->length - sizeof(struct iw_encode_ext); memcpy(wapiKeyRsc, ext->tx_seq, sizeof(wapiKeyRsc)); - if (A_MEMCMP(ext->addr.sa_data, broadcastMac, sizeof(broadcastMac)) == 0) { + if (memcmp(ext->addr.sa_data, broadcastMac, sizeof(broadcastMac)) == 0) { keyUsage |= GROUP_USAGE; PN = (u32 *)wapiKeyRsc; for (i = 0; i < 4; i++) { @@ -2315,7 +2315,7 @@ ar6000_ioctl_siwap(struct net_device *dev, return -EIO; } - if (A_MEMCMP(&ap_addr->sa_data, bcast_mac, AR6000_ETH_ADDR_LEN) == 0) { + if (memcmp(&ap_addr->sa_data, bcast_mac, AR6000_ETH_ADDR_LEN) == 0) { A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); } else { memcpy(ar->arReqBssid, &ap_addr->sa_data, sizeof(ar->arReqBssid)); diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211.h b/drivers/staging/ath6kl/wlan/include/ieee80211.h index dfad19ac74fd..532ab0eb20c3 100644 --- a/drivers/staging/ath6kl/wlan/include/ieee80211.h +++ b/drivers/staging/ath6kl/wlan/include/ieee80211.h @@ -68,7 +68,7 @@ #define IEEE80211_ADDR_EQ(addr1, addr2) \ - (A_MEMCMP(addr1, addr2, IEEE80211_ADDR_LEN) == 0) + (memcmp(addr1, addr2, IEEE80211_ADDR_LEN) == 0) #define IEEE80211_ADDR_COPY(dst,src) memcpy(dst,src,IEEE80211_ADDR_LEN) diff --git a/drivers/staging/ath6kl/wlan/src/wlan_node.c b/drivers/staging/ath6kl/wlan/src/wlan_node.c index c99a330ac00d..0edf9c184efb 100644 --- a/drivers/staging/ath6kl/wlan/src/wlan_node.c +++ b/drivers/staging/ath6kl/wlan/src/wlan_node.c @@ -334,7 +334,7 @@ wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt) while (bss != NULL) { nextBss = bss->ni_list_next; - if (A_MEMCMP(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0) + if (memcmp(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0) { /* * free up all but the current bss - if set @@ -357,7 +357,7 @@ wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt) while (bss != NULL) { nextBss = bss->ni_list_next; - if (A_MEMCMP(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0) + if (memcmp(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0) { if (((now - bss->ni_tstamp) > timeoutValue) || --bss->ni_actcnt == 0) @@ -391,7 +391,7 @@ wlan_node_timeout (A_ATH_TIMER arg) while (bss != NULL) { nextBss = bss->ni_list_next; - if (A_MEMCMP(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0) + if (memcmp(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0) { if ((now - bss->ni_tstamp) > timeoutValue) @@ -539,7 +539,7 @@ wlan_node_remove(struct ieee80211_node_table *nt, u8 *bssid) { nextBss = bss->ni_list_next; - if (A_MEMCMP(bssid, bss->ni_macaddr, 6) == 0) + if (memcmp(bssid, bss->ni_macaddr, 6) == 0) { wlan_node_remove_core (nt, bss); IEEE80211_NODE_UNLOCK(nt); -- cgit v1.2.3 From d8cb316fdc64fefbb7bd00f16dc8d1bdce24c2d3 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 10 Mar 2011 18:55:31 -0800 Subject: staging: ath6kl: remove-typedef: A_UCHAR remove-typedef -s A_UCHAR u8 drivers/staging/ath6kl/ This uses the remove-typedef utility: http://www.kernel.org/pub/linux/kernel/people/mcgrof/scripts/remove-typedef Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/bmi/include/bmi_internal.h | 4 +- drivers/staging/ath6kl/bmi/src/bmi.c | 34 ++++----- .../hif/sdio/linux_sdio/include/hif_internal.h | 2 +- .../staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 4 +- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 4 +- drivers/staging/ath6kl/htc2/htc_internal.h | 2 +- drivers/staging/ath6kl/include/a_debug.h | 2 +- drivers/staging/ath6kl/include/ar6000_diag.h | 4 +- drivers/staging/ath6kl/include/bmi.h | 12 ++-- .../include/common/regulatory/reg_dbschema.h | 2 +- drivers/staging/ath6kl/include/common/testcmd.h | 2 +- drivers/staging/ath6kl/include/common/wmi.h | 4 +- drivers/staging/ath6kl/include/common/wmi_thin.h | 2 +- drivers/staging/ath6kl/include/common_drv.h | 2 +- drivers/staging/ath6kl/include/hif.h | 2 +- drivers/staging/ath6kl/include/wlan_api.h | 4 +- drivers/staging/ath6kl/include/wmi_api.h | 10 +-- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c | 34 ++++----- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h | 4 +- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c | 36 +++++----- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h | 13 +--- drivers/staging/ath6kl/miscdrv/common_drv.c | 32 ++++----- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 82 +++++++++++----------- drivers/staging/ath6kl/os/linux/eeprom.c | 6 +- .../staging/ath6kl/os/linux/include/ar6000_drv.h | 2 +- .../ath6kl/os/linux/include/athtypes_linux.h | 1 - drivers/staging/ath6kl/os/linux/ioctl.c | 4 +- drivers/staging/ath6kl/wlan/src/wlan_node.c | 8 +-- drivers/staging/ath6kl/wmi/wmi.c | 16 ++--- 29 files changed, 163 insertions(+), 171 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/bmi/include/bmi_internal.h b/drivers/staging/ath6kl/bmi/include/bmi_internal.h index ebc037d7922b..e13fb01ec9ed 100644 --- a/drivers/staging/ath6kl/bmi/include/bmi_internal.h +++ b/drivers/staging/ath6kl/bmi/include/bmi_internal.h @@ -43,12 +43,12 @@ static bool bmiDone; int bmiBufferSend(HIF_DEVICE *device, - A_UCHAR *buffer, + u8 *buffer, u32 length); int bmiBufferReceive(HIF_DEVICE *device, - A_UCHAR *buffer, + u8 *buffer, u32 length, bool want_timeout); diff --git a/drivers/staging/ath6kl/bmi/src/bmi.c b/drivers/staging/ath6kl/bmi/src/bmi.c index 1e1e6ee6c39c..37f7cbce8654 100644 --- a/drivers/staging/ath6kl/bmi/src/bmi.c +++ b/drivers/staging/ath6kl/bmi/src/bmi.c @@ -55,7 +55,7 @@ very simple. static bool pendingEventsFuncCheck = false; static u32 *pBMICmdCredits; -static A_UCHAR *pBMICmdBuf; +static u8 *pBMICmdBuf; #define MAX_BMI_CMDBUF_SZ (BMI_DATASZ_MAX + \ sizeof(u32) /* cmd */ + \ sizeof(u32) /* addr */ + \ @@ -84,7 +84,7 @@ BMIInit(void) } if (!pBMICmdBuf) { - pBMICmdBuf = (A_UCHAR *)A_MALLOC_NOWAIT(MAX_BMI_CMDBUF_SZ); + pBMICmdBuf = (u8 *)A_MALLOC_NOWAIT(MAX_BMI_CMDBUF_SZ); A_ASSERT(pBMICmdBuf); } @@ -120,7 +120,7 @@ BMIDone(HIF_DEVICE *device) bmiDone = true; cid = BMI_DONE; - status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid)); + status = bmiBufferSend(device, (u8 *)&cid, sizeof(cid)); if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); return A_ERROR; @@ -155,13 +155,13 @@ BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Enter (device: 0x%p)\n", device)); cid = BMI_GET_TARGET_INFO; - status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid)); + status = bmiBufferSend(device, (u8 *)&cid, sizeof(cid)); if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); return A_ERROR; } - status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_ver, + status = bmiBufferReceive(device, (u8 *)&targ_info->target_ver, sizeof(targ_info->target_ver), true); if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Version from the device\n")); @@ -170,7 +170,7 @@ BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) if (targ_info->target_ver == TARGET_VERSION_SENTINAL) { /* Determine how many bytes are in the Target's targ_info */ - status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_info_byte_count, + status = bmiBufferReceive(device, (u8 *)&targ_info->target_info_byte_count, sizeof(targ_info->target_info_byte_count), true); if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info Byte Count from the device\n")); @@ -185,7 +185,7 @@ BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) /* Read the remainder of the targ_info */ status = bmiBufferReceive(device, - ((A_UCHAR *)targ_info)+sizeof(targ_info->target_info_byte_count), + ((u8 *)targ_info)+sizeof(targ_info->target_info_byte_count), sizeof(*targ_info)-sizeof(targ_info->target_info_byte_count), true); if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info (%d bytes) from the device\n", @@ -203,7 +203,7 @@ BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) int BMIReadMemory(HIF_DEVICE *device, u32 address, - A_UCHAR *buffer, + u8 *buffer, u32 length) { u32 cid; @@ -259,7 +259,7 @@ BMIReadMemory(HIF_DEVICE *device, int BMIWriteMemory(HIF_DEVICE *device, u32 address, - A_UCHAR *buffer, + u8 *buffer, u32 length) { u32 cid; @@ -267,8 +267,8 @@ BMIWriteMemory(HIF_DEVICE *device, u32 offset; u32 remaining, txlen; const u32 header = sizeof(cid) + sizeof(address) + sizeof(length); - A_UCHAR alignedBuffer[BMI_DATASZ_MAX]; - A_UCHAR *src; + u8 alignedBuffer[BMI_DATASZ_MAX]; + u8 *src; A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header)); memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + header); @@ -647,7 +647,7 @@ BMIrompatchDeactivate(HIF_DEVICE *device, int BMILZData(HIF_DEVICE *device, - A_UCHAR *buffer, + u8 *buffer, u32 length) { u32 cid; @@ -735,7 +735,7 @@ BMILZStreamStart(HIF_DEVICE *device, /* BMI Access routines */ int bmiBufferSend(HIF_DEVICE *device, - A_UCHAR *buffer, + u8 *buffer, u32 length) { int status; @@ -783,7 +783,7 @@ bmiBufferSend(HIF_DEVICE *device, int bmiBufferReceive(HIF_DEVICE *device, - A_UCHAR *buffer, + u8 *buffer, u32 length, bool want_timeout) { @@ -958,7 +958,7 @@ bmiBufferReceive(HIF_DEVICE *device, } int -BMIFastDownload(HIF_DEVICE *device, u32 address, A_UCHAR *buffer, u32 length) +BMIFastDownload(HIF_DEVICE *device, u32 address, u8 *buffer, u32 length) { int status = A_ERROR; u32 lastWord = 0; @@ -998,13 +998,13 @@ BMIFastDownload(HIF_DEVICE *device, u32 address, A_UCHAR *buffer, u32 length) } int -BMIRawWrite(HIF_DEVICE *device, A_UCHAR *buffer, u32 length) +BMIRawWrite(HIF_DEVICE *device, u8 *buffer, u32 length) { return bmiBufferSend(device, buffer, length); } int -BMIRawRead(HIF_DEVICE *device, A_UCHAR *buffer, u32 length, bool want_timeout) +BMIRawRead(HIF_DEVICE *device, u8 *buffer, u32 length, bool want_timeout) { return bmiBufferReceive(device, buffer, length, want_timeout); } diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h index 8ea3d02f602e..87057e35edd1 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h @@ -54,7 +54,7 @@ typedef struct bus_request { struct bus_request *inusenext; /* link list of in use requests */ struct semaphore sem_req; u32 address; /* request data */ - A_UCHAR *buffer; + u8 *buffer; u32 length; u32 request; void *context; diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index 850472404ff4..b9f8c7206da6 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -155,7 +155,7 @@ int HIFInit(OSDRV_CALLBACKS *callbacks) static int __HIFReadWrite(HIF_DEVICE *device, u32 address, - A_UCHAR *buffer, + u8 *buffer, u32 length, u32 request, void *context) @@ -332,7 +332,7 @@ void AddToAsyncList(HIF_DEVICE *device, BUS_REQUEST *busrequest) int HIFReadWrite(HIF_DEVICE *device, u32 address, - A_UCHAR *buffer, + u8 *buffer, u32 length, u32 request, void *context) diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index cf75c20fc90c..9090a3912f63 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -491,7 +491,7 @@ int DevEnableRecv(AR6K_DEVICE *pDev, bool AsyncMode) int DevWaitForPendingRecv(AR6K_DEVICE *pDev,u32 TimeoutInMs,bool *pbIsRecvPending) { int status = 0; - A_UCHAR host_int_status = 0x0; + u8 host_int_status = 0x0; u32 counter = 0x0; if(TimeoutInMs < 100) @@ -507,7 +507,7 @@ int DevWaitForPendingRecv(AR6K_DEVICE *pDev,u32 TimeoutInMs,bool *pbIsRecvPendin status = HIFReadWrite(pDev->HIFDevice, HOST_INT_STATUS_ADDRESS, &host_int_status, - sizeof(A_UCHAR), + sizeof(u8), HIF_RD_SYNC_BYTE_INC, NULL); if (status) diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h index 743469db60eb..73f6ed933ebf 100644 --- a/drivers/staging/ath6kl/htc2/htc_internal.h +++ b/drivers/staging/ath6kl/htc2/htc_internal.h @@ -178,7 +178,7 @@ void HTCFlushSendPkts(HTC_TARGET *target); #ifdef ATH_DEBUG_MODULE void DumpCreditDist(HTC_ENDPOINT_CREDIT_DIST *pEPDist); void DumpCreditDistStates(HTC_TARGET *target); -void DebugDumpBytes(A_UCHAR *buffer, u16 length, char *pDescription); +void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription); #endif static INLINE HTC_PACKET *HTC_ALLOC_CONTROL_TX(HTC_TARGET *target) { diff --git a/drivers/staging/ath6kl/include/a_debug.h b/drivers/staging/ath6kl/include/a_debug.h index 57472cfb7e96..0e5430d8077f 100644 --- a/drivers/staging/ath6kl/include/a_debug.h +++ b/drivers/staging/ath6kl/include/a_debug.h @@ -57,7 +57,7 @@ extern "C" { /* macro to make a module-specific masks */ #define ATH_DEBUG_MAKE_MODULE_MASK(index) (1 << (ATH_DEBUG_MODULE_MASK_SHIFT + (index))) -void DebugDumpBytes(A_UCHAR *buffer, u16 length, char *pDescription); +void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription); /* Debug support on a per-module basis * diff --git a/drivers/staging/ath6kl/include/ar6000_diag.h b/drivers/staging/ath6kl/include/ar6000_diag.h index 78ac59721dc7..ca0961ab5d57 100644 --- a/drivers/staging/ath6kl/include/ar6000_diag.h +++ b/drivers/staging/ath6kl/include/ar6000_diag.h @@ -33,11 +33,11 @@ ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data); int ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, u32 address, - A_UCHAR *data, u32 length); + u8 *data, u32 length); int ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, u32 address, - A_UCHAR *data, u32 length); + u8 *data, u32 length); int ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, u32 *regval); diff --git a/drivers/staging/ath6kl/include/bmi.h b/drivers/staging/ath6kl/include/bmi.h index 788f9af29fc0..b44988d6edc2 100644 --- a/drivers/staging/ath6kl/include/bmi.h +++ b/drivers/staging/ath6kl/include/bmi.h @@ -52,13 +52,13 @@ BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info); int BMIReadMemory(HIF_DEVICE *device, u32 address, - A_UCHAR *buffer, + u8 *buffer, u32 length); int BMIWriteMemory(HIF_DEVICE *device, u32 address, - A_UCHAR *buffer, + u8 *buffer, u32 length); int @@ -108,23 +108,23 @@ BMILZStreamStart(HIF_DEVICE *device, int BMILZData(HIF_DEVICE *device, - A_UCHAR *buffer, + u8 *buffer, u32 length); int BMIFastDownload(HIF_DEVICE *device, u32 address, - A_UCHAR *buffer, + u8 *buffer, u32 length); int BMIRawWrite(HIF_DEVICE *device, - A_UCHAR *buffer, + u8 *buffer, u32 length); int BMIRawRead(HIF_DEVICE *device, - A_UCHAR *buffer, + u8 *buffer, u32 length, bool want_timeout); diff --git a/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h b/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h index 93d7c0b64fd6..4904040f703f 100644 --- a/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h +++ b/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h @@ -124,7 +124,7 @@ enum searchType { * instance of table). */ typedef PREPACK struct dbMasterTable_t { /* Hold ptrs to Table data structures */ - A_UCHAR numOfEntries; + u8 numOfEntries; char entrySize; /* Entry size per table row */ char searchType; /* Index based access or key based */ char reserved[3]; /* for alignment */ diff --git a/drivers/staging/ath6kl/include/common/testcmd.h b/drivers/staging/ath6kl/include/common/testcmd.h index 3799b687498c..9ca1f2ac2cbf 100644 --- a/drivers/staging/ath6kl/include/common/testcmd.h +++ b/drivers/staging/ath6kl/include/common/testcmd.h @@ -142,7 +142,7 @@ typedef PREPACK struct { u16 rateCntShortGuard[TCMD_MAX_RATES]; } POSTPACK report; struct PREPACK TCMD_CONT_RX_MAC { - A_UCHAR addr[ATH_MAC_LEN]; + u8 addr[ATH_MAC_LEN]; } POSTPACK mac; struct PREPACK TCMD_CONT_RX_ANT_SWITCH_TABLE { u32 antswitch1; diff --git a/drivers/staging/ath6kl/include/common/wmi.h b/drivers/staging/ath6kl/include/common/wmi.h index a8b143ad12cd..c645af373442 100644 --- a/drivers/staging/ath6kl/include/common/wmi.h +++ b/drivers/staging/ath6kl/include/common/wmi.h @@ -537,7 +537,7 @@ typedef PREPACK struct { u8 groupCryptoType; u8 groupCryptoLen; u8 ssidLength; - A_UCHAR ssid[WMI_MAX_SSID_LEN]; + u8 ssid[WMI_MAX_SSID_LEN]; u16 channel; u8 bssid[ATH_MAC_LEN]; u32 ctrl_flags; @@ -3031,7 +3031,7 @@ typedef PREPACK struct { #define WMI_DISABLE_REGULATORY_CODE "FF" typedef PREPACK struct { - A_UCHAR countryCode[3]; + u8 countryCode[3]; } POSTPACK WMI_AP_SET_COUNTRY_CMD; typedef PREPACK struct { diff --git a/drivers/staging/ath6kl/include/common/wmi_thin.h b/drivers/staging/ath6kl/include/common/wmi_thin.h index 41f2b9ba1021..0a8364c9b574 100644 --- a/drivers/staging/ath6kl/include/common/wmi_thin.h +++ b/drivers/staging/ath6kl/include/common/wmi_thin.h @@ -309,7 +309,7 @@ typedef PREPACK struct { u8 ssidLength; /* 0 - 32 */ u8 probe; /* != 0 : issue probe req at start */ u8 reserved; /* alignment */ - A_UCHAR ssid[WMI_MAX_SSID_LEN]; + u8 ssid[WMI_MAX_SSID_LEN]; u8 bssid[ATH_MAC_LEN]; } POSTPACK WMI_THIN_JOIN_CMD; diff --git a/drivers/staging/ath6kl/include/common_drv.h b/drivers/staging/ath6kl/include/common_drv.h index 141b7efc5718..6ed490112643 100644 --- a/drivers/staging/ath6kl/include/common_drv.h +++ b/drivers/staging/ath6kl/include/common_drv.h @@ -70,7 +70,7 @@ int ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data); int ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data); -int ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, u32 address, A_UCHAR *data, u32 length); +int ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, u32 address, u8 *data, u32 length); int ar6000_reset_device(HIF_DEVICE *hifDevice, u32 TargetType, bool waitForCompletion, bool coldReset); diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h index 3906780d0200..ab1f4c1ad917 100644 --- a/drivers/staging/ath6kl/include/hif.h +++ b/drivers/staging/ath6kl/include/hif.h @@ -401,7 +401,7 @@ void HIFDetachHTC(HIF_DEVICE *device); int HIFReadWrite(HIF_DEVICE *device, u32 address, - A_UCHAR *buffer, + u8 *buffer, u32 length, u32 request, void *context); diff --git a/drivers/staging/ath6kl/include/wlan_api.h b/drivers/staging/ath6kl/include/wlan_api.h index ba5493c98a76..9eea5875dd38 100644 --- a/drivers/staging/ath6kl/include/wlan_api.h +++ b/drivers/staging/ath6kl/include/wlan_api.h @@ -108,7 +108,7 @@ void wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt); bss_t * -wlan_find_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid, +wlan_find_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid, u32 ssidLength, bool bIsWPA2, bool bMatchSSID); void @@ -117,7 +117,7 @@ wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni); bss_t *wlan_node_remove(struct ieee80211_node_table *nt, u8 *bssid); bss_t * -wlan_find_matching_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid, +wlan_find_matching_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid, u32 ssidLength, u32 dot11AuthMode, u32 authMode, u32 pairwiseCryptoType, u32 grpwiseCryptoTyp); diff --git a/drivers/staging/ath6kl/include/wmi_api.h b/drivers/staging/ath6kl/include/wmi_api.h index 7ba85051a79f..c8583e0c4a96 100644 --- a/drivers/staging/ath6kl/include/wmi_api.h +++ b/drivers/staging/ath6kl/include/wmi_api.h @@ -111,7 +111,7 @@ int wmi_connect_cmd(struct wmi_t *wmip, CRYPTO_TYPE groupCrypto, u8 groupCryptoLen, int ssidLength, - A_UCHAR *ssid, + u8 *ssid, u8 *bssid, u16 channel, u32 ctrl_flags); @@ -134,7 +134,7 @@ int wmi_scanparams_cmd(struct wmi_t *wmip, u16 fg_start_sec, u16 maxact_scan_per_ssid); int wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, u32 ieMask); int wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag, - u8 ssidLength, A_UCHAR *ssid); + u8 ssidLength, u8 *ssid); int wmi_listeninterval_cmd(struct wmi_t *wmip, u16 listenInterval, u16 listenBeacons); int wmi_bmisstime_cmd(struct wmi_t *wmip, u16 bmisstime, u16 bmissbeacons); int wmi_associnfo_cmd(struct wmi_t *wmip, u8 ieType, @@ -284,7 +284,7 @@ int wmi_set_reassocmode_cmd(struct wmi_t *wmip, u8 mode); int wmi_set_qos_supp_cmd(struct wmi_t *wmip,u8 status); int wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status); int wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG txEnable); -int wmi_set_country(struct wmi_t *wmip, A_UCHAR *countryCode); +int wmi_set_country(struct wmi_t *wmip, u8 *countryCode); int wmi_get_keepalive_configured(struct wmi_t *wmip); u8 wmi_get_keepalive_cmd(struct wmi_t *wmip); @@ -322,7 +322,7 @@ int wmi_mcast_filter_cmd(struct wmi_t *wmip, u8 enable); bss_t * -wmi_find_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid, +wmi_find_Ssidnode (struct wmi_t *wmip, u8 *pSsid, u32 ssidLength, bool bIsWPA2, bool bMatchSSID); @@ -429,7 +429,7 @@ u16 wmi_ieee2freq (int chan); u32 wmi_freq2ieee (u16 freq); bss_t * -wmi_find_matching_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid, +wmi_find_matching_Ssidnode (struct wmi_t *wmip, u8 *pSsid, u32 ssidLength, u32 dot11AuthMode, u32 authMode, u32 pairwiseCryptoType, u32 grpwiseCryptoTyp); diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c index 55b0633af9ee..3dce6f5e239a 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c @@ -62,20 +62,20 @@ int ReadVersionInfo(AR3K_CONFIG_INFO *pConfig); DECLARE_WAIT_QUEUE_HEAD(PsCompleteEvent); DECLARE_WAIT_QUEUE_HEAD(HciEvent); -A_UCHAR *HciEventpacket; +u8 *HciEventpacket; rwlock_t syncLock; wait_queue_t Eventwait; -int PSHciWritepacket(struct hci_dev*,A_UCHAR* Data, u32 len); +int PSHciWritepacket(struct hci_dev*,u8* Data, u32 len); extern char *bdaddr; #endif /* HCI_TRANSPORT_SDIO */ -int write_bdaddr(AR3K_CONFIG_INFO *pConfig,A_UCHAR *bdaddr,int type); +int write_bdaddr(AR3K_CONFIG_INFO *pConfig,u8 *bdaddr,int type); int PSSendOps(void *arg); #ifdef BT_PS_DEBUG -void Hci_log(A_UCHAR * log_string,A_UCHAR *data,u32 len) +void Hci_log(u8 * log_string,u8 *data,u32 len) { int i; AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s : ",log_string)); @@ -139,14 +139,14 @@ int PSSendOps(void *arg) u8 *event; u8 *bufferToFree; struct hci_dev *device; - A_UCHAR *buffer; + u8 *buffer; u32 len; u32 DevType; - A_UCHAR *PsFileName; - A_UCHAR *patchFileName; - A_UCHAR *path = NULL; - A_UCHAR *config_path = NULL; - A_UCHAR config_bdaddr[MAX_BDADDR_FORMAT_LENGTH]; + u8 *PsFileName; + u8 *patchFileName; + u8 *path = NULL; + u8 *config_path = NULL; + u8 config_bdaddr[MAX_BDADDR_FORMAT_LENGTH]; AR3K_CONFIG_INFO *hdev = (AR3K_CONFIG_INFO*)arg; struct device *firmwareDev = NULL; status = 0; @@ -162,12 +162,12 @@ int PSSendOps(void *arg) /* First verify if the controller is an FPGA or ASIC, so depending on the device type the PS file to be written will be different. */ - path =(A_UCHAR *)A_MALLOC(MAX_FW_PATH_LEN); + path =(u8 *)A_MALLOC(MAX_FW_PATH_LEN); if(path == NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for path\n", MAX_FW_PATH_LEN)); goto complete; } - config_path = (A_UCHAR *) A_MALLOC(MAX_FW_PATH_LEN); + config_path = (u8 *) A_MALLOC(MAX_FW_PATH_LEN); if(config_path == NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for config_path\n", MAX_FW_PATH_LEN)); goto complete; @@ -214,7 +214,7 @@ int PSSendOps(void *arg) status = 1; goto complete; } - buffer = (A_UCHAR *)A_MALLOC(firmware->size); + buffer = (u8 *)A_MALLOC(firmware->size); if(buffer != NULL) { /* Copy the read file to a local Dynamic buffer */ memcpy(buffer,firmware->data,firmware->size); @@ -248,7 +248,7 @@ int PSSendOps(void *arg) if(NULL == firmware || firmware->size == 0) { status = 0; } else { - buffer = (A_UCHAR *)A_MALLOC(firmware->size); + buffer = (u8 *)A_MALLOC(firmware->size); if(buffer != NULL) { /* Copy the read file to a local Dynamic buffer */ memcpy(buffer,firmware->data,firmware->size); @@ -419,7 +419,7 @@ int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, } #endif /* HCI_TRANSPORT_SDIO */ -int ReadPSEvent(A_UCHAR* Data){ +int ReadPSEvent(u8* Data){ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" PS Event %x %x %x\n",Data[4],Data[5],Data[3])); if(Data[4] == 0xFC && Data[5] == 0x00) @@ -481,9 +481,9 @@ int str2ba(unsigned char *str_bdaddr,unsigned char *bdaddr) return 0; } -int write_bdaddr(AR3K_CONFIG_INFO *pConfig,A_UCHAR *bdaddr,int type) +int write_bdaddr(AR3K_CONFIG_INFO *pConfig,u8 *bdaddr,int type) { - A_UCHAR bdaddr_cmd[] = { 0x0B, 0xFC, 0x0A, 0x01, 0x01, + u8 bdaddr_cmd[] = { 0x0B, 0xFC, 0x0A, 0x01, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; u8 *event; diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h index 975bf6250249..b97d91f15f34 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h @@ -67,9 +67,9 @@ #define AR3K_CONFIG_INFO struct hci_dev extern wait_queue_head_t HciEvent; extern wait_queue_t Eventwait; -extern A_UCHAR *HciEventpacket; +extern u8 *HciEventpacket; #endif /* #ifndef HCI_TRANSPORT_SDIO */ int AthPSInitialize(AR3K_CONFIG_INFO *hdev); -int ReadPSEvent(A_UCHAR* Data); +int ReadPSEvent(u8* Data); #endif /* __AR3KPSCONFIG_H */ diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c index 90ced223d1f1..300c501a1c0b 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c @@ -127,13 +127,13 @@ tPsTagEntry PsTagEntry[RAMPS_MAX_PS_TAGS_PER_FILE]; tRamPatch RamPatch[MAX_NUM_PATCH_ENTRY]; -int AthParseFilesUnified(A_UCHAR *srcbuffer,u32 srclen, int FileFormat); -char AthReadChar(A_UCHAR *buffer, u32 len,u32 *pos); -char *AthGetLine(char *buffer, int maxlen, A_UCHAR *srcbuffer,u32 len,u32 *pos); -static int AthPSCreateHCICommand(A_UCHAR Opcode, u32 Param1,PSCmdPacket *PSPatchPacket,u32 *index); +int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat); +char AthReadChar(u8 *buffer, u32 len,u32 *pos); +char *AthGetLine(char *buffer, int maxlen, u8 *srcbuffer,u32 len,u32 *pos); +static int AthPSCreateHCICommand(u8 Opcode, u32 Param1,PSCmdPacket *PSPatchPacket,u32 *index); /* Function to reads the next character from the input buffer */ -char AthReadChar(A_UCHAR *buffer, u32 len,u32 *pos) +char AthReadChar(u8 *buffer, u32 len,u32 *pos) { char Ch; if(buffer == NULL || *pos >=len ) @@ -315,7 +315,7 @@ unsigned int uReadDataInSection(char *pCharLine, ST_PS_DATA_FORMAT stPS_DataForm return (0x0FFF); } } -int AthParseFilesUnified(A_UCHAR *srcbuffer,u32 srclen, int FileFormat) +int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat) { char *Buffer; char *pCharLine; @@ -558,7 +558,7 @@ int AthParseFilesUnified(A_UCHAR *srcbuffer,u32 srclen, int FileFormat) /********************/ -int GetNextTwoChar(A_UCHAR *srcbuffer,u32 len, u32 *pos, char *buffer) +int GetNextTwoChar(u8 *srcbuffer,u32 len, u32 *pos, char *buffer) { unsigned char ch; @@ -579,7 +579,7 @@ int GetNextTwoChar(A_UCHAR *srcbuffer,u32 len, u32 *pos, char *buffer) return 0; } -int AthDoParsePatch(A_UCHAR *patchbuffer, u32 patchlen) +int AthDoParsePatch(u8 *patchbuffer, u32 patchlen) { char Byte[3]; @@ -659,7 +659,7 @@ int AthDoParsePatch(A_UCHAR *patchbuffer, u32 patchlen) /********************/ -int AthDoParsePS(A_UCHAR *srcbuffer, u32 srclen) +int AthDoParsePS(u8 *srcbuffer, u32 srclen) { int status; int i; @@ -713,7 +713,7 @@ int AthDoParsePS(A_UCHAR *srcbuffer, u32 srclen) return status; } -char *AthGetLine(char *buffer, int maxlen, A_UCHAR *srcbuffer,u32 len,u32 *pos) +char *AthGetLine(char *buffer, int maxlen, u8 *srcbuffer,u32 len,u32 *pos) { int count; @@ -751,7 +751,7 @@ char *AthGetLine(char *buffer, int maxlen, A_UCHAR *srcbuffer,u32 len,u32 *pos) return buffer; } -static void LoadHeader(A_UCHAR *HCI_PS_Command,A_UCHAR opcode,int length,int index){ +static void LoadHeader(u8 *HCI_PS_Command,u8 opcode,int length,int index){ HCI_PS_Command[0]= 0x0B; HCI_PS_Command[1]= 0xFC; @@ -833,9 +833,9 @@ int AthCreateCommandList(PSCmdPacket **HciPacketList, u32 *numPackets) //////////////////////// ///////////// -static int AthPSCreateHCICommand(A_UCHAR Opcode, u32 Param1,PSCmdPacket *PSPatchPacket,u32 *index) +static int AthPSCreateHCICommand(u8 Opcode, u32 Param1,PSCmdPacket *PSPatchPacket,u32 *index) { - A_UCHAR *HCI_PS_Command; + u8 *HCI_PS_Command; u32 Length; int i,j; @@ -846,7 +846,7 @@ static int AthPSCreateHCICommand(A_UCHAR Opcode, u32 Param1,PSCmdPacket *PSPatch for(i=0;i< Param1;i++){ - HCI_PS_Command = (A_UCHAR *) A_MALLOC(RamPatch[i].Len+HCI_COMMAND_HEADER); + HCI_PS_Command = (u8 *) A_MALLOC(RamPatch[i].Len+HCI_COMMAND_HEADER); AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Allocated Buffer Size %d\n",RamPatch[i].Len+HCI_COMMAND_HEADER)); if(HCI_PS_Command == NULL){ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n")); @@ -871,7 +871,7 @@ static int AthPSCreateHCICommand(A_UCHAR Opcode, u32 Param1,PSCmdPacket *PSPatch Length = 0; i= 0; - HCI_PS_Command = (A_UCHAR *) A_MALLOC(Length+HCI_COMMAND_HEADER); + HCI_PS_Command = (u8 *) A_MALLOC(Length+HCI_COMMAND_HEADER); if(HCI_PS_Command == NULL){ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n")); return A_ERROR; @@ -888,7 +888,7 @@ static int AthPSCreateHCICommand(A_UCHAR Opcode, u32 Param1,PSCmdPacket *PSPatch case PS_RESET: Length = 0x06; i=0; - HCI_PS_Command = (A_UCHAR *) A_MALLOC(Length+HCI_COMMAND_HEADER); + HCI_PS_Command = (u8 *) A_MALLOC(Length+HCI_COMMAND_HEADER); if(HCI_PS_Command == NULL){ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n")); return A_ERROR; @@ -909,7 +909,7 @@ static int AthPSCreateHCICommand(A_UCHAR Opcode, u32 Param1,PSCmdPacket *PSPatch if(PsTagEntry[i].TagId ==1) BDADDR = true; - HCI_PS_Command = (A_UCHAR *) A_MALLOC(PsTagEntry[i].TagLen+HCI_COMMAND_HEADER); + HCI_PS_Command = (u8 *) A_MALLOC(PsTagEntry[i].TagLen+HCI_COMMAND_HEADER); if(HCI_PS_Command == NULL){ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n")); return A_ERROR; @@ -936,7 +936,7 @@ static int AthPSCreateHCICommand(A_UCHAR Opcode, u32 Param1,PSCmdPacket *PSPatch AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("VALUE of CRC:%d At index %d\r\n",Param1,*index)); - HCI_PS_Command = (A_UCHAR *) A_MALLOC(Length+HCI_COMMAND_HEADER); + HCI_PS_Command = (u8 *) A_MALLOC(Length+HCI_COMMAND_HEADER); if(HCI_PS_Command == NULL){ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n")); return A_ERROR; diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h index fdc1c949ab80..62e298deb255 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h @@ -48,13 +48,6 @@ /* Helper data type declaration */ -#ifndef u32 #define A_UCHAR unsigned char -#define u32 unsigned long -#define u16 unsigned short -#define u8 unsigned char -#define bool unsigned char -#endif /* u32 */ - #define ATH_DEBUG_ERR (1 << 0) #define ATH_DEBUG_WARN (1 << 1) #define ATH_DEBUG_INFO (1 << 2) @@ -98,15 +91,15 @@ typedef struct PSCmdPacket { - A_UCHAR *Hcipacket; + u8 *Hcipacket; int packetLen; } PSCmdPacket; /* Parses a Patch information buffer and store it in global structure */ -int AthDoParsePatch(A_UCHAR *, u32 ); +int AthDoParsePatch(u8 *, u32 ); /* parses a PS information buffer and stores it in a global structure */ -int AthDoParsePS(A_UCHAR *, u32 ); +int AthDoParsePS(u8 *, u32 ); /* * Uses the output of Both AthDoParsePS and AthDoParsePatch APIs to form HCI command array with diff --git a/drivers/staging/ath6kl/miscdrv/common_drv.c b/drivers/staging/ath6kl/miscdrv/common_drv.c index a01f5d73203d..b5f74c574230 100644 --- a/drivers/staging/ath6kl/miscdrv/common_drv.c +++ b/drivers/staging/ath6kl/miscdrv/common_drv.c @@ -123,7 +123,7 @@ int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, u32 RegisterAddr, u32 * 3 byte write to bytes 1,2,3 has no effect since we are writing the same values again */ status = HIFReadWrite(hifDevice, RegisterAddr, - (A_UCHAR *)(&Address), + (u8 *)(&Address), 4, HIF_WR_SYNC_BYTE_INC, NULL); @@ -152,7 +152,7 @@ int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, u32 RegisterAddr, u32 * last to initiate the access cycle */ status = HIFReadWrite(hifDevice, RegisterAddr+1, /* write upper 3 bytes */ - ((A_UCHAR *)(&Address))+1, + ((u8 *)(&Address))+1, sizeof(u32)-1, HIF_WR_SYNC_BYTE_INC, NULL); @@ -166,7 +166,7 @@ int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, u32 RegisterAddr, u32 /* write the LSB of the register, this initiates the operation */ status = HIFReadWrite(hifDevice, RegisterAddr, - (A_UCHAR *)(&Address), + (u8 *)(&Address), sizeof(u8), HIF_WR_SYNC_BYTE_INC, NULL); @@ -203,7 +203,7 @@ ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data) /* read the data */ status = HIFReadWrite(hifDevice, WINDOW_DATA_ADDRESS, - (A_UCHAR *)data, + (u8 *)data, sizeof(u32), HIF_RD_SYNC_BYTE_INC, NULL); @@ -228,7 +228,7 @@ ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data) /* set write data */ status = HIFReadWrite(hifDevice, WINDOW_DATA_ADDRESS, - (A_UCHAR *)data, + (u8 *)data, sizeof(u32), HIF_WR_SYNC_BYTE_INC, NULL); @@ -245,7 +245,7 @@ ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data) int ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, u32 address, - A_UCHAR *data, u32 length) + u8 *data, u32 length) { u32 count; int status = 0; @@ -263,7 +263,7 @@ ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, u32 address, int ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, u32 address, - A_UCHAR *data, u32 length) + u8 *data, u32 length) { u32 count; int status = 0; @@ -283,8 +283,8 @@ int ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, u32 *regval) { int status; - A_UCHAR vals[4]; - A_UCHAR register_selection[4]; + u8 vals[4]; + u8 register_selection[4]; register_selection[0] = register_selection[1] = register_selection[2] = register_selection[3] = (regsel & 0xff); status = HIFReadWrite(hifDevice, @@ -301,7 +301,7 @@ ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, u32 *regval) status = HIFReadWrite(hifDevice, CPU_DBG_ADDRESS, - (A_UCHAR *)vals, + (u8 *)vals, sizeof(vals), HIF_RD_SYNC_BYTE_INC, NULL); @@ -489,7 +489,7 @@ ar6000_copy_cust_data_from_target(HIF_DEVICE *hifDevice, u32 TargetType) if (BMIReadMemory(hifDevice, HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_board_data), - (A_UCHAR *)&eepHeaderAddr, + (u8 *)&eepHeaderAddr, 4)!= 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadMemory for reading board data address failed \n")); @@ -595,7 +595,7 @@ void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, u32 TargetType) /* fetch register dump data */ status = ar6000_ReadDataDiag(hifDevice, regDumpArea, - (A_UCHAR *)®DumpValues[0], + (u8 *)®DumpValues[0], regDumpCount * (sizeof(u32))); if (status) { @@ -654,7 +654,7 @@ int ar6000_set_htc_params(HIF_DEVICE *hifDevice, /* set the host interest area for the block size */ status = BMIWriteMemory(hifDevice, HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_io_block_sz), - (A_UCHAR *)&blocksizes[1], + (u8 *)&blocksizes[1], 4); if (status) { @@ -669,7 +669,7 @@ int ar6000_set_htc_params(HIF_DEVICE *hifDevice, /* set the host interest area for the mbox ISR yield limit */ status = BMIWriteMemory(hifDevice, HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_isr_yield_limit), - (A_UCHAR *)&MboxIsrYieldValue, + (u8 *)&MboxIsrYieldValue, 4); if (status) { @@ -796,7 +796,7 @@ ar6002_REV1_reset_force_host (HIF_DEVICE *hifDevice) #endif /* CONFIG_AR6002_REV1_FORCE_HOST */ -void DebugDumpBytes(A_UCHAR *buffer, u16 length, char *pDescription) +void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription) { char stream[60]; char byteOffsetStr[10]; @@ -1015,7 +1015,7 @@ int ar6000_set_hci_bridge_flags(HIF_DEVICE *hifDevice, /* set hci bridge flags */ status = BMIWriteMemory(hifDevice, HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_hci_bridge_flags), - (A_UCHAR *)&Flags, + (u8 *)&Flags, 4); diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index e8277ffce240..f8d8999b90e0 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -416,7 +416,7 @@ ar6000_set_host_app_area(AR_SOFTC_T *ar) address = TARG_VTOP(ar->arTargetType, data); host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION; if (ar6000_WriteDataDiag(ar->arHifDevice, address, - (A_UCHAR *)&host_app_area, + (u8 *)&host_app_area, sizeof(struct host_app_area_s)) != 0) { return A_ERROR; @@ -433,7 +433,7 @@ u32 dbglog_get_debug_hdr_ptr(AR_SOFTC_T *ar) address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbglog_hdr)); if ((status = ar6000_ReadDataDiag(ar->arHifDevice, address, - (A_UCHAR *)¶m, 4)) != 0) + (u8 *)¶m, 4)) != 0) { param = 0; } @@ -550,13 +550,13 @@ ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar) address = TARG_VTOP(ar->arTargetType, debug_hdr_ptr); length = 4 /* sizeof(dbuf) */ + 4 /* sizeof(dropped) */; A_MEMZERO(data, sizeof(data)); - ar6000_ReadDataDiag(ar->arHifDevice, address, (A_UCHAR *)data, length); + ar6000_ReadDataDiag(ar->arHifDevice, address, (u8 *)data, length); address = TARG_VTOP(ar->arTargetType, data[0] /* dbuf */); firstbuf = address; dropped = data[1]; /* dropped */ length = 4 /* sizeof(next) */ + 4 /* sizeof(buffer) */ + 4 /* sizeof(bufsize) */ + 4 /* sizeof(length) */ + 4 /* sizeof(count) */ + 4 /* sizeof(free) */; A_MEMZERO(data, sizeof(data)); - ar6000_ReadDataDiag(ar->arHifDevice, address, (A_UCHAR *)&data, length); + ar6000_ReadDataDiag(ar->arHifDevice, address, (u8 *)&data, length); do { address = TARG_VTOP(ar->arTargetType, data[1] /* buffer*/); @@ -567,7 +567,7 @@ ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar) ar->log_cnt = 0; } if(0 != ar6000_ReadDataDiag(ar->arHifDevice, address, - (A_UCHAR *)&ar->log_buffer[ar->log_cnt], length)) + (u8 *)&ar->log_buffer[ar->log_cnt], length)) { break; } @@ -582,7 +582,7 @@ ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar) length = 4 /* sizeof(next) */ + 4 /* sizeof(buffer) */ + 4 /* sizeof(bufsize) */ + 4 /* sizeof(length) */ + 4 /* sizeof(count) */ + 4 /* sizeof(free) */; A_MEMZERO(data, sizeof(data)); if(0 != ar6000_ReadDataDiag(ar->arHifDevice, address, - (A_UCHAR *)&data, length)) + (u8 *)&data, length)) { break; } @@ -816,7 +816,7 @@ ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj, if (index == MAX_AR6000) return 0; - if ((BMIRawRead(ar->arHifDevice, (A_UCHAR*)buf, count, true)) != 0) { + if ((BMIRawRead(ar->arHifDevice, (u8*)buf, count, true)) != 0) { return 0; } @@ -843,7 +843,7 @@ ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj, if (index == MAX_AR6000) return 0; - if ((BMIRawWrite(ar->arHifDevice, (A_UCHAR*)buf, count)) != 0) { + if ((BMIRawWrite(ar->arHifDevice, (u8*)buf, count)) != 0) { return 0; } @@ -900,7 +900,7 @@ ar6000_sysfs_bmi_deinit(AR_SOFTC_T *ar) #define AR6002_MAC_ADDRESS_OFFSET 0x0A #define AR6003_MAC_ADDRESS_OFFSET 0x16 static -void calculate_crc(u32 TargetType, A_UCHAR *eeprom_data) +void calculate_crc(u32 TargetType, u8 *eeprom_data) { u16 *ptr_crc; u16 *ptr16_eeprom; @@ -916,12 +916,12 @@ void calculate_crc(u32 TargetType, A_UCHAR *eeprom_data) else if (TargetType == TARGET_TYPE_AR6003) { eeprom_size = 1024; - ptr_crc = (u16 *)((A_UCHAR *)eeprom_data + 0x04); + ptr_crc = (u16 *)((u8 *)eeprom_data + 0x04); } else { eeprom_size = 768; - ptr_crc = (u16 *)((A_UCHAR *)eeprom_data + 0x04); + ptr_crc = (u16 *)((u8 *)eeprom_data + 0x04); } @@ -941,17 +941,17 @@ void calculate_crc(u32 TargetType, A_UCHAR *eeprom_data) } static void -ar6000_softmac_update(AR_SOFTC_T *ar, A_UCHAR *eeprom_data, size_t size) +ar6000_softmac_update(AR_SOFTC_T *ar, u8 *eeprom_data, size_t size) { const char *source = "random generated"; const struct firmware *softmac_entry; - A_UCHAR *ptr_mac; + u8 *ptr_mac; switch (ar->arTargetType) { case TARGET_TYPE_AR6002: - ptr_mac = (u8 *)((A_UCHAR *)eeprom_data + AR6002_MAC_ADDRESS_OFFSET); + ptr_mac = (u8 *)((u8 *)eeprom_data + AR6002_MAC_ADDRESS_OFFSET); break; case TARGET_TYPE_AR6003: - ptr_mac = (u8 *)((A_UCHAR *)eeprom_data + AR6003_MAC_ADDRESS_OFFSET); + ptr_mac = (u8 *)((u8 *)eeprom_data + AR6003_MAC_ADDRESS_OFFSET); break; default: AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid Target Type\n")); @@ -1097,7 +1097,7 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, u32 address, bool c #ifdef SOFTMAC_FILE_USED if (file==AR6K_BOARD_DATA_FILE && fw_entry->data) { - ar6000_softmac_update(ar, (A_UCHAR *)fw_entry->data, fw_entry->size); + ar6000_softmac_update(ar, (u8 *)fw_entry->data, fw_entry->size); } #endif @@ -1117,14 +1117,14 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, u32 address, bool c (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_BOARD_DATA_SZ : 0)); /* Determine where in Target RAM to write Board Data */ - bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data), (A_UCHAR *)&board_ext_address, 4)); + bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data), (u8 *)&board_ext_address, 4)); AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board extended Data download address: 0x%x\n", board_ext_address)); /* check whether the target has allocated memory for extended board data and file contains extended board data */ if ((board_ext_address) && (fw_entry->size == (board_data_size + board_ext_data_size))) { u32 param; - status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (A_UCHAR *)(fw_entry->data + board_data_size), board_ext_data_size); + status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (u8 *)(fw_entry->data + board_data_size), board_ext_data_size); if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); @@ -1134,15 +1134,15 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, u32 address, bool c /* Record the fact that extended board Data IS initialized */ param = 1; - bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data_initialized), (A_UCHAR *)¶m, 4)); + bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data_initialized), (u8 *)¶m, 4)); } fw_entry_size = board_data_size; } if (compressed) { - status = BMIFastDownload(ar->arHifDevice, address, (A_UCHAR *)fw_entry->data, fw_entry_size); + status = BMIFastDownload(ar->arHifDevice, address, (u8 *)fw_entry->data, fw_entry_size); } else { - status = BMIWriteMemory(ar->arHifDevice, address, (A_UCHAR *)fw_entry->data, fw_entry_size); + status = BMIWriteMemory(ar->arHifDevice, address, (u8 *)fw_entry->data, fw_entry_size); } if (status) { @@ -1163,13 +1163,13 @@ ar6000_update_bdaddr(AR_SOFTC_T *ar) u32 address; if (BMIReadMemory(ar->arHifDevice, - HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (A_UCHAR *)&address, 4) != 0) + HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (u8 *)&address, 4) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for hi_board_data failed\n")); return A_ERROR; } - if (BMIReadMemory(ar->arHifDevice, address + BDATA_BDADDR_OFFSET, (A_UCHAR *)ar->bdaddr, 6) != 0) + if (BMIReadMemory(ar->arHifDevice, address + BDATA_BDADDR_OFFSET, (u8 *)ar->bdaddr, 6) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for BD address failed\n")); return A_ERROR; @@ -1234,7 +1234,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, u32 mode) param = 0; if (ar->arTargetType == TARGET_TYPE_AR6002) { - bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ext_clk_detected), (A_UCHAR *)¶m, 4)); + bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ext_clk_detected), (u8 *)¶m, 4)); } /* LPO_CAL.ENABLE = 1 if no external clk is detected */ @@ -1267,7 +1267,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, u32 mode) if (ar->arTargetType == TARGET_TYPE_AR6003) { /* hi_ext_clk_detected = 0 */ param = 0; - bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ext_clk_detected), (A_UCHAR *)¶m, 4)); + bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ext_clk_detected), (u8 *)¶m, 4)); /* CLOCK_CONTROL &= ~LF_CLK32 */ address = RTC_BASE_ADDRESS + CLOCK_CONTROL_ADDRESS; @@ -1280,7 +1280,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, u32 mode) /* Transfer Board Data from Target EEPROM to Target RAM */ if (ar->arTargetType == TARGET_TYPE_AR6003) { /* Determine where in Target RAM to write Board Data */ - bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (A_UCHAR *)&address, 4)); + bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (u8 *)&address, 4)); AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board Data download address: 0x%x\n", address)); /* Write EEPROM data to Target RAM */ @@ -1290,7 +1290,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, u32 mode) /* Record the fact that Board Data IS initialized */ param = 1; - bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data_initialized), (A_UCHAR *)¶m, 4)); + bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data_initialized), (u8 *)¶m, 4)); /* Transfer One time Programmable data */ AR6K_DATA_DOWNLOAD_ADDRESS(address, ar->arVersion.target_ver); @@ -1325,7 +1325,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, u32 mode) } param = address; - bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dset_list_head), (A_UCHAR *)¶m, 4)); + bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dset_list_head), (u8 *)¶m, 4)); if (ar->arTargetType == TARGET_TYPE_AR6003) { if (ar->arVersion.target_ver == AR6003_REV1_VERSION) { @@ -1335,7 +1335,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, u32 mode) /* Reserve 6.5K of RAM */ param = 6656; } - bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_end_RAM_reserve_sz), (A_UCHAR *)¶m, 4)); + bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_end_RAM_reserve_sz), (u8 *)¶m, 4)); } /* Restore system sleep */ @@ -1352,7 +1352,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, u32 mode) #define CONFIG_AR600x_DEBUG_UART_TX_PIN 8 #endif param = CONFIG_AR600x_DEBUG_UART_TX_PIN; - bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbg_uart_txpin), (A_UCHAR *)¶m, 4)); + bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbg_uart_txpin), (u8 *)¶m, 4)); #if (CONFIG_AR600x_DEBUG_UART_TX_PIN == 23) { @@ -1367,7 +1367,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, u32 mode) #ifdef ATH6KL_CONFIG_GPIO_BT_RESET #define CONFIG_AR600x_BT_RESET_PIN 0x16 param = CONFIG_AR600x_BT_RESET_PIN; - bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_support_pins), (A_UCHAR *)¶m, 4)); + bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_support_pins), (u8 *)¶m, 4)); #endif /* ATH6KL_CONFIG_GPIO_BT_RESET */ /* Configure UART flow control polarity */ @@ -1378,7 +1378,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, u32 mode) #if (CONFIG_ATH6KL_BT_UART_FC_POLARITY == 1) if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { param = ((CONFIG_ATH6KL_BT_UART_FC_POLARITY << 1) & 0x2); - bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_pwr_mgmt_params), (A_UCHAR *)¶m, 4)); + bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_pwr_mgmt_params), (u8 *)¶m, 4)); } #endif /* CONFIG_ATH6KL_BT_UART_FC_POLARITY */ } @@ -1405,7 +1405,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) param = 1; if (BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_serial_enable), - (A_UCHAR *)¶m, + (u8 *)¶m, 4)!= 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enableuartprint failed \n")); @@ -1418,7 +1418,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) param = HTC_PROTOCOL_VERSION; if (BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest), - (A_UCHAR *)¶m, + (u8 *)¶m, 4)!= 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for htc version failed \n")); @@ -1437,7 +1437,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) if (BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), - (A_UCHAR *)¶m, + (u8 *)¶m, 4)!= 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for enabletimerwar failed \n")); @@ -1448,7 +1448,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) if (BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), - (A_UCHAR *)¶m, + (u8 *)¶m, 4) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enabletimerwar failed \n")); @@ -1463,7 +1463,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) if (BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), - (A_UCHAR *)¶m, + (u8 *)¶m, 4)!= 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for setting fwmode failed \n")); @@ -1474,7 +1474,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) if (BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), - (A_UCHAR *)¶m, + (u8 *)¶m, 4) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for setting fwmode failed \n")); @@ -1489,7 +1489,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) if (BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), - (A_UCHAR *)¶m, + (u8 *)¶m, 4)!= 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for disabling debug logs failed\n")); @@ -1500,7 +1500,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) if (BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), - (A_UCHAR *)¶m, + (u8 *)¶m, 4) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for HI_OPTION_DISABLE_DBGLOG\n")); @@ -1522,7 +1522,7 @@ ar6000_configure_target(AR_SOFTC_T *ar) param = AR6003_BOARD_EXT_DATA_ADDRESS; if (BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data), - (A_UCHAR *)¶m, + (u8 *)¶m, 4) != 0) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for hi_board_ext_data failed \n")); diff --git a/drivers/staging/ath6kl/os/linux/eeprom.c b/drivers/staging/ath6kl/os/linux/eeprom.c index 7d7a63dd6f0e..7d049dffd222 100644 --- a/drivers/staging/ath6kl/os/linux/eeprom.c +++ b/drivers/staging/ath6kl/os/linux/eeprom.c @@ -53,7 +53,7 @@ char *p_mac = NULL; // static variables // -static A_UCHAR eeprom_data[EEPROM_SZ]; +static u8 eeprom_data[EEPROM_SZ]; static u32 sys_sleep_reg; static HIF_DEVICE *p_bmi_device; @@ -143,14 +143,14 @@ BMI_write_reg(u32 address, u32 value) inline void BMI_read_mem(u32 address, u32 *pvalue) { - BMIReadMemory(p_bmi_device, address, (A_UCHAR*)(pvalue), 4); + BMIReadMemory(p_bmi_device, address, (u8*)(pvalue), 4); } /* Write a word to a Target memory. */ inline void BMI_write_mem(u32 address, u8 *p_data, u32 sz) { - BMIWriteMemory(p_bmi_device, address, (A_UCHAR*)(p_data), sz); + BMIWriteMemory(p_bmi_device, address, (u8*)(p_data), sz); } /* diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index f3b7344d6675..0beba096e9d1 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -553,7 +553,7 @@ typedef struct ar6_softc { COMMON_CREDIT_STATE_INFO arCreditStateInfo; bool arWMIControlEpFull; bool dbgLogFetchInProgress; - A_UCHAR log_buffer[DBGLOG_HOST_LOG_BUFFER_SIZE]; + u8 log_buffer[DBGLOG_HOST_LOG_BUFFER_SIZE]; u32 log_cnt; u32 dbglog_init_done; u32 arConnectCtrlFlags; diff --git a/drivers/staging/ath6kl/os/linux/include/athtypes_linux.h b/drivers/staging/ath6kl/os/linux/include/athtypes_linux.h index 32bd29ba455d..8cb563203057 100644 --- a/drivers/staging/ath6kl/os/linux/include/athtypes_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/athtypes_linux.h @@ -45,7 +45,6 @@ typedef u_int32_t A_UINT32; typedef u_int64_t A_UINT64; typedef char A_CHAR; -typedef unsigned char A_UCHAR; typedef unsigned long A_ATH_TIMER; diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index a95b7430ad8f..18244757ae37 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -702,8 +702,8 @@ ar6000_ioctl_tcmd_get_rx_report(struct net_device *dev, buf[1] = ar->tcmdRxRssi; buf[2] = ar->tcmdRxcrcErrPkt; buf[3] = ar->tcmdRxsecErrPkt; - memcpy(((A_UCHAR *)buf)+(4*sizeof(u32)), ar->tcmdRateCnt, sizeof(ar->tcmdRateCnt)); - memcpy(((A_UCHAR *)buf)+(4*sizeof(u32))+(TCMD_MAX_RATES *sizeof(u16)), ar->tcmdRateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard)); + memcpy(((u8 *)buf)+(4*sizeof(u32)), ar->tcmdRateCnt, sizeof(ar->tcmdRateCnt)); + memcpy(((u8 *)buf)+(4*sizeof(u32))+(TCMD_MAX_RATES *sizeof(u16)), ar->tcmdRateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard)); if (!ret && copy_to_user(rq->ifr_data, buf, sizeof(buf))) { ret = -EFAULT; diff --git a/drivers/staging/ath6kl/wlan/src/wlan_node.c b/drivers/staging/ath6kl/wlan/src/wlan_node.c index 0edf9c184efb..83c4dc35e404 100644 --- a/drivers/staging/ath6kl/wlan/src/wlan_node.c +++ b/drivers/staging/ath6kl/wlan/src/wlan_node.c @@ -432,11 +432,11 @@ wlan_node_table_cleanup(struct ieee80211_node_table *nt) } bss_t * -wlan_find_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid, +wlan_find_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid, u32 ssidLength, bool bIsWPA2, bool bMatchSSID) { bss_t *ni = NULL; - A_UCHAR *pIESsid = NULL; + u8 *pIESsid = NULL; IEEE80211_NODE_LOCK (nt); @@ -554,13 +554,13 @@ wlan_node_remove(struct ieee80211_node_table *nt, u8 *bssid) } bss_t * -wlan_find_matching_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid, +wlan_find_matching_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid, u32 ssidLength, u32 dot11AuthMode, u32 authMode, u32 pairwiseCryptoType, u32 grpwiseCryptoTyp) { bss_t *ni = NULL; bss_t *best_ni = NULL; - A_UCHAR *pIESsid = NULL; + u8 *pIESsid = NULL; IEEE80211_NODE_LOCK (nt); diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index bf9dd0bd3af3..80ba629f94bd 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -1421,8 +1421,8 @@ wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len) WMI_BSS_INFO_HDR *bih; u8 *buf; u32 nodeCachingAllowed = 1; - A_UCHAR cached_ssid_len = 0; - A_UCHAR cached_ssid_buf[IEEE80211_NWID_LEN] = {0}; + u8 cached_ssid_len = 0; + u8 cached_ssid_buf[IEEE80211_NWID_LEN] = {0}; u8 beacon_ssid_len = 0; if (len <= sizeof(WMI_BSS_INFO_HDR)) { @@ -1477,7 +1477,7 @@ wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len) * so cache the probe-resp-ssid if already present. */ if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType)) { - A_UCHAR *ie_ssid; + u8 *ie_ssid; ie_ssid = bss->ni_cie.ie_ssid; if(ie_ssid && (ie_ssid[1] <= IEEE80211_NWID_LEN) && (ie_ssid[2] != 0)) @@ -2420,7 +2420,7 @@ wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType, DOT11_AUTH_MODE dot11AuthMode, AUTH_MODE authMode, CRYPTO_TYPE pairwiseCrypto, u8 pairwiseCryptoLen, CRYPTO_TYPE groupCrypto, u8 groupCryptoLen, - int ssidLength, A_UCHAR *ssid, + int ssidLength, u8 *ssid, u8 *bssid, u16 channel, u32 ctrl_flags) { void *osbuf; @@ -2616,7 +2616,7 @@ wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, u32 ieMask) int wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag, - u8 ssidLength, A_UCHAR *ssid) + u8 ssidLength, u8 *ssid) { void *osbuf; WMI_PROBED_SSID_CMD *cmd; @@ -4844,7 +4844,7 @@ wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG cfg) } int -wmi_set_country(struct wmi_t *wmip, A_UCHAR *countryCode) +wmi_set_country(struct wmi_t *wmip, u8 *countryCode) { void *osbuf; WMI_AP_SET_COUNTRY_CMD *cmd; @@ -5374,7 +5374,7 @@ wmi_set_nodeage(struct wmi_t *wmip, u32 nodeAge) } bss_t * -wmi_find_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid, +wmi_find_Ssidnode (struct wmi_t *wmip, u8 *pSsid, u32 ssidLength, bool bIsWPA2, bool bMatchSSID) { bss_t *node = NULL; @@ -6652,7 +6652,7 @@ wmi_SGI_cmd(struct wmi_t *wmip, u32 sgiMask, u8 sgiPERThreshold) } bss_t * -wmi_find_matching_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid, +wmi_find_matching_Ssidnode (struct wmi_t *wmip, u8 *pSsid, u32 ssidLength, u32 dot11AuthMode, u32 authMode, u32 pairwiseCryptoType, u32 grpwiseCryptoTyp) -- cgit v1.2.3 From ebb1f944f82ca3ee95415cf7cc174375562d6c8d Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 10 Mar 2011 18:55:32 -0800 Subject: staging: ath6kl: remove-typedef AGGR_INFO remove-typedef -s AGGR_INFO \ "struct aggr_info" drivers/staging/ath6kl/ Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/reorder/aggr_rx_internal.h | 4 +-- drivers/staging/ath6kl/reorder/rcv_aggr.c | 42 +++++++++++------------ 2 files changed, 23 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h index 523a23904499..20c894dcc717 100644 --- a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h +++ b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h @@ -100,7 +100,7 @@ typedef struct { u32 num_bar; /* num of resets of seq_num, via BAR */ }RXTID_STATS; -typedef struct { +struct aggr_info { u8 aggr_sz; /* config value of aggregation size */ u8 timerScheduled; A_TIMER timer; /* timer for returning held up pkts in re-order que */ @@ -111,6 +111,6 @@ typedef struct { A_NETBUF_QUEUE_T freeQ; /* pre-allocated buffers - for A_MSDU slicing */ RXTID_STATS stat[NUM_OF_TIDS]; /* Tid based statistics */ PACKET_LOG pkt_log; /* Log info of the packets */ -}AGGR_INFO; +}; #endif /* __AGGR_RX_INTERNAL_H__ */ diff --git a/drivers/staging/ath6kl/reorder/rcv_aggr.c b/drivers/staging/ath6kl/reorder/rcv_aggr.c index adb85eb0412d..8beb00dae5f0 100644 --- a/drivers/staging/ath6kl/reorder/rcv_aggr.c +++ b/drivers/staging/ath6kl/reorder/rcv_aggr.c @@ -37,24 +37,24 @@ extern int wmi_dot3_2_dix(void *osbuf); static void -aggr_slice_amsdu(AGGR_INFO *p_aggr, RXTID *rxtid, void **osbuf); +aggr_slice_amsdu(struct aggr_info *p_aggr, RXTID *rxtid, void **osbuf); static void aggr_timeout(A_ATH_TIMER arg); static void -aggr_deque_frms(AGGR_INFO *p_aggr, u8 tid, u16 seq_no, u8 order); +aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 seq_no, u8 order); static void -aggr_dispatch_frames(AGGR_INFO *p_aggr, A_NETBUF_QUEUE_T *q); +aggr_dispatch_frames(struct aggr_info *p_aggr, A_NETBUF_QUEUE_T *q); static void * -aggr_get_osbuf(AGGR_INFO *p_aggr); +aggr_get_osbuf(struct aggr_info *p_aggr); void * aggr_init(ALLOC_NETBUFS netbuf_allocator) { - AGGR_INFO *p_aggr = NULL; + struct aggr_info *p_aggr = NULL; RXTID *rxtid; u8 i; int status = 0; @@ -62,7 +62,7 @@ aggr_init(ALLOC_NETBUFS netbuf_allocator) A_PRINTF("In aggr_init..\n"); do { - p_aggr = A_MALLOC(sizeof(AGGR_INFO)); + p_aggr = A_MALLOC(sizeof(struct aggr_info)); if(!p_aggr) { A_PRINTF("Failed to allocate memory for aggr_node\n"); status = A_ERROR; @@ -70,7 +70,7 @@ aggr_init(ALLOC_NETBUFS netbuf_allocator) } /* Init timer and data structures */ - A_MEMZERO(p_aggr, sizeof(AGGR_INFO)); + A_MEMZERO(p_aggr, sizeof(struct aggr_info)); p_aggr->aggr_sz = AGGR_SZ_DEFAULT; A_INIT_TIMER(&p_aggr->timer, aggr_timeout, p_aggr); p_aggr->timerScheduled = false; @@ -101,7 +101,7 @@ aggr_init(ALLOC_NETBUFS netbuf_allocator) /* utility function to clear rx hold_q for a tid */ static void -aggr_delete_tid_state(AGGR_INFO *p_aggr, u8 tid) +aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid) { RXTID *rxtid; RXTID_STATS *stats; @@ -133,7 +133,7 @@ aggr_delete_tid_state(AGGR_INFO *p_aggr, u8 tid) void aggr_module_destroy(void *cntxt) { - AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; + struct aggr_info *p_aggr = (struct aggr_info *)cntxt; RXTID *rxtid; u8 i, k; A_PRINTF("%s(): aggr = %p\n",_A_FUNCNAME_, p_aggr); @@ -177,7 +177,7 @@ aggr_module_destroy(void *cntxt) void aggr_register_rx_dispatcher(void *cntxt, void * dev, RX_CALLBACK fn) { - AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; + struct aggr_info *p_aggr = (struct aggr_info *)cntxt; A_ASSERT(p_aggr && fn && dev); @@ -189,7 +189,7 @@ aggr_register_rx_dispatcher(void *cntxt, void * dev, RX_CALLBACK fn) void aggr_process_bar(void *cntxt, u8 tid, u16 seq_no) { - AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; + struct aggr_info *p_aggr = (struct aggr_info *)cntxt; RXTID_STATS *stats; A_ASSERT(p_aggr); @@ -203,7 +203,7 @@ aggr_process_bar(void *cntxt, u8 tid, u16 seq_no) void aggr_recv_addba_req_evt(void *cntxt, u8 tid, u16 seq_no, u8 win_sz) { - AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; + struct aggr_info *p_aggr = (struct aggr_info *)cntxt; RXTID *rxtid; RXTID_STATS *stats; @@ -255,7 +255,7 @@ aggr_recv_addba_req_evt(void *cntxt, u8 tid, u16 seq_no, u8 win_sz) void aggr_recv_delba_req_evt(void *cntxt, u8 tid) { - AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; + struct aggr_info *p_aggr = (struct aggr_info *)cntxt; RXTID *rxtid; A_ASSERT(p_aggr); @@ -269,7 +269,7 @@ aggr_recv_delba_req_evt(void *cntxt, u8 tid) } static void -aggr_deque_frms(AGGR_INFO *p_aggr, u8 tid, u16 seq_no, u8 order) +aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 seq_no, u8 order) { RXTID *rxtid; OSBUF_HOLD_Q *node; @@ -334,7 +334,7 @@ aggr_deque_frms(AGGR_INFO *p_aggr, u8 tid, u16 seq_no, u8 order) } static void * -aggr_get_osbuf(AGGR_INFO *p_aggr) +aggr_get_osbuf(struct aggr_info *p_aggr) { void *buf = NULL; @@ -356,7 +356,7 @@ aggr_get_osbuf(AGGR_INFO *p_aggr) static void -aggr_slice_amsdu(AGGR_INFO *p_aggr, RXTID *rxtid, void **osbuf) +aggr_slice_amsdu(struct aggr_info *p_aggr, RXTID *rxtid, void **osbuf) { void *new_buf; u16 frame_8023_len, payload_8023_len, mac_hdr_len, amsdu_len; @@ -428,7 +428,7 @@ aggr_slice_amsdu(AGGR_INFO *p_aggr, RXTID *rxtid, void **osbuf) void aggr_process_recv_frm(void *cntxt, u8 tid, u16 seq_no, bool is_amsdu, void **osbuf) { - AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; + struct aggr_info *p_aggr = (struct aggr_info *)cntxt; RXTID *rxtid; RXTID_STATS *stats; u16 idx, st, cur, end; @@ -562,7 +562,7 @@ void aggr_reset_state(void *cntxt) { u8 tid; - AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; + struct aggr_info *p_aggr = (struct aggr_info *)cntxt; A_ASSERT(p_aggr); @@ -576,7 +576,7 @@ static void aggr_timeout(A_ATH_TIMER arg) { u8 i,j; - AGGR_INFO *p_aggr = (AGGR_INFO *)arg; + struct aggr_info *p_aggr = (struct aggr_info *)arg; RXTID *rxtid; RXTID_STATS *stats; /* @@ -630,7 +630,7 @@ aggr_timeout(A_ATH_TIMER arg) } static void -aggr_dispatch_frames(AGGR_INFO *p_aggr, A_NETBUF_QUEUE_T *q) +aggr_dispatch_frames(struct aggr_info *p_aggr, A_NETBUF_QUEUE_T *q) { void *osbuf; @@ -642,7 +642,7 @@ aggr_dispatch_frames(AGGR_INFO *p_aggr, A_NETBUF_QUEUE_T *q) void aggr_dump_stats(void *cntxt, PACKET_LOG **log_buf) { - AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; + struct aggr_info *p_aggr = (struct aggr_info *)cntxt; RXTID *rxtid; RXTID_STATS *stats; u8 i; -- cgit v1.2.3 From 854019a3c6a0435b468e4a3f5e545a770d5cdf6f Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 10 Mar 2011 18:55:33 -0800 Subject: staging: ath6kl: remove-typedef AR3K_CONFIG_INFO remove-typedef -s AR3K_CONFIG_INFO \ "struct ar3k_config_info" drivers/staging/ath6kl/ Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/include/ar3kconfig.h | 6 +++--- drivers/staging/ath6kl/miscdrv/ar3kconfig.c | 20 ++++++++++---------- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c | 22 +++++++++++----------- .../staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h | 4 ++-- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 2 +- drivers/staging/ath6kl/os/linux/hci_bridge.c | 6 +++--- 6 files changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/include/ar3kconfig.h b/drivers/staging/ath6kl/include/ar3kconfig.h index 4d732019cf2c..20d295ba0da4 100644 --- a/drivers/staging/ath6kl/include/ar3kconfig.h +++ b/drivers/staging/ath6kl/include/ar3kconfig.h @@ -38,7 +38,7 @@ extern "C" { #define AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP (1 << 3) -typedef struct { +struct ar3k_config_info { u32 Flags; /* config flags */ void *pHCIDev; /* HCI bridge device */ HCI_TRANSPORT_PROPERTIES *pHCIProps; /* HCI bridge props */ @@ -52,9 +52,9 @@ typedef struct { u16 IdleTimeout; /* TLPM idle timeout */ u16 WakeupTimeout; /* TLPM wakeup timeout */ u8 bdaddr[6]; /* Bluetooth device address */ -} AR3K_CONFIG_INFO; +}; -int AR3KConfigure(AR3K_CONFIG_INFO *pConfigInfo); +int AR3KConfigure(struct ar3k_config_info *pConfigInfo); int AR3KConfigureExit(void *config); diff --git a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c index 005b3ba23b4e..3e9c95ea4eb4 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c @@ -47,9 +47,9 @@ #define HCI_MAX_EVT_RECV_LENGTH 257 #define EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET 5 -int AthPSInitialize(AR3K_CONFIG_INFO *hdev); +int AthPSInitialize(struct ar3k_config_info *hdev); -static int SendHCICommand(AR3K_CONFIG_INFO *pConfig, +static int SendHCICommand(struct ar3k_config_info *pConfig, u8 *pBuffer, int Length) { @@ -84,7 +84,7 @@ static int SendHCICommand(AR3K_CONFIG_INFO *pConfig, return status; } -static int RecvHCIEvent(AR3K_CONFIG_INFO *pConfig, +static int RecvHCIEvent(struct ar3k_config_info *pConfig, u8 *pBuffer, int *pLength) { @@ -122,7 +122,7 @@ static int RecvHCIEvent(AR3K_CONFIG_INFO *pConfig, return status; } -int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, +int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig, u8 *pHCICommand, int CmdLength, u8 **ppEventBuffer, @@ -209,7 +209,7 @@ int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, return status; } -static int AR3KConfigureHCIBaud(AR3K_CONFIG_INFO *pConfig) +static int AR3KConfigureHCIBaud(struct ar3k_config_info *pConfig) { int status = 0; u8 hciBaudChangeCommand[] = {0x0c,0xfc,0x2,0,0}; @@ -274,7 +274,7 @@ static int AR3KConfigureHCIBaud(AR3K_CONFIG_INFO *pConfig) return status; } -static int AR3KExitMinBoot(AR3K_CONFIG_INFO *pConfig) +static int AR3KExitMinBoot(struct ar3k_config_info *pConfig) { int status; char exitMinBootCmd[] = {0x25,0xFC,0x0c,0x03,0x00,0x00,0x00,0x00,0x00,0x00, @@ -310,7 +310,7 @@ static int AR3KExitMinBoot(AR3K_CONFIG_INFO *pConfig) return status; } -static int AR3KConfigureSendHCIReset(AR3K_CONFIG_INFO *pConfig) +static int AR3KConfigureSendHCIReset(struct ar3k_config_info *pConfig) { int status = 0; u8 hciResetCommand[] = {0x03,0x0c,0x0}; @@ -334,7 +334,7 @@ static int AR3KConfigureSendHCIReset(AR3K_CONFIG_INFO *pConfig) return status; } -static int AR3KEnableTLPM(AR3K_CONFIG_INFO *pConfig) +static int AR3KEnableTLPM(struct ar3k_config_info *pConfig) { int status; /* AR3K vendor specific command for Host Wakeup Config */ @@ -453,7 +453,7 @@ static int AR3KEnableTLPM(AR3K_CONFIG_INFO *pConfig) return status; } -int AR3KConfigure(AR3K_CONFIG_INFO *pConfig) +int AR3KConfigure(struct ar3k_config_info *pConfig) { int status = 0; @@ -524,7 +524,7 @@ int AR3KConfigure(AR3K_CONFIG_INFO *pConfig) int AR3KConfigureExit(void *config) { int status = 0; - AR3K_CONFIG_INFO *pConfig = (AR3K_CONFIG_INFO *)config; + struct ar3k_config_info *pConfig = (struct ar3k_config_info *)config; AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Cleaning up AR3K ...\n")); diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c index 3dce6f5e239a..3436cbdf59bd 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c @@ -43,10 +43,10 @@ typedef struct { PSCmdPacket *HciCmdList; u32 num_packets; - AR3K_CONFIG_INFO *dev; + struct ar3k_config_info *dev; }HciCommandListParam; -int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, +int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig, u8 *pHCICommand, int CmdLength, u8 **ppEventBuffer, @@ -56,8 +56,8 @@ u32 Rom_Version; u32 Build_Version; extern bool BDADDR; -int getDeviceType(AR3K_CONFIG_INFO *pConfig, u32 *code); -int ReadVersionInfo(AR3K_CONFIG_INFO *pConfig); +int getDeviceType(struct ar3k_config_info *pConfig, u32 *code); +int ReadVersionInfo(struct ar3k_config_info *pConfig); #ifndef HCI_TRANSPORT_SDIO DECLARE_WAIT_QUEUE_HEAD(PsCompleteEvent); @@ -70,7 +70,7 @@ int PSHciWritepacket(struct hci_dev*,u8* Data, u32 len); extern char *bdaddr; #endif /* HCI_TRANSPORT_SDIO */ -int write_bdaddr(AR3K_CONFIG_INFO *pConfig,u8 *bdaddr,int type); +int write_bdaddr(struct ar3k_config_info *pConfig,u8 *bdaddr,int type); int PSSendOps(void *arg); @@ -91,7 +91,7 @@ void Hci_log(u8 * log_string,u8 *data,u32 len) -int AthPSInitialize(AR3K_CONFIG_INFO *hdev) +int AthPSInitialize(struct ar3k_config_info *hdev) { int status = 0; if(hdev == NULL) { @@ -147,7 +147,7 @@ int PSSendOps(void *arg) u8 *path = NULL; u8 *config_path = NULL; u8 config_bdaddr[MAX_BDADDR_FORMAT_LENGTH]; - AR3K_CONFIG_INFO *hdev = (AR3K_CONFIG_INFO*)arg; + struct ar3k_config_info *hdev = (struct ar3k_config_info*)arg; struct device *firmwareDev = NULL; status = 0; HciCmdList = NULL; @@ -389,7 +389,7 @@ complete: * with a HCI Command Complete event. * For HCI SDIO transport, this will be internally defined. */ -int SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig, +int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig, u8 *pHCICommand, int CmdLength, u8 **ppEventBuffer, @@ -481,7 +481,7 @@ int str2ba(unsigned char *str_bdaddr,unsigned char *bdaddr) return 0; } -int write_bdaddr(AR3K_CONFIG_INFO *pConfig,u8 *bdaddr,int type) +int write_bdaddr(struct ar3k_config_info *pConfig,u8 *bdaddr,int type) { u8 bdaddr_cmd[] = { 0x0B, 0xFC, 0x0A, 0x01, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; @@ -516,7 +516,7 @@ int write_bdaddr(AR3K_CONFIG_INFO *pConfig,u8 *bdaddr,int type) return result; } -int ReadVersionInfo(AR3K_CONFIG_INFO *pConfig) +int ReadVersionInfo(struct ar3k_config_info *pConfig) { u8 hciCommand[] = {0x1E,0xfc,0x00}; u8 *event; @@ -531,7 +531,7 @@ int ReadVersionInfo(AR3K_CONFIG_INFO *pConfig) } return result; } -int getDeviceType(AR3K_CONFIG_INFO *pConfig, u32 *code) +int getDeviceType(struct ar3k_config_info *pConfig, u32 *code) { u8 hciCommand[] = {0x05,0xfc,0x05,0x00,0x00,0x00,0x00,0x04}; u8 *event; diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h index b97d91f15f34..d44351307807 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h @@ -64,12 +64,12 @@ #ifndef HCI_TRANSPORT_SDIO -#define AR3K_CONFIG_INFO struct hci_dev +#define struct ar3k_config_info struct hci_dev extern wait_queue_head_t HciEvent; extern wait_queue_t Eventwait; extern u8 *HciEventpacket; #endif /* #ifndef HCI_TRANSPORT_SDIO */ -int AthPSInitialize(AR3K_CONFIG_INFO *hdev); +int AthPSInitialize(struct ar3k_config_info *hdev); int ReadPSEvent(u8* Data); #endif /* __AR3KPSCONFIG_H */ diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index f8d8999b90e0..3397995b1c3d 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -2011,7 +2011,7 @@ ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs) #else // FIXME: workaround to reset BT's UART baud rate to default if (NULL != ar->exitCallback) { - AR3K_CONFIG_INFO ar3kconfig; + struct ar3k_config_info ar3kconfig; int status; A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig)); diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index db38bbfb2a2d..ee52d1195316 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -100,7 +100,7 @@ typedef struct { #define HCI_GET_OP_CODE(p) (((u16)((p)[1])) << 8) | ((u16)((p)[0])) extern unsigned int setupbtdev; -AR3K_CONFIG_INFO ar3kconfig; +struct ar3k_config_info ar3kconfig; #ifdef EXPORT_HCI_BRIDGE_INTERFACE AR6K_HCI_BRIDGE_INFO *g_pHcidevInfo; @@ -222,7 +222,7 @@ static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle, AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext; int status; u32 address, hci_uart_pwr_mgmt_params; -// AR3K_CONFIG_INFO ar3kconfig; +// struct ar3k_config_info ar3kconfig; pHcidevInfo->pHCIDev = HCIHandle; @@ -667,7 +667,7 @@ int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb) void ar6000_set_default_ar3kconfig(AR_SOFTC_T *ar, void *ar3kconfig) { AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)ar->hcidev_info; - AR3K_CONFIG_INFO *config = (AR3K_CONFIG_INFO *)ar3kconfig; + struct ar3k_config_info *config = (struct ar3k_config_info *)ar3kconfig; config->pHCIDev = pHcidevInfo->pHCIDev; config->pHCIProps = &pHcidevInfo->HCIProps; -- cgit v1.2.3 From 06265442028254cce5a6f19dfa0bab11c88f06fe Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 10 Mar 2011 18:55:34 -0800 Subject: staging: ath6kl: remove-typedef AR6000_USER_SETKEYS_INFO remove-typedef -s AR6000_USER_SETKEYS_INFO \ "struct ar6000_user_setkeys_info" drivers/staging/ath6kl/ Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/include/athdrv_linux.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h index 5a6c27e9aa5a..66817c2c5022 100644 --- a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h @@ -625,7 +625,7 @@ typedef enum { * arguments: * UINT32 cmd (AR6000_XIOCTL_USER_SETKEYS) * UINT32 keyOpCtrl - * uses AR6000_USER_SETKEYS_INFO + * uses struct ar6000_user_setkeys_info */ #define AR6000_XIOCTL_USER_SETKEYS 58 #endif /* USER_KEYS */ @@ -1098,10 +1098,9 @@ typedef struct targetStats_cmd_t { #define AR6000_XIOCTL_USER_SETKEYS_RSC_CTRL 1 #define AR6000_USER_SETKEYS_RSC_UNCHANGED 0x00000002 -typedef struct { +struct ar6000_user_setkeys_info { u32 keyOpCtrl; /* Bit Map of Key Mgmt Ctrl Flags */ -} AR6000_USER_SETKEYS_INFO; - +}; /* XXX: unused !? */ /* used by AR6000_XIOCTL_GPIO_OUTPUT_SET */ struct ar6000_gpio_output_set_cmd_s { -- cgit v1.2.3 From 26da4b510dab790905801e99c83230ea517d7eab Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 10 Mar 2011 18:55:35 -0800 Subject: staging: ath6kl: remove-typedef AR6K_ASYNC_REG_IO_BUFFER remove-typedef -s AR6K_ASYNC_REG_IO_BUFFER \ "struct ar6k_async_reg_io_buffer" drivers/staging/ath6kl/ Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index 19d8e706057d..e0c3926c0bcf 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -89,12 +89,12 @@ typedef PREPACK struct _AR6K_GMBOX_CTRL_REGISTERS { #define AR6K_MIN_TRANSFER_SIZE_PER_SCATTER 4*1024 /* buffers for ASYNC I/O */ -typedef struct AR6K_ASYNC_REG_IO_BUFFER { +struct ar6k_async_reg_io_buffer { HTC_PACKET HtcPacket; /* we use an HTC packet as a wrapper for our async register-based I/O */ u8 _Pad1[A_CACHE_LINE_PAD]; u8 Buffer[AR6K_REG_IO_BUFFER_SIZE]; /* cache-line safe with pads around */ u8 _Pad2[A_CACHE_LINE_PAD]; -} AR6K_ASYNC_REG_IO_BUFFER; +}; typedef struct _AR6K_GMBOX_INFO { void *pProtocolContext; @@ -119,7 +119,7 @@ typedef struct _AR6K_DEVICE { HIF_PENDING_EVENTS_FUNC GetPendingEventsFunc; void *HTCContext; HTC_PACKET_QUEUE RegisterIOList; - AR6K_ASYNC_REG_IO_BUFFER RegIOBuffers[AR6K_MAX_REG_IO_BUFFERS]; + struct ar6k_async_reg_io_buffer RegIOBuffers[AR6K_MAX_REG_IO_BUFFERS]; void (*TargetFailureCallback)(void *Context); int (*MessagePendingCallback)(void *Context, u32 LookAheads[], -- cgit v1.2.3 From 495abc7995ffff39ba4333ad8e382017dc2192f8 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 10 Mar 2011 18:55:36 -0800 Subject: staging: ath6kl: remove-typedef AR6K_DEVICE remove-typedef -s AR6K_DEVICE \ "struct ar6k_device" drivers/staging/ath6kl/ Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 64 +++++++++---------- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 74 +++++++++++----------- drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c | 28 ++++---- drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c | 32 +++++----- .../ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c | 10 +-- drivers/staging/ath6kl/htc2/htc.c | 2 +- drivers/staging/ath6kl/htc2/htc_internal.h | 2 +- 7 files changed, 106 insertions(+), 106 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index 9090a3912f63..85d45a7461f4 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -35,19 +35,19 @@ #define MAILBOX_FOR_BLOCK_SIZE 1 -int DevEnableInterrupts(AR6K_DEVICE *pDev); -int DevDisableInterrupts(AR6K_DEVICE *pDev); +int DevEnableInterrupts(struct ar6k_device *pDev); +int DevDisableInterrupts(struct ar6k_device *pDev); -static void DevCleanupVirtualScatterSupport(AR6K_DEVICE *pDev); +static void DevCleanupVirtualScatterSupport(struct ar6k_device *pDev); -void AR6KFreeIOPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket) +void AR6KFreeIOPacket(struct ar6k_device *pDev, HTC_PACKET *pPacket) { LOCK_AR6K(pDev); HTC_PACKET_ENQUEUE(&pDev->RegisterIOList,pPacket); UNLOCK_AR6K(pDev); } -HTC_PACKET *AR6KAllocIOPacket(AR6K_DEVICE *pDev) +HTC_PACKET *AR6KAllocIOPacket(struct ar6k_device *pDev) { HTC_PACKET *pPacket; @@ -58,7 +58,7 @@ HTC_PACKET *AR6KAllocIOPacket(AR6K_DEVICE *pDev) return pPacket; } -void DevCleanup(AR6K_DEVICE *pDev) +void DevCleanup(struct ar6k_device *pDev) { DevCleanupGMbox(pDev); @@ -74,7 +74,7 @@ void DevCleanup(AR6K_DEVICE *pDev) } } -int DevSetup(AR6K_DEVICE *pDev) +int DevSetup(struct ar6k_device *pDev) { u32 blocksizes[AR6K_MAILBOXES]; int status = 0; @@ -216,7 +216,7 @@ int DevSetup(AR6K_DEVICE *pDev) } -int DevEnableInterrupts(AR6K_DEVICE *pDev) +int DevEnableInterrupts(struct ar6k_device *pDev) { int status; AR6K_IRQ_ENABLE_REGISTERS regs; @@ -276,7 +276,7 @@ int DevEnableInterrupts(AR6K_DEVICE *pDev) return status; } -int DevDisableInterrupts(AR6K_DEVICE *pDev) +int DevDisableInterrupts(struct ar6k_device *pDev) { AR6K_IRQ_ENABLE_REGISTERS regs; @@ -301,7 +301,7 @@ int DevDisableInterrupts(AR6K_DEVICE *pDev) } /* enable device interrupts */ -int DevUnmaskInterrupts(AR6K_DEVICE *pDev) +int DevUnmaskInterrupts(struct ar6k_device *pDev) { /* for good measure, make sure interrupt are disabled before unmasking at the HIF * layer. @@ -327,7 +327,7 @@ int DevUnmaskInterrupts(AR6K_DEVICE *pDev) } /* disable all device interrupts */ -int DevMaskInterrupts(AR6K_DEVICE *pDev) +int DevMaskInterrupts(struct ar6k_device *pDev) { /* mask the interrupt at the HIF layer, we don't want a stray interrupt taken while * we zero out our shadow registers in DevDisableInterrupts()*/ @@ -339,7 +339,7 @@ int DevMaskInterrupts(AR6K_DEVICE *pDev) /* callback when our fetch to enable/disable completes */ static void DevDoEnableDisableRecvAsyncHandler(void *Context, HTC_PACKET *pPacket) { - AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; + struct ar6k_device *pDev = (struct ar6k_device *)Context; AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDoEnableDisableRecvAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); @@ -355,7 +355,7 @@ static void DevDoEnableDisableRecvAsyncHandler(void *Context, HTC_PACKET *pPacke /* disable packet reception (used in case the host runs out of buffers) * this is the "override" method when the HIF reports another methods to * disable recv events */ -static int DevDoEnableDisableRecvOverride(AR6K_DEVICE *pDev, bool EnableRecv, bool AsyncMode) +static int DevDoEnableDisableRecvOverride(struct ar6k_device *pDev, bool EnableRecv, bool AsyncMode) { int status = 0; HTC_PACKET *pIOPacket = NULL; @@ -403,7 +403,7 @@ static int DevDoEnableDisableRecvOverride(AR6K_DEVICE *pDev, bool EnableRecv, bo /* disable packet reception (used in case the host runs out of buffers) * this is the "normal" method using the interrupt enable registers through * the host I/F */ -static int DevDoEnableDisableRecvNormal(AR6K_DEVICE *pDev, bool EnableRecv, bool AsyncMode) +static int DevDoEnableDisableRecvNormal(struct ar6k_device *pDev, bool EnableRecv, bool AsyncMode) { int status = 0; HTC_PACKET *pIOPacket = NULL; @@ -470,7 +470,7 @@ static int DevDoEnableDisableRecvNormal(AR6K_DEVICE *pDev, bool EnableRecv, bool } -int DevStopRecv(AR6K_DEVICE *pDev, bool AsyncMode) +int DevStopRecv(struct ar6k_device *pDev, bool AsyncMode) { if (NULL == pDev->HifMaskUmaskRecvEvent) { return DevDoEnableDisableRecvNormal(pDev,false,AsyncMode); @@ -479,7 +479,7 @@ int DevStopRecv(AR6K_DEVICE *pDev, bool AsyncMode) } } -int DevEnableRecv(AR6K_DEVICE *pDev, bool AsyncMode) +int DevEnableRecv(struct ar6k_device *pDev, bool AsyncMode) { if (NULL == pDev->HifMaskUmaskRecvEvent) { return DevDoEnableDisableRecvNormal(pDev,true,AsyncMode); @@ -488,7 +488,7 @@ int DevEnableRecv(AR6K_DEVICE *pDev, bool AsyncMode) } } -int DevWaitForPendingRecv(AR6K_DEVICE *pDev,u32 TimeoutInMs,bool *pbIsRecvPending) +int DevWaitForPendingRecv(struct ar6k_device *pDev,u32 TimeoutInMs,bool *pbIsRecvPending) { int status = 0; u8 host_int_status = 0x0; @@ -536,7 +536,7 @@ int DevWaitForPendingRecv(AR6K_DEVICE *pDev,u32 TimeoutInMs,bool *pbIsRecvPendin return status; } -void DevDumpRegisters(AR6K_DEVICE *pDev, +void DevDumpRegisters(struct ar6k_device *pDev, AR6K_IRQ_PROC_REGISTERS *pIrqProcRegs, AR6K_IRQ_ENABLE_REGISTERS *pIrqEnableRegs) { @@ -590,7 +590,7 @@ void DevDumpRegisters(AR6K_DEVICE *pDev, static HIF_SCATTER_REQ *DevAllocScatterReq(HIF_DEVICE *Context) { DL_LIST *pItem; - AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; + struct ar6k_device *pDev = (struct ar6k_device *)Context; LOCK_AR6K(pDev); pItem = DL_ListRemoveItemFromHead(&pDev->ScatterReqHead); UNLOCK_AR6K(pDev); @@ -602,7 +602,7 @@ static HIF_SCATTER_REQ *DevAllocScatterReq(HIF_DEVICE *Context) static void DevFreeScatterReq(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) { - AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; + struct ar6k_device *pDev = (struct ar6k_device *)Context; LOCK_AR6K(pDev); DL_ListInsertTail(&pDev->ScatterReqHead, &pReq->ListLink); UNLOCK_AR6K(pDev); @@ -650,7 +650,7 @@ int DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, bool FromDMA) static void DevReadWriteScatterAsyncHandler(void *Context, HTC_PACKET *pPacket) { - AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; + struct ar6k_device *pDev = (struct ar6k_device *)Context; HIF_SCATTER_REQ *pReq = (HIF_SCATTER_REQ *)pPacket->pPktContext; AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevReadWriteScatterAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); @@ -666,7 +666,7 @@ static void DevReadWriteScatterAsyncHandler(void *Context, HTC_PACKET *pPacket) static int DevReadWriteScatter(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) { - AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; + struct ar6k_device *pDev = (struct ar6k_device *)Context; int status = 0; HTC_PACKET *pIOPacket = NULL; u32 request = pReq->Request; @@ -734,7 +734,7 @@ static int DevReadWriteScatter(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) } -static void DevCleanupVirtualScatterSupport(AR6K_DEVICE *pDev) +static void DevCleanupVirtualScatterSupport(struct ar6k_device *pDev) { HIF_SCATTER_REQ *pReq; @@ -749,7 +749,7 @@ static void DevCleanupVirtualScatterSupport(AR6K_DEVICE *pDev) } /* function to set up virtual scatter support if HIF layer has not implemented the interface */ -static int DevSetupVirtualScatterSupport(AR6K_DEVICE *pDev) +static int DevSetupVirtualScatterSupport(struct ar6k_device *pDev) { int status = 0; int bufferSize, sgreqSize; @@ -810,7 +810,7 @@ static int DevSetupVirtualScatterSupport(AR6K_DEVICE *pDev) return status; } -int DevCleanupMsgBundling(AR6K_DEVICE *pDev) +int DevCleanupMsgBundling(struct ar6k_device *pDev) { if(NULL != pDev) { @@ -820,7 +820,7 @@ int DevCleanupMsgBundling(AR6K_DEVICE *pDev) return 0; } -int DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer) +int DevSetupMsgBundling(struct ar6k_device *pDev, int MaxMsgsPerTransfer) { int status; @@ -885,7 +885,7 @@ int DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer) return status; } -int DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, bool Read, bool Async) +int DevSubmitScatterRequest(struct ar6k_device *pDev, HIF_SCATTER_REQ *pScatterReq, bool Read, bool Async) { int status; @@ -1134,7 +1134,7 @@ static u16 GetEndMarker(void) #define ATH_PRINT_OUT_ZONE ATH_DEBUG_ERR /* send the ordered buffers to the target */ -static int SendBuffers(AR6K_DEVICE *pDev, int mbox) +static int SendBuffers(struct ar6k_device *pDev, int mbox) { int status = 0; u32 request = HIF_WR_SYNC_BLOCK_INC; @@ -1178,7 +1178,7 @@ static int SendBuffers(AR6K_DEVICE *pDev, int mbox) } /* poll the mailbox credit counter until we get a credit or timeout */ -static int GetCredits(AR6K_DEVICE *pDev, int mbox, int *pCredits) +static int GetCredits(struct ar6k_device *pDev, int mbox, int *pCredits) { int status = 0; int timeout = TEST_CREDITS_RECV_TIMEOUT; @@ -1225,7 +1225,7 @@ static int GetCredits(AR6K_DEVICE *pDev, int mbox, int *pCredits) /* wait for the buffers to come back */ -static int RecvBuffers(AR6K_DEVICE *pDev, int mbox) +static int RecvBuffers(struct ar6k_device *pDev, int mbox) { int status = 0; u32 request = HIF_RD_SYNC_BLOCK_INC; @@ -1303,7 +1303,7 @@ static int RecvBuffers(AR6K_DEVICE *pDev, int mbox) } -static int DoOneMboxHWTest(AR6K_DEVICE *pDev, int mbox) +static int DoOneMboxHWTest(struct ar6k_device *pDev, int mbox) { int status; @@ -1339,7 +1339,7 @@ static int DoOneMboxHWTest(AR6K_DEVICE *pDev, int mbox) } /* here is where the test starts */ -int DoMboxHWTest(AR6K_DEVICE *pDev) +int DoMboxHWTest(struct ar6k_device *pDev) { int i; int status; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index e0c3926c0bcf..ebcc82b1362b 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -105,7 +105,7 @@ typedef struct _AR6K_GMBOX_INFO { bool CreditCountIRQEnabled; } AR6K_GMBOX_INFO; -typedef struct _AR6K_DEVICE { +struct ar6k_device { A_MUTEX_T Lock; u8 _Pad1[A_CACHE_LINE_PAD]; AR6K_IRQ_PROC_REGISTERS IrqProcRegisters; /* cache-line safe with pads around */ @@ -141,24 +141,24 @@ typedef struct _AR6K_DEVICE { bool GMboxEnabled; AR6K_GMBOX_CTRL_REGISTERS GMboxControlRegisters; int RecheckIRQStatusCnt; -} AR6K_DEVICE; +}; #define LOCK_AR6K(p) A_MUTEX_LOCK(&(p)->Lock); #define UNLOCK_AR6K(p) A_MUTEX_UNLOCK(&(p)->Lock); #define REF_IRQ_STATUS_RECHECK(p) (p)->RecheckIRQStatusCnt = 1 /* note: no need to lock this, it only gets set */ -int DevSetup(AR6K_DEVICE *pDev); -void DevCleanup(AR6K_DEVICE *pDev); -int DevUnmaskInterrupts(AR6K_DEVICE *pDev); -int DevMaskInterrupts(AR6K_DEVICE *pDev); -int DevPollMboxMsgRecv(AR6K_DEVICE *pDev, +int DevSetup(struct ar6k_device *pDev); +void DevCleanup(struct ar6k_device *pDev); +int DevUnmaskInterrupts(struct ar6k_device *pDev); +int DevMaskInterrupts(struct ar6k_device *pDev); +int DevPollMboxMsgRecv(struct ar6k_device *pDev, u32 *pLookAhead, int TimeoutMS); int DevRWCompletionHandler(void *context, int status); int DevDsrHandler(void *context); int DevCheckPendingRecvMsgsAsync(void *context); -void DevAsyncIrqProcessComplete(AR6K_DEVICE *pDev); -void DevDumpRegisters(AR6K_DEVICE *pDev, +void DevAsyncIrqProcessComplete(struct ar6k_device *pDev); +void DevDumpRegisters(struct ar6k_device *pDev, AR6K_IRQ_PROC_REGISTERS *pIrqProcRegs, AR6K_IRQ_ENABLE_REGISTERS *pIrqEnableRegs); @@ -166,17 +166,17 @@ void DevDumpRegisters(AR6K_DEVICE *pDev, #define DEV_STOP_RECV_SYNC false #define DEV_ENABLE_RECV_ASYNC true #define DEV_ENABLE_RECV_SYNC false -int DevStopRecv(AR6K_DEVICE *pDev, bool ASyncMode); -int DevEnableRecv(AR6K_DEVICE *pDev, bool ASyncMode); -int DevEnableInterrupts(AR6K_DEVICE *pDev); -int DevDisableInterrupts(AR6K_DEVICE *pDev); -int DevWaitForPendingRecv(AR6K_DEVICE *pDev,u32 TimeoutInMs,bool *pbIsRecvPending); +int DevStopRecv(struct ar6k_device *pDev, bool ASyncMode); +int DevEnableRecv(struct ar6k_device *pDev, bool ASyncMode); +int DevEnableInterrupts(struct ar6k_device *pDev); +int DevDisableInterrupts(struct ar6k_device *pDev); +int DevWaitForPendingRecv(struct ar6k_device *pDev,u32 TimeoutInMs,bool *pbIsRecvPending); #define DEV_CALC_RECV_PADDED_LEN(pDev, length) (((length) + (pDev)->BlockMask) & (~((pDev)->BlockMask))) #define DEV_CALC_SEND_PADDED_LEN(pDev, length) DEV_CALC_RECV_PADDED_LEN(pDev,length) #define DEV_IS_LEN_BLOCK_ALIGNED(pDev, length) (((length) % (pDev)->BlockSize) == 0) -static INLINE int DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 SendLength) { +static INLINE int DevSendPacket(struct ar6k_device *pDev, HTC_PACKET *pPacket, u32 SendLength) { u32 paddedLength; bool sync = (pPacket->Completion == NULL) ? true : false; int status; @@ -219,7 +219,7 @@ static INLINE int DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 Send return status; } -static INLINE int DevRecvPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 RecvLength) { +static INLINE int DevRecvPacket(struct ar6k_device *pDev, HTC_PACKET *pPacket, u32 RecvLength) { u32 paddedLength; int status; bool sync = (pPacket->Completion == NULL) ? true : false; @@ -296,9 +296,9 @@ static INLINE int DEV_PREPARE_SCATTER_OPERATION(HIF_SCATTER_REQ *pReq) { } -int DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer); +int DevSetupMsgBundling(struct ar6k_device *pDev, int MaxMsgsPerTransfer); -int DevCleanupMsgBundling(AR6K_DEVICE *pDev); +int DevCleanupMsgBundling(struct ar6k_device *pDev); #define DEV_GET_MAX_MSG_PER_BUNDLE(pDev) (pDev)->HifScatterInfo.MaxScatterEntries #define DEV_GET_MAX_BUNDLE_LENGTH(pDev) (pDev)->HifScatterInfo.MaxTransferSizePerScatterReq @@ -315,10 +315,10 @@ int DevCleanupMsgBundling(AR6K_DEVICE *pDev); #define DEV_SCATTER_WRITE false #define DEV_SCATTER_ASYNC true #define DEV_SCATTER_SYNC false -int DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, bool Read, bool Async); +int DevSubmitScatterRequest(struct ar6k_device *pDev, HIF_SCATTER_REQ *pScatterReq, bool Read, bool Async); #ifdef MBOXHW_UNIT_TEST -int DoMboxHWTest(AR6K_DEVICE *pDev); +int DoMboxHWTest(struct ar6k_device *pDev); #endif /* completely virtual */ @@ -329,7 +329,7 @@ typedef struct _DEV_SCATTER_DMA_VIRTUAL_INFO { -void DumpAR6KDevState(AR6K_DEVICE *pDev); +void DumpAR6KDevState(struct ar6k_device *pDev); /**************************************************/ /****** GMBOX functions and definitions @@ -339,10 +339,10 @@ void DumpAR6KDevState(AR6K_DEVICE *pDev); #ifdef ATH_AR6K_ENABLE_GMBOX -void DevCleanupGMbox(AR6K_DEVICE *pDev); -int DevSetupGMbox(AR6K_DEVICE *pDev); -int DevCheckGMboxInterrupts(AR6K_DEVICE *pDev); -void DevNotifyGMboxTargetFailure(AR6K_DEVICE *pDev); +void DevCleanupGMbox(struct ar6k_device *pDev); +int DevSetupGMbox(struct ar6k_device *pDev); +int DevCheckGMboxInterrupts(struct ar6k_device *pDev); +void DevNotifyGMboxTargetFailure(struct ar6k_device *pDev); #else @@ -351,7 +351,7 @@ void DevNotifyGMboxTargetFailure(AR6K_DEVICE *pDev); #define DevCheckGMboxInterrupts(p) 0 #define DevNotifyGMboxTargetFailure(p) -static INLINE int DevSetupGMbox(AR6K_DEVICE *pDev) { +static INLINE int DevSetupGMbox(struct ar6k_device *pDev) { pDev->GMboxEnabled = false; return 0; } @@ -361,12 +361,12 @@ static INLINE int DevSetupGMbox(AR6K_DEVICE *pDev) { #ifdef ATH_AR6K_ENABLE_GMBOX /* GMBOX protocol modules must expose each of these internal APIs */ -HCI_TRANSPORT_HANDLE GMboxAttachProtocol(AR6K_DEVICE *pDev, HCI_TRANSPORT_CONFIG_INFO *pInfo); -int GMboxProtocolInstall(AR6K_DEVICE *pDev); -void GMboxProtocolUninstall(AR6K_DEVICE *pDev); +HCI_TRANSPORT_HANDLE GMboxAttachProtocol(struct ar6k_device *pDev, HCI_TRANSPORT_CONFIG_INFO *pInfo); +int GMboxProtocolInstall(struct ar6k_device *pDev); +void GMboxProtocolUninstall(struct ar6k_device *pDev); /* API used by GMBOX protocol modules */ -AR6K_DEVICE *HTCGetAR6KDevice(void *HTCHandle); +struct ar6k_device *HTCGetAR6KDevice(void *HTCHandle); #define DEV_GMBOX_SET_PROTOCOL(pDev,recv_callback,credits_pending,failure,statedump,context) \ { \ (pDev)->GMboxInfo.pProtocolContext = (context); \ @@ -378,8 +378,8 @@ AR6K_DEVICE *HTCGetAR6KDevice(void *HTCHandle); #define DEV_GMBOX_GET_PROTOCOL(pDev) (pDev)->GMboxInfo.pProtocolContext -int DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 WriteLength); -int DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 ReadLength); +int DevGMboxWrite(struct ar6k_device *pDev, HTC_PACKET *pPacket, u32 WriteLength); +int DevGMboxRead(struct ar6k_device *pDev, HTC_PACKET *pPacket, u32 ReadLength); #define PROC_IO_ASYNC true #define PROC_IO_SYNC false @@ -393,11 +393,11 @@ typedef enum GMBOX_IRQ_ACTION_TYPE { GMBOX_CREDIT_IRQ_DISABLE, } GMBOX_IRQ_ACTION_TYPE; -int DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE, bool AsyncMode); -int DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, bool AsyncMode, int *pCredits); -int DevGMboxReadCreditSize(AR6K_DEVICE *pDev, int *pCreditSize); -int DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes); -int DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int SignalNumber, int AckTimeoutMS); +int DevGMboxIRQAction(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE, bool AsyncMode); +int DevGMboxReadCreditCounter(struct ar6k_device *pDev, bool AsyncMode, int *pCredits); +int DevGMboxReadCreditSize(struct ar6k_device *pDev, int *pCreditSize); +int DevGMboxRecvLookAheadPeek(struct ar6k_device *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes); +int DevGMboxSetTargetInterrupt(struct ar6k_device *pDev, int SignalNumber, int AckTimeoutMS); #endif diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c index bee4850b54fc..aa455907457d 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c @@ -33,10 +33,10 @@ #include "htc_packet.h" #include "ar6k.h" -extern void AR6KFreeIOPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket); -extern HTC_PACKET *AR6KAllocIOPacket(AR6K_DEVICE *pDev); +extern void AR6KFreeIOPacket(struct ar6k_device *pDev, HTC_PACKET *pPacket); +extern HTC_PACKET *AR6KAllocIOPacket(struct ar6k_device *pDev); -static int DevServiceDebugInterrupt(AR6K_DEVICE *pDev); +static int DevServiceDebugInterrupt(struct ar6k_device *pDev); #define DELAY_PER_INTERVAL_MS 10 /* 10 MS delay per polling interval */ @@ -59,7 +59,7 @@ int DevRWCompletionHandler(void *context, int status) } /* mailbox recv message polling */ -int DevPollMboxMsgRecv(AR6K_DEVICE *pDev, +int DevPollMboxMsgRecv(struct ar6k_device *pDev, u32 *pLookAhead, int TimeoutMS) { @@ -152,7 +152,7 @@ int DevPollMboxMsgRecv(AR6K_DEVICE *pDev, return status; } -static int DevServiceCPUInterrupt(AR6K_DEVICE *pDev) +static int DevServiceCPUInterrupt(struct ar6k_device *pDev) { int status; u8 cpu_int_status; @@ -192,7 +192,7 @@ static int DevServiceCPUInterrupt(AR6K_DEVICE *pDev) } -static int DevServiceErrorInterrupt(AR6K_DEVICE *pDev) +static int DevServiceErrorInterrupt(struct ar6k_device *pDev) { int status; u8 error_int_status; @@ -245,7 +245,7 @@ static int DevServiceErrorInterrupt(AR6K_DEVICE *pDev) return status; } -static int DevServiceDebugInterrupt(AR6K_DEVICE *pDev) +static int DevServiceDebugInterrupt(struct ar6k_device *pDev) { u32 dummy; int status; @@ -275,7 +275,7 @@ static int DevServiceDebugInterrupt(AR6K_DEVICE *pDev) return status; } -static int DevServiceCounterInterrupt(AR6K_DEVICE *pDev) +static int DevServiceCounterInterrupt(struct ar6k_device *pDev) { u8 counter_int_status; @@ -302,7 +302,7 @@ static int DevServiceCounterInterrupt(AR6K_DEVICE *pDev) /* callback when our fetch to get interrupt status registers completes */ static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket) { - AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; + struct ar6k_device *pDev = (struct ar6k_device *)Context; u32 lookAhead = 0; bool otherInts = false; @@ -390,7 +390,7 @@ static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket) * recv messages, this starts off a series of async requests to read interrupt registers */ int DevCheckPendingRecvMsgsAsync(void *context) { - AR6K_DEVICE *pDev = (AR6K_DEVICE *)context; + struct ar6k_device *pDev = (struct ar6k_device *)context; int status = 0; HTC_PACKET *pIOPacket; @@ -460,14 +460,14 @@ int DevCheckPendingRecvMsgsAsync(void *context) return status; } -void DevAsyncIrqProcessComplete(AR6K_DEVICE *pDev) +void DevAsyncIrqProcessComplete(struct ar6k_device *pDev) { AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("DevAsyncIrqProcessComplete - forcing HIF IRQ ACK \n")); HIFAckInterrupt(pDev->HIFDevice); } /* process pending interrupts synchronously */ -static int ProcessPendingIRQs(AR6K_DEVICE *pDev, bool *pDone, bool *pASyncProcessing) +static int ProcessPendingIRQs(struct ar6k_device *pDev, bool *pDone, bool *pASyncProcessing) { int status = 0; u8 host_int_status = 0; @@ -683,7 +683,7 @@ static int ProcessPendingIRQs(AR6K_DEVICE *pDev, bool *pDone, bool *pASyncProces /* Synchronousinterrupt handler, this handler kicks off all interrupt processing.*/ int DevDsrHandler(void *context) { - AR6K_DEVICE *pDev = (AR6K_DEVICE *)context; + struct ar6k_device *pDev = (struct ar6k_device *)context; int status = 0; bool done = false; bool asyncProc = false; @@ -744,7 +744,7 @@ int DevDsrHandler(void *context) } #ifdef ATH_DEBUG_MODULE -void DumpAR6KDevState(AR6K_DEVICE *pDev) +void DumpAR6KDevState(struct ar6k_device *pDev) { int status; AR6K_IRQ_ENABLE_REGISTERS regs; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c index 46bcb275e43a..cbfbdea27953 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c @@ -54,14 +54,14 @@ /* external APIs for allocating and freeing internal I/O packets to handle ASYNC I/O */ -extern void AR6KFreeIOPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket); -extern HTC_PACKET *AR6KAllocIOPacket(AR6K_DEVICE *pDev); +extern void AR6KFreeIOPacket(struct ar6k_device *pDev, HTC_PACKET *pPacket); +extern HTC_PACKET *AR6KAllocIOPacket(struct ar6k_device *pDev); /* callback when our fetch to enable/disable completes */ static void DevGMboxIRQActionAsyncHandler(void *Context, HTC_PACKET *pPacket) { - AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; + struct ar6k_device *pDev = (struct ar6k_device *)Context; AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxIRQActionAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); @@ -74,7 +74,7 @@ static void DevGMboxIRQActionAsyncHandler(void *Context, HTC_PACKET *pPacket) AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxIRQActionAsyncHandler \n")); } -static int DevGMboxCounterEnableDisable(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode) +static int DevGMboxCounterEnableDisable(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode) { int status = 0; AR6K_IRQ_ENABLE_REGISTERS regs; @@ -155,7 +155,7 @@ static int DevGMboxCounterEnableDisable(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE } -int DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode) +int DevGMboxIRQAction(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode) { int status = 0; HTC_PACKET *pIOPacket = NULL; @@ -261,7 +261,7 @@ int DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool A return status; } -void DevCleanupGMbox(AR6K_DEVICE *pDev) +void DevCleanupGMbox(struct ar6k_device *pDev) { if (pDev->GMboxEnabled) { pDev->GMboxEnabled = false; @@ -269,7 +269,7 @@ void DevCleanupGMbox(AR6K_DEVICE *pDev) } } -int DevSetupGMbox(AR6K_DEVICE *pDev) +int DevSetupGMbox(struct ar6k_device *pDev) { int status = 0; u8 muxControl[4]; @@ -322,7 +322,7 @@ int DevSetupGMbox(AR6K_DEVICE *pDev) return status; } -int DevCheckGMboxInterrupts(AR6K_DEVICE *pDev) +int DevCheckGMboxInterrupts(struct ar6k_device *pDev) { int status = 0; u8 counter_int_status; @@ -396,7 +396,7 @@ int DevCheckGMboxInterrupts(AR6K_DEVICE *pDev) } -int DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 WriteLength) +int DevGMboxWrite(struct ar6k_device *pDev, HTC_PACKET *pPacket, u32 WriteLength) { u32 paddedLength; bool sync = (pPacket->Completion == NULL) ? true : false; @@ -433,7 +433,7 @@ int DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 WriteLength) return status; } -int DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, u32 ReadLength) +int DevGMboxRead(struct ar6k_device *pDev, HTC_PACKET *pPacket, u32 ReadLength) { u32 paddedLength; @@ -518,7 +518,7 @@ static int ProcessCreditCounterReadBuffer(u8 *pBuffer, int Length) /* callback when our fetch to enable/disable completes */ static void DevGMboxReadCreditsAsyncHandler(void *Context, HTC_PACKET *pPacket) { - AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context; + struct ar6k_device *pDev = (struct ar6k_device *)Context; AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxReadCreditsAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); @@ -539,7 +539,7 @@ static void DevGMboxReadCreditsAsyncHandler(void *Context, HTC_PACKET *pPacket) AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxReadCreditsAsyncHandler \n")); } -int DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, bool AsyncMode, int *pCredits) +int DevGMboxReadCreditCounter(struct ar6k_device *pDev, bool AsyncMode, int *pCredits) { int status = 0; HTC_PACKET *pIOPacket = NULL; @@ -602,7 +602,7 @@ int DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, bool AsyncMode, int *pCredits) return status; } -int DevGMboxReadCreditSize(AR6K_DEVICE *pDev, int *pCreditSize) +int DevGMboxReadCreditSize(struct ar6k_device *pDev, int *pCreditSize) { int status; u8 buffer[4]; @@ -626,7 +626,7 @@ int DevGMboxReadCreditSize(AR6K_DEVICE *pDev, int *pCreditSize) return status; } -void DevNotifyGMboxTargetFailure(AR6K_DEVICE *pDev) +void DevNotifyGMboxTargetFailure(struct ar6k_device *pDev) { /* Target ASSERTED!!! */ if (pDev->GMboxInfo.pTargetFailureCallback != NULL) { @@ -634,7 +634,7 @@ void DevNotifyGMboxTargetFailure(AR6K_DEVICE *pDev) } } -int DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes) +int DevGMboxRecvLookAheadPeek(struct ar6k_device *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes) { int status = 0; @@ -676,7 +676,7 @@ int DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, u8 *pLookAheadBuffer, int *pLoo return status; } -int DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int Signal, int AckTimeoutMS) +int DevGMboxSetTargetInterrupt(struct ar6k_device *pDev, int Signal, int AckTimeoutMS) { int status = 0; int i; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c index 177f04dc9674..3ee3d40893da 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c @@ -66,7 +66,7 @@ typedef struct { HTC_PACKET_QUEUE SendQueue; /* write queue holding HCI Command and ACL packets */ HTC_PACKET_QUEUE HCIACLRecvBuffers; /* recv queue holding buffers for incomming ACL packets */ HTC_PACKET_QUEUE HCIEventBuffers; /* recv queue holding buffers for incomming event packets */ - AR6K_DEVICE *pDev; + struct ar6k_device *pDev; A_MUTEX_T HCIRxLock; A_MUTEX_T HCITxLock; int CreditsMax; @@ -846,7 +846,7 @@ static void FlushRecvBuffers(GMBOX_PROTO_HCI_UART *pProt) /*** protocol module install entry point ***/ -int GMboxProtocolInstall(AR6K_DEVICE *pDev) +int GMboxProtocolInstall(struct ar6k_device *pDev) { int status = 0; GMBOX_PROTO_HCI_UART *pProtocol = NULL; @@ -889,7 +889,7 @@ int GMboxProtocolInstall(AR6K_DEVICE *pDev) } /*** protocol module uninstall entry point ***/ -void GMboxProtocolUninstall(AR6K_DEVICE *pDev) +void GMboxProtocolUninstall(struct ar6k_device *pDev) { GMBOX_PROTO_HCI_UART *pProtocol = (GMBOX_PROTO_HCI_UART *)DEV_GMBOX_GET_PROTOCOL(pDev); @@ -939,7 +939,7 @@ static int NotifyTransportReady(GMBOX_PROTO_HCI_UART *pProt) HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, HCI_TRANSPORT_CONFIG_INFO *pInfo) { GMBOX_PROTO_HCI_UART *pProtocol = NULL; - AR6K_DEVICE *pDev; + struct ar6k_device *pDev; AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportAttach \n")); @@ -984,7 +984,7 @@ HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, HCI_TRANSPORT_CONFIG_I void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans) { GMBOX_PROTO_HCI_UART *pProtocol = (GMBOX_PROTO_HCI_UART *)HciTrans; - AR6K_DEVICE *pDev = pProtocol->pDev; + struct ar6k_device *pDev = pProtocol->pDev; AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportDetach \n")); diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index c200cfd339b3..8bde7bf38b34 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -573,7 +573,7 @@ bool HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, #endif } -AR6K_DEVICE *HTCGetAR6KDevice(void *HTCHandle) +struct ar6k_device *HTCGetAR6KDevice(void *HTCHandle) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); return &target->Device; diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h index 73f6ed933ebf..8bc3162cdfb9 100644 --- a/drivers/staging/ath6kl/htc2/htc_internal.h +++ b/drivers/staging/ath6kl/htc2/htc_internal.h @@ -122,7 +122,7 @@ typedef struct _HTC_TARGET { A_MUTEX_T HTCLock; A_MUTEX_T HTCRxLock; A_MUTEX_T HTCTxLock; - AR6K_DEVICE Device; /* AR6K - specific state */ + struct ar6k_device Device; /* AR6K - specific state */ u32 OpStateFlags; u32 RecvStateFlags; HTC_ENDPOINT_ID EpWaitingForBuffers; -- cgit v1.2.3 From 89c625bef65fd245692bc884ae8268f6d5b60da9 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 10 Mar 2011 18:55:37 -0800 Subject: staging: ath6kl: remove-typedef AR6K_GMBOX_CTRL_REGISTERS remove-typedef -s AR6K_GMBOX_CTRL_REGISTERS \ "struct ar6k_gmbox_ctrl_registers" drivers/staging/ath6k Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index ebcc82b1362b..e8b638c5ddfc 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -65,9 +65,9 @@ typedef PREPACK struct _AR6K_IRQ_ENABLE_REGISTERS { u8 counter_int_status_enable; } POSTPACK AR6K_IRQ_ENABLE_REGISTERS; -typedef PREPACK struct _AR6K_GMBOX_CTRL_REGISTERS { +PREPACK struct ar6k_gmbox_ctrl_registers { u8 int_status_enable; -} POSTPACK AR6K_GMBOX_CTRL_REGISTERS; +} POSTPACK; #include "athendpack.h" @@ -139,7 +139,7 @@ struct ar6k_device { int MaxSendBundleSize; AR6K_GMBOX_INFO GMboxInfo; bool GMboxEnabled; - AR6K_GMBOX_CTRL_REGISTERS GMboxControlRegisters; + struct ar6k_gmbox_ctrl_registers GMboxControlRegisters; int RecheckIRQStatusCnt; }; -- cgit v1.2.3 From 69c44f42f6467441cc413ccbabbb9deeb82d16c4 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 10 Mar 2011 18:55:38 -0800 Subject: staging: ath6kl: remove-typedef AR6K_GMBOX_INFO remove-typedef -s AR6K_GMBOX_INFO \ "struct ar6k_gmbox_info" drivers/staging/ath6kl/ Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index e8b638c5ddfc..0bee46af9009 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -96,14 +96,14 @@ struct ar6k_async_reg_io_buffer { u8 _Pad2[A_CACHE_LINE_PAD]; }; -typedef struct _AR6K_GMBOX_INFO { +struct ar6k_gmbox_info { void *pProtocolContext; int (*pMessagePendingCallBack)(void *pContext, u8 LookAheadBytes[], int ValidBytes); int (*pCreditsPendingCallback)(void *pContext, int NumCredits, bool CreditIRQEnabled); void (*pTargetFailureCallback)(void *pContext, int Status); void (*pStateDumpCallback)(void *pContext); bool CreditCountIRQEnabled; -} AR6K_GMBOX_INFO; +}; struct ar6k_device { A_MUTEX_T Lock; @@ -137,7 +137,7 @@ struct ar6k_device { bool ScatterIsVirtual; int MaxRecvBundleSize; int MaxSendBundleSize; - AR6K_GMBOX_INFO GMboxInfo; + struct ar6k_gmbox_info GMboxInfo; bool GMboxEnabled; struct ar6k_gmbox_ctrl_registers GMboxControlRegisters; int RecheckIRQStatusCnt; -- cgit v1.2.3 From 03e41d55390a5dab2ab9945eef331edb2eddd72f Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 10 Mar 2011 18:55:39 -0800 Subject: staging: ath6kl: remove-typedef AR6K_HCI_BRIDGE_INFO remove-typedef -s AR6K_HCI_BRIDGE_INFO \ "struct ar6k_hci_bridge_info" drivers/staging/ath6kl/ Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/hci_bridge.c | 88 ++++++++++++++-------------- 1 file changed, 44 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index ee52d1195316..a02827bab8d9 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -73,7 +73,7 @@ extern unsigned int hciuartscale; extern unsigned int hciuartstep; #endif /* EXPORT_HCI_BRIDGE_INTERFACE */ -typedef struct { +struct ar6k_hci_bridge_info { void *pHCIDev; /* HCI bridge device */ HCI_TRANSPORT_PROPERTIES HCIProps; /* HCI bridge props */ struct hci_dev *pBtStackHCIDev; /* BT Stack HCI dev */ @@ -87,7 +87,7 @@ typedef struct { #else AR_SOFTC_T *ar; #endif /* EXPORT_HCI_BRIDGE_INTERFACE */ -} AR6K_HCI_BRIDGE_INFO; +}; #define MAX_ACL_RECV_BUFS 16 #define MAX_EVT_RECV_BUFS 8 @@ -103,17 +103,17 @@ extern unsigned int setupbtdev; struct ar3k_config_info ar3kconfig; #ifdef EXPORT_HCI_BRIDGE_INTERFACE -AR6K_HCI_BRIDGE_INFO *g_pHcidevInfo; +struct ar6k_hci_bridge_info *g_pHcidevInfo; #endif -static int bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo); -static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo); -static int bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo); -static bool bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, +static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo); +static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo); +static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo); +static bool bt_indicate_recv(struct ar6k_hci_bridge_info *pHcidevInfo, HCI_TRANSPORT_PACKET_TYPE Type, struct sk_buff *skb); -static struct sk_buff *bt_alloc_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, int Length); -static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, struct sk_buff *skb); +static struct sk_buff *bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length); +static void bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_buff *skb); #ifdef EXPORT_HCI_BRIDGE_INTERFACE int ar6000_setup_hci(void *ar); @@ -129,7 +129,7 @@ int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb); #define LOCK_BRIDGE(dev) spin_lock_bh(&(dev)->BridgeLock) #define UNLOCK_BRIDGE(dev) spin_unlock_bh(&(dev)->BridgeLock) -static inline void FreeBtOsBuf(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, void *osbuf) +static inline void FreeBtOsBuf(struct ar6k_hci_bridge_info *pHcidevInfo, void *osbuf) { if (pHcidevInfo->HciNormalMode) { bt_free_buffer(pHcidevInfo, (struct sk_buff *)osbuf); @@ -139,14 +139,14 @@ static inline void FreeBtOsBuf(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, void *osbuf) } } -static void FreeHTCStruct(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, HTC_PACKET *pPacket) +static void FreeHTCStruct(struct ar6k_hci_bridge_info *pHcidevInfo, HTC_PACKET *pPacket) { LOCK_BRIDGE(pHcidevInfo); HTC_PACKET_ENQUEUE(&pHcidevInfo->HTCPacketStructHead,pPacket); UNLOCK_BRIDGE(pHcidevInfo); } -static HTC_PACKET * AllocHTCStruct(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) +static HTC_PACKET * AllocHTCStruct(struct ar6k_hci_bridge_info *pHcidevInfo) { HTC_PACKET *pPacket = NULL; LOCK_BRIDGE(pHcidevInfo); @@ -157,7 +157,7 @@ static HTC_PACKET * AllocHTCStruct(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) #define BLOCK_ROUND_UP_PWR2(x, align) (((int) (x) + ((align)-1)) & ~((align)-1)) -static void RefillRecvBuffers(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, +static void RefillRecvBuffers(struct ar6k_hci_bridge_info *pHcidevInfo, HCI_TRANSPORT_PACKET_TYPE Type, int NumBuffers) { @@ -219,7 +219,7 @@ static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle, HCI_TRANSPORT_PROPERTIES *pProps, void *pContext) { - AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext; + struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext; int status; u32 address, hci_uart_pwr_mgmt_params; // struct ar3k_config_info ar3kconfig; @@ -325,7 +325,7 @@ static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle, static void ar6000_hci_transport_failure(void *pContext, int Status) { - AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext; + struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext; AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: transport failure! \n")); @@ -336,7 +336,7 @@ static void ar6000_hci_transport_failure(void *pContext, int Status) static void ar6000_hci_transport_removed(void *pContext) { - AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext; + struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext; AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: transport removed. \n")); @@ -349,7 +349,7 @@ static void ar6000_hci_transport_removed(void *pContext) static void ar6000_hci_send_complete(void *pContext, HTC_PACKET *pPacket) { - AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext; + struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext; void *osbuf = pPacket->pPktContext; A_ASSERT(osbuf != NULL); A_ASSERT(pHcidevInfo != NULL); @@ -367,7 +367,7 @@ static void ar6000_hci_send_complete(void *pContext, HTC_PACKET *pPacket) static void ar6000_hci_pkt_recv(void *pContext, HTC_PACKET *pPacket) { - AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext; + struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext; struct sk_buff *skb; A_ASSERT(pHcidevInfo != NULL); @@ -432,7 +432,7 @@ static void ar6000_hci_pkt_recv(void *pContext, HTC_PACKET *pPacket) static void ar6000_hci_pkt_refill(void *pContext, HCI_TRANSPORT_PACKET_TYPE Type, int BuffersAvailable) { - AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext; + struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext; int refillCount; if (Type == HCI_ACL_TYPE) { @@ -449,7 +449,7 @@ static void ar6000_hci_pkt_refill(void *pContext, HCI_TRANSPORT_PACKET_TYPE Typ static HCI_SEND_FULL_ACTION ar6000_hci_pkt_send_full(void *pContext, HTC_PACKET *pPacket) { - AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)pContext; + struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext; HCI_SEND_FULL_ACTION action = HCI_SEND_FULL_KEEP; if (!pHcidevInfo->HciNormalMode) { @@ -473,19 +473,19 @@ int ar6000_setup_hci(AR_SOFTC_T *ar) int status = 0; int i; HTC_PACKET *pPacket; - AR6K_HCI_BRIDGE_INFO *pHcidevInfo; + struct ar6k_hci_bridge_info *pHcidevInfo; do { - pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)A_MALLOC(sizeof(AR6K_HCI_BRIDGE_INFO)); + pHcidevInfo = (struct ar6k_hci_bridge_info *)A_MALLOC(sizeof(struct ar6k_hci_bridge_info)); if (NULL == pHcidevInfo) { status = A_NO_MEMORY; break; } - A_MEMZERO(pHcidevInfo, sizeof(AR6K_HCI_BRIDGE_INFO)); + A_MEMZERO(pHcidevInfo, sizeof(struct ar6k_hci_bridge_info)); #ifdef EXPORT_HCI_BRIDGE_INTERFACE g_pHcidevInfo = pHcidevInfo; pHcidevInfo->HCITransHdl = *(HCI_TRANSPORT_MISC_HANDLES *)ar; @@ -567,9 +567,9 @@ void ar6000_cleanup_hci(AR_SOFTC_T *ar) #endif { #ifdef EXPORT_HCI_BRIDGE_INTERFACE - AR6K_HCI_BRIDGE_INFO *pHcidevInfo = g_pHcidevInfo; + struct ar6k_hci_bridge_info *pHcidevInfo = g_pHcidevInfo; #else - AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)ar->hcidev_info; + struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)ar->hcidev_info; #endif if (pHcidevInfo != NULL) { @@ -607,9 +607,9 @@ int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb) HTC_PACKET *pPacket; HTC_TX_TAG htc_tag = AR6K_DATA_PKT_TAG; #ifdef EXPORT_HCI_BRIDGE_INTERFACE - AR6K_HCI_BRIDGE_INFO *pHcidevInfo = g_pHcidevInfo; + struct ar6k_hci_bridge_info *pHcidevInfo = g_pHcidevInfo; #else - AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)ar->hcidev_info; + struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)ar->hcidev_info; #endif do { @@ -666,7 +666,7 @@ int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb) void ar6000_set_default_ar3kconfig(AR_SOFTC_T *ar, void *ar3kconfig) { - AR6K_HCI_BRIDGE_INFO *pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)ar->hcidev_info; + struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)ar->hcidev_info; struct ar3k_config_info *config = (struct ar3k_config_info *)ar3kconfig; config->pHCIDev = pHcidevInfo->pHCIDev; @@ -710,7 +710,7 @@ static int bt_send_frame(struct sk_buff *skb) { struct hci_dev *hdev = (struct hci_dev *)skb->dev; HCI_TRANSPORT_PACKET_TYPE type; - AR6K_HCI_BRIDGE_INFO *pHcidevInfo; + struct ar6k_hci_bridge_info *pHcidevInfo; HTC_PACKET *pPacket; int status = 0; struct sk_buff *txSkb = NULL; @@ -725,7 +725,7 @@ static int bt_send_frame(struct sk_buff *skb) return -EBUSY; } - pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)hdev->driver_data; + pHcidevInfo = (struct ar6k_hci_bridge_info *)hdev->driver_data; A_ASSERT(pHcidevInfo != NULL); AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("+bt_send_frame type: %d \n",bt_cb(skb)->pkt_type)); @@ -832,11 +832,11 @@ static int bt_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg) */ static int bt_flush(struct hci_dev *hdev) { - AR6K_HCI_BRIDGE_INFO *pHcidevInfo; + struct ar6k_hci_bridge_info *pHcidevInfo; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_flush - enter\n")); - pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)hdev->driver_data; + pHcidevInfo = (struct ar6k_hci_bridge_info *)hdev->driver_data; /* TODO??? */ @@ -853,7 +853,7 @@ static void bt_destruct(struct hci_dev *hdev) /* nothing to do here */ } -static int bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) +static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo) { int status = 0; struct hci_dev *pHciDev = NULL; @@ -913,7 +913,7 @@ static int bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) return status; } -static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) +static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo) { int err; @@ -935,7 +935,7 @@ static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) } } -static int bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) +static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo) { int err; int status = 0; @@ -959,7 +959,7 @@ static int bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) return status; } -static bool bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, +static bool bt_indicate_recv(struct ar6k_hci_bridge_info *pHcidevInfo, HCI_TRANSPORT_PACKET_TYPE Type, struct sk_buff *skb) { @@ -1022,7 +1022,7 @@ static bool bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, return success; } -static struct sk_buff* bt_alloc_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, int Length) +static struct sk_buff* bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length) { struct sk_buff *skb; /* in normal HCI mode we need to alloc from the bt core APIs */ @@ -1033,7 +1033,7 @@ static struct sk_buff* bt_alloc_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, int Le return skb; } -static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, struct sk_buff *skb) +static void bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_buff *skb) { kfree_skb(skb); } @@ -1041,21 +1041,21 @@ static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, struct sk_buff *sk #else // { CONFIG_BLUEZ_HCI_BRIDGE /* stubs when we only want to test the HCI bridging Interface without the HT stack */ -static int bt_setup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) +static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo) { return 0; } -static void bt_cleanup_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) +static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo) { } -static int bt_register_hci(AR6K_HCI_BRIDGE_INFO *pHcidevInfo) +static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo) { A_ASSERT(false); return A_ERROR; } -static bool bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, +static bool bt_indicate_recv(struct ar6k_hci_bridge_info *pHcidevInfo, HCI_TRANSPORT_PACKET_TYPE Type, struct sk_buff *skb) { @@ -1063,12 +1063,12 @@ static bool bt_indicate_recv(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, return false; } -static struct sk_buff* bt_alloc_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, int Length) +static struct sk_buff* bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length) { A_ASSERT(false); return NULL; } -static void bt_free_buffer(AR6K_HCI_BRIDGE_INFO *pHcidevInfo, struct sk_buff *skb) +static void bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_buff *skb) { A_ASSERT(false); } -- cgit v1.2.3 From dfaa26b47a67d4b3bf598bdf607f953ed3338681 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 10 Mar 2011 18:55:40 -0800 Subject: staging: ath6kl: remove-typedef AR6K_IRQ_ENABLE_REGISTERS remove-typedef -s AR6K_IRQ_ENABLE_REGISTERS \ "struct ar6k_irq_enable_registers" drivers/staging/ath6kl/ Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 8 ++++---- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 10 +++++----- drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c | 2 +- drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index 85d45a7461f4..77fa61848445 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -219,7 +219,7 @@ int DevSetup(struct ar6k_device *pDev) int DevEnableInterrupts(struct ar6k_device *pDev) { int status; - AR6K_IRQ_ENABLE_REGISTERS regs; + struct ar6k_irq_enable_registers regs; LOCK_AR6K(pDev); @@ -278,7 +278,7 @@ int DevEnableInterrupts(struct ar6k_device *pDev) int DevDisableInterrupts(struct ar6k_device *pDev) { - AR6K_IRQ_ENABLE_REGISTERS regs; + struct ar6k_irq_enable_registers regs; LOCK_AR6K(pDev); /* Disable all interrupts */ @@ -407,7 +407,7 @@ static int DevDoEnableDisableRecvNormal(struct ar6k_device *pDev, bool EnableRec { int status = 0; HTC_PACKET *pIOPacket = NULL; - AR6K_IRQ_ENABLE_REGISTERS regs; + struct ar6k_irq_enable_registers regs; /* take the lock to protect interrupt enable shadows */ LOCK_AR6K(pDev); @@ -538,7 +538,7 @@ int DevWaitForPendingRecv(struct ar6k_device *pDev,u32 TimeoutInMs,bool *pbIsRec void DevDumpRegisters(struct ar6k_device *pDev, AR6K_IRQ_PROC_REGISTERS *pIrqProcRegs, - AR6K_IRQ_ENABLE_REGISTERS *pIrqEnableRegs) + struct ar6k_irq_enable_registers *pIrqEnableRegs) { AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("\n<------- Register Table -------->\n")); diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index 0bee46af9009..fc781d17ce48 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -58,12 +58,12 @@ typedef PREPACK struct _AR6K_IRQ_PROC_REGISTERS { #define AR6K_IRQ_PROC_REGS_SIZE sizeof(AR6K_IRQ_PROC_REGISTERS) -typedef PREPACK struct _AR6K_IRQ_ENABLE_REGISTERS { +PREPACK struct ar6k_irq_enable_registers { u8 int_status_enable; u8 cpu_int_status_enable; u8 error_status_enable; u8 counter_int_status_enable; -} POSTPACK AR6K_IRQ_ENABLE_REGISTERS; +} POSTPACK; PREPACK struct ar6k_gmbox_ctrl_registers { u8 int_status_enable; @@ -71,7 +71,7 @@ PREPACK struct ar6k_gmbox_ctrl_registers { #include "athendpack.h" -#define AR6K_IRQ_ENABLE_REGS_SIZE sizeof(AR6K_IRQ_ENABLE_REGISTERS) +#define AR6K_IRQ_ENABLE_REGS_SIZE sizeof(struct ar6k_irq_enable_registers) #define AR6K_REG_IO_BUFFER_SIZE 32 #define AR6K_MAX_REG_IO_BUFFERS 8 @@ -110,7 +110,7 @@ struct ar6k_device { u8 _Pad1[A_CACHE_LINE_PAD]; AR6K_IRQ_PROC_REGISTERS IrqProcRegisters; /* cache-line safe with pads around */ u8 _Pad2[A_CACHE_LINE_PAD]; - AR6K_IRQ_ENABLE_REGISTERS IrqEnableRegisters; /* cache-line safe with pads around */ + struct ar6k_irq_enable_registers IrqEnableRegisters; /* cache-line safe with pads around */ u8 _Pad3[A_CACHE_LINE_PAD]; void *HIFDevice; u32 BlockSize; @@ -160,7 +160,7 @@ int DevCheckPendingRecvMsgsAsync(void *context); void DevAsyncIrqProcessComplete(struct ar6k_device *pDev); void DevDumpRegisters(struct ar6k_device *pDev, AR6K_IRQ_PROC_REGISTERS *pIrqProcRegs, - AR6K_IRQ_ENABLE_REGISTERS *pIrqEnableRegs); + struct ar6k_irq_enable_registers *pIrqEnableRegs); #define DEV_STOP_RECV_ASYNC true #define DEV_STOP_RECV_SYNC false diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c index aa455907457d..3aafbea57c17 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c @@ -747,7 +747,7 @@ int DevDsrHandler(void *context) void DumpAR6KDevState(struct ar6k_device *pDev) { int status; - AR6K_IRQ_ENABLE_REGISTERS regs; + struct ar6k_irq_enable_registers regs; AR6K_IRQ_PROC_REGISTERS procRegs; LOCK_AR6K(pDev); diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c index cbfbdea27953..1b44d079bc73 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c @@ -77,7 +77,7 @@ static void DevGMboxIRQActionAsyncHandler(void *Context, HTC_PACKET *pPacket) static int DevGMboxCounterEnableDisable(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode) { int status = 0; - AR6K_IRQ_ENABLE_REGISTERS regs; + struct ar6k_irq_enable_registers regs; HTC_PACKET *pIOPacket = NULL; LOCK_AR6K(pDev); -- cgit v1.2.3 From e6998a556b6773542b60e48b451f99574c05cbaa Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 10 Mar 2011 18:55:41 -0800 Subject: staging: ath6kl: remove-typedef AR6K_IRQ_PROC_REGISTERS remove-typedef -s AR6K_IRQ_PROC_REGISTERS \ "struct ar6k_irq_proc_registers" drivers/staging/ath6kl/ Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 2 +- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 10 +++++----- drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c | 4 ++-- drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index 77fa61848445..bdaffd7b13fe 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -537,7 +537,7 @@ int DevWaitForPendingRecv(struct ar6k_device *pDev,u32 TimeoutInMs,bool *pbIsRec } void DevDumpRegisters(struct ar6k_device *pDev, - AR6K_IRQ_PROC_REGISTERS *pIrqProcRegs, + struct ar6k_irq_proc_registers *pIrqProcRegs, struct ar6k_irq_enable_registers *pIrqEnableRegs) { diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index fc781d17ce48..247cf567f2ac 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -43,7 +43,7 @@ //#define MBOXHW_UNIT_TEST 1 #include "athstartpack.h" -typedef PREPACK struct _AR6K_IRQ_PROC_REGISTERS { +PREPACK struct ar6k_irq_proc_registers { u8 host_int_status; u8 cpu_int_status; u8 error_int_status; @@ -54,9 +54,9 @@ typedef PREPACK struct _AR6K_IRQ_PROC_REGISTERS { u8 gmbox_rx_avail; u32 rx_lookahead[2]; u32 rx_gmbox_lookahead_alias[2]; -} POSTPACK AR6K_IRQ_PROC_REGISTERS; +} POSTPACK; -#define AR6K_IRQ_PROC_REGS_SIZE sizeof(AR6K_IRQ_PROC_REGISTERS) +#define AR6K_IRQ_PROC_REGS_SIZE sizeof(struct ar6k_irq_proc_registers) PREPACK struct ar6k_irq_enable_registers { u8 int_status_enable; @@ -108,7 +108,7 @@ struct ar6k_gmbox_info { struct ar6k_device { A_MUTEX_T Lock; u8 _Pad1[A_CACHE_LINE_PAD]; - AR6K_IRQ_PROC_REGISTERS IrqProcRegisters; /* cache-line safe with pads around */ + struct ar6k_irq_proc_registers IrqProcRegisters; /* cache-line safe with pads around */ u8 _Pad2[A_CACHE_LINE_PAD]; struct ar6k_irq_enable_registers IrqEnableRegisters; /* cache-line safe with pads around */ u8 _Pad3[A_CACHE_LINE_PAD]; @@ -159,7 +159,7 @@ int DevDsrHandler(void *context); int DevCheckPendingRecvMsgsAsync(void *context); void DevAsyncIrqProcessComplete(struct ar6k_device *pDev); void DevDumpRegisters(struct ar6k_device *pDev, - AR6K_IRQ_PROC_REGISTERS *pIrqProcRegs, + struct ar6k_irq_proc_registers *pIrqProcRegs, struct ar6k_irq_enable_registers *pIrqEnableRegs); #define DEV_STOP_RECV_ASYNC true diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c index 3aafbea57c17..bac4f9374cd8 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c @@ -331,7 +331,7 @@ static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket) } } else { /* standard interrupt table handling.... */ - AR6K_IRQ_PROC_REGISTERS *pReg = (AR6K_IRQ_PROC_REGISTERS *)pPacket->pBuffer; + struct ar6k_irq_proc_registers *pReg = (struct ar6k_irq_proc_registers *)pPacket->pBuffer; u8 host_int_status; host_int_status = pReg->host_int_status & pDev->IrqEnableRegisters.int_status_enable; @@ -748,7 +748,7 @@ void DumpAR6KDevState(struct ar6k_device *pDev) { int status; struct ar6k_irq_enable_registers regs; - AR6K_IRQ_PROC_REGISTERS procRegs; + struct ar6k_irq_proc_registers procRegs; LOCK_AR6K(pDev); /* copy into our temp area */ diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c index 1b44d079bc73..106f9bf7b117 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c @@ -638,7 +638,7 @@ int DevGMboxRecvLookAheadPeek(struct ar6k_device *pDev, u8 *pLookAheadBuffer, in { int status = 0; - AR6K_IRQ_PROC_REGISTERS procRegs; + struct ar6k_irq_proc_registers procRegs; int maxCopy; do { -- cgit v1.2.3 From cbe7075102239dfc0187c30ac0cd4b79eddd35c2 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 10 Mar 2011 18:55:42 -0800 Subject: staging: ath6kl: remove-typedef AR_VIRTUAL_INTERFACE_T remove-typedef -s AR_VIRTUAL_INTERFACE_T \ "struct ar_virtual_interface" drivers/staging/ath6kl/ Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 12 ++++++------ drivers/staging/ath6kl/os/linux/include/ar6000_drv.h | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 3397995b1c3d..e52a88a4e4d4 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -6402,10 +6402,10 @@ static void DoHTCSendPktsTest(AR_SOFTC_T *ar, int MapNo, HTC_ENDPOINT_ID eid, st int ar6000_start_ap_interface(AR_SOFTC_T *ar) { - AR_VIRTUAL_INTERFACE_T *arApDev; + struct ar_virtual_interface *arApDev; /* Change net_device to point to AP instance */ - arApDev = (AR_VIRTUAL_INTERFACE_T *)ar->arApDev; + arApDev = (struct ar_virtual_interface *)ar->arApDev; ar->arNetDev = arApDev->arNetDev; return 0; @@ -6413,10 +6413,10 @@ int ar6000_start_ap_interface(AR_SOFTC_T *ar) int ar6000_stop_ap_interface(AR_SOFTC_T *ar) { - AR_VIRTUAL_INTERFACE_T *arApDev; + struct ar_virtual_interface *arApDev; /* Change net_device to point to sta instance */ - arApDev = (AR_VIRTUAL_INTERFACE_T *)ar->arApDev; + arApDev = (struct ar_virtual_interface *)ar->arApDev; if (arApDev) { ar->arNetDev = arApDev->arStaNetDev; } @@ -6428,9 +6428,9 @@ int ar6000_stop_ap_interface(AR_SOFTC_T *ar) int ar6000_create_ap_interface(AR_SOFTC_T *ar, char *ap_ifname) { struct net_device *dev; - AR_VIRTUAL_INTERFACE_T *arApDev; + struct ar_virtual_interface *arApDev; - dev = alloc_etherdev(sizeof(AR_VIRTUAL_INTERFACE_T)); + dev = alloc_etherdev(sizeof(struct ar_virtual_interface)); if (dev == NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: can't alloc etherdev\n")); return A_ERROR; diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 0beba096e9d1..2c6f873960a2 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -625,11 +625,11 @@ typedef struct ar6_softc { } AR_SOFTC_T; #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT -typedef struct { +struct ar_virtual_interface { struct net_device *arNetDev; /* net_device pointer */ AR_SOFTC_T *arDev; /* ar device pointer */ struct net_device *arStaNetDev; /* net_device pointer */ -} AR_VIRTUAL_INTERFACE_T; +}; #endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */ #ifdef ATH6K_CONFIG_CFG80211 @@ -645,7 +645,7 @@ static inline void *ar6k_priv(struct net_device *dev) if (arApNetDev == dev) { /* return arDev saved in virtual interface context */ - AR_VIRTUAL_INTERFACE_T *arVirDev; + struct ar_virtual_interface *arVirDev; arVirDev = netdev_priv(dev); return arVirDev->arDev; } else { -- cgit v1.2.3 From 42837dc9cb92ed7c0f69a23abad56b3ff2b190cd Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 10 Mar 2011 18:55:43 -0800 Subject: staging: ath6kl: remove-typedef ATHBT_FILTER_INSTANCE We mark this as unused as well, given that I find no users, at a later time we can determine to nuke this or not... Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/include/athbtfilter.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/include/athbtfilter.h b/drivers/staging/ath6kl/include/athbtfilter.h index 378f96719a17..81456eea3b0b 100644 --- a/drivers/staging/ath6kl/include/athbtfilter.h +++ b/drivers/staging/ath6kl/include/athbtfilter.h @@ -61,7 +61,7 @@ typedef enum _ATHBT_STATE { typedef void (*ATHBT_INDICATE_STATE_FN)(void *pContext, ATHBT_STATE_INDICATION Indication, ATHBT_STATE State, unsigned char LMPVersion); -typedef struct _ATHBT_FILTER_INSTANCE { +struct athbt_filter_instance { #ifdef UNDER_CE WCHAR *pWlanAdapterName; /* filled in by user */ #else @@ -74,7 +74,7 @@ typedef struct _ATHBT_FILTER_INSTANCE { ATHBT_FILTER_DATA_FN pFilterAclDataOut; /* function ptr to filter ACL data out (to radio) */ ATHBT_FILTER_DATA_FN pFilterAclDataIn; /* function ptr to filter ACL data in (from radio) */ ATHBT_INDICATE_STATE_FN pIndicateState; /* function ptr to indicate a state */ -} ATH_BT_FILTER_INSTANCE; +}; /* XXX: unused ? */ /* API MACROS */ -- cgit v1.2.3 From 090f807a0ddcb01884827870be4038d6b4b4d5e4 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 10 Mar 2011 18:55:44 -0800 Subject: staging: ath6kl: remove-typedef ATH_DEBUG_MASK_DESCRIPTION remove-typedef -s ATH_DEBUG_MASK_DESCRIPTION \ "struct ath_debug_mask_description" drivers/staging/ath6kl/ Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/bmi/src/bmi.c | 2 +- drivers/staging/ath6kl/htc2/htc.c | 2 +- drivers/staging/ath6kl/include/a_debug.h | 10 +++++----- drivers/staging/ath6kl/miscdrv/common_drv.c | 2 +- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 2 +- drivers/staging/ath6kl/os/linux/ar6000_pm.c | 2 +- drivers/staging/ath6kl/wlan/src/wlan_node.c | 2 +- drivers/staging/ath6kl/wmi/wmi.c | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/bmi/src/bmi.c b/drivers/staging/ath6kl/bmi/src/bmi.c index 37f7cbce8654..a9615b726005 100644 --- a/drivers/staging/ath6kl/bmi/src/bmi.c +++ b/drivers/staging/ath6kl/bmi/src/bmi.c @@ -33,7 +33,7 @@ #include "bmi_internal.h" #ifdef ATH_DEBUG_MODULE -static ATH_DEBUG_MASK_DESCRIPTION bmi_debug_desc[] = { +static struct ath_debug_mask_description bmi_debug_desc[] = { { ATH_DEBUG_BMI , "BMI Tracing"}, }; diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index 8bde7bf38b34..bb999b674537 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -23,7 +23,7 @@ #include "htc_internal.h" #ifdef ATH_DEBUG_MODULE -static ATH_DEBUG_MASK_DESCRIPTION g_HTCDebugDescription[] = { +static struct ath_debug_mask_description g_HTCDebugDescription[] = { { ATH_DEBUG_SEND , "Send"}, { ATH_DEBUG_RECV , "Recv"}, { ATH_DEBUG_SYNC , "Sync"}, diff --git a/drivers/staging/ath6kl/include/a_debug.h b/drivers/staging/ath6kl/include/a_debug.h index 0e5430d8077f..d433942e2b98 100644 --- a/drivers/staging/ath6kl/include/a_debug.h +++ b/drivers/staging/ath6kl/include/a_debug.h @@ -95,7 +95,7 @@ void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription); * #define ATH_DEBUG_BMI ATH_DEBUG_MAKE_MODULE_MASK(0) * * #ifdef DEBUG - * static ATH_DEBUG_MASK_DESCRIPTION bmi_debug_desc[] = { + * static struct ath_debug_mask_description bmi_debug_desc[] = { * { ATH_DEBUG_BMI , "BMI Tracing"}, <== description of the module specific mask * }; * @@ -118,10 +118,10 @@ void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription); #define ATH_DEBUG_MAX_MASK_DESC_LENGTH 32 #define ATH_DEBUG_MAX_MOD_DESC_LENGTH 64 -typedef struct { +struct ath_debug_mask_description { u32 Mask; char Description[ATH_DEBUG_MAX_MASK_DESC_LENGTH]; -} ATH_DEBUG_MASK_DESCRIPTION; +}; #define ATH_DEBUG_INFO_FLAGS_REGISTERED (1 << 0) @@ -132,10 +132,10 @@ typedef struct _ATH_DEBUG_MODULE_DBG_INFO{ u32 Flags; u32 CurrentMask; int MaxDescriptions; - ATH_DEBUG_MASK_DESCRIPTION *pMaskDescriptions; /* pointer to array of descriptions */ + struct ath_debug_mask_description *pMaskDescriptions; /* pointer to array of descriptions */ } ATH_DEBUG_MODULE_DBG_INFO; -#define ATH_DEBUG_DESCRIPTION_COUNT(d) (int)((sizeof((d))) / (sizeof(ATH_DEBUG_MASK_DESCRIPTION))) +#define ATH_DEBUG_DESCRIPTION_COUNT(d) (int)((sizeof((d))) / (sizeof(struct ath_debug_mask_description))) #define GET_ATH_MODULE_DEBUG_VAR_NAME(s) _XGET_ATH_MODULE_NAME_DEBUG_(s) #define GET_ATH_MODULE_DEBUG_VAR_MASK(s) _XGET_ATH_MODULE_NAME_DEBUG_(s).CurrentMask diff --git a/drivers/staging/ath6kl/miscdrv/common_drv.c b/drivers/staging/ath6kl/miscdrv/common_drv.c index b5f74c574230..3ada3317fdbc 100644 --- a/drivers/staging/ath6kl/miscdrv/common_drv.c +++ b/drivers/staging/ath6kl/miscdrv/common_drv.c @@ -834,7 +834,7 @@ void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription) void a_dump_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo) { int i; - ATH_DEBUG_MASK_DESCRIPTION *pDesc; + struct ath_debug_mask_description *pDesc; if (pInfo == NULL) { return; diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index e52a88a4e4d4..811235a7031b 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -60,7 +60,7 @@ u8 null_mac[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; #define ATH_DEBUG_HTC_RAW ATH_DEBUG_MAKE_MODULE_MASK(5) #define ATH_DEBUG_HCI_BRIDGE ATH_DEBUG_MAKE_MODULE_MASK(6) -static ATH_DEBUG_MASK_DESCRIPTION driver_debug_desc[] = { +static struct ath_debug_mask_description driver_debug_desc[] = { { ATH_DEBUG_DBG_LOG , "Target Debug Logs"}, { ATH_DEBUG_WLAN_CONNECT , "WLAN connect"}, { ATH_DEBUG_WLAN_SCAN , "WLAN scan"}, diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c index 46342d87cc00..5659ad8f8e16 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_pm.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_pm.c @@ -44,7 +44,7 @@ extern void android_ar6k_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, b #define ATH_DEBUG_PM ATH_DEBUG_MAKE_MODULE_MASK(0) #ifdef DEBUG -static ATH_DEBUG_MASK_DESCRIPTION pm_debug_desc[] = { +static struct ath_debug_mask_description pm_debug_desc[] = { { ATH_DEBUG_PM , "System power management"}, }; diff --git a/drivers/staging/ath6kl/wlan/src/wlan_node.c b/drivers/staging/ath6kl/wlan/src/wlan_node.c index 83c4dc35e404..1a3ac7dd5e34 100644 --- a/drivers/staging/ath6kl/wlan/src/wlan_node.c +++ b/drivers/staging/ath6kl/wlan/src/wlan_node.c @@ -40,7 +40,7 @@ #ifdef ATH_DEBUG_MODULE -static ATH_DEBUG_MASK_DESCRIPTION wlan_debug_desc[] = { +static struct ath_debug_mask_description wlan_debug_desc[] = { { ATH_DEBUG_WLAN , "General WLAN Node Tracing"}, }; diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index 80ba629f94bd..0ddaee21f9d7 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -48,7 +48,7 @@ #ifdef ATH_DEBUG_MODULE -static ATH_DEBUG_MASK_DESCRIPTION wmi_debug_desc[] = { +static struct ath_debug_mask_description wmi_debug_desc[] = { { ATH_DEBUG_WMI , "General WMI Tracing"}, }; -- cgit v1.2.3 From d184f4a0528f3734df4639c32a12c8ded4c1afb7 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 10 Mar 2011 18:55:45 -0800 Subject: staging: ath6kl: remove-typedef BUFFER_PROC_LIST remove-typedef -s BUFFER_PROC_LIST \ "struct buffer_proc_list" drivers/staging/ath6kl/ Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index bdaffd7b13fe..2797b556f463 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -1017,10 +1017,10 @@ static u32 g_BlockSizes[AR6K_MAILBOXES]; #define BUFFER_PROC_LIST_DEPTH 4 -typedef struct _BUFFER_PROC_LIST{ +struct buffer_proc_list { u8 *pBuffer; u32 length; -}BUFFER_PROC_LIST; +}; #define PUSH_BUFF_PROC_ENTRY(pList,len,pCurrpos) \ @@ -1032,7 +1032,7 @@ typedef struct _BUFFER_PROC_LIST{ } /* a simple and crude way to send different "message" sizes */ -static void AssembleBufferList(BUFFER_PROC_LIST *pList) +static void AssembleBufferList(struct buffer_proc_list *pList) { u8 *pBuffer = g_Buffer; @@ -1095,7 +1095,7 @@ static bool CheckBuffers(void) { int i; bool success = true; - BUFFER_PROC_LIST checkList[BUFFER_PROC_LIST_DEPTH]; + struct buffer_proc_list checkList[BUFFER_PROC_LIST_DEPTH]; /* assemble the list */ AssembleBufferList(checkList); @@ -1117,7 +1117,7 @@ static bool CheckBuffers(void) static u16 GetEndMarker(void) { u8 *pBuffer; - BUFFER_PROC_LIST checkList[BUFFER_PROC_LIST_DEPTH]; + struct buffer_proc_list checkList[BUFFER_PROC_LIST_DEPTH]; /* fill up buffers with the normal counting pattern */ InitBuffers(FILL_COUNTING); @@ -1138,7 +1138,7 @@ static int SendBuffers(struct ar6k_device *pDev, int mbox) { int status = 0; u32 request = HIF_WR_SYNC_BLOCK_INC; - BUFFER_PROC_LIST sendList[BUFFER_PROC_LIST_DEPTH]; + struct buffer_proc_list sendList[BUFFER_PROC_LIST_DEPTH]; int i; int totalBytes = 0; int paddedLength; @@ -1229,7 +1229,7 @@ static int RecvBuffers(struct ar6k_device *pDev, int mbox) { int status = 0; u32 request = HIF_RD_SYNC_BLOCK_INC; - BUFFER_PROC_LIST recvList[BUFFER_PROC_LIST_DEPTH]; + struct buffer_proc_list recvList[BUFFER_PROC_LIST_DEPTH]; int curBuffer; int credits; int i; -- cgit v1.2.3 From 84fd335f2d4f447363f79a8cb032635a05c91887 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 10 Mar 2011 18:55:46 -0800 Subject: staging: ath6kl: remove-typedef COMMON_CREDIT_STATE_INFO remove-typedef -s COMMON_CREDIT_STATE_INFO \ "struct common_credit_state_info" drivers/staging/ath6kl/ Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/include/common_drv.h | 6 +++--- drivers/staging/ath6kl/miscdrv/credit_dist.c | 18 +++++++++--------- drivers/staging/ath6kl/os/linux/include/ar6000_drv.h | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/include/common_drv.h b/drivers/staging/ath6kl/include/common_drv.h index 6ed490112643..f5bc9c3bf222 100644 --- a/drivers/staging/ath6kl/include/common_drv.h +++ b/drivers/staging/ath6kl/include/common_drv.h @@ -29,12 +29,12 @@ /* structure that is the state information for the default credit distribution callback * drivers should instantiate (zero-init as well) this structure in their driver instance * and pass it as a context to the HTC credit distribution functions */ -typedef struct _COMMON_CREDIT_STATE_INFO { +struct common_credit_state_info { int TotalAvailableCredits; /* total credits in the system at startup */ int CurrentFreeCredits; /* credits available in the pool that have not been given out to endpoints */ HTC_ENDPOINT_CREDIT_DIST *pLowestPriEpDist; /* pointer to the lowest priority endpoint dist struct */ -} COMMON_CREDIT_STATE_INFO; +}; typedef struct { s32 (*setupTransport)(void *ar); @@ -64,7 +64,7 @@ extern "C" { #endif /* OS-independent APIs */ -int ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, COMMON_CREDIT_STATE_INFO *pCredInfo); +int ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, struct common_credit_state_info *pCredInfo); int ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data); diff --git a/drivers/staging/ath6kl/miscdrv/credit_dist.c b/drivers/staging/ath6kl/miscdrv/credit_dist.c index 68b1ed67b307..8c418d2d8310 100644 --- a/drivers/staging/ath6kl/miscdrv/credit_dist.c +++ b/drivers/staging/ath6kl/miscdrv/credit_dist.c @@ -41,14 +41,14 @@ #define DATA_SVCS_USED 4 #endif -static void RedistributeCredits(COMMON_CREDIT_STATE_INFO *pCredInfo, +static void RedistributeCredits(struct common_credit_state_info *pCredInfo, HTC_ENDPOINT_CREDIT_DIST *pEPDistList); -static void SeekCredits(COMMON_CREDIT_STATE_INFO *pCredInfo, +static void SeekCredits(struct common_credit_state_info *pCredInfo, HTC_ENDPOINT_CREDIT_DIST *pEPDistList); /* reduce an ep's credits back to a set limit */ -static INLINE void ReduceCredits(COMMON_CREDIT_STATE_INFO *pCredInfo, +static INLINE void ReduceCredits(struct common_credit_state_info *pCredInfo, HTC_ENDPOINT_CREDIT_DIST *pEpDist, int Limit) { @@ -86,7 +86,7 @@ static void ar6000_credit_init(void *Context, { HTC_ENDPOINT_CREDIT_DIST *pCurEpDist; int count; - COMMON_CREDIT_STATE_INFO *pCredInfo = (COMMON_CREDIT_STATE_INFO *)Context; + struct common_credit_state_info *pCredInfo = (struct common_credit_state_info *)Context; pCredInfo->CurrentFreeCredits = TotalCredits; pCredInfo->TotalAvailableCredits = TotalCredits; @@ -179,7 +179,7 @@ static void ar6000_credit_distribute(void *Context, HTC_CREDIT_DIST_REASON Reason) { HTC_ENDPOINT_CREDIT_DIST *pCurEpDist; - COMMON_CREDIT_STATE_INFO *pCredInfo = (COMMON_CREDIT_STATE_INFO *)Context; + struct common_credit_state_info *pCredInfo = (struct common_credit_state_info *)Context; switch (Reason) { case HTC_CREDIT_DIST_SEND_COMPLETE : @@ -243,7 +243,7 @@ static void ar6000_credit_distribute(void *Context, } /* redistribute credits based on activity change */ -static void RedistributeCredits(COMMON_CREDIT_STATE_INFO *pCredInfo, +static void RedistributeCredits(struct common_credit_state_info *pCredInfo, HTC_ENDPOINT_CREDIT_DIST *pEPDistList) { HTC_ENDPOINT_CREDIT_DIST *pCurEpDist = pEPDistList; @@ -283,7 +283,7 @@ static void RedistributeCredits(COMMON_CREDIT_STATE_INFO *pCredInfo, } /* HTC has an endpoint that needs credits, pEPDist is the endpoint in question */ -static void SeekCredits(COMMON_CREDIT_STATE_INFO *pCredInfo, +static void SeekCredits(struct common_credit_state_info *pCredInfo, HTC_ENDPOINT_CREDIT_DIST *pEPDist) { HTC_ENDPOINT_CREDIT_DIST *pCurEpDist; @@ -393,11 +393,11 @@ static void SeekCredits(COMMON_CREDIT_STATE_INFO *pCredInfo, } /* initialize and setup credit distribution */ -int ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, COMMON_CREDIT_STATE_INFO *pCredInfo) +int ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, struct common_credit_state_info *pCredInfo) { HTC_SERVICE_ID servicepriority[5]; - A_MEMZERO(pCredInfo,sizeof(COMMON_CREDIT_STATE_INFO)); + A_MEMZERO(pCredInfo,sizeof(struct common_credit_state_info)); servicepriority[0] = WMI_CONTROL_SVC; /* highest */ servicepriority[1] = WMI_DATA_VO_SVC; diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 2c6f873960a2..2373ed55e573 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -550,7 +550,7 @@ typedef struct ar6_softc { bool arNetQueueStopped; bool arRawIfInit; int arDeviceIndex; - COMMON_CREDIT_STATE_INFO arCreditStateInfo; + struct common_credit_state_info arCreditStateInfo; bool arWMIControlEpFull; bool dbgLogFetchInProgress; u8 log_buffer[DBGLOG_HOST_LOG_BUFFER_SIZE]; -- cgit v1.2.3 From 9107a26ebcadf869e647100ada876e074b8d26a9 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 10 Mar 2011 18:55:47 -0800 Subject: staging: ath6kl: remove-typedef DEV_SCATTER_DMA_VIRTUAL_INFO remove-typedef -s DEV_SCATTER_DMA_VIRTUAL_INFO \ "struct dev_scatter_dma_virtual_info" drivers/staging/ath6kl/ Cc: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 10 +++++----- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index 2797b556f463..a41ed12043d6 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -585,7 +585,7 @@ void DevDumpRegisters(struct ar6k_device *pDev, } -#define DEV_GET_VIRT_DMA_INFO(p) ((DEV_SCATTER_DMA_VIRTUAL_INFO *)((p)->HIFPrivate[0])) +#define DEV_GET_VIRT_DMA_INFO(p) ((struct dev_scatter_dma_virtual_info *)((p)->HIFPrivate[0])) static HIF_SCATTER_REQ *DevAllocScatterReq(HIF_DEVICE *Context) { @@ -754,10 +754,10 @@ static int DevSetupVirtualScatterSupport(struct ar6k_device *pDev) int status = 0; int bufferSize, sgreqSize; int i; - DEV_SCATTER_DMA_VIRTUAL_INFO *pVirtualInfo; + struct dev_scatter_dma_virtual_info *pVirtualInfo; HIF_SCATTER_REQ *pReq; - bufferSize = sizeof(DEV_SCATTER_DMA_VIRTUAL_INFO) + + bufferSize = sizeof(struct dev_scatter_dma_virtual_info) + 2 * (A_GET_CACHE_LINE_BYTES()) + AR6K_MAX_TRANSFER_SIZE_PER_SCATTER; sgreqSize = sizeof(HIF_SCATTER_REQ) + @@ -775,8 +775,8 @@ static int DevSetupVirtualScatterSupport(struct ar6k_device *pDev) A_MEMZERO(pReq, sgreqSize); /* the virtual DMA starts after the scatter request struct */ - pVirtualInfo = (DEV_SCATTER_DMA_VIRTUAL_INFO *)((u8 *)pReq + sgreqSize); - A_MEMZERO(pVirtualInfo, sizeof(DEV_SCATTER_DMA_VIRTUAL_INFO)); + pVirtualInfo = (struct dev_scatter_dma_virtual_info *)((u8 *)pReq + sgreqSize); + A_MEMZERO(pVirtualInfo, sizeof(struct dev_scatter_dma_virtual_info)); pVirtualInfo->pVirtDmaBuffer = &pVirtualInfo->DataArea[0]; /* align buffer to cache line in case host controller can actually DMA this */ diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index 247cf567f2ac..3e4ece865be9 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -322,10 +322,10 @@ int DoMboxHWTest(struct ar6k_device *pDev); #endif /* completely virtual */ -typedef struct _DEV_SCATTER_DMA_VIRTUAL_INFO { +struct dev_scatter_dma_virtual_info { u8 *pVirtDmaBuffer; /* dma-able buffer - CPU accessible address */ u8 DataArea[1]; /* start of data area */ -} DEV_SCATTER_DMA_VIRTUAL_INFO; +}; -- cgit v1.2.3 From 0789b0033112e301f086f99bd15c7d67c051a51e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 11 Mar 2011 14:32:01 -0800 Subject: Staging: samsung-laptop: add support for N230 model Signed-off-by: Greg Kroah-Hartman --- drivers/staging/samsung-laptop/samsung-laptop.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index 1813d5b6a5f9..6607a89ccb4b 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -601,12 +601,12 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { .callback = dmi_check_cb, }, { - .ident = "N150/N210/N220", + .ident = "N150/N210/N220/N230", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220"), - DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220"), + DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220/N230"), + DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220/N230"), }, .callback = dmi_check_cb, }, -- cgit v1.2.3 From a9f7c5363b7d2d836ad2be2d96fd4af3fd0d349a Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Wed, 2 Mar 2011 06:52:30 +0000 Subject: ixgbevf: Fix Version String The kernel version string is off by a major version number since new silicon was just introduced and also uses the wrong format for the version postfix. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher --- drivers/net/ixgbevf/ixgbevf_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index c1fb2c1b540e..2f6bc31bc75b 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -51,7 +51,7 @@ char ixgbevf_driver_name[] = "ixgbevf"; static const char ixgbevf_driver_string[] = "Intel(R) 82599 Virtual Function"; -#define DRV_VERSION "1.1.0-k0" +#define DRV_VERSION "2.0.0-k2" const char ixgbevf_driver_version[] = DRV_VERSION; static char ixgbevf_copyright[] = "Copyright (c) 2009 - 2010 Intel Corporation."; -- cgit v1.2.3 From 422e05d12af9c1063d57210074b4e6db36a0cf39 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Sat, 12 Mar 2011 02:01:29 +0000 Subject: ixgbevf: Fix Driver String Change the driver string to match the PF driver string format. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher --- drivers/net/ixgbevf/ixgbevf_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 2f6bc31bc75b..054ab05b7c6a 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -49,7 +49,7 @@ char ixgbevf_driver_name[] = "ixgbevf"; static const char ixgbevf_driver_string[] = - "Intel(R) 82599 Virtual Function"; + "Intel(R) 10 Gigabit PCI Express Virtual Function Network Driver"; #define DRV_VERSION "2.0.0-k2" const char ixgbevf_driver_version[] = DRV_VERSION; -- cgit v1.2.3 From 09b068d45737abb49320ab25cb4ed2916017ace7 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Fri, 11 Mar 2011 20:42:13 -0800 Subject: igb: Add Energy Efficient Ethernet (EEE) for i350 devices. This patch adds the EEE feature for i350 devices, enabled by default. Signed-off-by: Carolyn Wyborny Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/igb/e1000_82575.c | 46 ++++++++++++++++++++++++++++++++++++++++- drivers/net/igb/e1000_82575.h | 1 + drivers/net/igb/e1000_defines.h | 7 +++++++ drivers/net/igb/e1000_hw.h | 1 + drivers/net/igb/e1000_regs.h | 4 ++++ drivers/net/igb/igb_main.c | 8 ++++++- 6 files changed, 65 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 65c1833244f7..20d172aeb1c0 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -195,7 +195,11 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) mac->arc_subsystem_valid = (rd32(E1000_FWSM) & E1000_FWSM_MODE_MASK) ? true : false; - + /* enable EEE on i350 parts */ + if (mac->type == e1000_i350) + dev_spec->eee_disable = false; + else + dev_spec->eee_disable = true; /* physical interface link setup */ mac->ops.setup_physical_interface = (hw->phy.media_type == e1000_media_type_copper) @@ -1754,6 +1758,46 @@ u16 igb_rxpbs_adjust_82580(u32 data) return ret_val; } +/** + * igb_set_eee_i350 - Enable/disable EEE support + * @hw: pointer to the HW structure + * + * Enable/disable EEE based on setting in dev_spec structure. + * + **/ +s32 igb_set_eee_i350(struct e1000_hw *hw) +{ + s32 ret_val = 0; + u32 ipcnfg, eeer, ctrl_ext; + + ctrl_ext = rd32(E1000_CTRL_EXT); + if ((hw->mac.type != e1000_i350) || + (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK)) + goto out; + ipcnfg = rd32(E1000_IPCNFG); + eeer = rd32(E1000_EEER); + + /* enable or disable per user setting */ + if (!(hw->dev_spec._82575.eee_disable)) { + ipcnfg |= (E1000_IPCNFG_EEE_1G_AN | + E1000_IPCNFG_EEE_100M_AN); + eeer |= (E1000_EEER_TX_LPI_EN | + E1000_EEER_RX_LPI_EN | + E1000_EEER_LPI_FC); + + } else { + ipcnfg &= ~(E1000_IPCNFG_EEE_1G_AN | + E1000_IPCNFG_EEE_100M_AN); + eeer &= ~(E1000_EEER_TX_LPI_EN | + E1000_EEER_RX_LPI_EN | + E1000_EEER_LPI_FC); + } + wr32(E1000_IPCNFG, ipcnfg); + wr32(E1000_EEER, eeer); +out: + + return ret_val; +} static struct e1000_mac_operations e1000_mac_ops_82575 = { .init_hw = igb_init_hw_82575, .check_for_link = igb_check_for_link_82575, diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h index 1d01af2472e7..dd6df3498998 100644 --- a/drivers/net/igb/e1000_82575.h +++ b/drivers/net/igb/e1000_82575.h @@ -251,5 +251,6 @@ void igb_vmdq_set_anti_spoofing_pf(struct e1000_hw *, bool, int); void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool); void igb_vmdq_set_replication_pf(struct e1000_hw *, bool); u16 igb_rxpbs_adjust_82580(u32 data); +s32 igb_set_eee_i350(struct e1000_hw *); #endif diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index 92e11da25749..79267813982a 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h @@ -758,6 +758,13 @@ #define E1000_MDIC_ERROR 0x40000000 #define E1000_MDIC_DEST 0x80000000 +/* Energy Efficient Ethernet */ +#define E1000_IPCNFG_EEE_1G_AN 0x00000008 /* EEE Enable 1G AN */ +#define E1000_IPCNFG_EEE_100M_AN 0x00000004 /* EEE Enable 100M AN */ +#define E1000_EEER_TX_LPI_EN 0x00010000 /* EEE Tx LPI Enable */ +#define E1000_EEER_RX_LPI_EN 0x00020000 /* EEE Rx LPI Enable */ +#define E1000_EEER_LPI_FC 0x00040000 /* EEE Enable on FC */ + /* SerDes Control */ #define E1000_GEN_CTL_READY 0x80000000 #define E1000_GEN_CTL_ADDRESS_SHIFT 8 diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h index eec9ed735588..17569bfe3f2e 100644 --- a/drivers/net/igb/e1000_hw.h +++ b/drivers/net/igb/e1000_hw.h @@ -488,6 +488,7 @@ struct e1000_mbx_info { struct e1000_dev_spec_82575 { bool sgmii_active; bool global_device_reset; + bool eee_disable; }; struct e1000_hw { diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h index 61713548c027..b2f8e593da87 100644 --- a/drivers/net/igb/e1000_regs.h +++ b/drivers/net/igb/e1000_regs.h @@ -329,6 +329,10 @@ /* DMA Coalescing registers */ #define E1000_PCIEMISC 0x05BB8 /* PCIE misc config register */ +/* Energy Efficient Ethernet "EEE" register */ +#define E1000_IPCNFG 0x0E38 /* Internal PHY Configuration */ +#define E1000_EEER 0x0E30 /* Energy Efficient Ethernet */ + /* OS2BMC Registers */ #define E1000_B2OSPC 0x08FE0 /* BMC2OS packets sent by BMC */ #define E1000_B2OGPRC 0x04158 /* BMC2OS packets received by host */ diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 3666b967846a..8643f8c29199 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -2014,7 +2014,13 @@ static int __devinit igb_probe(struct pci_dev *pdev, adapter->msix_entries ? "MSI-X" : (adapter->flags & IGB_FLAG_HAS_MSI) ? "MSI" : "legacy", adapter->num_rx_queues, adapter->num_tx_queues); - + switch (hw->mac.type) { + case e1000_i350: + igb_set_eee_i350(hw); + break; + default: + break; + } return 0; err_register: -- cgit v1.2.3 From 4322e561a93ec7ee034b603a6c610e7be90d4e8a Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Fri, 11 Mar 2011 20:43:18 -0800 Subject: igb: Update NVM functions to work with i350 devices This patch adds functions and functions pointers to accommodate differences between NVM interfaces and options for i350 devices, 82580 devices and the rest. Signed-off-by: Carolyn Wyborny Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/igb/e1000_82575.c | 239 +++++++++++++++++++++++++++++++++++++++- drivers/net/igb/e1000_defines.h | 3 + drivers/net/igb/e1000_hw.h | 3 +- drivers/net/igb/e1000_nvm.c | 64 ++++++++++- drivers/net/igb/e1000_nvm.h | 1 + drivers/net/igb/igb_ethtool.c | 2 +- drivers/net/igb/igb_main.c | 2 +- 7 files changed, 306 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 20d172aeb1c0..6b256c275e10 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -64,7 +64,14 @@ static s32 igb_reset_init_script_82575(struct e1000_hw *); static s32 igb_read_mac_addr_82575(struct e1000_hw *); static s32 igb_set_pcie_completion_timeout(struct e1000_hw *hw); static s32 igb_reset_mdicnfg_82580(struct e1000_hw *hw); - +static s32 igb_validate_nvm_checksum_82580(struct e1000_hw *hw); +static s32 igb_update_nvm_checksum_82580(struct e1000_hw *hw); +static s32 igb_update_nvm_checksum_with_offset(struct e1000_hw *hw, + u16 offset); +static s32 igb_validate_nvm_checksum_with_offset(struct e1000_hw *hw, + u16 offset); +static s32 igb_validate_nvm_checksum_i350(struct e1000_hw *hw); +static s32 igb_update_nvm_checksum_i350(struct e1000_hw *hw); static const u16 e1000_82580_rxpbs_table[] = { 36, 72, 144, 1, 2, 4, 8, 16, 35, 70, 140 }; @@ -237,10 +244,32 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) */ size += NVM_WORD_SIZE_BASE_SHIFT; - /* EEPROM access above 16k is unsupported */ - if (size > 14) - size = 14; nvm->word_size = 1 << size; + if (nvm->word_size == (1 << 15)) + nvm->page_size = 128; + + /* NVM Function Pointers */ + nvm->ops.acquire = igb_acquire_nvm_82575; + if (nvm->word_size < (1 << 15)) + nvm->ops.read = igb_read_nvm_eerd; + else + nvm->ops.read = igb_read_nvm_spi; + + nvm->ops.release = igb_release_nvm_82575; + switch (hw->mac.type) { + case e1000_82580: + nvm->ops.validate = igb_validate_nvm_checksum_82580; + nvm->ops.update = igb_update_nvm_checksum_82580; + break; + case e1000_i350: + nvm->ops.validate = igb_validate_nvm_checksum_i350; + nvm->ops.update = igb_update_nvm_checksum_i350; + break; + default: + nvm->ops.validate = igb_validate_nvm_checksum; + nvm->ops.update = igb_update_nvm_checksum; + } + nvm->ops.write = igb_write_nvm_spi; /* if part supports SR-IOV then initialize mailbox parameters */ switch (mac->type) { @@ -1758,6 +1787,207 @@ u16 igb_rxpbs_adjust_82580(u32 data) return ret_val; } +/** + * igb_validate_nvm_checksum_with_offset - Validate EEPROM + * checksum + * @hw: pointer to the HW structure + * @offset: offset in words of the checksum protected region + * + * Calculates the EEPROM checksum by reading/adding each word of the EEPROM + * and then verifies that the sum of the EEPROM is equal to 0xBABA. + **/ +s32 igb_validate_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset) +{ + s32 ret_val = 0; + u16 checksum = 0; + u16 i, nvm_data; + + for (i = offset; i < ((NVM_CHECKSUM_REG + offset) + 1); i++) { + ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data); + if (ret_val) { + hw_dbg("NVM Read Error\n"); + goto out; + } + checksum += nvm_data; + } + + if (checksum != (u16) NVM_SUM) { + hw_dbg("NVM Checksum Invalid\n"); + ret_val = -E1000_ERR_NVM; + goto out; + } + +out: + return ret_val; +} + +/** + * igb_update_nvm_checksum_with_offset - Update EEPROM + * checksum + * @hw: pointer to the HW structure + * @offset: offset in words of the checksum protected region + * + * Updates the EEPROM checksum by reading/adding each word of the EEPROM + * up to the checksum. Then calculates the EEPROM checksum and writes the + * value to the EEPROM. + **/ +s32 igb_update_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset) +{ + s32 ret_val; + u16 checksum = 0; + u16 i, nvm_data; + + for (i = offset; i < (NVM_CHECKSUM_REG + offset); i++) { + ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data); + if (ret_val) { + hw_dbg("NVM Read Error while updating checksum.\n"); + goto out; + } + checksum += nvm_data; + } + checksum = (u16) NVM_SUM - checksum; + ret_val = hw->nvm.ops.write(hw, (NVM_CHECKSUM_REG + offset), 1, + &checksum); + if (ret_val) + hw_dbg("NVM Write Error while updating checksum.\n"); + +out: + return ret_val; +} + +/** + * igb_validate_nvm_checksum_82580 - Validate EEPROM checksum + * @hw: pointer to the HW structure + * + * Calculates the EEPROM section checksum by reading/adding each word of + * the EEPROM and then verifies that the sum of the EEPROM is + * equal to 0xBABA. + **/ +static s32 igb_validate_nvm_checksum_82580(struct e1000_hw *hw) +{ + s32 ret_val = 0; + u16 eeprom_regions_count = 1; + u16 j, nvm_data; + u16 nvm_offset; + + ret_val = hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data); + if (ret_val) { + hw_dbg("NVM Read Error\n"); + goto out; + } + + if (nvm_data & NVM_COMPATIBILITY_BIT_MASK) { + /* if chekcsums compatibility bit is set validate checksums + * for all 4 ports. */ + eeprom_regions_count = 4; + } + + for (j = 0; j < eeprom_regions_count; j++) { + nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j); + ret_val = igb_validate_nvm_checksum_with_offset(hw, + nvm_offset); + if (ret_val != 0) + goto out; + } + +out: + return ret_val; +} + +/** + * igb_update_nvm_checksum_82580 - Update EEPROM checksum + * @hw: pointer to the HW structure + * + * Updates the EEPROM section checksums for all 4 ports by reading/adding + * each word of the EEPROM up to the checksum. Then calculates the EEPROM + * checksum and writes the value to the EEPROM. + **/ +static s32 igb_update_nvm_checksum_82580(struct e1000_hw *hw) +{ + s32 ret_val; + u16 j, nvm_data; + u16 nvm_offset; + + ret_val = hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data); + if (ret_val) { + hw_dbg("NVM Read Error while updating checksum" + " compatibility bit.\n"); + goto out; + } + + if ((nvm_data & NVM_COMPATIBILITY_BIT_MASK) == 0) { + /* set compatibility bit to validate checksums appropriately */ + nvm_data = nvm_data | NVM_COMPATIBILITY_BIT_MASK; + ret_val = hw->nvm.ops.write(hw, NVM_COMPATIBILITY_REG_3, 1, + &nvm_data); + if (ret_val) { + hw_dbg("NVM Write Error while updating checksum" + " compatibility bit.\n"); + goto out; + } + } + + for (j = 0; j < 4; j++) { + nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j); + ret_val = igb_update_nvm_checksum_with_offset(hw, nvm_offset); + if (ret_val) + goto out; + } + +out: + return ret_val; +} + +/** + * igb_validate_nvm_checksum_i350 - Validate EEPROM checksum + * @hw: pointer to the HW structure + * + * Calculates the EEPROM section checksum by reading/adding each word of + * the EEPROM and then verifies that the sum of the EEPROM is + * equal to 0xBABA. + **/ +static s32 igb_validate_nvm_checksum_i350(struct e1000_hw *hw) +{ + s32 ret_val = 0; + u16 j; + u16 nvm_offset; + + for (j = 0; j < 4; j++) { + nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j); + ret_val = igb_validate_nvm_checksum_with_offset(hw, + nvm_offset); + if (ret_val != 0) + goto out; + } + +out: + return ret_val; +} + +/** + * igb_update_nvm_checksum_i350 - Update EEPROM checksum + * @hw: pointer to the HW structure + * + * Updates the EEPROM section checksums for all 4 ports by reading/adding + * each word of the EEPROM up to the checksum. Then calculates the EEPROM + * checksum and writes the value to the EEPROM. + **/ +static s32 igb_update_nvm_checksum_i350(struct e1000_hw *hw) +{ + s32 ret_val = 0; + u16 j; + u16 nvm_offset; + + for (j = 0; j < 4; j++) { + nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j); + ret_val = igb_update_nvm_checksum_with_offset(hw, nvm_offset); + if (ret_val != 0) + goto out; + } + +out: + return ret_val; +} /** * igb_set_eee_i350 - Enable/disable EEE support * @hw: pointer to the HW structure @@ -1798,6 +2028,7 @@ out: return ret_val; } + static struct e1000_mac_operations e1000_mac_ops_82575 = { .init_hw = igb_init_hw_82575, .check_for_link = igb_check_for_link_82575, diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index 79267813982a..97969ad8afef 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h @@ -566,6 +566,8 @@ #define NVM_INIT_CONTROL3_PORT_A 0x0024 #define NVM_ALT_MAC_ADDR_PTR 0x0037 #define NVM_CHECKSUM_REG 0x003F +#define NVM_COMPATIBILITY_REG_3 0x0003 +#define NVM_COMPATIBILITY_BIT_MASK 0x8000 #define E1000_NVM_CFG_DONE_PORT_0 0x040000 /* MNG config cycle done */ #define E1000_NVM_CFG_DONE_PORT_1 0x080000 /* ...for second port */ @@ -600,6 +602,7 @@ /* NVM Commands - SPI */ #define NVM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */ #define NVM_WRITE_OPCODE_SPI 0x02 /* NVM write opcode */ +#define NVM_READ_OPCODE_SPI 0x03 /* NVM read opcode */ #define NVM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = address bit-8 */ #define NVM_WREN_OPCODE_SPI 0x06 /* NVM set Write Enable latch */ #define NVM_RDSR_OPCODE_SPI 0x05 /* NVM read Status register */ diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h index 17569bfe3f2e..27153e8d7b16 100644 --- a/drivers/net/igb/e1000_hw.h +++ b/drivers/net/igb/e1000_hw.h @@ -336,6 +336,8 @@ struct e1000_nvm_operations { s32 (*read)(struct e1000_hw *, u16, u16, u16 *); void (*release)(struct e1000_hw *); s32 (*write)(struct e1000_hw *, u16, u16, u16 *); + s32 (*update)(struct e1000_hw *); + s32 (*validate)(struct e1000_hw *); }; struct e1000_info { @@ -422,7 +424,6 @@ struct e1000_phy_info { struct e1000_nvm_info { struct e1000_nvm_operations ops; - enum e1000_nvm_type type; enum e1000_nvm_override override; diff --git a/drivers/net/igb/e1000_nvm.c b/drivers/net/igb/e1000_nvm.c index 6b5cc2cc453d..75bf36a4baee 100644 --- a/drivers/net/igb/e1000_nvm.c +++ b/drivers/net/igb/e1000_nvm.c @@ -317,6 +317,68 @@ out: return ret_val; } +/** + * igb_read_nvm_spi - Read EEPROM's using SPI + * @hw: pointer to the HW structure + * @offset: offset of word in the EEPROM to read + * @words: number of words to read + * @data: word read from the EEPROM + * + * Reads a 16 bit word from the EEPROM. + **/ +s32 igb_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) +{ + struct e1000_nvm_info *nvm = &hw->nvm; + u32 i = 0; + s32 ret_val; + u16 word_in; + u8 read_opcode = NVM_READ_OPCODE_SPI; + + /* + * A check for invalid values: offset too large, too many words, + * and not enough words. + */ + if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || + (words == 0)) { + hw_dbg("nvm parameter(s) out of bounds\n"); + ret_val = -E1000_ERR_NVM; + goto out; + } + + ret_val = nvm->ops.acquire(hw); + if (ret_val) + goto out; + + ret_val = igb_ready_nvm_eeprom(hw); + if (ret_val) + goto release; + + igb_standby_nvm(hw); + + if ((nvm->address_bits == 8) && (offset >= 128)) + read_opcode |= NVM_A8_OPCODE_SPI; + + /* Send the READ command (opcode + addr) */ + igb_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits); + igb_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits); + + /* + * Read the data. SPI NVMs increment the address with each byte + * read and will roll over if reading beyond the end. This allows + * us to read the whole NVM from any offset + */ + for (i = 0; i < words; i++) { + word_in = igb_shift_in_eec_bits(hw, 16); + data[i] = (word_in >> 8) | (word_in << 8); + } + +release: + nvm->ops.release(hw); + +out: + return ret_val; +} + /** * igb_read_nvm_eerd - Reads EEPROM using EERD register * @hw: pointer to the HW structure @@ -353,7 +415,7 @@ s32 igb_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) break; data[i] = (rd32(E1000_EERD) >> - E1000_NVM_RW_REG_DATA); + E1000_NVM_RW_REG_DATA); } out: diff --git a/drivers/net/igb/e1000_nvm.h b/drivers/net/igb/e1000_nvm.h index 29c956a84bd0..7f43564c4bcc 100644 --- a/drivers/net/igb/e1000_nvm.h +++ b/drivers/net/igb/e1000_nvm.h @@ -35,6 +35,7 @@ s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num); s32 igb_read_part_string(struct e1000_hw *hw, u8 *part_num, u32 part_num_size); s32 igb_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); +s32 igb_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); s32 igb_validate_nvm_checksum(struct e1000_hw *hw); s32 igb_update_nvm_checksum(struct e1000_hw *hw); diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index 78d420b4b2db..df15a915bbea 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -721,7 +721,7 @@ static int igb_set_eeprom(struct net_device *netdev, /* Update the checksum over the first part of the EEPROM if needed * and flush shadow RAM for 82573 controllers */ if ((ret_val == 0) && ((first_word <= NVM_CHECKSUM_REG))) - igb_update_nvm_checksum(hw); + hw->nvm.ops.update(hw); kfree(eeprom_buff); return ret_val; diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 8643f8c29199..8c6af11d93a6 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1884,7 +1884,7 @@ static int __devinit igb_probe(struct pci_dev *pdev, hw->mac.ops.reset_hw(hw); /* make sure the NVM is good */ - if (igb_validate_nvm_checksum(hw) < 0) { + if (hw->nvm.ops.validate(hw) < 0) { dev_err(&pdev->dev, "The NVM Checksum Is Not Valid\n"); err = -EIO; goto err_eeprom; -- cgit v1.2.3 From 831ec0b4226cec7ea34f5c4c9810e78aeb2069bf Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Fri, 11 Mar 2011 20:43:54 -0800 Subject: igb: Add DMA Coalescing feature to driver This patch add DMA Coalescing which is a power-saving feature that coalesces DMA writes in order to stay in a low-power state as much as possible. Feature is disabled by default. Signed-off-by: Carolyn Wyborny Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/igb/e1000_defines.h | 29 ++++++++++++++++++++- drivers/net/igb/e1000_regs.h | 9 +++++++ drivers/net/igb/igb.h | 6 +++++ drivers/net/igb/igb_ethtool.c | 6 +++++ drivers/net/igb/igb_main.c | 57 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 106 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index 97969ad8afef..9bb192825893 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h @@ -287,7 +287,34 @@ #define E1000_TCTL_COLD 0x003ff000 /* collision distance */ #define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */ -/* Transmit Arbitration Count */ +/* DMA Coalescing register fields */ +#define E1000_DMACR_DMACWT_MASK 0x00003FFF /* DMA Coalescing + * Watchdog Timer */ +#define E1000_DMACR_DMACTHR_MASK 0x00FF0000 /* DMA Coalescing Receive + * Threshold */ +#define E1000_DMACR_DMACTHR_SHIFT 16 +#define E1000_DMACR_DMAC_LX_MASK 0x30000000 /* Lx when no PCIe + * transactions */ +#define E1000_DMACR_DMAC_LX_SHIFT 28 +#define E1000_DMACR_DMAC_EN 0x80000000 /* Enable DMA Coalescing */ + +#define E1000_DMCTXTH_DMCTTHR_MASK 0x00000FFF /* DMA Coalescing Transmit + * Threshold */ + +#define E1000_DMCTLX_TTLX_MASK 0x00000FFF /* Time to LX request */ + +#define E1000_DMCRTRH_UTRESH_MASK 0x0007FFFF /* Receive Traffic Rate + * Threshold */ +#define E1000_DMCRTRH_LRPRCW 0x80000000 /* Rcv packet rate in + * current window */ + +#define E1000_DMCCNT_CCOUNT_MASK 0x01FFFFFF /* DMA Coal Rcv Traffic + * Current Cnt */ + +#define E1000_FCRTC_RTH_COAL_MASK 0x0003FFF0 /* Flow ctrl Rcv Threshold + * High val */ +#define E1000_FCRTC_RTH_COAL_SHIFT 4 +#define E1000_PCIEMISC_LX_DECISION 0x00000080 /* Lx power decision */ /* SerDes Control */ #define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400 diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h index b2f8e593da87..ad77ed510d7c 100644 --- a/drivers/net/igb/e1000_regs.h +++ b/drivers/net/igb/e1000_regs.h @@ -106,6 +106,15 @@ #define E1000_RQDPC(_n) (0x0C030 + ((_n) * 0x40)) +/* DMA Coalescing registers */ +#define E1000_DMACR 0x02508 /* Control Register */ +#define E1000_DMCTXTH 0x03550 /* Transmit Threshold */ +#define E1000_DMCTLX 0x02514 /* Time to Lx Request */ +#define E1000_DMCRTRH 0x05DD0 /* Receive Packet Rate Threshold */ +#define E1000_DMCCNT 0x05DD4 /* Current Rx Count */ +#define E1000_FCRTC 0x02170 /* Flow Control Rx high watermark */ +#define E1000_PCIEMISC 0x05BB8 /* PCIE misc config register */ + /* TX Rate Limit Registers */ #define E1000_RTTDQSEL 0x3604 /* Tx Desc Plane Queue Select - WO */ #define E1000_RTTBCNRC 0x36B0 /* Tx BCN Rate-Scheduler Config - WO */ diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index bbc5ebfe254a..1c687e298d5e 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h @@ -333,6 +333,12 @@ struct igb_adapter { #define IGB_FLAG_DCA_ENABLED (1 << 1) #define IGB_FLAG_QUAD_PORT_A (1 << 2) #define IGB_FLAG_QUEUE_PAIRS (1 << 3) +#define IGB_FLAG_DMAC (1 << 4) + +/* DMA Coalescing defines */ +#define IGB_MIN_TXPBSIZE 20408 +#define IGB_TX_BUF_4096 4096 +#define IGB_DMCTLX_DCFLUSH_DIS 0x80000000 /* Disable DMA Coal Flush */ #define IGB_82576_TSYNC_SHIFT 19 #define IGB_82580_TSYNC_SHIFT 24 diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index df15a915bbea..d976733bbcc2 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -2009,6 +2009,12 @@ static int igb_set_coalesce(struct net_device *netdev, if ((adapter->flags & IGB_FLAG_QUEUE_PAIRS) && ec->tx_coalesce_usecs) return -EINVAL; + /* If ITR is disabled, disable DMAC */ + if (ec->rx_coalesce_usecs == 0) { + if (adapter->flags & IGB_FLAG_DMAC) + adapter->flags &= ~IGB_FLAG_DMAC; + } + /* convert to rate of irq's per second */ if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) adapter->rx_itr_setting = ec->rx_coalesce_usecs; diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 8c6af11d93a6..49476f773825 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1674,7 +1674,58 @@ void igb_reset(struct igb_adapter *adapter) if (hw->mac.ops.init_hw(hw)) dev_err(&pdev->dev, "Hardware Error\n"); + if (hw->mac.type > e1000_82580) { + if (adapter->flags & IGB_FLAG_DMAC) { + u32 reg; + /* + * DMA Coalescing high water mark needs to be higher + * than * the * Rx threshold. The Rx threshold is + * currently * pba - 6, so we * should use a high water + * mark of pba * - 4. */ + hwm = (pba - 4) << 10; + + reg = (((pba-6) << E1000_DMACR_DMACTHR_SHIFT) + & E1000_DMACR_DMACTHR_MASK); + + /* transition to L0x or L1 if available..*/ + reg |= (E1000_DMACR_DMAC_EN | E1000_DMACR_DMAC_LX_MASK); + + /* watchdog timer= +-1000 usec in 32usec intervals */ + reg |= (1000 >> 5); + wr32(E1000_DMACR, reg); + + /* no lower threshold to disable coalescing(smart fifb) + * -UTRESH=0*/ + wr32(E1000_DMCRTRH, 0); + + /* set hwm to PBA - 2 * max frame size */ + wr32(E1000_FCRTC, hwm); + + /* + * This sets the time to wait before requesting tran- + * sition to * low power state to number of usecs needed + * to receive 1 512 * byte frame at gigabit line rate + */ + reg = rd32(E1000_DMCTLX); + reg |= IGB_DMCTLX_DCFLUSH_DIS; + + /* Delay 255 usec before entering Lx state. */ + reg |= 0xFF; + wr32(E1000_DMCTLX, reg); + + /* free space in Tx packet buffer to wake from DMAC */ + wr32(E1000_DMCTXTH, + (IGB_MIN_TXPBSIZE - + (IGB_TX_BUF_4096 + adapter->max_frame_size)) + >> 6); + + /* make low power state decision controlled by DMAC */ + reg = rd32(E1000_PCIEMISC); + reg |= E1000_PCIEMISC_LX_DECISION; + wr32(E1000_PCIEMISC, reg); + } /* end if IGB_FLAG_DMAC set */ + } if (hw->mac.type == e1000_82580) { u32 reg = rd32(E1000_PCIEMISC); wr32(E1000_PCIEMISC, @@ -2157,6 +2208,9 @@ static void __devinit igb_probe_vfs(struct igb_adapter * adapter) random_ether_addr(mac_addr); igb_set_vf_mac(adapter, i, mac_addr); } + /* DMA Coalescing is not supported in IOV mode. */ + if (adapter->flags & IGB_FLAG_DMAC) + adapter->flags &= ~IGB_FLAG_DMAC; } #endif /* CONFIG_PCI_IOV */ } @@ -2331,6 +2385,9 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter) /* Explicitly disable IRQ since the NIC can be in any state. */ igb_irq_disable(adapter); + if (hw->mac.type == e1000_i350) + adapter->flags &= ~IGB_FLAG_DMAC; + set_bit(__IGB_DOWN, &adapter->state); return 0; } -- cgit v1.2.3 From 0d1fe82deacdcc90458558b5d6a4a5af5db9a6c6 Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Fri, 11 Mar 2011 20:58:19 -0800 Subject: igb: Bump version to 3.0.6 This patch updates igb version to 3.0.6. Signed-off-by: Carolyn Wyborny Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/igb/igb_main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 49476f773825..b4f92b06f2ac 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -50,7 +50,12 @@ #endif #include "igb.h" -#define DRV_VERSION "2.4.13-k2" +#define MAJ 3 +#define MIN 0 +#define BUILD 6 +#define KFIX 2 +#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \ +__stringify(BUILD) "-k" __stringify(KFIX) char igb_driver_name[] = "igb"; char igb_driver_version[] = DRV_VERSION; static const char igb_driver_string[] = -- cgit v1.2.3 From 3032309b49622497430ecd2b40ff51fb204c35e8 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 1 Mar 2011 05:25:35 +0000 Subject: ixgbe: DCB, implement capabilities flags This implements dcbnl get and set capabilities ops. The devices supported by ixgbe can be configured to run in IEEE or CEE modes but not both. With the DCBX set capabilities bit we add an explicit signal that must be used to toggle between these modes. This patch adds logic to fail the CEE command set_hw_all() which programs the device with a CEE configuration if the CEE caps bit is not set. Similarly, IEEE set commands will fail if the IEEE caps bit is not set. We allow most CEE config set commands to occur because they do not touch the hardware until set_hw_all() is called. The one exception to the above is the {set|get}app routines. These must always be protected by caps bits to ensure side effects do not corrupt the current configured mode. By requiring the caps bit to be set correctly we can maintain a consistent configuration in the hardware for CEE or IEEE modes and prevent partial hardware configurations that may occur if user space does not send a complete IEEE or CEE configurations. It is expected that user space will signal a DCBX mode before programming device. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 1 + drivers/net/ixgbe/ixgbe_dcb_nl.c | 129 ++++++++++++++++++++++++++++----------- drivers/net/ixgbe/ixgbe_main.c | 1 + 3 files changed, 95 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 1e546fc127d0..815edfd7d0ee 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -341,6 +341,7 @@ struct ixgbe_adapter { struct ixgbe_dcb_config dcb_cfg; struct ixgbe_dcb_config temp_dcb_cfg; u8 dcb_set_bitmap; + u8 dcbx_cap; enum ixgbe_fc_mode last_lfc_mode; /* Interrupt Throttle Rate */ diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index d7f0024014b1..d7c456f685ff 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -346,7 +346,8 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) struct ixgbe_adapter *adapter = netdev_priv(netdev); int ret; - if (!adapter->dcb_set_bitmap) + if (!adapter->dcb_set_bitmap || + !(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) return DCB_NO_HW_CHG; ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg, @@ -448,40 +449,38 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) static u8 ixgbe_dcbnl_getcap(struct net_device *netdev, int capid, u8 *cap) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - u8 rval = 0; - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { - switch (capid) { - case DCB_CAP_ATTR_PG: - *cap = true; - break; - case DCB_CAP_ATTR_PFC: - *cap = true; - break; - case DCB_CAP_ATTR_UP2TC: - *cap = false; - break; - case DCB_CAP_ATTR_PG_TCS: - *cap = 0x80; - break; - case DCB_CAP_ATTR_PFC_TCS: - *cap = 0x80; - break; - case DCB_CAP_ATTR_GSP: - *cap = true; - break; - case DCB_CAP_ATTR_BCN: - *cap = false; - break; - default: - rval = -EINVAL; - break; - } - } else { - rval = -EINVAL; + switch (capid) { + case DCB_CAP_ATTR_PG: + *cap = true; + break; + case DCB_CAP_ATTR_PFC: + *cap = true; + break; + case DCB_CAP_ATTR_UP2TC: + *cap = false; + break; + case DCB_CAP_ATTR_PG_TCS: + *cap = 0x80; + break; + case DCB_CAP_ATTR_PFC_TCS: + *cap = 0x80; + break; + case DCB_CAP_ATTR_GSP: + *cap = true; + break; + case DCB_CAP_ATTR_BCN: + *cap = false; + break; + case DCB_CAP_ATTR_DCBX: + *cap = adapter->dcbx_cap; + break; + default: + *cap = false; + break; } - return rval; + return 0; } static u8 ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num) @@ -542,13 +541,17 @@ static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state) */ static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id) { + struct ixgbe_adapter *adapter = netdev_priv(netdev); u8 rval = 0; + if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) + return rval; + switch (idtype) { case DCB_APP_IDTYPE_ETHTYPE: #ifdef IXGBE_FCOE if (id == ETH_P_FCOE) - rval = ixgbe_fcoe_getapp(netdev_priv(netdev)); + rval = ixgbe_fcoe_getapp(adapter); #endif break; case DCB_APP_IDTYPE_PORTNUM: @@ -571,14 +574,17 @@ static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id) static u8 ixgbe_dcbnl_setapp(struct net_device *netdev, u8 idtype, u16 id, u8 up) { + struct ixgbe_adapter *adapter = netdev_priv(netdev); u8 rval = 1; + if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) + return rval; + switch (idtype) { case DCB_APP_IDTYPE_ETHTYPE: #ifdef IXGBE_FCOE if (id == ETH_P_FCOE) { u8 old_tc; - struct ixgbe_adapter *adapter = netdev_priv(netdev); /* Get current programmed tc */ old_tc = adapter->fcoe.tc; @@ -640,6 +646,9 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev, /* naively give each TC a bwg to map onto CEE hardware */ __u8 bwg_id[IEEE_8021QAZ_MAX_TCS] = {0, 1, 2, 3, 4, 5, 6, 7}; + if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) + return -EINVAL; + if (!adapter->ixgbe_ieee_ets) { adapter->ixgbe_ieee_ets = kmalloc(sizeof(struct ieee_ets), GFP_KERNEL); @@ -647,7 +656,6 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev, return -ENOMEM; } - memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets)); ixgbe_ieee_credits(ets->tc_tx_bw, refill, max, max_frame); @@ -686,6 +694,9 @@ static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev, struct ixgbe_adapter *adapter = netdev_priv(dev); int err; + if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) + return -EINVAL; + if (!adapter->ixgbe_ieee_pfc) { adapter->ixgbe_ieee_pfc = kmalloc(sizeof(struct ieee_pfc), GFP_KERNEL); @@ -698,6 +709,51 @@ static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev, return err; } +static u8 ixgbe_dcbnl_getdcbx(struct net_device *dev) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + return adapter->dcbx_cap; +} + +static u8 ixgbe_dcbnl_setdcbx(struct net_device *dev, u8 mode) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + struct ieee_ets ets = {0}; + struct ieee_pfc pfc = {0}; + + /* no support for LLD_MANAGED modes or CEE+IEEE */ + if ((mode & DCB_CAP_DCBX_LLD_MANAGED) || + ((mode & DCB_CAP_DCBX_VER_IEEE) && (mode & DCB_CAP_DCBX_VER_CEE)) || + !(mode & DCB_CAP_DCBX_HOST)) + return 1; + + if (mode == adapter->dcbx_cap) + return 0; + + adapter->dcbx_cap = mode; + + /* ETS and PFC defaults */ + ets.ets_cap = 8; + pfc.pfc_cap = 8; + + if (mode & DCB_CAP_DCBX_VER_IEEE) { + ixgbe_dcbnl_ieee_setets(dev, &ets); + ixgbe_dcbnl_ieee_setpfc(dev, &pfc); + } else if (mode & DCB_CAP_DCBX_VER_CEE) { + adapter->dcb_set_bitmap |= (BIT_PFC & BIT_PG_TX & BIT_PG_RX); + ixgbe_dcbnl_set_all(dev); + } else { + /* Drop into single TC mode strict priority as this + * indicates CEE and IEEE versions are disabled + */ + ixgbe_dcbnl_ieee_setets(dev, &ets); + ixgbe_dcbnl_ieee_setpfc(dev, &pfc); + ixgbe_dcbnl_set_state(dev, 0); + } + + return 0; +} + const struct dcbnl_rtnl_ops dcbnl_ops = { .ieee_getets = ixgbe_dcbnl_ieee_getets, .ieee_setets = ixgbe_dcbnl_ieee_setets, @@ -724,5 +780,6 @@ const struct dcbnl_rtnl_ops dcbnl_ops = { .setpfcstate = ixgbe_dcbnl_setpfcstate, .getapp = ixgbe_dcbnl_getapp, .setapp = ixgbe_dcbnl_setapp, + .getdcbx = ixgbe_dcbnl_getdcbx, + .setdcbx = ixgbe_dcbnl_setdcbx, }; - diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 5998dc94dd5c..4aeade82812a 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -5190,6 +5190,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->dcb_cfg.rx_pba_cfg = pba_equal; adapter->dcb_cfg.pfc_mode_enable = false; adapter->dcb_set_bitmap = 0x00; + adapter->dcbx_cap = DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_CEE; ixgbe_copy_dcb_cfg(&adapter->dcb_cfg, &adapter->temp_dcb_cfg, adapter->ring_feature[RING_F_DCB].indices); -- cgit v1.2.3 From f8628d404505e61bfc63638744656ede69227766 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Wed, 23 Feb 2011 05:57:47 +0000 Subject: ixgbe: DCB, implement ieee_setapp dcbnl ops Implement ieee_setapp dcbnl ops in ixgbe. This is required to setup FCoE which requires dedicated resources. If the app data is not for FCoE then no action is taken in ixgbe except to add it to the dcb_app_list. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb_nl.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index d7c456f685ff..8d139f7b393a 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -709,6 +709,35 @@ static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev, return err; } +static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev, + struct dcb_app *app) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + + if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) + return -EINVAL; +#ifdef IXGBE_FCOE + if (app->selector == 1 && app->protocol == ETH_P_FCOE) { + if (adapter->fcoe.tc == app->priority) + goto setapp; + + /* In IEEE mode map up to tc 1:1 */ + adapter->fcoe.tc = app->priority; + adapter->fcoe.up = app->priority; + + /* Force hardware reset required to push FCoE + * setup on {tx|rx}_rings + */ + adapter->dcb_set_bitmap |= BIT_APP_UPCHG; + ixgbe_dcbnl_set_all(dev); + } + +setapp: +#endif + dcb_setapp(dev, app); + return 0; +} + static u8 ixgbe_dcbnl_getdcbx(struct net_device *dev) { struct ixgbe_adapter *adapter = netdev_priv(dev); @@ -759,6 +788,7 @@ const struct dcbnl_rtnl_ops dcbnl_ops = { .ieee_setets = ixgbe_dcbnl_ieee_setets, .ieee_getpfc = ixgbe_dcbnl_ieee_getpfc, .ieee_setpfc = ixgbe_dcbnl_ieee_setpfc, + .ieee_setapp = ixgbe_dcbnl_ieee_setapp, .getstate = ixgbe_dcbnl_get_state, .setstate = ixgbe_dcbnl_set_state, .getpermhwaddr = ixgbe_dcbnl_get_perm_hw_addr, -- cgit v1.2.3 From dc166e22ede5ffb46b5b18b99ba0321ae545f89b Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Wed, 23 Feb 2011 05:57:52 +0000 Subject: ixgbe: DCB remove ixgbe_fcoe_getapp routine Remove ixgbe_fcoe_getapp() and use the generic kernel routine instead. Also add application priority to the kernel maintained list on setapp so applications and stacks can query the value. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb_nl.c | 28 +++++++++++++--------------- drivers/net/ixgbe/ixgbe_fcoe.c | 15 --------------- 2 files changed, 13 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index 8d139f7b393a..d4b2914376db 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -542,24 +542,15 @@ static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state) static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - u8 rval = 0; + struct dcb_app app = { + .selector = idtype, + .protocol = id, + }; if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) - return rval; + return 0; - switch (idtype) { - case DCB_APP_IDTYPE_ETHTYPE: -#ifdef IXGBE_FCOE - if (id == ETH_P_FCOE) - rval = ixgbe_fcoe_getapp(adapter); -#endif - break; - case DCB_APP_IDTYPE_PORTNUM: - break; - default: - break; - } - return rval; + return dcb_getapp(netdev, &app); } /** @@ -576,10 +567,17 @@ static u8 ixgbe_dcbnl_setapp(struct net_device *netdev, { struct ixgbe_adapter *adapter = netdev_priv(netdev); u8 rval = 1; + struct dcb_app app = { + .selector = idtype, + .protocol = id, + .priority = up + }; if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) return rval; + rval = dcb_setapp(netdev, &app); + switch (idtype) { case DCB_APP_IDTYPE_ETHTYPE: #ifdef IXGBE_FCOE diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 00af15a9cdc6..dba7d77588ef 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -812,21 +812,6 @@ out_disable: } #ifdef CONFIG_IXGBE_DCB -/** - * ixgbe_fcoe_getapp - retrieves current user priority bitmap for FCoE - * @adapter : ixgbe adapter - * - * Finds out the corresponding user priority bitmap from the current - * traffic class that FCoE belongs to. Returns 0 as the invalid user - * priority bitmap to indicate an error. - * - * Returns : 802.1p user priority bitmap for FCoE - */ -u8 ixgbe_fcoe_getapp(struct ixgbe_adapter *adapter) -{ - return 1 << adapter->fcoe.up; -} - /** * ixgbe_fcoe_setapp - sets the user priority bitmap for FCoE * @adapter : ixgbe adapter -- cgit v1.2.3 From e5b646355770d34eab360ebae93c56c407dfe803 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Tue, 8 Mar 2011 03:44:52 +0000 Subject: ixgbe: DCB, use multiple Tx rings per traffic class This enables multiple {Tx|Rx} rings per traffic class while in DCB mode. In order to get this working as expected the tc_to_tx net device mapping is configured as well as the prio_tc_map. skb priorities are mapped across a range of queue pairs to get a distribution per traffic class. The maximum number of queue pairs used while in DCB mode is capped at 64. The hardware max is actually 128 queues but 64 is sufficient for now and allocating more seemed a bit excessive. It is easy enough to increase the cap later if need be. To get the 802.1Q priority tags inserted correctly ixgbe was previously using the skb queue_mapping field to directly set the 802.1Q priority. This no longer works because we have removed the 1:1 mapping between queues and traffic class. Each ring is aligned with an 802.1Qaz traffic class so here we add an extra field to the ring struct to identify the 802.1Q traffic class. This uses an extra byte of the ixgbe_ring struct fortunately there was a 2byte hole, struct ixgbe_ring { void * desc; /* 0 8 */ struct device * dev; /* 8 8 */ struct net_device * netdev; /* 16 8 */ union { struct ixgbe_tx_buffer * tx_buffer_info; /* 8 */ struct ixgbe_rx_buffer * rx_buffer_info; /* 8 */ }; /* 24 8 */ long unsigned int state; /* 32 8 */ u8 atr_sample_rate; /* 40 1 */ u8 atr_count; /* 41 1 */ u16 count; /* 42 2 */ u16 rx_buf_len; /* 44 2 */ u16 next_to_use; /* 46 2 */ u16 next_to_clean; /* 48 2 */ u8 queue_index; /* 50 1 */ u8 reg_idx; /* 51 1 */ u16 work_limit; /* 52 2 */ /* XXX 2 bytes hole, try to pack */ u8 * tail; /* 56 8 */ /* --- cacheline 1 boundary (64 bytes) --- */ Now we can set the VLAN priority directly and it will be correct. User space can indicate the 802.1Qaz priority using the SO_PRIORITY setsocket() option and QOS layer will steer the skb to the correct rings. Additionally using the multiq qdisc with a queue_mapping action works as well. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 4 +- drivers/net/ixgbe/ixgbe_dcb_nl.c | 7 +- drivers/net/ixgbe/ixgbe_main.c | 339 ++++++++++++++++++++------------------- 3 files changed, 182 insertions(+), 168 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 815edfd7d0ee..b7e62d568b85 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -209,6 +209,7 @@ struct ixgbe_ring { * associated with this ring, which is * different for DCB and RSS modes */ + u8 dcb_tc; u16 work_limit; /* max work per interrupt */ @@ -243,7 +244,7 @@ enum ixgbe_ring_f_enum { RING_F_ARRAY_SIZE /* must be last in enum set */ }; -#define IXGBE_MAX_DCB_INDICES 8 +#define IXGBE_MAX_DCB_INDICES 64 #define IXGBE_MAX_RSS_INDICES 16 #define IXGBE_MAX_VMDQ_INDICES 64 #define IXGBE_MAX_FDIR_INDICES 64 @@ -542,6 +543,7 @@ extern void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, extern void ixgbe_clear_rscctl(struct ixgbe_adapter *adapter, struct ixgbe_ring *ring); extern void ixgbe_set_rx_mode(struct net_device *netdev); +extern int ixgbe_setup_tc(struct net_device *dev, u8 tc); #ifdef IXGBE_FCOE extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter); extern int ixgbe_fso(struct ixgbe_adapter *adapter, diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index d4b2914376db..b7b6db3bbd59 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -145,6 +145,9 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) } adapter->flags |= IXGBE_FLAG_DCB_ENABLED; + if (!netdev_get_num_tc(netdev)) + ixgbe_setup_tc(netdev, MAX_TRAFFIC_CLASS); + ixgbe_init_interrupt_scheme(adapter); if (netif_running(netdev)) netdev->netdev_ops->ndo_open(netdev); @@ -169,6 +172,8 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) break; } + ixgbe_setup_tc(netdev, 0); + ixgbe_init_interrupt_scheme(adapter); if (netif_running(netdev)) netdev->netdev_ops->ndo_open(netdev); @@ -351,7 +356,7 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) return DCB_NO_HW_CHG; ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg, - adapter->ring_feature[RING_F_DCB].indices); + MAX_TRAFFIC_CLASS); if (ret) return DCB_NO_HW_CHG; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 4aeade82812a..3694226462da 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -652,7 +652,7 @@ void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *tx_ring, static u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 reg_idx) { int tc = -1; - int dcb_i = adapter->ring_feature[RING_F_DCB].indices; + int dcb_i = netdev_get_num_tc(adapter->netdev); /* if DCB is not enabled the queues have no TC */ if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) @@ -4258,24 +4258,6 @@ static void ixgbe_reset_task(struct work_struct *work) ixgbe_reinit_locked(adapter); } -#ifdef CONFIG_IXGBE_DCB -static inline bool ixgbe_set_dcb_queues(struct ixgbe_adapter *adapter) -{ - bool ret = false; - struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_DCB]; - - if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) - return ret; - - f->mask = 0x7 << 3; - adapter->num_rx_queues = f->indices; - adapter->num_tx_queues = f->indices; - ret = true; - - return ret; -} -#endif - /** * ixgbe_set_rss_queues: Allocate queues for RSS * @adapter: board private structure to initialize @@ -4346,19 +4328,26 @@ static inline bool ixgbe_set_fdir_queues(struct ixgbe_adapter *adapter) **/ static inline bool ixgbe_set_fcoe_queues(struct ixgbe_adapter *adapter) { - bool ret = false; struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE]; - f->indices = min((int)num_online_cpus(), f->indices); - if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { - adapter->num_rx_queues = 1; - adapter->num_tx_queues = 1; + if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) + return false; + + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { #ifdef CONFIG_IXGBE_DCB - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { - e_info(probe, "FCoE enabled with DCB\n"); - ixgbe_set_dcb_queues(adapter); - } + int tc; + struct net_device *dev = adapter->netdev; + + tc = netdev_get_prio_tc_map(dev, adapter->fcoe.up); + f->indices = dev->tc_to_txq[tc].count; + f->mask = dev->tc_to_txq[tc].offset; #endif + } else { + f->indices = min((int)num_online_cpus(), f->indices); + + adapter->num_rx_queues = 1; + adapter->num_tx_queues = 1; + if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { e_info(probe, "FCoE enabled with RSS\n"); if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || @@ -4371,14 +4360,45 @@ static inline bool ixgbe_set_fcoe_queues(struct ixgbe_adapter *adapter) f->mask = adapter->num_rx_queues; adapter->num_rx_queues += f->indices; adapter->num_tx_queues += f->indices; + } - ret = true; + return true; +} +#endif /* IXGBE_FCOE */ + +#ifdef CONFIG_IXGBE_DCB +static inline bool ixgbe_set_dcb_queues(struct ixgbe_adapter *adapter) +{ + bool ret = false; + struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_DCB]; + int i, q; + + if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) + return ret; + + f->indices = 0; + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { + q = min((int)num_online_cpus(), MAX_TRAFFIC_CLASS); + f->indices += q; } + f->mask = 0x7 << 3; + adapter->num_rx_queues = f->indices; + adapter->num_tx_queues = f->indices; + ret = true; + +#ifdef IXGBE_FCOE + /* FCoE enabled queues require special configuration done through + * configure_fcoe() and others. Here we map FCoE indices onto the + * DCB queue pairs allowing FCoE to own configuration later. + */ + ixgbe_set_fcoe_queues(adapter); +#endif + return ret; } +#endif -#endif /* IXGBE_FCOE */ /** * ixgbe_set_sriov_queues: Allocate queues for IOV use * @adapter: board private structure to initialize @@ -4414,16 +4434,16 @@ static int ixgbe_set_num_queues(struct ixgbe_adapter *adapter) if (ixgbe_set_sriov_queues(adapter)) goto done; -#ifdef IXGBE_FCOE - if (ixgbe_set_fcoe_queues(adapter)) - goto done; - -#endif /* IXGBE_FCOE */ #ifdef CONFIG_IXGBE_DCB if (ixgbe_set_dcb_queues(adapter)) goto done; #endif +#ifdef IXGBE_FCOE + if (ixgbe_set_fcoe_queues(adapter)) + goto done; + +#endif /* IXGBE_FCOE */ if (ixgbe_set_fdir_queues(adapter)) goto done; @@ -4515,6 +4535,91 @@ static inline bool ixgbe_cache_ring_rss(struct ixgbe_adapter *adapter) } #ifdef CONFIG_IXGBE_DCB + +/* ixgbe_get_first_reg_idx - Return first register index associated with ring */ +void ixgbe_get_first_reg_idx(struct ixgbe_adapter *adapter, u8 tc, + unsigned int *tx, unsigned int *rx) +{ + struct net_device *dev = adapter->netdev; + struct ixgbe_hw *hw = &adapter->hw; + u8 num_tcs = netdev_get_num_tc(dev); + + *tx = 0; + *rx = 0; + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + *tx = tc << 3; + *rx = tc << 2; + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + if (num_tcs == 8) { + if (tc < 3) { + *tx = tc << 5; + *rx = tc << 4; + } else if (tc < 5) { + *tx = ((tc + 2) << 4); + *rx = tc << 4; + } else if (tc < num_tcs) { + *tx = ((tc + 8) << 3); + *rx = tc << 4; + } + } else if (num_tcs == 4) { + *rx = tc << 5; + switch (tc) { + case 0: + *tx = 0; + break; + case 1: + *tx = 64; + break; + case 2: + *tx = 96; + break; + case 3: + *tx = 112; + break; + default: + break; + } + } + break; + default: + break; + } +} + +#define IXGBE_MAX_Q_PER_TC (IXGBE_MAX_DCB_INDICES / MAX_TRAFFIC_CLASS) + +/* ixgbe_setup_tc - routine to configure net_device for multiple traffic + * classes. + * + * @netdev: net device to configure + * @tc: number of traffic classes to enable + */ +int ixgbe_setup_tc(struct net_device *dev, u8 tc) +{ + int i; + unsigned int q, offset = 0; + + if (!tc) { + netdev_reset_tc(dev); + } else { + if (netdev_set_num_tc(dev, tc)) + return -EINVAL; + + /* Partition Tx queues evenly amongst traffic classes */ + for (i = 0; i < tc; i++) { + q = min((int)num_online_cpus(), IXGBE_MAX_Q_PER_TC); + netdev_set_prio_tc_map(dev, i, i); + netdev_set_tc_queue(dev, i, q, offset); + offset += q; + } + } + return 0; +} + /** * ixgbe_cache_ring_dcb - Descriptor ring to register mapping for DCB * @adapter: board private structure to initialize @@ -4524,72 +4629,27 @@ static inline bool ixgbe_cache_ring_rss(struct ixgbe_adapter *adapter) **/ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter) { - int i; - bool ret = false; - int dcb_i = adapter->ring_feature[RING_F_DCB].indices; + struct net_device *dev = adapter->netdev; + int i, j, k; + u8 num_tcs = netdev_get_num_tc(dev); if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) return false; - /* the number of queues is assumed to be symmetric */ - switch (adapter->hw.mac.type) { - case ixgbe_mac_82598EB: - for (i = 0; i < dcb_i; i++) { - adapter->rx_ring[i]->reg_idx = i << 3; - adapter->tx_ring[i]->reg_idx = i << 2; - } - ret = true; - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: - if (dcb_i == 8) { - /* - * Tx TC0 starts at: descriptor queue 0 - * Tx TC1 starts at: descriptor queue 32 - * Tx TC2 starts at: descriptor queue 64 - * Tx TC3 starts at: descriptor queue 80 - * Tx TC4 starts at: descriptor queue 96 - * Tx TC5 starts at: descriptor queue 104 - * Tx TC6 starts at: descriptor queue 112 - * Tx TC7 starts at: descriptor queue 120 - * - * Rx TC0-TC7 are offset by 16 queues each - */ - for (i = 0; i < 3; i++) { - adapter->tx_ring[i]->reg_idx = i << 5; - adapter->rx_ring[i]->reg_idx = i << 4; - } - for ( ; i < 5; i++) { - adapter->tx_ring[i]->reg_idx = ((i + 2) << 4); - adapter->rx_ring[i]->reg_idx = i << 4; - } - for ( ; i < dcb_i; i++) { - adapter->tx_ring[i]->reg_idx = ((i + 8) << 3); - adapter->rx_ring[i]->reg_idx = i << 4; - } - ret = true; - } else if (dcb_i == 4) { - /* - * Tx TC0 starts at: descriptor queue 0 - * Tx TC1 starts at: descriptor queue 64 - * Tx TC2 starts at: descriptor queue 96 - * Tx TC3 starts at: descriptor queue 112 - * - * Rx TC0-TC3 are offset by 32 queues each - */ - adapter->tx_ring[0]->reg_idx = 0; - adapter->tx_ring[1]->reg_idx = 64; - adapter->tx_ring[2]->reg_idx = 96; - adapter->tx_ring[3]->reg_idx = 112; - for (i = 0 ; i < dcb_i; i++) - adapter->rx_ring[i]->reg_idx = i << 5; - ret = true; + for (i = 0, k = 0; i < num_tcs; i++) { + unsigned int tx_s, rx_s; + u16 count = dev->tc_to_txq[i].count; + + ixgbe_get_first_reg_idx(adapter, i, &tx_s, &rx_s); + for (j = 0; j < count; j++, k++) { + adapter->tx_ring[k]->reg_idx = tx_s + j; + adapter->rx_ring[k]->reg_idx = rx_s + j; + adapter->tx_ring[k]->dcb_tc = i; + adapter->rx_ring[k]->dcb_tc = i; } - break; - default: - break; } - return ret; + + return true; } #endif @@ -4635,33 +4695,6 @@ static inline bool ixgbe_cache_ring_fcoe(struct ixgbe_adapter *adapter) if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) return false; -#ifdef CONFIG_IXGBE_DCB - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { - struct ixgbe_fcoe *fcoe = &adapter->fcoe; - - ixgbe_cache_ring_dcb(adapter); - /* find out queues in TC for FCoE */ - fcoe_rx_i = adapter->rx_ring[fcoe->tc]->reg_idx + 1; - fcoe_tx_i = adapter->tx_ring[fcoe->tc]->reg_idx + 1; - /* - * In 82599, the number of Tx queues for each traffic - * class for both 8-TC and 4-TC modes are: - * TCs : TC0 TC1 TC2 TC3 TC4 TC5 TC6 TC7 - * 8 TCs: 32 32 16 16 8 8 8 8 - * 4 TCs: 64 64 32 32 - * We have max 8 queues for FCoE, where 8 the is - * FCoE redirection table size. If TC for FCoE is - * less than or equal to TC3, we have enough queues - * to add max of 8 queues for FCoE, so we start FCoE - * Tx queue from the next one, i.e., reg_idx + 1. - * If TC for FCoE is above TC3, implying 8 TC mode, - * and we need 8 for FCoE, we have to take all queues - * in that traffic class for FCoE. - */ - if ((f->indices == IXGBE_FCRETA_SIZE) && (fcoe->tc > 3)) - fcoe_tx_i--; - } -#endif /* CONFIG_IXGBE_DCB */ if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) @@ -4718,16 +4751,16 @@ static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter) if (ixgbe_cache_ring_sriov(adapter)) return; +#ifdef CONFIG_IXGBE_DCB + if (ixgbe_cache_ring_dcb(adapter)) + return; +#endif + #ifdef IXGBE_FCOE if (ixgbe_cache_ring_fcoe(adapter)) return; - #endif /* IXGBE_FCOE */ -#ifdef CONFIG_IXGBE_DCB - if (ixgbe_cache_ring_dcb(adapter)) - return; -#endif if (ixgbe_cache_ring_fdir(adapter)) return; @@ -5192,7 +5225,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->dcb_set_bitmap = 0x00; adapter->dcbx_cap = DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_CEE; ixgbe_copy_dcb_cfg(&adapter->dcb_cfg, &adapter->temp_dcb_cfg, - adapter->ring_feature[RING_F_DCB].indices); + MAX_TRAFFIC_CLASS); #endif @@ -6664,18 +6697,12 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) protocol = vlan_get_protocol(skb); - if ((protocol == htons(ETH_P_FCOE)) || - (protocol == htons(ETH_P_FIP))) { - if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { - txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1); - txq += adapter->ring_feature[RING_F_FCOE].mask; - return txq; -#ifdef CONFIG_IXGBE_DCB - } else if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { - txq = adapter->fcoe.up; - return txq; -#endif - } + if (((protocol == htons(ETH_P_FCOE)) || + (protocol == htons(ETH_P_FIP))) && + (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) { + txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1); + txq += adapter->ring_feature[RING_F_FCOE].mask; + return txq; } #endif @@ -6685,15 +6712,6 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) return txq; } - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { - if (skb->priority == TC_PRIO_CONTROL) - txq = adapter->ring_feature[RING_F_DCB].indices-1; - else - txq = (skb->vlan_tci & IXGBE_TX_FLAGS_VLAN_PRIO_MASK) - >> 13; - return txq; - } - return skb_tx_hash(dev, skb); } @@ -6715,13 +6733,13 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, tx_flags |= vlan_tx_tag_get(skb); if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { tx_flags &= ~IXGBE_TX_FLAGS_VLAN_PRIO_MASK; - tx_flags |= ((skb->queue_mapping & 0x7) << 13); + tx_flags |= tx_ring->dcb_tc << 13; } tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT; tx_flags |= IXGBE_TX_FLAGS_VLAN; } else if (adapter->flags & IXGBE_FLAG_DCB_ENABLED && skb->priority != TC_PRIO_CONTROL) { - tx_flags |= ((skb->queue_mapping & 0x7) << 13); + tx_flags |= tx_ring->dcb_tc << 13; tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT; tx_flags |= IXGBE_TX_FLAGS_VLAN; } @@ -6730,20 +6748,8 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, /* for FCoE with DCB, we force the priority to what * was specified by the switch */ if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED && - (protocol == htons(ETH_P_FCOE) || - protocol == htons(ETH_P_FIP))) { -#ifdef CONFIG_IXGBE_DCB - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { - tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK - << IXGBE_TX_FLAGS_VLAN_SHIFT); - tx_flags |= ((adapter->fcoe.up << 13) - << IXGBE_TX_FLAGS_VLAN_SHIFT); - } -#endif - /* flag for FCoE offloads */ - if (protocol == htons(ETH_P_FCOE)) - tx_flags |= IXGBE_TX_FLAGS_FCOE; - } + (protocol == htons(ETH_P_FCOE))) + tx_flags |= IXGBE_TX_FLAGS_FCOE; #endif /* four things can cause us to need a context descriptor */ @@ -7157,8 +7163,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, else indices = min_t(unsigned int, indices, IXGBE_MAX_FDIR_INDICES); +#if defined(CONFIG_DCB) indices = max_t(unsigned int, indices, IXGBE_MAX_DCB_INDICES); -#ifdef IXGBE_FCOE +#elif defined(IXGBE_FCOE) indices += min_t(unsigned int, num_possible_cpus(), IXGBE_MAX_FCOE_INDICES); #endif -- cgit v1.2.3 From 24095aa347a32673cf220fc0bd0b78d28ba0a69e Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Wed, 23 Feb 2011 05:58:03 +0000 Subject: ixgbe: enable ndo_tc_setup This patch adds the ndo_tc_setup to ixgbe. By default we set the device to use strict priority. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 3694226462da..3ce0f4f956df 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -4606,7 +4606,10 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc) if (!tc) { netdev_reset_tc(dev); } else { - if (netdev_set_num_tc(dev, tc)) + struct ixgbe_adapter *adapter = netdev_priv(dev); + + /* Hardware supports up to 8 traffic classes */ + if (tc > MAX_TRAFFIC_CLASS || netdev_set_num_tc(dev, tc)) return -EINVAL; /* Partition Tx queues evenly amongst traffic classes */ @@ -4616,6 +4619,22 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc) netdev_set_tc_queue(dev, i, q, offset); offset += q; } + + /* This enables multiple traffic class support in the hardware + * which defaults to strict priority transmission by default. + * If traffic classes are already enabled perhaps through DCB + * code path then existing configuration will be used. + */ + if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED) && + dev->dcbnl_ops && dev->dcbnl_ops->setdcbx) { + struct ieee_ets ets = { + .prio_tc = {0, 1, 2, 3, 4, 5, 6, 7}, + }; + u8 mode = DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_IEEE; + + dev->dcbnl_ops->setdcbx(dev, mode); + dev->dcbnl_ops->ieee_setets(dev, &ets); + } } return 0; } @@ -7022,6 +7041,9 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_set_vf_tx_rate = ixgbe_ndo_set_vf_bw, .ndo_get_vf_config = ixgbe_ndo_get_vf_config, .ndo_get_stats64 = ixgbe_get_stats64, +#ifdef CONFIG_IXGBE_DCB + .ndo_setup_tc = ixgbe_setup_tc, +#endif #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ixgbe_netpoll, #endif -- cgit v1.2.3 From 8187cd485b1a74b6ae258786b9ade3ecaafec318 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Wed, 23 Feb 2011 05:58:08 +0000 Subject: ixgbe: DCB: enable RSS to be used with DCB RSS had previously been disabled when DCB was enabled because DCB was single queued per traffic class. Now that DCB implements multiple Tx/Rx rings per traffic class enable RSS. Here RSS hashes across the queues in the traffic class. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb_nl.c | 2 -- drivers/net/ixgbe/ixgbe_main.c | 32 +++++++++++++++++++++++++------- 2 files changed, 25 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index b7b6db3bbd59..91ff51c53b04 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -129,7 +129,6 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) netdev->netdev_ops->ndo_stop(netdev); ixgbe_clear_interrupt_scheme(adapter); - adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED; switch (adapter->hw.mac.type) { case ixgbe_mac_82598EB: adapter->last_lfc_mode = adapter->hw.fc.current_mode; @@ -162,7 +161,6 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) adapter->temp_dcb_cfg.pfc_mode_enable = false; adapter->dcb_cfg.pfc_mode_enable = false; adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; - adapter->flags |= IXGBE_FLAG_RSS_ENABLED; switch (adapter->hw.mac.type) { case ixgbe_mac_82599EB: case ixgbe_mac_X540: diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 3ce0f4f956df..be2e145646bf 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2892,17 +2892,20 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) ); switch (mask) { +#ifdef CONFIG_IXGBE_DCB + case (IXGBE_FLAG_DCB_ENABLED | IXGBE_FLAG_RSS_ENABLED): + mrqc = IXGBE_MRQC_RTRSS8TCEN; + break; + case (IXGBE_FLAG_DCB_ENABLED): + mrqc = IXGBE_MRQC_RT8TCEN; + break; +#endif /* CONFIG_IXGBE_DCB */ case (IXGBE_FLAG_RSS_ENABLED): mrqc = IXGBE_MRQC_RSSEN; break; case (IXGBE_FLAG_SRIOV_ENABLED): mrqc = IXGBE_MRQC_VMDQEN; break; -#ifdef CONFIG_IXGBE_DCB - case (IXGBE_FLAG_DCB_ENABLED): - mrqc = IXGBE_MRQC_RT8TCEN; - break; -#endif /* CONFIG_IXGBE_DCB */ default: break; } @@ -3672,6 +3675,23 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) /* reconfigure the hardware */ ixgbe_dcb_hw_config(hw, &adapter->dcb_cfg); + + /* Enable RSS Hash per TC */ + if (hw->mac.type != ixgbe_mac_82598EB) { + int i; + u32 reg = 0; + + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { + u8 msb = 0; + u8 cnt = adapter->netdev->tc_to_txq[i].count; + + while (cnt >>= 1) + msb++; + + reg |= msb << IXGBE_RQTC_SHIFT_TC(i); + } + IXGBE_WRITE_REG(hw, IXGBE_RQTC, reg); + } } #endif @@ -7343,8 +7363,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) adapter->flags &= ~(IXGBE_FLAG_RSS_ENABLED | IXGBE_FLAG_DCB_ENABLED); - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) - adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED; #ifdef CONFIG_IXGBE_DCB netdev->dcbnl_ops = &dcbnl_ops; -- cgit v1.2.3 From 3b97fd695453ced96f22bdf1a84453f6744d25cc Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Wed, 23 Feb 2011 05:58:14 +0000 Subject: ixgbe: DCB, missed translation from 8021Qaz TSA to CEE link strict The patch below allowed IEEE 802.1Qaz and CEE DCB hardware configurations to use common hardware set routines, commit 88eb696cc6a7af8f9272266965b1a4dd7d6a931b Author: John Fastabend Date: Thu Feb 10 03:02:11 2011 -0800 ixgbe: DCB, abstract out dcb_config from DCB hardware configuration However the case when CEE link strict and group strict are set was missed and are currently being mapped incorrectly in some configurations. This patch resolves this. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb.c | 24 +----------------------- drivers/net/ixgbe/ixgbe_dcb_nl.c | 24 ++++++++++++++++++++++-- 2 files changed, 23 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c index c2ee6fcb4e91..e2e7a292525d 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.c +++ b/drivers/net/ixgbe/ixgbe_dcb.c @@ -292,30 +292,8 @@ s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en) } s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw, - u16 *refill, u16 *max, u8 *bwg_id, u8 *tsa) + u16 *refill, u16 *max, u8 *bwg_id, u8 *prio_type) { - int i; - u8 prio_type[IEEE_8021QAZ_MAX_TCS]; - - /* Map TSA onto CEE prio type */ - for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { - switch (tsa[i]) { - case IEEE_8021QAZ_TSA_STRICT: - prio_type[i] = 2; - break; - case IEEE_8021QAZ_TSA_ETS: - prio_type[i] = 0; - break; - default: - /* Hardware only supports priority strict or - * ETS transmission selection algorithms if - * we receive some other value from dcbnl - * throw an error - */ - return -EINVAL; - } - } - switch (hw->mac.type) { case ixgbe_mac_82598EB: ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index 91ff51c53b04..8abef8d588fd 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -642,8 +642,9 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev, { struct ixgbe_adapter *adapter = netdev_priv(dev); __u16 refill[IEEE_8021QAZ_MAX_TCS], max[IEEE_8021QAZ_MAX_TCS]; + __u8 prio_type[IEEE_8021QAZ_MAX_TCS]; int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN; - int err; + int i, err; /* naively give each TC a bwg to map onto CEE hardware */ __u8 bwg_id[IEEE_8021QAZ_MAX_TCS] = {0, 1, 2, 3, 4, 5, 6, 7}; @@ -659,9 +660,28 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev, memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets)); + /* Map TSA onto CEE prio type */ + for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { + switch (ets->tc_tsa[i]) { + case IEEE_8021QAZ_TSA_STRICT: + prio_type[i] = 2; + break; + case IEEE_8021QAZ_TSA_ETS: + prio_type[i] = 0; + break; + default: + /* Hardware only supports priority strict or + * ETS transmission selection algorithms if + * we receive some other value from dcbnl + * throw an error + */ + return -EINVAL; + } + } + ixgbe_ieee_credits(ets->tc_tx_bw, refill, max, max_frame); err = ixgbe_dcb_hw_ets_config(&adapter->hw, refill, max, - bwg_id, ets->tc_tsa); + bwg_id, prio_type); return err; } -- cgit v1.2.3 From 17049d30c2dec6f26d6165cc135578f9e41d53d3 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Wed, 23 Feb 2011 05:58:19 +0000 Subject: ixgbe: IEEE 802.1Qaz, implement priority assignment table This patch adds support to use the priority assignment table in the ieee_ets structure to map priorities to traffic classes. Previously ixgbe only supported a 1:1 mapping. Now we can enable and disable hardware DCB support when multiple traffic classes are actually being used. This allows the default case all priorities mapped to traffic class 0 to work in normal hardware mode and utilize the full packet buffer. This patch does not address putting the hardware in 4TC mode so packet buffer space may be underutilized in this case. A follow up patch can address this optimization. But at least we have the hooks to do this now. Also CEE will behave as it always has and map priorities 1:1 with traffic classes. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb.c | 13 ++++++++----- drivers/net/ixgbe/ixgbe_dcb.h | 4 ++-- drivers/net/ixgbe/ixgbe_dcb_82599.c | 17 ++++++++++------- drivers/net/ixgbe/ixgbe_dcb_82599.h | 9 ++++++--- drivers/net/ixgbe/ixgbe_dcb_nl.c | 12 ++++++++++-- 5 files changed, 36 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c index e2e7a292525d..e7b551af573d 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.c +++ b/drivers/net/ixgbe/ixgbe_dcb.c @@ -246,6 +246,8 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, u8 bwgid[MAX_TRAFFIC_CLASS]; u16 refill[MAX_TRAFFIC_CLASS]; u16 max[MAX_TRAFFIC_CLASS]; + /* CEE does not define a priority to tc mapping so map 1:1 */ + u8 prio_tc[MAX_TRAFFIC_CLASS] = {0, 1, 2, 3, 4, 5, 6, 7}; /* Unpack CEE standard containers */ ixgbe_dcb_unpack_pfc(dcb_config, &pfc_en); @@ -264,7 +266,7 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, case ixgbe_mac_X540: ret = ixgbe_dcb_hw_config_82599(hw, dcb_config->rx_pba_cfg, pfc_en, refill, max, bwgid, - ptype); + ptype, prio_tc); break; default: break; @@ -292,7 +294,8 @@ s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en) } s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw, - u16 *refill, u16 *max, u8 *bwg_id, u8 *prio_type) + u16 *refill, u16 *max, u8 *bwg_id, + u8 *prio_type, u8 *prio_tc) { switch (hw->mac.type) { case ixgbe_mac_82598EB: @@ -306,11 +309,11 @@ s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw, case ixgbe_mac_82599EB: case ixgbe_mac_X540: ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, - bwg_id, prio_type); + bwg_id, prio_type, prio_tc); ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, bwg_id, prio_type); - ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, - bwg_id, prio_type); + ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, bwg_id, + prio_type, prio_tc); break; default: break; diff --git a/drivers/net/ixgbe/ixgbe_dcb.h b/drivers/net/ixgbe/ixgbe_dcb.h index 515bc27477f6..944838fc7b59 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.h +++ b/drivers/net/ixgbe/ixgbe_dcb.h @@ -159,8 +159,8 @@ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *, struct ixgbe_dcb_config *, int, u8); /* DCB hw initialization */ -s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw, - u16 *refill, u16 *max, u8 *bwg_id, u8 *prio_type); +s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw, u16 *refill, u16 *max, + u8 *bwg_id, u8 *prio_type, u8 *tc_prio); s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en); s32 ixgbe_dcb_hw_config(struct ixgbe_hw *, struct ixgbe_dcb_config *); diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c index beaa1c1c1e67..0a482bbf1bd2 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c @@ -85,7 +85,8 @@ s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, u16 *refill, u16 *max, u8 *bwg_id, - u8 *prio_type) + u8 *prio_type, + u8 *prio_tc) { u32 reg = 0; u32 credit_refill = 0; @@ -102,7 +103,7 @@ s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, /* Map all traffic classes to their UP, 1 to 1 */ reg = 0; for (i = 0; i < MAX_TRAFFIC_CLASS; i++) - reg |= (i << (i * IXGBE_RTRUP2TC_UP_SHIFT)); + reg |= (prio_tc[i] << (i * IXGBE_RTRUP2TC_UP_SHIFT)); IXGBE_WRITE_REG(hw, IXGBE_RTRUP2TC, reg); /* Configure traffic class credits and priority */ @@ -194,7 +195,8 @@ s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, u16 *refill, u16 *max, u8 *bwg_id, - u8 *prio_type) + u8 *prio_type, + u8 *prio_tc) { u32 reg; u8 i; @@ -211,7 +213,7 @@ s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, /* Map all traffic classes to their UP, 1 to 1 */ reg = 0; for (i = 0; i < MAX_TRAFFIC_CLASS; i++) - reg |= (i << (i * IXGBE_RTTUP2TC_UP_SHIFT)); + reg |= (prio_tc[i] << (i * IXGBE_RTTUP2TC_UP_SHIFT)); IXGBE_WRITE_REG(hw, IXGBE_RTTUP2TC, reg); /* Configure traffic class credits and priority */ @@ -424,15 +426,16 @@ static s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw) */ s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw, u8 rx_pba, u8 pfc_en, u16 *refill, - u16 *max, u8 *bwg_id, u8 *prio_type) + u16 *max, u8 *bwg_id, u8 *prio_type, u8 *prio_tc) { ixgbe_dcb_config_packet_buffers_82599(hw, rx_pba); ixgbe_dcb_config_82599(hw); - ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id, prio_type); + ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id, + prio_type, prio_tc); ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, bwg_id, prio_type); ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max, - bwg_id, prio_type); + bwg_id, prio_type, prio_tc); ixgbe_dcb_config_pfc_82599(hw, pfc_en); ixgbe_dcb_config_tc_stats_82599(hw); diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.h b/drivers/net/ixgbe/ixgbe_dcb_82599.h index 0b39ab4ffc70..148fd8b477a9 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.h +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.h @@ -109,7 +109,8 @@ s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, u16 *refill, u16 *max, u8 *bwg_id, - u8 *prio_type); + u8 *prio_type, + u8 *prio_tc); s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, u16 *refill, @@ -121,10 +122,12 @@ s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, u16 *refill, u16 *max, u8 *bwg_id, - u8 *prio_type); + u8 *prio_type, + u8 *prio_tc); s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw, u8 rx_pba, u8 pfc_en, u16 *refill, - u16 *max, u8 *bwg_id, u8 *prio_type); + u16 *max, u8 *bwg_id, u8 *prio_type, + u8 *prio_tc); #endif /* _DCB_82599_CONFIG_H */ diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index 8abef8d588fd..fec4c724c37a 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -416,6 +416,8 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) if (adapter->dcb_set_bitmap & (BIT_PG_TX|BIT_PG_RX)) { u16 refill[MAX_TRAFFIC_CLASS], max[MAX_TRAFFIC_CLASS]; u8 bwg_id[MAX_TRAFFIC_CLASS], prio_type[MAX_TRAFFIC_CLASS]; + /* Priority to TC mapping in CEE case default to 1:1 */ + u8 prio_tc[MAX_TRAFFIC_CLASS] = {0, 1, 2, 3, 4, 5, 6, 7}; int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN; #ifdef CONFIG_FCOE @@ -437,7 +439,7 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) DCB_TX_CONFIG, prio_type); ixgbe_dcb_hw_ets_config(&adapter->hw, refill, max, - bwg_id, prio_type); + bwg_id, prio_type, prio_tc); } if (adapter->dcb_cfg.pfc_mode_enable) @@ -645,6 +647,7 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev, __u8 prio_type[IEEE_8021QAZ_MAX_TCS]; int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN; int i, err; + __u64 *p = (__u64 *) ets->prio_tc; /* naively give each TC a bwg to map onto CEE hardware */ __u8 bwg_id[IEEE_8021QAZ_MAX_TCS] = {0, 1, 2, 3, 4, 5, 6, 7}; @@ -679,9 +682,14 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev, } } + if (*p) + ixgbe_dcbnl_set_state(dev, 1); + else + ixgbe_dcbnl_set_state(dev, 0); + ixgbe_ieee_credits(ets->tc_tx_bw, refill, max, max_frame); err = ixgbe_dcb_hw_ets_config(&adapter->hw, refill, max, - bwg_id, prio_type); + bwg_id, prio_type, ets->prio_tc); return err; } -- cgit v1.2.3 From c27931da83bc486e192c8dfdab903ba51e176c54 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Wed, 23 Feb 2011 05:58:25 +0000 Subject: ixgbe: DCB during ifup use correct CEE or IEEE mode DCB settings are cleared in the hardware across link events during ifup ixgbe reprograms the hardware for DCB if it is enabled. Now that we have two modes CEE or IEEE we need to use the correct set of configuration data. This patch checks the dcbx_cap bits and then enables the device in the correct mode. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_main.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index be2e145646bf..38f9758c4c44 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3658,15 +3658,6 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) if (hw->mac.type == ixgbe_mac_82598EB) netif_set_gso_max_size(adapter->netdev, 32768); -#ifdef CONFIG_FCOE - if (adapter->netdev->features & NETIF_F_FCOE_MTU) - max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE); -#endif - - ixgbe_dcb_calculate_tc_credits(hw, &adapter->dcb_cfg, max_frame, - DCB_TX_CONFIG); - ixgbe_dcb_calculate_tc_credits(hw, &adapter->dcb_cfg, max_frame, - DCB_RX_CONFIG); /* Enable VLAN tag insert/strip */ adapter->netdev->features |= NETIF_F_HW_VLAN_RX; @@ -3674,7 +3665,26 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true); /* reconfigure the hardware */ - ixgbe_dcb_hw_config(hw, &adapter->dcb_cfg); + if (adapter->dcbx_cap & (DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_CEE)) { +#ifdef CONFIG_FCOE + if (adapter->netdev->features & NETIF_F_FCOE_MTU) + max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE); +#endif + ixgbe_dcb_calculate_tc_credits(hw, &adapter->dcb_cfg, max_frame, + DCB_TX_CONFIG); + ixgbe_dcb_calculate_tc_credits(hw, &adapter->dcb_cfg, max_frame, + DCB_RX_CONFIG); + ixgbe_dcb_hw_config(hw, &adapter->dcb_cfg); + } else { + struct net_device *dev = adapter->netdev; + + if (adapter->ixgbe_ieee_ets) + dev->dcbnl_ops->ieee_setets(dev, + adapter->ixgbe_ieee_ets); + if (adapter->ixgbe_ieee_pfc) + dev->dcbnl_ops->ieee_setpfc(dev, + adapter->ixgbe_ieee_pfc); + } /* Enable RSS Hash per TC */ if (hw->mac.type != ixgbe_mac_82598EB) { -- cgit v1.2.3 From 7e7eb4346329da3b9fd4b8d4a5a66d327d9fff6c Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Fri, 4 Mar 2011 03:20:59 +0000 Subject: ixgbe: remove timer reset to 0 on timeout The VF mailbox polling for acks and messages would reset the timer to zero on a timeout. Under heavy load a timeout may actually occur without being the result of an error and when this occurs it is not practical to perform a full VF driver reset on every message timeout. Instead, just return an error (which is already done) and the VF driver will have an opportunity to retry the operation. Signed-off-by: Emil Tantilov Acked-by: Greg Rose Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_mbx.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_mbx.c b/drivers/net/ixgbe/ixgbe_mbx.c index c7ed82eb2539..1ff0eefcfd0a 100644 --- a/drivers/net/ixgbe/ixgbe_mbx.c +++ b/drivers/net/ixgbe/ixgbe_mbx.c @@ -154,9 +154,6 @@ static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id) udelay(mbx->usec_delay); } - /* if we failed, all future posted messages fail until reset */ - if (!countdown) - mbx->timeout = 0; out: return countdown ? 0 : IXGBE_ERR_MBX; } @@ -183,9 +180,6 @@ static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id) udelay(mbx->usec_delay); } - /* if we failed, all future posted messages fail until reset */ - if (!countdown) - mbx->timeout = 0; out: return countdown ? 0 : IXGBE_ERR_MBX; } -- cgit v1.2.3 From 9dda173667207fe59d380e522d318c144dc032f7 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 5 Mar 2011 01:28:07 +0000 Subject: ixgbe: update PHY code to support 100Mbps as well as 1G/10G This change updates the PHY setup code to support 100Mbps capable PHYs as well as 10G and 1Gbps. Signed-off-by: Emil Tantilov Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_82598.c | 1 + drivers/net/ixgbe/ixgbe_phy.c | 335 ++++++++++++++++++++++++++++------------ drivers/net/ixgbe/ixgbe_phy.h | 1 + drivers/net/ixgbe/ixgbe_type.h | 7 + 4 files changed, 245 insertions(+), 99 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index ff23907bde0c..845c679c8b87 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -158,6 +158,7 @@ static s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw) switch (hw->phy.type) { case ixgbe_phy_tn: + phy->ops.setup_link = &ixgbe_setup_phy_link_tnx; phy->ops.check_link = &ixgbe_check_phy_link_tnx; phy->ops.get_firmware_version = &ixgbe_get_phy_firmware_version_tnx; diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index 9190a8fca427..f72f705f6183 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -402,49 +402,89 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, **/ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw) { - s32 status = IXGBE_NOT_IMPLEMENTED; + s32 status = 0; u32 time_out; u32 max_time_out = 10; - u16 autoneg_reg; + u16 autoneg_reg = IXGBE_MII_AUTONEG_REG; + bool autoneg = false; + ixgbe_link_speed speed; - /* - * Set advertisement settings in PHY based on autoneg_advertised - * settings. If autoneg_advertised = 0, then advertise default values - * tnx devices cannot be "forced" to a autoneg 10G and fail. But can - * for a 1G. - */ - hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, &autoneg_reg); + ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg); + + if (speed & IXGBE_LINK_SPEED_10GB_FULL) { + /* Set or unset auto-negotiation 10G advertisement */ + hw->phy.ops.read_reg(hw, MDIO_AN_10GBT_CTRL, + MDIO_MMD_AN, + &autoneg_reg); - if (hw->phy.autoneg_advertised == IXGBE_LINK_SPEED_1GB_FULL) autoneg_reg &= ~MDIO_AN_10GBT_CTRL_ADV10G; - else - autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) + autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G; - hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, autoneg_reg); + hw->phy.ops.write_reg(hw, MDIO_AN_10GBT_CTRL, + MDIO_MMD_AN, + autoneg_reg); + } + + if (speed & IXGBE_LINK_SPEED_1GB_FULL) { + /* Set or unset auto-negotiation 1G advertisement */ + hw->phy.ops.read_reg(hw, + IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, + MDIO_MMD_AN, + &autoneg_reg); + + autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) + autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE; + + hw->phy.ops.write_reg(hw, + IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG, + MDIO_MMD_AN, + autoneg_reg); + } + + if (speed & IXGBE_LINK_SPEED_100_FULL) { + /* Set or unset auto-negotiation 100M advertisement */ + hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE, + MDIO_MMD_AN, + &autoneg_reg); + + autoneg_reg &= ~ADVERTISE_100FULL; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) + autoneg_reg |= ADVERTISE_100FULL; + + hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, + MDIO_MMD_AN, + autoneg_reg); + } /* Restart PHY autonegotiation and wait for completion */ - hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_AN, &autoneg_reg); + hw->phy.ops.read_reg(hw, MDIO_CTRL1, + MDIO_MMD_AN, &autoneg_reg); autoneg_reg |= MDIO_AN_CTRL1_RESTART; - hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_AN, autoneg_reg); + hw->phy.ops.write_reg(hw, MDIO_CTRL1, + MDIO_MMD_AN, autoneg_reg); /* Wait for autonegotiation to finish */ for (time_out = 0; time_out < max_time_out; time_out++) { udelay(10); /* Restart PHY autonegotiation and wait for completion */ - status = hw->phy.ops.read_reg(hw, MDIO_STAT1, MDIO_MMD_AN, - &autoneg_reg); + status = hw->phy.ops.read_reg(hw, MDIO_STAT1, + MDIO_MMD_AN, + &autoneg_reg); autoneg_reg &= MDIO_AN_STAT1_COMPLETE; if (autoneg_reg == MDIO_AN_STAT1_COMPLETE) { - status = 0; break; } } - if (time_out == max_time_out) + if (time_out == max_time_out) { status = IXGBE_ERR_LINK_SETUP; + hw_dbg(hw, "ixgbe_setup_phy_link_generic: time out"); + } return status; } @@ -473,6 +513,9 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, if (speed & IXGBE_LINK_SPEED_1GB_FULL) hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL; + if (speed & IXGBE_LINK_SPEED_100_FULL) + hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL; + /* Setup link based on the new speed settings */ hw->phy.ops.setup_link(hw); @@ -512,6 +555,180 @@ s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw, return status; } +/** + * ixgbe_check_phy_link_tnx - Determine link and speed status + * @hw: pointer to hardware structure + * + * Reads the VS1 register to determine if link is up and the current speed for + * the PHY. + **/ +s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed, + bool *link_up) +{ + s32 status = 0; + u32 time_out; + u32 max_time_out = 10; + u16 phy_link = 0; + u16 phy_speed = 0; + u16 phy_data = 0; + + /* Initialize speed and link to default case */ + *link_up = false; + *speed = IXGBE_LINK_SPEED_10GB_FULL; + + /* + * Check current speed and link status of the PHY register. + * This is a vendor specific register and may have to + * be changed for other copper PHYs. + */ + for (time_out = 0; time_out < max_time_out; time_out++) { + udelay(10); + status = hw->phy.ops.read_reg(hw, + MDIO_STAT1, + MDIO_MMD_VEND1, + &phy_data); + phy_link = phy_data & + IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS; + phy_speed = phy_data & + IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS; + if (phy_link == IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS) { + *link_up = true; + if (phy_speed == + IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS) + *speed = IXGBE_LINK_SPEED_1GB_FULL; + break; + } + } + + return status; +} + +/** + * ixgbe_setup_phy_link_tnx - Set and restart autoneg + * @hw: pointer to hardware structure + * + * Restart autonegotiation and PHY and waits for completion. + **/ +s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw) +{ + s32 status = 0; + u32 time_out; + u32 max_time_out = 10; + u16 autoneg_reg = IXGBE_MII_AUTONEG_REG; + bool autoneg = false; + ixgbe_link_speed speed; + + ixgbe_get_copper_link_capabilities_generic(hw, &speed, &autoneg); + + if (speed & IXGBE_LINK_SPEED_10GB_FULL) { + /* Set or unset auto-negotiation 10G advertisement */ + hw->phy.ops.read_reg(hw, MDIO_AN_10GBT_CTRL, + MDIO_MMD_AN, + &autoneg_reg); + + autoneg_reg &= ~MDIO_AN_10GBT_CTRL_ADV10G; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) + autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G; + + hw->phy.ops.write_reg(hw, MDIO_AN_10GBT_CTRL, + MDIO_MMD_AN, + autoneg_reg); + } + + if (speed & IXGBE_LINK_SPEED_1GB_FULL) { + /* Set or unset auto-negotiation 1G advertisement */ + hw->phy.ops.read_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG, + MDIO_MMD_AN, + &autoneg_reg); + + autoneg_reg &= ~IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) + autoneg_reg |= IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX; + + hw->phy.ops.write_reg(hw, IXGBE_MII_AUTONEG_XNP_TX_REG, + MDIO_MMD_AN, + autoneg_reg); + } + + if (speed & IXGBE_LINK_SPEED_100_FULL) { + /* Set or unset auto-negotiation 100M advertisement */ + hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE, + MDIO_MMD_AN, + &autoneg_reg); + + autoneg_reg &= ~ADVERTISE_100FULL; + if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) + autoneg_reg |= ADVERTISE_100FULL; + + hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, + MDIO_MMD_AN, + autoneg_reg); + } + + /* Restart PHY autonegotiation and wait for completion */ + hw->phy.ops.read_reg(hw, MDIO_CTRL1, + MDIO_MMD_AN, &autoneg_reg); + + autoneg_reg |= MDIO_AN_CTRL1_RESTART; + + hw->phy.ops.write_reg(hw, MDIO_CTRL1, + MDIO_MMD_AN, autoneg_reg); + + /* Wait for autonegotiation to finish */ + for (time_out = 0; time_out < max_time_out; time_out++) { + udelay(10); + /* Restart PHY autonegotiation and wait for completion */ + status = hw->phy.ops.read_reg(hw, MDIO_STAT1, + MDIO_MMD_AN, + &autoneg_reg); + + autoneg_reg &= MDIO_AN_STAT1_COMPLETE; + if (autoneg_reg == MDIO_AN_STAT1_COMPLETE) + break; + } + + if (time_out == max_time_out) { + status = IXGBE_ERR_LINK_SETUP; + hw_dbg(hw, "ixgbe_setup_phy_link_tnx: time out"); + } + + return status; +} + +/** + * ixgbe_get_phy_firmware_version_tnx - Gets the PHY Firmware Version + * @hw: pointer to hardware structure + * @firmware_version: pointer to the PHY Firmware Version + **/ +s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, + u16 *firmware_version) +{ + s32 status = 0; + + status = hw->phy.ops.read_reg(hw, TNX_FW_REV, + MDIO_MMD_VEND1, + firmware_version); + + return status; +} + +/** + * ixgbe_get_phy_firmware_version_generic - Gets the PHY Firmware Version + * @hw: pointer to hardware structure + * @firmware_version: pointer to the PHY Firmware Version + **/ +s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw, + u16 *firmware_version) +{ + s32 status = 0; + + status = hw->phy.ops.read_reg(hw, AQ_FW_REV, + MDIO_MMD_VEND1, + firmware_version); + + return status; +} + /** * ixgbe_reset_phy_nl - Performs a PHY reset * @hw: pointer to hardware structure @@ -1476,86 +1693,6 @@ static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw) ixgbe_i2c_stop(hw); } -/** - * ixgbe_check_phy_link_tnx - Determine link and speed status - * @hw: pointer to hardware structure - * - * Reads the VS1 register to determine if link is up and the current speed for - * the PHY. - **/ -s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed, - bool *link_up) -{ - s32 status = 0; - u32 time_out; - u32 max_time_out = 10; - u16 phy_link = 0; - u16 phy_speed = 0; - u16 phy_data = 0; - - /* Initialize speed and link to default case */ - *link_up = false; - *speed = IXGBE_LINK_SPEED_10GB_FULL; - - /* - * Check current speed and link status of the PHY register. - * This is a vendor specific register and may have to - * be changed for other copper PHYs. - */ - for (time_out = 0; time_out < max_time_out; time_out++) { - udelay(10); - status = hw->phy.ops.read_reg(hw, - IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS, - MDIO_MMD_VEND1, - &phy_data); - phy_link = phy_data & - IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS; - phy_speed = phy_data & - IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS; - if (phy_link == IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS) { - *link_up = true; - if (phy_speed == - IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS) - *speed = IXGBE_LINK_SPEED_1GB_FULL; - break; - } - } - - return status; -} - -/** - * ixgbe_get_phy_firmware_version_tnx - Gets the PHY Firmware Version - * @hw: pointer to hardware structure - * @firmware_version: pointer to the PHY Firmware Version - **/ -s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, - u16 *firmware_version) -{ - s32 status = 0; - - status = hw->phy.ops.read_reg(hw, TNX_FW_REV, MDIO_MMD_VEND1, - firmware_version); - - return status; -} - -/** - * ixgbe_get_phy_firmware_version_generic - Gets the PHY Firmware Version - * @hw: pointer to hardware structure - * @firmware_version: pointer to the PHY Firmware Version -**/ -s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw, - u16 *firmware_version) -{ - s32 status = 0; - - status = hw->phy.ops.read_reg(hw, AQ_FW_REV, MDIO_MMD_VEND1, - firmware_version); - - return status; -} - /** * ixgbe_tn_check_overtemp - Checks if an overtemp occured. * @hw: pointer to hardware structure diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h index 9bf2783d7a74..197bdd13106a 100644 --- a/drivers/net/ixgbe/ixgbe_phy.h +++ b/drivers/net/ixgbe/ixgbe_phy.h @@ -108,6 +108,7 @@ s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw, s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *link_up); +s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw); s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, u16 *firmware_version); s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw, diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index f190a4a8faf4..63d862d3fd90 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -1009,6 +1009,13 @@ #define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA 0xC30B /* PHY_XS SDA/SCL Data Reg */ #define IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT 0xC30C /* PHY_XS SDA/SCL Status Reg */ +/* MII clause 22/28 definitions */ +#define IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG 0xC400 /* 1G Provisioning 1 */ +#define IXGBE_MII_AUTONEG_XNP_TX_REG 0x17 /* 1G XNP Transmit */ +#define IXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX 0x4000 /* full duplex, bit:14*/ +#define IXGBE_MII_1GBASE_T_ADVERTISE 0x8000 /* full duplex, bit:15*/ +#define IXGBE_MII_AUTONEG_REG 0x0 + #define IXGBE_PHY_REVISION_MASK 0xFFFFFFF0 #define IXGBE_MAX_PHY_ADDR 32 -- cgit v1.2.3 From 6fb456a07c68913516da9de90d3849ee9821dea8 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Sat, 5 Mar 2011 08:02:18 +0000 Subject: ixgbe: correct typo in define name VF Free Running Timer register name missing an F. Signed-off-by: Emil Tantilov Acked-by: Greg Rose Tested-by: Evan Swanson Signed-off-by: Jeff Kirsher --- drivers/net/ixgbevf/ethtool.c | 4 ++-- drivers/net/ixgbevf/regs.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbevf/ethtool.c b/drivers/net/ixgbevf/ethtool.c index fa29b3c8c464..0563ab29264e 100644 --- a/drivers/net/ixgbevf/ethtool.c +++ b/drivers/net/ixgbevf/ethtool.c @@ -172,7 +172,7 @@ static char *ixgbevf_reg_names[] = { "IXGBE_VFSTATUS", "IXGBE_VFLINKS", "IXGBE_VFRXMEMWRAP", - "IXGBE_VFRTIMER", + "IXGBE_VFFRTIMER", "IXGBE_VTEICR", "IXGBE_VTEICS", "IXGBE_VTEIMS", @@ -240,7 +240,7 @@ static void ixgbevf_get_regs(struct net_device *netdev, regs_buff[1] = IXGBE_READ_REG(hw, IXGBE_VFSTATUS); regs_buff[2] = IXGBE_READ_REG(hw, IXGBE_VFLINKS); regs_buff[3] = IXGBE_READ_REG(hw, IXGBE_VFRXMEMWRAP); - regs_buff[4] = IXGBE_READ_REG(hw, IXGBE_VFRTIMER); + regs_buff[4] = IXGBE_READ_REG(hw, IXGBE_VFFRTIMER); /* Interrupt */ /* don't read EICR because it can clear interrupt causes, instead diff --git a/drivers/net/ixgbevf/regs.h b/drivers/net/ixgbevf/regs.h index fb80ca1bcc93..189200eeca26 100644 --- a/drivers/net/ixgbevf/regs.h +++ b/drivers/net/ixgbevf/regs.h @@ -31,7 +31,7 @@ #define IXGBE_VFCTRL 0x00000 #define IXGBE_VFSTATUS 0x00008 #define IXGBE_VFLINKS 0x00010 -#define IXGBE_VFRTIMER 0x00048 +#define IXGBE_VFFRTIMER 0x00048 #define IXGBE_VFRXMEMWRAP 0x03190 #define IXGBE_VTEICR 0x00100 #define IXGBE_VTEICS 0x00104 -- cgit v1.2.3 From 1390a59452a0895d3fea5b5504fa75ba36c13a74 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Wed, 9 Mar 2011 04:46:16 +0000 Subject: ixgbe: DCB, set minimum bandwidth per traffic class DCB provides a guaranteed bandwidth in the case with 0% bandwidth then no bandwidth is guaranteed. However the traffic class should still be able to transmit traffic. For this to work the traffic class must be given the minimum credits required to send a frame. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c index e7b551af573d..41c529fac0ab 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.c +++ b/drivers/net/ixgbe/ixgbe_dcb.c @@ -64,7 +64,7 @@ s32 ixgbe_ieee_credits(__u8 *bw, __u16 *refill, __u16 *max, int max_frame) val = min_credit; refill[i] = val; - max[i] = (bw[i] * MAX_CREDIT)/100; + max[i] = bw[i] ? (bw[i] * MAX_CREDIT)/100 : min_credit; } return 0; } -- cgit v1.2.3 From ff4ab2061199cdb938282d302d5044b1858e28c8 Mon Sep 17 00:00:00 2001 From: Lior Levy Date: Fri, 11 Mar 2011 02:03:07 +0000 Subject: ixgbe: add support for VF Transmit rate limit using iproute2 Implemented ixgbe_ndo_set_vf_bw function which is being used by iproute2 tool. In addition, updated ixgbe_ndo_get_vf_config function to show the actual rate limit to the user. The rate limitation can be configured only when the link is up and the link speed is 10Gb. The rate limit value can be 0 or ranged between 11 and actual link speed measured in Mbps. A value of '0' disables the rate limit for this specific VF. iproute2 usage will be 'ip link set ethX vf Y rate Z'. After the command is made, the rate will be changed instantly. To view the current rate limit, use 'ip link show ethX'. The rates will be zeroed only upon driver reload or a link speed change. This feature is being supported by 82599 and X540 devices. Signed-off-by: Lior Levy Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe.h | 2 + drivers/net/ixgbe/ixgbe_main.c | 1 + drivers/net/ixgbe/ixgbe_sriov.c | 85 ++++++++++++++++++++++++++++++++++++++++- drivers/net/ixgbe/ixgbe_sriov.h | 1 + drivers/net/ixgbe/ixgbe_type.h | 6 +++ 5 files changed, 93 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index b7e62d568b85..8d468028bb55 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -118,6 +118,7 @@ struct vf_data_storage { bool pf_set_mac; u16 pf_vlan; /* When set, guest VLAN config not allowed. */ u16 pf_qos; + u16 tx_rate; }; /* wrapper around a pointer to a socket buffer, @@ -468,6 +469,7 @@ struct ixgbe_adapter { DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS); unsigned int num_vfs; struct vf_data_storage *vfinfo; + int vf_rate_link_speed; }; enum ixbge_state_t { diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 38f9758c4c44..f17e4a7ee731 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -6217,6 +6217,7 @@ static void ixgbe_watchdog_task(struct work_struct *work) (flow_tx ? "TX" : "None")))); netif_carrier_on(netdev); + ixgbe_check_vf_rate_limit(adapter); } else { /* Force detection of hung controller */ for (i = 0; i < adapter->num_tx_queues; i++) { diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c index 58c9b45989ff..6e50d8328942 100644 --- a/drivers/net/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ixgbe/ixgbe_sriov.c @@ -478,9 +478,90 @@ out: return err; } +static int ixgbe_link_mbps(int internal_link_speed) +{ + switch (internal_link_speed) { + case IXGBE_LINK_SPEED_100_FULL: + return 100; + case IXGBE_LINK_SPEED_1GB_FULL: + return 1000; + case IXGBE_LINK_SPEED_10GB_FULL: + return 10000; + default: + return 0; + } +} + +static void ixgbe_set_vf_rate_limit(struct ixgbe_hw *hw, int vf, int tx_rate, + int link_speed) +{ + int rf_dec, rf_int; + u32 bcnrc_val; + + if (tx_rate != 0) { + /* Calculate the rate factor values to set */ + rf_int = link_speed / tx_rate; + rf_dec = (link_speed - (rf_int * tx_rate)); + rf_dec = (rf_dec * (1<vf_rate_link_speed == 0) + return; + + actual_link_speed = ixgbe_link_mbps(adapter->link_speed); + if (actual_link_speed != adapter->vf_rate_link_speed) { + reset_rate = true; + adapter->vf_rate_link_speed = 0; + dev_info(&adapter->pdev->dev, + "Link speed has been changed. VF Transmit rate " + "is disabled\n"); + } + + for (i = 0; i < adapter->num_vfs; i++) { + if (reset_rate) + adapter->vfinfo[i].tx_rate = 0; + + ixgbe_set_vf_rate_limit(&adapter->hw, i, + adapter->vfinfo[i].tx_rate, + actual_link_speed); + } +} + int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate) { - return -EOPNOTSUPP; + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + int actual_link_speed; + + actual_link_speed = ixgbe_link_mbps(adapter->link_speed); + if ((vf >= adapter->num_vfs) || (!adapter->link_up) || + (tx_rate > actual_link_speed) || (actual_link_speed != 10000) || + ((tx_rate != 0) && (tx_rate <= 10))) + /* rate limit cannot be set to 10Mb or less in 10Gb adapters */ + return -EINVAL; + + adapter->vf_rate_link_speed = actual_link_speed; + adapter->vfinfo[vf].tx_rate = (u16)tx_rate; + ixgbe_set_vf_rate_limit(hw, vf, tx_rate, actual_link_speed); + + return 0; } int ixgbe_ndo_get_vf_config(struct net_device *netdev, @@ -491,7 +572,7 @@ int ixgbe_ndo_get_vf_config(struct net_device *netdev, return -EINVAL; ivi->vf = vf; memcpy(&ivi->mac, adapter->vfinfo[vf].vf_mac_addresses, ETH_ALEN); - ivi->tx_rate = 0; + ivi->tx_rate = adapter->vfinfo[vf].tx_rate; ivi->vlan = adapter->vfinfo[vf].pf_vlan; ivi->qos = adapter->vfinfo[vf].pf_qos; return 0; diff --git a/drivers/net/ixgbe/ixgbe_sriov.h b/drivers/net/ixgbe/ixgbe_sriov.h index e7dd029d576a..34175564bb78 100644 --- a/drivers/net/ixgbe/ixgbe_sriov.h +++ b/drivers/net/ixgbe/ixgbe_sriov.h @@ -40,6 +40,7 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan, int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate); int ixgbe_ndo_get_vf_config(struct net_device *netdev, int vf, struct ifla_vf_info *ivi); +void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter); #endif /* _IXGBE_SRIOV_H_ */ diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 63d862d3fd90..25c1fb7eda06 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -533,6 +533,12 @@ #define IXGBE_RTTDTECC 0x04990 #define IXGBE_RTTDTECC_NO_BCN 0x00000100 #define IXGBE_RTTBCNRC 0x04984 +#define IXGBE_RTTBCNRC_RS_ENA 0x80000000 +#define IXGBE_RTTBCNRC_RF_DEC_MASK 0x00003FFF +#define IXGBE_RTTBCNRC_RF_INT_SHIFT 14 +#define IXGBE_RTTBCNRC_RF_INT_MASK \ + (IXGBE_RTTBCNRC_RF_DEC_MASK << IXGBE_RTTBCNRC_RF_INT_SHIFT) + /* FCoE registers */ #define IXGBE_FCPTRL 0x02410 /* FC User Desc. PTR Low */ -- cgit v1.2.3 From 1f4a0244ff002672be855ff2eaa4a29a63d42d42 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Thu, 10 Mar 2011 12:06:12 +0000 Subject: ixgbe: DCB, PFC not cleared until reset occurs The PFC configuration is not cleared until the device is reset. This has not been a problem because setting DCB attributes forced a hardware reset. Now that we no longer require this reset to occur PFC remains configured even after being disabled until the device is reset. This removes a goto in the PFC hardware set routines for 82598 and 82599 devices that was short circuiting the clear. Signed-off-by: John Fastabend Tested-by: Ross Brattain Signed-off-by: Jeff Kirsher --- drivers/net/ixgbe/ixgbe_dcb_82598.c | 44 +++++++++++++++--------------- drivers/net/ixgbe/ixgbe_dcb_82599.c | 54 ++++++++++++++++++------------------- 2 files changed, 47 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c index c97cf9160dc0..1bc57e52cee3 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c @@ -233,21 +233,27 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en) u32 reg, rx_pba_size; u8 i; - if (!pfc_en) - goto out; - - /* Enable Transmit Priority Flow Control */ - reg = IXGBE_READ_REG(hw, IXGBE_RMCS); - reg &= ~IXGBE_RMCS_TFCE_802_3X; - /* correct the reporting of our flow control status */ - reg |= IXGBE_RMCS_TFCE_PRIORITY; - IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); - - /* Enable Receive Priority Flow Control */ - reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); - reg &= ~IXGBE_FCTRL_RFCE; - reg |= IXGBE_FCTRL_RPFCE; - IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg); + if (pfc_en) { + /* Enable Transmit Priority Flow Control */ + reg = IXGBE_READ_REG(hw, IXGBE_RMCS); + reg &= ~IXGBE_RMCS_TFCE_802_3X; + /* correct the reporting of our flow control status */ + reg |= IXGBE_RMCS_TFCE_PRIORITY; + IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); + + /* Enable Receive Priority Flow Control */ + reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); + reg &= ~IXGBE_FCTRL_RFCE; + reg |= IXGBE_FCTRL_RPFCE; + IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg); + + /* Configure pause time */ + for (i = 0; i < (MAX_TRAFFIC_CLASS >> 1); i++) + IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), 0x68006800); + + /* Configure flow control refresh threshold value */ + IXGBE_WRITE_REG(hw, IXGBE_FCRTV, 0x3400); + } /* * Configure flow control thresholds and enable priority flow control @@ -273,14 +279,6 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en) IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg); } - /* Configure pause time */ - for (i = 0; i < (MAX_TRAFFIC_CLASS >> 1); i++) - IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), 0x68006800); - - /* Configure flow control refresh threshold value */ - IXGBE_WRITE_REG(hw, IXGBE_FCRTV, 0x3400); - -out: return 0; } diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c index 0a482bbf1bd2..025af8c53ddb 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c @@ -253,13 +253,6 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en) { u32 i, reg, rx_pba_size; - /* If PFC is disabled globally then fall back to LFC. */ - if (!pfc_en) { - for (i = 0; i < MAX_TRAFFIC_CLASS; i++) - hw->mac.ops.fc_enable(hw, i); - goto out; - } - /* Configure PFC Tx thresholds per TC */ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { int enabled = pfc_en & (1 << i); @@ -278,28 +271,33 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en) IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg); } - /* Configure pause time (2 TCs per register) */ - reg = hw->fc.pause_time | (hw->fc.pause_time << 16); - for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++) - IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); - - /* Configure flow control refresh threshold value */ - IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2); - - /* Enable Transmit PFC */ - reg = IXGBE_FCCFG_TFCE_PRIORITY; - IXGBE_WRITE_REG(hw, IXGBE_FCCFG, reg); + if (pfc_en) { + /* Configure pause time (2 TCs per register) */ + reg = hw->fc.pause_time | (hw->fc.pause_time << 16); + for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++) + IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); + + /* Configure flow control refresh threshold value */ + IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2); + + + reg = IXGBE_FCCFG_TFCE_PRIORITY; + IXGBE_WRITE_REG(hw, IXGBE_FCCFG, reg); + /* + * Enable Receive PFC + * We will always honor XOFF frames we receive when + * we are in PFC mode. + */ + reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); + reg &= ~IXGBE_MFLCN_RFCE; + reg |= IXGBE_MFLCN_RPFCE | IXGBE_MFLCN_DPF; + IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg); + + } else { + for (i = 0; i < MAX_TRAFFIC_CLASS; i++) + hw->mac.ops.fc_enable(hw, i); + } - /* - * Enable Receive PFC - * We will always honor XOFF frames we receive when - * we are in PFC mode. - */ - reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); - reg &= ~IXGBE_MFLCN_RFCE; - reg |= IXGBE_MFLCN_RPFCE | IXGBE_MFLCN_DPF; - IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg); -out: return 0; } -- cgit v1.2.3 From 78fbfd8a653ca972afe479517a40661bfff6d8c3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 12 Mar 2011 00:00:52 -0500 Subject: ipv4: Create and use route lookup helpers. The idea here is this minimizes the number of places one has to edit in order to make changes to how flows are defined and used. Signed-off-by: David S. Miller --- drivers/infiniband/core/addr.c | 8 +----- drivers/infiniband/hw/cxgb3/iwch_cm.c | 21 +++------------ drivers/infiniband/hw/cxgb4/cm.c | 21 +++------------ drivers/infiniband/hw/nes/nes_cm.c | 5 +--- drivers/net/bonding/bond_main.c | 12 +++------ drivers/net/cnic.c | 16 ++++-------- drivers/net/pptp.c | 45 +++++++++++++------------------- drivers/scsi/cxgbi/libcxgbi.c | 20 +++----------- include/net/route.h | 48 ++++++++++++++++++++++++++++++++++ net/atm/clip.c | 4 +-- net/bridge/br_netfilter.c | 7 ++--- net/ipv4/af_inet.c | 20 +++----------- net/ipv4/arp.c | 12 +++------ net/ipv4/igmp.c | 34 +++++++++++------------- net/ipv4/ip_gre.c | 49 ++++++++++++----------------------- net/ipv4/ip_output.c | 33 ++++++++++------------- net/ipv4/ipip.c | 36 ++++++++++--------------- net/ipv4/ipmr.c | 24 +++++++---------- net/ipv6/ip6_tunnel.c | 19 +++++++------- net/ipv6/sit.c | 31 ++++++++++------------ net/l2tp/l2tp_ip.c | 30 ++++++++------------- net/netfilter/ipvs/ip_vs_xmit.c | 14 ++-------- net/rxrpc/ar-peer.c | 23 +++------------- 23 files changed, 206 insertions(+), 326 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 2d749937a969..1742f72fbd57 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -183,17 +183,11 @@ static int addr4_resolve(struct sockaddr_in *src_in, { __be32 src_ip = src_in->sin_addr.s_addr; __be32 dst_ip = dst_in->sin_addr.s_addr; - struct flowi fl; struct rtable *rt; struct neighbour *neigh; int ret; - memset(&fl, 0, sizeof fl); - fl.nl_u.ip4_u.daddr = dst_ip; - fl.nl_u.ip4_u.saddr = src_ip; - fl.oif = addr->bound_dev_if; - - rt = ip_route_output_key(&init_net, &fl); + rt = ip_route_output(&init_net, dst_ip, src_ip, 0, addr->bound_dev_if); if (IS_ERR(rt)) { ret = PTR_ERR(rt); goto out; diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index e0ccbc53fbcc..3216bcad7e82 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c @@ -338,23 +338,10 @@ static struct rtable *find_route(struct t3cdev *dev, __be32 local_ip, __be16 peer_port, u8 tos) { struct rtable *rt; - struct flowi fl = { - .oif = 0, - .nl_u = { - .ip4_u = { - .daddr = peer_ip, - .saddr = local_ip, - .tos = tos} - }, - .proto = IPPROTO_TCP, - .uli_u = { - .ports = { - .sport = local_port, - .dport = peer_port} - } - }; - - rt = ip_route_output_flow(&init_net, &fl, NULL); + + rt = ip_route_output_ports(&init_net, NULL, peer_ip, local_ip, + peer_port, local_port, IPPROTO_TCP, + tos, 0); if (IS_ERR(rt)) return NULL; return rt; diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 77b0eef2aad9..97a876a0f20b 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -315,23 +315,10 @@ static struct rtable *find_route(struct c4iw_dev *dev, __be32 local_ip, __be16 peer_port, u8 tos) { struct rtable *rt; - struct flowi fl = { - .oif = 0, - .nl_u = { - .ip4_u = { - .daddr = peer_ip, - .saddr = local_ip, - .tos = tos} - }, - .proto = IPPROTO_TCP, - .uli_u = { - .ports = { - .sport = local_port, - .dport = peer_port} - } - }; - - rt = ip_route_output_flow(&init_net, &fl, NULL); + + rt = ip_route_output_ports(&init_net, NULL, peer_ip, local_ip, + peer_port, local_port, IPPROTO_TCP, + tos, 0); if (IS_ERR(rt)) return NULL; return rt; diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index e81599cb1fe6..ef3291551bc6 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -1104,15 +1104,12 @@ static inline int mini_cm_accelerated(struct nes_cm_core *cm_core, static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpindex) { struct rtable *rt; - struct flowi fl; struct neighbour *neigh; int rc = arpindex; struct net_device *netdev; struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter; - memset(&fl, 0, sizeof fl); - fl.nl_u.ip4_u.daddr = htonl(dst_ip); - rt = ip_route_output_key(&init_net, &fl); + rt = ip_route_output(&init_net, htonl(dst_ip), 0, 0, 0); if (IS_ERR(rt)) { printk(KERN_ERR "%s: ip_route_output_key failed for 0x%08X\n", __func__, dst_ip); diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 68a5ce0a649f..3ad4f501949e 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2676,7 +2676,6 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) __be32 *targets = bond->params.arp_targets; struct vlan_entry *vlan; struct net_device *vlan_dev; - struct flowi fl; struct rtable *rt; for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) { @@ -2695,15 +2694,12 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) * determine which VLAN interface would be used, so we * can tag the ARP with the proper VLAN tag. */ - memset(&fl, 0, sizeof(fl)); - fl.fl4_dst = targets[i]; - fl.fl4_tos = RTO_ONLINK; - - rt = ip_route_output_key(dev_net(bond->dev), &fl); + rt = ip_route_output(dev_net(bond->dev), targets[i], 0, + RTO_ONLINK, 0); if (IS_ERR(rt)) { if (net_ratelimit()) { pr_warning("%s: no route to arp_ip_target %pI4\n", - bond->dev->name, &fl.fl4_dst); + bond->dev->name, &targets[i]); } continue; } @@ -2739,7 +2735,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) if (net_ratelimit()) { pr_warning("%s: no path to arp_ip_target %pI4 via rt.dev %s\n", - bond->dev->name, &fl.fl4_dst, + bond->dev->name, &targets[i], rt->dst.dev ? rt->dst.dev->name : "NULL"); } ip_rt_put(rt); diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 271a1f00c224..65832951fe07 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -3407,20 +3407,14 @@ static int cnic_get_v4_route(struct sockaddr_in *dst_addr, struct dst_entry **dst) { #if defined(CONFIG_INET) - struct flowi fl; - int err; struct rtable *rt; - memset(&fl, 0, sizeof(fl)); - fl.nl_u.ip4_u.daddr = dst_addr->sin_addr.s_addr; - - rt = ip_route_output_key(&init_net, &fl); - err = 0; - if (!IS_ERR(rt)) + rt = ip_route_output(&init_net, dst_addr->sin_addr.s_addr, 0, 0, 0); + if (!IS_ERR(rt)) { *dst = &rt->dst; - else - err = PTR_ERR(rt); - return err; + return 0; + } + return PTR_ERR(rt); #else return -ENETUNREACH; #endif diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c index 1af549c89d51..51dfcf8023c7 100644 --- a/drivers/net/pptp.c +++ b/drivers/net/pptp.c @@ -189,18 +189,14 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) if (sk_pppox(po)->sk_state & PPPOX_DEAD) goto tx_error; - { - struct flowi fl = { .oif = 0, - .nl_u = { - .ip4_u = { - .daddr = opt->dst_addr.sin_addr.s_addr, - .saddr = opt->src_addr.sin_addr.s_addr, - .tos = RT_TOS(0) } }, - .proto = IPPROTO_GRE }; - rt = ip_route_output_key(&init_net, &fl); - if (IS_ERR(rt)) - goto tx_error; - } + rt = ip_route_output_ports(&init_net, NULL, + opt->dst_addr.sin_addr.s_addr, + opt->src_addr.sin_addr.s_addr, + 0, 0, IPPROTO_GRE, + RT_TOS(0), 0); + if (IS_ERR(rt)) + goto tx_error; + tdev = rt->dst.dev; max_headroom = LL_RESERVED_SPACE(tdev) + sizeof(*iph) + sizeof(*hdr) + 2; @@ -467,22 +463,17 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr, po->chan.private = sk; po->chan.ops = &pptp_chan_ops; - { - struct flowi fl = { - .nl_u = { - .ip4_u = { - .daddr = opt->dst_addr.sin_addr.s_addr, - .saddr = opt->src_addr.sin_addr.s_addr, - .tos = RT_CONN_FLAGS(sk) } }, - .proto = IPPROTO_GRE }; - security_sk_classify_flow(sk, &fl); - rt = ip_route_output_key(&init_net, &fl); - if (IS_ERR(rt)) { - error = -EHOSTUNREACH; - goto end; - } - sk_setup_caps(sk, &rt->dst); + rt = ip_route_output_ports(&init_net, sk, + opt->dst_addr.sin_addr.s_addr, + opt->src_addr.sin_addr.s_addr, + 0, 0, + IPPROTO_GRE, RT_CONN_FLAGS(sk), 0); + if (IS_ERR(rt)) { + error = -EHOSTUNREACH; + goto end; } + sk_setup_caps(sk, &rt->dst); + po->chan.mtu = dst_mtu(&rt->dst); if (!po->chan.mtu) po->chan.mtu = PPP_MTU; diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index 889199aa1f5b..a24dff9f9163 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c @@ -451,26 +451,12 @@ static struct cxgbi_sock *cxgbi_sock_create(struct cxgbi_device *cdev) } static struct rtable *find_route_ipv4(__be32 saddr, __be32 daddr, - __be16 sport, __be16 dport, u8 tos) + __be16 sport, __be16 dport, u8 tos) { struct rtable *rt; - struct flowi fl = { - .oif = 0, - .nl_u = { - .ip4_u = { - .daddr = daddr, - .saddr = saddr, - .tos = tos } - }, - .proto = IPPROTO_TCP, - .uli_u = { - .ports = { - .sport = sport, - .dport = dport } - } - }; - rt = ip_route_output_flow(&init_net, &fl, NULL); + rt = ip_route_output_ports(&init_net, NULL, daddr, saddr, + dport, sport, IPPROTO_TCP, tos, 0); if (IS_ERR(rt)) return NULL; diff --git a/include/net/route.h b/include/net/route.h index 9257f5f17337..f140f4130fea 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -132,6 +132,54 @@ static inline struct rtable *ip_route_output_key(struct net *net, struct flowi * return ip_route_output_flow(net, flp, NULL); } +static inline struct rtable *ip_route_output(struct net *net, __be32 daddr, + __be32 saddr, u8 tos, int oif) +{ + struct flowi fl = { + .oif = oif, + .fl4_dst = daddr, + .fl4_src = saddr, + .fl4_tos = tos, + }; + return ip_route_output_key(net, &fl); +} + +static inline struct rtable *ip_route_output_ports(struct net *net, struct sock *sk, + __be32 daddr, __be32 saddr, + __be16 dport, __be16 sport, + __u8 proto, __u8 tos, int oif) +{ + struct flowi fl = { + .oif = oif, + .flags = sk ? inet_sk_flowi_flags(sk) : 0, + .mark = sk ? sk->sk_mark : 0, + .fl4_dst = daddr, + .fl4_src = saddr, + .fl4_tos = tos, + .proto = proto, + .fl_ip_dport = dport, + .fl_ip_sport = sport, + }; + if (sk) + security_sk_classify_flow(sk, &fl); + return ip_route_output_flow(net, &fl, sk); +} + +static inline struct rtable *ip_route_output_gre(struct net *net, + __be32 daddr, __be32 saddr, + __be32 gre_key, __u8 tos, int oif) +{ + struct flowi fl = { + .oif = oif, + .fl4_dst = daddr, + .fl4_src = saddr, + .fl4_tos = tos, + .proto = IPPROTO_GRE, + .fl_gre_key = gre_key, + }; + return ip_route_output_key(net, &fl); +} + extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, u8 tos, struct net_device *devin, bool noref); diff --git a/net/atm/clip.c b/net/atm/clip.c index 810a1294eddb..1d4be60e1390 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c @@ -502,8 +502,6 @@ static int clip_setentry(struct atm_vcc *vcc, __be32 ip) struct atmarp_entry *entry; int error; struct clip_vcc *clip_vcc; - struct flowi fl = { .fl4_dst = ip, - .fl4_tos = 1 }; struct rtable *rt; if (vcc->push != clip_push) { @@ -520,7 +518,7 @@ static int clip_setentry(struct atm_vcc *vcc, __be32 ip) unlink_clip_vcc(clip_vcc); return 0; } - rt = ip_route_output_key(&init_net, &fl); + rt = ip_route_output(&init_net, ip, 0, 1, 0); if (IS_ERR(rt)) return PTR_ERR(rt); neigh = __neigh_lookup(&clip_tbl, &ip, rt->dst.dev, 1); diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 45b57b173f70..f97af5590ba1 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -412,10 +412,6 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb) nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; if (dnat_took_place(skb)) { if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) { - struct flowi fl = { - .fl4_dst = iph->daddr, - .fl4_tos = RT_TOS(iph->tos), - }; struct in_device *in_dev = __in_dev_get_rcu(dev); /* If err equals -EHOSTUNREACH the error is due to a @@ -428,7 +424,8 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb) if (err != -EHOSTUNREACH || !in_dev || IN_DEV_FORWARD(in_dev)) goto free_skb; - rt = ip_route_output_key(dev_net(dev), &fl); + rt = ip_route_output(dev_net(dev), iph->daddr, 0, + RT_TOS(iph->tos), 0); if (!IS_ERR(rt)) { /* - Bridged-and-DNAT'ed traffic doesn't * require ip_forwarding. */ diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 35a502055018..807d83c02ef6 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1157,22 +1157,10 @@ int inet_sk_rebuild_header(struct sock *sk) daddr = inet->inet_daddr; if (inet->opt && inet->opt->srr) daddr = inet->opt->faddr; - { - struct flowi fl = { - .oif = sk->sk_bound_dev_if, - .mark = sk->sk_mark, - .fl4_dst = daddr, - .fl4_src = inet->inet_saddr, - .fl4_tos = RT_CONN_FLAGS(sk), - .proto = sk->sk_protocol, - .flags = inet_sk_flowi_flags(sk), - .fl_ip_sport = inet->inet_sport, - .fl_ip_dport = inet->inet_dport, - }; - - security_sk_classify_flow(sk, &fl); - rt = ip_route_output_flow(sock_net(sk), &fl, sk); - } + rt = ip_route_output_ports(sock_net(sk), sk, daddr, inet->inet_saddr, + inet->inet_dport, inet->inet_sport, + sk->sk_protocol, RT_CONN_FLAGS(sk), + sk->sk_bound_dev_if); if (!IS_ERR(rt)) { err = 0; sk_setup_caps(sk, &rt->dst); diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index fa9988da1da4..090d273d7865 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -433,14 +433,12 @@ static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip) static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev) { - struct flowi fl = { .fl4_dst = sip, - .fl4_src = tip }; struct rtable *rt; int flag = 0; /*unsigned long now; */ struct net *net = dev_net(dev); - rt = ip_route_output_key(net, &fl); + rt = ip_route_output(net, sip, tip, 0, 0); if (IS_ERR(rt)) return 1; if (rt->dst.dev != dev) { @@ -1062,9 +1060,7 @@ static int arp_req_set(struct net *net, struct arpreq *r, if (r->arp_flags & ATF_PERM) r->arp_flags |= ATF_COM; if (dev == NULL) { - struct flowi fl = { .fl4_dst = ip, - .fl4_tos = RTO_ONLINK }; - struct rtable *rt = ip_route_output_key(net, &fl); + struct rtable *rt = ip_route_output(net, ip, 0, RTO_ONLINK, 0); if (IS_ERR(rt)) return PTR_ERR(rt); @@ -1185,9 +1181,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r, ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr; if (dev == NULL) { - struct flowi fl = { .fl4_dst = ip, - .fl4_tos = RTO_ONLINK }; - struct rtable *rt = ip_route_output_key(net, &fl); + struct rtable *rt = ip_route_output(net, ip, 0, RTO_ONLINK, 0); if (IS_ERR(rt)) return PTR_ERR(rt); dev = rt->dst.dev; diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 12b65ccca8e9..1fd3d9ce8398 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -321,15 +321,12 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) } igmp_skb_size(skb) = size; - { - struct flowi fl = { .oif = dev->ifindex, - .fl4_dst = IGMPV3_ALL_MCR, - .proto = IPPROTO_IGMP }; - rt = ip_route_output_key(net, &fl); - if (IS_ERR(rt)) { - kfree_skb(skb); - return NULL; - } + rt = ip_route_output_ports(net, NULL, IGMPV3_ALL_MCR, 0, + 0, 0, + IPPROTO_IGMP, 0, dev->ifindex); + if (IS_ERR(rt)) { + kfree_skb(skb); + return NULL; } if (rt->rt_src == 0) { kfree_skb(skb); @@ -667,14 +664,12 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, else dst = group; - { - struct flowi fl = { .oif = dev->ifindex, - .fl4_dst = dst, - .proto = IPPROTO_IGMP }; - rt = ip_route_output_key(net, &fl); - if (IS_ERR(rt)) - return -1; - } + rt = ip_route_output_ports(net, NULL, dst, 0, + 0, 0, + IPPROTO_IGMP, 0, dev->ifindex); + if (IS_ERR(rt)) + return -1; + if (rt->rt_src == 0) { ip_rt_put(rt); return -1; @@ -1441,7 +1436,6 @@ void ip_mc_destroy_dev(struct in_device *in_dev) /* RTNL is locked */ static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr) { - struct flowi fl = { .fl4_dst = imr->imr_multiaddr.s_addr }; struct net_device *dev = NULL; struct in_device *idev = NULL; @@ -1456,7 +1450,9 @@ static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr) } if (!dev) { - struct rtable *rt = ip_route_output_key(net, &fl); + struct rtable *rt = ip_route_output(net, + imr->imr_multiaddr.s_addr, + 0, 0, 0); if (!IS_ERR(rt)) { dev = rt->dst.dev; ip_rt_put(rt); diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 71465955520b..da5941f18c3c 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -769,20 +769,12 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev tos = ipv6_get_dsfield((struct ipv6hdr *)old_iph); } - { - struct flowi fl = { - .oif = tunnel->parms.link, - .fl4_dst = dst, - .fl4_src = tiph->saddr, - .fl4_tos = RT_TOS(tos), - .proto = IPPROTO_GRE, - .fl_gre_key = tunnel->parms.o_key - }; - rt = ip_route_output_key(dev_net(dev), &fl); - if (IS_ERR(rt)) { - dev->stats.tx_carrier_errors++; - goto tx_error; - } + rt = ip_route_output_gre(dev_net(dev), dst, tiph->saddr, + tunnel->parms.o_key, RT_TOS(tos), + tunnel->parms.link); + if (IS_ERR(rt)) { + dev->stats.tx_carrier_errors++; + goto tx_error; } tdev = rt->dst.dev; @@ -946,15 +938,11 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev) /* Guess output device to choose reasonable mtu and needed_headroom */ if (iph->daddr) { - struct flowi fl = { - .oif = tunnel->parms.link, - .fl4_dst = iph->daddr, - .fl4_src = iph->saddr, - .fl4_tos = RT_TOS(iph->tos), - .proto = IPPROTO_GRE, - .fl_gre_key = tunnel->parms.o_key - }; - struct rtable *rt = ip_route_output_key(dev_net(dev), &fl); + struct rtable *rt = ip_route_output_gre(dev_net(dev), + iph->daddr, iph->saddr, + tunnel->parms.o_key, + RT_TOS(iph->tos), + tunnel->parms.link); if (!IS_ERR(rt)) { tdev = rt->dst.dev; @@ -1208,15 +1196,12 @@ static int ipgre_open(struct net_device *dev) struct ip_tunnel *t = netdev_priv(dev); if (ipv4_is_multicast(t->parms.iph.daddr)) { - struct flowi fl = { - .oif = t->parms.link, - .fl4_dst = t->parms.iph.daddr, - .fl4_src = t->parms.iph.saddr, - .fl4_tos = RT_TOS(t->parms.iph.tos), - .proto = IPPROTO_GRE, - .fl_gre_key = t->parms.o_key - }; - struct rtable *rt = ip_route_output_key(dev_net(dev), &fl); + struct rtable *rt = ip_route_output_gre(dev_net(dev), + t->parms.iph.daddr, + t->parms.iph.saddr, + t->parms.o_key, + RT_TOS(t->parms.iph.tos), + t->parms.link); if (IS_ERR(rt)) return -EADDRNOTAVAIL; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 171f483b21d5..916152dbdce4 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -339,26 +339,19 @@ int ip_queue_xmit(struct sk_buff *skb) if(opt && opt->srr) daddr = opt->faddr; - { - struct flowi fl = { .oif = sk->sk_bound_dev_if, - .mark = sk->sk_mark, - .fl4_dst = daddr, - .fl4_src = inet->inet_saddr, - .fl4_tos = RT_CONN_FLAGS(sk), - .proto = sk->sk_protocol, - .flags = inet_sk_flowi_flags(sk), - .fl_ip_sport = inet->inet_sport, - .fl_ip_dport = inet->inet_dport }; - - /* If this fails, retransmit mechanism of transport layer will - * keep trying until route appears or the connection times - * itself out. - */ - security_sk_classify_flow(sk, &fl); - rt = ip_route_output_flow(sock_net(sk), &fl, sk); - if (IS_ERR(rt)) - goto no_route; - } + /* If this fails, retransmit mechanism of transport layer will + * keep trying until route appears or the connection times + * itself out. + */ + rt = ip_route_output_ports(sock_net(sk), sk, + daddr, inet->inet_saddr, + inet->inet_dport, + inet->inet_sport, + sk->sk_protocol, + RT_CONN_FLAGS(sk), + sk->sk_bound_dev_if); + if (IS_ERR(rt)) + goto no_route; sk_setup_caps(sk, &rt->dst); } skb_dst_set_noref(skb, &rt->dst); diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 65008f45addc..bfc17c5914e7 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -460,20 +460,14 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) goto tx_error_icmp; } - { - struct flowi fl = { - .oif = tunnel->parms.link, - .fl4_dst = dst, - .fl4_src= tiph->saddr, - .fl4_tos = RT_TOS(tos), - .proto = IPPROTO_IPIP - }; - - rt = ip_route_output_key(dev_net(dev), &fl); - if (IS_ERR(rt)) { - dev->stats.tx_carrier_errors++; - goto tx_error_icmp; - } + rt = ip_route_output_ports(dev_net(dev), NULL, + dst, tiph->saddr, + 0, 0, + IPPROTO_IPIP, RT_TOS(tos), + tunnel->parms.link); + if (IS_ERR(rt)) { + dev->stats.tx_carrier_errors++; + goto tx_error_icmp; } tdev = rt->dst.dev; @@ -584,14 +578,12 @@ static void ipip_tunnel_bind_dev(struct net_device *dev) iph = &tunnel->parms.iph; if (iph->daddr) { - struct flowi fl = { - .oif = tunnel->parms.link, - .fl4_dst = iph->daddr, - .fl4_src = iph->saddr, - .fl4_tos = RT_TOS(iph->tos), - .proto = IPPROTO_IPIP - }; - struct rtable *rt = ip_route_output_key(dev_net(dev), &fl); + struct rtable *rt = ip_route_output_ports(dev_net(dev), NULL, + iph->daddr, iph->saddr, + 0, 0, + IPPROTO_IPIP, + RT_TOS(iph->tos), + tunnel->parms.link); if (!IS_ERR(rt)) { tdev = rt->dst.dev; diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 74909bac8817..594a3004367b 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -1611,25 +1611,19 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, #endif if (vif->flags & VIFF_TUNNEL) { - struct flowi fl = { - .oif = vif->link, - .fl4_dst = vif->remote, - .fl4_src = vif->local, - .fl4_tos = RT_TOS(iph->tos), - .proto = IPPROTO_IPIP - }; - rt = ip_route_output_key(net, &fl); + rt = ip_route_output_ports(net, NULL, + vif->remote, vif->local, + 0, 0, + IPPROTO_IPIP, + RT_TOS(iph->tos), vif->link); if (IS_ERR(rt)) goto out_free; encap = sizeof(struct iphdr); } else { - struct flowi fl = { - .oif = vif->link, - .fl4_dst = iph->daddr, - .fl4_tos = RT_TOS(iph->tos), - .proto = IPPROTO_IPIP - }; - rt = ip_route_output_key(net, &fl); + rt = ip_route_output_ports(net, NULL, iph->daddr, 0, + 0, 0, + IPPROTO_IPIP, + RT_TOS(iph->tos), vif->link); if (IS_ERR(rt)) goto out_free; } diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index ea8d5e8128a9..f199b8486120 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -536,7 +536,6 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, int err; struct sk_buff *skb2; struct iphdr *eiph; - struct flowi fl; struct rtable *rt; err = ip6_tnl_err(skb, IPPROTO_IPIP, opt, &rel_type, &rel_code, @@ -578,11 +577,10 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, eiph = ip_hdr(skb2); /* Try to guess incoming interface */ - memset(&fl, 0, sizeof(fl)); - fl.fl4_dst = eiph->saddr; - fl.fl4_tos = RT_TOS(eiph->tos); - fl.proto = IPPROTO_IPIP; - rt = ip_route_output_key(dev_net(skb->dev), &fl); + rt = ip_route_output_ports(dev_net(skb->dev), NULL, + eiph->saddr, 0, + 0, 0, + IPPROTO_IPIP, RT_TOS(eiph->tos), 0); if (IS_ERR(rt)) goto out; @@ -592,10 +590,11 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, if (rt->rt_flags & RTCF_LOCAL) { ip_rt_put(rt); rt = NULL; - fl.fl4_dst = eiph->daddr; - fl.fl4_src = eiph->saddr; - fl.fl4_tos = eiph->tos; - rt = ip_route_output_key(dev_net(skb->dev), &fl); + rt = ip_route_output_ports(dev_net(skb->dev), NULL, + eiph->daddr, eiph->saddr, + 0, 0, + IPPROTO_IPIP, + RT_TOS(eiph->tos), 0); if (IS_ERR(rt) || rt->dst.dev->type != ARPHRD_TUNNEL) { if (!IS_ERR(rt)) diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 3534ceaa4fba..43b33373adb2 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -732,17 +732,14 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, dst = addr6->s6_addr32[3]; } - { - struct flowi fl = { .fl4_dst = dst, - .fl4_src = tiph->saddr, - .fl4_tos = RT_TOS(tos), - .oif = tunnel->parms.link, - .proto = IPPROTO_IPV6 }; - rt = ip_route_output_key(dev_net(dev), &fl); - if (IS_ERR(rt)) { - dev->stats.tx_carrier_errors++; - goto tx_error_icmp; - } + rt = ip_route_output_ports(dev_net(dev), NULL, + dst, tiph->saddr, + 0, 0, + IPPROTO_IPV6, RT_TOS(tos), + tunnel->parms.link); + if (IS_ERR(rt)) { + dev->stats.tx_carrier_errors++; + goto tx_error_icmp; } if (rt->rt_type != RTN_UNICAST) { ip_rt_put(rt); @@ -858,12 +855,12 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev) iph = &tunnel->parms.iph; if (iph->daddr) { - struct flowi fl = { .fl4_dst = iph->daddr, - .fl4_src = iph->saddr, - .fl4_tos = RT_TOS(iph->tos), - .oif = tunnel->parms.link, - .proto = IPPROTO_IPV6 }; - struct rtable *rt = ip_route_output_key(dev_net(dev), &fl); + struct rtable *rt = ip_route_output_ports(dev_net(dev), NULL, + iph->daddr, iph->saddr, + 0, 0, + IPPROTO_IPV6, + RT_TOS(iph->tos), + tunnel->parms.link); if (!IS_ERR(rt)) { tdev = rt->dst.dev; diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 2a698ff89db6..fce9bd3bd3fe 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -475,25 +475,17 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m if (opt && opt->srr) daddr = opt->faddr; - { - struct flowi fl = { .oif = sk->sk_bound_dev_if, - .fl4_dst = daddr, - .fl4_src = inet->inet_saddr, - .fl4_tos = RT_CONN_FLAGS(sk), - .proto = sk->sk_protocol, - .flags = inet_sk_flowi_flags(sk), - .fl_ip_sport = inet->inet_sport, - .fl_ip_dport = inet->inet_dport }; - - /* If this fails, retransmit mechanism of transport layer will - * keep trying until route appears or the connection times - * itself out. - */ - security_sk_classify_flow(sk, &fl); - rt = ip_route_output_flow(sock_net(sk), &fl, sk); - if (IS_ERR(rt)) - goto no_route; - } + /* If this fails, retransmit mechanism of transport layer will + * keep trying until route appears or the connection times + * itself out. + */ + rt = ip_route_output_ports(sock_net(sk), sk, + daddr, inet->inet_saddr, + inet->inet_dport, inet->inet_sport, + sk->sk_protocol, RT_CONN_FLAGS(sk), + sk->sk_bound_dev_if); + if (IS_ERR(rt)) + goto no_route; sk_setup_caps(sk, &rt->dst); } skb_dst_set(skb, dst_clone(&rt->dst)); diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 878f6dd9dbad..faf381d9da7c 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -98,12 +98,7 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest, spin_lock(&dest->dst_lock); if (!(rt = (struct rtable *) __ip_vs_dst_check(dest, rtos))) { - struct flowi fl = { - .fl4_dst = dest->addr.ip, - .fl4_tos = rtos, - }; - - rt = ip_route_output_key(net, &fl); + rt = ip_route_output(net, dest->addr.ip, 0, rtos, 0); if (IS_ERR(rt)) { spin_unlock(&dest->dst_lock); IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n", @@ -117,12 +112,7 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest, } spin_unlock(&dest->dst_lock); } else { - struct flowi fl = { - .fl4_dst = daddr, - .fl4_tos = rtos, - }; - - rt = ip_route_output_key(net, &fl); + rt = ip_route_output(net, daddr, 0, rtos, 0); if (IS_ERR(rt)) { IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n", &daddr); diff --git a/net/rxrpc/ar-peer.c b/net/rxrpc/ar-peer.c index 3620c569275f..55b93dc60d0c 100644 --- a/net/rxrpc/ar-peer.c +++ b/net/rxrpc/ar-peer.c @@ -36,28 +36,13 @@ static void rxrpc_destroy_peer(struct work_struct *work); static void rxrpc_assess_MTU_size(struct rxrpc_peer *peer) { struct rtable *rt; - struct flowi fl; peer->if_mtu = 1500; - memset(&fl, 0, sizeof(fl)); - - switch (peer->srx.transport.family) { - case AF_INET: - fl.oif = 0; - fl.proto = IPPROTO_UDP, - fl.fl4_dst = peer->srx.transport.sin.sin_addr.s_addr; - fl.fl4_src = 0; - fl.fl4_tos = 0; - /* assume AFS.CM talking to AFS.FS */ - fl.fl_ip_sport = htons(7001); - fl.fl_ip_dport = htons(7000); - break; - default: - BUG(); - } - - rt = ip_route_output_key(&init_net, &fl); + rt = ip_route_output_ports(&init_net, NULL, + peer->srx.transport.sin.sin_addr.s_addr, 0, + htons(7000), htons(7001), + IPPROTO_UDP, 0, 0); if (IS_ERR(rt)) { _leave(" [route err %ld]", PTR_ERR(rt)); return; -- cgit v1.2.3 From 1d28f42c1bd4bb2363d88df74d0128b4da135b4a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 12 Mar 2011 00:29:39 -0500 Subject: net: Put flowi_* prefix on AF independent members of struct flowi I intend to turn struct flowi into a union of AF specific flowi structs. There will be a common structure that each variant includes first, much like struct sock_common. This is the first step to move in that direction. Signed-off-by: David S. Miller --- drivers/infiniband/core/addr.c | 2 +- drivers/net/cnic.c | 2 +- include/net/dn_route.h | 4 +- include/net/flow.h | 22 ++++----- include/net/route.h | 36 +++++++-------- include/net/xfrm.h | 4 +- net/core/fib_rules.c | 6 +-- net/dccp/ipv4.c | 17 +++---- net/dccp/ipv6.c | 20 ++++----- net/decnet/af_decnet.c | 4 +- net/decnet/dn_fib.c | 4 +- net/decnet/dn_nsp_out.c | 4 +- net/decnet/dn_route.c | 96 +++++++++++++++++++++------------------- net/ipv4/fib_frontend.c | 12 ++--- net/ipv4/fib_semantics.c | 2 +- net/ipv4/fib_trie.c | 2 +- net/ipv4/icmp.c | 12 ++--- net/ipv4/inet_connection_sock.c | 22 ++++----- net/ipv4/ip_output.c | 18 ++++---- net/ipv4/ipmr.c | 12 ++--- net/ipv4/netfilter.c | 6 +-- net/ipv4/raw.c | 10 ++--- net/ipv4/route.c | 72 +++++++++++++++--------------- net/ipv4/syncookies.c | 20 +++++---- net/ipv4/udp.c | 21 ++++----- net/ipv4/xfrm4_policy.c | 10 ++--- net/ipv4/xfrm4_state.c | 4 +- net/ipv6/af_inet6.c | 6 +-- net/ipv6/datagram.c | 20 ++++----- net/ipv6/icmp.c | 24 +++++----- net/ipv6/inet6_connection_sock.c | 12 ++--- net/ipv6/ip6_flowlabel.c | 2 +- net/ipv6/ip6_output.c | 10 ++--- net/ipv6/ip6_tunnel.c | 8 ++-- net/ipv6/ip6mr.c | 22 ++++----- net/ipv6/ipv6_sockglue.c | 4 +- net/ipv6/mip6.c | 6 +-- net/ipv6/netfilter.c | 4 +- net/ipv6/netfilter/ip6t_REJECT.c | 2 +- net/ipv6/raw.c | 20 ++++----- net/ipv6/route.c | 20 ++++----- net/ipv6/syncookies.c | 6 +-- net/ipv6/tcp_ipv6.c | 22 ++++----- net/ipv6/udp.c | 20 ++++----- net/ipv6/xfrm6_policy.c | 10 ++--- net/ipv6/xfrm6_state.c | 4 +- net/netfilter/ipvs/ip_vs_ctl.c | 2 +- net/netfilter/ipvs/ip_vs_xmit.c | 2 +- net/netfilter/xt_TEE.c | 4 +- net/sctp/ipv6.c | 8 ++-- net/sctp/protocol.c | 4 +- net/xfrm/xfrm_policy.c | 18 ++++---- net/xfrm/xfrm_state.c | 2 +- security/security.c | 4 +- security/selinux/hooks.c | 2 +- security/selinux/xfrm.c | 4 +- 56 files changed, 365 insertions(+), 351 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 1742f72fbd57..3c2b309ab891 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -239,7 +239,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in, memset(&fl, 0, sizeof fl); ipv6_addr_copy(&fl.fl6_dst, &dst_in->sin6_addr); ipv6_addr_copy(&fl.fl6_src, &src_in->sin6_addr); - fl.oif = addr->bound_dev_if; + fl.flowi_oif = addr->bound_dev_if; dst = ip6_route_output(&init_net, NULL, &fl); if ((ret = dst->error)) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 65832951fe07..c8922f69705e 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -3429,7 +3429,7 @@ static int cnic_get_v6_route(struct sockaddr_in6 *dst_addr, memset(&fl, 0, sizeof(fl)); ipv6_addr_copy(&fl.fl6_dst, &dst_addr->sin6_addr); if (ipv6_addr_type(&fl.fl6_dst) & IPV6_ADDR_LINKLOCAL) - fl.oif = dst_addr->sin6_scope_id; + fl.flowi_oif = dst_addr->sin6_scope_id; *dst = ip6_route_output(&init_net, NULL, &fl); if (*dst) diff --git a/include/net/dn_route.h b/include/net/dn_route.h index 9b185df265fb..1f59005e4979 100644 --- a/include/net/dn_route.h +++ b/include/net/dn_route.h @@ -82,12 +82,12 @@ struct dn_route { static inline bool dn_is_input_route(struct dn_route *rt) { - return rt->fl.iif != 0; + return rt->fl.flowi_iif != 0; } static inline bool dn_is_output_route(struct dn_route *rt) { - return rt->fl.iif == 0; + return rt->fl.flowi_iif == 0; } extern void dn_route_init(void); diff --git a/include/net/flow.h b/include/net/flow.h index a661fd6f76ba..8c4dbd078490 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -11,17 +11,17 @@ #include struct flowi { - int oif; - int iif; - __u32 mark; - __u8 tos; - __u8 scope; - __u8 proto; - __u8 flags; + int flowi_oif; + int flowi_iif; + __u32 flowi_mark; + __u8 flowi_tos; + __u8 flowi_scope; + __u8 flowi_proto; + __u8 flowi_flags; #define FLOWI_FLAG_ANYSRC 0x01 #define FLOWI_FLAG_PRECOW_METRICS 0x02 #define FLOWI_FLAG_CAN_SLEEP 0x04 - __u32 secid; + __u32 flowi_secid; union { struct { @@ -49,8 +49,8 @@ struct flowi { #define fl6_flowlabel nl_u.ip6_u.flowlabel #define fl4_dst nl_u.ip4_u.daddr #define fl4_src nl_u.ip4_u.saddr -#define fl4_tos tos -#define fl4_scope scope +#define fl4_tos flowi_tos +#define fl4_scope flowi_scope union { struct { @@ -116,7 +116,7 @@ extern atomic_t flow_cache_genid; static inline int flow_cache_uli_match(const struct flowi *fl1, const struct flowi *fl2) { - return (fl1->proto == fl2->proto && + return (fl1->flowi_proto == fl2->flowi_proto && !memcmp(&fl1->uli_u, &fl2->uli_u, sizeof(fl1->uli_u))); } diff --git a/include/net/route.h b/include/net/route.h index f140f4130fea..3d814f84abd0 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -136,7 +136,7 @@ static inline struct rtable *ip_route_output(struct net *net, __be32 daddr, __be32 saddr, u8 tos, int oif) { struct flowi fl = { - .oif = oif, + .flowi_oif = oif, .fl4_dst = daddr, .fl4_src = saddr, .fl4_tos = tos, @@ -150,13 +150,13 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct sock __u8 proto, __u8 tos, int oif) { struct flowi fl = { - .oif = oif, - .flags = sk ? inet_sk_flowi_flags(sk) : 0, - .mark = sk ? sk->sk_mark : 0, + .flowi_oif = oif, + .flowi_flags = sk ? inet_sk_flowi_flags(sk) : 0, + .flowi_mark = sk ? sk->sk_mark : 0, .fl4_dst = daddr, .fl4_src = saddr, .fl4_tos = tos, - .proto = proto, + .flowi_proto = proto, .fl_ip_dport = dport, .fl_ip_sport = sport, }; @@ -170,11 +170,11 @@ static inline struct rtable *ip_route_output_gre(struct net *net, __be32 gre_key, __u8 tos, int oif) { struct flowi fl = { - .oif = oif, + .flowi_oif = oif, .fl4_dst = daddr, .fl4_src = saddr, .fl4_tos = tos, - .proto = IPPROTO_GRE, + .flowi_proto = IPPROTO_GRE, .fl_gre_key = gre_key, }; return ip_route_output_key(net, &fl); @@ -228,23 +228,23 @@ static inline struct rtable *ip_route_connect(__be32 dst, __be32 src, u32 tos, __be16 sport, __be16 dport, struct sock *sk, bool can_sleep) { - struct flowi fl = { .oif = oif, - .mark = sk->sk_mark, + struct flowi fl = { .flowi_oif = oif, + .flowi_mark = sk->sk_mark, .fl4_dst = dst, .fl4_src = src, .fl4_tos = tos, - .proto = protocol, + .flowi_proto = protocol, .fl_ip_sport = sport, .fl_ip_dport = dport }; struct net *net = sock_net(sk); struct rtable *rt; if (inet_sk(sk)->transparent) - fl.flags |= FLOWI_FLAG_ANYSRC; + fl.flowi_flags |= FLOWI_FLAG_ANYSRC; if (protocol == IPPROTO_TCP) - fl.flags |= FLOWI_FLAG_PRECOW_METRICS; + fl.flowi_flags |= FLOWI_FLAG_PRECOW_METRICS; if (can_sleep) - fl.flags |= FLOWI_FLAG_CAN_SLEEP; + fl.flowi_flags |= FLOWI_FLAG_CAN_SLEEP; if (!dst || !src) { rt = __ip_route_output_key(net, &fl); @@ -264,19 +264,19 @@ static inline struct rtable *ip_route_newports(struct rtable *rt, __be16 dport, struct sock *sk) { if (sport != orig_sport || dport != orig_dport) { - struct flowi fl = { .oif = rt->rt_oif, - .mark = rt->rt_mark, + struct flowi fl = { .flowi_oif = rt->rt_oif, + .flowi_mark = rt->rt_mark, .fl4_dst = rt->rt_key_dst, .fl4_src = rt->rt_key_src, .fl4_tos = rt->rt_tos, - .proto = protocol, + .flowi_proto = protocol, .fl_ip_sport = sport, .fl_ip_dport = dport }; if (inet_sk(sk)->transparent) - fl.flags |= FLOWI_FLAG_ANYSRC; + fl.flowi_flags |= FLOWI_FLAG_ANYSRC; if (protocol == IPPROTO_TCP) - fl.flags |= FLOWI_FLAG_PRECOW_METRICS; + fl.flowi_flags |= FLOWI_FLAG_PRECOW_METRICS; ip_rt_put(rt); security_sk_classify_flow(sk, &fl); return ip_route_output_flow(sock_net(sk), &fl, sk); diff --git a/include/net/xfrm.h b/include/net/xfrm.h index d5dcf3974636..d5a12d10a0d4 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -803,7 +803,7 @@ static __inline__ __be16 xfrm_flowi_sport(const struct flowi *fl) { __be16 port; - switch(fl->proto) { + switch(fl->flowi_proto) { case IPPROTO_TCP: case IPPROTO_UDP: case IPPROTO_UDPLITE: @@ -830,7 +830,7 @@ static __inline__ __be16 xfrm_flowi_dport(const struct flowi *fl) { __be16 port; - switch(fl->proto) { + switch(fl->flowi_proto) { case IPPROTO_TCP: case IPPROTO_UDP: case IPPROTO_UDPLITE: diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index a20e5d3bbfa0..8248ebb5891d 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -181,13 +181,13 @@ static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops, { int ret = 0; - if (rule->iifindex && (rule->iifindex != fl->iif)) + if (rule->iifindex && (rule->iifindex != fl->flowi_iif)) goto out; - if (rule->oifindex && (rule->oifindex != fl->oif)) + if (rule->oifindex && (rule->oifindex != fl->flowi_oif)) goto out; - if ((rule->mark ^ fl->mark) & rule->mark_mask) + if ((rule->mark ^ fl->flowi_mark) & rule->mark_mask) goto out; ret = ops->match(rule, fl, flags); diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 7882377bc62e..09a09911c5ea 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -465,14 +465,15 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk, struct sk_buff *skb) { struct rtable *rt; - struct flowi fl = { .oif = skb_rtable(skb)->rt_iif, - .fl4_dst = ip_hdr(skb)->saddr, - .fl4_src = ip_hdr(skb)->daddr, - .fl4_tos = RT_CONN_FLAGS(sk), - .proto = sk->sk_protocol, - .fl_ip_sport = dccp_hdr(skb)->dccph_dport, - .fl_ip_dport = dccp_hdr(skb)->dccph_sport - }; + struct flowi fl = { + .flowi_oif = skb_rtable(skb)->rt_iif, + .fl4_dst = ip_hdr(skb)->saddr, + .fl4_src = ip_hdr(skb)->daddr, + .fl4_tos = RT_CONN_FLAGS(sk), + .flowi_proto = sk->sk_protocol, + .fl_ip_sport = dccp_hdr(skb)->dccph_dport, + .fl_ip_dport = dccp_hdr(skb)->dccph_sport, + }; security_skb_classify_flow(skb, &fl); rt = ip_route_output_flow(net, &fl, sk); diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 5efc57f5e605..5209ee7a3dc2 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -154,10 +154,10 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, for now. */ memset(&fl, 0, sizeof(fl)); - fl.proto = IPPROTO_DCCP; + fl.flowi_proto = IPPROTO_DCCP; ipv6_addr_copy(&fl.fl6_dst, &np->daddr); ipv6_addr_copy(&fl.fl6_src, &np->saddr); - fl.oif = sk->sk_bound_dev_if; + fl.flowi_oif = sk->sk_bound_dev_if; fl.fl_ip_dport = inet->inet_dport; fl.fl_ip_sport = inet->inet_sport; security_sk_classify_flow(sk, &fl); @@ -248,11 +248,11 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req, struct dst_entry *dst; memset(&fl, 0, sizeof(fl)); - fl.proto = IPPROTO_DCCP; + fl.flowi_proto = IPPROTO_DCCP; ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr); ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr); fl.fl6_flowlabel = 0; - fl.oif = ireq6->iif; + fl.flowi_oif = ireq6->iif; fl.fl_ip_dport = inet_rsk(req)->rmt_port; fl.fl_ip_sport = inet_rsk(req)->loc_port; security_req_classify_flow(req, &fl); @@ -321,8 +321,8 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb) ipv6_addr_copy(&fl.fl6_dst, &rxip6h->saddr); ipv6_addr_copy(&fl.fl6_src, &rxip6h->daddr); - fl.proto = IPPROTO_DCCP; - fl.oif = inet6_iif(rxskb); + fl.flowi_proto = IPPROTO_DCCP; + fl.flowi_oif = inet6_iif(rxskb); fl.fl_ip_dport = dccp_hdr(skb)->dccph_dport; fl.fl_ip_sport = dccp_hdr(skb)->dccph_sport; security_skb_classify_flow(rxskb, &fl); @@ -530,11 +530,11 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, struct flowi fl; memset(&fl, 0, sizeof(fl)); - fl.proto = IPPROTO_DCCP; + fl.flowi_proto = IPPROTO_DCCP; ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr); final_p = fl6_update_dst(&fl, opt, &final); ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr); - fl.oif = sk->sk_bound_dev_if; + fl.flowi_oif = sk->sk_bound_dev_if; fl.fl_ip_dport = inet_rsk(req)->rmt_port; fl.fl_ip_sport = inet_rsk(req)->loc_port; security_sk_classify_flow(sk, &fl); @@ -953,10 +953,10 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, if (!ipv6_addr_any(&np->rcv_saddr)) saddr = &np->rcv_saddr; - fl.proto = IPPROTO_DCCP; + fl.flowi_proto = IPPROTO_DCCP; ipv6_addr_copy(&fl.fl6_dst, &np->daddr); ipv6_addr_copy(&fl.fl6_src, saddr ? saddr : &np->saddr); - fl.oif = sk->sk_bound_dev_if; + fl.flowi_oif = sk->sk_bound_dev_if; fl.fl_ip_dport = usin->sin6_port; fl.fl_ip_sport = inet->inet_sport; security_sk_classify_flow(sk, &fl); diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 2af15b15d1fa..aafd15a01575 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -948,11 +948,11 @@ static int __dn_connect(struct sock *sk, struct sockaddr_dn *addr, int addrlen, err = -EHOSTUNREACH; memset(&fl, 0, sizeof(fl)); - fl.oif = sk->sk_bound_dev_if; + fl.flowi_oif = sk->sk_bound_dev_if; fl.fld_dst = dn_saddr2dn(&scp->peer); fl.fld_src = dn_saddr2dn(&scp->addr); dn_sk_ports_copy(&fl, scp); - fl.proto = DNPROTO_NSP; + fl.flowi_proto = DNPROTO_NSP; if (dn_route_output_sock(&sk->sk_dst_cache, &fl, sk, flags) < 0) goto out; sk->sk_route_caps = sk->sk_dst_cache->dev->features; diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index 0ef0a81bcd72..4dfffa0b67a8 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c @@ -223,7 +223,7 @@ static int dn_fib_check_nh(const struct rtmsg *r, struct dn_fib_info *fi, struct memset(&fl, 0, sizeof(fl)); fl.fld_dst = nh->nh_gw; - fl.oif = nh->nh_oif; + fl.flowi_oif = nh->nh_oif; fl.fld_scope = r->rtm_scope + 1; if (fl.fld_scope < RT_SCOPE_LINK) @@ -424,7 +424,7 @@ int dn_fib_semantic_match(int type, struct dn_fib_info *fi, const struct flowi * for_nexthops(fi) { if (nh->nh_flags & RTNH_F_DEAD) continue; - if (!fl->oif || fl->oif == nh->nh_oif) + if (!fl->flowi_oif || fl->flowi_oif == nh->nh_oif) break; } if (nhsel < fi->fib_nhs) { diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c index 2ef115277bea..b3d66742a01f 100644 --- a/net/decnet/dn_nsp_out.c +++ b/net/decnet/dn_nsp_out.c @@ -92,11 +92,11 @@ try_again: } memset(&fl, 0, sizeof(fl)); - fl.oif = sk->sk_bound_dev_if; + fl.flowi_oif = sk->sk_bound_dev_if; fl.fld_src = dn_saddr2dn(&scp->addr); fl.fld_dst = dn_saddr2dn(&scp->peer); dn_sk_ports_copy(&fl, scp); - fl.proto = DNPROTO_NSP; + fl.flowi_proto = DNPROTO_NSP; if (dn_route_output_sock(&sk->sk_dst_cache, &fl, sk, 0) == 0) { dst = sk_dst_get(sk); sk->sk_route_caps = dst->dev->features; diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 484fdbf92bd8..d74d34b93f80 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -286,10 +286,10 @@ static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) { return ((fl1->fld_dst ^ fl2->fld_dst) | (fl1->fld_src ^ fl2->fld_src) | - (fl1->mark ^ fl2->mark) | + (fl1->flowi_mark ^ fl2->flowi_mark) | (fl1->fld_scope ^ fl2->fld_scope) | - (fl1->oif ^ fl2->oif) | - (fl1->iif ^ fl2->iif)) == 0; + (fl1->flowi_oif ^ fl2->flowi_oif) | + (fl1->flowi_iif ^ fl2->flowi_iif)) == 0; } static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route **rp) @@ -905,12 +905,14 @@ static inline __le16 dn_fib_rules_map_destination(__le16 daddr, struct dn_fib_re static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *oldflp, int try_hard) { - struct flowi fl = { .fld_dst = oldflp->fld_dst, - .fld_src = oldflp->fld_src, - .fld_scope = RT_SCOPE_UNIVERSE, - .mark = oldflp->mark, - .iif = init_net.loopback_dev->ifindex, - .oif = oldflp->oif }; + struct flowi fl = { + .fld_dst = oldflp->fld_dst, + .fld_src = oldflp->fld_src, + .fld_scope = RT_SCOPE_UNIVERSE, + .flowi_mark = oldflp->flowi_mark, + .flowi_iif = init_net.loopback_dev->ifindex, + .flowi_oif = oldflp->flowi_oif, + }; struct dn_route *rt = NULL; struct net_device *dev_out = NULL, *dev; struct neighbour *neigh = NULL; @@ -926,11 +928,11 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old "dn_route_output_slow: dst=%04x src=%04x mark=%d" " iif=%d oif=%d\n", le16_to_cpu(oldflp->fld_dst), le16_to_cpu(oldflp->fld_src), - oldflp->mark, init_net.loopback_dev->ifindex, oldflp->oif); + oldflp->flowi_mark, init_net.loopback_dev->ifindex, oldflp->flowi_oif); /* If we have an output interface, verify its a DECnet device */ - if (oldflp->oif) { - dev_out = dev_get_by_index(&init_net, oldflp->oif); + if (oldflp->flowi_oif) { + dev_out = dev_get_by_index(&init_net, oldflp->flowi_oif); err = -ENODEV; if (dev_out && dev_out->dn_ptr == NULL) { dev_put(dev_out); @@ -988,7 +990,7 @@ source_ok: if (!fl.fld_dst) goto out; } - fl.oif = init_net.loopback_dev->ifindex; + fl.flowi_oif = init_net.loopback_dev->ifindex; res.type = RTN_LOCAL; goto make_route; } @@ -998,7 +1000,7 @@ source_ok: "dn_route_output_slow: initial checks complete." " dst=%o4x src=%04x oif=%d try_hard=%d\n", le16_to_cpu(fl.fld_dst), le16_to_cpu(fl.fld_src), - fl.oif, try_hard); + fl.flowi_oif, try_hard); /* * N.B. If the kernel is compiled without router support then @@ -1023,8 +1025,8 @@ source_ok: if (!try_hard) { neigh = neigh_lookup_nodev(&dn_neigh_table, &init_net, &fl.fld_dst); if (neigh) { - if ((oldflp->oif && - (neigh->dev->ifindex != oldflp->oif)) || + if ((oldflp->flowi_oif && + (neigh->dev->ifindex != oldflp->flowi_oif)) || (oldflp->fld_src && (!dn_dev_islocal(neigh->dev, oldflp->fld_src)))) { @@ -1078,7 +1080,7 @@ select_source: if (fl.fld_src == 0 && res.type != RTN_LOCAL) goto e_addr; } - fl.oif = dev_out->ifindex; + fl.flowi_oif = dev_out->ifindex; goto make_route; } free_res = 1; @@ -1093,14 +1095,14 @@ select_source: dev_put(dev_out); dev_out = init_net.loopback_dev; dev_hold(dev_out); - fl.oif = dev_out->ifindex; + fl.flowi_oif = dev_out->ifindex; if (res.fi) dn_fib_info_put(res.fi); res.fi = NULL; goto make_route; } - if (res.fi->fib_nhs > 1 && fl.oif == 0) + if (res.fi->fib_nhs > 1 && fl.flowi_oif == 0) dn_fib_select_multipath(&fl, &res); /* @@ -1115,7 +1117,7 @@ select_source: dev_put(dev_out); dev_out = DN_FIB_RES_DEV(res); dev_hold(dev_out); - fl.oif = dev_out->ifindex; + fl.flowi_oif = dev_out->ifindex; gateway = DN_FIB_RES_GW(res); make_route: @@ -1131,9 +1133,9 @@ make_route: rt->fl.fld_src = oldflp->fld_src; rt->fl.fld_dst = oldflp->fld_dst; - rt->fl.oif = oldflp->oif; - rt->fl.iif = 0; - rt->fl.mark = oldflp->mark; + rt->fl.flowi_oif = oldflp->flowi_oif; + rt->fl.flowi_iif = 0; + rt->fl.flowi_mark = oldflp->flowi_mark; rt->rt_saddr = fl.fld_src; rt->rt_daddr = fl.fld_dst; @@ -1201,9 +1203,9 @@ static int __dn_route_output_key(struct dst_entry **pprt, const struct flowi *fl rt = rcu_dereference_bh(rt->dst.dn_next)) { if ((flp->fld_dst == rt->fl.fld_dst) && (flp->fld_src == rt->fl.fld_src) && - (flp->mark == rt->fl.mark) && + (flp->flowi_mark == rt->fl.flowi_mark) && dn_is_output_route(rt) && - (rt->fl.oif == flp->oif)) { + (rt->fl.flowi_oif == flp->flowi_oif)) { dst_use(&rt->dst, jiffies); rcu_read_unlock_bh(); *pprt = &rt->dst; @@ -1221,7 +1223,7 @@ static int dn_route_output_key(struct dst_entry **pprt, struct flowi *flp, int f int err; err = __dn_route_output_key(pprt, flp, flags); - if (err == 0 && flp->proto) { + if (err == 0 && flp->flowi_proto) { *pprt = xfrm_lookup(&init_net, *pprt, flp, NULL, 0); if (IS_ERR(*pprt)) { err = PTR_ERR(*pprt); @@ -1236,9 +1238,9 @@ int dn_route_output_sock(struct dst_entry **pprt, struct flowi *fl, struct sock int err; err = __dn_route_output_key(pprt, fl, flags & MSG_TRYHARD); - if (err == 0 && fl->proto) { + if (err == 0 && fl->flowi_proto) { if (!(flags & MSG_DONTWAIT)) - fl->flags |= FLOWI_FLAG_CAN_SLEEP; + fl->flowi_flags |= FLOWI_FLAG_CAN_SLEEP; *pprt = xfrm_lookup(&init_net, *pprt, fl, sk, 0); if (IS_ERR(*pprt)) { err = PTR_ERR(*pprt); @@ -1260,11 +1262,13 @@ static int dn_route_input_slow(struct sk_buff *skb) int flags = 0; __le16 gateway = 0; __le16 local_src = 0; - struct flowi fl = { .fld_dst = cb->dst, - .fld_src = cb->src, - .fld_scope = RT_SCOPE_UNIVERSE, - .mark = skb->mark, - .iif = skb->dev->ifindex }; + struct flowi fl = { + .fld_dst = cb->dst, + .fld_src = cb->src, + .fld_scope = RT_SCOPE_UNIVERSE, + .flowi_mark = skb->mark, + .flowi_iif = skb->dev->ifindex, + }; struct dn_fib_res res = { .fi = NULL, .type = RTN_UNREACHABLE }; int err = -EINVAL; int free_res = 0; @@ -1343,7 +1347,7 @@ static int dn_route_input_slow(struct sk_buff *skb) if (dn_db->parms.forwarding == 0) goto e_inval; - if (res.fi->fib_nhs > 1 && fl.oif == 0) + if (res.fi->fib_nhs > 1 && fl.flowi_oif == 0) dn_fib_select_multipath(&fl, &res); /* @@ -1408,9 +1412,9 @@ make_route: rt->fl.fld_src = cb->src; rt->fl.fld_dst = cb->dst; - rt->fl.oif = 0; - rt->fl.iif = in_dev->ifindex; - rt->fl.mark = fl.mark; + rt->fl.flowi_oif = 0; + rt->fl.flowi_iif = in_dev->ifindex; + rt->fl.flowi_mark = fl.flowi_mark; rt->dst.flags = DST_HOST; rt->dst.neighbour = neigh; @@ -1482,9 +1486,9 @@ static int dn_route_input(struct sk_buff *skb) rt = rcu_dereference(rt->dst.dn_next)) { if ((rt->fl.fld_src == cb->src) && (rt->fl.fld_dst == cb->dst) && - (rt->fl.oif == 0) && - (rt->fl.mark == skb->mark) && - (rt->fl.iif == cb->iif)) { + (rt->fl.flowi_oif == 0) && + (rt->fl.flowi_mark == skb->mark) && + (rt->fl.flowi_iif == cb->iif)) { dst_use(&rt->dst, jiffies); rcu_read_unlock(); skb_dst_set(skb, (struct dst_entry *)rt); @@ -1541,7 +1545,7 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, rt->dst.error) < 0) goto rtattr_failure; if (dn_is_input_route(rt)) - RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fl.iif); + RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fl.flowi_iif); nlh->nlmsg_len = skb_tail_pointer(skb) - b; return skb->len; @@ -1570,7 +1574,7 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void return -EINVAL; memset(&fl, 0, sizeof(fl)); - fl.proto = DNPROTO_NSP; + fl.flowi_proto = DNPROTO_NSP; skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); if (skb == NULL) @@ -1583,11 +1587,11 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void if (rta[RTA_DST-1]) memcpy(&fl.fld_dst, RTA_DATA(rta[RTA_DST-1]), 2); if (rta[RTA_IIF-1]) - memcpy(&fl.iif, RTA_DATA(rta[RTA_IIF-1]), sizeof(int)); + memcpy(&fl.flowi_iif, RTA_DATA(rta[RTA_IIF-1]), sizeof(int)); - if (fl.iif) { + if (fl.flowi_iif) { struct net_device *dev; - if ((dev = dev_get_by_index(&init_net, fl.iif)) == NULL) { + if ((dev = dev_get_by_index(&init_net, fl.flowi_iif)) == NULL) { kfree_skb(skb); return -ENODEV; } @@ -1611,7 +1615,7 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void int oif = 0; if (rta[RTA_OIF - 1]) memcpy(&oif, RTA_DATA(rta[RTA_OIF - 1]), sizeof(int)); - fl.oif = oif; + fl.flowi_oif = oif; err = dn_route_output_key((struct dst_entry **)&rt, &fl, 0); } diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index fe10bcd0f307..76105284a81c 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -200,9 +200,9 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, int ret; struct net *net; - fl.oif = 0; - fl.iif = oif; - fl.mark = mark; + fl.flowi_oif = 0; + fl.flowi_iif = oif; + fl.flowi_mark = mark; fl.fl4_dst = src; fl.fl4_src = dst; fl.fl4_tos = tos; @@ -215,7 +215,7 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, rpf = IN_DEV_RPFILTER(in_dev); accept_local = IN_DEV_ACCEPT_LOCAL(in_dev); if (mark && !IN_DEV_SRC_VMARK(in_dev)) - fl.mark = 0; + fl.flowi_mark = 0; } if (in_dev == NULL) @@ -253,7 +253,7 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, goto last_resort; if (rpf == 1) goto e_rpf; - fl.oif = dev->ifindex; + fl.flowi_oif = dev->ifindex; ret = 0; if (fib_lookup(net, &fl, &res) == 0) { @@ -797,7 +797,7 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb) struct fib_result res; struct flowi fl = { - .mark = frn->fl_mark, + .flowi_mark = frn->fl_mark, .fl4_dst = frn->fl_addr, .fl4_tos = frn->fl_tos, .fl4_scope = frn->fl_scope, diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index b5d523b911e6..79179ade5294 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -563,7 +563,7 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, struct flowi fl = { .fl4_dst = nh->nh_gw, .fl4_scope = cfg->fc_scope + 1, - .oif = nh->nh_oif, + .flowi_oif = nh->nh_oif, }; /* It is not necessary, but requires a bit of thinking */ diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index a4109a544778..d5ff80ef001a 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1379,7 +1379,7 @@ static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l, if (nh->nh_flags & RTNH_F_DEAD) continue; - if (flp->oif && flp->oif != nh->nh_oif) + if (flp->flowi_oif && flp->flowi_oif != nh->nh_oif) continue; #ifdef CONFIG_IP_FIB_TRIE_STATS diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 1771ce662548..3fde7f23c70b 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -353,10 +353,12 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) daddr = icmp_param->replyopts.faddr; } { - struct flowi fl = { .fl4_dst= daddr, - .fl4_src = rt->rt_spec_dst, - .fl4_tos = RT_TOS(ip_hdr(skb)->tos), - .proto = IPPROTO_ICMP }; + struct flowi fl = { + .fl4_dst = daddr, + .fl4_src = rt->rt_spec_dst, + .fl4_tos = RT_TOS(ip_hdr(skb)->tos), + .flowi_proto = IPPROTO_ICMP, + }; security_skb_classify_flow(skb, &fl); rt = ip_route_output_key(net, &fl); if (IS_ERR(rt)) @@ -381,7 +383,7 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in, param->replyopts.faddr : iph->saddr), .fl4_src = saddr, .fl4_tos = RT_TOS(tos), - .proto = IPPROTO_ICMP, + .flowi_proto = IPPROTO_ICMP, .fl_icmp_type = type, .fl_icmp_code = code, }; diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index e4e301a61c5b..97081702dffd 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -356,16 +356,18 @@ struct dst_entry *inet_csk_route_req(struct sock *sk, struct rtable *rt; const struct inet_request_sock *ireq = inet_rsk(req); struct ip_options *opt = inet_rsk(req)->opt; - struct flowi fl = { .oif = sk->sk_bound_dev_if, - .mark = sk->sk_mark, - .fl4_dst = ((opt && opt->srr) ? - opt->faddr : ireq->rmt_addr), - .fl4_src = ireq->loc_addr, - .fl4_tos = RT_CONN_FLAGS(sk), - .proto = sk->sk_protocol, - .flags = inet_sk_flowi_flags(sk), - .fl_ip_sport = inet_sk(sk)->inet_sport, - .fl_ip_dport = ireq->rmt_port }; + struct flowi fl = { + .flowi_oif = sk->sk_bound_dev_if, + .flowi_mark = sk->sk_mark, + .fl4_dst = ((opt && opt->srr) ? + opt->faddr : ireq->rmt_addr), + .fl4_src = ireq->loc_addr, + .fl4_tos = RT_CONN_FLAGS(sk), + .flowi_proto = sk->sk_protocol, + .flowi_flags = inet_sk_flowi_flags(sk), + .fl_ip_sport = inet_sk(sk)->inet_sport, + .fl_ip_dport = ireq->rmt_port, + }; struct net *net = sock_net(sk); security_req_classify_flow(req, &fl); diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 916152dbdce4..e35ca40df03b 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -1474,14 +1474,16 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar } { - struct flowi fl = { .oif = arg->bound_dev_if, - .fl4_dst = daddr, - .fl4_src = rt->rt_spec_dst, - .fl4_tos = RT_TOS(ip_hdr(skb)->tos), - .fl_ip_sport = tcp_hdr(skb)->dest, - .fl_ip_dport = tcp_hdr(skb)->source, - .proto = sk->sk_protocol, - .flags = ip_reply_arg_flowi_flags(arg) }; + struct flowi fl = { + .flowi_oif = arg->bound_dev_if, + .fl4_dst = daddr, + .fl4_src = rt->rt_spec_dst, + .fl4_tos = RT_TOS(ip_hdr(skb)->tos), + .fl_ip_sport = tcp_hdr(skb)->dest, + .fl_ip_dport = tcp_hdr(skb)->source, + .flowi_proto = sk->sk_protocol, + .flowi_flags = ip_reply_arg_flowi_flags(arg), + }; security_skb_classify_flow(skb, &fl); rt = ip_route_output_key(sock_net(sk), &fl); if (IS_ERR(rt)) diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 594a3004367b..3b72b0a26d7e 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -436,9 +436,9 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) struct net *net = dev_net(dev); struct mr_table *mrt; struct flowi fl = { - .oif = dev->ifindex, - .iif = skb->skb_iif, - .mark = skb->mark, + .flowi_oif = dev->ifindex, + .flowi_iif = skb->skb_iif, + .flowi_mark = skb->mark, }; int err; @@ -1793,9 +1793,9 @@ static struct mr_table *ipmr_rt_fib_lookup(struct net *net, struct rtable *rt) .fl4_dst = rt->rt_key_dst, .fl4_src = rt->rt_key_src, .fl4_tos = rt->rt_tos, - .oif = rt->rt_oif, - .iif = rt->rt_iif, - .mark = rt->rt_mark, + .flowi_oif = rt->rt_oif, + .flowi_iif = rt->rt_iif, + .flowi_mark = rt->rt_mark, }; struct mr_table *mrt; int err; diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index 67bf709180de..6f40ba511c6b 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c @@ -35,9 +35,9 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) if (type == RTN_LOCAL) fl.fl4_src = iph->saddr; fl.fl4_tos = RT_TOS(iph->tos); - fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; - fl.mark = skb->mark; - fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; + fl.flowi_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; + fl.flowi_mark = skb->mark; + fl.flowi_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; rt = ip_route_output_key(net, &fl); if (IS_ERR(rt)) return -1; diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 467d570d087a..b42b7cd56c03 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -418,7 +418,7 @@ static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) if (!iov) continue; - switch (fl->proto) { + switch (fl->flowi_proto) { case IPPROTO_ICMP: /* check if one-byte field is readable or not. */ if (iov->iov_base && iov->iov_len < 1) @@ -548,14 +548,14 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, } { - struct flowi fl = { .oif = ipc.oif, - .mark = sk->sk_mark, + struct flowi fl = { .flowi_oif = ipc.oif, + .flowi_mark = sk->sk_mark, .fl4_dst = daddr, .fl4_src = saddr, .fl4_tos = tos, - .proto = inet->hdrincl ? IPPROTO_RAW : + .flowi_proto = inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, - .flags = FLOWI_FLAG_CAN_SLEEP, + .flowi_flags = FLOWI_FLAG_CAN_SLEEP, }; if (!inet->hdrincl) { err = raw_probe_proto_opt(&fl, msg); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 9c17e32d5623..c9aa4f9effe2 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1701,9 +1701,9 @@ void ip_rt_get_source(u8 *addr, struct rtable *rt) .fl4_dst = rt->rt_key_dst, .fl4_src = rt->rt_key_src, .fl4_tos = rt->rt_tos, - .oif = rt->rt_oif, - .iif = rt->rt_iif, - .mark = rt->rt_mark, + .flowi_oif = rt->rt_oif, + .flowi_iif = rt->rt_iif, + .flowi_mark = rt->rt_mark, }; rcu_read_lock(); @@ -1766,7 +1766,7 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi *oldflp, /* If a peer entry exists for this destination, we must hook * it up in order to get at cached metrics. */ - if (oldflp && (oldflp->flags & FLOWI_FLAG_PRECOW_METRICS)) + if (oldflp && (oldflp->flowi_flags & FLOWI_FLAG_PRECOW_METRICS)) create = 1; rt->peer = peer = inet_getpeer_v4(rt->rt_dst, create); @@ -2057,9 +2057,9 @@ static int ip_mkroute_input(struct sk_buff *skb, return err; /* put it into the cache */ - hash = rt_hash(daddr, saddr, fl->iif, + hash = rt_hash(daddr, saddr, fl->flowi_iif, rt_genid(dev_net(rth->dst.dev))); - rth = rt_intern_hash(hash, rth, skb, fl->iif); + rth = rt_intern_hash(hash, rth, skb, fl->flowi_iif); if (IS_ERR(rth)) return PTR_ERR(rth); return 0; @@ -2118,9 +2118,9 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, /* * Now we are ready to route packet. */ - fl.oif = 0; - fl.iif = dev->ifindex; - fl.mark = skb->mark; + fl.flowi_oif = 0; + fl.flowi_iif = dev->ifindex; + fl.flowi_mark = skb->mark; fl.fl4_dst = daddr; fl.fl4_src = saddr; fl.fl4_tos = tos; @@ -2205,8 +2205,8 @@ local_input: rth->rt_flags &= ~RTCF_LOCAL; } rth->rt_type = res.type; - hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); - rth = rt_intern_hash(hash, rth, skb, fl.iif); + hash = rt_hash(daddr, saddr, fl.flowi_iif, rt_genid(net)); + rth = rt_intern_hash(hash, rth, skb, fl.flowi_iif); err = 0; if (IS_ERR(rth)) err = PTR_ERR(rth); @@ -2369,7 +2369,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res, } else if (type == RTN_MULTICAST) { flags |= RTCF_MULTICAST | RTCF_LOCAL; if (!ip_check_mc_rcu(in_dev, oldflp->fl4_dst, oldflp->fl4_src, - oldflp->proto)) + oldflp->flowi_proto)) flags &= ~RTCF_LOCAL; /* If multicast route do not exist use * default one, but do not gateway in this case. @@ -2387,8 +2387,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res, rth->rt_key_dst = oldflp->fl4_dst; rth->rt_tos = tos; rth->rt_key_src = oldflp->fl4_src; - rth->rt_oif = oldflp->oif; - rth->rt_mark = oldflp->mark; + rth->rt_oif = oldflp->flowi_oif; + rth->rt_mark = oldflp->flowi_mark; rth->rt_dst = fl->fl4_dst; rth->rt_src = fl->fl4_src; rth->rt_iif = 0; @@ -2452,9 +2452,9 @@ static struct rtable *ip_route_output_slow(struct net *net, res.r = NULL; #endif - fl.oif = oldflp->oif; - fl.iif = net->loopback_dev->ifindex; - fl.mark = oldflp->mark; + fl.flowi_oif = oldflp->flowi_oif; + fl.flowi_iif = net->loopback_dev->ifindex; + fl.flowi_mark = oldflp->flowi_mark; fl.fl4_dst = oldflp->fl4_dst; fl.fl4_src = oldflp->fl4_src; fl.fl4_tos = tos & IPTOS_RT_MASK; @@ -2477,7 +2477,7 @@ static struct rtable *ip_route_output_slow(struct net *net, of another iface. --ANK */ - if (oldflp->oif == 0 && + if (oldflp->flowi_oif == 0 && (ipv4_is_multicast(oldflp->fl4_dst) || ipv4_is_lbcast(oldflp->fl4_dst))) { /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */ @@ -2500,11 +2500,11 @@ static struct rtable *ip_route_output_slow(struct net *net, Luckily, this hack is good workaround. */ - fl.oif = dev_out->ifindex; + fl.flowi_oif = dev_out->ifindex; goto make_route; } - if (!(oldflp->flags & FLOWI_FLAG_ANYSRC)) { + if (!(oldflp->flowi_flags & FLOWI_FLAG_ANYSRC)) { /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */ if (!__ip_dev_find(net, oldflp->fl4_src, false)) goto out; @@ -2512,8 +2512,8 @@ static struct rtable *ip_route_output_slow(struct net *net, } - if (oldflp->oif) { - dev_out = dev_get_by_index_rcu(net, oldflp->oif); + if (oldflp->flowi_oif) { + dev_out = dev_get_by_index_rcu(net, oldflp->flowi_oif); rth = ERR_PTR(-ENODEV); if (dev_out == NULL) goto out; @@ -2545,7 +2545,7 @@ static struct rtable *ip_route_output_slow(struct net *net, if (!fl.fl4_dst) fl.fl4_dst = fl.fl4_src = htonl(INADDR_LOOPBACK); dev_out = net->loopback_dev; - fl.oif = net->loopback_dev->ifindex; + fl.flowi_oif = net->loopback_dev->ifindex; res.type = RTN_LOCAL; flags |= RTCF_LOCAL; goto make_route; @@ -2553,7 +2553,7 @@ static struct rtable *ip_route_output_slow(struct net *net, if (fib_lookup(net, &fl, &res)) { res.fi = NULL; - if (oldflp->oif) { + if (oldflp->flowi_oif) { /* Apparently, routing tables are wrong. Assume, that the destination is on link. @@ -2590,25 +2590,25 @@ static struct rtable *ip_route_output_slow(struct net *net, fl.fl4_src = fl.fl4_dst; } dev_out = net->loopback_dev; - fl.oif = dev_out->ifindex; + fl.flowi_oif = dev_out->ifindex; res.fi = NULL; flags |= RTCF_LOCAL; goto make_route; } #ifdef CONFIG_IP_ROUTE_MULTIPATH - if (res.fi->fib_nhs > 1 && fl.oif == 0) + if (res.fi->fib_nhs > 1 && fl.flowi_oif == 0) fib_select_multipath(&res); else #endif - if (!res.prefixlen && res.type == RTN_UNICAST && !fl.oif) + if (!res.prefixlen && res.type == RTN_UNICAST && !fl.flowi_oif) fib_select_default(&res); if (!fl.fl4_src) fl.fl4_src = FIB_RES_PREFSRC(res); dev_out = FIB_RES_DEV(res); - fl.oif = dev_out->ifindex; + fl.flowi_oif = dev_out->ifindex; make_route: @@ -2616,9 +2616,9 @@ make_route: if (!IS_ERR(rth)) { unsigned int hash; - hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif, + hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->flowi_oif, rt_genid(dev_net(dev_out))); - rth = rt_intern_hash(hash, rth, NULL, oldflp->oif); + rth = rt_intern_hash(hash, rth, NULL, oldflp->flowi_oif); } out: @@ -2634,7 +2634,7 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi *flp) if (!rt_caching(net)) goto slow_output; - hash = rt_hash(flp->fl4_dst, flp->fl4_src, flp->oif, rt_genid(net)); + hash = rt_hash(flp->fl4_dst, flp->fl4_src, flp->flowi_oif, rt_genid(net)); rcu_read_lock_bh(); for (rth = rcu_dereference_bh(rt_hash_table[hash].chain); rth; @@ -2642,8 +2642,8 @@ struct rtable *__ip_route_output_key(struct net *net, const struct flowi *flp) if (rth->rt_key_dst == flp->fl4_dst && rth->rt_key_src == flp->fl4_src && rt_is_output_route(rth) && - rth->rt_oif == flp->oif && - rth->rt_mark == flp->mark && + rth->rt_oif == flp->flowi_oif && + rth->rt_mark == flp->flowi_mark && !((rth->rt_tos ^ flp->fl4_tos) & (IPTOS_RT_MASK | RTO_ONLINK)) && net_eq(dev_net(rth->dst.dev), net) && @@ -2741,7 +2741,7 @@ struct rtable *ip_route_output_flow(struct net *net, struct flowi *flp, if (IS_ERR(rt)) return rt; - if (flp->proto) { + if (flp->flowi_proto) { if (!flp->fl4_src) flp->fl4_src = rt->rt_src; if (!flp->fl4_dst) @@ -2917,8 +2917,8 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void .fl4_dst = dst, .fl4_src = src, .fl4_tos = rtm->rtm_tos, - .oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0, - .mark = mark, + .flowi_oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0, + .flowi_mark = mark, }; rt = ip_route_output_key(net, &fl); diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 0ad6ddf638a7..98d47dc60c89 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -345,15 +345,17 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, * no easy way to do this. */ { - struct flowi fl = { .mark = sk->sk_mark, - .fl4_dst = ((opt && opt->srr) ? - opt->faddr : ireq->rmt_addr), - .fl4_src = ireq->loc_addr, - .fl4_tos = RT_CONN_FLAGS(sk), - .proto = IPPROTO_TCP, - .flags = inet_sk_flowi_flags(sk), - .fl_ip_sport = th->dest, - .fl_ip_dport = th->source }; + struct flowi fl = { + .flowi_mark = sk->sk_mark, + .fl4_dst = ((opt && opt->srr) ? + opt->faddr : ireq->rmt_addr), + .fl4_src = ireq->loc_addr, + .fl4_tos = RT_CONN_FLAGS(sk), + .flowi_proto = IPPROTO_TCP, + .flowi_flags = inet_sk_flowi_flags(sk), + .fl_ip_sport = th->dest, + .fl_ip_dport = th->source, + }; security_req_classify_flow(req, &fl); rt = ip_route_output_key(sock_net(sk), &fl); if (IS_ERR(rt)) { diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index c9a73e5b26a3..e10f62e6c07c 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -908,16 +908,17 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, rt = (struct rtable *)sk_dst_check(sk, 0); if (rt == NULL) { - struct flowi fl = { .oif = ipc.oif, - .mark = sk->sk_mark, - .fl4_dst = faddr, - .fl4_src = saddr, - .fl4_tos = tos, - .proto = sk->sk_protocol, - .flags = (inet_sk_flowi_flags(sk) | - FLOWI_FLAG_CAN_SLEEP), - .fl_ip_sport = inet->inet_sport, - .fl_ip_dport = dport + struct flowi fl = { + .flowi_oif = ipc.oif, + .flowi_mark = sk->sk_mark, + .fl4_dst = faddr, + .fl4_src = saddr, + .fl4_tos = tos, + .flowi_proto = sk->sk_protocol, + .flowi_flags = (inet_sk_flowi_flags(sk) | + FLOWI_FLAG_CAN_SLEEP), + .fl_ip_sport = inet->inet_sport, + .fl_ip_dport = dport, }; struct net *net = sock_net(sk); diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index c70c42e7e77b..4294f121a749 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -73,9 +73,9 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, rt->rt_key_dst = fl->fl4_dst; rt->rt_key_src = fl->fl4_src; rt->rt_tos = fl->fl4_tos; - rt->rt_iif = fl->iif; - rt->rt_oif = fl->oif; - rt->rt_mark = fl->mark; + rt->rt_iif = fl->flowi_iif; + rt->rt_oif = fl->flowi_oif; + rt->rt_mark = fl->flowi_mark; xdst->u.dst.dev = dev; dev_hold(dev); @@ -104,7 +104,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) u8 *xprth = skb_network_header(skb) + iph->ihl * 4; memset(fl, 0, sizeof(struct flowi)); - fl->mark = skb->mark; + fl->flowi_mark = skb->mark; if (!(iph->frag_off & htons(IP_MF | IP_OFFSET))) { switch (iph->protocol) { @@ -173,7 +173,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) break; } } - fl->proto = iph->protocol; + fl->flowi_proto = iph->protocol; fl->fl4_dst = reverse ? iph->saddr : iph->daddr; fl->fl4_src = reverse ? iph->daddr : iph->saddr; fl->fl4_tos = iph->tos; diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c index 983eff248988..d2314348dd2a 100644 --- a/net/ipv4/xfrm4_state.c +++ b/net/ipv4/xfrm4_state.c @@ -32,8 +32,8 @@ __xfrm4_init_tempsel(struct xfrm_selector *sel, const struct flowi *fl) sel->family = AF_INET; sel->prefixlen_d = 32; sel->prefixlen_s = 32; - sel->proto = fl->proto; - sel->ifindex = fl->oif; + sel->proto = fl->flowi_proto; + sel->ifindex = fl->flowi_oif; } static void diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index a88b2e9d25f1..35b0be0463f9 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -655,12 +655,12 @@ int inet6_sk_rebuild_header(struct sock *sk) struct flowi fl; memset(&fl, 0, sizeof(fl)); - fl.proto = sk->sk_protocol; + fl.flowi_proto = sk->sk_protocol; ipv6_addr_copy(&fl.fl6_dst, &np->daddr); ipv6_addr_copy(&fl.fl6_src, &np->saddr); fl.fl6_flowlabel = np->flow_label; - fl.oif = sk->sk_bound_dev_if; - fl.mark = sk->sk_mark; + fl.flowi_oif = sk->sk_bound_dev_if; + fl.flowi_mark = sk->sk_mark; fl.fl_ip_dport = inet->inet_dport; fl.fl_ip_sport = inet->inet_sport; security_sk_classify_flow(sk, &fl); diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index be3a781c0085..6c24b26f67ec 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -146,16 +146,16 @@ ipv4_connected: * destination cache for it. */ - fl.proto = sk->sk_protocol; + fl.flowi_proto = sk->sk_protocol; ipv6_addr_copy(&fl.fl6_dst, &np->daddr); ipv6_addr_copy(&fl.fl6_src, &np->saddr); - fl.oif = sk->sk_bound_dev_if; - fl.mark = sk->sk_mark; + fl.flowi_oif = sk->sk_bound_dev_if; + fl.flowi_mark = sk->sk_mark; fl.fl_ip_dport = inet->inet_dport; fl.fl_ip_sport = inet->inet_sport; - if (!fl.oif && (addr_type&IPV6_ADDR_MULTICAST)) - fl.oif = np->mcast_oif; + if (!fl.flowi_oif && (addr_type&IPV6_ADDR_MULTICAST)) + fl.flowi_oif = np->mcast_oif; security_sk_classify_flow(sk, &fl); @@ -299,7 +299,7 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi *fl, u32 mtu) mtu_info->ip6m_addr.sin6_family = AF_INET6; mtu_info->ip6m_addr.sin6_port = 0; mtu_info->ip6m_addr.sin6_flowinfo = 0; - mtu_info->ip6m_addr.sin6_scope_id = fl->oif; + mtu_info->ip6m_addr.sin6_scope_id = fl->flowi_oif; ipv6_addr_copy(&mtu_info->ip6m_addr.sin6_addr, &ipv6_hdr(skb)->daddr); __skb_pull(skb, skb_tail_pointer(skb) - skb->data); @@ -629,16 +629,16 @@ int datagram_send_ctl(struct net *net, src_info = (struct in6_pktinfo *)CMSG_DATA(cmsg); if (src_info->ipi6_ifindex) { - if (fl->oif && src_info->ipi6_ifindex != fl->oif) + if (fl->flowi_oif && src_info->ipi6_ifindex != fl->flowi_oif) return -EINVAL; - fl->oif = src_info->ipi6_ifindex; + fl->flowi_oif = src_info->ipi6_ifindex; } addr_type = __ipv6_addr_type(&src_info->ipi6_addr); rcu_read_lock(); - if (fl->oif) { - dev = dev_get_by_index_rcu(net, fl->oif); + if (fl->flowi_oif) { + dev = dev_get_by_index_rcu(net, fl->flowi_oif); if (!dev) { rcu_read_unlock(); return -ENODEV; diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 55665956b3a8..9e123e08b9b7 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -235,7 +235,7 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct sizeof(struct icmp6hdr), skb->csum); icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src, &fl->fl6_dst, - len, fl->proto, + len, fl->flowi_proto, skb->csum); } else { __wsum tmp_csum = 0; @@ -248,7 +248,7 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct sizeof(struct icmp6hdr), tmp_csum); icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src, &fl->fl6_dst, - len, fl->proto, + len, fl->flowi_proto, tmp_csum); } ip6_push_pending_frames(sk); @@ -443,11 +443,11 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) mip6_addr_swap(skb); memset(&fl, 0, sizeof(fl)); - fl.proto = IPPROTO_ICMPV6; + fl.flowi_proto = IPPROTO_ICMPV6; ipv6_addr_copy(&fl.fl6_dst, &hdr->saddr); if (saddr) ipv6_addr_copy(&fl.fl6_src, saddr); - fl.oif = iif; + fl.flowi_oif = iif; fl.fl_icmp_type = type; fl.fl_icmp_code = code; security_skb_classify_flow(skb, &fl); @@ -465,8 +465,8 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) tmp_hdr.icmp6_cksum = 0; tmp_hdr.icmp6_pointer = htonl(info); - if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) - fl.oif = np->mcast_oif; + if (!fl.flowi_oif && ipv6_addr_is_multicast(&fl.fl6_dst)) + fl.flowi_oif = np->mcast_oif; dst = icmpv6_route_lookup(net, skb, sk, &fl); if (IS_ERR(dst)) @@ -539,11 +539,11 @@ static void icmpv6_echo_reply(struct sk_buff *skb) tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY; memset(&fl, 0, sizeof(fl)); - fl.proto = IPPROTO_ICMPV6; + fl.flowi_proto = IPPROTO_ICMPV6; ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr); if (saddr) ipv6_addr_copy(&fl.fl6_src, saddr); - fl.oif = skb->dev->ifindex; + fl.flowi_oif = skb->dev->ifindex; fl.fl_icmp_type = ICMPV6_ECHO_REPLY; security_skb_classify_flow(skb, &fl); @@ -552,8 +552,8 @@ static void icmpv6_echo_reply(struct sk_buff *skb) return; np = inet6_sk(sk); - if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) - fl.oif = np->mcast_oif; + if (!fl.flowi_oif && ipv6_addr_is_multicast(&fl.fl6_dst)) + fl.flowi_oif = np->mcast_oif; err = ip6_dst_lookup(sk, &dst, &fl); if (err) @@ -793,10 +793,10 @@ void icmpv6_flow_init(struct sock *sk, struct flowi *fl, memset(fl, 0, sizeof(*fl)); ipv6_addr_copy(&fl->fl6_src, saddr); ipv6_addr_copy(&fl->fl6_dst, daddr); - fl->proto = IPPROTO_ICMPV6; + fl->flowi_proto = IPPROTO_ICMPV6; fl->fl_icmp_type = type; fl->fl_icmp_code = 0; - fl->oif = oif; + fl->flowi_oif = oif; security_sk_classify_flow(sk, fl); } diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index d687e1397333..673f9bf28958 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -64,12 +64,12 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk, struct flowi fl; memset(&fl, 0, sizeof(fl)); - fl.proto = IPPROTO_TCP; + fl.flowi_proto = IPPROTO_TCP; ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); final_p = fl6_update_dst(&fl, np->opt, &final); ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr); - fl.oif = sk->sk_bound_dev_if; - fl.mark = sk->sk_mark; + fl.flowi_oif = sk->sk_bound_dev_if; + fl.flowi_mark = sk->sk_mark; fl.fl_ip_dport = inet_rsk(req)->rmt_port; fl.fl_ip_sport = inet_rsk(req)->loc_port; security_req_classify_flow(req, &fl); @@ -213,13 +213,13 @@ int inet6_csk_xmit(struct sk_buff *skb) struct in6_addr *final_p, final; memset(&fl, 0, sizeof(fl)); - fl.proto = sk->sk_protocol; + fl.flowi_proto = sk->sk_protocol; ipv6_addr_copy(&fl.fl6_dst, &np->daddr); ipv6_addr_copy(&fl.fl6_src, &np->saddr); fl.fl6_flowlabel = np->flow_label; IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel); - fl.oif = sk->sk_bound_dev_if; - fl.mark = sk->sk_mark; + fl.flowi_oif = sk->sk_bound_dev_if; + fl.flowi_mark = sk->sk_mark; fl.fl_ip_sport = inet->inet_sport; fl.fl_ip_dport = inet->inet_dport; security_sk_classify_flow(sk, &fl); diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 13654686aeab..c8fa470b174b 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c @@ -358,7 +358,7 @@ fl_create(struct net *net, struct in6_flowlabel_req *freq, char __user *optval, msg.msg_controllen = olen; msg.msg_control = (void*)(fl->opt+1); - flowi.oif = 0; + flowi.flowi_oif = 0; err = datagram_send_ctl(net, &msg, &flowi, fl->opt, &junk, &junk, &junk); diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index adaffaf84555..3d0f2ac868a7 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -182,7 +182,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, struct in6_addr *first_hop = &fl->fl6_dst; struct dst_entry *dst = skb_dst(skb); struct ipv6hdr *hdr; - u8 proto = fl->proto; + u8 proto = fl->flowi_proto; int seg_len = skb->len; int hlimit = -1; int tclass = 0; @@ -908,7 +908,7 @@ static struct dst_entry *ip6_sk_dst_check(struct sock *sk, #ifdef CONFIG_IPV6_SUBTREES ip6_rt_check(&rt->rt6i_src, &fl->fl6_src, np->saddr_cache) || #endif - (fl->oif && fl->oif != dst->dev->ifindex)) { + (fl->flowi_oif && fl->flowi_oif != dst->dev->ifindex)) { dst_release(dst); dst = NULL; } @@ -1026,7 +1026,7 @@ struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi *fl, if (final_dst) ipv6_addr_copy(&fl->fl6_dst, final_dst); if (can_sleep) - fl->flags |= FLOWI_FLAG_CAN_SLEEP; + fl->flowi_flags |= FLOWI_FLAG_CAN_SLEEP; return xfrm_lookup(sock_net(sk), dst, fl, sk, 0); } @@ -1062,7 +1062,7 @@ struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi *fl, if (final_dst) ipv6_addr_copy(&fl->fl6_dst, final_dst); if (can_sleep) - fl->flags |= FLOWI_FLAG_CAN_SLEEP; + fl->flowi_flags |= FLOWI_FLAG_CAN_SLEEP; return xfrm_lookup(sock_net(sk), dst, fl, sk, 0); } @@ -1517,7 +1517,7 @@ int ip6_push_pending_frames(struct sock *sk) struct ipv6_txoptions *opt = np->cork.opt; struct rt6_info *rt = (struct rt6_info *)inet->cork.dst; struct flowi *fl = &inet->cork.fl; - unsigned char proto = fl->proto; + unsigned char proto = fl->flowi_proto; int err = 0; if ((skb = __skb_dequeue(&sk->sk_write_queue)) == NULL) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index f199b8486120..c3fc824c24d9 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -963,7 +963,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, skb->transport_header = skb->network_header; - proto = fl->proto; + proto = fl->flowi_proto; if (encap_limit >= 0) { init_tel_txopt(&opt, encap_limit); ipv6_push_nfrag_opts(skb, &opt.ops, &proto, NULL); @@ -1020,7 +1020,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) encap_limit = t->parms.encap_limit; memcpy(&fl, &t->fl, sizeof (fl)); - fl.proto = IPPROTO_IPIP; + fl.flowi_proto = IPPROTO_IPIP; dsfield = ipv4_get_dsfield(iph); @@ -1070,7 +1070,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) encap_limit = t->parms.encap_limit; memcpy(&fl, &t->fl, sizeof (fl)); - fl.proto = IPPROTO_IPV6; + fl.flowi_proto = IPPROTO_IPV6; dsfield = ipv6_get_dsfield(ipv6h); if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)) @@ -1149,7 +1149,7 @@ static void ip6_tnl_link_config(struct ip6_tnl *t) /* Set up flowi template */ ipv6_addr_copy(&fl->fl6_src, &p->laddr); ipv6_addr_copy(&fl->fl6_dst, &p->raddr); - fl->oif = p->link; + fl->flowi_oif = p->link; fl->fl6_flowlabel = 0; if (!(p->flags&IP6_TNL_F_USE_ORIG_TCLASS)) diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 618f67ccda31..61a8be3ac4e4 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -618,8 +618,8 @@ static int pim6_rcv(struct sk_buff *skb) struct net *net = dev_net(skb->dev); struct mr6_table *mrt; struct flowi fl = { - .iif = skb->dev->ifindex, - .mark = skb->mark, + .flowi_iif = skb->dev->ifindex, + .flowi_mark = skb->mark, }; int reg_vif_num; @@ -688,9 +688,9 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net *net = dev_net(dev); struct mr6_table *mrt; struct flowi fl = { - .oif = dev->ifindex, - .iif = skb->skb_iif, - .mark = skb->mark, + .flowi_oif = dev->ifindex, + .flowi_iif = skb->skb_iif, + .flowi_mark = skb->mark, }; int err; @@ -1548,9 +1548,9 @@ struct sock *mroute6_socket(struct net *net, struct sk_buff *skb) { struct mr6_table *mrt; struct flowi fl = { - .iif = skb->skb_iif, - .oif = skb->dev->ifindex, - .mark = skb->mark, + .flowi_iif = skb->skb_iif, + .flowi_oif = skb->dev->ifindex, + .flowi_mark= skb->mark, }; if (ip6mr_fib_lookup(net, &fl, &mrt) < 0) @@ -1916,7 +1916,7 @@ static int ip6mr_forward2(struct net *net, struct mr6_table *mrt, ipv6h = ipv6_hdr(skb); fl = (struct flowi) { - .oif = vif->link, + .flowi_oif = vif->link, .fl6_dst = ipv6h->daddr, }; @@ -2044,8 +2044,8 @@ int ip6_mr_input(struct sk_buff *skb) struct net *net = dev_net(skb->dev); struct mr6_table *mrt; struct flowi fl = { - .iif = skb->dev->ifindex, - .mark = skb->mark, + .flowi_iif = skb->dev->ifindex, + .flowi_mark= skb->mark, }; int err; diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index d1770e061c08..1448c507fdff 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -448,8 +448,8 @@ sticky_done: int junk; fl.fl6_flowlabel = 0; - fl.oif = sk->sk_bound_dev_if; - fl.mark = sk->sk_mark; + fl.flowi_oif = sk->sk_bound_dev_if; + fl.flowi_mark = sk->sk_mark; if (optlen == 0) goto update; diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c index f3e3ca938a54..e2f852cd0f4e 100644 --- a/net/ipv6/mip6.c +++ b/net/ipv6/mip6.c @@ -214,7 +214,7 @@ static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, struct timeval stamp; int err = 0; - if (unlikely(fl->proto == IPPROTO_MH && + if (unlikely(fl->flowi_proto == IPPROTO_MH && fl->fl_mh_type <= IP6_MH_TYPE_MAX)) goto out; @@ -240,14 +240,14 @@ static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, sizeof(sel.saddr)); sel.prefixlen_s = 128; sel.family = AF_INET6; - sel.proto = fl->proto; + sel.proto = fl->flowi_proto; sel.dport = xfrm_flowi_dport(fl); if (sel.dport) sel.dport_mask = htons(~0); sel.sport = xfrm_flowi_sport(fl); if (sel.sport) sel.sport_mask = htons(~0); - sel.ifindex = fl->oif; + sel.ifindex = fl->flowi_oif; err = km_report(net, IPPROTO_DSTOPTS, &sel, (hao ? (xfrm_address_t *)&hao->addr : NULL)); diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index 8d74116ae27d..d282c62bc6f4 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c @@ -16,8 +16,8 @@ int ip6_route_me_harder(struct sk_buff *skb) struct ipv6hdr *iph = ipv6_hdr(skb); struct dst_entry *dst; struct flowi fl = { - .oif = skb->sk ? skb->sk->sk_bound_dev_if : 0, - .mark = skb->mark, + .flowi_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0, + .flowi_mark = skb->mark, .fl6_dst = iph->daddr, .fl6_src = iph->saddr, }; diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index 91f6a61cefab..fd3938803eb3 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c @@ -90,7 +90,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb) } memset(&fl, 0, sizeof(fl)); - fl.proto = IPPROTO_TCP; + fl.flowi_proto = IPPROTO_TCP; ipv6_addr_copy(&fl.fl6_src, &oip6h->daddr); ipv6_addr_copy(&fl.fl6_dst, &oip6h->saddr); fl.fl_ip_sport = otcph.dest; diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index dc29b07caf42..323ad44ff775 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -588,9 +588,9 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, csum = csum_ipv6_magic(&fl->fl6_src, &fl->fl6_dst, - total_len, fl->proto, tmp_csum); + total_len, fl->flowi_proto, tmp_csum); - if (csum == 0 && fl->proto == IPPROTO_UDP) + if (csum == 0 && fl->flowi_proto == IPPROTO_UDP) csum = CSUM_MANGLED_0; if (skb_store_bits(skb, offset, &csum, 2)) @@ -679,7 +679,7 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) if (!iov) continue; - switch (fl->proto) { + switch (fl->flowi_proto) { case IPPROTO_ICMPV6: /* check if one-byte field is readable or not. */ if (iov->iov_base && iov->iov_len < 1) @@ -758,7 +758,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, */ memset(&fl, 0, sizeof(fl)); - fl.mark = sk->sk_mark; + fl.flowi_mark = sk->sk_mark; if (sin6) { if (addr_len < SIN6_LEN_RFC2133) @@ -800,7 +800,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, if (addr_len >= sizeof(struct sockaddr_in6) && sin6->sin6_scope_id && ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL) - fl.oif = sin6->sin6_scope_id; + fl.flowi_oif = sin6->sin6_scope_id; } else { if (sk->sk_state != TCP_ESTABLISHED) return -EDESTADDRREQ; @@ -810,8 +810,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, fl.fl6_flowlabel = np->flow_label; } - if (fl.oif == 0) - fl.oif = sk->sk_bound_dev_if; + if (fl.flowi_oif == 0) + fl.flowi_oif = sk->sk_bound_dev_if; if (msg->msg_controllen) { opt = &opt_space; @@ -838,7 +838,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, opt = fl6_merge_options(&opt_space, flowlabel, opt); opt = ipv6_fixup_options(&opt_space, opt); - fl.proto = proto; + fl.flowi_proto = proto; err = rawv6_probe_proto_opt(&fl, msg); if (err) goto out; @@ -852,8 +852,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, final_p = fl6_update_dst(&fl, opt, &final); - if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) - fl.oif = np->mcast_oif; + if (!fl.flowi_oif && ipv6_addr_is_multicast(&fl.fl6_dst)) + fl.flowi_oif = np->mcast_oif; security_sk_classify_flow(sk, &fl); dst = ip6_dst_lookup_flow(sk, &fl, final_p, true); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 001276055a6b..c3b20d63921f 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -608,7 +608,7 @@ static struct rt6_info *ip6_pol_route_lookup(struct net *net, fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); restart: rt = fn->leaf; - rt = rt6_device_match(net, rt, &fl->fl6_src, fl->oif, flags); + rt = rt6_device_match(net, rt, &fl->fl6_src, fl->flowi_oif, flags); BACKTRACK(net, &fl->fl6_src); out: dst_use(&rt->dst, jiffies); @@ -621,7 +621,7 @@ struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr, const struct in6_addr *saddr, int oif, int strict) { struct flowi fl = { - .oif = oif, + .flowi_oif = oif, .fl6_dst = *daddr, }; struct dst_entry *dst; @@ -825,7 +825,7 @@ out2: static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *table, struct flowi *fl, int flags) { - return ip6_pol_route(net, table, fl->iif, fl, flags); + return ip6_pol_route(net, table, fl->flowi_iif, fl, flags); } void ip6_route_input(struct sk_buff *skb) @@ -834,12 +834,12 @@ void ip6_route_input(struct sk_buff *skb) struct net *net = dev_net(skb->dev); int flags = RT6_LOOKUP_F_HAS_SADDR; struct flowi fl = { - .iif = skb->dev->ifindex, + .flowi_iif = skb->dev->ifindex, .fl6_dst = iph->daddr, .fl6_src = iph->saddr, .fl6_flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK, - .mark = skb->mark, - .proto = iph->nexthdr, + .flowi_mark = skb->mark, + .flowi_proto = iph->nexthdr, }; if (rt6_need_strict(&iph->daddr) && skb->dev->type != ARPHRD_PIMREG) @@ -851,7 +851,7 @@ void ip6_route_input(struct sk_buff *skb) static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table, struct flowi *fl, int flags) { - return ip6_pol_route(net, table, fl->oif, fl, flags); + return ip6_pol_route(net, table, fl->flowi_oif, fl, flags); } struct dst_entry * ip6_route_output(struct net *net, struct sock *sk, @@ -1484,7 +1484,7 @@ restart: continue; if (!(rt->rt6i_flags & RTF_GATEWAY)) continue; - if (fl->oif != rt->rt6i_dev->ifindex) + if (fl->flowi_oif != rt->rt6i_dev->ifindex) continue; if (!ipv6_addr_equal(&rdfl->gateway, &rt->rt6i_gateway)) continue; @@ -1511,7 +1511,7 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest, struct net *net = dev_net(dev); struct ip6rd_flowi rdfl = { .fl = { - .oif = dev->ifindex, + .flowi_oif = dev->ifindex, .fl6_dst = *dest, .fl6_src = *src, }, @@ -2413,7 +2413,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void iif = nla_get_u32(tb[RTA_IIF]); if (tb[RTA_OIF]) - fl.oif = nla_get_u32(tb[RTA_OIF]); + fl.flowi_oif = nla_get_u32(tb[RTA_OIF]); if (iif) { struct net_device *dev; diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 0b4cf350631b..ca5255c08371 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c @@ -234,12 +234,12 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) struct in6_addr *final_p, final; struct flowi fl; memset(&fl, 0, sizeof(fl)); - fl.proto = IPPROTO_TCP; + fl.flowi_proto = IPPROTO_TCP; ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr); final_p = fl6_update_dst(&fl, np->opt, &final); ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr); - fl.oif = sk->sk_bound_dev_if; - fl.mark = sk->sk_mark; + fl.flowi_oif = sk->sk_bound_dev_if; + fl.flowi_mark = sk->sk_mark; fl.fl_ip_dport = inet_rsk(req)->rmt_port; fl.fl_ip_sport = inet_sk(sk)->inet_sport; security_req_classify_flow(req, &fl); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index e59a31c48baf..a3d1229b4004 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -242,12 +242,12 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, if (!ipv6_addr_any(&np->rcv_saddr)) saddr = &np->rcv_saddr; - fl.proto = IPPROTO_TCP; + fl.flowi_proto = IPPROTO_TCP; ipv6_addr_copy(&fl.fl6_dst, &np->daddr); ipv6_addr_copy(&fl.fl6_src, (saddr ? saddr : &np->saddr)); - fl.oif = sk->sk_bound_dev_if; - fl.mark = sk->sk_mark; + fl.flowi_oif = sk->sk_bound_dev_if; + fl.flowi_mark = sk->sk_mark; fl.fl_ip_dport = usin->sin6_port; fl.fl_ip_sport = inet->inet_sport; @@ -396,11 +396,11 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, for now. */ memset(&fl, 0, sizeof(fl)); - fl.proto = IPPROTO_TCP; + fl.flowi_proto = IPPROTO_TCP; ipv6_addr_copy(&fl.fl6_dst, &np->daddr); ipv6_addr_copy(&fl.fl6_src, &np->saddr); - fl.oif = sk->sk_bound_dev_if; - fl.mark = sk->sk_mark; + fl.flowi_oif = sk->sk_bound_dev_if; + fl.flowi_mark = sk->sk_mark; fl.fl_ip_dport = inet->inet_dport; fl.fl_ip_sport = inet->inet_sport; security_skb_classify_flow(skb, &fl); @@ -487,12 +487,12 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, int err; memset(&fl, 0, sizeof(fl)); - fl.proto = IPPROTO_TCP; + fl.flowi_proto = IPPROTO_TCP; ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr); fl.fl6_flowlabel = 0; - fl.oif = treq->iif; - fl.mark = sk->sk_mark; + fl.flowi_oif = treq->iif; + fl.flowi_mark = sk->sk_mark; fl.fl_ip_dport = inet_rsk(req)->rmt_port; fl.fl_ip_sport = inet_rsk(req)->loc_port; security_req_classify_flow(req, &fl); @@ -1055,8 +1055,8 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, __tcp_v6_send_check(buff, &fl.fl6_src, &fl.fl6_dst); - fl.proto = IPPROTO_TCP; - fl.oif = inet6_iif(skb); + fl.flowi_proto = IPPROTO_TCP; + fl.flowi_oif = inet6_iif(skb); fl.fl_ip_dport = t1->dest; fl.fl_ip_sport = t1->source; security_skb_classify_flow(skb, &fl); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index d86d7f67a597..91f8047463ec 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -915,7 +915,7 @@ static int udp_v6_push_pending_frames(struct sock *sk) /* add protocol-dependent pseudo-header */ uh->check = csum_ipv6_magic(&fl->fl6_src, &fl->fl6_dst, - up->len, fl->proto, csum ); + up->len, fl->flowi_proto, csum); if (uh->check == 0) uh->check = CSUM_MANGLED_0; @@ -1060,7 +1060,7 @@ do_udp_sendmsg: if (addr_len >= sizeof(struct sockaddr_in6) && sin6->sin6_scope_id && ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL) - fl.oif = sin6->sin6_scope_id; + fl.flowi_oif = sin6->sin6_scope_id; } else { if (sk->sk_state != TCP_ESTABLISHED) return -EDESTADDRREQ; @@ -1071,13 +1071,13 @@ do_udp_sendmsg: connected = 1; } - if (!fl.oif) - fl.oif = sk->sk_bound_dev_if; + if (!fl.flowi_oif) + fl.flowi_oif = sk->sk_bound_dev_if; - if (!fl.oif) - fl.oif = np->sticky_pktinfo.ipi6_ifindex; + if (!fl.flowi_oif) + fl.flowi_oif = np->sticky_pktinfo.ipi6_ifindex; - fl.mark = sk->sk_mark; + fl.flowi_mark = sk->sk_mark; if (msg->msg_controllen) { opt = &opt_space; @@ -1105,7 +1105,7 @@ do_udp_sendmsg: opt = fl6_merge_options(&opt_space, flowlabel, opt); opt = ipv6_fixup_options(&opt_space, opt); - fl.proto = sk->sk_protocol; + fl.flowi_proto = sk->sk_protocol; if (!ipv6_addr_any(daddr)) ipv6_addr_copy(&fl.fl6_dst, daddr); else @@ -1118,8 +1118,8 @@ do_udp_sendmsg: if (final_p) connected = 0; - if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) { - fl.oif = np->mcast_oif; + if (!fl.flowi_oif && ipv6_addr_is_multicast(&fl.fl6_dst)) { + fl.flowi_oif = np->mcast_oif; connected = 0; } diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 48ce496802fd..d62496c1a6f9 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -128,7 +128,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) u8 nexthdr = nh[IP6CB(skb)->nhoff]; memset(fl, 0, sizeof(struct flowi)); - fl->mark = skb->mark; + fl->flowi_mark = skb->mark; ipv6_addr_copy(&fl->fl6_dst, reverse ? &hdr->saddr : &hdr->daddr); ipv6_addr_copy(&fl->fl6_src, reverse ? &hdr->daddr : &hdr->saddr); @@ -161,7 +161,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) fl->fl_ip_sport = ports[!!reverse]; fl->fl_ip_dport = ports[!reverse]; } - fl->proto = nexthdr; + fl->flowi_proto = nexthdr; return; case IPPROTO_ICMPV6: @@ -171,7 +171,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) fl->fl_icmp_type = icmp[0]; fl->fl_icmp_code = icmp[1]; } - fl->proto = nexthdr; + fl->flowi_proto = nexthdr; return; #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) @@ -182,7 +182,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) fl->fl_mh_type = mh->ip6mh_type; } - fl->proto = nexthdr; + fl->flowi_proto = nexthdr; return; #endif @@ -192,7 +192,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) case IPPROTO_COMP: default: fl->fl_ipsec_spi = 0; - fl->proto = nexthdr; + fl->flowi_proto = nexthdr; return; } } diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index a02598e0079a..805d0e14c331 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c @@ -33,8 +33,8 @@ __xfrm6_init_tempsel(struct xfrm_selector *sel, const struct flowi *fl) sel->family = AF_INET6; sel->prefixlen_d = 128; sel->prefixlen_s = 128; - sel->proto = fl->proto; - sel->ifindex = fl->oif; + sel->proto = fl->flowi_proto; + sel->ifindex = fl->flowi_oif; } static void diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index d69ec26b6bd4..d07a32aa07b6 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -76,7 +76,7 @@ static int __ip_vs_addr_is_local_v6(struct net *net, { struct rt6_info *rt; struct flowi fl = { - .oif = 0, + .flowi_oif = 0, .fl6_dst = *addr, .fl6_src = { .s6_addr32 = {0, 0, 0, 0} }, }; diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index faf381d9da7c..cc8071f68903 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -169,7 +169,7 @@ __ip_vs_reroute_locally(struct sk_buff *skb) .fl4_dst = iph->daddr, .fl4_src = iph->saddr, .fl4_tos = RT_TOS(iph->tos), - .mark = skb->mark, + .flowi_mark = skb->mark, }; rt = ip_route_output_key(net, &fl); diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c index 624725b5286f..cb14ae2de15d 100644 --- a/net/netfilter/xt_TEE.c +++ b/net/netfilter/xt_TEE.c @@ -68,7 +68,7 @@ tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info) if (info->priv) { if (info->priv->oif == -1) return false; - fl.oif = info->priv->oif; + fl.flowi_oif = info->priv->oif; } fl.fl4_dst = info->gw.ip; fl.fl4_tos = RT_TOS(iph->tos); @@ -149,7 +149,7 @@ tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info) if (info->priv) { if (info->priv->oif == -1) return false; - fl.oif = info->priv->oif; + fl.flowi_oif = info->priv->oif; } fl.fl6_dst = info->gw.in6; fl.fl6_flowlabel = ((iph->flow_lbl[0] & 0xF) << 16) | diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 95e0c8eda1a0..831627156884 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -205,7 +205,7 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport) memset(&fl, 0, sizeof(fl)); - fl.proto = sk->sk_protocol; + fl.flowi_proto = sk->sk_protocol; /* Fill in the dest address from the route entry passed with the skb * and the source address from the transport. @@ -216,9 +216,9 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport) fl.fl6_flowlabel = np->flow_label; IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel); if (ipv6_addr_type(&fl.fl6_src) & IPV6_ADDR_LINKLOCAL) - fl.oif = transport->saddr.v6.sin6_scope_id; + fl.flowi_oif = transport->saddr.v6.sin6_scope_id; else - fl.oif = sk->sk_bound_dev_if; + fl.flowi_oif = sk->sk_bound_dev_if; if (np->opt && np->opt->srcrt) { struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; @@ -250,7 +250,7 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc, memset(&fl, 0, sizeof(fl)); ipv6_addr_copy(&fl.fl6_dst, &daddr->v6.sin6_addr); if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) - fl.oif = daddr->v6.sin6_scope_id; + fl.flowi_oif = daddr->v6.sin6_scope_id; SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl.fl6_dst); diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 4e55e6c49ec9..832665ac2100 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -477,10 +477,10 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, memset(&fl, 0x0, sizeof(struct flowi)); fl.fl4_dst = daddr->v4.sin_addr.s_addr; fl.fl_ip_dport = daddr->v4.sin_port; - fl.proto = IPPROTO_SCTP; + fl.flowi_proto = IPPROTO_SCTP; if (asoc) { fl.fl4_tos = RT_CONN_FLAGS(asoc->base.sk); - fl.oif = asoc->base.sk->sk_bound_dev_if; + fl.flowi_oif = asoc->base.sk->sk_bound_dev_if; fl.fl_ip_sport = htons(asoc->base.bind_addr.port); } if (saddr) { diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 9e4aacda26cc..dd6243f9d933 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -63,8 +63,8 @@ __xfrm4_selector_match(const struct xfrm_selector *sel, const struct flowi *fl) addr_match(&fl->fl4_src, &sel->saddr, sel->prefixlen_s) && !((xfrm_flowi_dport(fl) ^ sel->dport) & sel->dport_mask) && !((xfrm_flowi_sport(fl) ^ sel->sport) & sel->sport_mask) && - (fl->proto == sel->proto || !sel->proto) && - (fl->oif == sel->ifindex || !sel->ifindex); + (fl->flowi_proto == sel->proto || !sel->proto) && + (fl->flowi_oif == sel->ifindex || !sel->ifindex); } static inline int @@ -74,8 +74,8 @@ __xfrm6_selector_match(const struct xfrm_selector *sel, const struct flowi *fl) addr_match(&fl->fl6_src, &sel->saddr, sel->prefixlen_s) && !((xfrm_flowi_dport(fl) ^ sel->dport) & sel->dport_mask) && !((xfrm_flowi_sport(fl) ^ sel->sport) & sel->sport_mask) && - (fl->proto == sel->proto || !sel->proto) && - (fl->oif == sel->ifindex || !sel->ifindex); + (fl->flowi_proto == sel->proto || !sel->proto) && + (fl->flowi_oif == sel->ifindex || !sel->ifindex); } int xfrm_selector_match(const struct xfrm_selector *sel, const struct flowi *fl, @@ -876,13 +876,13 @@ static int xfrm_policy_match(const struct xfrm_policy *pol, int match, ret = -ESRCH; if (pol->family != family || - (fl->mark & pol->mark.m) != pol->mark.v || + (fl->flowi_mark & pol->mark.m) != pol->mark.v || pol->type != type) return ret; match = xfrm_selector_match(sel, fl, family); if (match) - ret = security_xfrm_policy_lookup(pol->security, fl->secid, + ret = security_xfrm_policy_lookup(pol->security, fl->flowi_secid, dir); return ret; @@ -1012,7 +1012,7 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, goto out; } err = security_xfrm_policy_lookup(pol->security, - fl->secid, + fl->flowi_secid, policy_to_flow_dir(dir)); if (!err) xfrm_pol_hold(pol); @@ -1848,7 +1848,7 @@ restart: return make_blackhole(net, family, dst_orig); } - if (fl->flags & FLOWI_FLAG_CAN_SLEEP) { + if (fl->flowi_flags & FLOWI_FLAG_CAN_SLEEP) { DECLARE_WAITQUEUE(wait, current); add_wait_queue(&net->xfrm.km_waitq, &wait); @@ -1990,7 +1990,7 @@ int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, return -EAFNOSUPPORT; afinfo->decode_session(skb, fl, reverse); - err = security_xfrm_decode_session(skb, &fl->secid); + err = security_xfrm_decode_session(skb, &fl->flowi_secid); xfrm_policy_put_afinfo(afinfo); return err; } diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 81221d9cbf06..cd6be49f2ae8 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -859,7 +859,7 @@ found: xfrm_init_tempstate(x, fl, tmpl, daddr, saddr, family); memcpy(&x->mark, &pol->mark, sizeof(x->mark)); - error = security_xfrm_state_alloc_acquire(x, pol->security, fl->secid); + error = security_xfrm_state_alloc_acquire(x, pol->security, fl->flowi_secid); if (error) { x->km.state = XFRM_STATE_DEAD; to_put = x; diff --git a/security/security.c b/security/security.c index 8ef1f7dff277..bae843c8a13e 100644 --- a/security/security.c +++ b/security/security.c @@ -1100,7 +1100,7 @@ void security_sk_clone(const struct sock *sk, struct sock *newsk) void security_sk_classify_flow(struct sock *sk, struct flowi *fl) { - security_ops->sk_getsecid(sk, &fl->secid); + security_ops->sk_getsecid(sk, &fl->flowi_secid); } EXPORT_SYMBOL(security_sk_classify_flow); @@ -1246,7 +1246,7 @@ int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid) void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl) { - int rc = security_ops->xfrm_decode_session(skb, &fl->secid, 0); + int rc = security_ops->xfrm_decode_session(skb, &fl->flowi_secid, 0); BUG_ON(rc); } diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index cef42f5d69a2..c178494850a9 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4306,7 +4306,7 @@ static void selinux_secmark_refcount_dec(void) static void selinux_req_classify_flow(const struct request_sock *req, struct flowi *fl) { - fl->secid = req->secid; + fl->flowi_secid = req->secid; } static int selinux_tun_dev_create(void) diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index c43ab542246c..510ec2cf6c23 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c @@ -135,10 +135,10 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy * state_sid = x->security->ctx_sid; - if (fl->secid != state_sid) + if (fl->flowi_secid != state_sid) return 0; - rc = avc_has_perm(fl->secid, state_sid, SECCLASS_ASSOCIATION, + rc = avc_has_perm(fl->flowi_secid, state_sid, SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, NULL)? 0:1; -- cgit v1.2.3 From 4c9483b2fb5d2548c3cc1fe03cdd4484ceeb5d1c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 12 Mar 2011 16:22:43 -0500 Subject: ipv6: Convert to use flowi6 where applicable. Signed-off-by: David S. Miller --- drivers/infiniband/core/addr.c | 18 +++--- drivers/net/cnic.c | 12 ++-- include/linux/icmpv6.h | 4 +- include/net/ip6_fib.h | 4 +- include/net/ip6_route.h | 2 +- include/net/ipv6.h | 16 ++--- include/net/transp_v6.h | 4 +- net/dccp/ipv6.c | 132 +++++++++++++++++++-------------------- net/ipv6/af_inet6.c | 32 +++++----- net/ipv6/datagram.c | 75 +++++++++++----------- net/ipv6/exthdrs.c | 12 ++-- net/ipv6/fib6_rules.c | 19 +++--- net/ipv6/icmp.c | 110 ++++++++++++++++---------------- net/ipv6/inet6_connection_sock.c | 60 +++++++++--------- net/ipv6/ip6_fib.c | 4 +- net/ipv6/ip6_flowlabel.c | 6 +- net/ipv6/ip6_output.c | 90 +++++++++++++------------- net/ipv6/ip6_tunnel.c | 50 +++++++-------- net/ipv6/ip6mr.c | 53 ++++++++-------- net/ipv6/ipv6_sockglue.c | 10 +-- net/ipv6/mcast.c | 12 ++-- net/ipv6/mip6.c | 13 ++-- net/ipv6/ndisc.c | 14 ++--- net/ipv6/netfilter.c | 18 +++--- net/ipv6/netfilter/ip6t_REJECT.c | 20 +++--- net/ipv6/raw.c | 79 ++++++++++++----------- net/ipv6/route.c | 96 ++++++++++++++-------------- net/ipv6/syncookies.c | 26 ++++---- net/ipv6/tcp_ipv6.c | 114 ++++++++++++++++----------------- net/ipv6/udp.c | 76 +++++++++++----------- net/ipv6/xfrm6_policy.c | 3 +- net/netfilter/ipvs/ip_vs_ctl.c | 10 ++- net/netfilter/ipvs/ip_vs_xmit.c | 14 ++--- net/netfilter/xt_TEE.c | 12 ++-- net/sctp/ipv6.c | 42 ++++++------- 35 files changed, 632 insertions(+), 630 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 3c2b309ab891..e0ef5fdc361e 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -231,28 +231,28 @@ static int addr6_resolve(struct sockaddr_in6 *src_in, struct sockaddr_in6 *dst_in, struct rdma_dev_addr *addr) { - struct flowi fl; + struct flowi6 fl6; struct neighbour *neigh; struct dst_entry *dst; int ret; - memset(&fl, 0, sizeof fl); - ipv6_addr_copy(&fl.fl6_dst, &dst_in->sin6_addr); - ipv6_addr_copy(&fl.fl6_src, &src_in->sin6_addr); - fl.flowi_oif = addr->bound_dev_if; + memset(&fl6, 0, sizeof fl6); + ipv6_addr_copy(&fl6.daddr, &dst_in->sin6_addr); + ipv6_addr_copy(&fl6.saddr, &src_in->sin6_addr); + fl6.flowi6_oif = addr->bound_dev_if; - dst = ip6_route_output(&init_net, NULL, &fl); + dst = ip6_route_output(&init_net, NULL, &fl6); if ((ret = dst->error)) goto put; - if (ipv6_addr_any(&fl.fl6_src)) { + if (ipv6_addr_any(&fl6.saddr)) { ret = ipv6_dev_get_saddr(&init_net, ip6_dst_idev(dst)->dev, - &fl.fl6_dst, 0, &fl.fl6_src); + &fl6.daddr, 0, &fl6.saddr); if (ret) goto put; src_in->sin6_family = AF_INET6; - ipv6_addr_copy(&src_in->sin6_addr, &fl.fl6_src); + ipv6_addr_copy(&src_in->sin6_addr, &fl6.saddr); } if (dst->dev->flags & IFF_LOOPBACK) { diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index c8922f69705e..8cca60e43444 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -3424,14 +3424,14 @@ static int cnic_get_v6_route(struct sockaddr_in6 *dst_addr, struct dst_entry **dst) { #if defined(CONFIG_IPV6) || (defined(CONFIG_IPV6_MODULE) && defined(MODULE)) - struct flowi fl; + struct flowi6 fl6; - memset(&fl, 0, sizeof(fl)); - ipv6_addr_copy(&fl.fl6_dst, &dst_addr->sin6_addr); - if (ipv6_addr_type(&fl.fl6_dst) & IPV6_ADDR_LINKLOCAL) - fl.flowi_oif = dst_addr->sin6_scope_id; + memset(&fl6, 0, sizeof(fl6)); + ipv6_addr_copy(&fl6.daddr, &dst_addr->sin6_addr); + if (ipv6_addr_type(&fl6.daddr) & IPV6_ADDR_LINKLOCAL) + fl6.flowi6_oif = dst_addr->sin6_scope_id; - *dst = ip6_route_output(&init_net, NULL, &fl); + *dst = ip6_route_output(&init_net, NULL, &fl6); if (*dst) return 0; #endif diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h index 4c4c74ec5987..ba45e6bc0764 100644 --- a/include/linux/icmpv6.h +++ b/include/linux/icmpv6.h @@ -183,10 +183,10 @@ extern void icmpv6_cleanup(void); extern void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos); -struct flowi; +struct flowi6; struct in6_addr; extern void icmpv6_flow_init(struct sock *sk, - struct flowi *fl, + struct flowi6 *fl6, u8 type, const struct in6_addr *saddr, const struct in6_addr *daddr, diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 46a6e8ae232c..bc3cde0a810c 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -183,7 +183,7 @@ struct fib6_table { typedef struct rt6_info *(*pol_lookup_t)(struct net *, struct fib6_table *, - struct flowi *, int); + struct flowi6 *, int); /* * exported functions @@ -192,7 +192,7 @@ typedef struct rt6_info *(*pol_lookup_t)(struct net *, extern struct fib6_table *fib6_get_table(struct net *net, u32 id); extern struct fib6_table *fib6_new_table(struct net *net, u32 id); extern struct dst_entry *fib6_rule_lookup(struct net *net, - struct flowi *fl, int flags, + struct flowi6 *fl6, int flags, pol_lookup_t lookup); extern struct fib6_node *fib6_lookup(struct fib6_node *root, diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 8552f0a2e854..642a80bb42cf 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -71,7 +71,7 @@ extern void ip6_route_input(struct sk_buff *skb); extern struct dst_entry * ip6_route_output(struct net *net, struct sock *sk, - struct flowi *fl); + struct flowi6 *fl6); extern int ip6_route_init(void); extern void ip6_route_cleanup(void); diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 4635a5c80967..34200f9e6805 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -492,7 +492,7 @@ extern int ip6_rcv_finish(struct sk_buff *skb); */ extern int ip6_xmit(struct sock *sk, struct sk_buff *skb, - struct flowi *fl, + struct flowi6 *fl6, struct ipv6_txoptions *opt); extern int ip6_nd_hdr(struct sock *sk, @@ -512,7 +512,7 @@ extern int ip6_append_data(struct sock *sk, int hlimit, int tclass, struct ipv6_txoptions *opt, - struct flowi *fl, + struct flowi6 *fl6, struct rt6_info *rt, unsigned int flags, int dontfrag); @@ -523,13 +523,13 @@ extern void ip6_flush_pending_frames(struct sock *sk); extern int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, - struct flowi *fl); + struct flowi6 *fl6); extern struct dst_entry * ip6_dst_lookup_flow(struct sock *sk, - struct flowi *fl, + struct flowi6 *fl6, const struct in6_addr *final_dst, bool can_sleep); extern struct dst_entry * ip6_sk_dst_lookup_flow(struct sock *sk, - struct flowi *fl, + struct flowi6 *fl6, const struct in6_addr *final_dst, bool can_sleep); extern struct dst_entry * ip6_blackhole_route(struct net *net, @@ -566,7 +566,7 @@ extern int ipv6_ext_hdr(u8 nexthdr); extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type); -extern struct in6_addr *fl6_update_dst(struct flowi *fl, +extern struct in6_addr *fl6_update_dst(struct flowi6 *fl6, const struct ipv6_txoptions *opt, struct in6_addr *orig); @@ -600,8 +600,8 @@ extern int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len); extern int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len); extern void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port, u32 info, u8 *payload); -extern void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info); -extern void ipv6_local_rxpmtu(struct sock *sk, struct flowi *fl, u32 mtu); +extern void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info); +extern void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu); extern int inet6_release(struct socket *sock); extern int inet6_bind(struct socket *sock, struct sockaddr *uaddr, diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h index 42a0eb68b7b6..eeb077dd735f 100644 --- a/include/net/transp_v6.h +++ b/include/net/transp_v6.h @@ -14,7 +14,7 @@ extern struct proto udpv6_prot; extern struct proto udplitev6_prot; extern struct proto tcpv6_prot; -struct flowi; +struct flowi6; /* extention headers */ extern int ipv6_exthdrs_init(void); @@ -42,7 +42,7 @@ extern int datagram_recv_ctl(struct sock *sk, extern int datagram_send_ctl(struct net *net, struct msghdr *msg, - struct flowi *fl, + struct flowi6 *fl6, struct ipv6_txoptions *opt, int *hlimit, int *tclass, int *dontfrag); diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 2b351c6da49a..8d26c122de64 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -147,22 +147,22 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, dst = __sk_dst_check(sk, np->dst_cookie); if (dst == NULL) { struct inet_sock *inet = inet_sk(sk); - struct flowi fl; + struct flowi6 fl6; /* BUGGG_FUTURE: Again, it is not clear how to handle rthdr case. Ignore this complexity for now. */ - memset(&fl, 0, sizeof(fl)); - fl.flowi_proto = IPPROTO_DCCP; - ipv6_addr_copy(&fl.fl6_dst, &np->daddr); - ipv6_addr_copy(&fl.fl6_src, &np->saddr); - fl.flowi_oif = sk->sk_bound_dev_if; - fl.fl6_dport = inet->inet_dport; - fl.fl6_sport = inet->inet_sport; - security_sk_classify_flow(sk, &fl); - - dst = ip6_dst_lookup_flow(sk, &fl, NULL, false); + memset(&fl6, 0, sizeof(fl6)); + fl6.flowi6_proto = IPPROTO_DCCP; + ipv6_addr_copy(&fl6.daddr, &np->daddr); + ipv6_addr_copy(&fl6.saddr, &np->saddr); + fl6.flowi6_oif = sk->sk_bound_dev_if; + fl6.uli.ports.dport = inet->inet_dport; + fl6.uli.ports.sport = inet->inet_sport; + security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); + + dst = ip6_dst_lookup_flow(sk, &fl6, NULL, false); if (IS_ERR(dst)) { sk->sk_err_soft = -PTR_ERR(dst); goto out; @@ -243,25 +243,25 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req, struct sk_buff *skb; struct ipv6_txoptions *opt = NULL; struct in6_addr *final_p, final; - struct flowi fl; + struct flowi6 fl6; int err = -1; struct dst_entry *dst; - memset(&fl, 0, sizeof(fl)); - fl.flowi_proto = IPPROTO_DCCP; - ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr); - ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr); - fl.fl6_flowlabel = 0; - fl.flowi_oif = ireq6->iif; - fl.fl6_dport = inet_rsk(req)->rmt_port; - fl.fl6_sport = inet_rsk(req)->loc_port; - security_req_classify_flow(req, &fl); + memset(&fl6, 0, sizeof(fl6)); + fl6.flowi6_proto = IPPROTO_DCCP; + ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr); + ipv6_addr_copy(&fl6.saddr, &ireq6->loc_addr); + fl6.flowlabel = 0; + fl6.flowi6_oif = ireq6->iif; + fl6.uli.ports.dport = inet_rsk(req)->rmt_port; + fl6.uli.ports.sport = inet_rsk(req)->loc_port; + security_req_classify_flow(req, flowi6_to_flowi(&fl6)); opt = np->opt; - final_p = fl6_update_dst(&fl, opt, &final); + final_p = fl6_update_dst(&fl6, opt, &final); - dst = ip6_dst_lookup_flow(sk, &fl, final_p, false); + dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); if (IS_ERR(dst)) { err = PTR_ERR(dst); dst = NULL; @@ -275,8 +275,8 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req, dh->dccph_checksum = dccp_v6_csum_finish(skb, &ireq6->loc_addr, &ireq6->rmt_addr); - ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr); - err = ip6_xmit(sk, skb, &fl, opt); + ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr); + err = ip6_xmit(sk, skb, &fl6, opt); err = net_xmit_eval(err); } @@ -298,7 +298,7 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb) { struct ipv6hdr *rxip6h; struct sk_buff *skb; - struct flowi fl; + struct flowi6 fl6; struct net *net = dev_net(skb_dst(rxskb)->dev); struct sock *ctl_sk = net->dccp.v6_ctl_sk; struct dst_entry *dst; @@ -317,21 +317,21 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb) dccp_hdr(skb)->dccph_checksum = dccp_v6_csum_finish(skb, &rxip6h->saddr, &rxip6h->daddr); - memset(&fl, 0, sizeof(fl)); - ipv6_addr_copy(&fl.fl6_dst, &rxip6h->saddr); - ipv6_addr_copy(&fl.fl6_src, &rxip6h->daddr); + memset(&fl6, 0, sizeof(fl6)); + ipv6_addr_copy(&fl6.daddr, &rxip6h->saddr); + ipv6_addr_copy(&fl6.saddr, &rxip6h->daddr); - fl.flowi_proto = IPPROTO_DCCP; - fl.flowi_oif = inet6_iif(rxskb); - fl.fl6_dport = dccp_hdr(skb)->dccph_dport; - fl.fl6_sport = dccp_hdr(skb)->dccph_sport; - security_skb_classify_flow(rxskb, &fl); + fl6.flowi6_proto = IPPROTO_DCCP; + fl6.flowi6_oif = inet6_iif(rxskb); + fl6.uli.ports.dport = dccp_hdr(skb)->dccph_dport; + fl6.uli.ports.sport = dccp_hdr(skb)->dccph_sport; + security_skb_classify_flow(rxskb, flowi6_to_flowi(&fl6)); /* sk = NULL, but it is safe for now. RST socket required. */ - dst = ip6_dst_lookup_flow(ctl_sk, &fl, NULL, false); + dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL, false); if (!IS_ERR(dst)) { skb_dst_set(skb, dst); - ip6_xmit(ctl_sk, skb, &fl, NULL); + ip6_xmit(ctl_sk, skb, &fl6, NULL); DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS); DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS); return; @@ -527,19 +527,19 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, if (dst == NULL) { struct in6_addr *final_p, final; - struct flowi fl; - - memset(&fl, 0, sizeof(fl)); - fl.flowi_proto = IPPROTO_DCCP; - ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr); - final_p = fl6_update_dst(&fl, opt, &final); - ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr); - fl.flowi_oif = sk->sk_bound_dev_if; - fl.fl6_dport = inet_rsk(req)->rmt_port; - fl.fl6_sport = inet_rsk(req)->loc_port; - security_sk_classify_flow(sk, &fl); - - dst = ip6_dst_lookup_flow(sk, &fl, final_p, false); + struct flowi6 fl6; + + memset(&fl6, 0, sizeof(fl6)); + fl6.flowi6_proto = IPPROTO_DCCP; + ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr); + final_p = fl6_update_dst(&fl6, opt, &final); + ipv6_addr_copy(&fl6.saddr, &ireq6->loc_addr); + fl6.flowi6_oif = sk->sk_bound_dev_if; + fl6.uli.ports.dport = inet_rsk(req)->rmt_port; + fl6.uli.ports.sport = inet_rsk(req)->loc_port; + security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); + + dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); if (IS_ERR(dst)) goto out; } @@ -859,7 +859,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, struct ipv6_pinfo *np = inet6_sk(sk); struct dccp_sock *dp = dccp_sk(sk); struct in6_addr *saddr = NULL, *final_p, final; - struct flowi fl; + struct flowi6 fl6; struct dst_entry *dst; int addr_type; int err; @@ -872,14 +872,14 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, if (usin->sin6_family != AF_INET6) return -EAFNOSUPPORT; - memset(&fl, 0, sizeof(fl)); + memset(&fl6, 0, sizeof(fl6)); if (np->sndflow) { - fl.fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK; - IP6_ECN_flow_init(fl.fl6_flowlabel); - if (fl.fl6_flowlabel & IPV6_FLOWLABEL_MASK) { + fl6.flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK; + IP6_ECN_flow_init(fl6.flowlabel); + if (fl6.flowlabel & IPV6_FLOWLABEL_MASK) { struct ip6_flowlabel *flowlabel; - flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel); + flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); if (flowlabel == NULL) return -EINVAL; ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst); @@ -916,7 +916,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, } ipv6_addr_copy(&np->daddr, &usin->sin6_addr); - np->flow_label = fl.fl6_flowlabel; + np->flow_label = fl6.flowlabel; /* * DCCP over IPv4 @@ -953,24 +953,24 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, if (!ipv6_addr_any(&np->rcv_saddr)) saddr = &np->rcv_saddr; - fl.flowi_proto = IPPROTO_DCCP; - ipv6_addr_copy(&fl.fl6_dst, &np->daddr); - ipv6_addr_copy(&fl.fl6_src, saddr ? saddr : &np->saddr); - fl.flowi_oif = sk->sk_bound_dev_if; - fl.fl6_dport = usin->sin6_port; - fl.fl6_sport = inet->inet_sport; - security_sk_classify_flow(sk, &fl); + fl6.flowi6_proto = IPPROTO_DCCP; + ipv6_addr_copy(&fl6.daddr, &np->daddr); + ipv6_addr_copy(&fl6.saddr, saddr ? saddr : &np->saddr); + fl6.flowi6_oif = sk->sk_bound_dev_if; + fl6.uli.ports.dport = usin->sin6_port; + fl6.uli.ports.sport = inet->inet_sport; + security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); - final_p = fl6_update_dst(&fl, np->opt, &final); + final_p = fl6_update_dst(&fl6, np->opt, &final); - dst = ip6_dst_lookup_flow(sk, &fl, final_p, true); + dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true); if (IS_ERR(dst)) { err = PTR_ERR(dst); goto failure; } if (saddr == NULL) { - saddr = &fl.fl6_src; + saddr = &fl6.saddr; ipv6_addr_copy(&np->rcv_saddr, saddr); } diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 923febea8989..689eea6553fd 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -652,22 +652,22 @@ int inet6_sk_rebuild_header(struct sock *sk) if (dst == NULL) { struct inet_sock *inet = inet_sk(sk); struct in6_addr *final_p, final; - struct flowi fl; - - memset(&fl, 0, sizeof(fl)); - fl.flowi_proto = sk->sk_protocol; - ipv6_addr_copy(&fl.fl6_dst, &np->daddr); - ipv6_addr_copy(&fl.fl6_src, &np->saddr); - fl.fl6_flowlabel = np->flow_label; - fl.flowi_oif = sk->sk_bound_dev_if; - fl.flowi_mark = sk->sk_mark; - fl.fl6_dport = inet->inet_dport; - fl.fl6_sport = inet->inet_sport; - security_sk_classify_flow(sk, &fl); - - final_p = fl6_update_dst(&fl, np->opt, &final); - - dst = ip6_dst_lookup_flow(sk, &fl, final_p, false); + struct flowi6 fl6; + + memset(&fl6, 0, sizeof(fl6)); + fl6.flowi6_proto = sk->sk_protocol; + ipv6_addr_copy(&fl6.daddr, &np->daddr); + ipv6_addr_copy(&fl6.saddr, &np->saddr); + fl6.flowlabel = np->flow_label; + fl6.flowi6_oif = sk->sk_bound_dev_if; + fl6.flowi6_mark = sk->sk_mark; + fl6.uli.ports.dport = inet->inet_dport; + fl6.uli.ports.sport = inet->inet_sport; + security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); + + final_p = fl6_update_dst(&fl6, np->opt, &final); + + dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); if (IS_ERR(dst)) { sk->sk_route_caps = 0; sk->sk_err_soft = -PTR_ERR(dst); diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 07e03e68243b..04ae676d14ee 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -40,7 +40,7 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) struct ipv6_pinfo *np = inet6_sk(sk); struct in6_addr *daddr, *final_p, final; struct dst_entry *dst; - struct flowi fl; + struct flowi6 fl6; struct ip6_flowlabel *flowlabel = NULL; struct ipv6_txoptions *opt; int addr_type; @@ -59,11 +59,11 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) if (usin->sin6_family != AF_INET6) return -EAFNOSUPPORT; - memset(&fl, 0, sizeof(fl)); + memset(&fl6, 0, sizeof(fl6)); if (np->sndflow) { - fl.fl6_flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK; - if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) { - flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel); + fl6.flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK; + if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) { + flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); if (flowlabel == NULL) return -EINVAL; ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst); @@ -137,7 +137,7 @@ ipv4_connected: } ipv6_addr_copy(&np->daddr, daddr); - np->flow_label = fl.fl6_flowlabel; + np->flow_label = fl6.flowlabel; inet->inet_dport = usin->sin6_port; @@ -146,23 +146,23 @@ ipv4_connected: * destination cache for it. */ - fl.flowi_proto = sk->sk_protocol; - ipv6_addr_copy(&fl.fl6_dst, &np->daddr); - ipv6_addr_copy(&fl.fl6_src, &np->saddr); - fl.flowi_oif = sk->sk_bound_dev_if; - fl.flowi_mark = sk->sk_mark; - fl.fl6_dport = inet->inet_dport; - fl.fl6_sport = inet->inet_sport; + fl6.flowi6_proto = sk->sk_protocol; + ipv6_addr_copy(&fl6.daddr, &np->daddr); + ipv6_addr_copy(&fl6.saddr, &np->saddr); + fl6.flowi6_oif = sk->sk_bound_dev_if; + fl6.flowi6_mark = sk->sk_mark; + fl6.uli.ports.dport = inet->inet_dport; + fl6.uli.ports.sport = inet->inet_sport; - if (!fl.flowi_oif && (addr_type&IPV6_ADDR_MULTICAST)) - fl.flowi_oif = np->mcast_oif; + if (!fl6.flowi6_oif && (addr_type&IPV6_ADDR_MULTICAST)) + fl6.flowi6_oif = np->mcast_oif; - security_sk_classify_flow(sk, &fl); + security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); opt = flowlabel ? flowlabel->opt : np->opt; - final_p = fl6_update_dst(&fl, opt, &final); + final_p = fl6_update_dst(&fl6, opt, &final); - dst = ip6_dst_lookup_flow(sk, &fl, final_p, true); + dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true); err = 0; if (IS_ERR(dst)) { err = PTR_ERR(dst); @@ -172,20 +172,20 @@ ipv4_connected: /* source address lookup done in ip6_dst_lookup */ if (ipv6_addr_any(&np->saddr)) - ipv6_addr_copy(&np->saddr, &fl.fl6_src); + ipv6_addr_copy(&np->saddr, &fl6.saddr); if (ipv6_addr_any(&np->rcv_saddr)) { - ipv6_addr_copy(&np->rcv_saddr, &fl.fl6_src); + ipv6_addr_copy(&np->rcv_saddr, &fl6.saddr); inet->inet_rcv_saddr = LOOPBACK4_IPV6; if (sk->sk_prot->rehash) sk->sk_prot->rehash(sk); } ip6_dst_store(sk, dst, - ipv6_addr_equal(&fl.fl6_dst, &np->daddr) ? + ipv6_addr_equal(&fl6.daddr, &np->daddr) ? &np->daddr : NULL, #ifdef CONFIG_IPV6_SUBTREES - ipv6_addr_equal(&fl.fl6_src, &np->saddr) ? + ipv6_addr_equal(&fl6.saddr, &np->saddr) ? &np->saddr : #endif NULL); @@ -231,7 +231,7 @@ void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, kfree_skb(skb); } -void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info) +void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info) { struct ipv6_pinfo *np = inet6_sk(sk); struct sock_exterr_skb *serr; @@ -250,7 +250,7 @@ void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info) skb_put(skb, sizeof(struct ipv6hdr)); skb_reset_network_header(skb); iph = ipv6_hdr(skb); - ipv6_addr_copy(&iph->daddr, &fl->fl6_dst); + ipv6_addr_copy(&iph->daddr, &fl6->daddr); serr = SKB_EXT_ERR(skb); serr->ee.ee_errno = err; @@ -261,7 +261,7 @@ void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info) serr->ee.ee_info = info; serr->ee.ee_data = 0; serr->addr_offset = (u8 *)&iph->daddr - skb_network_header(skb); - serr->port = fl->fl6_dport; + serr->port = fl6->uli.ports.dport; __skb_pull(skb, skb_tail_pointer(skb) - skb->data); skb_reset_transport_header(skb); @@ -270,7 +270,7 @@ void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info) kfree_skb(skb); } -void ipv6_local_rxpmtu(struct sock *sk, struct flowi *fl, u32 mtu) +void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu) { struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6hdr *iph; @@ -287,7 +287,7 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi *fl, u32 mtu) skb_put(skb, sizeof(struct ipv6hdr)); skb_reset_network_header(skb); iph = ipv6_hdr(skb); - ipv6_addr_copy(&iph->daddr, &fl->fl6_dst); + ipv6_addr_copy(&iph->daddr, &fl6->daddr); mtu_info = IP6CBMTU(skb); if (!mtu_info) { @@ -299,7 +299,7 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi *fl, u32 mtu) mtu_info->ip6m_addr.sin6_family = AF_INET6; mtu_info->ip6m_addr.sin6_port = 0; mtu_info->ip6m_addr.sin6_flowinfo = 0; - mtu_info->ip6m_addr.sin6_scope_id = fl->flowi_oif; + mtu_info->ip6m_addr.sin6_scope_id = fl6->flowi6_oif; ipv6_addr_copy(&mtu_info->ip6m_addr.sin6_addr, &ipv6_hdr(skb)->daddr); __skb_pull(skb, skb_tail_pointer(skb) - skb->data); @@ -593,7 +593,7 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) } int datagram_send_ctl(struct net *net, - struct msghdr *msg, struct flowi *fl, + struct msghdr *msg, struct flowi6 *fl6, struct ipv6_txoptions *opt, int *hlimit, int *tclass, int *dontfrag) { @@ -629,16 +629,17 @@ int datagram_send_ctl(struct net *net, src_info = (struct in6_pktinfo *)CMSG_DATA(cmsg); if (src_info->ipi6_ifindex) { - if (fl->flowi_oif && src_info->ipi6_ifindex != fl->flowi_oif) + if (fl6->flowi6_oif && + src_info->ipi6_ifindex != fl6->flowi6_oif) return -EINVAL; - fl->flowi_oif = src_info->ipi6_ifindex; + fl6->flowi6_oif = src_info->ipi6_ifindex; } addr_type = __ipv6_addr_type(&src_info->ipi6_addr); rcu_read_lock(); - if (fl->flowi_oif) { - dev = dev_get_by_index_rcu(net, fl->flowi_oif); + if (fl6->flowi6_oif) { + dev = dev_get_by_index_rcu(net, fl6->flowi6_oif); if (!dev) { rcu_read_unlock(); return -ENODEV; @@ -654,7 +655,7 @@ int datagram_send_ctl(struct net *net, strict ? dev : NULL, 0)) err = -EINVAL; else - ipv6_addr_copy(&fl->fl6_src, &src_info->ipi6_addr); + ipv6_addr_copy(&fl6->saddr, &src_info->ipi6_addr); } rcu_read_unlock(); @@ -671,13 +672,13 @@ int datagram_send_ctl(struct net *net, goto exit_f; } - if (fl->fl6_flowlabel&IPV6_FLOWINFO_MASK) { - if ((fl->fl6_flowlabel^*(__be32 *)CMSG_DATA(cmsg))&~IPV6_FLOWINFO_MASK) { + if (fl6->flowlabel&IPV6_FLOWINFO_MASK) { + if ((fl6->flowlabel^*(__be32 *)CMSG_DATA(cmsg))&~IPV6_FLOWINFO_MASK) { err = -EINVAL; goto exit_f; } } - fl->fl6_flowlabel = IPV6_FLOWINFO_MASK & *(__be32 *)CMSG_DATA(cmsg); + fl6->flowlabel = IPV6_FLOWINFO_MASK & *(__be32 *)CMSG_DATA(cmsg); break; case IPV6_2292HOPOPTS: diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 262f105d23b9..79a485e8a700 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -876,22 +876,22 @@ struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space, * fl6_update_dst - update flowi destination address with info given * by srcrt option, if any. * - * @fl: flowi for which fl6_dst is to be updated + * @fl6: flowi6 for which daddr is to be updated * @opt: struct ipv6_txoptions in which to look for srcrt opt - * @orig: copy of original fl6_dst address if modified + * @orig: copy of original daddr address if modified * * Returns NULL if no txoptions or no srcrt, otherwise returns orig - * and initial value of fl->fl6_dst set in orig + * and initial value of fl6->daddr set in orig */ -struct in6_addr *fl6_update_dst(struct flowi *fl, +struct in6_addr *fl6_update_dst(struct flowi6 *fl6, const struct ipv6_txoptions *opt, struct in6_addr *orig) { if (!opt || !opt->srcrt) return NULL; - ipv6_addr_copy(orig, &fl->fl6_dst); - ipv6_addr_copy(&fl->fl6_dst, ((struct rt0_hdr *)opt->srcrt)->addr); + ipv6_addr_copy(orig, &fl6->daddr); + ipv6_addr_copy(&fl6->daddr, ((struct rt0_hdr *)opt->srcrt)->addr); return orig; } diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index d829874d8946..34d244df907d 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -29,7 +29,7 @@ struct fib6_rule u8 tclass; }; -struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, +struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6, int flags, pol_lookup_t lookup) { struct fib_lookup_arg arg = { @@ -37,7 +37,8 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, .flags = FIB_LOOKUP_NOREF, }; - fib_rules_lookup(net->ipv6.fib6_rules_ops, fl, flags, &arg); + fib_rules_lookup(net->ipv6.fib6_rules_ops, + flowi6_to_flowi(fl6), flags, &arg); if (arg.result) return arg.result; @@ -49,6 +50,7 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, int flags, struct fib_lookup_arg *arg) { + struct flowi6 *flp6 = &flp->u.ip6; struct rt6_info *rt = NULL; struct fib6_table *table; struct net *net = rule->fr_net; @@ -71,7 +73,7 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, table = fib6_get_table(net, rule->table); if (table) - rt = lookup(net, table, flp, flags); + rt = lookup(net, table, flp6, flags); if (rt != net->ipv6.ip6_null_entry) { struct fib6_rule *r = (struct fib6_rule *)rule; @@ -86,14 +88,14 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, if (ipv6_dev_get_saddr(net, ip6_dst_idev(&rt->dst)->dev, - &flp->fl6_dst, + &flp6->daddr, rt6_flags2srcprefs(flags), &saddr)) goto again; if (!ipv6_prefix_equal(&saddr, &r->src.addr, r->src.plen)) goto again; - ipv6_addr_copy(&flp->fl6_src, &saddr); + ipv6_addr_copy(&flp6->saddr, &saddr); } goto out; } @@ -113,9 +115,10 @@ out: static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) { struct fib6_rule *r = (struct fib6_rule *) rule; + struct flowi6 *fl6 = &fl->u.ip6; if (r->dst.plen && - !ipv6_prefix_equal(&fl->fl6_dst, &r->dst.addr, r->dst.plen)) + !ipv6_prefix_equal(&fl6->daddr, &r->dst.addr, r->dst.plen)) return 0; /* @@ -125,14 +128,14 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) */ if (r->src.plen) { if (flags & RT6_LOOKUP_F_HAS_SADDR) { - if (!ipv6_prefix_equal(&fl->fl6_src, &r->src.addr, + if (!ipv6_prefix_equal(&fl6->saddr, &r->src.addr, r->src.plen)) return 0; } else if (!(r->common.flags & FIB_RULE_FIND_SADDR)) return 0; } - if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff)) + if (r->tclass && r->tclass != ((ntohl(fl6->flowlabel) >> 20) & 0xff)) return 0; return 1; diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 52ff7aa1f9fc..f7b9041f7845 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -158,7 +158,7 @@ static int is_ineligible(struct sk_buff *skb) * Check the ICMP output rate limit */ static inline bool icmpv6_xrlim_allow(struct sock *sk, u8 type, - struct flowi *fl) + struct flowi6 *fl6) { struct dst_entry *dst; struct net *net = sock_net(sk); @@ -177,7 +177,7 @@ static inline bool icmpv6_xrlim_allow(struct sock *sk, u8 type, * XXX: perhaps the expire for routing entries cloned by * this lookup should be more aggressive (not longer than timeout). */ - dst = ip6_route_output(net, sk, fl); + dst = ip6_route_output(net, sk, fl6); if (dst->error) { IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); @@ -217,7 +217,7 @@ static __inline__ int opt_unrec(struct sk_buff *skb, __u32 offset) return (*op & 0xC0) == 0x80; } -static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct icmp6hdr *thdr, int len) +static int icmpv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6, struct icmp6hdr *thdr, int len) { struct sk_buff *skb; struct icmp6hdr *icmp6h; @@ -233,9 +233,9 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct if (skb_queue_len(&sk->sk_write_queue) == 1) { skb->csum = csum_partial(icmp6h, sizeof(struct icmp6hdr), skb->csum); - icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src, - &fl->fl6_dst, - len, fl->flowi_proto, + icmp6h->icmp6_cksum = csum_ipv6_magic(&fl6->saddr, + &fl6->daddr, + len, fl6->flowi6_proto, skb->csum); } else { __wsum tmp_csum = 0; @@ -246,9 +246,9 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct tmp_csum = csum_partial(icmp6h, sizeof(struct icmp6hdr), tmp_csum); - icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src, - &fl->fl6_dst, - len, fl->flowi_proto, + icmp6h->icmp6_cksum = csum_ipv6_magic(&fl6->saddr, + &fl6->daddr, + len, fl6->flowi6_proto, tmp_csum); } ip6_push_pending_frames(sk); @@ -301,13 +301,13 @@ static inline void mip6_addr_swap(struct sk_buff *skb) {} #endif static struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *skb, - struct sock *sk, struct flowi *fl) + struct sock *sk, struct flowi6 *fl6) { struct dst_entry *dst, *dst2; - struct flowi fl2; + struct flowi6 fl2; int err; - err = ip6_dst_lookup(sk, &dst, fl); + err = ip6_dst_lookup(sk, &dst, fl6); if (err) return ERR_PTR(err); @@ -324,7 +324,7 @@ static struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *sk /* No need to clone since we're just using its address. */ dst2 = dst; - dst = xfrm_lookup(net, dst, fl, sk, 0); + dst = xfrm_lookup(net, dst, flowi6_to_flowi(fl6), sk, 0); if (!IS_ERR(dst)) { if (dst != dst2) return dst; @@ -335,7 +335,7 @@ static struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *sk return dst; } - err = xfrm_decode_session_reverse(skb, &fl2, AF_INET6); + err = xfrm_decode_session_reverse(skb, flowi6_to_flowi(&fl2), AF_INET6); if (err) goto relookup_failed; @@ -343,7 +343,7 @@ static struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *sk if (err) goto relookup_failed; - dst2 = xfrm_lookup(net, dst2, &fl2, sk, XFRM_LOOKUP_ICMP); + dst2 = xfrm_lookup(net, dst2, flowi6_to_flowi(&fl2), sk, XFRM_LOOKUP_ICMP); if (!IS_ERR(dst2)) { dst_release(dst); dst = dst2; @@ -375,7 +375,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) struct in6_addr *saddr = NULL; struct dst_entry *dst; struct icmp6hdr tmp_hdr; - struct flowi fl; + struct flowi6 fl6; struct icmpv6_msg msg; int iif = 0; int addr_type = 0; @@ -442,22 +442,22 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) mip6_addr_swap(skb); - memset(&fl, 0, sizeof(fl)); - fl.flowi_proto = IPPROTO_ICMPV6; - ipv6_addr_copy(&fl.fl6_dst, &hdr->saddr); + memset(&fl6, 0, sizeof(fl6)); + fl6.flowi6_proto = IPPROTO_ICMPV6; + ipv6_addr_copy(&fl6.daddr, &hdr->saddr); if (saddr) - ipv6_addr_copy(&fl.fl6_src, saddr); - fl.flowi_oif = iif; - fl.fl6_icmp_type = type; - fl.fl6_icmp_code = code; - security_skb_classify_flow(skb, &fl); + ipv6_addr_copy(&fl6.saddr, saddr); + fl6.flowi6_oif = iif; + fl6.uli.icmpt.type = type; + fl6.uli.icmpt.code = code; + security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); sk = icmpv6_xmit_lock(net); if (sk == NULL) return; np = inet6_sk(sk); - if (!icmpv6_xrlim_allow(sk, type, &fl)) + if (!icmpv6_xrlim_allow(sk, type, &fl6)) goto out; tmp_hdr.icmp6_type = type; @@ -465,14 +465,14 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) tmp_hdr.icmp6_cksum = 0; tmp_hdr.icmp6_pointer = htonl(info); - if (!fl.flowi_oif && ipv6_addr_is_multicast(&fl.fl6_dst)) - fl.flowi_oif = np->mcast_oif; + if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr)) + fl6.flowi6_oif = np->mcast_oif; - dst = icmpv6_route_lookup(net, skb, sk, &fl); + dst = icmpv6_route_lookup(net, skb, sk, &fl6); if (IS_ERR(dst)) goto out; - if (ipv6_addr_is_multicast(&fl.fl6_dst)) + if (ipv6_addr_is_multicast(&fl6.daddr)) hlimit = np->mcast_hops; else hlimit = np->hop_limit; @@ -495,14 +495,14 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) err = ip6_append_data(sk, icmpv6_getfrag, &msg, len + sizeof(struct icmp6hdr), sizeof(struct icmp6hdr), hlimit, - np->tclass, NULL, &fl, (struct rt6_info*)dst, + np->tclass, NULL, &fl6, (struct rt6_info*)dst, MSG_DONTWAIT, np->dontfrag); if (err) { ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS); ip6_flush_pending_frames(sk); goto out_put; } - err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, len + sizeof(struct icmp6hdr)); + err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, len + sizeof(struct icmp6hdr)); out_put: if (likely(idev != NULL)) @@ -524,7 +524,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) struct in6_addr *saddr = NULL; struct icmp6hdr *icmph = icmp6_hdr(skb); struct icmp6hdr tmp_hdr; - struct flowi fl; + struct flowi6 fl6; struct icmpv6_msg msg; struct dst_entry *dst; int err = 0; @@ -538,31 +538,31 @@ static void icmpv6_echo_reply(struct sk_buff *skb) memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr)); tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY; - memset(&fl, 0, sizeof(fl)); - fl.flowi_proto = IPPROTO_ICMPV6; - ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr); + memset(&fl6, 0, sizeof(fl6)); + fl6.flowi6_proto = IPPROTO_ICMPV6; + ipv6_addr_copy(&fl6.daddr, &ipv6_hdr(skb)->saddr); if (saddr) - ipv6_addr_copy(&fl.fl6_src, saddr); - fl.flowi_oif = skb->dev->ifindex; - fl.fl6_icmp_type = ICMPV6_ECHO_REPLY; - security_skb_classify_flow(skb, &fl); + ipv6_addr_copy(&fl6.saddr, saddr); + fl6.flowi6_oif = skb->dev->ifindex; + fl6.uli.icmpt.type = ICMPV6_ECHO_REPLY; + security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); sk = icmpv6_xmit_lock(net); if (sk == NULL) return; np = inet6_sk(sk); - if (!fl.flowi_oif && ipv6_addr_is_multicast(&fl.fl6_dst)) - fl.flowi_oif = np->mcast_oif; + if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr)) + fl6.flowi6_oif = np->mcast_oif; - err = ip6_dst_lookup(sk, &dst, &fl); + err = ip6_dst_lookup(sk, &dst, &fl6); if (err) goto out; - dst = xfrm_lookup(net, dst, &fl, sk, 0); + dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), sk, 0); if (IS_ERR(dst)) goto out; - if (ipv6_addr_is_multicast(&fl.fl6_dst)) + if (ipv6_addr_is_multicast(&fl6.daddr)) hlimit = np->mcast_hops; else hlimit = np->hop_limit; @@ -576,7 +576,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) msg.type = ICMPV6_ECHO_REPLY; err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr), - sizeof(struct icmp6hdr), hlimit, np->tclass, NULL, &fl, + sizeof(struct icmp6hdr), hlimit, np->tclass, NULL, &fl6, (struct rt6_info*)dst, MSG_DONTWAIT, np->dontfrag); @@ -585,7 +585,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) ip6_flush_pending_frames(sk); goto out_put; } - err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, skb->len + sizeof(struct icmp6hdr)); + err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, skb->len + sizeof(struct icmp6hdr)); out_put: if (likely(idev != NULL)) @@ -784,20 +784,20 @@ drop_no_count: return 0; } -void icmpv6_flow_init(struct sock *sk, struct flowi *fl, +void icmpv6_flow_init(struct sock *sk, struct flowi6 *fl6, u8 type, const struct in6_addr *saddr, const struct in6_addr *daddr, int oif) { - memset(fl, 0, sizeof(*fl)); - ipv6_addr_copy(&fl->fl6_src, saddr); - ipv6_addr_copy(&fl->fl6_dst, daddr); - fl->flowi_proto = IPPROTO_ICMPV6; - fl->fl6_icmp_type = type; - fl->fl6_icmp_code = 0; - fl->flowi_oif = oif; - security_sk_classify_flow(sk, fl); + memset(fl6, 0, sizeof(*fl6)); + ipv6_addr_copy(&fl6->saddr, saddr); + ipv6_addr_copy(&fl6->daddr, daddr); + fl6->flowi6_proto = IPPROTO_ICMPV6; + fl6->uli.icmpt.type = type; + fl6->uli.icmpt.code = 0; + fl6->flowi6_oif = oif; + security_sk_classify_flow(sk, flowi6_to_flowi(fl6)); } /* diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 1b06a24019c6..27d669160ba6 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -61,20 +61,20 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk, struct ipv6_pinfo *np = inet6_sk(sk); struct in6_addr *final_p, final; struct dst_entry *dst; - struct flowi fl; - - memset(&fl, 0, sizeof(fl)); - fl.flowi_proto = IPPROTO_TCP; - ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); - final_p = fl6_update_dst(&fl, np->opt, &final); - ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr); - fl.flowi_oif = sk->sk_bound_dev_if; - fl.flowi_mark = sk->sk_mark; - fl.fl6_dport = inet_rsk(req)->rmt_port; - fl.fl6_sport = inet_rsk(req)->loc_port; - security_req_classify_flow(req, &fl); - - dst = ip6_dst_lookup_flow(sk, &fl, final_p, false); + struct flowi6 fl6; + + memset(&fl6, 0, sizeof(fl6)); + fl6.flowi6_proto = IPPROTO_TCP; + ipv6_addr_copy(&fl6.daddr, &treq->rmt_addr); + final_p = fl6_update_dst(&fl6, np->opt, &final); + ipv6_addr_copy(&fl6.saddr, &treq->loc_addr); + fl6.flowi6_oif = sk->sk_bound_dev_if; + fl6.flowi6_mark = sk->sk_mark; + fl6.uli.ports.dport = inet_rsk(req)->rmt_port; + fl6.uli.ports.sport = inet_rsk(req)->loc_port; + security_req_classify_flow(req, flowi6_to_flowi(&fl6)); + + dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); if (IS_ERR(dst)) return NULL; @@ -208,28 +208,28 @@ int inet6_csk_xmit(struct sk_buff *skb) struct sock *sk = skb->sk; struct inet_sock *inet = inet_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk); - struct flowi fl; + struct flowi6 fl6; struct dst_entry *dst; struct in6_addr *final_p, final; - memset(&fl, 0, sizeof(fl)); - fl.flowi_proto = sk->sk_protocol; - ipv6_addr_copy(&fl.fl6_dst, &np->daddr); - ipv6_addr_copy(&fl.fl6_src, &np->saddr); - fl.fl6_flowlabel = np->flow_label; - IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel); - fl.flowi_oif = sk->sk_bound_dev_if; - fl.flowi_mark = sk->sk_mark; - fl.fl6_sport = inet->inet_sport; - fl.fl6_dport = inet->inet_dport; - security_sk_classify_flow(sk, &fl); + memset(&fl6, 0, sizeof(fl6)); + fl6.flowi6_proto = sk->sk_protocol; + ipv6_addr_copy(&fl6.daddr, &np->daddr); + ipv6_addr_copy(&fl6.saddr, &np->saddr); + fl6.flowlabel = np->flow_label; + IP6_ECN_flow_xmit(sk, fl6.flowlabel); + fl6.flowi6_oif = sk->sk_bound_dev_if; + fl6.flowi6_mark = sk->sk_mark; + fl6.uli.ports.sport = inet->inet_sport; + fl6.uli.ports.dport = inet->inet_dport; + security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); - final_p = fl6_update_dst(&fl, np->opt, &final); + final_p = fl6_update_dst(&fl6, np->opt, &final); dst = __inet6_csk_dst_check(sk, np->dst_cookie); if (dst == NULL) { - dst = ip6_dst_lookup_flow(sk, &fl, final_p, false); + dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); if (IS_ERR(dst)) { sk->sk_err_soft = -PTR_ERR(dst); @@ -244,9 +244,9 @@ int inet6_csk_xmit(struct sk_buff *skb) skb_dst_set(skb, dst_clone(dst)); /* Restore final destination back after routing done */ - ipv6_addr_copy(&fl.fl6_dst, &np->daddr); + ipv6_addr_copy(&fl6.daddr, &np->daddr); - return ip6_xmit(sk, skb, &fl, np->opt); + return ip6_xmit(sk, skb, &fl6, np->opt); } EXPORT_SYMBOL_GPL(inet6_csk_xmit); diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index de382114609b..7548905e79e1 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -260,10 +260,10 @@ struct fib6_table *fib6_get_table(struct net *net, u32 id) return net->ipv6.fib6_main_tbl; } -struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, +struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6, int flags, pol_lookup_t lookup) { - return (struct dst_entry *) lookup(net, net->ipv6.fib6_main_tbl, fl, flags); + return (struct dst_entry *) lookup(net, net->ipv6.fib6_main_tbl, fl6, flags); } static void __net_init fib6_tables_init(struct net *net) diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index c8fa470b174b..f3caf1b8d572 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c @@ -342,7 +342,7 @@ fl_create(struct net *net, struct in6_flowlabel_req *freq, char __user *optval, if (olen > 0) { struct msghdr msg; - struct flowi flowi; + struct flowi6 flowi6; int junk; err = -ENOMEM; @@ -358,9 +358,9 @@ fl_create(struct net *net, struct in6_flowlabel_req *freq, char __user *optval, msg.msg_controllen = olen; msg.msg_control = (void*)(fl->opt+1); - flowi.flowi_oif = 0; + memset(&flowi6, 0, sizeof(flowi6)); - err = datagram_send_ctl(net, &msg, &flowi, fl->opt, &junk, + err = datagram_send_ctl(net, &msg, &flowi6, fl->opt, &junk, &junk, &junk); if (err) goto done; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 3d0f2ac868a7..18208876aa8a 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -174,15 +174,15 @@ int ip6_output(struct sk_buff *skb) * xmit an sk_buff (used by TCP, SCTP and DCCP) */ -int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, +int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6, struct ipv6_txoptions *opt) { struct net *net = sock_net(sk); struct ipv6_pinfo *np = inet6_sk(sk); - struct in6_addr *first_hop = &fl->fl6_dst; + struct in6_addr *first_hop = &fl6->daddr; struct dst_entry *dst = skb_dst(skb); struct ipv6hdr *hdr; - u8 proto = fl->flowi_proto; + u8 proto = fl6->flowi6_proto; int seg_len = skb->len; int hlimit = -1; int tclass = 0; @@ -230,13 +230,13 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, if (hlimit < 0) hlimit = ip6_dst_hoplimit(dst); - *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl->fl6_flowlabel; + *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl6->flowlabel; hdr->payload_len = htons(seg_len); hdr->nexthdr = proto; hdr->hop_limit = hlimit; - ipv6_addr_copy(&hdr->saddr, &fl->fl6_src); + ipv6_addr_copy(&hdr->saddr, &fl6->saddr); ipv6_addr_copy(&hdr->daddr, first_hop); skb->priority = sk->sk_priority; @@ -879,7 +879,7 @@ static inline int ip6_rt_check(struct rt6key *rt_key, static struct dst_entry *ip6_sk_dst_check(struct sock *sk, struct dst_entry *dst, - struct flowi *fl) + struct flowi6 *fl6) { struct ipv6_pinfo *np = inet6_sk(sk); struct rt6_info *rt = (struct rt6_info *)dst; @@ -904,11 +904,11 @@ static struct dst_entry *ip6_sk_dst_check(struct sock *sk, * sockets. * 2. oif also should be the same. */ - if (ip6_rt_check(&rt->rt6i_dst, &fl->fl6_dst, np->daddr_cache) || + if (ip6_rt_check(&rt->rt6i_dst, &fl6->daddr, np->daddr_cache) || #ifdef CONFIG_IPV6_SUBTREES - ip6_rt_check(&rt->rt6i_src, &fl->fl6_src, np->saddr_cache) || + ip6_rt_check(&rt->rt6i_src, &fl6->saddr, np->saddr_cache) || #endif - (fl->flowi_oif && fl->flowi_oif != dst->dev->ifindex)) { + (fl6->flowi6_oif && fl6->flowi6_oif != dst->dev->ifindex)) { dst_release(dst); dst = NULL; } @@ -918,22 +918,22 @@ out: } static int ip6_dst_lookup_tail(struct sock *sk, - struct dst_entry **dst, struct flowi *fl) + struct dst_entry **dst, struct flowi6 *fl6) { int err; struct net *net = sock_net(sk); if (*dst == NULL) - *dst = ip6_route_output(net, sk, fl); + *dst = ip6_route_output(net, sk, fl6); if ((err = (*dst)->error)) goto out_err_release; - if (ipv6_addr_any(&fl->fl6_src)) { + if (ipv6_addr_any(&fl6->saddr)) { err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev, - &fl->fl6_dst, + &fl6->daddr, sk ? inet6_sk(sk)->srcprefs : 0, - &fl->fl6_src); + &fl6->saddr); if (err) goto out_err_release; } @@ -949,10 +949,10 @@ static int ip6_dst_lookup_tail(struct sock *sk, */ if ((*dst)->neighbour && !((*dst)->neighbour->nud_state & NUD_VALID)) { struct inet6_ifaddr *ifp; - struct flowi fl_gw; + struct flowi6 fl_gw6; int redirect; - ifp = ipv6_get_ifaddr(net, &fl->fl6_src, + ifp = ipv6_get_ifaddr(net, &fl6->saddr, (*dst)->dev, 1); redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC); @@ -965,9 +965,9 @@ static int ip6_dst_lookup_tail(struct sock *sk, * default router instead */ dst_release(*dst); - memcpy(&fl_gw, fl, sizeof(struct flowi)); - memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr)); - *dst = ip6_route_output(net, sk, &fl_gw); + memcpy(&fl_gw6, fl6, sizeof(struct flowi6)); + memset(&fl_gw6.daddr, 0, sizeof(struct in6_addr)); + *dst = ip6_route_output(net, sk, &fl_gw6); if ((err = (*dst)->error)) goto out_err_release; } @@ -988,23 +988,23 @@ out_err_release: * ip6_dst_lookup - perform route lookup on flow * @sk: socket which provides route info * @dst: pointer to dst_entry * for result - * @fl: flow to lookup + * @fl6: flow to lookup * * This function performs a route lookup on the given flow. * * It returns zero on success, or a standard errno code on error. */ -int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl) +int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi6 *fl6) { *dst = NULL; - return ip6_dst_lookup_tail(sk, dst, fl); + return ip6_dst_lookup_tail(sk, dst, fl6); } EXPORT_SYMBOL_GPL(ip6_dst_lookup); /** * ip6_dst_lookup_flow - perform route lookup on flow with ipsec * @sk: socket which provides route info - * @fl: flow to lookup + * @fl6: flow to lookup * @final_dst: final destination address for ipsec lookup * @can_sleep: we are in a sleepable context * @@ -1013,29 +1013,29 @@ EXPORT_SYMBOL_GPL(ip6_dst_lookup); * It returns a valid dst pointer on success, or a pointer encoded * error code. */ -struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi *fl, +struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6, const struct in6_addr *final_dst, bool can_sleep) { struct dst_entry *dst = NULL; int err; - err = ip6_dst_lookup_tail(sk, &dst, fl); + err = ip6_dst_lookup_tail(sk, &dst, fl6); if (err) return ERR_PTR(err); if (final_dst) - ipv6_addr_copy(&fl->fl6_dst, final_dst); + ipv6_addr_copy(&fl6->daddr, final_dst); if (can_sleep) - fl->flowi_flags |= FLOWI_FLAG_CAN_SLEEP; + fl6->flowi6_flags |= FLOWI_FLAG_CAN_SLEEP; - return xfrm_lookup(sock_net(sk), dst, fl, sk, 0); + return xfrm_lookup(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0); } EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow); /** * ip6_sk_dst_lookup_flow - perform socket cached route lookup on flow * @sk: socket which provides the dst cache and route info - * @fl: flow to lookup + * @fl6: flow to lookup * @final_dst: final destination address for ipsec lookup * @can_sleep: we are in a sleepable context * @@ -1047,24 +1047,24 @@ EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow); * It returns a valid dst pointer on success, or a pointer encoded * error code. */ -struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi *fl, +struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6, const struct in6_addr *final_dst, bool can_sleep) { struct dst_entry *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie); int err; - dst = ip6_sk_dst_check(sk, dst, fl); + dst = ip6_sk_dst_check(sk, dst, fl6); - err = ip6_dst_lookup_tail(sk, &dst, fl); + err = ip6_dst_lookup_tail(sk, &dst, fl6); if (err) return ERR_PTR(err); if (final_dst) - ipv6_addr_copy(&fl->fl6_dst, final_dst); + ipv6_addr_copy(&fl6->daddr, final_dst); if (can_sleep) - fl->flowi_flags |= FLOWI_FLAG_CAN_SLEEP; + fl6->flowi6_flags |= FLOWI_FLAG_CAN_SLEEP; - return xfrm_lookup(sock_net(sk), dst, fl, sk, 0); + return xfrm_lookup(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0); } EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow); @@ -1145,7 +1145,7 @@ static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src, int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), void *from, int length, int transhdrlen, - int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi *fl, + int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi6 *fl6, struct rt6_info *rt, unsigned int flags, int dontfrag) { struct inet_sock *inet = inet_sk(sk); @@ -1203,7 +1203,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, } dst_hold(&rt->dst); inet->cork.dst = &rt->dst; - inet->cork.fl = *fl; + inet->cork.fl.u.ip6 = *fl6; np->cork.hop_limit = hlimit; np->cork.tclass = tclass; mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ? @@ -1224,7 +1224,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, transhdrlen += exthdrlen; } else { rt = (struct rt6_info *)inet->cork.dst; - fl = &inet->cork.fl; + fl6 = &inet->cork.fl.u.ip6; opt = np->cork.opt; transhdrlen = 0; exthdrlen = 0; @@ -1239,7 +1239,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) { if (inet->cork.length + length > sizeof(struct ipv6hdr) + IPV6_MAXPLEN - fragheaderlen) { - ipv6_local_error(sk, EMSGSIZE, fl, mtu-exthdrlen); + ipv6_local_error(sk, EMSGSIZE, fl6, mtu-exthdrlen); return -EMSGSIZE; } } @@ -1271,7 +1271,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, if (length > mtu) { int proto = sk->sk_protocol; if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){ - ipv6_local_rxpmtu(sk, fl, mtu-exthdrlen); + ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen); return -EMSGSIZE; } @@ -1516,8 +1516,8 @@ int ip6_push_pending_frames(struct sock *sk) struct ipv6hdr *hdr; struct ipv6_txoptions *opt = np->cork.opt; struct rt6_info *rt = (struct rt6_info *)inet->cork.dst; - struct flowi *fl = &inet->cork.fl; - unsigned char proto = fl->flowi_proto; + struct flowi6 *fl6 = &inet->cork.fl.u.ip6; + unsigned char proto = fl6->flowi6_proto; int err = 0; if ((skb = __skb_dequeue(&sk->sk_write_queue)) == NULL) @@ -1542,7 +1542,7 @@ int ip6_push_pending_frames(struct sock *sk) if (np->pmtudisc < IPV6_PMTUDISC_DO) skb->local_df = 1; - ipv6_addr_copy(final_dst, &fl->fl6_dst); + ipv6_addr_copy(final_dst, &fl6->daddr); __skb_pull(skb, skb_network_header_len(skb)); if (opt && opt->opt_flen) ipv6_push_frag_opts(skb, opt, &proto); @@ -1553,12 +1553,12 @@ int ip6_push_pending_frames(struct sock *sk) skb_reset_network_header(skb); hdr = ipv6_hdr(skb); - *(__be32*)hdr = fl->fl6_flowlabel | + *(__be32*)hdr = fl6->flowlabel | htonl(0x60000000 | ((int)np->cork.tclass << 20)); hdr->hop_limit = np->cork.hop_limit; hdr->nexthdr = proto; - ipv6_addr_copy(&hdr->saddr, &fl->fl6_src); + ipv6_addr_copy(&hdr->saddr, &fl6->saddr); ipv6_addr_copy(&hdr->daddr, final_dst); skb->priority = sk->sk_priority; diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index c3fc824c24d9..c1b1bd312df2 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -884,7 +884,7 @@ static inline int ip6_tnl_xmit_ctl(struct ip6_tnl *t) static int ip6_tnl_xmit2(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, - struct flowi *fl, + struct flowi6 *fl6, int encap_limit, __u32 *pmtu) { @@ -904,11 +904,11 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, if ((dst = ip6_tnl_dst_check(t)) != NULL) dst_hold(dst); else { - dst = ip6_route_output(net, NULL, fl); + dst = ip6_route_output(net, NULL, fl6); if (dst->error) goto tx_err_link_failure; - dst = xfrm_lookup(net, dst, fl, NULL, 0); + dst = xfrm_lookup(net, dst, flowi6_to_flowi(fl6), NULL, 0); if (IS_ERR(dst)) { err = PTR_ERR(dst); dst = NULL; @@ -963,7 +963,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, skb->transport_header = skb->network_header; - proto = fl->flowi_proto; + proto = fl6->flowi6_proto; if (encap_limit >= 0) { init_tel_txopt(&opt, encap_limit); ipv6_push_nfrag_opts(skb, &opt.ops, &proto, NULL); @@ -971,13 +971,13 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, skb_push(skb, sizeof(struct ipv6hdr)); skb_reset_network_header(skb); ipv6h = ipv6_hdr(skb); - *(__be32*)ipv6h = fl->fl6_flowlabel | htonl(0x60000000); + *(__be32*)ipv6h = fl6->flowlabel | htonl(0x60000000); dsfield = INET_ECN_encapsulate(0, dsfield); ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield); ipv6h->hop_limit = t->parms.hop_limit; ipv6h->nexthdr = proto; - ipv6_addr_copy(&ipv6h->saddr, &fl->fl6_src); - ipv6_addr_copy(&ipv6h->daddr, &fl->fl6_dst); + ipv6_addr_copy(&ipv6h->saddr, &fl6->saddr); + ipv6_addr_copy(&ipv6h->daddr, &fl6->daddr); nf_reset(skb); pkt_len = skb->len; err = ip6_local_out(skb); @@ -1007,7 +1007,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) struct ip6_tnl *t = netdev_priv(dev); struct iphdr *iph = ip_hdr(skb); int encap_limit = -1; - struct flowi fl; + struct flowi6 fl6; __u8 dsfield; __u32 mtu; int err; @@ -1019,16 +1019,16 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) encap_limit = t->parms.encap_limit; - memcpy(&fl, &t->fl, sizeof (fl)); - fl.flowi_proto = IPPROTO_IPIP; + memcpy(&fl6, &t->fl.u.ip6, sizeof (fl6)); + fl6.flowi6_proto = IPPROTO_IPIP; dsfield = ipv4_get_dsfield(iph); if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)) - fl.fl6_flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT) + fl6.flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT) & IPV6_TCLASS_MASK; - err = ip6_tnl_xmit2(skb, dev, dsfield, &fl, encap_limit, &mtu); + err = ip6_tnl_xmit2(skb, dev, dsfield, &fl6, encap_limit, &mtu); if (err != 0) { /* XXX: send ICMP error even if DF is not set. */ if (err == -EMSGSIZE) @@ -1047,7 +1047,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) struct ipv6hdr *ipv6h = ipv6_hdr(skb); int encap_limit = -1; __u16 offset; - struct flowi fl; + struct flowi6 fl6; __u8 dsfield; __u32 mtu; int err; @@ -1069,16 +1069,16 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) } else if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) encap_limit = t->parms.encap_limit; - memcpy(&fl, &t->fl, sizeof (fl)); - fl.flowi_proto = IPPROTO_IPV6; + memcpy(&fl6, &t->fl.u.ip6, sizeof (fl6)); + fl6.flowi6_proto = IPPROTO_IPV6; dsfield = ipv6_get_dsfield(ipv6h); if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)) - fl.fl6_flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK); + fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK); if ((t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL)) - fl.fl6_flowlabel |= (*(__be32 *) ipv6h & IPV6_FLOWLABEL_MASK); + fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_FLOWLABEL_MASK); - err = ip6_tnl_xmit2(skb, dev, dsfield, &fl, encap_limit, &mtu); + err = ip6_tnl_xmit2(skb, dev, dsfield, &fl6, encap_limit, &mtu); if (err != 0) { if (err == -EMSGSIZE) icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); @@ -1141,21 +1141,21 @@ static void ip6_tnl_link_config(struct ip6_tnl *t) { struct net_device *dev = t->dev; struct ip6_tnl_parm *p = &t->parms; - struct flowi *fl = &t->fl; + struct flowi6 *fl6 = &t->fl.u.ip6; memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr)); memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr)); /* Set up flowi template */ - ipv6_addr_copy(&fl->fl6_src, &p->laddr); - ipv6_addr_copy(&fl->fl6_dst, &p->raddr); - fl->flowi_oif = p->link; - fl->fl6_flowlabel = 0; + ipv6_addr_copy(&fl6->saddr, &p->laddr); + ipv6_addr_copy(&fl6->daddr, &p->raddr); + fl6->flowi6_oif = p->link; + fl6->flowlabel = 0; if (!(p->flags&IP6_TNL_F_USE_ORIG_TCLASS)) - fl->fl6_flowlabel |= IPV6_TCLASS_MASK & p->flowinfo; + fl6->flowlabel |= IPV6_TCLASS_MASK & p->flowinfo; if (!(p->flags&IP6_TNL_F_USE_ORIG_FLOWLABEL)) - fl->fl6_flowlabel |= IPV6_FLOWLABEL_MASK & p->flowinfo; + fl6->flowlabel |= IPV6_FLOWLABEL_MASK & p->flowinfo; ip6_tnl_set_cap(t); diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 61a8be3ac4e4..7ff0343e05c7 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -135,14 +135,15 @@ static struct mr6_table *ip6mr_get_table(struct net *net, u32 id) return NULL; } -static int ip6mr_fib_lookup(struct net *net, struct flowi *flp, +static int ip6mr_fib_lookup(struct net *net, struct flowi6 *flp6, struct mr6_table **mrt) { struct ip6mr_result res; struct fib_lookup_arg arg = { .result = &res, }; int err; - err = fib_rules_lookup(net->ipv6.mr6_rules_ops, flp, 0, &arg); + err = fib_rules_lookup(net->ipv6.mr6_rules_ops, + flowi6_to_flowi(flp6), 0, &arg); if (err < 0) return err; *mrt = res.mrt; @@ -270,7 +271,7 @@ static struct mr6_table *ip6mr_get_table(struct net *net, u32 id) return net->ipv6.mrt6; } -static int ip6mr_fib_lookup(struct net *net, struct flowi *flp, +static int ip6mr_fib_lookup(struct net *net, struct flowi6 *flp6, struct mr6_table **mrt) { *mrt = net->ipv6.mrt6; @@ -617,9 +618,9 @@ static int pim6_rcv(struct sk_buff *skb) struct net_device *reg_dev = NULL; struct net *net = dev_net(skb->dev); struct mr6_table *mrt; - struct flowi fl = { - .flowi_iif = skb->dev->ifindex, - .flowi_mark = skb->mark, + struct flowi6 fl6 = { + .flowi6_iif = skb->dev->ifindex, + .flowi6_mark = skb->mark, }; int reg_vif_num; @@ -644,7 +645,7 @@ static int pim6_rcv(struct sk_buff *skb) ntohs(encap->payload_len) + sizeof(*pim) > skb->len) goto drop; - if (ip6mr_fib_lookup(net, &fl, &mrt) < 0) + if (ip6mr_fib_lookup(net, &fl6, &mrt) < 0) goto drop; reg_vif_num = mrt->mroute_reg_vif_num; @@ -687,14 +688,14 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, { struct net *net = dev_net(dev); struct mr6_table *mrt; - struct flowi fl = { - .flowi_oif = dev->ifindex, - .flowi_iif = skb->skb_iif, - .flowi_mark = skb->mark, + struct flowi6 fl6 = { + .flowi6_oif = dev->ifindex, + .flowi6_iif = skb->skb_iif, + .flowi6_mark = skb->mark, }; int err; - err = ip6mr_fib_lookup(net, &fl, &mrt); + err = ip6mr_fib_lookup(net, &fl6, &mrt); if (err < 0) return err; @@ -1547,13 +1548,13 @@ int ip6mr_sk_done(struct sock *sk) struct sock *mroute6_socket(struct net *net, struct sk_buff *skb) { struct mr6_table *mrt; - struct flowi fl = { - .flowi_iif = skb->skb_iif, - .flowi_oif = skb->dev->ifindex, - .flowi_mark= skb->mark, + struct flowi6 fl6 = { + .flowi6_iif = skb->skb_iif, + .flowi6_oif = skb->dev->ifindex, + .flowi6_mark = skb->mark, }; - if (ip6mr_fib_lookup(net, &fl, &mrt) < 0) + if (ip6mr_fib_lookup(net, &fl6, &mrt) < 0) return NULL; return mrt->mroute6_sk; @@ -1897,7 +1898,7 @@ static int ip6mr_forward2(struct net *net, struct mr6_table *mrt, struct mif_device *vif = &mrt->vif6_table[vifi]; struct net_device *dev; struct dst_entry *dst; - struct flowi fl; + struct flowi6 fl6; if (vif->dev == NULL) goto out_free; @@ -1915,12 +1916,12 @@ static int ip6mr_forward2(struct net *net, struct mr6_table *mrt, ipv6h = ipv6_hdr(skb); - fl = (struct flowi) { - .flowi_oif = vif->link, - .fl6_dst = ipv6h->daddr, + fl6 = (struct flowi6) { + .flowi6_oif = vif->link, + .daddr = ipv6h->daddr, }; - dst = ip6_route_output(net, NULL, &fl); + dst = ip6_route_output(net, NULL, &fl6); if (!dst) goto out_free; @@ -2043,13 +2044,13 @@ int ip6_mr_input(struct sk_buff *skb) struct mfc6_cache *cache; struct net *net = dev_net(skb->dev); struct mr6_table *mrt; - struct flowi fl = { - .flowi_iif = skb->dev->ifindex, - .flowi_mark= skb->mark, + struct flowi6 fl6 = { + .flowi6_iif = skb->dev->ifindex, + .flowi6_mark = skb->mark, }; int err; - err = ip6mr_fib_lookup(net, &fl, &mrt); + err = ip6mr_fib_lookup(net, &fl6, &mrt); if (err < 0) return err; diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 1448c507fdff..9cb191ecaba8 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -444,12 +444,12 @@ sticky_done: { struct ipv6_txoptions *opt = NULL; struct msghdr msg; - struct flowi fl; + struct flowi6 fl6; int junk; - fl.fl6_flowlabel = 0; - fl.flowi_oif = sk->sk_bound_dev_if; - fl.flowi_mark = sk->sk_mark; + memset(&fl6, 0, sizeof(fl6)); + fl6.flowi6_oif = sk->sk_bound_dev_if; + fl6.flowi6_mark = sk->sk_mark; if (optlen == 0) goto update; @@ -475,7 +475,7 @@ sticky_done: msg.msg_controllen = optlen; msg.msg_control = (void*)(opt+1); - retv = datagram_send_ctl(net, &msg, &fl, opt, &junk, &junk, + retv = datagram_send_ctl(net, &msg, &fl6, opt, &junk, &junk, &junk); if (retv) goto done; diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index f2c9b6930ffc..76b893771e6e 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -1396,7 +1396,7 @@ static void mld_sendpack(struct sk_buff *skb) struct inet6_dev *idev; struct net *net = dev_net(skb->dev); int err; - struct flowi fl; + struct flowi6 fl6; struct dst_entry *dst; rcu_read_lock(); @@ -1419,11 +1419,11 @@ static void mld_sendpack(struct sk_buff *skb) goto err_out; } - icmpv6_flow_init(net->ipv6.igmp_sk, &fl, ICMPV6_MLD2_REPORT, + icmpv6_flow_init(net->ipv6.igmp_sk, &fl6, ICMPV6_MLD2_REPORT, &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, skb->dev->ifindex); - dst = xfrm_lookup(net, dst, &fl, NULL, 0); + dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0); err = 0; if (IS_ERR(dst)) { err = PTR_ERR(dst); @@ -1731,7 +1731,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) u8 ra[8] = { IPPROTO_ICMPV6, 0, IPV6_TLV_ROUTERALERT, 2, 0, 0, IPV6_TLV_PADN, 0 }; - struct flowi fl; + struct flowi6 fl6; struct dst_entry *dst; if (type == ICMPV6_MGM_REDUCTION) @@ -1791,11 +1791,11 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) goto err_out; } - icmpv6_flow_init(sk, &fl, type, + icmpv6_flow_init(sk, &fl6, type, &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, skb->dev->ifindex); - dst = xfrm_lookup(net, dst, &fl, NULL, 0); + dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0); if (IS_ERR(dst)) { err = PTR_ERR(dst); goto err_out; diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c index e1767aec3334..6a137355311c 100644 --- a/net/ipv6/mip6.c +++ b/net/ipv6/mip6.c @@ -208,14 +208,15 @@ static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, { struct net *net = xs_net(x); struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb; + const struct flowi6 *fl6 = &fl->u.ip6; struct ipv6_destopt_hao *hao = NULL; struct xfrm_selector sel; int offset; struct timeval stamp; int err = 0; - if (unlikely(fl->flowi_proto == IPPROTO_MH && - fl->fl6_mh_type <= IP6_MH_TYPE_MAX)) + if (unlikely(fl6->flowi6_proto == IPPROTO_MH && + fl6->uli.mht.type <= IP6_MH_TYPE_MAX)) goto out; if (likely(opt->dsthao)) { @@ -240,14 +241,14 @@ static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, sizeof(sel.saddr)); sel.prefixlen_s = 128; sel.family = AF_INET6; - sel.proto = fl->flowi_proto; - sel.dport = xfrm_flowi_dport(fl, &fl->u.ip6.uli); + sel.proto = fl6->flowi6_proto; + sel.dport = xfrm_flowi_dport(fl, &fl6->uli); if (sel.dport) sel.dport_mask = htons(~0); - sel.sport = xfrm_flowi_sport(fl, &fl->u.ip6.uli); + sel.sport = xfrm_flowi_sport(fl, &fl6->uli); if (sel.sport) sel.sport_mask = htons(~0); - sel.ifindex = fl->flowi_oif; + sel.ifindex = fl6->flowi6_oif; err = km_report(net, IPPROTO_DSTOPTS, &sel, (hao ? (xfrm_address_t *)&hao->addr : NULL)); diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 9360d3be94f0..0e49c9db3c98 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -511,7 +511,7 @@ void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *saddr, struct icmp6hdr *icmp6h) { - struct flowi fl; + struct flowi6 fl6; struct dst_entry *dst; struct net *net = dev_net(dev); struct sock *sk = net->ipv6.ndisc_sk; @@ -521,7 +521,7 @@ void ndisc_send_skb(struct sk_buff *skb, type = icmp6h->icmp6_type; - icmpv6_flow_init(sk, &fl, type, saddr, daddr, dev->ifindex); + icmpv6_flow_init(sk, &fl6, type, saddr, daddr, dev->ifindex); dst = icmp6_dst_alloc(dev, neigh, daddr); if (!dst) { @@ -529,7 +529,7 @@ void ndisc_send_skb(struct sk_buff *skb, return; } - dst = xfrm_lookup(net, dst, &fl, NULL, 0); + dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0); if (IS_ERR(dst)) { kfree_skb(skb); return; @@ -1515,7 +1515,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, struct rt6_info *rt; struct dst_entry *dst; struct inet6_dev *idev; - struct flowi fl; + struct flowi6 fl6; u8 *opt; int rd_len; int err; @@ -1535,14 +1535,14 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, return; } - icmpv6_flow_init(sk, &fl, NDISC_REDIRECT, + icmpv6_flow_init(sk, &fl6, NDISC_REDIRECT, &saddr_buf, &ipv6_hdr(skb)->saddr, dev->ifindex); - dst = ip6_route_output(net, NULL, &fl); + dst = ip6_route_output(net, NULL, &fl6); if (dst == NULL) return; - dst = xfrm_lookup(net, dst, &fl, NULL, 0); + dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0); if (IS_ERR(dst)) return; diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index d282c62bc6f4..39aaca2b4fd2 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c @@ -15,14 +15,14 @@ int ip6_route_me_harder(struct sk_buff *skb) struct net *net = dev_net(skb_dst(skb)->dev); struct ipv6hdr *iph = ipv6_hdr(skb); struct dst_entry *dst; - struct flowi fl = { - .flowi_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0, - .flowi_mark = skb->mark, - .fl6_dst = iph->daddr, - .fl6_src = iph->saddr, + struct flowi6 fl6 = { + .flowi6_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0, + .flowi6_mark = skb->mark, + .daddr = iph->daddr, + .saddr = iph->saddr, }; - dst = ip6_route_output(net, skb->sk, &fl); + dst = ip6_route_output(net, skb->sk, &fl6); if (dst->error) { IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n"); @@ -37,9 +37,9 @@ int ip6_route_me_harder(struct sk_buff *skb) #ifdef CONFIG_XFRM if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && - xfrm_decode_session(skb, &fl, AF_INET6) == 0) { + xfrm_decode_session(skb, flowi6_to_flowi(&fl6), AF_INET6) == 0) { skb_dst_set(skb, NULL); - dst = xfrm_lookup(net, dst, &fl, skb->sk, 0); + dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), skb->sk, 0); if (IS_ERR(dst)) return -1; skb_dst_set(skb, dst); @@ -92,7 +92,7 @@ static int nf_ip6_reroute(struct sk_buff *skb, static int nf_ip6_route(struct dst_entry **dst, struct flowi *fl) { - *dst = ip6_route_output(&init_net, NULL, fl); + *dst = ip6_route_output(&init_net, NULL, &fl->u.ip6); return (*dst)->error; } diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index d1e905b7f563..df05511dea33 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c @@ -47,7 +47,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb) struct ipv6hdr *ip6h; struct dst_entry *dst = NULL; u8 proto; - struct flowi fl; + struct flowi6 fl6; if ((!(ipv6_addr_type(&oip6h->saddr) & IPV6_ADDR_UNICAST)) || (!(ipv6_addr_type(&oip6h->daddr) & IPV6_ADDR_UNICAST))) { @@ -89,19 +89,19 @@ static void send_reset(struct net *net, struct sk_buff *oldskb) return; } - memset(&fl, 0, sizeof(fl)); - fl.flowi_proto = IPPROTO_TCP; - ipv6_addr_copy(&fl.fl6_src, &oip6h->daddr); - ipv6_addr_copy(&fl.fl6_dst, &oip6h->saddr); - fl.fl6_sport = otcph.dest; - fl.fl6_dport = otcph.source; - security_skb_classify_flow(oldskb, &fl); - dst = ip6_route_output(net, NULL, &fl); + memset(&fl6, 0, sizeof(fl6)); + fl6.flowi6_proto = IPPROTO_TCP; + ipv6_addr_copy(&fl6.saddr, &oip6h->daddr); + ipv6_addr_copy(&fl6.daddr, &oip6h->saddr); + fl6.uli.ports.sport = otcph.dest; + fl6.uli.ports.dport = otcph.source; + security_skb_classify_flow(oldskb, flowi6_to_flowi(&fl6)); + dst = ip6_route_output(net, NULL, &fl6); if (dst == NULL || dst->error) { dst_release(dst); return; } - dst = xfrm_lookup(net, dst, &fl, NULL, 0); + dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0); if (IS_ERR(dst)) return; diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index d061465d6827..259f1b231038 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -524,7 +524,7 @@ csum_copy_err: goto out; } -static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, +static int rawv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6, struct raw6_sock *rp) { struct sk_buff *skb; @@ -586,11 +586,10 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, if (unlikely(csum)) tmp_csum = csum_sub(tmp_csum, csum_unfold(csum)); - csum = csum_ipv6_magic(&fl->fl6_src, - &fl->fl6_dst, - total_len, fl->flowi_proto, tmp_csum); + csum = csum_ipv6_magic(&fl6->saddr, &fl6->daddr, + total_len, fl6->flowi6_proto, tmp_csum); - if (csum == 0 && fl->flowi_proto == IPPROTO_UDP) + if (csum == 0 && fl6->flowi6_proto == IPPROTO_UDP) csum = CSUM_MANGLED_0; if (skb_store_bits(skb, offset, &csum, 2)) @@ -603,7 +602,7 @@ out: } static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, - struct flowi *fl, struct dst_entry **dstp, + struct flowi6 *fl6, struct dst_entry **dstp, unsigned int flags) { struct ipv6_pinfo *np = inet6_sk(sk); @@ -613,7 +612,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, struct rt6_info *rt = (struct rt6_info *)*dstp; if (length > rt->dst.dev->mtu) { - ipv6_local_error(sk, EMSGSIZE, fl, rt->dst.dev->mtu); + ipv6_local_error(sk, EMSGSIZE, fl6, rt->dst.dev->mtu); return -EMSGSIZE; } if (flags&MSG_PROBE) @@ -662,7 +661,7 @@ error: return err; } -static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) +static int rawv6_probe_proto_opt(struct flowi6 *fl6, struct msghdr *msg) { struct iovec *iov; u8 __user *type = NULL; @@ -679,7 +678,7 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) if (!iov) continue; - switch (fl->flowi_proto) { + switch (fl6->flowi6_proto) { case IPPROTO_ICMPV6: /* check if one-byte field is readable or not. */ if (iov->iov_base && iov->iov_len < 1) @@ -694,8 +693,8 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) code = iov->iov_base; if (type && code) { - if (get_user(fl->fl6_icmp_type, type) || - get_user(fl->fl6_icmp_code, code)) + if (get_user(fl6->uli.icmpt.type, type) || + get_user(fl6->uli.icmpt.code, code)) return -EFAULT; probed = 1; } @@ -706,7 +705,7 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) /* check if type field is readable or not. */ if (iov->iov_len > 2 - len) { u8 __user *p = iov->iov_base; - if (get_user(fl->fl6_mh_type, &p[2 - len])) + if (get_user(fl6->uli.mht.type, &p[2 - len])) return -EFAULT; probed = 1; } else @@ -735,7 +734,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct ipv6_txoptions *opt = NULL; struct ip6_flowlabel *flowlabel = NULL; struct dst_entry *dst = NULL; - struct flowi fl; + struct flowi6 fl6; int addr_len = msg->msg_namelen; int hlimit = -1; int tclass = -1; @@ -756,9 +755,9 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, /* * Get and verify the address. */ - memset(&fl, 0, sizeof(fl)); + memset(&fl6, 0, sizeof(fl6)); - fl.flowi_mark = sk->sk_mark; + fl6.flowi6_mark = sk->sk_mark; if (sin6) { if (addr_len < SIN6_LEN_RFC2133) @@ -780,9 +779,9 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, daddr = &sin6->sin6_addr; if (np->sndflow) { - fl.fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK; - if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) { - flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel); + fl6.flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK; + if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) { + flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); if (flowlabel == NULL) return -EINVAL; daddr = &flowlabel->dst; @@ -800,32 +799,32 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, if (addr_len >= sizeof(struct sockaddr_in6) && sin6->sin6_scope_id && ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL) - fl.flowi_oif = sin6->sin6_scope_id; + fl6.flowi6_oif = sin6->sin6_scope_id; } else { if (sk->sk_state != TCP_ESTABLISHED) return -EDESTADDRREQ; proto = inet->inet_num; daddr = &np->daddr; - fl.fl6_flowlabel = np->flow_label; + fl6.flowlabel = np->flow_label; } - if (fl.flowi_oif == 0) - fl.flowi_oif = sk->sk_bound_dev_if; + if (fl6.flowi6_oif == 0) + fl6.flowi6_oif = sk->sk_bound_dev_if; if (msg->msg_controllen) { opt = &opt_space; memset(opt, 0, sizeof(struct ipv6_txoptions)); opt->tot_len = sizeof(struct ipv6_txoptions); - err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit, + err = datagram_send_ctl(sock_net(sk), msg, &fl6, opt, &hlimit, &tclass, &dontfrag); if (err < 0) { fl6_sock_release(flowlabel); return err; } - if ((fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) { - flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel); + if ((fl6.flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) { + flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); if (flowlabel == NULL) return -EINVAL; } @@ -838,31 +837,31 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, opt = fl6_merge_options(&opt_space, flowlabel, opt); opt = ipv6_fixup_options(&opt_space, opt); - fl.flowi_proto = proto; - err = rawv6_probe_proto_opt(&fl, msg); + fl6.flowi6_proto = proto; + err = rawv6_probe_proto_opt(&fl6, msg); if (err) goto out; if (!ipv6_addr_any(daddr)) - ipv6_addr_copy(&fl.fl6_dst, daddr); + ipv6_addr_copy(&fl6.daddr, daddr); else - fl.fl6_dst.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */ - if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) - ipv6_addr_copy(&fl.fl6_src, &np->saddr); + fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */ + if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr)) + ipv6_addr_copy(&fl6.saddr, &np->saddr); - final_p = fl6_update_dst(&fl, opt, &final); + final_p = fl6_update_dst(&fl6, opt, &final); - if (!fl.flowi_oif && ipv6_addr_is_multicast(&fl.fl6_dst)) - fl.flowi_oif = np->mcast_oif; - security_sk_classify_flow(sk, &fl); + if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr)) + fl6.flowi6_oif = np->mcast_oif; + security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); - dst = ip6_dst_lookup_flow(sk, &fl, final_p, true); + dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true); if (IS_ERR(dst)) { err = PTR_ERR(dst); goto out; } if (hlimit < 0) { - if (ipv6_addr_is_multicast(&fl.fl6_dst)) + if (ipv6_addr_is_multicast(&fl6.daddr)) hlimit = np->mcast_hops; else hlimit = np->hop_limit; @@ -881,17 +880,17 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, back_from_confirm: if (inet->hdrincl) - err = rawv6_send_hdrinc(sk, msg->msg_iov, len, &fl, &dst, msg->msg_flags); + err = rawv6_send_hdrinc(sk, msg->msg_iov, len, &fl6, &dst, msg->msg_flags); else { lock_sock(sk); err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, - len, 0, hlimit, tclass, opt, &fl, (struct rt6_info*)dst, + len, 0, hlimit, tclass, opt, &fl6, (struct rt6_info*)dst, msg->msg_flags, dontfrag); if (err) ip6_flush_pending_frames(sk); else if (!(msg->msg_flags & MSG_MORE)) - err = rawv6_push_pending_frames(sk, &fl, rp); + err = rawv6_push_pending_frames(sk, &fl6, rp); release_sock(sk); } done: diff --git a/net/ipv6/route.c b/net/ipv6/route.c index c3b20d63921f..6814c8722fa7 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -599,17 +599,17 @@ do { \ static struct rt6_info *ip6_pol_route_lookup(struct net *net, struct fib6_table *table, - struct flowi *fl, int flags) + struct flowi6 *fl6, int flags) { struct fib6_node *fn; struct rt6_info *rt; read_lock_bh(&table->tb6_lock); - fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); + fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr); restart: rt = fn->leaf; - rt = rt6_device_match(net, rt, &fl->fl6_src, fl->flowi_oif, flags); - BACKTRACK(net, &fl->fl6_src); + rt = rt6_device_match(net, rt, &fl6->saddr, fl6->flowi6_oif, flags); + BACKTRACK(net, &fl6->saddr); out: dst_use(&rt->dst, jiffies); read_unlock_bh(&table->tb6_lock); @@ -620,19 +620,19 @@ out: struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr, const struct in6_addr *saddr, int oif, int strict) { - struct flowi fl = { - .flowi_oif = oif, - .fl6_dst = *daddr, + struct flowi6 fl6 = { + .flowi6_oif = oif, + .daddr = *daddr, }; struct dst_entry *dst; int flags = strict ? RT6_LOOKUP_F_IFACE : 0; if (saddr) { - memcpy(&fl.fl6_src, saddr, sizeof(*saddr)); + memcpy(&fl6.saddr, saddr, sizeof(*saddr)); flags |= RT6_LOOKUP_F_HAS_SADDR; } - dst = fib6_rule_lookup(net, &fl, flags, ip6_pol_route_lookup); + dst = fib6_rule_lookup(net, &fl6, flags, ip6_pol_route_lookup); if (dst->error == 0) return (struct rt6_info *) dst; @@ -753,7 +753,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, struct in6_addr *d } static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, int oif, - struct flowi *fl, int flags) + struct flowi6 *fl6, int flags) { struct fib6_node *fn; struct rt6_info *rt, *nrt; @@ -768,12 +768,12 @@ relookup: read_lock_bh(&table->tb6_lock); restart_2: - fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); + fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr); restart: rt = rt6_select(fn, oif, strict | reachable); - BACKTRACK(net, &fl->fl6_src); + BACKTRACK(net, &fl6->saddr); if (rt == net->ipv6.ip6_null_entry || rt->rt6i_flags & RTF_CACHE) goto out; @@ -782,9 +782,9 @@ restart: read_unlock_bh(&table->tb6_lock); if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) - nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src); + nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); else if (!(rt->dst.flags & DST_HOST)) - nrt = rt6_alloc_clone(rt, &fl->fl6_dst); + nrt = rt6_alloc_clone(rt, &fl6->daddr); else goto out2; @@ -823,9 +823,9 @@ out2: } static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *table, - struct flowi *fl, int flags) + struct flowi6 *fl6, int flags) { - return ip6_pol_route(net, table, fl->flowi_iif, fl, flags); + return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags); } void ip6_route_input(struct sk_buff *skb) @@ -833,41 +833,41 @@ void ip6_route_input(struct sk_buff *skb) struct ipv6hdr *iph = ipv6_hdr(skb); struct net *net = dev_net(skb->dev); int flags = RT6_LOOKUP_F_HAS_SADDR; - struct flowi fl = { - .flowi_iif = skb->dev->ifindex, - .fl6_dst = iph->daddr, - .fl6_src = iph->saddr, - .fl6_flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK, - .flowi_mark = skb->mark, - .flowi_proto = iph->nexthdr, + struct flowi6 fl6 = { + .flowi6_iif = skb->dev->ifindex, + .daddr = iph->daddr, + .saddr = iph->saddr, + .flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK, + .flowi6_mark = skb->mark, + .flowi6_proto = iph->nexthdr, }; if (rt6_need_strict(&iph->daddr) && skb->dev->type != ARPHRD_PIMREG) flags |= RT6_LOOKUP_F_IFACE; - skb_dst_set(skb, fib6_rule_lookup(net, &fl, flags, ip6_pol_route_input)); + skb_dst_set(skb, fib6_rule_lookup(net, &fl6, flags, ip6_pol_route_input)); } static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table, - struct flowi *fl, int flags) + struct flowi6 *fl6, int flags) { - return ip6_pol_route(net, table, fl->flowi_oif, fl, flags); + return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags); } struct dst_entry * ip6_route_output(struct net *net, struct sock *sk, - struct flowi *fl) + struct flowi6 *fl6) { int flags = 0; - if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl->fl6_dst)) + if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl6->daddr)) flags |= RT6_LOOKUP_F_IFACE; - if (!ipv6_addr_any(&fl->fl6_src)) + if (!ipv6_addr_any(&fl6->saddr)) flags |= RT6_LOOKUP_F_HAS_SADDR; else if (sk) flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs); - return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output); + return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_output); } EXPORT_SYMBOL(ip6_route_output); @@ -1444,16 +1444,16 @@ static int ip6_route_del(struct fib6_config *cfg) * Handle redirects */ struct ip6rd_flowi { - struct flowi fl; + struct flowi6 fl6; struct in6_addr gateway; }; static struct rt6_info *__ip6_route_redirect(struct net *net, struct fib6_table *table, - struct flowi *fl, + struct flowi6 *fl6, int flags) { - struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl; + struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl6; struct rt6_info *rt; struct fib6_node *fn; @@ -1469,7 +1469,7 @@ static struct rt6_info *__ip6_route_redirect(struct net *net, */ read_lock_bh(&table->tb6_lock); - fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); + fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr); restart: for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) { /* @@ -1484,7 +1484,7 @@ restart: continue; if (!(rt->rt6i_flags & RTF_GATEWAY)) continue; - if (fl->flowi_oif != rt->rt6i_dev->ifindex) + if (fl6->flowi6_oif != rt->rt6i_dev->ifindex) continue; if (!ipv6_addr_equal(&rdfl->gateway, &rt->rt6i_gateway)) continue; @@ -1493,7 +1493,7 @@ restart: if (!rt) rt = net->ipv6.ip6_null_entry; - BACKTRACK(net, &fl->fl6_src); + BACKTRACK(net, &fl6->saddr); out: dst_hold(&rt->dst); @@ -1510,10 +1510,10 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest, int flags = RT6_LOOKUP_F_HAS_SADDR; struct net *net = dev_net(dev); struct ip6rd_flowi rdfl = { - .fl = { - .flowi_oif = dev->ifindex, - .fl6_dst = *dest, - .fl6_src = *src, + .fl6 = { + .flowi6_oif = dev->ifindex, + .daddr = *dest, + .saddr = *src, }, }; @@ -1522,7 +1522,7 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest, if (rt6_need_strict(dest)) flags |= RT6_LOOKUP_F_IFACE; - return (struct rt6_info *)fib6_rule_lookup(net, (struct flowi *)&rdfl, + return (struct rt6_info *)fib6_rule_lookup(net, &rdfl.fl6, flags, __ip6_route_redirect); } @@ -2385,7 +2385,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void struct rt6_info *rt; struct sk_buff *skb; struct rtmsg *rtm; - struct flowi fl; + struct flowi6 fl6; int err, iif = 0; err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy); @@ -2393,27 +2393,27 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void goto errout; err = -EINVAL; - memset(&fl, 0, sizeof(fl)); + memset(&fl6, 0, sizeof(fl6)); if (tb[RTA_SRC]) { if (nla_len(tb[RTA_SRC]) < sizeof(struct in6_addr)) goto errout; - ipv6_addr_copy(&fl.fl6_src, nla_data(tb[RTA_SRC])); + ipv6_addr_copy(&fl6.saddr, nla_data(tb[RTA_SRC])); } if (tb[RTA_DST]) { if (nla_len(tb[RTA_DST]) < sizeof(struct in6_addr)) goto errout; - ipv6_addr_copy(&fl.fl6_dst, nla_data(tb[RTA_DST])); + ipv6_addr_copy(&fl6.daddr, nla_data(tb[RTA_DST])); } if (tb[RTA_IIF]) iif = nla_get_u32(tb[RTA_IIF]); if (tb[RTA_OIF]) - fl.flowi_oif = nla_get_u32(tb[RTA_OIF]); + fl6.flowi6_oif = nla_get_u32(tb[RTA_OIF]); if (iif) { struct net_device *dev; @@ -2436,10 +2436,10 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void skb_reset_mac_header(skb); skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr)); - rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl); + rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl6); skb_dst_set(skb, &rt->dst); - err = rt6_fill_node(net, skb, rt, &fl.fl6_dst, &fl.fl6_src, iif, + err = rt6_fill_node(net, skb, rt, &fl6.daddr, &fl6.saddr, iif, RTM_NEWROUTE, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, 0, 0, 0); if (err < 0) { diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 5b9eded1432c..97858d5d67e8 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c @@ -232,19 +232,19 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) */ { struct in6_addr *final_p, final; - struct flowi fl; - memset(&fl, 0, sizeof(fl)); - fl.flowi_proto = IPPROTO_TCP; - ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr); - final_p = fl6_update_dst(&fl, np->opt, &final); - ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr); - fl.flowi_oif = sk->sk_bound_dev_if; - fl.flowi_mark = sk->sk_mark; - fl.fl6_dport = inet_rsk(req)->rmt_port; - fl.fl6_sport = inet_sk(sk)->inet_sport; - security_req_classify_flow(req, &fl); - - dst = ip6_dst_lookup_flow(sk, &fl, final_p, false); + struct flowi6 fl6; + memset(&fl6, 0, sizeof(fl6)); + fl6.flowi6_proto = IPPROTO_TCP; + ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr); + final_p = fl6_update_dst(&fl6, np->opt, &final); + ipv6_addr_copy(&fl6.saddr, &ireq6->loc_addr); + fl6.flowi6_oif = sk->sk_bound_dev_if; + fl6.flowi6_mark = sk->sk_mark; + fl6.uli.ports.dport = inet_rsk(req)->rmt_port; + fl6.uli.ports.sport = inet_sk(sk)->inet_sport; + security_req_classify_flow(req, flowi6_to_flowi(&fl6)); + + dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); if (IS_ERR(dst)) goto out_free; } diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index c531ad5fbccc..7ed0ba1995f0 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -131,7 +131,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, struct tcp_sock *tp = tcp_sk(sk); struct in6_addr *saddr = NULL, *final_p, final; struct rt6_info *rt; - struct flowi fl; + struct flowi6 fl6; struct dst_entry *dst; int addr_type; int err; @@ -142,14 +142,14 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, if (usin->sin6_family != AF_INET6) return -EAFNOSUPPORT; - memset(&fl, 0, sizeof(fl)); + memset(&fl6, 0, sizeof(fl6)); if (np->sndflow) { - fl.fl6_flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK; - IP6_ECN_flow_init(fl.fl6_flowlabel); - if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) { + fl6.flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK; + IP6_ECN_flow_init(fl6.flowlabel); + if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) { struct ip6_flowlabel *flowlabel; - flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel); + flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); if (flowlabel == NULL) return -EINVAL; ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst); @@ -195,7 +195,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, } ipv6_addr_copy(&np->daddr, &usin->sin6_addr); - np->flow_label = fl.fl6_flowlabel; + np->flow_label = fl6.flowlabel; /* * TCP over IPv4 @@ -242,27 +242,27 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, if (!ipv6_addr_any(&np->rcv_saddr)) saddr = &np->rcv_saddr; - fl.flowi_proto = IPPROTO_TCP; - ipv6_addr_copy(&fl.fl6_dst, &np->daddr); - ipv6_addr_copy(&fl.fl6_src, + fl6.flowi6_proto = IPPROTO_TCP; + ipv6_addr_copy(&fl6.daddr, &np->daddr); + ipv6_addr_copy(&fl6.saddr, (saddr ? saddr : &np->saddr)); - fl.flowi_oif = sk->sk_bound_dev_if; - fl.flowi_mark = sk->sk_mark; - fl.fl6_dport = usin->sin6_port; - fl.fl6_sport = inet->inet_sport; + fl6.flowi6_oif = sk->sk_bound_dev_if; + fl6.flowi6_mark = sk->sk_mark; + fl6.uli.ports.dport = usin->sin6_port; + fl6.uli.ports.sport = inet->inet_sport; - final_p = fl6_update_dst(&fl, np->opt, &final); + final_p = fl6_update_dst(&fl6, np->opt, &final); - security_sk_classify_flow(sk, &fl); + security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); - dst = ip6_dst_lookup_flow(sk, &fl, final_p, true); + dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true); if (IS_ERR(dst)) { err = PTR_ERR(dst); goto failure; } if (saddr == NULL) { - saddr = &fl.fl6_src; + saddr = &fl6.saddr; ipv6_addr_copy(&np->rcv_saddr, saddr); } @@ -389,23 +389,23 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, if (dst == NULL) { struct inet_sock *inet = inet_sk(sk); - struct flowi fl; + struct flowi6 fl6; /* BUGGG_FUTURE: Again, it is not clear how to handle rthdr case. Ignore this complexity for now. */ - memset(&fl, 0, sizeof(fl)); - fl.flowi_proto = IPPROTO_TCP; - ipv6_addr_copy(&fl.fl6_dst, &np->daddr); - ipv6_addr_copy(&fl.fl6_src, &np->saddr); - fl.flowi_oif = sk->sk_bound_dev_if; - fl.flowi_mark = sk->sk_mark; - fl.fl6_dport = inet->inet_dport; - fl.fl6_sport = inet->inet_sport; - security_skb_classify_flow(skb, &fl); - - dst = ip6_dst_lookup_flow(sk, &fl, NULL, false); + memset(&fl6, 0, sizeof(fl6)); + fl6.flowi6_proto = IPPROTO_TCP; + ipv6_addr_copy(&fl6.daddr, &np->daddr); + ipv6_addr_copy(&fl6.saddr, &np->saddr); + fl6.flowi6_oif = sk->sk_bound_dev_if; + fl6.flowi6_mark = sk->sk_mark; + fl6.uli.ports.dport = inet->inet_dport; + fl6.uli.ports.sport = inet->inet_sport; + security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); + + dst = ip6_dst_lookup_flow(sk, &fl6, NULL, false); if (IS_ERR(dst)) { sk->sk_err_soft = -PTR_ERR(dst); goto out; @@ -482,25 +482,25 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, struct sk_buff * skb; struct ipv6_txoptions *opt = NULL; struct in6_addr * final_p, final; - struct flowi fl; + struct flowi6 fl6; struct dst_entry *dst; int err; - memset(&fl, 0, sizeof(fl)); - fl.flowi_proto = IPPROTO_TCP; - ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); - ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr); - fl.fl6_flowlabel = 0; - fl.flowi_oif = treq->iif; - fl.flowi_mark = sk->sk_mark; - fl.fl6_dport = inet_rsk(req)->rmt_port; - fl.fl6_sport = inet_rsk(req)->loc_port; - security_req_classify_flow(req, &fl); + memset(&fl6, 0, sizeof(fl6)); + fl6.flowi6_proto = IPPROTO_TCP; + ipv6_addr_copy(&fl6.daddr, &treq->rmt_addr); + ipv6_addr_copy(&fl6.saddr, &treq->loc_addr); + fl6.flowlabel = 0; + fl6.flowi6_oif = treq->iif; + fl6.flowi6_mark = sk->sk_mark; + fl6.uli.ports.dport = inet_rsk(req)->rmt_port; + fl6.uli.ports.sport = inet_rsk(req)->loc_port; + security_req_classify_flow(req, flowi6_to_flowi(&fl6)); opt = np->opt; - final_p = fl6_update_dst(&fl, opt, &final); + final_p = fl6_update_dst(&fl6, opt, &final); - dst = ip6_dst_lookup_flow(sk, &fl, final_p, false); + dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); if (IS_ERR(dst)) { err = PTR_ERR(dst); goto done; @@ -510,8 +510,8 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, if (skb) { __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); - ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); - err = ip6_xmit(sk, skb, &fl, opt); + ipv6_addr_copy(&fl6.daddr, &treq->rmt_addr); + err = ip6_xmit(sk, skb, &fl6, opt); err = net_xmit_eval(err); } @@ -992,7 +992,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, { struct tcphdr *th = tcp_hdr(skb), *t1; struct sk_buff *buff; - struct flowi fl; + struct flowi6 fl6; struct net *net = dev_net(skb_dst(skb)->dev); struct sock *ctl_sk = net->ipv6.tcp_sk; unsigned int tot_len = sizeof(struct tcphdr); @@ -1046,29 +1046,29 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, } #endif - memset(&fl, 0, sizeof(fl)); - ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr); - ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr); + memset(&fl6, 0, sizeof(fl6)); + ipv6_addr_copy(&fl6.daddr, &ipv6_hdr(skb)->saddr); + ipv6_addr_copy(&fl6.saddr, &ipv6_hdr(skb)->daddr); buff->ip_summed = CHECKSUM_PARTIAL; buff->csum = 0; - __tcp_v6_send_check(buff, &fl.fl6_src, &fl.fl6_dst); + __tcp_v6_send_check(buff, &fl6.saddr, &fl6.daddr); - fl.flowi_proto = IPPROTO_TCP; - fl.flowi_oif = inet6_iif(skb); - fl.fl6_dport = t1->dest; - fl.fl6_sport = t1->source; - security_skb_classify_flow(skb, &fl); + fl6.flowi6_proto = IPPROTO_TCP; + fl6.flowi6_oif = inet6_iif(skb); + fl6.uli.ports.dport = t1->dest; + fl6.uli.ports.sport = t1->source; + security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); /* Pass a socket to ip6_dst_lookup either it is for RST * Underlying function will use this to retrieve the network * namespace */ - dst = ip6_dst_lookup_flow(ctl_sk, &fl, NULL, false); + dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL, false); if (!IS_ERR(dst)) { skb_dst_set(buff, dst); - ip6_xmit(ctl_sk, buff, &fl, NULL); + ip6_xmit(ctl_sk, buff, &fl6, NULL); TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); if (rst) TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS); diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index dad035fb0afd..ce4b16fbf81c 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -886,7 +886,7 @@ static int udp_v6_push_pending_frames(struct sock *sk) struct udphdr *uh; struct udp_sock *up = udp_sk(sk); struct inet_sock *inet = inet_sk(sk); - struct flowi *fl = &inet->cork.fl; + struct flowi6 *fl6 = &inet->cork.fl.u.ip6; int err = 0; int is_udplite = IS_UDPLITE(sk); __wsum csum = 0; @@ -899,23 +899,23 @@ static int udp_v6_push_pending_frames(struct sock *sk) * Create a UDP header */ uh = udp_hdr(skb); - uh->source = fl->fl6_sport; - uh->dest = fl->fl6_dport; + uh->source = fl6->uli.ports.sport; + uh->dest = fl6->uli.ports.dport; uh->len = htons(up->len); uh->check = 0; if (is_udplite) csum = udplite_csum_outgoing(sk, skb); else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */ - udp6_hwcsum_outgoing(sk, skb, &fl->fl6_src, &fl->fl6_dst, + udp6_hwcsum_outgoing(sk, skb, &fl6->saddr, &fl6->daddr, up->len); goto send; } else csum = udp_csum_outgoing(sk, skb); /* add protocol-dependent pseudo-header */ - uh->check = csum_ipv6_magic(&fl->fl6_src, &fl->fl6_dst, - up->len, fl->flowi_proto, csum); + uh->check = csum_ipv6_magic(&fl6->saddr, &fl6->daddr, + up->len, fl6->flowi6_proto, csum); if (uh->check == 0) uh->check = CSUM_MANGLED_0; @@ -947,7 +947,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct in6_addr *daddr, *final_p, final; struct ipv6_txoptions *opt = NULL; struct ip6_flowlabel *flowlabel = NULL; - struct flowi fl; + struct flowi6 fl6; struct dst_entry *dst; int addr_len = msg->msg_namelen; int ulen = len; @@ -1030,19 +1030,19 @@ do_udp_sendmsg: } ulen += sizeof(struct udphdr); - memset(&fl, 0, sizeof(fl)); + memset(&fl6, 0, sizeof(fl6)); if (sin6) { if (sin6->sin6_port == 0) return -EINVAL; - fl.fl6_dport = sin6->sin6_port; + fl6.uli.ports.dport = sin6->sin6_port; daddr = &sin6->sin6_addr; if (np->sndflow) { - fl.fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK; - if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) { - flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel); + fl6.flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK; + if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) { + flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); if (flowlabel == NULL) return -EINVAL; daddr = &flowlabel->dst; @@ -1060,38 +1060,38 @@ do_udp_sendmsg: if (addr_len >= sizeof(struct sockaddr_in6) && sin6->sin6_scope_id && ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL) - fl.flowi_oif = sin6->sin6_scope_id; + fl6.flowi6_oif = sin6->sin6_scope_id; } else { if (sk->sk_state != TCP_ESTABLISHED) return -EDESTADDRREQ; - fl.fl6_dport = inet->inet_dport; + fl6.uli.ports.dport = inet->inet_dport; daddr = &np->daddr; - fl.fl6_flowlabel = np->flow_label; + fl6.flowlabel = np->flow_label; connected = 1; } - if (!fl.flowi_oif) - fl.flowi_oif = sk->sk_bound_dev_if; + if (!fl6.flowi6_oif) + fl6.flowi6_oif = sk->sk_bound_dev_if; - if (!fl.flowi_oif) - fl.flowi_oif = np->sticky_pktinfo.ipi6_ifindex; + if (!fl6.flowi6_oif) + fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex; - fl.flowi_mark = sk->sk_mark; + fl6.flowi6_mark = sk->sk_mark; if (msg->msg_controllen) { opt = &opt_space; memset(opt, 0, sizeof(struct ipv6_txoptions)); opt->tot_len = sizeof(*opt); - err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit, + err = datagram_send_ctl(sock_net(sk), msg, &fl6, opt, &hlimit, &tclass, &dontfrag); if (err < 0) { fl6_sock_release(flowlabel); return err; } - if ((fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) { - flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel); + if ((fl6.flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) { + flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); if (flowlabel == NULL) return -EINVAL; } @@ -1105,27 +1105,27 @@ do_udp_sendmsg: opt = fl6_merge_options(&opt_space, flowlabel, opt); opt = ipv6_fixup_options(&opt_space, opt); - fl.flowi_proto = sk->sk_protocol; + fl6.flowi6_proto = sk->sk_protocol; if (!ipv6_addr_any(daddr)) - ipv6_addr_copy(&fl.fl6_dst, daddr); + ipv6_addr_copy(&fl6.daddr, daddr); else - fl.fl6_dst.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */ - if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) - ipv6_addr_copy(&fl.fl6_src, &np->saddr); - fl.fl6_sport = inet->inet_sport; + fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */ + if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr)) + ipv6_addr_copy(&fl6.saddr, &np->saddr); + fl6.uli.ports.sport = inet->inet_sport; - final_p = fl6_update_dst(&fl, opt, &final); + final_p = fl6_update_dst(&fl6, opt, &final); if (final_p) connected = 0; - if (!fl.flowi_oif && ipv6_addr_is_multicast(&fl.fl6_dst)) { - fl.flowi_oif = np->mcast_oif; + if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr)) { + fl6.flowi6_oif = np->mcast_oif; connected = 0; } - security_sk_classify_flow(sk, &fl); + security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); - dst = ip6_sk_dst_lookup_flow(sk, &fl, final_p, true); + dst = ip6_sk_dst_lookup_flow(sk, &fl6, final_p, true); if (IS_ERR(dst)) { err = PTR_ERR(dst); dst = NULL; @@ -1133,7 +1133,7 @@ do_udp_sendmsg: } if (hlimit < 0) { - if (ipv6_addr_is_multicast(&fl.fl6_dst)) + if (ipv6_addr_is_multicast(&fl6.daddr)) hlimit = np->mcast_hops; else hlimit = np->hop_limit; @@ -1168,7 +1168,7 @@ do_append_data: up->len += ulen; getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag; err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen, - sizeof(struct udphdr), hlimit, tclass, opt, &fl, + sizeof(struct udphdr), hlimit, tclass, opt, &fl6, (struct rt6_info*)dst, corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags, dontfrag); if (err) @@ -1181,10 +1181,10 @@ do_append_data: if (dst) { if (connected) { ip6_dst_store(sk, dst, - ipv6_addr_equal(&fl.fl6_dst, &np->daddr) ? + ipv6_addr_equal(&fl6.daddr, &np->daddr) ? &np->daddr : NULL, #ifdef CONFIG_IPV6_SUBTREES - ipv6_addr_equal(&fl.fl6_src, &np->saddr) ? + ipv6_addr_equal(&fl6.saddr, &np->saddr) ? &np->saddr : #endif NULL); diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 254aa6d79506..bef62005c0ed 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -39,8 +39,7 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, if (saddr) memcpy(&fl6.saddr, saddr, sizeof(fl6.saddr)); - dst = ip6_route_output(net, NULL, - flowi6_to_flowi(&fl6)); + dst = ip6_route_output(net, NULL, &fl6); err = dst->error; if (dst->error) { diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index d07a32aa07b6..a60b20fa142e 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -75,15 +75,13 @@ static int __ip_vs_addr_is_local_v6(struct net *net, const struct in6_addr *addr) { struct rt6_info *rt; - struct flowi fl = { - .flowi_oif = 0, - .fl6_dst = *addr, - .fl6_src = { .s6_addr32 = {0, 0, 0, 0} }, + struct flowi6 fl6 = { + .daddr = *addr, }; - rt = (struct rt6_info *)ip6_route_output(net, NULL, &fl); + rt = (struct rt6_info *)ip6_route_output(net, NULL, &fl6); if (rt && rt->rt6i_dev && (rt->rt6i_dev->flags & IFF_LOOPBACK)) - return 1; + return 1; return 0; } diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 7dc00e313611..6132b213eddc 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -198,27 +198,27 @@ __ip_vs_route_output_v6(struct net *net, struct in6_addr *daddr, struct in6_addr *ret_saddr, int do_xfrm) { struct dst_entry *dst; - struct flowi fl = { - .fl6_dst = *daddr, + struct flowi6 fl6 = { + .daddr = *daddr, }; - dst = ip6_route_output(net, NULL, &fl); + dst = ip6_route_output(net, NULL, &fl6); if (dst->error) goto out_err; if (!ret_saddr) return dst; - if (ipv6_addr_any(&fl.fl6_src) && + if (ipv6_addr_any(&fl6.saddr) && ipv6_dev_get_saddr(net, ip6_dst_idev(dst)->dev, - &fl.fl6_dst, 0, &fl.fl6_src) < 0) + &fl6.daddr, 0, &fl6.saddr) < 0) goto out_err; if (do_xfrm) { - dst = xfrm_lookup(net, dst, &fl, NULL, 0); + dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0); if (IS_ERR(dst)) { dst = NULL; goto out_err; } } - ipv6_addr_copy(ret_saddr, &fl.fl6_src); + ipv6_addr_copy(ret_saddr, &fl6.saddr); return dst; out_err: diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c index d8c00f9342ae..5f054a0dbbb1 100644 --- a/net/netfilter/xt_TEE.c +++ b/net/netfilter/xt_TEE.c @@ -143,18 +143,18 @@ tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info) const struct ipv6hdr *iph = ipv6_hdr(skb); struct net *net = pick_net(skb); struct dst_entry *dst; - struct flowi fl; + struct flowi6 fl6; - memset(&fl, 0, sizeof(fl)); + memset(&fl6, 0, sizeof(fl6)); if (info->priv) { if (info->priv->oif == -1) return false; - fl.flowi_oif = info->priv->oif; + fl6.flowi6_oif = info->priv->oif; } - fl.fl6_dst = info->gw.in6; - fl.fl6_flowlabel = ((iph->flow_lbl[0] & 0xF) << 16) | + fl6.daddr = info->gw.in6; + fl6.flowlabel = ((iph->flow_lbl[0] & 0xF) << 16) | (iph->flow_lbl[1] << 8) | iph->flow_lbl[2]; - dst = ip6_route_output(net, NULL, &fl); + dst = ip6_route_output(net, NULL, &fl6); if (dst == NULL) return false; diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 831627156884..865ce7ba4e14 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -201,40 +201,40 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport) { struct sock *sk = skb->sk; struct ipv6_pinfo *np = inet6_sk(sk); - struct flowi fl; + struct flowi6 fl6; - memset(&fl, 0, sizeof(fl)); + memset(&fl6, 0, sizeof(fl6)); - fl.flowi_proto = sk->sk_protocol; + fl6.flowi6_proto = sk->sk_protocol; /* Fill in the dest address from the route entry passed with the skb * and the source address from the transport. */ - ipv6_addr_copy(&fl.fl6_dst, &transport->ipaddr.v6.sin6_addr); - ipv6_addr_copy(&fl.fl6_src, &transport->saddr.v6.sin6_addr); + ipv6_addr_copy(&fl6.daddr, &transport->ipaddr.v6.sin6_addr); + ipv6_addr_copy(&fl6.saddr, &transport->saddr.v6.sin6_addr); - fl.fl6_flowlabel = np->flow_label; - IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel); - if (ipv6_addr_type(&fl.fl6_src) & IPV6_ADDR_LINKLOCAL) - fl.flowi_oif = transport->saddr.v6.sin6_scope_id; + fl6.flowlabel = np->flow_label; + IP6_ECN_flow_xmit(sk, fl6.flowlabel); + if (ipv6_addr_type(&fl6.saddr) & IPV6_ADDR_LINKLOCAL) + fl6.flowi6_oif = transport->saddr.v6.sin6_scope_id; else - fl.flowi_oif = sk->sk_bound_dev_if; + fl6.flowi6_oif = sk->sk_bound_dev_if; if (np->opt && np->opt->srcrt) { struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; - ipv6_addr_copy(&fl.fl6_dst, rt0->addr); + ipv6_addr_copy(&fl6.daddr, rt0->addr); } SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", __func__, skb, skb->len, - &fl.fl6_src, &fl.fl6_dst); + &fl6.saddr, &fl6.daddr); SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); if (!(transport->param_flags & SPP_PMTUD_ENABLE)) skb->local_df = 1; - return ip6_xmit(sk, skb, &fl, np->opt); + return ip6_xmit(sk, skb, &fl6, np->opt); } /* Returns the dst cache entry for the given source and destination ip @@ -245,22 +245,22 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc, union sctp_addr *saddr) { struct dst_entry *dst; - struct flowi fl; + struct flowi6 fl6; - memset(&fl, 0, sizeof(fl)); - ipv6_addr_copy(&fl.fl6_dst, &daddr->v6.sin6_addr); + memset(&fl6, 0, sizeof(fl6)); + ipv6_addr_copy(&fl6.daddr, &daddr->v6.sin6_addr); if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) - fl.flowi_oif = daddr->v6.sin6_scope_id; + fl6.flowi6_oif = daddr->v6.sin6_scope_id; - SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl.fl6_dst); + SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl6.daddr); if (saddr) { - ipv6_addr_copy(&fl.fl6_src, &saddr->v6.sin6_addr); - SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl.fl6_src); + ipv6_addr_copy(&fl6.saddr, &saddr->v6.sin6_addr); + SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6.saddr); } - dst = ip6_route_output(&init_net, NULL, &fl); + dst = ip6_route_output(&init_net, NULL, &fl6); if (!dst->error) { struct rt6_info *rt; rt = (struct rt6_info *)dst; -- cgit v1.2.3 From c640e8ca172c6a5c45abe8e2e8353900a84427fa Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 11 Mar 2011 21:17:41 +1000 Subject: drm/radeon: fix page flipping hangs on r300/r400 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We've been getting reports of complete system lockups with rv3xx hw on AGP and PCIE when running gnome-shell or kwin with compositing. It appears the hw really doesn't like setting these registers while stuff is running, this moves the setting of the registers into the modeset since they aren't required to be changed anywhere else. fixes: https://bugs.freedesktop.org/show_bug.cgi?id=35183 Reported-and-tested-by: Álmos --- drivers/gpu/drm/radeon/r100.c | 17 ----------------- drivers/gpu/drm/radeon/radeon_legacy_crtc.c | 3 ++- 2 files changed, 2 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 93fa735c8c1a..79de991e1ea3 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -70,23 +70,6 @@ MODULE_FIRMWARE(FIRMWARE_R520); void r100_pre_page_flip(struct radeon_device *rdev, int crtc) { - struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; - u32 tmp; - - /* make sure flip is at vb rather than hb */ - tmp = RREG32(RADEON_CRTC_OFFSET_CNTL + radeon_crtc->crtc_offset); - tmp &= ~RADEON_CRTC_OFFSET_FLIP_CNTL; - /* make sure pending bit is asserted */ - tmp |= RADEON_CRTC_GUI_TRIG_OFFSET_LEFT_EN; - WREG32(RADEON_CRTC_OFFSET_CNTL + radeon_crtc->crtc_offset, tmp); - - /* set pageflip to happen as late as possible in the vblank interval. - * same field for crtc1/2 - */ - tmp = RREG32(RADEON_CRTC_GEN_CNTL); - tmp &= ~RADEON_CRTC_VSTAT_MODE_MASK; - WREG32(RADEON_CRTC_GEN_CNTL, tmp); - /* enable the pflip int */ radeon_irq_kms_pflip_irq_get(rdev, crtc); } diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index cf0638c3b7c7..78968b738e88 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c @@ -443,7 +443,7 @@ int radeon_crtc_do_set_base(struct drm_crtc *crtc, (target_fb->bits_per_pixel * 8)); crtc_pitch |= crtc_pitch << 16; - + crtc_offset_cntl |= RADEON_CRTC_GUI_TRIG_OFFSET_LEFT_EN; if (tiling_flags & RADEON_TILING_MACRO) { if (ASIC_IS_R300(rdev)) crtc_offset_cntl |= (R300_CRTC_X_Y_MODE_EN | @@ -502,6 +502,7 @@ int radeon_crtc_do_set_base(struct drm_crtc *crtc, gen_cntl_val = RREG32(gen_cntl_reg); gen_cntl_val &= ~(0xf << 8); gen_cntl_val |= (format << 8); + gen_cntl_val &= ~RADEON_CRTC_VSTAT_MODE_MASK; WREG32(gen_cntl_reg, gen_cntl_val); crtc_offset = (u32)base; -- cgit v1.2.3 From 14a4019de88111d26ba444495fd14833ddb2d65e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 13 Mar 2011 13:50:32 +0100 Subject: hwmon/f71882fg: Fix a typo in a comment Signed-off-by: Hans de Goede Acked-by: Jean Delvare Signed-off-by: Guenter Roeck --- drivers/hwmon/f71882fg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 3f49dd376f02..ed04f07410fb 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c @@ -37,7 +37,7 @@ #define SIO_F71858FG_LD_HWM 0x02 /* Hardware monitor logical device */ #define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device */ #define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */ -#define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */ +#define SIO_LOCK_KEY 0xAA /* Key to disable Super-I/O */ #define SIO_REG_LDSEL 0x07 /* Logical device select */ #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ -- cgit v1.2.3 From d9ebaa45472c92704f4814682eec21455edcfa1f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 13 Mar 2011 13:50:33 +0100 Subject: hwmon/f71882fg: Set platform drvdata to NULL later This avoids a possible race leading to trying to dereference NULL. Signed-off-by: Hans de Goede Acked-by: Jean Delvare Cc: stable@kernel.org Signed-off-by: Guenter Roeck --- drivers/hwmon/f71882fg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index ed04f07410fb..6e06019015a5 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c @@ -2111,7 +2111,6 @@ static int f71882fg_remove(struct platform_device *pdev) int nr_fans = (data->type == f71882fg) ? 4 : 3; u8 start_reg = f71882fg_read8(data, F71882FG_REG_START); - platform_set_drvdata(pdev, NULL); if (data->hwmon_dev) hwmon_device_unregister(data->hwmon_dev); @@ -2178,6 +2177,7 @@ static int f71882fg_remove(struct platform_device *pdev) } } + platform_set_drvdata(pdev, NULL); kfree(data); return 0; -- cgit v1.2.3 From 19234cdda517396e5e0b10e77493afa9e30095c3 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 11 Mar 2011 14:58:30 -0800 Subject: gpio: add MODULE_DEVICE_TABLE The device table is required to load modules based on modaliases. After adding MODULE_DEVICE_TABLE, below entries will be added to modules.pcimap: pch_gpio 0x00008086 0x00008803 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 ml_ioh_gpio 0x000010db 0x0000802e 0xffffffff 0xffffffff 0x00000000 0x00000000 0x0 Signed-off-by: Axel Lin Cc: Tomoya MORINAGA Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpio/ml_ioh_gpio.c | 1 + drivers/gpio/pch_gpio.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpio/ml_ioh_gpio.c b/drivers/gpio/ml_ioh_gpio.c index cead8e6ff345..7f6f01a4b145 100644 --- a/drivers/gpio/ml_ioh_gpio.c +++ b/drivers/gpio/ml_ioh_gpio.c @@ -326,6 +326,7 @@ static DEFINE_PCI_DEVICE_TABLE(ioh_gpio_pcidev_id) = { { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x802E) }, { 0, } }; +MODULE_DEVICE_TABLE(pci, ioh_gpio_pcidev_id); static struct pci_driver ioh_gpio_driver = { .name = "ml_ioh_gpio", diff --git a/drivers/gpio/pch_gpio.c b/drivers/gpio/pch_gpio.c index 0eba0a75c804..2c6af8705103 100644 --- a/drivers/gpio/pch_gpio.c +++ b/drivers/gpio/pch_gpio.c @@ -286,6 +286,7 @@ static DEFINE_PCI_DEVICE_TABLE(pch_gpio_pcidev_id) = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8803) }, { 0, } }; +MODULE_DEVICE_TABLE(pci, pch_gpio_pcidev_id); static struct pci_driver pch_gpio_driver = { .name = "pch_gpio", -- cgit v1.2.3 From db7c7c0aeef51dba12d877875b8deb78d9886647 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Wed, 29 Dec 2010 22:03:07 -0800 Subject: usb: Always return 0 or -EBUSY to the runtime PM core. The PM core reacts badly when the return code from usb_runtime_suspend() is not 0, -EAGAIN, or -EBUSY. The PM core regards this as a fatal error, and refuses to run anymore PM helper functions. In particular, usbfs_open() and other usbfs functions will fail because the PM core will return an error code when usb_autoresume_device() is called. This causes libusb and/or lsusb to either hang or segfault. If a USB device cannot suspend for some reason (e.g. a hub doesn't report it has remote wakeup capabilities), we still want lsusb and other userspace programs to work. So return -EBUSY, which will fill people's log files with failed tries, but will ensure userspace still works. Signed-off-by: Sarah Sharp --- drivers/usb/core/driver.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index fca61720b873..38072e4e74bd 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1659,6 +1659,11 @@ static int usb_runtime_suspend(struct device *dev) return -EAGAIN; status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND); + /* The PM core reacts badly unless the return code is 0, + * -EAGAIN, or -EBUSY, so always return -EBUSY on an error. + */ + if (status != 0) + return -EBUSY; return status; } -- cgit v1.2.3 From 0b8ca72a23df365a413e03f991bc6b8179dee13f Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 21 Oct 2010 12:22:28 -0700 Subject: xhci: Remove old no-op test. The test of placing a number of command no-ops on the command ring and counting the number of no-op events that were generated was only used during the initial xHCI driver bring up. This test is no longer used, so delete it. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-ring.c | 19 ------------------- drivers/usb/host/xhci.c | 10 ---------- drivers/usb/host/xhci.h | 6 ------ 3 files changed, 35 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 3e8211c1ce5a..b36d3b003fee 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1113,7 +1113,6 @@ bandwidth_change: handle_set_deq_completion(xhci, event, xhci->cmd_ring->dequeue); break; case TRB_TYPE(TRB_CMD_NOOP): - ++xhci->noops_handled; break; case TRB_TYPE(TRB_RESET_EP): handle_reset_ep_completion(xhci, event, xhci->cmd_ring->dequeue); @@ -3125,24 +3124,6 @@ static int queue_command(struct xhci_hcd *xhci, u32 field1, u32 field2, return 0; } -/* Queue a no-op command on the command ring */ -static int queue_cmd_noop(struct xhci_hcd *xhci) -{ - return queue_command(xhci, 0, 0, 0, TRB_TYPE(TRB_CMD_NOOP), false); -} - -/* - * Place a no-op command on the command ring to test the command and - * event ring. - */ -void *xhci_setup_one_noop(struct xhci_hcd *xhci) -{ - if (queue_cmd_noop(xhci) < 0) - return NULL; - xhci->noops_submitted++; - return xhci_ring_cmd_db; -} - /* Queue a slot enable or disable request on the command ring */ int xhci_queue_slot_control(struct xhci_hcd *xhci, u32 trb_type, u32 slot_id) { diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 34cf4e165877..64f82b999221 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -350,7 +350,6 @@ void xhci_event_ring_work(unsigned long arg) temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); xhci_dbg(xhci, "ir_set 0 pending = 0x%x\n", temp); - xhci_dbg(xhci, "No-op commands handled = %d\n", xhci->noops_handled); xhci_dbg(xhci, "HC error bitmask = 0x%x\n", xhci->error_bitmask); xhci->error_bitmask = 0; xhci_dbg(xhci, "Event ring:\n"); @@ -370,10 +369,6 @@ void xhci_event_ring_work(unsigned long arg) xhci_dbg_ep_rings(xhci, i, j, &xhci->devs[i]->eps[j]); } } - - if (xhci->noops_submitted != NUM_TEST_NOOPS) - if (xhci_setup_one_noop(xhci)) - xhci_ring_cmd_db(xhci); spin_unlock_irqrestore(&xhci->lock, flags); if (!xhci->zombie) @@ -402,7 +397,6 @@ int xhci_run(struct usb_hcd *hcd) u32 ret; struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); - void (*doorbell)(struct xhci_hcd *) = NULL; hcd->uses_new_polling = 1; @@ -475,8 +469,6 @@ int xhci_run(struct usb_hcd *hcd) &xhci->ir_set->irq_pending); xhci_print_ir_set(xhci, xhci->ir_set, 0); - if (NUM_TEST_NOOPS > 0) - doorbell = xhci_setup_one_noop(xhci); if (xhci->quirks & XHCI_NEC_HOST) xhci_queue_vendor_command(xhci, 0, 0, 0, TRB_TYPE(TRB_NEC_GET_FW)); @@ -486,8 +478,6 @@ int xhci_run(struct usb_hcd *hcd) return -ENODEV; } - if (doorbell) - (*doorbell)(xhci); if (xhci->quirks & XHCI_NEC_HOST) xhci_ring_cmd_db(xhci); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 7f236fd22015..2cb5932935d4 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1243,8 +1243,6 @@ struct xhci_hcd { */ #define XHCI_STATE_DYING (1 << 0) /* Statistics */ - int noops_submitted; - int noops_handled; int error_bitmask; unsigned int quirks; #define XHCI_LINK_TRB_QUIRK (1 << 0) @@ -1264,9 +1262,6 @@ struct xhci_hcd { unsigned int num_usb2_ports; }; -/* For testing purposes */ -#define NUM_TEST_NOOPS 0 - /* convert between an HCD pointer and the corresponding EHCI_HCD */ static inline struct xhci_hcd *hcd_to_xhci(struct usb_hcd *hcd) { @@ -1471,7 +1466,6 @@ struct xhci_segment *trb_in_td(struct xhci_segment *start_seg, dma_addr_t suspect_dma); int xhci_is_vendor_info_code(struct xhci_hcd *xhci, unsigned int trb_comp_code); void xhci_ring_cmd_db(struct xhci_hcd *xhci); -void *xhci_setup_one_noop(struct xhci_hcd *xhci); int xhci_queue_slot_control(struct xhci_hcd *xhci, u32 trb_type, u32 slot_id); int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, u32 slot_id); -- cgit v1.2.3 From da13051cc756756f10b2da8ea97b05bdf84bd7bb Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Tue, 30 Nov 2010 15:55:51 -0800 Subject: USB: Remove bitmap #define from hcd.h Using a #define to redefine a common variable name is a bad thing, especially when the #define is in a header. include/linux/usb/hcd.h redefined bitmap to DeviceRemovable to avoid typing a long field in the hub descriptor. This has unintended side effects for files like drivers/usb/core/devio.c that include that file, since another header included after hcd.h has different variables named bitmap. Remove the bitmap #define and replace instances of it in the host controller code. Cleanup the spaces around function calls and square brackets while we're at it. Signed-off-by: Sarah Sharp Cc: Nobuhiro Iwamatsu Cc: Inaky Perez-Gonzalez Cc: Tony Olech Cc: "Robert P. J. Day" Cc: Max Vozeler Cc: Tejun Heo Cc: Yoshihiro Shimoda Cc: Rodolfo Giometti Cc: Mike Frysinger Cc: Anton Vorontsov Cc: Sebastian Siewior Cc: Lothar Wassmann Cc: Olav Kongas Cc: Martin Fuzzey Cc: Alan Stern Cc: David Brownell --- drivers/staging/usbip/vhci_hcd.c | 4 ++-- drivers/usb/gadget/dummy_hcd.c | 4 ++-- drivers/usb/host/ehci-hub.c | 4 ++-- drivers/usb/host/imx21-hcd.c | 4 ++-- drivers/usb/host/isp116x-hcd.c | 6 +++--- drivers/usb/host/isp1362-hcd.c | 6 +++--- drivers/usb/host/isp1760-hcd.c | 6 +++--- drivers/usb/host/ohci-hub.c | 12 ++++++------ drivers/usb/host/oxu210hp-hcd.c | 6 +++--- drivers/usb/host/r8a66597-hcd.c | 4 ++-- drivers/usb/host/sl811-hcd.c | 6 +++--- drivers/usb/host/u132-hcd.c | 10 +++++----- drivers/usb/host/xhci-hub.c | 1 - drivers/usb/wusbcore/rh.c | 4 ++-- include/linux/usb/hcd.h | 7 ------- 15 files changed, 38 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index a35fe61268de..0fe7e49cdc37 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -255,8 +255,8 @@ static inline void hub_descriptor(struct usb_hub_descriptor *desc) desc->wHubCharacteristics = (__force __u16) (__constant_cpu_to_le16(0x0001)); desc->bNbrPorts = VHCI_NPORTS; - desc->bitmap[0] = 0xff; - desc->bitmap[1] = 0xff; + desc->DeviceRemovable[0] = 0xff; + desc->DeviceRemovable[1] = 0xff; } static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 13b9f47feecd..f2040e8af8b1 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -1593,8 +1593,8 @@ hub_descriptor (struct usb_hub_descriptor *desc) desc->bDescLength = 9; desc->wHubCharacteristics = cpu_to_le16(0x0001); desc->bNbrPorts = 1; - desc->bitmap [0] = 0xff; - desc->bitmap [1] = 0xff; + desc->DeviceRemovable[0] = 0xff; + desc->DeviceRemovable[1] = 0xff; } static int dummy_hub_control ( diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index ae0140dd9b9b..dfa1e1d371c8 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -717,8 +717,8 @@ ehci_hub_descriptor ( desc->bDescLength = 7 + 2 * temp; /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */ - memset (&desc->bitmap [0], 0, temp); - memset (&desc->bitmap [temp], 0xff, temp); + memset(&desc->DeviceRemovable[0], 0, temp); + memset(&desc->DeviceRemovable[temp], 0xff, temp); temp = 0x0008; /* per-port overcurrent reporting */ if (HCS_PPC (ehci->hcs_params)) diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index b7dfda8a1d51..2f180dfe5371 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -1472,8 +1472,8 @@ static int get_hub_descriptor(struct usb_hcd *hcd, 0x0010 | /* No over current protection */ 0); - desc->bitmap[0] = 1 << 1; - desc->bitmap[1] = ~0; + desc->DeviceRemovable[0] = 1 << 1; + desc->DeviceRemovable[1] = ~0; return 0; } diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 0da7fc05f453..2a60a50bc420 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -951,9 +951,9 @@ static void isp116x_hub_descriptor(struct isp116x *isp116x, /* Power switching, device type, overcurrent. */ desc->wHubCharacteristics = cpu_to_le16((u16) ((reg >> 8) & 0x1f)); desc->bPwrOn2PwrGood = (u8) ((reg >> 24) & 0xff); - /* two bitmaps: ports removable, and legacy PortPwrCtrlMask */ - desc->bitmap[0] = 0; - desc->bitmap[1] = ~0; + /* ports removable, and legacy PortPwrCtrlMask */ + desc->DeviceRemovable[0] = 0; + desc->DeviceRemovable[1] = ~0; } /* Perform reset of a given port. diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 02b742df332a..6dd94b997d97 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c @@ -1552,9 +1552,9 @@ static void isp1362_hub_descriptor(struct isp1362_hcd *isp1362_hcd, desc->wHubCharacteristics = cpu_to_le16((reg >> 8) & 0x1f); DBG(0, "%s: hubcharacteristics = %02x\n", __func__, cpu_to_le16((reg >> 8) & 0x1f)); desc->bPwrOn2PwrGood = (reg >> 24) & 0xff; - /* two bitmaps: ports removable, and legacy PortPwrCtrlMask */ - desc->bitmap[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1; - desc->bitmap[1] = ~0; + /* ports removable, and legacy PortPwrCtrlMask */ + desc->DeviceRemovable[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1; + desc->DeviceRemovable[1] = ~0; DBG(3, "%s: exit\n", __func__); } diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index c7c1e0aa0b8e..1c8de7666d6a 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -1751,9 +1751,9 @@ static void isp1760_hub_descriptor(struct isp1760_hcd *priv, temp = 1 + (ports / 8); desc->bDescLength = 7 + 2 * temp; - /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */ - memset(&desc->bitmap[0], 0, temp); - memset(&desc->bitmap[temp], 0xff, temp); + /* ports removable, and usb 1.0 legacy PortPwrCtrlMask */ + memset(&desc->DeviceRemovable[0], 0, temp); + memset(&desc->DeviceRemovable[temp], 0xff, temp); /* per-port overcurrent reporting */ temp = 0x0008; diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index cddcda95b579..cd4b74f27d06 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -580,15 +580,15 @@ ohci_hub_descriptor ( temp |= 0x0008; desc->wHubCharacteristics = (__force __u16)cpu_to_hc16(ohci, temp); - /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */ + /* ports removable, and usb 1.0 legacy PortPwrCtrlMask */ rh = roothub_b (ohci); - memset(desc->bitmap, 0xff, sizeof(desc->bitmap)); - desc->bitmap [0] = rh & RH_B_DR; + memset(desc->DeviceRemovable, 0xff, sizeof(desc->DeviceRemovable)); + desc->DeviceRemovable[0] = rh & RH_B_DR; if (ohci->num_ports > 7) { - desc->bitmap [1] = (rh & RH_B_DR) >> 8; - desc->bitmap [2] = 0xff; + desc->DeviceRemovable[1] = (rh & RH_B_DR) >> 8; + desc->DeviceRemovable[2] = 0xff; } else - desc->bitmap [1] = 0xff; + desc->DeviceRemovable[1] = 0xff; } /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index e0cb12b573f9..ad54a4144756 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c @@ -451,9 +451,9 @@ static void ehci_hub_descriptor(struct oxu_hcd *oxu, temp = 1 + (ports / 8); desc->bDescLength = 7 + 2 * temp; - /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */ - memset(&desc->bitmap[0], 0, temp); - memset(&desc->bitmap[temp], 0xff, temp); + /* ports removable, and usb 1.0 legacy PortPwrCtrlMask */ + memset(&desc->DeviceRemovable[0], 0, temp); + memset(&desc->DeviceRemovable[temp], 0xff, temp); temp = 0x0008; /* per-port overcurrent reporting */ if (HCS_PPC(oxu->hcs_params)) diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 3076b1cc05df..98afe75500cc 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -2150,8 +2150,8 @@ static void r8a66597_hub_descriptor(struct r8a66597 *r8a66597, desc->bDescLength = 9; desc->bPwrOn2PwrGood = 0; desc->wHubCharacteristics = cpu_to_le16(0x0011); - desc->bitmap[0] = ((1 << r8a66597->max_root_hub) - 1) << 1; - desc->bitmap[1] = ~0; + desc->DeviceRemovable[0] = ((1 << r8a66597->max_root_hub) - 1) << 1; + desc->DeviceRemovable[1] = ~0; } static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 2e9602a10e9b..f3899b334c73 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -1111,9 +1111,9 @@ sl811h_hub_descriptor ( desc->wHubCharacteristics = cpu_to_le16(temp); - /* two bitmaps: ports removable, and legacy PortPwrCtrlMask */ - desc->bitmap[0] = 0 << 1; - desc->bitmap[1] = ~0; + /* ports removable, and legacy PortPwrCtrlMask */ + desc->DeviceRemovable[0] = 0 << 1; + desc->DeviceRemovable[1] = ~0; } static void diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index fab764946c74..a659e1590bca 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -2604,13 +2604,13 @@ static int u132_roothub_descriptor(struct u132 *u132, retval = u132_read_pcimem(u132, roothub.b, &rh_b); if (retval) return retval; - memset(desc->bitmap, 0xff, sizeof(desc->bitmap)); - desc->bitmap[0] = rh_b & RH_B_DR; + memset(desc->DeviceRemovable, 0xff, sizeof(desc->DeviceRemovable)); + desc->DeviceRemovable[0] = rh_b & RH_B_DR; if (u132->num_ports > 7) { - desc->bitmap[1] = (rh_b & RH_B_DR) >> 8; - desc->bitmap[2] = 0xff; + desc->DeviceRemovable[1] = (rh_b & RH_B_DR) >> 8; + desc->DeviceRemovable[2] = 0xff; } else - desc->bitmap[1] = 0xff; + desc->DeviceRemovable[1] = 0xff; return 0; } diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 5d963e350494..d83c27b9725b 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -45,7 +45,6 @@ static void xhci_hub_descriptor(struct xhci_hcd *xhci, temp = 1 + (ports / 8); desc->bDescLength = 7 + 2 * temp; - /* Why does core/hcd.h define bitmap? It's just confusing. */ memset(&desc->DeviceRemovable[0], 0, temp); memset(&desc->DeviceRemovable[temp], 0xff, temp); diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c index 785772e66ed0..cff246b7cb26 100644 --- a/drivers/usb/wusbcore/rh.c +++ b/drivers/usb/wusbcore/rh.c @@ -184,8 +184,8 @@ static int wusbhc_rh_get_hub_descr(struct wusbhc *wusbhc, u16 wValue, descr->bPwrOn2PwrGood = 0; descr->bHubContrCurrent = 0; /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */ - memset(&descr->bitmap[0], 0, temp); - memset(&descr->bitmap[temp], 0xff, temp); + memset(&descr->DeviceRemovable[0], 0, temp); + memset(&descr->DeviceRemovable[temp], 0xff, temp); return 0; } diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 8b65068c6af9..0be61970074e 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -639,13 +639,6 @@ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb, #endif /* CONFIG_USB_MON || CONFIG_USB_MON_MODULE */ -/*-------------------------------------------------------------------------*/ - -/* hub.h ... DeviceRemovable in 2.4.2-ac11, gone in 2.4.10 */ -/* bleech -- resurfaced in 2.4.11 or 2.4.12 */ -#define bitmap DeviceRemovable - - /*-------------------------------------------------------------------------*/ /* random stuff */ -- cgit v1.2.3 From abc4f9b099e9e7db3f6f945210aee125571c236d Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Wed, 1 Dec 2010 09:22:05 -0800 Subject: USB: Fix usb_add_hcd() checkpatch errors. The irq enabling code is going to be refactored into a new function, so clean up some checkpatch errors before moving it. Signed-off-by: Sarah Sharp --- drivers/usb/core/hcd.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index e7d0c4571bbe..b70db6e78977 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2325,10 +2325,12 @@ int usb_add_hcd(struct usb_hcd *hcd, snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", hcd->driver->description, hcd->self.busnum); - if ((retval = request_irq(irqnum, &usb_hcd_irq, irqflags, - hcd->irq_descr, hcd)) != 0) { + retval = request_irq(irqnum, &usb_hcd_irq, irqflags, + hcd->irq_descr, hcd); + if (retval != 0) { dev_err(hcd->self.controller, - "request interrupt %d failed\n", irqnum); + "request interrupt %d failed\n", + irqnum); goto err_request_irq; } hcd->irq = irqnum; @@ -2345,7 +2347,8 @@ int usb_add_hcd(struct usb_hcd *hcd, (unsigned long long)hcd->rsrc_start); } - if ((retval = hcd->driver->start(hcd)) < 0) { + retval = hcd->driver->start(hcd); + if (retval < 0) { dev_err(hcd->self.controller, "startup error %d\n", retval); goto err_hcd_driver_start; } -- cgit v1.2.3 From 1d5810b6923c76fc95e52d9d3491c91824c2f075 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 9 Dec 2010 14:52:41 -0800 Subject: xhci: Rework port suspend structures for limited ports. The USB core only allows up to 31 (USB_MAXCHILDREN) ports under a roothub. The xHCI driver keeps track of which ports are suspended, which ports have a suspend change bit set, and what time the port will be done resuming. It keeps track of the first two by setting a bit in a u32 variable, suspended_ports or port_c_suspend. The xHCI driver currently assumes we can have up to 256 ports under a roothub, so it allocates an array of 8 u32 variables for both suspended_ports and port_c_suspend. It also allocates a 256-element array to keep track of when the ports will be done resuming. Since we can only have 31 roothub ports, we only need to use one u32 for each of the suspend state and change variables. We simplify the bit math that's trying to index into those arrays and set the correct bit, if we assume wIndex never exceeds 30. (wIndex is zero-based after it's decremented from the value passed in from the USB core.) Finally, we change the resume_done array to only hold 31 elements. Signed-off-by: Sarah Sharp Cc: Andiry Xu --- drivers/usb/host/xhci-hub.c | 28 ++++++++++------------------ drivers/usb/host/xhci-mem.c | 2 +- drivers/usb/host/xhci.h | 9 +++++---- 3 files changed, 16 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index d83c27b9725b..50e250ceee96 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -347,20 +347,15 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, goto error; } xhci_ring_device(xhci, slot_id); - xhci->port_c_suspend[wIndex >> 5] |= - 1 << (wIndex & 31); - xhci->suspended_ports[wIndex >> 5] &= - ~(1 << (wIndex & 31)); + xhci->port_c_suspend |= 1 << wIndex; + xhci->suspended_ports &= ~(1 << wIndex); } } if ((temp & PORT_PLS_MASK) == XDEV_U0 && (temp & PORT_POWER) - && (xhci->suspended_ports[wIndex >> 5] & - (1 << (wIndex & 31)))) { - xhci->suspended_ports[wIndex >> 5] &= - ~(1 << (wIndex & 31)); - xhci->port_c_suspend[wIndex >> 5] |= - 1 << (wIndex & 31); + && (xhci->suspended_ports & (1 << wIndex))) { + xhci->suspended_ports &= ~(1 << wIndex); + xhci->port_c_suspend |= 1 << wIndex; } if (temp & PORT_CONNECT) { status |= USB_PORT_STAT_CONNECTION; @@ -374,7 +369,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, status |= USB_PORT_STAT_RESET; if (temp & PORT_POWER) status |= USB_PORT_STAT_POWER; - if (xhci->port_c_suspend[wIndex >> 5] & (1 << (wIndex & 31))) + if (xhci->port_c_suspend & (1 << wIndex)) status |= 1 << USB_PORT_FEAT_C_SUSPEND; xhci_dbg(xhci, "Get port status returned 0x%x\n", status); put_unaligned(cpu_to_le32(status), (__le32 *) buf); @@ -421,8 +416,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, spin_lock_irqsave(&xhci->lock, flags); temp = xhci_readl(xhci, addr); - xhci->suspended_ports[wIndex >> 5] |= - 1 << (wIndex & (31)); + xhci->suspended_ports |= 1 << wIndex; break; case USB_PORT_FEAT_POWER: /* @@ -489,8 +483,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, temp |= PORT_LINK_STROBE | XDEV_U0; xhci_writel(xhci, temp, addr); } - xhci->port_c_suspend[wIndex >> 5] |= - 1 << (wIndex & 31); + xhci->port_c_suspend |= 1 << wIndex; } slot_id = xhci_find_slot_id_by_port(xhci, wIndex + 1); @@ -501,8 +494,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, xhci_ring_device(xhci, slot_id); break; case USB_PORT_FEAT_C_SUSPEND: - xhci->port_c_suspend[wIndex >> 5] &= - ~(1 << (wIndex & 31)); + xhci->port_c_suspend &= ~(1 << wIndex); case USB_PORT_FEAT_C_RESET: case USB_PORT_FEAT_C_CONNECTION: case USB_PORT_FEAT_C_OVER_CURRENT: @@ -560,7 +552,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) NUM_PORT_REGS*i; temp = xhci_readl(xhci, addr); if ((temp & mask) != 0 || - (xhci->port_c_suspend[i >> 5] & 1 << (i & 31)) || + (xhci->port_c_suspend & 1 << i) || (xhci->resume_done[i] && time_after_eq( jiffies, xhci->resume_done[i]))) { buf[(i + 1) / 8] |= 1 << (i + 1) % 8; diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 1d0f45f0e7a6..e3e6410d7b5e 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1971,7 +1971,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) init_completion(&xhci->addr_dev); for (i = 0; i < MAX_HC_SLOTS; ++i) xhci->devs[i] = NULL; - for (i = 0; i < MAX_HC_PORTS; ++i) + for (i = 0; i < USB_MAXCHILDREN; ++i) xhci->resume_done[i] = 0; if (scratchpad_alloc(xhci, flags)) diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 2cb5932935d4..c4e70c6d809c 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1248,10 +1248,11 @@ struct xhci_hcd { #define XHCI_LINK_TRB_QUIRK (1 << 0) #define XHCI_RESET_EP_QUIRK (1 << 1) #define XHCI_NEC_HOST (1 << 2) - u32 port_c_suspend[8]; /* port suspend change*/ - u32 suspended_ports[8]; /* which ports are - suspended */ - unsigned long resume_done[MAX_HC_PORTS]; + /* port suspend change*/ + u32 port_c_suspend; + /* which ports are suspended */ + u32 suspended_ports; + unsigned long resume_done[USB_MAXCHILDREN]; /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */ u8 *port_array; /* Array of pointers to USB 3.0 PORTSC registers */ -- cgit v1.2.3 From 518e848ea8e2932ce18ce2daef8ad5f55a145f27 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Wed, 15 Dec 2010 11:56:29 -0800 Subject: xhci: Rename variables and reduce register reads. The xhci_bus_suspend() and xhci_bus_resume() functions are a bit hard to read, because they have an ambiguously named variable "port". Rename it to "port_index". Introduce a new temporary variable, "max_ports" that holds the maximum number of roothub ports the host controller supports. This will reduce the number of register reads, and make it easy to change the maximum number of ports when there are two roothubs. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-hub.c | 41 ++++++++++++++++++++++------------------- drivers/usb/host/xhci-ring.c | 6 +++--- 2 files changed, 25 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 50e250ceee96..004a46557f9c 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -568,42 +568,44 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) int xhci_bus_suspend(struct usb_hcd *hcd) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); - int port; + int max_ports, port_index; unsigned long flags; xhci_dbg(xhci, "suspend root hub\n"); + max_ports = HCS_MAX_PORTS(xhci->hcs_params1); spin_lock_irqsave(&xhci->lock, flags); if (hcd->self.root_hub->do_remote_wakeup) { - port = HCS_MAX_PORTS(xhci->hcs_params1); - while (port--) { - if (xhci->resume_done[port] != 0) { + port_index = max_ports; + while (port_index--) { + if (xhci->resume_done[port_index] != 0) { spin_unlock_irqrestore(&xhci->lock, flags); xhci_dbg(xhci, "suspend failed because " "port %d is resuming\n", - port + 1); + port_index + 1); return -EBUSY; } } } - port = HCS_MAX_PORTS(xhci->hcs_params1); + port_index = max_ports; xhci->bus_suspended = 0; - while (port--) { + while (port_index--) { /* suspend the port if the port is not suspended */ u32 __iomem *addr; u32 t1, t2; int slot_id; addr = &xhci->op_regs->port_status_base + - NUM_PORT_REGS * (port & 0xff); + NUM_PORT_REGS * (port_index & 0xff); t1 = xhci_readl(xhci, addr); t2 = xhci_port_state_to_neutral(t1); if ((t1 & PORT_PE) && !(t1 & PORT_PLS_MASK)) { - xhci_dbg(xhci, "port %d not suspended\n", port); - slot_id = xhci_find_slot_id_by_port(xhci, port + 1); + xhci_dbg(xhci, "port %d not suspended\n", port_index); + slot_id = xhci_find_slot_id_by_port(xhci, + port_index + 1); if (slot_id) { spin_unlock_irqrestore(&xhci->lock, flags); xhci_stop_device(xhci, slot_id, 1); @@ -611,7 +613,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd) } t2 &= ~PORT_PLS_MASK; t2 |= PORT_LINK_STROBE | XDEV_U3; - set_bit(port, &xhci->bus_suspended); + set_bit(port_index, &xhci->bus_suspended); } if (hcd->self.root_hub->do_remote_wakeup) { if (t1 & PORT_CONNECT) { @@ -634,7 +636,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd) u32 tmp; addr = &xhci->op_regs->port_power_base + - NUM_PORT_REGS * (port & 0xff); + NUM_PORT_REGS * (port_index & 0xff); tmp = xhci_readl(xhci, addr); tmp |= PORT_RWE; xhci_writel(xhci, tmp, addr); @@ -649,11 +651,12 @@ int xhci_bus_suspend(struct usb_hcd *hcd) int xhci_bus_resume(struct usb_hcd *hcd) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); - int port; + int max_ports, port_index; u32 temp; unsigned long flags; xhci_dbg(xhci, "resume root hub\n"); + max_ports = HCS_MAX_PORTS(xhci->hcs_params1); if (time_before(jiffies, xhci->next_statechange)) msleep(5); @@ -669,8 +672,8 @@ int xhci_bus_resume(struct usb_hcd *hcd) temp &= ~CMD_EIE; xhci_writel(xhci, temp, &xhci->op_regs->command); - port = HCS_MAX_PORTS(xhci->hcs_params1); - while (port--) { + port_index = max_ports; + while (port_index--) { /* Check whether need resume ports. If needed resume port and disable remote wakeup */ u32 __iomem *addr; @@ -678,13 +681,13 @@ int xhci_bus_resume(struct usb_hcd *hcd) int slot_id; addr = &xhci->op_regs->port_status_base + - NUM_PORT_REGS * (port & 0xff); + NUM_PORT_REGS * (port_index & 0xff); temp = xhci_readl(xhci, addr); if (DEV_SUPERSPEED(temp)) temp &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS); else temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); - if (test_bit(port, &xhci->bus_suspended) && + if (test_bit(port_index, &xhci->bus_suspended) && (temp & PORT_PLS_MASK)) { if (DEV_SUPERSPEED(temp)) { temp = xhci_port_state_to_neutral(temp); @@ -707,7 +710,7 @@ int xhci_bus_resume(struct usb_hcd *hcd) temp |= PORT_LINK_STROBE | XDEV_U0; xhci_writel(xhci, temp, addr); } - slot_id = xhci_find_slot_id_by_port(xhci, port + 1); + slot_id = xhci_find_slot_id_by_port(xhci, port_index + 1); if (slot_id) xhci_ring_device(xhci, slot_id); } else @@ -719,7 +722,7 @@ int xhci_bus_resume(struct usb_hcd *hcd) u32 tmp; addr = &xhci->op_regs->port_power_base + - NUM_PORT_REGS * (port & 0xff); + NUM_PORT_REGS * (port_index & 0xff); tmp = xhci_readl(xhci, addr); tmp &= ~PORT_RWE; xhci_writel(xhci, tmp, addr); diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index b36d3b003fee..3264d6275bf2 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1163,7 +1163,7 @@ static void handle_port_status(struct xhci_hcd *xhci, u32 port_id; u32 temp, temp1; u32 __iomem *addr; - int ports; + int max_ports; int slot_id; /* Port status change events always have a successful completion code */ @@ -1174,8 +1174,8 @@ static void handle_port_status(struct xhci_hcd *xhci, port_id = GET_PORT_ID(event->generic.field[0]); xhci_dbg(xhci, "Port Status Change Event for port %d\n", port_id); - ports = HCS_MAX_PORTS(xhci->hcs_params1); - if ((port_id <= 0) || (port_id > ports)) { + max_ports = HCS_MAX_PORTS(xhci->hcs_params1); + if ((port_id <= 0) || (port_id > max_ports)) { xhci_warn(xhci, "Invalid port id %d\n", port_id); goto cleanup; } -- cgit v1.2.3 From 019a35f1142b1cd153c8a38338515e633ec0cf77 Mon Sep 17 00:00:00 2001 From: Andiry Xu Date: Thu, 6 Jan 2011 15:43:17 +0800 Subject: xHCI: Remove redundant variable in xhci_resume() Set hcd->state = HC_STATE_SUSPENDED if there is a power loss during system resume or the system is hibernated, otherwise leave it be. The variable old_state is redundant and made an unreachable code path, so remove it. Signed-off-by: Andiry Xu Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 64f82b999221..023175eab07d 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -696,9 +696,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) { u32 command, temp = 0; struct usb_hcd *hcd = xhci_to_hcd(xhci); - int old_state, retval; + int retval; - old_state = hcd->state; if (time_before(jiffies, xhci->next_statechange)) msleep(100); @@ -782,10 +781,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - if (!hibernated) - hcd->state = old_state; - else - hcd->state = HC_STATE_SUSPENDED; spin_unlock_irq(&xhci->lock); return 0; -- cgit v1.2.3 From bdfca5025a159c8bb966e3b87b0c084dd1f831a9 Mon Sep 17 00:00:00 2001 From: Andiry Xu Date: Thu, 6 Jan 2011 15:43:39 +0800 Subject: xHCI: prolong host controller halt time limit xHCI 1.0 spec specifies the xHC shall halt within 16ms after software clears Run/Stop bit. In xHCI 0.96 spec the time limit is 16 microframes (2ms), it's too short and often cause dmesg shows "Host controller not halted, aborting reset." message when rmmod xhci-hcd. Modify the time limit to comply with xHCI 1.0 specification and prevents the warning message showing when remove xhci-hcd. Signed-off-by: Andiry Xu Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-ext-caps.h | 4 ++-- drivers/usb/host/xhci.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h index 78c4edac1db1..ce5c9e51748e 100644 --- a/drivers/usb/host/xhci-ext-caps.h +++ b/drivers/usb/host/xhci-ext-caps.h @@ -19,8 +19,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* Up to 16 microframes to halt an HC - one microframe is 125 microsectonds */ -#define XHCI_MAX_HALT_USEC (16*125) +/* Up to 16 ms to halt an HC */ +#define XHCI_MAX_HALT_USEC (16*1000) /* HC not running - set to 1 when run/stop bit is cleared. */ #define XHCI_STS_HALT (1<<0) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 023175eab07d..8dfa67ff5fac 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -93,7 +93,7 @@ void xhci_quiesce(struct xhci_hcd *xhci) * * Disable any IRQs and clear the run/stop bit. * HC will complete any current and actively pipelined transactions, and - * should halt within 16 microframes of the run/stop bit being cleared. + * should halt within 16 ms of the run/stop bit being cleared. * Read HC Halted bit in the status register to see when the HC is finished. * XXX: shouldn't we set HC_STATE_HALT here somewhere? */ -- cgit v1.2.3 From ac04e6ff3e32699920ae75b22e2bec7f7c631434 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 11 Mar 2011 08:47:33 -0800 Subject: xhci: Remove references to HC_STATE_HALT. The xHCI driver doesn't ever test hcd->state for HC_STATE_HALT. The USB core recently stopped using it internally, so there's no point in setting it in the driver. We still need to set HC_STATE_RUNNING in order to make it past the USB core's hcd->state check in register_roothub(). Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-ring.c | 5 +---- drivers/usb/host/xhci.c | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 3264d6275bf2..6bca2526d54a 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -819,8 +819,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) if (ret < 0) { /* This is bad; the host is not responding to commands and it's * not allowing itself to be halted. At least interrupts are - * disabled, so we can set HC_STATE_HALT and notify the - * USB core. But if we call usb_hc_died(), it will attempt to + * disabled. If we call usb_hc_died(), it will attempt to * disconnect all device drivers under this host. Those * disconnect() methods will wait for all URBs to be unlinked, * so we must complete them. @@ -865,7 +864,6 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) } } spin_unlock(&xhci->lock); - xhci_to_hcd(xhci)->state = HC_STATE_HALT; xhci_dbg(xhci, "Calling usb_hc_died()\n"); usb_hc_died(xhci_to_hcd(xhci)); xhci_dbg(xhci, "xHCI host controller is dead.\n"); @@ -2113,7 +2111,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) xhci_warn(xhci, "WARNING: Host System Error\n"); xhci_halt(xhci); hw_died: - xhci_to_hcd(xhci)->state = HC_STATE_HALT; spin_unlock(&xhci->lock); return -ESHUTDOWN; } diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 8dfa67ff5fac..63b8db5275e9 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -95,7 +95,6 @@ void xhci_quiesce(struct xhci_hcd *xhci) * HC will complete any current and actively pipelined transactions, and * should halt within 16 ms of the run/stop bit being cleared. * Read HC Halted bit in the status register to see when the HC is finished. - * XXX: shouldn't we set HC_STATE_HALT here somewhere? */ int xhci_halt(struct xhci_hcd *xhci) { @@ -134,7 +133,7 @@ int xhci_start(struct xhci_hcd *xhci) } /* - * Reset a halted HC, and set the internal HC state to HC_STATE_HALT. + * Reset a halted HC. * * This resets pipelines, timers, counters, state machines, etc. * Transactions will be terminated immediately, and operational registers @@ -156,8 +155,6 @@ int xhci_reset(struct xhci_hcd *xhci) command = xhci_readl(xhci, &xhci->op_regs->command); command |= CMD_RESET; xhci_writel(xhci, command, &xhci->op_regs->command); - /* XXX: Why does EHCI set this here? Shouldn't other code do this? */ - xhci_to_hcd(xhci)->state = HC_STATE_HALT; ret = handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000); -- cgit v1.2.3 From 4814030ce11f08350b7a91573487ad4b600dae34 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 11 Mar 2011 13:46:17 -0800 Subject: usb: Initialize hcd->state roothubs. We would like to allow host controller drivers to stop using hcd->state. Unfortunately, some host controller drivers use hcd->state as an implicit way of telling the core that a controller has died. The roothub registration functions must assume the host died if hcd->state equals HC_STATE_HALT. To facilitate drivers that don't want to set hcd->state to HC_STATE_RUNNING in their initialization routines, we set the state to running before calling the host controller's start function. Signed-off-by: Sarah Sharp --- drivers/usb/core/hcd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index b70db6e78977..a97ed6d293e9 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2347,6 +2347,7 @@ int usb_add_hcd(struct usb_hcd *hcd, (unsigned long long)hcd->rsrc_start); } + hcd->state = HC_STATE_RUNNING; retval = hcd->driver->start(hcd); if (retval < 0) { dev_err(hcd->self.controller, "startup error %d\n", retval); -- cgit v1.2.3 From ad73dff32e04cad1ff2af89512bf489224b503cc Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 11 Mar 2011 13:49:55 -0800 Subject: xhci: Remove references to HC_STATE_RUNNING. The USB core will set hcd->state to HC_STATE_RUNNING before calling xhci_run, so there's no point in setting it twice. The USB core also doesn't pay attention to HC_STATE_RUNNING on the resume path anymore; it uses HCD_RH_RUNNING(), which looks at hcd->flags & (1U << HCD_FLAG_RH_RUNNING. Therefore, it's safe to remove the state set in xhci_bus_resume(). Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-hub.c | 1 - drivers/usb/host/xhci.c | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 004a46557f9c..43e0a099d634 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -732,7 +732,6 @@ int xhci_bus_resume(struct usb_hcd *hcd) (void) xhci_readl(xhci, &xhci->op_regs->command); xhci->next_statechange = jiffies + msecs_to_jiffies(5); - hcd->state = HC_STATE_RUNNING; /* re-enable irqs */ temp = xhci_readl(xhci, &xhci->op_regs->command); temp |= CMD_EIE; diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 63b8db5275e9..883b4c402c6a 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -452,7 +452,6 @@ int xhci_run(struct usb_hcd *hcd) xhci_writel(xhci, temp, &xhci->ir_set->irq_control); /* Set the HCD state before we enable the irqs */ - hcd->state = HC_STATE_RUNNING; temp = xhci_readl(xhci, &xhci->op_regs->command); temp |= (CMD_EIE); xhci_dbg(xhci, "// Enable interrupts, cmd = 0x%x.\n", -- cgit v1.2.3 From dbe79bbe9dcb22cb3651c46f18943477141ca452 Mon Sep 17 00:00:00 2001 From: John Youn Date: Mon, 17 Sep 2001 00:00:00 -0700 Subject: USB 3.0 Hub Changes Update the USB core to deal with USB 3.0 hubs. These hubs have a slightly different hub descriptor than USB 2.0 hubs, with a fixed (rather than variable length) size. Change the USB core's hub descriptor to have a union for the last fields that differ. Change the host controller drivers that access those last fields (DeviceRemovable and PortPowerCtrlMask) to use the union. Translate the new version of the hub port status field into the old version that khubd understands. (Note: we need to fix it to translate the roothub's port status once we stop converting it to USB 2.0 hub status internally.) Add new code to handle link state change status. Send out new control messages that are needed for USB 3.0 hubs, like Set Hub Depth. This patch is a modified version of the original patch submitted by John Youn. It's updated to reflect the removal of the "bitmap" #define, and change the hub descriptor accesses of a couple new host controller drivers. Signed-off-by: John Youn Signed-off-by: Sarah Sharp Cc: Nobuhiro Iwamatsu Cc: Inaky Perez-Gonzalez Cc: Tony Olech Cc: "Robert P. J. Day" Cc: Max Vozeler Cc: Tejun Heo Cc: Yoshihiro Shimoda Cc: Rodolfo Giometti Cc: Mike Frysinger Cc: Anton Vorontsov Cc: Sebastian Siewior Cc: Lothar Wassmann Cc: Olav Kongas Cc: Martin Fuzzey Cc: Alan Stern Cc: David Brownell --- drivers/staging/usbip/vhci_hcd.c | 4 +-- drivers/usb/core/hub.c | 73 +++++++++++++++++++++++++++++++++++----- drivers/usb/gadget/dummy_hcd.c | 4 +-- drivers/usb/host/ehci-hub.c | 4 +-- drivers/usb/host/imx21-hcd.c | 4 +-- drivers/usb/host/isp116x-hcd.c | 4 +-- drivers/usb/host/isp1362-hcd.c | 4 +-- drivers/usb/host/isp1760-hcd.c | 4 +-- drivers/usb/host/ohci-hub.c | 11 +++--- drivers/usb/host/oxu210hp-hcd.c | 4 +-- drivers/usb/host/r8a66597-hcd.c | 5 +-- drivers/usb/host/sl811-hcd.c | 4 +-- drivers/usb/host/u132-hcd.c | 11 +++--- drivers/usb/host/xhci-hub.c | 4 +-- drivers/usb/musb/musb_virthub.c | 4 +-- drivers/usb/wusbcore/rh.c | 4 +-- include/linux/usb/ch11.h | 41 +++++++++++++++++++--- 17 files changed, 141 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index 0fe7e49cdc37..29ccc0150996 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -255,8 +255,8 @@ static inline void hub_descriptor(struct usb_hub_descriptor *desc) desc->wHubCharacteristics = (__force __u16) (__constant_cpu_to_le16(0x0001)); desc->bNbrPorts = VHCI_NPORTS; - desc->DeviceRemovable[0] = 0xff; - desc->DeviceRemovable[1] = 0xff; + desc->u.hs.DeviceRemovable[0] = 0xff; + desc->u.hs.DeviceRemovable[1] = 0xff; } static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index b574f9131b43..feb6e596c7c9 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -82,6 +82,10 @@ struct usb_hub { void **port_owners; }; +static inline int hub_is_superspeed(struct usb_device *hdev) +{ + return (hdev->descriptor.bDeviceProtocol == 3); +} /* Protect struct usb_device->state and ->children members * Note: Both are also protected by ->dev.sem, except that ->state can @@ -172,14 +176,23 @@ static struct usb_hub *hdev_to_hub(struct usb_device *hdev) } /* USB 2.0 spec Section 11.24.4.5 */ -static int get_hub_descriptor(struct usb_device *hdev, void *data, int size) +static int get_hub_descriptor(struct usb_device *hdev, void *data) { - int i, ret; + int i, ret, size; + unsigned dtype; + + if (hub_is_superspeed(hdev)) { + dtype = USB_DT_SS_HUB; + size = USB_DT_SS_HUB_SIZE; + } else { + dtype = USB_DT_HUB; + size = sizeof(struct usb_hub_descriptor); + } for (i = 0; i < 3; i++) { ret = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB, - USB_DT_HUB << 8, 0, data, size, + dtype << 8, 0, data, size, USB_CTRL_GET_TIMEOUT); if (ret >= (USB_DT_HUB_NONVAR_SIZE + 2)) return ret; @@ -365,6 +378,19 @@ static int hub_port_status(struct usb_hub *hub, int port1, } else { *status = le16_to_cpu(hub->status->port.wPortStatus); *change = le16_to_cpu(hub->status->port.wPortChange); + + if ((hub->hdev->parent != NULL) && + hub_is_superspeed(hub->hdev)) { + /* Translate the USB 3 port status */ + u16 tmp = *status & USB_SS_PORT_STAT_MASK; + if (*status & USB_SS_PORT_STAT_POWER) + tmp |= USB_PORT_STAT_POWER; + if ((*status & USB_SS_PORT_STAT_SPEED) == + USB_PORT_STAT_SPEED_5GBPS) + tmp |= USB_PORT_STAT_SUPER_SPEED; + *status = tmp; + } + ret = 0; } mutex_unlock(&hub->status_mutex); @@ -607,7 +633,7 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state) if (hdev->children[port1-1] && set_state) usb_set_device_state(hdev->children[port1-1], USB_STATE_NOTATTACHED); - if (!hub->error) + if (!hub->error && !hub_is_superspeed(hub->hdev)) ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE); if (ret) dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n", @@ -795,6 +821,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) clear_port_feature(hub->hdev, port1, USB_PORT_FEAT_C_ENABLE); } + if (portchange & USB_PORT_STAT_C_LINK_STATE) { + need_debounce_delay = true; + clear_port_feature(hub->hdev, port1, + USB_PORT_FEAT_C_PORT_LINK_STATE); + } /* We can forget about a "removed" device when there's a * physical disconnect or the connect status changes. @@ -964,12 +995,23 @@ static int hub_configure(struct usb_hub *hub, goto fail; } + if (hub_is_superspeed(hdev) && (hdev->parent != NULL)) { + ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), + HUB_SET_DEPTH, USB_RT_HUB, + hdev->level - 1, 0, NULL, 0, + USB_CTRL_SET_TIMEOUT); + + if (ret < 0) { + message = "can't set hub depth"; + goto fail; + } + } + /* Request the entire hub descriptor. * hub->descriptor can handle USB_MAXCHILDREN ports, * but the hub can/will return fewer bytes here. */ - ret = get_hub_descriptor(hdev, hub->descriptor, - sizeof(*hub->descriptor)); + ret = get_hub_descriptor(hdev, hub->descriptor); if (ret < 0) { message = "can't read hub descriptor"; goto fail; @@ -991,12 +1033,14 @@ static int hub_configure(struct usb_hub *hub, wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); - if (wHubCharacteristics & HUB_CHAR_COMPOUND) { + /* FIXME for USB 3.0, skip for now */ + if ((wHubCharacteristics & HUB_CHAR_COMPOUND) && + !(hub_is_superspeed(hdev))) { int i; char portstr [USB_MAXCHILDREN + 1]; for (i = 0; i < hdev->maxchild; i++) - portstr[i] = hub->descriptor->DeviceRemovable + portstr[i] = hub->descriptor->u.hs.DeviceRemovable [((i + 1) / 8)] & (1 << ((i + 1) % 8)) ? 'F' : 'R'; portstr[hdev->maxchild] = 0; @@ -2029,6 +2073,8 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, udev->speed = USB_SPEED_HIGH; else if (portstatus & USB_PORT_STAT_LOW_SPEED) udev->speed = USB_SPEED_LOW; + else if (portstatus & USB_PORT_STAT_SUPER_SPEED) + udev->speed = USB_SPEED_SUPER; else udev->speed = USB_SPEED_FULL; return 0; @@ -3430,6 +3476,17 @@ static void hub_events(void) clear_port_feature(hdev, i, USB_PORT_FEAT_C_RESET); } + if (portchange & USB_PORT_STAT_C_LINK_STATE) { + clear_port_feature(hub->hdev, i, + USB_PORT_FEAT_C_PORT_LINK_STATE); + } + if (portchange & USB_PORT_STAT_C_CONFIG_ERROR) { + dev_warn(hub_dev, + "config error on port %d\n", + i); + clear_port_feature(hub->hdev, i, + USB_PORT_FEAT_C_PORT_CONFIG_ERROR); + } if (connect_change) hub_port_connect_change(hub, i, diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index f2040e8af8b1..3214ca375d64 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -1593,8 +1593,8 @@ hub_descriptor (struct usb_hub_descriptor *desc) desc->bDescLength = 9; desc->wHubCharacteristics = cpu_to_le16(0x0001); desc->bNbrPorts = 1; - desc->DeviceRemovable[0] = 0xff; - desc->DeviceRemovable[1] = 0xff; + desc->u.hs.DeviceRemovable[0] = 0xff; + desc->u.hs.DeviceRemovable[1] = 0xff; } static int dummy_hub_control ( diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index dfa1e1d371c8..d05ea03cfb4d 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -717,8 +717,8 @@ ehci_hub_descriptor ( desc->bDescLength = 7 + 2 * temp; /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */ - memset(&desc->DeviceRemovable[0], 0, temp); - memset(&desc->DeviceRemovable[temp], 0xff, temp); + memset(&desc->u.hs.DeviceRemovable[0], 0, temp); + memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); temp = 0x0008; /* per-port overcurrent reporting */ if (HCS_PPC (ehci->hcs_params)) diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index 2f180dfe5371..2562e92e3178 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -1472,8 +1472,8 @@ static int get_hub_descriptor(struct usb_hcd *hcd, 0x0010 | /* No over current protection */ 0); - desc->DeviceRemovable[0] = 1 << 1; - desc->DeviceRemovable[1] = ~0; + desc->u.hs.DeviceRemovable[0] = 1 << 1; + desc->u.hs.DeviceRemovable[1] = ~0; return 0; } diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 2a60a50bc420..c0e22f26da19 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -952,8 +952,8 @@ static void isp116x_hub_descriptor(struct isp116x *isp116x, desc->wHubCharacteristics = cpu_to_le16((u16) ((reg >> 8) & 0x1f)); desc->bPwrOn2PwrGood = (u8) ((reg >> 24) & 0xff); /* ports removable, and legacy PortPwrCtrlMask */ - desc->DeviceRemovable[0] = 0; - desc->DeviceRemovable[1] = ~0; + desc->u.hs.DeviceRemovable[0] = 0; + desc->u.hs.DeviceRemovable[1] = ~0; } /* Perform reset of a given port. diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 6dd94b997d97..662cd002adfc 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c @@ -1553,8 +1553,8 @@ static void isp1362_hub_descriptor(struct isp1362_hcd *isp1362_hcd, DBG(0, "%s: hubcharacteristics = %02x\n", __func__, cpu_to_le16((reg >> 8) & 0x1f)); desc->bPwrOn2PwrGood = (reg >> 24) & 0xff; /* ports removable, and legacy PortPwrCtrlMask */ - desc->DeviceRemovable[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1; - desc->DeviceRemovable[1] = ~0; + desc->u.hs.DeviceRemovable[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1; + desc->u.hs.DeviceRemovable[1] = ~0; DBG(3, "%s: exit\n", __func__); } diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 1c8de7666d6a..f50e84ac570a 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -1752,8 +1752,8 @@ static void isp1760_hub_descriptor(struct isp1760_hcd *priv, desc->bDescLength = 7 + 2 * temp; /* ports removable, and usb 1.0 legacy PortPwrCtrlMask */ - memset(&desc->DeviceRemovable[0], 0, temp); - memset(&desc->DeviceRemovable[temp], 0xff, temp); + memset(&desc->u.hs.DeviceRemovable[0], 0, temp); + memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); /* per-port overcurrent reporting */ temp = 0x0008; diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index cd4b74f27d06..9154615292db 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -582,13 +582,14 @@ ohci_hub_descriptor ( /* ports removable, and usb 1.0 legacy PortPwrCtrlMask */ rh = roothub_b (ohci); - memset(desc->DeviceRemovable, 0xff, sizeof(desc->DeviceRemovable)); - desc->DeviceRemovable[0] = rh & RH_B_DR; + memset(desc->u.hs.DeviceRemovable, 0xff, + sizeof(desc->u.hs.DeviceRemovable)); + desc->u.hs.DeviceRemovable[0] = rh & RH_B_DR; if (ohci->num_ports > 7) { - desc->DeviceRemovable[1] = (rh & RH_B_DR) >> 8; - desc->DeviceRemovable[2] = 0xff; + desc->u.hs.DeviceRemovable[1] = (rh & RH_B_DR) >> 8; + desc->u.hs.DeviceRemovable[2] = 0xff; } else - desc->DeviceRemovable[1] = 0xff; + desc->u.hs.DeviceRemovable[1] = 0xff; } /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index ad54a4144756..38193f4e980e 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c @@ -452,8 +452,8 @@ static void ehci_hub_descriptor(struct oxu_hcd *oxu, desc->bDescLength = 7 + 2 * temp; /* ports removable, and usb 1.0 legacy PortPwrCtrlMask */ - memset(&desc->DeviceRemovable[0], 0, temp); - memset(&desc->DeviceRemovable[temp], 0xff, temp); + memset(&desc->u.hs.DeviceRemovable[0], 0, temp); + memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); temp = 0x0008; /* per-port overcurrent reporting */ if (HCS_PPC(oxu->hcs_params)) diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 98afe75500cc..db6f8b9c19b6 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -2150,8 +2150,9 @@ static void r8a66597_hub_descriptor(struct r8a66597 *r8a66597, desc->bDescLength = 9; desc->bPwrOn2PwrGood = 0; desc->wHubCharacteristics = cpu_to_le16(0x0011); - desc->DeviceRemovable[0] = ((1 << r8a66597->max_root_hub) - 1) << 1; - desc->DeviceRemovable[1] = ~0; + desc->u.hs.DeviceRemovable[0] = + ((1 << r8a66597->max_root_hub) - 1) << 1; + desc->u.hs.DeviceRemovable[1] = ~0; } static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index f3899b334c73..18b7099a8125 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -1112,8 +1112,8 @@ sl811h_hub_descriptor ( desc->wHubCharacteristics = cpu_to_le16(temp); /* ports removable, and legacy PortPwrCtrlMask */ - desc->DeviceRemovable[0] = 0 << 1; - desc->DeviceRemovable[1] = ~0; + desc->u.hs.DeviceRemovable[0] = 0 << 1; + desc->u.hs.DeviceRemovable[1] = ~0; } static void diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index a659e1590bca..b4785934e091 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -2604,13 +2604,14 @@ static int u132_roothub_descriptor(struct u132 *u132, retval = u132_read_pcimem(u132, roothub.b, &rh_b); if (retval) return retval; - memset(desc->DeviceRemovable, 0xff, sizeof(desc->DeviceRemovable)); - desc->DeviceRemovable[0] = rh_b & RH_B_DR; + memset(desc->u.hs.DeviceRemovable, 0xff, + sizeof(desc->u.hs.DeviceRemovable)); + desc->u.hs.DeviceRemovable[0] = rh_b & RH_B_DR; if (u132->num_ports > 7) { - desc->DeviceRemovable[1] = (rh_b & RH_B_DR) >> 8; - desc->DeviceRemovable[2] = 0xff; + desc->u.hs.DeviceRemovable[1] = (rh_b & RH_B_DR) >> 8; + desc->u.hs.DeviceRemovable[2] = 0xff; } else - desc->DeviceRemovable[1] = 0xff; + desc->u.hs.DeviceRemovable[1] = 0xff; return 0; } diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 43e0a099d634..847b071b6fc9 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -45,8 +45,8 @@ static void xhci_hub_descriptor(struct xhci_hcd *xhci, temp = 1 + (ports / 8); desc->bDescLength = 7 + 2 * temp; - memset(&desc->DeviceRemovable[0], 0, temp); - memset(&desc->DeviceRemovable[temp], 0xff, temp); + memset(&desc->u.hs.DeviceRemovable[0], 0, temp); + memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); /* Ugh, these should be #defines, FIXME */ /* Using table 11-13 in USB 2.0 spec. */ diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index b46d1877e28e..489104a5ae14 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c @@ -305,8 +305,8 @@ int musb_hub_control( desc->bHubContrCurrent = 0; /* workaround bogus struct definition */ - desc->DeviceRemovable[0] = 0x02; /* port 1 */ - desc->DeviceRemovable[1] = 0xff; + desc->u.hs.DeviceRemovable[0] = 0x02; /* port 1 */ + desc->u.hs.DeviceRemovable[1] = 0xff; } break; case GetHubStatus: diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c index cff246b7cb26..c175b7300c73 100644 --- a/drivers/usb/wusbcore/rh.c +++ b/drivers/usb/wusbcore/rh.c @@ -184,8 +184,8 @@ static int wusbhc_rh_get_hub_descr(struct wusbhc *wusbhc, u16 wValue, descr->bPwrOn2PwrGood = 0; descr->bHubContrCurrent = 0; /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */ - memset(&descr->DeviceRemovable[0], 0, temp); - memset(&descr->DeviceRemovable[temp], 0xff, temp); + memset(&descr->u.hs.DeviceRemovable[0], 0, temp); + memset(&descr->u.hs.DeviceRemovable[temp], 0xff, temp); return 0; } diff --git a/include/linux/usb/ch11.h b/include/linux/usb/ch11.h index 38c42b013641..22afcd37bc3f 100644 --- a/include/linux/usb/ch11.h +++ b/include/linux/usb/ch11.h @@ -26,6 +26,7 @@ #define HUB_RESET_TT 9 #define HUB_GET_TT_STATE 10 #define HUB_STOP_TT 11 +#define HUB_SET_DEPTH 12 /* * Hub class additional requests defined by USB 3.0 spec @@ -61,6 +62,12 @@ #define USB_PORT_FEAT_TEST 21 #define USB_PORT_FEAT_INDICATOR 22 #define USB_PORT_FEAT_C_PORT_L1 23 +#define USB_PORT_FEAT_C_PORT_LINK_STATE 25 +#define USB_PORT_FEAT_C_PORT_CONFIG_ERROR 26 +#define USB_PORT_FEAT_PORT_REMOTE_WAKE_MASK 27 +#define USB_PORT_FEAT_BH_PORT_RESET 28 +#define USB_PORT_FEAT_C_BH_PORT_RESET 29 +#define USB_PORT_FEAT_FORCE_LINKPM_ACCEPT 30 /* * Port feature selectors added by USB 3.0 spec. @@ -110,8 +117,14 @@ struct usb_port_status { */ #define USB_PORT_STAT_LINK_STATE 0x01e0 #define USB_SS_PORT_STAT_POWER 0x0200 +#define USB_SS_PORT_STAT_SPEED 0x1c00 #define USB_PORT_STAT_SPEED_5GBPS 0x0000 /* Valid only if port is enabled */ +/* Bits that are the same from USB 2.0 */ +#define USB_SS_PORT_STAT_MASK (USB_PORT_STAT_CONNECTION | \ + USB_PORT_STAT_ENABLE | \ + USB_PORT_STAT_OVERCURRENT | \ + USB_PORT_STAT_RESET) /* * Definitions for PORT_LINK_STATE values @@ -141,6 +154,13 @@ struct usb_port_status { #define USB_PORT_STAT_C_OVERCURRENT 0x0008 #define USB_PORT_STAT_C_RESET 0x0010 #define USB_PORT_STAT_C_L1 0x0020 +/* + * USB 3.0 wPortChange bit fields + * See USB 3.0 spec Table 10-11 + */ +#define USB_PORT_STAT_C_BH_RESET 0x0020 +#define USB_PORT_STAT_C_LINK_STATE 0x0040 +#define USB_PORT_STAT_C_CONFIG_ERROR 0x0080 /* * wHubCharacteristics (masks) @@ -175,7 +195,9 @@ struct usb_hub_status { */ #define USB_DT_HUB (USB_TYPE_CLASS | 0x09) +#define USB_DT_SS_HUB (USB_TYPE_CLASS | 0x0a) #define USB_DT_HUB_NONVAR_SIZE 7 +#define USB_DT_SS_HUB_SIZE 12 struct usb_hub_descriptor { __u8 bDescLength; @@ -184,11 +206,22 @@ struct usb_hub_descriptor { __le16 wHubCharacteristics; __u8 bPwrOn2PwrGood; __u8 bHubContrCurrent; - /* add 1 bit for hub status change; round to bytes */ - __u8 DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8]; - __u8 PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8]; -} __attribute__ ((packed)); + /* 2.0 and 3.0 hubs differ here */ + union { + struct { + /* add 1 bit for hub status change; round to bytes */ + __u8 DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8]; + __u8 PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8]; + } __attribute__ ((packed)) hs; + + struct { + __u8 bHubHdrDecLat; + __u16 wHubDelay; + __u16 DeviceRemovable; + } __attribute__ ((packed)) ss; + } u; +} __attribute__ ((packed)); /* port indicator status selectors, tables 11-7 and 11-25 */ #define HUB_LED_AUTO 0 -- cgit v1.2.3 From c70615740996823580bb8fb58461347b7ffaad9a Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Mon, 6 Dec 2010 15:08:20 -0800 Subject: USB: Clear "warm" port reset change. In USB 3.0, there are two types of resets: a "hot" port reset and a "warm" port reset. The hot port reset is always tried first, and involves sending the reset signaling for a shorter amount of time. But sometimes devices don't respond to the hot reset, and a "Bigger Hammer" is needed. External hubs and roothubs will automatically try a warm reset when the hot reset fails, and they will set a status change bit to indicate when there is a "BH reset" change. Make sure the USB core clears that port status change bit, or we'll get lots of status change notifications on the interrupt endpoint of the USB 3.0 hub. (Side note: you may be confused why the USB 3.0 spec calls the same type of reset "warm reset" in some places and "BH reset" in other places. "BH" reset is supposed to stand for "Big Hammer" reset, but it also stands for "Brad Hosler". Brad died shortly after the USB 3.0 bus specification was started, and they decided to name the reset after him. The suggestion was made shortly before the spec was finalized, so the wording is a bit inconsistent.) Signed-off-by: Sarah Sharp --- drivers/usb/core/hub.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index feb6e596c7c9..0eb27006f846 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3476,6 +3476,14 @@ static void hub_events(void) clear_port_feature(hdev, i, USB_PORT_FEAT_C_RESET); } + if ((portchange & USB_PORT_STAT_C_BH_RESET) && + hub_is_superspeed(hub->hdev)) { + dev_dbg(hub_dev, + "warm reset change on port %d\n", + i); + clear_port_feature(hdev, i, + USB_PORT_FEAT_C_BH_PORT_RESET); + } if (portchange & USB_PORT_STAT_C_LINK_STATE) { clear_port_feature(hub->hdev, i, USB_PORT_FEAT_C_PORT_LINK_STATE); -- cgit v1.2.3 From 22c6a35d41f71b5b40ba8debcb8bd4e8e291ae43 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Mon, 13 Sep 2010 12:01:02 -0700 Subject: usb: Make USB 3.0 roothub have a SS EP comp descriptor. Make the USB 3.0 roothub registered by the USB core have a SuperSpeed Endpoint Companion Descriptor after the interrupt endpoint. All USB 3.0 devices are required to have this, and the USB 3.0 bus specification (section 10.13.1) says which values the descriptor should have. Signed-off-by: Sarah Sharp --- drivers/usb/core/hcd.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index a97ed6d293e9..93c0b92ae402 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -297,7 +297,7 @@ static const u8 ss_rh_config_descriptor[] = { /* one configuration */ 0x09, /* __u8 bLength; */ 0x02, /* __u8 bDescriptorType; Configuration */ - 0x19, 0x00, /* __le16 wTotalLength; FIXME */ + 0x1f, 0x00, /* __le16 wTotalLength; */ 0x01, /* __u8 bNumInterfaces; (1) */ 0x01, /* __u8 bConfigurationValue; */ 0x00, /* __u8 iConfiguration; */ @@ -327,11 +327,14 @@ static const u8 ss_rh_config_descriptor[] = { /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) * see hub.c:hub_configure() for details. */ (USB_MAXCHILDREN + 1 + 7) / 8, 0x00, - 0x0c /* __u8 ep_bInterval; (256ms -- usb 2.0 spec) */ - /* - * All 3.0 hubs should have an endpoint companion descriptor, - * but we're ignoring that for now. FIXME? - */ + 0x0c, /* __u8 ep_bInterval; (256ms -- usb 2.0 spec) */ + + /* one SuperSpeed endpoint companion descriptor */ + 0x06, /* __u8 ss_bLength */ + 0x30, /* __u8 ss_bDescriptorType; SuperSpeed EP Companion */ + 0x00, /* __u8 ss_bMaxBurst; allows 1 TX between ACKs */ + 0x00, /* __u8 ss_bmAttributes; 1 packet per service interval */ + 0x02, 0x00 /* __le16 ss_wBytesPerInterval; 15 bits for max 15 ports */ }; /*-------------------------------------------------------------------------*/ -- cgit v1.2.3 From aa1b13efb7cfa9f7bf4942c1e858463e335c9500 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 3 Mar 2011 05:40:51 -0800 Subject: xhci: Modify check for TT info. Commit d199c96d by Alan Stern ensured that low speed and full speed devices below a high speed hub without a transaction translator (TT) would never get enumerated. Simplify the check for a TT in the xHCI virtual device allocation to only check if the usb_device references a parent's TT. Make sure not to set the TT information on LS/FS devices directly connected to the roothub. The xHCI host doesn't really have a TT, and the host will throw an error when those virtual device TT fields are set for a device connected to the roothub. We need this check because the xHCI driver will shortly register two roothubs: a USB 2.0 roothub and a USB 3.0 roothub. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-mem.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index e3e6410d7b5e..9688a58611d4 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -870,9 +870,8 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud dev->port = top_dev->portnum; xhci_dbg(xhci, "Set root hub portnum to %d\n", top_dev->portnum); - /* Is this a LS/FS device under a HS hub? */ - if ((udev->speed == USB_SPEED_LOW || udev->speed == USB_SPEED_FULL) && - udev->tt) { + /* Is this a LS/FS device under an external HS hub? */ + if (udev->tt && udev->tt->hub->parent) { slot_ctx->tt_info = udev->tt->hub->slot_id; slot_ctx->tt_info |= udev->ttport << 8; if (udev->tt->multi) -- cgit v1.2.3 From 214f76f7d9198ddd090bd927a4bcd49391bfcd36 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Tue, 26 Oct 2010 11:22:02 -0700 Subject: xhci: Always use usb_hcd in URB instead of converting xhci_hcd. Make sure to call into the USB core's link, unlink, and giveback URB functions with the usb_hcd pointer found by using urb->dev->bus. This will avoid confusion later, when the xHCI driver will deal with URBs from two separate buses (the USB 3.0 roothub and the faked USB 2.0 roothub). Assume xhci_urb_dequeue() will be called with the proper usb_hcd. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-ring.c | 9 +++++---- drivers/usb/host/xhci.c | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 6bca2526d54a..9e2b26c3da40 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -594,13 +594,14 @@ static inline void xhci_stop_watchdog_timer_in_irq(struct xhci_hcd *xhci, static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci, struct xhci_td *cur_td, int status, char *adjective) { - struct usb_hcd *hcd = xhci_to_hcd(xhci); + struct usb_hcd *hcd; struct urb *urb; struct urb_priv *urb_priv; urb = cur_td->urb; urb_priv = urb->hcpriv; urb_priv->td_cnt++; + hcd = bus_to_hcd(urb->dev->bus); /* Only giveback urb when this is the last td in urb */ if (urb_priv->td_cnt == urb_priv->length) { @@ -1982,12 +1983,12 @@ cleanup: trb_comp_code != COMP_BABBLE)) xhci_urb_free_priv(xhci, urb_priv); - usb_hcd_unlink_urb_from_ep(xhci_to_hcd(xhci), urb); + usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); xhci_dbg(xhci, "Giveback URB %p, len = %d, " "status = %d\n", urb, urb->actual_length, status); spin_unlock(&xhci->lock); - usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, status); + usb_hcd_giveback_urb(bus_to_hcd(urb->dev->bus), urb, status); spin_lock(&xhci->lock); } @@ -2323,7 +2324,7 @@ static int prepare_transfer(struct xhci_hcd *xhci, INIT_LIST_HEAD(&td->cancelled_td_list); if (td_index == 0) { - ret = usb_hcd_link_urb_to_ep(xhci_to_hcd(xhci), urb); + ret = usb_hcd_link_urb_to_ep(bus_to_hcd(urb->dev->bus), urb); if (unlikely(ret)) { xhci_urb_free_priv(xhci, urb_priv); urb->hcpriv = NULL; diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 883b4c402c6a..a95108cba7d4 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1154,7 +1154,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) usb_hcd_unlink_urb_from_ep(hcd, urb); spin_unlock_irqrestore(&xhci->lock, flags); - usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, -ESHUTDOWN); + usb_hcd_giveback_urb(hcd, urb, -ESHUTDOWN); xhci_urb_free_priv(xhci, urb_priv); return ret; } -- cgit v1.2.3 From b02d0ed677acb3465e7600366f2353413bf24074 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Tue, 26 Oct 2010 11:03:44 -0700 Subject: xhci: Change hcd_priv into a pointer. Instead of allocating space for the whole xhci_hcd structure at the end of usb_hcd, make the USB core allocate enough space for a pointer to the xhci_hcd structure. This will make it easy to share the xhci_hcd structure across the two roothubs (the USB 3.0 usb_hcd and the USB 2.0 usb_hcd). Deallocate the xhci_hcd at PCI remove time, so the hcd_priv will be deallocated after the usb_hcd is deallocated. We do this by registering a different PCI remove function that calls the usb_hcd_pci_remove() function, and then frees the xhci_hcd. usb_hcd_pci_remove() calls kput() on the usb_hcd structure, which will deallocate the memory that contains the hcd_priv pointer, but not the memory it points to. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-pci.c | 33 +++++++++++++++++++++++++++------ drivers/usb/host/xhci.h | 5 +++-- 2 files changed, 30 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index bb668a894ab9..009082829364 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -57,6 +57,12 @@ static int xhci_pci_setup(struct usb_hcd *hcd) hcd->self.sg_tablesize = TRBS_PER_SEGMENT - 2; + xhci = kzalloc(sizeof(struct xhci_hcd), GFP_KERNEL); + if (!xhci) + return -ENOMEM; + *((struct xhci_hcd **) hcd->hcd_priv) = xhci; + xhci->main_hcd = hcd; + xhci->cap_regs = hcd->regs; xhci->op_regs = hcd->regs + HC_LENGTH(xhci_readl(xhci, &xhci->cap_regs->hc_capbase)); @@ -85,13 +91,13 @@ static int xhci_pci_setup(struct usb_hcd *hcd) /* Make sure the HC is halted. */ retval = xhci_halt(xhci); if (retval) - return retval; + goto error; xhci_dbg(xhci, "Resetting HCD\n"); /* Reset the internal HC memory state and registers. */ retval = xhci_reset(xhci); if (retval) - return retval; + goto error; xhci_dbg(xhci, "Reset complete\n"); temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params); @@ -106,14 +112,29 @@ static int xhci_pci_setup(struct usb_hcd *hcd) /* Initialize HCD and host controller data structures. */ retval = xhci_init(hcd); if (retval) - return retval; + goto error; xhci_dbg(xhci, "Called HCD init\n"); pci_read_config_byte(pdev, XHCI_SBRN_OFFSET, &xhci->sbrn); xhci_dbg(xhci, "Got SBRN %u\n", (unsigned int) xhci->sbrn); /* Find any debug ports */ - return xhci_pci_reinit(xhci, pdev); + retval = xhci_pci_reinit(xhci, pdev); + if (!retval) + return retval; + +error: + kfree(xhci); + return retval; +} + +static void xhci_pci_remove(struct pci_dev *dev) +{ + struct xhci_hcd *xhci; + + xhci = hcd_to_xhci(pci_get_drvdata(dev)); + usb_hcd_pci_remove(dev); + kfree(xhci); } #ifdef CONFIG_PM @@ -143,7 +164,7 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) static const struct hc_driver xhci_pci_hc_driver = { .description = hcd_name, .product_desc = "xHCI Host Controller", - .hcd_priv_size = sizeof(struct xhci_hcd), + .hcd_priv_size = sizeof(struct xhci_hcd *), /* * generic hardware linkage @@ -211,7 +232,7 @@ static struct pci_driver xhci_pci_driver = { .id_table = pci_ids, .probe = usb_hcd_pci_probe, - .remove = usb_hcd_pci_remove, + .remove = xhci_pci_remove, /* suspend and resume implemented later */ .shutdown = usb_hcd_pci_shutdown, diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index c4e70c6d809c..daa88581ad66 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1163,6 +1163,7 @@ struct s3_save { /* There is one ehci_hci structure per controller */ struct xhci_hcd { + struct usb_hcd *main_hcd; /* glue to PCI and HCD framework */ struct xhci_cap_regs __iomem *cap_regs; struct xhci_op_regs __iomem *op_regs; @@ -1266,12 +1267,12 @@ struct xhci_hcd { /* convert between an HCD pointer and the corresponding EHCI_HCD */ static inline struct xhci_hcd *hcd_to_xhci(struct usb_hcd *hcd) { - return (struct xhci_hcd *) (hcd->hcd_priv); + return *((struct xhci_hcd **) (hcd->hcd_priv)); } static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci) { - return container_of((void *) xhci, struct usb_hcd, hcd_priv); + return xhci->main_hcd; } #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING -- cgit v1.2.3 From 8766c815607e572556b04075d4545330123c4f27 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 15 Oct 2010 10:33:48 -0700 Subject: usb: Make usb_hcd_pci_probe labels more descriptive. Make the labels for the goto statements in usb_hcd_pci_probe() describe the cleanup they do, rather than being numbered err[1-4]. This makes it easier to add error handling later. The error handling for this function looks a little fishy, since set_hs_companion() isn't called until the very end of the function, and clear_hs_companion() is called if this function fails earlier than that. But it should be harmless to clear a NULL pointer, so leave the error handling as-is. Signed-off-by: Sarah Sharp --- drivers/usb/core/hcd-pci.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index d37088591d9a..88d9109b4b45 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -192,13 +192,13 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", pci_name(dev)); retval = -ENODEV; - goto err1; + goto disable_pci; } hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev)); if (!hcd) { retval = -ENOMEM; - goto err1; + goto disable_pci; } if (driver->flags & HCD_MEMORY) { @@ -209,13 +209,13 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) driver->description)) { dev_dbg(&dev->dev, "controller already in use\n"); retval = -EBUSY; - goto err2; + goto clear_companion; } hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); if (hcd->regs == NULL) { dev_dbg(&dev->dev, "error mapping memory\n"); retval = -EFAULT; - goto err3; + goto release_mem_region; } } else { @@ -236,7 +236,7 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) if (region == PCI_ROM_RESOURCE) { dev_dbg(&dev->dev, "no i/o regions available\n"); retval = -EBUSY; - goto err2; + goto clear_companion; } } @@ -244,24 +244,24 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) retval = usb_add_hcd(hcd, dev->irq, IRQF_DISABLED | IRQF_SHARED); if (retval != 0) - goto err4; + goto unmap_registers; set_hs_companion(dev, hcd); if (pci_dev_run_wake(dev)) pm_runtime_put_noidle(&dev->dev); return retval; - err4: +unmap_registers: if (driver->flags & HCD_MEMORY) { iounmap(hcd->regs); - err3: +release_mem_region: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); } else release_region(hcd->rsrc_start, hcd->rsrc_len); - err2: +clear_companion: clear_hs_companion(dev, hcd); usb_put_hcd(hcd); - err1: +disable_pci: pci_disable_device(dev); dev_err(&dev->dev, "init %s fail, %d\n", pci_name(dev), retval); return retval; -- cgit v1.2.3 From 23e0d1066f429ab44305e96fbff13f1793886277 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 21 Oct 2010 11:14:54 -0700 Subject: usb: Refactor irq enabling out of usb_add_hcd() Refactor out the code in usb_add_hcd() to request the IRQ line for the HCD. This will only need to be called once for the two xHCI roothubs, so it's easier to refactor it into a function, rather than wrapping the long if-else block into another if statement. Signed-off-by: Sarah Sharp --- drivers/usb/core/hcd.c | 75 +++++++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 93c0b92ae402..40c7a46ba7d3 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2236,6 +2236,46 @@ void usb_put_hcd (struct usb_hcd *hcd) } EXPORT_SYMBOL_GPL(usb_put_hcd); +static int usb_hcd_request_irqs(struct usb_hcd *hcd, + unsigned int irqnum, unsigned long irqflags) +{ + int retval; + + if (hcd->driver->irq) { + + /* IRQF_DISABLED doesn't work as advertised when used together + * with IRQF_SHARED. As usb_hcd_irq() will always disable + * interrupts we can remove it here. + */ + if (irqflags & IRQF_SHARED) + irqflags &= ~IRQF_DISABLED; + + snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", + hcd->driver->description, hcd->self.busnum); + retval = request_irq(irqnum, &usb_hcd_irq, irqflags, + hcd->irq_descr, hcd); + if (retval != 0) { + dev_err(hcd->self.controller, + "request interrupt %d failed\n", + irqnum); + return retval; + } + hcd->irq = irqnum; + dev_info(hcd->self.controller, "irq %d, %s 0x%08llx\n", irqnum, + (hcd->driver->flags & HCD_MEMORY) ? + "io mem" : "io base", + (unsigned long long)hcd->rsrc_start); + } else { + hcd->irq = -1; + if (hcd->rsrc_start) + dev_info(hcd->self.controller, "%s 0x%08llx\n", + (hcd->driver->flags & HCD_MEMORY) ? + "io mem" : "io base", + (unsigned long long)hcd->rsrc_start); + } + return 0; +} + /** * usb_add_hcd - finish generic HCD structure initialization and register * @hcd: the usb_hcd structure to initialize @@ -2317,38 +2357,9 @@ int usb_add_hcd(struct usb_hcd *hcd, dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); /* enable irqs just before we start the controller */ - if (hcd->driver->irq) { - - /* IRQF_DISABLED doesn't work as advertised when used together - * with IRQF_SHARED. As usb_hcd_irq() will always disable - * interrupts we can remove it here. - */ - if (irqflags & IRQF_SHARED) - irqflags &= ~IRQF_DISABLED; - - snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", - hcd->driver->description, hcd->self.busnum); - retval = request_irq(irqnum, &usb_hcd_irq, irqflags, - hcd->irq_descr, hcd); - if (retval != 0) { - dev_err(hcd->self.controller, - "request interrupt %d failed\n", - irqnum); - goto err_request_irq; - } - hcd->irq = irqnum; - dev_info(hcd->self.controller, "irq %d, %s 0x%08llx\n", irqnum, - (hcd->driver->flags & HCD_MEMORY) ? - "io mem" : "io base", - (unsigned long long)hcd->rsrc_start); - } else { - hcd->irq = -1; - if (hcd->rsrc_start) - dev_info(hcd->self.controller, "%s 0x%08llx\n", - (hcd->driver->flags & HCD_MEMORY) ? - "io mem" : "io base", - (unsigned long long)hcd->rsrc_start); - } + retval = usb_hcd_request_irqs(hcd, irqnum, irqflags); + if (retval) + goto err_request_irq; hcd->state = HC_STATE_RUNNING; retval = hcd->driver->start(hcd); -- cgit v1.2.3 From d673bfcbfffdeb56064a6b1ee047b85590bed76c Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 15 Oct 2010 08:55:24 -0700 Subject: usb: Change usb_hcd->bandwidth_mutex to a pointer. Change the bandwith_mutex in struct usb_hcd to a pointer. This will allow the pointer to be shared across usb_hcds for the upcoming work to split the xHCI driver roothub into a USB 2.0/1.1 and a USB 3.0 bus. Signed-off-by: Sarah Sharp --- drivers/usb/core/hcd.c | 11 ++++++++++- drivers/usb/core/hub.c | 8 ++++---- drivers/usb/core/message.c | 22 +++++++++++----------- include/linux/usb/hcd.h | 2 +- 4 files changed, 26 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 40c7a46ba7d3..3ba27118adc5 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2191,6 +2191,15 @@ struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, dev_dbg (dev, "hcd alloc failed\n"); return NULL; } + hcd->bandwidth_mutex = kmalloc(sizeof(*hcd->bandwidth_mutex), + GFP_KERNEL); + if (!hcd->bandwidth_mutex) { + kfree(hcd); + dev_dbg(dev, "hcd bandwidth mutex alloc failed\n"); + return NULL; + } + mutex_init(hcd->bandwidth_mutex); + dev_set_drvdata(dev, hcd); kref_init(&hcd->kref); @@ -2205,7 +2214,6 @@ struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, #ifdef CONFIG_USB_SUSPEND INIT_WORK(&hcd->wakeup_work, hcd_resume_work); #endif - mutex_init(&hcd->bandwidth_mutex); hcd->driver = driver; hcd->product_desc = (driver->product_desc) ? driver->product_desc : @@ -2218,6 +2226,7 @@ static void hcd_release (struct kref *kref) { struct usb_hcd *hcd = container_of (kref, struct usb_hcd, kref); + kfree(hcd->bandwidth_mutex); kfree(hcd); } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 0eb27006f846..825d803720b3 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3776,13 +3776,13 @@ static int usb_reset_and_verify_device(struct usb_device *udev) if (!udev->actconfig) goto done; - mutex_lock(&hcd->bandwidth_mutex); + mutex_lock(hcd->bandwidth_mutex); ret = usb_hcd_alloc_bandwidth(udev, udev->actconfig, NULL, NULL); if (ret < 0) { dev_warn(&udev->dev, "Busted HC? Not enough HCD resources for " "old configuration.\n"); - mutex_unlock(&hcd->bandwidth_mutex); + mutex_unlock(hcd->bandwidth_mutex); goto re_enumerate; } ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), @@ -3793,10 +3793,10 @@ static int usb_reset_and_verify_device(struct usb_device *udev) dev_err(&udev->dev, "can't restore configuration #%d (error=%d)\n", udev->actconfig->desc.bConfigurationValue, ret); - mutex_unlock(&hcd->bandwidth_mutex); + mutex_unlock(hcd->bandwidth_mutex); goto re_enumerate; } - mutex_unlock(&hcd->bandwidth_mutex); + mutex_unlock(hcd->bandwidth_mutex); usb_set_device_state(udev, USB_STATE_CONFIGURED); /* Put interfaces back into the same altsettings as before. diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 832487423826..5701e857392b 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1284,12 +1284,12 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) /* Make sure we have enough bandwidth for this alternate interface. * Remove the current alt setting and add the new alt setting. */ - mutex_lock(&hcd->bandwidth_mutex); + mutex_lock(hcd->bandwidth_mutex); ret = usb_hcd_alloc_bandwidth(dev, NULL, iface->cur_altsetting, alt); if (ret < 0) { dev_info(&dev->dev, "Not enough bandwidth for altsetting %d\n", alternate); - mutex_unlock(&hcd->bandwidth_mutex); + mutex_unlock(hcd->bandwidth_mutex); return ret; } @@ -1311,10 +1311,10 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) } else if (ret < 0) { /* Re-instate the old alt setting */ usb_hcd_alloc_bandwidth(dev, NULL, alt, iface->cur_altsetting); - mutex_unlock(&hcd->bandwidth_mutex); + mutex_unlock(hcd->bandwidth_mutex); return ret; } - mutex_unlock(&hcd->bandwidth_mutex); + mutex_unlock(hcd->bandwidth_mutex); /* FIXME drivers shouldn't need to replicate/bugfix the logic here * when they implement async or easily-killable versions of this or @@ -1413,7 +1413,7 @@ int usb_reset_configuration(struct usb_device *dev) config = dev->actconfig; retval = 0; - mutex_lock(&hcd->bandwidth_mutex); + mutex_lock(hcd->bandwidth_mutex); /* Make sure we have enough bandwidth for each alternate setting 0 */ for (i = 0; i < config->desc.bNumInterfaces; i++) { struct usb_interface *intf = config->interface[i]; @@ -1442,7 +1442,7 @@ reset_old_alts: usb_hcd_alloc_bandwidth(dev, NULL, alt, intf->cur_altsetting); } - mutex_unlock(&hcd->bandwidth_mutex); + mutex_unlock(hcd->bandwidth_mutex); return retval; } retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), @@ -1451,7 +1451,7 @@ reset_old_alts: NULL, 0, USB_CTRL_SET_TIMEOUT); if (retval < 0) goto reset_old_alts; - mutex_unlock(&hcd->bandwidth_mutex); + mutex_unlock(hcd->bandwidth_mutex); /* re-init hc/hcd interface/endpoint state */ for (i = 0; i < config->desc.bNumInterfaces; i++) { @@ -1739,10 +1739,10 @@ free_interfaces: * host controller will not allow submissions to dropped endpoints. If * this call fails, the device state is unchanged. */ - mutex_lock(&hcd->bandwidth_mutex); + mutex_lock(hcd->bandwidth_mutex); ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); if (ret < 0) { - mutex_unlock(&hcd->bandwidth_mutex); + mutex_unlock(hcd->bandwidth_mutex); usb_autosuspend_device(dev); goto free_interfaces; } @@ -1761,11 +1761,11 @@ free_interfaces: if (!cp) { usb_set_device_state(dev, USB_STATE_ADDRESS); usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); - mutex_unlock(&hcd->bandwidth_mutex); + mutex_unlock(hcd->bandwidth_mutex); usb_autosuspend_device(dev); goto free_interfaces; } - mutex_unlock(&hcd->bandwidth_mutex); + mutex_unlock(hcd->bandwidth_mutex); usb_set_device_state(dev, USB_STATE_CONFIGURED); /* Initialize the new interface structures and the diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 0be61970074e..836aaa91ee15 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -142,7 +142,7 @@ struct usb_hcd { * bandwidth_mutex should be dropped after a successful control message * to the device, or resetting the bandwidth after a failed attempt. */ - struct mutex bandwidth_mutex; + struct mutex *bandwidth_mutex; #define HCD_BUFFER_POOLS 4 -- cgit v1.2.3 From 83de4b2b90887b5b317d8313864fe4cc5db35280 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 2 Dec 2010 14:45:18 -0800 Subject: usb: Store bus type in usb_hcd, not in driver flags. The xHCI driver essentially has both a USB 2.0 and a USB 3.0 roothub. So setting the HCD_USB3 bits in the hcd->driver->flags is a bit misleading. Add a new field to usb_hcd, bcdUSB. Store the result of hcd->driver->flags & HCD_MASK in it. Later, when we have the xHCI driver register the two roothubs, we'll set the usb_hcd->bcdUSB field to HCD_USB2 for the USB 2.0 roothub, and HCD_USB3 for the USB 3.0 roothub. Signed-off-by: Sarah Sharp --- drivers/usb/core/hcd.c | 7 ++++--- include/linux/usb/hcd.h | 4 ++++ 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 3ba27118adc5..a0adcac3da08 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -507,7 +507,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) case DeviceRequest | USB_REQ_GET_DESCRIPTOR: switch (wValue & 0xff00) { case USB_DT_DEVICE << 8: - switch (hcd->driver->flags & HCD_MASK) { + switch (hcd->speed) { case HCD_USB3: bufp = usb3_rh_dev_descriptor; break; @@ -525,7 +525,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) patch_protocol = 1; break; case USB_DT_CONFIG << 8: - switch (hcd->driver->flags & HCD_MASK) { + switch (hcd->speed) { case HCD_USB3: bufp = ss_rh_config_descriptor; len = sizeof ss_rh_config_descriptor; @@ -2216,6 +2216,7 @@ struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, #endif hcd->driver = driver; + hcd->speed = driver->flags & HCD_MASK; hcd->product_desc = (driver->product_desc) ? driver->product_desc : "USB Host Controller"; return hcd; @@ -2325,7 +2326,7 @@ int usb_add_hcd(struct usb_hcd *hcd, } hcd->self.root_hub = rhdev; - switch (hcd->driver->flags & HCD_MASK) { + switch (hcd->speed) { case HCD_USB11: rhdev->speed = USB_SPEED_FULL; break; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 836aaa91ee15..b8bb6934f30b 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -76,6 +76,10 @@ struct usb_hcd { struct kref kref; /* reference counter */ const char *product_desc; /* product/vendor string */ + int speed; /* Speed for this roothub. + * May be different from + * hcd->driver->flags & HCD_MASK + */ char irq_descr[24]; /* driver + bus # */ struct timer_list rh_timer; /* drives root-hub polling */ -- cgit v1.2.3 From c56354378426e550aaf6ddf3983f502a8fddeab5 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 28 Oct 2010 15:40:26 -0700 Subject: usb: Make core allocate resources per PCI-device. Introduce the notion of a PCI device that may be associated with more than one USB host controller driver (struct usb_hcd). This patch is the start of the work to separate the xHCI host controller into two roothubs: a USB 3.0 roothub with SuperSpeed-only ports, and a USB 2.0 roothub with HS/FS/LS ports. One usb_hcd structure is designated to be the "primary HCD", and a pointer is added to the usb_hcd structure to keep track of that. A new function call, usb_hcd_is_primary_hcd() is added to check whether the USB hcd is marked as the primary HCD (or if it is not part of a roothub pair). To allow the USB core and xHCI driver to access either roothub in a pair, a "shared_hcd" pointer is added to the usb_hcd structure. Add a new function, usb_create_shared_hcd(), that does roothub allocation for paired roothubs. It will act just like usb_create_hcd() did if the primary_hcd pointer argument is NULL. If it is passed a non-NULL primary_hcd pointer, it sets usb_hcd->shared_hcd and usb_hcd->primary_hcd fields. It will also skip the bandwidth_mutex allocation, and set the secondary hcd's bandwidth_mutex pointer to the primary HCD's mutex. IRQs are only allocated once for the primary roothub. Introduce a new usb_hcd driver flag that indicates the host controller driver wants to create two roothubs. If the HCD_SHARED flag is set, then the USB core PCI probe methods will allocate a second roothub, and make sure that second roothub gets freed during rmmod and in initialization error paths. When usb_hc_died() is called with the primary HCD, make sure that any roothubs that share that host controller are also marked as being dead. Signed-off-by: Sarah Sharp --- drivers/usb/core/hcd.c | 108 +++++++++++++++++++++++++++++++++++++++--------- include/linux/usb/hcd.h | 7 ++++ 2 files changed, 96 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index a0adcac3da08..ba15eeab824e 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2143,7 +2143,9 @@ EXPORT_SYMBOL_GPL(usb_hcd_irq); * * This is called by bus glue to report a USB host controller that died * while operations may still have been pending. It's called automatically - * by the PCI glue, so only glue for non-PCI busses should need to call it. + * by the PCI glue, so only glue for non-PCI busses should need to call it. + * + * Only call this function with the primary HCD. */ void usb_hc_died (struct usb_hcd *hcd) { @@ -2162,17 +2164,31 @@ void usb_hc_died (struct usb_hcd *hcd) USB_STATE_NOTATTACHED); usb_kick_khubd (hcd->self.root_hub); } + if (usb_hcd_is_primary_hcd(hcd) && hcd->shared_hcd) { + hcd = hcd->shared_hcd; + if (hcd->rh_registered) { + clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); + + /* make khubd clean up old urbs and devices */ + usb_set_device_state(hcd->self.root_hub, + USB_STATE_NOTATTACHED); + usb_kick_khubd(hcd->self.root_hub); + } + } spin_unlock_irqrestore (&hcd_root_hub_lock, flags); + /* Make sure that the other roothub is also deallocated. */ } EXPORT_SYMBOL_GPL (usb_hc_died); /*-------------------------------------------------------------------------*/ /** - * usb_create_hcd - create and initialize an HCD structure + * usb_create_shared_hcd - create and initialize an HCD structure * @driver: HC driver that will use this hcd * @dev: device for this HC, stored in hcd->self.controller * @bus_name: value to store in hcd->self.bus_name + * @primary_hcd: a pointer to the usb_hcd structure that is sharing the + * PCI device. Only allocate certain resources for the primary HCD * Context: !in_interrupt() * * Allocate a struct usb_hcd, with extra space at the end for the @@ -2181,8 +2197,9 @@ EXPORT_SYMBOL_GPL (usb_hc_died); * * If memory is unavailable, returns NULL. */ -struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, - struct device *dev, const char *bus_name) +struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver, + struct device *dev, const char *bus_name, + struct usb_hcd *primary_hcd) { struct usb_hcd *hcd; @@ -2191,16 +2208,24 @@ struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, dev_dbg (dev, "hcd alloc failed\n"); return NULL; } - hcd->bandwidth_mutex = kmalloc(sizeof(*hcd->bandwidth_mutex), - GFP_KERNEL); - if (!hcd->bandwidth_mutex) { - kfree(hcd); - dev_dbg(dev, "hcd bandwidth mutex alloc failed\n"); - return NULL; + if (primary_hcd == NULL) { + hcd->bandwidth_mutex = kmalloc(sizeof(*hcd->bandwidth_mutex), + GFP_KERNEL); + if (!hcd->bandwidth_mutex) { + kfree(hcd); + dev_dbg(dev, "hcd bandwidth mutex alloc failed\n"); + return NULL; + } + mutex_init(hcd->bandwidth_mutex); + dev_set_drvdata(dev, hcd); + } else { + hcd->bandwidth_mutex = primary_hcd->bandwidth_mutex; + hcd->primary_hcd = primary_hcd; + primary_hcd->primary_hcd = primary_hcd; + hcd->shared_hcd = primary_hcd; + primary_hcd->shared_hcd = hcd; } - mutex_init(hcd->bandwidth_mutex); - dev_set_drvdata(dev, hcd); kref_init(&hcd->kref); usb_bus_init(&hcd->self); @@ -2221,13 +2246,46 @@ struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, "USB Host Controller"; return hcd; } +EXPORT_SYMBOL_GPL(usb_create_shared_hcd); + +/** + * usb_create_hcd - create and initialize an HCD structure + * @driver: HC driver that will use this hcd + * @dev: device for this HC, stored in hcd->self.controller + * @bus_name: value to store in hcd->self.bus_name + * Context: !in_interrupt() + * + * Allocate a struct usb_hcd, with extra space at the end for the + * HC driver's private data. Initialize the generic members of the + * hcd structure. + * + * If memory is unavailable, returns NULL. + */ +struct usb_hcd *usb_create_hcd(const struct hc_driver *driver, + struct device *dev, const char *bus_name) +{ + return usb_create_shared_hcd(driver, dev, bus_name, NULL); +} EXPORT_SYMBOL_GPL(usb_create_hcd); +/* + * Roothubs that share one PCI device must also share the bandwidth mutex. + * Don't deallocate the bandwidth_mutex until the last shared usb_hcd is + * deallocated. + * + * Make sure to only deallocate the bandwidth_mutex when the primary HCD is + * freed. When hcd_release() is called for the non-primary HCD, set the + * primary_hcd's shared_hcd pointer to null (since the non-primary HCD will be + * freed shortly). + */ static void hcd_release (struct kref *kref) { struct usb_hcd *hcd = container_of (kref, struct usb_hcd, kref); - kfree(hcd->bandwidth_mutex); + if (usb_hcd_is_primary_hcd(hcd)) + kfree(hcd->bandwidth_mutex); + else + hcd->shared_hcd->shared_hcd = NULL; kfree(hcd); } @@ -2246,6 +2304,14 @@ void usb_put_hcd (struct usb_hcd *hcd) } EXPORT_SYMBOL_GPL(usb_put_hcd); +int usb_hcd_is_primary_hcd(struct usb_hcd *hcd) +{ + if (!hcd->primary_hcd) + return 1; + return hcd == hcd->primary_hcd; +} +EXPORT_SYMBOL_GPL(usb_hcd_is_primary_hcd); + static int usb_hcd_request_irqs(struct usb_hcd *hcd, unsigned int irqnum, unsigned long irqflags) { @@ -2367,9 +2433,11 @@ int usb_add_hcd(struct usb_hcd *hcd, dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); /* enable irqs just before we start the controller */ - retval = usb_hcd_request_irqs(hcd, irqnum, irqflags); - if (retval) - goto err_request_irq; + if (usb_hcd_is_primary_hcd(hcd)) { + retval = usb_hcd_request_irqs(hcd, irqnum, irqflags); + if (retval) + goto err_request_irq; + } hcd->state = HC_STATE_RUNNING; retval = hcd->driver->start(hcd); @@ -2416,7 +2484,7 @@ err_register_root_hub: clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); del_timer_sync(&hcd->rh_timer); err_hcd_driver_start: - if (hcd->irq >= 0) + if (usb_hcd_is_primary_hcd(hcd) && hcd->irq >= 0) free_irq(irqnum, hcd); err_request_irq: err_hcd_driver_setup: @@ -2480,8 +2548,10 @@ void usb_remove_hcd(struct usb_hcd *hcd) clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); del_timer_sync(&hcd->rh_timer); - if (hcd->irq >= 0) - free_irq(hcd->irq, hcd); + if (usb_hcd_is_primary_hcd(hcd)) { + if (hcd->irq >= 0) + free_irq(hcd->irq, hcd); + } usb_put_dev(hcd->self.root_hub); usb_deregister_bus(&hcd->self); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index b8bb6934f30b..0097136ba45d 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -147,6 +147,8 @@ struct usb_hcd { * to the device, or resetting the bandwidth after a failed attempt. */ struct mutex *bandwidth_mutex; + struct usb_hcd *shared_hcd; + struct usb_hcd *primary_hcd; #define HCD_BUFFER_POOLS 4 @@ -209,6 +211,7 @@ struct hc_driver { int flags; #define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */ #define HCD_LOCAL_MEM 0x0002 /* HC needs local memory */ +#define HCD_SHARED 0x0004 /* Two (or more) usb_hcds share HW */ #define HCD_USB11 0x0010 /* USB 1.1 */ #define HCD_USB2 0x0020 /* USB 2.0 */ #define HCD_USB3 0x0040 /* USB 3.0 */ @@ -370,8 +373,12 @@ extern int usb_hcd_get_frame_number(struct usb_device *udev); extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver, struct device *dev, const char *bus_name); +extern struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver, + struct device *dev, const char *bus_name, + struct usb_hcd *shared_hcd); extern struct usb_hcd *usb_get_hcd(struct usb_hcd *hcd); extern void usb_put_hcd(struct usb_hcd *hcd); +extern int usb_hcd_is_primary_hcd(struct usb_hcd *hcd); extern int usb_add_hcd(struct usb_hcd *hcd, unsigned int irqnum, unsigned long irqflags); extern void usb_remove_hcd(struct usb_hcd *hcd); -- cgit v1.2.3 From ff9d78b36f76687c91c67b9f4c5c33bc888ed2f9 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 2 Dec 2010 19:10:02 -0800 Subject: USB: Set usb_hcd->state and flags for shared roothubs. The hcd->flags are in a sorry state. Some of them are clearly specific to the particular roothub (HCD_POLL_RH, HCD_POLL_PENDING, and HCD_WAKEUP_PENDING), but some flags are related to PCI device state (HCD_HW_ACCESSIBLE and HCD_SAW_IRQ). This is an issue when one PCI device can have two roothubs that share the same IRQ line and hardware. Make sure to set HCD_FLAG_SAW_IRQ for both roothubs when an interrupt is serviced, or an URB is unlinked without an interrupt. (We can't tell if the host actually serviced an interrupt for a particular bus, but we can tell it serviced some interrupt.) HCD_HW_ACCESSIBLE is set once by usb_add_hcd(), which is set for both roothubs as they are added, so it doesn't need to be modified. HCD_POLL_RH and HCD_POLL_PENDING are only checked by the USB core, and they are never set by the xHCI driver, since the roothub never needs to be polled. The usb_hcd's state field is a similar mess. Sometimes the state applies to the underlying hardware: HC_STATE_HALT, HC_STATE_RUNNING, and HC_STATE_QUIESCING. But sometimes the state refers to the roothub state: HC_STATE_RESUMING and HC_STATE_SUSPENDED. Alan Stern recently made the USB core not rely on the hcd->state variable. Internally, the xHCI driver still checks for HC_STATE_SUSPENDED, so leave that code in. Remove all references to HC_STATE_HALT, since the xHCI driver only sets and doesn't test those variables. We still have to set HC_STATE_RUNNING, since Alan's patch has a bug that means the roothub won't get registered if we don't set that. Alan's patch made the USB core check a different variable when trying to determine whether to suspend a roothub. The xHCI host has a split roothub, where two buses are registered for one PCI device. Each bus in the xHCI split roothub can be suspended separately, but both buses must be suspended before the PCI device can be suspended. Therefore, make sure that the USB core checks HCD_RH_RUNNING() for both roothubs before suspending the PCI host. Signed-off-by: Sarah Sharp --- drivers/usb/core/hcd-pci.c | 27 +++++++++++++++++++++++---- drivers/usb/core/hcd.c | 4 ++++ drivers/usb/host/xhci-ring.c | 2 ++ 3 files changed, 29 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 88d9109b4b45..b992a886f05c 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -367,6 +367,13 @@ static int check_root_hub_suspended(struct device *dev) dev_warn(dev, "Root hub is not suspended\n"); return -EBUSY; } + if (hcd->shared_hcd) { + hcd = hcd->shared_hcd; + if (HCD_RH_RUNNING(hcd)) { + dev_warn(dev, "Secondary root hub is not suspended\n"); + return -EBUSY; + } + } return 0; } @@ -391,11 +398,16 @@ static int suspend_common(struct device *dev, bool do_wakeup) */ if (do_wakeup && HCD_WAKEUP_PENDING(hcd)) return -EBUSY; + if (do_wakeup && hcd->shared_hcd && + HCD_WAKEUP_PENDING(hcd->shared_hcd)) + return -EBUSY; retval = hcd->driver->pci_suspend(hcd, do_wakeup); suspend_report_result(hcd->driver->pci_suspend, retval); /* Check again in case wakeup raced with pci_suspend */ - if (retval == 0 && do_wakeup && HCD_WAKEUP_PENDING(hcd)) { + if ((retval == 0 && do_wakeup && HCD_WAKEUP_PENDING(hcd)) || + (retval == 0 && do_wakeup && hcd->shared_hcd && + HCD_WAKEUP_PENDING(hcd->shared_hcd))) { if (hcd->driver->pci_resume) hcd->driver->pci_resume(hcd, false); retval = -EBUSY; @@ -426,7 +438,9 @@ static int resume_common(struct device *dev, int event) struct usb_hcd *hcd = pci_get_drvdata(pci_dev); int retval; - if (HCD_RH_RUNNING(hcd)) { + if (HCD_RH_RUNNING(hcd) || + (hcd->shared_hcd && + HCD_RH_RUNNING(hcd->shared_hcd))) { dev_dbg(dev, "can't resume, not suspended!\n"); return 0; } @@ -440,6 +454,8 @@ static int resume_common(struct device *dev, int event) pci_set_master(pci_dev); clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); + if (hcd->shared_hcd) + clear_bit(HCD_FLAG_SAW_IRQ, &hcd->shared_hcd->flags); if (hcd->driver->pci_resume && !HCD_DEAD(hcd)) { if (event != PM_EVENT_AUTO_RESUME) @@ -449,6 +465,8 @@ static int resume_common(struct device *dev, int event) event == PM_EVENT_RESTORE); if (retval) { dev_err(dev, "PCI post-resume error %d!\n", retval); + if (hcd->shared_hcd) + usb_hc_died(hcd->shared_hcd); usb_hc_died(hcd); } } @@ -474,8 +492,9 @@ static int hcd_pci_suspend_noirq(struct device *dev) pci_save_state(pci_dev); - /* If the root hub is dead rather than suspended, - * disallow remote wakeup. + /* If the root hub is dead rather than suspended, disallow remote + * wakeup. usb_hc_died() should ensure that both hosts are marked as + * dying, so we only need to check the primary roothub. */ if (HCD_DEAD(hcd)) device_set_wakeup_enable(dev, 0); diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index ba15eeab824e..02b4dbfa488a 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1153,6 +1153,8 @@ int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb, dev_warn(hcd->self.controller, "Unlink after no-IRQ? " "Controller is probably using the wrong IRQ.\n"); set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); + if (hcd->shared_hcd) + set_bit(HCD_FLAG_SAW_IRQ, &hcd->shared_hcd->flags); } return 0; @@ -2124,6 +2126,8 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd) rc = IRQ_NONE; } else { set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); + if (hcd->shared_hcd) + set_bit(HCD_FLAG_SAW_IRQ, &hcd->shared_hcd->flags); if (unlikely(hcd->state == HC_STATE_HALT)) usb_hc_died(hcd); diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 9e2b26c3da40..47763bed378a 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2181,6 +2181,8 @@ irqreturn_t xhci_msi_irq(int irq, struct usb_hcd *hcd) irqreturn_t ret; set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); + if (hcd->shared_hcd) + set_bit(HCD_FLAG_SAW_IRQ, &hcd->shared_hcd->flags); ret = xhci_irq(hcd); -- cgit v1.2.3 From 5308a91b9fc1a8f94b860c2589b06908a97cba7e Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Wed, 1 Dec 2010 11:34:59 -0800 Subject: xhci: Index with a port array instead of PORTSC addresses. In the upcoming patches, the roothub emulation code will need to return port status and port change buffers based on whether they are called with the xHCI USB 2.0 or USB 3.0 roothub. To facilitate that, make the roothub code index into an array of port addresses with wIndex, rather than calculating the address using the offset and the address of the PORTSC registers. Later we can set the port array to be the array of USB 3.0 port addresses, or the USB 2.0 port addresses, depending on the roothub passed in. Create a temporary (statically sized) port array and fill it in with both USB 3.0 and USB 2.0 port addresses. This is inefficient to do for every roothub call, but this is needed for git bisect compatibility. The temporary port array will be deleted in a subsequent patch. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-hub.c | 126 +++++++++++++++++++++++++++---------------- drivers/usb/host/xhci-ring.c | 22 +++++--- 2 files changed, 95 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 847b071b6fc9..89ff025b41be 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -288,10 +288,18 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, unsigned long flags; u32 temp, temp1, status; int retval = 0; - u32 __iomem *addr; + u32 __iomem *port_array[15 + USB_MAXCHILDREN]; + int i; int slot_id; ports = HCS_MAX_PORTS(xhci->hcs_params1); + for (i = 0; i < ports; i++) { + if (i < xhci->num_usb3_ports) + port_array[i] = xhci->usb3_ports[i]; + else + port_array[i] = + xhci->usb2_ports[i - xhci->num_usb3_ports]; + } spin_lock_irqsave(&xhci->lock, flags); switch (typeReq) { @@ -307,8 +315,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, goto error; wIndex--; status = 0; - addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS*(wIndex & 0xff); - temp = xhci_readl(xhci, addr); + temp = xhci_readl(xhci, port_array[wIndex]); xhci_dbg(xhci, "get port status, actual port %d status = 0x%x\n", wIndex, temp); /* wPortChange bits */ @@ -336,7 +343,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, temp1 = xhci_port_state_to_neutral(temp); temp1 &= ~PORT_PLS_MASK; temp1 |= PORT_LINK_STROBE | XDEV_U0; - xhci_writel(xhci, temp1, addr); + xhci_writel(xhci, temp1, port_array[wIndex]); xhci_dbg(xhci, "set port %d resume\n", wIndex + 1); @@ -379,12 +386,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, if (!wIndex || wIndex > ports) goto error; wIndex--; - addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS*(wIndex & 0xff); - temp = xhci_readl(xhci, addr); + temp = xhci_readl(xhci, port_array[wIndex]); temp = xhci_port_state_to_neutral(temp); switch (wValue) { case USB_PORT_FEAT_SUSPEND: - temp = xhci_readl(xhci, addr); + temp = xhci_readl(xhci, port_array[wIndex]); /* In spec software should not attempt to suspend * a port unless the port reports that it is in the * enabled (PED = ‘1’,PLS < ‘3’) state. @@ -409,13 +415,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, temp = xhci_port_state_to_neutral(temp); temp &= ~PORT_PLS_MASK; temp |= PORT_LINK_STROBE | XDEV_U3; - xhci_writel(xhci, temp, addr); + xhci_writel(xhci, temp, port_array[wIndex]); spin_unlock_irqrestore(&xhci->lock, flags); msleep(10); /* wait device to enter */ spin_lock_irqsave(&xhci->lock, flags); - temp = xhci_readl(xhci, addr); + temp = xhci_readl(xhci, port_array[wIndex]); xhci->suspended_ports |= 1 << wIndex; break; case USB_PORT_FEAT_POWER: @@ -425,34 +431,34 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, * However, khubd will ignore the roothub events until * the roothub is registered. */ - xhci_writel(xhci, temp | PORT_POWER, addr); + xhci_writel(xhci, temp | PORT_POWER, + port_array[wIndex]); - temp = xhci_readl(xhci, addr); + temp = xhci_readl(xhci, port_array[wIndex]); xhci_dbg(xhci, "set port power, actual port %d status = 0x%x\n", wIndex, temp); break; case USB_PORT_FEAT_RESET: temp = (temp | PORT_RESET); - xhci_writel(xhci, temp, addr); + xhci_writel(xhci, temp, port_array[wIndex]); - temp = xhci_readl(xhci, addr); + temp = xhci_readl(xhci, port_array[wIndex]); xhci_dbg(xhci, "set port reset, actual port %d status = 0x%x\n", wIndex, temp); break; default: goto error; } - temp = xhci_readl(xhci, addr); /* unblock any posted writes */ + /* unblock any posted writes */ + temp = xhci_readl(xhci, port_array[wIndex]); break; case ClearPortFeature: if (!wIndex || wIndex > ports) goto error; wIndex--; - addr = &xhci->op_regs->port_status_base + - NUM_PORT_REGS*(wIndex & 0xff); - temp = xhci_readl(xhci, addr); + temp = xhci_readl(xhci, port_array[wIndex]); temp = xhci_port_state_to_neutral(temp); switch (wValue) { case USB_PORT_FEAT_SUSPEND: - temp = xhci_readl(xhci, addr); + temp = xhci_readl(xhci, port_array[wIndex]); xhci_dbg(xhci, "clear USB_PORT_FEAT_SUSPEND\n"); xhci_dbg(xhci, "PORTSC %04x\n", temp); if (temp & PORT_RESET) @@ -464,24 +470,28 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, temp = xhci_port_state_to_neutral(temp); temp &= ~PORT_PLS_MASK; temp |= PORT_LINK_STROBE | XDEV_U0; - xhci_writel(xhci, temp, addr); - xhci_readl(xhci, addr); + xhci_writel(xhci, temp, + port_array[wIndex]); + xhci_readl(xhci, port_array[wIndex]); } else { temp = xhci_port_state_to_neutral(temp); temp &= ~PORT_PLS_MASK; temp |= PORT_LINK_STROBE | XDEV_RESUME; - xhci_writel(xhci, temp, addr); + xhci_writel(xhci, temp, + port_array[wIndex]); spin_unlock_irqrestore(&xhci->lock, flags); msleep(20); spin_lock_irqsave(&xhci->lock, flags); - temp = xhci_readl(xhci, addr); + temp = xhci_readl(xhci, + port_array[wIndex]); temp = xhci_port_state_to_neutral(temp); temp &= ~PORT_PLS_MASK; temp |= PORT_LINK_STROBE | XDEV_U0; - xhci_writel(xhci, temp, addr); + xhci_writel(xhci, temp, + port_array[wIndex]); } xhci->port_c_suspend |= 1 << wIndex; } @@ -500,10 +510,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, case USB_PORT_FEAT_C_OVER_CURRENT: case USB_PORT_FEAT_C_ENABLE: xhci_clear_port_change_bit(xhci, wValue, wIndex, - addr, temp); + port_array[wIndex], temp); break; case USB_PORT_FEAT_ENABLE: - xhci_disable_port(xhci, wIndex, addr, temp); + xhci_disable_port(xhci, wIndex, + port_array[wIndex], temp); break; default: goto error; @@ -534,9 +545,16 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) int i, retval; struct xhci_hcd *xhci = hcd_to_xhci(hcd); int ports; - u32 __iomem *addr; + u32 __iomem *port_array[15 + USB_MAXCHILDREN]; ports = HCS_MAX_PORTS(xhci->hcs_params1); + for (i = 0; i < ports; i++) { + if (i < xhci->num_usb3_ports) + port_array[i] = xhci->usb3_ports[i]; + else + port_array[i] = + xhci->usb2_ports[i - xhci->num_usb3_ports]; + } /* Initial status is no changes */ retval = (ports + 8) / 8; @@ -548,9 +566,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) spin_lock_irqsave(&xhci->lock, flags); /* For each port, did anything change? If so, set that bit in buf. */ for (i = 0; i < ports; i++) { - addr = &xhci->op_regs->port_status_base + - NUM_PORT_REGS*i; - temp = xhci_readl(xhci, addr); + temp = xhci_readl(xhci, port_array[i]); if ((temp & mask) != 0 || (xhci->port_c_suspend & 1 << i) || (xhci->resume_done[i] && time_after_eq( @@ -569,10 +585,19 @@ int xhci_bus_suspend(struct usb_hcd *hcd) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); int max_ports, port_index; + u32 __iomem *port_array[15 + USB_MAXCHILDREN]; + int i; unsigned long flags; xhci_dbg(xhci, "suspend root hub\n"); max_ports = HCS_MAX_PORTS(xhci->hcs_params1); + for (i = 0; i < max_ports; i++) { + if (i < xhci->num_usb3_ports) + port_array[i] = xhci->usb3_ports[i]; + else + port_array[i] = + xhci->usb2_ports[i - xhci->num_usb3_ports]; + } spin_lock_irqsave(&xhci->lock, flags); @@ -593,13 +618,10 @@ int xhci_bus_suspend(struct usb_hcd *hcd) xhci->bus_suspended = 0; while (port_index--) { /* suspend the port if the port is not suspended */ - u32 __iomem *addr; u32 t1, t2; int slot_id; - addr = &xhci->op_regs->port_status_base + - NUM_PORT_REGS * (port_index & 0xff); - t1 = xhci_readl(xhci, addr); + t1 = xhci_readl(xhci, port_array[port_index]); t2 = xhci_port_state_to_neutral(t1); if ((t1 & PORT_PE) && !(t1 & PORT_PLS_MASK)) { @@ -628,15 +650,17 @@ int xhci_bus_suspend(struct usb_hcd *hcd) t1 = xhci_port_state_to_neutral(t1); if (t1 != t2) - xhci_writel(xhci, t2, addr); + xhci_writel(xhci, t2, port_array[port_index]); if (DEV_HIGHSPEED(t1)) { /* enable remote wake up for USB 2.0 */ u32 __iomem *addr; u32 tmp; - addr = &xhci->op_regs->port_power_base + - NUM_PORT_REGS * (port_index & 0xff); + /* Add one to the port status register address to get + * the port power control register address. + */ + addr = port_array[port_index] + 1; tmp = xhci_readl(xhci, addr); tmp |= PORT_RWE; xhci_writel(xhci, tmp, addr); @@ -652,11 +676,20 @@ int xhci_bus_resume(struct usb_hcd *hcd) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); int max_ports, port_index; + u32 __iomem *port_array[15 + USB_MAXCHILDREN]; + int i; u32 temp; unsigned long flags; xhci_dbg(xhci, "resume root hub\n"); max_ports = HCS_MAX_PORTS(xhci->hcs_params1); + for (i = 0; i < max_ports; i++) { + if (i < xhci->num_usb3_ports) + port_array[i] = xhci->usb3_ports[i]; + else + port_array[i] = + xhci->usb2_ports[i - xhci->num_usb3_ports]; + } if (time_before(jiffies, xhci->next_statechange)) msleep(5); @@ -676,13 +709,10 @@ int xhci_bus_resume(struct usb_hcd *hcd) while (port_index--) { /* Check whether need resume ports. If needed resume port and disable remote wakeup */ - u32 __iomem *addr; u32 temp; int slot_id; - addr = &xhci->op_regs->port_status_base + - NUM_PORT_REGS * (port_index & 0xff); - temp = xhci_readl(xhci, addr); + temp = xhci_readl(xhci, port_array[port_index]); if (DEV_SUPERSPEED(temp)) temp &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS); else @@ -693,36 +723,38 @@ int xhci_bus_resume(struct usb_hcd *hcd) temp = xhci_port_state_to_neutral(temp); temp &= ~PORT_PLS_MASK; temp |= PORT_LINK_STROBE | XDEV_U0; - xhci_writel(xhci, temp, addr); + xhci_writel(xhci, temp, port_array[port_index]); } else { temp = xhci_port_state_to_neutral(temp); temp &= ~PORT_PLS_MASK; temp |= PORT_LINK_STROBE | XDEV_RESUME; - xhci_writel(xhci, temp, addr); + xhci_writel(xhci, temp, port_array[port_index]); spin_unlock_irqrestore(&xhci->lock, flags); msleep(20); spin_lock_irqsave(&xhci->lock, flags); - temp = xhci_readl(xhci, addr); + temp = xhci_readl(xhci, port_array[port_index]); temp = xhci_port_state_to_neutral(temp); temp &= ~PORT_PLS_MASK; temp |= PORT_LINK_STROBE | XDEV_U0; - xhci_writel(xhci, temp, addr); + xhci_writel(xhci, temp, port_array[port_index]); } slot_id = xhci_find_slot_id_by_port(xhci, port_index + 1); if (slot_id) xhci_ring_device(xhci, slot_id); } else - xhci_writel(xhci, temp, addr); + xhci_writel(xhci, temp, port_array[port_index]); if (DEV_HIGHSPEED(temp)) { /* disable remote wake up for USB 2.0 */ u32 __iomem *addr; u32 tmp; - addr = &xhci->op_regs->port_power_base + - NUM_PORT_REGS * (port_index & 0xff); + /* Add one to the port status register address to get + * the port power control register address. + */ + addr = port_array[port_index] + 1; tmp = xhci_readl(xhci, addr); tmp &= ~PORT_RWE; xhci_writel(xhci, tmp, addr); diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 47763bed378a..582537689ebc 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1161,9 +1161,11 @@ static void handle_port_status(struct xhci_hcd *xhci, struct usb_hcd *hcd = xhci_to_hcd(xhci); u32 port_id; u32 temp, temp1; - u32 __iomem *addr; int max_ports; int slot_id; + unsigned int faked_port_index; + u32 __iomem *port_array[15 + USB_MAXCHILDREN]; + int i; /* Port status change events always have a successful completion code */ if (GET_COMP_CODE(event->generic.field[2]) != COMP_SUCCESS) { @@ -1179,8 +1181,16 @@ static void handle_port_status(struct xhci_hcd *xhci, goto cleanup; } - addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS * (port_id - 1); - temp = xhci_readl(xhci, addr); + for (i = 0; i < max_ports; i++) { + if (i < xhci->num_usb3_ports) + port_array[i] = xhci->usb3_ports[i]; + else + port_array[i] = + xhci->usb2_ports[i - xhci->num_usb3_ports]; + } + + faked_port_index = port_id; + temp = xhci_readl(xhci, port_array[faked_port_index]); if (hcd->state == HC_STATE_SUSPENDED) { xhci_dbg(xhci, "resume root hub\n"); usb_hcd_resume_root_hub(hcd); @@ -1200,7 +1210,7 @@ static void handle_port_status(struct xhci_hcd *xhci, temp = xhci_port_state_to_neutral(temp); temp &= ~PORT_PLS_MASK; temp |= PORT_LINK_STROBE | XDEV_U0; - xhci_writel(xhci, temp, addr); + xhci_writel(xhci, temp, port_array[faked_port_index]); slot_id = xhci_find_slot_id_by_port(xhci, port_id); if (!slot_id) { xhci_dbg(xhci, "slot_id is zero\n"); @@ -1209,10 +1219,10 @@ static void handle_port_status(struct xhci_hcd *xhci, xhci_ring_device(xhci, slot_id); xhci_dbg(xhci, "resume SS port %d finished\n", port_id); /* Clear PORT_PLC */ - temp = xhci_readl(xhci, addr); + temp = xhci_readl(xhci, port_array[faked_port_index]); temp = xhci_port_state_to_neutral(temp); temp |= PORT_PLC; - xhci_writel(xhci, temp, addr); + xhci_writel(xhci, temp, port_array[faked_port_index]); } else { xhci_dbg(xhci, "resume HS port %d\n", port_id); xhci->resume_done[port_id - 1] = jiffies + -- cgit v1.2.3 From 20b67cf51fa606442bb343afad0ee1a393a6afb3 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Wed, 15 Dec 2010 12:47:14 -0800 Subject: xhci: Refactor bus suspend state into a struct. There are several variables in the xhci_hcd structure that are related to bus suspend and resume state. There are a couple different port status arrays that are accessed by port index. Move those variables into a separate structure, xhci_bus_state. Stash that structure in xhci_hcd. When we have two roothhubs that can be suspended and resumed separately, we can have two xhci_bus_states, and index into the port arrays in each structure with the fake roothub port index (not the real hardware port index). Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-hub.c | 50 +++++++++++++++++++++++++------------------- drivers/usb/host/xhci-mem.c | 4 ++-- drivers/usb/host/xhci-ring.c | 6 ++++-- drivers/usb/host/xhci.c | 5 ++++- drivers/usb/host/xhci.h | 28 ++++++++++++++++++------- 5 files changed, 59 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 89ff025b41be..4944ba135f9a 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -291,6 +291,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u32 __iomem *port_array[15 + USB_MAXCHILDREN]; int i; int slot_id; + struct xhci_bus_state *bus_state; ports = HCS_MAX_PORTS(xhci->hcs_params1); for (i = 0; i < ports; i++) { @@ -300,6 +301,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, port_array[i] = xhci->usb2_ports[i - xhci->num_usb3_ports]; } + bus_state = &xhci->bus_state[hcd_index(hcd)]; spin_lock_irqsave(&xhci->lock, flags); switch (typeReq) { @@ -336,10 +338,10 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, if ((temp & PORT_RESET) || !(temp & PORT_PE)) goto error; if (!DEV_SUPERSPEED(temp) && time_after_eq(jiffies, - xhci->resume_done[wIndex])) { + bus_state->resume_done[wIndex])) { xhci_dbg(xhci, "Resume USB2 port %d\n", wIndex + 1); - xhci->resume_done[wIndex] = 0; + bus_state->resume_done[wIndex] = 0; temp1 = xhci_port_state_to_neutral(temp); temp1 &= ~PORT_PLS_MASK; temp1 |= PORT_LINK_STROBE | XDEV_U0; @@ -354,15 +356,15 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, goto error; } xhci_ring_device(xhci, slot_id); - xhci->port_c_suspend |= 1 << wIndex; - xhci->suspended_ports &= ~(1 << wIndex); + bus_state->port_c_suspend |= 1 << wIndex; + bus_state->suspended_ports &= ~(1 << wIndex); } } if ((temp & PORT_PLS_MASK) == XDEV_U0 && (temp & PORT_POWER) - && (xhci->suspended_ports & (1 << wIndex))) { - xhci->suspended_ports &= ~(1 << wIndex); - xhci->port_c_suspend |= 1 << wIndex; + && (bus_state->suspended_ports & (1 << wIndex))) { + bus_state->suspended_ports &= ~(1 << wIndex); + bus_state->port_c_suspend |= 1 << wIndex; } if (temp & PORT_CONNECT) { status |= USB_PORT_STAT_CONNECTION; @@ -376,7 +378,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, status |= USB_PORT_STAT_RESET; if (temp & PORT_POWER) status |= USB_PORT_STAT_POWER; - if (xhci->port_c_suspend & (1 << wIndex)) + if (bus_state->port_c_suspend & (1 << wIndex)) status |= 1 << USB_PORT_FEAT_C_SUSPEND; xhci_dbg(xhci, "Get port status returned 0x%x\n", status); put_unaligned(cpu_to_le32(status), (__le32 *) buf); @@ -422,7 +424,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, spin_lock_irqsave(&xhci->lock, flags); temp = xhci_readl(xhci, port_array[wIndex]); - xhci->suspended_ports |= 1 << wIndex; + bus_state->suspended_ports |= 1 << wIndex; break; case USB_PORT_FEAT_POWER: /* @@ -493,7 +495,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, xhci_writel(xhci, temp, port_array[wIndex]); } - xhci->port_c_suspend |= 1 << wIndex; + bus_state->port_c_suspend |= 1 << wIndex; } slot_id = xhci_find_slot_id_by_port(xhci, wIndex + 1); @@ -504,7 +506,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, xhci_ring_device(xhci, slot_id); break; case USB_PORT_FEAT_C_SUSPEND: - xhci->port_c_suspend &= ~(1 << wIndex); + bus_state->port_c_suspend &= ~(1 << wIndex); case USB_PORT_FEAT_C_RESET: case USB_PORT_FEAT_C_CONNECTION: case USB_PORT_FEAT_C_OVER_CURRENT: @@ -546,6 +548,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) struct xhci_hcd *xhci = hcd_to_xhci(hcd); int ports; u32 __iomem *port_array[15 + USB_MAXCHILDREN]; + struct xhci_bus_state *bus_state; ports = HCS_MAX_PORTS(xhci->hcs_params1); for (i = 0; i < ports; i++) { @@ -555,6 +558,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) port_array[i] = xhci->usb2_ports[i - xhci->num_usb3_ports]; } + bus_state = &xhci->bus_state[hcd_index(hcd)]; /* Initial status is no changes */ retval = (ports + 8) / 8; @@ -568,9 +572,9 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) for (i = 0; i < ports; i++) { temp = xhci_readl(xhci, port_array[i]); if ((temp & mask) != 0 || - (xhci->port_c_suspend & 1 << i) || - (xhci->resume_done[i] && time_after_eq( - jiffies, xhci->resume_done[i]))) { + (bus_state->port_c_suspend & 1 << i) || + (bus_state->resume_done[i] && time_after_eq( + jiffies, bus_state->resume_done[i]))) { buf[(i + 1) / 8] |= 1 << (i + 1) % 8; status = 1; } @@ -587,6 +591,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd) int max_ports, port_index; u32 __iomem *port_array[15 + USB_MAXCHILDREN]; int i; + struct xhci_bus_state *bus_state; unsigned long flags; xhci_dbg(xhci, "suspend root hub\n"); @@ -598,13 +603,14 @@ int xhci_bus_suspend(struct usb_hcd *hcd) port_array[i] = xhci->usb2_ports[i - xhci->num_usb3_ports]; } + bus_state = &xhci->bus_state[hcd_index(hcd)]; spin_lock_irqsave(&xhci->lock, flags); if (hcd->self.root_hub->do_remote_wakeup) { port_index = max_ports; while (port_index--) { - if (xhci->resume_done[port_index] != 0) { + if (bus_state->resume_done[port_index] != 0) { spin_unlock_irqrestore(&xhci->lock, flags); xhci_dbg(xhci, "suspend failed because " "port %d is resuming\n", @@ -615,7 +621,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd) } port_index = max_ports; - xhci->bus_suspended = 0; + bus_state->bus_suspended = 0; while (port_index--) { /* suspend the port if the port is not suspended */ u32 t1, t2; @@ -635,7 +641,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd) } t2 &= ~PORT_PLS_MASK; t2 |= PORT_LINK_STROBE | XDEV_U3; - set_bit(port_index, &xhci->bus_suspended); + set_bit(port_index, &bus_state->bus_suspended); } if (hcd->self.root_hub->do_remote_wakeup) { if (t1 & PORT_CONNECT) { @@ -667,7 +673,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd) } } hcd->state = HC_STATE_SUSPENDED; - xhci->next_statechange = jiffies + msecs_to_jiffies(10); + bus_state->next_statechange = jiffies + msecs_to_jiffies(10); spin_unlock_irqrestore(&xhci->lock, flags); return 0; } @@ -678,6 +684,7 @@ int xhci_bus_resume(struct usb_hcd *hcd) int max_ports, port_index; u32 __iomem *port_array[15 + USB_MAXCHILDREN]; int i; + struct xhci_bus_state *bus_state; u32 temp; unsigned long flags; @@ -690,8 +697,9 @@ int xhci_bus_resume(struct usb_hcd *hcd) port_array[i] = xhci->usb2_ports[i - xhci->num_usb3_ports]; } + bus_state = &xhci->bus_state[hcd_index(hcd)]; - if (time_before(jiffies, xhci->next_statechange)) + if (time_before(jiffies, bus_state->next_statechange)) msleep(5); spin_lock_irqsave(&xhci->lock, flags); @@ -717,7 +725,7 @@ int xhci_bus_resume(struct usb_hcd *hcd) temp &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS); else temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); - if (test_bit(port_index, &xhci->bus_suspended) && + if (test_bit(port_index, &bus_state->bus_suspended) && (temp & PORT_PLS_MASK)) { if (DEV_SUPERSPEED(temp)) { temp = xhci_port_state_to_neutral(temp); @@ -763,7 +771,7 @@ int xhci_bus_resume(struct usb_hcd *hcd) (void) xhci_readl(xhci, &xhci->op_regs->command); - xhci->next_statechange = jiffies + msecs_to_jiffies(5); + bus_state->next_statechange = jiffies + msecs_to_jiffies(5); /* re-enable irqs */ temp = xhci_readl(xhci, &xhci->op_regs->command); temp |= CMD_EIE; diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 9688a58611d4..bc809cbd570a 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1451,7 +1451,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) xhci->page_size = 0; xhci->page_shift = 0; - xhci->bus_suspended = 0; + xhci->bus_state[0].bus_suspended = 0; } static int xhci_test_trb_in_td(struct xhci_hcd *xhci, @@ -1971,7 +1971,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) for (i = 0; i < MAX_HC_SLOTS; ++i) xhci->devs[i] = NULL; for (i = 0; i < USB_MAXCHILDREN; ++i) - xhci->resume_done[i] = 0; + xhci->bus_state[0].resume_done[i] = 0; if (scratchpad_alloc(xhci, flags)) goto fail; diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 582537689ebc..7cea2483e593 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1166,7 +1166,9 @@ static void handle_port_status(struct xhci_hcd *xhci, unsigned int faked_port_index; u32 __iomem *port_array[15 + USB_MAXCHILDREN]; int i; + struct xhci_bus_state *bus_state; + bus_state = &xhci->bus_state[0]; /* Port status change events always have a successful completion code */ if (GET_COMP_CODE(event->generic.field[2]) != COMP_SUCCESS) { xhci_warn(xhci, "WARN: xHC returned failed port status event\n"); @@ -1225,10 +1227,10 @@ static void handle_port_status(struct xhci_hcd *xhci, xhci_writel(xhci, temp, port_array[faked_port_index]); } else { xhci_dbg(xhci, "resume HS port %d\n", port_id); - xhci->resume_done[port_id - 1] = jiffies + + bus_state->resume_done[port_id - 1] = jiffies + msecs_to_jiffies(20); mod_timer(&hcd->rh_timer, - xhci->resume_done[port_id - 1]); + bus_state->resume_done[port_id - 1]); /* Do the rest in GetPortStatus */ } } diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index a95108cba7d4..8d45bbde3da4 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -694,7 +694,10 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) struct usb_hcd *hcd = xhci_to_hcd(xhci); int retval; - if (time_before(jiffies, xhci->next_statechange)) + /* Wait a bit if the bus needs to settle from the transistion to + * suspend. + */ + if (time_before(jiffies, xhci->bus_state[0].next_statechange)) msleep(100); spin_lock_irq(&xhci->lock); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index daa88581ad66..c15470eb121a 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1161,6 +1161,22 @@ struct s3_save { u64 erst_dequeue; }; +struct xhci_bus_state { + unsigned long bus_suspended; + unsigned long next_statechange; + + /* Port suspend arrays are indexed by the portnum of the fake roothub */ + /* ports suspend status arrays - max 31 ports for USB2, 15 for USB3 */ + u32 port_c_suspend; + u32 suspended_ports; + unsigned long resume_done[USB_MAXCHILDREN]; +}; + +static inline unsigned int hcd_index(struct usb_hcd *hcd) +{ + return 0; +} + /* There is one ehci_hci structure per controller */ struct xhci_hcd { struct usb_hcd *main_hcd; @@ -1225,9 +1241,6 @@ struct xhci_hcd { /* Host controller watchdog timer structures */ unsigned int xhc_state; - unsigned long bus_suspended; - unsigned long next_statechange; - u32 command; struct s3_save s3; /* Host controller is dying - not responding to commands. "I'm not dead yet!" @@ -1249,11 +1262,10 @@ struct xhci_hcd { #define XHCI_LINK_TRB_QUIRK (1 << 0) #define XHCI_RESET_EP_QUIRK (1 << 1) #define XHCI_NEC_HOST (1 << 2) - /* port suspend change*/ - u32 port_c_suspend; - /* which ports are suspended */ - u32 suspended_ports; - unsigned long resume_done[USB_MAXCHILDREN]; + /* There's only one roothub to keep track of bus suspend info for + * (right now). + */ + struct xhci_bus_state bus_state[1]; /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */ u8 *port_array; /* Array of pointers to USB 3.0 PORTSC registers */ -- cgit v1.2.3 From 5233630fcdd6f7d415dcbed264031439cab73f9d Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 16 Dec 2010 10:49:09 -0800 Subject: xhci: Change xhci_find_slot_id_by_port() API. xhci_find_slot_id_by_port() tries to map the port index to the slot ID for the USB device. In the future, there will be two xHCI roothubs, and their port indices will overlap. Therefore, xhci_find_slot_id_by_port() will need to use information in the roothub's usb_hcd structure to map the port index and roothub speed to the right slot ID. Add a new parameter to xhci_find_slot_id_by_port(), in order to pass in the roothub's usb_hcd structure. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-hub.c | 16 ++++++++++------ drivers/usb/host/xhci-ring.c | 3 ++- drivers/usb/host/xhci.h | 3 ++- 3 files changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 4944ba135f9a..4c3788c128df 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -135,7 +135,8 @@ u32 xhci_port_state_to_neutral(u32 state) /* * find slot id based on port number. */ -int xhci_find_slot_id_by_port(struct xhci_hcd *xhci, u16 port) +int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, + u16 port) { int slot_id; int i; @@ -349,7 +350,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, xhci_dbg(xhci, "set port %d resume\n", wIndex + 1); - slot_id = xhci_find_slot_id_by_port(xhci, + slot_id = xhci_find_slot_id_by_port(hcd, xhci, wIndex + 1); if (!slot_id) { xhci_dbg(xhci, "slot_id is zero\n"); @@ -404,7 +405,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, goto error; } - slot_id = xhci_find_slot_id_by_port(xhci, wIndex + 1); + slot_id = xhci_find_slot_id_by_port(hcd, xhci, + wIndex + 1); if (!slot_id) { xhci_warn(xhci, "slot_id is zero\n"); goto error; @@ -498,7 +500,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, bus_state->port_c_suspend |= 1 << wIndex; } - slot_id = xhci_find_slot_id_by_port(xhci, wIndex + 1); + slot_id = xhci_find_slot_id_by_port(hcd, xhci, + wIndex + 1); if (!slot_id) { xhci_dbg(xhci, "slot_id is zero\n"); goto error; @@ -632,7 +635,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd) if ((t1 & PORT_PE) && !(t1 & PORT_PLS_MASK)) { xhci_dbg(xhci, "port %d not suspended\n", port_index); - slot_id = xhci_find_slot_id_by_port(xhci, + slot_id = xhci_find_slot_id_by_port(hcd, xhci, port_index + 1); if (slot_id) { spin_unlock_irqrestore(&xhci->lock, flags); @@ -748,7 +751,8 @@ int xhci_bus_resume(struct usb_hcd *hcd) temp |= PORT_LINK_STROBE | XDEV_U0; xhci_writel(xhci, temp, port_array[port_index]); } - slot_id = xhci_find_slot_id_by_port(xhci, port_index + 1); + slot_id = xhci_find_slot_id_by_port(hcd, + xhci, port_index + 1); if (slot_id) xhci_ring_device(xhci, slot_id); } else diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 7cea2483e593..7fe9aebd3922 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1213,7 +1213,8 @@ static void handle_port_status(struct xhci_hcd *xhci, temp &= ~PORT_PLS_MASK; temp |= PORT_LINK_STROBE | XDEV_U0; xhci_writel(xhci, temp, port_array[faked_port_index]); - slot_id = xhci_find_slot_id_by_port(xhci, port_id); + slot_id = xhci_find_slot_id_by_port(hcd, xhci, + faked_port_index); if (!slot_id) { xhci_dbg(xhci, "slot_id is zero\n"); goto cleanup; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index c15470eb121a..443d6333f280 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1533,7 +1533,8 @@ int xhci_bus_resume(struct usb_hcd *hcd); #endif /* CONFIG_PM */ u32 xhci_port_state_to_neutral(u32 state); -int xhci_find_slot_id_by_port(struct xhci_hcd *xhci, u16 port); +int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, + u16 port); void xhci_ring_device(struct xhci_hcd *xhci, int slot_id); /* xHCI contexts */ -- cgit v1.2.3 From f6ff0ac878eb420011fa2448851dd48c3a7e7b31 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 16 Dec 2010 11:21:10 -0800 Subject: xhci: Register second xHCI roothub. This patch changes the xHCI driver to allocate two roothubs. This touches the driver initialization and shutdown paths, roothub emulation code, and port status change event handlers. This is a rather large patch, but it can't be broken up, or it would break git-bisect. Make the xHCI driver register its own PCI probe function. This will call the USB core to create the USB 2.0 roothub, and then create the USB 3.0 roothub. This gets the code for registering a shared roothub out of the USB core, and allows other HCDs later to decide if and how many shared roothubs they want to allocate. Make sure the xHCI's reset method marks the xHCI host controller's primary roothub as the USB 2.0 roothub. This ensures that the high speed bus will be processed first when the PCI device is resumed, and any USB 3.0 devices that have migrated over to high speed will migrate back after being reset. This ensures that USB persist works with these odd devices. The reset method will also mark the xHCI USB2 roothub as having an integrated TT. Like EHCI host controllers with a "rate matching hub" the xHCI USB 2.0 roothub doesn't have an OHCI or UHCI companion controller. It doesn't really have a TT, but we'll lie and say it has an integrated TT. We need to do this because the USB core will reject LS/FS devices under a HS hub without a TT. Other details: ------------- The roothub emulation code is changed to return the correct number of ports for the two roothubs. For the USB 3.0 roothub, it only reports the USB 3.0 ports. For the USB 2.0 roothub, it reports all the LS/FS/HS ports. The code to disable a port now checks the speed of the roothub, and refuses to disable SuperSpeed ports under the USB 3.0 roothub. The code for initializing a new device context must be changed to set the proper roothub port number. Since we've split the xHCI host into two roothubs, we can't just use the port number in the ancestor hub. Instead, we loop through the array of hardware port status register speeds and find the Nth port with a similar speed. The port status change event handler is updated to figure out whether the port that reported the change is a USB 3.0 port, or a non-SuperSpeed port. Once it figures out the port speed, it kicks the proper roothub. The function to find a slot ID based on the port index is updated to take into account that the two roothubs will have over-lapping port indexes. It checks that the virtual device with a matching port index is the same speed as the passed in roothub. There's also changes to the driver initialization and shutdown paths: 1. Make sure that the xhci_hcd pointer is shared across the two usb_hcd structures. The xhci_hcd pointer is allocated and the registers are mapped in when xhci_pci_setup() is called with the primary HCD. When xhci_pci_setup() is called with the non-primary HCD, the xhci_hcd pointer is stored. 2. Make sure to set the sg_tablesize for both usb_hcd structures. Set the PCI DMA mask for the non-primary HCD to allow for 64-bit or 32-bit DMA. (The PCI DMA mask is set from the primary HCD further down in the xhci_pci_setup() function.) 3. Ensure that the host controller doesn't start kicking khubd in response to port status changes before both usb_hcd structures are registered. xhci_run() only starts the xHC running once it has been called with the non-primary roothub. Similarly, the xhci_stop() function only halts the host controller when it is called with the non-primary HCD. Then on the second call, it resets and cleans up the MSI-X irqs. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-hub.c | 97 +++++++++++++++++++++++-------------------- drivers/usb/host/xhci-mem.c | 66 +++++++++++++++++++++++++++-- drivers/usb/host/xhci-pci.c | 98 ++++++++++++++++++++++++++++++++++++++++---- drivers/usb/host/xhci-ring.c | 94 +++++++++++++++++++++++++++++++++++------- drivers/usb/host/xhci.c | 62 +++++++++++++++++++++++----- drivers/usb/host/xhci.h | 12 +++--- 6 files changed, 341 insertions(+), 88 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 4c3788c128df..ee4af076a8fe 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -28,13 +28,20 @@ #define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_WRC | PORT_OCC | \ PORT_RC | PORT_PLC | PORT_PE) -static void xhci_hub_descriptor(struct xhci_hcd *xhci, +static void xhci_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci, struct usb_hub_descriptor *desc) { int ports; u16 temp; - ports = HCS_MAX_PORTS(xhci->hcs_params1); + if (hcd->speed == HCD_USB3) + ports = xhci->num_usb3_ports; + else + ports = xhci->num_usb2_ports; + + /* FIXME: return a USB 3.0 hub descriptor if this request was for the + * USB3 roothub. + */ /* USB 3.0 hubs have a different descriptor, but we fake this for now */ desc->bDescriptorType = 0x29; @@ -134,18 +141,22 @@ u32 xhci_port_state_to_neutral(u32 state) /* * find slot id based on port number. + * @port: The one-based port number from one of the two split roothubs. */ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, u16 port) { int slot_id; int i; + enum usb_device_speed speed; slot_id = 0; for (i = 0; i < MAX_HC_SLOTS; i++) { if (!xhci->devs[i]) continue; - if (xhci->devs[i]->port == port) { + speed = xhci->devs[i]->udev->speed; + if (((speed == USB_SPEED_SUPER) == (hcd->speed == HCD_USB3)) + && xhci->devs[i]->port == port) { slot_id = i; break; } @@ -226,11 +237,11 @@ void xhci_ring_device(struct xhci_hcd *xhci, int slot_id) return; } -static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex, - u32 __iomem *addr, u32 port_status) +static void xhci_disable_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, + u16 wIndex, u32 __iomem *addr, u32 port_status) { /* Don't allow the USB core to disable SuperSpeed ports. */ - if (xhci->port_array[wIndex] == 0x03) { + if (hcd->speed == HCD_USB3) { xhci_dbg(xhci, "Ignoring request to disable " "SuperSpeed port.\n"); return; @@ -289,18 +300,16 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, unsigned long flags; u32 temp, temp1, status; int retval = 0; - u32 __iomem *port_array[15 + USB_MAXCHILDREN]; - int i; + u32 __iomem **port_array; int slot_id; struct xhci_bus_state *bus_state; - ports = HCS_MAX_PORTS(xhci->hcs_params1); - for (i = 0; i < ports; i++) { - if (i < xhci->num_usb3_ports) - port_array[i] = xhci->usb3_ports[i]; - else - port_array[i] = - xhci->usb2_ports[i - xhci->num_usb3_ports]; + if (hcd->speed == HCD_USB3) { + ports = xhci->num_usb3_ports; + port_array = xhci->usb3_ports; + } else { + ports = xhci->num_usb2_ports; + port_array = xhci->usb2_ports; } bus_state = &xhci->bus_state[hcd_index(hcd)]; @@ -311,7 +320,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, memset(buf, 0, 4); break; case GetHubDescriptor: - xhci_hub_descriptor(xhci, (struct usb_hub_descriptor *) buf); + xhci_hub_descriptor(hcd, xhci, + (struct usb_hub_descriptor *) buf); break; case GetPortStatus: if (!wIndex || wIndex > ports) @@ -518,7 +528,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, port_array[wIndex], temp); break; case USB_PORT_FEAT_ENABLE: - xhci_disable_port(xhci, wIndex, + xhci_disable_port(hcd, xhci, wIndex, port_array[wIndex], temp); break; default: @@ -550,16 +560,15 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) int i, retval; struct xhci_hcd *xhci = hcd_to_xhci(hcd); int ports; - u32 __iomem *port_array[15 + USB_MAXCHILDREN]; + u32 __iomem **port_array; struct xhci_bus_state *bus_state; - ports = HCS_MAX_PORTS(xhci->hcs_params1); - for (i = 0; i < ports; i++) { - if (i < xhci->num_usb3_ports) - port_array[i] = xhci->usb3_ports[i]; - else - port_array[i] = - xhci->usb2_ports[i - xhci->num_usb3_ports]; + if (hcd->speed == HCD_USB3) { + ports = xhci->num_usb3_ports; + port_array = xhci->usb3_ports; + } else { + ports = xhci->num_usb2_ports; + port_array = xhci->usb2_ports; } bus_state = &xhci->bus_state[hcd_index(hcd)]; @@ -592,19 +601,18 @@ int xhci_bus_suspend(struct usb_hcd *hcd) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); int max_ports, port_index; - u32 __iomem *port_array[15 + USB_MAXCHILDREN]; - int i; + u32 __iomem **port_array; struct xhci_bus_state *bus_state; unsigned long flags; - xhci_dbg(xhci, "suspend root hub\n"); - max_ports = HCS_MAX_PORTS(xhci->hcs_params1); - for (i = 0; i < max_ports; i++) { - if (i < xhci->num_usb3_ports) - port_array[i] = xhci->usb3_ports[i]; - else - port_array[i] = - xhci->usb2_ports[i - xhci->num_usb3_ports]; + if (hcd->speed == HCD_USB3) { + max_ports = xhci->num_usb3_ports; + port_array = xhci->usb3_ports; + xhci_dbg(xhci, "suspend USB 3.0 root hub\n"); + } else { + max_ports = xhci->num_usb2_ports; + port_array = xhci->usb2_ports; + xhci_dbg(xhci, "suspend USB 2.0 root hub\n"); } bus_state = &xhci->bus_state[hcd_index(hcd)]; @@ -685,20 +693,19 @@ int xhci_bus_resume(struct usb_hcd *hcd) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); int max_ports, port_index; - u32 __iomem *port_array[15 + USB_MAXCHILDREN]; - int i; + u32 __iomem **port_array; struct xhci_bus_state *bus_state; u32 temp; unsigned long flags; - xhci_dbg(xhci, "resume root hub\n"); - max_ports = HCS_MAX_PORTS(xhci->hcs_params1); - for (i = 0; i < max_ports; i++) { - if (i < xhci->num_usb3_ports) - port_array[i] = xhci->usb3_ports[i]; - else - port_array[i] = - xhci->usb2_ports[i - xhci->num_usb3_ports]; + if (hcd->speed == HCD_USB3) { + max_ports = xhci->num_usb3_ports; + port_array = xhci->usb3_ports; + xhci_dbg(xhci, "resume USB 3.0 root hub\n"); + } else { + max_ports = xhci->num_usb2_ports; + port_array = xhci->usb2_ports; + xhci_dbg(xhci, "resume USB 2.0 root hub\n"); } bus_state = &xhci->bus_state[hcd_index(hcd)]; diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index bc809cbd570a..180a2abbc868 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -814,14 +814,64 @@ void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci, ep0_ctx->deq |= ep_ring->cycle_state; } +/* + * The xHCI roothub may have ports of differing speeds in any order in the port + * status registers. xhci->port_array provides an array of the port speed for + * each offset into the port status registers. + * + * The xHCI hardware wants to know the roothub port number that the USB device + * is attached to (or the roothub port its ancestor hub is attached to). All we + * know is the index of that port under either the USB 2.0 or the USB 3.0 + * roothub, but that doesn't give us the real index into the HW port status + * registers. Scan through the xHCI roothub port array, looking for the Nth + * entry of the correct port speed. Return the port number of that entry. + */ +static u32 xhci_find_real_port_number(struct xhci_hcd *xhci, + struct usb_device *udev) +{ + struct usb_device *top_dev; + unsigned int num_similar_speed_ports; + unsigned int faked_port_num; + int i; + + for (top_dev = udev; top_dev->parent && top_dev->parent->parent; + top_dev = top_dev->parent) + /* Found device below root hub */; + faked_port_num = top_dev->portnum; + for (i = 0, num_similar_speed_ports = 0; + i < HCS_MAX_PORTS(xhci->hcs_params1); i++) { + u8 port_speed = xhci->port_array[i]; + + /* + * Skip ports that don't have known speeds, or have duplicate + * Extended Capabilities port speed entries. + */ + if (port_speed == 0 || port_speed == -1) + continue; + + /* + * USB 3.0 ports are always under a USB 3.0 hub. USB 2.0 and + * 1.1 ports are under the USB 2.0 hub. If the port speed + * matches the device speed, it's a similar speed port. + */ + if ((port_speed == 0x03) == (udev->speed == USB_SPEED_SUPER)) + num_similar_speed_ports++; + if (num_similar_speed_ports == faked_port_num) + /* Roothub ports are numbered from 1 to N */ + return i+1; + } + return 0; +} + /* Setup an xHCI virtual device for a Set Address command */ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev) { struct xhci_virt_device *dev; struct xhci_ep_ctx *ep0_ctx; - struct usb_device *top_dev; struct xhci_slot_ctx *slot_ctx; struct xhci_input_control_ctx *ctrl_ctx; + u32 port_num; + struct usb_device *top_dev; dev = xhci->devs[udev->slot_id]; /* Slot ID 0 is reserved */ @@ -863,12 +913,17 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud BUG(); } /* Find the root hub port this device is under */ + port_num = xhci_find_real_port_number(xhci, udev); + if (!port_num) + return -EINVAL; + slot_ctx->dev_info2 |= (u32) ROOT_HUB_PORT(port_num); + /* Set the port number in the virtual_device to the faked port number */ for (top_dev = udev; top_dev->parent && top_dev->parent->parent; top_dev = top_dev->parent) /* Found device below root hub */; - slot_ctx->dev_info2 |= (u32) ROOT_HUB_PORT(top_dev->portnum); dev->port = top_dev->portnum; - xhci_dbg(xhci, "Set root hub portnum to %d\n", top_dev->portnum); + xhci_dbg(xhci, "Set root hub portnum to %d\n", port_num); + xhci_dbg(xhci, "Set fake root hub portnum to %d\n", dev->port); /* Is this a LS/FS device under an external HS hub? */ if (udev->tt && udev->tt->hub->parent) { @@ -1452,6 +1507,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) xhci->page_size = 0; xhci->page_shift = 0; xhci->bus_state[0].bus_suspended = 0; + xhci->bus_state[1].bus_suspended = 0; } static int xhci_test_trb_in_td(struct xhci_hcd *xhci, @@ -1970,8 +2026,10 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) init_completion(&xhci->addr_dev); for (i = 0; i < MAX_HC_SLOTS; ++i) xhci->devs[i] = NULL; - for (i = 0; i < USB_MAXCHILDREN; ++i) + for (i = 0; i < USB_MAXCHILDREN; ++i) { xhci->bus_state[0].resume_done[i] = 0; + xhci->bus_state[1].resume_done[i] = 0; + } if (scratchpad_alloc(xhci, flags)) goto fail; diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 009082829364..4a9d55e80f73 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -50,18 +50,44 @@ static int xhci_pci_reinit(struct xhci_hcd *xhci, struct pci_dev *pdev) /* called during probe() after chip reset completes */ static int xhci_pci_setup(struct usb_hcd *hcd) { - struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct xhci_hcd *xhci; struct pci_dev *pdev = to_pci_dev(hcd->self.controller); int retval; u32 temp; hcd->self.sg_tablesize = TRBS_PER_SEGMENT - 2; - xhci = kzalloc(sizeof(struct xhci_hcd), GFP_KERNEL); - if (!xhci) - return -ENOMEM; - *((struct xhci_hcd **) hcd->hcd_priv) = xhci; - xhci->main_hcd = hcd; + if (usb_hcd_is_primary_hcd(hcd)) { + xhci = kzalloc(sizeof(struct xhci_hcd), GFP_KERNEL); + if (!xhci) + return -ENOMEM; + *((struct xhci_hcd **) hcd->hcd_priv) = xhci; + xhci->main_hcd = hcd; + /* Mark the first roothub as being USB 2.0. + * The xHCI driver will register the USB 3.0 roothub. + */ + hcd->speed = HCD_USB2; + hcd->self.root_hub->speed = USB_SPEED_HIGH; + /* + * USB 2.0 roothub under xHCI has an integrated TT, + * (rate matching hub) as opposed to having an OHCI/UHCI + * companion controller. + */ + hcd->has_tt = 1; + } else { + /* xHCI private pointer was set in xhci_pci_probe for the second + * registered roothub. + */ + xhci = hcd_to_xhci(hcd); + temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params); + if (HCC_64BIT_ADDR(temp)) { + xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n"); + dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64)); + } else { + dma_set_mask(hcd->self.controller, DMA_BIT_MASK(32)); + } + return 0; + } xhci->cap_regs = hcd->regs; xhci->op_regs = hcd->regs + @@ -128,11 +154,67 @@ error: return retval; } +/* + * We need to register our own PCI probe function (instead of the USB core's + * function) in order to create a second roothub under xHCI. + */ +static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + int retval; + struct xhci_hcd *xhci; + struct hc_driver *driver; + struct usb_hcd *hcd; + + driver = (struct hc_driver *)id->driver_data; + /* Register the USB 2.0 roothub. + * FIXME: USB core must know to register the USB 2.0 roothub first. + * This is sort of silly, because we could just set the HCD driver flags + * to say USB 2.0, but I'm not sure what the implications would be in + * the other parts of the HCD code. + */ + retval = usb_hcd_pci_probe(dev, id); + + if (retval) + return retval; + + /* USB 2.0 roothub is stored in the PCI device now. */ + hcd = dev_get_drvdata(&dev->dev); + xhci = hcd_to_xhci(hcd); + xhci->shared_hcd = usb_create_shared_hcd(driver, &dev->dev, + pci_name(dev), hcd); + if (!xhci->shared_hcd) { + retval = -ENOMEM; + goto dealloc_usb2_hcd; + } + + /* Set the xHCI pointer before xhci_pci_setup() (aka hcd_driver.reset) + * is called by usb_add_hcd(). + */ + *((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci; + + retval = usb_add_hcd(xhci->shared_hcd, dev->irq, + IRQF_DISABLED | IRQF_SHARED); + if (retval) + goto put_usb3_hcd; + /* Roothub already marked as USB 3.0 speed */ + return 0; + +put_usb3_hcd: + usb_put_hcd(xhci->shared_hcd); +dealloc_usb2_hcd: + usb_hcd_pci_remove(dev); + return retval; +} + static void xhci_pci_remove(struct pci_dev *dev) { struct xhci_hcd *xhci; xhci = hcd_to_xhci(pci_get_drvdata(dev)); + if (xhci->shared_hcd) { + usb_remove_hcd(xhci->shared_hcd); + usb_put_hcd(xhci->shared_hcd); + } usb_hcd_pci_remove(dev); kfree(xhci); } @@ -170,7 +252,7 @@ static const struct hc_driver xhci_pci_hc_driver = { * generic hardware linkage */ .irq = xhci_irq, - .flags = HCD_MEMORY | HCD_USB3, + .flags = HCD_MEMORY | HCD_USB3 | HCD_SHARED, /* * basic lifecycle operations @@ -231,7 +313,7 @@ static struct pci_driver xhci_pci_driver = { .name = (char *) hcd_name, .id_table = pci_ids, - .probe = usb_hcd_pci_probe, + .probe = xhci_pci_probe, .remove = xhci_pci_remove, /* suspend and resume implemented later */ diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 7fe9aebd3922..3bdf30dd8ce6 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -866,7 +866,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) } spin_unlock(&xhci->lock); xhci_dbg(xhci, "Calling usb_hc_died()\n"); - usb_hc_died(xhci_to_hcd(xhci)); + usb_hc_died(xhci_to_hcd(xhci)->primary_hcd); xhci_dbg(xhci, "xHCI host controller is dead.\n"); } @@ -1155,20 +1155,56 @@ static void handle_vendor_event(struct xhci_hcd *xhci, handle_cmd_completion(xhci, &event->event_cmd); } +/* @port_id: the one-based port ID from the hardware (indexed from array of all + * port registers -- USB 3.0 and USB 2.0). + * + * Returns a zero-based port number, which is suitable for indexing into each of + * the split roothubs' port arrays and bus state arrays. + */ +static unsigned int find_faked_portnum_from_hw_portnum(struct usb_hcd *hcd, + struct xhci_hcd *xhci, u32 port_id) +{ + unsigned int i; + unsigned int num_similar_speed_ports = 0; + + /* port_id from the hardware is 1-based, but port_array[], usb3_ports[], + * and usb2_ports are 0-based indexes. Count the number of similar + * speed ports, up to 1 port before this port. + */ + for (i = 0; i < (port_id - 1); i++) { + u8 port_speed = xhci->port_array[i]; + + /* + * Skip ports that don't have known speeds, or have duplicate + * Extended Capabilities port speed entries. + */ + if (port_speed == 0 || port_speed == -1) + continue; + + /* + * USB 3.0 ports are always under a USB 3.0 hub. USB 2.0 and + * 1.1 ports are under the USB 2.0 hub. If the port speed + * matches the device speed, it's a similar speed port. + */ + if ((port_speed == 0x03) == (hcd->speed == HCD_USB3)) + num_similar_speed_ports++; + } + return num_similar_speed_ports; +} + static void handle_port_status(struct xhci_hcd *xhci, union xhci_trb *event) { - struct usb_hcd *hcd = xhci_to_hcd(xhci); + struct usb_hcd *hcd; u32 port_id; u32 temp, temp1; int max_ports; int slot_id; unsigned int faked_port_index; - u32 __iomem *port_array[15 + USB_MAXCHILDREN]; - int i; + u8 major_revision; struct xhci_bus_state *bus_state; + u32 __iomem **port_array; - bus_state = &xhci->bus_state[0]; /* Port status change events always have a successful completion code */ if (GET_COMP_CODE(event->generic.field[2]) != COMP_SUCCESS) { xhci_warn(xhci, "WARN: xHC returned failed port status event\n"); @@ -1183,15 +1219,43 @@ static void handle_port_status(struct xhci_hcd *xhci, goto cleanup; } - for (i = 0; i < max_ports; i++) { - if (i < xhci->num_usb3_ports) - port_array[i] = xhci->usb3_ports[i]; - else - port_array[i] = - xhci->usb2_ports[i - xhci->num_usb3_ports]; + /* Figure out which usb_hcd this port is attached to: + * is it a USB 3.0 port or a USB 2.0/1.1 port? + */ + major_revision = xhci->port_array[port_id - 1]; + if (major_revision == 0) { + xhci_warn(xhci, "Event for port %u not in " + "Extended Capabilities, ignoring.\n", + port_id); + goto cleanup; } + if (major_revision == (u8) -1) { + xhci_warn(xhci, "Event for port %u duplicated in" + "Extended Capabilities, ignoring.\n", + port_id); + goto cleanup; + } + + /* + * Hardware port IDs reported by a Port Status Change Event include USB + * 3.0 and USB 2.0 ports. We want to check if the port has reported a + * resume event, but we first need to translate the hardware port ID + * into the index into the ports on the correct split roothub, and the + * correct bus_state structure. + */ + /* Find the right roothub. */ + hcd = xhci_to_hcd(xhci); + if ((major_revision == 0x03) != (hcd->speed == HCD_USB3)) + hcd = xhci->shared_hcd; + bus_state = &xhci->bus_state[hcd_index(hcd)]; + if (hcd->speed == HCD_USB3) + port_array = xhci->usb3_ports; + else + port_array = xhci->usb2_ports; + /* Find the faked port hub number */ + faked_port_index = find_faked_portnum_from_hw_portnum(hcd, xhci, + port_id); - faked_port_index = port_id; temp = xhci_readl(xhci, port_array[faked_port_index]); if (hcd->state == HC_STATE_SUSPENDED) { xhci_dbg(xhci, "resume root hub\n"); @@ -1228,10 +1292,10 @@ static void handle_port_status(struct xhci_hcd *xhci, xhci_writel(xhci, temp, port_array[faked_port_index]); } else { xhci_dbg(xhci, "resume HS port %d\n", port_id); - bus_state->resume_done[port_id - 1] = jiffies + + bus_state->resume_done[faked_port_index] = jiffies + msecs_to_jiffies(20); mod_timer(&hcd->rh_timer, - bus_state->resume_done[port_id - 1]); + bus_state->resume_done[faked_port_index]); /* Do the rest in GetPortStatus */ } } @@ -1242,7 +1306,7 @@ cleanup: spin_unlock(&xhci->lock); /* Pass this up to the core */ - usb_hcd_poll_rh_status(xhci_to_hcd(xhci)); + usb_hcd_poll_rh_status(hcd); spin_lock(&xhci->lock); } diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 8d45bbde3da4..4549068758f5 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -375,6 +375,21 @@ void xhci_event_ring_work(unsigned long arg) } #endif +static int xhci_run_finished(struct xhci_hcd *xhci) +{ + if (xhci_start(xhci)) { + xhci_halt(xhci); + return -ENODEV; + } + xhci->shared_hcd->state = HC_STATE_RUNNING; + + if (xhci->quirks & XHCI_NEC_HOST) + xhci_ring_cmd_db(xhci); + + xhci_dbg(xhci, "Finished xhci_run for USB3 roothub\n"); + return 0; +} + /* * Start the HC after it was halted. * @@ -395,7 +410,13 @@ int xhci_run(struct usb_hcd *hcd) struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); + /* Start the xHCI host controller running only after the USB 2.0 roothub + * is setup. + */ + hcd->uses_new_polling = 1; + if (!usb_hcd_is_primary_hcd(hcd)) + return xhci_run_finished(xhci); xhci_dbg(xhci, "xhci_run\n"); /* unregister the legacy interrupt */ @@ -469,16 +490,23 @@ int xhci_run(struct usb_hcd *hcd) xhci_queue_vendor_command(xhci, 0, 0, 0, TRB_TYPE(TRB_NEC_GET_FW)); - if (xhci_start(xhci)) { - xhci_halt(xhci); - return -ENODEV; - } + xhci_dbg(xhci, "Finished xhci_run for USB2 roothub\n"); + return 0; +} - if (xhci->quirks & XHCI_NEC_HOST) - xhci_ring_cmd_db(xhci); +static void xhci_only_stop_hcd(struct usb_hcd *hcd) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); - xhci_dbg(xhci, "Finished xhci_run\n"); - return 0; + spin_lock_irq(&xhci->lock); + xhci_halt(xhci); + + /* The shared_hcd is going to be deallocated shortly (the USB core only + * calls this function when allocation fails in usb_add_hcd(), or + * usb_remove_hcd() is called). So we need to unset xHCI's pointer. + */ + xhci->shared_hcd = NULL; + spin_unlock_irq(&xhci->lock); } /* @@ -495,7 +523,15 @@ void xhci_stop(struct usb_hcd *hcd) u32 temp; struct xhci_hcd *xhci = hcd_to_xhci(hcd); + if (!usb_hcd_is_primary_hcd(hcd)) { + xhci_only_stop_hcd(xhci->shared_hcd); + return; + } + spin_lock_irq(&xhci->lock); + /* Make sure the xHC is halted for a USB3 roothub + * (xhci_stop() could be called as part of failed init). + */ xhci_halt(xhci); xhci_reset(xhci); spin_unlock_irq(&xhci->lock); @@ -528,6 +564,8 @@ void xhci_stop(struct usb_hcd *hcd) * This is called when the machine is rebooting or halting. We assume that the * machine will be powered off, and the HC's internal state will be reset. * Don't bother to free memory. + * + * This will only ever be called with the main usb_hcd (the USB3 roothub). */ void xhci_shutdown(struct usb_hcd *hcd) { @@ -694,10 +732,12 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) struct usb_hcd *hcd = xhci_to_hcd(xhci); int retval; - /* Wait a bit if the bus needs to settle from the transistion to - * suspend. + /* Wait a bit if either of the roothubs need to settle from the + * transistion into bus suspend. */ - if (time_before(jiffies, xhci->bus_state[0].next_statechange)) + if (time_before(jiffies, xhci->bus_state[0].next_statechange) || + time_before(jiffies, + xhci->bus_state[1].next_statechange)) msleep(100); spin_lock_irq(&xhci->lock); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 443d6333f280..e9217bb288ad 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1174,12 +1174,16 @@ struct xhci_bus_state { static inline unsigned int hcd_index(struct usb_hcd *hcd) { - return 0; + if (hcd->speed == HCD_USB3) + return 0; + else + return 1; } /* There is one ehci_hci structure per controller */ struct xhci_hcd { struct usb_hcd *main_hcd; + struct usb_hcd *shared_hcd; /* glue to PCI and HCD framework */ struct xhci_cap_regs __iomem *cap_regs; struct xhci_op_regs __iomem *op_regs; @@ -1262,10 +1266,8 @@ struct xhci_hcd { #define XHCI_LINK_TRB_QUIRK (1 << 0) #define XHCI_RESET_EP_QUIRK (1 << 1) #define XHCI_NEC_HOST (1 << 2) - /* There's only one roothub to keep track of bus suspend info for - * (right now). - */ - struct xhci_bus_state bus_state[1]; + /* There are two roothubs to keep track of bus suspend info for */ + struct xhci_bus_state bus_state[2]; /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */ u8 *port_array; /* Array of pointers to USB 3.0 PORTSC registers */ -- cgit v1.2.3 From 4bbb0ace9a3de8392527e3c87926309d541d3b00 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Mon, 29 Nov 2010 16:14:37 -0800 Subject: xhci: Return a USB 3.0 hub descriptor for USB3 roothub. Return the correct xHCI roothub descriptor, based on whether the roothub is marked as USB 3.0 or USB 2.0 in usb_hcd->bcdUSB. Fill in DeviceRemovable for the USB 2.0 and USB 3.0 roothub descriptors, using the Device Removable bit in the port status and control registers. xHCI is the first host controller to actually properly set these bits (other hosts say all devices are removable). When userspace asks for a USB 2.0-style hub descriptor for the USB 3.0 roothub, stall the endpoint. This is what real external USB 3.0 hubs do, and we don't want to return a descriptor that userspace didn't ask for. The USB core is already fixed to always ask for USB 3.0-style hub descriptors. Only usbfs (typically lsusb) will ask for the USB 2.0-style hub descriptors. This has already been fixed in usbutils version 0.91, but the kernel needs to deal with older usbutils versions. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-hub.c | 134 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 114 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index ee4af076a8fe..191ebc54cc7d 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -28,33 +28,15 @@ #define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_WRC | PORT_OCC | \ PORT_RC | PORT_PLC | PORT_PE) -static void xhci_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci, - struct usb_hub_descriptor *desc) +static void xhci_common_hub_descriptor(struct xhci_hcd *xhci, + struct usb_hub_descriptor *desc, int ports) { - int ports; u16 temp; - if (hcd->speed == HCD_USB3) - ports = xhci->num_usb3_ports; - else - ports = xhci->num_usb2_ports; - - /* FIXME: return a USB 3.0 hub descriptor if this request was for the - * USB3 roothub. - */ - - /* USB 3.0 hubs have a different descriptor, but we fake this for now */ - desc->bDescriptorType = 0x29; desc->bPwrOn2PwrGood = 10; /* xhci section 5.4.9 says 20ms max */ desc->bHubContrCurrent = 0; desc->bNbrPorts = ports; - temp = 1 + (ports / 8); - desc->bDescLength = 7 + 2 * temp; - - memset(&desc->u.hs.DeviceRemovable[0], 0, temp); - memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp); - /* Ugh, these should be #defines, FIXME */ /* Using table 11-13 in USB 2.0 spec. */ temp = 0; @@ -71,6 +53,102 @@ static void xhci_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci, desc->wHubCharacteristics = (__force __u16) cpu_to_le16(temp); } +/* Fill in the USB 2.0 roothub descriptor */ +static void xhci_usb2_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci, + struct usb_hub_descriptor *desc) +{ + int ports; + u16 temp; + __u8 port_removable[(USB_MAXCHILDREN + 1 + 7) / 8]; + u32 portsc; + unsigned int i; + + ports = xhci->num_usb2_ports; + + xhci_common_hub_descriptor(xhci, desc, ports); + desc->bDescriptorType = 0x29; + temp = 1 + (ports / 8); + desc->bDescLength = 7 + 2 * temp; + + /* The Device Removable bits are reported on a byte granularity. + * If the port doesn't exist within that byte, the bit is set to 0. + */ + memset(port_removable, 0, sizeof(port_removable)); + for (i = 0; i < ports; i++) { + portsc = xhci_readl(xhci, xhci->usb3_ports[i]); + /* If a device is removable, PORTSC reports a 0, same as in the + * hub descriptor DeviceRemovable bits. + */ + if (portsc & PORT_DEV_REMOVE) + /* This math is hairy because bit 0 of DeviceRemovable + * is reserved, and bit 1 is for port 1, etc. + */ + port_removable[(i + 1) / 8] |= 1 << ((i + 1) % 8); + } + + /* ch11.h defines a hub descriptor that has room for USB_MAXCHILDREN + * ports on it. The USB 2.0 specification says that there are two + * variable length fields at the end of the hub descriptor: + * DeviceRemovable and PortPwrCtrlMask. But since we can have less than + * USB_MAXCHILDREN ports, we may need to use the DeviceRemovable array + * to set PortPwrCtrlMask bits. PortPwrCtrlMask must always be set to + * 0xFF, so we initialize the both arrays (DeviceRemovable and + * PortPwrCtrlMask) to 0xFF. Then we set the DeviceRemovable for each + * set of ports that actually exist. + */ + memset(desc->u.hs.DeviceRemovable, 0xff, + sizeof(desc->u.hs.DeviceRemovable)); + memset(desc->u.hs.PortPwrCtrlMask, 0xff, + sizeof(desc->u.hs.PortPwrCtrlMask)); + + for (i = 0; i < (ports + 1 + 7) / 8; i++) + memset(&desc->u.hs.DeviceRemovable[i], port_removable[i], + sizeof(__u8)); +} + +/* Fill in the USB 3.0 roothub descriptor */ +static void xhci_usb3_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci, + struct usb_hub_descriptor *desc) +{ + int ports; + u16 port_removable; + u32 portsc; + unsigned int i; + + ports = xhci->num_usb3_ports; + xhci_common_hub_descriptor(xhci, desc, ports); + desc->bDescriptorType = 0x2a; + desc->bDescLength = 12; + + /* header decode latency should be zero for roothubs, + * see section 4.23.5.2. + */ + desc->u.ss.bHubHdrDecLat = 0; + desc->u.ss.wHubDelay = 0; + + port_removable = 0; + /* bit 0 is reserved, bit 1 is for port 1, etc. */ + for (i = 0; i < ports; i++) { + portsc = xhci_readl(xhci, xhci->usb3_ports[i]); + if (portsc & PORT_DEV_REMOVE) + port_removable |= 1 << (i + 1); + } + memset(&desc->u.ss.DeviceRemovable, + (__force __u16) cpu_to_le16(port_removable), + sizeof(__u16)); +} + +static void xhci_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci, + struct usb_hub_descriptor *desc) +{ + + if (hcd->speed == HCD_USB3) + xhci_usb3_hub_descriptor(hcd, xhci, desc); + else + xhci_usb2_hub_descriptor(hcd, xhci, desc); + +} + static unsigned int xhci_port_speed(unsigned int port_status) { if (DEV_LOWSPEED(port_status)) @@ -320,6 +398,17 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, memset(buf, 0, 4); break; case GetHubDescriptor: + /* Check to make sure userspace is asking for the USB 3.0 hub + * descriptor for the USB 3.0 roothub. If not, we stall the + * endpoint, like external hubs do. + */ + if (hcd->speed == HCD_USB3 && + (wLength < USB_DT_SS_HUB_SIZE || + wValue != (USB_DT_SS_HUB << 8))) { + xhci_dbg(xhci, "Wrong hub descriptor type for " + "USB 3.0 roothub.\n"); + goto error; + } xhci_hub_descriptor(hcd, xhci, (struct usb_hub_descriptor *) buf); break; @@ -331,6 +420,9 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, temp = xhci_readl(xhci, port_array[wIndex]); xhci_dbg(xhci, "get port status, actual port %d status = 0x%x\n", wIndex, temp); + /* FIXME - should we return a port status value like the USB + * 3.0 external hubs do? + */ /* wPortChange bits */ if (temp & PORT_CSC) status |= USB_PORT_STAT_C_CONNECTION << 16; @@ -401,6 +493,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, wIndex--; temp = xhci_readl(xhci, port_array[wIndex]); temp = xhci_port_state_to_neutral(temp); + /* FIXME: What new port features do we need to support? */ switch (wValue) { case USB_PORT_FEAT_SUSPEND: temp = xhci_readl(xhci, port_array[wIndex]); @@ -469,6 +562,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, goto error; wIndex--; temp = xhci_readl(xhci, port_array[wIndex]); + /* FIXME: What new port features do we need to support? */ temp = xhci_port_state_to_neutral(temp); switch (wValue) { case USB_PORT_FEAT_SUSPEND: -- cgit v1.2.3 From d30b2a208108a0b0fdeae7006b8824d9be16ca96 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Tue, 23 Nov 2010 10:42:22 -0800 Subject: xhci: Limit roothub ports to 15 USB3 & 31 USB2 ports. The USB core allocates a USB 2.0 roothub descriptor that has room for 31 (USB_MAXCHILDREN) ports' worth of DeviceRemovable and PortPwrCtrlMask fields. Limit the number of USB 2.0 roothub ports accordingly. I don't expect to run into this limitation ever, but this prevents a buffer overflow issue in the roothub descriptor filling code. Similarly, a USB 3.0 hub can only have 15 downstream ports, so limit the USB 3.0 roothub to 15 USB 3.0 ports. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-mem.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 180a2abbc868..71fd8bd287fe 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1803,6 +1803,20 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) } xhci_dbg(xhci, "Found %u USB 2.0 ports and %u USB 3.0 ports.\n", xhci->num_usb2_ports, xhci->num_usb3_ports); + + /* Place limits on the number of roothub ports so that the hub + * descriptors aren't longer than the USB core will allocate. + */ + if (xhci->num_usb3_ports > 15) { + xhci_dbg(xhci, "Limiting USB 3.0 roothub ports to 15.\n"); + xhci->num_usb3_ports = 15; + } + if (xhci->num_usb2_ports > USB_MAXCHILDREN) { + xhci_dbg(xhci, "Limiting USB 2.0 roothub ports to %u.\n", + USB_MAXCHILDREN); + xhci->num_usb2_ports = USB_MAXCHILDREN; + } + /* * Note we could have all USB 3.0 ports, or all USB 2.0 ports. * Not sure how the USB core will handle a hub with no ports... @@ -1827,6 +1841,8 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) "addr = %p\n", i, xhci->usb2_ports[port_index]); port_index++; + if (port_index == xhci->num_usb2_ports) + break; } } if (xhci->num_usb3_ports) { @@ -1845,6 +1861,8 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) "addr = %p\n", i, xhci->usb3_ports[port_index]); port_index++; + if (port_index == xhci->num_usb3_ports) + break; } } return 0; -- cgit v1.2.3 From f9de8151877b4f01cc8e124b0e213a6c6c78d970 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 29 Oct 2010 14:37:23 -0700 Subject: xhci: Make roothub functions deal with device removal. Return early in the roothub control and status functions if the xHCI host controller is not electrically present in the system (register reads return all "fs"). This issue only shows up when the xHCI driver registers two roothubs and the host controller is removed from the system. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-hub.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 191ebc54cc7d..770f84cb7327 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -418,6 +418,10 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, wIndex--; status = 0; temp = xhci_readl(xhci, port_array[wIndex]); + if (temp == 0xffffffff) { + retval = -ENODEV; + break; + } xhci_dbg(xhci, "get port status, actual port %d status = 0x%x\n", wIndex, temp); /* FIXME - should we return a port status value like the USB @@ -492,6 +496,10 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, goto error; wIndex--; temp = xhci_readl(xhci, port_array[wIndex]); + if (temp == 0xffffffff) { + retval = -ENODEV; + break; + } temp = xhci_port_state_to_neutral(temp); /* FIXME: What new port features do we need to support? */ switch (wValue) { @@ -562,6 +570,10 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, goto error; wIndex--; temp = xhci_readl(xhci, port_array[wIndex]); + if (temp == 0xffffffff) { + retval = -ENODEV; + break; + } /* FIXME: What new port features do we need to support? */ temp = xhci_port_state_to_neutral(temp); switch (wValue) { @@ -677,6 +689,10 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) /* For each port, did anything change? If so, set that bit in buf. */ for (i = 0; i < ports; i++) { temp = xhci_readl(xhci, port_array[i]); + if (temp == 0xffffffff) { + retval = -ENODEV; + break; + } if ((temp & mask) != 0 || (bus_state->port_c_suspend & 1 << i) || (bus_state->resume_done[i] && time_after_eq( -- cgit v1.2.3 From 65b22f93fde320b34d43e4a3978e1b52b1bcc279 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 17 Dec 2010 12:35:05 -0800 Subject: xhci: Fix re-init on power loss after resume. When a host controller has lost power during a suspend, we must reinitialize it. Now that the xHCI host has two roothubs, xhci_run() and xhci_stop() expect to be called with both usb_hcd structures. Be sure that the re-initialization code in xhci_resume() mirrors the process the USB PCI probe function uses. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 4549068758f5..ce024dc7116f 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -730,6 +730,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) { u32 command, temp = 0; struct usb_hcd *hcd = xhci_to_hcd(xhci); + struct usb_hcd *secondary_hcd; int retval; /* Wait a bit if either of the roothubs need to settle from the @@ -790,15 +791,29 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) xhci_dbg(xhci, "xhci_stop completed - status = %x\n", xhci_readl(xhci, &xhci->op_regs->status)); - xhci_dbg(xhci, "Initialize the HCD\n"); - retval = xhci_init(hcd); + /* USB core calls the PCI reinit and start functions twice: + * first with the primary HCD, and then with the secondary HCD. + * If we don't do the same, the host will never be started. + */ + if (!usb_hcd_is_primary_hcd(hcd)) + secondary_hcd = hcd; + else + secondary_hcd = xhci->shared_hcd; + + xhci_dbg(xhci, "Initialize the xhci_hcd\n"); + retval = xhci_init(hcd->primary_hcd); if (retval) return retval; + xhci_dbg(xhci, "Start the primary HCD\n"); + retval = xhci_run(hcd->primary_hcd); + if (retval) + goto failed_restart; - xhci_dbg(xhci, "Start the HCD\n"); - retval = xhci_run(hcd); + xhci_dbg(xhci, "Start the secondary HCD\n"); + retval = xhci_run(secondary_hcd); if (!retval) set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); +failed_restart: hcd->state = HC_STATE_SUSPENDED; return retval; } -- cgit v1.2.3 From b320937972d456db2a46fdcbc6bebc4dcdc9daa4 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Mon, 7 Mar 2011 11:24:07 -0800 Subject: xhci: Fixes for suspend/resume of shared HCDs. Make sure the HCD_FLAG_HW_ACCESSIBLE flag is mirrored by both roothubs, since it refers to whether the shared hardware is accessible. Make sure each bus is marked as suspended by setting usb_hcd->state to HC_STATE_SUSPENDED when the PCI host controller is resumed. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-pci.c | 3 ++- drivers/usb/host/xhci-ring.c | 6 ++++-- drivers/usb/host/xhci.c | 8 +++++++- 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 4a9d55e80f73..ceea9f33491c 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -225,7 +225,8 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) struct xhci_hcd *xhci = hcd_to_xhci(hcd); int retval = 0; - if (hcd->state != HC_STATE_SUSPENDED) + if (hcd->state != HC_STATE_SUSPENDED || + xhci->shared_hcd->state != HC_STATE_SUSPENDED) return -EINVAL; retval = xhci_suspend(xhci); diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 3bdf30dd8ce6..bd0f2343ef9c 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2256,10 +2256,12 @@ hw_died: irqreturn_t xhci_msi_irq(int irq, struct usb_hcd *hcd) { irqreturn_t ret; + struct xhci_hcd *xhci; + xhci = hcd_to_xhci(hcd); set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); - if (hcd->shared_hcd) - set_bit(HCD_FLAG_SAW_IRQ, &hcd->shared_hcd->flags); + if (xhci->shared_hcd) + set_bit(HCD_FLAG_SAW_IRQ, &xhci->shared_hcd->flags); ret = xhci_irq(hcd); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index ce024dc7116f..238ebe158b83 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -681,6 +681,7 @@ int xhci_suspend(struct xhci_hcd *xhci) spin_lock_irq(&xhci->lock); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); /* step 1: stop endpoint */ /* skipped assuming that port suspend has done */ @@ -811,10 +812,14 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) xhci_dbg(xhci, "Start the secondary HCD\n"); retval = xhci_run(secondary_hcd); - if (!retval) + if (!retval) { set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + set_bit(HCD_FLAG_HW_ACCESSIBLE, + &xhci->shared_hcd->flags); + } failed_restart: hcd->state = HC_STATE_SUSPENDED; + xhci->shared_hcd->state = HC_STATE_SUSPENDED; return retval; } @@ -835,6 +840,7 @@ failed_restart: */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); spin_unlock_irq(&xhci->lock); return 0; -- cgit v1.2.3 From c6cc27c782e3a64cced0fcf1d6f492c8d8881c76 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 11 Mar 2011 10:20:58 -0800 Subject: xhci: Return canceled URBs immediately when host is halted. When the xHCI host controller is halted, it won't respond to commands placed on the command ring. So if an URB is cancelled after the first roothub is deallocated, it will try to place a stop endpoint command on the command ring, which will fail. The command watchdog timer will fire after five seconds, and the host controller will be marked as dying, and all URBs will be completed. Add a flag to the xHCI's internal state variable for when the host controller is halted. Immediately return the canceled URB if the host controller is halted. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci.c | 10 ++++++++-- drivers/usb/host/xhci.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 238ebe158b83..2c11411ca5f5 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -98,11 +98,15 @@ void xhci_quiesce(struct xhci_hcd *xhci) */ int xhci_halt(struct xhci_hcd *xhci) { + int ret; xhci_dbg(xhci, "// Halt the HC\n"); xhci_quiesce(xhci); - return handshake(xhci, &xhci->op_regs->status, + ret = handshake(xhci, &xhci->op_regs->status, STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); + if (!ret) + xhci->xhc_state |= XHCI_STATE_HALTED; + return ret; } /* @@ -129,6 +133,8 @@ int xhci_start(struct xhci_hcd *xhci) xhci_err(xhci, "Host took too long to start, " "waited %u microseconds.\n", XHCI_MAX_HALT_USEC); + if (!ret) + xhci->xhc_state &= ~XHCI_STATE_HALTED; return ret; } @@ -1212,7 +1218,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) if (ret || !urb->hcpriv) goto done; temp = xhci_readl(xhci, &xhci->op_regs->status); - if (temp == 0xffffffff) { + if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) { xhci_dbg(xhci, "HW died, freeing TD.\n"); urb_priv = urb->hcpriv; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index e9217bb288ad..e69f1cdf4b5b 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1260,6 +1260,7 @@ struct xhci_hcd { * There are no reports of xHCI host controllers that display this issue. */ #define XHCI_STATE_DYING (1 << 0) +#define XHCI_STATE_HALTED (1 << 1) /* Statistics */ int error_bitmask; unsigned int quirks; -- cgit v1.2.3 From 131dec344d5e41f01e4791aa4c80eb4bdb1e5274 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Mon, 6 Dec 2010 21:00:19 -0800 Subject: USB: Remove bogus USB_PORT_STAT_SUPER_SPEED symbol. USB_PORT_STAT_SUPER_SPEED is a made up symbol that the USB core used to track whether USB ports had a SuperSpeed device attached. This is a linux-internal symbol that was used when SuperSpeed and non-SuperSpeed devices would show up under the same xHCI roothub. This particular port status is never returned by external USB 3.0 hubs. (Instead they have a USB_PORT_STAT_SPEED_5GBPS that uses a completely different speed mask.) Now that the xHCI driver registers two roothubs, USB 3.0 devices will only show up under USB 3.0 hubs. Rip out USB_PORT_STAT_SUPER_SPEED and replace it with calls to hub_is_superspeed(). Signed-off-by: Sarah Sharp --- drivers/usb/core/hub.c | 36 ++++++++---------------------------- drivers/usb/host/xhci-hub.c | 2 -- include/linux/usb/ch11.h | 1 - 3 files changed, 8 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 825d803720b3..13aafd1b45e5 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -155,14 +155,14 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem); static int usb_reset_and_verify_device(struct usb_device *udev); -static inline char *portspeed(int portstatus) +static inline char *portspeed(struct usb_hub *hub, int portstatus) { + if (hub_is_superspeed(hub->hdev)) + return "5.0 Gb/s"; if (portstatus & USB_PORT_STAT_HIGH_SPEED) return "480 Mb/s"; else if (portstatus & USB_PORT_STAT_LOW_SPEED) return "1.5 Mb/s"; - else if (portstatus & USB_PORT_STAT_SUPER_SPEED) - return "5.0 Gb/s"; else return "12 Mb/s"; } @@ -385,9 +385,6 @@ static int hub_port_status(struct usb_hub *hub, int port1, u16 tmp = *status & USB_SS_PORT_STAT_MASK; if (*status & USB_SS_PORT_STAT_POWER) tmp |= USB_PORT_STAT_POWER; - if ((*status & USB_SS_PORT_STAT_SPEED) == - USB_PORT_STAT_SPEED_5GBPS) - tmp |= USB_PORT_STAT_SUPER_SPEED; *status = tmp; } @@ -795,12 +792,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) * USB3 protocol ports will automatically transition * to Enabled state when detect an USB3.0 device attach. * Do not disable USB3 protocol ports. - * FIXME: USB3 root hub and external hubs are treated - * differently here. */ - if (hdev->descriptor.bDeviceProtocol != 3 || - (!hdev->parent && - !(portstatus & USB_PORT_STAT_SUPER_SPEED))) { + if (!hub_is_superspeed(hdev)) { clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE); portstatus &= ~USB_PORT_STAT_ENABLE; @@ -2067,14 +2060,12 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, (portstatus & USB_PORT_STAT_ENABLE)) { if (hub_is_wusb(hub)) udev->speed = USB_SPEED_WIRELESS; - else if (portstatus & USB_PORT_STAT_SUPER_SPEED) + else if (hub_is_superspeed(hub->hdev)) udev->speed = USB_SPEED_SUPER; else if (portstatus & USB_PORT_STAT_HIGH_SPEED) udev->speed = USB_SPEED_HIGH; else if (portstatus & USB_PORT_STAT_LOW_SPEED) udev->speed = USB_SPEED_LOW; - else if (portstatus & USB_PORT_STAT_SUPER_SPEED) - udev->speed = USB_SPEED_SUPER; else udev->speed = USB_SPEED_FULL; return 0; @@ -3067,7 +3058,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, dev_dbg (hub_dev, "port %d, status %04x, change %04x, %s\n", - port1, portstatus, portchange, portspeed (portstatus)); + port1, portstatus, portchange, portspeed(hub, portstatus)); if (hub->has_indicators) { set_port_led(hub, port1, HUB_LED_AUTO); @@ -3168,19 +3159,8 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, udev->level = hdev->level + 1; udev->wusb = hub_is_wusb(hub); - /* - * USB 3.0 devices are reset automatically before the connect - * port status change appears, and the root hub port status - * shows the correct speed. We also get port change - * notifications for USB 3.0 devices from the USB 3.0 portion of - * an external USB 3.0 hub, but this isn't handled correctly yet - * FIXME. - */ - - if (!(hcd->driver->flags & HCD_USB3)) - udev->speed = USB_SPEED_UNKNOWN; - else if ((hdev->parent == NULL) && - (portstatus & USB_PORT_STAT_SUPER_SPEED)) + /* Only USB 3.0 devices are connected to SuperSpeed hubs. */ + if (hub_is_superspeed(hub->hdev)) udev->speed = USB_SPEED_SUPER; else udev->speed = USB_SPEED_UNKNOWN; diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 770f84cb7327..a78f2ebd11b7 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -155,8 +155,6 @@ static unsigned int xhci_port_speed(unsigned int port_status) return USB_PORT_STAT_LOW_SPEED; if (DEV_HIGHSPEED(port_status)) return USB_PORT_STAT_HIGH_SPEED; - if (DEV_SUPERSPEED(port_status)) - return USB_PORT_STAT_SUPER_SPEED; /* * FIXME: Yes, we should check for full speed, but the core uses that as * a default in portspeed() in usb/core/hub.c (which is the only place diff --git a/include/linux/usb/ch11.h b/include/linux/usb/ch11.h index 22afcd37bc3f..4ebaf0824179 100644 --- a/include/linux/usb/ch11.h +++ b/include/linux/usb/ch11.h @@ -109,7 +109,6 @@ struct usb_port_status { #define USB_PORT_STAT_TEST 0x0800 #define USB_PORT_STAT_INDICATOR 0x1000 /* bits 13 to 15 are reserved */ -#define USB_PORT_STAT_SUPER_SPEED 0x8000 /* Linux-internal */ /* * Additions to wPortStatus bit field from USB 3.0 -- cgit v1.2.3 From 0c9ffe0f6286a02bf82f8d7fb7274aec2ad977f1 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 30 Dec 2010 13:27:36 -0800 Subject: USB: Disable auto-suspend for USB 3.0 hubs. USB 3.0 devices have a slightly different suspend sequence than USB 2.0/1.1 devices. There isn't support for USB 3.0 device suspend yet, so make khubd leave autosuspend disabled for USB 3.0 hubs. Make sure that USB 3.0 roothubs still have autosuspend enabled, since that path in the xHCI driver works fine. Signed-off-by: Sarah Sharp --- drivers/usb/core/hub.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 13aafd1b45e5..0968157f3beb 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1290,8 +1290,14 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) desc = intf->cur_altsetting; hdev = interface_to_usbdev(intf); - /* Hubs have proper suspend/resume support */ - usb_enable_autosuspend(hdev); + /* Hubs have proper suspend/resume support. USB 3.0 device suspend is + * different from USB 2.0/1.1 device suspend, and unfortunately we + * don't support it yet. So leave autosuspend disabled for USB 3.0 + * external hubs for now. Enable autosuspend for USB 3.0 roothubs, + * since that isn't a "real" hub. + */ + if (!hub_is_superspeed(hdev) || !hdev->parent) + usb_enable_autosuspend(hdev); if (hdev->level == MAX_TOPO_LEVEL) { dev_err(&intf->dev, -- cgit v1.2.3 From bf161e85fb153c0dd5a95faca73fd6a9d237c389 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Wed, 23 Feb 2011 15:46:42 -0800 Subject: xhci: Update internal dequeue pointers after stalls. When an endpoint stalls, the xHCI driver must move the endpoint ring's dequeue pointer past the stalled transfer. To do that, the driver issues a Set TR Dequeue Pointer command, which will complete some time later. Takashi was having issues with USB 1.1 audio devices that stalled, and his analysis of the code was that the old code would not update the xHCI driver's ring dequeue pointer after the command completes. However, the dequeue pointer is set in xhci_find_new_dequeue_state(), just before the set command is issued to the hardware. Setting the dequeue pointer before the Set TR Dequeue Pointer command completes is a dangerous thing to do, since the xHCI hardware can fail the command. Instead, store the new dequeue pointer in the xhci_virt_ep structure, and update the ring's dequeue pointer when the Set TR dequeue pointer command completes. While we're at it, make sure we can't queue another Set TR Dequeue Command while the first one is still being processed. This just won't work with the internal xHCI state code. I'm still not sure if this is the right thing to do, since we might have a case where a driver queues multiple URBs to a control ring, one of the URBs Stalls, and then the driver tries to cancel the second URB. There may be a race condition there where the xHCI driver might try to issue multiple Set TR Dequeue Pointer commands, but I would have to think very hard about how the Stop Endpoint and cancellation code works. Keep the fix simple until when/if we run into that case. This patch should be queued to kernels all the way back to 2.6.31. Signed-off-by: Sarah Sharp Tested-by: Takashi Iwai Cc: stable@kernel.org --- drivers/usb/host/xhci-ring.c | 29 ++++++++++++++++++++++++++--- drivers/usb/host/xhci.h | 9 +++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index bd0f2343ef9c..3577cd663ebc 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -501,9 +501,6 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, addr = xhci_trb_virt_to_dma(state->new_deq_seg, state->new_deq_ptr); xhci_dbg(xhci, "New dequeue pointer = 0x%llx (DMA)\n", (unsigned long long) addr); - xhci_dbg(xhci, "Setting dequeue pointer in internal ring state.\n"); - ep_ring->dequeue = state->new_deq_ptr; - ep_ring->deq_seg = state->new_deq_seg; } static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, @@ -945,9 +942,26 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci, } else { xhci_dbg(xhci, "Successful Set TR Deq Ptr cmd, deq = @%08llx\n", ep_ctx->deq); + if (xhci_trb_virt_to_dma(dev->eps[ep_index].queued_deq_seg, + dev->eps[ep_index].queued_deq_ptr) == + (ep_ctx->deq & ~(EP_CTX_CYCLE_MASK))) { + /* Update the ring's dequeue segment and dequeue pointer + * to reflect the new position. + */ + ep_ring->deq_seg = dev->eps[ep_index].queued_deq_seg; + ep_ring->dequeue = dev->eps[ep_index].queued_deq_ptr; + } else { + xhci_warn(xhci, "Mismatch between completed Set TR Deq " + "Ptr command & xHCI internal state.\n"); + xhci_warn(xhci, "ep deq seg = %p, deq ptr = %p\n", + dev->eps[ep_index].queued_deq_seg, + dev->eps[ep_index].queued_deq_ptr); + } } dev->eps[ep_index].ep_state &= ~SET_DEQ_PENDING; + dev->eps[ep_index].queued_deq_seg = NULL; + dev->eps[ep_index].queued_deq_ptr = NULL; /* Restart any rings with pending URBs */ ring_doorbell_for_active_rings(xhci, slot_id, ep_index); } @@ -3283,6 +3297,7 @@ static int queue_set_tr_deq(struct xhci_hcd *xhci, int slot_id, u32 trb_ep_index = EP_ID_FOR_TRB(ep_index); u32 trb_stream_id = STREAM_ID_FOR_TRB(stream_id); u32 type = TRB_TYPE(TRB_SET_DEQ); + struct xhci_virt_ep *ep; addr = xhci_trb_virt_to_dma(deq_seg, deq_ptr); if (addr == 0) { @@ -3291,6 +3306,14 @@ static int queue_set_tr_deq(struct xhci_hcd *xhci, int slot_id, deq_seg, deq_ptr); return 0; } + ep = &xhci->devs[slot_id]->eps[ep_index]; + if ((ep->ep_state & SET_DEQ_PENDING)) { + xhci_warn(xhci, "WARN Cannot submit Set TR Deq Ptr\n"); + xhci_warn(xhci, "A Set TR Deq Ptr command is pending.\n"); + return 0; + } + ep->queued_deq_seg = deq_seg; + ep->queued_deq_ptr = deq_ptr; return queue_command(xhci, lower_32_bits(addr) | cycle_state, upper_32_bits(addr), trb_stream_id, trb_slot_id | trb_ep_index | type, false); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index e69f1cdf4b5b..7aca6b16e986 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -644,6 +644,9 @@ struct xhci_ep_ctx { #define AVG_TRB_LENGTH_FOR_EP(p) ((p) & 0xffff) #define MAX_ESIT_PAYLOAD_FOR_EP(p) (((p) & 0xffff) << 16) +/* deq bitmasks */ +#define EP_CTX_CYCLE_MASK (1 << 0) + /** * struct xhci_input_control_context @@ -746,6 +749,12 @@ struct xhci_virt_ep { struct timer_list stop_cmd_timer; int stop_cmds_pending; struct xhci_hcd *xhci; + /* Dequeue pointer and dequeue segment for a submitted Set TR Dequeue + * command. We'll need to update the ring's dequeue segment and dequeue + * pointer after the command completes. + */ + struct xhci_segment *queued_deq_seg; + union xhci_trb *queued_deq_ptr; /* * Sometimes the xHC can not process isochronous endpoint ring quickly * enough, and it will miss some isoc tds on the ring and generate -- cgit v1.2.3 From 01a1fdb9a7afa5e3c14c9316d6f380732750b4e4 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Wed, 23 Feb 2011 18:12:29 -0800 Subject: xhci: Fix cycle bit calculation during stall handling. When an endpoint stalls, we need to update the xHCI host's internal dequeue pointer to move it past the stalled transfer. This includes updating the cycle bit (TRB ownership bit) if we have moved the dequeue pointer past a link TRB with the toggle cycle bit set. When we're trying to find the new dequeue segment, find_trb_seg() is supposed to keep track of whether we've passed any link TRBs with the toggle cycle bit set. However, this while loop's body while (cur_seg->trbs > trb || &cur_seg->trbs[TRBS_PER_SEGMENT - 1] < trb) { Will never get executed if the ring only contains one segment. find_trb_seg() will return immediately, without updating the new cycle bit. Since find_trb_seg() has no idea where in the segment the TD that stalled was, make the caller, xhci_find_new_dequeue_state(), check for this special case and update the cycle bit accordingly. This patch should be queued to kernels all the way back to 2.6.31. Signed-off-by: Sarah Sharp Tested-by: Takashi Iwai Cc: stable@kernel.org --- drivers/usb/host/xhci-ring.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 3577cd663ebc..cf86eb70a62e 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -495,6 +495,20 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, state->new_cycle_state = ~(state->new_cycle_state) & 0x1; next_trb(xhci, ep_ring, &state->new_deq_seg, &state->new_deq_ptr); + /* + * If there is only one segment in a ring, find_trb_seg()'s while loop + * will not run, and it will return before it has a chance to see if it + * needs to toggle the cycle bit. It can't tell if the stalled transfer + * ended just before the link TRB on a one-segment ring, or if the TD + * wrapped around the top of the ring, because it doesn't have the TD in + * question. Look for the one-segment case where stalled TRB's address + * is greater than the new dequeue pointer address. + */ + if (ep_ring->first_seg == ep_ring->first_seg->next && + state->new_deq_ptr < dev->eps[ep_index].stopped_trb) + state->new_cycle_state ^= 0x1; + xhci_dbg(xhci, "Cycle state = 0x%x\n", state->new_cycle_state); + /* Don't update the ring cycle state for the producer (us). */ xhci_dbg(xhci, "New dequeue segment = %p (virtual)\n", state->new_deq_seg); -- cgit v1.2.3 From ba0a4d9aaae789a6a632968b27c21d49b858b13a Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Wed, 23 Feb 2011 18:13:43 -0800 Subject: xhci: Clean up cycle bit math used during stalls. Use XOR to invert the cycle bit, instead of a more complicated calculation. Eliminate a check for the link TRB type in find_trb_seg(). We know that there will always be a link TRB at the end of a segment, so xhci_segment->trbs[TRBS_PER_SEGMENT - 1] will always have a link TRB type. Signed-off-by: Sarah Sharp Tested-by: Takashi Iwai --- drivers/usb/host/xhci-ring.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index cf86eb70a62e..032af7e8a6bf 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -380,10 +380,8 @@ static struct xhci_segment *find_trb_seg( while (cur_seg->trbs > trb || &cur_seg->trbs[TRBS_PER_SEGMENT - 1] < trb) { generic_trb = &cur_seg->trbs[TRBS_PER_SEGMENT - 1].generic; - if ((generic_trb->field[3] & TRB_TYPE_BITMASK) == - TRB_TYPE(TRB_LINK) && - (generic_trb->field[3] & LINK_TOGGLE)) - *cycle_state = ~(*cycle_state) & 0x1; + if (generic_trb->field[3] & LINK_TOGGLE) + *cycle_state ^= 0x1; cur_seg = cur_seg->next; if (cur_seg == start_seg) /* Looped over the entire list. Oops! */ @@ -492,7 +490,7 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, trb = &state->new_deq_ptr->generic; if ((trb->field[3] & TRB_TYPE_BITMASK) == TRB_TYPE(TRB_LINK) && (trb->field[3] & LINK_TOGGLE)) - state->new_cycle_state = ~(state->new_cycle_state) & 0x1; + state->new_cycle_state ^= 0x1; next_trb(xhci, ep_ring, &state->new_deq_seg, &state->new_deq_ptr); /* -- cgit v1.2.3 From 500132a0f26ad7d9916102193cbc6c1b1becb373 Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Mon, 28 Feb 2011 18:11:27 -0800 Subject: USB: Add support for SuperSpeed isoc endpoints Use the Mult and bMaxBurst values from the endpoint companion descriptor to calculate the max length of an isoc transfer. Add USB_SS_MULT macro to access Mult field of bmAttributes, at Sarah's suggestion. This patch should be queued for the 2.6.36 and 2.6.37 stable trees, since those were the first kernels to have isochronous support for SuperSpeed devices. Signed-off-by: Paul Zimmerman Signed-off-by: Sarah Sharp Cc: stable@kernel.org --- drivers/usb/core/urb.c | 11 ++++++++++- include/linux/usb/ch9.h | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index c14fc082864f..ae334b067c13 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -366,7 +366,16 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) if (xfertype == USB_ENDPOINT_XFER_ISOC) { int n, len; - /* FIXME SuperSpeed isoc endpoints have up to 16 bursts */ + /* SuperSpeed isoc endpoints have up to 16 bursts of up to + * 3 packets each + */ + if (dev->speed == USB_SPEED_SUPER) { + int burst = 1 + ep->ss_ep_comp.bMaxBurst; + int mult = USB_SS_MULT(ep->ss_ep_comp.bmAttributes); + max *= burst; + max *= mult; + } + /* "high bandwidth" mode, 1-3 packets/uframe? */ if (dev->speed == USB_SPEED_HIGH) { int mult = 1 + ((max >> 11) & 0x03); diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h index 34316ba05f29..b72f305ce6bd 100644 --- a/include/linux/usb/ch9.h +++ b/include/linux/usb/ch9.h @@ -585,6 +585,8 @@ struct usb_ss_ep_comp_descriptor { #define USB_DT_SS_EP_COMP_SIZE 6 /* Bits 4:0 of bmAttributes if this is a bulk endpoint */ #define USB_SS_MAX_STREAMS(p) (1 << ((p) & 0x1f)) +/* Bits 1:0 of bmAttributes if this is an isoc endpoint */ +#define USB_SS_MULT(p) (1 + ((p) & 0x3)) /*-------------------------------------------------------------------------*/ -- cgit v1.2.3 From 5359533801e3dd3abca5b7d3d985b0b33fd9fe8b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 14 Mar 2011 09:47:24 +1000 Subject: drm/radeon: fix problem with changing active VRAM size. (v2) So we used to use lpfn directly to restrict VRAM when we couldn't access the unmappable area, however this was removed in 93225b0d7bc030f4a93165347a65893685822d70 as it also restricted the gtt placements. However it was only later noticed that this broke on some hw. This removes the active_vram_size, and just explicitly sets it when it changes, TTM/drm_mm will always use the real_vram_size, and the active vram size will change the TTM size used for lpfn setting. We should re-work the fpfn/lpfn to per-placement at some point I suspect, but that is too late for this kernel. Hopefully this addresses: https://bugs.freedesktop.org/show_bug.cgi?id=35254 v2: fix reported useful VRAM size to userspace to be correct. Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 3 +-- drivers/gpu/drm/radeon/evergreen_blit_kms.c | 4 ++-- drivers/gpu/drm/radeon/r100.c | 5 ++--- drivers/gpu/drm/radeon/r600.c | 3 +-- drivers/gpu/drm/radeon/r600_blit_kms.c | 4 ++-- drivers/gpu/drm/radeon/radeon.h | 2 +- drivers/gpu/drm/radeon/radeon_gem.c | 5 ++++- drivers/gpu/drm/radeon/radeon_ttm.c | 14 ++++++++++++++ drivers/gpu/drm/radeon/rs600.c | 1 - drivers/gpu/drm/radeon/rs690.c | 1 - drivers/gpu/drm/radeon/rv770.c | 3 +-- 11 files changed, 28 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index d270b3ff896b..6140ea1de45a 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -2194,7 +2194,6 @@ int evergreen_mc_init(struct radeon_device *rdev) rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; } rdev->mc.visible_vram_size = rdev->mc.aper_size; - rdev->mc.active_vram_size = rdev->mc.visible_vram_size; r700_vram_gtt_location(rdev, &rdev->mc); radeon_update_bandwidth_info(rdev); @@ -2934,7 +2933,7 @@ static int evergreen_startup(struct radeon_device *rdev) /* XXX: ontario has problems blitting to gart at the moment */ if (rdev->family == CHIP_PALM) { rdev->asic->copy = NULL; - rdev->mc.active_vram_size = rdev->mc.visible_vram_size; + radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); } /* allocate wb buffer */ diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index 2adfb03f479b..2be698e78ff2 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c @@ -623,7 +623,7 @@ done: dev_err(rdev->dev, "(%d) pin blit object failed\n", r); return r; } - rdev->mc.active_vram_size = rdev->mc.real_vram_size; + radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); return 0; } @@ -631,7 +631,7 @@ void evergreen_blit_fini(struct radeon_device *rdev) { int r; - rdev->mc.active_vram_size = rdev->mc.visible_vram_size; + radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); if (rdev->r600_blit.shader_obj == NULL) return; /* If we can't reserve the bo, unref should be enough to destroy diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 79de991e1ea3..e372f9e1e5ce 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -1024,7 +1024,7 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) return r; } rdev->cp.ready = true; - rdev->mc.active_vram_size = rdev->mc.real_vram_size; + radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); return 0; } @@ -1042,7 +1042,7 @@ void r100_cp_fini(struct radeon_device *rdev) void r100_cp_disable(struct radeon_device *rdev) { /* Disable ring */ - rdev->mc.active_vram_size = rdev->mc.visible_vram_size; + radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); rdev->cp.ready = false; WREG32(RADEON_CP_CSQ_MODE, 0); WREG32(RADEON_CP_CSQ_CNTL, 0); @@ -2312,7 +2312,6 @@ void r100_vram_init_sizes(struct radeon_device *rdev) /* FIXME we don't use the second aperture yet when we could use it */ if (rdev->mc.visible_vram_size > rdev->mc.aper_size) rdev->mc.visible_vram_size = rdev->mc.aper_size; - rdev->mc.active_vram_size = rdev->mc.visible_vram_size; config_aper_size = RREG32(RADEON_CONFIG_APER_SIZE); if (rdev->flags & RADEON_IS_IGP) { uint32_t tom; diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index de88624d5f87..9b3fad23b76c 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1255,7 +1255,6 @@ int r600_mc_init(struct radeon_device *rdev) rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); rdev->mc.visible_vram_size = rdev->mc.aper_size; - rdev->mc.active_vram_size = rdev->mc.visible_vram_size; r600_vram_gtt_location(rdev, &rdev->mc); if (rdev->flags & RADEON_IS_IGP) { @@ -1937,7 +1936,7 @@ void r600_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v) */ void r600_cp_stop(struct radeon_device *rdev) { - rdev->mc.active_vram_size = rdev->mc.visible_vram_size; + radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); WREG32(SCRATCH_UMSK, 0); } diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index 41f7aafc97c4..df68d91e8190 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -558,7 +558,7 @@ done: dev_err(rdev->dev, "(%d) pin blit object failed\n", r); return r; } - rdev->mc.active_vram_size = rdev->mc.real_vram_size; + radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); return 0; } @@ -566,7 +566,7 @@ void r600_blit_fini(struct radeon_device *rdev) { int r; - rdev->mc.active_vram_size = rdev->mc.visible_vram_size; + radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); if (rdev->r600_blit.shader_obj == NULL) return; /* If we can't reserve the bo, unref should be enough to destroy diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 56c48b67ef3d..6b3429495118 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -345,7 +345,6 @@ struct radeon_mc { * about vram size near mc fb location */ u64 mc_vram_size; u64 visible_vram_size; - u64 active_vram_size; u64 gtt_size; u64 gtt_start; u64 gtt_end; @@ -1448,6 +1447,7 @@ extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *m extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); extern int radeon_resume_kms(struct drm_device *dev); extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state); +extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size); /* r600, rv610, rv630, rv620, rv635, rv670, rs780, rs880 */ extern bool r600_card_posted(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index df95eb83dac6..1fe95dfe48c9 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -156,9 +156,12 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data, { struct radeon_device *rdev = dev->dev_private; struct drm_radeon_gem_info *args = data; + struct ttm_mem_type_manager *man; + + man = &rdev->mman.bdev.man[TTM_PL_VRAM]; args->vram_size = rdev->mc.real_vram_size; - args->vram_visible = rdev->mc.real_vram_size; + args->vram_visible = (u64)man->size << PAGE_SHIFT; if (rdev->stollen_vga_memory) args->vram_visible -= radeon_bo_size(rdev->stollen_vga_memory); args->vram_visible -= radeon_fbdev_total_size(rdev); diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index e5b2cf10cbf4..8389b4c63d12 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -589,6 +589,20 @@ void radeon_ttm_fini(struct radeon_device *rdev) DRM_INFO("radeon: ttm finalized\n"); } +/* this should only be called at bootup or when userspace + * isn't running */ +void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size) +{ + struct ttm_mem_type_manager *man; + + if (!rdev->mman.initialized) + return; + + man = &rdev->mman.bdev.man[TTM_PL_VRAM]; + /* this just adjusts TTM size idea, which sets lpfn to the correct value */ + man->size = size >> PAGE_SHIFT; +} + static struct vm_operations_struct radeon_ttm_vm_ops; static const struct vm_operations_struct *ttm_vm_ops = NULL; diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 5afe294ed51f..8af4679db23e 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -751,7 +751,6 @@ void rs600_mc_init(struct radeon_device *rdev) rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); rdev->mc.mc_vram_size = rdev->mc.real_vram_size; rdev->mc.visible_vram_size = rdev->mc.aper_size; - rdev->mc.active_vram_size = rdev->mc.visible_vram_size; rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); base = RREG32_MC(R_000004_MC_FB_LOCATION); base = G_000004_MC_FB_START(base) << 16; diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 6638c8e4c81b..66c949b7c18c 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -157,7 +157,6 @@ void rs690_mc_init(struct radeon_device *rdev) rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); rdev->mc.visible_vram_size = rdev->mc.aper_size; - rdev->mc.active_vram_size = rdev->mc.visible_vram_size; base = RREG32_MC(R_000100_MCCFG_FB_LOCATION); base = G_000100_MC_FB_START(base) << 16; rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index d8ba67690656..714ad45757d0 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -307,7 +307,7 @@ static void rv770_mc_program(struct radeon_device *rdev) */ void r700_cp_stop(struct radeon_device *rdev) { - rdev->mc.active_vram_size = rdev->mc.visible_vram_size; + radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT)); WREG32(SCRATCH_UMSK, 0); } @@ -1123,7 +1123,6 @@ int rv770_mc_init(struct radeon_device *rdev) rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); rdev->mc.visible_vram_size = rdev->mc.aper_size; - rdev->mc.active_vram_size = rdev->mc.visible_vram_size; r700_vram_gtt_location(rdev, &rdev->mc); radeon_update_bandwidth_info(rdev); -- cgit v1.2.3 From 64a3903d0885879ba8706a8bcf71c5e3e7664db2 Mon Sep 17 00:00:00 2001 From: Seth Heasley Date: Fri, 11 Mar 2011 11:57:42 -0800 Subject: ahci: AHCI mode SATA patch for Intel Patsburg SATA RAID controller This patch adds an updated SATA RAID DeviceID for the Intel Patsburg PCH. Signed-off-by: Seth Heasley Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 256d2b72cd1c..0c22ebd540d3 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -259,6 +259,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */ { PCI_VDEVICE(INTEL, 0x1d04), board_ahci }, /* PBG RAID */ { PCI_VDEVICE(INTEL, 0x1d06), board_ahci }, /* PBG RAID */ + { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG RAID */ { PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */ /* JMicron 360/1/3/5/6, match class to avoid IDE function */ -- cgit v1.2.3 From 64b97594251bb909d74d64012a2b9e5cc32bb11d Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 22 Feb 2011 14:32:38 +0530 Subject: libata-sff: add ata_sff_queue_work() & ata_sff_queue_delayed_work() This patch adds ata_sff_queue_work() & ata_sff_queue_delayed_work() routine in libata-sff.c file. This routine can be used by ata drivers to use ata_sff_wq. Signed-off-by: Viresh Kumar Acked-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-sff.c | 15 +++++++++++++-- include/linux/libata.h | 3 +++ 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index e75a02d61a8f..cf7acbc0cfcb 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -1302,6 +1302,18 @@ fsm_start: } EXPORT_SYMBOL_GPL(ata_sff_hsm_move); +void ata_sff_queue_work(struct work_struct *work) +{ + queue_work(ata_sff_wq, work); +} +EXPORT_SYMBOL_GPL(ata_sff_queue_work); + +void ata_sff_queue_delayed_work(struct delayed_work *dwork, unsigned long delay) +{ + queue_delayed_work(ata_sff_wq, dwork, delay); +} +EXPORT_SYMBOL_GPL(ata_sff_queue_delayed_work); + void ata_sff_queue_pio_task(struct ata_link *link, unsigned long delay) { struct ata_port *ap = link->ap; @@ -1311,8 +1323,7 @@ void ata_sff_queue_pio_task(struct ata_link *link, unsigned long delay) ap->sff_pio_task_link = link; /* may fail if ata_sff_flush_pio_task() in progress */ - queue_delayed_work(ata_sff_wq, &ap->sff_pio_task, - msecs_to_jiffies(delay)); + ata_sff_queue_delayed_work(&ap->sff_pio_task, msecs_to_jiffies(delay)); } EXPORT_SYMBOL_GPL(ata_sff_queue_pio_task); diff --git a/include/linux/libata.h b/include/linux/libata.h index 71333aa39532..c71f46960f39 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1610,6 +1610,9 @@ extern void ata_sff_irq_on(struct ata_port *ap); extern void ata_sff_irq_clear(struct ata_port *ap); extern int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, u8 status, int in_wq); +extern void ata_sff_queue_work(struct work_struct *work); +extern void ata_sff_queue_delayed_work(struct delayed_work *dwork, + unsigned long delay); extern void ata_sff_queue_pio_task(struct ata_link *link, unsigned long delay); extern unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc); extern bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc); -- cgit v1.2.3 From a480167b23ef9b35ec0299bb3e1b11b4ed6b3508 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 22 Feb 2011 15:46:07 +0530 Subject: pata_arasan_cf: Adding support for arasan compact flash host controller The Arasan CompactFlash Device Controller has three basic modes of operation: PC card ATA using I/O mode, PC card ATA using memory mode, PC card ATA using true IDE modes. Currently driver supports only True IDE mode. Signed-off-by: Viresh Kumar Signed-off-by: Jeff Garzik --- MAINTAINERS | 7 + drivers/ata/Kconfig | 6 + drivers/ata/Makefile | 1 + drivers/ata/pata_arasan_cf.c | 977 ++++++++++++++++++++++++++++++++++++ include/linux/pata_arasan_cf_data.h | 47 ++ 5 files changed, 1038 insertions(+) create mode 100644 drivers/ata/pata_arasan_cf.c create mode 100644 include/linux/pata_arasan_cf_data.h (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index 8afba6321e24..3f4b3f9edd48 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -557,6 +557,13 @@ S: Maintained F: drivers/net/appletalk/ F: net/appletalk/ +ARASAN COMPACT FLASH PATA CONTROLLER +M: Viresh Kumar +L: linux-ide@vger.kernel.org +S: Maintained +F: include/linux/pata_arasan_cf_data.h +F: drivers/ata/pata_arasan_cf.c + ARC FRAMEBUFFER DRIVER M: Jaya Kumar S: Maintained diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 8a1fc396f055..75afa75a515e 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -311,6 +311,12 @@ config PATA_AMD If unsure, say N. +config PATA_ARASAN_CF + tristate "ARASAN CompactFlash PATA Controller Support" + select DMA_ENGINE + help + Say Y here to support the ARASAN CompactFlash PATA controller + config PATA_ARTOP tristate "ARTOP 6210/6260 PATA support" depends on PCI diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 27291aad6ca7..8ac64e1aa051 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o # SFF w/ custom DMA obj-$(CONFIG_PDC_ADMA) += pdc_adma.o +obj-$(CONFIG_PATA_ARASAN_CF) += pata_arasan_cf.o obj-$(CONFIG_PATA_OCTEON_CF) += pata_octeon_cf.o obj-$(CONFIG_SATA_QSTOR) += sata_qstor.o obj-$(CONFIG_SATA_SX4) += sata_sx4.o diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c new file mode 100644 index 000000000000..b99b3fce307f --- /dev/null +++ b/drivers/ata/pata_arasan_cf.c @@ -0,0 +1,977 @@ +/* + * drivers/ata/pata_arasan_cf.c + * + * Arasan Compact Flash host controller source file + * + * Copyright (C) 2011 ST Microelectronics + * Viresh Kumar + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +/* + * The Arasan CompactFlash Device Controller IP core has three basic modes of + * operation: PC card ATA using I/O mode, PC card ATA using memory mode, PC card + * ATA using true IDE modes. This driver supports only True IDE mode currently. + * + * Arasan CF Controller shares global irq register with Arasan XD Controller. + * + * Tested on arch/arm/mach-spear13xx + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "arasan_cf" +#define TIMEOUT msecs_to_jiffies(3000) + +/* Registers */ +/* CompactFlash Interface Status */ +#define CFI_STS 0x000 + #define STS_CHG (1) + #define BIN_AUDIO_OUT (1 << 1) + #define CARD_DETECT1 (1 << 2) + #define CARD_DETECT2 (1 << 3) + #define INP_ACK (1 << 4) + #define CARD_READY (1 << 5) + #define IO_READY (1 << 6) + #define B16_IO_PORT_SEL (1 << 7) +/* IRQ */ +#define IRQ_STS 0x004 +/* Interrupt Enable */ +#define IRQ_EN 0x008 + #define CARD_DETECT_IRQ (1) + #define STATUS_CHNG_IRQ (1 << 1) + #define MEM_MODE_IRQ (1 << 2) + #define IO_MODE_IRQ (1 << 3) + #define TRUE_IDE_MODE_IRQ (1 << 8) + #define PIO_XFER_ERR_IRQ (1 << 9) + #define BUF_AVAIL_IRQ (1 << 10) + #define XFER_DONE_IRQ (1 << 11) + #define IGNORED_IRQS (STATUS_CHNG_IRQ | MEM_MODE_IRQ | IO_MODE_IRQ |\ + TRUE_IDE_MODE_IRQ) + #define TRUE_IDE_IRQS (CARD_DETECT_IRQ | PIO_XFER_ERR_IRQ |\ + BUF_AVAIL_IRQ | XFER_DONE_IRQ) +/* Operation Mode */ +#define OP_MODE 0x00C + #define CARD_MODE_MASK (0x3) + #define MEM_MODE (0x0) + #define IO_MODE (0x1) + #define TRUE_IDE_MODE (0x2) + + #define CARD_TYPE_MASK (1 << 2) + #define CF_CARD (0) + #define CF_PLUS_CARD (1 << 2) + + #define CARD_RESET (1 << 3) + #define CFHOST_ENB (1 << 4) + #define OUTPUTS_TRISTATE (1 << 5) + #define ULTRA_DMA_ENB (1 << 8) + #define MULTI_WORD_DMA_ENB (1 << 9) + #define DRQ_BLOCK_SIZE_MASK (0x3 << 11) + #define DRQ_BLOCK_SIZE_512 (0) + #define DRQ_BLOCK_SIZE_1024 (1 << 11) + #define DRQ_BLOCK_SIZE_2048 (2 << 11) + #define DRQ_BLOCK_SIZE_4096 (3 << 11) +/* CF Interface Clock Configuration */ +#define CLK_CFG 0x010 + #define CF_IF_CLK_MASK (0XF) +/* CF Timing Mode Configuration */ +#define TM_CFG 0x014 + #define MEM_MODE_TIMING_MASK (0x3) + #define MEM_MODE_TIMING_250NS (0x0) + #define MEM_MODE_TIMING_120NS (0x1) + #define MEM_MODE_TIMING_100NS (0x2) + #define MEM_MODE_TIMING_80NS (0x3) + + #define IO_MODE_TIMING_MASK (0x3 << 2) + #define IO_MODE_TIMING_250NS (0x0 << 2) + #define IO_MODE_TIMING_120NS (0x1 << 2) + #define IO_MODE_TIMING_100NS (0x2 << 2) + #define IO_MODE_TIMING_80NS (0x3 << 2) + + #define TRUEIDE_PIO_TIMING_MASK (0x7 << 4) + #define TRUEIDE_PIO_TIMING_SHIFT 4 + + #define TRUEIDE_MWORD_DMA_TIMING_MASK (0x7 << 7) + #define TRUEIDE_MWORD_DMA_TIMING_SHIFT 7 + + #define ULTRA_DMA_TIMING_MASK (0x7 << 10) + #define ULTRA_DMA_TIMING_SHIFT 10 +/* CF Transfer Address */ +#define XFER_ADDR 0x014 + #define XFER_ADDR_MASK (0x7FF) + #define MAX_XFER_COUNT 0x20000u +/* Transfer Control */ +#define XFER_CTR 0x01C + #define XFER_COUNT_MASK (0x3FFFF) + #define ADDR_INC_DISABLE (1 << 24) + #define XFER_WIDTH_MASK (1 << 25) + #define XFER_WIDTH_8B (0) + #define XFER_WIDTH_16B (1 << 25) + + #define MEM_TYPE_MASK (1 << 26) + #define MEM_TYPE_COMMON (0) + #define MEM_TYPE_ATTRIBUTE (1 << 26) + + #define MEM_IO_XFER_MASK (1 << 27) + #define MEM_XFER (0) + #define IO_XFER (1 << 27) + + #define DMA_XFER_MODE (1 << 28) + + #define AHB_BUS_NORMAL_PIO_OPRTN (~(1 << 29)) + #define XFER_DIR_MASK (1 << 30) + #define XFER_READ (0) + #define XFER_WRITE (1 << 30) + + #define XFER_START (1 << 31) +/* Write Data Port */ +#define WRITE_PORT 0x024 +/* Read Data Port */ +#define READ_PORT 0x028 +/* ATA Data Port */ +#define ATA_DATA_PORT 0x030 + #define ATA_DATA_PORT_MASK (0xFFFF) +/* ATA Error/Features */ +#define ATA_ERR_FTR 0x034 +/* ATA Sector Count */ +#define ATA_SC 0x038 +/* ATA Sector Number */ +#define ATA_SN 0x03C +/* ATA Cylinder Low */ +#define ATA_CL 0x040 +/* ATA Cylinder High */ +#define ATA_CH 0x044 +/* ATA Select Card/Head */ +#define ATA_SH 0x048 +/* ATA Status-Command */ +#define ATA_STS_CMD 0x04C +/* ATA Alternate Status/Device Control */ +#define ATA_ASTS_DCTR 0x050 +/* Extended Write Data Port 0x200-0x3FC */ +#define EXT_WRITE_PORT 0x200 +/* Extended Read Data Port 0x400-0x5FC */ +#define EXT_READ_PORT 0x400 + #define FIFO_SIZE 0x200u +/* Global Interrupt Status */ +#define GIRQ_STS 0x800 +/* Global Interrupt Status enable */ +#define GIRQ_STS_EN 0x804 +/* Global Interrupt Signal enable */ +#define GIRQ_SGN_EN 0x808 + #define GIRQ_CF (1) + #define GIRQ_XD (1 << 1) + +/* Compact Flash Controller Dev Structure */ +struct arasan_cf_dev { + /* pointer to ata_host structure */ + struct ata_host *host; + /* clk structure, only if HAVE_CLK is defined */ +#ifdef CONFIG_HAVE_CLK + struct clk *clk; +#endif + + /* physical base address of controller */ + dma_addr_t pbase; + /* virtual base address of controller */ + void __iomem *vbase; + /* irq number*/ + int irq; + + /* status to be updated to framework regarding DMA transfer */ + u8 dma_status; + /* Card is present or Not */ + u8 card_present; + + /* dma specific */ + /* Completion for transfer complete interrupt from controller */ + struct completion cf_completion; + /* Completion for DMA transfer complete. */ + struct completion dma_completion; + /* Dma channel allocated */ + struct dma_chan *dma_chan; + /* Mask for DMA transfers */ + dma_cap_mask_t mask; + /* DMA transfer work */ + struct work_struct work; + /* DMA delayed finish work */ + struct delayed_work dwork; + /* qc to be transferred using DMA */ + struct ata_queued_cmd *qc; +}; + +static struct scsi_host_template arasan_cf_sht = { + ATA_BASE_SHT(DRIVER_NAME), + .sg_tablesize = SG_NONE, + .dma_boundary = 0xFFFFFFFFUL, +}; + +static void cf_dumpregs(struct arasan_cf_dev *acdev) +{ + struct device *dev = acdev->host->dev; + + dev_dbg(dev, ": =========== REGISTER DUMP ==========="); + dev_dbg(dev, ": CFI_STS: %x", readl(acdev->vbase + CFI_STS)); + dev_dbg(dev, ": IRQ_STS: %x", readl(acdev->vbase + IRQ_STS)); + dev_dbg(dev, ": IRQ_EN: %x", readl(acdev->vbase + IRQ_EN)); + dev_dbg(dev, ": OP_MODE: %x", readl(acdev->vbase + OP_MODE)); + dev_dbg(dev, ": CLK_CFG: %x", readl(acdev->vbase + CLK_CFG)); + dev_dbg(dev, ": TM_CFG: %x", readl(acdev->vbase + TM_CFG)); + dev_dbg(dev, ": XFER_CTR: %x", readl(acdev->vbase + XFER_CTR)); + dev_dbg(dev, ": GIRQ_STS: %x", readl(acdev->vbase + GIRQ_STS)); + dev_dbg(dev, ": GIRQ_STS_EN: %x", readl(acdev->vbase + GIRQ_STS_EN)); + dev_dbg(dev, ": GIRQ_SGN_EN: %x", readl(acdev->vbase + GIRQ_SGN_EN)); + dev_dbg(dev, ": ====================================="); +} + +/* Enable/Disable global interrupts shared between CF and XD ctrlr. */ +static void cf_ginterrupt_enable(struct arasan_cf_dev *acdev, bool enable) +{ + /* enable should be 0 or 1 */ + writel(enable, acdev->vbase + GIRQ_STS_EN); + writel(enable, acdev->vbase + GIRQ_SGN_EN); +} + +/* Enable/Disable CF interrupts */ +static inline void +cf_interrupt_enable(struct arasan_cf_dev *acdev, u32 mask, bool enable) +{ + u32 val = readl(acdev->vbase + IRQ_EN); + /* clear & enable/disable irqs */ + if (enable) { + writel(mask, acdev->vbase + IRQ_STS); + writel(val | mask, acdev->vbase + IRQ_EN); + } else + writel(val & ~mask, acdev->vbase + IRQ_EN); +} + +static inline void cf_card_reset(struct arasan_cf_dev *acdev) +{ + u32 val = readl(acdev->vbase + OP_MODE); + + writel(val | CARD_RESET, acdev->vbase + OP_MODE); + udelay(200); + writel(val & ~CARD_RESET, acdev->vbase + OP_MODE); +} + +static inline void cf_ctrl_reset(struct arasan_cf_dev *acdev) +{ + writel(readl(acdev->vbase + OP_MODE) & ~CFHOST_ENB, + acdev->vbase + OP_MODE); + writel(readl(acdev->vbase + OP_MODE) | CFHOST_ENB, + acdev->vbase + OP_MODE); +} + +static void cf_card_detect(struct arasan_cf_dev *acdev, bool hotplugged) +{ + struct ata_port *ap = acdev->host->ports[0]; + struct ata_eh_info *ehi = &ap->link.eh_info; + u32 val = readl(acdev->vbase + CFI_STS); + + /* Both CD1 & CD2 should be low if card inserted completely */ + if (!(val & (CARD_DETECT1 | CARD_DETECT2))) { + if (acdev->card_present) + return; + acdev->card_present = 1; + cf_card_reset(acdev); + } else { + if (!acdev->card_present) + return; + acdev->card_present = 0; + } + + if (hotplugged) { + ata_ehi_hotplugged(ehi); + ata_port_freeze(ap); + } +} + +static int cf_init(struct arasan_cf_dev *acdev) +{ + struct arasan_cf_pdata *pdata = dev_get_platdata(acdev->host->dev); + unsigned long flags; + int ret = 0; + +#ifdef CONFIG_HAVE_CLK + ret = clk_enable(acdev->clk); + if (ret) { + dev_dbg(acdev->host->dev, "clock enable failed"); + return ret; + } +#endif + + spin_lock_irqsave(&acdev->host->lock, flags); + /* configure CF interface clock */ + writel((pdata->cf_if_clk <= CF_IF_CLK_200M) ? pdata->cf_if_clk : + CF_IF_CLK_166M, acdev->vbase + CLK_CFG); + + writel(TRUE_IDE_MODE | CFHOST_ENB, acdev->vbase + OP_MODE); + cf_interrupt_enable(acdev, CARD_DETECT_IRQ, 1); + cf_ginterrupt_enable(acdev, 1); + spin_unlock_irqrestore(&acdev->host->lock, flags); + + return ret; +} + +static void cf_exit(struct arasan_cf_dev *acdev) +{ + unsigned long flags; + + spin_lock_irqsave(&acdev->host->lock, flags); + cf_ginterrupt_enable(acdev, 0); + cf_interrupt_enable(acdev, TRUE_IDE_IRQS, 0); + cf_card_reset(acdev); + writel(readl(acdev->vbase + OP_MODE) & ~CFHOST_ENB, + acdev->vbase + OP_MODE); + spin_unlock_irqrestore(&acdev->host->lock, flags); +#ifdef CONFIG_HAVE_CLK + clk_disable(acdev->clk); +#endif +} + +static void dma_callback(void *dev) +{ + struct arasan_cf_dev *acdev = (struct arasan_cf_dev *) dev; + + complete(&acdev->dma_completion); +} + +static bool filter(struct dma_chan *chan, void *slave) +{ + return true; +} + +static inline void dma_complete(struct arasan_cf_dev *acdev) +{ + struct ata_queued_cmd *qc = acdev->qc; + unsigned long flags; + + acdev->qc = NULL; + ata_sff_interrupt(acdev->irq, acdev->host); + + spin_lock_irqsave(&acdev->host->lock, flags); + if (unlikely(qc->err_mask) && ata_is_dma(qc->tf.protocol)) + ata_ehi_push_desc(&qc->ap->link.eh_info, "DMA Failed: Timeout"); + spin_unlock_irqrestore(&acdev->host->lock, flags); +} + +static inline int wait4buf(struct arasan_cf_dev *acdev) +{ + if (!wait_for_completion_timeout(&acdev->cf_completion, TIMEOUT)) { + u32 rw = acdev->qc->tf.flags & ATA_TFLAG_WRITE; + + dev_err(acdev->host->dev, "%s TimeOut", rw ? "write" : "read"); + return -ETIMEDOUT; + } + + /* Check if PIO Error interrupt has occured */ + if (acdev->dma_status & ATA_DMA_ERR) + return -EAGAIN; + + return 0; +} + +static int +dma_xfer(struct arasan_cf_dev *acdev, dma_addr_t src, dma_addr_t dest, u32 len) +{ + struct dma_async_tx_descriptor *tx; + struct dma_chan *chan = acdev->dma_chan; + dma_cookie_t cookie; + unsigned long flags = DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP | + DMA_COMPL_SKIP_DEST_UNMAP; + int ret = 0; + + tx = chan->device->device_prep_dma_memcpy(chan, dest, src, len, flags); + if (!tx) { + dev_err(acdev->host->dev, "device_prep_dma_memcpy failed\n"); + return -EAGAIN; + } + + tx->callback = dma_callback; + tx->callback_param = acdev; + cookie = tx->tx_submit(tx); + + ret = dma_submit_error(cookie); + if (ret) { + dev_err(acdev->host->dev, "dma_submit_error\n"); + return ret; + } + + chan->device->device_issue_pending(chan); + + /* Wait for DMA to complete */ + if (!wait_for_completion_timeout(&acdev->dma_completion, TIMEOUT)) { + chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); + dev_err(acdev->host->dev, "wait_for_completion_timeout\n"); + return -ETIMEDOUT; + } + + return ret; +} + +static int sg_xfer(struct arasan_cf_dev *acdev, struct scatterlist *sg) +{ + dma_addr_t dest = 0, src = 0; + u32 xfer_cnt, sglen, dma_len, xfer_ctr; + u32 write = acdev->qc->tf.flags & ATA_TFLAG_WRITE; + unsigned long flags; + int ret = 0; + + sglen = sg_dma_len(sg); + if (write) { + src = sg_dma_address(sg); + dest = acdev->pbase + EXT_WRITE_PORT; + } else { + dest = sg_dma_address(sg); + src = acdev->pbase + EXT_READ_PORT; + } + + /* + * For each sg: + * MAX_XFER_COUNT data will be transferred before we get transfer + * complete interrupt. Inbetween after FIFO_SIZE data + * buffer available interrupt will be generated. At this time we will + * fill FIFO again: max FIFO_SIZE data. + */ + while (sglen) { + xfer_cnt = min(sglen, MAX_XFER_COUNT); + spin_lock_irqsave(&acdev->host->lock, flags); + xfer_ctr = readl(acdev->vbase + XFER_CTR) & + ~XFER_COUNT_MASK; + writel(xfer_ctr | xfer_cnt | XFER_START, + acdev->vbase + XFER_CTR); + spin_unlock_irqrestore(&acdev->host->lock, flags); + + /* continue dma xfers untill current sg is completed */ + while (xfer_cnt) { + /* wait for read to complete */ + if (!write) { + ret = wait4buf(acdev); + if (ret) + goto fail; + } + + /* read/write FIFO in chunk of FIFO_SIZE */ + dma_len = min(xfer_cnt, FIFO_SIZE); + ret = dma_xfer(acdev, src, dest, dma_len); + if (ret) { + dev_err(acdev->host->dev, "dma failed"); + goto fail; + } + + if (write) + src += dma_len; + else + dest += dma_len; + + sglen -= dma_len; + xfer_cnt -= dma_len; + + /* wait for write to complete */ + if (write) { + ret = wait4buf(acdev); + if (ret) + goto fail; + } + } + } + +fail: + spin_lock_irqsave(&acdev->host->lock, flags); + writel(readl(acdev->vbase + XFER_CTR) & ~XFER_START, + acdev->vbase + XFER_CTR); + spin_unlock_irqrestore(&acdev->host->lock, flags); + + return ret; +} + +/* + * This routine uses External DMA controller to read/write data to FIFO of CF + * controller. There are two xfer related interrupt supported by CF controller: + * - buf_avail: This interrupt is generated as soon as we have buffer of 512 + * bytes available for reading or empty buffer available for writing. + * - xfer_done: This interrupt is generated on transfer of "xfer_size" amount of + * data to/from FIFO. xfer_size is programmed in XFER_CTR register. + * + * Max buffer size = FIFO_SIZE = 512 Bytes. + * Max xfer_size = MAX_XFER_COUNT = 256 KB. + */ +static void data_xfer(struct work_struct *work) +{ + struct arasan_cf_dev *acdev = container_of(work, struct arasan_cf_dev, + work); + struct ata_queued_cmd *qc = acdev->qc; + struct scatterlist *sg; + unsigned long flags; + u32 temp; + int ret = 0; + + /* request dma channels */ + /* dma_request_channel may sleep, so calling from process context */ + acdev->dma_chan = dma_request_channel(acdev->mask, filter, NULL); + if (!acdev->dma_chan) { + dev_err(acdev->host->dev, "Unable to get dma_chan\n"); + goto chan_request_fail; + } + + for_each_sg(qc->sg, sg, qc->n_elem, temp) { + ret = sg_xfer(acdev, sg); + if (ret) + break; + } + + dma_release_channel(acdev->dma_chan); + + /* data xferred successfully */ + if (!ret) { + u32 status; + + spin_lock_irqsave(&acdev->host->lock, flags); + status = ioread8(qc->ap->ioaddr.altstatus_addr); + spin_unlock_irqrestore(&acdev->host->lock, flags); + if (status & (ATA_BUSY | ATA_DRQ)) { + ata_sff_queue_delayed_work(&acdev->dwork, 1); + return; + } + + goto sff_intr; + } + + cf_dumpregs(acdev); + +chan_request_fail: + spin_lock_irqsave(&acdev->host->lock, flags); + /* error when transfering data to/from memory */ + qc->err_mask |= AC_ERR_HOST_BUS; + qc->ap->hsm_task_state = HSM_ST_ERR; + + cf_ctrl_reset(acdev); + spin_unlock_irqrestore(qc->ap->lock, flags); +sff_intr: + dma_complete(acdev); +} + +static void delayed_finish(struct work_struct *work) +{ + struct arasan_cf_dev *acdev = container_of(work, struct arasan_cf_dev, + dwork.work); + struct ata_queued_cmd *qc = acdev->qc; + unsigned long flags; + u8 status; + + spin_lock_irqsave(&acdev->host->lock, flags); + status = ioread8(qc->ap->ioaddr.altstatus_addr); + spin_unlock_irqrestore(&acdev->host->lock, flags); + + if (status & (ATA_BUSY | ATA_DRQ)) + ata_sff_queue_delayed_work(&acdev->dwork, 1); + else + dma_complete(acdev); +} + +static irqreturn_t arasan_cf_interrupt(int irq, void *dev) +{ + struct arasan_cf_dev *acdev = ((struct ata_host *)dev)->private_data; + unsigned long flags; + u32 irqsts; + + irqsts = readl(acdev->vbase + GIRQ_STS); + if (!(irqsts & GIRQ_CF)) + return IRQ_NONE; + + spin_lock_irqsave(&acdev->host->lock, flags); + irqsts = readl(acdev->vbase + IRQ_STS); + writel(irqsts, acdev->vbase + IRQ_STS); /* clear irqs */ + writel(GIRQ_CF, acdev->vbase + GIRQ_STS); /* clear girqs */ + + /* handle only relevant interrupts */ + irqsts &= ~IGNORED_IRQS; + + if (irqsts & CARD_DETECT_IRQ) { + cf_card_detect(acdev, 1); + spin_unlock_irqrestore(&acdev->host->lock, flags); + return IRQ_HANDLED; + } + + if (irqsts & PIO_XFER_ERR_IRQ) { + acdev->dma_status = ATA_DMA_ERR; + writel(readl(acdev->vbase + XFER_CTR) & ~XFER_START, + acdev->vbase + XFER_CTR); + spin_unlock_irqrestore(&acdev->host->lock, flags); + complete(&acdev->cf_completion); + dev_err(acdev->host->dev, "pio xfer err irq\n"); + return IRQ_HANDLED; + } + + spin_unlock_irqrestore(&acdev->host->lock, flags); + + if (irqsts & BUF_AVAIL_IRQ) { + complete(&acdev->cf_completion); + return IRQ_HANDLED; + } + + if (irqsts & XFER_DONE_IRQ) { + struct ata_queued_cmd *qc = acdev->qc; + + /* Send Complete only for write */ + if (qc->tf.flags & ATA_TFLAG_WRITE) + complete(&acdev->cf_completion); + } + + return IRQ_HANDLED; +} + +static void arasan_cf_freeze(struct ata_port *ap) +{ + struct arasan_cf_dev *acdev = ap->host->private_data; + + /* stop transfer and reset controller */ + writel(readl(acdev->vbase + XFER_CTR) & ~XFER_START, + acdev->vbase + XFER_CTR); + cf_ctrl_reset(acdev); + acdev->dma_status = ATA_DMA_ERR; + + ata_sff_dma_pause(ap); + ata_sff_freeze(ap); +} + +void arasan_cf_error_handler(struct ata_port *ap) +{ + struct arasan_cf_dev *acdev = ap->host->private_data; + + /* + * DMA transfers using an external DMA controller may be scheduled. + * Abort them before handling error. Refer data_xfer() for further + * details. + */ + cancel_work_sync(&acdev->work); + cancel_delayed_work_sync(&acdev->dwork); + return ata_sff_error_handler(ap); +} + +static void arasan_cf_dma_start(struct arasan_cf_dev *acdev) +{ + u32 xfer_ctr = readl(acdev->vbase + XFER_CTR) & ~XFER_DIR_MASK; + u32 write = acdev->qc->tf.flags & ATA_TFLAG_WRITE; + + xfer_ctr |= write ? XFER_WRITE : XFER_READ; + writel(xfer_ctr, acdev->vbase + XFER_CTR); + + acdev->qc->ap->ops->sff_exec_command(acdev->qc->ap, &acdev->qc->tf); + ata_sff_queue_work(&acdev->work); +} + +unsigned int arasan_cf_qc_issue(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct arasan_cf_dev *acdev = ap->host->private_data; + + /* defer PIO handling to sff_qc_issue */ + if (!ata_is_dma(qc->tf.protocol)) + return ata_sff_qc_issue(qc); + + /* select the device */ + ata_wait_idle(ap); + ata_sff_dev_select(ap, qc->dev->devno); + ata_wait_idle(ap); + + /* start the command */ + switch (qc->tf.protocol) { + case ATA_PROT_DMA: + WARN_ON_ONCE(qc->tf.flags & ATA_TFLAG_POLLING); + + ap->ops->sff_tf_load(ap, &qc->tf); + acdev->dma_status = 0; + acdev->qc = qc; + arasan_cf_dma_start(acdev); + ap->hsm_task_state = HSM_ST_LAST; + break; + + default: + WARN_ON(1); + return AC_ERR_SYSTEM; + } + + return 0; +} + +static void arasan_cf_set_piomode(struct ata_port *ap, struct ata_device *adev) +{ + struct arasan_cf_dev *acdev = ap->host->private_data; + u8 pio = adev->pio_mode - XFER_PIO_0; + unsigned long flags; + u32 val; + + /* Arasan ctrl supports Mode0 -> Mode6 */ + if (pio > 6) { + dev_err(ap->dev, "Unknown PIO mode\n"); + return; + } + + spin_lock_irqsave(&acdev->host->lock, flags); + val = readl(acdev->vbase + OP_MODE) & + ~(ULTRA_DMA_ENB | MULTI_WORD_DMA_ENB | DRQ_BLOCK_SIZE_MASK); + writel(val, acdev->vbase + OP_MODE); + val = readl(acdev->vbase + TM_CFG) & ~TRUEIDE_PIO_TIMING_MASK; + val |= pio << TRUEIDE_PIO_TIMING_SHIFT; + writel(val, acdev->vbase + TM_CFG); + + cf_interrupt_enable(acdev, BUF_AVAIL_IRQ | XFER_DONE_IRQ, 0); + cf_interrupt_enable(acdev, PIO_XFER_ERR_IRQ, 1); + spin_unlock_irqrestore(&acdev->host->lock, flags); +} + +static void arasan_cf_set_dmamode(struct ata_port *ap, struct ata_device *adev) +{ + struct arasan_cf_dev *acdev = ap->host->private_data; + u32 opmode, tmcfg, dma_mode = adev->dma_mode; + unsigned long flags; + + spin_lock_irqsave(&acdev->host->lock, flags); + opmode = readl(acdev->vbase + OP_MODE) & + ~(MULTI_WORD_DMA_ENB | ULTRA_DMA_ENB); + tmcfg = readl(acdev->vbase + TM_CFG); + + if ((dma_mode >= XFER_UDMA_0) && (dma_mode <= XFER_UDMA_6)) { + opmode |= ULTRA_DMA_ENB; + tmcfg &= ~ULTRA_DMA_TIMING_MASK; + tmcfg |= (dma_mode - XFER_UDMA_0) << ULTRA_DMA_TIMING_SHIFT; + } else if ((dma_mode >= XFER_MW_DMA_0) && (dma_mode <= XFER_MW_DMA_4)) { + opmode |= MULTI_WORD_DMA_ENB; + tmcfg &= ~TRUEIDE_MWORD_DMA_TIMING_MASK; + tmcfg |= (dma_mode - XFER_MW_DMA_0) << + TRUEIDE_MWORD_DMA_TIMING_SHIFT; + } else { + dev_err(ap->dev, "Unknown DMA mode\n"); + spin_unlock_irqrestore(&acdev->host->lock, flags); + return; + } + + writel(opmode, acdev->vbase + OP_MODE); + writel(tmcfg, acdev->vbase + TM_CFG); + writel(DMA_XFER_MODE, acdev->vbase + XFER_CTR); + + cf_interrupt_enable(acdev, PIO_XFER_ERR_IRQ, 0); + cf_interrupt_enable(acdev, BUF_AVAIL_IRQ | XFER_DONE_IRQ, 1); + spin_unlock_irqrestore(&acdev->host->lock, flags); +} + +static struct ata_port_operations arasan_cf_ops = { + .inherits = &ata_sff_port_ops, + .freeze = arasan_cf_freeze, + .error_handler = arasan_cf_error_handler, + .qc_issue = arasan_cf_qc_issue, + .set_piomode = arasan_cf_set_piomode, + .set_dmamode = arasan_cf_set_dmamode, +}; + +static int __devinit arasan_cf_probe(struct platform_device *pdev) +{ + struct arasan_cf_dev *acdev; + struct arasan_cf_pdata *pdata = dev_get_platdata(&pdev->dev); + struct ata_host *host; + struct ata_port *ap; + struct resource *res; + irq_handler_t irq_handler = NULL; + int ret = 0; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; + + if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res), + DRIVER_NAME)) { + dev_warn(&pdev->dev, "Failed to get memory region resource\n"); + return -ENOENT; + } + + acdev = devm_kzalloc(&pdev->dev, sizeof(*acdev), GFP_KERNEL); + if (!acdev) { + dev_warn(&pdev->dev, "kzalloc fail\n"); + return -ENOMEM; + } + + /* if irq is 0, support only PIO */ + acdev->irq = platform_get_irq(pdev, 0); + if (acdev->irq) + irq_handler = arasan_cf_interrupt; + else + pdata->quirk |= CF_BROKEN_MWDMA | CF_BROKEN_UDMA; + + acdev->pbase = res->start; + acdev->vbase = devm_ioremap_nocache(&pdev->dev, res->start, + resource_size(res)); + if (!acdev->vbase) { + dev_warn(&pdev->dev, "ioremap fail\n"); + return -ENOMEM; + } + +#ifdef CONFIG_HAVE_CLK + acdev->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(acdev->clk)) { + dev_warn(&pdev->dev, "Clock not found\n"); + return PTR_ERR(acdev->clk); + } +#endif + + /* allocate host */ + host = ata_host_alloc(&pdev->dev, 1); + if (!host) { + ret = -ENOMEM; + dev_warn(&pdev->dev, "alloc host fail\n"); + goto free_clk; + } + + ap = host->ports[0]; + host->private_data = acdev; + acdev->host = host; + ap->ops = &arasan_cf_ops; + ap->pio_mask = ATA_PIO6; + ap->mwdma_mask = ATA_MWDMA4; + ap->udma_mask = ATA_UDMA6; + + init_completion(&acdev->cf_completion); + init_completion(&acdev->dma_completion); + INIT_WORK(&acdev->work, data_xfer); + INIT_DELAYED_WORK(&acdev->dwork, delayed_finish); + dma_cap_set(DMA_MEMCPY, acdev->mask); + + /* Handle platform specific quirks */ + if (pdata->quirk) { + if (pdata->quirk & CF_BROKEN_PIO) { + ap->ops->set_piomode = NULL; + ap->pio_mask = 0; + } + if (pdata->quirk & CF_BROKEN_MWDMA) + ap->mwdma_mask = 0; + if (pdata->quirk & CF_BROKEN_UDMA) + ap->udma_mask = 0; + } + ap->flags |= ATA_FLAG_PIO_POLLING | ATA_FLAG_NO_ATAPI; + + ap->ioaddr.cmd_addr = acdev->vbase + ATA_DATA_PORT; + ap->ioaddr.data_addr = acdev->vbase + ATA_DATA_PORT; + ap->ioaddr.error_addr = acdev->vbase + ATA_ERR_FTR; + ap->ioaddr.feature_addr = acdev->vbase + ATA_ERR_FTR; + ap->ioaddr.nsect_addr = acdev->vbase + ATA_SC; + ap->ioaddr.lbal_addr = acdev->vbase + ATA_SN; + ap->ioaddr.lbam_addr = acdev->vbase + ATA_CL; + ap->ioaddr.lbah_addr = acdev->vbase + ATA_CH; + ap->ioaddr.device_addr = acdev->vbase + ATA_SH; + ap->ioaddr.status_addr = acdev->vbase + ATA_STS_CMD; + ap->ioaddr.command_addr = acdev->vbase + ATA_STS_CMD; + ap->ioaddr.altstatus_addr = acdev->vbase + ATA_ASTS_DCTR; + ap->ioaddr.ctl_addr = acdev->vbase + ATA_ASTS_DCTR; + + ata_port_desc(ap, "phy_addr %x virt_addr %p", res->start, acdev->vbase); + + ret = cf_init(acdev); + if (ret) + goto free_clk; + + cf_card_detect(acdev, 0); + + return ata_host_activate(host, acdev->irq, irq_handler, 0, + &arasan_cf_sht); + +free_clk: +#ifdef CONFIG_HAVE_CLK + clk_put(acdev->clk); +#endif + return ret; +} + +static int __devexit arasan_cf_remove(struct platform_device *pdev) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct arasan_cf_dev *acdev = host->ports[0]->private_data; + + ata_host_detach(host); + cf_exit(acdev); +#ifdef CONFIG_HAVE_CLK + clk_put(acdev->clk); +#endif + + return 0; +} + +#ifdef CONFIG_PM +static int arasan_cf_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct arasan_cf_dev *acdev = host->ports[0]->private_data; + + if (acdev->dma_chan) { + acdev->dma_chan->device->device_control(acdev->dma_chan, + DMA_TERMINATE_ALL, 0); + dma_release_channel(acdev->dma_chan); + } + cf_exit(acdev); + return ata_host_suspend(host, PMSG_SUSPEND); +} + +static int arasan_cf_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct arasan_cf_dev *acdev = host->ports[0]->private_data; + + cf_init(acdev); + ata_host_resume(host); + + return 0; +} + +static const struct dev_pm_ops arasan_cf_pm_ops = { + .suspend = arasan_cf_suspend, + .resume = arasan_cf_resume, +}; +#endif + +static struct platform_driver arasan_cf_driver = { + .probe = arasan_cf_probe, + .remove = __devexit_p(arasan_cf_remove), + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &arasan_cf_pm_ops, +#endif + }, +}; + +static int __init arasan_cf_init(void) +{ + return platform_driver_register(&arasan_cf_driver); +} +module_init(arasan_cf_init); + +static void __exit arasan_cf_exit(void) +{ + platform_driver_unregister(&arasan_cf_driver); +} +module_exit(arasan_cf_exit); + +MODULE_AUTHOR("Viresh Kumar "); +MODULE_DESCRIPTION("Arasan ATA Compact Flash driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/include/linux/pata_arasan_cf_data.h b/include/linux/pata_arasan_cf_data.h new file mode 100644 index 000000000000..d979fe688796 --- /dev/null +++ b/include/linux/pata_arasan_cf_data.h @@ -0,0 +1,47 @@ +/* + * include/linux/pata_arasan_cf_data.h + * + * Arasan Compact Flash host controller platform data header file + * + * Copyright (C) 2011 ST Microelectronics + * Viresh Kumar + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef _PATA_ARASAN_CF_DATA_H +#define _PATA_ARASAN_CF_DATA_H + +#include + +struct arasan_cf_pdata { + u8 cf_if_clk; + #define CF_IF_CLK_100M (0x0) + #define CF_IF_CLK_75M (0x1) + #define CF_IF_CLK_66M (0x2) + #define CF_IF_CLK_50M (0x3) + #define CF_IF_CLK_40M (0x4) + #define CF_IF_CLK_33M (0x5) + #define CF_IF_CLK_25M (0x6) + #define CF_IF_CLK_125M (0x7) + #define CF_IF_CLK_150M (0x8) + #define CF_IF_CLK_166M (0x9) + #define CF_IF_CLK_200M (0xA) + /* + * Platform specific incapabilities of CF controller is handled via + * quirks + */ + u32 quirk; + #define CF_BROKEN_PIO (1) + #define CF_BROKEN_MWDMA (1 << 1) + #define CF_BROKEN_UDMA (1 << 2) +}; + +static inline void +set_arasan_cf_pdata(struct platform_device *pdev, struct arasan_cf_pdata *data) +{ + pdev->dev.platform_data = data; +} +#endif /* _PATA_ARASAN_CF_DATA_H */ -- cgit v1.2.3 From a17139b6f63709b2d409c027f8ab401f5aa136d3 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 14 Mar 2011 02:54:03 -0400 Subject: pata_arasan_cf: fix printk format string warning Signed-off-by: Jeff Garzik --- drivers/ata/pata_arasan_cf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index b99b3fce307f..8b060c44bbe1 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -881,7 +881,8 @@ static int __devinit arasan_cf_probe(struct platform_device *pdev) ap->ioaddr.altstatus_addr = acdev->vbase + ATA_ASTS_DCTR; ap->ioaddr.ctl_addr = acdev->vbase + ATA_ASTS_DCTR; - ata_port_desc(ap, "phy_addr %x virt_addr %p", res->start, acdev->vbase); + ata_port_desc(ap, "phy_addr %llx virt_addr %p", + (unsigned long long) res->start, acdev->vbase); ret = cf_init(acdev); if (ret) -- cgit v1.2.3 From 8d7b1c70b3c1aac4b63109f5c73f732f1d63fad6 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 31 Jan 2011 08:39:24 -0800 Subject: ata: pata: Convert pr_*(DRV_NAME ...) to pr_fmt/pr_ Commit 40d69ba029c8d5de51aaeb5358999266c482d00a ("pata_hpt{37x|3x2n}: use pr_*(DRV_NAME ...) instead of printk(KERN_* ...)") used pr_. Add #define pr_fmt and remove DRV_NAME. Increment driver version numbers. Signed-off-by: Joe Perches Signed-off-by: Jeff Garzik --- drivers/ata/pata_hpt366.c | 7 ++++--- drivers/ata/pata_hpt37x.c | 23 ++++++++++++----------- drivers/ata/pata_hpt3x2n.c | 13 +++++++------ 3 files changed, 23 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index 538ec38ba995..6c77d68dbd05 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c @@ -14,6 +14,7 @@ * Look into engine reset on timeout errors. Should not be required. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include @@ -25,7 +26,7 @@ #include #define DRV_NAME "pata_hpt366" -#define DRV_VERSION "0.6.10" +#define DRV_VERSION "0.6.11" struct hpt_clock { u8 xfer_mode; @@ -160,8 +161,8 @@ static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, while (list[i] != NULL) { if (!strcmp(list[i], model_num)) { - pr_warning(DRV_NAME ": %s is not supported for %s.\n", - modestr, list[i]); + pr_warn("%s is not supported for %s\n", + modestr, list[i]); return 1; } i++; diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 4c5b5183225e..9620636aa405 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -14,6 +14,8 @@ * Look into engine reset on timeout errors. Should not be required. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -24,7 +26,7 @@ #include #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.6.22" +#define DRV_VERSION "0.6.23" struct hpt_clock { u8 xfer_speed; @@ -229,8 +231,8 @@ static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, while (list[i] != NULL) { if (!strcmp(list[i], model_num)) { - pr_warning(DRV_NAME ": %s is not supported for %s.\n", - modestr, list[i]); + pr_warn("%s is not supported for %s\n", + modestr, list[i]); return 1; } i++; @@ -863,8 +865,8 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) chip_table = &hpt372; break; default: - pr_err(DRV_NAME ": Unknown HPT366 subtype, " - "please report (%d).\n", rev); + pr_err("Unknown HPT366 subtype, please report (%d)\n", + rev); return -ENODEV; } break; @@ -904,8 +906,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) *ppi = &info_hpt374_fn1; break; default: - pr_err(DRV_NAME ": PCI table is bogus, please report (%d).\n", - dev->device); + pr_err("PCI table is bogus, please report (%d)\n", dev->device); return -ENODEV; } /* Ok so this is a chip we support */ @@ -953,7 +954,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) u8 sr; u32 total = 0; - pr_warning(DRV_NAME ": BIOS has not set timing clocks.\n"); + pr_warn("BIOS has not set timing clocks\n"); /* This is the process the HPT371 BIOS is reported to use */ for (i = 0; i < 128; i++) { @@ -1009,7 +1010,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) (f_high << 16) | f_low | 0x100); } if (adjust == 8) { - pr_err(DRV_NAME ": DPLL did not stabilize!\n"); + pr_err("DPLL did not stabilize!\n"); return -ENODEV; } if (dpll == 3) @@ -1017,7 +1018,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) else private_data = (void *)hpt37x_timings_50; - pr_info(DRV_NAME ": bus clock %dMHz, using %dMHz DPLL.\n", + pr_info("bus clock %dMHz, using %dMHz DPLL\n", MHz[clock_slot], MHz[dpll]); } else { private_data = (void *)chip_table->clocks[clock_slot]; @@ -1032,7 +1033,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) if (clock_slot < 2 && ppi[0] == &info_hpt370a) ppi[0] = &info_hpt370a_33; - pr_info(DRV_NAME ": %s using %dMHz bus clock.\n", + pr_info("%s using %dMHz bus clock\n", chip_table->name, MHz[clock_slot]); } diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index eca68caf5f46..765f136d8cd3 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -15,6 +15,8 @@ * Work out best PLL policy */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -25,7 +27,7 @@ #include #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3.14" +#define DRV_VERSION "0.3.15" enum { HPT_PCI_FAST = (1 << 31), @@ -418,7 +420,7 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev) u16 sr; u32 total = 0; - pr_warning(DRV_NAME ": BIOS clock data not set.\n"); + pr_warn("BIOS clock data not set\n"); /* This is the process the HPT371 BIOS is reported to use */ for (i = 0; i < 128; i++) { @@ -528,8 +530,7 @@ hpt372n: ppi[0] = &info_hpt372n; break; default: - pr_err(DRV_NAME ": PCI table is bogus, please report (%d).\n", - dev->device); + pr_err("PCI table is bogus, please report (%d)\n", dev->device); return -ENODEV; } @@ -578,11 +579,11 @@ hpt372n: pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); } if (adjust == 8) { - pr_err(DRV_NAME ": DPLL did not stabilize!\n"); + pr_err("DPLL did not stabilize!\n"); return -ENODEV; } - pr_info(DRV_NAME ": bus clock %dMHz, using 66MHz DPLL.\n", pci_mhz); + pr_info("bus clock %dMHz, using 66MHz DPLL\n", pci_mhz); /* * Set our private data up. We only need a few flags -- cgit v1.2.3 From 60a230e4a62be6837335911b09101bd8aeb7c95a Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 4 Mar 2011 16:39:29 +0530 Subject: ata/pata_arasan_cf: fill dma chan->private from pdata->dma_priv Some DMA controllers (eg: drivers/dma/dw_dmac*) allow platform specific configuration for dma transfers. User drivers need to set chan->private field of channel with pointer to configuration data. This patch takes dma_priv data from platform data and passes it to chan->private_data, in order to pass platform specific configuration to DMAC controller. Signed-off-by: Viresh Kumar Signed-off-by: Jeff Garzik --- drivers/ata/pata_arasan_cf.c | 7 ++++++- include/linux/pata_arasan_cf_data.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 8b060c44bbe1..65cee74605b4 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -210,6 +210,8 @@ struct arasan_cf_dev { struct dma_chan *dma_chan; /* Mask for DMA transfers */ dma_cap_mask_t mask; + /* dma channel private data */ + void *dma_priv; /* DMA transfer work */ struct work_struct work; /* DMA delayed finish work */ @@ -356,6 +358,7 @@ static void dma_callback(void *dev) static bool filter(struct dma_chan *chan, void *slave) { + chan->private = slave; return true; } @@ -526,7 +529,8 @@ static void data_xfer(struct work_struct *work) /* request dma channels */ /* dma_request_channel may sleep, so calling from process context */ - acdev->dma_chan = dma_request_channel(acdev->mask, filter, NULL); + acdev->dma_chan = dma_request_channel(acdev->mask, filter, + acdev->dma_priv); if (!acdev->dma_chan) { dev_err(acdev->host->dev, "Unable to get dma_chan\n"); goto chan_request_fail; @@ -853,6 +857,7 @@ static int __devinit arasan_cf_probe(struct platform_device *pdev) INIT_WORK(&acdev->work, data_xfer); INIT_DELAYED_WORK(&acdev->dwork, delayed_finish); dma_cap_set(DMA_MEMCPY, acdev->mask); + acdev->dma_priv = pdata->dma_priv; /* Handle platform specific quirks */ if (pdata->quirk) { diff --git a/include/linux/pata_arasan_cf_data.h b/include/linux/pata_arasan_cf_data.h index d979fe688796..a6ee9aa898bb 100644 --- a/include/linux/pata_arasan_cf_data.h +++ b/include/linux/pata_arasan_cf_data.h @@ -37,6 +37,8 @@ struct arasan_cf_pdata { #define CF_BROKEN_PIO (1) #define CF_BROKEN_MWDMA (1 << 1) #define CF_BROKEN_UDMA (1 << 2) + /* This is platform specific data for the DMA controller */ + void *dma_priv; }; static inline void -- cgit v1.2.3 From 6b3b9d73e08d8939aaf54f85bb47495171f49e20 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 7 Mar 2011 08:56:44 +0100 Subject: libata: Include WWN ID in inquiry VPD emulation As per SAT-3 the WWN ID should be included in the VPD page 0x83 (device identification) emulation. Signed-off-by: Hannes Reinecke Acked-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 11 +++++++++++ include/linux/ata.h | 7 +++++++ 2 files changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index c11675f34b93..a83419991357 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2056,6 +2056,17 @@ static unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf) ATA_ID_SERNO_LEN); num += ATA_ID_SERNO_LEN; + if (ata_id_has_wwn(args->id)) { + /* SAT defined lu world wide name */ + /* piv=0, assoc=lu, code_set=binary, designator=NAA */ + rbuf[num + 0] = 1; + rbuf[num + 1] = 3; + rbuf[num + 3] = ATA_ID_WWN_LEN; + num += 4; + ata_id_string(args->id, (unsigned char *) rbuf + num, + ATA_ID_WWN, ATA_ID_WWN_LEN); + num += ATA_ID_WWN_LEN; + } rbuf[3] = num - 4; /* page len (assume less than 256 bytes) */ return 0; } diff --git a/include/linux/ata.h b/include/linux/ata.h index 0c4929fa34d3..198e1ea2b2eb 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -89,6 +89,7 @@ enum { ATA_ID_SPG = 98, ATA_ID_LBA_CAPACITY_2 = 100, ATA_ID_SECTOR_SIZE = 106, + ATA_ID_WWN = 108, ATA_ID_LOGICAL_SECTOR_SIZE = 117, /* and 118 */ ATA_ID_LAST_LUN = 126, ATA_ID_DLF = 128, @@ -103,6 +104,7 @@ enum { ATA_ID_SERNO_LEN = 20, ATA_ID_FW_REV_LEN = 8, ATA_ID_PROD_LEN = 40, + ATA_ID_WWN_LEN = 8, ATA_PCI_CTL_OFS = 2, @@ -815,6 +817,11 @@ static inline int ata_id_has_unload(const u16 *id) return 0; } +static inline bool ata_id_has_wwn(const u16 *id) +{ + return (id[ATA_ID_CSF_DEFAULT] & 0xC100) == 0x4100; +} + static inline int ata_id_form_factor(const u16 *id) { u16 val = id[168]; -- cgit v1.2.3 From 4ac7534a7ff1aa1b1486e39bdf169aaa8a9bb3e2 Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Wed, 9 Mar 2011 12:47:18 +0530 Subject: sata_fsl: Fix wrong Device Error Register usage When a single device error is detected, the device under the error is indicated by the error bit set in the DER. There is a one to one mapping between register bit and devices on Port multiplier(PMP) i.e. bit 0 represents PMP device 0 and bit 1 represents PMP device 1 etc. Current implementation treats Device error register value as device number not set of bits representing multiple device on PMP. It is changed to consider bit level. No need to check for each set bit as all command is going to be aborted. Signed-off-by: Ashish Kalra Signed-off-by: Prabhakar Kushwaha Signed-off-by: Jeff Garzik --- drivers/ata/sata_fsl.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index beef37134a04..2ddb567f165b 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -1039,12 +1039,15 @@ static void sata_fsl_error_intr(struct ata_port *ap) /* find out the offending link and qc */ if (ap->nr_pmp_links) { + unsigned int dev_num; + dereg = ioread32(hcr_base + DE); iowrite32(dereg, hcr_base + DE); iowrite32(cereg, hcr_base + CE); - if (dereg < ap->nr_pmp_links) { - link = &ap->pmp_link[dereg]; + dev_num = ffs(dereg) - 1; + if (dev_num < ap->nr_pmp_links && dereg != 0) { + link = &ap->pmp_link[dev_num]; ehi = &link->eh_info; qc = ata_qc_from_tag(ap, link->active_tag); /* -- cgit v1.2.3 From 578ca87c9d18d344b449a8eefee40c10e4fc319f Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Mon, 7 Mar 2011 09:28:10 +0530 Subject: sata_fsl: Update RX_WATER_MARK for TRANSCFG RX_WATER_MARK sets the number of locations in Rx FIFO that can be used before the transport layer instructs the link layer to transmit HOLDS. Note that it can take some time for the HOLDs to get to the other end, and that in the interim there must be enough room in the FIFO to absorb all data that could arrive. Update the new recommended value to 16. Signed-off-by: Prabhakar Kushwaha Signed-off-by: Jeff Garzik --- drivers/ata/sata_fsl.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 2ddb567f165b..7f9eab34a386 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -185,6 +185,11 @@ enum { COMMANDSTAT = 0x20, }; +/* TRANSCFG (transport-layer) configuration control */ +enum { + TRANSCFG_RX_WATER_MARK = (1 << 4), +}; + /* PHY (link-layer) configuration control */ enum { PHY_BIST_ENABLE = 0x01, @@ -1305,6 +1310,7 @@ static int sata_fsl_probe(struct platform_device *ofdev, struct sata_fsl_host_priv *host_priv = NULL; int irq; struct ata_host *host; + u32 temp; struct ata_port_info pi = sata_fsl_port_info[0]; const struct ata_port_info *ppi[] = { &pi, NULL }; @@ -1319,6 +1325,12 @@ static int sata_fsl_probe(struct platform_device *ofdev, ssr_base = hcr_base + 0x100; csr_base = hcr_base + 0x140; + if (!of_device_is_compatible(ofdev->dev.of_node, "fsl,mpc8315-sata")) { + temp = ioread32(csr_base + TRANSCFG); + temp = temp & 0xffffffe0; + iowrite32(temp | TRANSCFG_RX_WATER_MARK, csr_base + TRANSCFG); + } + DPRINTK("@reset i/o = 0x%x\n", ioread32(csr_base + TRANSCFG)); DPRINTK("sizeof(cmd_desc) = %d\n", sizeof(struct command_desc)); DPRINTK("sizeof(#define cmd_desc) = %d\n", SATA_FSL_CMD_DESC_SIZE); -- cgit v1.2.3 From bbd562d717a84c6464211e8bd5efa0d9e25edc6d Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Mon, 21 Feb 2011 10:52:43 +0000 Subject: watchdog: cpwd: Fix buffer-overflow cppcheck-1.47 reports: [drivers/watchdog/cpwd.c:650]: (error) Buffer access out-of-bounds: p.devs The source code is for (i = 0; i < 4; i++) { misc_deregister(&p->devs[i].misc); where devs is defined as WD_NUMDEVS big and WD_NUMDEVS is equal to 3. So the 4 should be a 3 or WD_NUMDEVS. Reported-By: David Binderman Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/cpwd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index eca855a55c0d..3de4ba0260a5 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c @@ -646,7 +646,7 @@ static int __devexit cpwd_remove(struct platform_device *op) struct cpwd *p = dev_get_drvdata(&op->dev); int i; - for (i = 0; i < 4; i++) { + for (i = 0; i < WD_NUMDEVS; i++) { misc_deregister(&p->devs[i].misc); if (!p->enabled) { -- cgit v1.2.3 From a450c786a5769745cc8fa873a66ed3c377875ead Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Mon, 21 Feb 2011 19:09:40 +0000 Subject: watchdog: sch311x_wdt: Fix LDN active check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit if (sch311x_sio_inb(sio_config_port, 0x30) && 0x01 == 0) -> && should be & Reported-By: Toralf Förster Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/sch311x_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c index 0461858e07d0..7b687e9497f0 100644 --- a/drivers/watchdog/sch311x_wdt.c +++ b/drivers/watchdog/sch311x_wdt.c @@ -508,7 +508,7 @@ static int __init sch311x_detect(int sio_config_port, unsigned short *addr) sch311x_sio_outb(sio_config_port, 0x07, 0x0a); /* Check if Logical Device Register is currently active */ - if (sch311x_sio_inb(sio_config_port, 0x30) && 0x01 == 0) + if (sch311x_sio_inb(sio_config_port, 0x30) & 0x01 == 0) printk(KERN_INFO PFX "Seems that LDN 0x0a is not active...\n"); /* Get the base address of the runtime registers */ -- cgit v1.2.3 From 6899a8e13f76f37029084c891312e2cfad1305c8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 23 Feb 2011 23:26:01 +0300 Subject: watchdog: sch311x_wdt: fix printk condition "==" has higher precedence than "&". Since if (sch311x_sio_inb(sio_config_port, 0x30) & (0x01 == 0)) is always false the message is never printed. Signed-off-by: Dan Carpenter Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/sch311x_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c index 7b687e9497f0..b61ab1c54293 100644 --- a/drivers/watchdog/sch311x_wdt.c +++ b/drivers/watchdog/sch311x_wdt.c @@ -508,7 +508,7 @@ static int __init sch311x_detect(int sio_config_port, unsigned short *addr) sch311x_sio_outb(sio_config_port, 0x07, 0x0a); /* Check if Logical Device Register is currently active */ - if (sch311x_sio_inb(sio_config_port, 0x30) & 0x01 == 0) + if ((sch311x_sio_inb(sio_config_port, 0x30) & 0x01) == 0) printk(KERN_INFO PFX "Seems that LDN 0x0a is not active...\n"); /* Get the base address of the runtime registers */ -- cgit v1.2.3 From 943413c5b6e117a7eca029e3b07704d3b230d938 Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Mon, 21 Feb 2011 19:28:58 +0000 Subject: watchdog: w83697ug_wdt: Fix set bit 0 to activate GPIO2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit outb_p(c || 0x01, WDT_EFDR); -> || should be | Reported-By: Toralf Förster Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/w83697ug_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/w83697ug_wdt.c b/drivers/watchdog/w83697ug_wdt.c index a6c12dec91a1..df2a64dc9672 100644 --- a/drivers/watchdog/w83697ug_wdt.c +++ b/drivers/watchdog/w83697ug_wdt.c @@ -109,7 +109,7 @@ static int w83697ug_select_wd_register(void) outb_p(0x08, WDT_EFDR); /* select logical device 8 (GPIO2) */ outb_p(0x30, WDT_EFER); /* select CR30 */ c = inb_p(WDT_EFDR); - outb_p(c || 0x01, WDT_EFDR); /* set bit 0 to activate GPIO2 */ + outb_p(c | 0x01, WDT_EFDR); /* set bit 0 to activate GPIO2 */ return 0; } -- cgit v1.2.3 From b77b708868c23737a4d25a474736cc924deb44f1 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 2 Mar 2011 11:49:44 +0800 Subject: watchdog: hpwdt: eliminate section mismatch warning hpwdt_init_nmi_decoding() is called in hpwdt_init_one error handling, thus remove the __devexit annotation of hpwdt_exit_nmi_decoding(). This patch fixes below warning: WARNING: drivers/watchdog/hpwdt.o(.devinit.text+0x36f): Section mismatch in reference from the function hpwdt_init_one() to the function .devexit.text:hpwdt_exit_nmi_decoding() The function __devinit hpwdt_init_one() references a function __devexit hpwdt_exit_nmi_decoding(). This is often seen when error handling in the init function uses functionality in the exit path. The fix is often to remove the __devexit annotation of hpwdt_exit_nmi_decoding() so it may be used outside an exit section. Signed-off-by: Axel Lin Acked-by: Thomas Mingarelli Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/hpwdt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 24b966d5061a..204a5603c4ae 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -710,7 +710,7 @@ static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev) return 0; } -static void __devexit hpwdt_exit_nmi_decoding(void) +static void hpwdt_exit_nmi_decoding(void) { unregister_die_notifier(&die_notifier); if (cru_rom_addr) @@ -726,7 +726,7 @@ static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev) return 0; } -static void __devexit hpwdt_exit_nmi_decoding(void) +static void hpwdt_exit_nmi_decoding(void) { } #endif /* CONFIG_HPWDT_NMI_DECODING */ -- cgit v1.2.3 From 29422693c410c68071bdd60e0a0ec590490781aa Mon Sep 17 00:00:00 2001 From: Mike Waychison Date: Fri, 11 Mar 2011 17:43:00 -0800 Subject: efivars: move efivars globals into struct efivars In preparation for abstracting out efivars to be usable by other similar variable services, move the global lock, list and kset into a structure. Later patches will change the scope of 'efivars' and have it be passed by function argument. Signed-off-by: Mike Waychison Cc: Matt Domsch , Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/efivars.c | 86 +++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 2a62ec6390e0..f10ecb6d04b2 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -89,16 +89,21 @@ MODULE_DESCRIPTION("sysfs interface to EFI Variables"); MODULE_LICENSE("GPL"); MODULE_VERSION(EFIVARS_VERSION); -/* - * efivars_lock protects two things: - * 1) efivar_list - adds, removals, reads, writes - * 2) efi.[gs]et_variable() calls. - * It must not be held when creating sysfs entries or calling kmalloc. - * efi.get_next_variable() is only called from efivars_init(), - * which is protected by the BKL, so that path is safe. - */ -static DEFINE_SPINLOCK(efivars_lock); -static LIST_HEAD(efivar_list); +struct efivars { + /* + * ->lock protects two things: + * 1) ->list - adds, removals, reads, writes + * 2) efi.[gs]et_variable() calls. + * It must not be held when creating sysfs entries or calling kmalloc. + * efi.get_next_variable() is only called from efivars_init(), + * which is protected by the BKL, so that path is safe. + */ + spinlock_t lock; + struct list_head list; + struct kset *kset; +}; +static struct efivars __efivars; +static struct efivars *efivars = &__efivars; /* * The maximum size of VariableName + Data = 1024 @@ -174,14 +179,14 @@ get_var_data(struct efi_variable *var) { efi_status_t status; - spin_lock(&efivars_lock); + spin_lock(&efivars->lock); var->DataSize = 1024; status = efi.get_variable(var->VariableName, &var->VendorGuid, &var->Attributes, &var->DataSize, var->Data); - spin_unlock(&efivars_lock); + spin_unlock(&efivars->lock); if (status != EFI_SUCCESS) { printk(KERN_WARNING "efivars: get_variable() failed 0x%lx!\n", status); @@ -291,14 +296,14 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) return -EINVAL; } - spin_lock(&efivars_lock); + spin_lock(&efivars->lock); status = efi.set_variable(new_var->VariableName, &new_var->VendorGuid, new_var->Attributes, new_var->DataSize, new_var->Data); - spin_unlock(&efivars_lock); + spin_unlock(&efivars->lock); if (status != EFI_SUCCESS) { printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n", @@ -415,12 +420,12 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, if (!capable(CAP_SYS_ADMIN)) return -EACCES; - spin_lock(&efivars_lock); + spin_lock(&efivars->lock); /* * Does this variable already exist? */ - list_for_each_entry_safe(search_efivar, n, &efivar_list, list) { + list_for_each_entry_safe(search_efivar, n, &efivars->list, list) { strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); strsize2 = utf8_strsize(new_var->VariableName, 1024); if (strsize1 == strsize2 && @@ -433,7 +438,7 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, } } if (found) { - spin_unlock(&efivars_lock); + spin_unlock(&efivars->lock); return -EINVAL; } @@ -447,10 +452,10 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, if (status != EFI_SUCCESS) { printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n", status); - spin_unlock(&efivars_lock); + spin_unlock(&efivars->lock); return -EIO; } - spin_unlock(&efivars_lock); + spin_unlock(&efivars->lock); /* Create the entry in sysfs. Locking is not required here */ status = efivar_create_sysfs_entry(utf8_strsize(new_var->VariableName, @@ -474,12 +479,12 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, if (!capable(CAP_SYS_ADMIN)) return -EACCES; - spin_lock(&efivars_lock); + spin_lock(&efivars->lock); /* * Does this variable already exist? */ - list_for_each_entry_safe(search_efivar, n, &efivar_list, list) { + list_for_each_entry_safe(search_efivar, n, &efivars->list, list) { strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); strsize2 = utf8_strsize(del_var->VariableName, 1024); if (strsize1 == strsize2 && @@ -492,7 +497,7 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, } } if (!found) { - spin_unlock(&efivars_lock); + spin_unlock(&efivars->lock); return -EINVAL; } /* force the Attributes/DataSize to 0 to ensure deletion */ @@ -508,12 +513,12 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, if (status != EFI_SUCCESS) { printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n", status); - spin_unlock(&efivars_lock); + spin_unlock(&efivars->lock); return -EIO; } list_del(&search_efivar->list); /* We need to release this lock before unregistering. */ - spin_unlock(&efivars_lock); + spin_unlock(&efivars->lock); efivar_unregister(search_efivar); /* It's dead Jim.... */ @@ -572,8 +577,6 @@ static struct attribute_group efi_subsys_attr_group = { .attrs = efi_subsys_attrs, }; - -static struct kset *vars_kset; static struct kobject *efi_kobj; /* @@ -582,7 +585,7 @@ static struct kobject *efi_kobj; * variable_name_size = number of bytes required to hold * variable_name (not counting the NULL * character at the end. - * efivars_lock is not held on entry or exit. + * efivars->lock is not held on entry or exit. * Returns 1 on failure, 0 on success */ static int @@ -618,7 +621,7 @@ efivar_create_sysfs_entry(unsigned long variable_name_size, *(short_name + strlen(short_name)) = '-'; efi_guid_unparse(vendor_guid, short_name + strlen(short_name)); - new_efivar->kobj.kset = vars_kset; + new_efivar->kobj.kset = efivars->kset; i = kobject_init_and_add(&new_efivar->kobj, &efivar_ktype, NULL, "%s", short_name); if (i) { @@ -631,9 +634,9 @@ efivar_create_sysfs_entry(unsigned long variable_name_size, kfree(short_name); short_name = NULL; - spin_lock(&efivars_lock); - list_add(&new_efivar->list, &efivar_list); - spin_unlock(&efivars_lock); + spin_lock(&efivars->lock); + list_add(&new_efivar->list, &efivars->list); + spin_unlock(&efivars->lock); return 0; } @@ -674,8 +677,11 @@ efivars_init(void) goto out_free; } - vars_kset = kset_create_and_add("vars", NULL, efi_kobj); - if (!vars_kset) { + spin_lock_init(&efivars->lock); + INIT_LIST_HEAD(&efivars->list); + + efivars->kset = kset_create_and_add("vars", NULL, efi_kobj); + if (!efivars->kset) { printk(KERN_ERR "efivars: Subsystem registration failed.\n"); error = -ENOMEM; goto out_firmware_unregister; @@ -712,12 +718,12 @@ efivars_init(void) * Now add attributes to allow creation of new vars * and deletion of existing ones... */ - error = sysfs_create_bin_file(&vars_kset->kobj, + error = sysfs_create_bin_file(&efivars->kset->kobj, &var_subsys_attr_new_var); if (error) printk(KERN_ERR "efivars: unable to create new_var sysfs file" " due to error %d\n", error); - error = sysfs_create_bin_file(&vars_kset->kobj, + error = sysfs_create_bin_file(&efivars->kset->kobj, &var_subsys_attr_del_var); if (error) printk(KERN_ERR "efivars: unable to create del_var sysfs file" @@ -730,7 +736,7 @@ efivars_init(void) else goto out_free; - kset_unregister(vars_kset); + kset_unregister(efivars->kset); out_firmware_unregister: kobject_put(efi_kobj); @@ -746,14 +752,14 @@ efivars_exit(void) { struct efivar_entry *entry, *n; - list_for_each_entry_safe(entry, n, &efivar_list, list) { - spin_lock(&efivars_lock); + list_for_each_entry_safe(entry, n, &efivars->list, list) { + spin_lock(&efivars->lock); list_del(&entry->list); - spin_unlock(&efivars_lock); + spin_unlock(&efivars->lock); efivar_unregister(entry); } - kset_unregister(vars_kset); + kset_unregister(efivars->kset); kobject_put(efi_kobj); } -- cgit v1.2.3 From d502fbb0dc4d4babe5fb330257fa49a83fbf86a6 Mon Sep 17 00:00:00 2001 From: Mike Waychison Date: Fri, 11 Mar 2011 17:43:06 -0800 Subject: efivars: Make efivars bin_attributes dynamic In preparation for encapsulating efivars, we need to have the bin_attributes be dynamically allocated so that we can use their ->private fields to get back to the struct efivars structure. Signed-off-by: Mike Waychison Cc: Matt Domsch , Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/efivars.c | 93 +++++++++++++++++++++++++++++++++------------- 1 file changed, 68 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index f10ecb6d04b2..528ce47c1368 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -101,6 +101,7 @@ struct efivars { spinlock_t lock; struct list_head list; struct kset *kset; + struct bin_attribute *new_var, *del_var; }; static struct efivars __efivars; static struct efivars *efivars = &__efivars; @@ -525,16 +526,6 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, return count; } -static struct bin_attribute var_subsys_attr_new_var = { - .attr = {.name = "new_var", .mode = 0200}, - .write = efivar_create, -}; - -static struct bin_attribute var_subsys_attr_del_var = { - .attr = {.name = "del_var", .mode = 0200}, - .write = efivar_delete, -}; - /* * Let's not leave out systab information that snuck into * the efivars driver @@ -640,6 +631,66 @@ efivar_create_sysfs_entry(unsigned long variable_name_size, return 0; } + +static int +create_efivars_bin_attributes(struct efivars *efivars) +{ + struct bin_attribute *attr; + int error; + + /* new_var */ + attr = kzalloc(sizeof(*attr), GFP_KERNEL); + if (!attr) + return -ENOMEM; + + attr->attr.name = "new_var"; + attr->attr.mode = 0200; + attr->write = efivar_create; + attr->private = efivars; + efivars->new_var = attr; + + /* del_var */ + attr = kzalloc(sizeof(*attr), GFP_KERNEL); + if (!attr) { + error = -ENOMEM; + goto out_free; + } + attr->attr.name = "del_var"; + attr->attr.mode = 0200; + attr->write = efivar_delete; + attr->private = efivars; + efivars->del_var = attr; + + sysfs_bin_attr_init(efivars->new_var); + sysfs_bin_attr_init(efivars->del_var); + + /* Register */ + error = sysfs_create_bin_file(&efivars->kset->kobj, + efivars->new_var); + if (error) { + printk(KERN_ERR "efivars: unable to create new_var sysfs file" + " due to error %d\n", error); + goto out_free; + } + error = sysfs_create_bin_file(&efivars->kset->kobj, + efivars->del_var); + if (error) { + printk(KERN_ERR "efivars: unable to create del_var sysfs file" + " due to error %d\n", error); + sysfs_remove_bin_file(&efivars->kset->kobj, + efivars->new_var); + goto out_free; + } + + return 0; +out_free: + kfree(efivars->new_var); + efivars->new_var = NULL; + kfree(efivars->new_var); + efivars->new_var = NULL; + return error; +} + /* * For now we register the efi subsystem with the firmware subsystem * and the vars subsystem with the efi subsystem. In the future, it @@ -714,20 +765,7 @@ efivars_init(void) } } while (status != EFI_NOT_FOUND); - /* - * Now add attributes to allow creation of new vars - * and deletion of existing ones... - */ - error = sysfs_create_bin_file(&efivars->kset->kobj, - &var_subsys_attr_new_var); - if (error) - printk(KERN_ERR "efivars: unable to create new_var sysfs file" - " due to error %d\n", error); - error = sysfs_create_bin_file(&efivars->kset->kobj, - &var_subsys_attr_del_var); - if (error) - printk(KERN_ERR "efivars: unable to create del_var sysfs file" - " due to error %d\n", error); + error = create_efivars_bin_attributes(efivars); /* Don't forget the systab entry */ error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group); @@ -758,7 +796,12 @@ efivars_exit(void) spin_unlock(&efivars->lock); efivar_unregister(entry); } - + if (efivars->new_var) + sysfs_remove_bin_file(&efivars->kset->kobj, efivars->new_var); + if (efivars->del_var) + sysfs_remove_bin_file(&efivars->kset->kobj, efivars->del_var); + kfree(efivars->new_var); + kfree(efivars->del_var); kset_unregister(efivars->kset); kobject_put(efi_kobj); } -- cgit v1.2.3 From 4142ef146aee440731de956d9f9f3170d5a238ae Mon Sep 17 00:00:00 2001 From: Mike Waychison Date: Fri, 11 Mar 2011 17:43:11 -0800 Subject: efivars: parameterize efivars Now that we all global variable state is encapsulated by struct efivars, parameterize all functions to the efivars local to the control flow rather than at file scope. We do this by removing the variable "efivars" at file scope and move its storage down to the end of the file. Variables get at efivars by storing the efivars pointer within each efivar_entry. The "new_var" and "del_var" binary attribute files get at the efivars through the private pointer. Signed-off-by: Mike Waychison Cc: Matt Domsch , Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/efivars.c | 49 +++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 528ce47c1368..5633018c34af 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -103,8 +103,6 @@ struct efivars { struct kset *kset; struct bin_attribute *new_var, *del_var; }; -static struct efivars __efivars; -static struct efivars *efivars = &__efivars; /* * The maximum size of VariableName + Data = 1024 @@ -124,6 +122,7 @@ struct efi_variable { struct efivar_entry { + struct efivars *efivars; struct efi_variable var; struct list_head list; struct kobject kobj; @@ -150,9 +149,10 @@ struct efivar_attribute efivar_attr_##_name = { \ * Prototype for sysfs creation function */ static int -efivar_create_sysfs_entry(unsigned long variable_name_size, - efi_char16_t *variable_name, - efi_guid_t *vendor_guid); +efivar_create_sysfs_entry(struct efivars *efivars, + unsigned long variable_name_size, + efi_char16_t *variable_name, + efi_guid_t *vendor_guid); /* Return the number of unicode characters in data */ static unsigned long @@ -176,7 +176,7 @@ utf8_strsize(efi_char16_t *data, unsigned long maxlength) } static efi_status_t -get_var_data(struct efi_variable *var) +get_var_data(struct efivars *efivars, struct efi_variable *var) { efi_status_t status; @@ -221,7 +221,7 @@ efivar_attr_read(struct efivar_entry *entry, char *buf) if (!entry || !buf) return -EINVAL; - status = get_var_data(var); + status = get_var_data(entry->efivars, var); if (status != EFI_SUCCESS) return -EIO; @@ -244,7 +244,7 @@ efivar_size_read(struct efivar_entry *entry, char *buf) if (!entry || !buf) return -EINVAL; - status = get_var_data(var); + status = get_var_data(entry->efivars, var); if (status != EFI_SUCCESS) return -EIO; @@ -261,7 +261,7 @@ efivar_data_read(struct efivar_entry *entry, char *buf) if (!entry || !buf) return -EINVAL; - status = get_var_data(var); + status = get_var_data(entry->efivars, var); if (status != EFI_SUCCESS) return -EIO; @@ -276,6 +276,7 @@ static ssize_t efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) { struct efi_variable *new_var, *var = &entry->var; + struct efivars *efivars = entry->efivars; efi_status_t status = EFI_NOT_FOUND; if (count != sizeof(struct efi_variable)) @@ -325,7 +326,7 @@ efivar_show_raw(struct efivar_entry *entry, char *buf) if (!entry || !buf) return 0; - status = get_var_data(var); + status = get_var_data(entry->efivars, var); if (status != EFI_SUCCESS) return -EIO; @@ -413,6 +414,7 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, char *buf, loff_t pos, size_t count) { struct efi_variable *new_var = (struct efi_variable *)buf; + struct efivars *efivars = bin_attr->private; struct efivar_entry *search_efivar, *n; unsigned long strsize1, strsize2; efi_status_t status = EFI_NOT_FOUND; @@ -459,8 +461,11 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, spin_unlock(&efivars->lock); /* Create the entry in sysfs. Locking is not required here */ - status = efivar_create_sysfs_entry(utf8_strsize(new_var->VariableName, - 1024), new_var->VariableName, &new_var->VendorGuid); + status = efivar_create_sysfs_entry(efivars, + utf8_strsize(new_var->VariableName, + 1024), + new_var->VariableName, + &new_var->VendorGuid); if (status) { printk(KERN_WARNING "efivars: variable created, but sysfs entry wasn't.\n"); } @@ -472,6 +477,7 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, char *buf, loff_t pos, size_t count) { struct efi_variable *del_var = (struct efi_variable *)buf; + struct efivars *efivars = bin_attr->private; struct efivar_entry *search_efivar, *n; unsigned long strsize1, strsize2; efi_status_t status = EFI_NOT_FOUND; @@ -580,9 +586,10 @@ static struct kobject *efi_kobj; * Returns 1 on failure, 0 on success */ static int -efivar_create_sysfs_entry(unsigned long variable_name_size, - efi_char16_t *variable_name, - efi_guid_t *vendor_guid) +efivar_create_sysfs_entry(struct efivars *efivars, + unsigned long variable_name_size, + efi_char16_t *variable_name, + efi_guid_t *vendor_guid) { int i, short_name_size = variable_name_size / sizeof(efi_char16_t) + 38; char *short_name; @@ -597,6 +604,7 @@ efivar_create_sysfs_entry(unsigned long variable_name_size, return 1; } + new_efivar->efivars = efivars; memcpy(new_efivar->var.VariableName, variable_name, variable_name_size); memcpy(&(new_efivar->var.VendorGuid), vendor_guid, sizeof(efi_guid_t)); @@ -691,6 +699,8 @@ out_free: return error; } +static struct efivars __efivars; + /* * For now we register the efi subsystem with the firmware subsystem * and the vars subsystem with the efi subsystem. In the future, it @@ -706,6 +716,7 @@ efivars_init(void) efi_guid_t vendor_guid; efi_char16_t *variable_name; unsigned long variable_name_size = 1024; + struct efivars *efivars = &__efivars; int error = 0; if (!efi_enabled) @@ -751,9 +762,10 @@ efivars_init(void) &vendor_guid); switch (status) { case EFI_SUCCESS: - efivar_create_sysfs_entry(variable_name_size, - variable_name, - &vendor_guid); + efivar_create_sysfs_entry(efivars, + variable_name_size, + variable_name, + &vendor_guid); break; case EFI_NOT_FOUND: break; @@ -788,6 +800,7 @@ out_free: static void __exit efivars_exit(void) { + struct efivars *efivars = &__efivars; struct efivar_entry *entry, *n; list_for_each_entry_safe(entry, n, &efivars->list, list) { -- cgit v1.2.3 From 76b53f7c8bfa41f94ec32d84493a691f096e89f5 Mon Sep 17 00:00:00 2001 From: Mike Waychison Date: Fri, 11 Mar 2011 17:43:16 -0800 Subject: efivars: Split out variable registration In anticipation of re-using the variable facilities in efivars from elsewhere, split out the registration and unregistration of struct efivars from the rest of the EFI specific sysfs code. Signed-off-by: Mike Waychison Cc: Matt Domsch , Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/efivars.c | 122 +++++++++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 5633018c34af..f22bfcf2b968 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -95,7 +95,7 @@ struct efivars { * 1) ->list - adds, removals, reads, writes * 2) efi.[gs]et_variable() calls. * It must not be held when creating sysfs entries or calling kmalloc. - * efi.get_next_variable() is only called from efivars_init(), + * efi.get_next_variable() is only called from register_efivars(), * which is protected by the BKL, so that path is safe. */ spinlock_t lock; @@ -699,54 +699,48 @@ out_free: return error; } -static struct efivars __efivars; +static void unregister_efivars(struct efivars *efivars) +{ + struct efivar_entry *entry, *n; -/* - * For now we register the efi subsystem with the firmware subsystem - * and the vars subsystem with the efi subsystem. In the future, it - * might make sense to split off the efi subsystem into its own - * driver, but for now only efivars will register with it, so just - * include it here. - */ + list_for_each_entry_safe(entry, n, &efivars->list, list) { + spin_lock(&efivars->lock); + list_del(&entry->list); + spin_unlock(&efivars->lock); + efivar_unregister(entry); + } + if (efivars->new_var) + sysfs_remove_bin_file(&efivars->kset->kobj, efivars->new_var); + if (efivars->del_var) + sysfs_remove_bin_file(&efivars->kset->kobj, efivars->del_var); + kfree(efivars->new_var); + kfree(efivars->del_var); + kset_unregister(efivars->kset); +} -static int __init -efivars_init(void) +static int register_efivars(struct efivars *efivars, + struct kobject *parent_kobj) { efi_status_t status = EFI_NOT_FOUND; efi_guid_t vendor_guid; efi_char16_t *variable_name; unsigned long variable_name_size = 1024; - struct efivars *efivars = &__efivars; int error = 0; - if (!efi_enabled) - return -ENODEV; - variable_name = kzalloc(variable_name_size, GFP_KERNEL); if (!variable_name) { printk(KERN_ERR "efivars: Memory allocation failed.\n"); return -ENOMEM; } - printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION, - EFIVARS_DATE); - - /* For now we'll register the efi directory at /sys/firmware/efi */ - efi_kobj = kobject_create_and_add("efi", firmware_kobj); - if (!efi_kobj) { - printk(KERN_ERR "efivars: Firmware registration failed.\n"); - error = -ENOMEM; - goto out_free; - } - spin_lock_init(&efivars->lock); INIT_LIST_HEAD(&efivars->list); - efivars->kset = kset_create_and_add("vars", NULL, efi_kobj); + efivars->kset = kset_create_and_add("vars", NULL, parent_kobj); if (!efivars->kset) { printk(KERN_ERR "efivars: Subsystem registration failed.\n"); error = -ENOMEM; - goto out_firmware_unregister; + goto out; } /* @@ -778,21 +772,54 @@ efivars_init(void) } while (status != EFI_NOT_FOUND); error = create_efivars_bin_attributes(efivars); - - /* Don't forget the systab entry */ - error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group); if (error) - printk(KERN_ERR "efivars: Sysfs attribute export failed with error %d.\n", error); - else - goto out_free; + unregister_efivars(efivars); - kset_unregister(efivars->kset); +out: + kfree(variable_name); -out_firmware_unregister: - kobject_put(efi_kobj); + return error; +} -out_free: - kfree(variable_name); +static struct efivars __efivars; + +/* + * For now we register the efi subsystem with the firmware subsystem + * and the vars subsystem with the efi subsystem. In the future, it + * might make sense to split off the efi subsystem into its own + * driver, but for now only efivars will register with it, so just + * include it here. + */ + +static int __init +efivars_init(void) +{ + int error = 0; + + printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION, + EFIVARS_DATE); + + if (!efi_enabled) + return -ENODEV; + + /* For now we'll register the efi directory at /sys/firmware/efi */ + efi_kobj = kobject_create_and_add("efi", firmware_kobj); + if (!efi_kobj) { + printk(KERN_ERR "efivars: Firmware registration failed.\n"); + return -ENOMEM; + } + + error = register_efivars(&__efivars, efi_kobj); + + /* Don't forget the systab entry */ + error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group); + if (error) { + printk(KERN_ERR + "efivars: Sysfs attribute export failed with error %d.\n", + error); + unregister_efivars(&__efivars); + kobject_put(efi_kobj); + } return error; } @@ -800,22 +827,7 @@ out_free: static void __exit efivars_exit(void) { - struct efivars *efivars = &__efivars; - struct efivar_entry *entry, *n; - - list_for_each_entry_safe(entry, n, &efivars->list, list) { - spin_lock(&efivars->lock); - list_del(&entry->list); - spin_unlock(&efivars->lock); - efivar_unregister(entry); - } - if (efivars->new_var) - sysfs_remove_bin_file(&efivars->kset->kobj, efivars->new_var); - if (efivars->del_var) - sysfs_remove_bin_file(&efivars->kset->kobj, efivars->del_var); - kfree(efivars->new_var); - kfree(efivars->del_var); - kset_unregister(efivars->kset); + unregister_efivars(&__efivars); kobject_put(efi_kobj); } -- cgit v1.2.3 From 3295814d83c55e629abc6c2a31af1d504febb229 Mon Sep 17 00:00:00 2001 From: Mike Waychison Date: Fri, 11 Mar 2011 17:43:21 -0800 Subject: efivars: Parameterize operations. Instead of letting efivars access struct efi directly when dealing with variables, use an operations structure. This allows a later change to reuse the efivars logic without having to pretend to support everything in struct efi. Signed-off-by: Mike Waychison Cc: Matt Domsch , Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/efivars.c | 61 ++++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index f22bfcf2b968..b10b7d7bd7de 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -89,19 +89,26 @@ MODULE_DESCRIPTION("sysfs interface to EFI Variables"); MODULE_LICENSE("GPL"); MODULE_VERSION(EFIVARS_VERSION); +struct efivar_operations { + efi_get_variable_t *get_variable; + efi_get_next_variable_t *get_next_variable; + efi_set_variable_t *set_variable; +}; + struct efivars { /* * ->lock protects two things: * 1) ->list - adds, removals, reads, writes - * 2) efi.[gs]et_variable() calls. + * 2) ops.[gs]et_variable() calls. * It must not be held when creating sysfs entries or calling kmalloc. - * efi.get_next_variable() is only called from register_efivars(), + * ops.get_next_variable() is only called from register_efivars(), * which is protected by the BKL, so that path is safe. */ spinlock_t lock; struct list_head list; struct kset *kset; struct bin_attribute *new_var, *del_var; + const struct efivar_operations *ops; }; /* @@ -182,11 +189,11 @@ get_var_data(struct efivars *efivars, struct efi_variable *var) spin_lock(&efivars->lock); var->DataSize = 1024; - status = efi.get_variable(var->VariableName, - &var->VendorGuid, - &var->Attributes, - &var->DataSize, - var->Data); + status = efivars->ops->get_variable(var->VariableName, + &var->VendorGuid, + &var->Attributes, + &var->DataSize, + var->Data); spin_unlock(&efivars->lock); if (status != EFI_SUCCESS) { printk(KERN_WARNING "efivars: get_variable() failed 0x%lx!\n", @@ -299,11 +306,11 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) } spin_lock(&efivars->lock); - status = efi.set_variable(new_var->VariableName, - &new_var->VendorGuid, - new_var->Attributes, - new_var->DataSize, - new_var->Data); + status = efivars->ops->set_variable(new_var->VariableName, + &new_var->VendorGuid, + new_var->Attributes, + new_var->DataSize, + new_var->Data); spin_unlock(&efivars->lock); @@ -446,11 +453,11 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, } /* now *really* create the variable via EFI */ - status = efi.set_variable(new_var->VariableName, - &new_var->VendorGuid, - new_var->Attributes, - new_var->DataSize, - new_var->Data); + status = efivars->ops->set_variable(new_var->VariableName, + &new_var->VendorGuid, + new_var->Attributes, + new_var->DataSize, + new_var->Data); if (status != EFI_SUCCESS) { printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n", @@ -511,11 +518,11 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, del_var->Attributes = 0; del_var->DataSize = 0; - status = efi.set_variable(del_var->VariableName, - &del_var->VendorGuid, - del_var->Attributes, - del_var->DataSize, - del_var->Data); + status = efivars->ops->set_variable(del_var->VariableName, + &del_var->VendorGuid, + del_var->Attributes, + del_var->DataSize, + del_var->Data); if (status != EFI_SUCCESS) { printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n", @@ -719,6 +726,7 @@ static void unregister_efivars(struct efivars *efivars) } static int register_efivars(struct efivars *efivars, + const struct efivar_operations *ops, struct kobject *parent_kobj) { efi_status_t status = EFI_NOT_FOUND; @@ -735,6 +743,7 @@ static int register_efivars(struct efivars *efivars, spin_lock_init(&efivars->lock); INIT_LIST_HEAD(&efivars->list); + efivars->ops = ops; efivars->kset = kset_create_and_add("vars", NULL, parent_kobj); if (!efivars->kset) { @@ -751,7 +760,7 @@ static int register_efivars(struct efivars *efivars, do { variable_name_size = 1024; - status = efi.get_next_variable(&variable_name_size, + status = ops->get_next_variable(&variable_name_size, variable_name, &vendor_guid); switch (status) { @@ -782,6 +791,7 @@ out: } static struct efivars __efivars; +static struct efivar_operations ops; /* * For now we register the efi subsystem with the firmware subsystem @@ -809,7 +819,10 @@ efivars_init(void) return -ENOMEM; } - error = register_efivars(&__efivars, efi_kobj); + ops.get_variable = efi.get_variable; + ops.set_variable = efi.set_variable; + ops.get_next_variable = efi.get_next_variable; + error = register_efivars(&__efivars, &ops, efi_kobj); /* Don't forget the systab entry */ error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group); -- cgit v1.2.3 From 4fc756bd9dbf6b84fbf751e3bf495277849c5db7 Mon Sep 17 00:00:00 2001 From: Mike Waychison Date: Fri, 11 Mar 2011 17:43:27 -0800 Subject: efivars: Expose efivars functionality to external drivers. Signed-off-by: Mike Waychison Cc: Matt Domsch , Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/efivars.c | 34 +++++++--------------------------- include/linux/efi.h | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index b10b7d7bd7de..ff0c373e3bbf 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -89,28 +89,6 @@ MODULE_DESCRIPTION("sysfs interface to EFI Variables"); MODULE_LICENSE("GPL"); MODULE_VERSION(EFIVARS_VERSION); -struct efivar_operations { - efi_get_variable_t *get_variable; - efi_get_next_variable_t *get_next_variable; - efi_set_variable_t *set_variable; -}; - -struct efivars { - /* - * ->lock protects two things: - * 1) ->list - adds, removals, reads, writes - * 2) ops.[gs]et_variable() calls. - * It must not be held when creating sysfs entries or calling kmalloc. - * ops.get_next_variable() is only called from register_efivars(), - * which is protected by the BKL, so that path is safe. - */ - spinlock_t lock; - struct list_head list; - struct kset *kset; - struct bin_attribute *new_var, *del_var; - const struct efivar_operations *ops; -}; - /* * The maximum size of VariableName + Data = 1024 * Therefore, it's reasonable to save that much @@ -706,7 +684,7 @@ out_free: return error; } -static void unregister_efivars(struct efivars *efivars) +void unregister_efivars(struct efivars *efivars) { struct efivar_entry *entry, *n; @@ -724,10 +702,11 @@ static void unregister_efivars(struct efivars *efivars) kfree(efivars->del_var); kset_unregister(efivars->kset); } +EXPORT_SYMBOL_GPL(unregister_efivars); -static int register_efivars(struct efivars *efivars, - const struct efivar_operations *ops, - struct kobject *parent_kobj) +int register_efivars(struct efivars *efivars, + const struct efivar_operations *ops, + struct kobject *parent_kobj) { efi_status_t status = EFI_NOT_FOUND; efi_guid_t vendor_guid; @@ -789,6 +768,7 @@ out: return error; } +EXPORT_SYMBOL_GPL(register_efivars); static struct efivars __efivars; static struct efivar_operations ops; @@ -810,7 +790,7 @@ efivars_init(void) EFIVARS_DATE); if (!efi_enabled) - return -ENODEV; + return 0; /* For now we'll register the efi directory at /sys/firmware/efi */ efi_kobj = kobject_create_and_add("efi", firmware_kobj); diff --git a/include/linux/efi.h b/include/linux/efi.h index fb737bc19a8c..33fa1203024e 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -397,4 +397,41 @@ static inline void memrange_efi_to_native(u64 *addr, u64 *npages) *addr &= PAGE_MASK; } +#if defined(CONFIG_EFI_VARS) || defined(CONFIG_EFI_VARS_MODULE) +/* + * EFI Variable support. + * + * Different firmware drivers can expose their EFI-like variables using + * the following. + */ + +struct efivar_operations { + efi_get_variable_t *get_variable; + efi_get_next_variable_t *get_next_variable; + efi_set_variable_t *set_variable; +}; + +struct efivars { + /* + * ->lock protects two things: + * 1) ->list - adds, removals, reads, writes + * 2) ops.[gs]et_variable() calls. + * It must not be held when creating sysfs entries or calling kmalloc. + * ops.get_next_variable() is only called from register_efivars(), + * which is protected by the BKL, so that path is safe. + */ + spinlock_t lock; + struct list_head list; + struct kset *kset; + struct bin_attribute *new_var, *del_var; + const struct efivar_operations *ops; +}; + +int register_efivars(struct efivars *efivars, + const struct efivar_operations *ops, + struct kobject *parent_kobj); +void unregister_efivars(struct efivars *efivars); + +#endif /* CONFIG_EFI_VARS */ + #endif /* _LINUX_EFI_H */ -- cgit v1.2.3 From 0bf97bb1cff7204111c479c899dae30823314761 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Thu, 10 Mar 2011 11:35:06 +0100 Subject: staging: brcm80211: bugfix for NULL scb ptr dereference The driver uses a struct called 'scb', this struct is primarily used for AMPDU functionality and is embedded in struct ieee80211_sta. To increase driver robustness, the case in which this scb pointer is NULL is now handled graceful. This paves the way for the next patch in this series. Signed-off-by: Roland Vossen Reviewed-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 34 ++++++++++++++++++++------ 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index 7f8790d9b817..26dd9b6a8757 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -900,13 +900,7 @@ wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, tx_info = IEEE80211_SKB_CB(p); ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); - ASSERT(scb); - ASSERT(scb->magic == SCB_MAGIC); ASSERT(txs->status & TX_STATUS_AMPDU); - scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - ASSERT(scb_ampdu); - ini = SCB_AMPDU_INI(scb_ampdu, p->priority); - ASSERT(ini->scb == scb); /* BMAC_NOTE: For the split driver, second level txstatus comes later * So if the ACK was received then wait for the second level else just @@ -930,7 +924,33 @@ wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, s2 = R_REG(&wlc->regs->frmtxstatus2); } - wlc_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2); + if (likely(scb)) { + ASSERT(scb->magic == SCB_MAGIC); + scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); + ASSERT(scb_ampdu); + ini = SCB_AMPDU_INI(scb_ampdu, p->priority); + ASSERT(ini->scb == scb); + wlc_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2); + } else { + /* loop through all pkts and free */ + u8 queue = txs->frameid & TXFID_QUEUE_MASK; + d11txh_t *txh; + u16 mcl; + while (p) { + tx_info = IEEE80211_SKB_CB(p); + txh = (d11txh_t *) p->data; + mcl = le16_to_cpu(txh->MacTxControlLow); + ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); + pkt_buf_free_skb(p); + /* break out if last packet of ampdu */ + if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) == + TXC_AMPDU_LAST) + break; + p = GETNEXTTXP(wlc, queue); + ASSERT(p != NULL); + } + wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight); + } wlc_ampdu_txflowcontrol(wlc, scb_ampdu, ini); } -- cgit v1.2.3 From 8ada0be34014565dc4e57d1194d18594a5bcd161 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Thu, 10 Mar 2011 11:35:07 +0100 Subject: staging: brcm80211: bugfix for control.sta NULL ptr dereference Mac80211 can transmit packets where the control.sta field is NULL. The driver dereferenced this. Bugfix was to only dereference a non NULL ieee80211_sta pointer. Signed-off-by: Roland Vossen Reviewed-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c index cb1e1428cd87..8bee149f6316 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c @@ -6613,7 +6613,8 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) tx_info = IEEE80211_SKB_CB(p); h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); - scb = (struct scb *)tx_info->control.sta->drv_priv; + if (tx_info->control.sta) + scb = (struct scb *)tx_info->control.sta->drv_priv; if (N_ENAB(wlc->pub)) { u8 *plcp = (u8 *) (txh + 1); -- cgit v1.2.3 From 61f4420597b750e932ad0e8567715f1a3439bb03 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Thu, 10 Mar 2011 11:35:08 +0100 Subject: staging: brcm80211: added IEEE80211_AMPDU_TX_STOP handling Driver now flushes AMPDU packets for a specified station on Mac80211 calling wl_ops_ampdu_action(IEEE80211_AMPDU_TX_STOP). Not all AMPDU packets are flushed yet: there can still be AMPDU packets pending in hardware (DMA). That is the subject of the next patch in this series. Signed-off-by: Roland Vossen Reviewed-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 3 ++ drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 43 ++++++++++++++++++++++++ drivers/staging/brcm80211/brcmsmac/wlc_pub.h | 4 +++ 3 files changed, 50 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index 3550551da316..a523b231cffe 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -648,6 +648,9 @@ wl_ops_ampdu_action(struct ieee80211_hw *hw, break; case IEEE80211_AMPDU_TX_STOP: + WL_LOCK(wl); + wlc_ampdu_flush(wl->wlc, sta, tid); + WL_UNLOCK(wl); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; case IEEE80211_AMPDU_TX_OPERATIONAL: diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index 26dd9b6a8757..3d00180efacc 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -1363,3 +1363,46 @@ void wlc_ampdu_shm_upd(struct ampdu_info *ampdu) wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF); } } + +struct cb_del_ampdu_pars { + struct ieee80211_sta *sta; + u16 tid; +}; + +/* + * callback function that helps flushing ampdu packets from a priority queue + */ +static bool cb_del_ampdu_pkt(void *p, int arg_a) +{ + struct sk_buff *mpdu = (struct sk_buff *)p; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu); + struct cb_del_ampdu_pars *ampdu_pars = + (struct cb_del_ampdu_pars *)arg_a; + bool rc; + + rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false; + rc = rc && (tx_info->control.sta == NULL || ampdu_pars->sta == NULL || + tx_info->control.sta == ampdu_pars->sta); + rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid); + return rc; +} + +/* + * When a remote party is no longer available for ampdu communication, any + * pending tx ampdu packets in the driver have to be flushed. + */ +void wlc_ampdu_flush(struct wlc_info *wlc, + struct ieee80211_sta *sta, u16 tid) +{ + struct wlc_txq_info *qi = wlc->active_queue; + struct pktq *pq = &qi->q; + int prec; + struct cb_del_ampdu_pars ampdu_pars; + + ampdu_pars.sta = sta; + ampdu_pars.tid = tid; + for (prec = 0; prec < pq->num_prec; prec++) { + pktq_pflush(pq, prec, true, cb_del_ampdu_pkt, + (int)&du_pars); + } +} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h index 5536f5111f48..b956c23fa467 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_pub.h @@ -536,6 +536,10 @@ extern u32 wlc_delta_txfunfl(struct wlc_info *wlc, int fifo); extern void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset); extern void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs); +struct ieee80211_sta; +extern void wlc_ampdu_flush(struct wlc_info *wlc, struct ieee80211_sta *sta, + u16 tid); + /* wlc_phy.c helper functions */ extern void wlc_set_ps_ctrl(struct wlc_info *wlc); extern void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val); -- cgit v1.2.3 From 9ee63c6a9f122688ea05b977ffa894dd60bf99eb Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Thu, 10 Mar 2011 11:35:09 +0100 Subject: staging: brcm80211: invalidate all AMPDU packets on IEEE80211_AMPDU_TX_STOP The previous patch flushed the AMPDU packets associated to a certain STA/AP in the driver queues, but left the AMPDU packets in the DMA queue untouched. This patch invalidates AMPDU packets in the DMA queue, so they can be processed accordingly when hardware releases the packets to the driver. Signed-off-by: Roland Vossen Reviewed-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 14 ++++++++++++++ drivers/staging/brcm80211/brcmsmac/wlc_main.c | 18 ++++++++++++++++++ drivers/staging/brcm80211/brcmsmac/wlc_main.h | 3 +++ drivers/staging/brcm80211/include/hnddma.h | 3 ++- drivers/staging/brcm80211/util/hnddma.c | 24 ++++++++++++++++++++++++ 5 files changed, 61 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index 3d00180efacc..0a0ff3057f11 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -1387,6 +1387,19 @@ static bool cb_del_ampdu_pkt(void *p, int arg_a) return rc; } +/* + * callback function that helps invalidating ampdu packets in a DMA queue + */ +static void dma_cb_fn_ampdu(void *txi, void *arg_a) +{ + struct ieee80211_sta *sta = arg_a; + struct ieee80211_tx_info *tx_info = (struct ieee80211_tx_info *)txi; + + if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && + (tx_info->control.sta == sta || sta == NULL)) + tx_info->control.sta = NULL; +} + /* * When a remote party is no longer available for ampdu communication, any * pending tx ampdu packets in the driver have to be flushed. @@ -1405,4 +1418,5 @@ void wlc_ampdu_flush(struct wlc_info *wlc, pktq_pflush(pq, prec, true, cb_del_ampdu_pkt, (int)&du_pars); } + wlc_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu); } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c index 8bee149f6316..785357047d2c 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c @@ -8477,3 +8477,21 @@ void wlc_associate_upd(struct wlc_info *wlc, bool state) wlc->pub->associated = state; wlc->cfg->associated = state; } + +/* + * When a remote STA/AP is removed by Mac80211, or when it can no longer accept + * AMPDU traffic, packets pending in hardware have to be invalidated so that + * when later on hardware releases them, they can be handled appropriately. + */ +void wlc_inval_dma_pkts(struct wlc_hw_info *hw, + struct ieee80211_sta *sta, + void (*dma_callback_fn)) +{ + struct hnddma_pub *dmah; + int i; + for (i = 0; i < NFIFO; i++) { + dmah = hw->di[i]; + if (dmah != NULL) + dma_walk_packets(dmah, dma_callback_fn, sta); + } +} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.h b/drivers/staging/brcm80211/brcmsmac/wlc_main.h index 7c5d7e1df07c..0eaef07d3324 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.h @@ -873,6 +873,9 @@ extern u16 wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, bool ba); extern void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs); +extern void wlc_inval_dma_pkts(struct wlc_hw_info *hw, + struct ieee80211_sta *sta, + void (*dma_callback_fn)); #if defined(BCMDBG) extern void wlc_dump_ie(struct wlc_info *wlc, bcm_tlv_t *ie, diff --git a/drivers/staging/brcm80211/include/hnddma.h b/drivers/staging/brcm80211/include/hnddma.h index 121768eccfea..5d079e77490e 100644 --- a/drivers/staging/brcm80211/include/hnddma.h +++ b/drivers/staging/brcm80211/include/hnddma.h @@ -202,5 +202,6 @@ extern const di_fcn_t dma64proc; * This info is needed by DMA_ALLOC_CONSISTENT in dma attach */ extern uint dma_addrwidth(si_t *sih, void *dmaregs); - +void dma_walk_packets(struct hnddma_pub *dmah, void (*callback_fnc) + (void *pkt, void *arg_a), void *arg_a); #endif /* _hnddma_h_ */ diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 60afd06297e8..122f7d3fd704 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -1800,3 +1800,27 @@ uint dma_addrwidth(si_t *sih, void *dmaregs) return DMADDRWIDTH_64; } +/* + * Mac80211 initiated actions sometimes require packets in the DMA queue to be + * modified. The modified portion of the packet is not under control of the DMA + * engine. This function calls a caller-supplied function for each packet in + * the caller specified dma chain. + */ +void dma_walk_packets(struct hnddma_pub *dmah, void (*callback_fnc) + (void *pkt, void *arg_a), void *arg_a) +{ + dma_info_t *di = (dma_info_t *) dmah; + uint i = di->txin; + uint end = di->txout; + struct sk_buff *skb; + struct ieee80211_tx_info *tx_info; + + while (i != end) { + skb = (struct sk_buff *)di->txp[i]; + if (skb != NULL) { + tx_info = (struct ieee80211_tx_info *)skb->cb; + (callback_fnc)(tx_info, arg_a); + } + i = NEXTTXD(i); + } +} -- cgit v1.2.3 From d4b977bd4875e852c98f0423eab43d35f1e84874 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Thu, 10 Mar 2011 14:40:17 +0100 Subject: staging: brcm80211: removed comment in rx status processing Code cleanup. The comment is hinting that we should sanity check the header to verify that if it claims its from a 5Ghz channel, that the chip actually supports 5 Ghz. This is redundant (2.4G only chips do not report 5G channels) and thus the comment was removed. Signed-off-by: Roland Vossen Reviewed-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_main.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c index 785357047d2c..38330e7f36cc 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c @@ -6847,7 +6847,6 @@ prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, channel = WLC_CHAN_CHANNEL(rxh->RxChan); - /* XXX Channel/badn needs to be filtered against whether we are single/dual band card */ if (channel > 14) { rx_status->band = IEEE80211_BAND_5GHZ; rx_status->freq = ieee80211_ofdm_chan_to_freq( -- cgit v1.2.3 From b1562946267b14012e4d6e76c71db1f1af726913 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Thu, 10 Mar 2011 14:40:19 +0100 Subject: staging: brcm80211: replaced wlc_bsscfg_t by struct wlc_bsscfg Code cleanup. Signed-off-by: Roland Vossen Reviewed-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_alloc.c | 10 ++--- drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h | 5 ++- drivers/staging/brcm80211/brcmsmac/wlc_main.c | 50 +++++++++++++------------ drivers/staging/brcm80211/brcmsmac/wlc_main.h | 28 +++++++------- 4 files changed, 49 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c index 07684967d87c..e928fa10834e 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c @@ -120,11 +120,11 @@ static void wlc_pub_mfree(struct wlc_pub *pub) kfree(pub); } -static wlc_bsscfg_t *wlc_bsscfg_malloc(uint unit) +static struct wlc_bsscfg *wlc_bsscfg_malloc(uint unit) { - wlc_bsscfg_t *cfg; + struct wlc_bsscfg *cfg; - cfg = (wlc_bsscfg_t *) wlc_calloc(unit, sizeof(wlc_bsscfg_t)); + cfg = (struct wlc_bsscfg *) wlc_calloc(unit, sizeof(struct wlc_bsscfg)); if (cfg == NULL) goto fail; @@ -140,7 +140,7 @@ static wlc_bsscfg_t *wlc_bsscfg_malloc(uint unit) return NULL; } -static void wlc_bsscfg_mfree(wlc_bsscfg_t *cfg) +static void wlc_bsscfg_mfree(struct wlc_bsscfg *cfg) { if (cfg == NULL) return; @@ -150,7 +150,7 @@ static void wlc_bsscfg_mfree(wlc_bsscfg_t *cfg) kfree(cfg); } -void wlc_bsscfg_ID_assign(struct wlc_info *wlc, wlc_bsscfg_t *bsscfg) +void wlc_bsscfg_ID_assign(struct wlc_info *wlc, struct wlc_bsscfg *bsscfg) { bsscfg->ID = wlc->next_bsscfg_ID; wlc->next_bsscfg_ID++; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h b/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h index 0951574ea604..cd5cfbbce94a 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h @@ -31,7 +31,7 @@ typedef struct wlc_bsscfg wlc_bsscfg_t; #define BCN_TEMPLATE_COUNT 2 /* Iterator for "associated" STA bss configs: - (struct wlc_info *wlc, int idx, wlc_bsscfg_t *cfg) */ + (struct wlc_info *wlc, int idx, struct wlc_bsscfg *cfg) */ #define FOREACH_AS_STA(wlc, idx, cfg) \ for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \ if ((cfg = (wlc)->bsscfg[idx]) && BSSCFG_STA(cfg) && cfg->associated) @@ -125,7 +125,8 @@ struct wlc_bsscfg { #define HWBCN_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_BCN) != 0) #define HWPRB_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_PRB) != 0) -extern void wlc_bsscfg_ID_assign(struct wlc_info *wlc, wlc_bsscfg_t * bsscfg); +extern void wlc_bsscfg_ID_assign(struct wlc_info *wlc, + struct wlc_bsscfg *bsscfg); /* Extend N_ENAB to per-BSS */ #define BSS_N_ENAB(wlc, cfg) \ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c index 38330e7f36cc..97b320da433a 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c @@ -354,7 +354,7 @@ bool wlc_stay_awake(struct wlc_info *wlc) bool wlc_ps_allowed(struct wlc_info *wlc) { int idx; - wlc_bsscfg_t *cfg; + struct wlc_bsscfg *cfg; /* disallow PS when one of the following global conditions meets */ if (!wlc->pub->associated || !wlc->PMenabled || wlc->PM_override) @@ -437,7 +437,7 @@ void wlc_init(struct wlc_info *wlc) d11regs_t *regs; chanspec_t chanspec; int i; - wlc_bsscfg_t *bsscfg; + struct wlc_bsscfg *bsscfg; bool mute = false; WL_TRACE("wl%d: wlc_init\n", wlc->pub->unit); @@ -630,7 +630,7 @@ bool wlc_ps_check(struct wlc_info *wlc) if (hps != ((tmp & MCTL_HPS) != 0)) { int idx; - wlc_bsscfg_t *cfg; + struct wlc_bsscfg *cfg; WL_ERROR("wl%d: hps not sync, sw %d, maccontrol 0x%x\n", wlc->pub->unit, hps, tmp); FOREACH_BSS(wlc, idx, cfg) { @@ -688,7 +688,7 @@ void wlc_set_ps_ctrl(struct wlc_info *wlc) * Write this BSS config's MAC address to core. * Updates RXE match engine. */ -int wlc_set_mac(wlc_bsscfg_t *cfg) +int wlc_set_mac(struct wlc_bsscfg *cfg) { int err = 0; struct wlc_info *wlc = cfg->wlc; @@ -706,7 +706,7 @@ int wlc_set_mac(wlc_bsscfg_t *cfg) /* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl). * Updates RXE match engine. */ -void wlc_set_bssid(wlc_bsscfg_t *cfg) +void wlc_set_bssid(struct wlc_bsscfg *cfg) { struct wlc_info *wlc = cfg->wlc; @@ -728,7 +728,7 @@ void wlc_set_bssid(wlc_bsscfg_t *cfg) void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot) { int idx; - wlc_bsscfg_t *cfg; + struct wlc_bsscfg *cfg; ASSERT(wlc->band->gmode); @@ -786,7 +786,7 @@ void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec) { if (wlc->home_chanspec != chanspec) { int idx; - wlc_bsscfg_t *cfg; + struct wlc_bsscfg *cfg; wlc->home_chanspec = chanspec; @@ -1313,7 +1313,7 @@ static void WLBANDINITFN(wlc_bsinit) (struct wlc_info *wlc) static void WLBANDINITFN(wlc_setband) (struct wlc_info *wlc, uint bandunit) { int idx; - wlc_bsscfg_t *cfg; + struct wlc_bsscfg *cfg; ASSERT(NBANDS(wlc) > 1); ASSERT(!wlc->bandlocked); @@ -1439,7 +1439,7 @@ void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend) } -void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend) +void wlc_edcf_setparams(struct wlc_bsscfg *cfg, bool suspend) { struct wlc_info *wlc = cfg->wlc; uint aci, i, j; @@ -2450,7 +2450,7 @@ static void wlc_watchdog(void *arg) { struct wlc_info *wlc = (struct wlc_info *) arg; int i; - wlc_bsscfg_t *cfg; + struct wlc_bsscfg *cfg; WL_TRACE("wl%d: wlc_watchdog\n", wlc->pub->unit); @@ -2566,7 +2566,7 @@ int wlc_up(struct wlc_info *wlc) if (!mboolisset (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) { int idx; - wlc_bsscfg_t *bsscfg; + struct wlc_bsscfg *bsscfg; mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); @@ -3065,7 +3065,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, bool ta_ok; uint band; rw_reg_t *r; - wlc_bsscfg_t *bsscfg; + struct wlc_bsscfg *bsscfg; wlc_bss_info_t *current_bss; /* update bsscfg pointer */ @@ -4506,7 +4506,7 @@ wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, int val_size, struct wlc_if *wlcif) { struct wlc_info *wlc = hdl; - wlc_bsscfg_t *bsscfg; + struct wlc_bsscfg *bsscfg; int err = 0; s32 int_val = 0; s32 int_val2 = 0; @@ -5277,7 +5277,8 @@ void BCMFASTPATH wlc_send_q(struct wlc_info *wlc, struct wlc_txq_info *qi) * for MC frames so is used as part of the sequence number. */ static inline u16 -bcmc_fid_generate(struct wlc_info *wlc, wlc_bsscfg_t *bsscfg, d11txh_t *txh) +bcmc_fid_generate(struct wlc_info *wlc, struct wlc_bsscfg *bsscfg, + d11txh_t *txh) { u16 frameid; @@ -6378,7 +6379,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs) { - wlc_bsscfg_t *cfg = wlc->cfg; + struct wlc_bsscfg *cfg = wlc->cfg; wlc->pub->_cnt->tbtt++; @@ -6514,7 +6515,7 @@ void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus) /* delay the cleanup to wl_down in IBSS case */ if ((R_REG(®s->phydebug) & PDBG_RFD)) { int idx; - wlc_bsscfg_t *bsscfg; + struct wlc_bsscfg *bsscfg; FOREACH_BSS(wlc, idx, bsscfg) { if (!BSSCFG_STA(bsscfg) || !bsscfg->enable || !bsscfg->BSS) @@ -7629,7 +7630,7 @@ wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec, */ static void wlc_bcn_prb_template(struct wlc_info *wlc, u16 type, ratespec_t bcn_rspec, - wlc_bsscfg_t *cfg, u16 *buf, int *len) + struct wlc_bsscfg *cfg, u16 *buf, int *len) { static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; cck_phy_hdr_t *plcp; @@ -7696,7 +7697,7 @@ int wlc_get_header_len() * template updated. * Otherwise, it updates the hardware template. */ -void wlc_bss_update_beacon(struct wlc_info *wlc, wlc_bsscfg_t *cfg) +void wlc_bss_update_beacon(struct wlc_info *wlc, struct wlc_bsscfg *cfg) { int len = BCN_TMPL_LEN; @@ -7750,7 +7751,7 @@ void wlc_bss_update_beacon(struct wlc_info *wlc, wlc_bsscfg_t *cfg) void wlc_update_beacon(struct wlc_info *wlc) { int idx; - wlc_bsscfg_t *bsscfg; + struct wlc_bsscfg *bsscfg; /* update AP or IBSS beacons */ FOREACH_BSS(wlc, idx, bsscfg) { @@ -7760,7 +7761,7 @@ void wlc_update_beacon(struct wlc_info *wlc) } /* Write ssid into shared memory */ -void wlc_shm_ssid_upd(struct wlc_info *wlc, wlc_bsscfg_t *cfg) +void wlc_shm_ssid_upd(struct wlc_info *wlc, struct wlc_bsscfg *cfg) { u8 *ssidptr = cfg->SSID; u16 base = M_SSID; @@ -7779,7 +7780,7 @@ void wlc_shm_ssid_upd(struct wlc_info *wlc, wlc_bsscfg_t *cfg) void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend) { int idx; - wlc_bsscfg_t *bsscfg; + struct wlc_bsscfg *bsscfg; /* update AP or IBSS probe responses */ FOREACH_BSS(wlc, idx, bsscfg) { @@ -7789,7 +7790,8 @@ void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend) } void -wlc_bss_update_probe_resp(struct wlc_info *wlc, wlc_bsscfg_t *cfg, bool suspend) +wlc_bss_update_probe_resp(struct wlc_info *wlc, struct wlc_bsscfg *cfg, + bool suspend) { u16 prb_resp[BCN_TMPL_LEN / 2]; int len = BCN_TMPL_LEN; @@ -7867,7 +7869,7 @@ int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) void wlc_reprate_init(struct wlc_info *wlc) { int i; - wlc_bsscfg_t *bsscfg; + struct wlc_bsscfg *bsscfg; FOREACH_BSS(wlc, i, bsscfg) { wlc_bsscfg_reprate_init(bsscfg); @@ -7875,7 +7877,7 @@ void wlc_reprate_init(struct wlc_info *wlc) } /* per bsscfg init tx reported rate mechanism */ -void wlc_bsscfg_reprate_init(wlc_bsscfg_t *bsscfg) +void wlc_bsscfg_reprate_init(struct wlc_bsscfg *bsscfg) { bsscfg->txrspecidx = 0; memset((char *)bsscfg->txrspec, 0, sizeof(bsscfg->txrspec)); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.h b/drivers/staging/brcm80211/brcmsmac/wlc_main.h index 0eaef07d3324..960f82cbfbc9 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.h @@ -621,11 +621,12 @@ struct wlc_info { u16 tx_prec_map; /* Precedence map based on HW FIFO space */ u16 fifo2prec_map[NFIFO]; /* pointer to fifo2_prec map based on WME */ - /* BSS Configurations */ - wlc_bsscfg_t *bsscfg[WLC_MAXBSSCFG]; /* set of BSS configurations, idx 0 is default and - * always valid - */ - wlc_bsscfg_t *cfg; /* the primary bsscfg (can be AP or STA) */ + /* + * BSS Configurations set of BSS configurations, idx 0 is default and + * always valid + */ + struct wlc_bsscfg *bsscfg[WLC_MAXBSSCFG]; + struct wlc_bsscfg *cfg; /* the primary bsscfg (can be AP or STA) */ u8 stas_associated; /* count of ASSOCIATED STA bsscfgs */ u8 aps_associated; /* count of UP AP bsscfgs */ u8 block_datafifo; /* prohibit posting frames to data fifos */ @@ -846,7 +847,7 @@ extern bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rate, int band, extern void wlc_ap_upd(struct wlc_info *wlc); /* helper functions */ -extern void wlc_shm_ssid_upd(struct wlc_info *wlc, wlc_bsscfg_t *cfg); +extern void wlc_shm_ssid_upd(struct wlc_info *wlc, struct wlc_bsscfg *cfg); extern int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config); extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc); @@ -884,7 +885,7 @@ extern void wlc_dump_ie(struct wlc_info *wlc, bcm_tlv_t *ie, extern bool wlc_ps_check(struct wlc_info *wlc); extern void wlc_reprate_init(struct wlc_info *wlc); -extern void wlc_bsscfg_reprate_init(wlc_bsscfg_t *bsscfg); +extern void wlc_bsscfg_reprate_init(struct wlc_bsscfg *bsscfg); extern void wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, u32 b_low); extern u32 wlc_calc_tbtt_offset(u32 bi, u32 tsf_h, u32 tsf_l); @@ -903,8 +904,8 @@ extern void wlc_bss_update_beacon(struct wlc_info *wlc, struct wlc_bsscfg *bsscfg); extern void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend); -extern void wlc_bss_update_probe_resp(struct wlc_info *wlc, wlc_bsscfg_t *cfg, - bool suspend); +extern void wlc_bss_update_probe_resp(struct wlc_info *wlc, + struct wlc_bsscfg *cfg, bool suspend); extern bool wlc_ismpc(struct wlc_info *wlc); extern bool wlc_is_non_delay_mpc(struct wlc_info *wlc); @@ -936,14 +937,15 @@ extern void wlc_print_ies(struct wlc_info *wlc, u8 *ies, uint ies_len); extern int wlc_set_nmode(struct wlc_info *wlc, s32 nmode); extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode); extern void wlc_mimops_action_ht_send(struct wlc_info *wlc, - wlc_bsscfg_t *bsscfg, u8 mimops_mode); + struct wlc_bsscfg *bsscfg, + u8 mimops_mode); extern void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot); -extern void wlc_set_bssid(wlc_bsscfg_t *cfg); -extern void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend); +extern void wlc_set_bssid(struct wlc_bsscfg *cfg); +extern void wlc_edcf_setparams(struct wlc_bsscfg *cfg, bool suspend); extern void wlc_set_ratetable(struct wlc_info *wlc); -extern int wlc_set_mac(wlc_bsscfg_t *cfg); +extern int wlc_set_mac(struct wlc_bsscfg *cfg); extern void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, ratespec_t bcn_rate); extern void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len); -- cgit v1.2.3 From 89a4d0cbdee5289025c38b6b9706ad5dc5df264b Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Thu, 10 Mar 2011 14:40:20 +0100 Subject: staging: brcm80211: lower number of wlc_bsscfg.h includes Code cleanup. Signed-off-by: Roland Vossen Reviewed-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_antsel.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h | 3 --- drivers/staging/brcm80211/brcmsmac/wlc_channel.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c | 1 - drivers/staging/brcm80211/brcmsmac/wlc_stf.c | 1 - drivers/staging/brcm80211/include/bcmdefs.h | 1 + 8 files changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index 0a0ff3057f11..c6cdcd940956 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -34,7 +34,6 @@ #include "wlc_antsel.h" #include "wl_export.h" #include "wl_dbg.h" -#include "wlc_bsscfg.h" #include "wlc_channel.h" #include "wlc_main.h" #include "wlc_ampdu.h" diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c index 566be8689478..85a73a978d4f 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c @@ -36,7 +36,6 @@ #include "phy/wlc_phy_hal.h" #include "wlc_bmac.h" #include "wlc_channel.h" -#include "wlc_bsscfg.h" #include "wlc_main.h" #include "wl_export.h" #include "wlc_phy_shim.h" diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index b85194dd57ce..5a96dc3cdb36 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -47,7 +47,6 @@ #include "wlc_phy_shim.h" #include "phy/wlc_phy_hal.h" #include "wlc_channel.h" -#include "wlc_bsscfg.h" #include "wlc_main.h" #include "wl_export.h" #include "wl_ucode.h" diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h b/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h index cd5cfbbce94a..bbcff4fb5147 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h @@ -23,9 +23,6 @@ #define BSSCFG_IBSS(cfg) (!(cfg)->BSS) -/* forward declarations */ -typedef struct wlc_bsscfg wlc_bsscfg_t; - #define NTXRATE 64 /* # tx MPDUs rate is reported for */ #define MAXMACLIST 64 /* max # source MAC matches */ #define BCN_TEMPLATE_COUNT 2 diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c index d43948f1c643..96161c0ab65a 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c @@ -35,7 +35,6 @@ #include "wlc_bmac.h" #include "wlc_rate.h" #include "wlc_channel.h" -#include "wlc_bsscfg.h" #include "wlc_main.h" #include "wlc_stf.h" #include "wl_dbg.h" diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c index 1ac659769c57..96d36001f460 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c @@ -52,7 +52,6 @@ #include "wlc_bmac.h" #include "wlc_phy_hal.h" #include "wl_export.h" -#include "wlc_bsscfg.h" #include "wlc_main.h" #include "wlc_phy_shim.h" diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c index a6f6e5c649c7..098fd59ee153 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c @@ -36,7 +36,6 @@ #include "wlc_key.h" #include "phy/wlc_phy_hal.h" #include "wlc_channel.h" -#include "wlc_bsscfg.h" #include "wlc_main.h" #include "wl_export.h" #include "wlc_bmac.h" diff --git a/drivers/staging/brcm80211/include/bcmdefs.h b/drivers/staging/brcm80211/include/bcmdefs.h index 601ec706878c..22a389e1d511 100644 --- a/drivers/staging/brcm80211/include/bcmdefs.h +++ b/drivers/staging/brcm80211/include/bcmdefs.h @@ -157,5 +157,6 @@ typedef struct { /* handle forward declaration */ struct wl_info; +struct wlc_bsscfg; #endif /* _bcmdefs_h_ */ -- cgit v1.2.3 From 997941d7efe4d165a558ed5b6029a8b3c2c85cf7 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 11 Mar 2011 21:38:17 +0100 Subject: ath9k_hw: fix REG_SET_BIT and REG_CLR_BIT for multiple bits Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index ef79f4c876ca..6650fd48415c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -95,9 +95,9 @@ #define REG_READ_FIELD(_a, _r, _f) \ (((REG_READ(_a, _r) & _f) >> _f##_S)) #define REG_SET_BIT(_a, _r, _f) \ - REG_WRITE(_a, _r, REG_READ(_a, _r) | _f) + REG_WRITE(_a, _r, REG_READ(_a, _r) | (_f)) #define REG_CLR_BIT(_a, _r, _f) \ - REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f) + REG_WRITE(_a, _r, REG_READ(_a, _r) & ~(_f)) #define DO_DELAY(x) do { \ if ((++(x) % 64) == 0) \ -- cgit v1.2.3 From 0d51cccc2436fa4d978efc3764552779e163d840 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 11 Mar 2011 21:38:18 +0100 Subject: ath9k: fix stopping tx dma on reset In some situations, stopping Tx DMA frequently fails, leading to messages like this: ath: Failed to stop TX DMA in 100 msec after killing last frame ath: Failed to stop TX DMA! This patch uses a few MAC features to abort DMA globally instead of iterating over all hardware queues and attempting to stop them individually. Not only is that faster and works with a shorter timeout, it also makes the process much more reliable. With this change, I can no longer trigger these messages on AR9380, and on AR9280 they become much more rare. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/mac.c | 28 ++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/mac.h | 1 + drivers/net/wireless/ath/ath9k/xmit.c | 14 ++++++-------- 3 files changed, 35 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index c75d40fb86f1..58aaf9ab0920 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -143,6 +143,34 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel) } EXPORT_SYMBOL(ath9k_hw_updatetxtriglevel); +void ath9k_hw_abort_tx_dma(struct ath_hw *ah) +{ + int i, q; + + REG_WRITE(ah, AR_Q_TXD, AR_Q_TXD_M); + + REG_SET_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF); + REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); + REG_SET_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF); + + for (q = 0; q < AR_NUM_QCU; q++) { + for (i = 0; i < 1000; i++) { + if (i) + udelay(5); + + if (!ath9k_hw_numtxpending(ah, q)) + break; + } + } + + REG_CLR_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF); + REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); + REG_CLR_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF); + + REG_WRITE(ah, AR_Q_TXD, 0); +} +EXPORT_SYMBOL(ath9k_hw_abort_tx_dma); + bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q) { #define ATH9K_TX_STOP_DMA_TIMEOUT 4000 /* usec */ diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 04d58ae923bb..d37c6d413be1 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -677,6 +677,7 @@ void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds); u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q); bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel); bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q); +void ath9k_hw_abort_tx_dma(struct ath_hw *ah); void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs); bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, const struct ath9k_tx_queue_info *qinfo); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index e16136d61799..bb1d29e90eb1 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1194,16 +1194,14 @@ bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) if (sc->sc_flags & SC_OP_INVALID) return true; - /* Stop beacon queue */ - ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); + ath9k_hw_abort_tx_dma(ah); - /* Stop data queues */ + /* Check if any queue remains active */ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { - if (ATH_TXQ_SETUP(sc, i)) { - txq = &sc->tx.txq[i]; - ath9k_hw_stoptxdma(ah, txq->axq_qnum); - npend += ath9k_hw_numtxpending(ah, txq->axq_qnum); - } + if (!ATH_TXQ_SETUP(sc, i)) + continue; + + npend += ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum); } if (npend) -- cgit v1.2.3 From 86271e460a66003dc1f4cbfd845adafb790b7587 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 11 Mar 2011 21:38:19 +0100 Subject: ath9k: fix the .flush driver op implementation This patch simplifies the flush op and reuses ath_drain_all_txq for flushing out pending frames if necessary. It also uses a global timeout of 200ms instead of the per-queue 60ms timeout. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 - drivers/net/wireless/ath/ath9k/main.c | 56 +++++++++++++--------------------- drivers/net/wireless/ath/ath9k/xmit.c | 28 ++++++++--------- 3 files changed, 34 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index c718ab512a97..099bd4183ad0 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -189,7 +189,6 @@ struct ath_txq { u32 axq_ampdu_depth; bool stopped; bool axq_tx_inprogress; - bool txq_flush_inprogress; struct list_head axq_acq; struct list_head txq_fifo[ATH_TXFIFO_DEPTH]; struct list_head txq_fifo_pending; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 2e228aada1a9..115f162c617a 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2128,56 +2128,42 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) static void ath9k_flush(struct ieee80211_hw *hw, bool drop) { -#define ATH_FLUSH_TIMEOUT 60 /* ms */ struct ath_softc *sc = hw->priv; - struct ath_txq *txq = NULL; - struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); - int i, j, npend = 0; + int timeout = 200; /* ms */ + int i, j; + ath9k_ps_wakeup(sc); mutex_lock(&sc->mutex); cancel_delayed_work_sync(&sc->tx_complete_work); - for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { - if (!ATH_TXQ_SETUP(sc, i)) - continue; - txq = &sc->tx.txq[i]; + if (drop) + timeout = 1; - if (!drop) { - for (j = 0; j < ATH_FLUSH_TIMEOUT; j++) { - if (!ath9k_has_pending_frames(sc, txq)) - break; - usleep_range(1000, 2000); - } - } + for (j = 0; j < timeout; j++) { + int npend = 0; + + if (j) + usleep_range(1000, 2000); - if (drop || ath9k_has_pending_frames(sc, txq)) { - ath_dbg(common, ATH_DBG_QUEUE, "Drop frames from hw queue:%d\n", - txq->axq_qnum); - spin_lock_bh(&txq->axq_lock); - txq->txq_flush_inprogress = true; - spin_unlock_bh(&txq->axq_lock); - - ath9k_ps_wakeup(sc); - ath9k_hw_stoptxdma(ah, txq->axq_qnum); - npend = ath9k_hw_numtxpending(ah, txq->axq_qnum); - ath9k_ps_restore(sc); - if (npend) - break; - - ath_draintxq(sc, txq, false); - txq->txq_flush_inprogress = false; + for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { + if (!ATH_TXQ_SETUP(sc, i)) + continue; + + npend += ath9k_has_pending_frames(sc, &sc->tx.txq[i]); } + + if (!npend) + goto out; } - if (npend) { + if (!ath_drain_all_txq(sc, false)) ath_reset(sc, false); - txq->txq_flush_inprogress = false; - } +out: ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); mutex_unlock(&sc->mutex); + ath9k_ps_restore(sc); } struct ieee80211_ops ath9k_ops = { diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index bb1d29e90eb1..f977f804c68a 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -2012,8 +2012,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) spin_lock_bh(&txq->axq_lock); if (list_empty(&txq->axq_q)) { txq->axq_link = NULL; - if (sc->sc_flags & SC_OP_TXAGGR && - !txq->txq_flush_inprogress) + if (sc->sc_flags & SC_OP_TXAGGR) ath_txq_schedule(sc, txq); spin_unlock_bh(&txq->axq_lock); break; @@ -2094,7 +2093,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) spin_lock_bh(&txq->axq_lock); - if (sc->sc_flags & SC_OP_TXAGGR && !txq->txq_flush_inprogress) + if (sc->sc_flags & SC_OP_TXAGGR) ath_txq_schedule(sc, txq); spin_unlock_bh(&txq->axq_lock); } @@ -2265,18 +2264,17 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) spin_lock_bh(&txq->axq_lock); - if (!txq->txq_flush_inprogress) { - if (!list_empty(&txq->txq_fifo_pending)) { - INIT_LIST_HEAD(&bf_head); - bf = list_first_entry(&txq->txq_fifo_pending, - struct ath_buf, list); - list_cut_position(&bf_head, - &txq->txq_fifo_pending, - &bf->bf_lastbf->list); - ath_tx_txqaddbuf(sc, txq, &bf_head); - } else if (sc->sc_flags & SC_OP_TXAGGR) - ath_txq_schedule(sc, txq); - } + if (!list_empty(&txq->txq_fifo_pending)) { + INIT_LIST_HEAD(&bf_head); + bf = list_first_entry(&txq->txq_fifo_pending, + struct ath_buf, list); + list_cut_position(&bf_head, + &txq->txq_fifo_pending, + &bf->bf_lastbf->list); + ath_tx_txqaddbuf(sc, txq, &bf_head); + } else if (sc->sc_flags & SC_OP_TXAGGR) + ath_txq_schedule(sc, txq); + spin_unlock_bh(&txq->axq_lock); } } -- cgit v1.2.3 From efff395e97fffd55c60c77c09a18deba8d84e2c0 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 11 Mar 2011 21:38:20 +0100 Subject: ath9k: improve reliability of beacon transmission and stuck beacon handling ath9k calls ath9k_hw_stoptxdma every time it sends a beacon, however there is not much point in doing that if the previous beacon and mcast traffic went out properly. On AR9380, calling that function too often can result in an increase of stuck beacons due to differences in the handling of the queue enable/disable functionality. With this patch, the queue will only be explicitly stopped if the previous data frames were not sent successfully. With the beacon code being the only remaining user of ath9k_hw_stoptxdma, this function can be simplified in order to remove the now pointless attempts at waiting for transmission completion, which would never happen at this point due to the different method of tx scheduling of the beacon queue. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 13 +----- drivers/net/wireless/ath/ath9k/mac.c | 71 +++++---------------------------- drivers/net/wireless/ath/ath9k/mac.h | 2 +- 3 files changed, 12 insertions(+), 74 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index a4bdfdb043ef..6d2a545fc35e 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -373,6 +373,7 @@ void ath_beacon_tasklet(unsigned long data) ath_dbg(common, ATH_DBG_BSTUCK, "missed %u consecutive beacons\n", sc->beacon.bmisscnt); + ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq); ath9k_hw_bstuck_nfcal(ah); } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { ath_dbg(common, ATH_DBG_BSTUCK, @@ -450,16 +451,6 @@ void ath_beacon_tasklet(unsigned long data) sc->beacon.updateslot = OK; } if (bfaddr != 0) { - /* - * Stop any current dma and put the new frame(s) on the queue. - * This should never fail since we check above that no frames - * are still pending on the queue. - */ - if (!ath9k_hw_stoptxdma(ah, sc->beacon.beaconq)) { - ath_err(common, "beacon queue %u did not stop?\n", - sc->beacon.beaconq); - } - /* NB: cabq traffic should already be queued and primed */ ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr); ath9k_hw_txstart(ah, sc->beacon.beaconq); @@ -780,7 +771,7 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) ah->imask &= ~ATH9K_INT_SWBA; ath9k_hw_set_interrupts(ah, ah->imask); tasklet_kill(&sc->bcon_tasklet); - ath9k_hw_stoptxdma(ah, sc->beacon.beaconq); + ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq); } ath9k_ps_restore(sc); } diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 58aaf9ab0920..cb5d81426d57 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -171,84 +171,31 @@ void ath9k_hw_abort_tx_dma(struct ath_hw *ah) } EXPORT_SYMBOL(ath9k_hw_abort_tx_dma); -bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q) +bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q) { -#define ATH9K_TX_STOP_DMA_TIMEOUT 4000 /* usec */ +#define ATH9K_TX_STOP_DMA_TIMEOUT 1000 /* usec */ #define ATH9K_TIME_QUANTUM 100 /* usec */ - struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_hw_capabilities *pCap = &ah->caps; - struct ath9k_tx_queue_info *qi; - u32 tsfLow, j, wait; - u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM; - - if (q >= pCap->total_queues) { - ath_dbg(common, ATH_DBG_QUEUE, - "Stopping TX DMA, invalid queue: %u\n", q); - return false; - } - - qi = &ah->txq[q]; - if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { - ath_dbg(common, ATH_DBG_QUEUE, - "Stopping TX DMA, inactive queue: %u\n", q); - return false; - } + int wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM; + int wait; REG_WRITE(ah, AR_Q_TXD, 1 << q); for (wait = wait_time; wait != 0; wait--) { - if (ath9k_hw_numtxpending(ah, q) == 0) - break; - udelay(ATH9K_TIME_QUANTUM); - } - - if (ath9k_hw_numtxpending(ah, q)) { - ath_dbg(common, ATH_DBG_QUEUE, - "%s: Num of pending TX Frames %d on Q %d\n", - __func__, ath9k_hw_numtxpending(ah, q), q); - - for (j = 0; j < 2; j++) { - tsfLow = REG_READ(ah, AR_TSF_L32); - REG_WRITE(ah, AR_QUIET2, - SM(10, AR_QUIET2_QUIET_DUR)); - REG_WRITE(ah, AR_QUIET_PERIOD, 100); - REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10); - REG_SET_BIT(ah, AR_TIMER_MODE, - AR_QUIET_TIMER_EN); - - if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10)) - break; - - ath_dbg(common, ATH_DBG_QUEUE, - "TSF has moved while trying to set quiet time TSF: 0x%08x\n", - tsfLow); - } - - REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); - - udelay(200); - REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN); - - wait = wait_time; - while (ath9k_hw_numtxpending(ah, q)) { - if ((--wait) == 0) { - ath_err(common, - "Failed to stop TX DMA in 100 msec after killing last frame\n"); - break; - } + if (wait != wait_time) udelay(ATH9K_TIME_QUANTUM); - } - REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); + if (ath9k_hw_numtxpending(ah, q) == 0) + break; } REG_WRITE(ah, AR_Q_TXD, 0); + return wait != 0; #undef ATH9K_TX_STOP_DMA_TIMEOUT #undef ATH9K_TIME_QUANTUM } -EXPORT_SYMBOL(ath9k_hw_stoptxdma); +EXPORT_SYMBOL(ath9k_hw_stop_dma_queue); void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs) { diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index d37c6d413be1..b2b2ff852c32 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -676,7 +676,7 @@ void ath9k_hw_txstart(struct ath_hw *ah, u32 q); void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds); u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q); bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel); -bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q); +bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q); void ath9k_hw_abort_tx_dma(struct ath_hw *ah); void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs); bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, -- cgit v1.2.3 From 7d2c16befae67b901e6750b845661c1fdffd19f1 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 12 Mar 2011 01:11:28 +0100 Subject: ath9k: fix aggregation related interoperability issues Some clients seems to keep track of their reorder window even after an aggregation session has been disabled. This causes issues if there are still retried but not completed frames pending for the TID. To ensure that rx does not stall in such situations, set sendbar to 1 for any frame purged from the TID queue on teardown. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index f977f804c68a..ef22096d40c9 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -166,7 +166,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) fi = get_frame_info(bf->bf_mpdu); if (fi->retries) { ath_tx_update_baw(sc, tid, fi->seqno); - ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); + ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 1); } else { ath_tx_send_normal(sc, txq, NULL, &bf_head); } -- cgit v1.2.3 From a3b6ff03527247c81eab37d95b7fb36e7eda1939 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 14 Mar 2011 12:33:37 +0300 Subject: Staging: crystalhd: change GFP_ATOMIC to GFP_KERNEL These two allocations are only called from the probe() path and there aren't any locks held for probe(). Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/crystalhd/crystalhd_lnx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c index 719e70bc871e..9a6b650cd608 100644 --- a/drivers/staging/crystalhd/crystalhd_lnx.c +++ b/drivers/staging/crystalhd/crystalhd_lnx.c @@ -393,8 +393,7 @@ static int __devinit chd_dec_init_chdev(struct crystalhd_adp *adp) /* Allocate general purpose ioctl pool. */ for (i = 0; i < CHD_IODATA_POOL_SZ; i++) { - /* FIXME: jarod: why atomic? */ - temp = kzalloc(sizeof(struct crystalhd_ioctl_data), GFP_ATOMIC); + temp = kzalloc(sizeof(struct crystalhd_ioctl_data), GFP_KERNEL); if (!temp) { BCMLOG_ERR("ioctl data pool kzalloc failed\n"); rc = -ENOMEM; @@ -549,8 +548,7 @@ static int __devinit chd_dec_pci_probe(struct pci_dev *pdev, pdev->vendor, pdev->device, pdev->subsystem_vendor, pdev->subsystem_device); - /* FIXME: jarod: why atomic? */ - pinfo = kzalloc(sizeof(struct crystalhd_adp), GFP_ATOMIC); + pinfo = kzalloc(sizeof(struct crystalhd_adp), GFP_KERNEL); if (!pinfo) { BCMLOG_ERR("Failed to allocate memory\n"); return -ENOMEM; -- cgit v1.2.3 From e278913c3c70dea6302d99f5f0ee4961e09970b6 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 14 Mar 2011 12:35:31 +0300 Subject: Staging: crystalhd: don't waste the last char of buffer pinfo->name is a 32 char buffer. In the original code, the last char wasn't fully utilized. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/crystalhd/crystalhd_lnx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c index 9a6b650cd608..c1ee24c98315 100644 --- a/drivers/staging/crystalhd/crystalhd_lnx.c +++ b/drivers/staging/crystalhd/crystalhd_lnx.c @@ -562,7 +562,7 @@ static int __devinit chd_dec_pci_probe(struct pci_dev *pdev, return rc; } - snprintf(pinfo->name, 31, "crystalhd_pci_e:%d:%d:%d", + snprintf(pinfo->name, sizeof(pinfo->name), "crystalhd_pci_e:%d:%d:%d", pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); -- cgit v1.2.3 From bd51c0b078eb3edeee9e48eb236d5831d7ae34cf Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 10 Mar 2011 13:26:46 +0100 Subject: staging: IIO: DAC: AD5446: Add missing ID table entries Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5446.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index dcec29733807..4f1d8813272e 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -295,8 +295,10 @@ static int ad5446_remove(struct spi_device *spi) static const struct spi_device_id ad5446_id[] = { {"ad5444", ID_AD5444}, {"ad5446", ID_AD5446}, - {"ad5542a", ID_AD5542A}, {"ad5512a", ID_AD5512A}, + {"ad5542a", ID_AD5542A}, + {"ad5543", ID_AD5543}, + {"ad5553", ID_AD5553}, {"ad5620-2500", ID_AD5620_2500}, /* AD5620/40/60: */ {"ad5620-1250", ID_AD5620_1250}, /* part numbers may look differently */ {"ad5640-2500", ID_AD5640_2500}, -- cgit v1.2.3 From bbed4dc791036e97cbe844935dece153fdace0dc Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 10 Mar 2011 13:26:47 +0100 Subject: staging: IIO: DAC: AD5446: Add power down support Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5446.c | 153 +++++++++++++++++++++++++++++++++++---- drivers/staging/iio/dac/ad5446.h | 19 +++-- 2 files changed, 153 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index 4f1d8813272e..861a7eacdaf7 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -48,6 +48,20 @@ static void ad5660_store_sample(struct ad5446_state *st, unsigned val) st->data.d24[2] = val & 0xFF; } +static void ad5620_store_pwr_down(struct ad5446_state *st, unsigned mode) +{ + st->data.d16 = cpu_to_be16(mode << 14); +} + +static void ad5660_store_pwr_down(struct ad5446_state *st, unsigned mode) +{ + unsigned val = mode << 16; + + st->data.d24[0] = (val >> 16) & 0xFF; + st->data.d24[1] = (val >> 8) & 0xFF; + st->data.d24[2] = val & 0xFF; +} + static ssize_t ad5446_write(struct device *dev, struct device_attribute *attr, const char *buf, @@ -68,6 +82,7 @@ static ssize_t ad5446_write(struct device *dev, } mutex_lock(&dev_info->mlock); + st->cached_val = val; st->chip_info->store_sample(st, val); ret = spi_sync(st->spi, &st->msg); mutex_unlock(&dev_info->mlock); @@ -102,15 +117,119 @@ static ssize_t ad5446_show_name(struct device *dev, } static IIO_DEVICE_ATTR(name, S_IRUGO, ad5446_show_name, NULL, 0); +static ssize_t ad5446_write_powerdown_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad5446_state *st = dev_info->dev_data; + + if (sysfs_streq(buf, "1kohm_to_gnd")) + st->pwr_down_mode = MODE_PWRDWN_1k; + else if (sysfs_streq(buf, "100kohm_to_gnd")) + st->pwr_down_mode = MODE_PWRDWN_100k; + else if (sysfs_streq(buf, "three_state")) + st->pwr_down_mode = MODE_PWRDWN_TRISTATE; + else + return -EINVAL; + + return len; +} + +static ssize_t ad5446_read_powerdown_mode(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad5446_state *st = dev_info->dev_data; + + char mode[][15] = {"", "1kohm_to_gnd", "100kohm_to_gnd", "three_state"}; + + return sprintf(buf, "%s\n", mode[st->pwr_down_mode]); +} + +static ssize_t ad5446_read_dac_powerdown(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad5446_state *st = dev_info->dev_data; + + return sprintf(buf, "%d\n", st->pwr_down); +} + +static ssize_t ad5446_write_dac_powerdown(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad5446_state *st = dev_info->dev_data; + unsigned long readin; + int ret; + + ret = strict_strtol(buf, 10, &readin); + if (ret) + return ret; + + if (readin > 1) + ret = -EINVAL; + + mutex_lock(&dev_info->mlock); + st->pwr_down = readin; + + if (st->pwr_down) + st->chip_info->store_pwr_down(st, st->pwr_down_mode); + else + st->chip_info->store_sample(st, st->cached_val); + + ret = spi_sync(st->spi, &st->msg); + mutex_unlock(&dev_info->mlock); + + return ret ? ret : len; +} + +static IIO_DEVICE_ATTR(out_powerdown_mode, S_IRUGO | S_IWUSR, + ad5446_read_powerdown_mode, + ad5446_write_powerdown_mode, 0); + +static IIO_CONST_ATTR(out_powerdown_mode_available, + "1kohm_to_gnd 100kohm_to_gnd three_state"); + +static IIO_DEVICE_ATTR(out0_powerdown, S_IRUGO | S_IWUSR, + ad5446_read_dac_powerdown, + ad5446_write_dac_powerdown, 0); + static struct attribute *ad5446_attributes[] = { &iio_dev_attr_out0_raw.dev_attr.attr, &iio_dev_attr_out_scale.dev_attr.attr, + &iio_dev_attr_out0_powerdown.dev_attr.attr, + &iio_dev_attr_out_powerdown_mode.dev_attr.attr, + &iio_const_attr_out_powerdown_mode_available.dev_attr.attr, &iio_dev_attr_name.dev_attr.attr, NULL, }; +static mode_t ad5446_attr_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad5446_state *st = iio_dev_get_devdata(dev_info); + + mode_t mode = attr->mode; + + if (!st->chip_info->store_pwr_down && + (attr == &iio_dev_attr_out0_powerdown.dev_attr.attr || + attr == &iio_dev_attr_out_powerdown_mode.dev_attr.attr || + attr == + &iio_const_attr_out_powerdown_mode_available.dev_attr.attr)) + mode = 0; + + return mode; +} + static const struct attribute_group ad5446_attribute_group = { .attrs = ad5446_attributes, + .is_visible = ad5446_attr_is_visible, }; static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { @@ -156,6 +275,7 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { .left_shift = 2, .int_vref_mv = 2500, .store_sample = ad5620_store_sample, + .store_pwr_down = ad5620_store_pwr_down, }, [ID_AD5620_1250] = { .bits = 12, @@ -163,6 +283,7 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { .left_shift = 2, .int_vref_mv = 1250, .store_sample = ad5620_store_sample, + .store_pwr_down = ad5620_store_pwr_down, }, [ID_AD5640_2500] = { .bits = 14, @@ -170,6 +291,7 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { .left_shift = 0, .int_vref_mv = 2500, .store_sample = ad5620_store_sample, + .store_pwr_down = ad5620_store_pwr_down, }, [ID_AD5640_1250] = { .bits = 14, @@ -177,6 +299,7 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { .left_shift = 0, .int_vref_mv = 1250, .store_sample = ad5620_store_sample, + .store_pwr_down = ad5620_store_pwr_down, }, [ID_AD5660_2500] = { .bits = 16, @@ -184,6 +307,7 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { .left_shift = 0, .int_vref_mv = 2500, .store_sample = ad5660_store_sample, + .store_pwr_down = ad5660_store_pwr_down, }, [ID_AD5660_1250] = { .bits = 16, @@ -191,6 +315,7 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { .left_shift = 0, .int_vref_mv = 1250, .store_sample = ad5660_store_sample, + .store_pwr_down = ad5660_store_pwr_down, }, }; @@ -243,20 +368,20 @@ static int __devinit ad5446_probe(struct spi_device *spi) spi_message_add_tail(&st->xfer, &st->msg); switch (spi_get_device_id(spi)->driver_data) { - case ID_AD5620_2500: - case ID_AD5620_1250: - case ID_AD5640_2500: - case ID_AD5640_1250: - case ID_AD5660_2500: - case ID_AD5660_1250: - st->vref_mv = st->chip_info->int_vref_mv; - break; - default: - if (voltage_uv) - st->vref_mv = voltage_uv / 1000; - else - dev_warn(&spi->dev, - "reference voltage unspecified\n"); + case ID_AD5620_2500: + case ID_AD5620_1250: + case ID_AD5640_2500: + case ID_AD5640_1250: + case ID_AD5660_2500: + case ID_AD5660_1250: + st->vref_mv = st->chip_info->int_vref_mv; + break; + default: + if (voltage_uv) + st->vref_mv = voltage_uv / 1000; + else + dev_warn(&spi->dev, + "reference voltage unspecified\n"); } ret = iio_device_register(st->indio_dev); diff --git a/drivers/staging/iio/dac/ad5446.h b/drivers/staging/iio/dac/ad5446.h index 0cb9c14279e6..e9397a6783c5 100644 --- a/drivers/staging/iio/dac/ad5446.h +++ b/drivers/staging/iio/dac/ad5446.h @@ -27,6 +27,10 @@ #define RES_MASK(bits) ((1 << (bits)) - 1) +#define MODE_PWRDWN_1k 0x1 +#define MODE_PWRDWN_100k 0x2 +#define MODE_PWRDWN_TRISTATE 0x3 + /** * struct ad5446_state - driver instance specific data * @indio_dev: the industrial I/O device @@ -47,6 +51,9 @@ struct ad5446_state { struct regulator *reg; struct work_struct poll_work; unsigned short vref_mv; + unsigned cached_val; + unsigned pwr_down_mode; + unsigned pwr_down; struct spi_transfer xfer; struct spi_message msg; union { @@ -62,14 +69,16 @@ struct ad5446_state { * @left_shift: number of bits the datum must be shifted * @int_vref_mv: AD5620/40/60: the internal reference voltage * @store_sample: chip specific helper function to store the datum + * @store_sample: chip specific helper function to store the powerpown cmd */ struct ad5446_chip_info { - u8 bits; - u8 storagebits; - u8 left_shift; - u16 int_vref_mv; - void (*store_sample) (struct ad5446_state *st, unsigned val); + u8 bits; + u8 storagebits; + u8 left_shift; + u16 int_vref_mv; + void (*store_sample) (struct ad5446_state *st, unsigned val); + void (*store_pwr_down) (struct ad5446_state *st, unsigned mode); }; /** -- cgit v1.2.3 From 2b61535a6e210358255c872b3187e48869e16e27 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 10 Mar 2011 13:26:48 +0100 Subject: staging: IIO: DAC: AD5446: Add support for AD5601/AD5611/AD5621 This patch adds support for the AD5601/AD5611/AD5621 single channel, 8-/10-/12-bit, buffered voltage output DACs. Changes since v1: Sort Kconfig description my number Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/Kconfig | 3 ++- drivers/staging/iio/dac/ad5446.c | 24 ++++++++++++++++++++++++ drivers/staging/iio/dac/ad5446.h | 3 +++ 3 files changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/dac/Kconfig b/drivers/staging/iio/dac/Kconfig index 3c72871389a2..67defcb359b1 100644 --- a/drivers/staging/iio/dac/Kconfig +++ b/drivers/staging/iio/dac/Kconfig @@ -15,7 +15,8 @@ config AD5446 depends on SPI help Say yes here to build support for Analog Devices AD5444, AD5446, - AD5512A, AD5542A, AD5543, AD5553, AD5620, AD5640, AD5660 DACs. + AD5512A, AD5542A, AD5543, AD5553, AD5601, AD5611, AD5620, AD5621, + AD5640, AD5660 DACs. To compile this driver as a module, choose M here: the module will be called ad5446. diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index 861a7eacdaf7..8623a72e046c 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -269,6 +269,27 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { .left_shift = 0, .store_sample = ad5542_store_sample, }, + [ID_AD5601] = { + .bits = 8, + .storagebits = 16, + .left_shift = 6, + .store_sample = ad5542_store_sample, + .store_pwr_down = ad5620_store_pwr_down, + }, + [ID_AD5611] = { + .bits = 10, + .storagebits = 16, + .left_shift = 4, + .store_sample = ad5542_store_sample, + .store_pwr_down = ad5620_store_pwr_down, + }, + [ID_AD5621] = { + .bits = 12, + .storagebits = 16, + .left_shift = 2, + .store_sample = ad5542_store_sample, + .store_pwr_down = ad5620_store_pwr_down, + }, [ID_AD5620_2500] = { .bits = 12, .storagebits = 16, @@ -424,6 +445,9 @@ static const struct spi_device_id ad5446_id[] = { {"ad5542a", ID_AD5542A}, {"ad5543", ID_AD5543}, {"ad5553", ID_AD5553}, + {"ad5601", ID_AD5601}, + {"ad5611", ID_AD5611}, + {"ad5621", ID_AD5621}, {"ad5620-2500", ID_AD5620_2500}, /* AD5620/40/60: */ {"ad5620-1250", ID_AD5620_1250}, /* part numbers may look differently */ {"ad5640-2500", ID_AD5640_2500}, diff --git a/drivers/staging/iio/dac/ad5446.h b/drivers/staging/iio/dac/ad5446.h index e9397a6783c5..7ac63ab8a11d 100644 --- a/drivers/staging/iio/dac/ad5446.h +++ b/drivers/staging/iio/dac/ad5446.h @@ -96,6 +96,9 @@ enum ad5446_supported_device_ids { ID_AD5543, ID_AD5512A, ID_AD5553, + ID_AD5601, + ID_AD5611, + ID_AD5621, ID_AD5620_2500, ID_AD5620_1250, ID_AD5640_2500, -- cgit v1.2.3 From a209efadf0b93238fe052fe1e92f48ccf6da57a1 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:15 +0100 Subject: staging: ft1000: Replace camelcase CardSendCommand function name. Replace CardSendCommand by card_send_command. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_debug.c | 6 +++--- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 18 +++++++++--------- drivers/staging/ft1000/ft1000-usb/ft1000_usb.h | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c index 149ba59f96bf..19db23fe73ca 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c @@ -471,14 +471,14 @@ static long ft1000_ioctl (struct file *file, unsigned int command, // Connect Message DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_CONNECT\n"); ConnectionMsg[79] = 0xfc; - CardSendCommand(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); + card_send_command(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); break; case IOCTL_DISCONNECT: // Disconnect Message DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_DISCONNECT\n"); ConnectionMsg[79] = 0xfd; - CardSendCommand(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); + card_send_command(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); break; case IOCTL_GET_DSP_STAT_CMD: //DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DSP_STAT called\n"); @@ -642,7 +642,7 @@ static long ft1000_ioctl (struct file *file, unsigned int command, } pmsg++; ppseudo_hdr = (struct pseudo_hdr *)pmsg; - CardSendCommand(ft1000dev,(unsigned short*)dpram_data,total_len+2); + card_send_command(ft1000dev,(unsigned short*)dpram_data,total_len+2); info->app_info[app_index].nTxMsg++; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index e3b99347ff78..293a469fadce 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -467,7 +467,7 @@ static void card_reset_dsp(struct ft1000_device *ft1000dev, bool value) } //--------------------------------------------------------------------------- -// Function: CardSendCommand +// Function: card_send_command // // Parameters: ft1000_device - device structure // ptempbuffer - command buffer @@ -481,17 +481,17 @@ static void card_reset_dsp(struct ft1000_device *ft1000dev, bool value) // Notes: // //--------------------------------------------------------------------------- -void CardSendCommand(struct ft1000_device *ft1000dev, void *ptempbuffer, int size) +void card_send_command(struct ft1000_device *ft1000dev, void *ptempbuffer, int size) { unsigned short temp; unsigned char *commandbuf; - DEBUG("CardSendCommand: enter CardSendCommand... size=%d\n", size); + DEBUG("card_send_command: enter card_send_command... size=%d\n", size); commandbuf =(unsigned char*) kmalloc(size+2, GFP_KERNEL); memcpy((void*)commandbuf+2, (void*)ptempbuffer, size); - //DEBUG("CardSendCommand: Command Send\n"); + //DEBUG("card_send_command: Command Send\n"); ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL); @@ -509,18 +509,18 @@ void CardSendCommand(struct ft1000_device *ft1000dev, void *ptempbuffer, int siz } - //DEBUG("CardSendCommand: write dpram ... size=%d\n", size); + //DEBUG("card_send_command: write dpram ... size=%d\n", size); ft1000_write_dpram32(ft1000dev, 0,commandbuf, size); msleep(1); - //DEBUG("CardSendCommand: write into doorbell ...\n"); + //DEBUG("card_send_command: write into doorbell ...\n"); ft1000_write_register(ft1000dev, FT1000_DB_DPRAM_TX ,FT1000_REG_DOORBELL) ; msleep(1); ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL); - //DEBUG("CardSendCommand: read doorbell ...temp=%x\n", temp); + //DEBUG("card_send_command: read doorbell ...temp=%x\n", temp); if ( (temp & 0x0100) == 0) { - //DEBUG("CardSendCommand: Message sent\n"); + //DEBUG("card_send_command: Message sent\n"); } } @@ -1811,7 +1811,7 @@ static int ft1000_proc_drvmsg (struct ft1000_device *dev, u16 size) { *pmsg++ = convert.wrd; *pmsg++ = htons(info->DrvErrNum); - CardSendCommand (dev, (unsigned char*)&tempbuffer[0], (u16)(0x0012 + PSEUDOSZ)); + card_send_command (dev, (unsigned char*)&tempbuffer[0], (u16)(0x0012 + PSEUDOSZ)); info->DrvErrNum = 0; } info->DrvMsgPend = 0; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index 88183fe142a2..84ff53d2e2c9 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -581,7 +581,7 @@ extern spinlock_t free_buff_lock; // lock to arbitrate free buffer list for re int ft1000_create_dev(struct ft1000_device *dev); void ft1000_destroy_dev(struct net_device *dev); -extern void CardSendCommand(struct ft1000_device *ft1000dev, void *ptempbuffer, int size); +extern void card_send_command(struct ft1000_device *ft1000dev, void *ptempbuffer, int size); struct dpram_blk *ft1000_get_buffer(struct list_head *bufflist); void ft1000_free_buffer(struct dpram_blk *pdpram_blk, struct list_head *plist); -- cgit v1.2.3 From 68e79bccceba1efc3b4abac1594cb1798dd5e780 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:16 +0100 Subject: staging: ft1000: Fix coding style in card_send_command function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 60 +++++++++++++-------------- 1 file changed, 28 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 293a469fadce..ded13f2f8326 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -481,51 +481,47 @@ static void card_reset_dsp(struct ft1000_device *ft1000dev, bool value) // Notes: // //--------------------------------------------------------------------------- -void card_send_command(struct ft1000_device *ft1000dev, void *ptempbuffer, int size) +void card_send_command(struct ft1000_device *ft1000dev, void *ptempbuffer, + int size) { - unsigned short temp; - unsigned char *commandbuf; + unsigned short temp; + unsigned char *commandbuf; - DEBUG("card_send_command: enter card_send_command... size=%d\n", size); + DEBUG("card_send_command: enter card_send_command... size=%d\n", size); - commandbuf =(unsigned char*) kmalloc(size+2, GFP_KERNEL); - memcpy((void*)commandbuf+2, (void*)ptempbuffer, size); + commandbuf = (unsigned char *)kmalloc(size + 2, GFP_KERNEL); + memcpy((void *)commandbuf + 2, (void *)ptempbuffer, size); - //DEBUG("card_send_command: Command Send\n"); + //DEBUG("card_send_command: Command Send\n"); - ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL); + ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL); - if (temp & 0x0100) - { - msleep(10); - } + if (temp & 0x0100) + msleep(10); - // check for odd word - size = size + 2; - if (size % 4) - { - // Must force to be 32 bit aligned - size += 4 - (size % 4); - } + /* check for odd word */ + size = size + 2; + /* Must force to be 32 bit aligned */ + if (size % 4) + size += 4 - (size % 4); - //DEBUG("card_send_command: write dpram ... size=%d\n", size); - ft1000_write_dpram32(ft1000dev, 0,commandbuf, size); - msleep(1); - //DEBUG("card_send_command: write into doorbell ...\n"); - ft1000_write_register(ft1000dev, FT1000_DB_DPRAM_TX ,FT1000_REG_DOORBELL) ; - msleep(1); + //DEBUG("card_send_command: write dpram ... size=%d\n", size); + ft1000_write_dpram32(ft1000dev, 0, commandbuf, size); + msleep(1); + //DEBUG("card_send_command: write into doorbell ...\n"); + ft1000_write_register(ft1000dev, FT1000_DB_DPRAM_TX, + FT1000_REG_DOORBELL); + msleep(1); - ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL); - //DEBUG("card_send_command: read doorbell ...temp=%x\n", temp); - if ( (temp & 0x0100) == 0) - { - //DEBUG("card_send_command: Message sent\n"); - } + ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL); + //DEBUG("card_send_command: read doorbell ...temp=%x\n", temp); + if ((temp & 0x0100) == 0) { + //DEBUG("card_send_command: Message sent\n"); + } } - //-------------------------------------------------------------------------- // // Function: dsp_reload -- cgit v1.2.3 From 3529bd416491d5ebb1acf10e679447b08ae8051c Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:17 +0100 Subject: staging: ft1000: Fix coding style in dsp_reload function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 57 ++++++++++++++------------- 1 file changed, 30 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index ded13f2f8326..53073d55e0da 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -534,49 +534,52 @@ void card_send_command(struct ft1000_device *ft1000dev, void *ptempbuffer, //----------------------------------------------------------------------- int dsp_reload(struct ft1000_device *ft1000dev) { - u16 status; - u16 tempword; - u32 templong; + u16 status; + u16 tempword; + u32 templong; struct ft1000_info *pft1000info; - pft1000info = netdev_priv(ft1000dev->net); + pft1000info = netdev_priv(ft1000dev->net); - pft1000info->CardReady = 0; + pft1000info->CardReady = 0; - // Program Interrupt Mask register - status = ft1000_write_register (ft1000dev, 0xffff, FT1000_REG_SUP_IMASK); + /* Program Interrupt Mask register */ + status = ft1000_write_register(ft1000dev, 0xffff, FT1000_REG_SUP_IMASK); - status = ft1000_read_register (ft1000dev, &tempword, FT1000_REG_RESET); - tempword |= ASIC_RESET_BIT; - status = ft1000_write_register (ft1000dev, tempword, FT1000_REG_RESET); - msleep(1000); - status = ft1000_read_register (ft1000dev, &tempword, FT1000_REG_RESET); - DEBUG("Reset Register = 0x%x\n", tempword); + status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_RESET); + tempword |= ASIC_RESET_BIT; + status = ft1000_write_register(ft1000dev, tempword, FT1000_REG_RESET); + msleep(1000); + status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_RESET); + DEBUG("Reset Register = 0x%x\n", tempword); - // Toggle DSP reset - card_reset_dsp (ft1000dev, 1); - msleep(1000); - card_reset_dsp (ft1000dev, 0); - msleep(1000); + /* Toggle DSP reset */ + card_reset_dsp(ft1000dev, 1); + msleep(1000); + card_reset_dsp(ft1000dev, 0); + msleep(1000); - status = ft1000_write_register (ft1000dev, HOST_INTF_BE, FT1000_REG_SUP_CTRL); + status = + ft1000_write_register(ft1000dev, HOST_INTF_BE, FT1000_REG_SUP_CTRL); - // Let's check for FEFE - status = ft1000_read_dpram32 (ft1000dev, FT1000_MAG_DPRAM_FEFE_INDX, (u8 *)&templong, 4); - DEBUG("templong (fefe) = 0x%8x\n", templong); + /* Let's check for FEFE */ + status = + ft1000_read_dpram32(ft1000dev, FT1000_MAG_DPRAM_FEFE_INDX, + (u8 *) &templong, 4); + DEBUG("templong (fefe) = 0x%8x\n", templong); - // call codeloader - status = scram_dnldr(ft1000dev, pFileStart, FileLength); + /* call codeloader */ + status = scram_dnldr(ft1000dev, pFileStart, FileLength); if (status != STATUS_SUCCESS) return -EIO; - msleep(1000); + msleep(1000); - DEBUG("dsp_reload returned\n"); - return 0; + DEBUG("dsp_reload returned\n"); + return 0; } //--------------------------------------------------------------------------- -- cgit v1.2.3 From 84a60963e259263446c81776067957cac52afbfb Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:18 +0100 Subject: staging: ft1000: Fix coding style in ft1000_reset_asic function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 37 ++++++++++++++------------- 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 53073d55e0da..188a8e3af2bd 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -593,32 +593,33 @@ int dsp_reload(struct ft1000_device *ft1000dev) // none // //--------------------------------------------------------------------------- -static void ft1000_reset_asic (struct net_device *dev) +static void ft1000_reset_asic(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); - struct ft1000_device *ft1000dev = info->pFt1000Dev; - u16 tempword; - - DEBUG("ft1000_hw:ft1000_reset_asic called\n"); + struct ft1000_device *ft1000dev = info->pFt1000Dev; + u16 tempword; - info->ASICResetNum++; + DEBUG("ft1000_hw:ft1000_reset_asic called\n"); - // Let's use the register provided by the Magnemite ASIC to reset the - // ASIC and DSP. - ft1000_write_register(ft1000dev, (DSP_RESET_BIT | ASIC_RESET_BIT), FT1000_REG_RESET ); + info->ASICResetNum++; - mdelay(1); + /* Let's use the register provided by the Magnemite ASIC to reset the + * ASIC and DSP. + */ + ft1000_write_register(ft1000dev, (DSP_RESET_BIT | ASIC_RESET_BIT), + FT1000_REG_RESET); - // set watermark to -1 in order to not generate an interrrupt - ft1000_write_register(ft1000dev, 0xffff, FT1000_REG_MAG_WATERMARK); + mdelay(1); - // clear interrupts - ft1000_read_register (ft1000dev, &tempword, FT1000_REG_SUP_ISR); - DEBUG("ft1000_hw: interrupt status register = 0x%x\n",tempword); - ft1000_write_register (ft1000dev, tempword, FT1000_REG_SUP_ISR); - ft1000_read_register (ft1000dev, &tempword, FT1000_REG_SUP_ISR); - DEBUG("ft1000_hw: interrupt status register = 0x%x\n",tempword); + /* set watermark to -1 in order to not generate an interrrupt */ + ft1000_write_register(ft1000dev, 0xffff, FT1000_REG_MAG_WATERMARK); + /* clear interrupts */ + ft1000_read_register(ft1000dev, &tempword, FT1000_REG_SUP_ISR); + DEBUG("ft1000_hw: interrupt status register = 0x%x\n", tempword); + ft1000_write_register(ft1000dev, tempword, FT1000_REG_SUP_ISR); + ft1000_read_register(ft1000dev, &tempword, FT1000_REG_SUP_ISR); + DEBUG("ft1000_hw: interrupt status register = 0x%x\n", tempword); } -- cgit v1.2.3 From 3071c12ea799db6d46ccb8ce42980e39c6e3447e Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:19 +0100 Subject: staging: ft1000: Fix coding style in ft1000_reset_card function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 65 +++++++++++++-------------- 1 file changed, 32 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 188a8e3af2bd..71c7c5d92a69 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -634,54 +634,53 @@ static void ft1000_reset_asic(struct net_device *dev) // TRUE (card reset successful) // //--------------------------------------------------------------------------- -static int ft1000_reset_card (struct net_device *dev) +static int ft1000_reset_card(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); - struct ft1000_device *ft1000dev = info->pFt1000Dev; - u16 tempword; + struct ft1000_device *ft1000dev = info->pFt1000Dev; + u16 tempword; struct prov_record *ptr; - DEBUG("ft1000_hw:ft1000_reset_card called.....\n"); - - info->fCondResetPend = 1; - info->CardReady = 0; - info->fProvComplete = 0; + DEBUG("ft1000_hw:ft1000_reset_card called.....\n"); - // Make sure we free any memory reserve for provisioning - while (list_empty(&info->prov_list) == 0) { - DEBUG("ft1000_hw:ft1000_reset_card:deleting provisioning record\n"); - ptr = list_entry(info->prov_list.next, struct prov_record, list); - list_del(&ptr->list); - kfree(ptr->pprov_data); - kfree(ptr); - } + info->fCondResetPend = 1; + info->CardReady = 0; + info->fProvComplete = 0; - DEBUG("ft1000_hw:ft1000_reset_card: reset asic\n"); - //reset ASIC - ft1000_reset_asic(dev); - - info->DSPResetNum++; + /* Make sure we free any memory reserve for provisioning */ + while (list_empty(&info->prov_list) == 0) { + DEBUG("ft1000_reset_card:deleting provisioning record\n"); + ptr = + list_entry(info->prov_list.next, struct prov_record, list); + list_del(&ptr->list); + kfree(ptr->pprov_data); + kfree(ptr); + } - DEBUG("ft1000_hw:ft1000_reset_card: call dsp_reload\n"); - dsp_reload(ft1000dev); + DEBUG("ft1000_hw:ft1000_reset_card: reset asic\n"); + ft1000_reset_asic(dev); - DEBUG("dsp reload successful\n"); + info->DSPResetNum++; + DEBUG("ft1000_hw:ft1000_reset_card: call dsp_reload\n"); + dsp_reload(ft1000dev); - mdelay(10); + DEBUG("dsp reload successful\n"); - // Initialize DSP heartbeat area to ho - ft1000_write_dpram16(ft1000dev, FT1000_MAG_HI_HO, ho_mag, FT1000_MAG_HI_HO_INDX); - ft1000_read_dpram16(ft1000dev, FT1000_MAG_HI_HO, (u8 *)&tempword, FT1000_MAG_HI_HO_INDX); - DEBUG("ft1000_hw:ft1000_reset_card:hi_ho value = 0x%x\n", tempword); + mdelay(10); + /* Initialize DSP heartbeat area */ + ft1000_write_dpram16(ft1000dev, FT1000_MAG_HI_HO, ho_mag, + FT1000_MAG_HI_HO_INDX); + ft1000_read_dpram16(ft1000dev, FT1000_MAG_HI_HO, (u8 *) &tempword, + FT1000_MAG_HI_HO_INDX); + DEBUG("ft1000_hw:ft1000_reset_card:hi_ho value = 0x%x\n", tempword); + info->CardReady = 1; - info->CardReady = 1; - - info->fCondResetPend = 0; - return TRUE; + info->fCondResetPend = 0; + return TRUE; } -- cgit v1.2.3 From cb3aa5d5b50670c4ee438fb855706538c0fd4bf6 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:20 +0100 Subject: staging: ft1000: Fix identation in ftnet_ops struct. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 71c7c5d92a69..bf2c729267dc 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -688,10 +688,10 @@ static int ft1000_reset_card(struct net_device *dev) #ifdef HAVE_NET_DEVICE_OPS static const struct net_device_ops ftnet_ops = { -.ndo_open = &ft1000_open, -.ndo_stop = &ft1000_close, -.ndo_start_xmit = &ft1000_start_xmit, -.ndo_get_stats = &ft1000_netdev_stats, + .ndo_open = &ft1000_open, + .ndo_stop = &ft1000_close, + .ndo_start_xmit = &ft1000_start_xmit, + .ndo_get_stats = &ft1000_netdev_stats, }; #endif -- cgit v1.2.3 From 6c284c7b06a18b6b77653a755b57e9e0d0451602 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:21 +0100 Subject: staging: ft1000: Fix coding style in init_ft1000_netdev function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 124 ++++++++++++-------------- 1 file changed, 56 insertions(+), 68 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index bf2c729267dc..adf16c6099c7 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -712,7 +712,7 @@ static const struct net_device_ops ftnet_ops = //--------------------------------------------------------------------------- u16 init_ft1000_netdev(struct ft1000_device *ft1000dev) { - struct net_device *netdev; + struct net_device *netdev; struct ft1000_info *pInfo = NULL; struct dpram_blk *pdpram_blk; int i, ret_val; @@ -720,27 +720,23 @@ u16 init_ft1000_netdev(struct ft1000_device *ft1000dev) char card_nr[2]; unsigned long gCardIndex = 0; - DEBUG("Enter init_ft1000_netdev...\n"); - + DEBUG("Enter init_ft1000_netdev...\n"); netdev = alloc_etherdev(sizeof(struct ft1000_info)); - if (!netdev ) - { - DEBUG("init_ft1000_netdev: can not allocate network device\n"); - return -ENOMEM; - } + if (!netdev) { + DEBUG("init_ft1000_netdev: can not allocate network device\n"); + return -ENOMEM; + } pInfo = netdev_priv(netdev); - //DEBUG("init_ft1000_netdev: gFt1000Info=%x, netdev=%x, ft1000dev=%x\n", gFt1000Info, netdev, ft1000dev); - memset(pInfo, 0, sizeof(struct ft1000_info)); - dev_alloc_name(netdev, netdev->name); + dev_alloc_name(netdev, netdev->name); - DEBUG("init_ft1000_netdev: network device name is %s\n", netdev->name); + DEBUG("init_ft1000_netdev: network device name is %s\n", netdev->name); - if ( strncmp(netdev->name,"eth", 3) == 0) { + if (strncmp(netdev->name, "eth", 3) == 0) { card_nr[0] = netdev->name[3]; card_nr[1] = '\0'; ret_val = strict_strtoul(card_nr, 10, &gCardIndex); @@ -749,89 +745,83 @@ u16 init_ft1000_netdev(struct ft1000_device *ft1000dev) goto err_net; } - pInfo->CardNumber = gCardIndex; - DEBUG("card number = %d\n", pInfo->CardNumber); - } - else { - printk(KERN_ERR "ft1000: Invalid device name\n"); + pInfo->CardNumber = gCardIndex; + DEBUG("card number = %d\n", pInfo->CardNumber); + } else { + printk(KERN_ERR "ft1000: Invalid device name\n"); ret_val = -ENXIO; goto err_net; - } + } - memset(&pInfo->stats, 0, sizeof(struct net_device_stats) ); - - spin_lock_init(&pInfo->dpram_lock); - pInfo->pFt1000Dev = ft1000dev; - pInfo->DrvErrNum = 0; - pInfo->ASICResetNum = 0; - pInfo->registered = 1; - pInfo->ft1000_reset = ft1000_reset; - pInfo->mediastate = 0; - pInfo->fifo_cnt = 0; - pInfo->DeviceCreated = FALSE; - pInfo->CurrentInterruptEnableMask = ISR_DEFAULT_MASK; - pInfo->InterruptsEnabled = FALSE; - pInfo->CardReady = 0; - pInfo->DSP_TIME[0] = 0; - pInfo->DSP_TIME[1] = 0; - pInfo->DSP_TIME[2] = 0; - pInfo->DSP_TIME[3] = 0; - pInfo->fAppMsgPend = 0; - pInfo->fCondResetPend = 0; + memset(&pInfo->stats, 0, sizeof(struct net_device_stats)); + + spin_lock_init(&pInfo->dpram_lock); + pInfo->pFt1000Dev = ft1000dev; + pInfo->DrvErrNum = 0; + pInfo->ASICResetNum = 0; + pInfo->registered = 1; + pInfo->ft1000_reset = ft1000_reset; + pInfo->mediastate = 0; + pInfo->fifo_cnt = 0; + pInfo->DeviceCreated = FALSE; + pInfo->CurrentInterruptEnableMask = ISR_DEFAULT_MASK; + pInfo->InterruptsEnabled = FALSE; + pInfo->CardReady = 0; + pInfo->DSP_TIME[0] = 0; + pInfo->DSP_TIME[1] = 0; + pInfo->DSP_TIME[2] = 0; + pInfo->DSP_TIME[3] = 0; + pInfo->fAppMsgPend = 0; + pInfo->fCondResetPend = 0; pInfo->usbboot = 0; pInfo->dspalive = 0; memset(&pInfo->tempbuf[0], 0, sizeof(pInfo->tempbuf)); - INIT_LIST_HEAD(&pInfo->prov_list); + INIT_LIST_HEAD(&pInfo->prov_list); INIT_LIST_HEAD(&pInfo->nodes.list); -//mbelian + #ifdef HAVE_NET_DEVICE_OPS netdev->netdev_ops = &ftnet_ops; #else - netdev->hard_start_xmit = &ft1000_start_xmit; - netdev->get_stats = &ft1000_netdev_stats; - netdev->open = &ft1000_open; - netdev->stop = &ft1000_close; + netdev->hard_start_xmit = &ft1000_start_xmit; + netdev->get_stats = &ft1000_netdev_stats; + netdev->open = &ft1000_open; + netdev->stop = &ft1000_close; #endif - ft1000dev->net = netdev; - - + ft1000dev->net = netdev; -//init free_buff_lock, freercvpool, numofmsgbuf, pdpram_blk -//only init once per card -//Jim - DEBUG("Initialize free_buff_lock and freercvpool\n"); - spin_lock_init(&free_buff_lock); + DEBUG("Initialize free_buff_lock and freercvpool\n"); + spin_lock_init(&free_buff_lock); - // initialize a list of buffers to be use for queuing up receive command data - INIT_LIST_HEAD (&freercvpool); + /* initialize a list of buffers to be use for queuing + * up receive command data + */ + INIT_LIST_HEAD(&freercvpool); - // create list of free buffers - for (i=0; ipbuffer = kmalloc ( MAX_CMD_SQSIZE, GFP_KERNEL ); + /* Get a block of memory to store command data */ + pdpram_blk->pbuffer = kmalloc(MAX_CMD_SQSIZE, GFP_KERNEL); if (pdpram_blk->pbuffer == NULL) { ret_val = -ENOMEM; kfree(pdpram_blk); goto err_free; } - // link provisioning data - list_add_tail (&pdpram_blk->list, &freercvpool); - } - numofmsgbuf = NUM_OF_FREE_BUFFERS; - + /* link provisioning data */ + list_add_tail(&pdpram_blk->list, &freercvpool); + } + numofmsgbuf = NUM_OF_FREE_BUFFERS; return 0; - err_free: list_for_each_safe(cur, tmp, &freercvpool) { pdpram_blk = list_entry(cur, struct dpram_blk, list); @@ -844,8 +834,6 @@ err_net: return ret_val; } - - //--------------------------------------------------------------------------- // Function: reg_ft1000_netdev // -- cgit v1.2.3 From f135da03597e8ff5a47ab3eff5aeaab2171d95ba Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:22 +0100 Subject: staging: ft1000: Change return value for init_ft1000_netdev function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 2 +- drivers/staging/ft1000/ft1000-usb/ft1000_usb.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index adf16c6099c7..55998ec059f6 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -710,7 +710,7 @@ static const struct net_device_ops ftnet_ops = // Notes: // //--------------------------------------------------------------------------- -u16 init_ft1000_netdev(struct ft1000_device *ft1000dev) +int init_ft1000_netdev(struct ft1000_device *ft1000dev) { struct net_device *netdev; struct ft1000_info *pInfo = NULL; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index 84ff53d2e2c9..e047c03fbf3a 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -589,7 +589,7 @@ void ft1000_free_buffer(struct dpram_blk *pdpram_blk, struct list_head *plist); char *getfw (char *fn, size_t *pimgsz); int dsp_reload(struct ft1000_device *ft1000dev); -u16 init_ft1000_netdev(struct ft1000_device *ft1000dev); +int init_ft1000_netdev(struct ft1000_device *ft1000dev); struct usb_interface; int reg_ft1000_netdev(struct ft1000_device *ft1000dev, struct usb_interface *intf); int ft1000_poll(void* dev_id); -- cgit v1.2.3 From 05a7c39c36cdfb68ddbfc417bd461755ec32e258 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:23 +0100 Subject: staging: ft1000: Fix coding style in reg_ft1000_netdev function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 40 ++++++++++++--------------- 1 file changed, 18 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 55998ec059f6..0b8ff3d87c16 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -848,38 +848,34 @@ err_net: // Notes: // //--------------------------------------------------------------------------- -int reg_ft1000_netdev(struct ft1000_device *ft1000dev, struct usb_interface *intf) +int reg_ft1000_netdev(struct ft1000_device *ft1000dev, + struct usb_interface *intf) { - struct net_device *netdev; + struct net_device *netdev; struct ft1000_info *pInfo; int rc; - netdev = ft1000dev->net; - pInfo = netdev_priv(ft1000dev->net); - DEBUG("Enter reg_ft1000_netdev...\n"); - + netdev = ft1000dev->net; + pInfo = netdev_priv(ft1000dev->net); + DEBUG("Enter reg_ft1000_netdev...\n"); - ft1000_read_register(ft1000dev, &pInfo->AsicID, FT1000_REG_ASIC_ID); + ft1000_read_register(ft1000dev, &pInfo->AsicID, FT1000_REG_ASIC_ID); - usb_set_intfdata(intf, pInfo); - SET_NETDEV_DEV(netdev, &intf->dev); + usb_set_intfdata(intf, pInfo); + SET_NETDEV_DEV(netdev, &intf->dev); - rc = register_netdev(netdev); - if (rc) - { - DEBUG("reg_ft1000_netdev: could not register network device\n"); - free_netdev(netdev); - return rc; - } - - - //Create character device, implemented by Jim - ft1000_create_dev(ft1000dev); + rc = register_netdev(netdev); + if (rc) { + DEBUG("reg_ft1000_netdev: could not register network device\n"); + free_netdev(netdev); + return rc; + } - DEBUG ("reg_ft1000_netdev returned\n"); + ft1000_create_dev(ft1000dev); - pInfo->CardReady = 1; + DEBUG("reg_ft1000_netdev returned\n"); + pInfo->CardReady = 1; return 0; } -- cgit v1.2.3 From 2dd9017b47bb932d0f6c9a9e529b55b106ad0bd2 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:24 +0100 Subject: staging: ft1000: Fix coding style in ft1000_reset function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 0b8ff3d87c16..4c5f443121a8 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -882,8 +882,8 @@ int reg_ft1000_netdev(struct ft1000_device *ft1000dev, static int ft1000_reset(struct net_device *dev) { - ft1000_reset_card(dev); - return 0; + ft1000_reset_card(dev); + return 0; } //--------------------------------------------------------------------------- -- cgit v1.2.3 From 251c72f84ae300465c7b5ca5688b51f392ee646f Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:25 +0100 Subject: staging: ft1000: Fix coding style in ft1000_usb_transmit_complete function. Fix coding style and also replace printk with proper pr_err function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 4c5f443121a8..958292e8178a 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -902,14 +902,14 @@ static int ft1000_reset(struct net_device *dev) static void ft1000_usb_transmit_complete(struct urb *urb) { - struct ft1000_device *ft1000dev = urb->context; + struct ft1000_device *ft1000dev = urb->context; //DEBUG("ft1000_usb_transmit_complete entered\n"); - if (urb->status) - printk("%s: TX status %d\n", ft1000dev->net->name, urb->status); + if (urb->status) + pr_err("%s: TX status %d\n", ft1000dev->net->name, urb->status); - netif_wake_queue(ft1000dev->net); + netif_wake_queue(ft1000dev->net); //DEBUG("Return from ft1000_usb_transmit_complete\n"); } -- cgit v1.2.3 From d8dfaf4c94de533cffe9637cd14f9a0e39ad23ad Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:26 +0100 Subject: staging: ft1000: Fix coding style in ft1000_copy_down_pkt function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 75 ++++++++++++--------------- 1 file changed, 34 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 958292e8178a..bb1e9d695c27 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -929,37 +929,31 @@ static void ft1000_usb_transmit_complete(struct urb *urb) // SUCCESS // //--------------------------------------------------------------------------- -static int ft1000_copy_down_pkt (struct net_device *netdev, u8 *packet, u16 len) +static int ft1000_copy_down_pkt(struct net_device *netdev, u8 * packet, u16 len) { struct ft1000_info *pInfo = netdev_priv(netdev); - struct ft1000_device *pFt1000Dev = pInfo->pFt1000Dev; - + struct ft1000_device *pFt1000Dev = pInfo->pFt1000Dev; int count, ret; - u8 *t; + u8 *t; struct pseudo_hdr hdr; - if (!pInfo->CardReady) - { - - DEBUG("ft1000_copy_down_pkt::Card Not Ready\n"); - return -ENODEV; - - } - + if (!pInfo->CardReady) { + DEBUG("ft1000_copy_down_pkt::Card Not Ready\n"); + return -ENODEV; + } - //DEBUG("ft1000_copy_down_pkt() entered, len = %d\n", len); + //DEBUG("ft1000_copy_down_pkt() entered, len = %d\n", len); count = sizeof(struct pseudo_hdr) + len; - if(count > MAX_BUF_SIZE) - { - DEBUG("Error:ft1000_copy_down_pkt:Message Size Overflow!\n"); - DEBUG("size = %d\n", count); - return -EINVAL; - } + if (count > MAX_BUF_SIZE) { + DEBUG("Error:ft1000_copy_down_pkt:Message Size Overflow!\n"); + DEBUG("size = %d\n", count); + return -EINVAL; + } - if ( count % 4) - count = count + (4- (count %4) ); + if (count % 4) + count = count + (4 - (count % 4)); memset(&hdr, 0, sizeof(struct pseudo_hdr)); @@ -972,46 +966,45 @@ static int ft1000_copy_down_pkt (struct net_device *netdev, u8 *packet, u16 len) hdr.control = 0x00; hdr.checksum = hdr.length ^ hdr.source ^ hdr.destination ^ - hdr.portdest ^ hdr.portsrc ^ hdr.sh_str_id ^ - hdr.control; + hdr.portdest ^ hdr.portsrc ^ hdr.sh_str_id ^ hdr.control; memcpy(&pFt1000Dev->tx_buf[0], &hdr, sizeof(hdr)); memcpy(&(pFt1000Dev->tx_buf[sizeof(struct pseudo_hdr)]), packet, len); - netif_stop_queue(netdev); - - //DEBUG ("ft1000_copy_down_pkt: count = %d\n", count); + netif_stop_queue(netdev); - usb_fill_bulk_urb(pFt1000Dev->tx_urb, - pFt1000Dev->dev, - usb_sndbulkpipe(pFt1000Dev->dev, pFt1000Dev->bulk_out_endpointAddr), - pFt1000Dev->tx_buf, - count, - ft1000_usb_transmit_complete, - (void*)pFt1000Dev); + //DEBUG ("ft1000_copy_down_pkt: count = %d\n", count); - t = (u8 *)pFt1000Dev->tx_urb->transfer_buffer; - //DEBUG("transfer_length=%d\n", pFt1000Dev->tx_urb->transfer_buffer_length); - /*for (i=0; itx_urb, + pFt1000Dev->dev, + usb_sndbulkpipe(pFt1000Dev->dev, + pFt1000Dev->bulk_out_endpointAddr), + pFt1000Dev->tx_buf, count, + ft1000_usb_transmit_complete, (void *)pFt1000Dev); + t = (u8 *) pFt1000Dev->tx_urb->transfer_buffer; + //DEBUG("transfer_length=%d\n", pFt1000Dev->tx_urb->transfer_buffer_length); + /*for (i=0; itx_urb, GFP_ATOMIC); + if (ret) { DEBUG("ft1000 failed tx_urb %d\n", ret); return ret; } else { pInfo->stats.tx_packets++; - pInfo->stats.tx_bytes += (len+14); + pInfo->stats.tx_bytes += (len + 14); } - //DEBUG("ft1000_copy_down_pkt() exit\n"); + //DEBUG("ft1000_copy_down_pkt() exit\n"); return 0; } + //--------------------------------------------------------------------------- // Function: ft1000_start_xmit // -- cgit v1.2.3 From e31e33855ad9025f25b834305716307801a3d88c Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:27 +0100 Subject: staging: ft1000: Fix coding style in ft1000_start_xmit function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 81 +++++++++++++-------------- 1 file changed, 38 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index bb1e9d695c27..63ee38c308c0 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1022,61 +1022,56 @@ static int ft1000_copy_down_pkt(struct net_device *netdev, u8 * packet, u16 len) static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ft1000_info *pInfo = netdev_priv(dev); - struct ft1000_device *pFt1000Dev= pInfo->pFt1000Dev; - u8 *pdata; - int maxlen, pipe; - - - //DEBUG(" ft1000_start_xmit() entered\n"); - - if ( skb == NULL ) - { - DEBUG ("ft1000_hw: ft1000_start_xmit:skb == NULL!!!\n" ); - return NETDEV_TX_OK; - } - - if ( pFt1000Dev->status & FT1000_STATUS_CLOSING) - { - DEBUG("network driver is closed, return\n"); - goto err; - } - - //DEBUG("ft1000_start_xmit 1:length of packet = %d\n", skb->len); - pipe = usb_sndbulkpipe(pFt1000Dev->dev, pFt1000Dev->bulk_out_endpointAddr); - maxlen = usb_maxpacket(pFt1000Dev->dev, pipe, usb_pipeout(pipe)); - //DEBUG("ft1000_start_xmit 2: pipe=%d dev->maxpacket = %d\n", pipe, maxlen); - - pdata = (u8 *)skb->data; - /*for (i=0; ilen; i++) - DEBUG("skb->data[%d]=%x ", i, *(skb->data+i)); + struct ft1000_device *pFt1000Dev = pInfo->pFt1000Dev; + u8 *pdata; + int maxlen, pipe; - DEBUG("\n");*/ + //DEBUG(" ft1000_start_xmit() entered\n"); + if (skb == NULL) { + DEBUG("ft1000_hw: ft1000_start_xmit:skb == NULL!!!\n"); + return NETDEV_TX_OK; + } - if (pInfo->mediastate == 0) - { - /* Drop packet is mediastate is down */ - DEBUG("ft1000_hw:ft1000_start_xmit:mediastate is down\n"); - goto err; - } + if (pFt1000Dev->status & FT1000_STATUS_CLOSING) { + DEBUG("network driver is closed, return\n"); + goto err; + } + //DEBUG("ft1000_start_xmit 1:length of packet = %d\n", skb->len); + pipe = + usb_sndbulkpipe(pFt1000Dev->dev, pFt1000Dev->bulk_out_endpointAddr); + maxlen = usb_maxpacket(pFt1000Dev->dev, pipe, usb_pipeout(pipe)); + //DEBUG("ft1000_start_xmit 2: pipe=%d dev->maxpacket = %d\n", pipe, maxlen); + + pdata = (u8 *) skb->data; + /*for (i=0; ilen; i++) + DEBUG("skb->data[%d]=%x ", i, *(skb->data+i)); + + DEBUG("\n"); */ + + if (pInfo->mediastate == 0) { + /* Drop packet is mediastate is down */ + DEBUG("ft1000_hw:ft1000_start_xmit:mediastate is down\n"); + goto err; + } - if ( (skb->len < ENET_HEADER_SIZE) || (skb->len > ENET_MAX_SIZE) ) - { - /* Drop packet which has invalid size */ - DEBUG("ft1000_hw:ft1000_start_xmit:invalid ethernet length\n"); - goto err; - } + if ((skb->len < ENET_HEADER_SIZE) || (skb->len > ENET_MAX_SIZE)) { + /* Drop packet which has invalid size */ + DEBUG("ft1000_hw:ft1000_start_xmit:invalid ethernet length\n"); + goto err; + } //mbelian - ft1000_copy_down_pkt(dev, (pdata+ENET_HEADER_SIZE-2), - skb->len - ENET_HEADER_SIZE + 2); + ft1000_copy_down_pkt(dev, (pdata + ENET_HEADER_SIZE - 2), + skb->len - ENET_HEADER_SIZE + 2); err: dev_kfree_skb(skb); - //DEBUG(" ft1000_start_xmit() exit\n"); + //DEBUG(" ft1000_start_xmit() exit\n"); return NETDEV_TX_OK; } + //--------------------------------------------------------------------------- // // Function: ft1000_copy_up_pkt -- cgit v1.2.3 From 6b2a66f2500b69a1627c50b953ce301c19b24d56 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:28 +0100 Subject: staging: ft1000: Fix coding style in ft1000_submit_rx_urb function. Fix coding style and also replace printk with proper pr_err function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 46 +++++++++++++-------------- 1 file changed, 22 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 63ee38c308c0..f07b3ed60d26 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1203,38 +1203,36 @@ static int ft1000_copy_up_pkt (struct urb *urb) //--------------------------------------------------------------------------- static int ft1000_submit_rx_urb(struct ft1000_info *info) { - int result; - struct ft1000_device *pFt1000Dev = info->pFt1000Dev; + int result; + struct ft1000_device *pFt1000Dev = info->pFt1000Dev; + //DEBUG ("ft1000_submit_rx_urb entered: sizeof rx_urb is %d\n", sizeof(*pFt1000Dev->rx_urb)); + if (pFt1000Dev->status & FT1000_STATUS_CLOSING) { + DEBUG("network driver is closed, return\n"); + //usb_kill_urb(pFt1000Dev->rx_urb); //mbelian + return -ENODEV; + } - //DEBUG ("ft1000_submit_rx_urb entered: sizeof rx_urb is %d\n", sizeof(*pFt1000Dev->rx_urb)); - if ( pFt1000Dev->status & FT1000_STATUS_CLOSING) - { - DEBUG("network driver is closed, return\n"); - //usb_kill_urb(pFt1000Dev->rx_urb); //mbelian - return -ENODEV; - } - - usb_fill_bulk_urb(pFt1000Dev->rx_urb, - pFt1000Dev->dev, - usb_rcvbulkpipe(pFt1000Dev->dev, pFt1000Dev->bulk_in_endpointAddr), - pFt1000Dev->rx_buf, - MAX_BUF_SIZE, - (usb_complete_t)ft1000_copy_up_pkt, - info); - + usb_fill_bulk_urb(pFt1000Dev->rx_urb, + pFt1000Dev->dev, + usb_rcvbulkpipe(pFt1000Dev->dev, + pFt1000Dev->bulk_in_endpointAddr), + pFt1000Dev->rx_buf, MAX_BUF_SIZE, + (usb_complete_t) ft1000_copy_up_pkt, info); - if((result = usb_submit_urb(pFt1000Dev->rx_urb, GFP_ATOMIC))) - { - printk("ft1000_submit_rx_urb: submitting rx_urb %d failed\n", result); - return result; - } + result = usb_submit_urb(pFt1000Dev->rx_urb, GFP_ATOMIC); - //DEBUG("ft1000_submit_rx_urb exit: result=%d\n", result); + if (result) { + pr_err("ft1000_submit_rx_urb: submitting rx_urb %d failed\n", + result); + return result; + } + //DEBUG("ft1000_submit_rx_urb exit: result=%d\n", result); return 0; } + //--------------------------------------------------------------------------- // Function: ft1000_open // -- cgit v1.2.3 From bee1b21cfac6c415563e4643826b9d8b9b31b6f8 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:29 +0100 Subject: staging: ft1000: Fix coding style in ft1000_copy_up_pkt function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 167 ++++++++++++-------------- 1 file changed, 79 insertions(+), 88 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index f07b3ed60d26..6a9e5fad4142 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1085,109 +1085,100 @@ err: // SUCCESS // //--------------------------------------------------------------------------- -static int ft1000_copy_up_pkt (struct urb *urb) +static int ft1000_copy_up_pkt(struct urb *urb) { struct ft1000_info *info = urb->context; - struct ft1000_device *ft1000dev = info->pFt1000Dev; - struct net_device *net = ft1000dev->net; - - u16 tempword; - u16 len; - u16 lena; //mbelian - struct sk_buff *skb; - u16 i; - u8 *pbuffer=NULL; - u8 *ptemp=NULL; - u16 *chksum; - - - //DEBUG("ft1000_copy_up_pkt entered\n"); - - if ( ft1000dev->status & FT1000_STATUS_CLOSING) - { - DEBUG("network driver is closed, return\n"); - return STATUS_SUCCESS; - } - - // Read length - len = urb->transfer_buffer_length; - lena = urb->actual_length; //mbelian - //DEBUG("ft1000_copy_up_pkt: transfer_buffer_length=%d, actual_buffer_len=%d\n", - // urb->transfer_buffer_length, urb->actual_length); - - chksum = (u16 *)ft1000dev->rx_buf; - - tempword = *chksum++; - for (i=1; i<7; i++) - { - tempword ^= *chksum++; - } - - if (tempword != *chksum) - { - info->stats.rx_errors ++; - ft1000_submit_rx_urb(info); - return STATUS_FAILURE; - } - - - //DEBUG("ft1000_copy_up_pkt: checksum is correct %x\n", *chksum); - - skb = dev_alloc_skb(len+12+2); - - if (skb == NULL) - { - DEBUG("ft1000_copy_up_pkt: No Network buffers available\n"); - info->stats.rx_errors++; - ft1000_submit_rx_urb(info); - return STATUS_FAILURE; - } - - pbuffer = (u8 *)skb_put(skb, len+12); + struct ft1000_device *ft1000dev = info->pFt1000Dev; + struct net_device *net = ft1000dev->net; - //subtract the number of bytes read already - ptemp = pbuffer; + u16 tempword; + u16 len; + u16 lena; //mbelian + struct sk_buff *skb; + u16 i; + u8 *pbuffer = NULL; + u8 *ptemp = NULL; + u16 *chksum; - // fake MAC address - *pbuffer++ = net->dev_addr[0]; - *pbuffer++ = net->dev_addr[1]; - *pbuffer++ = net->dev_addr[2]; - *pbuffer++ = net->dev_addr[3]; - *pbuffer++ = net->dev_addr[4]; - *pbuffer++ = net->dev_addr[5]; - *pbuffer++ = 0x00; - *pbuffer++ = 0x07; - *pbuffer++ = 0x35; - *pbuffer++ = 0xff; - *pbuffer++ = 0xff; - *pbuffer++ = 0xfe; + //DEBUG("ft1000_copy_up_pkt entered\n"); + if (ft1000dev->status & FT1000_STATUS_CLOSING) { + DEBUG("network driver is closed, return\n"); + return STATUS_SUCCESS; + } + // Read length + len = urb->transfer_buffer_length; + lena = urb->actual_length; //mbelian + //DEBUG("ft1000_copy_up_pkt: transfer_buffer_length=%d, actual_buffer_len=%d\n", + // urb->transfer_buffer_length, urb->actual_length); + + chksum = (u16 *) ft1000dev->rx_buf; + + tempword = *chksum++; + for (i = 1; i < 7; i++) + tempword ^= *chksum++; + + if (tempword != *chksum) { + info->stats.rx_errors++; + ft1000_submit_rx_urb(info); + return STATUS_FAILURE; + } + //DEBUG("ft1000_copy_up_pkt: checksum is correct %x\n", *chksum); + skb = dev_alloc_skb(len + 12 + 2); - memcpy(pbuffer, ft1000dev->rx_buf+sizeof(struct pseudo_hdr), len-sizeof(struct pseudo_hdr)); + if (skb == NULL) { + DEBUG("ft1000_copy_up_pkt: No Network buffers available\n"); + info->stats.rx_errors++; + ft1000_submit_rx_urb(info); + return STATUS_FAILURE; + } - //DEBUG("ft1000_copy_up_pkt: Data passed to Protocol layer\n"); - /*for (i=0; idev_addr[0]; + *pbuffer++ = net->dev_addr[1]; + *pbuffer++ = net->dev_addr[2]; + *pbuffer++ = net->dev_addr[3]; + *pbuffer++ = net->dev_addr[4]; + *pbuffer++ = net->dev_addr[5]; + *pbuffer++ = 0x00; + *pbuffer++ = 0x07; + *pbuffer++ = 0x35; + *pbuffer++ = 0xff; + *pbuffer++ = 0xff; + *pbuffer++ = 0xfe; + + memcpy(pbuffer, ft1000dev->rx_buf + sizeof(struct pseudo_hdr), + len - sizeof(struct pseudo_hdr)); + + //DEBUG("ft1000_copy_up_pkt: Data passed to Protocol layer\n"); + /*for (i=0; idev = net; + skb->dev = net; - skb->protocol = eth_type_trans(skb, net); - skb->ip_summed = CHECKSUM_UNNECESSARY; - netif_rx(skb); + skb->protocol = eth_type_trans(skb, net); + skb->ip_summed = CHECKSUM_UNNECESSARY; + netif_rx(skb); - info->stats.rx_packets++; - // Add on 12 bytes for MAC address which was removed - info->stats.rx_bytes += (lena+12); //mbelian + info->stats.rx_packets++; + /* Add on 12 bytes for MAC address which was removed */ + info->stats.rx_bytes += (lena + 12); //mbelian - ft1000_submit_rx_urb(info); - //DEBUG("ft1000_copy_up_pkt exited\n"); - return SUCCESS; + ft1000_submit_rx_urb(info); + //DEBUG("ft1000_copy_up_pkt exited\n"); + return SUCCESS; } + //--------------------------------------------------------------------------- // // Function: ft1000_submit_rx_urb -- cgit v1.2.3 From a01ffcd69f4987f64e02151575743d756eb4e4d2 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:30 +0100 Subject: staging: ft1000: Fix coding style in ft1000_open function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 6a9e5fad4142..b57863048807 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1238,27 +1238,26 @@ static int ft1000_submit_rx_urb(struct ft1000_info *info) // Notes: // //--------------------------------------------------------------------------- -static int ft1000_open (struct net_device *dev) +static int ft1000_open(struct net_device *dev) { struct ft1000_info *pInfo = netdev_priv(dev); - struct timeval tv; //mbelian + struct timeval tv; //mbelian int ret; - DEBUG("ft1000_open is called for card %d\n", pInfo->CardNumber); - //DEBUG("ft1000_open: dev->addr=%x, dev->addr_len=%d\n", dev->addr, dev->addr_len); + DEBUG("ft1000_open is called for card %d\n", pInfo->CardNumber); + //DEBUG("ft1000_open: dev->addr=%x, dev->addr_len=%d\n", dev->addr, dev->addr_len); - pInfo->stats.rx_bytes = 0; //mbelian - pInfo->stats.tx_bytes = 0; //mbelian - pInfo->stats.rx_packets = 0; //mbelian - pInfo->stats.tx_packets = 0; //mbelian + pInfo->stats.rx_bytes = 0; //mbelian + pInfo->stats.tx_bytes = 0; //mbelian + pInfo->stats.rx_packets = 0; //mbelian + pInfo->stats.tx_packets = 0; //mbelian do_gettimeofday(&tv); - pInfo->ConTm = tv.tv_sec; - pInfo->ProgConStat = 0; //mbelian + pInfo->ConTm = tv.tv_sec; + pInfo->ProgConStat = 0; //mbelian + netif_start_queue(dev); - netif_start_queue(dev); - - netif_carrier_on(dev); //mbelian + netif_carrier_on(dev); //mbelian ret = ft1000_submit_rx_urb(pInfo); -- cgit v1.2.3 From a007e842af9cb06279f9a535c1de0c59cfa65742 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:31 +0100 Subject: staging: ft1000: Fix coding style in ft1000_close function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index b57863048807..8f38b08f0965 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1281,24 +1281,23 @@ static int ft1000_open(struct net_device *dev) int ft1000_close(struct net_device *net) { struct ft1000_info *pInfo = netdev_priv(net); - struct ft1000_device *ft1000dev = pInfo->pFt1000Dev; + struct ft1000_device *ft1000dev = pInfo->pFt1000Dev; - //DEBUG ("ft1000_close: netdev->refcnt=%d\n", net->refcnt); + //DEBUG ("ft1000_close: netdev->refcnt=%d\n", net->refcnt); - ft1000dev->status |= FT1000_STATUS_CLOSING; - - //DEBUG("ft1000_close: calling usb_kill_urb \n"); + ft1000dev->status |= FT1000_STATUS_CLOSING; - DEBUG("ft1000_close: pInfo=%p, ft1000dev=%p\n", pInfo, ft1000dev); - netif_carrier_off(net);//mbelian - netif_stop_queue(net); - //DEBUG("ft1000_close: netif_stop_queue called\n"); - ft1000dev->status &= ~FT1000_STATUS_CLOSING; + //DEBUG("ft1000_close: calling usb_kill_urb \n"); - pInfo->ProgConStat = 0xff; //mbelian + DEBUG("ft1000_close: pInfo=%p, ft1000dev=%p\n", pInfo, ft1000dev); + netif_carrier_off(net); //mbelian + netif_stop_queue(net); + //DEBUG("ft1000_close: netif_stop_queue called\n"); + ft1000dev->status &= ~FT1000_STATUS_CLOSING; + pInfo->ProgConStat = 0xff; //mbelian - return 0; + return 0; } static struct net_device_stats *ft1000_netdev_stats(struct net_device *dev) -- cgit v1.2.3 From 53cd3aa6194cf0f2970dd85e51b64e915e6ba99c Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:32 +0100 Subject: staging: ft1000: Fix coding style in ft1000_chkcard function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 61 ++++++++++++++------------- 1 file changed, 31 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 8f38b08f0965..3f70283d6ece 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1325,40 +1325,41 @@ Jim // TRUE (device is present) // //--------------------------------------------------------------------------- -static int ft1000_chkcard (struct ft1000_device *dev) { - u16 tempword; - u16 status; +static int ft1000_chkcard(struct ft1000_device *dev) +{ + u16 tempword; + u16 status; struct ft1000_info *info = netdev_priv(dev->net); - if (info->fCondResetPend) - { - DEBUG("ft1000_hw:ft1000_chkcard:Card is being reset, return FALSE\n"); - return TRUE; - } - - // Mask register is used to check for device presence since it is never - // set to zero. - status = ft1000_read_register(dev, &tempword, FT1000_REG_SUP_IMASK); - //DEBUG("ft1000_hw:ft1000_chkcard: read FT1000_REG_SUP_IMASK = %x\n", tempword); - if (tempword == 0) { - DEBUG("ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n"); - return FALSE; - } - - // The system will return the value of 0xffff for the version register - // if the device is not present. - status = ft1000_read_register(dev, &tempword, FT1000_REG_ASIC_ID); - //DEBUG("ft1000_hw:ft1000_chkcard: read FT1000_REG_ASIC_ID = %x\n", tempword); - if (tempword != 0x1b01 ){ - dev->status |= FT1000_STATUS_CLOSING; //mbelian - DEBUG("ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n"); - return FALSE; - } - return TRUE; + if (info->fCondResetPend) { + DEBUG + ("ft1000_hw:ft1000_chkcard:Card is being reset, return FALSE\n"); + return TRUE; + } + /* Mask register is used to check for device presence since it is never + * set to zero. + */ + status = ft1000_read_register(dev, &tempword, FT1000_REG_SUP_IMASK); + //DEBUG("ft1000_hw:ft1000_chkcard: read FT1000_REG_SUP_IMASK = %x\n", tempword); + if (tempword == 0) { + DEBUG + ("ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n"); + return FALSE; + } + /* The system will return the value of 0xffff for the version register + * if the device is not present. + */ + status = ft1000_read_register(dev, &tempword, FT1000_REG_ASIC_ID); + //DEBUG("ft1000_hw:ft1000_chkcard: read FT1000_REG_ASIC_ID = %x\n", tempword); + if (tempword != 0x1b01) { + dev->status |= FT1000_STATUS_CLOSING; //mbelian + DEBUG + ("ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n"); + return FALSE; + } + return TRUE; } - - //--------------------------------------------------------------------------- // // Function: ft1000_receive_cmd -- cgit v1.2.3 From 8b2dab1cf8dec78aecaf1b4cf65fb316562699ca Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:33 +0100 Subject: staging: ft1000: Fix coding style in ft1000_receive_cmd function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 108 +++++++++++++++----------- 1 file changed, 61 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 3f70283d6ece..f1b4ce15daa4 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1373,56 +1373,70 @@ static int ft1000_chkcard(struct ft1000_device *dev) // = 1 (successful) // //--------------------------------------------------------------------------- -static bool ft1000_receive_cmd (struct ft1000_device *dev, u16 *pbuffer, int maxsz, u16 *pnxtph) { - u16 size, ret; - u16 *ppseudohdr; - int i; - u16 tempword; +static bool ft1000_receive_cmd(struct ft1000_device *dev, u16 *pbuffer, + int maxsz, u16 *pnxtph) +{ + u16 size, ret; + u16 *ppseudohdr; + int i; + u16 tempword; - ret = ft1000_read_dpram16(dev, FT1000_MAG_PH_LEN, (u8 *)&size, FT1000_MAG_PH_LEN_INDX); - size = ntohs(size) + PSEUDOSZ; - if (size > maxsz) { - DEBUG("FT1000:ft1000_receive_cmd:Invalid command length = %d\n", size); - return FALSE; - } - else { - ppseudohdr = (u16 *)pbuffer; - ft1000_write_register(dev, FT1000_DPRAM_MAG_RX_BASE, FT1000_REG_DPRAM_ADDR); - ret = ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH); - //DEBUG("ft1000_hw:received data = 0x%x\n", *pbuffer); - pbuffer++; - ft1000_write_register(dev, FT1000_DPRAM_MAG_RX_BASE+1, FT1000_REG_DPRAM_ADDR); - for (i=0; i<=(size>>2); i++) { - ret = ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAL); - pbuffer++; - ret = ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH); - pbuffer++; - } - //copy odd aligned word - ret = ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAL); - //DEBUG("ft1000_hw:received data = 0x%x\n", *pbuffer); - pbuffer++; - ret = ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH); - //DEBUG("ft1000_hw:received data = 0x%x\n", *pbuffer); - pbuffer++; - if (size & 0x0001) { - //copy odd byte from fifo - ret = ft1000_read_register(dev, &tempword, FT1000_REG_DPRAM_DATA); - *pbuffer = ntohs(tempword); - } + ret = + ft1000_read_dpram16(dev, FT1000_MAG_PH_LEN, (u8 *) &size, + FT1000_MAG_PH_LEN_INDX); + size = ntohs(size) + PSEUDOSZ; + if (size > maxsz) { + DEBUG("FT1000:ft1000_receive_cmd:Invalid command length = %d\n", + size); + return FALSE; + } else { + ppseudohdr = (u16 *) pbuffer; + ft1000_write_register(dev, FT1000_DPRAM_MAG_RX_BASE, + FT1000_REG_DPRAM_ADDR); + ret = + ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH); + //DEBUG("ft1000_hw:received data = 0x%x\n", *pbuffer); + pbuffer++; + ft1000_write_register(dev, FT1000_DPRAM_MAG_RX_BASE + 1, + FT1000_REG_DPRAM_ADDR); + for (i = 0; i <= (size >> 2); i++) { + ret = + ft1000_read_register(dev, pbuffer, + FT1000_REG_MAG_DPDATAL); + pbuffer++; + ret = + ft1000_read_register(dev, pbuffer, + FT1000_REG_MAG_DPDATAH); + pbuffer++; + } + /* copy odd aligned word */ + ret = + ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAL); + //DEBUG("ft1000_hw:received data = 0x%x\n", *pbuffer); + pbuffer++; + ret = + ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH); + //DEBUG("ft1000_hw:received data = 0x%x\n", *pbuffer); + pbuffer++; + if (size & 0x0001) { + /* copy odd byte from fifo */ + ret = + ft1000_read_register(dev, &tempword, + FT1000_REG_DPRAM_DATA); + *pbuffer = ntohs(tempword); + } + /* Check if pseudo header checksum is good + * Calculate pseudo header checksum + */ + tempword = *ppseudohdr++; + for (i = 1; i < 7; i++) + tempword ^= *ppseudohdr++; - // Check if pseudo header checksum is good - // Calculate pseudo header checksum - tempword = *ppseudohdr++; - for (i=1; i<7; i++) { - tempword ^= *ppseudohdr++; - } - if ( (tempword != *ppseudohdr) ) { - return FALSE; - } + if ((tempword != *ppseudohdr)) + return FALSE; - return TRUE; - } + return TRUE; + } } -- cgit v1.2.3 From fc796a6502de4c146bf3893390cca43df2d0e539 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:34 +0100 Subject: staging: ft1000: Fix coding style in ft1000_dsp_prov function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 141 +++++++++++++------------- 1 file changed, 73 insertions(+), 68 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index f1b4ce15daa4..01877581a574 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1439,92 +1439,97 @@ static bool ft1000_receive_cmd(struct ft1000_device *dev, u16 *pbuffer, } } - static int ft1000_dsp_prov(void *arg) { - struct ft1000_device *dev = (struct ft1000_device *)arg; + struct ft1000_device *dev = (struct ft1000_device *)arg; struct ft1000_info *info = netdev_priv(dev->net); - u16 tempword; - u16 len; - u16 i=0; + u16 tempword; + u16 len; + u16 i = 0; struct prov_record *ptr; struct pseudo_hdr *ppseudo_hdr; - u16 *pmsg; - u16 status; - u16 TempShortBuf [256]; + u16 *pmsg; + u16 status; + u16 TempShortBuf[256]; - DEBUG("*** DspProv Entered\n"); + DEBUG("*** DspProv Entered\n"); - while (list_empty(&info->prov_list) == 0) - { - DEBUG("DSP Provisioning List Entry\n"); - - // Check if doorbell is available - DEBUG("check if doorbell is cleared\n"); - status = ft1000_read_register (dev, &tempword, FT1000_REG_DOORBELL); - if (status) - { - DEBUG("ft1000_dsp_prov::ft1000_read_register error\n"); - break; - } + while (list_empty(&info->prov_list) == 0) { + DEBUG("DSP Provisioning List Entry\n"); + + /* Check if doorbell is available */ + DEBUG("check if doorbell is cleared\n"); + status = + ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL); + if (status) { + DEBUG("ft1000_dsp_prov::ft1000_read_register error\n"); + break; + } - while (tempword & FT1000_DB_DPRAM_TX) { - mdelay(10); - i++; - if (i==10) { - DEBUG("FT1000:ft1000_dsp_prov:message drop\n"); - return STATUS_FAILURE; - } - ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL); - } + while (tempword & FT1000_DB_DPRAM_TX) { + mdelay(10); + i++; + if (i == 10) { + DEBUG("FT1000:ft1000_dsp_prov:message drop\n"); + return STATUS_FAILURE; + } + ft1000_read_register(dev, &tempword, + FT1000_REG_DOORBELL); + } - if ( !(tempword & FT1000_DB_DPRAM_TX) ) { - DEBUG("*** Provision Data Sent to DSP\n"); - - // Send provisioning data - ptr = list_entry(info->prov_list.next, struct prov_record, list); - len = *(u16 *)ptr->pprov_data; - len = htons(len); - len += PSEUDOSZ; - - pmsg = (u16 *)ptr->pprov_data; - ppseudo_hdr = (struct pseudo_hdr *)pmsg; - // Insert slow queue sequence number - ppseudo_hdr->seq_num = info->squeseqnum++; - ppseudo_hdr->portsrc = 0; - // Calculate new checksum - ppseudo_hdr->checksum = *pmsg++; - //DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum); - for (i=1; i<7; i++) { - ppseudo_hdr->checksum ^= *pmsg++; - //DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum); - } + if (!(tempword & FT1000_DB_DPRAM_TX)) { + DEBUG("*** Provision Data Sent to DSP\n"); - TempShortBuf[0] = 0; - TempShortBuf[1] = htons (len); - memcpy(&TempShortBuf[2], ppseudo_hdr, len); + /* Send provisioning data */ + ptr = + list_entry(info->prov_list.next, struct prov_record, + list); + len = *(u16 *) ptr->pprov_data; + len = htons(len); + len += PSEUDOSZ; - status = ft1000_write_dpram32 (dev, 0, (u8 *)&TempShortBuf[0], (unsigned short)(len+2)); - status = ft1000_write_register (dev, FT1000_DB_DPRAM_TX, FT1000_REG_DOORBELL); + pmsg = (u16 *) ptr->pprov_data; + ppseudo_hdr = (struct pseudo_hdr *)pmsg; + /* Insert slow queue sequence number */ + ppseudo_hdr->seq_num = info->squeseqnum++; + ppseudo_hdr->portsrc = 0; + /* Calculate new checksum */ + ppseudo_hdr->checksum = *pmsg++; + //DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum); + for (i = 1; i < 7; i++) { + ppseudo_hdr->checksum ^= *pmsg++; + //DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum); + } - list_del(&ptr->list); - kfree(ptr->pprov_data); - kfree(ptr); - } - msleep(10); - } + TempShortBuf[0] = 0; + TempShortBuf[1] = htons(len); + memcpy(&TempShortBuf[2], ppseudo_hdr, len); + + status = + ft1000_write_dpram32(dev, 0, + (u8 *) &TempShortBuf[0], + (unsigned short)(len + 2)); + status = + ft1000_write_register(dev, FT1000_DB_DPRAM_TX, + FT1000_REG_DOORBELL); + + list_del(&ptr->list); + kfree(ptr->pprov_data); + kfree(ptr); + } + msleep(10); + } - DEBUG("DSP Provisioning List Entry finished\n"); + DEBUG("DSP Provisioning List Entry finished\n"); - msleep(100); + msleep(100); - info->fProvComplete = 1; - info->CardReady = 1; - return STATUS_SUCCESS; + info->fProvComplete = 1; + info->CardReady = 1; + return STATUS_SUCCESS; } - static int ft1000_proc_drvmsg (struct ft1000_device *dev, u16 size) { struct ft1000_info *info = netdev_priv(dev->net); u16 msgtype; -- cgit v1.2.3 From 6d2b67219523afbb7d83e8664cb9b0f4f267bd9a Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 10 Mar 2011 11:51:35 +0100 Subject: staging: ft1000: Fix coding style in ft1000_proc_drvmsg function. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 558 ++++++++++++++------------ 1 file changed, 295 insertions(+), 263 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 01877581a574..78dcd49bb985 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1530,286 +1530,318 @@ static int ft1000_dsp_prov(void *arg) return STATUS_SUCCESS; } -static int ft1000_proc_drvmsg (struct ft1000_device *dev, u16 size) { +static int ft1000_proc_drvmsg(struct ft1000_device *dev, u16 size) +{ struct ft1000_info *info = netdev_priv(dev->net); - u16 msgtype; - u16 tempword; + u16 msgtype; + u16 tempword; struct media_msg *pmediamsg; struct dsp_init_msg *pdspinitmsg; struct drv_msg *pdrvmsg; - u16 i; + u16 i; struct pseudo_hdr *ppseudo_hdr; - u16 *pmsg; - u16 status; - union { - u8 byte[2]; - u16 wrd; - } convert; - - - char *cmdbuffer = kmalloc(1600, GFP_KERNEL); - if (!cmdbuffer) - return STATUS_FAILURE; - - status = ft1000_read_dpram32(dev, 0x200, cmdbuffer, size); + u16 *pmsg; + u16 status; + union { + u8 byte[2]; + u16 wrd; + } convert; + char *cmdbuffer = kmalloc(1600, GFP_KERNEL); + if (!cmdbuffer) + return STATUS_FAILURE; + status = ft1000_read_dpram32(dev, 0x200, cmdbuffer, size); #ifdef JDEBUG - DEBUG("ft1000_proc_drvmsg:cmdbuffer\n"); - for(i = 0; i < size; i+=5) - { - if( (i + 5) < size ) - DEBUG("0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", cmdbuffer[i], cmdbuffer[i+1], cmdbuffer[i+2], cmdbuffer[i+3], cmdbuffer[i+4]); - else - { - for (j = i; j < size; j++) - DEBUG("0x%x ", cmdbuffer[j]); - DEBUG("\n"); - break; - } - } + DEBUG("ft1000_proc_drvmsg:cmdbuffer\n"); + for (i = 0; i < size; i += 5) { + if ((i + 5) < size) + DEBUG("0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", cmdbuffer[i], + cmdbuffer[i + 1], cmdbuffer[i + 2], + cmdbuffer[i + 3], cmdbuffer[i + 4]); + else { + for (j = i; j < size; j++) + DEBUG("0x%x ", cmdbuffer[j]); + DEBUG("\n"); + break; + } + } #endif pdrvmsg = (struct drv_msg *)&cmdbuffer[2]; - msgtype = ntohs(pdrvmsg->type); - DEBUG("ft1000_proc_drvmsg:Command message type = 0x%x\n", msgtype); - switch (msgtype) { - case MEDIA_STATE: { - DEBUG("ft1000_proc_drvmsg:Command message type = MEDIA_STATE"); - - pmediamsg = (struct media_msg *)&cmdbuffer[0]; - if (info->ProgConStat != 0xFF) { - if (pmediamsg->state) { - DEBUG("Media is up\n"); - if (info->mediastate == 0) { - if ( info->NetDevRegDone ) - { - //netif_carrier_on(dev->net);//mbelian - netif_wake_queue(dev->net); - } - info->mediastate = 1; - /*do_gettimeofday(&tv); - info->ConTm = tv.tv_sec;*/ //mbelian - } - } - else { - DEBUG("Media is down\n"); - if (info->mediastate == 1) { - info->mediastate = 0; - if ( info->NetDevRegDone ) - { - //netif_carrier_off(dev->net); mbelian - //netif_stop_queue(dev->net); - } - info->ConTm = 0; - } - } - } - else { - DEBUG("Media is down\n"); - if (info->mediastate == 1) { - info->mediastate = 0; - if ( info->NetDevRegDone) - { - //netif_carrier_off(dev->net); //mbelian - //netif_stop_queue(dev->net); - } - info->ConTm = 0; - } - } - break; - } - case DSP_INIT_MSG: { - DEBUG("ft1000_proc_drvmsg:Command message type = DSP_INIT_MSG"); - - pdspinitmsg = (struct dsp_init_msg *)&cmdbuffer[2]; - memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ); - DEBUG("DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n", info->DspVer[0], info->DspVer[1], info->DspVer[2], info->DspVer[3]); - memcpy(info->HwSerNum, pdspinitmsg->HwSerNum, HWSERNUMSZ); - memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ); - memcpy(info->eui64, pdspinitmsg->eui64, EUISZ); - DEBUG("EUI64=%2x.%2x.%2x.%2x.%2x.%2x.%2x.%2x\n", info->eui64[0],info->eui64[1], info->eui64[2], info->eui64[3], info->eui64[4], info->eui64[5],info->eui64[6], info->eui64[7]); - dev->net->dev_addr[0] = info->eui64[0]; - dev->net->dev_addr[1] = info->eui64[1]; - dev->net->dev_addr[2] = info->eui64[2]; - dev->net->dev_addr[3] = info->eui64[5]; - dev->net->dev_addr[4] = info->eui64[6]; - dev->net->dev_addr[5] = info->eui64[7]; - - if (ntohs(pdspinitmsg->length) == (sizeof(struct dsp_init_msg) - 20)) { - memcpy(info->ProductMode, pdspinitmsg->ProductMode, MODESZ); - memcpy(info->RfCalVer, pdspinitmsg->RfCalVer, CALVERSZ); - memcpy(info->RfCalDate, pdspinitmsg->RfCalDate, CALDATESZ); - DEBUG("RFCalVer = 0x%2x 0x%2x\n", info->RfCalVer[0], info->RfCalVer[1]); - } - break; - } - case DSP_PROVISION: { - DEBUG("ft1000_proc_drvmsg:Command message type = DSP_PROVISION\n"); + msgtype = ntohs(pdrvmsg->type); + DEBUG("ft1000_proc_drvmsg:Command message type = 0x%x\n", msgtype); + switch (msgtype) { + case MEDIA_STATE:{ + DEBUG + ("ft1000_proc_drvmsg:Command message type = MEDIA_STATE"); + + pmediamsg = (struct media_msg *)&cmdbuffer[0]; + if (info->ProgConStat != 0xFF) { + if (pmediamsg->state) { + DEBUG("Media is up\n"); + if (info->mediastate == 0) { + if (info->NetDevRegDone) { + //netif_carrier_on(dev->net);//mbelian + netif_wake_queue(dev-> + net); + } + info->mediastate = 1; + /*do_gettimeofday(&tv); + info->ConTm = tv.tv_sec; *///mbelian + } + } else { + DEBUG("Media is down\n"); + if (info->mediastate == 1) { + info->mediastate = 0; + if (info->NetDevRegDone) { + //netif_carrier_off(dev->net); mbelian + //netif_stop_queue(dev->net); + } + info->ConTm = 0; + } + } + } else { + DEBUG("Media is down\n"); + if (info->mediastate == 1) { + info->mediastate = 0; + if (info->NetDevRegDone) { + //netif_carrier_off(dev->net); //mbelian + //netif_stop_queue(dev->net); + } + info->ConTm = 0; + } + } + break; + } + case DSP_INIT_MSG:{ + DEBUG + ("ft1000_proc_drvmsg:Command message type = DSP_INIT_MSG"); + + pdspinitmsg = (struct dsp_init_msg *)&cmdbuffer[2]; + memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ); + DEBUG("DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n", + info->DspVer[0], info->DspVer[1], info->DspVer[2], + info->DspVer[3]); + memcpy(info->HwSerNum, pdspinitmsg->HwSerNum, + HWSERNUMSZ); + memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ); + memcpy(info->eui64, pdspinitmsg->eui64, EUISZ); + DEBUG("EUI64=%2x.%2x.%2x.%2x.%2x.%2x.%2x.%2x\n", + info->eui64[0], info->eui64[1], info->eui64[2], + info->eui64[3], info->eui64[4], info->eui64[5], + info->eui64[6], info->eui64[7]); + dev->net->dev_addr[0] = info->eui64[0]; + dev->net->dev_addr[1] = info->eui64[1]; + dev->net->dev_addr[2] = info->eui64[2]; + dev->net->dev_addr[3] = info->eui64[5]; + dev->net->dev_addr[4] = info->eui64[6]; + dev->net->dev_addr[5] = info->eui64[7]; + + if (ntohs(pdspinitmsg->length) == + (sizeof(struct dsp_init_msg) - 20)) { + memcpy(info->ProductMode, + pdspinitmsg->ProductMode, MODESZ); + memcpy(info->RfCalVer, pdspinitmsg->RfCalVer, + CALVERSZ); + memcpy(info->RfCalDate, pdspinitmsg->RfCalDate, + CALDATESZ); + DEBUG("RFCalVer = 0x%2x 0x%2x\n", + info->RfCalVer[0], info->RfCalVer[1]); + } + break; + } + case DSP_PROVISION:{ + DEBUG + ("ft1000_proc_drvmsg:Command message type = DSP_PROVISION\n"); + + /* kick off dspprov routine to start provisioning + * Send provisioning data to DSP + */ + if (list_empty(&info->prov_list) == 0) { + info->fProvComplete = 0; + status = ft1000_dsp_prov(dev); + if (status != STATUS_SUCCESS) + goto out; + } else { + info->fProvComplete = 1; + status = + ft1000_write_register(dev, FT1000_DB_HB, + FT1000_REG_DOORBELL); + DEBUG + ("FT1000:drivermsg:No more DSP provisioning data in dsp image\n"); + } + DEBUG("ft1000_proc_drvmsg:DSP PROVISION is done\n"); + break; + } + case DSP_STORE_INFO:{ + DEBUG + ("ft1000_proc_drvmsg:Command message type = DSP_STORE_INFO"); + + DEBUG("FT1000:drivermsg:Got DSP_STORE_INFO\n"); + tempword = ntohs(pdrvmsg->length); + info->DSPInfoBlklen = tempword; + if (tempword < (MAX_DSP_SESS_REC - 4)) { + pmsg = (u16 *) &pdrvmsg->data[0]; + for (i = 0; i < ((tempword + 1) / 2); i++) { + DEBUG + ("FT1000:drivermsg:dsp info data = 0x%x\n", + *pmsg); + info->DSPInfoBlk[i + 10] = *pmsg++; + } + } else { + info->DSPInfoBlklen = 0; + } + break; + } + case DSP_GET_INFO:{ + DEBUG("FT1000:drivermsg:Got DSP_GET_INFO\n"); + /* copy dsp info block to dsp */ + info->DrvMsgPend = 1; + /* allow any outstanding ioctl to finish */ + mdelay(10); + status = + ft1000_read_register(dev, &tempword, + FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) { + mdelay(10); + status = + ft1000_read_register(dev, &tempword, + FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) { + mdelay(10); + status = + ft1000_read_register(dev, &tempword, + FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) + break; + } + } + /* Put message into Slow Queue + * Form Pseudo header + */ + pmsg = (u16 *) info->DSPInfoBlk; + *pmsg++ = 0; + *pmsg++ = + htons(info->DSPInfoBlklen + 20 + + info->DSPInfoBlklen); + ppseudo_hdr = + (struct pseudo_hdr *)(u16 *) &info->DSPInfoBlk[2]; + ppseudo_hdr->length = + htons(info->DSPInfoBlklen + 4 + + info->DSPInfoBlklen); + ppseudo_hdr->source = 0x10; + ppseudo_hdr->destination = 0x20; + ppseudo_hdr->portdest = 0; + ppseudo_hdr->portsrc = 0; + ppseudo_hdr->sh_str_id = 0; + ppseudo_hdr->control = 0; + ppseudo_hdr->rsvd1 = 0; + ppseudo_hdr->rsvd2 = 0; + ppseudo_hdr->qos_class = 0; + /* Insert slow queue sequence number */ + ppseudo_hdr->seq_num = info->squeseqnum++; + /* Insert application id */ + ppseudo_hdr->portsrc = 0; + /* Calculate new checksum */ + ppseudo_hdr->checksum = *pmsg++; + for (i = 1; i < 7; i++) + ppseudo_hdr->checksum ^= *pmsg++; - // kick off dspprov routine to start provisioning - // Send provisioning data to DSP - if (list_empty(&info->prov_list) == 0) - { - info->fProvComplete = 0; - status = ft1000_dsp_prov(dev); - if (status != STATUS_SUCCESS) - goto out; - } - else { - info->fProvComplete = 1; - status = ft1000_write_register (dev, FT1000_DB_HB, FT1000_REG_DOORBELL); - DEBUG("FT1000:drivermsg:No more DSP provisioning data in dsp image\n"); - } - DEBUG("ft1000_proc_drvmsg:DSP PROVISION is done\n"); - break; - } - case DSP_STORE_INFO: { - DEBUG("ft1000_proc_drvmsg:Command message type = DSP_STORE_INFO"); - - DEBUG("FT1000:drivermsg:Got DSP_STORE_INFO\n"); - tempword = ntohs(pdrvmsg->length); - info->DSPInfoBlklen = tempword; - if (tempword < (MAX_DSP_SESS_REC-4) ) { - pmsg = (u16 *)&pdrvmsg->data[0]; - for (i=0; i<((tempword+1)/2); i++) { - DEBUG("FT1000:drivermsg:dsp info data = 0x%x\n", *pmsg); - info->DSPInfoBlk[i+10] = *pmsg++; - } - } - else { - info->DSPInfoBlklen = 0; - } - break; - } - case DSP_GET_INFO: { - DEBUG("FT1000:drivermsg:Got DSP_GET_INFO\n"); - // copy dsp info block to dsp - info->DrvMsgPend = 1; - // allow any outstanding ioctl to finish - mdelay(10); - status = ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - mdelay(10); - status = ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - mdelay(10); - status = ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - break; - } - } - } - - // Put message into Slow Queue - // Form Pseudo header - pmsg = (u16 *)info->DSPInfoBlk; - *pmsg++ = 0; - *pmsg++ = htons(info->DSPInfoBlklen+20+info->DSPInfoBlklen); - ppseudo_hdr = (struct pseudo_hdr *)(u16 *)&info->DSPInfoBlk[2]; - ppseudo_hdr->length = htons(info->DSPInfoBlklen+4+info->DSPInfoBlklen); - ppseudo_hdr->source = 0x10; - ppseudo_hdr->destination = 0x20; - ppseudo_hdr->portdest = 0; - ppseudo_hdr->portsrc = 0; - ppseudo_hdr->sh_str_id = 0; - ppseudo_hdr->control = 0; - ppseudo_hdr->rsvd1 = 0; - ppseudo_hdr->rsvd2 = 0; - ppseudo_hdr->qos_class = 0; - // Insert slow queue sequence number - ppseudo_hdr->seq_num = info->squeseqnum++; - // Insert application id - ppseudo_hdr->portsrc = 0; - // Calculate new checksum - ppseudo_hdr->checksum = *pmsg++; - for (i=1; i<7; i++) { - ppseudo_hdr->checksum ^= *pmsg++; - } - info->DSPInfoBlk[10] = 0x7200; - info->DSPInfoBlk[11] = htons(info->DSPInfoBlklen); - status = ft1000_write_dpram32 (dev, 0, (u8 *)&info->DSPInfoBlk[0], (unsigned short)(info->DSPInfoBlklen+22)); - status = ft1000_write_register (dev, FT1000_DB_DPRAM_TX, FT1000_REG_DOORBELL); - info->DrvMsgPend = 0; - - break; - } + info->DSPInfoBlk[10] = 0x7200; + info->DSPInfoBlk[11] = htons(info->DSPInfoBlklen); + status = + ft1000_write_dpram32(dev, 0, + (u8 *) &info->DSPInfoBlk[0], + (unsigned short)(info-> + DSPInfoBlklen + + 22)); + status = + ft1000_write_register(dev, FT1000_DB_DPRAM_TX, + FT1000_REG_DOORBELL); + info->DrvMsgPend = 0; - case GET_DRV_ERR_RPT_MSG: { - DEBUG("FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n"); - // copy driver error message to dsp - info->DrvMsgPend = 1; - // allow any outstanding ioctl to finish - mdelay(10); - status = ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - mdelay(10); - status = ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - mdelay(10); - } - } - - if ( (tempword & FT1000_DB_DPRAM_TX) == 0) { - // Put message into Slow Queue - // Form Pseudo header - pmsg = (u16 *)&tempbuffer[0]; - ppseudo_hdr = (struct pseudo_hdr *)pmsg; - ppseudo_hdr->length = htons(0x0012); - ppseudo_hdr->source = 0x10; - ppseudo_hdr->destination = 0x20; - ppseudo_hdr->portdest = 0; - ppseudo_hdr->portsrc = 0; - ppseudo_hdr->sh_str_id = 0; - ppseudo_hdr->control = 0; - ppseudo_hdr->rsvd1 = 0; - ppseudo_hdr->rsvd2 = 0; - ppseudo_hdr->qos_class = 0; - // Insert slow queue sequence number - ppseudo_hdr->seq_num = info->squeseqnum++; - // Insert application id - ppseudo_hdr->portsrc = 0; - // Calculate new checksum - ppseudo_hdr->checksum = *pmsg++; - for (i=1; i<7; i++) { - ppseudo_hdr->checksum ^= *pmsg++; - } - pmsg = (u16 *)&tempbuffer[16]; - *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG); - *pmsg++ = htons(0x000e); - *pmsg++ = htons(info->DSP_TIME[0]); - *pmsg++ = htons(info->DSP_TIME[1]); - *pmsg++ = htons(info->DSP_TIME[2]); - *pmsg++ = htons(info->DSP_TIME[3]); - convert.byte[0] = info->DspVer[0]; - convert.byte[1] = info->DspVer[1]; - *pmsg++ = convert.wrd; - convert.byte[0] = info->DspVer[2]; - convert.byte[1] = info->DspVer[3]; - *pmsg++ = convert.wrd; - *pmsg++ = htons(info->DrvErrNum); - - card_send_command (dev, (unsigned char*)&tempbuffer[0], (u16)(0x0012 + PSEUDOSZ)); - info->DrvErrNum = 0; - } - info->DrvMsgPend = 0; - - break; - } - - default: - break; - } + break; + } + + case GET_DRV_ERR_RPT_MSG:{ + DEBUG("FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n"); + /* copy driver error message to dsp */ + info->DrvMsgPend = 1; + /* allow any outstanding ioctl to finish */ + mdelay(10); + status = + ft1000_read_register(dev, &tempword, + FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) { + mdelay(10); + status = + ft1000_read_register(dev, &tempword, + FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) + mdelay(10); + } + if ((tempword & FT1000_DB_DPRAM_TX) == 0) { + /* Put message into Slow Queue + * Form Pseudo header + */ + pmsg = (u16 *) &tempbuffer[0]; + ppseudo_hdr = (struct pseudo_hdr *)pmsg; + ppseudo_hdr->length = htons(0x0012); + ppseudo_hdr->source = 0x10; + ppseudo_hdr->destination = 0x20; + ppseudo_hdr->portdest = 0; + ppseudo_hdr->portsrc = 0; + ppseudo_hdr->sh_str_id = 0; + ppseudo_hdr->control = 0; + ppseudo_hdr->rsvd1 = 0; + ppseudo_hdr->rsvd2 = 0; + ppseudo_hdr->qos_class = 0; + /* Insert slow queue sequence number */ + ppseudo_hdr->seq_num = info->squeseqnum++; + /* Insert application id */ + ppseudo_hdr->portsrc = 0; + /* Calculate new checksum */ + ppseudo_hdr->checksum = *pmsg++; + for (i = 1; i < 7; i++) + ppseudo_hdr->checksum ^= *pmsg++; + + pmsg = (u16 *) &tempbuffer[16]; + *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG); + *pmsg++ = htons(0x000e); + *pmsg++ = htons(info->DSP_TIME[0]); + *pmsg++ = htons(info->DSP_TIME[1]); + *pmsg++ = htons(info->DSP_TIME[2]); + *pmsg++ = htons(info->DSP_TIME[3]); + convert.byte[0] = info->DspVer[0]; + convert.byte[1] = info->DspVer[1]; + *pmsg++ = convert.wrd; + convert.byte[0] = info->DspVer[2]; + convert.byte[1] = info->DspVer[3]; + *pmsg++ = convert.wrd; + *pmsg++ = htons(info->DrvErrNum); + + card_send_command(dev, + (unsigned char *)&tempbuffer[0], + (u16) (0x0012 + PSEUDOSZ)); + info->DrvErrNum = 0; + } + info->DrvMsgPend = 0; - status = STATUS_SUCCESS; -out: - kfree(cmdbuffer); - DEBUG("return from ft1000_proc_drvmsg\n"); - return status; -} + break; + } + default: + break; + } + status = STATUS_SUCCESS; +out: + kfree(cmdbuffer); + DEBUG("return from ft1000_proc_drvmsg\n"); + return status; +} int ft1000_poll(void* dev_id) { -- cgit v1.2.3 From 3f8214c33f3b9997f3351feef77eb32d213ef94d Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:05 +0200 Subject: staging: xgifb: vb_ext: move functions to avoid forward declarations Move functions to avoid forward declarations. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_ext.c | 320 ++++++++++++++++++++--------------------- 1 file changed, 156 insertions(+), 164 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_ext.c b/drivers/staging/xgifb/vb_ext.c index 33a063564efb..6863fc229637 100644 --- a/drivers/staging/xgifb/vb_ext.c +++ b/drivers/staging/xgifb/vb_ext.c @@ -9,14 +9,6 @@ #include "vb_util.h" #include "vb_setmode.h" #include "vb_ext.h" -static unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo); -static unsigned char XGINew_GetLCDDDCInfo( - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo); -static unsigned char XGINew_BridgeIsEnable(struct xgi_hw_device_info *, - struct vb_device_info *pVBInfo); -static unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo); /************************************************************** *********************** Dynamic Sense ************************ @@ -58,162 +50,6 @@ static unsigned char XGINew_Sense(unsigned short tempbx, unsigned short tempcx, return 0; } -void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) -{ - unsigned short tempax = 0, tempbx, tempcx, temp, P2reg0 = 0, SenseModeNo = 0, - OutputSelect = *pVBInfo->pOutputSelect, ModeIdIndex, i; - pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress; - - if (pVBInfo->IF_DEF_LVDS == 1) { - tempax = XGINew_GetReg1(pVBInfo->P3c4, 0x1A); /* ynlai 02/27/2002 */ - tempbx = XGINew_GetReg1(pVBInfo->P3c4, 0x1B); - tempax = ((tempax & 0xFE) >> 1) | (tempbx << 8); - if (tempax == 0x00) { /* Get Panel id from DDC */ - temp = XGINew_GetLCDDDCInfo(HwDeviceExtension, pVBInfo); - if (temp == 1) { /* LCD connect */ - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x39, 0xFF, 0x01); /* set CR39 bit0="1" */ - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, 0xEF, 0x00); /* clean CR37 bit4="0" */ - temp = LCDSense; - } else { /* LCD don't connect */ - temp = 0; - } - } else { - XGINew_GetPanelID(pVBInfo); - temp = LCDSense; - } - - tempbx = ~(LCDSense | AVIDEOSense | SVIDEOSense); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, tempbx, temp); - } else { /* for 301 */ - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiVision */ - tempax = XGINew_GetReg1(pVBInfo->P3c4, 0x38); - temp = tempax & 0x01; - tempax = XGINew_GetReg1(pVBInfo->P3c4, 0x3A); - temp = temp | (tempax & 0x02); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xA0, temp); - } else { - if (XGI_BridgeIsOn(pVBInfo)) { - P2reg0 = XGINew_GetReg1(pVBInfo->Part2Port, 0x00); - if (!XGINew_BridgeIsEnable(HwDeviceExtension, pVBInfo)) { - SenseModeNo = 0x2e; - /* XGINew_SetReg1(pVBInfo->P3d4, 0x30, 0x41); */ - /* XGISetModeNew(HwDeviceExtension, 0x2e); // ynlai InitMode */ - - temp = XGI_SearchModeID(SenseModeNo, &ModeIdIndex, pVBInfo); - XGI_GetVGAType(HwDeviceExtension, pVBInfo); - XGI_GetVBType(pVBInfo); - pVBInfo->SetFlag = 0x00; - pVBInfo->ModeType = ModeVGA; - pVBInfo->VBInfo = SetCRT2ToRAMDAC | LoadDACFlag | SetInSlaveMode; - XGI_GetLCDInfo(0x2e, ModeIdIndex, pVBInfo); - XGI_GetTVInfo(0x2e, ModeIdIndex, pVBInfo); - XGI_EnableBridge(HwDeviceExtension, pVBInfo); - XGI_SetCRT2Group301(SenseModeNo, HwDeviceExtension, pVBInfo); - XGI_SetCRT2ModeRegs(0x2e, HwDeviceExtension, pVBInfo); - /* XGI_DisableBridge( HwDeviceExtension, pVBInfo ) ; */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x20); /* Display Off 0212 */ - for (i = 0; i < 20; i++) - XGI_LongWait(pVBInfo); - } - XGINew_SetReg1(pVBInfo->Part2Port, 0x00, 0x1c); - tempax = 0; - tempbx = *pVBInfo->pRGBSenseData; - - if (!(XGINew_Is301B(pVBInfo))) - tempbx = *pVBInfo->pRGBSenseData2; - - tempcx = 0x0E08; - if (XGINew_Sense(tempbx, tempcx, pVBInfo)) { - if (XGINew_Sense(tempbx, tempcx, pVBInfo)) - tempax |= Monitor2Sense; - } - - if (pVBInfo->VBType & VB_XGI301C) - XGINew_SetRegOR(pVBInfo->Part4Port, 0x0d, 0x04); - - if (XGINew_SenseHiTV(HwDeviceExtension, pVBInfo)) { /* add by kuku for Multi-adapter sense HiTV */ - tempax |= HiTVSense; - if ((pVBInfo->VBType & VB_XGI301C)) - tempax ^= (HiTVSense | YPbPrSense); - } - - if (!(tempax & (HiTVSense | YPbPrSense))) { /* start */ - - tempbx = *pVBInfo->pYCSenseData; - - if (!(XGINew_Is301B(pVBInfo))) - tempbx = *pVBInfo->pYCSenseData2; - - tempcx = 0x0604; - if (XGINew_Sense(tempbx, tempcx, pVBInfo)) { - if (XGINew_Sense(tempbx, tempcx, pVBInfo)) - tempax |= SVIDEOSense; - } - - if (OutputSelect & BoardTVType) { - tempbx = *pVBInfo->pVideoSenseData; - - if (!(XGINew_Is301B(pVBInfo))) - tempbx = *pVBInfo->pVideoSenseData2; - - tempcx = 0x0804; - if (XGINew_Sense(tempbx, tempcx, pVBInfo)) { - if (XGINew_Sense(tempbx, tempcx, pVBInfo)) - tempax |= AVIDEOSense; - } - } else { - if (!(tempax & SVIDEOSense)) { - tempbx = *pVBInfo->pVideoSenseData; - - if (!(XGINew_Is301B(pVBInfo))) - tempbx = *pVBInfo->pVideoSenseData2; - - tempcx = 0x0804; - if (XGINew_Sense(tempbx, tempcx, pVBInfo)) { - if (XGINew_Sense(tempbx, tempcx, pVBInfo)) - tempax |= AVIDEOSense; - } - } - } - } - } /* end */ - if (!(tempax & Monitor2Sense)) { - if (XGINew_SenseLCD(HwDeviceExtension, pVBInfo)) - tempax |= LCDSense; - } - tempbx = 0; - tempcx = 0; - XGINew_Sense(tempbx, tempcx, pVBInfo); - - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~0xDF, tempax); - XGINew_SetReg1(pVBInfo->Part2Port, 0x00, P2reg0); - - if (!(P2reg0 & 0x20)) { - pVBInfo->VBInfo = DisableCRT2Display; - /* XGI_SetCRT2Group301(SenseModeNo, HwDeviceExtension, pVBInfo); */ - } - } - } - XGI_DisableBridge(HwDeviceExtension, pVBInfo); /* shampoo 0226 */ - -} - -unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) -{ - /* unsigned short SoftSetting ; */ - unsigned short temp; - - if ((HwDeviceExtension->jChipType >= XG20) || (HwDeviceExtension->jChipType >= XG40)) - temp = 0; - else - temp = XGINew_GetPanelID(pVBInfo); - - if (!temp) - temp = XGINew_GetLCDDDCInfo(HwDeviceExtension, pVBInfo); - - return temp; -} - static unsigned char XGINew_GetLCDDDCInfo(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { unsigned short temp; @@ -401,3 +237,159 @@ static unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtensi return 0; } } + +void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) +{ + unsigned short tempax = 0, tempbx, tempcx, temp, P2reg0 = 0, SenseModeNo = 0, + OutputSelect = *pVBInfo->pOutputSelect, ModeIdIndex, i; + pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress; + + if (pVBInfo->IF_DEF_LVDS == 1) { + tempax = XGINew_GetReg1(pVBInfo->P3c4, 0x1A); /* ynlai 02/27/2002 */ + tempbx = XGINew_GetReg1(pVBInfo->P3c4, 0x1B); + tempax = ((tempax & 0xFE) >> 1) | (tempbx << 8); + if (tempax == 0x00) { /* Get Panel id from DDC */ + temp = XGINew_GetLCDDDCInfo(HwDeviceExtension, pVBInfo); + if (temp == 1) { /* LCD connect */ + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x39, 0xFF, 0x01); /* set CR39 bit0="1" */ + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, 0xEF, 0x00); /* clean CR37 bit4="0" */ + temp = LCDSense; + } else { /* LCD don't connect */ + temp = 0; + } + } else { + XGINew_GetPanelID(pVBInfo); + temp = LCDSense; + } + + tempbx = ~(LCDSense | AVIDEOSense | SVIDEOSense); + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, tempbx, temp); + } else { /* for 301 */ + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiVision */ + tempax = XGINew_GetReg1(pVBInfo->P3c4, 0x38); + temp = tempax & 0x01; + tempax = XGINew_GetReg1(pVBInfo->P3c4, 0x3A); + temp = temp | (tempax & 0x02); + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xA0, temp); + } else { + if (XGI_BridgeIsOn(pVBInfo)) { + P2reg0 = XGINew_GetReg1(pVBInfo->Part2Port, 0x00); + if (!XGINew_BridgeIsEnable(HwDeviceExtension, pVBInfo)) { + SenseModeNo = 0x2e; + /* XGINew_SetReg1(pVBInfo->P3d4, 0x30, 0x41); */ + /* XGISetModeNew(HwDeviceExtension, 0x2e); // ynlai InitMode */ + + temp = XGI_SearchModeID(SenseModeNo, &ModeIdIndex, pVBInfo); + XGI_GetVGAType(HwDeviceExtension, pVBInfo); + XGI_GetVBType(pVBInfo); + pVBInfo->SetFlag = 0x00; + pVBInfo->ModeType = ModeVGA; + pVBInfo->VBInfo = SetCRT2ToRAMDAC | LoadDACFlag | SetInSlaveMode; + XGI_GetLCDInfo(0x2e, ModeIdIndex, pVBInfo); + XGI_GetTVInfo(0x2e, ModeIdIndex, pVBInfo); + XGI_EnableBridge(HwDeviceExtension, pVBInfo); + XGI_SetCRT2Group301(SenseModeNo, HwDeviceExtension, pVBInfo); + XGI_SetCRT2ModeRegs(0x2e, HwDeviceExtension, pVBInfo); + /* XGI_DisableBridge( HwDeviceExtension, pVBInfo ) ; */ + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x20); /* Display Off 0212 */ + for (i = 0; i < 20; i++) + XGI_LongWait(pVBInfo); + } + XGINew_SetReg1(pVBInfo->Part2Port, 0x00, 0x1c); + tempax = 0; + tempbx = *pVBInfo->pRGBSenseData; + + if (!(XGINew_Is301B(pVBInfo))) + tempbx = *pVBInfo->pRGBSenseData2; + + tempcx = 0x0E08; + if (XGINew_Sense(tempbx, tempcx, pVBInfo)) { + if (XGINew_Sense(tempbx, tempcx, pVBInfo)) + tempax |= Monitor2Sense; + } + + if (pVBInfo->VBType & VB_XGI301C) + XGINew_SetRegOR(pVBInfo->Part4Port, 0x0d, 0x04); + + if (XGINew_SenseHiTV(HwDeviceExtension, pVBInfo)) { /* add by kuku for Multi-adapter sense HiTV */ + tempax |= HiTVSense; + if ((pVBInfo->VBType & VB_XGI301C)) + tempax ^= (HiTVSense | YPbPrSense); + } + + if (!(tempax & (HiTVSense | YPbPrSense))) { /* start */ + + tempbx = *pVBInfo->pYCSenseData; + + if (!(XGINew_Is301B(pVBInfo))) + tempbx = *pVBInfo->pYCSenseData2; + + tempcx = 0x0604; + if (XGINew_Sense(tempbx, tempcx, pVBInfo)) { + if (XGINew_Sense(tempbx, tempcx, pVBInfo)) + tempax |= SVIDEOSense; + } + + if (OutputSelect & BoardTVType) { + tempbx = *pVBInfo->pVideoSenseData; + + if (!(XGINew_Is301B(pVBInfo))) + tempbx = *pVBInfo->pVideoSenseData2; + + tempcx = 0x0804; + if (XGINew_Sense(tempbx, tempcx, pVBInfo)) { + if (XGINew_Sense(tempbx, tempcx, pVBInfo)) + tempax |= AVIDEOSense; + } + } else { + if (!(tempax & SVIDEOSense)) { + tempbx = *pVBInfo->pVideoSenseData; + + if (!(XGINew_Is301B(pVBInfo))) + tempbx = *pVBInfo->pVideoSenseData2; + + tempcx = 0x0804; + if (XGINew_Sense(tempbx, tempcx, pVBInfo)) { + if (XGINew_Sense(tempbx, tempcx, pVBInfo)) + tempax |= AVIDEOSense; + } + } + } + } + } /* end */ + if (!(tempax & Monitor2Sense)) { + if (XGINew_SenseLCD(HwDeviceExtension, pVBInfo)) + tempax |= LCDSense; + } + tempbx = 0; + tempcx = 0; + XGINew_Sense(tempbx, tempcx, pVBInfo); + + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~0xDF, tempax); + XGINew_SetReg1(pVBInfo->Part2Port, 0x00, P2reg0); + + if (!(P2reg0 & 0x20)) { + pVBInfo->VBInfo = DisableCRT2Display; + /* XGI_SetCRT2Group301(SenseModeNo, HwDeviceExtension, pVBInfo); */ + } + } + } + XGI_DisableBridge(HwDeviceExtension, pVBInfo); /* shampoo 0226 */ + +} + +unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) +{ + /* unsigned short SoftSetting ; */ + unsigned short temp; + + if ((HwDeviceExtension->jChipType >= XG20) || (HwDeviceExtension->jChipType >= XG40)) + temp = 0; + else + temp = XGINew_GetPanelID(pVBInfo); + + if (!temp) + temp = XGINew_GetLCDDDCInfo(HwDeviceExtension, pVBInfo); + + return temp; +} -- cgit v1.2.3 From b9ebf5e5913307e67d226e61d953c3c4fd48de99 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:06 +0200 Subject: staging: xgifb: vb_init: move functions to avoid forward declarations Move functions to avoid forward declarations. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 2631 +++++++++++++++++++-------------------- 1 file changed, 1306 insertions(+), 1325 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 4bbcff6aedfe..7b8e00defd50 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -37,1623 +37,1604 @@ static unsigned short XGINew_DDRDRAM_TYPE20[12][5] = { { 2, 12, 9, 8, 0x35}, { 2, 12, 8, 4, 0x31} }; -static void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *, struct vb_device_info *); -static void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *); -static void XGINew_SetDRAMDefaultRegister340(struct xgi_hw_device_info *HwDeviceExtension, - unsigned long, struct vb_device_info *); -static unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo); - -static int XGINew_DDRSizing340(struct xgi_hw_device_info *, struct vb_device_info *); -static int XGINew_RAMType; /*int ModeIDOffset,StandTable,CRT1Table,ScreenOffset,REFIndex;*/ -static void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo); -static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo); -static void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ; -static void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ; -static unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo); -static void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ; -static unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo); -static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ; +static int XGINew_RAMType; static void DelayUS(unsigned long MicroSeconds) { udelay(MicroSeconds); } -unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) +static unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension, + struct vb_device_info *pVBInfo) { - struct vb_device_info VBINF; - struct vb_device_info *pVBInfo = &VBINF; - unsigned char i, temp = 0, temp1; - /* VBIOSVersion[5]; */ - volatile unsigned char *pVideoMemory; - - /* unsigned long j, k; */ - - unsigned long Temp; + unsigned char data, temp; - pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase; + if (HwDeviceExtension->jChipType < XG20) { + if (*pVBInfo->pSoftSetting & SoftDRAMType) { + data = *pVBInfo->pSoftSetting & 0x07; + return data; + } else { + data = XGINew_GetReg1(pVBInfo->P3c4, 0x39) & 0x02; - pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; + if (data == 0) + data = (XGINew_GetReg1(pVBInfo->P3c4, 0x3A) & 0x02) >> 1; - pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress; + return data; + } + } else if (HwDeviceExtension->jChipType == XG27) { + if (*pVBInfo->pSoftSetting & SoftDRAMType) { + data = *pVBInfo->pSoftSetting & 0x07; + return data; + } + temp = XGINew_GetReg1(pVBInfo->P3c4, 0x3B); - pVideoMemory = (unsigned char *) pVBInfo->ROMAddr; + if ((temp & 0x88) == 0x80) /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */ + data = 0; /* DDR */ + else + data = 1; /* DDRII */ + return data; + } else if (HwDeviceExtension->jChipType == XG21) { + XGINew_SetRegAND(pVBInfo->P3d4, 0xB4, ~0x02); /* Independent GPIO control */ + DelayUS(800); + XGINew_SetRegOR(pVBInfo->P3d4, 0x4A, 0x80); /* Enable GPIOH read */ + temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); /* GPIOF 0:DVI 1:DVO */ + /* HOTPLUG_SUPPORT */ + /* for current XG20 & XG21, GPIOH is floating, driver will fix DDR temporarily */ + if (temp & 0x01) /* DVI read GPIOH */ + data = 1; /* DDRII */ + else + data = 0; /* DDR */ + /* ~HOTPLUG_SUPPORT */ + XGINew_SetRegOR(pVBInfo->P3d4, 0xB4, 0x02); + return data; + } else { + data = XGINew_GetReg1(pVBInfo->P3d4, 0x97) & 0x01; - /* Newdebugcode(0x99); */ + if (data == 1) + data++; + return data; + } +} - /* if (pVBInfo->ROMAddr == 0) */ - /* return(0); */ +static void XGINew_DDR1x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBInfo) +{ + XGINew_SetReg1(P3c4, 0x18, 0x01); + XGINew_SetReg1(P3c4, 0x19, 0x20); + XGINew_SetReg1(P3c4, 0x16, 0x00); + XGINew_SetReg1(P3c4, 0x16, 0x80); - if (pVBInfo->FBAddr == NULL) { - printk("\n pVBInfo->FBAddr == 0 "); - return 0; - } - printk("1"); - if (pVBInfo->BaseAddr == 0) { - printk("\npVBInfo->BaseAddr == 0 "); - return 0; + if (*pVBInfo->pXGINew_DRAMTypeDefinition != 0x0C) { /* Samsung F Die */ + DelayUS(3000); /* Delay 67 x 3 Delay15us */ + XGINew_SetReg1(P3c4, 0x18, 0x00); + XGINew_SetReg1(P3c4, 0x19, 0x20); + XGINew_SetReg1(P3c4, 0x16, 0x00); + XGINew_SetReg1(P3c4, 0x16, 0x80); } - printk("2"); - XGINew_SetReg3((pVBInfo->BaseAddr + 0x12), 0x67); /* 3c2 <- 67 ,ynlai */ - - pVBInfo->ISXPDOS = 0; - printk("3"); + DelayUS(60); + XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ + XGINew_SetReg1(P3c4, 0x19, 0x01); + XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[0]); + XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[1]); + DelayUS(1000); + XGINew_SetReg1(P3c4, 0x1B, 0x03); + DelayUS(500); + XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ + XGINew_SetReg1(P3c4, 0x19, 0x00); + XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[2]); + XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[3]); + XGINew_SetReg1(P3c4, 0x1B, 0x00); +} - printk("4"); +static void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, + struct vb_device_info *pVBInfo) +{ - /* VBIOSVersion[4] = 0x0; */ + XGINew_SetReg1(pVBInfo->P3c4, 0x28, pVBInfo->MCLKData[XGINew_RAMType].SR28); + XGINew_SetReg1(pVBInfo->P3c4, 0x29, pVBInfo->MCLKData[XGINew_RAMType].SR29); + XGINew_SetReg1(pVBInfo->P3c4, 0x2A, pVBInfo->MCLKData[XGINew_RAMType].SR2A); - /* 09/07/99 modify by domao */ + XGINew_SetReg1(pVBInfo->P3c4, 0x2E, pVBInfo->ECLKData[XGINew_RAMType].SR2E); + XGINew_SetReg1(pVBInfo->P3c4, 0x2F, pVBInfo->ECLKData[XGINew_RAMType].SR2F); + XGINew_SetReg1(pVBInfo->P3c4, 0x30, pVBInfo->ECLKData[XGINew_RAMType].SR30); - pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14; - pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24; - pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10; - pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e; - pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12; - pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a; - pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16; - pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17; - pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18; - pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19; - pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A; - pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00; - pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04; - pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10; - pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12; - pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14; - pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2; - printk("5"); + /* [Vicent] 2004/07/07, When XG42 ECLK = MCLK = 207MHz, Set SR32 D[1:0] = 10b */ + /* [Hsuan] 2004/08/20, Modify SR32 value, when MCLK=207MHZ, ELCK=250MHz, Set SR32 D[1:0] = 10b */ + if (HwDeviceExtension->jChipType == XG42) { + if ((pVBInfo->MCLKData[XGINew_RAMType].SR28 == 0x1C) + && (pVBInfo->MCLKData[XGINew_RAMType].SR29 == 0x01) + && (((pVBInfo->ECLKData[XGINew_RAMType].SR2E == 0x1C) + && (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01)) + || ((pVBInfo->ECLKData[XGINew_RAMType].SR2E == 0x22) + && (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01)))) + XGINew_SetReg1(pVBInfo->P3c4, 0x32, ((unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x32) & 0xFC) | 0x02); + } +} - if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */ - XGI_GetVBType(pVBInfo); /* Run XGI_GetVBType before InitTo330Pointer */ +static void XGINew_DDRII_Bootup_XG27( + struct xgi_hw_device_info *HwDeviceExtension, + unsigned long P3c4, struct vb_device_info *pVBInfo) +{ + unsigned long P3d4 = P3c4 + 0x10; + XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); + XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo); - InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo); + /* Set Double Frequency */ + /* XGINew_SetReg1(P3d4, 0x97, 0x11); *//* CR97 */ + XGINew_SetReg1(P3d4, 0x97, *pVBInfo->pXGINew_CR97); /* CR97 */ - /* ReadVBIOSData */ - ReadVBIOSTablData(HwDeviceExtension->jChipType, pVBInfo); + DelayUS(200); - /* 1.Openkey */ - XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86); - printk("6"); + XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS2 */ + XGINew_SetReg1(P3c4, 0x19, 0x80); /* Set SR19 */ + XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ + DelayUS(15); + XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ + DelayUS(15); - /* GetXG21Sense (GPIO) */ - if (HwDeviceExtension->jChipType == XG21) - XGINew_GetXG21Sense(HwDeviceExtension, pVBInfo); + XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS3 */ + XGINew_SetReg1(P3c4, 0x19, 0xC0); /* Set SR19 */ + XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ + DelayUS(15); + XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ + DelayUS(15); - if (HwDeviceExtension->jChipType == XG27) - XGINew_GetXG27Sense(HwDeviceExtension, pVBInfo); + XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS1 */ + XGINew_SetReg1(P3c4, 0x19, 0x40); /* Set SR19 */ + XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ + DelayUS(30); + XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ + DelayUS(15); - printk("7"); + XGINew_SetReg1(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Enable */ + XGINew_SetReg1(P3c4, 0x19, 0x0A); /* Set SR19 */ + XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */ + DelayUS(30); + XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */ + XGINew_SetReg1(P3c4, 0x16, 0x80); /* Set SR16 */ + /* DelayUS(15); */ - /* 2.Reset Extended register */ + XGINew_SetReg1(P3c4, 0x1B, 0x04); /* Set SR1B */ + DelayUS(60); + XGINew_SetReg1(P3c4, 0x1B, 0x00); /* Set SR1B */ - for (i = 0x06; i < 0x20; i++) - XGINew_SetReg1(pVBInfo->P3c4, i, 0); + XGINew_SetReg1(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Reset */ + XGINew_SetReg1(P3c4, 0x19, 0x08); /* Set SR19 */ + XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */ - for (i = 0x21; i <= 0x27; i++) - XGINew_SetReg1(pVBInfo->P3c4, i, 0); + DelayUS(30); + XGINew_SetReg1(P3c4, 0x16, 0x83); /* Set SR16 */ + DelayUS(15); - /* for(i = 0x06; i <= 0x27; i++) */ - /* XGINew_SetReg1(pVBInfo->P3c4, i, 0); */ + XGINew_SetReg1(P3c4, 0x18, 0x80); /* Set SR18 */ /* MRS, ODT */ + XGINew_SetReg1(P3c4, 0x19, 0x46); /* Set SR19 */ + XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ + DelayUS(30); + XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ + DelayUS(15); - printk("8"); + XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS */ + XGINew_SetReg1(P3c4, 0x19, 0x40); /* Set SR19 */ + XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ + DelayUS(30); + XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ + DelayUS(15); - if ((HwDeviceExtension->jChipType >= XG20) || (HwDeviceExtension->jChipType >= XG40)) { - for (i = 0x31; i <= 0x3B; i++) - XGINew_SetReg1(pVBInfo->P3c4, i, 0); - } else { - for (i = 0x31; i <= 0x3D; i++) - XGINew_SetReg1(pVBInfo->P3c4, i, 0); - } - printk("9"); + XGINew_SetReg1(P3c4, 0x1B, 0x04); /* Set SR1B refresh control 000:close; 010:open */ + DelayUS(200); - if (HwDeviceExtension->jChipType == XG42) /* [Hsuan] 2004/08/20 Auto over driver for XG42 */ - XGINew_SetReg1(pVBInfo->P3c4, 0x3B, 0xC0); +} - /* for (i = 0x30; i <= 0x3F; i++) */ - /* XGINew_SetReg1(pVBInfo->P3d4, i, 0); */ +static void XGINew_DDR2_MRS_XG20(struct xgi_hw_device_info *HwDeviceExtension, + unsigned long P3c4, struct vb_device_info *pVBInfo) +{ + unsigned long P3d4 = P3c4 + 0x10; - for (i = 0x79; i <= 0x7C; i++) - XGINew_SetReg1(pVBInfo->P3d4, i, 0); /* shampoo 0208 */ + XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); + XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo); - printk("10"); + XGINew_SetReg1(P3d4, 0x97, 0x11); /* CR97 */ - if (HwDeviceExtension->jChipType >= XG20) - XGINew_SetReg1(pVBInfo->P3d4, 0x97, *pVBInfo->pXGINew_CR97); + DelayUS(200); + XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS2 */ + XGINew_SetReg1(P3c4, 0x19, 0x80); + XGINew_SetReg1(P3c4, 0x16, 0x05); + XGINew_SetReg1(P3c4, 0x16, 0x85); - /* 3.SetMemoryClock - - if (HwDeviceExtension->jChipType >= XG40) - XGINew_RAMType = (int)XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); - - if (HwDeviceExtension->jChipType < XG40) - XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo); */ - - printk("11"); + XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS3 */ + XGINew_SetReg1(P3c4, 0x19, 0xC0); + XGINew_SetReg1(P3c4, 0x16, 0x05); + XGINew_SetReg1(P3c4, 0x16, 0x85); - /* 4.SetDefExt1Regs begin */ - XGINew_SetReg1(pVBInfo->P3c4, 0x07, *pVBInfo->pSR07); - if (HwDeviceExtension->jChipType == XG27) { - XGINew_SetReg1(pVBInfo->P3c4, 0x40, *pVBInfo->pSR40); - XGINew_SetReg1(pVBInfo->P3c4, 0x41, *pVBInfo->pSR41); - } - XGINew_SetReg1(pVBInfo->P3c4, 0x11, 0x0F); - XGINew_SetReg1(pVBInfo->P3c4, 0x1F, *pVBInfo->pSR1F); - /* XGINew_SetReg1(pVBInfo->P3c4, 0x20, 0x20); */ - XGINew_SetReg1(pVBInfo->P3c4, 0x20, 0xA0); /* alan, 2001/6/26 Frame buffer can read/write SR20 */ - XGINew_SetReg1(pVBInfo->P3c4, 0x36, 0x70); /* Hsuan, 2006/01/01 H/W request for slow corner chip */ - if (HwDeviceExtension->jChipType == XG27) /* Alan 12/07/2006 */ - XGINew_SetReg1(pVBInfo->P3c4, 0x36, *pVBInfo->pSR36); + XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS1 */ + XGINew_SetReg1(P3c4, 0x19, 0x40); + XGINew_SetReg1(P3c4, 0x16, 0x05); + XGINew_SetReg1(P3c4, 0x16, 0x85); - /* SR11 = 0x0F; */ - /* XGINew_SetReg1(pVBInfo->P3c4, 0x11, SR11); */ + /* XGINew_SetReg1(P3c4, 0x18, 0x52); */ /* MRS1 */ + XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */ + XGINew_SetReg1(P3c4, 0x19, 0x02); + XGINew_SetReg1(P3c4, 0x16, 0x05); + XGINew_SetReg1(P3c4, 0x16, 0x85); - printk("12"); + DelayUS(15); + XGINew_SetReg1(P3c4, 0x1B, 0x04); /* SR1B */ + DelayUS(30); + XGINew_SetReg1(P3c4, 0x1B, 0x00); /* SR1B */ + DelayUS(100); - if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */ - /* Set AGP Rate */ - /* - temp1 = XGINew_GetReg1(pVBInfo->P3c4, 0x3B); - temp1 &= 0x02; - if (temp1 == 0x02) { - XGINew_SetReg4(0xcf8, 0x80000000); - ChipsetID = XGINew_GetReg3(0x0cfc); - XGINew_SetReg4(0xcf8, 0x8000002C); - VendorID = XGINew_GetReg3(0x0cfc); - VendorID &= 0x0000FFFF; - XGINew_SetReg4(0xcf8, 0x8001002C); - GraphicVendorID = XGINew_GetReg3(0x0cfc); - GraphicVendorID &= 0x0000FFFF; + /* XGINew_SetReg1(P3c4 ,0x18, 0x52); */ /* MRS2 */ + XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */ + XGINew_SetReg1(P3c4, 0x19, 0x00); + XGINew_SetReg1(P3c4, 0x16, 0x05); + XGINew_SetReg1(P3c4, 0x16, 0x85); - if (ChipsetID == 0x7301039) - XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x09); + DelayUS(200); +} - ChipsetID &= 0x0000FFFF; +static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo) +{ - if ((ChipsetID == 0x700E) || (ChipsetID == 0x1022) || (ChipsetID == 0x1106) || (ChipsetID == 0x10DE)) { - if (ChipsetID == 0x1106) { - if ((VendorID == 0x1019) && (GraphicVendorID == 0x1019)) - XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0D); - else - XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0B); - } else { - XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0B); - } - } - } - */ + XGINew_SetReg1(P3c4, 0x18, 0x01); + XGINew_SetReg1(P3c4, 0x19, 0x40); + XGINew_SetReg1(P3c4, 0x16, 0x00); + XGINew_SetReg1(P3c4, 0x16, 0x80); + DelayUS(60); - printk("13"); + XGINew_SetReg1(P3c4, 0x18, 0x00); + XGINew_SetReg1(P3c4, 0x19, 0x40); + XGINew_SetReg1(P3c4, 0x16, 0x00); + XGINew_SetReg1(P3c4, 0x16, 0x80); + DelayUS(60); + XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ + /* XGINew_SetReg1(P3c4, 0x18, 0x31); */ + XGINew_SetReg1(P3c4, 0x19, 0x01); + XGINew_SetReg1(P3c4, 0x16, 0x03); + XGINew_SetReg1(P3c4, 0x16, 0x83); + DelayUS(1000); + XGINew_SetReg1(P3c4, 0x1B, 0x03); + DelayUS(500); + /* XGINew_SetReg1(P3c4, 0x18, 0x31); */ + XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ + XGINew_SetReg1(P3c4, 0x19, 0x00); + XGINew_SetReg1(P3c4, 0x16, 0x03); + XGINew_SetReg1(P3c4, 0x16, 0x83); + XGINew_SetReg1(P3c4, 0x1B, 0x00); +} - if (HwDeviceExtension->jChipType >= XG40) { - /* Set AGP customize registers (in SetDefAGPRegs) Start */ - for (i = 0x47; i <= 0x4C; i++) - XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[i - 0x47]); +static void XGINew_DDR1x_DefaultRegister( + struct xgi_hw_device_info *HwDeviceExtension, + unsigned long Port, struct vb_device_info *pVBInfo) +{ + unsigned long P3d4 = Port, P3c4 = Port - 0x10; - for (i = 0x70; i <= 0x71; i++) - XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[6 + i - 0x70]); + if (HwDeviceExtension->jChipType >= XG20) { + XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo); + XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ + XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ + XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */ - for (i = 0x74; i <= 0x77; i++) - XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[8 + i - 0x74]); - /* Set AGP customize registers (in SetDefAGPRegs) End */ - /* [Hsuan]2004/12/14 AGP Input Delay Adjustment on 850 */ - /* XGINew_SetReg4(0xcf8 , 0x80000000); */ - /* ChipsetID = XGINew_GetReg3(0x0cfc); */ - /* if (ChipsetID == 0x25308086) */ - /* XGINew_SetReg1(pVBInfo->P3d4, 0x77, 0xF0); */ + XGINew_SetReg1(P3d4, 0x98, 0x01); + XGINew_SetReg1(P3d4, 0x9A, 0x02); - HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension, 0x50, 0, &Temp); /* Get */ - Temp >>= 20; - Temp &= 0xF; + XGINew_DDR1x_MRS_XG20(P3c4, pVBInfo); + } else { + XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo); - if (Temp == 1) - XGINew_SetReg1(pVBInfo->P3d4, 0x48, 0x20); /* CR48 */ + switch (HwDeviceExtension->jChipType) { + case XG41: + case XG42: + XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ + XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ + XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */ + break; + default: + XGINew_SetReg1(P3d4, 0x82, 0x88); + XGINew_SetReg1(P3d4, 0x86, 0x00); + XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */ + XGINew_SetReg1(P3d4, 0x86, 0x88); + XGINew_GetReg1(P3d4, 0x86); + XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); + XGINew_SetReg1(P3d4, 0x82, 0x77); + XGINew_SetReg1(P3d4, 0x85, 0x00); + XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */ + XGINew_SetReg1(P3d4, 0x85, 0x88); + XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */ + XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ + XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ + break; } - printk("14"); - if (HwDeviceExtension->jChipType < XG40) - XGINew_SetReg1(pVBInfo->P3d4, 0x49, pVBInfo->CR49[0]); - } /* != XG20 */ + XGINew_SetReg1(P3d4, 0x97, 0x00); + XGINew_SetReg1(P3d4, 0x98, 0x01); + XGINew_SetReg1(P3d4, 0x9A, 0x02); + XGINew_DDR1x_MRS_340(P3c4, pVBInfo); + } +} - /* Set PCI */ - XGINew_SetReg1(pVBInfo->P3c4, 0x23, *pVBInfo->pSR23); - XGINew_SetReg1(pVBInfo->P3c4, 0x24, *pVBInfo->pSR24); - XGINew_SetReg1(pVBInfo->P3c4, 0x25, pVBInfo->SR25[0]); - printk("15"); +static void XGINew_DDR2_DefaultRegister( + struct xgi_hw_device_info *HwDeviceExtension, + unsigned long Port, struct vb_device_info *pVBInfo) +{ + unsigned long P3d4 = Port, P3c4 = Port - 0x10; - if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */ - /* Set VB */ - XGI_UnLockCRT2(HwDeviceExtension, pVBInfo); - XGINew_SetRegANDOR(pVBInfo->Part0Port, 0x3F, 0xEF, 0x00); /* alan, disable VideoCapture */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x00, 0x00); - temp1 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x7B); /* chk if BCLK>=100MHz */ - temp = (unsigned char) ((temp1 >> 4) & 0x0F); + /* keep following setting sequence, each setting in the same reg insert idle */ + XGINew_SetReg1(P3d4, 0x82, 0x77); + XGINew_SetReg1(P3d4, 0x86, 0x00); + XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */ + XGINew_SetReg1(P3d4, 0x86, 0x88); + XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */ + XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */ + XGINew_SetReg1(P3d4, 0x82, 0x77); + XGINew_SetReg1(P3d4, 0x85, 0x00); + XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */ + XGINew_SetReg1(P3d4, 0x85, 0x88); + XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */ + XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ + if (HwDeviceExtension->jChipType == XG27) + XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ + else + XGINew_SetReg1(P3d4, 0x82, 0xA8); /* CR82 */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x02, (*pVBInfo->pCRT2Data_1_2)); + XGINew_SetReg1(P3d4, 0x98, 0x01); + XGINew_SetReg1(P3d4, 0x9A, 0x02); + if (HwDeviceExtension->jChipType == XG27) + XGINew_DDRII_Bootup_XG27(HwDeviceExtension, P3c4, pVBInfo); + else + XGINew_DDR2_MRS_XG20(HwDeviceExtension, P3c4, pVBInfo); +} - printk("16"); +static void XGINew_SetDRAMDefaultRegister340( + struct xgi_hw_device_info *HwDeviceExtension, + unsigned long Port, struct vb_device_info *pVBInfo) +{ + unsigned char temp, temp1, temp2, temp3, i, j, k; - XGINew_SetReg1(pVBInfo->Part1Port, 0x2E, 0x08); /* use VB */ - } /* != XG20 */ + unsigned long P3d4 = Port, P3c4 = Port - 0x10; - XGINew_SetReg1(pVBInfo->P3c4, 0x27, 0x1F); + XGINew_SetReg1(P3d4, 0x6D, pVBInfo->CR40[8][XGINew_RAMType]); + XGINew_SetReg1(P3d4, 0x68, pVBInfo->CR40[5][XGINew_RAMType]); + XGINew_SetReg1(P3d4, 0x69, pVBInfo->CR40[6][XGINew_RAMType]); + XGINew_SetReg1(P3d4, 0x6A, pVBInfo->CR40[7][XGINew_RAMType]); - if ((HwDeviceExtension->jChipType == XG42) - && XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) != 0) { /* Not DDR */ - XGINew_SetReg1(pVBInfo->P3c4, 0x31, (*pVBInfo->pSR31 & 0x3F) | 0x40); - XGINew_SetReg1(pVBInfo->P3c4, 0x32, (*pVBInfo->pSR32 & 0xFC) | 0x01); - } else { - XGINew_SetReg1(pVBInfo->P3c4, 0x31, *pVBInfo->pSR31); - XGINew_SetReg1(pVBInfo->P3c4, 0x32, *pVBInfo->pSR32); + temp2 = 0; + for (i = 0; i < 4; i++) { + temp = pVBInfo->CR6B[XGINew_RAMType][i]; /* CR6B DQS fine tune delay */ + for (j = 0; j < 4; j++) { + temp1 = ((temp >> (2 * j)) & 0x03) << 2; + temp2 |= temp1; + XGINew_SetReg1(P3d4, 0x6B, temp2); + XGINew_GetReg1(P3d4, 0x6B); /* Insert read command for delay */ + temp2 &= 0xF0; + temp2 += 0x10; + } } - XGINew_SetReg1(pVBInfo->P3c4, 0x33, *pVBInfo->pSR33); - printk("17"); - /* - if (HwDeviceExtension->jChipType >= XG40) - SetPowerConsume (HwDeviceExtension, pVBInfo->P3c4); */ - - if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */ - if (XGI_BridgeIsOn(pVBInfo) == 1) { - if (pVBInfo->IF_DEF_LVDS == 0) { - XGINew_SetReg1(pVBInfo->Part2Port, 0x00, 0x1C); - XGINew_SetReg1(pVBInfo->Part4Port, 0x0D, *pVBInfo->pCRT2Data_4_D); - XGINew_SetReg1(pVBInfo->Part4Port, 0x0E, *pVBInfo->pCRT2Data_4_E); - XGINew_SetReg1(pVBInfo->Part4Port, 0x10, *pVBInfo->pCRT2Data_4_10); - XGINew_SetReg1(pVBInfo->Part4Port, 0x0F, 0x3F); - } - - XGI_LockCRT2(HwDeviceExtension, pVBInfo); + temp2 = 0; + for (i = 0; i < 4; i++) { + temp = pVBInfo->CR6E[XGINew_RAMType][i]; /* CR6E DQM fine tune delay */ + for (j = 0; j < 4; j++) { + temp1 = ((temp >> (2 * j)) & 0x03) << 2; + temp2 |= temp1; + XGINew_SetReg1(P3d4, 0x6E, temp2); + XGINew_GetReg1(P3d4, 0x6E); /* Insert read command for delay */ + temp2 &= 0xF0; + temp2 += 0x10; } - } /* != XG20 */ - printk("18"); - - if (HwDeviceExtension->jChipType < XG40) - XGINew_SetReg1(pVBInfo->P3d4, 0x83, 0x00); - printk("181"); - - printk("182"); + } - XGI_SenseCRT1(pVBInfo); + temp3 = 0; + for (k = 0; k < 4; k++) { + XGINew_SetRegANDOR(P3d4, 0x6E, 0xFC, temp3); /* CR6E_D[1:0] select channel */ + temp2 = 0; + for (i = 0; i < 8; i++) { + temp = pVBInfo->CR6F[XGINew_RAMType][8 * k + i]; /* CR6F DQ fine tune delay */ + for (j = 0; j < 4; j++) { + temp1 = (temp >> (2 * j)) & 0x03; + temp2 |= temp1; + XGINew_SetReg1(P3d4, 0x6F, temp2); + XGINew_GetReg1(P3d4, 0x6F); /* Insert read command for delay */ + temp2 &= 0xF8; + temp2 += 0x08; + } + } + temp3 += 0x01; + } - printk("183"); - /* XGINew_DetectMonitor(HwDeviceExtension); */ - pVBInfo->IF_DEF_CH7007 = 0; - if ((HwDeviceExtension->jChipType == XG21) && (pVBInfo->IF_DEF_CH7007)) { - printk("184"); - XGI_GetSenseStatus(HwDeviceExtension, pVBInfo); /* sense CRT2 */ - printk("185"); + XGINew_SetReg1(P3d4, 0x80, pVBInfo->CR40[9][XGINew_RAMType]); /* CR80 */ + XGINew_SetReg1(P3d4, 0x81, pVBInfo->CR40[10][XGINew_RAMType]); /* CR81 */ + temp2 = 0x80; + temp = pVBInfo->CR89[XGINew_RAMType][0]; /* CR89 terminator type select */ + for (j = 0; j < 4; j++) { + temp1 = (temp >> (2 * j)) & 0x03; + temp2 |= temp1; + XGINew_SetReg1(P3d4, 0x89, temp2); + XGINew_GetReg1(P3d4, 0x89); /* Insert read command for delay */ + temp2 &= 0xF0; + temp2 += 0x10; } - if (HwDeviceExtension->jChipType == XG21) { - printk("186"); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */ - temp = GetXG21FPBits(pVBInfo); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~0x01, temp); - printk("187"); + temp = pVBInfo->CR89[XGINew_RAMType][1]; + temp1 = temp & 0x03; + temp2 |= temp1; + XGINew_SetReg1(P3d4, 0x89, temp2); - } - if (HwDeviceExtension->jChipType == XG27) { - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */ - temp = GetXG27FPBits(pVBInfo); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~0x03, temp); - } - printk("19"); + temp = pVBInfo->CR40[3][XGINew_RAMType]; + temp1 = temp & 0x0F; + temp2 = (temp >> 4) & 0x07; + temp3 = temp & 0x80; + XGINew_SetReg1(P3d4, 0x45, temp1); /* CR45 */ + XGINew_SetReg1(P3d4, 0x99, temp2); /* CR99 */ + XGINew_SetRegOR(P3d4, 0x40, temp3); /* CR40_D[7] */ + XGINew_SetReg1(P3d4, 0x41, pVBInfo->CR40[0][XGINew_RAMType]); /* CR41 */ - if (HwDeviceExtension->jChipType >= XG40) { - if (HwDeviceExtension->jChipType >= XG40) - XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); + if (HwDeviceExtension->jChipType == XG27) + XGINew_SetReg1(P3d4, 0x8F, *pVBInfo->pCR8F); /* CR8F */ - XGINew_SetDRAMDefaultRegister340(HwDeviceExtension, pVBInfo->P3d4, pVBInfo); + for (j = 0; j <= 6; j++) + XGINew_SetReg1(P3d4, (0x90 + j), + pVBInfo->CR40[14 + j][XGINew_RAMType]); /* CR90 - CR96 */ - printk("20"); - XGINew_SetDRAMSize_340(HwDeviceExtension, pVBInfo); - printk("21"); - } /* XG40 */ + for (j = 0; j <= 2; j++) + XGINew_SetReg1(P3d4, (0xC3 + j), + pVBInfo->CR40[21 + j][XGINew_RAMType]); /* CRC3 - CRC5 */ - printk("22"); + for (j = 0; j < 2; j++) + XGINew_SetReg1(P3d4, (0x8A + j), + pVBInfo->CR40[1 + j][XGINew_RAMType]); /* CR8A - CR8B */ - /* SetDefExt2Regs begin */ - /* - AGP = 1; - temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x3A); - temp &= 0x30; - if (temp == 0x30) - AGP = 0; + if ((HwDeviceExtension->jChipType == XG41) || (HwDeviceExtension->jChipType == XG42)) + XGINew_SetReg1(P3d4, 0x8C, 0x87); - if (AGP == 0) - *pVBInfo->pSR21 &= 0xEF; + XGINew_SetReg1(P3d4, 0x59, pVBInfo->CR40[4][XGINew_RAMType]); /* CR59 */ - XGINew_SetReg1(pVBInfo->P3c4, 0x21, *pVBInfo->pSR21); - if (AGP == 1) - *pVBInfo->pSR22 &= 0x20; - XGINew_SetReg1(pVBInfo->P3c4, 0x22, *pVBInfo->pSR22); - */ - /* base = 0x80000000; */ - /* OutPortLong(0xcf8, base); */ - /* Temp = (InPortLong(0xcfc) & 0xFFFF); */ - /* if (Temp == 0x1039) { */ - XGINew_SetReg1(pVBInfo->P3c4, 0x22, (unsigned char) ((*pVBInfo->pSR22) & 0xFE)); - /* } else { */ - /* XGINew_SetReg1(pVBInfo->P3c4, 0x22, *pVBInfo->pSR22); */ - /* } */ + XGINew_SetReg1(P3d4, 0x83, 0x09); /* CR83 */ + XGINew_SetReg1(P3d4, 0x87, 0x00); /* CR87 */ + XGINew_SetReg1(P3d4, 0xCF, *pVBInfo->pCRCF); /* CRCF */ + if (XGINew_RAMType) { + /* XGINew_SetReg1(P3c4, 0x17, 0xC0); */ /* SR17 DDRII */ + XGINew_SetReg1(P3c4, 0x17, 0x80); /* SR17 DDRII */ + if (HwDeviceExtension->jChipType == XG27) + XGINew_SetReg1(P3c4, 0x17, 0x02); /* SR17 DDRII */ - XGINew_SetReg1(pVBInfo->P3c4, 0x21, *pVBInfo->pSR21); + } else { + XGINew_SetReg1(P3c4, 0x17, 0x00); /* SR17 DDR */ + } + XGINew_SetReg1(P3c4, 0x1A, 0x87); /* SR1A */ - printk("23"); + temp = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); + if (temp == 0) { + XGINew_DDR1x_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo); + } else { + XGINew_SetReg1(P3d4, 0xB0, 0x80); /* DDRII Dual frequency mode */ + XGINew_DDR2_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo); + } + XGINew_SetReg1(P3c4, 0x1B, pVBInfo->SR15[3][XGINew_RAMType]); /* SR1B */ +} - XGINew_ChkSenseStatus(HwDeviceExtension, pVBInfo); - XGINew_SetModeScratch(HwDeviceExtension, pVBInfo); +static void XGINew_SetDRAMSizingType(int index, + unsigned short DRAMTYPE_TABLE[][5], + struct vb_device_info *pVBInfo) +{ + unsigned short data; - printk("24"); + data = DRAMTYPE_TABLE[index][4]; + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x13, 0x80, data); + DelayUS(15); + /* should delay 50 ns */ +} - XGINew_SetReg1(pVBInfo->P3d4, 0x8c, 0x87); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x31); - printk("25"); +static unsigned short XGINew_SetDRAMSizeReg(int index, + unsigned short DRAMTYPE_TABLE[][5], + struct vb_device_info *pVBInfo) +{ + unsigned short data = 0, memsize = 0; + int RankSize; + unsigned char ChannelNo; - return 1; -} /* end of init */ + RankSize = DRAMTYPE_TABLE[index][3] * XGINew_DataBusWidth / 32; + data = XGINew_GetReg1(pVBInfo->P3c4, 0x13); + data &= 0x80; -/* ============== alan ====================== */ + if (data == 0x80) + RankSize *= 2; -static unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned char data, temp; + data = 0; - if (HwDeviceExtension->jChipType < XG20) { - if (*pVBInfo->pSoftSetting & SoftDRAMType) { - data = *pVBInfo->pSoftSetting & 0x07; - return data; - } else { - data = XGINew_GetReg1(pVBInfo->P3c4, 0x39) & 0x02; + if (XGINew_ChannelAB == 3) + ChannelNo = 4; + else + ChannelNo = XGINew_ChannelAB; - if (data == 0) - data = (XGINew_GetReg1(pVBInfo->P3c4, 0x3A) & 0x02) >> 1; + if (ChannelNo * RankSize <= 256) { + while ((RankSize >>= 1) > 0) + data += 0x10; - return data; - } - } else if (HwDeviceExtension->jChipType == XG27) { - if (*pVBInfo->pSoftSetting & SoftDRAMType) { - data = *pVBInfo->pSoftSetting & 0x07; - return data; - } - temp = XGINew_GetReg1(pVBInfo->P3c4, 0x3B); + memsize = data >> 4; - if ((temp & 0x88) == 0x80) /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */ - data = 0; /* DDR */ - else - data = 1; /* DDRII */ - return data; - } else if (HwDeviceExtension->jChipType == XG21) { - XGINew_SetRegAND(pVBInfo->P3d4, 0xB4, ~0x02); /* Independent GPIO control */ - DelayUS(800); - XGINew_SetRegOR(pVBInfo->P3d4, 0x4A, 0x80); /* Enable GPIOH read */ - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); /* GPIOF 0:DVI 1:DVO */ - /* HOTPLUG_SUPPORT */ - /* for current XG20 & XG21, GPIOH is floating, driver will fix DDR temporarily */ - if (temp & 0x01) /* DVI read GPIOH */ - data = 1; /* DDRII */ - else - data = 0; /* DDR */ - /* ~HOTPLUG_SUPPORT */ - XGINew_SetRegOR(pVBInfo->P3d4, 0xB4, 0x02); - return data; - } else { - data = XGINew_GetReg1(pVBInfo->P3d4, 0x97) & 0x01; + /* [2004/03/25] Vicent, Fix DRAM Sizing Error */ + XGINew_SetReg1(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0)); - if (data == 1) - data++; + /* data |= XGINew_ChannelAB << 2; */ + /* data |= (XGINew_DataBusWidth / 64) << 1; */ + /* XGINew_SetReg1(pVBInfo->P3c4, 0x14, data); */ - return data; + /* should delay */ + /* XGINew_SetDRAMModeRegister340(pVBInfo); */ } + return memsize; } -static void XGINew_DDR1x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBInfo) +static unsigned short XGINew_SetDRAMSize20Reg(int index, + unsigned short DRAMTYPE_TABLE[][5], + struct vb_device_info *pVBInfo) { - XGINew_SetReg1(P3c4, 0x18, 0x01); - XGINew_SetReg1(P3c4, 0x19, 0x20); - XGINew_SetReg1(P3c4, 0x16, 0x00); - XGINew_SetReg1(P3c4, 0x16, 0x80); - - if (*pVBInfo->pXGINew_DRAMTypeDefinition != 0x0C) { /* Samsung F Die */ - DelayUS(3000); /* Delay 67 x 3 Delay15us */ - XGINew_SetReg1(P3c4, 0x18, 0x00); - XGINew_SetReg1(P3c4, 0x19, 0x20); - XGINew_SetReg1(P3c4, 0x16, 0x00); - XGINew_SetReg1(P3c4, 0x16, 0x80); - } + unsigned short data = 0, memsize = 0; + int RankSize; + unsigned char ChannelNo; - DelayUS(60); - XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ - XGINew_SetReg1(P3c4, 0x19, 0x01); - XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[0]); - XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[1]); - DelayUS(1000); - XGINew_SetReg1(P3c4, 0x1B, 0x03); - DelayUS(500); - XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ - XGINew_SetReg1(P3c4, 0x19, 0x00); - XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[2]); - XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[3]); - XGINew_SetReg1(P3c4, 0x1B, 0x00); -} + RankSize = DRAMTYPE_TABLE[index][3] * XGINew_DataBusWidth / 8; + data = XGINew_GetReg1(pVBInfo->P3c4, 0x13); + data &= 0x80; -static void XGINew_DDRII_Bootup_XG27( - struct xgi_hw_device_info *HwDeviceExtension, - unsigned long P3c4, struct vb_device_info *pVBInfo) -{ - unsigned long P3d4 = P3c4 + 0x10; - XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); - XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo); + if (data == 0x80) + RankSize *= 2; - /* Set Double Frequency */ - /* XGINew_SetReg1(P3d4, 0x97, 0x11); *//* CR97 */ - XGINew_SetReg1(P3d4, 0x97, *pVBInfo->pXGINew_CR97); /* CR97 */ + data = 0; - DelayUS(200); + if (XGINew_ChannelAB == 3) + ChannelNo = 4; + else + ChannelNo = XGINew_ChannelAB; - XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS2 */ - XGINew_SetReg1(P3c4, 0x19, 0x80); /* Set SR19 */ - XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ - DelayUS(15); - XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ - DelayUS(15); + if (ChannelNo * RankSize <= 256) { + while ((RankSize >>= 1) > 0) + data += 0x10; - XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS3 */ - XGINew_SetReg1(P3c4, 0x19, 0xC0); /* Set SR19 */ - XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ - DelayUS(15); - XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ - DelayUS(15); + memsize = data >> 4; - XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS1 */ - XGINew_SetReg1(P3c4, 0x19, 0x40); /* Set SR19 */ - XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ - DelayUS(30); - XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ - DelayUS(15); + /* [2004/03/25] Vicent, Fix DRAM Sizing Error */ + XGINew_SetReg1(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0)); + DelayUS(15); - XGINew_SetReg1(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Enable */ - XGINew_SetReg1(P3c4, 0x19, 0x0A); /* Set SR19 */ - XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */ - DelayUS(30); - XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */ - XGINew_SetReg1(P3c4, 0x16, 0x80); /* Set SR16 */ - /* DelayUS(15); */ + /* data |= XGINew_ChannelAB << 2; */ + /* data |= (XGINew_DataBusWidth / 64) << 1; */ + /* XGINew_SetReg1(pVBInfo->P3c4, 0x14, data); */ - XGINew_SetReg1(P3c4, 0x1B, 0x04); /* Set SR1B */ - DelayUS(60); - XGINew_SetReg1(P3c4, 0x1B, 0x00); /* Set SR1B */ + /* should delay */ + /* XGINew_SetDRAMModeRegister340(pVBInfo); */ + } + return memsize; +} - XGINew_SetReg1(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Reset */ - XGINew_SetReg1(P3c4, 0x19, 0x08); /* Set SR19 */ - XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */ +static int XGINew_ReadWriteRest(unsigned short StopAddr, + unsigned short StartAddr, struct vb_device_info *pVBInfo) +{ + int i; + unsigned long Position = 0; - DelayUS(30); - XGINew_SetReg1(P3c4, 0x16, 0x83); /* Set SR16 */ - DelayUS(15); + *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position; - XGINew_SetReg1(P3c4, 0x18, 0x80); /* Set SR18 */ /* MRS, ODT */ - XGINew_SetReg1(P3c4, 0x19, 0x46); /* Set SR19 */ - XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ - DelayUS(30); - XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ - DelayUS(15); + for (i = StartAddr; i <= StopAddr; i++) { + Position = 1 << i; + *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position; + } - XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS */ - XGINew_SetReg1(P3c4, 0x19, 0x40); /* Set SR19 */ - XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ - DelayUS(30); - XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ - DelayUS(15); + DelayUS(500); /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */ - XGINew_SetReg1(P3c4, 0x1B, 0x04); /* Set SR1B refresh control 000:close; 010:open */ - DelayUS(200); + Position = 0; + + if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position) + return 0; + for (i = StartAddr; i <= StopAddr; i++) { + Position = 1 << i; + if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position) + return 0; + } + return 1; } -static void XGINew_DDR2_MRS_XG20(struct xgi_hw_device_info *HwDeviceExtension, - unsigned long P3c4, struct vb_device_info *pVBInfo) +static unsigned char XGINew_CheckFrequence(struct vb_device_info *pVBInfo) { - unsigned long P3d4 = P3c4 + 0x10; - - XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); - XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo); + unsigned char data; - XGINew_SetReg1(P3d4, 0x97, 0x11); /* CR97 */ + data = XGINew_GetReg1(pVBInfo->P3d4, 0x97); - DelayUS(200); - XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS2 */ - XGINew_SetReg1(P3c4, 0x19, 0x80); - XGINew_SetReg1(P3c4, 0x16, 0x05); - XGINew_SetReg1(P3c4, 0x16, 0x85); + if ((data & 0x10) == 0) { + data = XGINew_GetReg1(pVBInfo->P3c4, 0x39); + data = (data & 0x02) >> 1; + return data; + } else { + return data & 0x01; + } +} - XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS3 */ - XGINew_SetReg1(P3c4, 0x19, 0xC0); - XGINew_SetReg1(P3c4, 0x16, 0x05); - XGINew_SetReg1(P3c4, 0x16, 0x85); +static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, + struct vb_device_info *pVBInfo) +{ + unsigned char data; - XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS1 */ - XGINew_SetReg1(P3c4, 0x19, 0x40); - XGINew_SetReg1(P3c4, 0x16, 0x05); - XGINew_SetReg1(P3c4, 0x16, 0x85); + switch (HwDeviceExtension->jChipType) { + case XG20: + case XG21: + data = XGINew_GetReg1(pVBInfo->P3d4, 0x97); + data = data & 0x01; + XGINew_ChannelAB = 1; /* XG20 "JUST" one channel */ - /* XGINew_SetReg1(P3c4, 0x18, 0x52); */ /* MRS1 */ - XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */ - XGINew_SetReg1(P3c4, 0x19, 0x02); - XGINew_SetReg1(P3c4, 0x16, 0x05); - XGINew_SetReg1(P3c4, 0x16, 0x85); + if (data == 0) { /* Single_32_16 */ - DelayUS(15); - XGINew_SetReg1(P3c4, 0x1B, 0x04); /* SR1B */ - DelayUS(30); - XGINew_SetReg1(P3c4, 0x1B, 0x00); /* SR1B */ - DelayUS(100); + if ((HwDeviceExtension->ulVideoMemorySize - 1) + > 0x1000000) { - /* XGINew_SetReg1(P3c4 ,0x18, 0x52); */ /* MRS2 */ - XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */ - XGINew_SetReg1(P3c4, 0x19, 0x00); - XGINew_SetReg1(P3c4, 0x16, 0x05); - XGINew_SetReg1(P3c4, 0x16, 0x85); + XGINew_DataBusWidth = 32; /* 32 bits */ + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 32bit */ + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52); + DelayUS(15); - DelayUS(200); -} + if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) + return; -static void XGINew_DDR1x_DefaultRegister( - struct xgi_hw_device_info *HwDeviceExtension, - unsigned long Port, struct vb_device_info *pVBInfo) -{ - unsigned long P3d4 = Port, P3c4 = Port - 0x10; + if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) { + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* 22bit + 1 rank + 32bit */ + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42); + DelayUS(15); - if (HwDeviceExtension->jChipType >= XG20) { - XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo); - XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ - XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ - XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */ + if (XGINew_ReadWriteRest(23, 23, pVBInfo) == 1) + return; + } + } - XGINew_SetReg1(P3d4, 0x98, 0x01); - XGINew_SetReg1(P3d4, 0x9A, 0x02); + if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) { + XGINew_DataBusWidth = 16; /* 16 bits */ + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 16bit */ + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x41); + DelayUS(15); - XGINew_DDR1x_MRS_XG20(P3c4, pVBInfo); - } else { - XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo); + if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) + return; + else + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); + DelayUS(15); + } - switch (HwDeviceExtension->jChipType) { - case XG41: - case XG42: - XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ - XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ - XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */ - break; - default: - XGINew_SetReg1(P3d4, 0x82, 0x88); - XGINew_SetReg1(P3d4, 0x86, 0x00); - XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */ - XGINew_SetReg1(P3d4, 0x86, 0x88); - XGINew_GetReg1(P3d4, 0x86); - XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); - XGINew_SetReg1(P3d4, 0x82, 0x77); - XGINew_SetReg1(P3d4, 0x85, 0x00); - XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */ - XGINew_SetReg1(P3d4, 0x85, 0x88); - XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */ - XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ - XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ - break; - } + } else { /* Dual_16_8 */ + if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) { - XGINew_SetReg1(P3d4, 0x97, 0x00); - XGINew_SetReg1(P3d4, 0x98, 0x01); - XGINew_SetReg1(P3d4, 0x9A, 0x02); - XGINew_DDR1x_MRS_340(P3c4, pVBInfo); - } -} - -static void XGINew_DDR2_DefaultRegister( - struct xgi_hw_device_info *HwDeviceExtension, - unsigned long Port, struct vb_device_info *pVBInfo) -{ - unsigned long P3d4 = Port, P3c4 = Port - 0x10; - - /* keep following setting sequence, each setting in the same reg insert idle */ - XGINew_SetReg1(P3d4, 0x82, 0x77); - XGINew_SetReg1(P3d4, 0x86, 0x00); - XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */ - XGINew_SetReg1(P3d4, 0x86, 0x88); - XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */ - XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */ - XGINew_SetReg1(P3d4, 0x82, 0x77); - XGINew_SetReg1(P3d4, 0x85, 0x00); - XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */ - XGINew_SetReg1(P3d4, 0x85, 0x88); - XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */ - XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ - if (HwDeviceExtension->jChipType == XG27) - XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ - else - XGINew_SetReg1(P3d4, 0x82, 0xA8); /* CR82 */ - - XGINew_SetReg1(P3d4, 0x98, 0x01); - XGINew_SetReg1(P3d4, 0x9A, 0x02); - if (HwDeviceExtension->jChipType == XG27) - XGINew_DDRII_Bootup_XG27(HwDeviceExtension, P3c4, pVBInfo); - else - XGINew_DDR2_MRS_XG20(HwDeviceExtension, P3c4, pVBInfo); -} - -static void XGINew_SetDRAMDefaultRegister340( - struct xgi_hw_device_info *HwDeviceExtension, - unsigned long Port, struct vb_device_info *pVBInfo) -{ - unsigned char temp, temp1, temp2, temp3, i, j, k; + XGINew_DataBusWidth = 16; /* 16 bits */ + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */ + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x41); /* 0x41:16Mx16 bit*/ + DelayUS(15); - unsigned long P3d4 = Port, P3c4 = Port - 0x10; + if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) + return; - XGINew_SetReg1(P3d4, 0x6D, pVBInfo->CR40[8][XGINew_RAMType]); - XGINew_SetReg1(P3d4, 0x68, pVBInfo->CR40[5][XGINew_RAMType]); - XGINew_SetReg1(P3d4, 0x69, pVBInfo->CR40[6][XGINew_RAMType]); - XGINew_SetReg1(P3d4, 0x6A, pVBInfo->CR40[7][XGINew_RAMType]); + if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x400000) { + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */ + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x31); /* 0x31:8Mx16 bit*/ + DelayUS(15); - temp2 = 0; - for (i = 0; i < 4; i++) { - temp = pVBInfo->CR6B[XGINew_RAMType][i]; /* CR6B DQS fine tune delay */ - for (j = 0; j < 4; j++) { - temp1 = ((temp >> (2 * j)) & 0x03) << 2; - temp2 |= temp1; - XGINew_SetReg1(P3d4, 0x6B, temp2); - XGINew_GetReg1(P3d4, 0x6B); /* Insert read command for delay */ - temp2 &= 0xF0; - temp2 += 0x10; - } - } + if (XGINew_ReadWriteRest(22, 22, pVBInfo) == 1) + return; + } + } - temp2 = 0; - for (i = 0; i < 4; i++) { - temp = pVBInfo->CR6E[XGINew_RAMType][i]; /* CR6E DQM fine tune delay */ - for (j = 0; j < 4; j++) { - temp1 = ((temp >> (2 * j)) & 0x03) << 2; - temp2 |= temp1; - XGINew_SetReg1(P3d4, 0x6E, temp2); - XGINew_GetReg1(P3d4, 0x6E); /* Insert read command for delay */ - temp2 &= 0xF0; - temp2 += 0x10; - } - } + if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x400000) { + XGINew_DataBusWidth = 8; /* 8 bits */ + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */ + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x30); /* 0x30:8Mx8 bit*/ + DelayUS(15); - temp3 = 0; - for (k = 0; k < 4; k++) { - XGINew_SetRegANDOR(P3d4, 0x6E, 0xFC, temp3); /* CR6E_D[1:0] select channel */ - temp2 = 0; - for (i = 0; i < 8; i++) { - temp = pVBInfo->CR6F[XGINew_RAMType][8 * k + i]; /* CR6F DQ fine tune delay */ - for (j = 0; j < 4; j++) { - temp1 = (temp >> (2 * j)) & 0x03; - temp2 |= temp1; - XGINew_SetReg1(P3d4, 0x6F, temp2); - XGINew_GetReg1(P3d4, 0x6F); /* Insert read command for delay */ - temp2 &= 0xF8; - temp2 += 0x08; + if (XGINew_ReadWriteRest(22, 21, pVBInfo) == 1) + return; + else + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */ + DelayUS(15); } } - temp3 += 0x01; - } + break; - XGINew_SetReg1(P3d4, 0x80, pVBInfo->CR40[9][XGINew_RAMType]); /* CR80 */ - XGINew_SetReg1(P3d4, 0x81, pVBInfo->CR40[10][XGINew_RAMType]); /* CR81 */ + case XG27: + XGINew_DataBusWidth = 16; /* 16 bits */ + XGINew_ChannelAB = 1; /* Single channel */ + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x51); /* 32Mx16 bit*/ + break; + case XG41: + if (XGINew_CheckFrequence(pVBInfo) == 1) { + XGINew_DataBusWidth = 32; /* 32 bits */ + XGINew_ChannelAB = 3; /* Quad Channel */ + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4C); - temp2 = 0x80; - temp = pVBInfo->CR89[XGINew_RAMType][0]; /* CR89 terminator type select */ - for (j = 0; j < 4; j++) { - temp1 = (temp >> (2 * j)) & 0x03; - temp2 |= temp1; - XGINew_SetReg1(P3d4, 0x89, temp2); - XGINew_GetReg1(P3d4, 0x89); /* Insert read command for delay */ - temp2 &= 0xF0; - temp2 += 0x10; - } + if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1) + return; - temp = pVBInfo->CR89[XGINew_RAMType][1]; - temp1 = temp & 0x03; - temp2 |= temp1; - XGINew_SetReg1(P3d4, 0x89, temp2); + XGINew_ChannelAB = 2; /* Dual channels */ + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x48); - temp = pVBInfo->CR40[3][XGINew_RAMType]; - temp1 = temp & 0x0F; - temp2 = (temp >> 4) & 0x07; - temp3 = temp & 0x80; - XGINew_SetReg1(P3d4, 0x45, temp1); /* CR45 */ - XGINew_SetReg1(P3d4, 0x99, temp2); /* CR99 */ - XGINew_SetRegOR(P3d4, 0x40, temp3); /* CR40_D[7] */ - XGINew_SetReg1(P3d4, 0x41, pVBInfo->CR40[0][XGINew_RAMType]); /* CR41 */ + if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) + return; - if (HwDeviceExtension->jChipType == XG27) - XGINew_SetReg1(P3d4, 0x8F, *pVBInfo->pCR8F); /* CR8F */ + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x49); - for (j = 0; j <= 6; j++) - XGINew_SetReg1(P3d4, (0x90 + j), - pVBInfo->CR40[14 + j][XGINew_RAMType]); /* CR90 - CR96 */ + if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) + return; - for (j = 0; j <= 2; j++) - XGINew_SetReg1(P3d4, (0xC3 + j), - pVBInfo->CR40[21 + j][XGINew_RAMType]); /* CRC3 - CRC5 */ + XGINew_ChannelAB = 3; + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x3C); - for (j = 0; j < 2; j++) - XGINew_SetReg1(P3d4, (0x8A + j), - pVBInfo->CR40[1 + j][XGINew_RAMType]); /* CR8A - CR8B */ + if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) + return; - if ((HwDeviceExtension->jChipType == XG41) || (HwDeviceExtension->jChipType == XG42)) - XGINew_SetReg1(P3d4, 0x8C, 0x87); + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x38); - XGINew_SetReg1(P3d4, 0x59, pVBInfo->CR40[4][XGINew_RAMType]); /* CR59 */ + if (XGINew_ReadWriteRest(8, 4, pVBInfo) == 1) + return; + else + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x39); + } else { /* DDR */ + XGINew_DataBusWidth = 64; /* 64 bits */ + XGINew_ChannelAB = 2; /* Dual channels */ + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x5A); - XGINew_SetReg1(P3d4, 0x83, 0x09); /* CR83 */ - XGINew_SetReg1(P3d4, 0x87, 0x00); /* CR87 */ - XGINew_SetReg1(P3d4, 0xCF, *pVBInfo->pCRCF); /* CRCF */ - if (XGINew_RAMType) { - /* XGINew_SetReg1(P3c4, 0x17, 0xC0); */ /* SR17 DDRII */ - XGINew_SetReg1(P3c4, 0x17, 0x80); /* SR17 DDRII */ - if (HwDeviceExtension->jChipType == XG27) - XGINew_SetReg1(P3c4, 0x17, 0x02); /* SR17 DDRII */ + if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1) + return; - } else { - XGINew_SetReg1(P3c4, 0x17, 0x00); /* SR17 DDR */ - } - XGINew_SetReg1(P3c4, 0x1A, 0x87); /* SR1A */ + XGINew_ChannelAB = 1; /* Single channels */ + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52); - temp = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); - if (temp == 0) { - XGINew_DDR1x_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo); - } else { - XGINew_SetReg1(P3d4, 0xB0, 0x80); /* DDRII Dual frequency mode */ - XGINew_DDR2_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo); - } - XGINew_SetReg1(P3c4, 0x1B, pVBInfo->SR15[3][XGINew_RAMType]); /* SR1B */ -} + if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) + return; -static void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short data; + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x53); - pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase; - pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; + if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) + return; - XGISetModeNew(HwDeviceExtension, 0x2e); + XGINew_ChannelAB = 2; /* Dual channels */ + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4A); - data = XGINew_GetReg1(pVBInfo->P3c4, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data & 0xDF)); /* disable read cache */ - XGI_DisplayOff(HwDeviceExtension, pVBInfo); + if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) + return; - /* data = XGINew_GetReg1(pVBInfo->P3c4, 0x1); */ - /* data |= 0x20 ; */ - /* XGINew_SetReg1(pVBInfo->P3c4, 0x01, data); *//* Turn OFF Display */ - XGINew_DDRSizing340(HwDeviceExtension, pVBInfo); - data = XGINew_GetReg1(pVBInfo->P3c4, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20)); /* enable read cache */ -} + XGINew_ChannelAB = 1; /* Single channels */ + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42); -static void XGINew_SetDRAMSizingType(int index, - unsigned short DRAMTYPE_TABLE[][5], - struct vb_device_info *pVBInfo) -{ - unsigned short data; + if (XGINew_ReadWriteRest(8, 4, pVBInfo) == 1) + return; + else + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x43); + } - data = DRAMTYPE_TABLE[index][4]; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x13, 0x80, data); - DelayUS(15); - /* should delay 50 ns */ -} + break; -static unsigned short XGINew_SetDRAMSizeReg(int index, - unsigned short DRAMTYPE_TABLE[][5], - struct vb_device_info *pVBInfo) -{ - unsigned short data = 0, memsize = 0; - int RankSize; - unsigned char ChannelNo; - - RankSize = DRAMTYPE_TABLE[index][3] * XGINew_DataBusWidth / 32; - data = XGINew_GetReg1(pVBInfo->P3c4, 0x13); - data &= 0x80; - - if (data == 0x80) - RankSize *= 2; - - data = 0; - - if (XGINew_ChannelAB == 3) - ChannelNo = 4; - else - ChannelNo = XGINew_ChannelAB; + case XG42: + /* + XG42 SR14 D[3] Reserve + D[2] = 1, Dual Channel + = 0, Single Channel - if (ChannelNo * RankSize <= 256) { - while ((RankSize >>= 1) > 0) - data += 0x10; + It's Different from Other XG40 Series. + */ + if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII, DDR2x */ + XGINew_DataBusWidth = 32; /* 32 bits */ + XGINew_ChannelAB = 2; /* 2 Channel */ + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x44); - memsize = data >> 4; + if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) + return; - /* [2004/03/25] Vicent, Fix DRAM Sizing Error */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0)); + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x34); + if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) + return; - /* data |= XGINew_ChannelAB << 2; */ - /* data |= (XGINew_DataBusWidth / 64) << 1; */ - /* XGINew_SetReg1(pVBInfo->P3c4, 0x14, data); */ + XGINew_ChannelAB = 1; /* Single Channel */ + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x40); - /* should delay */ - /* XGINew_SetDRAMModeRegister340(pVBInfo); */ - } - return memsize; -} + if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) + return; + else { + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x30); + } + } else { /* DDR */ + XGINew_DataBusWidth = 64; /* 64 bits */ + XGINew_ChannelAB = 1; /* 1 channels */ + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52); -static unsigned short XGINew_SetDRAMSize20Reg(int index, - unsigned short DRAMTYPE_TABLE[][5], - struct vb_device_info *pVBInfo) -{ - unsigned short data = 0, memsize = 0; - int RankSize; - unsigned char ChannelNo; + if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) + return; + else { + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42); + } + } - RankSize = DRAMTYPE_TABLE[index][3] * XGINew_DataBusWidth / 8; - data = XGINew_GetReg1(pVBInfo->P3c4, 0x13); - data &= 0x80; + break; - if (data == 0x80) - RankSize *= 2; + default: /* XG40 */ - data = 0; + if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII */ + XGINew_DataBusWidth = 32; /* 32 bits */ + XGINew_ChannelAB = 3; + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4C); - if (XGINew_ChannelAB == 3) - ChannelNo = 4; - else - ChannelNo = XGINew_ChannelAB; + if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1) + return; - if (ChannelNo * RankSize <= 256) { - while ((RankSize >>= 1) > 0) - data += 0x10; + XGINew_ChannelAB = 2; /* 2 channels */ + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x48); - memsize = data >> 4; + if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) + return; - /* [2004/03/25] Vicent, Fix DRAM Sizing Error */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0)); - DelayUS(15); + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x3C); - /* data |= XGINew_ChannelAB << 2; */ - /* data |= (XGINew_DataBusWidth / 64) << 1; */ - /* XGINew_SetReg1(pVBInfo->P3c4, 0x14, data); */ + if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) { + XGINew_ChannelAB = 3; /* 4 channels */ + } else { + XGINew_ChannelAB = 2; /* 2 channels */ + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x38); + } + } else { /* DDR */ + XGINew_DataBusWidth = 64; /* 64 bits */ + XGINew_ChannelAB = 2; /* 2 channels */ + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x5A); - /* should delay */ - /* XGINew_SetDRAMModeRegister340(pVBInfo); */ + if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1) { + return; + } else { + XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4A); + } + } + break; } - return memsize; } -static int XGINew_ReadWriteRest(unsigned short StopAddr, - unsigned short StartAddr, struct vb_device_info *pVBInfo) +static int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension, + struct vb_device_info *pVBInfo) { int i; - unsigned long Position = 0; - - *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position; - - for (i = StartAddr; i <= StopAddr; i++) { - Position = 1 << i; - *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position; - } + unsigned short memsize, addr; - DelayUS(500); /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */ + XGINew_SetReg1(pVBInfo->P3c4, 0x15, 0x00); /* noninterleaving */ + XGINew_SetReg1(pVBInfo->P3c4, 0x1C, 0x00); /* nontiling */ + XGINew_CheckChannel(HwDeviceExtension, pVBInfo); - Position = 0; + if (HwDeviceExtension->jChipType >= XG20) { + for (i = 0; i < 12; i++) { + XGINew_SetDRAMSizingType(i, XGINew_DDRDRAM_TYPE20, pVBInfo); + memsize = XGINew_SetDRAMSize20Reg(i, XGINew_DDRDRAM_TYPE20, pVBInfo); + if (memsize == 0) + continue; - if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position) - return 0; + addr = memsize + (XGINew_ChannelAB - 2) + 20; + if ((HwDeviceExtension->ulVideoMemorySize - 1) < (unsigned long) (1 << addr)) + continue; - for (i = StartAddr; i <= StopAddr; i++) { - Position = 1 << i; - if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position) - return 0; - } - return 1; -} + if (XGINew_ReadWriteRest(addr, 5, pVBInfo) == 1) + return 1; + } + } else { + for (i = 0; i < 4; i++) { + XGINew_SetDRAMSizingType(i, XGINew_DDRDRAM_TYPE340, pVBInfo); + memsize = XGINew_SetDRAMSizeReg(i, XGINew_DDRDRAM_TYPE340, pVBInfo); -static unsigned char XGINew_CheckFrequence(struct vb_device_info *pVBInfo) -{ - unsigned char data; + if (memsize == 0) + continue; - data = XGINew_GetReg1(pVBInfo->P3d4, 0x97); + addr = memsize + (XGINew_ChannelAB - 2) + 20; + if ((HwDeviceExtension->ulVideoMemorySize - 1) < (unsigned long) (1 << addr)) + continue; - if ((data & 0x10) == 0) { - data = XGINew_GetReg1(pVBInfo->P3c4, 0x39); - data = (data & 0x02) >> 1; - return data; - } else { - return data & 0x01; + if (XGINew_ReadWriteRest(addr, 9, pVBInfo) == 1) + return 1; + } } + return 0; } -static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, +static void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - unsigned char data; - - switch (HwDeviceExtension->jChipType) { - case XG20: - case XG21: - data = XGINew_GetReg1(pVBInfo->P3d4, 0x97); - data = data & 0x01; - XGINew_ChannelAB = 1; /* XG20 "JUST" one channel */ - - if (data == 0) { /* Single_32_16 */ - - if ((HwDeviceExtension->ulVideoMemorySize - 1) - > 0x1000000) { + unsigned short data; - XGINew_DataBusWidth = 32; /* 32 bits */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 32bit */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52); - DelayUS(15); + pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase; + pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; + XGISetModeNew(HwDeviceExtension, 0x2e); - if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) { - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* 22bit + 1 rank + 32bit */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42); - DelayUS(15); + data = XGINew_GetReg1(pVBInfo->P3c4, 0x21); + XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data & 0xDF)); /* disable read cache */ + XGI_DisplayOff(HwDeviceExtension, pVBInfo); - if (XGINew_ReadWriteRest(23, 23, pVBInfo) == 1) - return; - } - } + /* data = XGINew_GetReg1(pVBInfo->P3c4, 0x1); */ + /* data |= 0x20 ; */ + /* XGINew_SetReg1(pVBInfo->P3c4, 0x01, data); *//* Turn OFF Display */ + XGINew_DDRSizing340(HwDeviceExtension, pVBInfo); + data = XGINew_GetReg1(pVBInfo->P3c4, 0x21); + XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20)); /* enable read cache */ +} - if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) { - XGINew_DataBusWidth = 16; /* 16 bits */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 16bit */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x41); - DelayUS(15); +static void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo) +{ + volatile unsigned char *pVideoMemory = (unsigned char *) pVBInfo->ROMAddr; + unsigned long i; + unsigned char j, k; + /* Volari customize data area end */ - if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) - return; - else - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); - DelayUS(15); + if (ChipType == XG21) { + pVBInfo->IF_DEF_LVDS = 0; + if (pVideoMemory[0x65] & 0x1) { + pVBInfo->IF_DEF_LVDS = 1; + i = pVideoMemory[0x316] | (pVideoMemory[0x317] << 8); + j = pVideoMemory[i - 1]; + if (j != 0xff) { + k = 0; + do { + pVBInfo->XG21_LVDSCapList[k].LVDS_Capability + = pVideoMemory[i] | (pVideoMemory[i + 1] << 8); + pVBInfo->XG21_LVDSCapList[k].LVDSHT + = pVideoMemory[i + 2] | (pVideoMemory[i + 3] << 8); + pVBInfo->XG21_LVDSCapList[k].LVDSVT + = pVideoMemory[i + 4] | (pVideoMemory[i + 5] << 8); + pVBInfo->XG21_LVDSCapList[k].LVDSHDE + = pVideoMemory[i + 6] | (pVideoMemory[i + 7] << 8); + pVBInfo->XG21_LVDSCapList[k].LVDSVDE + = pVideoMemory[i + 8] | (pVideoMemory[i + 9] << 8); + pVBInfo->XG21_LVDSCapList[k].LVDSHFP + = pVideoMemory[i + 10] | (pVideoMemory[i + 11] << 8); + pVBInfo->XG21_LVDSCapList[k].LVDSVFP + = pVideoMemory[i + 12] | (pVideoMemory[i + 13] << 8); + pVBInfo->XG21_LVDSCapList[k].LVDSHSYNC + = pVideoMemory[i + 14] | (pVideoMemory[i + 15] << 8); + pVBInfo->XG21_LVDSCapList[k].LVDSVSYNC + = pVideoMemory[i + 16] | (pVideoMemory[i + 17] << 8); + pVBInfo->XG21_LVDSCapList[k].VCLKData1 + = pVideoMemory[i + 18]; + pVBInfo->XG21_LVDSCapList[k].VCLKData2 + = pVideoMemory[i + 19]; + pVBInfo->XG21_LVDSCapList[k].PSC_S1 + = pVideoMemory[i + 20]; + pVBInfo->XG21_LVDSCapList[k].PSC_S2 + = pVideoMemory[i + 21]; + pVBInfo->XG21_LVDSCapList[k].PSC_S3 + = pVideoMemory[i + 22]; + pVBInfo->XG21_LVDSCapList[k].PSC_S4 + = pVideoMemory[i + 23]; + pVBInfo->XG21_LVDSCapList[k].PSC_S5 + = pVideoMemory[i + 24]; + i += 25; + j--; + k++; + } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList) / sizeof(struct XGI21_LVDSCapStruct)))); + } else { + pVBInfo->XG21_LVDSCapList[0].LVDS_Capability + = pVideoMemory[i] | (pVideoMemory[i + 1] << 8); + pVBInfo->XG21_LVDSCapList[0].LVDSHT + = pVideoMemory[i + 2] | (pVideoMemory[i + 3] << 8); + pVBInfo->XG21_LVDSCapList[0].LVDSVT + = pVideoMemory[i + 4] | (pVideoMemory[i + 5] << 8); + pVBInfo->XG21_LVDSCapList[0].LVDSHDE + = pVideoMemory[i + 6] | (pVideoMemory[i + 7] << 8); + pVBInfo->XG21_LVDSCapList[0].LVDSVDE + = pVideoMemory[i + 8] | (pVideoMemory[i + 9] << 8); + pVBInfo->XG21_LVDSCapList[0].LVDSHFP + = pVideoMemory[i + 10] | (pVideoMemory[i + 11] << 8); + pVBInfo->XG21_LVDSCapList[0].LVDSVFP + = pVideoMemory[i + 12] | (pVideoMemory[i + 13] << 8); + pVBInfo->XG21_LVDSCapList[0].LVDSHSYNC + = pVideoMemory[i + 14] | (pVideoMemory[i + 15] << 8); + pVBInfo->XG21_LVDSCapList[0].LVDSVSYNC + = pVideoMemory[i + 16] | (pVideoMemory[i + 17] << 8); + pVBInfo->XG21_LVDSCapList[0].VCLKData1 + = pVideoMemory[i + 18]; + pVBInfo->XG21_LVDSCapList[0].VCLKData2 + = pVideoMemory[i + 19]; + pVBInfo->XG21_LVDSCapList[0].PSC_S1 + = pVideoMemory[i + 20]; + pVBInfo->XG21_LVDSCapList[0].PSC_S2 + = pVideoMemory[i + 21]; + pVBInfo->XG21_LVDSCapList[0].PSC_S3 + = pVideoMemory[i + 22]; + pVBInfo->XG21_LVDSCapList[0].PSC_S4 + = pVideoMemory[i + 23]; + pVBInfo->XG21_LVDSCapList[0].PSC_S5 + = pVideoMemory[i + 24]; } + } + } +} - } else { /* Dual_16_8 */ - if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) { - - XGINew_DataBusWidth = 16; /* 16 bits */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x41); /* 0x41:16Mx16 bit*/ - DelayUS(15); - - if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) - return; +static void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, + struct vb_device_info *pVBInfo) +{ + unsigned short tempbx = 0, temp, tempcx, CR3CData; - if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x400000) { - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x31); /* 0x31:8Mx16 bit*/ - DelayUS(15); + temp = XGINew_GetReg1(pVBInfo->P3d4, 0x32); - if (XGINew_ReadWriteRest(22, 22, pVBInfo) == 1) - return; - } - } + if (temp & Monitor1Sense) + tempbx |= ActiveCRT1; + if (temp & LCDSense) + tempbx |= ActiveLCD; + if (temp & Monitor2Sense) + tempbx |= ActiveCRT2; + if (temp & TVSense) { + tempbx |= ActiveTV; + if (temp & AVIDEOSense) + tempbx |= (ActiveAVideo << 8); + if (temp & SVIDEOSense) + tempbx |= (ActiveSVideo << 8); + if (temp & SCARTSense) + tempbx |= (ActiveSCART << 8); + if (temp & HiTVSense) + tempbx |= (ActiveHiTV << 8); + if (temp & YPbPrSense) + tempbx |= (ActiveYPbPr << 8); + } - if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x400000) { - XGINew_DataBusWidth = 8; /* 8 bits */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x30); /* 0x30:8Mx8 bit*/ - DelayUS(15); + tempcx = XGINew_GetReg1(pVBInfo->P3d4, 0x3d); + tempcx |= (XGINew_GetReg1(pVBInfo->P3d4, 0x3e) << 8); - if (XGINew_ReadWriteRest(22, 21, pVBInfo) == 1) - return; - else - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */ - DelayUS(15); - } + if (tempbx & tempcx) { + CR3CData = XGINew_GetReg1(pVBInfo->P3d4, 0x3c); + if (!(CR3CData & DisplayDeviceFromCMOS)) { + tempcx = 0x1FF0; + if (*pVBInfo->pSoftSetting & ModeSoftSetting) + tempbx = 0x1FF0; } - break; + } else { + tempcx = 0x1FF0; + if (*pVBInfo->pSoftSetting & ModeSoftSetting) + tempbx = 0x1FF0; + } - case XG27: - XGINew_DataBusWidth = 16; /* 16 bits */ - XGINew_ChannelAB = 1; /* Single channel */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x51); /* 32Mx16 bit*/ - break; - case XG41: - if (XGINew_CheckFrequence(pVBInfo) == 1) { - XGINew_DataBusWidth = 32; /* 32 bits */ - XGINew_ChannelAB = 3; /* Quad Channel */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4C); + tempbx &= tempcx; + XGINew_SetReg1(pVBInfo->P3d4, 0x3d, (tempbx & 0x00FF)); + XGINew_SetReg1(pVBInfo->P3d4, 0x3e, ((tempbx & 0xFF00) >> 8)); +} - if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1) - return; +static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, + struct vb_device_info *pVBInfo) +{ + unsigned short temp, tempcl = 0, tempch = 0, CR31Data, CR38Data; - XGINew_ChannelAB = 2; /* Dual channels */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x48); + temp = XGINew_GetReg1(pVBInfo->P3d4, 0x3d); + temp |= XGINew_GetReg1(pVBInfo->P3d4, 0x3e) << 8; + temp |= (XGINew_GetReg1(pVBInfo->P3d4, 0x31) & (DriverMode >> 8)) << 8; - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; + if (pVBInfo->IF_DEF_CRT2Monitor == 1) { + if (temp & ActiveCRT2) + tempcl = SetCRT2ToRAMDAC; + } - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x49); + if (temp & ActiveLCD) { + tempcl |= SetCRT2ToLCD; + if (temp & DriverMode) { + if (temp & ActiveTV) { + tempch = SetToLCDA | EnableDualEdge; + temp ^= SetCRT2ToLCD; - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; + if ((temp >> 8) & ActiveAVideo) + tempcl |= SetCRT2ToAVIDEO; + if ((temp >> 8) & ActiveSVideo) + tempcl |= SetCRT2ToSVIDEO; + if ((temp >> 8) & ActiveSCART) + tempcl |= SetCRT2ToSCART; - XGINew_ChannelAB = 3; - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x3C); + if (pVBInfo->IF_DEF_HiVision == 1) { + if ((temp >> 8) & ActiveHiTV) + tempcl |= SetCRT2ToHiVisionTV; + } - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; + if (pVBInfo->IF_DEF_YPbPr == 1) { + if ((temp >> 8) & ActiveYPbPr) + tempch |= SetYPbPr; + } + } + } + } else { + if ((temp >> 8) & ActiveAVideo) + tempcl |= SetCRT2ToAVIDEO; + if ((temp >> 8) & ActiveSVideo) + tempcl |= SetCRT2ToSVIDEO; + if ((temp >> 8) & ActiveSCART) + tempcl |= SetCRT2ToSCART; - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x38); + if (pVBInfo->IF_DEF_HiVision == 1) { + if ((temp >> 8) & ActiveHiTV) + tempcl |= SetCRT2ToHiVisionTV; + } - if (XGINew_ReadWriteRest(8, 4, pVBInfo) == 1) - return; - else - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x39); - } else { /* DDR */ - XGINew_DataBusWidth = 64; /* 64 bits */ - XGINew_ChannelAB = 2; /* Dual channels */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x5A); + if (pVBInfo->IF_DEF_YPbPr == 1) { + if ((temp >> 8) & ActiveYPbPr) + tempch |= SetYPbPr; + } + } - if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1) - return; + tempcl |= SetSimuScanMode; + if ((!(temp & ActiveCRT1)) && ((temp & ActiveLCD) || (temp & ActiveTV) + || (temp & ActiveCRT2))) + tempcl ^= (SetSimuScanMode | SwitchToCRT2); + if ((temp & ActiveLCD) && (temp & ActiveTV)) + tempcl ^= (SetSimuScanMode | SwitchToCRT2); + XGINew_SetReg1(pVBInfo->P3d4, 0x30, tempcl); - XGINew_ChannelAB = 1; /* Single channels */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52); + CR31Data = XGINew_GetReg1(pVBInfo->P3d4, 0x31); + CR31Data &= ~(SetNotSimuMode >> 8); + if (!(temp & ActiveCRT1)) + CR31Data |= (SetNotSimuMode >> 8); + CR31Data &= ~(DisableCRT2Display >> 8); + if (!((temp & ActiveLCD) || (temp & ActiveTV) || (temp & ActiveCRT2))) + CR31Data |= (DisableCRT2Display >> 8); + XGINew_SetReg1(pVBInfo->P3d4, 0x31, CR31Data); - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x53); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; + CR38Data = XGINew_GetReg1(pVBInfo->P3d4, 0x38); + CR38Data &= ~SetYPbPr; + CR38Data |= tempch; + XGINew_SetReg1(pVBInfo->P3d4, 0x38, CR38Data); - XGINew_ChannelAB = 2; /* Dual channels */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4A); +} - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; +static void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension, + struct vb_device_info *pVBInfo) +{ + unsigned char Temp; + volatile unsigned char *pVideoMemory = + (unsigned char *) pVBInfo->ROMAddr; - XGINew_ChannelAB = 1; /* Single channels */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42); + pVBInfo->IF_DEF_LVDS = 0; - if (XGINew_ReadWriteRest(8, 4, pVBInfo) == 1) - return; +#if 1 + if ((pVideoMemory[0x65] & 0x01)) { /* For XG21 LVDS */ + pVBInfo->IF_DEF_LVDS = 1; + XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense); + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS on chip */ + } else { +#endif + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* Enable GPIOA/B read */ + Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0xC0; + if (Temp == 0xC0) { /* DVI & DVO GPIOA/B pull high */ + XGINew_SenseLCD(HwDeviceExtension, pVBInfo); + XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense); + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x20, 0x20); /* Enable read GPIOF */ + Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0x04; + if (!Temp) + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0x80); /* TMDS on chip */ else - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x43); + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* Only DVO on chip */ + XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); /* Disable read GPIOF */ } +#if 1 + } +#endif +} - break; +static void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension, + struct vb_device_info *pVBInfo) +{ + unsigned char Temp, bCR4A; - case XG42: - /* - XG42 SR14 D[3] Reserve - D[2] = 1, Dual Channel - = 0, Single Channel + pVBInfo->IF_DEF_LVDS = 0; + bCR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A); + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x07, 0x07); /* Enable GPIOA/B/C read */ + Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0x07; + XGINew_SetReg1(pVBInfo->P3d4, 0x4A, bCR4A); - It's Different from Other XG40 Series. - */ - if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII, DDR2x */ - XGINew_DataBusWidth = 32; /* 32 bits */ - XGINew_ChannelAB = 2; /* 2 Channel */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x44); + if (Temp <= 0x02) { + pVBInfo->IF_DEF_LVDS = 1; + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS setting */ + XGINew_SetReg1(pVBInfo->P3d4, 0x30, 0x21); + } else { + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* TMDS/DVO setting */ + } + XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense); - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; +} - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x34); - if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) - return; +static unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo) +{ + unsigned char CR38, CR4A, temp; - XGINew_ChannelAB = 1; /* Single Channel */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x40); + CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A); + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x10, 0x10); /* enable GPIOE read */ + CR38 = XGINew_GetReg1(pVBInfo->P3d4, 0x38); + temp = 0; + if ((CR38 & 0xE0) > 0x80) { + temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); + temp &= 0x08; + temp >>= 3; + } - if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) - return; - else { - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x30); - } - } else { /* DDR */ - XGINew_DataBusWidth = 64; /* 64 bits */ - XGINew_ChannelAB = 1; /* 1 channels */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52); + XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A); - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - else { - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42); - } - } + return temp; +} - break; +static unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo) +{ + unsigned char CR4A, temp; - default: /* XG40 */ + CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A); + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* enable GPIOA/B/C read */ + temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); + if (temp <= 2) + temp &= 0x03; + else + temp = ((temp & 0x04) >> 1) || ((~temp) & 0x01); - if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII */ - XGINew_DataBusWidth = 32; /* 32 bits */ - XGINew_ChannelAB = 3; - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4C); + XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A); - if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1) - return; + return temp; +} - XGINew_ChannelAB = 2; /* 2 channels */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x48); +unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) +{ + struct vb_device_info VBINF; + struct vb_device_info *pVBInfo = &VBINF; + unsigned char i, temp = 0, temp1; + /* VBIOSVersion[5]; */ + volatile unsigned char *pVideoMemory; - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; + /* unsigned long j, k; */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x3C); + unsigned long Temp; - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) { - XGINew_ChannelAB = 3; /* 4 channels */ - } else { - XGINew_ChannelAB = 2; /* 2 channels */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x38); - } - } else { /* DDR */ - XGINew_DataBusWidth = 64; /* 64 bits */ - XGINew_ChannelAB = 2; /* 2 channels */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x5A); + pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase; - if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1) { - return; - } else { - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4A); - } - } - break; - } -} + pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; -static int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - int i; - unsigned short memsize, addr; + pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress; - XGINew_SetReg1(pVBInfo->P3c4, 0x15, 0x00); /* noninterleaving */ - XGINew_SetReg1(pVBInfo->P3c4, 0x1C, 0x00); /* nontiling */ - XGINew_CheckChannel(HwDeviceExtension, pVBInfo); + pVideoMemory = (unsigned char *) pVBInfo->ROMAddr; - if (HwDeviceExtension->jChipType >= XG20) { - for (i = 0; i < 12; i++) { - XGINew_SetDRAMSizingType(i, XGINew_DDRDRAM_TYPE20, pVBInfo); - memsize = XGINew_SetDRAMSize20Reg(i, XGINew_DDRDRAM_TYPE20, pVBInfo); - if (memsize == 0) - continue; + /* Newdebugcode(0x99); */ - addr = memsize + (XGINew_ChannelAB - 2) + 20; - if ((HwDeviceExtension->ulVideoMemorySize - 1) < (unsigned long) (1 << addr)) - continue; - if (XGINew_ReadWriteRest(addr, 5, pVBInfo) == 1) - return 1; - } - } else { - for (i = 0; i < 4; i++) { - XGINew_SetDRAMSizingType(i, XGINew_DDRDRAM_TYPE340, pVBInfo); - memsize = XGINew_SetDRAMSizeReg(i, XGINew_DDRDRAM_TYPE340, pVBInfo); + /* if (pVBInfo->ROMAddr == 0) */ + /* return(0); */ - if (memsize == 0) - continue; + if (pVBInfo->FBAddr == NULL) { + printk("\n pVBInfo->FBAddr == 0 "); + return 0; + } + printk("1"); + if (pVBInfo->BaseAddr == 0) { + printk("\npVBInfo->BaseAddr == 0 "); + return 0; + } + printk("2"); - addr = memsize + (XGINew_ChannelAB - 2) + 20; - if ((HwDeviceExtension->ulVideoMemorySize - 1) < (unsigned long) (1 << addr)) - continue; + XGINew_SetReg3((pVBInfo->BaseAddr + 0x12), 0x67); /* 3c2 <- 67 ,ynlai */ - if (XGINew_ReadWriteRest(addr, 9, pVBInfo) == 1) - return 1; - } - } - return 0; -} + pVBInfo->ISXPDOS = 0; + printk("3"); -static void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ + printk("4"); - XGINew_SetReg1(pVBInfo->P3c4, 0x28, pVBInfo->MCLKData[XGINew_RAMType].SR28); - XGINew_SetReg1(pVBInfo->P3c4, 0x29, pVBInfo->MCLKData[XGINew_RAMType].SR29); - XGINew_SetReg1(pVBInfo->P3c4, 0x2A, pVBInfo->MCLKData[XGINew_RAMType].SR2A); + /* VBIOSVersion[4] = 0x0; */ - XGINew_SetReg1(pVBInfo->P3c4, 0x2E, pVBInfo->ECLKData[XGINew_RAMType].SR2E); - XGINew_SetReg1(pVBInfo->P3c4, 0x2F, pVBInfo->ECLKData[XGINew_RAMType].SR2F); - XGINew_SetReg1(pVBInfo->P3c4, 0x30, pVBInfo->ECLKData[XGINew_RAMType].SR30); + /* 09/07/99 modify by domao */ - /* [Vicent] 2004/07/07, When XG42 ECLK = MCLK = 207MHz, Set SR32 D[1:0] = 10b */ - /* [Hsuan] 2004/08/20, Modify SR32 value, when MCLK=207MHZ, ELCK=250MHz, Set SR32 D[1:0] = 10b */ - if (HwDeviceExtension->jChipType == XG42) { - if ((pVBInfo->MCLKData[XGINew_RAMType].SR28 == 0x1C) - && (pVBInfo->MCLKData[XGINew_RAMType].SR29 == 0x01) - && (((pVBInfo->ECLKData[XGINew_RAMType].SR2E == 0x1C) - && (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01)) - || ((pVBInfo->ECLKData[XGINew_RAMType].SR2E == 0x22) - && (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01)))) - XGINew_SetReg1(pVBInfo->P3c4, 0x32, ((unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x32) & 0xFC) | 0x02); - } -} + pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14; + pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24; + pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10; + pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e; + pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12; + pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a; + pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16; + pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17; + pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18; + pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19; + pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A; + pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00; + pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04; + pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10; + pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12; + pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14; + pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2; + printk("5"); -static void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo) -{ - volatile unsigned char *pVideoMemory = (unsigned char *) pVBInfo->ROMAddr; - unsigned long i; - unsigned char j, k; - /* Volari customize data area end */ + if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */ + XGI_GetVBType(pVBInfo); /* Run XGI_GetVBType before InitTo330Pointer */ - if (ChipType == XG21) { - pVBInfo->IF_DEF_LVDS = 0; - if (pVideoMemory[0x65] & 0x1) { - pVBInfo->IF_DEF_LVDS = 1; - i = pVideoMemory[0x316] | (pVideoMemory[0x317] << 8); - j = pVideoMemory[i - 1]; - if (j != 0xff) { - k = 0; - do { - pVBInfo->XG21_LVDSCapList[k].LVDS_Capability - = pVideoMemory[i] | (pVideoMemory[i + 1] << 8); - pVBInfo->XG21_LVDSCapList[k].LVDSHT - = pVideoMemory[i + 2] | (pVideoMemory[i + 3] << 8); - pVBInfo->XG21_LVDSCapList[k].LVDSVT - = pVideoMemory[i + 4] | (pVideoMemory[i + 5] << 8); - pVBInfo->XG21_LVDSCapList[k].LVDSHDE - = pVideoMemory[i + 6] | (pVideoMemory[i + 7] << 8); - pVBInfo->XG21_LVDSCapList[k].LVDSVDE - = pVideoMemory[i + 8] | (pVideoMemory[i + 9] << 8); - pVBInfo->XG21_LVDSCapList[k].LVDSHFP - = pVideoMemory[i + 10] | (pVideoMemory[i + 11] << 8); - pVBInfo->XG21_LVDSCapList[k].LVDSVFP - = pVideoMemory[i + 12] | (pVideoMemory[i + 13] << 8); - pVBInfo->XG21_LVDSCapList[k].LVDSHSYNC - = pVideoMemory[i + 14] | (pVideoMemory[i + 15] << 8); - pVBInfo->XG21_LVDSCapList[k].LVDSVSYNC - = pVideoMemory[i + 16] | (pVideoMemory[i + 17] << 8); - pVBInfo->XG21_LVDSCapList[k].VCLKData1 - = pVideoMemory[i + 18]; - pVBInfo->XG21_LVDSCapList[k].VCLKData2 - = pVideoMemory[i + 19]; - pVBInfo->XG21_LVDSCapList[k].PSC_S1 - = pVideoMemory[i + 20]; - pVBInfo->XG21_LVDSCapList[k].PSC_S2 - = pVideoMemory[i + 21]; - pVBInfo->XG21_LVDSCapList[k].PSC_S3 - = pVideoMemory[i + 22]; - pVBInfo->XG21_LVDSCapList[k].PSC_S4 - = pVideoMemory[i + 23]; - pVBInfo->XG21_LVDSCapList[k].PSC_S5 - = pVideoMemory[i + 24]; - i += 25; - j--; - k++; - } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList) / sizeof(struct XGI21_LVDSCapStruct)))); - } else { - pVBInfo->XG21_LVDSCapList[0].LVDS_Capability - = pVideoMemory[i] | (pVideoMemory[i + 1] << 8); - pVBInfo->XG21_LVDSCapList[0].LVDSHT - = pVideoMemory[i + 2] | (pVideoMemory[i + 3] << 8); - pVBInfo->XG21_LVDSCapList[0].LVDSVT - = pVideoMemory[i + 4] | (pVideoMemory[i + 5] << 8); - pVBInfo->XG21_LVDSCapList[0].LVDSHDE - = pVideoMemory[i + 6] | (pVideoMemory[i + 7] << 8); - pVBInfo->XG21_LVDSCapList[0].LVDSVDE - = pVideoMemory[i + 8] | (pVideoMemory[i + 9] << 8); - pVBInfo->XG21_LVDSCapList[0].LVDSHFP - = pVideoMemory[i + 10] | (pVideoMemory[i + 11] << 8); - pVBInfo->XG21_LVDSCapList[0].LVDSVFP - = pVideoMemory[i + 12] | (pVideoMemory[i + 13] << 8); - pVBInfo->XG21_LVDSCapList[0].LVDSHSYNC - = pVideoMemory[i + 14] | (pVideoMemory[i + 15] << 8); - pVBInfo->XG21_LVDSCapList[0].LVDSVSYNC - = pVideoMemory[i + 16] | (pVideoMemory[i + 17] << 8); - pVBInfo->XG21_LVDSCapList[0].VCLKData1 - = pVideoMemory[i + 18]; - pVBInfo->XG21_LVDSCapList[0].VCLKData2 - = pVideoMemory[i + 19]; - pVBInfo->XG21_LVDSCapList[0].PSC_S1 - = pVideoMemory[i + 20]; - pVBInfo->XG21_LVDSCapList[0].PSC_S2 - = pVideoMemory[i + 21]; - pVBInfo->XG21_LVDSCapList[0].PSC_S3 - = pVideoMemory[i + 22]; - pVBInfo->XG21_LVDSCapList[0].PSC_S4 - = pVideoMemory[i + 23]; - pVBInfo->XG21_LVDSCapList[0].PSC_S5 - = pVideoMemory[i + 24]; - } - } + InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo); + + /* ReadVBIOSData */ + ReadVBIOSTablData(HwDeviceExtension->jChipType, pVBInfo); + + /* 1.Openkey */ + XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86); + printk("6"); + + /* GetXG21Sense (GPIO) */ + if (HwDeviceExtension->jChipType == XG21) + XGINew_GetXG21Sense(HwDeviceExtension, pVBInfo); + + if (HwDeviceExtension->jChipType == XG27) + XGINew_GetXG27Sense(HwDeviceExtension, pVBInfo); + + printk("7"); + + /* 2.Reset Extended register */ + + for (i = 0x06; i < 0x20; i++) + XGINew_SetReg1(pVBInfo->P3c4, i, 0); + + for (i = 0x21; i <= 0x27; i++) + XGINew_SetReg1(pVBInfo->P3c4, i, 0); + + /* for(i = 0x06; i <= 0x27; i++) */ + /* XGINew_SetReg1(pVBInfo->P3c4, i, 0); */ + + printk("8"); + + if ((HwDeviceExtension->jChipType >= XG20) || (HwDeviceExtension->jChipType >= XG40)) { + for (i = 0x31; i <= 0x3B; i++) + XGINew_SetReg1(pVBInfo->P3c4, i, 0); + } else { + for (i = 0x31; i <= 0x3D; i++) + XGINew_SetReg1(pVBInfo->P3c4, i, 0); } -} + printk("9"); -static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo) -{ + if (HwDeviceExtension->jChipType == XG42) /* [Hsuan] 2004/08/20 Auto over driver for XG42 */ + XGINew_SetReg1(pVBInfo->P3c4, 0x3B, 0xC0); - XGINew_SetReg1(P3c4, 0x18, 0x01); - XGINew_SetReg1(P3c4, 0x19, 0x40); - XGINew_SetReg1(P3c4, 0x16, 0x00); - XGINew_SetReg1(P3c4, 0x16, 0x80); - DelayUS(60); + /* for (i = 0x30; i <= 0x3F; i++) */ + /* XGINew_SetReg1(pVBInfo->P3d4, i, 0); */ - XGINew_SetReg1(P3c4, 0x18, 0x00); - XGINew_SetReg1(P3c4, 0x19, 0x40); - XGINew_SetReg1(P3c4, 0x16, 0x00); - XGINew_SetReg1(P3c4, 0x16, 0x80); - DelayUS(60); - XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ - /* XGINew_SetReg1(P3c4, 0x18, 0x31); */ - XGINew_SetReg1(P3c4, 0x19, 0x01); - XGINew_SetReg1(P3c4, 0x16, 0x03); - XGINew_SetReg1(P3c4, 0x16, 0x83); - DelayUS(1000); - XGINew_SetReg1(P3c4, 0x1B, 0x03); - DelayUS(500); - /* XGINew_SetReg1(P3c4, 0x18, 0x31); */ - XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ - XGINew_SetReg1(P3c4, 0x19, 0x00); - XGINew_SetReg1(P3c4, 0x16, 0x03); - XGINew_SetReg1(P3c4, 0x16, 0x83); - XGINew_SetReg1(P3c4, 0x1B, 0x00); -} + for (i = 0x79; i <= 0x7C; i++) + XGINew_SetReg1(pVBInfo->P3d4, i, 0); /* shampoo 0208 */ -static void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short tempbx = 0, temp, tempcx, CR3CData; + printk("10"); - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x32); + if (HwDeviceExtension->jChipType >= XG20) + XGINew_SetReg1(pVBInfo->P3d4, 0x97, *pVBInfo->pXGINew_CR97); - if (temp & Monitor1Sense) - tempbx |= ActiveCRT1; - if (temp & LCDSense) - tempbx |= ActiveLCD; - if (temp & Monitor2Sense) - tempbx |= ActiveCRT2; - if (temp & TVSense) { - tempbx |= ActiveTV; - if (temp & AVIDEOSense) - tempbx |= (ActiveAVideo << 8); - if (temp & SVIDEOSense) - tempbx |= (ActiveSVideo << 8); - if (temp & SCARTSense) - tempbx |= (ActiveSCART << 8); - if (temp & HiTVSense) - tempbx |= (ActiveHiTV << 8); - if (temp & YPbPrSense) - tempbx |= (ActiveYPbPr << 8); + /* 3.SetMemoryClock + + if (HwDeviceExtension->jChipType >= XG40) + XGINew_RAMType = (int)XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); + + if (HwDeviceExtension->jChipType < XG40) + XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo); */ + + printk("11"); + + /* 4.SetDefExt1Regs begin */ + XGINew_SetReg1(pVBInfo->P3c4, 0x07, *pVBInfo->pSR07); + if (HwDeviceExtension->jChipType == XG27) { + XGINew_SetReg1(pVBInfo->P3c4, 0x40, *pVBInfo->pSR40); + XGINew_SetReg1(pVBInfo->P3c4, 0x41, *pVBInfo->pSR41); } + XGINew_SetReg1(pVBInfo->P3c4, 0x11, 0x0F); + XGINew_SetReg1(pVBInfo->P3c4, 0x1F, *pVBInfo->pSR1F); + /* XGINew_SetReg1(pVBInfo->P3c4, 0x20, 0x20); */ + XGINew_SetReg1(pVBInfo->P3c4, 0x20, 0xA0); /* alan, 2001/6/26 Frame buffer can read/write SR20 */ + XGINew_SetReg1(pVBInfo->P3c4, 0x36, 0x70); /* Hsuan, 2006/01/01 H/W request for slow corner chip */ + if (HwDeviceExtension->jChipType == XG27) /* Alan 12/07/2006 */ + XGINew_SetReg1(pVBInfo->P3c4, 0x36, *pVBInfo->pSR36); - tempcx = XGINew_GetReg1(pVBInfo->P3d4, 0x3d); - tempcx |= (XGINew_GetReg1(pVBInfo->P3d4, 0x3e) << 8); + /* SR11 = 0x0F; */ + /* XGINew_SetReg1(pVBInfo->P3c4, 0x11, SR11); */ - if (tempbx & tempcx) { - CR3CData = XGINew_GetReg1(pVBInfo->P3d4, 0x3c); - if (!(CR3CData & DisplayDeviceFromCMOS)) { - tempcx = 0x1FF0; - if (*pVBInfo->pSoftSetting & ModeSoftSetting) - tempbx = 0x1FF0; + printk("12"); + + if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */ + /* Set AGP Rate */ + /* + temp1 = XGINew_GetReg1(pVBInfo->P3c4, 0x3B); + temp1 &= 0x02; + if (temp1 == 0x02) { + XGINew_SetReg4(0xcf8, 0x80000000); + ChipsetID = XGINew_GetReg3(0x0cfc); + XGINew_SetReg4(0xcf8, 0x8000002C); + VendorID = XGINew_GetReg3(0x0cfc); + VendorID &= 0x0000FFFF; + XGINew_SetReg4(0xcf8, 0x8001002C); + GraphicVendorID = XGINew_GetReg3(0x0cfc); + GraphicVendorID &= 0x0000FFFF; + + if (ChipsetID == 0x7301039) + XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x09); + + ChipsetID &= 0x0000FFFF; + + if ((ChipsetID == 0x700E) || (ChipsetID == 0x1022) || (ChipsetID == 0x1106) || (ChipsetID == 0x10DE)) { + if (ChipsetID == 0x1106) { + if ((VendorID == 0x1019) && (GraphicVendorID == 0x1019)) + XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0D); + else + XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0B); + } else { + XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0B); + } + } } - } else { - tempcx = 0x1FF0; - if (*pVBInfo->pSoftSetting & ModeSoftSetting) - tempbx = 0x1FF0; - } + */ - tempbx &= tempcx; - XGINew_SetReg1(pVBInfo->P3d4, 0x3d, (tempbx & 0x00FF)); - XGINew_SetReg1(pVBInfo->P3d4, 0x3e, ((tempbx & 0xFF00) >> 8)); -} + printk("13"); + + if (HwDeviceExtension->jChipType >= XG40) { + /* Set AGP customize registers (in SetDefAGPRegs) Start */ + for (i = 0x47; i <= 0x4C; i++) + XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[i - 0x47]); + + for (i = 0x70; i <= 0x71; i++) + XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[6 + i - 0x70]); + + for (i = 0x74; i <= 0x77; i++) + XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[8 + i - 0x74]); + /* Set AGP customize registers (in SetDefAGPRegs) End */ + /* [Hsuan]2004/12/14 AGP Input Delay Adjustment on 850 */ + /* XGINew_SetReg4(0xcf8 , 0x80000000); */ + /* ChipsetID = XGINew_GetReg3(0x0cfc); */ + /* if (ChipsetID == 0x25308086) */ + /* XGINew_SetReg1(pVBInfo->P3d4, 0x77, 0xF0); */ + + HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension, 0x50, 0, &Temp); /* Get */ + Temp >>= 20; + Temp &= 0xF; + + if (Temp == 1) + XGINew_SetReg1(pVBInfo->P3d4, 0x48, 0x20); /* CR48 */ + } + printk("14"); -static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short temp, tempcl = 0, tempch = 0, CR31Data, CR38Data; + if (HwDeviceExtension->jChipType < XG40) + XGINew_SetReg1(pVBInfo->P3d4, 0x49, pVBInfo->CR49[0]); + } /* != XG20 */ - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x3d); - temp |= XGINew_GetReg1(pVBInfo->P3d4, 0x3e) << 8; - temp |= (XGINew_GetReg1(pVBInfo->P3d4, 0x31) & (DriverMode >> 8)) << 8; + /* Set PCI */ + XGINew_SetReg1(pVBInfo->P3c4, 0x23, *pVBInfo->pSR23); + XGINew_SetReg1(pVBInfo->P3c4, 0x24, *pVBInfo->pSR24); + XGINew_SetReg1(pVBInfo->P3c4, 0x25, pVBInfo->SR25[0]); + printk("15"); - if (pVBInfo->IF_DEF_CRT2Monitor == 1) { - if (temp & ActiveCRT2) - tempcl = SetCRT2ToRAMDAC; - } + if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */ + /* Set VB */ + XGI_UnLockCRT2(HwDeviceExtension, pVBInfo); + XGINew_SetRegANDOR(pVBInfo->Part0Port, 0x3F, 0xEF, 0x00); /* alan, disable VideoCapture */ + XGINew_SetReg1(pVBInfo->Part1Port, 0x00, 0x00); + temp1 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x7B); /* chk if BCLK>=100MHz */ + temp = (unsigned char) ((temp1 >> 4) & 0x0F); - if (temp & ActiveLCD) { - tempcl |= SetCRT2ToLCD; - if (temp & DriverMode) { - if (temp & ActiveTV) { - tempch = SetToLCDA | EnableDualEdge; - temp ^= SetCRT2ToLCD; + XGINew_SetReg1(pVBInfo->Part1Port, 0x02, (*pVBInfo->pCRT2Data_1_2)); - if ((temp >> 8) & ActiveAVideo) - tempcl |= SetCRT2ToAVIDEO; - if ((temp >> 8) & ActiveSVideo) - tempcl |= SetCRT2ToSVIDEO; - if ((temp >> 8) & ActiveSCART) - tempcl |= SetCRT2ToSCART; + printk("16"); - if (pVBInfo->IF_DEF_HiVision == 1) { - if ((temp >> 8) & ActiveHiTV) - tempcl |= SetCRT2ToHiVisionTV; - } + XGINew_SetReg1(pVBInfo->Part1Port, 0x2E, 0x08); /* use VB */ + } /* != XG20 */ - if (pVBInfo->IF_DEF_YPbPr == 1) { - if ((temp >> 8) & ActiveYPbPr) - tempch |= SetYPbPr; - } - } - } + XGINew_SetReg1(pVBInfo->P3c4, 0x27, 0x1F); + + if ((HwDeviceExtension->jChipType == XG42) + && XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) != 0) { /* Not DDR */ + XGINew_SetReg1(pVBInfo->P3c4, 0x31, (*pVBInfo->pSR31 & 0x3F) | 0x40); + XGINew_SetReg1(pVBInfo->P3c4, 0x32, (*pVBInfo->pSR32 & 0xFC) | 0x01); } else { - if ((temp >> 8) & ActiveAVideo) - tempcl |= SetCRT2ToAVIDEO; - if ((temp >> 8) & ActiveSVideo) - tempcl |= SetCRT2ToSVIDEO; - if ((temp >> 8) & ActiveSCART) - tempcl |= SetCRT2ToSCART; + XGINew_SetReg1(pVBInfo->P3c4, 0x31, *pVBInfo->pSR31); + XGINew_SetReg1(pVBInfo->P3c4, 0x32, *pVBInfo->pSR32); + } + XGINew_SetReg1(pVBInfo->P3c4, 0x33, *pVBInfo->pSR33); + printk("17"); - if (pVBInfo->IF_DEF_HiVision == 1) { - if ((temp >> 8) & ActiveHiTV) - tempcl |= SetCRT2ToHiVisionTV; - } + /* + if (HwDeviceExtension->jChipType >= XG40) + SetPowerConsume (HwDeviceExtension, pVBInfo->P3c4); */ - if (pVBInfo->IF_DEF_YPbPr == 1) { - if ((temp >> 8) & ActiveYPbPr) - tempch |= SetYPbPr; + if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */ + if (XGI_BridgeIsOn(pVBInfo) == 1) { + if (pVBInfo->IF_DEF_LVDS == 0) { + XGINew_SetReg1(pVBInfo->Part2Port, 0x00, 0x1C); + XGINew_SetReg1(pVBInfo->Part4Port, 0x0D, *pVBInfo->pCRT2Data_4_D); + XGINew_SetReg1(pVBInfo->Part4Port, 0x0E, *pVBInfo->pCRT2Data_4_E); + XGINew_SetReg1(pVBInfo->Part4Port, 0x10, *pVBInfo->pCRT2Data_4_10); + XGINew_SetReg1(pVBInfo->Part4Port, 0x0F, 0x3F); + } + + XGI_LockCRT2(HwDeviceExtension, pVBInfo); } - } + } /* != XG20 */ + printk("18"); - tempcl |= SetSimuScanMode; - if ((!(temp & ActiveCRT1)) && ((temp & ActiveLCD) || (temp & ActiveTV) - || (temp & ActiveCRT2))) - tempcl ^= (SetSimuScanMode | SwitchToCRT2); - if ((temp & ActiveLCD) && (temp & ActiveTV)) - tempcl ^= (SetSimuScanMode | SwitchToCRT2); - XGINew_SetReg1(pVBInfo->P3d4, 0x30, tempcl); + if (HwDeviceExtension->jChipType < XG40) + XGINew_SetReg1(pVBInfo->P3d4, 0x83, 0x00); + printk("181"); - CR31Data = XGINew_GetReg1(pVBInfo->P3d4, 0x31); - CR31Data &= ~(SetNotSimuMode >> 8); - if (!(temp & ActiveCRT1)) - CR31Data |= (SetNotSimuMode >> 8); - CR31Data &= ~(DisableCRT2Display >> 8); - if (!((temp & ActiveLCD) || (temp & ActiveTV) || (temp & ActiveCRT2))) - CR31Data |= (DisableCRT2Display >> 8); - XGINew_SetReg1(pVBInfo->P3d4, 0x31, CR31Data); + printk("182"); - CR38Data = XGINew_GetReg1(pVBInfo->P3d4, 0x38); - CR38Data &= ~SetYPbPr; - CR38Data |= tempch; - XGINew_SetReg1(pVBInfo->P3d4, 0x38, CR38Data); + XGI_SenseCRT1(pVBInfo); -} + printk("183"); + /* XGINew_DetectMonitor(HwDeviceExtension); */ + pVBInfo->IF_DEF_CH7007 = 0; + if ((HwDeviceExtension->jChipType == XG21) && (pVBInfo->IF_DEF_CH7007)) { + printk("184"); + XGI_GetSenseStatus(HwDeviceExtension, pVBInfo); /* sense CRT2 */ + printk("185"); -static void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned char Temp; - volatile unsigned char *pVideoMemory = - (unsigned char *) pVBInfo->ROMAddr; + } + if (HwDeviceExtension->jChipType == XG21) { + printk("186"); - pVBInfo->IF_DEF_LVDS = 0; + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */ + temp = GetXG21FPBits(pVBInfo); + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~0x01, temp); + printk("187"); -#if 1 - if ((pVideoMemory[0x65] & 0x01)) { /* For XG21 LVDS */ - pVBInfo->IF_DEF_LVDS = 1; - XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS on chip */ - } else { -#endif - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* Enable GPIOA/B read */ - Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0xC0; - if (Temp == 0xC0) { /* DVI & DVO GPIOA/B pull high */ - XGINew_SenseLCD(HwDeviceExtension, pVBInfo); - XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x20, 0x20); /* Enable read GPIOF */ - Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0x04; - if (!Temp) - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0x80); /* TMDS on chip */ - else - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* Only DVO on chip */ - XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); /* Disable read GPIOF */ - } -#if 1 } -#endif -} + if (HwDeviceExtension->jChipType == XG27) { + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */ + temp = GetXG27FPBits(pVBInfo); + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~0x03, temp); + } + printk("19"); -static void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned char Temp, bCR4A; + if (HwDeviceExtension->jChipType >= XG40) { + if (HwDeviceExtension->jChipType >= XG40) + XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); - pVBInfo->IF_DEF_LVDS = 0; - bCR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x07, 0x07); /* Enable GPIOA/B/C read */ - Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0x07; - XGINew_SetReg1(pVBInfo->P3d4, 0x4A, bCR4A); + XGINew_SetDRAMDefaultRegister340(HwDeviceExtension, pVBInfo->P3d4, pVBInfo); - if (Temp <= 0x02) { - pVBInfo->IF_DEF_LVDS = 1; - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS setting */ - XGINew_SetReg1(pVBInfo->P3d4, 0x30, 0x21); - } else { - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* TMDS/DVO setting */ - } - XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense); + printk("20"); + XGINew_SetDRAMSize_340(HwDeviceExtension, pVBInfo); + printk("21"); + } /* XG40 */ -} + printk("22"); -static unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo) -{ - unsigned char CR38, CR4A, temp; + /* SetDefExt2Regs begin */ + /* + AGP = 1; + temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x3A); + temp &= 0x30; + if (temp == 0x30) + AGP = 0; - CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x10, 0x10); /* enable GPIOE read */ - CR38 = XGINew_GetReg1(pVBInfo->P3d4, 0x38); - temp = 0; - if ((CR38 & 0xE0) > 0x80) { - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); - temp &= 0x08; - temp >>= 3; - } + if (AGP == 0) + *pVBInfo->pSR21 &= 0xEF; - XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A); + XGINew_SetReg1(pVBInfo->P3c4, 0x21, *pVBInfo->pSR21); + if (AGP == 1) + *pVBInfo->pSR22 &= 0x20; + XGINew_SetReg1(pVBInfo->P3c4, 0x22, *pVBInfo->pSR22); + */ + /* base = 0x80000000; */ + /* OutPortLong(0xcf8, base); */ + /* Temp = (InPortLong(0xcfc) & 0xFFFF); */ + /* if (Temp == 0x1039) { */ + XGINew_SetReg1(pVBInfo->P3c4, 0x22, (unsigned char) ((*pVBInfo->pSR22) & 0xFE)); + /* } else { */ + /* XGINew_SetReg1(pVBInfo->P3c4, 0x22, *pVBInfo->pSR22); */ + /* } */ - return temp; -} + XGINew_SetReg1(pVBInfo->P3c4, 0x21, *pVBInfo->pSR21); -static unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo) -{ - unsigned char CR4A, temp; + printk("23"); - CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* enable GPIOA/B/C read */ - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); - if (temp <= 2) - temp &= 0x03; - else - temp = ((temp & 0x04) >> 1) || ((~temp) & 0x01); + XGINew_ChkSenseStatus(HwDeviceExtension, pVBInfo); + XGINew_SetModeScratch(HwDeviceExtension, pVBInfo); - XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A); + printk("24"); - return temp; -} + XGINew_SetReg1(pVBInfo->P3d4, 0x8c, 0x87); + XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x31); + printk("25"); + return 1; +} /* end of init */ -- cgit v1.2.3 From cc1e2398f757e2bf9fa3afd8166ae03e41f29502 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:07 +0200 Subject: staging: xgifb: vb_setmode: move functions to avoid forward declarations Move functions to avoid forward declarations. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 12469 +++++++++++++++++------------------ 1 file changed, 6178 insertions(+), 6291 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 542352449e28..693be078595b 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -19,118 +19,6 @@ #define XGI_MASK_DUAL_CHIP 0x04 /* SR3A */ #endif - - -static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, - unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - unsigned short *i, struct vb_device_info *pVBInfo); -static unsigned char XGI_GetModePtr(unsigned short ModeNo, - unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo); -static unsigned short XGI_GetOffset(unsigned short ModeNo, - unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo); -static unsigned short XGI_GetColorDepth(unsigned short ModeNo, - unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo); -static unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo); -static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, - unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo); -static void XGI_VBLongWait(struct vb_device_info *pVBInfo); -static void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBInfo); -static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -static void XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -static void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -static void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -static void XGI_AutoThreshold(struct vb_device_info *pVBInfo); -static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo); - -static void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -static void XGI_SetXG21LCD(struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex, unsigned short ModeNo); -static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -static void XGI_SetXG27LCD(struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex, unsigned short ModeNo); -static void XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex); -static void XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -static void XGI_SetMiscRegs(unsigned short StandTableIndex, struct vb_device_info *pVBInfo); -static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, unsigned short StandTableIndex, struct vb_device_info *pVBInfo); -static void XGI_SetATTRegs(unsigned short ModeNo, unsigned short StandTableIndex, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -static void XGI_SetGRCRegs(unsigned short StandTableIndex, struct vb_device_info *pVBInfo); -static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo); - -static void XGI_SetSync(unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo, struct xgi_hw_device_info *HwDeviceExtension); -static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, struct xgi_hw_device_info *HwDeviceExtension); -static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeNo, struct vb_device_info *pVBInfo); -static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -static void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -static void XGI_SetCRT1FIFO(unsigned short ModeNo, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); - -static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -static void XGI_WriteDAC(unsigned short dl, unsigned short ah, unsigned short al, unsigned short dh, struct vb_device_info *pVBInfo); -/*void XGI_ClearBuffer(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, struct vb_device_info *pVBInfo);*/ -static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -static void XGI_GetLVDSResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo); -static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo); -static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -static void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -static void XGI_GetLCDSync(unsigned short *HSyncWidth, unsigned short *VSyncWidth, struct vb_device_info *pVBInfo); -static void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -static void XGI_OEM310Setting(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -static void XGI_SetDelayComp(struct vb_device_info *pVBInfo); -static void XGI_SetLCDCap(struct vb_device_info *pVBInfo); -static void XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInfo); -static void XGI_SetLCDCap_B(unsigned short tempcx, struct vb_device_info *pVBInfo); -static void SetSpectrum(struct vb_device_info *pVBInfo); -static void XGI_SetAntiFlicker(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -static void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo); -static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char* tempcl, - unsigned char *tempch, struct vb_device_info *pVBInfo); -static void XGI_CloseCRTC(struct xgi_hw_device_info *, struct vb_device_info *pVBInfo); -static void XGI_GetRAMDAC2DATA(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo); -static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo); -static void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); -static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1, - struct vb_device_info *pVBInfo); -static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, - unsigned short ModeNo, - unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo); -static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0, - unsigned char *di_1, struct vb_device_info *pVBInfo); -static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo); -static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo); -static struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx, struct vb_device_info *pVBInfo); -static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo); -static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo); -static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo); -static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo); - static unsigned short XGINew_MDA_DAC[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, @@ -312,1486 +200,1233 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) } -unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension, - unsigned short ModeNo) +static unsigned char XGI_GetModePtr(unsigned short ModeNo, unsigned short ModeIdIndex, + struct vb_device_info *pVBInfo) { - unsigned short ModeIdIndex; - /* unsigned char *pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; */ - struct vb_device_info VBINF; - struct vb_device_info *pVBInfo = &VBINF; - pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase; - pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress; - pVBInfo->IF_DEF_LVDS = 0; - pVBInfo->IF_DEF_CH7005 = 0; - pVBInfo->IF_DEF_LCDA = 1; - pVBInfo->IF_DEF_CH7017 = 0; - pVBInfo->IF_DEF_CH7007 = 0; /* [Billy] 2007/05/14 */ - pVBInfo->IF_DEF_VideoCapture = 0; - pVBInfo->IF_DEF_ScaleLCD = 0; - pVBInfo->IF_DEF_OEMUtil = 0; - pVBInfo->IF_DEF_PWD = 0; + unsigned char index; - if (HwDeviceExtension->jChipType >= XG20) { /* kuku 2004/06/25 */ - pVBInfo->IF_DEF_YPbPr = 0; - pVBInfo->IF_DEF_HiVision = 0; - pVBInfo->IF_DEF_CRT2Monitor = 0; - pVBInfo->VBType = 0; /*set VBType default 0*/ - } else if (HwDeviceExtension->jChipType >= XG40) { - pVBInfo->IF_DEF_YPbPr = 1; - pVBInfo->IF_DEF_HiVision = 1; - pVBInfo->IF_DEF_CRT2Monitor = 1; - } else { - pVBInfo->IF_DEF_YPbPr = 1; - pVBInfo->IF_DEF_HiVision = 1; - pVBInfo->IF_DEF_CRT2Monitor = 0; + if (ModeNo <= 0x13) + index = pVBInfo->SModeIDTable[ModeIdIndex].St_StTableIndex; + else { + if (pVBInfo->ModeType <= 0x02) + index = 0x1B; /* 02 -> ModeEGA */ + else + index = 0x0F; } + return index; /* Get pVBInfo->StandTable index */ +} - pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14; - pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24; - pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10; - pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e; - pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12; - pVBInfo->P3cc = pVBInfo->BaseAddr + 0x1C; - pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a; - pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16; - pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17; - pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18; - pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19; - pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A; - pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00; - pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04; - pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10; - pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12; - pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14; - pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2; +/* +unsigned char XGI_SetBIOSData(unsigned short ModeNo, unsigned short ModeIdIndex) { + return (0); +} +*/ - if (HwDeviceExtension->jChipType == XG21) { /* for x86 Linux, XG21 LVDS */ - if ((XGINew_GetReg1(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) - pVBInfo->IF_DEF_LVDS = 1; - } - if (HwDeviceExtension->jChipType == XG27) { - if ((XGINew_GetReg1(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) { - if (XGINew_GetReg1(pVBInfo->P3d4, 0x30) & 0x20) - pVBInfo->IF_DEF_LVDS = 1; +/* unsigned char XGI_ClearBankRegs(unsigned short ModeNo, unsigned short ModeIdIndex) { + return( 0 ) ; +} +*/ + +static void XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex, + unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) +{ + unsigned char tempah, SRdata; + + unsigned short i, modeflag; + + if (ModeNo <= 0x13) + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; + else + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + + XGINew_SetReg1(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */ + tempah = pVBInfo->StandTable[StandTableIndex].SR[0]; + + i = SetCRT2ToLCDA; + if (pVBInfo->VBInfo & SetCRT2ToLCDA) { + tempah |= 0x01; + } else { + if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) { + if (pVBInfo->VBInfo & SetInSlaveMode) + tempah |= 0x01; } } - if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */ - XGI_GetVBType(pVBInfo); + tempah |= 0x20; /* screen off */ + XGINew_SetReg1(pVBInfo->P3c4, 0x01, tempah); /* Set SR1 */ - InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo); - if (ModeNo & 0x80) { - ModeNo = ModeNo & 0x7F; - /* XGINew_flag_clearbuffer = 0; */ + for (i = 02; i <= 04; i++) { + SRdata = pVBInfo->StandTable[StandTableIndex].SR[i - 1]; /* Get SR2,3,4 from file */ + XGINew_SetReg1(pVBInfo->P3c4, i, SRdata); /* Set SR2 3 4 */ } - /* else { - XGINew_flag_clearbuffer = 1; +} + +static void XGI_SetMiscRegs(unsigned short StandTableIndex, + struct vb_device_info *pVBInfo) +{ + unsigned char Miscdata; + + Miscdata = pVBInfo->StandTable[StandTableIndex].MISC; /* Get Misc from file */ + /* + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBInfo & SetCRT2ToLCDA) { + Miscdata |= 0x0C; + } } */ - XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86); - if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 1.Openkey */ - XGI_UnLockCRT2(HwDeviceExtension, pVBInfo); + XGINew_SetReg3(pVBInfo->P3c2, Miscdata); /* Set Misc(3c2) */ +} - XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo); +static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, + unsigned short StandTableIndex, struct vb_device_info *pVBInfo) +{ + unsigned char CRTCdata; + unsigned short i; - XGI_GetVGAType(HwDeviceExtension, pVBInfo); + CRTCdata = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); + CRTCdata &= 0x7f; + XGINew_SetReg1(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */ - if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */ - XGI_GetVBInfo(ModeNo, ModeIdIndex, HwDeviceExtension, pVBInfo); - XGI_GetTVInfo(ModeNo, ModeIdIndex, pVBInfo); - XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo); - XGI_DisableBridge(HwDeviceExtension, pVBInfo); - /* XGI_OpenCRTC(HwDeviceExtension, pVBInfo); */ + for (i = 0; i <= 0x18; i++) { + CRTCdata = pVBInfo->StandTable[StandTableIndex].CRTC[i]; /* Get CRTC from file */ + XGINew_SetReg1(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */ + } + /* + if ((HwDeviceExtension->jChipType == XGI_630) && (HwDeviceExtension->jChipRevision == 0x30)) { + if (pVBInfo->VBInfo & SetInSlaveMode) { + if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) { + XGINew_SetReg1(pVBInfo->P3d4, 0x18, 0xFE); + } + } + } + */ +} - if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) { - XGI_SetCRT1Group(HwDeviceExtension, ModeNo, - ModeIdIndex, pVBInfo); +static void XGI_SetATTRegs(unsigned short ModeNo, unsigned short StandTableIndex, + unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) +{ + unsigned char ARdata; + unsigned short i, modeflag; - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { - XGI_SetLCDAGroup(ModeNo, ModeIdIndex, - HwDeviceExtension, pVBInfo); - } - } else { - if (!(pVBInfo->VBInfo & SwitchToCRT2)) { - XGI_SetCRT1Group(HwDeviceExtension, ModeNo, - ModeIdIndex, pVBInfo); + if (ModeNo <= 0x13) + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; + else + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + + for (i = 0; i <= 0x13; i++) { + ARdata = pVBInfo->StandTable[StandTableIndex].ATTR[i]; + if (modeflag & Charx8Dot) { /* ifndef Dot9 */ + if (i == 0x13) { if (pVBInfo->VBInfo & SetCRT2ToLCDA) { - XGI_SetLCDAGroup(ModeNo, ModeIdIndex, - HwDeviceExtension, - pVBInfo); + ARdata = 0; + } else { + if (pVBInfo->VBInfo & (SetCRT2ToTV + | SetCRT2ToLCD)) { + if (pVBInfo->VBInfo + & SetInSlaveMode) + ARdata = 0; + } } } } - if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchToCRT2)) { - switch (HwDeviceExtension->ujVBChipID) { - case VB_CHIP_301: - XGI_SetCRT2Group301(ModeNo, HwDeviceExtension, - pVBInfo); /*add for CRT2 */ - break; + XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */ + XGINew_SetReg3(pVBInfo->P3c0, i); /* set index */ + XGINew_SetReg3(pVBInfo->P3c0, ARdata); /* set data */ + } - case VB_CHIP_302: - XGI_SetCRT2Group301(ModeNo, HwDeviceExtension, - pVBInfo); /*add for CRT2 */ - break; + XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */ + XGINew_SetReg3(pVBInfo->P3c0, 0x14); /* set index */ + XGINew_SetReg3(pVBInfo->P3c0, 0x00); /* set data */ + XGINew_GetReg2(pVBInfo->P3da); /* Enable Attribute */ + XGINew_SetReg3(pVBInfo->P3c0, 0x20); +} - default: - break; - } - } +static void XGI_SetGRCRegs(unsigned short StandTableIndex, + struct vb_device_info *pVBInfo) +{ + unsigned char GRdata; + unsigned short i; - XGI_SetCRT2ModeRegs(ModeNo, HwDeviceExtension, pVBInfo); - XGI_OEM310Setting(ModeNo, ModeIdIndex, pVBInfo); /*0212*/ - XGI_CloseCRTC(HwDeviceExtension, pVBInfo); - XGI_EnableBridge(HwDeviceExtension, pVBInfo); - } /* !XG20 */ - else { - if (pVBInfo->IF_DEF_LVDS == 1) - if (!XGI_XG21CheckLVDSMode(ModeNo, ModeIdIndex, pVBInfo)) - return 0; + for (i = 0; i <= 0x08; i++) { + GRdata = pVBInfo->StandTable[StandTableIndex].GRC[i]; /* Get GR from file */ + XGINew_SetReg1(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */ + } - if (ModeNo <= 0x13) { - pVBInfo->ModeType - = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag - & ModeInfoFlag; - } else { - pVBInfo->ModeType - = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag - & ModeInfoFlag; - } - - pVBInfo->SetFlag = 0; - if (pVBInfo->IF_DEF_CH7007 != 1) - pVBInfo->VBInfo = DisableCRT2Display; - - XGI_DisplayOff(HwDeviceExtension, pVBInfo); - - XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex, - pVBInfo); - - XGI_DisplayOn(HwDeviceExtension, pVBInfo); - /* - if (HwDeviceExtension->jChipType == XG21) - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0x80, 0x80); - */ + if (pVBInfo->ModeType > ModeVGA) { + GRdata = (unsigned char) XGINew_GetReg1(pVBInfo->P3ce, 0x05); + GRdata &= 0xBF; /* 256 color disable */ + XGINew_SetReg1(pVBInfo->P3ce, 0x05, GRdata); } +} - /* - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - } - pVBInfo->ModeType = modeflag&ModeInfoFlag; - pVBInfo->SetFlag = 0x00; - pVBInfo->VBInfo = DisableCRT2Display; - temp = XGINew_CheckMemorySize(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo); +static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo) +{ + unsigned short i; - if (temp == 0) - return (0); + for (i = 0x0A; i <= 0x0E; i++) + XGINew_SetReg1(pVBInfo->P3c4, i, 0x00); /* Clear SR0A-SR0E */ +} - XGI_DisplayOff(HwDeviceExtension, pVBInfo) ; - XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo); - XGI_DisplayOn(HwDeviceExtension, pVBInfo); - */ +static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo) +{ - XGI_UpdateModeInfo(HwDeviceExtension, pVBInfo); + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, 0x20); + XGINew_SetReg1(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[0].SR2B); + XGINew_SetReg1(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[0].SR2C); - if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */ - XGI_LockCRT2(HwDeviceExtension, pVBInfo); - } + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, 0x10); + XGINew_SetReg1(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[1].SR2B); + XGINew_SetReg1(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[1].SR2C); - return 1; + XGINew_SetRegAND(pVBInfo->P3c4, 0x31, ~0x30); + return 0; } -static void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension, - unsigned short ModeNo, unsigned short ModeIdIndex, +static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, + unsigned short ModeIdIndex, + unsigned short RefreshRateTableIndex, unsigned short *i, struct vb_device_info *pVBInfo) { - unsigned short StandTableIndex, RefreshRateTableIndex, b3CC, temp; - - unsigned short XGINew_P3cc = pVBInfo->P3cc; + unsigned short tempax, tempbx, resinfo, modeflag, infoflag; - /* XGINew_CRT1Mode = ModeNo; // SaveModeID */ - StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo); - /* XGI_SetBIOSData(ModeNo, ModeIdIndex); */ - /* XGI_ClearBankRegs(ModeNo, ModeIdIndex); */ - XGI_SetSeqRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo); - XGI_SetMiscRegs(StandTableIndex, pVBInfo); - XGI_SetCRTCRegs(HwDeviceExtension, StandTableIndex, pVBInfo); - XGI_SetATTRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo); - XGI_SetGRCRegs(StandTableIndex, pVBInfo); - XGI_ClearExt1Regs(pVBInfo); + if (ModeNo <= 0x13) + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */ + else + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - /* if (pVBInfo->IF_DEF_ExpLink) */ - if (HwDeviceExtension->jChipType == XG27) { - if (pVBInfo->IF_DEF_LVDS == 0) - XGI_SetDefaultVCLK(pVBInfo); - } + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + tempbx = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID; + tempax = 0; - temp = ~ProgrammingCRT2; - pVBInfo->SetFlag &= temp; - pVBInfo->SelectCRT2Rate = 0; + if (pVBInfo->IF_DEF_LVDS == 0) { + if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { + tempax |= SupportRAMDAC2; - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { - if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA - | SetInSlaveMode)) { - pVBInfo->SetFlag |= ProgrammingCRT2; + if (pVBInfo->VBType & VB_XGI301C) + tempax |= SupportCRT2in301C; } - } - RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, - ModeIdIndex, pVBInfo); - if (RefreshRateTableIndex != 0xFFFF) { - XGI_SetSync(RefreshRateTableIndex, pVBInfo); - XGI_SetCRT1CRTC(ModeNo, ModeIdIndex, RefreshRateTableIndex, - pVBInfo, HwDeviceExtension); - XGI_SetCRT1DE(HwDeviceExtension, ModeNo, ModeIdIndex, - RefreshRateTableIndex, pVBInfo); - XGI_SetCRT1Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex, - HwDeviceExtension, pVBInfo); - XGI_SetCRT1VCLK(ModeNo, ModeIdIndex, HwDeviceExtension, - RefreshRateTableIndex, pVBInfo); - } + if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* 301b */ + tempax |= SupportLCD; - if ((HwDeviceExtension->jChipType >= XG20) - && (HwDeviceExtension->jChipType < XG27)) { /* fix H/W DCLK/2 bug */ - if ((ModeNo == 0x00) | (ModeNo == 0x01)) { - XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x4E); - XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE9); - b3CC = (unsigned char) XGINew_GetReg2(XGINew_P3cc); - XGINew_SetReg3(XGINew_P3cc, (b3CC |= 0x0C)); - } else if ((ModeNo == 0x04) | (ModeNo == 0x05) | (ModeNo - == 0x0D)) { - XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x1B); - XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE3); - b3CC = (unsigned char) XGINew_GetReg2(XGINew_P3cc); - XGINew_SetReg3(XGINew_P3cc, (b3CC |= 0x0C)); + if (pVBInfo->LCDResInfo != Panel1280x1024) { + if (pVBInfo->LCDResInfo != Panel1280x960) { + if (pVBInfo->LCDInfo & LCDNonExpanding) { + if (resinfo >= 9) { + tempax = 0; + return 0; + } + } + } + } } - } - if (HwDeviceExtension->jChipType >= XG21) { - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38); - if (temp & 0xA0) { + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiTV */ + if ((pVBInfo->VBType & VB_XGI301LV) + && (pVBInfo->VBExtInfo == VB_YPbPr1080i)) { + tempax |= SupportYPbPr; + if (pVBInfo->VBInfo & SetInSlaveMode) { + if (resinfo == 4) + return 0; - /* XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); *//* Enable write GPIOF */ - /* XGINew_SetRegAND(pVBInfo->P3d4, 0x48, ~0x20); *//* P. DWN */ - /* XG21 CRT1 Timing */ - if (HwDeviceExtension->jChipType == XG27) - XGI_SetXG27CRTC(ModeNo, ModeIdIndex, - RefreshRateTableIndex, pVBInfo); - else - XGI_SetXG21CRTC(ModeNo, ModeIdIndex, - RefreshRateTableIndex, pVBInfo); + if (resinfo == 3) + return 0; - XGI_UpdateXG21CRTC(ModeNo, pVBInfo, - RefreshRateTableIndex); + if (resinfo > 7) + return 0; + } + } else { + tempax |= SupportHiVisionTV; + if (pVBInfo->VBInfo & SetInSlaveMode) { + if (resinfo == 4) + return 0; - if (HwDeviceExtension->jChipType == XG27) - XGI_SetXG27LCD(pVBInfo, RefreshRateTableIndex, - ModeNo); - else - XGI_SetXG21LCD(pVBInfo, RefreshRateTableIndex, - ModeNo); + if (resinfo == 3) { + if (pVBInfo->SetFlag + & TVSimuMode) + return 0; + } - if (pVBInfo->IF_DEF_LVDS == 1) { - if (HwDeviceExtension->jChipType == XG27) - XGI_SetXG27LVDSPara(ModeNo, - ModeIdIndex, pVBInfo); - else - XGI_SetXG21LVDSPara(ModeNo, - ModeIdIndex, pVBInfo); + if (resinfo > 7) + return 0; + } } - /* XGINew_SetRegOR(pVBInfo->P3d4, 0x48, 0x20); *//* P. ON */ - } - } + } else { + if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO + | SetCRT2ToSVIDEO | SetCRT2ToSCART + | SetCRT2ToYPbPr | SetCRT2ToHiVisionTV)) { + tempax |= SupportTV; - pVBInfo->SetFlag &= (~ProgrammingCRT2); - XGI_SetCRT1FIFO(ModeNo, HwDeviceExtension, pVBInfo); - XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeNo, ModeIdIndex, - RefreshRateTableIndex, pVBInfo); + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B + | VB_XGI301LV | VB_XGI302LV + | VB_XGI301C)) { + tempax |= SupportTV1024; + } - /* XGI_LoadCharacter(); //dif ifdef TVFont */ + if (!(pVBInfo->VBInfo & SetPALTV)) { + if (modeflag & NoSupportSimuTV) { + if (pVBInfo->VBInfo + & SetInSlaveMode) { + if (!(pVBInfo->VBInfo + & SetNotSimuMode)) { + return 0; + } + } + } + } + } + } + } else { /* for LVDS */ + if (pVBInfo->IF_DEF_CH7005 == 1) { + if (pVBInfo->VBInfo & SetCRT2ToTV) + tempax |= SupportCHTV; + } - XGI_LoadDAC(ModeNo, ModeIdIndex, pVBInfo); - /* XGI_ClearBuffer(HwDeviceExtension, ModeNo, pVBInfo); */ -} + if (pVBInfo->VBInfo & SetCRT2ToLCD) { + tempax |= SupportLCD; -static unsigned char XGI_GetModePtr(unsigned short ModeNo, unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned char index; + if (resinfo > 0x08) + return 0; /* 1024x768 */ - if (ModeNo <= 0x13) - index = pVBInfo->SModeIDTable[ModeIdIndex].St_StTableIndex; - else { - if (pVBInfo->ModeType <= 0x02) - index = 0x1B; /* 02 -> ModeEGA */ - else - index = 0x0F; - } - return index; /* Get pVBInfo->StandTable index */ -} + if (pVBInfo->LCDResInfo < Panel1024x768) { + if (resinfo > 0x07) + return 0; /* 800x600 */ -/* -unsigned char XGI_SetBIOSData(unsigned short ModeNo, unsigned short ModeIdIndex) { - return (0); -} -*/ - -/* unsigned char XGI_ClearBankRegs(unsigned short ModeNo, unsigned short ModeIdIndex) { - return( 0 ) ; -} -*/ - -static void XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex, - unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) -{ - unsigned char tempah, SRdata; - - unsigned short i, modeflag; - - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + if (resinfo == 0x04) + return 0; /* 512x384 */ + } + } + } - XGINew_SetReg1(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */ - tempah = pVBInfo->StandTable[StandTableIndex].SR[0]; + for (; pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID == tempbx; (*i)--) { + infoflag + = pVBInfo->RefIndex[RefreshRateTableIndex + + (*i)].Ext_InfoFlag; + if (infoflag & tempax) + return 1; - i = SetCRT2ToLCDA; - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { - tempah |= 0x01; - } else { - if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) { - if (pVBInfo->VBInfo & SetInSlaveMode) - tempah |= 0x01; - } + if ((*i) == 0) + break; } - tempah |= 0x20; /* screen off */ - XGINew_SetReg1(pVBInfo->P3c4, 0x01, tempah); /* Set SR1 */ + for ((*i) = 0;; (*i)++) { + infoflag + = pVBInfo->RefIndex[RefreshRateTableIndex + + (*i)].Ext_InfoFlag; + if (pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID + != tempbx) { + return 0; + } - for (i = 02; i <= 04; i++) { - SRdata = pVBInfo->StandTable[StandTableIndex].SR[i - 1]; /* Get SR2,3,4 from file */ - XGINew_SetReg1(pVBInfo->P3c4, i, SRdata); /* Set SR2 3 4 */ + if (infoflag & tempax) + return 1; } + return 1; } -static void XGI_SetMiscRegs(unsigned short StandTableIndex, +static void XGI_SetSync(unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - unsigned char Miscdata; - - Miscdata = pVBInfo->StandTable[StandTableIndex].MISC; /* Get Misc from file */ - /* - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { - Miscdata |= 0x0C; - } - } - */ + unsigned short sync, temp; - XGINew_SetReg3(pVBInfo->P3c2, Miscdata); /* Set Misc(3c2) */ + sync = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8; /* di+0x00 */ + sync &= 0xC0; + temp = 0x2F; + temp |= sync; + XGINew_SetReg3(pVBInfo->P3c2, temp); /* Set Misc(3c2) */ } -static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, - unsigned short StandTableIndex, struct vb_device_info *pVBInfo) +static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, + struct xgi_hw_device_info *HwDeviceExtension) { - unsigned char CRTCdata; - unsigned short i; + unsigned char data, data1, pushax; + unsigned short i, j; - CRTCdata = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); - CRTCdata &= 0x7f; - XGINew_SetReg1(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */ + /* XGINew_SetReg1(pVBInfo->P3d4, 0x51, 0); */ + /* XGINew_SetReg1(pVBInfo->P3d4, 0x56, 0); */ + /* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */ - for (i = 0; i <= 0x18; i++) { - CRTCdata = pVBInfo->StandTable[StandTableIndex].CRTC[i]; /* Get CRTC from file */ - XGINew_SetReg1(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */ - } - /* - if ((HwDeviceExtension->jChipType == XGI_630) && (HwDeviceExtension->jChipRevision == 0x30)) { - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) { - XGINew_SetReg1(pVBInfo->P3d4, 0x18, 0xFE); - } - } + data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); /* unlock cr0-7 */ + data &= 0x7F; + XGINew_SetReg1(pVBInfo->P3d4, 0x11, data); + + data = pVBInfo->TimingH[0].data[0]; + XGINew_SetReg1(pVBInfo->P3d4, 0, data); + + for (i = 0x01; i <= 0x04; i++) { + data = pVBInfo->TimingH[0].data[i]; + XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 1), data); } - */ -} -static void XGI_SetATTRegs(unsigned short ModeNo, unsigned short StandTableIndex, - unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) -{ - unsigned char ARdata; - unsigned short i, modeflag; + for (i = 0x05; i <= 0x06; i++) { + data = pVBInfo->TimingH[0].data[i]; + XGINew_SetReg1(pVBInfo->P3c4, (unsigned short) (i + 6), data); + } - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + j = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0e); + j &= 0x1F; + data = pVBInfo->TimingH[0].data[7]; + data &= 0xE0; + data |= j; + XGINew_SetReg1(pVBInfo->P3c4, 0x0e, data); - for (i = 0; i <= 0x13; i++) { - ARdata = pVBInfo->StandTable[StandTableIndex].ATTR[i]; - if (modeflag & Charx8Dot) { /* ifndef Dot9 */ - if (i == 0x13) { - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { - ARdata = 0; - } else { - if (pVBInfo->VBInfo & (SetCRT2ToTV - | SetCRT2ToLCD)) { - if (pVBInfo->VBInfo - & SetInSlaveMode) - ARdata = 0; - } - } - } + if (HwDeviceExtension->jChipType >= XG20) { + data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x04); + data = data - 1; + XGINew_SetReg1(pVBInfo->P3d4, 0x04, data); + data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x05); + data1 = data; + data1 &= 0xE0; + data &= 0x1F; + if (data == 0) { + pushax = data; + data = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, + 0x0c); + data &= 0xFB; + XGINew_SetReg1(pVBInfo->P3c4, 0x0c, data); + data = pushax; } - - XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */ - XGINew_SetReg3(pVBInfo->P3c0, i); /* set index */ - XGINew_SetReg3(pVBInfo->P3c0, ARdata); /* set data */ + data = data - 1; + data |= data1; + XGINew_SetReg1(pVBInfo->P3d4, 0x05, data); + data = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0e); + data = data >> 5; + data = data + 3; + if (data > 7) + data = data - 7; + data = data << 5; + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0e, ~0xE0, data); } - - XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */ - XGINew_SetReg3(pVBInfo->P3c0, 0x14); /* set index */ - XGINew_SetReg3(pVBInfo->P3c0, 0x00); /* set data */ - XGINew_GetReg2(pVBInfo->P3da); /* Enable Attribute */ - XGINew_SetReg3(pVBInfo->P3c0, 0x20); } -static void XGI_SetGRCRegs(unsigned short StandTableIndex, +static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeNo, struct vb_device_info *pVBInfo) { - unsigned char GRdata; - unsigned short i; + unsigned char data; + unsigned short i, j; - for (i = 0; i <= 0x08; i++) { - GRdata = pVBInfo->StandTable[StandTableIndex].GRC[i]; /* Get GR from file */ - XGINew_SetReg1(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */ + /* XGINew_SetReg1(pVBInfo->P3d4, 0x51, 0); */ + /* XGINew_SetReg1(pVBInfo->P3d4, 0x56, 0); */ + /* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */ + + for (i = 0x00; i <= 0x01; i++) { + data = pVBInfo->TimingV[0].data[i]; + XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 6), data); } - if (pVBInfo->ModeType > ModeVGA) { - GRdata = (unsigned char) XGINew_GetReg1(pVBInfo->P3ce, 0x05); - GRdata &= 0xBF; /* 256 color disable */ - XGINew_SetReg1(pVBInfo->P3ce, 0x05, GRdata); + for (i = 0x02; i <= 0x03; i++) { + data = pVBInfo->TimingV[0].data[i]; + XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 0x0e), data); } -} -static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo) -{ - unsigned short i; + for (i = 0x04; i <= 0x05; i++) { + data = pVBInfo->TimingV[0].data[i]; + XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 0x11), data); + } - for (i = 0x0A; i <= 0x0E; i++) - XGINew_SetReg1(pVBInfo->P3c4, i, 0x00); /* Clear SR0A-SR0E */ -} + j = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0a); + j &= 0xC0; + data = pVBInfo->TimingV[0].data[6]; + data &= 0x3F; + data |= j; + XGINew_SetReg1(pVBInfo->P3c4, 0x0a, data); -static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo) -{ + data = pVBInfo->TimingV[0].data[6]; + data &= 0x80; + data = data >> 2; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, 0x20); - XGINew_SetReg1(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[0].SR2B); - XGINew_SetReg1(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[0].SR2C); + if (ModeNo <= 0x13) + i = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; + else + i = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, 0x10); - XGINew_SetReg1(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[1].SR2B); - XGINew_SetReg1(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[1].SR2C); + i &= DoubleScanMode; + if (i) + data |= 0x80; - XGINew_SetRegAND(pVBInfo->P3c4, 0x31, ~0x30); - return 0; + j = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x09); + j &= 0x5F; + data |= j; + XGINew_SetReg1(pVBInfo->P3d4, 0x09, data); } -unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, - unsigned short ModeNo, unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) +static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, + unsigned short RefreshRateTableIndex, + struct vb_device_info *pVBInfo, + struct xgi_hw_device_info *HwDeviceExtension) { - short LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01 }, - LCDARefreshIndex[] = { 0x00, 0x00, 0x03, 0x01, 0x01, - 0x01, 0x01 }; - - unsigned short RefreshRateTableIndex, i, modeflag, index, temp; - - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - if (pVBInfo->IF_DEF_CH7005 == 1) { - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (modeflag & HalfDCLK) - return 0; - } - } - - if (ModeNo < 0x14) - return 0xFFFF; - - index = XGINew_GetReg1(pVBInfo->P3d4, 0x33); - index = index >> pVBInfo->SelectCRT2Rate; - index &= 0x0F; - - if (pVBInfo->LCDInfo & LCDNonExpanding) - index = 0; + unsigned char index, data; + unsigned short i; - if (index > 0) - index--; + index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; /* Get index */ + index = index & IndexMask; - if (pVBInfo->SetFlag & ProgrammingCRT2) { - if (pVBInfo->IF_DEF_CH7005 == 1) { - if (pVBInfo->VBInfo & SetCRT2ToTV) - index = 0; - } + data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); + data &= 0x7F; + XGINew_SetReg1(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */ - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { - if (pVBInfo->IF_DEF_LVDS == 0) { - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B - | VB_XGI301LV | VB_XGI302LV - | VB_XGI301C)) - temp - = LCDARefreshIndex[pVBInfo->LCDResInfo - & 0x0F]; /* 301b */ - else - temp - = LCDRefreshIndex[pVBInfo->LCDResInfo - & 0x0F]; + for (i = 0; i < 8; i++) + pVBInfo->TimingH[0].data[i] + = pVBInfo->XGINEWUB_CRT1Table[index].CR[i]; - if (index > temp) - index = temp; - } else { - index = 0; - } - } - } + for (i = 0; i < 7; i++) + pVBInfo->TimingV[0].data[i] + = pVBInfo->XGINEWUB_CRT1Table[index].CR[i + 8]; - RefreshRateTableIndex = pVBInfo->EModeIDTable[ModeIdIndex].REFindex; - ModeNo = pVBInfo->RefIndex[RefreshRateTableIndex].ModeID; - if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */ - /* - if (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & XG2xNotSupport) { - index++; - } - */ - if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 800) - && (pVBInfo->RefIndex[RefreshRateTableIndex].YRes - == 600)) { - index++; - } - /* Alan 10/19/2007; do the similiar adjustment like XGISearchCRT1Rate() */ - if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1024) - && (pVBInfo->RefIndex[RefreshRateTableIndex].YRes - == 768)) { - index++; - } - if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1280) - && (pVBInfo->RefIndex[RefreshRateTableIndex].YRes - == 1024)) { - index++; - } - } + XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension); - i = 0; - do { - if (pVBInfo->RefIndex[RefreshRateTableIndex + i].ModeID - != ModeNo) - break; - temp - = pVBInfo->RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag; - temp &= ModeInfoFlag; - if (temp < pVBInfo->ModeType) - break; - i++; - index--; + XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo); - } while (index != 0xFFFF); - if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) { - if (pVBInfo->VBInfo & SetInSlaveMode) { - temp - = pVBInfo->RefIndex[RefreshRateTableIndex - + i - 1].Ext_InfoFlag; - if (temp & InterlaceMode) - i++; - } - } - i--; - if ((pVBInfo->SetFlag & ProgrammingCRT2)) { - temp = XGI_AjustCRT2Rate(ModeNo, ModeIdIndex, - RefreshRateTableIndex, &i, pVBInfo); - } - return RefreshRateTableIndex + i; /* return (0x01 | (temp1<<1)); */ + if (pVBInfo->ModeType > 0x03) + XGINew_SetReg1(pVBInfo->P3d4, 0x14, 0x4F); } -static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, - unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, unsigned short *i, +/* --------------------------------------------------------------------- */ +/* Function : XGI_SetXG21CRTC */ +/* Input : Stand or enhance CRTC table */ +/* Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F */ +/* Description : Set LCD timing */ +/* --------------------------------------------------------------------- */ +static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, + unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - unsigned short tempax, tempbx, resinfo, modeflag, infoflag; - - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */ - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + unsigned char StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx; + unsigned short Temp1, Temp2, Temp3; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - tempbx = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID; - tempax = 0; + if (ModeNo <= 0x13) { + StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo); + Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; /* CR04 HRS */ + XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E [7:0]->HRS */ + Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; /* Tempbx: CR05 HRE */ + Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */ + Tempcx = Tempax; + Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */ + Tempdx = Tempcx | Tempbx; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */ + if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */ + Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */ + Tempdx <<= 2; /* Tempdx << 2 */ + XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */ + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00); - if (pVBInfo->IF_DEF_LVDS == 0) { - if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { - tempax |= SupportRAMDAC2; + Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; /* Tempax: CR16 VRS */ + Tempbx = Tempax; /* Tempbx=Tempax */ + Tempax &= 0x01; /* Tempax: VRS[0] */ + XGINew_SetRegOR(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS */ + Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; /* Tempax: CR7 VRS */ + Tempdx = Tempbx >> 1; /* Tempdx: VRS[7:1] */ + Tempcx = Tempax & 0x04; /* Tempcx: CR7[2] */ + Tempcx <<= 5; /* Tempcx[7]: VRS[8] */ + Tempdx |= Tempcx; /* Tempdx: VRS[8:1] */ + XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempdx); /* SR34[7:0]: VRS[8:1] */ - if (pVBInfo->VBType & VB_XGI301C) - tempax |= SupportCRT2in301C; - } + Temp1 = Tempcx << 1; /* Temp1[8]: VRS[8] unsigned char -> unsigned short */ + Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */ + Tempax &= 0x80; /* Tempax[7]: CR7[7] */ + Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */ + Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */ - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* 301b */ - tempax |= SupportLCD; + Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17]; /* CR16 VRE */ + Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ + Temp2 = Temp1 & 0x3F0; /* Temp2[9:4]: VRS[9:4] */ + Temp2 |= Tempax; /* Temp2[9:0]: VRE[9:0] */ + Temp3 = Temp1 & 0x0F; /* Temp3[3:0]: VRS[3:0] */ + if (Tempax < Temp3) /* VRE[3:0]>= 9; /* [10:9]->[1:0] */ + Tempbx = (unsigned char) Temp1; /* Tempbx[1:0]: VRS[10:9] */ + Tempax |= Tempbx; /* VRE[5:0]VRS[10:9] */ + Tempax &= 0x7F; + XGINew_SetReg1(pVBInfo->P3c4, 0x3F, Tempax); /* SR3F D[7:2]->VRE D[1:0]->VRS */ + } else { + index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */ + Tempcx = Tempax; /* Tempcx: HRS */ + XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E[7:0]->HRS */ - if (pVBInfo->LCDResInfo != Panel1280x1024) { - if (pVBInfo->LCDResInfo != Panel1280x960) { - if (pVBInfo->LCDInfo & LCDNonExpanding) { - if (resinfo >= 9) { - tempax = 0; - return 0; - } - } - } - } - } + Tempdx = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SRB */ + Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */ + Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */ + Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */ + Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */ - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiTV */ - if ((pVBInfo->VBType & VB_XGI301LV) - && (pVBInfo->VBExtInfo == VB_YPbPr1080i)) { - tempax |= SupportYPbPr; - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (resinfo == 4) - return 0; + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */ + Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ - if (resinfo == 3) - return 0; + Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */ + Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */ + Tempbx <<= 3; /* Tempbx[5]: HRE[5] */ + Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */ - if (resinfo > 7) - return 0; - } - } else { - tempax |= SupportHiVisionTV; - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (resinfo == 4) - return 0; + Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */ + Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */ - if (resinfo == 3) { - if (pVBInfo->SetFlag - & TVSimuMode) - return 0; - } + Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */ + if (Tempax < Tempcx) /* HRE < HRS */ + Temp2 |= 0x40; /* Temp2 + 0x40 */ - if (resinfo > 7) - return 0; - } - } - } else { - if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO - | SetCRT2ToSVIDEO | SetCRT2ToSCART - | SetCRT2ToYPbPr | SetCRT2ToHiVisionTV)) { - tempax |= SupportTV; - - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B - | VB_XGI301LV | VB_XGI302LV - | VB_XGI301C)) { - tempax |= SupportTV1024; - } - - if (!(pVBInfo->VBInfo & SetPALTV)) { - if (modeflag & NoSupportSimuTV) { - if (pVBInfo->VBInfo - & SetInSlaveMode) { - if (!(pVBInfo->VBInfo - & SetNotSimuMode)) { - return 0; - } - } - } - } - } - } - } else { /* for LVDS */ - if (pVBInfo->IF_DEF_CH7005 == 1) { - if (pVBInfo->VBInfo & SetCRT2ToTV) - tempax |= SupportCHTV; - } - - if (pVBInfo->VBInfo & SetCRT2ToLCD) { - tempax |= SupportLCD; - - if (resinfo > 0x08) - return 0; /* 1024x768 */ - - if (pVBInfo->LCDResInfo < Panel1024x768) { - if (resinfo > 0x07) - return 0; /* 800x600 */ + Temp2 &= 0xFF; + Tempax = (unsigned char) Temp2; /* Tempax: HRE[7:0] */ + Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */ + Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */ + Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */ + XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F D[7:2]->HRE, D[1:0]->HRS */ + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00); - if (resinfo == 0x04) - return 0; /* 512x384 */ - } - } - } + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; /* CR10 VRS */ + Tempbx = Tempax; /* Tempbx: VRS */ + Tempax &= 0x01; /* Tempax[0]: VRS[0] */ + XGINew_SetRegOR(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; /* CR7[2][7] VRE */ + Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */ + Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */ + Tempdx <<= 5; /* Tempdx[7]: VRS[8] */ + Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */ + XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */ - for (; pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID == tempbx; (*i)--) { - infoflag - = pVBInfo->RefIndex[RefreshRateTableIndex - + (*i)].Ext_InfoFlag; - if (infoflag & tempax) - return 1; + Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */ + Temp1 <<= 1; /* Temp1[8]: VRS[8] */ + Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */ + Tempax &= 0x80; + Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */ + Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempax: SRA */ + Tempax &= 0x08; /* Tempax[3]: VRS[3] */ + Temp2 = Tempax; + Temp2 <<= 7; /* Temp2[10]: VRS[10] */ + Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */ - if ((*i) == 0) - break; - } + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; /* Tempax: CR11 VRE */ + Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ + Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempbx: SRA */ + Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */ + Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ + Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ + Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */ + Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */ - for ((*i) = 0;; (*i)++) { - infoflag - = pVBInfo->RefIndex[RefreshRateTableIndex - + (*i)].Ext_InfoFlag; - if (pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID - != tempbx) { - return 0; - } + Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */ + if (Tempax < Temp3) /* VRE < VRS */ + Temp2 |= 0x20; /* VRE + 0x20 */ - if (infoflag & tempax) - return 1; + Temp2 &= 0xFF; + Tempax = (unsigned char) Temp2; /* Tempax: VRE[7:0] */ + Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */ + Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */ + Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */ + Tempbx = (unsigned char) Temp1; + Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */ + Tempax &= 0x7F; + XGINew_SetReg1(pVBInfo->P3c4, 0x3F, Tempax); /* SR3F D[7:2]->VRE D[1:0]->VRS */ } - return 1; } -static void XGI_SetSync(unsigned short RefreshRateTableIndex, +static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, + unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - unsigned short sync, temp; + unsigned short StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx; - sync = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8; /* di+0x00 */ - sync &= 0xC0; - temp = 0x2F; - temp |= sync; - XGINew_SetReg3(pVBInfo->P3c2, temp); /* Set Misc(3c2) */ -} + if (ModeNo <= 0x13) { + StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo); + Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; /* CR04 HRS */ + XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E [7:0]->HRS */ + Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; /* Tempbx: CR05 HRE */ + Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */ + Tempcx = Tempax; + Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */ + Tempdx = Tempcx | Tempbx; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */ + if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */ + Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */ + Tempdx <<= 2; /* Tempdx << 2 */ + XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */ + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00); -static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo, - struct xgi_hw_device_info *HwDeviceExtension) -{ - unsigned char index, data; - unsigned short i; + Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; /* Tempax: CR10 VRS */ + XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS */ + Tempcx = Tempax; /* Tempcx=Tempax=VRS[7:0] */ + Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; /* Tempax[7][2]: CR7[7][2] VRS[9][8] */ + Tempbx = Tempax; /* Tempbx=CR07 */ + Tempax &= 0x04; /* Tempax[2]: CR07[2] VRS[8] */ + Tempax >>= 2; + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x01, Tempax); /* SR35 D[0]->VRS D[8] */ + Tempcx |= (Tempax << 8); /* Tempcx[8] |= VRS[8] */ + Tempcx |= (Tempbx & 0x80) << 2; /* Tempcx[9] |= VRS[9] */ - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; /* Get index */ - index = index & IndexMask; + Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17]; /* CR11 VRE */ + Tempax &= 0x0F; /* Tempax: VRE[3:0] */ + Tempbx = Tempcx; /* Tempbx=Tempcx=VRS[9:0] */ + Tempbx &= 0x3F0; /* Tempbx[9:4]: VRS[9:4] */ + Tempbx |= Tempax; /* Tempbx[9:0]: VRE[9:0] */ + if (Tempax <= (Tempcx & 0x0F)) /* VRE[3:0]<=VRS[3:0] */ + Tempbx |= 0x10; /* Tempbx: VRE + 0x10 */ + Tempax = (unsigned char) Tempbx & 0xFF; /* Tempax[7:0]: VRE[7:0] */ + Tempax <<= 2; /* Tempax << 2: VRE[5:0] */ + Tempcx = (Tempcx & 0x600) >> 8; /* Tempcx VRS[10:9] */ + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); /* SR3F D[7:2]->VRE D[5:0] */ + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x06, Tempcx); /* SR35 D[2:1]->VRS[10:9] */ + } else { + index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */ + Tempbx = Tempax; /* Tempbx: HRS[7:0] */ + XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E[7:0]->HRS */ - data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); - data &= 0x7F; - XGINew_SetReg1(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */ + Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ + Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */ - for (i = 0; i < 8; i++) - pVBInfo->TimingH[0].data[i] - = pVBInfo->XGINEWUB_CRT1Table[index].CR[i]; + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */ + Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ + Tempcx = Tempax; /* Tempcx: HRE[4:0] */ - for (i = 0; i < 7; i++) - pVBInfo->TimingV[0].data[i] - = pVBInfo->XGINEWUB_CRT1Table[index].CR[i + 8]; + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */ + Tempax &= 0x04; /* Tempax[2]: HRE[5] */ + Tempax <<= 3; /* Tempax[5]: HRE[5] */ + Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */ - XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension); + Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */ + Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */ - XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo); + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */ + Tempax &= 0x3F; /* Tempax: HRS[5:0] */ + if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */ + Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/ - if (pVBInfo->ModeType > 0x03) - XGINew_SetReg1(pVBInfo->P3d4, 0x14, 0x4F); -} + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */ + Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ + Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/ + Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */ + XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */ + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00); -static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, - struct xgi_hw_device_info *HwDeviceExtension) -{ - unsigned char data, data1, pushax; - unsigned short i, j; + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; /* CR10 VRS */ + XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS[7:0] */ - /* XGINew_SetReg1(pVBInfo->P3d4, 0x51, 0); */ - /* XGINew_SetReg1(pVBInfo->P3d4, 0x56, 0); */ - /* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */ + Tempcx = Tempax; /* Tempcx <= VRS[7:0] */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; /* CR7[7][2] VRS[9][8] */ + Tempbx = Tempax; /* Tempbx <= CR07[7:0] */ + Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */ + Tempax >>= 2; /* Tempax[0]: VRS[8] */ + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x01, Tempax); /* SR35[0]: VRS[8] */ + Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */ + Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempax: SR0A */ + Tempax &= 0x08; /* SR0A[3] VRS[10] */ + Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */ - data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); /* unlock cr0-7 */ - data &= 0x7F; - XGINew_SetReg1(pVBInfo->P3d4, 0x11, data); + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; /* Tempax: CR11 VRE */ + Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ + Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempbx: SR0A */ + Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */ + Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ + Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ + Tempbx = Tempcx; /* Tempbx: VRS[10:0] */ + Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */ + Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */ - data = pVBInfo->TimingH[0].data[0]; - XGINew_SetReg1(pVBInfo->P3d4, 0, data); + if (Tempbx <= Tempcx) /* VRE <= VRS */ + Tempbx |= 0x20; /* VRE + 0x20 */ - for (i = 0x01; i <= 0x04; i++) { - data = pVBInfo->TimingH[0].data[i]; - XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 1), data); + Tempax = (Tempbx << 2) & 0xFF; /* Tempax: Tempax[7:0]; VRE[5:0]00 */ + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); /* SR3F[7:2]:VRE[5:0] */ + Tempax = Tempcx >> 8; + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x07, Tempax); /* SR35[2:0]:VRS[10:8] */ } +} - for (i = 0x05; i <= 0x06; i++) { - data = pVBInfo->TimingH[0].data[i]; - XGINew_SetReg1(pVBInfo->P3c4, (unsigned short) (i + 6), data); +/* --------------------------------------------------------------------- */ +/* Function : XGI_SetXG21LCD */ +/* Input : */ +/* Output : FCLK duty cycle, FCLK delay compensation */ +/* Description : All values set zero */ +/* --------------------------------------------------------------------- */ +static void XGI_SetXG21LCD(struct vb_device_info *pVBInfo, + unsigned short RefreshRateTableIndex, unsigned short ModeNo) +{ + unsigned short Data, Temp, b3CC; + unsigned short XGI_P3cc; + + XGI_P3cc = pVBInfo->P3cc; + + XGINew_SetReg1(pVBInfo->P3d4, 0x2E, 0x00); + XGINew_SetReg1(pVBInfo->P3d4, 0x2F, 0x00); + XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x00); + XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x00); + if (((*pVBInfo->pDVOSetting) & 0xC0) == 0xC0) { + XGINew_SetReg1(pVBInfo->P3d4, 0x2E, *pVBInfo->pCR2E); + XGINew_SetReg1(pVBInfo->P3d4, 0x2F, *pVBInfo->pCR2F); + XGINew_SetReg1(pVBInfo->P3d4, 0x46, *pVBInfo->pCR46); + XGINew_SetReg1(pVBInfo->P3d4, 0x47, *pVBInfo->pCR47); } - j = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0e); - j &= 0x1F; - data = pVBInfo->TimingH[0].data[7]; - data &= 0xE0; - data |= j; - XGINew_SetReg1(pVBInfo->P3c4, 0x0e, data); + Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); - if (HwDeviceExtension->jChipType >= XG20) { - data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x04); - data = data - 1; - XGINew_SetReg1(pVBInfo->P3d4, 0x04, data); - data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x05); - data1 = data; - data1 &= 0xE0; - data &= 0x1F; - if (data == 0) { - pushax = data; - data = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, - 0x0c); - data &= 0xFB; - XGINew_SetReg1(pVBInfo->P3c4, 0x0c, data); - data = pushax; - } - data = data - 1; - data |= data1; - XGINew_SetReg1(pVBInfo->P3d4, 0x05, data); - data = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0e); - data = data >> 5; - data = data + 3; - if (data > 7) - data = data - 7; - data = data << 5; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0e, ~0xE0, data); + if (Temp & 0x01) { + XGINew_SetRegOR(pVBInfo->P3c4, 0x06, 0x40); /* 18 bits FP */ + XGINew_SetRegOR(pVBInfo->P3c4, 0x09, 0x40); + } + + XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */ + + XGINew_SetRegAND(pVBInfo->P3c4, 0x30, ~0x20); + XGINew_SetRegAND(pVBInfo->P3c4, 0x35, ~0x80); + + if (ModeNo <= 0x13) { + b3CC = (unsigned char) XGINew_GetReg2(XGI_P3cc); + if (b3CC & 0x40) + XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */ + if (b3CC & 0x80) + XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */ + } else { + Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + if (Data & 0x4000) + XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */ + if (Data & 0x8000) + XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */ } } -static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeNo, - struct vb_device_info *pVBInfo) +static void XGI_SetXG27LCD(struct vb_device_info *pVBInfo, + unsigned short RefreshRateTableIndex, unsigned short ModeNo) { - unsigned char data; - unsigned short i, j; + unsigned short Data, Temp, b3CC; + unsigned short XGI_P3cc; - /* XGINew_SetReg1(pVBInfo->P3d4, 0x51, 0); */ - /* XGINew_SetReg1(pVBInfo->P3d4, 0x56, 0); */ - /* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */ + XGI_P3cc = pVBInfo->P3cc; - for (i = 0x00; i <= 0x01; i++) { - data = pVBInfo->TimingV[0].data[i]; - XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 6), data); - } + XGINew_SetReg1(pVBInfo->P3d4, 0x2E, 0x00); + XGINew_SetReg1(pVBInfo->P3d4, 0x2F, 0x00); + XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x00); + XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x00); - for (i = 0x02; i <= 0x03; i++) { - data = pVBInfo->TimingV[0].data[i]; - XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 0x0e), data); + Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); + if ((Temp & 0x03) == 0) { /* dual 12 */ + XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x13); + XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x13); } - for (i = 0x04; i <= 0x05; i++) { - data = pVBInfo->TimingV[0].data[i]; - XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 0x11), data); + if (((*pVBInfo->pDVOSetting) & 0xC0) == 0xC0) { + XGINew_SetReg1(pVBInfo->P3d4, 0x2E, *pVBInfo->pCR2E); + XGINew_SetReg1(pVBInfo->P3d4, 0x2F, *pVBInfo->pCR2F); + XGINew_SetReg1(pVBInfo->P3d4, 0x46, *pVBInfo->pCR46); + XGINew_SetReg1(pVBInfo->P3d4, 0x47, *pVBInfo->pCR47); } - j = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0a); - j &= 0xC0; - data = pVBInfo->TimingV[0].data[6]; - data &= 0x3F; - data |= j; - XGINew_SetReg1(pVBInfo->P3c4, 0x0a, data); - - data = pVBInfo->TimingV[0].data[6]; - data &= 0x80; - data = data >> 2; + XGI_SetXG27FPBits(pVBInfo); - if (ModeNo <= 0x13) - i = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - i = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */ - i &= DoubleScanMode; - if (i) - data |= 0x80; + XGINew_SetRegAND(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */ + XGINew_SetRegAND(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */ - j = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x09); - j &= 0x5F; - data |= j; - XGINew_SetReg1(pVBInfo->P3d4, 0x09, data); + if (ModeNo <= 0x13) { + b3CC = (unsigned char) XGINew_GetReg2(XGI_P3cc); + if (b3CC & 0x40) + XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */ + if (b3CC & 0x80) + XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */ + } else { + Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + if (Data & 0x4000) + XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */ + if (Data & 0x8000) + XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */ + } } /* --------------------------------------------------------------------- */ -/* Function : XGI_SetXG21CRTC */ -/* Input : Stand or enhance CRTC table */ -/* Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F */ -/* Description : Set LCD timing */ +/* Function : XGI_UpdateXG21CRTC */ +/* Input : */ +/* Output : CRT1 CRTC */ +/* Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing */ /* --------------------------------------------------------------------- */ -static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVBInfo, + unsigned short RefreshRateTableIndex) +{ + int i, index = -1; + + XGINew_SetRegAND(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */ + if (ModeNo <= 0x13) { + for (i = 0; i < 12; i++) { + if (ModeNo == pVBInfo->UpdateCRT1[i].ModeID) + index = i; + } + } else { + if (ModeNo == 0x2E + && (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC + == RES640x480x60)) + index = 12; + else if (ModeNo == 0x2E + && (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC + == RES640x480x72)) + index = 13; + else if (ModeNo == 0x2F) + index = 14; + else if (ModeNo == 0x50) + index = 15; + else if (ModeNo == 0x59) + index = 16; + } + + if (index != -1) { + XGINew_SetReg1(pVBInfo->P3d4, 0x02, + pVBInfo->UpdateCRT1[index].CR02); + XGINew_SetReg1(pVBInfo->P3d4, 0x03, + pVBInfo->UpdateCRT1[index].CR03); + XGINew_SetReg1(pVBInfo->P3d4, 0x15, + pVBInfo->UpdateCRT1[index].CR15); + XGINew_SetReg1(pVBInfo->P3d4, 0x16, + pVBInfo->UpdateCRT1[index].CR16); + } +} + +static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, + unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - unsigned char StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx; - unsigned short Temp1, Temp2, Temp3; + unsigned short resindex, tempax, tempbx, tempcx, temp, modeflag; + + unsigned char data; + + resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); if (ModeNo <= 0x13) { - StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo); - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; /* CR04 HRS */ - XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E [7:0]->HRS */ - Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; /* Tempbx: CR05 HRE */ - Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */ - Tempcx = Tempax; - Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */ - Tempdx = Tempcx | Tempbx; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */ - if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */ - Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */ - Tempdx <<= 2; /* Tempdx << 2 */ - XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00); + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; + tempax = pVBInfo->StResInfo[resindex].HTotal; + tempbx = pVBInfo->StResInfo[resindex].VTotal; + } else { + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + tempax = pVBInfo->ModeResInfo[resindex].HTotal; + tempbx = pVBInfo->ModeResInfo[resindex].VTotal; + } - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; /* Tempax: CR16 VRS */ - Tempbx = Tempax; /* Tempbx=Tempax */ - Tempax &= 0x01; /* Tempax: VRS[0] */ - XGINew_SetRegOR(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS */ - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; /* Tempax: CR7 VRS */ - Tempdx = Tempbx >> 1; /* Tempdx: VRS[7:1] */ - Tempcx = Tempax & 0x04; /* Tempcx: CR7[2] */ - Tempcx <<= 5; /* Tempcx[7]: VRS[8] */ - Tempdx |= Tempcx; /* Tempdx: VRS[8:1] */ - XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempdx); /* SR34[7:0]: VRS[8:1] */ + if (modeflag & HalfDCLK) + tempax = tempax >> 1; - Temp1 = Tempcx << 1; /* Temp1[8]: VRS[8] unsigned char -> unsigned short */ - Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */ - Tempax &= 0x80; /* Tempax[7]: CR7[7] */ - Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */ - Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */ + if (ModeNo > 0x13) { + if (modeflag & HalfDCLK) + tempax = tempax << 1; - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17]; /* CR16 VRE */ - Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ - Temp2 = Temp1 & 0x3F0; /* Temp2[9:4]: VRS[9:4] */ - Temp2 |= Tempax; /* Temp2[9:0]: VRE[9:0] */ - Temp3 = Temp1 & 0x0F; /* Temp3[3:0]: VRS[3:0] */ - if (Tempax < Temp3) /* VRE[3:0]>= 9; /* [10:9]->[1:0] */ - Tempbx = (unsigned char) Temp1; /* Tempbx[1:0]: VRS[10:9] */ - Tempax |= Tempbx; /* VRE[5:0]VRS[10:9] */ - Tempax &= 0x7F; - XGINew_SetReg1(pVBInfo->P3c4, 0x3F, Tempax); /* SR3F D[7:2]->VRE D[1:0]->VRS */ - } else { - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */ - Tempcx = Tempax; /* Tempcx: HRS */ - XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E[7:0]->HRS */ + temp = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - Tempdx = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SRB */ - Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */ - Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */ - Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */ - Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */ + if (temp & InterlaceMode) + tempbx = tempbx >> 1; - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */ - Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ + if (modeflag & DoubleScanMode) + tempbx = tempbx << 1; + } - Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */ - Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */ - Tempbx <<= 3; /* Tempbx[5]: HRE[5] */ - Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */ + tempcx = 8; - Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */ - Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */ + /* if (!(modeflag & Charx8Dot)) */ + /* tempcx = 9; */ - Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */ - if (Tempax < Tempcx) /* HRE < HRS */ - Temp2 |= 0x40; /* Temp2 + 0x40 */ + tempax /= tempcx; + tempax -= 1; + tempbx -= 1; + tempcx = tempax; + temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); + data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); + data &= 0x7F; + XGINew_SetReg1(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */ + XGINew_SetReg1(pVBInfo->P3d4, 0x01, (unsigned short) (tempcx & 0xff)); + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x0b, ~0x0c, + (unsigned short) ((tempcx & 0x0ff00) >> 10)); + XGINew_SetReg1(pVBInfo->P3d4, 0x12, (unsigned short) (tempbx & 0xff)); + tempax = 0; + tempbx = tempbx >> 8; - Temp2 &= 0xFF; - Tempax = (unsigned char) Temp2; /* Tempax: HRE[7:0] */ - Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */ - Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */ - Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */ - XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F D[7:2]->HRE, D[1:0]->HRS */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00); + if (tempbx & 0x01) + tempax |= 0x02; - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; /* CR10 VRS */ - Tempbx = Tempax; /* Tempbx: VRS */ - Tempax &= 0x01; /* Tempax[0]: VRS[0] */ - XGINew_SetRegOR(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; /* CR7[2][7] VRE */ - Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */ - Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */ - Tempdx <<= 5; /* Tempdx[7]: VRS[8] */ - Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */ - XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */ + if (tempbx & 0x02) + tempax |= 0x40; - Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */ - Temp1 <<= 1; /* Temp1[8]: VRS[8] */ - Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */ - Tempax &= 0x80; - Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */ - Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempax: SRA */ - Tempax &= 0x08; /* Tempax[3]: VRS[3] */ - Temp2 = Tempax; - Temp2 <<= 7; /* Temp2[10]: VRS[10] */ - Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */ + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x42, tempax); + data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x07); + data &= 0xFF; + tempax = 0; - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; /* Tempax: CR11 VRE */ - Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ - Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempbx: SRA */ - Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */ - Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ - Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ - Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */ - Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */ + if (tempbx & 0x04) + tempax |= 0x02; - Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */ - if (Tempax < Temp3) /* VRE < VRS */ - Temp2 |= 0x20; /* VRE + 0x20 */ + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x0a, ~0x02, tempax); + XGINew_SetReg1(pVBInfo->P3d4, 0x11, temp); +} - Temp2 &= 0xFF; - Tempax = (unsigned char) Temp2; /* Tempax: VRE[7:0] */ - Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */ - Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */ - Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */ - Tempbx = (unsigned char) Temp1; - Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */ - Tempax &= 0x7F; - XGINew_SetReg1(pVBInfo->P3c4, 0x3F, Tempax); /* SR3F D[7:2]->VRE D[1:0]->VRS */ - } +unsigned short XGI_GetResInfo(unsigned short ModeNo, + unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) +{ + unsigned short resindex; + + if (ModeNo <= 0x13) + resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */ + else + resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */ + return resindex; } -static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, + struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - unsigned short StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx; - - if (ModeNo <= 0x13) { - StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo); - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; /* CR04 HRS */ - XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E [7:0]->HRS */ - Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; /* Tempbx: CR05 HRE */ - Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */ - Tempcx = Tempax; - Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */ - Tempdx = Tempcx | Tempbx; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */ - if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */ - Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */ - Tempdx <<= 2; /* Tempdx << 2 */ - XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00); + unsigned short temp, ah, al, temp2, i, DisplayUnit; - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; /* Tempax: CR10 VRS */ - XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS */ - Tempcx = Tempax; /* Tempcx=Tempax=VRS[7:0] */ - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; /* Tempax[7][2]: CR7[7][2] VRS[9][8] */ - Tempbx = Tempax; /* Tempbx=CR07 */ - Tempax &= 0x04; /* Tempax[2]: CR07[2] VRS[8] */ - Tempax >>= 2; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x01, Tempax); /* SR35 D[0]->VRS D[8] */ - Tempcx |= (Tempax << 8); /* Tempcx[8] |= VRS[8] */ - Tempcx |= (Tempbx & 0x80) << 2; /* Tempcx[9] |= VRS[9] */ + /* GetOffset */ + temp = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo; + temp = temp >> 8; + temp = pVBInfo->ScreenOffset[temp]; - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17]; /* CR11 VRE */ - Tempax &= 0x0F; /* Tempax: VRE[3:0] */ - Tempbx = Tempcx; /* Tempbx=Tempcx=VRS[9:0] */ - Tempbx &= 0x3F0; /* Tempbx[9:4]: VRS[9:4] */ - Tempbx |= Tempax; /* Tempbx[9:0]: VRE[9:0] */ - if (Tempax <= (Tempcx & 0x0F)) /* VRE[3:0]<=VRS[3:0] */ - Tempbx |= 0x10; /* Tempbx: VRE + 0x10 */ - Tempax = (unsigned char) Tempbx & 0xFF; /* Tempax[7:0]: VRE[7:0] */ - Tempax <<= 2; /* Tempax << 2: VRE[5:0] */ - Tempcx = (Tempcx & 0x600) >> 8; /* Tempcx VRS[10:9] */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); /* SR3F D[7:2]->VRE D[5:0] */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x06, Tempcx); /* SR35 D[2:1]->VRS[10:9] */ - } else { - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */ - Tempbx = Tempax; /* Tempbx: HRS[7:0] */ - XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E[7:0]->HRS */ + temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + temp2 &= InterlaceMode; - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */ - Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ - Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */ + if (temp2) + temp = temp << 1; - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */ - Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ - Tempcx = Tempax; /* Tempcx: HRE[4:0] */ + temp2 = pVBInfo->ModeType - ModeEGA; - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */ - Tempax &= 0x04; /* Tempax[2]: HRE[5] */ - Tempax <<= 3; /* Tempax[5]: HRE[5] */ - Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */ + switch (temp2) { + case 0: + temp2 = 1; + break; + case 1: + temp2 = 2; + break; + case 2: + temp2 = 4; + break; + case 3: + temp2 = 4; + break; + case 4: + temp2 = 6; + break; + case 5: + temp2 = 8; + break; + default: + break; + } - Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */ - Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */ + if ((ModeNo >= 0x26) && (ModeNo <= 0x28)) + temp = temp * temp2 + temp2 / 2; + else + temp *= temp2; - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */ - Tempax &= 0x3F; /* Tempax: HRS[5:0] */ - if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */ - Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/ + /* SetOffset */ + DisplayUnit = temp; + temp2 = temp; + temp = temp >> 8; /* ah */ + temp &= 0x0F; + i = XGINew_GetReg1(pVBInfo->P3c4, 0x0E); + i &= 0xF0; + i |= temp; + XGINew_SetReg1(pVBInfo->P3c4, 0x0E, i); - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */ - Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ - Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/ - Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */ - XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00); + temp = (unsigned char) temp2; + temp &= 0xFF; /* al */ + XGINew_SetReg1(pVBInfo->P3d4, 0x13, temp); - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; /* CR10 VRS */ - XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS[7:0] */ + /* SetDisplayUnit */ + temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + temp2 &= InterlaceMode; + if (temp2) + DisplayUnit >>= 1; - Tempcx = Tempax; /* Tempcx <= VRS[7:0] */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; /* CR7[7][2] VRS[9][8] */ - Tempbx = Tempax; /* Tempbx <= CR07[7:0] */ - Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */ - Tempax >>= 2; /* Tempax[0]: VRS[8] */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x01, Tempax); /* SR35[0]: VRS[8] */ - Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */ - Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempax: SR0A */ - Tempax &= 0x08; /* SR0A[3] VRS[10] */ - Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */ - - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; /* Tempax: CR11 VRE */ - Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ - Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempbx: SR0A */ - Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */ - Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ - Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ - Tempbx = Tempcx; /* Tempbx: VRS[10:0] */ - Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */ - Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */ + DisplayUnit = DisplayUnit << 5; + ah = (DisplayUnit & 0xff00) >> 8; + al = DisplayUnit & 0x00ff; + if (al == 0) + ah += 1; + else + ah += 2; - if (Tempbx <= Tempcx) /* VRE <= VRS */ - Tempbx |= 0x20; /* VRE + 0x20 */ + if (HwDeviceExtension->jChipType >= XG20) + if ((ModeNo == 0x4A) | (ModeNo == 0x49)) + ah -= 1; - Tempax = (Tempbx << 2) & 0xFF; /* Tempax: Tempax[7:0]; VRE[5:0]00 */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); /* SR3F[7:2]:VRE[5:0] */ - Tempax = Tempcx >> 8; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x07, Tempax); /* SR35[2:0]:VRS[10:8] */ - } + XGINew_SetReg1(pVBInfo->P3c4, 0x10, ah); } -/* --------------------------------------------------------------------- */ -/* Function : XGI_SetXG21LCD */ -/* Input : */ -/* Output : FCLK duty cycle, FCLK delay compensation */ -/* Description : All values set zero */ -/* --------------------------------------------------------------------- */ -static void XGI_SetXG21LCD(struct vb_device_info *pVBInfo, - unsigned short RefreshRateTableIndex, unsigned short ModeNo) +static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, + unsigned short ModeIdIndex, + unsigned short RefreshRateTableIndex, + struct xgi_hw_device_info *HwDeviceExtension, + struct vb_device_info *pVBInfo) { - unsigned short Data, Temp, b3CC; - unsigned short XGI_P3cc; - - XGI_P3cc = pVBInfo->P3cc; - - XGINew_SetReg1(pVBInfo->P3d4, 0x2E, 0x00); - XGINew_SetReg1(pVBInfo->P3d4, 0x2F, 0x00); - XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x00); - XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x00); - if (((*pVBInfo->pDVOSetting) & 0xC0) == 0xC0) { - XGINew_SetReg1(pVBInfo->P3d4, 0x2E, *pVBInfo->pCR2E); - XGINew_SetReg1(pVBInfo->P3d4, 0x2F, *pVBInfo->pCR2F); - XGINew_SetReg1(pVBInfo->P3d4, 0x46, *pVBInfo->pCR46); - XGINew_SetReg1(pVBInfo->P3d4, 0x47, *pVBInfo->pCR47); - } - - Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); - - if (Temp & 0x01) { - XGINew_SetRegOR(pVBInfo->P3c4, 0x06, 0x40); /* 18 bits FP */ - XGINew_SetRegOR(pVBInfo->P3c4, 0x09, 0x40); - } + unsigned short tempbx; - XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */ + unsigned short LCDXlat1VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2, + VCLK65 + 2 }; + unsigned short LCDXlat2VCLK[4] = { VCLK108_2 + 5, VCLK108_2 + 5, + VCLK108_2 + 5, VCLK108_2 + 5 }; + unsigned short LVDSXlat1VCLK[4] = { VCLK40, VCLK40, VCLK40, VCLK40 }; + unsigned short LVDSXlat2VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2, + VCLK65 + 2 }; + unsigned short LVDSXlat3VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2, + VCLK65 + 2 }; - XGINew_SetRegAND(pVBInfo->P3c4, 0x30, ~0x20); - XGINew_SetRegAND(pVBInfo->P3c4, 0x35, ~0x80); + unsigned short CRT2Index, VCLKIndex; + unsigned short modeflag, resinfo; + unsigned char *CHTVVCLKPtr = NULL; if (ModeNo <= 0x13) { - b3CC = (unsigned char) XGINew_GetReg2(XGI_P3cc); - if (b3CC & 0x40) - XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */ - if (b3CC & 0x80) - XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */ + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */ + resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; + CRT2Index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; } else { - Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - if (Data & 0x4000) - XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */ - if (Data & 0x8000) - XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */ + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + CRT2Index + = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; } -} - -static void XGI_SetXG27LCD(struct vb_device_info *pVBInfo, - unsigned short RefreshRateTableIndex, unsigned short ModeNo) -{ - unsigned short Data, Temp, b3CC; - unsigned short XGI_P3cc; - XGI_P3cc = pVBInfo->P3cc; + if (pVBInfo->IF_DEF_LVDS == 0) { + CRT2Index = CRT2Index >> 6; /* for LCD */ + if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /*301b*/ + if (pVBInfo->LCDResInfo != Panel1024x768) + VCLKIndex = LCDXlat2VCLK[CRT2Index]; + else + VCLKIndex = LCDXlat1VCLK[CRT2Index]; + } else { /* for TV */ + if (pVBInfo->VBInfo & SetCRT2ToTV) { + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + if (pVBInfo->SetFlag & RPLLDIV2XO) { + VCLKIndex = HiTVVCLKDIV2; - XGINew_SetReg1(pVBInfo->P3d4, 0x2E, 0x00); - XGINew_SetReg1(pVBInfo->P3d4, 0x2F, 0x00); - XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x00); - XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x00); + VCLKIndex += 25; - Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); - if ((Temp & 0x03) == 0) { /* dual 12 */ - XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x13); - XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x13); - } + } else { + VCLKIndex = HiTVVCLK; - if (((*pVBInfo->pDVOSetting) & 0xC0) == 0xC0) { - XGINew_SetReg1(pVBInfo->P3d4, 0x2E, *pVBInfo->pCR2E); - XGINew_SetReg1(pVBInfo->P3d4, 0x2F, *pVBInfo->pCR2F); - XGINew_SetReg1(pVBInfo->P3d4, 0x46, *pVBInfo->pCR46); - XGINew_SetReg1(pVBInfo->P3d4, 0x47, *pVBInfo->pCR47); - } + VCLKIndex += 25; - XGI_SetXG27FPBits(pVBInfo); + } - XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */ + if (pVBInfo->SetFlag & TVSimuMode) { + if (modeflag & Charx8Dot) { + VCLKIndex + = HiTVSimuVCLK; - XGINew_SetRegAND(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */ - XGINew_SetRegAND(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */ + VCLKIndex += 25; - if (ModeNo <= 0x13) { - b3CC = (unsigned char) XGINew_GetReg2(XGI_P3cc); - if (b3CC & 0x40) - XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */ - if (b3CC & 0x80) - XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */ - } else { - Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - if (Data & 0x4000) - XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */ - if (Data & 0x8000) - XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */ - } -} + } else { + VCLKIndex + = HiTVTextVCLK; -/* --------------------------------------------------------------------- */ -/* Function : XGI_UpdateXG21CRTC */ -/* Input : */ -/* Output : CRT1 CRTC */ -/* Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing */ -/* --------------------------------------------------------------------- */ -static void XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVBInfo, - unsigned short RefreshRateTableIndex) -{ - int i, index = -1; + VCLKIndex += 25; - XGINew_SetRegAND(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */ - if (ModeNo <= 0x13) { - for (i = 0; i < 12; i++) { - if (ModeNo == pVBInfo->UpdateCRT1[i].ModeID) - index = i; - } - } else { - if (ModeNo == 0x2E - && (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC - == RES640x480x60)) - index = 12; - else if (ModeNo == 0x2E - && (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC - == RES640x480x72)) - index = 13; - else if (ModeNo == 0x2F) - index = 14; - else if (ModeNo == 0x50) - index = 15; - else if (ModeNo == 0x59) - index = 16; - } + } + } - if (index != -1) { - XGINew_SetReg1(pVBInfo->P3d4, 0x02, - pVBInfo->UpdateCRT1[index].CR02); - XGINew_SetReg1(pVBInfo->P3d4, 0x03, - pVBInfo->UpdateCRT1[index].CR03); - XGINew_SetReg1(pVBInfo->P3d4, 0x15, - pVBInfo->UpdateCRT1[index].CR15); - XGINew_SetReg1(pVBInfo->P3d4, 0x16, - pVBInfo->UpdateCRT1[index].CR16); - } -} + if (pVBInfo->VBType & VB_XGI301LV) { /* 301lv */ + if (!(pVBInfo->VBExtInfo + == VB_YPbPr1080i)) { + VCLKIndex + = YPbPr750pVCLK; + if (!(pVBInfo->VBExtInfo + == VB_YPbPr750p)) { + VCLKIndex + = YPbPr525pVCLK; + if (!(pVBInfo->VBExtInfo + == VB_YPbPr525p)) { + VCLKIndex + = YPbPr525iVCLK_2; + if (!(pVBInfo->SetFlag + & RPLLDIV2XO)) + VCLKIndex + = YPbPr525iVCLK; + } + } + } + } + } else { + if (pVBInfo->VBInfo & SetCRT2ToTV) { + if (pVBInfo->SetFlag + & RPLLDIV2XO) { + VCLKIndex = TVVCLKDIV2; -static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, - unsigned short ModeNo, unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short resindex, tempax, tempbx, tempcx, temp, modeflag; + VCLKIndex += 25; - unsigned char data; + } else { + VCLKIndex = TVVCLK; - resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); + VCLKIndex += 25; - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - tempax = pVBInfo->StResInfo[resindex].HTotal; - tempbx = pVBInfo->StResInfo[resindex].VTotal; - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - tempax = pVBInfo->ModeResInfo[resindex].HTotal; - tempbx = pVBInfo->ModeResInfo[resindex].VTotal; - } - - if (modeflag & HalfDCLK) - tempax = tempax >> 1; - - if (ModeNo > 0x13) { - if (modeflag & HalfDCLK) - tempax = tempax << 1; - - temp = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - - if (temp & InterlaceMode) - tempbx = tempbx >> 1; - - if (modeflag & DoubleScanMode) - tempbx = tempbx << 1; - } - - tempcx = 8; - - /* if (!(modeflag & Charx8Dot)) */ - /* tempcx = 9; */ - - tempax /= tempcx; - tempax -= 1; - tempbx -= 1; - tempcx = tempax; - temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); - data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); - data &= 0x7F; - XGINew_SetReg1(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */ - XGINew_SetReg1(pVBInfo->P3d4, 0x01, (unsigned short) (tempcx & 0xff)); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x0b, ~0x0c, - (unsigned short) ((tempcx & 0x0ff00) >> 10)); - XGINew_SetReg1(pVBInfo->P3d4, 0x12, (unsigned short) (tempbx & 0xff)); - tempax = 0; - tempbx = tempbx >> 8; - - if (tempbx & 0x01) - tempax |= 0x02; - - if (tempbx & 0x02) - tempax |= 0x40; - - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x42, tempax); - data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x07); - data &= 0xFF; - tempax = 0; - - if (tempbx & 0x04) - tempax |= 0x02; - - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x0a, ~0x02, tempax); - XGINew_SetReg1(pVBInfo->P3d4, 0x11, temp); -} - -unsigned short XGI_GetResInfo(unsigned short ModeNo, - unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) -{ - unsigned short resindex; - - if (ModeNo <= 0x13) - resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */ - else - resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */ - return resindex; -} - -static void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short temp, ah, al, temp2, i, DisplayUnit; + } + } + } + } else { /* for CRT2 */ + VCLKIndex = (unsigned char) XGINew_GetReg2( + (pVBInfo->P3ca + 0x02)); /* Port 3cch */ + VCLKIndex = ((VCLKIndex >> 2) & 0x03); + if (ModeNo > 0x13) { + VCLKIndex + = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; /* di+Ext_CRTVCLK */ + VCLKIndex &= IndexMask; + } + } + } + } else { /* LVDS */ + if (ModeNo <= 0x13) + VCLKIndex = CRT2Index; + else + VCLKIndex = CRT2Index; - /* GetOffset */ - temp = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo; - temp = temp >> 8; - temp = pVBInfo->ScreenOffset[temp]; + if (pVBInfo->IF_DEF_CH7005 == 1) { + if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) { + VCLKIndex &= 0x1f; + tempbx = 0; - temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - temp2 &= InterlaceMode; + if (pVBInfo->VBInfo & SetPALTV) + tempbx += 2; - if (temp2) - temp = temp << 1; + if (pVBInfo->VBInfo & SetCHTVOverScan) + tempbx += 1; - temp2 = pVBInfo->ModeType - ModeEGA; + switch (tempbx) { + case 0: + CHTVVCLKPtr = pVBInfo->CHTVVCLKUNTSC; + break; + case 1: + CHTVVCLKPtr = pVBInfo->CHTVVCLKONTSC; + break; + case 2: + CHTVVCLKPtr = pVBInfo->CHTVVCLKUPAL; + break; + case 3: + CHTVVCLKPtr = pVBInfo->CHTVVCLKOPAL; + break; + default: + break; + } - switch (temp2) { - case 0: - temp2 = 1; - break; - case 1: - temp2 = 2; - break; - case 2: - temp2 = 4; - break; - case 3: - temp2 = 4; - break; - case 4: - temp2 = 6; - break; - case 5: - temp2 = 8; - break; - default: - break; + VCLKIndex = CHTVVCLKPtr[VCLKIndex]; + } + } else { + VCLKIndex = VCLKIndex >> 6; + if ((pVBInfo->LCDResInfo == Panel800x600) + || (pVBInfo->LCDResInfo == Panel320x480)) + VCLKIndex = LVDSXlat1VCLK[VCLKIndex]; + else if ((pVBInfo->LCDResInfo == Panel1024x768) + || (pVBInfo->LCDResInfo + == Panel1024x768x75)) + VCLKIndex = LVDSXlat2VCLK[VCLKIndex]; + else + VCLKIndex = LVDSXlat3VCLK[VCLKIndex]; + } } + /* VCLKIndex = VCLKIndex&IndexMask; */ - if ((ModeNo >= 0x26) && (ModeNo <= 0x28)) - temp = temp * temp2 + temp2 / 2; - else - temp *= temp2; - - /* SetOffset */ - DisplayUnit = temp; - temp2 = temp; - temp = temp >> 8; /* ah */ - temp &= 0x0F; - i = XGINew_GetReg1(pVBInfo->P3c4, 0x0E); - i &= 0xF0; - i |= temp; - XGINew_SetReg1(pVBInfo->P3c4, 0x0E, i); - - temp = (unsigned char) temp2; - temp &= 0xFF; /* al */ - XGINew_SetReg1(pVBInfo->P3d4, 0x13, temp); - - /* SetDisplayUnit */ - temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - temp2 &= InterlaceMode; - if (temp2) - DisplayUnit >>= 1; - - DisplayUnit = DisplayUnit << 5; - ah = (DisplayUnit & 0xff00) >> 8; - al = DisplayUnit & 0x00ff; - if (al == 0) - ah += 1; - else - ah += 2; - - if (HwDeviceExtension->jChipType >= XG20) - if ((ModeNo == 0x4A) | (ModeNo == 0x49)) - ah -= 1; - - XGINew_SetReg1(pVBInfo->P3c4, 0x10, ah); + return VCLKIndex; } static void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, @@ -1887,38 +1522,91 @@ static void XGI_SetCRT1FIFO(unsigned short ModeNo, XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */ } -static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, - unsigned short ModeNo, unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, +static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, + unsigned short ModeNo, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - unsigned short data, data2, data3, infoflag = 0, modeflag, resindex, - xres; + unsigned short data, data2 = 0; + short VCLK; - if (ModeNo > 0x13) { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - infoflag - = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - } else - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */ + unsigned char index; - if (XGINew_GetReg1(pVBInfo->P3d4, 0x31) & 0x01) - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1F, 0x3F, 0x00); + if (ModeNo <= 0x13) + VCLK = 0; + else { + index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; + index &= IndexMask; + VCLK = pVBInfo->VCLKData[index].CLOCK; + } - if (ModeNo > 0x13) - data = infoflag; - else - data = 0; + data = XGINew_GetReg1(pVBInfo->P3c4, 0x32); + data &= 0xf3; + if (VCLK >= 200) + data |= 0x0c; /* VCLK > 200 */ - data2 = 0; + if (HwDeviceExtension->jChipType >= XG20) + data &= ~0x04; /* 2 pixel mode */ - if (ModeNo > 0x13) { - if (pVBInfo->ModeType > 0x02) { - data2 |= 0x02; - data3 = pVBInfo->ModeType - ModeVGA; - data3 = data3 << 2; - data2 |= data3; - } + XGINew_SetReg1(pVBInfo->P3c4, 0x32, data); + + if (HwDeviceExtension->jChipType < XG20) { + data = XGINew_GetReg1(pVBInfo->P3c4, 0x1F); + data &= 0xE7; + if (VCLK < 200) + data |= 0x10; + XGINew_SetReg1(pVBInfo->P3c4, 0x1F, data); + } + + /* Jong for Adavantech LCD ripple issue + if ((VCLK >= 0) && (VCLK < 135)) + data2 = 0x03; + else if ((VCLK >= 135) && (VCLK < 160)) + data2 = 0x02; + else if ((VCLK >= 160) && (VCLK < 260)) + data2 = 0x01; + else if (VCLK > 260) + data2 = 0x00; + */ + data2 = 0x00; + + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x07, 0xFC, data2); + if (HwDeviceExtension->jChipType >= XG27) + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x40, 0xFC, data2 & 0x03); + +} + +static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, + unsigned short ModeNo, unsigned short ModeIdIndex, + unsigned short RefreshRateTableIndex, + struct vb_device_info *pVBInfo) +{ + unsigned short data, data2, data3, infoflag = 0, modeflag, resindex, + xres; + + if (ModeNo > 0x13) { + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + infoflag + = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + } else + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */ + + if (XGINew_GetReg1(pVBInfo->P3d4, 0x31) & 0x01) + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1F, 0x3F, 0x00); + + if (ModeNo > 0x13) + data = infoflag; + else + data = 0; + + data2 = 0; + + if (ModeNo > 0x13) { + if (pVBInfo->ModeType > 0x02) { + data2 |= 0x02; + data3 = pVBInfo->ModeType - ModeVGA; + data3 = data3 << 2; + data2 |= data3; + } } data &= InterlaceMode; @@ -2002,60 +1690,6 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, } -static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, - unsigned short ModeNo, unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short data, data2 = 0; - short VCLK; - - unsigned char index; - - if (ModeNo <= 0x13) - VCLK = 0; - else { - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; - index &= IndexMask; - VCLK = pVBInfo->VCLKData[index].CLOCK; - } - - data = XGINew_GetReg1(pVBInfo->P3c4, 0x32); - data &= 0xf3; - if (VCLK >= 200) - data |= 0x0c; /* VCLK > 200 */ - - if (HwDeviceExtension->jChipType >= XG20) - data &= ~0x04; /* 2 pixel mode */ - - XGINew_SetReg1(pVBInfo->P3c4, 0x32, data); - - if (HwDeviceExtension->jChipType < XG20) { - data = XGINew_GetReg1(pVBInfo->P3c4, 0x1F); - data &= 0xE7; - if (VCLK < 200) - data |= 0x10; - XGINew_SetReg1(pVBInfo->P3c4, 0x1F, data); - } - - /* Jong for Adavantech LCD ripple issue - if ((VCLK >= 0) && (VCLK < 135)) - data2 = 0x03; - else if ((VCLK >= 135) && (VCLK < 160)) - data2 = 0x02; - else if ((VCLK >= 160) && (VCLK < 260)) - data2 = 0x01; - else if (VCLK > 260) - data2 = 0x00; - */ - data2 = 0x00; - - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x07, 0xFC, data2); - if (HwDeviceExtension->jChipType >= XG27) - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x40, 0xFC, data2 & 0x03); - -} - - /* void XGI_VesaLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { @@ -2088,6 +1722,33 @@ void XGI_VesaLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, st } */ +static void XGI_WriteDAC(unsigned short dl, unsigned short ah, unsigned short al, + unsigned short dh, struct vb_device_info *pVBInfo) +{ + unsigned short temp, bh, bl; + + bh = ah; + bl = al; + + if (dl != 0) { + temp = bh; + bh = dh; + dh = temp; + if (dl == 1) { + temp = bl; + bl = dh; + dh = temp; + } else { + temp = bl; + bl = bh; + bh = temp; + } + } + XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) dh); + XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) bh); + XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) bl); +} + static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { @@ -2180,53 +1841,6 @@ static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex, } } -static void XGI_WriteDAC(unsigned short dl, unsigned short ah, unsigned short al, - unsigned short dh, struct vb_device_info *pVBInfo) -{ - unsigned short temp, bh, bl; - - bh = ah; - bl = al; - - if (dl != 0) { - temp = bh; - bh = dh; - dh = temp; - if (dl == 1) { - temp = bl; - bl = dh; - dh = temp; - } else { - temp = bl; - bl = bh; - bh = temp; - } - } - XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) dh); - XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) bh); - XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) bl); -} - -static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short RefreshRateTableIndex; - /* unsigned short temp ; */ - - /* pVBInfo->SelectCRT2Rate = 0; */ - - pVBInfo->SetFlag |= ProgrammingCRT2; - RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, - ModeIdIndex, pVBInfo); - XGI_GetLVDSResInfo(ModeNo, ModeIdIndex, pVBInfo); - XGI_GetLVDSData(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); - XGI_ModCRT1Regs(ModeNo, ModeIdIndex, RefreshRateTableIndex, - HwDeviceExtension, pVBInfo); - XGI_SetLVDSRegs(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); - XGI_SetCRT2ECLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); -} - static void XGI_GetLVDSResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { @@ -2276,4312 +1890,4394 @@ static void XGI_GetLVDSResInfo(unsigned short ModeNo, unsigned short ModeIdIndex pVBInfo->VDE = yres; } -static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, +static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, + unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - unsigned short tempbx; - struct XGI330_LVDSDataStruct *LCDPtr = NULL; - struct XGI330_CHTVDataStruct *TVPtr = NULL; + unsigned short i, tempdx, tempcx, tempbx, tempal, modeflag, table; - tempbx = 2; + struct XGI330_LCDDataTablStruct *tempdi = NULL; - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { - LCDPtr = (struct XGI330_LVDSDataStruct *) XGI_GetLcdPtr(tempbx, - ModeNo, ModeIdIndex, RefreshRateTableIndex, - pVBInfo); - pVBInfo->VGAHT = LCDPtr->VGAHT; - pVBInfo->VGAVT = LCDPtr->VGAVT; - pVBInfo->HT = LCDPtr->LCDHT; - pVBInfo->VT = LCDPtr->LCDVT; + tempbx = BX; + + if (ModeNo <= 0x13) { + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; + tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; + } else { + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; } - if (pVBInfo->IF_DEF_CH7017 == 1) { - if (pVBInfo->VBInfo & SetCRT2ToTV) { - TVPtr = (struct XGI330_CHTVDataStruct *) XGI_GetTVPtr( - tempbx, ModeNo, ModeIdIndex, - RefreshRateTableIndex, pVBInfo); - pVBInfo->VGAHT = TVPtr->VGAHT; - pVBInfo->VGAVT = TVPtr->VGAVT; - pVBInfo->HT = TVPtr->LCDHT; - pVBInfo->VT = TVPtr->LCDVT; + + tempal = tempal & 0x0f; + + if (tempbx <= 1) { /* ExpLink */ + if (ModeNo <= 0x13) { + tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; /* find no Ext_CRT2CRTC2 */ + } else { + tempal + = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; } - } - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { - if (!(pVBInfo->LCDInfo & (SetLCDtoNonExpanding - | EnableScalingLCD))) { - if ((pVBInfo->LCDResInfo == Panel1024x768) - || (pVBInfo->LCDResInfo - == Panel1024x768x75)) { - pVBInfo->HDE = 1024; - pVBInfo->VDE = 768; - } else if ((pVBInfo->LCDResInfo == Panel1280x1024) - || (pVBInfo->LCDResInfo - == Panel1280x1024x75)) { - pVBInfo->HDE = 1280; - pVBInfo->VDE = 1024; - } else if (pVBInfo->LCDResInfo == Panel1400x1050) { - pVBInfo->HDE = 1400; - pVBInfo->VDE = 1050; - } else { - pVBInfo->HDE = 1600; - pVBInfo->VDE = 1200; - } + if (pVBInfo->VBInfo & SetCRT2ToLCDA) { + if (ModeNo <= 0x13) + tempal + = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC2; + else + tempal + = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC2; } - } -} -static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned char index; - unsigned short tempbx, i; - struct XGI_LVDSCRT1HDataStruct *LCDPtr = NULL; - struct XGI_LVDSCRT1VDataStruct *LCDPtr1 = NULL; - /* struct XGI330_CHTVDataStruct *TVPtr = NULL; */ - struct XGI_CH7007TV_TimingHStruct *CH7007TV_TimingHPtr = NULL; - struct XGI_CH7007TV_TimingVStruct *CH7007TV_TimingVPtr = NULL; + if (tempbx & 0x01) + tempal = (tempal >> 4); - if (ModeNo <= 0x13) - index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; - else - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + tempal = (tempal & 0x0f); + } - index = index & IndexMask; + tempcx = LCDLenList[tempbx]; /* mov cl,byte ptr cs:LCDLenList[bx] */ - if ((pVBInfo->IF_DEF_ScaleLCD == 0) || ((pVBInfo->IF_DEF_ScaleLCD == 1) - && (!(pVBInfo->LCDInfo & EnableScalingLCD)))) { - tempbx = 0; + if (pVBInfo->LCDInfo & EnableScalingLCD) { /* ScaleLCD */ + if ((tempbx == 5) || (tempbx) == 7) + tempcx = LCDDesDataLen2; + else if ((tempbx == 3) || (tempbx == 8)) + tempcx = LVDSDesDataLen2; + } + /* mov di, word ptr cs:LCDDataList[bx] */ + /* tempdi = pVideoMemory[LCDDataList + tempbx * 2] | (pVideoMemory[LCDDataList + tempbx * 2 + 1] << 8); */ - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { - LCDPtr - = (struct XGI_LVDSCRT1HDataStruct *) XGI_GetLcdPtr( - tempbx, ModeNo, - ModeIdIndex, - RefreshRateTableIndex, - pVBInfo); + switch (tempbx) { + case 0: + tempdi = XGI_EPLLCDCRT1Ptr_H; + break; + case 1: + tempdi = XGI_EPLLCDCRT1Ptr_V; + break; + case 2: + tempdi = XGI_EPLLCDDataPtr; + break; + case 3: + tempdi = XGI_EPLLCDDesDataPtr; + break; + case 4: + tempdi = XGI_LCDDataTable; + break; + case 5: + tempdi = XGI_LCDDesDataTable; + break; + case 6: + tempdi = XGI_EPLCHLCDRegPtr; + break; + case 7: + case 8: + case 9: + tempdi = NULL; + break; + default: + break; + } - for (i = 0; i < 8; i++) - pVBInfo->TimingH[0].data[i] = LCDPtr[0].Reg[i]; - } + if (tempdi == NULL) /* OEMUtil */ + return NULL; - if (pVBInfo->IF_DEF_CH7007 == 1) { - if (pVBInfo->VBInfo & SetCRT2ToTV) { - CH7007TV_TimingHPtr - = (struct XGI_CH7007TV_TimingHStruct *) XGI_GetTVPtr( - tempbx, - ModeNo, - ModeIdIndex, - RefreshRateTableIndex, - pVBInfo); + table = tempbx; + i = 0; - for (i = 0; i < 8; i++) - pVBInfo->TimingH[0].data[i] - = CH7007TV_TimingHPtr[0].data[i]; - } + while (tempdi[i].PANELID != 0xff) { + tempdx = pVBInfo->LCDResInfo; + if (tempbx & 0x0080) { /* OEMUtil */ + tempbx &= (~0x0080); + tempdx = pVBInfo->LCDTypeInfo; } - /* if (pVBInfo->IF_DEF_CH7017 == 1) { - if (pVBInfo->VBInfo & SetCRT2ToTV) - TVPtr = (struct XGI330_CHTVDataStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); - } - */ + if (pVBInfo->LCDInfo & EnableScalingLCD) + tempdx &= (~PanelResInfo); - XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension); + if (tempdi[i].PANELID == tempdx) { + tempbx = tempdi[i].MASK; + tempdx = pVBInfo->LCDInfo; - if (pVBInfo->IF_DEF_CH7007 == 1) { - XGINew_SetReg1(pVBInfo->P3c4, 0x2E, - CH7007TV_TimingHPtr[0].data[8]); - XGINew_SetReg1(pVBInfo->P3c4, 0x2F, - CH7007TV_TimingHPtr[0].data[9]); - } + if (ModeNo <= 0x13) /* alan 09/10/2003 */ + tempdx |= SetLCDStdMode; - tempbx = 1; + if (modeflag & HalfDCLK) + tempdx |= SetLCDLowResolution; - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { - LCDPtr1 - = (struct XGI_LVDSCRT1VDataStruct *) XGI_GetLcdPtr( - tempbx, ModeNo, - ModeIdIndex, - RefreshRateTableIndex, - pVBInfo); - for (i = 0; i < 7; i++) - pVBInfo->TimingV[0].data[i] = LCDPtr1[0].Reg[i]; + tempbx &= tempdx; + if (tempbx == tempdi[i].CAP) + break; } + i++; + } - if (pVBInfo->IF_DEF_CH7007 == 1) { - if (pVBInfo->VBInfo & SetCRT2ToTV) { - CH7007TV_TimingVPtr - = (struct XGI_CH7007TV_TimingVStruct *) XGI_GetTVPtr( - tempbx, - ModeNo, - ModeIdIndex, - RefreshRateTableIndex, - pVBInfo); - - for (i = 0; i < 7; i++) - pVBInfo->TimingV[0].data[i] - = CH7007TV_TimingVPtr[0].data[i]; - } - } - /* if (pVBInfo->IF_DEF_CH7017 == 1) { - if (pVBInfo->VBInfo & SetCRT2ToTV) - TVPtr = (struct XGI330_CHTVDataStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); + if (table == 0) { + switch (tempdi[i].DATAPTR) { + case 0: + return &XGI_LVDSCRT11024x768_1_H[tempal]; + break; + case 1: + return &XGI_LVDSCRT11024x768_2_H[tempal]; + break; + case 2: + return &XGI_LVDSCRT11280x1024_1_H[tempal]; + break; + case 3: + return &XGI_LVDSCRT11280x1024_2_H[tempal]; + break; + case 4: + return &XGI_LVDSCRT11400x1050_1_H[tempal]; + break; + case 5: + return &XGI_LVDSCRT11400x1050_2_H[tempal]; + break; + case 6: + return &XGI_LVDSCRT11600x1200_1_H[tempal]; + break; + case 7: + return &XGI_LVDSCRT11024x768_1_Hx75[tempal]; + break; + case 8: + return &XGI_LVDSCRT11024x768_2_Hx75[tempal]; + break; + case 9: + return &XGI_LVDSCRT11280x1024_1_Hx75[tempal]; + break; + case 10: + return &XGI_LVDSCRT11280x1024_2_Hx75[tempal]; + break; + default: + break; } - */ - - XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo); - - if (pVBInfo->IF_DEF_CH7007 == 1) { - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x33, ~0x01, - CH7007TV_TimingVPtr[0].data[7] & 0x01); - XGINew_SetReg1(pVBInfo->P3c4, 0x34, - CH7007TV_TimingVPtr[0].data[8]); - XGINew_SetReg1(pVBInfo->P3c4, 0x3F, - CH7007TV_TimingVPtr[0].data[9]); - + } else if (table == 1) { + switch (tempdi[i].DATAPTR) { + case 0: + return &XGI_LVDSCRT11024x768_1_V[tempal]; + break; + case 1: + return &XGI_LVDSCRT11024x768_2_V[tempal]; + break; + case 2: + return &XGI_LVDSCRT11280x1024_1_V[tempal]; + break; + case 3: + return &XGI_LVDSCRT11280x1024_2_V[tempal]; + break; + case 4: + return &XGI_LVDSCRT11400x1050_1_V[tempal]; + break; + case 5: + return &XGI_LVDSCRT11400x1050_2_V[tempal]; + break; + case 6: + return &XGI_LVDSCRT11600x1200_1_V[tempal]; + break; + case 7: + return &XGI_LVDSCRT11024x768_1_Vx75[tempal]; + break; + case 8: + return &XGI_LVDSCRT11024x768_2_Vx75[tempal]; + break; + case 9: + return &XGI_LVDSCRT11280x1024_1_Vx75[tempal]; + break; + case 10: + return &XGI_LVDSCRT11280x1024_2_Vx75[tempal]; + break; + default: + break; } - } -} - -static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag; - unsigned long temp, temp1, temp2, temp3, push3; - struct XGI330_LCDDataDesStruct *LCDPtr = NULL; - struct XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL; - - if (ModeNo > 0x13) - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - else - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - - if (!(pVBInfo->SetFlag & Win9xDOSMode)) { - if ((pVBInfo->IF_DEF_CH7017 == 0) || (pVBInfo->VBInfo - & (SetCRT2ToLCD | SetCRT2ToLCDA))) { - if (pVBInfo->IF_DEF_OEMUtil == 1) { - tempbx = 8; - LCDPtr - = (struct XGI330_LCDDataDesStruct *) XGI_GetLcdPtr( - tempbx, - ModeNo, - ModeIdIndex, - RefreshRateTableIndex, - pVBInfo); - } - - if ((pVBInfo->IF_DEF_OEMUtil == 0) || (LCDPtr == NULL)) { - tempbx = 3; - if (pVBInfo->LCDInfo & EnableScalingLCD) - LCDPtr1 - = (struct XGI330_LCDDataDesStruct2 *) XGI_GetLcdPtr( - tempbx, - ModeNo, - ModeIdIndex, - RefreshRateTableIndex, - pVBInfo); - else - LCDPtr - = (struct XGI330_LCDDataDesStruct *) XGI_GetLcdPtr( - tempbx, - ModeNo, - ModeIdIndex, - RefreshRateTableIndex, - pVBInfo); - } - - XGI_GetLCDSync(&tempax, &tempbx, pVBInfo); - push1 = tempbx; - push2 = tempax; - - /* GetLCDResInfo */ - if ((pVBInfo->LCDResInfo == Panel1024x768) - || (pVBInfo->LCDResInfo - == Panel1024x768x75)) { - tempax = 1024; - tempbx = 768; - } else if ((pVBInfo->LCDResInfo == Panel1280x1024) - || (pVBInfo->LCDResInfo - == Panel1280x1024x75)) { - tempax = 1280; - tempbx = 1024; - } else if (pVBInfo->LCDResInfo == Panel1400x1050) { - tempax = 1400; - tempbx = 1050; - } else { - tempax = 1600; - tempbx = 1200; - } - - if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) { - pVBInfo->HDE = tempax; - pVBInfo->VDE = tempbx; - pVBInfo->VGAHDE = tempax; - pVBInfo->VGAVDE = tempbx; - } - - if ((pVBInfo->IF_DEF_ScaleLCD == 1) - && (pVBInfo->LCDInfo & EnableScalingLCD)) { - tempax = pVBInfo->HDE; - tempbx = pVBInfo->VDE; - } - - tempax = pVBInfo->HT; - - if (pVBInfo->LCDInfo & EnableScalingLCD) - tempbx = LCDPtr1->LCDHDES; + } else if (table == 2) { + switch (tempdi[i].DATAPTR) { + case 0: + return &XGI_LVDS1024x768Data_1[tempal]; + break; + case 1: + return &XGI_LVDS1024x768Data_2[tempal]; + break; + case 2: + return &XGI_LVDS1280x1024Data_1[tempal]; + break; + case 3: + return &XGI_LVDS1280x1024Data_2[tempal]; + break; + case 4: + return &XGI_LVDS1400x1050Data_1[tempal]; + break; + case 5: + return &XGI_LVDS1400x1050Data_2[tempal]; + break; + case 6: + return &XGI_LVDS1600x1200Data_1[tempal]; + break; + case 7: + return &XGI_LVDSNoScalingData[tempal]; + break; + case 8: + return &XGI_LVDS1024x768Data_1x75[tempal]; + break; + case 9: + return &XGI_LVDS1024x768Data_2x75[tempal]; + break; + case 10: + return &XGI_LVDS1280x1024Data_1x75[tempal]; + break; + case 11: + return &XGI_LVDS1280x1024Data_2x75[tempal]; + break; + case 12: + return &XGI_LVDSNoScalingDatax75[tempal]; + break; + default: + break; + } + } else if (table == 3) { + switch (tempdi[i].DATAPTR) { + case 0: + return &XGI_LVDS1024x768Des_1[tempal]; + break; + case 1: + return &XGI_LVDS1024x768Des_3[tempal]; + break; + case 2: + return &XGI_LVDS1024x768Des_2[tempal]; + break; + case 3: + return &XGI_LVDS1280x1024Des_1[tempal]; + break; + case 4: + return &XGI_LVDS1280x1024Des_2[tempal]; + break; + case 5: + return &XGI_LVDS1400x1050Des_1[tempal]; + break; + case 6: + return &XGI_LVDS1400x1050Des_2[tempal]; + break; + case 7: + return &XGI_LVDS1600x1200Des_1[tempal]; + break; + case 8: + return &XGI_LVDSNoScalingDesData[tempal]; + break; + case 9: + return &XGI_LVDS1024x768Des_1x75[tempal]; + break; + case 10: + return &XGI_LVDS1024x768Des_3x75[tempal]; + break; + case 11: + return &XGI_LVDS1024x768Des_2x75[tempal]; + break; + case 12: + return &XGI_LVDS1280x1024Des_1x75[tempal]; + break; + case 13: + return &XGI_LVDS1280x1024Des_2x75[tempal]; + break; + case 14: + return &XGI_LVDSNoScalingDesDatax75[tempal]; + break; + default: + break; + } + } else if (table == 4) { + switch (tempdi[i].DATAPTR) { + case 0: + return &XGI_ExtLCD1024x768Data[tempal]; + break; + case 1: + return &XGI_StLCD1024x768Data[tempal]; + break; + case 2: + return &XGI_CetLCD1024x768Data[tempal]; + break; + case 3: + return &XGI_ExtLCD1280x1024Data[tempal]; + break; + case 4: + return &XGI_StLCD1280x1024Data[tempal]; + break; + case 5: + return &XGI_CetLCD1280x1024Data[tempal]; + break; + case 6: + return &XGI_ExtLCD1400x1050Data[tempal]; + break; + case 7: + return &XGI_StLCD1400x1050Data[tempal]; + break; + case 8: + return &XGI_CetLCD1400x1050Data[tempal]; + break; + case 9: + return &XGI_ExtLCD1600x1200Data[tempal]; + break; + case 10: + return &XGI_StLCD1600x1200Data[tempal]; + break; + case 11: + return &XGI_NoScalingData[tempal]; + break; + case 12: + return &XGI_ExtLCD1024x768x75Data[tempal]; + break; + case 13: + return &XGI_ExtLCD1024x768x75Data[tempal]; + break; + case 14: + return &XGI_CetLCD1024x768x75Data[tempal]; + break; + case 15: + return &XGI_ExtLCD1280x1024x75Data[tempal]; + break; + case 16: + return &XGI_StLCD1280x1024x75Data[tempal]; + break; + case 17: + return &XGI_CetLCD1280x1024x75Data[tempal]; + break; + case 18: + return &XGI_NoScalingDatax75[tempal]; + break; + default: + break; + } + } else if (table == 5) { + switch (tempdi[i].DATAPTR) { + case 0: + return &XGI_ExtLCDDes1024x768Data[tempal]; + break; + case 1: + return &XGI_StLCDDes1024x768Data[tempal]; + break; + case 2: + return &XGI_CetLCDDes1024x768Data[tempal]; + break; + case 3: + if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType + & VB_XGI302LV)) + return &XGI_ExtLCDDLDes1280x1024Data[tempal]; else - tempbx = LCDPtr->LCDHDES; - - tempcx = pVBInfo->HDE; - tempbx = tempbx & 0x0fff; - tempcx += tempbx; - - if (tempcx >= tempax) - tempcx -= tempax; - - XGINew_SetReg1(pVBInfo->Part1Port, 0x1A, tempbx & 0x07); - - tempcx = tempcx >> 3; - tempbx = tempbx >> 3; - - XGINew_SetReg1(pVBInfo->Part1Port, 0x16, - (unsigned short) (tempbx & 0xff)); - XGINew_SetReg1(pVBInfo->Part1Port, 0x17, - (unsigned short) (tempcx & 0xff)); - - tempax = pVBInfo->HT; - - if (pVBInfo->LCDInfo & EnableScalingLCD) - tempbx = LCDPtr1->LCDHRS; + return &XGI_ExtLCDDes1280x1024Data[tempal]; + break; + case 4: + if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType + & VB_XGI302LV)) + return &XGI_StLCDDLDes1280x1024Data[tempal]; else - tempbx = LCDPtr->LCDHRS; - - tempcx = push2; - - if (pVBInfo->LCDInfo & EnableScalingLCD) - tempcx = LCDPtr1->LCDHSync; - - tempcx += tempbx; - - if (tempcx >= tempax) - tempcx -= tempax; - - tempax = tempbx & 0x07; - tempax = tempax >> 5; - tempcx = tempcx >> 3; - tempbx = tempbx >> 3; - - tempcx &= 0x1f; - tempax |= tempcx; - - XGINew_SetReg1(pVBInfo->Part1Port, 0x15, tempax); - XGINew_SetReg1(pVBInfo->Part1Port, 0x14, - (unsigned short) (tempbx & 0xff)); - - tempax = pVBInfo->VT; - if (pVBInfo->LCDInfo & EnableScalingLCD) - tempbx = LCDPtr1->LCDVDES; + return &XGI_StLCDDes1280x1024Data[tempal]; + break; + case 5: + if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType + & VB_XGI302LV)) + return &XGI_CetLCDDLDes1280x1024Data[tempal]; + else + return &XGI_CetLCDDes1280x1024Data[tempal]; + break; + case 6: + if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType + & VB_XGI302LV)) + return &XGI_ExtLCDDLDes1400x1050Data[tempal]; + else + return &XGI_ExtLCDDes1400x1050Data[tempal]; + break; + case 7: + if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType + & VB_XGI302LV)) + return &XGI_StLCDDLDes1400x1050Data[tempal]; + else + return &XGI_StLCDDes1400x1050Data[tempal]; + break; + case 8: + return &XGI_CetLCDDes1400x1050Data[tempal]; + break; + case 9: + return &XGI_CetLCDDes1400x1050Data2[tempal]; + break; + case 10: + if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType + & VB_XGI302LV)) + return &XGI_ExtLCDDLDes1600x1200Data[tempal]; + else + return &XGI_ExtLCDDes1600x1200Data[tempal]; + break; + case 11: + if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType + & VB_XGI302LV)) + return &XGI_StLCDDLDes1600x1200Data[tempal]; + else + return &XGI_StLCDDes1600x1200Data[tempal]; + break; + case 12: + return &XGI_NoScalingDesData[tempal]; + break; + case 13: + return &XGI_ExtLCDDes1024x768x75Data[tempal]; + break; + case 14: + return &XGI_StLCDDes1024x768x75Data[tempal]; + break; + case 15: + return &XGI_CetLCDDes1024x768x75Data[tempal]; + break; + case 16: + if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType + & VB_XGI302LV)) + return &XGI_ExtLCDDLDes1280x1024x75Data[tempal]; else - tempbx = LCDPtr->LCDVDES; - tempcx = pVBInfo->VDE; - - tempbx = tempbx & 0x0fff; - tempcx += tempbx; - if (tempcx >= tempax) - tempcx -= tempax; - - XGINew_SetReg1(pVBInfo->Part1Port, 0x1b, - (unsigned short) (tempbx & 0xff)); - XGINew_SetReg1(pVBInfo->Part1Port, 0x1c, - (unsigned short) (tempcx & 0xff)); - - tempbx = (tempbx >> 8) & 0x07; - tempcx = (tempcx >> 8) & 0x07; - - XGINew_SetReg1(pVBInfo->Part1Port, 0x1d, - (unsigned short) ((tempcx << 3) - | tempbx)); - - tempax = pVBInfo->VT; - if (pVBInfo->LCDInfo & EnableScalingLCD) - tempbx = LCDPtr1->LCDVRS; + return &XGI_ExtLCDDes1280x1024x75Data[tempal]; + break; + case 17: + if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType + & VB_XGI302LV)) + return &XGI_StLCDDLDes1280x1024x75Data[tempal]; else - tempbx = LCDPtr->LCDVRS; - - /* tempbx = tempbx >> 4; */ - tempcx = push1; - - if (pVBInfo->LCDInfo & EnableScalingLCD) - tempcx = LCDPtr1->LCDVSync; - - tempcx += tempbx; - if (tempcx >= tempax) - tempcx -= tempax; - - XGINew_SetReg1(pVBInfo->Part1Port, 0x18, - (unsigned short) (tempbx & 0xff)); - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, ~0x0f, - (unsigned short) (tempcx & 0x0f)); - - tempax = ((tempbx >> 8) & 0x07) << 3; - - tempbx = pVBInfo->VGAVDE; - if (tempbx != pVBInfo->VDE) - tempax |= 0x40; - - if (pVBInfo->LCDInfo & EnableLVDSDDA) - tempax |= 0x40; - - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1a, 0x07, - tempax); - - tempcx = pVBInfo->VGAVT; - tempbx = pVBInfo->VDE; - tempax = pVBInfo->VGAVDE; - tempcx -= tempax; - - temp = tempax; /* 0430 ylshieh */ - temp1 = (temp << 18) / tempbx; - - tempdx = (unsigned short) ((temp << 18) % tempbx); - - if (tempdx != 0) - temp1 += 1; - - temp2 = temp1; - push3 = temp2; - - XGINew_SetReg1(pVBInfo->Part1Port, 0x37, - (unsigned short) (temp2 & 0xff)); - XGINew_SetReg1(pVBInfo->Part1Port, 0x36, - (unsigned short) ((temp2 >> 8) & 0xff)); - - tempbx = (unsigned short) (temp2 >> 16); - tempax = tempbx & 0x03; - - tempbx = pVBInfo->VGAVDE; - if (tempbx == pVBInfo->VDE) - tempax |= 0x04; - - XGINew_SetReg1(pVBInfo->Part1Port, 0x35, tempax); - - if (pVBInfo->VBType & VB_XGI301C) { - temp2 = push3; - XGINew_SetReg1(pVBInfo->Part4Port, 0x3c, - (unsigned short) (temp2 & 0xff)); - XGINew_SetReg1(pVBInfo->Part4Port, 0x3b, - (unsigned short) ((temp2 >> 8) - & 0xff)); - tempbx = (unsigned short) (temp2 >> 16); - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x3a, - ~0xc0, - (unsigned short) ((tempbx - & 0xff) << 6)); - - tempcx = pVBInfo->VGAVDE; - if (tempcx == pVBInfo->VDE) - XGINew_SetRegANDOR(pVBInfo->Part4Port, - 0x30, ~0x0c, 0x00); - else - XGINew_SetRegANDOR(pVBInfo->Part4Port, - 0x30, ~0x0c, 0x08); - } - - tempcx = pVBInfo->VGAHDE; - tempbx = pVBInfo->HDE; - - temp1 = tempcx << 16; - - tempax = (unsigned short) (temp1 / tempbx); - - if ((tempbx & 0xffff) == (tempcx & 0xffff)) - tempax = 65535; - - temp3 = tempax; - temp1 = pVBInfo->VGAHDE << 16; - - temp1 /= temp3; - temp3 = temp3 << 16; - temp1 -= 1; - - temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff); - - tempax = (unsigned short) (temp3 & 0xff); - XGINew_SetReg1(pVBInfo->Part1Port, 0x1f, tempax); - - temp1 = pVBInfo->VGAVDE << 18; - temp1 = temp1 / push3; - tempbx = (unsigned short) (temp1 & 0xffff); - - if (pVBInfo->LCDResInfo == Panel1024x768) - tempbx -= 1; - - tempax = ((tempbx >> 8) & 0xff) << 3; - tempax |= (unsigned short) ((temp3 >> 8) & 0x07); - XGINew_SetReg1(pVBInfo->Part1Port, 0x20, - (unsigned short) (tempax & 0xff)); - XGINew_SetReg1(pVBInfo->Part1Port, 0x21, - (unsigned short) (tempbx & 0xff)); - - temp3 = temp3 >> 16; - - if (modeflag & HalfDCLK) - temp3 = temp3 >> 1; - - XGINew_SetReg1(pVBInfo->Part1Port, 0x22, - (unsigned short) ((temp3 >> 8) & 0xff)); - XGINew_SetReg1(pVBInfo->Part1Port, 0x23, - (unsigned short) (temp3 & 0xff)); + return &XGI_StLCDDes1280x1024x75Data[tempal]; + break; + case 18: + if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType + & VB_XGI302LV)) + return &XGI_CetLCDDLDes1280x1024x75Data[tempal]; + else + return &XGI_CetLCDDes1280x1024x75Data[tempal]; + break; + case 19: + return &XGI_NoScalingDesDatax75[tempal]; + break; + default: + break; } - } -} - -static void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned char di_0, di_1, tempal; - int i; - - tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex, - pVBInfo); - XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo); - XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo); - - for (i = 0; i < 4; i++) { - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x31, ~0x30, - (unsigned short) (0x10 * i)); - if (pVBInfo->IF_DEF_CH7007 == 1) { - XGINew_SetReg1(pVBInfo->P3c4, 0x2b, di_0); - XGINew_SetReg1(pVBInfo->P3c4, 0x2c, di_1); - } else if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA)) - && (!(pVBInfo->VBInfo & SetInSlaveMode))) { - XGINew_SetReg1(pVBInfo->P3c4, 0x2e, di_0); - XGINew_SetReg1(pVBInfo->P3c4, 0x2f, di_1); - } else { - XGINew_SetReg1(pVBInfo->P3c4, 0x2b, di_0); - XGINew_SetReg1(pVBInfo->P3c4, 0x2c, di_1); + } else if (table == 6) { + switch (tempdi[i].DATAPTR) { + case 0: + return &XGI_CH7017LV1024x768[tempal]; + break; + case 1: + return &XGI_CH7017LV1400x1050[tempal]; + break; + default: + break; } } + return NULL; } -static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, +static void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo, + unsigned short ModeIdIndex, + unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - unsigned short tempcl, tempch, temp, tempbl, tempax; - - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { - tempcl = 0; - tempch = 0; - temp = XGINew_GetReg1(pVBInfo->P3c4, 0x01); - - if (!(temp & 0x20)) { - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x17); - if (temp & 0x80) { - if ((HwDeviceExtension->jChipType >= XG20) - || (HwDeviceExtension->jChipType - >= XG40)) - temp = XGINew_GetReg1(pVBInfo->P3d4, - 0x53); - else - temp = XGINew_GetReg1(pVBInfo->P3d4, - 0x63); - - if (!(temp & 0x40)) - tempcl |= ActiveCRT1; - } - } + unsigned short i, tempdx, tempbx, tempal, modeflag, table; + struct XGI330_TVDataTablStruct *tempdi = NULL; - temp = XGINew_GetReg1(pVBInfo->Part1Port, 0x2e); - temp &= 0x0f; + tempbx = BX; - if (!(temp == 0x08)) { - tempax = XGINew_GetReg1(pVBInfo->Part1Port, 0x13); /* Check ChannelA by Part1_13 [2003/10/03] */ - if (tempax & 0x04) - tempcl = tempcl | ActiveLCD; + if (ModeNo <= 0x13) { + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; + tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; + } else { + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + } - temp &= 0x05; + tempal = tempal & 0x3f; + table = tempbx; - if (!(tempcl & ActiveLCD)) - if (temp == 0x01) - tempcl |= ActiveCRT2; + switch (tempbx) { + case 0: + tempdi = NULL; /*EPLCHTVCRT1Ptr_H;*/ + if (pVBInfo->IF_DEF_CH7007 == 1) + tempdi = XGI_EPLCHTVCRT1Ptr; - if (temp == 0x04) - tempcl |= ActiveLCD; + break; + case 1: + tempdi = NULL; /*EPLCHTVCRT1Ptr_V;*/ + if (pVBInfo->IF_DEF_CH7007 == 1) + tempdi = XGI_EPLCHTVCRT1Ptr; - if (temp == 0x05) { - temp = XGINew_GetReg1(pVBInfo->Part2Port, 0x00); + break; + case 2: + tempdi = XGI_EPLCHTVDataPtr; + break; + case 3: + tempdi = NULL; + break; + case 4: + tempdi = XGI_TVDataTable; + break; + case 5: + tempdi = NULL; + break; + case 6: + tempdi = XGI_EPLCHTVRegPtr; + break; + default: + break; + } - if (!(temp & 0x08)) - tempch |= ActiveAVideo; + if (tempdi == NULL) /* OEMUtil */ + return NULL; - if (!(temp & 0x04)) - tempch |= ActiveSVideo; + tempdx = pVBInfo->TVInfo; - if (temp & 0x02) - tempch |= ActiveSCART; + if (pVBInfo->VBInfo & SetInSlaveMode) + tempdx = tempdx | SetTVLockMode; - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { - if (temp & 0x01) - tempch |= ActiveHiTV; - } + if (modeflag & HalfDCLK) + tempdx = tempdx | SetTVLowResolution; - if (pVBInfo->VBInfo & SetCRT2ToYPbPr) { - temp = XGINew_GetReg1( - pVBInfo->Part2Port, - 0x4d); + i = 0; - if (temp & 0x10) - tempch |= ActiveYPbPr; - } + while (tempdi[i].MASK != 0xffff) { + if ((tempdx & tempdi[i].MASK) == tempdi[i].CAP) + break; + i++; + } - if (tempch != 0) - tempcl |= ActiveTV; - } + if (table == 0x00) { /* 07/05/22 */ + } else if (table == 0x01) { + } else if (table == 0x04) { + switch (tempdi[i].DATAPTR) { + case 0: + return &XGI_ExtPALData[tempal]; + break; + case 1: + return &XGI_ExtNTSCData[tempal]; + break; + case 2: + return &XGI_StPALData[tempal]; + break; + case 3: + return &XGI_StNTSCData[tempal]; + break; + case 4: + return &XGI_ExtHiTVData[tempal]; + break; + case 5: + return &XGI_St2HiTVData[tempal]; + break; + case 6: + return &XGI_ExtYPbPr525iData[tempal]; + break; + case 7: + return &XGI_ExtYPbPr525pData[tempal]; + break; + case 8: + return &XGI_ExtYPbPr750pData[tempal]; + break; + case 9: + return &XGI_StYPbPr525iData[tempal]; + break; + case 10: + return &XGI_StYPbPr525pData[tempal]; + break; + case 11: + return &XGI_StYPbPr750pData[tempal]; + break; + case 12: /* avoid system hang */ + return &XGI_ExtNTSCData[tempal]; + break; + case 13: + return &XGI_St1HiTVData[tempal]; + break; + default: + break; } - - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x3d); - if (tempcl & ActiveLCD) { - if ((pVBInfo->SetFlag & ReserveTVOption)) { - if (temp & ActiveTV) - tempcl |= ActiveTV; - } + } else if (table == 0x02) { + switch (tempdi[i].DATAPTR) { + case 0: + return &XGI_CHTVUNTSCData[tempal]; + break; + case 1: + return &XGI_CHTVONTSCData[tempal]; + break; + case 2: + return &XGI_CHTVUPALData[tempal]; + break; + case 3: + return &XGI_CHTVOPALData[tempal]; + break; + default: + break; } - temp = tempcl; - tempbl = ~ModeSwitchStatus; - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x3d, tempbl, temp); - - if (!(pVBInfo->SetFlag & ReserveTVOption)) - XGINew_SetReg1(pVBInfo->P3d4, 0x3e, tempch); - } else { - return; + } else if (table == 0x06) { } + return NULL; } -void XGI_GetVGAType(struct xgi_hw_device_info *HwDeviceExtension, +static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, + unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - /* - if ( HwDeviceExtension->jChipType >= XG20 ) { - pVBInfo->Set_VGAType = XG20; - } else if (HwDeviceExtension->jChipType >= XG40) { - pVBInfo->Set_VGAType = VGA_XGI340; - } - */ - pVBInfo->Set_VGAType = HwDeviceExtension->jChipType; -} + unsigned short tempbx; + struct XGI330_LVDSDataStruct *LCDPtr = NULL; + struct XGI330_CHTVDataStruct *TVPtr = NULL; -void XGI_GetVBType(struct vb_device_info *pVBInfo) -{ - unsigned short flag, tempbx, tempah; + tempbx = 2; - if (pVBInfo->IF_DEF_CH7007 == 1) { - pVBInfo->VBType = VB_CH7007; - return; + if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + LCDPtr = (struct XGI330_LVDSDataStruct *) XGI_GetLcdPtr(tempbx, + ModeNo, ModeIdIndex, RefreshRateTableIndex, + pVBInfo); + pVBInfo->VGAHT = LCDPtr->VGAHT; + pVBInfo->VGAVT = LCDPtr->VGAVT; + pVBInfo->HT = LCDPtr->LCDHT; + pVBInfo->VT = LCDPtr->LCDVT; + } + if (pVBInfo->IF_DEF_CH7017 == 1) { + if (pVBInfo->VBInfo & SetCRT2ToTV) { + TVPtr = (struct XGI330_CHTVDataStruct *) XGI_GetTVPtr( + tempbx, ModeNo, ModeIdIndex, + RefreshRateTableIndex, pVBInfo); + pVBInfo->VGAHT = TVPtr->VGAHT; + pVBInfo->VGAVT = TVPtr->VGAVT; + pVBInfo->HT = TVPtr->LCDHT; + pVBInfo->VT = TVPtr->LCDVT; + } } - if (pVBInfo->IF_DEF_LVDS == 0) { - tempbx = VB_XGI302B; - flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x00); - if (flag != 0x02) { - tempbx = VB_XGI301; - flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x01); - if (flag >= 0xB0) { - tempbx = VB_XGI301B; - if (flag >= 0xC0) { - tempbx = VB_XGI301C; - if (flag >= 0xD0) { - tempbx = VB_XGI301LV; - if (flag >= 0xE0) { - tempbx = VB_XGI302LV; - tempah - = XGINew_GetReg1( - pVBInfo->Part4Port, - 0x39); - if (tempah != 0xFF) - tempbx - = VB_XGI301C; - } - } - } - - if (tempbx & (VB_XGI301B | VB_XGI302B)) { - flag = XGINew_GetReg1( - pVBInfo->Part4Port, - 0x23); - if (!(flag & 0x02)) - tempbx = tempbx | VB_NoLCD; - } + if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + if (!(pVBInfo->LCDInfo & (SetLCDtoNonExpanding + | EnableScalingLCD))) { + if ((pVBInfo->LCDResInfo == Panel1024x768) + || (pVBInfo->LCDResInfo + == Panel1024x768x75)) { + pVBInfo->HDE = 1024; + pVBInfo->VDE = 768; + } else if ((pVBInfo->LCDResInfo == Panel1280x1024) + || (pVBInfo->LCDResInfo + == Panel1280x1024x75)) { + pVBInfo->HDE = 1280; + pVBInfo->VDE = 1024; + } else if (pVBInfo->LCDResInfo == Panel1400x1050) { + pVBInfo->HDE = 1400; + pVBInfo->VDE = 1050; + } else { + pVBInfo->HDE = 1600; + pVBInfo->VDE = 1200; } } - pVBInfo->VBType = tempbx; } - /* - else if (pVBInfo->IF_DEF_CH7017 == 1) - pVBInfo->VBType = VB_CH7017; - else //LVDS - pVBInfo->VBType = VB_LVDS_NS; - */ - } -void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, + unsigned short RefreshRateTableIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - unsigned short tempax, push, tempbx, temp, modeflag; + unsigned char index; + unsigned short tempbx, i; + struct XGI_LVDSCRT1HDataStruct *LCDPtr = NULL; + struct XGI_LVDSCRT1VDataStruct *LCDPtr1 = NULL; + /* struct XGI330_CHTVDataStruct *TVPtr = NULL; */ + struct XGI_CH7007TV_TimingHStruct *CH7007TV_TimingHPtr = NULL; + struct XGI_CH7007TV_TimingVStruct *CH7007TV_TimingVPtr = NULL; if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; + index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - pVBInfo->SetFlag = 0; - pVBInfo->ModeType = modeflag & ModeInfoFlag; - tempbx = 0; + index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; - if (pVBInfo->VBType & 0xFFFF) { - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x30); /* Check Display Device */ - tempbx = tempbx | temp; - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x31); - push = temp; - push = push << 8; - tempax = temp << 8; - tempbx = tempbx | tempax; - temp = (SetCRT2ToDualEdge | SetCRT2ToYPbPr | SetCRT2ToLCDA - | SetInSlaveMode | DisableCRT2Display); - temp = 0xFFFF ^ temp; - tempbx &= temp; + index = index & IndexMask; - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38); + if ((pVBInfo->IF_DEF_ScaleLCD == 0) || ((pVBInfo->IF_DEF_ScaleLCD == 1) + && (!(pVBInfo->LCDInfo & EnableScalingLCD)))) { + tempbx = 0; - if (pVBInfo->IF_DEF_LCDA == 1) { + if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + LCDPtr + = (struct XGI_LVDSCRT1HDataStruct *) XGI_GetLcdPtr( + tempbx, ModeNo, + ModeIdIndex, + RefreshRateTableIndex, + pVBInfo); - if ((pVBInfo->Set_VGAType >= XG20) - || (pVBInfo->Set_VGAType >= XG40)) { - if (pVBInfo->IF_DEF_LVDS == 0) { - /* if ((pVBInfo->VBType & VB_XGI302B) || (pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType & VB_XGI301C)) */ - if (pVBInfo->VBType & (VB_XGI302B - | VB_XGI301LV - | VB_XGI302LV - | VB_XGI301C)) { - if (temp & EnableDualEdge) { - tempbx - |= SetCRT2ToDualEdge; + for (i = 0; i < 8; i++) + pVBInfo->TimingH[0].data[i] = LCDPtr[0].Reg[i]; + } - if (temp & SetToLCDA) - tempbx - |= SetCRT2ToLCDA; - } - } - } else if (pVBInfo->IF_DEF_CH7017 == 1) { - if (pVBInfo->VBType & VB_CH7017) { - if (temp & EnableDualEdge) { - tempbx - |= SetCRT2ToDualEdge; + if (pVBInfo->IF_DEF_CH7007 == 1) { + if (pVBInfo->VBInfo & SetCRT2ToTV) { + CH7007TV_TimingHPtr + = (struct XGI_CH7007TV_TimingHStruct *) XGI_GetTVPtr( + tempbx, + ModeNo, + ModeIdIndex, + RefreshRateTableIndex, + pVBInfo); - if (temp & SetToLCDA) - tempbx - |= SetCRT2ToLCDA; - } - } - } + for (i = 0; i < 8; i++) + pVBInfo->TimingH[0].data[i] + = CH7007TV_TimingHPtr[0].data[i]; } } - if (pVBInfo->IF_DEF_YPbPr == 1) { - if (((pVBInfo->IF_DEF_LVDS == 0) && ((pVBInfo->VBType - & VB_XGI301LV) || (pVBInfo->VBType - & VB_XGI302LV) || (pVBInfo->VBType - & VB_XGI301C))) - || ((pVBInfo->IF_DEF_CH7017 == 1) - && (pVBInfo->VBType - & VB_CH7017)) - || ((pVBInfo->IF_DEF_CH7007 == 1) - && (pVBInfo->VBType - & VB_CH7007))) { /* [Billy] 07/05/04 */ - if (temp & SetYPbPr) { /* temp = CR38 */ - if (pVBInfo->IF_DEF_HiVision == 1) { - temp = XGINew_GetReg1( - pVBInfo->P3d4, - 0x35); /* shampoo add for new scratch */ - temp &= YPbPrMode; - tempbx |= SetCRT2ToHiVisionTV; + /* if (pVBInfo->IF_DEF_CH7017 == 1) { + if (pVBInfo->VBInfo & SetCRT2ToTV) + TVPtr = (struct XGI330_CHTVDataStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); + } + */ - if (temp != YPbPrMode1080i) { - tempbx - &= (~SetCRT2ToHiVisionTV); - tempbx - |= SetCRT2ToYPbPr; - } - } + XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension); - /* tempbx |= SetCRT2ToYPbPr; */ - } - } + if (pVBInfo->IF_DEF_CH7007 == 1) { + XGINew_SetReg1(pVBInfo->P3c4, 0x2E, + CH7007TV_TimingHPtr[0].data[8]); + XGINew_SetReg1(pVBInfo->P3c4, 0x2F, + CH7007TV_TimingHPtr[0].data[9]); } - tempax = push; /* restore CR31 */ + tempbx = 1; - if (pVBInfo->IF_DEF_LVDS == 0) { - if (pVBInfo->IF_DEF_YPbPr == 1) { - if (pVBInfo->IF_DEF_HiVision == 1) - temp = 0x09FC; - else - temp = 0x097C; - } else { - if (pVBInfo->IF_DEF_HiVision == 1) - temp = 0x01FC; - else - temp = 0x017C; - } - } else { /* 3nd party chip */ - if (pVBInfo->IF_DEF_CH7017 == 1) - temp = (SetCRT2ToTV | SetCRT2ToLCD - | SetCRT2ToLCDA); - else if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/03 */ - temp = SetCRT2ToTV; - } else - temp = SetCRT2ToLCD; + if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + LCDPtr1 + = (struct XGI_LVDSCRT1VDataStruct *) XGI_GetLcdPtr( + tempbx, ModeNo, + ModeIdIndex, + RefreshRateTableIndex, + pVBInfo); + for (i = 0; i < 7; i++) + pVBInfo->TimingV[0].data[i] = LCDPtr1[0].Reg[i]; } - if (!(tempbx & temp)) { - tempax |= DisableCRT2Display; - tempbx = 0; - } + if (pVBInfo->IF_DEF_CH7007 == 1) { + if (pVBInfo->VBInfo & SetCRT2ToTV) { + CH7007TV_TimingVPtr + = (struct XGI_CH7007TV_TimingVStruct *) XGI_GetTVPtr( + tempbx, + ModeNo, + ModeIdIndex, + RefreshRateTableIndex, + pVBInfo); - if (pVBInfo->IF_DEF_LCDA == 1) { /* Select Display Device */ - if (!(pVBInfo->VBType & VB_NoLCD)) { - if (tempbx & SetCRT2ToLCDA) { - if (tempbx & SetSimuScanMode) - tempbx - &= (~(SetCRT2ToLCD - | SetCRT2ToRAMDAC - | SwitchToCRT2)); - else - tempbx - &= (~(SetCRT2ToLCD - | SetCRT2ToRAMDAC - | SetCRT2ToTV - | SwitchToCRT2)); - } + for (i = 0; i < 7; i++) + pVBInfo->TimingV[0].data[i] + = CH7007TV_TimingVPtr[0].data[i]; } } - - /* shampoo add */ - if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) { /* for driver abnormal */ - if (pVBInfo->IF_DEF_CRT2Monitor == 1) { - if (tempbx & SetCRT2ToRAMDAC) { - tempbx &= (0xFF00 | SetCRT2ToRAMDAC - | SwitchToCRT2 - | SetSimuScanMode); - tempbx &= (0x00FF | (~SetCRT2ToYPbPr)); - } - } else { - tempbx &= (~(SetCRT2ToRAMDAC | SetCRT2ToLCD - | SetCRT2ToTV)); - } + /* if (pVBInfo->IF_DEF_CH7017 == 1) { + if (pVBInfo->VBInfo & SetCRT2ToTV) + TVPtr = (struct XGI330_CHTVDataStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); } + */ - if (!(pVBInfo->VBType & VB_NoLCD)) { - if (tempbx & SetCRT2ToLCD) { - tempbx &= (0xFF00 | SetCRT2ToLCD | SwitchToCRT2 - | SetSimuScanMode); - tempbx &= (0x00FF | (~SetCRT2ToYPbPr)); - } - } + XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo); - if (tempbx & SetCRT2ToSCART) { - tempbx &= (0xFF00 | SetCRT2ToSCART | SwitchToCRT2 - | SetSimuScanMode); - tempbx &= (0x00FF | (~SetCRT2ToYPbPr)); - } + if (pVBInfo->IF_DEF_CH7007 == 1) { + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x33, ~0x01, + CH7007TV_TimingVPtr[0].data[7] & 0x01); + XGINew_SetReg1(pVBInfo->P3c4, 0x34, + CH7007TV_TimingVPtr[0].data[8]); + XGINew_SetReg1(pVBInfo->P3c4, 0x3F, + CH7007TV_TimingVPtr[0].data[9]); - if (pVBInfo->IF_DEF_YPbPr == 1) { - if (tempbx & SetCRT2ToYPbPr) - tempbx &= (0xFF00 | SwitchToCRT2 - | SetSimuScanMode); } + } +} - if (pVBInfo->IF_DEF_HiVision == 1) { - if (tempbx & SetCRT2ToHiVisionTV) - tempbx &= (0xFF00 | SetCRT2ToHiVisionTV - | SwitchToCRT2 - | SetSimuScanMode); - } +static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo) +{ + unsigned char tempal, tempah, tempbl, i; + + tempah = XGINew_GetReg1(pVBInfo->P3d4, 0x36); + tempal = tempah & 0x0F; + tempah = tempah & 0xF0; + i = 0; + tempbl = pVBInfo->LCDCapList[i].LCD_ID; - if (tempax & DisableCRT2Display) { /* Set Display Device Info */ - if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) - tempbx = DisableCRT2Display; + while (tempbl != 0xFF) { + if (tempbl & 0x80) { /* OEMUtil */ + tempal = tempah; + tempbl = tempbl & ~(0x80); } - if (!(tempbx & DisableCRT2Display)) { - if ((!(tempbx & DriverMode)) - || (!(modeflag & CRT2Mode))) { - if (pVBInfo->IF_DEF_LCDA == 1) { - if (!(tempbx & SetCRT2ToLCDA)) - tempbx - |= (SetInSlaveMode - | SetSimuScanMode); - } + if (tempal == tempbl) + break; - if (pVBInfo->IF_DEF_VideoCapture == 1) { - if (((HwDeviceExtension->jChipType - == XG40) - && (pVBInfo->Set_VGAType - == XG40)) - || ((HwDeviceExtension->jChipType - == XG41) - && (pVBInfo->Set_VGAType - == XG41)) - || ((HwDeviceExtension->jChipType - == XG42) - && (pVBInfo->Set_VGAType - == XG42)) - || ((HwDeviceExtension->jChipType - == XG45) - && (pVBInfo->Set_VGAType - == XG45))) { - if (ModeNo <= 13) { - if (!(tempbx - & SetCRT2ToRAMDAC)) { /*CRT2 not need to support*/ - tempbx - &= (0x00FF - | (~SetInSlaveMode)); - pVBInfo->SetFlag - |= EnableVCMode; - } - } - } - } - } + i++; - /* LCD+TV can't support in slave mode (Force LCDA+TV->LCDB) */ - if ((tempbx & SetInSlaveMode) && (tempbx - & SetCRT2ToLCDA)) { - tempbx ^= (SetCRT2ToLCD | SetCRT2ToLCDA - | SetCRT2ToDualEdge); - pVBInfo->SetFlag |= ReserveTVOption; - } - } + tempbl = pVBInfo->LCDCapList[i].LCD_ID; } - pVBInfo->VBInfo = tempbx; + return i; } -void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) +static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo) { - unsigned short temp, tempbx = 0, resinfo = 0, modeflag, index1; + unsigned short tempah, tempal, tempbl, i; - tempbx = 0; - resinfo = 0; + tempal = pVBInfo->LCDResInfo; + tempah = pVBInfo->LCDTypeInfo; - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (ModeNo <= 0x13) { - modeflag - = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */ - resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */ - } else { - modeflag - = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo - = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */ - } + i = 0; + tempbl = pVBInfo->LCDCapList[i].LCD_ID; - if (pVBInfo->VBInfo & SetCRT2ToTV) { - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x35); - tempbx = temp; - if (tempbx & SetPALTV) { - tempbx &= (SetCHTVOverScan | SetPALMTV - | SetPALNTV | SetPALTV); - if (tempbx & SetPALMTV) - tempbx &= ~SetPALTV; /* set to NTSC if PAL-M */ - } else - tempbx &= (SetCHTVOverScan | SetNTSCJ - | SetPALTV); - /* - if (pVBInfo->IF_DEF_LVDS == 0) { - index1 = XGINew_GetReg1(pVBInfo->P3d4, 0x38); //PAL-M/PAL-N Info - temp2 = (index1 & 0xC0) >> 5; //00:PAL, 01:PAL-M, 10:PAL-N - tempbx |= temp2; - if (temp2 & 0x02) //PAL-M - tempbx &= (~SetPALTV); - } - */ + while (tempbl != 0xFF) { + if ((tempbl & 0x80) && (tempbl != 0x80)) { + tempal = tempah; + tempbl &= ~0x80; } - if (pVBInfo->IF_DEF_CH7017 == 1) { - tempbx = XGINew_GetReg1(pVBInfo->P3d4, 0x35); + if (tempal == tempbl) + break; - if (tempbx & TVOverScan) - tempbx |= SetCHTVOverScan; - } + i++; + tempbl = pVBInfo->LCDCapList[i].LCD_ID; + } - if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/04 */ - tempbx = XGINew_GetReg1(pVBInfo->P3d4, 0x35); + if (tempbl == 0xFF) { + pVBInfo->LCDResInfo = Panel1024x768; + pVBInfo->LCDTypeInfo = 0; + i = 0; + } - if (tempbx & TVOverScan) - tempbx |= SetCHTVOverScan; - } + return i; +} - if (pVBInfo->IF_DEF_LVDS == 0) { - if (pVBInfo->VBInfo & SetCRT2ToSCART) - tempbx |= SetPALTV; - } +static void XGI_GetLCDSync(unsigned short *HSyncWidth, unsigned short *VSyncWidth, + struct vb_device_info *pVBInfo) +{ + unsigned short Index; - if (pVBInfo->IF_DEF_YPbPr == 1) { - if (pVBInfo->VBInfo & SetCRT2ToYPbPr) { - index1 = XGINew_GetReg1(pVBInfo->P3d4, 0x35); - index1 &= YPbPrMode; + Index = XGI_GetLCDCapPtr(pVBInfo); + *HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth; + *VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth; - if (index1 == YPbPrMode525i) - tempbx |= SetYPbPrMode525i; + return; +} - if (index1 == YPbPrMode525p) - tempbx = tempbx | SetYPbPrMode525p; - if (index1 == YPbPrMode750p) - tempbx = tempbx | SetYPbPrMode750p; - } - } +static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, + unsigned short RefreshRateTableIndex, + struct vb_device_info *pVBInfo) +{ + unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag; + unsigned long temp, temp1, temp2, temp3, push3; + struct XGI330_LCDDataDesStruct *LCDPtr = NULL; + struct XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL; - if (pVBInfo->IF_DEF_HiVision == 1) { - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) - tempbx = tempbx | SetYPbPrMode1080i | SetPALTV; - } + if (ModeNo > 0x13) + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + else + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */ - if ((pVBInfo->VBInfo & SetInSlaveMode) - && (!(pVBInfo->VBInfo & SetNotSimuMode))) - tempbx |= TVSimuMode; + if (!(pVBInfo->SetFlag & Win9xDOSMode)) { + if ((pVBInfo->IF_DEF_CH7017 == 0) || (pVBInfo->VBInfo + & (SetCRT2ToLCD | SetCRT2ToLCDA))) { + if (pVBInfo->IF_DEF_OEMUtil == 1) { + tempbx = 8; + LCDPtr + = (struct XGI330_LCDDataDesStruct *) XGI_GetLcdPtr( + tempbx, + ModeNo, + ModeIdIndex, + RefreshRateTableIndex, + pVBInfo); + } - if (!(tempbx & SetPALTV) && (modeflag > 13) && (resinfo - == 8)) /* NTSC 1024x768, */ - tempbx |= NTSC1024x768; + if ((pVBInfo->IF_DEF_OEMUtil == 0) || (LCDPtr == NULL)) { + tempbx = 3; + if (pVBInfo->LCDInfo & EnableScalingLCD) + LCDPtr1 + = (struct XGI330_LCDDataDesStruct2 *) XGI_GetLcdPtr( + tempbx, + ModeNo, + ModeIdIndex, + RefreshRateTableIndex, + pVBInfo); + else + LCDPtr + = (struct XGI330_LCDDataDesStruct *) XGI_GetLcdPtr( + tempbx, + ModeNo, + ModeIdIndex, + RefreshRateTableIndex, + pVBInfo); + } - tempbx |= RPLLDIV2XO; + XGI_GetLCDSync(&tempax, &tempbx, pVBInfo); + push1 = tempbx; + push2 = tempax; - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { - if (pVBInfo->VBInfo & SetInSlaveMode) - tempbx &= (~RPLLDIV2XO); + /* GetLCDResInfo */ + if ((pVBInfo->LCDResInfo == Panel1024x768) + || (pVBInfo->LCDResInfo + == Panel1024x768x75)) { + tempax = 1024; + tempbx = 768; + } else if ((pVBInfo->LCDResInfo == Panel1280x1024) + || (pVBInfo->LCDResInfo + == Panel1280x1024x75)) { + tempax = 1280; + tempbx = 1024; + } else if (pVBInfo->LCDResInfo == Panel1400x1050) { + tempax = 1400; + tempbx = 1050; } else { - if (tempbx & (SetYPbPrMode525p - | SetYPbPrMode750p)) - tempbx &= (~RPLLDIV2XO); - else if (!(pVBInfo->VBType & (VB_XGI301B - | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C))) { - if (tempbx & TVSimuMode) - tempbx &= (~RPLLDIV2XO); - } + tempax = 1600; + tempbx = 1200; + } + + if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) { + pVBInfo->HDE = tempax; + pVBInfo->VDE = tempbx; + pVBInfo->VGAHDE = tempax; + pVBInfo->VGAVDE = tempbx; + } + + if ((pVBInfo->IF_DEF_ScaleLCD == 1) + && (pVBInfo->LCDInfo & EnableScalingLCD)) { + tempax = pVBInfo->HDE; + tempbx = pVBInfo->VDE; } - } - } - pVBInfo->TVInfo = tempbx; -} -unsigned char XGI_GetLCDInfo(unsigned short ModeNo, unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short temp, tempax, tempbx, modeflag, resinfo = 0, LCDIdIndex; + tempax = pVBInfo->HT; - pVBInfo->LCDResInfo = 0; - pVBInfo->LCDTypeInfo = 0; - pVBInfo->LCDInfo = 0; + if (pVBInfo->LCDInfo & EnableScalingLCD) + tempbx = LCDPtr1->LCDHDES; + else + tempbx = LCDPtr->LCDHDES; - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag // */ - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo // */ - } + tempcx = pVBInfo->HDE; + tempbx = tempbx & 0x0fff; + tempcx += tempbx; - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */ - tempbx = temp & 0x0F; + if (tempcx >= tempax) + tempcx -= tempax; - if (tempbx == 0) - tempbx = Panel1024x768; /* default */ + XGINew_SetReg1(pVBInfo->Part1Port, 0x1A, tempbx & 0x07); - /* LCD75 [2003/8/22] Vicent */ - if ((tempbx == Panel1024x768) || (tempbx == Panel1280x1024)) { - if (pVBInfo->VBInfo & DriverMode) { - tempax = XGINew_GetReg1(pVBInfo->P3d4, 0x33); - if (pVBInfo->VBInfo & SetCRT2ToLCDA) - tempax &= 0x0F; + tempcx = tempcx >> 3; + tempbx = tempbx >> 3; + + XGINew_SetReg1(pVBInfo->Part1Port, 0x16, + (unsigned short) (tempbx & 0xff)); + XGINew_SetReg1(pVBInfo->Part1Port, 0x17, + (unsigned short) (tempcx & 0xff)); + + tempax = pVBInfo->HT; + + if (pVBInfo->LCDInfo & EnableScalingLCD) + tempbx = LCDPtr1->LCDHRS; else - tempax = tempax >> 4; + tempbx = LCDPtr->LCDHRS; - if ((resinfo == 6) || (resinfo == 9)) { - if (tempax >= 3) - tempbx |= PanelRef75Hz; - } else if ((resinfo == 7) || (resinfo == 8)) { - if (tempax >= 4) - tempbx |= PanelRef75Hz; - } - } - } + tempcx = push2; - pVBInfo->LCDResInfo = tempbx; + if (pVBInfo->LCDInfo & EnableScalingLCD) + tempcx = LCDPtr1->LCDHSync; - /* End of LCD75 */ + tempcx += tempbx; - if (pVBInfo->IF_DEF_OEMUtil == 1) - pVBInfo->LCDTypeInfo = (temp & 0xf0) >> 4; + if (tempcx >= tempax) + tempcx -= tempax; - if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) - return 0; + tempax = tempbx & 0x07; + tempax = tempax >> 5; + tempcx = tempcx >> 3; + tempbx = tempbx >> 3; - tempbx = 0; + tempcx &= 0x1f; + tempax |= tempcx; - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); + XGINew_SetReg1(pVBInfo->Part1Port, 0x15, tempax); + XGINew_SetReg1(pVBInfo->Part1Port, 0x14, + (unsigned short) (tempbx & 0xff)); - temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable); + tempax = pVBInfo->VT; + if (pVBInfo->LCDInfo & EnableScalingLCD) + tempbx = LCDPtr1->LCDVDES; + else + tempbx = LCDPtr->LCDVDES; + tempcx = pVBInfo->VDE; - if ((pVBInfo->IF_DEF_ScaleLCD == 1) && (temp & LCDNonExpanding)) - temp &= ~EnableScalingLCD; + tempbx = tempbx & 0x0fff; + tempcx += tempbx; + if (tempcx >= tempax) + tempcx -= tempax; - tempbx |= temp; + XGINew_SetReg1(pVBInfo->Part1Port, 0x1b, + (unsigned short) (tempbx & 0xff)); + XGINew_SetReg1(pVBInfo->Part1Port, 0x1c, + (unsigned short) (tempcx & 0xff)); - LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo); + tempbx = (tempbx >> 8) & 0x07; + tempcx = (tempcx >> 8) & 0x07; - tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability; + XGINew_SetReg1(pVBInfo->Part1Port, 0x1d, + (unsigned short) ((tempcx << 3) + | tempbx)); - if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */ - if (((pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType - & VB_XGI301C)) && (tempax & LCDDualLink)) { - tempbx |= SetLCDDualLink; - } - } + tempax = pVBInfo->VT; + if (pVBInfo->LCDInfo & EnableScalingLCD) + tempbx = LCDPtr1->LCDVRS; + else + tempbx = LCDPtr->LCDVRS; - if (pVBInfo->IF_DEF_CH7017 == 1) { - if (tempax & LCDDualLink) - tempbx |= SetLCDDualLink; - } + /* tempbx = tempbx >> 4; */ + tempcx = push1; - if (pVBInfo->IF_DEF_LVDS == 0) { - if ((pVBInfo->LCDResInfo == Panel1400x1050) && (pVBInfo->VBInfo - & SetCRT2ToLCD) && (ModeNo > 0x13) && (resinfo - == 9) && (!(tempbx & EnableScalingLCD))) - tempbx |= SetLCDtoNonExpanding; /* set to center in 1280x1024 LCDB for Panel1400x1050 */ - } + if (pVBInfo->LCDInfo & EnableScalingLCD) + tempcx = LCDPtr1->LCDVSync; - /* - if (tempax & LCDBToA) { - tempbx |= SetLCDBToA; - } - */ + tempcx += tempbx; + if (tempcx >= tempax) + tempcx -= tempax; - if (pVBInfo->IF_DEF_ExpLink == 1) { - if (modeflag & HalfDCLK) { - /* if (!(pVBInfo->LCDInfo&LCDNonExpanding)) */ - if (!(tempbx & SetLCDtoNonExpanding)) { - tempbx |= EnableLVDSDDA; - } else { - if (ModeNo > 0x13) { - if (pVBInfo->LCDResInfo - == Panel1024x768) { - if (resinfo == 4) { /* 512x384 */ - tempbx |= EnableLVDSDDA; - } - } - } - } - } - } + XGINew_SetReg1(pVBInfo->Part1Port, 0x18, + (unsigned short) (tempbx & 0xff)); + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, ~0x0f, + (unsigned short) (tempcx & 0x0f)); - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (pVBInfo->VBInfo & SetNotSimuMode) - tempbx |= LCDVESATiming; - } else { - tempbx |= LCDVESATiming; - } + tempax = ((tempbx >> 8) & 0x07) << 3; - pVBInfo->LCDInfo = tempbx; + tempbx = pVBInfo->VGAVDE; + if (tempbx != pVBInfo->VDE) + tempax |= 0x40; - if (pVBInfo->IF_DEF_PWD == 1) { - if (pVBInfo->LCDInfo & SetPWDEnable) { - if ((pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType - & VB_XGI301C)) { - if (!(tempax & PWDEnable)) - pVBInfo->LCDInfo &= ~SetPWDEnable; - } - } - } + if (pVBInfo->LCDInfo & EnableLVDSDDA) + tempax |= 0x40; - if (pVBInfo->IF_DEF_LVDS == 0) { - if (tempax & (LockLCDBToA | StLCDBToA)) { - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (!(tempax & LockLCDBToA)) { - if (ModeNo <= 0x13) { - pVBInfo->VBInfo - &= ~(SetSimuScanMode - | SetInSlaveMode - | SetCRT2ToLCD); - pVBInfo->VBInfo - |= SetCRT2ToLCDA - | SetCRT2ToDualEdge; - } - } - } - } - } + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1a, 0x07, + tempax); - /* - if (pVBInfo->IF_DEF_LVDS == 0) { - if (tempax & (LockLCDBToA | StLCDBToA)) { - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (!((!(tempax & LockLCDBToA)) && (ModeNo > 0x13))) { - pVBInfo->VBInfo&=~(SetSimuScanMode|SetInSlaveMode|SetCRT2ToLCD); - pVBInfo->VBInfo|=SetCRT2ToLCDA|SetCRT2ToDualEdge; - } - } - } - } - */ + tempcx = pVBInfo->VGAVT; + tempbx = pVBInfo->VDE; + tempax = pVBInfo->VGAVDE; + tempcx -= tempax; - return 1; -} + temp = tempax; /* 0430 ylshieh */ + temp1 = (temp << 18) / tempbx; -unsigned char XGI_SearchModeID(unsigned short ModeNo, - unsigned short *ModeIdIndex, struct vb_device_info *pVBInfo) -{ - if (ModeNo <= 5) - ModeNo |= 1; - if (ModeNo <= 0x13) { - /* for (*ModeIdIndex=0; *ModeIdIndex < sizeof(pVBInfo->SModeIDTable) / sizeof(struct XGI_StStruct); (*ModeIdIndex)++) */ - for (*ModeIdIndex = 0;; (*ModeIdIndex)++) { - if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == ModeNo) - break; - if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF) - return 0; - } + tempdx = (unsigned short) ((temp << 18) % tempbx); - if (ModeNo == 0x07) - (*ModeIdIndex)++; /* 400 lines */ - if (ModeNo <= 3) - (*ModeIdIndex) += 2; /* 400 lines */ - /* else 350 lines */ - } else { - /* for (*ModeIdIndex=0; *ModeIdIndex < sizeof(pVBInfo->EModeIDTable) / sizeof(struct XGI_ExtStruct); (*ModeIdIndex)++) */ - for (*ModeIdIndex = 0;; (*ModeIdIndex)++) { - if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo) - break; - if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) - return 0; - } - } + if (tempdx != 0) + temp1 += 1; + + temp2 = temp1; + push3 = temp2; + + XGINew_SetReg1(pVBInfo->Part1Port, 0x37, + (unsigned short) (temp2 & 0xff)); + XGINew_SetReg1(pVBInfo->Part1Port, 0x36, + (unsigned short) ((temp2 >> 8) & 0xff)); - return 1; -} + tempbx = (unsigned short) (temp2 >> 16); + tempax = tempbx & 0x03; -/* win2000 MM adapter not support standard mode! */ + tempbx = pVBInfo->VGAVDE; + if (tempbx == pVBInfo->VDE) + tempax |= 0x04; -#if 0 -static unsigned char XGINew_CheckMemorySize( - struct xgi_hw_device_info *HwDeviceExtension, - unsigned short ModeNo, - unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short memorysize, modeflag, temp, temp1, tmp; + XGINew_SetReg1(pVBInfo->Part1Port, 0x35, tempax); - /* - if ((HwDeviceExtension->jChipType == XGI_650) || - (HwDeviceExtension->jChipType == XGI_650M)) { - return 1; - } - */ + if (pVBInfo->VBType & VB_XGI301C) { + temp2 = push3; + XGINew_SetReg1(pVBInfo->Part4Port, 0x3c, + (unsigned short) (temp2 & 0xff)); + XGINew_SetReg1(pVBInfo->Part4Port, 0x3b, + (unsigned short) ((temp2 >> 8) + & 0xff)); + tempbx = (unsigned short) (temp2 >> 16); + XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x3a, + ~0xc0, + (unsigned short) ((tempbx + & 0xff) << 6)); - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + tempcx = pVBInfo->VGAVDE; + if (tempcx == pVBInfo->VDE) + XGINew_SetRegANDOR(pVBInfo->Part4Port, + 0x30, ~0x0c, 0x00); + else + XGINew_SetRegANDOR(pVBInfo->Part4Port, + 0x30, ~0x0c, 0x08); + } - /* ModeType = modeflag&ModeInfoFlag; // Get mode type */ + tempcx = pVBInfo->VGAHDE; + tempbx = pVBInfo->HDE; - memorysize = modeflag & MemoryInfoFlag; - memorysize = memorysize > MemorySizeShift; - memorysize++; /* Get memory size */ + temp1 = tempcx << 16; - temp = XGINew_GetReg1(pVBInfo->P3c4, 0x14); /* Get DRAM Size */ - tmp = temp; + tempax = (unsigned short) (temp1 / tempbx); - if (HwDeviceExtension->jChipType == XG40) { - temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */ - if ((tmp & 0x0c) == 0x0C) { /* Qual channels */ - temp <<= 2; - } else if ((tmp & 0x0c) == 0x08) { /* Dual channels */ - temp <<= 1; - } - } else if (HwDeviceExtension->jChipType == XG42) { - temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */ - if ((tmp & 0x04) == 0x04) { /* Dual channels */ - temp <<= 1; - } - } else if (HwDeviceExtension->jChipType == XG45) { - temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */ - if ((tmp & 0x0c) == 0x0C) { /* Qual channels */ - temp <<= 2; - } else if ((tmp & 0x0c) == 0x08) { /* triple channels */ - temp1 = temp; - temp <<= 1; - temp += temp1; - } else if ((tmp & 0x0c) == 0x04) { /* Dual channels */ - temp <<= 1; - } - } - if (temp < memorysize) - return 0; - else - return 1; -} -#endif + if ((tempbx & 0xffff) == (tempcx & 0xffff)) + tempax = 65535; -/* -void XGINew_IsLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned char XGINew_CheckMemorySize(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) -{ - unsigned short data ; - unsigned short ModeFlag ; + temp3 = tempax; + temp1 = pVBInfo->VGAHDE << 16; - data = XGINew_GetReg1(pVBInfo->P3c4, 0x0F); - data &= 0x7F; - XGINew_SetReg1(pVBInfo->P3c4, 0x0F, data); + temp1 /= temp3; + temp3 = temp3 << 16; + temp1 -= 1; - if (ModeNo > 0x13) { - ModeFlag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - if ((ModeFlag & HalfDCLK) && (ModeFlag & DoubleScanMode)) { - data = XGINew_GetReg1(pVBInfo->P3c4, 0x0F); - data |= 0x80; - XGINew_SetReg1(pVBInfo->P3c4, 0x0F, data); - data = XGINew_GetReg1(pVBInfo->P3c4, 0x01); - data &= 0xF7; - XGINew_SetReg1(pVBInfo->P3c4, 0x01, data); - } - } -} -*/ + temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff); -void XGI_DisplayOn(struct xgi_hw_device_info *pXGIHWDE, - struct vb_device_info *pVBInfo) -{ + tempax = (unsigned short) (temp3 & 0xff); + XGINew_SetReg1(pVBInfo->Part1Port, 0x1f, tempax); - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x00); - if (pXGIHWDE->jChipType == XG21) { - if (pVBInfo->IF_DEF_LVDS == 1) { - if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x1)) { - XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */ - XGI_XG21SetPanelDelay(2, pVBInfo); - } - if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x20)) - XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */ - XGI_XG21SetPanelDelay(3, pVBInfo); - XGI_XG21BLSignalVDD(0x02, 0x02, pVBInfo); /* LVDS backlight on */ - } else { - XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); /* DVO/DVI signal on */ - } + temp1 = pVBInfo->VGAVDE << 18; + temp1 = temp1 / push3; + tempbx = (unsigned short) (temp1 & 0xffff); - } + if (pVBInfo->LCDResInfo == Panel1024x768) + tempbx -= 1; - if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/23 For CH7007 */ + tempax = ((tempbx >> 8) & 0xff) << 3; + tempax |= (unsigned short) ((temp3 >> 8) & 0x07); + XGINew_SetReg1(pVBInfo->Part1Port, 0x20, + (unsigned short) (tempax & 0xff)); + XGINew_SetReg1(pVBInfo->Part1Port, 0x21, + (unsigned short) (tempbx & 0xff)); - } + temp3 = temp3 >> 16; - if (pXGIHWDE->jChipType == XG27) { - if (pVBInfo->IF_DEF_LVDS == 1) { - if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x1)) { - XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */ - XGI_XG21SetPanelDelay(2, pVBInfo); - } - if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x20)) - XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */ - XGI_XG21SetPanelDelay(3, pVBInfo); - XGI_XG27BLSignalVDD(0x02, 0x02, pVBInfo); /* LVDS backlight on */ - } else { - XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); /* DVO/DVI signal on */ - } + if (modeflag & HalfDCLK) + temp3 = temp3 >> 1; + XGINew_SetReg1(pVBInfo->Part1Port, 0x22, + (unsigned short) ((temp3 >> 8) & 0xff)); + XGINew_SetReg1(pVBInfo->Part1Port, 0x23, + (unsigned short) (temp3 & 0xff)); + } } } -void XGI_DisplayOff(struct xgi_hw_device_info *pXGIHWDE, +/* --------------------------------------------------------------------- */ +/* Function : XGI_GETLCDVCLKPtr */ +/* Input : */ +/* Output : al -> VCLK Index */ +/* Description : */ +/* --------------------------------------------------------------------- */ +static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1, struct vb_device_info *pVBInfo) { + unsigned short index; - if (pXGIHWDE->jChipType == XG21) { - if (pVBInfo->IF_DEF_LVDS == 1) { - XGI_XG21BLSignalVDD(0x02, 0x00, pVBInfo); /* LVDS backlight off */ - XGI_XG21SetPanelDelay(3, pVBInfo); - } else { - XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo); /* DVO/DVI signal off */ + if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + if (pVBInfo->IF_DEF_ScaleLCD == 1) { + if (pVBInfo->LCDInfo & EnableScalingLCD) + return; } - } - if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/23 For CH7007 */ - /* if (IsCH7007TVMode(pVBInfo) == 0) */ - { - } - } + /* index = XGI_GetLCDCapPtr(pVBInfo); */ + index = XGI_GetLCDCapPtr1(pVBInfo); - if (pXGIHWDE->jChipType == XG27) { - if ((XGI_XG27GetPSCValue(pVBInfo) & 0x2)) { - XGI_XG27BLSignalVDD(0x02, 0x00, pVBInfo); /* LVDS backlight off */ - XGI_XG21SetPanelDelay(3, pVBInfo); + if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */ + *di_0 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData1; + *di_1 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData2; + } else { /* LCDA */ + *di_0 = pVBInfo->LCDCapList[index].LCDA_VCLKData1; + *di_1 = pVBInfo->LCDCapList[index].LCDA_VCLKData2; } - - if (pVBInfo->IF_DEF_LVDS == 0) - XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo); /* DVO/DVI signal off */ } - - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x20); -} - -static void XGI_WaitDisply(struct vb_device_info *pVBInfo) -{ - while ((XGINew_GetReg2(pVBInfo->P3da) & 0x01)) - break; - - while (!(XGINew_GetReg2(pVBInfo->P3da) & 0x01)) - break; + return; } -void XGI_SenseCRT1(struct vb_device_info *pVBInfo) +static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, + unsigned short ModeNo, unsigned short ModeIdIndex, + struct vb_device_info *pVBInfo) { - unsigned char CRTCData[17] = { 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, - 0x0B, 0x3E, 0xE9, 0x0B, 0xDF, 0xE7, 0x04, 0x00, 0x00, - 0x05, 0x00 }; - - unsigned char SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0; - - unsigned char CR17, CR63, SR31; - unsigned short temp; - unsigned char DAC_TEST_PARMS[3] = { 0x0F, 0x0F, 0x0F }; - - int i; - XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86); - - /* [2004/05/06] Vicent to fix XG42 single LCD sense to CRT+LCD */ - XGINew_SetReg1(pVBInfo->P3d4, 0x57, 0x4A); - XGINew_SetReg1(pVBInfo->P3d4, 0x53, (unsigned char) (XGINew_GetReg1( - pVBInfo->P3d4, 0x53) | 0x02)); - SR31 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x31); - CR63 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x63); - SR01 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x01); + unsigned short index, modeflag; + unsigned short tempbx; + unsigned char tempal; + unsigned char *CHTVVCLKPtr = NULL; - XGINew_SetReg1(pVBInfo->P3c4, 0x01, (unsigned char) (SR01 & 0xDF)); - XGINew_SetReg1(pVBInfo->P3d4, 0x63, (unsigned char) (CR63 & 0xBF)); + if (ModeNo <= 0x13) + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */ + else + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */ - CR17 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x17); - XGINew_SetReg1(pVBInfo->P3d4, 0x17, (unsigned char) (CR17 | 0x80)); + if ((pVBInfo->SetFlag & ProgrammingCRT2) && (!(pVBInfo->LCDInfo + & EnableScalingLCD))) { /* {LCDA/LCDB} */ + index = XGI_GetLCDCapPtr(pVBInfo); + tempal = pVBInfo->LCDCapList[index].LCD_VCLK; - SR1F = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x1F); - XGINew_SetReg1(pVBInfo->P3c4, 0x1F, (unsigned char) (SR1F | 0x04)); + if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) + return tempal; - SR07 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x07); - XGINew_SetReg1(pVBInfo->P3c4, 0x07, (unsigned char) (SR07 & 0xFB)); - SR06 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x06); - XGINew_SetReg1(pVBInfo->P3c4, 0x06, (unsigned char) (SR06 & 0xC3)); + /* {TV} */ + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV + | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + tempal = HiTVVCLKDIV2; + if (!(pVBInfo->TVInfo & RPLLDIV2XO)) + tempal = HiTVVCLK; + if (pVBInfo->TVInfo & TVSimuMode) { + tempal = HiTVSimuVCLK; + if (!(modeflag & Charx8Dot)) + tempal = HiTVTextVCLK; - XGINew_SetReg1(pVBInfo->P3d4, 0x11, 0x00); + } + return tempal; + } - for (i = 0; i < 8; i++) - XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) i, CRTCData[i]); + if (pVBInfo->TVInfo & SetYPbPrMode750p) { + tempal = YPbPr750pVCLK; + return tempal; + } - for (i = 8; i < 11; i++) - XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 8), - CRTCData[i]); + if (pVBInfo->TVInfo & SetYPbPrMode525p) { + tempal = YPbPr525pVCLK; + return tempal; + } - for (i = 11; i < 13; i++) - XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 4), - CRTCData[i]); + tempal = NTSC1024VCLK; - for (i = 13; i < 16; i++) - XGINew_SetReg1(pVBInfo->P3c4, (unsigned short) (i - 3), - CRTCData[i]); + if (!(pVBInfo->TVInfo & NTSC1024x768)) { + tempal = TVVCLKDIV2; + if (!(pVBInfo->TVInfo & RPLLDIV2XO)) + tempal = TVVCLK; + } - XGINew_SetReg1(pVBInfo->P3c4, 0x0E, (unsigned char) (CRTCData[16] - & 0xE0)); + if (pVBInfo->VBInfo & SetCRT2ToTV) + return tempal; + } + /* else if ((pVBInfo->IF_DEF_CH7017==1)&&(pVBInfo->VBType&VB_CH7017)) { + if (ModeNo<=0x13) + *tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; + else + *tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + *tempal = *tempal & 0x1F; + tempbx = 0; + if (pVBInfo->TVInfo & SetPALTV) + tempbx = tempbx + 2; + if (pVBInfo->TVInfo & SetCHTVOverScan) + tempbx++; + tempbx = tempbx << 1; + } */ + } /* {End of VB} */ - XGINew_SetReg1(pVBInfo->P3c4, 0x31, 0x00); - XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x1B); - XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE1); + if ((pVBInfo->IF_DEF_CH7007 == 1) && (pVBInfo->VBType & VB_CH7007)) { /* [Billy] 07/05/08 CH7007 */ + /* VideoDebugPrint((0, "XGI_GetVCLKPtr: pVBInfo->IF_DEF_CH7007==1\n")); */ + if ((pVBInfo->VBInfo & SetCRT2ToTV)) { + if (ModeNo <= 0x13) { + tempal + = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; + } else { + tempal + = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + } - XGINew_SetReg3(pVBInfo->P3c8, 0x00); + tempal = tempal & 0x0F; + tempbx = 0; - for (i = 0; i < 256; i++) { - XGINew_SetReg3((pVBInfo->P3c8 + 1), - (unsigned char) DAC_TEST_PARMS[0]); - XGINew_SetReg3((pVBInfo->P3c8 + 1), - (unsigned char) DAC_TEST_PARMS[1]); - XGINew_SetReg3((pVBInfo->P3c8 + 1), - (unsigned char) DAC_TEST_PARMS[2]); - } + if (pVBInfo->TVInfo & SetPALTV) + tempbx = tempbx + 2; - XGI_VBLongWait(pVBInfo); - XGI_VBLongWait(pVBInfo); - XGI_VBLongWait(pVBInfo); + if (pVBInfo->TVInfo & SetCHTVOverScan) + tempbx++; - mdelay(1); + /** tempbx = tempbx << 1; CH7007 ? **/ - XGI_WaitDisply(pVBInfo); - temp = XGINew_GetReg2(pVBInfo->P3c2); + /* [Billy]07/05/29 CH7007 */ + if (pVBInfo->IF_DEF_CH7007 == 1) { + switch (tempbx) { + case 0: + CHTVVCLKPtr = XGI7007_CHTVVCLKUNTSC; + break; + case 1: + CHTVVCLKPtr = XGI7007_CHTVVCLKONTSC; + break; + case 2: + CHTVVCLKPtr = XGI7007_CHTVVCLKUPAL; + break; + case 3: + CHTVVCLKPtr = XGI7007_CHTVVCLKOPAL; + break; + default: + break; - if (temp & 0x10) - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xDF, 0x20); - else - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xDF, 0x00); + } + } + /* else { + switch(tempbx) { + case 0: + CHTVVCLKPtr = pVBInfo->CHTVVCLKUNTSC; + break; + case 1: + CHTVVCLKPtr = pVBInfo->CHTVVCLKONTSC; + break; + case 2: + CHTVVCLKPtr = pVBInfo->CHTVVCLKUPAL; + break; + case 3: + CHTVVCLKPtr = pVBInfo->CHTVVCLKOPAL; + break; + default: + break; + } + } + */ - /* alan, avoid display something, set BLACK DAC if not restore DAC */ - XGINew_SetReg3(pVBInfo->P3c8, 0x00); + tempal = CHTVVCLKPtr[tempal]; + return tempal; + } - for (i = 0; i < 256; i++) { - XGINew_SetReg3((pVBInfo->P3c8 + 1), 0); - XGINew_SetReg3((pVBInfo->P3c8 + 1), 0); - XGINew_SetReg3((pVBInfo->P3c8 + 1), 0); } - XGINew_SetReg1(pVBInfo->P3c4, 0x01, SR01); - XGINew_SetReg1(pVBInfo->P3d4, 0x63, CR63); - XGINew_SetReg1(pVBInfo->P3c4, 0x31, SR31); + tempal = (unsigned char) XGINew_GetReg2((pVBInfo->P3ca + 0x02)); + tempal = tempal >> 2; + tempal &= 0x03; - /* [2004/05/11] Vicent */ - XGINew_SetReg1(pVBInfo->P3d4, 0x53, (unsigned char) (XGINew_GetReg1( - pVBInfo->P3d4, 0x53) & 0xFD)); - XGINew_SetReg1(pVBInfo->P3c4, 0x1F, (unsigned char) SR1F); + if ((pVBInfo->LCDInfo & EnableScalingLCD) && (modeflag & Charx8Dot)) /* for Dot8 Scaling LCD */ + tempal = tempal ^ tempal; /* ; set to VCLK25MHz always */ + + if (ModeNo <= 0x13) + return tempal; + + tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; + return tempal; } -#if 0 -static void XGI_WaitDisplay(struct vb_device_info *pVBInfo) +static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0, + unsigned char *di_1, struct vb_device_info *pVBInfo) { - while (!(XGINew_GetReg2(pVBInfo->P3da) & 0x01)); - while (XGINew_GetReg2(pVBInfo->P3da) & 0x01); + if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 2007/05/16 */ + /* VideoDebugPrint((0, "XGI_GetVCLKLen: pVBInfo->IF_DEF_CH7007==1\n")); */ + *di_0 = (unsigned char) XGI_CH7007VCLKData[tempal].SR2B; + *di_1 = (unsigned char) XGI_CH7007VCLKData[tempal].SR2C; + } else if (pVBInfo->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI302B + | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { + if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA)) && (pVBInfo->SetFlag + & ProgrammingCRT2)) { + *di_0 = (unsigned char) XGI_VBVCLKData[tempal].SR2B; + *di_1 = XGI_VBVCLKData[tempal].SR2C; + } + } else { + *di_0 = XGI_VCLKData[tempal].SR2B; + *di_1 = XGI_VCLKData[tempal].SR2C; + } } -#endif -unsigned char XGI_SetCRT2Group301(unsigned short ModeNo, - struct xgi_hw_device_info *HwDeviceExtension, +static void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex, + unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - unsigned short tempbx, ModeIdIndex, RefreshRateTableIndex; + unsigned char di_0, di_1, tempal; + int i; - tempbx = pVBInfo->VBInfo; - pVBInfo->SetFlag |= ProgrammingCRT2; - XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo); - pVBInfo->SelectCRT2Rate = 4; - RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, - ModeIdIndex, pVBInfo); - XGI_SaveCRT2Info(ModeNo, pVBInfo); - XGI_GetCRT2ResInfo(ModeNo, ModeIdIndex, pVBInfo); - XGI_GetCRT2Data(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); - XGI_PreSetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension, - RefreshRateTableIndex, pVBInfo); - XGI_SetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension, - RefreshRateTableIndex, pVBInfo); - XGI_SetLockRegs(ModeNo, ModeIdIndex, HwDeviceExtension, - RefreshRateTableIndex, pVBInfo); - XGI_SetGroup2(ModeNo, ModeIdIndex, RefreshRateTableIndex, - HwDeviceExtension, pVBInfo); - XGI_SetLCDRegs(ModeNo, ModeIdIndex, HwDeviceExtension, - RefreshRateTableIndex, pVBInfo); - XGI_SetTap4Regs(pVBInfo); - XGI_SetGroup3(ModeNo, ModeIdIndex, pVBInfo); - XGI_SetGroup4(ModeNo, ModeIdIndex, RefreshRateTableIndex, - HwDeviceExtension, pVBInfo); - XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); - XGI_SetGroup5(ModeNo, ModeIdIndex, pVBInfo); - XGI_AutoThreshold(pVBInfo); - return 1; + tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex, + pVBInfo); + XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo); + XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo); + + for (i = 0; i < 4; i++) { + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x31, ~0x30, + (unsigned short) (0x10 * i)); + if (pVBInfo->IF_DEF_CH7007 == 1) { + XGINew_SetReg1(pVBInfo->P3c4, 0x2b, di_0); + XGINew_SetReg1(pVBInfo->P3c4, 0x2c, di_1); + } else if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA)) + && (!(pVBInfo->VBInfo & SetInSlaveMode))) { + XGINew_SetReg1(pVBInfo->P3c4, 0x2e, di_0); + XGINew_SetReg1(pVBInfo->P3c4, 0x2f, di_1); + } else { + XGINew_SetReg1(pVBInfo->P3c4, 0x2b, di_0); + XGINew_SetReg1(pVBInfo->P3c4, 0x2c, di_1); + } + } } -static void XGI_AutoThreshold(struct vb_device_info *pVBInfo) +static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, + struct vb_device_info *pVBInfo) { - if (!(pVBInfo->SetFlag & Win9xDOSMode)) - XGINew_SetRegOR(pVBInfo->Part1Port, 0x01, 0x40); -} + unsigned short tempcl, tempch, temp, tempbl, tempax; -static void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBInfo) -{ - unsigned short temp1, temp2; + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV + | VB_XGI302LV | VB_XGI301C)) { + tempcl = 0; + tempch = 0; + temp = XGINew_GetReg1(pVBInfo->P3c4, 0x01); - XGINew_SetReg1(pVBInfo->P3d4, 0x34, ModeNo); /* reserve CR34 for CRT1 Mode No */ - temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8; - temp2 = ~(SetInSlaveMode >> 8); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x31, temp2, temp1); -} + if (!(temp & 0x20)) { + temp = XGINew_GetReg1(pVBInfo->P3d4, 0x17); + if (temp & 0x80) { + if ((HwDeviceExtension->jChipType >= XG20) + || (HwDeviceExtension->jChipType + >= XG40)) + temp = XGINew_GetReg1(pVBInfo->P3d4, + 0x53); + else + temp = XGINew_GetReg1(pVBInfo->P3d4, + 0x63); -static void XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short xres, yres, modeflag, resindex; + if (!(temp & 0x40)) + tempcl |= ActiveCRT1; + } + } - resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); - if (ModeNo <= 0x13) { - xres = pVBInfo->StResInfo[resindex].HTotal; - yres = pVBInfo->StResInfo[resindex].VTotal; - /* modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; si+St_ResInfo */ - } else { - xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ - yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+St_ModeFlag */ + temp = XGINew_GetReg1(pVBInfo->Part1Port, 0x2e); + temp &= 0x0f; - /* - if (pVBInfo->IF_DEF_FSTN) { - xres *= 2; - yres *= 2; - } else { - */ - if (modeflag & HalfDCLK) - xres *= 2; + if (!(temp == 0x08)) { + tempax = XGINew_GetReg1(pVBInfo->Part1Port, 0x13); /* Check ChannelA by Part1_13 [2003/10/03] */ + if (tempax & 0x04) + tempcl = tempcl | ActiveLCD; - if (modeflag & DoubleScanMode) - yres *= 2; - /* } */ - } + temp &= 0x05; - if (pVBInfo->VBInfo & SetCRT2ToLCD) { - if (pVBInfo->IF_DEF_LVDS == 0) { - if (pVBInfo->LCDResInfo == Panel1600x1200) { - if (!(pVBInfo->LCDInfo & LCDVESATiming)) { - if (yres == 1024) - yres = 1056; + if (!(tempcl & ActiveLCD)) + if (temp == 0x01) + tempcl |= ActiveCRT2; + + if (temp == 0x04) + tempcl |= ActiveLCD; + + if (temp == 0x05) { + temp = XGINew_GetReg1(pVBInfo->Part2Port, 0x00); + + if (!(temp & 0x08)) + tempch |= ActiveAVideo; + + if (!(temp & 0x04)) + tempch |= ActiveSVideo; + + if (temp & 0x02) + tempch |= ActiveSCART; + + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + if (temp & 0x01) + tempch |= ActiveHiTV; } - } - if (pVBInfo->LCDResInfo == Panel1280x1024) { - if (yres == 400) - yres = 405; - else if (yres == 350) - yres = 360; + if (pVBInfo->VBInfo & SetCRT2ToYPbPr) { + temp = XGINew_GetReg1( + pVBInfo->Part2Port, + 0x4d); - if (pVBInfo->LCDInfo & LCDVESATiming) { - if (yres == 360) - yres = 375; + if (temp & 0x10) + tempch |= ActiveYPbPr; } + + if (tempch != 0) + tempcl |= ActiveTV; } + } - if (pVBInfo->LCDResInfo == Panel1024x768) { - if (!(pVBInfo->LCDInfo & LCDVESATiming)) { - if (!(pVBInfo->LCDInfo - & LCDNonExpanding)) { - if (yres == 350) - yres = 357; - else if (yres == 400) - yres = 420; - else if (yres == 480) - yres = 525; - } - } + temp = XGINew_GetReg1(pVBInfo->P3d4, 0x3d); + if (tempcl & ActiveLCD) { + if ((pVBInfo->SetFlag & ReserveTVOption)) { + if (temp & ActiveTV) + tempcl |= ActiveTV; } } + temp = tempcl; + tempbl = ~ModeSwitchStatus; + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x3d, tempbl, temp); - if (xres == 720) - xres = 640; + if (!(pVBInfo->SetFlag & ReserveTVOption)) + XGINew_SetReg1(pVBInfo->P3d4, 0x3e, tempch); + } else { + return; } +} - pVBInfo->VGAHDE = xres; - pVBInfo->HDE = xres; - pVBInfo->VGAVDE = yres; - pVBInfo->VDE = yres; +void XGI_GetVGAType(struct xgi_hw_device_info *HwDeviceExtension, + struct vb_device_info *pVBInfo) +{ + /* + if ( HwDeviceExtension->jChipType >= XG20 ) { + pVBInfo->Set_VGAType = XG20; + } else if (HwDeviceExtension->jChipType >= XG40) { + pVBInfo->Set_VGAType = VGA_XGI340; + } + */ + pVBInfo->Set_VGAType = HwDeviceExtension->jChipType; } -static unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo) +void XGI_GetVBType(struct vb_device_info *pVBInfo) { + unsigned short flag, tempbx, tempah; - if ((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) && - (pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */ - return 1; + if (pVBInfo->IF_DEF_CH7007 == 1) { + pVBInfo->VBType = VB_CH7007; + return; + } + if (pVBInfo->IF_DEF_LVDS == 0) { + tempbx = VB_XGI302B; + flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x00); + if (flag != 0x02) { + tempbx = VB_XGI301; + flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x01); + if (flag >= 0xB0) { + tempbx = VB_XGI301B; + if (flag >= 0xC0) { + tempbx = VB_XGI301C; + if (flag >= 0xD0) { + tempbx = VB_XGI301LV; + if (flag >= 0xE0) { + tempbx = VB_XGI302LV; + tempah + = XGINew_GetReg1( + pVBInfo->Part4Port, + 0x39); + if (tempah != 0xFF) + tempbx + = VB_XGI301C; + } + } + } + + if (tempbx & (VB_XGI301B | VB_XGI302B)) { + flag = XGINew_GetReg1( + pVBInfo->Part4Port, + 0x23); + + if (!(flag & 0x02)) + tempbx = tempbx | VB_NoLCD; + } + } + } + pVBInfo->VBType = tempbx; + } + /* + else if (pVBInfo->IF_DEF_CH7017 == 1) + pVBInfo->VBType = VB_CH7017; + else //LVDS + pVBInfo->VBType = VB_LVDS_NS; + */ - return 0; } -static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, +void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, + struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - unsigned short tempax = 0, tempbx, modeflag, resinfo; + unsigned short tempax, push, tempbx, temp, modeflag; - struct XGI_LCDDataStruct *LCDPtr = NULL; - struct XGI_TVDataStruct *TVPtr = NULL; + if (ModeNo <= 0x13) + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; + else + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */ - resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */ - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - } + pVBInfo->SetFlag = 0; + pVBInfo->ModeType = modeflag & ModeInfoFlag; + tempbx = 0; + + if (pVBInfo->VBType & 0xFFFF) { + temp = XGINew_GetReg1(pVBInfo->P3d4, 0x30); /* Check Display Device */ + tempbx = tempbx | temp; + temp = XGINew_GetReg1(pVBInfo->P3d4, 0x31); + push = temp; + push = push << 8; + tempax = temp << 8; + tempbx = tempbx | tempax; + temp = (SetCRT2ToDualEdge | SetCRT2ToYPbPr | SetCRT2ToLCDA + | SetInSlaveMode | DisableCRT2Display); + temp = 0xFFFF ^ temp; + tempbx &= temp; + + temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38); + + if (pVBInfo->IF_DEF_LCDA == 1) { + + if ((pVBInfo->Set_VGAType >= XG20) + || (pVBInfo->Set_VGAType >= XG40)) { + if (pVBInfo->IF_DEF_LVDS == 0) { + /* if ((pVBInfo->VBType & VB_XGI302B) || (pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType & VB_XGI301C)) */ + if (pVBInfo->VBType & (VB_XGI302B + | VB_XGI301LV + | VB_XGI302LV + | VB_XGI301C)) { + if (temp & EnableDualEdge) { + tempbx + |= SetCRT2ToDualEdge; - pVBInfo->NewFlickerMode = 0; - pVBInfo->RVBHRS = 50; + if (temp & SetToLCDA) + tempbx + |= SetCRT2ToLCDA; + } + } + } else if (pVBInfo->IF_DEF_CH7017 == 1) { + if (pVBInfo->VBType & VB_CH7017) { + if (temp & EnableDualEdge) { + tempbx + |= SetCRT2ToDualEdge; - if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { - XGI_GetRAMDAC2DATA(ModeNo, ModeIdIndex, RefreshRateTableIndex, - pVBInfo); - return; - } + if (temp & SetToLCDA) + tempbx + |= SetCRT2ToLCDA; + } + } + } + } + } - tempbx = 4; + if (pVBInfo->IF_DEF_YPbPr == 1) { + if (((pVBInfo->IF_DEF_LVDS == 0) && ((pVBInfo->VBType + & VB_XGI301LV) || (pVBInfo->VBType + & VB_XGI302LV) || (pVBInfo->VBType + & VB_XGI301C))) + || ((pVBInfo->IF_DEF_CH7017 == 1) + && (pVBInfo->VBType + & VB_CH7017)) + || ((pVBInfo->IF_DEF_CH7007 == 1) + && (pVBInfo->VBType + & VB_CH7007))) { /* [Billy] 07/05/04 */ + if (temp & SetYPbPr) { /* temp = CR38 */ + if (pVBInfo->IF_DEF_HiVision == 1) { + temp = XGINew_GetReg1( + pVBInfo->P3d4, + 0x35); /* shampoo add for new scratch */ + temp &= YPbPrMode; + tempbx |= SetCRT2ToHiVisionTV; - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { - LCDPtr = (struct XGI_LCDDataStruct *) XGI_GetLcdPtr(tempbx, - ModeNo, ModeIdIndex, RefreshRateTableIndex, - pVBInfo); + if (temp != YPbPrMode1080i) { + tempbx + &= (~SetCRT2ToHiVisionTV); + tempbx + |= SetCRT2ToYPbPr; + } + } - pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX; - pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT; - pVBInfo->VGAHT = LCDPtr->VGAHT; - pVBInfo->VGAVT = LCDPtr->VGAVT; - pVBInfo->HT = LCDPtr->LCDHT; - pVBInfo->VT = LCDPtr->LCDVT; + /* tempbx |= SetCRT2ToYPbPr; */ + } + } + } - if (pVBInfo->LCDResInfo == Panel1024x768) { - tempax = 1024; - tempbx = 768; + tempax = push; /* restore CR31 */ - if (!(pVBInfo->LCDInfo & LCDVESATiming)) { - if (pVBInfo->VGAVDE == 357) - tempbx = 527; - else if (pVBInfo->VGAVDE == 420) - tempbx = 620; - else if (pVBInfo->VGAVDE == 525) - tempbx = 775; - else if (pVBInfo->VGAVDE == 600) - tempbx = 775; - /* else if (pVBInfo->VGAVDE==350) tempbx=560; */ - /* else if (pVBInfo->VGAVDE==400) tempbx=640; */ + if (pVBInfo->IF_DEF_LVDS == 0) { + if (pVBInfo->IF_DEF_YPbPr == 1) { + if (pVBInfo->IF_DEF_HiVision == 1) + temp = 0x09FC; else - tempbx = 768; + temp = 0x097C; + } else { + if (pVBInfo->IF_DEF_HiVision == 1) + temp = 0x01FC; + else + temp = 0x017C; + } + } else { /* 3nd party chip */ + if (pVBInfo->IF_DEF_CH7017 == 1) + temp = (SetCRT2ToTV | SetCRT2ToLCD + | SetCRT2ToLCDA); + else if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/03 */ + temp = SetCRT2ToTV; } else - tempbx = 768; - } else if (pVBInfo->LCDResInfo == Panel1024x768x75) { - tempax = 1024; - tempbx = 768; - } else if (pVBInfo->LCDResInfo == Panel1280x1024) { - tempax = 1280; - if (pVBInfo->VGAVDE == 360) - tempbx = 768; - else if (pVBInfo->VGAVDE == 375) - tempbx = 800; - else if (pVBInfo->VGAVDE == 405) - tempbx = 864; - else - tempbx = 1024; - } else if (pVBInfo->LCDResInfo == Panel1280x1024x75) { - tempax = 1280; - tempbx = 1024; - } else if (pVBInfo->LCDResInfo == Panel1280x960) { - tempax = 1280; - if (pVBInfo->VGAVDE == 350) - tempbx = 700; - else if (pVBInfo->VGAVDE == 400) - tempbx = 800; - else if (pVBInfo->VGAVDE == 1024) - tempbx = 960; - else - tempbx = 960; - } else if (pVBInfo->LCDResInfo == Panel1400x1050) { - tempax = 1400; - tempbx = 1050; + temp = SetCRT2ToLCD; + } - if (pVBInfo->VGAVDE == 1024) { - tempax = 1280; - tempbx = 1024; - } - } else if (pVBInfo->LCDResInfo == Panel1600x1200) { - tempax = 1600; - tempbx = 1200; /* alan 10/14/2003 */ - if (!(pVBInfo->LCDInfo & LCDVESATiming)) { - if (pVBInfo->VGAVDE == 350) - tempbx = 875; - else if (pVBInfo->VGAVDE == 400) - tempbx = 1000; - } + if (!(tempbx & temp)) { + tempax |= DisableCRT2Display; + tempbx = 0; } - if (pVBInfo->LCDInfo & LCDNonExpanding) { - tempax = pVBInfo->VGAHDE; - tempbx = pVBInfo->VGAVDE; + if (pVBInfo->IF_DEF_LCDA == 1) { /* Select Display Device */ + if (!(pVBInfo->VBType & VB_NoLCD)) { + if (tempbx & SetCRT2ToLCDA) { + if (tempbx & SetSimuScanMode) + tempbx + &= (~(SetCRT2ToLCD + | SetCRT2ToRAMDAC + | SwitchToCRT2)); + else + tempbx + &= (~(SetCRT2ToLCD + | SetCRT2ToRAMDAC + | SetCRT2ToTV + | SwitchToCRT2)); + } + } } - pVBInfo->HDE = tempax; - pVBInfo->VDE = tempbx; - return; - } + /* shampoo add */ + if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) { /* for driver abnormal */ + if (pVBInfo->IF_DEF_CRT2Monitor == 1) { + if (tempbx & SetCRT2ToRAMDAC) { + tempbx &= (0xFF00 | SetCRT2ToRAMDAC + | SwitchToCRT2 + | SetSimuScanMode); + tempbx &= (0x00FF | (~SetCRT2ToYPbPr)); + } + } else { + tempbx &= (~(SetCRT2ToRAMDAC | SetCRT2ToLCD + | SetCRT2ToTV)); + } + } - if (pVBInfo->VBInfo & (SetCRT2ToTV)) { - tempbx = 4; - TVPtr = (struct XGI_TVDataStruct *) XGI_GetTVPtr(tempbx, - ModeNo, ModeIdIndex, RefreshRateTableIndex, - pVBInfo); + if (!(pVBInfo->VBType & VB_NoLCD)) { + if (tempbx & SetCRT2ToLCD) { + tempbx &= (0xFF00 | SetCRT2ToLCD | SwitchToCRT2 + | SetSimuScanMode); + tempbx &= (0x00FF | (~SetCRT2ToYPbPr)); + } + } - pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX; - pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT; - pVBInfo->VGAHT = TVPtr->VGAHT; - pVBInfo->VGAVT = TVPtr->VGAVT; - pVBInfo->HDE = TVPtr->TVHDE; - pVBInfo->VDE = TVPtr->TVVDE; - pVBInfo->RVBHRS = TVPtr->RVBHRS; - pVBInfo->NewFlickerMode = TVPtr->FlickerMode; + if (tempbx & SetCRT2ToSCART) { + tempbx &= (0xFF00 | SetCRT2ToSCART | SwitchToCRT2 + | SetSimuScanMode); + tempbx &= (0x00FF | (~SetCRT2ToYPbPr)); + } - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { - if (resinfo == 0x08) - pVBInfo->NewFlickerMode = 0x40; - else if (resinfo == 0x09) - pVBInfo->NewFlickerMode = 0x40; - else if (resinfo == 0x12) - pVBInfo->NewFlickerMode = 0x40; + if (pVBInfo->IF_DEF_YPbPr == 1) { + if (tempbx & SetCRT2ToYPbPr) + tempbx &= (0xFF00 | SwitchToCRT2 + | SetSimuScanMode); + } - if (pVBInfo->VGAVDE == 350) - pVBInfo->TVInfo |= TVSimuMode; + if (pVBInfo->IF_DEF_HiVision == 1) { + if (tempbx & SetCRT2ToHiVisionTV) + tempbx &= (0xFF00 | SetCRT2ToHiVisionTV + | SwitchToCRT2 + | SetSimuScanMode); + } - tempax = ExtHiTVHT; - tempbx = ExtHiTVVT; + if (tempax & DisableCRT2Display) { /* Set Display Device Info */ + if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) + tempbx = DisableCRT2Display; + } - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (pVBInfo->TVInfo & TVSimuMode) { - tempax = StHiTVHT; - tempbx = StHiTVVT; + if (!(tempbx & DisableCRT2Display)) { + if ((!(tempbx & DriverMode)) + || (!(modeflag & CRT2Mode))) { + if (pVBInfo->IF_DEF_LCDA == 1) { + if (!(tempbx & SetCRT2ToLCDA)) + tempbx + |= (SetInSlaveMode + | SetSimuScanMode); + } - if (!(modeflag & Charx8Dot)) { - tempax = StHiTextTVHT; - tempbx = StHiTextTVVT; + if (pVBInfo->IF_DEF_VideoCapture == 1) { + if (((HwDeviceExtension->jChipType + == XG40) + && (pVBInfo->Set_VGAType + == XG40)) + || ((HwDeviceExtension->jChipType + == XG41) + && (pVBInfo->Set_VGAType + == XG41)) + || ((HwDeviceExtension->jChipType + == XG42) + && (pVBInfo->Set_VGAType + == XG42)) + || ((HwDeviceExtension->jChipType + == XG45) + && (pVBInfo->Set_VGAType + == XG45))) { + if (ModeNo <= 13) { + if (!(tempbx + & SetCRT2ToRAMDAC)) { /*CRT2 not need to support*/ + tempbx + &= (0x00FF + | (~SetInSlaveMode)); + pVBInfo->SetFlag + |= EnableVCMode; + } + } } } } - } else if (pVBInfo->VBInfo & SetCRT2ToYPbPr) { - if (pVBInfo->TVInfo & SetYPbPrMode750p) { - tempax = YPbPrTV750pHT; /* Ext750pTVHT */ - tempbx = YPbPrTV750pVT; /* Ext750pTVVT */ - } - if (pVBInfo->TVInfo & SetYPbPrMode525p) { - tempax = YPbPrTV525pHT; /* Ext525pTVHT */ - tempbx = YPbPrTV525pVT; /* Ext525pTVVT */ - } else if (pVBInfo->TVInfo & SetYPbPrMode525i) { - tempax = YPbPrTV525iHT; /* Ext525iTVHT */ - tempbx = YPbPrTV525iVT; /* Ext525iTVVT */ - if (pVBInfo->TVInfo & NTSC1024x768) - tempax = NTSC1024x768HT; - } - } else { - tempax = PALHT; - tempbx = PALVT; - if (!(pVBInfo->TVInfo & SetPALTV)) { - tempax = NTSCHT; - tempbx = NTSCVT; - if (pVBInfo->TVInfo & NTSC1024x768) - tempax = NTSC1024x768HT; + /* LCD+TV can't support in slave mode (Force LCDA+TV->LCDB) */ + if ((tempbx & SetInSlaveMode) && (tempbx + & SetCRT2ToLCDA)) { + tempbx ^= (SetCRT2ToLCD | SetCRT2ToLCDA + | SetCRT2ToDualEdge); + pVBInfo->SetFlag |= ReserveTVOption; } } - - pVBInfo->HT = tempax; - pVBInfo->VT = tempbx; - return; } + + pVBInfo->VBInfo = tempbx; } -static void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, +void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { - unsigned char di_0, di_1, tempal; - - tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex, - pVBInfo); - XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo); - XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo); + unsigned short temp, tempbx = 0, resinfo = 0, modeflag, index1; - if (pVBInfo->VBType & VB_XGI301) { /* shampoo 0129 */ - /* 301 */ - XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, 0x10); - XGINew_SetReg1(pVBInfo->Part4Port, 0x0B, di_1); - XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, di_0); - } else { /* 301b/302b/301lv/302lv */ - XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, di_0); - XGINew_SetReg1(pVBInfo->Part4Port, 0x0B, di_1); - } + tempbx = 0; + resinfo = 0; - XGINew_SetReg1(pVBInfo->Part4Port, 0x00, 0x12); + if (pVBInfo->VBInfo & SetCRT2ToTV) { + if (ModeNo <= 0x13) { + modeflag + = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */ + resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */ + } else { + modeflag + = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo + = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */ + } - if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) - XGINew_SetRegOR(pVBInfo->Part4Port, 0x12, 0x28); - else - XGINew_SetRegOR(pVBInfo->Part4Port, 0x12, 0x08); -} + if (pVBInfo->VBInfo & SetCRT2ToTV) { + temp = XGINew_GetReg1(pVBInfo->P3d4, 0x35); + tempbx = temp; + if (tempbx & SetPALTV) { + tempbx &= (SetCHTVOverScan | SetPALMTV + | SetPALNTV | SetPALTV); + if (tempbx & SetPALMTV) + tempbx &= ~SetPALTV; /* set to NTSC if PAL-M */ + } else + tempbx &= (SetCHTVOverScan | SetNTSCJ + | SetPALTV); + /* + if (pVBInfo->IF_DEF_LVDS == 0) { + index1 = XGINew_GetReg1(pVBInfo->P3d4, 0x38); //PAL-M/PAL-N Info + temp2 = (index1 & 0xC0) >> 5; //00:PAL, 01:PAL-M, 10:PAL-N + tempbx |= temp2; + if (temp2 & 0x02) //PAL-M + tempbx &= (~SetPALTV); + } + */ + } -/* --------------------------------------------------------------------- */ -/* Function : XGI_GETLCDVCLKPtr */ -/* Input : */ -/* Output : al -> VCLK Index */ -/* Description : */ -/* --------------------------------------------------------------------- */ -static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1, - struct vb_device_info *pVBInfo) -{ - unsigned short index; + if (pVBInfo->IF_DEF_CH7017 == 1) { + tempbx = XGINew_GetReg1(pVBInfo->P3d4, 0x35); - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { - if (pVBInfo->IF_DEF_ScaleLCD == 1) { - if (pVBInfo->LCDInfo & EnableScalingLCD) - return; + if (tempbx & TVOverScan) + tempbx |= SetCHTVOverScan; } - /* index = XGI_GetLCDCapPtr(pVBInfo); */ - index = XGI_GetLCDCapPtr1(pVBInfo); + if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/04 */ + tempbx = XGINew_GetReg1(pVBInfo->P3d4, 0x35); - if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */ - *di_0 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData1; - *di_1 = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData2; - } else { /* LCDA */ - *di_0 = pVBInfo->LCDCapList[index].LCDA_VCLKData1; - *di_1 = pVBInfo->LCDCapList[index].LCDA_VCLKData2; + if (tempbx & TVOverScan) + tempbx |= SetCHTVOverScan; } - } - return; -} -static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, - unsigned short ModeNo, unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ + if (pVBInfo->IF_DEF_LVDS == 0) { + if (pVBInfo->VBInfo & SetCRT2ToSCART) + tempbx |= SetPALTV; + } - unsigned short index, modeflag; - unsigned short tempbx; - unsigned char tempal; - unsigned char *CHTVVCLKPtr = NULL; + if (pVBInfo->IF_DEF_YPbPr == 1) { + if (pVBInfo->VBInfo & SetCRT2ToYPbPr) { + index1 = XGINew_GetReg1(pVBInfo->P3d4, 0x35); + index1 &= YPbPrMode; - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */ - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */ + if (index1 == YPbPrMode525i) + tempbx |= SetYPbPrMode525i; - if ((pVBInfo->SetFlag & ProgrammingCRT2) && (!(pVBInfo->LCDInfo - & EnableScalingLCD))) { /* {LCDA/LCDB} */ - index = XGI_GetLCDCapPtr(pVBInfo); - tempal = pVBInfo->LCDCapList[index].LCD_VCLK; + if (index1 == YPbPrMode525p) + tempbx = tempbx | SetYPbPrMode525p; + if (index1 == YPbPrMode750p) + tempbx = tempbx | SetYPbPrMode750p; + } + } - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) - return tempal; + if (pVBInfo->IF_DEF_HiVision == 1) { + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) + tempbx = tempbx | SetYPbPrMode1080i | SetPALTV; + } - /* {TV} */ - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { - tempal = HiTVVCLKDIV2; - if (!(pVBInfo->TVInfo & RPLLDIV2XO)) - tempal = HiTVVCLK; - if (pVBInfo->TVInfo & TVSimuMode) { - tempal = HiTVSimuVCLK; - if (!(modeflag & Charx8Dot)) - tempal = HiTVTextVCLK; + if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */ + if ((pVBInfo->VBInfo & SetInSlaveMode) + && (!(pVBInfo->VBInfo & SetNotSimuMode))) + tempbx |= TVSimuMode; + + if (!(tempbx & SetPALTV) && (modeflag > 13) && (resinfo + == 8)) /* NTSC 1024x768, */ + tempbx |= NTSC1024x768; + + tempbx |= RPLLDIV2XO; + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + if (pVBInfo->VBInfo & SetInSlaveMode) + tempbx &= (~RPLLDIV2XO); + } else { + if (tempbx & (SetYPbPrMode525p + | SetYPbPrMode750p)) + tempbx &= (~RPLLDIV2XO); + else if (!(pVBInfo->VBType & (VB_XGI301B + | VB_XGI302B | VB_XGI301LV + | VB_XGI302LV | VB_XGI301C))) { + if (tempbx & TVSimuMode) + tempbx &= (~RPLLDIV2XO); } - return tempal; } + } + } + pVBInfo->TVInfo = tempbx; +} - if (pVBInfo->TVInfo & SetYPbPrMode750p) { - tempal = YPbPr750pVCLK; - return tempal; - } +unsigned char XGI_GetLCDInfo(unsigned short ModeNo, unsigned short ModeIdIndex, + struct vb_device_info *pVBInfo) +{ + unsigned short temp, tempax, tempbx, modeflag, resinfo = 0, LCDIdIndex; - if (pVBInfo->TVInfo & SetYPbPrMode525p) { - tempal = YPbPr525pVCLK; - return tempal; - } + pVBInfo->LCDResInfo = 0; + pVBInfo->LCDTypeInfo = 0; + pVBInfo->LCDInfo = 0; - tempal = NTSC1024VCLK; + if (ModeNo <= 0x13) { + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag // */ + } else { + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo // */ + } - if (!(pVBInfo->TVInfo & NTSC1024x768)) { - tempal = TVVCLKDIV2; - if (!(pVBInfo->TVInfo & RPLLDIV2XO)) - tempal = TVVCLK; - } + temp = XGINew_GetReg1(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */ + tempbx = temp & 0x0F; - if (pVBInfo->VBInfo & SetCRT2ToTV) - return tempal; - } - /* else if ((pVBInfo->IF_DEF_CH7017==1)&&(pVBInfo->VBType&VB_CH7017)) { - if (ModeNo<=0x13) - *tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; + if (tempbx == 0) + tempbx = Panel1024x768; /* default */ + + /* LCD75 [2003/8/22] Vicent */ + if ((tempbx == Panel1024x768) || (tempbx == Panel1280x1024)) { + if (pVBInfo->VBInfo & DriverMode) { + tempax = XGINew_GetReg1(pVBInfo->P3d4, 0x33); + if (pVBInfo->VBInfo & SetCRT2ToLCDA) + tempax &= 0x0F; else - *tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; - *tempal = *tempal & 0x1F; - tempbx = 0; - if (pVBInfo->TVInfo & SetPALTV) - tempbx = tempbx + 2; - if (pVBInfo->TVInfo & SetCHTVOverScan) - tempbx++; - tempbx = tempbx << 1; - } */ - } /* {End of VB} */ + tempax = tempax >> 4; - if ((pVBInfo->IF_DEF_CH7007 == 1) && (pVBInfo->VBType & VB_CH7007)) { /* [Billy] 07/05/08 CH7007 */ - /* VideoDebugPrint((0, "XGI_GetVCLKPtr: pVBInfo->IF_DEF_CH7007==1\n")); */ - if ((pVBInfo->VBInfo & SetCRT2ToTV)) { - if (ModeNo <= 0x13) { - tempal - = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; - } else { - tempal - = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + if ((resinfo == 6) || (resinfo == 9)) { + if (tempax >= 3) + tempbx |= PanelRef75Hz; + } else if ((resinfo == 7) || (resinfo == 8)) { + if (tempax >= 4) + tempbx |= PanelRef75Hz; } + } + } - tempal = tempal & 0x0F; - tempbx = 0; - - if (pVBInfo->TVInfo & SetPALTV) - tempbx = tempbx + 2; + pVBInfo->LCDResInfo = tempbx; - if (pVBInfo->TVInfo & SetCHTVOverScan) - tempbx++; + /* End of LCD75 */ - /** tempbx = tempbx << 1; CH7007 ? **/ + if (pVBInfo->IF_DEF_OEMUtil == 1) + pVBInfo->LCDTypeInfo = (temp & 0xf0) >> 4; - /* [Billy]07/05/29 CH7007 */ - if (pVBInfo->IF_DEF_CH7007 == 1) { - switch (tempbx) { - case 0: - CHTVVCLKPtr = XGI7007_CHTVVCLKUNTSC; - break; - case 1: - CHTVVCLKPtr = XGI7007_CHTVVCLKONTSC; - break; - case 2: - CHTVVCLKPtr = XGI7007_CHTVVCLKUPAL; - break; - case 3: - CHTVVCLKPtr = XGI7007_CHTVVCLKOPAL; - break; - default: - break; + if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) + return 0; - } - } - /* else { - switch(tempbx) { - case 0: - CHTVVCLKPtr = pVBInfo->CHTVVCLKUNTSC; - break; - case 1: - CHTVVCLKPtr = pVBInfo->CHTVVCLKONTSC; - break; - case 2: - CHTVVCLKPtr = pVBInfo->CHTVVCLKUPAL; - break; - case 3: - CHTVVCLKPtr = pVBInfo->CHTVVCLKOPAL; - break; - default: - break; - } - } - */ + tempbx = 0; - tempal = CHTVVCLKPtr[tempal]; - return tempal; - } + temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); - } + temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable); - tempal = (unsigned char) XGINew_GetReg2((pVBInfo->P3ca + 0x02)); - tempal = tempal >> 2; - tempal &= 0x03; + if ((pVBInfo->IF_DEF_ScaleLCD == 1) && (temp & LCDNonExpanding)) + temp &= ~EnableScalingLCD; - if ((pVBInfo->LCDInfo & EnableScalingLCD) && (modeflag & Charx8Dot)) /* for Dot8 Scaling LCD */ - tempal = tempal ^ tempal; /* ; set to VCLK25MHz always */ + tempbx |= temp; - if (ModeNo <= 0x13) - return tempal; + LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo); - tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; - return tempal; -} + tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability; -static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0, - unsigned char *di_1, struct vb_device_info *pVBInfo) -{ - if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 2007/05/16 */ - /* VideoDebugPrint((0, "XGI_GetVCLKLen: pVBInfo->IF_DEF_CH7007==1\n")); */ - *di_0 = (unsigned char) XGI_CH7007VCLKData[tempal].SR2B; - *di_1 = (unsigned char) XGI_CH7007VCLKData[tempal].SR2C; - } else if (pVBInfo->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI302B - | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { - if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA)) && (pVBInfo->SetFlag - & ProgrammingCRT2)) { - *di_0 = (unsigned char) XGI_VBVCLKData[tempal].SR2B; - *di_1 = XGI_VBVCLKData[tempal].SR2C; + if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */ + if (((pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType + & VB_XGI301C)) && (tempax & LCDDualLink)) { + tempbx |= SetLCDDualLink; } - } else { - *di_0 = XGI_VCLKData[tempal].SR2B; - *di_1 = XGI_VCLKData[tempal].SR2C; } -} - -static void XGI_SetCRT2Offset(unsigned short ModeNo, - unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short offset; - unsigned char temp; - if (pVBInfo->VBInfo & SetInSlaveMode) - return; + if (pVBInfo->IF_DEF_CH7017 == 1) { + if (tempax & LCDDualLink) + tempbx |= SetLCDDualLink; + } - offset = XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex, - HwDeviceExtension, pVBInfo); - temp = (unsigned char) (offset & 0xFF); - XGINew_SetReg1(pVBInfo->Part1Port, 0x07, temp); - temp = (unsigned char) ((offset & 0xFF00) >> 8); - XGINew_SetReg1(pVBInfo->Part1Port, 0x09, temp); - temp = (unsigned char) (((offset >> 3) & 0xFF) + 1); - XGINew_SetReg1(pVBInfo->Part1Port, 0x03, temp); -} + if (pVBInfo->IF_DEF_LVDS == 0) { + if ((pVBInfo->LCDResInfo == Panel1400x1050) && (pVBInfo->VBInfo + & SetCRT2ToLCD) && (ModeNo > 0x13) && (resinfo + == 9) && (!(tempbx & EnableScalingLCD))) + tempbx |= SetLCDtoNonExpanding; /* set to center in 1280x1024 LCDB for Panel1400x1050 */ + } -static unsigned short XGI_GetOffset(unsigned short ModeNo, unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short temp, colordepth, modeinfo, index, infoflag, - ColorDepth[] = { 0x01, 0x02, 0x04 }; + /* + if (tempax & LCDBToA) { + tempbx |= SetLCDBToA; + } + */ - modeinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo; - if (ModeNo <= 0x14) - infoflag = 0; - else - infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + if (pVBInfo->IF_DEF_ExpLink == 1) { + if (modeflag & HalfDCLK) { + /* if (!(pVBInfo->LCDInfo&LCDNonExpanding)) */ + if (!(tempbx & SetLCDtoNonExpanding)) { + tempbx |= EnableLVDSDDA; + } else { + if (ModeNo > 0x13) { + if (pVBInfo->LCDResInfo + == Panel1024x768) { + if (resinfo == 4) { /* 512x384 */ + tempbx |= EnableLVDSDDA; + } + } + } + } + } + } - index = (modeinfo >> 8) & 0xFF; + if (pVBInfo->VBInfo & SetInSlaveMode) { + if (pVBInfo->VBInfo & SetNotSimuMode) + tempbx |= LCDVESATiming; + } else { + tempbx |= LCDVESATiming; + } - temp = pVBInfo->ScreenOffset[index]; + pVBInfo->LCDInfo = tempbx; - if (infoflag & InterlaceMode) - temp = temp << 1; + if (pVBInfo->IF_DEF_PWD == 1) { + if (pVBInfo->LCDInfo & SetPWDEnable) { + if ((pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType + & VB_XGI301C)) { + if (!(tempax & PWDEnable)) + pVBInfo->LCDInfo &= ~SetPWDEnable; + } + } + } - colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo); + if (pVBInfo->IF_DEF_LVDS == 0) { + if (tempax & (LockLCDBToA | StLCDBToA)) { + if (pVBInfo->VBInfo & SetInSlaveMode) { + if (!(tempax & LockLCDBToA)) { + if (ModeNo <= 0x13) { + pVBInfo->VBInfo + &= ~(SetSimuScanMode + | SetInSlaveMode + | SetCRT2ToLCD); + pVBInfo->VBInfo + |= SetCRT2ToLCDA + | SetCRT2ToDualEdge; + } + } + } + } + } - if ((ModeNo >= 0x7C) && (ModeNo <= 0x7E)) { - temp = ModeNo - 0x7C; - colordepth = ColorDepth[temp]; - temp = 0x6B; - if (infoflag & InterlaceMode) - temp = temp << 1; - return temp * colordepth; - } else { - return temp * colordepth; + /* + if (pVBInfo->IF_DEF_LVDS == 0) { + if (tempax & (LockLCDBToA | StLCDBToA)) { + if (pVBInfo->VBInfo & SetInSlaveMode) { + if (!((!(tempax & LockLCDBToA)) && (ModeNo > 0x13))) { + pVBInfo->VBInfo&=~(SetSimuScanMode|SetInSlaveMode|SetCRT2ToLCD); + pVBInfo->VBInfo|=SetCRT2ToLCDA|SetCRT2ToDualEdge; + } + } + } } -} + */ -static void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo) -{ - XGINew_SetReg1(pVBInfo->Part1Port, 0x01, 0x3B); /* threshold high ,disable auto threshold */ - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04); /* threshold low default 04h */ + return 1; } -static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, - struct xgi_hw_device_info *HwDeviceExtension, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) +unsigned char XGI_SearchModeID(unsigned short ModeNo, + unsigned short *ModeIdIndex, struct vb_device_info *pVBInfo) { - unsigned short tempcx = 0, CRT1Index = 0, resinfo = 0; + if (ModeNo <= 5) + ModeNo |= 1; + if (ModeNo <= 0x13) { + /* for (*ModeIdIndex=0; *ModeIdIndex < sizeof(pVBInfo->SModeIDTable) / sizeof(struct XGI_StStruct); (*ModeIdIndex)++) */ + for (*ModeIdIndex = 0;; (*ModeIdIndex)++) { + if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == ModeNo) + break; + if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF) + return 0; + } - if (ModeNo > 0x13) { - CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - CRT1Index &= IndexMask; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + if (ModeNo == 0x07) + (*ModeIdIndex)++; /* 400 lines */ + if (ModeNo <= 3) + (*ModeIdIndex) += 2; /* 400 lines */ + /* else 350 lines */ + } else { + /* for (*ModeIdIndex=0; *ModeIdIndex < sizeof(pVBInfo->EModeIDTable) / sizeof(struct XGI_ExtStruct); (*ModeIdIndex)++) */ + for (*ModeIdIndex = 0;; (*ModeIdIndex)++) { + if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo) + break; + if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) + return 0; + } } - XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex, - HwDeviceExtension, pVBInfo); - XGI_SetCRT2FIFO(pVBInfo); - /* XGI_SetCRT2Sync(ModeNo,RefreshRateTableIndex); */ - - for (tempcx = 4; tempcx < 7; tempcx++) - XGINew_SetReg1(pVBInfo->Part1Port, tempcx, 0x0); - - XGINew_SetReg1(pVBInfo->Part1Port, 0x50, 0x00); - XGINew_SetReg1(pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */ + return 1; } -static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, +/* win2000 MM adapter not support standard mode! */ + +#if 0 +static unsigned char XGINew_CheckMemorySize( struct xgi_hw_device_info *HwDeviceExtension, - unsigned short RefreshRateTableIndex, + unsigned short ModeNo, + unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { - unsigned short temp = 0, tempax = 0, tempbx = 0, tempcx = 0, - pushbx = 0, CRT1Index = 0, modeflag, resinfo = 0; + unsigned short memorysize, modeflag, temp, temp1, tmp; - if (ModeNo > 0x13) { - CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - CRT1Index &= IndexMask; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + /* + if ((HwDeviceExtension->jChipType == XGI_650) || + (HwDeviceExtension->jChipType == XGI_650M)) { + return 1; } + */ if (ModeNo <= 0x13) modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; else modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - /* bainy change table name */ - if (modeflag & HalfDCLK) { - temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x08, temp); - temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4; - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x09, ~0x0F0, temp); - temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp); - tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2; - pushbx = pVBInfo->VGAHDE / 2 + 16; - tempcx = tempcx >> 1; - tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */ - tempcx += tempbx; + /* ModeType = modeflag&ModeInfoFlag; // Get mode type */ - if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { - tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4]; - tempbx |= ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] - & 0xC0) << 2); - tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */ - tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5]; - tempcx &= 0x1F; - temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[15]; - temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */ - tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */ - } + memorysize = modeflag & MemoryInfoFlag; + memorysize = memorysize > MemorySizeShift; + memorysize++; /* Get memory size */ - tempbx += 4; - tempcx += 4; + temp = XGINew_GetReg1(pVBInfo->P3c4, 0x14); /* Get DRAM Size */ + tmp = temp; - if (tempcx > (pVBInfo->VGAHT / 2)) - tempcx = pVBInfo->VGAHT / 2; + if (HwDeviceExtension->jChipType == XG40) { + temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */ + if ((tmp & 0x0c) == 0x0C) { /* Qual channels */ + temp <<= 2; + } else if ((tmp & 0x0c) == 0x08) { /* Dual channels */ + temp <<= 1; + } + } else if (HwDeviceExtension->jChipType == XG42) { + temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */ + if ((tmp & 0x04) == 0x04) { /* Dual channels */ + temp <<= 1; + } + } else if (HwDeviceExtension->jChipType == XG45) { + temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */ + if ((tmp & 0x0c) == 0x0C) { /* Qual channels */ + temp <<= 2; + } else if ((tmp & 0x0c) == 0x08) { /* triple channels */ + temp1 = temp; + temp <<= 1; + temp += temp1; + } else if ((tmp & 0x0c) == 0x04) { /* Dual channels */ + temp <<= 1; + } + } + if (temp < memorysize) + return 0; + else + return 1; +} +#endif - temp = tempbx & 0x00FF; +/* +void XGINew_IsLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned char XGINew_CheckMemorySize(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) +{ + unsigned short data ; + unsigned short ModeFlag ; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp); - } else { - temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x08, temp); - temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4; - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x09, ~0x0F0, temp); - temp = (pVBInfo->VGAHDE + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp); - tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */ - pushbx = pVBInfo->VGAHDE + 16; - tempcx = tempcx >> 1; - tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */ - tempcx += tempbx; + data = XGINew_GetReg1(pVBInfo->P3c4, 0x0F); + data &= 0x7F; + XGINew_SetReg1(pVBInfo->P3c4, 0x0F, data); - if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { - tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[3]; - tempbx |= ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5] - & 0xC0) << 2); - tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */ - tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4]; - tempcx &= 0x1F; - temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[6]; - temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */ - tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */ - tempbx += 16; - tempcx += 16; + if (ModeNo > 0x13) { + ModeFlag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + if ((ModeFlag & HalfDCLK) && (ModeFlag & DoubleScanMode)) { + data = XGINew_GetReg1(pVBInfo->P3c4, 0x0F); + data |= 0x80; + XGINew_SetReg1(pVBInfo->P3c4, 0x0F, data); + data = XGINew_GetReg1(pVBInfo->P3c4, 0x01); + data &= 0xF7; + XGINew_SetReg1(pVBInfo->P3c4, 0x01, data); } + } +} +*/ - if (tempcx > pVBInfo->VGAHT) - tempcx = pVBInfo->VGAHT; +static unsigned char XG21GPIODataTransfer(unsigned char ujDate) +{ + unsigned char ujRet = 0; + unsigned char i = 0; - temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp); + for (i = 0; i < 8; i++) { + ujRet = ujRet << 1; + /* ujRet |= GETBITS(ujDate >> i, 0:0); */ + ujRet |= (ujDate >> i) & 1; } - tempax = (tempax & 0x00FF) | (tempbx & 0xFF00); - tempbx = pushbx; - tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4); - tempax |= (tempbx & 0xFF00); - temp = (tempax & 0xFF00) >> 8; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0C, temp); - temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0D, temp); - tempcx = (pVBInfo->VGAVT - 1); - temp = tempcx & 0x00FF; + return ujRet; +} - if (pVBInfo->IF_DEF_CH7005 == 1) { - if (pVBInfo->VBInfo & 0x0C) - temp--; - } +/*----------------------------------------------------------------------------*/ +/* output */ +/* bl[5] : LVDS signal */ +/* bl[1] : LVDS backlight */ +/* bl[0] : LVDS VDD */ +/*----------------------------------------------------------------------------*/ +static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo) +{ + unsigned char CR4A, temp; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0E, temp); - tempbx = pVBInfo->VGAVDE - 1; - temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0F, temp); - temp = ((tempbx & 0xFF00) << 3) >> 8; - temp |= ((tempcx & 0xFF00) >> 8); - XGINew_SetReg1(pVBInfo->Part1Port, 0x12, temp); + CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A); + XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x23); /* enable GPIO write */ - tempax = pVBInfo->VGAVDE; - tempbx = pVBInfo->VGAVDE; - tempcx = pVBInfo->VGAVT; - tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */ - tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */ + temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); - if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { - tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[10]; - temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9]; + temp = XG21GPIODataTransfer(temp); + temp &= 0x23; + XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A); + return temp; +} + +/*----------------------------------------------------------------------------*/ +/* output */ +/* bl[5] : LVDS signal */ +/* bl[1] : LVDS backlight */ +/* bl[0] : LVDS VDD */ +/*----------------------------------------------------------------------------*/ +static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo) +{ + unsigned char CR4A, CRB4, temp; - if (temp & 0x04) - tempbx |= 0x0100; + CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A); + XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x0C); /* enable GPIO write */ - if (temp & 0x080) - tempbx |= 0x0200; + temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); - temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14]; + temp &= 0x0C; + temp >>= 2; + XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A); + CRB4 = XGINew_GetReg1(pVBInfo->P3d4, 0xB4); + temp |= ((CRB4 & 0x04) << 3); + return temp; +} - if (temp & 0x08) - tempbx |= 0x0400; +void XGI_DisplayOn(struct xgi_hw_device_info *pXGIHWDE, + struct vb_device_info *pVBInfo) +{ + + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x00); + if (pXGIHWDE->jChipType == XG21) { + if (pVBInfo->IF_DEF_LVDS == 1) { + if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x1)) { + XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */ + XGI_XG21SetPanelDelay(2, pVBInfo); + } + if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x20)) + XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */ + XGI_XG21SetPanelDelay(3, pVBInfo); + XGI_XG21BLSignalVDD(0x02, 0x02, pVBInfo); /* LVDS backlight on */ + } else { + XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); /* DVO/DVI signal on */ + } - temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[11]; - tempcx = (tempcx & 0xFF00) | (temp & 0x00FF); } - temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp); - temp = ((tempbx & 0xFF00) >> 8) << 4; - temp = ((tempcx & 0x000F) | (temp)); - XGINew_SetReg1(pVBInfo->Part1Port, 0x11, temp); - tempax = 0; + if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/23 For CH7007 */ - if (modeflag & DoubleScanMode) - tempax |= 0x80; + } - if (modeflag & HalfDCLK) - tempax |= 0x40; + if (pXGIHWDE->jChipType == XG27) { + if (pVBInfo->IF_DEF_LVDS == 1) { + if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x1)) { + XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */ + XGI_XG21SetPanelDelay(2, pVBInfo); + } + if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x20)) + XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */ + XGI_XG21SetPanelDelay(3, pVBInfo); + XGI_XG27BLSignalVDD(0x02, 0x02, pVBInfo); /* LVDS backlight on */ + } else { + XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); /* DVO/DVI signal on */ + } - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax); + } } -static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, - struct xgi_hw_device_info *HwDeviceExtension, - unsigned short RefreshRateTableIndex, +void XGI_DisplayOff(struct xgi_hw_device_info *pXGIHWDE, struct vb_device_info *pVBInfo) { - unsigned short push1, push2, tempax, tempbx = 0, tempcx, temp, resinfo, - modeflag, CRT1Index; - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */ - resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */ - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - CRT1Index &= IndexMask; + if (pXGIHWDE->jChipType == XG21) { + if (pVBInfo->IF_DEF_LVDS == 1) { + XGI_XG21BLSignalVDD(0x02, 0x00, pVBInfo); /* LVDS backlight off */ + XGI_XG21SetPanelDelay(3, pVBInfo); + } else { + XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo); /* DVO/DVI signal off */ + } } - if (!(pVBInfo->VBInfo & SetInSlaveMode)) - return; - - temp = 0xFF; /* set MAX HT */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x03, temp); - /* if (modeflag & Charx8Dot) */ - /* tempcx = 0x08; */ - /* else */ - tempcx = 0x08; - - if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) - modeflag |= Charx8Dot; + if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/23 For CH7007 */ + /* if (IsCH7007TVMode(pVBInfo) == 0) */ + { + } + } - tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */ + if (pXGIHWDE->jChipType == XG27) { + if ((XGI_XG27GetPSCValue(pVBInfo) & 0x2)) { + XGI_XG27BLSignalVDD(0x02, 0x00, pVBInfo); /* LVDS backlight off */ + XGI_XG21SetPanelDelay(3, pVBInfo); + } - if (modeflag & HalfDCLK) - tempax = tempax >> 1; + if (pVBInfo->IF_DEF_LVDS == 0) + XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo); /* DVO/DVI signal off */ + } - tempax = (tempax / tempcx) - 1; - tempbx |= ((tempax & 0x00FF) << 8); - temp = tempax & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x04, temp); + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x20); +} - temp = (tempbx & 0xFF00) >> 8; +static void XGI_WaitDisply(struct vb_device_info *pVBInfo) +{ + while ((XGINew_GetReg2(pVBInfo->P3da) & 0x01)) + break; - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (!(pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C))) - temp += 2; + while (!(XGINew_GetReg2(pVBInfo->P3da) & 0x01)) + break; +} - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { - if (pVBInfo->VBType & VB_XGI301LV) { - if (pVBInfo->VBExtInfo == VB_YPbPr1080i) { - if (resinfo == 7) - temp -= 2; - } - } else if (resinfo == 7) { - temp -= 2; - } - } - } +#if 0 +static void XGI_WaitDisplay(struct vb_device_info *pVBInfo) +{ + while (!(XGINew_GetReg2(pVBInfo->P3da) & 0x01)); + while (XGINew_GetReg2(pVBInfo->P3da) & 0x01); +} +#endif - XGINew_SetReg1(pVBInfo->Part1Port, 0x05, temp); /* 0x05 Horizontal Display Start */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x06, 0x03); /* 0x06 Horizontal Blank end */ +static void XGI_AutoThreshold(struct vb_device_info *pVBInfo) +{ + if (!(pVBInfo->SetFlag & Win9xDOSMode)) + XGINew_SetRegOR(pVBInfo->Part1Port, 0x01, 0x40); +} - if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */ - if (pVBInfo->VBInfo & SetCRT2ToTV) - tempax = pVBInfo->VGAHT; - else - tempax = XGI_GetVGAHT2(pVBInfo); - } +static void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBInfo) +{ + unsigned short temp1, temp2; - if (tempax >= pVBInfo->VGAHT) - tempax = pVBInfo->VGAHT; + XGINew_SetReg1(pVBInfo->P3d4, 0x34, ModeNo); /* reserve CR34 for CRT1 Mode No */ + temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8; + temp2 = ~(SetInSlaveMode >> 8); + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x31, temp2, temp1); +} - if (modeflag & HalfDCLK) - tempax = tempax >> 1; +static void XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, + struct vb_device_info *pVBInfo) +{ + unsigned short xres, yres, modeflag, resindex; - tempax = (tempax / tempcx) - 5; - tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */ - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { - temp = (tempbx & 0x00FF) - 1; - if (!(modeflag & HalfDCLK)) { - temp -= 6; - if (pVBInfo->TVInfo & TVSimuMode) { - temp -= 4; - if (ModeNo > 0x13) - temp -= 10; - } - } + resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); + if (ModeNo <= 0x13) { + xres = pVBInfo->StResInfo[resindex].HTotal; + yres = pVBInfo->StResInfo[resindex].VTotal; + /* modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; si+St_ResInfo */ } else { - /* tempcx = tempbx & 0x00FF ; */ - tempbx = (tempbx & 0xFF00) >> 8; - tempcx = (tempcx + tempbx) >> 1; - temp = (tempcx & 0x00FF) + 2; - - if (pVBInfo->VBInfo & SetCRT2ToTV) { - temp -= 1; - if (!(modeflag & HalfDCLK)) { - if ((modeflag & Charx8Dot)) { - temp += 4; - if (pVBInfo->VGAHDE >= 800) - temp -= 6; - } - } - } else { - if (!(modeflag & HalfDCLK)) { - temp -= 4; - if (pVBInfo->LCDResInfo != Panel1280x960) { - if (pVBInfo->VGAHDE >= 800) { - temp -= 7; - if (pVBInfo->ModeType - == ModeEGA) { - if (pVBInfo->VGAVDE - == 1024) { - temp += 15; - if (pVBInfo->LCDResInfo - != Panel1280x1024) { - temp - += 7; - } - } - } - - if (pVBInfo->VGAHDE >= 1280) { - if (pVBInfo->LCDResInfo - != Panel1280x960) { - if (pVBInfo->LCDInfo - & LCDNonExpanding) { - temp - += 28; - } - } - } - } - } - } - } - } + xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ + yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+St_ModeFlag */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x07, temp); /* 0x07 Horizontal Retrace Start */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x08, 0); /* 0x08 Horizontal Retrace End */ + /* + if (pVBInfo->IF_DEF_FSTN) { + xres *= 2; + yres *= 2; + } else { + */ + if (modeflag & HalfDCLK) + xres *= 2; - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (pVBInfo->TVInfo & TVSimuMode) { - if ((ModeNo == 0x06) || (ModeNo == 0x10) || (ModeNo - == 0x11) || (ModeNo == 0x13) || (ModeNo - == 0x0F)) { - XGINew_SetReg1(pVBInfo->Part1Port, 0x07, 0x5b); - XGINew_SetReg1(pVBInfo->Part1Port, 0x08, 0x03); - } + if (modeflag & DoubleScanMode) + yres *= 2; + /* } */ + } - if ((ModeNo == 0x00) || (ModeNo == 0x01)) { - if (pVBInfo->TVInfo & SetNTSCTV) { - XGINew_SetReg1(pVBInfo->Part1Port, - 0x07, 0x2A); - XGINew_SetReg1(pVBInfo->Part1Port, - 0x08, 0x61); - } else { - XGINew_SetReg1(pVBInfo->Part1Port, - 0x07, 0x2A); - XGINew_SetReg1(pVBInfo->Part1Port, - 0x08, 0x41); - XGINew_SetReg1(pVBInfo->Part1Port, - 0x0C, 0xF0); + if (pVBInfo->VBInfo & SetCRT2ToLCD) { + if (pVBInfo->IF_DEF_LVDS == 0) { + if (pVBInfo->LCDResInfo == Panel1600x1200) { + if (!(pVBInfo->LCDInfo & LCDVESATiming)) { + if (yres == 1024) + yres = 1056; } } - if ((ModeNo == 0x02) || (ModeNo == 0x03) || (ModeNo - == 0x07)) { - if (pVBInfo->TVInfo & SetNTSCTV) { - XGINew_SetReg1(pVBInfo->Part1Port, - 0x07, 0x54); - XGINew_SetReg1(pVBInfo->Part1Port, - 0x08, 0x00); - } else { - XGINew_SetReg1(pVBInfo->Part1Port, - 0x07, 0x55); - XGINew_SetReg1(pVBInfo->Part1Port, - 0x08, 0x00); - XGINew_SetReg1(pVBInfo->Part1Port, - 0x0C, 0xF0); + if (pVBInfo->LCDResInfo == Panel1280x1024) { + if (yres == 400) + yres = 405; + else if (yres == 350) + yres = 360; + + if (pVBInfo->LCDInfo & LCDVESATiming) { + if (yres == 360) + yres = 375; } } - if ((ModeNo == 0x04) || (ModeNo == 0x05) || (ModeNo - == 0x0D) || (ModeNo == 0x50)) { - if (pVBInfo->TVInfo & SetNTSCTV) { - XGINew_SetReg1(pVBInfo->Part1Port, - 0x07, 0x30); - XGINew_SetReg1(pVBInfo->Part1Port, - 0x08, 0x03); - } else { - XGINew_SetReg1(pVBInfo->Part1Port, - 0x07, 0x2f); - XGINew_SetReg1(pVBInfo->Part1Port, - 0x08, 0x02); + if (pVBInfo->LCDResInfo == Panel1024x768) { + if (!(pVBInfo->LCDInfo & LCDVESATiming)) { + if (!(pVBInfo->LCDInfo + & LCDNonExpanding)) { + if (yres == 350) + yres = 357; + else if (yres == 400) + yres = 420; + else if (yres == 480) + yres = 525; + } } } } + + if (xres == 720) + xres = 640; } - XGINew_SetReg1(pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */ - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0xF0, 0x00); - XGINew_SetReg1(pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */ + pVBInfo->VGAHDE = xres; + pVBInfo->HDE = xres; + pVBInfo->VGAVDE = yres; + pVBInfo->VDE = yres; +} - tempbx = pVBInfo->VGAVT; - push1 = tempbx; - tempcx = 0x121; - tempbx = pVBInfo->VGAVDE; /* 0x0E Virtical Display End */ +static unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo) +{ - if (tempbx == 357) - tempbx = 350; - if (tempbx == 360) - tempbx = 350; - if (tempbx == 375) - tempbx = 350; - if (tempbx == 405) - tempbx = 400; - if (tempbx == 525) - tempbx = 480; + if ((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) && + (pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */ + return 1; - push2 = tempbx; + return 0; +} + +static void XGI_GetRAMDAC2DATA(unsigned short ModeNo, unsigned short ModeIdIndex, + unsigned short RefreshRateTableIndex, + struct vb_device_info *pVBInfo) +{ + unsigned short tempax, tempbx, temp1, temp2, modeflag = 0, tempcx, + StandTableIndex, CRT1Index; + + pVBInfo->RVBHCMAX = 1; + pVBInfo->RVBHCFACT = 1; + + if (ModeNo <= 0x13) { + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; + StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo); + tempax = pVBInfo->StandTable[StandTableIndex].CRTC[0]; + tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[6]; + temp1 = pVBInfo->StandTable[StandTableIndex].CRTC[7]; + } else { + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + CRT1Index + = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index &= IndexMask; + temp1 + = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0]; + temp2 + = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5]; + tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8); + tempbx + = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[8]; + tempcx + = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] + << 8; + tempcx &= 0x0100; + tempcx = tempcx << 2; + tempbx |= tempcx; + temp1 + = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9]; + } + + if (temp1 & 0x01) + tempbx |= 0x0100; + + if (temp1 & 0x20) + tempbx |= 0x0200; + tempax += 5; + + if (modeflag & Charx8Dot) + tempax *= 8; + else + tempax *= 9; + + pVBInfo->VGAHT = tempax; + pVBInfo->HT = tempax; + tempbx++; + pVBInfo->VGAVT = tempbx; + pVBInfo->VT = tempbx; +} + +static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, + unsigned short RefreshRateTableIndex, + struct vb_device_info *pVBInfo) +{ + unsigned short tempax = 0, tempbx, modeflag, resinfo; + + struct XGI_LCDDataStruct *LCDPtr = NULL; + struct XGI_TVDataStruct *TVPtr = NULL; + + if (ModeNo <= 0x13) { + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */ + resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; + } else { + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */ + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + } + + pVBInfo->NewFlickerMode = 0; + pVBInfo->RVBHRS = 50; + + if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { + XGI_GetRAMDAC2DATA(ModeNo, ModeIdIndex, RefreshRateTableIndex, + pVBInfo); + return; + } + + tempbx = 4; + + if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + LCDPtr = (struct XGI_LCDDataStruct *) XGI_GetLcdPtr(tempbx, + ModeNo, ModeIdIndex, RefreshRateTableIndex, + pVBInfo); + + pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX; + pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT; + pVBInfo->VGAHT = LCDPtr->VGAHT; + pVBInfo->VGAVT = LCDPtr->VGAVT; + pVBInfo->HT = LCDPtr->LCDHT; + pVBInfo->VT = LCDPtr->LCDVT; - if (pVBInfo->VBInfo & SetCRT2ToLCD) { if (pVBInfo->LCDResInfo == Panel1024x768) { + tempax = 1024; + tempbx = 768; + + if (!(pVBInfo->LCDInfo & LCDVESATiming)) { + if (pVBInfo->VGAVDE == 357) + tempbx = 527; + else if (pVBInfo->VGAVDE == 420) + tempbx = 620; + else if (pVBInfo->VGAVDE == 525) + tempbx = 775; + else if (pVBInfo->VGAVDE == 600) + tempbx = 775; + /* else if (pVBInfo->VGAVDE==350) tempbx=560; */ + /* else if (pVBInfo->VGAVDE==400) tempbx=640; */ + else + tempbx = 768; + } else + tempbx = 768; + } else if (pVBInfo->LCDResInfo == Panel1024x768x75) { + tempax = 1024; + tempbx = 768; + } else if (pVBInfo->LCDResInfo == Panel1280x1024) { + tempax = 1280; + if (pVBInfo->VGAVDE == 360) + tempbx = 768; + else if (pVBInfo->VGAVDE == 375) + tempbx = 800; + else if (pVBInfo->VGAVDE == 405) + tempbx = 864; + else + tempbx = 1024; + } else if (pVBInfo->LCDResInfo == Panel1280x1024x75) { + tempax = 1280; + tempbx = 1024; + } else if (pVBInfo->LCDResInfo == Panel1280x960) { + tempax = 1280; + if (pVBInfo->VGAVDE == 350) + tempbx = 700; + else if (pVBInfo->VGAVDE == 400) + tempbx = 800; + else if (pVBInfo->VGAVDE == 1024) + tempbx = 960; + else + tempbx = 960; + } else if (pVBInfo->LCDResInfo == Panel1400x1050) { + tempax = 1400; + tempbx = 1050; + + if (pVBInfo->VGAVDE == 1024) { + tempax = 1280; + tempbx = 1024; + } + } else if (pVBInfo->LCDResInfo == Panel1600x1200) { + tempax = 1600; + tempbx = 1200; /* alan 10/14/2003 */ if (!(pVBInfo->LCDInfo & LCDVESATiming)) { - if (tempbx == 350) - tempbx += 5; - if (tempbx == 480) - tempbx += 5; + if (pVBInfo->VGAVDE == 350) + tempbx = 875; + else if (pVBInfo->VGAVDE == 400) + tempbx = 1000; } } - } - tempbx--; - temp = tempbx & 0x00FF; - tempbx--; - temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp); /* 0x10 vertical Blank Start */ - tempbx = push2; - tempbx--; - temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0E, temp); - - if (tempbx & 0x0100) - tempcx |= 0x0002; - - tempax = 0x000B; - if (modeflag & DoubleScanMode) - tempax |= 0x08000; + if (pVBInfo->LCDInfo & LCDNonExpanding) { + tempax = pVBInfo->VGAHDE; + tempbx = pVBInfo->VGAVDE; + } - if (tempbx & 0x0200) - tempcx |= 0x0040; + pVBInfo->HDE = tempax; + pVBInfo->VDE = tempbx; + return; + } - temp = (tempax & 0xFF00) >> 8; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp); + if (pVBInfo->VBInfo & (SetCRT2ToTV)) { + tempbx = 4; + TVPtr = (struct XGI_TVDataStruct *) XGI_GetTVPtr(tempbx, + ModeNo, ModeIdIndex, RefreshRateTableIndex, + pVBInfo); - if (tempbx & 0x0400) - tempcx |= 0x0600; + pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX; + pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT; + pVBInfo->VGAHT = TVPtr->VGAHT; + pVBInfo->VGAVT = TVPtr->VGAVT; + pVBInfo->HDE = TVPtr->TVHDE; + pVBInfo->VDE = TVPtr->TVVDE; + pVBInfo->RVBHRS = TVPtr->RVBHRS; + pVBInfo->NewFlickerMode = TVPtr->FlickerMode; - XGINew_SetReg1(pVBInfo->Part1Port, 0x11, 0x00); /* 0x11 Vertival Blank End */ + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + if (resinfo == 0x08) + pVBInfo->NewFlickerMode = 0x40; + else if (resinfo == 0x09) + pVBInfo->NewFlickerMode = 0x40; + else if (resinfo == 0x12) + pVBInfo->NewFlickerMode = 0x40; - tempax = push1; - tempax -= tempbx; /* 0x0C Vertical Retrace Start */ - tempax = tempax >> 2; - push1 = tempax; /* push ax */ + if (pVBInfo->VGAVDE == 350) + pVBInfo->TVInfo |= TVSimuMode; - if (resinfo != 0x09) { - tempax = tempax << 1; - tempbx += tempax; - } + tempax = ExtHiTVHT; + tempbx = ExtHiTVVT; - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { - if (pVBInfo->VBType & VB_XGI301LV) { - if (pVBInfo->TVInfo & SetYPbPrMode1080i) { - tempbx -= 10; - } else { + if (pVBInfo->VBInfo & SetInSlaveMode) { if (pVBInfo->TVInfo & TVSimuMode) { - if (pVBInfo->TVInfo & SetPALTV) { - if (pVBInfo->VBType - & VB_XGI301LV) { - if (!(pVBInfo->TVInfo - & (SetYPbPrMode525p - | SetYPbPrMode750p - | SetYPbPrMode1080i))) - tempbx += 40; - } else { - tempbx += 40; - } + tempax = StHiTVHT; + tempbx = StHiTVVT; + + if (!(modeflag & Charx8Dot)) { + tempax = StHiTextTVHT; + tempbx = StHiTextTVVT; } } } + } else if (pVBInfo->VBInfo & SetCRT2ToYPbPr) { + if (pVBInfo->TVInfo & SetYPbPrMode750p) { + tempax = YPbPrTV750pHT; /* Ext750pTVHT */ + tempbx = YPbPrTV750pVT; /* Ext750pTVVT */ + } + + if (pVBInfo->TVInfo & SetYPbPrMode525p) { + tempax = YPbPrTV525pHT; /* Ext525pTVHT */ + tempbx = YPbPrTV525pVT; /* Ext525pTVVT */ + } else if (pVBInfo->TVInfo & SetYPbPrMode525i) { + tempax = YPbPrTV525iHT; /* Ext525iTVHT */ + tempbx = YPbPrTV525iVT; /* Ext525iTVVT */ + if (pVBInfo->TVInfo & NTSC1024x768) + tempax = NTSC1024x768HT; + } } else { - tempbx -= 10; - } - } else { - if (pVBInfo->TVInfo & TVSimuMode) { - if (pVBInfo->TVInfo & SetPALTV) { - if (pVBInfo->VBType & VB_XGI301LV) { - if (!(pVBInfo->TVInfo - & (SetYPbPrMode525p - | SetYPbPrMode750p - | SetYPbPrMode1080i))) - tempbx += 40; - } else { - tempbx += 40; - } + tempax = PALHT; + tempbx = PALVT; + if (!(pVBInfo->TVInfo & SetPALTV)) { + tempax = NTSCHT; + tempbx = NTSCVT; + if (pVBInfo->TVInfo & NTSC1024x768) + tempax = NTSC1024x768HT; } } - } - tempax = push1; - tempax = tempax >> 2; - tempax++; - tempax += tempbx; - push1 = tempax; /* push ax */ - if ((pVBInfo->TVInfo & SetPALTV)) { - if (tempbx <= 513) { - if (tempax >= 513) - tempbx = 513; - } + pVBInfo->HT = tempax; + pVBInfo->VT = tempbx; + return; } - - temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0C, temp); - tempbx--; - temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp); - - if (tempbx & 0x0100) - tempcx |= 0x0008; - - if (tempbx & 0x0200) - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20); - - tempbx++; - - if (tempbx & 0x0100) - tempcx |= 0x0004; - - if (tempbx & 0x0200) - tempcx |= 0x0080; - - if (tempbx & 0x0400) - tempcx |= 0x0C00; - - tempbx = push1; /* pop ax */ - temp = tempbx & 0x00FF; - temp &= 0x0F; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0D, temp); /* 0x0D vertical Retrace End */ - - if (tempbx & 0x0010) - tempcx |= 0x2000; - - temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */ - temp = (tempcx & 0x0FF00) >> 8; - XGINew_SetReg1(pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */ - tempax = modeflag; - temp = (tempax & 0xFF00) >> 8; - - temp = (temp >> 1) & 0x09; - - if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) - temp |= 0x01; - - XGINew_SetReg1(pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */ - - if (pVBInfo->LCDInfo & LCDRGB18Bit) - temp = 0x80; - else - temp = 0x00; - - XGINew_SetReg1(pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */ - - return; } -static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, - struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - unsigned short i, j, tempax, tempbx, tempcx, temp, push1, push2, - modeflag, resinfo, crt2crtc; - unsigned char *TimingPoint; + unsigned char di_0, di_1, tempal; - unsigned long longtemp, tempeax, tempebx, temp2, tempecx; + tempal = XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex, + pVBInfo); + XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo); + XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo); - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */ - resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - crt2crtc = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */ - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - crt2crtc - = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + if (pVBInfo->VBType & VB_XGI301) { /* shampoo 0129 */ + /* 301 */ + XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, 0x10); + XGINew_SetReg1(pVBInfo->Part4Port, 0x0B, di_1); + XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, di_0); + } else { /* 301b/302b/301lv/302lv */ + XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, di_0); + XGINew_SetReg1(pVBInfo->Part4Port, 0x0B, di_1); } - tempax = 0; - - if (!(pVBInfo->VBInfo & SetCRT2ToAVIDEO)) - tempax |= 0x0800; - - if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO)) - tempax |= 0x0400; - - if (pVBInfo->VBInfo & SetCRT2ToSCART) - tempax |= 0x0200; + XGINew_SetReg1(pVBInfo->Part4Port, 0x00, 0x12); - if (!(pVBInfo->TVInfo & SetPALTV)) - tempax |= 0x1000; + if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) + XGINew_SetRegOR(pVBInfo->Part4Port, 0x12, 0x28); + else + XGINew_SetRegOR(pVBInfo->Part4Port, 0x12, 0x08); +} - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) - tempax |= 0x0100; +static unsigned short XGI_GetColorDepth(unsigned short ModeNo, + unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) +{ + unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 }; + short index; + unsigned short modeflag; - if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)) - tempax &= 0xfe00; + if (ModeNo <= 0x13) + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; + else + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - tempax = (tempax & 0xff00) >> 8; + index = (modeflag & ModeInfoFlag) - ModeEGA; - XGINew_SetReg1(pVBInfo->Part2Port, 0x0, tempax); - TimingPoint = pVBInfo->NTSCTiming; + if (index < 0) + index = 0; - if (pVBInfo->TVInfo & SetPALTV) - TimingPoint = pVBInfo->PALTiming; + return ColorDepth[index]; +} - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { - TimingPoint = pVBInfo->HiTVExtTiming; +static unsigned short XGI_GetOffset(unsigned short ModeNo, unsigned short ModeIdIndex, + unsigned short RefreshRateTableIndex, + struct xgi_hw_device_info *HwDeviceExtension, + struct vb_device_info *pVBInfo) +{ + unsigned short temp, colordepth, modeinfo, index, infoflag, + ColorDepth[] = { 0x01, 0x02, 0x04 }; - if (pVBInfo->VBInfo & SetInSlaveMode) - TimingPoint = pVBInfo->HiTVSt2Timing; + modeinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo; + if (ModeNo <= 0x14) + infoflag = 0; + else + infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - if (pVBInfo->SetFlag & TVSimuMode) - TimingPoint = pVBInfo->HiTVSt1Timing; + index = (modeinfo >> 8) & 0xFF; - if (!(modeflag & Charx8Dot)) - TimingPoint = pVBInfo->HiTVTextTiming; - } + temp = pVBInfo->ScreenOffset[index]; - if (pVBInfo->VBInfo & SetCRT2ToYPbPr) { - if (pVBInfo->TVInfo & SetYPbPrMode525i) - TimingPoint = pVBInfo->YPbPr525iTiming; + if (infoflag & InterlaceMode) + temp = temp << 1; - if (pVBInfo->TVInfo & SetYPbPrMode525p) - TimingPoint = pVBInfo->YPbPr525pTiming; + colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo); - if (pVBInfo->TVInfo & SetYPbPrMode750p) - TimingPoint = pVBInfo->YPbPr750pTiming; + if ((ModeNo >= 0x7C) && (ModeNo <= 0x7E)) { + temp = ModeNo - 0x7C; + colordepth = ColorDepth[temp]; + temp = 0x6B; + if (infoflag & InterlaceMode) + temp = temp << 1; + return temp * colordepth; + } else { + return temp * colordepth; } +} - for (i = 0x01, j = 0; i <= 0x2D; i++, j++) - XGINew_SetReg1(pVBInfo->Part2Port, i, TimingPoint[j]); +static void XGI_SetCRT2Offset(unsigned short ModeNo, + unsigned short ModeIdIndex, + unsigned short RefreshRateTableIndex, + struct xgi_hw_device_info *HwDeviceExtension, + struct vb_device_info *pVBInfo) +{ + unsigned short offset; + unsigned char temp; - for (i = 0x39; i <= 0x45; i++, j++) - XGINew_SetReg1(pVBInfo->Part2Port, i, TimingPoint[j]); /* di->temp2[j] */ + if (pVBInfo->VBInfo & SetInSlaveMode) + return; - if (pVBInfo->VBInfo & SetCRT2ToTV) - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x3A, 0x1F, 0x00); + offset = XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex, + HwDeviceExtension, pVBInfo); + temp = (unsigned char) (offset & 0xFF); + XGINew_SetReg1(pVBInfo->Part1Port, 0x07, temp); + temp = (unsigned char) ((offset & 0xFF00) >> 8); + XGINew_SetReg1(pVBInfo->Part1Port, 0x09, temp); + temp = (unsigned char) (((offset >> 3) & 0xFF) + 1); + XGINew_SetReg1(pVBInfo->Part1Port, 0x03, temp); +} - temp = pVBInfo->NewFlickerMode; - temp &= 0x80; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0xFF, temp); +static void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo) +{ + XGINew_SetReg1(pVBInfo->Part1Port, 0x01, 0x3B); /* threshold high ,disable auto threshold */ + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04); /* threshold low default 04h */ +} - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) - tempax = 950; +static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, + struct xgi_hw_device_info *HwDeviceExtension, + unsigned short RefreshRateTableIndex, + struct vb_device_info *pVBInfo) +{ + unsigned short tempcx = 0, CRT1Index = 0, resinfo = 0; - if (pVBInfo->TVInfo & SetPALTV) - tempax = 520; - else - tempax = 440; + if (ModeNo > 0x13) { + CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index &= IndexMask; + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + } - if (pVBInfo->VDE <= tempax) { - tempax -= pVBInfo->VDE; - tempax = tempax >> 2; - tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8); - push1 = tempax; - temp = (tempax & 0xFF00) >> 8; - temp += (unsigned short) TimingPoint[0]; + XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex, + HwDeviceExtension, pVBInfo); + XGI_SetCRT2FIFO(pVBInfo); + /* XGI_SetCRT2Sync(ModeNo,RefreshRateTableIndex); */ - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { - if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO - | SetCRT2ToSVIDEO | SetCRT2ToSCART - | SetCRT2ToYPbPr)) { - tempcx = pVBInfo->VGAHDE; - if (tempcx >= 1024) { - temp = 0x17; /* NTSC */ - if (pVBInfo->TVInfo & SetPALTV) - temp = 0x19; /* PAL */ - } - } - } + for (tempcx = 4; tempcx < 7; tempcx++) + XGINew_SetReg1(pVBInfo->Part1Port, tempcx, 0x0); - XGINew_SetReg1(pVBInfo->Part2Port, 0x01, temp); - tempax = push1; - temp = (tempax & 0xFF00) >> 8; - temp += TimingPoint[1]; + XGINew_SetReg1(pVBInfo->Part1Port, 0x50, 0x00); + XGINew_SetReg1(pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */ +} - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { - if ((pVBInfo->VBInfo & (SetCRT2ToAVIDEO - | SetCRT2ToSVIDEO | SetCRT2ToSCART - | SetCRT2ToYPbPr))) { - tempcx = pVBInfo->VGAHDE; - if (tempcx >= 1024) { - temp = 0x1D; /* NTSC */ - if (pVBInfo->TVInfo & SetPALTV) - temp = 0x52; /* PAL */ - } - } - } - XGINew_SetReg1(pVBInfo->Part2Port, 0x02, temp); +static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, + struct xgi_hw_device_info *HwDeviceExtension, + unsigned short RefreshRateTableIndex, + struct vb_device_info *pVBInfo) +{ + unsigned short temp = 0, tempax = 0, tempbx = 0, tempcx = 0, + pushbx = 0, CRT1Index = 0, modeflag, resinfo = 0; + + if (ModeNo > 0x13) { + CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index &= IndexMask; + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; } - /* 301b */ - tempcx = pVBInfo->HT; + if (ModeNo <= 0x13) + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; + else + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - if (XGI_IsLCDDualLink(pVBInfo)) + /* bainy change table name */ + if (modeflag & HalfDCLK) { + temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */ + XGINew_SetReg1(pVBInfo->Part1Port, 0x08, temp); + temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4; + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x09, ~0x0F0, temp); + temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */ + XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp); + tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2; + pushbx = pVBInfo->VGAHDE / 2 + 16; tempcx = tempcx >> 1; + tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */ + tempcx += tempbx; - tempcx -= 2; - temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x1B, temp); + if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { + tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4]; + tempbx |= ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] + & 0xC0) << 2); + tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */ + tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5]; + tempcx &= 0x1F; + temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[15]; + temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */ + tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */ + } - temp = (tempcx & 0xFF00) >> 8; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1D, ~0x0F, temp); + tempbx += 4; + tempcx += 4; - tempcx = pVBInfo->HT >> 1; - push1 = tempcx; /* push cx */ - tempcx += 7; + if (tempcx > (pVBInfo->VGAHT / 2)) + tempcx = pVBInfo->VGAHT / 2; - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) - tempcx -= 4; + temp = tempbx & 0x00FF; - temp = tempcx & 0x00FF; - temp = temp << 4; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x22, 0x0F, temp); + XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp); + } else { + temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */ + XGINew_SetReg1(pVBInfo->Part1Port, 0x08, temp); + temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4; + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x09, ~0x0F0, temp); + temp = (pVBInfo->VGAHDE + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */ + XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp); + tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */ + pushbx = pVBInfo->VGAHDE + 16; + tempcx = tempcx >> 1; + tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */ + tempcx += tempbx; - tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8); - tempbx += tempcx; - push2 = tempbx; - temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x24, temp); - temp = (tempbx & 0xFF00) >> 8; - temp = temp << 4; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x25, 0x0F, temp); + if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { + tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[3]; + tempbx |= ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5] + & 0xC0) << 2); + tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */ + tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4]; + tempcx &= 0x1F; + temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[6]; + temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */ + tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */ + tempbx += 16; + tempcx += 16; + } - tempbx = push2; - tempbx = tempbx + 8; - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { - tempbx = tempbx - 4; - tempcx = tempbx; - } + if (tempcx > pVBInfo->VGAHT) + tempcx = pVBInfo->VGAHT; - temp = (tempbx & 0x00FF) << 4; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x29, 0x0F, temp); + temp = tempbx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp); + } - j += 2; - tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8)); + tempax = (tempax & 0x00FF) | (tempbx & 0xFF00); + tempbx = pushbx; + tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4); + tempax |= (tempbx & 0xFF00); + temp = (tempax & 0xFF00) >> 8; + XGINew_SetReg1(pVBInfo->Part1Port, 0x0C, temp); temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x27, temp); - temp = ((tempcx & 0xFF00) >> 8) << 4; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x28, 0x0F, temp); - - tempcx += 8; - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) - tempcx -= 4; - - temp = tempcx & 0xFF; - temp = temp << 4; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2A, 0x0F, temp); - - tempcx = push1; /* pop cx */ - j += 2; - temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8); - tempcx -= temp; + XGINew_SetReg1(pVBInfo->Part1Port, 0x0D, temp); + tempcx = (pVBInfo->VGAVT - 1); temp = tempcx & 0x00FF; - temp = temp << 4; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2D, 0x0F, temp); - - tempcx -= 11; - if (!(pVBInfo->VBInfo & SetCRT2ToTV)) { - tempax = XGI_GetVGAHT2(pVBInfo); - tempcx = tempax - 1; + if (pVBInfo->IF_DEF_CH7005 == 1) { + if (pVBInfo->VBInfo & 0x0C) + temp--; } - temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x2E, temp); - - tempbx = pVBInfo->VDE; - if (pVBInfo->VGAVDE == 360) - tempbx = 746; - if (pVBInfo->VGAVDE == 375) - tempbx = 746; - if (pVBInfo->VGAVDE == 405) - tempbx = 853; + XGINew_SetReg1(pVBInfo->Part1Port, 0x0E, temp); + tempbx = pVBInfo->VGAVDE - 1; + temp = tempbx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part1Port, 0x0F, temp); + temp = ((tempbx & 0xFF00) << 3) >> 8; + temp |= ((tempcx & 0xFF00) >> 8); + XGINew_SetReg1(pVBInfo->Part1Port, 0x12, temp); - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { - if (!(pVBInfo->TVInfo & (SetYPbPrMode525p - | SetYPbPrMode750p))) - tempbx = tempbx >> 1; - } else - tempbx = tempbx >> 1; - } + tempax = pVBInfo->VGAVDE; + tempbx = pVBInfo->VGAVDE; + tempcx = pVBInfo->VGAVT; + tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */ + tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */ - tempbx -= 2; - temp = tempbx & 0x00FF; + if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { + tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[10]; + temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9]; - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { - if (pVBInfo->VBType & VB_XGI301LV) { - if (pVBInfo->TVInfo & SetYPbPrMode1080i) { - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (ModeNo == 0x2f) - temp += 1; - } - } - } else { - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (ModeNo == 0x2f) - temp += 1; - } - } - } + if (temp & 0x04) + tempbx |= 0x0100; - XGINew_SetReg1(pVBInfo->Part2Port, 0x2F, temp); + if (temp & 0x080) + tempbx |= 0x0200; - temp = (tempcx & 0xFF00) >> 8; - temp |= ((tempbx & 0xFF00) >> 8) << 6; + temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14]; - if (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) { - if (pVBInfo->VBType & VB_XGI301LV) { - if (pVBInfo->TVInfo & SetYPbPrMode1080i) { - temp |= 0x10; + if (temp & 0x08) + tempbx |= 0x0400; - if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO)) - temp |= 0x20; - } - } else { - temp |= 0x10; - if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO)) - temp |= 0x20; - } + temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[11]; + tempcx = (tempcx & 0xFF00) | (temp & 0x00FF); } - XGINew_SetReg1(pVBInfo->Part2Port, 0x30, temp); + temp = tempbx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp); + temp = ((tempbx & 0xFF00) >> 8) << 4; + temp = ((tempcx & 0x000F) | (temp)); + XGINew_SetReg1(pVBInfo->Part1Port, 0x11, temp); + tempax = 0; - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { /* TV gatingno */ - tempbx = pVBInfo->VDE; - tempcx = tempbx - 2; + if (modeflag & DoubleScanMode) + tempax |= 0x80; - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (!(pVBInfo->TVInfo & (SetYPbPrMode525p - | SetYPbPrMode750p))) - tempbx = tempbx >> 1; - } + if (modeflag & HalfDCLK) + tempax |= 0x40; - if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) { - temp = 0; - if (tempcx & 0x0400) - temp |= 0x20; + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax); +} - if (tempbx & 0x0400) - temp |= 0x40; +static unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo) +{ + unsigned long tempax, tempbx; - XGINew_SetReg1(pVBInfo->Part4Port, 0x10, temp); - } + tempbx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) * pVBInfo->RVBHCMAX) + & 0xFFFF; + tempax = (pVBInfo->VT - pVBInfo->VDE) * pVBInfo->RVBHCFACT; + tempax = (tempax * pVBInfo->HT) / tempbx; - temp = (((tempbx - 3) & 0x0300) >> 8) << 5; - XGINew_SetReg1(pVBInfo->Part2Port, 0x46, temp); - temp = (tempbx - 3) & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x47, temp); - } + return (unsigned short) tempax; +} - tempbx = tempbx & 0x00FF; +static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, + struct xgi_hw_device_info *HwDeviceExtension, + unsigned short RefreshRateTableIndex, + struct vb_device_info *pVBInfo) +{ + unsigned short push1, push2, tempax, tempbx = 0, tempcx, temp, resinfo, + modeflag, CRT1Index; - if (!(modeflag & HalfDCLK)) { - tempcx = pVBInfo->VGAHDE; - if (tempcx >= pVBInfo->HDE) { - tempbx |= 0x2000; - tempax &= 0x00FF; - } + if (ModeNo <= 0x13) { + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */ + resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; + } else { + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */ + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index &= IndexMask; } - tempcx = 0x0101; + if (!(pVBInfo->VBInfo & SetInSlaveMode)) + return; - if (pVBInfo->VBInfo & SetCRT2ToTV) { /*301b*/ - if (pVBInfo->VGAHDE >= 1024) { - tempcx = 0x1920; - if (pVBInfo->VGAHDE >= 1280) { - tempcx = 0x1420; - tempbx = tempbx & 0xDFFF; - } - } - } + temp = 0xFF; /* set MAX HT */ + XGINew_SetReg1(pVBInfo->Part1Port, 0x03, temp); + /* if (modeflag & Charx8Dot) */ + /* tempcx = 0x08; */ + /* else */ + tempcx = 0x08; - if (!(tempbx & 0x2000)) { - if (modeflag & HalfDCLK) - tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1); + if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) + modeflag |= Charx8Dot; - push1 = tempbx; - tempeax = pVBInfo->VGAHDE; - tempebx = (tempcx & 0xFF00) >> 8; - longtemp = tempeax * tempebx; - tempecx = tempcx & 0x00FF; - longtemp = longtemp / tempecx; + tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */ - /* 301b */ - tempecx = 8 * 1024; + if (modeflag & HalfDCLK) + tempax = tempax >> 1; - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { - tempecx = tempecx * 8; - } + tempax = (tempax / tempcx) - 1; + tempbx |= ((tempax & 0x00FF) << 8); + temp = tempax & 0x00FF; + XGINew_SetReg1(pVBInfo->Part1Port, 0x04, temp); - longtemp = longtemp * tempecx; - tempecx = pVBInfo->HDE; - temp2 = longtemp % tempecx; - tempeax = longtemp / tempecx; - if (temp2 != 0) - tempeax += 1; + temp = (tempbx & 0xFF00) >> 8; - tempax = (unsigned short) tempeax; + if (pVBInfo->VBInfo & SetCRT2ToTV) { + if (!(pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV + | VB_XGI302LV | VB_XGI301C))) + temp += 2; - /* 301b */ - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { - tempcx = ((tempax & 0xFF00) >> 5) >> 8; + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + if (pVBInfo->VBType & VB_XGI301LV) { + if (pVBInfo->VBExtInfo == VB_YPbPr1080i) { + if (resinfo == 7) + temp -= 2; + } + } else if (resinfo == 7) { + temp -= 2; + } } - /* end 301b */ - - tempbx = push1; - tempbx = (unsigned short) (((tempeax & 0x0000FF00) & 0x1F00) - | (tempbx & 0x00FF)); - tempax = (unsigned short) (((tempeax & 0x000000FF) << 8) - | (tempax & 0x00FF)); - temp = (tempax & 0xFF00) >> 8; - } else { - temp = (tempax & 0x00FF) >> 8; } - XGINew_SetReg1(pVBInfo->Part2Port, 0x44, temp); - temp = (tempbx & 0xFF00) >> 8; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x45, ~0x03F, temp); - temp = tempcx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part1Port, 0x05, temp); /* 0x05 Horizontal Display Start */ + XGINew_SetReg1(pVBInfo->Part1Port, 0x06, 0x03); /* 0x06 Horizontal Blank end */ - if (tempbx & 0x2000) - temp = 0; + if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */ + if (pVBInfo->VBInfo & SetCRT2ToTV) + tempax = pVBInfo->VGAHT; + else + tempax = XGI_GetVGAHT2(pVBInfo); + } - if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) - temp |= 0x18; + if (tempax >= pVBInfo->VGAHT) + tempax = pVBInfo->VGAHT; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x46, ~0x1F, temp); - if (pVBInfo->TVInfo & SetPALTV) { - tempbx = 0x0382; - tempcx = 0x007e; + if (modeflag & HalfDCLK) + tempax = tempax >> 1; + + tempax = (tempax / tempcx) - 5; + tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */ + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + temp = (tempbx & 0x00FF) - 1; + if (!(modeflag & HalfDCLK)) { + temp -= 6; + if (pVBInfo->TVInfo & TVSimuMode) { + temp -= 4; + if (ModeNo > 0x13) + temp -= 10; + } + } } else { - tempbx = 0x0369; - tempcx = 0x0061; - } + /* tempcx = tempbx & 0x00FF ; */ + tempbx = (tempbx & 0xFF00) >> 8; + tempcx = (tempcx + tempbx) >> 1; + temp = (tempcx & 0x00FF) + 2; - temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x4b, temp); - temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x4c, temp); + if (pVBInfo->VBInfo & SetCRT2ToTV) { + temp -= 1; + if (!(modeflag & HalfDCLK)) { + if ((modeflag & Charx8Dot)) { + temp += 4; + if (pVBInfo->VGAHDE >= 800) + temp -= 6; + } + } + } else { + if (!(modeflag & HalfDCLK)) { + temp -= 4; + if (pVBInfo->LCDResInfo != Panel1280x960) { + if (pVBInfo->VGAHDE >= 800) { + temp -= 7; + if (pVBInfo->ModeType + == ModeEGA) { + if (pVBInfo->VGAVDE + == 1024) { + temp += 15; + if (pVBInfo->LCDResInfo + != Panel1280x1024) { + temp + += 7; + } + } + } - temp = ((tempcx & 0xFF00) >> 8) & 0x03; - temp = temp << 2; - temp |= ((tempbx & 0xFF00) >> 8) & 0x03; + if (pVBInfo->VGAHDE >= 1280) { + if (pVBInfo->LCDResInfo + != Panel1280x960) { + if (pVBInfo->LCDInfo + & LCDNonExpanding) { + temp + += 28; + } + } + } + } + } + } + } + } - if (pVBInfo->VBInfo & SetCRT2ToYPbPr) { - temp |= 0x10; + XGINew_SetReg1(pVBInfo->Part1Port, 0x07, temp); /* 0x07 Horizontal Retrace Start */ + XGINew_SetReg1(pVBInfo->Part1Port, 0x08, 0); /* 0x08 Horizontal Retrace End */ - if (pVBInfo->TVInfo & SetYPbPrMode525p) - temp |= 0x20; + if (pVBInfo->VBInfo & SetCRT2ToTV) { + if (pVBInfo->TVInfo & TVSimuMode) { + if ((ModeNo == 0x06) || (ModeNo == 0x10) || (ModeNo + == 0x11) || (ModeNo == 0x13) || (ModeNo + == 0x0F)) { + XGINew_SetReg1(pVBInfo->Part1Port, 0x07, 0x5b); + XGINew_SetReg1(pVBInfo->Part1Port, 0x08, 0x03); + } - if (pVBInfo->TVInfo & SetYPbPrMode750p) - temp |= 0x60; - } + if ((ModeNo == 0x00) || (ModeNo == 0x01)) { + if (pVBInfo->TVInfo & SetNTSCTV) { + XGINew_SetReg1(pVBInfo->Part1Port, + 0x07, 0x2A); + XGINew_SetReg1(pVBInfo->Part1Port, + 0x08, 0x61); + } else { + XGINew_SetReg1(pVBInfo->Part1Port, + 0x07, 0x2A); + XGINew_SetReg1(pVBInfo->Part1Port, + 0x08, 0x41); + XGINew_SetReg1(pVBInfo->Part1Port, + 0x0C, 0xF0); + } + } - XGINew_SetReg1(pVBInfo->Part2Port, 0x4d, temp); - temp = XGINew_GetReg1(pVBInfo->Part2Port, 0x43); /* 301b change */ - XGINew_SetReg1(pVBInfo->Part2Port, 0x43, (unsigned short) (temp - 3)); + if ((ModeNo == 0x02) || (ModeNo == 0x03) || (ModeNo + == 0x07)) { + if (pVBInfo->TVInfo & SetNTSCTV) { + XGINew_SetReg1(pVBInfo->Part1Port, + 0x07, 0x54); + XGINew_SetReg1(pVBInfo->Part1Port, + 0x08, 0x00); + } else { + XGINew_SetReg1(pVBInfo->Part1Port, + 0x07, 0x55); + XGINew_SetReg1(pVBInfo->Part1Port, + 0x08, 0x00); + XGINew_SetReg1(pVBInfo->Part1Port, + 0x0C, 0xF0); + } + } - if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) { - if (pVBInfo->TVInfo & NTSC1024x768) { - TimingPoint = XGI_NTSC1024AdjTime; - for (i = 0x1c, j = 0; i <= 0x30; i++, j++) { - XGINew_SetReg1(pVBInfo->Part2Port, i, - TimingPoint[j]); + if ((ModeNo == 0x04) || (ModeNo == 0x05) || (ModeNo + == 0x0D) || (ModeNo == 0x50)) { + if (pVBInfo->TVInfo & SetNTSCTV) { + XGINew_SetReg1(pVBInfo->Part1Port, + 0x07, 0x30); + XGINew_SetReg1(pVBInfo->Part1Port, + 0x08, 0x03); + } else { + XGINew_SetReg1(pVBInfo->Part1Port, + 0x07, 0x2f); + XGINew_SetReg1(pVBInfo->Part1Port, + 0x08, 0x02); + } } - XGINew_SetReg1(pVBInfo->Part2Port, 0x43, 0x72); } } - /* [ycchen] 01/14/03 Modify for 301C PALM Support */ - if (pVBInfo->VBType & VB_XGI301C) { - if (pVBInfo->TVInfo & SetPALMTV) - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x08, - 0x08); /* PALM Mode */ - } + XGINew_SetReg1(pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */ + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0xF0, 0x00); + XGINew_SetReg1(pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */ - if (pVBInfo->TVInfo & SetPALMTV) { - tempax = (unsigned char) XGINew_GetReg1(pVBInfo->Part2Port, - 0x01); - tempax--; - XGINew_SetRegAND(pVBInfo->Part2Port, 0x01, tempax); + tempbx = pVBInfo->VGAVT; + push1 = tempbx; + tempcx = 0x121; + tempbx = pVBInfo->VGAVDE; /* 0x0E Virtical Display End */ - /* if ( !( pVBInfo->VBType & VB_XGI301C ) ) */ - XGINew_SetRegAND(pVBInfo->Part2Port, 0x00, 0xEF); - } + if (tempbx == 357) + tempbx = 350; + if (tempbx == 360) + tempbx = 350; + if (tempbx == 375) + tempbx = 350; + if (tempbx == 405) + tempbx = 400; + if (tempbx == 525) + tempbx = 480; - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { - if (!(pVBInfo->VBInfo & SetInSlaveMode)) - XGINew_SetReg1(pVBInfo->Part2Port, 0x0B, 0x00); - } + push2 = tempbx; - if (pVBInfo->VBInfo & SetCRT2ToTV) - return; -} + if (pVBInfo->VBInfo & SetCRT2ToLCD) { + if (pVBInfo->LCDResInfo == Panel1024x768) { + if (!(pVBInfo->LCDInfo & LCDVESATiming)) { + if (tempbx == 350) + tempbx += 5; + if (tempbx == 480) + tempbx += 5; + } + } + } + tempbx--; + temp = tempbx & 0x00FF; + tempbx--; + temp = tempbx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp); /* 0x10 vertical Blank Start */ + tempbx = push2; + tempbx--; + temp = tempbx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part1Port, 0x0E, temp); -static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, - struct xgi_hw_device_info *HwDeviceExtension, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short push1, push2, pushbx, tempax, tempbx, tempcx, temp, - tempah, tempbh, tempch, resinfo, modeflag, CRT1Index; + if (tempbx & 0x0100) + tempcx |= 0x0002; - struct XGI_LCDDesStruct *LCDBDesPtr = NULL; + tempax = 0x000B; - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */ - resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */ - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - CRT1Index - = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - CRT1Index &= IndexMask; - } + if (modeflag & DoubleScanMode) + tempax |= 0x08000; - if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) - return; + if (tempbx & 0x0200) + tempcx |= 0x0040; - tempbx = pVBInfo->HDE; /* RHACTE=HDE-1 */ + temp = (tempax & 0xFF00) >> 8; + XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp); - if (XGI_IsLCDDualLink(pVBInfo)) - tempbx = tempbx >> 1; + if (tempbx & 0x0400) + tempcx |= 0x0600; - tempbx -= 1; - temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x2C, temp); - temp = (tempbx & 0xFF00) >> 8; - temp = temp << 4; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2B, 0x0F, temp); - temp = 0x01; + XGINew_SetReg1(pVBInfo->Part1Port, 0x11, 0x00); /* 0x11 Vertival Blank End */ - if (pVBInfo->LCDResInfo == Panel1280x1024) { - if (pVBInfo->ModeType == ModeEGA) { - if (pVBInfo->VGAHDE >= 1024) { - temp = 0x02; - if (pVBInfo->LCDInfo & LCDVESATiming) - temp = 0x01; + tempax = push1; + tempax -= tempbx; /* 0x0C Vertical Retrace Start */ + tempax = tempax >> 2; + push1 = tempax; /* push ax */ + + if (resinfo != 0x09) { + tempax = tempax << 1; + tempbx += tempax; + } + + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + if (pVBInfo->VBType & VB_XGI301LV) { + if (pVBInfo->TVInfo & SetYPbPrMode1080i) { + tempbx -= 10; + } else { + if (pVBInfo->TVInfo & TVSimuMode) { + if (pVBInfo->TVInfo & SetPALTV) { + if (pVBInfo->VBType + & VB_XGI301LV) { + if (!(pVBInfo->TVInfo + & (SetYPbPrMode525p + | SetYPbPrMode750p + | SetYPbPrMode1080i))) + tempbx += 40; + } else { + tempbx += 40; + } + } + } + } + } else { + tempbx -= 10; + } + } else { + if (pVBInfo->TVInfo & TVSimuMode) { + if (pVBInfo->TVInfo & SetPALTV) { + if (pVBInfo->VBType & VB_XGI301LV) { + if (!(pVBInfo->TVInfo + & (SetYPbPrMode525p + | SetYPbPrMode750p + | SetYPbPrMode1080i))) + tempbx += 40; + } else { + tempbx += 40; + } } } } + tempax = push1; + tempax = tempax >> 2; + tempax++; + tempax += tempbx; + push1 = tempax; /* push ax */ - XGINew_SetReg1(pVBInfo->Part2Port, 0x0B, temp); - tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */ - push1 = tempbx; + if ((pVBInfo->TVInfo & SetPALTV)) { + if (tempbx <= 513) { + if (tempax >= 513) + tempbx = 513; + } + } + + temp = tempbx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part1Port, 0x0C, temp); tempbx--; temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x03, temp); - temp = ((tempbx & 0xFF00) >> 8) & 0x07; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0C, ~0x07, temp); + XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp); - tempcx = pVBInfo->VT - 1; - push2 = tempcx + 1; - temp = tempcx & 0x00FF; /* RVTVT=VT-1 */ - XGINew_SetReg1(pVBInfo->Part2Port, 0x19, temp); - temp = (tempcx & 0xFF00) >> 8; - temp = temp << 5; - XGINew_SetReg1(pVBInfo->Part2Port, 0x1A, temp); - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x09, 0xF0, 0x00); - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0xF0, 0x00); - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x17, 0xFB, 0x00); - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x18, 0xDF, 0x00); + if (tempbx & 0x0100) + tempcx |= 0x0008; - /* Customized LCDB Des no add */ - tempbx = 5; - LCDBDesPtr = (struct XGI_LCDDesStruct *) XGI_GetLcdPtr(tempbx, ModeNo, - ModeIdIndex, RefreshRateTableIndex, pVBInfo); - tempah = pVBInfo->LCDResInfo; - tempah &= PanelResInfo; + if (tempbx & 0x0200) + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20); - if ((tempah == Panel1024x768) || (tempah == Panel1024x768x75)) { - tempbx = 1024; - tempcx = 768; - } else if ((tempah == Panel1280x1024) || (tempah == Panel1280x1024x75)) { - tempbx = 1280; - tempcx = 1024; - } else if (tempah == Panel1400x1050) { - tempbx = 1400; - tempcx = 1050; - } else { - tempbx = 1600; - tempcx = 1200; - } + tempbx++; - if (pVBInfo->LCDInfo & EnableScalingLCD) { - tempbx = pVBInfo->HDE; - tempcx = pVBInfo->VDE; - } + if (tempbx & 0x0100) + tempcx |= 0x0004; - pushbx = tempbx; - tempax = pVBInfo->VT; - pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES; - pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS; - pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES; - pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS; - tempbx = pVBInfo->LCDVDES; - tempcx += tempbx; + if (tempbx & 0x0200) + tempcx |= 0x0080; - if (tempcx >= tempax) - tempcx -= tempax; /* lcdvdes */ + if (tempbx & 0x0400) + tempcx |= 0x0C00; - temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */ - XGINew_SetReg1(pVBInfo->Part2Port, 0x05, temp); - temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x06, temp); - tempch = ((tempcx & 0xFF00) >> 8) & 0x07; - tempbh = ((tempbx & 0xFF00) >> 8) & 0x07; - tempah = tempch; - tempah = tempah << 3; - tempah |= tempbh; - XGINew_SetReg1(pVBInfo->Part2Port, 0x02, tempah); + tempbx = push1; /* pop ax */ + temp = tempbx & 0x00FF; + temp &= 0x0F; + XGINew_SetReg1(pVBInfo->Part1Port, 0x0D, temp); /* 0x0D vertical Retrace End */ - /* getlcdsync() */ - XGI_GetLCDSync(&tempax, &tempbx, pVBInfo); - tempcx = tempbx; - tempax = pVBInfo->VT; - tempbx = pVBInfo->LCDVRS; + if (tempbx & 0x0010) + tempcx |= 0x2000; - /* if (SetLCD_Info & EnableScalingLCD) */ - tempcx += tempbx; - if (tempcx >= tempax) - tempcx -= tempax; + temp = tempcx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */ + temp = (tempcx & 0x0FF00) >> 8; + XGINew_SetReg1(pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */ + tempax = modeflag; + temp = (tempax & 0xFF00) >> 8; - temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */ - XGINew_SetReg1(pVBInfo->Part2Port, 0x04, temp); - temp = (tempbx & 0xFF00) >> 8; - temp = temp << 4; - temp |= (tempcx & 0x000F); - XGINew_SetReg1(pVBInfo->Part2Port, 0x01, temp); - tempcx = pushbx; - tempax = pVBInfo->HT; - tempbx = pVBInfo->LCDHDES; - tempbx &= 0x0FFF; + temp = (temp >> 1) & 0x09; - if (XGI_IsLCDDualLink(pVBInfo)) { - tempax = tempax >> 1; - tempbx = tempbx >> 1; - tempcx = tempcx >> 1; - } + if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) + temp |= 0x01; - if (pVBInfo->VBType & VB_XGI302LV) - tempbx += 1; + XGINew_SetReg1(pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */ + XGINew_SetReg1(pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */ + XGINew_SetReg1(pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */ - if (pVBInfo->VBType & VB_XGI301C) /* tap4 */ - tempbx += 1; + if (pVBInfo->LCDInfo & LCDRGB18Bit) + temp = 0x80; + else + temp = 0x00; - tempcx += tempbx; + XGINew_SetReg1(pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */ - if (tempcx >= tempax) - tempcx -= tempax; + return; +} - temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */ - temp = ((tempbx & 0xFF00) >> 8) << 4; - XGINew_SetReg1(pVBInfo->Part2Port, 0x20, temp); - temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */ - temp = (tempcx & 0xFF00) >> 8; - XGINew_SetReg1(pVBInfo->Part2Port, 0x25, temp); +static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, + unsigned short RefreshRateTableIndex, + struct xgi_hw_device_info *HwDeviceExtension, + struct vb_device_info *pVBInfo) +{ + unsigned short i, j, tempax, tempbx, tempcx, temp, push1, push2, + modeflag, resinfo, crt2crtc; + unsigned char *TimingPoint; - /* getlcdsync() */ - XGI_GetLCDSync(&tempax, &tempbx, pVBInfo); - tempcx = tempax; - tempax = pVBInfo->HT; - tempbx = pVBInfo->LCDHRS; - /* if ( SetLCD_Info & EnableScalingLCD) */ - if (XGI_IsLCDDualLink(pVBInfo)) { - tempax = tempax >> 1; - tempbx = tempbx >> 1; - tempcx = tempcx >> 1; + unsigned long longtemp, tempeax, tempebx, temp2, tempecx; + + if (ModeNo <= 0x13) { + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */ + resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; + crt2crtc = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; + } else { + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */ + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + crt2crtc + = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; } - if (pVBInfo->VBType & VB_XGI302LV) - tempbx += 1; + tempax = 0; + + if (!(pVBInfo->VBInfo & SetCRT2ToAVIDEO)) + tempax |= 0x0800; - tempcx += tempbx; + if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO)) + tempax |= 0x0400; - if (tempcx >= tempax) - tempcx -= tempax; + if (pVBInfo->VBInfo & SetCRT2ToSCART) + tempax |= 0x0200; - temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */ - XGINew_SetReg1(pVBInfo->Part2Port, 0x1C, temp); + if (!(pVBInfo->TVInfo & SetPALTV)) + tempax |= 0x1000; - temp = (tempbx & 0xFF00) >> 8; - temp = temp << 4; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1D, ~0x0F0, temp); - temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */ - XGINew_SetReg1(pVBInfo->Part2Port, 0x21, temp); + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) + tempax |= 0x0100; - if (!(pVBInfo->LCDInfo & LCDVESATiming)) { - if (pVBInfo->VGAVDE == 525) { - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B - | VB_XGI301LV | VB_XGI302LV - | VB_XGI301C)) { - temp = 0xC6; - } else - temp = 0xC4; + if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)) + tempax &= 0xfe00; - XGINew_SetReg1(pVBInfo->Part2Port, 0x2f, temp); - XGINew_SetReg1(pVBInfo->Part2Port, 0x30, 0xB3); - } + tempax = (tempax & 0xff00) >> 8; - if (pVBInfo->VGAVDE == 420) { - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B - | VB_XGI301LV | VB_XGI302LV - | VB_XGI301C)) { - temp = 0x4F; - } else - temp = 0x4E; - XGINew_SetReg1(pVBInfo->Part2Port, 0x2f, temp); - } - } -} + XGINew_SetReg1(pVBInfo->Part2Port, 0x0, tempax); + TimingPoint = pVBInfo->NTSCTiming; -/* --------------------------------------------------------------------- */ -/* Function : XGI_GetTap4Ptr */ -/* Input : */ -/* Output : di -> Tap4 Reg. Setting Pointer */ -/* Description : */ -/* --------------------------------------------------------------------- */ -static struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx, - struct vb_device_info *pVBInfo) -{ - unsigned short tempax, tempbx, i; + if (pVBInfo->TVInfo & SetPALTV) + TimingPoint = pVBInfo->PALTiming; - struct XGI301C_Tap4TimingStruct *Tap4TimingPtr; + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + TimingPoint = pVBInfo->HiTVExtTiming; - if (tempcx == 0) { - tempax = pVBInfo->VGAHDE; - tempbx = pVBInfo->HDE; - } else { - tempax = pVBInfo->VGAVDE; - tempbx = pVBInfo->VDE; - } + if (pVBInfo->VBInfo & SetInSlaveMode) + TimingPoint = pVBInfo->HiTVSt2Timing; - if (tempax < tempbx) - return &EnlargeTap4Timing[0]; - else if (tempax == tempbx) - return &NoScaleTap4Timing[0]; /* 1:1 */ - else - Tap4TimingPtr = NTSCTap4Timing; /* NTSC */ + if (pVBInfo->SetFlag & TVSimuMode) + TimingPoint = pVBInfo->HiTVSt1Timing; - if (pVBInfo->TVInfo & SetPALTV) - Tap4TimingPtr = PALTap4Timing; + if (!(modeflag & Charx8Dot)) + TimingPoint = pVBInfo->HiTVTextTiming; + } if (pVBInfo->VBInfo & SetCRT2ToYPbPr) { if (pVBInfo->TVInfo & SetYPbPrMode525i) - Tap4TimingPtr = YPbPr525iTap4Timing; + TimingPoint = pVBInfo->YPbPr525iTiming; + if (pVBInfo->TVInfo & SetYPbPrMode525p) - Tap4TimingPtr = YPbPr525pTap4Timing; + TimingPoint = pVBInfo->YPbPr525pTiming; + if (pVBInfo->TVInfo & SetYPbPrMode750p) - Tap4TimingPtr = YPbPr750pTap4Timing; + TimingPoint = pVBInfo->YPbPr750pTiming; } + for (i = 0x01, j = 0; i <= 0x2D; i++, j++) + XGINew_SetReg1(pVBInfo->Part2Port, i, TimingPoint[j]); + + for (i = 0x39; i <= 0x45; i++, j++) + XGINew_SetReg1(pVBInfo->Part2Port, i, TimingPoint[j]); /* di->temp2[j] */ + + if (pVBInfo->VBInfo & SetCRT2ToTV) + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x3A, 0x1F, 0x00); + + temp = pVBInfo->NewFlickerMode; + temp &= 0x80; + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0xFF, temp); + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) - Tap4TimingPtr = HiTVTap4Timing; + tempax = 950; - i = 0; - while (Tap4TimingPtr[i].DE != 0xFFFF) { - if (Tap4TimingPtr[i].DE == tempax) - break; - i++; + if (pVBInfo->TVInfo & SetPALTV) + tempax = 520; + else + tempax = 440; + + if (pVBInfo->VDE <= tempax) { + tempax -= pVBInfo->VDE; + tempax = tempax >> 2; + tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8); + push1 = tempax; + temp = (tempax & 0xFF00) >> 8; + temp += (unsigned short) TimingPoint[0]; + + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV + | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO + | SetCRT2ToSVIDEO | SetCRT2ToSCART + | SetCRT2ToYPbPr)) { + tempcx = pVBInfo->VGAHDE; + if (tempcx >= 1024) { + temp = 0x17; /* NTSC */ + if (pVBInfo->TVInfo & SetPALTV) + temp = 0x19; /* PAL */ + } + } + } + + XGINew_SetReg1(pVBInfo->Part2Port, 0x01, temp); + tempax = push1; + temp = (tempax & 0xFF00) >> 8; + temp += TimingPoint[1]; + + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV + | VB_XGI302LV | VB_XGI301C)) { + if ((pVBInfo->VBInfo & (SetCRT2ToAVIDEO + | SetCRT2ToSVIDEO | SetCRT2ToSCART + | SetCRT2ToYPbPr))) { + tempcx = pVBInfo->VGAHDE; + if (tempcx >= 1024) { + temp = 0x1D; /* NTSC */ + if (pVBInfo->TVInfo & SetPALTV) + temp = 0x52; /* PAL */ + } + } + } + XGINew_SetReg1(pVBInfo->Part2Port, 0x02, temp); } - return &Tap4TimingPtr[i]; -} -static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo) -{ - unsigned short i, j; + /* 301b */ + tempcx = pVBInfo->HT; - struct XGI301C_Tap4TimingStruct *Tap4TimingPtr; + if (XGI_IsLCDDualLink(pVBInfo)) + tempcx = tempcx >> 1; - if (!(pVBInfo->VBType & VB_XGI301C)) - return; + tempcx -= 2; + temp = tempcx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part2Port, 0x1B, temp); -#ifndef Tap4 - XGINew_SetRegAND(pVBInfo->Part2Port, 0x4E, 0xEB); /* Disable Tap4 */ -#else /* Tap4 Setting */ + temp = (tempcx & 0xFF00) >> 8; + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1D, ~0x0F, temp); - Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */ - for (i = 0x80, j = 0; i <= 0xBF; i++, j++) - XGINew_SetReg1(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]); + tempcx = pVBInfo->HT >> 1; + push1 = tempcx; /* push cx */ + tempcx += 7; - if ((pVBInfo->VBInfo & SetCRT2ToTV) && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) { - Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo); /* Set Vertical Scaling */ - for (i = 0xC0, j = 0; i < 0xFF; i++, j++) - XGINew_SetReg1(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]); + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) + tempcx -= 4; + + temp = tempcx & 0x00FF; + temp = temp << 4; + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x22, 0x0F, temp); + + tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8); + tempbx += tempcx; + push2 = tempbx; + temp = tempbx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part2Port, 0x24, temp); + temp = (tempbx & 0xFF00) >> 8; + temp = temp << 4; + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x25, 0x0F, temp); + + tempbx = push2; + tempbx = tempbx + 8; + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + tempbx = tempbx - 4; + tempcx = tempbx; } - if ((pVBInfo->VBInfo & SetCRT2ToTV) && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04); /* Enable V.Scaling */ - else - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x14, 0x10); /* Enable H.Scaling */ -#endif -} + temp = (tempbx & 0x00FF) << 4; + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x29, 0x0F, temp); -static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short i; - unsigned char *tempdi; - unsigned short modeflag; + j += 2; + tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8)); + temp = tempcx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part2Port, 0x27, temp); + temp = ((tempcx & 0xFF00) >> 8) << 4; + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x28, 0x0F, temp); - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */ - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */ + tempcx += 8; + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) + tempcx -= 4; - XGINew_SetReg1(pVBInfo->Part3Port, 0x00, 0x00); - if (pVBInfo->TVInfo & SetPALTV) { - XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xFA); - XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xC8); - } else { - XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xF5); - XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xB7); + temp = tempcx & 0xFF; + temp = temp << 4; + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2A, 0x0F, temp); + + tempcx = push1; /* pop cx */ + j += 2; + temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8); + tempcx -= temp; + temp = tempcx & 0x00FF; + temp = temp << 4; + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2D, 0x0F, temp); + + tempcx -= 11; + + if (!(pVBInfo->VBInfo & SetCRT2ToTV)) { + tempax = XGI_GetVGAHT2(pVBInfo); + tempcx = tempax - 1; } + temp = tempcx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part2Port, 0x2E, temp); - if (!(pVBInfo->VBInfo & SetCRT2ToTV)) - return; + tempbx = pVBInfo->VDE; - if (pVBInfo->TVInfo & SetPALMTV) { - XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xFA); - XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xC8); - XGINew_SetReg1(pVBInfo->Part3Port, 0x3D, 0xA8); + if (pVBInfo->VGAVDE == 360) + tempbx = 746; + if (pVBInfo->VGAVDE == 375) + tempbx = 746; + if (pVBInfo->VGAVDE == 405) + tempbx = 853; + + if (pVBInfo->VBInfo & SetCRT2ToTV) { + if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { + if (!(pVBInfo->TVInfo & (SetYPbPrMode525p + | SetYPbPrMode750p))) + tempbx = tempbx >> 1; + } else + tempbx = tempbx >> 1; } - if ((pVBInfo->VBInfo & SetCRT2ToHiVisionTV) || (pVBInfo->VBInfo - & SetCRT2ToYPbPr)) { - if (pVBInfo->TVInfo & SetYPbPrMode525i) - return; + tempbx -= 2; + temp = tempbx & 0x00FF; - tempdi = pVBInfo->HiTVGroup3Data; - if (pVBInfo->SetFlag & TVSimuMode) { - tempdi = pVBInfo->HiTVGroup3Simu; - if (!(modeflag & Charx8Dot)) - tempdi = pVBInfo->HiTVGroup3Text; + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + if (pVBInfo->VBType & VB_XGI301LV) { + if (pVBInfo->TVInfo & SetYPbPrMode1080i) { + if (pVBInfo->VBInfo & SetInSlaveMode) { + if (ModeNo == 0x2f) + temp += 1; + } + } + } else { + if (pVBInfo->VBInfo & SetInSlaveMode) { + if (ModeNo == 0x2f) + temp += 1; + } } + } - if (pVBInfo->TVInfo & SetYPbPrMode525p) - tempdi = pVBInfo->Ren525pGroup3; + XGINew_SetReg1(pVBInfo->Part2Port, 0x2F, temp); - if (pVBInfo->TVInfo & SetYPbPrMode750p) - tempdi = pVBInfo->Ren750pGroup3; + temp = (tempcx & 0xFF00) >> 8; + temp |= ((tempbx & 0xFF00) >> 8) << 6; - for (i = 0; i <= 0x3E; i++) - XGINew_SetReg1(pVBInfo->Part3Port, i, tempdi[i]); + if (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) { + if (pVBInfo->VBType & VB_XGI301LV) { + if (pVBInfo->TVInfo & SetYPbPrMode1080i) { + temp |= 0x10; - if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */ - if (pVBInfo->TVInfo & SetYPbPrMode525p) - XGINew_SetReg1(pVBInfo->Part3Port, 0x28, 0x3f); + if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO)) + temp |= 0x20; + } + } else { + temp |= 0x10; + if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO)) + temp |= 0x20; } } - return; -} /* {end of XGI_SetGroup3} */ -static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short tempax, tempcx, tempbx, modeflag, temp, temp2; + XGINew_SetReg1(pVBInfo->Part2Port, 0x30, temp); - unsigned long tempebx, tempeax, templong; + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV + | VB_XGI302LV | VB_XGI301C)) { /* TV gatingno */ + tempbx = pVBInfo->VDE; + tempcx = tempbx - 2; - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */ - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */ + if (pVBInfo->VBInfo & SetCRT2ToTV) { + if (!(pVBInfo->TVInfo & (SetYPbPrMode525p + | SetYPbPrMode750p))) + tempbx = tempbx >> 1; + } - temp = pVBInfo->RVBHCFACT; - XGINew_SetReg1(pVBInfo->Part4Port, 0x13, temp); + if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) { + temp = 0; + if (tempcx & 0x0400) + temp |= 0x20; - tempbx = pVBInfo->RVBHCMAX; - temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part4Port, 0x14, temp); - temp2 = ((tempbx & 0xFF00) >> 8) << 7; - tempcx = pVBInfo->VGAHT - 1; - temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part4Port, 0x16, temp); + if (tempbx & 0x0400) + temp |= 0x40; - temp = ((tempcx & 0xFF00) >> 8) << 3; - temp2 |= temp; + XGINew_SetReg1(pVBInfo->Part4Port, 0x10, temp); + } - tempcx = pVBInfo->VGAVT - 1; - if (!(pVBInfo->VBInfo & SetCRT2ToTV)) - tempcx -= 5; + temp = (((tempbx - 3) & 0x0300) >> 8) << 5; + XGINew_SetReg1(pVBInfo->Part2Port, 0x46, temp); + temp = (tempbx - 3) & 0x00FF; + XGINew_SetReg1(pVBInfo->Part2Port, 0x47, temp); + } - temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part4Port, 0x17, temp); - temp = temp2 | ((tempcx & 0xFF00) >> 8); - XGINew_SetReg1(pVBInfo->Part4Port, 0x15, temp); - XGINew_SetRegOR(pVBInfo->Part4Port, 0x0D, 0x08); - tempcx = pVBInfo->VBInfo; - tempbx = pVBInfo->VGAHDE; + tempbx = tempbx & 0x00FF; - if (modeflag & HalfDCLK) - tempbx = tempbx >> 1; + if (!(modeflag & HalfDCLK)) { + tempcx = pVBInfo->VGAHDE; + if (tempcx >= pVBInfo->HDE) { + tempbx |= 0x2000; + tempax &= 0x00FF; + } + } - if (XGI_IsLCDDualLink(pVBInfo)) - tempbx = tempbx >> 1; + tempcx = 0x0101; - if (tempcx & SetCRT2ToHiVisionTV) { - temp = 0; - if (tempbx <= 1024) - temp = 0xA0; - if (tempbx == 1280) - temp = 0xC0; - } else if (tempcx & SetCRT2ToTV) { - temp = 0xA0; - if (tempbx <= 800) - temp = 0x80; - } else { - temp = 0x80; - if (pVBInfo->VBInfo & SetCRT2ToLCD) { - temp = 0; - if (tempbx > 800) - temp = 0x60; + if (pVBInfo->VBInfo & SetCRT2ToTV) { /*301b*/ + if (pVBInfo->VGAHDE >= 1024) { + tempcx = 0x1920; + if (pVBInfo->VGAHDE >= 1280) { + tempcx = 0x1420; + tempbx = tempbx & 0xDFFF; + } } } - if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)) { - temp = 0x00; - if (pVBInfo->VGAHDE == 1280) - temp = 0x40; - if (pVBInfo->VGAHDE == 1024) - temp = 0x20; - } - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0E, ~0xEF, temp); + if (!(tempbx & 0x2000)) { + if (modeflag & HalfDCLK) + tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1); - tempebx = pVBInfo->VDE; + push1 = tempbx; + tempeax = pVBInfo->VGAHDE; + tempebx = (tempcx & 0xFF00) >> 8; + longtemp = tempeax * tempebx; + tempecx = tempcx & 0x00FF; + longtemp = longtemp / tempecx; - if (tempcx & SetCRT2ToHiVisionTV) { - if (!(temp & 0xE000)) - tempbx = tempbx >> 1; - } + /* 301b */ + tempecx = 8 * 1024; - tempcx = pVBInfo->RVBHRS; - temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part4Port, 0x18, temp); + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV + | VB_XGI302LV | VB_XGI301C)) { + tempecx = tempecx * 8; + } - tempeax = pVBInfo->VGAVDE; - tempcx |= 0x04000; + longtemp = longtemp * tempecx; + tempecx = pVBInfo->HDE; + temp2 = longtemp % tempecx; + tempeax = longtemp / tempecx; + if (temp2 != 0) + tempeax += 1; - if (tempeax <= tempebx) { - tempcx = (tempcx & (~0x4000)); - tempeax = pVBInfo->VGAVDE; - } else { - tempeax -= tempebx; - } + tempax = (unsigned short) tempeax; - templong = (tempeax * 256 * 1024) % tempebx; - tempeax = (tempeax * 256 * 1024) / tempebx; - tempebx = tempeax; + /* 301b */ + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV + | VB_XGI302LV | VB_XGI301C)) { + tempcx = ((tempax & 0xFF00) >> 5) >> 8; + } + /* end 301b */ - if (templong != 0) - tempebx++; + tempbx = push1; + tempbx = (unsigned short) (((tempeax & 0x0000FF00) & 0x1F00) + | (tempbx & 0x00FF)); + tempax = (unsigned short) (((tempeax & 0x000000FF) << 8) + | (tempax & 0x00FF)); + temp = (tempax & 0xFF00) >> 8; + } else { + temp = (tempax & 0x00FF) >> 8; + } - temp = (unsigned short) (tempebx & 0x000000FF); - XGINew_SetReg1(pVBInfo->Part4Port, 0x1B, temp); + XGINew_SetReg1(pVBInfo->Part2Port, 0x44, temp); + temp = (tempbx & 0xFF00) >> 8; + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x45, ~0x03F, temp); + temp = tempcx & 0x00FF; - temp = (unsigned short) ((tempebx & 0x0000FF00) >> 8); - XGINew_SetReg1(pVBInfo->Part4Port, 0x1A, temp); - tempbx = (unsigned short) (tempebx >> 16); - temp = tempbx & 0x00FF; - temp = temp << 4; - temp |= ((tempcx & 0xFF00) >> 8); - XGINew_SetReg1(pVBInfo->Part4Port, 0x19, temp); + if (tempbx & 0x2000) + temp = 0; - /* 301b */ - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { - temp = 0x0028; - XGINew_SetReg1(pVBInfo->Part4Port, 0x1C, temp); - tempax = pVBInfo->VGAHDE; - if (modeflag & HalfDCLK) - tempax = tempax >> 1; + if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) + temp |= 0x18; - if (XGI_IsLCDDualLink(pVBInfo)) - tempax = tempax >> 1; + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x46, ~0x1F, temp); + if (pVBInfo->TVInfo & SetPALTV) { + tempbx = 0x0382; + tempcx = 0x007e; + } else { + tempbx = 0x0369; + tempcx = 0x0061; + } - /* if((pVBInfo->VBInfo&(SetCRT2ToLCD))||((pVBInfo->TVInfo&SetYPbPrMode525p)||(pVBInfo->TVInfo&SetYPbPrMode750p))) { */ - if (pVBInfo->VBInfo & SetCRT2ToLCD) { - if (tempax > 800) - tempax -= 800; - } else { - if (pVBInfo->VGAHDE > 800) { - if (pVBInfo->VGAHDE == 1024) - tempax = (tempax * 25 / 32) - 1; - else - tempax = (tempax * 20 / 32) - 1; - } - } - tempax -= 1; + temp = tempbx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part2Port, 0x4b, temp); + temp = tempcx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part2Port, 0x4c, temp); - /* - if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) { - if (pVBInfo->VBType & VB_XGI301LV) { - if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p | SetYPbPrMode1080i))) { - if (pVBInfo->VGAHDE > 800) { - if (pVBInfo->VGAHDE == 1024) - tempax = (tempax * 25 / 32) - 1; - else - tempax = (tempax * 20 / 32) - 1; - } - } - } else { - if (pVBInfo->VGAHDE > 800) { - if (pVBInfo->VGAHDE == 1024) - tempax = (tempax * 25 / 32) - 1; - else - tempax = (tempax * 20 / 32) - 1; - } - } - } - */ + temp = ((tempcx & 0xFF00) >> 8) & 0x03; + temp = temp << 2; + temp |= ((tempbx & 0xFF00) >> 8) & 0x03; - temp = (tempax & 0xFF00) >> 8; - temp = ((temp & 0x0003) << 4); - XGINew_SetReg1(pVBInfo->Part4Port, 0x1E, temp); - temp = (tempax & 0x00FF); - XGINew_SetReg1(pVBInfo->Part4Port, 0x1D, temp); + if (pVBInfo->VBInfo & SetCRT2ToYPbPr) { + temp |= 0x10; - if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) { - if (pVBInfo->VGAHDE > 800) - XGINew_SetRegOR(pVBInfo->Part4Port, 0x1E, 0x08); + if (pVBInfo->TVInfo & SetYPbPrMode525p) + temp |= 0x20; - } - temp = 0x0036; + if (pVBInfo->TVInfo & SetYPbPrMode750p) + temp |= 0x60; + } - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (!(pVBInfo->TVInfo & (NTSC1024x768 - | SetYPbPrMode525p | SetYPbPrMode750p - | SetYPbPrMode1080i))) { - temp |= 0x0001; - if ((pVBInfo->VBInfo & SetInSlaveMode) - && (!(pVBInfo->TVInfo - & TVSimuMode))) - temp &= (~0x0001); + XGINew_SetReg1(pVBInfo->Part2Port, 0x4d, temp); + temp = XGINew_GetReg1(pVBInfo->Part2Port, 0x43); /* 301b change */ + XGINew_SetReg1(pVBInfo->Part2Port, 0x43, (unsigned short) (temp - 3)); + + if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) { + if (pVBInfo->TVInfo & NTSC1024x768) { + TimingPoint = XGI_NTSC1024AdjTime; + for (i = 0x1c, j = 0; i <= 0x30; i++, j++) { + XGINew_SetReg1(pVBInfo->Part2Port, i, + TimingPoint[j]); } + XGINew_SetReg1(pVBInfo->Part2Port, 0x43, 0x72); } + } - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x1F, 0x00C0, temp); - tempbx = pVBInfo->HT; - if (XGI_IsLCDDualLink(pVBInfo)) - tempbx = tempbx >> 1; - tempbx = (tempbx >> 1) - 2; - temp = ((tempbx & 0x0700) >> 8) << 3; - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x21, 0x00C0, temp); - temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part4Port, 0x22, temp); + /* [ycchen] 01/14/03 Modify for 301C PALM Support */ + if (pVBInfo->VBType & VB_XGI301C) { + if (pVBInfo->TVInfo & SetPALMTV) + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x08, + 0x08); /* PALM Mode */ } - /* end 301b */ - if (pVBInfo->ISXPDOS == 0) - XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, - pVBInfo); -} + if (pVBInfo->TVInfo & SetPALMTV) { + tempax = (unsigned char) XGINew_GetReg1(pVBInfo->Part2Port, + 0x01); + tempax--; + XGINew_SetRegAND(pVBInfo->Part2Port, 0x01, tempax); -static void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short Pindex, Pdata; + /* if ( !( pVBInfo->VBType & VB_XGI301C ) ) */ + XGINew_SetRegAND(pVBInfo->Part2Port, 0x00, 0xEF); + } - Pindex = pVBInfo->Part5Port; - Pdata = pVBInfo->Part5Port + 1; - if (pVBInfo->ModeType == ModeVGA) { - if (!(pVBInfo->VBInfo & (SetInSlaveMode | LoadDACFlag - | CRT2DisplayFlag))) { - XGINew_EnableCRT2(pVBInfo); - /* LoadDAC2(pVBInfo->Part5Port, ModeNo, ModeIdIndex); */ - } + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { + if (!(pVBInfo->VBInfo & SetInSlaveMode)) + XGINew_SetReg1(pVBInfo->Part2Port, 0x0B, 0x00); } - return; + + if (pVBInfo->VBInfo & SetCRT2ToTV) + return; } -static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, - unsigned short ModeIdIndex, +static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, + struct xgi_hw_device_info *HwDeviceExtension, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - unsigned short i, tempdx, tempcx, tempbx, tempal, modeflag, table; - - struct XGI330_LCDDataTablStruct *tempdi = NULL; + unsigned short push1, push2, pushbx, tempax, tempbx, tempcx, temp, + tempah, tempbh, tempch, resinfo, modeflag, CRT1Index; - tempbx = BX; + struct XGI_LCDDesStruct *LCDBDesPtr = NULL; if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */ + resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */ + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + CRT1Index + = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index &= IndexMask; } - tempal = tempal & 0x0f; + if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) + return; - if (tempbx <= 1) { /* ExpLink */ - if (ModeNo <= 0x13) { - tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; /* find no Ext_CRT2CRTC2 */ - } else { - tempal - = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; - } + tempbx = pVBInfo->HDE; /* RHACTE=HDE-1 */ - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { - if (ModeNo <= 0x13) - tempal - = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC2; - else - tempal - = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC2; - } + if (XGI_IsLCDDualLink(pVBInfo)) + tempbx = tempbx >> 1; - if (tempbx & 0x01) - tempal = (tempal >> 4); + tempbx -= 1; + temp = tempbx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part2Port, 0x2C, temp); + temp = (tempbx & 0xFF00) >> 8; + temp = temp << 4; + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2B, 0x0F, temp); + temp = 0x01; - tempal = (tempal & 0x0f); + if (pVBInfo->LCDResInfo == Panel1280x1024) { + if (pVBInfo->ModeType == ModeEGA) { + if (pVBInfo->VGAHDE >= 1024) { + temp = 0x02; + if (pVBInfo->LCDInfo & LCDVESATiming) + temp = 0x01; + } + } } - tempcx = LCDLenList[tempbx]; /* mov cl,byte ptr cs:LCDLenList[bx] */ - - if (pVBInfo->LCDInfo & EnableScalingLCD) { /* ScaleLCD */ - if ((tempbx == 5) || (tempbx) == 7) - tempcx = LCDDesDataLen2; - else if ((tempbx == 3) || (tempbx == 8)) - tempcx = LVDSDesDataLen2; - } - /* mov di, word ptr cs:LCDDataList[bx] */ - /* tempdi = pVideoMemory[LCDDataList + tempbx * 2] | (pVideoMemory[LCDDataList + tempbx * 2 + 1] << 8); */ + XGINew_SetReg1(pVBInfo->Part2Port, 0x0B, temp); + tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */ + push1 = tempbx; + tempbx--; + temp = tempbx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part2Port, 0x03, temp); + temp = ((tempbx & 0xFF00) >> 8) & 0x07; + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0C, ~0x07, temp); - switch (tempbx) { - case 0: - tempdi = XGI_EPLLCDCRT1Ptr_H; - break; - case 1: - tempdi = XGI_EPLLCDCRT1Ptr_V; - break; - case 2: - tempdi = XGI_EPLLCDDataPtr; - break; - case 3: - tempdi = XGI_EPLLCDDesDataPtr; - break; - case 4: - tempdi = XGI_LCDDataTable; - break; - case 5: - tempdi = XGI_LCDDesDataTable; - break; - case 6: - tempdi = XGI_EPLCHLCDRegPtr; - break; - case 7: - case 8: - case 9: - tempdi = NULL; - break; - default: - break; - } + tempcx = pVBInfo->VT - 1; + push2 = tempcx + 1; + temp = tempcx & 0x00FF; /* RVTVT=VT-1 */ + XGINew_SetReg1(pVBInfo->Part2Port, 0x19, temp); + temp = (tempcx & 0xFF00) >> 8; + temp = temp << 5; + XGINew_SetReg1(pVBInfo->Part2Port, 0x1A, temp); + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x09, 0xF0, 0x00); + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0xF0, 0x00); + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x17, 0xFB, 0x00); + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x18, 0xDF, 0x00); - if (tempdi == NULL) /* OEMUtil */ - return NULL; + /* Customized LCDB Des no add */ + tempbx = 5; + LCDBDesPtr = (struct XGI_LCDDesStruct *) XGI_GetLcdPtr(tempbx, ModeNo, + ModeIdIndex, RefreshRateTableIndex, pVBInfo); + tempah = pVBInfo->LCDResInfo; + tempah &= PanelResInfo; - table = tempbx; - i = 0; + if ((tempah == Panel1024x768) || (tempah == Panel1024x768x75)) { + tempbx = 1024; + tempcx = 768; + } else if ((tempah == Panel1280x1024) || (tempah == Panel1280x1024x75)) { + tempbx = 1280; + tempcx = 1024; + } else if (tempah == Panel1400x1050) { + tempbx = 1400; + tempcx = 1050; + } else { + tempbx = 1600; + tempcx = 1200; + } - while (tempdi[i].PANELID != 0xff) { - tempdx = pVBInfo->LCDResInfo; - if (tempbx & 0x0080) { /* OEMUtil */ - tempbx &= (~0x0080); - tempdx = pVBInfo->LCDTypeInfo; - } + if (pVBInfo->LCDInfo & EnableScalingLCD) { + tempbx = pVBInfo->HDE; + tempcx = pVBInfo->VDE; + } - if (pVBInfo->LCDInfo & EnableScalingLCD) - tempdx &= (~PanelResInfo); + pushbx = tempbx; + tempax = pVBInfo->VT; + pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES; + pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS; + pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES; + pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS; + tempbx = pVBInfo->LCDVDES; + tempcx += tempbx; - if (tempdi[i].PANELID == tempdx) { - tempbx = tempdi[i].MASK; - tempdx = pVBInfo->LCDInfo; + if (tempcx >= tempax) + tempcx -= tempax; /* lcdvdes */ - if (ModeNo <= 0x13) /* alan 09/10/2003 */ - tempdx |= SetLCDStdMode; + temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */ + XGINew_SetReg1(pVBInfo->Part2Port, 0x05, temp); + temp = tempcx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part2Port, 0x06, temp); + tempch = ((tempcx & 0xFF00) >> 8) & 0x07; + tempbh = ((tempbx & 0xFF00) >> 8) & 0x07; + tempah = tempch; + tempah = tempah << 3; + tempah |= tempbh; + XGINew_SetReg1(pVBInfo->Part2Port, 0x02, tempah); - if (modeflag & HalfDCLK) - tempdx |= SetLCDLowResolution; + /* getlcdsync() */ + XGI_GetLCDSync(&tempax, &tempbx, pVBInfo); + tempcx = tempbx; + tempax = pVBInfo->VT; + tempbx = pVBInfo->LCDVRS; - tempbx &= tempdx; - if (tempbx == tempdi[i].CAP) - break; - } - i++; - } + /* if (SetLCD_Info & EnableScalingLCD) */ + tempcx += tempbx; + if (tempcx >= tempax) + tempcx -= tempax; - if (table == 0) { - switch (tempdi[i].DATAPTR) { - case 0: - return &XGI_LVDSCRT11024x768_1_H[tempal]; - break; - case 1: - return &XGI_LVDSCRT11024x768_2_H[tempal]; - break; - case 2: - return &XGI_LVDSCRT11280x1024_1_H[tempal]; - break; - case 3: - return &XGI_LVDSCRT11280x1024_2_H[tempal]; - break; - case 4: - return &XGI_LVDSCRT11400x1050_1_H[tempal]; - break; - case 5: - return &XGI_LVDSCRT11400x1050_2_H[tempal]; - break; - case 6: - return &XGI_LVDSCRT11600x1200_1_H[tempal]; - break; - case 7: - return &XGI_LVDSCRT11024x768_1_Hx75[tempal]; - break; - case 8: - return &XGI_LVDSCRT11024x768_2_Hx75[tempal]; - break; - case 9: - return &XGI_LVDSCRT11280x1024_1_Hx75[tempal]; - break; - case 10: - return &XGI_LVDSCRT11280x1024_2_Hx75[tempal]; - break; - default: - break; - } - } else if (table == 1) { - switch (tempdi[i].DATAPTR) { - case 0: - return &XGI_LVDSCRT11024x768_1_V[tempal]; - break; - case 1: - return &XGI_LVDSCRT11024x768_2_V[tempal]; - break; - case 2: - return &XGI_LVDSCRT11280x1024_1_V[tempal]; - break; - case 3: - return &XGI_LVDSCRT11280x1024_2_V[tempal]; - break; - case 4: - return &XGI_LVDSCRT11400x1050_1_V[tempal]; - break; - case 5: - return &XGI_LVDSCRT11400x1050_2_V[tempal]; - break; - case 6: - return &XGI_LVDSCRT11600x1200_1_V[tempal]; - break; - case 7: - return &XGI_LVDSCRT11024x768_1_Vx75[tempal]; - break; - case 8: - return &XGI_LVDSCRT11024x768_2_Vx75[tempal]; - break; - case 9: - return &XGI_LVDSCRT11280x1024_1_Vx75[tempal]; - break; - case 10: - return &XGI_LVDSCRT11280x1024_2_Vx75[tempal]; - break; - default: - break; - } - } else if (table == 2) { - switch (tempdi[i].DATAPTR) { - case 0: - return &XGI_LVDS1024x768Data_1[tempal]; - break; - case 1: - return &XGI_LVDS1024x768Data_2[tempal]; - break; - case 2: - return &XGI_LVDS1280x1024Data_1[tempal]; - break; - case 3: - return &XGI_LVDS1280x1024Data_2[tempal]; - break; - case 4: - return &XGI_LVDS1400x1050Data_1[tempal]; - break; - case 5: - return &XGI_LVDS1400x1050Data_2[tempal]; - break; - case 6: - return &XGI_LVDS1600x1200Data_1[tempal]; - break; - case 7: - return &XGI_LVDSNoScalingData[tempal]; - break; - case 8: - return &XGI_LVDS1024x768Data_1x75[tempal]; - break; - case 9: - return &XGI_LVDS1024x768Data_2x75[tempal]; - break; - case 10: - return &XGI_LVDS1280x1024Data_1x75[tempal]; - break; - case 11: - return &XGI_LVDS1280x1024Data_2x75[tempal]; - break; - case 12: - return &XGI_LVDSNoScalingDatax75[tempal]; - break; - default: - break; - } - } else if (table == 3) { - switch (tempdi[i].DATAPTR) { - case 0: - return &XGI_LVDS1024x768Des_1[tempal]; - break; - case 1: - return &XGI_LVDS1024x768Des_3[tempal]; - break; - case 2: - return &XGI_LVDS1024x768Des_2[tempal]; - break; - case 3: - return &XGI_LVDS1280x1024Des_1[tempal]; - break; - case 4: - return &XGI_LVDS1280x1024Des_2[tempal]; - break; - case 5: - return &XGI_LVDS1400x1050Des_1[tempal]; - break; - case 6: - return &XGI_LVDS1400x1050Des_2[tempal]; - break; - case 7: - return &XGI_LVDS1600x1200Des_1[tempal]; - break; - case 8: - return &XGI_LVDSNoScalingDesData[tempal]; - break; - case 9: - return &XGI_LVDS1024x768Des_1x75[tempal]; - break; - case 10: - return &XGI_LVDS1024x768Des_3x75[tempal]; - break; - case 11: - return &XGI_LVDS1024x768Des_2x75[tempal]; - break; - case 12: - return &XGI_LVDS1280x1024Des_1x75[tempal]; - break; - case 13: - return &XGI_LVDS1280x1024Des_2x75[tempal]; - break; - case 14: - return &XGI_LVDSNoScalingDesDatax75[tempal]; - break; - default: - break; + temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */ + XGINew_SetReg1(pVBInfo->Part2Port, 0x04, temp); + temp = (tempbx & 0xFF00) >> 8; + temp = temp << 4; + temp |= (tempcx & 0x000F); + XGINew_SetReg1(pVBInfo->Part2Port, 0x01, temp); + tempcx = pushbx; + tempax = pVBInfo->HT; + tempbx = pVBInfo->LCDHDES; + tempbx &= 0x0FFF; + + if (XGI_IsLCDDualLink(pVBInfo)) { + tempax = tempax >> 1; + tempbx = tempbx >> 1; + tempcx = tempcx >> 1; + } + + if (pVBInfo->VBType & VB_XGI302LV) + tempbx += 1; + + if (pVBInfo->VBType & VB_XGI301C) /* tap4 */ + tempbx += 1; + + tempcx += tempbx; + + if (tempcx >= tempax) + tempcx -= tempax; + + temp = tempbx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */ + temp = ((tempbx & 0xFF00) >> 8) << 4; + XGINew_SetReg1(pVBInfo->Part2Port, 0x20, temp); + temp = tempcx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */ + temp = (tempcx & 0xFF00) >> 8; + XGINew_SetReg1(pVBInfo->Part2Port, 0x25, temp); + + /* getlcdsync() */ + XGI_GetLCDSync(&tempax, &tempbx, pVBInfo); + tempcx = tempax; + tempax = pVBInfo->HT; + tempbx = pVBInfo->LCDHRS; + /* if ( SetLCD_Info & EnableScalingLCD) */ + if (XGI_IsLCDDualLink(pVBInfo)) { + tempax = tempax >> 1; + tempbx = tempbx >> 1; + tempcx = tempcx >> 1; + } + + if (pVBInfo->VBType & VB_XGI302LV) + tempbx += 1; + + tempcx += tempbx; + + if (tempcx >= tempax) + tempcx -= tempax; + + temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */ + XGINew_SetReg1(pVBInfo->Part2Port, 0x1C, temp); + + temp = (tempbx & 0xFF00) >> 8; + temp = temp << 4; + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1D, ~0x0F0, temp); + temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */ + XGINew_SetReg1(pVBInfo->Part2Port, 0x21, temp); + + if (!(pVBInfo->LCDInfo & LCDVESATiming)) { + if (pVBInfo->VGAVDE == 525) { + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B + | VB_XGI301LV | VB_XGI302LV + | VB_XGI301C)) { + temp = 0xC6; + } else + temp = 0xC4; + + XGINew_SetReg1(pVBInfo->Part2Port, 0x2f, temp); + XGINew_SetReg1(pVBInfo->Part2Port, 0x30, 0xB3); } - } else if (table == 4) { - switch (tempdi[i].DATAPTR) { - case 0: - return &XGI_ExtLCD1024x768Data[tempal]; - break; - case 1: - return &XGI_StLCD1024x768Data[tempal]; - break; - case 2: - return &XGI_CetLCD1024x768Data[tempal]; - break; - case 3: - return &XGI_ExtLCD1280x1024Data[tempal]; - break; - case 4: - return &XGI_StLCD1280x1024Data[tempal]; - break; - case 5: - return &XGI_CetLCD1280x1024Data[tempal]; - break; - case 6: - return &XGI_ExtLCD1400x1050Data[tempal]; - break; - case 7: - return &XGI_StLCD1400x1050Data[tempal]; - break; - case 8: - return &XGI_CetLCD1400x1050Data[tempal]; - break; - case 9: - return &XGI_ExtLCD1600x1200Data[tempal]; - break; - case 10: - return &XGI_StLCD1600x1200Data[tempal]; - break; - case 11: - return &XGI_NoScalingData[tempal]; - break; - case 12: - return &XGI_ExtLCD1024x768x75Data[tempal]; - break; - case 13: - return &XGI_ExtLCD1024x768x75Data[tempal]; - break; - case 14: - return &XGI_CetLCD1024x768x75Data[tempal]; - break; - case 15: - return &XGI_ExtLCD1280x1024x75Data[tempal]; - break; - case 16: - return &XGI_StLCD1280x1024x75Data[tempal]; - break; - case 17: - return &XGI_CetLCD1280x1024x75Data[tempal]; - break; - case 18: - return &XGI_NoScalingDatax75[tempal]; - break; - default: - break; + + if (pVBInfo->VGAVDE == 420) { + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B + | VB_XGI301LV | VB_XGI302LV + | VB_XGI301C)) { + temp = 0x4F; + } else + temp = 0x4E; + XGINew_SetReg1(pVBInfo->Part2Port, 0x2f, temp); } - } else if (table == 5) { - switch (tempdi[i].DATAPTR) { - case 0: - return &XGI_ExtLCDDes1024x768Data[tempal]; - break; - case 1: - return &XGI_StLCDDes1024x768Data[tempal]; - break; - case 2: - return &XGI_CetLCDDes1024x768Data[tempal]; - break; - case 3: - if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType - & VB_XGI302LV)) - return &XGI_ExtLCDDLDes1280x1024Data[tempal]; - else - return &XGI_ExtLCDDes1280x1024Data[tempal]; - break; - case 4: - if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType - & VB_XGI302LV)) - return &XGI_StLCDDLDes1280x1024Data[tempal]; - else - return &XGI_StLCDDes1280x1024Data[tempal]; - break; - case 5: - if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType - & VB_XGI302LV)) - return &XGI_CetLCDDLDes1280x1024Data[tempal]; - else - return &XGI_CetLCDDes1280x1024Data[tempal]; - break; - case 6: - if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType - & VB_XGI302LV)) - return &XGI_ExtLCDDLDes1400x1050Data[tempal]; - else - return &XGI_ExtLCDDes1400x1050Data[tempal]; - break; - case 7: - if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType - & VB_XGI302LV)) - return &XGI_StLCDDLDes1400x1050Data[tempal]; - else - return &XGI_StLCDDes1400x1050Data[tempal]; - break; - case 8: - return &XGI_CetLCDDes1400x1050Data[tempal]; - break; - case 9: - return &XGI_CetLCDDes1400x1050Data2[tempal]; - break; - case 10: - if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType - & VB_XGI302LV)) - return &XGI_ExtLCDDLDes1600x1200Data[tempal]; - else - return &XGI_ExtLCDDes1600x1200Data[tempal]; - break; - case 11: - if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType - & VB_XGI302LV)) - return &XGI_StLCDDLDes1600x1200Data[tempal]; - else - return &XGI_StLCDDes1600x1200Data[tempal]; - break; - case 12: - return &XGI_NoScalingDesData[tempal]; - break; - case 13: - return &XGI_ExtLCDDes1024x768x75Data[tempal]; - break; - case 14: - return &XGI_StLCDDes1024x768x75Data[tempal]; - break; - case 15: - return &XGI_CetLCDDes1024x768x75Data[tempal]; - break; - case 16: - if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType - & VB_XGI302LV)) - return &XGI_ExtLCDDLDes1280x1024x75Data[tempal]; - else - return &XGI_ExtLCDDes1280x1024x75Data[tempal]; - break; - case 17: - if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType - & VB_XGI302LV)) - return &XGI_StLCDDLDes1280x1024x75Data[tempal]; - else - return &XGI_StLCDDes1280x1024x75Data[tempal]; - break; - case 18: - if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType - & VB_XGI302LV)) - return &XGI_CetLCDDLDes1280x1024x75Data[tempal]; - else - return &XGI_CetLCDDes1280x1024x75Data[tempal]; - break; - case 19: - return &XGI_NoScalingDesDatax75[tempal]; - break; - default: + } +} + +/* --------------------------------------------------------------------- */ +/* Function : XGI_GetTap4Ptr */ +/* Input : */ +/* Output : di -> Tap4 Reg. Setting Pointer */ +/* Description : */ +/* --------------------------------------------------------------------- */ +static struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx, + struct vb_device_info *pVBInfo) +{ + unsigned short tempax, tempbx, i; + + struct XGI301C_Tap4TimingStruct *Tap4TimingPtr; + + if (tempcx == 0) { + tempax = pVBInfo->VGAHDE; + tempbx = pVBInfo->HDE; + } else { + tempax = pVBInfo->VGAVDE; + tempbx = pVBInfo->VDE; + } + + if (tempax < tempbx) + return &EnlargeTap4Timing[0]; + else if (tempax == tempbx) + return &NoScaleTap4Timing[0]; /* 1:1 */ + else + Tap4TimingPtr = NTSCTap4Timing; /* NTSC */ + + if (pVBInfo->TVInfo & SetPALTV) + Tap4TimingPtr = PALTap4Timing; + + if (pVBInfo->VBInfo & SetCRT2ToYPbPr) { + if (pVBInfo->TVInfo & SetYPbPrMode525i) + Tap4TimingPtr = YPbPr525iTap4Timing; + if (pVBInfo->TVInfo & SetYPbPrMode525p) + Tap4TimingPtr = YPbPr525pTap4Timing; + if (pVBInfo->TVInfo & SetYPbPrMode750p) + Tap4TimingPtr = YPbPr750pTap4Timing; + } + + if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) + Tap4TimingPtr = HiTVTap4Timing; + + i = 0; + while (Tap4TimingPtr[i].DE != 0xFFFF) { + if (Tap4TimingPtr[i].DE == tempax) break; + i++; + } + return &Tap4TimingPtr[i]; +} + +static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo) +{ + unsigned short i, j; + + struct XGI301C_Tap4TimingStruct *Tap4TimingPtr; + + if (!(pVBInfo->VBType & VB_XGI301C)) + return; + +#ifndef Tap4 + XGINew_SetRegAND(pVBInfo->Part2Port, 0x4E, 0xEB); /* Disable Tap4 */ +#else /* Tap4 Setting */ + + Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */ + for (i = 0x80, j = 0; i <= 0xBF; i++, j++) + XGINew_SetReg1(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]); + + if ((pVBInfo->VBInfo & SetCRT2ToTV) && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) { + Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo); /* Set Vertical Scaling */ + for (i = 0xC0, j = 0; i < 0xFF; i++, j++) + XGINew_SetReg1(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]); + } + + if ((pVBInfo->VBInfo & SetCRT2ToTV) && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04); /* Enable V.Scaling */ + else + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x14, 0x10); /* Enable H.Scaling */ +#endif +} + +static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, + struct vb_device_info *pVBInfo) +{ + unsigned short i; + unsigned char *tempdi; + unsigned short modeflag; + + if (ModeNo <= 0x13) + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */ + else + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */ + + XGINew_SetReg1(pVBInfo->Part3Port, 0x00, 0x00); + if (pVBInfo->TVInfo & SetPALTV) { + XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xFA); + XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xC8); + } else { + XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xF5); + XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xB7); + } + + if (!(pVBInfo->VBInfo & SetCRT2ToTV)) + return; + + if (pVBInfo->TVInfo & SetPALMTV) { + XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xFA); + XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xC8); + XGINew_SetReg1(pVBInfo->Part3Port, 0x3D, 0xA8); + } + + if ((pVBInfo->VBInfo & SetCRT2ToHiVisionTV) || (pVBInfo->VBInfo + & SetCRT2ToYPbPr)) { + if (pVBInfo->TVInfo & SetYPbPrMode525i) + return; + + tempdi = pVBInfo->HiTVGroup3Data; + if (pVBInfo->SetFlag & TVSimuMode) { + tempdi = pVBInfo->HiTVGroup3Simu; + if (!(modeflag & Charx8Dot)) + tempdi = pVBInfo->HiTVGroup3Text; } - } else if (table == 6) { - switch (tempdi[i].DATAPTR) { - case 0: - return &XGI_CH7017LV1024x768[tempal]; - break; - case 1: - return &XGI_CH7017LV1400x1050[tempal]; - break; - default: - break; + + if (pVBInfo->TVInfo & SetYPbPrMode525p) + tempdi = pVBInfo->Ren525pGroup3; + + if (pVBInfo->TVInfo & SetYPbPrMode750p) + tempdi = pVBInfo->Ren750pGroup3; + + for (i = 0; i <= 0x3E; i++) + XGINew_SetReg1(pVBInfo->Part3Port, i, tempdi[i]); + + if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */ + if (pVBInfo->TVInfo & SetYPbPrMode525p) + XGINew_SetReg1(pVBInfo->Part3Port, 0x28, 0x3f); } } - return NULL; -} + return; +} /* {end of XGI_SetGroup3} */ -static void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo, - unsigned short ModeIdIndex, +static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, + struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - unsigned short i, tempdx, tempbx, tempal, modeflag, table; - struct XGI330_TVDataTablStruct *tempdi = NULL; + unsigned short tempax, tempcx, tempbx, modeflag, temp, temp2; - tempbx = BX; + unsigned long tempebx, tempeax, templong; + + if (ModeNo <= 0x13) + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */ + else + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */ + + temp = pVBInfo->RVBHCFACT; + XGINew_SetReg1(pVBInfo->Part4Port, 0x13, temp); + + tempbx = pVBInfo->RVBHCMAX; + temp = tempbx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part4Port, 0x14, temp); + temp2 = ((tempbx & 0xFF00) >> 8) << 7; + tempcx = pVBInfo->VGAHT - 1; + temp = tempcx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part4Port, 0x16, temp); + + temp = ((tempcx & 0xFF00) >> 8) << 3; + temp2 |= temp; + + tempcx = pVBInfo->VGAVT - 1; + if (!(pVBInfo->VBInfo & SetCRT2ToTV)) + tempcx -= 5; + + temp = tempcx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part4Port, 0x17, temp); + temp = temp2 | ((tempcx & 0xFF00) >> 8); + XGINew_SetReg1(pVBInfo->Part4Port, 0x15, temp); + XGINew_SetRegOR(pVBInfo->Part4Port, 0x0D, 0x08); + tempcx = pVBInfo->VBInfo; + tempbx = pVBInfo->VGAHDE; + + if (modeflag & HalfDCLK) + tempbx = tempbx >> 1; + + if (XGI_IsLCDDualLink(pVBInfo)) + tempbx = tempbx >> 1; + + if (tempcx & SetCRT2ToHiVisionTV) { + temp = 0; + if (tempbx <= 1024) + temp = 0xA0; + if (tempbx == 1280) + temp = 0xC0; + } else if (tempcx & SetCRT2ToTV) { + temp = 0xA0; + if (tempbx <= 800) + temp = 0x80; + } else { + temp = 0x80; + if (pVBInfo->VBInfo & SetCRT2ToLCD) { + temp = 0; + if (tempbx > 800) + temp = 0x60; + } + } + + if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)) { + temp = 0x00; + if (pVBInfo->VGAHDE == 1280) + temp = 0x40; + if (pVBInfo->VGAHDE == 1024) + temp = 0x20; + } + XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0E, ~0xEF, temp); + + tempebx = pVBInfo->VDE; + + if (tempcx & SetCRT2ToHiVisionTV) { + if (!(temp & 0xE000)) + tempbx = tempbx >> 1; + } + + tempcx = pVBInfo->RVBHRS; + temp = tempcx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part4Port, 0x18, temp); + + tempeax = pVBInfo->VGAVDE; + tempcx |= 0x04000; + + if (tempeax <= tempebx) { + tempcx = (tempcx & (~0x4000)); + tempeax = pVBInfo->VGAVDE; + } else { + tempeax -= tempebx; + } + + templong = (tempeax * 256 * 1024) % tempebx; + tempeax = (tempeax * 256 * 1024) / tempebx; + tempebx = tempeax; + + if (templong != 0) + tempebx++; + + temp = (unsigned short) (tempebx & 0x000000FF); + XGINew_SetReg1(pVBInfo->Part4Port, 0x1B, temp); + + temp = (unsigned short) ((tempebx & 0x0000FF00) >> 8); + XGINew_SetReg1(pVBInfo->Part4Port, 0x1A, temp); + tempbx = (unsigned short) (tempebx >> 16); + temp = tempbx & 0x00FF; + temp = temp << 4; + temp |= ((tempcx & 0xFF00) >> 8); + XGINew_SetReg1(pVBInfo->Part4Port, 0x19, temp); + + /* 301b */ + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV + | VB_XGI302LV | VB_XGI301C)) { + temp = 0x0028; + XGINew_SetReg1(pVBInfo->Part4Port, 0x1C, temp); + tempax = pVBInfo->VGAHDE; + if (modeflag & HalfDCLK) + tempax = tempax >> 1; - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; - } + if (XGI_IsLCDDualLink(pVBInfo)) + tempax = tempax >> 1; - tempal = tempal & 0x3f; - table = tempbx; + /* if((pVBInfo->VBInfo&(SetCRT2ToLCD))||((pVBInfo->TVInfo&SetYPbPrMode525p)||(pVBInfo->TVInfo&SetYPbPrMode750p))) { */ + if (pVBInfo->VBInfo & SetCRT2ToLCD) { + if (tempax > 800) + tempax -= 800; + } else { + if (pVBInfo->VGAHDE > 800) { + if (pVBInfo->VGAHDE == 1024) + tempax = (tempax * 25 / 32) - 1; + else + tempax = (tempax * 20 / 32) - 1; + } + } + tempax -= 1; - switch (tempbx) { - case 0: - tempdi = NULL; /*EPLCHTVCRT1Ptr_H;*/ - if (pVBInfo->IF_DEF_CH7007 == 1) - tempdi = XGI_EPLCHTVCRT1Ptr; + /* + if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) { + if (pVBInfo->VBType & VB_XGI301LV) { + if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p | SetYPbPrMode1080i))) { + if (pVBInfo->VGAHDE > 800) { + if (pVBInfo->VGAHDE == 1024) + tempax = (tempax * 25 / 32) - 1; + else + tempax = (tempax * 20 / 32) - 1; + } + } + } else { + if (pVBInfo->VGAHDE > 800) { + if (pVBInfo->VGAHDE == 1024) + tempax = (tempax * 25 / 32) - 1; + else + tempax = (tempax * 20 / 32) - 1; + } + } + } + */ - break; - case 1: - tempdi = NULL; /*EPLCHTVCRT1Ptr_V;*/ - if (pVBInfo->IF_DEF_CH7007 == 1) - tempdi = XGI_EPLCHTVCRT1Ptr; + temp = (tempax & 0xFF00) >> 8; + temp = ((temp & 0x0003) << 4); + XGINew_SetReg1(pVBInfo->Part4Port, 0x1E, temp); + temp = (tempax & 0x00FF); + XGINew_SetReg1(pVBInfo->Part4Port, 0x1D, temp); - break; - case 2: - tempdi = XGI_EPLCHTVDataPtr; - break; - case 3: - tempdi = NULL; - break; - case 4: - tempdi = XGI_TVDataTable; - break; - case 5: - tempdi = NULL; - break; - case 6: - tempdi = XGI_EPLCHTVRegPtr; - break; - default: - break; - } + if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) { + if (pVBInfo->VGAHDE > 800) + XGINew_SetRegOR(pVBInfo->Part4Port, 0x1E, 0x08); - if (tempdi == NULL) /* OEMUtil */ - return NULL; + } + temp = 0x0036; - tempdx = pVBInfo->TVInfo; + if (pVBInfo->VBInfo & SetCRT2ToTV) { + if (!(pVBInfo->TVInfo & (NTSC1024x768 + | SetYPbPrMode525p | SetYPbPrMode750p + | SetYPbPrMode1080i))) { + temp |= 0x0001; + if ((pVBInfo->VBInfo & SetInSlaveMode) + && (!(pVBInfo->TVInfo + & TVSimuMode))) + temp &= (~0x0001); + } + } - if (pVBInfo->VBInfo & SetInSlaveMode) - tempdx = tempdx | SetTVLockMode; + XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x1F, 0x00C0, temp); + tempbx = pVBInfo->HT; + if (XGI_IsLCDDualLink(pVBInfo)) + tempbx = tempbx >> 1; + tempbx = (tempbx >> 1) - 2; + temp = ((tempbx & 0x0700) >> 8) << 3; + XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x21, 0x00C0, temp); + temp = tempbx & 0x00FF; + XGINew_SetReg1(pVBInfo->Part4Port, 0x22, temp); + } + /* end 301b */ - if (modeflag & HalfDCLK) - tempdx = tempdx | SetTVLowResolution; + if (pVBInfo->ISXPDOS == 0) + XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, + pVBInfo); +} - i = 0; +static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo) +{ + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1E, 0xFF, 0x20); +} - while (tempdi[i].MASK != 0xffff) { - if ((tempdx & tempdi[i].MASK) == tempdi[i].CAP) - break; - i++; - } +static void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex, + struct vb_device_info *pVBInfo) +{ + unsigned short Pindex, Pdata; - if (table == 0x00) { /* 07/05/22 */ - } else if (table == 0x01) { - } else if (table == 0x04) { - switch (tempdi[i].DATAPTR) { - case 0: - return &XGI_ExtPALData[tempal]; - break; - case 1: - return &XGI_ExtNTSCData[tempal]; - break; - case 2: - return &XGI_StPALData[tempal]; - break; - case 3: - return &XGI_StNTSCData[tempal]; - break; - case 4: - return &XGI_ExtHiTVData[tempal]; - break; - case 5: - return &XGI_St2HiTVData[tempal]; - break; - case 6: - return &XGI_ExtYPbPr525iData[tempal]; - break; - case 7: - return &XGI_ExtYPbPr525pData[tempal]; - break; - case 8: - return &XGI_ExtYPbPr750pData[tempal]; - break; - case 9: - return &XGI_StYPbPr525iData[tempal]; - break; - case 10: - return &XGI_StYPbPr525pData[tempal]; - break; - case 11: - return &XGI_StYPbPr750pData[tempal]; - break; - case 12: /* avoid system hang */ - return &XGI_ExtNTSCData[tempal]; - break; - case 13: - return &XGI_St1HiTVData[tempal]; - break; - default: - break; - } - } else if (table == 0x02) { - switch (tempdi[i].DATAPTR) { - case 0: - return &XGI_CHTVUNTSCData[tempal]; - break; - case 1: - return &XGI_CHTVONTSCData[tempal]; - break; - case 2: - return &XGI_CHTVUPALData[tempal]; - break; - case 3: - return &XGI_CHTVOPALData[tempal]; - break; - default: - break; + Pindex = pVBInfo->Part5Port; + Pdata = pVBInfo->Part5Port + 1; + if (pVBInfo->ModeType == ModeVGA) { + if (!(pVBInfo->VBInfo & (SetInSlaveMode | LoadDACFlag + | CRT2DisplayFlag))) { + XGINew_EnableCRT2(pVBInfo); + /* LoadDAC2(pVBInfo->Part5Port, ModeNo, ModeIdIndex); */ } - } else if (table == 0x06) { } - return NULL; + return; } /* --------------------------------------------------------------------- */ @@ -6680,69 +6376,12 @@ static void XGI_SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBI static void XGI_SetPanelPower(unsigned short tempah, unsigned short tempbl, struct vb_device_info *pVBInfo) { - if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x26, tempbl, tempah); - else - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x11, tempbl, tempah); -} - -static unsigned char XG21GPIODataTransfer(unsigned char ujDate) -{ - unsigned char ujRet = 0; - unsigned char i = 0; - - for (i = 0; i < 8; i++) { - ujRet = ujRet << 1; - /* ujRet |= GETBITS(ujDate >> i, 0:0); */ - ujRet |= (ujDate >> i) & 1; - } - - return ujRet; -} - -/*----------------------------------------------------------------------------*/ -/* output */ -/* bl[5] : LVDS signal */ -/* bl[1] : LVDS backlight */ -/* bl[0] : LVDS VDD */ -/*----------------------------------------------------------------------------*/ -static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo) -{ - unsigned char CR4A, temp; - - CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A); - XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x23); /* enable GPIO write */ - - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); - - temp = XG21GPIODataTransfer(temp); - temp &= 0x23; - XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A); - return temp; -} - -/*----------------------------------------------------------------------------*/ -/* output */ -/* bl[5] : LVDS signal */ -/* bl[1] : LVDS backlight */ -/* bl[0] : LVDS VDD */ -/*----------------------------------------------------------------------------*/ -static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo) -{ - unsigned char CR4A, CRB4, temp; - - CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A); - XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x0C); /* enable GPIO write */ - - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); - - temp &= 0x0C; - temp >>= 2; - XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A); - CRB4 = XGINew_GetReg1(pVBInfo->P3d4, 0xB4); - temp |= ((CRB4 & 0x04) << 3); - return temp; + if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) + XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x26, tempbl, tempah); + else + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x11, tempbl, tempah); } + /*----------------------------------------------------------------------------*/ /* input */ /* bl[5] : 1;LVDS signal on */ @@ -7386,453 +7025,575 @@ static unsigned char XGI_EnableChISLCD(struct vb_device_info *pVBInfo) if (tempah & 0x01) /* Chk LCDB Mode */ return 1; - return 0; + return 0; +} + +void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, + struct vb_device_info *pVBInfo) +{ + unsigned short tempax, tempbx, tempah = 0, tempbl = 0; + + if (pVBInfo->SetFlag == Win9xDOSMode) + return; + + if (HwDeviceExtension->jChipType < XG40) { + if ((!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) + || (XGI_DisableChISLCD(pVBInfo))) { + if (!XGI_IsLCDON(pVBInfo)) { + if (pVBInfo->LCDInfo & SetPWDEnable) + XGI_EnablePWD(pVBInfo); + else { + pVBInfo->LCDInfo &= ~SetPWDEnable; + XGI_DisablePWD(pVBInfo); + if (pVBInfo->VBType & (VB_XGI301LV + | VB_XGI302LV + | VB_XGI301C)) { + tempbx = 0xFE; /* not 01h */ + tempax = 0; + } else { + tempbx = 0xF7; /* not 08h */ + tempax = 0x08; + } + XGI_SetPanelPower(tempax, tempbx, + pVBInfo); + XGI_SetPanelDelay(3, pVBInfo); + } + } /* end if (!XGI_IsLCDON(pVBInfo)) */ + } + } + + /* + if (CH7017) { + if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2toLCDA)) || (XGI_DisableChISLCD(pVBInfo))) { + if (!XGI_IsLCDON(pVBInfo)) { + if (DISCHARGE) { + tempbx = XGINew_GetCH7005(0x61); + if (tempbx < 0x01) // first time we power up + XGINew_SetCH7005(0x0066); // and disable power sequence + else + XGINew_SetCH7005(0x5f66); // leave VDD on - disable power + } + } + } + } + */ + + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV + | VB_XGI302LV | VB_XGI301C)) { + tempah = 0x3F; + if (!(pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))) { + if (pVBInfo->VBInfo & SetCRT2ToLCDA) { + if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { + tempah = 0x7F; /* Disable Channel A */ + if (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) + tempah = 0xBF; /* Disable Channel B */ + + if (pVBInfo->SetFlag & DisableChB) + tempah &= 0xBF; /* force to disable Cahnnel */ + + if (pVBInfo->SetFlag & DisableChA) + tempah &= 0x7F; /* Force to disable Channel B */ + } + } + } + + XGINew_SetRegAND(pVBInfo->Part4Port, 0x1F, tempah); /* disable part4_1f */ + + if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) { + if (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) + || (XGI_DisableChISLCD(pVBInfo)) + || (XGI_IsLCDON(pVBInfo))) + XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x80); /* LVDS Driver power down */ + } + + if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo + & (DisableCRT2Display | SetCRT2ToLCDA + | SetSimuScanMode))) { + if (pVBInfo->SetFlag & GatingCRT) + XGI_EnableGatingCRT(HwDeviceExtension, pVBInfo); + XGI_DisplayOff(HwDeviceExtension, pVBInfo); + } + + if (pVBInfo->VBInfo & SetCRT2ToLCDA) { + if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo + & SetCRT2ToLCDA)) + XGINew_SetRegAND(pVBInfo->Part1Port, 0x1e, 0xdf); /* Power down */ + } + + XGINew_SetRegAND(pVBInfo->P3c4, 0x32, 0xdf); /* disable TV as primary VGA swap */ + + if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge))) + XGINew_SetRegAND(pVBInfo->Part2Port, 0x00, 0xdf); + + if ((pVBInfo->SetFlag & DisableChB) || (pVBInfo->VBInfo + & (DisableCRT2Display | SetSimuScanMode)) + || ((!(pVBInfo->VBInfo & SetCRT2ToLCDA)) + && (pVBInfo->VBInfo + & (SetCRT2ToRAMDAC + | SetCRT2ToLCD + | SetCRT2ToTV)))) + XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */ + + if ((pVBInfo->SetFlag & DisableChB) || (pVBInfo->VBInfo + & (DisableCRT2Display | SetSimuScanMode)) + || (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) + || (pVBInfo->VBInfo & (SetCRT2ToRAMDAC + | SetCRT2ToLCD | SetCRT2ToTV))) { + tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x00); /* save Part1 index 0 */ + XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x10); /* BTDAC = 1, avoid VB reset */ + XGINew_SetRegAND(pVBInfo->Part1Port, 0x1E, 0xDF); /* disable CRT2 */ + XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah); /* restore Part1 index 0 */ + } + } else { /* {301} */ + if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) { + XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */ + XGINew_SetRegAND(pVBInfo->Part1Port, 0x1E, 0xDF); /* Disable CRT2 */ + XGINew_SetRegAND(pVBInfo->P3c4, 0x32, 0xDF); /* Disable TV asPrimary VGA swap */ + } + + if (pVBInfo->VBInfo & (DisableCRT2Display | SetCRT2ToLCDA + | SetSimuScanMode)) + XGI_DisplayOff(HwDeviceExtension, pVBInfo); + } + + if (HwDeviceExtension->jChipType < XG40) { + if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) + || (XGI_DisableChISLCD(pVBInfo)) + || (XGI_IsLCDON(pVBInfo))) { + if (pVBInfo->LCDInfo & SetPWDEnable) { + if (pVBInfo->LCDInfo & SetPWDEnable) + XGI_BacklightByDrv(pVBInfo); + else { + XGI_SetPanelDelay(4, pVBInfo); + if (pVBInfo->VBType & VB_XGI301LV) { + tempbl = 0xFD; + tempah = 0x00; + } else { + tempbl = 0xFB; + tempah = 0x04; + } + } + } + XGI_SetPanelPower(tempah, tempbl, pVBInfo); + } + } +} + +/* --------------------------------------------------------------------- */ +/* Function : XGI_GetTVPtrIndex */ +/* Input : */ +/* Output : */ +/* Description : bx 0 : ExtNTSC */ +/* 1 : StNTSC */ +/* 2 : ExtPAL */ +/* 3 : StPAL */ +/* 4 : ExtHiTV */ +/* 5 : StHiTV */ +/* 6 : Ext525i */ +/* 7 : St525i */ +/* 8 : Ext525p */ +/* 9 : St525p */ +/* A : Ext750p */ +/* B : St750p */ +/* --------------------------------------------------------------------- */ +static unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo) +{ + unsigned short tempbx = 0; + + if (pVBInfo->TVInfo & SetPALTV) + tempbx = 2; + if (pVBInfo->TVInfo & SetYPbPrMode1080i) + tempbx = 4; + if (pVBInfo->TVInfo & SetYPbPrMode525i) + tempbx = 6; + if (pVBInfo->TVInfo & SetYPbPrMode525p) + tempbx = 8; + if (pVBInfo->TVInfo & SetYPbPrMode750p) + tempbx = 10; + if (pVBInfo->TVInfo & TVSimuMode) + tempbx++; + + return tempbx; +} + +/* --------------------------------------------------------------------- */ +/* Function : XGI_GetTVPtrIndex2 */ +/* Input : */ +/* Output : bx 0 : NTSC */ +/* 1 : PAL */ +/* 2 : PALM */ +/* 3 : PALN */ +/* 4 : NTSC1024x768 */ +/* 5 : PAL-M 1024x768 */ +/* 6-7: reserved */ +/* cl 0 : YFilter1 */ +/* 1 : YFilter2 */ +/* ch 0 : 301A */ +/* 1 : 301B/302B/301LV/302LV */ +/* Description : */ +/* --------------------------------------------------------------------- */ +static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl, + unsigned char *tempch, struct vb_device_info *pVBInfo) +{ + *tempbx = 0; + *tempcl = 0; + *tempch = 0; + + if (pVBInfo->TVInfo & SetPALTV) + *tempbx = 1; + + if (pVBInfo->TVInfo & SetPALMTV) + *tempbx = 2; + + if (pVBInfo->TVInfo & SetPALNTV) + *tempbx = 3; + + if (pVBInfo->TVInfo & NTSC1024x768) { + *tempbx = 4; + if (pVBInfo->TVInfo & SetPALMTV) + *tempbx = 5; + } + + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV + | VB_XGI302LV | VB_XGI301C)) { + if ((!(pVBInfo->VBInfo & SetInSlaveMode)) || (pVBInfo->TVInfo + & TVSimuMode)) { + *tempbx += 8; + *tempcl += 1; + } + } + + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV + | VB_XGI302LV | VB_XGI301C)) + (*tempch)++; } -static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo) +static void XGI_SetDelayComp(struct vb_device_info *pVBInfo) { - unsigned char tempal, tempah, tempbl, i; - - tempah = XGINew_GetReg1(pVBInfo->P3d4, 0x36); - tempal = tempah & 0x0F; - tempah = tempah & 0xF0; - i = 0; - tempbl = pVBInfo->LCDCapList[i].LCD_ID; + unsigned short index; - while (tempbl != 0xFF) { - if (tempbl & 0x80) { /* OEMUtil */ - tempal = tempah; - tempbl = tempbl & ~(0x80); - } + unsigned char tempah, tempbl, tempbh; - if (tempal == tempbl) - break; + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV + | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA + | SetCRT2ToTV | SetCRT2ToRAMDAC)) { + tempbl = 0; + tempbh = 0; - i++; + index = XGI_GetTVPtrIndex(pVBInfo); /* Get TV Delay */ + tempbl = pVBInfo->XGI_TVDelayList[index]; - tempbl = pVBInfo->LCDCapList[i].LCD_ID; - } + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B + | VB_XGI301LV | VB_XGI302LV + | VB_XGI301C)) + tempbl = pVBInfo->XGI_TVDelayList2[index]; - return i; -} + if (pVBInfo->VBInfo & SetCRT2ToDualEdge) + tempbl = tempbl >> 4; + /* + if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) + tempbl = CRT2Delay1; // Get CRT2 Delay + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) + tempbl = CRT2Delay2; + */ + if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + index = XGI_GetLCDCapPtr(pVBInfo); /* Get LCD Delay */ + tempbh = pVBInfo->LCDCapList[index].LCD_DelayCompensation; -static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo) -{ - unsigned short tempah, tempal, tempbl, i; + if (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) + tempbl = tempbh; + } - tempal = pVBInfo->LCDResInfo; - tempah = pVBInfo->LCDTypeInfo; + tempbl &= 0x0F; + tempbh &= 0xF0; + tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x2D); - i = 0; - tempbl = pVBInfo->LCDCapList[i].LCD_ID; + if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD + | SetCRT2ToTV)) { /* Channel B */ + tempah &= 0xF0; + tempah |= tempbl; + } - while (tempbl != 0xFF) { - if ((tempbl & 0x80) && (tempbl != 0x80)) { - tempal = tempah; - tempbl &= ~0x80; + if (pVBInfo->VBInfo & SetCRT2ToLCDA) { /* Channel A */ + tempah &= 0x0F; + tempah |= tempbh; + } + XGINew_SetReg1(pVBInfo->Part1Port, 0x2D, tempah); + } + } else if (pVBInfo->IF_DEF_LVDS == 1) { + tempbl = 0; + tempbh = 0; + if (pVBInfo->VBInfo & SetCRT2ToLCD) { + tempah + = pVBInfo->LCDCapList[XGI_GetLCDCapPtr( + pVBInfo)].LCD_DelayCompensation; /* / Get LCD Delay */ + tempah &= 0x0f; + tempah = tempah << 4; + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2D, 0x0f, + tempah); } + } +} - if (tempal == tempbl) - break; +static void XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInfo) +{ + unsigned short temp; - i++; - tempbl = pVBInfo->LCDCapList[i].LCD_ID; + temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); + + if (temp & LCDRGB18Bit) { + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, + (unsigned short) (0x20 | (tempcx & 0x00C0))); /* Enable Dither */ + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80); + } else { + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, + (unsigned short) (0x30 | (tempcx & 0x00C0))); + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00); } - if (tempbl == 0xFF) { - pVBInfo->LCDResInfo = Panel1024x768; - pVBInfo->LCDTypeInfo = 0; - i = 0; + /* + if (tempcx & EnableLCD24bpp) { // 24bits + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short)(0x30 | (tempcx&0x00C0))); + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00); + } else { + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short)(0x20 | (tempcx&0x00C0))); // Enable Dither + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80); } + */ +} - return i; +/* --------------------------------------------------------------------- */ +/* Function : XGI_SetLCDCap_B */ +/* Input : cx -> LCD Capability */ +/* Output : */ +/* Description : */ +/* --------------------------------------------------------------------- */ +static void XGI_SetLCDCap_B(unsigned short tempcx, struct vb_device_info *pVBInfo) +{ + if (tempcx & EnableLCD24bpp) /* 24bits */ + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1A, 0xE0, + (unsigned short) (((tempcx & 0x00ff) >> 6) + | 0x0c)); + else + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1A, 0xE0, + (unsigned short) (((tempcx & 0x00ff) >> 6) + | 0x18)); /* Enable Dither */ } -static void XGI_GetLCDSync(unsigned short *HSyncWidth, unsigned short *VSyncWidth, - struct vb_device_info *pVBInfo) +static void SetSpectrum(struct vb_device_info *pVBInfo) { - unsigned short Index; + unsigned short index; - Index = XGI_GetLCDCapPtr(pVBInfo); - *HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth; - *VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth; + index = XGI_GetLCDCapPtr(pVBInfo); - return; + XGINew_SetRegAND(pVBInfo->Part4Port, 0x30, 0x8F); /* disable down spectrum D[4] */ + XGI_LongWait(pVBInfo); + XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */ + XGI_LongWait(pVBInfo); + + XGINew_SetReg1(pVBInfo->Part4Port, 0x31, + pVBInfo->LCDCapList[index].Spectrum_31); + XGINew_SetReg1(pVBInfo->Part4Port, 0x32, + pVBInfo->LCDCapList[index].Spectrum_32); + XGINew_SetReg1(pVBInfo->Part4Port, 0x33, + pVBInfo->LCDCapList[index].Spectrum_33); + XGINew_SetReg1(pVBInfo->Part4Port, 0x34, + pVBInfo->LCDCapList[index].Spectrum_34); + XGI_LongWait(pVBInfo); + XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */ } -void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) +static void XGI_SetLCDCap(struct vb_device_info *pVBInfo) { - unsigned short tempbl, tempah; - - if (pVBInfo->SetFlag == Win9xDOSMode) { - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { - XGI_DisplayOn(HwDeviceExtension, pVBInfo); - return; - } else - /* LVDS or CH7017 */ - return; - } - - if (HwDeviceExtension->jChipType < XG40) { - if (!XGI_DisableChISLCD(pVBInfo)) { - if ((XGI_EnableChISLCD(pVBInfo)) || (pVBInfo->VBInfo - & (SetCRT2ToLCD | SetCRT2ToLCDA))) { - if (pVBInfo->LCDInfo & SetPWDEnable) { - XGI_EnablePWD(pVBInfo); - } else { - pVBInfo->LCDInfo &= (~SetPWDEnable); - if (pVBInfo->VBType & (VB_XGI301LV - | VB_XGI302LV - | VB_XGI301C)) { - tempbl = 0xFD; - tempah = 0x02; - } else { - tempbl = 0xFB; - tempah = 0x00; - } + unsigned short tempcx; - XGI_SetPanelPower(tempah, tempbl, - pVBInfo); - XGI_SetPanelDelay(1, pVBInfo); - } - } - } - } /* Not 340 */ + tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability; if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { - if (!(pVBInfo->SetFlag & DisableChA)) { - if (pVBInfo->SetFlag & EnableChA) { - XGINew_SetReg1(pVBInfo->Part1Port, 0x1E, 0x20); /* Power on */ - } else { - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { /* SetCRT2ToLCDA ) */ - XGINew_SetReg1(pVBInfo->Part1Port, - 0x1E, 0x20); /* Power on */ - } - } - } - - if (!(pVBInfo->SetFlag & DisableChB)) { - if ((pVBInfo->SetFlag & EnableChB) || (pVBInfo->VBInfo - & (SetCRT2ToLCD | SetCRT2ToTV - | SetCRT2ToRAMDAC))) { - tempah = (unsigned char) XGINew_GetReg1( - pVBInfo->P3c4, 0x32); - tempah &= 0xDF; - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) - tempah |= 0x20; - } - XGINew_SetReg1(pVBInfo->P3c4, 0x32, tempah); - XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x20); - - tempah = (unsigned char) XGINew_GetReg1( - pVBInfo->Part1Port, 0x2E); - - if (!(tempah & 0x80)) - XGINew_SetRegOR(pVBInfo->Part1Port, - 0x2E, 0x80); /* BVBDOENABLE = 1 */ - - XGINew_SetRegAND(pVBInfo->Part1Port, 0x00, 0x7F); /* BScreenOFF = 0 */ - } - } - - if ((pVBInfo->SetFlag & (EnableChA | EnableChB)) - || (!(pVBInfo->VBInfo & DisableCRT2Display))) { - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x00, ~0xE0, - 0x20); /* shampoo 0129 */ - if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) { - if (!XGI_DisableChISLCD(pVBInfo)) { - if (XGI_EnableChISLCD(pVBInfo) - || (pVBInfo->VBInfo - & (SetCRT2ToLCD - | SetCRT2ToLCDA))) - XGINew_SetRegAND( - pVBInfo->Part4Port, - 0x2A, 0x7F); /* LVDS PLL power on */ - } - XGINew_SetRegAND(pVBInfo->Part4Port, 0x30, 0x7F); /* LVDS Driver power on */ - } + if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { /* 301LV/302LV only */ + /* Set 301LV Capability */ + XGINew_SetReg1(pVBInfo->Part4Port, 0x24, + (unsigned char) (tempcx & 0x1F)); } + /* VB Driving */ + XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0D, + ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8), + (unsigned short) ((tempcx & (EnableVBCLKDRVLOW + | EnablePLLSPLOW)) >> 8)); + } - tempah = 0x00; - - if (!(pVBInfo->VBInfo & DisableCRT2Display)) { - tempah = 0xc0; + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV + | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBInfo & SetCRT2ToLCD) + XGI_SetLCDCap_B(tempcx, pVBInfo); + else if (pVBInfo->VBInfo & SetCRT2ToLCDA) + XGI_SetLCDCap_A(tempcx, pVBInfo); - if (!(pVBInfo->VBInfo & SetSimuScanMode)) { - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { - tempah = tempah & 0x40; - if (pVBInfo->VBInfo - & SetCRT2ToLCDA) - tempah = tempah ^ 0xC0; + if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) { + if (tempcx & EnableSpectrum) + SetSpectrum(pVBInfo); + } + } else { + /* LVDS,CH7017 */ + XGI_SetLCDCap_A(tempcx, pVBInfo); + } +} - if (pVBInfo->SetFlag - & DisableChB) - tempah &= 0xBF; +/* --------------------------------------------------------------------- */ +/* Function : XGI_SetAntiFlicker */ +/* Input : */ +/* Output : */ +/* Description : Set TV Customized Param. */ +/* --------------------------------------------------------------------- */ +static void XGI_SetAntiFlicker(unsigned short ModeNo, unsigned short ModeIdIndex, + struct vb_device_info *pVBInfo) +{ + unsigned short tempbx, index; - if (pVBInfo->SetFlag - & DisableChA) - tempah &= 0x7F; + unsigned char tempah; - if (pVBInfo->SetFlag - & EnableChB) - tempah |= 0x40; + if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)) + return; - if (pVBInfo->SetFlag - & EnableChA) - tempah |= 0x80; - } - } - } - } + tempbx = XGI_GetTVPtrIndex(pVBInfo); + tempbx &= 0xFE; - XGINew_SetRegOR(pVBInfo->Part4Port, 0x1F, tempah); /* EnablePart4_1F */ + if (ModeNo <= 0x13) + index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex; + else + index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex; - if (pVBInfo->SetFlag & Win9xDOSMode) { - XGI_DisplayOn(HwDeviceExtension, pVBInfo); - return; - } + tempbx += index; + tempah = TVAntiFlickList[tempbx]; + tempah = tempah << 4; - if (!(pVBInfo->SetFlag & DisableChA)) { - XGI_VBLongWait(pVBInfo); - if (!(pVBInfo->SetFlag & GatingCRT)) { - XGI_DisableGatingCRT(HwDeviceExtension, pVBInfo); - XGI_DisplayOn(HwDeviceExtension, pVBInfo); - XGI_VBLongWait(pVBInfo); - } - } - } /* 301 */ - else { /* LVDS */ - if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD - | SetCRT2ToLCDA)) - XGINew_SetRegOR(pVBInfo->Part1Port, 0x1E, 0x20); /* enable CRT2 */ + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0x8F, tempah); +} - tempah = (unsigned char) XGINew_GetReg1(pVBInfo->Part1Port, - 0x2E); - if (!(tempah & 0x80)) - XGINew_SetRegOR(pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */ +static void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex, + struct vb_device_info *pVBInfo) +{ + unsigned short tempbx, index; - XGINew_SetRegAND(pVBInfo->Part1Port, 0x00, 0x7F); - XGI_DisplayOn(HwDeviceExtension, pVBInfo); - } /* End of VB */ + unsigned char tempah; - if (HwDeviceExtension->jChipType < XG40) { - if (!XGI_EnableChISLCD(pVBInfo)) { - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { - if (XGI_BacklightByDrv(pVBInfo)) - return; - } else - return; - } + tempbx = XGI_GetTVPtrIndex(pVBInfo); + tempbx &= 0xFE; - if (pVBInfo->LCDInfo & SetPWDEnable) { - XGI_FirePWDEnable(pVBInfo); - return; - } + if (ModeNo <= 0x13) + index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex; + else + index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex; - XGI_SetPanelDelay(2, pVBInfo); + tempbx += index; + tempah = TVEdgeList[tempbx]; + tempah = tempah << 5; - if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { - tempah = 0x01; - tempbl = 0xFE; /* turn on backlght */ - } else { - tempbl = 0xF7; - tempah = 0x00; - } - XGI_SetPanelPower(tempah, tempbl, pVBInfo); - } + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x3A, 0x1F, tempah); } -void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) +static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo) { - unsigned short tempax, tempbx, tempah = 0, tempbl = 0; + unsigned short tempbx; - if (pVBInfo->SetFlag == Win9xDOSMode) - return; + unsigned char tempcl, tempch; - if (HwDeviceExtension->jChipType < XG40) { - if ((!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) - || (XGI_DisableChISLCD(pVBInfo))) { - if (!XGI_IsLCDON(pVBInfo)) { - if (pVBInfo->LCDInfo & SetPWDEnable) - XGI_EnablePWD(pVBInfo); - else { - pVBInfo->LCDInfo &= ~SetPWDEnable; - XGI_DisablePWD(pVBInfo); - if (pVBInfo->VBType & (VB_XGI301LV - | VB_XGI302LV - | VB_XGI301C)) { - tempbx = 0xFE; /* not 01h */ - tempax = 0; - } else { - tempbx = 0xF7; /* not 08h */ - tempax = 0x08; - } - XGI_SetPanelPower(tempax, tempbx, - pVBInfo); - XGI_SetPanelDelay(3, pVBInfo); - } - } /* end if (!XGI_IsLCDON(pVBInfo)) */ - } - } + unsigned long tempData; - /* - if (CH7017) { - if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2toLCDA)) || (XGI_DisableChISLCD(pVBInfo))) { - if (!XGI_IsLCDON(pVBInfo)) { - if (DISCHARGE) { - tempbx = XGINew_GetCH7005(0x61); - if (tempbx < 0x01) // first time we power up - XGINew_SetCH7005(0x0066); // and disable power sequence - else - XGINew_SetCH7005(0x5f66); // leave VDD on - disable power - } - } - } - } - */ + XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */ + tempData = TVPhaseList[tempbx]; - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { - tempah = 0x3F; - if (!(pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))) { - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { - tempah = 0x7F; /* Disable Channel A */ - if (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) - tempah = 0xBF; /* Disable Channel B */ + XGINew_SetReg1(pVBInfo->Part2Port, 0x31, (unsigned short) (tempData + & 0x000000FF)); + XGINew_SetReg1(pVBInfo->Part2Port, 0x32, (unsigned short) ((tempData + & 0x0000FF00) >> 8)); + XGINew_SetReg1(pVBInfo->Part2Port, 0x33, (unsigned short) ((tempData + & 0x00FF0000) >> 16)); + XGINew_SetReg1(pVBInfo->Part2Port, 0x34, (unsigned short) ((tempData + & 0xFF000000) >> 24)); +} - if (pVBInfo->SetFlag & DisableChB) - tempah &= 0xBF; /* force to disable Cahnnel */ +static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex, + struct vb_device_info *pVBInfo) +{ + unsigned short tempbx, index; - if (pVBInfo->SetFlag & DisableChA) - tempah &= 0x7F; /* Force to disable Channel B */ - } - } - } + unsigned char tempcl, tempch, tempal, *filterPtr; - XGINew_SetRegAND(pVBInfo->Part4Port, 0x1F, tempah); /* disable part4_1f */ + XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */ - if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) { - if (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) - || (XGI_DisableChISLCD(pVBInfo)) - || (XGI_IsLCDON(pVBInfo))) - XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x80); /* LVDS Driver power down */ - } + switch (tempbx) { + case 0x00: + case 0x04: + filterPtr = NTSCYFilter1; + break; - if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo - & (DisableCRT2Display | SetCRT2ToLCDA - | SetSimuScanMode))) { - if (pVBInfo->SetFlag & GatingCRT) - XGI_EnableGatingCRT(HwDeviceExtension, pVBInfo); - XGI_DisplayOff(HwDeviceExtension, pVBInfo); - } + case 0x01: + filterPtr = PALYFilter1; + break; - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { - if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo - & SetCRT2ToLCDA)) - XGINew_SetRegAND(pVBInfo->Part1Port, 0x1e, 0xdf); /* Power down */ - } + case 0x02: + case 0x05: + case 0x0D: + filterPtr = PALMYFilter1; + break; + + case 0x03: + filterPtr = PALNYFilter1; + break; - XGINew_SetRegAND(pVBInfo->P3c4, 0x32, 0xdf); /* disable TV as primary VGA swap */ + case 0x08: + case 0x0C: + filterPtr = NTSCYFilter2; + break; - if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge))) - XGINew_SetRegAND(pVBInfo->Part2Port, 0x00, 0xdf); + case 0x0A: + filterPtr = PALMYFilter2; + break; - if ((pVBInfo->SetFlag & DisableChB) || (pVBInfo->VBInfo - & (DisableCRT2Display | SetSimuScanMode)) - || ((!(pVBInfo->VBInfo & SetCRT2ToLCDA)) - && (pVBInfo->VBInfo - & (SetCRT2ToRAMDAC - | SetCRT2ToLCD - | SetCRT2ToTV)))) - XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */ + case 0x0B: + filterPtr = PALNYFilter2; + break; - if ((pVBInfo->SetFlag & DisableChB) || (pVBInfo->VBInfo - & (DisableCRT2Display | SetSimuScanMode)) - || (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) - || (pVBInfo->VBInfo & (SetCRT2ToRAMDAC - | SetCRT2ToLCD | SetCRT2ToTV))) { - tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x00); /* save Part1 index 0 */ - XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x10); /* BTDAC = 1, avoid VB reset */ - XGINew_SetRegAND(pVBInfo->Part1Port, 0x1E, 0xDF); /* disable CRT2 */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah); /* restore Part1 index 0 */ - } - } else { /* {301} */ - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) { - XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */ - XGINew_SetRegAND(pVBInfo->Part1Port, 0x1E, 0xDF); /* Disable CRT2 */ - XGINew_SetRegAND(pVBInfo->P3c4, 0x32, 0xDF); /* Disable TV asPrimary VGA swap */ - } + case 0x09: + filterPtr = PALYFilter2; + break; - if (pVBInfo->VBInfo & (DisableCRT2Display | SetCRT2ToLCDA - | SetSimuScanMode)) - XGI_DisplayOff(HwDeviceExtension, pVBInfo); + default: + return; } - if (HwDeviceExtension->jChipType < XG40) { - if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) - || (XGI_DisableChISLCD(pVBInfo)) - || (XGI_IsLCDON(pVBInfo))) { - if (pVBInfo->LCDInfo & SetPWDEnable) { - if (pVBInfo->LCDInfo & SetPWDEnable) - XGI_BacklightByDrv(pVBInfo); - else { - XGI_SetPanelDelay(4, pVBInfo); - if (pVBInfo->VBType & VB_XGI301LV) { - tempbl = 0xFD; - tempah = 0x00; - } else { - tempbl = 0xFB; - tempah = 0x04; - } - } - } - XGI_SetPanelPower(tempah, tempbl, pVBInfo); - } - } -} + if (ModeNo <= 0x13) + tempal = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex; + else + tempal + = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex; -/* --------------------------------------------------------------------- */ -/* Function : XGI_GetTVPtrIndex */ -/* Input : */ -/* Output : */ -/* Description : bx 0 : ExtNTSC */ -/* 1 : StNTSC */ -/* 2 : ExtPAL */ -/* 3 : StPAL */ -/* 4 : ExtHiTV */ -/* 5 : StHiTV */ -/* 6 : Ext525i */ -/* 7 : St525i */ -/* 8 : Ext525p */ -/* 9 : St525p */ -/* A : Ext750p */ -/* B : St750p */ -/* --------------------------------------------------------------------- */ -static unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo) -{ - unsigned short tempbx = 0; + if (tempcl == 0) + index = tempal * 4; + else + index = tempal * 7; - if (pVBInfo->TVInfo & SetPALTV) - tempbx = 2; - if (pVBInfo->TVInfo & SetYPbPrMode1080i) - tempbx = 4; - if (pVBInfo->TVInfo & SetYPbPrMode525i) - tempbx = 6; - if (pVBInfo->TVInfo & SetYPbPrMode525p) - tempbx = 8; - if (pVBInfo->TVInfo & SetYPbPrMode750p) - tempbx = 10; - if (pVBInfo->TVInfo & TVSimuMode) - tempbx++; + if ((tempcl == 0) && (tempch == 1)) { + XGINew_SetReg1(pVBInfo->Part2Port, 0x35, 0); + XGINew_SetReg1(pVBInfo->Part2Port, 0x36, 0); + XGINew_SetReg1(pVBInfo->Part2Port, 0x37, 0); + XGINew_SetReg1(pVBInfo->Part2Port, 0x38, filterPtr[index++]); + } else { + XGINew_SetReg1(pVBInfo->Part2Port, 0x35, filterPtr[index++]); + XGINew_SetReg1(pVBInfo->Part2Port, 0x36, filterPtr[index++]); + XGINew_SetReg1(pVBInfo->Part2Port, 0x37, filterPtr[index++]); + XGINew_SetReg1(pVBInfo->Part2Port, 0x38, filterPtr[index++]); + } - return tempbx; + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV + | VB_XGI302LV | VB_XGI301C)) { + XGINew_SetReg1(pVBInfo->Part2Port, 0x48, filterPtr[index++]); + XGINew_SetReg1(pVBInfo->Part2Port, 0x49, filterPtr[index++]); + XGINew_SetReg1(pVBInfo->Part2Port, 0x4A, filterPtr[index++]); + } } /* --------------------------------------------------------------------- */ @@ -7864,962 +7625,1088 @@ static void XGI_OEM310Setting(unsigned short ModeNo, unsigned short ModeIdIndex, } } -static void XGI_SetDelayComp(struct vb_device_info *pVBInfo) +/* --------------------------------------------------------------------- */ +/* Function : XGI_SetCRT2ModeRegs */ +/* Input : */ +/* Output : */ +/* Description : Origin code for crt2group */ +/* --------------------------------------------------------------------- */ +void XGI_SetCRT2ModeRegs(unsigned short ModeNo, + struct xgi_hw_device_info *HwDeviceExtension, + struct vb_device_info *pVBInfo) { - unsigned short index; - - unsigned char tempah, tempbl, tempbh; + unsigned short tempbl; + short tempcl; - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA - | SetCRT2ToTV | SetCRT2ToRAMDAC)) { - tempbl = 0; - tempbh = 0; + unsigned char tempah; - index = XGI_GetTVPtrIndex(pVBInfo); /* Get TV Delay */ - tempbl = pVBInfo->XGI_TVDelayList[index]; + /* XGINew_SetReg1(pVBInfo->Part1Port, 0x03, 0x00); // fix write part1 index 0 BTDRAM bit Bug */ + tempah = 0; + if (!(pVBInfo->VBInfo & DisableCRT2Display)) { + tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x00); + tempah &= ~0x10; /* BTRAMDAC */ + tempah |= 0x40; /* BTRAM */ - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B - | VB_XGI301LV | VB_XGI302LV - | VB_XGI301C)) - tempbl = pVBInfo->XGI_TVDelayList2[index]; + if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV + | SetCRT2ToLCD)) { + tempah = 0x40; /* BTDRAM */ + if (ModeNo > 0x13) { + tempcl = pVBInfo->ModeType; + tempcl -= ModeVGA; + if (tempcl >= 0) { + tempah = (0x008 >> tempcl); /* BT Color */ + if (tempah == 0) + tempah = 1; + tempah |= 0x040; + } + } + if (pVBInfo->VBInfo & SetInSlaveMode) + tempah ^= 0x50; /* BTDAC */ + } + } - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) - tempbl = tempbl >> 4; - /* - if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) - tempbl = CRT2Delay1; // Get CRT2 Delay - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) - tempbl = CRT2Delay2; - */ - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { - index = XGI_GetLCDCapPtr(pVBInfo); /* Get LCD Delay */ - tempbh = pVBInfo->LCDCapList[index].LCD_DelayCompensation; + /* 0210 shampoo + if (pVBInfo->VBInfo & DisableCRT2Display) { + tempah = 0; + } - if (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) - tempbl = tempbh; + XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah); + if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)) { + tempcl = pVBInfo->ModeType; + if (ModeNo > 0x13) { + tempcl -= ModeVGA; + if ((tempcl > 0) || (tempcl == 0)) { + tempah=(0x008>>tempcl) ; + if (tempah == 0) + tempah = 1; + tempah |= 0x040; } + } else { + tempah = 0x040; + } - tempbl &= 0x0F; - tempbh &= 0xF0; - tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x2D); + if (pVBInfo->VBInfo & SetInSlaveMode) { + tempah = (tempah ^ 0x050); + } + } + */ - if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD - | SetCRT2ToTV)) { /* Channel B */ - tempah &= 0xF0; - tempah |= tempbl; - } + XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah); + tempah = 0x08; + tempbl = 0xf0; + + if (pVBInfo->VBInfo & DisableCRT2Display) { + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e, tempbl, tempah); + } else { + tempah = 0x00; + tempbl = 0xff; + + if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV + | SetCRT2ToLCD | SetCRT2ToLCDA)) { + if ((pVBInfo->VBInfo & SetCRT2ToLCDA) + && (!(pVBInfo->VBInfo & SetSimuScanMode))) { + tempbl &= 0xf7; + tempah |= 0x01; + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e, + tempbl, tempah); + } else { + if (pVBInfo->VBInfo & SetCRT2ToLCDA) { + tempbl &= 0xf7; + tempah |= 0x01; + } + + if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC + | SetCRT2ToTV | SetCRT2ToLCD)) { + tempbl &= 0xf8; + tempah = 0x01; + + if (!(pVBInfo->VBInfo & SetInSlaveMode)) + tempah |= 0x02; + + if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) { + tempah = tempah ^ 0x05; + if (!(pVBInfo->VBInfo + & SetCRT2ToLCD)) + tempah = tempah ^ 0x01; + } - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { /* Channel A */ - tempah &= 0x0F; - tempah |= tempbh; + if (!(pVBInfo->VBInfo + & SetCRT2ToDualEdge)) + tempah |= 0x08; + XGINew_SetRegANDOR(pVBInfo->Part1Port, + 0x2e, tempbl, tempah); + } else { + XGINew_SetRegANDOR(pVBInfo->Part1Port, + 0x2e, tempbl, tempah); + } } - XGINew_SetReg1(pVBInfo->Part1Port, 0x2D, tempah); - } - } else if (pVBInfo->IF_DEF_LVDS == 1) { - tempbl = 0; - tempbh = 0; - if (pVBInfo->VBInfo & SetCRT2ToLCD) { - tempah - = pVBInfo->LCDCapList[XGI_GetLCDCapPtr( - pVBInfo)].LCD_DelayCompensation; /* / Get LCD Delay */ - tempah &= 0x0f; - tempah = tempah << 4; - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2D, 0x0f, + } else { + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e, tempbl, tempah); } } -} -static void XGI_SetLCDCap(struct vb_device_info *pVBInfo) -{ - unsigned short tempcx; + if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD + | SetCRT2ToLCDA)) { + tempah &= (~0x08); + if ((pVBInfo->ModeType == ModeVGA) && (!(pVBInfo->VBInfo + & SetInSlaveMode))) { + tempah |= 0x010; + } + tempah |= 0x080; - tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability; + if (pVBInfo->VBInfo & SetCRT2ToTV) { + /* if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) { */ + tempah |= 0x020; + if (ModeNo > 0x13) { + if (pVBInfo->VBInfo & DriverMode) + tempah = tempah ^ 0x20; + } + /* } */ + } - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { - if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { /* 301LV/302LV only */ - /* Set 301LV Capability */ - XGINew_SetReg1(pVBInfo->Part4Port, 0x24, - (unsigned char) (tempcx & 0x1F)); + XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah); + tempah = 0; + + if (pVBInfo->LCDInfo & SetLCDDualLink) + tempah |= 0x40; + + if (pVBInfo->VBInfo & SetCRT2ToTV) { + /* if ((!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) && (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)))) { */ + if (pVBInfo->TVInfo & RPLLDIV2XO) + tempah |= 0x40; + /* } */ } - /* VB Driving */ - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0D, - ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8), - (unsigned short) ((tempcx & (EnableVBCLKDRVLOW - | EnablePLLSPLOW)) >> 8)); + + if ((pVBInfo->LCDResInfo == Panel1280x1024) + || (pVBInfo->LCDResInfo == Panel1280x1024x75)) + tempah |= 0x80; + + if (pVBInfo->LCDResInfo == Panel1280x960) + tempah |= 0x80; + + XGINew_SetReg1(pVBInfo->Part4Port, 0x0C, tempah); } if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { - if (pVBInfo->VBInfo & SetCRT2ToLCD) - XGI_SetLCDCap_B(tempcx, pVBInfo); - else if (pVBInfo->VBInfo & SetCRT2ToLCDA) - XGI_SetLCDCap_A(tempcx, pVBInfo); + tempah = 0; + tempbl = 0xfb; - if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) { - if (tempcx & EnableSpectrum) - SetSpectrum(pVBInfo); + if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { + tempbl = 0xff; + if (pVBInfo->VBInfo & SetCRT2ToLCDA) + tempah |= 0x04; /* shampoo 0129 */ } - } else { - /* LVDS,CH7017 */ - XGI_SetLCDCap_A(tempcx, pVBInfo); - } -} -static void XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInfo) -{ - unsigned short temp; + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x13, tempbl, tempah); + tempah = 0x00; + tempbl = 0xcf; + if (!(pVBInfo->VBInfo & DisableCRT2Display)) { + if (pVBInfo->VBInfo & SetCRT2ToDualEdge) + tempah |= 0x30; + } - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2c, tempbl, tempah); + tempah = 0; + tempbl = 0x3f; - if (temp & LCDRGB18Bit) { - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, - (unsigned short) (0x20 | (tempcx & 0x00C0))); /* Enable Dither */ - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80); - } else { - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, - (unsigned short) (0x30 | (tempcx & 0x00C0))); - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00); + if (!(pVBInfo->VBInfo & DisableCRT2Display)) { + if (pVBInfo->VBInfo & SetCRT2ToDualEdge) + tempah |= 0xc0; + } + XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x21, tempbl, tempah); } - /* - if (tempcx & EnableLCD24bpp) { // 24bits - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short)(0x30 | (tempcx&0x00C0))); - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00); - } else { - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short)(0x20 | (tempcx&0x00C0))); // Enable Dither - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80); + tempah = 0; + tempbl = 0x7f; + if (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) { + tempbl = 0xff; + if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge)) + tempah |= 0x80; } - */ -} - -/* --------------------------------------------------------------------- */ -/* Function : XGI_SetLCDCap_B */ -/* Input : cx -> LCD Capability */ -/* Output : */ -/* Description : */ -/* --------------------------------------------------------------------- */ -static void XGI_SetLCDCap_B(unsigned short tempcx, struct vb_device_info *pVBInfo) -{ - if (tempcx & EnableLCD24bpp) /* 24bits */ - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1A, 0xE0, - (unsigned short) (((tempcx & 0x00ff) >> 6) - | 0x0c)); - else - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1A, 0xE0, - (unsigned short) (((tempcx & 0x00ff) >> 6) - | 0x18)); /* Enable Dither */ -} - -static void SetSpectrum(struct vb_device_info *pVBInfo) -{ - unsigned short index; - - index = XGI_GetLCDCapPtr(pVBInfo); - XGINew_SetRegAND(pVBInfo->Part4Port, 0x30, 0x8F); /* disable down spectrum D[4] */ - XGI_LongWait(pVBInfo); - XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */ - XGI_LongWait(pVBInfo); + XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x23, tempbl, tempah); - XGINew_SetReg1(pVBInfo->Part4Port, 0x31, - pVBInfo->LCDCapList[index].Spectrum_31); - XGINew_SetReg1(pVBInfo->Part4Port, 0x32, - pVBInfo->LCDCapList[index].Spectrum_32); - XGINew_SetReg1(pVBInfo->Part4Port, 0x33, - pVBInfo->LCDCapList[index].Spectrum_33); - XGINew_SetReg1(pVBInfo->Part4Port, 0x34, - pVBInfo->LCDCapList[index].Spectrum_34); - XGI_LongWait(pVBInfo); - XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */ + if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->LCDInfo & SetLCDDualLink) { + XGINew_SetRegOR(pVBInfo->Part4Port, 0x27, 0x20); + XGINew_SetRegOR(pVBInfo->Part4Port, 0x34, 0x10); + } + } } -/* --------------------------------------------------------------------- */ -/* Function : XGI_SetAntiFlicker */ -/* Input : */ -/* Output : */ -/* Description : Set TV Customized Param. */ -/* --------------------------------------------------------------------- */ -static void XGI_SetAntiFlicker(unsigned short ModeNo, unsigned short ModeIdIndex, +static void XGI_CloseCRTC(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - unsigned short tempbx, index; - - unsigned char tempah; - - if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)) - return; - - tempbx = XGI_GetTVPtrIndex(pVBInfo); - tempbx &= 0xFE; + unsigned short tempbx; - if (ModeNo <= 0x13) - index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex; - else - index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex; + tempbx = 0; - tempbx += index; - tempah = TVAntiFlickList[tempbx]; - tempah = tempah << 4; + if (pVBInfo->VBInfo & SetCRT2ToLCDA) + tempbx = 0x08A0; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0x8F, tempah); } -static void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex, +void XGI_OpenCRTC(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - unsigned short tempbx, index; - - unsigned char tempah; - - tempbx = XGI_GetTVPtrIndex(pVBInfo); - tempbx &= 0xFE; - - if (ModeNo <= 0x13) - index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex; - else - index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex; - - tempbx += index; - tempah = TVEdgeList[tempbx]; - tempah = tempah << 5; - - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x3A, 0x1F, tempah); + unsigned short tempbx; + tempbx = 0; } -static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo) +void XGI_UnLockCRT2(struct xgi_hw_device_info *HwDeviceExtension, + struct vb_device_info *pVBInfo) { - unsigned short tempbx; - unsigned char tempcl, tempch; - - unsigned long tempData; - - XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */ - tempData = TVPhaseList[tempbx]; - - XGINew_SetReg1(pVBInfo->Part2Port, 0x31, (unsigned short) (tempData - & 0x000000FF)); - XGINew_SetReg1(pVBInfo->Part2Port, 0x32, (unsigned short) ((tempData - & 0x0000FF00) >> 8)); - XGINew_SetReg1(pVBInfo->Part2Port, 0x33, (unsigned short) ((tempData - & 0x00FF0000) >> 16)); - XGINew_SetReg1(pVBInfo->Part2Port, 0x34, (unsigned short) ((tempData - & 0xFF000000) >> 24)); + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2f, 0xFF, 0x01); + } -static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex, +void XGI_LockCRT2(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - unsigned short tempbx, index; - unsigned char tempcl, tempch, tempal, *filterPtr; + XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2F, 0xFE, 0x00); - XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */ +} - switch (tempbx) { - case 0x00: - case 0x04: - filterPtr = NTSCYFilter1; - break; +unsigned char XGI_BridgeIsOn(struct vb_device_info *pVBInfo) +{ + unsigned short flag; - case 0x01: - filterPtr = PALYFilter1; - break; + if (pVBInfo->IF_DEF_LVDS == 1) { + return 1; + } else { + flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x00); + if ((flag == 1) || (flag == 2)) + return 1; /* 301b */ + else + return 0; + } +} - case 0x02: - case 0x05: - case 0x0D: - filterPtr = PALMYFilter1; - break; +void XGI_LongWait(struct vb_device_info *pVBInfo) +{ + unsigned short i; - case 0x03: - filterPtr = PALNYFilter1; - break; + i = XGINew_GetReg1(pVBInfo->P3c4, 0x1F); - case 0x08: - case 0x0C: - filterPtr = NTSCYFilter2; - break; + if (!(i & 0xC0)) { + for (i = 0; i < 0xFFFF; i++) { + if (!(XGINew_GetReg2(pVBInfo->P3da) & 0x08)) + break; + } - case 0x0A: - filterPtr = PALMYFilter2; - break; + for (i = 0; i < 0xFFFF; i++) { + if ((XGINew_GetReg2(pVBInfo->P3da) & 0x08)) + break; + } + } +} - case 0x0B: - filterPtr = PALNYFilter2; - break; +static void XGI_VBLongWait(struct vb_device_info *pVBInfo) +{ + unsigned short tempal, temp, i, j; + return; + if (!(pVBInfo->VBInfo & SetCRT2ToTV)) { + temp = 0; + for (i = 0; i < 3; i++) { + for (j = 0; j < 100; j++) { + tempal = XGINew_GetReg2(pVBInfo->P3da); + if (temp & 0x01) { /* VBWaitMode2 */ + if ((tempal & 0x08)) + continue; - case 0x09: - filterPtr = PALYFilter2; - break; + if (!(tempal & 0x08)) + break; - default: - return; + } else { /* VBWaitMode1 */ + if (!(tempal & 0x08)) + continue; + + if ((tempal & 0x08)) + break; + } + } + temp = temp ^ 0x01; + } + } else { + XGI_LongWait(pVBInfo); } + return; +} - if (ModeNo <= 0x13) - tempal = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex; - else - tempal - = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex; +unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, + unsigned short ModeNo, unsigned short ModeIdIndex, + struct vb_device_info *pVBInfo) +{ + short LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01 }, + LCDARefreshIndex[] = { 0x00, 0x00, 0x03, 0x01, 0x01, + 0x01, 0x01 }; - if (tempcl == 0) - index = tempal * 4; + unsigned short RefreshRateTableIndex, i, modeflag, index, temp; + + if (ModeNo <= 0x13) + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; else - index = tempal * 7; + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - if ((tempcl == 0) && (tempch == 1)) { - XGINew_SetReg1(pVBInfo->Part2Port, 0x35, 0); - XGINew_SetReg1(pVBInfo->Part2Port, 0x36, 0); - XGINew_SetReg1(pVBInfo->Part2Port, 0x37, 0); - XGINew_SetReg1(pVBInfo->Part2Port, 0x38, filterPtr[index++]); - } else { - XGINew_SetReg1(pVBInfo->Part2Port, 0x35, filterPtr[index++]); - XGINew_SetReg1(pVBInfo->Part2Port, 0x36, filterPtr[index++]); - XGINew_SetReg1(pVBInfo->Part2Port, 0x37, filterPtr[index++]); - XGINew_SetReg1(pVBInfo->Part2Port, 0x38, filterPtr[index++]); + if (pVBInfo->IF_DEF_CH7005 == 1) { + if (pVBInfo->VBInfo & SetCRT2ToTV) { + if (modeflag & HalfDCLK) + return 0; + } } - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { - XGINew_SetReg1(pVBInfo->Part2Port, 0x48, filterPtr[index++]); - XGINew_SetReg1(pVBInfo->Part2Port, 0x49, filterPtr[index++]); - XGINew_SetReg1(pVBInfo->Part2Port, 0x4A, filterPtr[index++]); - } -} + if (ModeNo < 0x14) + return 0xFFFF; -/* --------------------------------------------------------------------- */ -/* Function : XGI_GetTVPtrIndex2 */ -/* Input : */ -/* Output : bx 0 : NTSC */ -/* 1 : PAL */ -/* 2 : PALM */ -/* 3 : PALN */ -/* 4 : NTSC1024x768 */ -/* 5 : PAL-M 1024x768 */ -/* 6-7: reserved */ -/* cl 0 : YFilter1 */ -/* 1 : YFilter2 */ -/* ch 0 : 301A */ -/* 1 : 301B/302B/301LV/302LV */ -/* Description : */ -/* --------------------------------------------------------------------- */ -static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl, - unsigned char *tempch, struct vb_device_info *pVBInfo) -{ - *tempbx = 0; - *tempcl = 0; - *tempch = 0; + index = XGINew_GetReg1(pVBInfo->P3d4, 0x33); + index = index >> pVBInfo->SelectCRT2Rate; + index &= 0x0F; - if (pVBInfo->TVInfo & SetPALTV) - *tempbx = 1; + if (pVBInfo->LCDInfo & LCDNonExpanding) + index = 0; - if (pVBInfo->TVInfo & SetPALMTV) - *tempbx = 2; + if (index > 0) + index--; - if (pVBInfo->TVInfo & SetPALNTV) - *tempbx = 3; + if (pVBInfo->SetFlag & ProgrammingCRT2) { + if (pVBInfo->IF_DEF_CH7005 == 1) { + if (pVBInfo->VBInfo & SetCRT2ToTV) + index = 0; + } - if (pVBInfo->TVInfo & NTSC1024x768) { - *tempbx = 4; - if (pVBInfo->TVInfo & SetPALMTV) - *tempbx = 5; + if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + if (pVBInfo->IF_DEF_LVDS == 0) { + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B + | VB_XGI301LV | VB_XGI302LV + | VB_XGI301C)) + temp + = LCDARefreshIndex[pVBInfo->LCDResInfo + & 0x0F]; /* 301b */ + else + temp + = LCDRefreshIndex[pVBInfo->LCDResInfo + & 0x0F]; + + if (index > temp) + index = temp; + } else { + index = 0; + } + } } - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { - if ((!(pVBInfo->VBInfo & SetInSlaveMode)) || (pVBInfo->TVInfo - & TVSimuMode)) { - *tempbx += 8; - *tempcl += 1; + RefreshRateTableIndex = pVBInfo->EModeIDTable[ModeIdIndex].REFindex; + ModeNo = pVBInfo->RefIndex[RefreshRateTableIndex].ModeID; + if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */ + /* + if (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & XG2xNotSupport) { + index++; + } + */ + if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 800) + && (pVBInfo->RefIndex[RefreshRateTableIndex].YRes + == 600)) { + index++; + } + /* Alan 10/19/2007; do the similiar adjustment like XGISearchCRT1Rate() */ + if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1024) + && (pVBInfo->RefIndex[RefreshRateTableIndex].YRes + == 768)) { + index++; + } + if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1280) + && (pVBInfo->RefIndex[RefreshRateTableIndex].YRes + == 1024)) { + index++; + } + } + + i = 0; + do { + if (pVBInfo->RefIndex[RefreshRateTableIndex + i].ModeID + != ModeNo) + break; + temp + = pVBInfo->RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag; + temp &= ModeInfoFlag; + if (temp < pVBInfo->ModeType) + break; + i++; + index--; + + } while (index != 0xFFFF); + if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) { + if (pVBInfo->VBInfo & SetInSlaveMode) { + temp + = pVBInfo->RefIndex[RefreshRateTableIndex + + i - 1].Ext_InfoFlag; + if (temp & InterlaceMode) + i++; } } + i--; + if ((pVBInfo->SetFlag & ProgrammingCRT2)) { + temp = XGI_AjustCRT2Rate(ModeNo, ModeIdIndex, + RefreshRateTableIndex, &i, pVBInfo); + } + return RefreshRateTableIndex + i; /* return (0x01 | (temp1<<1)); */ +} - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) - (*tempch)++; +static void XGI_SetLCDAGroup(unsigned short ModeNo, unsigned short ModeIdIndex, + struct xgi_hw_device_info *HwDeviceExtension, + struct vb_device_info *pVBInfo) +{ + unsigned short RefreshRateTableIndex; + /* unsigned short temp ; */ + + /* pVBInfo->SelectCRT2Rate = 0; */ + + pVBInfo->SetFlag |= ProgrammingCRT2; + RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, + ModeIdIndex, pVBInfo); + XGI_GetLVDSResInfo(ModeNo, ModeIdIndex, pVBInfo); + XGI_GetLVDSData(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); + XGI_ModCRT1Regs(ModeNo, ModeIdIndex, RefreshRateTableIndex, + HwDeviceExtension, pVBInfo); + XGI_SetLVDSRegs(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); + XGI_SetCRT2ECLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); } -/* --------------------------------------------------------------------- */ -/* Function : XGI_SetCRT2ModeRegs */ -/* Input : */ -/* Output : */ -/* Description : Origin code for crt2group */ -/* --------------------------------------------------------------------- */ -void XGI_SetCRT2ModeRegs(unsigned short ModeNo, +unsigned char XGI_SetCRT2Group301(unsigned short ModeNo, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - unsigned short tempbl; - short tempcl; + unsigned short tempbx, ModeIdIndex, RefreshRateTableIndex; - unsigned char tempah; + tempbx = pVBInfo->VBInfo; + pVBInfo->SetFlag |= ProgrammingCRT2; + XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo); + pVBInfo->SelectCRT2Rate = 4; + RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, + ModeIdIndex, pVBInfo); + XGI_SaveCRT2Info(ModeNo, pVBInfo); + XGI_GetCRT2ResInfo(ModeNo, ModeIdIndex, pVBInfo); + XGI_GetCRT2Data(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); + XGI_PreSetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension, + RefreshRateTableIndex, pVBInfo); + XGI_SetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension, + RefreshRateTableIndex, pVBInfo); + XGI_SetLockRegs(ModeNo, ModeIdIndex, HwDeviceExtension, + RefreshRateTableIndex, pVBInfo); + XGI_SetGroup2(ModeNo, ModeIdIndex, RefreshRateTableIndex, + HwDeviceExtension, pVBInfo); + XGI_SetLCDRegs(ModeNo, ModeIdIndex, HwDeviceExtension, + RefreshRateTableIndex, pVBInfo); + XGI_SetTap4Regs(pVBInfo); + XGI_SetGroup3(ModeNo, ModeIdIndex, pVBInfo); + XGI_SetGroup4(ModeNo, ModeIdIndex, RefreshRateTableIndex, + HwDeviceExtension, pVBInfo); + XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); + XGI_SetGroup5(ModeNo, ModeIdIndex, pVBInfo); + XGI_AutoThreshold(pVBInfo); + return 1; +} - /* XGINew_SetReg1(pVBInfo->Part1Port, 0x03, 0x00); // fix write part1 index 0 BTDRAM bit Bug */ - tempah = 0; - if (!(pVBInfo->VBInfo & DisableCRT2Display)) { - tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x00); - tempah &= ~0x10; /* BTRAMDAC */ - tempah |= 0x40; /* BTRAM */ +void XGI_SenseCRT1(struct vb_device_info *pVBInfo) +{ + unsigned char CRTCData[17] = { 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, + 0x0B, 0x3E, 0xE9, 0x0B, 0xDF, 0xE7, 0x04, 0x00, 0x00, + 0x05, 0x00 }; - if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV - | SetCRT2ToLCD)) { - tempah = 0x40; /* BTDRAM */ - if (ModeNo > 0x13) { - tempcl = pVBInfo->ModeType; - tempcl -= ModeVGA; - if (tempcl >= 0) { - tempah = (0x008 >> tempcl); /* BT Color */ - if (tempah == 0) - tempah = 1; - tempah |= 0x040; - } - } - if (pVBInfo->VBInfo & SetInSlaveMode) - tempah ^= 0x50; /* BTDAC */ - } - } + unsigned char SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0; - /* 0210 shampoo - if (pVBInfo->VBInfo & DisableCRT2Display) { - tempah = 0; - } + unsigned char CR17, CR63, SR31; + unsigned short temp; + unsigned char DAC_TEST_PARMS[3] = { 0x0F, 0x0F, 0x0F }; - XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah); - if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)) { - tempcl = pVBInfo->ModeType; - if (ModeNo > 0x13) { - tempcl -= ModeVGA; - if ((tempcl > 0) || (tempcl == 0)) { - tempah=(0x008>>tempcl) ; - if (tempah == 0) - tempah = 1; - tempah |= 0x040; - } - } else { - tempah = 0x040; - } + int i; + XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86); - if (pVBInfo->VBInfo & SetInSlaveMode) { - tempah = (tempah ^ 0x050); - } - } - */ + /* [2004/05/06] Vicent to fix XG42 single LCD sense to CRT+LCD */ + XGINew_SetReg1(pVBInfo->P3d4, 0x57, 0x4A); + XGINew_SetReg1(pVBInfo->P3d4, 0x53, (unsigned char) (XGINew_GetReg1( + pVBInfo->P3d4, 0x53) | 0x02)); - XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah); - tempah = 0x08; - tempbl = 0xf0; + SR31 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x31); + CR63 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x63); + SR01 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x01); - if (pVBInfo->VBInfo & DisableCRT2Display) { - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e, tempbl, tempah); - } else { - tempah = 0x00; - tempbl = 0xff; + XGINew_SetReg1(pVBInfo->P3c4, 0x01, (unsigned char) (SR01 & 0xDF)); + XGINew_SetReg1(pVBInfo->P3d4, 0x63, (unsigned char) (CR63 & 0xBF)); - if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV - | SetCRT2ToLCD | SetCRT2ToLCDA)) { - if ((pVBInfo->VBInfo & SetCRT2ToLCDA) - && (!(pVBInfo->VBInfo & SetSimuScanMode))) { - tempbl &= 0xf7; - tempah |= 0x01; - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e, - tempbl, tempah); - } else { - if (pVBInfo->VBInfo & SetCRT2ToLCDA) { - tempbl &= 0xf7; - tempah |= 0x01; - } + CR17 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x17); + XGINew_SetReg1(pVBInfo->P3d4, 0x17, (unsigned char) (CR17 | 0x80)); - if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC - | SetCRT2ToTV | SetCRT2ToLCD)) { - tempbl &= 0xf8; - tempah = 0x01; + SR1F = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x1F); + XGINew_SetReg1(pVBInfo->P3c4, 0x1F, (unsigned char) (SR1F | 0x04)); - if (!(pVBInfo->VBInfo & SetInSlaveMode)) - tempah |= 0x02; + SR07 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x07); + XGINew_SetReg1(pVBInfo->P3c4, 0x07, (unsigned char) (SR07 & 0xFB)); + SR06 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x06); + XGINew_SetReg1(pVBInfo->P3c4, 0x06, (unsigned char) (SR06 & 0xC3)); - if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) { - tempah = tempah ^ 0x05; - if (!(pVBInfo->VBInfo - & SetCRT2ToLCD)) - tempah = tempah ^ 0x01; - } + XGINew_SetReg1(pVBInfo->P3d4, 0x11, 0x00); - if (!(pVBInfo->VBInfo - & SetCRT2ToDualEdge)) - tempah |= 0x08; - XGINew_SetRegANDOR(pVBInfo->Part1Port, - 0x2e, tempbl, tempah); - } else { - XGINew_SetRegANDOR(pVBInfo->Part1Port, - 0x2e, tempbl, tempah); - } - } - } else { - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e, tempbl, - tempah); - } - } + for (i = 0; i < 8; i++) + XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) i, CRTCData[i]); - if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD - | SetCRT2ToLCDA)) { - tempah &= (~0x08); - if ((pVBInfo->ModeType == ModeVGA) && (!(pVBInfo->VBInfo - & SetInSlaveMode))) { - tempah |= 0x010; - } - tempah |= 0x080; + for (i = 8; i < 11; i++) + XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 8), + CRTCData[i]); - if (pVBInfo->VBInfo & SetCRT2ToTV) { - /* if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) { */ - tempah |= 0x020; - if (ModeNo > 0x13) { - if (pVBInfo->VBInfo & DriverMode) - tempah = tempah ^ 0x20; - } - /* } */ - } + for (i = 11; i < 13; i++) + XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 4), + CRTCData[i]); - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah); - tempah = 0; + for (i = 13; i < 16; i++) + XGINew_SetReg1(pVBInfo->P3c4, (unsigned short) (i - 3), + CRTCData[i]); - if (pVBInfo->LCDInfo & SetLCDDualLink) - tempah |= 0x40; + XGINew_SetReg1(pVBInfo->P3c4, 0x0E, (unsigned char) (CRTCData[16] + & 0xE0)); - if (pVBInfo->VBInfo & SetCRT2ToTV) { - /* if ((!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) && (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)))) { */ - if (pVBInfo->TVInfo & RPLLDIV2XO) - tempah |= 0x40; - /* } */ - } + XGINew_SetReg1(pVBInfo->P3c4, 0x31, 0x00); + XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x1B); + XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE1); - if ((pVBInfo->LCDResInfo == Panel1280x1024) - || (pVBInfo->LCDResInfo == Panel1280x1024x75)) - tempah |= 0x80; + XGINew_SetReg3(pVBInfo->P3c8, 0x00); + + for (i = 0; i < 256; i++) { + XGINew_SetReg3((pVBInfo->P3c8 + 1), + (unsigned char) DAC_TEST_PARMS[0]); + XGINew_SetReg3((pVBInfo->P3c8 + 1), + (unsigned char) DAC_TEST_PARMS[1]); + XGINew_SetReg3((pVBInfo->P3c8 + 1), + (unsigned char) DAC_TEST_PARMS[2]); + } + + XGI_VBLongWait(pVBInfo); + XGI_VBLongWait(pVBInfo); + XGI_VBLongWait(pVBInfo); + + mdelay(1); + + XGI_WaitDisply(pVBInfo); + temp = XGINew_GetReg2(pVBInfo->P3c2); + + if (temp & 0x10) + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xDF, 0x20); + else + XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xDF, 0x00); - if (pVBInfo->LCDResInfo == Panel1280x960) - tempah |= 0x80; + /* alan, avoid display something, set BLACK DAC if not restore DAC */ + XGINew_SetReg3(pVBInfo->P3c8, 0x00); - XGINew_SetReg1(pVBInfo->Part4Port, 0x0C, tempah); + for (i = 0; i < 256; i++) { + XGINew_SetReg3((pVBInfo->P3c8 + 1), 0); + XGINew_SetReg3((pVBInfo->P3c8 + 1), 0); + XGINew_SetReg3((pVBInfo->P3c8 + 1), 0); } - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV - | VB_XGI302LV | VB_XGI301C)) { - tempah = 0; - tempbl = 0xfb; - - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { - tempbl = 0xff; - if (pVBInfo->VBInfo & SetCRT2ToLCDA) - tempah |= 0x04; /* shampoo 0129 */ - } + XGINew_SetReg1(pVBInfo->P3c4, 0x01, SR01); + XGINew_SetReg1(pVBInfo->P3d4, 0x63, CR63); + XGINew_SetReg1(pVBInfo->P3c4, 0x31, SR31); - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x13, tempbl, tempah); - tempah = 0x00; - tempbl = 0xcf; - if (!(pVBInfo->VBInfo & DisableCRT2Display)) { - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) - tempah |= 0x30; - } + /* [2004/05/11] Vicent */ + XGINew_SetReg1(pVBInfo->P3d4, 0x53, (unsigned char) (XGINew_GetReg1( + pVBInfo->P3d4, 0x53) & 0xFD)); + XGINew_SetReg1(pVBInfo->P3c4, 0x1F, (unsigned char) SR1F); +} - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2c, tempbl, tempah); - tempah = 0; - tempbl = 0x3f; +void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, + struct vb_device_info *pVBInfo) +{ + unsigned short tempbl, tempah; - if (!(pVBInfo->VBInfo & DisableCRT2Display)) { - if (pVBInfo->VBInfo & SetCRT2ToDualEdge) - tempah |= 0xc0; - } - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x21, tempbl, tempah); + if (pVBInfo->SetFlag == Win9xDOSMode) { + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV + | VB_XGI302LV | VB_XGI301C)) { + XGI_DisplayOn(HwDeviceExtension, pVBInfo); + return; + } else + /* LVDS or CH7017 */ + return; } - tempah = 0; - tempbl = 0x7f; - if (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) { - tempbl = 0xff; - if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge)) - tempah |= 0x80; - } + if (HwDeviceExtension->jChipType < XG40) { + if (!XGI_DisableChISLCD(pVBInfo)) { + if ((XGI_EnableChISLCD(pVBInfo)) || (pVBInfo->VBInfo + & (SetCRT2ToLCD | SetCRT2ToLCDA))) { + if (pVBInfo->LCDInfo & SetPWDEnable) { + XGI_EnablePWD(pVBInfo); + } else { + pVBInfo->LCDInfo &= (~SetPWDEnable); + if (pVBInfo->VBType & (VB_XGI301LV + | VB_XGI302LV + | VB_XGI301C)) { + tempbl = 0xFD; + tempah = 0x02; + } else { + tempbl = 0xFB; + tempah = 0x00; + } - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x23, tempbl, tempah); + XGI_SetPanelPower(tempah, tempbl, + pVBInfo); + XGI_SetPanelDelay(1, pVBInfo); + } + } + } + } /* Not 340 */ - if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) { - if (pVBInfo->LCDInfo & SetLCDDualLink) { - XGINew_SetRegOR(pVBInfo->Part4Port, 0x27, 0x20); - XGINew_SetRegOR(pVBInfo->Part4Port, 0x34, 0x10); + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV + | VB_XGI302LV | VB_XGI301C)) { + if (!(pVBInfo->SetFlag & DisableChA)) { + if (pVBInfo->SetFlag & EnableChA) { + XGINew_SetReg1(pVBInfo->Part1Port, 0x1E, 0x20); /* Power on */ + } else { + if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { /* SetCRT2ToLCDA ) */ + XGINew_SetReg1(pVBInfo->Part1Port, + 0x1E, 0x20); /* Power on */ + } + } } - } -} -static void XGI_CloseCRTC(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short tempbx; + if (!(pVBInfo->SetFlag & DisableChB)) { + if ((pVBInfo->SetFlag & EnableChB) || (pVBInfo->VBInfo + & (SetCRT2ToLCD | SetCRT2ToTV + | SetCRT2ToRAMDAC))) { + tempah = (unsigned char) XGINew_GetReg1( + pVBInfo->P3c4, 0x32); + tempah &= 0xDF; + if (pVBInfo->VBInfo & SetInSlaveMode) { + if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) + tempah |= 0x20; + } + XGINew_SetReg1(pVBInfo->P3c4, 0x32, tempah); + XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x20); - tempbx = 0; + tempah = (unsigned char) XGINew_GetReg1( + pVBInfo->Part1Port, 0x2E); - if (pVBInfo->VBInfo & SetCRT2ToLCDA) - tempbx = 0x08A0; + if (!(tempah & 0x80)) + XGINew_SetRegOR(pVBInfo->Part1Port, + 0x2E, 0x80); /* BVBDOENABLE = 1 */ -} + XGINew_SetRegAND(pVBInfo->Part1Port, 0x00, 0x7F); /* BScreenOFF = 0 */ + } + } -void XGI_OpenCRTC(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ - unsigned short tempbx; - tempbx = 0; -} + if ((pVBInfo->SetFlag & (EnableChA | EnableChB)) + || (!(pVBInfo->VBInfo & DisableCRT2Display))) { + XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x00, ~0xE0, + 0x20); /* shampoo 0129 */ + if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) { + if (!XGI_DisableChISLCD(pVBInfo)) { + if (XGI_EnableChISLCD(pVBInfo) + || (pVBInfo->VBInfo + & (SetCRT2ToLCD + | SetCRT2ToLCDA))) + XGINew_SetRegAND( + pVBInfo->Part4Port, + 0x2A, 0x7F); /* LVDS PLL power on */ + } + XGINew_SetRegAND(pVBInfo->Part4Port, 0x30, 0x7F); /* LVDS Driver power on */ + } + } -static void XGI_GetRAMDAC2DATA(unsigned short ModeNo, unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) -{ - unsigned short tempax, tempbx, temp1, temp2, modeflag = 0, tempcx, - StandTableIndex, CRT1Index; + tempah = 0x00; - pVBInfo->RVBHCMAX = 1; - pVBInfo->RVBHCFACT = 1; + if (!(pVBInfo->VBInfo & DisableCRT2Display)) { + tempah = 0xc0; - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo); - tempax = pVBInfo->StandTable[StandTableIndex].CRTC[0]; - tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[6]; - temp1 = pVBInfo->StandTable[StandTableIndex].CRTC[7]; - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - CRT1Index - = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - CRT1Index &= IndexMask; - temp1 - = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0]; - temp2 - = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5]; - tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8); - tempbx - = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[8]; - tempcx - = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] - << 8; - tempcx &= 0x0100; - tempcx = tempcx << 2; - tempbx |= tempcx; - temp1 - = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9]; - } + if (!(pVBInfo->VBInfo & SetSimuScanMode)) { + if (pVBInfo->VBInfo & SetCRT2ToLCDA) { + if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { + tempah = tempah & 0x40; + if (pVBInfo->VBInfo + & SetCRT2ToLCDA) + tempah = tempah ^ 0xC0; - if (temp1 & 0x01) - tempbx |= 0x0100; + if (pVBInfo->SetFlag + & DisableChB) + tempah &= 0xBF; - if (temp1 & 0x20) - tempbx |= 0x0200; - tempax += 5; + if (pVBInfo->SetFlag + & DisableChA) + tempah &= 0x7F; - if (modeflag & Charx8Dot) - tempax *= 8; - else - tempax *= 9; + if (pVBInfo->SetFlag + & EnableChB) + tempah |= 0x40; - pVBInfo->VGAHT = tempax; - pVBInfo->HT = tempax; - tempbx++; - pVBInfo->VGAVT = tempbx; - pVBInfo->VT = tempbx; -} + if (pVBInfo->SetFlag + & EnableChA) + tempah |= 0x80; + } + } + } + } -static unsigned short XGI_GetColorDepth(unsigned short ModeNo, - unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) -{ - unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 }; - short index; - unsigned short modeflag; + XGINew_SetRegOR(pVBInfo->Part4Port, 0x1F, tempah); /* EnablePart4_1F */ - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + if (pVBInfo->SetFlag & Win9xDOSMode) { + XGI_DisplayOn(HwDeviceExtension, pVBInfo); + return; + } + + if (!(pVBInfo->SetFlag & DisableChA)) { + XGI_VBLongWait(pVBInfo); + if (!(pVBInfo->SetFlag & GatingCRT)) { + XGI_DisableGatingCRT(HwDeviceExtension, pVBInfo); + XGI_DisplayOn(HwDeviceExtension, pVBInfo); + XGI_VBLongWait(pVBInfo); + } + } + } /* 301 */ + else { /* LVDS */ + if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD + | SetCRT2ToLCDA)) + XGINew_SetRegOR(pVBInfo->Part1Port, 0x1E, 0x20); /* enable CRT2 */ - index = (modeflag & ModeInfoFlag) - ModeEGA; + tempah = (unsigned char) XGINew_GetReg1(pVBInfo->Part1Port, + 0x2E); + if (!(tempah & 0x80)) + XGINew_SetRegOR(pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */ - if (index < 0) - index = 0; + XGINew_SetRegAND(pVBInfo->Part1Port, 0x00, 0x7F); + XGI_DisplayOn(HwDeviceExtension, pVBInfo); + } /* End of VB */ - return ColorDepth[index]; -} + if (HwDeviceExtension->jChipType < XG40) { + if (!XGI_EnableChISLCD(pVBInfo)) { + if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { + if (XGI_BacklightByDrv(pVBInfo)) + return; + } else + return; + } -void XGI_UnLockCRT2(struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) -{ + if (pVBInfo->LCDInfo & SetPWDEnable) { + XGI_FirePWDEnable(pVBInfo); + return; + } - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2f, 0xFF, 0x01); + XGI_SetPanelDelay(2, pVBInfo); + if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { + tempah = 0x01; + tempbl = 0xFE; /* turn on backlght */ + } else { + tempbl = 0xF7; + tempah = 0x00; + } + XGI_SetPanelPower(tempah, tempbl, pVBInfo); + } } -void XGI_LockCRT2(struct xgi_hw_device_info *HwDeviceExtension, +static void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension, + unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { + unsigned short StandTableIndex, RefreshRateTableIndex, b3CC, temp; - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2F, 0xFE, 0x00); - -} - -static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo) -{ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1E, 0xFF, 0x20); -} + unsigned short XGINew_P3cc = pVBInfo->P3cc; -unsigned char XGI_BridgeIsOn(struct vb_device_info *pVBInfo) -{ - unsigned short flag; + /* XGINew_CRT1Mode = ModeNo; // SaveModeID */ + StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo); + /* XGI_SetBIOSData(ModeNo, ModeIdIndex); */ + /* XGI_ClearBankRegs(ModeNo, ModeIdIndex); */ + XGI_SetSeqRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo); + XGI_SetMiscRegs(StandTableIndex, pVBInfo); + XGI_SetCRTCRegs(HwDeviceExtension, StandTableIndex, pVBInfo); + XGI_SetATTRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo); + XGI_SetGRCRegs(StandTableIndex, pVBInfo); + XGI_ClearExt1Regs(pVBInfo); - if (pVBInfo->IF_DEF_LVDS == 1) { - return 1; - } else { - flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x00); - if ((flag == 1) || (flag == 2)) - return 1; /* 301b */ - else - return 0; + /* if (pVBInfo->IF_DEF_ExpLink) */ + if (HwDeviceExtension->jChipType == XG27) { + if (pVBInfo->IF_DEF_LVDS == 0) + XGI_SetDefaultVCLK(pVBInfo); } -} - -void XGI_LongWait(struct vb_device_info *pVBInfo) -{ - unsigned short i; - i = XGINew_GetReg1(pVBInfo->P3c4, 0x1F); + temp = ~ProgrammingCRT2; + pVBInfo->SetFlag &= temp; + pVBInfo->SelectCRT2Rate = 0; - if (!(i & 0xC0)) { - for (i = 0; i < 0xFFFF; i++) { - if (!(XGINew_GetReg2(pVBInfo->P3da) & 0x08)) - break; + if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV + | VB_XGI302LV | VB_XGI301C)) { + if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA + | SetInSlaveMode)) { + pVBInfo->SetFlag |= ProgrammingCRT2; } + } - for (i = 0; i < 0xFFFF; i++) { - if ((XGINew_GetReg2(pVBInfo->P3da) & 0x08)) - break; + RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, + ModeIdIndex, pVBInfo); + if (RefreshRateTableIndex != 0xFFFF) { + XGI_SetSync(RefreshRateTableIndex, pVBInfo); + XGI_SetCRT1CRTC(ModeNo, ModeIdIndex, RefreshRateTableIndex, + pVBInfo, HwDeviceExtension); + XGI_SetCRT1DE(HwDeviceExtension, ModeNo, ModeIdIndex, + RefreshRateTableIndex, pVBInfo); + XGI_SetCRT1Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex, + HwDeviceExtension, pVBInfo); + XGI_SetCRT1VCLK(ModeNo, ModeIdIndex, HwDeviceExtension, + RefreshRateTableIndex, pVBInfo); + } + + if ((HwDeviceExtension->jChipType >= XG20) + && (HwDeviceExtension->jChipType < XG27)) { /* fix H/W DCLK/2 bug */ + if ((ModeNo == 0x00) | (ModeNo == 0x01)) { + XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x4E); + XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE9); + b3CC = (unsigned char) XGINew_GetReg2(XGINew_P3cc); + XGINew_SetReg3(XGINew_P3cc, (b3CC |= 0x0C)); + } else if ((ModeNo == 0x04) | (ModeNo == 0x05) | (ModeNo + == 0x0D)) { + XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x1B); + XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE3); + b3CC = (unsigned char) XGINew_GetReg2(XGINew_P3cc); + XGINew_SetReg3(XGINew_P3cc, (b3CC |= 0x0C)); } } -} -static void XGI_VBLongWait(struct vb_device_info *pVBInfo) -{ - unsigned short tempal, temp, i, j; - return; - if (!(pVBInfo->VBInfo & SetCRT2ToTV)) { - temp = 0; - for (i = 0; i < 3; i++) { - for (j = 0; j < 100; j++) { - tempal = XGINew_GetReg2(pVBInfo->P3da); - if (temp & 0x01) { /* VBWaitMode2 */ - if ((tempal & 0x08)) - continue; + if (HwDeviceExtension->jChipType >= XG21) { + temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38); + if (temp & 0xA0) { - if (!(tempal & 0x08)) - break; + /* XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); *//* Enable write GPIOF */ + /* XGINew_SetRegAND(pVBInfo->P3d4, 0x48, ~0x20); *//* P. DWN */ + /* XG21 CRT1 Timing */ + if (HwDeviceExtension->jChipType == XG27) + XGI_SetXG27CRTC(ModeNo, ModeIdIndex, + RefreshRateTableIndex, pVBInfo); + else + XGI_SetXG21CRTC(ModeNo, ModeIdIndex, + RefreshRateTableIndex, pVBInfo); - } else { /* VBWaitMode1 */ - if (!(tempal & 0x08)) - continue; + XGI_UpdateXG21CRTC(ModeNo, pVBInfo, + RefreshRateTableIndex); - if ((tempal & 0x08)) - break; - } + if (HwDeviceExtension->jChipType == XG27) + XGI_SetXG27LCD(pVBInfo, RefreshRateTableIndex, + ModeNo); + else + XGI_SetXG21LCD(pVBInfo, RefreshRateTableIndex, + ModeNo); + + if (pVBInfo->IF_DEF_LVDS == 1) { + if (HwDeviceExtension->jChipType == XG27) + XGI_SetXG27LVDSPara(ModeNo, + ModeIdIndex, pVBInfo); + else + XGI_SetXG21LVDSPara(ModeNo, + ModeIdIndex, pVBInfo); } - temp = temp ^ 0x01; + /* XGINew_SetRegOR(pVBInfo->P3d4, 0x48, 0x20); *//* P. ON */ } - } else { - XGI_LongWait(pVBInfo); } - return; -} -static unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo) -{ - unsigned long tempax, tempbx; + pVBInfo->SetFlag &= (~ProgrammingCRT2); + XGI_SetCRT1FIFO(ModeNo, HwDeviceExtension, pVBInfo); + XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeNo, ModeIdIndex, + RefreshRateTableIndex, pVBInfo); - tempbx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) * pVBInfo->RVBHCMAX) - & 0xFFFF; - tempax = (pVBInfo->VT - pVBInfo->VDE) * pVBInfo->RVBHCFACT; - tempax = (tempax * pVBInfo->HT) / tempbx; + /* XGI_LoadCharacter(); //dif ifdef TVFont */ - return (unsigned short) tempax; + XGI_LoadDAC(ModeNo, ModeIdIndex, pVBInfo); + /* XGI_ClearBuffer(HwDeviceExtension, ModeNo, pVBInfo); */ } -static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, - unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct xgi_hw_device_info *HwDeviceExtension, - struct vb_device_info *pVBInfo) +unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension, + unsigned short ModeNo) { - unsigned short tempbx; + unsigned short ModeIdIndex; + /* unsigned char *pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; */ + struct vb_device_info VBINF; + struct vb_device_info *pVBInfo = &VBINF; + pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase; + pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress; + pVBInfo->IF_DEF_LVDS = 0; + pVBInfo->IF_DEF_CH7005 = 0; + pVBInfo->IF_DEF_LCDA = 1; + pVBInfo->IF_DEF_CH7017 = 0; + pVBInfo->IF_DEF_CH7007 = 0; /* [Billy] 2007/05/14 */ + pVBInfo->IF_DEF_VideoCapture = 0; + pVBInfo->IF_DEF_ScaleLCD = 0; + pVBInfo->IF_DEF_OEMUtil = 0; + pVBInfo->IF_DEF_PWD = 0; + + if (HwDeviceExtension->jChipType >= XG20) { /* kuku 2004/06/25 */ + pVBInfo->IF_DEF_YPbPr = 0; + pVBInfo->IF_DEF_HiVision = 0; + pVBInfo->IF_DEF_CRT2Monitor = 0; + pVBInfo->VBType = 0; /*set VBType default 0*/ + } else if (HwDeviceExtension->jChipType >= XG40) { + pVBInfo->IF_DEF_YPbPr = 1; + pVBInfo->IF_DEF_HiVision = 1; + pVBInfo->IF_DEF_CRT2Monitor = 1; + } else { + pVBInfo->IF_DEF_YPbPr = 1; + pVBInfo->IF_DEF_HiVision = 1; + pVBInfo->IF_DEF_CRT2Monitor = 0; + } + + pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14; + pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24; + pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10; + pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e; + pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12; + pVBInfo->P3cc = pVBInfo->BaseAddr + 0x1C; + pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a; + pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16; + pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17; + pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18; + pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19; + pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A; + pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00; + pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04; + pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10; + pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12; + pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14; + pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2; - unsigned short LCDXlat1VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2, - VCLK65 + 2 }; - unsigned short LCDXlat2VCLK[4] = { VCLK108_2 + 5, VCLK108_2 + 5, - VCLK108_2 + 5, VCLK108_2 + 5 }; - unsigned short LVDSXlat1VCLK[4] = { VCLK40, VCLK40, VCLK40, VCLK40 }; - unsigned short LVDSXlat2VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2, - VCLK65 + 2 }; - unsigned short LVDSXlat3VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2, - VCLK65 + 2 }; + if (HwDeviceExtension->jChipType == XG21) { /* for x86 Linux, XG21 LVDS */ + if ((XGINew_GetReg1(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) + pVBInfo->IF_DEF_LVDS = 1; + } + if (HwDeviceExtension->jChipType == XG27) { + if ((XGINew_GetReg1(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) { + if (XGINew_GetReg1(pVBInfo->P3d4, 0x30) & 0x20) + pVBInfo->IF_DEF_LVDS = 1; + } + } - unsigned short CRT2Index, VCLKIndex; - unsigned short modeflag, resinfo; - unsigned char *CHTVVCLKPtr = NULL; + if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */ + XGI_GetVBType(pVBInfo); - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */ - resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - CRT2Index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */ - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - CRT2Index - = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo); + if (ModeNo & 0x80) { + ModeNo = ModeNo & 0x7F; + /* XGINew_flag_clearbuffer = 0; */ + } + /* else { + XGINew_flag_clearbuffer = 1; } + */ + XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86); - if (pVBInfo->IF_DEF_LVDS == 0) { - CRT2Index = CRT2Index >> 6; /* for LCD */ - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /*301b*/ - if (pVBInfo->LCDResInfo != Panel1024x768) - VCLKIndex = LCDXlat2VCLK[CRT2Index]; - else - VCLKIndex = LCDXlat1VCLK[CRT2Index]; - } else { /* for TV */ - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { - if (pVBInfo->SetFlag & RPLLDIV2XO) { - VCLKIndex = HiTVVCLKDIV2; + if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 1.Openkey */ + XGI_UnLockCRT2(HwDeviceExtension, pVBInfo); - VCLKIndex += 25; + XGI_SearchModeID(ModeNo, &ModeIdIndex, pVBInfo); - } else { - VCLKIndex = HiTVVCLK; + XGI_GetVGAType(HwDeviceExtension, pVBInfo); - VCLKIndex += 25; + if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */ + XGI_GetVBInfo(ModeNo, ModeIdIndex, HwDeviceExtension, pVBInfo); + XGI_GetTVInfo(ModeNo, ModeIdIndex, pVBInfo); + XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo); + XGI_DisableBridge(HwDeviceExtension, pVBInfo); + /* XGI_OpenCRTC(HwDeviceExtension, pVBInfo); */ - } + if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) { + XGI_SetCRT1Group(HwDeviceExtension, ModeNo, + ModeIdIndex, pVBInfo); - if (pVBInfo->SetFlag & TVSimuMode) { - if (modeflag & Charx8Dot) { - VCLKIndex - = HiTVSimuVCLK; + if (pVBInfo->VBInfo & SetCRT2ToLCDA) { + XGI_SetLCDAGroup(ModeNo, ModeIdIndex, + HwDeviceExtension, pVBInfo); + } + } else { + if (!(pVBInfo->VBInfo & SwitchToCRT2)) { + XGI_SetCRT1Group(HwDeviceExtension, ModeNo, + ModeIdIndex, pVBInfo); + if (pVBInfo->VBInfo & SetCRT2ToLCDA) { + XGI_SetLCDAGroup(ModeNo, ModeIdIndex, + HwDeviceExtension, + pVBInfo); + } + } + } - VCLKIndex += 25; + if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchToCRT2)) { + switch (HwDeviceExtension->ujVBChipID) { + case VB_CHIP_301: + XGI_SetCRT2Group301(ModeNo, HwDeviceExtension, + pVBInfo); /*add for CRT2 */ + break; - } else { - VCLKIndex - = HiTVTextVCLK; + case VB_CHIP_302: + XGI_SetCRT2Group301(ModeNo, HwDeviceExtension, + pVBInfo); /*add for CRT2 */ + break; - VCLKIndex += 25; + default: + break; + } + } - } - } + XGI_SetCRT2ModeRegs(ModeNo, HwDeviceExtension, pVBInfo); + XGI_OEM310Setting(ModeNo, ModeIdIndex, pVBInfo); /*0212*/ + XGI_CloseCRTC(HwDeviceExtension, pVBInfo); + XGI_EnableBridge(HwDeviceExtension, pVBInfo); + } /* !XG20 */ + else { + if (pVBInfo->IF_DEF_LVDS == 1) + if (!XGI_XG21CheckLVDSMode(ModeNo, ModeIdIndex, pVBInfo)) + return 0; - if (pVBInfo->VBType & VB_XGI301LV) { /* 301lv */ - if (!(pVBInfo->VBExtInfo - == VB_YPbPr1080i)) { - VCLKIndex - = YPbPr750pVCLK; - if (!(pVBInfo->VBExtInfo - == VB_YPbPr750p)) { - VCLKIndex - = YPbPr525pVCLK; - if (!(pVBInfo->VBExtInfo - == VB_YPbPr525p)) { - VCLKIndex - = YPbPr525iVCLK_2; - if (!(pVBInfo->SetFlag - & RPLLDIV2XO)) - VCLKIndex - = YPbPr525iVCLK; - } - } - } - } - } else { - if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (pVBInfo->SetFlag - & RPLLDIV2XO) { - VCLKIndex = TVVCLKDIV2; + if (ModeNo <= 0x13) { + pVBInfo->ModeType + = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag + & ModeInfoFlag; + } else { + pVBInfo->ModeType + = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag + & ModeInfoFlag; + } - VCLKIndex += 25; + pVBInfo->SetFlag = 0; + if (pVBInfo->IF_DEF_CH7007 != 1) + pVBInfo->VBInfo = DisableCRT2Display; - } else { - VCLKIndex = TVVCLK; + XGI_DisplayOff(HwDeviceExtension, pVBInfo); - VCLKIndex += 25; + XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex, + pVBInfo); - } - } - } - } else { /* for CRT2 */ - VCLKIndex = (unsigned char) XGINew_GetReg2( - (pVBInfo->P3ca + 0x02)); /* Port 3cch */ - VCLKIndex = ((VCLKIndex >> 2) & 0x03); - if (ModeNo > 0x13) { - VCLKIndex - = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; /* di+Ext_CRTVCLK */ - VCLKIndex &= IndexMask; - } - } - } - } else { /* LVDS */ - if (ModeNo <= 0x13) - VCLKIndex = CRT2Index; - else - VCLKIndex = CRT2Index; + XGI_DisplayOn(HwDeviceExtension, pVBInfo); + /* + if (HwDeviceExtension->jChipType == XG21) + XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0x80, 0x80); + */ + } - if (pVBInfo->IF_DEF_CH7005 == 1) { - if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) { - VCLKIndex &= 0x1f; - tempbx = 0; + /* + if (ModeNo <= 0x13) { + modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; + } else { + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + } + pVBInfo->ModeType = modeflag&ModeInfoFlag; + pVBInfo->SetFlag = 0x00; + pVBInfo->VBInfo = DisableCRT2Display; + temp = XGINew_CheckMemorySize(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo); - if (pVBInfo->VBInfo & SetPALTV) - tempbx += 2; + if (temp == 0) + return (0); - if (pVBInfo->VBInfo & SetCHTVOverScan) - tempbx += 1; + XGI_DisplayOff(HwDeviceExtension, pVBInfo) ; + XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo); + XGI_DisplayOn(HwDeviceExtension, pVBInfo); + */ - switch (tempbx) { - case 0: - CHTVVCLKPtr = pVBInfo->CHTVVCLKUNTSC; - break; - case 1: - CHTVVCLKPtr = pVBInfo->CHTVVCLKONTSC; - break; - case 2: - CHTVVCLKPtr = pVBInfo->CHTVVCLKUPAL; - break; - case 3: - CHTVVCLKPtr = pVBInfo->CHTVVCLKOPAL; - break; - default: - break; - } + XGI_UpdateModeInfo(HwDeviceExtension, pVBInfo); - VCLKIndex = CHTVVCLKPtr[VCLKIndex]; - } - } else { - VCLKIndex = VCLKIndex >> 6; - if ((pVBInfo->LCDResInfo == Panel800x600) - || (pVBInfo->LCDResInfo == Panel320x480)) - VCLKIndex = LVDSXlat1VCLK[VCLKIndex]; - else if ((pVBInfo->LCDResInfo == Panel1024x768) - || (pVBInfo->LCDResInfo - == Panel1024x768x75)) - VCLKIndex = LVDSXlat2VCLK[VCLKIndex]; - else - VCLKIndex = LVDSXlat3VCLK[VCLKIndex]; - } + if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */ + XGI_LockCRT2(HwDeviceExtension, pVBInfo); } - /* VCLKIndex = VCLKIndex&IndexMask; */ - return VCLKIndex; + return 1; } - -- cgit v1.2.3 From ebe7846def655647608993c9c295158766f2e301 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:08 +0200 Subject: staging: xgifb: delete unsupported chip types The probe routine will fail if the chip is other than XG40..XG27, so the other types can be dropped. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 31 +++++-------------------------- drivers/staging/xgifb/XGIfb.h | 18 ------------------ 2 files changed, 5 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index ee8017175762..b2cb7a3889a2 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -182,8 +182,6 @@ static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr, */ ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; - if (HwDeviceExtension->jChipType < XGI_315H) - ClockIndex &= 0x3F; Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000; @@ -859,12 +857,6 @@ static int XGIfb_validate_mode(int myindex) if (XGIbios_mode[myindex].bpp == 32) return -1; } - /* TW: LVDS/CHRONTEL only supports < 800 (1024 on 650/Ch7019) */ - if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL - || xgi_video_info.hasVB == HASVB_CHRONTEL) { - if (xgi_video_info.chip < XGI_315H) - return -1; - } break; default: return -1; @@ -1684,24 +1676,11 @@ static void XGIfb_detect_VB(void) xgi_video_info.TV_plug = TVPLUG_SCART; if (xgi_video_info.TV_type == 0) { - /* TW: PAL/NTSC changed for 650 */ - if ((xgi_video_info.chip <= XGI_315PRO) || (xgi_video_info.chip - >= XGI_330)) { - - inXGIIDXREG(XGICR, 0x38, temp); - if (temp & 0x10) - xgi_video_info.TV_type = TVMODE_PAL; - else - xgi_video_info.TV_type = TVMODE_NTSC; - - } else { - - inXGIIDXREG(XGICR, 0x79, temp); - if (temp & 0x20) - xgi_video_info.TV_type = TVMODE_PAL; - else - xgi_video_info.TV_type = TVMODE_NTSC; - } + inXGIIDXREG(XGICR, 0x38, temp); + if (temp & 0x10) + xgi_video_info.TV_type = TVMODE_PAL; + else + xgi_video_info.TV_type = TVMODE_NTSC; } /* TW: Copy forceCRT1 option to CRT1off if option is given */ diff --git a/drivers/staging/xgifb/XGIfb.h b/drivers/staging/xgifb/XGIfb.h index 7813bbe664ae..b43a7588e57d 100644 --- a/drivers/staging/xgifb/XGIfb.h +++ b/drivers/staging/xgifb/XGIfb.h @@ -27,23 +27,6 @@ #endif enum XGI_CHIP_TYPE { - XGI_VGALegacy = 0, - XGI_300, - XGI_630, - XGI_730, - XGI_540, - XGI_315H, - XGI_315, - XGI_315PRO, - XGI_550, - XGI_640, - XGI_740, - XGI_650, - XGI_650M, - XGI_330 = 16, - XGI_660, - XGI_661, - XGI_760, XG40 = 32, XG41, XG42, @@ -51,7 +34,6 @@ enum XGI_CHIP_TYPE { XG20 = 48, XG21, XG27, - MAX_XGI_CHIP }; enum xgi_tvtype { -- cgit v1.2.3 From fd0ad4701a3d096e6caf609e15eecae1459cc4b4 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:09 +0200 Subject: staging: xgifb: delete dead code for chip types < XG40 XG40 is the first supported chip, so the code for earlier chips can be dropped. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 9 +- drivers/staging/xgifb/vb_setmode.c | 216 +------------------------------------ 2 files changed, 3 insertions(+), 222 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 7b8e00defd50..10c0a3bcbbae 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -1409,9 +1409,7 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) if (HwDeviceExtension->jChipType >= XG40) XGINew_RAMType = (int)XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); - - if (HwDeviceExtension->jChipType < XG40) - XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo); */ + */ printk("11"); @@ -1494,9 +1492,6 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) XGINew_SetReg1(pVBInfo->P3d4, 0x48, 0x20); /* CR48 */ } printk("14"); - - if (HwDeviceExtension->jChipType < XG40) - XGINew_SetReg1(pVBInfo->P3d4, 0x49, pVBInfo->CR49[0]); } /* != XG20 */ /* Set PCI */ @@ -1552,8 +1547,6 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) } /* != XG20 */ printk("18"); - if (HwDeviceExtension->jChipType < XG40) - XGINew_SetReg1(pVBInfo->P3d4, 0x83, 0x00); printk("181"); printk("182"); diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 693be078595b..4d5696349bcb 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -6280,47 +6280,6 @@ static void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex, return; } -/* --------------------------------------------------------------------- */ -/* Function : XGI_BacklightByDrv */ -/* Input : */ -/* Output : 1 -> Skip backlight control */ -/* Description : */ -/* --------------------------------------------------------------------- */ -static unsigned char XGI_BacklightByDrv(struct vb_device_info *pVBInfo) -{ - unsigned char tempah; - - tempah = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x3A); - if (tempah & BacklightControlBit) - return 1; - else - return 0; -} - -/* --------------------------------------------------------------------- */ -/* Function : XGI_FirePWDDisable */ -/* Input : */ -/* Output : */ -/* Description : Turn off VDD & Backlight : Fire disable procedure */ -/* --------------------------------------------------------------------- */ -/* -void XGI_FirePWDDisable(struct vb_device_info *pVBInfo) -{ - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x26, 0x00, 0xFC); -} -*/ - -/* --------------------------------------------------------------------- */ -/* Function : XGI_FirePWDEnable */ -/* Input : */ -/* Output : */ -/* Description : Turn on VDD & Backlight : Fire enable procedure */ -/* --------------------------------------------------------------------- */ -static void XGI_FirePWDEnable(struct vb_device_info *pVBInfo) -{ - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x26, 0x03, 0xFC); -} - static void XGI_EnableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { @@ -6334,54 +6293,6 @@ static void XGI_DisableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension, XGINew_SetRegANDOR(pVBInfo->P3d4, 0x63, 0xBF, 0x00); } -/* --------------------------------------------------------------------- */ -/* Function : XGI_SetPanelDelay */ -/* Input : */ -/* Output : */ -/* Description : */ -/* I/P : bl : 1 ; T1 : the duration between CPL on and signal on */ -/* : bl : 2 ; T2 : the duration signal on and Vdd on */ -/* : bl : 3 ; T3 : the duration between CPL off and signal off */ -/* : bl : 4 ; T4 : the duration signal off and Vdd off */ -/* --------------------------------------------------------------------- */ -static void XGI_SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBInfo) -{ - unsigned short index; - - index = XGI_GetLCDCapPtr(pVBInfo); - - if (tempbl == 1) - mdelay(pVBInfo->LCDCapList[index].PSC_S1); - - if (tempbl == 2) - mdelay(pVBInfo->LCDCapList[index].PSC_S2); - - if (tempbl == 3) - mdelay(pVBInfo->LCDCapList[index].PSC_S3); - - if (tempbl == 4) - mdelay(pVBInfo->LCDCapList[index].PSC_S4); -} - -/* --------------------------------------------------------------------- */ -/* Function : XGI_SetPanelPower */ -/* Input : */ -/* Output : */ -/* Description : */ -/* I/O : ah = 0011b = 03h ; Backlight on, Power on */ -/* = 0111b = 07h ; Backlight on, Power off */ -/* = 1011b = 0Bh ; Backlight off, Power on */ -/* = 1111b = 0Fh ; Backlight off, Power off */ -/* --------------------------------------------------------------------- */ -static void XGI_SetPanelPower(unsigned short tempah, unsigned short tempbl, - struct vb_device_info *pVBInfo) -{ - if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x26, tempbl, tempah); - else - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x11, tempbl, tempah); -} - /*----------------------------------------------------------------------------*/ /* input */ /* bl[5] : 1;LVDS signal on */ @@ -6951,29 +6862,6 @@ static unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo) return 0; } -static void XGI_EnablePWD(struct vb_device_info *pVBInfo) -{ - unsigned short index, temp; - - index = XGI_GetLCDCapPtr(pVBInfo); - temp = pVBInfo->LCDCapList[index].PWD_2B; - XGINew_SetReg1(pVBInfo->Part4Port, 0x2B, temp); - XGINew_SetReg1(pVBInfo->Part4Port, 0x2C, - pVBInfo->LCDCapList[index].PWD_2C); - XGINew_SetReg1(pVBInfo->Part4Port, 0x2D, - pVBInfo->LCDCapList[index].PWD_2D); - XGINew_SetReg1(pVBInfo->Part4Port, 0x2E, - pVBInfo->LCDCapList[index].PWD_2E); - XGINew_SetReg1(pVBInfo->Part4Port, 0x2F, - pVBInfo->LCDCapList[index].PWD_2F); - XGINew_SetRegOR(pVBInfo->Part4Port, 0x27, 0x80); /* enable PWD */ -} - -static void XGI_DisablePWD(struct vb_device_info *pVBInfo) -{ - XGINew_SetRegAND(pVBInfo->Part4Port, 0x27, 0x7F); /* disable PWD */ -} - /* --------------------------------------------------------------------- */ /* Function : XGI_DisableChISLCD */ /* Input : */ @@ -7031,37 +6919,11 @@ static unsigned char XGI_EnableChISLCD(struct vb_device_info *pVBInfo) void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - unsigned short tempax, tempbx, tempah = 0, tempbl = 0; + unsigned short tempah = 0; if (pVBInfo->SetFlag == Win9xDOSMode) return; - if (HwDeviceExtension->jChipType < XG40) { - if ((!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) - || (XGI_DisableChISLCD(pVBInfo))) { - if (!XGI_IsLCDON(pVBInfo)) { - if (pVBInfo->LCDInfo & SetPWDEnable) - XGI_EnablePWD(pVBInfo); - else { - pVBInfo->LCDInfo &= ~SetPWDEnable; - XGI_DisablePWD(pVBInfo); - if (pVBInfo->VBType & (VB_XGI301LV - | VB_XGI302LV - | VB_XGI301C)) { - tempbx = 0xFE; /* not 01h */ - tempax = 0; - } else { - tempbx = 0xF7; /* not 08h */ - tempax = 0x08; - } - XGI_SetPanelPower(tempax, tempbx, - pVBInfo); - XGI_SetPanelDelay(3, pVBInfo); - } - } /* end if (!XGI_IsLCDON(pVBInfo)) */ - } - } - /* if (CH7017) { if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2toLCDA)) || (XGI_DisableChISLCD(pVBInfo))) { @@ -7155,28 +7017,6 @@ void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, | SetSimuScanMode)) XGI_DisplayOff(HwDeviceExtension, pVBInfo); } - - if (HwDeviceExtension->jChipType < XG40) { - if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) - || (XGI_DisableChISLCD(pVBInfo)) - || (XGI_IsLCDON(pVBInfo))) { - if (pVBInfo->LCDInfo & SetPWDEnable) { - if (pVBInfo->LCDInfo & SetPWDEnable) - XGI_BacklightByDrv(pVBInfo); - else { - XGI_SetPanelDelay(4, pVBInfo); - if (pVBInfo->VBType & VB_XGI301LV) { - tempbl = 0xFD; - tempah = 0x00; - } else { - tempbl = 0xFB; - tempah = 0x04; - } - } - } - XGI_SetPanelPower(tempah, tempbl, pVBInfo); - } - } } /* --------------------------------------------------------------------- */ @@ -8220,7 +8060,7 @@ void XGI_SenseCRT1(struct vb_device_info *pVBInfo) void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - unsigned short tempbl, tempah; + unsigned short tempah; if (pVBInfo->SetFlag == Win9xDOSMode) { if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV @@ -8232,32 +8072,6 @@ void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, return; } - if (HwDeviceExtension->jChipType < XG40) { - if (!XGI_DisableChISLCD(pVBInfo)) { - if ((XGI_EnableChISLCD(pVBInfo)) || (pVBInfo->VBInfo - & (SetCRT2ToLCD | SetCRT2ToLCDA))) { - if (pVBInfo->LCDInfo & SetPWDEnable) { - XGI_EnablePWD(pVBInfo); - } else { - pVBInfo->LCDInfo &= (~SetPWDEnable); - if (pVBInfo->VBType & (VB_XGI301LV - | VB_XGI302LV - | VB_XGI301C)) { - tempbl = 0xFD; - tempah = 0x02; - } else { - tempbl = 0xFB; - tempah = 0x00; - } - - XGI_SetPanelPower(tempah, tempbl, - pVBInfo); - XGI_SetPanelDelay(1, pVBInfo); - } - } - } - } /* Not 340 */ - if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { if (!(pVBInfo->SetFlag & DisableChA)) { @@ -8376,32 +8190,6 @@ void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, XGINew_SetRegAND(pVBInfo->Part1Port, 0x00, 0x7F); XGI_DisplayOn(HwDeviceExtension, pVBInfo); } /* End of VB */ - - if (HwDeviceExtension->jChipType < XG40) { - if (!XGI_EnableChISLCD(pVBInfo)) { - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { - if (XGI_BacklightByDrv(pVBInfo)) - return; - } else - return; - } - - if (pVBInfo->LCDInfo & SetPWDEnable) { - XGI_FirePWDEnable(pVBInfo); - return; - } - - XGI_SetPanelDelay(2, pVBInfo); - - if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { - tempah = 0x01; - tempbl = 0xFE; /* turn on backlght */ - } else { - tempbl = 0xF7; - tempah = 0x00; - } - XGI_SetPanelPower(tempah, tempbl, pVBInfo); - } } static void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension, -- cgit v1.2.3 From 0658733528268ed055d1fd43fc5296b0ac98a7c2 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:10 +0200 Subject: staging: xgifb: eliminate redudant chip type >= XG40 checks Since all chips supported by the driver are >= XG40, these checks are redundant and the code can be modified accordingly. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 5 +-- drivers/staging/xgifb/vb_ext.c | 8 +---- drivers/staging/xgifb/vb_init.c | 70 +++++++++++++++---------------------- drivers/staging/xgifb/vb_setmode.c | 32 +++-------------- drivers/staging/xgifb/vb_table.h | 23 ------------ 5 files changed, 36 insertions(+), 102 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index b2cb7a3889a2..ed0d554d595b 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1502,10 +1502,7 @@ static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con, fix->line_length = xgi_video_info.video_linelength; fix->mmio_start = xgi_video_info.mmio_base; fix->mmio_len = xgi_video_info.mmio_size; - if (xgi_video_info.chip >= XG40) - fix->accel = FB_ACCEL_XGI_XABRE; - else - fix->accel = FB_ACCEL_XGI_GLAMOUR_2; + fix->accel = FB_ACCEL_XGI_XABRE; DEBUGPRN("end of get_fix"); return 0; diff --git a/drivers/staging/xgifb/vb_ext.c b/drivers/staging/xgifb/vb_ext.c index 6863fc229637..5cf094a64f23 100644 --- a/drivers/staging/xgifb/vb_ext.c +++ b/drivers/staging/xgifb/vb_ext.c @@ -383,13 +383,7 @@ unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *HwDeviceExtension, str /* unsigned short SoftSetting ; */ unsigned short temp; - if ((HwDeviceExtension->jChipType >= XG20) || (HwDeviceExtension->jChipType >= XG40)) - temp = 0; - else - temp = XGINew_GetPanelID(pVBInfo); - - if (!temp) - temp = XGINew_GetLCDDDCInfo(HwDeviceExtension, pVBInfo); + temp = XGINew_GetLCDDDCInfo(HwDeviceExtension, pVBInfo); return temp; } diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 10c0a3bcbbae..86d7333956db 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -1382,13 +1382,8 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) printk("8"); - if ((HwDeviceExtension->jChipType >= XG20) || (HwDeviceExtension->jChipType >= XG40)) { - for (i = 0x31; i <= 0x3B; i++) - XGINew_SetReg1(pVBInfo->P3c4, i, 0); - } else { - for (i = 0x31; i <= 0x3D; i++) - XGINew_SetReg1(pVBInfo->P3c4, i, 0); - } + for (i = 0x31; i <= 0x3B; i++) + XGINew_SetReg1(pVBInfo->P3c4, i, 0); printk("9"); if (HwDeviceExtension->jChipType == XG42) /* [Hsuan] 2004/08/20 Auto over driver for XG42 */ @@ -1407,7 +1402,6 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) /* 3.SetMemoryClock - if (HwDeviceExtension->jChipType >= XG40) XGINew_RAMType = (int)XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); */ @@ -1467,30 +1461,28 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) printk("13"); - if (HwDeviceExtension->jChipType >= XG40) { - /* Set AGP customize registers (in SetDefAGPRegs) Start */ - for (i = 0x47; i <= 0x4C; i++) - XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[i - 0x47]); - - for (i = 0x70; i <= 0x71; i++) - XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[6 + i - 0x70]); - - for (i = 0x74; i <= 0x77; i++) - XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[8 + i - 0x74]); - /* Set AGP customize registers (in SetDefAGPRegs) End */ - /* [Hsuan]2004/12/14 AGP Input Delay Adjustment on 850 */ - /* XGINew_SetReg4(0xcf8 , 0x80000000); */ - /* ChipsetID = XGINew_GetReg3(0x0cfc); */ - /* if (ChipsetID == 0x25308086) */ - /* XGINew_SetReg1(pVBInfo->P3d4, 0x77, 0xF0); */ - - HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension, 0x50, 0, &Temp); /* Get */ - Temp >>= 20; - Temp &= 0xF; - - if (Temp == 1) - XGINew_SetReg1(pVBInfo->P3d4, 0x48, 0x20); /* CR48 */ - } + /* Set AGP customize registers (in SetDefAGPRegs) Start */ + for (i = 0x47; i <= 0x4C; i++) + XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[i - 0x47]); + + for (i = 0x70; i <= 0x71; i++) + XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[6 + i - 0x70]); + + for (i = 0x74; i <= 0x77; i++) + XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[8 + i - 0x74]); + /* Set AGP customize registers (in SetDefAGPRegs) End */ + /* [Hsuan]2004/12/14 AGP Input Delay Adjustment on 850 */ + /* XGINew_SetReg4(0xcf8 , 0x80000000); */ + /* ChipsetID = XGINew_GetReg3(0x0cfc); */ + /* if (ChipsetID == 0x25308086) */ + /* XGINew_SetReg1(pVBInfo->P3d4, 0x77, 0xF0); */ + + HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension, 0x50, 0, &Temp); /* Get */ + Temp >>= 20; + Temp &= 0xF; + + if (Temp == 1) + XGINew_SetReg1(pVBInfo->P3d4, 0x48, 0x20); /* CR48 */ printk("14"); } /* != XG20 */ @@ -1529,7 +1521,6 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) printk("17"); /* - if (HwDeviceExtension->jChipType >= XG40) SetPowerConsume (HwDeviceExtension, pVBInfo->P3c4); */ if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */ @@ -1578,16 +1569,13 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) } printk("19"); - if (HwDeviceExtension->jChipType >= XG40) { - if (HwDeviceExtension->jChipType >= XG40) - XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); + XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); - XGINew_SetDRAMDefaultRegister340(HwDeviceExtension, pVBInfo->P3d4, pVBInfo); + XGINew_SetDRAMDefaultRegister340(HwDeviceExtension, pVBInfo->P3d4, pVBInfo); - printk("20"); - XGINew_SetDRAMSize_340(HwDeviceExtension, pVBInfo); - printk("21"); - } /* XG40 */ + printk("20"); + XGINew_SetDRAMSize_340(HwDeviceExtension, pVBInfo); + printk("21"); printk("22"); diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 4d5696349bcb..c9a97e631bc0 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -74,18 +74,8 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) /* XGINew_UBLCDDataTable = (struct XGI_LCDDataTablStruct *) XGI_LCDDataTable; */ /* XGINew_UBTVDataTable = (XGI_TVDataTablStruct *) XGI_TVDataTable; */ - if (ChipType >= XG40) { - pVBInfo->MCLKData - = (struct XGI_MCLKDataStruct *) XGI340New_MCLKData; - pVBInfo->ECLKData - = (struct XGI_ECLKDataStruct *) XGI340_ECLKData; - } else { - pVBInfo->MCLKData - = (struct XGI_MCLKDataStruct *) XGI330New_MCLKData; - pVBInfo->ECLKData - = (struct XGI_ECLKDataStruct *) XGI330_ECLKData; - } - + pVBInfo->MCLKData = (struct XGI_MCLKDataStruct *) XGI340New_MCLKData; + pVBInfo->ECLKData = (struct XGI_ECLKDataStruct *) XGI340_ECLKData; pVBInfo->VCLKData = (struct XGI_VCLKDataStruct *) XGI_VCLKData; pVBInfo->VBVCLKData = (struct XGI_VBVCLKDataStruct *) XGI_VBVCLKData; pVBInfo->ScreenOffset = XGI330_ScreenOffset; @@ -3291,15 +3281,7 @@ static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, if (!(temp & 0x20)) { temp = XGINew_GetReg1(pVBInfo->P3d4, 0x17); if (temp & 0x80) { - if ((HwDeviceExtension->jChipType >= XG20) - || (HwDeviceExtension->jChipType - >= XG40)) - temp = XGINew_GetReg1(pVBInfo->P3d4, - 0x53); - else - temp = XGINew_GetReg1(pVBInfo->P3d4, - 0x63); - + temp = XGINew_GetReg1(pVBInfo->P3d4, 0x53); if (!(temp & 0x40)) tempcl |= ActiveCRT1; } @@ -3377,7 +3359,7 @@ void XGI_GetVGAType(struct xgi_hw_device_info *HwDeviceExtension, /* if ( HwDeviceExtension->jChipType >= XG20 ) { pVBInfo->Set_VGAType = XG20; - } else if (HwDeviceExtension->jChipType >= XG40) { + } else { pVBInfo->Set_VGAType = VGA_XGI340; } */ @@ -8330,14 +8312,10 @@ unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension, pVBInfo->IF_DEF_HiVision = 0; pVBInfo->IF_DEF_CRT2Monitor = 0; pVBInfo->VBType = 0; /*set VBType default 0*/ - } else if (HwDeviceExtension->jChipType >= XG40) { - pVBInfo->IF_DEF_YPbPr = 1; - pVBInfo->IF_DEF_HiVision = 1; - pVBInfo->IF_DEF_CRT2Monitor = 1; } else { pVBInfo->IF_DEF_YPbPr = 1; pVBInfo->IF_DEF_HiVision = 1; - pVBInfo->IF_DEF_CRT2Monitor = 0; + pVBInfo->IF_DEF_CRT2Monitor = 1; } pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 78b1c796f01e..d71cd55a7057 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -1,17 +1,5 @@ #define Tap4 - -static struct XGI_MCLKDataStruct XGI330New_MCLKData[] = -{ - { 0x5c,0x23,0x01,166}, - { 0x5c,0x23,0x01,166}, - { 0x7C,0x08,0x80,200}, - { 0x79,0x06,0x80,250}, - { 0x29,0x01,0x81,300}, - { 0x29,0x01,0x81,300}, - { 0x29,0x01,0x81,300}, - { 0x29,0x01,0x81,300} -}; //yilin modify for xgi20 static struct XGI_MCLKDataStruct XGI340New_MCLKData[] = { @@ -37,17 +25,6 @@ static struct XGI_MCLKDataStruct XGI27New_MCLKData[] = { 0x5c,0x23,0x01,166} }; -static struct XGI_ECLKDataStruct XGI330_ECLKData[] = -{ - { 0x7c,0x08,0x01,200}, - { 0x7c,0x08,0x01,200}, - { 0x7C,0x08,0x80,200}, - { 0x79,0x06,0x80,250}, - { 0x29,0x01,0x81,300}, - { 0x29,0x01,0x81,300}, - { 0x29,0x01,0x81,300}, - { 0x29,0x01,0x81,300} -}; //yilin modify for xgi20 static struct XGI_ECLKDataStruct XGI340_ECLKData[] = { -- cgit v1.2.3 From 38583420d34a470f6dd7b66bfb84908ab29af399 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:11 +0200 Subject: staging: xgifb: delete unused LINUXBIOS code Delete unused LINUXBIOS code. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main.h | 2 -- drivers/staging/xgifb/XGI_main_26.c | 27 --------------------------- 2 files changed, 29 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index b27623a1578d..a014405cb448 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -9,8 +9,6 @@ #include "vb_struct.h" #include "vb_def.h" -//#define LINUXBIOS /* turn this on when compiling for LINUXBIOS */ - #define XGIFAIL(x) do { printk(x "\n"); return -EINVAL; } while(0) #define VER_MAJOR 0 diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index ed0d554d595b..79ff4df36a8c 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -2265,34 +2265,10 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, /* Mapping Max FB Size for 315 Init */ XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000); if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) { -#ifdef LINUXBIOS - printk("XGIfb: XGIInit() ..."); - /* XGIInitNewt for LINUXBIOS only */ - if (XGIInitNew(&XGIhw_ext)) - printk("OK\n"); - else - printk("Fail\n"); -#endif - outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD); } } -#ifdef LINUXBIOS - else { - XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000); - if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) { - - outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD); - - /* yilin Because no VBIOS DRAM Sizing, Dram size will error. */ - /* Set SR13 ,14 temporarily for UDtech */ - outXGIIDXREG(XGISR, 0x13, 0x45); - outXGIIDXREG(XGISR, 0x14, 0x51); - - } - } -#endif if (XGIfb_get_dram_size()) { printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n"); ret = -ENODEV; @@ -2459,7 +2435,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, XGIfb_detectedpdc = 0; XGIfb_detectedlcda = 0xff; -#ifndef LINUXBIOS /* TW: Try to find about LCDA */ @@ -2492,8 +2467,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, } -#endif - if (xgifb_mode_idx >= 0) xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx); -- cgit v1.2.3 From 8a1ed67b51911086c7c284dd1d43c2e699afd884 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:12 +0200 Subject: staging: xgifb: delete redundant extended register access enable The extended register access enable in !XGIvga_enabled case is not needed. The driver has enabled the access unconditionally already earlier in the routine. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 79ff4df36a8c..17f2aef30d16 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -2264,10 +2264,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, if (!XGIvga_enabled) { /* Mapping Max FB Size for 315 Init */ XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000); - if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) { - outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD); - - } } if (XGIfb_get_dram_size()) { printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n"); -- cgit v1.2.3 From 8277cf87bd676e3af869bb2c2c5249a215e2822c Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:13 +0200 Subject: staging: xgifb: delete incorrect I/O mapping If the PCI device was disabled when the probe() routine started, the driver will create 256 MB video memory mapping which is never used or properly released. It's also unsafe as the size is incorrect for many video cards. Deleting it also allows eliminating XGIvga_enable global variable. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main.h | 1 - drivers/staging/xgifb/XGI_main_26.c | 7 ------- 2 files changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index a014405cb448..46b5958ddf37 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -303,7 +303,6 @@ static u32 pseudo_palette[17]; static int XGIfb_off = 0; static int XGIfb_crt1off = 0; static int XGIfb_forcecrt1 = -1; -static int XGIvga_enabled = 0; static int XGIfb_userom = 0; //static int XGIfb_useoem = -1; diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 17f2aef30d16..3aec3f1dbe88 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -2163,7 +2163,6 @@ done: static int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - u16 reg16; u8 reg, reg1; u8 CR48, CR38; int ret; @@ -2180,9 +2179,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgi_video_info.chip_id = pdev->device; pci_read_config_byte(pdev, PCI_REVISION_ID, &xgi_video_info.revision_id); - pci_read_config_word(pdev, PCI_COMMAND, ®16); XGIhw_ext.jChipRevision = xgi_video_info.revision_id; - XGIvga_enabled = reg16 & 0x01; xgi_video_info.pcibus = pdev->bus->number; xgi_video_info.pcislot = PCI_SLOT(pdev->devfn); @@ -2261,10 +2258,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, } XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space; - if (!XGIvga_enabled) { - /* Mapping Max FB Size for 315 Init */ - XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000); - } if (XGIfb_get_dram_size()) { printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n"); ret = -ENODEV; -- cgit v1.2.3 From c83c620afabb582fa0d540aea1817724a5118c4f Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:14 +0200 Subject: staging: xgifb: use mdelay() for millisecond delays Use mdelay() instead of udelay() for millisecond delays. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 86d7333956db..856769664091 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -105,7 +105,7 @@ static void XGINew_DDR1x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBI XGINew_SetReg1(P3c4, 0x16, 0x80); if (*pVBInfo->pXGINew_DRAMTypeDefinition != 0x0C) { /* Samsung F Die */ - DelayUS(3000); /* Delay 67 x 3 Delay15us */ + mdelay(3); XGINew_SetReg1(P3c4, 0x18, 0x00); XGINew_SetReg1(P3c4, 0x19, 0x20); XGINew_SetReg1(P3c4, 0x16, 0x00); @@ -117,7 +117,7 @@ static void XGINew_DDR1x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBI XGINew_SetReg1(P3c4, 0x19, 0x01); XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[0]); XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[1]); - DelayUS(1000); + mdelay(1); XGINew_SetReg1(P3c4, 0x1B, 0x03); DelayUS(500); XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ @@ -292,7 +292,7 @@ static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVB XGINew_SetReg1(P3c4, 0x19, 0x01); XGINew_SetReg1(P3c4, 0x16, 0x03); XGINew_SetReg1(P3c4, 0x16, 0x83); - DelayUS(1000); + mdelay(1); XGINew_SetReg1(P3c4, 0x1B, 0x03); DelayUS(500); /* XGINew_SetReg1(P3c4, 0x18, 0x31); */ -- cgit v1.2.3 From c45715bb95527f69f9c741b05d1771b2a1e5eac9 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:15 +0200 Subject: staging: xgifb: replace DelayUS() with udelay() Replace DelayUS() with udelay(). Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 83 +++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 856769664091..22a3beaa64f9 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -39,11 +39,6 @@ static unsigned short XGINew_DDRDRAM_TYPE20[12][5] = { static int XGINew_RAMType; -static void DelayUS(unsigned long MicroSeconds) -{ - udelay(MicroSeconds); -} - static unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { @@ -75,7 +70,7 @@ static unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceE return data; } else if (HwDeviceExtension->jChipType == XG21) { XGINew_SetRegAND(pVBInfo->P3d4, 0xB4, ~0x02); /* Independent GPIO control */ - DelayUS(800); + udelay(800); XGINew_SetRegOR(pVBInfo->P3d4, 0x4A, 0x80); /* Enable GPIOH read */ temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); /* GPIOF 0:DVI 1:DVO */ /* HOTPLUG_SUPPORT */ @@ -112,14 +107,14 @@ static void XGINew_DDR1x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBI XGINew_SetReg1(P3c4, 0x16, 0x80); } - DelayUS(60); + udelay(60); XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ XGINew_SetReg1(P3c4, 0x19, 0x01); XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[0]); XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[1]); mdelay(1); XGINew_SetReg1(P3c4, 0x1B, 0x03); - DelayUS(500); + udelay(500); XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ XGINew_SetReg1(P3c4, 0x19, 0x00); XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[2]); @@ -164,65 +159,65 @@ static void XGINew_DDRII_Bootup_XG27( /* XGINew_SetReg1(P3d4, 0x97, 0x11); *//* CR97 */ XGINew_SetReg1(P3d4, 0x97, *pVBInfo->pXGINew_CR97); /* CR97 */ - DelayUS(200); + udelay(200); XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS2 */ XGINew_SetReg1(P3c4, 0x19, 0x80); /* Set SR19 */ XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ - DelayUS(15); + udelay(15); XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ - DelayUS(15); + udelay(15); XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS3 */ XGINew_SetReg1(P3c4, 0x19, 0xC0); /* Set SR19 */ XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ - DelayUS(15); + udelay(15); XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ - DelayUS(15); + udelay(15); XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS1 */ XGINew_SetReg1(P3c4, 0x19, 0x40); /* Set SR19 */ XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ - DelayUS(30); + udelay(30); XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ - DelayUS(15); + udelay(15); XGINew_SetReg1(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Enable */ XGINew_SetReg1(P3c4, 0x19, 0x0A); /* Set SR19 */ XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */ - DelayUS(30); + udelay(30); XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */ XGINew_SetReg1(P3c4, 0x16, 0x80); /* Set SR16 */ - /* DelayUS(15); */ + /* udelay(15); */ XGINew_SetReg1(P3c4, 0x1B, 0x04); /* Set SR1B */ - DelayUS(60); + udelay(60); XGINew_SetReg1(P3c4, 0x1B, 0x00); /* Set SR1B */ XGINew_SetReg1(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Reset */ XGINew_SetReg1(P3c4, 0x19, 0x08); /* Set SR19 */ XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */ - DelayUS(30); + udelay(30); XGINew_SetReg1(P3c4, 0x16, 0x83); /* Set SR16 */ - DelayUS(15); + udelay(15); XGINew_SetReg1(P3c4, 0x18, 0x80); /* Set SR18 */ /* MRS, ODT */ XGINew_SetReg1(P3c4, 0x19, 0x46); /* Set SR19 */ XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ - DelayUS(30); + udelay(30); XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ - DelayUS(15); + udelay(15); XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS */ XGINew_SetReg1(P3c4, 0x19, 0x40); /* Set SR19 */ XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ - DelayUS(30); + udelay(30); XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ - DelayUS(15); + udelay(15); XGINew_SetReg1(P3c4, 0x1B, 0x04); /* Set SR1B refresh control 000:close; 010:open */ - DelayUS(200); + udelay(200); } @@ -236,7 +231,7 @@ static void XGINew_DDR2_MRS_XG20(struct xgi_hw_device_info *HwDeviceExtension, XGINew_SetReg1(P3d4, 0x97, 0x11); /* CR97 */ - DelayUS(200); + udelay(200); XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS2 */ XGINew_SetReg1(P3c4, 0x19, 0x80); XGINew_SetReg1(P3c4, 0x16, 0x05); @@ -258,11 +253,11 @@ static void XGINew_DDR2_MRS_XG20(struct xgi_hw_device_info *HwDeviceExtension, XGINew_SetReg1(P3c4, 0x16, 0x05); XGINew_SetReg1(P3c4, 0x16, 0x85); - DelayUS(15); + udelay(15); XGINew_SetReg1(P3c4, 0x1B, 0x04); /* SR1B */ - DelayUS(30); + udelay(30); XGINew_SetReg1(P3c4, 0x1B, 0x00); /* SR1B */ - DelayUS(100); + udelay(100); /* XGINew_SetReg1(P3c4 ,0x18, 0x52); */ /* MRS2 */ XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */ @@ -270,7 +265,7 @@ static void XGINew_DDR2_MRS_XG20(struct xgi_hw_device_info *HwDeviceExtension, XGINew_SetReg1(P3c4, 0x16, 0x05); XGINew_SetReg1(P3c4, 0x16, 0x85); - DelayUS(200); + udelay(200); } static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo) @@ -280,13 +275,13 @@ static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVB XGINew_SetReg1(P3c4, 0x19, 0x40); XGINew_SetReg1(P3c4, 0x16, 0x00); XGINew_SetReg1(P3c4, 0x16, 0x80); - DelayUS(60); + udelay(60); XGINew_SetReg1(P3c4, 0x18, 0x00); XGINew_SetReg1(P3c4, 0x19, 0x40); XGINew_SetReg1(P3c4, 0x16, 0x00); XGINew_SetReg1(P3c4, 0x16, 0x80); - DelayUS(60); + udelay(60); XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ /* XGINew_SetReg1(P3c4, 0x18, 0x31); */ XGINew_SetReg1(P3c4, 0x19, 0x01); @@ -294,7 +289,7 @@ static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVB XGINew_SetReg1(P3c4, 0x16, 0x83); mdelay(1); XGINew_SetReg1(P3c4, 0x1B, 0x03); - DelayUS(500); + udelay(500); /* XGINew_SetReg1(P3c4, 0x18, 0x31); */ XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ XGINew_SetReg1(P3c4, 0x19, 0x00); @@ -522,7 +517,7 @@ static void XGINew_SetDRAMSizingType(int index, data = DRAMTYPE_TABLE[index][4]; XGINew_SetRegANDOR(pVBInfo->P3c4, 0x13, 0x80, data); - DelayUS(15); + udelay(15); /* should delay 50 ns */ } @@ -597,7 +592,7 @@ static unsigned short XGINew_SetDRAMSize20Reg(int index, /* [2004/03/25] Vicent, Fix DRAM Sizing Error */ XGINew_SetReg1(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0)); - DelayUS(15); + udelay(15); /* data |= XGINew_ChannelAB << 2; */ /* data |= (XGINew_DataBusWidth / 64) << 1; */ @@ -622,7 +617,7 @@ static int XGINew_ReadWriteRest(unsigned short StopAddr, *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position; } - DelayUS(500); /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */ + udelay(500); /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */ Position = 0; @@ -672,7 +667,7 @@ static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, XGINew_DataBusWidth = 32; /* 32 bits */ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 32bit */ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52); - DelayUS(15); + udelay(15); if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) return; @@ -680,7 +675,7 @@ static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) { XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* 22bit + 1 rank + 32bit */ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42); - DelayUS(15); + udelay(15); if (XGINew_ReadWriteRest(23, 23, pVBInfo) == 1) return; @@ -691,13 +686,13 @@ static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, XGINew_DataBusWidth = 16; /* 16 bits */ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 16bit */ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x41); - DelayUS(15); + udelay(15); if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) return; else XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); - DelayUS(15); + udelay(15); } } else { /* Dual_16_8 */ @@ -706,7 +701,7 @@ static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, XGINew_DataBusWidth = 16; /* 16 bits */ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x41); /* 0x41:16Mx16 bit*/ - DelayUS(15); + udelay(15); if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) return; @@ -714,7 +709,7 @@ static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x400000) { XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x31); /* 0x31:8Mx16 bit*/ - DelayUS(15); + udelay(15); if (XGINew_ReadWriteRest(22, 22, pVBInfo) == 1) return; @@ -725,13 +720,13 @@ static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, XGINew_DataBusWidth = 8; /* 8 bits */ XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */ XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x30); /* 0x30:8Mx8 bit*/ - DelayUS(15); + udelay(15); if (XGINew_ReadWriteRest(22, 21, pVBInfo) == 1) return; else XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */ - DelayUS(15); + udelay(15); } } break; -- cgit v1.2.3 From 0998e1db988658bb5ca660b4d929e1d2e7e8473e Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:16 +0200 Subject: staging: xgifb: vb_util: include the .h file Include the .h file and delete redundant definitions. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_util.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_util.c b/drivers/staging/xgifb/vb_util.c index 65b3954d8ff2..f542d6699d92 100644 --- a/drivers/staging/xgifb/vb_util.c +++ b/drivers/staging/xgifb/vb_util.c @@ -6,20 +6,7 @@ #include #include -void XGINew_SetReg1(unsigned long, unsigned short, unsigned short); -void XGINew_SetReg2(unsigned long, unsigned short, unsigned short); -void XGINew_SetReg3(unsigned long, unsigned short); -void XGINew_SetReg4(unsigned long, unsigned long); -unsigned char XGINew_GetReg1(unsigned long, unsigned short); -unsigned char XGINew_GetReg2(unsigned long); -unsigned long XGINew_GetReg3(unsigned long); -void XGINew_ClearDAC(unsigned char *); -void XGINew_SetRegANDOR(unsigned long Port, unsigned short Index, - unsigned short DataAND, unsigned short DataOR); -void XGINew_SetRegOR(unsigned long Port, unsigned short Index, - unsigned short DataOR); -void XGINew_SetRegAND(unsigned long Port, unsigned short Index, - unsigned short DataAND); +#include "vb_util.h" /* --------------------------------------------------------------------- */ /* Function : XGINew_SetReg1 */ -- cgit v1.2.3 From b649c827a90969f586a6595af9b9040b1f6b75b4 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:17 +0200 Subject: staging: xgifb: vb_util: delete commented-out code Delete commented-out code. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_util.c | 34 ---------------------------------- drivers/staging/xgifb/vb_util.h | 2 -- 2 files changed, 36 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_util.c b/drivers/staging/xgifb/vb_util.c index f542d6699d92..465bcda1e0c7 100644 --- a/drivers/staging/xgifb/vb_util.c +++ b/drivers/staging/xgifb/vb_util.c @@ -21,22 +21,6 @@ void XGINew_SetReg1(unsigned long port, unsigned short index, outb(data, port + 1); } -/* --------------------------------------------------------------------- */ -/* Function : XGINew_SetReg2 */ -/* Input : */ -/* Output : */ -/* Description : AR( 3C0 ) */ -/* --------------------------------------------------------------------- */ -/* -void XGINew_SetReg2(unsigned long port, unsigned short index, unsigned short data) -{ - InPortByte((P unsigned char)port + 0x3da - 0x3c0) ; - OutPortByte(XGINew_P3c0, index); - OutPortByte(XGINew_P3c0, data); - OutPortByte(XGINew_P3c0, 0x20); -} -*/ - void XGINew_SetReg3(unsigned long port, unsigned short data) { outb(data, port); @@ -103,21 +87,3 @@ void XGINew_SetRegOR(unsigned long Port, unsigned short Index, temp |= DataOR; XGINew_SetReg1(Port, Index, temp); } - -#if 0 -void NewDelaySeconds(int seconds) -{ - int i; - - for (i = 0; i < seconds; i++) { - - } -} - -void Newdebugcode(unsigned char code) -{ - /* OutPortByte(0x80, code); */ - /* OutPortByte(0x300, code); */ - /* NewDelaySeconds(0x3); */ -} -#endif diff --git a/drivers/staging/xgifb/vb_util.h b/drivers/staging/xgifb/vb_util.h index 156f6445c88d..bf5212755fd1 100644 --- a/drivers/staging/xgifb/vb_util.h +++ b/drivers/staging/xgifb/vb_util.h @@ -1,7 +1,5 @@ #ifndef _VBUTIL_ #define _VBUTIL_ -extern void NewDelaySeconds( int ); -extern void Newdebugcode(unsigned char); extern void XGINew_SetReg1(unsigned long, unsigned short, unsigned short); extern void XGINew_SetReg3(unsigned long, unsigned short); extern unsigned char XGINew_GetReg1(unsigned long, unsigned short); -- cgit v1.2.3 From d8ad0a6d29ed6203b4ddc3114a9adf5bd48ba45b Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:18 +0200 Subject: staging: xgifb: replace XGINew_GetReg2() with inb() Replace XGINew_GetReg2() with inb(). Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 50 +++++++++++++++++++------------------- drivers/staging/xgifb/vb_util.c | 9 ------- drivers/staging/xgifb/vb_util.h | 1 - 3 files changed, 25 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index c9a97e631bc0..32f06e8402b8 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -321,15 +321,15 @@ static void XGI_SetATTRegs(unsigned short ModeNo, unsigned short StandTableIndex } } - XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */ + inb(pVBInfo->P3da); /* reset 3da */ XGINew_SetReg3(pVBInfo->P3c0, i); /* set index */ XGINew_SetReg3(pVBInfo->P3c0, ARdata); /* set data */ } - XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */ + inb(pVBInfo->P3da); /* reset 3da */ XGINew_SetReg3(pVBInfo->P3c0, 0x14); /* set index */ XGINew_SetReg3(pVBInfo->P3c0, 0x00); /* set data */ - XGINew_GetReg2(pVBInfo->P3da); /* Enable Attribute */ + inb(pVBInfo->P3da); /* Enable Attribute */ XGINew_SetReg3(pVBInfo->P3c0, 0x20); } @@ -968,7 +968,7 @@ static void XGI_SetXG21LCD(struct vb_device_info *pVBInfo, XGINew_SetRegAND(pVBInfo->P3c4, 0x35, ~0x80); if (ModeNo <= 0x13) { - b3CC = (unsigned char) XGINew_GetReg2(XGI_P3cc); + b3CC = (unsigned char) inb(XGI_P3cc); if (b3CC & 0x40) XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */ if (b3CC & 0x80) @@ -1016,7 +1016,7 @@ static void XGI_SetXG27LCD(struct vb_device_info *pVBInfo, XGINew_SetRegAND(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */ if (ModeNo <= 0x13) { - b3CC = (unsigned char) XGINew_GetReg2(XGI_P3cc); + b3CC = (unsigned char) inb(XGI_P3cc); if (b3CC & 0x40) XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */ if (b3CC & 0x80) @@ -1355,7 +1355,7 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, } } } else { /* for CRT2 */ - VCLKIndex = (unsigned char) XGINew_GetReg2( + VCLKIndex = (unsigned char) inb( (pVBInfo->P3ca + 0x02)); /* Port 3cch */ VCLKIndex = ((VCLKIndex >> 2) & 0x03); if (ModeNo > 0x13) { @@ -3204,7 +3204,7 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, } - tempal = (unsigned char) XGINew_GetReg2((pVBInfo->P3ca + 0x02)); + tempal = (unsigned char) inb((pVBInfo->P3ca + 0x02)); tempal = tempal >> 2; tempal &= 0x03; @@ -4190,18 +4190,18 @@ void XGI_DisplayOff(struct xgi_hw_device_info *pXGIHWDE, static void XGI_WaitDisply(struct vb_device_info *pVBInfo) { - while ((XGINew_GetReg2(pVBInfo->P3da) & 0x01)) + while ((inb(pVBInfo->P3da) & 0x01)) break; - while (!(XGINew_GetReg2(pVBInfo->P3da) & 0x01)) + while (!(inb(pVBInfo->P3da) & 0x01)) break; } #if 0 static void XGI_WaitDisplay(struct vb_device_info *pVBInfo) { - while (!(XGINew_GetReg2(pVBInfo->P3da) & 0x01)); - while (XGINew_GetReg2(pVBInfo->P3da) & 0x01); + while (!(inb(pVBInfo->P3da) & 0x01)); + while (inb(pVBInfo->P3da) & 0x01); } #endif @@ -6469,7 +6469,7 @@ static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde temp = (unsigned char) ((pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & (LCDPolarity << 8)) >> 8); temp &= LCDPolarity; - Miscdata = (unsigned char) XGINew_GetReg2(pVBInfo->P3cc); + Miscdata = (unsigned char) inb(pVBInfo->P3cc); XGINew_SetReg3(pVBInfo->P3c2, (Miscdata & 0x3F) | temp); @@ -6628,14 +6628,14 @@ static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde } if (!(modeflag & Charx8Dot)) { - XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */ + inb(pVBInfo->P3da); /* reset 3da */ XGINew_SetReg3(pVBInfo->P3c0, 0x13); /* set index */ XGINew_SetReg3(pVBInfo->P3c0, 0x00); /* set data, panning = 0, shift left 1 dot*/ - XGINew_GetReg2(pVBInfo->P3da); /* Enable Attribute */ + inb(pVBInfo->P3da); /* Enable Attribute */ XGINew_SetReg3(pVBInfo->P3c0, 0x20); - XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */ + inb(pVBInfo->P3da); /* reset 3da */ } } @@ -6654,7 +6654,7 @@ static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde temp = (unsigned char) ((pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & (LCDPolarity << 8)) >> 8); temp &= LCDPolarity; - Miscdata = (unsigned char) XGINew_GetReg2(pVBInfo->P3cc); + Miscdata = (unsigned char) inb(pVBInfo->P3cc); XGINew_SetReg3(pVBInfo->P3c2, (Miscdata & 0x3F) | temp); @@ -6812,14 +6812,14 @@ static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde } if (!(modeflag & Charx8Dot)) { - XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */ + inb(pVBInfo->P3da); /* reset 3da */ XGINew_SetReg3(pVBInfo->P3c0, 0x13); /* set index */ XGINew_SetReg3(pVBInfo->P3c0, 0x00); /* set data, panning = 0, shift left 1 dot*/ - XGINew_GetReg2(pVBInfo->P3da); /* Enable Attribute */ + inb(pVBInfo->P3da); /* Enable Attribute */ XGINew_SetReg3(pVBInfo->P3c0, 0x20); - XGINew_GetReg2(pVBInfo->P3da); /* reset 3da */ + inb(pVBInfo->P3da); /* reset 3da */ } } @@ -7716,12 +7716,12 @@ void XGI_LongWait(struct vb_device_info *pVBInfo) if (!(i & 0xC0)) { for (i = 0; i < 0xFFFF; i++) { - if (!(XGINew_GetReg2(pVBInfo->P3da) & 0x08)) + if (!(inb(pVBInfo->P3da) & 0x08)) break; } for (i = 0; i < 0xFFFF; i++) { - if ((XGINew_GetReg2(pVBInfo->P3da) & 0x08)) + if ((inb(pVBInfo->P3da) & 0x08)) break; } } @@ -7735,7 +7735,7 @@ static void XGI_VBLongWait(struct vb_device_info *pVBInfo) temp = 0; for (i = 0; i < 3; i++) { for (j = 0; j < 100; j++) { - tempal = XGINew_GetReg2(pVBInfo->P3da); + tempal = inb(pVBInfo->P3da); if (temp & 0x01) { /* VBWaitMode2 */ if ((tempal & 0x08)) continue; @@ -8013,7 +8013,7 @@ void XGI_SenseCRT1(struct vb_device_info *pVBInfo) mdelay(1); XGI_WaitDisply(pVBInfo); - temp = XGINew_GetReg2(pVBInfo->P3c2); + temp = inb(pVBInfo->P3c2); if (temp & 0x10) XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xDF, 0x20); @@ -8230,13 +8230,13 @@ static void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension, if ((ModeNo == 0x00) | (ModeNo == 0x01)) { XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x4E); XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE9); - b3CC = (unsigned char) XGINew_GetReg2(XGINew_P3cc); + b3CC = (unsigned char) inb(XGINew_P3cc); XGINew_SetReg3(XGINew_P3cc, (b3CC |= 0x0C)); } else if ((ModeNo == 0x04) | (ModeNo == 0x05) | (ModeNo == 0x0D)) { XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x1B); XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE3); - b3CC = (unsigned char) XGINew_GetReg2(XGINew_P3cc); + b3CC = (unsigned char) inb(XGINew_P3cc); XGINew_SetReg3(XGINew_P3cc, (b3CC |= 0x0C)); } } diff --git a/drivers/staging/xgifb/vb_util.c b/drivers/staging/xgifb/vb_util.c index 465bcda1e0c7..299f05c422f5 100644 --- a/drivers/staging/xgifb/vb_util.c +++ b/drivers/staging/xgifb/vb_util.c @@ -40,15 +40,6 @@ unsigned char XGINew_GetReg1(unsigned long port, unsigned short index) return data; } -unsigned char XGINew_GetReg2(unsigned long port) -{ - unsigned char data; - - data = inb(port); - - return data; -} - unsigned long XGINew_GetReg3(unsigned long port) { unsigned long data; diff --git a/drivers/staging/xgifb/vb_util.h b/drivers/staging/xgifb/vb_util.h index bf5212755fd1..e211320607cc 100644 --- a/drivers/staging/xgifb/vb_util.h +++ b/drivers/staging/xgifb/vb_util.h @@ -3,7 +3,6 @@ extern void XGINew_SetReg1(unsigned long, unsigned short, unsigned short); extern void XGINew_SetReg3(unsigned long, unsigned short); extern unsigned char XGINew_GetReg1(unsigned long, unsigned short); -extern unsigned char XGINew_GetReg2(unsigned long); extern void XGINew_SetReg4(unsigned long, unsigned long); extern unsigned long XGINew_GetReg3(unsigned long); extern void XGINew_SetRegOR(unsigned long Port,unsigned short Index,unsigned short DataOR); -- cgit v1.2.3 From f5b571fa24f523265b6bf9a282e0aa7eeff8098a Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:19 +0200 Subject: staging: xgifb: replace XGINew_GetReg3() with inl() Replace XGINew_GetReg3() with inl(). Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 8 ++++---- drivers/staging/xgifb/vb_util.c | 9 --------- drivers/staging/xgifb/vb_util.h | 1 - 3 files changed, 4 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 22a3beaa64f9..0c9e2777e05a 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -1428,12 +1428,12 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) temp1 &= 0x02; if (temp1 == 0x02) { XGINew_SetReg4(0xcf8, 0x80000000); - ChipsetID = XGINew_GetReg3(0x0cfc); + ChipsetID = inl(0x0cfc); XGINew_SetReg4(0xcf8, 0x8000002C); - VendorID = XGINew_GetReg3(0x0cfc); + VendorID = inl(0x0cfc); VendorID &= 0x0000FFFF; XGINew_SetReg4(0xcf8, 0x8001002C); - GraphicVendorID = XGINew_GetReg3(0x0cfc); + GraphicVendorID = inl(0x0cfc); GraphicVendorID &= 0x0000FFFF; if (ChipsetID == 0x7301039) @@ -1468,7 +1468,7 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) /* Set AGP customize registers (in SetDefAGPRegs) End */ /* [Hsuan]2004/12/14 AGP Input Delay Adjustment on 850 */ /* XGINew_SetReg4(0xcf8 , 0x80000000); */ - /* ChipsetID = XGINew_GetReg3(0x0cfc); */ + /* ChipsetID = inl(0x0cfc); */ /* if (ChipsetID == 0x25308086) */ /* XGINew_SetReg1(pVBInfo->P3d4, 0x77, 0xF0); */ diff --git a/drivers/staging/xgifb/vb_util.c b/drivers/staging/xgifb/vb_util.c index 299f05c422f5..be6224e373e8 100644 --- a/drivers/staging/xgifb/vb_util.c +++ b/drivers/staging/xgifb/vb_util.c @@ -40,15 +40,6 @@ unsigned char XGINew_GetReg1(unsigned long port, unsigned short index) return data; } -unsigned long XGINew_GetReg3(unsigned long port) -{ - unsigned long data; - - data = inl(port); - - return data; -} - void XGINew_SetRegANDOR(unsigned long Port, unsigned short Index, unsigned short DataAND, unsigned short DataOR) { diff --git a/drivers/staging/xgifb/vb_util.h b/drivers/staging/xgifb/vb_util.h index e211320607cc..b35c63d11264 100644 --- a/drivers/staging/xgifb/vb_util.h +++ b/drivers/staging/xgifb/vb_util.h @@ -4,7 +4,6 @@ extern void XGINew_SetReg1(unsigned long, unsigned short, unsigned short); extern void XGINew_SetReg3(unsigned long, unsigned short); extern unsigned char XGINew_GetReg1(unsigned long, unsigned short); extern void XGINew_SetReg4(unsigned long, unsigned long); -extern unsigned long XGINew_GetReg3(unsigned long); extern void XGINew_SetRegOR(unsigned long Port,unsigned short Index,unsigned short DataOR); extern void XGINew_SetRegAND(unsigned long Port,unsigned short Index,unsigned short DataAND); extern void XGINew_SetRegANDOR(unsigned long Port,unsigned short Index,unsigned short DataAND,unsigned short DataOR); -- cgit v1.2.3 From efdf4ee78cd5eb1172955a63fff1e6f6748a41d9 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:20 +0200 Subject: staging: xgifb: replace XGINew_SetReg3() with outb() Replace XGINew_SetReg3() with outb(). Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 2 +- drivers/staging/xgifb/vb_setmode.c | 67 ++++++++++++++++++-------------------- drivers/staging/xgifb/vb_util.c | 5 --- drivers/staging/xgifb/vb_util.h | 1 - 4 files changed, 33 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 0c9e2777e05a..46ccdf1b3a44 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -1313,7 +1313,7 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) } printk("2"); - XGINew_SetReg3((pVBInfo->BaseAddr + 0x12), 0x67); /* 3c2 <- 67 ,ynlai */ + outb(0x67, (pVBInfo->BaseAddr + 0x12)); /* 3c2 <- 67 ,ynlai */ pVBInfo->ISXPDOS = 0; printk("3"); diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 32f06e8402b8..b4f211297564 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -265,7 +265,7 @@ static void XGI_SetMiscRegs(unsigned short StandTableIndex, } */ - XGINew_SetReg3(pVBInfo->P3c2, Miscdata); /* Set Misc(3c2) */ + outb(Miscdata, pVBInfo->P3c2); /* Set Misc(3c2) */ } static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, @@ -322,15 +322,15 @@ static void XGI_SetATTRegs(unsigned short ModeNo, unsigned short StandTableIndex } inb(pVBInfo->P3da); /* reset 3da */ - XGINew_SetReg3(pVBInfo->P3c0, i); /* set index */ - XGINew_SetReg3(pVBInfo->P3c0, ARdata); /* set data */ + outb(i, pVBInfo->P3c0); /* set index */ + outb(ARdata, pVBInfo->P3c0); /* set data */ } inb(pVBInfo->P3da); /* reset 3da */ - XGINew_SetReg3(pVBInfo->P3c0, 0x14); /* set index */ - XGINew_SetReg3(pVBInfo->P3c0, 0x00); /* set data */ + outb(0x14, pVBInfo->P3c0); /* set index */ + outb(0x00, pVBInfo->P3c0); /* set data */ inb(pVBInfo->P3da); /* Enable Attribute */ - XGINew_SetReg3(pVBInfo->P3c0, 0x20); + outb(0x20, pVBInfo->P3c0); } static void XGI_SetGRCRegs(unsigned short StandTableIndex, @@ -525,7 +525,7 @@ static void XGI_SetSync(unsigned short RefreshRateTableIndex, sync &= 0xC0; temp = 0x2F; temp |= sync; - XGINew_SetReg3(pVBInfo->P3c2, temp); /* Set Misc(3c2) */ + outb(temp, pVBInfo->P3c2); /* Set Misc(3c2) */ } static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, @@ -1734,9 +1734,9 @@ static void XGI_WriteDAC(unsigned short dl, unsigned short ah, unsigned short al bh = temp; } } - XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) dh); - XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) bh); - XGINew_SetReg3(pVBInfo->P3c9, (unsigned short) bl); + outb((unsigned short) dh, pVBInfo->P3c9); + outb((unsigned short) bh, pVBInfo->P3c9); + outb((unsigned short) bl, pVBInfo->P3c9); } static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex, @@ -1769,8 +1769,8 @@ static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex, else j = time; - XGINew_SetReg3(pVBInfo->P3c6, 0xFF); - XGINew_SetReg3(pVBInfo->P3c8, 0x00); + outb(0xFF, pVBInfo->P3c6); + outb(0x00, pVBInfo->P3c8); for (i = 0; i < j; i++) { data = table[i]; @@ -1784,7 +1784,7 @@ static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex, if (data & 0x02) data2 += 0x15; - XGINew_SetReg3(pVBInfo->P3c9, data2); + outb(data2, pVBInfo->P3c9); data = data >> 2; } } @@ -1794,7 +1794,7 @@ static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex, data = table[i]; for (k = 0; k < 3; k++) - XGINew_SetReg3(pVBInfo->P3c9, data); + outb(data, pVBInfo->P3c9); } si = 32; @@ -6471,7 +6471,7 @@ static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde temp &= LCDPolarity; Miscdata = (unsigned char) inb(pVBInfo->P3cc); - XGINew_SetReg3(pVBInfo->P3c2, (Miscdata & 0x3F) | temp); + outb((Miscdata & 0x3F) | temp, pVBInfo->P3c2); temp = (unsigned char) (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & LCDPolarity); @@ -6629,11 +6629,11 @@ static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde if (!(modeflag & Charx8Dot)) { inb(pVBInfo->P3da); /* reset 3da */ - XGINew_SetReg3(pVBInfo->P3c0, 0x13); /* set index */ - XGINew_SetReg3(pVBInfo->P3c0, 0x00); /* set data, panning = 0, shift left 1 dot*/ + outb(0x13, pVBInfo->P3c0); /* set index */ + outb(0x00, pVBInfo->P3c0); /* set data, panning = 0, shift left 1 dot*/ inb(pVBInfo->P3da); /* Enable Attribute */ - XGINew_SetReg3(pVBInfo->P3c0, 0x20); + outb(0x20, pVBInfo->P3c0); inb(pVBInfo->P3da); /* reset 3da */ } @@ -6656,7 +6656,7 @@ static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde temp &= LCDPolarity; Miscdata = (unsigned char) inb(pVBInfo->P3cc); - XGINew_SetReg3(pVBInfo->P3c2, (Miscdata & 0x3F) | temp); + outb((Miscdata & 0x3F) | temp, pVBInfo->P3c2); temp = (unsigned char) (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & LCDPolarity); @@ -6813,11 +6813,11 @@ static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde if (!(modeflag & Charx8Dot)) { inb(pVBInfo->P3da); /* reset 3da */ - XGINew_SetReg3(pVBInfo->P3c0, 0x13); /* set index */ - XGINew_SetReg3(pVBInfo->P3c0, 0x00); /* set data, panning = 0, shift left 1 dot*/ + outb(0x13, pVBInfo->P3c0); /* set index */ + outb(0x00, pVBInfo->P3c0); /* set data, panning = 0, shift left 1 dot*/ inb(pVBInfo->P3da); /* Enable Attribute */ - XGINew_SetReg3(pVBInfo->P3c0, 0x20); + outb(0x20, pVBInfo->P3c0); inb(pVBInfo->P3da); /* reset 3da */ } @@ -7995,15 +7995,12 @@ void XGI_SenseCRT1(struct vb_device_info *pVBInfo) XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x1B); XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE1); - XGINew_SetReg3(pVBInfo->P3c8, 0x00); + outb(0x00, pVBInfo->P3c8); for (i = 0; i < 256; i++) { - XGINew_SetReg3((pVBInfo->P3c8 + 1), - (unsigned char) DAC_TEST_PARMS[0]); - XGINew_SetReg3((pVBInfo->P3c8 + 1), - (unsigned char) DAC_TEST_PARMS[1]); - XGINew_SetReg3((pVBInfo->P3c8 + 1), - (unsigned char) DAC_TEST_PARMS[2]); + outb((unsigned char) DAC_TEST_PARMS[0], (pVBInfo->P3c8 + 1)); + outb((unsigned char) DAC_TEST_PARMS[1], (pVBInfo->P3c8 + 1)); + outb((unsigned char) DAC_TEST_PARMS[2], (pVBInfo->P3c8 + 1)); } XGI_VBLongWait(pVBInfo); @@ -8021,12 +8018,12 @@ void XGI_SenseCRT1(struct vb_device_info *pVBInfo) XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xDF, 0x00); /* alan, avoid display something, set BLACK DAC if not restore DAC */ - XGINew_SetReg3(pVBInfo->P3c8, 0x00); + outb(0x00, pVBInfo->P3c8); for (i = 0; i < 256; i++) { - XGINew_SetReg3((pVBInfo->P3c8 + 1), 0); - XGINew_SetReg3((pVBInfo->P3c8 + 1), 0); - XGINew_SetReg3((pVBInfo->P3c8 + 1), 0); + outb(0, (pVBInfo->P3c8 + 1)); + outb(0, (pVBInfo->P3c8 + 1)); + outb(0, (pVBInfo->P3c8 + 1)); } XGINew_SetReg1(pVBInfo->P3c4, 0x01, SR01); @@ -8231,13 +8228,13 @@ static void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension, XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x4E); XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE9); b3CC = (unsigned char) inb(XGINew_P3cc); - XGINew_SetReg3(XGINew_P3cc, (b3CC |= 0x0C)); + outb((b3CC |= 0x0C), XGINew_P3cc); } else if ((ModeNo == 0x04) | (ModeNo == 0x05) | (ModeNo == 0x0D)) { XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x1B); XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE3); b3CC = (unsigned char) inb(XGINew_P3cc); - XGINew_SetReg3(XGINew_P3cc, (b3CC |= 0x0C)); + outb((b3CC |= 0x0C), XGINew_P3cc); } } diff --git a/drivers/staging/xgifb/vb_util.c b/drivers/staging/xgifb/vb_util.c index be6224e373e8..064580eb895b 100644 --- a/drivers/staging/xgifb/vb_util.c +++ b/drivers/staging/xgifb/vb_util.c @@ -21,11 +21,6 @@ void XGINew_SetReg1(unsigned long port, unsigned short index, outb(data, port + 1); } -void XGINew_SetReg3(unsigned long port, unsigned short data) -{ - outb(data, port); -} - void XGINew_SetReg4(unsigned long port, unsigned long data) { outl(data, port); diff --git a/drivers/staging/xgifb/vb_util.h b/drivers/staging/xgifb/vb_util.h index b35c63d11264..a67f72009056 100644 --- a/drivers/staging/xgifb/vb_util.h +++ b/drivers/staging/xgifb/vb_util.h @@ -1,7 +1,6 @@ #ifndef _VBUTIL_ #define _VBUTIL_ extern void XGINew_SetReg1(unsigned long, unsigned short, unsigned short); -extern void XGINew_SetReg3(unsigned long, unsigned short); extern unsigned char XGINew_GetReg1(unsigned long, unsigned short); extern void XGINew_SetReg4(unsigned long, unsigned long); extern void XGINew_SetRegOR(unsigned long Port,unsigned short Index,unsigned short DataOR); -- cgit v1.2.3 From 3d2a60a29ed4c36a09955dddc27e503de5a5041a Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:21 +0200 Subject: staging: xgifb: replace XGINew_SetReg4() with outl() Replace XGINew_SetReg4() with outl(). Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 8 ++++---- drivers/staging/xgifb/vb_util.c | 5 ----- drivers/staging/xgifb/vb_util.h | 1 - 3 files changed, 4 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 46ccdf1b3a44..577f7de0b9e9 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -1427,12 +1427,12 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) temp1 = XGINew_GetReg1(pVBInfo->P3c4, 0x3B); temp1 &= 0x02; if (temp1 == 0x02) { - XGINew_SetReg4(0xcf8, 0x80000000); + outl(0x80000000, 0xcf8); ChipsetID = inl(0x0cfc); - XGINew_SetReg4(0xcf8, 0x8000002C); + outl(0x8000002C, 0xcf8); VendorID = inl(0x0cfc); VendorID &= 0x0000FFFF; - XGINew_SetReg4(0xcf8, 0x8001002C); + outl(0x8001002C, 0xcf8); GraphicVendorID = inl(0x0cfc); GraphicVendorID &= 0x0000FFFF; @@ -1467,7 +1467,7 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[8 + i - 0x74]); /* Set AGP customize registers (in SetDefAGPRegs) End */ /* [Hsuan]2004/12/14 AGP Input Delay Adjustment on 850 */ - /* XGINew_SetReg4(0xcf8 , 0x80000000); */ + /* outl(0x80000000, 0xcf8); */ /* ChipsetID = inl(0x0cfc); */ /* if (ChipsetID == 0x25308086) */ /* XGINew_SetReg1(pVBInfo->P3d4, 0x77, 0xF0); */ diff --git a/drivers/staging/xgifb/vb_util.c b/drivers/staging/xgifb/vb_util.c index 064580eb895b..a919fd69120d 100644 --- a/drivers/staging/xgifb/vb_util.c +++ b/drivers/staging/xgifb/vb_util.c @@ -21,11 +21,6 @@ void XGINew_SetReg1(unsigned long port, unsigned short index, outb(data, port + 1); } -void XGINew_SetReg4(unsigned long port, unsigned long data) -{ - outl(data, port); -} - unsigned char XGINew_GetReg1(unsigned long port, unsigned short index) { unsigned char data; diff --git a/drivers/staging/xgifb/vb_util.h b/drivers/staging/xgifb/vb_util.h index a67f72009056..7049fc7241cf 100644 --- a/drivers/staging/xgifb/vb_util.h +++ b/drivers/staging/xgifb/vb_util.h @@ -2,7 +2,6 @@ #define _VBUTIL_ extern void XGINew_SetReg1(unsigned long, unsigned short, unsigned short); extern unsigned char XGINew_GetReg1(unsigned long, unsigned short); -extern void XGINew_SetReg4(unsigned long, unsigned long); extern void XGINew_SetRegOR(unsigned long Port,unsigned short Index,unsigned short DataOR); extern void XGINew_SetRegAND(unsigned long Port,unsigned short Index,unsigned short DataAND); extern void XGINew_SetRegANDOR(unsigned long Port,unsigned short Index,unsigned short DataAND,unsigned short DataOR); -- cgit v1.2.3 From 8104e32996be6099379176b5a7e2d99eecc2df64 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:22 +0200 Subject: staging: xgifb: rename XGINew_SetReg1() to xgifb_reg_set() Rename XGINew_SetReg1() to xgifb_reg_set(). Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 2 +- drivers/staging/xgifb/vb_ext.c | 16 +- drivers/staging/xgifb/vb_init.c | 584 +++++++++++++++--------------- drivers/staging/xgifb/vb_setmode.c | 702 ++++++++++++++++++------------------ drivers/staging/xgifb/vb_util.c | 14 +- drivers/staging/xgifb/vb_util.h | 2 +- 6 files changed, 657 insertions(+), 663 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 3aec3f1dbe88..721bd25fe542 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -2321,7 +2321,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) { if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) && (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) { - XGINew_SetReg1(XGI_Pr.P3d4, 0x36, m); + xgifb_reg_set(XGI_Pr.P3d4, 0x36, m); } } } diff --git a/drivers/staging/xgifb/vb_ext.c b/drivers/staging/xgifb/vb_ext.c index 5cf094a64f23..a2998645fa1e 100644 --- a/drivers/staging/xgifb/vb_ext.c +++ b/drivers/staging/xgifb/vb_ext.c @@ -31,7 +31,7 @@ static unsigned char XGINew_Sense(unsigned short tempbx, unsigned short tempcx, unsigned short temp, i, tempch; temp = tempbx & 0xFF; - XGINew_SetReg1(pVBInfo->Part4Port, 0x11, temp); + xgifb_reg_set(pVBInfo->Part4Port, 0x11, temp); temp = (tempbx & 0xFF00) >> 8; temp |= (tempcx & 0x00FF); XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x10, ~0x1F, temp); @@ -143,7 +143,7 @@ static unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo) tempbx = tempbx >> 1; temp = tempbx & 0x00F; - XGINew_SetReg1(pVBInfo->P3d4, 0x36, temp); + xgifb_reg_set(pVBInfo->P3d4, 0x36, temp); tempbx--; tempbx = PanelTypeTable[tempbx]; @@ -179,7 +179,7 @@ static unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtensi tempcx = 0x0604; temp = tempbx & 0xFF; - XGINew_SetReg1(pVBInfo->Part4Port, 0x11, temp); + xgifb_reg_set(pVBInfo->Part4Port, 0x11, temp); temp = (tempbx & 0xFF00) >> 8; temp |= (tempcx & 0x00FF); XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x10, ~0x1F, temp); @@ -199,7 +199,7 @@ static unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtensi tempcx = 0x0804; temp = tempbx & 0xFF; - XGINew_SetReg1(pVBInfo->Part4Port, 0x11, temp); + xgifb_reg_set(pVBInfo->Part4Port, 0x11, temp); temp = (tempbx & 0xFF00) >> 8; temp |= (tempcx & 0x00FF); XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x10, ~0x1F, temp); @@ -218,7 +218,7 @@ static unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtensi tempbx = 0x3FF; tempcx = 0x0804; temp = tempbx & 0xFF; - XGINew_SetReg1(pVBInfo->Part4Port, 0x11, temp); + xgifb_reg_set(pVBInfo->Part4Port, 0x11, temp); temp = (tempbx & 0xFF00) >> 8; temp |= (tempcx & 0x00FF); XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x10, ~0x1F, temp); @@ -276,7 +276,7 @@ void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_ P2reg0 = XGINew_GetReg1(pVBInfo->Part2Port, 0x00); if (!XGINew_BridgeIsEnable(HwDeviceExtension, pVBInfo)) { SenseModeNo = 0x2e; - /* XGINew_SetReg1(pVBInfo->P3d4, 0x30, 0x41); */ + /* xgifb_reg_set(pVBInfo->P3d4, 0x30, 0x41); */ /* XGISetModeNew(HwDeviceExtension, 0x2e); // ynlai InitMode */ temp = XGI_SearchModeID(SenseModeNo, &ModeIdIndex, pVBInfo); @@ -295,7 +295,7 @@ void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_ for (i = 0; i < 20; i++) XGI_LongWait(pVBInfo); } - XGINew_SetReg1(pVBInfo->Part2Port, 0x00, 0x1c); + xgifb_reg_set(pVBInfo->Part2Port, 0x00, 0x1c); tempax = 0; tempbx = *pVBInfo->pRGBSenseData; @@ -366,7 +366,7 @@ void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_ XGINew_Sense(tempbx, tempcx, pVBInfo); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~0xDF, tempax); - XGINew_SetReg1(pVBInfo->Part2Port, 0x00, P2reg0); + xgifb_reg_set(pVBInfo->Part2Port, 0x00, P2reg0); if (!(P2reg0 & 0x20)) { pVBInfo->VBInfo = DisableCRT2Display; diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 577f7de0b9e9..07fa73dec794 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -94,45 +94,45 @@ static unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceE static void XGINew_DDR1x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBInfo) { - XGINew_SetReg1(P3c4, 0x18, 0x01); - XGINew_SetReg1(P3c4, 0x19, 0x20); - XGINew_SetReg1(P3c4, 0x16, 0x00); - XGINew_SetReg1(P3c4, 0x16, 0x80); + xgifb_reg_set(P3c4, 0x18, 0x01); + xgifb_reg_set(P3c4, 0x19, 0x20); + xgifb_reg_set(P3c4, 0x16, 0x00); + xgifb_reg_set(P3c4, 0x16, 0x80); if (*pVBInfo->pXGINew_DRAMTypeDefinition != 0x0C) { /* Samsung F Die */ mdelay(3); - XGINew_SetReg1(P3c4, 0x18, 0x00); - XGINew_SetReg1(P3c4, 0x19, 0x20); - XGINew_SetReg1(P3c4, 0x16, 0x00); - XGINew_SetReg1(P3c4, 0x16, 0x80); + xgifb_reg_set(P3c4, 0x18, 0x00); + xgifb_reg_set(P3c4, 0x19, 0x20); + xgifb_reg_set(P3c4, 0x16, 0x00); + xgifb_reg_set(P3c4, 0x16, 0x80); } udelay(60); - XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ - XGINew_SetReg1(P3c4, 0x19, 0x01); - XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[0]); - XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[1]); + xgifb_reg_set(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ + xgifb_reg_set(P3c4, 0x19, 0x01); + xgifb_reg_set(P3c4, 0x16, pVBInfo->SR16[0]); + xgifb_reg_set(P3c4, 0x16, pVBInfo->SR16[1]); mdelay(1); - XGINew_SetReg1(P3c4, 0x1B, 0x03); + xgifb_reg_set(P3c4, 0x1B, 0x03); udelay(500); - XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ - XGINew_SetReg1(P3c4, 0x19, 0x00); - XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[2]); - XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[3]); - XGINew_SetReg1(P3c4, 0x1B, 0x00); + xgifb_reg_set(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ + xgifb_reg_set(P3c4, 0x19, 0x00); + xgifb_reg_set(P3c4, 0x16, pVBInfo->SR16[2]); + xgifb_reg_set(P3c4, 0x16, pVBInfo->SR16[3]); + xgifb_reg_set(P3c4, 0x1B, 0x00); } static void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - XGINew_SetReg1(pVBInfo->P3c4, 0x28, pVBInfo->MCLKData[XGINew_RAMType].SR28); - XGINew_SetReg1(pVBInfo->P3c4, 0x29, pVBInfo->MCLKData[XGINew_RAMType].SR29); - XGINew_SetReg1(pVBInfo->P3c4, 0x2A, pVBInfo->MCLKData[XGINew_RAMType].SR2A); + xgifb_reg_set(pVBInfo->P3c4, 0x28, pVBInfo->MCLKData[XGINew_RAMType].SR28); + xgifb_reg_set(pVBInfo->P3c4, 0x29, pVBInfo->MCLKData[XGINew_RAMType].SR29); + xgifb_reg_set(pVBInfo->P3c4, 0x2A, pVBInfo->MCLKData[XGINew_RAMType].SR2A); - XGINew_SetReg1(pVBInfo->P3c4, 0x2E, pVBInfo->ECLKData[XGINew_RAMType].SR2E); - XGINew_SetReg1(pVBInfo->P3c4, 0x2F, pVBInfo->ECLKData[XGINew_RAMType].SR2F); - XGINew_SetReg1(pVBInfo->P3c4, 0x30, pVBInfo->ECLKData[XGINew_RAMType].SR30); + xgifb_reg_set(pVBInfo->P3c4, 0x2E, pVBInfo->ECLKData[XGINew_RAMType].SR2E); + xgifb_reg_set(pVBInfo->P3c4, 0x2F, pVBInfo->ECLKData[XGINew_RAMType].SR2F); + xgifb_reg_set(pVBInfo->P3c4, 0x30, pVBInfo->ECLKData[XGINew_RAMType].SR30); /* [Vicent] 2004/07/07, When XG42 ECLK = MCLK = 207MHz, Set SR32 D[1:0] = 10b */ /* [Hsuan] 2004/08/20, Modify SR32 value, when MCLK=207MHZ, ELCK=250MHz, Set SR32 D[1:0] = 10b */ @@ -143,7 +143,7 @@ static void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, && (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01)) || ((pVBInfo->ECLKData[XGINew_RAMType].SR2E == 0x22) && (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01)))) - XGINew_SetReg1(pVBInfo->P3c4, 0x32, ((unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x32) & 0xFC) | 0x02); + xgifb_reg_set(pVBInfo->P3c4, 0x32, ((unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x32) & 0xFC) | 0x02); } } @@ -156,67 +156,67 @@ static void XGINew_DDRII_Bootup_XG27( XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo); /* Set Double Frequency */ - /* XGINew_SetReg1(P3d4, 0x97, 0x11); *//* CR97 */ - XGINew_SetReg1(P3d4, 0x97, *pVBInfo->pXGINew_CR97); /* CR97 */ + /* xgifb_reg_set(P3d4, 0x97, 0x11); *//* CR97 */ + xgifb_reg_set(P3d4, 0x97, *pVBInfo->pXGINew_CR97); /* CR97 */ udelay(200); - XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS2 */ - XGINew_SetReg1(P3c4, 0x19, 0x80); /* Set SR19 */ - XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ + xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS2 */ + xgifb_reg_set(P3c4, 0x19, 0x80); /* Set SR19 */ + xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */ udelay(15); - XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ + xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */ udelay(15); - XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS3 */ - XGINew_SetReg1(P3c4, 0x19, 0xC0); /* Set SR19 */ - XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ + xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS3 */ + xgifb_reg_set(P3c4, 0x19, 0xC0); /* Set SR19 */ + xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */ udelay(15); - XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ + xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */ udelay(15); - XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS1 */ - XGINew_SetReg1(P3c4, 0x19, 0x40); /* Set SR19 */ - XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ + xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS1 */ + xgifb_reg_set(P3c4, 0x19, 0x40); /* Set SR19 */ + xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */ udelay(30); - XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ + xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */ udelay(15); - XGINew_SetReg1(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Enable */ - XGINew_SetReg1(P3c4, 0x19, 0x0A); /* Set SR19 */ - XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */ + xgifb_reg_set(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Enable */ + xgifb_reg_set(P3c4, 0x19, 0x0A); /* Set SR19 */ + xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */ udelay(30); - XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */ - XGINew_SetReg1(P3c4, 0x16, 0x80); /* Set SR16 */ + xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */ + xgifb_reg_set(P3c4, 0x16, 0x80); /* Set SR16 */ /* udelay(15); */ - XGINew_SetReg1(P3c4, 0x1B, 0x04); /* Set SR1B */ + xgifb_reg_set(P3c4, 0x1B, 0x04); /* Set SR1B */ udelay(60); - XGINew_SetReg1(P3c4, 0x1B, 0x00); /* Set SR1B */ + xgifb_reg_set(P3c4, 0x1B, 0x00); /* Set SR1B */ - XGINew_SetReg1(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Reset */ - XGINew_SetReg1(P3c4, 0x19, 0x08); /* Set SR19 */ - XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */ + xgifb_reg_set(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Reset */ + xgifb_reg_set(P3c4, 0x19, 0x08); /* Set SR19 */ + xgifb_reg_set(P3c4, 0x16, 0x00); /* Set SR16 */ udelay(30); - XGINew_SetReg1(P3c4, 0x16, 0x83); /* Set SR16 */ + xgifb_reg_set(P3c4, 0x16, 0x83); /* Set SR16 */ udelay(15); - XGINew_SetReg1(P3c4, 0x18, 0x80); /* Set SR18 */ /* MRS, ODT */ - XGINew_SetReg1(P3c4, 0x19, 0x46); /* Set SR19 */ - XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ + xgifb_reg_set(P3c4, 0x18, 0x80); /* Set SR18 */ /* MRS, ODT */ + xgifb_reg_set(P3c4, 0x19, 0x46); /* Set SR19 */ + xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */ udelay(30); - XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ + xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */ udelay(15); - XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS */ - XGINew_SetReg1(P3c4, 0x19, 0x40); /* Set SR19 */ - XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */ + xgifb_reg_set(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS */ + xgifb_reg_set(P3c4, 0x19, 0x40); /* Set SR19 */ + xgifb_reg_set(P3c4, 0x16, 0x20); /* Set SR16 */ udelay(30); - XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */ + xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */ udelay(15); - XGINew_SetReg1(P3c4, 0x1B, 0x04); /* Set SR1B refresh control 000:close; 010:open */ + xgifb_reg_set(P3c4, 0x1B, 0x04); /* Set SR1B refresh control 000:close; 010:open */ udelay(200); } @@ -229,41 +229,41 @@ static void XGINew_DDR2_MRS_XG20(struct xgi_hw_device_info *HwDeviceExtension, XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo); - XGINew_SetReg1(P3d4, 0x97, 0x11); /* CR97 */ + xgifb_reg_set(P3d4, 0x97, 0x11); /* CR97 */ udelay(200); - XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS2 */ - XGINew_SetReg1(P3c4, 0x19, 0x80); - XGINew_SetReg1(P3c4, 0x16, 0x05); - XGINew_SetReg1(P3c4, 0x16, 0x85); - - XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS3 */ - XGINew_SetReg1(P3c4, 0x19, 0xC0); - XGINew_SetReg1(P3c4, 0x16, 0x05); - XGINew_SetReg1(P3c4, 0x16, 0x85); - - XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS1 */ - XGINew_SetReg1(P3c4, 0x19, 0x40); - XGINew_SetReg1(P3c4, 0x16, 0x05); - XGINew_SetReg1(P3c4, 0x16, 0x85); - - /* XGINew_SetReg1(P3c4, 0x18, 0x52); */ /* MRS1 */ - XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */ - XGINew_SetReg1(P3c4, 0x19, 0x02); - XGINew_SetReg1(P3c4, 0x16, 0x05); - XGINew_SetReg1(P3c4, 0x16, 0x85); + xgifb_reg_set(P3c4, 0x18, 0x00); /* EMRS2 */ + xgifb_reg_set(P3c4, 0x19, 0x80); + xgifb_reg_set(P3c4, 0x16, 0x05); + xgifb_reg_set(P3c4, 0x16, 0x85); + + xgifb_reg_set(P3c4, 0x18, 0x00); /* EMRS3 */ + xgifb_reg_set(P3c4, 0x19, 0xC0); + xgifb_reg_set(P3c4, 0x16, 0x05); + xgifb_reg_set(P3c4, 0x16, 0x85); + + xgifb_reg_set(P3c4, 0x18, 0x00); /* EMRS1 */ + xgifb_reg_set(P3c4, 0x19, 0x40); + xgifb_reg_set(P3c4, 0x16, 0x05); + xgifb_reg_set(P3c4, 0x16, 0x85); + + /* xgifb_reg_set(P3c4, 0x18, 0x52); */ /* MRS1 */ + xgifb_reg_set(P3c4, 0x18, 0x42); /* MRS1 */ + xgifb_reg_set(P3c4, 0x19, 0x02); + xgifb_reg_set(P3c4, 0x16, 0x05); + xgifb_reg_set(P3c4, 0x16, 0x85); udelay(15); - XGINew_SetReg1(P3c4, 0x1B, 0x04); /* SR1B */ + xgifb_reg_set(P3c4, 0x1B, 0x04); /* SR1B */ udelay(30); - XGINew_SetReg1(P3c4, 0x1B, 0x00); /* SR1B */ + xgifb_reg_set(P3c4, 0x1B, 0x00); /* SR1B */ udelay(100); - /* XGINew_SetReg1(P3c4 ,0x18, 0x52); */ /* MRS2 */ - XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */ - XGINew_SetReg1(P3c4, 0x19, 0x00); - XGINew_SetReg1(P3c4, 0x16, 0x05); - XGINew_SetReg1(P3c4, 0x16, 0x85); + /* xgifb_reg_set(P3c4 ,0x18, 0x52); */ /* MRS2 */ + xgifb_reg_set(P3c4, 0x18, 0x42); /* MRS1 */ + xgifb_reg_set(P3c4, 0x19, 0x00); + xgifb_reg_set(P3c4, 0x16, 0x05); + xgifb_reg_set(P3c4, 0x16, 0x85); udelay(200); } @@ -271,31 +271,31 @@ static void XGINew_DDR2_MRS_XG20(struct xgi_hw_device_info *HwDeviceExtension, static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo) { - XGINew_SetReg1(P3c4, 0x18, 0x01); - XGINew_SetReg1(P3c4, 0x19, 0x40); - XGINew_SetReg1(P3c4, 0x16, 0x00); - XGINew_SetReg1(P3c4, 0x16, 0x80); + xgifb_reg_set(P3c4, 0x18, 0x01); + xgifb_reg_set(P3c4, 0x19, 0x40); + xgifb_reg_set(P3c4, 0x16, 0x00); + xgifb_reg_set(P3c4, 0x16, 0x80); udelay(60); - XGINew_SetReg1(P3c4, 0x18, 0x00); - XGINew_SetReg1(P3c4, 0x19, 0x40); - XGINew_SetReg1(P3c4, 0x16, 0x00); - XGINew_SetReg1(P3c4, 0x16, 0x80); + xgifb_reg_set(P3c4, 0x18, 0x00); + xgifb_reg_set(P3c4, 0x19, 0x40); + xgifb_reg_set(P3c4, 0x16, 0x00); + xgifb_reg_set(P3c4, 0x16, 0x80); udelay(60); - XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ - /* XGINew_SetReg1(P3c4, 0x18, 0x31); */ - XGINew_SetReg1(P3c4, 0x19, 0x01); - XGINew_SetReg1(P3c4, 0x16, 0x03); - XGINew_SetReg1(P3c4, 0x16, 0x83); + xgifb_reg_set(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ + /* xgifb_reg_set(P3c4, 0x18, 0x31); */ + xgifb_reg_set(P3c4, 0x19, 0x01); + xgifb_reg_set(P3c4, 0x16, 0x03); + xgifb_reg_set(P3c4, 0x16, 0x83); mdelay(1); - XGINew_SetReg1(P3c4, 0x1B, 0x03); + xgifb_reg_set(P3c4, 0x1B, 0x03); udelay(500); - /* XGINew_SetReg1(P3c4, 0x18, 0x31); */ - XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ - XGINew_SetReg1(P3c4, 0x19, 0x00); - XGINew_SetReg1(P3c4, 0x16, 0x03); - XGINew_SetReg1(P3c4, 0x16, 0x83); - XGINew_SetReg1(P3c4, 0x1B, 0x00); + /* xgifb_reg_set(P3c4, 0x18, 0x31); */ + xgifb_reg_set(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */ + xgifb_reg_set(P3c4, 0x19, 0x00); + xgifb_reg_set(P3c4, 0x16, 0x03); + xgifb_reg_set(P3c4, 0x16, 0x83); + xgifb_reg_set(P3c4, 0x1B, 0x00); } static void XGINew_DDR1x_DefaultRegister( @@ -306,12 +306,12 @@ static void XGINew_DDR1x_DefaultRegister( if (HwDeviceExtension->jChipType >= XG20) { XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo); - XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ - XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ - XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */ + xgifb_reg_set(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ + xgifb_reg_set(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ + xgifb_reg_set(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */ - XGINew_SetReg1(P3d4, 0x98, 0x01); - XGINew_SetReg1(P3d4, 0x9A, 0x02); + xgifb_reg_set(P3d4, 0x98, 0x01); + xgifb_reg_set(P3d4, 0x9A, 0x02); XGINew_DDR1x_MRS_XG20(P3c4, pVBInfo); } else { @@ -320,30 +320,30 @@ static void XGINew_DDR1x_DefaultRegister( switch (HwDeviceExtension->jChipType) { case XG41: case XG42: - XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ - XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ - XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */ + xgifb_reg_set(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ + xgifb_reg_set(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ + xgifb_reg_set(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */ break; default: - XGINew_SetReg1(P3d4, 0x82, 0x88); - XGINew_SetReg1(P3d4, 0x86, 0x00); + xgifb_reg_set(P3d4, 0x82, 0x88); + xgifb_reg_set(P3d4, 0x86, 0x00); XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */ - XGINew_SetReg1(P3d4, 0x86, 0x88); + xgifb_reg_set(P3d4, 0x86, 0x88); XGINew_GetReg1(P3d4, 0x86); - XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); - XGINew_SetReg1(P3d4, 0x82, 0x77); - XGINew_SetReg1(P3d4, 0x85, 0x00); + xgifb_reg_set(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); + xgifb_reg_set(P3d4, 0x82, 0x77); + xgifb_reg_set(P3d4, 0x85, 0x00); XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */ - XGINew_SetReg1(P3d4, 0x85, 0x88); + xgifb_reg_set(P3d4, 0x85, 0x88); XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */ - XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ - XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ + xgifb_reg_set(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ + xgifb_reg_set(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ break; } - XGINew_SetReg1(P3d4, 0x97, 0x00); - XGINew_SetReg1(P3d4, 0x98, 0x01); - XGINew_SetReg1(P3d4, 0x9A, 0x02); + xgifb_reg_set(P3d4, 0x97, 0x00); + xgifb_reg_set(P3d4, 0x98, 0x01); + xgifb_reg_set(P3d4, 0x9A, 0x02); XGINew_DDR1x_MRS_340(P3c4, pVBInfo); } } @@ -355,25 +355,25 @@ static void XGINew_DDR2_DefaultRegister( unsigned long P3d4 = Port, P3c4 = Port - 0x10; /* keep following setting sequence, each setting in the same reg insert idle */ - XGINew_SetReg1(P3d4, 0x82, 0x77); - XGINew_SetReg1(P3d4, 0x86, 0x00); + xgifb_reg_set(P3d4, 0x82, 0x77); + xgifb_reg_set(P3d4, 0x86, 0x00); XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */ - XGINew_SetReg1(P3d4, 0x86, 0x88); + xgifb_reg_set(P3d4, 0x86, 0x88); XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */ - XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */ - XGINew_SetReg1(P3d4, 0x82, 0x77); - XGINew_SetReg1(P3d4, 0x85, 0x00); + xgifb_reg_set(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */ + xgifb_reg_set(P3d4, 0x82, 0x77); + xgifb_reg_set(P3d4, 0x85, 0x00); XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */ - XGINew_SetReg1(P3d4, 0x85, 0x88); + xgifb_reg_set(P3d4, 0x85, 0x88); XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */ - XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ + xgifb_reg_set(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ if (HwDeviceExtension->jChipType == XG27) - XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ + xgifb_reg_set(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ else - XGINew_SetReg1(P3d4, 0x82, 0xA8); /* CR82 */ + xgifb_reg_set(P3d4, 0x82, 0xA8); /* CR82 */ - XGINew_SetReg1(P3d4, 0x98, 0x01); - XGINew_SetReg1(P3d4, 0x9A, 0x02); + xgifb_reg_set(P3d4, 0x98, 0x01); + xgifb_reg_set(P3d4, 0x9A, 0x02); if (HwDeviceExtension->jChipType == XG27) XGINew_DDRII_Bootup_XG27(HwDeviceExtension, P3c4, pVBInfo); else @@ -388,10 +388,10 @@ static void XGINew_SetDRAMDefaultRegister340( unsigned long P3d4 = Port, P3c4 = Port - 0x10; - XGINew_SetReg1(P3d4, 0x6D, pVBInfo->CR40[8][XGINew_RAMType]); - XGINew_SetReg1(P3d4, 0x68, pVBInfo->CR40[5][XGINew_RAMType]); - XGINew_SetReg1(P3d4, 0x69, pVBInfo->CR40[6][XGINew_RAMType]); - XGINew_SetReg1(P3d4, 0x6A, pVBInfo->CR40[7][XGINew_RAMType]); + xgifb_reg_set(P3d4, 0x6D, pVBInfo->CR40[8][XGINew_RAMType]); + xgifb_reg_set(P3d4, 0x68, pVBInfo->CR40[5][XGINew_RAMType]); + xgifb_reg_set(P3d4, 0x69, pVBInfo->CR40[6][XGINew_RAMType]); + xgifb_reg_set(P3d4, 0x6A, pVBInfo->CR40[7][XGINew_RAMType]); temp2 = 0; for (i = 0; i < 4; i++) { @@ -399,7 +399,7 @@ static void XGINew_SetDRAMDefaultRegister340( for (j = 0; j < 4; j++) { temp1 = ((temp >> (2 * j)) & 0x03) << 2; temp2 |= temp1; - XGINew_SetReg1(P3d4, 0x6B, temp2); + xgifb_reg_set(P3d4, 0x6B, temp2); XGINew_GetReg1(P3d4, 0x6B); /* Insert read command for delay */ temp2 &= 0xF0; temp2 += 0x10; @@ -412,7 +412,7 @@ static void XGINew_SetDRAMDefaultRegister340( for (j = 0; j < 4; j++) { temp1 = ((temp >> (2 * j)) & 0x03) << 2; temp2 |= temp1; - XGINew_SetReg1(P3d4, 0x6E, temp2); + xgifb_reg_set(P3d4, 0x6E, temp2); XGINew_GetReg1(P3d4, 0x6E); /* Insert read command for delay */ temp2 &= 0xF0; temp2 += 0x10; @@ -428,7 +428,7 @@ static void XGINew_SetDRAMDefaultRegister340( for (j = 0; j < 4; j++) { temp1 = (temp >> (2 * j)) & 0x03; temp2 |= temp1; - XGINew_SetReg1(P3d4, 0x6F, temp2); + xgifb_reg_set(P3d4, 0x6F, temp2); XGINew_GetReg1(P3d4, 0x6F); /* Insert read command for delay */ temp2 &= 0xF8; temp2 += 0x08; @@ -437,15 +437,15 @@ static void XGINew_SetDRAMDefaultRegister340( temp3 += 0x01; } - XGINew_SetReg1(P3d4, 0x80, pVBInfo->CR40[9][XGINew_RAMType]); /* CR80 */ - XGINew_SetReg1(P3d4, 0x81, pVBInfo->CR40[10][XGINew_RAMType]); /* CR81 */ + xgifb_reg_set(P3d4, 0x80, pVBInfo->CR40[9][XGINew_RAMType]); /* CR80 */ + xgifb_reg_set(P3d4, 0x81, pVBInfo->CR40[10][XGINew_RAMType]); /* CR81 */ temp2 = 0x80; temp = pVBInfo->CR89[XGINew_RAMType][0]; /* CR89 terminator type select */ for (j = 0; j < 4; j++) { temp1 = (temp >> (2 * j)) & 0x03; temp2 |= temp1; - XGINew_SetReg1(P3d4, 0x89, temp2); + xgifb_reg_set(P3d4, 0x89, temp2); XGINew_GetReg1(P3d4, 0x89); /* Insert read command for delay */ temp2 &= 0xF0; temp2 += 0x10; @@ -454,59 +454,59 @@ static void XGINew_SetDRAMDefaultRegister340( temp = pVBInfo->CR89[XGINew_RAMType][1]; temp1 = temp & 0x03; temp2 |= temp1; - XGINew_SetReg1(P3d4, 0x89, temp2); + xgifb_reg_set(P3d4, 0x89, temp2); temp = pVBInfo->CR40[3][XGINew_RAMType]; temp1 = temp & 0x0F; temp2 = (temp >> 4) & 0x07; temp3 = temp & 0x80; - XGINew_SetReg1(P3d4, 0x45, temp1); /* CR45 */ - XGINew_SetReg1(P3d4, 0x99, temp2); /* CR99 */ + xgifb_reg_set(P3d4, 0x45, temp1); /* CR45 */ + xgifb_reg_set(P3d4, 0x99, temp2); /* CR99 */ XGINew_SetRegOR(P3d4, 0x40, temp3); /* CR40_D[7] */ - XGINew_SetReg1(P3d4, 0x41, pVBInfo->CR40[0][XGINew_RAMType]); /* CR41 */ + xgifb_reg_set(P3d4, 0x41, pVBInfo->CR40[0][XGINew_RAMType]); /* CR41 */ if (HwDeviceExtension->jChipType == XG27) - XGINew_SetReg1(P3d4, 0x8F, *pVBInfo->pCR8F); /* CR8F */ + xgifb_reg_set(P3d4, 0x8F, *pVBInfo->pCR8F); /* CR8F */ for (j = 0; j <= 6; j++) - XGINew_SetReg1(P3d4, (0x90 + j), + xgifb_reg_set(P3d4, (0x90 + j), pVBInfo->CR40[14 + j][XGINew_RAMType]); /* CR90 - CR96 */ for (j = 0; j <= 2; j++) - XGINew_SetReg1(P3d4, (0xC3 + j), + xgifb_reg_set(P3d4, (0xC3 + j), pVBInfo->CR40[21 + j][XGINew_RAMType]); /* CRC3 - CRC5 */ for (j = 0; j < 2; j++) - XGINew_SetReg1(P3d4, (0x8A + j), + xgifb_reg_set(P3d4, (0x8A + j), pVBInfo->CR40[1 + j][XGINew_RAMType]); /* CR8A - CR8B */ if ((HwDeviceExtension->jChipType == XG41) || (HwDeviceExtension->jChipType == XG42)) - XGINew_SetReg1(P3d4, 0x8C, 0x87); + xgifb_reg_set(P3d4, 0x8C, 0x87); - XGINew_SetReg1(P3d4, 0x59, pVBInfo->CR40[4][XGINew_RAMType]); /* CR59 */ + xgifb_reg_set(P3d4, 0x59, pVBInfo->CR40[4][XGINew_RAMType]); /* CR59 */ - XGINew_SetReg1(P3d4, 0x83, 0x09); /* CR83 */ - XGINew_SetReg1(P3d4, 0x87, 0x00); /* CR87 */ - XGINew_SetReg1(P3d4, 0xCF, *pVBInfo->pCRCF); /* CRCF */ + xgifb_reg_set(P3d4, 0x83, 0x09); /* CR83 */ + xgifb_reg_set(P3d4, 0x87, 0x00); /* CR87 */ + xgifb_reg_set(P3d4, 0xCF, *pVBInfo->pCRCF); /* CRCF */ if (XGINew_RAMType) { - /* XGINew_SetReg1(P3c4, 0x17, 0xC0); */ /* SR17 DDRII */ - XGINew_SetReg1(P3c4, 0x17, 0x80); /* SR17 DDRII */ + /* xgifb_reg_set(P3c4, 0x17, 0xC0); */ /* SR17 DDRII */ + xgifb_reg_set(P3c4, 0x17, 0x80); /* SR17 DDRII */ if (HwDeviceExtension->jChipType == XG27) - XGINew_SetReg1(P3c4, 0x17, 0x02); /* SR17 DDRII */ + xgifb_reg_set(P3c4, 0x17, 0x02); /* SR17 DDRII */ } else { - XGINew_SetReg1(P3c4, 0x17, 0x00); /* SR17 DDR */ + xgifb_reg_set(P3c4, 0x17, 0x00); /* SR17 DDR */ } - XGINew_SetReg1(P3c4, 0x1A, 0x87); /* SR1A */ + xgifb_reg_set(P3c4, 0x1A, 0x87); /* SR1A */ temp = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo); if (temp == 0) { XGINew_DDR1x_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo); } else { - XGINew_SetReg1(P3d4, 0xB0, 0x80); /* DDRII Dual frequency mode */ + xgifb_reg_set(P3d4, 0xB0, 0x80); /* DDRII Dual frequency mode */ XGINew_DDR2_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo); } - XGINew_SetReg1(P3c4, 0x1B, pVBInfo->SR15[3][XGINew_RAMType]); /* SR1B */ + xgifb_reg_set(P3c4, 0x1B, pVBInfo->SR15[3][XGINew_RAMType]); /* SR1B */ } static void XGINew_SetDRAMSizingType(int index, @@ -550,11 +550,11 @@ static unsigned short XGINew_SetDRAMSizeReg(int index, memsize = data >> 4; /* [2004/03/25] Vicent, Fix DRAM Sizing Error */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0)); + xgifb_reg_set(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0)); /* data |= XGINew_ChannelAB << 2; */ /* data |= (XGINew_DataBusWidth / 64) << 1; */ - /* XGINew_SetReg1(pVBInfo->P3c4, 0x14, data); */ + /* xgifb_reg_set(pVBInfo->P3c4, 0x14, data); */ /* should delay */ /* XGINew_SetDRAMModeRegister340(pVBInfo); */ @@ -591,12 +591,12 @@ static unsigned short XGINew_SetDRAMSize20Reg(int index, memsize = data >> 4; /* [2004/03/25] Vicent, Fix DRAM Sizing Error */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0)); + xgifb_reg_set(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0)); udelay(15); /* data |= XGINew_ChannelAB << 2; */ /* data |= (XGINew_DataBusWidth / 64) << 1; */ - /* XGINew_SetReg1(pVBInfo->P3c4, 0x14, data); */ + /* xgifb_reg_set(pVBInfo->P3c4, 0x14, data); */ /* should delay */ /* XGINew_SetDRAMModeRegister340(pVBInfo); */ @@ -665,16 +665,16 @@ static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, > 0x1000000) { XGINew_DataBusWidth = 32; /* 32 bits */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 32bit */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52); + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 32bit */ + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x52); udelay(15); if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) return; if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) { - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* 22bit + 1 rank + 32bit */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42); + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x31); /* 22bit + 1 rank + 32bit */ + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x42); udelay(15); if (XGINew_ReadWriteRest(23, 23, pVBInfo) == 1) @@ -684,14 +684,14 @@ static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) { XGINew_DataBusWidth = 16; /* 16 bits */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 16bit */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x41); + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 16bit */ + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x41); udelay(15); if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) return; else - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x31); udelay(15); } @@ -699,16 +699,16 @@ static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) { XGINew_DataBusWidth = 16; /* 16 bits */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x41); /* 0x41:16Mx16 bit*/ + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */ + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x41); /* 0x41:16Mx16 bit*/ udelay(15); if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) return; if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x400000) { - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x31); /* 0x31:8Mx16 bit*/ + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */ + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x31); /* 0x31:8Mx16 bit*/ udelay(15); if (XGINew_ReadWriteRest(22, 22, pVBInfo) == 1) @@ -718,14 +718,14 @@ static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x400000) { XGINew_DataBusWidth = 8; /* 8 bits */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x30); /* 0x30:8Mx8 bit*/ + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */ + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x30); /* 0x30:8Mx8 bit*/ udelay(15); if (XGINew_ReadWriteRest(22, 21, pVBInfo) == 1) return; else - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */ + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */ udelay(15); } } @@ -734,76 +734,76 @@ static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, case XG27: XGINew_DataBusWidth = 16; /* 16 bits */ XGINew_ChannelAB = 1; /* Single channel */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x51); /* 32Mx16 bit*/ + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x51); /* 32Mx16 bit*/ break; case XG41: if (XGINew_CheckFrequence(pVBInfo) == 1) { XGINew_DataBusWidth = 32; /* 32 bits */ XGINew_ChannelAB = 3; /* Quad Channel */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4C); + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x4C); if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1) return; XGINew_ChannelAB = 2; /* Dual channels */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x48); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x48); if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) return; - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x49); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x49); if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) return; XGINew_ChannelAB = 3; - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x3C); + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x3C); if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) return; - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x38); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x38); if (XGINew_ReadWriteRest(8, 4, pVBInfo) == 1) return; else - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x39); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x39); } else { /* DDR */ XGINew_DataBusWidth = 64; /* 64 bits */ XGINew_ChannelAB = 2; /* Dual channels */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x5A); + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x5A); if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1) return; XGINew_ChannelAB = 1; /* Single channels */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x52); if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) return; - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x53); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x53); if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) return; XGINew_ChannelAB = 2; /* Dual channels */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4A); + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x4A); if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) return; XGINew_ChannelAB = 1; /* Single channels */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x42); if (XGINew_ReadWriteRest(8, 4, pVBInfo) == 1) return; else - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x43); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x43); } break; @@ -819,38 +819,38 @@ static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII, DDR2x */ XGINew_DataBusWidth = 32; /* 32 bits */ XGINew_ChannelAB = 2; /* 2 Channel */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x44); + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x44); if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) return; - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x34); + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x34); if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) return; XGINew_ChannelAB = 1; /* Single Channel */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x40); + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x40); if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1) return; else { - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x30); + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x30); } } else { /* DDR */ XGINew_DataBusWidth = 64; /* 64 bits */ XGINew_ChannelAB = 1; /* 1 channels */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52); + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x52); if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) return; else { - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42); + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x42); } } @@ -861,38 +861,38 @@ static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII */ XGINew_DataBusWidth = 32; /* 32 bits */ XGINew_ChannelAB = 3; - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4C); + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x4C); if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1) return; XGINew_ChannelAB = 2; /* 2 channels */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x48); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x48); if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) return; - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x3C); + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x3C); if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) { XGINew_ChannelAB = 3; /* 4 channels */ } else { XGINew_ChannelAB = 2; /* 2 channels */ - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x38); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x38); } } else { /* DDR */ XGINew_DataBusWidth = 64; /* 64 bits */ XGINew_ChannelAB = 2; /* 2 channels */ - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x5A); + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x5A); if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1) { return; } else { - XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4A); + xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x4A); } } break; @@ -905,8 +905,8 @@ static int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension, int i; unsigned short memsize, addr; - XGINew_SetReg1(pVBInfo->P3c4, 0x15, 0x00); /* noninterleaving */ - XGINew_SetReg1(pVBInfo->P3c4, 0x1C, 0x00); /* nontiling */ + xgifb_reg_set(pVBInfo->P3c4, 0x15, 0x00); /* noninterleaving */ + xgifb_reg_set(pVBInfo->P3c4, 0x1C, 0x00); /* nontiling */ XGINew_CheckChannel(HwDeviceExtension, pVBInfo); if (HwDeviceExtension->jChipType >= XG20) { @@ -953,15 +953,15 @@ static void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *HwDeviceExtension, XGISetModeNew(HwDeviceExtension, 0x2e); data = XGINew_GetReg1(pVBInfo->P3c4, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data & 0xDF)); /* disable read cache */ + xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short) (data & 0xDF)); /* disable read cache */ XGI_DisplayOff(HwDeviceExtension, pVBInfo); /* data = XGINew_GetReg1(pVBInfo->P3c4, 0x1); */ /* data |= 0x20 ; */ - /* XGINew_SetReg1(pVBInfo->P3c4, 0x01, data); *//* Turn OFF Display */ + /* xgifb_reg_set(pVBInfo->P3c4, 0x01, data); *//* Turn OFF Display */ XGINew_DDRSizing340(HwDeviceExtension, pVBInfo); data = XGINew_GetReg1(pVBInfo->P3c4, 0x21); - XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20)); /* enable read cache */ + xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20)); /* enable read cache */ } static void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo) @@ -1098,8 +1098,8 @@ static void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, } tempbx &= tempcx; - XGINew_SetReg1(pVBInfo->P3d4, 0x3d, (tempbx & 0x00FF)); - XGINew_SetReg1(pVBInfo->P3d4, 0x3e, ((tempbx & 0xFF00) >> 8)); + xgifb_reg_set(pVBInfo->P3d4, 0x3d, (tempbx & 0x00FF)); + xgifb_reg_set(pVBInfo->P3d4, 0x3e, ((tempbx & 0xFF00) >> 8)); } static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, @@ -1166,7 +1166,7 @@ static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, tempcl ^= (SetSimuScanMode | SwitchToCRT2); if ((temp & ActiveLCD) && (temp & ActiveTV)) tempcl ^= (SetSimuScanMode | SwitchToCRT2); - XGINew_SetReg1(pVBInfo->P3d4, 0x30, tempcl); + xgifb_reg_set(pVBInfo->P3d4, 0x30, tempcl); CR31Data = XGINew_GetReg1(pVBInfo->P3d4, 0x31); CR31Data &= ~(SetNotSimuMode >> 8); @@ -1175,12 +1175,12 @@ static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, CR31Data &= ~(DisableCRT2Display >> 8); if (!((temp & ActiveLCD) || (temp & ActiveTV) || (temp & ActiveCRT2))) CR31Data |= (DisableCRT2Display >> 8); - XGINew_SetReg1(pVBInfo->P3d4, 0x31, CR31Data); + xgifb_reg_set(pVBInfo->P3d4, 0x31, CR31Data); CR38Data = XGINew_GetReg1(pVBInfo->P3d4, 0x38); CR38Data &= ~SetYPbPr; CR38Data |= tempch; - XGINew_SetReg1(pVBInfo->P3d4, 0x38, CR38Data); + xgifb_reg_set(pVBInfo->P3d4, 0x38, CR38Data); } @@ -1227,12 +1227,12 @@ static void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension, bCR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x07, 0x07); /* Enable GPIOA/B/C read */ Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0x07; - XGINew_SetReg1(pVBInfo->P3d4, 0x4A, bCR4A); + xgifb_reg_set(pVBInfo->P3d4, 0x4A, bCR4A); if (Temp <= 0x02) { pVBInfo->IF_DEF_LVDS = 1; XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS setting */ - XGINew_SetReg1(pVBInfo->P3d4, 0x30, 0x21); + xgifb_reg_set(pVBInfo->P3d4, 0x30, 0x21); } else { XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* TMDS/DVO setting */ } @@ -1254,7 +1254,7 @@ static unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo) temp >>= 3; } - XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A); + xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A); return temp; } @@ -1271,7 +1271,7 @@ static unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo) else temp = ((temp & 0x04) >> 1) || ((~temp) & 0x01); - XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A); + xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A); return temp; } @@ -1352,7 +1352,7 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) ReadVBIOSTablData(HwDeviceExtension->jChipType, pVBInfo); /* 1.Openkey */ - XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86); + xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86); printk("6"); /* GetXG21Sense (GPIO) */ @@ -1367,33 +1367,33 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) /* 2.Reset Extended register */ for (i = 0x06; i < 0x20; i++) - XGINew_SetReg1(pVBInfo->P3c4, i, 0); + xgifb_reg_set(pVBInfo->P3c4, i, 0); for (i = 0x21; i <= 0x27; i++) - XGINew_SetReg1(pVBInfo->P3c4, i, 0); + xgifb_reg_set(pVBInfo->P3c4, i, 0); /* for(i = 0x06; i <= 0x27; i++) */ - /* XGINew_SetReg1(pVBInfo->P3c4, i, 0); */ + /* xgifb_reg_set(pVBInfo->P3c4, i, 0); */ printk("8"); for (i = 0x31; i <= 0x3B; i++) - XGINew_SetReg1(pVBInfo->P3c4, i, 0); + xgifb_reg_set(pVBInfo->P3c4, i, 0); printk("9"); if (HwDeviceExtension->jChipType == XG42) /* [Hsuan] 2004/08/20 Auto over driver for XG42 */ - XGINew_SetReg1(pVBInfo->P3c4, 0x3B, 0xC0); + xgifb_reg_set(pVBInfo->P3c4, 0x3B, 0xC0); /* for (i = 0x30; i <= 0x3F; i++) */ - /* XGINew_SetReg1(pVBInfo->P3d4, i, 0); */ + /* xgifb_reg_set(pVBInfo->P3d4, i, 0); */ for (i = 0x79; i <= 0x7C; i++) - XGINew_SetReg1(pVBInfo->P3d4, i, 0); /* shampoo 0208 */ + xgifb_reg_set(pVBInfo->P3d4, i, 0); /* shampoo 0208 */ printk("10"); if (HwDeviceExtension->jChipType >= XG20) - XGINew_SetReg1(pVBInfo->P3d4, 0x97, *pVBInfo->pXGINew_CR97); + xgifb_reg_set(pVBInfo->P3d4, 0x97, *pVBInfo->pXGINew_CR97); /* 3.SetMemoryClock @@ -1403,21 +1403,21 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) printk("11"); /* 4.SetDefExt1Regs begin */ - XGINew_SetReg1(pVBInfo->P3c4, 0x07, *pVBInfo->pSR07); + xgifb_reg_set(pVBInfo->P3c4, 0x07, *pVBInfo->pSR07); if (HwDeviceExtension->jChipType == XG27) { - XGINew_SetReg1(pVBInfo->P3c4, 0x40, *pVBInfo->pSR40); - XGINew_SetReg1(pVBInfo->P3c4, 0x41, *pVBInfo->pSR41); + xgifb_reg_set(pVBInfo->P3c4, 0x40, *pVBInfo->pSR40); + xgifb_reg_set(pVBInfo->P3c4, 0x41, *pVBInfo->pSR41); } - XGINew_SetReg1(pVBInfo->P3c4, 0x11, 0x0F); - XGINew_SetReg1(pVBInfo->P3c4, 0x1F, *pVBInfo->pSR1F); - /* XGINew_SetReg1(pVBInfo->P3c4, 0x20, 0x20); */ - XGINew_SetReg1(pVBInfo->P3c4, 0x20, 0xA0); /* alan, 2001/6/26 Frame buffer can read/write SR20 */ - XGINew_SetReg1(pVBInfo->P3c4, 0x36, 0x70); /* Hsuan, 2006/01/01 H/W request for slow corner chip */ + xgifb_reg_set(pVBInfo->P3c4, 0x11, 0x0F); + xgifb_reg_set(pVBInfo->P3c4, 0x1F, *pVBInfo->pSR1F); + /* xgifb_reg_set(pVBInfo->P3c4, 0x20, 0x20); */ + xgifb_reg_set(pVBInfo->P3c4, 0x20, 0xA0); /* alan, 2001/6/26 Frame buffer can read/write SR20 */ + xgifb_reg_set(pVBInfo->P3c4, 0x36, 0x70); /* Hsuan, 2006/01/01 H/W request for slow corner chip */ if (HwDeviceExtension->jChipType == XG27) /* Alan 12/07/2006 */ - XGINew_SetReg1(pVBInfo->P3c4, 0x36, *pVBInfo->pSR36); + xgifb_reg_set(pVBInfo->P3c4, 0x36, *pVBInfo->pSR36); /* SR11 = 0x0F; */ - /* XGINew_SetReg1(pVBInfo->P3c4, 0x11, SR11); */ + /* xgifb_reg_set(pVBInfo->P3c4, 0x11, SR11); */ printk("12"); @@ -1437,18 +1437,18 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) GraphicVendorID &= 0x0000FFFF; if (ChipsetID == 0x7301039) - XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x09); + xgifb_reg_set(pVBInfo->P3d4, 0x5F, 0x09); ChipsetID &= 0x0000FFFF; if ((ChipsetID == 0x700E) || (ChipsetID == 0x1022) || (ChipsetID == 0x1106) || (ChipsetID == 0x10DE)) { if (ChipsetID == 0x1106) { if ((VendorID == 0x1019) && (GraphicVendorID == 0x1019)) - XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0D); + xgifb_reg_set(pVBInfo->P3d4, 0x5F, 0x0D); else - XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0B); + xgifb_reg_set(pVBInfo->P3d4, 0x5F, 0x0B); } else { - XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0B); + xgifb_reg_set(pVBInfo->P3d4, 0x5F, 0x0B); } } } @@ -1458,61 +1458,61 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) /* Set AGP customize registers (in SetDefAGPRegs) Start */ for (i = 0x47; i <= 0x4C; i++) - XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[i - 0x47]); + xgifb_reg_set(pVBInfo->P3d4, i, pVBInfo->AGPReg[i - 0x47]); for (i = 0x70; i <= 0x71; i++) - XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[6 + i - 0x70]); + xgifb_reg_set(pVBInfo->P3d4, i, pVBInfo->AGPReg[6 + i - 0x70]); for (i = 0x74; i <= 0x77; i++) - XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[8 + i - 0x74]); + xgifb_reg_set(pVBInfo->P3d4, i, pVBInfo->AGPReg[8 + i - 0x74]); /* Set AGP customize registers (in SetDefAGPRegs) End */ /* [Hsuan]2004/12/14 AGP Input Delay Adjustment on 850 */ /* outl(0x80000000, 0xcf8); */ /* ChipsetID = inl(0x0cfc); */ /* if (ChipsetID == 0x25308086) */ - /* XGINew_SetReg1(pVBInfo->P3d4, 0x77, 0xF0); */ + /* xgifb_reg_set(pVBInfo->P3d4, 0x77, 0xF0); */ HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension, 0x50, 0, &Temp); /* Get */ Temp >>= 20; Temp &= 0xF; if (Temp == 1) - XGINew_SetReg1(pVBInfo->P3d4, 0x48, 0x20); /* CR48 */ + xgifb_reg_set(pVBInfo->P3d4, 0x48, 0x20); /* CR48 */ printk("14"); } /* != XG20 */ /* Set PCI */ - XGINew_SetReg1(pVBInfo->P3c4, 0x23, *pVBInfo->pSR23); - XGINew_SetReg1(pVBInfo->P3c4, 0x24, *pVBInfo->pSR24); - XGINew_SetReg1(pVBInfo->P3c4, 0x25, pVBInfo->SR25[0]); + xgifb_reg_set(pVBInfo->P3c4, 0x23, *pVBInfo->pSR23); + xgifb_reg_set(pVBInfo->P3c4, 0x24, *pVBInfo->pSR24); + xgifb_reg_set(pVBInfo->P3c4, 0x25, pVBInfo->SR25[0]); printk("15"); if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */ /* Set VB */ XGI_UnLockCRT2(HwDeviceExtension, pVBInfo); XGINew_SetRegANDOR(pVBInfo->Part0Port, 0x3F, 0xEF, 0x00); /* alan, disable VideoCapture */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x00, 0x00); + xgifb_reg_set(pVBInfo->Part1Port, 0x00, 0x00); temp1 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x7B); /* chk if BCLK>=100MHz */ temp = (unsigned char) ((temp1 >> 4) & 0x0F); - XGINew_SetReg1(pVBInfo->Part1Port, 0x02, (*pVBInfo->pCRT2Data_1_2)); + xgifb_reg_set(pVBInfo->Part1Port, 0x02, (*pVBInfo->pCRT2Data_1_2)); printk("16"); - XGINew_SetReg1(pVBInfo->Part1Port, 0x2E, 0x08); /* use VB */ + xgifb_reg_set(pVBInfo->Part1Port, 0x2E, 0x08); /* use VB */ } /* != XG20 */ - XGINew_SetReg1(pVBInfo->P3c4, 0x27, 0x1F); + xgifb_reg_set(pVBInfo->P3c4, 0x27, 0x1F); if ((HwDeviceExtension->jChipType == XG42) && XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) != 0) { /* Not DDR */ - XGINew_SetReg1(pVBInfo->P3c4, 0x31, (*pVBInfo->pSR31 & 0x3F) | 0x40); - XGINew_SetReg1(pVBInfo->P3c4, 0x32, (*pVBInfo->pSR32 & 0xFC) | 0x01); + xgifb_reg_set(pVBInfo->P3c4, 0x31, (*pVBInfo->pSR31 & 0x3F) | 0x40); + xgifb_reg_set(pVBInfo->P3c4, 0x32, (*pVBInfo->pSR32 & 0xFC) | 0x01); } else { - XGINew_SetReg1(pVBInfo->P3c4, 0x31, *pVBInfo->pSR31); - XGINew_SetReg1(pVBInfo->P3c4, 0x32, *pVBInfo->pSR32); + xgifb_reg_set(pVBInfo->P3c4, 0x31, *pVBInfo->pSR31); + xgifb_reg_set(pVBInfo->P3c4, 0x32, *pVBInfo->pSR32); } - XGINew_SetReg1(pVBInfo->P3c4, 0x33, *pVBInfo->pSR33); + xgifb_reg_set(pVBInfo->P3c4, 0x33, *pVBInfo->pSR33); printk("17"); /* @@ -1521,11 +1521,11 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */ if (XGI_BridgeIsOn(pVBInfo) == 1) { if (pVBInfo->IF_DEF_LVDS == 0) { - XGINew_SetReg1(pVBInfo->Part2Port, 0x00, 0x1C); - XGINew_SetReg1(pVBInfo->Part4Port, 0x0D, *pVBInfo->pCRT2Data_4_D); - XGINew_SetReg1(pVBInfo->Part4Port, 0x0E, *pVBInfo->pCRT2Data_4_E); - XGINew_SetReg1(pVBInfo->Part4Port, 0x10, *pVBInfo->pCRT2Data_4_10); - XGINew_SetReg1(pVBInfo->Part4Port, 0x0F, 0x3F); + xgifb_reg_set(pVBInfo->Part2Port, 0x00, 0x1C); + xgifb_reg_set(pVBInfo->Part4Port, 0x0D, *pVBInfo->pCRT2Data_4_D); + xgifb_reg_set(pVBInfo->Part4Port, 0x0E, *pVBInfo->pCRT2Data_4_E); + xgifb_reg_set(pVBInfo->Part4Port, 0x10, *pVBInfo->pCRT2Data_4_10); + xgifb_reg_set(pVBInfo->Part4Port, 0x0F, 0x3F); } XGI_LockCRT2(HwDeviceExtension, pVBInfo); @@ -1585,21 +1585,21 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) if (AGP == 0) *pVBInfo->pSR21 &= 0xEF; - XGINew_SetReg1(pVBInfo->P3c4, 0x21, *pVBInfo->pSR21); + xgifb_reg_set(pVBInfo->P3c4, 0x21, *pVBInfo->pSR21); if (AGP == 1) *pVBInfo->pSR22 &= 0x20; - XGINew_SetReg1(pVBInfo->P3c4, 0x22, *pVBInfo->pSR22); + xgifb_reg_set(pVBInfo->P3c4, 0x22, *pVBInfo->pSR22); */ /* base = 0x80000000; */ /* OutPortLong(0xcf8, base); */ /* Temp = (InPortLong(0xcfc) & 0xFFFF); */ /* if (Temp == 0x1039) { */ - XGINew_SetReg1(pVBInfo->P3c4, 0x22, (unsigned char) ((*pVBInfo->pSR22) & 0xFE)); + xgifb_reg_set(pVBInfo->P3c4, 0x22, (unsigned char) ((*pVBInfo->pSR22) & 0xFE)); /* } else { */ - /* XGINew_SetReg1(pVBInfo->P3c4, 0x22, *pVBInfo->pSR22); */ + /* xgifb_reg_set(pVBInfo->P3c4, 0x22, *pVBInfo->pSR22); */ /* } */ - XGINew_SetReg1(pVBInfo->P3c4, 0x21, *pVBInfo->pSR21); + xgifb_reg_set(pVBInfo->P3c4, 0x21, *pVBInfo->pSR21); printk("23"); @@ -1608,8 +1608,8 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) printk("24"); - XGINew_SetReg1(pVBInfo->P3d4, 0x8c, 0x87); - XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x31); + xgifb_reg_set(pVBInfo->P3d4, 0x8c, 0x87); + xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x31); printk("25"); return 1; diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index b4f211297564..4cca02dc5ad0 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -229,7 +229,7 @@ static void XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex else modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - XGINew_SetReg1(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */ + xgifb_reg_set(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */ tempah = pVBInfo->StandTable[StandTableIndex].SR[0]; i = SetCRT2ToLCDA; @@ -243,11 +243,11 @@ static void XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex } tempah |= 0x20; /* screen off */ - XGINew_SetReg1(pVBInfo->P3c4, 0x01, tempah); /* Set SR1 */ + xgifb_reg_set(pVBInfo->P3c4, 0x01, tempah); /* Set SR1 */ for (i = 02; i <= 04; i++) { SRdata = pVBInfo->StandTable[StandTableIndex].SR[i - 1]; /* Get SR2,3,4 from file */ - XGINew_SetReg1(pVBInfo->P3c4, i, SRdata); /* Set SR2 3 4 */ + xgifb_reg_set(pVBInfo->P3c4, i, SRdata); /* Set SR2 3 4 */ } } @@ -276,17 +276,17 @@ static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, CRTCdata = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); CRTCdata &= 0x7f; - XGINew_SetReg1(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */ + xgifb_reg_set(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */ for (i = 0; i <= 0x18; i++) { CRTCdata = pVBInfo->StandTable[StandTableIndex].CRTC[i]; /* Get CRTC from file */ - XGINew_SetReg1(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */ + xgifb_reg_set(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */ } /* if ((HwDeviceExtension->jChipType == XGI_630) && (HwDeviceExtension->jChipRevision == 0x30)) { if (pVBInfo->VBInfo & SetInSlaveMode) { if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) { - XGINew_SetReg1(pVBInfo->P3d4, 0x18, 0xFE); + xgifb_reg_set(pVBInfo->P3d4, 0x18, 0xFE); } } } @@ -341,13 +341,13 @@ static void XGI_SetGRCRegs(unsigned short StandTableIndex, for (i = 0; i <= 0x08; i++) { GRdata = pVBInfo->StandTable[StandTableIndex].GRC[i]; /* Get GR from file */ - XGINew_SetReg1(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */ + xgifb_reg_set(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */ } if (pVBInfo->ModeType > ModeVGA) { GRdata = (unsigned char) XGINew_GetReg1(pVBInfo->P3ce, 0x05); GRdata &= 0xBF; /* 256 color disable */ - XGINew_SetReg1(pVBInfo->P3ce, 0x05, GRdata); + xgifb_reg_set(pVBInfo->P3ce, 0x05, GRdata); } } @@ -356,19 +356,19 @@ static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo) unsigned short i; for (i = 0x0A; i <= 0x0E; i++) - XGINew_SetReg1(pVBInfo->P3c4, i, 0x00); /* Clear SR0A-SR0E */ + xgifb_reg_set(pVBInfo->P3c4, i, 0x00); /* Clear SR0A-SR0E */ } static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo) { XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, 0x20); - XGINew_SetReg1(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[0].SR2B); - XGINew_SetReg1(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[0].SR2C); + xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[0].SR2B); + xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[0].SR2C); XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, 0x10); - XGINew_SetReg1(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[1].SR2B); - XGINew_SetReg1(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[1].SR2C); + xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[1].SR2B); + xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[1].SR2C); XGINew_SetRegAND(pVBInfo->P3c4, 0x31, ~0x30); return 0; @@ -534,25 +534,25 @@ static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, unsigned char data, data1, pushax; unsigned short i, j; - /* XGINew_SetReg1(pVBInfo->P3d4, 0x51, 0); */ - /* XGINew_SetReg1(pVBInfo->P3d4, 0x56, 0); */ + /* xgifb_reg_set(pVBInfo->P3d4, 0x51, 0); */ + /* xgifb_reg_set(pVBInfo->P3d4, 0x56, 0); */ /* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */ data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); /* unlock cr0-7 */ data &= 0x7F; - XGINew_SetReg1(pVBInfo->P3d4, 0x11, data); + xgifb_reg_set(pVBInfo->P3d4, 0x11, data); data = pVBInfo->TimingH[0].data[0]; - XGINew_SetReg1(pVBInfo->P3d4, 0, data); + xgifb_reg_set(pVBInfo->P3d4, 0, data); for (i = 0x01; i <= 0x04; i++) { data = pVBInfo->TimingH[0].data[i]; - XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 1), data); + xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 1), data); } for (i = 0x05; i <= 0x06; i++) { data = pVBInfo->TimingH[0].data[i]; - XGINew_SetReg1(pVBInfo->P3c4, (unsigned short) (i + 6), data); + xgifb_reg_set(pVBInfo->P3c4, (unsigned short) (i + 6), data); } j = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0e); @@ -560,12 +560,12 @@ static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, data = pVBInfo->TimingH[0].data[7]; data &= 0xE0; data |= j; - XGINew_SetReg1(pVBInfo->P3c4, 0x0e, data); + xgifb_reg_set(pVBInfo->P3c4, 0x0e, data); if (HwDeviceExtension->jChipType >= XG20) { data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x04); data = data - 1; - XGINew_SetReg1(pVBInfo->P3d4, 0x04, data); + xgifb_reg_set(pVBInfo->P3d4, 0x04, data); data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x05); data1 = data; data1 &= 0xE0; @@ -575,12 +575,12 @@ static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, data = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0c); data &= 0xFB; - XGINew_SetReg1(pVBInfo->P3c4, 0x0c, data); + xgifb_reg_set(pVBInfo->P3c4, 0x0c, data); data = pushax; } data = data - 1; data |= data1; - XGINew_SetReg1(pVBInfo->P3d4, 0x05, data); + xgifb_reg_set(pVBInfo->P3d4, 0x05, data); data = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0e); data = data >> 5; data = data + 3; @@ -597,23 +597,23 @@ static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeN unsigned char data; unsigned short i, j; - /* XGINew_SetReg1(pVBInfo->P3d4, 0x51, 0); */ - /* XGINew_SetReg1(pVBInfo->P3d4, 0x56, 0); */ + /* xgifb_reg_set(pVBInfo->P3d4, 0x51, 0); */ + /* xgifb_reg_set(pVBInfo->P3d4, 0x56, 0); */ /* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */ for (i = 0x00; i <= 0x01; i++) { data = pVBInfo->TimingV[0].data[i]; - XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 6), data); + xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 6), data); } for (i = 0x02; i <= 0x03; i++) { data = pVBInfo->TimingV[0].data[i]; - XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 0x0e), data); + xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x0e), data); } for (i = 0x04; i <= 0x05; i++) { data = pVBInfo->TimingV[0].data[i]; - XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 0x11), data); + xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x11), data); } j = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0a); @@ -621,7 +621,7 @@ static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeN data = pVBInfo->TimingV[0].data[6]; data &= 0x3F; data |= j; - XGINew_SetReg1(pVBInfo->P3c4, 0x0a, data); + xgifb_reg_set(pVBInfo->P3c4, 0x0a, data); data = pVBInfo->TimingV[0].data[6]; data &= 0x80; @@ -639,7 +639,7 @@ static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeN j = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x09); j &= 0x5F; data |= j; - XGINew_SetReg1(pVBInfo->P3d4, 0x09, data); + xgifb_reg_set(pVBInfo->P3d4, 0x09, data); } static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, @@ -655,7 +655,7 @@ static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); data &= 0x7F; - XGINew_SetReg1(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */ + xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */ for (i = 0; i < 8; i++) pVBInfo->TimingH[0].data[i] @@ -670,7 +670,7 @@ static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo); if (pVBInfo->ModeType > 0x03) - XGINew_SetReg1(pVBInfo->P3d4, 0x14, 0x4F); + xgifb_reg_set(pVBInfo->P3d4, 0x14, 0x4F); } /* --------------------------------------------------------------------- */ @@ -689,7 +689,7 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, if (ModeNo <= 0x13) { StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo); Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; /* CR04 HRS */ - XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E [7:0]->HRS */ + xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E [7:0]->HRS */ Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; /* Tempbx: CR05 HRE */ Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */ Tempcx = Tempax; @@ -698,7 +698,7 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */ Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */ Tempdx <<= 2; /* Tempdx << 2 */ - XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */ + xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00); Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; /* Tempax: CR16 VRS */ @@ -710,7 +710,7 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, Tempcx = Tempax & 0x04; /* Tempcx: CR7[2] */ Tempcx <<= 5; /* Tempcx[7]: VRS[8] */ Tempdx |= Tempcx; /* Tempdx: VRS[8:1] */ - XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempdx); /* SR34[7:0]: VRS[8:1] */ + xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempdx); /* SR34[7:0]: VRS[8:1] */ Temp1 = Tempcx << 1; /* Temp1[8]: VRS[8] unsigned char -> unsigned short */ Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */ @@ -733,12 +733,12 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, Tempbx = (unsigned char) Temp1; /* Tempbx[1:0]: VRS[10:9] */ Tempax |= Tempbx; /* VRE[5:0]VRS[10:9] */ Tempax &= 0x7F; - XGINew_SetReg1(pVBInfo->P3c4, 0x3F, Tempax); /* SR3F D[7:2]->VRE D[1:0]->VRS */ + xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax); /* SR3F D[7:2]->VRE D[1:0]->VRS */ } else { index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */ Tempcx = Tempax; /* Tempcx: HRS */ - XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E[7:0]->HRS */ + xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E[7:0]->HRS */ Tempdx = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SRB */ Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */ @@ -766,7 +766,7 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */ Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */ Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */ - XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F D[7:2]->HRE, D[1:0]->HRS */ + xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F D[7:2]->HRE, D[1:0]->HRS */ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00); Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; /* CR10 VRS */ @@ -778,7 +778,7 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */ Tempdx <<= 5; /* Tempdx[7]: VRS[8] */ Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */ - XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */ + xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */ Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */ Temp1 <<= 1; /* Temp1[8]: VRS[8] */ @@ -813,7 +813,7 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, Tempbx = (unsigned char) Temp1; Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */ Tempax &= 0x7F; - XGINew_SetReg1(pVBInfo->P3c4, 0x3F, Tempax); /* SR3F D[7:2]->VRE D[1:0]->VRS */ + xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax); /* SR3F D[7:2]->VRE D[1:0]->VRS */ } } @@ -826,7 +826,7 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, if (ModeNo <= 0x13) { StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo); Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; /* CR04 HRS */ - XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E [7:0]->HRS */ + xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E [7:0]->HRS */ Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; /* Tempbx: CR05 HRE */ Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */ Tempcx = Tempax; @@ -835,11 +835,11 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */ Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */ Tempdx <<= 2; /* Tempdx << 2 */ - XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */ + xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00); Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; /* Tempax: CR10 VRS */ - XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS */ + xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS */ Tempcx = Tempax; /* Tempcx=Tempax=VRS[7:0] */ Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; /* Tempax[7][2]: CR7[7][2] VRS[9][8] */ Tempbx = Tempax; /* Tempbx=CR07 */ @@ -865,7 +865,7 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */ Tempbx = Tempax; /* Tempbx: HRS[7:0] */ - XGINew_SetReg1(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E[7:0]->HRS */ + xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E[7:0]->HRS */ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */ Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ @@ -892,11 +892,11 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/ Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */ - XGINew_SetReg1(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */ + xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00); Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; /* CR10 VRS */ - XGINew_SetReg1(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS[7:0] */ + xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS[7:0] */ Tempcx = Tempax; /* Tempcx <= VRS[7:0] */ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; /* CR7[7][2] VRS[9][8] */ @@ -944,15 +944,15 @@ static void XGI_SetXG21LCD(struct vb_device_info *pVBInfo, XGI_P3cc = pVBInfo->P3cc; - XGINew_SetReg1(pVBInfo->P3d4, 0x2E, 0x00); - XGINew_SetReg1(pVBInfo->P3d4, 0x2F, 0x00); - XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x00); - XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x00); + xgifb_reg_set(pVBInfo->P3d4, 0x2E, 0x00); + xgifb_reg_set(pVBInfo->P3d4, 0x2F, 0x00); + xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x00); + xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x00); if (((*pVBInfo->pDVOSetting) & 0xC0) == 0xC0) { - XGINew_SetReg1(pVBInfo->P3d4, 0x2E, *pVBInfo->pCR2E); - XGINew_SetReg1(pVBInfo->P3d4, 0x2F, *pVBInfo->pCR2F); - XGINew_SetReg1(pVBInfo->P3d4, 0x46, *pVBInfo->pCR46); - XGINew_SetReg1(pVBInfo->P3d4, 0x47, *pVBInfo->pCR47); + xgifb_reg_set(pVBInfo->P3d4, 0x2E, *pVBInfo->pCR2E); + xgifb_reg_set(pVBInfo->P3d4, 0x2F, *pVBInfo->pCR2F); + xgifb_reg_set(pVBInfo->P3d4, 0x46, *pVBInfo->pCR46); + xgifb_reg_set(pVBInfo->P3d4, 0x47, *pVBInfo->pCR47); } Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); @@ -990,22 +990,22 @@ static void XGI_SetXG27LCD(struct vb_device_info *pVBInfo, XGI_P3cc = pVBInfo->P3cc; - XGINew_SetReg1(pVBInfo->P3d4, 0x2E, 0x00); - XGINew_SetReg1(pVBInfo->P3d4, 0x2F, 0x00); - XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x00); - XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x00); + xgifb_reg_set(pVBInfo->P3d4, 0x2E, 0x00); + xgifb_reg_set(pVBInfo->P3d4, 0x2F, 0x00); + xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x00); + xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x00); Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); if ((Temp & 0x03) == 0) { /* dual 12 */ - XGINew_SetReg1(pVBInfo->P3d4, 0x46, 0x13); - XGINew_SetReg1(pVBInfo->P3d4, 0x47, 0x13); + xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x13); + xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x13); } if (((*pVBInfo->pDVOSetting) & 0xC0) == 0xC0) { - XGINew_SetReg1(pVBInfo->P3d4, 0x2E, *pVBInfo->pCR2E); - XGINew_SetReg1(pVBInfo->P3d4, 0x2F, *pVBInfo->pCR2F); - XGINew_SetReg1(pVBInfo->P3d4, 0x46, *pVBInfo->pCR46); - XGINew_SetReg1(pVBInfo->P3d4, 0x47, *pVBInfo->pCR47); + xgifb_reg_set(pVBInfo->P3d4, 0x2E, *pVBInfo->pCR2E); + xgifb_reg_set(pVBInfo->P3d4, 0x2F, *pVBInfo->pCR2F); + xgifb_reg_set(pVBInfo->P3d4, 0x46, *pVBInfo->pCR46); + xgifb_reg_set(pVBInfo->P3d4, 0x47, *pVBInfo->pCR47); } XGI_SetXG27FPBits(pVBInfo); @@ -1065,13 +1065,13 @@ static void XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVB } if (index != -1) { - XGINew_SetReg1(pVBInfo->P3d4, 0x02, + xgifb_reg_set(pVBInfo->P3d4, 0x02, pVBInfo->UpdateCRT1[index].CR02); - XGINew_SetReg1(pVBInfo->P3d4, 0x03, + xgifb_reg_set(pVBInfo->P3d4, 0x03, pVBInfo->UpdateCRT1[index].CR03); - XGINew_SetReg1(pVBInfo->P3d4, 0x15, + xgifb_reg_set(pVBInfo->P3d4, 0x15, pVBInfo->UpdateCRT1[index].CR15); - XGINew_SetReg1(pVBInfo->P3d4, 0x16, + xgifb_reg_set(pVBInfo->P3d4, 0x16, pVBInfo->UpdateCRT1[index].CR16); } } @@ -1125,11 +1125,11 @@ static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); data &= 0x7F; - XGINew_SetReg1(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */ - XGINew_SetReg1(pVBInfo->P3d4, 0x01, (unsigned short) (tempcx & 0xff)); + xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */ + xgifb_reg_set(pVBInfo->P3d4, 0x01, (unsigned short) (tempcx & 0xff)); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x0b, ~0x0c, (unsigned short) ((tempcx & 0x0ff00) >> 10)); - XGINew_SetReg1(pVBInfo->P3d4, 0x12, (unsigned short) (tempbx & 0xff)); + xgifb_reg_set(pVBInfo->P3d4, 0x12, (unsigned short) (tempbx & 0xff)); tempax = 0; tempbx = tempbx >> 8; @@ -1148,7 +1148,7 @@ static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, tempax |= 0x02; XGINew_SetRegANDOR(pVBInfo->P3d4, 0x0a, ~0x02, tempax); - XGINew_SetReg1(pVBInfo->P3d4, 0x11, temp); + xgifb_reg_set(pVBInfo->P3d4, 0x11, temp); } unsigned short XGI_GetResInfo(unsigned short ModeNo, @@ -1219,11 +1219,11 @@ static void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex, i = XGINew_GetReg1(pVBInfo->P3c4, 0x0E); i &= 0xF0; i |= temp; - XGINew_SetReg1(pVBInfo->P3c4, 0x0E, i); + xgifb_reg_set(pVBInfo->P3c4, 0x0E, i); temp = (unsigned char) temp2; temp &= 0xFF; /* al */ - XGINew_SetReg1(pVBInfo->P3d4, 0x13, temp); + xgifb_reg_set(pVBInfo->P3d4, 0x13, temp); /* SetDisplayUnit */ temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; @@ -1243,7 +1243,7 @@ static void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex, if ((ModeNo == 0x4A) | (ModeNo == 0x49)) ah -= 1; - XGINew_SetReg1(pVBInfo->P3c4, 0x10, ah); + xgifb_reg_set(pVBInfo->P3c4, 0x10, ah); } static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, @@ -1430,12 +1430,12 @@ static void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->IF_DEF_LVDS == 1) { index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; data = XGINew_GetReg1(pVBInfo->P3c4, 0x31) & 0xCF; - XGINew_SetReg1(pVBInfo->P3c4, 0x31, data); - XGINew_SetReg1(pVBInfo->P3c4, 0x2B, + xgifb_reg_set(pVBInfo->P3c4, 0x31, data); + xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[index].SR2B); - XGINew_SetReg1(pVBInfo->P3c4, 0x2C, + xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[index].SR2C); - XGINew_SetReg1(pVBInfo->P3c4, 0x2D, 0x01); + xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01); } else if ((pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) && (pVBInfo->VBInfo & SetCRT2ToLCDA)) { @@ -1443,27 +1443,27 @@ static void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, RefreshRateTableIndex, HwDeviceExtension, pVBInfo); data = XGINew_GetReg1(pVBInfo->P3c4, 0x31) & 0xCF; - XGINew_SetReg1(pVBInfo->P3c4, 0x31, data); + xgifb_reg_set(pVBInfo->P3c4, 0x31, data); data = pVBInfo->VBVCLKData[vclkindex].Part4_A; - XGINew_SetReg1(pVBInfo->P3c4, 0x2B, data); + xgifb_reg_set(pVBInfo->P3c4, 0x2B, data); data = pVBInfo->VBVCLKData[vclkindex].Part4_B; - XGINew_SetReg1(pVBInfo->P3c4, 0x2C, data); - XGINew_SetReg1(pVBInfo->P3c4, 0x2D, 0x01); + xgifb_reg_set(pVBInfo->P3c4, 0x2C, data); + xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01); } else { index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; data = XGINew_GetReg1(pVBInfo->P3c4, 0x31) & 0xCF; - XGINew_SetReg1(pVBInfo->P3c4, 0x31, data); - XGINew_SetReg1(pVBInfo->P3c4, 0x2B, + xgifb_reg_set(pVBInfo->P3c4, 0x31, data); + xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[index].SR2B); - XGINew_SetReg1(pVBInfo->P3c4, 0x2C, + xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[index].SR2C); - XGINew_SetReg1(pVBInfo->P3c4, 0x2D, 0x01); + xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01); } if (HwDeviceExtension->jChipType >= XG20) { if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag & HalfDCLK) { data = XGINew_GetReg1(pVBInfo->P3c4, 0x2B); - XGINew_SetReg1(pVBInfo->P3c4, 0x2B, data); + xgifb_reg_set(pVBInfo->P3c4, 0x2B, data); data = XGINew_GetReg1(pVBInfo->P3c4, 0x2C); index = data; index &= 0xE0; @@ -1471,7 +1471,7 @@ static void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, data = data << 1; data += 1; data |= index; - XGINew_SetReg1(pVBInfo->P3c4, 0x2C, data); + xgifb_reg_set(pVBInfo->P3c4, 0x2C, data); } } } @@ -1484,27 +1484,27 @@ static void XGI_SetCRT1FIFO(unsigned short ModeNo, data = XGINew_GetReg1(pVBInfo->P3c4, 0x3D); data &= 0xfe; - XGINew_SetReg1(pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */ + xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */ if (ModeNo > 0x13) { - XGINew_SetReg1(pVBInfo->P3c4, 0x08, 0x34); + xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x34); data = XGINew_GetReg1(pVBInfo->P3c4, 0x09); data &= 0xC0; - XGINew_SetReg1(pVBInfo->P3c4, 0x09, data | 0x30); + xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x30); data = XGINew_GetReg1(pVBInfo->P3c4, 0x3D); data |= 0x01; - XGINew_SetReg1(pVBInfo->P3c4, 0x3D, data); + xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); } else { if (HwDeviceExtension->jChipType == XG27) { - XGINew_SetReg1(pVBInfo->P3c4, 0x08, 0x0E); + xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x0E); data = XGINew_GetReg1(pVBInfo->P3c4, 0x09); data &= 0xC0; - XGINew_SetReg1(pVBInfo->P3c4, 0x09, data | 0x20); + xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x20); } else { - XGINew_SetReg1(pVBInfo->P3c4, 0x08, 0xAE); + xgifb_reg_set(pVBInfo->P3c4, 0x08, 0xAE); data = XGINew_GetReg1(pVBInfo->P3c4, 0x09); data &= 0xF0; - XGINew_SetReg1(pVBInfo->P3c4, 0x09, data); + xgifb_reg_set(pVBInfo->P3c4, 0x09, data); } } @@ -1537,14 +1537,14 @@ static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, if (HwDeviceExtension->jChipType >= XG20) data &= ~0x04; /* 2 pixel mode */ - XGINew_SetReg1(pVBInfo->P3c4, 0x32, data); + xgifb_reg_set(pVBInfo->P3c4, 0x32, data); if (HwDeviceExtension->jChipType < XG20) { data = XGINew_GetReg1(pVBInfo->P3c4, 0x1F); data &= 0xE7; if (VCLK < 200) data |= 0x10; - XGINew_SetReg1(pVBInfo->P3c4, 0x1F, data); + xgifb_reg_set(pVBInfo->P3c4, 0x1F, data); } /* Jong for Adavantech LCD ripple issue @@ -1605,7 +1605,7 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, data2 |= 0x20; XGINew_SetRegANDOR(pVBInfo->P3c4, 0x06, ~0x3F, data2); - /* XGINew_SetReg1(pVBInfo->P3c4,0x06,data2); */ + /* xgifb_reg_set(pVBInfo->P3c4,0x06,data2); */ resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); if (ModeNo <= 0x13) xres = pVBInfo->StResInfo[resindex].HTotal; @@ -1661,21 +1661,21 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, data = 0x2c; else data = 0x6c; - XGINew_SetReg1(pVBInfo->P3d4, 0x52, data); + xgifb_reg_set(pVBInfo->P3d4, 0x52, data); XGINew_SetRegOR(pVBInfo->P3d4, 0x51, 0x10); } else if (HwDeviceExtension->jChipType >= XG20) { if (data & 0x40) data = 0x33; else data = 0x73; - XGINew_SetReg1(pVBInfo->P3d4, 0x52, data); - XGINew_SetReg1(pVBInfo->P3d4, 0x51, 0x02); + xgifb_reg_set(pVBInfo->P3d4, 0x52, data); + xgifb_reg_set(pVBInfo->P3d4, 0x51, 0x02); } else { if (data & 0x40) data = 0x2c; else data = 0x6c; - XGINew_SetReg1(pVBInfo->P3d4, 0x52, data); + xgifb_reg_set(pVBInfo->P3d4, 0x52, data); } } @@ -2610,9 +2610,9 @@ static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension); if (pVBInfo->IF_DEF_CH7007 == 1) { - XGINew_SetReg1(pVBInfo->P3c4, 0x2E, + xgifb_reg_set(pVBInfo->P3c4, 0x2E, CH7007TV_TimingHPtr[0].data[8]); - XGINew_SetReg1(pVBInfo->P3c4, 0x2F, + xgifb_reg_set(pVBInfo->P3c4, 0x2F, CH7007TV_TimingHPtr[0].data[9]); } @@ -2655,9 +2655,9 @@ static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->IF_DEF_CH7007 == 1) { XGINew_SetRegANDOR(pVBInfo->P3c4, 0x33, ~0x01, CH7007TV_TimingVPtr[0].data[7] & 0x01); - XGINew_SetReg1(pVBInfo->P3c4, 0x34, + xgifb_reg_set(pVBInfo->P3c4, 0x34, CH7007TV_TimingVPtr[0].data[8]); - XGINew_SetReg1(pVBInfo->P3c4, 0x3F, + xgifb_reg_set(pVBInfo->P3c4, 0x3F, CH7007TV_TimingVPtr[0].data[9]); } @@ -2833,14 +2833,14 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, if (tempcx >= tempax) tempcx -= tempax; - XGINew_SetReg1(pVBInfo->Part1Port, 0x1A, tempbx & 0x07); + xgifb_reg_set(pVBInfo->Part1Port, 0x1A, tempbx & 0x07); tempcx = tempcx >> 3; tempbx = tempbx >> 3; - XGINew_SetReg1(pVBInfo->Part1Port, 0x16, + xgifb_reg_set(pVBInfo->Part1Port, 0x16, (unsigned short) (tempbx & 0xff)); - XGINew_SetReg1(pVBInfo->Part1Port, 0x17, + xgifb_reg_set(pVBInfo->Part1Port, 0x17, (unsigned short) (tempcx & 0xff)); tempax = pVBInfo->HT; @@ -2868,8 +2868,8 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, tempcx &= 0x1f; tempax |= tempcx; - XGINew_SetReg1(pVBInfo->Part1Port, 0x15, tempax); - XGINew_SetReg1(pVBInfo->Part1Port, 0x14, + xgifb_reg_set(pVBInfo->Part1Port, 0x15, tempax); + xgifb_reg_set(pVBInfo->Part1Port, 0x14, (unsigned short) (tempbx & 0xff)); tempax = pVBInfo->VT; @@ -2884,15 +2884,15 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, if (tempcx >= tempax) tempcx -= tempax; - XGINew_SetReg1(pVBInfo->Part1Port, 0x1b, + xgifb_reg_set(pVBInfo->Part1Port, 0x1b, (unsigned short) (tempbx & 0xff)); - XGINew_SetReg1(pVBInfo->Part1Port, 0x1c, + xgifb_reg_set(pVBInfo->Part1Port, 0x1c, (unsigned short) (tempcx & 0xff)); tempbx = (tempbx >> 8) & 0x07; tempcx = (tempcx >> 8) & 0x07; - XGINew_SetReg1(pVBInfo->Part1Port, 0x1d, + xgifb_reg_set(pVBInfo->Part1Port, 0x1d, (unsigned short) ((tempcx << 3) | tempbx)); @@ -2912,7 +2912,7 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, if (tempcx >= tempax) tempcx -= tempax; - XGINew_SetReg1(pVBInfo->Part1Port, 0x18, + xgifb_reg_set(pVBInfo->Part1Port, 0x18, (unsigned short) (tempbx & 0xff)); XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, ~0x0f, (unsigned short) (tempcx & 0x0f)); @@ -2945,9 +2945,9 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, temp2 = temp1; push3 = temp2; - XGINew_SetReg1(pVBInfo->Part1Port, 0x37, + xgifb_reg_set(pVBInfo->Part1Port, 0x37, (unsigned short) (temp2 & 0xff)); - XGINew_SetReg1(pVBInfo->Part1Port, 0x36, + xgifb_reg_set(pVBInfo->Part1Port, 0x36, (unsigned short) ((temp2 >> 8) & 0xff)); tempbx = (unsigned short) (temp2 >> 16); @@ -2957,13 +2957,13 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, if (tempbx == pVBInfo->VDE) tempax |= 0x04; - XGINew_SetReg1(pVBInfo->Part1Port, 0x35, tempax); + xgifb_reg_set(pVBInfo->Part1Port, 0x35, tempax); if (pVBInfo->VBType & VB_XGI301C) { temp2 = push3; - XGINew_SetReg1(pVBInfo->Part4Port, 0x3c, + xgifb_reg_set(pVBInfo->Part4Port, 0x3c, (unsigned short) (temp2 & 0xff)); - XGINew_SetReg1(pVBInfo->Part4Port, 0x3b, + xgifb_reg_set(pVBInfo->Part4Port, 0x3b, (unsigned short) ((temp2 >> 8) & 0xff)); tempbx = (unsigned short) (temp2 >> 16); @@ -3001,7 +3001,7 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff); tempax = (unsigned short) (temp3 & 0xff); - XGINew_SetReg1(pVBInfo->Part1Port, 0x1f, tempax); + xgifb_reg_set(pVBInfo->Part1Port, 0x1f, tempax); temp1 = pVBInfo->VGAVDE << 18; temp1 = temp1 / push3; @@ -3012,9 +3012,9 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, tempax = ((tempbx >> 8) & 0xff) << 3; tempax |= (unsigned short) ((temp3 >> 8) & 0x07); - XGINew_SetReg1(pVBInfo->Part1Port, 0x20, + xgifb_reg_set(pVBInfo->Part1Port, 0x20, (unsigned short) (tempax & 0xff)); - XGINew_SetReg1(pVBInfo->Part1Port, 0x21, + xgifb_reg_set(pVBInfo->Part1Port, 0x21, (unsigned short) (tempbx & 0xff)); temp3 = temp3 >> 16; @@ -3022,9 +3022,9 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, if (modeflag & HalfDCLK) temp3 = temp3 >> 1; - XGINew_SetReg1(pVBInfo->Part1Port, 0x22, + xgifb_reg_set(pVBInfo->Part1Port, 0x22, (unsigned short) ((temp3 >> 8) & 0xff)); - XGINew_SetReg1(pVBInfo->Part1Port, 0x23, + xgifb_reg_set(pVBInfo->Part1Port, 0x23, (unsigned short) (temp3 & 0xff)); } } @@ -3254,15 +3254,15 @@ static void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex, XGINew_SetRegANDOR(pVBInfo->P3d4, 0x31, ~0x30, (unsigned short) (0x10 * i)); if (pVBInfo->IF_DEF_CH7007 == 1) { - XGINew_SetReg1(pVBInfo->P3c4, 0x2b, di_0); - XGINew_SetReg1(pVBInfo->P3c4, 0x2c, di_1); + xgifb_reg_set(pVBInfo->P3c4, 0x2b, di_0); + xgifb_reg_set(pVBInfo->P3c4, 0x2c, di_1); } else if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA)) && (!(pVBInfo->VBInfo & SetInSlaveMode))) { - XGINew_SetReg1(pVBInfo->P3c4, 0x2e, di_0); - XGINew_SetReg1(pVBInfo->P3c4, 0x2f, di_1); + xgifb_reg_set(pVBInfo->P3c4, 0x2e, di_0); + xgifb_reg_set(pVBInfo->P3c4, 0x2f, di_1); } else { - XGINew_SetReg1(pVBInfo->P3c4, 0x2b, di_0); - XGINew_SetReg1(pVBInfo->P3c4, 0x2c, di_1); + xgifb_reg_set(pVBInfo->P3c4, 0x2b, di_0); + xgifb_reg_set(pVBInfo->P3c4, 0x2c, di_1); } } } @@ -3347,7 +3347,7 @@ static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, XGINew_SetRegANDOR(pVBInfo->P3d4, 0x3d, tempbl, temp); if (!(pVBInfo->SetFlag & ReserveTVOption)) - XGINew_SetReg1(pVBInfo->P3d4, 0x3e, tempch); + xgifb_reg_set(pVBInfo->P3d4, 0x3e, tempch); } else { return; } @@ -4040,17 +4040,17 @@ void XGINew_IsLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, u data = XGINew_GetReg1(pVBInfo->P3c4, 0x0F); data &= 0x7F; - XGINew_SetReg1(pVBInfo->P3c4, 0x0F, data); + xgifb_reg_set(pVBInfo->P3c4, 0x0F, data); if (ModeNo > 0x13) { ModeFlag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; if ((ModeFlag & HalfDCLK) && (ModeFlag & DoubleScanMode)) { data = XGINew_GetReg1(pVBInfo->P3c4, 0x0F); data |= 0x80; - XGINew_SetReg1(pVBInfo->P3c4, 0x0F, data); + xgifb_reg_set(pVBInfo->P3c4, 0x0F, data); data = XGINew_GetReg1(pVBInfo->P3c4, 0x01); data &= 0xF7; - XGINew_SetReg1(pVBInfo->P3c4, 0x01, data); + xgifb_reg_set(pVBInfo->P3c4, 0x01, data); } } } @@ -4087,7 +4087,7 @@ static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo) temp = XG21GPIODataTransfer(temp); temp &= 0x23; - XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A); + xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A); return temp; } @@ -4108,7 +4108,7 @@ static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo) temp &= 0x0C; temp >>= 2; - XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A); + xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A); CRB4 = XGINew_GetReg1(pVBInfo->P3d4, 0xB4); temp |= ((CRB4 & 0x04) << 3); return temp; @@ -4215,7 +4215,7 @@ static void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBIn { unsigned short temp1, temp2; - XGINew_SetReg1(pVBInfo->P3d4, 0x34, ModeNo); /* reserve CR34 for CRT1 Mode No */ + xgifb_reg_set(pVBInfo->P3d4, 0x34, ModeNo); /* reserve CR34 for CRT1 Mode No */ temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8; temp2 = ~(SetInSlaveMode >> 8); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x31, temp2, temp1); @@ -4562,15 +4562,15 @@ static void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->VBType & VB_XGI301) { /* shampoo 0129 */ /* 301 */ - XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, 0x10); - XGINew_SetReg1(pVBInfo->Part4Port, 0x0B, di_1); - XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, di_0); + xgifb_reg_set(pVBInfo->Part4Port, 0x0A, 0x10); + xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1); + xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0); } else { /* 301b/302b/301lv/302lv */ - XGINew_SetReg1(pVBInfo->Part4Port, 0x0A, di_0); - XGINew_SetReg1(pVBInfo->Part4Port, 0x0B, di_1); + xgifb_reg_set(pVBInfo->Part4Port, 0x0A, di_0); + xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1); } - XGINew_SetReg1(pVBInfo->Part4Port, 0x00, 0x12); + xgifb_reg_set(pVBInfo->Part4Port, 0x00, 0x12); if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) XGINew_SetRegOR(pVBInfo->Part4Port, 0x12, 0x28); @@ -4648,16 +4648,16 @@ static void XGI_SetCRT2Offset(unsigned short ModeNo, offset = XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex, HwDeviceExtension, pVBInfo); temp = (unsigned char) (offset & 0xFF); - XGINew_SetReg1(pVBInfo->Part1Port, 0x07, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp); temp = (unsigned char) ((offset & 0xFF00) >> 8); - XGINew_SetReg1(pVBInfo->Part1Port, 0x09, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x09, temp); temp = (unsigned char) (((offset >> 3) & 0xFF) + 1); - XGINew_SetReg1(pVBInfo->Part1Port, 0x03, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp); } static void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo) { - XGINew_SetReg1(pVBInfo->Part1Port, 0x01, 0x3B); /* threshold high ,disable auto threshold */ + xgifb_reg_set(pVBInfo->Part1Port, 0x01, 0x3B); /* threshold high ,disable auto threshold */ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04); /* threshold low default 04h */ } @@ -4680,10 +4680,10 @@ static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, /* XGI_SetCRT2Sync(ModeNo,RefreshRateTableIndex); */ for (tempcx = 4; tempcx < 7; tempcx++) - XGINew_SetReg1(pVBInfo->Part1Port, tempcx, 0x0); + xgifb_reg_set(pVBInfo->Part1Port, tempcx, 0x0); - XGINew_SetReg1(pVBInfo->Part1Port, 0x50, 0x00); - XGINew_SetReg1(pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */ + xgifb_reg_set(pVBInfo->Part1Port, 0x50, 0x00); + xgifb_reg_set(pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */ } static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, @@ -4708,11 +4708,11 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, /* bainy change table name */ if (modeflag & HalfDCLK) { temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x08, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp); temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4; XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x09, ~0x0F0, temp); temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2; pushbx = pVBInfo->VGAHDE / 2 + 16; tempcx = tempcx >> 1; @@ -4739,14 +4739,14 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp); } else { temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x08, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp); temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4; XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x09, ~0x0F0, temp); temp = (pVBInfo->VGAHDE + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */ pushbx = pVBInfo->VGAHDE + 16; tempcx = tempcx >> 1; @@ -4771,7 +4771,7 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, tempcx = pVBInfo->VGAHT; temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp); } tempax = (tempax & 0x00FF) | (tempbx & 0xFF00); @@ -4779,9 +4779,9 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4); tempax |= (tempbx & 0xFF00); temp = (tempax & 0xFF00) >> 8; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0C, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp); temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0D, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp); tempcx = (pVBInfo->VGAVT - 1); temp = tempcx & 0x00FF; @@ -4790,13 +4790,13 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, temp--; } - XGINew_SetReg1(pVBInfo->Part1Port, 0x0E, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp); tempbx = pVBInfo->VGAVDE - 1; temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0F, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x0F, temp); temp = ((tempbx & 0xFF00) << 3) >> 8; temp |= ((tempcx & 0xFF00) >> 8); - XGINew_SetReg1(pVBInfo->Part1Port, 0x12, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x12, temp); tempax = pVBInfo->VGAVDE; tempbx = pVBInfo->VGAVDE; @@ -4824,10 +4824,10 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, } temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp); temp = ((tempbx & 0xFF00) >> 8) << 4; temp = ((tempcx & 0x000F) | (temp)); - XGINew_SetReg1(pVBInfo->Part1Port, 0x11, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x11, temp); tempax = 0; if (modeflag & DoubleScanMode) @@ -4873,7 +4873,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, return; temp = 0xFF; /* set MAX HT */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x03, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp); /* if (modeflag & Charx8Dot) */ /* tempcx = 0x08; */ /* else */ @@ -4890,7 +4890,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, tempax = (tempax / tempcx) - 1; tempbx |= ((tempax & 0x00FF) << 8); temp = tempax & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x04, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x04, temp); temp = (tempbx & 0xFF00) >> 8; @@ -4911,8 +4911,8 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, } } - XGINew_SetReg1(pVBInfo->Part1Port, 0x05, temp); /* 0x05 Horizontal Display Start */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x06, 0x03); /* 0x06 Horizontal Blank end */ + xgifb_reg_set(pVBInfo->Part1Port, 0x05, temp); /* 0x05 Horizontal Display Start */ + xgifb_reg_set(pVBInfo->Part1Port, 0x06, 0x03); /* 0x06 Horizontal Blank end */ if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */ if (pVBInfo->VBInfo & SetCRT2ToTV) @@ -4989,30 +4989,30 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, } } - XGINew_SetReg1(pVBInfo->Part1Port, 0x07, temp); /* 0x07 Horizontal Retrace Start */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x08, 0); /* 0x08 Horizontal Retrace End */ + xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp); /* 0x07 Horizontal Retrace Start */ + xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0); /* 0x08 Horizontal Retrace End */ if (pVBInfo->VBInfo & SetCRT2ToTV) { if (pVBInfo->TVInfo & TVSimuMode) { if ((ModeNo == 0x06) || (ModeNo == 0x10) || (ModeNo == 0x11) || (ModeNo == 0x13) || (ModeNo == 0x0F)) { - XGINew_SetReg1(pVBInfo->Part1Port, 0x07, 0x5b); - XGINew_SetReg1(pVBInfo->Part1Port, 0x08, 0x03); + xgifb_reg_set(pVBInfo->Part1Port, 0x07, 0x5b); + xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0x03); } if ((ModeNo == 0x00) || (ModeNo == 0x01)) { if (pVBInfo->TVInfo & SetNTSCTV) { - XGINew_SetReg1(pVBInfo->Part1Port, + xgifb_reg_set(pVBInfo->Part1Port, 0x07, 0x2A); - XGINew_SetReg1(pVBInfo->Part1Port, + xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0x61); } else { - XGINew_SetReg1(pVBInfo->Part1Port, + xgifb_reg_set(pVBInfo->Part1Port, 0x07, 0x2A); - XGINew_SetReg1(pVBInfo->Part1Port, + xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0x41); - XGINew_SetReg1(pVBInfo->Part1Port, + xgifb_reg_set(pVBInfo->Part1Port, 0x0C, 0xF0); } } @@ -5020,16 +5020,16 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, if ((ModeNo == 0x02) || (ModeNo == 0x03) || (ModeNo == 0x07)) { if (pVBInfo->TVInfo & SetNTSCTV) { - XGINew_SetReg1(pVBInfo->Part1Port, + xgifb_reg_set(pVBInfo->Part1Port, 0x07, 0x54); - XGINew_SetReg1(pVBInfo->Part1Port, + xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0x00); } else { - XGINew_SetReg1(pVBInfo->Part1Port, + xgifb_reg_set(pVBInfo->Part1Port, 0x07, 0x55); - XGINew_SetReg1(pVBInfo->Part1Port, + xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0x00); - XGINew_SetReg1(pVBInfo->Part1Port, + xgifb_reg_set(pVBInfo->Part1Port, 0x0C, 0xF0); } } @@ -5037,23 +5037,23 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, if ((ModeNo == 0x04) || (ModeNo == 0x05) || (ModeNo == 0x0D) || (ModeNo == 0x50)) { if (pVBInfo->TVInfo & SetNTSCTV) { - XGINew_SetReg1(pVBInfo->Part1Port, + xgifb_reg_set(pVBInfo->Part1Port, 0x07, 0x30); - XGINew_SetReg1(pVBInfo->Part1Port, + xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0x03); } else { - XGINew_SetReg1(pVBInfo->Part1Port, + xgifb_reg_set(pVBInfo->Part1Port, 0x07, 0x2f); - XGINew_SetReg1(pVBInfo->Part1Port, + xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0x02); } } } } - XGINew_SetReg1(pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */ + xgifb_reg_set(pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */ XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0xF0, 0x00); - XGINew_SetReg1(pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */ + xgifb_reg_set(pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */ tempbx = pVBInfo->VGAVT; push1 = tempbx; @@ -5087,11 +5087,11 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, temp = tempbx & 0x00FF; tempbx--; temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp); /* 0x10 vertical Blank Start */ + xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp); /* 0x10 vertical Blank Start */ tempbx = push2; tempbx--; temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0E, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x0E, temp); if (tempbx & 0x0100) tempcx |= 0x0002; @@ -5105,12 +5105,12 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, tempcx |= 0x0040; temp = (tempax & 0xFF00) >> 8; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0B, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x0B, temp); if (tempbx & 0x0400) tempcx |= 0x0600; - XGINew_SetReg1(pVBInfo->Part1Port, 0x11, 0x00); /* 0x11 Vertival Blank End */ + xgifb_reg_set(pVBInfo->Part1Port, 0x11, 0x00); /* 0x11 Vertival Blank End */ tempax = push1; tempax -= tempbx; /* 0x0C Vertical Retrace Start */ @@ -5174,10 +5174,10 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, } temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0C, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x0C, temp); tempbx--; temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x10, temp); + xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp); if (tempbx & 0x0100) tempcx |= 0x0008; @@ -5199,15 +5199,15 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx = push1; /* pop ax */ temp = tempbx & 0x00FF; temp &= 0x0F; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0D, temp); /* 0x0D vertical Retrace End */ + xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp); /* 0x0D vertical Retrace End */ if (tempbx & 0x0010) tempcx |= 0x2000; temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */ + xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */ temp = (tempcx & 0x0FF00) >> 8; - XGINew_SetReg1(pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */ + xgifb_reg_set(pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */ tempax = modeflag; temp = (tempax & 0xFF00) >> 8; @@ -5216,16 +5216,16 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) temp |= 0x01; - XGINew_SetReg1(pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */ + xgifb_reg_set(pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */ + xgifb_reg_set(pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */ + xgifb_reg_set(pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */ if (pVBInfo->LCDInfo & LCDRGB18Bit) temp = 0x80; else temp = 0x00; - XGINew_SetReg1(pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */ + xgifb_reg_set(pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */ return; } @@ -5274,7 +5274,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, tempax = (tempax & 0xff00) >> 8; - XGINew_SetReg1(pVBInfo->Part2Port, 0x0, tempax); + xgifb_reg_set(pVBInfo->Part2Port, 0x0, tempax); TimingPoint = pVBInfo->NTSCTiming; if (pVBInfo->TVInfo & SetPALTV) @@ -5305,10 +5305,10 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, } for (i = 0x01, j = 0; i <= 0x2D; i++, j++) - XGINew_SetReg1(pVBInfo->Part2Port, i, TimingPoint[j]); + xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]); for (i = 0x39; i <= 0x45; i++, j++) - XGINew_SetReg1(pVBInfo->Part2Port, i, TimingPoint[j]); /* di->temp2[j] */ + xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]); /* di->temp2[j] */ if (pVBInfo->VBInfo & SetCRT2ToTV) XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x3A, 0x1F, 0x00); @@ -5347,7 +5347,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, } } - XGINew_SetReg1(pVBInfo->Part2Port, 0x01, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp); tempax = push1; temp = (tempax & 0xFF00) >> 8; temp += TimingPoint[1]; @@ -5365,7 +5365,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, } } } - XGINew_SetReg1(pVBInfo->Part2Port, 0x02, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x02, temp); } /* 301b */ @@ -5376,7 +5376,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, tempcx -= 2; temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x1B, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x1B, temp); temp = (tempcx & 0xFF00) >> 8; XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1D, ~0x0F, temp); @@ -5396,7 +5396,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx += tempcx; push2 = tempbx; temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x24, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x24, temp); temp = (tempbx & 0xFF00) >> 8; temp = temp << 4; XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x25, 0x0F, temp); @@ -5414,7 +5414,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, j += 2; tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8)); temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x27, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x27, temp); temp = ((tempcx & 0xFF00) >> 8) << 4; XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x28, 0x0F, temp); @@ -5441,7 +5441,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, tempcx = tempax - 1; } temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x2E, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x2E, temp); tempbx = pVBInfo->VDE; @@ -5480,7 +5480,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, } } - XGINew_SetReg1(pVBInfo->Part2Port, 0x2F, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x2F, temp); temp = (tempcx & 0xFF00) >> 8; temp |= ((tempbx & 0xFF00) >> 8) << 6; @@ -5500,7 +5500,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, } } - XGINew_SetReg1(pVBInfo->Part2Port, 0x30, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x30, temp); if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { /* TV gatingno */ @@ -5521,13 +5521,13 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, if (tempbx & 0x0400) temp |= 0x40; - XGINew_SetReg1(pVBInfo->Part4Port, 0x10, temp); + xgifb_reg_set(pVBInfo->Part4Port, 0x10, temp); } temp = (((tempbx - 3) & 0x0300) >> 8) << 5; - XGINew_SetReg1(pVBInfo->Part2Port, 0x46, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x46, temp); temp = (tempbx - 3) & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x47, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x47, temp); } tempbx = tempbx & 0x00FF; @@ -5597,7 +5597,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, temp = (tempax & 0x00FF) >> 8; } - XGINew_SetReg1(pVBInfo->Part2Port, 0x44, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x44, temp); temp = (tempbx & 0xFF00) >> 8; XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x45, ~0x03F, temp); temp = tempcx & 0x00FF; @@ -5618,9 +5618,9 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, } temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x4b, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x4b, temp); temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x4c, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x4c, temp); temp = ((tempcx & 0xFF00) >> 8) & 0x03; temp = temp << 2; @@ -5636,18 +5636,18 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, temp |= 0x60; } - XGINew_SetReg1(pVBInfo->Part2Port, 0x4d, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x4d, temp); temp = XGINew_GetReg1(pVBInfo->Part2Port, 0x43); /* 301b change */ - XGINew_SetReg1(pVBInfo->Part2Port, 0x43, (unsigned short) (temp - 3)); + xgifb_reg_set(pVBInfo->Part2Port, 0x43, (unsigned short) (temp - 3)); if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) { if (pVBInfo->TVInfo & NTSC1024x768) { TimingPoint = XGI_NTSC1024AdjTime; for (i = 0x1c, j = 0; i <= 0x30; i++, j++) { - XGINew_SetReg1(pVBInfo->Part2Port, i, + xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]); } - XGINew_SetReg1(pVBInfo->Part2Port, 0x43, 0x72); + xgifb_reg_set(pVBInfo->Part2Port, 0x43, 0x72); } } @@ -5670,7 +5670,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { if (!(pVBInfo->VBInfo & SetInSlaveMode)) - XGINew_SetReg1(pVBInfo->Part2Port, 0x0B, 0x00); + xgifb_reg_set(pVBInfo->Part2Port, 0x0B, 0x00); } if (pVBInfo->VBInfo & SetCRT2ToTV) @@ -5708,7 +5708,7 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx -= 1; temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x2C, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x2C, temp); temp = (tempbx & 0xFF00) >> 8; temp = temp << 4; XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2B, 0x0F, temp); @@ -5724,22 +5724,22 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, } } - XGINew_SetReg1(pVBInfo->Part2Port, 0x0B, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x0B, temp); tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */ push1 = tempbx; tempbx--; temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x03, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x03, temp); temp = ((tempbx & 0xFF00) >> 8) & 0x07; XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0C, ~0x07, temp); tempcx = pVBInfo->VT - 1; push2 = tempcx + 1; temp = tempcx & 0x00FF; /* RVTVT=VT-1 */ - XGINew_SetReg1(pVBInfo->Part2Port, 0x19, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x19, temp); temp = (tempcx & 0xFF00) >> 8; temp = temp << 5; - XGINew_SetReg1(pVBInfo->Part2Port, 0x1A, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x1A, temp); XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x09, 0xF0, 0x00); XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0xF0, 0x00); XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x17, 0xFB, 0x00); @@ -5784,15 +5784,15 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, tempcx -= tempax; /* lcdvdes */ temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */ - XGINew_SetReg1(pVBInfo->Part2Port, 0x05, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x05, temp); temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x06, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x06, temp); tempch = ((tempcx & 0xFF00) >> 8) & 0x07; tempbh = ((tempbx & 0xFF00) >> 8) & 0x07; tempah = tempch; tempah = tempah << 3; tempah |= tempbh; - XGINew_SetReg1(pVBInfo->Part2Port, 0x02, tempah); + xgifb_reg_set(pVBInfo->Part2Port, 0x02, tempah); /* getlcdsync() */ XGI_GetLCDSync(&tempax, &tempbx, pVBInfo); @@ -5806,11 +5806,11 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, tempcx -= tempax; temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */ - XGINew_SetReg1(pVBInfo->Part2Port, 0x04, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x04, temp); temp = (tempbx & 0xFF00) >> 8; temp = temp << 4; temp |= (tempcx & 0x000F); - XGINew_SetReg1(pVBInfo->Part2Port, 0x01, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x01, temp); tempcx = pushbx; tempax = pVBInfo->HT; tempbx = pVBInfo->LCDHDES; @@ -5834,13 +5834,13 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, tempcx -= tempax; temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */ + xgifb_reg_set(pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */ temp = ((tempbx & 0xFF00) >> 8) << 4; - XGINew_SetReg1(pVBInfo->Part2Port, 0x20, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x20, temp); temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */ + xgifb_reg_set(pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */ temp = (tempcx & 0xFF00) >> 8; - XGINew_SetReg1(pVBInfo->Part2Port, 0x25, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x25, temp); /* getlcdsync() */ XGI_GetLCDSync(&tempax, &tempbx, pVBInfo); @@ -5863,13 +5863,13 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, tempcx -= tempax; temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */ - XGINew_SetReg1(pVBInfo->Part2Port, 0x1C, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x1C, temp); temp = (tempbx & 0xFF00) >> 8; temp = temp << 4; XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1D, ~0x0F0, temp); temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */ - XGINew_SetReg1(pVBInfo->Part2Port, 0x21, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x21, temp); if (!(pVBInfo->LCDInfo & LCDVESATiming)) { if (pVBInfo->VGAVDE == 525) { @@ -5880,8 +5880,8 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, } else temp = 0xC4; - XGINew_SetReg1(pVBInfo->Part2Port, 0x2f, temp); - XGINew_SetReg1(pVBInfo->Part2Port, 0x30, 0xB3); + xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x30, 0xB3); } if (pVBInfo->VGAVDE == 420) { @@ -5891,7 +5891,7 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, temp = 0x4F; } else temp = 0x4E; - XGINew_SetReg1(pVBInfo->Part2Port, 0x2f, temp); + xgifb_reg_set(pVBInfo->Part2Port, 0x2f, temp); } } } @@ -5963,12 +5963,12 @@ static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo) Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */ for (i = 0x80, j = 0; i <= 0xBF; i++, j++) - XGINew_SetReg1(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]); + xgifb_reg_set(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]); if ((pVBInfo->VBInfo & SetCRT2ToTV) && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) { Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo); /* Set Vertical Scaling */ for (i = 0xC0, j = 0; i < 0xFF; i++, j++) - XGINew_SetReg1(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]); + xgifb_reg_set(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]); } if ((pVBInfo->VBInfo & SetCRT2ToTV) && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) @@ -5990,22 +5990,22 @@ static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, else modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */ - XGINew_SetReg1(pVBInfo->Part3Port, 0x00, 0x00); + xgifb_reg_set(pVBInfo->Part3Port, 0x00, 0x00); if (pVBInfo->TVInfo & SetPALTV) { - XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xFA); - XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xC8); + xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA); + xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8); } else { - XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xF5); - XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xB7); + xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xF5); + xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xB7); } if (!(pVBInfo->VBInfo & SetCRT2ToTV)) return; if (pVBInfo->TVInfo & SetPALMTV) { - XGINew_SetReg1(pVBInfo->Part3Port, 0x13, 0xFA); - XGINew_SetReg1(pVBInfo->Part3Port, 0x14, 0xC8); - XGINew_SetReg1(pVBInfo->Part3Port, 0x3D, 0xA8); + xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA); + xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8); + xgifb_reg_set(pVBInfo->Part3Port, 0x3D, 0xA8); } if ((pVBInfo->VBInfo & SetCRT2ToHiVisionTV) || (pVBInfo->VBInfo @@ -6027,11 +6027,11 @@ static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, tempdi = pVBInfo->Ren750pGroup3; for (i = 0; i <= 0x3E; i++) - XGINew_SetReg1(pVBInfo->Part3Port, i, tempdi[i]); + xgifb_reg_set(pVBInfo->Part3Port, i, tempdi[i]); if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */ if (pVBInfo->TVInfo & SetYPbPrMode525p) - XGINew_SetReg1(pVBInfo->Part3Port, 0x28, 0x3f); + xgifb_reg_set(pVBInfo->Part3Port, 0x28, 0x3f); } } return; @@ -6052,15 +6052,15 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */ temp = pVBInfo->RVBHCFACT; - XGINew_SetReg1(pVBInfo->Part4Port, 0x13, temp); + xgifb_reg_set(pVBInfo->Part4Port, 0x13, temp); tempbx = pVBInfo->RVBHCMAX; temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part4Port, 0x14, temp); + xgifb_reg_set(pVBInfo->Part4Port, 0x14, temp); temp2 = ((tempbx & 0xFF00) >> 8) << 7; tempcx = pVBInfo->VGAHT - 1; temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part4Port, 0x16, temp); + xgifb_reg_set(pVBInfo->Part4Port, 0x16, temp); temp = ((tempcx & 0xFF00) >> 8) << 3; temp2 |= temp; @@ -6070,9 +6070,9 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, tempcx -= 5; temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part4Port, 0x17, temp); + xgifb_reg_set(pVBInfo->Part4Port, 0x17, temp); temp = temp2 | ((tempcx & 0xFF00) >> 8); - XGINew_SetReg1(pVBInfo->Part4Port, 0x15, temp); + xgifb_reg_set(pVBInfo->Part4Port, 0x15, temp); XGINew_SetRegOR(pVBInfo->Part4Port, 0x0D, 0x08); tempcx = pVBInfo->VBInfo; tempbx = pVBInfo->VGAHDE; @@ -6120,7 +6120,7 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, tempcx = pVBInfo->RVBHRS; temp = tempcx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part4Port, 0x18, temp); + xgifb_reg_set(pVBInfo->Part4Port, 0x18, temp); tempeax = pVBInfo->VGAVDE; tempcx |= 0x04000; @@ -6140,21 +6140,21 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, tempebx++; temp = (unsigned short) (tempebx & 0x000000FF); - XGINew_SetReg1(pVBInfo->Part4Port, 0x1B, temp); + xgifb_reg_set(pVBInfo->Part4Port, 0x1B, temp); temp = (unsigned short) ((tempebx & 0x0000FF00) >> 8); - XGINew_SetReg1(pVBInfo->Part4Port, 0x1A, temp); + xgifb_reg_set(pVBInfo->Part4Port, 0x1A, temp); tempbx = (unsigned short) (tempebx >> 16); temp = tempbx & 0x00FF; temp = temp << 4; temp |= ((tempcx & 0xFF00) >> 8); - XGINew_SetReg1(pVBInfo->Part4Port, 0x19, temp); + xgifb_reg_set(pVBInfo->Part4Port, 0x19, temp); /* 301b */ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { temp = 0x0028; - XGINew_SetReg1(pVBInfo->Part4Port, 0x1C, temp); + xgifb_reg_set(pVBInfo->Part4Port, 0x1C, temp); tempax = pVBInfo->VGAHDE; if (modeflag & HalfDCLK) tempax = tempax >> 1; @@ -6200,9 +6200,9 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, temp = (tempax & 0xFF00) >> 8; temp = ((temp & 0x0003) << 4); - XGINew_SetReg1(pVBInfo->Part4Port, 0x1E, temp); + xgifb_reg_set(pVBInfo->Part4Port, 0x1E, temp); temp = (tempax & 0x00FF); - XGINew_SetReg1(pVBInfo->Part4Port, 0x1D, temp); + xgifb_reg_set(pVBInfo->Part4Port, 0x1D, temp); if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) { if (pVBInfo->VGAHDE > 800) @@ -6231,7 +6231,7 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, temp = ((tempbx & 0x0700) >> 8) << 3; XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x21, 0x00C0, temp); temp = tempbx & 0x00FF; - XGINew_SetReg1(pVBInfo->Part4Port, 0x22, temp); + xgifb_reg_set(pVBInfo->Part4Port, 0x22, temp); } /* end 301b */ @@ -6306,7 +6306,7 @@ void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl, temp = XG21GPIODataTransfer(temp); temp &= ~tempbh; temp |= tempbl; - XGINew_SetReg1(pVBInfo->P3d4, 0x48, temp); + xgifb_reg_set(pVBInfo->P3d4, 0x48, temp); } void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl, @@ -6536,7 +6536,7 @@ static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE; temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); - XGINew_SetReg1(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */ + xgifb_reg_set(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */ if (!(modeflag & Charx8Dot)) XGINew_SetRegOR(pVBInfo->P3c4, 0x1, 0x1); @@ -6544,12 +6544,12 @@ static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde /* HT SR0B[1:0] CR00 */ value = (LVDSHT >> 3) - 5; XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0x03, (value & 0x300) >> 8); - XGINew_SetReg1(pVBInfo->P3d4, 0x0, (value & 0xFF)); + xgifb_reg_set(pVBInfo->P3d4, 0x0, (value & 0xFF)); /* HBS SR0B[5:4] CR02 */ value = (LVDSHBS >> 3) - 1; XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0x30, (value & 0x300) >> 4); - XGINew_SetReg1(pVBInfo->P3d4, 0x2, (value & 0xFF)); + xgifb_reg_set(pVBInfo->P3d4, 0x2, (value & 0xFF)); /* HBE SR0C[1:0] CR05[7] CR03[4:0] */ value = (LVDSHBE >> 3) - 1; @@ -6560,12 +6560,12 @@ static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde /* HRS SR0B[7:6] CR04 */ value = (LVDSHRS >> 3) + 2; XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0xC0, (value & 0x300) >> 2); - XGINew_SetReg1(pVBInfo->P3d4, 0x4, (value & 0xFF)); + xgifb_reg_set(pVBInfo->P3d4, 0x4, (value & 0xFF)); /* Panel HRS SR2F[1:0] SR2E[7:0] */ value--; XGINew_SetRegANDOR(pVBInfo->P3c4, 0x2F, ~0x03, (value & 0x300) >> 8); - XGINew_SetReg1(pVBInfo->P3c4, 0x2E, (value & 0xFF)); + xgifb_reg_set(pVBInfo->P3c4, 0x2E, (value & 0xFF)); /* HRE SR0C[2] CR05[4:0] */ value = (LVDSHRE >> 3) + 2; @@ -6581,30 +6581,30 @@ static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x01, (value & 0x400) >> 10); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x20, (value & 0x200) >> 4); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x01, (value & 0x100) >> 8); - XGINew_SetReg1(pVBInfo->P3d4, 0x06, (value & 0xFF)); + xgifb_reg_set(pVBInfo->P3d4, 0x06, (value & 0xFF)); /* VBS SR0A[2] CR09[5] CR07[3] CR15 */ value = LVDSVBS - 1; XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x04, (value & 0x400) >> 8); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x09, ~0x20, (value & 0x200) >> 4); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x08, (value & 0x100) >> 5); - XGINew_SetReg1(pVBInfo->P3d4, 0x15, (value & 0xFF)); + xgifb_reg_set(pVBInfo->P3d4, 0x15, (value & 0xFF)); /* VBE SR0A[4] CR16 */ value = LVDSVBE - 1; XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x10, (value & 0x100) >> 4); - XGINew_SetReg1(pVBInfo->P3d4, 0x16, (value & 0xFF)); + xgifb_reg_set(pVBInfo->P3d4, 0x16, (value & 0xFF)); /* VRS SR0A[3] CR7[7][2] CR10 */ value = LVDSVRS - 1; XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x08, (value & 0x400) >> 7); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x80, (value & 0x200) >> 2); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x04, (value & 0x100) >> 6); - XGINew_SetReg1(pVBInfo->P3d4, 0x10, (value & 0xFF)); + xgifb_reg_set(pVBInfo->P3d4, 0x10, (value & 0xFF)); /* Panel VRS SR3F[1:0] SR34[7:0] SR33[0] */ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0x03, (value & 0x600) >> 9); - XGINew_SetReg1(pVBInfo->P3c4, 0x34, (value >> 1) & 0xFF); + xgifb_reg_set(pVBInfo->P3c4, 0x34, (value >> 1) & 0xFF); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x33, ~0x01, value & 0x01); /* VRE SR0A[5] CR11[3:0] */ @@ -6618,10 +6618,10 @@ static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde for (temp = 0, value = 0; temp < 3; temp++) { XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, value); - XGINew_SetReg1(pVBInfo->P3c4, + xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1); - XGINew_SetReg1(pVBInfo->P3c4, + xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2); value += 0x10; @@ -6721,7 +6721,7 @@ static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE; temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); - XGINew_SetReg1(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */ + xgifb_reg_set(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */ if (!(modeflag & Charx8Dot)) XGINew_SetRegOR(pVBInfo->P3c4, 0x1, 0x1); @@ -6729,12 +6729,12 @@ static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde /* HT SR0B[1:0] CR00 */ value = (LVDSHT >> 3) - 5; XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0x03, (value & 0x300) >> 8); - XGINew_SetReg1(pVBInfo->P3d4, 0x0, (value & 0xFF)); + xgifb_reg_set(pVBInfo->P3d4, 0x0, (value & 0xFF)); /* HBS SR0B[5:4] CR02 */ value = (LVDSHBS >> 3) - 1; XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0x30, (value & 0x300) >> 4); - XGINew_SetReg1(pVBInfo->P3d4, 0x2, (value & 0xFF)); + xgifb_reg_set(pVBInfo->P3d4, 0x2, (value & 0xFF)); /* HBE SR0C[1:0] CR05[7] CR03[4:0] */ value = (LVDSHBE >> 3) - 1; @@ -6745,12 +6745,12 @@ static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde /* HRS SR0B[7:6] CR04 */ value = (LVDSHRS >> 3) + 2; XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0xC0, (value & 0x300) >> 2); - XGINew_SetReg1(pVBInfo->P3d4, 0x4, (value & 0xFF)); + xgifb_reg_set(pVBInfo->P3d4, 0x4, (value & 0xFF)); /* Panel HRS SR2F[1:0] SR2E[7:0] */ value--; XGINew_SetRegANDOR(pVBInfo->P3c4, 0x2F, ~0x03, (value & 0x300) >> 8); - XGINew_SetReg1(pVBInfo->P3c4, 0x2E, (value & 0xFF)); + xgifb_reg_set(pVBInfo->P3c4, 0x2E, (value & 0xFF)); /* HRE SR0C[2] CR05[4:0] */ value = (LVDSHRE >> 3) + 2; @@ -6766,30 +6766,30 @@ static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x01, (value & 0x400) >> 10); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x20, (value & 0x200) >> 4); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x01, (value & 0x100) >> 8); - XGINew_SetReg1(pVBInfo->P3d4, 0x06, (value & 0xFF)); + xgifb_reg_set(pVBInfo->P3d4, 0x06, (value & 0xFF)); /* VBS SR0A[2] CR09[5] CR07[3] CR15 */ value = LVDSVBS - 1; XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x04, (value & 0x400) >> 8); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x09, ~0x20, (value & 0x200) >> 4); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x08, (value & 0x100) >> 5); - XGINew_SetReg1(pVBInfo->P3d4, 0x15, (value & 0xFF)); + xgifb_reg_set(pVBInfo->P3d4, 0x15, (value & 0xFF)); /* VBE SR0A[4] CR16 */ value = LVDSVBE - 1; XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x10, (value & 0x100) >> 4); - XGINew_SetReg1(pVBInfo->P3d4, 0x16, (value & 0xFF)); + xgifb_reg_set(pVBInfo->P3d4, 0x16, (value & 0xFF)); /* VRS SR0A[3] CR7[7][2] CR10 */ value = LVDSVRS - 1; XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x08, (value & 0x400) >> 7); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x80, (value & 0x200) >> 2); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x04, (value & 0x100) >> 6); - XGINew_SetReg1(pVBInfo->P3d4, 0x10, (value & 0xFF)); + xgifb_reg_set(pVBInfo->P3d4, 0x10, (value & 0xFF)); /* Panel VRS SR35[2:0] SR34[7:0] */ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x07, (value & 0x700) >> 8); - XGINew_SetReg1(pVBInfo->P3c4, 0x34, value & 0xFF); + xgifb_reg_set(pVBInfo->P3c4, 0x34, value & 0xFF); /* VRE SR0A[5] CR11[3:0] */ value = LVDSVRE - 1; @@ -6802,10 +6802,10 @@ static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde for (temp = 0, value = 0; temp < 3; temp++) { XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, value); - XGINew_SetReg1(pVBInfo->P3c4, + xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1); - XGINew_SetReg1(pVBInfo->P3c4, + xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2); value += 0x10; @@ -6986,7 +6986,7 @@ void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x00); /* save Part1 index 0 */ XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x10); /* BTDAC = 1, avoid VB reset */ XGINew_SetRegAND(pVBInfo->Part1Port, 0x1E, 0xDF); /* disable CRT2 */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah); /* restore Part1 index 0 */ + xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah); /* restore Part1 index 0 */ } } else { /* {301} */ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) { @@ -7141,7 +7141,7 @@ static void XGI_SetDelayComp(struct vb_device_info *pVBInfo) tempah &= 0x0F; tempah |= tempbh; } - XGINew_SetReg1(pVBInfo->Part1Port, 0x2D, tempah); + xgifb_reg_set(pVBInfo->Part1Port, 0x2D, tempah); } } else if (pVBInfo->IF_DEF_LVDS == 1) { tempbl = 0; @@ -7214,13 +7214,13 @@ static void SetSpectrum(struct vb_device_info *pVBInfo) XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */ XGI_LongWait(pVBInfo); - XGINew_SetReg1(pVBInfo->Part4Port, 0x31, + xgifb_reg_set(pVBInfo->Part4Port, 0x31, pVBInfo->LCDCapList[index].Spectrum_31); - XGINew_SetReg1(pVBInfo->Part4Port, 0x32, + xgifb_reg_set(pVBInfo->Part4Port, 0x32, pVBInfo->LCDCapList[index].Spectrum_32); - XGINew_SetReg1(pVBInfo->Part4Port, 0x33, + xgifb_reg_set(pVBInfo->Part4Port, 0x33, pVBInfo->LCDCapList[index].Spectrum_33); - XGINew_SetReg1(pVBInfo->Part4Port, 0x34, + xgifb_reg_set(pVBInfo->Part4Port, 0x34, pVBInfo->LCDCapList[index].Spectrum_34); XGI_LongWait(pVBInfo); XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */ @@ -7236,7 +7236,7 @@ static void XGI_SetLCDCap(struct vb_device_info *pVBInfo) | VB_XGI302LV | VB_XGI301C)) { if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { /* 301LV/302LV only */ /* Set 301LV Capability */ - XGINew_SetReg1(pVBInfo->Part4Port, 0x24, + xgifb_reg_set(pVBInfo->Part4Port, 0x24, (unsigned char) (tempcx & 0x1F)); } /* VB Driving */ @@ -7327,13 +7327,13 @@ static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo) XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */ tempData = TVPhaseList[tempbx]; - XGINew_SetReg1(pVBInfo->Part2Port, 0x31, (unsigned short) (tempData + xgifb_reg_set(pVBInfo->Part2Port, 0x31, (unsigned short) (tempData & 0x000000FF)); - XGINew_SetReg1(pVBInfo->Part2Port, 0x32, (unsigned short) ((tempData + xgifb_reg_set(pVBInfo->Part2Port, 0x32, (unsigned short) ((tempData & 0x0000FF00) >> 8)); - XGINew_SetReg1(pVBInfo->Part2Port, 0x33, (unsigned short) ((tempData + xgifb_reg_set(pVBInfo->Part2Port, 0x33, (unsigned short) ((tempData & 0x00FF0000) >> 16)); - XGINew_SetReg1(pVBInfo->Part2Port, 0x34, (unsigned short) ((tempData + xgifb_reg_set(pVBInfo->Part2Port, 0x34, (unsigned short) ((tempData & 0xFF000000) >> 24)); } @@ -7399,22 +7399,22 @@ static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex, index = tempal * 7; if ((tempcl == 0) && (tempch == 1)) { - XGINew_SetReg1(pVBInfo->Part2Port, 0x35, 0); - XGINew_SetReg1(pVBInfo->Part2Port, 0x36, 0); - XGINew_SetReg1(pVBInfo->Part2Port, 0x37, 0); - XGINew_SetReg1(pVBInfo->Part2Port, 0x38, filterPtr[index++]); + xgifb_reg_set(pVBInfo->Part2Port, 0x35, 0); + xgifb_reg_set(pVBInfo->Part2Port, 0x36, 0); + xgifb_reg_set(pVBInfo->Part2Port, 0x37, 0); + xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]); } else { - XGINew_SetReg1(pVBInfo->Part2Port, 0x35, filterPtr[index++]); - XGINew_SetReg1(pVBInfo->Part2Port, 0x36, filterPtr[index++]); - XGINew_SetReg1(pVBInfo->Part2Port, 0x37, filterPtr[index++]); - XGINew_SetReg1(pVBInfo->Part2Port, 0x38, filterPtr[index++]); + xgifb_reg_set(pVBInfo->Part2Port, 0x35, filterPtr[index++]); + xgifb_reg_set(pVBInfo->Part2Port, 0x36, filterPtr[index++]); + xgifb_reg_set(pVBInfo->Part2Port, 0x37, filterPtr[index++]); + xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]); } if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { - XGINew_SetReg1(pVBInfo->Part2Port, 0x48, filterPtr[index++]); - XGINew_SetReg1(pVBInfo->Part2Port, 0x49, filterPtr[index++]); - XGINew_SetReg1(pVBInfo->Part2Port, 0x4A, filterPtr[index++]); + xgifb_reg_set(pVBInfo->Part2Port, 0x48, filterPtr[index++]); + xgifb_reg_set(pVBInfo->Part2Port, 0x49, filterPtr[index++]); + xgifb_reg_set(pVBInfo->Part2Port, 0x4A, filterPtr[index++]); } } @@ -7462,7 +7462,7 @@ void XGI_SetCRT2ModeRegs(unsigned short ModeNo, unsigned char tempah; - /* XGINew_SetReg1(pVBInfo->Part1Port, 0x03, 0x00); // fix write part1 index 0 BTDRAM bit Bug */ + /* xgifb_reg_set(pVBInfo->Part1Port, 0x03, 0x00); // fix write part1 index 0 BTDRAM bit Bug */ tempah = 0; if (!(pVBInfo->VBInfo & DisableCRT2Display)) { tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x00); @@ -7492,7 +7492,7 @@ void XGI_SetCRT2ModeRegs(unsigned short ModeNo, tempah = 0; } - XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah); + xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah); if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)) { tempcl = pVBInfo->ModeType; if (ModeNo > 0x13) { @@ -7513,7 +7513,7 @@ void XGI_SetCRT2ModeRegs(unsigned short ModeNo, } */ - XGINew_SetReg1(pVBInfo->Part1Port, 0x00, tempah); + xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah); tempah = 0x08; tempbl = 0xf0; @@ -7607,7 +7607,7 @@ void XGI_SetCRT2ModeRegs(unsigned short ModeNo, if (pVBInfo->LCDResInfo == Panel1280x960) tempah |= 0x80; - XGINew_SetReg1(pVBInfo->Part4Port, 0x0C, tempah); + xgifb_reg_set(pVBInfo->Part4Port, 0x0C, tempah); } if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV @@ -7946,54 +7946,54 @@ void XGI_SenseCRT1(struct vb_device_info *pVBInfo) unsigned char DAC_TEST_PARMS[3] = { 0x0F, 0x0F, 0x0F }; int i; - XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86); + xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86); /* [2004/05/06] Vicent to fix XG42 single LCD sense to CRT+LCD */ - XGINew_SetReg1(pVBInfo->P3d4, 0x57, 0x4A); - XGINew_SetReg1(pVBInfo->P3d4, 0x53, (unsigned char) (XGINew_GetReg1( + xgifb_reg_set(pVBInfo->P3d4, 0x57, 0x4A); + xgifb_reg_set(pVBInfo->P3d4, 0x53, (unsigned char) (XGINew_GetReg1( pVBInfo->P3d4, 0x53) | 0x02)); SR31 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x31); CR63 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x63); SR01 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x01); - XGINew_SetReg1(pVBInfo->P3c4, 0x01, (unsigned char) (SR01 & 0xDF)); - XGINew_SetReg1(pVBInfo->P3d4, 0x63, (unsigned char) (CR63 & 0xBF)); + xgifb_reg_set(pVBInfo->P3c4, 0x01, (unsigned char) (SR01 & 0xDF)); + xgifb_reg_set(pVBInfo->P3d4, 0x63, (unsigned char) (CR63 & 0xBF)); CR17 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x17); - XGINew_SetReg1(pVBInfo->P3d4, 0x17, (unsigned char) (CR17 | 0x80)); + xgifb_reg_set(pVBInfo->P3d4, 0x17, (unsigned char) (CR17 | 0x80)); SR1F = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x1F); - XGINew_SetReg1(pVBInfo->P3c4, 0x1F, (unsigned char) (SR1F | 0x04)); + xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char) (SR1F | 0x04)); SR07 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x07); - XGINew_SetReg1(pVBInfo->P3c4, 0x07, (unsigned char) (SR07 & 0xFB)); + xgifb_reg_set(pVBInfo->P3c4, 0x07, (unsigned char) (SR07 & 0xFB)); SR06 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x06); - XGINew_SetReg1(pVBInfo->P3c4, 0x06, (unsigned char) (SR06 & 0xC3)); + xgifb_reg_set(pVBInfo->P3c4, 0x06, (unsigned char) (SR06 & 0xC3)); - XGINew_SetReg1(pVBInfo->P3d4, 0x11, 0x00); + xgifb_reg_set(pVBInfo->P3d4, 0x11, 0x00); for (i = 0; i < 8; i++) - XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) i, CRTCData[i]); + xgifb_reg_set(pVBInfo->P3d4, (unsigned short) i, CRTCData[i]); for (i = 8; i < 11; i++) - XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 8), + xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 8), CRTCData[i]); for (i = 11; i < 13; i++) - XGINew_SetReg1(pVBInfo->P3d4, (unsigned short) (i + 4), + xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 4), CRTCData[i]); for (i = 13; i < 16; i++) - XGINew_SetReg1(pVBInfo->P3c4, (unsigned short) (i - 3), + xgifb_reg_set(pVBInfo->P3c4, (unsigned short) (i - 3), CRTCData[i]); - XGINew_SetReg1(pVBInfo->P3c4, 0x0E, (unsigned char) (CRTCData[16] + xgifb_reg_set(pVBInfo->P3c4, 0x0E, (unsigned char) (CRTCData[16] & 0xE0)); - XGINew_SetReg1(pVBInfo->P3c4, 0x31, 0x00); - XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x1B); - XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE1); + xgifb_reg_set(pVBInfo->P3c4, 0x31, 0x00); + xgifb_reg_set(pVBInfo->P3c4, 0x2B, 0x1B); + xgifb_reg_set(pVBInfo->P3c4, 0x2C, 0xE1); outb(0x00, pVBInfo->P3c8); @@ -8026,14 +8026,14 @@ void XGI_SenseCRT1(struct vb_device_info *pVBInfo) outb(0, (pVBInfo->P3c8 + 1)); } - XGINew_SetReg1(pVBInfo->P3c4, 0x01, SR01); - XGINew_SetReg1(pVBInfo->P3d4, 0x63, CR63); - XGINew_SetReg1(pVBInfo->P3c4, 0x31, SR31); + xgifb_reg_set(pVBInfo->P3c4, 0x01, SR01); + xgifb_reg_set(pVBInfo->P3d4, 0x63, CR63); + xgifb_reg_set(pVBInfo->P3c4, 0x31, SR31); /* [2004/05/11] Vicent */ - XGINew_SetReg1(pVBInfo->P3d4, 0x53, (unsigned char) (XGINew_GetReg1( + xgifb_reg_set(pVBInfo->P3d4, 0x53, (unsigned char) (XGINew_GetReg1( pVBInfo->P3d4, 0x53) & 0xFD)); - XGINew_SetReg1(pVBInfo->P3c4, 0x1F, (unsigned char) SR1F); + xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char) SR1F); } void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, @@ -8055,10 +8055,10 @@ void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, | VB_XGI302LV | VB_XGI301C)) { if (!(pVBInfo->SetFlag & DisableChA)) { if (pVBInfo->SetFlag & EnableChA) { - XGINew_SetReg1(pVBInfo->Part1Port, 0x1E, 0x20); /* Power on */ + xgifb_reg_set(pVBInfo->Part1Port, 0x1E, 0x20); /* Power on */ } else { if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { /* SetCRT2ToLCDA ) */ - XGINew_SetReg1(pVBInfo->Part1Port, + xgifb_reg_set(pVBInfo->Part1Port, 0x1E, 0x20); /* Power on */ } } @@ -8075,7 +8075,7 @@ void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) tempah |= 0x20; } - XGINew_SetReg1(pVBInfo->P3c4, 0x32, tempah); + xgifb_reg_set(pVBInfo->P3c4, 0x32, tempah); XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x20); tempah = (unsigned char) XGINew_GetReg1( @@ -8225,14 +8225,14 @@ static void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension, if ((HwDeviceExtension->jChipType >= XG20) && (HwDeviceExtension->jChipType < XG27)) { /* fix H/W DCLK/2 bug */ if ((ModeNo == 0x00) | (ModeNo == 0x01)) { - XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x4E); - XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE9); + xgifb_reg_set(pVBInfo->P3c4, 0x2B, 0x4E); + xgifb_reg_set(pVBInfo->P3c4, 0x2C, 0xE9); b3CC = (unsigned char) inb(XGINew_P3cc); outb((b3CC |= 0x0C), XGINew_P3cc); } else if ((ModeNo == 0x04) | (ModeNo == 0x05) | (ModeNo == 0x0D)) { - XGINew_SetReg1(pVBInfo->P3c4, 0x2B, 0x1B); - XGINew_SetReg1(pVBInfo->P3c4, 0x2C, 0xE3); + xgifb_reg_set(pVBInfo->P3c4, 0x2B, 0x1B); + xgifb_reg_set(pVBInfo->P3c4, 0x2C, 0xE3); b3CC = (unsigned char) inb(XGINew_P3cc); outb((b3CC |= 0x0C), XGINew_P3cc); } @@ -8357,7 +8357,7 @@ unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension, XGINew_flag_clearbuffer = 1; } */ - XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86); + xgifb_reg_set(pVBInfo->P3c4, 0x05, 0x86); if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 1.Openkey */ XGI_UnLockCRT2(HwDeviceExtension, pVBInfo); diff --git a/drivers/staging/xgifb/vb_util.c b/drivers/staging/xgifb/vb_util.c index a919fd69120d..f7cad57a134e 100644 --- a/drivers/staging/xgifb/vb_util.c +++ b/drivers/staging/xgifb/vb_util.c @@ -8,13 +8,7 @@ #include "vb_util.h" -/* --------------------------------------------------------------------- */ -/* Function : XGINew_SetReg1 */ -/* Input : */ -/* Output : */ -/* Description : SR CRTC GR */ -/* --------------------------------------------------------------------- */ -void XGINew_SetReg1(unsigned long port, unsigned short index, +void xgifb_reg_set(unsigned long port, unsigned short index, unsigned short data) { outb(index, port); @@ -37,7 +31,7 @@ void XGINew_SetRegANDOR(unsigned long Port, unsigned short Index, temp = XGINew_GetReg1(Port, Index); /* XGINew_Part1Port index 02 */ temp = (temp & (DataAND)) | DataOR; - XGINew_SetReg1(Port, Index, temp); + xgifb_reg_set(Port, Index, temp); } void XGINew_SetRegAND(unsigned long Port, unsigned short Index, @@ -47,7 +41,7 @@ void XGINew_SetRegAND(unsigned long Port, unsigned short Index, temp = XGINew_GetReg1(Port, Index); /* XGINew_Part1Port index 02 */ temp &= DataAND; - XGINew_SetReg1(Port, Index, temp); + xgifb_reg_set(Port, Index, temp); } void XGINew_SetRegOR(unsigned long Port, unsigned short Index, @@ -57,5 +51,5 @@ void XGINew_SetRegOR(unsigned long Port, unsigned short Index, temp = XGINew_GetReg1(Port, Index); /* XGINew_Part1Port index 02 */ temp |= DataOR; - XGINew_SetReg1(Port, Index, temp); + xgifb_reg_set(Port, Index, temp); } diff --git a/drivers/staging/xgifb/vb_util.h b/drivers/staging/xgifb/vb_util.h index 7049fc7241cf..c99592a51d72 100644 --- a/drivers/staging/xgifb/vb_util.h +++ b/drivers/staging/xgifb/vb_util.h @@ -1,6 +1,6 @@ #ifndef _VBUTIL_ #define _VBUTIL_ -extern void XGINew_SetReg1(unsigned long, unsigned short, unsigned short); +extern void xgifb_reg_set(unsigned long, unsigned short, unsigned short); extern unsigned char XGINew_GetReg1(unsigned long, unsigned short); extern void XGINew_SetRegOR(unsigned long Port,unsigned short Index,unsigned short DataOR); extern void XGINew_SetRegAND(unsigned long Port,unsigned short Index,unsigned short DataAND); -- cgit v1.2.3 From 58839b0194a44dfb9ab16fc097ef1f1f91f06b32 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:23 +0200 Subject: staging: xgifb: rename XGINew_GetReg1() to xgifb_reg_get() Rename XGINew_GetReg1() to xgifb_reg_get(). Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_ext.c | 28 +++--- drivers/staging/xgifb/vb_init.c | 98 +++++++++--------- drivers/staging/xgifb/vb_setmode.c | 200 ++++++++++++++++++------------------- drivers/staging/xgifb/vb_util.c | 8 +- drivers/staging/xgifb/vb_util.h | 2 +- 5 files changed, 168 insertions(+), 168 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_ext.c b/drivers/staging/xgifb/vb_ext.c index a2998645fa1e..3a3710539207 100644 --- a/drivers/staging/xgifb/vb_ext.c +++ b/drivers/staging/xgifb/vb_ext.c @@ -18,7 +18,7 @@ static unsigned char XGINew_Is301B(struct vb_device_info *pVBInfo) { unsigned short flag; - flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x01); + flag = xgifb_reg_get(pVBInfo->Part4Port, 0x01); if (flag > 0x0B0) return 0; /* 301b */ @@ -40,7 +40,7 @@ static unsigned char XGINew_Sense(unsigned short tempbx, unsigned short tempcx, XGI_LongWait(pVBInfo); tempch = (tempcx & 0x7F00) >> 8; - temp = XGINew_GetReg1(pVBInfo->Part4Port, 0x03); + temp = xgifb_reg_get(pVBInfo->Part4Port, 0x03); temp = temp ^ (0x0E); temp &= tempch; @@ -114,7 +114,7 @@ static unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo) unsigned short tempax, tempbx, temp; /* unsigned short return_flag; */ - tempax = XGINew_GetReg1(pVBInfo->P3c4, 0x1A); + tempax = xgifb_reg_get(pVBInfo->P3c4, 0x1A); tempbx = tempax & 0x1E; if (tempax == 0) @@ -124,7 +124,7 @@ static unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo) if (!(tempax & 0x10)) { if (pVBInfo->IF_DEF_LVDS == 1) { tempbx = 0; - temp = XGINew_GetReg1(pVBInfo->P3c4, 0x38); + temp = xgifb_reg_get(pVBInfo->P3c4, 0x38); if (temp & 0x40) tempbx |= 0x08; if (temp & 0x20) @@ -132,7 +132,7 @@ static unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo) if (temp & 0x01) tempbx |= 0x01; - temp = XGINew_GetReg1(pVBInfo->P3c4, 0x39); + temp = xgifb_reg_get(pVBInfo->P3c4, 0x39); if (temp & 0x80) tempbx |= 0x04; } else { @@ -159,7 +159,7 @@ static unsigned char XGINew_BridgeIsEnable(struct xgi_hw_device_info *HwDeviceEx unsigned short flag; if (XGI_BridgeIsOn(pVBInfo) == 0) { - flag = XGINew_GetReg1(pVBInfo->Part1Port, 0x0); + flag = xgifb_reg_get(pVBInfo->Part1Port, 0x0); if (flag & 0x050) return 1; @@ -188,7 +188,7 @@ static unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtensi XGI_LongWait(pVBInfo); tempch = (tempcx & 0xFF00) >> 8; - temp = XGINew_GetReg1(pVBInfo->Part4Port, 0x03); + temp = xgifb_reg_get(pVBInfo->Part4Port, 0x03); temp = temp ^ (0x0E); temp &= tempch; @@ -208,7 +208,7 @@ static unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtensi XGI_LongWait(pVBInfo); tempch = (tempcx & 0xFF00) >> 8; - temp = XGINew_GetReg1(pVBInfo->Part4Port, 0x03); + temp = xgifb_reg_get(pVBInfo->Part4Port, 0x03); temp = temp ^ (0x0E); temp &= tempch; @@ -227,7 +227,7 @@ static unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtensi XGI_LongWait(pVBInfo); tempch = (tempcx & 0xFF00) >> 8; - temp = XGINew_GetReg1(pVBInfo->Part4Port, 0x03); + temp = xgifb_reg_get(pVBInfo->Part4Port, 0x03); temp = temp ^ (0x0E); temp &= tempch; @@ -245,8 +245,8 @@ void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_ pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress; if (pVBInfo->IF_DEF_LVDS == 1) { - tempax = XGINew_GetReg1(pVBInfo->P3c4, 0x1A); /* ynlai 02/27/2002 */ - tempbx = XGINew_GetReg1(pVBInfo->P3c4, 0x1B); + tempax = xgifb_reg_get(pVBInfo->P3c4, 0x1A); /* ynlai 02/27/2002 */ + tempbx = xgifb_reg_get(pVBInfo->P3c4, 0x1B); tempax = ((tempax & 0xFE) >> 1) | (tempbx << 8); if (tempax == 0x00) { /* Get Panel id from DDC */ temp = XGINew_GetLCDDDCInfo(HwDeviceExtension, pVBInfo); @@ -266,14 +266,14 @@ void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_ XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, tempbx, temp); } else { /* for 301 */ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiVision */ - tempax = XGINew_GetReg1(pVBInfo->P3c4, 0x38); + tempax = xgifb_reg_get(pVBInfo->P3c4, 0x38); temp = tempax & 0x01; - tempax = XGINew_GetReg1(pVBInfo->P3c4, 0x3A); + tempax = xgifb_reg_get(pVBInfo->P3c4, 0x3A); temp = temp | (tempax & 0x02); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xA0, temp); } else { if (XGI_BridgeIsOn(pVBInfo)) { - P2reg0 = XGINew_GetReg1(pVBInfo->Part2Port, 0x00); + P2reg0 = xgifb_reg_get(pVBInfo->Part2Port, 0x00); if (!XGINew_BridgeIsEnable(HwDeviceExtension, pVBInfo)) { SenseModeNo = 0x2e; /* xgifb_reg_set(pVBInfo->P3d4, 0x30, 0x41); */ diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 07fa73dec794..7138a24f83ad 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -49,10 +49,10 @@ static unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceE data = *pVBInfo->pSoftSetting & 0x07; return data; } else { - data = XGINew_GetReg1(pVBInfo->P3c4, 0x39) & 0x02; + data = xgifb_reg_get(pVBInfo->P3c4, 0x39) & 0x02; if (data == 0) - data = (XGINew_GetReg1(pVBInfo->P3c4, 0x3A) & 0x02) >> 1; + data = (xgifb_reg_get(pVBInfo->P3c4, 0x3A) & 0x02) >> 1; return data; } @@ -61,7 +61,7 @@ static unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceE data = *pVBInfo->pSoftSetting & 0x07; return data; } - temp = XGINew_GetReg1(pVBInfo->P3c4, 0x3B); + temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B); if ((temp & 0x88) == 0x80) /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */ data = 0; /* DDR */ @@ -72,7 +72,7 @@ static unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceE XGINew_SetRegAND(pVBInfo->P3d4, 0xB4, ~0x02); /* Independent GPIO control */ udelay(800); XGINew_SetRegOR(pVBInfo->P3d4, 0x4A, 0x80); /* Enable GPIOH read */ - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); /* GPIOF 0:DVI 1:DVO */ + temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); /* GPIOF 0:DVI 1:DVO */ /* HOTPLUG_SUPPORT */ /* for current XG20 & XG21, GPIOH is floating, driver will fix DDR temporarily */ if (temp & 0x01) /* DVI read GPIOH */ @@ -83,7 +83,7 @@ static unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceE XGINew_SetRegOR(pVBInfo->P3d4, 0xB4, 0x02); return data; } else { - data = XGINew_GetReg1(pVBInfo->P3d4, 0x97) & 0x01; + data = xgifb_reg_get(pVBInfo->P3d4, 0x97) & 0x01; if (data == 1) data++; @@ -143,7 +143,7 @@ static void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, && (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01)) || ((pVBInfo->ECLKData[XGINew_RAMType].SR2E == 0x22) && (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01)))) - xgifb_reg_set(pVBInfo->P3c4, 0x32, ((unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x32) & 0xFC) | 0x02); + xgifb_reg_set(pVBInfo->P3c4, 0x32, ((unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x32) & 0xFC) | 0x02); } } @@ -327,15 +327,15 @@ static void XGINew_DDR1x_DefaultRegister( default: xgifb_reg_set(P3d4, 0x82, 0x88); xgifb_reg_set(P3d4, 0x86, 0x00); - XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */ + xgifb_reg_get(P3d4, 0x86); /* Insert read command for delay */ xgifb_reg_set(P3d4, 0x86, 0x88); - XGINew_GetReg1(P3d4, 0x86); + xgifb_reg_get(P3d4, 0x86); xgifb_reg_set(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); xgifb_reg_set(P3d4, 0x82, 0x77); xgifb_reg_set(P3d4, 0x85, 0x00); - XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */ + xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */ xgifb_reg_set(P3d4, 0x85, 0x88); - XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */ + xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */ xgifb_reg_set(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ xgifb_reg_set(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ break; @@ -357,15 +357,15 @@ static void XGINew_DDR2_DefaultRegister( /* keep following setting sequence, each setting in the same reg insert idle */ xgifb_reg_set(P3d4, 0x82, 0x77); xgifb_reg_set(P3d4, 0x86, 0x00); - XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */ + xgifb_reg_get(P3d4, 0x86); /* Insert read command for delay */ xgifb_reg_set(P3d4, 0x86, 0x88); - XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */ + xgifb_reg_get(P3d4, 0x86); /* Insert read command for delay */ xgifb_reg_set(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */ xgifb_reg_set(P3d4, 0x82, 0x77); xgifb_reg_set(P3d4, 0x85, 0x00); - XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */ + xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */ xgifb_reg_set(P3d4, 0x85, 0x88); - XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */ + xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */ xgifb_reg_set(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */ if (HwDeviceExtension->jChipType == XG27) xgifb_reg_set(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */ @@ -400,7 +400,7 @@ static void XGINew_SetDRAMDefaultRegister340( temp1 = ((temp >> (2 * j)) & 0x03) << 2; temp2 |= temp1; xgifb_reg_set(P3d4, 0x6B, temp2); - XGINew_GetReg1(P3d4, 0x6B); /* Insert read command for delay */ + xgifb_reg_get(P3d4, 0x6B); /* Insert read command for delay */ temp2 &= 0xF0; temp2 += 0x10; } @@ -413,7 +413,7 @@ static void XGINew_SetDRAMDefaultRegister340( temp1 = ((temp >> (2 * j)) & 0x03) << 2; temp2 |= temp1; xgifb_reg_set(P3d4, 0x6E, temp2); - XGINew_GetReg1(P3d4, 0x6E); /* Insert read command for delay */ + xgifb_reg_get(P3d4, 0x6E); /* Insert read command for delay */ temp2 &= 0xF0; temp2 += 0x10; } @@ -429,7 +429,7 @@ static void XGINew_SetDRAMDefaultRegister340( temp1 = (temp >> (2 * j)) & 0x03; temp2 |= temp1; xgifb_reg_set(P3d4, 0x6F, temp2); - XGINew_GetReg1(P3d4, 0x6F); /* Insert read command for delay */ + xgifb_reg_get(P3d4, 0x6F); /* Insert read command for delay */ temp2 &= 0xF8; temp2 += 0x08; } @@ -446,7 +446,7 @@ static void XGINew_SetDRAMDefaultRegister340( temp1 = (temp >> (2 * j)) & 0x03; temp2 |= temp1; xgifb_reg_set(P3d4, 0x89, temp2); - XGINew_GetReg1(P3d4, 0x89); /* Insert read command for delay */ + xgifb_reg_get(P3d4, 0x89); /* Insert read command for delay */ temp2 &= 0xF0; temp2 += 0x10; } @@ -530,7 +530,7 @@ static unsigned short XGINew_SetDRAMSizeReg(int index, unsigned char ChannelNo; RankSize = DRAMTYPE_TABLE[index][3] * XGINew_DataBusWidth / 32; - data = XGINew_GetReg1(pVBInfo->P3c4, 0x13); + data = xgifb_reg_get(pVBInfo->P3c4, 0x13); data &= 0x80; if (data == 0x80) @@ -550,7 +550,7 @@ static unsigned short XGINew_SetDRAMSizeReg(int index, memsize = data >> 4; /* [2004/03/25] Vicent, Fix DRAM Sizing Error */ - xgifb_reg_set(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0)); + xgifb_reg_set(pVBInfo->P3c4, 0x14, (xgifb_reg_get(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0)); /* data |= XGINew_ChannelAB << 2; */ /* data |= (XGINew_DataBusWidth / 64) << 1; */ @@ -571,7 +571,7 @@ static unsigned short XGINew_SetDRAMSize20Reg(int index, unsigned char ChannelNo; RankSize = DRAMTYPE_TABLE[index][3] * XGINew_DataBusWidth / 8; - data = XGINew_GetReg1(pVBInfo->P3c4, 0x13); + data = xgifb_reg_get(pVBInfo->P3c4, 0x13); data &= 0x80; if (data == 0x80) @@ -591,7 +591,7 @@ static unsigned short XGINew_SetDRAMSize20Reg(int index, memsize = data >> 4; /* [2004/03/25] Vicent, Fix DRAM Sizing Error */ - xgifb_reg_set(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0)); + xgifb_reg_set(pVBInfo->P3c4, 0x14, (xgifb_reg_get(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0)); udelay(15); /* data |= XGINew_ChannelAB << 2; */ @@ -636,10 +636,10 @@ static unsigned char XGINew_CheckFrequence(struct vb_device_info *pVBInfo) { unsigned char data; - data = XGINew_GetReg1(pVBInfo->P3d4, 0x97); + data = xgifb_reg_get(pVBInfo->P3d4, 0x97); if ((data & 0x10) == 0) { - data = XGINew_GetReg1(pVBInfo->P3c4, 0x39); + data = xgifb_reg_get(pVBInfo->P3c4, 0x39); data = (data & 0x02) >> 1; return data; } else { @@ -655,7 +655,7 @@ static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, switch (HwDeviceExtension->jChipType) { case XG20: case XG21: - data = XGINew_GetReg1(pVBInfo->P3d4, 0x97); + data = xgifb_reg_get(pVBInfo->P3d4, 0x97); data = data & 0x01; XGINew_ChannelAB = 1; /* XG20 "JUST" one channel */ @@ -952,15 +952,15 @@ static void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *HwDeviceExtension, XGISetModeNew(HwDeviceExtension, 0x2e); - data = XGINew_GetReg1(pVBInfo->P3c4, 0x21); + data = xgifb_reg_get(pVBInfo->P3c4, 0x21); xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short) (data & 0xDF)); /* disable read cache */ XGI_DisplayOff(HwDeviceExtension, pVBInfo); - /* data = XGINew_GetReg1(pVBInfo->P3c4, 0x1); */ + /* data = xgifb_reg_get(pVBInfo->P3c4, 0x1); */ /* data |= 0x20 ; */ /* xgifb_reg_set(pVBInfo->P3c4, 0x01, data); *//* Turn OFF Display */ XGINew_DDRSizing340(HwDeviceExtension, pVBInfo); - data = XGINew_GetReg1(pVBInfo->P3c4, 0x21); + data = xgifb_reg_get(pVBInfo->P3c4, 0x21); xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20)); /* enable read cache */ } @@ -1059,7 +1059,7 @@ static void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, { unsigned short tempbx = 0, temp, tempcx, CR3CData; - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x32); + temp = xgifb_reg_get(pVBInfo->P3d4, 0x32); if (temp & Monitor1Sense) tempbx |= ActiveCRT1; @@ -1081,11 +1081,11 @@ static void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, tempbx |= (ActiveYPbPr << 8); } - tempcx = XGINew_GetReg1(pVBInfo->P3d4, 0x3d); - tempcx |= (XGINew_GetReg1(pVBInfo->P3d4, 0x3e) << 8); + tempcx = xgifb_reg_get(pVBInfo->P3d4, 0x3d); + tempcx |= (xgifb_reg_get(pVBInfo->P3d4, 0x3e) << 8); if (tempbx & tempcx) { - CR3CData = XGINew_GetReg1(pVBInfo->P3d4, 0x3c); + CR3CData = xgifb_reg_get(pVBInfo->P3d4, 0x3c); if (!(CR3CData & DisplayDeviceFromCMOS)) { tempcx = 0x1FF0; if (*pVBInfo->pSoftSetting & ModeSoftSetting) @@ -1107,9 +1107,9 @@ static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, { unsigned short temp, tempcl = 0, tempch = 0, CR31Data, CR38Data; - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x3d); - temp |= XGINew_GetReg1(pVBInfo->P3d4, 0x3e) << 8; - temp |= (XGINew_GetReg1(pVBInfo->P3d4, 0x31) & (DriverMode >> 8)) << 8; + temp = xgifb_reg_get(pVBInfo->P3d4, 0x3d); + temp |= xgifb_reg_get(pVBInfo->P3d4, 0x3e) << 8; + temp |= (xgifb_reg_get(pVBInfo->P3d4, 0x31) & (DriverMode >> 8)) << 8; if (pVBInfo->IF_DEF_CRT2Monitor == 1) { if (temp & ActiveCRT2) @@ -1168,7 +1168,7 @@ static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, tempcl ^= (SetSimuScanMode | SwitchToCRT2); xgifb_reg_set(pVBInfo->P3d4, 0x30, tempcl); - CR31Data = XGINew_GetReg1(pVBInfo->P3d4, 0x31); + CR31Data = xgifb_reg_get(pVBInfo->P3d4, 0x31); CR31Data &= ~(SetNotSimuMode >> 8); if (!(temp & ActiveCRT1)) CR31Data |= (SetNotSimuMode >> 8); @@ -1177,7 +1177,7 @@ static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, CR31Data |= (DisableCRT2Display >> 8); xgifb_reg_set(pVBInfo->P3d4, 0x31, CR31Data); - CR38Data = XGINew_GetReg1(pVBInfo->P3d4, 0x38); + CR38Data = xgifb_reg_get(pVBInfo->P3d4, 0x38); CR38Data &= ~SetYPbPr; CR38Data |= tempch; xgifb_reg_set(pVBInfo->P3d4, 0x38, CR38Data); @@ -1201,12 +1201,12 @@ static void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension, } else { #endif XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* Enable GPIOA/B read */ - Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0xC0; + Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0xC0; if (Temp == 0xC0) { /* DVI & DVO GPIOA/B pull high */ XGINew_SenseLCD(HwDeviceExtension, pVBInfo); XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x20, 0x20); /* Enable read GPIOF */ - Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0x04; + Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0x04; if (!Temp) XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0x80); /* TMDS on chip */ else @@ -1224,9 +1224,9 @@ static void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension, unsigned char Temp, bCR4A; pVBInfo->IF_DEF_LVDS = 0; - bCR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A); + bCR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x07, 0x07); /* Enable GPIOA/B/C read */ - Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0x07; + Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0x07; xgifb_reg_set(pVBInfo->P3d4, 0x4A, bCR4A); if (Temp <= 0x02) { @@ -1244,12 +1244,12 @@ static unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo) { unsigned char CR38, CR4A, temp; - CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A); + CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x10, 0x10); /* enable GPIOE read */ - CR38 = XGINew_GetReg1(pVBInfo->P3d4, 0x38); + CR38 = xgifb_reg_get(pVBInfo->P3d4, 0x38); temp = 0; if ((CR38 & 0xE0) > 0x80) { - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); + temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); temp &= 0x08; temp >>= 3; } @@ -1263,9 +1263,9 @@ static unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo) { unsigned char CR4A, temp; - CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A); + CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* enable GPIOA/B/C read */ - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); + temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); if (temp <= 2) temp &= 0x03; else @@ -1424,7 +1424,7 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */ /* Set AGP Rate */ /* - temp1 = XGINew_GetReg1(pVBInfo->P3c4, 0x3B); + temp1 = xgifb_reg_get(pVBInfo->P3c4, 0x3B); temp1 &= 0x02; if (temp1 == 0x02) { outl(0x80000000, 0xcf8); @@ -1492,7 +1492,7 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) XGI_UnLockCRT2(HwDeviceExtension, pVBInfo); XGINew_SetRegANDOR(pVBInfo->Part0Port, 0x3F, 0xEF, 0x00); /* alan, disable VideoCapture */ xgifb_reg_set(pVBInfo->Part1Port, 0x00, 0x00); - temp1 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x7B); /* chk if BCLK>=100MHz */ + temp1 = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x7B); /* chk if BCLK>=100MHz */ temp = (unsigned char) ((temp1 >> 4) & 0x0F); xgifb_reg_set(pVBInfo->Part1Port, 0x02, (*pVBInfo->pCRT2Data_1_2)); @@ -1577,7 +1577,7 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) /* SetDefExt2Regs begin */ /* AGP = 1; - temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x3A); + temp = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x3A); temp &= 0x30; if (temp == 0x30) AGP = 0; diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 4cca02dc5ad0..cef0cf7f759b 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -274,7 +274,7 @@ static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, unsigned char CRTCdata; unsigned short i; - CRTCdata = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); + CRTCdata = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11); CRTCdata &= 0x7f; xgifb_reg_set(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */ @@ -345,7 +345,7 @@ static void XGI_SetGRCRegs(unsigned short StandTableIndex, } if (pVBInfo->ModeType > ModeVGA) { - GRdata = (unsigned char) XGINew_GetReg1(pVBInfo->P3ce, 0x05); + GRdata = (unsigned char) xgifb_reg_get(pVBInfo->P3ce, 0x05); GRdata &= 0xBF; /* 256 color disable */ xgifb_reg_set(pVBInfo->P3ce, 0x05, GRdata); } @@ -538,7 +538,7 @@ static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, /* xgifb_reg_set(pVBInfo->P3d4, 0x56, 0); */ /* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */ - data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); /* unlock cr0-7 */ + data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11); /* unlock cr0-7 */ data &= 0x7F; xgifb_reg_set(pVBInfo->P3d4, 0x11, data); @@ -555,7 +555,7 @@ static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, xgifb_reg_set(pVBInfo->P3c4, (unsigned short) (i + 6), data); } - j = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0e); + j = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x0e); j &= 0x1F; data = pVBInfo->TimingH[0].data[7]; data &= 0xE0; @@ -563,16 +563,16 @@ static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, xgifb_reg_set(pVBInfo->P3c4, 0x0e, data); if (HwDeviceExtension->jChipType >= XG20) { - data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x04); + data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x04); data = data - 1; xgifb_reg_set(pVBInfo->P3d4, 0x04, data); - data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x05); + data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x05); data1 = data; data1 &= 0xE0; data &= 0x1F; if (data == 0) { pushax = data; - data = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, + data = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x0c); data &= 0xFB; xgifb_reg_set(pVBInfo->P3c4, 0x0c, data); @@ -581,7 +581,7 @@ static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, data = data - 1; data |= data1; xgifb_reg_set(pVBInfo->P3d4, 0x05, data); - data = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0e); + data = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x0e); data = data >> 5; data = data + 3; if (data > 7) @@ -616,7 +616,7 @@ static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeN xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x11), data); } - j = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x0a); + j = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x0a); j &= 0xC0; data = pVBInfo->TimingV[0].data[6]; data &= 0x3F; @@ -636,7 +636,7 @@ static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeN if (i) data |= 0x80; - j = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x09); + j = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x09); j &= 0x5F; data |= j; xgifb_reg_set(pVBInfo->P3d4, 0x09, data); @@ -653,7 +653,7 @@ static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; /* Get index */ index = index & IndexMask; - data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); + data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11); data &= 0x7F; xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */ @@ -955,7 +955,7 @@ static void XGI_SetXG21LCD(struct vb_device_info *pVBInfo, xgifb_reg_set(pVBInfo->P3d4, 0x47, *pVBInfo->pCR47); } - Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); + Temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); if (Temp & 0x01) { XGINew_SetRegOR(pVBInfo->P3c4, 0x06, 0x40); /* 18 bits FP */ @@ -995,7 +995,7 @@ static void XGI_SetXG27LCD(struct vb_device_info *pVBInfo, xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x00); xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x00); - Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); + Temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); if ((Temp & 0x03) == 0) { /* dual 12 */ xgifb_reg_set(pVBInfo->P3d4, 0x46, 0x13); xgifb_reg_set(pVBInfo->P3d4, 0x47, 0x13); @@ -1122,8 +1122,8 @@ static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, tempax -= 1; tempbx -= 1; tempcx = tempax; - temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); - data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); + temp = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11); + data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11); data &= 0x7F; xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */ xgifb_reg_set(pVBInfo->P3d4, 0x01, (unsigned short) (tempcx & 0xff)); @@ -1140,7 +1140,7 @@ static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, tempax |= 0x40; XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x42, tempax); - data = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x07); + data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x07); data &= 0xFF; tempax = 0; @@ -1216,7 +1216,7 @@ static void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex, temp2 = temp; temp = temp >> 8; /* ah */ temp &= 0x0F; - i = XGINew_GetReg1(pVBInfo->P3c4, 0x0E); + i = xgifb_reg_get(pVBInfo->P3c4, 0x0E); i &= 0xF0; i |= temp; xgifb_reg_set(pVBInfo->P3c4, 0x0E, i); @@ -1429,7 +1429,7 @@ static void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->IF_DEF_LVDS == 1) { index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; - data = XGINew_GetReg1(pVBInfo->P3c4, 0x31) & 0xCF; + data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF; xgifb_reg_set(pVBInfo->P3c4, 0x31, data); xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[index].SR2B); @@ -1442,7 +1442,7 @@ static void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, vclkindex = XGI_GetVCLK2Ptr(ModeNo, ModeIdIndex, RefreshRateTableIndex, HwDeviceExtension, pVBInfo); - data = XGINew_GetReg1(pVBInfo->P3c4, 0x31) & 0xCF; + data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF; xgifb_reg_set(pVBInfo->P3c4, 0x31, data); data = pVBInfo->VBVCLKData[vclkindex].Part4_A; xgifb_reg_set(pVBInfo->P3c4, 0x2B, data); @@ -1451,7 +1451,7 @@ static void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01); } else { index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; - data = XGINew_GetReg1(pVBInfo->P3c4, 0x31) & 0xCF; + data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF; xgifb_reg_set(pVBInfo->P3c4, 0x31, data); xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[index].SR2B); @@ -1462,9 +1462,9 @@ static void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, if (HwDeviceExtension->jChipType >= XG20) { if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag & HalfDCLK) { - data = XGINew_GetReg1(pVBInfo->P3c4, 0x2B); + data = xgifb_reg_get(pVBInfo->P3c4, 0x2B); xgifb_reg_set(pVBInfo->P3c4, 0x2B, data); - data = XGINew_GetReg1(pVBInfo->P3c4, 0x2C); + data = xgifb_reg_get(pVBInfo->P3c4, 0x2C); index = data; index &= 0xE0; data &= 0x1F; @@ -1482,27 +1482,27 @@ static void XGI_SetCRT1FIFO(unsigned short ModeNo, { unsigned short data; - data = XGINew_GetReg1(pVBInfo->P3c4, 0x3D); + data = xgifb_reg_get(pVBInfo->P3c4, 0x3D); data &= 0xfe; xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */ if (ModeNo > 0x13) { xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x34); - data = XGINew_GetReg1(pVBInfo->P3c4, 0x09); + data = xgifb_reg_get(pVBInfo->P3c4, 0x09); data &= 0xC0; xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x30); - data = XGINew_GetReg1(pVBInfo->P3c4, 0x3D); + data = xgifb_reg_get(pVBInfo->P3c4, 0x3D); data |= 0x01; xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); } else { if (HwDeviceExtension->jChipType == XG27) { xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x0E); - data = XGINew_GetReg1(pVBInfo->P3c4, 0x09); + data = xgifb_reg_get(pVBInfo->P3c4, 0x09); data &= 0xC0; xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x20); } else { xgifb_reg_set(pVBInfo->P3c4, 0x08, 0xAE); - data = XGINew_GetReg1(pVBInfo->P3c4, 0x09); + data = xgifb_reg_get(pVBInfo->P3c4, 0x09); data &= 0xF0; xgifb_reg_set(pVBInfo->P3c4, 0x09, data); } @@ -1529,7 +1529,7 @@ static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, VCLK = pVBInfo->VCLKData[index].CLOCK; } - data = XGINew_GetReg1(pVBInfo->P3c4, 0x32); + data = xgifb_reg_get(pVBInfo->P3c4, 0x32); data &= 0xf3; if (VCLK >= 200) data |= 0x0c; /* VCLK > 200 */ @@ -1540,7 +1540,7 @@ static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, xgifb_reg_set(pVBInfo->P3c4, 0x32, data); if (HwDeviceExtension->jChipType < XG20) { - data = XGINew_GetReg1(pVBInfo->P3c4, 0x1F); + data = xgifb_reg_get(pVBInfo->P3c4, 0x1F); data &= 0xE7; if (VCLK < 200) data |= 0x10; @@ -1580,7 +1580,7 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, } else modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */ - if (XGINew_GetReg1(pVBInfo->P3d4, 0x31) & 0x01) + if (xgifb_reg_get(pVBInfo->P3d4, 0x31) & 0x01) XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1F, 0x3F, 0x00); if (ModeNo > 0x13) @@ -1654,7 +1654,7 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, /* if (XGINew_IF_DEF_NEW_LOWRES) */ /* XGI_VesaLowResolution(ModeNo, ModeIdIndex); //030305 fix lowresolution bug */ - data = XGINew_GetReg1(pVBInfo->P3d4, 0x31); + data = xgifb_reg_get(pVBInfo->P3d4, 0x31); if (HwDeviceExtension->jChipType == XG27) { if (data & 0x40) @@ -2668,7 +2668,7 @@ static unsigned short XGI_GetLCDCapPtr(struct vb_device_info *pVBInfo) { unsigned char tempal, tempah, tempbl, i; - tempah = XGINew_GetReg1(pVBInfo->P3d4, 0x36); + tempah = xgifb_reg_get(pVBInfo->P3d4, 0x36); tempal = tempah & 0x0F; tempah = tempah & 0xF0; i = 0; @@ -3276,22 +3276,22 @@ static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, | VB_XGI302LV | VB_XGI301C)) { tempcl = 0; tempch = 0; - temp = XGINew_GetReg1(pVBInfo->P3c4, 0x01); + temp = xgifb_reg_get(pVBInfo->P3c4, 0x01); if (!(temp & 0x20)) { - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x17); + temp = xgifb_reg_get(pVBInfo->P3d4, 0x17); if (temp & 0x80) { - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x53); + temp = xgifb_reg_get(pVBInfo->P3d4, 0x53); if (!(temp & 0x40)) tempcl |= ActiveCRT1; } } - temp = XGINew_GetReg1(pVBInfo->Part1Port, 0x2e); + temp = xgifb_reg_get(pVBInfo->Part1Port, 0x2e); temp &= 0x0f; if (!(temp == 0x08)) { - tempax = XGINew_GetReg1(pVBInfo->Part1Port, 0x13); /* Check ChannelA by Part1_13 [2003/10/03] */ + tempax = xgifb_reg_get(pVBInfo->Part1Port, 0x13); /* Check ChannelA by Part1_13 [2003/10/03] */ if (tempax & 0x04) tempcl = tempcl | ActiveLCD; @@ -3305,7 +3305,7 @@ static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, tempcl |= ActiveLCD; if (temp == 0x05) { - temp = XGINew_GetReg1(pVBInfo->Part2Port, 0x00); + temp = xgifb_reg_get(pVBInfo->Part2Port, 0x00); if (!(temp & 0x08)) tempch |= ActiveAVideo; @@ -3322,7 +3322,7 @@ static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, } if (pVBInfo->VBInfo & SetCRT2ToYPbPr) { - temp = XGINew_GetReg1( + temp = xgifb_reg_get( pVBInfo->Part2Port, 0x4d); @@ -3335,7 +3335,7 @@ static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, } } - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x3d); + temp = xgifb_reg_get(pVBInfo->P3d4, 0x3d); if (tempcl & ActiveLCD) { if ((pVBInfo->SetFlag & ReserveTVOption)) { if (temp & ActiveTV) @@ -3376,10 +3376,10 @@ void XGI_GetVBType(struct vb_device_info *pVBInfo) } if (pVBInfo->IF_DEF_LVDS == 0) { tempbx = VB_XGI302B; - flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x00); + flag = xgifb_reg_get(pVBInfo->Part4Port, 0x00); if (flag != 0x02) { tempbx = VB_XGI301; - flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x01); + flag = xgifb_reg_get(pVBInfo->Part4Port, 0x01); if (flag >= 0xB0) { tempbx = VB_XGI301B; if (flag >= 0xC0) { @@ -3389,7 +3389,7 @@ void XGI_GetVBType(struct vb_device_info *pVBInfo) if (flag >= 0xE0) { tempbx = VB_XGI302LV; tempah - = XGINew_GetReg1( + = xgifb_reg_get( pVBInfo->Part4Port, 0x39); if (tempah != 0xFF) @@ -3400,7 +3400,7 @@ void XGI_GetVBType(struct vb_device_info *pVBInfo) } if (tempbx & (VB_XGI301B | VB_XGI302B)) { - flag = XGINew_GetReg1( + flag = xgifb_reg_get( pVBInfo->Part4Port, 0x23); @@ -3436,9 +3436,9 @@ void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx = 0; if (pVBInfo->VBType & 0xFFFF) { - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x30); /* Check Display Device */ + temp = xgifb_reg_get(pVBInfo->P3d4, 0x30); /* Check Display Device */ tempbx = tempbx | temp; - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x31); + temp = xgifb_reg_get(pVBInfo->P3d4, 0x31); push = temp; push = push << 8; tempax = temp << 8; @@ -3448,7 +3448,7 @@ void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, temp = 0xFFFF ^ temp; tempbx &= temp; - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38); + temp = xgifb_reg_get(pVBInfo->P3d4, 0x38); if (pVBInfo->IF_DEF_LCDA == 1) { @@ -3497,7 +3497,7 @@ void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, & VB_CH7007))) { /* [Billy] 07/05/04 */ if (temp & SetYPbPr) { /* temp = CR38 */ if (pVBInfo->IF_DEF_HiVision == 1) { - temp = XGINew_GetReg1( + temp = xgifb_reg_get( pVBInfo->P3d4, 0x35); /* shampoo add for new scratch */ temp &= YPbPrMode; @@ -3685,7 +3685,7 @@ void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, } if (pVBInfo->VBInfo & SetCRT2ToTV) { - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x35); + temp = xgifb_reg_get(pVBInfo->P3d4, 0x35); tempbx = temp; if (tempbx & SetPALTV) { tempbx &= (SetCHTVOverScan | SetPALMTV @@ -3697,7 +3697,7 @@ void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, | SetPALTV); /* if (pVBInfo->IF_DEF_LVDS == 0) { - index1 = XGINew_GetReg1(pVBInfo->P3d4, 0x38); //PAL-M/PAL-N Info + index1 = xgifb_reg_get(pVBInfo->P3d4, 0x38); //PAL-M/PAL-N Info temp2 = (index1 & 0xC0) >> 5; //00:PAL, 01:PAL-M, 10:PAL-N tempbx |= temp2; if (temp2 & 0x02) //PAL-M @@ -3707,14 +3707,14 @@ void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, } if (pVBInfo->IF_DEF_CH7017 == 1) { - tempbx = XGINew_GetReg1(pVBInfo->P3d4, 0x35); + tempbx = xgifb_reg_get(pVBInfo->P3d4, 0x35); if (tempbx & TVOverScan) tempbx |= SetCHTVOverScan; } if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/04 */ - tempbx = XGINew_GetReg1(pVBInfo->P3d4, 0x35); + tempbx = xgifb_reg_get(pVBInfo->P3d4, 0x35); if (tempbx & TVOverScan) tempbx |= SetCHTVOverScan; @@ -3727,7 +3727,7 @@ void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->IF_DEF_YPbPr == 1) { if (pVBInfo->VBInfo & SetCRT2ToYPbPr) { - index1 = XGINew_GetReg1(pVBInfo->P3d4, 0x35); + index1 = xgifb_reg_get(pVBInfo->P3d4, 0x35); index1 &= YPbPrMode; if (index1 == YPbPrMode525i) @@ -3791,7 +3791,7 @@ unsigned char XGI_GetLCDInfo(unsigned short ModeNo, unsigned short ModeIdIndex, resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo // */ } - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */ + temp = xgifb_reg_get(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */ tempbx = temp & 0x0F; if (tempbx == 0) @@ -3800,7 +3800,7 @@ unsigned char XGI_GetLCDInfo(unsigned short ModeNo, unsigned short ModeIdIndex, /* LCD75 [2003/8/22] Vicent */ if ((tempbx == Panel1024x768) || (tempbx == Panel1280x1024)) { if (pVBInfo->VBInfo & DriverMode) { - tempax = XGINew_GetReg1(pVBInfo->P3d4, 0x33); + tempax = xgifb_reg_get(pVBInfo->P3d4, 0x33); if (pVBInfo->VBInfo & SetCRT2ToLCDA) tempax &= 0x0F; else @@ -3828,7 +3828,7 @@ unsigned char XGI_GetLCDInfo(unsigned short ModeNo, unsigned short ModeIdIndex, tempbx = 0; - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); + temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable); @@ -3998,7 +3998,7 @@ static unsigned char XGINew_CheckMemorySize( memorysize = memorysize > MemorySizeShift; memorysize++; /* Get memory size */ - temp = XGINew_GetReg1(pVBInfo->P3c4, 0x14); /* Get DRAM Size */ + temp = xgifb_reg_get(pVBInfo->P3c4, 0x14); /* Get DRAM Size */ tmp = temp; if (HwDeviceExtension->jChipType == XG40) { @@ -4038,17 +4038,17 @@ void XGINew_IsLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, u unsigned short data ; unsigned short ModeFlag ; - data = XGINew_GetReg1(pVBInfo->P3c4, 0x0F); + data = xgifb_reg_get(pVBInfo->P3c4, 0x0F); data &= 0x7F; xgifb_reg_set(pVBInfo->P3c4, 0x0F, data); if (ModeNo > 0x13) { ModeFlag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; if ((ModeFlag & HalfDCLK) && (ModeFlag & DoubleScanMode)) { - data = XGINew_GetReg1(pVBInfo->P3c4, 0x0F); + data = xgifb_reg_get(pVBInfo->P3c4, 0x0F); data |= 0x80; xgifb_reg_set(pVBInfo->P3c4, 0x0F, data); - data = XGINew_GetReg1(pVBInfo->P3c4, 0x01); + data = xgifb_reg_get(pVBInfo->P3c4, 0x01); data &= 0xF7; xgifb_reg_set(pVBInfo->P3c4, 0x01, data); } @@ -4080,10 +4080,10 @@ static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo) { unsigned char CR4A, temp; - CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A); + CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x23); /* enable GPIO write */ - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); + temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); temp = XG21GPIODataTransfer(temp); temp &= 0x23; @@ -4101,15 +4101,15 @@ static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo) { unsigned char CR4A, CRB4, temp; - CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A); + CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x0C); /* enable GPIO write */ - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); + temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); temp &= 0x0C; temp >>= 2; xgifb_reg_set(pVBInfo->P3d4, 0x4A, CR4A); - CRB4 = XGINew_GetReg1(pVBInfo->P3d4, 0xB4); + CRB4 = xgifb_reg_get(pVBInfo->P3d4, 0xB4); temp |= ((CRB4 & 0x04) << 3); return temp; } @@ -5637,7 +5637,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, } xgifb_reg_set(pVBInfo->Part2Port, 0x4d, temp); - temp = XGINew_GetReg1(pVBInfo->Part2Port, 0x43); /* 301b change */ + temp = xgifb_reg_get(pVBInfo->Part2Port, 0x43); /* 301b change */ xgifb_reg_set(pVBInfo->Part2Port, 0x43, (unsigned short) (temp - 3)); if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) { @@ -5659,7 +5659,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, } if (pVBInfo->TVInfo & SetPALMTV) { - tempax = (unsigned char) XGINew_GetReg1(pVBInfo->Part2Port, + tempax = (unsigned char) xgifb_reg_get(pVBInfo->Part2Port, 0x01); tempax--; XGINew_SetRegAND(pVBInfo->Part2Port, 0x01, tempax); @@ -6289,7 +6289,7 @@ void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl, { unsigned char CR4A, temp; - CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A); + CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); tempbh &= 0x23; tempbl &= 0x23; XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */ @@ -6301,7 +6301,7 @@ void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl, } - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); + temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); temp = XG21GPIODataTransfer(temp); temp &= ~tempbh; @@ -6330,7 +6330,7 @@ void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl, } XGINew_SetRegANDOR(pVBInfo->P3d4, 0xB4, ~tempbh0, tempbl0); - CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A); + CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); tempbh &= 0x03; tempbl &= 0x03; tempbh <<= 2; @@ -6344,7 +6344,7 @@ unsigned short XGI_GetLVDSOEMTableIndex(struct vb_device_info *pVBInfo) { unsigned short index; - index = XGINew_GetReg1(pVBInfo->P3d4, 0x36); + index = xgifb_reg_get(pVBInfo->P3d4, 0x36); if (index < sizeof(XGI21_LCDCapList) / sizeof(struct XGI21_LVDSCapStruct)) return index; @@ -6437,7 +6437,7 @@ void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo) { unsigned char temp; - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); /* D[0] 1: 18bit */ + temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); /* D[0] 1: 18bit */ temp = (temp & 1) << 6; XGINew_SetRegANDOR(pVBInfo->P3c4, 0x06, ~0x40, temp); /* SR06[6] 18bit Dither */ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80); /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */ @@ -6448,7 +6448,7 @@ void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo) { unsigned char temp; - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */ + temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */ temp = (temp & 3) << 6; XGINew_SetRegANDOR(pVBInfo->P3c4, 0x06, ~0xc0, temp & 0x80); /* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */ XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80); /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */ @@ -6535,7 +6535,7 @@ static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde LVDSVBE = LVDSVBS + LVDSVT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE; - temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); + temp = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11); xgifb_reg_set(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */ if (!(modeflag & Charx8Dot)) @@ -6720,7 +6720,7 @@ static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde LVDSVBE = LVDSVBS + LVDSVT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE; - temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x11); + temp = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11); xgifb_reg_set(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */ if (!(modeflag & Charx8Dot)) @@ -6855,7 +6855,7 @@ static unsigned char XGI_DisableChISLCD(struct vb_device_info *pVBInfo) unsigned short tempbx, tempah; tempbx = pVBInfo->SetFlag & (DisableChA | DisableChB); - tempah = ~((unsigned short) XGINew_GetReg1(pVBInfo->Part1Port, 0x2E)); + tempah = ~((unsigned short) xgifb_reg_get(pVBInfo->Part1Port, 0x2E)); if (tempbx & (EnableChA | DisableChA)) { if (!(tempah & 0x08)) /* Chk LCDA Mode */ @@ -6882,7 +6882,7 @@ static unsigned char XGI_EnableChISLCD(struct vb_device_info *pVBInfo) unsigned short tempbx, tempah; tempbx = pVBInfo->SetFlag & (EnableChA | EnableChB); - tempah = ~((unsigned short) XGINew_GetReg1(pVBInfo->Part1Port, 0x2E)); + tempah = ~((unsigned short) xgifb_reg_get(pVBInfo->Part1Port, 0x2E)); if (tempbx & (EnableChA | DisableChA)) { if (!(tempah & 0x08)) /* Chk LCDA Mode */ @@ -6983,7 +6983,7 @@ void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, || (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) || (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))) { - tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x00); /* save Part1 index 0 */ + tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00); /* save Part1 index 0 */ XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x10); /* BTDAC = 1, avoid VB reset */ XGINew_SetRegAND(pVBInfo->Part1Port, 0x1E, 0xDF); /* disable CRT2 */ xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah); /* restore Part1 index 0 */ @@ -7129,7 +7129,7 @@ static void XGI_SetDelayComp(struct vb_device_info *pVBInfo) tempbl &= 0x0F; tempbh &= 0xF0; - tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x2D); + tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x2D); if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV)) { /* Channel B */ @@ -7162,7 +7162,7 @@ static void XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInf { unsigned short temp; - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x37); + temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); if (temp & LCDRGB18Bit) { XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, @@ -7465,7 +7465,7 @@ void XGI_SetCRT2ModeRegs(unsigned short ModeNo, /* xgifb_reg_set(pVBInfo->Part1Port, 0x03, 0x00); // fix write part1 index 0 BTDRAM bit Bug */ tempah = 0; if (!(pVBInfo->VBInfo & DisableCRT2Display)) { - tempah = XGINew_GetReg1(pVBInfo->Part1Port, 0x00); + tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00); tempah &= ~0x10; /* BTRAMDAC */ tempah |= 0x40; /* BTRAM */ @@ -7700,7 +7700,7 @@ unsigned char XGI_BridgeIsOn(struct vb_device_info *pVBInfo) if (pVBInfo->IF_DEF_LVDS == 1) { return 1; } else { - flag = XGINew_GetReg1(pVBInfo->Part4Port, 0x00); + flag = xgifb_reg_get(pVBInfo->Part4Port, 0x00); if ((flag == 1) || (flag == 2)) return 1; /* 301b */ else @@ -7712,7 +7712,7 @@ void XGI_LongWait(struct vb_device_info *pVBInfo) { unsigned short i; - i = XGINew_GetReg1(pVBInfo->P3c4, 0x1F); + i = xgifb_reg_get(pVBInfo->P3c4, 0x1F); if (!(i & 0xC0)) { for (i = 0; i < 0xFFFF; i++) { @@ -7784,7 +7784,7 @@ unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, if (ModeNo < 0x14) return 0xFFFF; - index = XGINew_GetReg1(pVBInfo->P3d4, 0x33); + index = xgifb_reg_get(pVBInfo->P3d4, 0x33); index = index >> pVBInfo->SelectCRT2Rate; index &= 0x0F; @@ -7950,25 +7950,25 @@ void XGI_SenseCRT1(struct vb_device_info *pVBInfo) /* [2004/05/06] Vicent to fix XG42 single LCD sense to CRT+LCD */ xgifb_reg_set(pVBInfo->P3d4, 0x57, 0x4A); - xgifb_reg_set(pVBInfo->P3d4, 0x53, (unsigned char) (XGINew_GetReg1( + xgifb_reg_set(pVBInfo->P3d4, 0x53, (unsigned char) (xgifb_reg_get( pVBInfo->P3d4, 0x53) | 0x02)); - SR31 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x31); - CR63 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x63); - SR01 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x01); + SR31 = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x31); + CR63 = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x63); + SR01 = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x01); xgifb_reg_set(pVBInfo->P3c4, 0x01, (unsigned char) (SR01 & 0xDF)); xgifb_reg_set(pVBInfo->P3d4, 0x63, (unsigned char) (CR63 & 0xBF)); - CR17 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x17); + CR17 = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x17); xgifb_reg_set(pVBInfo->P3d4, 0x17, (unsigned char) (CR17 | 0x80)); - SR1F = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x1F); + SR1F = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x1F); xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char) (SR1F | 0x04)); - SR07 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x07); + SR07 = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x07); xgifb_reg_set(pVBInfo->P3c4, 0x07, (unsigned char) (SR07 & 0xFB)); - SR06 = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x06); + SR06 = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x06); xgifb_reg_set(pVBInfo->P3c4, 0x06, (unsigned char) (SR06 & 0xC3)); xgifb_reg_set(pVBInfo->P3d4, 0x11, 0x00); @@ -8031,7 +8031,7 @@ void XGI_SenseCRT1(struct vb_device_info *pVBInfo) xgifb_reg_set(pVBInfo->P3c4, 0x31, SR31); /* [2004/05/11] Vicent */ - xgifb_reg_set(pVBInfo->P3d4, 0x53, (unsigned char) (XGINew_GetReg1( + xgifb_reg_set(pVBInfo->P3d4, 0x53, (unsigned char) (xgifb_reg_get( pVBInfo->P3d4, 0x53) & 0xFD)); xgifb_reg_set(pVBInfo->P3c4, 0x1F, (unsigned char) SR1F); } @@ -8068,7 +8068,7 @@ void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, if ((pVBInfo->SetFlag & EnableChB) || (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV | SetCRT2ToRAMDAC))) { - tempah = (unsigned char) XGINew_GetReg1( + tempah = (unsigned char) xgifb_reg_get( pVBInfo->P3c4, 0x32); tempah &= 0xDF; if (pVBInfo->VBInfo & SetInSlaveMode) { @@ -8078,7 +8078,7 @@ void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, xgifb_reg_set(pVBInfo->P3c4, 0x32, tempah); XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x20); - tempah = (unsigned char) XGINew_GetReg1( + tempah = (unsigned char) xgifb_reg_get( pVBInfo->Part1Port, 0x2E); if (!(tempah & 0x80)) @@ -8161,7 +8161,7 @@ void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, | SetCRT2ToLCDA)) XGINew_SetRegOR(pVBInfo->Part1Port, 0x1E, 0x20); /* enable CRT2 */ - tempah = (unsigned char) XGINew_GetReg1(pVBInfo->Part1Port, + tempah = (unsigned char) xgifb_reg_get(pVBInfo->Part1Port, 0x2E); if (!(tempah & 0x80)) XGINew_SetRegOR(pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */ @@ -8239,7 +8239,7 @@ static void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension, } if (HwDeviceExtension->jChipType >= XG21) { - temp = XGINew_GetReg1(pVBInfo->P3d4, 0x38); + temp = xgifb_reg_get(pVBInfo->P3d4, 0x38); if (temp & 0xA0) { /* XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); *//* Enable write GPIOF */ @@ -8335,12 +8335,12 @@ unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension, pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2; if (HwDeviceExtension->jChipType == XG21) { /* for x86 Linux, XG21 LVDS */ - if ((XGINew_GetReg1(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) + if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) pVBInfo->IF_DEF_LVDS = 1; } if (HwDeviceExtension->jChipType == XG27) { - if ((XGINew_GetReg1(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) { - if (XGINew_GetReg1(pVBInfo->P3d4, 0x30) & 0x20) + if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0) { + if (xgifb_reg_get(pVBInfo->P3d4, 0x30) & 0x20) pVBInfo->IF_DEF_LVDS = 1; } } diff --git a/drivers/staging/xgifb/vb_util.c b/drivers/staging/xgifb/vb_util.c index f7cad57a134e..65f134955383 100644 --- a/drivers/staging/xgifb/vb_util.c +++ b/drivers/staging/xgifb/vb_util.c @@ -15,7 +15,7 @@ void xgifb_reg_set(unsigned long port, unsigned short index, outb(data, port + 1); } -unsigned char XGINew_GetReg1(unsigned long port, unsigned short index) +unsigned char xgifb_reg_get(unsigned long port, unsigned short index) { unsigned char data; @@ -29,7 +29,7 @@ void XGINew_SetRegANDOR(unsigned long Port, unsigned short Index, { unsigned short temp; - temp = XGINew_GetReg1(Port, Index); /* XGINew_Part1Port index 02 */ + temp = xgifb_reg_get(Port, Index); /* XGINew_Part1Port index 02 */ temp = (temp & (DataAND)) | DataOR; xgifb_reg_set(Port, Index, temp); } @@ -39,7 +39,7 @@ void XGINew_SetRegAND(unsigned long Port, unsigned short Index, { unsigned short temp; - temp = XGINew_GetReg1(Port, Index); /* XGINew_Part1Port index 02 */ + temp = xgifb_reg_get(Port, Index); /* XGINew_Part1Port index 02 */ temp &= DataAND; xgifb_reg_set(Port, Index, temp); } @@ -49,7 +49,7 @@ void XGINew_SetRegOR(unsigned long Port, unsigned short Index, { unsigned short temp; - temp = XGINew_GetReg1(Port, Index); /* XGINew_Part1Port index 02 */ + temp = xgifb_reg_get(Port, Index); /* XGINew_Part1Port index 02 */ temp |= DataOR; xgifb_reg_set(Port, Index, temp); } diff --git a/drivers/staging/xgifb/vb_util.h b/drivers/staging/xgifb/vb_util.h index c99592a51d72..6332d4c66810 100644 --- a/drivers/staging/xgifb/vb_util.h +++ b/drivers/staging/xgifb/vb_util.h @@ -1,7 +1,7 @@ #ifndef _VBUTIL_ #define _VBUTIL_ extern void xgifb_reg_set(unsigned long, unsigned short, unsigned short); -extern unsigned char XGINew_GetReg1(unsigned long, unsigned short); +extern unsigned char xgifb_reg_get(unsigned long, unsigned short); extern void XGINew_SetRegOR(unsigned long Port,unsigned short Index,unsigned short DataOR); extern void XGINew_SetRegAND(unsigned long Port,unsigned short Index,unsigned short DataAND); extern void XGINew_SetRegANDOR(unsigned long Port,unsigned short Index,unsigned short DataAND,unsigned short DataOR); -- cgit v1.2.3 From b9bf6e4e62bd40a5867e4958d21a145536582875 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:24 +0200 Subject: staging: xgifb: rename XGINew_SetRegOR() to xgifb_reg_or() Rename XGINew_SetRegOR() to xgifb_reg_or(). Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_ext.c | 2 +- drivers/staging/xgifb/vb_init.c | 12 +++---- drivers/staging/xgifb/vb_setmode.c | 72 +++++++++++++++++++------------------- drivers/staging/xgifb/vb_util.c | 2 +- drivers/staging/xgifb/vb_util.h | 2 +- 5 files changed, 45 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_ext.c b/drivers/staging/xgifb/vb_ext.c index 3a3710539207..c24ece2c0135 100644 --- a/drivers/staging/xgifb/vb_ext.c +++ b/drivers/staging/xgifb/vb_ext.c @@ -309,7 +309,7 @@ void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_ } if (pVBInfo->VBType & VB_XGI301C) - XGINew_SetRegOR(pVBInfo->Part4Port, 0x0d, 0x04); + xgifb_reg_or(pVBInfo->Part4Port, 0x0d, 0x04); if (XGINew_SenseHiTV(HwDeviceExtension, pVBInfo)) { /* add by kuku for Multi-adapter sense HiTV */ tempax |= HiTVSense; diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 7138a24f83ad..46b8ebd7b2f0 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -71,7 +71,7 @@ static unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceE } else if (HwDeviceExtension->jChipType == XG21) { XGINew_SetRegAND(pVBInfo->P3d4, 0xB4, ~0x02); /* Independent GPIO control */ udelay(800); - XGINew_SetRegOR(pVBInfo->P3d4, 0x4A, 0x80); /* Enable GPIOH read */ + xgifb_reg_or(pVBInfo->P3d4, 0x4A, 0x80); /* Enable GPIOH read */ temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); /* GPIOF 0:DVI 1:DVO */ /* HOTPLUG_SUPPORT */ /* for current XG20 & XG21, GPIOH is floating, driver will fix DDR temporarily */ @@ -80,7 +80,7 @@ static unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceE else data = 0; /* DDR */ /* ~HOTPLUG_SUPPORT */ - XGINew_SetRegOR(pVBInfo->P3d4, 0xB4, 0x02); + xgifb_reg_or(pVBInfo->P3d4, 0xB4, 0x02); return data; } else { data = xgifb_reg_get(pVBInfo->P3d4, 0x97) & 0x01; @@ -462,7 +462,7 @@ static void XGINew_SetDRAMDefaultRegister340( temp3 = temp & 0x80; xgifb_reg_set(P3d4, 0x45, temp1); /* CR45 */ xgifb_reg_set(P3d4, 0x99, temp2); /* CR99 */ - XGINew_SetRegOR(P3d4, 0x40, temp3); /* CR40_D[7] */ + xgifb_reg_or(P3d4, 0x40, temp3); /* CR40_D[7] */ xgifb_reg_set(P3d4, 0x41, pVBInfo->CR40[0][XGINew_RAMType]); /* CR41 */ if (HwDeviceExtension->jChipType == XG27) @@ -1196,7 +1196,7 @@ static void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension, #if 1 if ((pVideoMemory[0x65] & 0x01)) { /* For XG21 LVDS */ pVBInfo->IF_DEF_LVDS = 1; - XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense); + xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS on chip */ } else { #endif @@ -1204,7 +1204,7 @@ static void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension, Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0xC0; if (Temp == 0xC0) { /* DVI & DVO GPIOA/B pull high */ XGINew_SenseLCD(HwDeviceExtension, pVBInfo); - XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense); + xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense); XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x20, 0x20); /* Enable read GPIOF */ Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0x04; if (!Temp) @@ -1236,7 +1236,7 @@ static void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension, } else { XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* TMDS/DVO setting */ } - XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense); + xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense); } diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index cef0cf7f759b..2dc8a1fb322a 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -704,7 +704,7 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; /* Tempax: CR16 VRS */ Tempbx = Tempax; /* Tempbx=Tempax */ Tempax &= 0x01; /* Tempax: VRS[0] */ - XGINew_SetRegOR(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS */ + xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS */ Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; /* Tempax: CR7 VRS */ Tempdx = Tempbx >> 1; /* Tempdx: VRS[7:1] */ Tempcx = Tempax & 0x04; /* Tempcx: CR7[2] */ @@ -772,7 +772,7 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; /* CR10 VRS */ Tempbx = Tempax; /* Tempbx: VRS */ Tempax &= 0x01; /* Tempax[0]: VRS[0] */ - XGINew_SetRegOR(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */ + xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; /* CR7[2][7] VRE */ Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */ Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */ @@ -958,11 +958,11 @@ static void XGI_SetXG21LCD(struct vb_device_info *pVBInfo, Temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); if (Temp & 0x01) { - XGINew_SetRegOR(pVBInfo->P3c4, 0x06, 0x40); /* 18 bits FP */ - XGINew_SetRegOR(pVBInfo->P3c4, 0x09, 0x40); + xgifb_reg_or(pVBInfo->P3c4, 0x06, 0x40); /* 18 bits FP */ + xgifb_reg_or(pVBInfo->P3c4, 0x09, 0x40); } - XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */ + xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */ XGINew_SetRegAND(pVBInfo->P3c4, 0x30, ~0x20); XGINew_SetRegAND(pVBInfo->P3c4, 0x35, ~0x80); @@ -970,15 +970,15 @@ static void XGI_SetXG21LCD(struct vb_device_info *pVBInfo, if (ModeNo <= 0x13) { b3CC = (unsigned char) inb(XGI_P3cc); if (b3CC & 0x40) - XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */ + xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */ if (b3CC & 0x80) - XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */ + xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */ } else { Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; if (Data & 0x4000) - XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */ + xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */ if (Data & 0x8000) - XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */ + xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */ } } @@ -1010,7 +1010,7 @@ static void XGI_SetXG27LCD(struct vb_device_info *pVBInfo, XGI_SetXG27FPBits(pVBInfo); - XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */ + xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */ XGINew_SetRegAND(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */ XGINew_SetRegAND(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */ @@ -1018,15 +1018,15 @@ static void XGI_SetXG27LCD(struct vb_device_info *pVBInfo, if (ModeNo <= 0x13) { b3CC = (unsigned char) inb(XGI_P3cc); if (b3CC & 0x40) - XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */ + xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */ if (b3CC & 0x80) - XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */ + xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */ } else { Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; if (Data & 0x4000) - XGINew_SetRegOR(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */ + xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */ if (Data & 0x8000) - XGINew_SetRegOR(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */ + xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */ } } @@ -1662,7 +1662,7 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, else data = 0x6c; xgifb_reg_set(pVBInfo->P3d4, 0x52, data); - XGINew_SetRegOR(pVBInfo->P3d4, 0x51, 0x10); + xgifb_reg_or(pVBInfo->P3d4, 0x51, 0x10); } else if (HwDeviceExtension->jChipType >= XG20) { if (data & 0x40) data = 0x33; @@ -4208,7 +4208,7 @@ static void XGI_WaitDisplay(struct vb_device_info *pVBInfo) static void XGI_AutoThreshold(struct vb_device_info *pVBInfo) { if (!(pVBInfo->SetFlag & Win9xDOSMode)) - XGINew_SetRegOR(pVBInfo->Part1Port, 0x01, 0x40); + xgifb_reg_or(pVBInfo->Part1Port, 0x01, 0x40); } static void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBInfo) @@ -4573,9 +4573,9 @@ static void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_set(pVBInfo->Part4Port, 0x00, 0x12); if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) - XGINew_SetRegOR(pVBInfo->Part4Port, 0x12, 0x28); + xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x28); else - XGINew_SetRegOR(pVBInfo->Part4Port, 0x12, 0x08); + xgifb_reg_or(pVBInfo->Part4Port, 0x12, 0x08); } static unsigned short XGI_GetColorDepth(unsigned short ModeNo, @@ -6073,7 +6073,7 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_set(pVBInfo->Part4Port, 0x17, temp); temp = temp2 | ((tempcx & 0xFF00) >> 8); xgifb_reg_set(pVBInfo->Part4Port, 0x15, temp); - XGINew_SetRegOR(pVBInfo->Part4Port, 0x0D, 0x08); + xgifb_reg_or(pVBInfo->Part4Port, 0x0D, 0x08); tempcx = pVBInfo->VBInfo; tempbx = pVBInfo->VGAHDE; @@ -6206,7 +6206,7 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) { if (pVBInfo->VGAHDE > 800) - XGINew_SetRegOR(pVBInfo->Part4Port, 0x1E, 0x08); + xgifb_reg_or(pVBInfo->Part4Port, 0x1E, 0x08); } temp = 0x0036; @@ -6539,7 +6539,7 @@ static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde xgifb_reg_set(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */ if (!(modeflag & Charx8Dot)) - XGINew_SetRegOR(pVBInfo->P3c4, 0x1, 0x1); + xgifb_reg_or(pVBInfo->P3c4, 0x1, 0x1); /* HT SR0B[1:0] CR00 */ value = (LVDSHT >> 3) - 5; @@ -6724,7 +6724,7 @@ static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde xgifb_reg_set(pVBInfo->P3d4, 0x11, temp & 0x7f); /* Unlock CRTC */ if (!(modeflag & Charx8Dot)) - XGINew_SetRegOR(pVBInfo->P3c4, 0x1, 0x1); + xgifb_reg_or(pVBInfo->P3c4, 0x1, 0x1); /* HT SR0B[1:0] CR00 */ value = (LVDSHT >> 3) - 5; @@ -6947,7 +6947,7 @@ void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, if (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) || (XGI_DisableChISLCD(pVBInfo)) || (XGI_IsLCDON(pVBInfo))) - XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x80); /* LVDS Driver power down */ + xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x80); /* LVDS Driver power down */ } if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo @@ -6976,7 +6976,7 @@ void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, & (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV)))) - XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */ + xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */ if ((pVBInfo->SetFlag & DisableChB) || (pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode)) @@ -6984,13 +6984,13 @@ void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, || (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))) { tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00); /* save Part1 index 0 */ - XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x10); /* BTDAC = 1, avoid VB reset */ + xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x10); /* BTDAC = 1, avoid VB reset */ XGINew_SetRegAND(pVBInfo->Part1Port, 0x1E, 0xDF); /* disable CRT2 */ xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah); /* restore Part1 index 0 */ } } else { /* {301} */ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) { - XGINew_SetRegOR(pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */ + xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */ XGINew_SetRegAND(pVBInfo->Part1Port, 0x1E, 0xDF); /* Disable CRT2 */ XGINew_SetRegAND(pVBInfo->P3c4, 0x32, 0xDF); /* Disable TV asPrimary VGA swap */ } @@ -7211,7 +7211,7 @@ static void SetSpectrum(struct vb_device_info *pVBInfo) XGINew_SetRegAND(pVBInfo->Part4Port, 0x30, 0x8F); /* disable down spectrum D[4] */ XGI_LongWait(pVBInfo); - XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */ + xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */ XGI_LongWait(pVBInfo); xgifb_reg_set(pVBInfo->Part4Port, 0x31, @@ -7223,7 +7223,7 @@ static void SetSpectrum(struct vb_device_info *pVBInfo) xgifb_reg_set(pVBInfo->Part4Port, 0x34, pVBInfo->LCDCapList[index].Spectrum_34); XGI_LongWait(pVBInfo); - XGINew_SetRegOR(pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */ + xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */ } static void XGI_SetLCDCap(struct vb_device_info *pVBInfo) @@ -7652,8 +7652,8 @@ void XGI_SetCRT2ModeRegs(unsigned short ModeNo, if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) { if (pVBInfo->LCDInfo & SetLCDDualLink) { - XGINew_SetRegOR(pVBInfo->Part4Port, 0x27, 0x20); - XGINew_SetRegOR(pVBInfo->Part4Port, 0x34, 0x10); + xgifb_reg_or(pVBInfo->Part4Port, 0x27, 0x20); + xgifb_reg_or(pVBInfo->Part4Port, 0x34, 0x10); } } } @@ -8076,13 +8076,13 @@ void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, tempah |= 0x20; } xgifb_reg_set(pVBInfo->P3c4, 0x32, tempah); - XGINew_SetRegOR(pVBInfo->P3c4, 0x1E, 0x20); + xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x20); tempah = (unsigned char) xgifb_reg_get( pVBInfo->Part1Port, 0x2E); if (!(tempah & 0x80)) - XGINew_SetRegOR(pVBInfo->Part1Port, + xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */ XGINew_SetRegAND(pVBInfo->Part1Port, 0x00, 0x7F); /* BScreenOFF = 0 */ @@ -8140,7 +8140,7 @@ void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, } } - XGINew_SetRegOR(pVBInfo->Part4Port, 0x1F, tempah); /* EnablePart4_1F */ + xgifb_reg_or(pVBInfo->Part4Port, 0x1F, tempah); /* EnablePart4_1F */ if (pVBInfo->SetFlag & Win9xDOSMode) { XGI_DisplayOn(HwDeviceExtension, pVBInfo); @@ -8159,12 +8159,12 @@ void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, else { /* LVDS */ if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA)) - XGINew_SetRegOR(pVBInfo->Part1Port, 0x1E, 0x20); /* enable CRT2 */ + xgifb_reg_or(pVBInfo->Part1Port, 0x1E, 0x20); /* enable CRT2 */ tempah = (unsigned char) xgifb_reg_get(pVBInfo->Part1Port, 0x2E); if (!(tempah & 0x80)) - XGINew_SetRegOR(pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */ + xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */ XGINew_SetRegAND(pVBInfo->Part1Port, 0x00, 0x7F); XGI_DisplayOn(HwDeviceExtension, pVBInfo); @@ -8270,7 +8270,7 @@ static void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension, XGI_SetXG21LVDSPara(ModeNo, ModeIdIndex, pVBInfo); } - /* XGINew_SetRegOR(pVBInfo->P3d4, 0x48, 0x20); *//* P. ON */ + /* xgifb_reg_or(pVBInfo->P3d4, 0x48, 0x20); *//* P. ON */ } } diff --git a/drivers/staging/xgifb/vb_util.c b/drivers/staging/xgifb/vb_util.c index 65f134955383..f9605dd14fb5 100644 --- a/drivers/staging/xgifb/vb_util.c +++ b/drivers/staging/xgifb/vb_util.c @@ -44,7 +44,7 @@ void XGINew_SetRegAND(unsigned long Port, unsigned short Index, xgifb_reg_set(Port, Index, temp); } -void XGINew_SetRegOR(unsigned long Port, unsigned short Index, +void xgifb_reg_or(unsigned long Port, unsigned short Index, unsigned short DataOR) { unsigned short temp; diff --git a/drivers/staging/xgifb/vb_util.h b/drivers/staging/xgifb/vb_util.h index 6332d4c66810..6bcdca84032f 100644 --- a/drivers/staging/xgifb/vb_util.h +++ b/drivers/staging/xgifb/vb_util.h @@ -2,7 +2,7 @@ #define _VBUTIL_ extern void xgifb_reg_set(unsigned long, unsigned short, unsigned short); extern unsigned char xgifb_reg_get(unsigned long, unsigned short); -extern void XGINew_SetRegOR(unsigned long Port,unsigned short Index,unsigned short DataOR); +extern void xgifb_reg_or(unsigned long, unsigned short, unsigned short); extern void XGINew_SetRegAND(unsigned long Port,unsigned short Index,unsigned short DataAND); extern void XGINew_SetRegANDOR(unsigned long Port,unsigned short Index,unsigned short DataAND,unsigned short DataOR); #endif -- cgit v1.2.3 From ec9e5d3e73d675915ac572631ef0d5dcc03d2b6c Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:25 +0200 Subject: staging: xgifb: rename XGINew_SetRegANDOR() to xgifb_reg_and_or() Rename XGINew_SetRegANDOR() to xgifb_reg_and_or(). Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_ext.c | 24 +-- drivers/staging/xgifb/vb_init.c | 34 ++-- drivers/staging/xgifb/vb_setmode.c | 338 ++++++++++++++++++------------------- drivers/staging/xgifb/vb_util.c | 2 +- drivers/staging/xgifb/vb_util.h | 2 +- 5 files changed, 200 insertions(+), 200 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_ext.c b/drivers/staging/xgifb/vb_ext.c index c24ece2c0135..d7c1b2ebed17 100644 --- a/drivers/staging/xgifb/vb_ext.c +++ b/drivers/staging/xgifb/vb_ext.c @@ -34,7 +34,7 @@ static unsigned char XGINew_Sense(unsigned short tempbx, unsigned short tempcx, xgifb_reg_set(pVBInfo->Part4Port, 0x11, temp); temp = (tempbx & 0xFF00) >> 8; temp |= (tempcx & 0x00FF); - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x10, ~0x1F, temp); + xgifb_reg_and_or(pVBInfo->Part4Port, 0x10, ~0x1F, temp); for (i = 0; i < 10; i++) XGI_LongWait(pVBInfo); @@ -87,7 +87,7 @@ static unsigned char XGINew_GetLCDDDCInfo(struct xgi_hw_device_info *HwDeviceExt default: break; } - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x36, 0xF0, temp); + xgifb_reg_and_or(pVBInfo->P3d4, 0x36, 0xF0, temp); return 1; } } @@ -148,7 +148,7 @@ static unsigned char XGINew_GetPanelID(struct vb_device_info *pVBInfo) tempbx = PanelTypeTable[tempbx]; temp = (tempbx & 0xFF00) >> 8; - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~(LCDSyncBit + xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~(LCDSyncBit | LCDRGB18Bit), temp); return 1; } @@ -182,7 +182,7 @@ static unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtensi xgifb_reg_set(pVBInfo->Part4Port, 0x11, temp); temp = (tempbx & 0xFF00) >> 8; temp |= (tempcx & 0x00FF); - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x10, ~0x1F, temp); + xgifb_reg_and_or(pVBInfo->Part4Port, 0x10, ~0x1F, temp); for (i = 0; i < 10; i++) XGI_LongWait(pVBInfo); @@ -202,7 +202,7 @@ static unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtensi xgifb_reg_set(pVBInfo->Part4Port, 0x11, temp); temp = (tempbx & 0xFF00) >> 8; temp |= (tempcx & 0x00FF); - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x10, ~0x1F, temp); + xgifb_reg_and_or(pVBInfo->Part4Port, 0x10, ~0x1F, temp); for (i = 0; i < 10; i++) XGI_LongWait(pVBInfo); @@ -221,7 +221,7 @@ static unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtensi xgifb_reg_set(pVBInfo->Part4Port, 0x11, temp); temp = (tempbx & 0xFF00) >> 8; temp |= (tempcx & 0x00FF); - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x10, ~0x1F, temp); + xgifb_reg_and_or(pVBInfo->Part4Port, 0x10, ~0x1F, temp); for (i = 0; i < 10; i++) XGI_LongWait(pVBInfo); @@ -251,8 +251,8 @@ void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_ if (tempax == 0x00) { /* Get Panel id from DDC */ temp = XGINew_GetLCDDDCInfo(HwDeviceExtension, pVBInfo); if (temp == 1) { /* LCD connect */ - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x39, 0xFF, 0x01); /* set CR39 bit0="1" */ - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, 0xEF, 0x00); /* clean CR37 bit4="0" */ + xgifb_reg_and_or(pVBInfo->P3d4, 0x39, 0xFF, 0x01); /* set CR39 bit0="1" */ + xgifb_reg_and_or(pVBInfo->P3d4, 0x37, 0xEF, 0x00); /* clean CR37 bit4="0" */ temp = LCDSense; } else { /* LCD don't connect */ temp = 0; @@ -263,14 +263,14 @@ void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_ } tempbx = ~(LCDSense | AVIDEOSense | SVIDEOSense); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, tempbx, temp); + xgifb_reg_and_or(pVBInfo->P3d4, 0x32, tempbx, temp); } else { /* for 301 */ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiVision */ tempax = xgifb_reg_get(pVBInfo->P3c4, 0x38); temp = tempax & 0x01; tempax = xgifb_reg_get(pVBInfo->P3c4, 0x3A); temp = temp | (tempax & 0x02); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xA0, temp); + xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xA0, temp); } else { if (XGI_BridgeIsOn(pVBInfo)) { P2reg0 = xgifb_reg_get(pVBInfo->Part2Port, 0x00); @@ -291,7 +291,7 @@ void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_ XGI_SetCRT2Group301(SenseModeNo, HwDeviceExtension, pVBInfo); XGI_SetCRT2ModeRegs(0x2e, HwDeviceExtension, pVBInfo); /* XGI_DisableBridge( HwDeviceExtension, pVBInfo ) ; */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x20); /* Display Off 0212 */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x20); /* Display Off 0212 */ for (i = 0; i < 20; i++) XGI_LongWait(pVBInfo); } @@ -365,7 +365,7 @@ void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_ tempcx = 0; XGINew_Sense(tempbx, tempcx, pVBInfo); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~0xDF, tempax); + xgifb_reg_and_or(pVBInfo->P3d4, 0x32, ~0xDF, tempax); xgifb_reg_set(pVBInfo->Part2Port, 0x00, P2reg0); if (!(P2reg0 & 0x20)) { diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 46b8ebd7b2f0..45491be70b01 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -421,7 +421,7 @@ static void XGINew_SetDRAMDefaultRegister340( temp3 = 0; for (k = 0; k < 4; k++) { - XGINew_SetRegANDOR(P3d4, 0x6E, 0xFC, temp3); /* CR6E_D[1:0] select channel */ + xgifb_reg_and_or(P3d4, 0x6E, 0xFC, temp3); /* CR6E_D[1:0] select channel */ temp2 = 0; for (i = 0; i < 8; i++) { temp = pVBInfo->CR6F[XGINew_RAMType][8 * k + i]; /* CR6F DQ fine tune delay */ @@ -516,7 +516,7 @@ static void XGINew_SetDRAMSizingType(int index, unsigned short data; data = DRAMTYPE_TABLE[index][4]; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x13, 0x80, data); + xgifb_reg_and_or(pVBInfo->P3c4, 0x13, 0x80, data); udelay(15); /* should delay 50 ns */ } @@ -1197,20 +1197,20 @@ static void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension, if ((pVideoMemory[0x65] & 0x01)) { /* For XG21 LVDS */ pVBInfo->IF_DEF_LVDS = 1; xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS on chip */ + xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS on chip */ } else { #endif - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* Enable GPIOA/B read */ + xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* Enable GPIOA/B read */ Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0xC0; if (Temp == 0xC0) { /* DVI & DVO GPIOA/B pull high */ XGINew_SenseLCD(HwDeviceExtension, pVBInfo); xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x20, 0x20); /* Enable read GPIOF */ + xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x20, 0x20); /* Enable read GPIOF */ Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0x04; if (!Temp) - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0x80); /* TMDS on chip */ + xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0x80); /* TMDS on chip */ else - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* Only DVO on chip */ + xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* Only DVO on chip */ XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); /* Disable read GPIOF */ } #if 1 @@ -1225,16 +1225,16 @@ static void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension, pVBInfo->IF_DEF_LVDS = 0; bCR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x07, 0x07); /* Enable GPIOA/B/C read */ + xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x07, 0x07); /* Enable GPIOA/B/C read */ Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0x07; xgifb_reg_set(pVBInfo->P3d4, 0x4A, bCR4A); if (Temp <= 0x02) { pVBInfo->IF_DEF_LVDS = 1; - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS setting */ + xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS setting */ xgifb_reg_set(pVBInfo->P3d4, 0x30, 0x21); } else { - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* TMDS/DVO setting */ + xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* TMDS/DVO setting */ } xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense); @@ -1245,7 +1245,7 @@ static unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo) unsigned char CR38, CR4A, temp; CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x10, 0x10); /* enable GPIOE read */ + xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x10, 0x10); /* enable GPIOE read */ CR38 = xgifb_reg_get(pVBInfo->P3d4, 0x38); temp = 0; if ((CR38 & 0xE0) > 0x80) { @@ -1264,7 +1264,7 @@ static unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo) unsigned char CR4A, temp; CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* enable GPIOA/B/C read */ + xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* enable GPIOA/B/C read */ temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); if (temp <= 2) temp &= 0x03; @@ -1490,7 +1490,7 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */ /* Set VB */ XGI_UnLockCRT2(HwDeviceExtension, pVBInfo); - XGINew_SetRegANDOR(pVBInfo->Part0Port, 0x3F, 0xEF, 0x00); /* alan, disable VideoCapture */ + xgifb_reg_and_or(pVBInfo->Part0Port, 0x3F, 0xEF, 0x00); /* alan, disable VideoCapture */ xgifb_reg_set(pVBInfo->Part1Port, 0x00, 0x00); temp1 = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x7B); /* chk if BCLK>=100MHz */ temp = (unsigned char) ((temp1 >> 4) & 0x0F); @@ -1551,16 +1551,16 @@ unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) if (HwDeviceExtension->jChipType == XG21) { printk("186"); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */ + xgifb_reg_and_or(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */ temp = GetXG21FPBits(pVBInfo); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~0x01, temp); + xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x01, temp); printk("187"); } if (HwDeviceExtension->jChipType == XG27) { - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */ + xgifb_reg_and_or(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */ temp = GetXG27FPBits(pVBInfo); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~0x03, temp); + xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x03, temp); } printk("19"); diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 2dc8a1fb322a..49791c47d8ee 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -362,11 +362,11 @@ static void XGI_ClearExt1Regs(struct vb_device_info *pVBInfo) static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo) { - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, 0x20); + xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x20); xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[0].SR2B); xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[0].SR2C); - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, 0x10); + xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x10); xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[1].SR2B); xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[1].SR2C); @@ -536,7 +536,7 @@ static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, /* xgifb_reg_set(pVBInfo->P3d4, 0x51, 0); */ /* xgifb_reg_set(pVBInfo->P3d4, 0x56, 0); */ - /* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */ + /* xgifb_reg_and_or(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */ data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11); /* unlock cr0-7 */ data &= 0x7F; @@ -587,7 +587,7 @@ static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, if (data > 7) data = data - 7; data = data << 5; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0e, ~0xE0, data); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0e, ~0xE0, data); } } @@ -599,7 +599,7 @@ static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeN /* xgifb_reg_set(pVBInfo->P3d4, 0x51, 0); */ /* xgifb_reg_set(pVBInfo->P3d4, 0x56, 0); */ - /* XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */ + /* xgifb_reg_and_or(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */ for (i = 0x00; i <= 0x01; i++) { data = pVBInfo->TimingV[0].data[i]; @@ -699,7 +699,7 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */ Tempdx <<= 2; /* Tempdx << 2 */ xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00); + xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; /* Tempax: CR16 VRS */ Tempbx = Tempax; /* Tempbx=Tempax */ @@ -767,7 +767,7 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */ Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */ xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F D[7:2]->HRE, D[1:0]->HRS */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00); + xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; /* CR10 VRS */ Tempbx = Tempax; /* Tempbx: VRS */ @@ -836,7 +836,7 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */ Tempdx <<= 2; /* Tempdx << 2 */ xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00); + xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; /* Tempax: CR10 VRS */ xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS */ @@ -845,7 +845,7 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, Tempbx = Tempax; /* Tempbx=CR07 */ Tempax &= 0x04; /* Tempax[2]: CR07[2] VRS[8] */ Tempax >>= 2; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x01, Tempax); /* SR35 D[0]->VRS D[8] */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax); /* SR35 D[0]->VRS D[8] */ Tempcx |= (Tempax << 8); /* Tempcx[8] |= VRS[8] */ Tempcx |= (Tempbx & 0x80) << 2; /* Tempcx[9] |= VRS[9] */ @@ -859,8 +859,8 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, Tempax = (unsigned char) Tempbx & 0xFF; /* Tempax[7:0]: VRE[7:0] */ Tempax <<= 2; /* Tempax << 2: VRE[5:0] */ Tempcx = (Tempcx & 0x600) >> 8; /* Tempcx VRS[10:9] */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); /* SR3F D[7:2]->VRE D[5:0] */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x06, Tempcx); /* SR35 D[2:1]->VRS[10:9] */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); /* SR3F D[7:2]->VRE D[5:0] */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x06, Tempcx); /* SR35 D[2:1]->VRS[10:9] */ } else { index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */ @@ -893,7 +893,7 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/ Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */ xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, 0xE3, 00); + xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; /* CR10 VRS */ xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS[7:0] */ @@ -903,7 +903,7 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, Tempbx = Tempax; /* Tempbx <= CR07[7:0] */ Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */ Tempax >>= 2; /* Tempax[0]: VRS[8] */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x01, Tempax); /* SR35[0]: VRS[8] */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax); /* SR35[0]: VRS[8] */ Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */ Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempax: SR0A */ @@ -924,9 +924,9 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, Tempbx |= 0x20; /* VRE + 0x20 */ Tempax = (Tempbx << 2) & 0xFF; /* Tempax: Tempax[7:0]; VRE[5:0]00 */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); /* SR3F[7:2]:VRE[5:0] */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); /* SR3F[7:2]:VRE[5:0] */ Tempax = Tempcx >> 8; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x07, Tempax); /* SR35[2:0]:VRS[10:8] */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, Tempax); /* SR35[2:0]:VRS[10:8] */ } } @@ -1127,7 +1127,7 @@ static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, data &= 0x7F; xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */ xgifb_reg_set(pVBInfo->P3d4, 0x01, (unsigned short) (tempcx & 0xff)); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x0b, ~0x0c, + xgifb_reg_and_or(pVBInfo->P3d4, 0x0b, ~0x0c, (unsigned short) ((tempcx & 0x0ff00) >> 10)); xgifb_reg_set(pVBInfo->P3d4, 0x12, (unsigned short) (tempbx & 0xff)); tempax = 0; @@ -1139,7 +1139,7 @@ static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, if (tempbx & 0x02) tempax |= 0x40; - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x42, tempax); + xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x42, tempax); data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x07); data &= 0xFF; tempax = 0; @@ -1147,7 +1147,7 @@ static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, if (tempbx & 0x04) tempax |= 0x02; - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x0a, ~0x02, tempax); + xgifb_reg_and_or(pVBInfo->P3d4, 0x0a, ~0x02, tempax); xgifb_reg_set(pVBInfo->P3d4, 0x11, temp); } @@ -1559,9 +1559,9 @@ static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, */ data2 = 0x00; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x07, 0xFC, data2); + xgifb_reg_and_or(pVBInfo->P3c4, 0x07, 0xFC, data2); if (HwDeviceExtension->jChipType >= XG27) - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x40, 0xFC, data2 & 0x03); + xgifb_reg_and_or(pVBInfo->P3c4, 0x40, 0xFC, data2 & 0x03); } @@ -1581,7 +1581,7 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */ if (xgifb_reg_get(pVBInfo->P3d4, 0x31) & 0x01) - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1F, 0x3F, 0x00); + xgifb_reg_and_or(pVBInfo->P3c4, 0x1F, 0x3F, 0x00); if (ModeNo > 0x13) data = infoflag; @@ -1604,7 +1604,7 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, if (data) data2 |= 0x20; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x06, ~0x3F, data2); + xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x3F, data2); /* xgifb_reg_set(pVBInfo->P3c4,0x06,data2); */ resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); if (ModeNo <= 0x13) @@ -1621,12 +1621,12 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, } data2 = data & 0x00FF; - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x19, 0xFF, data2); + xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFF, data2); data2 = (data & 0xFF00) >> 8; - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x19, 0xFC, data2); + xgifb_reg_and_or(pVBInfo->P3d4, 0x19, 0xFC, data2); if (modeflag & HalfDCLK) - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xF7, 0x08); + xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xF7, 0x08); data2 = 0; @@ -1638,14 +1638,14 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, data2 |= 0x40; } - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0F, ~0x48, data2); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0F, ~0x48, data2); data = 0x60; if (pVBInfo->ModeType != ModeText) { data = data ^ 0x60; if (pVBInfo->ModeType != ModeEGA) data = data ^ 0xA0; } - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x21, 0x1F, data); + xgifb_reg_and_or(pVBInfo->P3c4, 0x21, 0x1F, data); XGI_SetVCLKState(HwDeviceExtension, ModeNo, RefreshRateTableIndex, pVBInfo); @@ -1696,19 +1696,19 @@ void XGI_VesaLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, st if (pVBInfo->VBType & VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) { if (pVBInfo->VBInfo & SetInSlaveMode) { - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xf7, 0x00); - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0f, 0x7f, 0x00); + xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xf7, 0x00); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0f, 0x7f, 0x00); return; } } } - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0f, 0xff, 0x80); - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xf7, 0x00); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0f, 0xff, 0x80); + xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xf7, 0x00); return; } } } - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0f, 0x7f, 0x00); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0f, 0x7f, 0x00); } */ @@ -2653,7 +2653,7 @@ static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo); if (pVBInfo->IF_DEF_CH7007 == 1) { - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x33, ~0x01, + xgifb_reg_and_or(pVBInfo->P3c4, 0x33, ~0x01, CH7007TV_TimingVPtr[0].data[7] & 0x01); xgifb_reg_set(pVBInfo->P3c4, 0x34, CH7007TV_TimingVPtr[0].data[8]); @@ -2914,7 +2914,7 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_set(pVBInfo->Part1Port, 0x18, (unsigned short) (tempbx & 0xff)); - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, ~0x0f, + xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, ~0x0f, (unsigned short) (tempcx & 0x0f)); tempax = ((tempbx >> 8) & 0x07) << 3; @@ -2926,7 +2926,7 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->LCDInfo & EnableLVDSDDA) tempax |= 0x40; - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1a, 0x07, + xgifb_reg_and_or(pVBInfo->Part1Port, 0x1a, 0x07, tempax); tempcx = pVBInfo->VGAVT; @@ -2967,17 +2967,17 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, (unsigned short) ((temp2 >> 8) & 0xff)); tempbx = (unsigned short) (temp2 >> 16); - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x3a, + xgifb_reg_and_or(pVBInfo->Part4Port, 0x3a, ~0xc0, (unsigned short) ((tempbx & 0xff) << 6)); tempcx = pVBInfo->VGAVDE; if (tempcx == pVBInfo->VDE) - XGINew_SetRegANDOR(pVBInfo->Part4Port, + xgifb_reg_and_or(pVBInfo->Part4Port, 0x30, ~0x0c, 0x00); else - XGINew_SetRegANDOR(pVBInfo->Part4Port, + xgifb_reg_and_or(pVBInfo->Part4Port, 0x30, ~0x0c, 0x08); } @@ -3251,7 +3251,7 @@ static void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex, XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo); for (i = 0; i < 4; i++) { - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x31, ~0x30, + xgifb_reg_and_or(pVBInfo->P3d4, 0x31, ~0x30, (unsigned short) (0x10 * i)); if (pVBInfo->IF_DEF_CH7007 == 1) { xgifb_reg_set(pVBInfo->P3c4, 0x2b, di_0); @@ -3344,7 +3344,7 @@ static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension, } temp = tempcl; tempbl = ~ModeSwitchStatus; - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x3d, tempbl, temp); + xgifb_reg_and_or(pVBInfo->P3d4, 0x3d, tempbl, temp); if (!(pVBInfo->SetFlag & ReserveTVOption)) xgifb_reg_set(pVBInfo->P3d4, 0x3e, tempch); @@ -4118,7 +4118,7 @@ void XGI_DisplayOn(struct xgi_hw_device_info *pXGIHWDE, struct vb_device_info *pVBInfo) { - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x00); + xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x00); if (pXGIHWDE->jChipType == XG21) { if (pVBInfo->IF_DEF_LVDS == 1) { if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x1)) { @@ -4185,7 +4185,7 @@ void XGI_DisplayOff(struct xgi_hw_device_info *pXGIHWDE, XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo); /* DVO/DVI signal off */ } - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x01, 0xDF, 0x20); + xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x20); } static void XGI_WaitDisply(struct vb_device_info *pVBInfo) @@ -4218,7 +4218,7 @@ static void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBIn xgifb_reg_set(pVBInfo->P3d4, 0x34, ModeNo); /* reserve CR34 for CRT1 Mode No */ temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8; temp2 = ~(SetInSlaveMode >> 8); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x31, temp2, temp1); + xgifb_reg_and_or(pVBInfo->P3d4, 0x31, temp2, temp1); } static void XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, @@ -4658,7 +4658,7 @@ static void XGI_SetCRT2Offset(unsigned short ModeNo, static void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo) { xgifb_reg_set(pVBInfo->Part1Port, 0x01, 0x3B); /* threshold high ,disable auto threshold */ - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04); /* threshold low default 04h */ + xgifb_reg_and_or(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04); /* threshold low default 04h */ } static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, @@ -4710,7 +4710,7 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */ xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp); temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4; - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x09, ~0x0F0, temp); + xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp); temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */ xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2; @@ -4744,7 +4744,7 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */ xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp); temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4; - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x09, ~0x0F0, temp); + xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp); temp = (pVBInfo->VGAHDE + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */ xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp); tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */ @@ -4836,7 +4836,7 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, if (modeflag & HalfDCLK) tempax |= 0x40; - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax); + xgifb_reg_and_or(pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax); } static unsigned short XGI_GetVGAHT2(struct vb_device_info *pVBInfo) @@ -5052,7 +5052,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, } xgifb_reg_set(pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */ - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0xF0, 0x00); + xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0xF0, 0x00); xgifb_reg_set(pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */ tempbx = pVBInfo->VGAVT; @@ -5183,7 +5183,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, tempcx |= 0x0008; if (tempbx & 0x0200) - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20); + xgifb_reg_and_or(pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20); tempbx++; @@ -5311,11 +5311,11 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]); /* di->temp2[j] */ if (pVBInfo->VBInfo & SetCRT2ToTV) - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x3A, 0x1F, 0x00); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, 0x00); temp = pVBInfo->NewFlickerMode; temp &= 0x80; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0xFF, temp); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xFF, temp); if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) tempax = 950; @@ -5379,7 +5379,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_set(pVBInfo->Part2Port, 0x1B, temp); temp = (tempcx & 0xFF00) >> 8; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1D, ~0x0F, temp); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F, temp); tempcx = pVBInfo->HT >> 1; push1 = tempcx; /* push cx */ @@ -5390,7 +5390,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, temp = tempcx & 0x00FF; temp = temp << 4; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x22, 0x0F, temp); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x22, 0x0F, temp); tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8); tempbx += tempcx; @@ -5399,7 +5399,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_set(pVBInfo->Part2Port, 0x24, temp); temp = (tempbx & 0xFF00) >> 8; temp = temp << 4; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x25, 0x0F, temp); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x25, 0x0F, temp); tempbx = push2; tempbx = tempbx + 8; @@ -5409,14 +5409,14 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, } temp = (tempbx & 0x00FF) << 4; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x29, 0x0F, temp); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x29, 0x0F, temp); j += 2; tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8)); temp = tempcx & 0x00FF; xgifb_reg_set(pVBInfo->Part2Port, 0x27, temp); temp = ((tempcx & 0xFF00) >> 8) << 4; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x28, 0x0F, temp); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x28, 0x0F, temp); tempcx += 8; if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) @@ -5424,7 +5424,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, temp = tempcx & 0xFF; temp = temp << 4; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2A, 0x0F, temp); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x2A, 0x0F, temp); tempcx = push1; /* pop cx */ j += 2; @@ -5432,7 +5432,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, tempcx -= temp; temp = tempcx & 0x00FF; temp = temp << 4; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2D, 0x0F, temp); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x2D, 0x0F, temp); tempcx -= 11; @@ -5599,7 +5599,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_set(pVBInfo->Part2Port, 0x44, temp); temp = (tempbx & 0xFF00) >> 8; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x45, ~0x03F, temp); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x45, ~0x03F, temp); temp = tempcx & 0x00FF; if (tempbx & 0x2000) @@ -5608,7 +5608,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) temp |= 0x18; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x46, ~0x1F, temp); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x46, ~0x1F, temp); if (pVBInfo->TVInfo & SetPALTV) { tempbx = 0x0382; tempcx = 0x007e; @@ -5654,7 +5654,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, /* [ycchen] 01/14/03 Modify for 301C PALM Support */ if (pVBInfo->VBType & VB_XGI301C) { if (pVBInfo->TVInfo & SetPALMTV) - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x08, + xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x08, 0x08); /* PALM Mode */ } @@ -5711,7 +5711,7 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_set(pVBInfo->Part2Port, 0x2C, temp); temp = (tempbx & 0xFF00) >> 8; temp = temp << 4; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x2B, 0x0F, temp); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x2B, 0x0F, temp); temp = 0x01; if (pVBInfo->LCDResInfo == Panel1280x1024) { @@ -5731,7 +5731,7 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, temp = tempbx & 0x00FF; xgifb_reg_set(pVBInfo->Part2Port, 0x03, temp); temp = ((tempbx & 0xFF00) >> 8) & 0x07; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0C, ~0x07, temp); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x0C, ~0x07, temp); tempcx = pVBInfo->VT - 1; push2 = tempcx + 1; @@ -5740,10 +5740,10 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, temp = (tempcx & 0xFF00) >> 8; temp = temp << 5; xgifb_reg_set(pVBInfo->Part2Port, 0x1A, temp); - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x09, 0xF0, 0x00); - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0xF0, 0x00); - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x17, 0xFB, 0x00); - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x18, 0xDF, 0x00); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x09, 0xF0, 0x00); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xF0, 0x00); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x17, 0xFB, 0x00); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x18, 0xDF, 0x00); /* Customized LCDB Des no add */ tempbx = 5; @@ -5867,7 +5867,7 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, temp = (tempbx & 0xFF00) >> 8; temp = temp << 4; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1D, ~0x0F0, temp); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x1D, ~0x0F0, temp); temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */ xgifb_reg_set(pVBInfo->Part2Port, 0x21, temp); @@ -5972,9 +5972,9 @@ static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo) } if ((pVBInfo->VBInfo & SetCRT2ToTV) && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04); /* Enable V.Scaling */ + xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04); /* Enable V.Scaling */ else - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x4E, ~0x14, 0x10); /* Enable H.Scaling */ + xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x10); /* Enable H.Scaling */ #endif } @@ -6109,7 +6109,7 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->VGAHDE == 1024) temp = 0x20; } - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0E, ~0xEF, temp); + xgifb_reg_and_or(pVBInfo->Part4Port, 0x0E, ~0xEF, temp); tempebx = pVBInfo->VDE; @@ -6223,13 +6223,13 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, } } - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x1F, 0x00C0, temp); + xgifb_reg_and_or(pVBInfo->Part4Port, 0x1F, 0x00C0, temp); tempbx = pVBInfo->HT; if (XGI_IsLCDDualLink(pVBInfo)) tempbx = tempbx >> 1; tempbx = (tempbx >> 1) - 2; temp = ((tempbx & 0x0700) >> 8) << 3; - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x21, 0x00C0, temp); + xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, 0x00C0, temp); temp = tempbx & 0x00FF; xgifb_reg_set(pVBInfo->Part4Port, 0x22, temp); } @@ -6242,7 +6242,7 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, static void XGINew_EnableCRT2(struct vb_device_info *pVBInfo) { - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x1E, 0xFF, 0x20); + xgifb_reg_and_or(pVBInfo->P3c4, 0x1E, 0xFF, 0x20); } static void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex, @@ -6265,14 +6265,14 @@ static void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex, static void XGI_EnableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x63, 0xBF, 0x40); + xgifb_reg_and_or(pVBInfo->P3d4, 0x63, 0xBF, 0x40); } static void XGI_DisableGatingCRT(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x63, 0xBF, 0x00); + xgifb_reg_and_or(pVBInfo->P3d4, 0x63, 0xBF, 0x00); } /*----------------------------------------------------------------------------*/ @@ -6297,7 +6297,7 @@ void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl, if (tempbh & 0x20) { temp = (tempbl >> 4) & 0x02; - XGINew_SetRegANDOR(pVBInfo->P3d4, 0xB4, ~0x02, temp); /* CR B4[1] */ + xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp); /* CR B4[1] */ } @@ -6325,10 +6325,10 @@ void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl, if (tempbh & 0x20) { temp = (tempbl >> 4) & 0x02; - XGINew_SetRegANDOR(pVBInfo->P3d4, 0xB4, ~0x02, temp); /* CR B4[1] */ + xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp); /* CR B4[1] */ } - XGINew_SetRegANDOR(pVBInfo->P3d4, 0xB4, ~tempbh0, tempbl0); + xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~tempbh0, tempbl0); CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); tempbh &= 0x03; @@ -6336,7 +6336,7 @@ void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl, tempbh <<= 2; tempbl <<= 2; /* GPIOC,GPIOD */ XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */ - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x48, ~tempbh, tempbl); + xgifb_reg_and_or(pVBInfo->P3d4, 0x48, ~tempbh, tempbl); } /* --------------------------------------------------------------------- */ @@ -6439,8 +6439,8 @@ void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo) temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); /* D[0] 1: 18bit */ temp = (temp & 1) << 6; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x06, ~0x40, temp); /* SR06[6] 18bit Dither */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80); /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x40, temp); /* SR06[6] 18bit Dither */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80); /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */ } @@ -6450,8 +6450,8 @@ void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo) temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */ temp = (temp & 3) << 6; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x06, ~0xc0, temp & 0x80); /* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80); /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0xc0, temp & 0x80); /* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80); /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */ } @@ -6475,8 +6475,8 @@ static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde temp = (unsigned char) (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & LCDPolarity); - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80); /* SR35[7] FP VSync polarity */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1); /* SR30[5] FP HSync polarity */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80); /* SR35[7] FP VSync polarity */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1); /* SR30[5] FP HSync polarity */ XGI_SetXG21FPBits(pVBInfo); resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); @@ -6543,81 +6543,81 @@ static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde /* HT SR0B[1:0] CR00 */ value = (LVDSHT >> 3) - 5; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0x03, (value & 0x300) >> 8); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x03, (value & 0x300) >> 8); xgifb_reg_set(pVBInfo->P3d4, 0x0, (value & 0xFF)); /* HBS SR0B[5:4] CR02 */ value = (LVDSHBS >> 3) - 1; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0x30, (value & 0x300) >> 4); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x30, (value & 0x300) >> 4); xgifb_reg_set(pVBInfo->P3d4, 0x2, (value & 0xFF)); /* HBE SR0C[1:0] CR05[7] CR03[4:0] */ value = (LVDSHBE >> 3) - 1; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0C, ~0x03, (value & 0xC0) >> 6); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x05, ~0x80, (value & 0x20) << 2); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x03, ~0x1F, value & 0x1F); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x03, (value & 0xC0) >> 6); + xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x80, (value & 0x20) << 2); + xgifb_reg_and_or(pVBInfo->P3d4, 0x03, ~0x1F, value & 0x1F); /* HRS SR0B[7:6] CR04 */ value = (LVDSHRS >> 3) + 2; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0xC0, (value & 0x300) >> 2); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0xC0, (value & 0x300) >> 2); xgifb_reg_set(pVBInfo->P3d4, 0x4, (value & 0xFF)); /* Panel HRS SR2F[1:0] SR2E[7:0] */ value--; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x2F, ~0x03, (value & 0x300) >> 8); + xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0x03, (value & 0x300) >> 8); xgifb_reg_set(pVBInfo->P3c4, 0x2E, (value & 0xFF)); /* HRE SR0C[2] CR05[4:0] */ value = (LVDSHRE >> 3) + 2; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0C, ~0x04, (value & 0x20) >> 3); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x05, ~0x1F, value & 0x1F); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x04, (value & 0x20) >> 3); + xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x1F, value & 0x1F); /* Panel HRE SR2F[7:2] */ value--; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x2F, ~0xFC, value << 2); + xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0xFC, value << 2); /* VT SR0A[0] CR07[5][0] CR06 */ value = LVDSVT - 2; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x01, (value & 0x400) >> 10); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x20, (value & 0x200) >> 4); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x01, (value & 0x100) >> 8); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x01, (value & 0x400) >> 10); + xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x20, (value & 0x200) >> 4); + xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x01, (value & 0x100) >> 8); xgifb_reg_set(pVBInfo->P3d4, 0x06, (value & 0xFF)); /* VBS SR0A[2] CR09[5] CR07[3] CR15 */ value = LVDSVBS - 1; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x04, (value & 0x400) >> 8); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x09, ~0x20, (value & 0x200) >> 4); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x08, (value & 0x100) >> 5); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x04, (value & 0x400) >> 8); + xgifb_reg_and_or(pVBInfo->P3d4, 0x09, ~0x20, (value & 0x200) >> 4); + xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x08, (value & 0x100) >> 5); xgifb_reg_set(pVBInfo->P3d4, 0x15, (value & 0xFF)); /* VBE SR0A[4] CR16 */ value = LVDSVBE - 1; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x10, (value & 0x100) >> 4); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x10, (value & 0x100) >> 4); xgifb_reg_set(pVBInfo->P3d4, 0x16, (value & 0xFF)); /* VRS SR0A[3] CR7[7][2] CR10 */ value = LVDSVRS - 1; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x08, (value & 0x400) >> 7); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x80, (value & 0x200) >> 2); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x04, (value & 0x100) >> 6); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x08, (value & 0x400) >> 7); + xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x80, (value & 0x200) >> 2); + xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x04, (value & 0x100) >> 6); xgifb_reg_set(pVBInfo->P3d4, 0x10, (value & 0xFF)); /* Panel VRS SR3F[1:0] SR34[7:0] SR33[0] */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0x03, (value & 0x600) >> 9); + xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0x03, (value & 0x600) >> 9); xgifb_reg_set(pVBInfo->P3c4, 0x34, (value >> 1) & 0xFF); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x33, ~0x01, value & 0x01); + xgifb_reg_and_or(pVBInfo->P3d4, 0x33, ~0x01, value & 0x01); /* VRE SR0A[5] CR11[3:0] */ value = LVDSVRE - 1; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x20, (value & 0x10) << 1); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, ~0x0F, value & 0x0F); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x20, (value & 0x10) << 1); + xgifb_reg_and_or(pVBInfo->P3d4, 0x11, ~0x0F, value & 0x0F); /* Panel VRE SR3F[7:2] *//* SR3F[7] has to be 0, h/w bug */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, (value << 2) & 0x7C); + xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, (value << 2) & 0x7C); for (temp = 0, value = 0; temp < 3; temp++) { - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, value); + xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, value); xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1); @@ -6660,8 +6660,8 @@ static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde temp = (unsigned char) (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & LCDPolarity); - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80); /* SR35[7] FP VSync polarity */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1); /* SR30[5] FP HSync polarity */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80); /* SR35[7] FP VSync polarity */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1); /* SR30[5] FP HSync polarity */ XGI_SetXG27FPBits(pVBInfo); resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); @@ -6728,80 +6728,80 @@ static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdInde /* HT SR0B[1:0] CR00 */ value = (LVDSHT >> 3) - 5; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0x03, (value & 0x300) >> 8); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x03, (value & 0x300) >> 8); xgifb_reg_set(pVBInfo->P3d4, 0x0, (value & 0xFF)); /* HBS SR0B[5:4] CR02 */ value = (LVDSHBS >> 3) - 1; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0x30, (value & 0x300) >> 4); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0x30, (value & 0x300) >> 4); xgifb_reg_set(pVBInfo->P3d4, 0x2, (value & 0xFF)); /* HBE SR0C[1:0] CR05[7] CR03[4:0] */ value = (LVDSHBE >> 3) - 1; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0C, ~0x03, (value & 0xC0) >> 6); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x05, ~0x80, (value & 0x20) << 2); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x03, ~0x1F, value & 0x1F); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x03, (value & 0xC0) >> 6); + xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x80, (value & 0x20) << 2); + xgifb_reg_and_or(pVBInfo->P3d4, 0x03, ~0x1F, value & 0x1F); /* HRS SR0B[7:6] CR04 */ value = (LVDSHRS >> 3) + 2; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0B, ~0xC0, (value & 0x300) >> 2); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0B, ~0xC0, (value & 0x300) >> 2); xgifb_reg_set(pVBInfo->P3d4, 0x4, (value & 0xFF)); /* Panel HRS SR2F[1:0] SR2E[7:0] */ value--; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x2F, ~0x03, (value & 0x300) >> 8); + xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0x03, (value & 0x300) >> 8); xgifb_reg_set(pVBInfo->P3c4, 0x2E, (value & 0xFF)); /* HRE SR0C[2] CR05[4:0] */ value = (LVDSHRE >> 3) + 2; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0C, ~0x04, (value & 0x20) >> 3); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x05, ~0x1F, value & 0x1F); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0C, ~0x04, (value & 0x20) >> 3); + xgifb_reg_and_or(pVBInfo->P3d4, 0x05, ~0x1F, value & 0x1F); /* Panel HRE SR2F[7:2] */ value--; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x2F, ~0xFC, value << 2); + xgifb_reg_and_or(pVBInfo->P3c4, 0x2F, ~0xFC, value << 2); /* VT SR0A[0] CR07[5][0] CR06 */ value = LVDSVT - 2; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x01, (value & 0x400) >> 10); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x20, (value & 0x200) >> 4); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x01, (value & 0x100) >> 8); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x01, (value & 0x400) >> 10); + xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x20, (value & 0x200) >> 4); + xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x01, (value & 0x100) >> 8); xgifb_reg_set(pVBInfo->P3d4, 0x06, (value & 0xFF)); /* VBS SR0A[2] CR09[5] CR07[3] CR15 */ value = LVDSVBS - 1; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x04, (value & 0x400) >> 8); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x09, ~0x20, (value & 0x200) >> 4); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x08, (value & 0x100) >> 5); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x04, (value & 0x400) >> 8); + xgifb_reg_and_or(pVBInfo->P3d4, 0x09, ~0x20, (value & 0x200) >> 4); + xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x08, (value & 0x100) >> 5); xgifb_reg_set(pVBInfo->P3d4, 0x15, (value & 0xFF)); /* VBE SR0A[4] CR16 */ value = LVDSVBE - 1; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x10, (value & 0x100) >> 4); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x10, (value & 0x100) >> 4); xgifb_reg_set(pVBInfo->P3d4, 0x16, (value & 0xFF)); /* VRS SR0A[3] CR7[7][2] CR10 */ value = LVDSVRS - 1; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x08, (value & 0x400) >> 7); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x80, (value & 0x200) >> 2); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x07, ~0x04, (value & 0x100) >> 6); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x08, (value & 0x400) >> 7); + xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x80, (value & 0x200) >> 2); + xgifb_reg_and_or(pVBInfo->P3d4, 0x07, ~0x04, (value & 0x100) >> 6); xgifb_reg_set(pVBInfo->P3d4, 0x10, (value & 0xFF)); /* Panel VRS SR35[2:0] SR34[7:0] */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x35, ~0x07, (value & 0x700) >> 8); + xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, (value & 0x700) >> 8); xgifb_reg_set(pVBInfo->P3c4, 0x34, value & 0xFF); /* VRE SR0A[5] CR11[3:0] */ value = LVDSVRE - 1; - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x0A, ~0x20, (value & 0x10) << 1); - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x11, ~0x0F, value & 0x0F); + xgifb_reg_and_or(pVBInfo->P3c4, 0x0A, ~0x20, (value & 0x10) << 1); + xgifb_reg_and_or(pVBInfo->P3d4, 0x11, ~0x0F, value & 0x0F); /* Panel VRE SR3F[7:2] */ - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x3F, ~0xFC, (value << 2) & 0xFC); + xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, (value << 2) & 0xFC); for (temp = 0, value = 0; temp < 3; temp++) { - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x31, ~0x30, value); + xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, value); xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1); @@ -7152,7 +7152,7 @@ static void XGI_SetDelayComp(struct vb_device_info *pVBInfo) pVBInfo)].LCD_DelayCompensation; /* / Get LCD Delay */ tempah &= 0x0f; tempah = tempah << 4; - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2D, 0x0f, + xgifb_reg_and_or(pVBInfo->Part1Port, 0x2D, 0x0f, tempah); } } @@ -7165,22 +7165,22 @@ static void XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInf temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); if (temp & LCDRGB18Bit) { - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, + xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short) (0x20 | (tempcx & 0x00C0))); /* Enable Dither */ - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80); + xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80); } else { - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, + xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short) (0x30 | (tempcx & 0x00C0))); - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00); + xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00); } /* if (tempcx & EnableLCD24bpp) { // 24bits - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short)(0x30 | (tempcx&0x00C0))); - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00); + xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short)(0x30 | (tempcx&0x00C0))); + xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00); } else { - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short)(0x20 | (tempcx&0x00C0))); // Enable Dither - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80); + xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short)(0x20 | (tempcx&0x00C0))); // Enable Dither + xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80); } */ } @@ -7194,11 +7194,11 @@ static void XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInf static void XGI_SetLCDCap_B(unsigned short tempcx, struct vb_device_info *pVBInfo) { if (tempcx & EnableLCD24bpp) /* 24bits */ - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1A, 0xE0, + xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0, (unsigned short) (((tempcx & 0x00ff) >> 6) | 0x0c)); else - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x1A, 0xE0, + xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0, (unsigned short) (((tempcx & 0x00ff) >> 6) | 0x18)); /* Enable Dither */ } @@ -7240,7 +7240,7 @@ static void XGI_SetLCDCap(struct vb_device_info *pVBInfo) (unsigned char) (tempcx & 0x1F)); } /* VB Driving */ - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0D, + xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D, ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8), (unsigned short) ((tempcx & (EnableVBCLKDRVLOW | EnablePLLSPLOW)) >> 8)); @@ -7291,7 +7291,7 @@ static void XGI_SetAntiFlicker(unsigned short ModeNo, unsigned short ModeIdIndex tempah = TVAntiFlickList[tempbx]; tempah = tempah << 4; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x0A, 0x8F, tempah); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0x8F, tempah); } static void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex, @@ -7313,7 +7313,7 @@ static void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex tempah = TVEdgeList[tempbx]; tempah = tempah << 5; - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x3A, 0x1F, tempah); + xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, tempah); } static void XGI_SetPhaseIncr(struct vb_device_info *pVBInfo) @@ -7518,7 +7518,7 @@ void XGI_SetCRT2ModeRegs(unsigned short ModeNo, tempbl = 0xf0; if (pVBInfo->VBInfo & DisableCRT2Display) { - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e, tempbl, tempah); + xgifb_reg_and_or(pVBInfo->Part1Port, 0x2e, tempbl, tempah); } else { tempah = 0x00; tempbl = 0xff; @@ -7529,7 +7529,7 @@ void XGI_SetCRT2ModeRegs(unsigned short ModeNo, && (!(pVBInfo->VBInfo & SetSimuScanMode))) { tempbl &= 0xf7; tempah |= 0x01; - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e, + xgifb_reg_and_or(pVBInfo->Part1Port, 0x2e, tempbl, tempah); } else { if (pVBInfo->VBInfo & SetCRT2ToLCDA) { @@ -7555,15 +7555,15 @@ void XGI_SetCRT2ModeRegs(unsigned short ModeNo, if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge)) tempah |= 0x08; - XGINew_SetRegANDOR(pVBInfo->Part1Port, + xgifb_reg_and_or(pVBInfo->Part1Port, 0x2e, tempbl, tempah); } else { - XGINew_SetRegANDOR(pVBInfo->Part1Port, + xgifb_reg_and_or(pVBInfo->Part1Port, 0x2e, tempbl, tempah); } } } else { - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2e, tempbl, + xgifb_reg_and_or(pVBInfo->Part1Port, 0x2e, tempbl, tempah); } } @@ -7587,7 +7587,7 @@ void XGI_SetCRT2ModeRegs(unsigned short ModeNo, /* } */ } - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah); + xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah); tempah = 0; if (pVBInfo->LCDInfo & SetLCDDualLink) @@ -7621,7 +7621,7 @@ void XGI_SetCRT2ModeRegs(unsigned short ModeNo, tempah |= 0x04; /* shampoo 0129 */ } - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x13, tempbl, tempah); + xgifb_reg_and_or(pVBInfo->Part1Port, 0x13, tempbl, tempah); tempah = 0x00; tempbl = 0xcf; if (!(pVBInfo->VBInfo & DisableCRT2Display)) { @@ -7629,7 +7629,7 @@ void XGI_SetCRT2ModeRegs(unsigned short ModeNo, tempah |= 0x30; } - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2c, tempbl, tempah); + xgifb_reg_and_or(pVBInfo->Part1Port, 0x2c, tempbl, tempah); tempah = 0; tempbl = 0x3f; @@ -7637,7 +7637,7 @@ void XGI_SetCRT2ModeRegs(unsigned short ModeNo, if (pVBInfo->VBInfo & SetCRT2ToDualEdge) tempah |= 0xc0; } - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x21, tempbl, tempah); + xgifb_reg_and_or(pVBInfo->Part4Port, 0x21, tempbl, tempah); } tempah = 0; @@ -7648,7 +7648,7 @@ void XGI_SetCRT2ModeRegs(unsigned short ModeNo, tempah |= 0x80; } - XGINew_SetRegANDOR(pVBInfo->Part4Port, 0x23, tempbl, tempah); + xgifb_reg_and_or(pVBInfo->Part4Port, 0x23, tempbl, tempah); if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) { if (pVBInfo->LCDInfo & SetLCDDualLink) { @@ -7681,7 +7681,7 @@ void XGI_UnLockCRT2(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2f, 0xFF, 0x01); + xgifb_reg_and_or(pVBInfo->Part1Port, 0x2f, 0xFF, 0x01); } @@ -7689,7 +7689,7 @@ void XGI_LockCRT2(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) { - XGINew_SetRegANDOR(pVBInfo->Part1Port, 0x2F, 0xFE, 0x00); + xgifb_reg_and_or(pVBInfo->Part1Port, 0x2F, 0xFE, 0x00); } @@ -8013,9 +8013,9 @@ void XGI_SenseCRT1(struct vb_device_info *pVBInfo) temp = inb(pVBInfo->P3c2); if (temp & 0x10) - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xDF, 0x20); + xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x20); else - XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, 0xDF, 0x00); + xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xDF, 0x00); /* alan, avoid display something, set BLACK DAC if not restore DAC */ outb(0x00, pVBInfo->P3c8); @@ -8091,7 +8091,7 @@ void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, if ((pVBInfo->SetFlag & (EnableChA | EnableChB)) || (!(pVBInfo->VBInfo & DisableCRT2Display))) { - XGINew_SetRegANDOR(pVBInfo->Part2Port, 0x00, ~0xE0, + xgifb_reg_and_or(pVBInfo->Part2Port, 0x00, ~0xE0, 0x20); /* shampoo 0129 */ if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) { if (!XGI_DisableChISLCD(pVBInfo)) { @@ -8442,7 +8442,7 @@ unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension, XGI_DisplayOn(HwDeviceExtension, pVBInfo); /* if (HwDeviceExtension->jChipType == XG21) - XGINew_SetRegANDOR(pVBInfo->P3c4, 0x09, ~0x80, 0x80); + xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0x80, 0x80); */ } diff --git a/drivers/staging/xgifb/vb_util.c b/drivers/staging/xgifb/vb_util.c index f9605dd14fb5..9eb80600ac3c 100644 --- a/drivers/staging/xgifb/vb_util.c +++ b/drivers/staging/xgifb/vb_util.c @@ -24,7 +24,7 @@ unsigned char xgifb_reg_get(unsigned long port, unsigned short index) return data; } -void XGINew_SetRegANDOR(unsigned long Port, unsigned short Index, +void xgifb_reg_and_or(unsigned long Port, unsigned short Index, unsigned short DataAND, unsigned short DataOR) { unsigned short temp; diff --git a/drivers/staging/xgifb/vb_util.h b/drivers/staging/xgifb/vb_util.h index 6bcdca84032f..e8e36a261b06 100644 --- a/drivers/staging/xgifb/vb_util.h +++ b/drivers/staging/xgifb/vb_util.h @@ -4,6 +4,6 @@ extern void xgifb_reg_set(unsigned long, unsigned short, unsigned short); extern unsigned char xgifb_reg_get(unsigned long, unsigned short); extern void xgifb_reg_or(unsigned long, unsigned short, unsigned short); extern void XGINew_SetRegAND(unsigned long Port,unsigned short Index,unsigned short DataAND); -extern void XGINew_SetRegANDOR(unsigned long Port,unsigned short Index,unsigned short DataAND,unsigned short DataOR); +extern void xgifb_reg_and_or(unsigned long, unsigned short, unsigned short, unsigned short); #endif -- cgit v1.2.3 From dc50556bbbee6a2ec642aac4c4c46364cca191b3 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:26 +0200 Subject: staging: xgifb: rename XGINew_SetRegAND() to xgifb_reg_and() Rename XGINew_SetRegAND() to xgifb_reg_and(). Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 4 +-- drivers/staging/xgifb/vb_setmode.c | 54 +++++++++++++++++++------------------- drivers/staging/xgifb/vb_util.c | 2 +- drivers/staging/xgifb/vb_util.h | 2 +- 4 files changed, 31 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 45491be70b01..61d137098aa1 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -69,7 +69,7 @@ static unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceE data = 1; /* DDRII */ return data; } else if (HwDeviceExtension->jChipType == XG21) { - XGINew_SetRegAND(pVBInfo->P3d4, 0xB4, ~0x02); /* Independent GPIO control */ + xgifb_reg_and(pVBInfo->P3d4, 0xB4, ~0x02); /* Independent GPIO control */ udelay(800); xgifb_reg_or(pVBInfo->P3d4, 0x4A, 0x80); /* Enable GPIOH read */ temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); /* GPIOF 0:DVI 1:DVO */ @@ -1211,7 +1211,7 @@ static void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension, xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0x80); /* TMDS on chip */ else xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* Only DVO on chip */ - XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); /* Disable read GPIOF */ + xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x20); /* Disable read GPIOF */ } #if 1 } diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 49791c47d8ee..8762a5327693 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -370,7 +370,7 @@ static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo) xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[1].SR2B); xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[1].SR2C); - XGINew_SetRegAND(pVBInfo->P3c4, 0x31, ~0x30); + xgifb_reg_and(pVBInfo->P3c4, 0x31, ~0x30); return 0; } @@ -964,8 +964,8 @@ static void XGI_SetXG21LCD(struct vb_device_info *pVBInfo, xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */ - XGINew_SetRegAND(pVBInfo->P3c4, 0x30, ~0x20); - XGINew_SetRegAND(pVBInfo->P3c4, 0x35, ~0x80); + xgifb_reg_and(pVBInfo->P3c4, 0x30, ~0x20); + xgifb_reg_and(pVBInfo->P3c4, 0x35, ~0x80); if (ModeNo <= 0x13) { b3CC = (unsigned char) inb(XGI_P3cc); @@ -1012,8 +1012,8 @@ static void XGI_SetXG27LCD(struct vb_device_info *pVBInfo, xgifb_reg_or(pVBInfo->P3c4, 0x1E, 0x01); /* Negative blank polarity */ - XGINew_SetRegAND(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */ - XGINew_SetRegAND(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */ + xgifb_reg_and(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */ + xgifb_reg_and(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */ if (ModeNo <= 0x13) { b3CC = (unsigned char) inb(XGI_P3cc); @@ -1041,7 +1041,7 @@ static void XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVB { int i, index = -1; - XGINew_SetRegAND(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */ + xgifb_reg_and(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */ if (ModeNo <= 0x13) { for (i = 0; i < 12; i++) { if (ModeNo == pVBInfo->UpdateCRT1[i].ModeID) @@ -4081,7 +4081,7 @@ static unsigned char XGI_XG21GetPSCValue(struct vb_device_info *pVBInfo) unsigned char CR4A, temp; CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); - XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x23); /* enable GPIO write */ + xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x23); /* enable GPIO write */ temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); @@ -4102,7 +4102,7 @@ static unsigned char XGI_XG27GetPSCValue(struct vb_device_info *pVBInfo) unsigned char CR4A, CRB4, temp; CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); - XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x0C); /* enable GPIO write */ + xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x0C); /* enable GPIO write */ temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); @@ -5662,10 +5662,10 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, tempax = (unsigned char) xgifb_reg_get(pVBInfo->Part2Port, 0x01); tempax--; - XGINew_SetRegAND(pVBInfo->Part2Port, 0x01, tempax); + xgifb_reg_and(pVBInfo->Part2Port, 0x01, tempax); /* if ( !( pVBInfo->VBType & VB_XGI301C ) ) */ - XGINew_SetRegAND(pVBInfo->Part2Port, 0x00, 0xEF); + xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xEF); } if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { @@ -5958,7 +5958,7 @@ static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo) return; #ifndef Tap4 - XGINew_SetRegAND(pVBInfo->Part2Port, 0x4E, 0xEB); /* Disable Tap4 */ + xgifb_reg_and(pVBInfo->Part2Port, 0x4E, 0xEB); /* Disable Tap4 */ #else /* Tap4 Setting */ Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */ @@ -6292,7 +6292,7 @@ void XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl, CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A); tempbh &= 0x23; tempbl &= 0x23; - XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */ + xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */ if (tempbh & 0x20) { temp = (tempbl >> 4) & 0x02; @@ -6335,7 +6335,7 @@ void XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl, tempbl &= 0x03; tempbh <<= 2; tempbl <<= 2; /* GPIOC,GPIOD */ - XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */ + xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~tempbh); /* enable GPIO write */ xgifb_reg_and_or(pVBInfo->P3d4, 0x48, ~tempbh, tempbl); } @@ -6941,7 +6941,7 @@ void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, } } - XGINew_SetRegAND(pVBInfo->Part4Port, 0x1F, tempah); /* disable part4_1f */ + xgifb_reg_and(pVBInfo->Part4Port, 0x1F, tempah); /* disable part4_1f */ if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) { if (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) @@ -6961,13 +6961,13 @@ void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, if (pVBInfo->VBInfo & SetCRT2ToLCDA) { if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo & SetCRT2ToLCDA)) - XGINew_SetRegAND(pVBInfo->Part1Port, 0x1e, 0xdf); /* Power down */ + xgifb_reg_and(pVBInfo->Part1Port, 0x1e, 0xdf); /* Power down */ } - XGINew_SetRegAND(pVBInfo->P3c4, 0x32, 0xdf); /* disable TV as primary VGA swap */ + xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xdf); /* disable TV as primary VGA swap */ if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge))) - XGINew_SetRegAND(pVBInfo->Part2Port, 0x00, 0xdf); + xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xdf); if ((pVBInfo->SetFlag & DisableChB) || (pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode)) @@ -6985,14 +6985,14 @@ void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, | SetCRT2ToLCD | SetCRT2ToTV))) { tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00); /* save Part1 index 0 */ xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x10); /* BTDAC = 1, avoid VB reset */ - XGINew_SetRegAND(pVBInfo->Part1Port, 0x1E, 0xDF); /* disable CRT2 */ + xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF); /* disable CRT2 */ xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah); /* restore Part1 index 0 */ } } else { /* {301} */ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) { xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */ - XGINew_SetRegAND(pVBInfo->Part1Port, 0x1E, 0xDF); /* Disable CRT2 */ - XGINew_SetRegAND(pVBInfo->P3c4, 0x32, 0xDF); /* Disable TV asPrimary VGA swap */ + xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF); /* Disable CRT2 */ + xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xDF); /* Disable TV asPrimary VGA swap */ } if (pVBInfo->VBInfo & (DisableCRT2Display | SetCRT2ToLCDA @@ -7209,7 +7209,7 @@ static void SetSpectrum(struct vb_device_info *pVBInfo) index = XGI_GetLCDCapPtr(pVBInfo); - XGINew_SetRegAND(pVBInfo->Part4Port, 0x30, 0x8F); /* disable down spectrum D[4] */ + xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x8F); /* disable down spectrum D[4] */ XGI_LongWait(pVBInfo); xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */ XGI_LongWait(pVBInfo); @@ -8085,7 +8085,7 @@ void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */ - XGINew_SetRegAND(pVBInfo->Part1Port, 0x00, 0x7F); /* BScreenOFF = 0 */ + xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F); /* BScreenOFF = 0 */ } } @@ -8099,11 +8099,11 @@ void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, || (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) - XGINew_SetRegAND( + xgifb_reg_and( pVBInfo->Part4Port, 0x2A, 0x7F); /* LVDS PLL power on */ } - XGINew_SetRegAND(pVBInfo->Part4Port, 0x30, 0x7F); /* LVDS Driver power on */ + xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x7F); /* LVDS Driver power on */ } } @@ -8166,7 +8166,7 @@ void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, if (!(tempah & 0x80)) xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */ - XGINew_SetRegAND(pVBInfo->Part1Port, 0x00, 0x7F); + xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F); XGI_DisplayOn(HwDeviceExtension, pVBInfo); } /* End of VB */ } @@ -8242,8 +8242,8 @@ static void XGI_SetCRT1Group(struct xgi_hw_device_info *HwDeviceExtension, temp = xgifb_reg_get(pVBInfo->P3d4, 0x38); if (temp & 0xA0) { - /* XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); *//* Enable write GPIOF */ - /* XGINew_SetRegAND(pVBInfo->P3d4, 0x48, ~0x20); *//* P. DWN */ + /* xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x20); *//* Enable write GPIOF */ + /* xgifb_reg_and(pVBInfo->P3d4, 0x48, ~0x20); *//* P. DWN */ /* XG21 CRT1 Timing */ if (HwDeviceExtension->jChipType == XG27) XGI_SetXG27CRTC(ModeNo, ModeIdIndex, diff --git a/drivers/staging/xgifb/vb_util.c b/drivers/staging/xgifb/vb_util.c index 9eb80600ac3c..d8429e836e85 100644 --- a/drivers/staging/xgifb/vb_util.c +++ b/drivers/staging/xgifb/vb_util.c @@ -34,7 +34,7 @@ void xgifb_reg_and_or(unsigned long Port, unsigned short Index, xgifb_reg_set(Port, Index, temp); } -void XGINew_SetRegAND(unsigned long Port, unsigned short Index, +void xgifb_reg_and(unsigned long Port, unsigned short Index, unsigned short DataAND) { unsigned short temp; diff --git a/drivers/staging/xgifb/vb_util.h b/drivers/staging/xgifb/vb_util.h index e8e36a261b06..98af1c0eaa42 100644 --- a/drivers/staging/xgifb/vb_util.h +++ b/drivers/staging/xgifb/vb_util.h @@ -3,7 +3,7 @@ extern void xgifb_reg_set(unsigned long, unsigned short, unsigned short); extern unsigned char xgifb_reg_get(unsigned long, unsigned short); extern void xgifb_reg_or(unsigned long, unsigned short, unsigned short); -extern void XGINew_SetRegAND(unsigned long Port,unsigned short Index,unsigned short DataAND); +extern void xgifb_reg_and(unsigned long, unsigned short, unsigned short); extern void xgifb_reg_and_or(unsigned long, unsigned short, unsigned short, unsigned short); #endif -- cgit v1.2.3 From d0e23bdf3a73b1aff1fe51a71d5e05d89465e2aa Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:27 +0200 Subject: staging: xgifb: clean up register access types Make type usage consistent. Use u8 for HW registers and unsigned for bitmasks. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_util.c | 23 ++++++++++------------- drivers/staging/xgifb/vb_util.h | 10 +++++----- 2 files changed, 15 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_util.c b/drivers/staging/xgifb/vb_util.c index d8429e836e85..19bcdab8debe 100644 --- a/drivers/staging/xgifb/vb_util.c +++ b/drivers/staging/xgifb/vb_util.c @@ -8,46 +8,43 @@ #include "vb_util.h" -void xgifb_reg_set(unsigned long port, unsigned short index, - unsigned short data) +void xgifb_reg_set(unsigned long port, u8 index, u8 data) { outb(index, port); outb(data, port + 1); } -unsigned char xgifb_reg_get(unsigned long port, unsigned short index) +u8 xgifb_reg_get(unsigned long port, u8 index) { - unsigned char data; + u8 data; outb(index, port); data = inb(port + 1); return data; } -void xgifb_reg_and_or(unsigned long Port, unsigned short Index, - unsigned short DataAND, unsigned short DataOR) +void xgifb_reg_and_or(unsigned long Port, u8 Index, + unsigned DataAND, unsigned DataOR) { - unsigned short temp; + u8 temp; temp = xgifb_reg_get(Port, Index); /* XGINew_Part1Port index 02 */ temp = (temp & (DataAND)) | DataOR; xgifb_reg_set(Port, Index, temp); } -void xgifb_reg_and(unsigned long Port, unsigned short Index, - unsigned short DataAND) +void xgifb_reg_and(unsigned long Port, u8 Index, unsigned DataAND) { - unsigned short temp; + u8 temp; temp = xgifb_reg_get(Port, Index); /* XGINew_Part1Port index 02 */ temp &= DataAND; xgifb_reg_set(Port, Index, temp); } -void xgifb_reg_or(unsigned long Port, unsigned short Index, - unsigned short DataOR) +void xgifb_reg_or(unsigned long Port, u8 Index, unsigned DataOR) { - unsigned short temp; + u8 temp; temp = xgifb_reg_get(Port, Index); /* XGINew_Part1Port index 02 */ temp |= DataOR; diff --git a/drivers/staging/xgifb/vb_util.h b/drivers/staging/xgifb/vb_util.h index 98af1c0eaa42..9161de1d37dd 100644 --- a/drivers/staging/xgifb/vb_util.h +++ b/drivers/staging/xgifb/vb_util.h @@ -1,9 +1,9 @@ #ifndef _VBUTIL_ #define _VBUTIL_ -extern void xgifb_reg_set(unsigned long, unsigned short, unsigned short); -extern unsigned char xgifb_reg_get(unsigned long, unsigned short); -extern void xgifb_reg_or(unsigned long, unsigned short, unsigned short); -extern void xgifb_reg_and(unsigned long, unsigned short, unsigned short); -extern void xgifb_reg_and_or(unsigned long, unsigned short, unsigned short, unsigned short); +extern void xgifb_reg_set(unsigned long, u8, u8); +extern u8 xgifb_reg_get(unsigned long, u8); +extern void xgifb_reg_or(unsigned long, u8, unsigned); +extern void xgifb_reg_and(unsigned long, u8, unsigned); +extern void xgifb_reg_and_or(unsigned long, u8, unsigned, unsigned); #endif -- cgit v1.2.3 From 459d2ea0b5547e55e22c5edff6760ab07c2b3fd1 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 13 Mar 2011 12:26:28 +0200 Subject: staging: xgifb: clean up register function variable names Eliminate mixed case from variable names. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_util.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/xgifb/vb_util.c b/drivers/staging/xgifb/vb_util.c index 19bcdab8debe..a97e44f98c08 100644 --- a/drivers/staging/xgifb/vb_util.c +++ b/drivers/staging/xgifb/vb_util.c @@ -23,30 +23,30 @@ u8 xgifb_reg_get(unsigned long port, u8 index) return data; } -void xgifb_reg_and_or(unsigned long Port, u8 Index, - unsigned DataAND, unsigned DataOR) +void xgifb_reg_and_or(unsigned long port, u8 index, + unsigned data_and, unsigned data_or) { u8 temp; - temp = xgifb_reg_get(Port, Index); /* XGINew_Part1Port index 02 */ - temp = (temp & (DataAND)) | DataOR; - xgifb_reg_set(Port, Index, temp); + temp = xgifb_reg_get(port, index); /* XGINew_Part1Port index 02 */ + temp = (temp & data_and) | data_or; + xgifb_reg_set(port, index, temp); } -void xgifb_reg_and(unsigned long Port, u8 Index, unsigned DataAND) +void xgifb_reg_and(unsigned long port, u8 index, unsigned data_and) { u8 temp; - temp = xgifb_reg_get(Port, Index); /* XGINew_Part1Port index 02 */ - temp &= DataAND; - xgifb_reg_set(Port, Index, temp); + temp = xgifb_reg_get(port, index); /* XGINew_Part1Port index 02 */ + temp &= data_and; + xgifb_reg_set(port, index, temp); } -void xgifb_reg_or(unsigned long Port, u8 Index, unsigned DataOR) +void xgifb_reg_or(unsigned long port, u8 index, unsigned data_or) { u8 temp; - temp = xgifb_reg_get(Port, Index); /* XGINew_Part1Port index 02 */ - temp |= DataOR; - xgifb_reg_set(Port, Index, temp); + temp = xgifb_reg_get(port, index); /* XGINew_Part1Port index 02 */ + temp |= data_or; + xgifb_reg_set(port, index, temp); } -- cgit v1.2.3 From 4dd53810912089380223c8fbddd83dcb642b6166 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:28:54 -0500 Subject: staging: ath6kl: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Acked-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 4 +--- drivers/staging/ath6kl/os/linux/ar6000_android.c | 4 +--- drivers/staging/ath6kl/os/linux/ar6k_pal.c | 6 ++---- drivers/staging/ath6kl/os/linux/hci_bridge.c | 6 ++---- 4 files changed, 6 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index b9f8c7206da6..8a1cedb9eea9 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -1214,9 +1214,7 @@ delHifDevice(HIF_DEVICE * device) { AR_DEBUG_ASSERT(device!= NULL); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: delHifDevice; 0x%p\n", device)); - if (device->dma_buffer != NULL) { - kfree(device->dma_buffer); - } + kfree(device->dma_buffer); kfree(device); } diff --git a/drivers/staging/ath6kl/os/linux/ar6000_android.c b/drivers/staging/ath6kl/os/linux/ar6000_android.c index f7d1069072b9..002cdc76c830 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_android.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_android.c @@ -120,9 +120,7 @@ int logger_write(const enum logidx index, } set_fs(oldfs); out_free_message: - if (msg) { - kfree(msg); - } + kfree(msg); return ret; } #endif diff --git a/drivers/staging/ath6kl/os/linux/ar6k_pal.c b/drivers/staging/ath6kl/os/linux/ar6k_pal.c index fee7cb945e24..8dd51ee0f72f 100644 --- a/drivers/staging/ath6kl/os/linux/ar6k_pal.c +++ b/drivers/staging/ath6kl/os/linux/ar6k_pal.c @@ -260,10 +260,8 @@ static void bt_cleanup_hci_pal(ar6k_hci_pal_info_t *pHciPalInfo) } } - if (pHciPalInfo->hdev != NULL) { - kfree(pHciPalInfo->hdev); - pHciPalInfo->hdev = NULL; - } + kfree(pHciPalInfo->hdev); + pHciPalInfo->hdev = NULL; } /********************************************************* diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index a02827bab8d9..327aab6f0109 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -929,10 +929,8 @@ static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo) } } - if (pHcidevInfo->pBtStackHCIDev != NULL) { - kfree(pHcidevInfo->pBtStackHCIDev); - pHcidevInfo->pBtStackHCIDev = NULL; - } + kfree(pHcidevInfo->pBtStackHCIDev); + pHcidevInfo->pBtStackHCIDev = NULL; } static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo) -- cgit v1.2.3 From 23c32986870b4abb5b426d3399a4cbd43948e37c Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:28:55 -0500 Subject: staging: bcm: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index 017b4717b25b..9be184f143e5 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -974,11 +974,7 @@ static VOID CopyToAdapter( register PMINI_ADAPTER Adapter, /**u8RequesttransmissionPolicy & MASK_DISABLE_HEADER_SUPPRESSION); - if(Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication) - { - kfree(Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication); - Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication = NULL; - } + kfree(Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication); Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication = pstAddIndication; //Re Sort the SF list in PackInfo according to Traffic Priority @@ -1971,10 +1967,7 @@ INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter) INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter) { - if(Adapter->caDsxReqResp) - { - kfree(Adapter->caDsxReqResp); - } + kfree(Adapter->caDsxReqResp); return 0; } -- cgit v1.2.3 From 46d994b1f5b481c7f0a77edece270cf253db84c9 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:28:56 -0500 Subject: staging: brcm80211: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_cdc.c | 3 +-- drivers/staging/brcm80211/brcmfmac/dhd_common.c | 9 +++----- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 3 +-- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 24 ++++++++-------------- .../staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c | 3 +-- drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c | 6 ++---- drivers/staging/brcm80211/brcmsmac/wl_mac80211.c | 9 +++----- drivers/staging/brcm80211/brcmsmac/wlc_main.c | 6 ++---- drivers/staging/brcm80211/util/bcmotp.c | 3 +-- drivers/staging/brcm80211/util/bcmsrom.c | 3 +-- drivers/staging/brcm80211/util/hnddma.c | 14 +++++-------- 11 files changed, 28 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c index 8398fa4c0340..39a4d001fbd0 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c @@ -415,8 +415,7 @@ int dhd_prot_attach(dhd_pub_t *dhd) return 0; fail: - if (cdc != NULL) - kfree(cdc); + kfree(cdc); return BCME_NOMEM; } diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index 64d88c20354e..aa171f6181e9 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -996,8 +996,7 @@ dhd_pktfilter_offload_enable(dhd_pub_t *dhd, char *arg, int enable, __func__, arg, rc)); fail: - if (arg_org) - kfree(arg_org); + kfree(arg_org); } void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg) @@ -1132,11 +1131,9 @@ void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg) __func__, arg)); fail: - if (arg_org) - kfree(arg_org); + kfree(arg_org); - if (buf) - kfree(buf); + kfree(buf); } void dhd_arp_offload_set(dhd_pub_t *dhd, int arp_mode) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index d473f64bc0df..02c6d446934c 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -1777,8 +1777,7 @@ done: bcmerror = -EFAULT; } - if (buf) - kfree(buf); + kfree(buf); if (bcmerror > 0) bcmerror = 0; diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index dd2e36749d0a..a6da7268d87a 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -1930,10 +1930,8 @@ static int dhdsdio_checkdied(dhd_bus_t *bus, u8 *data, uint size) #endif /* DHD_DEBUG */ done: - if (mbuffer) - kfree(mbuffer); - if (str) - kfree(str); + kfree(mbuffer); + kfree(str); return bcmerror; } @@ -1962,8 +1960,7 @@ static int dhdsdio_mem_dump(dhd_bus_t *bus) ret = dhdsdio_membytes(bus, false, start, databuf, read_size); if (ret) { DHD_ERROR(("%s: Error membytes %d\n", __func__, ret)); - if (buf) - kfree(buf); + kfree(buf); return -1; } printk("."); @@ -2081,8 +2078,7 @@ int dhdsdio_downloadvars(dhd_bus_t *bus, void *arg, int len) } /* Free the old ones and replace with passed variables */ - if (bus->vars) - kfree(bus->vars); + kfree(bus->vars); bus->vars = kmalloc(len, GFP_ATOMIC); bus->varsz = bus->vars ? len : 0; @@ -5541,10 +5537,8 @@ static void dhdsdio_release_malloc(dhd_bus_t *bus) bus->rxlen = 0; } - if (bus->databuf) { - kfree(bus->databuf); - bus->databuf = NULL; - } + kfree(bus->databuf); + bus->databuf = NULL; } static void dhdsdio_release_dongle(dhd_bus_t *bus) @@ -5732,8 +5726,7 @@ static int dhdsdio_download_code_file(struct dhd_bus *bus, char *fw_path) } err: - if (memblock) - kfree(memblock); + kfree(memblock); if (image) dhd_os_close_image(image); @@ -5872,8 +5865,7 @@ static int dhdsdio_download_nvram(struct dhd_bus *bus) } err: - if (memblock) - kfree(memblock); + kfree(memblock); if (image) dhd_os_close_image(image); diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c index fc810e342df8..8f75af2ffc58 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c @@ -759,8 +759,7 @@ wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, char *vars return &pi->pubpi_ro; err: - if (pi) - kfree(pi); + kfree(pi); return NULL; } diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c index a38587309ccc..7947c6028b6e 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c @@ -22383,8 +22383,7 @@ wlc_phy_gen_load_samples_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val, wlc_phy_loadsampletable_nphy(pi, tone_buf, num_samps); - if (tone_buf != NULL) - kfree(tone_buf); + kfree(tone_buf); return num_samps; } @@ -22431,8 +22430,7 @@ wlc_phy_loadsampletable_nphy(phy_info_t *pi, cs32 *tone_buf, wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SAMPLEPLAY, num_samps, 0, 32, data_buf); - if (data_buf != NULL) - kfree(data_buf); + kfree(data_buf); if (pi->phyhang_avoid) wlc_phy_stay_in_carriersearch_nphy(pi, false); diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c index a523b231cffe..66708d8df7f6 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c @@ -1379,8 +1379,7 @@ static void wl_free(struct wl_info *wl) for (t = wl->timers; t; t = next) { next = t->next; #ifdef BCMDBG - if (t->name) - kfree(t->name); + kfree(t->name); #endif kfree(t); } @@ -1716,8 +1715,7 @@ void wl_free_timer(struct wl_info *wl, struct wl_timer *t) if (wl->timers == t) { wl->timers = wl->timers->next; #ifdef BCMDBG - if (t->name) - kfree(t->name); + kfree(t->name); #endif kfree(t); return; @@ -1729,8 +1727,7 @@ void wl_free_timer(struct wl_info *wl, struct wl_timer *t) if (tmp->next == t) { tmp->next = t->next; #ifdef BCMDBG - if (t->name) - kfree(t->name); + kfree(t->name); #endif kfree(t); return; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c index 97b320da433a..0870dc913cda 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c @@ -2160,10 +2160,8 @@ uint wlc_detach(struct wlc_info *wlc) #ifdef BCMDBG - if (wlc->country_ie_override) { - kfree(wlc->country_ie_override); - wlc->country_ie_override = NULL; - } + kfree(wlc->country_ie_override); + wlc->country_ie_override = NULL; #endif /* BCMDBG */ { diff --git a/drivers/staging/brcm80211/util/bcmotp.c b/drivers/staging/brcm80211/util/bcmotp.c index b080345397f0..ba71c108b366 100644 --- a/drivers/staging/brcm80211/util/bcmotp.c +++ b/drivers/staging/brcm80211/util/bcmotp.c @@ -830,8 +830,7 @@ static int hndotp_nvread(void *oh, char *data, uint *len) *len = offset; out: - if (rawotp) - kfree(rawotp); + kfree(rawotp); si_setcoreidx(oi->sih, idx); return rc; diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index 7373603b6646..eca35b94e96c 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -1527,8 +1527,7 @@ static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz) memcpy(buf, otp, bufsz); - if (otp) - kfree(otp); + kfree(otp); /* Check CRC */ if (buf[0] == 0xffff) { diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 122f7d3fd704..8a81eb997f99 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -559,21 +559,17 @@ static void _dma_detach(dma_info_t *di) (di->rxdpaorig)); /* free packet pointer vectors */ - if (di->txp) - kfree((void *)di->txp); - if (di->rxp) - kfree((void *)di->rxp); + kfree(di->txp); + kfree(di->rxp); /* free tx packet DMA handles */ - if (di->txp_dmah) - kfree(di->txp_dmah); + kfree(di->txp_dmah); /* free rx packet DMA handles */ - if (di->rxp_dmah) - kfree(di->rxp_dmah); + kfree(di->rxp_dmah); /* free our private info structure */ - kfree((void *)di); + kfree(di); } -- cgit v1.2.3 From e4e1f289be88a75dc8b63d50ade1f9a2e6168021 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:28:57 -0500 Subject: staging: comedi: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 9 +-------- drivers/staging/comedi/drivers/das16.c | 6 ++---- drivers/staging/comedi/drivers/ni_at_a2150.c | 3 +-- drivers/staging/comedi/drivers/ni_labpc.c | 3 +-- drivers/staging/comedi/drivers/serial2002.c | 8 ++------ drivers/staging/comedi/drivers/usbdux.c | 8 ++------ 6 files changed, 9 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 95049a8d3b38..6c26ac887eee 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -383,14 +383,7 @@ EXPORT_SYMBOL(subdev_8255_init_irq); void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice *s) { - if (s->private) { - /* this test does nothing, so comment it out - * if (subdevpriv->have_irq) { - * } - */ - - kfree(s->private); - } + kfree(s->private); } EXPORT_SYMBOL(subdev_8255_cleanup); diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 0af1b4659088..e7905bac92da 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -1695,10 +1695,8 @@ static int das16_detach(struct comedi_device *dev) } if (devpriv->dma_chan) free_dma(devpriv->dma_chan); - if (devpriv->user_ai_range_table) - kfree(devpriv->user_ai_range_table); - if (devpriv->user_ao_range_table) - kfree(devpriv->user_ao_range_table); + kfree(devpriv->user_ai_range_table); + kfree(devpriv->user_ao_range_table); } if (dev->irq) diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index e46d62b75fc0..4d0053ea2465 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -479,8 +479,7 @@ static int a2150_detach(struct comedi_device *dev) if (devpriv) { if (devpriv->dma) free_dma(devpriv->dma); - if (devpriv->dma_buffer) - kfree(devpriv->dma_buffer); + kfree(devpriv->dma_buffer); } return 0; diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 0728c3c0cb0e..241fe525abf0 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -797,8 +797,7 @@ int labpc_common_detach(struct comedi_device *dev) subdev_8255_cleanup(dev, dev->subdevices + 2); /* only free stuff if it has been allocated by _attach */ - if (devpriv->dma_buffer) - kfree(devpriv->dma_buffer); + kfree(devpriv->dma_buffer); if (devpriv->dma_chan) free_dma(devpriv->dma_chan); if (dev->irq) diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index c9be9e05f028..ebfce33f0b4f 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -907,12 +907,8 @@ static int serial2002_detach(struct comedi_device *dev) printk("comedi%d: serial2002: remove\n", dev->minor); for (i = 0; i < 5; i++) { s = &dev->subdevices[i]; - if (s->maxdata_list) { - kfree(s->maxdata_list); - } - if (s->range_table_list) { - kfree(s->range_table_list); - } + kfree(s->maxdata_list); + kfree(s->range_table_list); } return 0; } diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 696ee045e25f..be93c30e4b15 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -2265,12 +2265,8 @@ static void tidy_up(struct usbduxsub *usbduxsub_tmp) usbduxsub_unlink_OutURBs(usbduxsub_tmp); } for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) { - if (usbduxsub_tmp->urbOut[i]->transfer_buffer) { - kfree(usbduxsub_tmp-> - urbOut[i]->transfer_buffer); - usbduxsub_tmp->urbOut[i]->transfer_buffer = - NULL; - } + kfree(usbduxsub_tmp->urbOut[i]->transfer_buffer); + usbduxsub_tmp->urbOut[i]->transfer_buffer = NULL; if (usbduxsub_tmp->urbOut[i]) { usb_kill_urb(usbduxsub_tmp->urbOut[i]); usb_free_urb(usbduxsub_tmp->urbOut[i]); -- cgit v1.2.3 From b00917802bda6eba09125e8b4d273339188f9bad Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:28:58 -0500 Subject: staging: cx25821: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/cx25821/cx25821-audio-upstream.c | 9 +++------ drivers/staging/cx25821/cx25821-video-upstream-ch2.c | 9 +++------ drivers/staging/cx25821/cx25821-video-upstream.c | 9 +++------ 3 files changed, 9 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.c b/drivers/staging/cx25821/cx25821-audio-upstream.c index 7992a3ba526f..0f9ca777bd4d 100644 --- a/drivers/staging/cx25821/cx25821-audio-upstream.c +++ b/drivers/staging/cx25821/cx25821-audio-upstream.c @@ -244,13 +244,10 @@ void cx25821_stop_upstream_audio(struct cx25821_dev *dev) dev->_audioframe_count = 0; dev->_audiofile_status = END_OF_FILE; - if (dev->_irq_audio_queues) { - kfree(dev->_irq_audio_queues); - dev->_irq_audio_queues = NULL; - } + kfree(dev->_irq_audio_queues); + dev->_irq_audio_queues = NULL; - if (dev->_audiofilename != NULL) - kfree(dev->_audiofilename); + kfree(dev->_audiofilename); } void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev) diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c index e2efacdfb874..655357da3d6a 100644 --- a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c +++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c @@ -234,13 +234,10 @@ void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev) dev->_frame_count_ch2 = 0; dev->_file_status_ch2 = END_OF_FILE; - if (dev->_irq_queues_ch2) { - kfree(dev->_irq_queues_ch2); - dev->_irq_queues_ch2 = NULL; - } + kfree(dev->_irq_queues_ch2); + dev->_irq_queues_ch2 = NULL; - if (dev->_filename_ch2 != NULL) - kfree(dev->_filename_ch2); + kfree(dev->_filename_ch2); tmp = cx_read(VID_CH_MODE_SEL); cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00); diff --git a/drivers/staging/cx25821/cx25821-video-upstream.c b/drivers/staging/cx25821/cx25821-video-upstream.c index 31b4e3c74c8d..eb0172bf39d1 100644 --- a/drivers/staging/cx25821/cx25821-video-upstream.c +++ b/drivers/staging/cx25821/cx25821-video-upstream.c @@ -279,13 +279,10 @@ void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev) dev->_frame_count = 0; dev->_file_status = END_OF_FILE; - if (dev->_irq_queues) { - kfree(dev->_irq_queues); - dev->_irq_queues = NULL; - } + kfree(dev->_irq_queues); + dev->_irq_queues = NULL; - if (dev->_filename != NULL) - kfree(dev->_filename); + kfree(dev->_filename); tmp = cx_read(VID_CH_MODE_SEL); cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00); -- cgit v1.2.3 From 56d17639703b4683e3e9be36dff7c6d811f4cbf5 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:28:59 -0500 Subject: staging: go7007: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/go7007/go7007-usb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/go7007/go7007-usb.c b/drivers/staging/go7007/go7007-usb.c index bea9f4d5bc3c..3db3b0a91cc1 100644 --- a/drivers/staging/go7007/go7007-usb.c +++ b/drivers/staging/go7007/go7007-usb.c @@ -1247,15 +1247,13 @@ static void go7007_usb_disconnect(struct usb_interface *intf) vurb = usb->video_urbs[i]; if (vurb) { usb_kill_urb(vurb); - if (vurb->transfer_buffer) - kfree(vurb->transfer_buffer); + kfree(vurb->transfer_buffer); usb_free_urb(vurb); } aurb = usb->audio_urbs[i]; if (aurb) { usb_kill_urb(aurb); - if (aurb->transfer_buffer) - kfree(aurb->transfer_buffer); + kfree(aurb->transfer_buffer); usb_free_urb(aurb); } } -- cgit v1.2.3 From 306be9e1c167dcd7d6635bd434ee8e63ab22a5d6 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:29:01 -0500 Subject: staging: keucr: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/keucr/ms.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/keucr/ms.c b/drivers/staging/keucr/ms.c index 48496e4da42b..a7137217cf86 100644 --- a/drivers/staging/keucr/ms.c +++ b/drivers/staging/keucr/ms.c @@ -244,8 +244,8 @@ int MS_CardInit(struct us_data *us) result = MS_STATUS_SUCCESS; exit: - if (PageBuffer1) kfree(PageBuffer1); - if (PageBuffer0) kfree(PageBuffer0); + kfree(PageBuffer1); + kfree(PageBuffer0); printk("MS_CardInit end\n"); return result; @@ -280,7 +280,7 @@ int MS_LibCheckDisableBlock(struct us_data *us, WORD PhyBlock) } while(1); exit: - if (PageBuf) kfree(PageBuf); + kfree(PageBuf); return result; } @@ -324,17 +324,11 @@ void MS_LibFreeWriteBuf(struct us_data *us) //----- MS_LibFreeLogicalMap() --------------------------------------- int MS_LibFreeLogicalMap(struct us_data *us) { - if (us->MS_Lib.Phy2LogMap) - { - kfree(us->MS_Lib.Phy2LogMap); - us->MS_Lib.Phy2LogMap = NULL; - } + kfree(us->MS_Lib.Phy2LogMap); + us->MS_Lib.Phy2LogMap = NULL; - if (us->MS_Lib.Log2PhyMap) - { - kfree(us->MS_Lib.Log2PhyMap); - us->MS_Lib.Log2PhyMap = NULL; - } + kfree(us->MS_Lib.Log2PhyMap); + us->MS_Lib.Log2PhyMap = NULL; return 0; } @@ -470,7 +464,7 @@ int MS_LibProcessBootBlock(struct us_data *us, WORD PhyBlock, BYTE *PageData) exit: if (result) MS_LibFreeLogicalMap(us); - if (PageBuffer) kfree(PageBuffer); + kfree(PageBuffer); result = 0; return result; -- cgit v1.2.3 From 43c04d42c3c5a23e2aff330d4d361c733118df80 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:29:02 -0500 Subject: staging: line6: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/pcm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c index b9c55f9eb501..9d4c8a606eea 100644 --- a/drivers/staging/line6/pcm.c +++ b/drivers/staging/line6/pcm.c @@ -189,8 +189,7 @@ int line6_pcm_stop(struct snd_line6_pcm *line6pcm, int channels) line6pcm->buffer_out = NULL; } #if LINE6_BACKUP_MONITOR_SIGNAL - if (line6pcm->prev_fbuf != NULL) - kfree(line6pcm->prev_fbuf); + kfree(line6pcm->prev_fbuf); #endif return 0; -- cgit v1.2.3 From 14910178fcdcca53230afd4155a6c48e230b2919 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:29:03 -0500 Subject: staging: pohmelfs: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/pohmelfs/config.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c index ed913306e5d6..a9a3e25a7efa 100644 --- a/drivers/staging/pohmelfs/config.c +++ b/drivers/staging/pohmelfs/config.c @@ -601,11 +601,9 @@ void pohmelfs_config_exit(void) list_del(&g->group_entry); - if (g->hash_string) - kfree(g->hash_string); + kfree(g->hash_string); - if (g->cipher_string) - kfree(g->cipher_string); + kfree(g->cipher_string); kfree(g); } -- cgit v1.2.3 From aea9d72f97218d45e993836bcb6c6e6fd49e0b90 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:29:04 -0500 Subject: staging: rt2860: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/common/spectrum.c | 6 ++---- drivers/staging/rt2860/rt_linux.c | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/common/spectrum.c b/drivers/staging/rt2860/common/spectrum.c index 1dfb802aab9a..c0d2f428069c 100644 --- a/drivers/staging/rt2860/common/spectrum.c +++ b/drivers/staging/rt2860/common/spectrum.c @@ -416,8 +416,7 @@ void MeasureReqTabExit(struct rt_rtmp_adapter *pAd) { NdisFreeSpinLock(&pAd->CommonCfg.MeasureReqTabLock); - if (pAd->CommonCfg.pMeasureReqTab) - kfree(pAd->CommonCfg.pMeasureReqTab); + kfree(pAd->CommonCfg.pMeasureReqTab); pAd->CommonCfg.pMeasureReqTab = NULL; return; @@ -614,8 +613,7 @@ void TpcReqTabExit(struct rt_rtmp_adapter *pAd) { NdisFreeSpinLock(&pAd->CommonCfg.TpcReqTabLock); - if (pAd->CommonCfg.pTpcReqTab) - kfree(pAd->CommonCfg.pTpcReqTab); + kfree(pAd->CommonCfg.pTpcReqTab); pAd->CommonCfg.pTpcReqTab = NULL; return; diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c index b3f836de332b..e5b042712430 100644 --- a/drivers/staging/rt2860/rt_linux.c +++ b/drivers/staging/rt2860/rt_linux.c @@ -241,8 +241,7 @@ void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd) os_cookie = (struct os_cookie *)pAd->OS_Cookie; - if (pAd->BeaconBuf) - kfree(pAd->BeaconBuf); + kfree(pAd->BeaconBuf); NdisFreeSpinLock(&pAd->MgmtRingLock); @@ -264,8 +263,7 @@ void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd) release_firmware(pAd->firmware); vfree(pAd); /* pci_free_consistent(os_cookie->pci_dev,sizeof(struct rt_rtmp_adapter),pAd,os_cookie->pAd_pa); */ - if (os_cookie) - kfree(os_cookie); + kfree(os_cookie); } BOOLEAN OS_Need_Clone_Packet(void) -- cgit v1.2.3 From 76be349c0045073bbed4f669f87e36b1d8fda256 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:29:05 -0500 Subject: staging: rtl8187se: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c | 3 +-- drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index 74a3b4c211ad..771e0196842e 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -2605,8 +2605,7 @@ void ieee80211_softmac_free(struct ieee80211_device *ieee) cancel_delayed_work(&ieee->GPIOChangeRFWorkItem); destroy_workqueue(ieee->wq); - if(NULL != ieee->pDot11dInfo) - kfree(ieee->pDot11dInfo); + kfree(ieee->pDot11dInfo); up(&ieee->wx_sem); } diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c index 07d8dbcdca28..ca414a915a4e 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c @@ -735,7 +735,6 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len) ieee->wpa_ie_len = len; } else{ - if (ieee->wpa_ie) kfree(ieee->wpa_ie); ieee->wpa_ie = NULL; ieee->wpa_ie_len = 0; -- cgit v1.2.3 From 7e901dcd73d73230ad0e66e35fb6f1da244e41f7 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:29:06 -0500 Subject: staging: rtl8192e: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211_module.c | 7 ++----- drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c | 7 ++----- drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c | 7 ++----- drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c | 1 - 4 files changed, 6 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c index 67bcd41e66b1..663b0b8e1095 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c @@ -195,11 +195,8 @@ void free_ieee80211(struct net_device *dev) { struct ieee80211_device *ieee = netdev_priv(dev); int i; - if (ieee->pHTInfo != NULL) - { - kfree(ieee->pHTInfo); - ieee->pHTInfo = NULL; - } + kfree(ieee->pHTInfo); + ieee->pHTInfo = NULL; RemoveAllTS(ieee); ieee80211_softmac_free(ieee); del_timer_sync(&ieee->crypt_deinit_timer); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c index e2eac7cadf4f..57acb3f21adf 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c @@ -1411,11 +1411,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, return 1; rx_dropped: - if (rxb != NULL) - { - kfree(rxb); - rxb = NULL; - } + kfree(rxb); + rxb = NULL; stats->rx_dropped++; /* Returning 0 indicates to caller that we have not handled the SKB-- diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index fc96676bb9ce..8d73a7313766 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -2818,11 +2818,8 @@ void ieee80211_softmac_free(struct ieee80211_device *ieee) { down(&ieee->wx_sem); #ifdef ENABLE_DOT11D - if(NULL != ieee->pDot11dInfo) - { - kfree(ieee->pDot11dInfo); - ieee->pDot11dInfo = NULL; - } + kfree(ieee->pDot11dInfo); + ieee->pDot11dInfo = NULL; #endif del_timer_sync(&ieee->associate_timer); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c index cac340e5238a..bb0ff26bd843 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c @@ -862,7 +862,6 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len) ieee->wpa_ie_len = len; } else{ - if (ieee->wpa_ie) kfree(ieee->wpa_ie); ieee->wpa_ie = NULL; ieee->wpa_ie_len = 0; -- cgit v1.2.3 From e72714fb20b2bac88e6bc06401a124243791ca08 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:29:07 -0500 Subject: staging: rtl8192u: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/cipher.c | 3 +- .../staging/rtl8192u/ieee80211/ieee80211_module.c | 7 ++-- drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c | 7 ++-- .../staging/rtl8192u/ieee80211/ieee80211_softmac.c | 7 ++-- drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c | 1 - drivers/staging/rtl8192u/r8192U_core.c | 39 +++++++--------------- 6 files changed, 19 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192u/ieee80211/cipher.c b/drivers/staging/rtl8192u/ieee80211/cipher.c index 0b9e8a4ae7b5..69dcc3176ebc 100644 --- a/drivers/staging/rtl8192u/ieee80211/cipher.c +++ b/drivers/staging/rtl8192u/ieee80211/cipher.c @@ -294,6 +294,5 @@ out: void crypto_exit_cipher_ops(struct crypto_tfm *tfm) { - if (tfm->crt_cipher.cit_iv) - kfree(tfm->crt_cipher.cit_iv); + kfree(tfm->crt_cipher.cit_iv); } diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c index 7455264aa543..fe978f359f91 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c @@ -198,11 +198,8 @@ void free_ieee80211(struct net_device *dev) int i; //struct list_head *p, *q; // del_timer_sync(&ieee->SwBwTimer); - if (ieee->pHTInfo != NULL) - { - kfree(ieee->pHTInfo); - ieee->pHTInfo = NULL; - } + kfree(ieee->pHTInfo); + ieee->pHTInfo = NULL; RemoveAllTS(ieee); ieee80211_softmac_free(ieee); del_timer_sync(&ieee->crypt_deinit_timer); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index 1ea8da3655ec..498b520efcf4 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -1384,11 +1384,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, return 1; rx_dropped: - if (rxb != NULL) - { - kfree(rxb); - rxb = NULL; - } + kfree(rxb); + rxb = NULL; stats->rx_dropped++; /* Returning 0 indicates to caller that we have not handled the SKB-- diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index 20f8c347cae4..4992d630f984 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -2755,11 +2755,8 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee) void ieee80211_softmac_free(struct ieee80211_device *ieee) { down(&ieee->wx_sem); - if(NULL != ieee->pDot11dInfo) - { - kfree(ieee->pDot11dInfo); - ieee->pDot11dInfo = NULL; - } + kfree(ieee->pDot11dInfo); + ieee->pDot11dInfo = NULL; del_timer_sync(&ieee->associate_timer); cancel_delayed_work(&ieee->associate_retry_wq); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c index d6f55c290dbe..f0ba7f467493 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c @@ -855,7 +855,6 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len) ieee->wpa_ie_len = len; } else{ - if (ieee->wpa_ie) kfree(ieee->wpa_ie); ieee->wpa_ie = NULL; ieee->wpa_ie_len = 0; diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index ae4f2b9d9e8f..da612e6d994e 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -2242,12 +2242,8 @@ short rtl8192_usb_initendpoints(struct net_device *dev) destroy: - if (priv->pp_rxskb) { - kfree(priv->pp_rxskb); - } - if (priv->rx_urb) { - kfree(priv->rx_urb); - } + kfree(priv->pp_rxskb); + kfree(priv->rx_urb); priv->pp_rxskb = NULL; priv->rx_urb = NULL; @@ -2276,10 +2272,8 @@ void rtl8192_usb_deleteendpoints(struct net_device *dev) kfree(priv->rx_urb); priv->rx_urb = NULL; } - if(priv->oldaddr){ - kfree(priv->oldaddr); - priv->oldaddr = NULL; - } + kfree(priv->oldaddr); + priv->oldaddr = NULL; if (priv->pp_rxskb) { kfree(priv->pp_rxskb); priv->pp_rxskb = 0; @@ -2304,14 +2298,10 @@ void rtl8192_usb_deleteendpoints(struct net_device *dev) } #else - if(priv->rx_urb){ - kfree(priv->rx_urb); - priv->rx_urb = NULL; - } - if(priv->oldaddr){ - kfree(priv->oldaddr); - priv->oldaddr = NULL; - } + kfree(priv->rx_urb); + priv->rx_urb = NULL; + kfree(priv->oldaddr); + priv->oldaddr = NULL; if (priv->pp_rxskb) { kfree(priv->pp_rxskb); priv->pp_rxskb = 0; @@ -5828,10 +5818,8 @@ static int __devinit rtl8192_usb_probe(struct usb_interface *intf, fail2: rtl8192_down(dev); - if (priv->pFirmware) { - kfree(priv->pFirmware); - priv->pFirmware = NULL; - } + kfree(priv->pFirmware); + priv->pFirmware = NULL; rtl8192_usb_deleteendpoints(dev); destroy_workqueue(priv->priv_wq); mdelay(10); @@ -5869,11 +5857,8 @@ static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf) rtl8192_proc_remove_one(dev); rtl8192_down(dev); - if (priv->pFirmware) - { - kfree(priv->pFirmware); - priv->pFirmware = NULL; - } + kfree(priv->pFirmware); + priv->pFirmware = NULL; // priv->rf_close(dev); // rtl8192_SetRFPowerState(dev, eRfOff); rtl8192_usb_deleteendpoints(dev); -- cgit v1.2.3 From b7977fa250c1732d1fc1b5832f257655fd7471a4 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:29:08 -0500 Subject: staging: rtl8712: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_ioctl_linux.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index 8ebfdd620ba4..bd315c77610a 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -1873,8 +1873,7 @@ static int r871x_mp_ioctl_hdl(struct net_device *dev, goto _r871x_mp_ioctl_hdl_exit; } _r871x_mp_ioctl_hdl_exit: - if (pparmbuf != NULL) - kfree(pparmbuf); + kfree(pparmbuf); return ret; } -- cgit v1.2.3 From ef055f10000c5013d269cac9fc92c200bf314e40 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:29:09 -0500 Subject: staging: serqt_usb2: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/serqt_usb2/serqt_usb2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 27841ef6a568..2be2d889d443 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -1098,8 +1098,7 @@ static void qt_close(struct usb_serial_port *port) if (qt_port->write_urb) { /* if this urb had a transfer buffer already (old tx) free it */ - if (qt_port->write_urb->transfer_buffer != NULL) - kfree(qt_port->write_urb->transfer_buffer); + kfree(qt_port->write_urb->transfer_buffer); usb_free_urb(qt_port->write_urb); } -- cgit v1.2.3 From 39dd3e5d7b09b5a5010ed1aef512f2d58b65cb99 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:29:10 -0500 Subject: staging: speakup: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index cd981a13c12d..42fcf7e9cb64 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -1305,10 +1305,8 @@ void speakup_deallocate(struct vc_data *vc) int vc_num; vc_num = vc->vc_num; - if (speakup_console[vc_num] != NULL) { - kfree(speakup_console[vc_num]); - speakup_console[vc_num] = NULL; - } + kfree(speakup_console[vc_num]); + speakup_console[vc_num] = NULL; } static u_char is_cursor; -- cgit v1.2.3 From 9f7ff701ad7b7bdcab949aa0527fe7efb3882afa Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:29:11 -0500 Subject: staging: tidspbridge: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tidspbridge/core/chnl_sm.c | 3 +-- drivers/staging/tidspbridge/pmgr/dbll.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c index 3c05d7cb9c94..8381130e1460 100644 --- a/drivers/staging/tidspbridge/core/chnl_sm.c +++ b/drivers/staging/tidspbridge/core/chnl_sm.c @@ -828,8 +828,7 @@ out_err: free_chirp_list(&pchnl->io_requests); free_chirp_list(&pchnl->free_packets_list); - if (sync_event) - kfree(sync_event); + kfree(sync_event); if (pchnl->ntfy_obj) { ntfy_delete(pchnl->ntfy_obj); diff --git a/drivers/staging/tidspbridge/pmgr/dbll.c b/drivers/staging/tidspbridge/pmgr/dbll.c index 2e20f78e2c31..31da62b14bc9 100644 --- a/drivers/staging/tidspbridge/pmgr/dbll.c +++ b/drivers/staging/tidspbridge/pmgr/dbll.c @@ -272,8 +272,7 @@ void dbll_delete(struct dbll_tar_obj *target) DBC_REQUIRE(refs > 0); DBC_REQUIRE(zl_target); - if (zl_target != NULL) - kfree(zl_target); + kfree(zl_target); } -- cgit v1.2.3 From 06dde506203147e8d245a505d491c40254561f17 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:29:12 -0500 Subject: staging: usbip: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/stub_main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/stub_main.c b/drivers/staging/usbip/stub_main.c index f3a40968aae2..076a7e531098 100644 --- a/drivers/staging/usbip/stub_main.c +++ b/drivers/staging/usbip/stub_main.c @@ -264,11 +264,9 @@ void stub_device_cleanup_urbs(struct stub_device *sdev) kmem_cache_free(stub_priv_cache, priv); - if (urb->transfer_buffer != NULL) - kfree(urb->transfer_buffer); + kfree(urb->transfer_buffer); - if (urb->setup_packet != NULL) - kfree(urb->setup_packet); + kfree(urb->setup_packet); usb_free_urb(urb); } -- cgit v1.2.3 From 794a8946ba2339af09dd1f39c8462c3611bebf77 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:29:13 -0500 Subject: staging: vme: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/bridges/vme_ca91cx42.c | 3 +-- drivers/staging/vme/bridges/vme_tsi148.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c index 5d734d9ed27d..d4a48c4e59c2 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ b/drivers/staging/vme/bridges/vme_ca91cx42.c @@ -516,8 +516,7 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image, if (existing_size != 0) { iounmap(image->kern_base); image->kern_base = NULL; - if (image->bus_resource.name != NULL) - kfree(image->bus_resource.name); + kfree(image->bus_resource.name); release_resource(&image->bus_resource); memset(&image->bus_resource, 0, sizeof(struct resource)); } diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index 2df19eacbca5..b00a53e793e7 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -821,8 +821,7 @@ static int tsi148_alloc_resource(struct vme_master_resource *image, if (existing_size != 0) { iounmap(image->kern_base); image->kern_base = NULL; - if (image->bus_resource.name != NULL) - kfree(image->bus_resource.name); + kfree(image->bus_resource.name); release_resource(&image->bus_resource); memset(&image->bus_resource, 0, sizeof(struct resource)); } -- cgit v1.2.3 From 6403bb7dc1f6d77a93850935d9277a0d74783cf0 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:29:14 -0500 Subject: staging: vt6655: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 3 +-- drivers/staging/vt6655/hostap.c | 3 +-- drivers/staging/vt6655/wpactl.c | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 638e3916774d..efaf19bc07b7 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -3064,8 +3064,7 @@ else { } error1: - if(buffer) - kfree(buffer); + kfree(buffer); if(filp_close(filp,NULL)) printk("Config_FileOperation:close file fail\n"); diff --git a/drivers/staging/vt6655/hostap.c b/drivers/staging/vt6655/hostap.c index 5b83f942cdab..773502702203 100644 --- a/drivers/staging/vt6655/hostap.c +++ b/drivers/staging/vt6655/hostap.c @@ -860,8 +860,7 @@ int vt6655_hostap_ioctl(PSDevice pDevice, struct iw_point *p) } out: - if (param != NULL) - kfree(param); + kfree(param); return ret; } diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c index 4bdb8362de82..fbae16de27a7 100644 --- a/drivers/staging/vt6655/wpactl.c +++ b/drivers/staging/vt6655/wpactl.c @@ -987,8 +987,7 @@ int wpa_ioctl(PSDevice pDevice, struct iw_point *p) } out: - if (param != NULL) - kfree(param); + kfree(param); return ret; } -- cgit v1.2.3 From 1d5c536efeb9c109e330209867ae1242d42cdb7b Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:29:15 -0500 Subject: staging: vt6656: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/firmware.c | 3 +-- drivers/staging/vt6656/hostap.c | 3 +-- drivers/staging/vt6656/main_usb.c | 12 ++++-------- drivers/staging/vt6656/wpactl.c | 3 +-- 4 files changed, 7 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c index 162541255a02..8c8126a3540b 100644 --- a/drivers/staging/vt6656/firmware.c +++ b/drivers/staging/vt6656/firmware.c @@ -109,8 +109,7 @@ FIRMWAREbDownload( result = TRUE; out: - if (pBuffer) - kfree(pBuffer); + kfree(pBuffer); spin_lock_irq(&pDevice->lock); return result; diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c index f70e922a615b..51b5adf36577 100644 --- a/drivers/staging/vt6656/hostap.c +++ b/drivers/staging/vt6656/hostap.c @@ -858,8 +858,7 @@ int vt6656_hostap_ioctl(PSDevice pDevice, struct iw_point *p) } out: - if (param != NULL) - kfree(param); + kfree(param); return ret; } diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 37d639602c8b..af14ab01ed7b 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -837,8 +837,7 @@ static void device_free_tx_bufs(PSDevice pDevice) usb_kill_urb(pTxContext->pUrb); usb_free_urb(pTxContext->pUrb); } - if (pTxContext) - kfree(pTxContext); + kfree(pTxContext); } return; } @@ -861,8 +860,7 @@ static void device_free_rx_bufs(PSDevice pDevice) if (pRCB->skb) dev_kfree_skb(pRCB->skb); } - if (pDevice->pRCBMem) - kfree(pDevice->pRCBMem); + kfree(pDevice->pRCBMem); return; } @@ -878,8 +876,7 @@ static void usb_device_reset(PSDevice pDevice) static void device_free_int_bufs(PSDevice pDevice) { - if (pDevice->intBuf.pDataBuf != NULL) - kfree(pDevice->intBuf.pDataBuf); + kfree(pDevice->intBuf.pDataBuf); return; } @@ -1480,8 +1477,7 @@ error2: */ if(result!=0) { - if(buffer) - kfree(buffer); + kfree(buffer); buffer=NULL; } return buffer; diff --git a/drivers/staging/vt6656/wpactl.c b/drivers/staging/vt6656/wpactl.c index 7fd300f2e7c3..8752736181bb 100644 --- a/drivers/staging/vt6656/wpactl.c +++ b/drivers/staging/vt6656/wpactl.c @@ -999,8 +999,7 @@ int wpa_ioctl(PSDevice pDevice, struct iw_point *p) } out: - if (param != NULL) - kfree(param); + kfree(param); return ret; } -- cgit v1.2.3 From 4d527a7adbc47bdc357ddab513861e6a7636755e Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:29:16 -0500 Subject: staging: winbond: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wb35reg.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/wb35reg.c b/drivers/staging/winbond/wb35reg.c index 42ae61014522..da595f16f634 100644 --- a/drivers/staging/winbond/wb35reg.c +++ b/drivers/staging/winbond/wb35reg.c @@ -66,8 +66,7 @@ unsigned char Wb35Reg_BurstWrite(struct hw_data *pHwData, u16 RegisterNo, u32 *p } else { if (urb) usb_free_urb(urb); - if (reg_queue) - kfree(reg_queue); + kfree(reg_queue); return false; } return false; -- cgit v1.2.3 From a6f9c48fdd566e09d437e104c5b5963133db1be4 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:29:17 -0500 Subject: staging: wlan-ng: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/hfa384x_usb.c | 6 ++---- drivers/staging/wlan-ng/prism2fw.c | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index a6efc033fe10..7843dfdaa3cf 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -612,10 +612,8 @@ void hfa384x_destroy(hfa384x_t *hw) hfa384x_drvr_stop(hw); hw->state = HFA384x_STATE_PREINIT; - if (hw->scanresults) { - kfree(hw->scanresults); - hw->scanresults = NULL; - } + kfree(hw->scanresults); + hw->scanresults = NULL; /* Now to clean out the auth queue */ while ((skb = skb_dequeue(&hw->authq))) diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index fd5ddb29436c..729d03d28d75 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -443,8 +443,7 @@ void free_chunks(struct imgchunk *fchunk, unsigned int *nfchunks) { int i; for (i = 0; i < *nfchunks; i++) { - if (fchunk[i].data != NULL) - kfree(fchunk[i].data); + kfree(fchunk[i].data); } *nfchunks = 0; memset(fchunk, 0, sizeof(*fchunk)); -- cgit v1.2.3 From 01eb1da1aad93a36ab1254fc2d337ed0f6783156 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:35 -0700 Subject: ath6kl: remove-tyepdef DL_LIST and PDL_LIST pointer This required two passes: remove-typedef -s DL_LIST "struct dl_list" \ drivers/staging/ath6kl/ remove-typedef -s PDL_LIST "struct dl_list *" \ drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- .../hif/sdio/linux_sdio/include/hif_internal.h | 2 +- .../ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c | 2 +- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 2 +- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 2 +- drivers/staging/ath6kl/include/dl_list.h | 26 +++++++++++----------- drivers/staging/ath6kl/include/hif.h | 2 +- drivers/staging/ath6kl/include/htc_packet.h | 8 +++---- 7 files changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h index 87057e35edd1..b5d1ad430ff2 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h @@ -77,7 +77,7 @@ struct hif_device { void *claimedContext; HTC_CALLBACKS htcCallbacks; u8 *dma_buffer; - DL_LIST ScatterReqHead; /* scatter request list head */ + struct dl_list ScatterReqHead; /* scatter request list head */ bool scatter_enabled; /* scatter enabled flag */ bool is_suspend; bool is_disabled; diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c index 78cbbb11ed61..2a56a50bc211 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c @@ -62,7 +62,7 @@ static void FreeScatterReq(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq) static HIF_SCATTER_REQ *AllocScatterReq(HIF_DEVICE *device) { - DL_LIST *pItem; + struct dl_list *pItem; unsigned long flag; spin_lock_irqsave(&device->lock, flag); diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index a41ed12043d6..f9f411ae43b3 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -589,7 +589,7 @@ void DevDumpRegisters(struct ar6k_device *pDev, static HIF_SCATTER_REQ *DevAllocScatterReq(HIF_DEVICE *Context) { - DL_LIST *pItem; + struct dl_list *pItem; struct ar6k_device *pDev = (struct ar6k_device *)Context; LOCK_AR6K(pDev); pItem = DL_ListRemoveItemFromHead(&pDev->ScatterReqHead); diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index 3e4ece865be9..88ef25a1abcd 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -133,7 +133,7 @@ struct ar6k_device { bool DSRCanYield; int CurrentDSRRecvCount; HIF_DEVICE_SCATTER_SUPPORT_INFO HifScatterInfo; - DL_LIST ScatterReqHead; + struct dl_list ScatterReqHead; bool ScatterIsVirtual; int MaxRecvBundleSize; int MaxSendBundleSize; diff --git a/drivers/staging/ath6kl/include/dl_list.h b/drivers/staging/ath6kl/include/dl_list.h index 110e1d8b047d..13b1e6956c22 100644 --- a/drivers/staging/ath6kl/include/dl_list.h +++ b/drivers/staging/ath6kl/include/dl_list.h @@ -32,10 +32,10 @@ /* list functions */ /* pointers for the list */ -typedef struct _DL_LIST { - struct _DL_LIST *pPrev; - struct _DL_LIST *pNext; -}DL_LIST, *PDL_LIST; +struct dl_list { + struct dl_list *pPrev; + struct dl_list *pNext; +}; /* * DL_LIST_INIT , initialize doubly linked list */ @@ -67,7 +67,7 @@ typedef struct _DL_LIST { */ #define ITERATE_OVER_LIST_ALLOW_REMOVE(pStart,pItem,st,offset) \ { \ - PDL_LIST pTemp; \ + struct dl_list * pTemp; \ pTemp = (pStart)->pNext; \ while (pTemp != (pStart)) { \ (pItem) = A_CONTAINING_STRUCT(pTemp,st,offset); \ @@ -78,7 +78,7 @@ typedef struct _DL_LIST { /* * DL_ListInsertTail - insert pAdd to the end of the list */ -static INLINE PDL_LIST DL_ListInsertTail(PDL_LIST pList, PDL_LIST pAdd) { +static INLINE struct dl_list *DL_ListInsertTail(struct dl_list *pList, struct dl_list *pAdd) { /* insert at tail */ pAdd->pPrev = pList->pPrev; pAdd->pNext = pList; @@ -90,7 +90,7 @@ static INLINE PDL_LIST DL_ListInsertTail(PDL_LIST pList, PDL_LIST pAdd) { /* * DL_ListInsertHead - insert pAdd into the head of the list */ -static INLINE PDL_LIST DL_ListInsertHead(PDL_LIST pList, PDL_LIST pAdd) { +static INLINE struct dl_list * DL_ListInsertHead(struct dl_list * pList, struct dl_list * pAdd) { /* insert at head */ pAdd->pPrev = pList; pAdd->pNext = pList->pNext; @@ -103,7 +103,7 @@ static INLINE PDL_LIST DL_ListInsertHead(PDL_LIST pList, PDL_LIST pAdd) { /* * DL_ListRemove - remove pDel from list */ -static INLINE PDL_LIST DL_ListRemove(PDL_LIST pDel) { +static INLINE struct dl_list * DL_ListRemove(struct dl_list * pDel) { pDel->pNext->pPrev = pDel->pPrev; pDel->pPrev->pNext = pDel->pNext; /* point back to itself just to be safe, incase remove is called again */ @@ -115,8 +115,8 @@ static INLINE PDL_LIST DL_ListRemove(PDL_LIST pDel) { /* * DL_ListRemoveItemFromHead - get a list item from the head */ -static INLINE PDL_LIST DL_ListRemoveItemFromHead(PDL_LIST pList) { - PDL_LIST pItem = NULL; +static INLINE struct dl_list * DL_ListRemoveItemFromHead(struct dl_list * pList) { + struct dl_list * pItem = NULL; if (pList->pNext != pList) { pItem = pList->pNext; /* remove the first item from head */ @@ -125,8 +125,8 @@ static INLINE PDL_LIST DL_ListRemoveItemFromHead(PDL_LIST pList) { return pItem; } -static INLINE PDL_LIST DL_ListRemoveItemFromTail(PDL_LIST pList) { - PDL_LIST pItem = NULL; +static INLINE struct dl_list * DL_ListRemoveItemFromTail(struct dl_list * pList) { + struct dl_list * pItem = NULL; if (pList->pPrev != pList) { pItem = pList->pPrev; /* remove the item from tail */ @@ -136,7 +136,7 @@ static INLINE PDL_LIST DL_ListRemoveItemFromTail(PDL_LIST pList) { } /* transfer src list items to the tail of the destination list */ -static INLINE void DL_ListTransferItemsToTail(PDL_LIST pDest, PDL_LIST pSrc) { +static INLINE void DL_ListTransferItemsToTail(struct dl_list * pDest, struct dl_list * pSrc) { /* only concatenate if src is not empty */ if (!DL_LIST_IS_EMPTY(pSrc)) { /* cut out circular list in src and re-attach to end of dest */ diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h index ab1f4c1ad917..3421a593a0ce 100644 --- a/drivers/staging/ath6kl/include/hif.h +++ b/drivers/staging/ath6kl/include/hif.h @@ -287,7 +287,7 @@ typedef enum _HIF_SCATTER_METHOD { } HIF_SCATTER_METHOD; typedef struct _HIF_SCATTER_REQ { - DL_LIST ListLink; /* link management */ + struct dl_list ListLink; /* link management */ u32 Address; /* address for the read/write operation */ u32 Request; /* request flags */ u32 TotalLength; /* total length of entire transfer */ diff --git a/drivers/staging/ath6kl/include/htc_packet.h b/drivers/staging/ath6kl/include/htc_packet.h index fcf0a0c3bedb..9282e909fc8c 100644 --- a/drivers/staging/ath6kl/include/htc_packet.h +++ b/drivers/staging/ath6kl/include/htc_packet.h @@ -69,7 +69,7 @@ typedef struct _HTC_RX_PACKET_INFO { /* wrapper around endpoint-specific packets */ typedef struct _HTC_PACKET { - DL_LIST ListLink; /* double link */ + struct dl_list ListLink; /* double link */ void *pPktContext; /* caller's per packet specific context */ u8 *pBufferStart; /* the true buffer start , the caller can @@ -140,7 +140,7 @@ typedef struct _HTC_PACKET { /* HTC Packet Queueing Macros */ typedef struct _HTC_PACKET_QUEUE { - DL_LIST QueueHead; + struct dl_list QueueHead; int Depth; } HTC_PACKET_QUEUE; @@ -180,7 +180,7 @@ static INLINE HTC_PACKET *HTC_GET_PKT_AT_HEAD(HTC_PACKET_QUEUE *queue) { /* dequeue an HTC packet from the head of the queue */ static INLINE HTC_PACKET *HTC_PACKET_DEQUEUE(HTC_PACKET_QUEUE *queue) { - DL_LIST *pItem = DL_ListRemoveItemFromHead(&queue->QueueHead); + struct dl_list *pItem = DL_ListRemoveItemFromHead(&queue->QueueHead); if (pItem != NULL) { queue->Depth--; return A_CONTAINING_STRUCT(pItem, HTC_PACKET, ListLink); @@ -190,7 +190,7 @@ static INLINE HTC_PACKET *HTC_PACKET_DEQUEUE(HTC_PACKET_QUEUE *queue) { /* dequeue an HTC packet from the tail of the queue */ static INLINE HTC_PACKET *HTC_PACKET_DEQUEUE_TAIL(HTC_PACKET_QUEUE *queue) { - DL_LIST *pItem = DL_ListRemoveItemFromTail(&queue->QueueHead); + struct dl_list *pItem = DL_ListRemoveItemFromTail(&queue->QueueHead); if (pItem != NULL) { queue->Depth--; return A_CONTAINING_STRUCT(pItem, HTC_PACKET, ListLink); -- cgit v1.2.3 From 55b0f0daa6f3f7225042ba67cfe5773c77efe425 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:36 -0700 Subject: ath6kl: remove-typedef GMBOX_PROTO_HCI_UART remove-typedef -s GMBOX_PROTO_HCI_UART \ "struct gmbox_proto_hci_uart" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- .../ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c | 60 +++++++++++----------- 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c index 3ee3d40893da..78da8a155129 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c @@ -56,7 +56,7 @@ #define BAUD_TIMEOUT_MS 1 #define BTPWRSAV_TIMEOUT_MS 1 -typedef struct { +struct gmbox_proto_hci_uart { HCI_TRANSPORT_CONFIG_INFO HCIConfig; bool HCIAttached; bool HCIStopped; @@ -75,7 +75,7 @@ typedef struct { int CreditSize; int CreditsCurrentSeek; int SendProcessCount; -} GMBOX_PROTO_HCI_UART; +}; #define LOCK_HCI_RX(t) A_MUTEX_LOCK(&(t)->HCIRxLock); #define UNLOCK_HCI_RX(t) A_MUTEX_UNLOCK(&(t)->HCIRxLock); @@ -99,9 +99,9 @@ do { \ (p)->HCIConfig.pHCISendComplete((p)->HCIConfig.pContext, (pt)); \ } -static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, bool Synchronous); +static int HCITrySend(struct gmbox_proto_hci_uart *pProt, HTC_PACKET *pPacket, bool Synchronous); -static void HCIUartCleanup(GMBOX_PROTO_HCI_UART *pProtocol) +static void HCIUartCleanup(struct gmbox_proto_hci_uart *pProtocol) { A_ASSERT(pProtocol != NULL); @@ -111,7 +111,7 @@ static void HCIUartCleanup(GMBOX_PROTO_HCI_UART *pProtocol) A_FREE(pProtocol); } -static int InitTxCreditState(GMBOX_PROTO_HCI_UART *pProt) +static int InitTxCreditState(struct gmbox_proto_hci_uart *pProt) { int status; int credits; @@ -191,7 +191,7 @@ static int InitTxCreditState(GMBOX_PROTO_HCI_UART *pProt) static int CreditsAvailableCallback(void *pContext, int Credits, bool CreditIRQEnabled) { - GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)pContext; + struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)pContext; bool enableCreditIrq = false; bool disableCreditIrq = false; bool doPendingSends = false; @@ -274,7 +274,7 @@ static int CreditsAvailableCallback(void *pContext, int Credits, bool CreditIRQE return status; } -static INLINE void NotifyTransportFailure(GMBOX_PROTO_HCI_UART *pProt, int status) +static INLINE void NotifyTransportFailure(struct gmbox_proto_hci_uart *pProt, int status) { if (pProt->HCIConfig.TransportFailure != NULL) { pProt->HCIConfig.TransportFailure(pProt->HCIConfig.pContext, status); @@ -283,7 +283,7 @@ static INLINE void NotifyTransportFailure(GMBOX_PROTO_HCI_UART *pProt, int stat static void FailureCallback(void *pContext, int Status) { - GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)pContext; + struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)pContext; /* target assertion occured */ NotifyTransportFailure(pProt, Status); @@ -291,7 +291,7 @@ static void FailureCallback(void *pContext, int Status) static void StateDumpCallback(void *pContext) { - GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)pContext; + struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)pContext; AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("============ HCIUart State ======================\n")); AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("RecvStateFlags : 0x%X \n",pProt->RecvStateFlags)); @@ -306,7 +306,7 @@ static void StateDumpCallback(void *pContext) static int HCIUartMessagePending(void *pContext, u8 LookAheadBytes[], int ValidBytes) { - GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)pContext; + struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)pContext; int status = 0; int totalRecvLength = 0; HCI_TRANSPORT_PACKET_TYPE pktType = HCI_PACKET_INVALID; @@ -534,7 +534,7 @@ static int HCIUartMessagePending(void *pContext, u8 LookAheadBytes[], int ValidB static void HCISendPacketCompletion(void *Context, HTC_PACKET *pPacket) { - GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)Context; + struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)Context; AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCISendPacketCompletion (pPacket:0x%lX) \n",(unsigned long)pPacket)); if (pPacket->Status) { @@ -547,7 +547,7 @@ static void HCISendPacketCompletion(void *Context, HTC_PACKET *pPacket) AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCISendPacketCompletion \n")); } -static int SeekCreditsSynch(GMBOX_PROTO_HCI_UART *pProt) +static int SeekCreditsSynch(struct gmbox_proto_hci_uart *pProt) { int status = 0; int credits; @@ -579,7 +579,7 @@ static int SeekCreditsSynch(GMBOX_PROTO_HCI_UART *pProt) return status; } -static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, bool Synchronous) +static int HCITrySend(struct gmbox_proto_hci_uart *pProt, HTC_PACKET *pPacket, bool Synchronous) { int status = 0; int transferLength; @@ -794,7 +794,7 @@ static int HCITrySend(GMBOX_PROTO_HCI_UART *pProt, HTC_PACKET *pPacket, bool Syn return status; } -static void FlushSendQueue(GMBOX_PROTO_HCI_UART *pProt) +static void FlushSendQueue(struct gmbox_proto_hci_uart *pProt) { HTC_PACKET *pPacket; HTC_PACKET_QUEUE discardQueue; @@ -818,7 +818,7 @@ static void FlushSendQueue(GMBOX_PROTO_HCI_UART *pProt) } -static void FlushRecvBuffers(GMBOX_PROTO_HCI_UART *pProt) +static void FlushRecvBuffers(struct gmbox_proto_hci_uart *pProt) { HTC_PACKET_QUEUE discardQueue; HTC_PACKET *pPacket; @@ -849,11 +849,11 @@ static void FlushRecvBuffers(GMBOX_PROTO_HCI_UART *pProt) int GMboxProtocolInstall(struct ar6k_device *pDev) { int status = 0; - GMBOX_PROTO_HCI_UART *pProtocol = NULL; + struct gmbox_proto_hci_uart *pProtocol = NULL; do { - pProtocol = A_MALLOC(sizeof(GMBOX_PROTO_HCI_UART)); + pProtocol = A_MALLOC(sizeof(struct gmbox_proto_hci_uart)); if (NULL == pProtocol) { status = A_NO_MEMORY; @@ -891,7 +891,7 @@ int GMboxProtocolInstall(struct ar6k_device *pDev) /*** protocol module uninstall entry point ***/ void GMboxProtocolUninstall(struct ar6k_device *pDev) { - GMBOX_PROTO_HCI_UART *pProtocol = (GMBOX_PROTO_HCI_UART *)DEV_GMBOX_GET_PROTOCOL(pDev); + struct gmbox_proto_hci_uart *pProtocol = (struct gmbox_proto_hci_uart *)DEV_GMBOX_GET_PROTOCOL(pDev); if (pProtocol != NULL) { @@ -908,7 +908,7 @@ void GMboxProtocolUninstall(struct ar6k_device *pDev) } -static int NotifyTransportReady(GMBOX_PROTO_HCI_UART *pProt) +static int NotifyTransportReady(struct gmbox_proto_hci_uart *pProt) { HCI_TRANSPORT_PROPERTIES props; int status = 0; @@ -938,7 +938,7 @@ static int NotifyTransportReady(GMBOX_PROTO_HCI_UART *pProt) HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, HCI_TRANSPORT_CONFIG_INFO *pInfo) { - GMBOX_PROTO_HCI_UART *pProtocol = NULL; + struct gmbox_proto_hci_uart *pProtocol = NULL; struct ar6k_device *pDev; AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportAttach \n")); @@ -949,7 +949,7 @@ HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, HCI_TRANSPORT_CONFIG_I do { - pProtocol = (GMBOX_PROTO_HCI_UART *)DEV_GMBOX_GET_PROTOCOL(pDev); + pProtocol = (struct gmbox_proto_hci_uart *)DEV_GMBOX_GET_PROTOCOL(pDev); if (NULL == pProtocol) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("GMBOX protocol not installed! \n")); @@ -983,7 +983,7 @@ HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, HCI_TRANSPORT_CONFIG_I void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans) { - GMBOX_PROTO_HCI_UART *pProtocol = (GMBOX_PROTO_HCI_UART *)HciTrans; + struct gmbox_proto_hci_uart *pProtocol = (struct gmbox_proto_hci_uart *)HciTrans; struct ar6k_device *pDev = pProtocol->pDev; AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportDetach \n")); @@ -1003,7 +1003,7 @@ void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans) int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue) { - GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; + struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; int status = 0; bool unblockRecv = false; HTC_PACKET *pPacket; @@ -1071,14 +1071,14 @@ int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE int HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, bool Synchronous) { - GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; + struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; return HCITrySend(pProt,pPacket,Synchronous); } void HCI_TransportStop(HCI_TRANSPORT_HANDLE HciTrans) { - GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; + struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportStop \n")); @@ -1105,7 +1105,7 @@ void HCI_TransportStop(HCI_TRANSPORT_HANDLE HciTrans) int HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans) { int status; - GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; + struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportStart \n")); @@ -1151,7 +1151,7 @@ int HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans) int HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, bool Enable) { - GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; + struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; return DevGMboxIRQAction(pProt->pDev, Enable ? GMBOX_RECV_IRQ_ENABLE : GMBOX_RECV_IRQ_DISABLE, PROC_IO_SYNC); @@ -1162,7 +1162,7 @@ int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, int MaxPollMS) { - GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; + struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; int status = 0; u8 lookAhead[8]; int bytes; @@ -1232,7 +1232,7 @@ int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, #define MSB_SCRATCH_IDX 5 int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud) { - GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; + struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; HIF_DEVICE *pHIFDevice = (HIF_DEVICE *)(pProt->pDev->HIFDevice); u32 scaledBaud, scratchAddr; int status = 0; @@ -1264,7 +1264,7 @@ int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud) int HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, bool Enable) { int status; - GMBOX_PROTO_HCI_UART *pProt = (GMBOX_PROTO_HCI_UART *)HciTrans; + struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; if (Enable) { status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_PWR_SAV_ON, BTPWRSAV_TIMEOUT_MS); -- cgit v1.2.3 From ed8b361d88c23e2ee01ceb3ab00ab57e3b0d8233 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:37 -0700 Subject: ath6kl: remove-typedef HCI_TRANSPORT_CALLBACKS remove-typedef -s HCI_TRANSPORT_CALLBACKS \ "struct hci_transport_callbacks" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/include/common_drv.h | 4 ++-- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 2 +- drivers/staging/ath6kl/os/linux/ar6k_pal.c | 4 ++-- drivers/staging/ath6kl/os/linux/export_hci_transport.c | 4 ++-- drivers/staging/ath6kl/os/linux/hci_bridge.c | 2 +- drivers/staging/ath6kl/os/linux/include/export_hci_transport.h | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/include/common_drv.h b/drivers/staging/ath6kl/include/common_drv.h index f5bc9c3bf222..2b633d92064d 100644 --- a/drivers/staging/ath6kl/include/common_drv.h +++ b/drivers/staging/ath6kl/include/common_drv.h @@ -36,10 +36,10 @@ struct common_credit_state_info { HTC_ENDPOINT_CREDIT_DIST *pLowestPriEpDist; /* pointer to the lowest priority endpoint dist struct */ }; -typedef struct { +struct hci_transport_callbacks { s32 (*setupTransport)(void *ar); void (*cleanupTransport)(void *ar); -} HCI_TRANSPORT_CALLBACKS; +}; typedef struct { void *netDevice; diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 811235a7031b..add1cebaee53 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -114,7 +114,7 @@ APTC_TRAFFIC_RECORD aptcTR; #ifdef EXPORT_HCI_BRIDGE_INTERFACE // callbacks registered by HCI transport driver -HCI_TRANSPORT_CALLBACKS ar6kHciTransCallbacks = { NULL }; +struct hci_transport_callbacks ar6kHciTransCallbacks = { NULL }; #endif unsigned int processDot11Hdr = 0; diff --git a/drivers/staging/ath6kl/os/linux/ar6k_pal.c b/drivers/staging/ath6kl/os/linux/ar6k_pal.c index 8dd51ee0f72f..08f3710b2103 100644 --- a/drivers/staging/ath6kl/os/linux/ar6k_pal.c +++ b/drivers/staging/ath6kl/os/linux/ar6k_pal.c @@ -455,10 +455,10 @@ void ar6k_cleanup_hci_pal(void *ar_p) * Register init and callback function with ar6k * when PAL driver is a separate kernel module. ****************************************************/ -int ar6k_register_hci_pal(HCI_TRANSPORT_CALLBACKS *hciTransCallbacks); +int ar6k_register_hci_pal(struct hci_transport_callbacks *hciTransCallbacks); static int __init pal_init_module(void) { - HCI_TRANSPORT_CALLBACKS hciTransCallbacks; + struct hci_transport_callbacks hciTransCallbacks; hciTransCallbacks.setupTransport = ar6k_setup_hci_pal; hciTransCallbacks.cleanupTransport = ar6k_cleanup_hci_pal; diff --git a/drivers/staging/ath6kl/os/linux/export_hci_transport.c b/drivers/staging/ath6kl/os/linux/export_hci_transport.c index 9e8ca5cafdd0..168d6f7282be 100644 --- a/drivers/staging/ath6kl/os/linux/export_hci_transport.c +++ b/drivers/staging/ath6kl/os/linux/export_hci_transport.c @@ -49,9 +49,9 @@ int (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans, int (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud); int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); -extern HCI_TRANSPORT_CALLBACKS ar6kHciTransCallbacks; +extern struct hci_transport_callbacks ar6kHciTransCallbacks; -int ar6000_register_hci_transport(HCI_TRANSPORT_CALLBACKS *hciTransCallbacks) +int ar6000_register_hci_transport(struct hci_transport_callbacks *hciTransCallbacks) { ar6kHciTransCallbacks = *hciTransCallbacks; diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index 327aab6f0109..61ce094be2c6 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -1119,7 +1119,7 @@ static int __init hcibridge_init_module(void) { int status; - HCI_TRANSPORT_CALLBACKS hciTransCallbacks; + struct hci_transport_callbacks hciTransCallbacks; hciTransCallbacks.setupTransport = ar6000_setup_hci; hciTransCallbacks.cleanupTransport = ar6000_cleanup_hci; diff --git a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h index 63d887c14328..51187f6b706b 100644 --- a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h +++ b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h @@ -61,7 +61,7 @@ extern int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, bo _HCI_TransportEnablePowerMgmt((HciTrans), (Enable)) -extern int ar6000_register_hci_transport(HCI_TRANSPORT_CALLBACKS *hciTransCallbacks); +extern int ar6000_register_hci_transport(struct hci_transport_callbacks *hciTransCallbacks); extern int ar6000_get_hif_dev(HIF_DEVICE *device, void *config); -- cgit v1.2.3 From c9478eaf5e78c6379fab320eac98f9a878efd579 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:38 -0700 Subject: ath6kl: remove-typedef HCI_TRANSPORT_CONFIG_INFO remove-typedef -s HCI_TRANSPORT_CONFIG_INFO \ "struct hci_transport_config_info" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 2 +- drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c | 6 +++--- drivers/staging/ath6kl/include/hci_transport_api.h | 6 +++--- drivers/staging/ath6kl/os/linux/export_hci_transport.c | 2 +- drivers/staging/ath6kl/os/linux/hci_bridge.c | 4 ++-- drivers/staging/ath6kl/os/linux/include/export_hci_transport.h | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index 88ef25a1abcd..4b69f91ef3ff 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -361,7 +361,7 @@ static INLINE int DevSetupGMbox(struct ar6k_device *pDev) { #ifdef ATH_AR6K_ENABLE_GMBOX /* GMBOX protocol modules must expose each of these internal APIs */ -HCI_TRANSPORT_HANDLE GMboxAttachProtocol(struct ar6k_device *pDev, HCI_TRANSPORT_CONFIG_INFO *pInfo); +HCI_TRANSPORT_HANDLE GMboxAttachProtocol(struct ar6k_device *pDev, struct hci_transport_config_info *pInfo); int GMboxProtocolInstall(struct ar6k_device *pDev); void GMboxProtocolUninstall(struct ar6k_device *pDev); diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c index 78da8a155129..c7e8f711ad0f 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c @@ -57,7 +57,7 @@ #define BTPWRSAV_TIMEOUT_MS 1 struct gmbox_proto_hci_uart { - HCI_TRANSPORT_CONFIG_INFO HCIConfig; + struct hci_transport_config_info HCIConfig; bool HCIAttached; bool HCIStopped; u32 RecvStateFlags; @@ -936,7 +936,7 @@ static int NotifyTransportReady(struct gmbox_proto_hci_uart *pProt) /*********** HCI UART protocol implementation ************************************************/ -HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, HCI_TRANSPORT_CONFIG_INFO *pInfo) +HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, struct hci_transport_config_info *pInfo) { struct gmbox_proto_hci_uart *pProtocol = NULL; struct ar6k_device *pDev; @@ -961,7 +961,7 @@ HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, HCI_TRANSPORT_CONFIG_I break; } - memcpy(&pProtocol->HCIConfig, pInfo, sizeof(HCI_TRANSPORT_CONFIG_INFO)); + memcpy(&pProtocol->HCIConfig, pInfo, sizeof(struct hci_transport_config_info)); A_ASSERT(pProtocol->HCIConfig.pHCIPktRecv != NULL); A_ASSERT(pProtocol->HCIConfig.pHCISendComplete != NULL); diff --git a/drivers/staging/ath6kl/include/hci_transport_api.h b/drivers/staging/ath6kl/include/hci_transport_api.h index 8ab692db6cfe..7fa44f0e12a4 100644 --- a/drivers/staging/ath6kl/include/hci_transport_api.h +++ b/drivers/staging/ath6kl/include/hci_transport_api.h @@ -85,7 +85,7 @@ typedef struct { int IOBlockPad; /* I/O block padding required (always a power of 2) */ } HCI_TRANSPORT_PROPERTIES; -typedef struct _HCI_TRANSPORT_CONFIG_INFO { +struct hci_transport_config_info { int ACLRecvBufferWaterMark; /* low watermark to trigger recv refill */ int EventRecvBufferWaterMark; /* low watermark to trigger recv refill */ int MaxSendQueueDepth; /* max number of packets in the single send queue */ @@ -99,7 +99,7 @@ typedef struct _HCI_TRANSPORT_CONFIG_INFO { HCI_TRANSPORT_RECV_REFILL pHCIPktRecvRefill; HCI_TRANSPORT_RECV_ALLOC pHCIPktRecvAlloc; HCI_TRANSPORT_SEND_FULL pHCISendFull; -} HCI_TRANSPORT_CONFIG_INFO; +}; /* ------ Function Prototypes ------ */ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -113,7 +113,7 @@ typedef struct _HCI_TRANSPORT_CONFIG_INFO { @example: @see also: HCI_TransportDetach +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, HCI_TRANSPORT_CONFIG_INFO *pInfo); +HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, struct hci_transport_config_info *pInfo); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Detach from the HCI transport module diff --git a/drivers/staging/ath6kl/os/linux/export_hci_transport.c b/drivers/staging/ath6kl/os/linux/export_hci_transport.c index 168d6f7282be..fd875263f27f 100644 --- a/drivers/staging/ath6kl/os/linux/export_hci_transport.c +++ b/drivers/staging/ath6kl/os/linux/export_hci_transport.c @@ -36,7 +36,7 @@ #include "AR6002/hw4.0/hw/uart_reg.h" #include "AR6002/hw4.0/hw/rtc_wlan_reg.h" -HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, HCI_TRANSPORT_CONFIG_INFO *pInfo); +HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, struct hci_transport_config_info *pInfo); void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans); int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue); int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, bool Synchronous); diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index 61ce094be2c6..d0b68144359e 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -469,7 +469,7 @@ int ar6000_setup_hci(void *ar) int ar6000_setup_hci(AR_SOFTC_T *ar) #endif { - HCI_TRANSPORT_CONFIG_INFO config; + struct hci_transport_config_info config; int status = 0; int i; HTC_PACKET *pPacket; @@ -521,7 +521,7 @@ int ar6000_setup_hci(AR_SOFTC_T *ar) FreeHTCStruct(pHcidevInfo,pPacket); } - A_MEMZERO(&config,sizeof(HCI_TRANSPORT_CONFIG_INFO)); + A_MEMZERO(&config,sizeof(struct hci_transport_config_info)); config.ACLRecvBufferWaterMark = MAX_ACL_RECV_BUFS / 2; config.EventRecvBufferWaterMark = MAX_EVT_RECV_BUFS / 2; config.MaxSendQueueDepth = MAX_HCI_WRITE_QUEUE_DEPTH; diff --git a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h index 51187f6b706b..cf66717de391 100644 --- a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h +++ b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h @@ -25,7 +25,7 @@ #include "hci_transport_api.h" #include "common_drv.h" -extern HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, HCI_TRANSPORT_CONFIG_INFO *pInfo); +extern HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, struct hci_transport_config_info *pInfo); extern void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans); extern int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue); extern int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, bool Synchronous); -- cgit v1.2.3 From e83750e79169e860aa1eb9077084e67b7ce5d86b Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:39 -0700 Subject: ath6kl: remove-typedef HCI_TRANSPORT_MISC_HANDLES remove-typedef -s HCI_TRANSPORT_MISC_HANDLES \ "struct hci_transport_misc_handles" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/include/common_drv.h | 4 ++-- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 2 +- drivers/staging/ath6kl/os/linux/hci_bridge.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/include/common_drv.h b/drivers/staging/ath6kl/include/common_drv.h index 2b633d92064d..4c70a779e1f0 100644 --- a/drivers/staging/ath6kl/include/common_drv.h +++ b/drivers/staging/ath6kl/include/common_drv.h @@ -41,11 +41,11 @@ struct hci_transport_callbacks { void (*cleanupTransport)(void *ar); }; -typedef struct { +struct hci_transport_misc_handles { void *netDevice; void *hifDevice; void *htcHandle; -} HCI_TRANSPORT_MISC_HANDLES; +}; /* HTC TX packet tagging definitions */ #define AR6K_CONTROL_PKT_TAG HTC_TX_PACKET_TAG_USER_DEFINED diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index add1cebaee53..749e28422f75 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -2723,7 +2723,7 @@ int ar6000_init(struct net_device *dev) #ifdef EXPORT_HCI_BRIDGE_INTERFACE if (setuphci && (NULL != ar6kHciTransCallbacks.setupTransport)) { - HCI_TRANSPORT_MISC_HANDLES hciHandles; + struct hci_transport_misc_handles hciHandles; hciHandles.netDevice = ar->arNetDev; hciHandles.hifDevice = ar->arHifDevice; diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index d0b68144359e..433c69eb739b 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -83,7 +83,7 @@ struct ar6k_hci_bridge_info { u8 *pHTCStructAlloc; spinlock_t BridgeLock; #ifdef EXPORT_HCI_BRIDGE_INTERFACE - HCI_TRANSPORT_MISC_HANDLES HCITransHdl; + struct hci_transport_misc_handles HCITransHdl; #else AR_SOFTC_T *ar; #endif /* EXPORT_HCI_BRIDGE_INTERFACE */ @@ -488,7 +488,7 @@ int ar6000_setup_hci(AR_SOFTC_T *ar) A_MEMZERO(pHcidevInfo, sizeof(struct ar6k_hci_bridge_info)); #ifdef EXPORT_HCI_BRIDGE_INTERFACE g_pHcidevInfo = pHcidevInfo; - pHcidevInfo->HCITransHdl = *(HCI_TRANSPORT_MISC_HANDLES *)ar; + pHcidevInfo->HCITransHdl = *(struct hci_transport_misc_handles *)ar; #else ar->hcidev_info = pHcidevInfo; pHcidevInfo->ar = ar; -- cgit v1.2.3 From f1ab30823feddb533ad5840e873c79698b77abf0 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:40 -0700 Subject: ath6kl: remove-typedef HCI_TRANSPORT_PROPERTIES remove-typedef -s HCI_TRANSPORT_PROPERTIES \ "struct hci_transport_properties" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c | 2 +- drivers/staging/ath6kl/include/ar3kconfig.h | 2 +- drivers/staging/ath6kl/include/hci_transport_api.h | 6 +++--- drivers/staging/ath6kl/os/linux/hci_bridge.c | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c index c7e8f711ad0f..8e5abe8e67ec 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c @@ -910,7 +910,7 @@ void GMboxProtocolUninstall(struct ar6k_device *pDev) static int NotifyTransportReady(struct gmbox_proto_hci_uart *pProt) { - HCI_TRANSPORT_PROPERTIES props; + struct hci_transport_properties props; int status = 0; do { diff --git a/drivers/staging/ath6kl/include/ar3kconfig.h b/drivers/staging/ath6kl/include/ar3kconfig.h index 20d295ba0da4..80f948e99576 100644 --- a/drivers/staging/ath6kl/include/ar3kconfig.h +++ b/drivers/staging/ath6kl/include/ar3kconfig.h @@ -41,7 +41,7 @@ extern "C" { struct ar3k_config_info { u32 Flags; /* config flags */ void *pHCIDev; /* HCI bridge device */ - HCI_TRANSPORT_PROPERTIES *pHCIProps; /* HCI bridge props */ + struct hci_transport_properties *pHCIProps; /* HCI bridge props */ HIF_DEVICE *pHIFDevice; /* HIF layer device */ u32 AR3KBaudRate; /* AR3K operational baud rate */ diff --git a/drivers/staging/ath6kl/include/hci_transport_api.h b/drivers/staging/ath6kl/include/hci_transport_api.h index 7fa44f0e12a4..ee25c6b5cfdc 100644 --- a/drivers/staging/ath6kl/include/hci_transport_api.h +++ b/drivers/staging/ath6kl/include/hci_transport_api.h @@ -79,11 +79,11 @@ typedef enum _HCI_SEND_FULL_ACTION { * the callback must return the send full action to take (either DROP or KEEP) */ typedef HCI_SEND_FULL_ACTION (*HCI_TRANSPORT_SEND_FULL)(void *, HTC_PACKET *); -typedef struct { +struct hci_transport_properties { int HeadRoom; /* number of bytes in front of HCI packet for header space */ int TailRoom; /* number of bytes at the end of the HCI packet for tail space */ int IOBlockPad; /* I/O block padding required (always a power of 2) */ -} HCI_TRANSPORT_PROPERTIES; +}; struct hci_transport_config_info { int ACLRecvBufferWaterMark; /* low watermark to trigger recv refill */ @@ -91,7 +91,7 @@ struct hci_transport_config_info { int MaxSendQueueDepth; /* max number of packets in the single send queue */ void *pContext; /* context for all callbacks */ void (*TransportFailure)(void *pContext, int Status); /* transport failure callback */ - int (*TransportReady)(HCI_TRANSPORT_HANDLE, HCI_TRANSPORT_PROPERTIES *,void *pContext); /* transport is ready */ + int (*TransportReady)(HCI_TRANSPORT_HANDLE, struct hci_transport_properties *,void *pContext); /* transport is ready */ void (*TransportRemoved)(void *pContext); /* transport was removed */ /* packet processing callbacks */ HCI_TRANSPORT_SEND_PKT_COMPLETE pHCISendComplete; diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index 433c69eb739b..4500f84b5608 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -75,7 +75,7 @@ extern unsigned int hciuartstep; struct ar6k_hci_bridge_info { void *pHCIDev; /* HCI bridge device */ - HCI_TRANSPORT_PROPERTIES HCIProps; /* HCI bridge props */ + struct hci_transport_properties HCIProps; /* HCI bridge props */ struct hci_dev *pBtStackHCIDev; /* BT Stack HCI dev */ bool HciNormalMode; /* Actual HCI mode enabled (non-TEST)*/ bool HciRegistered; /* HCI device registered with stack */ @@ -216,7 +216,7 @@ static void RefillRecvBuffers(struct ar6k_hci_bridge_info *pHcidevInfo, (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \ (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0)) static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle, - HCI_TRANSPORT_PROPERTIES *pProps, + struct hci_transport_properties *pProps, void *pContext) { struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext; -- cgit v1.2.3 From 4386ee312e413a33b9e5f406388c9488e6237c7c Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:41 -0700 Subject: ath6kl: remove-typedef HIF_DEVICE_IRQ_YIELD_PARAMS remove-typedef -s HIF_DEVICE_IRQ_YIELD_PARAMS \ "struct hif_device_irq_yield_params" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 2 +- drivers/staging/ath6kl/include/hif.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index 4b69f91ef3ff..e367288d5d7d 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -129,7 +129,7 @@ struct ar6k_device { HIF_DEVICE_IRQ_PROCESSING_MODE HifIRQProcessingMode; HIF_MASK_UNMASK_RECV_EVENT HifMaskUmaskRecvEvent; bool HifAttached; - HIF_DEVICE_IRQ_YIELD_PARAMS HifIRQYieldParams; + struct hif_device_irq_yield_params HifIRQYieldParams; bool DSRCanYield; int CurrentDSRRecvCount; HIF_DEVICE_SCATTER_SUPPORT_INFO HifScatterInfo; diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h index 3421a593a0ce..044af7e65b1b 100644 --- a/drivers/staging/ath6kl/include/hif.h +++ b/drivers/staging/ath6kl/include/hif.h @@ -190,7 +190,7 @@ typedef enum { * HIF_DEVICE_GET_IRQ_YIELD_PARAMS * * input : none - * output : HIF_DEVICE_IRQ_YIELD_PARAMS + * output : struct hif_device_irq_yield_params * note: This query checks if the HIF layer wishes to impose a processing yield count for the DSR handler. * The DSR callback handler will exit after a fixed number of RX packets or events are processed. * This query is only made if the device reports an IRQ processing mode of HIF_DEVICE_IRQ_SYNC_ONLY. @@ -265,9 +265,9 @@ typedef enum { */ } HIF_DEVICE_POWER_CHANGE_TYPE; -typedef struct { +struct hif_device_irq_yield_params { int RecvPacketYieldCount; /* max number of packets to force DSR to return */ -} HIF_DEVICE_IRQ_YIELD_PARAMS; +}; typedef struct _HIF_SCATTER_ITEM { -- cgit v1.2.3 From 02e12e08f4e94973c3bae9f3f6445680a120bebc Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:42 -0700 Subject: ath6kl: remove-typedef HIF_DEVICE_MBOX_INFO remove-typedef -s HIF_DEVICE_MBOX_INFO \ "struct hif_device_mbox_info" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/hif/common/hif_sdio_common.h | 2 +- drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 4 ++-- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 2 +- drivers/staging/ath6kl/include/hif.h | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/hif/common/hif_sdio_common.h b/drivers/staging/ath6kl/hif/common/hif_sdio_common.h index 9939a4a30d25..93a2adceca33 100644 --- a/drivers/staging/ath6kl/hif/common/hif_sdio_common.h +++ b/drivers/staging/ath6kl/hif/common/hif_sdio_common.h @@ -58,7 +58,7 @@ #define HIF_DEFAULT_IO_BLOCK_SIZE 128 /* set extended MBOX window information for SDIO interconnects */ -static INLINE void SetExtendedMboxWindowInfo(u16 Manfid, HIF_DEVICE_MBOX_INFO *pInfo) +static INLINE void SetExtendedMboxWindowInfo(u16 Manfid, struct hif_device_mbox_info *pInfo) { switch (Manfid & MANUFACTURER_ID_AR6K_BASE_MASK) { case MANUFACTURER_ID_AR6002_BASE : diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index 8a1cedb9eea9..9b947b4934fa 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -710,9 +710,9 @@ HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, ((u32 *)config)[count] = HIF_MBOX_START_ADDR(count); } - if (configLen >= sizeof(HIF_DEVICE_MBOX_INFO)) { + if (configLen >= sizeof(struct hif_device_mbox_info)) { SetExtendedMboxWindowInfo((u16)device->func->device, - (HIF_DEVICE_MBOX_INFO *)config); + (struct hif_device_mbox_info *)config); } break; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index e367288d5d7d..85c59157736d 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -115,7 +115,7 @@ struct ar6k_device { void *HIFDevice; u32 BlockSize; u32 BlockMask; - HIF_DEVICE_MBOX_INFO MailBoxInfo; + struct hif_device_mbox_info MailBoxInfo; HIF_PENDING_EVENTS_FUNC GetPendingEventsFunc; void *HTCContext; HTC_PACKET_QUEUE RegisterIOList; diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h index 044af7e65b1b..8df01b307f7d 100644 --- a/drivers/staging/ath6kl/include/hif.h +++ b/drivers/staging/ath6kl/include/hif.h @@ -153,7 +153,7 @@ typedef enum { * * HIF_DEVICE_GET_MBOX_ADDR * input : none - * output : HIF_DEVICE_MBOX_INFO + * output : struct hif_device_mbox_info * notes: * * HIF_DEVICE_GET_PENDING_EVENTS_FUNC @@ -235,7 +235,7 @@ typedef enum _MBOX_BUF_IF_TYPE { MBOX_BUS_IF_SPI = 1, } MBOX_BUF_IF_TYPE; -typedef struct { +struct hif_device_mbox_info { u32 MboxAddresses[4]; /* must be first element for legacy HIFs that return the address in and ARRAY of 32-bit words */ @@ -247,7 +247,7 @@ typedef struct { u32 GMboxSize; u32 Flags; /* flags to describe mbox behavior or usage */ MBOX_BUF_IF_TYPE MboxBusIFType; /* mailbox bus interface type */ -} HIF_DEVICE_MBOX_INFO; +}; typedef enum { HIF_DEVICE_IRQ_SYNC_ONLY, /* for HIF implementations that require the DSR to process all -- cgit v1.2.3 From e6b5260ee8d2e682ef90caac902124ca884f7386 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:43 -0700 Subject: ath6kl: remove-typedef HIF_DEVICE_OS_DEVICE_INFO remove-typedef -s HIF_DEVICE_OS_DEVICE_INFO \ "struct hif_device_os_device_info" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 2 +- drivers/staging/ath6kl/include/hif.h | 6 +++--- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 10 +++++----- drivers/staging/ath6kl/os/linux/export_hci_transport.c | 4 ++-- drivers/staging/ath6kl/os/linux/hci_bridge.c | 2 +- drivers/staging/ath6kl/os/linux/include/ar6000_drv.h | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index 9b947b4934fa..6d3b9f49d3b2 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -730,7 +730,7 @@ HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, break; case HIF_DEVICE_GET_OS_DEVICE: /* pass back a pointer to the SDIO function's "dev" struct */ - ((HIF_DEVICE_OS_DEVICE_INFO *)config)->pOSDevice = &device->func->dev; + ((struct hif_device_os_device_info *)config)->pOSDevice = &device->func->dev; break; case HIF_DEVICE_POWER_STATE_CHANGE: status = PowerStateChangeNotify(device, *(HIF_DEVICE_POWER_CHANGE_TYPE *)config); diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h index 8df01b307f7d..2c0f490f2530 100644 --- a/drivers/staging/ath6kl/include/hif.h +++ b/drivers/staging/ath6kl/include/hif.h @@ -211,7 +211,7 @@ typedef enum { * * HIF_DEVICE_GET_OS_DEVICE * intput : none - * output : HIF_DEVICE_OS_DEVICE_INFO; + * output : struct hif_device_os_device_info; * note: On some operating systems, the HIF layer has a parent device object for the bus. This object * may be required to register certain types of logical devices. * @@ -315,9 +315,9 @@ typedef struct _HIF_DEVICE_SCATTER_SUPPORT_INFO { int MaxTransferSizePerScatterReq; } HIF_DEVICE_SCATTER_SUPPORT_INFO; -typedef struct { +struct hif_device_os_device_info { void *pOSDevice; -} HIF_DEVICE_OS_DEVICE_INFO; +}; #define HIF_MAX_DEVICES 1 diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 749e28422f75..b739943d0ab8 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -803,7 +803,7 @@ ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj, { int index; AR_SOFTC_T *ar; - HIF_DEVICE_OS_DEVICE_INFO *osDevInfo; + struct hif_device_os_device_info *osDevInfo; AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Read %d bytes\n", (u32)count)); for (index=0; index < MAX_AR6000; index++) { @@ -830,7 +830,7 @@ ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj, { int index; AR_SOFTC_T *ar; - HIF_DEVICE_OS_DEVICE_INFO *osDevInfo; + struct hif_device_os_device_info *osDevInfo; AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Write %d bytes\n", (u32)count)); for (index=0; index < MAX_AR6000; index++) { @@ -856,13 +856,13 @@ ar6000_sysfs_bmi_init(AR_SOFTC_T *ar) int status; AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Creating sysfs entry\n")); - A_MEMZERO(&ar->osDevInfo, sizeof(HIF_DEVICE_OS_DEVICE_INFO)); + A_MEMZERO(&ar->osDevInfo, sizeof(struct hif_device_os_device_info)); /* Get the underlying OS device */ status = HIFConfigureDevice(ar->arHifDevice, HIF_DEVICE_GET_OS_DEVICE, &ar->osDevInfo, - sizeof(HIF_DEVICE_OS_DEVICE_INFO)); + sizeof(struct hif_device_os_device_info)); if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failed to get OS device info from HIF\n")); @@ -1604,7 +1604,7 @@ ar6000_avail_ev(void *context, void *hif_handle) struct wireless_dev *wdev; #endif /* ATH6K_CONFIG_CFG80211 */ int init_status = 0; - HIF_DEVICE_OS_DEVICE_INFO osDevInfo; + struct hif_device_os_device_info osDevInfo; memset(&osDevInfo, 0, sizeof(osDevInfo)); if (HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_OS_DEVICE, diff --git a/drivers/staging/ath6kl/os/linux/export_hci_transport.c b/drivers/staging/ath6kl/os/linux/export_hci_transport.c index fd875263f27f..79b30ebab797 100644 --- a/drivers/staging/ath6kl/os/linux/export_hci_transport.c +++ b/drivers/staging/ath6kl/os/linux/export_hci_transport.c @@ -76,8 +76,8 @@ ar6000_get_hif_dev(HIF_DEVICE *device, void *config) status = HIFConfigureDevice(device, HIF_DEVICE_GET_OS_DEVICE, - (HIF_DEVICE_OS_DEVICE_INFO *)config, - sizeof(HIF_DEVICE_OS_DEVICE_INFO)); + (struct hif_device_os_device_info *)config, + sizeof(struct hif_device_os_device_info)); return status; } diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index 4500f84b5608..d30ca24a1d58 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -857,7 +857,7 @@ static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo) { int status = 0; struct hci_dev *pHciDev = NULL; - HIF_DEVICE_OS_DEVICE_INFO osDevInfo; + struct hif_device_os_device_info osDevInfo; if (!setupbtdev) { return 0; diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 2373ed55e573..a20913380303 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -596,7 +596,7 @@ typedef struct ar6_softc { WMI_BTCOEX_CONFIG_EVENT arBtcoexConfig; WMI_BTCOEX_STATS_EVENT arBtcoexStats; s32 (*exitCallback)(void *config); /* generic callback at AR6K exit */ - HIF_DEVICE_OS_DEVICE_INFO osDevInfo; + struct hif_device_os_device_info osDevInfo; #ifdef ATH6K_CONFIG_CFG80211 struct wireless_dev *wdev; struct cfg80211_scan_request *scan_request; -- cgit v1.2.3 From 031a71c77427904367583762b91470bbf161b78c Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:44 -0700 Subject: ath6kl: remove-typedef HIF_DEVICE_SCATTER_SUPPORT_INFO remove-typedef -s HIF_DEVICE_SCATTER_SUPPORT_INFO \ "struct hif_device_scatter_support_info" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h | 4 ++-- drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 2 +- drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c | 2 +- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 2 +- drivers/staging/ath6kl/include/hif.h | 6 +++--- 5 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h index b5d1ad430ff2..e2d2266ba327 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h @@ -110,13 +110,13 @@ typedef struct _HIF_SCATTER_REQ_PRIV { #define ATH_DEBUG_SCATTER ATH_DEBUG_MAKE_MODULE_MASK(0) -int SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo); +int SetupHIFScatterSupport(HIF_DEVICE *device, struct hif_device_scatter_support_info *pInfo); void CleanupHIFScatterResources(HIF_DEVICE *device); int DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest); #else // HIF_LINUX_MMC_SCATTER_SUPPORT -static inline int SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo) +static inline int SetupHIFScatterSupport(HIF_DEVICE *device, struct hif_device_scatter_support_info *pInfo) { return A_ENOTSUP; } diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index 6d3b9f49d3b2..9c9fb1ef86d0 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -723,7 +723,7 @@ HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, if (!device->scatter_enabled) { return A_ENOTSUP; } - status = SetupHIFScatterSupport(device, (HIF_DEVICE_SCATTER_SUPPORT_INFO *)config); + status = SetupHIFScatterSupport(device, (struct hif_device_scatter_support_info *)config); if (status) { device->scatter_enabled = false; } diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c index 2a56a50bc211..567993f7d4ed 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c @@ -275,7 +275,7 @@ static int HifReadWriteScatter(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq) } /* setup of HIF scatter resources */ -int SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo) +int SetupHIFScatterSupport(HIF_DEVICE *device, struct hif_device_scatter_support_info *pInfo) { int status = A_ERROR; int i; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index 85c59157736d..08e9ef294ac9 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -132,7 +132,7 @@ struct ar6k_device { struct hif_device_irq_yield_params HifIRQYieldParams; bool DSRCanYield; int CurrentDSRRecvCount; - HIF_DEVICE_SCATTER_SUPPORT_INFO HifScatterInfo; + struct hif_device_scatter_support_info HifScatterInfo; struct dl_list ScatterReqHead; bool ScatterIsVirtual; int MaxRecvBundleSize; diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h index 2c0f490f2530..61e4392a9911 100644 --- a/drivers/staging/ath6kl/include/hif.h +++ b/drivers/staging/ath6kl/include/hif.h @@ -203,7 +203,7 @@ typedef enum { * * HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT * input : none - * output : HIF_DEVICE_SCATTER_SUPPORT_INFO + * output : struct hif_device_scatter_support_info * note: This query checks if the HIF layer implements the SCATTER request interface. Scatter requests * allows upper layers to submit mailbox I/O operations using a list of buffers. This is useful for * multi-message transfers that can better utilize the bus interconnect. @@ -306,14 +306,14 @@ typedef HIF_SCATTER_REQ * ( *HIF_ALLOCATE_SCATTER_REQUEST)(HIF_DEVICE *device); typedef void ( *HIF_FREE_SCATTER_REQUEST)(HIF_DEVICE *device, HIF_SCATTER_REQ *request); typedef int ( *HIF_READWRITE_SCATTER)(HIF_DEVICE *device, HIF_SCATTER_REQ *request); -typedef struct _HIF_DEVICE_SCATTER_SUPPORT_INFO { +struct hif_device_scatter_support_info { /* information returned from HIF layer */ HIF_ALLOCATE_SCATTER_REQUEST pAllocateReqFunc; HIF_FREE_SCATTER_REQUEST pFreeReqFunc; HIF_READWRITE_SCATTER pReadWriteScatterFunc; int MaxScatterEntries; int MaxTransferSizePerScatterReq; -} HIF_DEVICE_SCATTER_SUPPORT_INFO; +}; struct hif_device_os_device_info { void *pOSDevice; -- cgit v1.2.3 From d45f742841a27af7ad2ea16e9ddda7473fb2b795 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:45 -0700 Subject: ath6kl: remove-typedef HIF_MBOX_PROPERTIES remove-typedef -s HIF_MBOX_PROPERTIES \ "struct hif_mbox_properties" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/include/hif.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h index 61e4392a9911..4f9be8a7eddd 100644 --- a/drivers/staging/ath6kl/include/hif.h +++ b/drivers/staging/ath6kl/include/hif.h @@ -223,10 +223,10 @@ typedef enum { * */ -typedef struct { +struct hif_mbox_properties { u32 ExtendedAddress; /* extended address for larger writes */ u32 ExtendedSize; -} HIF_MBOX_PROPERTIES; +}; #define HIF_MBOX_FLAG_NO_BUNDLING (1 << 0) /* do not allow bundling over the mailbox */ @@ -240,7 +240,7 @@ struct hif_device_mbox_info { and ARRAY of 32-bit words */ /* the following describe extended mailbox properties */ - HIF_MBOX_PROPERTIES MboxProp[4]; + struct hif_mbox_properties MboxProp[4]; /* if the HIF supports the GMbox extended address region it can report it * here, some interfaces cannot support the GMBOX address range and not set this */ u32 GMboxAddress; -- cgit v1.2.3 From 03210b8fbc85127a3a5097e7ce71370c8f0eb31a Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:46 -0700 Subject: ath6kl: remove-typedef HIF_PENDING_EVENTS_INFO remove-typedef -s HIF_PENDING_EVENTS_INFO \ "struct hif_pending_events_info" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/bmi/src/bmi.c | 2 +- drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c | 8 ++++---- drivers/staging/ath6kl/include/hif.h | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/bmi/src/bmi.c b/drivers/staging/ath6kl/bmi/src/bmi.c index a9615b726005..34d1befa0bc4 100644 --- a/drivers/staging/ath6kl/bmi/src/bmi.c +++ b/drivers/staging/ath6kl/bmi/src/bmi.c @@ -790,7 +790,7 @@ bmiBufferReceive(HIF_DEVICE *device, int status; u32 address; u32 mboxAddress[HTC_MAILBOX_NUM_MAX]; - HIF_PENDING_EVENTS_INFO hifPendingEvents; + struct hif_pending_events_info hifPendingEvents; static HIF_PENDING_EVENTS_FUNC getPendingEventsFunc = NULL; if (!pendingEventsFuncCheck) { diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c index bac4f9374cd8..ca6abb490e24 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c @@ -74,7 +74,7 @@ int DevPollMboxMsgRecv(struct ar6k_device *pDev, if (pDev->GetPendingEventsFunc != NULL) { - HIF_PENDING_EVENTS_INFO events; + struct hif_pending_events_info events; #ifdef THREAD_X events.Polling =1; @@ -319,7 +319,7 @@ static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket) if (pDev->GetPendingEventsFunc != NULL) { /* the HIF layer collected the information for us */ - HIF_PENDING_EVENTS_INFO *pEvents = (HIF_PENDING_EVENTS_INFO *)pPacket->pBuffer; + struct hif_pending_events_info *pEvents = (struct hif_pending_events_info *)pPacket->pBuffer; if (pEvents->Events & HIF_RECV_MSG_AVAIL) { lookAhead = pEvents->LookAhead; if (0 == lookAhead) { @@ -439,7 +439,7 @@ int DevCheckPendingRecvMsgsAsync(void *context) if (pDev->GetPendingEventsFunc) { /* HIF layer has it's own mechanism, pass the IO to it.. */ status = pDev->GetPendingEventsFunc(pDev->HIFDevice, - (HIF_PENDING_EVENTS_INFO *)pIOPacket->pBuffer, + (struct hif_pending_events_info *)pIOPacket->pBuffer, pIOPacket); } else { @@ -490,7 +490,7 @@ static int ProcessPendingIRQs(struct ar6k_device *pDev, bool *pDone, bool *pASyn } if (pDev->GetPendingEventsFunc != NULL) { - HIF_PENDING_EVENTS_INFO events; + struct hif_pending_events_info events; #ifdef THREAD_X events.Polling= 0; diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h index 4f9be8a7eddd..8d0c94e7b29c 100644 --- a/drivers/staging/ath6kl/include/hif.h +++ b/drivers/staging/ath6kl/include/hif.h @@ -343,7 +343,7 @@ typedef struct osdrv_callbacks { needs to read the register table to figure out what */ #define HIF_RECV_MSG_AVAIL (1 << 1) /* pending recv packet */ -typedef struct _HIF_PENDING_EVENTS_INFO { +struct hif_pending_events_info { u32 Events; u32 LookAhead; u32 AvailableRecvBytes; @@ -351,12 +351,12 @@ typedef struct _HIF_PENDING_EVENTS_INFO { u32 Polling; u32 INT_CAUSE_REG; #endif -} HIF_PENDING_EVENTS_INFO; +}; /* function to get pending events , some HIF modules use special mechanisms * to detect packet available and other interrupts */ typedef int ( *HIF_PENDING_EVENTS_FUNC)(HIF_DEVICE *device, - HIF_PENDING_EVENTS_INFO *pEvents, + struct hif_pending_events_info *pEvents, void *AsyncContext); #define HIF_MASK_RECV true -- cgit v1.2.3 From f88902c01ba58bad05e485aaff608cdbe65c3d7f Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:47 -0700 Subject: ath6kl: remove-typedef HIF_SCATTER_ITEM remove-typedef -s HIF_SCATTER_ITEM \ "struct hif_scatter_item" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c | 2 +- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 2 +- drivers/staging/ath6kl/include/hif.h | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c index 567993f7d4ed..196d33db4470 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c @@ -306,7 +306,7 @@ int SetupHIFScatterSupport(HIF_DEVICE *device, struct hif_device_scatter_support pReqPriv->device = device; /* allocate the scatter request */ pReqPriv->pHifScatterReq = (HIF_SCATTER_REQ *)A_MALLOC(sizeof(HIF_SCATTER_REQ) + - (MAX_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(HIF_SCATTER_ITEM))); + (MAX_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(struct hif_scatter_item))); if (NULL == pReqPriv->pHifScatterReq) { A_FREE(pReqPriv); diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index f9f411ae43b3..3ebf630a15a2 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -761,7 +761,7 @@ static int DevSetupVirtualScatterSupport(struct ar6k_device *pDev) 2 * (A_GET_CACHE_LINE_BYTES()) + AR6K_MAX_TRANSFER_SIZE_PER_SCATTER; sgreqSize = sizeof(HIF_SCATTER_REQ) + - (AR6K_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(HIF_SCATTER_ITEM)); + (AR6K_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(struct hif_scatter_item)); for (i = 0; i < AR6K_SCATTER_REQS; i++) { /* allocate the scatter request, buffer info and the actual virtual buffer itself */ diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h index 8d0c94e7b29c..427e7b8c0125 100644 --- a/drivers/staging/ath6kl/include/hif.h +++ b/drivers/staging/ath6kl/include/hif.h @@ -270,11 +270,11 @@ struct hif_device_irq_yield_params { }; -typedef struct _HIF_SCATTER_ITEM { +struct hif_scatter_item { u8 *pBuffer; /* CPU accessible address of buffer */ int Length; /* length of transfer to/from this buffer */ void *pCallerContexts[2]; /* space for caller to insert a context associated with this item */ -} HIF_SCATTER_ITEM; +}; struct _HIF_SCATTER_REQ; @@ -299,7 +299,7 @@ typedef struct _HIF_SCATTER_REQ { HIF_SCATTER_METHOD ScatterMethod; /* scatter method handled by HIF */ void *HIFPrivate[4]; /* HIF private area */ u8 *pScatterBounceBuffer; /* bounce buffer for upper layers to copy to/from */ - HIF_SCATTER_ITEM ScatterList[1]; /* start of scatter list */ + struct hif_scatter_item ScatterList[1]; /* start of scatter list */ } HIF_SCATTER_REQ; typedef HIF_SCATTER_REQ * ( *HIF_ALLOCATE_SCATTER_REQUEST)(HIF_DEVICE *device); -- cgit v1.2.3 From 7038aac1165d4dcbf02fcfb9ee91ac6dc46645a2 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:48 -0700 Subject: ath6kl: remove-typedef HIF_SCATTER_REQ_PRIV remove-typedef -s HIF_SCATTER_REQ_PRIV \ "struct hif_scatter_req_priv" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- .../ath6kl/hif/sdio/linux_sdio/include/hif_internal.h | 8 +++----- .../staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c | 14 +++++++------- 2 files changed, 10 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h index e2d2266ba327..99885e39cbb8 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h @@ -47,8 +47,6 @@ #define HIF_MBOX2_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE #define HIF_MBOX3_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE -struct _HIF_SCATTER_REQ_PRIV; - typedef struct bus_request { struct bus_request *next; /* link list of available requests */ struct bus_request *inusenext; /* link list of in use requests */ @@ -59,7 +57,7 @@ typedef struct bus_request { u32 request; void *context; int status; - struct _HIF_SCATTER_REQ_PRIV *pScatterReq; /* this request is a scatter request */ + struct hif_scatter_req_priv *pScatterReq; /* this request is a scatter request */ } BUS_REQUEST; struct hif_device { @@ -100,13 +98,13 @@ void AddToAsyncList(HIF_DEVICE *device, BUS_REQUEST *busrequest); #define MAX_SCATTER_ENTRIES_PER_REQ 16 #define MAX_SCATTER_REQ_TRANSFER_SIZE 32*1024 -typedef struct _HIF_SCATTER_REQ_PRIV { +struct hif_scatter_req_priv { HIF_SCATTER_REQ *pHifScatterReq; /* HIF scatter request with allocated entries */ HIF_DEVICE *device; /* this device */ BUS_REQUEST *busrequest; /* request associated with request */ /* scatter list for linux */ struct scatterlist sgentries[MAX_SCATTER_ENTRIES_PER_REQ]; -} HIF_SCATTER_REQ_PRIV; +}; #define ATH_DEBUG_SCATTER ATH_DEBUG_MAKE_MODULE_MASK(0) diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c index 196d33db4470..9f07040e34ab 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c @@ -87,7 +87,7 @@ int DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest) struct mmc_request mmcreq; struct mmc_command cmd; struct mmc_data data; - HIF_SCATTER_REQ_PRIV *pReqPriv; + struct hif_scatter_req_priv *pReqPriv; HIF_SCATTER_REQ *pReq; int status = 0; struct scatterlist *pSg; @@ -203,7 +203,7 @@ static int HifReadWriteScatter(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq) { int status = A_EINVAL; u32 request = pReq->Request; - HIF_SCATTER_REQ_PRIV *pReqPriv = (HIF_SCATTER_REQ_PRIV *)pReq->HIFPrivate[0]; + struct hif_scatter_req_priv *pReqPriv = (struct hif_scatter_req_priv *)pReq->HIFPrivate[0]; do { @@ -279,7 +279,7 @@ int SetupHIFScatterSupport(HIF_DEVICE *device, struct hif_device_scatter_support { int status = A_ERROR; int i; - HIF_SCATTER_REQ_PRIV *pReqPriv; + struct hif_scatter_req_priv *pReqPriv; BUS_REQUEST *busrequest; do { @@ -297,11 +297,11 @@ int SetupHIFScatterSupport(HIF_DEVICE *device, struct hif_device_scatter_support for (i = 0; i < MAX_SCATTER_REQUESTS; i++) { /* allocate the private request blob */ - pReqPriv = (HIF_SCATTER_REQ_PRIV *)A_MALLOC(sizeof(HIF_SCATTER_REQ_PRIV)); + pReqPriv = (struct hif_scatter_req_priv *)A_MALLOC(sizeof(struct hif_scatter_req_priv)); if (NULL == pReqPriv) { break; } - A_MEMZERO(pReqPriv, sizeof(HIF_SCATTER_REQ_PRIV)); + A_MEMZERO(pReqPriv, sizeof(struct hif_scatter_req_priv)); /* save the device instance*/ pReqPriv->device = device; /* allocate the scatter request */ @@ -358,7 +358,7 @@ int SetupHIFScatterSupport(HIF_DEVICE *device, struct hif_device_scatter_support /* clean up scatter support */ void CleanupHIFScatterResources(HIF_DEVICE *device) { - HIF_SCATTER_REQ_PRIV *pReqPriv; + struct hif_scatter_req_priv *pReqPriv; HIF_SCATTER_REQ *pReq; /* empty the free list */ @@ -371,7 +371,7 @@ void CleanupHIFScatterResources(HIF_DEVICE *device) break; } - pReqPriv = (HIF_SCATTER_REQ_PRIV *)pReq->HIFPrivate[0]; + pReqPriv = (struct hif_scatter_req_priv *)pReq->HIFPrivate[0]; A_ASSERT(pReqPriv != NULL); if (pReqPriv->busrequest != NULL) { -- cgit v1.2.3 From 0aaabb8e9ca2478d7ce44f715c60fef4826d1f39 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:49 -0700 Subject: ath6kl: remove-typedef HIF_SCATTER_REQ This requird two passes: remove-typedef -s HIF_SCATTER_REQ \ "struct hif_scatter_req" drivers/staging/ath6kl/ remove-typedef -s _HIF_SCATTER_REQ \ "struct hif_scatter_req" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- .../hif/sdio/linux_sdio/include/hif_internal.h | 2 +- .../ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c | 16 ++++++++-------- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 22 +++++++++++----------- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 6 +++--- drivers/staging/ath6kl/htc2/htc_recv.c | 4 ++-- drivers/staging/ath6kl/htc2/htc_send.c | 4 ++-- drivers/staging/ath6kl/include/hif.h | 15 +++++++-------- 7 files changed, 34 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h index 99885e39cbb8..04fc284f4a60 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h @@ -99,7 +99,7 @@ void AddToAsyncList(HIF_DEVICE *device, BUS_REQUEST *busrequest); #define MAX_SCATTER_REQ_TRANSFER_SIZE 32*1024 struct hif_scatter_req_priv { - HIF_SCATTER_REQ *pHifScatterReq; /* HIF scatter request with allocated entries */ + struct hif_scatter_req *pHifScatterReq; /* HIF scatter request with allocated entries */ HIF_DEVICE *device; /* this device */ BUS_REQUEST *busrequest; /* request associated with request */ /* scatter list for linux */ diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c index 9f07040e34ab..2c64abe04d61 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c @@ -48,7 +48,7 @@ (((address) & 0x1FFFF) << 9) | \ ((bytes_blocks) & 0x1FF) -static void FreeScatterReq(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq) +static void FreeScatterReq(HIF_DEVICE *device, struct hif_scatter_req *pReq) { unsigned long flag; @@ -60,7 +60,7 @@ static void FreeScatterReq(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq) } -static HIF_SCATTER_REQ *AllocScatterReq(HIF_DEVICE *device) +static struct hif_scatter_req *AllocScatterReq(HIF_DEVICE *device) { struct dl_list *pItem; unsigned long flag; @@ -72,7 +72,7 @@ static HIF_SCATTER_REQ *AllocScatterReq(HIF_DEVICE *device) spin_unlock_irqrestore(&device->lock, flag); if (pItem != NULL) { - return A_CONTAINING_STRUCT(pItem, HIF_SCATTER_REQ, ListLink); + return A_CONTAINING_STRUCT(pItem, struct hif_scatter_req, ListLink); } return NULL; @@ -88,7 +88,7 @@ int DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest) struct mmc_command cmd; struct mmc_data data; struct hif_scatter_req_priv *pReqPriv; - HIF_SCATTER_REQ *pReq; + struct hif_scatter_req *pReq; int status = 0; struct scatterlist *pSg; @@ -199,7 +199,7 @@ int DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest) } /* callback to issue a read-write scatter request */ -static int HifReadWriteScatter(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq) +static int HifReadWriteScatter(HIF_DEVICE *device, struct hif_scatter_req *pReq) { int status = A_EINVAL; u32 request = pReq->Request; @@ -305,7 +305,7 @@ int SetupHIFScatterSupport(HIF_DEVICE *device, struct hif_device_scatter_support /* save the device instance*/ pReqPriv->device = device; /* allocate the scatter request */ - pReqPriv->pHifScatterReq = (HIF_SCATTER_REQ *)A_MALLOC(sizeof(HIF_SCATTER_REQ) + + pReqPriv->pHifScatterReq = (struct hif_scatter_req *)A_MALLOC(sizeof(struct hif_scatter_req) + (MAX_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(struct hif_scatter_item))); if (NULL == pReqPriv->pHifScatterReq) { @@ -313,7 +313,7 @@ int SetupHIFScatterSupport(HIF_DEVICE *device, struct hif_device_scatter_support break; } /* just zero the main part of the scatter request */ - A_MEMZERO(pReqPriv->pHifScatterReq, sizeof(HIF_SCATTER_REQ)); + A_MEMZERO(pReqPriv->pHifScatterReq, sizeof(struct hif_scatter_req)); /* back pointer to the private struct */ pReqPriv->pHifScatterReq->HIFPrivate[0] = pReqPriv; /* allocate a bus request for this scatter request */ @@ -359,7 +359,7 @@ int SetupHIFScatterSupport(HIF_DEVICE *device, struct hif_device_scatter_support void CleanupHIFScatterResources(HIF_DEVICE *device) { struct hif_scatter_req_priv *pReqPriv; - HIF_SCATTER_REQ *pReq; + struct hif_scatter_req *pReq; /* empty the free list */ diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index 3ebf630a15a2..c780e4fb49ba 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -587,7 +587,7 @@ void DevDumpRegisters(struct ar6k_device *pDev, #define DEV_GET_VIRT_DMA_INFO(p) ((struct dev_scatter_dma_virtual_info *)((p)->HIFPrivate[0])) -static HIF_SCATTER_REQ *DevAllocScatterReq(HIF_DEVICE *Context) +static struct hif_scatter_req *DevAllocScatterReq(HIF_DEVICE *Context) { struct dl_list *pItem; struct ar6k_device *pDev = (struct ar6k_device *)Context; @@ -595,12 +595,12 @@ static HIF_SCATTER_REQ *DevAllocScatterReq(HIF_DEVICE *Context) pItem = DL_ListRemoveItemFromHead(&pDev->ScatterReqHead); UNLOCK_AR6K(pDev); if (pItem != NULL) { - return A_CONTAINING_STRUCT(pItem, HIF_SCATTER_REQ, ListLink); + return A_CONTAINING_STRUCT(pItem, struct hif_scatter_req, ListLink); } return NULL; } -static void DevFreeScatterReq(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) +static void DevFreeScatterReq(HIF_DEVICE *Context, struct hif_scatter_req *pReq) { struct ar6k_device *pDev = (struct ar6k_device *)Context; LOCK_AR6K(pDev); @@ -608,7 +608,7 @@ static void DevFreeScatterReq(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) UNLOCK_AR6K(pDev); } -int DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, bool FromDMA) +int DevCopyScatterListToFromDMABuffer(struct hif_scatter_req *pReq, bool FromDMA) { u8 *pDMABuffer = NULL; int i, remaining; @@ -651,7 +651,7 @@ int DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, bool FromDMA) static void DevReadWriteScatterAsyncHandler(void *Context, HTC_PACKET *pPacket) { struct ar6k_device *pDev = (struct ar6k_device *)Context; - HIF_SCATTER_REQ *pReq = (HIF_SCATTER_REQ *)pPacket->pPktContext; + struct hif_scatter_req *pReq = (struct hif_scatter_req *)pPacket->pPktContext; AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevReadWriteScatterAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); @@ -664,7 +664,7 @@ static void DevReadWriteScatterAsyncHandler(void *Context, HTC_PACKET *pPacket) AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-DevReadWriteScatterAsyncHandler \n")); } -static int DevReadWriteScatter(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) +static int DevReadWriteScatter(HIF_DEVICE *Context, struct hif_scatter_req *pReq) { struct ar6k_device *pDev = (struct ar6k_device *)Context; int status = 0; @@ -736,7 +736,7 @@ static int DevReadWriteScatter(HIF_DEVICE *Context, HIF_SCATTER_REQ *pReq) static void DevCleanupVirtualScatterSupport(struct ar6k_device *pDev) { - HIF_SCATTER_REQ *pReq; + struct hif_scatter_req *pReq; while (1) { pReq = DevAllocScatterReq((HIF_DEVICE *)pDev); @@ -755,17 +755,17 @@ static int DevSetupVirtualScatterSupport(struct ar6k_device *pDev) int bufferSize, sgreqSize; int i; struct dev_scatter_dma_virtual_info *pVirtualInfo; - HIF_SCATTER_REQ *pReq; + struct hif_scatter_req *pReq; bufferSize = sizeof(struct dev_scatter_dma_virtual_info) + 2 * (A_GET_CACHE_LINE_BYTES()) + AR6K_MAX_TRANSFER_SIZE_PER_SCATTER; - sgreqSize = sizeof(HIF_SCATTER_REQ) + + sgreqSize = sizeof(struct hif_scatter_req) + (AR6K_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(struct hif_scatter_item)); for (i = 0; i < AR6K_SCATTER_REQS; i++) { /* allocate the scatter request, buffer info and the actual virtual buffer itself */ - pReq = (HIF_SCATTER_REQ *)A_MALLOC(sgreqSize + bufferSize); + pReq = (struct hif_scatter_req *)A_MALLOC(sgreqSize + bufferSize); if (NULL == pReq) { status = A_NO_MEMORY; @@ -885,7 +885,7 @@ int DevSetupMsgBundling(struct ar6k_device *pDev, int MaxMsgsPerTransfer) return status; } -int DevSubmitScatterRequest(struct ar6k_device *pDev, HIF_SCATTER_REQ *pScatterReq, bool Read, bool Async) +int DevSubmitScatterRequest(struct ar6k_device *pDev, struct hif_scatter_req *pScatterReq, bool Read, bool Async) { int status; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index 08e9ef294ac9..baad0bf472d0 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -272,7 +272,7 @@ static INLINE int DevRecvPacket(struct ar6k_device *pDev, HTC_PACKET *pPacket, u * */ -int DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, bool FromDMA); +int DevCopyScatterListToFromDMABuffer(struct hif_scatter_req *pReq, bool FromDMA); /* copy any READ data back into scatter list */ #define DEV_FINISH_SCATTER_OPERATION(pR) \ @@ -287,7 +287,7 @@ do { \ } while (0) /* copy any WRITE data to bounce buffer */ -static INLINE int DEV_PREPARE_SCATTER_OPERATION(HIF_SCATTER_REQ *pReq) { +static INLINE int DEV_PREPARE_SCATTER_OPERATION(struct hif_scatter_req *pReq) { if ((pReq->Request & HIF_WRITE) && (pReq->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) { return DevCopyScatterListToFromDMABuffer(pReq,TO_DMA_BUFFER); } else { @@ -315,7 +315,7 @@ int DevCleanupMsgBundling(struct ar6k_device *pDev); #define DEV_SCATTER_WRITE false #define DEV_SCATTER_ASYNC true #define DEV_SCATTER_SYNC false -int DevSubmitScatterRequest(struct ar6k_device *pDev, HIF_SCATTER_REQ *pScatterReq, bool Read, bool Async); +int DevSubmitScatterRequest(struct ar6k_device *pDev, struct hif_scatter_req *pScatterReq, bool Read, bool Async); #ifdef MBOXHW_UNIT_TEST int DoMboxHWTest(struct ar6k_device *pDev); diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c index daa6efcf2144..7a333edca8be 100644 --- a/drivers/staging/ath6kl/htc2/htc_recv.c +++ b/drivers/staging/ath6kl/htc2/htc_recv.c @@ -879,7 +879,7 @@ static int AllocAndPrepareRxPackets(HTC_TARGET *target, return status; } -static void HTCAsyncRecvScatterCompletion(HIF_SCATTER_REQ *pScatterReq) +static void HTCAsyncRecvScatterCompletion(struct hif_scatter_req *pScatterReq) { int i; HTC_PACKET *pPacket; @@ -991,7 +991,7 @@ static int HTCIssueRecvPacketBundle(HTC_TARGET *target, bool PartialBundle) { int status = 0; - HIF_SCATTER_REQ *pScatterReq; + struct hif_scatter_req *pScatterReq; int i, totalLength; int pktsToScatter; HTC_PACKET *pPacket; diff --git a/drivers/staging/ath6kl/htc2/htc_send.c b/drivers/staging/ath6kl/htc2/htc_send.c index a31acae9620e..f133d93bf209 100644 --- a/drivers/staging/ath6kl/htc2/htc_send.c +++ b/drivers/staging/ath6kl/htc2/htc_send.c @@ -264,7 +264,7 @@ static INLINE void GetHTCSendPackets(HTC_TARGET *target, } -static void HTCAsyncSendScatterCompletion(HIF_SCATTER_REQ *pScatterReq) +static void HTCAsyncSendScatterCompletion(struct hif_scatter_req *pScatterReq) { int i; HTC_PACKET *pPacket; @@ -316,7 +316,7 @@ static void HTCIssueSendBundle(HTC_ENDPOINT *pEndpoint, { int pktsToScatter; unsigned int scatterSpaceRemaining; - HIF_SCATTER_REQ *pScatterReq = NULL; + struct hif_scatter_req *pScatterReq = NULL; int i, packetsInScatterReq; unsigned int transferLength; HTC_PACKET *pPacket; diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h index 427e7b8c0125..3dcb78713b6b 100644 --- a/drivers/staging/ath6kl/include/hif.h +++ b/drivers/staging/ath6kl/include/hif.h @@ -276,9 +276,8 @@ struct hif_scatter_item { void *pCallerContexts[2]; /* space for caller to insert a context associated with this item */ }; -struct _HIF_SCATTER_REQ; - -typedef void ( *HIF_SCATTER_COMP_CB)(struct _HIF_SCATTER_REQ *); +struct hif_scatter_req; +typedef void ( *HIF_SCATTER_COMP_CB)(struct hif_scatter_req *); typedef enum _HIF_SCATTER_METHOD { HIF_SCATTER_NONE = 0, @@ -286,7 +285,7 @@ typedef enum _HIF_SCATTER_METHOD { HIF_SCATTER_DMA_BOUNCE, /* Uses SG DMA but HIF layer uses an internal bounce buffer */ } HIF_SCATTER_METHOD; -typedef struct _HIF_SCATTER_REQ { +struct hif_scatter_req { struct dl_list ListLink; /* link management */ u32 Address; /* address for the read/write operation */ u32 Request; /* request flags */ @@ -300,11 +299,11 @@ typedef struct _HIF_SCATTER_REQ { void *HIFPrivate[4]; /* HIF private area */ u8 *pScatterBounceBuffer; /* bounce buffer for upper layers to copy to/from */ struct hif_scatter_item ScatterList[1]; /* start of scatter list */ -} HIF_SCATTER_REQ; +}; -typedef HIF_SCATTER_REQ * ( *HIF_ALLOCATE_SCATTER_REQUEST)(HIF_DEVICE *device); -typedef void ( *HIF_FREE_SCATTER_REQUEST)(HIF_DEVICE *device, HIF_SCATTER_REQ *request); -typedef int ( *HIF_READWRITE_SCATTER)(HIF_DEVICE *device, HIF_SCATTER_REQ *request); +typedef struct hif_scatter_req * ( *HIF_ALLOCATE_SCATTER_REQUEST)(HIF_DEVICE *device); +typedef void ( *HIF_FREE_SCATTER_REQUEST)(HIF_DEVICE *device, struct hif_scatter_req *request); +typedef int ( *HIF_READWRITE_SCATTER)(HIF_DEVICE *device, struct hif_scatter_req *request); struct hif_device_scatter_support_info { /* information returned from HIF layer */ -- cgit v1.2.3 From 3e5074e94f69038904101c203d62a7dbbb53e399 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:50 -0700 Subject: ath6kl: remove-typedef HTC_CONTROL_BUFFER remove-typedef -s HTC_CONTROL_BUFFER \ "struct htc_control_buffer" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/htc_internal.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h index 8bc3162cdfb9..e3857cfd5002 100644 --- a/drivers/staging/ath6kl/htc2/htc_internal.h +++ b/drivers/staging/ath6kl/htc2/htc_internal.h @@ -99,10 +99,10 @@ typedef struct _HTC_ENDPOINT { #define NUM_CONTROL_TX_BUFFERS 2 #define NUM_CONTROL_RX_BUFFERS (NUM_CONTROL_BUFFERS - NUM_CONTROL_TX_BUFFERS) -typedef struct HTC_CONTROL_BUFFER { +struct htc_control_buffer { HTC_PACKET HtcPacket; u8 *Buffer; -} HTC_CONTROL_BUFFER; +}; #define HTC_RECV_WAIT_BUFFERS (1 << 0) #define HTC_OP_STATE_STOPPING (1 << 0) @@ -110,7 +110,7 @@ typedef struct HTC_CONTROL_BUFFER { /* our HTC target state */ typedef struct _HTC_TARGET { HTC_ENDPOINT EndPoint[ENDPOINT_MAX]; - HTC_CONTROL_BUFFER HTCControlBuffers[NUM_CONTROL_BUFFERS]; + struct htc_control_buffer HTCControlBuffers[NUM_CONTROL_BUFFERS]; HTC_ENDPOINT_CREDIT_DIST *EpCreditDistributionListHead; HTC_PACKET_QUEUE ControlBufferTXFreeList; HTC_PACKET_QUEUE ControlBufferRXFreeList; -- cgit v1.2.3 From df5a718f0f868659224015e6f71930e507262b22 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:51 -0700 Subject: ath6kl: remove-typedef HTC_ENDPOINT remove-typedef -s HTC_ENDPOINT \ "struct htc_endpoint" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/htc.c | 2 +- drivers/staging/ath6kl/htc2/htc_internal.h | 6 +++--- drivers/staging/ath6kl/htc2/htc_recv.c | 24 ++++++++++----------- drivers/staging/ath6kl/htc2/htc_send.c | 34 +++++++++++++++--------------- drivers/staging/ath6kl/htc2/htc_services.c | 2 +- 5 files changed, 34 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index bb999b674537..e897c0cb319a 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -438,7 +438,7 @@ int HTCStart(HTC_HANDLE HTCHandle) static void ResetEndpointStates(HTC_TARGET *target) { - HTC_ENDPOINT *pEndpoint; + struct htc_endpoint *pEndpoint; int i; for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) { diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h index e3857cfd5002..a6eaa1bbac3d 100644 --- a/drivers/staging/ath6kl/htc2/htc_internal.h +++ b/drivers/staging/ath6kl/htc2/htc_internal.h @@ -65,7 +65,7 @@ extern "C" { #define HTC_SCATTER_REQ_FLAGS_PARTIAL_BUNDLE (1 << 0) -typedef struct _HTC_ENDPOINT { +struct htc_endpoint { HTC_ENDPOINT_ID Id; HTC_SERVICE_ID ServiceID; /* service ID this endpoint is bound to non-zero value means this endpoint is in use */ @@ -85,7 +85,7 @@ typedef struct _HTC_ENDPOINT { #ifdef HTC_EP_STAT_PROFILING HTC_ENDPOINT_STATS EndPointStats; /* endpoint statistics */ #endif -} HTC_ENDPOINT; +}; #ifdef HTC_EP_STAT_PROFILING #define INC_HTC_EP_STAT(p,stat,count) (p)->EndPointStats.stat += (count); @@ -109,7 +109,7 @@ struct htc_control_buffer { /* our HTC target state */ typedef struct _HTC_TARGET { - HTC_ENDPOINT EndPoint[ENDPOINT_MAX]; + struct htc_endpoint EndPoint[ENDPOINT_MAX]; struct htc_control_buffer HTCControlBuffers[NUM_CONTROL_BUFFERS]; HTC_ENDPOINT_CREDIT_DIST *EpCreditDistributionListHead; HTC_PACKET_QUEUE ControlBufferTXFreeList; diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c index 7a333edca8be..4095f8e07e53 100644 --- a/drivers/staging/ath6kl/htc2/htc_recv.c +++ b/drivers/staging/ath6kl/htc2/htc_recv.c @@ -50,7 +50,7 @@ #define HTC_RX_STAT_PROFILE(t,ep,lookAhead) #endif -static void DoRecvCompletion(HTC_ENDPOINT *pEndpoint, +static void DoRecvCompletion(struct htc_endpoint *pEndpoint, HTC_PACKET_QUEUE *pQueueToIndicate) { @@ -432,7 +432,7 @@ static INLINE void HTCAsyncRecvCheckMorePackets(HTC_TARGET *target, } /* unload the recv completion queue */ -static INLINE void DrainRecvIndicationQueue(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint) +static INLINE void DrainRecvIndicationQueue(HTC_TARGET *target, struct htc_endpoint *pEndpoint) { HTC_PACKET_QUEUE recvCompletions; @@ -497,7 +497,7 @@ static INLINE void DrainRecvIndicationQueue(HTC_TARGET *target, HTC_ENDPOINT *pE /* note: this function can be called with the RX lock held */ static INLINE void SetRxPacketIndicationFlags(u32 LookAhead, - HTC_ENDPOINT *pEndpoint, + struct htc_endpoint *pEndpoint, HTC_PACKET *pPacket) { HTC_FRAME_HDR *pHdr = (HTC_FRAME_HDR *)&LookAhead; @@ -518,7 +518,7 @@ static INLINE void SetRxPacketIndicationFlags(u32 LookAhead, void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket) { HTC_TARGET *target = (HTC_TARGET *)Context; - HTC_ENDPOINT *pEndpoint; + struct htc_endpoint *pEndpoint; u32 nextLookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; int numLookAheads = 0; int status; @@ -689,7 +689,7 @@ int HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket) static int AllocAndPrepareRxPackets(HTC_TARGET *target, u32 LookAheads[], int Messages, - HTC_ENDPOINT *pEndpoint, + struct htc_endpoint *pEndpoint, HTC_PACKET_QUEUE *pQueue) { int status = 0; @@ -883,7 +883,7 @@ static void HTCAsyncRecvScatterCompletion(struct hif_scatter_req *pScatterReq) { int i; HTC_PACKET *pPacket; - HTC_ENDPOINT *pEndpoint; + struct htc_endpoint *pEndpoint; u32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; int numLookAheads = 0; HTC_TARGET *target = (HTC_TARGET *)pScatterReq->Context; @@ -1102,7 +1102,7 @@ static int HTCIssueRecvPacketBundle(HTC_TARGET *target, return status; } -static INLINE void CheckRecvWaterMark(HTC_ENDPOINT *pEndpoint) +static INLINE void CheckRecvWaterMark(struct htc_endpoint *pEndpoint) { /* see if endpoint is using a refill watermark * ** no need to use a lock here, since we are only inspecting... @@ -1122,7 +1122,7 @@ int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLook HTC_TARGET *target = (HTC_TARGET *)Context; int status = 0; HTC_PACKET *pPacket; - HTC_ENDPOINT *pEndpoint; + struct htc_endpoint *pEndpoint; bool asyncProc = false; u32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; int pktsFetched; @@ -1388,7 +1388,7 @@ int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLook int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - HTC_ENDPOINT *pEndpoint; + struct htc_endpoint *pEndpoint; bool unblockRecv = false; int status = 0; HTC_PACKET *pFirstPacket; @@ -1486,7 +1486,7 @@ void HTCUnblockRecv(HTC_HANDLE HTCHandle) } } -static void HTCFlushRxQueue(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint, HTC_PACKET_QUEUE *pQueue) +static void HTCFlushRxQueue(HTC_TARGET *target, struct htc_endpoint *pEndpoint, HTC_PACKET_QUEUE *pQueue) { HTC_PACKET *pPacket; HTC_PACKET_QUEUE container; @@ -1512,7 +1512,7 @@ static void HTCFlushRxQueue(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint, HTC_PAC UNLOCK_HTC_RX(target); } -static void HTCFlushEndpointRX(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint) +static void HTCFlushEndpointRX(HTC_TARGET *target, struct htc_endpoint *pEndpoint) { /* flush any recv indications not already made */ HTCFlushRxQueue(target,pEndpoint,&pEndpoint->RecvIndicationQueue); @@ -1522,7 +1522,7 @@ static void HTCFlushEndpointRX(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint) void HTCFlushRecvBuffers(HTC_TARGET *target) { - HTC_ENDPOINT *pEndpoint; + struct htc_endpoint *pEndpoint; int i; for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) { diff --git a/drivers/staging/ath6kl/htc2/htc_send.c b/drivers/staging/ath6kl/htc2/htc_send.c index f133d93bf209..4e1d9bc732d0 100644 --- a/drivers/staging/ath6kl/htc2/htc_send.c +++ b/drivers/staging/ath6kl/htc2/htc_send.c @@ -43,7 +43,7 @@ typedef enum _HTC_SEND_QUEUE_RESULT { (reason)); \ } -static void DoSendCompletion(HTC_ENDPOINT *pEndpoint, +static void DoSendCompletion(struct htc_endpoint *pEndpoint, HTC_PACKET_QUEUE *pQueueToIndicate) { do { @@ -77,7 +77,7 @@ static void DoSendCompletion(HTC_ENDPOINT *pEndpoint, } /* do final completion on sent packet */ -static INLINE void CompleteSentPacket(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint, HTC_PACKET *pPacket) +static INLINE void CompleteSentPacket(HTC_TARGET *target, struct htc_endpoint *pEndpoint, HTC_PACKET *pPacket) { pPacket->Completion = NULL; @@ -104,7 +104,7 @@ static INLINE void CompleteSentPacket(HTC_TARGET *target, HTC_ENDPOINT *pEndpoin static void HTCSendPktCompletionHandler(void *Context, HTC_PACKET *pPacket) { HTC_TARGET *target = (HTC_TARGET *)Context; - HTC_ENDPOINT *pEndpoint = &target->EndPoint[pPacket->Endpoint]; + struct htc_endpoint *pEndpoint = &target->EndPoint[pPacket->Endpoint]; HTC_PACKET_QUEUE container; CompleteSentPacket(target,pEndpoint,pPacket); @@ -147,7 +147,7 @@ int HTCIssueSend(HTC_TARGET *target, HTC_PACKET *pPacket) /* get HTC send packets from the TX queue on an endpoint */ static INLINE void GetHTCSendPackets(HTC_TARGET *target, - HTC_ENDPOINT *pEndpoint, + struct htc_endpoint *pEndpoint, HTC_PACKET_QUEUE *pQueue) { int creditsRequired; @@ -268,7 +268,7 @@ static void HTCAsyncSendScatterCompletion(struct hif_scatter_req *pScatterReq) { int i; HTC_PACKET *pPacket; - HTC_ENDPOINT *pEndpoint = (HTC_ENDPOINT *)pScatterReq->Context; + struct htc_endpoint *pEndpoint = (struct htc_endpoint *)pScatterReq->Context; HTC_TARGET *target = (HTC_TARGET *)pEndpoint->target; int status = 0; HTC_PACKET_QUEUE sendCompletes; @@ -309,7 +309,7 @@ static void HTCAsyncSendScatterCompletion(struct hif_scatter_req *pScatterReq) * - a message that will consume a partial credit will stop the bundling process early * - we drop below the minimum number of messages for a bundle * */ -static void HTCIssueSendBundle(HTC_ENDPOINT *pEndpoint, +static void HTCIssueSendBundle(struct htc_endpoint *pEndpoint, HTC_PACKET_QUEUE *pQueue, int *pBundlesSent, int *pTotalBundlesPkts) @@ -478,7 +478,7 @@ static void HTCIssueSendBundle(HTC_ENDPOINT *pEndpoint, * if there are no credits, the packet(s) remains in the queue. * this function returns the result of the attempt to send a queue of HTC packets */ static HTC_SEND_QUEUE_RESULT HTCTrySend(HTC_TARGET *target, - HTC_ENDPOINT *pEndpoint, + struct htc_endpoint *pEndpoint, HTC_PACKET_QUEUE *pCallersSendQueue) { HTC_PACKET_QUEUE sendQueue; /* temp queue to hold packets at various stages */ @@ -671,7 +671,7 @@ static HTC_SEND_QUEUE_RESULT HTCTrySend(HTC_TARGET *target, int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - HTC_ENDPOINT *pEndpoint; + struct htc_endpoint *pEndpoint; HTC_PACKET *pPacket; AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCSendPktsMultiple: Queue: 0x%lX, Pkts %d \n", @@ -723,7 +723,7 @@ int HTCSendPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket) /* check TX queues to drain because of credit distribution update */ static INLINE void HTCCheckEndpointTxQueues(HTC_TARGET *target) { - HTC_ENDPOINT *pEndpoint; + struct htc_endpoint *pEndpoint; HTC_ENDPOINT_CREDIT_DIST *pDistItem; AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCCheckEndpointTxQueues \n")); @@ -734,7 +734,7 @@ static INLINE void HTCCheckEndpointTxQueues(HTC_TARGET *target) * NOTE: no locks need to be taken since the distribution list * is not dynamic (cannot be re-ordered) and we are not modifying any state */ while (pDistItem != NULL) { - pEndpoint = (HTC_ENDPOINT *)pDistItem->pHTCReserved; + pEndpoint = (struct htc_endpoint *)pDistItem->pHTCReserved; if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) > 0) { AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Ep %d has %d credits and %d Packets in TX Queue \n", @@ -756,7 +756,7 @@ static INLINE void HTCCheckEndpointTxQueues(HTC_TARGET *target) void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint) { int i; - HTC_ENDPOINT *pEndpoint; + struct htc_endpoint *pEndpoint; int totalCredits = 0; bool doDist = false; @@ -838,7 +838,7 @@ void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEnt } /* flush endpoint TX queue */ -static void HTCFlushEndpointTX(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint, HTC_TX_TAG Tag) +static void HTCFlushEndpointTX(HTC_TARGET *target, struct htc_endpoint *pEndpoint, HTC_TX_TAG Tag) { HTC_PACKET *pPacket; HTC_PACKET_QUEUE discardQueue; @@ -895,7 +895,7 @@ void DumpCreditDist(HTC_ENDPOINT_CREDIT_DIST *pEPDist) AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsPerMaxMsg : %d \n", pEPDist->TxCreditsPerMaxMsg)); AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsToDist : %d \n", pEPDist->TxCreditsToDist)); AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxQueueDepth : %d \n", - HTC_PACKET_QUEUE_DEPTH(&((HTC_ENDPOINT *)pEPDist->pHTCReserved)->TxQueue))); + HTC_PACKET_QUEUE_DEPTH(&((struct htc_endpoint *)pEPDist->pHTCReserved)->TxQueue))); AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("----------------------------------------------------\n")); } @@ -919,7 +919,7 @@ void DumpCreditDistStates(HTC_TARGET *target) /* flush all send packets from all endpoint queues */ void HTCFlushSendPkts(HTC_TARGET *target) { - HTC_ENDPOINT *pEndpoint; + struct htc_endpoint *pEndpoint; int i; if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_TRC)) { @@ -942,7 +942,7 @@ void HTCFlushSendPkts(HTC_TARGET *target) void HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG Tag) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - HTC_ENDPOINT *pEndpoint = &target->EndPoint[Endpoint]; + struct htc_endpoint *pEndpoint = &target->EndPoint[Endpoint]; if (pEndpoint->ServiceID == 0) { AR_DEBUG_ASSERT(false); @@ -959,7 +959,7 @@ void HTCIndicateActivityChange(HTC_HANDLE HTCHandle, bool Active) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - HTC_ENDPOINT *pEndpoint = &target->EndPoint[Endpoint]; + struct htc_endpoint *pEndpoint = &target->EndPoint[Endpoint]; bool doDist = false; if (pEndpoint->ServiceID == 0) { @@ -1009,7 +1009,7 @@ bool HTCIsEndpointActive(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - HTC_ENDPOINT *pEndpoint = &target->EndPoint[Endpoint]; + struct htc_endpoint *pEndpoint = &target->EndPoint[Endpoint]; if (pEndpoint->ServiceID == 0) { return false; diff --git a/drivers/staging/ath6kl/htc2/htc_services.c b/drivers/staging/ath6kl/htc2/htc_services.c index 61a332e856b1..2f999892bd94 100644 --- a/drivers/staging/ath6kl/htc2/htc_services.c +++ b/drivers/staging/ath6kl/htc2/htc_services.c @@ -132,7 +132,7 @@ int HTCConnectService(HTC_HANDLE HTCHandle, HTC_CONNECT_SERVICE_RESPONSE_MSG *pResponseMsg; HTC_CONNECT_SERVICE_MSG *pConnectMsg; HTC_ENDPOINT_ID assignedEndpoint = ENDPOINT_MAX; - HTC_ENDPOINT *pEndpoint; + struct htc_endpoint *pEndpoint; unsigned int maxMsgSize = 0; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCConnectService, target:0x%lX SvcID:0x%X \n", -- cgit v1.2.3 From 57c9d5b3304ab84fcc26851dd02b453e1cf3b191 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:52 -0700 Subject: ath6kl: remove-typedef HTC_ENDPOINT_CREDIT_DIST This required two passes: remove-typedef -s HTC_ENDPOINT_CREDIT_DIST \ "struct htc_endpoint_credit_dist" drivers/staging/ath6kl/ remove-typedef -s _HTC_ENDPOINT_CREDIT_DIST \ "struct htc_endpoint_credit_dist" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/htc_internal.h | 6 +++--- drivers/staging/ath6kl/htc2/htc_send.c | 6 +++--- drivers/staging/ath6kl/htc2/htc_services.c | 12 ++++++------ drivers/staging/ath6kl/include/common_drv.h | 2 +- drivers/staging/ath6kl/include/htc_api.h | 12 ++++++------ drivers/staging/ath6kl/miscdrv/credit_dist.c | 22 +++++++++++----------- 6 files changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h index a6eaa1bbac3d..d726a028456c 100644 --- a/drivers/staging/ath6kl/htc2/htc_internal.h +++ b/drivers/staging/ath6kl/htc2/htc_internal.h @@ -71,7 +71,7 @@ struct htc_endpoint { non-zero value means this endpoint is in use */ HTC_PACKET_QUEUE TxQueue; /* HTC frame buffer TX queue */ HTC_PACKET_QUEUE RxBuffers; /* HTC frame buffer RX list */ - HTC_ENDPOINT_CREDIT_DIST CreditDist; /* credit distribution structure (exposed to driver layer) */ + struct htc_endpoint_credit_dist CreditDist; /* credit distribution structure (exposed to driver layer) */ HTC_EP_CALLBACKS EpCallBacks; /* callbacks associated with this endpoint */ int MaxTxQueueDepth; /* max depth of the TX queue before we need to call driver's full handler */ @@ -111,7 +111,7 @@ struct htc_control_buffer { typedef struct _HTC_TARGET { struct htc_endpoint EndPoint[ENDPOINT_MAX]; struct htc_control_buffer HTCControlBuffers[NUM_CONTROL_BUFFERS]; - HTC_ENDPOINT_CREDIT_DIST *EpCreditDistributionListHead; + struct htc_endpoint_credit_dist *EpCreditDistributionListHead; HTC_PACKET_QUEUE ControlBufferTXFreeList; HTC_PACKET_QUEUE ControlBufferRXFreeList; HTC_CREDIT_DIST_CALLBACK DistributeCredits; @@ -176,7 +176,7 @@ void HTCFlushRecvBuffers(HTC_TARGET *target); void HTCFlushSendPkts(HTC_TARGET *target); #ifdef ATH_DEBUG_MODULE -void DumpCreditDist(HTC_ENDPOINT_CREDIT_DIST *pEPDist); +void DumpCreditDist(struct htc_endpoint_credit_dist *pEPDist); void DumpCreditDistStates(HTC_TARGET *target); void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription); #endif diff --git a/drivers/staging/ath6kl/htc2/htc_send.c b/drivers/staging/ath6kl/htc2/htc_send.c index 4e1d9bc732d0..b3135735bb9a 100644 --- a/drivers/staging/ath6kl/htc2/htc_send.c +++ b/drivers/staging/ath6kl/htc2/htc_send.c @@ -724,7 +724,7 @@ int HTCSendPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket) static INLINE void HTCCheckEndpointTxQueues(HTC_TARGET *target) { struct htc_endpoint *pEndpoint; - HTC_ENDPOINT_CREDIT_DIST *pDistItem; + struct htc_endpoint_credit_dist *pDistItem; AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCCheckEndpointTxQueues \n")); pDistItem = target->EpCreditDistributionListHead; @@ -879,7 +879,7 @@ static void HTCFlushEndpointTX(HTC_TARGET *target, struct htc_endpoint *pEndpoin } -void DumpCreditDist(HTC_ENDPOINT_CREDIT_DIST *pEPDist) +void DumpCreditDist(struct htc_endpoint_credit_dist *pEPDist) { AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("--- EP : %d ServiceID: 0x%X --------------\n", pEPDist->Endpoint, pEPDist->ServiceID)); @@ -901,7 +901,7 @@ void DumpCreditDist(HTC_ENDPOINT_CREDIT_DIST *pEPDist) void DumpCreditDistStates(HTC_TARGET *target) { - HTC_ENDPOINT_CREDIT_DIST *pEPList = target->EpCreditDistributionListHead; + struct htc_endpoint_credit_dist *pEPList = target->EpCreditDistributionListHead; while (pEPList != NULL) { DumpCreditDist(pEPList); diff --git a/drivers/staging/ath6kl/htc2/htc_services.c b/drivers/staging/ath6kl/htc2/htc_services.c index 2f999892bd94..34bba7e8f416 100644 --- a/drivers/staging/ath6kl/htc2/htc_services.c +++ b/drivers/staging/ath6kl/htc2/htc_services.c @@ -307,9 +307,9 @@ int HTCConnectService(HTC_HANDLE HTCHandle, return status; } -static void AddToEndpointDistList(HTC_TARGET *target, HTC_ENDPOINT_CREDIT_DIST *pEpDist) +static void AddToEndpointDistList(HTC_TARGET *target, struct htc_endpoint_credit_dist *pEpDist) { - HTC_ENDPOINT_CREDIT_DIST *pCurEntry,*pLastEntry; + struct htc_endpoint_credit_dist *pCurEntry,*pLastEntry; if (NULL == target->EpCreditDistributionListHead) { target->EpCreditDistributionListHead = pEpDist; @@ -336,10 +336,10 @@ static void AddToEndpointDistList(HTC_TARGET *target, HTC_ENDPOINT_CREDIT_DIST * /* default credit init callback */ static void HTCDefaultCreditInit(void *Context, - HTC_ENDPOINT_CREDIT_DIST *pEPList, + struct htc_endpoint_credit_dist *pEPList, int TotalCredits) { - HTC_ENDPOINT_CREDIT_DIST *pCurEpDist; + struct htc_endpoint_credit_dist *pCurEpDist; int totalEps = 0; int creditsPerEndpoint; @@ -379,10 +379,10 @@ static void HTCDefaultCreditInit(void *Context, /* default credit distribution callback, NOTE, this callback holds the TX lock */ void HTCDefaultCreditDist(void *Context, - HTC_ENDPOINT_CREDIT_DIST *pEPDistList, + struct htc_endpoint_credit_dist *pEPDistList, HTC_CREDIT_DIST_REASON Reason) { - HTC_ENDPOINT_CREDIT_DIST *pCurEpDist; + struct htc_endpoint_credit_dist *pCurEpDist; if (Reason == HTC_CREDIT_DIST_SEND_COMPLETE) { pCurEpDist = pEPDistList; diff --git a/drivers/staging/ath6kl/include/common_drv.h b/drivers/staging/ath6kl/include/common_drv.h index 4c70a779e1f0..3508df4e806c 100644 --- a/drivers/staging/ath6kl/include/common_drv.h +++ b/drivers/staging/ath6kl/include/common_drv.h @@ -33,7 +33,7 @@ struct common_credit_state_info { int TotalAvailableCredits; /* total credits in the system at startup */ int CurrentFreeCredits; /* credits available in the pool that have not been given out to endpoints */ - HTC_ENDPOINT_CREDIT_DIST *pLowestPriEpDist; /* pointer to the lowest priority endpoint dist struct */ + struct htc_endpoint_credit_dist *pLowestPriEpDist; /* pointer to the lowest priority endpoint dist struct */ }; struct hci_transport_callbacks { diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h index c5c9fed3fe4d..f5baf7459e98 100644 --- a/drivers/staging/ath6kl/include/htc_api.h +++ b/drivers/staging/ath6kl/include/htc_api.h @@ -163,9 +163,9 @@ typedef struct _HTC_SERVICE_CONNECT_RESP { } HTC_SERVICE_CONNECT_RESP; /* endpoint distribution structure */ -typedef struct _HTC_ENDPOINT_CREDIT_DIST { - struct _HTC_ENDPOINT_CREDIT_DIST *pNext; - struct _HTC_ENDPOINT_CREDIT_DIST *pPrev; +struct htc_endpoint_credit_dist { + struct htc_endpoint_credit_dist *pNext; + struct htc_endpoint_credit_dist *pPrev; HTC_SERVICE_ID ServiceID; /* Service ID (set by HTC) */ HTC_ENDPOINT_ID Endpoint; /* endpoint for this distribution struct (set by HTC) */ u32 DistFlags; /* distribution flags, distribution function can @@ -195,7 +195,7 @@ typedef struct _HTC_ENDPOINT_CREDIT_DIST { or HTC_CREDIT_DIST_SEND_COMPLETE is indicated on an endpoint that has non-zero credits to recover */ -} HTC_ENDPOINT_CREDIT_DIST; +}; #define HTC_EP_ACTIVE ((u32) (1u << 31)) @@ -216,11 +216,11 @@ typedef enum _HTC_CREDIT_DIST_REASON { } HTC_CREDIT_DIST_REASON; typedef void (*HTC_CREDIT_DIST_CALLBACK)(void *Context, - HTC_ENDPOINT_CREDIT_DIST *pEPList, + struct htc_endpoint_credit_dist *pEPList, HTC_CREDIT_DIST_REASON Reason); typedef void (*HTC_CREDIT_INIT_CALLBACK)(void *Context, - HTC_ENDPOINT_CREDIT_DIST *pEPList, + struct htc_endpoint_credit_dist *pEPList, int TotalCredits); /* endpoint statistics action */ diff --git a/drivers/staging/ath6kl/miscdrv/credit_dist.c b/drivers/staging/ath6kl/miscdrv/credit_dist.c index 8c418d2d8310..ae54e1f48e50 100644 --- a/drivers/staging/ath6kl/miscdrv/credit_dist.c +++ b/drivers/staging/ath6kl/miscdrv/credit_dist.c @@ -42,14 +42,14 @@ #endif static void RedistributeCredits(struct common_credit_state_info *pCredInfo, - HTC_ENDPOINT_CREDIT_DIST *pEPDistList); + struct htc_endpoint_credit_dist *pEPDistList); static void SeekCredits(struct common_credit_state_info *pCredInfo, - HTC_ENDPOINT_CREDIT_DIST *pEPDistList); + struct htc_endpoint_credit_dist *pEPDistList); /* reduce an ep's credits back to a set limit */ static INLINE void ReduceCredits(struct common_credit_state_info *pCredInfo, - HTC_ENDPOINT_CREDIT_DIST *pEpDist, + struct htc_endpoint_credit_dist *pEpDist, int Limit) { int credits; @@ -81,10 +81,10 @@ static INLINE void ReduceCredits(struct common_credit_state_info *pCredInfo, * This function is called in the context of HTCStart() to setup initial (application-specific) * credit distributions */ static void ar6000_credit_init(void *Context, - HTC_ENDPOINT_CREDIT_DIST *pEPList, + struct htc_endpoint_credit_dist *pEPList, int TotalCredits) { - HTC_ENDPOINT_CREDIT_DIST *pCurEpDist; + struct htc_endpoint_credit_dist *pCurEpDist; int count; struct common_credit_state_info *pCredInfo = (struct common_credit_state_info *)Context; @@ -175,10 +175,10 @@ static void ar6000_credit_init(void *Context, * */ static void ar6000_credit_distribute(void *Context, - HTC_ENDPOINT_CREDIT_DIST *pEPDistList, + struct htc_endpoint_credit_dist *pEPDistList, HTC_CREDIT_DIST_REASON Reason) { - HTC_ENDPOINT_CREDIT_DIST *pCurEpDist; + struct htc_endpoint_credit_dist *pCurEpDist; struct common_credit_state_info *pCredInfo = (struct common_credit_state_info *)Context; switch (Reason) { @@ -244,9 +244,9 @@ static void ar6000_credit_distribute(void *Context, /* redistribute credits based on activity change */ static void RedistributeCredits(struct common_credit_state_info *pCredInfo, - HTC_ENDPOINT_CREDIT_DIST *pEPDistList) + struct htc_endpoint_credit_dist *pEPDistList) { - HTC_ENDPOINT_CREDIT_DIST *pCurEpDist = pEPDistList; + struct htc_endpoint_credit_dist *pCurEpDist = pEPDistList; /* walk through the list and remove credits from inactive endpoints */ while (pCurEpDist != NULL) { @@ -284,9 +284,9 @@ static void RedistributeCredits(struct common_credit_state_info *pCredInfo, /* HTC has an endpoint that needs credits, pEPDist is the endpoint in question */ static void SeekCredits(struct common_credit_state_info *pCredInfo, - HTC_ENDPOINT_CREDIT_DIST *pEPDist) + struct htc_endpoint_credit_dist *pEPDist) { - HTC_ENDPOINT_CREDIT_DIST *pCurEpDist; + struct htc_endpoint_credit_dist *pCurEpDist; int credits = 0; int need; -- cgit v1.2.3 From 84efc7ff1c55a5f27cbd9b55cdcf31facb7bf9b2 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:53 -0700 Subject: ath6kl: remove-typedef HTC_ENDPOINT_STATS remove-typedef -s HTC_ENDPOINT_STATS \ "struct htc_endpoint_stats" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/htc.c | 6 +++--- drivers/staging/ath6kl/htc2/htc_internal.h | 2 +- drivers/staging/ath6kl/include/htc_api.h | 6 +++--- drivers/staging/ath6kl/os/linux/ioctl.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index e897c0cb319a..2a065b4c4c3f 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -524,7 +524,7 @@ static void HTCReportFailure(void *Context) bool HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_ENDPOINT_STAT_ACTION Action, - HTC_ENDPOINT_STATS *pStats) + struct htc_endpoint_stats *pStats) { #ifdef HTC_EP_STAT_PROFILING @@ -556,12 +556,12 @@ bool HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, if (sample) { A_ASSERT(pStats != NULL); /* return the stats to the caller */ - memcpy(pStats, &target->EndPoint[Endpoint].EndPointStats, sizeof(HTC_ENDPOINT_STATS)); + memcpy(pStats, &target->EndPoint[Endpoint].EndPointStats, sizeof(struct htc_endpoint_stats)); } if (clearStats) { /* reset stats */ - A_MEMZERO(&target->EndPoint[Endpoint].EndPointStats, sizeof(HTC_ENDPOINT_STATS)); + A_MEMZERO(&target->EndPoint[Endpoint].EndPointStats, sizeof(struct htc_endpoint_stats)); } UNLOCK_HTC_RX(target); diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h index d726a028456c..0e363a8fb3ef 100644 --- a/drivers/staging/ath6kl/htc2/htc_internal.h +++ b/drivers/staging/ath6kl/htc2/htc_internal.h @@ -83,7 +83,7 @@ struct htc_endpoint { u8 SeqNo; /* TX seq no (helpful) for debugging */ u32 LocalConnectionFlags; /* local connection flags */ #ifdef HTC_EP_STAT_PROFILING - HTC_ENDPOINT_STATS EndPointStats; /* endpoint statistics */ + struct htc_endpoint_stats EndPointStats; /* endpoint statistics */ #endif }; diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h index f5baf7459e98..db3cbcf92b18 100644 --- a/drivers/staging/ath6kl/include/htc_api.h +++ b/drivers/staging/ath6kl/include/htc_api.h @@ -231,7 +231,7 @@ typedef enum _HTC_ENDPOINT_STAT_ACTION { } HTC_ENDPOINT_STAT_ACTION; /* endpoint statistics */ -typedef struct _HTC_ENDPOINT_STATS { +struct htc_endpoint_stats { u32 TxCreditLowIndications; /* number of times the host set the credit-low flag in a send message on this endpoint */ u32 TxIssued; /* running count of total TX packets issued */ @@ -255,7 +255,7 @@ typedef struct _HTC_ENDPOINT_STATS { u32 RxBundleIndFromHdr; /* count of the number of bundle indications from the HTC header */ u32 RxAllocThreshHit; /* count of the number of times the recv allocation threshhold was hit */ u32 RxAllocThreshBytes; /* total number of bytes */ -} HTC_ENDPOINT_STATS; +}; /* ------ Function Prototypes ------ */ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -472,7 +472,7 @@ void HTCIndicateActivityChange(HTC_HANDLE HTCHandle, bool HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_ENDPOINT_STAT_ACTION Action, - HTC_ENDPOINT_STATS *pStats); + struct htc_endpoint_stats *pStats); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Unblock HTC message reception diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index 18244757ae37..2c0d4fd3a517 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -3976,7 +3976,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) #endif /* ATH_DEBUG_MODULE */ #ifdef HTC_EP_STAT_PROFILING { - HTC_ENDPOINT_STATS stats; + struct htc_endpoint_stats stats; int i; for (i = 0; i < 5; i++) { -- cgit v1.2.3 From 80ab2899c223599450ec5d0c188c0783b6806057 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:54 -0700 Subject: ath6kl: remove-typedef HTC_EP_CALLBACKS remove-typedef -s HTC_EP_CALLBACKS \ "struct htc_ep_callbacks" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/htc_internal.h | 2 +- drivers/staging/ath6kl/include/htc_api.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h index 0e363a8fb3ef..d5740152ae45 100644 --- a/drivers/staging/ath6kl/htc2/htc_internal.h +++ b/drivers/staging/ath6kl/htc2/htc_internal.h @@ -72,7 +72,7 @@ struct htc_endpoint { HTC_PACKET_QUEUE TxQueue; /* HTC frame buffer TX queue */ HTC_PACKET_QUEUE RxBuffers; /* HTC frame buffer RX list */ struct htc_endpoint_credit_dist CreditDist; /* credit distribution structure (exposed to driver layer) */ - HTC_EP_CALLBACKS EpCallBacks; /* callbacks associated with this endpoint */ + struct htc_ep_callbacks EpCallBacks; /* callbacks associated with this endpoint */ int MaxTxQueueDepth; /* max depth of the TX queue before we need to call driver's full handler */ int MaxMsgLength; /* max length of endpoint message */ diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h index db3cbcf92b18..ad25d3ea40f8 100644 --- a/drivers/staging/ath6kl/include/htc_api.h +++ b/drivers/staging/ath6kl/include/htc_api.h @@ -116,7 +116,7 @@ typedef enum _HTC_SEND_FULL_ACTION { * must ONLY inspect the packet, it may not free or reclaim the packet. */ typedef HTC_SEND_FULL_ACTION (*HTC_EP_SEND_QUEUE_FULL)(void *, HTC_PACKET *pPacket); -typedef struct _HTC_EP_CALLBACKS { +struct htc_ep_callbacks { void *pContext; /* context for each callback */ HTC_EP_SEND_PKT_COMPLETE EpTxComplete; /* tx completion callback for connected endpoint */ HTC_EP_RECV_PKT EpRecv; /* receive callback for connected endpoint */ @@ -136,7 +136,7 @@ typedef struct _HTC_EP_CALLBACKS { when the recv queue drops below this value if set to 0, the refill is only called when packets are empty */ -} HTC_EP_CALLBACKS; +}; /* service connection information */ typedef struct _HTC_SERVICE_CONNECT_REQ { @@ -144,7 +144,7 @@ typedef struct _HTC_SERVICE_CONNECT_REQ { u16 ConnectionFlags; /* connection flags, see htc protocol definition */ u8 *pMetaData; /* ptr to optional service-specific meta-data */ u8 MetaDataLength; /* optional meta data length */ - HTC_EP_CALLBACKS EpCallbacks; /* endpoint callbacks */ + struct htc_ep_callbacks EpCallbacks; /* endpoint callbacks */ int MaxSendQueueDepth; /* maximum depth of any send queue */ u32 LocalConnectionFlags; /* HTC flags for the host-side (local) connection */ unsigned int MaxSendMsgSize; /* override max message size in send direction */ -- cgit v1.2.3 From af26f25c84a8340eae1362727ee0584870b2948d Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:55 -0700 Subject: ath6kl: remove-typedef HTC_FRAME_HDR remove-typedef -s HTC_FRAME_HDR \ "struct htc_frame_hdr" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/htc_internal.h | 12 ++++----- drivers/staging/ath6kl/htc2/htc_recv.c | 30 +++++++++++----------- .../staging/ath6kl/include/common/epping_test.h | 2 +- drivers/staging/ath6kl/include/common/htc.h | 8 +++--- 4 files changed, 26 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h index d5740152ae45..deff62a6cf11 100644 --- a/drivers/staging/ath6kl/htc2/htc_internal.h +++ b/drivers/staging/ath6kl/htc2/htc_internal.h @@ -128,7 +128,7 @@ typedef struct _HTC_TARGET { HTC_ENDPOINT_ID EpWaitingForBuffers; bool TargetFailure; #ifdef HTC_CAPTURE_LAST_FRAME - HTC_FRAME_HDR LastFrameHdr; /* useful for debugging */ + struct htc_frame_hdr LastFrameHdr; /* useful for debugging */ u8 LastTrailer[256]; u8 LastTrailerLength; #endif @@ -203,11 +203,11 @@ static INLINE HTC_PACKET *HTC_ALLOC_CONTROL_TX(HTC_TARGET *target) { u8 *pHdrBuf; \ (pP)->pBuffer -= HTC_HDR_LENGTH; \ pHdrBuf = (pP)->pBuffer; \ - A_SET_UINT16_FIELD(pHdrBuf,HTC_FRAME_HDR,PayloadLen,(u16)(pP)->ActualLength); \ - A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,Flags,(sendflags)); \ - A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,EndpointID, (u8)(pP)->Endpoint); \ - A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,ControlBytes[0], (u8)(ctrl0)); \ - A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,ControlBytes[1], (u8)(ctrl1)); \ + A_SET_UINT16_FIELD(pHdrBuf,struct htc_frame_hdr,PayloadLen,(u16)(pP)->ActualLength); \ + A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,Flags,(sendflags)); \ + A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,EndpointID, (u8)(pP)->Endpoint); \ + A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,ControlBytes[0], (u8)(ctrl0)); \ + A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,ControlBytes[1], (u8)(ctrl1)); \ } #define HTC_UNPREPARE_SEND_PKT(pP) \ diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c index 4095f8e07e53..771dc5e217c0 100644 --- a/drivers/staging/ath6kl/htc2/htc_recv.c +++ b/drivers/staging/ath6kl/htc2/htc_recv.c @@ -252,7 +252,7 @@ static int HTCProcessRecvHeader(HTC_TARGET *target, do { /* note, we cannot assume the alignment of pBuffer, so we use the safe macros to * retrieve 16 bit fields */ - payloadLen = A_GET_UINT16_FIELD(pBuf, HTC_FRAME_HDR, PayloadLen); + payloadLen = A_GET_UINT16_FIELD(pBuf, struct htc_frame_hdr, PayloadLen); ((u8 *)&lookAhead)[0] = pBuf[0]; ((u8 *)&lookAhead)[1] = pBuf[1]; @@ -277,10 +277,10 @@ static int HTCProcessRecvHeader(HTC_TARGET *target, break; } - if (pPacket->Endpoint != A_GET_UINT8_FIELD(pBuf, HTC_FRAME_HDR, EndpointID)) { + if (pPacket->Endpoint != A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, EndpointID)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Refreshed HDR endpoint (%d) does not match expected endpoint (%d) \n", - A_GET_UINT8_FIELD(pBuf, HTC_FRAME_HDR, EndpointID), pPacket->Endpoint)); + A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, EndpointID), pPacket->Endpoint)); status = A_EPROTO; break; } @@ -294,9 +294,9 @@ static int HTCProcessRecvHeader(HTC_TARGET *target, (unsigned long)pPacket, pPacket->PktInfo.AsRx.HTCRxFlags)); #ifdef ATH_DEBUG_MODULE DebugDumpBytes((u8 *)&pPacket->PktInfo.AsRx.ExpectedHdr,4,"Expected Message LookAhead"); - DebugDumpBytes(pBuf,sizeof(HTC_FRAME_HDR),"Current Frame Header"); + DebugDumpBytes(pBuf,sizeof(struct htc_frame_hdr),"Current Frame Header"); #ifdef HTC_CAPTURE_LAST_FRAME - DebugDumpBytes((u8 *)&target->LastFrameHdr,sizeof(HTC_FRAME_HDR),"Last Frame Header"); + DebugDumpBytes((u8 *)&target->LastFrameHdr,sizeof(struct htc_frame_hdr),"Last Frame Header"); if (target->LastTrailerLength != 0) { DebugDumpBytes(target->LastTrailer, target->LastTrailerLength, @@ -309,13 +309,13 @@ static int HTCProcessRecvHeader(HTC_TARGET *target, } /* get flags */ - temp = A_GET_UINT8_FIELD(pBuf, HTC_FRAME_HDR, Flags); + temp = A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, Flags); if (temp & HTC_FLAGS_RECV_TRAILER) { /* this packet has a trailer */ /* extract the trailer length in control byte 0 */ - temp = A_GET_UINT8_FIELD(pBuf, HTC_FRAME_HDR, ControlBytes[0]); + temp = A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, ControlBytes[0]); if ((temp < sizeof(HTC_RECORD_HDR)) || (temp > payloadLen)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, @@ -372,7 +372,7 @@ static int HTCProcessRecvHeader(HTC_TARGET *target, #endif } else { #ifdef HTC_CAPTURE_LAST_FRAME - memcpy(&target->LastFrameHdr,pBuf,sizeof(HTC_FRAME_HDR)); + memcpy(&target->LastFrameHdr,pBuf,sizeof(struct htc_frame_hdr)); #endif if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { if (pPacket->ActualLength > 0) { @@ -500,7 +500,7 @@ static INLINE void SetRxPacketIndicationFlags(u32 LookAhead, struct htc_endpoint *pEndpoint, HTC_PACKET *pPacket) { - HTC_FRAME_HDR *pHdr = (HTC_FRAME_HDR *)&LookAhead; + struct htc_frame_hdr *pHdr = (struct htc_frame_hdr *)&LookAhead; /* check to see if the "next" packet is from the same endpoint of the completing packet */ if (pHdr->EndpointID == pPacket->Endpoint) { @@ -592,7 +592,7 @@ int HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket) int status; u32 lookAhead; HTC_PACKET *pPacket = NULL; - HTC_FRAME_HDR *pHdr; + struct htc_frame_hdr *pHdr; AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCWaitforControlMessage \n")); @@ -613,7 +613,7 @@ int HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket) ("HTCWaitforControlMessage : lookAhead : 0x%X \n", lookAhead)); /* check the lookahead */ - pHdr = (HTC_FRAME_HDR *)&lookAhead; + pHdr = (struct htc_frame_hdr *)&lookAhead; if (pHdr->EndpointID != ENDPOINT_0) { /* unexpected endpoint number, should be zero */ @@ -694,7 +694,7 @@ static int AllocAndPrepareRxPackets(HTC_TARGET *target, { int status = 0; HTC_PACKET *pPacket; - HTC_FRAME_HDR *pHdr; + struct htc_frame_hdr *pHdr; int i,j; int numMessages; int fullLength; @@ -705,7 +705,7 @@ static int AllocAndPrepareRxPackets(HTC_TARGET *target, for (i = 0; i < Messages; i++) { - pHdr = (HTC_FRAME_HDR *)&LookAheads[i]; + pHdr = (struct htc_frame_hdr *)&LookAheads[i]; if (pHdr->EndpointID >= ENDPOINT_MAX) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Endpoint in look-ahead: %d \n",pHdr->EndpointID)); @@ -751,7 +751,7 @@ static int AllocAndPrepareRxPackets(HTC_TARGET *target, ("HTC header indicates :%d messages can be fetched as a bundle \n",numMessages)); } - fullLength = DEV_CALC_RECV_PADDED_LEN(&target->Device,pHdr->PayloadLen + sizeof(HTC_FRAME_HDR)); + fullLength = DEV_CALC_RECV_PADDED_LEN(&target->Device,pHdr->PayloadLen + sizeof(struct htc_frame_hdr)); /* get packet buffers for each message, if there was a bundle detected in the header, * use pHdr as a template to fetch all packets in the bundle */ @@ -1170,7 +1170,7 @@ int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLook } /* first lookahead sets the expected endpoint IDs for all packets in a bundle */ - id = ((HTC_FRAME_HDR *)&lookAheads[0])->EndpointID; + id = ((struct htc_frame_hdr *)&lookAheads[0])->EndpointID; pEndpoint = &target->EndPoint[id]; if (id >= ENDPOINT_MAX) { diff --git a/drivers/staging/ath6kl/include/common/epping_test.h b/drivers/staging/ath6kl/include/common/epping_test.h index 2cd43c46c144..5c40d8a2229d 100644 --- a/drivers/staging/ath6kl/include/common/epping_test.h +++ b/drivers/staging/ath6kl/include/common/epping_test.h @@ -30,7 +30,7 @@ #endif /* alignment to 4-bytes */ -#define EPPING_ALIGNMENT_PAD (((sizeof(HTC_FRAME_HDR) + 3) & (~0x3)) - sizeof(HTC_FRAME_HDR)) +#define EPPING_ALIGNMENT_PAD (((sizeof(struct htc_frame_hdr) + 3) & (~0x3)) - sizeof(struct htc_frame_hdr)) #ifndef A_OFFSETOF #define A_OFFSETOF(type,field) (int)(&(((type *)NULL)->field)) diff --git a/drivers/staging/ath6kl/include/common/htc.h b/drivers/staging/ath6kl/include/common/htc.h index bed8e26abc3d..b9d4495d4324 100644 --- a/drivers/staging/ath6kl/include/common/htc.h +++ b/drivers/staging/ath6kl/include/common/htc.h @@ -66,7 +66,7 @@ */ /* HTC frame header */ -typedef PREPACK struct _HTC_FRAME_HDR{ +PREPACK struct htc_frame_hdr { /* do not remove or re-arrange these fields, these are minimally required * to take advantage of 4-byte lookaheads in some hardware implementations */ u8 EndpointID; @@ -79,7 +79,7 @@ typedef PREPACK struct _HTC_FRAME_HDR{ /* message payload starts after the header */ -} POSTPACK HTC_FRAME_HDR; +} POSTPACK; /* frame header flags */ @@ -94,9 +94,9 @@ typedef PREPACK struct _HTC_FRAME_HDR{ #define HTC_FLAGS_RECV_BUNDLE_CNT_MASK (0xF0) /* bits 7..4 */ #define HTC_FLAGS_RECV_BUNDLE_CNT_SHIFT 4 -#define HTC_HDR_LENGTH (sizeof(HTC_FRAME_HDR)) +#define HTC_HDR_LENGTH (sizeof(struct htc_frame_hdr)) #define HTC_MAX_TRAILER_LENGTH 255 -#define HTC_MAX_PAYLOAD_LENGTH (4096 - sizeof(HTC_FRAME_HDR)) +#define HTC_MAX_PAYLOAD_LENGTH (4096 - sizeof(struct htc_frame_hdr)) /* HTC control message IDs */ -- cgit v1.2.3 From 4f0cce96a1c40e3874ac7d3794ad0d36c79fb995 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:56 -0700 Subject: ath6kl: remove-typedef HTC_INIT_INFO remove-typedef -s HTC_INIT_INFO \ "struct htc_init_info" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/htc.c | 4 ++-- drivers/staging/ath6kl/htc2/htc_internal.h | 2 +- drivers/staging/ath6kl/include/htc_api.h | 6 +++--- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index 2a065b4c4c3f..810fe7b919e6 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -90,7 +90,7 @@ static void HTCCleanup(HTC_TARGET *target) } /* registered target arrival callback from the HIF layer */ -HTC_HANDLE HTCCreate(void *hif_handle, HTC_INIT_INFO *pInfo) +HTC_HANDLE HTCCreate(void *hif_handle, struct htc_init_info *pInfo) { HTC_TARGET *target = NULL; int status = 0; @@ -130,7 +130,7 @@ HTC_HANDLE HTCCreate(void *hif_handle, HTC_INIT_INFO *pInfo) target->Device.MessagePendingCallback = HTCRecvMessagePendingHandler; target->EpWaitingForBuffers = ENDPOINT_MAX; - memcpy(&target->HTCInitInfo,pInfo,sizeof(HTC_INIT_INFO)); + memcpy(&target->HTCInitInfo,pInfo,sizeof(struct htc_init_info)); ResetEndpointStates(target); diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h index deff62a6cf11..c5727ca60932 100644 --- a/drivers/staging/ath6kl/htc2/htc_internal.h +++ b/drivers/staging/ath6kl/htc2/htc_internal.h @@ -132,7 +132,7 @@ typedef struct _HTC_TARGET { u8 LastTrailer[256]; u8 LastTrailerLength; #endif - HTC_INIT_INFO HTCInitInfo; + struct htc_init_info HTCInitInfo; u8 HTCTargetVersion; int MaxMsgPerBundle; /* max messages per bundle for HTC */ bool SendBundlingEnabled; /* run time enable for send bundling (dynamic) */ diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h index ad25d3ea40f8..5878417c3443 100644 --- a/drivers/staging/ath6kl/include/htc_api.h +++ b/drivers/staging/ath6kl/include/htc_api.h @@ -43,10 +43,10 @@ typedef void *HTC_HANDLE; typedef u16 HTC_SERVICE_ID; -typedef struct _HTC_INIT_INFO { +struct htc_init_info { void *pContext; /* context for target failure notification */ void (*TargetFailure)(void *Instance, int Status); -} HTC_INIT_INFO; +}; /* per service connection send completion */ typedef void (*HTC_EP_SEND_PKT_COMPLETE)(void *,HTC_PACKET *); @@ -269,7 +269,7 @@ struct htc_endpoint_stats { @example: @see also: HTCDestroy +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -HTC_HANDLE HTCCreate(void *HifDevice, HTC_INIT_INFO *pInfo); +HTC_HANDLE HTCCreate(void *HifDevice, struct htc_init_info *pInfo); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Get the underlying HIF device handle @function name: HTCGetHifDevice diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index b739943d0ab8..ebfe1e8b0f87 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -1599,7 +1599,7 @@ ar6000_avail_ev(void *context, void *hif_handle) void *ar_netif; AR_SOFTC_T *ar; int device_index = 0; - HTC_INIT_INFO htcInfo; + struct htc_init_info htcInfo; #ifdef ATH6K_CONFIG_CFG80211 struct wireless_dev *wdev; #endif /* ATH6K_CONFIG_CFG80211 */ -- cgit v1.2.3 From c6528e2f0dca96ee2c4bf7f1600d9537fad88197 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:57 -0700 Subject: ath6kl: remove-typedef HTC_PACKET This required two passes: remove-typedef -s HTC_PACKET \ "struct htc_packet" drivers/staging/ath6kl/ remove-typedef -s _HTC_PACKET \ "struct htc_packet" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 18 ++++++------ drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 10 +++---- drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c | 10 +++---- drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c | 18 ++++++------ .../ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c | 18 ++++++------ drivers/staging/ath6kl/htc2/htc.c | 14 +++++----- drivers/staging/ath6kl/htc2/htc_internal.h | 20 +++++++------- drivers/staging/ath6kl/htc2/htc_recv.c | 32 +++++++++++----------- drivers/staging/ath6kl/htc2/htc_send.c | 30 ++++++++++---------- drivers/staging/ath6kl/htc2/htc_services.c | 10 +++---- drivers/staging/ath6kl/include/hci_transport_api.h | 12 ++++---- drivers/staging/ath6kl/include/htc_api.h | 12 ++++---- drivers/staging/ath6kl/include/htc_packet.h | 22 +++++++-------- drivers/staging/ath6kl/miscdrv/ar3kconfig.c | 12 ++++---- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 26 +++++++++--------- drivers/staging/ath6kl/os/linux/ar6000_raw_if.c | 4 +-- .../staging/ath6kl/os/linux/export_hci_transport.c | 4 +-- drivers/staging/ath6kl/os/linux/hci_bridge.c | 24 ++++++++-------- .../staging/ath6kl/os/linux/include/ar6000_drv.h | 4 +-- .../ath6kl/os/linux/include/export_hci_transport.h | 4 +-- drivers/staging/ath6kl/os/linux/netbuf.c | 4 +-- 21 files changed, 154 insertions(+), 154 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index c780e4fb49ba..91e763a4abf7 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -40,16 +40,16 @@ int DevDisableInterrupts(struct ar6k_device *pDev); static void DevCleanupVirtualScatterSupport(struct ar6k_device *pDev); -void AR6KFreeIOPacket(struct ar6k_device *pDev, HTC_PACKET *pPacket) +void AR6KFreeIOPacket(struct ar6k_device *pDev, struct htc_packet *pPacket) { LOCK_AR6K(pDev); HTC_PACKET_ENQUEUE(&pDev->RegisterIOList,pPacket); UNLOCK_AR6K(pDev); } -HTC_PACKET *AR6KAllocIOPacket(struct ar6k_device *pDev) +struct htc_packet *AR6KAllocIOPacket(struct ar6k_device *pDev) { - HTC_PACKET *pPacket; + struct htc_packet *pPacket; LOCK_AR6K(pDev); pPacket = HTC_PACKET_DEQUEUE(&pDev->RegisterIOList); @@ -113,7 +113,7 @@ int DevSetup(struct ar6k_device *pDev) /* carve up register I/O packets (these are for ASYNC register I/O ) */ for (i = 0; i < AR6K_MAX_REG_IO_BUFFERS; i++) { - HTC_PACKET *pIOPacket; + struct htc_packet *pIOPacket; pIOPacket = &pDev->RegIOBuffers[i].HtcPacket; SET_HTC_PACKET_INFO_RX_REFILL(pIOPacket, pDev, @@ -337,7 +337,7 @@ int DevMaskInterrupts(struct ar6k_device *pDev) } /* callback when our fetch to enable/disable completes */ -static void DevDoEnableDisableRecvAsyncHandler(void *Context, HTC_PACKET *pPacket) +static void DevDoEnableDisableRecvAsyncHandler(void *Context, struct htc_packet *pPacket) { struct ar6k_device *pDev = (struct ar6k_device *)Context; @@ -358,7 +358,7 @@ static void DevDoEnableDisableRecvAsyncHandler(void *Context, HTC_PACKET *pPacke static int DevDoEnableDisableRecvOverride(struct ar6k_device *pDev, bool EnableRecv, bool AsyncMode) { int status = 0; - HTC_PACKET *pIOPacket = NULL; + struct htc_packet *pIOPacket = NULL; AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("DevDoEnableDisableRecvOverride: Enable:%d Mode:%d\n", EnableRecv,AsyncMode)); @@ -406,7 +406,7 @@ static int DevDoEnableDisableRecvOverride(struct ar6k_device *pDev, bool EnableR static int DevDoEnableDisableRecvNormal(struct ar6k_device *pDev, bool EnableRecv, bool AsyncMode) { int status = 0; - HTC_PACKET *pIOPacket = NULL; + struct htc_packet *pIOPacket = NULL; struct ar6k_irq_enable_registers regs; /* take the lock to protect interrupt enable shadows */ @@ -648,7 +648,7 @@ int DevCopyScatterListToFromDMABuffer(struct hif_scatter_req *pReq, bool FromDMA return 0; } -static void DevReadWriteScatterAsyncHandler(void *Context, HTC_PACKET *pPacket) +static void DevReadWriteScatterAsyncHandler(void *Context, struct htc_packet *pPacket) { struct ar6k_device *pDev = (struct ar6k_device *)Context; struct hif_scatter_req *pReq = (struct hif_scatter_req *)pPacket->pPktContext; @@ -668,7 +668,7 @@ static int DevReadWriteScatter(HIF_DEVICE *Context, struct hif_scatter_req *pReq { struct ar6k_device *pDev = (struct ar6k_device *)Context; int status = 0; - HTC_PACKET *pIOPacket = NULL; + struct htc_packet *pIOPacket = NULL; u32 request = pReq->Request; do { diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index baad0bf472d0..b01542e2c3a7 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -90,7 +90,7 @@ PREPACK struct ar6k_gmbox_ctrl_registers { /* buffers for ASYNC I/O */ struct ar6k_async_reg_io_buffer { - HTC_PACKET HtcPacket; /* we use an HTC packet as a wrapper for our async register-based I/O */ + struct htc_packet HtcPacket; /* we use an HTC packet as a wrapper for our async register-based I/O */ u8 _Pad1[A_CACHE_LINE_PAD]; u8 Buffer[AR6K_REG_IO_BUFFER_SIZE]; /* cache-line safe with pads around */ u8 _Pad2[A_CACHE_LINE_PAD]; @@ -176,7 +176,7 @@ int DevWaitForPendingRecv(struct ar6k_device *pDev,u32 TimeoutInMs,bool *pbIsRec #define DEV_CALC_SEND_PADDED_LEN(pDev, length) DEV_CALC_RECV_PADDED_LEN(pDev,length) #define DEV_IS_LEN_BLOCK_ALIGNED(pDev, length) (((length) % (pDev)->BlockSize) == 0) -static INLINE int DevSendPacket(struct ar6k_device *pDev, HTC_PACKET *pPacket, u32 SendLength) { +static INLINE int DevSendPacket(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 SendLength) { u32 paddedLength; bool sync = (pPacket->Completion == NULL) ? true : false; int status; @@ -219,7 +219,7 @@ static INLINE int DevSendPacket(struct ar6k_device *pDev, HTC_PACKET *pPacket, u return status; } -static INLINE int DevRecvPacket(struct ar6k_device *pDev, HTC_PACKET *pPacket, u32 RecvLength) { +static INLINE int DevRecvPacket(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 RecvLength) { u32 paddedLength; int status; bool sync = (pPacket->Completion == NULL) ? true : false; @@ -378,8 +378,8 @@ struct ar6k_device *HTCGetAR6KDevice(void *HTCHandle); #define DEV_GMBOX_GET_PROTOCOL(pDev) (pDev)->GMboxInfo.pProtocolContext -int DevGMboxWrite(struct ar6k_device *pDev, HTC_PACKET *pPacket, u32 WriteLength); -int DevGMboxRead(struct ar6k_device *pDev, HTC_PACKET *pPacket, u32 ReadLength); +int DevGMboxWrite(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 WriteLength); +int DevGMboxRead(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 ReadLength); #define PROC_IO_ASYNC true #define PROC_IO_SYNC false diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c index ca6abb490e24..5e6d1e062922 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c @@ -33,8 +33,8 @@ #include "htc_packet.h" #include "ar6k.h" -extern void AR6KFreeIOPacket(struct ar6k_device *pDev, HTC_PACKET *pPacket); -extern HTC_PACKET *AR6KAllocIOPacket(struct ar6k_device *pDev); +extern void AR6KFreeIOPacket(struct ar6k_device *pDev, struct htc_packet *pPacket); +extern struct htc_packet *AR6KAllocIOPacket(struct ar6k_device *pDev); static int DevServiceDebugInterrupt(struct ar6k_device *pDev); @@ -43,7 +43,7 @@ static int DevServiceDebugInterrupt(struct ar6k_device *pDev); /* completion routine for ALL HIF layer async I/O */ int DevRWCompletionHandler(void *context, int status) { - HTC_PACKET *pPacket = (HTC_PACKET *)context; + struct htc_packet *pPacket = (struct htc_packet *)context; AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+DevRWCompletionHandler (Pkt:0x%lX) , Status: %d \n", @@ -300,7 +300,7 @@ static int DevServiceCounterInterrupt(struct ar6k_device *pDev) } /* callback when our fetch to get interrupt status registers completes */ -static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket) +static void DevGetEventAsyncHandler(void *Context, struct htc_packet *pPacket) { struct ar6k_device *pDev = (struct ar6k_device *)Context; u32 lookAhead = 0; @@ -392,7 +392,7 @@ int DevCheckPendingRecvMsgsAsync(void *context) { struct ar6k_device *pDev = (struct ar6k_device *)context; int status = 0; - HTC_PACKET *pIOPacket; + struct htc_packet *pIOPacket; /* this is called in an ASYNC only context, we may NOT block, sleep or call any apis that can * cause us to switch contexts */ diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c index 106f9bf7b117..374001155feb 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c @@ -54,12 +54,12 @@ /* external APIs for allocating and freeing internal I/O packets to handle ASYNC I/O */ -extern void AR6KFreeIOPacket(struct ar6k_device *pDev, HTC_PACKET *pPacket); -extern HTC_PACKET *AR6KAllocIOPacket(struct ar6k_device *pDev); +extern void AR6KFreeIOPacket(struct ar6k_device *pDev, struct htc_packet *pPacket); +extern struct htc_packet *AR6KAllocIOPacket(struct ar6k_device *pDev); /* callback when our fetch to enable/disable completes */ -static void DevGMboxIRQActionAsyncHandler(void *Context, HTC_PACKET *pPacket) +static void DevGMboxIRQActionAsyncHandler(void *Context, struct htc_packet *pPacket) { struct ar6k_device *pDev = (struct ar6k_device *)Context; @@ -78,7 +78,7 @@ static int DevGMboxCounterEnableDisable(struct ar6k_device *pDev, GMBOX_IRQ_ACTI { int status = 0; struct ar6k_irq_enable_registers regs; - HTC_PACKET *pIOPacket = NULL; + struct htc_packet *pIOPacket = NULL; LOCK_AR6K(pDev); @@ -158,7 +158,7 @@ static int DevGMboxCounterEnableDisable(struct ar6k_device *pDev, GMBOX_IRQ_ACTI int DevGMboxIRQAction(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode) { int status = 0; - HTC_PACKET *pIOPacket = NULL; + struct htc_packet *pIOPacket = NULL; u8 GMboxIntControl[4]; if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) { @@ -396,7 +396,7 @@ int DevCheckGMboxInterrupts(struct ar6k_device *pDev) } -int DevGMboxWrite(struct ar6k_device *pDev, HTC_PACKET *pPacket, u32 WriteLength) +int DevGMboxWrite(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 WriteLength) { u32 paddedLength; bool sync = (pPacket->Completion == NULL) ? true : false; @@ -433,7 +433,7 @@ int DevGMboxWrite(struct ar6k_device *pDev, HTC_PACKET *pPacket, u32 WriteLength return status; } -int DevGMboxRead(struct ar6k_device *pDev, HTC_PACKET *pPacket, u32 ReadLength) +int DevGMboxRead(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 ReadLength) { u32 paddedLength; @@ -516,7 +516,7 @@ static int ProcessCreditCounterReadBuffer(u8 *pBuffer, int Length) /* callback when our fetch to enable/disable completes */ -static void DevGMboxReadCreditsAsyncHandler(void *Context, HTC_PACKET *pPacket) +static void DevGMboxReadCreditsAsyncHandler(void *Context, struct htc_packet *pPacket) { struct ar6k_device *pDev = (struct ar6k_device *)Context; @@ -542,7 +542,7 @@ static void DevGMboxReadCreditsAsyncHandler(void *Context, HTC_PACKET *pPacket) int DevGMboxReadCreditCounter(struct ar6k_device *pDev, bool AsyncMode, int *pCredits) { int status = 0; - HTC_PACKET *pIOPacket = NULL; + struct htc_packet *pIOPacket = NULL; AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+DevGMboxReadCreditCounter (%s) \n", AsyncMode ? "ASYNC" : "SYNC")); diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c index 8e5abe8e67ec..90e303f342a8 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c @@ -99,7 +99,7 @@ do { \ (p)->HCIConfig.pHCISendComplete((p)->HCIConfig.pContext, (pt)); \ } -static int HCITrySend(struct gmbox_proto_hci_uart *pProt, HTC_PACKET *pPacket, bool Synchronous); +static int HCITrySend(struct gmbox_proto_hci_uart *pProt, struct htc_packet *pPacket, bool Synchronous); static void HCIUartCleanup(struct gmbox_proto_hci_uart *pProtocol) { @@ -312,7 +312,7 @@ static int HCIUartMessagePending(void *pContext, u8 LookAheadBytes[], int ValidB HCI_TRANSPORT_PACKET_TYPE pktType = HCI_PACKET_INVALID; bool recvRefillCalled = false; bool blockRecv = false; - HTC_PACKET *pPacket = NULL; + struct htc_packet *pPacket = NULL; /** caller guarantees that this is a fully block-able context (synch I/O is allowed) */ @@ -532,7 +532,7 @@ static int HCIUartMessagePending(void *pContext, u8 LookAheadBytes[], int ValidB return status; } -static void HCISendPacketCompletion(void *Context, HTC_PACKET *pPacket) +static void HCISendPacketCompletion(void *Context, struct htc_packet *pPacket) { struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)Context; AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCISendPacketCompletion (pPacket:0x%lX) \n",(unsigned long)pPacket)); @@ -579,7 +579,7 @@ static int SeekCreditsSynch(struct gmbox_proto_hci_uart *pProt) return status; } -static int HCITrySend(struct gmbox_proto_hci_uart *pProt, HTC_PACKET *pPacket, bool Synchronous) +static int HCITrySend(struct gmbox_proto_hci_uart *pProt, struct htc_packet *pPacket, bool Synchronous) { int status = 0; int transferLength; @@ -796,7 +796,7 @@ static int HCITrySend(struct gmbox_proto_hci_uart *pProt, HTC_PACKET *pPacket, b static void FlushSendQueue(struct gmbox_proto_hci_uart *pProt) { - HTC_PACKET *pPacket; + struct htc_packet *pPacket; HTC_PACKET_QUEUE discardQueue; INIT_HTC_PACKET_QUEUE(&discardQueue); @@ -821,7 +821,7 @@ static void FlushSendQueue(struct gmbox_proto_hci_uart *pProt) static void FlushRecvBuffers(struct gmbox_proto_hci_uart *pProt) { HTC_PACKET_QUEUE discardQueue; - HTC_PACKET *pPacket; + struct htc_packet *pPacket; INIT_HTC_PACKET_QUEUE(&discardQueue); @@ -1006,7 +1006,7 @@ int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; int status = 0; bool unblockRecv = false; - HTC_PACKET *pPacket; + struct htc_packet *pPacket; AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HCI_TransportAddReceivePkt \n")); @@ -1069,7 +1069,7 @@ int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE return 0; } -int HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, bool Synchronous) +int HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous) { struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; @@ -1159,7 +1159,7 @@ int HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, bool Enab } int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, - HTC_PACKET *pPacket, + struct htc_packet *pPacket, int MaxPollMS) { struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index 810fe7b919e6..04ba80ef8227 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -43,16 +43,16 @@ ATH_DEBUG_INSTANTIATE_MODULE_VAR(htc, static void HTCReportFailure(void *Context); static void ResetEndpointStates(HTC_TARGET *target); -void HTCFreeControlBuffer(HTC_TARGET *target, HTC_PACKET *pPacket, HTC_PACKET_QUEUE *pList) +void HTCFreeControlBuffer(HTC_TARGET *target, struct htc_packet *pPacket, HTC_PACKET_QUEUE *pList) { LOCK_HTC(target); HTC_PACKET_ENQUEUE(pList,pPacket); UNLOCK_HTC(target); } -HTC_PACKET *HTCAllocControlBuffer(HTC_TARGET *target, HTC_PACKET_QUEUE *pList) +struct htc_packet *HTCAllocControlBuffer(HTC_TARGET *target, HTC_PACKET_QUEUE *pList) { - HTC_PACKET *pPacket; + struct htc_packet *pPacket; LOCK_HTC(target); pPacket = HTC_PACKET_DEQUEUE(pList); @@ -171,7 +171,7 @@ HTC_HANDLE HTCCreate(void *hif_handle, struct htc_init_info *pInfo) /* carve up buffers/packets for control messages */ for (i = 0; i < NUM_CONTROL_RX_BUFFERS; i++) { - HTC_PACKET *pControlPacket; + struct htc_packet *pControlPacket; pControlPacket = &target->HTCControlBuffers[i].HtcPacket; SET_HTC_PACKET_INFO_RX_REFILL(pControlPacket, target, @@ -182,7 +182,7 @@ HTC_HANDLE HTCCreate(void *hif_handle, struct htc_init_info *pInfo) } for (;i < NUM_CONTROL_BUFFERS;i++) { - HTC_PACKET *pControlPacket; + struct htc_packet *pControlPacket; pControlPacket = &target->HTCControlBuffers[i].HtcPacket; INIT_HTC_PACKET_INFO(pControlPacket, target->HTCControlBuffers[i].Buffer, @@ -226,7 +226,7 @@ int HTCWaitTarget(HTC_HANDLE HTCHandle) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); int status; - HTC_PACKET *pPacket = NULL; + struct htc_packet *pPacket = NULL; HTC_READY_EX_MSG *pRdyMsg; HTC_SERVICE_CONNECT_REQ connect; @@ -372,7 +372,7 @@ int HTCWaitTarget(HTC_HANDLE HTCHandle) int HTCStart(HTC_HANDLE HTCHandle) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - HTC_PACKET *pPacket; + struct htc_packet *pPacket; int status; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n")); diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h index c5727ca60932..5f85350b50a1 100644 --- a/drivers/staging/ath6kl/htc2/htc_internal.h +++ b/drivers/staging/ath6kl/htc2/htc_internal.h @@ -100,7 +100,7 @@ struct htc_endpoint { #define NUM_CONTROL_RX_BUFFERS (NUM_CONTROL_BUFFERS - NUM_CONTROL_TX_BUFFERS) struct htc_control_buffer { - HTC_PACKET HtcPacket; + struct htc_packet HtcPacket; u8 *Buffer; }; @@ -162,13 +162,13 @@ typedef struct _HTC_TARGET { } /* internal HTC functions */ -void HTCControlTxComplete(void *Context, HTC_PACKET *pPacket); -void HTCControlRecv(void *Context, HTC_PACKET *pPacket); -int HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket); -HTC_PACKET *HTCAllocControlBuffer(HTC_TARGET *target, HTC_PACKET_QUEUE *pList); -void HTCFreeControlBuffer(HTC_TARGET *target, HTC_PACKET *pPacket, HTC_PACKET_QUEUE *pList); -int HTCIssueSend(HTC_TARGET *target, HTC_PACKET *pPacket); -void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket); +void HTCControlTxComplete(void *Context, struct htc_packet *pPacket); +void HTCControlRecv(void *Context, struct htc_packet *pPacket); +int HTCWaitforControlMessage(HTC_TARGET *target, struct htc_packet **ppControlPacket); +struct htc_packet *HTCAllocControlBuffer(HTC_TARGET *target, HTC_PACKET_QUEUE *pList); +void HTCFreeControlBuffer(HTC_TARGET *target, struct htc_packet *pPacket, HTC_PACKET_QUEUE *pList); +int HTCIssueSend(HTC_TARGET *target, struct htc_packet *pPacket); +void HTCRecvCompleteHandler(void *Context, struct htc_packet *pPacket); int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched); void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint); int HTCSendSetupComplete(HTC_TARGET *target); @@ -181,8 +181,8 @@ void DumpCreditDistStates(HTC_TARGET *target); void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription); #endif -static INLINE HTC_PACKET *HTC_ALLOC_CONTROL_TX(HTC_TARGET *target) { - HTC_PACKET *pPacket = HTCAllocControlBuffer(target,&target->ControlBufferTXFreeList); +static INLINE struct htc_packet *HTC_ALLOC_CONTROL_TX(HTC_TARGET *target) { + struct htc_packet *pPacket = HTCAllocControlBuffer(target,&target->ControlBufferTXFreeList); if (pPacket != NULL) { /* set payload pointer area with some headroom */ pPacket->pBuffer = pPacket->pBufferStart + HTC_HDR_LENGTH; diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c index 771dc5e217c0..f70296321b72 100644 --- a/drivers/staging/ath6kl/htc2/htc_recv.c +++ b/drivers/staging/ath6kl/htc2/htc_recv.c @@ -69,7 +69,7 @@ static void DoRecvCompletion(struct htc_endpoint *pEndpoint, pQueueToIndicate); INIT_HTC_PACKET_QUEUE(pQueueToIndicate); } else { - HTC_PACKET *pPacket; + struct htc_packet *pPacket; /* using legacy EpRecv */ do { pPacket = HTC_PACKET_DEQUEUE(pQueueToIndicate); @@ -227,7 +227,7 @@ static INLINE int HTCProcessTrailer(HTC_TARGET *target, /* process a received message (i.e. strip off header, process any trailer data) * note : locks must be released when this function is called */ static int HTCProcessRecvHeader(HTC_TARGET *target, - HTC_PACKET *pPacket, + struct htc_packet *pPacket, u32 *pNextLookAheads, int *pNumLookAheads) { @@ -498,7 +498,7 @@ static INLINE void DrainRecvIndicationQueue(HTC_TARGET *target, struct htc_endpo /* note: this function can be called with the RX lock held */ static INLINE void SetRxPacketIndicationFlags(u32 LookAhead, struct htc_endpoint *pEndpoint, - HTC_PACKET *pPacket) + struct htc_packet *pPacket) { struct htc_frame_hdr *pHdr = (struct htc_frame_hdr *)&LookAhead; /* check to see if the "next" packet is from the same endpoint of the @@ -515,7 +515,7 @@ static INLINE void SetRxPacketIndicationFlags(u32 LookAhead, /* asynchronous completion handler for recv packet fetching, when the device layer * completes a read request, it will call this completion handler */ -void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket) +void HTCRecvCompleteHandler(void *Context, struct htc_packet *pPacket) { HTC_TARGET *target = (HTC_TARGET *)Context; struct htc_endpoint *pEndpoint; @@ -587,11 +587,11 @@ void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket) /* synchronously wait for a control message from the target, * This function is used at initialization time ONLY. At init messages * on ENDPOINT 0 are expected. */ -int HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket) +int HTCWaitforControlMessage(HTC_TARGET *target, struct htc_packet **ppControlPacket) { int status; u32 lookAhead; - HTC_PACKET *pPacket = NULL; + struct htc_packet *pPacket = NULL; struct htc_frame_hdr *pHdr; AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCWaitforControlMessage \n")); @@ -693,7 +693,7 @@ static int AllocAndPrepareRxPackets(HTC_TARGET *target, HTC_PACKET_QUEUE *pQueue) { int status = 0; - HTC_PACKET *pPacket; + struct htc_packet *pPacket; struct htc_frame_hdr *pHdr; int i,j; int numMessages; @@ -882,7 +882,7 @@ static int AllocAndPrepareRxPackets(HTC_TARGET *target, static void HTCAsyncRecvScatterCompletion(struct hif_scatter_req *pScatterReq) { int i; - HTC_PACKET *pPacket; + struct htc_packet *pPacket; struct htc_endpoint *pEndpoint; u32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; int numLookAheads = 0; @@ -909,7 +909,7 @@ static void HTCAsyncRecvScatterCompletion(struct hif_scatter_req *pScatterReq) INIT_HTC_PACKET_QUEUE(&localRecvQueue); - pPacket = (HTC_PACKET *)pScatterReq->ScatterList[0].pCallerContexts[0]; + pPacket = (struct htc_packet *)pScatterReq->ScatterList[0].pCallerContexts[0]; /* note: all packets in a scatter req are for the same endpoint ! */ pEndpoint = &target->EndPoint[pPacket->Endpoint]; @@ -917,7 +917,7 @@ static void HTCAsyncRecvScatterCompletion(struct hif_scatter_req *pScatterReq) /* **** NOTE: DO NOT HOLD ANY LOCKS here, HTCProcessRecvHeader can take the TX lock * as it processes credit reports */ for (i = 0; i < pScatterReq->ValidScatterEntries; i++) { - pPacket = (HTC_PACKET *)pScatterReq->ScatterList[i].pCallerContexts[0]; + pPacket = (struct htc_packet *)pScatterReq->ScatterList[i].pCallerContexts[0]; A_ASSERT(pPacket != NULL); /* reset count, we are only interested in the look ahead in the last packet when we * break out of this loop */ @@ -994,7 +994,7 @@ static int HTCIssueRecvPacketBundle(HTC_TARGET *target, struct hif_scatter_req *pScatterReq; int i, totalLength; int pktsToScatter; - HTC_PACKET *pPacket; + struct htc_packet *pPacket; bool asyncMode = (pSyncCompletionQueue == NULL) ? true : false; int scatterSpaceRemaining = DEV_GET_MAX_BUNDLE_RECV_LENGTH(&target->Device); @@ -1121,7 +1121,7 @@ int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLook { HTC_TARGET *target = (HTC_TARGET *)Context; int status = 0; - HTC_PACKET *pPacket; + struct htc_packet *pPacket; struct htc_endpoint *pEndpoint; bool asyncProc = false; u32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; @@ -1391,7 +1391,7 @@ int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) struct htc_endpoint *pEndpoint; bool unblockRecv = false; int status = 0; - HTC_PACKET *pFirstPacket; + struct htc_packet *pFirstPacket; pFirstPacket = HTC_GET_PKT_AT_HEAD(pPktQueue); @@ -1415,7 +1415,7 @@ int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) LOCK_HTC_RX(target); if (HTC_STOPPING(target)) { - HTC_PACKET *pPacket; + struct htc_packet *pPacket; UNLOCK_HTC_RX(target); @@ -1455,7 +1455,7 @@ int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) } /* Makes a buffer available to the HTC module */ -int HTCAddReceivePkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket) +int HTCAddReceivePkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket) { HTC_PACKET_QUEUE queue; INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket); @@ -1488,7 +1488,7 @@ void HTCUnblockRecv(HTC_HANDLE HTCHandle) static void HTCFlushRxQueue(HTC_TARGET *target, struct htc_endpoint *pEndpoint, HTC_PACKET_QUEUE *pQueue) { - HTC_PACKET *pPacket; + struct htc_packet *pPacket; HTC_PACKET_QUEUE container; LOCK_HTC_RX(target); diff --git a/drivers/staging/ath6kl/htc2/htc_send.c b/drivers/staging/ath6kl/htc2/htc_send.c index b3135735bb9a..8fb05d9fdbc8 100644 --- a/drivers/staging/ath6kl/htc2/htc_send.c +++ b/drivers/staging/ath6kl/htc2/htc_send.c @@ -62,7 +62,7 @@ static void DoSendCompletion(struct htc_endpoint *pEndpoint, /* all packets are now owned by the callback, reset queue to be safe */ INIT_HTC_PACKET_QUEUE(pQueueToIndicate); } else { - HTC_PACKET *pPacket; + struct htc_packet *pPacket; /* using legacy EpTxComplete */ do { pPacket = HTC_PACKET_DEQUEUE(pQueueToIndicate); @@ -77,7 +77,7 @@ static void DoSendCompletion(struct htc_endpoint *pEndpoint, } /* do final completion on sent packet */ -static INLINE void CompleteSentPacket(HTC_TARGET *target, struct htc_endpoint *pEndpoint, HTC_PACKET *pPacket) +static INLINE void CompleteSentPacket(HTC_TARGET *target, struct htc_endpoint *pEndpoint, struct htc_packet *pPacket) { pPacket->Completion = NULL; @@ -101,7 +101,7 @@ static INLINE void CompleteSentPacket(HTC_TARGET *target, struct htc_endpoint *p /* our internal send packet completion handler when packets are submited to the AR6K device * layer */ -static void HTCSendPktCompletionHandler(void *Context, HTC_PACKET *pPacket) +static void HTCSendPktCompletionHandler(void *Context, struct htc_packet *pPacket) { HTC_TARGET *target = (HTC_TARGET *)Context; struct htc_endpoint *pEndpoint = &target->EndPoint[pPacket->Endpoint]; @@ -113,7 +113,7 @@ static void HTCSendPktCompletionHandler(void *Context, HTC_PACKET *pPacket) DO_EP_TX_COMPLETION(pEndpoint,&container); } -int HTCIssueSend(HTC_TARGET *target, HTC_PACKET *pPacket) +int HTCIssueSend(HTC_TARGET *target, struct htc_packet *pPacket) { int status; bool sync = false; @@ -153,7 +153,7 @@ static INLINE void GetHTCSendPackets(HTC_TARGET *target, int creditsRequired; int remainder; u8 sendFlags; - HTC_PACKET *pPacket; + struct htc_packet *pPacket; unsigned int transferLength; /****** NOTE : the TX lock is held when this function is called *****************/ @@ -267,7 +267,7 @@ static INLINE void GetHTCSendPackets(HTC_TARGET *target, static void HTCAsyncSendScatterCompletion(struct hif_scatter_req *pScatterReq) { int i; - HTC_PACKET *pPacket; + struct htc_packet *pPacket; struct htc_endpoint *pEndpoint = (struct htc_endpoint *)pScatterReq->Context; HTC_TARGET *target = (HTC_TARGET *)pEndpoint->target; int status = 0; @@ -287,7 +287,7 @@ static void HTCAsyncSendScatterCompletion(struct hif_scatter_req *pScatterReq) /* walk through the scatter list and process */ for (i = 0; i < pScatterReq->ValidScatterEntries; i++) { - pPacket = (HTC_PACKET *)(pScatterReq->ScatterList[i].pCallerContexts[0]); + pPacket = (struct htc_packet *)(pScatterReq->ScatterList[i].pCallerContexts[0]); A_ASSERT(pPacket != NULL); pPacket->Status = status; CompleteSentPacket(target,pEndpoint,pPacket); @@ -319,7 +319,7 @@ static void HTCIssueSendBundle(struct htc_endpoint *pEndpoint, struct hif_scatter_req *pScatterReq = NULL; int i, packetsInScatterReq; unsigned int transferLength; - HTC_PACKET *pPacket; + struct htc_packet *pPacket; bool done = false; int bundlesSent = 0; int totalPktsInBundle = 0; @@ -450,7 +450,7 @@ static void HTCIssueSendBundle(struct htc_endpoint *pEndpoint, if (packetsInScatterReq > 0) { /* work backwards to requeue requests */ for (i = (packetsInScatterReq - 1); i >= 0; i--) { - pPacket = (HTC_PACKET *)(pScatterReq->ScatterList[i].pCallerContexts[0]); + pPacket = (struct htc_packet *)(pScatterReq->ScatterList[i].pCallerContexts[0]); if (pPacket != NULL) { /* undo any prep */ HTC_UNPREPARE_SEND_PKT(pPacket); @@ -482,7 +482,7 @@ static HTC_SEND_QUEUE_RESULT HTCTrySend(HTC_TARGET *target, HTC_PACKET_QUEUE *pCallersSendQueue) { HTC_PACKET_QUEUE sendQueue; /* temp queue to hold packets at various stages */ - HTC_PACKET *pPacket; + struct htc_packet *pPacket; int bundlesSent; int pktsInBundles; int overflow; @@ -546,7 +546,7 @@ static HTC_SEND_QUEUE_RESULT HTCTrySend(HTC_TARGET *target, /* the caller's queue has all the packets that won't fit*/ /* walk through the caller's queue and indicate each one to the send full handler */ - ITERATE_OVER_LIST_ALLOW_REMOVE(&pCallersSendQueue->QueueHead, pPacket, HTC_PACKET, ListLink) { + ITERATE_OVER_LIST_ALLOW_REMOVE(&pCallersSendQueue->QueueHead, pPacket, struct htc_packet, ListLink) { AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Indicating overflowed TX packet: 0x%lX \n", (unsigned long)pPacket)); @@ -672,7 +672,7 @@ int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); struct htc_endpoint *pEndpoint; - HTC_PACKET *pPacket; + struct htc_packet *pPacket; AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCSendPktsMultiple: Queue: 0x%lX, Pkts %d \n", (unsigned long)pPktQueue, HTC_PACKET_QUEUE_DEPTH(pPktQueue))); @@ -709,7 +709,7 @@ int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) } /* HTC API - HTCSendPkt */ -int HTCSendPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket) +int HTCSendPkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket) { HTC_PACKET_QUEUE queue; @@ -840,7 +840,7 @@ void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEnt /* flush endpoint TX queue */ static void HTCFlushEndpointTX(HTC_TARGET *target, struct htc_endpoint *pEndpoint, HTC_TX_TAG Tag) { - HTC_PACKET *pPacket; + struct htc_packet *pPacket; HTC_PACKET_QUEUE discardQueue; HTC_PACKET_QUEUE container; @@ -850,7 +850,7 @@ static void HTCFlushEndpointTX(HTC_TARGET *target, struct htc_endpoint *pEndpoin LOCK_HTC_TX(target); /* interate from the front of the TX queue and flush out packets */ - ITERATE_OVER_LIST_ALLOW_REMOVE(&pEndpoint->TxQueue.QueueHead, pPacket, HTC_PACKET, ListLink) { + ITERATE_OVER_LIST_ALLOW_REMOVE(&pEndpoint->TxQueue.QueueHead, pPacket, struct htc_packet, ListLink) { /* check for removal */ if ((HTC_TX_PACKET_TAG_ALL == Tag) || (Tag == pPacket->PktInfo.AsTx.Tag)) { diff --git a/drivers/staging/ath6kl/htc2/htc_services.c b/drivers/staging/ath6kl/htc2/htc_services.c index 34bba7e8f416..cb0731f45864 100644 --- a/drivers/staging/ath6kl/htc2/htc_services.c +++ b/drivers/staging/ath6kl/htc2/htc_services.c @@ -22,7 +22,7 @@ //============================================================================== #include "htc_internal.h" -void HTCControlTxComplete(void *Context, HTC_PACKET *pPacket) +void HTCControlTxComplete(void *Context, struct htc_packet *pPacket) { /* not implemented * we do not send control TX frames during normal runtime, only during setup */ @@ -30,7 +30,7 @@ void HTCControlTxComplete(void *Context, HTC_PACKET *pPacket) } /* callback when a control message arrives on this endpoint */ -void HTCControlRecv(void *Context, HTC_PACKET *pPacket) +void HTCControlRecv(void *Context, struct htc_packet *pPacket) { AR_DEBUG_ASSERT(pPacket->Endpoint == ENDPOINT_0); @@ -59,7 +59,7 @@ void HTCControlRecv(void *Context, HTC_PACKET *pPacket) int HTCSendSetupComplete(HTC_TARGET *target) { - HTC_PACKET *pSendPacket = NULL; + struct htc_packet *pSendPacket = NULL; int status; do { @@ -127,8 +127,8 @@ int HTCConnectService(HTC_HANDLE HTCHandle, { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); int status = 0; - HTC_PACKET *pRecvPacket = NULL; - HTC_PACKET *pSendPacket = NULL; + struct htc_packet *pRecvPacket = NULL; + struct htc_packet *pSendPacket = NULL; HTC_CONNECT_SERVICE_RESPONSE_MSG *pResponseMsg; HTC_CONNECT_SERVICE_MSG *pConnectMsg; HTC_ENDPOINT_ID assignedEndpoint = ENDPOINT_MAX; diff --git a/drivers/staging/ath6kl/include/hci_transport_api.h b/drivers/staging/ath6kl/include/hci_transport_api.h index ee25c6b5cfdc..3eac19221836 100644 --- a/drivers/staging/ath6kl/include/hci_transport_api.h +++ b/drivers/staging/ath6kl/include/hci_transport_api.h @@ -43,9 +43,9 @@ typedef HTC_ENDPOINT_ID HCI_TRANSPORT_PACKET_TYPE; #define HCI_SET_PACKET_TYPE(pP,s) (pP)->Endpoint = (s) /* callback when an HCI packet was completely sent */ -typedef void (*HCI_TRANSPORT_SEND_PKT_COMPLETE)(void *, HTC_PACKET *); +typedef void (*HCI_TRANSPORT_SEND_PKT_COMPLETE)(void *, struct htc_packet *); /* callback when an HCI packet is received */ -typedef void (*HCI_TRANSPORT_RECV_PKT)(void *, HTC_PACKET *); +typedef void (*HCI_TRANSPORT_RECV_PKT)(void *, struct htc_packet *); /* Optional receive buffer re-fill callback, * On some OSes (like Linux) packets are allocated from a global pool and indicated up * to the network stack. The driver never gets the packets back from the OS. For these OSes @@ -68,7 +68,7 @@ typedef void (*HCI_TRANSPORT_RECV_REFILL)(void *, HCI_TRANSPORT_PACKET_TYPE Ty * NOTE*** This callback is mutually exclusive with the the refill callback above. * * */ -typedef HTC_PACKET *(*HCI_TRANSPORT_RECV_ALLOC)(void *, HCI_TRANSPORT_PACKET_TYPE Type, int Length); +typedef struct htc_packet *(*HCI_TRANSPORT_RECV_ALLOC)(void *, HCI_TRANSPORT_PACKET_TYPE Type, int Length); typedef enum _HCI_SEND_FULL_ACTION { HCI_SEND_FULL_KEEP = 0, /* packet that overflowed should be kept in the queue */ @@ -77,7 +77,7 @@ typedef enum _HCI_SEND_FULL_ACTION { /* callback when an HCI send queue exceeds the caller's MaxSendQueueDepth threshold, * the callback must return the send full action to take (either DROP or KEEP) */ -typedef HCI_SEND_FULL_ACTION (*HCI_TRANSPORT_SEND_FULL)(void *, HTC_PACKET *); +typedef HCI_SEND_FULL_ACTION (*HCI_TRANSPORT_SEND_FULL)(void *, struct htc_packet *); struct hci_transport_properties { int HeadRoom; /* number of bytes in front of HCI packet for header space */ @@ -166,7 +166,7 @@ int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUE @example: @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, bool Synchronous); +int HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -223,7 +223,7 @@ int HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, bool E @see also: HCI_TransportEnableDisableAsyncRecv +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, - HTC_PACKET *pPacket, + struct htc_packet *pPacket, int MaxPollMS); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h index 5878417c3443..ca85bada6d54 100644 --- a/drivers/staging/ath6kl/include/htc_api.h +++ b/drivers/staging/ath6kl/include/htc_api.h @@ -49,7 +49,7 @@ struct htc_init_info { }; /* per service connection send completion */ -typedef void (*HTC_EP_SEND_PKT_COMPLETE)(void *,HTC_PACKET *); +typedef void (*HTC_EP_SEND_PKT_COMPLETE)(void *,struct htc_packet *); /* per service connection callback when a plurality of packets have been sent * The HTC_PACKET_QUEUE is a temporary queue object (e.g. freed on return from the callback) * to hold a list of completed send packets. @@ -58,7 +58,7 @@ typedef void (*HTC_EP_SEND_PKT_COMPLETE)(void *,HTC_PACKET *); * HTC_PACKET_ENQUEUE() */ typedef void (*HTC_EP_SEND_PKT_COMP_MULTIPLE)(void *,HTC_PACKET_QUEUE *); /* per service connection pkt received */ -typedef void (*HTC_EP_RECV_PKT)(void *,HTC_PACKET *); +typedef void (*HTC_EP_RECV_PKT)(void *,struct htc_packet *); /* per service connection callback when a plurality of packets are received * The HTC_PACKET_QUEUE is a temporary queue object (e.g. freed on return from the callback) * to hold a list of recv packets. @@ -94,7 +94,7 @@ typedef void (*HTC_EP_RECV_REFILL)(void *, HTC_ENDPOINT_ID Endpoint); * amount of "committed" memory used to receive packets. * * */ -typedef HTC_PACKET *(*HTC_EP_RECV_ALLOC)(void *, HTC_ENDPOINT_ID Endpoint, int Length); +typedef struct htc_packet *(*HTC_EP_RECV_ALLOC)(void *, HTC_ENDPOINT_ID Endpoint, int Length); typedef enum _HTC_SEND_FULL_ACTION { HTC_SEND_FULL_KEEP = 0, /* packet that overflowed should be kept in the queue */ @@ -114,7 +114,7 @@ typedef enum _HTC_SEND_FULL_ACTION { * closed loop mechanism will prevent the network stack from overunning the NIC * The packet to keep or drop is passed for inspection to the registered handler the handler * must ONLY inspect the packet, it may not free or reclaim the packet. */ -typedef HTC_SEND_FULL_ACTION (*HTC_EP_SEND_QUEUE_FULL)(void *, HTC_PACKET *pPacket); +typedef HTC_SEND_FULL_ACTION (*HTC_EP_SEND_QUEUE_FULL)(void *, struct htc_packet *pPacket); struct htc_ep_callbacks { void *pContext; /* context for each callback */ @@ -348,7 +348,7 @@ int HTCStart(HTC_HANDLE HTCHandle); @example: @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HTCAddReceivePkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket); +int HTCAddReceivePkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Connect to an HTC service @function name: HTCConnectService @@ -377,7 +377,7 @@ int HTCConnectService(HTC_HANDLE HTCHandle, @example: @see also: HTCFlushEndpoint +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HTCSendPkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket); +int HTCSendPkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Stop HTC service communications @function name: HTCStop diff --git a/drivers/staging/ath6kl/include/htc_packet.h b/drivers/staging/ath6kl/include/htc_packet.h index 9282e909fc8c..4311c932b302 100644 --- a/drivers/staging/ath6kl/include/htc_packet.h +++ b/drivers/staging/ath6kl/include/htc_packet.h @@ -42,9 +42,9 @@ typedef enum ENDPOINT_MAX, } HTC_ENDPOINT_ID; -struct _HTC_PACKET; +struct htc_packet; -typedef void (* HTC_PACKET_COMPLETION)(void *,struct _HTC_PACKET *); +typedef void (* HTC_PACKET_COMPLETION)(void *,struct htc_packet *); typedef u16 HTC_TX_TAG; @@ -68,7 +68,7 @@ typedef struct _HTC_RX_PACKET_INFO { #define HTC_RX_FLAGS_INDICATE_MORE_PKTS (1 << 0) /* more packets on this endpoint are being fetched */ /* wrapper around endpoint-specific packets */ -typedef struct _HTC_PACKET { +struct htc_packet { struct dl_list ListLink; /* double link */ void *pPktContext; /* caller's per packet specific context */ @@ -98,7 +98,7 @@ typedef struct _HTC_PACKET { /* the following fields are for internal HTC use */ HTC_PACKET_COMPLETION Completion; /* completion */ void *pContext; /* HTC private completion context */ -} HTC_PACKET; +}; @@ -165,11 +165,11 @@ typedef struct _HTC_PACKET_QUEUE { /* test if a queue is empty */ #define HTC_QUEUE_EMPTY(pQ) ((pQ)->Depth == 0) /* get packet at head without removing it */ -static INLINE HTC_PACKET *HTC_GET_PKT_AT_HEAD(HTC_PACKET_QUEUE *queue) { +static INLINE struct htc_packet *HTC_GET_PKT_AT_HEAD(HTC_PACKET_QUEUE *queue) { if (queue->Depth == 0) { return NULL; } - return A_CONTAINING_STRUCT((DL_LIST_GET_ITEM_AT_HEAD(&queue->QueueHead)),HTC_PACKET,ListLink); + return A_CONTAINING_STRUCT((DL_LIST_GET_ITEM_AT_HEAD(&queue->QueueHead)),struct htc_packet,ListLink); } /* remove a packet from a queue, where-ever it is in the queue */ #define HTC_PACKET_REMOVE(pQ,p) \ @@ -179,21 +179,21 @@ static INLINE HTC_PACKET *HTC_GET_PKT_AT_HEAD(HTC_PACKET_QUEUE *queue) { } /* dequeue an HTC packet from the head of the queue */ -static INLINE HTC_PACKET *HTC_PACKET_DEQUEUE(HTC_PACKET_QUEUE *queue) { +static INLINE struct htc_packet *HTC_PACKET_DEQUEUE(HTC_PACKET_QUEUE *queue) { struct dl_list *pItem = DL_ListRemoveItemFromHead(&queue->QueueHead); if (pItem != NULL) { queue->Depth--; - return A_CONTAINING_STRUCT(pItem, HTC_PACKET, ListLink); + return A_CONTAINING_STRUCT(pItem, struct htc_packet, ListLink); } return NULL; } /* dequeue an HTC packet from the tail of the queue */ -static INLINE HTC_PACKET *HTC_PACKET_DEQUEUE_TAIL(HTC_PACKET_QUEUE *queue) { +static INLINE struct htc_packet *HTC_PACKET_DEQUEUE_TAIL(HTC_PACKET_QUEUE *queue) { struct dl_list *pItem = DL_ListRemoveItemFromTail(&queue->QueueHead); if (pItem != NULL) { queue->Depth--; - return A_CONTAINING_STRUCT(pItem, HTC_PACKET, ListLink); + return A_CONTAINING_STRUCT(pItem, struct htc_packet, ListLink); } return NULL; } @@ -220,7 +220,7 @@ static INLINE HTC_PACKET *HTC_PACKET_DEQUEUE_TAIL(HTC_PACKET_QUEUE *queue) { } #define HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pQ, pPTemp) \ - ITERATE_OVER_LIST_ALLOW_REMOVE(&(pQ)->QueueHead,(pPTemp), HTC_PACKET, ListLink) + ITERATE_OVER_LIST_ALLOW_REMOVE(&(pQ)->QueueHead,(pPTemp), struct htc_packet, ListLink) #define HTC_PACKET_QUEUE_ITERATE_END ITERATE_END diff --git a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c index 3e9c95ea4eb4..4f18f4306465 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c @@ -53,18 +53,18 @@ static int SendHCICommand(struct ar3k_config_info *pConfig, u8 *pBuffer, int Length) { - HTC_PACKET *pPacket = NULL; + struct htc_packet *pPacket = NULL; int status = 0; do { - pPacket = (HTC_PACKET *)A_MALLOC(sizeof(HTC_PACKET)); + pPacket = (struct htc_packet *)A_MALLOC(sizeof(struct htc_packet)); if (NULL == pPacket) { status = A_NO_MEMORY; break; } - A_MEMZERO(pPacket,sizeof(HTC_PACKET)); + A_MEMZERO(pPacket,sizeof(struct htc_packet)); SET_HTC_PACKET_INFO_TX(pPacket, NULL, pBuffer, @@ -89,18 +89,18 @@ static int RecvHCIEvent(struct ar3k_config_info *pConfig, int *pLength) { int status = 0; - HTC_PACKET *pRecvPacket = NULL; + struct htc_packet *pRecvPacket = NULL; do { - pRecvPacket = (HTC_PACKET *)A_MALLOC(sizeof(HTC_PACKET)); + pRecvPacket = (struct htc_packet *)A_MALLOC(sizeof(struct htc_packet)); if (NULL == pRecvPacket) { status = A_NO_MEMORY; AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n")); break; } - A_MEMZERO(pRecvPacket,sizeof(HTC_PACKET)); + A_MEMZERO(pRecvPacket,sizeof(struct htc_packet)); SET_HTC_PACKET_INFO_RX_REFILL(pRecvPacket,NULL,pBuffer,*pLength,HCI_EVENT_TYPE); diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index ebfe1e8b0f87..ebfc7fdb53ae 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -313,13 +313,13 @@ int ar6000_configure_target(AR_SOFTC_T *ar); static void ar6000_target_failure(void *Instance, int Status); -static void ar6000_rx(void *Context, HTC_PACKET *pPacket); +static void ar6000_rx(void *Context, struct htc_packet *pPacket); static void ar6000_rx_refill(void *Context,HTC_ENDPOINT_ID Endpoint); static void ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPackets); -static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, HTC_PACKET *pPacket); +static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, struct htc_packet *pPacket); #ifdef ATH_AR6K_11N_SUPPORT static void ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num); @@ -327,7 +327,7 @@ static void ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num); static void ar6000_deliver_frames_to_nw_stack(void * dev, void *osbuf); //static void ar6000_deliver_frames_to_bt_stack(void * dev, void *osbuf); -static HTC_PACKET *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length); +static struct htc_packet *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length); static void ar6000_refill_amsdu_rxbufs(AR_SOFTC_T *ar, int Count); @@ -3376,7 +3376,7 @@ applyAPTCHeuristics(AR_SOFTC_T *ar) } #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ -static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, HTC_PACKET *pPacket) +static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, struct htc_packet *pPacket) { AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; HTC_SEND_FULL_ACTION action = HTC_SEND_FULL_KEEP; @@ -3470,7 +3470,7 @@ ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPacketQueue) HTC_ENDPOINT_ID eid; bool wakeEvent = false; struct sk_buff_head skb_queue; - HTC_PACKET *pPacket; + struct htc_packet *pPacket; struct sk_buff *pktSkb; bool flushing = false; @@ -3642,7 +3642,7 @@ sta_t *ieee80211_find_conn_for_aid(AR_SOFTC_T *ar, u8 aid) */ int pktcount; static void -ar6000_rx(void *Context, HTC_PACKET *pPacket) +ar6000_rx(void *Context, struct htc_packet *pPacket) { AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; struct sk_buff *skb = (struct sk_buff *)pPacket->pPktContext; @@ -3991,7 +3991,7 @@ ar6000_rx_refill(void *Context, HTC_ENDPOINT_ID Endpoint) void *osBuf; int RxBuffers; int buffersToRefill; - HTC_PACKET *pPacket; + struct htc_packet *pPacket; HTC_PACKET_QUEUE queue; buffersToRefill = (int)AR6000_MAX_RX_BUFFERS - @@ -4014,7 +4014,7 @@ ar6000_rx_refill(void *Context, HTC_ENDPOINT_ID Endpoint) } /* the HTC packet wrapper is at the head of the reserved area * in the skb */ - pPacket = (HTC_PACKET *)(A_NETBUF_HEAD(osBuf)); + pPacket = (struct htc_packet *)(A_NETBUF_HEAD(osBuf)); /* set re-fill info */ SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_BUFFER_SIZE,Endpoint); /* add to queue */ @@ -4031,7 +4031,7 @@ ar6000_rx_refill(void *Context, HTC_ENDPOINT_ID Endpoint) /* clean up our amsdu buffer list */ static void ar6000_cleanup_amsdu_rxbufs(AR_SOFTC_T *ar) { - HTC_PACKET *pPacket; + struct htc_packet *pPacket; void *osBuf; /* empty AMSDU buffer queue and free OS bufs */ @@ -4060,7 +4060,7 @@ static void ar6000_cleanup_amsdu_rxbufs(AR_SOFTC_T *ar) /* refill the amsdu buffer list */ static void ar6000_refill_amsdu_rxbufs(AR_SOFTC_T *ar, int Count) { - HTC_PACKET *pPacket; + struct htc_packet *pPacket; void *osBuf; while (Count > 0) { @@ -4070,7 +4070,7 @@ static void ar6000_refill_amsdu_rxbufs(AR_SOFTC_T *ar, int Count) } /* the HTC packet wrapper is at the head of the reserved area * in the skb */ - pPacket = (HTC_PACKET *)(A_NETBUF_HEAD(osBuf)); + pPacket = (struct htc_packet *)(A_NETBUF_HEAD(osBuf)); /* set re-fill info */ SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_AMSDU_BUFFER_SIZE,0); @@ -4090,9 +4090,9 @@ static void ar6000_refill_amsdu_rxbufs(AR_SOFTC_T *ar, int Count) * keep the allocation size the same to optimize cached-slab allocations. * * */ -static HTC_PACKET *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length) +static struct htc_packet *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length) { - HTC_PACKET *pPacket = NULL; + struct htc_packet *pPacket = NULL; AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; int refillCount = 0; diff --git a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c index 8a197ff9a36c..f8637f6b4477 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c @@ -26,7 +26,7 @@ #ifdef HTC_RAW_INTERFACE static void -ar6000_htc_raw_read_cb(void *Context, HTC_PACKET *pPacket) +ar6000_htc_raw_read_cb(void *Context, struct htc_packet *pPacket) { AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; raw_htc_buffer *busy; @@ -70,7 +70,7 @@ ar6000_htc_raw_read_cb(void *Context, HTC_PACKET *pPacket) } static void -ar6000_htc_raw_write_cb(void *Context, HTC_PACKET *pPacket) +ar6000_htc_raw_write_cb(void *Context, struct htc_packet *pPacket) { AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; raw_htc_buffer *free; diff --git a/drivers/staging/ath6kl/os/linux/export_hci_transport.c b/drivers/staging/ath6kl/os/linux/export_hci_transport.c index 79b30ebab797..319dc2ea731c 100644 --- a/drivers/staging/ath6kl/os/linux/export_hci_transport.c +++ b/drivers/staging/ath6kl/os/linux/export_hci_transport.c @@ -39,12 +39,12 @@ HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, struct hci_transport_config_info *pInfo); void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans); int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue); -int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, bool Synchronous); +int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous); void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans); int (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans); int (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); int (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans, - HTC_PACKET *pPacket, + struct htc_packet *pPacket, int MaxPollMS); int (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud); int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index d30ca24a1d58..4324a9d1b0ef 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -139,16 +139,16 @@ static inline void FreeBtOsBuf(struct ar6k_hci_bridge_info *pHcidevInfo, void *o } } -static void FreeHTCStruct(struct ar6k_hci_bridge_info *pHcidevInfo, HTC_PACKET *pPacket) +static void FreeHTCStruct(struct ar6k_hci_bridge_info *pHcidevInfo, struct htc_packet *pPacket) { LOCK_BRIDGE(pHcidevInfo); HTC_PACKET_ENQUEUE(&pHcidevInfo->HTCPacketStructHead,pPacket); UNLOCK_BRIDGE(pHcidevInfo); } -static HTC_PACKET * AllocHTCStruct(struct ar6k_hci_bridge_info *pHcidevInfo) +static struct htc_packet * AllocHTCStruct(struct ar6k_hci_bridge_info *pHcidevInfo) { - HTC_PACKET *pPacket = NULL; + struct htc_packet *pPacket = NULL; LOCK_BRIDGE(pHcidevInfo); pPacket = HTC_PACKET_DEQUEUE(&pHcidevInfo->HTCPacketStructHead); UNLOCK_BRIDGE(pHcidevInfo); @@ -164,7 +164,7 @@ static void RefillRecvBuffers(struct ar6k_hci_bridge_info *pHcidevInfo, int length, i; void *osBuf = NULL; HTC_PACKET_QUEUE queue; - HTC_PACKET *pPacket; + struct htc_packet *pPacket; INIT_HTC_PACKET_QUEUE(&queue); @@ -347,7 +347,7 @@ static void ar6000_hci_transport_removed(void *pContext) pHcidevInfo->pHCIDev = NULL; } -static void ar6000_hci_send_complete(void *pContext, HTC_PACKET *pPacket) +static void ar6000_hci_send_complete(void *pContext, struct htc_packet *pPacket) { struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext; void *osbuf = pPacket->pPktContext; @@ -365,7 +365,7 @@ static void ar6000_hci_send_complete(void *pContext, HTC_PACKET *pPacket) } -static void ar6000_hci_pkt_recv(void *pContext, HTC_PACKET *pPacket) +static void ar6000_hci_pkt_recv(void *pContext, struct htc_packet *pPacket) { struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext; struct sk_buff *skb; @@ -447,7 +447,7 @@ static void ar6000_hci_pkt_refill(void *pContext, HCI_TRANSPORT_PACKET_TYPE Typ } -static HCI_SEND_FULL_ACTION ar6000_hci_pkt_send_full(void *pContext, HTC_PACKET *pPacket) +static HCI_SEND_FULL_ACTION ar6000_hci_pkt_send_full(void *pContext, struct htc_packet *pPacket) { struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext; HCI_SEND_FULL_ACTION action = HCI_SEND_FULL_KEEP; @@ -472,7 +472,7 @@ int ar6000_setup_hci(AR_SOFTC_T *ar) struct hci_transport_config_info config; int status = 0; int i; - HTC_PACKET *pPacket; + struct htc_packet *pPacket; struct ar6k_hci_bridge_info *pHcidevInfo; @@ -509,14 +509,14 @@ int ar6000_setup_hci(AR_SOFTC_T *ar) AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in test mode... \n")); } - pHcidevInfo->pHTCStructAlloc = (u8 *)A_MALLOC((sizeof(HTC_PACKET)) * NUM_HTC_PACKET_STRUCTS); + pHcidevInfo->pHTCStructAlloc = (u8 *)A_MALLOC((sizeof(struct htc_packet)) * NUM_HTC_PACKET_STRUCTS); if (NULL == pHcidevInfo->pHTCStructAlloc) { status = A_NO_MEMORY; break; } - pPacket = (HTC_PACKET *)pHcidevInfo->pHTCStructAlloc; + pPacket = (struct htc_packet *)pHcidevInfo->pHTCStructAlloc; for (i = 0; i < NUM_HTC_PACKET_STRUCTS; i++,pPacket++) { FreeHTCStruct(pHcidevInfo,pPacket); } @@ -604,7 +604,7 @@ int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb) int status = 0; int length; EPPING_HEADER *pHeader; - HTC_PACKET *pPacket; + struct htc_packet *pPacket; HTC_TX_TAG htc_tag = AR6K_DATA_PKT_TAG; #ifdef EXPORT_HCI_BRIDGE_INTERFACE struct ar6k_hci_bridge_info *pHcidevInfo = g_pHcidevInfo; @@ -711,7 +711,7 @@ static int bt_send_frame(struct sk_buff *skb) struct hci_dev *hdev = (struct hci_dev *)skb->dev; HCI_TRANSPORT_PACKET_TYPE type; struct ar6k_hci_bridge_info *pHcidevInfo; - HTC_PACKET *pPacket; + struct htc_packet *pPacket; int status = 0; struct sk_buff *txSkb = NULL; diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index a20913380303..29ac8300c479 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -362,7 +362,7 @@ typedef struct { int currPtr; int length; unsigned char data[HTC_RAW_BUFFER_SIZE]; - HTC_PACKET HTCPacket; + struct htc_packet HTCPacket; } raw_htc_buffer; #ifdef CONFIG_HOST_TCMD_SUPPORT @@ -410,7 +410,7 @@ struct ar_node_mapping { struct ar_cookie { unsigned long arc_bp[2]; /* Must be first field */ - HTC_PACKET HtcPkt; /* HTC packet wrapper */ + struct htc_packet HtcPkt; /* HTC packet wrapper */ struct ar_cookie *arc_list_next; }; diff --git a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h index cf66717de391..8e52de7c2808 100644 --- a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h +++ b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h @@ -28,12 +28,12 @@ extern HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, struct hci_transport_config_info *pInfo); extern void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans); extern int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue); -extern int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, bool Synchronous); +extern int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous); extern void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans); extern int (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans); extern int (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); extern int (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans, - HTC_PACKET *pPacket, + struct htc_packet *pPacket, int MaxPollMS); extern int (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud); extern int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); diff --git a/drivers/staging/ath6kl/os/linux/netbuf.c b/drivers/staging/ath6kl/os/linux/netbuf.c index 63acedf8e3af..a9c96b315c48 100644 --- a/drivers/staging/ath6kl/os/linux/netbuf.c +++ b/drivers/staging/ath6kl/os/linux/netbuf.c @@ -63,8 +63,8 @@ a_netbuf_alloc(int size) { struct sk_buff *skb; size += 2 * (A_GET_CACHE_LINE_BYTES()); /* add some cacheline space at front and back of buffer */ - skb = dev_alloc_skb(AR6000_DATA_OFFSET + sizeof(HTC_PACKET) + size); - skb_reserve(skb, AR6000_DATA_OFFSET + sizeof(HTC_PACKET) + A_GET_CACHE_LINE_BYTES()); + skb = dev_alloc_skb(AR6000_DATA_OFFSET + sizeof(struct htc_packet) + size); + skb_reserve(skb, AR6000_DATA_OFFSET + sizeof(struct htc_packet) + A_GET_CACHE_LINE_BYTES()); return ((void *)skb); } -- cgit v1.2.3 From 6ca0f664e18f967dad2ff47c4de447b1d37fbdfc Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:58 -0700 Subject: ath6kl: remove-typedef HTC_PACKET_QUEUE remove-typedef -s HTC_PACKET_QUEUE \ "struct htc_packet_queue" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/AR6000/ar6k.h | 2 +- .../ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c | 18 ++++++++-------- drivers/staging/ath6kl/htc2/htc.c | 4 ++-- drivers/staging/ath6kl/htc2/htc_internal.h | 14 ++++++------- drivers/staging/ath6kl/htc2/htc_recv.c | 24 +++++++++++----------- drivers/staging/ath6kl/htc2/htc_send.c | 22 ++++++++++---------- drivers/staging/ath6kl/include/hci_transport_api.h | 2 +- drivers/staging/ath6kl/include/htc_api.h | 16 +++++++-------- drivers/staging/ath6kl/include/htc_packet.h | 10 ++++----- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 8 ++++---- .../staging/ath6kl/os/linux/export_hci_transport.c | 2 +- drivers/staging/ath6kl/os/linux/hci_bridge.c | 4 ++-- .../staging/ath6kl/os/linux/include/ar6000_drv.h | 2 +- .../ath6kl/os/linux/include/export_hci_transport.h | 2 +- 14 files changed, 65 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h index b01542e2c3a7..1ff221838c0f 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h @@ -118,7 +118,7 @@ struct ar6k_device { struct hif_device_mbox_info MailBoxInfo; HIF_PENDING_EVENTS_FUNC GetPendingEventsFunc; void *HTCContext; - HTC_PACKET_QUEUE RegisterIOList; + struct htc_packet_queue RegisterIOList; struct ar6k_async_reg_io_buffer RegIOBuffers[AR6K_MAX_REG_IO_BUFFERS]; void (*TargetFailureCallback)(void *Context); int (*MessagePendingCallback)(void *Context, diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c index 90e303f342a8..8cf46b13390d 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c @@ -63,9 +63,9 @@ struct gmbox_proto_hci_uart { u32 RecvStateFlags; u32 SendStateFlags; HCI_TRANSPORT_PACKET_TYPE WaitBufferType; - HTC_PACKET_QUEUE SendQueue; /* write queue holding HCI Command and ACL packets */ - HTC_PACKET_QUEUE HCIACLRecvBuffers; /* recv queue holding buffers for incomming ACL packets */ - HTC_PACKET_QUEUE HCIEventBuffers; /* recv queue holding buffers for incomming event packets */ + struct htc_packet_queue SendQueue; /* write queue holding HCI Command and ACL packets */ + struct htc_packet_queue HCIACLRecvBuffers; /* recv queue holding buffers for incomming ACL packets */ + struct htc_packet_queue HCIEventBuffers; /* recv queue holding buffers for incomming event packets */ struct ar6k_device *pDev; A_MUTEX_T HCIRxLock; A_MUTEX_T HCITxLock; @@ -366,7 +366,7 @@ static int HCIUartMessagePending(void *pContext, u8 LookAheadBytes[], int ValidB LOCK_HCI_RX(pProt); } else { - HTC_PACKET_QUEUE *pQueue; + struct htc_packet_queue *pQueue; /* user is using a refill handler that can refill multiple HTC buffers */ /* select buffer queue */ @@ -483,7 +483,7 @@ static int HCIUartMessagePending(void *pContext, u8 LookAheadBytes[], int ValidB /* check if we need to refill recv buffers */ if ((pProt->HCIConfig.pHCIPktRecvRefill != NULL) && !recvRefillCalled) { - HTC_PACKET_QUEUE *pQueue; + struct htc_packet_queue *pQueue; int watermark; if (pktType == HCI_ACL_TYPE) { @@ -514,7 +514,7 @@ static int HCIUartMessagePending(void *pContext, u8 LookAheadBytes[], int ValidB /* see if we need to recycle the recv buffer */ if (status && (pPacket != NULL)) { - HTC_PACKET_QUEUE queue; + struct htc_packet_queue queue; if (A_EPROTO == status) { DebugDumpBytes(pPacket->pBuffer, totalRecvLength, "Bad HCI-UART Recv packet"); @@ -797,7 +797,7 @@ static int HCITrySend(struct gmbox_proto_hci_uart *pProt, struct htc_packet *pPa static void FlushSendQueue(struct gmbox_proto_hci_uart *pProt) { struct htc_packet *pPacket; - HTC_PACKET_QUEUE discardQueue; + struct htc_packet_queue discardQueue; INIT_HTC_PACKET_QUEUE(&discardQueue); @@ -820,7 +820,7 @@ static void FlushSendQueue(struct gmbox_proto_hci_uart *pProt) static void FlushRecvBuffers(struct gmbox_proto_hci_uart *pProt) { - HTC_PACKET_QUEUE discardQueue; + struct htc_packet_queue discardQueue; struct htc_packet *pPacket; INIT_HTC_PACKET_QUEUE(&discardQueue); @@ -1001,7 +1001,7 @@ void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans) AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportAttach \n")); } -int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue) +int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue) { struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; int status = 0; diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index 04ba80ef8227..bf4fdb34e9e9 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -43,14 +43,14 @@ ATH_DEBUG_INSTANTIATE_MODULE_VAR(htc, static void HTCReportFailure(void *Context); static void ResetEndpointStates(HTC_TARGET *target); -void HTCFreeControlBuffer(HTC_TARGET *target, struct htc_packet *pPacket, HTC_PACKET_QUEUE *pList) +void HTCFreeControlBuffer(HTC_TARGET *target, struct htc_packet *pPacket, struct htc_packet_queue *pList) { LOCK_HTC(target); HTC_PACKET_ENQUEUE(pList,pPacket); UNLOCK_HTC(target); } -struct htc_packet *HTCAllocControlBuffer(HTC_TARGET *target, HTC_PACKET_QUEUE *pList) +struct htc_packet *HTCAllocControlBuffer(HTC_TARGET *target, struct htc_packet_queue *pList) { struct htc_packet *pPacket; diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h index 5f85350b50a1..67de917dc6f5 100644 --- a/drivers/staging/ath6kl/htc2/htc_internal.h +++ b/drivers/staging/ath6kl/htc2/htc_internal.h @@ -69,15 +69,15 @@ struct htc_endpoint { HTC_ENDPOINT_ID Id; HTC_SERVICE_ID ServiceID; /* service ID this endpoint is bound to non-zero value means this endpoint is in use */ - HTC_PACKET_QUEUE TxQueue; /* HTC frame buffer TX queue */ - HTC_PACKET_QUEUE RxBuffers; /* HTC frame buffer RX list */ + struct htc_packet_queue TxQueue; /* HTC frame buffer TX queue */ + struct htc_packet_queue RxBuffers; /* HTC frame buffer RX list */ struct htc_endpoint_credit_dist CreditDist; /* credit distribution structure (exposed to driver layer) */ struct htc_ep_callbacks EpCallBacks; /* callbacks associated with this endpoint */ int MaxTxQueueDepth; /* max depth of the TX queue before we need to call driver's full handler */ int MaxMsgLength; /* max length of endpoint message */ int TxProcessCount; /* reference count to continue tx processing */ - HTC_PACKET_QUEUE RecvIndicationQueue; /* recv packets ready to be indicated */ + struct htc_packet_queue RecvIndicationQueue; /* recv packets ready to be indicated */ int RxProcessCount; /* reference count to allow single processing context */ struct _HTC_TARGET *target; /* back pointer to target */ u8 SeqNo; /* TX seq no (helpful) for debugging */ @@ -112,8 +112,8 @@ typedef struct _HTC_TARGET { struct htc_endpoint EndPoint[ENDPOINT_MAX]; struct htc_control_buffer HTCControlBuffers[NUM_CONTROL_BUFFERS]; struct htc_endpoint_credit_dist *EpCreditDistributionListHead; - HTC_PACKET_QUEUE ControlBufferTXFreeList; - HTC_PACKET_QUEUE ControlBufferRXFreeList; + struct htc_packet_queue ControlBufferTXFreeList; + struct htc_packet_queue ControlBufferRXFreeList; HTC_CREDIT_DIST_CALLBACK DistributeCredits; HTC_CREDIT_INIT_CALLBACK InitCredits; void *pCredDistContext; @@ -165,8 +165,8 @@ typedef struct _HTC_TARGET { void HTCControlTxComplete(void *Context, struct htc_packet *pPacket); void HTCControlRecv(void *Context, struct htc_packet *pPacket); int HTCWaitforControlMessage(HTC_TARGET *target, struct htc_packet **ppControlPacket); -struct htc_packet *HTCAllocControlBuffer(HTC_TARGET *target, HTC_PACKET_QUEUE *pList); -void HTCFreeControlBuffer(HTC_TARGET *target, struct htc_packet *pPacket, HTC_PACKET_QUEUE *pList); +struct htc_packet *HTCAllocControlBuffer(HTC_TARGET *target, struct htc_packet_queue *pList); +void HTCFreeControlBuffer(HTC_TARGET *target, struct htc_packet *pPacket, struct htc_packet_queue *pList); int HTCIssueSend(HTC_TARGET *target, struct htc_packet *pPacket); void HTCRecvCompleteHandler(void *Context, struct htc_packet *pPacket); int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched); diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c index f70296321b72..8ad1d03fceb3 100644 --- a/drivers/staging/ath6kl/htc2/htc_recv.c +++ b/drivers/staging/ath6kl/htc2/htc_recv.c @@ -51,7 +51,7 @@ #endif static void DoRecvCompletion(struct htc_endpoint *pEndpoint, - HTC_PACKET_QUEUE *pQueueToIndicate) + struct htc_packet_queue *pQueueToIndicate) { do { @@ -434,7 +434,7 @@ static INLINE void HTCAsyncRecvCheckMorePackets(HTC_TARGET *target, /* unload the recv completion queue */ static INLINE void DrainRecvIndicationQueue(HTC_TARGET *target, struct htc_endpoint *pEndpoint) { - HTC_PACKET_QUEUE recvCompletions; + struct htc_packet_queue recvCompletions; AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+DrainRecvIndicationQueue \n")); @@ -690,7 +690,7 @@ static int AllocAndPrepareRxPackets(HTC_TARGET *target, u32 LookAheads[], int Messages, struct htc_endpoint *pEndpoint, - HTC_PACKET_QUEUE *pQueue) + struct htc_packet_queue *pQueue) { int status = 0; struct htc_packet *pPacket; @@ -889,7 +889,7 @@ static void HTCAsyncRecvScatterCompletion(struct hif_scatter_req *pScatterReq) HTC_TARGET *target = (HTC_TARGET *)pScatterReq->Context; int status; bool partialBundle = false; - HTC_PACKET_QUEUE localRecvQueue; + struct htc_packet_queue localRecvQueue; bool procError = false; AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCAsyncRecvScatterCompletion TotLen: %d Entries: %d\n", @@ -985,8 +985,8 @@ static void HTCAsyncRecvScatterCompletion(struct hif_scatter_req *pScatterReq) } static int HTCIssueRecvPacketBundle(HTC_TARGET *target, - HTC_PACKET_QUEUE *pRecvPktQueue, - HTC_PACKET_QUEUE *pSyncCompletionQueue, + struct htc_packet_queue *pRecvPktQueue, + struct htc_packet_queue *pSyncCompletionQueue, int *pNumPacketsFetched, bool PartialBundle) { @@ -1126,7 +1126,7 @@ int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLook bool asyncProc = false; u32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; int pktsFetched; - HTC_PACKET_QUEUE recvPktQueue, syncCompletedPktsQueue; + struct htc_packet_queue recvPktQueue, syncCompletedPktsQueue; bool partialBundle; HTC_ENDPOINT_ID id; int totalFetched = 0; @@ -1283,7 +1283,7 @@ int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLook /* unload sync completion queue */ while (!HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) { - HTC_PACKET_QUEUE container; + struct htc_packet_queue container; pPacket = HTC_PACKET_DEQUEUE(&syncCompletedPktsQueue); A_ASSERT(pPacket != NULL); @@ -1385,7 +1385,7 @@ int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLook return status; } -int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) +int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); struct htc_endpoint *pEndpoint; @@ -1457,7 +1457,7 @@ int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) /* Makes a buffer available to the HTC module */ int HTCAddReceivePkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket) { - HTC_PACKET_QUEUE queue; + struct htc_packet_queue queue; INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket); return HTCAddReceivePktMultiple(HTCHandle, &queue); } @@ -1486,10 +1486,10 @@ void HTCUnblockRecv(HTC_HANDLE HTCHandle) } } -static void HTCFlushRxQueue(HTC_TARGET *target, struct htc_endpoint *pEndpoint, HTC_PACKET_QUEUE *pQueue) +static void HTCFlushRxQueue(HTC_TARGET *target, struct htc_endpoint *pEndpoint, struct htc_packet_queue *pQueue) { struct htc_packet *pPacket; - HTC_PACKET_QUEUE container; + struct htc_packet_queue container; LOCK_HTC_RX(target); diff --git a/drivers/staging/ath6kl/htc2/htc_send.c b/drivers/staging/ath6kl/htc2/htc_send.c index 8fb05d9fdbc8..805265880820 100644 --- a/drivers/staging/ath6kl/htc2/htc_send.c +++ b/drivers/staging/ath6kl/htc2/htc_send.c @@ -44,7 +44,7 @@ typedef enum _HTC_SEND_QUEUE_RESULT { } static void DoSendCompletion(struct htc_endpoint *pEndpoint, - HTC_PACKET_QUEUE *pQueueToIndicate) + struct htc_packet_queue *pQueueToIndicate) { do { @@ -105,7 +105,7 @@ static void HTCSendPktCompletionHandler(void *Context, struct htc_packet *pPacke { HTC_TARGET *target = (HTC_TARGET *)Context; struct htc_endpoint *pEndpoint = &target->EndPoint[pPacket->Endpoint]; - HTC_PACKET_QUEUE container; + struct htc_packet_queue container; CompleteSentPacket(target,pEndpoint,pPacket); INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket); @@ -148,7 +148,7 @@ int HTCIssueSend(HTC_TARGET *target, struct htc_packet *pPacket) /* get HTC send packets from the TX queue on an endpoint */ static INLINE void GetHTCSendPackets(HTC_TARGET *target, struct htc_endpoint *pEndpoint, - HTC_PACKET_QUEUE *pQueue) + struct htc_packet_queue *pQueue) { int creditsRequired; int remainder; @@ -271,7 +271,7 @@ static void HTCAsyncSendScatterCompletion(struct hif_scatter_req *pScatterReq) struct htc_endpoint *pEndpoint = (struct htc_endpoint *)pScatterReq->Context; HTC_TARGET *target = (HTC_TARGET *)pEndpoint->target; int status = 0; - HTC_PACKET_QUEUE sendCompletes; + struct htc_packet_queue sendCompletes; INIT_HTC_PACKET_QUEUE(&sendCompletes); @@ -310,7 +310,7 @@ static void HTCAsyncSendScatterCompletion(struct hif_scatter_req *pScatterReq) * - we drop below the minimum number of messages for a bundle * */ static void HTCIssueSendBundle(struct htc_endpoint *pEndpoint, - HTC_PACKET_QUEUE *pQueue, + struct htc_packet_queue *pQueue, int *pBundlesSent, int *pTotalBundlesPkts) { @@ -479,9 +479,9 @@ static void HTCIssueSendBundle(struct htc_endpoint *pEndpoint, * this function returns the result of the attempt to send a queue of HTC packets */ static HTC_SEND_QUEUE_RESULT HTCTrySend(HTC_TARGET *target, struct htc_endpoint *pEndpoint, - HTC_PACKET_QUEUE *pCallersSendQueue) + struct htc_packet_queue *pCallersSendQueue) { - HTC_PACKET_QUEUE sendQueue; /* temp queue to hold packets at various stages */ + struct htc_packet_queue sendQueue; /* temp queue to hold packets at various stages */ struct htc_packet *pPacket; int bundlesSent; int pktsInBundles; @@ -668,7 +668,7 @@ static HTC_SEND_QUEUE_RESULT HTCTrySend(HTC_TARGET *target, return HTC_SEND_QUEUE_OK; } -int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) +int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); struct htc_endpoint *pEndpoint; @@ -711,7 +711,7 @@ int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue) /* HTC API - HTCSendPkt */ int HTCSendPkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket) { - HTC_PACKET_QUEUE queue; + struct htc_packet_queue queue; AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+-HTCSendPkt: Enter endPointId: %d, buffer: 0x%lX, length: %d \n", @@ -841,8 +841,8 @@ void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEnt static void HTCFlushEndpointTX(HTC_TARGET *target, struct htc_endpoint *pEndpoint, HTC_TX_TAG Tag) { struct htc_packet *pPacket; - HTC_PACKET_QUEUE discardQueue; - HTC_PACKET_QUEUE container; + struct htc_packet_queue discardQueue; + struct htc_packet_queue container; /* initialize the discard queue */ INIT_HTC_PACKET_QUEUE(&discardQueue); diff --git a/drivers/staging/ath6kl/include/hci_transport_api.h b/drivers/staging/ath6kl/include/hci_transport_api.h index 3eac19221836..5e903fad23fc 100644 --- a/drivers/staging/ath6kl/include/hci_transport_api.h +++ b/drivers/staging/ath6kl/include/hci_transport_api.h @@ -141,7 +141,7 @@ void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans); @example: @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue); +int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Send an HCI packet packet diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h index ca85bada6d54..ae41f985c9f3 100644 --- a/drivers/staging/ath6kl/include/htc_api.h +++ b/drivers/staging/ath6kl/include/htc_api.h @@ -51,21 +51,21 @@ struct htc_init_info { /* per service connection send completion */ typedef void (*HTC_EP_SEND_PKT_COMPLETE)(void *,struct htc_packet *); /* per service connection callback when a plurality of packets have been sent - * The HTC_PACKET_QUEUE is a temporary queue object (e.g. freed on return from the callback) + * The struct htc_packet_queue is a temporary queue object (e.g. freed on return from the callback) * to hold a list of completed send packets. * If the handler cannot fully traverse the packet queue before returning, it should * transfer the items of the queue into the caller's private queue using: * HTC_PACKET_ENQUEUE() */ -typedef void (*HTC_EP_SEND_PKT_COMP_MULTIPLE)(void *,HTC_PACKET_QUEUE *); +typedef void (*HTC_EP_SEND_PKT_COMP_MULTIPLE)(void *,struct htc_packet_queue *); /* per service connection pkt received */ typedef void (*HTC_EP_RECV_PKT)(void *,struct htc_packet *); /* per service connection callback when a plurality of packets are received - * The HTC_PACKET_QUEUE is a temporary queue object (e.g. freed on return from the callback) + * The struct htc_packet_queue is a temporary queue object (e.g. freed on return from the callback) * to hold a list of recv packets. * If the handler cannot fully traverse the packet queue before returning, it should * transfer the items of the queue into the caller's private queue using: * HTC_PACKET_ENQUEUE() */ -typedef void (*HTC_EP_RECV_PKT_MULTIPLE)(void *,HTC_PACKET_QUEUE *); +typedef void (*HTC_EP_RECV_PKT_MULTIPLE)(void *,struct htc_packet_queue *); /* Optional per service connection receive buffer re-fill callback, * On some OSes (like Linux) packets are allocated from a global pool and indicated up @@ -502,7 +502,7 @@ void HTCUnblockRecv(HTC_HANDLE HTCHandle); @return: 0 @notes: Caller must initialize each packet using SET_HTC_PACKET_INFO_TX() macro. The queue must only contain packets directed at the same endpoint. - Caller supplies a pointer to an HTC_PACKET_QUEUE structure holding the TX packets in FIFO order. + Caller supplies a pointer to an struct htc_packet_queue structure holding the TX packets in FIFO order. This API will remove the packets from the pkt queue and place them into the HTC Tx Queue and bundle messages where possible. The caller may allocate the pkt queue on the stack to hold the packets. @@ -511,7 +511,7 @@ void HTCUnblockRecv(HTC_HANDLE HTCHandle); @example: @see also: HTCFlushEndpoint +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue); +int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Add multiple receive packets to HTC @@ -523,14 +523,14 @@ int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue); @notes: user must supply HTC packets for capturing incomming HTC frames. The caller must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL() macro. The queue must only contain recv packets for the same endpoint. - Caller supplies a pointer to an HTC_PACKET_QUEUE structure holding the recv packet. + Caller supplies a pointer to an struct htc_packet_queue structure holding the recv packet. This API will remove the packets from the pkt queue and place them into internal recv packet list. The caller may allocate the pkt queue on the stack to hold the packets. @example: @see also: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, HTC_PACKET_QUEUE *pPktQueue); +int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Check if an endpoint is marked active diff --git a/drivers/staging/ath6kl/include/htc_packet.h b/drivers/staging/ath6kl/include/htc_packet.h index 4311c932b302..ca23efd06e65 100644 --- a/drivers/staging/ath6kl/include/htc_packet.h +++ b/drivers/staging/ath6kl/include/htc_packet.h @@ -139,10 +139,10 @@ struct htc_packet { } /* HTC Packet Queueing Macros */ -typedef struct _HTC_PACKET_QUEUE { +struct htc_packet_queue { struct dl_list QueueHead; int Depth; -} HTC_PACKET_QUEUE; +}; /* initialize queue */ #define INIT_HTC_PACKET_QUEUE(pQ) \ @@ -165,7 +165,7 @@ typedef struct _HTC_PACKET_QUEUE { /* test if a queue is empty */ #define HTC_QUEUE_EMPTY(pQ) ((pQ)->Depth == 0) /* get packet at head without removing it */ -static INLINE struct htc_packet *HTC_GET_PKT_AT_HEAD(HTC_PACKET_QUEUE *queue) { +static INLINE struct htc_packet *HTC_GET_PKT_AT_HEAD(struct htc_packet_queue *queue) { if (queue->Depth == 0) { return NULL; } @@ -179,7 +179,7 @@ static INLINE struct htc_packet *HTC_GET_PKT_AT_HEAD(HTC_PACKET_QUEUE *queue) } /* dequeue an HTC packet from the head of the queue */ -static INLINE struct htc_packet *HTC_PACKET_DEQUEUE(HTC_PACKET_QUEUE *queue) { +static INLINE struct htc_packet *HTC_PACKET_DEQUEUE(struct htc_packet_queue *queue) { struct dl_list *pItem = DL_ListRemoveItemFromHead(&queue->QueueHead); if (pItem != NULL) { queue->Depth--; @@ -189,7 +189,7 @@ static INLINE struct htc_packet *HTC_PACKET_DEQUEUE(HTC_PACKET_QUEUE *queue) { } /* dequeue an HTC packet from the tail of the queue */ -static INLINE struct htc_packet *HTC_PACKET_DEQUEUE_TAIL(HTC_PACKET_QUEUE *queue) { +static INLINE struct htc_packet *HTC_PACKET_DEQUEUE_TAIL(struct htc_packet_queue *queue) { struct dl_list *pItem = DL_ListRemoveItemFromTail(&queue->QueueHead); if (pItem != NULL) { queue->Depth--; diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index ebfc7fdb53ae..fab1e02f23f3 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -317,7 +317,7 @@ static void ar6000_rx(void *Context, struct htc_packet *pPacket); static void ar6000_rx_refill(void *Context,HTC_ENDPOINT_ID Endpoint); -static void ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPackets); +static void ar6000_tx_complete(void *Context, struct htc_packet_queue *pPackets); static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, struct htc_packet *pPacket); @@ -3461,7 +3461,7 @@ static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, struct htc_packe static void -ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPacketQueue) +ar6000_tx_complete(void *Context, struct htc_packet_queue *pPacketQueue) { AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; u32 mapNo = 0; @@ -3992,7 +3992,7 @@ ar6000_rx_refill(void *Context, HTC_ENDPOINT_ID Endpoint) int RxBuffers; int buffersToRefill; struct htc_packet *pPacket; - HTC_PACKET_QUEUE queue; + struct htc_packet_queue queue; buffersToRefill = (int)AR6000_MAX_RX_BUFFERS - HTCGetNumRecvBuffers(ar->arHtcTarget, Endpoint); @@ -6323,7 +6323,7 @@ static void DoHTCSendPktsTest(AR_SOFTC_T *ar, int MapNo, HTC_ENDPOINT_ID eid, st struct sk_buff *new_skb; int i; int pkts = 0; - HTC_PACKET_QUEUE pktQueue; + struct htc_packet_queue pktQueue; EPPING_HEADER *eppingHdr; eppingHdr = A_NETBUF_DATA(dupskb); diff --git a/drivers/staging/ath6kl/os/linux/export_hci_transport.c b/drivers/staging/ath6kl/os/linux/export_hci_transport.c index 319dc2ea731c..787a8bdb5cbd 100644 --- a/drivers/staging/ath6kl/os/linux/export_hci_transport.c +++ b/drivers/staging/ath6kl/os/linux/export_hci_transport.c @@ -38,7 +38,7 @@ HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, struct hci_transport_config_info *pInfo); void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans); -int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue); +int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue); int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous); void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans); int (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans); diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index 4324a9d1b0ef..4b7f5a81b652 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -79,7 +79,7 @@ struct ar6k_hci_bridge_info { struct hci_dev *pBtStackHCIDev; /* BT Stack HCI dev */ bool HciNormalMode; /* Actual HCI mode enabled (non-TEST)*/ bool HciRegistered; /* HCI device registered with stack */ - HTC_PACKET_QUEUE HTCPacketStructHead; + struct htc_packet_queue HTCPacketStructHead; u8 *pHTCStructAlloc; spinlock_t BridgeLock; #ifdef EXPORT_HCI_BRIDGE_INTERFACE @@ -163,7 +163,7 @@ static void RefillRecvBuffers(struct ar6k_hci_bridge_info *pHcidevInfo, { int length, i; void *osBuf = NULL; - HTC_PACKET_QUEUE queue; + struct htc_packet_queue queue; struct htc_packet *pPacket; INIT_HTC_PACKET_QUEUE(&queue); diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 29ac8300c479..8d8a964bac17 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -586,7 +586,7 @@ typedef struct ar6_softc { u16 ap_beacon_interval; u16 arRTS; u16 arACS; /* AP mode - Auto Channel Selection */ - HTC_PACKET_QUEUE amsdu_rx_buffer_queue; + struct htc_packet_queue amsdu_rx_buffer_queue; bool bIsDestroyProgress; /* flag to indicate ar6k destroy is in progress */ A_TIMER disconnect_timer; u8 rxMetaVersion; diff --git a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h index 8e52de7c2808..31f4f783dcc0 100644 --- a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h +++ b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h @@ -27,7 +27,7 @@ extern HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, struct hci_transport_config_info *pInfo); extern void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans); -extern int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET_QUEUE *pQueue); +extern int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue); extern int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous); extern void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans); extern int (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans); -- cgit v1.2.3 From cfc854728ff2a7549b7572eb11dd4665f2809461 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:58:59 -0700 Subject: ath6kl: remove-typedef HTC_RX_PACKET_INFO remove-typedef -s HTC_RX_PACKET_INFO \ "struct htc_rx_packet_info" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/include/htc_packet.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/include/htc_packet.h b/drivers/staging/ath6kl/include/htc_packet.h index ca23efd06e65..b6ecf7e4e46e 100644 --- a/drivers/staging/ath6kl/include/htc_packet.h +++ b/drivers/staging/ath6kl/include/htc_packet.h @@ -59,11 +59,11 @@ typedef struct _HTC_TX_PACKET_INFO { #define HTC_TX_PACKET_TAG_INTERNAL 1 /* internal tags start here */ #define HTC_TX_PACKET_TAG_USER_DEFINED (HTC_TX_PACKET_TAG_INTERNAL + 9) /* user-defined tags start here */ -typedef struct _HTC_RX_PACKET_INFO { +struct htc_rx_packet_info { u32 ExpectedHdr; /* HTC internal use */ u32 HTCRxFlags; /* HTC internal use */ u32 IndicationFlags; /* indication flags set on each RX packet indication */ -} HTC_RX_PACKET_INFO; +}; #define HTC_RX_FLAGS_INDICATE_MORE_PKTS (1 << 0) /* more packets on this endpoint are being fetched */ @@ -92,7 +92,7 @@ struct htc_packet { int Status; /* completion status */ union { HTC_TX_PACKET_INFO AsTx; /* Tx Packet specific info */ - HTC_RX_PACKET_INFO AsRx; /* Rx Packet specific info */ + struct htc_rx_packet_info AsRx; /* Rx Packet specific info */ } PktInfo; /* the following fields are for internal HTC use */ -- cgit v1.2.3 From 3d82b15e9f42ac6d9b350ebfb04c56ae8cc06966 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:59:00 -0700 Subject: ath6kl: remove-typedef HTC_SERVICE_CONNECT_REQ remove-typedef -s HTC_SERVICE_CONNECT_REQ \ "struct htc_service_connect_req" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/htc.c | 2 +- drivers/staging/ath6kl/htc2/htc_services.c | 2 +- drivers/staging/ath6kl/include/htc_api.h | 6 +++--- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 4 ++-- drivers/staging/ath6kl/os/linux/ar6000_raw_if.c | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index bf4fdb34e9e9..887a687b1392 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -229,7 +229,7 @@ int HTCWaitTarget(HTC_HANDLE HTCHandle) struct htc_packet *pPacket = NULL; HTC_READY_EX_MSG *pRdyMsg; - HTC_SERVICE_CONNECT_REQ connect; + struct htc_service_connect_req connect; HTC_SERVICE_CONNECT_RESP resp; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Enter (target:0x%lX) \n", (unsigned long)target)); diff --git a/drivers/staging/ath6kl/htc2/htc_services.c b/drivers/staging/ath6kl/htc2/htc_services.c index cb0731f45864..5c092fd3f61a 100644 --- a/drivers/staging/ath6kl/htc2/htc_services.c +++ b/drivers/staging/ath6kl/htc2/htc_services.c @@ -122,7 +122,7 @@ int HTCSendSetupComplete(HTC_TARGET *target) int HTCConnectService(HTC_HANDLE HTCHandle, - HTC_SERVICE_CONNECT_REQ *pConnectReq, + struct htc_service_connect_req *pConnectReq, HTC_SERVICE_CONNECT_RESP *pConnectResp) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h index ae41f985c9f3..f8f00a0600a0 100644 --- a/drivers/staging/ath6kl/include/htc_api.h +++ b/drivers/staging/ath6kl/include/htc_api.h @@ -139,7 +139,7 @@ struct htc_ep_callbacks { }; /* service connection information */ -typedef struct _HTC_SERVICE_CONNECT_REQ { +struct htc_service_connect_req { HTC_SERVICE_ID ServiceID; /* service ID to connect to */ u16 ConnectionFlags; /* connection flags, see htc protocol definition */ u8 *pMetaData; /* ptr to optional service-specific meta-data */ @@ -148,7 +148,7 @@ typedef struct _HTC_SERVICE_CONNECT_REQ { int MaxSendQueueDepth; /* maximum depth of any send queue */ u32 LocalConnectionFlags; /* HTC flags for the host-side (local) connection */ unsigned int MaxSendMsgSize; /* override max message size in send direction */ -} HTC_SERVICE_CONNECT_REQ; +}; #define HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING (1 << 0) /* enable send bundle padding for this endpoint */ @@ -362,7 +362,7 @@ int HTCAddReceivePkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket); @see also: HTCStart +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int HTCConnectService(HTC_HANDLE HTCHandle, - HTC_SERVICE_CONNECT_REQ *pReq, + struct htc_service_connect_req *pReq, HTC_SERVICE_CONNECT_RESP *pResp); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Send an HTC packet diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index fab1e02f23f3..a7c57e3f3b67 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -2339,7 +2339,7 @@ ar6000_close(struct net_device *dev) /* connect to a service */ static int ar6000_connectservice(AR_SOFTC_T *ar, - HTC_SERVICE_CONNECT_REQ *pConnect, + struct htc_service_connect_req *pConnect, char *pDesc) { int status; @@ -2605,7 +2605,7 @@ int ar6000_init(struct net_device *dev) } do { - HTC_SERVICE_CONNECT_REQ connect; + struct htc_service_connect_req connect; /* the reason we have to wait for the target here is that the driver layer * has to init BMI in order to set the host block size, diff --git a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c index f8637f6b4477..35de2fb9f455 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c @@ -117,7 +117,7 @@ static int ar6000_connect_raw_service(AR_SOFTC_T *ar, int status; HTC_SERVICE_CONNECT_RESP response; u8 streamNo; - HTC_SERVICE_CONNECT_REQ connect; + struct htc_service_connect_req connect; do { -- cgit v1.2.3 From cb3ea094c9cb3b1a904ccc025fe19150d5a34d6b Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:59:01 -0700 Subject: ath6kl: remove-typedef HTC_SERVICE_CONNECT_RESP remove-typedef -s HTC_SERVICE_CONNECT_RESP \ "struct htc_service_connect_resp" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/htc.c | 2 +- drivers/staging/ath6kl/htc2/htc_services.c | 2 +- drivers/staging/ath6kl/include/htc_api.h | 6 +++--- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 2 +- drivers/staging/ath6kl/os/linux/ar6000_raw_if.c | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index 887a687b1392..b08fd828fc6a 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -230,7 +230,7 @@ int HTCWaitTarget(HTC_HANDLE HTCHandle) HTC_READY_EX_MSG *pRdyMsg; struct htc_service_connect_req connect; - HTC_SERVICE_CONNECT_RESP resp; + struct htc_service_connect_resp resp; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Enter (target:0x%lX) \n", (unsigned long)target)); diff --git a/drivers/staging/ath6kl/htc2/htc_services.c b/drivers/staging/ath6kl/htc2/htc_services.c index 5c092fd3f61a..d1f1c54e5b89 100644 --- a/drivers/staging/ath6kl/htc2/htc_services.c +++ b/drivers/staging/ath6kl/htc2/htc_services.c @@ -123,7 +123,7 @@ int HTCSendSetupComplete(HTC_TARGET *target) int HTCConnectService(HTC_HANDLE HTCHandle, struct htc_service_connect_req *pConnectReq, - HTC_SERVICE_CONNECT_RESP *pConnectResp) + struct htc_service_connect_resp *pConnectResp) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); int status = 0; diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h index f8f00a0600a0..1bc2488788ab 100644 --- a/drivers/staging/ath6kl/include/htc_api.h +++ b/drivers/staging/ath6kl/include/htc_api.h @@ -153,14 +153,14 @@ struct htc_service_connect_req { #define HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING (1 << 0) /* enable send bundle padding for this endpoint */ /* service connection response information */ -typedef struct _HTC_SERVICE_CONNECT_RESP { +struct htc_service_connect_resp { u8 *pMetaData; /* caller supplied buffer to optional meta-data */ u8 BufferLength; /* length of caller supplied buffer */ u8 ActualLength; /* actual length of meta data */ HTC_ENDPOINT_ID Endpoint; /* endpoint to communicate over */ unsigned int MaxMsgLength; /* max length of all messages over this endpoint */ u8 ConnectRespCode; /* connect response code from target */ -} HTC_SERVICE_CONNECT_RESP; +}; /* endpoint distribution structure */ struct htc_endpoint_credit_dist { @@ -363,7 +363,7 @@ int HTCAddReceivePkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket); +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int HTCConnectService(HTC_HANDLE HTCHandle, struct htc_service_connect_req *pReq, - HTC_SERVICE_CONNECT_RESP *pResp); + struct htc_service_connect_resp *pResp); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @desc: Send an HTC packet @function name: HTCSendPkt diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index a7c57e3f3b67..41c66b77e5f6 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -2343,7 +2343,7 @@ static int ar6000_connectservice(AR_SOFTC_T *ar, char *pDesc) { int status; - HTC_SERVICE_CONNECT_RESP response; + struct htc_service_connect_resp response; do { diff --git a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c index 35de2fb9f455..7b6339c41e95 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c @@ -115,7 +115,7 @@ static int ar6000_connect_raw_service(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID) { int status; - HTC_SERVICE_CONNECT_RESP response; + struct htc_service_connect_resp response; u8 streamNo; struct htc_service_connect_req connect; -- cgit v1.2.3 From c1ebe36136bc06117b74d2a3be76e234f4e4b6c8 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:59:02 -0700 Subject: ath6kl: remove-typedef HTC_TARGET This required two passes: remove-typedef -s _HTC_TARGET \ "struct htc_target" drivers/staging/ath6kl/ remove-typedef -s HTC_TARGET \ "struct htc_target" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/htc2/htc.c | 34 +++++++++++++------------- drivers/staging/ath6kl/htc2/htc_internal.h | 28 +++++++++++----------- drivers/staging/ath6kl/htc2/htc_recv.c | 38 +++++++++++++++--------------- drivers/staging/ath6kl/htc2/htc_send.c | 32 ++++++++++++------------- drivers/staging/ath6kl/htc2/htc_services.c | 12 +++++----- 5 files changed, 72 insertions(+), 72 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c index b08fd828fc6a..d40bb14a2dac 100644 --- a/drivers/staging/ath6kl/htc2/htc.c +++ b/drivers/staging/ath6kl/htc2/htc.c @@ -41,16 +41,16 @@ ATH_DEBUG_INSTANTIATE_MODULE_VAR(htc, #endif static void HTCReportFailure(void *Context); -static void ResetEndpointStates(HTC_TARGET *target); +static void ResetEndpointStates(struct htc_target *target); -void HTCFreeControlBuffer(HTC_TARGET *target, struct htc_packet *pPacket, struct htc_packet_queue *pList) +void HTCFreeControlBuffer(struct htc_target *target, struct htc_packet *pPacket, struct htc_packet_queue *pList) { LOCK_HTC(target); HTC_PACKET_ENQUEUE(pList,pPacket); UNLOCK_HTC(target); } -struct htc_packet *HTCAllocControlBuffer(HTC_TARGET *target, struct htc_packet_queue *pList) +struct htc_packet *HTCAllocControlBuffer(struct htc_target *target, struct htc_packet_queue *pList) { struct htc_packet *pPacket; @@ -62,7 +62,7 @@ struct htc_packet *HTCAllocControlBuffer(HTC_TARGET *target, struct htc_packet_ } /* cleanup the HTC instance */ -static void HTCCleanup(HTC_TARGET *target) +static void HTCCleanup(struct htc_target *target) { s32 i; @@ -92,7 +92,7 @@ static void HTCCleanup(HTC_TARGET *target) /* registered target arrival callback from the HIF layer */ HTC_HANDLE HTCCreate(void *hif_handle, struct htc_init_info *pInfo) { - HTC_TARGET *target = NULL; + struct htc_target *target = NULL; int status = 0; int i; u32 ctrl_bufsz; @@ -105,13 +105,13 @@ HTC_HANDLE HTCCreate(void *hif_handle, struct htc_init_info *pInfo) do { /* allocate target memory */ - if ((target = (HTC_TARGET *)A_MALLOC(sizeof(HTC_TARGET))) == NULL) { + if ((target = (struct htc_target *)A_MALLOC(sizeof(struct htc_target))) == NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n")); status = A_ERROR; break; } - A_MEMZERO(target, sizeof(HTC_TARGET)); + A_MEMZERO(target, sizeof(struct htc_target)); A_MUTEX_INIT(&target->HTCLock); A_MUTEX_INIT(&target->HTCRxLock); A_MUTEX_INIT(&target->HTCTxLock); @@ -206,7 +206,7 @@ HTC_HANDLE HTCCreate(void *hif_handle, struct htc_init_info *pInfo) void HTCDestroy(HTC_HANDLE HTCHandle) { - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCDestroy .. Destroying :0x%lX \n",(unsigned long)target)); HTCCleanup(target); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCDestroy \n")); @@ -216,7 +216,7 @@ void HTCDestroy(HTC_HANDLE HTCHandle) * HIF requests */ void *HTCGetHifDevice(HTC_HANDLE HTCHandle) { - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); return target->Device.HIFDevice; } @@ -224,7 +224,7 @@ void *HTCGetHifDevice(HTC_HANDLE HTCHandle) * this operation is fully synchronous and the message is polled for */ int HTCWaitTarget(HTC_HANDLE HTCHandle) { - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); int status; struct htc_packet *pPacket = NULL; HTC_READY_EX_MSG *pRdyMsg; @@ -371,7 +371,7 @@ int HTCWaitTarget(HTC_HANDLE HTCHandle) /* Start HTC, enable interrupts and let the target know host has finished setup */ int HTCStart(HTC_HANDLE HTCHandle) { - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); struct htc_packet *pPacket; int status; @@ -436,7 +436,7 @@ int HTCStart(HTC_HANDLE HTCHandle) return status; } -static void ResetEndpointStates(HTC_TARGET *target) +static void ResetEndpointStates(struct htc_target *target) { struct htc_endpoint *pEndpoint; int i; @@ -463,7 +463,7 @@ static void ResetEndpointStates(HTC_TARGET *target) /* stop HTC communications, i.e. stop interrupt reception, and flush all queued buffers */ void HTCStop(HTC_HANDLE HTCHandle) { - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCStop \n")); LOCK_HTC(target); @@ -496,7 +496,7 @@ void HTCStop(HTC_HANDLE HTCHandle) #ifdef ATH_DEBUG_MODULE void HTCDumpCreditStates(HTC_HANDLE HTCHandle) { - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); LOCK_HTC_TX(target); @@ -511,7 +511,7 @@ void HTCDumpCreditStates(HTC_HANDLE HTCHandle) * which uses a mechanism to report errors from the target (i.e. special interrupts) */ static void HTCReportFailure(void *Context) { - HTC_TARGET *target = (HTC_TARGET *)Context; + struct htc_target *target = (struct htc_target *)Context; target->TargetFailure = true; @@ -528,7 +528,7 @@ bool HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, { #ifdef HTC_EP_STAT_PROFILING - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); bool clearStats = false; bool sample = false; @@ -575,7 +575,7 @@ bool HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, struct ar6k_device *HTCGetAR6KDevice(void *HTCHandle) { - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); return &target->Device; } diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h index 67de917dc6f5..9425ed983671 100644 --- a/drivers/staging/ath6kl/htc2/htc_internal.h +++ b/drivers/staging/ath6kl/htc2/htc_internal.h @@ -79,7 +79,7 @@ struct htc_endpoint { int TxProcessCount; /* reference count to continue tx processing */ struct htc_packet_queue RecvIndicationQueue; /* recv packets ready to be indicated */ int RxProcessCount; /* reference count to allow single processing context */ - struct _HTC_TARGET *target; /* back pointer to target */ + struct htc_target *target; /* back pointer to target */ u8 SeqNo; /* TX seq no (helpful) for debugging */ u32 LocalConnectionFlags; /* local connection flags */ #ifdef HTC_EP_STAT_PROFILING @@ -108,7 +108,7 @@ struct htc_control_buffer { #define HTC_OP_STATE_STOPPING (1 << 0) /* our HTC target state */ -typedef struct _HTC_TARGET { +struct htc_target { struct htc_endpoint EndPoint[ENDPOINT_MAX]; struct htc_control_buffer HTCControlBuffers[NUM_CONTROL_BUFFERS]; struct htc_endpoint_credit_dist *EpCreditDistributionListHead; @@ -137,7 +137,7 @@ typedef struct _HTC_TARGET { int MaxMsgPerBundle; /* max messages per bundle for HTC */ bool SendBundlingEnabled; /* run time enable for send bundling (dynamic) */ int RecvBundlingEnabled; /* run time enable for recv bundling (dynamic) */ -} HTC_TARGET; +}; #define HTC_STOPPING(t) ((t)->OpStateFlags & HTC_OP_STATE_STOPPING) #define LOCK_HTC(t) A_MUTEX_LOCK(&(t)->HTCLock); @@ -147,7 +147,7 @@ typedef struct _HTC_TARGET { #define LOCK_HTC_TX(t) A_MUTEX_LOCK(&(t)->HTCTxLock); #define UNLOCK_HTC_TX(t) A_MUTEX_UNLOCK(&(t)->HTCTxLock); -#define GET_HTC_TARGET_FROM_HANDLE(hnd) ((HTC_TARGET *)(hnd)) +#define GET_HTC_TARGET_FROM_HANDLE(hnd) ((struct htc_target *)(hnd)) #define HTC_RECYCLE_RX_PKT(target,p,e) \ { \ if ((p)->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_NO_RECYCLE) { \ @@ -164,24 +164,24 @@ typedef struct _HTC_TARGET { /* internal HTC functions */ void HTCControlTxComplete(void *Context, struct htc_packet *pPacket); void HTCControlRecv(void *Context, struct htc_packet *pPacket); -int HTCWaitforControlMessage(HTC_TARGET *target, struct htc_packet **ppControlPacket); -struct htc_packet *HTCAllocControlBuffer(HTC_TARGET *target, struct htc_packet_queue *pList); -void HTCFreeControlBuffer(HTC_TARGET *target, struct htc_packet *pPacket, struct htc_packet_queue *pList); -int HTCIssueSend(HTC_TARGET *target, struct htc_packet *pPacket); +int HTCWaitforControlMessage(struct htc_target *target, struct htc_packet **ppControlPacket); +struct htc_packet *HTCAllocControlBuffer(struct htc_target *target, struct htc_packet_queue *pList); +void HTCFreeControlBuffer(struct htc_target *target, struct htc_packet *pPacket, struct htc_packet_queue *pList); +int HTCIssueSend(struct htc_target *target, struct htc_packet *pPacket); void HTCRecvCompleteHandler(void *Context, struct htc_packet *pPacket); int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched); -void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint); -int HTCSendSetupComplete(HTC_TARGET *target); -void HTCFlushRecvBuffers(HTC_TARGET *target); -void HTCFlushSendPkts(HTC_TARGET *target); +void HTCProcessCreditRpt(struct htc_target *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint); +int HTCSendSetupComplete(struct htc_target *target); +void HTCFlushRecvBuffers(struct htc_target *target); +void HTCFlushSendPkts(struct htc_target *target); #ifdef ATH_DEBUG_MODULE void DumpCreditDist(struct htc_endpoint_credit_dist *pEPDist); -void DumpCreditDistStates(HTC_TARGET *target); +void DumpCreditDistStates(struct htc_target *target); void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription); #endif -static INLINE struct htc_packet *HTC_ALLOC_CONTROL_TX(HTC_TARGET *target) { +static INLINE struct htc_packet *HTC_ALLOC_CONTROL_TX(struct htc_target *target) { struct htc_packet *pPacket = HTCAllocControlBuffer(target,&target->ControlBufferTXFreeList); if (pPacket != NULL) { /* set payload pointer area with some headroom */ diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c index 8ad1d03fceb3..c2088018c51d 100644 --- a/drivers/staging/ath6kl/htc2/htc_recv.c +++ b/drivers/staging/ath6kl/htc2/htc_recv.c @@ -83,7 +83,7 @@ static void DoRecvCompletion(struct htc_endpoint *pEndpoint, } -static INLINE int HTCProcessTrailer(HTC_TARGET *target, +static INLINE int HTCProcessTrailer(struct htc_target *target, u8 *pBuffer, int Length, u32 *pNextLookAheads, @@ -226,7 +226,7 @@ static INLINE int HTCProcessTrailer(HTC_TARGET *target, /* process a received message (i.e. strip off header, process any trailer data) * note : locks must be released when this function is called */ -static int HTCProcessRecvHeader(HTC_TARGET *target, +static int HTCProcessRecvHeader(struct htc_target *target, struct htc_packet *pPacket, u32 *pNextLookAheads, int *pNumLookAheads) @@ -385,7 +385,7 @@ static int HTCProcessRecvHeader(HTC_TARGET *target, return status; } -static INLINE void HTCAsyncRecvCheckMorePackets(HTC_TARGET *target, +static INLINE void HTCAsyncRecvCheckMorePackets(struct htc_target *target, u32 NextLookAheads[], int NumLookAheads, bool CheckMoreMsgs) @@ -432,7 +432,7 @@ static INLINE void HTCAsyncRecvCheckMorePackets(HTC_TARGET *target, } /* unload the recv completion queue */ -static INLINE void DrainRecvIndicationQueue(HTC_TARGET *target, struct htc_endpoint *pEndpoint) +static INLINE void DrainRecvIndicationQueue(struct htc_target *target, struct htc_endpoint *pEndpoint) { struct htc_packet_queue recvCompletions; @@ -517,7 +517,7 @@ static INLINE void SetRxPacketIndicationFlags(u32 LookAhead, * completes a read request, it will call this completion handler */ void HTCRecvCompleteHandler(void *Context, struct htc_packet *pPacket) { - HTC_TARGET *target = (HTC_TARGET *)Context; + struct htc_target *target = (struct htc_target *)Context; struct htc_endpoint *pEndpoint; u32 nextLookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; int numLookAheads = 0; @@ -587,7 +587,7 @@ void HTCRecvCompleteHandler(void *Context, struct htc_packet *pPacket) /* synchronously wait for a control message from the target, * This function is used at initialization time ONLY. At init messages * on ENDPOINT 0 are expected. */ -int HTCWaitforControlMessage(HTC_TARGET *target, struct htc_packet **ppControlPacket) +int HTCWaitforControlMessage(struct htc_target *target, struct htc_packet **ppControlPacket) { int status; u32 lookAhead; @@ -686,7 +686,7 @@ int HTCWaitforControlMessage(HTC_TARGET *target, struct htc_packet **ppControlPa return status; } -static int AllocAndPrepareRxPackets(HTC_TARGET *target, +static int AllocAndPrepareRxPackets(struct htc_target *target, u32 LookAheads[], int Messages, struct htc_endpoint *pEndpoint, @@ -886,7 +886,7 @@ static void HTCAsyncRecvScatterCompletion(struct hif_scatter_req *pScatterReq) struct htc_endpoint *pEndpoint; u32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; int numLookAheads = 0; - HTC_TARGET *target = (HTC_TARGET *)pScatterReq->Context; + struct htc_target *target = (struct htc_target *)pScatterReq->Context; int status; bool partialBundle = false; struct htc_packet_queue localRecvQueue; @@ -984,7 +984,7 @@ static void HTCAsyncRecvScatterCompletion(struct hif_scatter_req *pScatterReq) AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCAsyncRecvScatterCompletion \n")); } -static int HTCIssueRecvPacketBundle(HTC_TARGET *target, +static int HTCIssueRecvPacketBundle(struct htc_target *target, struct htc_packet_queue *pRecvPktQueue, struct htc_packet_queue *pSyncCompletionQueue, int *pNumPacketsFetched, @@ -1119,7 +1119,7 @@ static INLINE void CheckRecvWaterMark(struct htc_endpoint *pEndpoint) /* callback when device layer or lookahead report parsing detects a pending message */ int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched) { - HTC_TARGET *target = (HTC_TARGET *)Context; + struct htc_target *target = (struct htc_target *)Context; int status = 0; struct htc_packet *pPacket; struct htc_endpoint *pEndpoint; @@ -1387,7 +1387,7 @@ int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLook int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue) { - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); struct htc_endpoint *pEndpoint; bool unblockRecv = false; int status = 0; @@ -1464,7 +1464,7 @@ int HTCAddReceivePkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket) void HTCUnblockRecv(HTC_HANDLE HTCHandle) { - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); bool unblockRecv = false; LOCK_HTC_RX(target); @@ -1486,7 +1486,7 @@ void HTCUnblockRecv(HTC_HANDLE HTCHandle) } } -static void HTCFlushRxQueue(HTC_TARGET *target, struct htc_endpoint *pEndpoint, struct htc_packet_queue *pQueue) +static void HTCFlushRxQueue(struct htc_target *target, struct htc_endpoint *pEndpoint, struct htc_packet_queue *pQueue) { struct htc_packet *pPacket; struct htc_packet_queue container; @@ -1512,7 +1512,7 @@ static void HTCFlushRxQueue(HTC_TARGET *target, struct htc_endpoint *pEndpoint, UNLOCK_HTC_RX(target); } -static void HTCFlushEndpointRX(HTC_TARGET *target, struct htc_endpoint *pEndpoint) +static void HTCFlushEndpointRX(struct htc_target *target, struct htc_endpoint *pEndpoint) { /* flush any recv indications not already made */ HTCFlushRxQueue(target,pEndpoint,&pEndpoint->RecvIndicationQueue); @@ -1520,7 +1520,7 @@ static void HTCFlushEndpointRX(HTC_TARGET *target, struct htc_endpoint *pEndpoin HTCFlushRxQueue(target,pEndpoint,&pEndpoint->RxBuffers); } -void HTCFlushRecvBuffers(HTC_TARGET *target) +void HTCFlushRecvBuffers(struct htc_target *target) { struct htc_endpoint *pEndpoint; int i; @@ -1538,7 +1538,7 @@ void HTCFlushRecvBuffers(HTC_TARGET *target) void HTCEnableRecv(HTC_HANDLE HTCHandle) { - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); if (!HTC_STOPPING(target)) { /* re-enable */ @@ -1548,7 +1548,7 @@ void HTCEnableRecv(HTC_HANDLE HTCHandle) void HTCDisableRecv(HTC_HANDLE HTCHandle) { - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); if (!HTC_STOPPING(target)) { /* disable */ @@ -1559,7 +1559,7 @@ void HTCDisableRecv(HTC_HANDLE HTCHandle) int HTCGetNumRecvBuffers(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint) { - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); return HTC_PACKET_QUEUE_DEPTH(&(target->EndPoint[Endpoint].RxBuffers)); } @@ -1568,7 +1568,7 @@ int HTCWaitForPendingRecv(HTC_HANDLE HTCHandle, bool *pbIsRecvPending) { int status = 0; - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); status = DevWaitForPendingRecv(&target->Device, TimeoutInMs, diff --git a/drivers/staging/ath6kl/htc2/htc_send.c b/drivers/staging/ath6kl/htc2/htc_send.c index 805265880820..6f4050a98c85 100644 --- a/drivers/staging/ath6kl/htc2/htc_send.c +++ b/drivers/staging/ath6kl/htc2/htc_send.c @@ -77,7 +77,7 @@ static void DoSendCompletion(struct htc_endpoint *pEndpoint, } /* do final completion on sent packet */ -static INLINE void CompleteSentPacket(HTC_TARGET *target, struct htc_endpoint *pEndpoint, struct htc_packet *pPacket) +static INLINE void CompleteSentPacket(struct htc_target *target, struct htc_endpoint *pEndpoint, struct htc_packet *pPacket) { pPacket->Completion = NULL; @@ -103,7 +103,7 @@ static INLINE void CompleteSentPacket(HTC_TARGET *target, struct htc_endpoint *p * layer */ static void HTCSendPktCompletionHandler(void *Context, struct htc_packet *pPacket) { - HTC_TARGET *target = (HTC_TARGET *)Context; + struct htc_target *target = (struct htc_target *)Context; struct htc_endpoint *pEndpoint = &target->EndPoint[pPacket->Endpoint]; struct htc_packet_queue container; @@ -113,7 +113,7 @@ static void HTCSendPktCompletionHandler(void *Context, struct htc_packet *pPacke DO_EP_TX_COMPLETION(pEndpoint,&container); } -int HTCIssueSend(HTC_TARGET *target, struct htc_packet *pPacket) +int HTCIssueSend(struct htc_target *target, struct htc_packet *pPacket) { int status; bool sync = false; @@ -146,7 +146,7 @@ int HTCIssueSend(HTC_TARGET *target, struct htc_packet *pPacket) } /* get HTC send packets from the TX queue on an endpoint */ -static INLINE void GetHTCSendPackets(HTC_TARGET *target, +static INLINE void GetHTCSendPackets(struct htc_target *target, struct htc_endpoint *pEndpoint, struct htc_packet_queue *pQueue) { @@ -269,7 +269,7 @@ static void HTCAsyncSendScatterCompletion(struct hif_scatter_req *pScatterReq) int i; struct htc_packet *pPacket; struct htc_endpoint *pEndpoint = (struct htc_endpoint *)pScatterReq->Context; - HTC_TARGET *target = (HTC_TARGET *)pEndpoint->target; + struct htc_target *target = (struct htc_target *)pEndpoint->target; int status = 0; struct htc_packet_queue sendCompletes; @@ -323,7 +323,7 @@ static void HTCIssueSendBundle(struct htc_endpoint *pEndpoint, bool done = false; int bundlesSent = 0; int totalPktsInBundle = 0; - HTC_TARGET *target = pEndpoint->target; + struct htc_target *target = pEndpoint->target; int creditRemainder = 0; int creditPad; @@ -477,7 +477,7 @@ static void HTCIssueSendBundle(struct htc_endpoint *pEndpoint, /* * if there are no credits, the packet(s) remains in the queue. * this function returns the result of the attempt to send a queue of HTC packets */ -static HTC_SEND_QUEUE_RESULT HTCTrySend(HTC_TARGET *target, +static HTC_SEND_QUEUE_RESULT HTCTrySend(struct htc_target *target, struct htc_endpoint *pEndpoint, struct htc_packet_queue *pCallersSendQueue) { @@ -670,7 +670,7 @@ static HTC_SEND_QUEUE_RESULT HTCTrySend(HTC_TARGET *target, int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue) { - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); struct htc_endpoint *pEndpoint; struct htc_packet *pPacket; @@ -721,7 +721,7 @@ int HTCSendPkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket) } /* check TX queues to drain because of credit distribution update */ -static INLINE void HTCCheckEndpointTxQueues(HTC_TARGET *target) +static INLINE void HTCCheckEndpointTxQueues(struct htc_target *target) { struct htc_endpoint *pEndpoint; struct htc_endpoint_credit_dist *pDistItem; @@ -753,7 +753,7 @@ static INLINE void HTCCheckEndpointTxQueues(HTC_TARGET *target) } /* process credit reports and call distribution function */ -void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint) +void HTCProcessCreditRpt(struct htc_target *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint) { int i; struct htc_endpoint *pEndpoint; @@ -838,7 +838,7 @@ void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEnt } /* flush endpoint TX queue */ -static void HTCFlushEndpointTX(HTC_TARGET *target, struct htc_endpoint *pEndpoint, HTC_TX_TAG Tag) +static void HTCFlushEndpointTX(struct htc_target *target, struct htc_endpoint *pEndpoint, HTC_TX_TAG Tag) { struct htc_packet *pPacket; struct htc_packet_queue discardQueue; @@ -899,7 +899,7 @@ void DumpCreditDist(struct htc_endpoint_credit_dist *pEPDist) AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("----------------------------------------------------\n")); } -void DumpCreditDistStates(HTC_TARGET *target) +void DumpCreditDistStates(struct htc_target *target) { struct htc_endpoint_credit_dist *pEPList = target->EpCreditDistributionListHead; @@ -917,7 +917,7 @@ void DumpCreditDistStates(HTC_TARGET *target) } /* flush all send packets from all endpoint queues */ -void HTCFlushSendPkts(HTC_TARGET *target) +void HTCFlushSendPkts(struct htc_target *target) { struct htc_endpoint *pEndpoint; int i; @@ -941,7 +941,7 @@ void HTCFlushSendPkts(HTC_TARGET *target) /* HTC API to flush an endpoint's TX queue*/ void HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG Tag) { - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); struct htc_endpoint *pEndpoint = &target->EndPoint[Endpoint]; if (pEndpoint->ServiceID == 0) { @@ -958,7 +958,7 @@ void HTCIndicateActivityChange(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, bool Active) { - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); struct htc_endpoint *pEndpoint = &target->EndPoint[Endpoint]; bool doDist = false; @@ -1008,7 +1008,7 @@ void HTCIndicateActivityChange(HTC_HANDLE HTCHandle, bool HTCIsEndpointActive(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint) { - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); struct htc_endpoint *pEndpoint = &target->EndPoint[Endpoint]; if (pEndpoint->ServiceID == 0) { diff --git a/drivers/staging/ath6kl/htc2/htc_services.c b/drivers/staging/ath6kl/htc2/htc_services.c index d1f1c54e5b89..c48070cbd54f 100644 --- a/drivers/staging/ath6kl/htc2/htc_services.c +++ b/drivers/staging/ath6kl/htc2/htc_services.c @@ -36,7 +36,7 @@ void HTCControlRecv(void *Context, struct htc_packet *pPacket) if (pPacket->Status == A_ECANCELED) { /* this is a flush operation, return the control packet back to the pool */ - HTC_FREE_CONTROL_RX((HTC_TARGET*)Context,pPacket); + HTC_FREE_CONTROL_RX((struct htc_target*)Context,pPacket); return; } @@ -54,10 +54,10 @@ void HTCControlRecv(void *Context, struct htc_packet *pPacket) #endif } - HTC_RECYCLE_RX_PKT((HTC_TARGET*)Context,pPacket,&((HTC_TARGET*)Context)->EndPoint[0]); + HTC_RECYCLE_RX_PKT((struct htc_target*)Context,pPacket,&((struct htc_target*)Context)->EndPoint[0]); } -int HTCSendSetupComplete(HTC_TARGET *target) +int HTCSendSetupComplete(struct htc_target *target) { struct htc_packet *pSendPacket = NULL; int status; @@ -125,7 +125,7 @@ int HTCConnectService(HTC_HANDLE HTCHandle, struct htc_service_connect_req *pConnectReq, struct htc_service_connect_resp *pConnectResp) { - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); int status = 0; struct htc_packet *pRecvPacket = NULL; struct htc_packet *pSendPacket = NULL; @@ -307,7 +307,7 @@ int HTCConnectService(HTC_HANDLE HTCHandle, return status; } -static void AddToEndpointDistList(HTC_TARGET *target, struct htc_endpoint_credit_dist *pEpDist) +static void AddToEndpointDistList(struct htc_target *target, struct htc_endpoint_credit_dist *pEpDist) { struct htc_endpoint_credit_dist *pCurEntry,*pLastEntry; @@ -408,7 +408,7 @@ void HTCSetCreditDistribution(HTC_HANDLE HTCHandle, HTC_SERVICE_ID ServicePriorityOrder[], int ListLength) { - HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); int i; int ep; -- cgit v1.2.3 From fc5f36239385784ecd122392ac15f8a59df3bb82 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:59:03 -0700 Subject: ath6kl: remove-typedef HTC_TX_PACKET_INFO remove-typedef -s HTC_TX_PACKET_INFO \ "struct htc_tx_packet_info" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/include/htc_packet.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/include/htc_packet.h b/drivers/staging/ath6kl/include/htc_packet.h index b6ecf7e4e46e..ba65c34ebc9c 100644 --- a/drivers/staging/ath6kl/include/htc_packet.h +++ b/drivers/staging/ath6kl/include/htc_packet.h @@ -48,12 +48,12 @@ typedef void (* HTC_PACKET_COMPLETION)(void *,struct htc_packet *); typedef u16 HTC_TX_TAG; -typedef struct _HTC_TX_PACKET_INFO { +struct htc_tx_packet_info { HTC_TX_TAG Tag; /* tag used to selective flush packets */ int CreditsUsed; /* number of credits used for this TX packet (HTC internal) */ u8 SendFlags; /* send flags (HTC internal) */ int SeqNo; /* internal seq no for debugging (HTC internal) */ -} HTC_TX_PACKET_INFO; +}; #define HTC_TX_PACKET_TAG_ALL 0 /* a tag of zero is reserved and used to flush ALL packets */ #define HTC_TX_PACKET_TAG_INTERNAL 1 /* internal tags start here */ @@ -91,7 +91,7 @@ struct htc_packet { HTC_ENDPOINT_ID Endpoint; /* endpoint that this packet was sent/recv'd from */ int Status; /* completion status */ union { - HTC_TX_PACKET_INFO AsTx; /* Tx Packet specific info */ + struct htc_tx_packet_info AsTx; /* Tx Packet specific info */ struct htc_rx_packet_info AsRx; /* Rx Packet specific info */ } PktInfo; -- cgit v1.2.3 From 628608591f4d3dfb4ce14793c23e188cc708cb3f Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:59:04 -0700 Subject: ath6kl: remove-typedef OSBUF_HOLD_Q remove-typedef -s OSBUF_HOLD_Q \ "struct osbuf_hold_q" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/reorder/aggr_rx_internal.h | 8 ++++---- drivers/staging/ath6kl/reorder/rcv_aggr.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h index 20c894dcc717..082a8da02028 100644 --- a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h +++ b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h @@ -48,7 +48,7 @@ #define AGGR_GET_RXTID(_p, _x) (&(_p->RxTid[(_x)])) /* Hold q is a function of win_sz, which is negotiated per tid */ -#define HOLD_Q_SZ(_x) (TID_WINDOW_SZ((_x))*sizeof(OSBUF_HOLD_Q)) +#define HOLD_Q_SZ(_x) (TID_WINDOW_SZ((_x))*sizeof(struct osbuf_hold_q)) /* AGGR_RX_TIMEOUT value is important as a (too) small value can cause frames to be * delivered out of order and a (too) large value can cause undesirable latency in * certain situations. */ @@ -59,11 +59,11 @@ typedef enum { CONTIGUOUS_SEQNO = 1, }DELIVERY_ORDER; -typedef struct { +struct osbuf_hold_q { void *osbuf; bool is_amsdu; u16 seq_no; -}OSBUF_HOLD_Q; +}; #if 0 @@ -80,7 +80,7 @@ typedef struct { u16 win_sz; /* negotiated window size */ u16 seq_next; /* Next seq no, in current window */ u32 hold_q_sz; /* Num of frames that can be held in hold q */ - OSBUF_HOLD_Q *hold_q; /* Hold q for re-order */ + struct osbuf_hold_q *hold_q; /* Hold q for re-order */ #if 0 WINDOW_SNAPSHOT old_win; /* Sliding window snapshot - for timeout */ #endif diff --git a/drivers/staging/ath6kl/reorder/rcv_aggr.c b/drivers/staging/ath6kl/reorder/rcv_aggr.c index 8beb00dae5f0..c54d492e444b 100644 --- a/drivers/staging/ath6kl/reorder/rcv_aggr.c +++ b/drivers/staging/ath6kl/reorder/rcv_aggr.c @@ -272,7 +272,7 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 seq_no, u8 order) { RXTID *rxtid; - OSBUF_HOLD_Q *node; + struct osbuf_hold_q *node; u16 idx, idx_end, seq_end; RXTID_STATS *stats; @@ -433,7 +433,7 @@ aggr_process_recv_frm(void *cntxt, u8 tid, u16 seq_no, bool is_amsdu, void **osb RXTID_STATS *stats; u16 idx, st, cur, end; u16 *log_idx; - OSBUF_HOLD_Q *node; + struct osbuf_hold_q *node; PACKET_LOG *log; A_ASSERT(p_aggr); -- cgit v1.2.3 From a541306e81c531d85e052315dc47dac91adb50c9 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:59:05 -0700 Subject: ath6kl: remove-typedef PSCmdPacket remove-typedef -s PSCmdPacket \ "struct ps_cmd_packet" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c | 4 ++-- drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c | 12 ++++++------ drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c index 3436cbdf59bd..8393efe69f5b 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c @@ -41,7 +41,7 @@ */ typedef struct { - PSCmdPacket *HciCmdList; + struct ps_cmd_packet *HciCmdList; u32 num_packets; struct ar3k_config_info *dev; }HciCommandListParam; @@ -133,7 +133,7 @@ int PSSendOps(void *arg) { int i; int status = 0; - PSCmdPacket *HciCmdList; /* List storing the commands */ + struct ps_cmd_packet *HciCmdList; /* List storing the commands */ const struct firmware* firmware; u32 numCmds; u8 *event; diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c index 300c501a1c0b..b334a3d7f72a 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c @@ -130,7 +130,7 @@ tRamPatch RamPatch[MAX_NUM_PATCH_ENTRY]; int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat); char AthReadChar(u8 *buffer, u32 len,u32 *pos); char *AthGetLine(char *buffer, int maxlen, u8 *srcbuffer,u32 len,u32 *pos); -static int AthPSCreateHCICommand(u8 Opcode, u32 Param1,PSCmdPacket *PSPatchPacket,u32 *index); +static int AthPSCreateHCICommand(u8 Opcode, u32 Param1,struct ps_cmd_packet *PSPatchPacket,u32 *index); /* Function to reads the next character from the input buffer */ char AthReadChar(u8 *buffer, u32 len,u32 *pos) @@ -764,7 +764,7 @@ static void LoadHeader(u8 *HCI_PS_Command,u8 opcode,int length,int index){ ///////////////////////// // -int AthCreateCommandList(PSCmdPacket **HciPacketList, u32 *numPackets) +int AthCreateCommandList(struct ps_cmd_packet **HciPacketList, u32 *numPackets) { u8 count; @@ -785,8 +785,8 @@ int AthCreateCommandList(PSCmdPacket **HciPacketList, u32 *numPackets) if(Patch_Count > 0) { NumcmdEntry++; /* Patch Enable Command */ } - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Num Cmd Entries %d Size %d \r\n",NumcmdEntry,(u32)sizeof(PSCmdPacket) * NumcmdEntry)); - (*HciPacketList) = A_MALLOC(sizeof(PSCmdPacket) * NumcmdEntry); + AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Num Cmd Entries %d Size %d \r\n",NumcmdEntry,(u32)sizeof(struct ps_cmd_packet) * NumcmdEntry)); + (*HciPacketList) = A_MALLOC(sizeof(struct ps_cmd_packet) * NumcmdEntry); if(NULL == *HciPacketList) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("memory allocation failed \r\n")); } @@ -833,7 +833,7 @@ int AthCreateCommandList(PSCmdPacket **HciPacketList, u32 *numPackets) //////////////////////// ///////////// -static int AthPSCreateHCICommand(u8 Opcode, u32 Param1,PSCmdPacket *PSPatchPacket,u32 *index) +static int AthPSCreateHCICommand(u8 Opcode, u32 Param1,struct ps_cmd_packet *PSPatchPacket,u32 *index) { u8 *HCI_PS_Command; u32 Length; @@ -955,7 +955,7 @@ static int AthPSCreateHCICommand(u8 Opcode, u32 Param1,PSCmdPacket *PSPatchPacke } return 0; } -int AthFreeCommandList(PSCmdPacket **HciPacketList, u32 numPackets) +int AthFreeCommandList(struct ps_cmd_packet **HciPacketList, u32 numPackets) { int i; if(*HciPacketList == NULL) { diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h index 62e298deb255..9378efcd586e 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h @@ -89,11 +89,11 @@ -typedef struct PSCmdPacket +struct ps_cmd_packet { u8 *Hcipacket; int packetLen; -} PSCmdPacket; +}; /* Parses a Patch information buffer and store it in global structure */ int AthDoParsePatch(u8 *, u32 ); @@ -112,8 +112,8 @@ int AthDoParsePS(u8 *, u32 ); * PS Tag Command(s) * */ -int AthCreateCommandList(PSCmdPacket **, u32 *); +int AthCreateCommandList(struct ps_cmd_packet **, u32 *); /* Cleanup the dynamically allicated HCI command list */ -int AthFreeCommandList(PSCmdPacket **HciPacketList, u32 numPackets); +int AthFreeCommandList(struct ps_cmd_packet **HciPacketList, u32 numPackets); #endif /* __AR3KPSPARSER_H */ -- cgit v1.2.3 From ebb3aa52edeb6a05ccb690738259943023afcce9 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:59:06 -0700 Subject: ath6kl: remove-typedef RXTID remove-typedef -s RXTID \ "struct rxtid" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/reorder/aggr_rx_internal.h | 6 +++--- drivers/staging/ath6kl/reorder/rcv_aggr.c | 22 +++++++++++----------- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h index 082a8da02028..8b091dfb9cfe 100644 --- a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h +++ b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h @@ -73,7 +73,7 @@ typedef struct { }WINDOW_SNAPSHOT; #endif -typedef struct { +struct rxtid { bool aggr; /* is it ON or OFF */ bool progress; /* true when frames have arrived after a timer start */ bool timerMon; /* true if the timer started for the sake of this TID */ @@ -86,7 +86,7 @@ typedef struct { #endif A_NETBUF_QUEUE_T q; /* q head for enqueuing frames for dispatch */ A_MUTEX_T lock; -}RXTID; +}; typedef struct { u32 num_into_aggr; /* hitting at the input of this module */ @@ -106,7 +106,7 @@ struct aggr_info { A_TIMER timer; /* timer for returning held up pkts in re-order que */ void *dev; /* dev handle */ RX_CALLBACK rx_fn; /* callback function to return frames; to upper layer */ - RXTID RxTid[NUM_OF_TIDS]; /* Per tid window */ + struct rxtid RxTid[NUM_OF_TIDS]; /* Per tid window */ ALLOC_NETBUFS netbuf_allocator; /* OS netbuf alloc fn */ A_NETBUF_QUEUE_T freeQ; /* pre-allocated buffers - for A_MSDU slicing */ RXTID_STATS stat[NUM_OF_TIDS]; /* Tid based statistics */ diff --git a/drivers/staging/ath6kl/reorder/rcv_aggr.c b/drivers/staging/ath6kl/reorder/rcv_aggr.c index c54d492e444b..8d134898e4c1 100644 --- a/drivers/staging/ath6kl/reorder/rcv_aggr.c +++ b/drivers/staging/ath6kl/reorder/rcv_aggr.c @@ -37,7 +37,7 @@ extern int wmi_dot3_2_dix(void *osbuf); static void -aggr_slice_amsdu(struct aggr_info *p_aggr, RXTID *rxtid, void **osbuf); +aggr_slice_amsdu(struct aggr_info *p_aggr, struct rxtid *rxtid, void **osbuf); static void aggr_timeout(A_ATH_TIMER arg); @@ -55,7 +55,7 @@ void * aggr_init(ALLOC_NETBUFS netbuf_allocator) { struct aggr_info *p_aggr = NULL; - RXTID *rxtid; + struct rxtid *rxtid; u8 i; int status = 0; @@ -103,7 +103,7 @@ aggr_init(ALLOC_NETBUFS netbuf_allocator) static void aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid) { - RXTID *rxtid; + struct rxtid *rxtid; RXTID_STATS *stats; A_ASSERT(tid < NUM_OF_TIDS && p_aggr); @@ -134,7 +134,7 @@ void aggr_module_destroy(void *cntxt) { struct aggr_info *p_aggr = (struct aggr_info *)cntxt; - RXTID *rxtid; + struct rxtid *rxtid; u8 i, k; A_PRINTF("%s(): aggr = %p\n",_A_FUNCNAME_, p_aggr); A_ASSERT(p_aggr); @@ -204,7 +204,7 @@ void aggr_recv_addba_req_evt(void *cntxt, u8 tid, u16 seq_no, u8 win_sz) { struct aggr_info *p_aggr = (struct aggr_info *)cntxt; - RXTID *rxtid; + struct rxtid *rxtid; RXTID_STATS *stats; A_ASSERT(p_aggr); @@ -256,7 +256,7 @@ void aggr_recv_delba_req_evt(void *cntxt, u8 tid) { struct aggr_info *p_aggr = (struct aggr_info *)cntxt; - RXTID *rxtid; + struct rxtid *rxtid; A_ASSERT(p_aggr); A_PRINTF("%s(): tid %d\n", _A_FUNCNAME_, tid); @@ -271,7 +271,7 @@ aggr_recv_delba_req_evt(void *cntxt, u8 tid) static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 seq_no, u8 order) { - RXTID *rxtid; + struct rxtid *rxtid; struct osbuf_hold_q *node; u16 idx, idx_end, seq_end; RXTID_STATS *stats; @@ -356,7 +356,7 @@ aggr_get_osbuf(struct aggr_info *p_aggr) static void -aggr_slice_amsdu(struct aggr_info *p_aggr, RXTID *rxtid, void **osbuf) +aggr_slice_amsdu(struct aggr_info *p_aggr, struct rxtid *rxtid, void **osbuf) { void *new_buf; u16 frame_8023_len, payload_8023_len, mac_hdr_len, amsdu_len; @@ -429,7 +429,7 @@ void aggr_process_recv_frm(void *cntxt, u8 tid, u16 seq_no, bool is_amsdu, void **osbuf) { struct aggr_info *p_aggr = (struct aggr_info *)cntxt; - RXTID *rxtid; + struct rxtid *rxtid; RXTID_STATS *stats; u16 idx, st, cur, end; u16 *log_idx; @@ -577,7 +577,7 @@ aggr_timeout(A_ATH_TIMER arg) { u8 i,j; struct aggr_info *p_aggr = (struct aggr_info *)arg; - RXTID *rxtid; + struct rxtid *rxtid; RXTID_STATS *stats; /* * If the q for which the timer was originally started has @@ -643,7 +643,7 @@ void aggr_dump_stats(void *cntxt, PACKET_LOG **log_buf) { struct aggr_info *p_aggr = (struct aggr_info *)cntxt; - RXTID *rxtid; + struct rxtid *rxtid; RXTID_STATS *stats; u8 i; -- cgit v1.2.3 From 9da9daf274002d240f5b72dd4d2e18e1f629ac26 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:59:07 -0700 Subject: ath6kl: remove-typedef RXTID_STATS remove-typedef -s RXTID_STATS \ "struct rxtid_stats" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/reorder/aggr_rx_internal.h | 6 +++--- drivers/staging/ath6kl/reorder/rcv_aggr.c | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h index 8b091dfb9cfe..becbab9a8d8e 100644 --- a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h +++ b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h @@ -88,7 +88,7 @@ struct rxtid { A_MUTEX_T lock; }; -typedef struct { +struct rxtid_stats { u32 num_into_aggr; /* hitting at the input of this module */ u32 num_dups; /* duplicate */ u32 num_oow; /* out of window */ @@ -98,7 +98,7 @@ typedef struct { u32 num_timeouts; /* num of timeouts, during which frames delivered */ u32 num_hole; /* frame not present, when window moved over */ u32 num_bar; /* num of resets of seq_num, via BAR */ -}RXTID_STATS; +}; struct aggr_info { u8 aggr_sz; /* config value of aggregation size */ @@ -109,7 +109,7 @@ struct aggr_info { struct rxtid RxTid[NUM_OF_TIDS]; /* Per tid window */ ALLOC_NETBUFS netbuf_allocator; /* OS netbuf alloc fn */ A_NETBUF_QUEUE_T freeQ; /* pre-allocated buffers - for A_MSDU slicing */ - RXTID_STATS stat[NUM_OF_TIDS]; /* Tid based statistics */ + struct rxtid_stats stat[NUM_OF_TIDS]; /* Tid based statistics */ PACKET_LOG pkt_log; /* Log info of the packets */ }; diff --git a/drivers/staging/ath6kl/reorder/rcv_aggr.c b/drivers/staging/ath6kl/reorder/rcv_aggr.c index 8d134898e4c1..094b227b32c4 100644 --- a/drivers/staging/ath6kl/reorder/rcv_aggr.c +++ b/drivers/staging/ath6kl/reorder/rcv_aggr.c @@ -104,7 +104,7 @@ static void aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid) { struct rxtid *rxtid; - RXTID_STATS *stats; + struct rxtid_stats *stats; A_ASSERT(tid < NUM_OF_TIDS && p_aggr); @@ -127,7 +127,7 @@ aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid) rxtid->hold_q = NULL; } - A_MEMZERO(stats, sizeof(RXTID_STATS)); + A_MEMZERO(stats, sizeof(struct rxtid_stats)); } void @@ -190,7 +190,7 @@ void aggr_process_bar(void *cntxt, u8 tid, u16 seq_no) { struct aggr_info *p_aggr = (struct aggr_info *)cntxt; - RXTID_STATS *stats; + struct rxtid_stats *stats; A_ASSERT(p_aggr); stats = AGGR_GET_RXTID_STATS(p_aggr, tid); @@ -205,7 +205,7 @@ aggr_recv_addba_req_evt(void *cntxt, u8 tid, u16 seq_no, u8 win_sz) { struct aggr_info *p_aggr = (struct aggr_info *)cntxt; struct rxtid *rxtid; - RXTID_STATS *stats; + struct rxtid_stats *stats; A_ASSERT(p_aggr); rxtid = AGGR_GET_RXTID(p_aggr, tid); @@ -274,7 +274,7 @@ aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 seq_no, u8 order) struct rxtid *rxtid; struct osbuf_hold_q *node; u16 idx, idx_end, seq_end; - RXTID_STATS *stats; + struct rxtid_stats *stats; A_ASSERT(p_aggr); rxtid = AGGR_GET_RXTID(p_aggr, tid); @@ -430,7 +430,7 @@ aggr_process_recv_frm(void *cntxt, u8 tid, u16 seq_no, bool is_amsdu, void **osb { struct aggr_info *p_aggr = (struct aggr_info *)cntxt; struct rxtid *rxtid; - RXTID_STATS *stats; + struct rxtid_stats *stats; u16 idx, st, cur, end; u16 *log_idx; struct osbuf_hold_q *node; @@ -578,7 +578,7 @@ aggr_timeout(A_ATH_TIMER arg) u8 i,j; struct aggr_info *p_aggr = (struct aggr_info *)arg; struct rxtid *rxtid; - RXTID_STATS *stats; + struct rxtid_stats *stats; /* * If the q for which the timer was originally started has * not progressed then it is necessary to dequeue all the @@ -644,7 +644,7 @@ aggr_dump_stats(void *cntxt, PACKET_LOG **log_buf) { struct aggr_info *p_aggr = (struct aggr_info *)cntxt; struct rxtid *rxtid; - RXTID_STATS *stats; + struct rxtid_stats *stats; u8 i; *log_buf = &p_aggr->pkt_log; -- cgit v1.2.3 From 5f801f7f44805269ff750568a146c38b3367d7f0 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:59:08 -0700 Subject: ath6kl: remove-typedef ST_PS_DATA_FORMAT remove-typedef -s ST_PS_DATA_FORMAT \ "struct st_ps_data_format" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c index b334a3d7f72a..7c9d4a80ee0d 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c @@ -100,10 +100,10 @@ typedef struct tRamPatch -typedef struct ST_PS_DATA_FORMAT { +struct st_ps_data_format { enum eType eDataType; bool bIsArray; -}ST_PS_DATA_FORMAT; +}; typedef struct ST_READ_STATUS { unsigned uTagID; @@ -146,7 +146,7 @@ char AthReadChar(u8 *buffer, u32 len,u32 *pos) } } /* PS parser helper function */ -unsigned int uGetInputDataFormat(char *pCharLine, ST_PS_DATA_FORMAT *pstFormat) +unsigned int uGetInputDataFormat(char *pCharLine, struct st_ps_data_format *pstFormat) { if(pCharLine[0] != '[') { pstFormat->eDataType = eHex; @@ -286,7 +286,7 @@ unsigned int uGetInputDataFormat(char *pCharLine, ST_PS_DATA_FORMAT *pstFormat) } } -unsigned int uReadDataInSection(char *pCharLine, ST_PS_DATA_FORMAT stPS_DataFormat) +unsigned int uReadDataInSection(char *pCharLine, struct st_ps_data_format stPS_DataFormat) { char *pTokenPtr = pCharLine; @@ -327,7 +327,7 @@ int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat) int uReadCount; - ST_PS_DATA_FORMAT stPS_DataFormat; + struct st_ps_data_format stPS_DataFormat; ST_READ_STATUS stReadStatus = {0, 0, 0,0}; pos = 0; Buffer = NULL; -- cgit v1.2.3 From 1982f05de1d572a048c4acf584fc4b5294f487e3 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:59:09 -0700 Subject: ath6kl: remove-typedef ST_READ_STATUS remove-typedef -s ST_READ_STATUS \ "struct st_read_status" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c index 7c9d4a80ee0d..94a0939bfbf2 100644 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c +++ b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c @@ -105,13 +105,13 @@ struct st_ps_data_format { bool bIsArray; }; -typedef struct ST_READ_STATUS { +struct st_read_status { unsigned uTagID; unsigned uSection; unsigned uLineCount; unsigned uCharCount; unsigned uByteCount; -}ST_READ_STATUS; +}; /* Stores the number of PS Tags */ @@ -328,7 +328,7 @@ int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat) int uReadCount; struct st_ps_data_format stPS_DataFormat; - ST_READ_STATUS stReadStatus = {0, 0, 0,0}; + struct st_read_status stReadStatus = {0, 0, 0,0}; pos = 0; Buffer = NULL; -- cgit v1.2.3 From b2bad0874006d504a887468f0ce40f4de326e8e8 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:59:10 -0700 Subject: ath6kl: remove-typedef WINDOW_SNAPSHOT remove-typedef -s WINDOW_SNAPSHOT \ "struct window_snapshot" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/reorder/aggr_rx_internal.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h index becbab9a8d8e..11125967d53d 100644 --- a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h +++ b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h @@ -67,10 +67,11 @@ struct osbuf_hold_q { #if 0 -typedef struct { +/* XXX: unused ? */ +struct window_snapshot { u16 seqno_st; u16 seqno_end; -}WINDOW_SNAPSHOT; +}; #endif struct rxtid { @@ -82,7 +83,7 @@ struct rxtid { u32 hold_q_sz; /* Num of frames that can be held in hold q */ struct osbuf_hold_q *hold_q; /* Hold q for re-order */ #if 0 - WINDOW_SNAPSHOT old_win; /* Sliding window snapshot - for timeout */ + struct window_snapshot old_win; /* Sliding window snapshot - for timeout */ #endif A_NETBUF_QUEUE_T q; /* q head for enqueuing frames for dispatch */ A_MUTEX_T lock; -- cgit v1.2.3 From a71f0bf684bc1d1ae74ede5639d376d45a64ba7e Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:59:11 -0700 Subject: ath6kl: remove-typedef AR_SOFTC_T remove-typedef -s AR_SOFTC_T \ "struct ar6_softc" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/os/linux/ar6000_android.c | 2 +- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 242 ++++++++++----------- drivers/staging/ath6kl/os/linux/ar6000_pm.c | 18 +- drivers/staging/ath6kl/os/linux/ar6000_raw_if.c | 18 +- drivers/staging/ath6kl/os/linux/ar6k_pal.c | 8 +- drivers/staging/ath6kl/os/linux/cfg80211.c | 50 ++--- drivers/staging/ath6kl/os/linux/hci_bridge.c | 24 +- .../staging/ath6kl/os/linux/include/ar6000_drv.h | 36 +-- drivers/staging/ath6kl/os/linux/include/cfg80211.h | 10 +- drivers/staging/ath6kl/os/linux/ioctl.c | 112 +++++----- drivers/staging/ath6kl/os/linux/wireless_ext.c | 66 +++--- 11 files changed, 293 insertions(+), 293 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/os/linux/ar6000_android.c b/drivers/staging/ath6kl/os/linux/ar6000_android.c index 002cdc76c830..c96f6e9c99c6 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_android.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_android.c @@ -334,7 +334,7 @@ void android_module_exit(void) } #ifdef CONFIG_PM -void android_ar6k_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, bool isEvent) +void android_ar6k_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent) { if ( #ifdef CONFIG_HAS_EARLYSUSPEND diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 41c66b77e5f6..27cb02dfad3c 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -281,7 +281,7 @@ static void ar6000_cleanup_module(void); int ar6000_init(struct net_device *dev); static int ar6000_open(struct net_device *dev); static int ar6000_close(struct net_device *dev); -static void ar6000_init_control_info(AR_SOFTC_T *ar); +static void ar6000_init_control_info(struct ar6_softc *ar); static int ar6000_data_tx(struct sk_buff *skb, struct net_device *dev); void ar6000_destroy(struct net_device *dev, unsigned int unregister); @@ -292,7 +292,7 @@ static struct iw_statistics *ar6000_get_iwstats(struct net_device * dev); static void disconnect_timer_handler(unsigned long ptr); -void read_rssi_compensation_param(AR_SOFTC_T *ar); +void read_rssi_compensation_param(struct ar6_softc *ar); /* for android builds we call external APIs that handle firmware download and configuration */ #ifdef ANDROID_ENV @@ -309,7 +309,7 @@ static int ar6000_avail_ev(void *context, void *hif_handle); static int ar6000_unavail_ev(void *context, void *hif_handle); -int ar6000_configure_target(AR_SOFTC_T *ar); +int ar6000_configure_target(struct ar6_softc *ar); static void ar6000_target_failure(void *Instance, int Status); @@ -329,9 +329,9 @@ static void ar6000_deliver_frames_to_nw_stack(void * dev, void *osbuf); static struct htc_packet *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length); -static void ar6000_refill_amsdu_rxbufs(AR_SOFTC_T *ar, int Count); +static void ar6000_refill_amsdu_rxbufs(struct ar6_softc *ar, int Count); -static void ar6000_cleanup_amsdu_rxbufs(AR_SOFTC_T *ar); +static void ar6000_cleanup_amsdu_rxbufs(struct ar6_softc *ar); static ssize_t ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj, @@ -344,17 +344,17 @@ ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj, char *buf, loff_t pos, size_t count); static int -ar6000_sysfs_bmi_init(AR_SOFTC_T *ar); +ar6000_sysfs_bmi_init(struct ar6_softc *ar); /* HCI PAL callback function declarations */ -int ar6k_setup_hci_pal(AR_SOFTC_T *ar); -void ar6k_cleanup_hci_pal(AR_SOFTC_T *ar); +int ar6k_setup_hci_pal(struct ar6_softc *ar); +void ar6k_cleanup_hci_pal(struct ar6_softc *ar); static void -ar6000_sysfs_bmi_deinit(AR_SOFTC_T *ar); +ar6000_sysfs_bmi_deinit(struct ar6_softc *ar); int -ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, u32 mode); +ar6000_sysfs_bmi_get_config(struct ar6_softc *ar, u32 mode); /* * Static variables @@ -364,13 +364,13 @@ struct net_device *ar6000_devices[MAX_AR6000]; static int is_netdev_registered; extern struct iw_handler_def ath_iw_handler_def; DECLARE_WAIT_QUEUE_HEAD(arEvent); -static void ar6000_cookie_init(AR_SOFTC_T *ar); -static void ar6000_cookie_cleanup(AR_SOFTC_T *ar); -static void ar6000_free_cookie(AR_SOFTC_T *ar, struct ar_cookie * cookie); -static struct ar_cookie *ar6000_alloc_cookie(AR_SOFTC_T *ar); +static void ar6000_cookie_init(struct ar6_softc *ar); +static void ar6000_cookie_cleanup(struct ar6_softc *ar); +static void ar6000_free_cookie(struct ar6_softc *ar, struct ar_cookie * cookie); +static struct ar_cookie *ar6000_alloc_cookie(struct ar6_softc *ar); #ifdef USER_KEYS -static int ar6000_reinstall_keys(AR_SOFTC_T *ar,u8 key_op_ctrl); +static int ar6000_reinstall_keys(struct ar6_softc *ar,u8 key_op_ctrl); #endif #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT @@ -403,7 +403,7 @@ static struct net_device_ops ar6000_netdev_ops = { #define REPORT_DEBUG_LOGS_TO_APP int -ar6000_set_host_app_area(AR_SOFTC_T *ar) +ar6000_set_host_app_area(struct ar6_softc *ar) { u32 address, data; struct host_app_area_s host_app_area; @@ -425,7 +425,7 @@ ar6000_set_host_app_area(AR_SOFTC_T *ar) return 0; } -u32 dbglog_get_debug_hdr_ptr(AR_SOFTC_T *ar) +u32 dbglog_get_debug_hdr_ptr(struct ar6_softc *ar) { u32 param; u32 address; @@ -446,7 +446,7 @@ u32 dbglog_get_debug_hdr_ptr(AR_SOFTC_T *ar) * data stuctures over the diagnostic window. */ void -ar6000_dbglog_init_done(AR_SOFTC_T *ar) +ar6000_dbglog_init_done(struct ar6_softc *ar) { ar->dbglog_init_done = true; } @@ -518,7 +518,7 @@ dbglog_parse_debug_logs(s8 *datap, u32 len) } int -ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar) +ar6000_dbglog_get_debug_logs(struct ar6_softc *ar) { u32 data[8]; /* Should be able to accomodate struct dbglog_buf_s */ u32 address; @@ -596,7 +596,7 @@ ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar) } void -ar6000_dbglog_event(AR_SOFTC_T *ar, u32 dropped, +ar6000_dbglog_event(struct ar6_softc *ar, u32 dropped, s8 *buffer, u32 length) { #ifdef REPORT_DEBUG_LOGS_TO_APP @@ -738,10 +738,10 @@ aptcTimerHandler(unsigned long arg) { u32 numbytes; u32 throughput; - AR_SOFTC_T *ar; + struct ar6_softc *ar; int status; - ar = (AR_SOFTC_T *)arg; + ar = (struct ar6_softc *)arg; A_ASSERT(ar != NULL); A_ASSERT(!timer_pending(&aptcTimer)); @@ -802,12 +802,12 @@ ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj, char *buf, loff_t pos, size_t count) { int index; - AR_SOFTC_T *ar; + struct ar6_softc *ar; struct hif_device_os_device_info *osDevInfo; AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Read %d bytes\n", (u32)count)); for (index=0; index < MAX_AR6000; index++) { - ar = (AR_SOFTC_T *)ar6k_priv(ar6000_devices[index]); + ar = (struct ar6_softc *)ar6k_priv(ar6000_devices[index]); osDevInfo = &ar->osDevInfo; if (kobj == (&(((struct device *)osDevInfo->pOSDevice)->kobj))) { break; @@ -829,12 +829,12 @@ ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj, char *buf, loff_t pos, size_t count) { int index; - AR_SOFTC_T *ar; + struct ar6_softc *ar; struct hif_device_os_device_info *osDevInfo; AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Write %d bytes\n", (u32)count)); for (index=0; index < MAX_AR6000; index++) { - ar = (AR_SOFTC_T *)ar6k_priv(ar6000_devices[index]); + ar = (struct ar6_softc *)ar6k_priv(ar6000_devices[index]); osDevInfo = &ar->osDevInfo; if (kobj == (&(((struct device *)osDevInfo->pOSDevice)->kobj))) { break; @@ -851,7 +851,7 @@ ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj, } static int -ar6000_sysfs_bmi_init(AR_SOFTC_T *ar) +ar6000_sysfs_bmi_init(struct ar6_softc *ar) { int status; @@ -880,7 +880,7 @@ ar6000_sysfs_bmi_init(AR_SOFTC_T *ar) } static void -ar6000_sysfs_bmi_deinit(AR_SOFTC_T *ar) +ar6000_sysfs_bmi_deinit(struct ar6_softc *ar) { AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Deleting sysfs entry\n")); @@ -941,7 +941,7 @@ void calculate_crc(u32 TargetType, u8 *eeprom_data) } static void -ar6000_softmac_update(AR_SOFTC_T *ar, u8 *eeprom_data, size_t size) +ar6000_softmac_update(struct ar6_softc *ar, u8 *eeprom_data, size_t size) { const char *source = "random generated"; const struct firmware *softmac_entry; @@ -992,7 +992,7 @@ ar6000_softmac_update(AR_SOFTC_T *ar, u8 *eeprom_data, size_t size) #endif /* SOFTMAC_FILE_USED */ static int -ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, u32 address, bool compressed) +ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, bool compressed) { int status; const char *filename; @@ -1156,7 +1156,7 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, u32 address, bool c #endif /* INIT_MODE_DRV_ENABLED */ int -ar6000_update_bdaddr(AR_SOFTC_T *ar) +ar6000_update_bdaddr(struct ar6_softc *ar) { if (setupbtdev != 0) { @@ -1183,7 +1183,7 @@ return 0; } int -ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, u32 mode) +ar6000_sysfs_bmi_get_config(struct ar6_softc *ar, u32 mode) { AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Requesting device specific configuration\n")); @@ -1398,7 +1398,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, u32 mode) } int -ar6000_configure_target(AR_SOFTC_T *ar) +ar6000_configure_target(struct ar6_softc *ar) { u32 param; if (enableuartprint) { @@ -1597,7 +1597,7 @@ ar6000_avail_ev(void *context, void *hif_handle) int i; struct net_device *dev; void *ar_netif; - AR_SOFTC_T *ar; + struct ar6_softc *ar; int device_index = 0; struct htc_init_info htcInfo; #ifdef ATH6K_CONFIG_CFG80211 @@ -1638,7 +1638,7 @@ ar6000_avail_ev(void *context, void *hif_handle) } ar_netif = wdev_priv(wdev); #else - dev = alloc_etherdev(sizeof(AR_SOFTC_T)); + dev = alloc_etherdev(sizeof(struct ar6_softc)); if (dev == NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_available: can't alloc etherdev\n")); return A_ERROR; @@ -1652,8 +1652,8 @@ ar6000_avail_ev(void *context, void *hif_handle) return A_ERROR; } - A_MEMZERO(ar_netif, sizeof(AR_SOFTC_T)); - ar = (AR_SOFTC_T *)ar_netif; + A_MEMZERO(ar_netif, sizeof(struct ar6_softc)); + ar = (struct ar6_softc *)ar_netif; #ifdef ATH6K_CONFIG_CFG80211 ar->wdev = wdev; @@ -1854,7 +1854,7 @@ avail_ev_failed : static void ar6000_target_failure(void *Instance, int Status) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)Instance; + struct ar6_softc *ar = (struct ar6_softc *)Instance; WMI_TARGET_ERROR_REPORT_EVENT errEvent; static bool sip = false; @@ -1890,7 +1890,7 @@ static void ar6000_target_failure(void *Instance, int Status) static int ar6000_unavail_ev(void *context, void *hif_handle) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)context; + struct ar6_softc *ar = (struct ar6_softc *)context; /* NULL out it's entry in the global list */ ar6000_devices[ar->arDeviceIndex] = NULL; ar6000_destroy(ar->arNetDev, 1); @@ -1902,7 +1902,7 @@ void ar6000_restart_endpoint(struct net_device *dev) { int status = 0; - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); BMIInit(); do { @@ -1936,7 +1936,7 @@ ar6000_restart_endpoint(struct net_device *dev) void ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); /* Stop the transmit queues */ netif_stop_queue(dev); @@ -2074,7 +2074,7 @@ ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs) void ar6000_destroy(struct net_device *dev, unsigned int unregister) { - AR_SOFTC_T *ar; + struct ar6_softc *ar; AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("+ar6000_destroy \n")); @@ -2159,7 +2159,7 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister) static void disconnect_timer_handler(unsigned long ptr) { struct net_device *dev = (struct net_device *)ptr; - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); A_UNTIMEOUT(&ar->disconnect_timer); @@ -2170,7 +2170,7 @@ static void disconnect_timer_handler(unsigned long ptr) static void ar6000_detect_error(unsigned long ptr) { struct net_device *dev = (struct net_device *)ptr; - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_TARGET_ERROR_REPORT_EVENT errEvent; AR6000_SPIN_LOCK(&ar->arLock, 0); @@ -2209,7 +2209,7 @@ static void ar6000_detect_error(unsigned long ptr) A_TIMEOUT_MS(&ar->arHBChallengeResp.timer, ar->arHBChallengeResp.frequency * 1000, 0); } -void ar6000_init_profile_info(AR_SOFTC_T *ar) +void ar6000_init_profile_info(struct ar6_softc *ar) { ar->arSsidLen = 0; A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); @@ -2239,7 +2239,7 @@ void ar6000_init_profile_info(AR_SOFTC_T *ar) } static void -ar6000_init_control_info(AR_SOFTC_T *ar) +ar6000_init_control_info(struct ar6_softc *ar) { ar->arWmiEnabled = false; ar6000_init_profile_info(ar); @@ -2291,7 +2291,7 @@ static int ar6000_open(struct net_device *dev) { unsigned long flags; - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); spin_lock_irqsave(&ar->arLock, flags); @@ -2317,7 +2317,7 @@ static int ar6000_close(struct net_device *dev) { #ifdef ATH6K_CONFIG_CFG80211 - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); #endif /* ATH6K_CONFIG_CFG80211 */ netif_stop_queue(dev); @@ -2338,7 +2338,7 @@ ar6000_close(struct net_device *dev) } /* connect to a service */ -static int ar6000_connectservice(AR_SOFTC_T *ar, +static int ar6000_connectservice(struct ar6_softc *ar, struct htc_service_connect_req *pConnect, char *pDesc) { @@ -2390,7 +2390,7 @@ static int ar6000_connectservice(AR_SOFTC_T *ar, return status; } -void ar6000_TxDataCleanup(AR_SOFTC_T *ar) +void ar6000_TxDataCleanup(struct ar6_softc *ar) { /* flush all the data (non-control) streams * we only flush packets that are tagged as data, we leave any control packets that @@ -2412,20 +2412,20 @@ void ar6000_TxDataCleanup(AR_SOFTC_T *ar) HTC_ENDPOINT_ID ar6000_ac2_endpoint_id ( void * devt, u8 ac) { - AR_SOFTC_T *ar = (AR_SOFTC_T *) devt; + struct ar6_softc *ar = (struct ar6_softc *) devt; return(arAc2EndpointID(ar, ac)); } u8 ar6000_endpoint_id2_ac(void * devt, HTC_ENDPOINT_ID ep ) { - AR_SOFTC_T *ar = (AR_SOFTC_T *) devt; + struct ar6_softc *ar = (struct ar6_softc *) devt; return(arEndpoint2Ac(ar, ep )); } /* * This function applies WLAN specific configuration defined in wlan_config.h */ -int ar6000_target_config_wlan_params(AR_SOFTC_T *ar) +int ar6000_target_config_wlan_params(struct ar6_softc *ar) { int status = 0; #if defined(INIT_MODE_DRV_ENABLED) && defined(ENABLE_COEXISTENCE) @@ -2546,7 +2546,7 @@ int ar6000_target_config_wlan_params(AR_SOFTC_T *ar) /* This function does one time initialization for the lifetime of the device */ int ar6000_init(struct net_device *dev) { - AR_SOFTC_T *ar; + struct ar6_softc *ar; int status; s32 timeleft; s16 i; @@ -2845,7 +2845,7 @@ ar6000_init_done: void ar6000_bitrate_rx(void *devt, s32 rateKbps) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; + struct ar6_softc *ar = (struct ar6_softc *)devt; ar->arBitRate = rateKbps; wake_up(&arEvent); @@ -2854,7 +2854,7 @@ ar6000_bitrate_rx(void *devt, s32 rateKbps) void ar6000_ratemask_rx(void *devt, u32 ratemask) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; + struct ar6_softc *ar = (struct ar6_softc *)devt; ar->arRateMask = ratemask; wake_up(&arEvent); @@ -2863,7 +2863,7 @@ ar6000_ratemask_rx(void *devt, u32 ratemask) void ar6000_txPwr_rx(void *devt, u8 txPwr) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; + struct ar6_softc *ar = (struct ar6_softc *)devt; ar->arTxPwr = txPwr; wake_up(&arEvent); @@ -2873,7 +2873,7 @@ ar6000_txPwr_rx(void *devt, u8 txPwr) void ar6000_channelList_rx(void *devt, s8 numChan, u16 *chanList) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; + struct ar6_softc *ar = (struct ar6_softc *)devt; memcpy(ar->arChannelList, chanList, numChan * sizeof (u16)); ar->arNumChannels = numChan; @@ -2883,7 +2883,7 @@ ar6000_channelList_rx(void *devt, s8 numChan, u16 *chanList) u8 ar6000_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, u32 *mapNo) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); u8 *datap; ATH_MAC_HDR *macHdr; u32 i, eptMap; @@ -2952,14 +2952,14 @@ static void ar6000_dump_skb(struct sk_buff *skb) #endif #ifdef HTC_TEST_SEND_PKTS -static void DoHTCSendPktsTest(AR_SOFTC_T *ar, int MapNo, HTC_ENDPOINT_ID eid, struct sk_buff *skb); +static void DoHTCSendPktsTest(struct ar6_softc *ar, int MapNo, HTC_ENDPOINT_ID eid, struct sk_buff *skb); #endif static int ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) { #define AC_NOT_MAPPED 99 - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); u8 ac = AC_NOT_MAPPED; HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED; u32 mapNo = 0; @@ -3281,7 +3281,7 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) int ar6000_acl_data_tx(struct sk_buff *skb, struct net_device *dev) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); struct ar_cookie *cookie; HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED; @@ -3337,7 +3337,7 @@ tvsub(register struct timeval *out, register struct timeval *in) } void -applyAPTCHeuristics(AR_SOFTC_T *ar) +applyAPTCHeuristics(struct ar6_softc *ar) { u32 duration; u32 numbytes; @@ -3378,7 +3378,7 @@ applyAPTCHeuristics(AR_SOFTC_T *ar) static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, struct htc_packet *pPacket) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; + struct ar6_softc *ar = (struct ar6_softc *)Context; HTC_SEND_FULL_ACTION action = HTC_SEND_FULL_KEEP; bool stopNet = false; HTC_ENDPOINT_ID Endpoint = HTC_GET_ENDPOINT_FROM_PKT(pPacket); @@ -3463,7 +3463,7 @@ static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, struct htc_packe static void ar6000_tx_complete(void *Context, struct htc_packet_queue *pPacketQueue) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; + struct ar6_softc *ar = (struct ar6_softc *)Context; u32 mapNo = 0; int status; struct ar_cookie * ar_cookie; @@ -3599,7 +3599,7 @@ ar6000_tx_complete(void *Context, struct htc_packet_queue *pPacketQueue) } sta_t * -ieee80211_find_conn(AR_SOFTC_T *ar, u8 *node_addr) +ieee80211_find_conn(struct ar6_softc *ar, u8 *node_addr) { sta_t *conn = NULL; u8 i, max_conn; @@ -3623,7 +3623,7 @@ ieee80211_find_conn(AR_SOFTC_T *ar, u8 *node_addr) return conn; } -sta_t *ieee80211_find_conn_for_aid(AR_SOFTC_T *ar, u8 aid) +sta_t *ieee80211_find_conn_for_aid(struct ar6_softc *ar, u8 aid) { sta_t *conn = NULL; u8 ctr; @@ -3644,7 +3644,7 @@ int pktcount; static void ar6000_rx(void *Context, struct htc_packet *pPacket) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; + struct ar6_softc *ar = (struct ar6_softc *)Context; struct sk_buff *skb = (struct sk_buff *)pPacket->pPktContext; int minHdrLen; u8 containsDot11Hdr = 0; @@ -3942,7 +3942,7 @@ ar6000_deliver_frames_to_nw_stack(void *dev, void *osbuf) skb->dev = dev; if ((skb->dev->flags & IFF_UP) == IFF_UP) { #ifdef CONFIG_PM - ar6000_check_wow_status((AR_SOFTC_T *)ar6k_priv(dev), skb, false); + ar6000_check_wow_status((struct ar6_softc *)ar6k_priv(dev), skb, false); #endif /* CONFIG_PM */ skb->protocol = eth_type_trans(skb, skb->dev); /* @@ -3987,7 +3987,7 @@ ar6000_deliver_frames_to_bt_stack(void *dev, void *osbuf) static void ar6000_rx_refill(void *Context, HTC_ENDPOINT_ID Endpoint) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; + struct ar6_softc *ar = (struct ar6_softc *)Context; void *osBuf; int RxBuffers; int buffersToRefill; @@ -4029,7 +4029,7 @@ ar6000_rx_refill(void *Context, HTC_ENDPOINT_ID Endpoint) } /* clean up our amsdu buffer list */ -static void ar6000_cleanup_amsdu_rxbufs(AR_SOFTC_T *ar) +static void ar6000_cleanup_amsdu_rxbufs(struct ar6_softc *ar) { struct htc_packet *pPacket; void *osBuf; @@ -4058,7 +4058,7 @@ static void ar6000_cleanup_amsdu_rxbufs(AR_SOFTC_T *ar) /* refill the amsdu buffer list */ -static void ar6000_refill_amsdu_rxbufs(AR_SOFTC_T *ar, int Count) +static void ar6000_refill_amsdu_rxbufs(struct ar6_softc *ar, int Count) { struct htc_packet *pPacket; void *osBuf; @@ -4093,7 +4093,7 @@ static void ar6000_refill_amsdu_rxbufs(AR_SOFTC_T *ar, int Count) static struct htc_packet *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length) { struct htc_packet *pPacket = NULL; - AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; + struct ar6_softc *ar = (struct ar6_softc *)Context; int refillCount = 0; AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_alloc_amsdu_rxbuf: eid=%d, Length:%d\n",Endpoint,Length)); @@ -4142,14 +4142,14 @@ ar6000_set_multicast_list(struct net_device *dev) static struct net_device_stats * ar6000_get_stats(struct net_device *dev) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); return &ar->arNetStats; } static struct iw_statistics * ar6000_get_iwstats(struct net_device * dev) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); TARGET_STATS *pStats = &ar->arTargetStats; struct iw_statistics * pIwStats = &ar->arIwStats; int rtnllocked; @@ -4236,7 +4236,7 @@ err_exit: void ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, u32 sw_ver, u32 abi_ver) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; + struct ar6_softc *ar = (struct ar6_softc *)devt; struct net_device *dev = ar->arNetDev; memcpy(dev->dev_addr, datap, AR6000_ETH_ADDR_LEN); @@ -4255,7 +4255,7 @@ ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, u32 sw_ver, u32 abi_ver) } void -add_new_sta(AR_SOFTC_T *ar, u8 *mac, u16 aid, u8 *wpaie, +add_new_sta(struct ar6_softc *ar, u8 *mac, u16 aid, u8 *wpaie, u8 ielen, u8 keymgmt, u8 ucipher, u8 auth) { u8 free_slot=aid-1; @@ -4271,7 +4271,7 @@ add_new_sta(AR_SOFTC_T *ar, u8 *mac, u16 aid, u8 *wpaie, } void -ar6000_connect_event(AR_SOFTC_T *ar, u16 channel, u8 *bssid, +ar6000_connect_event(struct ar6_softc *ar, u16 channel, u8 *bssid, u16 listenInterval, u16 beaconInterval, NETWORK_TYPE networkType, u8 beaconIeLen, u8 assocReqLen, u8 assocRespLen, @@ -4557,14 +4557,14 @@ skip_key: } -void ar6000_set_numdataendpts(AR_SOFTC_T *ar, u32 num) +void ar6000_set_numdataendpts(struct ar6_softc *ar, u32 num) { A_ASSERT(num <= (HTC_MAILBOX_NUM_MAX - 1)); ar->arNumDataEndPts = num; } void -sta_cleanup(AR_SOFTC_T *ar, u8 i) +sta_cleanup(struct ar6_softc *ar, u8 i) { struct sk_buff *skb; @@ -4587,7 +4587,7 @@ sta_cleanup(AR_SOFTC_T *ar, u8 i) } -u8 remove_sta(AR_SOFTC_T *ar, u8 *mac, u16 reason) +u8 remove_sta(struct ar6_softc *ar, u8 *mac, u16 reason) { u8 i, removed=0; @@ -4620,7 +4620,7 @@ u8 remove_sta(AR_SOFTC_T *ar, u8 *mac, u16 reason) } void -ar6000_disconnect_event(AR_SOFTC_T *ar, u8 reason, u8 *bssid, +ar6000_disconnect_event(struct ar6_softc *ar, u8 reason, u8 *bssid, u8 assocRespLen, u8 *assocInfo, u16 protocolReasonStatus) { u8 i; @@ -4768,7 +4768,7 @@ ar6000_disconnect_event(AR_SOFTC_T *ar, u8 reason, u8 *bssid, } void -ar6000_regDomain_event(AR_SOFTC_T *ar, u32 regCode) +ar6000_regDomain_event(struct ar6_softc *ar, u32 regCode) { A_PRINTF("AR6000 Reg Code = 0x%x\n", regCode); ar->arRegCode = regCode; @@ -4776,7 +4776,7 @@ ar6000_regDomain_event(AR_SOFTC_T *ar, u32 regCode) #ifdef ATH_AR6K_11N_SUPPORT void -ar6000_aggr_rcv_addba_req_evt(AR_SOFTC_T *ar, WMI_ADDBA_REQ_EVENT *evt) +ar6000_aggr_rcv_addba_req_evt(struct ar6_softc *ar, WMI_ADDBA_REQ_EVENT *evt) { if(evt->status == 0) { aggr_recv_addba_req_evt(ar->aggr_cntxt, evt->tid, evt->st_seq_no, evt->win_sz); @@ -4784,7 +4784,7 @@ ar6000_aggr_rcv_addba_req_evt(AR_SOFTC_T *ar, WMI_ADDBA_REQ_EVENT *evt) } void -ar6000_aggr_rcv_addba_resp_evt(AR_SOFTC_T *ar, WMI_ADDBA_RESP_EVENT *evt) +ar6000_aggr_rcv_addba_resp_evt(struct ar6_softc *ar, WMI_ADDBA_RESP_EVENT *evt) { A_PRINTF("ADDBA RESP. tid %d status %d, sz %d\n", evt->tid, evt->status, evt->amsdu_sz); if(evt->status == 0) { @@ -4792,7 +4792,7 @@ ar6000_aggr_rcv_addba_resp_evt(AR_SOFTC_T *ar, WMI_ADDBA_RESP_EVENT *evt) } void -ar6000_aggr_rcv_delba_req_evt(AR_SOFTC_T *ar, WMI_DELBA_EVENT *evt) +ar6000_aggr_rcv_delba_req_evt(struct ar6_softc *ar, WMI_DELBA_EVENT *evt) { aggr_recv_delba_req_evt(ar->aggr_cntxt, evt->tid); } @@ -4849,7 +4849,7 @@ ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd) } void -ar6000_neighborReport_event(AR_SOFTC_T *ar, int numAps, WMI_NEIGHBOR_INFO *info) +ar6000_neighborReport_event(struct ar6_softc *ar, int numAps, WMI_NEIGHBOR_INFO *info) { #if WIRELESS_EXT >= 18 struct iw_pmkid_cand *pmkcand; @@ -4897,7 +4897,7 @@ ar6000_neighborReport_event(AR_SOFTC_T *ar, int numAps, WMI_NEIGHBOR_INFO *info) } void -ar6000_tkip_micerr_event(AR_SOFTC_T *ar, u8 keyid, bool ismcast) +ar6000_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast) { static const char *tag = "MLME-MICHAELMICFAILURE.indication"; char buf[128]; @@ -4934,7 +4934,7 @@ ar6000_tkip_micerr_event(AR_SOFTC_T *ar, u8 keyid, bool ismcast) } void -ar6000_scanComplete_event(AR_SOFTC_T *ar, int status) +ar6000_scanComplete_event(struct ar6_softc *ar, int status) { #ifdef ATH6K_CONFIG_CFG80211 @@ -4957,7 +4957,7 @@ ar6000_scanComplete_event(AR_SOFTC_T *ar, int status) } void -ar6000_targetStats_event(AR_SOFTC_T *ar, u8 *ptr, u32 len) +ar6000_targetStats_event(struct ar6_softc *ar, u8 *ptr, u32 len) { u8 ac; @@ -5082,7 +5082,7 @@ ar6000_targetStats_event(AR_SOFTC_T *ar, u8 *ptr, u32 len) } void -ar6000_rssiThreshold_event(AR_SOFTC_T *ar, WMI_RSSI_THRESHOLD_VAL newThreshold, s16 rssi) +ar6000_rssiThreshold_event(struct ar6_softc *ar, WMI_RSSI_THRESHOLD_VAL newThreshold, s16 rssi) { USER_RSSI_THOLD userRssiThold; @@ -5103,7 +5103,7 @@ ar6000_rssiThreshold_event(AR_SOFTC_T *ar, WMI_RSSI_THRESHOLD_VAL newThreshold, void -ar6000_hbChallengeResp_event(AR_SOFTC_T *ar, u32 cookie, u32 source) +ar6000_hbChallengeResp_event(struct ar6_softc *ar, u32 cookie, u32 source) { if (source == APP_HB_CHALLENGE) { /* Report it to the app in case it wants a positive acknowledgement */ @@ -5119,7 +5119,7 @@ ar6000_hbChallengeResp_event(AR_SOFTC_T *ar, u32 cookie, u32 source) void -ar6000_reportError_event(AR_SOFTC_T *ar, WMI_TARGET_ERROR_VAL errorVal) +ar6000_reportError_event(struct ar6_softc *ar, WMI_TARGET_ERROR_VAL errorVal) { static const char * const errString[] = { [WMI_TARGET_PM_ERR_FAIL] "WMI_TARGET_PM_ERR_FAIL", @@ -5154,7 +5154,7 @@ ar6000_reportError_event(AR_SOFTC_T *ar, WMI_TARGET_ERROR_VAL errorVal) void -ar6000_cac_event(AR_SOFTC_T *ar, u8 ac, u8 cacIndication, +ar6000_cac_event(struct ar6_softc *ar, u8 ac, u8 cacIndication, u8 statusCode, u8 *tspecSuggestion) { WMM_TSPEC_IE *tspecIe; @@ -5177,7 +5177,7 @@ ar6000_cac_event(AR_SOFTC_T *ar, u8 ac, u8 cacIndication, } void -ar6000_channel_change_event(AR_SOFTC_T *ar, u16 oldChannel, +ar6000_channel_change_event(struct ar6_softc *ar, u16 oldChannel, u16 newChannel) { A_PRINTF("Channel Change notification\nOld Channel: %d, New Channel: %d\n", @@ -5191,7 +5191,7 @@ ar6000_channel_change_event(AR_SOFTC_T *ar, u16 oldChannel, } while(0) void -ar6000_roam_tbl_event(AR_SOFTC_T *ar, WMI_TARGET_ROAM_TBL *pTbl) +ar6000_roam_tbl_event(struct ar6_softc *ar, WMI_TARGET_ROAM_TBL *pTbl) { u8 i; @@ -5270,7 +5270,7 @@ ar6000_display_roam_time(WMI_TARGET_ROAM_TIME *p) } void -ar6000_roam_data_event(AR_SOFTC_T *ar, WMI_TARGET_ROAM_DATA *p) +ar6000_roam_data_event(struct ar6_softc *ar, WMI_TARGET_ROAM_DATA *p) { switch (p->roamDataType) { case ROAM_DATA_TIME: @@ -5282,7 +5282,7 @@ ar6000_roam_data_event(AR_SOFTC_T *ar, WMI_TARGET_ROAM_DATA *p) } void -ar6000_bssInfo_event_rx(AR_SOFTC_T *ar, u8 *datap, int len) +ar6000_bssInfo_event_rx(struct ar6_softc *ar, u8 *datap, int len) { struct sk_buff *skb; WMI_BSS_INFO_HDR *bih = (WMI_BSS_INFO_HDR *)datap; @@ -5317,7 +5317,7 @@ u32 wmiSendCmdNum; int ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; + struct ar6_softc *ar = (struct ar6_softc *)devt; int status = 0; struct ar_cookie *cookie = NULL; int i; @@ -5396,7 +5396,7 @@ ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid) /* indicate tx activity or inactivity on a WMI stream */ void ar6000_indicate_tx_activity(void *devt, u8 TrafficClass, bool Active) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; + struct ar6_softc *ar = (struct ar6_softc *)devt; HTC_ENDPOINT_ID eid ; int i; @@ -5510,7 +5510,7 @@ module_exit(ar6000_cleanup_module); /* Init cookie queue */ static void -ar6000_cookie_init(AR_SOFTC_T *ar) +ar6000_cookie_init(struct ar6_softc *ar) { u32 i; @@ -5526,7 +5526,7 @@ ar6000_cookie_init(AR_SOFTC_T *ar) /* cleanup cookie queue */ static void -ar6000_cookie_cleanup(AR_SOFTC_T *ar) +ar6000_cookie_cleanup(struct ar6_softc *ar) { /* It is gone .... */ ar->arCookieList = NULL; @@ -5535,7 +5535,7 @@ ar6000_cookie_cleanup(AR_SOFTC_T *ar) /* Init cookie queue */ static void -ar6000_free_cookie(AR_SOFTC_T *ar, struct ar_cookie * cookie) +ar6000_free_cookie(struct ar6_softc *ar, struct ar_cookie * cookie) { /* Insert first */ A_ASSERT(ar != NULL); @@ -5548,7 +5548,7 @@ ar6000_free_cookie(AR_SOFTC_T *ar, struct ar_cookie * cookie) /* cleanup cookie queue */ static struct ar_cookie * -ar6000_alloc_cookie(AR_SOFTC_T *ar) +ar6000_alloc_cookie(struct ar6_softc *ar) { struct ar_cookie *cookie; @@ -5569,7 +5569,7 @@ ar6000_alloc_cookie(AR_SOFTC_T *ar) * the event ID and event content. */ #define EVENT_ID_LEN 2 -void ar6000_send_event_to_app(AR_SOFTC_T *ar, u16 eventId, +void ar6000_send_event_to_app(struct ar6_softc *ar, u16 eventId, u8 *datap, int len) { @@ -5614,7 +5614,7 @@ void ar6000_send_event_to_app(AR_SOFTC_T *ar, u16 eventId, * to the application. The buf which is sent to application * includes the event ID and event content. */ -void ar6000_send_generic_event_to_app(AR_SOFTC_T *ar, u16 eventId, +void ar6000_send_generic_event_to_app(struct ar6_softc *ar, u16 eventId, u8 *datap, int len) { @@ -5666,7 +5666,7 @@ void ar6000_snrThresholdEvent_rx(void *devt, WMI_SNR_THRESHOLD_VAL newThreshold, u8 snr) { WMI_SNR_THRESHOLD_EVENT event; - AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; + struct ar6_softc *ar = (struct ar6_softc *)devt; event.range = newThreshold; event.snr = snr; @@ -5721,7 +5721,7 @@ ar6000_get_driver_cfg(struct net_device *dev, void ar6000_keepalive_rx(void *devt, u8 configured) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; + struct ar6_softc *ar = (struct ar6_softc *)devt; ar->arKeepaliveConfigured = configured; wake_up(&arEvent); @@ -5750,7 +5750,7 @@ ar6000_pmkid_list_event(void *devt, u8 numPMKID, WMI_PMKID *pmkidList, } } -void ar6000_pspoll_event(AR_SOFTC_T *ar,u8 aid) +void ar6000_pspoll_event(struct ar6_softc *ar,u8 aid) { sta_t *conn=NULL; bool isPsqEmpty = false; @@ -5790,7 +5790,7 @@ void ar6000_pspoll_event(AR_SOFTC_T *ar,u8 aid) } } -void ar6000_dtimexpiry_event(AR_SOFTC_T *ar) +void ar6000_dtimexpiry_event(struct ar6_softc *ar) { bool isMcastQueued = false; struct sk_buff *skb = NULL; @@ -5836,7 +5836,7 @@ void ar6000_dtimexpiry_event(AR_SOFTC_T *ar) } void -read_rssi_compensation_param(AR_SOFTC_T *ar) +read_rssi_compensation_param(struct ar6_softc *ar) { u8 *cust_data_ptr; @@ -5907,7 +5907,7 @@ s32 rssi_compensation_calc_tcmd(u32 freq, s32 rssi, u32 totalPkt) return rssi; } -s16 rssi_compensation_calc(AR_SOFTC_T *ar, s16 rssi) +s16 rssi_compensation_calc(struct ar6_softc *ar, s16 rssi) { if (ar->arBssChannel > 5000) { @@ -5935,7 +5935,7 @@ s16 rssi_compensation_calc(AR_SOFTC_T *ar, s16 rssi) return rssi; } -s16 rssi_compensation_reverse_calc(AR_SOFTC_T *ar, s16 rssi, bool Above) +s16 rssi_compensation_reverse_calc(struct ar6_softc *ar, s16 rssi, bool Above) { s16 i; @@ -5980,7 +5980,7 @@ s16 rssi_compensation_reverse_calc(AR_SOFTC_T *ar, s16 rssi, bool Above) } #ifdef WAPI_ENABLE -void ap_wapi_rekey_event(AR_SOFTC_T *ar, u8 type, u8 *mac) +void ap_wapi_rekey_event(struct ar6_softc *ar, u8 type, u8 *mac) { union iwreq_data wrqu; char buf[20]; @@ -6002,7 +6002,7 @@ void ap_wapi_rekey_event(AR_SOFTC_T *ar, u8 type, u8 *mac) #ifdef USER_KEYS static int -ar6000_reinstall_keys(AR_SOFTC_T *ar, u8 key_op_ctrl) +ar6000_reinstall_keys(struct ar6_softc *ar, u8 key_op_ctrl) { int status = 0; struct ieee80211req_key *uik = &ar->user_saved_keys.ucast_ik; @@ -6316,7 +6316,7 @@ void ar6000_peer_event( #ifdef HTC_TEST_SEND_PKTS #define HTC_TEST_DUPLICATE 8 -static void DoHTCSendPktsTest(AR_SOFTC_T *ar, int MapNo, HTC_ENDPOINT_ID eid, struct sk_buff *dupskb) +static void DoHTCSendPktsTest(struct ar6_softc *ar, int MapNo, HTC_ENDPOINT_ID eid, struct sk_buff *dupskb) { struct ar_cookie *cookie; struct ar_cookie *cookieArray[HTC_TEST_DUPLICATE]; @@ -6400,7 +6400,7 @@ static void DoHTCSendPktsTest(AR_SOFTC_T *ar, int MapNo, HTC_ENDPOINT_ID eid, st * AP mode. */ -int ar6000_start_ap_interface(AR_SOFTC_T *ar) +int ar6000_start_ap_interface(struct ar6_softc *ar) { struct ar_virtual_interface *arApDev; @@ -6411,7 +6411,7 @@ int ar6000_start_ap_interface(AR_SOFTC_T *ar) return 0; } -int ar6000_stop_ap_interface(AR_SOFTC_T *ar) +int ar6000_stop_ap_interface(struct ar6_softc *ar) { struct ar_virtual_interface *arApDev; @@ -6425,7 +6425,7 @@ int ar6000_stop_ap_interface(AR_SOFTC_T *ar) } -int ar6000_create_ap_interface(AR_SOFTC_T *ar, char *ap_ifname) +int ar6000_create_ap_interface(struct ar6_softc *ar, char *ap_ifname) { struct net_device *dev; struct ar_virtual_interface *arApDev; @@ -6458,7 +6458,7 @@ int ar6000_create_ap_interface(AR_SOFTC_T *ar, char *ap_ifname) return 0; } -int ar6000_add_ap_interface(AR_SOFTC_T *ar, char *ap_ifname) +int ar6000_add_ap_interface(struct ar6_softc *ar, char *ap_ifname) { /* Interface already added, need not proceed further */ if (ar->arApDev != NULL) { @@ -6475,7 +6475,7 @@ int ar6000_add_ap_interface(AR_SOFTC_T *ar, char *ap_ifname) return ar6000_start_ap_interface(ar); } -int ar6000_remove_ap_interface(AR_SOFTC_T *ar) +int ar6000_remove_ap_interface(struct ar6_softc *ar) { if (arApNetDev) { ar6000_stop_ap_interface(ar); diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c index 5659ad8f8e16..1a9042446bcb 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_pm.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_pm.c @@ -37,7 +37,7 @@ extern unsigned int wmitimeout; extern wait_queue_head_t arEvent; #ifdef ANDROID_ENV -extern void android_ar6k_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, bool isEvent); +extern void android_ar6k_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent); #endif #undef ATH_MODULE_NAME #define ATH_MODULE_NAME pm @@ -57,10 +57,10 @@ ATH_DEBUG_INSTANTIATE_MODULE_VAR(pm, #endif /* DEBUG */ -int ar6000_exit_cut_power_state(AR_SOFTC_T *ar); +int ar6000_exit_cut_power_state(struct ar6_softc *ar); #ifdef CONFIG_PM -static void ar6k_send_asleep_event_to_app(AR_SOFTC_T *ar, bool asleep) +static void ar6k_send_asleep_event_to_app(struct ar6_softc *ar, bool asleep) { char buf[128]; union iwreq_data wrqu; @@ -71,7 +71,7 @@ static void ar6k_send_asleep_event_to_app(AR_SOFTC_T *ar, bool asleep) wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf); } -static void ar6000_wow_resume(AR_SOFTC_T *ar) +static void ar6000_wow_resume(struct ar6_softc *ar) { if (ar->arWowState!= WLAN_WOW_STATE_NONE) { u16 fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period; @@ -110,7 +110,7 @@ static void ar6000_wow_resume(AR_SOFTC_T *ar) ar->arWlanPowerState = WLAN_POWER_STATE_ON; } -static void ar6000_wow_suspend(AR_SOFTC_T *ar) +static void ar6000_wow_suspend(struct ar6_softc *ar) { #define WOW_LIST_ID 1 if (ar->arNetworkType != AP_NETWORK) { @@ -214,7 +214,7 @@ static void ar6000_wow_suspend(AR_SOFTC_T *ar) int ar6000_suspend_ev(void *context) { int status = 0; - AR_SOFTC_T *ar = (AR_SOFTC_T *)context; + struct ar6_softc *ar = (struct ar6_softc *)context; s16 pmmode = ar->arSuspendConfig; wow_not_connected: switch (pmmode) { @@ -250,7 +250,7 @@ wow_not_connected: int ar6000_resume_ev(void *context) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)context; + struct ar6_softc *ar = (struct ar6_softc *)context; u16 powerState = ar->arWlanPowerState; AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: enter previous state %d wowState %d\n", __func__, powerState, ar->arWowState)); @@ -273,7 +273,7 @@ int ar6000_resume_ev(void *context) return 0; } -void ar6000_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, bool isEvent) +void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent) { if (ar->arWowState!=WLAN_WOW_STATE_NONE) { if (ar->arWowState==WLAN_WOW_STATE_SUSPENDING) { @@ -292,7 +292,7 @@ void ar6000_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, bool isEvent) int ar6000_power_change_ev(void *context, u32 config) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)context; + struct ar6_softc *ar = (struct ar6_softc *)context; int status = 0; AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: power change event callback %d \n", __func__, config)); diff --git a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c index 7b6339c41e95..ae7c1dd96d83 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c @@ -28,7 +28,7 @@ static void ar6000_htc_raw_read_cb(void *Context, struct htc_packet *pPacket) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; + struct ar6_softc *ar = (struct ar6_softc *)Context; raw_htc_buffer *busy; HTC_RAW_STREAM_ID streamID; AR_RAW_HTC_T *arRaw = ar->arRawHtc; @@ -72,7 +72,7 @@ ar6000_htc_raw_read_cb(void *Context, struct htc_packet *pPacket) static void ar6000_htc_raw_write_cb(void *Context, struct htc_packet *pPacket) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)Context; + struct ar6_softc *ar = (struct ar6_softc *)Context; raw_htc_buffer *free; HTC_RAW_STREAM_ID streamID; AR_RAW_HTC_T *arRaw = ar->arRawHtc; @@ -111,7 +111,7 @@ ar6000_htc_raw_write_cb(void *Context, struct htc_packet *pPacket) } /* connect to a service */ -static int ar6000_connect_raw_service(AR_SOFTC_T *ar, +static int ar6000_connect_raw_service(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID) { int status; @@ -166,7 +166,7 @@ static int ar6000_connect_raw_service(AR_SOFTC_T *ar, return status; } -int ar6000_htc_raw_open(AR_SOFTC_T *ar) +int ar6000_htc_raw_open(struct ar6_softc *ar) { int status; int streamID, endPt, count2; @@ -272,7 +272,7 @@ int ar6000_htc_raw_open(AR_SOFTC_T *ar) return 0; } -int ar6000_htc_raw_close(AR_SOFTC_T *ar) +int ar6000_htc_raw_close(struct ar6_softc *ar) { A_PRINTF("ar6000_htc_raw_close called \n"); HTCStop(ar->arHtcTarget); @@ -286,7 +286,7 @@ int ar6000_htc_raw_close(AR_SOFTC_T *ar) } raw_htc_buffer * -get_filled_buffer(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID) +get_filled_buffer(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID) { int count; raw_htc_buffer *busy; @@ -308,7 +308,7 @@ get_filled_buffer(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID) return busy; } -ssize_t ar6000_htc_raw_read(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID, +ssize_t ar6000_htc_raw_read(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID, char __user *buffer, size_t length) { int readPtr; @@ -368,7 +368,7 @@ ssize_t ar6000_htc_raw_read(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID, } static raw_htc_buffer * -get_free_buffer(AR_SOFTC_T *ar, HTC_ENDPOINT_ID StreamID) +get_free_buffer(struct ar6_softc *ar, HTC_ENDPOINT_ID StreamID) { int count; raw_htc_buffer *free; @@ -390,7 +390,7 @@ get_free_buffer(AR_SOFTC_T *ar, HTC_ENDPOINT_ID StreamID) return free; } -ssize_t ar6000_htc_raw_write(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID, +ssize_t ar6000_htc_raw_write(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID, char __user *buffer, size_t length) { int writePtr; diff --git a/drivers/staging/ath6kl/os/linux/ar6k_pal.c b/drivers/staging/ath6kl/os/linux/ar6k_pal.c index 08f3710b2103..1f7179acfd70 100644 --- a/drivers/staging/ath6kl/os/linux/ar6k_pal.c +++ b/drivers/staging/ath6kl/os/linux/ar6k_pal.c @@ -49,7 +49,7 @@ typedef struct ar6k_hci_pal_info_s{ #define HCI_NORMAL_MODE (1) #define HCI_REGISTERED (1<<1) struct hci_dev *hdev; /* BT Stack HCI dev */ - AR_SOFTC_T *ar; + struct ar6_softc *ar; }ar6k_hci_pal_info_t; @@ -122,7 +122,7 @@ static int btpal_send_frame(struct sk_buff *skb) ar6k_hci_pal_info_t *pHciPalInfo; int status = 0; struct sk_buff *txSkb = NULL; - AR_SOFTC_T *ar; + struct ar6_softc *ar; if (!hdev) { PRIN_LOG("HCI PAL: btpal_send_frame - no device\n"); @@ -313,7 +313,7 @@ static int bt_setup_hci_pal(ar6k_hci_pal_info_t *pHciPalInfo) *********************************************/ void ar6k_cleanup_hci_pal(void *ar_p) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar_p; + struct ar6_softc *ar = (struct ar6_softc *)ar_p; ar6k_hci_pal_info_t *pHciPalInfo = (ar6k_hci_pal_info_t *)ar->hcipal_info; if (pHciPalInfo != NULL) { @@ -405,7 +405,7 @@ int ar6k_setup_hci_pal(void *ar_p) int status = 0; ar6k_hci_pal_info_t *pHciPalInfo; ar6k_pal_config_t ar6k_pal_config; - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar_p; + struct ar6_softc *ar = (struct ar6_softc *)ar_p; do { diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index 2edac0723af4..bcca39418f90 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -136,7 +136,7 @@ ieee80211_supported_band ar6k_band_5ghz = { }; static int -ar6k_set_wpa_version(AR_SOFTC_T *ar, enum nl80211_wpa_versions wpa_version) +ar6k_set_wpa_version(struct ar6_softc *ar, enum nl80211_wpa_versions wpa_version) { AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: %u\n", __func__, wpa_version)); @@ -157,7 +157,7 @@ ar6k_set_wpa_version(AR_SOFTC_T *ar, enum nl80211_wpa_versions wpa_version) } static int -ar6k_set_auth_type(AR_SOFTC_T *ar, enum nl80211_auth_type auth_type) +ar6k_set_auth_type(struct ar6_softc *ar, enum nl80211_auth_type auth_type) { AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, auth_type)); @@ -183,7 +183,7 @@ ar6k_set_auth_type(AR_SOFTC_T *ar, enum nl80211_auth_type auth_type) } static int -ar6k_set_cipher(AR_SOFTC_T *ar, u32 cipher, bool ucast) +ar6k_set_cipher(struct ar6_softc *ar, u32 cipher, bool ucast) { u8 *ar_cipher = ucast ? &ar->arPairwiseCrypto : &ar->arGroupCrypto; @@ -225,7 +225,7 @@ ar6k_set_cipher(AR_SOFTC_T *ar, u32 cipher, bool ucast) } static void -ar6k_set_key_mgmt(AR_SOFTC_T *ar, u32 key_mgmt) +ar6k_set_key_mgmt(struct ar6_softc *ar, u32 key_mgmt) { AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, key_mgmt)); @@ -244,7 +244,7 @@ static int ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) { - AR_SOFTC_T *ar = ar6k_priv(dev); + struct ar6_softc *ar = ar6k_priv(dev); int status; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); @@ -429,7 +429,7 @@ ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, } void -ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, u16 channel, +ar6k_cfg80211_connect_event(struct ar6_softc *ar, u16 channel, u8 *bssid, u16 listenInterval, u16 beaconInterval,NETWORK_TYPE networkType, u8 beaconIeLen, u8 assocReqLen, @@ -581,7 +581,7 @@ static int ar6k_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason_code)); @@ -620,7 +620,7 @@ ar6k_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, } void -ar6k_cfg80211_disconnect_event(AR_SOFTC_T *ar, u8 reason, +ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason, u8 *bssid, u8 assocRespLen, u8 *assocInfo, u16 protocolReasonStatus) { @@ -736,7 +736,7 @@ static int ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_scan_request *request) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev); int ret = 0; u32 forceFgScan = 0; @@ -792,7 +792,7 @@ ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, } void -ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, int status) +ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status) { AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status)); @@ -823,7 +823,7 @@ ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev); struct ar_key *key = NULL; u8 key_usage; u8 key_type; @@ -915,7 +915,7 @@ static int ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev); AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index)); @@ -952,7 +952,7 @@ ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, void *cookie, void (*callback)(void *cookie, struct key_params*)) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev); struct ar_key *key = NULL; struct key_params params; @@ -992,7 +992,7 @@ static int ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool unicast, bool multicast) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev); struct ar_key *key = NULL; int status = 0; u8 key_usage; @@ -1044,7 +1044,7 @@ static int ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev); AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index)); @@ -1063,7 +1063,7 @@ ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev, } void -ar6k_cfg80211_tkip_micerr_event(AR_SOFTC_T *ar, u8 keyid, bool ismcast) +ar6k_cfg80211_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast) { AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast)); @@ -1076,7 +1076,7 @@ ar6k_cfg80211_tkip_micerr_event(AR_SOFTC_T *ar, u8 keyid, bool ismcast) static int ar6k_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)wiphy_priv(wiphy); + struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy); AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: changed 0x%x\n", __func__, changed)); @@ -1113,7 +1113,7 @@ ar6k_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, static int ar6k_cfg80211_set_txpower(struct wiphy *wiphy, enum nl80211_tx_power_setting type, int dbm) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)wiphy_priv(wiphy); + struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy); u8 ar_dbm; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x, dbm %d\n", __func__, type, dbm)); @@ -1149,7 +1149,7 @@ ar6k_cfg80211_set_txpower(struct wiphy *wiphy, enum nl80211_tx_power_setting typ static int ar6k_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)wiphy_priv(wiphy); + struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy); AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); @@ -1188,7 +1188,7 @@ ar6k_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool pmgmt, int timeout) { - AR_SOFTC_T *ar = ar6k_priv(dev); + struct ar6_softc *ar = ar6k_priv(dev); WMI_POWER_MODE_CMD pwrMode; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: pmgmt %d, timeout %d\n", __func__, pmgmt, timeout)); @@ -1250,7 +1250,7 @@ ar6k_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, enum nl80211_iftype type, u32 *flags, struct vif_params *params) { - AR_SOFTC_T *ar = ar6k_priv(ndev); + struct ar6_softc *ar = ar6k_priv(ndev); struct wireless_dev *wdev = ar->wdev; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type %u\n", __func__, type)); @@ -1286,7 +1286,7 @@ static int ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *ibss_param) { - AR_SOFTC_T *ar = ar6k_priv(dev); + struct ar6_softc *ar = ar6k_priv(dev); int status; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); @@ -1361,7 +1361,7 @@ ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, static int ar6k_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); @@ -1429,7 +1429,7 @@ ar6k_cfg80211_init(struct device *dev) } /* create a new wiphy for use with cfg80211 */ - wdev->wiphy = wiphy_new(&ar6k_cfg80211_ops, sizeof(AR_SOFTC_T)); + wdev->wiphy = wiphy_new(&ar6k_cfg80211_ops, sizeof(struct ar6_softc)); if(!wdev->wiphy) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't allocate wiphy device\n", __func__)); @@ -1463,7 +1463,7 @@ ar6k_cfg80211_init(struct device *dev) } void -ar6k_cfg80211_deinit(AR_SOFTC_T *ar) +ar6k_cfg80211_deinit(struct ar6_softc *ar) { struct wireless_dev *wdev = ar->wdev; diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index 4b7f5a81b652..1ff71e867691 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -85,7 +85,7 @@ struct ar6k_hci_bridge_info { #ifdef EXPORT_HCI_BRIDGE_INTERFACE struct hci_transport_misc_handles HCITransHdl; #else - AR_SOFTC_T *ar; + struct ar6_softc *ar; #endif /* EXPORT_HCI_BRIDGE_INTERFACE */ }; @@ -120,10 +120,10 @@ int ar6000_setup_hci(void *ar); void ar6000_cleanup_hci(void *ar); int hci_test_send(void *ar, struct sk_buff *skb); #else -int ar6000_setup_hci(AR_SOFTC_T *ar); -void ar6000_cleanup_hci(AR_SOFTC_T *ar); +int ar6000_setup_hci(struct ar6_softc *ar); +void ar6000_cleanup_hci(struct ar6_softc *ar); /* HCI bridge testing */ -int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb); +int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb); #endif /* EXPORT_HCI_BRIDGE_INTERFACE */ #define LOCK_BRIDGE(dev) spin_lock_bh(&(dev)->BridgeLock) @@ -466,7 +466,7 @@ static HCI_SEND_FULL_ACTION ar6000_hci_pkt_send_full(void *pContext, struct htc #ifdef EXPORT_HCI_BRIDGE_INTERFACE int ar6000_setup_hci(void *ar) #else -int ar6000_setup_hci(AR_SOFTC_T *ar) +int ar6000_setup_hci(struct ar6_softc *ar) #endif { struct hci_transport_config_info config; @@ -563,7 +563,7 @@ int ar6000_setup_hci(AR_SOFTC_T *ar) #ifdef EXPORT_HCI_BRIDGE_INTERFACE void ar6000_cleanup_hci(void *ar) #else -void ar6000_cleanup_hci(AR_SOFTC_T *ar) +void ar6000_cleanup_hci(struct ar6_softc *ar) #endif { #ifdef EXPORT_HCI_BRIDGE_INTERFACE @@ -598,7 +598,7 @@ void ar6000_cleanup_hci(AR_SOFTC_T *ar) #ifdef EXPORT_HCI_BRIDGE_INTERFACE int hci_test_send(void *ar, struct sk_buff *skb) #else -int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb) +int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb) #endif { int status = 0; @@ -664,7 +664,7 @@ int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb) return status; } -void ar6000_set_default_ar3kconfig(AR_SOFTC_T *ar, void *ar3kconfig) +void ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig) { struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)ar->hcidev_info; struct ar3k_config_info *config = (struct ar3k_config_info *)ar3kconfig; @@ -1080,7 +1080,7 @@ static void bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_b #ifdef EXPORT_HCI_BRIDGE_INTERFACE int ar6000_setup_hci(void *ar) #else -int ar6000_setup_hci(AR_SOFTC_T *ar) +int ar6000_setup_hci(struct ar6_softc *ar) #endif { return 0; @@ -1089,14 +1089,14 @@ int ar6000_setup_hci(AR_SOFTC_T *ar) #ifdef EXPORT_HCI_BRIDGE_INTERFACE void ar6000_cleanup_hci(void *ar) #else -void ar6000_cleanup_hci(AR_SOFTC_T *ar) +void ar6000_cleanup_hci(struct ar6_softc *ar) #endif { return; } #ifndef EXPORT_HCI_BRIDGE_INTERFACE -void ar6000_set_default_ar3kconfig(AR_SOFTC_T *ar, void *ar3kconfig) +void ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig) { return; } @@ -1105,7 +1105,7 @@ void ar6000_set_default_ar3kconfig(AR_SOFTC_T *ar, void *ar3kconfig) #ifdef EXPORT_HCI_BRIDGE_INTERFACE int hci_test_send(void *ar, struct sk_buff *skb) #else -int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb) +int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb) #endif { return -EOPNOTSUPP; diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 8d8a964bac17..9b5c0a3970b6 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -466,7 +466,7 @@ typedef struct ar6_raw_htc { bool read_buffer_available[HTC_RAW_STREAM_NUM_MAX]; } AR_RAW_HTC_T; -typedef struct ar6_softc { +struct ar6_softc { struct net_device *arNetDev; /* net_device pointer */ void *arWmi; int arTxPending[ENDPOINT_MAX]; @@ -622,12 +622,12 @@ typedef struct ar6_softc { #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT void *arApDev; #endif -} AR_SOFTC_T; +}; #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT struct ar_virtual_interface { struct net_device *arNetDev; /* net_device pointer */ - AR_SOFTC_T *arDev; /* ar device pointer */ + struct ar6_softc *arDev; /* ar device pointer */ struct net_device *arStaNetDev; /* net_device pointer */ }; #endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */ @@ -704,11 +704,11 @@ struct ar_giwscan_param { int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); int ar6000_ioctl_dispatcher(struct net_device *dev, struct ifreq *rq, int cmd); void ar6000_gpio_init(void); -void ar6000_init_profile_info(AR_SOFTC_T *ar); -void ar6000_install_static_wep_keys(AR_SOFTC_T *ar); +void ar6000_init_profile_info(struct ar6_softc *ar); +void ar6000_install_static_wep_keys(struct ar6_softc *ar); int ar6000_init(struct net_device *dev); -int ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar); -void ar6000_TxDataCleanup(AR_SOFTC_T *ar); +int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar); +void ar6000_TxDataCleanup(struct ar6_softc *ar); int ar6000_acl_data_tx(struct sk_buff *skb, struct net_device *dev); void ar6000_restart_endpoint(struct net_device *dev); void ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs); @@ -719,12 +719,12 @@ void ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbgl #define __user #endif -int ar6000_htc_raw_open(AR_SOFTC_T *ar); -int ar6000_htc_raw_close(AR_SOFTC_T *ar); -ssize_t ar6000_htc_raw_read(AR_SOFTC_T *ar, +int ar6000_htc_raw_open(struct ar6_softc *ar); +int ar6000_htc_raw_close(struct ar6_softc *ar); +ssize_t ar6000_htc_raw_read(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID, char __user *buffer, size_t count); -ssize_t ar6000_htc_raw_write(AR_SOFTC_T *ar, +ssize_t ar6000_htc_raw_write(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID, char __user *buffer, size_t count); @@ -733,22 +733,22 @@ ssize_t ar6000_htc_raw_write(AR_SOFTC_T *ar, /* AP mode */ /*TODO: These routines should be moved to a file that is common across OS */ sta_t * -ieee80211_find_conn(AR_SOFTC_T *ar, u8 *node_addr); +ieee80211_find_conn(struct ar6_softc *ar, u8 *node_addr); sta_t * -ieee80211_find_conn_for_aid(AR_SOFTC_T *ar, u8 aid); +ieee80211_find_conn_for_aid(struct ar6_softc *ar, u8 aid); -u8 remove_sta(AR_SOFTC_T *ar, u8 *mac, u16 reason); +u8 remove_sta(struct ar6_softc *ar, u8 *mac, u16 reason); /* HCI support */ #ifndef EXPORT_HCI_BRIDGE_INTERFACE -int ar6000_setup_hci(AR_SOFTC_T *ar); -void ar6000_cleanup_hci(AR_SOFTC_T *ar); -void ar6000_set_default_ar3kconfig(AR_SOFTC_T *ar, void *ar3kconfig); +int ar6000_setup_hci(struct ar6_softc *ar); +void ar6000_cleanup_hci(struct ar6_softc *ar); +void ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig); /* HCI bridge testing */ -int hci_test_send(AR_SOFTC_T *ar, struct sk_buff *skb); +int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb); #endif ATH_DEBUG_DECLARE_EXTERN(htc); diff --git a/drivers/staging/ath6kl/os/linux/include/cfg80211.h b/drivers/staging/ath6kl/os/linux/include/cfg80211.h index c2e4fa2ef23b..1a6ae97c6b08 100644 --- a/drivers/staging/ath6kl/os/linux/include/cfg80211.h +++ b/drivers/staging/ath6kl/os/linux/include/cfg80211.h @@ -25,21 +25,21 @@ #define _AR6K_CFG80211_H_ struct wireless_dev *ar6k_cfg80211_init(struct device *dev); -void ar6k_cfg80211_deinit(AR_SOFTC_T *ar); +void ar6k_cfg80211_deinit(struct ar6_softc *ar); -void ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, int status); +void ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status); -void ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, u16 channel, +void ar6k_cfg80211_connect_event(struct ar6_softc *ar, u16 channel, u8 *bssid, u16 listenInterval, u16 beaconInterval,NETWORK_TYPE networkType, u8 beaconIeLen, u8 assocReqLen, u8 assocRespLen, u8 *assocInfo); -void ar6k_cfg80211_disconnect_event(AR_SOFTC_T *ar, u8 reason, +void ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason, u8 *bssid, u8 assocRespLen, u8 *assocInfo, u16 protocolReasonStatus); -void ar6k_cfg80211_tkip_micerr_event(AR_SOFTC_T *ar, u8 keyid, bool ismcast); +void ar6k_cfg80211_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast); #endif /* _AR6K_CFG80211_H_ */ diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index 2c0d4fd3a517..c650faa28bbb 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -39,7 +39,7 @@ extern int loghci; static int ar6000_ioctl_get_roam_tbl(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); if (ar->arWmiReady == false) { return -EIO; @@ -55,7 +55,7 @@ ar6000_ioctl_get_roam_tbl(struct net_device *dev, struct ifreq *rq) static int ar6000_ioctl_get_roam_data(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); if (ar->arWmiReady == false) { return -EIO; @@ -74,7 +74,7 @@ ar6000_ioctl_get_roam_data(struct net_device *dev, struct ifreq *rq) static int ar6000_ioctl_set_roam_ctrl(struct net_device *dev, char *userdata) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_SET_ROAM_CTRL_CMD cmd; u8 size = sizeof(cmd); @@ -107,7 +107,7 @@ ar6000_ioctl_set_roam_ctrl(struct net_device *dev, char *userdata) static int ar6000_ioctl_set_powersave_timers(struct net_device *dev, char *userdata) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_POWERSAVE_TIMERS_POLICY_CMD cmd; u8 size = sizeof(cmd); @@ -133,7 +133,7 @@ ar6000_ioctl_set_powersave_timers(struct net_device *dev, char *userdata) static int ar6000_ioctl_set_qos_supp(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_SET_QOS_SUPP_CMD cmd; int ret; @@ -168,7 +168,7 @@ ar6000_ioctl_set_qos_supp(struct net_device *dev, struct ifreq *rq) static int ar6000_ioctl_set_wmm(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_SET_WMM_CMD cmd; int ret; @@ -209,7 +209,7 @@ ar6000_ioctl_set_wmm(struct net_device *dev, struct ifreq *rq) static int ar6000_ioctl_set_txop(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_SET_WMM_TXOP_CMD cmd; int ret; @@ -244,7 +244,7 @@ ar6000_ioctl_set_txop(struct net_device *dev, struct ifreq *rq) static int ar6000_ioctl_get_rd(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); int ret = 0; if ((dev->flags & IFF_UP) != IFF_UP || ar->arWmiReady == false) { @@ -261,7 +261,7 @@ ar6000_ioctl_get_rd(struct net_device *dev, struct ifreq *rq) static int ar6000_ioctl_set_country(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_AP_SET_COUNTRY_CMD cmd; int ret; @@ -301,7 +301,7 @@ ar6000_ioctl_set_country(struct net_device *dev, struct ifreq *rq) static int ar6000_ioctl_get_power_mode(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_POWER_MODE_CMD power_mode; int ret = 0; @@ -321,7 +321,7 @@ ar6000_ioctl_get_power_mode(struct net_device *dev, struct ifreq *rq) static int ar6000_ioctl_set_channelParams(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_CHANNEL_PARAMS_CMD cmd, *cmdp; int ret = 0; @@ -382,7 +382,7 @@ static int ar6000_ioctl_set_snr_threshold(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_SNR_THRESHOLD_PARAMS_CMD cmd; int ret = 0; @@ -414,7 +414,7 @@ ar6000_ioctl_set_rssi_threshold(struct net_device *dev, struct ifreq *rq) thold2.rssi = tmpThold.rssi; \ } while (0) - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_RSSI_THRESHOLD_PARAMS_CMD cmd; USER_RSSI_PARAMS rssiParams; s32 i, j; @@ -491,7 +491,7 @@ static int ar6000_ioctl_set_lq_threshold(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_LQ_THRESHOLD_PARAMS_CMD cmd; int ret = 0; @@ -514,7 +514,7 @@ ar6000_ioctl_set_lq_threshold(struct net_device *dev, struct ifreq *rq) static int ar6000_ioctl_set_probedSsid(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_PROBED_SSID_CMD cmd; int ret = 0; @@ -538,7 +538,7 @@ ar6000_ioctl_set_probedSsid(struct net_device *dev, struct ifreq *rq) static int ar6000_ioctl_set_badAp(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_ADD_BAD_AP_CMD cmd; int ret = 0; @@ -574,7 +574,7 @@ ar6000_ioctl_set_badAp(struct net_device *dev, struct ifreq *rq) static int ar6000_ioctl_create_qos(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_CREATE_PSTREAM_CMD cmd; int ret; @@ -607,7 +607,7 @@ ar6000_ioctl_create_qos(struct net_device *dev, struct ifreq *rq) static int ar6000_ioctl_delete_qos(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_DELETE_PSTREAM_CMD cmd; int ret = 0; @@ -637,7 +637,7 @@ ar6000_ioctl_delete_qos(struct net_device *dev, struct ifreq *rq) static int ar6000_ioctl_get_qos_queue(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); struct ar6000_queuereq qreq; int ret = 0; @@ -665,7 +665,7 @@ static int ar6000_ioctl_tcmd_get_rx_report(struct net_device *dev, struct ifreq *rq, u8 *data, u32 len) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); u32 buf[4+TCMD_MAX_RATES]; int ret = 0; @@ -717,7 +717,7 @@ ar6000_ioctl_tcmd_get_rx_report(struct net_device *dev, void ar6000_tcmd_rx_report_event(void *devt, u8 *results, int len) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; + struct ar6_softc *ar = (struct ar6_softc *)devt; TCMD_CONT_RX * rx_rep = (TCMD_CONT_RX *)results; if (enablerssicompensation) { @@ -742,7 +742,7 @@ ar6000_tcmd_rx_report_event(void *devt, u8 *results, int len) static int ar6000_ioctl_set_error_report_bitmask(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_TARGET_ERROR_REPORT_BITMASK cmd; int ret = 0; @@ -762,7 +762,7 @@ ar6000_ioctl_set_error_report_bitmask(struct net_device *dev, struct ifreq *rq) static int ar6000_clear_target_stats(struct net_device *dev) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); TARGET_STATS *pStats = &ar->arTargetStats; int ret = 0; @@ -778,7 +778,7 @@ ar6000_clear_target_stats(struct net_device *dev) static int ar6000_ioctl_get_target_stats(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); TARGET_STATS_CMD cmd; TARGET_STATS *pStats = &ar->arTargetStats; int ret = 0; @@ -829,7 +829,7 @@ ar6000_ioctl_get_target_stats(struct net_device *dev, struct ifreq *rq) static int ar6000_ioctl_get_ap_stats(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); u32 action; /* Allocating only the desired space on the frame. Declaring is as a WMI_AP_MODE_STAT variable results in exceeding the compiler imposed limit on the maximum frame size */ WMI_AP_MODE_STAT *pStats = &ar->arAPStats; int ret = 0; @@ -888,7 +888,7 @@ ar6000_ioctl_get_ap_stats(struct net_device *dev, struct ifreq *rq) static int ar6000_ioctl_set_access_params(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_SET_ACCESS_PARAMS_CMD cmd; int ret = 0; @@ -914,7 +914,7 @@ ar6000_ioctl_set_access_params(struct net_device *dev, struct ifreq *rq) static int ar6000_ioctl_set_disconnect_timeout(struct net_device *dev, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_DISC_TIMEOUT_CMD cmd; int ret = 0; @@ -939,7 +939,7 @@ ar6000_ioctl_set_disconnect_timeout(struct net_device *dev, struct ifreq *rq) static int ar6000_xioctl_set_voice_pkt_size(struct net_device *dev, char *userdata) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_SET_VOICE_PKT_SIZE_CMD cmd; int ret = 0; @@ -965,7 +965,7 @@ ar6000_xioctl_set_voice_pkt_size(struct net_device *dev, char *userdata) static int ar6000_xioctl_set_max_sp_len(struct net_device *dev, char *userdata) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_SET_MAX_SP_LEN_CMD cmd; int ret = 0; @@ -991,7 +991,7 @@ ar6000_xioctl_set_max_sp_len(struct net_device *dev, char *userdata) static int ar6000_xioctl_set_bt_status_cmd(struct net_device *dev, char *userdata) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_SET_BT_STATUS_CMD cmd; int ret = 0; @@ -1016,7 +1016,7 @@ ar6000_xioctl_set_bt_status_cmd(struct net_device *dev, char *userdata) static int ar6000_xioctl_set_bt_params_cmd(struct net_device *dev, char *userdata) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_SET_BT_PARAMS_CMD cmd; int ret = 0; @@ -1041,7 +1041,7 @@ ar6000_xioctl_set_bt_params_cmd(struct net_device *dev, char *userdata) static int ar6000_xioctl_set_btcoex_fe_ant_cmd(struct net_device * dev, char *userdata) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_SET_BTCOEX_FE_ANT_CMD cmd; int ret = 0; @@ -1065,7 +1065,7 @@ ar6000_xioctl_set_btcoex_fe_ant_cmd(struct net_device * dev, char *userdata) static int ar6000_xioctl_set_btcoex_colocated_bt_dev_cmd(struct net_device * dev, char *userdata) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD cmd; int ret = 0; @@ -1090,7 +1090,7 @@ ar6000_xioctl_set_btcoex_colocated_bt_dev_cmd(struct net_device * dev, char *use static int ar6000_xioctl_set_btcoex_btinquiry_page_config_cmd(struct net_device * dev, char *userdata) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD cmd; int ret = 0; @@ -1115,7 +1115,7 @@ ar6000_xioctl_set_btcoex_btinquiry_page_config_cmd(struct net_device * dev, cha static int ar6000_xioctl_set_btcoex_sco_config_cmd(struct net_device * dev, char *userdata) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_SET_BTCOEX_SCO_CONFIG_CMD cmd; int ret = 0; @@ -1141,7 +1141,7 @@ static int ar6000_xioctl_set_btcoex_a2dp_config_cmd(struct net_device * dev, char *userdata) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_SET_BTCOEX_A2DP_CONFIG_CMD cmd; int ret = 0; @@ -1166,7 +1166,7 @@ ar6000_xioctl_set_btcoex_a2dp_config_cmd(struct net_device * dev, static int ar6000_xioctl_set_btcoex_aclcoex_config_cmd(struct net_device * dev, char *userdata) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD cmd; int ret = 0; @@ -1191,7 +1191,7 @@ ar6000_xioctl_set_btcoex_aclcoex_config_cmd(struct net_device * dev, char *userd static int ar60000_xioctl_set_btcoex_debug_cmd(struct net_device * dev, char *userdata) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_SET_BTCOEX_DEBUG_CMD cmd; int ret = 0; @@ -1216,7 +1216,7 @@ ar60000_xioctl_set_btcoex_debug_cmd(struct net_device * dev, char *userdata) static int ar6000_xioctl_set_btcoex_bt_operating_status_cmd(struct net_device * dev, char *userdata) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD cmd; int ret = 0; @@ -1242,7 +1242,7 @@ ar6000_xioctl_get_btcoex_config_cmd(struct net_device * dev, char *userdata, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); AR6000_BTCOEX_CONFIG btcoexConfig; WMI_BTCOEX_CONFIG_EVENT *pbtcoexConfigEv = &ar->arBtcoexConfig; @@ -1285,7 +1285,7 @@ ar6000_xioctl_get_btcoex_config_cmd(struct net_device * dev, char *userdata, static int ar6000_xioctl_get_btcoex_stats_cmd(struct net_device * dev, char *userdata, struct ifreq *rq) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); AR6000_BTCOEX_STATS btcoexStats; WMI_BTCOEX_STATS_EVENT *pbtcoexStats = &ar->arBtcoexStats; int ret = 0; @@ -1332,7 +1332,7 @@ ar6000_xioctl_get_btcoex_stats_cmd(struct net_device * dev, char *userdata, stru static int ar6000_xioctl_set_excess_tx_retry_thres_cmd(struct net_device * dev, char * userdata) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_SET_EXCESS_TX_RETRY_THRES_CMD cmd; int ret = 0; @@ -1414,7 +1414,7 @@ ar6000_gpio_output_set(struct net_device *dev, u32 enable_mask, u32 disable_mask) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); gpio_ack_received = false; return wmi_gpio_output_set(ar->arWmi, @@ -1424,7 +1424,7 @@ ar6000_gpio_output_set(struct net_device *dev, static int ar6000_gpio_input_get(struct net_device *dev) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); *((volatile bool *)&gpio_data_available) = false; return wmi_gpio_input_get(ar->arWmi); @@ -1435,7 +1435,7 @@ ar6000_gpio_register_set(struct net_device *dev, u32 gpioreg_id, u32 value) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); gpio_ack_received = false; return wmi_gpio_register_set(ar->arWmi, gpioreg_id, value); @@ -1445,7 +1445,7 @@ static int ar6000_gpio_register_get(struct net_device *dev, u32 gpioreg_id) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); *((volatile bool *)&gpio_data_available) = false; return wmi_gpio_register_get(ar->arWmi, gpioreg_id); @@ -1455,7 +1455,7 @@ static int ar6000_gpio_intr_ack(struct net_device *dev, u32 ack_mask) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); gpio_intr_available = false; return wmi_gpio_intr_ack(ar->arWmi, ack_mask); @@ -1469,7 +1469,7 @@ static bool prof_count_available; /* Requested GPIO data available */ static int prof_count_get(struct net_device *dev) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); *((volatile bool *)&prof_count_available) = false; return wmi_prof_count_get_cmd(ar->arWmi); @@ -1541,7 +1541,7 @@ ar6000_create_acl_data_osbuf(struct net_device *dev, u8 *userdata, void **p_osbu int -ar6000_ioctl_ap_setparam(AR_SOFTC_T *ar, int param, int value) +ar6000_ioctl_ap_setparam(struct ar6_softc *ar, int param, int value) { int ret=0; @@ -1621,7 +1621,7 @@ ar6000_ioctl_ap_setparam(AR_SOFTC_T *ar, int param, int value) } int -ar6000_ioctl_setparam(AR_SOFTC_T *ar, int param, int value) +ar6000_ioctl_setparam(struct ar6_softc *ar, int param, int value) { bool profChanged = false; int ret=0; @@ -1757,7 +1757,7 @@ ar6000_ioctl_setparam(AR_SOFTC_T *ar, int param, int value) } int -ar6000_ioctl_setkey(AR_SOFTC_T *ar, struct ieee80211req_key *ik) +ar6000_ioctl_setkey(struct ar6_softc *ar, struct ieee80211req_key *ik) { KEY_USAGE keyUsage; int status; @@ -1864,7 +1864,7 @@ ar6000_ioctl_setkey(AR_SOFTC_T *ar, struct ieee80211req_key *ik) int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); HIF_DEVICE *hifDevice = ar->arHifDevice; int ret = 0, param; unsigned int address = 0; @@ -3141,7 +3141,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_SET_OPT_MODE: { WMI_SET_OPT_MODE_CMD optModeCmd; - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); if (ar->arWmiReady == false) { ret = -EIO; @@ -3242,7 +3242,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } case IEEE80211_IOCTL_SETAUTHALG: { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); struct ieee80211req_authalg req; if (ar->arWmiReady == false) { @@ -3417,7 +3417,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case AR6000_XIOCTL_WMI_GETFIXRATES: { WMI_FIX_RATES_CMD getFixRatesCmd; - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); int ret = 0; if (ar->bIsDestroyProgress) { @@ -3627,7 +3627,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } case AR6000_XIOCTL_WMI_GET_KEEPALIVE: { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_GET_KEEPALIVE_CMD getKeepAlive; int ret = 0; if (ar->bIsDestroyProgress) { diff --git a/drivers/staging/ath6kl/os/linux/wireless_ext.c b/drivers/staging/ath6kl/os/linux/wireless_ext.c index 824f1be9883f..4b779434956f 100644 --- a/drivers/staging/ath6kl/os/linux/wireless_ext.c +++ b/drivers/staging/ath6kl/os/linux/wireless_ext.c @@ -416,7 +416,7 @@ ar6000_ioctl_giwscan(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); struct ar_giwscan_param param; if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { @@ -461,7 +461,7 @@ ar6000_ioctl_siwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *ssid) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); int status; u8 arNetworkType; u8 prevMode = ar->arNetworkType; @@ -658,7 +658,7 @@ ar6000_ioctl_giwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *essid) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); @@ -681,7 +681,7 @@ ar6000_ioctl_giwessid(struct net_device *dev, } -void ar6000_install_static_wep_keys(AR_SOFTC_T *ar) +void ar6000_install_static_wep_keys(struct ar6_softc *ar) { u8 index; u8 keyUsage; @@ -712,7 +712,7 @@ ar6000_ioctl_siwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); u32 kbps; s8 rate_idx; @@ -749,7 +749,7 @@ ar6000_ioctl_giwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); int ret = 0; if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { @@ -812,7 +812,7 @@ ar6000_ioctl_siwtxpow(struct net_device *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); u8 dbM; if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { @@ -854,7 +854,7 @@ ar6000_ioctl_giwtxpow(struct net_device *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); int ret = 0; if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { @@ -924,7 +924,7 @@ ar6000_ioctl_siwretry(struct net_device *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); @@ -965,7 +965,7 @@ ar6000_ioctl_giwretry(struct net_device *dev, struct iw_request_info *info, struct iw_param *rrq, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); @@ -1006,7 +1006,7 @@ ar6000_ioctl_siwencode(struct net_device *dev, struct iw_request_info *info, struct iw_point *erq, char *keybuf) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); int index; s32 auth = 0; @@ -1122,7 +1122,7 @@ ar6000_ioctl_giwencode(struct net_device *dev, struct iw_request_info *info, struct iw_point *erq, char *key) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); u8 keyIndex; struct ar_wep_key *wk; @@ -1192,7 +1192,7 @@ ar6000_ioctl_siwgenie(struct net_device *dev, struct iw_request_info *info, struct iw_point *erq, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); #ifdef WAPI_ENABLE u8 *ie = erq->pointer; @@ -1228,7 +1228,7 @@ ar6000_ioctl_giwgenie(struct net_device *dev, struct iw_request_info *info, struct iw_point *erq, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); if (ar->arWmiReady == false) { return -EIO; @@ -1247,7 +1247,7 @@ ar6000_ioctl_siwauth(struct net_device *dev, struct iw_request_info *info, struct iw_param *data, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); bool profChanged; u16 param; @@ -1418,7 +1418,7 @@ ar6000_ioctl_giwauth(struct net_device *dev, struct iw_request_info *info, struct iw_param *data, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); u16 param; s32 ret; @@ -1546,7 +1546,7 @@ ar6000_ioctl_siwpmksa(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); s32 ret; int status; struct iw_pmksa *pmksa; @@ -1591,7 +1591,7 @@ static int ar6000_set_wapi_key(struct net_device *dev, struct iw_request_info *info, struct iw_point *erq, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; KEY_USAGE keyUsage = 0; s32 keyLen; @@ -1653,7 +1653,7 @@ ar6000_ioctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, struct iw_point *erq, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); s32 index; struct iw_encode_ext *ext; KEY_USAGE keyUsage; @@ -1827,7 +1827,7 @@ ar6000_ioctl_giwencodeext(struct net_device *dev, struct iw_request_info *info, struct iw_point *erq, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); if (ar->arWlanState == WLAN_DISABLED) { return -EIO; @@ -1850,7 +1850,7 @@ static int ar6000_ioctl_siwpower(struct net_device *dev, union iwreq_data *wrqu, char *extra) { #ifndef ATH6K_CONFIG_OTA_MODE - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_POWER_MODE power_mode; if (ar->arWmiReady == false) { @@ -1876,7 +1876,7 @@ static int ar6000_ioctl_giwpower(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); WMI_POWER_MODE power_mode; if (ar->arWmiReady == false) { @@ -1907,7 +1907,7 @@ ar6000_ioctl_giwname(struct net_device *dev, char *name, char *extra) { u8 capability; - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); @@ -1961,7 +1961,7 @@ ar6000_ioctl_siwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *freq, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); @@ -2006,7 +2006,7 @@ ar6000_ioctl_giwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *freq, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); @@ -2046,7 +2046,7 @@ ar6000_ioctl_siwmode(struct net_device *dev, struct iw_request_info *info, __u32 *mode, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); @@ -2117,7 +2117,7 @@ ar6000_ioctl_giwmode(struct net_device *dev, struct iw_request_info *info, __u32 *mode, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); @@ -2177,7 +2177,7 @@ ar6000_ioctl_giwrange(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); struct iw_range *range = (struct iw_range *) extra; int i, ret = 0; @@ -2300,7 +2300,7 @@ ar6000_ioctl_siwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *ap_addr, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); @@ -2332,7 +2332,7 @@ ar6000_ioctl_giwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *ap_addr, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); @@ -2368,7 +2368,7 @@ ar6000_ioctl_siwmlme(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); @@ -2460,7 +2460,7 @@ ar6000_ioctl_siwscan(struct net_device *dev, #define ACT_DWELLTIME_DEFAULT 105 #define HOME_TXDRAIN_TIME 100 #define SCAN_INT HOME_TXDRAIN_TIME + ACT_DWELLTIME_DEFAULT - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); int ret = 0; if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { @@ -2588,7 +2588,7 @@ ar6000_ioctl_siwcommit(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra) { - AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); + struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) { A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd); -- cgit v1.2.3 From 9dabb7224ffcbdcb493f82859a0f19dd9a55e693 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 14 Mar 2011 10:59:12 -0700 Subject: ath6kl: remove-typedef HIF_DEVICE remove-typedef -s HIF_DEVICE \ "struct hif_device" drivers/staging/ath6kl/ Tested-by: Naveen Singh Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/bmi/include/bmi_internal.h | 4 +- drivers/staging/ath6kl/bmi/src/bmi.c | 40 +++++------ .../hif/sdio/linux_sdio/include/hif_internal.h | 18 ++--- .../staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 84 +++++++++++----------- .../ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c | 12 ++-- drivers/staging/ath6kl/htc2/AR6000/ar6k.c | 10 +-- .../ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c | 2 +- drivers/staging/ath6kl/include/ar3kconfig.h | 2 +- drivers/staging/ath6kl/include/ar6000_diag.h | 12 ++-- drivers/staging/ath6kl/include/bmi.h | 34 ++++----- drivers/staging/ath6kl/include/common_drv.h | 18 ++--- drivers/staging/ath6kl/include/hif.h | 34 ++++----- drivers/staging/ath6kl/miscdrv/common_drv.c | 38 +++++----- drivers/staging/ath6kl/os/linux/eeprom.c | 6 +- .../staging/ath6kl/os/linux/export_hci_transport.c | 6 +- drivers/staging/ath6kl/os/linux/hci_bridge.c | 4 +- .../staging/ath6kl/os/linux/include/ar6000_drv.h | 4 +- .../ath6kl/os/linux/include/export_hci_transport.h | 6 +- drivers/staging/ath6kl/os/linux/ioctl.c | 2 +- 19 files changed, 168 insertions(+), 168 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ath6kl/bmi/include/bmi_internal.h b/drivers/staging/ath6kl/bmi/include/bmi_internal.h index e13fb01ec9ed..6ae2ea7233d8 100644 --- a/drivers/staging/ath6kl/bmi/include/bmi_internal.h +++ b/drivers/staging/ath6kl/bmi/include/bmi_internal.h @@ -42,12 +42,12 @@ static bool bmiDone; int -bmiBufferSend(HIF_DEVICE *device, +bmiBufferSend(struct hif_device *device, u8 *buffer, u32 length); int -bmiBufferReceive(HIF_DEVICE *device, +bmiBufferReceive(struct hif_device *device, u8 *buffer, u32 length, bool want_timeout); diff --git a/drivers/staging/ath6kl/bmi/src/bmi.c b/drivers/staging/ath6kl/bmi/src/bmi.c index 34d1befa0bc4..9268bf3eabd9 100644 --- a/drivers/staging/ath6kl/bmi/src/bmi.c +++ b/drivers/staging/ath6kl/bmi/src/bmi.c @@ -106,7 +106,7 @@ BMICleanup(void) } int -BMIDone(HIF_DEVICE *device) +BMIDone(struct hif_device *device) { int status; u32 cid; @@ -142,7 +142,7 @@ BMIDone(HIF_DEVICE *device) } int -BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) +BMIGetTargetInfo(struct hif_device *device, struct bmi_target_info *targ_info) { int status; u32 cid; @@ -201,7 +201,7 @@ BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info) } int -BMIReadMemory(HIF_DEVICE *device, +BMIReadMemory(struct hif_device *device, u32 address, u8 *buffer, u32 length) @@ -257,7 +257,7 @@ BMIReadMemory(HIF_DEVICE *device, } int -BMIWriteMemory(HIF_DEVICE *device, +BMIWriteMemory(struct hif_device *device, u32 address, u8 *buffer, u32 length) @@ -322,7 +322,7 @@ BMIWriteMemory(HIF_DEVICE *device, } int -BMIExecute(HIF_DEVICE *device, +BMIExecute(struct hif_device *device, u32 address, u32 *param) { @@ -370,7 +370,7 @@ BMIExecute(HIF_DEVICE *device, } int -BMISetAppStart(HIF_DEVICE *device, +BMISetAppStart(struct hif_device *device, u32 address) { u32 cid; @@ -407,7 +407,7 @@ BMISetAppStart(HIF_DEVICE *device, } int -BMIReadSOCRegister(HIF_DEVICE *device, +BMIReadSOCRegister(struct hif_device *device, u32 address, u32 *param) { @@ -453,7 +453,7 @@ BMIReadSOCRegister(HIF_DEVICE *device, } int -BMIWriteSOCRegister(HIF_DEVICE *device, +BMIWriteSOCRegister(struct hif_device *device, u32 address, u32 param) { @@ -493,7 +493,7 @@ BMIWriteSOCRegister(HIF_DEVICE *device, } int -BMIrompatchInstall(HIF_DEVICE *device, +BMIrompatchInstall(struct hif_device *device, u32 ROM_addr, u32 RAM_addr, u32 nbytes, @@ -549,7 +549,7 @@ BMIrompatchInstall(HIF_DEVICE *device, } int -BMIrompatchUninstall(HIF_DEVICE *device, +BMIrompatchUninstall(struct hif_device *device, u32 rompatch_id) { u32 cid; @@ -586,7 +586,7 @@ BMIrompatchUninstall(HIF_DEVICE *device, } static int -_BMIrompatchChangeActivation(HIF_DEVICE *device, +_BMIrompatchChangeActivation(struct hif_device *device, u32 rompatch_count, u32 *rompatch_list, u32 do_activate) @@ -630,7 +630,7 @@ _BMIrompatchChangeActivation(HIF_DEVICE *device, } int -BMIrompatchActivate(HIF_DEVICE *device, +BMIrompatchActivate(struct hif_device *device, u32 rompatch_count, u32 *rompatch_list) { @@ -638,7 +638,7 @@ BMIrompatchActivate(HIF_DEVICE *device, } int -BMIrompatchDeactivate(HIF_DEVICE *device, +BMIrompatchDeactivate(struct hif_device *device, u32 rompatch_count, u32 *rompatch_list) { @@ -646,7 +646,7 @@ BMIrompatchDeactivate(HIF_DEVICE *device, } int -BMILZData(HIF_DEVICE *device, +BMILZData(struct hif_device *device, u8 *buffer, u32 length) { @@ -696,7 +696,7 @@ BMILZData(HIF_DEVICE *device, } int -BMILZStreamStart(HIF_DEVICE *device, +BMILZStreamStart(struct hif_device *device, u32 address) { u32 cid; @@ -734,7 +734,7 @@ BMILZStreamStart(HIF_DEVICE *device, /* BMI Access routines */ int -bmiBufferSend(HIF_DEVICE *device, +bmiBufferSend(struct hif_device *device, u8 *buffer, u32 length) { @@ -782,7 +782,7 @@ bmiBufferSend(HIF_DEVICE *device, } int -bmiBufferReceive(HIF_DEVICE *device, +bmiBufferReceive(struct hif_device *device, u8 *buffer, u32 length, bool want_timeout) @@ -958,7 +958,7 @@ bmiBufferReceive(HIF_DEVICE *device, } int -BMIFastDownload(HIF_DEVICE *device, u32 address, u8 *buffer, u32 length) +BMIFastDownload(struct hif_device *device, u32 address, u8 *buffer, u32 length) { int status = A_ERROR; u32 lastWord = 0; @@ -998,13 +998,13 @@ BMIFastDownload(HIF_DEVICE *device, u32 address, u8 *buffer, u32 length) } int -BMIRawWrite(HIF_DEVICE *device, u8 *buffer, u32 length) +BMIRawWrite(struct hif_device *device, u8 *buffer, u32 length) { return bmiBufferSend(device, buffer, length); } int -BMIRawRead(HIF_DEVICE *device, u8 *buffer, u32 length, bool want_timeout) +BMIRawRead(struct hif_device *device, u8 *buffer, u32 length, bool want_timeout) { return bmiBufferReceive(device, buffer, length, want_timeout); } diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h index 04fc284f4a60..6341560b2108 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h @@ -88,9 +88,9 @@ struct hif_device { #define CMD53_FIXED_ADDRESS 1 #define CMD53_INCR_ADDRESS 2 -BUS_REQUEST *hifAllocateBusRequest(HIF_DEVICE *device); -void hifFreeBusRequest(HIF_DEVICE *device, BUS_REQUEST *busrequest); -void AddToAsyncList(HIF_DEVICE *device, BUS_REQUEST *busrequest); +BUS_REQUEST *hifAllocateBusRequest(struct hif_device *device); +void hifFreeBusRequest(struct hif_device *device, BUS_REQUEST *busrequest); +void AddToAsyncList(struct hif_device *device, BUS_REQUEST *busrequest); #ifdef HIF_LINUX_MMC_SCATTER_SUPPORT @@ -100,7 +100,7 @@ void AddToAsyncList(HIF_DEVICE *device, BUS_REQUEST *busrequest); struct hif_scatter_req_priv { struct hif_scatter_req *pHifScatterReq; /* HIF scatter request with allocated entries */ - HIF_DEVICE *device; /* this device */ + struct hif_device *device; /* this device */ BUS_REQUEST *busrequest; /* request associated with request */ /* scatter list for linux */ struct scatterlist sgentries[MAX_SCATTER_ENTRIES_PER_REQ]; @@ -108,18 +108,18 @@ struct hif_scatter_req_priv { #define ATH_DEBUG_SCATTER ATH_DEBUG_MAKE_MODULE_MASK(0) -int SetupHIFScatterSupport(HIF_DEVICE *device, struct hif_device_scatter_support_info *pInfo); -void CleanupHIFScatterResources(HIF_DEVICE *device); -int DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest); +int SetupHIFScatterSupport(struct hif_device *device, struct hif_device_scatter_support_info *pInfo); +void CleanupHIFScatterResources(struct hif_device *device); +int DoHifReadWriteScatter(struct hif_device *device, BUS_REQUEST *busrequest); #else // HIF_LINUX_MMC_SCATTER_SUPPORT -static inline int SetupHIFScatterSupport(HIF_DEVICE *device, struct hif_device_scatter_support_info *pInfo) +static inline int SetupHIFScatterSupport(struct hif_device *device, struct hif_device_scatter_support_info *pInfo) { return A_ENOTSUP; } -static inline int DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest) +static inline int DoHifReadWriteScatter(struct hif_device *device, BUS_REQUEST *busrequest) { return A_ENOTSUP; } diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index 9c9fb1ef86d0..e6d9cd802dee 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -58,9 +58,9 @@ static int hifDeviceResume(struct device *dev); #endif /* CONFIG_PM */ static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id); static void hifDeviceRemoved(struct sdio_func *func); -static HIF_DEVICE *addHifDevice(struct sdio_func *func); -static HIF_DEVICE *getHifDevice(struct sdio_func *func); -static void delHifDevice(HIF_DEVICE * device); +static struct hif_device *addHifDevice(struct sdio_func *func); +static struct hif_device *getHifDevice(struct sdio_func *func); +static void delHifDevice(struct hif_device * device); static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte); static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte); @@ -107,8 +107,8 @@ extern u32 busspeedlow; extern u32 debughif; static void ResetAllCards(void); -static int hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func); -static int hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func); +static int hifDisableFunc(struct hif_device *device, struct sdio_func *func); +static int hifEnableFunc(struct hif_device *device, struct sdio_func *func); #ifdef DEBUG @@ -153,7 +153,7 @@ int HIFInit(OSDRV_CALLBACKS *callbacks) } static int -__HIFReadWrite(HIF_DEVICE *device, +__HIFReadWrite(struct hif_device *device, u32 address, u8 *buffer, u32 length, @@ -304,7 +304,7 @@ __HIFReadWrite(HIF_DEVICE *device, return status; } -void AddToAsyncList(HIF_DEVICE *device, BUS_REQUEST *busrequest) +void AddToAsyncList(struct hif_device *device, BUS_REQUEST *busrequest) { unsigned long flags; BUS_REQUEST *async; @@ -330,7 +330,7 @@ void AddToAsyncList(HIF_DEVICE *device, BUS_REQUEST *busrequest) /* queue a read/write request */ int -HIFReadWrite(HIF_DEVICE *device, +HIFReadWrite(struct hif_device *device, u32 address, u8 *buffer, u32 length, @@ -400,12 +400,12 @@ HIFReadWrite(HIF_DEVICE *device, /* thread to serialize all requests, both sync and async */ static int async_task(void *param) { - HIF_DEVICE *device; + struct hif_device *device; BUS_REQUEST *request; int status; unsigned long flags; - device = (HIF_DEVICE *)param; + device = (struct hif_device *)param; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task\n")); set_current_state(TASK_INTERRUPTIBLE); while(!device->async_shutdown) { @@ -465,7 +465,7 @@ static int async_task(void *param) return 0; } -static s32 IssueSDCommand(HIF_DEVICE *device, u32 opcode, u32 arg, u32 flags, u32 *resp) +static s32 IssueSDCommand(struct hif_device *device, u32 opcode, u32 arg, u32 flags, u32 *resp) { struct mmc_command cmd; s32 err; @@ -488,7 +488,7 @@ static s32 IssueSDCommand(HIF_DEVICE *device, u32 opcode, u32 arg, u32 flags, u3 return err; } -int ReinitSDIO(HIF_DEVICE *device) +int ReinitSDIO(struct hif_device *device) { s32 err; struct mmc_host *host; @@ -648,7 +648,7 @@ int ReinitSDIO(HIF_DEVICE *device) } int -PowerStateChangeNotify(HIF_DEVICE *device, HIF_DEVICE_POWER_CHANGE_TYPE config) +PowerStateChangeNotify(struct hif_device *device, HIF_DEVICE_POWER_CHANGE_TYPE config) { int status = 0; #if defined(CONFIG_PM) @@ -691,7 +691,7 @@ PowerStateChangeNotify(HIF_DEVICE *device, HIF_DEVICE_POWER_CHANGE_TYPE config) } int -HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, +HIFConfigureDevice(struct hif_device *device, HIF_DEVICE_CONFIG_OPCODE opcode, void *config, u32 configLen) { u32 count; @@ -745,7 +745,7 @@ HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, } void -HIFShutDownDevice(HIF_DEVICE *device) +HIFShutDownDevice(struct hif_device *device) { AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +HIFShutDownDevice\n")); if (device != NULL) { @@ -775,7 +775,7 @@ static void hifIRQHandler(struct sdio_func *func) { int status; - HIF_DEVICE *device; + struct hif_device *device; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifIRQHandler\n")); device = getHifDevice(func); @@ -792,9 +792,9 @@ hifIRQHandler(struct sdio_func *func) /* handle HTC startup via thread*/ static int startup_task(void *param) { - HIF_DEVICE *device; + struct hif_device *device; - device = (HIF_DEVICE *)param; + device = (struct hif_device *)param; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call HTC from startup_task\n")); /* start up inform DRV layer */ if ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context,device)) != 0) { @@ -806,8 +806,8 @@ static int startup_task(void *param) #if defined(CONFIG_PM) static int enable_task(void *param) { - HIF_DEVICE *device; - device = (HIF_DEVICE *)param; + struct hif_device *device; + device = (struct hif_device *)param; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call from resume_task\n")); /* start up inform DRV layer */ @@ -826,7 +826,7 @@ static int enable_task(void *param) static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id) { int ret; - HIF_DEVICE * device; + struct hif_device * device; int count; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, @@ -866,7 +866,7 @@ static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id void -HIFAckInterrupt(HIF_DEVICE *device) +HIFAckInterrupt(struct hif_device *device) { AR_DEBUG_ASSERT(device != NULL); @@ -874,7 +874,7 @@ HIFAckInterrupt(HIF_DEVICE *device) } void -HIFUnMaskInterrupt(HIF_DEVICE *device) +HIFUnMaskInterrupt(struct hif_device *device) { int ret; @@ -890,7 +890,7 @@ HIFUnMaskInterrupt(HIF_DEVICE *device) AR_DEBUG_ASSERT(ret == 0); } -void HIFMaskInterrupt(HIF_DEVICE *device) +void HIFMaskInterrupt(struct hif_device *device) { int ret; AR_DEBUG_ASSERT(device != NULL); @@ -910,7 +910,7 @@ void HIFMaskInterrupt(HIF_DEVICE *device) AR_DEBUG_ASSERT(ret == 0); } -BUS_REQUEST *hifAllocateBusRequest(HIF_DEVICE *device) +BUS_REQUEST *hifAllocateBusRequest(struct hif_device *device) { BUS_REQUEST *busrequest; unsigned long flag; @@ -930,7 +930,7 @@ BUS_REQUEST *hifAllocateBusRequest(HIF_DEVICE *device) } void -hifFreeBusRequest(HIF_DEVICE *device, BUS_REQUEST *busrequest) +hifFreeBusRequest(struct hif_device *device, BUS_REQUEST *busrequest) { unsigned long flag; @@ -949,7 +949,7 @@ hifFreeBusRequest(HIF_DEVICE *device, BUS_REQUEST *busrequest) spin_unlock_irqrestore(&device->lock, flag); } -static int hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func) +static int hifDisableFunc(struct hif_device *device, struct sdio_func *func) { int ret; int status = 0; @@ -996,7 +996,7 @@ static int hifDisableFunc(HIF_DEVICE *device, struct sdio_func *func) return status; } -static int hifEnableFunc(HIF_DEVICE *device, struct sdio_func *func) +static int hifEnableFunc(struct hif_device *device, struct sdio_func *func) { struct task_struct* pTask; const char *taskName = NULL; @@ -1081,7 +1081,7 @@ static int hifDeviceSuspend(struct device *dev) { struct sdio_func *func=dev_to_sdio_func(dev); int status = 0; - HIF_DEVICE *device; + struct hif_device *device; device = getHifDevice(func); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceSuspend\n")); @@ -1109,7 +1109,7 @@ static int hifDeviceResume(struct device *dev) { struct sdio_func *func=dev_to_sdio_func(dev); int status = 0; - HIF_DEVICE *device; + struct hif_device *device; device = getHifDevice(func); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceResume\n")); @@ -1128,7 +1128,7 @@ static int hifDeviceResume(struct device *dev) static void hifDeviceRemoved(struct sdio_func *func) { int status = 0; - HIF_DEVICE *device; + struct hif_device *device; AR_DEBUG_ASSERT(func != NULL); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceRemoved\n")); @@ -1152,7 +1152,7 @@ static void hifDeviceRemoved(struct sdio_func *func) /* * This should be moved to AR6K HTC layer. */ -int hifWaitForPendingRecv(HIF_DEVICE *device) +int hifWaitForPendingRecv(struct hif_device *device) { s32 cnt = 10; u8 host_int_status; @@ -1183,13 +1183,13 @@ int hifWaitForPendingRecv(HIF_DEVICE *device) } -static HIF_DEVICE * +static struct hif_device * addHifDevice(struct sdio_func *func) { - HIF_DEVICE *hifdevice; + struct hif_device *hifdevice; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice\n")); AR_DEBUG_ASSERT(func != NULL); - hifdevice = kzalloc(sizeof(HIF_DEVICE), GFP_KERNEL); + hifdevice = kzalloc(sizeof(struct hif_device), GFP_KERNEL); AR_DEBUG_ASSERT(hifdevice != NULL); #if HIF_USE_DMA_BOUNCE_BUFFER hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL); @@ -1202,15 +1202,15 @@ addHifDevice(struct sdio_func *func) return hifdevice; } -static HIF_DEVICE * +static struct hif_device * getHifDevice(struct sdio_func *func) { AR_DEBUG_ASSERT(func != NULL); - return (HIF_DEVICE *)sdio_get_drvdata(func); + return (struct hif_device *)sdio_get_drvdata(func); } static void -delHifDevice(HIF_DEVICE * device) +delHifDevice(struct hif_device * device) { AR_DEBUG_ASSERT(device!= NULL); AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: delHifDevice; 0x%p\n", device)); @@ -1222,17 +1222,17 @@ static void ResetAllCards(void) { } -void HIFClaimDevice(HIF_DEVICE *device, void *context) +void HIFClaimDevice(struct hif_device *device, void *context) { device->claimedContext = context; } -void HIFReleaseDevice(HIF_DEVICE *device) +void HIFReleaseDevice(struct hif_device *device) { device->claimedContext = NULL; } -int HIFAttachHTC(HIF_DEVICE *device, HTC_CALLBACKS *callbacks) +int HIFAttachHTC(struct hif_device *device, HTC_CALLBACKS *callbacks) { if (device->htcCallbacks.context != NULL) { /* already in use! */ @@ -1242,7 +1242,7 @@ int HIFAttachHTC(HIF_DEVICE *device, HTC_CALLBACKS *callbacks) return 0; } -void HIFDetachHTC(HIF_DEVICE *device) +void HIFDetachHTC(struct hif_device *device) { A_MEMZERO(&device->htcCallbacks,sizeof(device->htcCallbacks)); } diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c index 2c64abe04d61..a1fdcc189f7e 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c @@ -48,7 +48,7 @@ (((address) & 0x1FFFF) << 9) | \ ((bytes_blocks) & 0x1FF) -static void FreeScatterReq(HIF_DEVICE *device, struct hif_scatter_req *pReq) +static void FreeScatterReq(struct hif_device *device, struct hif_scatter_req *pReq) { unsigned long flag; @@ -60,7 +60,7 @@ static void FreeScatterReq(HIF_DEVICE *device, struct hif_scatter_req *pReq) } -static struct hif_scatter_req *AllocScatterReq(HIF_DEVICE *device) +static struct hif_scatter_req *AllocScatterReq(struct hif_device *device) { struct dl_list *pItem; unsigned long flag; @@ -79,7 +79,7 @@ static struct hif_scatter_req *AllocScatterReq(HIF_DEVICE *device) } /* called by async task to perform the operation synchronously using direct MMC APIs */ -int DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest) +int DoHifReadWriteScatter(struct hif_device *device, BUS_REQUEST *busrequest) { int i; u8 rw; @@ -199,7 +199,7 @@ int DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest) } /* callback to issue a read-write scatter request */ -static int HifReadWriteScatter(HIF_DEVICE *device, struct hif_scatter_req *pReq) +static int HifReadWriteScatter(struct hif_device *device, struct hif_scatter_req *pReq) { int status = A_EINVAL; u32 request = pReq->Request; @@ -275,7 +275,7 @@ static int HifReadWriteScatter(HIF_DEVICE *device, struct hif_scatter_req *pReq) } /* setup of HIF scatter resources */ -int SetupHIFScatterSupport(HIF_DEVICE *device, struct hif_device_scatter_support_info *pInfo) +int SetupHIFScatterSupport(struct hif_device *device, struct hif_device_scatter_support_info *pInfo) { int status = A_ERROR; int i; @@ -356,7 +356,7 @@ int SetupHIFScatterSupport(HIF_DEVICE *device, struct hif_device_scatter_support } /* clean up scatter support */ -void CleanupHIFScatterResources(HIF_DEVICE *device) +void CleanupHIFScatterResources(struct hif_device *device) { struct hif_scatter_req_priv *pReqPriv; struct hif_scatter_req *pReq; diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c index 91e763a4abf7..eeddf6021f6d 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c @@ -587,7 +587,7 @@ void DevDumpRegisters(struct ar6k_device *pDev, #define DEV_GET_VIRT_DMA_INFO(p) ((struct dev_scatter_dma_virtual_info *)((p)->HIFPrivate[0])) -static struct hif_scatter_req *DevAllocScatterReq(HIF_DEVICE *Context) +static struct hif_scatter_req *DevAllocScatterReq(struct hif_device *Context) { struct dl_list *pItem; struct ar6k_device *pDev = (struct ar6k_device *)Context; @@ -600,7 +600,7 @@ static struct hif_scatter_req *DevAllocScatterReq(HIF_DEVICE *Context) return NULL; } -static void DevFreeScatterReq(HIF_DEVICE *Context, struct hif_scatter_req *pReq) +static void DevFreeScatterReq(struct hif_device *Context, struct hif_scatter_req *pReq) { struct ar6k_device *pDev = (struct ar6k_device *)Context; LOCK_AR6K(pDev); @@ -664,7 +664,7 @@ static void DevReadWriteScatterAsyncHandler(void *Context, struct htc_packet *pP AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-DevReadWriteScatterAsyncHandler \n")); } -static int DevReadWriteScatter(HIF_DEVICE *Context, struct hif_scatter_req *pReq) +static int DevReadWriteScatter(struct hif_device *Context, struct hif_scatter_req *pReq) { struct ar6k_device *pDev = (struct ar6k_device *)Context; int status = 0; @@ -739,7 +739,7 @@ static void DevCleanupVirtualScatterSupport(struct ar6k_device *pDev) struct hif_scatter_req *pReq; while (1) { - pReq = DevAllocScatterReq((HIF_DEVICE *)pDev); + pReq = DevAllocScatterReq((struct hif_device *)pDev); if (NULL == pReq) { break; } @@ -787,7 +787,7 @@ static int DevSetupVirtualScatterSupport(struct ar6k_device *pDev) pReq->ScatterMethod = HIF_SCATTER_DMA_BOUNCE; pReq->pScatterBounceBuffer = pVirtualInfo->pVirtDmaBuffer; /* free request to the list */ - DevFreeScatterReq((HIF_DEVICE *)pDev,pReq); + DevFreeScatterReq((struct hif_device *)pDev,pReq); } if (status) { diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c index 8cf46b13390d..c6488e0d1305 100644 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c +++ b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c @@ -1233,7 +1233,7 @@ int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud) { struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; - HIF_DEVICE *pHIFDevice = (HIF_DEVICE *)(pProt->pDev->HIFDevice); + struct hif_device *pHIFDevice = (struct hif_device *)(pProt->pDev->HIFDevice); u32 scaledBaud, scratchAddr; int status = 0; diff --git a/drivers/staging/ath6kl/include/ar3kconfig.h b/drivers/staging/ath6kl/include/ar3kconfig.h index 80f948e99576..91bc4ee3512d 100644 --- a/drivers/staging/ath6kl/include/ar3kconfig.h +++ b/drivers/staging/ath6kl/include/ar3kconfig.h @@ -42,7 +42,7 @@ struct ar3k_config_info { u32 Flags; /* config flags */ void *pHCIDev; /* HCI bridge device */ struct hci_transport_properties *pHCIProps; /* HCI bridge props */ - HIF_DEVICE *pHIFDevice; /* HIF layer device */ + struct hif_device *pHIFDevice; /* HIF layer device */ u32 AR3KBaudRate; /* AR3K operational baud rate */ u16 AR6KScale; /* AR6K UART scale value */ diff --git a/drivers/staging/ath6kl/include/ar6000_diag.h b/drivers/staging/ath6kl/include/ar6000_diag.h index ca0961ab5d57..739c01c53f08 100644 --- a/drivers/staging/ath6kl/include/ar6000_diag.h +++ b/drivers/staging/ath6kl/include/ar6000_diag.h @@ -26,23 +26,23 @@ int -ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data); +ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data); int -ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data); +ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data); int -ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, u32 address, +ar6000_ReadDataDiag(struct hif_device *hifDevice, u32 address, u8 *data, u32 length); int -ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, u32 address, +ar6000_WriteDataDiag(struct hif_device *hifDevice, u32 address, u8 *data, u32 length); int -ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, u32 *regval); +ar6k_ReadTargetRegister(struct hif_device *hifDevice, int regsel, u32 *regval); void -ar6k_FetchTargetRegs(HIF_DEVICE *hifDevice, u32 *targregs); +ar6k_FetchTargetRegs(struct hif_device *hifDevice, u32 *targregs); #endif /*AR6000_DIAG_H_*/ diff --git a/drivers/staging/ath6kl/include/bmi.h b/drivers/staging/ath6kl/include/bmi.h index b44988d6edc2..eb1e75607247 100644 --- a/drivers/staging/ath6kl/include/bmi.h +++ b/drivers/staging/ath6kl/include/bmi.h @@ -44,44 +44,44 @@ void BMICleanup(void); int -BMIDone(HIF_DEVICE *device); +BMIDone(struct hif_device *device); int -BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info); +BMIGetTargetInfo(struct hif_device *device, struct bmi_target_info *targ_info); int -BMIReadMemory(HIF_DEVICE *device, +BMIReadMemory(struct hif_device *device, u32 address, u8 *buffer, u32 length); int -BMIWriteMemory(HIF_DEVICE *device, +BMIWriteMemory(struct hif_device *device, u32 address, u8 *buffer, u32 length); int -BMIExecute(HIF_DEVICE *device, +BMIExecute(struct hif_device *device, u32 address, u32 *param); int -BMISetAppStart(HIF_DEVICE *device, +BMISetAppStart(struct hif_device *device, u32 address); int -BMIReadSOCRegister(HIF_DEVICE *device, +BMIReadSOCRegister(struct hif_device *device, u32 address, u32 *param); int -BMIWriteSOCRegister(HIF_DEVICE *device, +BMIWriteSOCRegister(struct hif_device *device, u32 address, u32 param); int -BMIrompatchInstall(HIF_DEVICE *device, +BMIrompatchInstall(struct hif_device *device, u32 ROM_addr, u32 RAM_addr, u32 nbytes, @@ -89,41 +89,41 @@ BMIrompatchInstall(HIF_DEVICE *device, u32 *patch_id); int -BMIrompatchUninstall(HIF_DEVICE *device, +BMIrompatchUninstall(struct hif_device *device, u32 rompatch_id); int -BMIrompatchActivate(HIF_DEVICE *device, +BMIrompatchActivate(struct hif_device *device, u32 rompatch_count, u32 *rompatch_list); int -BMIrompatchDeactivate(HIF_DEVICE *device, +BMIrompatchDeactivate(struct hif_device *device, u32 rompatch_count, u32 *rompatch_list); int -BMILZStreamStart(HIF_DEVICE *device, +BMILZStreamStart(struct hif_device *device, u32 address); int -BMILZData(HIF_DEVICE *device, +BMILZData(struct hif_device *device, u8 *buffer, u32 length); int -BMIFastDownload(HIF_DEVICE *device, +BMIFastDownload(struct hif_device *device, u32 address, u8 *buffer, u32 length); int -BMIRawWrite(HIF_DEVICE *device, +BMIRawWrite(struct hif_device *device, u8 *buffer, u32 length); int -BMIRawRead(HIF_DEVICE *device, +BMIRawRead(struct hif_device *device, u8 *buffer, u32 length, bool want_timeout); diff --git a/drivers/staging/ath6kl/include/common_drv.h b/drivers/staging/ath6kl/include/common_drv.h index 3508df4e806c..b6063347229f 100644 --- a/drivers/staging/ath6kl/include/common_drv.h +++ b/drivers/staging/ath6kl/include/common_drv.h @@ -66,30 +66,30 @@ extern "C" { /* OS-independent APIs */ int ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, struct common_credit_state_info *pCredInfo); -int ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data); +int ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data); -int ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data); +int ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data); -int ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, u32 address, u8 *data, u32 length); +int ar6000_ReadDataDiag(struct hif_device *hifDevice, u32 address, u8 *data, u32 length); -int ar6000_reset_device(HIF_DEVICE *hifDevice, u32 TargetType, bool waitForCompletion, bool coldReset); +int ar6000_reset_device(struct hif_device *hifDevice, u32 TargetType, bool waitForCompletion, bool coldReset); -void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, u32 TargetType); +void ar6000_dump_target_assert_info(struct hif_device *hifDevice, u32 TargetType); -int ar6000_set_htc_params(HIF_DEVICE *hifDevice, +int ar6000_set_htc_params(struct hif_device *hifDevice, u32 TargetType, u32 MboxIsrYieldValue, u8 HtcControlBuffers); -int ar6000_prepare_target(HIF_DEVICE *hifDevice, +int ar6000_prepare_target(struct hif_device *hifDevice, u32 TargetType, u32 TargetVersion); -int ar6000_set_hci_bridge_flags(HIF_DEVICE *hifDevice, +int ar6000_set_hci_bridge_flags(struct hif_device *hifDevice, u32 TargetType, u32 Flags); -void ar6000_copy_cust_data_from_target(HIF_DEVICE *hifDevice, u32 TargetType); +void ar6000_copy_cust_data_from_target(struct hif_device *hifDevice, u32 TargetType); u8 *ar6000_get_cust_data_buffer(u32 TargetType); diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h index 3dcb78713b6b..83650d5ce3fb 100644 --- a/drivers/staging/ath6kl/include/hif.h +++ b/drivers/staging/ath6kl/include/hif.h @@ -38,7 +38,7 @@ extern "C" { typedef struct htc_callbacks HTC_CALLBACKS; -typedef struct hif_device HIF_DEVICE; +struct hif_device; /* * direction - Direction of transfer (HIF_READ/HIF_WRITE). @@ -301,9 +301,9 @@ struct hif_scatter_req { struct hif_scatter_item ScatterList[1]; /* start of scatter list */ }; -typedef struct hif_scatter_req * ( *HIF_ALLOCATE_SCATTER_REQUEST)(HIF_DEVICE *device); -typedef void ( *HIF_FREE_SCATTER_REQUEST)(HIF_DEVICE *device, struct hif_scatter_req *request); -typedef int ( *HIF_READWRITE_SCATTER)(HIF_DEVICE *device, struct hif_scatter_req *request); +typedef struct hif_scatter_req * ( *HIF_ALLOCATE_SCATTER_REQUEST)(struct hif_device *device); +typedef void ( *HIF_FREE_SCATTER_REQUEST)(struct hif_device *device, struct hif_scatter_req *request); +typedef int ( *HIF_READWRITE_SCATTER)(struct hif_device *device, struct hif_scatter_req *request); struct hif_device_scatter_support_info { /* information returned from HIF layer */ @@ -354,14 +354,14 @@ struct hif_pending_events_info { /* function to get pending events , some HIF modules use special mechanisms * to detect packet available and other interrupts */ -typedef int ( *HIF_PENDING_EVENTS_FUNC)(HIF_DEVICE *device, +typedef int ( *HIF_PENDING_EVENTS_FUNC)(struct hif_device *device, struct hif_pending_events_info *pEvents, void *AsyncContext); #define HIF_MASK_RECV true #define HIF_UNMASK_RECV false /* function to mask recv events */ -typedef int ( *HIF_MASK_UNMASK_RECV_EVENT)(HIF_DEVICE *device, +typedef int ( *HIF_MASK_UNMASK_RECV_EVENT)(struct hif_device *device, bool Mask, void *AsyncContext); @@ -376,14 +376,14 @@ int HIFInit(OSDRV_CALLBACKS *callbacks); /* This API claims the HIF device and provides a context for handling removal. * The device removal callback is only called when the OSDRV layer claims * a device. The claimed context must be non-NULL */ -void HIFClaimDevice(HIF_DEVICE *device, void *claimedContext); +void HIFClaimDevice(struct hif_device *device, void *claimedContext); /* release the claimed device */ -void HIFReleaseDevice(HIF_DEVICE *device); +void HIFReleaseDevice(struct hif_device *device); /* This API allows the HTC layer to attach to the HIF device */ -int HIFAttachHTC(HIF_DEVICE *device, HTC_CALLBACKS *callbacks); +int HIFAttachHTC(struct hif_device *device, HTC_CALLBACKS *callbacks); /* This API detaches the HTC layer from the HIF device */ -void HIFDetachHTC(HIF_DEVICE *device); +void HIFDetachHTC(struct hif_device *device); /* * This API is used to provide the read/write interface over the specific bus @@ -398,7 +398,7 @@ void HIFDetachHTC(HIF_DEVICE *device); * request - Characterizes the attributes of the command. */ int -HIFReadWrite(HIF_DEVICE *device, +HIFReadWrite(struct hif_device *device, u32 address, u8 *buffer, u32 length, @@ -409,7 +409,7 @@ HIFReadWrite(HIF_DEVICE *device, * This can be initiated from the unload driver context when the OSDRV layer has no more use for * the device. */ -void HIFShutDownDevice(HIF_DEVICE *device); +void HIFShutDownDevice(struct hif_device *device); /* * This should translate to an acknowledgment to the bus driver indicating that @@ -418,11 +418,11 @@ void HIFShutDownDevice(HIF_DEVICE *device); * This should prevent the bus driver from raising an interrupt unless the * previous one has been serviced and acknowledged using the previous API. */ -void HIFAckInterrupt(HIF_DEVICE *device); +void HIFAckInterrupt(struct hif_device *device); -void HIFMaskInterrupt(HIF_DEVICE *device); +void HIFMaskInterrupt(struct hif_device *device); -void HIFUnMaskInterrupt(HIF_DEVICE *device); +void HIFUnMaskInterrupt(struct hif_device *device); #ifdef THREAD_X /* @@ -441,14 +441,14 @@ int HIFRWCompleteEventNotify(void); #endif int -HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode, +HIFConfigureDevice(struct hif_device *device, HIF_DEVICE_CONFIG_OPCODE opcode, void *config, u32 configLen); /* * This API wait for the remaining MBOX messages to be drained * This should be moved to HTC AR6K layer */ -int hifWaitForPendingRecv(HIF_DEVICE *device); +int hifWaitForPendingRecv(struct hif_device *device); #ifdef __cplusplus } diff --git a/drivers/staging/ath6kl/miscdrv/common_drv.c b/drivers/staging/ath6kl/miscdrv/common_drv.c index 3ada3317fdbc..a23a52412b3d 100644 --- a/drivers/staging/ath6kl/miscdrv/common_drv.c +++ b/drivers/staging/ath6kl/miscdrv/common_drv.c @@ -83,7 +83,7 @@ static u8 custDataAR6003[AR6003_CUST_DATA_SIZE]; #ifdef USE_4BYTE_REGISTER_ACCESS /* set the window address register (using 4-byte register access ). */ -int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, u32 RegisterAddr, u32 Address) +int ar6000_SetAddressWindowRegister(struct hif_device *hifDevice, u32 RegisterAddr, u32 Address) { int status; u8 addrValue[4]; @@ -144,7 +144,7 @@ int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, u32 RegisterAddr, u32 #else /* set the window address register */ -int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, u32 RegisterAddr, u32 Address) +int ar6000_SetAddressWindowRegister(struct hif_device *hifDevice, u32 RegisterAddr, u32 Address) { int status; @@ -187,7 +187,7 @@ int ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, u32 RegisterAddr, u32 * No cooperation from the Target is required for this. */ int -ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data) +ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data) { int status; @@ -221,7 +221,7 @@ ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data) * No cooperation from the Target is required for this. */ int -ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data) +ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data) { int status; @@ -244,7 +244,7 @@ ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data) } int -ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, u32 address, +ar6000_ReadDataDiag(struct hif_device *hifDevice, u32 address, u8 *data, u32 length) { u32 count; @@ -262,7 +262,7 @@ ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, u32 address, } int -ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, u32 address, +ar6000_WriteDataDiag(struct hif_device *hifDevice, u32 address, u8 *data, u32 length) { u32 count; @@ -280,7 +280,7 @@ ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, u32 address, } int -ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, u32 *regval) +ar6k_ReadTargetRegister(struct hif_device *hifDevice, int regsel, u32 *regval) { int status; u8 vals[4]; @@ -316,7 +316,7 @@ ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, u32 *regval) } void -ar6k_FetchTargetRegs(HIF_DEVICE *hifDevice, u32 *targregs) +ar6k_FetchTargetRegs(struct hif_device *hifDevice, u32 *targregs) { int i; u32 val; @@ -330,7 +330,7 @@ ar6k_FetchTargetRegs(HIF_DEVICE *hifDevice, u32 *targregs) #if 0 static int -_do_write_diag(HIF_DEVICE *hifDevice, u32 addr, u32 value) +_do_write_diag(struct hif_device *hifDevice, u32 addr, u32 value) { int status; @@ -358,7 +358,7 @@ _do_write_diag(HIF_DEVICE *hifDevice, u32 addr, u32 value) */ #if 0 static int -_delay_until_target_alive(HIF_DEVICE *hifDevice, s32 wait_msecs, u32 TargetType) +_delay_until_target_alive(struct hif_device *hifDevice, s32 wait_msecs, u32 TargetType) { s32 actual_wait; s32 i; @@ -399,7 +399,7 @@ _delay_until_target_alive(HIF_DEVICE *hifDevice, s32 wait_msecs, u32 TargetType) #define AR6002_RESET_CONTROL_ADDRESS 0x00004000 #define AR6003_RESET_CONTROL_ADDRESS 0x00004000 /* reset device */ -int ar6000_reset_device(HIF_DEVICE *hifDevice, u32 TargetType, bool waitForCompletion, bool coldReset) +int ar6000_reset_device(struct hif_device *hifDevice, u32 TargetType, bool waitForCompletion, bool coldReset) { int status = 0; u32 address; @@ -481,7 +481,7 @@ int ar6000_reset_device(HIF_DEVICE *hifDevice, u32 TargetType, bool waitForCompl /* This should be called in BMI phase after firmware is downloaded */ void -ar6000_copy_cust_data_from_target(HIF_DEVICE *hifDevice, u32 TargetType) +ar6000_copy_cust_data_from_target(struct hif_device *hifDevice, u32 TargetType) { u32 eepHeaderAddr; u8 AR6003CustDataShadow[AR6003_CUST_DATA_SIZE+4]; @@ -552,7 +552,7 @@ u8 *ar6000_get_cust_data_buffer(u32 TargetType) #endif -void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, u32 TargetType) +void ar6000_dump_target_assert_info(struct hif_device *hifDevice, u32 TargetType) { u32 address; u32 regDumpArea = 0; @@ -624,7 +624,7 @@ void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, u32 TargetType) /* set HTC/Mbox operational parameters, this can only be called when the target is in the * BMI phase */ -int ar6000_set_htc_params(HIF_DEVICE *hifDevice, +int ar6000_set_htc_params(struct hif_device *hifDevice, u32 TargetType, u32 MboxIsrYieldValue, u8 HtcControlBuffers) @@ -684,7 +684,7 @@ int ar6000_set_htc_params(HIF_DEVICE *hifDevice, } -static int prepare_ar6002(HIF_DEVICE *hifDevice, u32 TargetVersion) +static int prepare_ar6002(struct hif_device *hifDevice, u32 TargetVersion) { int status = 0; @@ -693,7 +693,7 @@ static int prepare_ar6002(HIF_DEVICE *hifDevice, u32 TargetVersion) return status; } -static int prepare_ar6003(HIF_DEVICE *hifDevice, u32 TargetVersion) +static int prepare_ar6003(struct hif_device *hifDevice, u32 TargetVersion) { int status = 0; @@ -703,7 +703,7 @@ static int prepare_ar6003(HIF_DEVICE *hifDevice, u32 TargetVersion) } /* this function assumes the caller has already initialized the BMI APIs */ -int ar6000_prepare_target(HIF_DEVICE *hifDevice, +int ar6000_prepare_target(struct hif_device *hifDevice, u32 TargetType, u32 TargetVersion) { @@ -725,7 +725,7 @@ int ar6000_prepare_target(HIF_DEVICE *hifDevice, * TBDXXX: Remove this function when REV 1.x is desupported. */ int -ar6002_REV1_reset_force_host (HIF_DEVICE *hifDevice) +ar6002_REV1_reset_force_host (struct hif_device *hifDevice) { s32 i; struct forceROM_s { @@ -998,7 +998,7 @@ void a_module_debug_support_cleanup(void) } /* can only be called during bmi init stage */ -int ar6000_set_hci_bridge_flags(HIF_DEVICE *hifDevice, +int ar6000_set_hci_bridge_flags(struct hif_device *hifDevice, u32 TargetType, u32 Flags) { diff --git a/drivers/staging/ath6kl/os/linux/eeprom.c b/drivers/staging/ath6kl/os/linux/eeprom.c index 7d049dffd222..4cff9da2f03e 100644 --- a/drivers/staging/ath6kl/os/linux/eeprom.c +++ b/drivers/staging/ath6kl/os/linux/eeprom.c @@ -55,7 +55,7 @@ char *p_mac = NULL; static u8 eeprom_data[EEPROM_SZ]; static u32 sys_sleep_reg; -static HIF_DEVICE *p_bmi_device; +static struct hif_device *p_bmi_device; // // Functions @@ -158,7 +158,7 @@ BMI_write_mem(u32 address, u8 *p_data, u32 sz) * so we can access the EEPROM. */ static void -enable_SI(HIF_DEVICE *p_device) +enable_SI(struct hif_device *p_device) { u32 regval; @@ -361,7 +361,7 @@ commit_4bytes(int offset, u32 data) } /* ATHENV */ #ifdef ANDROID_ENV -void eeprom_ar6000_transfer(HIF_DEVICE *device, char *fake_file, char *p_mac) +void eeprom_ar6000_transfer(struct hif_device *device, char *fake_file, char *p_mac) { u32 first_word; u32 board_data_addr; diff --git a/drivers/staging/ath6kl/os/linux/export_hci_transport.c b/drivers/staging/ath6kl/os/linux/export_hci_transport.c index 787a8bdb5cbd..442a2860d24a 100644 --- a/drivers/staging/ath6kl/os/linux/export_hci_transport.c +++ b/drivers/staging/ath6kl/os/linux/export_hci_transport.c @@ -70,7 +70,7 @@ int ar6000_register_hci_transport(struct hci_transport_callbacks *hciTransCallba } int -ar6000_get_hif_dev(HIF_DEVICE *device, void *config) +ar6000_get_hif_dev(struct hif_device *device, void *config) { int status; @@ -81,7 +81,7 @@ ar6000_get_hif_dev(HIF_DEVICE *device, void *config) return status; } -int ar6000_set_uart_config(HIF_DEVICE *hifDevice, +int ar6000_set_uart_config(struct hif_device *hifDevice, u32 scale, u32 step) { @@ -97,7 +97,7 @@ int ar6000_set_uart_config(HIF_DEVICE *hifDevice, return status; } -int ar6000_get_core_clock_config(HIF_DEVICE *hifDevice, u32 *data) +int ar6000_get_core_clock_config(struct hif_device *hifDevice, u32 *data) { u32 regAddress; int status; diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c index 1ff71e867691..39e5798f5e80 100644 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ b/drivers/staging/ath6kl/os/linux/hci_bridge.c @@ -270,7 +270,7 @@ static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle, ar3kconfig.pHCIDev = pHcidevInfo->pHCIDev; ar3kconfig.pHCIProps = &pHcidevInfo->HCIProps; #ifdef EXPORT_HCI_BRIDGE_INTERFACE - ar3kconfig.pHIFDevice = (HIF_DEVICE *)(pHcidevInfo->HCITransHdl.hifDevice); + ar3kconfig.pHIFDevice = (struct hif_device *)(pHcidevInfo->HCITransHdl.hifDevice); #else ar3kconfig.pHIFDevice = pHcidevInfo->ar->arHifDevice; #endif @@ -868,7 +868,7 @@ static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo) A_MEMZERO(&osDevInfo,sizeof(osDevInfo)); /* get the underlying OS device */ #ifdef EXPORT_HCI_BRIDGE_INTERFACE - status = ar6000_get_hif_dev((HIF_DEVICE *)(pHcidevInfo->HCITransHdl.hifDevice), + status = ar6000_get_hif_dev((struct hif_device *)(pHcidevInfo->HCITransHdl.hifDevice), &osDevInfo); #else status = HIFConfigureDevice(pHcidevInfo->ar->arHifDevice, diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 9b5c0a3970b6..89fd80a2c8ed 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -121,8 +121,8 @@ struct USER_SAVEDKEYS { #define DBG_DEFAULTS (DBG_ERROR|DBG_WARNING) -int ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data); -int ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, u32 *address, u32 *data); +int ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data); +int ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data); #ifdef __cplusplus extern "C" { diff --git a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h index 31f4f783dcc0..74f986183347 100644 --- a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h +++ b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h @@ -63,9 +63,9 @@ extern int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, bo extern int ar6000_register_hci_transport(struct hci_transport_callbacks *hciTransCallbacks); -extern int ar6000_get_hif_dev(HIF_DEVICE *device, void *config); +extern int ar6000_get_hif_dev(struct hif_device *device, void *config); -extern int ar6000_set_uart_config(HIF_DEVICE *hifDevice, u32 scale, u32 step); +extern int ar6000_set_uart_config(struct hif_device *hifDevice, u32 scale, u32 step); /* get core clock register settings * data: 0 - 40/44MHz @@ -73,4 +73,4 @@ extern int ar6000_set_uart_config(HIF_DEVICE *hifDevice, u32 scale, u32 step); * where (5G band/2.4G band) * assume 2.4G band for now */ -extern int ar6000_get_core_clock_config(HIF_DEVICE *hifDevice, u32 *data); +extern int ar6000_get_core_clock_config(struct hif_device *hifDevice, u32 *data); diff --git a/drivers/staging/ath6kl/os/linux/ioctl.c b/drivers/staging/ath6kl/os/linux/ioctl.c index c650faa28bbb..0daa201c6cca 100644 --- a/drivers/staging/ath6kl/os/linux/ioctl.c +++ b/drivers/staging/ath6kl/os/linux/ioctl.c @@ -1865,7 +1865,7 @@ ar6000_ioctl_setkey(struct ar6_softc *ar, struct ieee80211req_key *ik) int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - HIF_DEVICE *hifDevice = ar->arHifDevice; + struct hif_device *hifDevice = ar->arHifDevice; int ret = 0, param; unsigned int address = 0; unsigned int length = 0; -- cgit v1.2.3 From b52fe09e3309c3d7069cd0e5a3bdb5b4ba45e01f Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Fri, 11 Mar 2011 22:30:01 +0000 Subject: RDMA/cxgb4: Turn on delayed ACK Set the default to on. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/cm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 8b00e6c46f01..65d3fe6cfd5c 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -61,9 +61,9 @@ static char *states[] = { NULL, }; -static int dack_mode; +static int dack_mode = 1; module_param(dack_mode, int, 0644); -MODULE_PARM_DESC(dack_mode, "Delayed ack mode (default=0)"); +MODULE_PARM_DESC(dack_mode, "Delayed ack mode (default=1)"); int c4iw_max_read_depth = 8; module_param(c4iw_max_read_depth, int, 0644); -- cgit v1.2.3 From 294281373999e7fff393c04eb16092a8f00ad5aa Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Fri, 11 Mar 2011 22:30:32 +0000 Subject: RDMA/cxgb4: Remove db_drop_task Unloading iw_cxgb4 can crash due to the unload code trying to use db_drop_task, which is uninitialized. So remove this dead code. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/device.c | 1 - drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index 54fbc1118abe..1a65ee6235bf 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c @@ -368,7 +368,6 @@ static void c4iw_rdev_close(struct c4iw_rdev *rdev) static void c4iw_remove(struct c4iw_dev *dev) { PDBG("%s c4iw_dev %p\n", __func__, dev); - cancel_delayed_work_sync(&dev->db_drop_task); list_del(&dev->entry); if (dev->registered) c4iw_unregister_device(dev); diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index 2fe19ec9ba60..9f6166f59268 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h @@ -176,7 +176,6 @@ struct c4iw_dev { struct idr mmidr; spinlock_t lock; struct list_head entry; - struct delayed_work db_drop_task; struct dentry *debugfs_root; u8 registered; }; -- cgit v1.2.3 From ffc3f7487ff0b32500b319c770475383f6f6efab Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Fri, 11 Mar 2011 22:30:42 +0000 Subject: RDMA/cxgb4: Do CIDX_INC updates every 1/16 CQ depth CQE reaps This avoids the CIDX_INC overflow issue with T4A2 when running kernel RDMA applications. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/t4.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h index 70004425d695..24af12fc8228 100644 --- a/drivers/infiniband/hw/cxgb4/t4.h +++ b/drivers/infiniband/hw/cxgb4/t4.h @@ -507,8 +507,14 @@ static inline void t4_swcq_consume(struct t4_cq *cq) static inline void t4_hwcq_consume(struct t4_cq *cq) { cq->bits_type_ts = cq->queue[cq->cidx].bits_type_ts; - if (++cq->cidx_inc == cq->size) + if (++cq->cidx_inc == (cq->size >> 4)) { + u32 val; + + val = SEINTARM(0) | CIDXINC(cq->cidx_inc) | TIMERREG(7) | + INGRESSQID(cq->cqid); + writel(val, cq->gts); cq->cidx_inc = 0; + } if (++cq->cidx == cq->size) { cq->cidx = 0; cq->gen ^= 1; -- cgit v1.2.3 From a9c7719800ac513b2df14e267d062ec84dc9313e Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Fri, 11 Mar 2011 22:30:11 +0000 Subject: RDMA/cxgb4: Enable on-chip SQ support by default Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/qp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 4f0be25cab1a..70a5a3c646da 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -31,9 +31,9 @@ */ #include "iw_cxgb4.h" -static int ocqp_support; +static int ocqp_support = 1; module_param(ocqp_support, int, 0644); -MODULE_PARM_DESC(ocqp_support, "Support on-chip SQs (default=0)"); +MODULE_PARM_DESC(ocqp_support, "Support on-chip SQs (default=1)"); static void set_state(struct c4iw_qp *qhp, enum c4iw_qp_state state) { -- cgit v1.2.3 From b48f3b9c10d731160f0af5c3028ad57d9c66673b Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Fri, 11 Mar 2011 22:30:21 +0000 Subject: RDMA/cxgb4: Use ULP_MODE_TCPDDP Set the ULP mode for initial RDMA connection setup to the proper DDP mode. This avoids wasting some HW resources while in streaming mode. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/cm.c | 2 ++ drivers/net/cxgb4/t4_msg.h | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 65d3fe6cfd5c..b4d9e4caf3c9 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -482,6 +482,7 @@ static int send_connect(struct c4iw_ep *ep) TX_CHAN(ep->tx_chan) | SMAC_SEL(ep->smac_idx) | DSCP(ep->tos) | + ULP_MODE(ULP_MODE_TCPDDP) | RCV_BUFSIZ(rcv_win>>10); opt2 = RX_CHANNEL(0) | RSS_QUEUE_VALID | RSS_QUEUE(ep->rss_qid); @@ -1274,6 +1275,7 @@ static void accept_cr(struct c4iw_ep *ep, __be32 peer_ip, struct sk_buff *skb, TX_CHAN(ep->tx_chan) | SMAC_SEL(ep->smac_idx) | DSCP(ep->tos) | + ULP_MODE(ULP_MODE_TCPDDP) | RCV_BUFSIZ(rcv_win>>10); opt2 = RX_CHANNEL(0) | RSS_QUEUE_VALID | RSS_QUEUE(ep->rss_qid); diff --git a/drivers/net/cxgb4/t4_msg.h b/drivers/net/cxgb4/t4_msg.h index a550d0c706f3..eb71b8250b91 100644 --- a/drivers/net/cxgb4/t4_msg.h +++ b/drivers/net/cxgb4/t4_msg.h @@ -123,6 +123,7 @@ enum { ULP_MODE_NONE = 0, ULP_MODE_ISCSI = 2, ULP_MODE_RDMA = 4, + ULP_MODE_TCPDDP = 5, ULP_MODE_FCOE = 6, }; -- cgit v1.2.3 From 767fbe8151d1a7cc8a69e52e354e4220a5e804fb Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Fri, 11 Mar 2011 22:30:53 +0000 Subject: RDMA/cxgb4: Dispatch FATAL event on EEH errors This at least kicks the user mode applications that are watching for device events. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/device.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index 1a65ee6235bf..fadb326e41e0 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c @@ -522,8 +522,16 @@ static int c4iw_uld_state_change(void *handle, enum cxgb4_state new_state) case CXGB4_STATE_START_RECOVERY: printk(KERN_INFO MOD "%s: Fatal Error\n", pci_name(dev->rdev.lldi.pdev)); - if (dev->registered) + dev->rdev.flags |= T4_FATAL_ERROR; + if (dev->registered) { + struct ib_event event; + + memset(&event, 0, sizeof event); + event.event = IB_EVENT_DEVICE_FATAL; + event.device = &dev->ibdev; + ib_dispatch_event(&event); c4iw_unregister_device(dev); + } break; case CXGB4_STATE_DETACH: printk(KERN_INFO MOD "%s: Detach\n", -- cgit v1.2.3 From db5d040d7b2d15539d2c84932f93621d9bd482f7 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Fri, 11 Mar 2011 22:29:50 +0000 Subject: RDMA/cxgb4: Debugfs dump_qp() updates - Show whether the SQ is in onchip memory or not. - Dump both SQ and RQ QIDs. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/device.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index fadb326e41e0..e29172c2afcb 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c @@ -87,17 +87,22 @@ static int dump_qp(int id, void *p, void *data) return 1; if (qp->ep) - cc = snprintf(qpd->buf + qpd->pos, space, "qp id %u state %u " + cc = snprintf(qpd->buf + qpd->pos, space, + "qp sq id %u rq id %u state %u onchip %u " "ep tid %u state %u %pI4:%u->%pI4:%u\n", - qp->wq.sq.qid, (int)qp->attr.state, + qp->wq.sq.qid, qp->wq.rq.qid, (int)qp->attr.state, + qp->wq.sq.flags & T4_SQ_ONCHIP, qp->ep->hwtid, (int)qp->ep->com.state, &qp->ep->com.local_addr.sin_addr.s_addr, ntohs(qp->ep->com.local_addr.sin_port), &qp->ep->com.remote_addr.sin_addr.s_addr, ntohs(qp->ep->com.remote_addr.sin_port)); else - cc = snprintf(qpd->buf + qpd->pos, space, "qp id %u state %u\n", - qp->wq.sq.qid, (int)qp->attr.state); + cc = snprintf(qpd->buf + qpd->pos, space, + "qp sq id %u rq id %u state %u onchip %u\n", + qp->wq.sq.qid, qp->wq.rq.qid, + (int)qp->attr.state, + qp->wq.sq.flags & T4_SQ_ONCHIP); if (cc < space) qpd->pos += cc; return 0; -- cgit v1.2.3 From 4634b7945cf0d6a66036ad10c3d658ae4eb39fa0 Mon Sep 17 00:00:00 2001 From: Mitko Haralanov Date: Mon, 28 Feb 2011 13:39:49 +0000 Subject: IB/qib: Set default LE2 value for active cables to 0 For active and far-EQ cables use an LE2 value of 0 for improved SI. Signed-off-by: Mitko Haralanov Signed-off-by: Mike Marciniszyn Signed-off-by: Roland Dreier --- drivers/infiniband/hw/qib/qib_iba7322.c | 13 ++++++++++--- drivers/infiniband/hw/qib/qib_qsfp.h | 2 ++ 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index b01809a82cb0..4a2d21e15a70 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c @@ -5582,9 +5582,16 @@ static void qsfp_7322_event(struct work_struct *work) * even on failure to read cable information. We don't * get here for QME, so IS_QME check not needed here. */ - le2 = (!ret && qd->cache.atten[1] >= qib_long_atten && - !ppd->dd->cspec->r1 && QSFP_IS_CU(qd->cache.tech)) ? - LE2_5m : LE2_DEFAULT; + if (!ret && !ppd->dd->cspec->r1) { + if (QSFP_IS_ACTIVE_FAR(qd->cache.tech)) + le2 = LE2_QME; + else if (qd->cache.atten[1] >= qib_long_atten && + QSFP_IS_CU(qd->cache.tech)) + le2 = LE2_5m; + else + le2 = LE2_DEFAULT; + } else + le2 = LE2_DEFAULT; ibsd_wr_allchans(ppd, 13, (le2 << 7), BMASK(9, 7)); init_txdds_table(ppd, 0); } diff --git a/drivers/infiniband/hw/qib/qib_qsfp.h b/drivers/infiniband/hw/qib/qib_qsfp.h index 19b527bafd57..c109bbdc90ac 100644 --- a/drivers/infiniband/hw/qib/qib_qsfp.h +++ b/drivers/infiniband/hw/qib/qib_qsfp.h @@ -79,6 +79,8 @@ extern const char *const qib_qsfp_devtech[16]; /* Active Equalization includes fiber, copper full EQ, and copper near Eq */ #define QSFP_IS_ACTIVE(tech) ((0xA2FF >> ((tech) >> 4)) & 1) +/* Active Equalization includes fiber, copper full EQ, and copper far Eq */ +#define QSFP_IS_ACTIVE_FAR(tech) ((0x32FF >> ((tech) >> 4)) & 1) /* Attenuation should be valid for copper other than full/near Eq */ #define QSFP_HAS_ATTEN(tech) ((0x4D00 >> ((tech) >> 4)) & 1) /* Length is only valid if technology is "copper" */ -- cgit v1.2.3 From 36b87b419c7616a8aaa9889566d9a9b50689dee1 Mon Sep 17 00:00:00 2001 From: Mitko Haralanov Date: Fri, 4 Mar 2011 18:53:17 +0000 Subject: IB/qib: Fix M_Key field in SubnGet and SubnGetResp MADs Set the M_Key field in SubnGet and SugnGetResp MADs based on correctly interpreting the protection level specified in the M_KeyProtBits field. Signed-off-by: Mitko Haralanov Signed-off-by: Mike Marciniszyn Signed-off-by: Roland Dreier --- drivers/infiniband/hw/qib/qib_mad.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/qib/qib_mad.c b/drivers/infiniband/hw/qib/qib_mad.c index 4b9e11cc561b..8fd3df5bf04d 100644 --- a/drivers/infiniband/hw/qib/qib_mad.c +++ b/drivers/infiniband/hw/qib/qib_mad.c @@ -464,8 +464,9 @@ static int subn_get_portinfo(struct ib_smp *smp, struct ib_device *ibdev, memset(smp->data, 0, sizeof(smp->data)); /* Only return the mkey if the protection field allows it. */ - if (smp->method == IB_MGMT_METHOD_SET || ibp->mkey == smp->mkey || - ibp->mkeyprot == 0) + if (!(smp->method == IB_MGMT_METHOD_GET && + ibp->mkey != smp->mkey && + ibp->mkeyprot == 1)) pip->mkey = ibp->mkey; pip->gid_prefix = ibp->gid_prefix; lid = ppd->lid; -- cgit v1.2.3 From 17e2a542032f3ab735352d1d4b5d2ca3c154158a Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 10 Mar 2011 09:09:47 +0100 Subject: Staging: IIO: DAC: AD5624R: Consistency cleanup - no functional changes Consistently use indio_dev and access macro for devdata Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5624r_spi.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c index 0f97ce02fcdb..a945b18ff843 100644 --- a/drivers/staging/iio/dac/ad5624r_spi.c +++ b/drivers/staging/iio/dac/ad5624r_spi.c @@ -77,7 +77,7 @@ static ssize_t ad5624r_write_dac(struct device *dev, long readin; int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5624r_state *st = indio_dev->dev_data; + struct ad5624r_state *st = iio_dev_get_devdata(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); ret = strict_strtol(buf, 10, &readin); @@ -94,7 +94,7 @@ static ssize_t ad5624r_read_powerdown_mode(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5624r_state *st = indio_dev->dev_data; + struct ad5624r_state *st = iio_dev_get_devdata(indio_dev); char mode[][15] = {"", "1kohm_to_gnd", "100kohm_to_gnd", "three_state"}; @@ -106,7 +106,7 @@ static ssize_t ad5624r_write_powerdown_mode(struct device *dev, const char *buf, size_t len) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5624r_state *st = indio_dev->dev_data; + struct ad5624r_state *st = iio_dev_get_devdata(indio_dev); int ret; if (sysfs_streq(buf, "1kohm_to_gnd")) @@ -126,7 +126,7 @@ static ssize_t ad5624r_read_dac_powerdown(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5624r_state *st = indio_dev->dev_data; + struct ad5624r_state *st = iio_dev_get_devdata(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); return sprintf(buf, "%d\n", @@ -140,7 +140,7 @@ static ssize_t ad5624r_write_dac_powerdown(struct device *dev, long readin; int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5624r_state *st = indio_dev->dev_data; + struct ad5624r_state *st = iio_dev_get_devdata(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); ret = strict_strtol(buf, 10, &readin); @@ -165,8 +165,8 @@ static ssize_t ad5624r_show_scale(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad5624r_state *st = iio_dev_get_devdata(dev_info); + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5624r_state *st = iio_dev_get_devdata(indio_dev); /* Corresponds to Vref / 2^(bits) */ unsigned int scale_uv = (st->vref_mv * 1000) >> st->chip_info->bits; @@ -178,8 +178,8 @@ static ssize_t ad5624r_show_name(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad5624r_state *st = iio_dev_get_devdata(dev_info); + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5624r_state *st = iio_dev_get_devdata(indio_dev); return sprintf(buf, "%s\n", spi_get_device_id(st->us)->name); } -- cgit v1.2.3 From ab42abf33a3efdf754710a0a513c00c40854cd61 Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Fri, 11 Mar 2011 18:29:06 -0600 Subject: staging: tidspbridge: protect dmm_map properly We need to protect not only the dmm_map list, but the individual map_obj's, otherwise, we might be building the scatter-gather list with garbage. So, use the existing proc_lock for that. I observed race conditions which caused kernel panics while running stress tests, also, Tuomas Kulve found it happening quite often in Gumstix Over. This patch fixes those. Cc: Tuomas Kulve Signed-off-by: Felipe Contreras Signed-off-by: Omar Ramirez Luna Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tidspbridge/rmgr/proc.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c index 54f61336d778..c4e5c4e0d71c 100644 --- a/drivers/staging/tidspbridge/rmgr/proc.c +++ b/drivers/staging/tidspbridge/rmgr/proc.c @@ -779,12 +779,14 @@ int proc_begin_dma(void *hprocessor, void *pmpu_addr, u32 ul_size, (u32)pmpu_addr, ul_size, dir); + mutex_lock(&proc_lock); + /* find requested memory are in cached mapping information */ map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size); if (!map_obj) { pr_err("%s: find_containing_mapping failed\n", __func__); status = -EFAULT; - goto err_out; + goto no_map; } if (memory_give_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) { @@ -793,6 +795,8 @@ int proc_begin_dma(void *hprocessor, void *pmpu_addr, u32 ul_size, status = -EFAULT; } +no_map: + mutex_unlock(&proc_lock); err_out: return status; @@ -817,21 +821,24 @@ int proc_end_dma(void *hprocessor, void *pmpu_addr, u32 ul_size, (u32)pmpu_addr, ul_size, dir); + mutex_lock(&proc_lock); + /* find requested memory are in cached mapping information */ map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size); if (!map_obj) { pr_err("%s: find_containing_mapping failed\n", __func__); status = -EFAULT; - goto err_out; + goto no_map; } if (memory_regain_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) { pr_err("%s: InValid address parameters %p %x\n", __func__, pmpu_addr, ul_size); status = -EFAULT; - goto err_out; } +no_map: + mutex_unlock(&proc_lock); err_out: return status; } @@ -1724,9 +1731,8 @@ int proc_un_map(void *hprocessor, void *map_addr, (p_proc_object->bridge_context, va_align, size_align); } - mutex_unlock(&proc_lock); if (status) - goto func_end; + goto unmap_failed; /* * A successful unmap should be followed by removal of map_obj @@ -1735,6 +1741,9 @@ int proc_un_map(void *hprocessor, void *map_addr, */ remove_mapping_information(pr_ctxt, (u32) map_addr, size_align); +unmap_failed: + mutex_unlock(&proc_lock); + func_end: dev_dbg(bridge, "%s: hprocessor: 0x%p map_addr: 0x%p status: 0x%x\n", __func__, hprocessor, map_addr, status); -- cgit v1.2.3 From 570edd3b2337a94b4159aa9ff10e0b96c5a69ec2 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sun, 13 Mar 2011 21:58:47 +0300 Subject: staging: brcm80211: fix memory leaks Free resources before exit. Signed-off-by: Alexander Beregalov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index a6da7268d87a..106627040db0 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -5641,6 +5641,10 @@ static int dhdsdio_download_code_array(struct dhd_bus *bus) unsigned char *ularray; ularray = kmalloc(bus->ramsize, GFP_ATOMIC); + if (!ularray) { + bcmerror = BCME_NOMEM; + goto err; + } /* Upload image to verify downloaded contents. */ offset = 0; memset(ularray, 0xaa, bus->ramsize); @@ -5652,7 +5656,7 @@ static int dhdsdio_download_code_array(struct dhd_bus *bus) DHD_ERROR(("%s: error %d on reading %d membytes" " at 0x%08x\n", __func__, bcmerror, MEMBLOCK, offset)); - goto err; + goto free; } offset += MEMBLOCK; @@ -5666,7 +5670,7 @@ static int dhdsdio_download_code_array(struct dhd_bus *bus) DHD_ERROR(("%s: error %d on reading %d membytes at 0x%08x\n", __func__, bcmerror, sizeof(dlarray) - offset, offset)); - goto err; + goto free; } } @@ -5674,11 +5678,11 @@ static int dhdsdio_download_code_array(struct dhd_bus *bus) DHD_ERROR(("%s: Downloaded image is corrupted.\n", __func__)); ASSERT(0); - goto err; + goto free; } else DHD_ERROR(("%s: Download/Upload/Compare succeeded.\n", __func__)); - +free: kfree(ularray); } #endif /* DHD_DEBUG */ -- cgit v1.2.3 From 819d4eb11605408e0267301d8853367ff82286a5 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sun, 13 Mar 2011 21:58:50 +0300 Subject: staging: ste_rmi4: fix memory leaks Free resources before exit. Signed-off-by: Alexander Beregalov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c index 51b4a79e4b83..d55a8e40318b 100644 --- a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c +++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c @@ -764,8 +764,10 @@ static int synaptics_rmi4_i2c_query_device(struct synaptics_rmi4_data *pdata) (pdata, rfi, &rmi_fd, intr_count); - if (retval < 0) + if (retval < 0) { + kfree(rfi); return retval; + } } break; } -- cgit v1.2.3 From b4c77848600906055c66dd32074d23858e6e200d Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sun, 13 Mar 2011 21:58:48 +0300 Subject: staging: crystalhd: fix memory leaks Free resources before exit. Signed-off-by: Alexander Beregalov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/crystalhd/crystalhd_hw.c | 1 + drivers/staging/crystalhd/crystalhd_lnx.c | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/crystalhd/crystalhd_hw.c b/drivers/staging/crystalhd/crystalhd_hw.c index 153ddbf4247d..13a514dd0f79 100644 --- a/drivers/staging/crystalhd/crystalhd_hw.c +++ b/drivers/staging/crystalhd/crystalhd_hw.c @@ -1965,6 +1965,7 @@ enum BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *hw) } else { BCMLOG_ERR("Insufficient Memory For RX\n"); crystalhd_hw_free_dma_rings(hw); + kfree(rpkt); return BC_STS_INSUFF_RES; } rpkt->desc_mem.pdma_desc_start = mem; diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c index c1ee24c98315..7e0c199f6893 100644 --- a/drivers/staging/crystalhd/crystalhd_lnx.c +++ b/drivers/staging/crystalhd/crystalhd_lnx.c @@ -559,7 +559,7 @@ static int __devinit chd_dec_pci_probe(struct pci_dev *pdev, rc = pci_enable_device(pdev); if (rc) { BCMLOG_ERR("Failed to enable PCI device\n"); - return rc; + goto err; } snprintf(pinfo->name, sizeof(pinfo->name), "crystalhd_pci_e:%d:%d:%d", @@ -570,7 +570,8 @@ static int __devinit chd_dec_pci_probe(struct pci_dev *pdev, if (rc) { BCMLOG_ERR("Failed to setup memory regions.\n"); pci_disable_device(pdev); - return -ENOMEM; + rc = -ENOMEM; + goto err; } pinfo->present = 1; @@ -585,7 +586,8 @@ static int __devinit chd_dec_pci_probe(struct pci_dev *pdev, if (rc) { BCMLOG_ERR("_enable_int err:%d\n", rc); pci_disable_device(pdev); - return -ENODEV; + rc = -ENODEV; + goto err; } /* Set dma mask... */ @@ -598,14 +600,16 @@ static int __devinit chd_dec_pci_probe(struct pci_dev *pdev, } else { BCMLOG_ERR("Unabled to setup DMA %d\n", rc); pci_disable_device(pdev); - return -ENODEV; + rc = -ENODEV; + goto err; } sts = crystalhd_setup_cmd_context(&pinfo->cmds, pinfo); if (sts != BC_STS_SUCCESS) { BCMLOG_ERR("cmd setup :%d\n", sts); pci_disable_device(pdev); - return -ENODEV; + rc = -ENODEV; + goto err; } pci_set_master(pdev); @@ -615,6 +619,10 @@ static int __devinit chd_dec_pci_probe(struct pci_dev *pdev, g_adp_info = pinfo; return 0; + +err: + kfree(pinfo); + return rc; } #ifdef CONFIG_PM -- cgit v1.2.3 From 28344f1a1b271d183e7aa9ab01c72c50c80e1b94 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 10 Mar 2011 22:31:56 +0900 Subject: staging: rtl8192e: Remove unused header Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211_crypt.h | 86 ------------------------------ 1 file changed, 86 deletions(-) delete mode 100644 drivers/staging/rtl8192e/ieee80211_crypt.h (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211_crypt.h b/drivers/staging/rtl8192e/ieee80211_crypt.h deleted file mode 100644 index b58a3bcc0dc0..000000000000 --- a/drivers/staging/rtl8192e/ieee80211_crypt.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Original code based on Host AP (software wireless LAN access point) driver - * for Intersil Prism2/2.5/3. - * - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * - * Copyright (c) 2002-2003, Jouni Malinen - * - * Adaption to a generic IEEE 802.11 stack by James Ketrenos - * - * - * Copyright (c) 2004, Intel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See README and COPYING for - * more details. - */ - -/* - * This file defines the interface to the ieee80211 crypto module. - */ -#ifndef IEEE80211_CRYPT_H -#define IEEE80211_CRYPT_H - -#include - -struct ieee80211_crypto_ops { - const char *name; - - /* init new crypto context (e.g., allocate private data space, - * select IV, etc.); returns NULL on failure or pointer to allocated - * private data on success */ - void * (*init)(int keyidx); - - /* deinitialize crypto context and free allocated private data */ - void (*deinit)(void *priv); - - /* encrypt/decrypt return < 0 on error or >= 0 on success. The return - * value from decrypt_mpdu is passed as the keyidx value for - * decrypt_msdu. skb must have enough head and tail room for the - * encryption; if not, error will be returned; these functions are - * called for all MPDUs (i.e., fragments). - */ - int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv); - int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv); - - /* These functions are called for full MSDUs, i.e. full frames. - * These can be NULL if full MSDU operations are not needed. */ - int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv); - int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len, - void *priv); - - int (*set_key)(void *key, int len, u8 *seq, void *priv); - int (*get_key)(void *key, int len, u8 *seq, void *priv); - - /* procfs handler for printing out key information and possible - * statistics */ - char * (*print_stats)(char *p, void *priv); - - /* maximum number of bytes added by encryption; encrypt buf is - * allocated with extra_prefix_len bytes, copy of in_buf, and - * extra_postfix_len; encrypt need not use all this space, but - * the result must start at the beginning of the buffer and correct - * length must be returned */ - int extra_prefix_len, extra_postfix_len; - - struct module *owner; -}; - -struct ieee80211_crypt_data { - struct list_head list; /* delayed deletion list */ - struct ieee80211_crypto_ops *ops; - void *priv; - atomic_t refcnt; -}; - -int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops); -int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops); -struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name); -void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int); -void ieee80211_crypt_deinit_handler(unsigned long); -void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, - struct ieee80211_crypt_data **crypt); - -#endif -- cgit v1.2.3 From f19dbc0ca8aa8bac415857c14be4252c38b1d925 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 10 Mar 2011 22:32:05 +0900 Subject: staging: rtl8192e: Delete commented code Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 48 +------------------------- 1 file changed, 1 insertion(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index 75aa69917ccd..d8f9c898110e 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -1538,8 +1538,6 @@ typedef struct _bss_ht{ u16 ht_info_len; HT_SPEC_VER ht_spec_ver; - //HT_CAPABILITY_ELE bdHTCapEle; - //HT_INFORMATION_ELE bdHTInfoEle; bool aggregation; bool long_slot_time; @@ -1881,12 +1879,10 @@ struct ieee80211_device { u8 (*rtllib_ap_sec_type)(struct ieee80211_device *ieee); //hw security related -// u8 hwsec_support; //support? u8 hwsec_active; //hw security active. bool is_silent_reset; bool is_roaming; bool ieee_up; - //added by amy bool bSupportRemoteWakeUp; bool actscanning; bool beinretry; @@ -1895,8 +1891,6 @@ struct ieee80211_device { //11n HT below PRT_HIGH_THROUGHPUT pHTInfo; - //struct timer_list SwBwTimer; -// spinlock_t chnlop_spinlock; spinlock_t bw_spinlock; spinlock_t reorder_spinlock; @@ -1912,8 +1906,6 @@ struct ieee80211_device { u8 bTxUseDriverAssingedRate; atomic_t atm_chnlop; atomic_t atm_swbw; -// u8 HTHighestOperaRate; -// u8 HTCurrentOperaRate; // 802.11e and WMM Traffic Stream Info (TX) struct list_head Tx_TS_Admit_List; @@ -2153,9 +2145,7 @@ struct ieee80211_device { //added by amy for AP roaming RT_LINK_DETECT_T LinkDetectInfo; - //added by amy for ps - //RT_POWER_SAVE_CONTROL PowerSaveControl; -//} + /* used if IEEE_SOFTMAC_TX_QUEUE is set */ struct tx_pending_t tx_pending; @@ -2173,12 +2163,6 @@ struct ieee80211_device { struct work_struct wx_sync_scan_wq; struct workqueue_struct *wq; - // Qos related. Added by Annie, 2005-11-01. - //STA_QOS StaQos; - - //u32 STA_EDCA_PARAM[4]; - //CHANNEL_ACCESS_SETTING ChannelAccessSetting; - /* Callback functions */ void (*set_security)(struct net_device *dev, @@ -2269,45 +2253,15 @@ struct ieee80211_device { /* power save mode related */ void (*sta_wake_up) (struct net_device *dev); -// void (*ps_request_tx_ack) (struct net_device *dev); void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl); short (*ps_is_queue_empty) (struct net_device *dev); -#if 0 - /* Typical STA methods */ - int (*handle_auth) (struct net_device * dev, - struct ieee80211_auth * auth); - int (*handle_deauth) (struct net_device * dev, - struct ieee80211_deauth * auth); - int (*handle_action) (struct net_device * dev, - struct ieee80211_action * action, - struct ieee80211_rx_stats * stats); - int (*handle_disassoc) (struct net_device * dev, - struct ieee80211_disassoc * assoc); -#endif int (*handle_beacon) (struct net_device * dev, struct ieee80211_beacon * beacon, struct ieee80211_network * network); -#if 0 - int (*handle_probe_response) (struct net_device * dev, - struct ieee80211_probe_response * resp, - struct ieee80211_network * network); - int (*handle_probe_request) (struct net_device * dev, - struct ieee80211_probe_request * req, - struct ieee80211_rx_stats * stats); -#endif int (*handle_assoc_response) (struct net_device * dev, struct ieee80211_assoc_response_frame * resp, struct ieee80211_network * network); -#if 0 - /* Typical AP methods */ - int (*handle_assoc_request) (struct net_device * dev); - int (*handle_reassoc_request) (struct net_device * dev, - struct ieee80211_reassoc_request * req); -#endif - /* check whether Tx hw resouce available */ short (*check_nic_enough_desc)(struct net_device *dev, int queue_index); //added by wb for HT related -// void (*SwChnlByTimerHandler)(struct net_device *dev, int channel); void (*SetBWModeHandler)(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); -// void (*UpdateHalRATRTableHandler)(struct net_device* dev, u8* pMcsRate); bool (*GetNmodeSupportBySecCfg)(struct net_device* dev); void (*SetWirelessMode)(struct net_device* dev, u8 wireless_mode); bool (*GetHalfNmodeSupportByAPsHandler)(struct net_device* dev); -- cgit v1.2.3 From 9a77bd58f6bfe05df7ec807c22be40fb2dc62e23 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 10 Mar 2011 22:32:16 +0900 Subject: staging: rtl8192e: Store mem_start in priv struct Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 2 ++ drivers/staging/rtl8192e/r8192E_core.c | 38 ++++++++++++++-------------------- 2 files changed, 17 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index c18705ff8160..d59fc0e796da 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -868,6 +868,8 @@ struct rtl8192_tx_ring { typedef struct r8192_priv { struct pci_dev *pdev; + u8 *mem_start; + /* maintain info from eeprom */ short epromtype; u16 eeprom_vid; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 06b35a234b49..8715d2cee8f1 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -210,40 +210,34 @@ u32 read_cam(struct r8192_priv *priv, u8 addr) u8 read_nic_byte(struct r8192_priv *priv, int x) { - struct net_device *dev = priv->ieee80211->dev; - return 0xff&readb((u8*)dev->mem_start +x); + return 0xff & readb(priv->mem_start + x); } u32 read_nic_dword(struct r8192_priv *priv, int x) { - struct net_device *dev = priv->ieee80211->dev; - return readl((u8*)dev->mem_start +x); + return readl(priv->mem_start + x); } u16 read_nic_word(struct r8192_priv *priv, int x) { - struct net_device *dev = priv->ieee80211->dev; - return readw((u8*)dev->mem_start +x); + return readw(priv->mem_start + x); } void write_nic_byte(struct r8192_priv *priv, int x,u8 y) { - struct net_device *dev = priv->ieee80211->dev; - writeb(y,(u8*)dev->mem_start +x); + writeb(y, priv->mem_start + x); udelay(20); } void write_nic_dword(struct r8192_priv *priv, int x,u32 y) { - struct net_device *dev = priv->ieee80211->dev; - writel(y,(u8*)dev->mem_start +x); + writel(y, priv->mem_start + x); udelay(20); } void write_nic_word(struct r8192_priv *priv, int x,u16 y) { - struct net_device *dev = priv->ieee80211->dev; - writew(y,(u8*)dev->mem_start +x); + writew(y, priv->mem_start + x); udelay(20); } @@ -4568,7 +4562,6 @@ static const struct net_device_ops rtl8192_netdev_ops = { static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { - unsigned long ioaddr = 0; struct net_device *dev = NULL; struct r8192_priv *priv= NULL; u8 unit = 0; @@ -4619,16 +4612,15 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, goto fail; } - - ioaddr = (unsigned long)ioremap_nocache( pmem_start, pmem_len); - if( ioaddr == (unsigned long)NULL ){ + priv->mem_start = ioremap_nocache(pmem_start, pmem_len); + if (!priv->mem_start) { RT_TRACE(COMP_ERR,"ioremap failed!\n"); - // release_mem_region( pmem_start, pmem_len ); goto fail1; } - dev->mem_start = ioaddr; // shared mem start - dev->mem_end = ioaddr + pci_resource_len(pdev, 0); // shared mem end + dev->mem_start = (unsigned long) priv->mem_start; + dev->mem_end = (unsigned long) (priv->mem_start + + pci_resource_len(pdev, 0)); /* We disable the RETRY_TIMEOUT register (0x41) to keep * PCI Tx retries from interfering with C3 CPU state */ @@ -4670,8 +4662,8 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, fail1: - if( dev->mem_start != (unsigned long)NULL ){ - iounmap( (void *)dev->mem_start ); + if (priv->mem_start) { + iounmap(priv->mem_start); release_mem_region( pci_resource_start(pdev, 1), pci_resource_len(pdev, 1) ); } @@ -4747,8 +4739,8 @@ static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev) priv->irq=0; } - if( dev->mem_start != (unsigned long)NULL ){ - iounmap( (void *)dev->mem_start ); + if (priv->mem_start) { + iounmap(priv->mem_start); release_mem_region( pci_resource_start(pdev, 1), pci_resource_len(pdev, 1) ); } -- cgit v1.2.3 From a78275349ceca6dea754ddaa0ef85ab636af57c1 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 10 Mar 2011 22:32:26 +0900 Subject: staging: rtl8192e: Delete unused struct members Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 12 ------------ drivers/staging/rtl8192e/r8192E_core.c | 11 +---------- 2 files changed, 1 insertion(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index d8f9c898110e..f9678734ac25 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -880,7 +880,6 @@ struct ieee_ibss_seq { * information for frames received. Not setting these will not cause * any adverse affects. */ struct ieee80211_rx_stats { -#if 1 u32 mac_time[2]; s8 rssi; u8 signal; @@ -895,7 +894,6 @@ struct ieee80211_rx_stats { u32 beacon_time; u8 nic_type; u16 Length; - // u8 DataRate; // In 0.5 Mbps u8 SignalQuality; // in 0-100 index. s32 RecvSignalPower; // Real power in dBm for this packet, no beautification and aggregation. s8 RxPower; // in dBm Translate from PWdB @@ -924,26 +922,16 @@ struct ieee80211_rx_stats { bool bIsAMPDU; bool bFirstMPDU; bool bContainHTC; - bool RxIs40MHzPacket; u32 RxPWDBAll; u8 RxMIMOSignalStrength[4]; // in 0~100 index s8 RxMIMOSignalQuality[2]; bool bPacketMatchBSSID; bool bIsCCK; bool bPacketToSelf; - //added by amy u8* virtual_address; - u16 packetlength; // Total packet length: Must equal to sum of all FragLength - u16 fraglength; // FragLength should equal to PacketLength in non-fragment case - u16 fragoffset; // Data offset for this fragment - u16 ntotalfrag; - bool bisrxaggrsubframe; bool bPacketBeacon; //cosa add for rssi bool bToSelfBA; //cosa add for rssi char cck_adc_pwdb[4]; //cosa add for rx path selection - u16 Seq_Num; -#endif - }; /* IEEE 802.11 requires that STA supports concurrent reception of at least diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 8715d2cee8f1..3877ce57d40a 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -3742,8 +3742,7 @@ static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct sc = le16_to_cpu(hdr->seq_ctl); frag = WLAN_GET_SEQ_FRAG(sc); seq = WLAN_GET_SEQ_SEQ(sc); - //cosa add 04292008 to record the sequence number - pcurrent_stats->Seq_Num = seq; + // // Check whether we should take the previous packet into accounting // @@ -4248,7 +4247,6 @@ rtl8192_record_rxdesc_forlateruse( { ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU; ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU; - //ptarget_stats->Seq_Num = psrc_stats->Seq_Num; } @@ -4486,8 +4484,6 @@ static void rtl8192_rx(struct r8192_priv *priv) if((stats.RxBufShift + stats.RxDrvInfoSize) > 0) stats.bShift = 1; - stats.RxIs40MHzPacket = pDrvInfo->BW; - /* ???? */ TranslateRxSignalStuff819xpci(priv, skb, &stats, pdesc, pDrvInfo); @@ -4509,11 +4505,6 @@ static void rtl8192_rx(struct r8192_priv *priv) unicast_packet = true; } - stats.packetlength = stats.Length-4; - stats.fraglength = stats.packetlength; - stats.fragoffset = 0; - stats.ntotalfrag = 1; - if(!ieee80211_rtl_rx(priv->ieee80211, skb, &stats)){ dev_kfree_skb_any(skb); } else { -- cgit v1.2.3 From db386800613060757d511fa60e11fc5f3c7fd5d5 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 10 Mar 2011 22:32:36 +0900 Subject: staging: rtl8192e: Use better loop counter name Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 3877ce57d40a..9896a5de6b00 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -4310,15 +4310,15 @@ static void rtl8192_tx_resume(struct r8192_priv *priv) struct ieee80211_device *ieee = priv->ieee80211; struct net_device *dev = priv->ieee80211->dev; struct sk_buff *skb; - int queue_index; + int i; - for(queue_index = BK_QUEUE; queue_index < TXCMD_QUEUE;queue_index++) { - while((!skb_queue_empty(&ieee->skb_waitQ[queue_index]))&& - (priv->ieee80211->check_nic_enough_desc(dev,queue_index) > 0)) { + for (i = BK_QUEUE; i < TXCMD_QUEUE; i++) { + while ((!skb_queue_empty(&ieee->skb_waitQ[i])) && + (priv->ieee80211->check_nic_enough_desc(dev, i) > 0)) { /* 1. dequeue the packet from the wait queue */ - skb = skb_dequeue(&ieee->skb_waitQ[queue_index]); + skb = skb_dequeue(&ieee->skb_waitQ[i]); /* 2. tx the packet directly */ - ieee->softmac_data_hard_start_xmit(skb,dev,0/* rate useless now*/); + ieee->softmac_data_hard_start_xmit(skb, dev, 0); } } } -- cgit v1.2.3 From 699d01570230f3830ddf299c5f932e7525c9647a Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 10 Mar 2011 22:32:46 +0900 Subject: staging: rtl8192e: Delete dead code Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_hw.h | 322 +---------------------------------- 1 file changed, 4 insertions(+), 318 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_hw.h b/drivers/staging/rtl8192e/r8192E_hw.h index 7c1cd5d18675..24e7303e56a4 100644 --- a/drivers/staging/rtl8192e/r8192E_hw.h +++ b/drivers/staging/rtl8192e/r8192E_hw.h @@ -21,7 +21,6 @@ #define R8180_HW typedef enum _VERSION_8190{ - // RTL8190 VERSION_8190_BD=0x3, VERSION_8190_BE }VERSION_8190,*PVERSION_8190; @@ -38,15 +37,7 @@ typedef enum _BaseBand_Config_Type{ BaseBand_Config_PHY_REG = 0, //Radio Path A BaseBand_Config_AGC_TAB = 1, //Radio Path B }BaseBand_Config_Type, *PBaseBand_Config_Type; -#if 0 -typedef enum _RT_RF_TYPE_819xU{ - RF_TYPE_MIN = 0, - RF_8225, - RF_8256, - RF_8258, - RF_PSEUDO_11N = 4, -}RT_RF_TYPE_819xU, *PRT_RF_TYPE_819xU; -#endif + #define RTL8187_REQT_READ 0xc0 #define RTL8187_REQT_WRITE 0x40 #define RTL8187_REQ_GET_REGS 0x05 @@ -55,8 +46,6 @@ typedef enum _RT_RF_TYPE_819xU{ #define R8180_MAX_RETRY 255 #define MAX_TX_URB 5 #define MAX_RX_URB 16 -//#define MAX_RX_NORMAL_URB 3 -//#define MAX_RX_COMMAND_URB 2 #define RX_URB_SIZE 9100 #define BB_ANTATTEN_CHAN14 0x0c @@ -68,7 +57,6 @@ typedef enum _RT_RF_TYPE_819xU{ #define BB_HOST_BANG_RW (1<<3) #define BB_HOST_BANG_DATA 1 -//#if (RTL819X_FPGA_VER & RTL819X_FPGA_VIVI_070920) #define RTL8190_EEPROM_ID 0x8129 #define EEPROM_VID 0x02 #define EEPROM_DID 0x04 @@ -103,7 +91,7 @@ typedef enum _RT_RF_TYPE_819xU{ #define EEPROM_TxPwIndex_OFDM_24G 0x3A //0x24~0x26 #define EEPROM_Default_TxPowerLevel 0x10 -//#define EEPROM_ChannelPlan 0x7c //0x7C + #define EEPROM_IC_VER 0x7d //0x7D #define EEPROM_CRC 0x7e //0x7E~0x7F @@ -117,7 +105,7 @@ typedef enum _RT_RF_TYPE_819xU{ #define EEPROM_CID_Pronet 0x7 #define EEPROM_CID_DLINK 0x8 #define EEPROM_CID_WHQL 0xFE //added by sherry for dtm, 20080728 -//#endif + enum _RTL8192Pci_HW { MAC0 = 0x000, MAC1 = 0x001, @@ -485,311 +473,9 @@ enum _RTL8192Pci_HW { DRIVER_RSSI = 0x32c, // Driver tell Firmware current RSSI MCS_TXAGC = 0x340, // MCS AGC CCK_TXAGC = 0x348, // CCK AGC -// IMR = 0x354, // Interrupt Mask Register -// IMR_POLL = 0x360, MacBlkCtrl = 0x403, // Mac block on/off control register - //Cmd9346CR = 0x00e, -//#define Cmd9346CR_9356SEL (1<<4) -#if 0 -/* 0x0006 - 0x0007 - reserved */ - RXFIFOCOUNT = 0x010, - TXFIFOCOUNT = 0x012, - BQREQ = 0x013, -/* 0x0010 - 0x0017 - reserved */ - TSFTR = 0x018, - TLPDA = 0x020, - TNPDA = 0x024, - THPDA = 0x028, - BSSID = 0x02E, - RESP_RATE = 0x034, - CMD = 0x037, -#define CMD_RST_SHIFT 4 -#define CMD_RESERVED_MASK ((1<<1) | (1<<5) | (1<<6) | (1<<7)) -#define CMD_RX_ENABLE_SHIFT 3 -#define CMD_TX_ENABLE_SHIFT 2 -#define CR_RST ((1<< 4)) -#define CR_RE ((1<< 3)) -#define CR_TE ((1<< 2)) -#define CR_MulRW ((1<< 0)) - - INTA = 0x03e, -#endif - -/////////////////// -////////////////// -#if 0 - TX_CONF = 0x040, -#define TX_CONF_HEADER_AUTOICREMENT_SHIFT 30 -#define TX_LOOPBACK_SHIFT 17 -#define TX_LOOPBACK_MAC 1 -#define TX_LOOPBACK_BASEBAND 2 -#define TX_LOOPBACK_NONE 0 -#define TX_LOOPBACK_CONTINUE 3 -#define TX_LOOPBACK_MASK ((1<<17)|(1<<18)) -#define TX_LRLRETRY_SHIFT 0 -#define TX_SRLRETRY_SHIFT 8 -#define TX_NOICV_SHIFT 19 -#define TX_NOCRC_SHIFT 16 -#define TCR_DurProcMode ((1<<30)) -#define TCR_DISReqQsize ((1<<28)) -#define TCR_HWVERID_MASK ((1<<27)|(1<<26)|(1<<25)) -#define TCR_HWVERID_SHIFT 25 -#define TCR_SWPLCPLEN ((1<<24)) -#define TCR_PLCP_LEN TCR_SAT // rtl8180 -#define TCR_MXDMA_MASK ((1<<23)|(1<<22)|(1<<21)) -#define TCR_MXDMA_1024 6 -#define TCR_MXDMA_2048 7 -#define TCR_MXDMA_SHIFT 21 -#define TCR_DISCW ((1<<20)) -#define TCR_ICV ((1<<19)) -#define TCR_LBK ((1<<18)|(1<<17)) -#define TCR_LBK1 ((1<<18)) -#define TCR_LBK0 ((1<<17)) -#define TCR_CRC ((1<<16)) -#define TCR_SRL_MASK ((1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)) -#define TCR_LRL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)) -#define TCR_PROBE_NOTIMESTAMP_SHIFT 29 //rtl8185 - - RX_CONF = 0x044, -#define MAC_FILTER_MASK ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<5) | \ -(1<<12) | (1<<18) | (1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23)) -#define RX_CHECK_BSSID_SHIFT 23 -#define ACCEPT_PWR_FRAME_SHIFT 22 -#define ACCEPT_MNG_FRAME_SHIFT 20 -#define ACCEPT_CTL_FRAME_SHIFT 19 -#define ACCEPT_DATA_FRAME_SHIFT 18 -#define ACCEPT_ICVERR_FRAME_SHIFT 12 -#define ACCEPT_CRCERR_FRAME_SHIFT 5 -#define ACCEPT_BCAST_FRAME_SHIFT 3 -#define ACCEPT_MCAST_FRAME_SHIFT 2 -#define ACCEPT_ALLMAC_FRAME_SHIFT 0 -#define ACCEPT_NICMAC_FRAME_SHIFT 1 -#define RX_FIFO_THRESHOLD_MASK ((1<<13) | (1<<14) | (1<<15)) -#define RX_FIFO_THRESHOLD_SHIFT 13 -#define RX_FIFO_THRESHOLD_128 3 -#define RX_FIFO_THRESHOLD_256 4 -#define RX_FIFO_THRESHOLD_512 5 -#define RX_FIFO_THRESHOLD_1024 6 -#define RX_FIFO_THRESHOLD_NONE 7 -#define RX_AUTORESETPHY_SHIFT 28 -#define MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10)) -#define MAX_RX_DMA_2048 7 -#define MAX_RX_DMA_1024 6 -#define MAX_RX_DMA_SHIFT 10 -#define RCR_ONLYERLPKT ((1<<31)) -#define RCR_CS_SHIFT 29 -#define RCR_CS_MASK ((1<<30) | (1<<29)) -#define RCR_ENMARP ((1<<28)) -#define RCR_CBSSID ((1<<23)) -#define RCR_APWRMGT ((1<<22)) -#define RCR_ADD3 ((1<<21)) -#define RCR_AMF ((1<<20)) -#define RCR_ACF ((1<<19)) -#define RCR_ADF ((1<<18)) -#define RCR_RXFTH ((1<<15)|(1<<14)|(1<<13)) -#define RCR_RXFTH2 ((1<<15)) -#define RCR_RXFTH1 ((1<<14)) -#define RCR_RXFTH0 ((1<<13)) -#define RCR_AICV ((1<<12)) -#define RCR_MXDMA ((1<<10)|(1<< 9)|(1<< 8)) -#define RCR_MXDMA2 ((1<<10)) -#define RCR_MXDMA1 ((1<< 9)) -#define RCR_MXDMA0 ((1<< 8)) -#define RCR_9356SEL ((1<< 6)) -#define RCR_ACRC32 ((1<< 5)) -#define RCR_AB ((1<< 3)) -#define RCR_AM ((1<< 2)) -#define RCR_APM ((1<< 1)) -#define RCR_AAP ((1<< 0)) - - INT_TIMEOUT = 0x048, - - TX_BEACON_RING_ADDR = 0x04c, - -#endif -#if 0 - CONFIG0 = 0x051, -#define CONFIG0_WEP104 ((1<<6)) -#define CONFIG0_LEDGPO_En ((1<<4)) -#define CONFIG0_Aux_Status ((1<<3)) -#define CONFIG0_GL ((1<<1)|(1<<0)) -#define CONFIG0_GL1 ((1<<1)) -#define CONFIG0_GL0 ((1<<0)) - CONFIG1 = 0x052, -#define CONFIG1_LEDS ((1<<7)|(1<<6)) -#define CONFIG1_LEDS1 ((1<<7)) -#define CONFIG1_LEDS0 ((1<<6)) -#define CONFIG1_LWACT ((1<<4)) -#define CONFIG1_MEMMAP ((1<<3)) -#define CONFIG1_IOMAP ((1<<2)) -#define CONFIG1_VPD ((1<<1)) -#define CONFIG1_PMEn ((1<<0)) - CONFIG2 = 0x053, -#define CONFIG2_LCK ((1<<7)) -#define CONFIG2_ANT ((1<<6)) -#define CONFIG2_DPS ((1<<3)) -#define CONFIG2_PAPE_sign ((1<<2)) -#define CONFIG2_PAPE_time ((1<<1)|(1<<0)) -#define CONFIG2_PAPE_time1 ((1<<1)) -#define CONFIG2_PAPE_time0 ((1<<0)) - ANA_PARAM = 0x054, - CONFIG3 = 0x059, -#define CONFIG3_GNTSel ((1<<7)) -#define CONFIG3_PARM_En ((1<<6)) -#define CONFIG3_Magic ((1<<5)) -#define CONFIG3_CardB_En ((1<<3)) -#define CONFIG3_CLKRUN_En ((1<<2)) -#define CONFIG3_FuncRegEn ((1<<1)) -#define CONFIG3_FBtbEn ((1<<0)) -#define CONFIG3_CLKRUN_SHIFT 2 -#define CONFIG3_ANAPARAM_W_SHIFT 6 - CONFIG4 = 0x05a, -#define CONFIG4_VCOPDN ((1<<7)) -#define CONFIG4_PWROFF ((1<<6)) -#define CONFIG4_PWRMGT ((1<<5)) -#define CONFIG4_LWPME ((1<<4)) -#define CONFIG4_LWPTN ((1<<2)) -#define CONFIG4_RFTYPE ((1<<1)|(1<<0)) -#define CONFIG4_RFTYPE1 ((1<<1)) -#define CONFIG4_RFTYPE0 ((1<<0)) - TESTR = 0x05b, -#define TFPC_AC 0x05C - -#define SCR 0x05F - PGSELECT = 0x05e, -#define PGSELECT_PG_SHIFT 0 - SECURITY = 0x05f, -#define SECURITY_WEP_TX_ENABLE_SHIFT 1 -#define SECURITY_WEP_RX_ENABLE_SHIFT 0 -#define SECURITY_ENCRYP_104 1 -#define SECURITY_ENCRYP_SHIFT 4 -#define SECURITY_ENCRYP_MASK ((1<<4)|(1<<5)) - - ANA_PARAM2 = 0x060, - BEACON_INTERVAL = 0x070, -#define BEACON_INTERVAL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)| \ -(1<<6)|(1<<7)|(1<<8)|(1<<9)) - - ATIM_WND = 0x072, -#define ATIM_WND_MASK (0x01FF) - - BCN_INTR_ITV = 0x074, -#define BCN_INTR_ITV_MASK (0x01FF) - - ATIM_INTR_ITV = 0x076, -#define ATIM_INTR_ITV_MASK (0x01FF) - - AckTimeOutReg = 0x079, //ACK timeout register, in unit of 4 us. - PHY_ADR = 0x07c, - PHY_READ = 0x07e, - RFPinsOutput = 0x080, - RFPinsEnable = 0x082, -//Page 0 - RFPinsSelect = 0x084, -#define SW_CONTROL_GPIO 0x400 - RFPinsInput = 0x086, - RF_PARA = 0x088, - RF_TIMING = 0x08c, - GP_ENABLE = 0x090, - GPIO = 0x091, - TX_AGC_CTL = 0x09c, -#define TX_AGC_CTL_PER_PACKET_TXAGC 0x01 -#define TX_AGC_CTL_PERPACKET_GAIN_SHIFT 0 -#define TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT 1 -#define TX_AGC_CTL_FEEDBACK_ANT 2 -#define TXAGC_CTL_PER_PACKET_ANT_SEL 0x02 - OFDM_TXAGC = 0x09e, - ANTSEL = 0x09f, - - - - SIFS = 0x0b4, - DIFS = 0x0b5, - SLOT = 0x0b6, - CW_CONF = 0x0bc, -#define CW_CONF_PERPACKET_RETRY_LIMIT 0x02 -#define CW_CONF_PERPACKET_CW 0x01 -#define CW_CONF_PERPACKET_RETRY_SHIFT 1 -#define CW_CONF_PERPACKET_CW_SHIFT 0 - CW_VAL = 0x0bd, - RATE_FALLBACK = 0x0be, -#define MAX_RESP_RATE_SHIFT 4 -#define MIN_RESP_RATE_SHIFT 0 -#define RATE_FALLBACK_CTL_ENABLE 0x80 -#define RATE_FALLBACK_CTL_AUTO_STEP0 0x00 - ACM_CONTROL = 0x0BF, // ACM Control Registe -//---------------------------------------------------------------------------- -// 8187B ACM_CONTROL bits (Offset 0xBF, 1 Byte) -//---------------------------------------------------------------------------- -#define VOQ_ACM_EN (0x01 << 7) //BIT7 -#define VIQ_ACM_EN (0x01 << 6) //BIT6 -#define BEQ_ACM_EN (0x01 << 5) //BIT5 -#define ACM_HW_EN (0x01 << 4) //BIT4 -#define TXOPSEL (0x01 << 3) //BIT3 -#define VOQ_ACM_CTL (0x01 << 2) //BIT2 // Set to 1 when AC_VO used time reaches or exceeds the admitted time -#define VIQ_ACM_CTL (0x01 << 1) //BIT1 // Set to 1 when AC_VI used time reaches or exceeds the admitted time -#define BEQ_ACM_CTL (0x01 << 0) //BIT0 // Set to 1 when AC_BE used time reaches or exceeds the admitted time - CONFIG5 = 0x0D8, -#define CONFIG5_TX_FIFO_OK ((1<<7)) -#define CONFIG5_RX_FIFO_OK ((1<<6)) -#define CONFIG5_CALON ((1<<5)) -#define CONFIG5_EACPI ((1<<2)) -#define CONFIG5_LANWake ((1<<1)) -#define CONFIG5_PME_STS ((1<<0)) - TX_DMA_POLLING = 0x0fd, -#define TX_DMA_POLLING_BEACON_SHIFT 7 -#define TX_DMA_POLLING_HIPRIORITY_SHIFT 6 -#define TX_DMA_POLLING_NORMPRIORITY_SHIFT 5 -#define TX_DMA_POLLING_LOWPRIORITY_SHIFT 4 -#define TX_DMA_STOP_BEACON_SHIFT 3 -#define TX_DMA_STOP_HIPRIORITY_SHIFT 2 -#define TX_DMA_STOP_NORMPRIORITY_SHIFT 1 -#define TX_DMA_STOP_LOWPRIORITY_SHIFT 0 - CWR = 0x0DC, - RetryCTR = 0x0DE, - INT_MIG = 0x0E2, // Interrupt Migration (0xE2 ~ 0xE3) - TID_AC_MAP = 0x0E8, // TID to AC Mapping Register - ANA_PARAM3 = 0x0EE, - - -//page 1 - Wakeup0 = 0x084, - Wakeup1 = 0x08C, - Wakeup2LD = 0x094, - Wakeup2HD = 0x09C, - Wakeup3LD = 0x0A4, - Wakeup3HD = 0x0AC, - Wakeup4LD = 0x0B4, - Wakeup4HD = 0x0BC, - CRC0 = 0x0C4, - CRC1 = 0x0C6, - CRC2 = 0x0C8, - CRC3 = 0x0CA, - CRC4 = 0x0CC, -/* 0x00CE - 0x00D3 - reserved */ - - RFSW_CTRL = 0x272, // 0x272-0x273. - -/**************************************************************************/ - FER = 0x0F0, - FEMR = 0x0F4, - FPSR = 0x0F8, - FFER = 0x0FC, - - AC_VO_PARAM = 0x0F0, // AC_VO Parameters Record - AC_VI_PARAM = 0x0F4, // AC_VI Parameters Record - AC_BE_PARAM = 0x0F8, // AC_BE Parameters Record - AC_BK_PARAM = 0x0FC, // AC_BK Parameters Record - TALLY_SEL = 0x0fc, -#endif -} -; -//---------------------------------------------------------------------------- -// 818xB AnaParm & AnaParm2 Register -//---------------------------------------------------------------------------- -//#define ANAPARM_ASIC_ON 0x45090658 -//#define ANAPARM2_ASIC_ON 0x727f3f52 +}; #define GPI 0x108 #define GPO 0x109 -- cgit v1.2.3 From de69ba32136a790ee6b4d009df4c0a0b9cc0f6cd Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 10 Mar 2011 22:33:01 +0900 Subject: staging: rtl8192e: Pass priv pointer to proc Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 9896a5de6b00..cd3e2ce2aef7 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -368,8 +368,7 @@ static int proc_get_stats_ap(char *page, char **start, off_t offset, int count, int *eof, void *data) { - struct net_device *dev = data; - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + struct r8192_priv *priv = data; struct ieee80211_device *ieee = priv->ieee80211; struct ieee80211_network *target; int len = 0; @@ -398,8 +397,7 @@ static int proc_get_registers(char *page, char **start, off_t offset, int count, int *eof, void *data) { - struct net_device *dev = data; - struct r8192_priv *priv = ieee80211_priv(dev); + struct r8192_priv *priv = data; int len = 0; int i,n; int max=0xff; @@ -451,8 +449,7 @@ static int proc_get_stats_tx(char *page, char **start, off_t offset, int count, int *eof, void *data) { - struct net_device *dev = data; - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + struct r8192_priv *priv = data; int len = 0; @@ -477,7 +474,7 @@ static int proc_get_stats_tx(char *page, char **start, priv->stats.txbeaconokint, priv->stats.txbeaconerr, priv->stats.txcmdpktokint, - netif_queue_stopped(dev), + netif_queue_stopped(priv->ieee80211->dev), priv->stats.txoverflow, priv->ieee80211->stats.tx_packets, priv->ieee80211->stats.tx_bytes); @@ -492,9 +489,7 @@ static int proc_get_stats_rx(char *page, char **start, off_t offset, int count, int *eof, void *data) { - struct net_device *dev = data; - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - + struct r8192_priv *priv = data; int len = 0; len += snprintf(page + len, count - len, @@ -553,7 +548,7 @@ static void rtl8192_proc_init_one(struct r8192_priv *priv) return; } e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_stats_rx, dev); + priv->dir_dev, proc_get_stats_rx, priv); if (!e) { RT_TRACE(COMP_ERR,"Unable to initialize " @@ -563,7 +558,7 @@ static void rtl8192_proc_init_one(struct r8192_priv *priv) e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_stats_tx, dev); + priv->dir_dev, proc_get_stats_tx, priv); if (!e) { RT_TRACE(COMP_ERR, "Unable to initialize " @@ -572,7 +567,7 @@ static void rtl8192_proc_init_one(struct r8192_priv *priv) } e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_stats_ap, dev); + priv->dir_dev, proc_get_stats_ap, priv); if (!e) { RT_TRACE(COMP_ERR, "Unable to initialize " @@ -581,7 +576,7 @@ static void rtl8192_proc_init_one(struct r8192_priv *priv) } e = create_proc_read_entry("registers", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_registers, dev); + priv->dir_dev, proc_get_registers, priv); if (!e) { RT_TRACE(COMP_ERR, "Unable to initialize " "/proc/net/rtl8192/%s/registers\n", -- cgit v1.2.3 From 8031aecb2dc4a973792f147ece4e23771d5071d3 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 10 Mar 2011 22:33:11 +0900 Subject: staging: rtl8192e: Remove ifdefs and dead code Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 62 ++------------------------ 1 file changed, 3 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index f9678734ac25..1acaefcd54f2 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -47,25 +47,6 @@ #define IWEVCUSTOM 0x8c02 #endif -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -#ifndef __bitwise -#define __bitwise __attribute__((bitwise)) -#endif -typedef __u16 __le16; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27)) -struct iw_spy_data{ - /* --- Standard spy support --- */ - int spy_number; - u_char spy_address[IW_MAX_SPY][ETH_ALEN]; - struct iw_quality spy_stat[IW_MAX_SPY]; - /* --- Enhanced spy support (event) */ - struct iw_quality spy_thr_low; /* Low threshold */ - struct iw_quality spy_thr_high; /* High threshold */ - u_char spy_thr_under[IW_MAX_SPY]; -}; -#endif -#endif - #ifndef container_of /** * container_of - cast a member of a structure out to the containing structure @@ -370,12 +351,10 @@ enum _ReasonCode{ #define ieee80211_wx_get_scan ieee80211_wx_get_scan_rsl #define ieee80211_wx_set_encode ieee80211_wx_set_encode_rsl #define ieee80211_wx_get_encode ieee80211_wx_get_encode_rsl -#if WIRELESS_EXT >= 18 #define ieee80211_wx_set_mlme ieee80211_wx_set_mlme_rsl #define ieee80211_wx_set_auth ieee80211_wx_set_auth_rsl #define ieee80211_wx_set_encode_ext ieee80211_wx_set_encode_ext_rsl #define ieee80211_wx_get_encode_ext ieee80211_wx_get_encode_ext_rsl -#endif typedef struct ieee_param { @@ -408,15 +387,6 @@ typedef struct ieee_param { }ieee_param; -#if WIRELESS_EXT < 17 -#define IW_QUAL_QUAL_INVALID 0x10 -#define IW_QUAL_LEVEL_INVALID 0x20 -#define IW_QUAL_NOISE_INVALID 0x40 -#define IW_QUAL_QUAL_UPDATED 0x1 -#define IW_QUAL_LEVEL_UPDATED 0x2 -#define IW_QUAL_NOISE_UPDATED 0x4 -#endif - // linux under 2.6.9 release may not support it, so modify it for common use #define MSECS(t) msecs_to_jiffies(t) #define msleep_interruptible_rsl msleep_interruptible @@ -1286,7 +1256,7 @@ typedef union _frameqos { #define QOS_OUI_PARAM_SUB_TYPE 1 #define QOS_VERSION_1 1 #define QOS_AIFSN_MIN_VALUE 2 -#if 1 + struct ieee80211_qos_information_element { u8 elementID; u8 length; @@ -1361,7 +1331,7 @@ struct ieee80211_wmm_tspec_elem { u16 surp_band_allow; u16 medium_time; }__attribute__((packed)); -#endif + enum eap_type { EAP_PACKET = 0, EAPOL_START, @@ -1483,15 +1453,13 @@ enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame}; #define MAX_RECEIVE_BUFFER_SIZE 9100 //UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP -//#define UP2AC(up) ((up<3) ? ((up==0)?1:0) : (up>>1)) -#if 1 #define UP2AC(up) ( \ ((up) < 1) ? WME_AC_BE : \ ((up) < 3) ? WME_AC_BK : \ ((up) < 4) ? WME_AC_BE : \ ((up) < 6) ? WME_AC_VI : \ WME_AC_VO) -#endif + //AC Mapping to UP, using in Tx part for selecting the corresponding TX queue #define AC2UP(_ac) ( \ ((_ac) == WME_AC_VO) ? 6 : \ @@ -1545,12 +1513,7 @@ struct ieee80211_network { /* Ensure null-terminated for any debug msgs */ u8 ssid[IW_ESSID_MAX_SIZE + 1]; u8 ssid_len; -#if 1 struct ieee80211_qos_data qos_data; -#else - // Qos related. Added by Annie, 2005-11-01. - BSS_QOS BssQos; -#endif //added by amy for LEAP bool bWithAironetIE; @@ -1617,7 +1580,6 @@ struct ieee80211_network { struct list_head list; }; -#if 1 enum ieee80211_state { /* the card is not linked at all */ @@ -1656,17 +1618,6 @@ enum ieee80211_state { IEEE80211_LINKED_SCANNING, }; -#else -enum ieee80211_state { - IEEE80211_UNINITIALIZED = 0, - IEEE80211_INITIALIZED, - IEEE80211_ASSOCIATING, - IEEE80211_ASSOCIATED, - IEEE80211_AUTHENTICATING, - IEEE80211_AUTHENTICATED, - IEEE80211_SHUTDOWN -}; -#endif #define DEFAULT_MAX_SCAN_AGE (15 * HZ) #define DEFAULT_FTS 2346 @@ -1905,12 +1856,8 @@ struct ieee80211_device { struct list_head Rx_TS_Pending_List; struct list_head Rx_TS_Unused_List; RX_TS_RECORD RxTsRecord[TOTAL_TS_NUM]; -//#ifdef TO_DO_LIST RX_REORDER_ENTRY RxReorderEntry[128]; struct list_head RxReorder_Unused_List; -//#endif - // Qos related. Added by Annie, 2005-11-01. -// PSTA_QOS pStaQos; u8 ForcedPriority; // Force per-packet priority 1~7. (default: 0, not to force it.) @@ -2096,7 +2043,6 @@ struct ieee80211_device { struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM]; int mgmt_queue_head; int mgmt_queue_tail; -//{ added for rtl819x #define IEEE80211_QUEUE_LIMIT 128 u8 AsocRetryCount; unsigned int hw_header; @@ -2464,7 +2410,6 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee, int ieee80211_wx_get_encode(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *key); -#if WIRELESS_EXT >= 18 int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data* wrqu, char *extra); @@ -2477,7 +2422,6 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee, int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); -#endif int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len); /* ieee80211_softmac.c */ -- cgit v1.2.3 From 45a43a84cdabc1918b9e59c829587fe1be7cee92 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 10 Mar 2011 22:33:20 +0900 Subject: staging: rtl8192e: Simplify rtl819x_ifcheck_resetornot Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 43 ++++++++++++++-------------------- 1 file changed, 18 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index cd3e2ce2aef7..eb956eab8891 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -2971,38 +2971,31 @@ static RESET_TYPE RxCheckStuck(struct r8192_priv *priv) return RESET_TYPE_NORESET; } -static RESET_TYPE -rtl819x_ifcheck_resetornot(struct r8192_priv *priv) +static RESET_TYPE rtl819x_check_reset(struct r8192_priv *priv) { - RESET_TYPE TxResetType = RESET_TYPE_NORESET; - RESET_TYPE RxResetType = RESET_TYPE_NORESET; - RT_RF_POWER_STATE rfState; + RESET_TYPE RxResetType = RESET_TYPE_NORESET; + RT_RF_POWER_STATE rfState; rfState = priv->eRFPowerState; - if( rfState != eRfOff && - /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/ - (priv->ieee80211->iw_mode != IW_MODE_ADHOC)) - { - // If driver is in the status of firmware download failure , driver skips RF initialization and RF is - // in turned off state. Driver should check whether Rx stuck and do silent reset. And - // if driver is in firmware download failure status, driver should initialize RF in the following - // silent reset procedure Emily, 2008.01.21 - - // Driver should not check RX stuck in IBSS mode because it is required to - // set Check BSSID in order to send beacon, however, if check BSSID is - // set, STA cannot hear any packet a all. Emily, 2008.04.12 + if (rfState != eRfOff && (priv->ieee80211->iw_mode != IW_MODE_ADHOC)) { + /* + * If driver is in the status of firmware download failure, + * driver skips RF initialization and RF is in turned off state. + * Driver should check whether Rx stuck and do silent reset. And + * if driver is in firmware download failure status, driver + * should initialize RF in the following silent reset procedure + * + * Driver should not check RX stuck in IBSS mode because it is + * required to set Check BSSID in order to send beacon, however, + * if check BSSID is set, STA cannot hear any packet a all. + */ RxResetType = RxCheckStuck(priv); } - RT_TRACE(COMP_RESET,"%s(): TxResetType is %d, RxResetType is %d\n",__FUNCTION__,TxResetType,RxResetType); - if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL) - return RESET_TYPE_NORMAL; - else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT) - return RESET_TYPE_SILENT; - else - return RESET_TYPE_NORESET; + RT_TRACE(COMP_RESET, "%s(): RxResetType is %d\n", __FUNCTION__, RxResetType); + return RxResetType; } #ifdef ENABLE_IPS @@ -3341,7 +3334,7 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) if (priv->watchdog_check_reset_cnt++ >= 3 && !ieee->is_roaming && priv->watchdog_last_time != 1) { - ResetType = rtl819x_ifcheck_resetornot(priv); + ResetType = rtl819x_check_reset(priv); priv->watchdog_check_reset_cnt = 3; } if(!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL) -- cgit v1.2.3 From 09145962d6fdcecc229e685bc2321bd29fdc94c9 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 10 Mar 2011 22:33:36 +0900 Subject: staging: rtl8192e: Pass ieee80211_device to callbacks Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 14 ++++---- .../staging/rtl8192e/ieee80211/ieee80211_softmac.c | 38 ++++++++++---------- .../rtl8192e/ieee80211/ieee80211_softmac_wx.c | 6 ++-- .../staging/rtl8192e/ieee80211/rtl819x_HTProc.c | 8 ++--- drivers/staging/rtl8192e/r8192E.h | 4 +-- drivers/staging/rtl8192e/r8192E_core.c | 41 +++++++++++----------- drivers/staging/rtl8192e/r819xE_cmdpkt.c | 2 +- drivers/staging/rtl8192e/r819xE_firmware.c | 2 +- drivers/staging/rtl8192e/r819xE_phy.c | 5 +-- drivers/staging/rtl8192e/r819xE_phy.h | 2 +- 10 files changed, 62 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index 1acaefcd54f2..57ff8e55bd63 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -2124,7 +2124,7 @@ struct ieee80211_device { * This fucntion can't sleep. */ int (*softmac_hard_start_xmit)(struct sk_buff *skb, - struct net_device *dev); + struct ieee80211_device *ieee80211); /* used instead of hard_start_xmit (not softmac_hard_start_xmit) * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data @@ -2133,22 +2133,22 @@ struct ieee80211_device { * This function can't sleep. */ void (*softmac_data_hard_start_xmit)(struct sk_buff *skb, - struct net_device *dev,int rate); + struct ieee80211_device *ieee80211, int rate); /* stops the HW queue for DATA frames. Useful to avoid * waste time to TX data frame when we are reassociating * This function can sleep. */ - void (*data_hard_stop)(struct net_device *dev); + void (*data_hard_stop)(struct ieee80211_device *ieee80211); /* OK this is complementar to data_poll_hard_stop */ - void (*data_hard_resume)(struct net_device *dev); + void (*data_hard_resume)(struct ieee80211_device *ieee80211); /* ask to the driver to retune the radio . * This function can sleep. the driver should ensure * the radio has been swithced before return. */ - void (*set_chan)(struct net_device *dev,short ch); + void (*set_chan)(struct ieee80211_device *ieee80211, short ch); /* These are not used if the ieee stack takes care of * scanning (IEEE_SOFTMAC_SCAN feature set). @@ -2182,8 +2182,8 @@ struct ieee80211_device { * stop_send_bacons is NOT guaranteed to be called only * after start_send_beacons. */ - void (*start_send_beacons) (struct net_device *dev); - void (*stop_send_beacons) (struct net_device *dev); + void (*start_send_beacons) (struct ieee80211_device *dev); + void (*stop_send_beacons) (struct ieee80211_device *dev); /* power save mode related */ void (*sta_wake_up) (struct net_device *dev); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index 8d73a7313766..b4fea6f7509e 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -243,7 +243,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee ieee->seq_ctrl[0]++; /* avoid watchdog triggers */ - ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate); + ieee->softmac_data_hard_start_xmit(skb, ieee, ieee->basic_rate); } spin_unlock_irqrestore(&ieee->lock, flags); @@ -268,7 +268,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee * */ skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb); } else { - ieee->softmac_hard_start_xmit(skb,ieee->dev); + ieee->softmac_hard_start_xmit(skb, ieee); } spin_unlock(&ieee->mgmt_tx_lock); } @@ -297,7 +297,7 @@ inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *i ieee->seq_ctrl[0]++; /* avoid watchdog triggers */ - ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate); + ieee->softmac_data_hard_start_xmit(skb, ieee, ieee->basic_rate); }else{ @@ -308,7 +308,7 @@ inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *i else ieee->seq_ctrl[0]++; - ieee->softmac_hard_start_xmit(skb,ieee->dev); + ieee->softmac_hard_start_xmit(skb, ieee); } } @@ -448,7 +448,7 @@ void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee) if (ieee->state == IEEE80211_LINKED) goto out; - ieee->set_chan(ieee->dev, ch); + ieee->set_chan(ieee, ch); #ifdef ENABLE_DOT11D if(channel_map[ch] == 1) #endif @@ -517,7 +517,7 @@ void ieee80211_softmac_scan_wq(struct work_struct *work) #endif if (ieee->scanning == 0 ) goto out; - ieee->set_chan(ieee->dev, ieee->current_network.channel); + ieee->set_chan(ieee, ieee->current_network.channel); #ifdef ENABLE_DOT11D if(channel_map[ieee->current_network.channel] == 1) #endif @@ -568,7 +568,7 @@ void ieee80211_beacons_stop(struct ieee80211_device *ieee) void ieee80211_stop_send_beacons(struct ieee80211_device *ieee) { if(ieee->stop_send_beacons) - ieee->stop_send_beacons(ieee->dev); + ieee->stop_send_beacons(ieee); if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS) ieee80211_beacons_stop(ieee); } @@ -577,7 +577,7 @@ void ieee80211_stop_send_beacons(struct ieee80211_device *ieee) void ieee80211_start_send_beacons(struct ieee80211_device *ieee) { if(ieee->start_send_beacons) - ieee->start_send_beacons(ieee->dev); + ieee->start_send_beacons(ieee); if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS) ieee80211_beacons_start(ieee); } @@ -1390,7 +1390,7 @@ void ieee80211_associate_complete_wq(struct work_struct *work) } if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); + ieee->data_hard_resume(ieee); netif_carrier_on(ieee->dev); } @@ -1414,7 +1414,7 @@ void ieee80211_associate_procedure_wq(struct work_struct *work) down(&ieee->wx_sem); if (ieee->data_hard_stop) - ieee->data_hard_stop(ieee->dev); + ieee->data_hard_stop(ieee); ieee80211_stop_scan(ieee); printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel); @@ -2221,7 +2221,7 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device * }else{ ieee->softmac_data_hard_start_xmit( txb->fragments[i], - ieee->dev,ieee->rate); + ieee, ieee->rate); } } @@ -2244,7 +2244,7 @@ void ieee80211_resume_tx(struct ieee80211_device *ieee) ieee->softmac_data_hard_start_xmit( ieee->tx_pending.txb->fragments[i], - ieee->dev,ieee->rate); + ieee, ieee->rate); ieee->stats.tx_packets++; } } @@ -2294,7 +2294,7 @@ void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee) else ieee->seq_ctrl[0]++; - ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate); + ieee->softmac_data_hard_start_xmit(skb, ieee, ieee->basic_rate); } } if (!ieee->queue_stop && ieee->tx_pending.txb) @@ -2348,13 +2348,13 @@ void ieee80211_start_master_bss(struct ieee80211_device *ieee) memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN); - ieee->set_chan(ieee->dev, ieee->current_network.channel); + ieee->set_chan(ieee, ieee->current_network.channel); ieee->state = IEEE80211_LINKED; ieee->link_change(ieee->dev); notify_wx_assoc_event(ieee); if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); + ieee->data_hard_resume(ieee); netif_carrier_on(ieee->dev); } @@ -2364,7 +2364,7 @@ void ieee80211_start_monitor_mode(struct ieee80211_device *ieee) if(ieee->raw_tx){ if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); + ieee->data_hard_resume(ieee); netif_carrier_on(ieee->dev); } @@ -2467,7 +2467,7 @@ void ieee80211_start_ibss_wq(struct work_struct *work) ieee->state = IEEE80211_LINKED; - ieee->set_chan(ieee->dev, ieee->current_network.channel); + ieee->set_chan(ieee, ieee->current_network.channel); ieee->link_change(ieee->dev); notify_wx_assoc_event(ieee); @@ -2475,7 +2475,7 @@ void ieee80211_start_ibss_wq(struct work_struct *work) ieee80211_start_send_beacons(ieee); if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); + ieee->data_hard_resume(ieee); netif_carrier_on(ieee->dev); up(&ieee->wx_sem); @@ -2540,7 +2540,7 @@ void ieee80211_disassociate(struct ieee80211_device *ieee) ieee80211_reset_queue(ieee); if (ieee->data_hard_stop) - ieee->data_hard_stop(ieee->dev); + ieee->data_hard_stop(ieee); #ifdef ENABLE_DOT11D if(IS_DOT11D_ENABLE(ieee)) Dot11d_Reset(ieee); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c index 1456387795bb..427dfc1d0ffa 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c @@ -316,7 +316,7 @@ void ieee80211_wx_sync_scan_wq(struct work_struct *work) #endif if (ieee->data_hard_stop) - ieee->data_hard_stop(ieee->dev); + ieee->data_hard_stop(ieee); ieee80211_stop_send_beacons(ieee); @@ -360,7 +360,7 @@ void ieee80211_wx_sync_scan_wq(struct work_struct *work) ieee->LinkDetectInfo.NumRecvDataInPeriod= 1; } if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); + ieee->data_hard_resume(ieee); if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER) ieee80211_start_send_beacons(ieee); @@ -479,7 +479,7 @@ out: { if(prev == 0 && ieee->raw_tx){ if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); + ieee->data_hard_resume(ieee); netif_carrier_on(ieee->dev); } diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c index a4415972a60f..5e0b0b55f24f 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c @@ -1716,15 +1716,15 @@ void HTSetConnectBwModeCallback(struct ieee80211_device* ieee) if(pHTInfo->bCurBW40MHz) { if(pHTInfo->CurSTAExtChnlOffset==HT_EXTCHNL_OFFSET_UPPER) - ieee->set_chan(ieee->dev, ieee->current_network.channel+2); + ieee->set_chan(ieee, ieee->current_network.channel+2); else if(pHTInfo->CurSTAExtChnlOffset==HT_EXTCHNL_OFFSET_LOWER) - ieee->set_chan(ieee->dev, ieee->current_network.channel-2); + ieee->set_chan(ieee, ieee->current_network.channel-2); else - ieee->set_chan(ieee->dev, ieee->current_network.channel); + ieee->set_chan(ieee, ieee->current_network.channel); ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40, pHTInfo->CurSTAExtChnlOffset); } else { - ieee->set_chan(ieee->dev, ieee->current_network.channel); + ieee->set_chan(ieee, ieee->current_network.channel); ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); } diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index d59fc0e796da..9ff0548f188e 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -916,8 +916,8 @@ typedef struct r8192_priv struct semaphore rf_sem; //used to lock rf write operation added by wb, modified by david u8 rf_type; /* 0 means 1T2R, 1 means 2T4R */ - short (*rf_set_sens)(struct net_device *dev,short sens); - u8 (*rf_set_chan)(struct net_device *dev,u8 ch); + short (*rf_set_sens)(struct net_device *dev, short sens); + u8 (*rf_set_chan)(struct ieee80211_device *ieee80211, u8 ch); short promisc; /* stats */ struct Stats stats; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index eb956eab8891..c392f19b0bdb 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -96,8 +96,8 @@ static struct pci_driver rtl8192_pci_driver = { #endif }; -static void rtl8192_start_beacon(struct net_device *dev); -static void rtl8192_stop_beacon(struct net_device *dev); +static void rtl8192_start_beacon(struct ieee80211_device *ieee80211); +static void rtl8192_stop_beacon(struct ieee80211_device *ieee80211); static void rtl819x_watchdog_wqcallback(struct work_struct *work); static void rtl8192_irq_rx_tasklet(unsigned long arg); static void rtl8192_irq_tx_tasklet(unsigned long arg); @@ -648,16 +648,16 @@ static void rtl8192_update_msr(struct r8192_priv *priv) write_nic_byte(priv, MSR, msr); } -static void rtl8192_set_chan(struct net_device *dev,short ch) +static void rtl8192_set_chan(struct ieee80211_device *ieee80211, short ch) { - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); priv->chan = ch; /* need to implement rf set channel here WB */ if (priv->rf_set_chan) - priv->rf_set_chan(dev, priv->chan); + priv->rf_set_chan(ieee80211, priv->chan); } static void rtl8192_rx_enable(struct r8192_priv *priv) @@ -803,11 +803,11 @@ static void rtl8192_halt_adapter(struct r8192_priv *priv, bool reset) skb_queue_purge(&priv->skb_queue); } -static void rtl8192_data_hard_stop(struct net_device *dev) +static void rtl8192_data_hard_stop(struct ieee80211_device *ieee80211) { } -static void rtl8192_data_hard_resume(struct net_device *dev) +static void rtl8192_data_hard_resume(struct ieee80211_device *ieee80211) { } @@ -815,9 +815,10 @@ static void rtl8192_data_hard_resume(struct net_device *dev) * this function TX data frames when the ieee80211 stack requires this. * It checks also if we need to stop the ieee tx queue, eventually do it */ -static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate) +static void rtl8192_hard_data_xmit(struct sk_buff *skb, + struct ieee80211_device *ieee80211, int rate) { - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); int ret; cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); u8 queue_index = tcb_desc->queue_index; @@ -831,7 +832,7 @@ static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, return; } - memcpy(skb->cb, &dev, sizeof(dev)); + memcpy(skb->cb, &ieee80211->dev, sizeof(ieee80211->dev)); skb_push(skb, priv->ieee80211->tx_headroom); ret = rtl8192_tx(priv, skb); @@ -851,9 +852,9 @@ static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, * If the ring is full packet are dropped (for data frame the queue * is stopped before this can happen). */ -static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev) +static int rtl8192_hard_start_xmit(struct sk_buff *skb, struct ieee80211_device *ieee80211) { - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); int ret; cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); u8 queue_index = tcb_desc->queue_index; @@ -866,7 +867,7 @@ static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev) } } - memcpy(skb->cb, &dev, sizeof(dev)); + memcpy(skb->cb, &ieee80211->dev, sizeof(ieee80211->dev)); if (queue_index == TXCMD_QUEUE) { rtl819xE_tx_cmd(priv, skb); ret = 0; @@ -876,7 +877,7 @@ static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev) tcb_desc->bTxDisableRateFallBack = 1; tcb_desc->bTxUseDriverAssingedRate = 1; tcb_desc->bTxEnableFwCalcDur = 1; - skb_push(skb, priv->ieee80211->tx_headroom); + skb_push(skb, ieee80211->tx_headroom); ret = rtl8192_tx(priv, skb); if (ret != 0) { kfree_skb(skb); @@ -918,7 +919,7 @@ static void rtl8192_tx_isr(struct r8192_priv *priv, int prio) } } -static void rtl8192_stop_beacon(struct net_device *dev) +static void rtl8192_stop_beacon(struct ieee80211_device *ieee80211) { } @@ -1927,8 +1928,8 @@ static void rtl8192_init_priv_variable(struct r8192_priv *priv) priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION; priv->ieee80211->host_encrypt = 1; priv->ieee80211->host_decrypt = 1; - priv->ieee80211->start_send_beacons = rtl8192_start_beacon;//+by david 081107 - priv->ieee80211->stop_send_beacons = rtl8192_stop_beacon;//+by david 081107 + priv->ieee80211->start_send_beacons = rtl8192_start_beacon; + priv->ieee80211->stop_send_beacons = rtl8192_stop_beacon; priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit; priv->ieee80211->set_chan = rtl8192_set_chan; priv->ieee80211->link_change = rtl8192_link_change; @@ -2853,9 +2854,9 @@ static void rtl8192_prepare_beacon(unsigned long arg) * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might * be used to stop beacon transmission */ -static void rtl8192_start_beacon(struct net_device *dev) +static void rtl8192_start_beacon(struct ieee80211_device *ieee80211) { - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); struct ieee80211_network *net = &priv->ieee80211->current_network; u16 BcnTimeCfg = 0; u16 BcnCW = 6; @@ -4306,7 +4307,7 @@ static void rtl8192_tx_resume(struct r8192_priv *priv) /* 1. dequeue the packet from the wait queue */ skb = skb_dequeue(&ieee->skb_waitQ[i]); /* 2. tx the packet directly */ - ieee->softmac_data_hard_start_xmit(skb, dev, 0); + ieee->softmac_data_hard_start_xmit(skb, ieee, 0); } } } diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.c b/drivers/staging/rtl8192e/r819xE_cmdpkt.c index d5e1e7ee7c52..a8310c92fd83 100644 --- a/drivers/staging/rtl8192e/r819xE_cmdpkt.c +++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.c @@ -104,7 +104,7 @@ RT_STATUS cmpk_message_handle_tx( *seg_ptr++ = ((i+3)ieee80211->softmac_hard_start_xmit(skb,dev); + priv->ieee80211->softmac_hard_start_xmit(skb, priv->ieee80211); code_virtual_address += frag_length; frag_offset += frag_length; diff --git a/drivers/staging/rtl8192e/r819xE_firmware.c b/drivers/staging/rtl8192e/r819xE_firmware.c index d1da2697cfe7..af99d0edfc88 100644 --- a/drivers/staging/rtl8192e/r819xE_firmware.c +++ b/drivers/staging/rtl8192e/r819xE_firmware.c @@ -96,7 +96,7 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, } tcb_desc->txbuf_size = (u16)i; skb_put(skb, i); - priv->ieee80211->softmac_hard_start_xmit(skb, dev); + priv->ieee80211->softmac_hard_start_xmit(skb, priv->ieee80211); code_virtual_address += frag_length; frag_offset += frag_length; diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c index f0975c617759..338fb04a5f32 100644 --- a/drivers/staging/rtl8192e/r819xE_phy.c +++ b/drivers/staging/rtl8192e/r819xE_phy.c @@ -1850,9 +1850,10 @@ void rtl8192_SwChnl_WorkItem(struct r8192_priv *priv) * return: return code show if workitem is scheduled(1:pass, 0:fail) * Note: Delay may be required for RF configuration * ***************************************************************************/ -u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel) +u8 rtl8192_phy_SwChnl(struct ieee80211_device *ieee80211, u8 channel) { - struct r8192_priv *priv = ieee80211_priv(dev); + struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); + RT_TRACE(COMP_PHY, "=====>%s()\n", __FUNCTION__); if(!priv->up) return false; diff --git a/drivers/staging/rtl8192e/r819xE_phy.h b/drivers/staging/rtl8192e/r819xE_phy.h index 46008eee5126..faab39b70ebf 100644 --- a/drivers/staging/rtl8192e/r819xE_phy.h +++ b/drivers/staging/rtl8192e/r819xE_phy.h @@ -117,7 +117,7 @@ void rtl8192_phy_updateInitGain(struct r8192_priv *priv); u8 rtl8192_phy_ConfigRFWithHeaderFile(struct r8192_priv *priv, RF90_RADIO_PATH_E eRFPath); -u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel); +u8 rtl8192_phy_SwChnl(struct ieee80211_device *ieee80211, u8 channel); void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); -- cgit v1.2.3 From d1c580aa706ad49a670af9c7188d1e13c319bd9a Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 10 Mar 2011 22:33:47 +0900 Subject: staging: rtl8192e: Pass ieee80211_device to callbacks Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 12 ++++---- drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c | 2 +- .../staging/rtl8192e/ieee80211/ieee80211_softmac.c | 12 ++++---- .../rtl8192e/ieee80211/ieee80211_softmac_wx.c | 12 ++++---- drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c | 2 +- drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c | 4 +-- drivers/staging/rtl8192e/r8192E.h | 8 ++--- drivers/staging/rtl8192e/r8192E_core.c | 36 ++++++++++------------ drivers/staging/rtl8192e/r8192E_wx.c | 2 +- 9 files changed, 44 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index 57ff8e55bd63..8bbf79d29300 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -1803,7 +1803,7 @@ struct ieee80211_device { u8 LPSDelayCnt; bool bIsAggregateFrame; bool polling; - void (*LeisurePSLeave)(struct net_device *dev); + void (*LeisurePSLeave)(struct ieee80211_device *ieee); #endif #ifdef ENABLE_IPS @@ -1811,10 +1811,10 @@ struct ieee80211_device { bool wx_set_enc; struct semaphore ips_sem; struct work_struct ips_leave_wq; - void (*ieee80211_ips_leave_wq) (struct net_device *dev); - void (*ieee80211_ips_leave)(struct net_device *dev); + void (*ieee80211_ips_leave_wq) (struct ieee80211_device *ieee); + void (*ieee80211_ips_leave)(struct ieee80211_device *ieee); #endif - void (*SetHwRegHandler)(struct net_device *dev,u8 variable,u8* val); + void (*SetHwRegHandler)(struct ieee80211_device *ieee, u8 variable, u8 *val); u8 (*rtllib_ap_sec_type)(struct ieee80211_device *ieee); //hw security related @@ -2099,7 +2099,7 @@ struct ieee80211_device { struct workqueue_struct *wq; /* Callback functions */ - void (*set_security)(struct net_device *dev, + void (*set_security)(struct ieee80211_device *ieee, struct ieee80211_security *sec); /* Used to TX data frame by using txb structs. @@ -2107,7 +2107,7 @@ struct ieee80211_device { * is set the flag IEEE_SOFTMAC_TX_QUEUE */ int (*hard_start_xmit)(struct ieee80211_txb *txb, - struct net_device *dev); + struct ieee80211_device *ieee); int (*reset_port)(struct net_device *dev); int (*is_queue_full) (struct net_device * dev, int pri); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c index 57acb3f21adf..c57a90e41058 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c @@ -1341,7 +1341,7 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) ) { if(ieee->LeisurePSLeave) - ieee->LeisurePSLeave(dev); + ieee->LeisurePSLeave(ieee); } } } diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index b4fea6f7509e..d75c731157ba 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -609,7 +609,7 @@ void ieee80211_rtl_start_scan(struct ieee80211_device *ieee) { #ifdef ENABLE_IPS if(ieee->ieee80211_ips_leave_wq != NULL) - ieee->ieee80211_ips_leave_wq(ieee->dev); + ieee->ieee80211_ips_leave_wq(ieee); #endif #ifdef ENABLE_DOT11D @@ -1408,7 +1408,7 @@ void ieee80211_associate_procedure_wq(struct work_struct *work) ieee->sync_scan_hurryup = 1; #ifdef ENABLE_IPS if(ieee->ieee80211_ips_leave != NULL) - ieee->ieee80211_ips_leave(ieee->dev); + ieee->ieee80211_ips_leave(ieee); #endif down(&ieee->wx_sem); @@ -2522,7 +2522,7 @@ void ieee80211_start_bss(struct ieee80211_device *ieee) if (ieee->state == IEEE80211_NOLINK){ #ifdef ENABLE_IPS if(ieee->ieee80211_ips_leave_wq != NULL) - ieee->ieee80211_ips_leave_wq(ieee->dev); + ieee->ieee80211_ips_leave_wq(ieee); #endif ieee->actscanning = true; ieee80211_rtl_start_scan(ieee); @@ -2933,7 +2933,7 @@ static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value) if (ieee->set_security) - ieee->set_security(ieee->dev, &sec); + ieee->set_security(ieee, &sec); return ret; } @@ -2981,7 +2981,7 @@ static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 v sec.level = SEC_LEVEL_1; } if (ieee->set_security) - ieee->set_security(ieee->dev, &sec); + ieee->set_security(ieee, &sec); break; } @@ -3147,7 +3147,7 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, } done: if (ieee->set_security) - ieee->set_security(ieee->dev, &sec); + ieee->set_security(ieee, &sec); /* Do not reset port if card is in Managed mode since resetting will * generate new IEEE 802.11 authentication which may end up in looping diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c index 427dfc1d0ffa..f82bb7d6203d 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c @@ -70,7 +70,7 @@ int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info } #endif ieee->current_network.channel = fwrq->m; - ieee->set_chan(ieee->dev, ieee->current_network.channel); + ieee->set_chan(ieee, ieee->current_network.channel); if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER) if(ieee->state == IEEE80211_LINKED){ @@ -307,7 +307,7 @@ void ieee80211_wx_sync_scan_wq(struct work_struct *work) #ifdef ENABLE_LPS if (ieee->LeisurePSLeave) { - ieee->LeisurePSLeave(ieee->dev); + ieee->LeisurePSLeave(ieee); } /* notify AP to be in PS mode */ @@ -334,14 +334,14 @@ void ieee80211_wx_sync_scan_wq(struct work_struct *work) if (b40M) { printk("Scan in 20M, back to 40M\n"); if (chan_offset == HT_EXTCHNL_OFFSET_UPPER) - ieee->set_chan(ieee->dev, chan + 2); + ieee->set_chan(ieee, chan + 2); else if (chan_offset == HT_EXTCHNL_OFFSET_LOWER) - ieee->set_chan(ieee->dev, chan - 2); + ieee->set_chan(ieee, chan - 2); else - ieee->set_chan(ieee->dev, chan); + ieee->set_chan(ieee, chan); ieee->SetBWModeHandler(ieee->dev, bandwidth, chan_offset); } else { - ieee->set_chan(ieee->dev, chan); + ieee->set_chan(ieee, chan); } ieee->InitialGainHandler(ieee->dev,IG_Restore); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c index 17535a23c57b..ea715a2d4dc3 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c @@ -935,7 +935,7 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){ ieee80211_softmac_xmit(txb, ieee); }else{ - if ((*ieee->hard_start_xmit)(txb, dev) == 0) { + if ((*ieee->hard_start_xmit)(txb, ieee) == 0) { stats->tx_packets++; stats->tx_bytes += txb->payload_size; return 0; diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c index bb0ff26bd843..ef3a9b202d42 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c @@ -463,7 +463,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee, sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */ if (ieee->set_security) - ieee->set_security(dev, &sec); + ieee->set_security(ieee, &sec); /* Do not reset port if card is in Managed mode since resetting will * generate new IEEE 802.11 authentication which may end up in looping @@ -696,7 +696,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, #endif done: if (ieee->set_security) - ieee->set_security(ieee->dev, &sec); + ieee->set_security(ieee, &sec); if (ieee->reset_on_keychange && ieee->iw_mode != IW_MODE_INFRA && diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 9ff0548f188e..8052d0cf9fb9 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1133,12 +1133,12 @@ RT_STATUS cmpk_message_handle_tx(struct net_device *dev, u8* codevirtualaddress, void IPSEnter(struct r8192_priv *priv); void IPSLeave(struct r8192_priv *priv); void IPSLeave_wq(struct work_struct *work); -void ieee80211_ips_leave_wq(struct net_device *dev); -void ieee80211_ips_leave(struct net_device *dev); +void ieee80211_ips_leave_wq(struct ieee80211_device *ieee80211); +void ieee80211_ips_leave(struct ieee80211_device *ieee80211); #endif #ifdef ENABLE_LPS -void LeisurePSEnter(struct net_device *dev); -void LeisurePSLeave(struct net_device *dev); +void LeisurePSEnter(struct ieee80211_device *ieee80211); +void LeisurePSLeave(struct ieee80211_device *ieee80211); #endif bool NicIFEnableNIC(struct r8192_priv *priv); diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index c392f19b0bdb..efd7e7f0a4f0 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -271,10 +271,9 @@ u8 rtl8192e_ap_sec_type(struct ieee80211_device *ieee) } } -void -rtl8192e_SetHwReg(struct net_device *dev,u8 variable,u8* val) +void rtl8192e_SetHwReg(struct ieee80211_device *ieee80211, u8 variable, u8 *val) { - struct r8192_priv* priv = ieee80211_priv(dev); + struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); switch(variable) { @@ -748,13 +747,12 @@ void PHY_SetRtl8192eRfOff(struct r8192_priv *priv) static void rtl8192_halt_adapter(struct r8192_priv *priv, bool reset) { - struct net_device *dev = priv->ieee80211->dev; int i; u8 OpMode; u32 ulRegRead; OpMode = RT_OP_MODE_NO_LINK; - priv->ieee80211->SetHwRegHandler(dev, HW_VAR_MEDIA_STATUS, &OpMode); + priv->ieee80211->SetHwRegHandler(priv->ieee80211, HW_VAR_MEDIA_STATUS, &OpMode); if (!priv->ieee80211->bSupportRemoteWakeUp) { /* @@ -3071,9 +3069,9 @@ bool MgntActSet_802_11_PowerSaveMode(struct r8192_priv *priv, u8 rtPsMode) } /* Enter the leisure power save mode. */ -void LeisurePSEnter(struct net_device *dev) +void LeisurePSEnter(struct ieee80211_device *ieee80211) { - struct r8192_priv *priv = ieee80211_priv(dev); + struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; if(!((priv->ieee80211->iw_mode == IW_MODE_INFRA) && @@ -3101,9 +3099,9 @@ void LeisurePSEnter(struct net_device *dev) /* Leave leisure power save mode. */ -void LeisurePSLeave(struct net_device *dev) +void LeisurePSLeave(struct ieee80211_device *ieee80211) { - struct r8192_priv *priv = ieee80211_priv(dev); + struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; if (pPSC->bLeisurePs) @@ -3181,9 +3179,9 @@ void IPSLeave_wq(struct work_struct *work) up(&priv->ieee80211->ips_sem); } -void ieee80211_ips_leave_wq(struct net_device *dev) +void ieee80211_ips_leave_wq(struct ieee80211_device *ieee80211) { - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); RT_RF_POWER_STATE rtState; rtState = priv->eRFPowerState; @@ -3202,12 +3200,12 @@ void ieee80211_ips_leave_wq(struct net_device *dev) } } //added by amy 090331 end -void ieee80211_ips_leave(struct net_device *dev) +void ieee80211_ips_leave(struct ieee80211_device *ieee80211) { - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - down(&priv->ieee80211->ips_sem); + struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); + down(&ieee80211->ips_sem); IPSLeave(priv); - up(&priv->ieee80211->ips_sem); + up(&ieee80211->ips_sem); } #endif @@ -3283,11 +3281,11 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) // LeisurePS only work in infra mode. if(bEnterPS) { - LeisurePSEnter(dev); + LeisurePSEnter(priv->ieee80211); } else { - LeisurePSLeave(dev); + LeisurePSLeave(priv->ieee80211); } #endif @@ -3295,7 +3293,7 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) else { #ifdef ENABLE_LPS - LeisurePSLeave(dev); + LeisurePSLeave(priv->ieee80211); #endif } @@ -3449,7 +3447,7 @@ int rtl8192_down(struct net_device *dev) #ifdef ENABLE_LPS //LZM for PS-Poll AID issue. 090429 if(priv->ieee80211->state == IEEE80211_LINKED) - LeisurePSLeave(dev); + LeisurePSLeave(priv->ieee80211); #endif priv->up=0; diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c index f76377602da6..adad91b0b6b1 100644 --- a/drivers/staging/rtl8192e/r8192E_wx.c +++ b/drivers/staging/rtl8192e/r8192E_wx.c @@ -1006,7 +1006,7 @@ static int r8192_wx_adapter_power_status(struct net_device *dev, } else { //LZM for PS-Poll AID issue. 090429 if(priv->ieee80211->state == IEEE80211_LINKED) - LeisurePSLeave(dev); + LeisurePSLeave(priv->ieee80211); priv->ps_force = true; pPSC->bLeisurePs = false; -- cgit v1.2.3 From 7c186cff26eea4a7e2f1c0df9feb3f20aff7c71c Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 10 Mar 2011 22:33:57 +0900 Subject: staging: rtl8192e: Pass ieee80211_device to callbacks Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 8 ++++---- drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c | 2 +- drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index 8bbf79d29300..af6465334036 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -2109,12 +2109,12 @@ struct ieee80211_device { int (*hard_start_xmit)(struct ieee80211_txb *txb, struct ieee80211_device *ieee); - int (*reset_port)(struct net_device *dev); - int (*is_queue_full) (struct net_device * dev, int pri); + int (*reset_port)(struct ieee80211_device *ieee); + int (*is_queue_full) (struct ieee80211_device *ieee, int pri); - int (*handle_management) (struct net_device * dev, + int (*handle_management) (struct ieee80211_device *ieee, struct ieee80211_network * network, u16 type); - int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb); + int (*is_qos_active) (struct ieee80211_device *ieee, struct sk_buff *skb); /* Softmac-generated frames (mamagement) are TXed via this * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index d75c731157ba..7888cfe383f8 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -3157,7 +3157,7 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, if (ieee->reset_on_keychange && ieee->iw_mode != IW_MODE_INFRA && ieee->reset_port && - ieee->reset_port(ieee->dev)) { + ieee->reset_port(ieee)) { printk("reset_port failed\n"); param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED; return -EINVAL; diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c index ef3a9b202d42..6530d9b6829d 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c @@ -472,7 +472,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee, * the callbacks structures used to initialize the 802.11 stack. */ if (ieee->reset_on_keychange && ieee->iw_mode != IW_MODE_INFRA && - ieee->reset_port && ieee->reset_port(dev)) { + ieee->reset_port && ieee->reset_port(ieee)) { printk(KERN_DEBUG "%s: reset_port failed\n", dev->name); return -EINVAL; } @@ -700,7 +700,7 @@ done: if (ieee->reset_on_keychange && ieee->iw_mode != IW_MODE_INFRA && - ieee->reset_port && ieee->reset_port(dev)) { + ieee->reset_port && ieee->reset_port(ieee)) { IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name); return -EINVAL; } -- cgit v1.2.3 From ad44d2a1c57d45e8f0f74f69c02bd59eb46c0656 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 10 Mar 2011 22:34:06 +0900 Subject: staging: rtl8192e: Pass ieee80211_device to callbacks Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 8 ++++---- drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c | 14 +++++++------- drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c | 4 ++-- drivers/staging/rtl8192e/r8192E_core.c | 7 +++---- 4 files changed, 16 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index af6465334036..527c368897c0 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -2165,16 +2165,16 @@ struct ieee80211_device { * The fucntion start_scan should initiate the background * scanning and can't sleep. */ - void (*scan_syncro)(struct net_device *dev); - void (*start_scan)(struct net_device *dev); - void (*stop_scan)(struct net_device *dev); + void (*scan_syncro)(struct ieee80211_device *ieee80211); + void (*start_scan)(struct ieee80211_device *ieee80211); + void (*stop_scan)(struct ieee80211_device *ieee80211); /* indicate the driver that the link state is changed * for example it may indicate the card is associated now. * Driver might be interested in this to apply RX filter * rules or simply light the LINK led */ - void (*link_change)(struct net_device *dev); + void (*link_change)(struct ieee80211_device *ieee80211); /* these two function indicates to the HW when to start * and stop to send beacons. This is used when the diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index 7888cfe383f8..92cd71c3217c 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -601,7 +601,7 @@ void ieee80211_stop_scan(struct ieee80211_device *ieee) if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) ieee80211_softmac_stop_scan(ieee); else - ieee->stop_scan(ieee->dev); + ieee->stop_scan(ieee); } /* called with ieee->lock held */ @@ -627,7 +627,7 @@ void ieee80211_rtl_start_scan(struct ieee80211_device *ieee) queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0); } }else - ieee->start_scan(ieee->dev); + ieee->start_scan(ieee); } @@ -647,7 +647,7 @@ void ieee80211_start_scan_syncro(struct ieee80211_device *ieee) if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) ieee80211_softmac_scan_syncro(ieee); else - ieee->scan_syncro(ieee->dev); + ieee->scan_syncro(ieee); } @@ -1378,7 +1378,7 @@ void ieee80211_associate_complete_wq(struct work_struct *work) ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1; ieee->LinkDetectInfo.NumRecvDataInPeriod= 1; } - ieee->link_change(ieee->dev); + ieee->link_change(ieee); if(ieee->is_silent_reset == 0){ printk("============>normal associate\n"); notify_wx_assoc_event(ieee); @@ -2350,7 +2350,7 @@ void ieee80211_start_master_bss(struct ieee80211_device *ieee) ieee->set_chan(ieee, ieee->current_network.channel); ieee->state = IEEE80211_LINKED; - ieee->link_change(ieee->dev); + ieee->link_change(ieee); notify_wx_assoc_event(ieee); if (ieee->data_hard_resume) @@ -2468,7 +2468,7 @@ void ieee80211_start_ibss_wq(struct work_struct *work) ieee->state = IEEE80211_LINKED; ieee->set_chan(ieee, ieee->current_network.channel); - ieee->link_change(ieee->dev); + ieee->link_change(ieee); notify_wx_assoc_event(ieee); @@ -2546,7 +2546,7 @@ void ieee80211_disassociate(struct ieee80211_device *ieee) Dot11d_Reset(ieee); #endif ieee->is_set_key = false; - ieee->link_change(ieee->dev); + ieee->link_change(ieee); if (ieee->state == IEEE80211_LINKED || ieee->state == IEEE80211_ASSOCIATING) { ieee->state = IEEE80211_NOLINK; diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c index f82bb7d6203d..fcafe1925a72 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c @@ -321,7 +321,7 @@ void ieee80211_wx_sync_scan_wq(struct work_struct *work) ieee80211_stop_send_beacons(ieee); ieee->state = IEEE80211_LINKED_SCANNING; - ieee->link_change(ieee->dev); + ieee->link_change(ieee); ieee->InitialGainHandler(ieee->dev,IG_Backup); if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT && ieee->pHTInfo->bCurBW40MHz) { b40M = 1; @@ -346,7 +346,7 @@ void ieee80211_wx_sync_scan_wq(struct work_struct *work) ieee->InitialGainHandler(ieee->dev,IG_Restore); ieee->state = IEEE80211_LINKED; - ieee->link_change(ieee->dev); + ieee->link_change(ieee); #ifdef ENABLE_LPS /* Notify AP that I wake up again */ diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index efd7e7f0a4f0..661c904ea8f7 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1464,10 +1464,9 @@ static void rtl8192_pci_resetdescring(struct r8192_priv *priv) } } -static void rtl8192_link_change(struct net_device *dev) +static void rtl8192_link_change(struct ieee80211_device *ieee) { - struct r8192_priv *priv = ieee80211_priv(dev); - struct ieee80211_device* ieee = priv->ieee80211; + struct r8192_priv *priv = ieee80211_priv(ieee->dev); if (ieee->state == IEEE80211_LINKED) { @@ -3322,7 +3321,7 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid); ieee->is_roaming = true; ieee->is_set_key = false; - ieee->link_change(dev); + ieee->link_change(ieee); queue_work(ieee->wq, &ieee->associate_procedure_wq); } } -- cgit v1.2.3 From 1e04ca7adf56e90c3dd3cbbf94936edb94f44d72 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 10 Mar 2011 22:39:50 +0900 Subject: staging: rtl8192e: Pass ieee80211_device to callbacks Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 22 ++++----- drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c | 2 +- .../staging/rtl8192e/ieee80211/ieee80211_softmac.c | 28 ++++++------ .../rtl8192e/ieee80211/ieee80211_softmac_wx.c | 8 ++-- drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c | 2 +- .../staging/rtl8192e/ieee80211/rtl819x_BAProc.c | 2 +- .../staging/rtl8192e/ieee80211/rtl819x_HTProc.c | 16 +++---- drivers/staging/rtl8192e/r8192E_core.c | 52 +++++++++------------- drivers/staging/rtl8192e/r8192E_dm.c | 2 +- drivers/staging/rtl8192e/r819xE_phy.c | 8 ++-- drivers/staging/rtl8192e/r819xE_phy.h | 4 +- 11 files changed, 69 insertions(+), 77 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index 527c368897c0..3ca388152616 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -2186,20 +2186,20 @@ struct ieee80211_device { void (*stop_send_beacons) (struct ieee80211_device *dev); /* power save mode related */ - void (*sta_wake_up) (struct net_device *dev); - void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl); - short (*ps_is_queue_empty) (struct net_device *dev); - int (*handle_beacon) (struct net_device * dev, struct ieee80211_beacon * beacon, struct ieee80211_network * network); - int (*handle_assoc_response) (struct net_device * dev, struct ieee80211_assoc_response_frame * resp, struct ieee80211_network * network); + void (*sta_wake_up) (struct ieee80211_device *ieee80211); + void (*enter_sleep_state) (struct ieee80211_device *ieee80211, u32 th, u32 tl); + short (*ps_is_queue_empty) (struct ieee80211_device *ieee80211); + int (*handle_beacon) (struct ieee80211_device *ieee80211, struct ieee80211_beacon *beacon, struct ieee80211_network *network); + int (*handle_assoc_response) (struct ieee80211_device *ieee80211, struct ieee80211_assoc_response_frame *resp, struct ieee80211_network *network); /* check whether Tx hw resouce available */ - short (*check_nic_enough_desc)(struct net_device *dev, int queue_index); + short (*check_nic_enough_desc)(struct ieee80211_device *ieee80211, int queue_index); //added by wb for HT related - void (*SetBWModeHandler)(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); - bool (*GetNmodeSupportBySecCfg)(struct net_device* dev); - void (*SetWirelessMode)(struct net_device* dev, u8 wireless_mode); - bool (*GetHalfNmodeSupportByAPsHandler)(struct net_device* dev); - void (*InitialGainHandler)(struct net_device *dev, u8 Operation); + void (*SetBWModeHandler)(struct ieee80211_device *ieee80211, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); + bool (*GetNmodeSupportBySecCfg)(struct ieee80211_device *ieee80211); + void (*SetWirelessMode)(struct ieee80211_device *ieee80211, u8 wireless_mode); + bool (*GetHalfNmodeSupportByAPsHandler)(struct ieee80211_device *ieee80211); + void (*InitialGainHandler)(struct ieee80211_device *ieee80211, u8 Operation); /* This must be the last item so that it points to the data * allocated beyond this structure by alloc_ieee80211 */ diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c index c57a90e41058..add015ebba1c 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c @@ -2634,7 +2634,7 @@ static inline void ieee80211_process_probe_response( if (is_beacon(beacon->header.frame_ctl)&&is_same_network(&ieee->current_network, &network, ieee)&&\ (ieee->state == IEEE80211_LINKED)) { if(ieee->handle_beacon != NULL) { - ieee->handle_beacon(ieee->dev,beacon,&ieee->current_network); + ieee->handle_beacon(ieee, beacon, &ieee->current_network); } } } diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index 92cd71c3217c..f6922d40a88a 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -259,8 +259,8 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee ieee->seq_ctrl[0]++; /* check wether the managed packet queued greater than 5 */ - if(!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\ - (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\ + if(!ieee->check_nic_enough_desc(ieee, tcb_desc->queue_index)|| + (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)|| (ieee->queue_stop) ) { /* insert the skb packet to the management queue */ /* as for the completion function, it does not need @@ -1508,11 +1508,11 @@ inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee if(ieee80211_is_54g(ieee->current_network) && (ieee->modulation & IEEE80211_OFDM_MODULATION)){ ieee->rate = 108; - ieee->SetWirelessMode(ieee->dev, IEEE_G); + ieee->SetWirelessMode(ieee, IEEE_G); printk(KERN_INFO"Using G rates\n"); }else{ ieee->rate = 22; - ieee->SetWirelessMode(ieee->dev, IEEE_B); + ieee->SetWirelessMode(ieee, IEEE_B); printk(KERN_INFO"Using B rates\n"); } memset(ieee->dot11HTOperationalRateSet, 0, 16); @@ -1845,13 +1845,13 @@ inline void ieee80211_sta_ps(struct ieee80211_device *ieee) } if(sleep == 1){ if(ieee->sta_sleep == 1){ - ieee->enter_sleep_state(ieee->dev,th,tl); + ieee->enter_sleep_state(ieee, th, tl); } else if(ieee->sta_sleep == 0){ spin_lock(&ieee->mgmt_tx_lock); - if(ieee->ps_is_queue_empty(ieee->dev)){ + if (ieee->ps_is_queue_empty(ieee)) { ieee->sta_sleep = 2; ieee->ack_tx_to_ieee = 1; ieee80211_sta_ps_send_null_frame(ieee,1); @@ -1897,7 +1897,7 @@ void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl) } if(ieee->sta_sleep == 1) - ieee->sta_wake_up(ieee->dev); + ieee->sta_wake_up(ieee); if(nl){ if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING) @@ -1929,7 +1929,7 @@ void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success) /* Null frame with PS bit set */ if(success){ ieee->sta_sleep = 1; - ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl); + ieee->enter_sleep_state(ieee, ieee->ps_th, ieee->ps_tl); } } else {/* 21112005 - tx again null without PS bit if lost */ @@ -2028,7 +2028,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen); } if (ieee->handle_assoc_response != NULL) - ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame*)header, network); + ieee->handle_assoc_response(ieee, (struct ieee80211_assoc_response_frame*)header, network); } ieee80211_associate_complete(ieee); } else { @@ -2072,7 +2072,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, ieee->softmac_stats.rx_auth_rs_ok++; if(!(ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE)) { - if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) + if (!ieee->GetNmodeSupportBySecCfg(ieee)) { // WEP or TKIP encryption if(IsHTHalfNmodeAPs(ieee)) @@ -2091,12 +2091,12 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, /* Dummy wirless mode setting to avoid encryption issue */ if(bSupportNmode) { //N mode setting - ieee->SetWirelessMode(ieee->dev, \ + ieee->SetWirelessMode(ieee, ieee->current_network.mode); }else{ //b/g mode setting /*TODO*/ - ieee->SetWirelessMode(ieee->dev, IEEE_G); + ieee->SetWirelessMode(ieee, IEEE_G); } if (ieee->current_network.mode == IEEE_N_24G && bHalfSupportNmode == true) @@ -2207,7 +2207,7 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device * #else if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) || #endif - (!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\ + (!ieee->check_nic_enough_desc(ieee, queue_index))|| (ieee->queue_stop)) { /* insert the skb packet to the wait queue */ /* as for the completion function, it does not need @@ -2457,7 +2457,7 @@ void ieee80211_start_ibss_wq(struct work_struct *work) // By default, WMM function will be disabled in IBSS mode ieee->current_network.QoS_Enable = 0; - ieee->SetWirelessMode(ieee->dev, IEEE_G); + ieee->SetWirelessMode(ieee, IEEE_G); ieee->current_network.atim_window = 0; ieee->current_network.capability = WLAN_CAPABILITY_IBSS; if(ieee->short_slot) diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c index fcafe1925a72..d8a068e32e5e 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c @@ -322,13 +322,13 @@ void ieee80211_wx_sync_scan_wq(struct work_struct *work) ieee->state = IEEE80211_LINKED_SCANNING; ieee->link_change(ieee); - ieee->InitialGainHandler(ieee->dev,IG_Backup); + ieee->InitialGainHandler(ieee, IG_Backup); if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT && ieee->pHTInfo->bCurBW40MHz) { b40M = 1; chan_offset = ieee->pHTInfo->CurSTAExtChnlOffset; bandwidth = (HT_CHANNEL_WIDTH)ieee->pHTInfo->bCurBW40MHz; printk("Scan in 40M, force to 20M first:%d, %d\n", chan_offset, bandwidth); - ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); + ieee->SetBWModeHandler(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); } ieee80211_start_scan_syncro(ieee); if (b40M) { @@ -339,12 +339,12 @@ void ieee80211_wx_sync_scan_wq(struct work_struct *work) ieee->set_chan(ieee, chan - 2); else ieee->set_chan(ieee, chan); - ieee->SetBWModeHandler(ieee->dev, bandwidth, chan_offset); + ieee->SetBWModeHandler(ieee, bandwidth, chan_offset); } else { ieee->set_chan(ieee, chan); } - ieee->InitialGainHandler(ieee->dev,IG_Restore); + ieee->InitialGainHandler(ieee, IG_Restore); ieee->state = IEEE80211_LINKED; ieee->link_change(ieee); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c index ea715a2d4dc3..995346def24f 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c @@ -330,7 +330,7 @@ void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* s #if 1 - if(!ieee->GetNmodeSupportBySecCfg(ieee->dev)) + if (!ieee->GetNmodeSupportBySecCfg(ieee)) { return; } diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c index 2bfa48c8ab71..b690cbc51362 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c @@ -353,7 +353,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb) pBA->BaTimeoutValue = *pBaTimeoutVal; pBA->BaStartSeqCtrl = *pBaStartSeqCtrl; //for half N mode we only aggregate 1 frame - if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) + if (ieee->GetHalfNmodeSupportByAPsHandler(ieee)) pBA->BaParamSet.field.BufferSize = 1; else pBA->BaParamSet.field.BufferSize = 32; diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c index 5e0b0b55f24f..a2a4fe9dd9da 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c @@ -223,7 +223,7 @@ bool IsHTHalfNmode40Bandwidth(struct ieee80211_device* ieee) retValue = false; else if(pHTInfo->bRegBW40MHz == false) // station supports 40 bw retValue = false; - else if(!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) // station in half n mode + else if (!ieee->GetHalfNmodeSupportByAPsHandler(ieee)) // station in half n mode retValue = false; else if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ChlWidth) // ap support 40 bw retValue = true; @@ -240,7 +240,7 @@ bool IsHTHalfNmodeSGI(struct ieee80211_device* ieee, bool is40MHz) if(pHTInfo->bCurrentHTSupport == false ) // wireless is n mode retValue = false; - else if(!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) // station in half n mode + else if (!ieee->GetHalfNmodeSupportByAPsHandler(ieee)) // station in half n mode retValue = false; else if(is40MHz) // ap support 40 bw { @@ -652,7 +652,7 @@ void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u //HT capability info pCapELE->AdvCoding = 0; // This feature is not supported now!! - if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) + if (ieee->GetHalfNmodeSupportByAPsHandler(ieee)) { pCapELE->ChlWidth = 0; } @@ -705,7 +705,7 @@ void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u // 2008.06.12 // For RTL819X, if pairwisekey = wep/tkip, ap is ralink, we support only MCS0~7. - if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) + if (ieee->GetHalfNmodeSupportByAPsHandler(ieee)) { int i; for(i = 1; i< 16; i++) @@ -993,7 +993,7 @@ u8 HTFilterMCSRate( struct ieee80211_device* ieee, u8* pSupportMCS, u8* pOperate HT_PickMCSRate(ieee, pOperateMCS); // For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7. - if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) + if (ieee->GetHalfNmodeSupportByAPsHandler(ieee)) pOperateMCS[1] = 0; // @@ -1679,7 +1679,7 @@ void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidt return; } //if in half N mode, set to 20M bandwidth please 09.08.2008 WB. - if(Bandwidth==HT_CHANNEL_WIDTH_20_40 && (!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))) + if (Bandwidth==HT_CHANNEL_WIDTH_20_40 && (!ieee->GetHalfNmodeSupportByAPsHandler(ieee))) { // Handle Illegal extention channel offset!! if(ieee->current_network.channel<2 && Offset==HT_EXTCHNL_OFFSET_LOWER) @@ -1722,10 +1722,10 @@ void HTSetConnectBwModeCallback(struct ieee80211_device* ieee) else ieee->set_chan(ieee, ieee->current_network.channel); - ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40, pHTInfo->CurSTAExtChnlOffset); + ieee->SetBWModeHandler(ieee, HT_CHANNEL_WIDTH_20_40, pHTInfo->CurSTAExtChnlOffset); } else { ieee->set_chan(ieee, ieee->current_network.channel); - ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); + ieee->SetBWModeHandler(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); } pHTInfo->bSwBwInProgress = false; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 661c904ea8f7..d1cb5283c9da 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -583,9 +583,9 @@ static void rtl8192_proc_init_one(struct r8192_priv *priv) } } -static short check_nic_enough_desc(struct net_device *dev, int prio) +static short check_nic_enough_desc(struct ieee80211_device *ieee, int prio) { - struct r8192_priv *priv = ieee80211_priv(dev); + struct r8192_priv *priv = ieee80211_priv(ieee->dev); struct rtl8192_tx_ring *ring = &priv->tx_ring[prio]; /* for now we reserve two free descriptor as a safety boundary @@ -1597,11 +1597,11 @@ static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv, } /* handle manage frame frame beacon and probe response */ -static int rtl8192_handle_beacon(struct net_device * dev, +static int rtl8192_handle_beacon(struct ieee80211_device *ieee, struct ieee80211_beacon * beacon, struct ieee80211_network * network) { - struct r8192_priv *priv = ieee80211_priv(dev); + struct r8192_priv *priv = ieee80211_priv(ieee->dev); rtl8192_qos_handle_probe_response(priv,1,network); @@ -1663,11 +1663,11 @@ static int rtl8192_qos_association_resp(struct r8192_priv *priv, } -static int rtl8192_handle_assoc_response(struct net_device *dev, +static int rtl8192_handle_assoc_response(struct ieee80211_device *ieee, struct ieee80211_assoc_response_frame *resp, struct ieee80211_network *network) { - struct r8192_priv *priv = ieee80211_priv(dev); + struct r8192_priv *priv = ieee80211_priv(ieee->dev); rtl8192_qos_association_resp(priv, network); return 0; } @@ -1719,11 +1719,8 @@ static void rtl8192_update_ratr_table(struct r8192_priv* priv) write_nic_byte(priv, UFWP, 1); } -static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev) +static bool GetNmodeSupportBySecCfg8190Pci(struct ieee80211_device *ieee) { - struct r8192_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; - return !(ieee->rtllib_ap_sec_type && (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP))); } @@ -1745,9 +1742,9 @@ static u8 rtl8192_getSupportedWireleeMode(void) return (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B); } -static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode) +static void rtl8192_SetWirelessMode(struct ieee80211_device *ieee, u8 wireless_mode) { - struct r8192_priv *priv = ieee80211_priv(dev); + struct r8192_priv *priv = ieee80211_priv(ieee->dev); u8 bSupportMode = rtl8192_getSupportedWireleeMode(); if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0)) @@ -1787,18 +1784,16 @@ static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode) rtl8192_refresh_supportrate(priv); } -static bool GetHalfNmodeSupportByAPs819xPci(struct net_device* dev) +static bool GetHalfNmodeSupportByAPs819xPci(struct ieee80211_device* ieee) { - struct r8192_priv* priv = ieee80211_priv(dev); - struct ieee80211_device* ieee = priv->ieee80211; - return ieee->bHalfWirelessN24GMode; } -static short rtl8192_is_tx_queue_empty(struct net_device *dev) +static short rtl8192_is_tx_queue_empty(struct ieee80211_device *ieee) { int i=0; - struct r8192_priv *priv = ieee80211_priv(dev); + struct r8192_priv *priv = ieee80211_priv(ieee->dev); + for (i=0; i<=MGNT_QUEUE; i++) { if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) ) @@ -1816,9 +1811,9 @@ static void rtl8192_hw_sleep_down(struct r8192_priv *priv) MgntActSet_RF_State(priv, eRfSleep, RF_CHANGE_BY_PS); } -static void rtl8192_hw_wakeup(struct net_device* dev) +static void rtl8192_hw_wakeup(struct ieee80211_device *ieee) { - struct r8192_priv *priv = ieee80211_priv(dev); + struct r8192_priv *priv = ieee80211_priv(ieee->dev); MgntActSet_RF_State(priv, eRfOn, RF_CHANGE_BY_PS); } @@ -1826,16 +1821,15 @@ static void rtl8192_hw_wakeup_wq (struct work_struct *work) { struct delayed_work *dwork = container_of(work,struct delayed_work,work); struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq); - struct net_device *dev = ieee->dev; - rtl8192_hw_wakeup(dev); + rtl8192_hw_wakeup(ieee); } #define MIN_SLEEP_TIME 50 #define MAX_SLEEP_TIME 10000 -static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl) +static void rtl8192_hw_to_sleep(struct ieee80211_device *ieee, u32 th, u32 tl) { - struct r8192_priv *priv = ieee80211_priv(dev); + struct r8192_priv *priv = ieee80211_priv(ieee->dev); u32 tmp; u32 rb = jiffies; @@ -2658,7 +2652,7 @@ static RT_STATUS rtl8192_adapter_start(struct r8192_priv *priv) write_nic_byte(priv, ACK_TIMEOUT, 0x30); if(priv->ResetProgress == RESET_TYPE_NORESET) - rtl8192_SetWirelessMode(dev, priv->ieee80211->mode); + rtl8192_SetWirelessMode(priv->ieee80211, priv->ieee80211->mode); //----------------------------------------------------------------------------- // Set up security related. 070106, by rcnjko: // 1. Clear all H/W keys. @@ -3055,7 +3049,7 @@ bool MgntActSet_802_11_PowerSaveMode(struct r8192_priv *priv, u8 rtPsMode) if(priv->ieee80211->sta_sleep != 0 && rtPsMode == IEEE80211_PS_DISABLED) { // Notify the AP we awke. - rtl8192_hw_wakeup(priv->ieee80211->dev); + rtl8192_hw_wakeup(priv->ieee80211); priv->ieee80211->sta_sleep = 0; spin_lock(&priv->ieee80211->mgmt_tx_lock); @@ -4294,13 +4288,12 @@ static void TranslateRxSignalStuff819xpci(struct r8192_priv *priv, static void rtl8192_tx_resume(struct r8192_priv *priv) { struct ieee80211_device *ieee = priv->ieee80211; - struct net_device *dev = priv->ieee80211->dev; struct sk_buff *skb; int i; for (i = BK_QUEUE; i < TXCMD_QUEUE; i++) { while ((!skb_queue_empty(&ieee->skb_waitQ[i])) && - (priv->ieee80211->check_nic_enough_desc(dev, i) > 0)) { + (priv->ieee80211->check_nic_enough_desc(ieee, i) > 0)) { /* 1. dequeue the packet from the wait queue */ skb = skb_dequeue(&ieee->skb_waitQ[i]); /* 2. tx the packet directly */ @@ -4313,7 +4306,6 @@ static void rtl8192_irq_tx_tasklet(unsigned long arg) { struct r8192_priv *priv = (struct r8192_priv*) arg; struct rtl8192_tx_ring *mgnt_ring = &priv->tx_ring[MGNT_QUEUE]; - struct net_device *dev = priv->ieee80211->dev; unsigned long flags; /* check if we need to report that the management queue is drained */ @@ -4321,7 +4313,7 @@ static void rtl8192_irq_tx_tasklet(unsigned long arg) if (!skb_queue_len(&mgnt_ring->queue) && priv->ieee80211->ack_tx_to_ieee && - rtl8192_is_tx_queue_empty(dev)) { + rtl8192_is_tx_queue_empty(priv->ieee80211)) { priv->ieee80211->ack_tx_to_ieee = 0; ieee80211_ps_tx_ack(priv->ieee80211, 1); } diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index 974555bd3c6f..68ac73e4c7f0 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -313,7 +313,7 @@ static void dm_check_rate_adaptive(struct r8192_priv *priv) } // For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7. - if(priv->ieee80211->GetHalfNmodeSupportByAPsHandler(priv->ieee80211->dev)) + if(priv->ieee80211->GetHalfNmodeSupportByAPsHandler(priv->ieee80211)) targetRATR &= 0xf00fffff; // diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c index 338fb04a5f32..dfa4e112ef46 100644 --- a/drivers/staging/rtl8192e/r819xE_phy.c +++ b/drivers/staging/rtl8192e/r819xE_phy.c @@ -2125,9 +2125,9 @@ void rtl8192_SetBWModeWorkItem(struct r8192_priv *priv) * Note: I doubt whether SetBWModeInProgress flag is necessary as we can * test whether current work in the queue or not.//do I? * ***************************************************************************/ -void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset) +void rtl8192_SetBWMode(struct ieee80211_device *ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset) { - struct r8192_priv *priv = ieee80211_priv(dev); + struct r8192_priv *priv = ieee80211_priv(ieee->dev); if(priv->SetBWModeInProgress) @@ -2152,11 +2152,11 @@ void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EX } -void InitialGain819xPci(struct net_device *dev, u8 Operation) +void InitialGain819xPci(struct ieee80211_device *ieee, u8 Operation) { #define SCAN_RX_INITIAL_GAIN 0x17 #define POWER_DETECTION_TH 0x08 - struct r8192_priv *priv = ieee80211_priv(dev); + struct r8192_priv *priv = ieee80211_priv(ieee->dev); u32 BitMask; u8 initial_gain; diff --git a/drivers/staging/rtl8192e/r819xE_phy.h b/drivers/staging/rtl8192e/r819xE_phy.h index faab39b70ebf..496e76fbadbc 100644 --- a/drivers/staging/rtl8192e/r819xE_phy.h +++ b/drivers/staging/rtl8192e/r819xE_phy.h @@ -119,13 +119,13 @@ u8 rtl8192_phy_ConfigRFWithHeaderFile(struct r8192_priv *priv, u8 rtl8192_phy_SwChnl(struct ieee80211_device *ieee80211, u8 channel); -void rtl8192_SetBWMode(struct net_device *dev, +void rtl8192_SetBWMode(struct ieee80211_device *ieee80211, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); void rtl8192_SwChnl_WorkItem(struct r8192_priv *priv); void rtl8192_SetBWModeWorkItem(struct r8192_priv *priv); -void InitialGain819xPci(struct net_device *dev, u8 Operation); +void InitialGain819xPci(struct ieee80211_device *ieee, u8 Operation); #endif /* _R819XU_PHY_H */ -- cgit v1.2.3 From eea7205027cdeaafe97ccf3c6df10b7f253af7c3 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 10 Mar 2011 22:40:06 +0900 Subject: staging: rtl8192e: Pass rtl8192_priv to dm functions Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 9 ++++----- drivers/staging/rtl8192e/r8192E_dm.c | 19 ++++++------------- drivers/staging/rtl8192e/r8192E_dm.h | 8 ++++---- 3 files changed, 14 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index d1cb5283c9da..332b2030518e 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -2292,7 +2292,7 @@ static void rtl8192_read_eeprom_info(struct r8192_priv *priv) // 2008/01/16 MH We can only know RF type in the function. So we have to init // DIG RATR table again. - init_rate_adaptive(dev); + init_rate_adaptive(priv); //1 Make a copy for following variables and we can change them if we want @@ -2408,7 +2408,7 @@ static short rtl8192_init(struct r8192_priv *priv) rtl8192_get_eeprom_size(priv); rtl8192_read_eeprom_info(priv); rtl8192_get_channel_map(priv); - init_hal_dm(dev); + init_hal_dm(priv); init_timer(&priv->watch_dog_timer); priv->watch_dog_timer.data = (unsigned long)priv; priv->watch_dog_timer.function = watch_dog_timer_callback; @@ -3228,7 +3228,6 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) { struct delayed_work *dwork = container_of(work,struct delayed_work,work); struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq); - struct net_device *dev = priv->ieee80211->dev; struct ieee80211_device* ieee = priv->ieee80211; RESET_TYPE ResetType = RESET_TYPE_NORESET; bool bBusyTraffic = false; @@ -3239,7 +3238,7 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work) if(!priv->up) return; - hal_dm_watchdog(dev); + hal_dm_watchdog(priv); #ifdef ENABLE_IPS if(ieee->actscanning == false){ if((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == IEEE80211_NOLINK) && @@ -3452,7 +3451,7 @@ int rtl8192_down(struct net_device *dev) rtl8192_irq_disable(priv); rtl8192_cancel_deferred_work(priv); - deinit_hal_dm(dev); + deinit_hal_dm(priv); del_timer_sync(&priv->watch_dog_timer); ieee80211_softmac_stop_protocol(priv->ieee80211,true); diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index 68ac73e4c7f0..4ea50b8c57ca 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -95,16 +95,14 @@ static void dm_fsync_timer_callback(unsigned long data); * Prepare SW resource for HW dynamic mechanism. * This function is only invoked at driver intialization once. */ -void init_hal_dm(struct net_device *dev) +void init_hal_dm(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); - // Undecorated Smoothed Signal Strength, it can utilized to dynamic mechanism. priv->undecorated_smoothed_pwdb = -1; //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. dm_init_dynamic_txpower(priv); - init_rate_adaptive(dev); + init_rate_adaptive(priv); //dm_initialize_txpower_tracking(dev); dm_dig_init(priv); dm_init_edca_turbo(priv); @@ -116,16 +114,13 @@ void init_hal_dm(struct net_device *dev) } -void deinit_hal_dm(struct net_device *dev) +void deinit_hal_dm(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); - dm_deInit_fsync(priv); } -void hal_dm_watchdog(struct net_device *dev) +void hal_dm_watchdog(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); /*Add by amy 2008/05/15 ,porting from windows code.*/ dm_check_rate_adaptive(priv); @@ -154,11 +149,9 @@ void hal_dm_watchdog(struct net_device *dev) * 01/16/2008 MHC RF_Type is assigned in ReadAdapterInfo(). We must call * the function after making sure RF_Type. */ -void init_rate_adaptive(struct net_device * dev) +void init_rate_adaptive(struct r8192_priv *priv) { - - struct r8192_priv *priv = ieee80211_priv(dev); - prate_adaptive pra = (prate_adaptive)&priv->rate_adaptive; + prate_adaptive pra = &priv->rate_adaptive; pra->ratr_state = DM_RATR_STA_MAX; pra->high2low_rssi_thresh_for_ra = RateAdaptiveTH_High; diff --git a/drivers/staging/rtl8192e/r8192E_dm.h b/drivers/staging/rtl8192e/r8192E_dm.h index 306dc367d93c..b5b34eaaee93 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.h +++ b/drivers/staging/rtl8192e/r8192E_dm.h @@ -212,12 +212,12 @@ typedef struct tag_Tx_Config_Cmd_Format extern dig_t dm_digtable; extern DRxPathSel DM_RxPathSelTable; -void init_hal_dm(struct net_device *dev); -void deinit_hal_dm(struct net_device *dev); +void init_hal_dm(struct r8192_priv *priv); +void deinit_hal_dm(struct r8192_priv *priv); -void hal_dm_watchdog(struct net_device *dev); +void hal_dm_watchdog(struct r8192_priv *priv); -void init_rate_adaptive(struct net_device *dev); +void init_rate_adaptive(struct r8192_priv *priv); void dm_txpower_trackingcallback(struct work_struct *work); void dm_rf_pathcheck_workitemcallback(struct work_struct *work); void dm_initialize_txpower_tracking(struct r8192_priv *priv); -- cgit v1.2.3 From 4368607df103e218a0fe3656f88daf49bb35f8cc Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 10 Mar 2011 22:40:15 +0900 Subject: staging: rtl8192e: Pass priv to rtl8192_interrupt Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 332b2030518e..933574c572f3 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -102,7 +102,7 @@ static void rtl819x_watchdog_wqcallback(struct work_struct *work); static void rtl8192_irq_rx_tasklet(unsigned long arg); static void rtl8192_irq_tx_tasklet(unsigned long arg); static void rtl8192_prepare_beacon(unsigned long arg); -static irqreturn_t rtl8192_interrupt(int irq, void *netdev); +static irqreturn_t rtl8192_interrupt(int irq, void *param); static void rtl819xE_tx_cmd(struct r8192_priv *priv, struct sk_buff *skb); static void rtl8192_update_ratr_table(struct r8192_priv *priv); static void rtl8192_restart(struct work_struct *work); @@ -2412,7 +2412,7 @@ static short rtl8192_init(struct r8192_priv *priv) init_timer(&priv->watch_dog_timer); priv->watch_dog_timer.data = (unsigned long)priv; priv->watch_dog_timer.function = watch_dog_timer_callback; - if (request_irq(dev->irq, rtl8192_interrupt, IRQF_SHARED, dev->name, dev)) { + if (request_irq(dev->irq, rtl8192_interrupt, IRQF_SHARED, dev->name, priv)) { printk("Error allocating IRQ %d",dev->irq); return -1; }else{ @@ -4640,8 +4640,8 @@ fail: if(dev){ if (priv->irq) { - free_irq(dev->irq, dev); - dev->irq=0; + free_irq(priv->irq, priv); + priv->irq = 0; } free_ieee80211(dev); } @@ -4702,9 +4702,9 @@ static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev) rtl8192_free_tx_ring(priv, i); if (priv->irq) { - printk("Freeing irq %d\n",dev->irq); - free_irq(dev->irq, dev); - priv->irq=0; + printk("Freeing irq %d\n", priv->irq); + free_irq(priv->irq, priv); + priv->irq = 0; } if (priv->mem_start) { @@ -4754,10 +4754,10 @@ static void __exit rtl8192_pci_module_exit(void) ieee80211_rtl_exit(); } -static irqreturn_t rtl8192_interrupt(int irq, void *netdev) +static irqreturn_t rtl8192_interrupt(int irq, void *param) { - struct net_device *dev = (struct net_device *) netdev; - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); + struct r8192_priv *priv = param; + struct net_device *dev = priv->ieee80211->dev; unsigned long flags; u32 inta; irqreturn_t ret = IRQ_HANDLED; -- cgit v1.2.3 From ef8efe5b2dd70f48efcb5b34b0d5cf73df99b32b Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 10 Mar 2011 22:40:36 +0900 Subject: staging: rtl8192e: Pass priv to firmware download functions Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 4 ++-- drivers/staging/rtl8192e/r8192E_core.c | 2 +- drivers/staging/rtl8192e/r819xE_cmdpkt.c | 2 +- drivers/staging/rtl8192e/r819xE_firmware.c | 24 ++++++++++-------------- 4 files changed, 14 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 8052d0cf9fb9..fc231a068fea 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1108,7 +1108,7 @@ typedef struct r8192_priv struct workqueue_struct *priv_wq; }r8192_priv; -bool init_firmware(struct net_device *dev); +bool init_firmware(struct r8192_priv *priv); u32 read_cam(struct r8192_priv *priv, u8 addr); void write_cam(struct r8192_priv *priv, u8 addr, u32 data); u8 read_nic_byte(struct r8192_priv *priv, int x); @@ -1126,7 +1126,7 @@ void CamResetAllEntry(struct r8192_priv *priv); void EnableHWSecurityConfig8192(struct r8192_priv *priv); void setKey(struct r8192_priv *priv, u8 EntryNo, u8 KeyIndex, u16 KeyType, const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent); -void firmware_init_param(struct net_device *dev); +void firmware_init_param(struct r8192_priv *priv); RT_STATUS cmpk_message_handle_tx(struct net_device *dev, u8* codevirtualaddress, u32 packettype, u32 buffer_len); #ifdef ENABLE_IPS diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 933574c572f3..b29c37fa2ef6 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -2713,7 +2713,7 @@ static RT_STATUS rtl8192_adapter_start(struct r8192_priv *priv) //Firmware download RT_TRACE(COMP_INIT, "Load Firmware!\n"); - bfirmwareok = init_firmware(dev); + bfirmwareok = init_firmware(priv); if(bfirmwareok != true) { rtStatus = RT_STATUS_FAILURE; return rtStatus; diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.c b/drivers/staging/rtl8192e/r819xE_cmdpkt.c index a8310c92fd83..f60396015df8 100644 --- a/drivers/staging/rtl8192e/r819xE_cmdpkt.c +++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.c @@ -53,7 +53,7 @@ RT_STATUS cmpk_message_handle_tx( int i; RT_TRACE(COMP_CMDPKT,"%s(),buffer_len is %d\n",__FUNCTION__,buffer_len); - firmware_init_param(dev); + firmware_init_param(priv); //Fragmentation might be required frag_threshold = pfirmware->cmdpacket_frag_thresold; do { diff --git a/drivers/staging/rtl8192e/r819xE_firmware.c b/drivers/staging/rtl8192e/r819xE_firmware.c index af99d0edfc88..1557d8030ca8 100644 --- a/drivers/staging/rtl8192e/r819xE_firmware.c +++ b/drivers/staging/rtl8192e/r819xE_firmware.c @@ -25,9 +25,8 @@ enum opt_rst_type { OPT_FIRMWARE_RESET = 1, }; -void firmware_init_param(struct net_device *dev) +void firmware_init_param(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); rt_firmware *pfirmware = priv->pFirmware; pfirmware->cmdpacket_frag_thresold = @@ -37,10 +36,10 @@ void firmware_init_param(struct net_device *dev) /* * segment the img and use the ptr and length to remember info on each segment */ -static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, +static bool fw_download_code(struct r8192_priv *priv, u8 *code_virtual_address, u32 buffer_len) { - struct r8192_priv *priv = ieee80211_priv(dev); + struct net_device *dev = priv->ieee80211->dev; bool rt_status = true; u16 frag_threshold; u16 frag_length, frag_offset = 0; @@ -52,7 +51,7 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, cb_desc *tcb_desc; u8 bLastIniPkt; - firmware_init_param(dev); + firmware_init_param(priv); /* Fragmentation might be required */ frag_threshold = pfirmware->cmdpacket_frag_thresold; @@ -113,9 +112,8 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, * register. Switch to CPU register in the begin and switch * back before return */ -static bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev) +static bool CPUcheck_maincodeok_turnonCPU(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); unsigned long timeout; bool rt_status = true; u32 CPU_status = 0; @@ -166,9 +164,8 @@ CPUCheckMainCodeOKAndTurnOnCPU_Fail: return rt_status; } -static bool CPUcheck_firmware_ready(struct net_device *dev) +static bool CPUcheck_firmware_ready(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); unsigned long timeout; bool rt_status = true; u32 CPU_status = 0; @@ -197,9 +194,8 @@ CPUCheckFirmwareReady_Fail: } -bool init_firmware(struct net_device *dev) +bool init_firmware(struct r8192_priv *priv) { - struct r8192_priv *priv = ieee80211_priv(dev); bool rt_status = true; u32 file_length = 0; u8 *mapped_file = NULL; @@ -289,7 +285,7 @@ bool init_firmware(struct net_device *dev) * 3. each skb_buff packet data content will already include * the firmware info and Tx descriptor info */ - rt_status = fw_download_code(dev, mapped_file, file_length); + rt_status = fw_download_code(priv, mapped_file, file_length); if (rt_status != TRUE) goto download_firmware_fail; @@ -314,7 +310,7 @@ bool init_firmware(struct net_device *dev) pfirmware->firmware_status = FW_STATUS_2_MOVE_MAIN_CODE; /* Check Put Code OK and Turn On CPU */ - rt_status = CPUcheck_maincodeok_turnonCPU(dev); + rt_status = CPUcheck_maincodeok_turnonCPU(priv); if (rt_status != TRUE) { RT_TRACE(COMP_FIRMWARE, "CPUcheck_maincodeok_turnonCPU fail!\n"); @@ -329,7 +325,7 @@ bool init_firmware(struct net_device *dev) pfirmware->firmware_status = FW_STATUS_4_MOVE_DATA_CODE; mdelay(1); - rt_status = CPUcheck_firmware_ready(dev); + rt_status = CPUcheck_firmware_ready(priv); if (rt_status != TRUE) { RT_TRACE(COMP_FIRMWARE, "CPUcheck_firmware_ready fail(%d)!\n", -- cgit v1.2.3 From 83970d9ba1768f1b9ad6c154872cbc08f89da062 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 10 Mar 2011 22:40:53 +0900 Subject: staging: rtl8192e: Pass priv to cmdpkt functions Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E.h | 2 +- drivers/staging/rtl8192e/r8192E_dm.c | 3 +- drivers/staging/rtl8192e/r819xE_cmdpkt.c | 58 ++++++++++---------------------- drivers/staging/rtl8192e/r819xE_cmdpkt.h | 2 +- 4 files changed, 20 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index fc231a068fea..0229031d88d7 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -1127,7 +1127,7 @@ void EnableHWSecurityConfig8192(struct r8192_priv *priv); void setKey(struct r8192_priv *priv, u8 EntryNo, u8 KeyIndex, u16 KeyType, const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent); void firmware_init_param(struct r8192_priv *priv); -RT_STATUS cmpk_message_handle_tx(struct net_device *dev, u8* codevirtualaddress, u32 packettype, u32 buffer_len); +RT_STATUS cmpk_message_handle_tx(struct r8192_priv *priv, u8 *codevirtualaddress, u32 packettype, u32 buffer_len); #ifdef ENABLE_IPS void IPSEnter(struct r8192_priv *priv); diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c index 4ea50b8c57ca..688d29b55884 100644 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ b/drivers/staging/rtl8192e/r8192E_dm.c @@ -422,7 +422,6 @@ static const u8 CCKSwingTable_Ch14[CCK_Table_length][8] = { #define FW_Busy_Flag 0x13f static void dm_TXPowerTrackingCallback_TSSI(struct r8192_priv *priv) { - struct net_device *dev = priv->ieee80211->dev; bool bHighpowerstate, viviflag = FALSE; DCMD_TXCMD_T tx_cmd; u8 powerlevelOFDM24G; @@ -452,7 +451,7 @@ static void dm_TXPowerTrackingCallback_TSSI(struct r8192_priv *priv) tx_cmd.Op = TXCMD_SET_TX_PWR_TRACKING; tx_cmd.Length = 4; tx_cmd.Value = Value; - cmpk_message_handle_tx(dev, (u8*)&tx_cmd, DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T)); + cmpk_message_handle_tx(priv, (u8*)&tx_cmd, DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T)); mdelay(1); for(i = 0;i <= 30; i++) diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.c b/drivers/staging/rtl8192e/r819xE_cmdpkt.c index f60396015df8..41dcb9026dd7 100644 --- a/drivers/staging/rtl8192e/r819xE_cmdpkt.c +++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.c @@ -33,14 +33,13 @@ * run time. We do not support message more than one segment now. */ RT_STATUS cmpk_message_handle_tx( - struct net_device *dev, + struct r8192_priv *priv, u8* code_virtual_address, u32 packettype, u32 buffer_len) { - + struct net_device *dev = priv->ieee80211->dev; RT_STATUS rt_status = RT_STATUS_SUCCESS; - struct r8192_priv *priv = ieee80211_priv(dev); u16 frag_threshold; u16 frag_length = 0, frag_offset = 0; rt_firmware *pfirmware = priv->pFirmware; @@ -115,12 +114,8 @@ Failed: return rt_status; } -static void -cmpk_count_txstatistic( - struct net_device *dev, - cmpk_txfb_t *pstx_fb) +static void cmpk_count_txstatistic(struct r8192_priv *priv, cmpk_txfb_t *pstx_fb) { - struct r8192_priv *priv = ieee80211_priv(dev); #ifdef ENABLE_PS RT_RF_POWER_STATE rtState; @@ -163,19 +158,15 @@ cmpk_count_txstatistic( * refer to chapter "TX Feedback Element". We have to read 20 bytes * in the command packet. */ -static void -cmpk_handle_tx_feedback( - struct net_device *dev, - u8 * pmsg) +static void cmpk_handle_tx_feedback(struct r8192_priv *priv, u8 *pmsg) { - struct r8192_priv *priv = ieee80211_priv(dev); cmpk_txfb_t rx_tx_fb; /* */ priv->stats.txfeedback++; memcpy((u8*)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t)); /* Use tx feedback info to count TX statistics. */ - cmpk_count_txstatistic(dev, &rx_tx_fb); + cmpk_count_txstatistic(priv, &rx_tx_fb); } @@ -185,13 +176,9 @@ cmpk_handle_tx_feedback( * ws-07-0063-v06-rtl819x-command-packet-specification-070315.doc. * Please refer to chapter "Interrupt Status Element". */ -static void -cmpk_handle_interrupt_status( - struct net_device *dev, - u8* pmsg) +static void cmpk_handle_interrupt_status(struct r8192_priv *priv, u8 *pmsg) { cmpk_intr_sta_t rx_intr_status; /* */ - struct r8192_priv *priv = ieee80211_priv(dev); DMESG("---> cmpk_Handle_Interrupt_Status()\n"); @@ -244,10 +231,7 @@ cmpk_handle_interrupt_status( * ws-06-0063-rtl8190-command-packet-specification. Please * refer to chapter "Beacon State Element". */ -static void -cmpk_handle_query_config_rx( - struct net_device *dev, - u8* pmsg) +static void cmpk_handle_query_config_rx(struct r8192_priv *priv, u8 *pmsg) { cmpk_query_cfg_t rx_query_cfg; /* */ @@ -277,10 +261,8 @@ cmpk_handle_query_config_rx( * Count aggregated tx status from firmwar of one type rx command * packet element id = RX_TX_STATUS. */ -static void cmpk_count_tx_status( struct net_device *dev, - cmpk_tx_status_t *pstx_status) +static void cmpk_count_tx_status(struct r8192_priv *priv, cmpk_tx_status_t *pstx_status) { - struct r8192_priv *priv = ieee80211_priv(dev); #ifdef ENABLE_PS @@ -309,25 +291,19 @@ static void cmpk_count_tx_status( struct net_device *dev, * Firmware add a new tx feedback status to reduce rx command * packet buffer operation load. */ -static void -cmpk_handle_tx_status( - struct net_device *dev, - u8* pmsg) +static void cmpk_handle_tx_status(struct r8192_priv *priv, u8 *pmsg) { cmpk_tx_status_t rx_tx_sts; /* */ memcpy((void*)&rx_tx_sts, (void*)pmsg, sizeof(cmpk_tx_status_t)); /* 2. Use tx feedback info to count TX statistics. */ - cmpk_count_tx_status(dev, &rx_tx_sts); + cmpk_count_tx_status(priv, &rx_tx_sts); } /* Firmware add a new tx rate history */ -static void -cmpk_handle_tx_rate_history( - struct net_device *dev, - u8* pmsg) +static void cmpk_handle_tx_rate_history(struct r8192_priv *priv, u8 *pmsg) { u8 i; u16 length = sizeof(cmpk_tx_rahis_t); @@ -369,7 +345,7 @@ cmpk_handle_tx_rate_history( * command packet now. Please refer to document * ws-06-0063-rtl8190-command-packet-specification. */ -u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats *pstats) +u32 cmpk_message_handle_rx(struct r8192_priv *priv, struct ieee80211_rx_stats *pstats) { // u32 debug_level = DBG_LOUD; int total_length; @@ -414,28 +390,28 @@ u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats *ps case RX_TX_FEEDBACK: RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_FEEDBACK\n"); - cmpk_handle_tx_feedback (dev, pcmd_buff); + cmpk_handle_tx_feedback(priv, pcmd_buff); cmd_length = CMPK_RX_TX_FB_SIZE; break; case RX_INTERRUPT_STATUS: RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_INTERRUPT_STATUS\n"); - cmpk_handle_interrupt_status(dev, pcmd_buff); + cmpk_handle_interrupt_status(priv, pcmd_buff); cmd_length = sizeof(cmpk_intr_sta_t); break; case BOTH_QUERY_CONFIG: RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():BOTH_QUERY_CONFIG\n"); - cmpk_handle_query_config_rx(dev, pcmd_buff); + cmpk_handle_query_config_rx(priv, pcmd_buff); cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE; break; case RX_TX_STATUS: RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_STATUS\n"); - cmpk_handle_tx_status(dev, pcmd_buff); + cmpk_handle_tx_status(priv, pcmd_buff); cmd_length = CMPK_RX_TX_STS_SIZE; break; @@ -451,7 +427,7 @@ u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats *ps //DbgPrint(" rx tx rate history\r\n"); RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_HISTORY\n"); - cmpk_handle_tx_rate_history(dev, pcmd_buff); + cmpk_handle_tx_rate_history(priv, pcmd_buff); cmd_length = CMPK_TX_RAHIS_SIZE; break; diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.h b/drivers/staging/rtl8192e/r819xE_cmdpkt.h index 8d705ce4da12..312e4f84dedb 100644 --- a/drivers/staging/rtl8192e/r819xE_cmdpkt.h +++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.h @@ -201,7 +201,7 @@ typedef enum tag_command_packet_directories RX_CMD_ELE_MAX }cmpk_element_e; -u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats * pstats); +u32 cmpk_message_handle_rx(struct r8192_priv *priv, struct ieee80211_rx_stats *pstats); #endif -- cgit v1.2.3 From f0dee9f26c31363f43a643a36f1de70a073bca0e Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 10 Mar 2011 22:41:06 +0900 Subject: staging: rtl8192e: Don't copy dev pointer to skb Signed-off-by: Mike McCormack Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 3 --- drivers/staging/rtl8192e/r819xE_cmdpkt.c | 2 -- drivers/staging/rtl8192e/r819xE_firmware.c | 2 -- 3 files changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index b29c37fa2ef6..58d800f1b5ee 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -830,8 +830,6 @@ static void rtl8192_hard_data_xmit(struct sk_buff *skb, return; } - memcpy(skb->cb, &ieee80211->dev, sizeof(ieee80211->dev)); - skb_push(skb, priv->ieee80211->tx_headroom); ret = rtl8192_tx(priv, skb); if (ret != 0) { @@ -865,7 +863,6 @@ static int rtl8192_hard_start_xmit(struct sk_buff *skb, struct ieee80211_device } } - memcpy(skb->cb, &ieee80211->dev, sizeof(ieee80211->dev)); if (queue_index == TXCMD_QUEUE) { rtl819xE_tx_cmd(priv, skb); ret = 0; diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.c b/drivers/staging/rtl8192e/r819xE_cmdpkt.c index 41dcb9026dd7..756e0660bbe5 100644 --- a/drivers/staging/rtl8192e/r819xE_cmdpkt.c +++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.c @@ -38,7 +38,6 @@ RT_STATUS cmpk_message_handle_tx( u32 packettype, u32 buffer_len) { - struct net_device *dev = priv->ieee80211->dev; RT_STATUS rt_status = RT_STATUS_SUCCESS; u16 frag_threshold; u16 frag_length = 0, frag_offset = 0; @@ -75,7 +74,6 @@ RT_STATUS cmpk_message_handle_tx( goto Failed; } - memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev)); tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE); tcb_desc->queue_index = TXCMD_QUEUE; tcb_desc->bCmdOrInit = packettype; diff --git a/drivers/staging/rtl8192e/r819xE_firmware.c b/drivers/staging/rtl8192e/r819xE_firmware.c index 1557d8030ca8..d9e8b5a08904 100644 --- a/drivers/staging/rtl8192e/r819xE_firmware.c +++ b/drivers/staging/rtl8192e/r819xE_firmware.c @@ -39,7 +39,6 @@ void firmware_init_param(struct r8192_priv *priv) static bool fw_download_code(struct r8192_priv *priv, u8 *code_virtual_address, u32 buffer_len) { - struct net_device *dev = priv->ieee80211->dev; bool rt_status = true; u16 frag_threshold; u16 frag_length, frag_offset = 0; @@ -69,7 +68,6 @@ static bool fw_download_code(struct r8192_priv *priv, u8 *code_virtual_address, * descriptor info add 4 to avoid packet appending overflow. */ skb = dev_alloc_skb(frag_length + 4); - memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); tcb_desc->queue_index = TXCMD_QUEUE; tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT; -- cgit v1.2.3 From a6e4d8e3fee3cb49c4a0f696c26f1c7b1e4d7a1b Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 10 Mar 2011 14:03:51 -0800 Subject: Staging: hv: Simplify root device management As part of simplifying root device management, get rid of the hv_driver object from vmbus_driver_context. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 41 +++++++++++------------------------------ 1 file changed, 11 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 159dfdaec0fc..884a4c65159d 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -42,7 +42,6 @@ /* Main vmbus driver data structure */ struct vmbus_driver_context { - struct hv_driver drv_obj; struct bus_type bus; struct tasklet_struct msg_dpc; @@ -458,7 +457,6 @@ static ssize_t vmbus_show_device_attr(struct device *dev, static int vmbus_bus_init(void) { struct vmbus_driver_context *vmbus_drv_ctx = &vmbus_drv; - struct hv_driver *driver = &vmbus_drv.drv_obj; struct hv_device *dev_ctx = &vmbus_drv.device_ctx; int ret; unsigned int vector; @@ -474,13 +472,6 @@ static int vmbus_bus_init(void) sizeof(struct vmbus_channel_packet_page_buffer), sizeof(struct vmbus_channel_packet_multipage_buffer)); - driver->name = driver_name; - memcpy(&driver->dev_type, &device_type, sizeof(struct hv_guid)); - - /* Setup dispatch table */ - driver->dev_add = vmbus_dev_add; - driver->dev_rm = vmbus_dev_rm; - driver->cleanup = vmbus_cleanup; /* Hypervisor initialization...setup hypercall page..etc */ ret = hv_init(); @@ -490,22 +481,16 @@ static int vmbus_bus_init(void) goto cleanup; } - /* Sanity checks */ - if (!driver->dev_add) { - DPRINT_ERR(VMBUS_DRV, "OnDeviceAdd() routine not set"); - ret = -1; - goto cleanup; - } - vmbus_drv_ctx->bus.name = driver->name; + vmbus_drv_ctx->bus.name = driver_name; /* Initialize the bus context */ tasklet_init(&vmbus_drv_ctx->msg_dpc, vmbus_msg_dpc, - (unsigned long)driver); + (unsigned long)NULL); tasklet_init(&vmbus_drv_ctx->event_dpc, vmbus_event_dpc, - (unsigned long)driver); + (unsigned long)NULL); - /* Now, register the bus driver with LDM */ + /* Now, register the bus with LDM */ ret = bus_register(&vmbus_drv_ctx->bus); if (ret) { ret = -1; @@ -514,7 +499,7 @@ static int vmbus_bus_init(void) /* Get the interrupt resource */ ret = request_irq(vmbus_irq, vmbus_isr, IRQF_SAMPLE_RANDOM, - driver->name, NULL); + driver_name, NULL); if (ret != 0) { DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to request IRQ %d", @@ -529,10 +514,10 @@ static int vmbus_bus_init(void) DPRINT_INFO(VMBUS_DRV, "irq 0x%x vector 0x%x", vmbus_irq, vector); - /* Call to bus driver to add the root device */ + /* Add the root device */ memset(dev_ctx, 0, sizeof(struct hv_device)); - ret = driver->dev_add(dev_ctx, &vector); + ret = vmbus_dev_add(dev_ctx, &vector); if (ret != 0) { DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to add vmbus root device"); @@ -555,7 +540,7 @@ static int vmbus_bus_init(void) /* Setup the device dispatch table */ dev_ctx->device.release = vmbus_bus_release; - /* Setup the bus as root device */ + /* register the root device */ ret = device_register(&dev_ctx->device); if (ret) { DPRINT_ERR(VMBUS_DRV, @@ -582,17 +567,14 @@ cleanup: */ static void vmbus_bus_exit(void) { - struct hv_driver *driver = &vmbus_drv.drv_obj; struct vmbus_driver_context *vmbus_drv_ctx = &vmbus_drv; struct hv_device *dev_ctx = &vmbus_drv.device_ctx; /* Remove the root device */ - if (driver->dev_rm) - driver->dev_rm(dev_ctx); + vmbus_dev_rm(dev_ctx); - if (driver->cleanup) - driver->cleanup(driver); + vmbus_cleanup(NULL); /* Unregister the root bus device */ device_unregister(&dev_ctx->device); @@ -1026,11 +1008,10 @@ static void vmbus_event_dpc(unsigned long data) static irqreturn_t vmbus_isr(int irq, void *dev_id) { - struct hv_driver *driver = &vmbus_drv.drv_obj; int ret; /* Call to bus driver to handle interrupt */ - ret = vmbus_on_isr(driver); + ret = vmbus_on_isr(NULL); /* Schedules a dpc if necessary */ if (ret > 0) { -- cgit v1.2.3 From 21ec2de26a418e8a5839f2d260876b952a61b9ac Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 10 Mar 2011 14:04:29 -0800 Subject: Staging: hv: Change the signature for vmbus_cleanup() As part of geting rid of hv_driver object from vmbus_driver_context, change the signature of vmbus_cleanup() function. Note that while vmbus_cleanup() was passed a pointer to hv_driver, this argument was unused. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 884a4c65159d..95654b180cbc 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -190,9 +190,8 @@ static int vmbus_dev_rm(struct hv_device *dev) /* * vmbus_cleanup - Perform any cleanup when the driver is removed */ -static void vmbus_cleanup(struct hv_driver *drv) +static void vmbus_cleanup(void) { - /* struct vmbus_driver *driver = (struct vmbus_driver *)drv; */ hv_cleanup(); } @@ -574,7 +573,7 @@ static void vmbus_bus_exit(void) /* Remove the root device */ vmbus_dev_rm(dev_ctx); - vmbus_cleanup(NULL); + vmbus_cleanup(); /* Unregister the root bus device */ device_unregister(&dev_ctx->device); -- cgit v1.2.3 From 62c1059d6e20fe23e9e36cd1e79fafb778c86627 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 10 Mar 2011 14:04:53 -0800 Subject: Staging: hv: Get rid of the function vmbus_msg_dpc() vmbus_msg_dpc() was a wrapper adding no additional value; get rid of this function. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 95654b180cbc..7e679331f648 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -56,7 +56,6 @@ static int vmbus_probe(struct device *device); static int vmbus_remove(struct device *device); static void vmbus_shutdown(struct device *device); static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env); -static void vmbus_msg_dpc(unsigned long data); static void vmbus_event_dpc(unsigned long data); static irqreturn_t vmbus_isr(int irq, void *dev_id); @@ -214,7 +213,7 @@ static void vmbus_onmessage_work(struct work_struct *work) /* * vmbus_on_msg_dpc - DPC routine to handle messages from the hypervisior */ -static void vmbus_on_msg_dpc(struct hv_driver *drv) +static void vmbus_on_msg_dpc(unsigned long data) { int cpu = smp_processor_id(); void *page_addr = hv_context.synic_message_page[cpu]; @@ -484,7 +483,7 @@ static int vmbus_bus_init(void) vmbus_drv_ctx->bus.name = driver_name; /* Initialize the bus context */ - tasklet_init(&vmbus_drv_ctx->msg_dpc, vmbus_msg_dpc, + tasklet_init(&vmbus_drv_ctx->msg_dpc, vmbus_on_msg_dpc, (unsigned long)NULL); tasklet_init(&vmbus_drv_ctx->event_dpc, vmbus_event_dpc, (unsigned long)NULL); @@ -985,16 +984,6 @@ static void vmbus_device_release(struct device *device) /* !!DO NOT REFERENCE device_ctx anymore at this point!! */ } -/* - * vmbus_msg_dpc - Tasklet routine to handle hypervisor messages - */ -static void vmbus_msg_dpc(unsigned long data) -{ - struct hv_driver *driver = (struct hv_driver *)data; - - /* Call to bus driver to handle interrupt */ - vmbus_on_msg_dpc(driver); -} /* * vmbus_event_dpc - Tasklet routine to handle hypervisor events -- cgit v1.2.3 From 6de3d6aa9ad455726eb7b689e2d3e57d89374e55 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 10 Mar 2011 14:05:16 -0800 Subject: Staging: hv: Eliminate vmbus_event_dpc() vmbus_event_dpc() was a wrapper function not adding any value; get rid of it. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/connection.c | 2 +- drivers/staging/hv/vmbus_drv.c | 11 +---------- drivers/staging/hv/vmbus_private.h | 2 +- 3 files changed, 3 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index f7df47934cf9..fd589e381e31 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -285,7 +285,7 @@ static void process_chn_event(void *context) /* * vmbus_on_event - Handler for events */ -void vmbus_on_event(void) +void vmbus_on_event(unsigned long data) { int dword; int maxdword = MAX_NUM_CHANNELS_SUPPORTED >> 5; diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 7e679331f648..4b4483b2e18e 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -56,7 +56,6 @@ static int vmbus_probe(struct device *device); static int vmbus_remove(struct device *device); static void vmbus_shutdown(struct device *device); static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env); -static void vmbus_event_dpc(unsigned long data); static irqreturn_t vmbus_isr(int irq, void *dev_id); @@ -485,7 +484,7 @@ static int vmbus_bus_init(void) /* Initialize the bus context */ tasklet_init(&vmbus_drv_ctx->msg_dpc, vmbus_on_msg_dpc, (unsigned long)NULL); - tasklet_init(&vmbus_drv_ctx->event_dpc, vmbus_event_dpc, + tasklet_init(&vmbus_drv_ctx->event_dpc, vmbus_on_event, (unsigned long)NULL); /* Now, register the bus with LDM */ @@ -985,14 +984,6 @@ static void vmbus_device_release(struct device *device) } -/* - * vmbus_event_dpc - Tasklet routine to handle hypervisor events - */ -static void vmbus_event_dpc(unsigned long data) -{ - /* Call to bus driver to handle interrupt */ - vmbus_on_event(); -} static irqreturn_t vmbus_isr(int irq, void *dev_id) { diff --git a/drivers/staging/hv/vmbus_private.h b/drivers/staging/hv/vmbus_private.h index 9f505c44c600..1b88b6f9be08 100644 --- a/drivers/staging/hv/vmbus_private.h +++ b/drivers/staging/hv/vmbus_private.h @@ -129,7 +129,7 @@ int vmbus_post_msg(void *buffer, size_t buflen); int vmbus_set_event(u32 child_relid); -void vmbus_on_event(void); +void vmbus_on_event(unsigned long data); #endif /* _VMBUS_PRIVATE_H_ */ -- cgit v1.2.3 From 480ae58db525e57cc18611eec7ae24633d2e7efc Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 10 Mar 2011 14:06:06 -0800 Subject: Staging: hv: Change the signature for vmbus_on_isr() As part of getting getting rid of the hv_driver object from vmbus_driver_context, change the signature for vmbus_on_isr. Note that the argument to vmbus_on_isr() is not used. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 4b4483b2e18e..8e8a408d6877 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -258,7 +258,7 @@ static void vmbus_on_msg_dpc(unsigned long data) /* * vmbus_on_isr - ISR routine */ -static int vmbus_on_isr(struct hv_driver *drv) +static int vmbus_on_isr(void) { int ret = 0; int cpu = smp_processor_id(); @@ -989,8 +989,7 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) { int ret; - /* Call to bus driver to handle interrupt */ - ret = vmbus_on_isr(NULL); + ret = vmbus_on_isr(); /* Schedules a dpc if necessary */ if (ret > 0) { -- cgit v1.2.3 From f51b3593bbea8b403117212588bda87429545fa7 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 10 Mar 2011 14:06:31 -0800 Subject: Staging: hv: Get rid of vmbus_dev_rm() function Get rid of the vmbus_dev_rm() function by inlining the necessary code. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 8e8a408d6877..11c69c576e3e 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -172,18 +172,6 @@ static int vmbus_dev_add(struct hv_device *dev, void *info) return ret; } -/* - * vmbus_dev_rm - Callback when the root bus device is removed - */ -static int vmbus_dev_rm(struct hv_device *dev) -{ - int ret = 0; - - vmbus_release_unattached_channels(); - vmbus_disconnect(); - on_each_cpu(hv_synic_cleanup, NULL, 1); - return ret; -} /* * vmbus_cleanup - Perform any cleanup when the driver is removed @@ -568,8 +556,9 @@ static void vmbus_bus_exit(void) struct hv_device *dev_ctx = &vmbus_drv.device_ctx; - /* Remove the root device */ - vmbus_dev_rm(dev_ctx); + vmbus_release_unattached_channels(); + vmbus_disconnect(); + on_each_cpu(hv_synic_cleanup, NULL, 1); vmbus_cleanup(); -- cgit v1.2.3 From ece0e32fd2870f7d2b2f28a99f8e63bef3c01686 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 10 Mar 2011 14:06:55 -0800 Subject: Staging: hv: Get rid of vmbus_cleanup() function Get rid of the vmbus_cleanup() function by inlining the necessary code. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 11c69c576e3e..e078c5944d51 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -173,15 +173,6 @@ static int vmbus_dev_add(struct hv_device *dev, void *info) } -/* - * vmbus_cleanup - Perform any cleanup when the driver is removed - */ -static void vmbus_cleanup(void) -{ - - hv_cleanup(); -} - struct onmessage_work_context { struct work_struct work; struct hv_message msg; @@ -560,7 +551,7 @@ static void vmbus_bus_exit(void) vmbus_disconnect(); on_each_cpu(hv_synic_cleanup, NULL, 1); - vmbus_cleanup(); + hv_cleanup(); /* Unregister the root bus device */ device_unregister(&dev_ctx->device); -- cgit v1.2.3 From 3ca07cb06d3176b3eb1bfd49fdc8c8fbe649fa5b Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 10 Mar 2011 14:07:21 -0800 Subject: Staging: hv: Change the signature for vmbus_child_device_register() In preparation for getting rid of the vmbus_child_dev_add() function, modify the signature of vmbus_child_device_register(). Note that the root device is a global variable. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 7 +++---- drivers/staging/hv/vmbus_private.h | 3 +-- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index e078c5944d51..0b91edad6e11 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -144,7 +144,7 @@ static struct hv_device *vmbus_device; /* vmbus root device */ */ int vmbus_child_dev_add(struct hv_device *child_dev) { - return vmbus_child_device_register(vmbus_device, child_dev); + return vmbus_child_device_register(child_dev); } /* @@ -664,8 +664,7 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *type, /* * vmbus_child_device_register - Register the child device on the specified bus */ -int vmbus_child_device_register(struct hv_device *root_device_obj, - struct hv_device *child_device_obj) +int vmbus_child_device_register(struct hv_device *child_device_obj) { int ret = 0; @@ -680,7 +679,7 @@ int vmbus_child_device_register(struct hv_device *root_device_obj, /* The new device belongs to this bus */ child_device_obj->device.bus = &vmbus_drv.bus; /* device->dev.bus; */ - child_device_obj->device.parent = &root_device_obj->device; + child_device_obj->device.parent = &vmbus_device->device; child_device_obj->device.release = vmbus_device_release; /* diff --git a/drivers/staging/hv/vmbus_private.h b/drivers/staging/hv/vmbus_private.h index 1b88b6f9be08..c176773440d2 100644 --- a/drivers/staging/hv/vmbus_private.h +++ b/drivers/staging/hv/vmbus_private.h @@ -108,8 +108,7 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *type, struct vmbus_channel *channel); int vmbus_child_dev_add(struct hv_device *device); -int vmbus_child_device_register(struct hv_device *root_device_obj, - struct hv_device *child_device_obj); +int vmbus_child_device_register(struct hv_device *child_device_obj); void vmbus_child_device_unregister(struct hv_device *device_obj); /* static void */ -- cgit v1.2.3 From e13a0b5a4b2ca9e318896a1c8c4b45d62477c956 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 10 Mar 2011 14:07:44 -0800 Subject: Staging: hv: Get rid of vmbus_child_dev_add() The function vmbus_child_dev_add() is a wrapper that can be eliminated; get rid of it. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Mike Sterling Signed-off-by: Abhishek Kane Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel_mgmt.c | 2 +- drivers/staging/hv/vmbus_drv.c | 9 +-------- drivers/staging/hv/vmbus_private.h | 1 - 3 files changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 0781c0ed7056..33688094e1fd 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -408,7 +408,7 @@ static void vmbus_process_offer(struct work_struct *work) * binding which eventually invokes the device driver's AddDevice() * method. */ - ret = vmbus_child_dev_add(newchannel->device_obj); + ret = vmbus_child_device_register(newchannel->device_obj); if (ret != 0) { DPRINT_ERR(VMBUS, "unable to add child device object (relid %d)", diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 0b91edad6e11..b473f468dd83 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -139,13 +139,6 @@ static const struct hv_guid device_id = { static struct hv_device *vmbus_device; /* vmbus root device */ -/* - * vmbus_child_dev_add - Registers the child device with the vmbus - */ -int vmbus_child_dev_add(struct hv_device *child_dev) -{ - return vmbus_child_device_register(child_dev); -} /* * vmbus_dev_add - Callback when the root bus device is added @@ -662,7 +655,7 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *type, } /* - * vmbus_child_device_register - Register the child device on the specified bus + * vmbus_child_device_register - Register the child device */ int vmbus_child_device_register(struct hv_device *child_device_obj) { diff --git a/drivers/staging/hv/vmbus_private.h b/drivers/staging/hv/vmbus_private.h index c176773440d2..ca050a499b99 100644 --- a/drivers/staging/hv/vmbus_private.h +++ b/drivers/staging/hv/vmbus_private.h @@ -107,7 +107,6 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *type, struct hv_guid *instance, struct vmbus_channel *channel); -int vmbus_child_dev_add(struct hv_device *device); int vmbus_child_device_register(struct hv_device *child_device_obj); void vmbus_child_device_unregister(struct hv_device *device_obj); -- cgit v1.2.3 From dd9b15dc03075993f63a8a69667a3a8989aedfa1 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 13 Mar 2011 00:29:00 -0500 Subject: staging: hv: Remove NULL check before kfree This patch was generated by the following semantic patch: // @@ expression E; @@ - if (E != NULL) { kfree(E); } + kfree(E); @@ expression E; @@ - if (E != NULL) { kfree(E); E = NULL; } + kfree(E); + E = NULL; // Signed-off-by: Ilia Mirkin Cc: K. Y. Srinivasan Cc: Haiyang Zhang Cc: Mike Sterling Cc: Abhishek Kane Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel_mgmt.c | 3 +-- drivers/staging/hv/connection.c | 4 +--- drivers/staging/hv/hv_mouse.c | 12 ++++-------- 3 files changed, 6 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 33688094e1fd..bc0393a41d29 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -829,8 +829,7 @@ int vmbus_request_offers(void) cleanup: - if (msginfo) - kfree(msginfo); + kfree(msginfo); return ret; } diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index fd589e381e31..44b203b95a22 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -186,9 +186,7 @@ Cleanup: vmbus_connection.monitor_pages = NULL; } - if (msginfo) { - kfree(msginfo); - } + kfree(msginfo); return ret; } diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 8f94f433961f..6fa462109ce9 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -402,15 +402,11 @@ static void MousevscOnReceiveDeviceInfo(struct mousevsc_dev *InputDevice, struct return; Cleanup: - if (InputDevice->HidDesc) { - kfree(InputDevice->HidDesc); - InputDevice->HidDesc = NULL; - } + kfree(InputDevice->HidDesc); + InputDevice->HidDesc = NULL; - if (InputDevice->ReportDesc) { - kfree(InputDevice->ReportDesc); - InputDevice->ReportDesc = NULL; - } + kfree(InputDevice->ReportDesc); + InputDevice->ReportDesc = NULL; InputDevice->DeviceInfoStatus = -1; InputDevice->device_wait_condition = 1; -- cgit v1.2.3 From 12bb12fac06d6212be9a5ed282c5670d4e90747f Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sun, 13 Mar 2011 21:58:49 +0300 Subject: staging: hv: fix memory leaks Free resources before exit. Signed-off-by: Alexander Beregalov Cc: K. Y. Srinivasan Cc: Haiyang Zhang Cc: Mike Sterling Cc: Abhishek Kane Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_mouse.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index 6fa462109ce9..50147f84741c 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -684,6 +684,7 @@ static int MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) if (ret != 0) { pr_err("unable to open channel: %d", ret); + FreeInputDevice(inputDevice); return -1; } @@ -695,6 +696,7 @@ static int MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) pr_err("unable to connect channel: %d", ret); vmbus_close(Device->channel); + FreeInputDevice(inputDevice); return ret; } -- cgit v1.2.3 From 423cfa7e1fe68974b3b25fe8233ea57a5c2e5f02 Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Mon, 14 Mar 2011 13:43:22 -0700 Subject: bnx2x: fix swap of rx-ticks and tx-ticks parameters in interrupt coalescing flow Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index aa032339e321..10bc0a6a32d9 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -4208,7 +4208,7 @@ void bnx2x_update_coalesce(struct bnx2x *bp) for_each_eth_queue(bp, i) bnx2x_update_coalesce_sb(bp, bp->fp[i].fw_sb_id, - bp->rx_ticks, bp->tx_ticks); + bp->tx_ticks, bp->rx_ticks); } static void bnx2x_init_sp_ring(struct bnx2x *bp) -- cgit v1.2.3 From 4a55530f38e4eeee3afb06093e81309138fe8360 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 7 Mar 2011 21:59:26 +0000 Subject: net: sh_eth: modify the definitions of register The previous code cannot handle the ETHER and GETHER both as same time because the definitions of register was hardcoded. Signed-off-by: Yoshihiro Shimoda Signed-off-by: David S. Miller --- arch/sh/include/asm/sh_eth.h | 6 + drivers/net/sh_eth.c | 326 +++++++++++----------- drivers/net/sh_eth.h | 623 +++++++++++++++++++++++++------------------ 3 files changed, 533 insertions(+), 422 deletions(-) (limited to 'drivers') diff --git a/arch/sh/include/asm/sh_eth.h b/arch/sh/include/asm/sh_eth.h index f739061e2ee4..155769601065 100644 --- a/arch/sh/include/asm/sh_eth.h +++ b/arch/sh/include/asm/sh_eth.h @@ -2,10 +2,16 @@ #define __ASM_SH_ETH_H__ enum {EDMAC_LITTLE_ENDIAN, EDMAC_BIG_ENDIAN}; +enum { + SH_ETH_REG_GIGABIT, + SH_ETH_REG_FAST_SH4, + SH_ETH_REG_FAST_SH3_SH2 +}; struct sh_eth_plat_data { int phy; int edmac_endian; + int register_type; unsigned char mac_addr[6]; unsigned no_ether_link:1; diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 095e52580884..51268f591405 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -49,25 +49,23 @@ static void sh_eth_set_duplex(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); - u32 ioaddr = ndev->base_addr; if (mdp->duplex) /* Full */ - writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); + sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR); else /* Half */ - writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); + sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR); } static void sh_eth_set_rate(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); - u32 ioaddr = ndev->base_addr; switch (mdp->speed) { case 10: /* 10BASE */ - writel(readl(ioaddr + ECMR) & ~ECMR_RTM, ioaddr + ECMR); + sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_RTM, ECMR); break; case 100:/* 100BASE */ - writel(readl(ioaddr + ECMR) | ECMR_RTM, ioaddr + ECMR); + sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_RTM, ECMR); break; default: break; @@ -100,25 +98,23 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { static void sh_eth_set_duplex(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); - u32 ioaddr = ndev->base_addr; if (mdp->duplex) /* Full */ - writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); + sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR); else /* Half */ - writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); + sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR); } static void sh_eth_set_rate(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); - u32 ioaddr = ndev->base_addr; switch (mdp->speed) { case 10: /* 10BASE */ - writel(0, ioaddr + RTRATE); + sh_eth_write(ndev, 0, RTRATE); break; case 100:/* 100BASE */ - writel(1, ioaddr + RTRATE); + sh_eth_write(ndev, 1, RTRATE); break; default: break; @@ -156,13 +152,12 @@ static void sh_eth_chip_reset(struct net_device *ndev) static void sh_eth_reset(struct net_device *ndev) { - u32 ioaddr = ndev->base_addr; int cnt = 100; - writel(EDSR_ENALL, ioaddr + EDSR); - writel(readl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR); + sh_eth_write(ndev, EDSR_ENALL, EDSR); + sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST, EDMR); while (cnt > 0) { - if (!(readl(ioaddr + EDMR) & 0x3)) + if (!(sh_eth_read(ndev, EDMR) & 0x3)) break; mdelay(1); cnt--; @@ -171,41 +166,39 @@ static void sh_eth_reset(struct net_device *ndev) printk(KERN_ERR "Device reset fail\n"); /* Table Init */ - writel(0x0, ioaddr + TDLAR); - writel(0x0, ioaddr + TDFAR); - writel(0x0, ioaddr + TDFXR); - writel(0x0, ioaddr + TDFFR); - writel(0x0, ioaddr + RDLAR); - writel(0x0, ioaddr + RDFAR); - writel(0x0, ioaddr + RDFXR); - writel(0x0, ioaddr + RDFFR); + sh_eth_write(ndev, 0x0, TDLAR); + sh_eth_write(ndev, 0x0, TDFAR); + sh_eth_write(ndev, 0x0, TDFXR); + sh_eth_write(ndev, 0x0, TDFFR); + sh_eth_write(ndev, 0x0, RDLAR); + sh_eth_write(ndev, 0x0, RDFAR); + sh_eth_write(ndev, 0x0, RDFXR); + sh_eth_write(ndev, 0x0, RDFFR); } static void sh_eth_set_duplex(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); - u32 ioaddr = ndev->base_addr; if (mdp->duplex) /* Full */ - writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); + sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR); else /* Half */ - writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); + sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR); } static void sh_eth_set_rate(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); - u32 ioaddr = ndev->base_addr; switch (mdp->speed) { case 10: /* 10BASE */ - writel(GECMR_10, ioaddr + GECMR); + sh_eth_write(ndev, GECMR_10, GECMR); break; case 100:/* 100BASE */ - writel(GECMR_100, ioaddr + GECMR); + sh_eth_write(ndev, GECMR_100, GECMR); break; case 1000: /* 1000BASE */ - writel(GECMR_1000, ioaddr + GECMR); + sh_eth_write(ndev, GECMR_1000, GECMR); break; default: break; @@ -288,11 +281,9 @@ static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd) /* Chip Reset */ static void sh_eth_reset(struct net_device *ndev) { - u32 ioaddr = ndev->base_addr; - - writel(readl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR); + sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST, EDMR); mdelay(3); - writel(readl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR); + sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST, EDMR); } #endif @@ -341,13 +332,11 @@ static inline __u32 edmac_to_cpu(struct sh_eth_private *mdp, u32 x) */ static void update_mac_address(struct net_device *ndev) { - u32 ioaddr = ndev->base_addr; - - writel((ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) | - (ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]), - ioaddr + MAHR); - writel((ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]), - ioaddr + MALR); + sh_eth_write(ndev, + (ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) | + (ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]), MAHR); + sh_eth_write(ndev, + (ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]), MALR); } /* @@ -360,17 +349,15 @@ static void update_mac_address(struct net_device *ndev) */ static void read_mac_address(struct net_device *ndev, unsigned char *mac) { - u32 ioaddr = ndev->base_addr; - if (mac[0] || mac[1] || mac[2] || mac[3] || mac[4] || mac[5]) { memcpy(ndev->dev_addr, mac, 6); } else { - ndev->dev_addr[0] = (readl(ioaddr + MAHR) >> 24); - ndev->dev_addr[1] = (readl(ioaddr + MAHR) >> 16) & 0xFF; - ndev->dev_addr[2] = (readl(ioaddr + MAHR) >> 8) & 0xFF; - ndev->dev_addr[3] = (readl(ioaddr + MAHR) & 0xFF); - ndev->dev_addr[4] = (readl(ioaddr + MALR) >> 8) & 0xFF; - ndev->dev_addr[5] = (readl(ioaddr + MALR) & 0xFF); + ndev->dev_addr[0] = (sh_eth_read(ndev, MAHR) >> 24); + ndev->dev_addr[1] = (sh_eth_read(ndev, MAHR) >> 16) & 0xFF; + ndev->dev_addr[2] = (sh_eth_read(ndev, MAHR) >> 8) & 0xFF; + ndev->dev_addr[3] = (sh_eth_read(ndev, MAHR) & 0xFF); + ndev->dev_addr[4] = (sh_eth_read(ndev, MALR) >> 8) & 0xFF; + ndev->dev_addr[5] = (sh_eth_read(ndev, MALR) & 0xFF); } } @@ -477,7 +464,6 @@ static void sh_eth_ring_free(struct net_device *ndev) /* format skb and descriptor buffer */ static void sh_eth_ring_format(struct net_device *ndev) { - u32 ioaddr = ndev->base_addr; struct sh_eth_private *mdp = netdev_priv(ndev); int i; struct sk_buff *skb; @@ -513,9 +499,9 @@ static void sh_eth_ring_format(struct net_device *ndev) rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16); /* Rx descriptor address set */ if (i == 0) { - writel(mdp->rx_desc_dma, ioaddr + RDLAR); + sh_eth_write(ndev, mdp->rx_desc_dma, RDLAR); #if defined(CONFIG_CPU_SUBTYPE_SH7763) - writel(mdp->rx_desc_dma, ioaddr + RDFAR); + sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR); #endif } } @@ -535,9 +521,9 @@ static void sh_eth_ring_format(struct net_device *ndev) txdesc->buffer_length = 0; if (i == 0) { /* Tx descriptor address set */ - writel(mdp->tx_desc_dma, ioaddr + TDLAR); + sh_eth_write(ndev, mdp->tx_desc_dma, TDLAR); #if defined(CONFIG_CPU_SUBTYPE_SH7763) - writel(mdp->tx_desc_dma, ioaddr + TDFAR); + sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR); #endif } } @@ -620,7 +606,6 @@ static int sh_eth_dev_init(struct net_device *ndev) { int ret = 0; struct sh_eth_private *mdp = netdev_priv(ndev); - u32 ioaddr = ndev->base_addr; u_int32_t rx_int_var, tx_int_var; u32 val; @@ -630,71 +615,71 @@ static int sh_eth_dev_init(struct net_device *ndev) /* Descriptor format */ sh_eth_ring_format(ndev); if (mdp->cd->rpadir) - writel(mdp->cd->rpadir_value, ioaddr + RPADIR); + sh_eth_write(ndev, mdp->cd->rpadir_value, RPADIR); /* all sh_eth int mask */ - writel(0, ioaddr + EESIPR); + sh_eth_write(ndev, 0, EESIPR); #if defined(__LITTLE_ENDIAN__) if (mdp->cd->hw_swap) - writel(EDMR_EL, ioaddr + EDMR); + sh_eth_write(ndev, EDMR_EL, EDMR); else #endif - writel(0, ioaddr + EDMR); + sh_eth_write(ndev, 0, EDMR); /* FIFO size set */ - writel(mdp->cd->fdr_value, ioaddr + FDR); - writel(0, ioaddr + TFTR); + sh_eth_write(ndev, mdp->cd->fdr_value, FDR); + sh_eth_write(ndev, 0, TFTR); /* Frame recv control */ - writel(mdp->cd->rmcr_value, ioaddr + RMCR); + sh_eth_write(ndev, mdp->cd->rmcr_value, RMCR); rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5; tx_int_var = mdp->tx_int_var = DESC_I_TINT2; - writel(rx_int_var | tx_int_var, ioaddr + TRSCER); + sh_eth_write(ndev, rx_int_var | tx_int_var, TRSCER); if (mdp->cd->bculr) - writel(0x800, ioaddr + BCULR); /* Burst sycle set */ + sh_eth_write(ndev, 0x800, BCULR); /* Burst sycle set */ - writel(mdp->cd->fcftr_value, ioaddr + FCFTR); + sh_eth_write(ndev, mdp->cd->fcftr_value, FCFTR); if (!mdp->cd->no_trimd) - writel(0, ioaddr + TRIMD); + sh_eth_write(ndev, 0, TRIMD); /* Recv frame limit set register */ - writel(RFLR_VALUE, ioaddr + RFLR); + sh_eth_write(ndev, RFLR_VALUE, RFLR); - writel(readl(ioaddr + EESR), ioaddr + EESR); - writel(mdp->cd->eesipr_value, ioaddr + EESIPR); + sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR); + sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); /* PAUSE Prohibition */ - val = (readl(ioaddr + ECMR) & ECMR_DM) | + val = (sh_eth_read(ndev, ECMR) & ECMR_DM) | ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) | ECMR_TE | ECMR_RE; - writel(val, ioaddr + ECMR); + sh_eth_write(ndev, val, ECMR); if (mdp->cd->set_rate) mdp->cd->set_rate(ndev); /* E-MAC Status Register clear */ - writel(mdp->cd->ecsr_value, ioaddr + ECSR); + sh_eth_write(ndev, mdp->cd->ecsr_value, ECSR); /* E-MAC Interrupt Enable register */ - writel(mdp->cd->ecsipr_value, ioaddr + ECSIPR); + sh_eth_write(ndev, mdp->cd->ecsipr_value, ECSIPR); /* Set MAC address */ update_mac_address(ndev); /* mask reset */ if (mdp->cd->apr) - writel(APR_AP, ioaddr + APR); + sh_eth_write(ndev, APR_AP, APR); if (mdp->cd->mpr) - writel(MPR_MP, ioaddr + MPR); + sh_eth_write(ndev, MPR_MP, MPR); if (mdp->cd->tpauser) - writel(TPAUSER_UNLIMITED, ioaddr + TPAUSER); + sh_eth_write(ndev, TPAUSER_UNLIMITED, TPAUSER); /* Setting the Rx mode will start the Rx process. */ - writel(EDRRR_R, ioaddr + EDRRR); + sh_eth_write(ndev, EDRRR_R, EDRRR); netif_start_queue(ndev); @@ -818,38 +803,37 @@ static int sh_eth_rx(struct net_device *ndev) /* Restart Rx engine if stopped. */ /* If we don't need to check status, don't. -KDU */ - if (!(readl(ndev->base_addr + EDRRR) & EDRRR_R)) - writel(EDRRR_R, ndev->base_addr + EDRRR); + if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) + sh_eth_write(ndev, EDRRR_R, EDRRR); return 0; } -static void sh_eth_rcv_snd_disable(u32 ioaddr) +static void sh_eth_rcv_snd_disable(struct net_device *ndev) { /* disable tx and rx */ - writel(readl(ioaddr + ECMR) & - ~(ECMR_RE | ECMR_TE), ioaddr + ECMR); + sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & + ~(ECMR_RE | ECMR_TE), ECMR); } -static void sh_eth_rcv_snd_enable(u32 ioaddr) +static void sh_eth_rcv_snd_enable(struct net_device *ndev) { /* enable tx and rx */ - writel(readl(ioaddr + ECMR) | - (ECMR_RE | ECMR_TE), ioaddr + ECMR); + sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | + (ECMR_RE | ECMR_TE), ECMR); } /* error control function */ static void sh_eth_error(struct net_device *ndev, int intr_status) { struct sh_eth_private *mdp = netdev_priv(ndev); - u32 ioaddr = ndev->base_addr; u32 felic_stat; u32 link_stat; u32 mask; if (intr_status & EESR_ECI) { - felic_stat = readl(ioaddr + ECSR); - writel(felic_stat, ioaddr + ECSR); /* clear int */ + felic_stat = sh_eth_read(ndev, ECSR); + sh_eth_write(ndev, felic_stat, ECSR); /* clear int */ if (felic_stat & ECSR_ICD) mdp->stats.tx_carrier_errors++; if (felic_stat & ECSR_LCHNG) { @@ -860,23 +844,23 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) else link_stat = PHY_ST_LINK; } else { - link_stat = (readl(ioaddr + PSR)); + link_stat = (sh_eth_read(ndev, PSR)); if (mdp->ether_link_active_low) link_stat = ~link_stat; } if (!(link_stat & PHY_ST_LINK)) - sh_eth_rcv_snd_disable(ioaddr); + sh_eth_rcv_snd_disable(ndev); else { /* Link Up */ - writel(readl(ioaddr + EESIPR) & - ~DMAC_M_ECI, ioaddr + EESIPR); + sh_eth_write(ndev, sh_eth_read(ndev, EESIPR) & + ~DMAC_M_ECI, EESIPR); /*clear int */ - writel(readl(ioaddr + ECSR), - ioaddr + ECSR); - writel(readl(ioaddr + EESIPR) | - DMAC_M_ECI, ioaddr + EESIPR); + sh_eth_write(ndev, sh_eth_read(ndev, ECSR), + ECSR); + sh_eth_write(ndev, sh_eth_read(ndev, EESIPR) | + DMAC_M_ECI, EESIPR); /* enable tx and rx */ - sh_eth_rcv_snd_enable(ioaddr); + sh_eth_rcv_snd_enable(ndev); } } } @@ -917,8 +901,8 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) /* Receive Descriptor Empty int */ mdp->stats.rx_over_errors++; - if (readl(ioaddr + EDRRR) ^ EDRRR_R) - writel(EDRRR_R, ioaddr + EDRRR); + if (sh_eth_read(ndev, EDRRR) ^ EDRRR_R) + sh_eth_write(ndev, EDRRR_R, EDRRR); if (netif_msg_rx_err(mdp)) dev_err(&ndev->dev, "Receive Descriptor Empty\n"); } @@ -942,7 +926,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) mask &= ~EESR_ADE; if (intr_status & mask) { /* Tx error */ - u32 edtrr = readl(ndev->base_addr + EDTRR); + u32 edtrr = sh_eth_read(ndev, EDTRR); /* dmesg */ dev_err(&ndev->dev, "TX error. status=%8.8x cur_tx=%8.8x ", intr_status, mdp->cur_tx); @@ -954,7 +938,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) /* SH7712 BUG */ if (edtrr ^ EDTRR_TRNS) { /* tx dma start */ - writel(EDTRR_TRNS, ndev->base_addr + EDTRR); + sh_eth_write(ndev, EDTRR_TRNS, EDTRR); } /* wakeup */ netif_wake_queue(ndev); @@ -967,18 +951,17 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) struct sh_eth_private *mdp = netdev_priv(ndev); struct sh_eth_cpu_data *cd = mdp->cd; irqreturn_t ret = IRQ_NONE; - u32 ioaddr, intr_status = 0; + u32 intr_status = 0; - ioaddr = ndev->base_addr; spin_lock(&mdp->lock); /* Get interrpt stat */ - intr_status = readl(ioaddr + EESR); + intr_status = sh_eth_read(ndev, EESR); /* Clear interrupt */ if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF | EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF | cd->tx_check | cd->eesr_err_check)) { - writel(intr_status, ioaddr + EESR); + sh_eth_write(ndev, intr_status, EESR); ret = IRQ_HANDLED; } else goto other_irq; @@ -1021,7 +1004,6 @@ static void sh_eth_adjust_link(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); struct phy_device *phydev = mdp->phydev; - u32 ioaddr = ndev->base_addr; int new_state = 0; if (phydev->link != PHY_DOWN) { @@ -1039,8 +1021,8 @@ static void sh_eth_adjust_link(struct net_device *ndev) mdp->cd->set_rate(ndev); } if (mdp->link == PHY_DOWN) { - writel((readl(ioaddr + ECMR) & ~ECMR_TXF) - | ECMR_DM, ioaddr + ECMR); + sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_TXF) + | ECMR_DM, ECMR); new_state = 1; mdp->link = phydev->link; } @@ -1122,12 +1104,11 @@ static int sh_eth_set_settings(struct net_device *ndev, struct sh_eth_private *mdp = netdev_priv(ndev); unsigned long flags; int ret; - u32 ioaddr = ndev->base_addr; spin_lock_irqsave(&mdp->lock, flags); /* disable tx and rx */ - sh_eth_rcv_snd_disable(ioaddr); + sh_eth_rcv_snd_disable(ndev); ret = phy_ethtool_sset(mdp->phydev, ecmd); if (ret) @@ -1145,7 +1126,7 @@ error_exit: mdelay(1); /* enable tx and rx */ - sh_eth_rcv_snd_enable(ioaddr); + sh_eth_rcv_snd_enable(ndev); spin_unlock_irqrestore(&mdp->lock, flags); @@ -1282,7 +1263,6 @@ out_free_irq: static void sh_eth_tx_timeout(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); - u32 ioaddr = ndev->base_addr; struct sh_eth_rxdesc *rxdesc; int i; @@ -1290,7 +1270,7 @@ static void sh_eth_tx_timeout(struct net_device *ndev) if (netif_msg_timer(mdp)) dev_err(&ndev->dev, "%s: transmit timed out, status %8.8x," - " resetting...\n", ndev->name, (int)readl(ioaddr + EESR)); + " resetting...\n", ndev->name, (int)sh_eth_read(ndev, EESR)); /* tx_errors count up */ mdp->stats.tx_errors++; @@ -1363,8 +1343,8 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) mdp->cur_tx++; - if (!(readl(ndev->base_addr + EDTRR) & EDTRR_TRNS)) - writel(EDTRR_TRNS, ndev->base_addr + EDTRR); + if (!(sh_eth_read(ndev, EDTRR) & EDTRR_TRNS)) + sh_eth_write(ndev, EDTRR_TRNS, EDTRR); return NETDEV_TX_OK; } @@ -1373,17 +1353,16 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) static int sh_eth_close(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); - u32 ioaddr = ndev->base_addr; int ringsize; netif_stop_queue(ndev); /* Disable interrupts by clearing the interrupt mask. */ - writel(0x0000, ioaddr + EESIPR); + sh_eth_write(ndev, 0x0000, EESIPR); /* Stop the chip's Tx and Rx processes. */ - writel(0, ioaddr + EDTRR); - writel(0, ioaddr + EDRRR); + sh_eth_write(ndev, 0, EDTRR); + sh_eth_write(ndev, 0, EDRRR); /* PHY Disconnect */ if (mdp->phydev) { @@ -1414,24 +1393,23 @@ static int sh_eth_close(struct net_device *ndev) static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); - u32 ioaddr = ndev->base_addr; pm_runtime_get_sync(&mdp->pdev->dev); - mdp->stats.tx_dropped += readl(ioaddr + TROCR); - writel(0, ioaddr + TROCR); /* (write clear) */ - mdp->stats.collisions += readl(ioaddr + CDCR); - writel(0, ioaddr + CDCR); /* (write clear) */ - mdp->stats.tx_carrier_errors += readl(ioaddr + LCCR); - writel(0, ioaddr + LCCR); /* (write clear) */ + mdp->stats.tx_dropped += sh_eth_read(ndev, TROCR); + sh_eth_write(ndev, 0, TROCR); /* (write clear) */ + mdp->stats.collisions += sh_eth_read(ndev, CDCR); + sh_eth_write(ndev, 0, CDCR); /* (write clear) */ + mdp->stats.tx_carrier_errors += sh_eth_read(ndev, LCCR); + sh_eth_write(ndev, 0, LCCR); /* (write clear) */ #if defined(CONFIG_CPU_SUBTYPE_SH7763) - mdp->stats.tx_carrier_errors += readl(ioaddr + CERCR);/* CERCR */ - writel(0, ioaddr + CERCR); /* (write clear) */ - mdp->stats.tx_carrier_errors += readl(ioaddr + CEECR);/* CEECR */ - writel(0, ioaddr + CEECR); /* (write clear) */ + mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR);/* CERCR */ + sh_eth_write(ndev, 0, CERCR); /* (write clear) */ + mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR);/* CEECR */ + sh_eth_write(ndev, 0, CEECR); /* (write clear) */ #else - mdp->stats.tx_carrier_errors += readl(ioaddr + CNDCR); - writel(0, ioaddr + CNDCR); /* (write clear) */ + mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR); + sh_eth_write(ndev, 0, CNDCR); /* (write clear) */ #endif pm_runtime_put_sync(&mdp->pdev->dev); @@ -1458,46 +1436,44 @@ static int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq, /* Multicast reception directions set */ static void sh_eth_set_multicast_list(struct net_device *ndev) { - u32 ioaddr = ndev->base_addr; - if (ndev->flags & IFF_PROMISC) { /* Set promiscuous. */ - writel((readl(ioaddr + ECMR) & ~ECMR_MCT) | ECMR_PRM, - ioaddr + ECMR); + sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_MCT) | + ECMR_PRM, ECMR); } else { /* Normal, unicast/broadcast-only mode. */ - writel((readl(ioaddr + ECMR) & ~ECMR_PRM) | ECMR_MCT, - ioaddr + ECMR); + sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_PRM) | + ECMR_MCT, ECMR); } } /* SuperH's TSU register init function */ -static void sh_eth_tsu_init(u32 ioaddr) +static void sh_eth_tsu_init(struct sh_eth_private *mdp) { - writel(0, ioaddr + TSU_FWEN0); /* Disable forward(0->1) */ - writel(0, ioaddr + TSU_FWEN1); /* Disable forward(1->0) */ - writel(0, ioaddr + TSU_FCM); /* forward fifo 3k-3k */ - writel(0xc, ioaddr + TSU_BSYSL0); - writel(0xc, ioaddr + TSU_BSYSL1); - writel(0, ioaddr + TSU_PRISL0); - writel(0, ioaddr + TSU_PRISL1); - writel(0, ioaddr + TSU_FWSL0); - writel(0, ioaddr + TSU_FWSL1); - writel(TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, ioaddr + TSU_FWSLC); + sh_eth_tsu_write(mdp, 0, TSU_FWEN0); /* Disable forward(0->1) */ + sh_eth_tsu_write(mdp, 0, TSU_FWEN1); /* Disable forward(1->0) */ + sh_eth_tsu_write(mdp, 0, TSU_FCM); /* forward fifo 3k-3k */ + sh_eth_tsu_write(mdp, 0xc, TSU_BSYSL0); + sh_eth_tsu_write(mdp, 0xc, TSU_BSYSL1); + sh_eth_tsu_write(mdp, 0, TSU_PRISL0); + sh_eth_tsu_write(mdp, 0, TSU_PRISL1); + sh_eth_tsu_write(mdp, 0, TSU_FWSL0); + sh_eth_tsu_write(mdp, 0, TSU_FWSL1); + sh_eth_tsu_write(mdp, TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, TSU_FWSLC); #if defined(CONFIG_CPU_SUBTYPE_SH7763) - writel(0, ioaddr + TSU_QTAG0); /* Disable QTAG(0->1) */ - writel(0, ioaddr + TSU_QTAG1); /* Disable QTAG(1->0) */ + sh_eth_tsu_write(mdp, 0, TSU_QTAG0); /* Disable QTAG(0->1) */ + sh_eth_tsu_write(mdp, 0, TSU_QTAG1); /* Disable QTAG(1->0) */ #else - writel(0, ioaddr + TSU_QTAGM0); /* Disable QTAG(0->1) */ - writel(0, ioaddr + TSU_QTAGM1); /* Disable QTAG(1->0) */ + sh_eth_tsu_write(mdp, 0, TSU_QTAGM0); /* Disable QTAG(0->1) */ + sh_eth_tsu_write(mdp, 0, TSU_QTAGM1); /* Disable QTAG(1->0) */ #endif - writel(0, ioaddr + TSU_FWSR); /* all interrupt status clear */ - writel(0, ioaddr + TSU_FWINMK); /* Disable all interrupt */ - writel(0, ioaddr + TSU_TEN); /* Disable all CAM entry */ - writel(0, ioaddr + TSU_POST1); /* Disable CAM entry [ 0- 7] */ - writel(0, ioaddr + TSU_POST2); /* Disable CAM entry [ 8-15] */ - writel(0, ioaddr + TSU_POST3); /* Disable CAM entry [16-23] */ - writel(0, ioaddr + TSU_POST4); /* Disable CAM entry [24-31] */ + sh_eth_tsu_write(mdp, 0, TSU_FWSR); /* all interrupt status clear */ + sh_eth_tsu_write(mdp, 0, TSU_FWINMK); /* Disable all interrupt */ + sh_eth_tsu_write(mdp, 0, TSU_TEN); /* Disable all CAM entry */ + sh_eth_tsu_write(mdp, 0, TSU_POST1); /* Disable CAM entry [ 0- 7] */ + sh_eth_tsu_write(mdp, 0, TSU_POST2); /* Disable CAM entry [ 8-15] */ + sh_eth_tsu_write(mdp, 0, TSU_POST3); /* Disable CAM entry [16-23] */ + sh_eth_tsu_write(mdp, 0, TSU_POST4); /* Disable CAM entry [24-31] */ } #endif /* SH_ETH_HAS_TSU */ @@ -1536,7 +1512,7 @@ static int sh_mdio_init(struct net_device *ndev, int id) } /* bitbang init */ - bitbang->addr = ndev->base_addr + PIR; + bitbang->addr = ndev->base_addr + mdp->reg_offset[PIR]; bitbang->mdi_msk = 0x08; bitbang->mdo_msk = 0x04; bitbang->mmd_msk = 0x02;/* MMD */ @@ -1587,6 +1563,28 @@ out: return ret; } +static const u16 *sh_eth_get_register_offset(int register_type) +{ + const u16 *reg_offset = NULL; + + switch (register_type) { + case SH_ETH_REG_GIGABIT: + reg_offset = sh_eth_offset_gigabit; + break; + case SH_ETH_REG_FAST_SH4: + reg_offset = sh_eth_offset_fast_sh4; + break; + case SH_ETH_REG_FAST_SH3_SH2: + reg_offset = sh_eth_offset_fast_sh3_sh2; + break; + default: + printk(KERN_ERR "Unknown register type (%d)\n", register_type); + break; + } + + return reg_offset; +} + static const struct net_device_ops sh_eth_netdev_ops = { .ndo_open = sh_eth_open, .ndo_stop = sh_eth_close, @@ -1657,6 +1655,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev) mdp->edmac_endian = pd->edmac_endian; mdp->no_ether_link = pd->no_ether_link; mdp->ether_link_active_low = pd->ether_link_active_low; + mdp->reg_offset = sh_eth_get_register_offset(pd->register_type); /* set cpu data */ mdp->cd = &sh_eth_my_cpu_data; @@ -1682,7 +1681,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev) #if defined(SH_ETH_HAS_TSU) /* TSU init (Init only)*/ - sh_eth_tsu_init(SH_TSU_ADDR); + mdp->tsu_addr = SH_TSU_ADDR; + sh_eth_tsu_init(mdp); #endif } diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h index efa64221eede..1510a7ca956a 100644 --- a/drivers/net/sh_eth.h +++ b/drivers/net/sh_eth.h @@ -2,7 +2,7 @@ * SuperH Ethernet device driver * * Copyright (C) 2006-2008 Nobuhiro Iwamatsu - * Copyright (C) 2008-2009 Renesas Solutions Corp. + * Copyright (C) 2008-2011 Renesas Solutions Corp. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -38,162 +38,345 @@ #define ETHERSMALL 60 #define PKT_BUF_SZ 1538 +enum { + /* E-DMAC registers */ + EDSR = 0, + EDMR, + EDTRR, + EDRRR, + EESR, + EESIPR, + TDLAR, + TDFAR, + TDFXR, + TDFFR, + RDLAR, + RDFAR, + RDFXR, + RDFFR, + TRSCER, + RMFCR, + TFTR, + FDR, + RMCR, + EDOCR, + TFUCR, + RFOCR, + FCFTR, + RPADIR, + TRIMD, + RBWAR, + TBRAR, + + /* Ether registers */ + ECMR, + ECSR, + ECSIPR, + PIR, + PSR, + RDMLR, + PIPR, + RFLR, + IPGR, + APR, + MPR, + PFTCR, + PFRCR, + RFCR, + RFCF, + TPAUSER, + TPAUSECR, + BCFR, + BCFRR, + GECMR, + BCULR, + MAHR, + MALR, + TROCR, + CDCR, + LCCR, + CNDCR, + CEFCR, + FRECR, + TSFRCR, + TLFRCR, + CERCR, + CEECR, + MAFCR, + RTRATE, + + /* TSU Absolute address */ + ARSTR, + TSU_CTRST, + TSU_FWEN0, + TSU_FWEN1, + TSU_FCM, + TSU_BSYSL0, + TSU_BSYSL1, + TSU_PRISL0, + TSU_PRISL1, + TSU_FWSL0, + TSU_FWSL1, + TSU_FWSLC, + TSU_QTAG0, + TSU_QTAG1, + TSU_QTAGM0, + TSU_QTAGM1, + TSU_FWSR, + TSU_FWINMK, + TSU_ADQT0, + TSU_ADQT1, + TSU_VTAG0, + TSU_VTAG1, + TSU_ADSBSY, + TSU_TEN, + TSU_POST1, + TSU_POST2, + TSU_POST3, + TSU_POST4, + TSU_ADRH0, + TSU_ADRL0, + TSU_ADRH31, + TSU_ADRL31, + + TXNLCR0, + TXALCR0, + RXNLCR0, + RXALCR0, + FWNLCR0, + FWALCR0, + TXNLCR1, + TXALCR1, + RXNLCR1, + RXALCR1, + FWNLCR1, + FWALCR1, + + /* This value must be written at last. */ + SH_ETH_MAX_REGISTER_OFFSET, +}; + +static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = { + [EDSR] = 0x0000, + [EDMR] = 0x0400, + [EDTRR] = 0x0408, + [EDRRR] = 0x0410, + [EESR] = 0x0428, + [EESIPR] = 0x0430, + [TDLAR] = 0x0010, + [TDFAR] = 0x0014, + [TDFXR] = 0x0018, + [TDFFR] = 0x001c, + [RDLAR] = 0x0030, + [RDFAR] = 0x0034, + [RDFXR] = 0x0038, + [RDFFR] = 0x003c, + [TRSCER] = 0x0438, + [RMFCR] = 0x0440, + [TFTR] = 0x0448, + [FDR] = 0x0450, + [RMCR] = 0x0458, + [RPADIR] = 0x0460, + [FCFTR] = 0x0468, + + [ECMR] = 0x0500, + [ECSR] = 0x0510, + [ECSIPR] = 0x0518, + [PIR] = 0x0520, + [PSR] = 0x0528, + [PIPR] = 0x052c, + [RFLR] = 0x0508, + [APR] = 0x0554, + [MPR] = 0x0558, + [PFTCR] = 0x055c, + [PFRCR] = 0x0560, + [TPAUSER] = 0x0564, + [GECMR] = 0x05b0, + [BCULR] = 0x05b4, + [MAHR] = 0x05c0, + [MALR] = 0x05c8, + [TROCR] = 0x0700, + [CDCR] = 0x0708, + [LCCR] = 0x0710, + [CEFCR] = 0x0740, + [FRECR] = 0x0748, + [TSFRCR] = 0x0750, + [TLFRCR] = 0x0758, + [RFCR] = 0x0760, + [CERCR] = 0x0768, + [CEECR] = 0x0770, + [MAFCR] = 0x0778, + + [TSU_CTRST] = 0x0004, + [TSU_FWEN0] = 0x0010, + [TSU_FWEN1] = 0x0014, + [TSU_FCM] = 0x0018, + [TSU_BSYSL0] = 0x0020, + [TSU_BSYSL1] = 0x0024, + [TSU_PRISL0] = 0x0028, + [TSU_PRISL1] = 0x002c, + [TSU_FWSL0] = 0x0030, + [TSU_FWSL1] = 0x0034, + [TSU_FWSLC] = 0x0038, + [TSU_QTAG0] = 0x0040, + [TSU_QTAG1] = 0x0044, + [TSU_FWSR] = 0x0050, + [TSU_FWINMK] = 0x0054, + [TSU_ADQT0] = 0x0048, + [TSU_ADQT1] = 0x004c, + [TSU_VTAG0] = 0x0058, + [TSU_VTAG1] = 0x005c, + [TSU_ADSBSY] = 0x0060, + [TSU_TEN] = 0x0064, + [TSU_POST1] = 0x0070, + [TSU_POST2] = 0x0074, + [TSU_POST3] = 0x0078, + [TSU_POST4] = 0x007c, + [TSU_ADRH0] = 0x0100, + [TSU_ADRL0] = 0x0104, + [TSU_ADRH31] = 0x01f8, + [TSU_ADRL31] = 0x01fc, + + [TXNLCR0] = 0x0080, + [TXALCR0] = 0x0084, + [RXNLCR0] = 0x0088, + [RXALCR0] = 0x008c, + [FWNLCR0] = 0x0090, + [FWALCR0] = 0x0094, + [TXNLCR1] = 0x00a0, + [TXALCR1] = 0x00a0, + [RXNLCR1] = 0x00a8, + [RXALCR1] = 0x00ac, + [FWNLCR1] = 0x00b0, + [FWALCR1] = 0x00b4, +}; + +static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = { + [ECMR] = 0x0100, + [RFLR] = 0x0108, + [ECSR] = 0x0110, + [ECSIPR] = 0x0118, + [PIR] = 0x0120, + [PSR] = 0x0128, + [RDMLR] = 0x0140, + [IPGR] = 0x0150, + [APR] = 0x0154, + [MPR] = 0x0158, + [TPAUSER] = 0x0164, + [RFCF] = 0x0160, + [TPAUSECR] = 0x0168, + [BCFRR] = 0x016c, + [MAHR] = 0x01c0, + [MALR] = 0x01c8, + [TROCR] = 0x01d0, + [CDCR] = 0x01d4, + [LCCR] = 0x01d8, + [CNDCR] = 0x01dc, + [CEFCR] = 0x01e4, + [FRECR] = 0x01e8, + [TSFRCR] = 0x01ec, + [TLFRCR] = 0x01f0, + [RFCR] = 0x01f4, + [MAFCR] = 0x01f8, + [RTRATE] = 0x01fc, + + [EDMR] = 0x0000, + [EDTRR] = 0x0008, + [EDRRR] = 0x0010, + [TDLAR] = 0x0018, + [RDLAR] = 0x0020, + [EESR] = 0x0028, + [EESIPR] = 0x0030, + [TRSCER] = 0x0038, + [RMFCR] = 0x0040, + [TFTR] = 0x0048, + [FDR] = 0x0050, + [RMCR] = 0x0058, + [TFUCR] = 0x0064, + [RFOCR] = 0x0068, + [FCFTR] = 0x0070, + [RPADIR] = 0x0078, + [TRIMD] = 0x007c, + [RBWAR] = 0x00c8, + [RDFAR] = 0x00cc, + [TBRAR] = 0x00d4, + [TDFAR] = 0x00d8, +}; + +static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = { + [ECMR] = 0x0160, + [ECSR] = 0x0164, + [ECSIPR] = 0x0168, + [PIR] = 0x016c, + [MAHR] = 0x0170, + [MALR] = 0x0174, + [RFLR] = 0x0178, + [PSR] = 0x017c, + [TROCR] = 0x0180, + [CDCR] = 0x0184, + [LCCR] = 0x0188, + [CNDCR] = 0x018c, + [CEFCR] = 0x0194, + [FRECR] = 0x0198, + [TSFRCR] = 0x019c, + [TLFRCR] = 0x01a0, + [RFCR] = 0x01a4, + [MAFCR] = 0x01a8, + [IPGR] = 0x01b4, + [APR] = 0x01b8, + [MPR] = 0x01bc, + [TPAUSER] = 0x01c4, + [BCFR] = 0x01cc, + + [TSU_CTRST] = 0x0004, + [TSU_FWEN0] = 0x0010, + [TSU_FWEN1] = 0x0014, + [TSU_FCM] = 0x0018, + [TSU_BSYSL0] = 0x0020, + [TSU_BSYSL1] = 0x0024, + [TSU_PRISL0] = 0x0028, + [TSU_PRISL1] = 0x002c, + [TSU_FWSL0] = 0x0030, + [TSU_FWSL1] = 0x0034, + [TSU_FWSLC] = 0x0038, + [TSU_QTAGM0] = 0x0040, + [TSU_QTAGM1] = 0x0044, + [TSU_ADQT0] = 0x0048, + [TSU_ADQT1] = 0x004c, + [TSU_FWSR] = 0x0050, + [TSU_FWINMK] = 0x0054, + [TSU_ADSBSY] = 0x0060, + [TSU_TEN] = 0x0064, + [TSU_POST1] = 0x0070, + [TSU_POST2] = 0x0074, + [TSU_POST3] = 0x0078, + [TSU_POST4] = 0x007c, + + [TXNLCR0] = 0x0080, + [TXALCR0] = 0x0084, + [RXNLCR0] = 0x0088, + [RXALCR0] = 0x008c, + [FWNLCR0] = 0x0090, + [FWALCR0] = 0x0094, + [TXNLCR1] = 0x00a0, + [TXALCR1] = 0x00a0, + [RXNLCR1] = 0x00a8, + [RXALCR1] = 0x00ac, + [FWNLCR1] = 0x00b0, + [FWALCR1] = 0x00b4, + + [TSU_ADRH0] = 0x0100, + [TSU_ADRL0] = 0x0104, + [TSU_ADRL31] = 0x01fc, + +}; + #if defined(CONFIG_CPU_SUBTYPE_SH7763) /* This CPU register maps is very difference by other SH4 CPU */ - /* Chip Base Address */ # define SH_TSU_ADDR 0xFEE01800 # define ARSTR SH_TSU_ADDR - -/* Chip Registers */ -/* E-DMAC */ -# define EDSR 0x000 -# define EDMR 0x400 -# define EDTRR 0x408 -# define EDRRR 0x410 -# define EESR 0x428 -# define EESIPR 0x430 -# define TDLAR 0x010 -# define TDFAR 0x014 -# define TDFXR 0x018 -# define TDFFR 0x01C -# define RDLAR 0x030 -# define RDFAR 0x034 -# define RDFXR 0x038 -# define RDFFR 0x03C -# define TRSCER 0x438 -# define RMFCR 0x440 -# define TFTR 0x448 -# define FDR 0x450 -# define RMCR 0x458 -# define RPADIR 0x460 -# define FCFTR 0x468 - -/* Ether Register */ -# define ECMR 0x500 -# define ECSR 0x510 -# define ECSIPR 0x518 -# define PIR 0x520 -# define PSR 0x528 -# define PIPR 0x52C -# define RFLR 0x508 -# define APR 0x554 -# define MPR 0x558 -# define PFTCR 0x55C -# define PFRCR 0x560 -# define TPAUSER 0x564 -# define GECMR 0x5B0 -# define BCULR 0x5B4 -# define MAHR 0x5C0 -# define MALR 0x5C8 -# define TROCR 0x700 -# define CDCR 0x708 -# define LCCR 0x710 -# define CEFCR 0x740 -# define FRECR 0x748 -# define TSFRCR 0x750 -# define TLFRCR 0x758 -# define RFCR 0x760 -# define CERCR 0x768 -# define CEECR 0x770 -# define MAFCR 0x778 - -/* TSU Absolute Address */ -# define TSU_CTRST 0x004 -# define TSU_FWEN0 0x010 -# define TSU_FWEN1 0x014 -# define TSU_FCM 0x18 -# define TSU_BSYSL0 0x20 -# define TSU_BSYSL1 0x24 -# define TSU_PRISL0 0x28 -# define TSU_PRISL1 0x2C -# define TSU_FWSL0 0x30 -# define TSU_FWSL1 0x34 -# define TSU_FWSLC 0x38 -# define TSU_QTAG0 0x40 -# define TSU_QTAG1 0x44 -# define TSU_FWSR 0x50 -# define TSU_FWINMK 0x54 -# define TSU_ADQT0 0x48 -# define TSU_ADQT1 0x4C -# define TSU_VTAG0 0x58 -# define TSU_VTAG1 0x5C -# define TSU_ADSBSY 0x60 -# define TSU_TEN 0x64 -# define TSU_POST1 0x70 -# define TSU_POST2 0x74 -# define TSU_POST3 0x78 -# define TSU_POST4 0x7C -# define TSU_ADRH0 0x100 -# define TSU_ADRL0 0x104 -# define TSU_ADRH31 0x1F8 -# define TSU_ADRL31 0x1FC - -# define TXNLCR0 0x80 -# define TXALCR0 0x84 -# define RXNLCR0 0x88 -# define RXALCR0 0x8C -# define FWNLCR0 0x90 -# define FWALCR0 0x94 -# define TXNLCR1 0xA0 -# define TXALCR1 0xA4 -# define RXNLCR1 0xA8 -# define RXALCR1 0xAC -# define FWNLCR1 0xB0 -# define FWALCR1 0x40 - #elif defined(CONFIG_CPU_SH4) /* #if defined(CONFIG_CPU_SUBTYPE_SH7763) */ -/* EtherC */ -#define ECMR 0x100 -#define RFLR 0x108 -#define ECSR 0x110 -#define ECSIPR 0x118 -#define PIR 0x120 -#define PSR 0x128 -#define RDMLR 0x140 -#define IPGR 0x150 -#define APR 0x154 -#define MPR 0x158 -#define TPAUSER 0x164 -#define RFCF 0x160 -#define TPAUSECR 0x168 -#define BCFRR 0x16c -#define MAHR 0x1c0 -#define MALR 0x1c8 -#define TROCR 0x1d0 -#define CDCR 0x1d4 -#define LCCR 0x1d8 -#define CNDCR 0x1dc -#define CEFCR 0x1e4 -#define FRECR 0x1e8 -#define TSFRCR 0x1ec -#define TLFRCR 0x1f0 -#define RFCR 0x1f4 -#define MAFCR 0x1f8 -#define RTRATE 0x1fc - -/* E-DMAC */ -#define EDMR 0x000 -#define EDTRR 0x008 -#define EDRRR 0x010 -#define TDLAR 0x018 -#define RDLAR 0x020 -#define EESR 0x028 -#define EESIPR 0x030 -#define TRSCER 0x038 -#define RMFCR 0x040 -#define TFTR 0x048 -#define FDR 0x050 -#define RMCR 0x058 -#define TFUCR 0x064 -#define RFOCR 0x068 -#define FCFTR 0x070 -#define RPADIR 0x078 -#define TRIMD 0x07c -#define RBWAR 0x0c8 -#define RDFAR 0x0cc -#define TBRAR 0x0d4 -#define TDFAR 0x0d8 #else /* #elif defined(CONFIG_CPU_SH4) */ /* This section is SH3 or SH2 */ #ifndef CONFIG_CPU_SUBTYPE_SH7619 @@ -201,116 +384,8 @@ # define SH_TSU_ADDR 0xA7000804 # define ARSTR 0xA7000800 #endif -/* Chip Registers */ -/* E-DMAC */ -# define EDMR 0x0000 -# define EDTRR 0x0004 -# define EDRRR 0x0008 -# define TDLAR 0x000C -# define RDLAR 0x0010 -# define EESR 0x0014 -# define EESIPR 0x0018 -# define TRSCER 0x001C -# define RMFCR 0x0020 -# define TFTR 0x0024 -# define FDR 0x0028 -# define RMCR 0x002C -# define EDOCR 0x0030 -# define FCFTR 0x0034 -# define RPADIR 0x0038 -# define TRIMD 0x003C -# define RBWAR 0x0040 -# define RDFAR 0x0044 -# define TBRAR 0x004C -# define TDFAR 0x0050 - -/* Ether Register */ -# define ECMR 0x0160 -# define ECSR 0x0164 -# define ECSIPR 0x0168 -# define PIR 0x016C -# define MAHR 0x0170 -# define MALR 0x0174 -# define RFLR 0x0178 -# define PSR 0x017C -# define TROCR 0x0180 -# define CDCR 0x0184 -# define LCCR 0x0188 -# define CNDCR 0x018C -# define CEFCR 0x0194 -# define FRECR 0x0198 -# define TSFRCR 0x019C -# define TLFRCR 0x01A0 -# define RFCR 0x01A4 -# define MAFCR 0x01A8 -# define IPGR 0x01B4 -# if defined(CONFIG_CPU_SUBTYPE_SH7710) -# define APR 0x01B8 -# define MPR 0x01BC -# define TPAUSER 0x1C4 -# define BCFR 0x1CC -# endif /* CONFIG_CPU_SH7710 */ - -/* TSU */ -# define TSU_CTRST 0x004 -# define TSU_FWEN0 0x010 -# define TSU_FWEN1 0x014 -# define TSU_FCM 0x018 -# define TSU_BSYSL0 0x020 -# define TSU_BSYSL1 0x024 -# define TSU_PRISL0 0x028 -# define TSU_PRISL1 0x02C -# define TSU_FWSL0 0x030 -# define TSU_FWSL1 0x034 -# define TSU_FWSLC 0x038 -# define TSU_QTAGM0 0x040 -# define TSU_QTAGM1 0x044 -# define TSU_ADQT0 0x048 -# define TSU_ADQT1 0x04C -# define TSU_FWSR 0x050 -# define TSU_FWINMK 0x054 -# define TSU_ADSBSY 0x060 -# define TSU_TEN 0x064 -# define TSU_POST1 0x070 -# define TSU_POST2 0x074 -# define TSU_POST3 0x078 -# define TSU_POST4 0x07C -# define TXNLCR0 0x080 -# define TXALCR0 0x084 -# define RXNLCR0 0x088 -# define RXALCR0 0x08C -# define FWNLCR0 0x090 -# define FWALCR0 0x094 -# define TXNLCR1 0x0A0 -# define TXALCR1 0x0A4 -# define RXNLCR1 0x0A8 -# define RXALCR1 0x0AC -# define FWNLCR1 0x0B0 -# define FWALCR1 0x0B4 - -#define TSU_ADRH0 0x0100 -#define TSU_ADRL0 0x0104 -#define TSU_ADRL31 0x01FC - #endif /* CONFIG_CPU_SUBTYPE_SH7763 */ -/* There are avoid compile error... */ -#if !defined(BCULR) -#define BCULR 0x0fc -#endif -#if !defined(TRIMD) -#define TRIMD 0x0fc -#endif -#if !defined(APR) -#define APR 0x0fc -#endif -#if !defined(MPR) -#define MPR 0x0fc -#endif -#if !defined(TPAUSER) -#define TPAUSER 0x0fc -#endif - /* Driver's parameters */ #if defined(CONFIG_CPU_SH4) #define SH4_SKB_RX_ALIGN 32 @@ -704,6 +779,8 @@ struct sh_eth_cpu_data { struct sh_eth_private { struct platform_device *pdev; struct sh_eth_cpu_data *cd; + const u16 *reg_offset; + void __iomem *tsu_addr; dma_addr_t rx_desc_dma; dma_addr_t tx_desc_dma; struct sh_eth_rxdesc *rx_ring; @@ -746,4 +823,32 @@ static inline void sh_eth_soft_swap(char *src, int len) #endif } +static inline void sh_eth_write(struct net_device *ndev, unsigned long data, + int enum_index) +{ + struct sh_eth_private *mdp = netdev_priv(ndev); + + writel(data, ndev->base_addr + mdp->reg_offset[enum_index]); +} + +static inline unsigned long sh_eth_read(struct net_device *ndev, + int enum_index) +{ + struct sh_eth_private *mdp = netdev_priv(ndev); + + return readl(ndev->base_addr + mdp->reg_offset[enum_index]); +} + +static inline void sh_eth_tsu_write(struct sh_eth_private *mdp, + unsigned long data, int enum_index) +{ + writel(data, mdp->tsu_addr + mdp->reg_offset[enum_index]); +} + +static inline unsigned long sh_eth_tsu_read(struct sh_eth_private *mdp, + int enum_index) +{ + return readl(mdp->tsu_addr + mdp->reg_offset[enum_index]); +} + #endif /* #ifndef __SH_ETH_H__ */ -- cgit v1.2.3 From 4986b996882d82c68ab54b822d7cfdd7dd35f19a Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 7 Mar 2011 21:59:34 +0000 Subject: net: sh_eth: remove the SH_TSU_ADDR The defination is hardcoded in this driver for some CPUs. This patch modifies to get resource of TSU address from platform_device. Signed-off-by: Yoshihiro Shimoda Signed-off-by: David S. Miller --- drivers/net/sh_eth.c | 31 ++++++++++++++++++++++++------- drivers/net/sh_eth.h | 18 +++--------------- 2 files changed, 27 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 51268f591405..c7abcc586dbd 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -145,8 +145,10 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { #define SH_ETH_HAS_TSU 1 static void sh_eth_chip_reset(struct net_device *ndev) { + struct sh_eth_private *mdp = netdev_priv(ndev); + /* reset device */ - writel(ARSTR_ARSTR, ARSTR); + sh_eth_tsu_write(mdp, ARSTR_ARSTR, ARSTR); mdelay(1); } @@ -229,6 +231,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { .hw_swap = 1, .no_trimd = 1, .no_ade = 1, + .tsu = 1, }; #elif defined(CONFIG_CPU_SUBTYPE_SH7619) @@ -246,6 +249,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { #define SH_ETH_HAS_TSU 1 static struct sh_eth_cpu_data sh_eth_my_cpu_data = { .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, + .tsu = 1, }; #endif @@ -1446,6 +1450,7 @@ static void sh_eth_set_multicast_list(struct net_device *ndev) ECMR_MCT, ECMR); } } +#endif /* SH_ETH_HAS_TSU */ /* SuperH's TSU register init function */ static void sh_eth_tsu_init(struct sh_eth_private *mdp) @@ -1475,7 +1480,6 @@ static void sh_eth_tsu_init(struct sh_eth_private *mdp) sh_eth_tsu_write(mdp, 0, TSU_POST3); /* Disable CAM entry [16-23] */ sh_eth_tsu_write(mdp, 0, TSU_POST4); /* Disable CAM entry [24-31] */ } -#endif /* SH_ETH_HAS_TSU */ /* MDIO bus release function */ static int sh_mdio_release(struct net_device *ndev) @@ -1676,14 +1680,23 @@ static int sh_eth_drv_probe(struct platform_device *pdev) /* First device only init */ if (!devno) { + if (mdp->cd->tsu) { + struct resource *rtsu; + rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!rtsu) { + dev_err(&pdev->dev, "Not found TSU resource\n"); + goto out_release; + } + mdp->tsu_addr = ioremap(rtsu->start, + resource_size(rtsu)); + } if (mdp->cd->chip_reset) mdp->cd->chip_reset(ndev); -#if defined(SH_ETH_HAS_TSU) - /* TSU init (Init only)*/ - mdp->tsu_addr = SH_TSU_ADDR; - sh_eth_tsu_init(mdp); -#endif + if (mdp->cd->tsu) { + /* TSU init (Init only)*/ + sh_eth_tsu_init(mdp); + } } /* network device register */ @@ -1709,6 +1722,8 @@ out_unregister: out_release: /* net_dev free */ + if (mdp->tsu_addr) + iounmap(mdp->tsu_addr); if (ndev) free_netdev(ndev); @@ -1719,7 +1734,9 @@ out: static int sh_eth_drv_remove(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); + struct sh_eth_private *mdp = netdev_priv(ndev); + iounmap(mdp->tsu_addr); sh_mdio_release(ndev); unregister_netdev(ndev); pm_runtime_disable(&pdev->dev); diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h index 1510a7ca956a..35a3adbb2e7a 100644 --- a/drivers/net/sh_eth.h +++ b/drivers/net/sh_eth.h @@ -207,6 +207,7 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = { [CEECR] = 0x0770, [MAFCR] = 0x0778, + [ARSTR] = 0x0000, [TSU_CTRST] = 0x0004, [TSU_FWEN0] = 0x0010, [TSU_FWEN1] = 0x0014, @@ -328,6 +329,7 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = { [TPAUSER] = 0x01c4, [BCFR] = 0x01cc, + [ARSTR] = 0x0000, [TSU_CTRST] = 0x0004, [TSU_FWEN0] = 0x0010, [TSU_FWEN1] = 0x0014, @@ -371,21 +373,6 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = { }; -#if defined(CONFIG_CPU_SUBTYPE_SH7763) -/* This CPU register maps is very difference by other SH4 CPU */ -/* Chip Base Address */ -# define SH_TSU_ADDR 0xFEE01800 -# define ARSTR SH_TSU_ADDR -#elif defined(CONFIG_CPU_SH4) /* #if defined(CONFIG_CPU_SUBTYPE_SH7763) */ -#else /* #elif defined(CONFIG_CPU_SH4) */ -/* This section is SH3 or SH2 */ -#ifndef CONFIG_CPU_SUBTYPE_SH7619 -/* Chip base address */ -# define SH_TSU_ADDR 0xA7000804 -# define ARSTR 0xA7000800 -#endif -#endif /* CONFIG_CPU_SUBTYPE_SH7763 */ - /* Driver's parameters */ #if defined(CONFIG_CPU_SH4) #define SH4_SKB_RX_ALIGN 32 @@ -770,6 +757,7 @@ struct sh_eth_cpu_data { unsigned mpr:1; /* EtherC have MPR */ unsigned tpauser:1; /* EtherC have TPAUSER */ unsigned bculr:1; /* EtherC have BCULR */ + unsigned tsu:1; /* EtherC have TSU */ unsigned hw_swap:1; /* E-DMAC have DE bit in EDMR */ unsigned rpadir:1; /* E-DMAC have RPADIR */ unsigned no_trimd:1; /* E-DMAC DO NOT have TRIMD */ -- cgit v1.2.3 From c5ed53687b39c195b4730de8c0355c1b78054ba6 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 7 Mar 2011 21:59:38 +0000 Subject: net: sh_eth: remove almost #ifdef of SH7763 The SH7763 has GETHER. So the specification of some registers differs than other CPUs. This patch removes almost #ifdef of CONFIG_CPU_SUBTYPE_SH7763. Then we are able to add other CPU's GETHER easily. Signed-off-by: Yoshihiro Shimoda Signed-off-by: David S. Miller --- drivers/net/sh_eth.c | 72 +++++++++++++++++++++++++++++++--------------------- drivers/net/sh_eth.h | 14 +++------- 2 files changed, 47 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index c7abcc586dbd..6734311e56e4 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -157,7 +157,7 @@ static void sh_eth_reset(struct net_device *ndev) int cnt = 100; sh_eth_write(ndev, EDSR_ENALL, EDSR); - sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST, EDMR); + sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR); while (cnt > 0) { if (!(sh_eth_read(ndev, EDMR) & 0x3)) break; @@ -285,9 +285,9 @@ static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd) /* Chip Reset */ static void sh_eth_reset(struct net_device *ndev) { - sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST, EDMR); + sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER, EDMR); mdelay(3); - sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST, EDMR); + sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER, EDMR); } #endif @@ -365,6 +365,22 @@ static void read_mac_address(struct net_device *ndev, unsigned char *mac) } } +static int sh_eth_is_gether(struct sh_eth_private *mdp) +{ + if (mdp->reg_offset == sh_eth_offset_gigabit) + return 1; + else + return 0; +} + +static unsigned long sh_eth_get_edtrr_trns(struct sh_eth_private *mdp) +{ + if (sh_eth_is_gether(mdp)) + return EDTRR_TRNS_GETHER; + else + return EDTRR_TRNS_ETHER; +} + struct bb_info { struct mdiobb_ctrl ctrl; u32 addr; @@ -504,9 +520,8 @@ static void sh_eth_ring_format(struct net_device *ndev) /* Rx descriptor address set */ if (i == 0) { sh_eth_write(ndev, mdp->rx_desc_dma, RDLAR); -#if defined(CONFIG_CPU_SUBTYPE_SH7763) - sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR); -#endif + if (sh_eth_is_gether(mdp)) + sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR); } } @@ -526,9 +541,8 @@ static void sh_eth_ring_format(struct net_device *ndev) if (i == 0) { /* Tx descriptor address set */ sh_eth_write(ndev, mdp->tx_desc_dma, TDLAR); -#if defined(CONFIG_CPU_SUBTYPE_SH7763) - sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR); -#endif + if (sh_eth_is_gether(mdp)) + sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR); } } @@ -940,9 +954,9 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) sh_eth_txfree(ndev); /* SH7712 BUG */ - if (edtrr ^ EDTRR_TRNS) { + if (edtrr ^ sh_eth_get_edtrr_trns(mdp)) { /* tx dma start */ - sh_eth_write(ndev, EDTRR_TRNS, EDTRR); + sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR); } /* wakeup */ netif_wake_queue(ndev); @@ -1347,8 +1361,8 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) mdp->cur_tx++; - if (!(sh_eth_read(ndev, EDTRR) & EDTRR_TRNS)) - sh_eth_write(ndev, EDTRR_TRNS, EDTRR); + if (!(sh_eth_read(ndev, EDTRR) & sh_eth_get_edtrr_trns(mdp))) + sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR); return NETDEV_TX_OK; } @@ -1406,15 +1420,15 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev) sh_eth_write(ndev, 0, CDCR); /* (write clear) */ mdp->stats.tx_carrier_errors += sh_eth_read(ndev, LCCR); sh_eth_write(ndev, 0, LCCR); /* (write clear) */ -#if defined(CONFIG_CPU_SUBTYPE_SH7763) - mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR);/* CERCR */ - sh_eth_write(ndev, 0, CERCR); /* (write clear) */ - mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR);/* CEECR */ - sh_eth_write(ndev, 0, CEECR); /* (write clear) */ -#else - mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR); - sh_eth_write(ndev, 0, CNDCR); /* (write clear) */ -#endif + if (sh_eth_is_gether(mdp)) { + mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR); + sh_eth_write(ndev, 0, CERCR); /* (write clear) */ + mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR); + sh_eth_write(ndev, 0, CEECR); /* (write clear) */ + } else { + mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR); + sh_eth_write(ndev, 0, CNDCR); /* (write clear) */ + } pm_runtime_put_sync(&mdp->pdev->dev); return &mdp->stats; @@ -1465,13 +1479,13 @@ static void sh_eth_tsu_init(struct sh_eth_private *mdp) sh_eth_tsu_write(mdp, 0, TSU_FWSL0); sh_eth_tsu_write(mdp, 0, TSU_FWSL1); sh_eth_tsu_write(mdp, TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, TSU_FWSLC); -#if defined(CONFIG_CPU_SUBTYPE_SH7763) - sh_eth_tsu_write(mdp, 0, TSU_QTAG0); /* Disable QTAG(0->1) */ - sh_eth_tsu_write(mdp, 0, TSU_QTAG1); /* Disable QTAG(1->0) */ -#else - sh_eth_tsu_write(mdp, 0, TSU_QTAGM0); /* Disable QTAG(0->1) */ - sh_eth_tsu_write(mdp, 0, TSU_QTAGM1); /* Disable QTAG(1->0) */ -#endif + if (sh_eth_is_gether(mdp)) { + sh_eth_tsu_write(mdp, 0, TSU_QTAG0); /* Disable QTAG(0->1) */ + sh_eth_tsu_write(mdp, 0, TSU_QTAG1); /* Disable QTAG(1->0) */ + } else { + sh_eth_tsu_write(mdp, 0, TSU_QTAGM0); /* Disable QTAG(0->1) */ + sh_eth_tsu_write(mdp, 0, TSU_QTAGM1); /* Disable QTAG(1->0) */ + } sh_eth_tsu_write(mdp, 0, TSU_FWSR); /* all interrupt status clear */ sh_eth_tsu_write(mdp, 0, TSU_FWINMK); /* Disable all interrupt */ sh_eth_tsu_write(mdp, 0, TSU_TEN); /* Disable all CAM entry */ diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h index 35a3adbb2e7a..b349c5e2bcda 100644 --- a/drivers/net/sh_eth.h +++ b/drivers/net/sh_eth.h @@ -400,20 +400,14 @@ enum GECMR_BIT { enum DMAC_M_BIT { EDMR_EL = 0x40, /* Litte endian */ EDMR_DL1 = 0x20, EDMR_DL0 = 0x10, -#ifdef CONFIG_CPU_SUBTYPE_SH7763 - EDMR_SRST = 0x03, -#else /* CONFIG_CPU_SUBTYPE_SH7763 */ - EDMR_SRST = 0x01, -#endif + EDMR_SRST_GETHER = 0x03, + EDMR_SRST_ETHER = 0x01, }; /* EDTRR */ enum DMAC_T_BIT { -#ifdef CONFIG_CPU_SUBTYPE_SH7763 - EDTRR_TRNS = 0x03, -#else - EDTRR_TRNS = 0x01, -#endif + EDTRR_TRNS_GETHER = 0x03, + EDTRR_TRNS_ETHER = 0x01, }; /* EDRRR*/ -- cgit v1.2.3 From e47c90523484518aac30498150e427d824ace705 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 7 Mar 2011 21:59:45 +0000 Subject: net: sh_eth: modify the PHY_INTERFACE_MODE The previous code had hardcoded the PHY_INTERFACE_MODE_MII of phy_connect. So some Gigabit PHYs will not behave correctly. The patch adds the phy_interface in sh_eth_plat_data, so we can select the phy interface. Signed-off-by: Yoshihiro Shimoda Signed-off-by: David S. Miller --- arch/sh/include/asm/sh_eth.h | 3 +++ drivers/net/sh_eth.c | 3 ++- drivers/net/sh_eth.h | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/arch/sh/include/asm/sh_eth.h b/arch/sh/include/asm/sh_eth.h index 155769601065..e86c880b7e4c 100644 --- a/arch/sh/include/asm/sh_eth.h +++ b/arch/sh/include/asm/sh_eth.h @@ -1,6 +1,8 @@ #ifndef __ASM_SH_ETH_H__ #define __ASM_SH_ETH_H__ +#include + enum {EDMAC_LITTLE_ENDIAN, EDMAC_BIG_ENDIAN}; enum { SH_ETH_REG_GIGABIT, @@ -12,6 +14,7 @@ struct sh_eth_plat_data { int phy; int edmac_endian; int register_type; + phy_interface_t phy_interface; unsigned char mac_addr[6]; unsigned no_ether_link:1; diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 6734311e56e4..5d28ce68f357 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -1071,7 +1071,7 @@ static int sh_eth_phy_init(struct net_device *ndev) /* Try connect to PHY */ phydev = phy_connect(ndev, phy_id, sh_eth_adjust_link, - 0, PHY_INTERFACE_MODE_MII); + 0, mdp->phy_interface); if (IS_ERR(phydev)) { dev_err(&ndev->dev, "phy_connect failed\n"); return PTR_ERR(phydev); @@ -1669,6 +1669,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev) pd = (struct sh_eth_plat_data *)(pdev->dev.platform_data); /* get PHY ID */ mdp->phy_id = pd->phy; + mdp->phy_interface = pd->phy_interface; /* EDMAC endian */ mdp->edmac_endian = pd->edmac_endian; mdp->no_ether_link = pd->no_ether_link; diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h index b349c5e2bcda..c3048a6ba676 100644 --- a/drivers/net/sh_eth.h +++ b/drivers/net/sh_eth.h @@ -781,6 +781,7 @@ struct sh_eth_private { struct mii_bus *mii_bus; /* MDIO bus control */ struct phy_device *phydev; /* PHY device control */ enum phy_state link; + phy_interface_t phy_interface; int msg_enable; int speed; int duplex; -- cgit v1.2.3 From 8fcd496151b4354569283056076339239b86fabe Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 7 Mar 2011 21:59:49 +0000 Subject: net: sh_eth: add support for SH7757's GETHER The SH7757 have GETHER and ETHER both. This patch supports them. Signed-off-by: Yoshihiro Shimoda Signed-off-by: David S. Miller --- drivers/net/sh_eth.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 135 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 5d28ce68f357..dcf9f87d021f 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -94,7 +94,8 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { .rpadir_value = 0x00020000, /* NET_IP_ALIGN assumed to be 2 */ }; #elif defined(CONFIG_CPU_SUBTYPE_SH7757) -#define SH_ETH_RESET_DEFAULT 1 +#define SH_ETH_HAS_BOTH_MODULES 1 +#define SH_ETH_HAS_TSU 1 static void sh_eth_set_duplex(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); @@ -141,6 +142,135 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { .no_ade = 1, }; +#define SH_GIGA_ETH_BASE 0xfee00000 +#define GIGA_MALR(port) (SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c8) +#define GIGA_MAHR(port) (SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c0) +static void sh_eth_chip_reset_giga(struct net_device *ndev) +{ + int i; + unsigned long mahr[2], malr[2]; + + /* save MAHR and MALR */ + for (i = 0; i < 2; i++) { + malr[i] = readl(GIGA_MALR(i)); + mahr[i] = readl(GIGA_MAHR(i)); + } + + /* reset device */ + writel(ARSTR_ARSTR, SH_GIGA_ETH_BASE + 0x1800); + mdelay(1); + + /* restore MAHR and MALR */ + for (i = 0; i < 2; i++) { + writel(malr[i], GIGA_MALR(i)); + writel(mahr[i], GIGA_MAHR(i)); + } +} + +static int sh_eth_is_gether(struct sh_eth_private *mdp); +static void sh_eth_reset(struct net_device *ndev) +{ + struct sh_eth_private *mdp = netdev_priv(ndev); + int cnt = 100; + + if (sh_eth_is_gether(mdp)) { + sh_eth_write(ndev, 0x03, EDSR); + sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, + EDMR); + while (cnt > 0) { + if (!(sh_eth_read(ndev, EDMR) & 0x3)) + break; + mdelay(1); + cnt--; + } + if (cnt < 0) + printk(KERN_ERR "Device reset fail\n"); + + /* Table Init */ + sh_eth_write(ndev, 0x0, TDLAR); + sh_eth_write(ndev, 0x0, TDFAR); + sh_eth_write(ndev, 0x0, TDFXR); + sh_eth_write(ndev, 0x0, TDFFR); + sh_eth_write(ndev, 0x0, RDLAR); + sh_eth_write(ndev, 0x0, RDFAR); + sh_eth_write(ndev, 0x0, RDFXR); + sh_eth_write(ndev, 0x0, RDFFR); + } else { + sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER, + EDMR); + mdelay(3); + sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER, + EDMR); + } +} + +static void sh_eth_set_duplex_giga(struct net_device *ndev) +{ + struct sh_eth_private *mdp = netdev_priv(ndev); + + if (mdp->duplex) /* Full */ + sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR); + else /* Half */ + sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR); +} + +static void sh_eth_set_rate_giga(struct net_device *ndev) +{ + struct sh_eth_private *mdp = netdev_priv(ndev); + + switch (mdp->speed) { + case 10: /* 10BASE */ + sh_eth_write(ndev, 0x00000000, GECMR); + break; + case 100:/* 100BASE */ + sh_eth_write(ndev, 0x00000010, GECMR); + break; + case 1000: /* 1000BASE */ + sh_eth_write(ndev, 0x00000020, GECMR); + break; + default: + break; + } +} + +/* SH7757(GETHERC) */ +static struct sh_eth_cpu_data sh_eth_my_cpu_data_giga = { + .chip_reset = sh_eth_chip_reset_giga, + .set_duplex = sh_eth_set_duplex_giga, + .set_rate = sh_eth_set_rate_giga, + + .ecsr_value = ECSR_ICD | ECSR_MPD, + .ecsipr_value = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP, + .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, + + .tx_check = EESR_TC1 | EESR_FTC, + .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \ + EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \ + EESR_ECI, + .tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \ + EESR_TFE, + .fdr_value = 0x0000072f, + .rmcr_value = 0x00000001, + + .apr = 1, + .mpr = 1, + .tpauser = 1, + .bculr = 1, + .hw_swap = 1, + .rpadir = 1, + .rpadir_value = 2 << 16, + .no_trimd = 1, + .no_ade = 1, +}; + +static struct sh_eth_cpu_data *sh_eth_get_cpu_data(struct sh_eth_private *mdp) +{ + if (sh_eth_is_gether(mdp)) + return &sh_eth_my_cpu_data_giga; + else + return &sh_eth_my_cpu_data; +} + #elif defined(CONFIG_CPU_SUBTYPE_SH7763) #define SH_ETH_HAS_TSU 1 static void sh_eth_chip_reset(struct net_device *ndev) @@ -1677,7 +1807,11 @@ static int sh_eth_drv_probe(struct platform_device *pdev) mdp->reg_offset = sh_eth_get_register_offset(pd->register_type); /* set cpu data */ +#if defined(SH_ETH_HAS_BOTH_MODULES) + mdp->cd = sh_eth_get_cpu_data(mdp); +#else mdp->cd = &sh_eth_my_cpu_data; +#endif sh_eth_set_default_cpu_data(mdp->cd); /* set function */ -- cgit v1.2.3 From b3017e6a03d261778ad9450b5510460c4d462203 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 7 Mar 2011 21:59:55 +0000 Subject: net: sh_eth: add set_mdio_gate in bb_info The SH7757's ETHER and GETHER use common MDIO pin. The MDIO pin is selected by specific register. So this patch adds new interface in bb_info, and when the sh_eth driver use the mdio, the register can be changed by the function. Signed-off-by: Yoshihiro Shimoda Signed-off-by: David S. Miller --- arch/sh/include/asm/sh_eth.h | 1 + drivers/net/sh_eth.c | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/arch/sh/include/asm/sh_eth.h b/arch/sh/include/asm/sh_eth.h index e86c880b7e4c..0f325da0f923 100644 --- a/arch/sh/include/asm/sh_eth.h +++ b/arch/sh/include/asm/sh_eth.h @@ -15,6 +15,7 @@ struct sh_eth_plat_data { int edmac_endian; int register_type; phy_interface_t phy_interface; + void (*set_mdio_gate)(unsigned long addr); unsigned char mac_addr[6]; unsigned no_ether_link:1; diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index dcf9f87d021f..e9e7a530552c 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -512,6 +512,7 @@ static unsigned long sh_eth_get_edtrr_trns(struct sh_eth_private *mdp) } struct bb_info { + void (*set_gate)(unsigned long addr); struct mdiobb_ctrl ctrl; u32 addr; u32 mmd_msk;/* MMD */ @@ -542,6 +543,10 @@ static int bb_read(u32 addr, u32 msk) static void sh_mmd_ctrl(struct mdiobb_ctrl *ctrl, int bit) { struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); + + if (bitbang->set_gate) + bitbang->set_gate(bitbang->addr); + if (bit) bb_set(bitbang->addr, bitbang->mmd_msk); else @@ -553,6 +558,9 @@ static void sh_set_mdio(struct mdiobb_ctrl *ctrl, int bit) { struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); + if (bitbang->set_gate) + bitbang->set_gate(bitbang->addr); + if (bit) bb_set(bitbang->addr, bitbang->mdo_msk); else @@ -563,6 +571,10 @@ static void sh_set_mdio(struct mdiobb_ctrl *ctrl, int bit) static int sh_get_mdio(struct mdiobb_ctrl *ctrl) { struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); + + if (bitbang->set_gate) + bitbang->set_gate(bitbang->addr); + return bb_read(bitbang->addr, bitbang->mdi_msk); } @@ -571,6 +583,9 @@ static void sh_mdc_ctrl(struct mdiobb_ctrl *ctrl, int bit) { struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); + if (bitbang->set_gate) + bitbang->set_gate(bitbang->addr); + if (bit) bb_set(bitbang->addr, bitbang->mdc_msk); else @@ -1646,7 +1661,8 @@ static int sh_mdio_release(struct net_device *ndev) } /* MDIO bus init function */ -static int sh_mdio_init(struct net_device *ndev, int id) +static int sh_mdio_init(struct net_device *ndev, int id, + struct sh_eth_plat_data *pd) { int ret, i; struct bb_info *bitbang; @@ -1661,6 +1677,7 @@ static int sh_mdio_init(struct net_device *ndev, int id) /* bitbang init */ bitbang->addr = ndev->base_addr + mdp->reg_offset[PIR]; + bitbang->set_gate = pd->set_mdio_gate; bitbang->mdi_msk = 0x08; bitbang->mdo_msk = 0x04; bitbang->mmd_msk = 0x02;/* MMD */ @@ -1854,7 +1871,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev) goto out_release; /* mdio bus init */ - ret = sh_mdio_init(ndev, pdev->id); + ret = sh_mdio_init(ndev, pdev->id, pd); if (ret) goto out_unregister; -- cgit v1.2.3 From 942527634e201883b39fe0c97a1e47db7a026f91 Mon Sep 17 00:00:00 2001 From: Michel Lespinasse Date: Sun, 6 Mar 2011 16:14:50 +0000 Subject: drivers/net: fix build warnings with CONFIG_PM_SLEEP disabled This fixes a couple of build warnings when CONFIG_PM is enabled but CONFIG_PM_SLEEP is disabled. Applies on top of v2.6.38-rc7 - I know it's late, but it would be great if v2.6.38 could compile without warnings! Signed-off-by: Michel Lespinasse Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 8 ++++++-- drivers/net/sky2.c | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 9c0b1bac6af6..7b92897ca66b 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -5744,7 +5744,7 @@ static void __devexit nv_remove(struct pci_dev *pci_dev) pci_set_drvdata(pci_dev, NULL); } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int nv_suspend(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); @@ -5795,6 +5795,11 @@ static int nv_resume(struct device *device) static SIMPLE_DEV_PM_OPS(nv_pm_ops, nv_suspend, nv_resume); #define NV_PM_OPS (&nv_pm_ops) +#else +#define NV_PM_OPS NULL +#endif /* CONFIG_PM_SLEEP */ + +#ifdef CONFIG_PM static void nv_shutdown(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); @@ -5822,7 +5827,6 @@ static void nv_shutdown(struct pci_dev *pdev) } } #else -#define NV_PM_OPS NULL #define nv_shutdown NULL #endif /* CONFIG_PM */ diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 7d85a38377a1..2a91868788f7 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -4983,7 +4983,7 @@ static int sky2_suspend(struct device *dev) return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int sky2_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); -- cgit v1.2.3 From 2a543904ddcb463db9d56d1efcb2f80884ea55f3 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Tue, 26 Oct 2010 15:47:52 +0000 Subject: IB/ipath: Don't reset disabled devices The comment some lines above states that disabled devices must not reset. Signed-off-by: Nicolas Kaiser --- drivers/infiniband/hw/ipath/ipath_sysfs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/infiniband/hw/ipath/ipath_sysfs.c b/drivers/infiniband/hw/ipath/ipath_sysfs.c index b8cb2f145ae4..8991677e9a08 100644 --- a/drivers/infiniband/hw/ipath/ipath_sysfs.c +++ b/drivers/infiniband/hw/ipath/ipath_sysfs.c @@ -557,6 +557,7 @@ static ssize_t store_reset(struct device *dev, dev_info(dev,"Unit %d is disabled, can't reset\n", dd->ipath_unit); ret = -EINVAL; + goto bail; } ret = ipath_reset_device(dd->ipath_unit); bail: -- cgit v1.2.3 From 0b32211164da2b100553cb45e4e862f09c5cab11 Mon Sep 17 00:00:00 2001 From: roel kluin Date: Tue, 8 Mar 2011 09:52:55 +0000 Subject: can: wrong index used in inner loop Index i was already used in the outer loop. Signed-off-by: Roel Kluin Signed-off-by: David S. Miller --- drivers/net/can/usb/esd_usb2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c index 05a52754f486..dc53c831ea95 100644 --- a/drivers/net/can/usb/esd_usb2.c +++ b/drivers/net/can/usb/esd_usb2.c @@ -659,7 +659,7 @@ failed: static void unlink_all_urbs(struct esd_usb2 *dev) { struct esd_usb2_net_priv *priv; - int i; + int i, j; usb_kill_anchored_urbs(&dev->rx_submitted); for (i = 0; i < dev->net_count; i++) { @@ -668,8 +668,8 @@ static void unlink_all_urbs(struct esd_usb2 *dev) usb_kill_anchored_urbs(&priv->tx_submitted); atomic_set(&priv->active_tx_jobs, 0); - for (i = 0; i < MAX_TX_URBS; i++) - priv->tx_contexts[i].echo_index = MAX_TX_URBS; + for (j = 0; j < MAX_TX_URBS; j++) + priv->tx_contexts[j].echo_index = MAX_TX_URBS; } } } -- cgit v1.2.3 From ea0f0d8bc6d13c2580d668ecf95297d5105a57fc Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Tue, 8 Mar 2011 15:35:30 +0000 Subject: enic: Support newer version of firmware devcmd CMD_MCPU_FW_INFO This patch provides support to the newer version of firmware devcmd CMD_MCPU_FW_INFO that returns additional information (ASIC type and revision) about the underlying hardware. This knowledge is required by the driver to implement any hardware specific features. Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 2 +- drivers/net/enic/vnic_dev.c | 7 +++++++ drivers/net/enic/vnic_devcmd.h | 38 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 44 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index e816bbb9fbf9..3a3c3c8a3a9b 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "2.1.1.10" +#define DRV_VERSION "2.1.1.12" #define DRV_COPYRIGHT "Copyright 2008-2011 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c index c489e72107de..c089b362a36f 100644 --- a/drivers/net/enic/vnic_dev.c +++ b/drivers/net/enic/vnic_dev.c @@ -408,10 +408,17 @@ int vnic_dev_fw_info(struct vnic_dev *vdev, if (!vdev->fw_info) return -ENOMEM; + memset(vdev->fw_info, 0, sizeof(struct vnic_devcmd_fw_info)); + a0 = vdev->fw_info_pa; + a1 = sizeof(struct vnic_devcmd_fw_info); /* only get fw_info once and cache it */ err = vnic_dev_cmd(vdev, CMD_MCPU_FW_INFO, &a0, &a1, wait); + if (err == ERR_ECMDUNKNOWN) { + err = vnic_dev_cmd(vdev, CMD_MCPU_FW_INFO_OLD, + &a0, &a1, wait); + } } *fw_info = vdev->fw_info; diff --git a/drivers/net/enic/vnic_devcmd.h b/drivers/net/enic/vnic_devcmd.h index 9abb3d51dea1..d833a071bac5 100644 --- a/drivers/net/enic/vnic_devcmd.h +++ b/drivers/net/enic/vnic_devcmd.h @@ -80,8 +80,34 @@ enum vnic_devcmd_cmd { CMD_NONE = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_NONE, 0), - /* mcpu fw info in mem: (u64)a0=paddr to struct vnic_devcmd_fw_info */ - CMD_MCPU_FW_INFO = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 1), + /* + * mcpu fw info in mem: + * in: + * (u64)a0=paddr to struct vnic_devcmd_fw_info + * action: + * Fills in struct vnic_devcmd_fw_info (128 bytes) + * note: + * An old definition of CMD_MCPU_FW_INFO + */ + CMD_MCPU_FW_INFO_OLD = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 1), + + /* + * mcpu fw info in mem: + * in: + * (u64)a0=paddr to struct vnic_devcmd_fw_info + * (u16)a1=size of the structure + * out: + * (u16)a1=0 for in:a1 = 0, + * data size actually written for other values. + * action: + * Fills in first 128 bytes of vnic_devcmd_fw_info for in:a1 = 0, + * first in:a1 bytes for 0 < in:a1 <= 132, + * 132 bytes for other values of in:a1. + * note: + * CMD_MCPU_FW_INFO and CMD_MCPU_FW_INFO_OLD have the same enum 1 + * for source compatibility. + */ + CMD_MCPU_FW_INFO = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 1), /* dev-specific block member: * in: (u16)a0=offset,(u8)a1=size @@ -291,11 +317,19 @@ enum vnic_devcmd_error { ERR_EMAXRES = 10, }; +/* + * note: hw_version and asic_rev refer to the same thing, + * but have different formats. hw_version is + * a 32-byte string (e.g. "A2") and asic_rev is + * a 16-bit integer (e.g. 0xA2). + */ struct vnic_devcmd_fw_info { char fw_version[32]; char fw_build[32]; char hw_version[32]; char hw_serial_number[32]; + u16 asic_type; + u16 asic_rev; }; struct vnic_devcmd_notify { -- cgit v1.2.3 From dc187cb381f1bceb30498861ece510245c43ed9f Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 14 Mar 2011 15:00:12 -0700 Subject: bnx2: Update firmware and version Update 5709 mips firmware to 6.2.1a to fix iSCSI performance regression. There was an unnecessary context read in the fast path affecting performance. Update bnx2 to 2.1.6. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 8 +- drivers/net/bnx2.h | 2 +- firmware/Makefile | 2 +- firmware/WHENCE | 2 +- firmware/bnx2/bnx2-mips-09-6.2.1.fw.ihex | 6526 ----------------------------- firmware/bnx2/bnx2-mips-09-6.2.1a.fw.ihex | 6512 ++++++++++++++++++++++++++++ 6 files changed, 6519 insertions(+), 6533 deletions(-) delete mode 100644 firmware/bnx2/bnx2-mips-09-6.2.1.fw.ihex create mode 100644 firmware/bnx2/bnx2-mips-09-6.2.1a.fw.ihex (limited to 'drivers') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 2a961b7f7e17..d1865cc97313 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -1,6 +1,6 @@ /* bnx2.c: Broadcom NX2 network driver. * - * Copyright (c) 2004-2010 Broadcom Corporation + * Copyright (c) 2004-2011 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -56,11 +56,11 @@ #include "bnx2_fw.h" #define DRV_MODULE_NAME "bnx2" -#define DRV_MODULE_VERSION "2.0.21" -#define DRV_MODULE_RELDATE "Dec 23, 2010" +#define DRV_MODULE_VERSION "2.1.6" +#define DRV_MODULE_RELDATE "Mar 7, 2011" #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.2.1.fw" #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw" -#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1.fw" +#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1a.fw" #define FW_RV2P_FILE_09_Ax "bnx2/bnx2-rv2p-09ax-6.0.17.fw" #define FW_RV2P_FILE_09 "bnx2/bnx2-rv2p-09-6.0.17.fw" diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 7a5e88f831f6..68020451dc4f 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -1,6 +1,6 @@ /* bnx2.h: Broadcom NX2 network driver. * - * Copyright (c) 2004-2009 Broadcom Corporation + * Copyright (c) 2004-2011 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/firmware/Makefile b/firmware/Makefile index 0a9d1e28ad23..0384afa93de9 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -35,7 +35,7 @@ fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-6.2.5.0.fw \ bnx2x/bnx2x-e1h-6.2.5.0.fw \ bnx2x/bnx2x-e2-6.2.5.0.fw -fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-6.2.1.fw \ +fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-6.2.1a.fw \ bnx2/bnx2-rv2p-09-6.0.17.fw \ bnx2/bnx2-rv2p-09ax-6.0.17.fw \ bnx2/bnx2-mips-06-6.2.1.fw \ diff --git a/firmware/WHENCE b/firmware/WHENCE index 14aaee85d062..76404f9ce74d 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -701,7 +701,7 @@ Driver: BNX2 - Broadcom NetXtremeII File: bnx2/bnx2-mips-06-6.2.1.fw File: bnx2/bnx2-rv2p-06-6.0.15.fw -File: bnx2/bnx2-mips-09-6.2.1.fw +File: bnx2/bnx2-mips-09-6.2.1a.fw File: bnx2/bnx2-rv2p-09-6.0.17.fw File: bnx2/bnx2-rv2p-09ax-6.0.17.fw diff --git a/firmware/bnx2/bnx2-mips-09-6.2.1.fw.ihex b/firmware/bnx2/bnx2-mips-09-6.2.1.fw.ihex deleted file mode 100644 index 68279b53e102..000000000000 --- a/firmware/bnx2/bnx2-mips-09-6.2.1.fw.ihex +++ /dev/null @@ -1,6526 +0,0 @@ -:10000000080001180800000000005594000000C816 -:1000100000000000000000000000000008005594EF -:10002000000000380000565C080000A00800000036 -:100030000000574400005694080059200000008436 -:100040000000ADD808005744000001C00000AE5CBD -:100050000800321008000000000092F80000B01CF8 -:10006000000000000000000000000000080092F8FE -:100070000000033C00014314080004900800040041 -:10008000000012FC000146500000000000000000CB -:1000900000000000080016FC000000040001594C9C -:1000A000080000A80800000000003D280001595089 -:1000B00000000000000000000000000008003D28D3 -:0800C0000000003000019678F9 -:0800C8000A00004600000000E0 -:1000D000000000000000000D636F6D362E322E31DF -:1000E0000000000006020102000000000000000302 -:1000F000000000C800000032000000030000000003 -:1001000000000000000000000000000000000000EF -:1001100000000010000001360000EA600000000549 -:1001200000000000000000000000000000000008C7 -:1001300000000000000000000000000000000000BF -:1001400000000000000000000000000000000000AF -:10015000000000000000000000000000000000009F -:10016000000000020000000000000000000000008D -:10017000000000000000000000000000000000007F -:10018000000000000000000000000010000000005F -:10019000000000000000000000000000000000005F -:1001A000000000000000000000000000000000004F -:1001B000000000000000000000000000000000003F -:1001C000000000000000000000000000000000002F -:1001D000000000000000000000000000000000001F -:1001E0000000000010000003000000000000000DEF -:1001F0000000000D3C020800244256083C030800A1 -:1002000024635754AC4000000043202B1480FFFDB2 -:10021000244200043C1D080037BD9FFC03A0F021D0 -:100220003C100800261001183C1C0800279C5608AA -:100230000E000256000000000000000D27BDFFB4B4 -:10024000AFA10000AFA20004AFA30008AFA4000C50 -:10025000AFA50010AFA60014AFA70018AFA8001CF0 -:10026000AFA90020AFAA0024AFAB0028AFAC002C90 -:10027000AFAD0030AFAE0034AFAF0038AFB8003C28 -:10028000AFB90040AFBC0044AFBF00480E001544FA -:10029000000000008FBF00488FBC00448FB90040B1 -:1002A0008FB8003C8FAF00388FAE00348FAD003078 -:1002B0008FAC002C8FAB00288FAA00248FA90020C0 -:1002C0008FA8001C8FA700188FA600148FA5001000 -:1002D0008FA4000C8FA300088FA200048FA1000040 -:1002E00027BD004C3C1B60108F7A5030377B502864 -:1002F00003400008AF7A00008F82002427BDFFE092 -:10030000AFB00010AFBF0018AFB100148C42000CAA -:100310003C1080008E110100104000348FBF001887 -:100320000E000D84000000008F85002024047FFF54 -:100330000091202BACB100008E030104960201084D -:1003400000031C003042FFFF00621825ACA300042C -:100350009202010A96030114304200FF3063FFFF4E -:100360000002140000431025ACA200089603010C03 -:100370009602010E00031C003042FFFF00621825A8 -:10038000ACA3000C960301109602011200031C009E -:100390003042FFFF00621825ACA300108E02011846 -:1003A000ACA200148E02011CACA20018148000083C -:1003B0008F820024978200003C0420050044182509 -:1003C00024420001ACA3001C0A0000C6A782000062 -:1003D0003C0340189442001E00431025ACA2001CB0 -:1003E0000E000DB8240400018FBF00188FB1001457 -:1003F0008FB000100000102103E0000827BD00208E -:100400003C0780008CE202B834E50100044100089A -:10041000240300013C0208008C42006024420001D9 -:100420003C010800AC22006003E0000800601021DD -:100430003C0208008C42005C8CA4002094A30016AF -:100440008CA6000494A5000E24420001ACE40280B6 -:100450002463FFFC3C010800AC22005C3C0210005D -:10046000A4E30284A4E5028600001821ACE6028819 -:10047000ACE202B803E000080060102127BDFFE0F5 -:100480003C028000AFB0001034420100AFBF001C3E -:10049000AFB20018AFB100148C43000094450008BF -:1004A0002462FE002C42038110400003000381C23D -:1004B0000A00010226100004240201001462000553 -:1004C0003C1180003C02800890420004305000FF44 -:1004D0003C11800036320100964300143202000FB6 -:1004E00000021500004310253C0308008C63004403 -:1004F00030A40004AE220080246300013C01080007 -:10050000AC2300441080000730A200028FBF001C03 -:100510008FB200188FB100148FB000100A0000CE07 -:1005200027BD00201040002D0000182130A20080BF -:1005300010400005362200708E44001C0E000C672F -:10054000240500A0362200708C4400008F82000C2D -:10055000008210232C43012C10600004AF82001095 -:10056000240300010A000145AF84000C8E42000400 -:100570003C036020AF84000CAC6200143C02080015 -:100580008C42005850400015000018218C62000475 -:10059000240301FE304203FF144300100000182121 -:1005A0002E020004104000032E0200080A00014041 -:1005B0000000802114400003000000000A000140F8 -:1005C0002610FFF90000000D2402000202021004B0 -:1005D0003C036000AC626914000018218FBF001C4E -:1005E0008FB200188FB100148FB00010006010217E -:1005F00003E0000827BD00203C0480008C8301003C -:1006000024020100506200033C0280080000000D3B -:100610003C02800890430004000010213063000F6A -:1006200000031D0003E00008AC8300800004188074 -:100630002782FF9C00621821000410C00044102390 -:100640008C640000000210C03C030800246356E4E0 -:10065000004310213C038000AC64009003E00008DC -:10066000AF8200243C0208008C42011410400019A3 -:100670003084400030A2007F000231C03C02020002 -:100680001080001400A218253C026020AC43001426 -:100690003C0408008C8456B83C0308008C630110AD -:1006A0003C02800024050900AC4500200086202182 -:1006B000246300013C028008AC4400643C01080053 -:1006C000AC2301103C010800AC2456B803E000083C -:1006D000000000003C02602003E00008AC4500146C -:1006E00003E000080000102103E0000800001021D2 -:1006F00030A2000810400008240201003C0208005B -:100700008C42010C244200013C010800AC22010C87 -:1007100003E0000800000000148200080000000050 -:100720003C0208008C4200FC244200013C0108000D -:10073000AC2200FC0A0001A330A200203C02080009 -:100740008C420084244200013C010800AC22008459 -:1007500030A200201040000830A200103C02080027 -:100760008C420108244200013C010800AC2201082F -:1007700003E0000800000000104000080000000036 -:100780003C0208008C420104244200013C010800A4 -:10079000AC22010403E00008000000003C02080055 -:1007A0008C420100244200013C010800AC220100FF -:1007B00003E000080000000027BDFFE0AFB1001417 -:1007C0003C118000AFB20018AFBF001CAFB00010EA -:1007D0003632010096500008320200041040000733 -:1007E000320300028FBF001C8FB200188FB10014BB -:1007F0008FB000100A0000CE27BD00201060000B53 -:10080000020028218E2401000E00018A0000000051 -:100810003202008010400003240500A10E000C6786 -:100820008E44001C0A0001E3240200018E2301040F -:100830008F82000810430006020028218E24010048 -:100840000E00018A000000008E220104AF82000821 -:10085000000010218FBF001C8FB200188FB1001450 -:100860008FB0001003E0000827BD00202C82000498 -:1008700014400002000018212483FFFD240200021E -:10088000006210043C03600003E00008AC626914DD -:1008900027BDFFE0AFBF001CAFB20018AFB100141E -:1008A000AFB000103C048000948201083043700017 -:1008B000240220001062000A2862200154400052E5 -:1008C0008FBF001C24024000106200482402600018 -:1008D0001062004A8FBF001C0A0002518FB200183C -:1008E00034820100904300098C5000189451000C90 -:1008F000240200091062001C0000902128620009F7 -:10090000144000218F8200242402000A5062001249 -:10091000323100FF2402000B1062000F00000000C3 -:100920002402000C146200188F8200243C0208008C -:100930008C4256B824030900AC83002000501021DB -:100940003C038008AC6200643C010800AC2256B84D -:100950000A0002508FBF001C0E0001E900102602A1 -:100960000A0002308F8200240E0001E900102602E6 -:100970003C0380089462001A8C72000C3042FFFF26 -:10098000020280258F8200248C42000C5040001E01 -:100990008FBF001C0E000D84000000003C02800090 -:1009A00034420100944300088F82002400031C009D -:1009B0009444001E8F82002000641825AC50000073 -:1009C00024040001AC510004AC520008AC40000CFF -:1009D000AC400010AC400014AC4000180E000DB844 -:1009E000AC43001C0A0002508FBF001C0E000440E4 -:1009F000000000000A0002508FBF001C0E000C9F78 -:100A0000000000008FBF001C8FB200188FB10014CF -:100A10008FB000100000102103E0000827BD002067 -:100A200027BDFFD8AFB400203C036010AFBF002447 -:100A3000AFB3001CAFB20018AFB10014AFB00010DC -:100A40008C6450002402FF7F3C1408002694563822 -:100A5000008220243484380CAC6450003C028000B6 -:100A6000240300370E0014B0AC4300083C07080014 -:100A700024E70618028010212404001D2484FFFFAF -:100A8000AC4700000481FFFD244200043C02080042 -:100A9000244207C83C010800AC2256403C02080032 -:100AA000244202303C030800246306203C04080072 -:100AB000248403B43C05080024A506F03C06080085 -:100AC00024C62C9C3C010800AC2256803C02080045 -:100AD000244205303C010800AC2756843C01080044 -:100AE000AC2656943C010800AC23569C3C010800FF -:100AF000AC2456A03C010800AC2556A43C010800DB -:100B0000AC2256A83C010800AC23563C3C0108002E -:100B1000AC2456443C010800AC2056603C0108005F -:100B2000AC2556643C010800AC2056703C0108001E -:100B3000AC27567C3C010800AC2656903C010800CE -:100B4000AC2356980E00056E00000000AF80000C2C -:100B50003C0280008C5300008F8300043C0208009C -:100B60008C420020106200213262000700008821C0 -:100B70002792FF9C3C100800261056E43C02080017 -:100B80008C42002024050001022518040043202483 -:100B90008F820004004310245044000C26310001D1 -:100BA00010800008AF9000248E4300003C028000BB -:100BB000AC4300900E000D4BAE05000C0A0002C1C4 -:100BC00026310001AE00000C263100012E22000269 -:100BD000261000381440FFE9265200043C020800A9 -:100BE0008C420020AF820004326200071040FFD91F -:100BF0003C028000326200011040002D326200028F -:100C00003C0580008CA2010000002021ACA2002045 -:100C10008CA301042C42078110400008ACA300A85B -:100C200094A2010824032000304270001443000302 -:100C30003C02800890420005304400FF0E0001593C -:100C4000000000003C0280009042010B304300FF96 -:100C50002C62001E54400004000310800E00018628 -:100C60000A0002EC00000000005410218C42000039 -:100C70000040F80900000000104000043C02800021 -:100C80008C4301043C026020AC4300143C02080089 -:100C90008C4200343C0440003C03800024420001AC -:100CA000AC6401383C010800AC220034326200021E -:100CB00010400010326200043C1080008E0201409F -:100CC000000020210E000159AE0200200E00038317 -:100CD000000000003C024000AE0201783C02080027 -:100CE0008C420038244200013C010800AC2200384C -:100CF000326200041040FF973C0280003C108000EC -:100D00008E020180000020210E000159AE02002059 -:100D10008E03018024020F00546200073C02800809 -:100D20008E0201883C0300E03042FFFF00431025A3 -:100D30000A000328AE020080344200809042000086 -:100D400024030050304200FF14430007000000005D -:100D50000E000362000000001440000300000000C9 -:100D60000E000971000000003C0208008C42003CAB -:100D70003C0440003C03800024420001AC6401B804 -:100D80003C010800AC22003C0A0002A33C028000A7 -:100D90003C02900034420001008220253C02800089 -:100DA000AC4400203C0380008C6200200440FFFE25 -:100DB0000000000003E00008000000003C0280008A -:100DC000344300010083202503E00008AC440020E8 -:100DD00027BDFFE0AFB10014AFB000100080882144 -:100DE000AFBF00180E00033230B000FF8F83FF94B6 -:100DF000022020219062002502028025A07000259B -:100E00008C7000183C0280000E00033D020280241A -:100E10001600000B8FBF00183C0480008C8201F884 -:100E20000440FFFE348201C024030002AC510000E4 -:100E3000A04300043C021000AC8201F88FBF0018F0 -:100E40008FB100148FB0001003E0000827BD002010 -:100E500027BDFFE83C028000AFBF00103442018094 -:100E6000944300048C4400083063020010600005C5 -:100E7000000028210E00100C000000000A0003787A -:100E8000240500013C02FF000480000700821824B2 -:100E90003C02040014620004240500018F82FF94C8 -:100EA00090420008240500018FBF001000A010210F -:100EB00003E0000827BD00188F82FF982405000179 -:100EC000A040001A3C028000344201400A00034264 -:100ED0008C4400008F85FF9427BDFFE0AFBF001C4E -:100EE000AFB20018AFB10014AFB0001090A2000074 -:100EF000304400FF38830020388200300003182B74 -:100F00000002102B0062182410600003240200501D -:100F1000148200A88FBF001C90A20005304200017F -:100F2000104000A48FBF001C3C02800034420140EE -:100F3000904200082443FFFF2C6200051040009EF1 -:100F40008FB20018000310803C030800246355ACE6 -:100F5000004310218C420000004000080000000007 -:100F60003C028000345101400E0003328E24000008 -:100F70008F92FF948E2200048E50000C1602000205 -:100F800024020001AE42000C0E00033D8E2400003E -:100F90008E220004145000068FBF001C8FB2001870 -:100FA0008FB100148FB000100A000F7827BD002009 -:100FB0008E42000C0A000419000000003C0480006E -:100FC0003482014094A300108C4200043063FFFF80 -:100FD0001443001C0000000024020001A4A2001021 -:100FE0008C8202380441000F3C0380003C02003F29 -:100FF0003448F0003C0760003C06FFC08CE22BBC8C -:1010000000461824004810240002130200031D8229 -:10101000106200583C0280008C8202380440FFF7C6 -:101020003C038000346201408C44000034620200C2 -:10103000AC4400003C021000AC6202380A00043BE1 -:101040008FBF001C94A200100A00041900000000C9 -:10105000240200201482000F3C0280003C03800028 -:1010600094A20012346301408C6300043042FFFFFD -:10107000146200050000000024020001A4A2001276 -:101080000A0004028FBF001C94A200120A00041977 -:1010900000000000345101400E0003328E24000095 -:1010A0008F92FF948E230004964200123050FFFF6F -:1010B0001603000224020001A64200120E00033DA6 -:1010C0008E2400008E220004160200068FBF001C32 -:1010D0008FB200188FB100148FB000100A00037C8B -:1010E00027BD0020964200120A00041900000000EB -:1010F0003C03800094A20014346301408C6300041C -:101100003042FFFF14620008240200018FBF001C60 -:101110008FB200188FB100148FB00010A4A2001479 -:101120000A00146327BD002094A20014144000217B -:101130008FBF001C0A000435000000003C03800043 -:1011400094A20016346301408C6300043042FFFF18 -:101150001462000D240200018FBF001C8FB2001822 -:101160008FB100148FB00010A4A200160A000B1457 -:1011700027BD00209442007824420004A4A200105D -:101180000A00043B8FBF001C94A200162403000138 -:101190003042FFFF144300078FBF001C3C020800D1 -:1011A0008C420070244200013C010800AC22007017 -:1011B0008FBF001C8FB200188FB100148FB00010C9 -:1011C00003E0000827BD002027BDFFD8AFB20018FC -:1011D0008F92FF94AFB10014AFBF0020AFB3001CDB -:1011E000AFB000103C028000345101008C5001006F -:1011F0009242000092230009304400FF2402001FA5 -:10120000106200AB28620020104000192402003850 -:101210002862000A1040000D2402000B286200081A -:101220001040002E8F820024046001042862000216 -:101230001440002A8F820024240200061062002637 -:101240008FBF00200A00055F8FB3001C1062006092 -:101250002862000B144000FA8FBF00202402000E09 -:10126000106200788F8200240A00055F8FB3001C93 -:10127000106200D2286200391040000A2402008067 -:1012800024020036106200E528620037104000C3D7 -:1012900024020035106200D98FBF00200A00055FCC -:1012A0008FB3001C1062002D2862008110400006E0 -:1012B000240200C824020039106200C98FBF002038 -:1012C0000A00055F8FB3001C106200A28FBF0020D0 -:1012D0000A00055F8FB3001C8F8200248C42000C33 -:1012E000104000D78FBF00200E000D8400000000CA -:1012F0003C038000346301008C6200008F85002075 -:10130000946700089466000CACA200008C64000492 -:101310008F82002400063400ACA400049448001E10 -:101320008C62001800073C0000E83825ACA20008D9 -:101330008C62001C24040001ACA2000C9062000A24 -:1013400000C23025ACA60010ACA00014ACA0001860 -:10135000ACA7001C0A00051D8FBF00208F8200244F -:101360008C42000C104000B68FBF00200E000D8490 -:10137000000000008F820024962400089625000CAF -:101380009443001E000422029626000E8F82002045 -:10139000000426000083202500052C003C0300806B -:1013A00000A6282500832025AC400000AC400004A6 -:1013B000AC400008AC40000CAC450010AC40001440 -:1013C000AC400018AC44001C0A00051C24040001B9 -:1013D0009622000C14400018000000009242000504 -:1013E0003042001014400014000000000E000332D0 -:1013F0000200202192420005020020213442001008 -:101400000E00033DA242000592420000240300208A -:10141000304200FF10430089020020218FBF0020CE -:101420008FB3001C8FB200188FB100148FB0001062 -:101430000A00107527BD00280000000D0A00055E97 -:101440008FBF00208C42000C1040007D8FBF002019 -:101450000E000D84000000008E2200048F84002006 -:101460009623000CAC8200003C0280089445002CBE -:101470008F82002400031C0030A5FFFF9446001E4D -:101480003C02400E0065182500C23025AC830004E4 -:10149000AC800008AC80000CAC800010AC80001464 -:1014A000AC800018AC86001C0A00051C2404000156 -:1014B0000E000332020020218F93FF9802002021AA -:1014C0000E00033DA660000C020020210E00034226 -:1014D000240500018F8200248C42000C104000582B -:1014E0008FBF00200E000D84000000009622000C2B -:1014F0008F83002000021400AC700000AC62000476 -:10150000AC6000088E4400388F820024AC64000C6C -:101510008E46003C9445001E3C02401FAC66001005 -:1015200000A228258E62000424040001AC6200148D -:10153000AC600018AC65001C8FBF00208FB3001C8E -:101540008FB200188FB100148FB000100A000DB8D0 -:1015500027BD0028240200201082003A8FB3001C0F -:101560000E000F5E00000000104000358FBF00200D -:101570003C0480008C8201F80440FFFE348201C0EC -:1015800024030002AC500000A04300043C02100001 -:10159000AC8201F80A00055E8FBF00200200202106 -:1015A0008FBF00208FB3001C8FB200188FB10014C2 -:1015B0008FB000100A000EA727BD00289625000C4A -:1015C000020020218FBF00208FB3001C8FB20018B3 -:1015D0008FB100148FB000100A000ECC27BD002878 -:1015E000020020218FB3001C8FB200188FB10014AD -:1015F0008FB000100A000EF727BD00289225000DBD -:10160000020020218FB3001C8FB200188FB100148C -:101610008FB000100A000F4827BD002802002021CB -:101620008FBF00208FB3001C8FB200188FB1001441 -:101630008FB000100A000F1F27BD00288FBF0020A9 -:101640008FB3001C8FB200188FB100148FB0001040 -:1016500003E0000827BD00283C0580008CA202782A -:101660000440FFFE34A2024024030002AC44000008 -:10167000A04300043C02100003E00008ACA2027882 -:10168000A380001803E00008A38000193C03800039 -:101690008C6202780440FFFE8F82001CAC62024024 -:1016A00024020002A06202443C02100003E0000891 -:1016B000AC6202783C02600003E000088C425404F3 -:1016C0009083003024020005008040213063003FF9 -:1016D0000000482114620005000050219082004C57 -:1016E0009483004E304900FF306AFFFFAD00000CCC -:1016F000AD000010AD000024950200148D05001C03 -:101700008D0400183042FFFF004910230002110031 -:10171000000237C3004038210086202300A2102B8E -:101720000082202300A72823AD05001CAD0400186B -:10173000A5090014A5090020A50A001603E0000869 -:10174000A50A002203E000080000000027BDFFD822 -:10175000AFB200183C128008AFB40020AFB3001C39 -:10176000AFB10014AFBF0024AFB00010365101007C -:101770003C0260008C4254049222000C3C1408008D -:10178000929400F7304300FF2402000110620032FF -:101790000080982124020002146200353650008037 -:1017A0000E00143D000000009202004C2403FF8054 -:1017B0003C0480003042007F000211C024420240FD -:1017C0000262102100431824AC8300949245000863 -:1017D0009204004C3042007F3C03800614850007D1 -:1017E000004380212402FFFFA22200112402FFFFF8 -:1017F000A62200120A0005D22402FFFF9602002052 -:10180000A222001196020022A62200128E020024BB -:101810003C048008AE2200143485008090A2004C65 -:1018200034830100A06200108CA2003CAC6200185E -:101830008C820068AC6200F48C820064AC6200F0C0 -:101840008C82006CAC6200F824020001A0A2006847 -:101850000A0005EE3C0480080E001456000000004B -:1018600036420080A04000680A0005EE3C04800873 -:10187000A2000068A20000690A0006293C02800854 -:10188000348300808C62003834850100AC62006CC7 -:1018900024020001A062006990A200D59083000894 -:1018A000305100FF3072007F12320019001111C058 -:1018B00024420240026210212403FF8000431824C6 -:1018C0003C048000AC8300943042007F3C038006DF -:1018D000004380218E02000C1040000D02002021E8 -:1018E0000E00057E0000000026220001305100FF9E -:1018F0009203003C023410260002102B0002102339 -:101900003063007F022288240A0005F8A203003C0D -:101910003C088008350401008C8200E03507008017 -:10192000ACE2003C8C8200E0AD02000090E5004C8F -:10193000908600D590E3004C908400D52402FF806F -:1019400000A228243063007F308400FF00A62825F1 -:101950000064182A1060000230A500FF38A500803E -:10196000A0E5004CA10500093C0280089043000E50 -:10197000344400803C058000A043000A8C8300189A -:101980003C027FFF3442FFFF00621824AC83001842 -:101990008CA201F80440FFFE00000000ACB301C0BF -:1019A0008FBF00248FB400208FB3001C8FB20018AB -:1019B0008FB100148FB0001024020002A0A201C455 -:1019C00027BD00283C02100003E00008ACA201F88B -:1019D00090A2000024420001A0A200003C030800E5 -:1019E0008C6300F4304200FF144300020080302179 -:1019F000A0A0000090A200008F84001C000211C073 -:101A00002442024024830040008220212402FF80DF -:101A1000008220243063007F3C02800A006218218B -:101A20003C028000AC44002403E00008ACC300008A -:101A300094820006908300058C85000C8C86001033 -:101A40008C8700188C88001C8C8400203C010800C6 -:101A5000A42256C63C010800A02356C53C0108003C -:101A6000AC2556CC3C010800AC2656D03C01080001 -:101A7000AC2756D83C010800AC2856DC3C010800D5 -:101A8000AC2456E003E00008000000003C0280089F -:101A9000344201008C4400343C038000346504006F -:101AA000AC6400388C420038AF850028AC62003C42 -:101AB0003C020005AC6200300000000000000000A5 -:101AC00003E00008000000003C020006308400FF34 -:101AD000008220253C028000AC4400300000000061 -:101AE00000000000000000003C0380008C62000049 -:101AF000304200101040FFFD3462040003E0000893 -:101B0000AF82002894C200003C080800950800CA73 -:101B100030E7FFFF0080482101021021A4C200002D -:101B200094C200003042FFFF00E2102B544000013D -:101B3000A4C7000094A200003C0308008C6300CC02 -:101B400024420001A4A2000094A200003042FFFF42 -:101B5000144300073C0280080107102BA4A00000DA -:101B60005440000101003821A4C700003C02800855 -:101B7000344601008CC3002894A200003C0480007D -:101B80003042FFFE000210C000621021AC82003C17 -:101B90008C82003C006218231860000400000000E2 -:101BA0008CC200240A0006BA244200018CC2002420 -:101BB000AC8200383C020050344200103C038000EC -:101BC000AC620030000000000000000000000000D7 -:101BD0008C620000304200201040FFFD0000000039 -:101BE00094A200003C04800030420001000210C0BA -:101BF000004410218C430400AD2300008C420404F7 -:101C0000AD2200043C02002003E00008AC8200305A -:101C100027BDFFE0AFB20018AFB10014AFB00010A5 -:101C2000AFBF001C94C2000000C080213C1208001D -:101C3000965200C624420001A6020000960300004E -:101C400094E2000000E03021144300058FB1003021 -:101C50000E00068F024038210A0006F10000000045 -:101C60008C8300048C82000424420040046100073D -:101C7000AC8200048C8200040440000400000000D8 -:101C80008C82000024420001AC8200009602000019 -:101C90003042FFFF50520001A600000096220000D3 -:101CA00024420001A62200003C02800834420100C8 -:101CB000962300009442003C144300048FBF001C94 -:101CC00024020001A62200008FBF001C8FB2001862 -:101CD0008FB100148FB0001003E0000827BD002072 -:101CE00027BDFFE03C028008AFBF0018344201006E -:101CF0008C4800343C03800034690400AC68003830 -:101D00008C42003830E700FFAF890028AC62003C0D -:101D10003C020005AC620030000000000000000042 -:101D200000000000000000000000000000000000B3 -:101D30008C82000C8C82000C97830016AD22000070 -:101D40008C82001000604021AD2200048C820018BB -:101D5000AD2200088C82001CAD22000C8CA2001465 -:101D6000AD2200108C820020AD220014908200056C -:101D7000304200FF00021200AD2200188CA20018B1 -:101D8000AD22001C8CA2000CAD2200208CA2001001 -:101D9000AD2200248CA2001CAD2200288CA20020C1 -:101DA000AD22002C3402FFFFAD260030AD20003400 -:101DB000506200013408FFFFAD28003850E00011E8 -:101DC0003C0280083C048008348401009482005066 -:101DD0003042FFFFAD22003C9483004494850044D0 -:101DE000240200013063FFFF000318C200641821C1 -:101DF0009064006430A5000700A210040A00075C8C -:101E00000044102534420100AD20003C94430044BE -:101E1000944400443063FFFF000318C2006218219D -:101E200030840007906500642402000100821004E1 -:101E30000002102700451024A0620064000000008A -:101E400000000000000000003C0200063442004098 -:101E50003C038000AC620030000000000000000085 -:101E6000000000008C620000304200101040FFFDB6 -:101E70003C06800834C201503463040034C7014A70 -:101E800034C4013434C5014034C60144AFA200104B -:101E90000E0006D2AF8300288FBF001803E00008B1 -:101EA00027BD00208F8300143C0608008CC600E884 -:101EB0008F82001C30633FFF000319800046102111 -:101EC000004310212403FF80004318243C068000B7 -:101ED000ACC300283042007F3C03800C004330211B -:101EE00090C2000D30A500FF0000382134420010E0 -:101EF000A0C2000D8F8900143C028008344201000A -:101F00009443004400091382304800032402000176 -:101F1000A4C3000E1102000B2902000210400005AC -:101F2000240200021100000C240300010A0007A48F -:101F30000000182111020006000000000A0007A49A -:101F4000000018218CC2002C0A0007A424430001C1 -:101F50008CC20014244300018CC200180043102BD3 -:101F60005040000A240700012402002714A20003A5 -:101F70003C0380080A0007B1240700013463010014 -:101F80009462004C24420001A462004C00091382B8 -:101F9000304300032C620002104000090080282119 -:101FA000146000040000000094C200340A0007C15D -:101FB0003046FFFF8CC600380A0007C10080282188 -:101FC000000030213C040800248456C00A000706A3 -:101FD0000000000027BDFF90AFB60068AFB50064F9 -:101FE000AFB40060AFB3005CAFB20058AFB1005403 -:101FF000AFBF006CAFB000508C9000000080B021EB -:102000003C0208008C4200E8960400328F83001CDA -:102010002414FF8030843FFF0062182100042180D7 -:1020200000641821007410243C13800000A090214B -:1020300090A50000AE620028920400323C02800CA1 -:102040003063007F00628821308400C02402004099 -:10205000148200320000A8218E3500388E2200182C -:102060001440000224020001AE2200189202003C3B -:10207000304200201440000E8F83001C000511C068 -:102080002442024000621821306400783C02008043 -:102090000082202500741824AE630800AE64081086 -:1020A0008E2200188E03000800431021AE22001873 -:1020B0008E22002C8E230018244200010062182B6F -:1020C0001060004300000000924200002442000122 -:1020D000A24200003C0308008C6300F4304200FF81 -:1020E00050430001A2400000924200008F84001C77 -:1020F000000211C024420240248300403063007F6C -:10210000008220213C02800A0094202400621821D1 -:10211000AE6400240A0008D2AEC30000920300326D -:102120002402FFC000431024304200FF1440000589 -:1021300024020001AE220018962200340A00084250 -:102140003055FFFF8E22001424420001AE220018F9 -:102150009202003000021600000216030441001C27 -:10216000000000009602003227A400100080282101 -:10217000A7A20016960200320000302124070001B9 -:102180003042FFFFAF8200140E000706AFA0001C14 -:10219000960200328F83001C3C0408008C8400E807 -:1021A00030423FFF000211800064182100621821B4 -:1021B00000741024AE62002C3063007F3C02800E5D -:1021C000006218219062000D3042007FA062000D75 -:1021D0009222000D304200105040007892420000E0 -:1021E0003C028008344401009482004C8EC30000FD -:1021F0003C130800967300C62442FFFFA482004CE3 -:10220000946200329623000E3054FFFF3070FFFFBF -:102210003C0308008C6300D000701807A7A30038A7 -:102220009482003E3063FFFF3042FFFF14620007DC -:10223000000000008C8200303C038000244200300B -:10224000AC62003C0A00086A8C82002C9482004038 -:102250003042FFFF5462000927A400408C820038FE -:102260003C03800024420030AC62003C8C8200348D -:10227000AC6200380A0008793C03800027A50038CA -:1022800027A60048026038210E00068FA7A000484C -:102290008FA300403C02800024630030AC43003830 -:1022A0008FA30044AC43003C3C0380003C0200058B -:1022B000AC6200303C028008344401009482004249 -:1022C000346304003042FFFF0202102B1440000769 -:1022D000AF8300289482004E9483004202021021B2 -:1022E000004310230A00088F3043FFFF9483004E01 -:1022F00094820042026318210050102300621823C8 -:102300003063FFFF3C028008344401009482003CAB -:102310003042FFFF14430003000000000A00089F42 -:10232000240300019482003C3042FFFF0062102B26 -:10233000144000058F8200289482003C0062102324 -:102340003043FFFF8F820028AC550000AC400004F2 -:10235000AC540008AC43000C3C02000634420010B0 -:102360003C038000AC620030000000000000000070 -:10237000000000008C620000304200101040FFFDA1 -:102380003C04800834840100001018C20064182145 -:102390009065006432020007240600010046100424 -:1023A00000451025A0620064948300429622000E2E -:1023B00050430001A386001892420000244200010D -:1023C000A24200003C0308008C6300F4304200FF8E -:1023D00050430001A2400000924200008F84001C84 -:1023E000000211C0244202402483004000822021C8 -:1023F0002402FF80008220243063007F3C02800A98 -:10240000006218213C028000AC440024AEC30000EE -:102410008FBF006C8FB600688FB500648FB400600A -:102420008FB3005C8FB200588FB100548FB0005052 -:1024300003E0000827BD007027BDFFD8AFB3001C24 -:10244000AFB20018AFB10014AFB00010AFBF0020A2 -:102450000080982100E0802130B1FFFF0E000D8444 -:1024600030D200FF0000000000000000000000006B -:102470008F8200208F830024AC510000AC520004F6 -:10248000AC530008AC40000CAC400010AC40001451 -:10249000AC4000189463001E02038025AC50001C61 -:1024A0000000000000000000000000002404000103 -:1024B0008FBF00208FB3001C8FB200188FB10014A3 -:1024C0008FB000100A000DB827BD002830A5FFFF0F -:1024D0000A0008DC30C600FF3C02800834430100DB -:1024E0009462000E3C080800950800C63046FFFFC5 -:1024F00014C000043402FFFF946500EA0A000929B1 -:102500008F84001C10C20027000000009462004E5F -:102510009464003C3045FFFF00A6102300A6182B52 -:102520003087FFFF106000043044FFFF00C5102318 -:1025300000E210233044FFFF0088102B1040000EF3 -:1025400000E810233C028008344401002403000109 -:1025500034420080A44300162402FFFFA482000E30 -:10256000948500EA8F84001C0000302130A5FFFF15 -:102570000A0009013C0760200044102A10400009AD -:102580003C0280083443008094620016304200010F -:10259000104000043C0280009442007E244200145B -:1025A000A462001603E000080000000027BDFFE061 -:1025B0003C028008AFBF001CAFB0001834420100DD -:1025C000944300429442004C104000193068FFFFD1 -:1025D0009383001824020001146200298FBF001C9D -:1025E0003C06800834D00100000810C200501021C1 -:1025F000904200643103000734C70148304200FFB5 -:10260000006210073042000134C9014E34C4012C6D -:1026100034C5013E1040001634C601420E0006D2F9 -:10262000AFA90010960200420A0009463048FFFF99 -:102630003C028008344401009483004494820042A8 -:102640001043000F8FBF001C94820044A4820042FC -:1026500094820050A482004E8C820038AC820030FC -:1026600094820040A482003E9482004AA4820048E2 -:102670008FBF001C8FB000180A00090427BD00207E -:102680008FB0001803E0000827BD002027BDFFA081 -:10269000AFB1004C3C118000AFBF0058AFB3005445 -:1026A000AFB20050AFB000483626018890C2000398 -:1026B0003044007FA3A400108E32018090C200003D -:1026C0003043007F240200031062003BAF92001CE5 -:1026D00028620004104000062402000424020002C4 -:1026E000106200098FBF00580A000B0F8FB300540F -:1026F0001062004D240200051062014E8FBF005889 -:102700000A000B0F8FB30054000411C002421021C5 -:102710002404FF8024420240004410242643004049 -:10272000AE2200243063007F3C02800A0062182140 -:102730009062003CAFA3003C00441025A062003C26 -:102740008FA3003C9062003C304200401040016C7E -:102750008FBF00583C108008A3800018361001007D -:102760008E0200E08C63003427A4003C27A50010F3 -:10277000004310210E0007C3AE0200E093A2001038 -:102780003C038000A20200D58C6202780440FFFE68 -:102790008F82001CAC62024024020002A06202444C -:1027A0003C021000AC6202780E0009390000000003 -:1027B0000A000B0E8FBF00583C05800890C3000133 -:1027C00090A2000B1443014E8FBF005834A4008028 -:1027D0008C8200189082004C90A200083C0260009D -:1027E0008C4254048C8300183C027FFF3442FFFF6C -:1027F000006218243C0208008C4200B4AC8300182C -:102800003C038000244200013C010800AC2200B4DB -:102810008C6201F80440FFFE8F82001CAC6201C094 -:102820000A000AD6240200023C10800890C300016E -:102830009202000B144301328FBF005827A40018E6 -:1028400036050110240600033C0260008C4254044B -:102850000E000E470000000027A40028360501F0F6 -:102860000E000E47240600038FA200283603010045 -:10287000AE0200648FA2002CAE0200688FA200306E -:10288000AE02006C93A40018906300D52402FF8070 -:102890000082102400431025304900FF3084007F5F -:1028A0003122007F0082102A544000013929008023 -:1028B000000411C0244202402403FF800242102180 -:1028C00000431024AE220094264200403042007F94 -:1028D0003C038006004340218FA3001C2402FFFF1D -:1028E000AFA800403C130800927300F71062003359 -:1028F00093A2001995030014304400FF3063FFFFDA -:102900000064182B106000100000000095040014F3 -:102910008D07001C8D0600183084FFFF0044202323 -:102920000004210000E438210000102100E4202BE5 -:1029300000C2302100C43021AD07001CAD060018D4 -:102940000A000A2F93A20019950400148D07001C99 -:102950008D0600183084FFFF008220230004210030 -:10296000000010210080182100C2302300E4202B39 -:1029700000C4302300E33823AD07001CAD06001867 -:1029800093A200198FA30040A462001497A2001A1A -:10299000A46200168FA2001CAC6200108FA2001C63 -:1029A000AC62000C93A20019A462002097A2001A46 -:1029B000A46200228FA2001CAC6200243C048008A8 -:1029C000348300808C6200388FA20020012088218F -:1029D000AC62003C8FA20020AC82000093A20018E1 -:1029E000A062004C93A20018A0820009A0600068B9 -:1029F00093A20018105100512407FF803229007F54 -:102A0000000911C024420240024210213046007FDA -:102A10003C03800000471024AC6200943C02800616 -:102A200000C2302190C2003CAFA60040000020212F -:102A300000471025A0C2003C8FA80040950200026C -:102A4000950300148D07001C3042FFFF3063FFFF29 -:102A50008D060018004310230002110000E2382107 -:102A600000E2102B00C4302100C23021AD07001C51 -:102A7000AD06001895020002A5020014A50000167C -:102A80008D020008AD0200108D020008AD02000C9E -:102A900095020002A5020020A50000228D02000878 -:102AA000AD0200249102003C304200401040001A68 -:102AB000262200013C108008A3A90038A38000183A -:102AC000361001008E0200E08D03003427A4004080 -:102AD00027A50038004310210E0007C3AE0200E016 -:102AE00093A200383C038000A20200D58C620278D9 -:102AF0000440FFFE8F82001CAC62024024020002F0 -:102B0000A06202443C021000AC6202780E00093957 -:102B100000000000262200013043007F14730004EF -:102B2000004020212403FF8002231024004320269C -:102B300093A200180A000A4B309100FF93A40018DA -:102B40008FA3001C2402FFFF1062000A308900FFDF -:102B500024820001248300013042007F14530005C9 -:102B6000306900FF2403FF800083102400431026F7 -:102B7000304900FF3C028008904200080120882173 -:102B8000305000FF123000193222007F000211C0C5 -:102B900002421021244202402403FF8000431824F3 -:102BA0003C048000AC8300943042007F3C038006EC -:102BB000004310218C43000C004020211060000BCA -:102BC000AFA200400E00057E000000002623000199 -:102BD0002405FF803062007F145300020225202468 -:102BE000008518260A000AAF307100FF3C048008F7 -:102BF000348400808C8300183C027FFF3442FFFF46 -:102C000000621824AC8300183C0380008C6201F839 -:102C10000440FFFE00000000AC7201C0240200026C -:102C2000A06201C43C021000AC6201F80A000B0E65 -:102C30008FBF00583C04800890C300019082000BB5 -:102C40001443002F8FBF0058349000809202000878 -:102C500030420040104000200000000092020008B6 -:102C60000002160000021603044100050240202164 -:102C70000E000ECC240500930A000B0E8FBF0058E7 -:102C80009202000924030018304200FF1443000D93 -:102C900002402021240500390E000E64000030217E -:102CA0000E0003328F84001C8F82FF9424030012D5 -:102CB000A04300090E00033D8F84001C0A000B0E88 -:102CC0008FBF0058240500360E000E64000030212E -:102CD0000A000B0E8FBF00580E0003320240202165 -:102CE000920200058F84001C344200200E00033D38 -:102CF000A20200050E0010758F84001C8FBF0058C3 -:102D00008FB300548FB200508FB1004C8FB0004889 -:102D100003E0000827BD00603C0280083445010044 -:102D20003C0280008C42014094A3000E0000302140 -:102D300000402021AF82001C3063FFFF3402FFFF00 -:102D4000106200063C0760202402FFFFA4A2000ED0 -:102D500094A500EA0A00090130A5FFFF03E000087E -:102D60000000000027BDFFC83C0280003C06800830 -:102D7000AFB5002CAFB1001CAFBF0030AFB400281E -:102D8000AFB30024AFB20020AFB00018345101003F -:102D900034C501008C4301008E2200148CA400E491 -:102DA0000000A821AF83001C0044102318400052EB -:102DB000A38000188E22001400005021ACA200E471 -:102DC00090C3000890A200D53073007FA3A200102A -:102DD0008CB200E08CB400E4304200FF1053003BA2 -:102DE00093A200108F83001C2407FF80000211C0F3 -:102DF0000062102124420240246300400047102456 -:102E00003063007F3C0980003C08800A006818217C -:102E1000AD2200248C62003427A4001427A50010E2 -:102E2000024280210290102304400028AFA3001426 -:102E30009062003C00E21024304200FF1440001970 -:102E4000020090219062003C34420040A062003CAD -:102E50008F86001C93A3001024C200403042007FE4 -:102E6000004828213C0208008C4200F42463000141 -:102E7000306400FF14820002A3A30010A3A000107E -:102E800093A20010AFA50014000211C0244202401A -:102E900000C2102100471024AD2200240A000B4577 -:102EA00093A200100E0007C3000000003C0280083F -:102EB00034420100AC5000E093A30010240A00014A -:102EC000A04300D50A000B4593A200102402000184 -:102ED000154200093C0380008C6202780440FFFE2A -:102EE0008F82001CAC62024024020002A0620244F5 -:102EF0003C021000AC6202789222000B2403000214 -:102F0000304200FF144300720000000096220008C7 -:102F1000304300FF24020082146200402402008437 -:102F20003C028000344901008D22000C95230006EC -:102F3000000216023063FFFF3045003F24020027E5 -:102F400010A2000FAF83001428A200281040000830 -:102F5000240200312402002110A2000924020025CD -:102F600010A20007938200190A000BBD00000000A8 -:102F700010A20007938200190A000BBD0000000098 -:102F80000E000777012020210A000C3D0000000000 -:102F90003C0380008C6202780440FFFE8F82001C9C -:102FA000AC62024024020002A06202443C02100013 -:102FB000AC6202780A000C3D000000009523000678 -:102FC000912400058D25000C8D2600108D270018FA -:102FD0008D28001C8D290020244200013C0108009E -:102FE000A42356C63C010800A02456C53C01080095 -:102FF000AC2556CC3C010800AC2656D03C0108005C -:10300000AC2756D83C010800AC2856DC3C0108002F -:10301000AC2956E00A000C3DA38200191462000A94 -:10302000240200813C02800834420100944500EAF9 -:10303000922600058F84001C30A5FFFF30C600FFDC -:103040000A000BFE3C0760211462005C00000000D7 -:103050009222000A304300FF306200201040000737 -:10306000306200403C02800834420100944500EA8E -:103070008F84001C0A000BFC24060040104000074F -:10308000000316003C02800834420100944500EA27 -:103090008F84001C0A000BFC24060041000216036A -:1030A000044100463C02800834420100944500EA95 -:1030B0008F84001C2406004230A5FFFF3C076019E6 -:1030C0000E000901000000000A000C3D0000000095 -:1030D0009222000B24040016304200FF1044000628 -:1030E0003C0680009222000B24030017304200FFB0 -:1030F000144300320000000034C5010090A2000B10 -:10310000304200FF1444000B000080218CA20020FC -:103110008CA400202403FF800043102400021140EF -:103120003084007F004410253C032000004310251C -:10313000ACC2083094A2000800021400000214037C -:10314000044200012410000194A2000830420080D3 -:103150005040001A0200A82194A20008304220002A -:10316000504000160200A8218CA300183C021C2D20 -:10317000344219ED106200110200A8213C0208003F -:103180008C4200D4104000053C0280082403000457 -:1031900034420100A04300FC3C028008344201009C -:1031A000944500EA8F84001C2406000630A5FFFF2A -:1031B0000E0009013C0760210200A8210E00093918 -:1031C000000000009222000A304200081040000473 -:1031D00002A010210E0013790000000002A01021AF -:1031E0008FBF00308FB5002C8FB400288FB3002420 -:1031F0008FB200208FB1001C8FB0001803E00008D0 -:1032000027BD00382402FF80008220243C02900069 -:1032100034420007008220253C028000AC4400209C -:103220003C0380008C6200200440FFFE0000000090 -:1032300003E00008000000003C0380002402FF803F -:10324000008220243462000700822025AC64002024 -:103250008C6200200440FFFE0000000003E0000834 -:103260000000000027BDFFD8AFB3001CAFB10014B1 -:10327000AFB00010AFBF0020AFB200183C1180000B -:103280003C0280088E32002034530100AE2400201E -:10329000966300EA000514003C074000004738250B -:1032A00000A08021000030210E0009013065FFFFE1 -:1032B000240200A1160200022402FFFFA2620009FC -:1032C000AE3200208FBF00208FB3001C8FB20018D9 -:1032D0008FB100148FB0001003E0000827BD002854 -:1032E0003C0280082403000527BDFFE834420100AA -:1032F000A04300FCAFBF00103C0280008C420100E4 -:10330000240500A1004020210E000C67AF82001CA4 -:103310003C0380008C6202780440FFFE8F82001C18 -:103320008FBF001027BD0018AC62024024020002CB -:10333000A06202443C021000AC62027803E0000884 -:103340000000000027BDFFE83C068000AFBF001072 -:1033500034C7010094E20008304400FF3883008243 -:10336000388200842C6300012C4200010062182581 -:103370001060002D24020083938200195040003B0E -:103380008FBF00103C020800904256CC8CC4010054 -:103390003C06080094C656C63045003F38A30032AC -:1033A00038A2003F2C6300012C4200010062182566 -:1033B000AF84001CAF860014A380001914600007BE -:1033C00000E020212402002014A2001200000000CE -:1033D0003402FFFF14C2000F00000000240200208E -:1033E00014A2000500E028218CE300142402FFFF52 -:1033F0005062000B8FBF00103C040800248456C0AC -:10340000000030210E000706240700010A000CD638 -:103410008FBF00100E000777000000008FBF001064 -:103420000A00093927BD001814820004240200850F -:103430008CC501040A000CE1000020211482000662 -:103440002482FF808CC50104240440008FBF00103B -:103450000A00016727BD0018304200FF2C4200021D -:1034600010400004240200228FBF00100A000B2726 -:1034700027BD0018148200048F8200248FBF001023 -:103480000A000C8627BD00188C42000C1040001E5C -:1034900000E0282190E300092402001814620003D0 -:1034A000240200160A000CFC240300081462000722 -:1034B00024020017240300123C02800834420080DA -:1034C000A04300090A000D0994A7000854620007F0 -:1034D00094A700088F82FF942404FFFE9043000508 -:1034E00000641824A043000594A7000890A6001BC0 -:1034F0008CA4000094A500068FBF001000073C00BC -:103500000A0008DC27BD00188FBF001003E0000888 -:1035100027BD00188F8500243C04800094A2002A57 -:103520008CA30034000230C02402FFF000C210243B -:1035300000621821AC83003C8CA200303C03800068 -:10354000AC8200383C02005034420010AC620030C3 -:103550000000000000000000000000008C6200007D -:10356000304200201040FFFD30C20008104000062D -:103570003C0280008C620408ACA200208C62040C27 -:103580000A000D34ACA200248C430400ACA300203C -:103590008C420404ACA200243C0300203C028000C6 -:1035A000AC4300303C0480008C8200300043102487 -:1035B0001440FFFD8F8600243C020040AC820030A6 -:1035C00094C3002A94C2002894C4002C94C5002EF1 -:1035D00024630001004410213064FFFFA4C20028CE -:1035E00014850002A4C3002AA4C0002A03E0000836 -:1035F000000000008F84002427BDFFE83C05800404 -:1036000024840010AFBF00100E000E472406000AED -:103610008F840024948200129483002E3042000F85 -:10362000244200030043180424027FFF0043102BB0 -:1036300010400002AC8300000000000D0E000D13CE -:10364000000000008F8300248FBF001027BD0018EA -:10365000946200149463001A3042000F00021500B7 -:10366000006218253C02800003E00008AC4300A083 -:103670008F8300243C028004944400069462001A64 -:103680008C650000A4640016004410233042FFFF44 -:103690000045102B03E00008384200018F8400240D -:1036A0003C0780049486001A8C85000094E2000692 -:1036B000A482001694E3000600C310233042FFFFEB -:1036C0000045102B384200011440FFF8A483001677 -:1036D00003E00008000000008F8400243C02800406 -:1036E000944200069483001A8C850000A482001680 -:1036F000006210233042FFFF0045102B38420001CA -:103700005040000D8F850024006030213C0780046C -:1037100094E20006A482001694E3000600C310237E -:103720003042FFFF0045102B384200011440FFF8E3 -:10373000A48300168F8500243C03800034620400BB -:103740008CA40020AF820020AC6400388CA200243E -:10375000AC62003C3C020005AC62003003E00008B3 -:10376000ACA000048F8400243C0300068C8200047B -:1037700000021140004310253C038000AC62003081 -:103780000000000000000000000000008C6200004B -:10379000304200101040FFFD34620400AC80000491 -:1037A00003E00008AF8200208F86002427BDFFE0E1 -:1037B000AFB10014AFB00010AFBF00188CC300044D -:1037C0008CC500248F820020309000FF94C4001A22 -:1037D00024630001244200202484000124A7002047 -:1037E000ACC30004AF820020A4C4001AACC70024FC -:1037F00004A100060000882104E2000594C2001A1A -:103800008CC2002024420001ACC2002094C2001AE5 -:1038100094C300282E040001004310262C4200010E -:10382000004410245040000594C2001A24020001F4 -:10383000ACC2000894C2001A94C300280010202BC8 -:10384000004310262C4200010044102514400007BC -:10385000000000008CC20008144000042402001084 -:103860008CC300041462000F8F8500240E000DA786 -:10387000241100018F820024944300289442001AEE -:1038800014430003000000000E000D1300000000B0 -:10389000160000048F8500240E000D840000000037 -:1038A0008F85002494A2001E94A4001C24420001D1 -:1038B0003043FFFF14640002A4A2001EA4A0001E57 -:1038C0001200000A3C02800494A2001494A3001A7F -:1038D0003042000F00021500006218253C028000F3 -:1038E000AC4300A00A000E1EACA0000894420006E3 -:1038F00094A3001A8CA40000A4A200160062102356 -:103900003042FFFF0044102B384200011040000DF0 -:1039100002201021006030213C07800494E2000660 -:10392000A4A2001694E3000600C310233042FFFF58 -:103930000044102B384200011440FFF8A4A30016E5 -:10394000022010218FBF00188FB100148FB000101B -:1039500003E0000827BD002003E00008000000008D -:103960008F82002C3C03000600021140004310250A -:103970003C038000AC62003000000000000000004A -:10398000000000008C620000304200101040FFFD7B -:1039900034620400AF82002803E00008AF80002CEE -:1039A00003E000080000102103E000080000000010 -:1039B0003084FFFF30A5FFFF0000182110800007B2 -:1039C000000000003082000110400002000420428C -:1039D000006518210A000E3D0005284003E000089C -:1039E0000060102110C0000624C6FFFF8CA200005A -:1039F00024A50004AC8200000A000E4724840004C1 -:103A000003E000080000000010A0000824A3FFFF4E -:103A1000AC86000000000000000000002402FFFF50 -:103A20002463FFFF1462FFFA2484000403E000080B -:103A3000000000003C0280083442008024030001A2 -:103A4000AC43000CA4430010A4430012A443001490 -:103A500003E00008A44300168F82002427BDFFD88E -:103A6000AFB3001CAFB20018AFB10014AFB000107C -:103A7000AFBF00208C47000C248200802409FF8007 -:103A80003C08800E3043007F008080213C0A80008B -:103A9000004920240068182130B100FF30D200FF17 -:103AA00010E000290000982126020100AD44002CFE -:103AB000004928243042007F004820219062000005 -:103AC00024030050304200FF1443000400000000B3 -:103AD000AD45002C948200EA3053FFFF0E000D84A8 -:103AE000000000008F8200248F83002000112C0032 -:103AF0009442001E001224003484000100A22825F4 -:103B00003C02400000A22825AC7000008FBF0020BE -:103B1000AC6000048FB20018AC7300088FB10014C1 -:103B2000AC60000C8FB3001CAC6400108FB00010B0 -:103B3000AC60001424040001AC60001827BD00280C -:103B40000A000DB8AC65001C8FBF00208FB3001CAD -:103B50008FB200188FB100148FB0001003E000087E -:103B600027BD00283C06800034C201009043000FAE -:103B7000240200101062000E2865001110A000073A -:103B800024020012240200082405003A10620006F4 -:103B90000000302103E0000800000000240500358B -:103BA0001462FFFC000030210A000E6400000000D7 -:103BB0008CC200748F83FF9424420FA003E000089E -:103BC000AC62000C27BDFFE8AFBF00100E0003423F -:103BD000240500013C0480088FBF0010240200016E -:103BE00034830080A462001227BD00182402000163 -:103BF00003E00008A080001A27BDFFE0AFB2001864 -:103C0000AFB10014AFB00010AFBF001C30B2FFFF67 -:103C10000E000332008088213C028008345000806E -:103C20009202000924030004304200FF1443000CF8 -:103C30003C028008124000082402000A0E000E5BBD -:103C400000000000920200052403FFFE0043102440 -:103C5000A202000524020012A20200093C02800810 -:103C600034420080022020210E00033DA0400027A6 -:103C700016400003022020210E000EBF00000000AD -:103C800002202021324600FF8FBF001C8FB2001897 -:103C90008FB100148FB00010240500380A000E64A4 -:103CA00027BD002027BDFFE0AFBF001CAFB200184A -:103CB000AFB10014AFB000100E00033200808021BD -:103CC0000E000E5B000000003C02800834450080BE -:103CD00090A2000924120018305100FF1232000394 -:103CE0000200202124020012A0A2000990A20005D7 -:103CF0002403FFFE004310240E00033DA0A2000594 -:103D00000200202124050020163200070000302187 -:103D10008FBF001C8FB200188FB100148FB000103D -:103D20000A00034227BD00208FBF001C8FB200187D -:103D30008FB100148FB00010240500390A000E6402 -:103D400027BD002027BDFFE83C028000AFB0001077 -:103D5000AFBF0014344201009442000C2405003629 -:103D60000080802114400012304600FF0E00033214 -:103D7000000000003C02800834420080240300124E -:103D8000A043000990430005346300100E000E5B51 -:103D9000A04300050E00033D020020210200202167 -:103DA0000E000342240500200A000F3C0000000022 -:103DB0000E000E64000000000E00033202002021FD -:103DC0003C0280089043001B2405FF9F0200202135 -:103DD000006518248FBF00148FB00010A043001B93 -:103DE0000A00033D27BD001827BDFFE0AFBF001844 -:103DF000AFB10014AFB0001030B100FF0E000332BD -:103E0000008080213C02800824030012344200809C -:103E10000E000E5BA04300090E00033D02002021AE -:103E200002002021022030218FBF00188FB1001422 -:103E30008FB00010240500350A000E6427BD002055 -:103E40003C0480089083000E9082000A1443000B0B -:103E5000000028218F82FF942403005024050001D4 -:103E600090420000304200FF1443000400000000B4 -:103E70009082000E24420001A082000E03E00008A0 -:103E800000A010213C0380008C6201F80440FFFE7A -:103E900024020002AC6401C0A06201C43C02100014 -:103EA00003E00008AC6201F827BDFFE0AFB20018E4 -:103EB0003C128008AFB10014AFBF001CAFB00010BF -:103EC00036510080922200092403000A304200FF8C -:103ED0001443003E000000008E4300048E22003890 -:103EE000506200808FBF001C92220000240300500B -:103EF000304200FF144300253C0280008C42014008 -:103F00008E4300043642010002202821AC43001CED -:103F10009622005C8E2300383042FFFF00021040E2 -:103F200000621821AE23001C8E4300048E2400384A -:103F30009622005C006418233042FFFF0003184300 -:103F4000000210400043102A10400006000000004C -:103F50008E4200048E230038004310230A000FAA6B -:103F6000000220439622005C3042FFFF0002204006 -:103F70003C0280083443010034420080ACA4002C91 -:103F8000A040002424020001A062000C0E000F5E7D -:103F900000000000104000538FBF001C3C02800056 -:103FA0008C4401403C0380008C6201F80440FFFE19 -:103FB00024020002AC6401C0A06201C43C021000F3 -:103FC000AC6201F80A0010078FBF001C92220009A2 -:103FD00024030010304200FF144300043C02800020 -:103FE0008C4401400A000FEE0000282192220009B3 -:103FF00024030016304200FF14430006240200147C -:10400000A22200093C0280008C4401400A001001F9 -:104010008FBF001C8E2200388E23003C00431023EB -:10402000044100308FBF001C92220027244200016F -:10403000A2220027922200272C42000414400016DE -:104040003C1080009222000924030004304200FF4B -:10405000144300093C0280008C4401408FBF001CC7 -:104060008FB200188FB100148FB000102405009398 -:104070000A000ECC27BD00208C440140240500938B -:104080008FBF001C8FB200188FB100148FB00010CA -:104090000A000F4827BD00208E0401400E000332A5 -:1040A000000000008E4200042442FFFFAE420004E4 -:1040B0008E22003C2442FFFFAE22003C0E00033D56 -:1040C0008E0401408E0401408FBF001C8FB2001887 -:1040D0008FB100148FB00010240500040A000342C1 -:1040E00027BD00208FB200188FB100148FB00010D0 -:1040F00003E0000827BD00203C0680008CC2018838 -:104100003C038008346500809063000E00021402B6 -:10411000304400FF306300FF1464000E3C0280084E -:1041200090A20026304200FF104400098F82FF94C5 -:10413000A0A400262403005090420000304200FF5B -:1041400014430006000000000A0005A18CC4018091 -:104150003C02800834420080A044002603E00008AE -:104160000000000027BDFFE030E700FFAFB20018FD -:10417000AFBF001CAFB10014AFB0001000809021A1 -:1041800014E0000630C600FF000000000000000D33 -:10419000000000000A001060240001163C038008A3 -:1041A0009062000E304200FF14460023346200800B -:1041B00090420026304200FF1446001F000000001D -:1041C0009062000F304200FF1446001B0000000008 -:1041D0009062000A304200FF144600038F90FF9463 -:1041E0000000000D8F90FF948F82FF983C1180009B -:1041F000AE05003CAC450000A066000A0E0003328C -:104200008E240100A20000240E00033D8E24010034 -:104210003C0380008C6201F80440FFFE240200028F -:10422000AC7201C0A06201C43C021000AC6201F893 -:104230000A0010618FBF001C000000000000000D8C -:10424000000000002400013F8FBF001C8FB2001847 -:104250008FB100148FB0001003E0000827BD0020CC -:104260008F83FF943C0280008C44010034420100A3 -:104270008C65003C9046001B0A00102724070001B3 -:104280003C0280089043000E9042000A0043102632 -:10429000304200FF03E000080002102B27BDFFE0C2 -:1042A0003C028008AFB10014AFB00010AFBF0018DF -:1042B0003450008092020005240300303042003068 -:1042C00014430085008088218F8200248C42000CDA -:1042D000104000828FBF00180E000D840000000007 -:1042E0008F860020ACD100009202000892030009E2 -:1042F000304200FF00021200306300FF004310252F -:10430000ACC200049202004D000216000002160327 -:1043100004410005000000003C0308008C630048D5 -:104320000A00109F3C1080089202000830420040B2 -:10433000144000030000182192020027304300FFC0 -:104340003C108008361100809222004D00031E00B0 -:10435000304200FF0002140000621825ACC30008C0 -:104360008E2400308F820024ACC4000C8E250034D3 -:104370009443001E3C02C00BACC50010006218251F -:104380008E22003800002021ACC200148E22003C96 -:10439000ACC200180E000DB8ACC3001C8E020004A5 -:1043A0008F8400203C058000AC8200008E2200201B -:1043B000AC8200048E22001CAC8200088E220058C1 -:1043C0008CA3007400431021AC82000C8E22002CC0 -:1043D000AC8200108E2200408E23004400021400A4 -:1043E00000431025AC8200149222004D240300806B -:1043F000304200FF1443000400000000AC800018AD -:104400000A0010E38F8200248E23000C2402000196 -:104410001062000E2402FFFF92220008304200408A -:104420001440000A2402FFFF8E23000C8CA20074AB -:10443000006218233C0208000062102414400002AD -:10444000000028210060282100051043AC820018DC -:104450008F820024000020219443001E3C02C00CE7 -:10446000006218258F8200200E000DB8AC43001C9E -:104470003C038008346201008C4200008F850020DC -:10448000346300808FBF0018ACA20000ACA0000411 -:104490008C6400488F8200248FB10014ACA4000803 -:1044A000ACA0000CACA00010906300059446001E68 -:1044B0003C02400D00031E0000C23025ACA30014D6 -:1044C0008FB00010ACA0001824040001ACA6001CA2 -:1044D0000A000DB827BD00208FBF00188FB100144F -:1044E0008FB0001003E0000827BD00203C028000D0 -:1044F0009443007C3C02800834460100308400FF75 -:104500003065FFFF2402000524A34650A0C4000C20 -:104510005482000C3065FFFF90C2000D2C42000752 -:104520001040000724A30A0090C3000D24020014C9 -:104530000062100400A210210A00111F3045FFFF85 -:104540003065FFFF3C0280083442008003E0000831 -:10455000A44500143C03800834680080AD05003891 -:10456000346701008CE2001C308400FF00A210239D -:104570001840000330C600FF24A2FFFCACE2001C80 -:1045800030820001504000083C0380088D02003C4E -:1045900000A2102304410012240400058C620004D0 -:1045A00010A2000F3C0380088C62000414A2001EBD -:1045B000000000003C0208008C4200D8304200207D -:1045C000104000093C0280083462008090630008BB -:1045D0009042004C144300043C0280082404000470 -:1045E0000A00110900000000344300803442010039 -:1045F000A040000C24020001A462001410C0000AB4 -:104600003C0280008C4401003C0380008C6201F875 -:104610000440FFFE24020002AC6401C0A06201C499 -:104620003C021000AC6201F803E00008000000004A -:1046300027BDFFE800A61823AFBF00101860008058 -:10464000308800FF3C02800834470080A0E000244E -:1046500034440100A0E000278C82001C00A210233B -:1046600004400056000000008CE2003C94E3005C33 -:104670008CE4002C004530233063FFFF00C3182179 -:104680000083202B1080000400E018218CE2002C15 -:104690000A00117800A2102194E2005C3042FFFF72 -:1046A00000C2102100A21021AC62001C3C02800854 -:1046B000344400809482005C8C83001C3042FFFFF5 -:1046C0000002104000A210210043102B10400004F3 -:1046D000000000008C82001C0A00118B3C06800840 -:1046E0009482005C3042FFFF0002104000A21021C3 -:1046F0003C06800834C3010034C70080AC82001C33 -:10470000A060000CACE500388C62001C00A21023F5 -:104710001840000224A2FFFCAC62001C3102000120 -:10472000104000083C0380088CE2003C00A21023EB -:1047300004410012240400058CC2000410A20010E1 -:104740008FBF00108C62000414A2004F8FBF0010B6 -:104750003C0208008C4200D8304200201040000A81 -:104760003C02800834620080906300089042004C54 -:10477000144300053C028008240400048FBF00108D -:104780000A00110927BD001834430080344201009B -:10479000A040000C24020001A46200143C0280002E -:1047A0008C4401003C0380008C6201F80440FFFE51 -:1047B000240200020A0011D8000000008CE2001C54 -:1047C000004610230043102B54400001ACE5001CB0 -:1047D00094E2005C3042FFFF0062102B144000079F -:1047E0002402000294E2005C8CE3001C3042FFFFD4 -:1047F00000621821ACE3001C24020002ACE5003882 -:104800000E000F5EA082000C1040001F8FBF001032 -:104810003C0280008C4401003C0380008C6201F863 -:104820000440FFFE24020002AC6401C0A06201C487 -:104830003C021000AC6201F80A0011F08FBF0010BA -:1048400031020010104000108FBF00103C028008A1 -:10485000344500808CA3001C94A2005C00661823E1 -:104860003042FFFF006218213C023FFF3444FFFF4B -:104870000083102B544000010080182100C3102138 -:10488000ACA2001C8FBF001003E0000827BD001879 -:1048900027BDFFE800C0402100A63023AFBF0010B5 -:1048A00018C00026308A00FF3C028008344900808E -:1048B0008D24001C8D23002C008820230064182BDD -:1048C0001060000F344701008CE2002000461021E8 -:1048D000ACE200208CE200200044102B1440000BBE -:1048E0003C023FFF8CE2002000441023ACE2002099 -:1048F0009522005C3042FFFF0A0012100082202146 -:10490000ACE00020008620213C023FFF3443FFFF43 -:104910000064102B54400001006020213C028008FC -:104920003442008000851821AC43001CA0400024C4 -:10493000A04000270A0012623C03800831420010A8 -:10494000104000433C0380083C06800834C40080CB -:104950008C82003C004810235840003E34660080A2 -:104960009082002424420001A0820024908200242E -:104970003C0308008C630024304200FF0043102BEE -:10498000144000688FBF001034C201008C42001C2C -:1049900000A2102318400063000000008CC3000434 -:1049A0009482005C006818233042FFFF0003184324 -:1049B000000210400043102A1040000500000000D3 -:1049C0008CC20004004810230A0012450002104364 -:1049D0009482005C3042FFFF000210403C068008D9 -:1049E000AC82002C34C5008094A2005C8CA4002C06 -:1049F00094A3005C3042FFFF00021040008220219F -:104A00003063FFFF0083202101041021ACA2001CB1 -:104A10008CC2000434C60100ACC2001C2402000297 -:104A20000E000F5EA0C2000C1040003E8FBF0010B1 -:104A30003C0280008C4401003C0380008C6201F841 -:104A40000440FFFE240200020A001292000000004F -:104A500034660080ACC50038346401008C82001CD0 -:104A600000A210231840000224A2FFFCAC82001C0C -:104A7000314200015040000A3C0380088CC2003CD7 -:104A800000A2102304430014240400058C620004D7 -:104A900014A200033C0380080A00128424040005C9 -:104AA0008C62000414A2001F8FBF00103C0208009B -:104AB0008C4200D8304200201040000A3C0280089E -:104AC00034620080906300089042004C144300055B -:104AD0003C028008240400048FBF00100A00110962 -:104AE00027BD00183443008034420100A040000C70 -:104AF00024020001A46200143C0280008C440100E6 -:104B00003C0380008C6201F80440FFFE2402000296 -:104B1000AC6401C0A06201C43C021000AC6201F8A8 -:104B20008FBF001003E0000827BD001827BDFFE875 -:104B30003C0A8008AFBF0010354900808D22003C40 -:104B400000C04021308400FF004610231840009D23 -:104B500030E700FF354701002402000100A63023A2 -:104B6000A0E0000CA0E0000DA522001418C0002455 -:104B7000308200108D23001C8D22002C0068182329 -:104B80000043102B1040000F000000008CE20020BA -:104B900000461021ACE200208CE200200043102BE4 -:104BA0001440000B3C023FFF8CE200200043102326 -:104BB000ACE200209522005C3042FFFF0A0012C1E7 -:104BC00000621821ACE00020006618213C023FFF83 -:104BD0003446FFFF00C3102B5440000100C01821D1 -:104BE0003C0280083442008000651821AC43001C60 -:104BF000A0400024A04000270A00130F3C038008B7 -:104C0000104000403C0380088D22003C00481023E7 -:104C10005840003D34670080912200242442000166 -:104C2000A1220024912200243C0308008C6300246C -:104C3000304200FF0043102B1440009A8FBF001039 -:104C40008CE2001C00A21023184000960000000017 -:104C50008D4300049522005C006818233042FFFF5A -:104C600000031843000210400043102A10400005C2 -:104C7000012020218D420004004810230A0012F276 -:104C8000000210439522005C3042FFFF00021040FA -:104C90003C068008AC82002C34C5008094A2005CE5 -:104CA0008CA4002C94A3005C3042FFFF0002104053 -:104CB000008220213063FFFF0083182101031021AF -:104CC000ACA2001C8CC2000434C60100ACC2001CA3 -:104CD000240200020E000F5EA0C2000C1040007102 -:104CE0008FBF00103C0280008C4401003C03800018 -:104CF0008C6201F80440FFFE240200020A0013390E -:104D00000000000034670080ACE500383466010024 -:104D10008CC2001C00A210231840000224A2FFFC39 -:104D2000ACC2001C30820001504000083C038008E7 -:104D30008CE2003C00A2102304430051240400052F -:104D40008C62000410A2003E3C0380088C620004C8 -:104D500054A200548FBF00103C0208008C4200D8BF -:104D600030420020104000063C028008346200807F -:104D7000906300089042004C104300403C028008C1 -:104D80003443008034420100A040000C24020001A2 -:104D9000A46200143C0280008C4401003C038000AB -:104DA0008C6201F80440FFFE24020002AC6401C0E2 -:104DB000A06201C43C021000AC6201F80A00137743 -:104DC0008FBF001024020005A120002714E2000A72 -:104DD0003C038008354301009062000D2C42000620 -:104DE000504000053C0380089062000D2442000101 -:104DF000A062000D3C03800834670080ACE50038F9 -:104E0000346601008CC2001C00A21023184000026E -:104E100024A2FFFCACC2001C308200015040000AFA -:104E20003C0380088CE2003C00A2102304410014E3 -:104E3000240400058C62000414A200033C038008D3 -:104E40000A00136E240400058C62000414A20015ED -:104E50008FBF00103C0208008C4200D83042002076 -:104E60001040000A3C028008346200809063000811 -:104E70009042004C144300053C02800824040004C6 -:104E80008FBF00100A00110927BD001834430080AD -:104E900034420100A040000C24020001A46200146E -:104EA0008FBF001003E0000827BD00183C0B8008EE -:104EB00027BDFFE83C028000AFBF00103442010074 -:104EC000356A00809044000A356901008C45001461 -:104ED0008D4800389123000C308400FF0105102319 -:104EE0001C4000B3306700FF2CE20006504000B1C8 -:104EF0008FBF00102402000100E2300430C2000322 -:104F00005440000800A8302330C2000C144000A117 -:104F100030C20030144000A38FBF00100A00143BC1 -:104F20000000000018C00024308200108D43001CD7 -:104F30008D42002C006818230043102B1040000FF6 -:104F4000000000008D22002000461021AD2200202C -:104F50008D2200200043102B1440000B3C023FFF29 -:104F60008D22002000431023AD2200209542005CDA -:104F70003042FFFF0A0013AF00621821AD2000206D -:104F8000006618213C023FFF3446FFFF00C3102B90 -:104F90005440000100C018213C02800834420080C7 -:104FA00000651821AC43001CA0400024A04000274D -:104FB0000A0013FD3C038008104000403C038008B9 -:104FC0008D42003C004810231840003D34670080AB -:104FD0009142002424420001A14200249142002475 -:104FE0003C0308008C630024304200FF0043102B78 -:104FF000144000708FBF00108D22001C00A21023EF -:105000001840006C000000008D6300049542005CB5 -:10501000006818233042FFFF0003184300021040CD -:105020000043102A10400005014020218D62000439 -:10503000004810230A0013E0000210439542005C70 -:105040003042FFFF000210403C068008AC82002C7A -:1050500034C5008094A2005C8CA4002C94A3005C56 -:105060003042FFFF00021040008220213063FFFF2A -:105070000083182101031021ACA2001C8CC2000483 -:1050800034C60100ACC2001C240200020E000F5EF8 -:10509000A0C2000C104000478FBF00103C028000EF -:1050A0008C4401003C0380008C6201F80440FFFE48 -:1050B000240200020A00142D000000003467008062 -:1050C000ACE50038346601008CC2001C00A210233D -:1050D0001840000224A2FFFCACC2001C3082000178 -:1050E0005040000A3C0380088CE2003C00A21023E0 -:1050F00004430014240400058C62000414A200037D -:105100003C0380080A00141F240400058C6200047C -:1051100014A200288FBF00103C0208008C4200D867 -:10512000304200201040000A3C02800834620080B7 -:10513000906300089042004C144300053C02800834 -:10514000240400048FBF00100A00110927BD0018B5 -:105150003443008034420100A040000C24020001CE -:10516000A46200143C0280008C4401003C038000D7 -:105170008C6201F80440FFFE24020002AC6401C00E -:10518000A06201C43C021000AC6201F80A00143BAA -:105190008FBF00108FBF0010010030210A00115A8C -:1051A00027BD0018010030210A00129927BD001800 -:1051B0008FBF001003E0000827BD00183C038008E3 -:1051C0003464010024020003A082000C8C620004FD -:1051D00003E00008AC82001C3C05800834A300807A -:1051E0009062002734A501002406004324420001F8 -:1051F000A0620027906300273C0208008C42004810 -:10520000306300FF146200043C07602194A500EAAB -:105210000A00090130A5FFFF03E0000800000000BC -:1052200027BDFFE8AFBF00103C0280000E00144411 -:105230008C4401803C02800834430100A060000CD3 -:105240008C4200048FBF001027BD001803E0000847 -:10525000AC62001C27BDFFE03C028008AFBF001815 -:10526000AFB10014AFB000103445008034460100E7 -:105270003C0880008D09014090C3000C8CA4003CC8 -:105280008CA200381482003B306700FF9502007C3E -:1052900090A30027146000093045FFFF2402000599 -:1052A00054E200083C04800890C2000D2442000132 -:1052B000A0C2000D0A00147F3C048008A0C0000DAD -:1052C0003C048008348201009042000C2403000555 -:1052D000304200FF1443000A24A205DC348300801E -:1052E000906200272C4200075040000524A20A00CB -:1052F00090630027240200140062100400A2102111 -:105300003C108008361000803045FFFF012020212E -:105310000E001444A60500149602005C8E030038AB -:105320003C1180003042FFFF000210400062182153 -:10533000AE03001C0E0003328E24014092020025B1 -:1053400034420040A20200250E00033D8E2401409D -:105350008E2401403C0380008C6201F80440FFFE73 -:1053600024020002AC6401C0A06201C43C0210002F -:10537000AC6201F88FBF00188FB100148FB000101D -:1053800003E0000827BD00203C0360103C02080039 -:1053900024420174AC62502C8C6250003C048000AA -:1053A00034420080AC6250003C0208002442547C2D -:1053B0003C010800AC2256003C020800244254384C -:1053C0003C010800AC2256043C020002AC840008F8 -:1053D000AC82000C03E000082402000100A0302190 -:1053E0003C1C0800279C56083C0200023C050400B7 -:1053F00000852826008220260004102B2CA5000101 -:105400002C840001000210803C0308002463560035 -:105410000085202500431821108000030000102182 -:10542000AC6600002402000103E000080000000058 -:105430003C1C0800279C56083C0200023C05040066 -:1054400000852826008220260004102B2CA50001B0 -:105450002C840001000210803C03080024635600E5 -:105460000085202500431821108000050000102130 -:105470003C02080024425438AC62000024020001BF -:1054800003E00008000000003C0200023C030400AE -:1054900000821026008318262C4200012C63000194 -:1054A000004310251040000B000028213C1C080080 -:1054B000279C56083C0380008C62000824050001EC -:1054C00000431025AC6200088C62000C00441025DB -:1054D000AC62000C03E0000800A010213C1C080096 -:1054E000279C56083C0580008CA3000C0004202754 -:1054F000240200010064182403E00008ACA3000C9F -:105500003C020002148200063C0560008CA208D018 -:105510002403FFFE0043102403E00008ACA208D0DF -:105520003C02040014820005000000008CA208D098 -:105530002403FFFD00431024ACA208D003E00008C0 -:10554000000000003C02601A344200108C430080CE -:1055500027BDFFF88C440084AFA3000093A3000094 -:10556000240200041462001AAFA4000493A20001F4 -:105570001040000797A300023062FFFC3C0380004C -:10558000004310218C4200000A001536AFA200042F -:105590003062FFFC3C03800000431021AC4400005B -:1055A000A3A000003C0560008CA208D02403FFFEED -:1055B0003C04601A00431024ACA208D08FA300045E -:1055C0008FA2000034840010AC830084AC82008081 -:1055D00003E0000827BD000827BDFFE8AFBF0010AB -:1055E0003C1C0800279C56083C0280008C43000CA1 -:1055F0008C420004004318243C0200021060001496 -:10560000006228243C0204003C04000210A00005B3 -:10561000006210243C0208008C4256000A00155B10 -:1056200000000000104000073C0404003C02080099 -:105630008C4256040040F809000000000A00156082 -:10564000000000000000000D3C1C0800279C5608CC -:0C5650008FBF001003E0000827BD001809 -:04565C008008024080 -:1056600080080100800800808008000000000C8095 -:105670000000320008000E9808000EF408000F88A1 -:1056800008001028080010748008010080080080BD -:04569000800800008E -:0C5694000A0000280000000000000000D8 -:1056A0000000000D6370362E322E31000000000025 -:1056B00006020104000000000000000000000000DD -:1056C000000000000000000038003C000000000066 -:1056D00000000000000000000000000000000020AA -:1056E00000000000000000000000000000000000BA -:1056F00000000000000000000000000000000000AA -:10570000000000000000000021003800000000013F -:105710000000002B000000000000000400030D400A -:105720000000000000000000000000000000000079 -:105730000000000000000000100000030000000056 -:105740000000000D0000000D3C020800244259AC8E -:105750003C03080024635BF4AC4000000043202BB2 -:105760001480FFFD244200043C1D080037BD9FFC4F -:1057700003A0F0213C100800261000A03C1C0800EB -:10578000279C59AC0E0002F6000000000000000D3E -:1057900027BDFFB4AFA10000AFA20004AFA3000873 -:1057A000AFA4000CAFA50010AFA60014AFA700185F -:1057B000AFA8001CAFA90020AFAA0024AFAB0028FF -:1057C000AFAC002CAFAD0030AFAE0034AFAF00389F -:1057D000AFB8003CAFB90040AFBC0044AFBF004819 -:1057E0000E000820000000008FBF00488FBC00445E -:1057F0008FB900408FB8003C8FAF00388FAE0034B7 -:105800008FAD00308FAC002C8FAB00288FAA002406 -:105810008FA900208FA8001C8FA700188FA6001446 -:105820008FA500108FA4000C8FA300088FA2000486 -:105830008FA1000027BD004C3C1B60188F7A5030B0 -:10584000377B502803400008AF7A000000A01821E1 -:1058500000801021008028213C0460003C0760008B -:105860002406000810600006348420788C42000072 -:10587000ACE220088C63000003E00008ACE3200CDD -:105880000A000F8100000000240300403C02600079 -:1058900003E00008AC4320003C0760008F86000452 -:1058A0008CE520740086102100A2182B14600007DC -:1058B000000028218F8AFDA024050001A1440013C7 -:1058C0008F89000401244021AF88000403E0000810 -:1058D00000A010218F84FDA08F8500049086001306 -:1058E00030C300FF00A31023AF82000403E00008D0 -:1058F000A08000138F84FDA027BDFFE8AFB000108B -:10590000AFBF001490890011908700112402002875 -:10591000312800FF3906002830E300FF2485002CE1 -:105920002CD00001106200162484001C0E00006EB2 -:10593000000000008F8FFDA03C05600024020204DF -:1059400095EE003E95ED003C000E5C0031ACFFFF93 -:10595000016C5025ACAA2010520000012402000462 -:10596000ACA22000000000000000000000000000C9 -:105970008FBF00148FB0001003E0000827BD00188F -:105980000A0000A6000028218F85FDA027BDFFD8B2 -:10599000AFBF0020AFB3001CAFB20018AFB100140E -:1059A000AFB000100080982190A4001124B0001C1A -:1059B00024B1002C308300FF386200280E000090D4 -:1059C0002C5200010E00009800000000020020216F -:1059D0001240000202202821000028210E00006E43 -:1059E000000000008F8DFDA03C0880003C05600099 -:1059F00095AC003E95AB003C02683025000C4C0095 -:105A0000316AFFFF012A3825ACA7201024020202C8 -:105A1000ACA6201452400001240200028FBF0020D7 -:105A20008FB3001C8FB200188FB100148FB000101C -:105A300027BD002803E00008ACA2200027BDFFE03E -:105A4000AFB20018AFB10014AFB00010AFBF001C70 -:105A50003C1160008E2320748F82000430D0FFFF41 -:105A600030F2FFFF1062000C2406008F0E00006E63 -:105A7000000000003C06801F0010440034C5FF00F9 -:105A80000112382524040002AE2720100000302126 -:105A9000AE252014AE2420008FBF001C8FB200184A -:105AA0008FB100148FB0001000C0102103E0000877 -:105AB00027BD002027BDFFE0AFB0001030D0FFFFB2 -:105AC000AFBF0018AFB100140E00006E30F1FFFF41 -:105AD00000102400009180253C036000AC70201071 -:105AE0008FBF00188FB100148FB000102402000483 -:105AF000AC62200027BD002003E000080000102158 -:105B000027BDFFE03C046018AFBF0018AFB1001420 -:105B1000AFB000108C8850002403FF7F34028071E6 -:105B20000103382434E5380C241F00313C1980006F -:105B3000AC8550003C11800AAC8253BCAF3F0008DA -:105B40000E00054CAF9100400E00050A3C116000AC -:105B50000E00007D000000008E3008083C0F570941 -:105B60002418FFF00218602435EEE00035EDF00057 -:105B7000018E5026018D58262D4600012D69000109 -:105B8000AF86004C0E000D09AF8900503C06601630 -:105B90008CC700003C0860148D0500A03C03FFFF8B -:105BA00000E320243C02535300052FC2108200550D -:105BB00034D07C00960201F2A780006C10400003F4 -:105BC000A780007C384B1E1EA78B006C960201F844 -:105BD000104000048F8D0050384C1E1EA78C007C96 -:105BE0008F8D005011A000058F83004C240E0020E3 -:105BF000A78E007CA78E006C8F83004C1060000580 -:105C00009785007C240F0020A78F007CA78F006C55 -:105C10009785007C2CB8008153000001240500808A -:105C20009784006C2C91040152200001240404008C -:105C30001060000B3C0260008FBF00188FB1001491 -:105C40008FB0001027BD0020A784006CA785007CC2 -:105C5000A380007EA780007403E00008A780009264 -:105C60008C4704382419103C30FFFFFF13F9000360 -:105C700030A8FFFF1100004624030050A380007EDF -:105C80009386007E50C00024A785007CA780007CFE -:105C90009798007CA780006CA7800074A780009272 -:105CA0003C010800AC3800800E00078700000000AF -:105CB0003C0F60008DED0808240EFFF03C0B600ED9 -:105CC000260C0388356A00100000482100002821B6 -:105CD00001AE20243C105709AF8C0010AF8A004859 -:105CE000AF89001810900023AF8500148FBF0018F3 -:105CF0008FB100148FB0001027BD002003E0000812 -:105D0000AF80005400055080014648218D260004D4 -:105D10000A00014800D180219798007CA784006C7C -:105D2000A7800074A78000923C010800AC38008076 -:105D30000E000787000000003C0F60008DED080892 -:105D4000240EFFF03C0B600E260C0388356A001011 -:105D5000000048210000282101AE20243C105709F2 -:105D6000AF8C0010AF8A0048AF8900181490FFDF95 -:105D7000AF85001424110001AF9100548FBF0018AB -:105D80008FB100148FB0001003E0000827BD002081 -:105D90000A00017BA383007E3083FFFF8F880040D1 -:105DA0008F87003C000321403C0580003C020050EE -:105DB000008248253C0660003C0A010034AC040027 -:105DC0008CCD08E001AA58241160000500000000F5 -:105DD0008CCF08E024E7000101EA7025ACCE08E092 -:105DE0008D19001001805821ACB900388D180014AD -:105DF000ACB8003CACA9003000000000000000007E -:105E00000000000000000000000000000000000092 -:105E100000000000000000003C0380008C640000D3 -:105E2000308200201040FFFD3C0F60008DED08E047 -:105E30003C0E010001AE18241460FFE100000000D8 -:105E4000AF87003C03E00008AF8B00588F8500400F -:105E5000240BFFF03C06800094A7001A8CA90024B4 -:105E600030ECFFFF000C38C000EB5024012A402129 -:105E7000ACC8003C8CA400248CC3003C00831023DD -:105E800018400033000000008CAD002025A2000166 -:105E90003C0F0050ACC2003835EE00103C068000CC -:105EA000ACCE003000000000000000000000000048 -:105EB00000000000000000000000000000000000E2 -:105EC000000000003C0480008C9900003338002062 -:105ED0001300FFFD30E20008104000173C0980006D -:105EE0008C880408ACA800108C83040CACA30014AC -:105EF0003C1900203C188000AF19003094AE001807 -:105F000094AF001C01CF3021A4A6001894AD001A54 -:105F100025A70001A4A7001A94AB001A94AC001E98 -:105F2000118B00030000000003E0000800000000E7 -:105F300003E00008A4A0001A8D2A0400ACAA0010F7 -:105F40008D240404ACA400140A0002183C1900209B -:105F50008CA200200A0002003C0F00500A0001EE53 -:105F60000000000027BDFFE8AFBF00100E000232A6 -:105F7000000000008F8900408FBF00103C038000AC -:105F8000A520000A9528000A9527000427BD0018BF -:105F90003105FFFF30E6000F0006150000A22025A6 -:105FA00003E00008AC6400803C0508008CA50020DC -:105FB0008F83000C27BDFFE8AFB00010AFBF001407 -:105FC00010A300100000802124040001020430040A -:105FD00000A6202400C3102450440006261000010F -:105FE000001018802787FDA41480000A006718217C -:105FF000261000012E0900025520FFF38F83000CAC -:10600000AF85000C8FBF00148FB0001003E00008B4 -:1060100027BD00188C6800003C058000ACA8002457 -:106020000E000234261000013C0508008CA500205B -:106030000A0002592E0900022405000100851804F7 -:106040003C0408008C84002027BDFFC8AFBF00348B -:1060500000831024AFBE0030AFB7002CAFB60028CD -:10606000AFB50024AFB40020AFB3001CAFB200182E -:10607000AFB1001410400051AFB000108F84004049 -:10608000948700069488000A00E8302330D5FFFF8B -:1060900012A0004B8FBF0034948B0018948C000A20 -:1060A000016C50233142FFFF02A2482B1520000251 -:1060B00002A02021004020212C8F000515E00002C5 -:1060C00000809821241300040E0001C102602021E9 -:1060D0008F87004002609021AF80004494F4000A52 -:1060E000026080211260004E3291FFFF3C1670006A -:1060F0003C1440003C1E20003C1760008F99005863 -:106100008F380000031618241074004F0283F82BF8 -:1061100017E0003600000000107E00478F86004424 -:1061200014C0003A2403000102031023022320219B -:106130003050FFFF1600FFF13091FFFF8F870040C6 -:106140003C1100203C108000AE11003094EB000A9E -:106150003C178000024B5021A4EA000A94E9000A8F -:1061600094E800043123FFFF3106000F00062D00E4 -:106170000065F025AEFE008094F3000A94F6001846 -:1061800012D30036001221408CFF00148CF4001052 -:1061900003E468210000C02101A4782B029870213B -:1061A00001CF6021ACED0014ACEC001002B238233A -:1061B00030F5FFFF16A0FFB88F8400408FBF00347A -:1061C0008FBE00308FB7002C8FB600288FB500240B -:1061D0008FB400208FB3001C8FB200188FB1001451 -:1061E0008FB0001003E0000827BD00381477FFCC03 -:1061F0008F8600440E000EE202002021004018218C -:106200008F86004410C0FFC9020310230270702360 -:106210008F87004001C368210A0002E431B2FFFF0A -:106220008F86004414C0FFC93C1100203C10800040 -:106230000A0002AEAE1100300E00046602002021FA -:106240000A0002DB00401821020020210E0009395B -:10625000022028210A0002DB004018210E0001EE76 -:10626000000000000A0002C702B2382327BDFFC8A1 -:10627000AFB7002CAFB60028AFB50024AFB40020F4 -:10628000AFB3001CAFB20018AFB10014AFB0001034 -:10629000AFBF00300E00011B241300013C047FFF40 -:1062A0003C0380083C0220003C010800AC20007048 -:1062B0003496FFFF34770080345200033C1512C03F -:1062C000241400013C1080002411FF800E000245C0 -:1062D000000000008F8700488F8B00188F89001402 -:1062E0008CEA00EC8CE800E8014B302B01092823F4 -:1062F00000A6102314400006014B18231440000E82 -:106300003C05800002A3602B1180000B0000000000 -:106310003C0560008CEE00EC8CED00E88CA4180CC1 -:10632000AF8E001804800053AF8D00148F8F0010C3 -:10633000ADF400003C0580008CBF00003BF900017B -:10634000333800011700FFE13C0380008C6201003C -:1063500024060C0010460009000000008C680100B3 -:106360002D043080548000103C0480008C690100B2 -:106370002D2331811060000C3C0480008CAA0100A8 -:1063800011460004000020218CA6010024C5FF81D5 -:1063900030A400FF8E0B01000E000269AE0B00243A -:1063A0000A00034F3C0480008C8D01002DAC3300AB -:1063B00011800022000000003C0708008CE70098D4 -:1063C00024EE00013C010800AC2E00983C04800043 -:1063D0008C8201001440000300000000566000148D -:1063E0003C0440008C9F01008C9801000000982123 -:1063F00003F1C82400193940330F007F00EF7025E6 -:1064000001D26825AC8D08308C8C01008C85010090 -:10641000258B0100017130240006514030A3007F1C -:106420000143482501324025AC8808303C04400037 -:10643000AE0401380A00030E000000008C99010030 -:10644000240F0020AC99002092F80000330300FFD5 -:10645000106F000C241F0050547FFFDD3C048000AF -:106460008C8401000E00154E000000000A00034F4E -:106470003C04800000963824ACA7180C0A000327BF -:106480008F8F00108C8501000E0008F72404008017 -:106490000A00034F3C04800000A4102B24030001D9 -:1064A00010400009000030210005284000A4102BF6 -:1064B00004A00003000318405440FFFC00052840DE -:1064C0005060000A0004182B0085382B54E00004AB -:1064D0000003184200C33025008520230003184222 -:1064E0001460FFF9000528420004182B03E000089F -:1064F00000C310213084FFFF30C600FF3C0780003E -:106500008CE201B80440FFFE00064C000124302557 -:106510003C08200000C820253C031000ACE00180AE -:10652000ACE50184ACE4018803E00008ACE301B809 -:106530003C0660008CC5201C2402FFF03083020062 -:10654000308601001060000E00A2282434A500014E -:106550003087300010E0000530830C0034A50004C3 -:106560003C04600003E00008AC85201C1060FFFDC7 -:106570003C04600034A5000803E00008AC85201C42 -:1065800054C0FFF334A500020A0003B03087300086 -:1065900027BDFFE8AFB00010AFBF00143C0760009C -:1065A000240600021080001100A080218F83005873 -:1065B0000E0003A78C6400188F8200580000202171 -:1065C000240600018C45000C0E000398000000001A -:1065D0001600000224020003000010218FBF0014E7 -:1065E0008FB0001003E0000827BD00188CE8201CC5 -:1065F0002409FFF001092824ACE5201C8F870058EE -:106600000A0003CD8CE5000C3C02600E00804021A6 -:1066100034460100240900180000000000000000BA -:10662000000000003C0A00503C0380003547020097 -:10663000AC68003834640400AC65003CAC670030E2 -:106640008C6C0000318B00201160FFFD2407FFFFE0 -:106650002403007F8C8D00002463FFFF248400044A -:10666000ACCD00001467FFFB24C60004000000004E -:10667000000000000000000024A402000085282B78 -:106680003C0300203C0E80002529FFFF010540212E -:10669000ADC300301520FFE00080282103E0000892 -:1066A000000000008F82005827BDFFD8AFB3001C48 -:1066B000AFBF0020AFB20018AFB10014AFB00010F0 -:1066C00094460002008098218C5200182CC300814F -:1066D0008C4800048C4700088C51000C8C49001039 -:1066E000106000078C4A00142CC4000414800013AE -:1066F00030EB000730C5000310A0001000000000C0 -:106700002410008B02002021022028210E00039873 -:10671000240600031660000224020003000010217A -:106720008FBF00208FB3001C8FB200188FB10014F0 -:106730008FB0001003E0000827BD00281560FFF1AE -:106740002410008B3C0C80003C030020241F00011F -:10675000AD830030AF9F0044000000000000000047 -:10676000000000002419FFF024D8000F031978243A -:106770003C1000D0AD88003801F0702524CD000316 -:106780003C08600EAD87003C35850400AD8E0030BE -:10679000000D38823504003C3C0380008C6B000007 -:1067A000316200201040FFFD0000000010E00008F2 -:1067B00024E3FFFF2407FFFF8CA800002463FFFFF2 -:1067C00024A50004AC8800001467FFFB24840004A7 -:1067D0003C05600EACA60038000000000000000080 -:1067E000000000008F8600543C0400203C0780001D -:1067F000ACE4003054C000060120202102402021DA -:106800000E0003A7000080210A00041D02002021C1 -:106810000E0003DD01402821024020210E0003A7C5 -:10682000000080210A00041D0200202127BDFFE096 -:10683000AFB200183092FFFFAFB10014AFBF001C21 -:10684000AFB000101640000D000088210A0004932C -:106850000220102124050003508500278CE5000C40 -:106860000000000D262800013111FFFF24E2002066 -:106870000232802B12000019AF8200588F82004430 -:10688000144000168F8700583C0670003C0320001F -:106890008CE5000000A62024148300108F84006083 -:1068A000000544023C09800000A980241480FFE90F -:1068B000310600FF2CCA000B5140FFEB26280001D7 -:1068C000000668803C0E080025CE575801AE6021B6 -:1068D0008D8B0000016000080000000002201021E4 -:1068E0008FBF001C8FB200188FB100148FB0001042 -:1068F00003E0000827BD00200E0003982404008454 -:106900001600FFD88F8700580A000474AF8000601B -:10691000020028210E0003BF240400018F870058C5 -:106920000A000474AF820060020028210E0003BF39 -:10693000000020210A0004A38F8700580E000404E1 -:10694000020020218F8700580A000474AF82006083 -:1069500030AFFFFF000F19C03C0480008C9001B8DD -:106960000600FFFE3C1920043C181000AC83018097 -:10697000AC800184AC990188AC9801B80A00047518 -:106980002628000190E2000390E30002000020218D -:106990000002FE0000033A0000FF2825240600083C -:1069A0000E000398000000001600FFDC2402000324 -:1069B0008F870058000010210A000474AF82006025 -:1069C00090E8000200002021240600090A0004C308 -:1069D00000082E0090E4000C240900FF308500FF21 -:1069E00010A900150000302190F9000290F8000372 -:1069F000308F00FF94EB000400196E000018740043 -:106A0000000F62000186202501AE5025014B28258C -:106A10003084FF8B0A0004C32406000A90E30002BE -:106A200090FF0004000020210003360000DF28252D -:106A30000A0004C32406000B0A0004D52406008BB8 -:106A4000000449C23127003F000443423C02800059 -:106A500000082040240316802CE60020AC43002CC4 -:106A600024EAFFE02482000114C0000330A900FFE3 -:106A700000801021314700FF000260803C0D800043 -:106A8000240A0001018D20213C0B000E00EA28049D -:106A9000008B302111200005000538278CCE000026 -:106AA00001C5382503E00008ACC700008CD8000001 -:106AB0000307782403E00008ACCF000027BDFFE007 -:106AC000AFB10014AFB00010AFBF00183C076000BA -:106AD0008CE408083402F0003C1160003083F000C0 -:106AE000240501C03C04800E000030211062000625 -:106AF000241000018CEA08083149F0003928E00030 -:106B00000008382B000780403C0D0200AE2D081411 -:106B1000240C16803C0B80008E2744000E000F8B47 -:106B2000AD6C002C120000043C02169124050001FB -:106B3000120500103C023D2C345800E0AE384408E9 -:106B40003C1108008E31007C8FBF00183C066000AD -:106B500000118540360F16808FB100148FB00010E1 -:106B60003C0E020027BD0020ACCF442003E000080B -:106B7000ACCE08103C0218DA345800E0AE384408B5 -:106B80003C1108008E31007C8FBF00183C0660006D -:106B900000118540360F16808FB100148FB00010A1 -:106BA0003C0E020027BD0020ACCF442003E00008CB -:106BB000ACCE08100A0004EB240500010A0004EB27 -:106BC0000000282124020400A7820024A780001CC2 -:106BD000000020213C06080024C65A582405FFFF67 -:106BE00024890001000440803124FFFF01061821A0 -:106BF0002C87002014E0FFFAAC6500002404040098 -:106C0000A7840026A780001E000020213C06080063 -:106C100024C65AD82405FFFF248D0001000460809B -:106C200031A4FFFF018658212C8A00201540FFFA6D -:106C3000AD650000A7800028A7800020A780002263 -:106C4000000020213C06080024C65B582405FFFFF5 -:106C5000249900010004C0803324FFFF030678213B -:106C60002C8E000415C0FFFAADE500003C05600065 -:106C70008CA73D002403E08F00E31024344601403C -:106C800003E00008ACA63D002487007F000731C266 -:106C900024C5FFFF000518C2246400013082FFFFF5 -:106CA000000238C0A78400303C010800AC27003047 -:106CB000AF80002C0000282100002021000030219E -:106CC0002489000100A728213124FFFF2CA81701E7 -:106CD000110000032C8300801460FFF924C600011A -:106CE00000C02821AF86002C10C0001DA786002AF6 -:106CF00024CAFFFF000A11423C08080025085B581F -:106D00001040000A00002021004030212407FFFF2E -:106D1000248E00010004688031C4FFFF01A86021B7 -:106D20000086582B1560FFFAAD87000030A2001FC7 -:106D30005040000800043080240300010043C804D0 -:106D400000041080004878212738FFFF03E0000886 -:106D5000ADF8000000C820212405FFFFAC8500002D -:106D600003E000080000000030A5FFFF30C6FFFF71 -:106D700030A8001F0080602130E700FF0005294295 -:106D80000000502110C0001D24090001240B000147 -:106D900025180001010B2004330800FF0126782686 -:106DA000390E00202DED00012DC2000101A2182591 -:106DB0001060000D014450250005C880032C4021BF -:106DC0000100182110E0000F000A20278D040000A8 -:106DD000008A1825AD03000024AD00010000402109 -:106DE0000000502131A5FFFF252E000131C9FFFF12 -:106DF00000C9102B1040FFE72518000103E0000830 -:106E0000000000008D0A0000014440240A0005D162 -:106E1000AC68000027BDFFE830A5FFFF30C6FFFFCC -:106E2000AFB00010AFBF001430E7FFFF00005021EB -:106E30003410FFFF0000602124AF001F00C0482174 -:106E4000241800012419002005E0001601E010219B -:106E50000002F943019F682A0009702B01AE40240B -:106E600011000017000C18800064102110E00005CC -:106E70008C4B000000F840040008382301675824B8 -:106E800000003821154000410000402155600016E7 -:106E90003169FFFF258B0001316CFFFF05E1FFEC3D -:106EA00001E0102124A2003E0002F943019F682A5C -:106EB0000009702B01AE40241500FFEB000C188078 -:106EC000154600053402FFFF020028210E0005B51B -:106ED00000003821020010218FBF00148FB0001075 -:106EE00003E0000827BD00181520000301601821E9 -:106EF000000B1C0224080010306A00FF154000053A -:106F0000306E000F250D000800031A0231A800FFA3 -:106F1000306E000F15C00005307F000325100004FF -:106F200000031902320800FF307F000317E000055C -:106F3000386900012502000200031882304800FF72 -:106F4000386900013123000110600004310300FFA3 -:106F5000250A0001314800FF310300FF000C6940A1 -:106F600001A34021240A000110CAFFD53110FFFF00 -:106F7000246E000131C800FF1119FFC638C9000195 -:106F80002D1F002053E0001C258B0001240D000163 -:106F90000A000648240E002051460017258B0001E8 -:106FA00025090001312800FF2D0900205120001281 -:106FB000258B000125430001010D5004014B1024D5 -:106FC000250900011440FFF4306AFFFF3127FFFF5D -:106FD00010EE000C2582FFFF304CFFFF0000502117 -:106FE0003410FFFF312800FF2D0900205520FFF24B -:106FF00025430001258B0001014648260A000602B0 -:10700000316CFFFF00003821000050210A000654B7 -:107010003410FFFF27BDFFD8AFB0001030F0FFFFE6 -:10702000AFB10014001039423211FFE000071080A8 -:10703000AFB3001C00B1282330D3FFFFAFB200185C -:1070400030A5FFFF00809021026030210044202104 -:10705000AFBF00200E0005E03207001F022288218A -:107060003403FFFF0240202102002821026030216A -:1070700000003821104300093231FFFF02201021A7 -:107080008FBF00208FB3001C8FB200188FB1001487 -:107090008FB0001003E0000827BD00280E0005E0B7 -:1070A0000000000000408821022010218FBF002036 -:1070B0008FB3001C8FB200188FB100148FB0001076 -:1070C00003E0000827BD0028000424003C03600002 -:1070D000AC603D0810A00002348210063482101605 -:1070E00003E00008AC623D0427BDFFE0AFB0001034 -:1070F000309000FF2E020006AFBF001810400008BD -:10710000AFB10014001030803C03080024635784A2 -:1071100000C328218CA400000080000800000000AB -:10712000000020218FBF00188FB100148FB0001015 -:107130000080102103E0000827BD00209791002A5D -:1071400016200051000020213C020800904200332C -:107150000A0006BB00000000978D002615A0003134 -:10716000000020210A0006BB2402000897870024A3 -:1071700014E0001A00001821006020212402000100 -:107180001080FFE98FBF0018000429C2004530219C -:1071900000A6582B1160FFE43C0880003C0720004B -:1071A000000569C001A76025AD0C00203C038008E4 -:1071B0002402001F2442FFFFAC6000000441FFFDD9 -:1071C0002463000424A5000100A6702B15C0FFF560 -:1071D000000569C00A0006A58FBF00189787001C2C -:1071E0003C04080024845A58240504000E0006605C -:1071F00024060001978B002424440001308AFFFFFD -:107200002569FFFF2D48040000402821150000409B -:10721000A789002424AC3800000C19C00A0006B964 -:10722000A780001C9787001E3C04080024845AD8BD -:10723000240504000E00066024060001979900262C -:10724000244400013098FFFF272FFFFF2F0E04007A -:107250000040882115C0002CA78F0026A780001EA3 -:107260003A020003262401003084FFFF0E00068D41 -:107270002C4500010011F8C027F00100001021C0CA -:107280000A0006BB240200089785002E978700227B -:107290003C04080024845B580E00066024060001AC -:1072A0009787002A8F89002C2445000130A8FFFF12 -:1072B00024E3FFFF0109302B0040802114C0001897 -:1072C000A783002AA7800022978500300E000F7543 -:1072D00002002021244A05003144FFFF0E00068DE4 -:1072E000240500013C05080094A500320E000F752E -:1072F00002002021244521003C0208009042003376 -:107300000A0006BB000521C00A0006F3A784001E80 -:1073100024AC3800000C19C00A0006B9A784001C70 -:107320000A00070DA7850022308400FF27BDFFE873 -:107330002C820006AFBF0014AFB000101040001543 -:1073400000A03821000440803C0308002463579CBF -:10735000010328218CA40000008000080000000028 -:1073600024CC007F000751C2000C59C23170FFFFCE -:107370002547C40030E5FFFF2784001C02003021B0 -:107380000E0005B52407000197860028020620217B -:10739000A78400288FBF00148FB0001003E00008FE -:1073A00027BD00183C0508008CA50030000779C2F5 -:1073B0000E00038125E4DF003045FFFF3C04080098 -:1073C00024845B58240600010E0005B52407000143 -:1073D000978E002A8FBF00148FB0001025CD0001BA -:1073E00027BD001803E00008A78D002A0007C9C2C6 -:1073F0002738FF00001878C231F0FFFF3C04080076 -:1074000024845AD802002821240600010E0005B564 -:1074100024070001978D0026260E0100000E84002F -:1074200025AC00013C0B6000A78C0026AD603D0838 -:1074300036040006000030213C0760008CE23D0469 -:10744000305F000617E0FFFD24C9000100061B00A5 -:10745000312600FF006440252CC50004ACE83D0443 -:1074600014A0FFF68FBF00148FB0001003E00008D7 -:1074700027BD0018000751C22549C8002406000195 -:10748000240700013C04080024845A580E0005B566 -:107490003125FFFF978700248FBF00148FB00010A5 -:1074A00024E6000127BD001803E00008A786002499 -:1074B0003C0660183C090800252900FCACC9502C8A -:1074C0008CC850003C0580003C020002350700805B -:1074D000ACC750003C04080024841FE03C030800B3 -:1074E00024631F98ACA50008ACA2000C3C01080066 -:1074F000AC2459A43C010800AC2359A803E00008BF -:107500002402000100A030213C1C0800279C59AC3B -:107510003C0C04003C0B0002008B3826008C4026FB -:107520002CE200010007502B2D050001000A4880C5 -:107530003C030800246359A4004520250123182199 -:107540001080000300001021AC660000240200013E -:1075500003E00008000000003C1C0800279C59AC18 -:107560003C0B04003C0A0002008A3026008B3826BF -:107570002CC200010006482B2CE5000100094080C8 -:107580003C030800246359A4004520250103182169 -:1075900010800005000010213C0C0800258C1F986D -:1075A000AC6C00002402000103E0000800000000B1 -:1075B0003C0900023C080400008830260089382677 -:1075C0002CC30001008028212CE400010083102539 -:1075D0001040000B000030213C1C0800279C59ACD7 -:1075E0003C0A80008D4E00082406000101CA68256F -:1075F000AD4D00088D4C000C01855825AD4B000C9D -:1076000003E0000800C010213C1C0800279C59AC76 -:107610003C0580008CA6000C0004202724020001F9 -:1076200000C4182403E00008ACA3000C3C020002D4 -:107630001082000B3C0560003C070400108700032B -:107640000000000003E00008000000008CA908D042 -:10765000240AFFFD012A402403E00008ACA808D05A -:107660008CA408D02406FFFE0086182403E000083E -:10767000ACA308D03C05601A34A600108CC300806F -:1076800027BDFFF88CC50084AFA3000093A40000C1 -:107690002402001010820003AFA5000403E00008DC -:1076A00027BD000893A7000114E0001497AC000266 -:1076B00097B800023C0F8000330EFFFC01CF682119 -:1076C000ADA50000A3A000003C0660008CC708D058 -:1076D0002408FFFE3C04601A00E82824ACC508D04A -:1076E0008FA300048FA200003499001027BD00086A -:1076F000AF22008003E00008AF2300843C0B800031 -:10770000318AFFFC014B48218D2800000A00080C3B -:10771000AFA8000427BDFFE8AFBF00103C1C080065 -:10772000279C59AC3C0580008CA4000C8CA2000462 -:107730003C0300020044282410A0000A00A31824DF -:107740003C0604003C0400021460000900A610245A -:107750001440000F3C0404000000000D3C1C080015 -:10776000279C59AC8FBF001003E0000827BD00180C -:107770003C0208008C4259A40040F80900000000B7 -:107780003C1C0800279C59AC0A0008358FBF00102C -:107790003C0208008C4259A80040F8090000000093 -:1077A0000A00083B000000003C0880008D0201B880 -:1077B0000440FFFE35090180AD2400003C031000A9 -:1077C00024040040AD250004A1240008A1260009DE -:1077D000A527000A03E00008AD0301B83084FFFFCD -:1077E0000080382130A5FFFF000020210A00084555 -:1077F000240600803087FFFF8CA400002406003898 -:107800000A000845000028218F8300788F860070C9 -:107810001066000B008040213C07080024E75B68ED -:10782000000328C000A710218C440000246300013D -:10783000108800053063000F5466FFFA000328C06B -:1078400003E00008000010213C07080024E75B6CFF -:1078500000A7302103E000088CC200003C03900028 -:1078600034620001008220253C038000AC640020CB -:107870008C65002004A0FFFE0000000003E000086B -:10788000000000003C0280003443000100832025FA -:1078900003E00008AC44002027BDFFE0AFB10014B6 -:1078A0003091FFFFAFB00010AFBF001812200013DF -:1078B00000A080218CA20000240400022406020003 -:1078C0001040000F004028210E0007250000000096 -:1078D00000001021AE000000022038218FBF0018E8 -:1078E0008FB100148FB0001000402021000028212B -:1078F000000030210A00084527BD00208CA20000AE -:10790000022038218FBF00188FB100148FB00010F3 -:107910000040202100002821000030210A000845F5 -:1079200027BD002000A010213087FFFF8CA5000498 -:107930008C4400000A000845240600068F83FD9C45 -:1079400027BDFFE8AFBF0014AFB00010906700087C -:10795000008010210080282130E600400000202116 -:1079600010C000088C5000000E0000BD0200202155 -:10797000020020218FBF00148FB000100A000548BC -:1079800027BD00180E0008A4000000000E0000BD76 -:1079900002002021020020218FBF00148FB00010B0 -:1079A0000A00054827BD001827BDFFE0AFB0001052 -:1079B0008F90FD9CAFBF001CAFB20018AFB1001498 -:1079C00092060001008088210E00087230D2000467 -:1079D00092040005001129C2A6050000348300406E -:1079E000A20300050E00087C022020210E00054A9B -:1079F0000220202124020001AE02000C02202821D6 -:107A0000A602001024040002A602001224060200AE -:107A1000A60200140E000725A60200161640000F4D -:107A20008FBF001C978C00743C0B08008D6B007896 -:107A30002588FFFF3109FFFF256A0001012A382B45 -:107A400010E00006A78800743C0F6006240E0016A4 -:107A500035ED0010ADAE00508FBF001C8FB2001886 -:107A60008FB100148FB0001003E0000827BD002084 -:107A700027BDFFE0AFB10014AFBF0018AFB00010DA -:107A80001080000400A088212402008010820007DA -:107A9000000000000000000D8FBF00188FB100141F -:107AA0008FB0001003E0000827BD00200E00087210 -:107AB00000A020218F86FD9C0220202190C500057A -:107AC0000E00087C30B000FF2403003E1603FFF1D7 -:107AD0003C0680008CC401780480FFFE34C801405D -:107AE000240900073C071000AD11000002202021EE -:107AF000A10900048FBF00188FB100148FB00010CF -:107B0000ACC701780A0008C527BD002027BDFFE0EB -:107B1000AFB00010AFBF0018AFB100143C10800030 -:107B20008E110020000000000E00054AAE04002067 -:107B3000AE1100208FBF00188FB100148FB000105D -:107B400003E0000827BD00203084FFFF00803821BB -:107B50002406003500A020210A0008450000282145 -:107B60003084FFFF008038212406003600A0202149 -:107B70000A0008450000282127BDFFD0AFB500242A -:107B80003095FFFFAFB60028AFB40020AFBF002C88 -:107B9000AFB3001CAFB20018AFB10014AFB000100B -:107BA00030B6FFFF12A000270000A0218F920058DE -:107BB0008E4300003C0680002402004000033E0289 -:107BC00000032C0230E4007F006698241482001D1C -:107BD00030A500FF8F8300682C68000A1100001098 -:107BE0008F8D0044000358803C0C0800258C57B84A -:107BF000016C50218D4900000120000800000000A8 -:107C000002D4302130C5FFFF0E0008522404008446 -:107C1000166000028F920058AF8000688F8D00447C -:107C20002659002026980001032090213314FFFFDD -:107C300015A00004AF9900580295202B1480FFDC9A -:107C400000000000028010218FBF002C8FB600289A -:107C50008FB500248FB400208FB3001C8FB20018A2 -:107C60008FB100148FB0001003E0000827BD003072 -:107C70002407003414A70149000000009247000EB9 -:107C80008F9FFDA08F90FD9C24181600A3E700197C -:107C90009242000D3C0880003C07800CA3E20018D3 -:107CA000964A00123C0D60003C117FFFA60A005C62 -:107CB000964400103623FFFF240200053099FFFF91 -:107CC000AE1900548E46001CAD1800288CEF000041 -:107CD0008DAE444801E6482601C93021AE06003881 -:107CE0008E05003824CB00013C0E7F00AE05003C21 -:107CF0008E0C003CAFEC0004AE0B00208E13002075 -:107D0000AE13001CA3E0001BAE03002CA3E2001284 -:107D10008E4A001424130050AE0A00348E0400343E -:107D2000AFE400148E590018AE1900489258000CA8 -:107D3000A218004E920D000835AF0020A20F0008D7 -:107D40008E090018012E282434AC4000AE0C001817 -:107D5000920B0000317200FF1253027F2403FF8058 -:107D60003C04080024845BE80E0008AA0000000020 -:107D70003C1108008E315BE80E00087202202021C1 -:107D80002405000424080001A2050025022020216A -:107D90000E00087CA20800053C0580008CB001782C -:107DA0000600FFFE8F92005834AE0140240F0002FF -:107DB0003C091000ADD10000A1CF0004ACA90178AE -:107DC0000A000962AF8000682CAD003751A0FF9413 -:107DD0008F8D0044000580803C110800263157E05B -:107DE000021178218DEE000001C0000800000000A3 -:107DF0002411000414B1008C3C0780003C080800EA -:107E00008D085BE88F86FD9CACE800208E4500085D -:107E10008F99FDA0240D0050ACC500308E4C000899 -:107E2000ACCC00508E4B000CACCB00348E43001019 -:107E3000ACC300388E4A0010ACCA00548E42001405 -:107E4000ACC2003C8E5F0018AF3F00048E50001C97 -:107E5000ACD0002090C40000309800FF130D024AFF -:107E6000000000008CC400348CD00030009030231F -:107E700004C000F12404008C126000EE2402000310 -:107E80000A000962AF8200682419000514B900666F -:107E90003C0580003C0808008D085BE88F86FD9C4F -:107EA000ACA800208E4C00048F8AFDA0240720007F -:107EB000ACCC001C924B000824120008A14B001906 -:107EC0008F82005890430009A14300188F85005805 -:107ED00090BF000A33E400FF1092001028890009C7 -:107EE000152000BA240E0002240D0020108D000B76 -:107EF000340780002898002117000008240740005C -:107F000024100040109000053C0700012419008057 -:107F1000109900023C070002240740008CC20018A0 -:107F20003C03FF00004350240147F825ACDF001854 -:107F300090B2000BA0D200278F8300589464000CED -:107F4000108001FE000000009467000C3C1F8000C0 -:107F50002405FFBFA4C7005C9063000E2407000443 -:107F6000A0C300088F820058904A000FA0CA0009E1 -:107F70008F8900588D3200108FE400740244C823AA -:107F8000ACD900588D300014ACD0002C95380018B6 -:107F9000330DFFFFACCD00409531001A322FFFFFAB -:107FA000ACCF00448D2E001CACCE00489128000EB2 -:107FB000A0C8000890CC000801855824126001B6C2 -:107FC000A0CB00088F9200580A000962AF870068B2 -:107FD0002406000614A600143C0E80003C0F080086 -:107FE0008DEF5BE88F85FD98ADCF00208E4900189E -:107FF0008F86FD9C8F8BFDA0ACA900008CC800383B -:1080000024040005ACA800048CCC003C1260008164 -:10801000AD6C00000A000962AF84006824110007FB -:1080200010B1004B240400063C05080024A55BE8C1 -:108030000E000881240400818F9200580013102B39 -:108040000A000962AF820068241F002314BFFFF6F4 -:108050003C0C80003C0508008CA55BE88F8BFDA0E4 -:10806000AD8500208F91FD9C8E4600042564002084 -:1080700026450014AE260028240600030E000F81BA -:10808000257000308F87005802002021240600034D -:108090000E000F8124E500083C04080024845BE8FE -:1080A0000E0008AA0000000092230000240A0050DD -:1080B000306200FF544AFFE18F9200580E000F6CAF -:1080C000000000000A000A6A8F920058240800335A -:1080D00014A800323C0380003C1108008E315BE89C -:1080E0008F8FFDA0AC7100208E420008240D002867 -:1080F0008F89FD9CADE200308E4A000C24060009F9 -:10810000ADEA00348E5F0010ADFF00388E440014DD -:10811000ADE400208E590018ADF900248E58001CE3 -:10812000ADF80028A1ED00118E4E00041260003160 -:10813000AD2E00288F9200580A000962AF860068B1 -:10814000240D002214ADFFB8000000002404000735 -:108150003C1008008E105BE83C188000AF10002037 -:108160005660FEAEAF8400683C04080024845BE8DF -:108170000E0008AA241300508F84FD9C90920000EA -:10818000325900FF1333014B000000008F9200585A -:10819000000020210A000962AF8400683C05080045 -:1081A00024A55BE80E000858240400810A000A6A2E -:1081B0008F92005802D498213265FFFF0E000852BA -:1081C000240400840A0009628F920058108EFF5325 -:1081D000240704002887000310E00179241100041B -:1081E000240F0001548FFF4D240740000A000A228B -:1081F000240701003C05080024A55BE80E0008A444 -:10820000240400828F920058000030210A00096285 -:10821000AF8600683C04080024845BE88CC2003808 -:108220000E0008AA8CC3003C8F9200580A000AC0B6 -:1082300000002021240400823C05080024A55BE8FE -:108240000E0008A4000000008F92005800001021CA -:108250000A000962AF8200688E5000048F91FD9C75 -:108260003C078000ACF00020922C00050200282181 -:10827000318B0002156001562404008A8F92FDA004 -:108280002404008D9245001B30A6002014C001502C -:1082900002002821922E00092408001231C900FF93 -:1082A0001128014B240400810E00087202002021D5 -:1082B0009258001B240F000402002021370D0042B9 -:1082C000A24D001B0E00087CA22F00253C0580005B -:1082D0008CA401780480FFFE34B90140241F000201 -:1082E000AF300000A33F00048F9200583C101000F4 -:1082F000ACB001780A000A6B0013102B8E500004FA -:108300008F91FD9C3C038000AC700020922A0005F8 -:108310000200282131420002144000172404008A80 -:10832000922C00092412000402002821318B00FF46 -:1083300011720011240400810E0008720200202135 -:108340008F89FDA0240800122405FFFE912F001B39 -:108350000200202135EE0020A12E001BA2280009DA -:108360009226000500C538240E00087CA2270005CF -:1083700002002821000020210E0009330000000027 -:108380000A000A6A8F9200588E4C00043C07800055 -:108390003C10080026105BE8ACEC00203C01080013 -:1083A000AC2C5BE8924B0003317100041220013BBE -:1083B0008F84FD9C24020006A0820009924F001BBE -:1083C000240EFFC031E9003F012E4025A08800089F -:1083D0009245000330A6000114C0013200000000E5 -:1083E0008E420008AE0200083C0208008C425BF09E -:1083F000104001318F90FDA0000219C28F8DFD9CAD -:10840000A603000C8E4A000C24180001240400145A -:10841000AE0A002C8E420010AE02001C965F0016C1 -:10842000A61F003C96590014A619003EADB8000CDA -:10843000A5B80010A5B80012A5B80014A5B800167C -:1084400012600144A2040011925100033232000272 -:108450002E5300018F920058266200080A0009621C -:10846000AF8200688E4400043C1980003C068008FE -:10847000AF2400208E45000890D80000240D005045 -:10848000331100FF122D009C2407008824060009E8 -:108490000E000845000000000A000A6A8F9200588A -:1084A0008E5000043C0980003C118008AD30002053 -:1084B0009228000024050050310400FF10850110AF -:1084C0002407008802002021000028210E00084512 -:1084D0002406000E922D00002418FF80020028219F -:1084E00001B8802524040004240600300E0007256E -:1084F000A23000000A000A6A8F9200588E500004D1 -:108500008F91FDA03C028000AC500020923F001BE8 -:1085100033F900101320006C240700810200202191 -:10852000000028212406001F0E000845000000005E -:108530000A000A6A8F9200588E44001C0E00085DE3 -:1085400000000000104000E3004048218F880058E0 -:1085500024070089012020218D05001C240600012C -:108560000E000845000000000A000A6A8F920058B9 -:10857000964900023C10080026105BE831280004F0 -:10858000110000973C0460008E4E001C3C0F8000E0 -:10859000ADEE00203C010800AC2E5BE896470002DF -:1085A00030E40001148000E6000000008E42000468 -:1085B000AE0200083C1008008E105BF0120000ECC8 -:1085C0003C0F80008F92FD9C241000018E4E0018FD -:1085D0008F8DFDA08F9FFD9801CF4825AE490018D3 -:1085E000A2400005AE50000C3C0808008D085BF06E -:1085F0008F840058A6500010000839C2A6500012FF -:10860000A6500014A6500016A5A7000C8C8C0008DC -:108610008F8B00588F8A0058ADAC002C8D63000CF6 -:1086200024070002ADA3001C91460010A1A6001172 -:108630008F82005890450011A3E500088F990058DB -:1086400093380012A258004E8F910058922F0013B9 -:10865000A1AF00128F920058964E0014A5AE003CB8 -:1086600096490016A5A9003E8E480018ADA8001432 -:108670005660FD6AAF8700683C05080024A55BE8EA -:108680000E000881000020218F9200580000382140 -:108690000A000962AF8700683C05080024A55BE872 -:1086A0000E0008A4240400828F9200580A000A4D8C -:1086B000000038210E000F6C000000008F9200585F -:1086C0000A000AC0000020210E00087202002021CA -:1086D0009223001B02002021346A00100E00087C47 -:1086E000A22A001B000038210200202100002821BE -:1086F0000A000BA52406001F9242000C305F000107 -:1087000013E0000300000000964A000EA4CA002CEB -:10871000924B000C316300025060000600003821CB -:108720008E470014964C0012ACC7001CA4CC001A53 -:10873000000038210A000B7F240600093C050800D0 -:1087400024A55BE80E0008A42404008B8F92005837 -:108750000A000A4D0013382B3C0C08008D8C5BE896 -:1087600024DFFFFE25930100326B007F016790211B -:1087700002638824AD110028AE4600E0AE4000E45C -:108780000A0009B3AE5F001CACC000543C0D0800E9 -:108790008DAD5BE83C18800C37090100ACED00287A -:1087A0008E510014AD3100E08E4F0014AD2F00E467 -:1087B0008E4E001025C7FFFE0A0009F4AD27001CED -:1087C0005491FDD6240740000A000A222407100015 -:1087D0000E00092D000000000A000A6A8F9200585E -:1087E0008C83442C3C12DEAD3651BEEF3C010800B8 -:1087F000AC205BE810710062000000003C196C6264 -:1088000037387970147800082404000297850074C2 -:108810009782006C2404009200A2F82B13E0001948 -:1088200002002821240400020E00069524050200FF -:108830003C068000ACC200203C010800AC225BE892 -:108840001040000D8F8C0058240A002824040003D7 -:10885000918B0010316300FF546A00012404000171 -:108860000E0000810000000010400004240400837A -:108870000A000BC28F920058240400833C050800B4 -:1088800024A55BE80E000881000000008F920058CC -:108890000013382B0A000962AF8700680A000B49F1 -:1088A000240200128E4400080E00085D0000000043 -:1088B0000A000B55AE0200083C05080024A55BE841 -:1088C0000E000858240400878F9200580A000B728B -:1088D0000013102B240400040E000695240500301C -:1088E0001440002A004048218F8800582407008344 -:1088F000012020218D05001C0A000BB32406000175 -:108900008F8300788F8600701066FEEE000038219D -:108910003C07080024E75B6C000320C00087282187 -:108920008CAE000011D0005D246F000131E3000F18 -:108930005466FFFA000320C00A000B8C00003821A7 -:108940008E4400040E00085D000000000A000BC801 -:10895000AE0200083C05080024A55BE80E0008A450 -:10896000240400828F9200580A000B72000010212C -:108970003C05080024A55BE80A000C7C2404008761 -:108980008C83442C0A000C5B3C196C628F88005865 -:108990003C0780083C0C8000240B0050240A000196 -:1089A000AD820020A0EB0000A0EA000191030004CA -:1089B000A0E3001891040005A0E400199106000648 -:1089C0003C04080024845B6CA0E6001A91020007B6 -:1089D0003C06080024C65B68A0E2001B9105000865 -:1089E000A0E5001C911F0009A0FF001D9119000ABD -:1089F000A0F9001E9118000BA0F8001F9112000CA6 -:108A0000A0F200209111000DA0F100219110000EA4 -:108A1000A0F00022910F000FA0EF0023910E001094 -:108A2000A0EE0024910D0011A0ED0025950C00147E -:108A3000A4EC0028950B00168F8A00708F920078A6 -:108A4000A4EB002A95030018000A10C02545000178 -:108A5000A4E3002C8D1F001C0044C0210046C82147 -:108A600030A5000FAF3F0000AF09000010B20006B4 -:108A7000AF850070000038218D05001C01202021E9 -:108A80000A000BB32406000124AD000131A7000F3A -:108A9000AF8700780A000CF9000038213C06080076 -:108AA00024C65B680086902100003821ACA000003D -:108AB0000A000B8CAE4000003C0482013C036000C5 -:108AC00034820E02AC603D68AF80009803E000087D -:108AD000AC623D6C27BDFFE8AFB000103090FFFFE7 -:108AE000001018422C620041AFBF00141440000275 -:108AF00024040080240300403C010800AC300060E6 -:108B00003C010800AC2300640E000F7500602821B2 -:108B1000244802BF2409FF8001092824001039805D -:108B2000001030408FBF00148FB0001000A720212C -:108B300000861821AF8300803C010800AC25005856 -:108B40003C010800AC24005C03E0000827BD0018CD -:108B5000308300FF30C6FFFF30E400FF3C08800098 -:108B60008D0201B80440FFFE000354000144382583 -:108B70003C09600000E920253C031000AD050180A0 -:108B8000AD060184AD04018803E00008AD0301B81F -:108B90008F8500583C0A6012354800108CAC0004E8 -:108BA0003C0D600E35A60010318B00062D690001CA -:108BB000AD0900C48CA70004ACC731808CA20008AA -:108BC00094A40002ACC231848CA3001C0460000396 -:108BD000A784009003E00008000000008CAF00189C -:108BE000ACCF31D08CAE001C03E00008ACCE31D449 -:108BF0008F8500588F87FF288F86FF308CAE00044A -:108C00003C0F601235E80010ACEE00788CAD000827 -:108C1000ACED007C8CAC0010ACCC004C8CAB000CF0 -:108C2000ACCB004894CA00543C0208008C4200447B -:108C300025490001A4C9005494C400543083FFFFA7 -:108C400010620017000000003C0208008C42004047 -:108C5000A4C200528CA30018ACE300308CA2001414 -:108C6000ACE2002C8CB90018ACF900388CB80014B8 -:108C700024050001ACF800348D0600BC50C5001975 -:108C80008D0200B48D0200B8A4E2004894E40048CC -:108C9000A4E4004A94E800EA03E000083102FFFF80 -:108CA0003C0208008C420024A4C00054A4C200521C -:108CB0008CA30018ACE300308CA20014ACE2002CB2 -:108CC0008CB90018ACF900388CB8001424050001E8 -:108CD000ACF800348D0600BC54C5FFEB8D0200B823 -:108CE0008D0200B4A4E2004894E40048A4E4004AE1 -:108CF00094E800EA03E000083102FFFF8F86005885 -:108D00003C0480008CC900088CC80008000929C0F8 -:108D1000000839C0AC87002090C30007306200040F -:108D20001040003EAF85009490CB0007316A0008E8 -:108D30001140003D8F87FF2C8CCD000C8CCE001491 -:108D400001AE602B11800036000000008CC2000CC8 -:108D5000ACE200708CCB00188F85FF288F88FF3025 -:108D6000ACEB00748CCA00102402FFF8ACAA00D847 -:108D70008CC9000CAD0900608CC4001CACA400D0F0 -:108D800090E3007C0062C824A0F9007C90D8000722 -:108D9000330F000811E000040000000090ED007C9B -:108DA00035AC0001A0EC007C90CF000731EE000153 -:108DB00011C000060000000090E3007C241800347D -:108DC00034790002A0F9007CACB800DC90C2000746 -:108DD0003046000210C000040000000090E8007C53 -:108DE00035040004A0E4007C90ED007D3C0B600E97 -:108DF000356A001031AC003FA0EC007D8D4931D4C4 -:108E00003127000110E00002240E0001A0AE00098D -:108E100094AF00EA03E0000831E2FFFF8F87FF2CE8 -:108E20000A000DAF8CC200140A000DB0ACE0007057 -:108E30008F8C005827BDFFD8AFB3001CAFB200180D -:108E4000AFB00010AFBF0020AFB10014918F00157C -:108E50003C13600E3673001031EB000FA38B009CA7 -:108E60008D8F00048D8B0008959F0012959900103E -:108E70009584001A9598001E958E001C33EDFFFF17 -:108E8000332AFFFF3089FFFF3308FFFF31C7FFFFA1 -:108E90003C010800AC2D00243C010800AC29004432 -:108EA0003C010800AC2A0040AE683178AE67317CE6 -:108EB00091850015959100163C12601236520010F3 -:108EC00030A200FF3230FFFFAE623188AE5000B4F6 -:108ED00091830014959F0018240600010066C804C1 -:108EE00033F8FFFFAE5900B8AE5800BC918E0014A5 -:108EF000AF8F00843C08600631CD00FFAE4D00C04E -:108F0000918A00159584000E3C07600A314900FFE4 -:108F1000AF8B00883084FFFFAE4900C835110010C8 -:108F20000E000D1034F004103C0208008C4200606A -:108F30003C0308008C6300643C0608008CC60058A3 -:108F40003C0508008CA5005C8F8400808FBF00204A -:108F5000AE23004CAE65319CAE030054AE4500DC40 -:108F6000AE6231A0AE6331A4AE663198AE22004845 -:108F70008FB3001CAE0200508FB10014AE4200E06F -:108F8000AE4300E4AE4600D88FB000108FB2001898 -:108F90000A00057D27BD0028978500929783007CF5 -:108FA00027BDFFE8AFB0001000A3102BAFBF001427 -:108FB000240400058F900058104000552409000239 -:108FC0000E0006958F850080AF8200942404000374 -:108FD0001040004F240900023C0680000E00008172 -:108FE000ACC2002024070001240820001040004DDE -:108FF00024040005978E00928F8AFF2C24090050CC -:1090000025C50001A7850092A14900003C0D08007C -:109010008DAD0064240380008F84FF28000D66005E -:10902000AD4C0018A5400006954B000A8F85FF3017 -:109030002402FF8001633024A546000A915F000AE4 -:109040000000482103E2C825A159000AA0A0000899 -:10905000A140004CA08000D5961800029783009094 -:109060003C020004A49800EA960F00022418FFBFF7 -:1090700025EE2401A48E00BE8E0D0004ACAD00448C -:109080008E0C0008ACAC0040A4A00050A4A000547A -:109090008E0B000C240C0030AC8B00288E060010C8 -:1090A000AC860024A480003EA487004EA487005014 -:1090B000A483003CAD420074AC8800D8ACA800602A -:1090C000A08700FC909F00D433F9007FA09900D4C2 -:1090D000909000D402187824A08F00D4914E007C88 -:1090E00035CD0001A14D007C938B009CAD480070F4 -:1090F000AC8C00DCA08B00D68F8800888F87008422 -:10910000AC8800C4AC8700C8A5400078A540007AB0 -:109110008FBF00148FB000100120102103E0000861 -:1091200027BD00188F8500940E0007258F860080CC -:109130000A000E9F2409000227BDFFE0AFB0001017 -:109140008F900058AFB10014AFBF00188E09000413 -:109150000E00054A000921C08E0800048F84FF28F4 -:109160008F82FF30000839C03C068000ACC7002069 -:10917000948500EA904300131460001C30B1FFFF97 -:109180008F8CFF2C918B0008316A00401540000B3A -:10919000000000008E0D0004022030218FBF001857 -:1091A0008FB100148FB00010240400220000382179 -:1091B000000D29C00A000D2F27BD00200E000098C9 -:1091C000000000008E0D0004022030218FBF001827 -:1091D0008FB100148FB00010240400220000382149 -:1091E000000D29C00A000D2F27BD00200E000090A1 -:1091F000000000008E0D0004022030218FBF0018F7 -:109200008FB100148FB00010240400220000382118 -:10921000000D29C00A000D2F27BD002027BDFFE04B -:10922000AFB200183092FFFFAFB00010AFBF001C0C -:10923000AFB100141240001E000080218F8600583C -:109240008CC500002403000600053F02000514023F -:1092500030E4000714830016304500FF2CA80006F8 -:1092600011000040000558803C0C0800258C58BCBB -:10927000016C50218D490000012000080000000011 -:109280008F8E0098240D000111CD005024020002A1 -:10929000AF820098260900013130FFFF24C800206A -:1092A0000212202B010030211480FFE5AF88005806 -:1092B000020010218FBF001C8FB200188FB1001464 -:1092C0008FB0001003E0000827BD00209387007EC8 -:1092D00054E00034000030210E000DE700000000D3 -:1092E0008F8600580A000EFF240200018F87009825 -:1092F0002405000210E50031240400130000282199 -:1093000000003021240700010E000D2F0000000096 -:109310000A000F008F8600588F83009824020002F5 -:109320001462FFF6240400120E000D9A00000000E3 -:109330008F85009400403021240400120E000D2F70 -:10934000000038210A000F008F8600588F83009894 -:109350002411000310710029241F0002107FFFCE8A -:1093600026090001240400100000282100003021FB -:109370000A000F1D240700018F91009824060002A7 -:109380001626FFF9240400100E000E410000000014 -:10939000144000238F9800588F8600580A000EFF53 -:1093A00024020003240400140E000D2F00002821C5 -:1093B0008F8600580A000EFF240200020E000EA93C -:1093C000000000000A000F008F8600580E000D3FBD -:1093D00000000000241900022404001400002821C9 -:1093E0000000302100003821AF9900980E000D2FA9 -:1093F000000000000A000F008F8600580E000D5775 -:10940000000000008F8500942419000200403021E4 -:1094100024040010000038210A000F56AF9900986C -:109420000040382124040010970F0002000028217A -:109430000E000D2F31E6FFFF8F8600580A000F0047 -:10944000AF9100988F84FF2C3C077FFF34E6FFFF2D -:109450008C8500182402000100A61824AC83001893 -:1094600003E00008A08200053084FFFF30A5FFFF65 -:109470001080000700001821308200011040000217 -:1094800000042042006518211480FFFB00052840DD -:1094900003E000080060102110C000070000000079 -:1094A0008CA2000024C6FFFF24A50004AC820000AB -:1094B00014C0FFFB2484000403E000080000000047 -:1094C00010A0000824A3FFFFAC86000000000000ED -:1094D000000000002402FFFF2463FFFF1462FFFA74 -:1094E0002484000403E0000800000000000411C010 -:1094F00003E000082442024027BDFFE8AFB000109F -:1095000000808021AFBF00140E000F9600A0202124 -:1095100000504821240AFF808FBF00148FB0001034 -:10952000012A30243127007F3C08800A3C042100B6 -:1095300000E8102100C428253C03800027BD001846 -:10954000AC650024AF820038AC400000AC6500245C -:1095500003E00008AC4000403C0D08008DAD005811 -:1095600000056180240AFF8001A45821016C482174 -:10957000012A30243127007F3C08800C3C04210064 -:1095800000E8102100C428253C038000AC650028B9 -:10959000AF82003403E00008AC40002430A5FFFF98 -:1095A0003C0680008CC201B80440FFFE3C086015F8 -:1095B00000A838253C031000ACC40180ACC0018475 -:1095C000ACC7018803E00008ACC301B83C0D08003B -:1095D0008DAD005800056180240AFF8001A4582148 -:1095E000016C4021010A4824000931403107007F05 -:1095F00000C728253C04200000A418253C02800058 -:10960000AC43083003E00008AF80003427BDFFE81A -:10961000AFB0001000808021AFBF00140E000F9685 -:1096200000A0202100504821240BFF80012B502452 -:10963000000A39403128007F3C0620008FBF00140B -:109640008FB0001000E8282534C2000100A21825C0 -:109650003C04800027BD0018AC83083003E00008FC -:10966000AF8000383C0580088CA700603C0680086D -:109670000087102B144000112C8340008CA8006040 -:109680002D0340001060000F240340008CC90060CF -:109690000089282B14A00002008018218CC30060D0 -:1096A00000035A42000B30803C0A0800254A59202A -:1096B00000CA202103E000088C8200001460FFF340 -:1096C0002403400000035A42000B30803C0A08008B -:1096D000254A592000CA202103E000088C8200009E -:1096E0003C05800890A60008938400AB24C20001CA -:1096F000304200FF3043007F1064000C0002382726 -:10970000A0A200083C0480008C85017804A0FFFE24 -:109710008F8A00A0240900023C081000AC8A014096 -:10972000A089014403E00008AC8801780A00101BFE -:1097300030E2008027BDFFD8AFB200188F9200A49E -:10974000AFBF0020AFB3001CAFB00010AFB100142A -:109750008F9300348E5900283C1000803C0EFFEFA0 -:10976000AE7900008E580024A260000A35CDFFFFBC -:10977000AE7800049251002C3C0BFF9F356AFFFF2E -:10978000A271000C8E6F000C3C080040A271000B0F -:1097900001F06025018D4824012A382400E8302595 -:1097A000AE66000C8E450004AE6000183C0400FF5D -:1097B000AE6500148E43002C3482FFFFA6600008C3 -:1097C0000062F824AE7F00108E5900088F9000A030 -:1097D000964E0012AE7900208E51000C31D83FFF1A -:1097E00000187980AE7100248E4D001401F06021C4 -:1097F00031CB0001AE6D00288E4A0018000C41C22A -:10980000000B4B80AE6A002C8E46001C01093821EB -:10981000A667001CAE660030964500028E4400200C -:10982000A665001EAE64003492430033306200042B -:1098300054400006924700003C0280083443010077 -:109840008C7F00D0AE7F0030924700008F860038BA -:10985000A0C700309245003330A4000250800007BA -:10986000925100018F880038240BFF80910A00304C -:10987000014B4825A1090030925100018F9000381A -:10988000240CFFBF2404FFDFA21100318F8D0038AC -:109890003C1880083711008091AF003C31EE007F0A -:1098A000A1AE003C8F890038912B003C016C502404 -:1098B000A12A003C8F9F00388E68001493E6003C7C -:1098C0002D0700010007114000C4282400A218251C -:1098D000A3E3003C8F87003896590012A4F90032A8 -:1098E0008E450004922E007C30B0000300107823D7 -:1098F00031ED000300AD102131CC000215800002D3 -:1099000024460034244600303C0280083443008062 -:10991000907F007C00BFC824333800041700000289 -:1099200024C2000400C010218F98003824190002BE -:10993000ACE20034A3190000924F003F8F8E003834 -:109940003C0C8008358B0080A1CF00018F9100383E -:10995000924D003F8E440004A62D0002956A005CE3 -:109960000E000FF43150FFFF00024B800209382532 -:109970003C08420000E82825AE2500048E4400384B -:109980008F850038ACA400188E460034ACA6001CAD -:10999000ACA0000CACA00010A4A00014A4A0001661 -:1099A000A4A00020A4A00022ACA000248E62001479 -:1099B00050400001240200018FBF00208FB3001C23 -:1099C0008FB200188FB100148FB00010ACA2000845 -:1099D0000A00101327BD002827BDFFC83C058008DA -:1099E00034A40080AFBF0034AFBE0030AFB7002C4E -:1099F000AFB60028AFB50024AFB40020AFB3001C51 -:109A0000AFB20018AFB10014AFB00010948300786B -:109A10009482007A104300512405FFFF0080F0215A -:109A20000A0011230080B821108B004D8FBF003435 -:109A30008F8600A03C1808008F18005C2411FF805E -:109A40003C1680000306782101F18024AED0002C62 -:109A500096EE007A31EC007F3C0D800E31CB7FFF1B -:109A6000018D5021000B4840012AA82196A4000036 -:109A70003C0808008D0800582405FF8030953FFF02 -:109A800001061821001539800067C8210325F82434 -:109A90003C02010003E290253338007F3C11800C2A -:109AA000AED20028031190219250000D320F000415 -:109AB00011E0003702E0982196E3007A96E8007AF8 -:109AC00096E5007A2404800031077FFF24E300013B -:109AD00030627FFF00A4F82403E2C825A6F9007ACB -:109AE00096E6007A3C1408008E94006030D67FFF22 -:109AF00012D400C1000000008E5800188F8400A00E -:109B000002A028212713FFFF0E000FCEAE53002C1A -:109B100097D5007897D4007A12950010000028217C -:109B20003C098008352401003C0A8008914800085F -:109B3000908700D53114007F30E400FF0284302B81 -:109B400014C0FFB9268B0001938E00AB268C000158 -:109B5000008E682115ACFFB78F8600A08FBF003440 -:109B60008FBE00308FB7002C8FB600288FB5002431 -:109B70008FB400208FB3001C8FB200188FB1001477 -:109B80008FB0001000A0102103E0000827BD0038AE -:109B900000C020210E000F99028028218E4B00105A -:109BA0008E4C00308F84003824090002016C502351 -:109BB000AE4A0010A089000096E3005C8E4400309D -:109BC0008F9100380E000FF43070FFFF00024380C9 -:109BD000020838253C02420000E22825AE25000498 -:109BE0008E5F00048F8A00388E590000240B000815 -:109BF000AD5F001CAD590018AD40000CAD40001029 -:109C00009246000A240400052408C00030D000FF5A -:109C1000A550001496580008A55800169251000A45 -:109C20003C188008322F00FFA54F0020964E0008F8 -:109C300037110100A54E0022AD400024924D000BCB -:109C400031AC00FFA54C0002A14B00018E49003051 -:109C50008F830038240BFFBFAC690008A06400307C -:109C60008F9000382403FFDF9607003200E8282495 -:109C700000B51025A6020032921F003233F9003FD2 -:109C800037260040A20600328F8C0038AD800034A9 -:109C90008E2F00D0AD8F0038918E003C3C0F7FFF9F -:109CA00031CD007FA18D003C8F84003835EEFFFF61 -:109CB000908A003C014B4824A089003C8F850038E5 -:109CC00090A8003C01033824A0A7003C8E42003439 -:109CD0008F9100383C038008AE2200408E59002C42 -:109CE0008E5F0030033F3023AE26004492300048A0 -:109CF0003218007FA23800488F8800388E4D00301F -:109D00008D0C004801AE582401965024014B482583 -:109D1000AD0900489244000AA104004C964700088F -:109D20008F850038A4A7004E8E5000308E4400303E -:109D30000E0003818C65006092F9007C0002F940FE -:109D4000004028210002110003E2302133360002D6 -:109D500012C00003020680210005B0800216802197 -:109D6000926D007C31B30004126000020005708027 -:109D7000020E80218E4B00308F8800382405800031 -:109D8000316A0003000A4823312400030204182129 -:109D9000AD03003496E4007A96F0007A96F1007AEA -:109DA00032027FFF2447000130FF7FFF0225C824D5 -:109DB000033F3025A6E6007A96F8007A3C120800A8 -:109DC0008E520060330F7FFF11F200180000000078 -:109DD0008F8400A00E000FCE02A028218F8400A047 -:109DE0000E000FDE028028210E001013000000007C -:109DF0000A00111F0000000096F1007A022480245E -:109E0000A6F0007A92EF007A92EB007A31EE00FF32 -:109E1000000E69C2000D6027000C51C03169007F3F -:109E2000012A20250A001119A2E4007A96E6007A98 -:109E300000C5C024A6F8007A92EF007A92F3007A67 -:109E400031F200FF001271C2000E6827000DB1C090 -:109E5000326C007F01962825A2E5007A0A0011D015 -:109E60008F8400A03C0380003084FFFF30A5FFFFFB -:109E7000AC640018AC65001C03E000088C620014A0 -:109E800027BDFFA03C068008AFBF005CAFBE0058F6 -:109E9000AFB70054AFB60050AFB5004CAFB40048F8 -:109EA000AFB30044AFB20040AFB1003CAFB0003838 -:109EB00034C80100910500D590C700083084FFFF29 -:109EC00030A500FF30E2007F0045182AAFA4001043 -:109ED000A7A00018A7A0002610600055AFA000148E -:109EE00090CA00083149007F00A9302324D3FFFF26 -:109EF0000013802B8FB400100014902B02128824C2 -:109F0000522000888FB300143C03800894790052DB -:109F1000947E00508FB60010033EC0230018BC0092 -:109F2000001714030016FC0002C2A82A16A00002A3 -:109F3000001F2C030040282100133C0000072403CD -:109F400000A4102A5440000100A020212885000907 -:109F500014A000020080A021241400083C0C8008FA -:109F60008D860048001459808D88004C3C03800089 -:109F70003169FFFF3C0A0010012A202534710400DA -:109F8000AC660038AF9100A4AC68003CAC64003013 -:109F900000000000000000000000000000000000C1 -:109FA00000000000000000000000000000000000B1 -:109FB0008C6E000031CD002011A0FFFD0014782A26 -:109FC00001F01024104000390000A8213C16800840 -:109FD00092D700083C1280008E44010032F6007FC8 -:109FE0000E000F9902C028218E3900108E44010006 -:109FF0000000902133373FFF0E000FB102E028210F -:10A00000923800003302003F2C500008520000102C -:10A0100000008821000210803C030800246358E4FB -:10A020000043F8218FFE000003C00008000000007C -:10A0300090CF0008938C00AB31EE007F00AE682318 -:10A04000018D58210A0012172573FFFF0000882197 -:10A050003C1E80008FC401000E000FCE02E02821BC -:10A060008FC401000E000FDE02C028211220000F55 -:10A070000013802B8F8B00A426A400010004AC00E9 -:10A08000027298230015AC032578004002B4B02A70 -:10A090000013802B241700010300882102D0102414 -:10A0A000AF9800A41440FFC9AFB700143C07800864 -:10A0B00094E200508FAE00103C05800002A288217F -:10A0C0003C060020A4F10050ACA6003094F40050EF -:10A0D00094EF005201D51823306CFFFF11F4001EDD -:10A0E000AFAC00108CEF004C001561808CF500487F -:10A0F00001EC28210000202100AC582B02A4C02133 -:10A10000030BB021ACE5004CACF600488FB4001056 -:10A110000014902B021288241620FF7C3C03800838 -:10A120008FB300148FBF005C8FBE00583A620001ED -:10A130008FB700548FB600508FB5004C8FB40048D5 -:10A140008FB300448FB200408FB1003C8FB0003815 -:10A1500003E0000827BD006094FE00548CF2004428 -:10A1600033C9FFFE0009C8C00259F821ACBF003C4A -:10A170008CE800448CAD003C010D50231940003B9D -:10A18000000000008CF7004026E20001ACA200387D -:10A190003C05005034A700103C038000AC67003041 -:10A1A00000000000000000000000000000000000AF -:10A1B000000000000000000000000000000000009F -:10A1C0008C7800003316002012C0FFFD3C1180087F -:10A1D000962200543C1580003C068008304E000159 -:10A1E000000E18C0007578218DEC04003C070800B3 -:10A1F0008CE700443C040020ACCC00488DF40404FF -:10A20000240B0001ACD4004C10EB0260AEA4003073 -:10A21000963900523C0508008CA5004000B99021F9 -:10A22000A6320052963F005427ED0001A62D00549F -:10A230009626005430C4FFFF5487FF2F8FB40010C0 -:10A2400030A5FFFF0E0011F4A62000543C070800C3 -:10A250008CE70024963E00520047B82303D74823DA -:10A26000A62900520A0012198FB400108CE2004097 -:10A270000A0012BE00000000922400012407000121 -:10A280003085007F14A7001C97AD00268E2B00148C -:10A29000240CC000316A3FFF01AC48243C06080092 -:10A2A0008CC60060012A402531043FFF0086882BC0 -:10A2B00012200011A7A800263C0508008CA5005814 -:10A2C0008F9100A0000439802402FF8000B1182182 -:10A2D0000067F82103E2F02433F8007F3C1280008D -:10A2E0003C19800EAE5E002C0319702191D0000D38 -:10A2F000360F0004A1CF000D0E001028241200011B -:10A30000241100013C1E80008FC401000E000FCEFE -:10A3100002E028218FC401000E000FDE02C02821B8 -:10A320001620FF558F8B00A40A0012860013802B85 -:10A330008F8600A490C80001310400201080019194 -:10A34000241000013C048008348B0080916A007C5A -:10A350008F9E0034AFA0002C314900011120000F66 -:10A36000AFB000288CCD00148C8E006001AE602B45 -:10A370001580000201A038218C8700603C188008FD -:10A38000370300808C70007000F0782B15E000021D -:10A3900000E020218C640070AFA4002C3C028008F7 -:10A3A000344500808CD200148CBF0070025FC82B33 -:10A3B00017200002024020218CA400708FA7002CDF -:10A3C0000087182310600003AFA3003024050002AB -:10A3D000AFA500288FA400280264882B162000BA9D -:10A3E000000018218CD000388FCE000C3C0F00806C -:10A3F000AFD000008CCD00343C0CFF9F01CF58251E -:10A40000AFCD000490CA003F3586FFFF01662024CF -:10A410003C0900203C08FFEFA3CA000B0089382547 -:10A420003511FFFF00F118243C0500088F8700A4B8 -:10A430000065C825AFD9000C8CE20014AFC000182D -:10A440008FA60030AFC200148CF800188FB0002C1B -:10A450003C1FFFFBAFD8001C8CEF000837F2FFFF5A -:10A4600003326824AFCF00248CEC000C020670216C -:10A47000AFCD000CA7C00038A7C0003AAFCE002C6B -:10A48000AFCC0020AFC000288CEA00148FAB002CAA -:10A49000014B48230126402311000011AFC80010D2 -:10A4A00090EB003D8FC900048FC80000000B5100E5 -:10A4B000012A28210000102100AA882B010218215E -:10A4C0000071F821AFC50004AFDF000090F2003D3D -:10A4D000A3D2000A8F9900A497380006A7D80008D5 -:10A4E0008F910038240800023C038008A228000055 -:10A4F0003465008094BF005C8FA4002C33F0FFFF14 -:10A500000E000FF48F9200380002CB808F8500A4DC -:10A51000021978253C18420001F87025AE4E00045F -:10A520008F8400388CAD0038AC8D00188CAC0034B2 -:10A53000AC8C001CAC80000CAC800010A48000141B -:10A54000A4800016A4800020A4800022AC800024F7 -:10A5500090A6003F8FA7002CA486000250E0019235 -:10A56000240700018FA200305040000290A2003D5D -:10A5700090A2003E244A0001A08A00018F84003886 -:10A580008FA9002CAC8900083C128008364D008051 -:10A5900091AC007C3186000214C000022407003414 -:10A5A000240700308F8500A43C198008373F0080C5 -:10A5B00090B0000093F9007C240E0004A0900030BD -:10A5C0008F8F00A48FB8002C8F8D003891F200017E -:10A5D0003304000301C46023A1B200318F8E003820 -:10A5E0008F8600A42402C00095CA003294C90012CC -:10A5F0008FAB002C0142402431233FFF010388250B -:10A60000A5D1003291D000323185000300EBF82152 -:10A610003218003F370F0040A1CF00328FA4002C2A -:10A6200003E5382133280004108000028F850038AC -:10A6300000E838213C0A8008ACA700343549010005 -:10A640008D2800D08FA3002C2419FFBFACA80038A0 -:10A6500090B1003C2C640001240FFFDF3227007F03 -:10A66000A0A7003C8F98003800049140931F003C45 -:10A6700003F98024A310003C8F8C0038918E003C9D -:10A6800001CF682401B23025A186003C8F8900A447 -:10A690008F8800388D2B0020AD0B00408D220024C8 -:10A6A000AD0200448D2A0028AD0A00488D23002CFD -:10A6B0000E001013AD03004C8FB1002824070002D8 -:10A6C000122700118FA300280003282B00058023E8 -:10A6D0000270982400608021006090210A00126FAF -:10A6E0000010882B962900128F8400A00000902172 -:10A6F0003125FFFFA7A900180E000FC22411000189 -:10A700000A00131D3C1E80003C0B80003C12800898 -:10A710008D640100924900088F92FF340E000F995A -:10A720003125007F8F9900388FA700288FA4003033 -:10A73000A3270000965F005C33F0FFFF0E000FF4CC -:10A740008F91003800026B80020D80253C0842008A -:10A750008F8D00A402085025AE2A00048DA5003874 -:10A760008F8A003800007821000F1100AD450018D5 -:10A770008DB800343C047FFF3488FFFFAD58001CC7 -:10A7800091A6003E8D4C001C8D4900180006190052 -:10A79000000677020183C821004E58250323882B29 -:10A7A000012B382100F1F821AD59001CAD5F0018D4 -:10A7B000AD40000CAD40001091B0003E8FA40030C1 -:10A7C00024090005A550001495A500042419C00013 -:10A7D00000884024A545001691B8003EA5580020E9 -:10A7E00095AF0004A54F0022AD40002491AE003F7C -:10A7F000A54E000291A6003E91AC003D01861023BB -:10A80000244B0001A14B00018F9100388FA3003031 -:10A810003C028008344B0100AE230008A22900301E -:10A820008F8C00388F8700A4959F003294F000121F -:10A830002407FFBF033FC02432053FFF03057825EF -:10A84000A58F0032918E00322418FFDF31CD003FFA -:10A8500035A60040A18600328F910038240DFFFFFD -:10A86000240CFF80AE2000348D6A00D0AE2A003860 -:10A870009223003C3069007FA229003C8F90003871 -:10A880003C0380009219003C0327F824A21F003CDF -:10A890008F8E003891C5003C00B87824A1CF003CD1 -:10A8A0008F8A00383C0E8008AD4D00408FA6002CEA -:10A8B000AD46004491420048004C5825A14B004849 -:10A8C0008F9000388F9900A48E09004801238824B6 -:10A8D00002283825AE070048933F003EA21F004CD7 -:10A8E0008F9800A48F8F003897050004A5E5004ECF -:10A8F0000E0003818DC500609246007C8FAC003055 -:10A9000000026940000291000040282130CB000283 -:10A9100001B21021156000AA018230213C0E80088E -:10A9200035C20080904C007C31830004106000032D -:10A930008FB900300005788000CF3021241F00043B -:10A940008F910038332D000303ED8023320800037C -:10A9500000C85021AE2A00343C188000A7C500383A -:10A960003C0680088F04010090DE00080E000FDE18 -:10A9700033C5007F0E001013000000000A00140D04 -:10A980008FA300288F9800348CC90038241F00033F -:10A99000A7000008AF0900008CC50034A300000A1E -:10A9A0008F9900A4AF0500043C080080932D003F60 -:10A9B000A31F000C8F0A000C3C02FF9FA30D000B8D -:10A9C0000148F0253451FFFF3C12FFEF8F9900A49E -:10A9D00003D170243646FFFF01C61824AF03000CD4 -:10A9E0008F2C0014972900128F8400A0AF0C001048 -:10A9F0008F2F0014AF000018AF000020AF0F00141D -:10AA0000AF0000248F270018312F3FFF000F59801F -:10AA1000AF0700288F2500080164F821312D0001BF -:10AA2000AF0500308F31000C8F920038001F51C2EB -:10AA3000000D438001481021241E00023C068008BE -:10AA4000A702001CA7000034AF11002CA25E00007A -:10AA500034D20080964E005C8F9900383C0342004F -:10AA600031CCFFFF01833825AF2700048F8B00A472 -:10AA7000240500012402C0008D640038240700343E -:10AA8000AF2400188D690034AF29001CAF20000CE2 -:10AA9000AF200010A7200014A7200016A720002038 -:10AAA000A7200022AF200024A7300002A325000128 -:10AAB0008F8800388F9F00A4AD10000893ED000030 -:10AAC000A10D00308F8A00A48F98003891510001A9 -:10AAD000A31100318F8B0038957E003203C27024A1 -:10AAE00001CF6025A56C0032916300323064003FD5 -:10AAF000A16400329249007C3125000214A00002BA -:10AB00008F840038240700303C198008AC8700345B -:10AB1000373201008E5F00D0240AFFBF020090216F -:10AB2000AC9F0038908D003C31A8007FA088003C8D -:10AB30008F9E003893C2003C004A8824A3D1003C79 -:10AB40008F8300380010882B9066003C34CE0020A4 -:10AB5000A06E003C8F8400A48F9800388C8C00205D -:10AB6000AF0C00408C8F0024AF0F00448C8700286E -:10AB7000AF0700488C8B002CAF0B004C0E0010135D -:10AB80003C1E80000A0012700000000094C80052B1 -:10AB90003C0A08008D4A002401488821A4D10052B3 -:10ABA0000A0012198FB40010A08700018F840038AA -:10ABB000240B0001AC8B00080A0013BE3C12800875 -:10ABC000000520800A0014A200C4302127BDFFE048 -:10ABD0003C0D8008AFB20018AFB00010AFBF001C32 -:10ABE000AFB1001435B200808E4C001835A80100BA -:10ABF000964B000695A70050910900FC000C5602E8 -:10AC0000016728233143007F312600FF240200031F -:10AC1000AF8300A8AF8400A010C2001B30B0FFFFBC -:10AC2000910600FC2412000530C200FF10520033D0 -:10AC300000000000160000098FBF001C8FB2001832 -:10AC40008FB100148FB00010240D0C003C0C80005C -:10AC500027BD002003E00008AD8D00240E0011FB8D -:10AC6000020020218FBF001C8FB200188FB100148A -:10AC70008FB00010240D0C003C0C800027BD00207C -:10AC800003E00008AD8D0024965800789651007AB4 -:10AC9000924E007D0238782631E8FFFF31C400C0B3 -:10ACA000148000092D11000116000037000000007B -:10ACB0005620FFE28FBF001C0E0010D100000000E4 -:10ACC0000A00156A8FBF001C1620FFDA0000000082 -:10ACD0000E0010D1000000001440FFD88FBF001CF0 -:10ACE0001600002200000000925F007D33E2003F6A -:10ACF000A242007D0A00156A8FBF001C950900EA78 -:10AD00008F86008000802821240400050E0007257E -:10AD10003130FFFF978300923C0480002465FFFFE1 -:10AD2000A78500928C8A01B80540FFFE0000000054 -:10AD3000AC8001808FBF001CAC9001848FB20018E2 -:10AD40008FB100148FB000103C0760133C0B100053 -:10AD5000240D0C003C0C800027BD0020AC8701882E -:10AD6000AC8B01B803E00008AD8D00240E0011FB90 -:10AD7000020020215040FFB18FBF001C925F007D78 -:10AD80000A00159733E2003F0E0011FB020020215C -:10AD90001440FFAA8FBF001C122000070000000013 -:10ADA0009259007D3330003F36020040A242007DC0 -:10ADB0000A00156A8FBF001C0E0010D100000000B1 -:10ADC0005040FF9E8FBF001C9259007D3330003FE2 -:08ADD0000A0015C6360200401E -:08ADD800000000000000001B58 -:10ADE0000000000F0000000A00000008000000063C -:10ADF0000000000500000005000000040000000441 -:10AE00000000000300000003000000030000000336 -:10AE10000000000300000002000000020000000229 -:10AE2000000000020000000200000002000000021A -:10AE3000000000020000000200000002000000020A -:10AE400000000002000000020000000200000002FA -:0CAE5000000000010000000100000001F3 -:04AE5C008008010069 -:10AE6000800800808008000000000C000000308096 -:10AE7000080011D00800127C08001294080012A8E3 -:10AE8000080012BC080011D0080011D0080012F010 -:10AE90000800132C080013400800138808001A8CBF -:10AEA00008001A8C08001AC408001AC408001AD82E -:10AEB00008001AA808001D0008001CCC08001D5836 -:10AEC00008001D5808001DE008001D108008024001 -:10AED000080027340800256C0800275C080027F4C8 -:10AEE0000800293C0800298808002AAC080029B479 -:10AEF00008002A38080025DC08002EDC08002EA4F3 -:10AF000008002588080025880800258808002B20CF -:10AF100008002B20080025880800258808002DD06F -:10AF2000080025880800258808002588080025884D -:10AF300008002E0C080025880800258808002588B0 -:10AF4000080025880800258808002588080025882D -:10AF5000080025880800258808002588080025881D -:10AF6000080025880800258808002588080029A8E9 -:10AF7000080025880800258808002E680800258814 -:10AF800008002588080025880800258808002588ED -:10AF900008002588080025880800258808002588DD -:10AFA00008002588080025880800258808002588CD -:10AFB00008002588080025880800258808002588BD -:10AFC00008002CF4080025880800258808002C6853 -:10AFD00008002BC408003CE408003CB808003C848E -:10AFE00008003C5808003C3808003BEC8008010091 -:10AFF00080080080800800008008008008004C6401 -:10B0000008004C9C08004BE408004C6408004C64A9 -:0CB01000080049B808004C6408005050CB -:04B01C000A000C8496 -:10B0200000000000000000000000000D7278703683 -:10B030002E322E3100000000060201030000000045 -:10B0400000000001000000000000000000000000FF -:10B0500000000000000000000000000000000000F0 -:10B0600000000000000000000000000000000000E0 -:10B0700000000000000000000000000000000000D0 -:10B0800000000000000000000000000000000000C0 -:10B0900000000000000000000000000000000000B0 -:10B0A00000000000000000000000000000000000A0 -:10B0B0000000000000000000000000000000000090 -:10B0C0000000000000000000000000000000000080 -:10B0D0000000000000000000000000000000000070 -:10B0E0000000000000000000000000000000000060 -:10B0F0000000000000000000000000000000000050 -:10B10000000000000000000000000000000000003F -:10B11000000000000000000000000000000000002F -:10B12000000000000000000000000000000000001F -:10B13000000000000000000000000000000000000F -:10B1400000000000000000000000000000000000FF -:10B1500000000000000000000000000000000000EF -:10B1600000000000000000000000000000000000DF -:10B1700000000000000000000000000000000000CF -:10B1800000000000000000000000000000000000BF -:10B1900000000000000000000000000000000000AF -:10B1A000000000000000000000000000000000009F -:10B1B000000000000000000000000000000000008F -:10B1C000000000000000000000000000000000007F -:10B1D000000000000000000000000000000000006F -:10B1E000000000000000000000000000000000005F -:10B1F000000000000000000000000000000000004F -:10B20000000000000000000000000000000000003E -:10B21000000000000000000000000000000000002E -:10B22000000000000000000000000000000000001E -:10B23000000000000000000000000000000000000E -:10B2400000000000000000000000000000000000FE -:10B2500000000000000000000000000000000000EE -:10B2600000000000000000000000000000000000DE -:10B2700000000000000000000000000000000000CE -:10B2800000000000000000000000000000000000BE -:10B2900000000000000000000000000000000000AE -:10B2A000000000000000000000000000000000009E -:10B2B000000000000000000000000000000000008E -:10B2C000000000000000000000000000000000007E -:10B2D000000000000000000000000000000000006E -:10B2E000000000000000000000000000000000005E -:10B2F000000000000000000000000000000000004E -:10B30000000000000000000000000000000000003D -:10B31000000000000000000000000000000000002D -:10B32000000000000000000000000000000000001D -:10B33000000000000000000000000000000000000D -:10B3400000000000000000000000000000000000FD -:10B3500000000000000000000000000000000000ED -:10B3600000000000000000000000000000000000DD -:10B3700000000000000000000000000000000000CD -:10B3800000000000000000000000000000000000BD -:10B3900000000000000000000000000000000000AD -:10B3A000000000000000000000000000000000009D -:10B3B000000000000000000000000000000000008D -:10B3C000000000000000000000000000000000007D -:10B3D000000000000000000000000000000000006D -:10B3E000000000000000000000000000000000005D -:10B3F000000000000000000000000000000000004D -:10B40000000000000000000000000000000000003C -:10B41000000000000000000000000000000000002C -:10B42000000000000000000000000000000000001C -:10B43000000000000000000000000000000000000C -:10B4400000000000000000000000000000000000FC -:10B4500000000000000000000000000000000000EC -:10B4600000000000000000000000000000000000DC -:10B4700000000000000000000000000000000000CC -:10B4800000000000000000000000000000000000BC -:10B4900000000000000000000000000000000000AC -:10B4A000000000000000000000000000000000009C -:10B4B000000000000000000000000000000000008C -:10B4C000000000000000000000000000000000007C -:10B4D000000000000000000000000000000000006C -:10B4E000000000000000000000000000000000005C -:10B4F000000000000000000000000000000000004C -:10B50000000000000000000000000000000000003B -:10B51000000000000000000000000000000000002B -:10B52000000000000000000000000000000000001B -:10B53000000000000000000000000000000000000B -:10B5400000000000000000000000000000000000FB -:10B5500000000000000000000000000000000000EB -:10B5600000000000000000000000000000000000DB -:10B5700000000000000000000000000000000000CB -:10B5800000000000000000000000000000000000BB -:10B5900000000000000000000000000000000000AB -:10B5A000000000000000000000000000000000009B -:10B5B000000000000000000000000000000000008B -:10B5C000000000000000000000000000000000007B -:10B5D000000000000000000000000000000000006B -:10B5E000000000000000000000000000000000005B -:10B5F000000000000000000000000000000000004B -:10B60000000000000000000000000000000000003A -:10B61000000000000000000000000000000000002A -:10B62000000000000000000000000000000000001A -:10B63000000000000000000000000000000000000A -:10B6400000000000000000000000000000000000FA -:10B6500000000000000000000000000000000000EA -:10B6600000000000000000000000000000000000DA -:10B6700000000000000000000000000000000000CA -:10B6800000000000000000000000000000000000BA -:10B6900000000000000000000000000000000000AA -:10B6A000000000000000000000000000000000009A -:10B6B000000000000000000000000000000000008A -:10B6C000000000000000000000000000000000007A -:10B6D000000000000000000000000000000000006A -:10B6E000000000000000000000000000000000005A -:10B6F000000000000000000000000000000000004A -:10B700000000000000000000000000000000000039 -:10B710000000000000000000000000000000000029 -:10B720000000000000000000000000000000000019 -:10B730000000000000000000000000000000000009 -:10B7400000000000000000000000000000000000F9 -:10B7500000000000000000000000000000000000E9 -:10B7600000000000000000000000000000000000D9 -:10B7700000000000000000000000000000000000C9 -:10B7800000000000000000000000000000000000B9 -:10B7900000000000000000000000000000000000A9 -:10B7A0000000000000000000000000000000000099 -:10B7B0000000000000000000000000000000000089 -:10B7C0000000000000000000000000000000000079 -:10B7D0000000000000000000000000000000000069 -:10B7E0000000000000000000000000000000000059 -:10B7F0000000000000000000000000000000000049 -:10B800000000000000000000000000000000000038 -:10B810000000000000000000000000000000000028 -:10B820000000000000000000000000000000000018 -:10B830000000000000000000000000000000000008 -:10B8400000000000000000000000000000000000F8 -:10B8500000000000000000000000000000000000E8 -:10B8600000000000000000000000000000000000D8 -:10B8700000000000000000000000000000000000C8 -:10B8800000000000000000000000000000000000B8 -:10B8900000000000000000000000000000000000A8 -:10B8A0000000000000000000000000000000000098 -:10B8B0000000000000000000000000000000000088 -:10B8C0000000000000000000000000000000000078 -:10B8D0000000000000000000000000000000000068 -:10B8E0000000000000000000000000000000000058 -:10B8F0000000000000000000000000000000000048 -:10B900000000000000000000000000000000000037 -:10B910000000000000000000000000000000000027 -:10B920000000000000000000000000000000000017 -:10B930000000000000000000000000000000000007 -:10B9400000000000000000000000000000000000F7 -:10B9500000000000000000000000000000000000E7 -:10B9600000000000000000000000000000000000D7 -:10B9700000000000000000000000000000000000C7 -:10B9800000000000000000000000000000000000B7 -:10B9900000000000000000000000000000000000A7 -:10B9A0000000000000000000000000000000000097 -:10B9B0000000000000000000000000000000000087 -:10B9C0000000000000000000000000000000000077 -:10B9D0000000000000000000000000000000000067 -:10B9E0000000000000000000000000000000000057 -:10B9F0000000000000000000000000000000000047 -:10BA00000000000000000000000000000000000036 -:10BA10000000000000000000000000000000000026 -:10BA20000000000000000000000000000000000016 -:10BA30000000000000000000000000000000000006 -:10BA400000000000000000000000000000000000F6 -:10BA500000000000000000000000000000000000E6 -:10BA600000000000000000000000000000000000D6 -:10BA700000000000000000000000000000000000C6 -:10BA800000000000000000000000000000000000B6 -:10BA900000000000000000000000000000000000A6 -:10BAA0000000000000000000000000000000000096 -:10BAB0000000000000000000000000000000000086 -:10BAC0000000000000000000000000000000000076 -:10BAD0000000000000000000000000000000000066 -:10BAE0000000000000000000000000000000000056 -:10BAF0000000000000000000000000000000000046 -:10BB00000000000000000000000000000000000035 -:10BB10000000000000000000000000000000000025 -:10BB20000000000000000000000000000000000015 -:10BB30000000000000000000000000000000000005 -:10BB400000000000000000000000000000000000F5 -:10BB500000000000000000000000000000000000E5 -:10BB600000000000000000000000000000000000D5 -:10BB700000000000000000000000000000000000C5 -:10BB800000000000000000000000000000000000B5 -:10BB900000000000000000000000000000000000A5 -:10BBA0000000000000000000000000000000000095 -:10BBB0000000000000000000000000000000000085 -:10BBC0000000000000000000000000000000000075 -:10BBD0000000000000000000000000000000000065 -:10BBE0000000000000000000000000000000000055 -:10BBF0000000000000000000000000000000000045 -:10BC00000000000000000000000000000000000034 -:10BC10000000000000000000000000000000000024 -:10BC20000000000000000000000000000000000014 -:10BC30000000000000000000000000000000000004 -:10BC400000000000000000000000000000000000F4 -:10BC500000000000000000000000000000000000E4 -:10BC600000000000000000000000000000000000D4 -:10BC700000000000000000000000000000000000C4 -:10BC800000000000000000000000000000000000B4 -:10BC900000000000000000000000000000000000A4 -:10BCA0000000000000000000000000000000000094 -:10BCB0000000000000000000000000000000000084 -:10BCC0000000000000000000000000000000000074 -:10BCD0000000000000000000000000000000000064 -:10BCE0000000000000000000000000000000000054 -:10BCF0000000000000000000000000000000000044 -:10BD00000000000000000000000000000000000033 -:10BD10000000000000000000000000000000000023 -:10BD20000000000000000000000000000000000013 -:10BD30000000000000000000000000000000000003 -:10BD400000000000000000000000000000000000F3 -:10BD500000000000000000000000000000000000E3 -:10BD600000000000000000000000000000000000D3 -:10BD700000000000000000000000000000000000C3 -:10BD800000000000000000000000000000000000B3 -:10BD900000000000000000000000000000000000A3 -:10BDA0000000000000000000000000000000000093 -:10BDB0000000000000000000000000000000000083 -:10BDC0000000000000000000000000000000000073 -:10BDD0000000000000000000000000000000000063 -:10BDE0000000000000000000000000000000000053 -:10BDF0000000000000000000000000000000000043 -:10BE00000000000000000000000000000000000032 -:10BE10000000000000000000000000000000000022 -:10BE20000000000000000000000000000000000012 -:10BE30000000000000000000000000000000000002 -:10BE400000000000000000000000000000000000F2 -:10BE500000000000000000000000000000000000E2 -:10BE600000000000000000000000000000000000D2 -:10BE700000000000000000000000000000000000C2 -:10BE800000000000000000000000000000000000B2 -:10BE900000000000000000000000000000000000A2 -:10BEA0000000000000000000000000000000000092 -:10BEB0000000000000000000000000000000000082 -:10BEC0000000000000000000000000000000000072 -:10BED0000000000000000000000000000000000062 -:10BEE0000000000000000000000000000000000052 -:10BEF0000000000000000000000000000000000042 -:10BF00000000000000000000000000000000000031 -:10BF10000000000000000000000000000000000021 -:10BF20000000000000000000000000000000000011 -:10BF30000000000000000000000000000000000001 -:10BF400000000000000000000000000000000000F1 -:10BF500000000000000000000000000000000000E1 -:10BF600000000000000000000000000000000000D1 -:10BF700000000000000000000000000000000000C1 -:10BF800000000000000000000000000000000000B1 -:10BF900000000000000000000000000000000000A1 -:10BFA0000000000000000000000000000000000091 -:10BFB0000000000000000000000000000000000081 -:10BFC0000000000000000000000000000000000071 -:10BFD0000000000000000000000000000000000061 -:10BFE0000000000000000000000000000000000051 -:10BFF0000000000000000000000000000000000041 -:10C000000000000000000000000000000000000030 -:10C010000000000000000000000000000000000020 -:10C020000000000000000000000000000000000010 -:10C030000000000000000000000000000000000000 -:10C0400000000000000000000000000000000000F0 -:10C0500000000000000000000000000000000000E0 -:10C0600000000000000000000000000000000000D0 -:10C0700000000000000000000000000000000000C0 -:10C0800000000000000000000000000000000000B0 -:10C0900000000000000000000000000000000000A0 -:10C0A0000000000000000000000000000000000090 -:10C0B0000000000000000000000000000000000080 -:10C0C0000000000000000000000000000000000070 -:10C0D0000000000000000000000000000000000060 -:10C0E0000000000000000000000000000000000050 -:10C0F0000000000000000000000000000000000040 -:10C10000000000000000000000000000000000002F -:10C11000000000000000000000000000000000001F -:10C12000000000000000000000000000000000000F -:10C1300000000000000000000000000000000000FF -:10C1400000000000000000000000000000000000EF -:10C1500000000000000000000000000000000000DF -:10C1600000000000000000000000000000000000CF -:10C1700000000000000000000000000000000000BF -:10C1800000000000000000000000000000000000AF -:10C19000000000000000000000000000000000009F -:10C1A000000000000000000000000000000000008F -:10C1B000000000000000000000000000000000007F -:10C1C000000000000000000000000000000000006F -:10C1D000000000000000000000000000000000005F -:10C1E000000000000000000000000000000000004F -:10C1F000000000000000000000000000000000003F -:10C20000000000000000000000000000000000002E -:10C21000000000000000000000000000000000001E -:10C22000000000000000000000000000000000000E -:10C2300000000000000000000000000000000000FE -:10C2400000000000000000000000000000000000EE -:10C2500000000000000000000000000000000000DE -:10C2600000000000000000000000000000000000CE -:10C2700000000000000000000000000000000000BE -:10C2800000000000000000000000000000000000AE -:10C29000000000000000000000000000000000009E -:10C2A000000000000000000000000000000000008E -:10C2B000000000000000000000000000000000007E -:10C2C000000000000000000000000000000000006E -:10C2D000000000000000000000000000000000005E -:10C2E000000000000000000000000000000000004E -:10C2F000000000000000000000000000000000003E -:10C30000000000000000000000000000000000002D -:10C31000000000000000000000000000000000001D -:10C32000000000000000000000000000000000000D -:10C3300000000000000000000000000000000000FD -:10C3400000000000000000000000000000000000ED -:10C3500000000000000000000000000000000000DD -:10C3600000000000000000000000000000000000CD -:10C3700000000000000000000000000000000000BD -:10C3800000000000000000000000000000000000AD -:10C39000000000000000000000000000000000009D -:10C3A000000000000000000000000000000000008D -:10C3B000000000000000000000000000000000007D -:10C3C000000000000000000000000000000000006D -:10C3D000000000000000000000000000000000005D -:10C3E000000000000000000000000000000000004D -:10C3F000000000000000000000000000000000003D -:10C40000000000000000000000000000000000002C -:10C41000000000000000000000000000000000001C -:10C42000000000000000000000000000000000000C -:10C4300000000000000000000000000000000000FC -:10C4400000000000000000000000000000000000EC -:10C4500000000000000000000000000000000000DC -:10C4600000000000000000000000000000000000CC -:10C4700000000000000000000000000000000000BC -:10C4800000000000000000000000000000000000AC -:10C49000000000000000000000000000000000009C -:10C4A000000000000000000000000000000000008C -:10C4B000000000000000000000000000000000007C -:10C4C000000000000000000000000000000000006C -:10C4D000000000000000000000000000000000005C -:10C4E000000000000000000000000000000000004C -:10C4F000000000000000000000000000000000003C -:10C50000000000000000000000000000000000002B -:10C51000000000000000000000000000000000001B -:10C52000000000000000000000000000000000000B -:10C5300000000000000000000000000000000000FB -:10C5400000000000000000000000000000000000EB -:10C5500000000000000000000000000000000000DB -:10C5600000000000000000000000000000000000CB -:10C5700000000000000000000000000000000000BB -:10C5800000000000000000000000000000000000AB -:10C59000000000000000000000000000000000009B -:10C5A000000000000000000000000000000000008B -:10C5B000000000000000000000000000000000007B -:10C5C000000000000000000000000000000000006B -:10C5D000000000000000000000000000000000005B -:10C5E000000000000000000000000000000000004B -:10C5F000000000000000000000000000000000003B -:10C60000000000000000000000000000000000002A -:10C61000000000000000000000000000000000001A -:10C62000000000000000000000000000000000000A -:10C6300000000000000000000000000000000000FA -:10C6400000000000000000000000000000000000EA -:10C6500000000000000000000000000000000000DA -:10C6600000000000000000000000000000000000CA -:10C6700000000000000000000000000000000000BA -:10C6800000000000000000000000000000000000AA -:10C69000000000000000000000000000000000009A -:10C6A000000000000000000000000000000000008A -:10C6B000000000000000000000000000000000007A -:10C6C000000000000000000000000000000000006A -:10C6D000000000000000000000000000000000005A -:10C6E000000000000000000000000000000000004A -:10C6F000000000000000000000000000000000003A -:10C700000000000000000000000000000000000029 -:10C710000000000000000000000000000000000019 -:10C720000000000000000000000000000000000009 -:10C7300000000000000000000000000000000000F9 -:10C7400000000000000000000000000000000000E9 -:10C7500000000000000000000000000000000000D9 -:10C7600000000000000000000000000000000000C9 -:10C7700000000000000000000000000000000000B9 -:10C7800000000000000000000000000000000000A9 -:10C790000000000000000000000000000000000099 -:10C7A0000000000000000000000000000000000089 -:10C7B0000000000000000000000000000000000079 -:10C7C0000000000000000000000000000000000069 -:10C7D0000000000000000000000000000000000059 -:10C7E0000000000000000000000000000000000049 -:10C7F0000000000000000000000000000000000039 -:10C800000000000000000000000000000000000028 -:10C810000000000000000000000000000000000018 -:10C820000000000000000000000000000000000008 -:10C8300000000000000000000000000000000000F8 -:10C8400000000000000000000000000000000000E8 -:10C8500000000000000000000000000000000000D8 -:10C8600000000000000000000000000000000000C8 -:10C8700000000000000000000000000000000000B8 -:10C8800000000000000000000000000000000000A8 -:10C890000000000000000000000000000000000098 -:10C8A0000000000000000000000000000000000088 -:10C8B0000000000000000000000000000000000078 -:10C8C0000000000000000000000000000000000068 -:10C8D0000000000000000000000000000000000058 -:10C8E0000000000000000000000000000000000048 -:10C8F0000000000000000000000000000000000038 -:10C900000000000000000000000000000000000027 -:10C910000000000000000000000000000000000017 -:10C920000000000000000000000000000000000007 -:10C9300000000000000000000000000000000000F7 -:10C9400000000000000000000000000000000000E7 -:10C9500000000000000000000000000000000000D7 -:10C9600000000000000000000000000000000000C7 -:10C9700000000000000000000000000000000000B7 -:10C9800000000000000000000000000000000000A7 -:10C990000000000000000000000000000000000097 -:10C9A0000000000000000000000000000000000087 -:10C9B0000000000000000000000000000000000077 -:10C9C0000000000000000000000000000000000067 -:10C9D0000000000000000000000000000000000057 -:10C9E0000000000000000000000000000000000047 -:10C9F0000000000000000000000000000000000037 -:10CA00000000000000000000000000000000000026 -:10CA10000000000000000000000000000000000016 -:10CA20000000000000000000000000000000000006 -:10CA300000000000000000000000000000000000F6 -:10CA400000000000000000000000000000000000E6 -:10CA500000000000000000000000000000000000D6 -:10CA600000000000000000000000000000000000C6 -:10CA700000000000000000000000000000000000B6 -:10CA800000000000000000000000000000000000A6 -:10CA90000000000000000000000000000000000096 -:10CAA0000000000000000000000000000000000086 -:10CAB0000000000000000000000000000000000076 -:10CAC0000000000000000000000000000000000066 -:10CAD0000000000000000000000000000000000056 -:10CAE0000000000000000000000000000000000046 -:10CAF0000000000000000000000000000000000036 -:10CB00000000000000000000000000000000000025 -:10CB10000000000000000000000000000000000015 -:10CB20000000000000000000000000000000000005 -:10CB300000000000000000000000000000000000F5 -:10CB400000000000000000000000000000000000E5 -:10CB500000000000000000000000000000000000D5 -:10CB600000000000000000000000000000000000C5 -:10CB700000000000000000000000000000000000B5 -:10CB800000000000000000000000000000000000A5 -:10CB90000000000000000000000000000000000095 -:10CBA0000000000000000000000000000000000085 -:10CBB0000000000000000000000000000000000075 -:10CBC0000000000000000000000000000000000065 -:10CBD0000000000000000000000000000000000055 -:10CBE0000000000000000000000000000000000045 -:10CBF0000000000000000000000000000000000035 -:10CC00000000000000000000000000000000000024 -:10CC10000000000000000000000000000000000014 -:10CC20000000000000000000000000000000000004 -:10CC300000000000000000000000000000000000F4 -:10CC400000000000000000000000000000000000E4 -:10CC500000000000000000000000000000000000D4 -:10CC600000000000000000000000000000000000C4 -:10CC700000000000000000000000000000000000B4 -:10CC800000000000000000000000000000000000A4 -:10CC90000000000000000000000000000000000094 -:10CCA0000000000000000000000000000000000084 -:10CCB0000000000000000000000000000000000074 -:10CCC0000000000000000000000000000000000064 -:10CCD0000000000000000000000000000000000054 -:10CCE0000000000000000000000000000000000044 -:10CCF0000000000000000000000000000000000034 -:10CD00000000000000000000000000000000000023 -:10CD10000000000000000000000000000000000013 -:10CD20000000000000000000000000000000000003 -:10CD300000000000000000000000000000000000F3 -:10CD400000000000000000000000000000000000E3 -:10CD500000000000000000000000000000000000D3 -:10CD600000000000000000000000000000000000C3 -:10CD700000000000000000000000000000000000B3 -:10CD800000000000000000000000000000000000A3 -:10CD90000000000000000000000000000000000093 -:10CDA0000000000000000000000000000000000083 -:10CDB0000000000000000000000000000000000073 -:10CDC0000000000000000000000000000000000063 -:10CDD0000000000000000000000000000000000053 -:10CDE0000000000000000000000000000000000043 -:10CDF0000000000000000000000000000000000033 -:10CE00000000000000000000000000000000000022 -:10CE10000000000000000000000000000000000012 -:10CE20000000000000000000000000000000000002 -:10CE300000000000000000000000000000000000F2 -:10CE400000000000000000000000000000000000E2 -:10CE500000000000000000000000000000000000D2 -:10CE600000000000000000000000000000000000C2 -:10CE700000000000000000000000000000000000B2 -:10CE800000000000000000000000000000000000A2 -:10CE90000000000000000000000000000000000092 -:10CEA0000000000000000000000000000000000082 -:10CEB0000000000000000000000000000000000072 -:10CEC0000000000000000000000000000000000062 -:10CED0000000000000000000000000000000000052 -:10CEE0000000000000000000000000000000000042 -:10CEF0000000000000000000000000000000000032 -:10CF00000000000000000000000000000000000021 -:10CF10000000000000000000000000000000000011 -:10CF20000000000000000000000000000000000001 -:10CF300000000000000000000000000000000000F1 -:10CF400000000000000000000000000000000000E1 -:10CF500000000000000000000000000000000000D1 -:10CF600000000000000000000000000000000000C1 -:10CF700000000000000000000000000000000000B1 -:10CF800000000000000000000000000000000000A1 -:10CF90000000000000000000000000000000000091 -:10CFA0000000000000000000000000000000000081 -:10CFB0000000000000000000000000000000000071 -:10CFC0000000000000000000000000000000000061 -:10CFD0000000000000000000000000000000000051 -:10CFE0000000000000000000000000000000000041 -:10CFF0000000000000000000000000000000000031 -:10D000000000000000000000000000000000000020 -:10D010000000000000000000000000000000000010 -:10D020000000000000000000000000000000000000 -:10D0300000000000000000000000000000000000F0 -:10D0400000000000000000000000000000000000E0 -:10D0500000000000000000000000000000000000D0 -:10D0600000000000000000000000000000000000C0 -:10D0700000000000000000000000000000000000B0 -:10D0800000000000000000000000000000000000A0 -:10D090000000000000000000000000000000000090 -:10D0A0000000000000000000000000000000000080 -:10D0B0000000000000000000000000000000000070 -:10D0C0000000000000000000000000000000000060 -:10D0D0000000000000000000000000000000000050 -:10D0E0000000000000000000000000000000000040 -:10D0F0000000000000000000000000000000000030 -:10D10000000000000000000000000000000000001F -:10D11000000000000000000000000000000000000F -:10D1200000000000000000000000000000000000FF -:10D1300000000000000000000000000000000000EF -:10D1400000000000000000000000000000000000DF -:10D1500000000000000000000000000000000000CF -:10D1600000000000000000000000000000000000BF -:10D1700000000000000000000000000000000000AF -:10D18000000000000000000000000000000000009F -:10D19000000000000000000000000000000000008F -:10D1A000000000000000000000000000000000007F -:10D1B000000000000000000000000000000000006F -:10D1C000000000000000000000000000000000005F -:10D1D000000000000000000000000000000000004F -:10D1E000000000000000000000000000000000003F -:10D1F000000000000000000000000000000000002F -:10D20000000000000000000000000000000000001E -:10D21000000000000000000000000000000000000E -:10D2200000000000000000000000000000000000FE -:10D2300000000000000000000000000000000000EE -:10D2400000000000000000000000000000000000DE -:10D2500000000000000000000000000000000000CE -:10D2600000000000000000000000000000000000BE -:10D2700000000000000000000000000000000000AE -:10D28000000000000000000000000000000000009E -:10D29000000000000000000000000000000000008E -:10D2A000000000000000000000000000000000007E -:10D2B000000000000000000000000000000000006E -:10D2C000000000000000000000000000000000005E -:10D2D000000000000000000000000000000000004E -:10D2E000000000000000000000000000000000003E -:10D2F000000000000000000000000000000000002E -:10D30000000000000000000000000000000000001D -:10D31000000000000000000000000000000000000D -:10D3200000000000000000000000000000000000FD -:10D3300000000000000000000000000000000000ED -:10D3400000000000000000000000000000000000DD -:10D3500000000000000000000000000000000000CD -:10D3600000000000000000000000000000000000BD -:10D3700000000000000000000000000000000000AD -:10D38000000000000000000000000000000000009D -:10D39000000000000000000000000000000000008D -:10D3A000000000000000000000000000000000007D -:10D3B000000000000000000000000000000000006D -:10D3C000000000000000000000000000000000005D -:10D3D000000000000000000000000000000000004D -:10D3E000000000000000000000000000000000003D -:10D3F000000000000000000000000000000000002D -:10D40000000000000000000000000000000000001C -:10D41000000000000000000000000000000000000C -:10D4200000000000000000000000000000000000FC -:10D4300000000000000000000000000000000000EC -:10D4400000000000000000000000000000000000DC -:10D4500000000000000000000000000000000000CC -:10D4600000000000000000000000000000000000BC -:10D4700000000000000000000000000000000000AC -:10D48000000000000000000000000000000000009C -:10D49000000000000000000000000000000000008C -:10D4A000000000000000000000000000000000007C -:10D4B000000000000000000000000000000000006C -:10D4C000000000000000000000000000000000005C -:10D4D000000000000000000000000000000000004C -:10D4E000000000000000000000000000000000003C -:10D4F000000000000000000000000000000000002C -:10D50000000000000000000000000000000000001B -:10D51000000000000000000000000000000000000B -:10D5200000000000000000000000000000000000FB -:10D5300000000000000000000000000000000000EB -:10D5400000000000000000000000000000000000DB -:10D5500000000000000000000000000000000000CB -:10D5600000000000000000000000000000000000BB -:10D5700000000000000000000000000000000000AB -:10D58000000000000000000000000000000000009B -:10D59000000000000000000000000000000000008B -:10D5A000000000000000000000000000000000007B -:10D5B000000000000000000000000000000000006B -:10D5C000000000000000000000000000000000005B -:10D5D000000000000000000000000000000000004B -:10D5E000000000000000000000000000000000003B -:10D5F000000000000000000000000000000000002B -:10D60000000000000000000000000000000000001A -:10D61000000000000000000000000000000000000A -:10D6200000000000000000000000000000000000FA -:10D6300000000000000000000000000000000000EA -:10D6400000000000000000000000000000000000DA -:10D6500000000000000000000000000000000000CA -:10D6600000000000000000000000000000000000BA -:10D6700000000000000000000000000000000000AA -:10D68000000000000000000000000000000000009A -:10D69000000000000000000000000000000000008A -:10D6A000000000000000000000000000000000007A -:10D6B000000000000000000000000000000000006A -:10D6C000000000000000000000000000000000005A -:10D6D000000000000000000000000000000000004A -:10D6E000000000000000000000000000000000003A -:10D6F000000000000000000000000000000000002A -:10D700000000000000000000000000000000000019 -:10D710000000000000000000000000000000000009 -:10D7200000000000000000000000000000000000F9 -:10D7300000000000000000000000000000000000E9 -:10D7400000000000000000000000000000000000D9 -:10D7500000000000000000000000000000000000C9 -:10D7600000000000000000000000000000000000B9 -:10D7700000000000000000000000000000000000A9 -:10D780000000000000000000000000000000000099 -:10D790000000000000000000000000000000000089 -:10D7A0000000000000000000000000000000000079 -:10D7B0000000000000000000000000000000000069 -:10D7C0000000000000000000000000000000000059 -:10D7D0000000000000000000000000000000000049 -:10D7E0000000000000000000000000000000000039 -:10D7F0000000000000000000000000000000000029 -:10D800000000000000000000000000000000000018 -:10D810000000000000000000000000000000000008 -:10D8200000000000000000000000000000000000F8 -:10D8300000000000000000000000000000000000E8 -:10D8400000000000000000000000000000000000D8 -:10D8500000000000000000000000000000000000C8 -:10D8600000000000000000000000000000000000B8 -:10D8700000000000000000000000000000000000A8 -:10D880000000000000000000000000000000000098 -:10D890000000000000000000000000000000000088 -:10D8A0000000000000000000000000000000000078 -:10D8B0000000000000000000000000000000000068 -:10D8C0000000000000000000000000000000000058 -:10D8D0000000000000000000000000000000000048 -:10D8E0000000000000000000000000000000000038 -:10D8F0000000000000000000000000000000000028 -:10D900000000000000000000000000000000000017 -:10D910000000000000000000000000000000000007 -:10D9200000000000000000000000000000000000F7 -:10D9300000000000000000000000000000000000E7 -:10D9400000000000000000000000000000000000D7 -:10D9500000000000000000000000000000000000C7 -:10D9600000000000000000000000000000000000B7 -:10D9700000000000000000000000000000000000A7 -:10D980000000000000000000000000000000000097 -:10D990000000000000000000000000000000000087 -:10D9A0000000000000000000000000000000000077 -:10D9B0000000000000000000000000000000000067 -:10D9C0000000000000000000000000000000000057 -:10D9D0000000000000000000000000000000000047 -:10D9E0000000000000000000000000000000000037 -:10D9F0000000000000000000000000000000000027 -:10DA00000000000000000000000000000000000016 -:10DA10000000000000000000000000000000000006 -:10DA200000000000000000000000000000000000F6 -:10DA300000000000000000000000000000000000E6 -:10DA400000000000000000000000000000000000D6 -:10DA500000000000000000000000000000000000C6 -:10DA600000000000000000000000000000000000B6 -:10DA700000000000000000000000000000000000A6 -:10DA80000000000000000000000000000000000096 -:10DA90000000000000000000000000000000000086 -:10DAA0000000000000000000000000000000000076 -:10DAB0000000000000000000000000000000000066 -:10DAC0000000000000000000000000000000000056 -:10DAD0000000000000000000000000000000000046 -:10DAE0000000000000000000000000000000000036 -:10DAF0000000000000000000000000000000000026 -:10DB00000000000000000000000000000000000015 -:10DB10000000000000000000000000000000000005 -:10DB200000000000000000000000000000000000F5 -:10DB300000000000000000000000000000000000E5 -:10DB400000000000000000000000000000000000D5 -:10DB500000000000000000000000000000000000C5 -:10DB600000000000000000000000000000000000B5 -:10DB700000000000000000000000000000000000A5 -:10DB80000000000000000000000000000000000095 -:10DB90000000000000000000000000000000000085 -:10DBA0000000000000000000000000000000000075 -:10DBB0000000000000000000000000000000000065 -:10DBC0000000000000000000000000000000000055 -:10DBD0000000000000000000000000000000000045 -:10DBE0000000000000000000000000000000000035 -:10DBF0000000000000000000000000000000000025 -:10DC00000000000000000000000000000000000014 -:10DC10000000000000000000000000000000000004 -:10DC200000000000000000000000000000000000F4 -:10DC300000000000000000000000000000000000E4 -:10DC400000000000000000000000000000000000D4 -:10DC500000000000000000000000000000000000C4 -:10DC600000000000000000000000000000000000B4 -:10DC700000000000000000000000000000000000A4 -:10DC80000000000000000000000000000000000094 -:10DC90000000000000000000000000000000000084 -:10DCA0000000000000000000000000000000000074 -:10DCB0000000000000000000000000000000000064 -:10DCC0000000000000000000000000000000000054 -:10DCD0000000000000000000000000000000000044 -:10DCE0000000000000000000000000000000000034 -:10DCF0000000000000000000000000000000000024 -:10DD00000000000000000000000000000000000013 -:10DD10000000000000000000000000000000000003 -:10DD200000000000000000000000000000000000F3 -:10DD300000000000000000000000000000000000E3 -:10DD400000000000000000000000000000000000D3 -:10DD500000000000000000000000000000000000C3 -:10DD600000000000000000000000000000000000B3 -:10DD700000000000000000000000000000000000A3 -:10DD80000000000000000000000000000000000093 -:10DD90000000000000000000000000000000000083 -:10DDA0000000000000000000000000000000000073 -:10DDB0000000000000000000000000000000000063 -:10DDC0000000000000000000000000000000000053 -:10DDD0000000000000000000000000000000000043 -:10DDE0000000000000000000000000000000000033 -:10DDF0000000000000000000000000000000000023 -:10DE00000000000000000000000000000000000012 -:10DE10000000000000000000000000000000000002 -:10DE200000000000000000000000000000000000F2 -:10DE300000000000000000000000000000000000E2 -:10DE400000000000000000000000000000000000D2 -:10DE500000000000000000000000000000000000C2 -:10DE600000000000000000000000000000000000B2 -:10DE700000000000000000000000000000000000A2 -:10DE80000000000000000000000000000000000092 -:10DE90000000000000000000000000000000000082 -:10DEA0000000000000000000000000000000000072 -:10DEB0000000000000000000000000000000000062 -:10DEC0000000000000000000000000000000000052 -:10DED0000000000000000000000000000000000042 -:10DEE0000000000000000000000000000000000032 -:10DEF0000000000000000000000000000000000022 -:10DF00000000000000000000000000000000000011 -:10DF10000000000000000000000000000000000001 -:10DF200000000000000000000000000000000000F1 -:10DF300000000000000000000000000000000000E1 -:10DF400000000000000000000000000000000000D1 -:10DF500000000000000000000000000000000000C1 -:10DF600000000000000000000000000000000000B1 -:10DF700000000000000000000000000000000000A1 -:10DF80000000000000000000000000000000000091 -:10DF90000000000000000000000000000000000081 -:10DFA0000000000000000000000000000000000071 -:10DFB0000000000000000000000000000000000061 -:10DFC0000000000000000000000000000000000051 -:10DFD0000000000000000000000000000000000041 -:10DFE0000000000000000000000000000000000031 -:10DFF0000000000000000000000000000000000021 -:10E000000000000000000000000000000000000010 -:10E010000000000000000000000000000000000000 -:10E0200000000000000000000000000000000000F0 -:10E0300000000000000000000000000000000000E0 -:10E0400000000000000000000000000000000000D0 -:10E0500000000000000000000000000000000000C0 -:10E0600000000000000000000000000000000000B0 -:10E0700000000000000000000000000000000000A0 -:10E080000000000000000000000000000000000090 -:10E090000000000000000000000000000000000080 -:10E0A0000000000000000000000000000000000070 -:10E0B0000000000000000000000000000000000060 -:10E0C0000000000000000000000000000000000050 -:10E0D0000000000000000000000000000000000040 -:10E0E0000000000000000000000000000000000030 -:10E0F0000000000000000000000000000000000020 -:10E10000000000000000000000000000000000000F -:10E1100000000000000000000000000000000000FF -:10E1200000000000000000000000000000000000EF -:10E1300000000000000000000000000000000000DF -:10E1400000000000000000000000000000000000CF -:10E1500000000000000000000000000000000000BF -:10E1600000000000000000000000000000000000AF -:10E17000000000000000000000000000000000009F -:10E18000000000000000000000000000000000008F -:10E19000000000000000000000000000000000007F -:10E1A000000000000000000000000000000000006F -:10E1B000000000000000000000000000000000005F -:10E1C000000000000000000000000000000000004F -:10E1D000000000000000000000000000000000003F -:10E1E000000000000000000000000000000000002F -:10E1F000000000000000000000000000000000809F -:10E20000000000000000000000000000000000000E -:10E2100000000000000000000000000000000000FE -:10E220000000000A000000000000000000000000E4 -:10E2300010000003000000000000000D0000000DB1 -:10E240003C020801244296603C0308012463989C28 -:10E25000AC4000000043202B1480FFFD244200044A -:10E260003C1D080037BD9FFC03A0F0213C100800B6 -:10E27000261032103C1C0801279C96600E0012BE2E -:10E28000000000000000000D3C02800030A5FFFFF0 -:10E2900030C600FF344301803C0880008D0901B87E -:10E2A0000520FFFE00000000AC6400002404000212 -:10E2B000A4650008A066000AA064000BAC67001803 -:10E2C0003C03100003E00008AD0301B83C0560000A -:10E2D0008CA24FF80440FFFE00000000ACA44FC029 -:10E2E0003C0310003C040200ACA44FC403E000084F -:10E2F000ACA34FF89486000C00A050212488001491 -:10E3000000062B0200051080004448210109182B4B -:10E310001060001100000000910300002C6400094F -:10E320005080000991190001000360803C0D080134 -:10E3300025AD92F8018D58218D67000000E000089E -:10E340000000000091190001011940210109302B42 -:10E3500054C0FFF29103000003E000080000102108 -:10E360000A000CCC25080001910F0001240E000AC0 -:10E3700015EE00400128C8232F38000A1700003D81 -:10E38000250D00028D580000250F0006370E0100F4 -:10E39000AD4E0000910C000291AB000191A400026F -:10E3A00091A60003000C2E00000B3C0000A71025D6 -:10E3B00000041A000043C8250326C025AD580004F8 -:10E3C000910E000691ED000191E7000291E5000336 -:10E3D000000E5E00000D6400016C30250007220075 -:10E3E00000C41025004518252508000A0A000CCC99 -:10E3F000AD430008910F000125040002240800022B -:10E4000055E80001012020210A000CCC00804021A9 -:10E41000910C0001240B0003158B00160000000076 -:10E420008D580000910E000225080003370D0008EA -:10E43000A14E00100A000CCCAD4D00009119000156 -:10E44000240F0004172F000B0000000091070002AA -:10E45000910400038D43000000072A0000A410254A -:10E460003466000425080004AD42000C0A000CCC00 -:10E47000AD46000003E000082402000127BDFFE8CC -:10E48000AFBF0014AFB000100E00167F00808021D7 -:10E490003C0480083485008090A600052403FFFE1C -:10E4A0000200202100C310248FBF00148FB0001081 -:10E4B000A0A200050A00168927BD001827BDFFE8A5 -:10E4C000AFB00010AFBF00140E000FD40080802149 -:10E4D0003C06800834C5008090A40000240200504F -:10E4E000308300FF106200073C09800002002021F9 -:10E4F0008FBF00148FB00010AD2001800A00108F74 -:10E5000027BD0018240801003C07800002002021DC -:10E510008FBF00148FB00010ACE801800A00108F8C -:10E5200027BD001827BDFF783C058008AFBE0080DE -:10E53000AFB7007CAFB3006CAFB10064AFBF008475 -:10E54000AFB60078AFB50074AFB40070AFB200687A -:10E55000AFB0006034A600803C0580008CB201287A -:10E5600090C400098CA701043C020001309100FF17 -:10E5700000E218240000B8210000F021106000071C -:10E58000000098213C0908008D2931F02413000176 -:10E59000252800013C010800AC2831F0ACA0008423 -:10E5A00090CC0005000C5827316A0001154000721C -:10E5B000AFA0005090CD00002406002031A400FF41 -:10E5C00010860018240E0050108E009300000000EA -:10E5D0003C1008008E1000DC260F00013C010800F2 -:10E5E000AC2F00DC0E0016F80000000000401821DF -:10E5F0008FBF00848FBE00808FB7007C8FB60078FD -:10E600008FB500748FB400708FB3006C8FB2006848 -:10E610008FB100648FB000600060102103E000083B -:10E6200027BD00880000000D3C1F8000AFA0003017 -:10E6300097E501168FE201043C04002030B9FFFF8A -:10E64000004438240007182B00033140AFA60030E7 -:10E650008FF5010437F80C003C1600400338802188 -:10E6600002B6A02434C40040128000479215000D69 -:10E6700032A800201500000234860080008030217E -:10E6800014C0009FAFA600303C0D800835A6008066 -:10E6900090CC0008318B0040516000063C06800899 -:10E6A000240E0004122E00A8240F0012122F003294 -:10E6B0003C06800834C401003C0280009447011AE3 -:10E6C0009619000E909F00088E18000830E3FFFF97 -:10E6D00003F9B00432B40004AFB6005CAFA3005835 -:10E6E0008E1600041280002EAFB8005434C3008090 -:10E6F000906800083105004014A0002500000000CB -:10E700008C70005002D090230640000500000000ED -:10E710008C71003402D1A82306A201678EE20008A2 -:10E72000126000063C1280003C1508008EB531F4E2 -:10E7300026B600013C010800AC3631F4AE4000447E -:10E74000240300018FBF00848FBE00808FB7007C40 -:10E750008FB600788FB500748FB400708FB3006CE3 -:10E760008FB200688FB100648FB00060006010212C -:10E7700003E0000827BD00880E000D2800002021BE -:10E780000A000D75004018210A000D9500C02021D7 -:10E790000E00174802C020211440FFE100000000D5 -:10E7A0003C0B8008356400808C8A003402CA482300 -:10E7B0000520001D000000003C1E08008FDE310017 -:10E7C00027D700013C010800AC3731001260000679 -:10E7D000024020213C1408008E9431F42690000160 -:10E7E0003C010800AC3031F40E00167F3C1E80085E -:10E7F00037CD008091B700250240202136EE00047D -:10E800000E001689A1AE00250E000CAC024020219E -:10E810000A000DCA240300013C17080126F797607F -:10E820000A000D843C1F80008C86003002C66023E5 -:10E830001980000C2419000C908F004F3C14080024 -:10E840008E94310032B500FC35ED0001268E0001BA -:10E850003C010800AC2E3100A08D004FAFA0005845 -:10E860002419000CAFB900308C9800300316A02397 -:10E870001A80010B8FA300580074F82A17E0FFD309 -:10E88000000000001074002A8FA5005802D4B021A7 -:10E8900000B410233044FFFFAFA4005832A8000298 -:10E8A0001100002E32AB00103C15800836B00080FD -:10E8B0009216000832D30040526000FB8EE200083E -:10E8C0000E00167F02402021240A0018A20A000927 -:10E8D000921100052409FFFE024020210229902404 -:10E8E0000E001689A2120005240400390000282118 -:10E8F0000E001723240600180A000DCA2403000185 -:10E9000092FE000C3C0A800835490080001EBB00C6 -:10E910008D27003836F10081024020213225F08118 -:10E920000E000C9B30C600FF0A000DC10000000065 -:10E930003AA7000130E300011460FFA402D4B02123 -:10E940000A000E1D00000000024020210E00176585 -:10E95000020028210A000D75004018211160FF7087 -:10E960003C0F80083C0D800835EE00808DC40038D7 -:10E970008FA300548DA60004006660231D80FF68ED -:10E98000000000000064C02307020001AFA400548F -:10E990003C1F08008FFF31E433F9000113200015FC -:10E9A0008FAC00583C07800094E3011A10600012FD -:10E9B0003C0680080E002192024020213C03080101 -:10E9C00090639791306400021480014500000000BC -:10E9D000306C0004118000078FAC0058306600FBDB -:10E9E0003C010801A026979132B500FCAFA0005869 -:10E9F0008FAC00583C06800834D30080AFB40018B8 -:10EA0000AFB60010AFAC00143C088000950B01209D -:10EA10008E6F0030966A005C8FA3005C8FBF003061 -:10EA20003169FFFF3144FFFF8FAE005401341021E4 -:10EA3000350540000064382B0045C82103E7C02598 -:10EA4000AFB90020AFAF0028AFB80030AFAF00249F -:10EA5000AFA0002CAFAE0034926D000831B40008B6 -:10EA6000168000BB020020218EE200040040F8095D -:10EA700027A400108FAF003031F300025660000170 -:10EA800032B500FE3C048008349F008093F90008F2 -:10EA900033380040530000138FA400248C850004F9 -:10EAA0008FA7005410A700D52404001432B0000131 -:10EAB0001200000C8FA400242414000C1234011A3C -:10EAC0002A2D000D11A001022413000E240E000AAD -:10EAD000522E0001241E00088FAF002425E40001FF -:10EAE000AFA400248FAA00143C0B80083565008079 -:10EAF000008A48218CB10030ACA9003090A4004EAF -:10EB00008CA700303408FFFC0088180400E3F821CB -:10EB1000ACBF00348FA600308FB900548FB8005CB2 -:10EB200030C200081040000B033898218CAC002044 -:10EB3000119300D330C600FF92EE000C8FA7003473 -:10EB400002402021000E6B0035B400800E000C9BAB -:10EB50003285F0803C028008345000808E0F0030F7 -:10EB600001F1302318C00097264800803C070800B8 -:10EB70008CE731E42404FF80010418243118007F5D -:10EB80003C1F80003C19800430F10001AFE300908D -:10EB900012200006031928213C0308019063979175 -:10EBA00030690008152000C6306A00F73C10800864 -:10EBB00036040080908C004F318B000115600042BC -:10EBC000000000003C0608008CC6319830CE0010D2 -:10EBD00051C0004230F9000190AF006B55E0003F9A -:10EBE00030F9000124180001A0B8006B3C1180002E -:10EBF0009622007A24470064A48700123C0D800806 -:10EC000035A5008090B40008329000401600000442 -:10EC10003C03800832AE000115C0008B00000000EC -:10EC2000346400808C86002010D3000A3463010015 -:10EC30008C67000002C7782319E000978FBF00544B -:10EC4000AC93002024130001AC760000AFB3005059 -:10EC5000AC7F000417C0004E000000008FA90050D8 -:10EC60001520000B000000003C0308019063979101 -:10EC7000306A00011140002E8FAB0058306400FE56 -:10EC80003C010801A02497910A000D75000018218D -:10EC90000E000CAC024020210A000F1300000000FF -:10ECA0000A000E200000A0210040F80924040017EB -:10ECB0000A000DCA240300010040F80924040016CC -:10ECC0000A000DCA240300019094004F240DFFFE9A -:10ECD000028D2824A085004F30F900011320000682 -:10ECE0003C0480083C03080190639791307F00103A -:10ECF00017E00051306800EF34900080240A0001D2 -:10ED0000024020210E00167FA60A00129203002561 -:10ED100024090001AFA90050346200010240202103 -:10ED20000E001689A20200250A000EF93C0D80088B -:10ED30001160FE83000018218FA5003030AC000464 -:10ED40001180FE2C8FBF00840A000DCB240300012C -:10ED500027A500380E000CB6AFA000385440FF4382 -:10ED60008EE200048FB40038329001005200FF3F61 -:10ED70008EE200048FA3003C8E6E0058006E682364 -:10ED800005A3FF39AE6300580A000E948EE200041A -:10ED90000E00167F024020213C038008346800806A -:10EDA000024020210E001689A11E000903C0302157 -:10EDB000240400370E001723000028210A000F1139 -:10EDC0008FA900508FAB00185960FF8D3C0D800853 -:10EDD0000E00167F02402021920C00252405000120 -:10EDE000AFA5005035820004024020210E00168994 -:10EDF000A20200250A000EF93C0D800812240059D9 -:10EE00002A2300151060004D240900162408000C68 -:10EE10005628FF2732B000013C0A8008914C001BA5 -:10EE20002406FFBD241E000E01865824A14B001BA2 -:10EE30000A000EA532B000013C010801A0289791FC -:10EE40000A000EF93C0D80088CB500308EFE0008DB -:10EE50002404001826B6000103C0F809ACB600303F -:10EE60003C030801906397913077000116E0FF8121 -:10EE7000306A00018FB200300A000D753243000481 -:10EE80003C1080009605011A50A0FF2B34C60010DC -:10EE90000A000EC892EE000C8C6200001456FF6D42 -:10EEA000000000008C7800048FB9005403388823D8 -:10EEB0000621FF638FBF00540A000F0E0000000000 -:10EEC0003C010801A02A97910A000F3030F9000197 -:10EED0001633FF028FAF00240A000EB0241E00106C -:10EEE0000E00167F024020213C0B80083568008010 -:10EEF00091090025240A0001AFAA0050353300040F -:10EF0000024020210E001689A11300253C050801AE -:10EF100090A5979130A200FD3C010801A022979195 -:10EF20000A000E6D004018212411000E53D1FEEA94 -:10EF3000241E00100A000EAF241E00165629FEDC07 -:10EF400032B000013C0A8008914C001B2406FFBD32 -:10EF5000241E001001865824A14B001B0A000EA598 -:10EF600032B000010A000EA4241E00123C038000EF -:10EF70008C6201B80440FFFE24040800AC6401B8B0 -:10EF800003E000080000000030A5FFFF30C6FFFFCF -:10EF90003C0780008CE201B80440FFFE34EA0180A7 -:10EFA000AD440000ACE400203C0480089483004899 -:10EFB0003068FFFF11000016AF88000824AB001274 -:10EFC000010B482B512000133C04800034EF01005A -:10EFD00095EE00208F890000240D001A31CCFFFF30 -:10EFE00031274000A14D000B10E000362583FFFEC5 -:10EFF0000103C02B170000348F9900048F88000490 -:10F00000A5430014350700010A001003AF87000470 -:10F010003C04800024030003348201808F890000B7 -:10F020008F870004A043000B3C088000350C018052 -:10F03000A585000EA585001A8F85000C30EB800099 -:10F04000A5890010AD850028A58600081160000F75 -:10F050008F85001435190100972A00163158FFFCDE -:10F06000270F000401E870218DCD400031A6FFFF7D -:10F0700014C000072403BFFF3C02FFFF34487FFF9A -:10F0800000E83824AF8700048F8500142403BFFFF5 -:10F090003C04800000E3582434830180A46B0026E4 -:10F0A000AC69002C10A0000300054C02A465001000 -:10F0B000A46900263C071000AC8701B803E00008F3 -:10F0C000000000008F990004240AFFFE032A382460 -:10F0D0000A001003AF87000427BDFFE88FA20028B5 -:10F0E00030A5FFFF30C6FFFFAFBF0010AF87000C99 -:10F0F000AF820014AF8000040E000FDBAF80000071 -:10F100008FBF001027BD001803E00008AF80001477 -:10F110003C06800034C4007034C701008C8A0000B3 -:10F1200090E500128F84000027BDFFF030A300FFA0 -:10F13000000318823082400010400037246500032D -:10F140000005C8800326C0218F0E4000246F0004F4 -:10F15000000F6880AFAE000001A660218D8B4000DB -:10F16000AFAB000494E900163128FFFC01063821FA -:10F170008CE64000AFA600088FA9000800003021EF -:10F18000000028213C07080024E701000A0010675E -:10F19000240800089059000024A500012CAC000CA4 -:10F1A0000079C0210018788001E770218DCD000022 -:10F1B0001180000600CD302603A5102114A8FFF50C -:10F1C00000051A005520FFF4905900003C0480000F -:10F1D000348700703C0508008CA531048CE30000E6 -:10F1E0002CA2002010400009006A38230005488046 -:10F1F0003C0B0800256B3108012B402124AA00019B -:10F20000AD0700003C010800AC2A310400C0102109 -:10F2100003E0000827BD0010308220001040000BE2 -:10F2200000055880016648218D24400024680004B0 -:10F2300000083880AFA4000000E618218C6540006B -:10F24000AFA000080A001057AFA500040000000D91 -:10F250000A0010588FA9000827BDFFE03C07800076 -:10F2600034E60100AFBF001CAFB20018AFB100140C -:10F27000AFB0001094C5000E8F87000030A4FFFFD0 -:10F280002483000430E2400010400010AF83002CC3 -:10F290003C09002000E940241100000D30EC800002 -:10F2A0008F8A0004240BBFFF00EB38243543100085 -:10F2B000AF87000030F220001640000B3C1900041C -:10F2C000241FFFBF0A0010B7007F102430EC80001D -:10F2D000158000423C0E002030F220001240FFF862 -:10F2E0008F8300043C19000400F9C0241300FFF5CB -:10F2F000241FFFBF34620040AF82000430E20100EF -:10F300001040001130F010008F83003010600006B4 -:10F310003C0F80003C05002000E52024148000C044 -:10F320003C0800043C0F800035EE010095CD001E26 -:10F3300095CC001C31AAFFFF000C5C00014B482556 -:10F34000AF89000C30F010001200000824110001F9 -:10F3500030F100201620008B3C18100000F890249B -:10F36000164000823C040C002411000130E801002A -:10F370001500000B3C0900018F85000430A94000F6 -:10F38000152000073C0900013C0C1F0100EC58242B -:10F390003C0A1000116A01183C1080003C09000171 -:10F3A00000E9302410C000173C0B10003C18080086 -:10F3B0008F1800243307000214E0014024030001E9 -:10F3C0008FBF001C8FB200188FB100148FB00010D7 -:10F3D0000060102103E0000827BD002000EE682433 -:10F3E00011A0FFBE30F220008F8F00043C11FFFF00 -:10F3F00036307FFF00F0382435E380000A0010A685 -:10F40000AF87000000EB102450400065AF8000285B -:10F410008F8C00303C0D0F0000ED18241580008803 -:10F42000AF83001030E8010011000086938F0010B8 -:10F430003C0A0200106A00833C1280003650010032 -:10F44000920500139789002E3626000230AF00FF88 -:10F4500025EE0004000E19C03C0480008C9801B811 -:10F460000700FFFE34880180AD0300003C198008CE -:10F47000AC830020973100483225FFFF10A0015CCB -:10F48000AF8500082523001200A3F82B53E0015993 -:10F490008F850004348D010095AC00202402001AF1 -:10F4A00030E44000318BFFFFA102000B108001927D -:10F4B0002563FFFE00A3502B154001908F8F0004A1 -:10F4C000A50300148F88000435050001AF850004F2 -:10F4D0003C08800035190180A729000EA729001AD1 -:10F4E0008F89000C30B18000A7270010AF290028B9 -:10F4F000A72600081220000E3C04800035020100FF -:10F50000944C0016318BFFFC256400040088182100 -:10F510008C7F400033E6FFFF14C000053C048000F0 -:10F520003C0AFFFF354D7FFF00AD2824AF85000466 -:10F53000240EBFFF00AE402434850180A4A800261D -:10F54000ACA7002C3C071000AC8701B800001821C4 -:10F550008FBF001C8FB200188FB100148FB0001045 -:10F560000060102103E0000827BD00203C020BFFD3 -:10F5700000E41824345FFFFF03E3C82B5320FF7B14 -:10F58000241100013C0608008CC6002C24C5000193 -:10F590003C010800AC25002C0A0010D42411000501 -:10F5A0008F85002810A0002FAF80001090A30000CE -:10F5B000146000792419000310A0002A30E601002D -:10F5C00010C000CC8F860010241F000210DF00C97D -:10F5D0008F8B000C3C0708008CE7003824E4FFFF09 -:10F5E00014E0000201641824000018213C0D0800FA -:10F5F00025AD0038006D1021904C00048F85002C43 -:10F6000025830004000321C030A5FFFF3626000239 -:10F610000E000FDB000000000A00114D0000182151 -:10F6200000E8302414C0FF403C0F80000E00103D65 -:10F63000000000008F8700000A0010CAAF82000C93 -:10F64000938F00103C180801271896E0000F90C017 -:10F6500002588021AF9000288F85002814A0FFD386 -:10F66000AF8F00103C0480008C86400030C5010044 -:10F6700010A000BC322300043C0C08008D8C002438 -:10F6800024120004106000C23190000D3C04800080 -:10F690008C8D40003402FFFF11A201003231FFFBCC -:10F6A0008C884000310A01005540000124110010EF -:10F6B00030EE080011C000BE2419FFFB8F98002C0B -:10F6C0002F0F03EF51E000010219802430E90100FF -:10F6D00011200014320800018F87003014E000FB75 -:10F6E0008F8C000C3C05800034AB0100917F00132F -:10F6F00033E300FF246A00042403FFFE0203802496 -:10F70000000A21C012000002023230253226FFFF1B -:10F710000E000FDB9785002E1200FF290000182134 -:10F72000320800011100000D32180004240E0001FF -:10F73000120E0002023230253226FFFF9785002E7E -:10F740000E000FDB00002021240FFFFE020F80249B -:10F750001200FF1B00001821321800045300FF188C -:10F760002403000102323025241200045612000145 -:10F770003226FFFF9785002E0E000FDB24040100C8 -:10F780002419FFFB021988241220FF0D0000182104 -:10F790000A0010E9240300011079009C00003021C8 -:10F7A00090AD00012402000211A200BE30EA004028 -:10F7B00090B90001241800011338007F30E900409F -:10F7C0008CA600049785002E00C020210E000FDBC0 -:10F7D0003626000200004021010018218FBF001CC6 -:10F7E0008FB200188FB100148FB00010006010218C -:10F7F00003E0000827BD0020360F010095EE000C45 -:10F8000031CD020015A0FEE63C0900013C1880083D -:10F81000971200489789002E362600023248FFFFD3 -:10F82000AF8800083C0380008C7101B80620FFFE01 -:10F83000346A0180AD4000001100008E3C0F800052 -:10F84000253F0012011FC82B1320008B240E00033C -:10F85000346C0100958B00202402001A30E4400033 -:10F860003163FFFFA142000B108000A72463FFFE5D -:10F870000103682B15A000A52408FFFE34A5000194 -:10F88000A5430014AF8500043C0480002412BFFF90 -:10F8900000B2802434850180A4A9000EA4A9001A16 -:10F8A000A4A60008A4B00026A4A700103C071000DE -:10F8B000AC8701B80A00114D000018213C038000FC -:10F8C00034640100949F000E3C1908008F3900D861 -:10F8D0002404008033E5FFFF273100013C010800CC -:10F8E000AC3100D80E000FDB240600030A00114DD6 -:10F8F00000001821240A000210CA00598F85002C2C -:10F900003C0308008C6300D0240E0001106E005EE2 -:10F910002CCF000C24D2FFFC2E5000041600002136 -:10F9200000002021241800021078001B2CD9000CA4 -:10F9300024DFFFF82FE900041520FF330000202109 -:10F9400030EB020051600004000621C054C00022C8 -:10F9500030A5FFFF000621C030A5FFFF0A00117D82 -:10F96000362600023C0908008D29002431300001B0 -:10F970005200FEF7000018219785002E362600025F -:10F980000E000FDB000020210A00114D000018219D -:10F990000A00119C241200021320FFE624DFFFF866 -:10F9A0000000202130A5FFFF0A00117D362600024D -:10F9B0000A0011AC021980245120FF828CA6000499 -:10F9C0003C05080190A596E110A0FF7E24080001E7 -:10F9D0000A0011F0010018210E000FDB3226000191 -:10F9E0008F8600108F85002C0A00124F000621C060 -:10F9F0008F8500043C18800024120003371001801A -:10FA0000A212000B0A00112E3C08800090A30001F6 -:10FA1000241100011071FF70240800012409000264 -:10FA20005069000430E60040240800010A0011F08B -:10FA30000100182150C0FFFD240800013C0C80008B -:10FA4000358B01009563001094A40002307FFFFF06 -:10FA5000509FFF62010018210A001284240800014F -:10FA60002CA803EF1100FE56240300010A001239EE -:10FA700000000000240E000335EA0180A14E000BB7 -:10FA80000A00121C3C04800011E0FFA2000621C005 -:10FA900030A5FFFF0A00117D362600020A0011A5DD -:10FAA000241100201140FFC63C1280003650010096 -:10FAB000960F001094AE000231E80FFF15C8FFC08A -:10FAC000000000000A0011E690B900013C060800A1 -:10FAD0008CC6003824C4FFFF14C00002018418241F -:10FAE000000018213C0D080025AD0038006D1021E4 -:10FAF0000A0011B6904300048F8F0004240EFFFE0D -:10FB00000A00112C01EE28242408FFFE0A00121A14 -:10FB100000A8282427BDFFC8AFB00010AFBF003435 -:10FB20003C10600CAFBE0030AFB7002CAFB6002861 -:10FB3000AFB50024AFB40020AFB3001CAFB20018C3 -:10FB4000AFB100148E0E5000240FFF7F3C068000E2 -:10FB500001CF682435AC380C240B0003AE0C5000E8 -:10FB6000ACCB00083C010800AC2000200E00184A75 -:10FB7000000000003C0A0010354980513C06601628 -:10FB8000AE09537C8CC700003C0860148D0500A0B2 -:10FB90003C03FFFF00E320243C02535300051FC237 -:10FBA0001482000634C57C000003A08002869821E0 -:10FBB0008E7200043C116000025128218CBF007C31 -:10FBC0008CA200783C1E600037C420203C05080150 -:10FBD00024A59328AF820018AF9F001C0E00170EBB -:10FBE0002406000A3C190001273996E03C01080070 -:10FBF000AC3931DC0E002105AF8000148FD7080826 -:10FC00002418FFF03C15570902F8B02412D503243C -:10FC100024040001AF8000303C148000369701803E -:10FC20003C1E080127DE96E0369301008E9000000E -:10FC30003205000310A0FFFD3207000110E000882C -:10FC4000320600028E7100283C048000AE91002034 -:10FC50008E6500048E66000000A0382100C040219F -:10FC60008C8301B80460FFFE3C0B0010240A0800DE -:10FC700000AB4824AC8A01B8552000E2240ABFFF3B -:10FC80009675000E3C1208008E52002030AC4000E9 -:10FC900032AFFFFF264E000125ED00043C010800B5 -:10FCA000AC2E0020118000EAAF8D002C3C18002003 -:10FCB00000B8B02412C000E730B980002408BFFFAC -:10FCC00000A8382434C81000AF87000030E62000B8 -:10FCD00010C000EB2409FFBF3C03000400E328240C -:10FCE00010A00002010910243502004030EA010092 -:10FCF00011400010AF8200048F8B003011600007AC -:10FD00003C0D002000ED6024118000043C0F000435 -:10FD100000EF702411C00239000000009668001E38 -:10FD20009678001C3115FFFF0018B40002B690252C -:10FD3000AF92000C30F910001320001324150001BD -:10FD400030FF002017E0000A3C04100000E41024FB -:10FD50001040000D3C0A0C003C090BFF00EA18247F -:10FD60003525FFFF00A3302B10C0000830ED010047 -:10FD70003C0C08008D8C002C24150005258B0001FF -:10FD80003C010800AC2B002C30ED010015A0000B4D -:10FD90003C0500018F85000430AE400055C00007CF -:10FDA0003C0500013C161F0100F690243C0F10009A -:10FDB000124F01CE000000003C05000100E5302498 -:10FDC00010C000B13C0C10003C1F08008FFF002445 -:10FDD00033E90002152000732403000100601021A4 -:10FDE000104000083C0680003C188000370F0100DE -:10FDF0008DEE00243C056020ACAE00140000000035 -:10FE00003C0680003C084000ACC8013800000000FF -:10FE10005220001332060002262A0140262B0080C1 -:10FE2000240DFF80014D2024016D6024000C194039 -:10FE30003162007F0004A9403152007F3C1620004F -:10FE400036C900020062F82502B2382500E988258B -:10FE500003E9C825ACD90830ACD10830320600021D -:10FE600010C0FF723C0F800035E501408CB80000E7 -:10FE700024100040ADF8002090AE000831C300709F -:10FE8000107000D628680041510000082405006069 -:10FE9000241100201071000E3C0B40003C06800035 -:10FEA000ACCB01780A001304000000001465FFFBCE -:10FEB0003C0B40000E002022000000003C0B4000E4 -:10FEC0003C068000ACCB01780A001304000000005F -:10FED00090BF0009241900048CA7000033E900FF3B -:10FEE000113901B22523FFFA2C72000612400016C8 -:10FEF0003C0680008CAB00048F86002494A2000A8C -:10FF0000000B5602312500FF10C000053044FFFFF2 -:10FF10002D4C000815800002254A0004240A000325 -:10FF20002410000910B001F828AE000A11C001DC4D -:10FF3000240F000A2404000810A40028000A41C06D -:10FF4000010038213C0680008CC801B80500FFFE86 -:10FF500034D00180AE07000034C401409085000811 -:10FF6000240A00023C0B400030B900FF00198A004F -:10FF70000229C025A6180008A20A000B948F000AC7 -:10FF80003C091000A60F00108C8E0004AE0E002459 -:10FF9000ACC901B83C068000ACCB01780A00130460 -:10FFA000000000003C0A8000354401009483000EEC -:10FFB0003C0208008C4200D8240400803065FFFF1A -:10FFC000245500013C010800AC3500D80E000FDBC1 -:10FFD000240600030A00137000001821000BC2025F -:10FFE000330300FF240A0001146AFFD60100382100 -:10FFF0008F910020AF830024262B00010A0013CA32 -:020000040001F9 -:10000000AF8B002000CA2024AF85000010800008BC -:10001000AF860004240C87FF00CC5824156000082C -:100020003C0D006000AD302410C000050000000051 -:100030000E000D42000000000A00137100000000D5 -:100040000E001636000000000A00137100000000C8 -:1000500030B980005320FF1DAF8500003C02002016 -:1000600000A2F82453E0FF19AF8500003C07FFFF12 -:1000700034E47FFF00A438240A00132B34C8800026 -:100080000A0013340109102400EC58245160005A6E -:10009000AF8000288F8D00303C0E0F0000EE18243A -:1000A00015A00075AF83001030EF010011E0007360 -:1000B000939800103C120200107200703C06800001 -:1000C00034D90100932800139789002E36A6000228 -:1000D000311800FF27160004001619C03C048000E8 -:1000E0008C8501B804A0FFFE34880180AD030000B8 -:1000F0003C158008AC83002096BF004833E5FFFF25 -:1001000010A001EBAF8500082523001200A3102BDF -:10011000504001E88F850004348D010095AC00202B -:10012000240B001A30E44000318AFFFFA10B000BC2 -:10013000108001E92543FFFE00A3702B15C001E7E5 -:100140008F9600048F8F0004A503001435E500018D -:10015000AF8500043C08800035150180A6A9000E7B -:10016000A6A9001A8F89000C30BF8000A6A7001036 -:10017000AEA90028A6A6000813E0000F3C0F8000DF -:10018000350C0100958B0016316AFFFC25440004F4 -:10019000008818218C6240003046FFFF14C0000721 -:1001A0002416BFFF3C0EFFFF35CD7FFF00AD282496 -:1001B000AF8500043C0F80002416BFFF00B69024DA -:1001C00035E50180A4B20026ACA7002C3C07100046 -:1001D000ADE701B80A001370000018210E00168E5A -:1001E000000000003C0B40003C068000ACCB0178D6 -:1001F0000A001304000000008F85002810A00025CD -:10020000AF80001090A3000010600072241F000354 -:10021000107F00FF0000302190AD0001240C00028F -:1002200011AC015930EE004090BF000124190001CB -:1002300013F9000930E900408CA600049785002ED0 -:1002400000C020210E000FDB36A600020000402176 -:100250000A001370010018215120FFF88CA6000439 -:100260003C07080190E796E110E0FFF42408000144 -:100270000A00137001001821939800100018C8C0DC -:10028000033E4021AF8800288F85002814A0FFDDA1 -:10029000AF9800103C0480008C86400030C50100FF -:1002A00010A0008732AA00043C0B08008D6B0024CC -:1002B00024160004154000033172000D24160002BC -:1002C0003C0480008C8D4000340CFFFF11AC012CED -:1002D00032B5FFFB8C8F400031EE010055C00001AC -:1002E0002415001030F8080013000038241FFFFB0D -:1002F0008F99002C2F2803EF51000001025F9024FA -:1003000030E9010011200014325900018F870030BC -:1003100014E001278F8B000C3C0480003486010020 -:1003200090C5001330A300FF24620004000221C026 -:100330002408FFFE024890241240000202B6302535 -:1003400032A6FFFF0E000FDB9785002E1240FEA3A2 -:1003500000001821325900011320000D324700041B -:10036000241F0001125F000202B6302532A6FFFFF3 -:100370009785002E0E000FDB000020212409FFFED0 -:10038000024990241240FE950000182132470004D3 -:1003900050E0FE922403000102B63025241600042A -:1003A0005656000132A6FFFF9785002E0E000FDB88 -:1003B000240401002402FFFB0242A82412A0FE87AD -:1003C000000018210A001370240300010A0014B968 -:1003D000025F902410A0FFAF30E5010010A00017CD -:1003E0008F8600102402000210C200148F84000CBB -:1003F0003C0608008CC6003824C3FFFF14C000026E -:1004000000831024000010213C0D080025AD0038A9 -:10041000004D6021918B00048F85002C256A00041B -:10042000000A21C030A5FFFF36A600020E000FDB38 -:10043000000000000A00137000001821240E0002C2 -:1004400010CE0088241200013C0308008C6300D009 -:100450001072008D8F85002C24C8FFFC2D1800041D -:100460001700006300002021241900021079005DAC -:100470002CDF000C24C2FFF82C4900041520FFE9F2 -:100480000000202130E3020050600004000621C07B -:1004900054C0000530A5FFFF000621C030A5FFFFB6 -:1004A0000A00150436A600020E000FDB32A600017A -:1004B0008F8600108F85002C0A001520000621C0B1 -:1004C0003C0308008C630024307200015240FE435C -:1004D000000018219785002E36A600020E000FDBC3 -:1004E000000020210A001370000018219668000CFB -:1004F000311802005700FE313C0500013C1F800806 -:1005000097F900489789002E36A600023328FFFF8E -:10051000AF8800083C0380008C7501B806A0FFFE80 -:100520003C04800034820180AC400000110000E7F0 -:1005300024180003252A0012010A182B106000E37A -:1005400000000000966F00203C0E8000240D001A71 -:1005500031ECFFFF35CA018030EB4000A14D000BAC -:10056000116000E12583FFFE0103902B164000DFA0 -:100570002416FFFE34A50001A5430014AF85000436 -:100580002419BFFF00B94024A6E9000EA6E9001A0D -:10059000A6E60008A6E80026A6E700103C07100023 -:1005A000AE8701B80A001370000018213C048000D7 -:1005B0008C8901B80520FFFE349601802415001CAB -:1005C000AEC70000A2D5000B3C071000AC8701B8F5 -:1005D0003C0B40003C068000ACCB01780A001304C1 -:1005E0000000000013E0FFA424C2FFF80000202157 -:1005F00030A5FFFF0A00150436A600020E00103DCC -:10060000000000008F8700000A001346AF82000C34 -:1006100090A30001241500011075FF0D24080001AE -:10062000240900021069000430E60040240800019B -:100630000A0013700100182150C0FFFD24080001BA -:100640003C0B8000356A01009543001094A4000221 -:100650003062FFFF5082FDE1010018210A0015857C -:10066000240800018F85002C2CAF03EF11E0FDDB87 -:10067000240300013C0308008C6300D02412000115 -:100680001472FF7624C8FFFC2CD6000C12C0FF7237 -:10069000000621C030A5FFFF0A00150436A600029F -:1006A00010AF005700043A022406000B14A6FE24E3 -:1006B000000A41C0316600FF0006FE00001F5E0315 -:1006C0000562007230C6007F000668C001BE382196 -:1006D000A0E00001A0E000003C1660008ED21820CF -:1006E000240C000100CC100400021827000A41C0AD -:1006F0000243A824A4E0000201003821AED518204E -:100700000A0013CB3C06800014C000368F8D0020F9 -:10071000000A41C03C1F80003C058008AFE8002073 -:1007200094B9004013200002240500012405004173 -:100730003C0480008C8701B804E0FFFE3495018002 -:1007400024020003AEA80000A2A2000BA6A0000E87 -:10075000A6A0001AA6A00010AEA00028A6A500081A -:1007600096A3002634720001A6B20026AEA0002C8B -:100770003C161000AC9601B80A0013CA01003821DB -:100780000A0014B22415002011C0FEB53C088000F8 -:10079000351801009716001094B2000232CF0FFFF7 -:1007A000164FFEAF000000000A00148490BF000145 -:1007B0003C0A08008D4A0038254CFFFF1540000216 -:1007C000016C1024000010213C1808002718003884 -:1007D0000058782191EE000425CD00040A0014C5CC -:1007E000000D21C0000A41C025ACFFFF1580FDD4DB -:1007F000AF8C0020010038210A0013CAAF8000240A -:10080000240300FF10E3FDCE000A41C010C0001712 -:1008100000078600000720C0009E18212402000166 -:100820003C05080124A596E4009E7821000A41C0F9 -:100830000085C821000B8C02A0620000AF280000D8 -:10084000A1F100013C0E60008DC6182024180001A3 -:1008500000F8500400CA202501003821A5EB000251 -:10086000ADC418200A0013CB3C06800000104603DC -:100870000502000D30E7007F11430006000720C08D -:10088000009E18210A001601240200020A0015AB7E -:10089000AF800020009E18210A00160124020003E8 -:1008A0000A0012FFAF8400300A001617AF8700203D -:1008B0008F8500043C19800024080003373801802C -:1008C000A308000B0A00144F3C088000A2F8000B9C -:1008D0000A00155A2419BFFF8F9600042412FFFE48 -:1008E0000A00144D02D228242416FFFE0A001558CF -:1008F00000B628243C038000346401008C8500008D -:1009000030A2003E1440000800000000AC60004827 -:100910008C87000030E607C010C000050000000012 -:10092000AC60004CAC60005003E000082402000101 -:10093000AC600054AC6000408C880000310438008A -:100940001080FFF9000000002402000103E000080D -:10095000AC6000443C0380008C6201B80440FFFEA0 -:1009600034670180ACE4000024080001ACE000041E -:10097000A4E5000824050002A0E8000A3464014050 -:10098000A0E5000B9483000A14C00008A4E3001043 -:10099000ACE000243C07800034E901803C041000F6 -:1009A000AD20002803E00008ACE401B88C86000408 -:1009B0003C041000ACE600243C07800034E90180D0 -:1009C000AD20002803E00008ACE401B83C0680003C -:1009D0008CC201B80440FFFE34C701802409000224 -:1009E000ACE40000ACE40004A4E50008A0E9000ABF -:1009F00034C50140A0E9000B94A8000A3C04100093 -:100A0000A4E80010ACE000248CA30004ACE30028B0 -:100A100003E00008ACC401B83C039000346200015C -:100A2000008220253C038000AC6400208C650020FF -:100A300004A0FFFE0000000003E00008000000002A -:100A40003C028000344300010083202503E00008BD -:100A5000AC44002027BDFFE03C098000AFBF001878 -:100A6000AFB10014AFB00010352801408D10000068 -:100A7000910400099107000891050008308400FFE7 -:100A800030E600FF00061A002C820081008330252A -:100A90001040002A30A50080000460803C0D080151 -:100AA00025AD9350018D58218D6A0000014000084A -:100AB000000000003C038000346201409445000ABD -:100AC00014A0001E8F91FCC09227000530E60004A0 -:100AD00014C0001A000000000E00167F0200202142 -:100AE000922A000502002021354900040E001689D3 -:100AF000A229000592280005310400041480000298 -:100B0000000000000000000D922D0000240B0020CA -:100B100031AC00FF158B00093C0580008CAE01B89C -:100B200005C0FFFE34B10180AE3000003C0F100064 -:100B300024100005A230000BACAF01B80000000D7E -:100B40008FBF00188FB100148FB0001003E00008B1 -:100B500027BD00200200202100C028218FBF0018DF -:100B60008FB100148FB00010240600010A00164E49 -:100B700027BD00200000000D0200202100C0282118 -:100B80008FBF00188FB100148FB00010000030210B -:100B90000A00164E27BD002014A0FFE80000000048 -:100BA000020020218FBF00188FB100148FB00010F9 -:100BB00000C028210A00166C27BD00203C078000D9 -:100BC0008CEE01B805C0FFFE34F00180241F000246 -:100BD000A21F000B34F80140A60600089719000A6E -:100BE0003C0F1000A61900108F110004A61100126E -:100BF000ACEF01B80A0016CA8FBF001827BDFFE886 -:100C0000AFBF00100E000FD4000000003C028000B7 -:100C10008FBF001000002021AC4001800A00108F1F -:100C200027BD00183084FFFF30A5FFFF10800007AC -:100C30000000182130820001104000020004204210 -:100C4000006518211480FFFB0005284003E0000820 -:100C50000060102110C00007000000008CA20000FE -:100C600024C6FFFF24A50004AC82000014C0FFFBD3 -:100C70002484000403E000080000000010A0000825 -:100C800024A3FFFFAC86000000000000000000006D -:100C90002402FFFF2463FFFF1462FFFA2484000490 -:100CA00003E00008000000003C03800027BDFFF8BF -:100CB00034620180AFA20000308C00FF30AD00FF35 -:100CC00030CE00FF3C0B80008D6401B80480FFFE35 -:100CD000000000008FA900008D6801288FAA000085 -:100CE0008FA700008FA40000240500012402000249 -:100CF000A085000A8FA30000359940003C05100034 -:100D0000A062000B8FB800008FAC00008FA600001F -:100D10008FAF000027BD0008AD280000AD400004E3 -:100D2000AD800024ACC00028A4F90008A70D001075 -:100D3000A5EE001203E00008AD6501B83C0680088E -:100D400027BDFFE834C50080AFBF001090A70009A1 -:100D50002402001230E300FF1062000B00803021FB -:100D60008CA8005000882023048000088FBF00104A -:100D70008CAA0034240400390000282100CA48232A -:100D800005200005240600128FBF00102402000178 -:100D900003E0000827BD00180E0017230000000024 -:100DA0008FBF00102402000103E0000827BD0018D7 -:100DB00027BDFFC8AFB20030AFB00028AFBF0034CE -:100DC000AFB1002C00A0802190A5000D30A600102E -:100DD00010C00010008090213C0280088C44000468 -:100DE0008E0300081064000C30A7000530A6000533 -:100DF00010C00093240400018FBF00348FB2003074 -:100E00008FB1002C8FB000280080102103E0000873 -:100E100027BD003830A7000510E0000F30AB0012EE -:100E200010C00006240400013C0980088E08000858 -:100E30008D2500045105009C240400388FBF003428 -:100E40008FB200308FB1002C8FB0002800801021AD -:100E500003E0000827BD0038240A0012156AFFE6E7 -:100E6000240400010200202127A500100E000CB66A -:100E7000AFA000101440007C3C198008372400808B -:100E800090980008331100081220000A8FA7001064 -:100E900030FF010013E000A48FA300148C860058DB -:100EA00000661023044000043C0A8008AC8300580C -:100EB0008FA700103C0A800835480080910900087F -:100EC000312400081480000224080003000040219F -:100ED0003C1F800893F1001193F9001237E600805F -:100EE0008CCC0054333800FF03087821322D00FFEA -:100EF000000F708001AE282100AC582B1160006FEC -:100F00000000000094CA005C8CC900543144FFFF0B -:100F1000012510230082182B1460006800000000D7 -:100F20008CCB00540165182330EC00041180006C58 -:100F3000000830808FA8001C0068102B1040006251 -:100F400030ED0004006610232C46008010C0000223 -:100F500000408821241100800E00167F02402021CD -:100F60003C0D800835A6008024070001ACC7000CAA -:100F700090C800080011484035A70100310C007FDF -:100F8000A0CC00088E05000424AB0001ACCB0030DF -:100F9000A4D1005C8CCA003C9602000E01422021C4 -:100FA000ACC400208CC3003C0069F821ACDF001CFD -:100FB0008E190004ACF900008E180008ACF800048B -:100FC0008FB10010322F000855E0004793A6002093 -:100FD000A0C0004E90D8004E2411FFDFA0F80008FA -:100FE00090CF000801F17024A0CE00088E05000803 -:100FF0003C0B800835690080AD2500388D6A0014EF -:101000008D2200302419005001422021AD240034EB -:1010100091230000307F00FF13F90036264F0100B6 -:101020000E001689024020212404003800002821E7 -:101030000E0017232406000A0A0017882404000162 -:101040000E000D28000020218FBF00348FB2003029 -:101050008FB1002C8FB0002800402021008010218B -:1010600003E0000827BD00388E0E00083C0F800802 -:1010700035F00080AE0E005402402021AE0000305A -:101080000E00167F00000000920D00250240202176 -:1010900035AC00200E001689A20C00250E000CAC09 -:1010A00002402021240400382405008D0E0017235F -:1010B000240600120A0017882404000194C5005C6D -:1010C0000A0017C330A3FFFF2407021811A0FF9ED8 -:1010D00000E610238FAE001C0A0017CB01C61023B8 -:1010E0000A0017C82C620218A0E600080A0017F5CB -:1010F0008E0500082406FF8001E6C0243C11800014 -:10110000AE3800288E0D000831E7007F3C0E800CC1 -:1011100000EE6021AD8D00E08E080008AF8C003C31 -:101120000A001801AD8800E4AC80005890850008E2 -:101130002403FFF700A33824A08700080A0017A69D -:101140008FA700103C05080024A5616C3C04080032 -:10115000248470B83C020800244261742403000611 -:101160003C010801AC2597603C010801AC24976460 -:101170003C010801AC2297683C010801A023976C50 -:1011800003E000080000000003E000082402000162 -:101190003C028000308800FF344701803C0680001C -:1011A0008CC301B80460FFFE000000008CC501285C -:1011B0002418FF803C0D800A24AF010001F8702440 -:1011C00031EC007FACCE0024018D2021ACE5000085 -:1011D000948B00EA3509600024080002316AFFFFA1 -:1011E000ACEA000424020001A4E90008A0E8000B16 -:1011F000ACE000243C071000ACC701B8AF84003C51 -:1012000003E00008AF8500709388004C8F8900646C -:101210008F82003C30C600FF0109382330E900FF0F -:101220000122182130A500FF2468008810C00002A8 -:10123000012438210080382130E4000314800003A9 -:1012400030AA00031140000D312B000310A000094B -:101250000000102190ED0000244E000131C200FF7B -:101260000045602BA10D000024E700011580FFF967 -:101270002508000103E00008000000001560FFF3EE -:101280000000000010A0FFFB000010218CF80000FF -:1012900024590004332200FF0045782BAD180000CC -:1012A00024E7000415E0FFF92508000403E0000826 -:1012B000000000009385004C9388005C8F870064D9 -:1012C000000432003103007F00E5102B30C47F00A2 -:1012D0001040000F006428258F84003C3C098000EA -:1012E0008C8A00ECAD2A00A43C03800000A35825A2 -:1012F000AC6B00A08C6C00A00580FFFE000000001D -:101300008C6D00ACAC8D00EC03E000088C6200A892 -:101310000A0018B38F84003C9388005D3C02800073 -:1013200000805021310300FEA383005D30ABFFFF3E -:1013300030CC00FF30E7FFFF344801803C098000DB -:101340008D2401B80480FFFE8F8D007024180016D4 -:10135000AD0D00008D2201248F8D003CAD020004F4 -:101360008D590020A5070008240201C4A119000A14 -:10137000A118000B952F01208D4E00088D47000409 -:10138000978300608D59002401CF302100C72821A8 -:1013900000A320232418FFFFA504000CA50B000EBA -:1013A000A5020010A50C0012AD190018AD180024FC -:1013B00095AF00E83C0B10002407FFF731EEFFFF6C -:1013C000AD0E00288DAC0084AD0C002CAD2B01B807 -:1013D0008D46002000C7282403E00008AD4500200A -:1013E0008F88003C0080582130E7FFFF910900D62C -:1013F0003C02800030A5FFFF312400FF00041A00EA -:101400000067502530C600FF344701803C0980004A -:101410008D2C01B80580FFFE8F820070240F00170D -:10142000ACE200008D390124ACF900048D78002075 -:10143000A4EA0008241901C4A0F8000AA0EF000BD8 -:10144000952301208D6E00088D6D00049784006047 -:1014500001C35021014D602101841023A4E2000C3E -:10146000A4E5000EA4F90010A4E60012ACE00014FC -:101470008D780024240DFFFFACF800188D0F007C40 -:10148000ACEF001C8D0E00783C0F1000ACEE00207D -:10149000ACED0024950A00BE240DFFF73146FFFF96 -:1014A000ACE60028950C00809504008231837FFF14 -:1014B0000003CA003082FFFF0322C021ACF8002CD9 -:1014C000AD2F01B8950E00828D6A002000AE30214C -:1014D000014D2824A506008203E00008AD65002028 -:1014E0003C028000344501803C0480008C8301B8BC -:1014F0000460FFFE8F8A0048240600199549001CED -:101500003128FFFF000839C0ACA70000A0A6000BDF -:101510003C05100003E00008AC8501B88F8700503F -:101520000080402130C400FF3C0680008CC201B81E -:101530000440FFFE8F8900709383006C3499600033 -:10154000ACA90000A0A300058CE20010240F00024B -:101550002403FFF7A4A20006A4B900088D180020F8 -:10156000A0B8000AA0AF000B8CEE0000ACAE0010DB -:101570008CED0004ACAD00148CEC001CACAC002471 -:101580008CEB0020ACAB00288CEA002C3C07100050 -:10159000ACAA002C8D090024ACA90018ACC701B876 -:1015A0008D05002000A3202403E00008AD040020E6 -:1015B0008F86003C27BDFFE0AFB10014AFBF00181D -:1015C000AFB0001090C300D430A500FF30620020FF -:1015D00010400008008088218CCB00D02409FFDF58 -:1015E000256A0001ACCA00D090C800D40109382493 -:1015F000A0C700D414A000403C0C80008F84003CA5 -:10160000908700D42418FFBF2406FFEF30E3007F4B -:10161000A08300D4979F00608F8200648F8D003C70 -:1016200003E2C823A7990060A5A000BC91AF00D435 -:1016300001F87024A1AE00D48F8C003CA18000D7AB -:101640008F8A003CA5400082AD4000EC914500D45B -:1016500000A65824A14B00D48F9000388F840064DA -:10166000978600600204282110C0000FAF85003863 -:10167000A380005C3C0780008E2C000894ED0120C4 -:101680008E2B0004018D5021014B80210206202366 -:101690003086FFFF30C8000F3909000131310001E9 -:1016A00016200009A388005C9386004C8FBF0018A9 -:1016B0008FB100148FB0001027BD0020AF850068E7 -:1016C00003E00008AF86006400C870238FBF0018D5 -:1016D0009386004C8FB100148FB0001034EF0C00D3 -:1016E000010F282127BD0020ACEE0084AF850068E3 -:1016F00003E00008AF8600643590018002002821D5 -:101700000E001940240600828F84003C908600D48D -:1017100030C5004050A0FFBAA380006C8F850050F8 -:101720003C0680008CCD01B805A0FFFE8F890070BB -:101730002408608224070002AE090000A608000801 -:10174000A207000B8CA300083C0E1000AE03001093 -:101750008CA2000CAE0200148CBF0014AE1F001847 -:101760008CB90018AE1900248CB80024AE180028DB -:101770008CAF0028AE0F002CACCE01B80A0019794E -:10178000A380006C8F8A003C27BDFFE0AFB100143E -:10179000AFB000108F880064AFBF0018938900407D -:1017A000954200BC30D100FF0109182B0080802138 -:1017B00030AC00FF3047FFFF0000582114600003E9 -:1017C000310600FF01203021010958239783006072 -:1017D0000068202B148000270000000010680056CD -:1017E000241900011199006334E708803165FFFF77 -:1017F0000E0018F1020020218F8300703C0780004A -:1018000034E601803C0580008CAB01B80560FFFE2A -:10181000240A00188F84003CACC30000A0CA000B4F -:10182000948900BE3C081000A4C90010ACC0003070 -:10183000ACA801B89482008024430001A4830080F6 -:10184000949F00803C0608008CC6318833EC7FFFF3 -:101850001186005E000000000200202102202821E5 -:101860008FBF00188FB100148FB000100A001965E7 -:1018700027BD0020914400D42403FF8000838825E5 -:10188000A15100D4978400603088FFFF51000023ED -:10189000938C00408F85003C2402EFFF008B78235F -:1018A00094AE00BC0168502B31E900FF01C26824EE -:1018B000A4AD00BC51400039010058213C1F8000FC -:1018C00037E601008CD800043C19000103194024BC -:1018D0005500000134E740008E0A00202403FFFB7E -:1018E0002411000101432024AE0400201191002D99 -:1018F00034E7800002002021012030210E0018F181 -:101900003165FFFF978700608F890064A7800060C2 -:1019100001278023AF900064938C00408F8B003CA4 -:101920008FBF00188FB100148FB0001027BD0020AA -:1019300003E00008A16C00D73C0D800035AA01002F -:101940008D4800043C0900010109282454A000012D -:1019500034E740008E0F00202418FFFB34E780009E -:1019600001F8702424190001AE0E00201599FF9F84 -:1019700034E70880020020210E0018BF3165FFFF08 -:1019800002002021022028218FBF00188FB10014EF -:101990008FB000100A00196527BD00200A001A2820 -:1019A0000000482102002021012030210E0018BF34 -:1019B0003165FFFF978700608F890064A780006012 -:1019C000012780230A001A3FAF900064948C0080A6 -:1019D000241F8000019F3024A4860080908B00800B -:1019E000908F0080316700FF0007C9C20019C0272F -:1019F000001871C031ED007F01AE2825A085008060 -:101A00000A001A10020020219385006C24030001B3 -:101A100027BDFFE800A330042CA20020AFB00010C7 -:101A2000AFBF001400C01821104000132410FFFEA7 -:101A30003C0708008CE7319000E610243C08800049 -:101A40003505018014400005240600848F89003C80 -:101A5000240A00042410FFFFA12A00FC0E001940F4 -:101A600000000000020010218FBF00148FB0001092 -:101A700003E0000827BD00183C0608008CC631941E -:101A80000A001A8800C310248F87004827BDFFE092 -:101A9000AFB20018AFB10014AFB00010AFBF001C60 -:101AA00030D000FF90E6000D00A08821008090213A -:101AB00030C5007FA0E5000D8F85003C8E23001807 -:101AC0008CA200D01062002E240A000E0E001A7B99 -:101AD000A38A006C2409FFFF104900222404FFFFA1 -:101AE00052000020000020218E2600003C0C001037 -:101AF00000CC5824156000393C0E000800CE682444 -:101B000055A0003F024020213C18000200D880244C -:101B10001200001F3C0A00048F8700488CE200146A -:101B20008CE300108CE500140043F82303E5C82B78 -:101B300013200005024020218E24002C8CF100107F -:101B4000109100310240202124020012A382006C77 -:101B50000E001A7B2412FFFF105200022404FFFF24 -:101B6000000020218FBF001C8FB200188FB100141D -:101B70008FB000100080102103E0000827BD002076 -:101B800090A800D4350400200A001AB1A0A400D403 -:101B900000CA48241520000B8F8B00488F8D004809 -:101BA0008DAC00101580000B024020218E2E002CE1 -:101BB00051C0FFEC00002021024020210A001ACC75 -:101BC000240200178D66001050C0FFE6000020219F -:101BD000024020210A001ACC2402001102402021D8 -:101BE000240200150E001A7BA382006C240FFFFF55 -:101BF000104FFFDC2404FFFF0A001ABB8E260000F2 -:101C00000A001AF2240200143C08000400C8382418 -:101C100050E0FFD400002021024020210A001ACC0D -:101C2000240200138F85003C27BDFFD8AFB3001CF2 -:101C3000AFB20018AFB10014AFB00010AFBF0020BA -:101C400090A700D48F9000502412FFFF34E2004090 -:101C500092060000A0A200D48E03001000809821FC -:101C60001072000630D1003F2408000D0E001A7BD0 -:101C7000A388006C105200252404FFFF8F8A003CCB -:101C80008E0900188D4400D0112400070260202125 -:101C9000240C000E0E001A7BA38C006C240BFFFF9B -:101CA000104B001A2404FFFF240400201224000417 -:101CB0008F8D003C91AF00D435EE0020A1AE00D452 -:101CC0008F85005810A00019000000001224004A5F -:101CD0008F98003C8F92FCC0971000809651000AAC -:101CE000523000488F9300443C1F08008FFF318C16 -:101CF00003E5C82B1720001E0260202100002821C8 -:101D00000E0019DA24060001000020218FBF0020F8 -:101D10008FB3001C8FB200188FB100148FB0001069 -:101D20000080102103E0000827BD00285224002A6B -:101D30008E0500148F84003C948A008025490001A0 -:101D4000A4890080948800803C0208008C4231887D -:101D500031077FFF10E2000E00000000026020212A -:101D60000E001965240500010A001B3C000020211B -:101D70002402002D0E001A7BA382006C2403FFFFB7 -:101D80001443FFE12404FFFF0A001B3D8FBF002026 -:101D900094990080241F800024050001033FC02483 -:101DA000A498008090920080908E0080325100FFB5 -:101DB000001181C200107827000F69C031CC007F6C -:101DC000018D5825A08B00800E001965026020212E -:101DD0000A001B3C000020212406FFFF54A6FFD66A -:101DE0008F84003C026020210E001965240500014B -:101DF0000A001B3C00002021026020210A001B5623 -:101E00002402000A2404FFFD0A001B3CAF93006477 -:101E10008F88003C27BDFFE8AFB00010AFBF0014B3 -:101E2000910A00D48F8700500080802135490040FE -:101E30008CE60010A10900D43C0208008C4231B0AD -:101E400030C53FFF00A2182B106000078F8500549B -:101E5000240DFF8090AE000D01AE6024318B00FF99 -:101E6000156000080006C382020020212403000D33 -:101E70008FBF00148FB0001027BD00180A001A7B16 -:101E8000A383006C33060003240F000254CFFFF736 -:101E90000200202194A2001C8F85003C24190023FD -:101EA000A4A200E88CE8000000081E02307F003F7A -:101EB00013F900353C0A00838CE800188CA600D08A -:101EC00011060008000000002405000E0E001A7B19 -:101ED000A385006C2407FFFF104700182404FFFFB0 -:101EE0008F85003C90A900D435240020A0A400D404 -:101EF0008F8C0048918E000D31CD007FA18D000D9B -:101F00008F8300581060001C020020218F84005431 -:101F10008C9800100303782B11E0000D2419001891 -:101F200002002021A399006C0E001A7B2410FFFFF1 -:101F3000105000022404FFFF000020218FBF001476 -:101F40008FB000100080102103E0000827BD0018AA -:101F50008C8600108F9F00480200202100C31023B0 -:101F6000AFE20010240500010E0019DA240600017A -:101F70000A001BC8000020210E001965240500017D -:101F80000A001BC800002021010A5824156AFFD945 -:101F90008F8C0048A0A600FC0A001BB5A386005E3B -:101FA00030A500FF2406000124A9000100C9102B60 -:101FB0001040000C00004021240A000100A6182354 -:101FC000308B000124C60001006A3804000420425E -:101FD0001160000200C9182B010740251460FFF8AA -:101FE00000A6182303E000080100102127BDFFD838 -:101FF000AFB000188F900050AFB1001CAFBF0020F1 -:102000002403FFFF2411002FAFA30010920600004D -:102010002405000826100001006620260E001BE1A2 -:10202000308400FF00021E003C021EDC34466F417B -:102030000A001C090000102110A0000900801821CE -:102040002445000130A2FFFF2C4500080461FFFA7F -:10205000000320400086202614A0FFF900801821EC -:102060000E001BE1240500208FA300102629FFFF8E -:10207000313100FF00034202240700FF1627FFE270 -:102080000102182600035027AFAA0014AFAA0010BF -:102090000000302127A8001027A7001400E67823AD -:1020A00091ED000324CE000100C8602131C600FF7D -:1020B0002CCB00041560FFF9A18D00008FA2001049 -:1020C0008FBF00208FB1001C8FB0001803E0000804 -:1020D00027BD002827BDFFD0AFB3001CAFB0001054 -:1020E000AFBF0028AFB50024AFB40020AFB20018D6 -:1020F000AFB100143C0C80008D880128240FFF80B4 -:102100003C06800A25100100250B0080020F682480 -:102110003205007F016F7024AD8E009000A628214B -:10212000AD8D002490A600FC3169007F3C0A80043C -:10213000012A1821A386005E9067007C0080982108 -:10214000AF83003430E20002AF880070AF85003CFE -:1021500000A018211440000224040034240400309C -:10216000A384004C8C7200DC30D100FF24040004F6 -:10217000AF92006412240004A380006C8E740004EB -:102180001680001E3C0880009386005D30C7000169 -:1021900050E0000F8F8600648CA400848CA800841B -:1021A0002413FF8000936024000C49403110007F0D -:1021B000013078253C19200001F9682530DF00FE48 -:1021C0003C038000AC6D0830A39F005D8F860064E7 -:1021D0008FBF00288FB500248FB400208FB3001C60 -:1021E0008FB200188FB100148FB0001024020001CC -:1021F00027BD003003E00008ACA600DC8E7F00089D -:10220000950201208E67001003E2C8213326FFFFEC -:1022100030D8000F33150001AF87003816A00058E2 -:10222000A398005C35090C000309382100D8182355 -:10223000AD030084AF8700688E6A00043148FFFF59 -:102240001100007EA78A006090AC00D42407FF80B4 -:1022500000EC302430CB00FF1560004B9786006007 -:10226000938E005E240D000230D5FFFF11CD02A237 -:102270000000A0218F85006402A5802B160000BC01 -:102280009388004C3C11800096240120310400FF0B -:10229000148500888F8400688F98003833120003FB -:1022A0005640008530A500FF8F900068310C00FF7C -:1022B0002406003411860095AF900050920400046B -:1022C000148001198F8E003CA38000408E0D000405 -:1022D0008DC800D83C0600FF34CCFFFF01AC302491 -:1022E0000106182B14600121AF8600588F87006407 -:1022F00097980060AF8700440307402310C000C7D1 -:10230000A78800608F91003430C300030003582376 -:10231000922A007C3171000302261021000A2082DB -:10232000309200010012488000492821311FFFFF30 -:1023300003E5C82B132001208F88003C8F850038CF -:102340008F8800681105025A3C0E3F018E0600007E -:102350003C0C250000CE682411AC01638F84005032 -:1023600030E500FF0E00187B000030218F88003C14 -:102370008F8700648F8500380A001DE88F8600581B -:102380000A001C87AF87006890AC00D400EC2024C2 -:10239000309000FF120000169386005D90B5008813 -:1023A00090B400D724A8008832A2003F2446FFE062 -:1023B0002CD10020A39400401220000CAF880050C4 -:1023C000240E000100CE2004308A00191540012B94 -:1023D0003C06800034D80002009858241560022E74 -:1023E0003092002016400234000000009386005D09 -:1023F00030CE000111C0000F978800608CA90084C6 -:102400008CAF00842410FF800130C82400191940CB -:1024100031ED007F006D38253C1F200000FF902526 -:1024200030CB00FE3C188000AF120830A38B005D5B -:10243000978800601500FF84000000008E63002074 -:10244000306C00041180FF519386005D2404FFFB73 -:10245000006430243C038000AE66002034660180B6 -:102460008C7301B80660FFFE8F8E0070346A010025 -:102470003C150001ACCE00008C620124240760856D -:10248000ACC200048D54000402958824522000013F -:1024900024076083241200023C1810003C0B8000CB -:1024A000A4C70008A0D2000BAD7801B80A001C5CDC -:1024B0009386005D30A500FF0E00187B2406000106 -:1024C0008F8800703C05800034A90900250201882E -:1024D0009388004C304A0007304B00783C03408022 -:1024E0002407FF800163C825014980210047F824A3 -:1024F000310C00FF24060034ACBF0800AF90005040 -:10250000ACB908105586FF6E920400048F84003C1D -:102510008E110030908E00D431CD001015A0001027 -:102520008F8300642C6F000515E000E400000000BC -:10253000909800D42465FFFC331200101640000868 -:1025400030A400FF8F9F00688F99003813F90004B2 -:102550003887000130E20001144001C8000000008B -:102560000E001BF4000000000A001E2900000000FD -:102570008F84006830C500FF0E00187B2406000120 -:10258000938E004C240A003411CA00A08F85003CB1 -:102590008F860064978300603062FFFF00C288234B -:1025A000AF910064A78000601280FF900280182124 -:1025B0002414FFFD5474FFA28E6300208E69000472 -:1025C0002403FFBF240BFFEF0135C823AE790004BD -:1025D00090AF00D431ED007FA0AD00D48E66002016 -:1025E0008F98003CA780006034DF0002AE7F00209F -:1025F000A70000BC931200D402434024A30800D4D7 -:102600008F95003CAEA000EC92AE00D401CB5024DC -:10261000A2AA00D40A001D088F85003C8F910038C3 -:10262000AF80006402275821AF8B003800002021C2 -:102630002403FFFF108301B48F85003C8E0C001033 -:102640003C0D08008DAD31B09208000031843FFF91 -:10265000008D802B12000023310D003F3C19080033 -:102660008F3931A88F9F0070000479802408FF8083 -:10267000033F2021008FC8219385005D0328F824A3 -:102680003C0600803C0F800034D80001001F9140C0 -:102690003331007F8F86003C0251502535EE0940D2 -:1026A000332B0078333000073C0310003C02800CD1 -:1026B00001789025020E48210143C02502223821CD -:1026C00034AE0001ADFF0804AF890054ADF2081428 -:1026D000AF870048ADFF0028ACD90084ADF80830C2 -:1026E000A38E005D9383005E2407000350670028DB -:1026F00025A3FFE0240C0001146CFFAB8F85003C88 -:102700002411002311B10084000000002402000BFA -:10271000026020210E001A7BA382006C0040A021E1 -:102720000A001D638F85003C02602021240B000CF1 -:102730000E001A7BA38B006C240AFFFF104AFFBC1B -:102740002404FFFF8F8E003CA38000408E0D000408 -:102750008DC800D83C0600FF34CCFFFF01AC30240C -:102760000106182B1060FEE1AF86005802602021A0 -:10277000241200190E001A7BA392006C240FFFFF95 -:10278000104FFFAB2404FFFF0A001CB48F860058D3 -:102790002C7400201280FFDE2402000B000328802E -:1027A0003C1108012631955400B148218D2D0000BF -:1027B00001A00008000000008F85003800A710214C -:1027C00093850040AF82003802251821A383004082 -:1027D000951F00BC0226282137F91000A51900BC5E -:1027E0005240FF92AF850064246A0004A38A00402F -:1027F000950900BC24A40004AF8400643532200095 -:10280000A51200BC0A001D85000020218F860064EF -:102810002CCB00051560FF60978300603072FFFFCE -:1028200000D240232D18000513000003306400FF80 -:1028300024DFFFFC33E400FF8F8500688F860038BB -:1028400010A60004388F000131ED000115A00138F9 -:10285000000000008F84003C908C00D4358700106D -:10286000A08700D48F85003C8F860064978300602A -:10287000ACA000EC0A001D603062FFFF8CAA00844F -:102880008CB500843C0410000147102400028940EC -:1028900032B4007F0234302500C460253C0880003B -:1028A0002405000102602021240600010E0019DA2F -:1028B000AD0C08300A001CF48F85003C8C8200ECC3 -:1028C0001222FE7E0260202124090005A389006CEB -:1028D0000E001A7B2411FFFF1451FE782404FFFF21 -:1028E0000A001D862403FFFF8F8F00508F88003C55 -:1028F0008DF80000AD1800888DE70010AD07009836 -:102900008F8700640A001DE88F8600582407FFFFA8 -:1029100011870005000000000E001B7D02602021D1 -:102920000A001DC10040A0210E001B0202602021F0 -:102930000A001DC10040A0218F9000503C090800F2 -:102940008D2931B08E11001032323FFF0249682BC1 -:1029500011A0000C240AFF808F85005490AE000D5A -:10296000014E1024304C00FF11800007026020212E -:102970000011C38233030003240B0001106B010517 -:1029800000000000026020212418000D0E001A7BB8 -:10299000A398006C004020218F85003C0A001D6335 -:1029A0000080A0218F9000503C0A08008D4A31B071 -:1029B0008F8500548E0400100000A0218CB10014FB -:1029C00030823FFF004A602B8CB200205180FFEE26 -:1029D0000260202190B8000D240BFF800178702444 -:1029E00031C300FF5060FFE80260202100044382F1 -:1029F0003106000314C0FFE40260202194BF001CD4 -:102A00008F99003C8E060028A73F00E88CAF00108D -:102A1000022F202314C40139026020218F83005823 -:102A200000C36821022D382B14E001352402001860 -:102A30008F8A00488F820034024390218D4B001012 -:102A400001637023AD4E0010AD5200208C4C007419 -:102A50000192282B14A00156026020218F8400547B -:102A60008E0800248C8600241106000702602021B5 -:102A70002419001C0E001A7BA399006C240FFFFF81 -:102A8000104FFFC52404FFFF8F8400488C8700246B -:102A900024FF0001AC9F0024125101338F8D0034BC -:102AA0008DB10074123201303C0B00808E0E00009C -:102AB00001CB502415400075000000008E03001467 -:102AC0002411FFFF10710006026020212418001B52 -:102AD0000E001A7BA398006C1051FFAF2404FFFF77 -:102AE0008E0300003C0800010068302410C0001371 -:102AF0003C0400800064A024168000090200282104 -:102B0000026020212419001A0E001A7BA399006C80 -:102B1000240FFFFF104FFFA02404FFFF0200282115 -:102B2000026020210E001A9B240600012410FFFFE2 -:102B30001050FF992404FFFF241400018F9F0048C8 -:102B4000026020210280302197F100342405000129 -:102B500026270001A7E700340E0019DA0000000064 -:102B6000000020218F85003C0A001D630080A02109 -:102B70008F9000503C1408008E9431B08E070010E6 -:102B800030E83FFF0114302B10C000618F860054E5 -:102B9000241FFF8090C5000D03E52024309200FF24 -:102BA0005240005C026020218F8D005811A0000768 -:102BB00000078B828F85003C8F89FCC094AF00801A -:102BC0009539000A132F00F68F870044322C00033A -:102BD000158000630000000092020002104000D740 -:102BE000000000008E0A0024154000D80260202159 -:102BF0009204000324060002308800FF1506000539 -:102C0000308500FF8F940058528000F2026020212E -:102C1000308500FF38AD00102DA400012CBF00014D -:102C200003E43025020028210E001A9B02602021B7 -:102C30002410FFFF105000BE8F85003C8F8300588A -:102C4000106000C4240500013C1908008F39318C44 -:102C50000323782B15E000B12409002D0260202108 -:102C6000000028210E0019DA240600018F85003C9F -:102C7000000018210A001D630060A0210E0018A6A4 -:102C8000000000000A001E2900000000AC800020A7 -:102C90000A001EA98E0300140000282102602021D2 -:102CA0000E0019DA240600010A001CF48F85003C8E -:102CB0000A001DE88F88003C8CB000848CB9008429 -:102CC0003C0310000207482400096940332F007FAD -:102CD00001AFF82503E32825ACC5083091070001B2 -:102CE00024050001026020210E0019DA30E60001FF -:102CF0000A001CF48F85003C938F004C2403FFFDD9 -:102D00000A001D65AF8F00640A001D652403FFFFE4 -:102D1000026020212410000D0E001A7BA390006C8D -:102D2000004018218F85003C0A001D630060A0212F -:102D30000E0018A600000000978300608F860064D4 -:102D40003070FFFF00D048232D3900051320FE12FC -:102D50008F85003CACA200EC0A001D603062FFFFD2 -:102D600090C3000D307800085700FFA292040003C2 -:102D700002602021240200100E001A7BA382006C46 -:102D80002403FFFF5443FF9B920400030A001F43E8 -:102D90008F85003C90A8000D3106000810C00095FA -:102DA0008F9400581680009E026020218E0F000C28 -:102DB0008CA4002055E40005026020218E1F00082D -:102DC0008CB9002413F9003A02602021240200206B -:102DD0000E001A7BA382006C2405FFFF1045FEEE57 -:102DE0002404FFFF8F8F0048240CFFF72403FF808B -:102DF00091E9000D3C14800E3C0B8000012CC8248E -:102E0000A1F9000D8F8F00343C0708008CE731AC2E -:102E10008F8D007095E500788F99004800ED902126 -:102E200030BF7FFF001F20400244302130C8007FA8 -:102E300000C3C02401147021AD78002CA5D100007E -:102E40008F2A002825420001AF2200288F29002C5C -:102E50008E0C002C012C6821AF2D002C8E07002C2D -:102E6000AF2700308E050014AF250034973F003A9D -:102E700027E40001A724003A95F200783C100800EE -:102E80008E1031B02643000130717FFF1230005C9C -:102E9000006030218F83003402602021240500016E -:102EA0000E001965A46600780A001ED200002021D9 -:102EB0008E0700142412FFFF10F200638F8C003C79 -:102EC0008E0900188D8D00D0152D005D0260202127 -:102ED0008E0A00248CA200281142005324020021F3 -:102EE0000E001A7BA382006C1452FFBE2404FFFF65 -:102EF0008F85003C0A001D630080A0212402001F72 -:102F00000E001A7BA382006C2409FFFF1049FEA269 -:102F10002404FFFF0A001E858F83005802602021D1 -:102F20000E001A7BA389006C1450FF518F85003C62 -:102F30002403FFFF0A001D630060A0218CCE002443 -:102F40008E0B0024116EFF2A026020210A001F57F9 -:102F50002402000F0E001965026020218F85003CBD -:102F60000A001F16000018218E0900003C05008091 -:102F7000012590241640FF452402001A02602021FA -:102F80000E001A7BA382006C240CFFFF144CFECBB6 -:102F90002404FFFF8F85003C0A001D630080A021F0 -:102FA0002403FFFD0060A0210A001D63AF870064B9 -:102FB0002418001D0E001A7BA398006C2403FFFF49 -:102FC0001443FEA62404FFFF8F85003C0A001D6306 -:102FD0000080A0212412002C0E001A7BA392006C0A -:102FE0002403FFFF1043FF508F85003C0A001EFDA5 -:102FF00092040003026020210A001F6D24020024B5 -:10300000240B8000006B702431CAFFFF000A13C23A -:10301000305100FF001180270A001F9E001033C0AE -:103020000A001F6D240200278E0600288CAE002C9B -:1030300010CE0008026020210A001FB12402001FE8 -:103040000A001FB12402000E026020210A001FB1F5 -:10305000240200258E04002C1080000D8F83003484 -:103060008C7800740304582B5560000C02602021FA -:103070008CA800140086A0210114302B10C0FF5A28 -:103080008F8F0048026020210A001FB12402002215 -:10309000026020210A001FB1240200230A001FB190 -:1030A0002402002627BDFFD8AFB3001CAFB1001427 -:1030B000AFBF0020AFB20018AFB000103C028000DC -:1030C0008C5201408C4B01483C048000000B8C0268 -:1030D000322300FF317300FF8C8501B804A0FFFE8E -:1030E00034900180AE1200008C8701442464FFF00C -:1030F000240600022C830013AE070004A61100086A -:10310000A206000BAE1300241060004F8FBF0020FA -:10311000000448803C0A0801254A95D4012A402130 -:103120008D04000000800008000000003C0308003F -:103130008C6331A831693FFF0009998000728021BA -:10314000021370212405FF80264D0100264C0080CB -:103150003C02800031B1007F3198007F31CA007F8E -:103160003C1F800A3C1980043C0F800C01C52024C0 -:1031700001A5302401853824014F1821AC460024D4 -:10318000023F402103194821AC470090AC4400287D -:10319000AF830048AF88003CAF8900340E0019317E -:1031A000016080213C0380008C6B01B80560FFFE4C -:1031B0008F8700488F86003C3465018090E8000DC1 -:1031C000ACB20000A4B000060008260000041603FC -:1031D00000029027001227C21080008124C20088BC -:1031E000241F6082A4BF0008A0A0000524020002E2 -:1031F000A0A2000B8F8B0034000424003C082700A1 -:1032000000889025ACB20010ACA00014ACA0002443 -:10321000ACA00028ACA0002C8D6900382413FF80DE -:10322000ACA9001890E3000D02638024320500FF72 -:1032300010A000058FBF002090ED000D31AC007F85 -:10324000A0EC000D8FBF00208FB3001C8FB20018C0 -:103250008FB100148FB000103C0A10003C0E8000AB -:1032600027BD002803E00008ADCA01B8265F0100B1 -:103270002405FF8033F8007F3C06800003E57824B6 -:103280003C19800A03192021ACCF0024908E00D471 -:1032900000AE682431AC00FF11800024AF84003CF4 -:1032A000248E008895CD00123C0C08008D8C31A82E -:1032B00031AB3FFF01924821000B5180012A402190 -:1032C00001052024ACC400283107007F3C06800C97 -:1032D00000E620219083000D00A31024304500FF5C -:1032E00010A0FFD8AF8400489098000D330F001055 -:1032F00015E0FFD58FBF00200E001931000000003F -:103300003C0380008C7901B80720FFFE000000001C -:10331000AE1200008C7F0144AE1F0004A61100080D -:1033200024110002A211000BAE1300243C1308016B -:1033300092739790327000015200FFC38FBF00203C -:103340000E00216E024020210A00208B8FBF00203A -:103350003C1260008E452C083C03F0033462FFFFF2 -:1033600000A2F824AE5F2C088E582C083C1901C02E -:1033700003199825AE532C080A00208B8FBF00201C -:10338000264D010031AF007F3C10800A240EFF80E3 -:1033900001F0282101AE60243C0B8000AD6C0024BC -:1033A0001660FFA8AF85003C24110003A0B100FC0B -:1033B0000A00208B8FBF002026480100310A007FC1 -:1033C0003C0B800A2409FF80014B30210109202495 -:1033D0003C078000ACE400240A00208AAF86003C51 -:1033E000944E0012320C3FFF31CD3FFF15ACFF7DF4 -:1033F000241F608290D900D42418FF8003197824F8 -:1034000031EA00FF1140FF770000000024070004AC -:10341000A0C700FC8F870048241160842406000D9B -:10342000A4B10008A0A600050A002075240200022D -:103430003C0400012484977C24030014240200FE31 -:103440003C010800AC2431EC3C010800AC2331E81D -:103450003C010801A42297983C0408012484979811 -:103460000000182100643021A0C30004246300017F -:103470002C6500FF54A0FFFC006430213C070800CD -:1034800024E7010003E00008AF87007C00A058217A -:10349000008048210000102114A0001200005021DB -:1034A0000A00216A000000003C010801A42097984E -:1034B0003C05080194A597988F82007C3C0C08017C -:1034C000258C979800E2182100AC2021014B302B6D -:1034D000A089000400001021A460000810C0003979 -:1034E000010048218F86007C0009384000E9402116 -:1034F0000008388000E6282190A8000B90B9000A47 -:103500000008204000881021000218800066C021B9 -:10351000A319000A8F85007C00E5782191EE000A4E -:1035200091E6000B000E684001AE6021000C208087 -:1035300000851021A046000B3C0308019063979280 -:10354000106000222462FFFF8F83003C3C010801D1 -:10355000A0229792906C00FF1180000400000000F0 -:10356000906E00FF25CDFFFFA06D00FF3C19080104 -:1035700097399798272300013078FFFF2F0F00FF1E -:1035800011E0FFC9254A00013C010801A4239798D6 -:103590003C05080194A597988F82007C3C0C08019B -:1035A000258C979800E2182100AC2021014B302B8C -:1035B000A089000400001021A460000814C0FFC905 -:1035C0000100482103E000080000000003E00008BB -:1035D0002402000227BDFFE0248501002407FF80AC -:1035E000AFB00010AFBF0018AFB1001400A718248F -:1035F0003C10800030A4007F3C06800A0086282111 -:103600008E110024AE03002490A200FF1440000895 -:10361000AF85003CA0A000098FBF0018AE110024A8 -:103620008FB100148FB0001003E0000827BD002008 -:1036300090A900FD90A800FF312400FF0E00211C7E -:10364000310500FF8F85003C8FBF0018A0A0000946 -:10365000AE1100248FB100148FB0001003E00008F9 -:1036600027BD002027BDFFD0AFB20020AFB1001CA6 -:10367000AFB00018AFBF002CAFB40028AFB3002428 -:103680003C0980009533011635320C00952F011A44 -:103690003271FFFF023280218E08000431EEFFFFFD -:1036A000248B0100010E6821240CFF8025A5FFFF5B -:1036B000016C50243166007F3C07800AAD2A00244B -:1036C00000C73021AF850078AF8800743C01080145 -:1036D000A020979190C300090200D021008098217A -:1036E000306300FF2862000510400048AF86003CB0 -:1036F000286400021480008E24140001240D0005AB -:103700003C010801A02D977590CC00FD3C010801FB -:10371000A02097763C010801A020977790CB000A63 -:10372000240AFF80318500FF014B4824312700FF28 -:1037300010E0000C000058213C1280083651008037 -:103740008E2F00308CD0005C01F0702305C0018EFC -:103750008F87007490D4000A3284007FA0C4000ACE -:103760008F86003C3C118008363000808E0F003080 -:103770008F87007400EF702319C000EE0000000076 -:1037800090D4000924120002328400FF10920247F4 -:10379000000000008CC2005800E2F82327F9FFFF68 -:1037A0001B2001300000000090C50009240800041F -:1037B00030A300FF10680057240A00013C010801F3 -:1037C000A02A977590C900FF252700013C01080138 -:1037D000A02797743C0308019063977524060005A1 -:1037E0001066006A2C780005130000C400009021C8 -:1037F0000003F8803C0408012484962003E4C821D7 -:103800008F25000000A0000800000000241800FF21 -:103810001078005C0000000090CC000A90CA0009FB -:103820003C080801910897913187008000EA4825FB -:103830003C010801A029977C90C500FD3C140801BB -:1038400092949792311100013C010801A025977DC7 -:1038500090DF00FE3C010801A03F977E90D200FF60 -:103860003C010801A032977F8CD900543C0108012B -:10387000AC3997808CD000583C010801AC3097845B -:103880008CC3005C3C010801AC34978C3C010801FE -:10389000AC239788162000088FBF002C8FB4002817 -:1038A0008FB300248FB200208FB1001C8FB000189E -:1038B00003E0000827BD00303C1180009624010E73 -:1038C0000E000FD43094FFFF3C0B08018D6B9794D2 -:1038D0000260382102802821AE2B01803C130801B0 -:1038E0008E73977401602021240600830E00102F30 -:1038F000AFB300108FBF002C8FB400288FB300240B -:103900008FB200208FB1001C8FB0001803E00008B8 -:1039100027BD00303C1808008F1831FC270F00012C -:103920003C010800AC2F31FC0A0021FF0000000020 -:103930001474FFB900000000A0C000FF3C0508009F -:103940008CA531E43C0308008C6331E03C020800A4 -:103950008C4232048F99003C34A80001241F0002DD -:103960003C010801AC2397943C010801A0289790E2 -:103970003C010801A0229793A33F00090A0021B847 -:103980008F86003C0E00216E000000000A0021FF1F -:103990008F86003C3C1F080193FF97742419000197 -:1039A00013F902298F8700743C1008019210977850 -:1039B0003C06080190C6977610C000050200A021C1 -:1039C0003C04080190849779109001E48F87007C73 -:1039D000001088408F9F007C023048210009C88079 -:1039E000033F702195D80008270F0001A5CF0008DC -:1039F0003C040801908497793C05080190A59776CE -:103A00000E00211C000000008F87007C0230202166 -:103A10000004308000C720218C8500048F8200784C -:103A200000A2402305020006AC8200048C8A00003C -:103A30008F830074014310235C400001AC830000BD -:103A40008F86003C90CB00FF2D6C00025580002D2E -:103A5000241400010230F821001F408001072821B2 -:103A600090B9000B8CAE00040019C04003197821F6 -:103A7000000F1880006710218C4D000001AE8823D4 -:103A80002630FFFF5E00001F241400018C44000458 -:103A90008CAA0000008A482319200019240E000473 -:103AA0003C010801A02E977590AD000B8CAB000473 -:103AB000000D8840022D8021001010800047102149 -:103AC0008C440004016460230582020094430008D2 -:103AD00090DF00FE90B9000B33E500FF54B90004FD -:103AE0000107A021A0D400FE8F87007C0107A02140 -:103AF0009284000B0E00211C240500018F86003CDF -:103B000024140001125400962E50000116000042A9 -:103B10003C08FFFF241900021659FF3F0000000077 -:103B2000A0C000FF8F86003CA0D200090A0021FF40 -:103B30008F86003C90C700092404000230E300FF98 -:103B40001064016F24090004106901528F88007805 -:103B50008CCE0054010E682325B1000106200175AA -:103B6000241800043C010801A03897753C010801A5 -:103B7000A020977490D400FD90D200FF2E4F000239 -:103B800015E0FF14328400FF000438408F89007C68 -:103B900090DF00FF00E41021000220800089C8218E -:103BA0002FE500029324000B14A0FF0A2407000253 -:103BB0000004184000648021001058800169282109 -:103BC0008CAC0004010C50230540FF0200000000F3 -:103BD0003C0308019063977614600005246F000190 -:103BE0003C010801A02497793C010801A0279777A0 -:103BF0003C010801A02F977690CE00FF24E700013A -:103C000031CD00FF01A7882B1220FFE990A4000B03 -:103C10000A0021EE000000003C0508018CA5977405 -:103C20003C12000400A8F82413F200062402000548 -:103C30003C09080191299775152000022402000310 -:103C4000240200053C010801A022979190C700FFC3 -:103C500014E0012024020002A0C200090A0021FF92 -:103C60008F86003C90CC00FF1180FEDA240A000110 -:103C70008F8C00788F89007C240F000301806821DD -:103C80001160001E240E0002000540400105A02125 -:103C900000142080008990218E510004019180231E -:103CA0000600FECC000000003C020801904297761E -:103CB00014400005245800013C010801A02A977710 -:103CC0003C010801A02597793C010801A0389776AE -:103CD00090DF00FF010510210002C88033E500FFDE -:103CE000254A00010329202100AA402B1500FEB916 -:103CF0009085000B1560FFE5000540400005404041 -:103D000001051821000310803C010801A02A9774C6 -:103D10003C010801A0259778004918218C64000413 -:103D200000E4F82327F9FFFF1F20FFE9000000004F -:103D30008C63000000E358230560013A01A3882347 -:103D400010E301170184C0231B00FEA20000000045 -:103D50003C010801A02E97750A00232D240B0001B9 -:103D6000240E0004A0CE00093C0D08008DAD31F8F2 -:103D70008F86003C25A200013C010800AC2231F8EE -:103D80000A0021FF000000008CD9005C00F9C0236C -:103D90001F00FE7B000000008CDF005C10FFFF6551 -:103DA0008F8400788CC3005C0083402325020001CF -:103DB0001C40FF60000000008CC9005C24870001EB -:103DC00000E9282B10A0FE943C0D80008DAB01046F -:103DD0003C0C0001016C50241140FE8F24020010A5 -:103DE0003C010801A02297910A0021FF0000000079 -:103DF0008F9100788F86003C26220001ACC2005CC7 -:103E00000A0022BA241400018F87003C2404FF809A -:103E10000000882190E9000A2414000101243025C3 -:103E2000A0E6000A3C05080190A597763C0408012D -:103E3000908497790E00211C000000008F86003CC2 -:103E40008F85007C90C800FD310700FF00074040CF -:103E50000107F821001FC0800305C8219323000B30 -:103E6000A0C300FD8F85007C8F86003C0305602188 -:103E7000918F000B000F704001CF6821000D8080F2 -:103E8000020510218C4B0000ACCB00548D84000443 -:103E90008F830078006450231940000224820001BF -:103EA0002462000101074821ACC2005C0009308097 -:103EB00000C5402100E02021240500010E00211C46 -:103EC0009110000B8F86003C90C500FF10A0FF0CE6 -:103ED000001070408F85007C01D06821000D10809B -:103EE000004558218D6400008F8C00780184502398 -:103EF0002547000104E0FF02263100013C030801D0 -:103F0000906397762E2F0002247800013C0108016F -:103F1000A03897763C010801A034977711E0FEF8AD -:103F2000020038210A00238D000740408F84003CA6 -:103F30008F8300788C85005800A340230502FE9AE9 -:103F4000AC8300580A002263000000003C0708010F -:103F500090E79792240200FF10E200BE8F86003C9B -:103F60003C1108019631979A3C0308012463979805 -:103F7000262500013230FFFF30ABFFFF0203602136 -:103F80002D6A00FF1540008D918700043C01080157 -:103F9000A420979A8F88003C0007484001272821D9 -:103FA000911800FF0005308024050001271400014E -:103FB000A11400FF3C120801925297928F88007C56 -:103FC0008F8E0074264F000100C820213C0108019B -:103FD000A02F9792AC8E00008F8D0078A4850008EA -:103FE000AC8D00043C030801906397741460007763 -:103FF000000090213C010801A0259774A087000BC8 -:104000008F8C007C00CC5021A147000A8F82003C9D -:10401000A04700FD8F84003CA08700FE8F86003CF7 -:104020008F9F0074ACDF00548F990078ACD9005892 -:104030008F8D007C0127C02100185880016DA021C0 -:10404000928F000A000F704001CF18210003888072 -:10405000022D8021A207000B8F86007C0166602163 -:10406000918A000B000A1040004A20210004288099 -:1040700000A64021A107000A3C07800834E900801F -:104080008D2200308F86003CACC2005C0A0022BA50 -:104090002414000190CA00FF1540FEAD8F880078FF -:1040A000A0C400090A0021FF8F86003CA0C000FDCB -:1040B0008F98003C24060001A30000FE3C0108018B -:1040C000A02697753C010801A02097740A0021EEF4 -:1040D0000000000090CB00FF3C04080190849793FF -:1040E000316C00FF0184502B1540000F24020003A7 -:1040F00024020004A0C200090A0021FF8F86003CB0 -:1041000090C3000A2410FF8002035824316C00FF82 -:104110001180FDC1000000003C010801A02097753E -:104120000A0021EE00000000A0C200090A0021FFE1 -:104130008F86003C90D4000A2412FF800254482449 -:10414000312800FF1500FFF4240200083C0108019B -:10415000A02297910A0021FF000000000010884073 -:104160008F8B0074023018210003688001A7202182 -:10417000AC8B00008F8A0078240C0001A48C00080E -:10418000AC8A00043C05080190A597762402000142 -:1041900010A2FE1E24A5FFFF0A0022799084000BC6 -:1041A0000184A0231A80FD8B000000003C0108015F -:1041B000A02E97750A00232D240B00013C01080155 -:1041C000A425979A0A0023DF8F88003C240B000166 -:1041D000106B00228F98003C8F85003C90BF00FF41 -:1041E00033F900FF1079002B000000003C1F08018C -:1041F00093FF9778001FC840033FC0210018A0809C -:104200000288782191EE000AA08E000A8F8D007C32 -:104210003C0308019063977800CD88210A002405AB -:10422000A223000B263000010600003101A49023D8 -:104230000640002B240200033C010801A02F9775C3 -:104240000A00232D240B00018F89003C0A00226301 -:10425000AD2700540A0022B924120001931400FD76 -:10426000A094000B8F88003C8F8F007C910E00FE85 -:1042700000CF6821A1AE000A8F91003CA22700FD6B -:104280008F8300748F90003CAE0300540A00240614 -:104290008F8D007C90B000FEA090000A8F8B003CB8 -:1042A0008F8C007C916A00FD00CC1021A04A000B8D -:1042B0008F84003CA08700FE8F8600788F85003CAD -:1042C000ACA600580A0024068F8D007C94B8000824 -:1042D000ACA40004030378210A0022ADA4AF0008B7 -:1042E0003C010801A02297750A0021EE00000000A1 -:1042F00090CF0009240D000431EE00FF11CDFD85A3 -:10430000240200013C010801A02297750A0021EE59 -:0443100000000000A9 -:0C43140008003344080033440800342043 -:10432000080033F4080033D8080033280800332885 -:10433000080033280800334C800801008008008002 -:10434000800800005F865437E4AC62CC50103A45D8 -:1043500036621985BF14C0E81BC27A1E84F4B556B4 -:10436000094EA6FE7DDA01E7C04D748108005B3876 -:1043700008005B7C08005B2008005B2008005B20D5 -:1043800008005B2008005B3808005B2008005B2009 -:1043900008005B8408005B2008005A9808005B2036 -:1043A00008005B2008005B8408005B2008005B209D -:1043B00008005B2008005B2008005B2008005B20F1 -:1043C00008005B2008005B2008005B2008005B20E1 -:1043D00008005B5808005B2008005B5808005B2061 -:1043E00008005B2008005B2008005B5C08005B584D -:1043F00008005B2008005B2008005B2008005B20B1 -:1044000008005B2008005B2008005B2008005B20A0 -:1044100008005B2008005B2008005B2008005B2090 -:1044200008005B2008005B2008005B2008005B2080 -:1044300008005B2008005B2008005B2008005B2070 -:1044400008005B5C08005B5C08005B2008005B5CAC -:1044500008005B2008005B2008005B2008005B2050 -:1044600008005B2008005B2008005B2008005B2040 -:1044700008005B2008005B2008005B2008005B2030 -:1044800008005B2008005B2008005B2008005B2020 -:1044900008005B2008005B2008005B2008005B2010 -:1044A00008005B2008005B2008005B2008005B2000 -:1044B00008005B2008005B2008005B2008005B20F0 -:1044C00008005B2008005B2008005B2008005B20E0 -:1044D00008005B2008005B2008005B2008005B20D0 -:1044E00008005B2008005B2008005B2008005B20C0 -:1044F00008005B2008005B2008005B2008005B20B0 -:1045000008005B2008005B2008005B2008005B209F -:1045100008005B2008005B2008005B2008005B208F -:1045200008005B2008005B2008005B2008005B207F -:1045300008005B2008005B2008005B2008005B206F -:1045400008005B2008005B2008005B2008005B205F -:1045500008005B2008005B2008005B2008005B204F -:1045600008005B2008005B2008005B2008005BA0BF -:10457000080078F008007B54080078FC080076F00A -:10458000080078FC08007988080078FC080076F0BC -:10459000080076F0080076F0080076F0080076F063 -:1045A000080076F0080076F0080076F0080076F053 -:1045B000080076F00800791C0800790C080076F0F5 -:1045C000080076F0080076F0080076F0080076F033 -:1045D000080076F0080076F0080076F0080076F023 -:1045E000080076F0080076F0080076F00800790CF4 -:1045F0000800839C08008228080083640800822841 -:1046000008008334080081100800822808008228EE -:1046100008008228080082280800822808008228D2 -:1046200008008228080082280800822808008228C2 -:1046300008008228080082280800825008008DD4D3 -:1046400008008F3008008F100800897808008DEC72 -:104650000A00012400000000000000000000000D1E -:10466000747061362E322E31000000000602010106 -:10467000000000000000000000000000000000003A -:10468000000000000000000000000000000000002A -:10469000000000000000000000000000000000001A -:1046A000000000000000000000000000000000000A -:1046B00000000000000000000000000000000000FA -:1046C00000000000000000000000000000000000EA -:1046D00000000000000000000000000000000000DA -:1046E0000000000010000003000000000000000DAA -:1046F0000000000D3C020800244217203C03080083 -:1047000024632A10AC4000000043202B1480FFFDDE -:10471000244200043C1D080037BD2FFC03A0F021FB -:104720003C100800261004903C1C0800279C172011 -:104730000E000262000000000000000D2402FF8055 -:1047400027BDFFE000821024AFB00010AF42002070 -:10475000AFBF0018AFB10014936500043084007F30 -:10476000034418213C0200080062182130A50020F3 -:10477000036080213C080111277B000814A000027F -:104780002466005C246600589202000497430104EA -:10479000920400043047000F3063FFFF3084004074 -:1047A00000672823108000090000482192020005BC -:1047B00030420004104000050000000010A000037B -:1047C0000000000024A5FFFC24090004920200055B -:1047D00030420004104000120000000010A0001041 -:1047E000000000009602000200A7202101044025DD -:1047F0002442FFFEA7421016920300042402FF8009 -:1048000000431024304200FF104000033C0204002B -:104810000A000174010240258CC20000AF4210184A -:104820008F4201780440FFFE2402000AA7420140A3 -:1048300096020002240400093042000700021023FF -:1048400030420007A7420142960200022442FFFEC6 -:10485000A7420144A740014697420104A7420148EC -:104860008F42010830420020504000012404000122 -:104870009202000430420010144000023483001001 -:1048800000801821A743014A00000000000000003A -:104890000000000000000000AF4810000000000011 -:1048A0000000000000000000000000008F42100027 -:1048B0000441FFFE3102FFFF10400007000000002E -:1048C0009202000430420040144000030000000047 -:1048D0008F421018ACC20000960200063042FFFF63 -:1048E00024420002000210430002104003628821AB -:1048F000962200001120000D3044FFFF00A7102178 -:104900008F8300388F45101C000210820002108037 -:1049100000431021AC45000030A6FFFF0E00058DBE -:1049200000052C0200402021A62200009203000472 -:104930002402FF8000431024304200FF1040001F7B -:104940000000000092020005304200021040001BEF -:10495000000000009742100C2442FFFEA7421016F0 -:10496000000000003C02040034420030AF4210005E -:104970000000000000000000000000000000000037 -:104980008F4210000441FFFE000000009742100C0F -:104990008F45101C3042FFFF24420030000210827D -:1049A00000021080005B1021AC45000030A6FFFF24 -:1049B0000E00058D00052C02A622000096040002C0 -:1049C000248400080E0001E93084FFFF97440104AD -:1049D0000E0001F73084FFFF8FBF00188FB1001465 -:1049E0008FB000103C02100027BD002003E000083B -:1049F000AF4201783084FFFF308200078F850024AA -:104A000010400002248300073064FFF800A4102146 -:104A100030421FFF03421821247B4000AF8500284D -:104A2000AF82002403E00008AF4200843084FFFF1F -:104A30003082000F8F85002C8F86003410400002DA -:104A40002483000F3064FFF000A410210046182BCF -:104A5000AF8500300046202314600002AF82002C96 -:104A6000AF84002C8F82002C340480000342182174 -:104A700000641821AF83003803E00008AF420080D3 -:104A80008F820014104000088F8200048F82FFDCA8 -:104A9000144000058F8200043C02FFBF3442FFFF38 -:104AA000008220248F82000430430006240200028A -:104AB0001062000F3C0201012C620003504000050F -:104AC000240200041060000F3C0200010A000230C2 -:104AD0000000000010620005240200061462000CB1 -:104AE0003C0201110A000229008210253C0200113B -:104AF00000821025AF421000240200010A0002309B -:104B0000AF82000C00821025AF421000AF80000C75 -:104B100000000000000000000000000003E00008AA -:104B2000000000008F82000C104000040000000014 -:104B30008F4210000441FFFE0000000003E0000867 -:104B4000000000008F8200102443F800000231C2F0 -:104B500024C2FFF02C630301106000030002104226 -:104B60000A000257AC8200008F85001800C5102B88 -:104B70001440000B0000182100C510232447000139 -:104B80008F82001C00A210212442FFFF0046102B40 -:104B9000544000042402FFFF0A000257AC870000C3 -:104BA0002402FFFF0A000260AC8200008C82000039 -:104BB00000021940006218210003188000621821C9 -:104BC000000318803C0208002442175C0062182190 -:104BD00003E000080060102127BDFFD8AFBF002010 -:104BE000AFB1001CAFB000183C0460088C825000CC -:104BF0002403FF7F3C066000004310243442380C3D -:104C0000AC8250008CC24C1C3C1A80000002160280 -:104C10003042000F10400007AF82001C8CC34C1CB8 -:104C20003C02001F3442FC0000621824000319C239 -:104C3000AF8300188F420008275B40003442000118 -:104C4000AF420008AF8000243C02601CAF400080EF -:104C5000AF4000848C4500088CC3080834028000F3 -:104C6000034220212402FFF0006218243C0200804D -:104C70003C010800AC2204203C025709AF840038F4 -:104C800014620004AF850034240200010A0002927D -:104C9000AF820014AF8000148F4200003842000140 -:104CA000304200011440FFFC8F82001410400016B7 -:104CB0000000000097420104104000058F830000AF -:104CC000146000072462FFFF0A0002A72C62000A9A -:104CD0002C620010504000048F8300002462000109 -:104CE000AF8200008F8300002C62000A1440000392 -:104CF0002C6200070A0002AEAF80FFDC1040000209 -:104D000024020001AF82FFDC8F4301088F440100C1 -:104D100030622000AF83000410400008AF84001010 -:104D20003C0208008C42042C244200013C01080093 -:104D3000AC22042C0A00058A3C02400030650200C7 -:104D400014A0000324020F001482026024020D004C -:104D500097420104104002C83C024000306240000B -:104D6000144000AD8F8200388C4400088F420178D7 -:104D70000440FFFE24020800AF420178240200082C -:104D8000A7420140A7400142974201048F840004DA -:104D90003051FFFF308200011040000702208021C7 -:104DA0002623FFFE240200023070FFFFA7420146C7 -:104DB0000A0002DBA7430148A74001463C02080065 -:104DC0008C42043C1440000D8F8300103082002080 -:104DD0001440000224030009240300010060202184 -:104DE0008F83001024020900506200013484000403 -:104DF000A744014A0A0002F60000000024020F0046 -:104E00001462000530820020144000062403000DC7 -:104E10000A0002F5240300051440000224030009DF -:104E200024030001A743014A3C0208008C420420ED -:104E30003C0400480E00020C004420250E00023500 -:104E4000000000008F82000C1040003E00000000B7 -:104E50008F4210003C030020004310241040003912 -:104E60008F82000430420002104000360000000033 -:104E700097421014144000330000000097421008BD -:104E80008F8800383042FFFF24420006000218825B -:104E90000003388000E83021304300018CC400005A -:104EA00010600004304200030000000D0A000337C8 -:104EB00000E81021544000103084FFFF3C05FFFF44 -:104EC00000852024008518260003182B0004102BD1 -:104ED0000043102410400005000000000000000006 -:104EE0000000000D00000000240002228CC200001F -:104EF0000A000336004520253883FFFF0003182BE6 -:104F00000004102B00431024104000050000000096 -:104F1000000000000000000D000000002400022B33 -:104F20008CC200003444FFFF00E81021AC440000B4 -:104F30003C0208008C420430244200013C0108007D -:104F4000AC2204308F6200008F840038AF820008EA -:104F50008C8300003402FFFF1462000F0000102158 -:104F60003C0508008CA504543C0408008C840450C3 -:104F700000B0282100B0302B0082202100862021A3 -:104F80003C010800AC2504543C010800AC2404504A -:104F90000A000580240400088C82000030420100D1 -:104FA0001040000F000010213C0508008CA5044CA7 -:104FB0003C0408008C84044800B0282100B0302B49 -:104FC00000822021008620213C010800AC25044CF1 -:104FD0003C010800AC2404480A00058024040008B1 -:104FE0003C0508008CA504443C0408008C84044063 -:104FF00000B0282100B0302B008220210086202123 -:105000003C010800AC2504443C010800AC240440E9 -:105010000A000580240400088F6200088F620000E7 -:1050200000021602304300F0240200301062000536 -:1050300024020040106200E08F8200200A000588F0 -:105040002442000114A00005000000000000000040 -:105050000000000D00000000240002568F4201787D -:105060000440FFFE000000000E00023D27A40010D7 -:105070001440000500408021000000000000000DE9 -:10508000000000002400025D8E02000010400005B8 -:1050900000000000000000000000000D0000000003 -:1050A000240002608F62000C04430003240200010C -:1050B0000A00042EAE000000AE0200008F8200380D -:1050C0008C480008A20000078F65000C8F64000464 -:1050D00030A3FFFF0004240200852023308200FF5C -:1050E0000043102124420005000230832CC20081BD -:1050F000A605000A14400005A204000400000000F8 -:105100000000000D00000000240002788F850038A8 -:105110000E0005AB260400148F6200048F430108C3 -:10512000A60200083C02100000621824106000086B -:105130000000000097420104920300072442FFECA4 -:10514000346300023045FFFF0A0003C3A2030007D7 -:10515000974201042442FFF03045FFFF9606000805 -:105160002CC200135440000592030007920200076E -:1051700034420001A202000792030007240200014A -:1051800010620005240200031062000B8F820038B9 -:105190000A0003E030C6FFFF8F8200383C04FFFFA7 -:1051A0008C43000C0064182400651825AC43000CE7 -:1051B0000A0003E030C6FFFF3C04FFFF8C430010F1 -:1051C0000064182400651825AC43001030C6FFFFAA -:1051D00024C2000200021083A20200058F8300385F -:1051E000304200FF00021080004328218CA80000FC -:1051F0008CA20000240300040002170214430012D2 -:1052000000000000974201043C03FFFF0103182443 -:105210003042FFFF004610232442FFFE006240257B -:10522000ACA8000092030005306200FF000210806D -:1052300000501021904200143042000F0043102112 -:105240000A000415A20200068CA40004974201047F -:105250009603000A3088FFFF3042FFFF004610230C -:105260002442FFD60002140001024025ACA800042D -:1052700092020007920400052463002800031883AB -:105280000064182134420004A2030006A2020007B1 -:105290008F8200042403FFFB3442000200431024E9 -:1052A000AF820004920300068F8700380003188045 -:1052B000007010218C4400203C02FFF63442FFFFB6 -:1052C0000082402400671821AE04000CAC68000C7A -:1052D000920500063C03FF7F8E02000C000528802B -:1052E00000B020213463FFFF01033024948800269E -:1052F00000A7282100431024AE02000CAC86002039 -:10530000AC880024ACA8001024020010A742014081 -:1053100024020002A7400142A7400144A7420146DF -:10532000974201043C0400082442FFFEA7420148C2 -:10533000240200010E00020CA742014A9603000A53 -:105340009202000400431021244200023042000770 -:1053500000021023304200070E000235AE0200109A -:105360008F6200003C0308008C6304442404001096 -:10537000AF820008974201043042FFFF2442FFFE43 -:1053800000403821000237C33C0208008C42044030 -:10539000006718210067282B0046102100451021C6 -:1053A0003C010800AC2304443C010800AC2204404A -:1053B0000A0005150000000014A000050000000010 -:1053C000000000000000000D000000002400030A9F -:1053D0008F4201780440FFFE000000000E00023DF5 -:1053E00027A40014144000050040802100000000A4 -:1053F0000000000D00000000240003118E020000D8 -:105400005440000692020007000000000000000D5A -:10541000000000002400031C920200073042000438 -:10542000104000058F8200042403FFFB3442000279 -:1054300000431024AF8200048F620004044300087C -:1054400092020007920200068E03000CAE000000DC -:105450000002108000501021AC430020920200078F -:1054600030420004544000099602000A92020005EE -:105470003C03000100021080005010218C460018EF -:1054800000C33021AC4600189602000A92060004C0 -:10549000277100080220202100C2302124C6000507 -:1054A000260500140E0005AB0006308292040006AB -:1054B0008F6500043C027FFF0004208000912021C2 -:1054C0008C8300043442FFFF00A2282400651821C9 -:1054D000AC830004920200079204000592030004CA -:1054E000304200041040001496070008308400FF8A -:1054F00000042080009120218C8600049742010442 -:105500009605000A306300FF3042FFFF0043102180 -:105510000045102130E3FFFF004310232442FFD851 -:1055200030C6FFFF0002140000C23025AC86000424 -:105530000A0004C992030007308500FF0005288097 -:1055400000B128218CA4000097420104306300FFC1 -:105550003042FFFF00431021004710233C03FFFFB0 -:10556000008320243042FFFF00822025ACA40000ED -:1055700092030007240200011062000600000000F0 -:105580002402000310620011000000000A0004EC75 -:105590008E03001097420104920300049605000A4E -:1055A0008E24000C00431021004510212442FFF2FC -:1055B0003C03FFFF008320243042FFFF00822025B0 -:1055C000AE24000C0A0004EC8E0300109742010484 -:1055D000920300049605000A8E2400100043102157 -:1055E000004510212442FFEE3C03FFFF00832024EE -:1055F0003042FFFF00822025AE2400108E030010F1 -:105600002402000AA7420140A74301429603000A70 -:10561000920200043C04004000431021A7420144D0 -:10562000A740014697420104A74201482402000115 -:105630000E00020CA742014A0E00023500000000D5 -:105640008F6200009203000400002021AF82000856 -:10565000974201049606000A3042FFFF00621821BB -:10566000006028213C0308008C6304443C020800CD -:105670008C42044000651821004410210065382B3D -:10568000004710213C010800AC2304443C01080001 -:10569000AC22044092040004008620212484000AE5 -:1056A0003084FFFF0E0001E9000000009744010470 -:1056B0003084FFFF0E0001F7000000003C021000E4 -:1056C000AF4201780A0005878F82002014820027EC -:1056D0003062000697420104104000673C0240001F -:1056E0003062400010400005000000000000000093 -:1056F0000000000D00000000240004208F4201780B -:105700000440FFFE24020800AF4201782402000892 -:10571000A7420140A74001428F8200049743010441 -:1057200030420001104000073070FFFF2603FFFEEB -:1057300024020002A7420146A74301480A00053F90 -:105740002402000DA74001462402000DA742014A91 -:105750008F62000024040008AF8200080E0001E9F7 -:10576000000000000A00051902002021104000423C -:105770003C02400093620000304300F0240200101D -:105780001062000524020070106200358F82002034 -:105790000A000588244200018F620000974301043B -:1057A0003050FFFF3071FFFF8F4201780440FFFE51 -:1057B0003202000700021023304200072403000ACF -:1057C0002604FFFEA7430140A7420142A74401442B -:1057D000A7400146A75101488F42010830420020EE -:1057E000144000022403000924030001A743014AD6 -:1057F0000E00020C3C0400400E00023500000000C8 -:105800003C0708008CE70444021110212442FFFEEB -:105810003C0608008CC604400040182100E33821F3 -:10582000000010218F65000000E3402B00C23021F2 -:105830002604000800C830213084FFFFAF8500082F -:105840003C010800AC2704443C010800AC2604409D -:105850000E0001E9000000000A00051902202021C5 -:105860000E00013B000000008F8200202442000156 -:10587000AF8200203C024000AF4201380A00029291 -:10588000000000003084FFFF30C6FFFF00052C0041 -:1058900000A628253882FFFF004510210045282B4F -:1058A0000045102100021C023042FFFF004310217E -:1058B00000021C023042FFFF004310213842FFFF6C -:1058C00003E000083042FFFF3084FFFF30A5FFFFF8 -:1058D0000000182110800007000000003082000145 -:1058E0001040000200042042006518210A0005A1B2 -:1058F0000005284003E000080060102110C00006E9 -:1059000024C6FFFF8CA2000024A50004AC82000086 -:105910000A0005AB2484000403E000080000000036 -:1059200010A0000824A3FFFFAC86000000000000C8 -:10593000000000002402FFFF2463FFFF1462FFFA4F -:0C5940002484000403E0000800000000C4 -:04594C000000000156 -:105950000A00002A00000000000000000000000D06 -:10596000747870362E322E310000000006020100DD -:1059700000000000000001360000EA6000000000A6 -:105980000000000000000000000000000000000017 -:105990000000000000000000000000000000000007 -:1059A00000000000000000000000000000000000F7 -:1059B00000000016000000000000000000000000D1 -:1059C00000000000000000000000000000000000D7 -:1059D00000000000000000000000000000000000C7 -:1059E000000000000000000000001388000000001C -:1059F000000005DC000000000000000010000003B3 -:105A0000000000000000000D0000000D3C02080036 -:105A100024423D883C0308002463403CAC40000025 -:105A20000043202B1480FFFD244200043C1D08008D -:105A300037BD7FFC03A0F0213C100800261000A811 -:105A40003C1C0800279C3D880E00044E000000000E -:105A50000000000D27BDFFB4AFA10000AFA20004FD -:105A6000AFA30008AFA4000CAFA50010AFA60014B0 -:105A7000AFA70018AFA8001CAFA90020AFAA002450 -:105A8000AFAB0028AFAC002CAFAD0030AFAE0034F0 -:105A9000AFAF0038AFB8003CAFB90040AFBC004476 -:105AA000AFBF00480E000591000000008FBF004806 -:105AB0008FBC00448FB900408FB8003C8FAF0038D6 -:105AC0008FAE00348FAD00308FAC002C8FAB002830 -:105AD0008FAA00248FA900208FA8001C8FA7001870 -:105AE0008FA600148FA500108FA4000C8FA30008B0 -:105AF0008FA200048FA1000027BD004C3C1B600456 -:105B00008F7A5030377B502803400008AF7A00006E -:105B10008F86003C3C0390003C02800000862825D4 -:105B200000A32025AC4400203C0380008C670020AB -:105B300004E0FFFE0000000003E000080000000099 -:105B40000A000070240400018F85003C3C048000A2 -:105B50003483000100A3102503E00008AC8200207C -:105B600003E00008000010213084FFFF30A5FFFF94 -:105B70001080000700001821308200011040000250 -:105B800000042042006518211480FFFB0005284016 -:105B900003E000080060102110C0000700000000B2 -:105BA0008CA2000024C6FFFF24A50004AC820000E4 -:105BB00014C0FFFB2484000403E000080000000080 -:105BC00010A0000824A3FFFFAC8600000000000026 -:105BD000000000002402FFFF2463FFFF1462FFFAAD -:105BE0002484000403E000080000000090AA0031B3 -:105BF0008FAB00108CAC00403C0300FF8D680004AC -:105C0000AD6C00208CAD004400E060213462FFFFE9 -:105C1000AD6D00248CA700483C09FF000109C02499 -:105C2000AD6700288CAE004C0182C824031978258A -:105C3000AD6F0004AD6E002C8CAD0038314A00FF12 -:105C4000AD6D001C94A900323128FFFFAD68001033 -:105C500090A70030A5600002A1600004A1670000C9 -:105C600090A30032306200FF00021982106000052C -:105C7000240500011065000E0000000003E000088C -:105C8000A16A00018CD80028354A0080AD78001840 -:105C90008CCF0014AD6F00148CCE0030AD6E0008B8 -:105CA0008CC4002CA16A000103E00008AD64000C64 -:105CB0008CCD001CAD6D00188CC90014AD690014AA -:105CC0008CC80024AD6800088CC70020AD67000CAC -:105CD0008CC200148C8300700043C82B1320000773 -:105CE000000000008CC20014144CFFE4000000000F -:105CF000354A008003E00008A16A00018C82007030 -:105D00000A0000E6000000009089003027BDFFF87F -:105D10008FA8001CA3A900008FA300003C0DFF80EA -:105D200035A2FFFF8CAC002C00625824AFAB000002 -:105D3000A100000400C05821A7A000028D060004A5 -:105D400000A048210167C8218FA5000000805021D4 -:105D50003C18FF7F032C20263C0E00FF2C8C0001FA -:105D6000370FFFFF35CDFFFF3C02FF0000AFC82417 -:105D700000EDC02400C27824000C1DC00323682558 -:105D800001F87025AD0D0000AD0E00048D24002437 -:105D9000AFAD0000AD0400088D2C00202404FFFFEF -:105DA000AD0C000C9547003230E6FFFFAD06001049 -:105DB0009145004830A200FF000219C25060000166 -:105DC0008D240034AD0400148D4700388FAA0018CC -:105DD00027BD0008AD0B0028AD0A0024AD07001C4C -:105DE000AD00002CAD00001803E00008AD0000205D -:105DF00027BDFFE0AFB20018AFB10014AFB0001084 -:105E0000AFBF001C9098003000C088213C0D00FFFF -:105E1000330F007FA0CF0000908E003135ACFFFF24 -:105E20003C0AFF00A0CE000194A6001EA2200004A0 -:105E30008CAB00148E29000400A08021016C282462 -:105E4000012A40240080902101052025A626000279 -:105E5000AE24000426050020262400080E0000922F -:105E6000240600029247003026050028262400144C -:105E700000071E000003160324060004044000036C -:105E80002403FFFF965900323323FFFF0E000092D8 -:105E9000AE230010262400248FBF001C8FB20018F0 -:105EA0008FB100148FB000102405000300003021D2 -:105EB0000A00009C27BD002027BDFFD8AFB1001C01 -:105EC000AFB00018AFBF002090A90030240200013D -:105ED00000E050213123003F00A040218FB000405E -:105EE0000080882100C04821106200148FA700386C -:105EF000240B000500A0202100C02821106B0013F6 -:105F0000020030210E000128000000009225007CD4 -:105F100030A400021080000326030030AE000030E1 -:105F2000260300348FBF00208FB1001C8FB00018F3 -:105F30000060102103E0000827BD00280E0000A724 -:105F4000AFB000100A00016F000000008FA3003CFA -:105F5000010020210120282101403021AFA30010A1 -:105F60000E0000EEAFB000140A00016F0000000048 -:105F70003C06800034C20E008C4400108F85004423 -:105F8000ACA400208C43001803E00008ACA300245C -:105F90003C06800034C20E008C4400148F850044FF -:105FA000ACA400208C43001C03E00008ACA3002438 -:105FB0009382000C1040001B2483000F2404FFF088 -:105FC0000064382410E00019978B00109784000EAD -:105FD0009389000D3C0A601C0A0001AC0164402357 -:105FE00001037021006428231126000231C2FFFF43 -:105FF00030A2FFFF0047302B50C0000E00E44821C4 -:106000008D4D000C31A3FFFF00036400000C2C0336 -:1060100004A1FFF30000302130637FFF0A0001A4D8 -:106020002406000103E00008000000009784000E31 -:1060300000E448213123FFFF3168FFFF0068382B5F -:1060400054E0FFF8A783000E938A000D114000056D -:10605000240F0001006BC023A380000D03E00008A3 -:10606000A798000E006BC023A38F000D03E000086B -:10607000A798000E03E000080000000027BDFFE81D -:10608000AFB000103C10800036030140308BFFFFA2 -:1060900093AA002BAFBF0014A46B000436040E00BB -:1060A0009488001630C600FF8FA90030A46800064F -:1060B000AC650008A0660012A46A001AAC67002054 -:1060C0008FA5002CA4690018012020210E00019842 -:1060D000AC6500143C021000AE0201788FBF0014C2 -:1060E0008FB0001003E0000827BD00188F85000066 -:1060F0002484000727BDFFF83084FFF83C068000A9 -:1061000094CB008A316AFFFFAFAA00008FA900007C -:10611000012540232507FFFF30E31FFF0064102BFC -:106120001440FFF700056882000D288034CC400041 -:1061300000AC102103E0000827BD00088F8200009A -:106140002486000730C5FFF800A2182130641FFF25 -:1061500003E00008AF8400008F87003C8F84004478 -:1061600027BDFFB0AFB70044AFB40038AFB1002CCB -:10617000AFBF0048AFB60040AFB5003CAFB300348E -:10618000AFB20030AFB000283C0B80008C860024FA -:10619000AD6700808C8A002035670E0035690100EC -:1061A000ACEA00108C8800248D2500040000B82182 -:1061B000ACE800188CE3001000A688230000A021A2 -:1061C000ACE300148CE20018ACE2001C122000FECC -:1061D00000E0B021936C0008118000F40000000082 -:1061E000976F001031EEFFFF022E682B15A000EF15 -:1061F00000000000977200103250FFFFAED0000088 -:106200003C0380008C740000329300081260FFFD94 -:106210000000000096D800088EC700043305FFFF79 -:1062200030B5000112A000E4000000000000000DE5 -:1062300030BFA0402419004013F9011B30B4A00066 -:10624000128000DF00000000937300081260000855 -:1062500000000000976D001031ACFFFF00EC202B18 -:106260001080000330AE004011C000D500000000D7 -:10627000A7850040AF8700389363000802202821DB -:10628000AFB10020146000F527B40020AF60000C0F -:10629000978F004031F140001620000224030016C1 -:1062A0002403000E24054007A363000AAF65001411 -:1062B000938A00428F70001431550001001512407E -:1062C00002024825AF690014979F00408F780014A0 -:1062D00033F9001003194025AF680014979200406D -:1062E0003247000810E0016E000000008F670014C4 -:1062F0003C1210003C11800000F27825AF6F0014B2 -:1063000036230E00946E000A3C0D81002406000E18 -:1063100031CCFFFF018D2025AF640004A36600028D -:106320009373000A3406FFFC266B0004A36B000A7B -:1063300097980040330820001100015F0000000022 -:106340003C05800034A90E00979900409538000C58 -:1063500097870040001940423312C0003103000308 -:1063600000127B0330F11000006F682500117203EA -:1063700001AE6025000C20C0A76400129793004076 -:10638000936A000A001359823175003C02AA102159 -:106390002450003CA3700009953F000C33F93FFFE7 -:1063A000A779001097700012936900090130F82155 -:1063B00027E5000230B900070019C02333080007A1 -:1063C000A368000B9371000997720012976F001079 -:1063D000322700FF8F910038978D004000F218217E -:1063E000006F702101C6602131A6004010C0000579 -:1063F0003185FFFF00B1102B3C12800010400017C8 -:10640000000098210225A82B56A0013E8FA5002050 -:106410003C048000348A0E008D5300143C0680003A -:10642000AD5300108D4B001CAD4B0018AD45000066 -:106430008CCD000031AC00081180FFFD34CE0E0081 -:1064400095C3000800A0882100009021A783004088 -:106450008DC6000424130001AF860038976F00102A -:1064600031F5FFFF8E9F000003F1282310A0011FCC -:10647000AE85000093620008144000DD00000000BB -:106480000E0001E7240400108F90004800402821EE -:106490003C023200320600FF000654000142F8259B -:1064A00026090001AF890048ACBF000093790009BC -:1064B00097780012936F000A332800FF3303FFFF21 -:1064C0000103382100076C0031EE00FF01AE6025AA -:1064D000ACAC00048F840048978B0040316A2000E8 -:1064E0001140010AACA4000897640012308BFFFF32 -:1064F00006400108ACAB000C978E004031C5000887 -:1065000014A0000226280006262800023C1F800056 -:1065100037E70E0094F900148CE5001C8F67000427 -:10652000937800023324FFFF330300FFAFA3001072 -:106530008F6F0014AFA800180E0001CBAFAF00148E -:10654000240400100E0001FB000000008E920000E9 -:1065500016400005000000008F7800142403FFBFE0 -:106560000303A024AF7400148F67000C00F5C8214A -:10657000AF79000C9375000816A000080000000019 -:1065800012600006000000008F6800143C0AEFFF54 -:106590003549FFFE0109F824AF7F0014A3730008FA -:1065A0008FA500200A00034F02202021AED1000059 -:1065B0000A00022D3C03800014E0FF1E30BFA04003 -:1065C0000E0001900000A0212E9100010237B0259D -:1065D00012C000188FBF00488F87003C24170F009F -:1065E00010F700D43C0680008CD901780720FFFE0C -:1065F000241F0F0010FF00F634CA0E008D56001441 -:1066000034C7014024080240ACF600048D49001C48 -:106610003C141000ACE90008A0E00012A4E0001A4D -:10662000ACE00020A4E00018ACE80014ACD4017881 -:106630008FBF00488FB700448FB600408FB5003C35 -:106640008FB400388FB300348FB200308FB1002C7C -:106650008FB0002803E0000827BD00508F9100385C -:10666000978800403C1280000220A821310700409A -:1066700014E0FF7C00009821977900108F92003879 -:106680003338FFFF131200A8000020210080A02152 -:10669000108000F300A088211620FECE000000002C -:1066A0000A00031F2E9100013C0380008C620178D8 -:1066B0000440FFFE240808008F860000AC680178C3 -:1066C0003C038000946D008A31ACFFFF01865823A3 -:1066D000256AFFFF31441FFF2C8900081520FFF9B0 -:1066E000000000008F8F0048347040008F83003C12 -:1066F00000E0A021240E0F0025E70001AF8700482D -:1067000000D03021023488233C08800031F500FF9E -:10671000106E000524070001939800423313000116 -:106720000013924036470001001524003C0A010086 -:10673000008A4825ACC900008F82004830BF00366F -:1067400030B90008ACC200041320009900FF98255E -:1067500035120E009650000A8F8700003C0F810012 -:106760003203FFFF24ED000835060140006F60256D -:106770003C0E100031AB1FFF269200062405000ED0 -:10678000ACCC0020026E9825A4C5001AAF8B000087 -:10679000A4D20018162000083C1080008F89003C0D -:1067A00024020F005122000224170001367300401A -:1067B0000E0001883C10800036060E008CCB0014C1 -:1067C000360A014002402021AD4B00048CC5001C5C -:1067D000AD450008A1550012AD5300140E000198FC -:1067E0003C151000AE1501780A00035200000000AD -:1067F000936F0009976E0012936D000B31E500FF57 -:1068000000AE202131AC00FF008C80212602000A5E -:106810003050FFFF0E0001E7020020218F86004864 -:106820003C0341003C05800024CB0001AF8B0048B5 -:10683000936A00099769001230C600FF315F00FFBC -:106840003128FFFF03E8382124F900020006C400C4 -:106850000319782501E37025AC4E00008F6D000C04 -:1068600034A40E00948B001401B26025AC4C0004DB -:106870008C85001C8F670004936A00023164FFFF5F -:10688000314900FFAFA900108F680014AFB10018A4 -:106890000E0001CBAFA800140A0002FD0200202167 -:1068A000AF600004A3600002979800403308200006 -:1068B0001500FEA300003021A7600012978400405D -:1068C000936B000A3C10800030931F00001351832B -:1068D000014BA82126A20028A362000936090E0058 -:1068E000953F000C0A000295A77F00108F700014DE -:1068F000360900400E000188AF6900140A0002C981 -:10690000000000000A00034F000020210641FEFAAB -:10691000ACA0000C8CAC000C3C0D8000018D9025CF -:106920000A0002EAACB2000C000090210A0002C585 -:1069300024130001128000073C028000344B0E003B -:106940009566000830D30040126000490000000046 -:106950003C0680008CD001780600FFFE34C50E0096 -:1069600094B500103C03050034CC014032B8FFFF61 -:1069700003039025AD92000C8CAF0014240D200071 -:106980003C041000AD8F00048CAE001CAD8E0008DE -:10699000A1800012A580001AAD800020A5800018FB -:1069A000AD8D0014ACC401780A0003263C068000BB -:1069B0008F9F0000351801402692000227F9000839 -:1069C00033281FFFA71200180A000391AF880000A8 -:1069D0003C02800034450140ACA0000C1280001B3A -:1069E00034530E0034510E008E370010ACB7000443 -:1069F0008E2400183C0B8000ACA4000835700140C8 -:106A000024040040A20000128FBF0048A600001A14 -:106A10008FB70044AE0000208FB60040A6000018DB -:106A20008FB5003CAE0400148FB400388FB300342F -:106A30008FB200308FB1002C8FB000283C021000C4 -:106A400027BD005003E00008AD6201788E66001497 -:106A5000ACA600048E64001C0A00042A3C0B8000D3 -:106A60000E0001902E9100010A0003200237B0258C -:106A7000000000000000000D000000002400036979 -:106A80000A0004013C06800027BDFFD8AFBF0020EC -:106A90003C0980003C1F20FFAFB200183C0760009B -:106AA00035320E002402001037F9FFFDACE2300849 -:106AB000AFB3001CAFB10014AFB00010AE5900006E -:106AC00000000000000000000000000000000000C6 -:106AD000000000003C1800FF3713FFFDAE5300001C -:106AE0003C0B60048D7050002411FF7F3C0E0002AF -:106AF0000211782435EC380C35CD0109ACED4C1879 -:106B0000240A0009AD6C50008CE80438AD2A000856 -:106B1000AD2000148CE54C1C3106FFFF38C42F71EA -:106B200000051E023062000F2486C0B3104000072B -:106B3000AF8200088CE54C1C3C09001F3528FC0086 -:106B400000A81824000321C2AF8400048CF10808B7 -:106B50003C0F57092412F0000232702435F0001067 -:106B600001D0602601CF68262DAA00012D8B0001DF -:106B7000014B382550E00009A380000C3C1F601C2D -:106B80008FF8000824190001A399000C33137C002E -:106B9000A7930010A780000EA380000DAF800048CF -:106BA00014C00003AF8000003C066000ACC0442C61 -:106BB0000E0005B93C1080000E000F2436110100B4 -:106BC0003C12080026523DF03C13080026733E702C -:106BD0008E03000038640001308200011440FFFC85 -:106BE0003C0B800A8E2600002407FF8024C9024047 -:106BF000312A007F014B402101272824AE060020C6 -:106C0000AF880044AE0500243C048000AF86003C01 -:106C10008C8C01780580FFFE24180800922F000854 -:106C2000AC980178A38F0042938E004231CD0001D1 -:106C300011A0000F24050D0024DFF8002FF9030137 -:106C40001320001C000629C224A4FFF000041042F7 -:106C5000000231400E00020200D2D8213C02400066 -:106C60003C068000ACC201380A0004A0000000000D -:106C700010C50023240D0F0010CD00273C1F8008F5 -:106C800037F9008093380000240E0050330F00FFC6 -:106C900015EEFFF33C0240000E000A400000000029 -:106CA0003C0240003C068000ACC201380A0004A04F -:106CB000000000008F83000400A3402B1500000B90 -:106CC0008F8B0008006B50212547FFFF00E5482B04 -:106CD0001520000600A36023000C19400E000202DC -:106CE0000073D8210A0004C43C0240000000000DDB -:106CF0000E000202000000000A0004C43C02400032 -:106D00003C1B0800277B3F700E00020200000000C1 -:106D10000A0004C43C0240003C1B0800277B3F9053 -:106D20000E000202000000000A0004C43C02400001 -:106D30003C0660043C09080025290104ACC9502C1C -:106D40008CC850003C0580003C02000235070080E2 -:106D5000ACC750003C040800248415A43C03080080 -:106D60002463155CACA50008ACA2000C3C01080033 -:106D7000AC243D803C010800AC233D8403E00008C6 -:106D80002402000100A030213C1C0800279C3D8803 -:106D90003C0C04003C0B0002008B3826008C402683 -:106DA0002CE200010007502B2D050001000A48804D -:106DB0003C03080024633D80004520250123182161 -:106DC0001080000300001021AC66000024020001C6 -:106DD00003E00008000000003C1C0800279C3D88E0 -:106DE0003C0B04003C0A0002008A3026008B382647 -:106DF0002CC200010006482B2CE500010009408050 -:106E00003C03080024633D80004520250103182130 -:106E100010800005000010213C0C0800258C155C3A -:106E2000AC6C00002402000103E000080000000038 -:106E30003C0900023C0804000088302600893826FE -:106E40002CC30001008028212CE4000100831025C0 -:106E50001040000B000030213C1C0800279C3D889E -:106E60003C0A80008D4E00082406000101CA6825F6 -:106E7000AD4D00088D4C000C01855825AD4B000C24 -:106E800003E0000800C010213C1C0800279C3D883E -:106E90003C0580008CA6000C000420272402000181 -:106EA00000C4182403E00008ACA3000C3C0200025C -:106EB0001082000B3C0560003C07040010870003B3 -:106EC0000000000003E00008000000008CA908D0CA -:106ED000240AFFFD012A402403E00008ACA808D0E2 -:106EE0008CA408D02406FFFE0086182403E00008C6 -:106EF000ACA308D03C05601A34A600108CC30080F7 -:106F000027BDFFF88CC50084AFA3000093A4000048 -:106F10002402000110820003AFA5000403E0000872 -:106F200027BD000893A7000114E0001497AC0002ED -:106F300097B800023C0F8000330EFFFC01CF6821A0 -:106F4000ADA50000A3A000003C0660008CC708D0DF -:106F50002408FFFE3C04601A00E82824ACC508D0D1 -:106F60008FA300048FA200003499001027BD0008F1 -:106F7000AF22008003E00008AF2300843C0B8000B8 -:106F8000318AFFFC014B48218D2800000A00057D55 -:106F9000AFA8000427BDFFE8AFBF00103C1C0800ED -:106FA000279C3D883C0580008CA4000C8CA200042A -:106FB0003C0300020044282410A0000A00A3182467 -:106FC0003C0604003C0400021460000900A61024E2 -:106FD0001440000F3C0404000000000D3C1C08009D -:106FE000279C3D888FBF001003E0000827BD0018D4 -:106FF0003C0208008C423D800040F809000000007F -:107000003C1C0800279C3D880A0005A68FBF001085 -:107010003C0208008C423D840040F809000000005A -:107020000A0005AC00000000000411C003E00008E5 -:10703000244202403C04080024843FD42405001A62 -:107040000A00009C0000302127BDFFE0AFB0001017 -:107050003C108000AFBF0018AFB100143611010022 -:10706000922200090E0005B63044007F8E3F0000DA -:107070008F89003C3C0F008003E26021258800409E -:107080000049F821240DFF80310E007831980078F6 -:1070900035F9000135F100020319382501D14825E1 -:1070A000010D302403ED5824018D2824240A0040CA -:1070B00024040080240300C0AE0B0024AE0008109E -:1070C000AE0A0814AE040818AE03081CAE05080486 -:1070D000AE070820AE060808AE09082436090900E4 -:1070E0009539000C3605098033ED007F3338FFFFFA -:1070F000001889C0AE110800AE0F0828952C000CAE -:107100008FBF00188FB10014318BFFFF000B51C0EF -:10711000AE0A002C8CA400508FB000108CA3003C51 -:107120008D2700048CA8001C8CA600383C0E800A19 -:1071300001AE102127BD0020AF820044AF84005073 -:10714000AF830054AF87004CAF88005C03E00008B9 -:10715000AF8600603C09080091293FF924A800028D -:107160003C05110000093C0000E8302500C5182549 -:1071700024820008AC83000003E00008AC80000417 -:107180003C098000352309009128010B906A001109 -:107190002402002800804821314700FF00A0702110 -:1071A00000C068213108004010E20002340C86DD86 -:1071B000240C08003C0A800035420A9A94470000DB -:1071C000354B0A9C35460AA030F9FFFFAD39000067 -:1071D0008D780000354B0A8024040001AD3800048E -:1071E0008CCF0000AD2F00089165001930A300037B -:1071F0001064009A28640002148000B9240500027B -:10720000106500A8240F0003106F00BE35450AA4C6 -:10721000240A0800118A004D0000000051000042BD -:107220003C0B80003C04800034830900906700120E -:1072300030E200FF004D7821000FC88027240001B4 -:107240003C0A8000354F090091E50019354C098052 -:107250008D87002830A300FF000315000047582544 -:107260000004C4003C19600001793025370806FF8E -:10727000AD260000AD2800048DEA002C252800284A -:10728000AD2A00088DEC0030AD2C000C8DE50034EB -:10729000AD2500108DE40038AD2400148DE3001CF2 -:1072A000AD2300188DE70020AD27001C8DE20024DF -:1072B000AD2200208DF90028AD3900243C09800062 -:1072C0003526093C8CCF0000352A0100AD0E0004A4 -:1072D000AD0F00008D4E000C3523090035250980C7 -:1072E000AD0E0008906C00128D47000C8CB9003474 -:1072F0003C18080093183FF8318200FF004D5821D8 -:1073000003277823000B37000018240000C47025E1 -:1073100031E9FFFC01C9682525020014AD0D000C00 -:1073200003E00008AD000010357809009306001254 -:107330003C05080094A53FE830C800FF010D50212E -:10734000000A60800A00063C0185202115000060CB -:10735000000000003C08080095083FEE3C060800CD -:1073600094C63FE8010610213C0B800035790900E6 -:1073700093380011932A001935660A80330800FFFC -:1073800094CF002A00086082314500FF978A005898 -:10739000000C1E00000524003047FFFF006410258C -:1073A0000047C02501EA30213C0B4000030B40257B -:1073B00000066400AD280000AD2C000493250018E1 -:1073C0003C0300062528001400053E0000E31025BC -:1073D000AD2200088F24002C254F000131EB7FFFE8 -:1073E000AD24000C8F38001CA78B0058AD3800105E -:1073F0003C0980003526093C8CCF0000352A01006D -:10740000AD0E0004AD0F00008D4E000C35230900B9 -:1074100035250980AD0E0008906C00128D47000CD8 -:107420008CB900343C18080093183FF8318200FFF3 -:10743000004D582103277823000B37000018240043 -:1074400000C4702531E9FFFC01C96825250200143C -:10745000AD0D000C03E00008AD0000103C02080078 -:1074600094423FF23C05080094A53FE835440AA445 -:107470003C07080094E73FE4948B00000045C821D6 -:107480000327C023000B1C002706FFF200665025CF -:10749000AD2A000CAD200010AD2C00140A000630FF -:1074A00025290018354F0AA495E5000095640028A9 -:1074B0000005140000043C003459810000EC5825FC -:1074C000AD39000CAD2B00100A0006302529001440 -:1074D0003C0C0800958C3FEE0A00068625820001D0 -:1074E0005460FF4C240A080035580AA4970600008F -:1074F00000061C00006C5025AD2A000C0A00063066 -:10750000252900103C03080094633FF23C07080063 -:1075100094E73FE83C0F080095EF3FE494A4000097 -:107520009579002800671021004F582300041C00A3 -:10753000001934002578FFEE00D87825346A8100E0 -:10754000AD2A000CAD2F0010AD200014AD2C00189A -:107550000A0006302529001C03E00008240207D099 -:1075600027BDFFE0AFB20018AFB10014AFB00010FC -:10757000AFBF001C0E00007C008088218F88005463 -:107580008F87004C3C05800834B20080011128210F -:107590003C10800024020080240300C000A72023A8 -:1075A000AE0208183C068008AE03081C18800004D0 -:1075B000AF850054ACC500048CC90004AF89004CF1 -:1075C00012200009360409800E00070200000000A6 -:1075D000924C00278E0B007401825004014B302125 -:1075E000AE46000C360409808C8E001C8F8F005C28 -:1075F00001CF682319A000048FBF001C8C90001CD1 -:10760000AF90005C8FBF001C8FB200188FB10014C8 -:107610008FB000100A00007E27BD00208F8600502A -:107620008F8300548F82004C3C05800834A4008076 -:10763000AC860050AC83003C03E00008ACA2000420 -:107640003C0308008C63005427BDFFF8308400FF22 -:107650002462000130A500FF3C010800AC22005468 -:1076600030C600FF3C0780008CE801780500FFFE73 -:107670003C0C7FFFA3A400038FAA0000358BFFFF03 -:10768000014B4824000627C001244025AFA8000074 -:1076900034E201009043000AA3A000023C1980FFDD -:1076A000A3A300018FAF000030AE007F3738FFFF8B -:1076B00001F86024000E6E003C0A002034E5014011 -:1076C000018D5825354920002406FF803C04100018 -:1076D00027BD0008ACAB000CACA90014A4A0001896 -:1076E000A0A6001203E00008ACE40178308800FF97 -:1076F00030A700FF3C0380008C6201780440FFFE4D -:107700003C0C8000358A0A008D4B002035840140F6 -:1077100035850980AC8B00048D4900240007302B8F -:1077200000061540AC890008A088001090A3004C0A -:10773000A083002D03E00008A480001827BDFFE807 -:10774000308400FFAFBF00100E00076730A500FFB8 -:107750008F8300548FBF00103C06800034C5014069 -:10776000344700402404FF903C02100027BD00185D -:10777000ACA3000CA0A40012ACA7001403E0000806 -:10778000ACC2017827BDFFE03C088008AFBF001CF9 -:10779000AFB20018AFB10014AFB0001035100080C8 -:1077A0008E0600183C078000309200FF00C720259D -:1077B000AE0400180E00007C30B100FF92030005FB -:1077C000346200080E00007EA20200050240202163 -:1077D0000E00077B02202821024020218FBF001CC1 -:1077E0008FB200188FB100148FB00010240500056F -:1077F000240600010A00073C27BD00203C0580004C -:1078000034A309809066000830C200081040000FC1 -:107810003C0A01013549080AAC8900008CA80074B3 -:10782000AC8800043C07080090E73FF830E5001002 -:1078300050A00008AC8000083C0D800835AC0080EA -:107840008D8B0058AC8B00082484000C03E00008EA -:10785000008010210A0007BF2484000C27BDFFE828 -:107860003C098000AFB00010AFBF0014352609807E -:1078700090C800092402000600A05821310300FF2F -:107880003527090000808021240500041062007B58 -:107890002408000294CF005C3C0E020431EDFFFF8F -:1078A00001AE6025AE0C000090CA000831440020F3 -:1078B000108000080000000090C2004E3C1F010331 -:1078C00037F90300305800FF03193025240500085C -:1078D000AE06000490F9001190E6001290E4001149 -:1078E000333800FF0018708230CF00FF01CF5021E5 -:1078F000014B6821308900FF31AAFFFF392300289E -:10790000000A60801460002C020C482390E40012EE -:107910003C198000372F0100308C00FF018B1821AB -:10792000000310800045F821001F8400360706FF81 -:10793000AD270004373F090093EC001193EE0012CD -:10794000372609800005C0828DE4000C8CC5003408 -:1079500031CD00FF01AB10210058182100A4F823FD -:107960000008840000033F0000F0302533F9FFFFDA -:10797000318F00FC00D970250158202101E96821D0 -:1079800000045080ADAE000C0E00007C012A802166 -:107990003C088008240B0004350500800E00007EA2 -:1079A000A0AB0009020010218FBF00148FB000109F -:1079B00003E0000827BD001890EC001190E30019C7 -:1079C0003C18080097183FEE318200FF0002F88251 -:1079D000307000FF001FCE0000103C000327302550 -:1079E00000D870253C0F400001CF68253C1980006D -:1079F000AD2D0000373F090093EC001193EE00120B -:107A0000372F0100372609800005C0828DE4000C65 -:107A10008CC5003431CD00FF01AB10210058182176 -:107A200000A4F8230008840000033F0000F0302584 -:107A300033F9FFFF318F00FC00D970250158202158 -:107A400001E9682100045080ADAE000C0E00007CFE -:107A5000012A80213C088008240B000435050080A1 -:107A60000E00007EA0AB0009020010218FBF0014A1 -:107A70008FB0001003E0000827BD00180A0007D1EE -:107A80002408001227BDFFD03C038000AFB60028B9 -:107A9000AFB50024AFB40020AFB10014AFBF002CCD -:107AA000AFB3001CAFB20018AFB0001034670100D4 -:107AB00090E6000B309400FF30B500FF30C200307C -:107AC0000000B02110400099000088213464098032 -:107AD0009088000800082E0000051E03046000C006 -:107AE000240400048F8600543C010800A0243FF8C1 -:107AF0003C0C8000AD8000483C048000348E0100C6 -:107B000091CD000B31A5002010A000073C0780009C -:107B100034930980927200080012860000107E03E0 -:107B200005E000C43C1F800834EC0100918A000B82 -:107B300034EB098091690008314400400004402B77 -:107B40003123000800C898231460000224120003A7 -:107B5000000090213C10800036180A80360409008D -:107B6000970E002C90830011908900129305001845 -:107B7000307F00FF312800FF024810210002C8803A -:107B8000930D0018033F782101F1302130B100FF3F -:107B900000D11821A78E00583C010800A4263FEE12 -:107BA0003C010800A4233FF015A0000200000000E3 -:107BB0000000000D920B010B3065FFFF3C01080037 -:107BC000A4233FF2316A00403C010800A4203FE8B2 -:107BD0003C010800A4203FE41140000224A4000A54 -:107BE00024A4000B3091FFFF0E0001E702202021AA -:107BF0009206010B3C0C0800958C3FF200402021BE -:107C00000006698231A700010E00060101872821C4 -:107C100000402021026028210E00060C0240302185 -:107C20000E0007AB0040202116C000690040202153 -:107C30009212010B3256004012C000053C0500FFB5 -:107C40008C93000034AEFFFF026E8024AC900000E5 -:107C50000E0001FB022020213C0F080091EF3FF8AD -:107C600031F10003122000163C1380088F8200546B -:107C70003C09800835280080245F0001AD1F003CCE -:107C80003C0580088CB9000403E02021033FC02399 -:107C90001B000002AF9F00548CA400040E000702DA -:107CA000ACA400043C0780008CEB00743C0480080A -:107CB00034830080004B5021AC6A000C3C138008D8 -:107CC000367000800280202102A02821A200006BD3 -:107CD0000E0007673C1480008F920054368C0140E0 -:107CE000AD92000C8F8600483C151000344D000604 -:107CF00024D60001AF9600488FBF002CA186001249 -:107D00008FB60028AD8D00148FB3001CAE9501789E -:107D10008FB200188FB500248FB400208FB10014EB -:107D20008FB0001003E0000827BD003034640980E4 -:107D3000908F0008000F7600000E6E0305A0003340 -:107D4000347F090093F8001B241900103C0108003F -:107D5000A0393FF8331300021260FF678F8600548A -:107D60008F8200601446FF653C0480000E00007C9A -:107D7000000000003C0480083485008090A80009C1 -:107D800024060016310300FF1066000D00000000FD -:107D900090AB00093C07080090E73FF82409000871 -:107DA000316400FF34EA00013C010800A02A3FF8DA -:107DB0001089002F240C000A108C00282402000CCB -:107DC0000E00007E000000000A00086A8F86005442 -:107DD0000E0007C3024028210A0008B800402021F5 -:107DE0003C0B8008356A00808D4600548CE9000CFD -:107DF0001120FF3DAF860054240700143C01080009 -:107E0000A0273FF80A0008693C0C80009091000808 -:107E1000241200023C010800A0323FF8323000205A -:107E20001200000B241600018F8600540A00086A15 -:107E30002411000837F800808F020038AFE20004F8 -:107E40008FF90004AF19003C0A0008763C07800057 -:107E50008F8600540A00086A24110004A0A20009B9 -:107E60000E00007E000000000A00086A8F860054A1 -:107E7000240200140A000944A0A2000927BDFFE85B -:107E8000AFB000103C108000AFBF001436020100FC -:107E9000904400090E000767240500013C04800897 -:107EA0009099000E34830080909F000F906F002601 -:107EB0009089000A33F800FF00196E000018740062 -:107EC00031EC00FF01AE5025000C5A00014B382563 -:107ED000312800FF360301403445600000E83025BA -:107EE0002402FF813C041000AC66000C8FBF00141C -:107EF000AC650014A0620012AE0401788FB00010CF -:107F000003E0000827BD001827BDFFE8308400FF0C -:107F1000AFBF00100E00076730A500FF3C058000D2 -:107F200034A40140344700402406FF92AC8700147B -:107F3000A08600128F8300548FBF00103C021000F7 -:107F400027BD0018AC83000C03E00008ACA2017848 -:107F500027BDFFD8AFB00010308400FF30B000FF65 -:107F60003C058000AFB10014AFBF0020AFB3001CD0 -:107F7000AFB20018000410C234A6010032030002A0 -:107F8000305100011460000790D200093C098008BC -:107F900035330080926800053107000810E0000CBE -:107FA000308A0010024020210E00078D0220282177 -:107FB000240200018FBF00208FB3001C8FB2001875 -:107FC0008FB100148FB0001003E0000827BD002817 -:107FD0001540003434A50A008CB800248CAF00088A -:107FE000130F004B000038213C0D800835B3008092 -:107FF000926C006824060002318B00FF1166008439 -:108000003C06800034C201009263004C9059000984 -:10801000307F00FF53F900043213007C10E0006948 -:10802000000000003213007C5660005C02402021FA -:1080300016200009320D00013C0C8000358401003F -:10804000358B0A008D6500248C86000414A6FFD9A8 -:1080500000001021320D000111A0000E024020216D -:108060003C188000371001008E0F000C8F8E0050DE -:1080700011EE0008000000000E00084D022028212B -:108080008E19000C3C1F800837F00080AE1900509C -:10809000024020210E00077B022028210A000999B6 -:1080A000240200013C0508008CA5006424A4000102 -:1080B0003C010800AC2400641600000D0000000024 -:1080C000022028210E00077B02402021926E0068CA -:1080D000240C000231CD00FF11AC0022024020210F -:1080E0000E00094B000000000A000999240200015B -:1080F0000E00007024040001926B0025020B302555 -:108100000E00007EA26600250A0009DD022028215B -:108110008E6200188CDF00048CB9002400021E025D -:1081200017F9FFB13065007F9268004C26440001CA -:108130003093007F12650040310300FF1464FFABF1 -:108140003C0D80082647000130F1007F30E200FF3F -:108150001225000B24070001004090210A0009A607 -:1081600024110001240500040E00073C2406000130 -:108170000E00094B000000000A00099924020001CA -:108180002405FF800245202400859026324200FF0E -:10819000004090210A0009A6241100010E00084D9C -:1081A000022028213207003010E0FFA132100082A7 -:1081B000024020210E00078D022028210A00099983 -:1081C000240200018E69001802402021022028218B -:1081D000012640250E00096EAE6800189264004C1E -:1081E00024050003240600010E00073C308400FF34 -:1081F0000E00007024040001927100250211502528 -:108200000E00007EA26A00250A00099924020001DE -:108210008E6F00183C1880000240202101F8702564 -:10822000022028210E00077BAE6E00189264004CDD -:108230000A000A2524050004324A008039490080DA -:108240001469FF6A3C0D80080A0009FE26470001F8 -:1082500027BDFFC0AFB000183C108000AFBF003892 -:10826000AFB70034AFB60030AFB5002CAFB40028C4 -:10827000AFB30024AFB200200E0005BEAFB1001CAA -:10828000360201009045000B0E0009809044000862 -:10829000144000E78FBF00383C0880083507008095 -:1082A000A0E0006B3606098090C500002403005052 -:1082B0003C17080026F73FB030A400FF3C1308002D -:1082C00026733FC0108300033C1080000000B821DB -:1082D00000009821241F00103611010036120A00F8 -:1082E000361509808E5800248E3400048EAF00208D -:1082F0008F8C00543C010800A03F3FF836190A80DB -:10830000972B002C8EF60000932A001802987023F9 -:1083100001EC68233C010800AC2E3FD43C0108006E -:10832000AC2D3FD83C010800AC2C3FFCA78B00587B -:1083300002C0F809315400FF30490002152000E95D -:1083400030420001504000C49227000992A9000861 -:108350003128000815000002241500030000A821A0 -:108360003C0A80003543090035440A008C8D002406 -:108370009072001190700012907F0011325900FF2E -:10838000321100FF02B110210002C08033EF00FF64 -:108390000319B021028F702102D4602125CB001077 -:1083A0003C010800A4363FEE3C010800AC2D400023 -:1083B0003C010800A42C3FF03C010800A42B3FEC3A -:1083C000355601003554098035510E008F87005411 -:1083D0008F89005C8E850020240800060127302349 -:1083E0003C010800AC283FF400A7282304C000B5D6 -:1083F0000000902104A000B300C5502B114000B52F -:10840000000000003C010800AC263FD88E6200004E -:108410000040F809000000003046000214C000745B -:1084200000408021304B0001556000118E62000435 -:108430003C0D08008DAD3FDC3C0EC0003C048000CC -:1084400001AE6025AE2C00008C980000330F0008B0 -:1084500011E0FFFD00000000963F0008241200011B -:10846000A79F00408E390004AF9900388E62000447 -:108470000040F809000000000202802532030002DB -:10848000146000B3000000003C09080095293FE497 -:108490003C06080094C63FF03C0A0800954A3FE6B7 -:1084A0003C0708008CE73FDC012670213C030800F4 -:1084B0008C6340003C08080095083FFA01CA20215F -:1084C0008ED9000C00E92821249F000200A8782101 -:1084D0000067C02133E4FFFFAF9900503C01080062 -:1084E000AC3840003C010800A42F3FE83C010800E4 -:1084F000A42E3FF20E0001E7000000008F8D00481F -:10850000004020213C010800A02D3FF98E620008A8 -:1085100025AC0001AF8C00480040F80900000000C5 -:108520008F85005402A030210E00060C004020214F -:108530000E0007AB004020218E6B000C0160F80993 -:10854000004020213C0A0800954A3FF23C06080002 -:1085500094C63FE601464821252800020E0001FB93 -:108560003104FFFF3C0508008CA53FD43C07080000 -:108570008CE73FDC00A720233C010800AC243FD45B -:1085800014800006000000003C0208008C423FF40A -:10859000344B00403C010800AC2B3FF41240004338 -:1085A0008F8E00448E2D00108F920044AE4D00201F -:1085B0008E2C0018AE4C00243C04080094843FE844 -:1085C0000E000704000000008F9F00548E6700100B -:1085D0003C010800AC3F3FFC00E0F809000000004F -:1085E0003C1908008F393FD41720FF798F8700543A -:1085F000979300583C11800E321601000E0007338D -:10860000A633002C16C00045320300105460004C05 -:108610008EE50004320800405500001D8EF0000871 -:108620008EE4000C0080F809000000008FBF0038C5 -:108630008FB700348FB600308FB5002C8FB4002870 -:108640008FB300248FB200208FB1001C8FB00018B0 -:1086500003E0000827BD00408F86003C36110E0065 -:1086600000072E0000A62025AE0400808E430020C7 -:108670008E500024AFA30010AE2300148FB2001060 -:10868000AE320010AE30001C0A000A7FAE30001877 -:108690000200F809000000008EE4000C0080F809D8 -:1086A000000000000A000B388FBF003824180001BA -:1086B000240F0001A5C00020A5D800220A000B1A33 -:1086C000ADCF00243C010800AC203FD80A000AB01E -:1086D0008E6200003C010800AC253FD80A000AB0B9 -:1086E0008E620000922400090E00077B0000282102 -:1086F0008FBF00388FB700348FB600308FB5002C95 -:108700008FB400288FB300248FB200208FB1001CDB -:108710008FB0001803E0000827BD00403C14800023 -:1087200092950109000028210E00084D32A400FF97 -:10873000320300105060FFB8320800408EE500049C -:1087400000A0F809000000000A000B3232080040C7 -:108750005240FFA8979300588E3400148F93004422 -:10876000AE7400208E35001CAE7500240A000B2963 -:10877000979300588F8200140004218003E00008C2 -:10878000008210213C07800834E200809043006999 -:1087900000804021106000093C0401003C070800F3 -:1087A0008CE73FFC8F83003000E320230480000827 -:1087B0009389001C14E300030100202103E000085A -:1087C000008010213C04010003E00008008010211B -:1087D0001120000B006738233C0D800035AC098068 -:1087E000918B007C316A0002114000202409003482 -:1087F00000E9702B15C0FFF10100202100E93823AA -:108800002403FFFC00A3C82400E3C02400F9782B54 -:1088100015E0FFEA0308202130C400030004102300 -:1088200014C00014304900030000302100A9782151 -:1088300001E6702100EE682B11A0FFE03C0401006E -:108840002D3800010006C82B0105482103193824E2 -:1088500014E0FFDA2524FFFC2402FFFC00A2182408 -:108860000068202103E00008008010210A000BA806 -:10887000240900303C0C80003586098090CB007CB8 -:10888000316A00041540FFE9240600040A000BB712 -:10889000000030213C0308008C63005C8F820018CC -:1088A00027BDFFE0AFBF0018AFB100141062000594 -:1088B000AFB00010000329C024A40280AF840014CC -:1088C000AF8300183C10800036020A009445003245 -:1088D000361101000E000B8930A43FFF8E240000EA -:1088E000241FFF803C1100800082C021031F6024F0 -:1088F0003309007F000CC94003294025330E00785E -:10890000362F00033C0D1000010D502501CF5825D6 -:10891000AE0C002836080980AE0C080CAE0B082CF3 -:10892000AE0A0830910300693C06800C012638210C -:1089300010600006AF8700348D09003C8D03006C89 -:108940000123382318E00082000000003C0B80085F -:10895000356A00803C108000A1400069360609801D -:108960008CC200383C06800034C50A0090A8003C48 -:10897000310C00201180001AAF820030240D00015C -:108980003C0E800035D10A00A38D001CAF8000246E -:108990008E2400248F850024240D0008AF80002041 -:1089A000AF8000283C010800A42D3FE63C010800F0 -:1089B000A4203FFA0E000B8D000030219228003CCD -:1089C0008FBF00188FB100148FB0001000086142F3 -:1089D000AF82002C27BD002003E000083182000197 -:1089E00090B80032240E0001330F00FF000F2182E7 -:1089F000108E0041241900021099006434C40AC08A -:108A00003C03800034640A008C8F002415E0001EB3 -:108A100034660900909F00302418000533F9003FA8 -:108A20001338004E240300018F860020A383001C0E -:108A3000AF860028AF8600243C0E800035D10A00A6 -:108A40008E2400248F850024240D00083C0108009A -:108A5000A42D3FE63C010800A4203FFA0E000B8D38 -:108A6000000000009228003C8FBF00188FB1001456 -:108A70008FB0001000086142AF82002C27BD00209B -:108A800003E00008318200018C8A00088C8B0024EE -:108A90008CD000643C0E800035D10A00014B2823A5 -:108AA000AF900024A380001CAF8500288E240024F2 -:108AB0008F8600208F850024240D00083C010800CB -:108AC000A42D3FE63C010800A4203FFA0E000B8DC8 -:108AD000000000009228003C8FBF00188FB10014E6 -:108AE0008FB0001000086142AF82002C27BD00202B -:108AF00003E000083182000190A200303051003FB5 -:108B00005224002834C50AC08CB00024160000226C -:108B100034CB09008CA600483C0A7FFF3545FFFF97 -:108B200000C510243C0E8000AF82002035C509002E -:108B30008F8800208CAD0060010D602B1580000235 -:108B4000010020218CA400600A000C2CAF840020BE -:108B50008D02006C0A000C063C0680008C820048E6 -:108B60008F8600203C097FFF3527FFFF00478824C0 -:108B70003C04800824030001AF910028AC80006C05 -:108B8000A383001C0A000C3AAF8600248C9F0014BB -:108B90000A000C2CAF9F00208D6200680A000C7642 -:108BA0003C0E800034C409808C8900708CA30014B2 -:108BB0000123382B10E00004000000008C820070BC -:108BC0000A000C763C0E80008CA200140A000C7681 -:108BD0003C0E80008F85002427BDFFE0AFBF00184A -:108BE000AFB1001414A00008AFB000103C04800026 -:108BF00034870A0090E600302402000530C3003FAD -:108C0000106200B9348409008F91002000A08021F7 -:108C10003C048000348E0A008DCD00043C06080020 -:108C20008CC63FD831A73FFF00E6602B558000017E -:108C300000E03021938F001C11E0007800D0282B39 -:108C4000349F098093F9007C3338000213000079C7 -:108C50002403003400C3102B144000D9000000008E -:108C600000C3302300D0282B3C010800A4233FE49C -:108C700014A0006E020018213C0408008C843FD42C -:108C80000064402B55000001006020213C0580005D -:108C900034A90A00912A003C3C010800AC243FDCC6 -:108CA00031430020146000030000482134AB0E0063 -:108CB0008D6900188F88002C0128202B1080005F00 -:108CC000000000003C0508008CA53FDC00A96821DD -:108CD000010D602B1180005C00B0702B010938235E -:108CE00000E028213C010800AC273FDC1200000313 -:108CF000240AFFFC10B0008D3224000300AA1824BF -:108D00003C010800A4203FFA3C010800AC233FDCF2 -:108D1000006028218F840024120400063C0B800888 -:108D20008D6C006C02002021AF9100202590000185 -:108D3000AD70006C8F8D002800858823AF910024D2 -:108D400001A52023AF840028122000022407001868 -:108D5000240700103C1880083706008090CF006878 -:108D60003C010800A0273FF82407000131EE00FF76 -:108D700011C70047000000001480001800002821DF -:108D80003C06800034D1098034CD010091A6000951 -:108D90008E2C001824C40001000C86023205007FCE -:108DA000308B007F1165007F2407FF803C1980080D -:108DB00037290080A124004C3C0808008D083FF4AE -:108DC000241800023C010800A0384039350F000883 -:108DD0003C010800AC2F3FF4240500103C02800049 -:108DE00034440A009083003C307F002013E00005EB -:108DF00000A02021240A00013C010800AC2A3FDC2D -:108E000034A400018FBF00188FB100148FB0001080 -:108E10000080102103E0000827BD00203C0108006D -:108E2000A4203FE410A0FF94020018210A000CCAFD -:108E300000C018210A000CC1240300303C050800C2 -:108E40008CA53FDC00B0702B11C0FFA80000000013 -:108E50003C19080097393FE40325C0210307782B0C -:108E600011E000072CAA00043C0360008C6254044B -:108E7000305F003F17E0FFE3240400422CAA000407 -:108E80001140FF9A240400420A000D2E8FBF0018E3 -:108E90001528FFB9000000008CCA00183C1F800094 -:108EA00024020002015F1825ACC3001837F90A003C -:108EB000A0C200689329003C2404000400A01021F3 -:108EC000312800203C010800A02440391100000294 -:108ED00024050010240200013C010800AC223FD40C -:108EE0000A000D243C0280008F8800288C890060D5 -:108EF0000109282B14A00002010088218C91006038 -:108F00003C048000348B0E008D640018240A00019C -:108F10000220282102203021A38A001C0E000B8D84 -:108F2000022080210A000CB0AF82002C00045823DC -:108F300012200007316400033C0E800035C7098011 -:108F400090ED007C31AC000415800019248F0004E2 -:108F50003C010800A4243FFA3C1F080097FF3FFA99 -:108F600003E5C82100D9C02B1300FF6B8F840024B8 -:108F70002CA6000514C0FFA32404004230A2000365 -:108F80001440000200A2182324A3FFFC3C010800A7 -:108F9000AC233FDC3C010800A4203FFA0A000CF19E -:108FA0000060282100C770240A000D1701C7202681 -:108FB0003C010800A42F3FFA0A000D8200000000C7 -:108FC0003C010800AC203FDC0A000D2D24040042C7 -:108FD0008F8300283C05800034AA0A001460000634 -:108FE00000001021914700302406000530E400FF06 -:108FF000108600030000000003E0000800000000ED -:10900000914B0048316900FF000941C21500FFFA89 -:109010003C0680083C04080094843FE43C030800BC -:109020008C633FFC3C1908008F393FDC3C0F080083 -:1090300095EF3FFA0064C0218CCD00040319702124 -:1090400001CF602134AB0E00018D282318A0001D34 -:1090500000000000914F004C8F8C0034956D001083 -:1090600031EE00FF8D89000401AE30238D8A0000AF -:1090700030CEFFFF000E29000125C8210000382155 -:10908000014720210325182B0083C021AD9900043E -:10909000AD980000918F000A01CF6821A18D000AD0 -:1090A000956500128F8A0034A5450008954B00385D -:1090B00025690001A54900389148000D35070008D1 -:1090C000A147000D03E000080000000027BDFFD805 -:1090D000AFB000189388001C8FB000143C0A8000C9 -:1090E0003C197FFF8F8700243738FFFFAFBF002078 -:1090F000AFB1001C355F0A000218182493EB003C46 -:1091000000087FC03C02BFFF006F60252CF000010B -:109110003449FFFF3C1F08008FFF3FFC8F99003050 -:109120003C18080097183FF2018978240010478006 -:109130003C07EFFF3C05F0FF01E818253C118000DB -:109140003169002034E2FFFF34ADFFFF362E098085 -:1091500027A500102406000203F96023270B000254 -:10916000354A0E000062182400808021152000027C -:10917000000040218D48001CA7AB0012058000397B -:109180002407000030E800FF00083F000067582572 -:109190003C028008AFAB0014344F008091EA0068B5 -:1091A0003C08080091083FF93C09DFFF352CFFFF20 -:1091B000000AF82B3C02080094423FECA3A80011DF -:1091C000016CC024001FCF40031918258FA7001081 -:1091D000AFA300143C0C0800918C3FFBA7A2001623 -:1091E0008FAB001400ED48243C0F01003C0A0FFF38 -:1091F000012FC82531980003355FFFFF016D402422 -:109200003C027000033F382400181E0000E248258D -:1092100001037825AFAF0014AFA9001091CC007CFA -:109220000E000092A3AC0015362D0A0091A6003C5A -:1092300030C4002010800006260200083C110800FF -:1092400096313FE8262EFFFF3C010800A42E3FE8A0 -:109250008FBF00208FB1001C8FB0001803E0000802 -:1092600027BD00288F8B002C010B502B5540FFC5CC -:10927000240700010A000E0E30E800FF9383001C53 -:109280003C02800027BDFFD834480A0000805021EE -:10929000AFBF002034460AC0010028211060000E34 -:1092A0003444098091070030240B00058F89002089 -:1092B00030EC003F118B000B00003821AFA90010EB -:1092C0003C0B80088D69006CAFAA00180E00015A93 -:1092D000AFA90014A380001C8FBF002003E000088A -:1092E00027BD00288D1F00483C1808008F183FDC60 -:1092F0008F9900283C027FFF8D0800443443FFFF14 -:10930000AFA900103C0B80088D69006C03E370244A -:109310000319782101CF682301A83821AFAA0018CA -:109320000E00015AAFA900140A000E62A380001CAF -:109330003C05800034A60A0090C7003C3C060800AB -:1093400094C63FFA3C0208008C423FF430E3002010 -:10935000000624001060001E004438253C088008E8 -:109360003505008090A30068000048212408000112 -:1093700000002821240400013C0680008CCD0178E7 -:1093800005A0FFFE34CF0140ADE800083C02080014 -:109390008C423FFCA5E50004A5E40006ADE2000C0C -:1093A0003C04080090843FF93C0380083479008035 -:1093B000A1E40012ADE70014A5E900189338004CB1 -:1093C0003C0E1000A1F8002D03E00008ACCE01789F -:1093D00034A90E008D28001C3C0C08008D8C3FDC4D -:1093E000952B0016952A0014018648213164FFFF51 -:1093F0000A000E8A3145FFFF3C04800034830A00D6 -:109400009065003C30A200201040001934870E0007 -:109410000000402100003821000020213C0680008F -:109420008CC901780520FFFE34CA014034CF010009 -:1094300091EB0009AD4800083C0E08008DCE3FFCC2 -:10944000240DFF91240C00403C081000A5440004AA -:10945000A5470006AD4E000CA14D0012AD4C001406 -:10946000A5400018A14B002D03E00008ACC801780E -:109470008CE8001894E6001294E4001030C7FFFF57 -:109480000A000EB33084FFFF3C04800034830A00DE -:109490009065003C30A200201040002727BDFFF857 -:1094A0002409000100003821240800013C06800046 -:1094B0008CCA01780540FFFE3C0280FF34C40100E5 -:1094C000908D00093C0C0800918C4039A3AD00033D -:1094D0008FAB00003185007F3459FFFF01665025B6 -:1094E000AFAA00009083000AA3A0000200057E003E -:1094F000A3A300018FB8000034CB0140240C30003E -:109500000319702401CF6825AD6D000C27BD00083C -:10951000AD6C0014A5600018AD690008A5670004D3 -:109520002409FF80A56800063C081000A16900120C -:1095300003E00008ACC8017834870E008CE90018FD -:1095400094E6001294E4001030C8FFFF0A000ED722 -:109550003087FFFF27BDFFE0AFB100143C11800052 -:10956000AFB00010AFBF001836380A00970F0032B6 -:10957000363001000E000B8931E43FFF8E0E0000F3 -:10958000240DFF803C04200001C25821016D60249D -:10959000000C4940316A007F012A4025010438252A -:1095A0003C048008AE2708303486008090C50068EF -:1095B0002403000230A200FF104300048F9F00200C -:1095C0008F990024AC9F0068AC9900648FBF00188D -:1095D0008FB100148FB0001003E0000827BD0020F9 -:1095E0003C0A0800254A3AA83C09080025293B38CE -:1095F0003C08080025082F443C07080024E73C04E9 -:109600003C06080024C6392C3C05080024A53680F9 -:109610003C040800248432843C030800246339E0BD -:109620003C0208002442377C3C010800AC2A3FB8C9 -:109630003C010800AC293FB43C010800AC283FB015 -:109640003C010800AC273FBC3C010800AC263FCCE5 -:109650003C010800AC253FC43C010800AC243FC0DD -:109660003C010800AC233FD03C010800AC223FC8BD -:0896700003E000080000000007 -:08967800800009408000090098 -:10968000800801008008008080080000800E000033 -:10969000800800808008000080000A8080000A00A6 -:0896A000800009808000090030 -:00000001FF -/* - * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware data - * in hexadecimal or equivalent format, provided this copyright notice is - * accompanying it. - */ diff --git a/firmware/bnx2/bnx2-mips-09-6.2.1a.fw.ihex b/firmware/bnx2/bnx2-mips-09-6.2.1a.fw.ihex new file mode 100644 index 000000000000..05e710248d2c --- /dev/null +++ b/firmware/bnx2/bnx2-mips-09-6.2.1a.fw.ihex @@ -0,0 +1,6512 @@ +:10000000080001180800000000005594000000C816 +:1000100000000000000000000000000008005594EF +:10002000000000380000565C080000A00800000036 +:100030000000574400005694080059200000008436 +:100040000000ADD808005744000001C00000AE5CBD +:100050000800321008000000000092340000B01CBC +:1000600000000000000000000000000008009234C2 +:100070000000033C00014250080004900800040006 +:10008000000012FC0001458C000000000000000090 +:1000900000000000080016FC000000040001588861 +:1000A000080000A80800000000003D000001588C76 +:1000B00000000000000000000000000008003D00FB +:0800C000000000300001958CE6 +:0800C8000A00004600000000E0 +:1000D000000000000000000D636F6D362E322E31DF +:1000E00061000000060201020000000000000003A1 +:1000F000000000C800000032000000030000000003 +:1001000000000000000000000000000000000000EF +:1001100000000010000001360000EA600000000549 +:1001200000000000000000000000000000000008C7 +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000020000000000000000000000008D +:10017000000000000000000000000000000000007F +:10018000000000000000000000000010000000005F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E0000000000010000003000000000000000DEF +:1001F0000000000D3C020800244256083C030800A1 +:1002000024635754AC4000000043202B1480FFFDB2 +:10021000244200043C1D080037BD9FFC03A0F021D0 +:100220003C100800261001183C1C0800279C5608AA +:100230000E000256000000000000000D27BDFFB4B4 +:10024000AFA10000AFA20004AFA30008AFA4000C50 +:10025000AFA50010AFA60014AFA70018AFA8001CF0 +:10026000AFA90020AFAA0024AFAB0028AFAC002C90 +:10027000AFAD0030AFAE0034AFAF0038AFB8003C28 +:10028000AFB90040AFBC0044AFBF00480E001544FA +:10029000000000008FBF00488FBC00448FB90040B1 +:1002A0008FB8003C8FAF00388FAE00348FAD003078 +:1002B0008FAC002C8FAB00288FAA00248FA90020C0 +:1002C0008FA8001C8FA700188FA600148FA5001000 +:1002D0008FA4000C8FA300088FA200048FA1000040 +:1002E00027BD004C3C1B60108F7A5030377B502864 +:1002F00003400008AF7A00008F82002427BDFFE092 +:10030000AFB00010AFBF0018AFB100148C42000CAA +:100310003C1080008E110100104000348FBF001887 +:100320000E000D84000000008F85002024047FFF54 +:100330000091202BACB100008E030104960201084D +:1003400000031C003042FFFF00621825ACA300042C +:100350009202010A96030114304200FF3063FFFF4E +:100360000002140000431025ACA200089603010C03 +:100370009602010E00031C003042FFFF00621825A8 +:10038000ACA3000C960301109602011200031C009E +:100390003042FFFF00621825ACA300108E02011846 +:1003A000ACA200148E02011CACA20018148000083C +:1003B0008F820024978200003C0420050044182509 +:1003C00024420001ACA3001C0A0000C6A782000062 +:1003D0003C0340189442001E00431025ACA2001CB0 +:1003E0000E000DB8240400018FBF00188FB1001457 +:1003F0008FB000100000102103E0000827BD00208E +:100400003C0780008CE202B834E50100044100089A +:10041000240300013C0208008C42006024420001D9 +:100420003C010800AC22006003E0000800601021DD +:100430003C0208008C42005C8CA4002094A30016AF +:100440008CA6000494A5000E24420001ACE40280B6 +:100450002463FFFC3C010800AC22005C3C0210005D +:10046000A4E30284A4E5028600001821ACE6028819 +:10047000ACE202B803E000080060102127BDFFE0F5 +:100480003C028000AFB0001034420100AFBF001C3E +:10049000AFB20018AFB100148C43000094450008BF +:1004A0002462FE002C42038110400003000381C23D +:1004B0000A00010226100004240201001462000553 +:1004C0003C1180003C02800890420004305000FF44 +:1004D0003C11800036320100964300143202000FB6 +:1004E00000021500004310253C0308008C63004403 +:1004F00030A40004AE220080246300013C01080007 +:10050000AC2300441080000730A200028FBF001C03 +:100510008FB200188FB100148FB000100A0000CE07 +:1005200027BD00201040002D0000182130A20080BF +:1005300010400005362200708E44001C0E000C672F +:10054000240500A0362200708C4400008F82000C2D +:10055000008210232C43012C10600004AF82001095 +:10056000240300010A000145AF84000C8E42000400 +:100570003C036020AF84000CAC6200143C02080015 +:100580008C42005850400015000018218C62000475 +:10059000240301FE304203FF144300100000182121 +:1005A0002E020004104000032E0200080A00014041 +:1005B0000000802114400003000000000A000140F8 +:1005C0002610FFF90000000D2402000202021004B0 +:1005D0003C036000AC626914000018218FBF001C4E +:1005E0008FB200188FB100148FB00010006010217E +:1005F00003E0000827BD00203C0480008C8301003C +:1006000024020100506200033C0280080000000D3B +:100610003C02800890430004000010213063000F6A +:1006200000031D0003E00008AC8300800004188074 +:100630002782FF9C00621821000410C00044102390 +:100640008C640000000210C03C030800246356E4E0 +:10065000004310213C038000AC64009003E00008DC +:10066000AF8200243C0208008C42011410400019A3 +:100670003084400030A2007F000231C03C02020002 +:100680001080001400A218253C026020AC43001426 +:100690003C0408008C8456B83C0308008C630110AD +:1006A0003C02800024050900AC4500200086202182 +:1006B000246300013C028008AC4400643C01080053 +:1006C000AC2301103C010800AC2456B803E000083C +:1006D000000000003C02602003E00008AC4500146C +:1006E00003E000080000102103E0000800001021D2 +:1006F00030A2000810400008240201003C0208005B +:100700008C42010C244200013C010800AC22010C87 +:1007100003E0000800000000148200080000000050 +:100720003C0208008C4200FC244200013C0108000D +:10073000AC2200FC0A0001A330A200203C02080009 +:100740008C420084244200013C010800AC22008459 +:1007500030A200201040000830A200103C02080027 +:100760008C420108244200013C010800AC2201082F +:1007700003E0000800000000104000080000000036 +:100780003C0208008C420104244200013C010800A4 +:10079000AC22010403E00008000000003C02080055 +:1007A0008C420100244200013C010800AC220100FF +:1007B00003E000080000000027BDFFE0AFB1001417 +:1007C0003C118000AFB20018AFBF001CAFB00010EA +:1007D0003632010096500008320200041040000733 +:1007E000320300028FBF001C8FB200188FB10014BB +:1007F0008FB000100A0000CE27BD00201060000B53 +:10080000020028218E2401000E00018A0000000051 +:100810003202008010400003240500A10E000C6786 +:100820008E44001C0A0001E3240200018E2301040F +:100830008F82000810430006020028218E24010048 +:100840000E00018A000000008E220104AF82000821 +:10085000000010218FBF001C8FB200188FB1001450 +:100860008FB0001003E0000827BD00202C82000498 +:1008700014400002000018212483FFFD240200021E +:10088000006210043C03600003E00008AC626914DD +:1008900027BDFFE0AFBF001CAFB20018AFB100141E +:1008A000AFB000103C048000948201083043700017 +:1008B000240220001062000A2862200154400052E5 +:1008C0008FBF001C24024000106200482402600018 +:1008D0001062004A8FBF001C0A0002518FB200183C +:1008E00034820100904300098C5000189451000C90 +:1008F000240200091062001C0000902128620009F7 +:10090000144000218F8200242402000A5062001249 +:10091000323100FF2402000B1062000F00000000C3 +:100920002402000C146200188F8200243C0208008C +:100930008C4256B824030900AC83002000501021DB +:100940003C038008AC6200643C010800AC2256B84D +:100950000A0002508FBF001C0E0001E900102602A1 +:100960000A0002308F8200240E0001E900102602E6 +:100970003C0380089462001A8C72000C3042FFFF26 +:10098000020280258F8200248C42000C5040001E01 +:100990008FBF001C0E000D84000000003C02800090 +:1009A00034420100944300088F82002400031C009D +:1009B0009444001E8F82002000641825AC50000073 +:1009C00024040001AC510004AC520008AC40000CFF +:1009D000AC400010AC400014AC4000180E000DB844 +:1009E000AC43001C0A0002508FBF001C0E000440E4 +:1009F000000000000A0002508FBF001C0E000C9F78 +:100A0000000000008FBF001C8FB200188FB10014CF +:100A10008FB000100000102103E0000827BD002067 +:100A200027BDFFD8AFB400203C036010AFBF002447 +:100A3000AFB3001CAFB20018AFB10014AFB00010DC +:100A40008C6450002402FF7F3C1408002694563822 +:100A5000008220243484380CAC6450003C028000B6 +:100A6000240300370E0014B0AC4300083C07080014 +:100A700024E70618028010212404001D2484FFFFAF +:100A8000AC4700000481FFFD244200043C02080042 +:100A9000244207C83C010800AC2256403C02080032 +:100AA000244202303C030800246306203C04080072 +:100AB000248403B43C05080024A506F03C06080085 +:100AC00024C62C9C3C010800AC2256803C02080045 +:100AD000244205303C010800AC2756843C01080044 +:100AE000AC2656943C010800AC23569C3C010800FF +:100AF000AC2456A03C010800AC2556A43C010800DB +:100B0000AC2256A83C010800AC23563C3C0108002E +:100B1000AC2456443C010800AC2056603C0108005F +:100B2000AC2556643C010800AC2056703C0108001E +:100B3000AC27567C3C010800AC2656903C010800CE +:100B4000AC2356980E00056E00000000AF80000C2C +:100B50003C0280008C5300008F8300043C0208009C +:100B60008C420020106200213262000700008821C0 +:100B70002792FF9C3C100800261056E43C02080017 +:100B80008C42002024050001022518040043202483 +:100B90008F820004004310245044000C26310001D1 +:100BA00010800008AF9000248E4300003C028000BB +:100BB000AC4300900E000D4BAE05000C0A0002C1C4 +:100BC00026310001AE00000C263100012E22000269 +:100BD000261000381440FFE9265200043C020800A9 +:100BE0008C420020AF820004326200071040FFD91F +:100BF0003C028000326200011040002D326200028F +:100C00003C0580008CA2010000002021ACA2002045 +:100C10008CA301042C42078110400008ACA300A85B +:100C200094A2010824032000304270001443000302 +:100C30003C02800890420005304400FF0E0001593C +:100C4000000000003C0280009042010B304300FF96 +:100C50002C62001E54400004000310800E00018628 +:100C60000A0002EC00000000005410218C42000039 +:100C70000040F80900000000104000043C02800021 +:100C80008C4301043C026020AC4300143C02080089 +:100C90008C4200343C0440003C03800024420001AC +:100CA000AC6401383C010800AC220034326200021E +:100CB00010400010326200043C1080008E0201409F +:100CC000000020210E000159AE0200200E00038317 +:100CD000000000003C024000AE0201783C02080027 +:100CE0008C420038244200013C010800AC2200384C +:100CF000326200041040FF973C0280003C108000EC +:100D00008E020180000020210E000159AE02002059 +:100D10008E03018024020F00546200073C02800809 +:100D20008E0201883C0300E03042FFFF00431025A3 +:100D30000A000328AE020080344200809042000086 +:100D400024030050304200FF14430007000000005D +:100D50000E000362000000001440000300000000C9 +:100D60000E000971000000003C0208008C42003CAB +:100D70003C0440003C03800024420001AC6401B804 +:100D80003C010800AC22003C0A0002A33C028000A7 +:100D90003C02900034420001008220253C02800089 +:100DA000AC4400203C0380008C6200200440FFFE25 +:100DB0000000000003E00008000000003C0280008A +:100DC000344300010083202503E00008AC440020E8 +:100DD00027BDFFE0AFB10014AFB000100080882144 +:100DE000AFBF00180E00033230B000FF8F83FF94B6 +:100DF000022020219062002502028025A07000259B +:100E00008C7000183C0280000E00033D020280241A +:100E10001600000B8FBF00183C0480008C8201F884 +:100E20000440FFFE348201C024030002AC510000E4 +:100E3000A04300043C021000AC8201F88FBF0018F0 +:100E40008FB100148FB0001003E0000827BD002010 +:100E500027BDFFE83C028000AFBF00103442018094 +:100E6000944300048C4400083063020010600005C5 +:100E7000000028210E00100C000000000A0003787A +:100E8000240500013C02FF000480000700821824B2 +:100E90003C02040014620004240500018F82FF94C8 +:100EA00090420008240500018FBF001000A010210F +:100EB00003E0000827BD00188F82FF982405000179 +:100EC000A040001A3C028000344201400A00034264 +:100ED0008C4400008F85FF9427BDFFE0AFBF001C4E +:100EE000AFB20018AFB10014AFB0001090A2000074 +:100EF000304400FF38830020388200300003182B74 +:100F00000002102B0062182410600003240200501D +:100F1000148200A88FBF001C90A20005304200017F +:100F2000104000A48FBF001C3C02800034420140EE +:100F3000904200082443FFFF2C6200051040009EF1 +:100F40008FB20018000310803C030800246355ACE6 +:100F5000004310218C420000004000080000000007 +:100F60003C028000345101400E0003328E24000008 +:100F70008F92FF948E2200048E50000C1602000205 +:100F800024020001AE42000C0E00033D8E2400003E +:100F90008E220004145000068FBF001C8FB2001870 +:100FA0008FB100148FB000100A000F7827BD002009 +:100FB0008E42000C0A000419000000003C0480006E +:100FC0003482014094A300108C4200043063FFFF80 +:100FD0001443001C0000000024020001A4A2001021 +:100FE0008C8202380441000F3C0380003C02003F29 +:100FF0003448F0003C0760003C06FFC08CE22BBC8C +:1010000000461824004810240002130200031D8229 +:10101000106200583C0280008C8202380440FFF7C6 +:101020003C038000346201408C44000034620200C2 +:10103000AC4400003C021000AC6202380A00043BE1 +:101040008FBF001C94A200100A00041900000000C9 +:10105000240200201482000F3C0280003C03800028 +:1010600094A20012346301408C6300043042FFFFFD +:10107000146200050000000024020001A4A2001276 +:101080000A0004028FBF001C94A200120A00041977 +:1010900000000000345101400E0003328E24000095 +:1010A0008F92FF948E230004964200123050FFFF6F +:1010B0001603000224020001A64200120E00033DA6 +:1010C0008E2400008E220004160200068FBF001C32 +:1010D0008FB200188FB100148FB000100A00037C8B +:1010E00027BD0020964200120A00041900000000EB +:1010F0003C03800094A20014346301408C6300041C +:101100003042FFFF14620008240200018FBF001C60 +:101110008FB200188FB100148FB00010A4A2001479 +:101120000A00146327BD002094A20014144000217B +:101130008FBF001C0A000435000000003C03800043 +:1011400094A20016346301408C6300043042FFFF18 +:101150001462000D240200018FBF001C8FB2001822 +:101160008FB100148FB00010A4A200160A000B1457 +:1011700027BD00209442007824420004A4A200105D +:101180000A00043B8FBF001C94A200162403000138 +:101190003042FFFF144300078FBF001C3C020800D1 +:1011A0008C420070244200013C010800AC22007017 +:1011B0008FBF001C8FB200188FB100148FB00010C9 +:1011C00003E0000827BD002027BDFFD8AFB20018FC +:1011D0008F92FF94AFB10014AFBF0020AFB3001CDB +:1011E000AFB000103C028000345101008C5001006F +:1011F0009242000092230009304400FF2402001FA5 +:10120000106200AB28620020104000192402003850 +:101210002862000A1040000D2402000B286200081A +:101220001040002E8F820024046001042862000216 +:101230001440002A8F820024240200061062002637 +:101240008FBF00200A00055F8FB3001C1062006092 +:101250002862000B144000FA8FBF00202402000E09 +:10126000106200788F8200240A00055F8FB3001C93 +:10127000106200D2286200391040000A2402008067 +:1012800024020036106200E528620037104000C3D7 +:1012900024020035106200D98FBF00200A00055FCC +:1012A0008FB3001C1062002D2862008110400006E0 +:1012B000240200C824020039106200C98FBF002038 +:1012C0000A00055F8FB3001C106200A28FBF0020D0 +:1012D0000A00055F8FB3001C8F8200248C42000C33 +:1012E000104000D78FBF00200E000D8400000000CA +:1012F0003C038000346301008C6200008F85002075 +:10130000946700089466000CACA200008C64000492 +:101310008F82002400063400ACA400049448001E10 +:101320008C62001800073C0000E83825ACA20008D9 +:101330008C62001C24040001ACA2000C9062000A24 +:1013400000C23025ACA60010ACA00014ACA0001860 +:10135000ACA7001C0A00051D8FBF00208F8200244F +:101360008C42000C104000B68FBF00200E000D8490 +:10137000000000008F820024962400089625000CAF +:101380009443001E000422029626000E8F82002045 +:10139000000426000083202500052C003C0300806B +:1013A00000A6282500832025AC400000AC400004A6 +:1013B000AC400008AC40000CAC450010AC40001440 +:1013C000AC400018AC44001C0A00051C24040001B9 +:1013D0009622000C14400018000000009242000504 +:1013E0003042001014400014000000000E000332D0 +:1013F0000200202192420005020020213442001008 +:101400000E00033DA242000592420000240300208A +:10141000304200FF10430089020020218FBF0020CE +:101420008FB3001C8FB200188FB100148FB0001062 +:101430000A00107527BD00280000000D0A00055E97 +:101440008FBF00208C42000C1040007D8FBF002019 +:101450000E000D84000000008E2200048F84002006 +:101460009623000CAC8200003C0280089445002CBE +:101470008F82002400031C0030A5FFFF9446001E4D +:101480003C02400E0065182500C23025AC830004E4 +:10149000AC800008AC80000CAC800010AC80001464 +:1014A000AC800018AC86001C0A00051C2404000156 +:1014B0000E000332020020218F93FF9802002021AA +:1014C0000E00033DA660000C020020210E00034226 +:1014D000240500018F8200248C42000C104000582B +:1014E0008FBF00200E000D84000000009622000C2B +:1014F0008F83002000021400AC700000AC62000476 +:10150000AC6000088E4400388F820024AC64000C6C +:101510008E46003C9445001E3C02401FAC66001005 +:1015200000A228258E62000424040001AC6200148D +:10153000AC600018AC65001C8FBF00208FB3001C8E +:101540008FB200188FB100148FB000100A000DB8D0 +:1015500027BD0028240200201082003A8FB3001C0F +:101560000E000F5E00000000104000358FBF00200D +:101570003C0480008C8201F80440FFFE348201C0EC +:1015800024030002AC500000A04300043C02100001 +:10159000AC8201F80A00055E8FBF00200200202106 +:1015A0008FBF00208FB3001C8FB200188FB10014C2 +:1015B0008FB000100A000EA727BD00289625000C4A +:1015C000020020218FBF00208FB3001C8FB20018B3 +:1015D0008FB100148FB000100A000ECC27BD002878 +:1015E000020020218FB3001C8FB200188FB10014AD +:1015F0008FB000100A000EF727BD00289225000DBD +:10160000020020218FB3001C8FB200188FB100148C +:101610008FB000100A000F4827BD002802002021CB +:101620008FBF00208FB3001C8FB200188FB1001441 +:101630008FB000100A000F1F27BD00288FBF0020A9 +:101640008FB3001C8FB200188FB100148FB0001040 +:1016500003E0000827BD00283C0580008CA202782A +:101660000440FFFE34A2024024030002AC44000008 +:10167000A04300043C02100003E00008ACA2027882 +:10168000A380001803E00008A38000193C03800039 +:101690008C6202780440FFFE8F82001CAC62024024 +:1016A00024020002A06202443C02100003E0000891 +:1016B000AC6202783C02600003E000088C425404F3 +:1016C0009083003024020005008040213063003FF9 +:1016D0000000482114620005000050219082004C57 +:1016E0009483004E304900FF306AFFFFAD00000CCC +:1016F000AD000010AD000024950200148D05001C03 +:101700008D0400183042FFFF004910230002110031 +:10171000000237C3004038210086202300A2102B8E +:101720000082202300A72823AD05001CAD0400186B +:10173000A5090014A5090020A50A001603E0000869 +:10174000A50A002203E000080000000027BDFFD822 +:10175000AFB200183C128008AFB40020AFB3001C39 +:10176000AFB10014AFBF0024AFB00010365101007C +:101770003C0260008C4254049222000C3C1408008D +:10178000929400F7304300FF2402000110620032FF +:101790000080982124020002146200353650008037 +:1017A0000E00143D000000009202004C2403FF8054 +:1017B0003C0480003042007F000211C024420240FD +:1017C0000262102100431824AC8300949245000863 +:1017D0009204004C3042007F3C03800614850007D1 +:1017E000004380212402FFFFA22200112402FFFFF8 +:1017F000A62200120A0005D22402FFFF9602002052 +:10180000A222001196020022A62200128E020024BB +:101810003C048008AE2200143485008090A2004C65 +:1018200034830100A06200108CA2003CAC6200185E +:101830008C820068AC6200F48C820064AC6200F0C0 +:101840008C82006CAC6200F824020001A0A2006847 +:101850000A0005EE3C0480080E001456000000004B +:1018600036420080A04000680A0005EE3C04800873 +:10187000A2000068A20000690A0006293C02800854 +:10188000348300808C62003834850100AC62006CC7 +:1018900024020001A062006990A200D59083000894 +:1018A000305100FF3072007F12320019001111C058 +:1018B00024420240026210212403FF8000431824C6 +:1018C0003C048000AC8300943042007F3C038006DF +:1018D000004380218E02000C1040000D02002021E8 +:1018E0000E00057E0000000026220001305100FF9E +:1018F0009203003C023410260002102B0002102339 +:101900003063007F022288240A0005F8A203003C0D +:101910003C088008350401008C8200E03507008017 +:10192000ACE2003C8C8200E0AD02000090E5004C8F +:10193000908600D590E3004C908400D52402FF806F +:1019400000A228243063007F308400FF00A62825F1 +:101950000064182A1060000230A500FF38A500803E +:10196000A0E5004CA10500093C0280089043000E50 +:10197000344400803C058000A043000A8C8300189A +:101980003C027FFF3442FFFF00621824AC83001842 +:101990008CA201F80440FFFE00000000ACB301C0BF +:1019A0008FBF00248FB400208FB3001C8FB20018AB +:1019B0008FB100148FB0001024020002A0A201C455 +:1019C00027BD00283C02100003E00008ACA201F88B +:1019D00090A2000024420001A0A200003C030800E5 +:1019E0008C6300F4304200FF144300020080302179 +:1019F000A0A0000090A200008F84001C000211C073 +:101A00002442024024830040008220212402FF80DF +:101A1000008220243063007F3C02800A006218218B +:101A20003C028000AC44002403E00008ACC300008A +:101A300094820006908300058C85000C8C86001033 +:101A40008C8700188C88001C8C8400203C010800C6 +:101A5000A42256C63C010800A02356C53C0108003C +:101A6000AC2556CC3C010800AC2656D03C01080001 +:101A7000AC2756D83C010800AC2856DC3C010800D5 +:101A8000AC2456E003E00008000000003C0280089F +:101A9000344201008C4400343C038000346504006F +:101AA000AC6400388C420038AF850028AC62003C42 +:101AB0003C020005AC6200300000000000000000A5 +:101AC00003E00008000000003C020006308400FF34 +:101AD000008220253C028000AC4400300000000061 +:101AE00000000000000000003C0380008C62000049 +:101AF000304200101040FFFD3462040003E0000893 +:101B0000AF82002894C200003C080800950800CA73 +:101B100030E7FFFF0080482101021021A4C200002D +:101B200094C200003042FFFF00E2102B544000013D +:101B3000A4C7000094A200003C0308008C6300CC02 +:101B400024420001A4A2000094A200003042FFFF42 +:101B5000144300073C0280080107102BA4A00000DA +:101B60005440000101003821A4C700003C02800855 +:101B7000344601008CC3002894A200003C0480007D +:101B80003042FFFE000210C000621021AC82003C17 +:101B90008C82003C006218231860000400000000E2 +:101BA0008CC200240A0006BA244200018CC2002420 +:101BB000AC8200383C020050344200103C038000EC +:101BC000AC620030000000000000000000000000D7 +:101BD0008C620000304200201040FFFD0000000039 +:101BE00094A200003C04800030420001000210C0BA +:101BF000004410218C430400AD2300008C420404F7 +:101C0000AD2200043C02002003E00008AC8200305A +:101C100027BDFFE0AFB20018AFB10014AFB00010A5 +:101C2000AFBF001C94C2000000C080213C1208001D +:101C3000965200C624420001A6020000960300004E +:101C400094E2000000E03021144300058FB1003021 +:101C50000E00068F024038210A0006F10000000045 +:101C60008C8300048C82000424420040046100073D +:101C7000AC8200048C8200040440000400000000D8 +:101C80008C82000024420001AC8200009602000019 +:101C90003042FFFF50520001A600000096220000D3 +:101CA00024420001A62200003C02800834420100C8 +:101CB000962300009442003C144300048FBF001C94 +:101CC00024020001A62200008FBF001C8FB2001862 +:101CD0008FB100148FB0001003E0000827BD002072 +:101CE00027BDFFE03C028008AFBF0018344201006E +:101CF0008C4800343C03800034690400AC68003830 +:101D00008C42003830E700FFAF890028AC62003C0D +:101D10003C020005AC620030000000000000000042 +:101D200000000000000000000000000000000000B3 +:101D30008C82000C8C82000C97830016AD22000070 +:101D40008C82001000604021AD2200048C820018BB +:101D5000AD2200088C82001CAD22000C8CA2001465 +:101D6000AD2200108C820020AD220014908200056C +:101D7000304200FF00021200AD2200188CA20018B1 +:101D8000AD22001C8CA2000CAD2200208CA2001001 +:101D9000AD2200248CA2001CAD2200288CA20020C1 +:101DA000AD22002C3402FFFFAD260030AD20003400 +:101DB000506200013408FFFFAD28003850E00011E8 +:101DC0003C0280083C048008348401009482005066 +:101DD0003042FFFFAD22003C9483004494850044D0 +:101DE000240200013063FFFF000318C200641821C1 +:101DF0009064006430A5000700A210040A00075C8C +:101E00000044102534420100AD20003C94430044BE +:101E1000944400443063FFFF000318C2006218219D +:101E200030840007906500642402000100821004E1 +:101E30000002102700451024A0620064000000008A +:101E400000000000000000003C0200063442004098 +:101E50003C038000AC620030000000000000000085 +:101E6000000000008C620000304200101040FFFDB6 +:101E70003C06800834C201503463040034C7014A70 +:101E800034C4013434C5014034C60144AFA200104B +:101E90000E0006D2AF8300288FBF001803E00008B1 +:101EA00027BD00208F8300143C0608008CC600E884 +:101EB0008F82001C30633FFF000319800046102111 +:101EC000004310212403FF80004318243C068000B7 +:101ED000ACC300283042007F3C03800C004330211B +:101EE00090C2000D30A500FF0000382134420010E0 +:101EF000A0C2000D8F8900143C028008344201000A +:101F00009443004400091382304800032402000176 +:101F1000A4C3000E1102000B2902000210400005AC +:101F2000240200021100000C240300010A0007A48F +:101F30000000182111020006000000000A0007A49A +:101F4000000018218CC2002C0A0007A424430001C1 +:101F50008CC20014244300018CC200180043102BD3 +:101F60005040000A240700012402002714A20003A5 +:101F70003C0380080A0007B1240700013463010014 +:101F80009462004C24420001A462004C00091382B8 +:101F9000304300032C620002104000090080282119 +:101FA000146000040000000094C200340A0007C15D +:101FB0003046FFFF8CC600380A0007C10080282188 +:101FC000000030213C040800248456C00A000706A3 +:101FD0000000000027BDFF90AFB60068AFB50064F9 +:101FE000AFB40060AFB3005CAFB20058AFB1005403 +:101FF000AFBF006CAFB000508C9000000080B021EB +:102000003C0208008C4200E8960400328F83001CDA +:102010002414FF8030843FFF0062182100042180D7 +:1020200000641821007410243C13800000A090214B +:1020300090A50000AE620028920400323C02800CA1 +:102040003063007F00628821308400C02402004099 +:10205000148200320000A8218E3500388E2200182C +:102060001440000224020001AE2200189202003C3B +:10207000304200201440000E8F83001C000511C068 +:102080002442024000621821306400783C02008043 +:102090000082202500741824AE630800AE64081086 +:1020A0008E2200188E03000800431021AE22001873 +:1020B0008E22002C8E230018244200010062182B6F +:1020C0001060004300000000924200002442000122 +:1020D000A24200003C0308008C6300F4304200FF81 +:1020E00050430001A2400000924200008F84001C77 +:1020F000000211C024420240248300403063007F6C +:10210000008220213C02800A0094202400621821D1 +:10211000AE6400240A0008D2AEC30000920300326D +:102120002402FFC000431024304200FF1440000589 +:1021300024020001AE220018962200340A00084250 +:102140003055FFFF8E22001424420001AE220018F9 +:102150009202003000021600000216030441001C27 +:10216000000000009602003227A400100080282101 +:10217000A7A20016960200320000302124070001B9 +:102180003042FFFFAF8200140E000706AFA0001C14 +:10219000960200328F83001C3C0408008C8400E807 +:1021A00030423FFF000211800064182100621821B4 +:1021B00000741024AE62002C3063007F3C02800E5D +:1021C000006218219062000D3042007FA062000D75 +:1021D0009222000D304200105040007892420000E0 +:1021E0003C028008344401009482004C8EC30000FD +:1021F0003C130800967300C62442FFFFA482004CE3 +:10220000946200329623000E3054FFFF3070FFFFBF +:102210003C0308008C6300D000701807A7A30038A7 +:102220009482003E3063FFFF3042FFFF14620007DC +:10223000000000008C8200303C038000244200300B +:10224000AC62003C0A00086A8C82002C9482004038 +:102250003042FFFF5462000927A400408C820038FE +:102260003C03800024420030AC62003C8C8200348D +:10227000AC6200380A0008793C03800027A50038CA +:1022800027A60048026038210E00068FA7A000484C +:102290008FA300403C02800024630030AC43003830 +:1022A0008FA30044AC43003C3C0380003C0200058B +:1022B000AC6200303C028008344401009482004249 +:1022C000346304003042FFFF0202102B1440000769 +:1022D000AF8300289482004E9483004202021021B2 +:1022E000004310230A00088F3043FFFF9483004E01 +:1022F00094820042026318210050102300621823C8 +:102300003063FFFF3C028008344401009482003CAB +:102310003042FFFF14430003000000000A00089F42 +:10232000240300019482003C3042FFFF0062102B26 +:10233000144000058F8200289482003C0062102324 +:102340003043FFFF8F820028AC550000AC400004F2 +:10235000AC540008AC43000C3C02000634420010B0 +:102360003C038000AC620030000000000000000070 +:10237000000000008C620000304200101040FFFDA1 +:102380003C04800834840100001018C20064182145 +:102390009065006432020007240600010046100424 +:1023A00000451025A0620064948300429622000E2E +:1023B00050430001A386001892420000244200010D +:1023C000A24200003C0308008C6300F4304200FF8E +:1023D00050430001A2400000924200008F84001C84 +:1023E000000211C0244202402483004000822021C8 +:1023F0002402FF80008220243063007F3C02800A98 +:10240000006218213C028000AC440024AEC30000EE +:102410008FBF006C8FB600688FB500648FB400600A +:102420008FB3005C8FB200588FB100548FB0005052 +:1024300003E0000827BD007027BDFFD8AFB3001C24 +:10244000AFB20018AFB10014AFB00010AFBF0020A2 +:102450000080982100E0802130B1FFFF0E000D8444 +:1024600030D200FF0000000000000000000000006B +:102470008F8200208F830024AC510000AC520004F6 +:10248000AC530008AC40000CAC400010AC40001451 +:10249000AC4000189463001E02038025AC50001C61 +:1024A0000000000000000000000000002404000103 +:1024B0008FBF00208FB3001C8FB200188FB10014A3 +:1024C0008FB000100A000DB827BD002830A5FFFF0F +:1024D0000A0008DC30C600FF3C02800834430100DB +:1024E0009462000E3C080800950800C63046FFFFC5 +:1024F00014C000043402FFFF946500EA0A000929B1 +:102500008F84001C10C20027000000009462004E5F +:102510009464003C3045FFFF00A6102300A6182B52 +:102520003087FFFF106000043044FFFF00C5102318 +:1025300000E210233044FFFF0088102B1040000EF3 +:1025400000E810233C028008344401002403000109 +:1025500034420080A44300162402FFFFA482000E30 +:10256000948500EA8F84001C0000302130A5FFFF15 +:102570000A0009013C0760200044102A10400009AD +:102580003C0280083443008094620016304200010F +:10259000104000043C0280009442007E244200145B +:1025A000A462001603E000080000000027BDFFE061 +:1025B0003C028008AFBF001CAFB0001834420100DD +:1025C000944300429442004C104000193068FFFFD1 +:1025D0009383001824020001146200298FBF001C9D +:1025E0003C06800834D00100000810C200501021C1 +:1025F000904200643103000734C70148304200FFB5 +:10260000006210073042000134C9014E34C4012C6D +:1026100034C5013E1040001634C601420E0006D2F9 +:10262000AFA90010960200420A0009463048FFFF99 +:102630003C028008344401009483004494820042A8 +:102640001043000F8FBF001C94820044A4820042FC +:1026500094820050A482004E8C820038AC820030FC +:1026600094820040A482003E9482004AA4820048E2 +:102670008FBF001C8FB000180A00090427BD00207E +:102680008FB0001803E0000827BD002027BDFFA081 +:10269000AFB1004C3C118000AFBF0058AFB3005445 +:1026A000AFB20050AFB000483626018890C2000398 +:1026B0003044007FA3A400108E32018090C200003D +:1026C0003043007F240200031062003BAF92001CE5 +:1026D00028620004104000062402000424020002C4 +:1026E000106200098FBF00580A000B0F8FB300540F +:1026F0001062004D240200051062014E8FBF005889 +:102700000A000B0F8FB30054000411C002421021C5 +:102710002404FF8024420240004410242643004049 +:10272000AE2200243063007F3C02800A0062182140 +:102730009062003CAFA3003C00441025A062003C26 +:102740008FA3003C9062003C304200401040016C7E +:102750008FBF00583C108008A3800018361001007D +:102760008E0200E08C63003427A4003C27A50010F3 +:10277000004310210E0007C3AE0200E093A2001038 +:102780003C038000A20200D58C6202780440FFFE68 +:102790008F82001CAC62024024020002A06202444C +:1027A0003C021000AC6202780E0009390000000003 +:1027B0000A000B0E8FBF00583C05800890C3000133 +:1027C00090A2000B1443014E8FBF005834A4008028 +:1027D0008C8200189082004C90A200083C0260009D +:1027E0008C4254048C8300183C027FFF3442FFFF6C +:1027F000006218243C0208008C4200B4AC8300182C +:102800003C038000244200013C010800AC2200B4DB +:102810008C6201F80440FFFE8F82001CAC6201C094 +:102820000A000AD6240200023C10800890C300016E +:102830009202000B144301328FBF005827A40018E6 +:1028400036050110240600033C0260008C4254044B +:102850000E000E470000000027A40028360501F0F6 +:102860000E000E47240600038FA200283603010045 +:10287000AE0200648FA2002CAE0200688FA200306E +:10288000AE02006C93A40018906300D52402FF8070 +:102890000082102400431025304900FF3084007F5F +:1028A0003122007F0082102A544000013929008023 +:1028B000000411C0244202402403FF800242102180 +:1028C00000431024AE220094264200403042007F94 +:1028D0003C038006004340218FA3001C2402FFFF1D +:1028E000AFA800403C130800927300F71062003359 +:1028F00093A2001995030014304400FF3063FFFFDA +:102900000064182B106000100000000095040014F3 +:102910008D07001C8D0600183084FFFF0044202323 +:102920000004210000E438210000102100E4202BE5 +:1029300000C2302100C43021AD07001CAD060018D4 +:102940000A000A2F93A20019950400148D07001C99 +:102950008D0600183084FFFF008220230004210030 +:10296000000010210080182100C2302300E4202B39 +:1029700000C4302300E33823AD07001CAD06001867 +:1029800093A200198FA30040A462001497A2001A1A +:10299000A46200168FA2001CAC6200108FA2001C63 +:1029A000AC62000C93A20019A462002097A2001A46 +:1029B000A46200228FA2001CAC6200243C048008A8 +:1029C000348300808C6200388FA20020012088218F +:1029D000AC62003C8FA20020AC82000093A20018E1 +:1029E000A062004C93A20018A0820009A0600068B9 +:1029F00093A20018105100512407FF803229007F54 +:102A0000000911C024420240024210213046007FDA +:102A10003C03800000471024AC6200943C02800616 +:102A200000C2302190C2003CAFA60040000020212F +:102A300000471025A0C2003C8FA80040950200026C +:102A4000950300148D07001C3042FFFF3063FFFF29 +:102A50008D060018004310230002110000E2382107 +:102A600000E2102B00C4302100C23021AD07001C51 +:102A7000AD06001895020002A5020014A50000167C +:102A80008D020008AD0200108D020008AD02000C9E +:102A900095020002A5020020A50000228D02000878 +:102AA000AD0200249102003C304200401040001A68 +:102AB000262200013C108008A3A90038A38000183A +:102AC000361001008E0200E08D03003427A4004080 +:102AD00027A50038004310210E0007C3AE0200E016 +:102AE00093A200383C038000A20200D58C620278D9 +:102AF0000440FFFE8F82001CAC62024024020002F0 +:102B0000A06202443C021000AC6202780E00093957 +:102B100000000000262200013043007F14730004EF +:102B2000004020212403FF8002231024004320269C +:102B300093A200180A000A4B309100FF93A40018DA +:102B40008FA3001C2402FFFF1062000A308900FFDF +:102B500024820001248300013042007F14530005C9 +:102B6000306900FF2403FF800083102400431026F7 +:102B7000304900FF3C028008904200080120882173 +:102B8000305000FF123000193222007F000211C0C5 +:102B900002421021244202402403FF8000431824F3 +:102BA0003C048000AC8300943042007F3C038006EC +:102BB000004310218C43000C004020211060000BCA +:102BC000AFA200400E00057E000000002623000199 +:102BD0002405FF803062007F145300020225202468 +:102BE000008518260A000AAF307100FF3C048008F7 +:102BF000348400808C8300183C027FFF3442FFFF46 +:102C000000621824AC8300183C0380008C6201F839 +:102C10000440FFFE00000000AC7201C0240200026C +:102C2000A06201C43C021000AC6201F80A000B0E65 +:102C30008FBF00583C04800890C300019082000BB5 +:102C40001443002F8FBF0058349000809202000878 +:102C500030420040104000200000000092020008B6 +:102C60000002160000021603044100050240202164 +:102C70000E000ECC240500930A000B0E8FBF0058E7 +:102C80009202000924030018304200FF1443000D93 +:102C900002402021240500390E000E64000030217E +:102CA0000E0003328F84001C8F82FF9424030012D5 +:102CB000A04300090E00033D8F84001C0A000B0E88 +:102CC0008FBF0058240500360E000E64000030212E +:102CD0000A000B0E8FBF00580E0003320240202165 +:102CE000920200058F84001C344200200E00033D38 +:102CF000A20200050E0010758F84001C8FBF0058C3 +:102D00008FB300548FB200508FB1004C8FB0004889 +:102D100003E0000827BD00603C0280083445010044 +:102D20003C0280008C42014094A3000E0000302140 +:102D300000402021AF82001C3063FFFF3402FFFF00 +:102D4000106200063C0760202402FFFFA4A2000ED0 +:102D500094A500EA0A00090130A5FFFF03E000087E +:102D60000000000027BDFFC83C0280003C06800830 +:102D7000AFB5002CAFB1001CAFBF0030AFB400281E +:102D8000AFB30024AFB20020AFB00018345101003F +:102D900034C501008C4301008E2200148CA400E491 +:102DA0000000A821AF83001C0044102318400052EB +:102DB000A38000188E22001400005021ACA200E471 +:102DC00090C3000890A200D53073007FA3A200102A +:102DD0008CB200E08CB400E4304200FF1053003BA2 +:102DE00093A200108F83001C2407FF80000211C0F3 +:102DF0000062102124420240246300400047102456 +:102E00003063007F3C0980003C08800A006818217C +:102E1000AD2200248C62003427A4001427A50010E2 +:102E2000024280210290102304400028AFA3001426 +:102E30009062003C00E21024304200FF1440001970 +:102E4000020090219062003C34420040A062003CAD +:102E50008F86001C93A3001024C200403042007FE4 +:102E6000004828213C0208008C4200F42463000141 +:102E7000306400FF14820002A3A30010A3A000107E +:102E800093A20010AFA50014000211C0244202401A +:102E900000C2102100471024AD2200240A000B4577 +:102EA00093A200100E0007C3000000003C0280083F +:102EB00034420100AC5000E093A30010240A00014A +:102EC000A04300D50A000B4593A200102402000184 +:102ED000154200093C0380008C6202780440FFFE2A +:102EE0008F82001CAC62024024020002A0620244F5 +:102EF0003C021000AC6202789222000B2403000214 +:102F0000304200FF144300720000000096220008C7 +:102F1000304300FF24020082146200402402008437 +:102F20003C028000344901008D22000C95230006EC +:102F3000000216023063FFFF3045003F24020027E5 +:102F400010A2000FAF83001428A200281040000830 +:102F5000240200312402002110A2000924020025CD +:102F600010A20007938200190A000BBD00000000A8 +:102F700010A20007938200190A000BBD0000000098 +:102F80000E000777012020210A000C3D0000000000 +:102F90003C0380008C6202780440FFFE8F82001C9C +:102FA000AC62024024020002A06202443C02100013 +:102FB000AC6202780A000C3D000000009523000678 +:102FC000912400058D25000C8D2600108D270018FA +:102FD0008D28001C8D290020244200013C0108009E +:102FE000A42356C63C010800A02456C53C01080095 +:102FF000AC2556CC3C010800AC2656D03C0108005C +:10300000AC2756D83C010800AC2856DC3C0108002F +:10301000AC2956E00A000C3DA38200191462000A94 +:10302000240200813C02800834420100944500EAF9 +:10303000922600058F84001C30A5FFFF30C600FFDC +:103040000A000BFE3C0760211462005C00000000D7 +:103050009222000A304300FF306200201040000737 +:10306000306200403C02800834420100944500EA8E +:103070008F84001C0A000BFC24060040104000074F +:10308000000316003C02800834420100944500EA27 +:103090008F84001C0A000BFC24060041000216036A +:1030A000044100463C02800834420100944500EA95 +:1030B0008F84001C2406004230A5FFFF3C076019E6 +:1030C0000E000901000000000A000C3D0000000095 +:1030D0009222000B24040016304200FF1044000628 +:1030E0003C0680009222000B24030017304200FFB0 +:1030F000144300320000000034C5010090A2000B10 +:10310000304200FF1444000B000080218CA20020FC +:103110008CA400202403FF800043102400021140EF +:103120003084007F004410253C032000004310251C +:10313000ACC2083094A2000800021400000214037C +:10314000044200012410000194A2000830420080D3 +:103150005040001A0200A82194A20008304220002A +:10316000504000160200A8218CA300183C021C2D20 +:10317000344219ED106200110200A8213C0208003F +:103180008C4200D4104000053C0280082403000457 +:1031900034420100A04300FC3C028008344201009C +:1031A000944500EA8F84001C2406000630A5FFFF2A +:1031B0000E0009013C0760210200A8210E00093918 +:1031C000000000009222000A304200081040000473 +:1031D00002A010210E0013790000000002A01021AF +:1031E0008FBF00308FB5002C8FB400288FB3002420 +:1031F0008FB200208FB1001C8FB0001803E00008D0 +:1032000027BD00382402FF80008220243C02900069 +:1032100034420007008220253C028000AC4400209C +:103220003C0380008C6200200440FFFE0000000090 +:1032300003E00008000000003C0380002402FF803F +:10324000008220243462000700822025AC64002024 +:103250008C6200200440FFFE0000000003E0000834 +:103260000000000027BDFFD8AFB3001CAFB10014B1 +:10327000AFB00010AFBF0020AFB200183C1180000B +:103280003C0280088E32002034530100AE2400201E +:10329000966300EA000514003C074000004738250B +:1032A00000A08021000030210E0009013065FFFFE1 +:1032B000240200A1160200022402FFFFA2620009FC +:1032C000AE3200208FBF00208FB3001C8FB20018D9 +:1032D0008FB100148FB0001003E0000827BD002854 +:1032E0003C0280082403000527BDFFE834420100AA +:1032F000A04300FCAFBF00103C0280008C420100E4 +:10330000240500A1004020210E000C67AF82001CA4 +:103310003C0380008C6202780440FFFE8F82001C18 +:103320008FBF001027BD0018AC62024024020002CB +:10333000A06202443C021000AC62027803E0000884 +:103340000000000027BDFFE83C068000AFBF001072 +:1033500034C7010094E20008304400FF3883008243 +:10336000388200842C6300012C4200010062182581 +:103370001060002D24020083938200195040003B0E +:103380008FBF00103C020800904256CC8CC4010054 +:103390003C06080094C656C63045003F38A30032AC +:1033A00038A2003F2C6300012C4200010062182566 +:1033B000AF84001CAF860014A380001914600007BE +:1033C00000E020212402002014A2001200000000CE +:1033D0003402FFFF14C2000F00000000240200208E +:1033E00014A2000500E028218CE300142402FFFF52 +:1033F0005062000B8FBF00103C040800248456C0AC +:10340000000030210E000706240700010A000CD638 +:103410008FBF00100E000777000000008FBF001064 +:103420000A00093927BD001814820004240200850F +:103430008CC501040A000CE1000020211482000662 +:103440002482FF808CC50104240440008FBF00103B +:103450000A00016727BD0018304200FF2C4200021D +:1034600010400004240200228FBF00100A000B2726 +:1034700027BD0018148200048F8200248FBF001023 +:103480000A000C8627BD00188C42000C1040001E5C +:1034900000E0282190E300092402001814620003D0 +:1034A000240200160A000CFC240300081462000722 +:1034B00024020017240300123C02800834420080DA +:1034C000A04300090A000D0994A7000854620007F0 +:1034D00094A700088F82FF942404FFFE9043000508 +:1034E00000641824A043000594A7000890A6001BC0 +:1034F0008CA4000094A500068FBF001000073C00BC +:103500000A0008DC27BD00188FBF001003E0000888 +:1035100027BD00188F8500243C04800094A2002A57 +:103520008CA30034000230C02402FFF000C210243B +:1035300000621821AC83003C8CA200303C03800068 +:10354000AC8200383C02005034420010AC620030C3 +:103550000000000000000000000000008C6200007D +:10356000304200201040FFFD30C20008104000062D +:103570003C0280008C620408ACA200208C62040C27 +:103580000A000D34ACA200248C430400ACA300203C +:103590008C420404ACA200243C0300203C028000C6 +:1035A000AC4300303C0480008C8200300043102487 +:1035B0001440FFFD8F8600243C020040AC820030A6 +:1035C00094C3002A94C2002894C4002C94C5002EF1 +:1035D00024630001004410213064FFFFA4C20028CE +:1035E00014850002A4C3002AA4C0002A03E0000836 +:1035F000000000008F84002427BDFFE83C05800404 +:1036000024840010AFBF00100E000E472406000AED +:103610008F840024948200129483002E3042000F85 +:10362000244200030043180424027FFF0043102BB0 +:1036300010400002AC8300000000000D0E000D13CE +:10364000000000008F8300248FBF001027BD0018EA +:10365000946200149463001A3042000F00021500B7 +:10366000006218253C02800003E00008AC4300A083 +:103670008F8300243C028004944400069462001A64 +:103680008C650000A4640016004410233042FFFF44 +:103690000045102B03E00008384200018F8400240D +:1036A0003C0780049486001A8C85000094E2000692 +:1036B000A482001694E3000600C310233042FFFFEB +:1036C0000045102B384200011440FFF8A483001677 +:1036D00003E00008000000008F8400243C02800406 +:1036E000944200069483001A8C850000A482001680 +:1036F000006210233042FFFF0045102B38420001CA +:103700005040000D8F850024006030213C0780046C +:1037100094E20006A482001694E3000600C310237E +:103720003042FFFF0045102B384200011440FFF8E3 +:10373000A48300168F8500243C03800034620400BB +:103740008CA40020AF820020AC6400388CA200243E +:10375000AC62003C3C020005AC62003003E00008B3 +:10376000ACA000048F8400243C0300068C8200047B +:1037700000021140004310253C038000AC62003081 +:103780000000000000000000000000008C6200004B +:10379000304200101040FFFD34620400AC80000491 +:1037A00003E00008AF8200208F86002427BDFFE0E1 +:1037B000AFB10014AFB00010AFBF00188CC300044D +:1037C0008CC500248F820020309000FF94C4001A22 +:1037D00024630001244200202484000124A7002047 +:1037E000ACC30004AF820020A4C4001AACC70024FC +:1037F00004A100060000882104E2000594C2001A1A +:103800008CC2002024420001ACC2002094C2001AE5 +:1038100094C300282E040001004310262C4200010E +:10382000004410245040000594C2001A24020001F4 +:10383000ACC2000894C2001A94C300280010202BC8 +:10384000004310262C4200010044102514400007BC +:10385000000000008CC20008144000042402001084 +:103860008CC300041462000F8F8500240E000DA786 +:10387000241100018F820024944300289442001AEE +:1038800014430003000000000E000D1300000000B0 +:10389000160000048F8500240E000D840000000037 +:1038A0008F85002494A2001E94A4001C24420001D1 +:1038B0003043FFFF14640002A4A2001EA4A0001E57 +:1038C0001200000A3C02800494A2001494A3001A7F +:1038D0003042000F00021500006218253C028000F3 +:1038E000AC4300A00A000E1EACA0000894420006E3 +:1038F00094A3001A8CA40000A4A200160062102356 +:103900003042FFFF0044102B384200011040000DF0 +:1039100002201021006030213C07800494E2000660 +:10392000A4A2001694E3000600C310233042FFFF58 +:103930000044102B384200011440FFF8A4A30016E5 +:10394000022010218FBF00188FB100148FB000101B +:1039500003E0000827BD002003E00008000000008D +:103960008F82002C3C03000600021140004310250A +:103970003C038000AC62003000000000000000004A +:10398000000000008C620000304200101040FFFD7B +:1039900034620400AF82002803E00008AF80002CEE +:1039A00003E000080000102103E000080000000010 +:1039B0003084FFFF30A5FFFF0000182110800007B2 +:1039C000000000003082000110400002000420428C +:1039D000006518210A000E3D0005284003E000089C +:1039E0000060102110C0000624C6FFFF8CA200005A +:1039F00024A50004AC8200000A000E4724840004C1 +:103A000003E000080000000010A0000824A3FFFF4E +:103A1000AC86000000000000000000002402FFFF50 +:103A20002463FFFF1462FFFA2484000403E000080B +:103A3000000000003C0280083442008024030001A2 +:103A4000AC43000CA4430010A4430012A443001490 +:103A500003E00008A44300168F82002427BDFFD88E +:103A6000AFB3001CAFB20018AFB10014AFB000107C +:103A7000AFBF00208C47000C248200802409FF8007 +:103A80003C08800E3043007F008080213C0A80008B +:103A9000004920240068182130B100FF30D200FF17 +:103AA00010E000290000982126020100AD44002CFE +:103AB000004928243042007F004820219062000005 +:103AC00024030050304200FF1443000400000000B3 +:103AD000AD45002C948200EA3053FFFF0E000D84A8 +:103AE000000000008F8200248F83002000112C0032 +:103AF0009442001E001224003484000100A22825F4 +:103B00003C02400000A22825AC7000008FBF0020BE +:103B1000AC6000048FB20018AC7300088FB10014C1 +:103B2000AC60000C8FB3001CAC6400108FB00010B0 +:103B3000AC60001424040001AC60001827BD00280C +:103B40000A000DB8AC65001C8FBF00208FB3001CAD +:103B50008FB200188FB100148FB0001003E000087E +:103B600027BD00283C06800034C201009043000FAE +:103B7000240200101062000E2865001110A000073A +:103B800024020012240200082405003A10620006F4 +:103B90000000302103E0000800000000240500358B +:103BA0001462FFFC000030210A000E6400000000D7 +:103BB0008CC200748F83FF9424420FA003E000089E +:103BC000AC62000C27BDFFE8AFBF00100E0003423F +:103BD000240500013C0480088FBF0010240200016E +:103BE00034830080A462001227BD00182402000163 +:103BF00003E00008A080001A27BDFFE0AFB2001864 +:103C0000AFB10014AFB00010AFBF001C30B2FFFF67 +:103C10000E000332008088213C028008345000806E +:103C20009202000924030004304200FF1443000CF8 +:103C30003C028008124000082402000A0E000E5BBD +:103C400000000000920200052403FFFE0043102440 +:103C5000A202000524020012A20200093C02800810 +:103C600034420080022020210E00033DA0400027A6 +:103C700016400003022020210E000EBF00000000AD +:103C800002202021324600FF8FBF001C8FB2001897 +:103C90008FB100148FB00010240500380A000E64A4 +:103CA00027BD002027BDFFE0AFBF001CAFB200184A +:103CB000AFB10014AFB000100E00033200808021BD +:103CC0000E000E5B000000003C02800834450080BE +:103CD00090A2000924120018305100FF1232000394 +:103CE0000200202124020012A0A2000990A20005D7 +:103CF0002403FFFE004310240E00033DA0A2000594 +:103D00000200202124050020163200070000302187 +:103D10008FBF001C8FB200188FB100148FB000103D +:103D20000A00034227BD00208FBF001C8FB200187D +:103D30008FB100148FB00010240500390A000E6402 +:103D400027BD002027BDFFE83C028000AFB0001077 +:103D5000AFBF0014344201009442000C2405003629 +:103D60000080802114400012304600FF0E00033214 +:103D7000000000003C02800834420080240300124E +:103D8000A043000990430005346300100E000E5B51 +:103D9000A04300050E00033D020020210200202167 +:103DA0000E000342240500200A000F3C0000000022 +:103DB0000E000E64000000000E00033202002021FD +:103DC0003C0280089043001B2405FF9F0200202135 +:103DD000006518248FBF00148FB00010A043001B93 +:103DE0000A00033D27BD001827BDFFE0AFBF001844 +:103DF000AFB10014AFB0001030B100FF0E000332BD +:103E0000008080213C02800824030012344200809C +:103E10000E000E5BA04300090E00033D02002021AE +:103E200002002021022030218FBF00188FB1001422 +:103E30008FB00010240500350A000E6427BD002055 +:103E40003C0480089083000E9082000A1443000B0B +:103E5000000028218F82FF942403005024050001D4 +:103E600090420000304200FF1443000400000000B4 +:103E70009082000E24420001A082000E03E00008A0 +:103E800000A010213C0380008C6201F80440FFFE7A +:103E900024020002AC6401C0A06201C43C02100014 +:103EA00003E00008AC6201F827BDFFE0AFB20018E4 +:103EB0003C128008AFB10014AFBF001CAFB00010BF +:103EC00036510080922200092403000A304200FF8C +:103ED0001443003E000000008E4300048E22003890 +:103EE000506200808FBF001C92220000240300500B +:103EF000304200FF144300253C0280008C42014008 +:103F00008E4300043642010002202821AC43001CED +:103F10009622005C8E2300383042FFFF00021040E2 +:103F200000621821AE23001C8E4300048E2400384A +:103F30009622005C006418233042FFFF0003184300 +:103F4000000210400043102A10400006000000004C +:103F50008E4200048E230038004310230A000FAA6B +:103F6000000220439622005C3042FFFF0002204006 +:103F70003C0280083443010034420080ACA4002C91 +:103F8000A040002424020001A062000C0E000F5E7D +:103F900000000000104000538FBF001C3C02800056 +:103FA0008C4401403C0380008C6201F80440FFFE19 +:103FB00024020002AC6401C0A06201C43C021000F3 +:103FC000AC6201F80A0010078FBF001C92220009A2 +:103FD00024030010304200FF144300043C02800020 +:103FE0008C4401400A000FEE0000282192220009B3 +:103FF00024030016304200FF14430006240200147C +:10400000A22200093C0280008C4401400A001001F9 +:104010008FBF001C8E2200388E23003C00431023EB +:10402000044100308FBF001C92220027244200016F +:10403000A2220027922200272C42000414400016DE +:104040003C1080009222000924030004304200FF4B +:10405000144300093C0280008C4401408FBF001CC7 +:104060008FB200188FB100148FB000102405009398 +:104070000A000ECC27BD00208C440140240500938B +:104080008FBF001C8FB200188FB100148FB00010CA +:104090000A000F4827BD00208E0401400E000332A5 +:1040A000000000008E4200042442FFFFAE420004E4 +:1040B0008E22003C2442FFFFAE22003C0E00033D56 +:1040C0008E0401408E0401408FBF001C8FB2001887 +:1040D0008FB100148FB00010240500040A000342C1 +:1040E00027BD00208FB200188FB100148FB00010D0 +:1040F00003E0000827BD00203C0680008CC2018838 +:104100003C038008346500809063000E00021402B6 +:10411000304400FF306300FF1464000E3C0280084E +:1041200090A20026304200FF104400098F82FF94C5 +:10413000A0A400262403005090420000304200FF5B +:1041400014430006000000000A0005A18CC4018091 +:104150003C02800834420080A044002603E00008AE +:104160000000000027BDFFE030E700FFAFB20018FD +:10417000AFBF001CAFB10014AFB0001000809021A1 +:1041800014E0000630C600FF000000000000000D33 +:10419000000000000A001060240001163C038008A3 +:1041A0009062000E304200FF14460023346200800B +:1041B00090420026304200FF1446001F000000001D +:1041C0009062000F304200FF1446001B0000000008 +:1041D0009062000A304200FF144600038F90FF9463 +:1041E0000000000D8F90FF948F82FF983C1180009B +:1041F000AE05003CAC450000A066000A0E0003328C +:104200008E240100A20000240E00033D8E24010034 +:104210003C0380008C6201F80440FFFE240200028F +:10422000AC7201C0A06201C43C021000AC6201F893 +:104230000A0010618FBF001C000000000000000D8C +:10424000000000002400013F8FBF001C8FB2001847 +:104250008FB100148FB0001003E0000827BD0020CC +:104260008F83FF943C0280008C44010034420100A3 +:104270008C65003C9046001B0A00102724070001B3 +:104280003C0280089043000E9042000A0043102632 +:10429000304200FF03E000080002102B27BDFFE0C2 +:1042A0003C028008AFB10014AFB00010AFBF0018DF +:1042B0003450008092020005240300303042003068 +:1042C00014430085008088218F8200248C42000CDA +:1042D000104000828FBF00180E000D840000000007 +:1042E0008F860020ACD100009202000892030009E2 +:1042F000304200FF00021200306300FF004310252F +:10430000ACC200049202004D000216000002160327 +:1043100004410005000000003C0308008C630048D5 +:104320000A00109F3C1080089202000830420040B2 +:10433000144000030000182192020027304300FFC0 +:104340003C108008361100809222004D00031E00B0 +:10435000304200FF0002140000621825ACC30008C0 +:104360008E2400308F820024ACC4000C8E250034D3 +:104370009443001E3C02C00BACC50010006218251F +:104380008E22003800002021ACC200148E22003C96 +:10439000ACC200180E000DB8ACC3001C8E020004A5 +:1043A0008F8400203C058000AC8200008E2200201B +:1043B000AC8200048E22001CAC8200088E220058C1 +:1043C0008CA3007400431021AC82000C8E22002CC0 +:1043D000AC8200108E2200408E23004400021400A4 +:1043E00000431025AC8200149222004D240300806B +:1043F000304200FF1443000400000000AC800018AD +:104400000A0010E38F8200248E23000C2402000196 +:104410001062000E2402FFFF92220008304200408A +:104420001440000A2402FFFF8E23000C8CA20074AB +:10443000006218233C0208000062102414400002AD +:10444000000028210060282100051043AC820018DC +:104450008F820024000020219443001E3C02C00CE7 +:10446000006218258F8200200E000DB8AC43001C9E +:104470003C038008346201008C4200008F850020DC +:10448000346300808FBF0018ACA20000ACA0000411 +:104490008C6400488F8200248FB10014ACA4000803 +:1044A000ACA0000CACA00010906300059446001E68 +:1044B0003C02400D00031E0000C23025ACA30014D6 +:1044C0008FB00010ACA0001824040001ACA6001CA2 +:1044D0000A000DB827BD00208FBF00188FB100144F +:1044E0008FB0001003E0000827BD00203C028000D0 +:1044F0009443007C3C02800834460100308400FF75 +:104500003065FFFF2402000524A34650A0C4000C20 +:104510005482000C3065FFFF90C2000D2C42000752 +:104520001040000724A30A0090C3000D24020014C9 +:104530000062100400A210210A00111F3045FFFF85 +:104540003065FFFF3C0280083442008003E0000831 +:10455000A44500143C03800834680080AD05003891 +:10456000346701008CE2001C308400FF00A210239D +:104570001840000330C600FF24A2FFFCACE2001C80 +:1045800030820001504000083C0380088D02003C4E +:1045900000A2102304410012240400058C620004D0 +:1045A00010A2000F3C0380088C62000414A2001EBD +:1045B000000000003C0208008C4200D8304200207D +:1045C000104000093C0280083462008090630008BB +:1045D0009042004C144300043C0280082404000470 +:1045E0000A00110900000000344300803442010039 +:1045F000A040000C24020001A462001410C0000AB4 +:104600003C0280008C4401003C0380008C6201F875 +:104610000440FFFE24020002AC6401C0A06201C499 +:104620003C021000AC6201F803E00008000000004A +:1046300027BDFFE800A61823AFBF00101860008058 +:10464000308800FF3C02800834470080A0E000244E +:1046500034440100A0E000278C82001C00A210233B +:1046600004400056000000008CE2003C94E3005C33 +:104670008CE4002C004530233063FFFF00C3182179 +:104680000083202B1080000400E018218CE2002C15 +:104690000A00117800A2102194E2005C3042FFFF72 +:1046A00000C2102100A21021AC62001C3C02800854 +:1046B000344400809482005C8C83001C3042FFFFF5 +:1046C0000002104000A210210043102B10400004F3 +:1046D000000000008C82001C0A00118B3C06800840 +:1046E0009482005C3042FFFF0002104000A21021C3 +:1046F0003C06800834C3010034C70080AC82001C33 +:10470000A060000CACE500388C62001C00A21023F5 +:104710001840000224A2FFFCAC62001C3102000120 +:10472000104000083C0380088CE2003C00A21023EB +:1047300004410012240400058CC2000410A20010E1 +:104740008FBF00108C62000414A2004F8FBF0010B6 +:104750003C0208008C4200D8304200201040000A81 +:104760003C02800834620080906300089042004C54 +:10477000144300053C028008240400048FBF00108D +:104780000A00110927BD001834430080344201009B +:10479000A040000C24020001A46200143C0280002E +:1047A0008C4401003C0380008C6201F80440FFFE51 +:1047B000240200020A0011D8000000008CE2001C54 +:1047C000004610230043102B54400001ACE5001CB0 +:1047D00094E2005C3042FFFF0062102B144000079F +:1047E0002402000294E2005C8CE3001C3042FFFFD4 +:1047F00000621821ACE3001C24020002ACE5003882 +:104800000E000F5EA082000C1040001F8FBF001032 +:104810003C0280008C4401003C0380008C6201F863 +:104820000440FFFE24020002AC6401C0A06201C487 +:104830003C021000AC6201F80A0011F08FBF0010BA +:1048400031020010104000108FBF00103C028008A1 +:10485000344500808CA3001C94A2005C00661823E1 +:104860003042FFFF006218213C023FFF3444FFFF4B +:104870000083102B544000010080182100C3102138 +:10488000ACA2001C8FBF001003E0000827BD001879 +:1048900027BDFFE800C0402100A63023AFBF0010B5 +:1048A00018C00026308A00FF3C028008344900808E +:1048B0008D24001C8D23002C008820230064182BDD +:1048C0001060000F344701008CE2002000461021E8 +:1048D000ACE200208CE200200044102B1440000BBE +:1048E0003C023FFF8CE2002000441023ACE2002099 +:1048F0009522005C3042FFFF0A0012100082202146 +:10490000ACE00020008620213C023FFF3443FFFF43 +:104910000064102B54400001006020213C028008FC +:104920003442008000851821AC43001CA0400024C4 +:10493000A04000270A0012623C03800831420010A8 +:10494000104000433C0380083C06800834C40080CB +:104950008C82003C004810235840003E34660080A2 +:104960009082002424420001A0820024908200242E +:104970003C0308008C630024304200FF0043102BEE +:10498000144000688FBF001034C201008C42001C2C +:1049900000A2102318400063000000008CC3000434 +:1049A0009482005C006818233042FFFF0003184324 +:1049B000000210400043102A1040000500000000D3 +:1049C0008CC20004004810230A0012450002104364 +:1049D0009482005C3042FFFF000210403C068008D9 +:1049E000AC82002C34C5008094A2005C8CA4002C06 +:1049F00094A3005C3042FFFF00021040008220219F +:104A00003063FFFF0083202101041021ACA2001CB1 +:104A10008CC2000434C60100ACC2001C2402000297 +:104A20000E000F5EA0C2000C1040003E8FBF0010B1 +:104A30003C0280008C4401003C0380008C6201F841 +:104A40000440FFFE240200020A001292000000004F +:104A500034660080ACC50038346401008C82001CD0 +:104A600000A210231840000224A2FFFCAC82001C0C +:104A7000314200015040000A3C0380088CC2003CD7 +:104A800000A2102304430014240400058C620004D7 +:104A900014A200033C0380080A00128424040005C9 +:104AA0008C62000414A2001F8FBF00103C0208009B +:104AB0008C4200D8304200201040000A3C0280089E +:104AC00034620080906300089042004C144300055B +:104AD0003C028008240400048FBF00100A00110962 +:104AE00027BD00183443008034420100A040000C70 +:104AF00024020001A46200143C0280008C440100E6 +:104B00003C0380008C6201F80440FFFE2402000296 +:104B1000AC6401C0A06201C43C021000AC6201F8A8 +:104B20008FBF001003E0000827BD001827BDFFE875 +:104B30003C0A8008AFBF0010354900808D22003C40 +:104B400000C04021308400FF004610231840009D23 +:104B500030E700FF354701002402000100A63023A2 +:104B6000A0E0000CA0E0000DA522001418C0002455 +:104B7000308200108D23001C8D22002C0068182329 +:104B80000043102B1040000F000000008CE20020BA +:104B900000461021ACE200208CE200200043102BE4 +:104BA0001440000B3C023FFF8CE200200043102326 +:104BB000ACE200209522005C3042FFFF0A0012C1E7 +:104BC00000621821ACE00020006618213C023FFF83 +:104BD0003446FFFF00C3102B5440000100C01821D1 +:104BE0003C0280083442008000651821AC43001C60 +:104BF000A0400024A04000270A00130F3C038008B7 +:104C0000104000403C0380088D22003C00481023E7 +:104C10005840003D34670080912200242442000166 +:104C2000A1220024912200243C0308008C6300246C +:104C3000304200FF0043102B1440009A8FBF001039 +:104C40008CE2001C00A21023184000960000000017 +:104C50008D4300049522005C006818233042FFFF5A +:104C600000031843000210400043102A10400005C2 +:104C7000012020218D420004004810230A0012F276 +:104C8000000210439522005C3042FFFF00021040FA +:104C90003C068008AC82002C34C5008094A2005CE5 +:104CA0008CA4002C94A3005C3042FFFF0002104053 +:104CB000008220213063FFFF0083182101031021AF +:104CC000ACA2001C8CC2000434C60100ACC2001CA3 +:104CD000240200020E000F5EA0C2000C1040007102 +:104CE0008FBF00103C0280008C4401003C03800018 +:104CF0008C6201F80440FFFE240200020A0013390E +:104D00000000000034670080ACE500383466010024 +:104D10008CC2001C00A210231840000224A2FFFC39 +:104D2000ACC2001C30820001504000083C038008E7 +:104D30008CE2003C00A2102304430051240400052F +:104D40008C62000410A2003E3C0380088C620004C8 +:104D500054A200548FBF00103C0208008C4200D8BF +:104D600030420020104000063C028008346200807F +:104D7000906300089042004C104300403C028008C1 +:104D80003443008034420100A040000C24020001A2 +:104D9000A46200143C0280008C4401003C038000AB +:104DA0008C6201F80440FFFE24020002AC6401C0E2 +:104DB000A06201C43C021000AC6201F80A00137743 +:104DC0008FBF001024020005A120002714E2000A72 +:104DD0003C038008354301009062000D2C42000620 +:104DE000504000053C0380089062000D2442000101 +:104DF000A062000D3C03800834670080ACE50038F9 +:104E0000346601008CC2001C00A21023184000026E +:104E100024A2FFFCACC2001C308200015040000AFA +:104E20003C0380088CE2003C00A2102304410014E3 +:104E3000240400058C62000414A200033C038008D3 +:104E40000A00136E240400058C62000414A20015ED +:104E50008FBF00103C0208008C4200D83042002076 +:104E60001040000A3C028008346200809063000811 +:104E70009042004C144300053C02800824040004C6 +:104E80008FBF00100A00110927BD001834430080AD +:104E900034420100A040000C24020001A46200146E +:104EA0008FBF001003E0000827BD00183C0B8008EE +:104EB00027BDFFE83C028000AFBF00103442010074 +:104EC000356A00809044000A356901008C45001461 +:104ED0008D4800389123000C308400FF0105102319 +:104EE0001C4000B3306700FF2CE20006504000B1C8 +:104EF0008FBF00102402000100E2300430C2000322 +:104F00005440000800A8302330C2000C144000A117 +:104F100030C20030144000A38FBF00100A00143BC1 +:104F20000000000018C00024308200108D43001CD7 +:104F30008D42002C006818230043102B1040000FF6 +:104F4000000000008D22002000461021AD2200202C +:104F50008D2200200043102B1440000B3C023FFF29 +:104F60008D22002000431023AD2200209542005CDA +:104F70003042FFFF0A0013AF00621821AD2000206D +:104F8000006618213C023FFF3446FFFF00C3102B90 +:104F90005440000100C018213C02800834420080C7 +:104FA00000651821AC43001CA0400024A04000274D +:104FB0000A0013FD3C038008104000403C038008B9 +:104FC0008D42003C004810231840003D34670080AB +:104FD0009142002424420001A14200249142002475 +:104FE0003C0308008C630024304200FF0043102B78 +:104FF000144000708FBF00108D22001C00A21023EF +:105000001840006C000000008D6300049542005CB5 +:10501000006818233042FFFF0003184300021040CD +:105020000043102A10400005014020218D62000439 +:10503000004810230A0013E0000210439542005C70 +:105040003042FFFF000210403C068008AC82002C7A +:1050500034C5008094A2005C8CA4002C94A3005C56 +:105060003042FFFF00021040008220213063FFFF2A +:105070000083182101031021ACA2001C8CC2000483 +:1050800034C60100ACC2001C240200020E000F5EF8 +:10509000A0C2000C104000478FBF00103C028000EF +:1050A0008C4401003C0380008C6201F80440FFFE48 +:1050B000240200020A00142D000000003467008062 +:1050C000ACE50038346601008CC2001C00A210233D +:1050D0001840000224A2FFFCACC2001C3082000178 +:1050E0005040000A3C0380088CE2003C00A21023E0 +:1050F00004430014240400058C62000414A200037D +:105100003C0380080A00141F240400058C6200047C +:1051100014A200288FBF00103C0208008C4200D867 +:10512000304200201040000A3C02800834620080B7 +:10513000906300089042004C144300053C02800834 +:10514000240400048FBF00100A00110927BD0018B5 +:105150003443008034420100A040000C24020001CE +:10516000A46200143C0280008C4401003C038000D7 +:105170008C6201F80440FFFE24020002AC6401C00E +:10518000A06201C43C021000AC6201F80A00143BAA +:105190008FBF00108FBF0010010030210A00115A8C +:1051A00027BD0018010030210A00129927BD001800 +:1051B0008FBF001003E0000827BD00183C038008E3 +:1051C0003464010024020003A082000C8C620004FD +:1051D00003E00008AC82001C3C05800834A300807A +:1051E0009062002734A501002406004324420001F8 +:1051F000A0620027906300273C0208008C42004810 +:10520000306300FF146200043C07602194A500EAAB +:105210000A00090130A5FFFF03E0000800000000BC +:1052200027BDFFE8AFBF00103C0280000E00144411 +:105230008C4401803C02800834430100A060000CD3 +:105240008C4200048FBF001027BD001803E0000847 +:10525000AC62001C27BDFFE03C028008AFBF001815 +:10526000AFB10014AFB000103445008034460100E7 +:105270003C0880008D09014090C3000C8CA4003CC8 +:105280008CA200381482003B306700FF9502007C3E +:1052900090A30027146000093045FFFF2402000599 +:1052A00054E200083C04800890C2000D2442000132 +:1052B000A0C2000D0A00147F3C048008A0C0000DAD +:1052C0003C048008348201009042000C2403000555 +:1052D000304200FF1443000A24A205DC348300801E +:1052E000906200272C4200075040000524A20A00CB +:1052F00090630027240200140062100400A2102111 +:105300003C108008361000803045FFFF012020212E +:105310000E001444A60500149602005C8E030038AB +:105320003C1180003042FFFF000210400062182153 +:10533000AE03001C0E0003328E24014092020025B1 +:1053400034420040A20200250E00033D8E2401409D +:105350008E2401403C0380008C6201F80440FFFE73 +:1053600024020002AC6401C0A06201C43C0210002F +:10537000AC6201F88FBF00188FB100148FB000101D +:1053800003E0000827BD00203C0360103C02080039 +:1053900024420174AC62502C8C6250003C048000AA +:1053A00034420080AC6250003C0208002442547C2D +:1053B0003C010800AC2256003C020800244254384C +:1053C0003C010800AC2256043C020002AC840008F8 +:1053D000AC82000C03E000082402000100A0302190 +:1053E0003C1C0800279C56083C0200023C050400B7 +:1053F00000852826008220260004102B2CA5000101 +:105400002C840001000210803C0308002463560035 +:105410000085202500431821108000030000102182 +:10542000AC6600002402000103E000080000000058 +:105430003C1C0800279C56083C0200023C05040066 +:1054400000852826008220260004102B2CA50001B0 +:105450002C840001000210803C03080024635600E5 +:105460000085202500431821108000050000102130 +:105470003C02080024425438AC62000024020001BF +:1054800003E00008000000003C0200023C030400AE +:1054900000821026008318262C4200012C63000194 +:1054A000004310251040000B000028213C1C080080 +:1054B000279C56083C0380008C62000824050001EC +:1054C00000431025AC6200088C62000C00441025DB +:1054D000AC62000C03E0000800A010213C1C080096 +:1054E000279C56083C0580008CA3000C0004202754 +:1054F000240200010064182403E00008ACA3000C9F +:105500003C020002148200063C0560008CA208D018 +:105510002403FFFE0043102403E00008ACA208D0DF +:105520003C02040014820005000000008CA208D098 +:105530002403FFFD00431024ACA208D003E00008C0 +:10554000000000003C02601A344200108C430080CE +:1055500027BDFFF88C440084AFA3000093A3000094 +:10556000240200041462001AAFA4000493A20001F4 +:105570001040000797A300023062FFFC3C0380004C +:10558000004310218C4200000A001536AFA200042F +:105590003062FFFC3C03800000431021AC4400005B +:1055A000A3A000003C0560008CA208D02403FFFEED +:1055B0003C04601A00431024ACA208D08FA300045E +:1055C0008FA2000034840010AC830084AC82008081 +:1055D00003E0000827BD000827BDFFE8AFBF0010AB +:1055E0003C1C0800279C56083C0280008C43000CA1 +:1055F0008C420004004318243C0200021060001496 +:10560000006228243C0204003C04000210A00005B3 +:10561000006210243C0208008C4256000A00155B10 +:1056200000000000104000073C0404003C02080099 +:105630008C4256040040F809000000000A00156082 +:10564000000000000000000D3C1C0800279C5608CC +:0C5650008FBF001003E0000827BD001809 +:04565C008008024080 +:1056600080080100800800808008000000000C8095 +:105670000000320008000E9808000EF408000F88A1 +:1056800008001028080010748008010080080080BD +:04569000800800008E +:0C5694000A0000280000000000000000D8 +:1056A0000000000D6370362E322E316100000000C4 +:1056B00006020104000000000000000000000000DD +:1056C000000000000000000038003C000000000066 +:1056D00000000000000000000000000000000020AA +:1056E00000000000000000000000000000000000BA +:1056F00000000000000000000000000000000000AA +:10570000000000000000000021003800000000013F +:105710000000002B000000000000000400030D400A +:105720000000000000000000000000000000000079 +:105730000000000000000000100000030000000056 +:105740000000000D0000000D3C020800244259AC8E +:105750003C03080024635BF4AC4000000043202BB2 +:105760001480FFFD244200043C1D080037BD9FFC4F +:1057700003A0F0213C100800261000A03C1C0800EB +:10578000279C59AC0E0002F6000000000000000D3E +:1057900027BDFFB4AFA10000AFA20004AFA3000873 +:1057A000AFA4000CAFA50010AFA60014AFA700185F +:1057B000AFA8001CAFA90020AFAA0024AFAB0028FF +:1057C000AFAC002CAFAD0030AFAE0034AFAF00389F +:1057D000AFB8003CAFB90040AFBC0044AFBF004819 +:1057E0000E000820000000008FBF00488FBC00445E +:1057F0008FB900408FB8003C8FAF00388FAE0034B7 +:105800008FAD00308FAC002C8FAB00288FAA002406 +:105810008FA900208FA8001C8FA700188FA6001446 +:105820008FA500108FA4000C8FA300088FA2000486 +:105830008FA1000027BD004C3C1B60188F7A5030B0 +:10584000377B502803400008AF7A000000A01821E1 +:1058500000801021008028213C0460003C0760008B +:105860002406000810600006348420788C42000072 +:10587000ACE220088C63000003E00008ACE3200CDD +:105880000A000F8100000000240300403C02600079 +:1058900003E00008AC4320003C0760008F86000452 +:1058A0008CE520740086102100A2182B14600007DC +:1058B000000028218F8AFDA024050001A1440013C7 +:1058C0008F89000401244021AF88000403E0000810 +:1058D00000A010218F84FDA08F8500049086001306 +:1058E00030C300FF00A31023AF82000403E00008D0 +:1058F000A08000138F84FDA027BDFFE8AFB000108B +:10590000AFBF001490890011908700112402002875 +:10591000312800FF3906002830E300FF2485002CE1 +:105920002CD00001106200162484001C0E00006EB2 +:10593000000000008F8FFDA03C05600024020204DF +:1059400095EE003E95ED003C000E5C0031ACFFFF93 +:10595000016C5025ACAA2010520000012402000462 +:10596000ACA22000000000000000000000000000C9 +:105970008FBF00148FB0001003E0000827BD00188F +:105980000A0000A6000028218F85FDA027BDFFD8B2 +:10599000AFBF0020AFB3001CAFB20018AFB100140E +:1059A000AFB000100080982190A4001124B0001C1A +:1059B00024B1002C308300FF386200280E000090D4 +:1059C0002C5200010E00009800000000020020216F +:1059D0001240000202202821000028210E00006E43 +:1059E000000000008F8DFDA03C0880003C05600099 +:1059F00095AC003E95AB003C02683025000C4C0095 +:105A0000316AFFFF012A3825ACA7201024020202C8 +:105A1000ACA6201452400001240200028FBF0020D7 +:105A20008FB3001C8FB200188FB100148FB000101C +:105A300027BD002803E00008ACA2200027BDFFE03E +:105A4000AFB20018AFB10014AFB00010AFBF001C70 +:105A50003C1160008E2320748F82000430D0FFFF41 +:105A600030F2FFFF1062000C2406008F0E00006E63 +:105A7000000000003C06801F0010440034C5FF00F9 +:105A80000112382524040002AE2720100000302126 +:105A9000AE252014AE2420008FBF001C8FB200184A +:105AA0008FB100148FB0001000C0102103E0000877 +:105AB00027BD002027BDFFE0AFB0001030D0FFFFB2 +:105AC000AFBF0018AFB100140E00006E30F1FFFF41 +:105AD00000102400009180253C036000AC70201071 +:105AE0008FBF00188FB100148FB000102402000483 +:105AF000AC62200027BD002003E000080000102158 +:105B000027BDFFE03C046018AFBF0018AFB1001420 +:105B1000AFB000108C8850002403FF7F34028071E6 +:105B20000103382434E5380C241F00313C1980006F +:105B3000AC8550003C11800AAC8253BCAF3F0008DA +:105B40000E00054CAF9100400E00050A3C116000AC +:105B50000E00007D000000008E3008083C0F570941 +:105B60002418FFF00218602435EEE00035EDF00057 +:105B7000018E5026018D58262D4600012D69000109 +:105B8000AF86004C0E000D09AF8900503C06601630 +:105B90008CC700003C0860148D0500A03C03FFFF8B +:105BA00000E320243C02535300052FC2108200550D +:105BB00034D07C00960201F2A780006C10400003F4 +:105BC000A780007C384B1E1EA78B006C960201F844 +:105BD000104000048F8D0050384C1E1EA78C007C96 +:105BE0008F8D005011A000058F83004C240E0020E3 +:105BF000A78E007CA78E006C8F83004C1060000580 +:105C00009785007C240F0020A78F007CA78F006C55 +:105C10009785007C2CB8008153000001240500808A +:105C20009784006C2C91040152200001240404008C +:105C30001060000B3C0260008FBF00188FB1001491 +:105C40008FB0001027BD0020A784006CA785007CC2 +:105C5000A380007EA780007403E00008A780009264 +:105C60008C4704382419103C30FFFFFF13F9000360 +:105C700030A8FFFF1100004624030050A380007EDF +:105C80009386007E50C00024A785007CA780007CFE +:105C90009798007CA780006CA7800074A780009272 +:105CA0003C010800AC3800800E00078700000000AF +:105CB0003C0F60008DED0808240EFFF03C0B600ED9 +:105CC000260C0388356A00100000482100002821B6 +:105CD00001AE20243C105709AF8C0010AF8A004859 +:105CE000AF89001810900023AF8500148FBF0018F3 +:105CF0008FB100148FB0001027BD002003E0000812 +:105D0000AF80005400055080014648218D260004D4 +:105D10000A00014800D180219798007CA784006C7C +:105D2000A7800074A78000923C010800AC38008076 +:105D30000E000787000000003C0F60008DED080892 +:105D4000240EFFF03C0B600E260C0388356A001011 +:105D5000000048210000282101AE20243C105709F2 +:105D6000AF8C0010AF8A0048AF8900181490FFDF95 +:105D7000AF85001424110001AF9100548FBF0018AB +:105D80008FB100148FB0001003E0000827BD002081 +:105D90000A00017BA383007E3083FFFF8F880040D1 +:105DA0008F87003C000321403C0580003C020050EE +:105DB000008248253C0660003C0A010034AC040027 +:105DC0008CCD08E001AA58241160000500000000F5 +:105DD0008CCF08E024E7000101EA7025ACCE08E092 +:105DE0008D19001001805821ACB900388D180014AD +:105DF000ACB8003CACA9003000000000000000007E +:105E00000000000000000000000000000000000092 +:105E100000000000000000003C0380008C640000D3 +:105E2000308200201040FFFD3C0F60008DED08E047 +:105E30003C0E010001AE18241460FFE100000000D8 +:105E4000AF87003C03E00008AF8B00588F8500400F +:105E5000240BFFF03C06800094A7001A8CA90024B4 +:105E600030ECFFFF000C38C000EB5024012A402129 +:105E7000ACC8003C8CA400248CC3003C00831023DD +:105E800018400033000000008CAD002025A2000166 +:105E90003C0F0050ACC2003835EE00103C068000CC +:105EA000ACCE003000000000000000000000000048 +:105EB00000000000000000000000000000000000E2 +:105EC000000000003C0480008C9900003338002062 +:105ED0001300FFFD30E20008104000173C0980006D +:105EE0008C880408ACA800108C83040CACA30014AC +:105EF0003C1900203C188000AF19003094AE001807 +:105F000094AF001C01CF3021A4A6001894AD001A54 +:105F100025A70001A4A7001A94AB001A94AC001E98 +:105F2000118B00030000000003E0000800000000E7 +:105F300003E00008A4A0001A8D2A0400ACAA0010F7 +:105F40008D240404ACA400140A0002183C1900209B +:105F50008CA200200A0002003C0F00500A0001EE53 +:105F60000000000027BDFFE8AFBF00100E000232A6 +:105F7000000000008F8900408FBF00103C038000AC +:105F8000A520000A9528000A9527000427BD0018BF +:105F90003105FFFF30E6000F0006150000A22025A6 +:105FA00003E00008AC6400803C0508008CA50020DC +:105FB0008F83000C27BDFFE8AFB00010AFBF001407 +:105FC00010A300100000802124040001020430040A +:105FD00000A6202400C3102450440006261000010F +:105FE000001018802787FDA41480000A006718217C +:105FF000261000012E0900025520FFF38F83000CAC +:10600000AF85000C8FBF00148FB0001003E00008B4 +:1060100027BD00188C6800003C058000ACA8002457 +:106020000E000234261000013C0508008CA500205B +:106030000A0002592E0900022405000100851804F7 +:106040003C0408008C84002027BDFFC8AFBF00348B +:1060500000831024AFBE0030AFB7002CAFB60028CD +:10606000AFB50024AFB40020AFB3001CAFB200182E +:10607000AFB1001410400051AFB000108F84004049 +:10608000948700069488000A00E8302330D5FFFF8B +:1060900012A0004B8FBF0034948B0018948C000A20 +:1060A000016C50233142FFFF02A2482B1520000251 +:1060B00002A02021004020212C8F000515E00002C5 +:1060C00000809821241300040E0001C102602021E9 +:1060D0008F87004002609021AF80004494F4000A52 +:1060E000026080211260004E3291FFFF3C1670006A +:1060F0003C1440003C1E20003C1760008F99005863 +:106100008F380000031618241074004F0283F82BF8 +:1061100017E0003600000000107E00478F86004424 +:1061200014C0003A2403000102031023022320219B +:106130003050FFFF1600FFF13091FFFF8F870040C6 +:106140003C1100203C108000AE11003094EB000A9E +:106150003C178000024B5021A4EA000A94E9000A8F +:1061600094E800043123FFFF3106000F00062D00E4 +:106170000065F025AEFE008094F3000A94F6001846 +:1061800012D30036001221408CFF00148CF4001052 +:1061900003E468210000C02101A4782B029870213B +:1061A00001CF6021ACED0014ACEC001002B238233A +:1061B00030F5FFFF16A0FFB88F8400408FBF00347A +:1061C0008FBE00308FB7002C8FB600288FB500240B +:1061D0008FB400208FB3001C8FB200188FB1001451 +:1061E0008FB0001003E0000827BD00381477FFCC03 +:1061F0008F8600440E000EE202002021004018218C +:106200008F86004410C0FFC9020310230270702360 +:106210008F87004001C368210A0002E431B2FFFF0A +:106220008F86004414C0FFC93C1100203C10800040 +:106230000A0002AEAE1100300E00046602002021FA +:106240000A0002DB00401821020020210E0009395B +:10625000022028210A0002DB004018210E0001EE76 +:10626000000000000A0002C702B2382327BDFFC8A1 +:10627000AFB7002CAFB60028AFB50024AFB40020F4 +:10628000AFB3001CAFB20018AFB10014AFB0001034 +:10629000AFBF00300E00011B241300013C047FFF40 +:1062A0003C0380083C0220003C010800AC20007048 +:1062B0003496FFFF34770080345200033C1512C03F +:1062C000241400013C1080002411FF800E000245C0 +:1062D000000000008F8700488F8B00188F89001402 +:1062E0008CEA00EC8CE800E8014B302B01092823F4 +:1062F00000A6102314400006014B18231440000E82 +:106300003C05800002A3602B1180000B0000000000 +:106310003C0560008CEE00EC8CED00E88CA4180CC1 +:10632000AF8E001804800053AF8D00148F8F0010C3 +:10633000ADF400003C0580008CBF00003BF900017B +:10634000333800011700FFE13C0380008C6201003C +:1063500024060C0010460009000000008C680100B3 +:106360002D043080548000103C0480008C690100B2 +:106370002D2331811060000C3C0480008CAA0100A8 +:1063800011460004000020218CA6010024C5FF81D5 +:1063900030A400FF8E0B01000E000269AE0B00243A +:1063A0000A00034F3C0480008C8D01002DAC3300AB +:1063B00011800022000000003C0708008CE70098D4 +:1063C00024EE00013C010800AC2E00983C04800043 +:1063D0008C8201001440000300000000566000148D +:1063E0003C0440008C9F01008C9801000000982123 +:1063F00003F1C82400193940330F007F00EF7025E6 +:1064000001D26825AC8D08308C8C01008C85010090 +:10641000258B0100017130240006514030A3007F1C +:106420000143482501324025AC8808303C04400037 +:10643000AE0401380A00030E000000008C99010030 +:10644000240F0020AC99002092F80000330300FFD5 +:10645000106F000C241F0050547FFFDD3C048000AF +:106460008C8401000E00154E000000000A00034F4E +:106470003C04800000963824ACA7180C0A000327BF +:106480008F8F00108C8501000E0008F72404008017 +:106490000A00034F3C04800000A4102B24030001D9 +:1064A00010400009000030210005284000A4102BF6 +:1064B00004A00003000318405440FFFC00052840DE +:1064C0005060000A0004182B0085382B54E00004AB +:1064D0000003184200C33025008520230003184222 +:1064E0001460FFF9000528420004182B03E000089F +:1064F00000C310213084FFFF30C600FF3C0780003E +:106500008CE201B80440FFFE00064C000124302557 +:106510003C08200000C820253C031000ACE00180AE +:10652000ACE50184ACE4018803E00008ACE301B809 +:106530003C0660008CC5201C2402FFF03083020062 +:10654000308601001060000E00A2282434A500014E +:106550003087300010E0000530830C0034A50004C3 +:106560003C04600003E00008AC85201C1060FFFDC7 +:106570003C04600034A5000803E00008AC85201C42 +:1065800054C0FFF334A500020A0003B03087300086 +:1065900027BDFFE8AFB00010AFBF00143C0760009C +:1065A000240600021080001100A080218F83005873 +:1065B0000E0003A78C6400188F8200580000202171 +:1065C000240600018C45000C0E000398000000001A +:1065D0001600000224020003000010218FBF0014E7 +:1065E0008FB0001003E0000827BD00188CE8201CC5 +:1065F0002409FFF001092824ACE5201C8F870058EE +:106600000A0003CD8CE5000C3C02600E00804021A6 +:1066100034460100240900180000000000000000BA +:10662000000000003C0A00503C0380003547020097 +:10663000AC68003834640400AC65003CAC670030E2 +:106640008C6C0000318B00201160FFFD2407FFFFE0 +:106650002403007F8C8D00002463FFFF248400044A +:10666000ACCD00001467FFFB24C60004000000004E +:10667000000000000000000024A402000085282B78 +:106680003C0300203C0E80002529FFFF010540212E +:10669000ADC300301520FFE00080282103E0000892 +:1066A000000000008F82005827BDFFD8AFB3001C48 +:1066B000AFBF0020AFB20018AFB10014AFB00010F0 +:1066C00094460002008098218C5200182CC300814F +:1066D0008C4800048C4700088C51000C8C49001039 +:1066E000106000078C4A00142CC4000414800013AE +:1066F00030EB000730C5000310A0001000000000C0 +:106700002410008B02002021022028210E00039873 +:10671000240600031660000224020003000010217A +:106720008FBF00208FB3001C8FB200188FB10014F0 +:106730008FB0001003E0000827BD00281560FFF1AE +:106740002410008B3C0C80003C030020241F00011F +:10675000AD830030AF9F0044000000000000000047 +:10676000000000002419FFF024D8000F031978243A +:106770003C1000D0AD88003801F0702524CD000316 +:106780003C08600EAD87003C35850400AD8E0030BE +:10679000000D38823504003C3C0380008C6B000007 +:1067A000316200201040FFFD0000000010E00008F2 +:1067B00024E3FFFF2407FFFF8CA800002463FFFFF2 +:1067C00024A50004AC8800001467FFFB24840004A7 +:1067D0003C05600EACA60038000000000000000080 +:1067E000000000008F8600543C0400203C0780001D +:1067F000ACE4003054C000060120202102402021DA +:106800000E0003A7000080210A00041D02002021C1 +:106810000E0003DD01402821024020210E0003A7C5 +:10682000000080210A00041D0200202127BDFFE096 +:10683000AFB200183092FFFFAFB10014AFBF001C21 +:10684000AFB000101640000D000088210A0004932C +:106850000220102124050003508500278CE5000C40 +:106860000000000D262800013111FFFF24E2002066 +:106870000232802B12000019AF8200588F82004430 +:10688000144000168F8700583C0670003C0320001F +:106890008CE5000000A62024148300108F84006083 +:1068A000000544023C09800000A980241480FFE90F +:1068B000310600FF2CCA000B5140FFEB26280001D7 +:1068C000000668803C0E080025CE575801AE6021B6 +:1068D0008D8B0000016000080000000002201021E4 +:1068E0008FBF001C8FB200188FB100148FB0001042 +:1068F00003E0000827BD00200E0003982404008454 +:106900001600FFD88F8700580A000474AF8000601B +:10691000020028210E0003BF240400018F870058C5 +:106920000A000474AF820060020028210E0003BF39 +:10693000000020210A0004A38F8700580E000404E1 +:10694000020020218F8700580A000474AF82006083 +:1069500030AFFFFF000F19C03C0480008C9001B8DD +:106960000600FFFE3C1920043C181000AC83018097 +:10697000AC800184AC990188AC9801B80A00047518 +:106980002628000190E2000390E30002000020218D +:106990000002FE0000033A0000FF2825240600083C +:1069A0000E000398000000001600FFDC2402000324 +:1069B0008F870058000010210A000474AF82006025 +:1069C00090E8000200002021240600090A0004C308 +:1069D00000082E0090E4000C240900FF308500FF21 +:1069E00010A900150000302190F9000290F8000372 +:1069F000308F00FF94EB000400196E000018740043 +:106A0000000F62000186202501AE5025014B28258C +:106A10003084FF8B0A0004C32406000A90E30002BE +:106A200090FF0004000020210003360000DF28252D +:106A30000A0004C32406000B0A0004D52406008BB8 +:106A4000000449C23127003F000443423C02800059 +:106A500000082040240316802CE60020AC43002CC4 +:106A600024EAFFE02482000114C0000330A900FFE3 +:106A700000801021314700FF000260803C0D800043 +:106A8000240A0001018D20213C0B000E00EA28049D +:106A9000008B302111200005000538278CCE000026 +:106AA00001C5382503E00008ACC700008CD8000001 +:106AB0000307782403E00008ACCF000027BDFFE007 +:106AC000AFB10014AFB00010AFBF00183C076000BA +:106AD0008CE408083402F0003C1160003083F000C0 +:106AE000240501C03C04800E000030211062000625 +:106AF000241000018CEA08083149F0003928E00030 +:106B00000008382B000780403C0D0200AE2D081411 +:106B1000240C16803C0B80008E2744000E000F8B47 +:106B2000AD6C002C120000043C02169124050001FB +:106B3000120500103C023D2C345800E0AE384408E9 +:106B40003C1108008E31007C8FBF00183C066000AD +:106B500000118540360F16808FB100148FB00010E1 +:106B60003C0E020027BD0020ACCF442003E000080B +:106B7000ACCE08103C0218DA345800E0AE384408B5 +:106B80003C1108008E31007C8FBF00183C0660006D +:106B900000118540360F16808FB100148FB00010A1 +:106BA0003C0E020027BD0020ACCF442003E00008CB +:106BB000ACCE08100A0004EB240500010A0004EB27 +:106BC0000000282124020400A7820024A780001CC2 +:106BD000000020213C06080024C65A582405FFFF67 +:106BE00024890001000440803124FFFF01061821A0 +:106BF0002C87002014E0FFFAAC6500002404040098 +:106C0000A7840026A780001E000020213C06080063 +:106C100024C65AD82405FFFF248D0001000460809B +:106C200031A4FFFF018658212C8A00201540FFFA6D +:106C3000AD650000A7800028A7800020A780002263 +:106C4000000020213C06080024C65B582405FFFFF5 +:106C5000249900010004C0803324FFFF030678213B +:106C60002C8E000415C0FFFAADE500003C05600065 +:106C70008CA73D002403E08F00E31024344601403C +:106C800003E00008ACA63D002487007F000731C266 +:106C900024C5FFFF000518C2246400013082FFFFF5 +:106CA000000238C0A78400303C010800AC27003047 +:106CB000AF80002C0000282100002021000030219E +:106CC0002489000100A728213124FFFF2CA81701E7 +:106CD000110000032C8300801460FFF924C600011A +:106CE00000C02821AF86002C10C0001DA786002AF6 +:106CF00024CAFFFF000A11423C08080025085B581F +:106D00001040000A00002021004030212407FFFF2E +:106D1000248E00010004688031C4FFFF01A86021B7 +:106D20000086582B1560FFFAAD87000030A2001FC7 +:106D30005040000800043080240300010043C804D0 +:106D400000041080004878212738FFFF03E0000886 +:106D5000ADF8000000C820212405FFFFAC8500002D +:106D600003E000080000000030A5FFFF30C6FFFF71 +:106D700030A8001F0080602130E700FF0005294295 +:106D80000000502110C0001D24090001240B000147 +:106D900025180001010B2004330800FF0126782686 +:106DA000390E00202DED00012DC2000101A2182591 +:106DB0001060000D014450250005C880032C4021BF +:106DC0000100182110E0000F000A20278D040000A8 +:106DD000008A1825AD03000024AD00010000402109 +:106DE0000000502131A5FFFF252E000131C9FFFF12 +:106DF00000C9102B1040FFE72518000103E0000830 +:106E0000000000008D0A0000014440240A0005D162 +:106E1000AC68000027BDFFE830A5FFFF30C6FFFFCC +:106E2000AFB00010AFBF001430E7FFFF00005021EB +:106E30003410FFFF0000602124AF001F00C0482174 +:106E4000241800012419002005E0001601E010219B +:106E50000002F943019F682A0009702B01AE40240B +:106E600011000017000C18800064102110E00005CC +:106E70008C4B000000F840040008382301675824B8 +:106E800000003821154000410000402155600016E7 +:106E90003169FFFF258B0001316CFFFF05E1FFEC3D +:106EA00001E0102124A2003E0002F943019F682A5C +:106EB0000009702B01AE40241500FFEB000C188078 +:106EC000154600053402FFFF020028210E0005B51B +:106ED00000003821020010218FBF00148FB0001075 +:106EE00003E0000827BD00181520000301601821E9 +:106EF000000B1C0224080010306A00FF154000053A +:106F0000306E000F250D000800031A0231A800FFA3 +:106F1000306E000F15C00005307F000325100004FF +:106F200000031902320800FF307F000317E000055C +:106F3000386900012502000200031882304800FF72 +:106F4000386900013123000110600004310300FFA3 +:106F5000250A0001314800FF310300FF000C6940A1 +:106F600001A34021240A000110CAFFD53110FFFF00 +:106F7000246E000131C800FF1119FFC638C9000195 +:106F80002D1F002053E0001C258B0001240D000163 +:106F90000A000648240E002051460017258B0001E8 +:106FA00025090001312800FF2D0900205120001281 +:106FB000258B000125430001010D5004014B1024D5 +:106FC000250900011440FFF4306AFFFF3127FFFF5D +:106FD00010EE000C2582FFFF304CFFFF0000502117 +:106FE0003410FFFF312800FF2D0900205520FFF24B +:106FF00025430001258B0001014648260A000602B0 +:10700000316CFFFF00003821000050210A000654B7 +:107010003410FFFF27BDFFD8AFB0001030F0FFFFE6 +:10702000AFB10014001039423211FFE000071080A8 +:10703000AFB3001C00B1282330D3FFFFAFB200185C +:1070400030A5FFFF00809021026030210044202104 +:10705000AFBF00200E0005E03207001F022288218A +:107060003403FFFF0240202102002821026030216A +:1070700000003821104300093231FFFF02201021A7 +:107080008FBF00208FB3001C8FB200188FB1001487 +:107090008FB0001003E0000827BD00280E0005E0B7 +:1070A0000000000000408821022010218FBF002036 +:1070B0008FB3001C8FB200188FB100148FB0001076 +:1070C00003E0000827BD0028000424003C03600002 +:1070D000AC603D0810A00002348210063482101605 +:1070E00003E00008AC623D0427BDFFE0AFB0001034 +:1070F000309000FF2E020006AFBF001810400008BD +:10710000AFB10014001030803C03080024635784A2 +:1071100000C328218CA400000080000800000000AB +:10712000000020218FBF00188FB100148FB0001015 +:107130000080102103E0000827BD00209791002A5D +:1071400016200051000020213C020800904200332C +:107150000A0006BB00000000978D002615A0003134 +:10716000000020210A0006BB2402000897870024A3 +:1071700014E0001A00001821006020212402000100 +:107180001080FFE98FBF0018000429C2004530219C +:1071900000A6582B1160FFE43C0880003C0720004B +:1071A000000569C001A76025AD0C00203C038008E4 +:1071B0002402001F2442FFFFAC6000000441FFFDD9 +:1071C0002463000424A5000100A6702B15C0FFF560 +:1071D000000569C00A0006A58FBF00189787001C2C +:1071E0003C04080024845A58240504000E0006605C +:1071F00024060001978B002424440001308AFFFFFD +:107200002569FFFF2D48040000402821150000409B +:10721000A789002424AC3800000C19C00A0006B964 +:10722000A780001C9787001E3C04080024845AD8BD +:10723000240504000E00066024060001979900262C +:10724000244400013098FFFF272FFFFF2F0E04007A +:107250000040882115C0002CA78F0026A780001EA3 +:107260003A020003262401003084FFFF0E00068D41 +:107270002C4500010011F8C027F00100001021C0CA +:107280000A0006BB240200089785002E978700227B +:107290003C04080024845B580E00066024060001AC +:1072A0009787002A8F89002C2445000130A8FFFF12 +:1072B00024E3FFFF0109302B0040802114C0001897 +:1072C000A783002AA7800022978500300E000F7543 +:1072D00002002021244A05003144FFFF0E00068DE4 +:1072E000240500013C05080094A500320E000F752E +:1072F00002002021244521003C0208009042003376 +:107300000A0006BB000521C00A0006F3A784001E80 +:1073100024AC3800000C19C00A0006B9A784001C70 +:107320000A00070DA7850022308400FF27BDFFE873 +:107330002C820006AFBF0014AFB000101040001543 +:1073400000A03821000440803C0308002463579CBF +:10735000010328218CA40000008000080000000028 +:1073600024CC007F000751C2000C59C23170FFFFCE +:107370002547C40030E5FFFF2784001C02003021B0 +:107380000E0005B52407000197860028020620217B +:10739000A78400288FBF00148FB0001003E00008FE +:1073A00027BD00183C0508008CA50030000779C2F5 +:1073B0000E00038125E4DF003045FFFF3C04080098 +:1073C00024845B58240600010E0005B52407000143 +:1073D000978E002A8FBF00148FB0001025CD0001BA +:1073E00027BD001803E00008A78D002A0007C9C2C6 +:1073F0002738FF00001878C231F0FFFF3C04080076 +:1074000024845AD802002821240600010E0005B564 +:1074100024070001978D0026260E0100000E84002F +:1074200025AC00013C0B6000A78C0026AD603D0838 +:1074300036040006000030213C0760008CE23D0469 +:10744000305F000617E0FFFD24C9000100061B00A5 +:10745000312600FF006440252CC50004ACE83D0443 +:1074600014A0FFF68FBF00148FB0001003E00008D7 +:1074700027BD0018000751C22549C8002406000195 +:10748000240700013C04080024845A580E0005B566 +:107490003125FFFF978700248FBF00148FB00010A5 +:1074A00024E6000127BD001803E00008A786002499 +:1074B0003C0660183C090800252900FCACC9502C8A +:1074C0008CC850003C0580003C020002350700805B +:1074D000ACC750003C04080024841FE03C030800B3 +:1074E00024631F98ACA50008ACA2000C3C01080066 +:1074F000AC2459A43C010800AC2359A803E00008BF +:107500002402000100A030213C1C0800279C59AC3B +:107510003C0C04003C0B0002008B3826008C4026FB +:107520002CE200010007502B2D050001000A4880C5 +:107530003C030800246359A4004520250123182199 +:107540001080000300001021AC660000240200013E +:1075500003E00008000000003C1C0800279C59AC18 +:107560003C0B04003C0A0002008A3026008B3826BF +:107570002CC200010006482B2CE5000100094080C8 +:107580003C030800246359A4004520250103182169 +:1075900010800005000010213C0C0800258C1F986D +:1075A000AC6C00002402000103E0000800000000B1 +:1075B0003C0900023C080400008830260089382677 +:1075C0002CC30001008028212CE400010083102539 +:1075D0001040000B000030213C1C0800279C59ACD7 +:1075E0003C0A80008D4E00082406000101CA68256F +:1075F000AD4D00088D4C000C01855825AD4B000C9D +:1076000003E0000800C010213C1C0800279C59AC76 +:107610003C0580008CA6000C0004202724020001F9 +:1076200000C4182403E00008ACA3000C3C020002D4 +:107630001082000B3C0560003C070400108700032B +:107640000000000003E00008000000008CA908D042 +:10765000240AFFFD012A402403E00008ACA808D05A +:107660008CA408D02406FFFE0086182403E000083E +:10767000ACA308D03C05601A34A600108CC300806F +:1076800027BDFFF88CC50084AFA3000093A40000C1 +:107690002402001010820003AFA5000403E00008DC +:1076A00027BD000893A7000114E0001497AC000266 +:1076B00097B800023C0F8000330EFFFC01CF682119 +:1076C000ADA50000A3A000003C0660008CC708D058 +:1076D0002408FFFE3C04601A00E82824ACC508D04A +:1076E0008FA300048FA200003499001027BD00086A +:1076F000AF22008003E00008AF2300843C0B800031 +:10770000318AFFFC014B48218D2800000A00080C3B +:10771000AFA8000427BDFFE8AFBF00103C1C080065 +:10772000279C59AC3C0580008CA4000C8CA2000462 +:107730003C0300020044282410A0000A00A31824DF +:107740003C0604003C0400021460000900A610245A +:107750001440000F3C0404000000000D3C1C080015 +:10776000279C59AC8FBF001003E0000827BD00180C +:107770003C0208008C4259A40040F80900000000B7 +:107780003C1C0800279C59AC0A0008358FBF00102C +:107790003C0208008C4259A80040F8090000000093 +:1077A0000A00083B000000003C0880008D0201B880 +:1077B0000440FFFE35090180AD2400003C031000A9 +:1077C00024040040AD250004A1240008A1260009DE +:1077D000A527000A03E00008AD0301B83084FFFFCD +:1077E0000080382130A5FFFF000020210A00084555 +:1077F000240600803087FFFF8CA400002406003898 +:107800000A000845000028218F8300788F860070C9 +:107810001066000B008040213C07080024E75B68ED +:10782000000328C000A710218C440000246300013D +:10783000108800053063000F5466FFFA000328C06B +:1078400003E00008000010213C07080024E75B6CFF +:1078500000A7302103E000088CC200003C03900028 +:1078600034620001008220253C038000AC640020CB +:107870008C65002004A0FFFE0000000003E000086B +:10788000000000003C0280003443000100832025FA +:1078900003E00008AC44002027BDFFE0AFB10014B6 +:1078A0003091FFFFAFB00010AFBF001812200013DF +:1078B00000A080218CA20000240400022406020003 +:1078C0001040000F004028210E0007250000000096 +:1078D00000001021AE000000022038218FBF0018E8 +:1078E0008FB100148FB0001000402021000028212B +:1078F000000030210A00084527BD00208CA20000AE +:10790000022038218FBF00188FB100148FB00010F3 +:107910000040202100002821000030210A000845F5 +:1079200027BD002000A010213087FFFF8CA5000498 +:107930008C4400000A000845240600068F83FD9C45 +:1079400027BDFFE8AFBF0014AFB00010906700087C +:10795000008010210080282130E600400000202116 +:1079600010C000088C5000000E0000BD0200202155 +:10797000020020218FBF00148FB000100A000548BC +:1079800027BD00180E0008A4000000000E0000BD76 +:1079900002002021020020218FBF00148FB00010B0 +:1079A0000A00054827BD001827BDFFE0AFB0001052 +:1079B0008F90FD9CAFBF001CAFB20018AFB1001498 +:1079C00092060001008088210E00087230D2000467 +:1079D00092040005001129C2A6050000348300406E +:1079E000A20300050E00087C022020210E00054A9B +:1079F0000220202124020001AE02000C02202821D6 +:107A0000A602001024040002A602001224060200AE +:107A1000A60200140E000725A60200161640000F4D +:107A20008FBF001C978C00743C0B08008D6B007896 +:107A30002588FFFF3109FFFF256A0001012A382B45 +:107A400010E00006A78800743C0F6006240E0016A4 +:107A500035ED0010ADAE00508FBF001C8FB2001886 +:107A60008FB100148FB0001003E0000827BD002084 +:107A700027BDFFE0AFB10014AFBF0018AFB00010DA +:107A80001080000400A088212402008010820007DA +:107A9000000000000000000D8FBF00188FB100141F +:107AA0008FB0001003E0000827BD00200E00087210 +:107AB00000A020218F86FD9C0220202190C500057A +:107AC0000E00087C30B000FF2403003E1603FFF1D7 +:107AD0003C0680008CC401780480FFFE34C801405D +:107AE000240900073C071000AD11000002202021EE +:107AF000A10900048FBF00188FB100148FB00010CF +:107B0000ACC701780A0008C527BD002027BDFFE0EB +:107B1000AFB00010AFBF0018AFB100143C10800030 +:107B20008E110020000000000E00054AAE04002067 +:107B3000AE1100208FBF00188FB100148FB000105D +:107B400003E0000827BD00203084FFFF00803821BB +:107B50002406003500A020210A0008450000282145 +:107B60003084FFFF008038212406003600A0202149 +:107B70000A0008450000282127BDFFD0AFB500242A +:107B80003095FFFFAFB60028AFB40020AFBF002C88 +:107B9000AFB3001CAFB20018AFB10014AFB000100B +:107BA00030B6FFFF12A000270000A0218F920058DE +:107BB0008E4300003C0680002402004000033E0289 +:107BC00000032C0230E4007F006698241482001D1C +:107BD00030A500FF8F8300682C68000A1100001098 +:107BE0008F8D0044000358803C0C0800258C57B84A +:107BF000016C50218D4900000120000800000000A8 +:107C000002D4302130C5FFFF0E0008522404008446 +:107C1000166000028F920058AF8000688F8D00447C +:107C20002659002026980001032090213314FFFFDD +:107C300015A00004AF9900580295202B1480FFDC9A +:107C400000000000028010218FBF002C8FB600289A +:107C50008FB500248FB400208FB3001C8FB20018A2 +:107C60008FB100148FB0001003E0000827BD003072 +:107C70002407003414A70149000000009247000EB9 +:107C80008F9FFDA08F90FD9C24181600A3E700197C +:107C90009242000D3C0880003C07800CA3E20018D3 +:107CA000964A00123C0D60003C117FFFA60A005C62 +:107CB000964400103623FFFF240200053099FFFF91 +:107CC000AE1900548E46001CAD1800288CEF000041 +:107CD0008DAE444801E6482601C93021AE06003881 +:107CE0008E05003824CB00013C0E7F00AE05003C21 +:107CF0008E0C003CAFEC0004AE0B00208E13002075 +:107D0000AE13001CA3E0001BAE03002CA3E2001284 +:107D10008E4A001424130050AE0A00348E0400343E +:107D2000AFE400148E590018AE1900489258000CA8 +:107D3000A218004E920D000835AF0020A20F0008D7 +:107D40008E090018012E282434AC4000AE0C001817 +:107D5000920B0000317200FF1253027F2403FF8058 +:107D60003C04080024845BE80E0008AA0000000020 +:107D70003C1108008E315BE80E00087202202021C1 +:107D80002405000424080001A2050025022020216A +:107D90000E00087CA20800053C0580008CB001782C +:107DA0000600FFFE8F92005834AE0140240F0002FF +:107DB0003C091000ADD10000A1CF0004ACA90178AE +:107DC0000A000962AF8000682CAD003751A0FF9413 +:107DD0008F8D0044000580803C110800263157E05B +:107DE000021178218DEE000001C0000800000000A3 +:107DF0002411000414B1008C3C0780003C080800EA +:107E00008D085BE88F86FD9CACE800208E4500085D +:107E10008F99FDA0240D0050ACC500308E4C000899 +:107E2000ACCC00508E4B000CACCB00348E43001019 +:107E3000ACC300388E4A0010ACCA00548E42001405 +:107E4000ACC2003C8E5F0018AF3F00048E50001C97 +:107E5000ACD0002090C40000309800FF130D024AFF +:107E6000000000008CC400348CD00030009030231F +:107E700004C000F12404008C126000EE2402000310 +:107E80000A000962AF8200682419000514B900666F +:107E90003C0580003C0808008D085BE88F86FD9C4F +:107EA000ACA800208E4C00048F8AFDA0240720007F +:107EB000ACCC001C924B000824120008A14B001906 +:107EC0008F82005890430009A14300188F85005805 +:107ED00090BF000A33E400FF1092001028890009C7 +:107EE000152000BA240E0002240D0020108D000B76 +:107EF000340780002898002117000008240740005C +:107F000024100040109000053C0700012419008057 +:107F1000109900023C070002240740008CC20018A0 +:107F20003C03FF00004350240147F825ACDF001854 +:107F300090B2000BA0D200278F8300589464000CED +:107F4000108001FE000000009467000C3C1F8000C0 +:107F50002405FFBFA4C7005C9063000E2407000443 +:107F6000A0C300088F820058904A000FA0CA0009E1 +:107F70008F8900588D3200108FE400740244C823AA +:107F8000ACD900588D300014ACD0002C95380018B6 +:107F9000330DFFFFACCD00409531001A322FFFFFAB +:107FA000ACCF00448D2E001CACCE00489128000EB2 +:107FB000A0C8000890CC000801855824126001B6C2 +:107FC000A0CB00088F9200580A000962AF870068B2 +:107FD0002406000614A600143C0E80003C0F080086 +:107FE0008DEF5BE88F85FD98ADCF00208E4900189E +:107FF0008F86FD9C8F8BFDA0ACA900008CC800383B +:1080000024040005ACA800048CCC003C1260008164 +:10801000AD6C00000A000962AF84006824110007FB +:1080200010B1004B240400063C05080024A55BE8C1 +:108030000E000881240400818F9200580013102B39 +:108040000A000962AF820068241F002314BFFFF6F4 +:108050003C0C80003C0508008CA55BE88F8BFDA0E4 +:10806000AD8500208F91FD9C8E4600042564002084 +:1080700026450014AE260028240600030E000F81BA +:10808000257000308F87005802002021240600034D +:108090000E000F8124E500083C04080024845BE8FE +:1080A0000E0008AA0000000092230000240A0050DD +:1080B000306200FF544AFFE18F9200580E000F6CAF +:1080C000000000000A000A6A8F920058240800335A +:1080D00014A800323C0380003C1108008E315BE89C +:1080E0008F8FFDA0AC7100208E420008240D002867 +:1080F0008F89FD9CADE200308E4A000C24060009F9 +:10810000ADEA00348E5F0010ADFF00388E440014DD +:10811000ADE400208E590018ADF900248E58001CE3 +:10812000ADF80028A1ED00118E4E00041260003160 +:10813000AD2E00288F9200580A000962AF860068B1 +:10814000240D002214ADFFB8000000002404000735 +:108150003C1008008E105BE83C188000AF10002037 +:108160005660FEAEAF8400683C04080024845BE8DF +:108170000E0008AA241300508F84FD9C90920000EA +:10818000325900FF1333014B000000008F9200585A +:10819000000020210A000962AF8400683C05080045 +:1081A00024A55BE80E000858240400810A000A6A2E +:1081B0008F92005802D498213265FFFF0E000852BA +:1081C000240400840A0009628F920058108EFF5325 +:1081D000240704002887000310E00179241100041B +:1081E000240F0001548FFF4D240740000A000A228B +:1081F000240701003C05080024A55BE80E0008A444 +:10820000240400828F920058000030210A00096285 +:10821000AF8600683C04080024845BE88CC2003808 +:108220000E0008AA8CC3003C8F9200580A000AC0B6 +:1082300000002021240400823C05080024A55BE8FE +:108240000E0008A4000000008F92005800001021CA +:108250000A000962AF8200688E5000048F91FD9C75 +:108260003C078000ACF00020922C00050200282181 +:10827000318B0002156001562404008A8F92FDA004 +:108280002404008D9245001B30A6002014C001502C +:1082900002002821922E00092408001231C900FF93 +:1082A0001128014B240400810E00087202002021D5 +:1082B0009258001B240F000402002021370D0042B9 +:1082C000A24D001B0E00087CA22F00253C0580005B +:1082D0008CA401780480FFFE34B90140241F000201 +:1082E000AF300000A33F00048F9200583C101000F4 +:1082F000ACB001780A000A6B0013102B8E500004FA +:108300008F91FD9C3C038000AC700020922A0005F8 +:108310000200282131420002144000172404008A80 +:10832000922C00092412000402002821318B00FF46 +:1083300011720011240400810E0008720200202135 +:108340008F89FDA0240800122405FFFE912F001B39 +:108350000200202135EE0020A12E001BA2280009DA +:108360009226000500C538240E00087CA2270005CF +:1083700002002821000020210E0009330000000027 +:108380000A000A6A8F9200588E4C00043C07800055 +:108390003C10080026105BE8ACEC00203C01080013 +:1083A000AC2C5BE8924B0003317100041220013BBE +:1083B0008F84FD9C24020006A0820009924F001BBE +:1083C000240EFFC031E9003F012E4025A08800089F +:1083D0009245000330A6000114C0013200000000E5 +:1083E0008E420008AE0200083C0208008C425BF09E +:1083F000104001318F90FDA0000219C28F8DFD9CAD +:10840000A603000C8E4A000C24180001240400145A +:10841000AE0A002C8E420010AE02001C965F0016C1 +:10842000A61F003C96590014A619003EADB8000CDA +:10843000A5B80010A5B80012A5B80014A5B800167C +:1084400012600144A2040011925100033232000272 +:108450002E5300018F920058266200080A0009621C +:10846000AF8200688E4400043C1980003C068008FE +:10847000AF2400208E45000890D80000240D005045 +:10848000331100FF122D009C2407008824060009E8 +:108490000E000845000000000A000A6A8F9200588A +:1084A0008E5000043C0980003C118008AD30002053 +:1084B0009228000024050050310400FF10850110AF +:1084C0002407008802002021000028210E00084512 +:1084D0002406000E922D00002418FF80020028219F +:1084E00001B8802524040004240600300E0007256E +:1084F000A23000000A000A6A8F9200588E500004D1 +:108500008F91FDA03C028000AC500020923F001BE8 +:1085100033F900101320006C240700810200202191 +:10852000000028212406001F0E000845000000005E +:108530000A000A6A8F9200588E44001C0E00085DE3 +:1085400000000000104000E3004048218F880058E0 +:1085500024070089012020218D05001C240600012C +:108560000E000845000000000A000A6A8F920058B9 +:10857000964900023C10080026105BE831280004F0 +:10858000110000973C0460008E4E001C3C0F8000E0 +:10859000ADEE00203C010800AC2E5BE896470002DF +:1085A00030E40001148000E6000000008E42000468 +:1085B000AE0200083C1008008E105BF0120000ECC8 +:1085C0003C0F80008F92FD9C241000018E4E0018FD +:1085D0008F8DFDA08F9FFD9801CF4825AE490018D3 +:1085E000A2400005AE50000C3C0808008D085BF06E +:1085F0008F840058A6500010000839C2A6500012FF +:10860000A6500014A6500016A5A7000C8C8C0008DC +:108610008F8B00588F8A0058ADAC002C8D63000CF6 +:1086200024070002ADA3001C91460010A1A6001172 +:108630008F82005890450011A3E500088F990058DB +:1086400093380012A258004E8F910058922F0013B9 +:10865000A1AF00128F920058964E0014A5AE003CB8 +:1086600096490016A5A9003E8E480018ADA8001432 +:108670005660FD6AAF8700683C05080024A55BE8EA +:108680000E000881000020218F9200580000382140 +:108690000A000962AF8700683C05080024A55BE872 +:1086A0000E0008A4240400828F9200580A000A4D8C +:1086B000000038210E000F6C000000008F9200585F +:1086C0000A000AC0000020210E00087202002021CA +:1086D0009223001B02002021346A00100E00087C47 +:1086E000A22A001B000038210200202100002821BE +:1086F0000A000BA52406001F9242000C305F000107 +:1087000013E0000300000000964A000EA4CA002CEB +:10871000924B000C316300025060000600003821CB +:108720008E470014964C0012ACC7001CA4CC001A53 +:10873000000038210A000B7F240600093C050800D0 +:1087400024A55BE80E0008A42404008B8F92005837 +:108750000A000A4D0013382B3C0C08008D8C5BE896 +:1087600024DFFFFE25930100326B007F016790211B +:1087700002638824AD110028AE4600E0AE4000E45C +:108780000A0009B3AE5F001CACC000543C0D0800E9 +:108790008DAD5BE83C18800C37090100ACED00287A +:1087A0008E510014AD3100E08E4F0014AD2F00E467 +:1087B0008E4E001025C7FFFE0A0009F4AD27001CED +:1087C0005491FDD6240740000A000A222407100015 +:1087D0000E00092D000000000A000A6A8F9200585E +:1087E0008C83442C3C12DEAD3651BEEF3C010800B8 +:1087F000AC205BE810710062000000003C196C6264 +:1088000037387970147800082404000297850074C2 +:108810009782006C2404009200A2F82B13E0001948 +:1088200002002821240400020E00069524050200FF +:108830003C068000ACC200203C010800AC225BE892 +:108840001040000D8F8C0058240A002824040003D7 +:10885000918B0010316300FF546A00012404000171 +:108860000E0000810000000010400004240400837A +:108870000A000BC28F920058240400833C050800B4 +:1088800024A55BE80E000881000000008F920058CC +:108890000013382B0A000962AF8700680A000B49F1 +:1088A000240200128E4400080E00085D0000000043 +:1088B0000A000B55AE0200083C05080024A55BE841 +:1088C0000E000858240400878F9200580A000B728B +:1088D0000013102B240400040E000695240500301C +:1088E0001440002A004048218F8800582407008344 +:1088F000012020218D05001C0A000BB32406000175 +:108900008F8300788F8600701066FEEE000038219D +:108910003C07080024E75B6C000320C00087282187 +:108920008CAE000011D0005D246F000131E3000F18 +:108930005466FFFA000320C00A000B8C00003821A7 +:108940008E4400040E00085D000000000A000BC801 +:10895000AE0200083C05080024A55BE80E0008A450 +:10896000240400828F9200580A000B72000010212C +:108970003C05080024A55BE80A000C7C2404008761 +:108980008C83442C0A000C5B3C196C628F88005865 +:108990003C0780083C0C8000240B0050240A000196 +:1089A000AD820020A0EB0000A0EA000191030004CA +:1089B000A0E3001891040005A0E400199106000648 +:1089C0003C04080024845B6CA0E6001A91020007B6 +:1089D0003C06080024C65B68A0E2001B9105000865 +:1089E000A0E5001C911F0009A0FF001D9119000ABD +:1089F000A0F9001E9118000BA0F8001F9112000CA6 +:108A0000A0F200209111000DA0F100219110000EA4 +:108A1000A0F00022910F000FA0EF0023910E001094 +:108A2000A0EE0024910D0011A0ED0025950C00147E +:108A3000A4EC0028950B00168F8A00708F920078A6 +:108A4000A4EB002A95030018000A10C02545000178 +:108A5000A4E3002C8D1F001C0044C0210046C82147 +:108A600030A5000FAF3F0000AF09000010B20006B4 +:108A7000AF850070000038218D05001C01202021E9 +:108A80000A000BB32406000124AD000131A7000F3A +:108A9000AF8700780A000CF9000038213C06080076 +:108AA00024C65B680086902100003821ACA000003D +:108AB0000A000B8CAE4000003C0482013C036000C5 +:108AC00034820E02AC603D68AF80009803E000087D +:108AD000AC623D6C27BDFFE8AFB000103090FFFFE7 +:108AE000001018422C620041AFBF00141440000275 +:108AF00024040080240300403C010800AC300060E6 +:108B00003C010800AC2300640E000F7500602821B2 +:108B1000244802BF2409FF8001092824001039805D +:108B2000001030408FBF00148FB0001000A720212C +:108B300000861821AF8300803C010800AC25005856 +:108B40003C010800AC24005C03E0000827BD0018CD +:108B5000308300FF30C6FFFF30E400FF3C08800098 +:108B60008D0201B80440FFFE000354000144382583 +:108B70003C09600000E920253C031000AD050180A0 +:108B8000AD060184AD04018803E00008AD0301B81F +:108B90008F8500583C0A6012354800108CAC0004E8 +:108BA0003C0D600E35A60010318B00062D690001CA +:108BB000AD0900C48CA70004ACC731808CA20008AA +:108BC00094A40002ACC231848CA3001C0460000396 +:108BD000A784009003E00008000000008CAF00189C +:108BE000ACCF31D08CAE001C03E00008ACCE31D449 +:108BF0008F8500588F87FF288F86FF308CAE00044A +:108C00003C0F601235E80010ACEE00788CAD000827 +:108C1000ACED007C8CAC0010ACCC004C8CAB000CF0 +:108C2000ACCB004894CA00543C0208008C4200447B +:108C300025490001A4C9005494C400543083FFFFA7 +:108C400010620017000000003C0208008C42004047 +:108C5000A4C200528CA30018ACE300308CA2001414 +:108C6000ACE2002C8CB90018ACF900388CB80014B8 +:108C700024050001ACF800348D0600BC50C5001975 +:108C80008D0200B48D0200B8A4E2004894E40048CC +:108C9000A4E4004A94E800EA03E000083102FFFF80 +:108CA0003C0208008C420024A4C00054A4C200521C +:108CB0008CA30018ACE300308CA20014ACE2002CB2 +:108CC0008CB90018ACF900388CB8001424050001E8 +:108CD000ACF800348D0600BC54C5FFEB8D0200B823 +:108CE0008D0200B4A4E2004894E40048A4E4004AE1 +:108CF00094E800EA03E000083102FFFF8F86005885 +:108D00003C0480008CC900088CC80008000929C0F8 +:108D1000000839C0AC87002090C30007306200040F +:108D20001040003EAF85009490CB0007316A0008E8 +:108D30001140003D8F87FF2C8CCD000C8CCE001491 +:108D400001AE602B11800036000000008CC2000CC8 +:108D5000ACE200708CCB00188F85FF288F88FF3025 +:108D6000ACEB00748CCA00102402FFF8ACAA00D847 +:108D70008CC9000CAD0900608CC4001CACA400D0F0 +:108D800090E3007C0062C824A0F9007C90D8000722 +:108D9000330F000811E000040000000090ED007C9B +:108DA00035AC0001A0EC007C90CF000731EE000153 +:108DB00011C000060000000090E3007C241800347D +:108DC00034790002A0F9007CACB800DC90C2000746 +:108DD0003046000210C000040000000090E8007C53 +:108DE00035040004A0E4007C90ED007D3C0B600E97 +:108DF000356A001031AC003FA0EC007D8D4931D4C4 +:108E00003127000110E00002240E0001A0AE00098D +:108E100094AF00EA03E0000831E2FFFF8F87FF2CE8 +:108E20000A000DAF8CC200140A000DB0ACE0007057 +:108E30008F8C005827BDFFD8AFB3001CAFB200180D +:108E4000AFB00010AFBF0020AFB10014918F00157C +:108E50003C13600E3673001031EB000FA38B009CA7 +:108E60008D8F00048D8B0008959F0012959900103E +:108E70009584001A9598001E958E001C33EDFFFF17 +:108E8000332AFFFF3089FFFF3308FFFF31C7FFFFA1 +:108E90003C010800AC2D00243C010800AC29004432 +:108EA0003C010800AC2A0040AE683178AE67317CE6 +:108EB00091850015959100163C12601236520010F3 +:108EC00030A200FF3230FFFFAE623188AE5000B4F6 +:108ED00091830014959F0018240600010066C804C1 +:108EE00033F8FFFFAE5900B8AE5800BC918E0014A5 +:108EF000AF8F00843C08600631CD00FFAE4D00C04E +:108F0000918A00159584000E3C07600A314900FFE4 +:108F1000AF8B00883084FFFFAE4900C835110010C8 +:108F20000E000D1034F004103C0208008C4200606A +:108F30003C0308008C6300643C0608008CC60058A3 +:108F40003C0508008CA5005C8F8400808FBF00204A +:108F5000AE23004CAE65319CAE030054AE4500DC40 +:108F6000AE6231A0AE6331A4AE663198AE22004845 +:108F70008FB3001CAE0200508FB10014AE4200E06F +:108F8000AE4300E4AE4600D88FB000108FB2001898 +:108F90000A00057D27BD0028978500929783007CF5 +:108FA00027BDFFE8AFB0001000A3102BAFBF001427 +:108FB000240400058F900058104000552409000239 +:108FC0000E0006958F850080AF8200942404000374 +:108FD0001040004F240900023C0680000E00008172 +:108FE000ACC2002024070001240820001040004DDE +:108FF00024040005978E00928F8AFF2C24090050CC +:1090000025C50001A7850092A14900003C0D08007C +:109010008DAD0064240380008F84FF28000D66005E +:10902000AD4C0018A5400006954B000A8F85FF3017 +:109030002402FF8001633024A546000A915F000AE4 +:109040000000482103E2C825A159000AA0A0000899 +:10905000A140004CA08000D5961800029783009094 +:109060003C020004A49800EA960F00022418FFBFF7 +:1090700025EE2401A48E00BE8E0D0004ACAD00448C +:109080008E0C0008ACAC0040A4A00050A4A000547A +:109090008E0B000C240C0030AC8B00288E060010C8 +:1090A000AC860024A480003EA487004EA487005014 +:1090B000A483003CAD420074AC8800D8ACA800602A +:1090C000A08700FC909F00D433F9007FA09900D4C2 +:1090D000909000D402187824A08F00D4914E007C88 +:1090E00035CD0001A14D007C938B009CAD480070F4 +:1090F000AC8C00DCA08B00D68F8800888F87008422 +:10910000AC8800C4AC8700C8A5400078A540007AB0 +:109110008FBF00148FB000100120102103E0000861 +:1091200027BD00188F8500940E0007258F860080CC +:109130000A000E9F2409000227BDFFE0AFB0001017 +:109140008F900058AFB10014AFBF00188E09000413 +:109150000E00054A000921C08E0800048F84FF28F4 +:109160008F82FF30000839C03C068000ACC7002069 +:10917000948500EA904300131460001C30B1FFFF97 +:109180008F8CFF2C918B0008316A00401540000B3A +:10919000000000008E0D0004022030218FBF001857 +:1091A0008FB100148FB00010240400220000382179 +:1091B000000D29C00A000D2F27BD00200E000098C9 +:1091C000000000008E0D0004022030218FBF001827 +:1091D0008FB100148FB00010240400220000382149 +:1091E000000D29C00A000D2F27BD00200E000090A1 +:1091F000000000008E0D0004022030218FBF0018F7 +:109200008FB100148FB00010240400220000382118 +:10921000000D29C00A000D2F27BD002027BDFFE04B +:10922000AFB200183092FFFFAFB00010AFBF001C0C +:10923000AFB100141240001E000080218F8600583C +:109240008CC500002403000600053F02000514023F +:1092500030E4000714830016304500FF2CA80006F8 +:1092600011000040000558803C0C0800258C58BCBB +:10927000016C50218D490000012000080000000011 +:109280008F8E0098240D000111CD005024020002A1 +:10929000AF820098260900013130FFFF24C800206A +:1092A0000212202B010030211480FFE5AF88005806 +:1092B000020010218FBF001C8FB200188FB1001464 +:1092C0008FB0001003E0000827BD00209387007EC8 +:1092D00054E00034000030210E000DE700000000D3 +:1092E0008F8600580A000EFF240200018F87009825 +:1092F0002405000210E50031240400130000282199 +:1093000000003021240700010E000D2F0000000096 +:109310000A000F008F8600588F83009824020002F5 +:109320001462FFF6240400120E000D9A00000000E3 +:109330008F85009400403021240400120E000D2F70 +:10934000000038210A000F008F8600588F83009894 +:109350002411000310710029241F0002107FFFCE8A +:1093600026090001240400100000282100003021FB +:109370000A000F1D240700018F91009824060002A7 +:109380001626FFF9240400100E000E410000000014 +:10939000144000238F9800588F8600580A000EFF53 +:1093A00024020003240400140E000D2F00002821C5 +:1093B0008F8600580A000EFF240200020E000EA93C +:1093C000000000000A000F008F8600580E000D3FBD +:1093D00000000000241900022404001400002821C9 +:1093E0000000302100003821AF9900980E000D2FA9 +:1093F000000000000A000F008F8600580E000D5775 +:10940000000000008F8500942419000200403021E4 +:1094100024040010000038210A000F56AF9900986C +:109420000040382124040010970F0002000028217A +:109430000E000D2F31E6FFFF8F8600580A000F0047 +:10944000AF9100988F84FF2C3C077FFF34E6FFFF2D +:109450008C8500182402000100A61824AC83001893 +:1094600003E00008A08200053084FFFF30A5FFFF65 +:109470001080000700001821308200011040000217 +:1094800000042042006518211480FFFB00052840DD +:1094900003E000080060102110C000070000000079 +:1094A0008CA2000024C6FFFF24A50004AC820000AB +:1094B00014C0FFFB2484000403E000080000000047 +:1094C00010A0000824A3FFFFAC86000000000000ED +:1094D000000000002402FFFF2463FFFF1462FFFA74 +:1094E0002484000403E0000800000000000411C010 +:1094F00003E000082442024027BDFFE8AFB000109F +:1095000000808021AFBF00140E000F9600A0202124 +:1095100000504821240AFF808FBF00148FB0001034 +:10952000012A30243127007F3C08800A3C042100B6 +:1095300000E8102100C428253C03800027BD001846 +:10954000AC650024AF820038AC400000AC6500245C +:1095500003E00008AC4000403C0D08008DAD005811 +:1095600000056180240AFF8001A45821016C482174 +:10957000012A30243127007F3C08800C3C04210064 +:1095800000E8102100C428253C038000AC650028B9 +:10959000AF82003403E00008AC40002430A5FFFF98 +:1095A0003C0680008CC201B80440FFFE3C086015F8 +:1095B00000A838253C031000ACC40180ACC0018475 +:1095C000ACC7018803E00008ACC301B83C0D08003B +:1095D0008DAD005800056180240AFF8001A4582148 +:1095E000016C4021010A4824000931403107007F05 +:1095F00000C728253C04200000A418253C02800058 +:10960000AC43083003E00008AF80003427BDFFE81A +:10961000AFB0001000808021AFBF00140E000F9685 +:1096200000A0202100504821240BFF80012B502452 +:10963000000A39403128007F3C0620008FBF00140B +:109640008FB0001000E8282534C2000100A21825C0 +:109650003C04800027BD0018AC83083003E00008FC +:10966000AF8000383C0580088CA700603C0680086D +:109670000087102B144000112C8340008CA8006040 +:109680002D0340001060000F240340008CC90060CF +:109690000089282B14A00002008018218CC30060D0 +:1096A00000035A42000B30803C0A0800254A59202A +:1096B00000CA202103E000088C8200001460FFF340 +:1096C0002403400000035A42000B30803C0A08008B +:1096D000254A592000CA202103E000088C8200009E +:1096E0003C05800890A60008938400AB24C20001CA +:1096F000304200FF3043007F1064000C0002382726 +:10970000A0A200083C0480008C85017804A0FFFE24 +:109710008F8A00A0240900023C081000AC8A014096 +:10972000A089014403E00008AC8801780A00101BFE +:1097300030E2008027BDFFD8AFB200188F9200A49E +:10974000AFBF0020AFB3001CAFB00010AFB100142A +:109750008F9300348E5900283C1000803C0EFFEFA0 +:10976000AE7900008E580024A260000A35CDFFFFBC +:10977000AE7800049251002C3C0BFF9F356AFFFF2E +:10978000A271000C8E6F000C3C080040A271000B0F +:1097900001F06025018D4824012A382400E8302595 +:1097A000AE66000C8E450004AE6000183C0400FF5D +:1097B000AE6500148E43002C3482FFFFA6600008C3 +:1097C0000062F824AE7F00108E5900088F9000A030 +:1097D000964E0012AE7900208E51000C31D83FFF1A +:1097E00000187980AE7100248E4D001401F06021C4 +:1097F00031CB0001AE6D00288E4A0018000C41C22A +:10980000000B4B80AE6A002C8E46001C01093821EB +:10981000A667001CAE660030964500028E4400200C +:10982000A665001EAE64003492430033306200042B +:1098300054400006924700003C0280083443010077 +:109840008C7F00D0AE7F0030924700008F860038BA +:10985000A0C700309245003330A4000250800007BA +:10986000925100018F880038240BFF80910A00304C +:10987000014B4825A1090030925100018F9000381A +:10988000240CFFBF2404FFDFA21100318F8D0038AC +:109890003C1880083711008091AF003C31EE007F0A +:1098A000A1AE003C8F890038912B003C016C502404 +:1098B000A12A003C8F9F00388E68001493E6003C7C +:1098C0002D0700010007114000C4282400A218251C +:1098D000A3E3003C8F87003896590012A4F90032A8 +:1098E0008E450004922E007C30B0000300107823D7 +:1098F00031ED000300AD102131CC000215800002D3 +:1099000024460034244600303C0280083443008062 +:10991000907F007C00BFC824333800041700000289 +:1099200024C2000400C010218F98003824190002BE +:10993000ACE20034A3190000924F003F8F8E003834 +:109940003C0C8008358B0080A1CF00018F9100383E +:10995000924D003F8E440004A62D0002956A005CE3 +:109960000E000FF43150FFFF00024B800209382532 +:109970003C08420000E82825AE2500048E4400384B +:109980008F850038ACA400188E460034ACA6001CAD +:10999000ACA0000CACA00010A4A00014A4A0001661 +:1099A000A4A00020A4A00022ACA000248E62001479 +:1099B00050400001240200018FBF00208FB3001C23 +:1099C0008FB200188FB100148FB00010ACA2000845 +:1099D0000A00101327BD002827BDFFC83C058008DA +:1099E00034A40080AFBF0034AFBE0030AFB7002C4E +:1099F000AFB60028AFB50024AFB40020AFB3001C51 +:109A0000AFB20018AFB10014AFB00010948300786B +:109A10009482007A104300512405FFFF0080F0215A +:109A20000A0011230080B821108B004D8FBF003435 +:109A30008F8600A03C1808008F18005C2411FF805E +:109A40003C1680000306782101F18024AED0002C62 +:109A500096EE007A31EC007F3C0D800E31CB7FFF1B +:109A6000018D5021000B4840012AA82196A4000036 +:109A70003C0808008D0800582405FF8030953FFF02 +:109A800001061821001539800067C8210325F82434 +:109A90003C02010003E290253338007F3C11800C2A +:109AA000AED20028031190219250000D320F000415 +:109AB00011E0003702E0982196E3007A96E8007AF8 +:109AC00096E5007A2404800031077FFF24E300013B +:109AD00030627FFF00A4F82403E2C825A6F9007ACB +:109AE00096E6007A3C1408008E94006030D67FFF22 +:109AF00012D400C1000000008E5800188F8400A00E +:109B000002A028212713FFFF0E000FCEAE53002C1A +:109B100097D5007897D4007A12950010000028217C +:109B20003C098008352401003C0A8008914800085F +:109B3000908700D53114007F30E400FF0284302B81 +:109B400014C0FFB9268B0001938E00AB268C000158 +:109B5000008E682115ACFFB78F8600A08FBF003440 +:109B60008FBE00308FB7002C8FB600288FB5002431 +:109B70008FB400208FB3001C8FB200188FB1001477 +:109B80008FB0001000A0102103E0000827BD0038AE +:109B900000C020210E000F99028028218E4B00105A +:109BA0008E4C00308F84003824090002016C502351 +:109BB000AE4A0010A089000096E3005C8E4400309D +:109BC0008F9100380E000FF43070FFFF00024380C9 +:109BD000020838253C02420000E22825AE25000498 +:109BE0008E5F00048F8A00388E590000240B000815 +:109BF000AD5F001CAD590018AD40000CAD40001029 +:109C00009246000A240400052408C00030D000FF5A +:109C1000A550001496580008A55800169251000A45 +:109C20003C188008322F00FFA54F0020964E0008F8 +:109C300037110100A54E0022AD400024924D000BCB +:109C400031AC00FFA54C0002A14B00018E49003051 +:109C50008F830038240BFFBFAC690008A06400307C +:109C60008F9000382403FFDF9607003200E8282495 +:109C700000B51025A6020032921F003233F9003FD2 +:109C800037260040A20600328F8C0038AD800034A9 +:109C90008E2F00D0AD8F0038918E003C3C0F7FFF9F +:109CA00031CD007FA18D003C8F84003835EEFFFF61 +:109CB000908A003C014B4824A089003C8F850038E5 +:109CC00090A8003C01033824A0A7003C8E42003439 +:109CD0008F9100383C038008AE2200408E59002C42 +:109CE0008E5F0030033F3023AE26004492300048A0 +:109CF0003218007FA23800488F8800388E4D00301F +:109D00008D0C004801AE582401965024014B482583 +:109D1000AD0900489244000AA104004C964700088F +:109D20008F850038A4A7004E8E5000308E4400303E +:109D30000E0003818C65006092F9007C0002F940FE +:109D4000004028210002110003E2302133360002D6 +:109D500012C00003020680210005B0800216802197 +:109D6000926D007C31B30004126000020005708027 +:109D7000020E80218E4B00308F8800382405800031 +:109D8000316A0003000A4823312400030204182129 +:109D9000AD03003496E4007A96F0007A96F1007AEA +:109DA00032027FFF2447000130FF7FFF0225C824D5 +:109DB000033F3025A6E6007A96F8007A3C120800A8 +:109DC0008E520060330F7FFF11F200180000000078 +:109DD0008F8400A00E000FCE02A028218F8400A047 +:109DE0000E000FDE028028210E001013000000007C +:109DF0000A00111F0000000096F1007A022480245E +:109E0000A6F0007A92EF007A92EB007A31EE00FF32 +:109E1000000E69C2000D6027000C51C03169007F3F +:109E2000012A20250A001119A2E4007A96E6007A98 +:109E300000C5C024A6F8007A92EF007A92F3007A67 +:109E400031F200FF001271C2000E6827000DB1C090 +:109E5000326C007F01962825A2E5007A0A0011D015 +:109E60008F8400A03C0380003084FFFF30A5FFFFFB +:109E7000AC640018AC65001C03E000088C620014A0 +:109E800027BDFFA03C068008AFBF005CAFBE0058F6 +:109E9000AFB70054AFB60050AFB5004CAFB40048F8 +:109EA000AFB30044AFB20040AFB1003CAFB0003838 +:109EB00034C80100910500D590C700083084FFFF29 +:109EC00030A500FF30E2007F0045182AAFA4001043 +:109ED000A7A00018A7A0002610600055AFA000148E +:109EE00090CA00083149007F00A9302324D3FFFF26 +:109EF0000013802B8FB400100014902B02128824C2 +:109F0000522000888FB300143C03800894790052DB +:109F1000947E00508FB60010033EC0230018BC0092 +:109F2000001714030016FC0002C2A82A16A00002A3 +:109F3000001F2C030040282100133C0000072403CD +:109F400000A4102A5440000100A020212885000907 +:109F500014A000020080A021241400083C0C8008FA +:109F60008D860048001459808D88004C3C03800089 +:109F70003169FFFF3C0A0010012A202534710400DA +:109F8000AC660038AF9100A4AC68003CAC64003013 +:109F900000000000000000000000000000000000C1 +:109FA00000000000000000000000000000000000B1 +:109FB0008C6E000031CD002011A0FFFD0014782A26 +:109FC00001F01024104000390000A8213C16800840 +:109FD00092D700083C1280008E44010032F6007FC8 +:109FE0000E000F9902C028218E3900108E44010006 +:109FF0000000902133373FFF0E000FB102E028210F +:10A00000923800003302003F2C500008520000102C +:10A0100000008821000210803C030800246358E4FB +:10A020000043F8218FFE000003C00008000000007C +:10A0300090CF0008938C00AB31EE007F00AE682318 +:10A04000018D58210A0012172573FFFF0000882197 +:10A050003C1E80008FC401000E000FCE02E02821BC +:10A060008FC401000E000FDE02C028211220000F55 +:10A070000013802B8F8B00A426A400010004AC00E9 +:10A08000027298230015AC032578004002B4B02A70 +:10A090000013802B241700010300882102D0102414 +:10A0A000AF9800A41440FFC9AFB700143C07800864 +:10A0B00094E200508FAE00103C05800002A288217F +:10A0C0003C060020A4F10050ACA6003094F40050EF +:10A0D00094EF005201D51823306CFFFF11F4001EDD +:10A0E000AFAC00108CEF004C001561808CF500487F +:10A0F00001EC28210000202100AC582B02A4C02133 +:10A10000030BB021ACE5004CACF600488FB4001056 +:10A110000014902B021288241620FF7C3C03800838 +:10A120008FB300148FBF005C8FBE00583A620001ED +:10A130008FB700548FB600508FB5004C8FB40048D5 +:10A140008FB300448FB200408FB1003C8FB0003815 +:10A1500003E0000827BD006094FE00548CF2004428 +:10A1600033C9FFFE0009C8C00259F821ACBF003C4A +:10A170008CE800448CAD003C010D50231940003B9D +:10A18000000000008CF7004026E20001ACA200387D +:10A190003C05005034A700103C038000AC67003041 +:10A1A00000000000000000000000000000000000AF +:10A1B000000000000000000000000000000000009F +:10A1C0008C7800003316002012C0FFFD3C1180087F +:10A1D000962200543C1580003C068008304E000159 +:10A1E000000E18C0007578218DEC04003C070800B3 +:10A1F0008CE700443C040020ACCC00488DF40404FF +:10A20000240B0001ACD4004C10EB0260AEA4003073 +:10A21000963900523C0508008CA5004000B99021F9 +:10A22000A6320052963F005427ED0001A62D00549F +:10A230009626005430C4FFFF5487FF2F8FB40010C0 +:10A2400030A5FFFF0E0011F4A62000543C070800C3 +:10A250008CE70024963E00520047B82303D74823DA +:10A26000A62900520A0012198FB400108CE2004097 +:10A270000A0012BE00000000922400012407000121 +:10A280003085007F14A7001C97AD00268E2B00148C +:10A29000240CC000316A3FFF01AC48243C06080092 +:10A2A0008CC60060012A402531043FFF0086882BC0 +:10A2B00012200011A7A800263C0508008CA5005814 +:10A2C0008F9100A0000439802402FF8000B1182182 +:10A2D0000067F82103E2F02433F8007F3C1280008D +:10A2E0003C19800EAE5E002C0319702191D0000D38 +:10A2F000360F0004A1CF000D0E001028241200011B +:10A30000241100013C1E80008FC401000E000FCEFE +:10A3100002E028218FC401000E000FDE02C02821B8 +:10A320001620FF558F8B00A40A0012860013802B85 +:10A330008F8600A490C80001310400201080019194 +:10A34000241000013C048008348B0080916A007C5A +:10A350008F9E0034AFA0002C314900011120000F66 +:10A36000AFB000288CCD00148C8E006001AE602B45 +:10A370001580000201A038218C8700603C188008FD +:10A38000370300808C70007000F0782B15E000021D +:10A3900000E020218C640070AFA4002C3C028008F7 +:10A3A000344500808CD200148CBF0070025FC82B33 +:10A3B00017200002024020218CA400708FA7002CDF +:10A3C0000087182310600003AFA3003024050002AB +:10A3D000AFA500288FA400280264882B162000BA9D +:10A3E000000018218CD000388FCE000C3C0F00806C +:10A3F000AFD000008CCD00343C0CFF9F01CF58251E +:10A40000AFCD000490CA003F3586FFFF01662024CF +:10A410003C0900203C08FFEFA3CA000B0089382547 +:10A420003511FFFF00F118243C0500088F8700A4B8 +:10A430000065C825AFD9000C8CE20014AFC000182D +:10A440008FA60030AFC200148CF800188FB0002C1B +:10A450003C1FFFFBAFD8001C8CEF000837F2FFFF5A +:10A4600003326824AFCF00248CEC000C020670216C +:10A47000AFCD000CA7C00038A7C0003AAFCE002C6B +:10A48000AFCC0020AFC000288CEA00148FAB002CAA +:10A49000014B48230126402311000011AFC80010D2 +:10A4A00090EB003D8FC900048FC80000000B5100E5 +:10A4B000012A28210000102100AA882B010218215E +:10A4C0000071F821AFC50004AFDF000090F2003D3D +:10A4D000A3D2000A8F9900A497380006A7D80008D5 +:10A4E0008F910038240800023C038008A228000055 +:10A4F0003465008094BF005C8FA4002C33F0FFFF14 +:10A500000E000FF48F9200380002CB808F8500A4DC +:10A51000021978253C18420001F87025AE4E00045F +:10A520008F8400388CAD0038AC8D00188CAC0034B2 +:10A53000AC8C001CAC80000CAC800010A48000141B +:10A54000A4800016A4800020A4800022AC800024F7 +:10A5500090A6003F8FA7002CA486000250E0019235 +:10A56000240700018FA200305040000290A2003D5D +:10A5700090A2003E244A0001A08A00018F84003886 +:10A580008FA9002CAC8900083C128008364D008051 +:10A5900091AC007C3186000214C000022407003414 +:10A5A000240700308F8500A43C198008373F0080C5 +:10A5B00090B0000093F9007C240E0004A0900030BD +:10A5C0008F8F00A48FB8002C8F8D003891F200017E +:10A5D0003304000301C46023A1B200318F8E003820 +:10A5E0008F8600A42402C00095CA003294C90012CC +:10A5F0008FAB002C0142402431233FFF010388250B +:10A60000A5D1003291D000323185000300EBF82152 +:10A610003218003F370F0040A1CF00328FA4002C2A +:10A6200003E5382133280004108000028F850038AC +:10A6300000E838213C0A8008ACA700343549010005 +:10A640008D2800D08FA3002C2419FFBFACA80038A0 +:10A6500090B1003C2C640001240FFFDF3227007F03 +:10A66000A0A7003C8F98003800049140931F003C45 +:10A6700003F98024A310003C8F8C0038918E003C9D +:10A6800001CF682401B23025A186003C8F8900A447 +:10A690008F8800388D2B0020AD0B00408D220024C8 +:10A6A000AD0200448D2A0028AD0A00488D23002CFD +:10A6B0000E001013AD03004C8FB1002824070002D8 +:10A6C000122700118FA300280003282B00058023E8 +:10A6D0000270982400608021006090210A00126FAF +:10A6E0000010882B962900128F8400A00000902172 +:10A6F0003125FFFFA7A900180E000FC22411000189 +:10A700000A00131D3C1E80003C0B80003C12800898 +:10A710008D640100924900088F92FF340E000F995A +:10A720003125007F8F9900388FA700288FA4003033 +:10A73000A3270000965F005C33F0FFFF0E000FF4CC +:10A740008F91003800026B80020D80253C0842008A +:10A750008F8D00A402085025AE2A00048DA5003874 +:10A760008F8A003800007821000F1100AD450018D5 +:10A770008DB800343C047FFF3488FFFFAD58001CC7 +:10A7800091A6003E8D4C001C8D4900180006190052 +:10A79000000677020183C821004E58250323882B29 +:10A7A000012B382100F1F821AD59001CAD5F0018D4 +:10A7B000AD40000CAD40001091B0003E8FA40030C1 +:10A7C00024090005A550001495A500042419C00013 +:10A7D00000884024A545001691B8003EA5580020E9 +:10A7E00095AF0004A54F0022AD40002491AE003F7C +:10A7F000A54E000291A6003E91AC003D01861023BB +:10A80000244B0001A14B00018F9100388FA3003031 +:10A810003C028008344B0100AE230008A22900301E +:10A820008F8C00388F8700A4959F003294F000121F +:10A830002407FFBF033FC02432053FFF03057825EF +:10A84000A58F0032918E00322418FFDF31CD003FFA +:10A8500035A60040A18600328F910038240DFFFFFD +:10A86000240CFF80AE2000348D6A00D0AE2A003860 +:10A870009223003C3069007FA229003C8F90003871 +:10A880003C0380009219003C0327F824A21F003CDF +:10A890008F8E003891C5003C00B87824A1CF003CD1 +:10A8A0008F8A00383C0E8008AD4D00408FA6002CEA +:10A8B000AD46004491420048004C5825A14B004849 +:10A8C0008F9000388F9900A48E09004801238824B6 +:10A8D00002283825AE070048933F003EA21F004CD7 +:10A8E0008F9800A48F8F003897050004A5E5004ECF +:10A8F0000E0003818DC500609246007C8FAC003055 +:10A9000000026940000291000040282130CB000283 +:10A9100001B21021156000AA018230213C0E80088E +:10A9200035C20080904C007C31830004106000032D +:10A930008FB900300005788000CF3021241F00043B +:10A940008F910038332D000303ED8023320800037C +:10A9500000C85021AE2A00343C188000A7C500383A +:10A960003C0680088F04010090DE00080E000FDE18 +:10A9700033C5007F0E001013000000000A00140D04 +:10A980008FA300288F9800348CC90038241F00033F +:10A99000A7000008AF0900008CC50034A300000A1E +:10A9A0008F9900A4AF0500043C080080932D003F60 +:10A9B000A31F000C8F0A000C3C02FF9FA30D000B8D +:10A9C0000148F0253451FFFF3C12FFEF8F9900A49E +:10A9D00003D170243646FFFF01C61824AF03000CD4 +:10A9E0008F2C0014972900128F8400A0AF0C001048 +:10A9F0008F2F0014AF000018AF000020AF0F00141D +:10AA0000AF0000248F270018312F3FFF000F59801F +:10AA1000AF0700288F2500080164F821312D0001BF +:10AA2000AF0500308F31000C8F920038001F51C2EB +:10AA3000000D438001481021241E00023C068008BE +:10AA4000A702001CA7000034AF11002CA25E00007A +:10AA500034D20080964E005C8F9900383C0342004F +:10AA600031CCFFFF01833825AF2700048F8B00A472 +:10AA7000240500012402C0008D640038240700343E +:10AA8000AF2400188D690034AF29001CAF20000CE2 +:10AA9000AF200010A7200014A7200016A720002038 +:10AAA000A7200022AF200024A7300002A325000128 +:10AAB0008F8800388F9F00A4AD10000893ED000030 +:10AAC000A10D00308F8A00A48F98003891510001A9 +:10AAD000A31100318F8B0038957E003203C27024A1 +:10AAE00001CF6025A56C0032916300323064003FD5 +:10AAF000A16400329249007C3125000214A00002BA +:10AB00008F840038240700303C198008AC8700345B +:10AB1000373201008E5F00D0240AFFBF020090216F +:10AB2000AC9F0038908D003C31A8007FA088003C8D +:10AB30008F9E003893C2003C004A8824A3D1003C79 +:10AB40008F8300380010882B9066003C34CE0020A4 +:10AB5000A06E003C8F8400A48F9800388C8C00205D +:10AB6000AF0C00408C8F0024AF0F00448C8700286E +:10AB7000AF0700488C8B002CAF0B004C0E0010135D +:10AB80003C1E80000A0012700000000094C80052B1 +:10AB90003C0A08008D4A002401488821A4D10052B3 +:10ABA0000A0012198FB40010A08700018F840038AA +:10ABB000240B0001AC8B00080A0013BE3C12800875 +:10ABC000000520800A0014A200C4302127BDFFE048 +:10ABD0003C0D8008AFB20018AFB00010AFBF001C32 +:10ABE000AFB1001435B200808E4C001835A80100BA +:10ABF000964B000695A70050910900FC000C5602E8 +:10AC0000016728233143007F312600FF240200031F +:10AC1000AF8300A8AF8400A010C2001B30B0FFFFBC +:10AC2000910600FC2412000530C200FF10520033D0 +:10AC300000000000160000098FBF001C8FB2001832 +:10AC40008FB100148FB00010240D0C003C0C80005C +:10AC500027BD002003E00008AD8D00240E0011FB8D +:10AC6000020020218FBF001C8FB200188FB100148A +:10AC70008FB00010240D0C003C0C800027BD00207C +:10AC800003E00008AD8D0024965800789651007AB4 +:10AC9000924E007D0238782631E8FFFF31C400C0B3 +:10ACA000148000092D11000116000037000000007B +:10ACB0005620FFE28FBF001C0E0010D100000000E4 +:10ACC0000A00156A8FBF001C1620FFDA0000000082 +:10ACD0000E0010D1000000001440FFD88FBF001CF0 +:10ACE0001600002200000000925F007D33E2003F6A +:10ACF000A242007D0A00156A8FBF001C950900EA78 +:10AD00008F86008000802821240400050E0007257E +:10AD10003130FFFF978300923C0480002465FFFFE1 +:10AD2000A78500928C8A01B80540FFFE0000000054 +:10AD3000AC8001808FBF001CAC9001848FB20018E2 +:10AD40008FB100148FB000103C0760133C0B100053 +:10AD5000240D0C003C0C800027BD0020AC8701882E +:10AD6000AC8B01B803E00008AD8D00240E0011FB90 +:10AD7000020020215040FFB18FBF001C925F007D78 +:10AD80000A00159733E2003F0E0011FB020020215C +:10AD90001440FFAA8FBF001C122000070000000013 +:10ADA0009259007D3330003F36020040A242007DC0 +:10ADB0000A00156A8FBF001C0E0010D100000000B1 +:10ADC0005040FF9E8FBF001C9259007D3330003FE2 +:08ADD0000A0015C6360200401E +:08ADD800000000000000001B58 +:10ADE0000000000F0000000A00000008000000063C +:10ADF0000000000500000005000000040000000441 +:10AE00000000000300000003000000030000000336 +:10AE10000000000300000002000000020000000229 +:10AE2000000000020000000200000002000000021A +:10AE3000000000020000000200000002000000020A +:10AE400000000002000000020000000200000002FA +:0CAE5000000000010000000100000001F3 +:04AE5C008008010069 +:10AE6000800800808008000000000C000000308096 +:10AE7000080011D00800127C08001294080012A8E3 +:10AE8000080012BC080011D0080011D0080012F010 +:10AE90000800132C080013400800138808001A8CBF +:10AEA00008001A8C08001AC408001AC408001AD82E +:10AEB00008001AA808001D0008001CCC08001D5836 +:10AEC00008001D5808001DE008001D108008024001 +:10AED000080027340800256C0800275C080027F4C8 +:10AEE0000800293C0800298808002AAC080029B479 +:10AEF00008002A38080025DC08002EDC08002EA4F3 +:10AF000008002588080025880800258808002B20CF +:10AF100008002B20080025880800258808002DD06F +:10AF2000080025880800258808002588080025884D +:10AF300008002E0C080025880800258808002588B0 +:10AF4000080025880800258808002588080025882D +:10AF5000080025880800258808002588080025881D +:10AF6000080025880800258808002588080029A8E9 +:10AF7000080025880800258808002E680800258814 +:10AF800008002588080025880800258808002588ED +:10AF900008002588080025880800258808002588DD +:10AFA00008002588080025880800258808002588CD +:10AFB00008002588080025880800258808002588BD +:10AFC00008002CF4080025880800258808002C6853 +:10AFD00008002BC408003CE408003CB808003C848E +:10AFE00008003C5808003C3808003BEC8008010091 +:10AFF00080080080800800008008008008004C6401 +:10B0000008004C9C08004BE408004C6408004C64A9 +:0CB01000080049B808004C6408005050CB +:04B01C000A000C8496 +:10B0200000000000000000000000000D7278703683 +:10B030002E322E31610000000602010300000000E4 +:10B0400000000001000000000000000000000000FF +:10B0500000000000000000000000000000000000F0 +:10B0600000000000000000000000000000000000E0 +:10B0700000000000000000000000000000000000D0 +:10B0800000000000000000000000000000000000C0 +:10B0900000000000000000000000000000000000B0 +:10B0A00000000000000000000000000000000000A0 +:10B0B0000000000000000000000000000000000090 +:10B0C0000000000000000000000000000000000080 +:10B0D0000000000000000000000000000000000070 +:10B0E0000000000000000000000000000000000060 +:10B0F0000000000000000000000000000000000050 +:10B10000000000000000000000000000000000003F +:10B11000000000000000000000000000000000002F +:10B12000000000000000000000000000000000001F +:10B13000000000000000000000000000000000000F +:10B1400000000000000000000000000000000000FF +:10B1500000000000000000000000000000000000EF +:10B1600000000000000000000000000000000000DF +:10B1700000000000000000000000000000000000CF +:10B1800000000000000000000000000000000000BF +:10B1900000000000000000000000000000000000AF +:10B1A000000000000000000000000000000000009F +:10B1B000000000000000000000000000000000008F +:10B1C000000000000000000000000000000000007F +:10B1D000000000000000000000000000000000006F +:10B1E000000000000000000000000000000000005F +:10B1F000000000000000000000000000000000004F +:10B20000000000000000000000000000000000003E +:10B21000000000000000000000000000000000002E +:10B22000000000000000000000000000000000001E +:10B23000000000000000000000000000000000000E +:10B2400000000000000000000000000000000000FE +:10B2500000000000000000000000000000000000EE +:10B2600000000000000000000000000000000000DE +:10B2700000000000000000000000000000000000CE +:10B2800000000000000000000000000000000000BE +:10B2900000000000000000000000000000000000AE +:10B2A000000000000000000000000000000000009E +:10B2B000000000000000000000000000000000008E +:10B2C000000000000000000000000000000000007E +:10B2D000000000000000000000000000000000006E +:10B2E000000000000000000000000000000000005E +:10B2F000000000000000000000000000000000004E +:10B30000000000000000000000000000000000003D +:10B31000000000000000000000000000000000002D +:10B32000000000000000000000000000000000001D +:10B33000000000000000000000000000000000000D +:10B3400000000000000000000000000000000000FD +:10B3500000000000000000000000000000000000ED +:10B3600000000000000000000000000000000000DD +:10B3700000000000000000000000000000000000CD +:10B3800000000000000000000000000000000000BD +:10B3900000000000000000000000000000000000AD +:10B3A000000000000000000000000000000000009D +:10B3B000000000000000000000000000000000008D +:10B3C000000000000000000000000000000000007D +:10B3D000000000000000000000000000000000006D +:10B3E000000000000000000000000000000000005D +:10B3F000000000000000000000000000000000004D +:10B40000000000000000000000000000000000003C +:10B41000000000000000000000000000000000002C +:10B42000000000000000000000000000000000001C +:10B43000000000000000000000000000000000000C +:10B4400000000000000000000000000000000000FC +:10B4500000000000000000000000000000000000EC +:10B4600000000000000000000000000000000000DC +:10B4700000000000000000000000000000000000CC +:10B4800000000000000000000000000000000000BC +:10B4900000000000000000000000000000000000AC +:10B4A000000000000000000000000000000000009C +:10B4B000000000000000000000000000000000008C +:10B4C000000000000000000000000000000000007C +:10B4D000000000000000000000000000000000006C +:10B4E000000000000000000000000000000000005C +:10B4F000000000000000000000000000000000004C +:10B50000000000000000000000000000000000003B +:10B51000000000000000000000000000000000002B +:10B52000000000000000000000000000000000001B +:10B53000000000000000000000000000000000000B +:10B5400000000000000000000000000000000000FB +:10B5500000000000000000000000000000000000EB +:10B5600000000000000000000000000000000000DB +:10B5700000000000000000000000000000000000CB +:10B5800000000000000000000000000000000000BB +:10B5900000000000000000000000000000000000AB +:10B5A000000000000000000000000000000000009B +:10B5B000000000000000000000000000000000008B +:10B5C000000000000000000000000000000000007B +:10B5D000000000000000000000000000000000006B +:10B5E000000000000000000000000000000000005B +:10B5F000000000000000000000000000000000004B +:10B60000000000000000000000000000000000003A +:10B61000000000000000000000000000000000002A +:10B62000000000000000000000000000000000001A +:10B63000000000000000000000000000000000000A +:10B6400000000000000000000000000000000000FA +:10B6500000000000000000000000000000000000EA +:10B6600000000000000000000000000000000000DA +:10B6700000000000000000000000000000000000CA +:10B6800000000000000000000000000000000000BA +:10B6900000000000000000000000000000000000AA +:10B6A000000000000000000000000000000000009A +:10B6B000000000000000000000000000000000008A +:10B6C000000000000000000000000000000000007A +:10B6D000000000000000000000000000000000006A +:10B6E000000000000000000000000000000000005A +:10B6F000000000000000000000000000000000004A +:10B700000000000000000000000000000000000039 +:10B710000000000000000000000000000000000029 +:10B720000000000000000000000000000000000019 +:10B730000000000000000000000000000000000009 +:10B7400000000000000000000000000000000000F9 +:10B7500000000000000000000000000000000000E9 +:10B7600000000000000000000000000000000000D9 +:10B7700000000000000000000000000000000000C9 +:10B7800000000000000000000000000000000000B9 +:10B7900000000000000000000000000000000000A9 +:10B7A0000000000000000000000000000000000099 +:10B7B0000000000000000000000000000000000089 +:10B7C0000000000000000000000000000000000079 +:10B7D0000000000000000000000000000000000069 +:10B7E0000000000000000000000000000000000059 +:10B7F0000000000000000000000000000000000049 +:10B800000000000000000000000000000000000038 +:10B810000000000000000000000000000000000028 +:10B820000000000000000000000000000000000018 +:10B830000000000000000000000000000000000008 +:10B8400000000000000000000000000000000000F8 +:10B8500000000000000000000000000000000000E8 +:10B8600000000000000000000000000000000000D8 +:10B8700000000000000000000000000000000000C8 +:10B8800000000000000000000000000000000000B8 +:10B8900000000000000000000000000000000000A8 +:10B8A0000000000000000000000000000000000098 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B900000000000000000000000000000000000037 +:10B910000000000000000000000000000000000027 +:10B920000000000000000000000000000000000017 +:10B930000000000000000000000000000000000007 +:10B9400000000000000000000000000000000000F7 +:10B9500000000000000000000000000000000000E7 +:10B9600000000000000000000000000000000000D7 +:10B9700000000000000000000000000000000000C7 +:10B9800000000000000000000000000000000000B7 +:10B9900000000000000000000000000000000000A7 +:10B9A0000000000000000000000000000000000097 +:10B9B0000000000000000000000000000000000087 +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000000000000B6 +:10BA900000000000000000000000000000000000A6 +:10BAA0000000000000000000000000000000000096 +:10BAB0000000000000000000000000000000000086 +:10BAC0000000000000000000000000000000000076 +:10BAD0000000000000000000000000000000000066 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000000000F5 +:10BB500000000000000000000000000000000000E5 +:10BB600000000000000000000000000000000000D5 +:10BB700000000000000000000000000000000000C5 +:10BB800000000000000000000000000000000000B5 +:10BB900000000000000000000000000000000000A5 +:10BBA0000000000000000000000000000000000095 +:10BBB0000000000000000000000000000000000085 +:10BBC0000000000000000000000000000000000075 +:10BBD0000000000000000000000000000000000065 +:10BBE0000000000000000000000000000000000055 +:10BBF0000000000000000000000000000000000045 +:10BC00000000000000000000000000000000000034 +:10BC10000000000000000000000000000000000024 +:10BC20000000000000000000000000000000000014 +:10BC30000000000000000000000000000000000004 +:10BC400000000000000000000000000000000000F4 +:10BC500000000000000000000000000000000000E4 +:10BC600000000000000000000000000000000000D4 +:10BC700000000000000000000000000000000000C4 +:10BC800000000000000000000000000000000000B4 +:10BC900000000000000000000000000000000000A4 +:10BCA0000000000000000000000000000000000094 +:10BCB0000000000000000000000000000000000084 +:10BCC0000000000000000000000000000000000074 +:10BCD0000000000000000000000000000000000064 +:10BCE0000000000000000000000000000000000054 +:10BCF0000000000000000000000000000000000044 +:10BD00000000000000000000000000000000000033 +:10BD10000000000000000000000000000000000023 +:10BD20000000000000000000000000000000000013 +:10BD30000000000000000000000000000000000003 +:10BD400000000000000000000000000000000000F3 +:10BD500000000000000000000000000000000000E3 +:10BD600000000000000000000000000000000000D3 +:10BD700000000000000000000000000000000000C3 +:10BD800000000000000000000000000000000000B3 +:10BD900000000000000000000000000000000000A3 +:10BDA0000000000000000000000000000000000093 +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:10BDD0000000000000000000000000000000000063 +:10BDE0000000000000000000000000000000000053 +:10BDF0000000000000000000000000000000000043 +:10BE00000000000000000000000000000000000032 +:10BE10000000000000000000000000000000000022 +:10BE20000000000000000000000000000000000012 +:10BE30000000000000000000000000000000000002 +:10BE400000000000000000000000000000000000F2 +:10BE500000000000000000000000000000000000E2 +:10BE600000000000000000000000000000000000D2 +:10BE700000000000000000000000000000000000C2 +:10BE800000000000000000000000000000000000B2 +:10BE900000000000000000000000000000000000A2 +:10BEA0000000000000000000000000000000000092 +:10BEB0000000000000000000000000000000000082 +:10BEC0000000000000000000000000000000000072 +:10BED0000000000000000000000000000000000062 +:10BEE0000000000000000000000000000000000052 +:10BEF0000000000000000000000000000000000042 +:10BF00000000000000000000000000000000000031 +:10BF10000000000000000000000000000000000021 +:10BF20000000000000000000000000000000000011 +:10BF30000000000000000000000000000000000001 +:10BF400000000000000000000000000000000000F1 +:10BF500000000000000000000000000000000000E1 +:10BF600000000000000000000000000000000000D1 +:10BF700000000000000000000000000000000000C1 +:10BF800000000000000000000000000000000000B1 +:10BF900000000000000000000000000000000000A1 +:10BFA0000000000000000000000000000000000091 +:10BFB0000000000000000000000000000000000081 +:10BFC0000000000000000000000000000000000071 +:10BFD0000000000000000000000000000000000061 +:10BFE0000000000000000000000000000000000051 +:10BFF0000000000000000000000000000000000041 +:10C000000000000000000000000000000000000030 +:10C010000000000000000000000000000000000020 +:10C020000000000000000000000000000000000010 +:10C030000000000000000000000000000000000000 +:10C0400000000000000000000000000000000000F0 +:10C0500000000000000000000000000000000000E0 +:10C0600000000000000000000000000000000000D0 +:10C0700000000000000000000000000000000000C0 +:10C0800000000000000000000000000000000000B0 +:10C0900000000000000000000000000000000000A0 +:10C0A0000000000000000000000000000000000090 +:10C0B0000000000000000000000000000000000080 +:10C0C0000000000000000000000000000000000070 +:10C0D0000000000000000000000000000000000060 +:10C0E0000000000000000000000000000000000050 +:10C0F0000000000000000000000000000000000040 +:10C10000000000000000000000000000000000002F +:10C11000000000000000000000000000000000001F +:10C12000000000000000000000000000000000000F +:10C1300000000000000000000000000000000000FF +:10C1400000000000000000000000000000000000EF +:10C1500000000000000000000000000000000000DF +:10C1600000000000000000000000000000000000CF +:10C1700000000000000000000000000000000000BF +:10C1800000000000000000000000000000000000AF +:10C19000000000000000000000000000000000009F +:10C1A000000000000000000000000000000000008F +:10C1B000000000000000000000000000000000007F +:10C1C000000000000000000000000000000000006F +:10C1D000000000000000000000000000000000005F +:10C1E000000000000000000000000000000000004F +:10C1F000000000000000000000000000000000003F +:10C20000000000000000000000000000000000002E +:10C21000000000000000000000000000000000001E +:10C22000000000000000000000000000000000000E +:10C2300000000000000000000000000000000000FE +:10C2400000000000000000000000000000000000EE +:10C2500000000000000000000000000000000000DE +:10C2600000000000000000000000000000000000CE +:10C2700000000000000000000000000000000000BE +:10C2800000000000000000000000000000000000AE +:10C29000000000000000000000000000000000009E +:10C2A000000000000000000000000000000000008E +:10C2B000000000000000000000000000000000007E +:10C2C000000000000000000000000000000000006E +:10C2D000000000000000000000000000000000005E +:10C2E000000000000000000000000000000000004E +:10C2F000000000000000000000000000000000003E +:10C30000000000000000000000000000000000002D +:10C31000000000000000000000000000000000001D +:10C32000000000000000000000000000000000000D +:10C3300000000000000000000000000000000000FD +:10C3400000000000000000000000000000000000ED +:10C3500000000000000000000000000000000000DD +:10C3600000000000000000000000000000000000CD +:10C3700000000000000000000000000000000000BD +:10C3800000000000000000000000000000000000AD +:10C39000000000000000000000000000000000009D +:10C3A000000000000000000000000000000000008D +:10C3B000000000000000000000000000000000007D +:10C3C000000000000000000000000000000000006D +:10C3D000000000000000000000000000000000005D +:10C3E000000000000000000000000000000000004D +:10C3F000000000000000000000000000000000003D +:10C40000000000000000000000000000000000002C +:10C41000000000000000000000000000000000001C +:10C42000000000000000000000000000000000000C +:10C4300000000000000000000000000000000000FC +:10C4400000000000000000000000000000000000EC +:10C4500000000000000000000000000000000000DC +:10C4600000000000000000000000000000000000CC +:10C4700000000000000000000000000000000000BC +:10C4800000000000000000000000000000000000AC +:10C49000000000000000000000000000000000009C +:10C4A000000000000000000000000000000000008C +:10C4B000000000000000000000000000000000007C +:10C4C000000000000000000000000000000000006C +:10C4D000000000000000000000000000000000005C +:10C4E000000000000000000000000000000000004C +:10C4F000000000000000000000000000000000003C +:10C50000000000000000000000000000000000002B +:10C51000000000000000000000000000000000001B +:10C52000000000000000000000000000000000000B +:10C5300000000000000000000000000000000000FB +:10C5400000000000000000000000000000000000EB +:10C5500000000000000000000000000000000000DB +:10C5600000000000000000000000000000000000CB +:10C5700000000000000000000000000000000000BB +:10C5800000000000000000000000000000000000AB +:10C59000000000000000000000000000000000009B +:10C5A000000000000000000000000000000000008B +:10C5B000000000000000000000000000000000007B +:10C5C000000000000000000000000000000000006B +:10C5D000000000000000000000000000000000005B +:10C5E000000000000000000000000000000000004B +:10C5F000000000000000000000000000000000003B +:10C60000000000000000000000000000000000002A +:10C61000000000000000000000000000000000001A +:10C62000000000000000000000000000000000000A +:10C6300000000000000000000000000000000000FA +:10C6400000000000000000000000000000000000EA +:10C6500000000000000000000000000000000000DA +:10C6600000000000000000000000000000000000CA +:10C6700000000000000000000000000000000000BA +:10C6800000000000000000000000000000000000AA +:10C69000000000000000000000000000000000009A +:10C6A000000000000000000000000000000000008A +:10C6B000000000000000000000000000000000007A +:10C6C000000000000000000000000000000000006A +:10C6D000000000000000000000000000000000005A +:10C6E000000000000000000000000000000000004A +:10C6F000000000000000000000000000000000003A +:10C700000000000000000000000000000000000029 +:10C710000000000000000000000000000000000019 +:10C720000000000000000000000000000000000009 +:10C7300000000000000000000000000000000000F9 +:10C7400000000000000000000000000000000000E9 +:10C7500000000000000000000000000000000000D9 +:10C7600000000000000000000000000000000000C9 +:10C7700000000000000000000000000000000000B9 +:10C7800000000000000000000000000000000000A9 +:10C790000000000000000000000000000000000099 +:10C7A0000000000000000000000000000000000089 +:10C7B0000000000000000000000000000000000079 +:10C7C0000000000000000000000000000000000069 +:10C7D0000000000000000000000000000000000059 +:10C7E0000000000000000000000000000000000049 +:10C7F0000000000000000000000000000000000039 +:10C800000000000000000000000000000000000028 +:10C810000000000000000000000000000000000018 +:10C820000000000000000000000000000000000008 +:10C8300000000000000000000000000000000000F8 +:10C8400000000000000000000000000000000000E8 +:10C8500000000000000000000000000000000000D8 +:10C8600000000000000000000000000000000000C8 +:10C8700000000000000000000000000000000000B8 +:10C8800000000000000000000000000000000000A8 +:10C890000000000000000000000000000000000098 +:10C8A0000000000000000000000000000000000088 +:10C8B0000000000000000000000000000000000078 +:10C8C0000000000000000000000000000000000068 +:10C8D0000000000000000000000000000000000058 +:10C8E0000000000000000000000000000000000048 +:10C8F0000000000000000000000000000000000038 +:10C900000000000000000000000000000000000027 +:10C910000000000000000000000000000000000017 +:10C920000000000000000000000000000000000007 +:10C9300000000000000000000000000000000000F7 +:10C9400000000000000000000000000000000000E7 +:10C9500000000000000000000000000000000000D7 +:10C9600000000000000000000000000000000000C7 +:10C9700000000000000000000000000000000000B7 +:10C9800000000000000000000000000000000000A7 +:10C990000000000000000000000000000000000097 +:10C9A0000000000000000000000000000000000087 +:10C9B0000000000000000000000000000000000077 +:10C9C0000000000000000000000000000000000067 +:10C9D0000000000000000000000000000000000057 +:10C9E0000000000000000000000000000000000047 +:10C9F0000000000000000000000000000000000037 +:10CA00000000000000000000000000000000000026 +:10CA10000000000000000000000000000000000016 +:10CA20000000000000000000000000000000000006 +:10CA300000000000000000000000000000000000F6 +:10CA400000000000000000000000000000000000E6 +:10CA500000000000000000000000000000000000D6 +:10CA600000000000000000000000000000000000C6 +:10CA700000000000000000000000000000000000B6 +:10CA800000000000000000000000000000000000A6 +:10CA90000000000000000000000000000000000096 +:10CAA0000000000000000000000000000000000086 +:10CAB0000000000000000000000000000000000076 +:10CAC0000000000000000000000000000000000066 +:10CAD0000000000000000000000000000000000056 +:10CAE0000000000000000000000000000000000046 +:10CAF0000000000000000000000000000000000036 +:10CB00000000000000000000000000000000000025 +:10CB10000000000000000000000000000000000015 +:10CB20000000000000000000000000000000000005 +:10CB300000000000000000000000000000000000F5 +:10CB400000000000000000000000000000000000E5 +:10CB500000000000000000000000000000000000D5 +:10CB600000000000000000000000000000000000C5 +:10CB700000000000000000000000000000000000B5 +:10CB800000000000000000000000000000000000A5 +:10CB90000000000000000000000000000000000095 +:10CBA0000000000000000000000000000000000085 +:10CBB0000000000000000000000000000000000075 +:10CBC0000000000000000000000000000000000065 +:10CBD0000000000000000000000000000000000055 +:10CBE0000000000000000000000000000000000045 +:10CBF0000000000000000000000000000000000035 +:10CC00000000000000000000000000000000000024 +:10CC10000000000000000000000000000000000014 +:10CC20000000000000000000000000000000000004 +:10CC300000000000000000000000000000000000F4 +:10CC400000000000000000000000000000000000E4 +:10CC500000000000000000000000000000000000D4 +:10CC600000000000000000000000000000000000C4 +:10CC700000000000000000000000000000000000B4 +:10CC800000000000000000000000000000000000A4 +:10CC90000000000000000000000000000000000094 +:10CCA0000000000000000000000000000000000084 +:10CCB0000000000000000000000000000000000074 +:10CCC0000000000000000000000000000000000064 +:10CCD0000000000000000000000000000000000054 +:10CCE0000000000000000000000000000000000044 +:10CCF0000000000000000000000000000000000034 +:10CD00000000000000000000000000000000000023 +:10CD10000000000000000000000000000000000013 +:10CD20000000000000000000000000000000000003 +:10CD300000000000000000000000000000000000F3 +:10CD400000000000000000000000000000000000E3 +:10CD500000000000000000000000000000000000D3 +:10CD600000000000000000000000000000000000C3 +:10CD700000000000000000000000000000000000B3 +:10CD800000000000000000000000000000000000A3 +:10CD90000000000000000000000000000000000093 +:10CDA0000000000000000000000000000000000083 +:10CDB0000000000000000000000000000000000073 +:10CDC0000000000000000000000000000000000063 +:10CDD0000000000000000000000000000000000053 +:10CDE0000000000000000000000000000000000043 +:10CDF0000000000000000000000000000000000033 +:10CE00000000000000000000000000000000000022 +:10CE10000000000000000000000000000000000012 +:10CE20000000000000000000000000000000000002 +:10CE300000000000000000000000000000000000F2 +:10CE400000000000000000000000000000000000E2 +:10CE500000000000000000000000000000000000D2 +:10CE600000000000000000000000000000000000C2 +:10CE700000000000000000000000000000000000B2 +:10CE800000000000000000000000000000000000A2 +:10CE90000000000000000000000000000000000092 +:10CEA0000000000000000000000000000000000082 +:10CEB0000000000000000000000000000000000072 +:10CEC0000000000000000000000000000000000062 +:10CED0000000000000000000000000000000000052 +:10CEE0000000000000000000000000000000000042 +:10CEF0000000000000000000000000000000000032 +:10CF00000000000000000000000000000000000021 +:10CF10000000000000000000000000000000000011 +:10CF20000000000000000000000000000000000001 +:10CF300000000000000000000000000000000000F1 +:10CF400000000000000000000000000000000000E1 +:10CF500000000000000000000000000000000000D1 +:10CF600000000000000000000000000000000000C1 +:10CF700000000000000000000000000000000000B1 +:10CF800000000000000000000000000000000000A1 +:10CF90000000000000000000000000000000000091 +:10CFA0000000000000000000000000000000000081 +:10CFB0000000000000000000000000000000000071 +:10CFC0000000000000000000000000000000000061 +:10CFD0000000000000000000000000000000000051 +:10CFE0000000000000000000000000000000000041 +:10CFF0000000000000000000000000000000000031 +:10D000000000000000000000000000000000000020 +:10D010000000000000000000000000000000000010 +:10D020000000000000000000000000000000000000 +:10D0300000000000000000000000000000000000F0 +:10D0400000000000000000000000000000000000E0 +:10D0500000000000000000000000000000000000D0 +:10D0600000000000000000000000000000000000C0 +:10D0700000000000000000000000000000000000B0 +:10D0800000000000000000000000000000000000A0 +:10D090000000000000000000000000000000000090 +:10D0A0000000000000000000000000000000000080 +:10D0B0000000000000000000000000000000000070 +:10D0C0000000000000000000000000000000000060 +:10D0D0000000000000000000000000000000000050 +:10D0E0000000000000000000000000000000000040 +:10D0F0000000000000000000000000000000000030 +:10D10000000000000000000000000000000000001F +:10D11000000000000000000000000000000000000F +:10D1200000000000000000000000000000000000FF +:10D1300000000000000000000000000000000000EF +:10D1400000000000000000000000000000000000DF +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000000000000000000000000000000000006D +:10D3C000000000000000000000000000000000005D +:10D3D000000000000000000000000000000000004D +:10D3E000000000000000000000000000000000003D +:10D3F000000000000000000000000000000000002D +:10D40000000000000000000000000000000000001C +:10D41000000000000000000000000000000000000C +:10D4200000000000000000000000000000000000FC +:10D4300000000000000000000000000000000000EC +:10D4400000000000000000000000000000000000DC +:10D4500000000000000000000000000000000000CC +:10D4600000000000000000000000000000000000BC +:10D4700000000000000000000000000000000000AC +:10D48000000000000000000000000000000000009C +:10D49000000000000000000000000000000000008C +:10D4A000000000000000000000000000000000007C +:10D4B000000000000000000000000000000000006C +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D5400000000000000000000000000000000000DB +:10D5500000000000000000000000000000000000CB +:10D5600000000000000000000000000000000000BB +:10D5700000000000000000000000000000000000AB +:10D58000000000000000000000000000000000009B +:10D59000000000000000000000000000000000008B +:10D5A000000000000000000000000000000000007B +:10D5B000000000000000000000000000000000006B +:10D5C000000000000000000000000000000000005B +:10D5D000000000000000000000000000000000004B +:10D5E000000000000000000000000000000000003B +:10D5F000000000000000000000000000000000002B +:10D60000000000000000000000000000000000001A +:10D61000000000000000000000000000000000000A +:10D6200000000000000000000000000000000000FA +:10D6300000000000000000000000000000000000EA +:10D6400000000000000000000000000000000000DA +:10D6500000000000000000000000000000000000CA +:10D6600000000000000000000000000000000000BA +:10D6700000000000000000000000000000000000AA +:10D68000000000000000000000000000000000009A +:10D69000000000000000000000000000000000008A +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000000009 +:10D7200000000000000000000000000000000000F9 +:10D7300000000000000000000000000000000000E9 +:10D7400000000000000000000000000000000000D9 +:10D7500000000000000000000000000000000000C9 +:10D7600000000000000000000000000000000000B9 +:10D7700000000000000000000000000000000000A9 +:10D780000000000000000000000000000000000099 +:10D790000000000000000000000000000000000089 +:10D7A0000000000000000000000000000000000079 +:10D7B0000000000000000000000000000000000069 +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F0000000000000000000000000000000000029 +:10D800000000000000000000000000000000000018 +:10D810000000000000000000000000000000000008 +:10D8200000000000000000000000000000000000F8 +:10D8300000000000000000000000000000000000E8 +:10D8400000000000000000000000000000000000D8 +:10D8500000000000000000000000000000000000C8 +:10D8600000000000000000000000000000000000B8 +:10D8700000000000000000000000000000000000A8 +:10D880000000000000000000000000000000000098 +:10D890000000000000000000000000000000000088 +:10D8A0000000000000000000000000000000000078 +:10D8B0000000000000000000000000000000000068 +:10D8C0000000000000000000000000000000000058 +:10D8D0000000000000000000000000000000000048 +:10D8E0000000000000000000000000000000000038 +:10D8F0000000000000000000000000000000000028 +:10D900000000000000000000000000000000000017 +:10D910000000000000000000000000000000000007 +:10D9200000000000000000000000000000000000F7 +:10D9300000000000000000000000000000000000E7 +:10D9400000000000000000000000000000000000D7 +:10D9500000000000000000000000000000000000C7 +:10D9600000000000000000000000000000000000B7 +:10D9700000000000000000000000000000000000A7 +:10D980000000000000000000000000000000000097 +:10D990000000000000000000000000000000000087 +:10D9A0000000000000000000000000000000000077 +:10D9B0000000000000000000000000000000000067 +:10D9C0000000000000000000000000000000000057 +:10D9D0000000000000000000000000000000000047 +:10D9E0000000000000000000000000000000000037 +:10D9F0000000000000000000000000000000000027 +:10DA00000000000000000000000000000000000016 +:10DA10000000000000000000000000000000000006 +:10DA200000000000000000000000000000000000F6 +:10DA300000000000000000000000000000000000E6 +:10DA400000000000000000000000000000000000D6 +:10DA500000000000000000000000000000000000C6 +:10DA600000000000000000000000000000000000B6 +:10DA700000000000000000000000000000000000A6 +:10DA80000000000000000000000000000000000096 +:10DA90000000000000000000000000000000000086 +:10DAA0000000000000000000000000000000000076 +:10DAB0000000000000000000000000000000000066 +:10DAC0000000000000000000000000000000000056 +:10DAD0000000000000000000000000000000000046 +:10DAE0000000000000000000000000000000000036 +:10DAF0000000000000000000000000000000000026 +:10DB00000000000000000000000000000000000015 +:10DB10000000000000000000000000000000000005 +:10DB200000000000000000000000000000000000F5 +:10DB300000000000000000000000000000000000E5 +:10DB400000000000000000000000000000000000D5 +:10DB500000000000000000000000000000000000C5 +:10DB600000000000000000000000000000000000B5 +:10DB700000000000000000000000000000000000A5 +:10DB80000000000000000000000000000000000095 +:10DB90000000000000000000000000000000000085 +:10DBA0000000000000000000000000000000000075 +:10DBB0000000000000000000000000000000000065 +:10DBC0000000000000000000000000000000000055 +:10DBD0000000000000000000000000000000000045 +:10DBE0000000000000000000000000000000000035 +:10DBF0000000000000000000000000000000000025 +:10DC00000000000000000000000000000000000014 +:10DC10000000000000000000000000000000000004 +:10DC200000000000000000000000000000000000F4 +:10DC300000000000000000000000000000000000E4 +:10DC400000000000000000000000000000000000D4 +:10DC500000000000000000000000000000000000C4 +:10DC600000000000000000000000000000000000B4 +:10DC700000000000000000000000000000000000A4 +:10DC80000000000000000000000000000000000094 +:10DC90000000000000000000000000000000000084 +:10DCA0000000000000000000000000000000000074 +:10DCB0000000000000000000000000000000000064 +:10DCC0000000000000000000000000000000000054 +:10DCD0000000000000000000000000000000000044 +:10DCE0000000000000000000000000000000000034 +:10DCF0000000000000000000000000000000000024 +:10DD00000000000000000000000000000000000013 +:10DD10000000000000000000000000000000000003 +:10DD200000000000000000000000000000000000F3 +:10DD300000000000000000000000000000000000E3 +:10DD400000000000000000000000000000000000D3 +:10DD500000000000000000000000000000000000C3 +:10DD600000000000000000000000000000000000B3 +:10DD700000000000000000000000000000000000A3 +:10DD80000000000000000000000000000000000093 +:10DD90000000000000000000000000000000000083 +:10DDA0000000000000000000000000000000000073 +:10DDB0000000000000000000000000000000000063 +:10DDC0000000000000000000000000000000000053 +:10DDD0000000000000000000000000000000000043 +:10DDE0000000000000000000000000000000000033 +:10DDF0000000000000000000000000000000000023 +:10DE00000000000000000000000000000000000012 +:10DE10000000000000000000000000000000000002 +:10DE200000000000000000000000000000000000F2 +:10DE300000000000000000000000000000000000E2 +:10DE400000000000000000000000000000000000D2 +:10DE500000000000000000000000000000000000C2 +:10DE600000000000000000000000000000000000B2 +:10DE700000000000000000000000000000000000A2 +:10DE80000000000000000000000000000000000092 +:10DE90000000000000000000000000000000000082 +:10DEA0000000000000000000000000000000000072 +:10DEB0000000000000000000000000000000000062 +:10DEC0000000000000000000000000000000000052 +:10DED0000000000000000000000000000000000042 +:10DEE0000000000000000000000000000000000032 +:10DEF0000000000000000000000000000000000022 +:10DF00000000000000000000000000000000000011 +:10DF10000000000000000000000000000000000001 +:10DF200000000000000000000000000000000000F1 +:10DF300000000000000000000000000000000000E1 +:10DF400000000000000000000000000000000000D1 +:10DF500000000000000000000000000000000000C1 +:10DF600000000000000000000000000000000000B1 +:10DF700000000000000000000000000000000000A1 +:10DF80000000000000000000000000000000000091 +:10DF90000000000000000000000000000000000081 +:10DFA0000000000000000000000000000000000071 +:10DFB0000000000000000000000000000000000061 +:10DFC0000000000000000000000000000000000051 +:10DFD0000000000000000000000000000000000041 +:10DFE0000000000000000000000000000000000031 +:10DFF0000000000000000000000000000000000021 +:10E000000000000000000000000000000000000010 +:10E010000000000000000000000000000000000000 +:10E0200000000000000000000000000000000000F0 +:10E0300000000000000000000000000000000000E0 +:10E0400000000000000000000000000000000000D0 +:10E0500000000000000000000000000000000000C0 +:10E0600000000000000000000000000000000000B0 +:10E0700000000000000000000000000000000000A0 +:10E080000000000000000000000000000000000090 +:10E090000000000000000000000000000000000080 +:10E0A0000000000000000000000000000000000070 +:10E0B0000000000000000000000000000000000060 +:10E0C0000000000000000000000000000000000050 +:10E0D0000000000000000000000000000000000040 +:10E0E0000000000000000000000000000000000030 +:10E0F0000000000000000000000000000000000020 +:10E10000000000000000000000000000000000000F +:10E1100000000000000000000000000000000000FF +:10E1200000000000000000000000000000000000EF +:10E1300000000000000000000000000000000000DF +:10E1400000000000000000000000000000000000CF +:10E1500000000000000000000000000000000000BF +:10E1600000000000000000000000000000000000AF +:10E17000000000000000000000000000000000009F +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000809F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E220000000000A000000000000000000000000E4 +:10E2300010000003000000000000000D0000000DB1 +:10E240003C020801244295A03C030801246397DCAA +:10E25000AC4000000043202B1480FFFD244200044A +:10E260003C1D080037BD9FFC03A0F0213C100800B6 +:10E27000261032103C1C0801279C95A00E0012BEEF +:10E28000000000000000000D3C02800030A5FFFFF0 +:10E2900030C600FF344301803C0880008D0901B87E +:10E2A0000520FFFE00000000AC6400002404000212 +:10E2B000A4650008A066000AA064000BAC67001803 +:10E2C0003C03100003E00008AD0301B83C0560000A +:10E2D0008CA24FF80440FFFE00000000ACA44FC029 +:10E2E0003C0310003C040200ACA44FC403E000084F +:10E2F000ACA34FF89486000C00A050212488001491 +:10E3000000062B0200051080004448210109182B4B +:10E310001060001100000000910300002C6400094F +:10E320005080000991190001000360803C0D080134 +:10E3300025AD9234018D58218D67000000E0000862 +:10E340000000000091190001011940210109302B42 +:10E3500054C0FFF29103000003E000080000102108 +:10E360000A000CCC25080001910F0001240E000AC0 +:10E3700015EE00400128C8232F38000A1700003D81 +:10E38000250D00028D580000250F0006370E0100F4 +:10E39000AD4E0000910C000291AB000191A400026F +:10E3A00091A60003000C2E00000B3C0000A71025D6 +:10E3B00000041A000043C8250326C025AD580004F8 +:10E3C000910E000691ED000191E7000291E5000336 +:10E3D000000E5E00000D6400016C30250007220075 +:10E3E00000C41025004518252508000A0A000CCC99 +:10E3F000AD430008910F000125040002240800022B +:10E4000055E80001012020210A000CCC00804021A9 +:10E41000910C0001240B0003158B00160000000076 +:10E420008D580000910E000225080003370D0008EA +:10E43000A14E00100A000CCCAD4D00009119000156 +:10E44000240F0004172F000B0000000091070002AA +:10E45000910400038D43000000072A0000A410254A +:10E460003466000425080004AD42000C0A000CCC00 +:10E47000AD46000003E000082402000127BDFFE8CC +:10E48000AFBF0014AFB000100E00164E0080802108 +:10E490003C0480083485008090A600052403FFFE1C +:10E4A0000200202100C310248FBF00148FB0001081 +:10E4B000A0A200050A00165827BD001827BDFFE8D6 +:10E4C000AFB00010AFBF00140E000FD40080802149 +:10E4D0003C06800834C5008090A40000240200504F +:10E4E000308300FF106200073C09800002002021F9 +:10E4F0008FBF00148FB00010AD2001800A00108F74 +:10E5000027BD0018240801003C07800002002021DC +:10E510008FBF00148FB00010ACE801800A00108F8C +:10E5200027BD001827BDFF783C058008AFBE0080DE +:10E53000AFB7007CAFB3006CAFB10064AFBF008475 +:10E54000AFB60078AFB50074AFB40070AFB200687A +:10E55000AFB0006034A600803C0580008CB201287A +:10E5600090C400098CA701043C020001309100FF17 +:10E5700000E218240000B8210000F021106000071C +:10E58000000098213C0908008D2931F02413000176 +:10E59000252800013C010800AC2831F0ACA0008423 +:10E5A00090CC0005000C5827316A0001154000721C +:10E5B000AFA0005090CD00002406002031A400FF41 +:10E5C00010860018240E0050108E009300000000EA +:10E5D0003C1008008E1000DC260F00013C010800F2 +:10E5E000AC2F00DC0E0016C7000000000040182110 +:10E5F0008FBF00848FBE00808FB7007C8FB60078FD +:10E600008FB500748FB400708FB3006C8FB2006848 +:10E610008FB100648FB000600060102103E000083B +:10E6200027BD00880000000D3C1F8000AFA0003017 +:10E6300097E501168FE201043C04002030B9FFFF8A +:10E64000004438240007182B00033140AFA60030E7 +:10E650008FF5010437F80C003C1600400338802188 +:10E6600002B6A02434C40040128000479215000D69 +:10E6700032A800201500000234860080008030217E +:10E6800014C0009FAFA600303C0D800835A6008066 +:10E6900090CC0008318B0040516000063C06800899 +:10E6A000240E0004122E00A8240F0012122F003294 +:10E6B0003C06800834C401003C0280009447011AE3 +:10E6C0009619000E909F00088E18000830E3FFFF97 +:10E6D00003F9B00432B40004AFB6005CAFA3005835 +:10E6E0008E1600041280002EAFB8005434C3008090 +:10E6F000906800083105004014A0002500000000CB +:10E700008C70005002D090230640000500000000ED +:10E710008C71003402D1A82306A201678EE20008A2 +:10E72000126000063C1280003C1508008EB531F4E2 +:10E7300026B600013C010800AC3631F4AE4000447E +:10E74000240300018FBF00848FBE00808FB7007C40 +:10E750008FB600788FB500748FB400708FB3006CE3 +:10E760008FB200688FB100648FB00060006010212C +:10E7700003E0000827BD00880E000D2800002021BE +:10E780000A000D75004018210A000D9500C02021D7 +:10E790000E00171702C020211440FFE10000000006 +:10E7A0003C0B8008356400808C8A003402CA482300 +:10E7B0000520001D000000003C1E08008FDE310017 +:10E7C00027D700013C010800AC3731001260000679 +:10E7D000024020213C1408008E9431F42690000160 +:10E7E0003C010800AC3031F40E00164E3C1E80088F +:10E7F00037CD008091B700250240202136EE00047D +:10E800000E001658A1AE00250E000CAC02402021CF +:10E810000A000DCA240300013C17080126F796A040 +:10E820000A000D843C1F80008C86003002C66023E5 +:10E830001980000C2419000C908F004F3C14080024 +:10E840008E94310032B500FC35ED0001268E0001BA +:10E850003C010800AC2E3100A08D004FAFA0005845 +:10E860002419000CAFB900308C9800300316A02397 +:10E870001A80010B8FA300580074F82A17E0FFD309 +:10E88000000000001074002A8FA5005802D4B021A7 +:10E8900000B410233044FFFFAFA4005832A8000298 +:10E8A0001100002E32AB00103C15800836B00080FD +:10E8B0009216000832D30040526000FB8EE200083E +:10E8C0000E00164E02402021240A0018A20A000958 +:10E8D000921100052409FFFE024020210229902404 +:10E8E0000E001658A2120005240400390000282149 +:10E8F0000E0016F2240600180A000DCA24030001B7 +:10E9000092FE000C3C0A800835490080001EBB00C6 +:10E910008D27003836F10081024020213225F08118 +:10E920000E000C9B30C600FF0A000DC10000000065 +:10E930003AA7000130E300011460FFA402D4B02123 +:10E940000A000E1D00000000024020210E001734B6 +:10E95000020028210A000D75004018211160FF7087 +:10E960003C0F80083C0D800835EE00808DC40038D7 +:10E970008FA300548DA60004006660231D80FF68ED +:10E98000000000000064C02307020001AFA400548F +:10E990003C1F08008FFF31E433F9000113200015FC +:10E9A0008FAC00583C07800094E3011A10600012FD +:10E9B0003C0680080E002161024020213C03080132 +:10E9C000906396D13064000214800145000000007D +:10E9D000306C0004118000078FAC0058306600FBDB +:10E9E0003C010801A02696D132B500FCAFA000582A +:10E9F0008FAC00583C06800834D30080AFB40018B8 +:10EA0000AFB60010AFAC00143C088000950B01209D +:10EA10008E6F0030966A005C8FA3005C8FBF003061 +:10EA20003169FFFF3144FFFF8FAE005401341021E4 +:10EA3000350540000064382B0045C82103E7C02598 +:10EA4000AFB90020AFAF0028AFB80030AFAF00249F +:10EA5000AFA0002CAFAE0034926D000831B40008B6 +:10EA6000168000BB020020218EE200040040F8095D +:10EA700027A400108FAF003031F300025660000170 +:10EA800032B500FE3C048008349F008093F90008F2 +:10EA900033380040530000138FA400248C850004F9 +:10EAA0008FA7005410A700D52404001432B0000131 +:10EAB0001200000C8FA400242414000C1234011A3C +:10EAC0002A2D000D11A001022413000E240E000AAD +:10EAD000522E0001241E00088FAF002425E40001FF +:10EAE000AFA400248FAA00143C0B80083565008079 +:10EAF000008A48218CB10030ACA9003090A4004EAF +:10EB00008CA700303408FFFF0088180400E3F821C8 +:10EB1000ACBF00348FA600308FB900548FB8005CB2 +:10EB200030C200081040000B033898218CAC002044 +:10EB3000119300D330C600FF92EE000C8FA7003473 +:10EB400002402021000E6B0035B400800E000C9BAB +:10EB50003285F0803C028008345000808E0F0030F7 +:10EB600001F1302318C00097264800803C070800B8 +:10EB70008CE731E42404FF80010418243118007F5D +:10EB80003C1F80003C19800430F10001AFE300908D +:10EB900012200006031928213C030801906396D136 +:10EBA00030690008152000C6306A00F73C10800864 +:10EBB00036040080908C004F318B000115600042BC +:10EBC000000000003C0608008CC6319830CE0010D2 +:10EBD00051C0004230F9000190AF006B55E0003F9A +:10EBE00030F9000124180001A0B8006B3C1180002E +:10EBF0009622007A24470064A48700123C0D800806 +:10EC000035A5008090B40008329000401600000442 +:10EC10003C03800832AE000115C0008B00000000EC +:10EC2000346400808C86002010D3000A3463010015 +:10EC30008C67000002C7782319E000978FBF00544B +:10EC4000AC93002024130001AC760000AFB3005059 +:10EC5000AC7F000417C0004E000000008FA90050D8 +:10EC60001520000B000000003C030801906396D1C2 +:10EC7000306A00011140002E8FAB0058306400FE56 +:10EC80003C010801A02496D10A000D75000018214E +:10EC90000E000CAC024020210A000F1300000000FF +:10ECA0000A000E200000A0210040F80924040017EB +:10ECB0000A000DCA240300010040F80924040016CC +:10ECC0000A000DCA240300019094004F240DFFFE9A +:10ECD000028D2824A085004F30F900011320000682 +:10ECE0003C0480083C030801906396D1307F0010FB +:10ECF00017E00051306800EF34900080240A0001D2 +:10ED0000024020210E00164EA60A00129203002592 +:10ED100024090001AFA90050346200010240202103 +:10ED20000E001658A20200250A000EF93C0D8008BC +:10ED30001160FE83000018218FA5003030AC000464 +:10ED40001180FE2C8FBF00840A000DCB240300012C +:10ED500027A500380E000CB6AFA000385440FF4382 +:10ED60008EE200048FB40038329001005200FF3F61 +:10ED70008EE200048FA3003C8E6E0058006E682364 +:10ED800005A3FF39AE6300580A000E948EE200041A +:10ED90000E00164E024020213C038008346800809B +:10EDA000024020210E001658A11E000903C0302188 +:10EDB000240400370E0016F2000028210A000F116B +:10EDC0008FA900508FAB00185960FF8D3C0D800853 +:10EDD0000E00164E02402021920C00252405000151 +:10EDE000AFA5005035820004024020210E001658C5 +:10EDF000A20200250A000EF93C0D800812240059D9 +:10EE00002A2300151060004D240900162408000C68 +:10EE10005628FF2732B000013C0A8008914C001BA5 +:10EE20002406FFBD241E000E01865824A14B001BA2 +:10EE30000A000EA532B000013C010801A02896D1BD +:10EE40000A000EF93C0D80088CB500308EFE0008DB +:10EE50002404001826B6000103C0F809ACB600303F +:10EE60003C030801906396D13077000116E0FF81E2 +:10EE7000306A00018FB200300A000D753243000481 +:10EE80003C1080009605011A50A0FF2B34C60010DC +:10EE90000A000EC892EE000C8C6200001456FF6D42 +:10EEA000000000008C7800048FB9005403388823D8 +:10EEB0000621FF638FBF00540A000F0E0000000000 +:10EEC0003C010801A02A96D10A000F3030F9000158 +:10EED0001633FF028FAF00240A000EB0241E00106C +:10EEE0000E00164E024020213C0B80083568008041 +:10EEF00091090025240A0001AFAA0050353300040F +:10EF0000024020210E001658A11300253C050801DF +:10EF100090A596D130A200FD3C010801A02296D117 +:10EF20000A000E6D004018212411000E53D1FEEA94 +:10EF3000241E00100A000EAF241E00165629FEDC07 +:10EF400032B000013C0A8008914C001B2406FFBD32 +:10EF5000241E001001865824A14B001B0A000EA598 +:10EF600032B000010A000EA4241E00123C038000EF +:10EF70008C6201B80440FFFE24040800AC6401B8B0 +:10EF800003E000080000000030A5FFFF30C6FFFFCF +:10EF90003C0780008CE201B80440FFFE34EA0180A7 +:10EFA000AD440000ACE400203C0480089483004899 +:10EFB0003068FFFF11000016AF88000824AB001274 +:10EFC000010B482B512000133C04800034EF01005A +:10EFD00095EE00208F890000240D001A31CCFFFF30 +:10EFE00031274000A14D000B10E000362583FFFEC5 +:10EFF0000103C02B170000348F9900048F88000490 +:10F00000A5430014350700010A001003AF87000470 +:10F010003C04800024030003348201808F890000B7 +:10F020008F870004A043000B3C088000350C018052 +:10F03000A585000EA585001A8F85000C30EB800099 +:10F04000A5890010AD850028A58600081160000F75 +:10F050008F85001435190100972A00163158FFFCDE +:10F06000270F000401E870218DCD400031A6FFFF7D +:10F0700014C000072403BFFF3C02FFFF34487FFF9A +:10F0800000E83824AF8700048F8500142403BFFFF5 +:10F090003C04800000E3582434830180A46B0026E4 +:10F0A000AC69002C10A0000300054C02A465001000 +:10F0B000A46900263C071000AC8701B803E00008F3 +:10F0C000000000008F990004240AFFFE032A382460 +:10F0D0000A001003AF87000427BDFFE88FA20028B5 +:10F0E00030A5FFFF30C6FFFFAFBF0010AF87000C99 +:10F0F000AF820014AF8000040E000FDBAF80000071 +:10F100008FBF001027BD001803E00008AF80001477 +:10F110003C06800034C4007034C701008C8A0000B3 +:10F1200090E500128F84000027BDFFF030A300FFA0 +:10F13000000318823082400010400037246500032D +:10F140000005C8800326C0218F0E4000246F0004F4 +:10F15000000F6880AFAE000001A660218D8B4000DB +:10F16000AFAB000494E900163128FFFC01063821FA +:10F170008CE64000AFA600088FA9000800003021EF +:10F18000000028213C07080024E701000A0010675E +:10F19000240800089059000024A500012CAC000CA4 +:10F1A0000079C0210018788001E770218DCD000022 +:10F1B0001180000600CD302603A5102114A8FFF50C +:10F1C00000051A005520FFF4905900003C0480000F +:10F1D000348700703C0508008CA531048CE30000E6 +:10F1E0002CA2002010400009006A38230005488046 +:10F1F0003C0B0800256B3108012B402124AA00019B +:10F20000AD0700003C010800AC2A310400C0102109 +:10F2100003E0000827BD0010308220001040000BE2 +:10F2200000055880016648218D24400024680004B0 +:10F2300000083880AFA4000000E618218C6540006B +:10F24000AFA000080A001057AFA500040000000D91 +:10F250000A0010588FA9000827BDFFE03C07800076 +:10F2600034E60100AFBF001CAFB20018AFB100140C +:10F27000AFB0001094C5000E8F87000030A4FFFFD0 +:10F280002483000430E2400010400010AF830028C7 +:10F290003C09002000E940241100000D30EC800002 +:10F2A0008F8A0004240BBFFF00EB38243543100085 +:10F2B000AF87000030F220001640000B3C1900041C +:10F2C000241FFFBF0A0010B7007F102430EC80001D +:10F2D000158000423C0E002030F220001240FFF862 +:10F2E0008F8300043C19000400F9C0241300FFF5CB +:10F2F000241FFFBF34620040AF82000430E20100EF +:10F300001040001130F010008F83002C10600006B8 +:10F310003C0F80003C05002000E52024148000C044 +:10F320003C0800043C0F800035EE010095CD001E26 +:10F3300095CC001C31AAFFFF000C5C00014B482556 +:10F34000AF89000C30F010001200000824110001F9 +:10F3500030F100201620008B3C18100000F890249B +:10F36000164000823C040C002411000130E801002A +:10F370001500000B3C0900018F85000430A94000F6 +:10F38000152000073C0900013C0C1F0100EC58242B +:10F390003C0A1000116A01183C1080003C09000171 +:10F3A00000E9302410C000173C0B10003C18080086 +:10F3B0008F1800243307000214E0014024030001E9 +:10F3C0008FBF001C8FB200188FB100148FB00010D7 +:10F3D0000060102103E0000827BD002000EE682433 +:10F3E00011A0FFBE30F220008F8F00043C11FFFF00 +:10F3F00036307FFF00F0382435E380000A0010A685 +:10F40000AF87000000EB102450400065AF8000245F +:10F410008F8C002C3C0D0F0000ED18241580008807 +:10F42000AF83001030E8010011000086938F0010B8 +:10F430003C0A0200106A00833C1280003650010032 +:10F44000920500139789002A3626000230AF00FF8C +:10F4500025EE0004000E19C03C0480008C9801B811 +:10F460000700FFFE34880180AD0300003C198008CE +:10F47000AC830020973100483225FFFF10A0015CCB +:10F48000AF8500082523001200A3F82B53E0015993 +:10F490008F850004348D010095AC00202402001AF1 +:10F4A00030E44000318BFFFFA102000B108001927D +:10F4B0002563FFFE00A3502B154001908F8F0004A1 +:10F4C000A50300148F88000435050001AF850004F2 +:10F4D0003C08800035190180A729000EA729001AD1 +:10F4E0008F89000C30B18000A7270010AF290028B9 +:10F4F000A72600081220000E3C04800035020100FF +:10F50000944C0016318BFFFC256400040088182100 +:10F510008C7F400033E6FFFF14C000053C048000F0 +:10F520003C0AFFFF354D7FFF00AD2824AF85000466 +:10F53000240EBFFF00AE402434850180A4A800261D +:10F54000ACA7002C3C071000AC8701B800001821C4 +:10F550008FBF001C8FB200188FB100148FB0001045 +:10F560000060102103E0000827BD00203C020BFFD3 +:10F5700000E41824345FFFFF03E3C82B5320FF7B14 +:10F58000241100013C0608008CC6002C24C5000193 +:10F590003C010800AC25002C0A0010D42411000501 +:10F5A0008F85002410A0002FAF80001090A30000D2 +:10F5B000146000792419000310A0002A30E601002D +:10F5C00010C000CC8F860010241F000210DF00C97D +:10F5D0008F8B000C3C0708008CE7003824E4FFFF09 +:10F5E00014E0000201641824000018213C0D0800FA +:10F5F00025AD0038006D1021904C00048F85002847 +:10F6000025830004000321C030A5FFFF3626000239 +:10F610000E000FDB000000000A00114D0000182151 +:10F6200000E8302414C0FF403C0F80000E00103D65 +:10F63000000000008F8700000A0010CAAF82000C93 +:10F64000938F00103C18080127189620000F90C0D7 +:10F6500002588021AF9000248F85002414A0FFD38E +:10F66000AF8F00103C0480008C86400030C5010044 +:10F6700010A000BC322300043C0C08008D8C002438 +:10F6800024120004106000C23190000D3C04800080 +:10F690008C8D40003402FFFF11A201003231FFFBCC +:10F6A0008C884000310A01005540000124110010EF +:10F6B00030EE080011C000BE2419FFFB8F9800280F +:10F6C0002F0F03EF51E000010219802430E90100FF +:10F6D00011200014320800018F87002C14E000FB79 +:10F6E0008F8C000C3C05800034AB0100917F00132F +:10F6F00033E300FF246A00042403FFFE0203802496 +:10F70000000A21C012000002023230253226FFFF1B +:10F710000E000FDB9785002A1200FF290000182138 +:10F72000320800011100000D32180004240E0001FF +:10F73000120E0002023230253226FFFF9785002A82 +:10F740000E000FDB00002021240FFFFE020F80249B +:10F750001200FF1B00001821321800045300FF188C +:10F760002403000102323025241200045612000145 +:10F770003226FFFF9785002A0E000FDB24040100CC +:10F780002419FFFB021988241220FF0D0000182104 +:10F790000A0010E9240300011079009C00003021C8 +:10F7A00090AD00012402000211A200BE30EA004028 +:10F7B00090B90001241800011338007F30E900409F +:10F7C0008CA600049785002A00C020210E000FDBC4 +:10F7D0003626000200004021010018218FBF001CC6 +:10F7E0008FB200188FB100148FB00010006010218C +:10F7F00003E0000827BD0020360F010095EE000C45 +:10F8000031CD020015A0FEE63C0900013C1880083D +:10F81000971200489789002A362600023248FFFFD7 +:10F82000AF8800083C0380008C7101B80620FFFE01 +:10F83000346A0180AD4000001100008E3C0F800052 +:10F84000253F0012011FC82B1320008B240E00033C +:10F85000346C0100958B00202402001A30E4400033 +:10F860003163FFFFA142000B108000A72463FFFE5D +:10F870000103682B15A000A52408FFFE34A5000194 +:10F88000A5430014AF8500043C0480002412BFFF90 +:10F8900000B2802434850180A4A9000EA4A9001A16 +:10F8A000A4A60008A4B00026A4A700103C071000DE +:10F8B000AC8701B80A00114D000018213C038000FC +:10F8C00034640100949F000E3C1908008F3900D861 +:10F8D0002404008033E5FFFF273100013C010800CC +:10F8E000AC3100D80E000FDB240600030A00114DD6 +:10F8F00000001821240A000210CA00598F85002830 +:10F900003C0308008C6300D0240E0001106E005EE2 +:10F910002CCF000C24D2FFFC2E5000041600002136 +:10F9200000002021241800021078001B2CD9000CA4 +:10F9300024DFFFF82FE900041520FF330000202109 +:10F9400030EB020051600004000621C054C00022C8 +:10F9500030A5FFFF000621C030A5FFFF0A00117D82 +:10F96000362600023C0908008D29002431300001B0 +:10F970005200FEF7000018219785002A3626000263 +:10F980000E000FDB000020210A00114D000018219D +:10F990000A00119C241200021320FFE624DFFFF866 +:10F9A0000000202130A5FFFF0A00117D362600024D +:10F9B0000A0011AC021980245120FF828CA6000499 +:10F9C0003C05080190A5962110A0FF7E24080001A7 +:10F9D0000A0011F0010018210E000FDB3226000191 +:10F9E0008F8600108F8500280A00124F000621C064 +:10F9F0008F8500043C18800024120003371001801A +:10FA0000A212000B0A00112E3C08800090A30001F6 +:10FA1000241100011071FF70240800012409000264 +:10FA20005069000430E60040240800010A0011F08B +:10FA30000100182150C0FFFD240800013C0C80008B +:10FA4000358B01009563001094A40002307FFFFF06 +:10FA5000509FFF62010018210A001284240800014F +:10FA60002CA803EF1100FE56240300010A001239EE +:10FA700000000000240E000335EA0180A14E000BB7 +:10FA80000A00121C3C04800011E0FFA2000621C005 +:10FA900030A5FFFF0A00117D362600020A0011A5DD +:10FAA000241100201140FFC63C1280003650010096 +:10FAB000960F001094AE000231E80FFF15C8FFC08A +:10FAC000000000000A0011E690B900013C060800A1 +:10FAD0008CC6003824C4FFFF14C00002018418241F +:10FAE000000018213C0D080025AD0038006D1021E4 +:10FAF0000A0011B6904300048F8F0004240EFFFE0D +:10FB00000A00112C01EE28242408FFFE0A00121A14 +:10FB100000A8282427BDFFC8AFB00010AFBF003435 +:10FB20003C10600CAFBE0030AFB7002CAFB6002861 +:10FB3000AFB50024AFB40020AFB3001CAFB20018C3 +:10FB4000AFB100148E0E5000240FFF7F3C068000E2 +:10FB500001CF682435AC380C240B0003AE0C5000E8 +:10FB6000ACCB00083C010800AC2000200E001819A6 +:10FB7000000000003C0A0010354980513C06601628 +:10FB8000AE09537C8CC700003C0860148D0500A0B2 +:10FB90003C03FFFF00E320243C02535300051FC237 +:10FBA0001482000634C57C000003A08002869821E0 +:10FBB0008E7200043C116000025128218CBF007C31 +:10FBC0008CA200783C1E600037C420203C05080150 +:10FBD00024A59264AF820018AF9F001C0E0016DDB2 +:10FBE0002406000A3C190001273996203C01080030 +:10FBF000AC3931DC0E0020D4AF8000148FD7080858 +:10FC00002418FFF03C15570902F8B02412D502F56C +:10FC100024040001AF80002C3C1480003697018042 +:10FC20003C1E080127DE9624369301008E900000CA +:10FC30003205000310A0FFFD3207000110E000882C +:10FC4000320600028E7100283C048000AE91002034 +:10FC50008E6500048E66000000A0382100C040219F +:10FC60008C8301B80460FFFE3C0B0010240A0800DE +:10FC700000AB4824AC8A01B8552000E0240BBFFF3C +:10FC80009675000E3C1208008E52002030AC4000E9 +:10FC900032AFFFFF264E000125ED00043C010800B5 +:10FCA000AC2E0020118000E8AF8D00283C18002009 +:10FCB00000B8B02412C000E530B980002408BFFFAE +:10FCC00000A8382434C81000AF87000030E62000B8 +:10FCD00010C000E92409FFBF3C03000400E328240E +:10FCE00010A00002010910243502004030EA010092 +:10FCF00011400010AF8200048F8B002C11600007B0 +:10FD00003C0D002000ED6024118000043C0F000435 +:10FD100000EF702411C00239000000009668001E38 +:10FD20009678001C3115FFFF0018B40002B690252C +:10FD3000AF92000C30F910001320001324150001BD +:10FD400030FF002017E0000A3C04100000E41024FB +:10FD50001040000D3C0A0C003C090BFF00EA18247F +:10FD60003525FFFF00A3302B10C0000830ED010047 +:10FD70003C0C08008D8C002C24150005258B0001FF +:10FD80003C010800AC2B002C30ED010015A0000B4D +:10FD90003C0500018F85000430AE400055C00007CF +:10FDA0003C0500013C161F0100F690243C0F10009A +:10FDB000124F01CE000000003C05000100E5302498 +:10FDC00010C000AF3C0C10003C1F08008FFF002447 +:10FDD00033E90002152000712403000100601021A6 +:10FDE000104000083C0680003C08800035180100E7 +:10FDF0008F0F00243C056020ACAF00140000000011 +:10FE00003C0680003C194000ACD9013800000000DD +:10FE10005220001332060002262B0140262C0080BF +:10FE2000240EFF80016E2024018E6824000D1940ED +:10FE3000318A007F0004A9403172007F3C16200007 +:10FE400036C20002006A482502B2382500E2882541 +:10FE50000122F825ACDF0830ACD1083032060002B0 +:10FE600010C0FF723C188000370501408CA80000CC +:10FE700024100040AF08002090AF000831E300706C +:10FE8000107000D428790041532000082405006038 +:10FE9000241100201071000E3C0A40003C09800033 +:10FEA000AD2A01780A001304000000001465FFFB6E +:10FEB0003C0A40000E001FF1000000003C0A400018 +:10FEC0003C098000AD2A01780A00130400000000FC +:10FED00090A90009241F00048CA70000312800FF0E +:10FEE000111F01B22503FFFA2C7200061240001404 +:10FEF0003C0680008CA9000494A4000A310500FF90 +:10FF000000095E022D6A00083086FFFF15400002DE +:10FF10002567000424070003240C000910AC01FA33 +:10FF200028AD000A11A001DE2410000A240E0008EA +:10FF300010AE0028000731C000C038213C06800008 +:10FF40008CD501B806A0FFFE34D20180AE47000078 +:10FF500034CB0140916E0008240300023C0A4000AB +:10FF600031C400FF00046A0001A86025A64C000807 +:10FF7000A243000B9562000A3C0810003C09800077 +:10FF8000A64200108D670004AE470024ACC801B83B +:10FF9000AD2A01780A001304000000003C0A80002A +:10FFA000354401009483000E3C0208008C4200D8C6 +:10FFB000240400803065FFFF245500013C01080047 +:10FFC000AC3500D80E000FDB240600030A001370C6 +:10FFD000000018210009320230D900FF2418000166 +:10FFE0001738FFD5000731C08F910020262200016D +:10FFF000AF8200200A0013C800C0382100CB2024A3 +:020000040001F9 +:10000000AF85000010800008AF860004240D87FF34 +:1000100000CD6024158000083C0E006000AE302446 +:1000200010C00005000000000E000D42000000009E +:100030000A001371000000000E0016050000000009 +:100040000A0013710000000030B980005320FF1F28 +:10005000AF8500003C02002000A2F82453E0FF1B03 +:10006000AF8500003C07FFFF34E47FFF00A4382485 +:100070000A00132B34C880000A001334010910242D +:1000800000EC58245160005AAF8000248F8D002C62 +:100090003C0E0F0000EE182415A00075AF83001071 +:1000A00030EF010011E00073939800103C12020041 +:1000B000107200703C06800034D9010093280013B0 +:1000C0009789002A36A60002311800FF271600047F +:1000D000001619C03C0480008C8501B804A0FFFE06 +:1000E00034880180AD0300003C158008AC830020FB +:1000F00096BF004833E5FFFF10A001BCAF850008A4 +:100100002523001200A3102B504001B98F85000455 +:10011000348D010095AC0020240B001A30E440001F +:10012000318AFFFFA10B000B108001BA2543FFFEAF +:1001300000A3702B15C001B88F9600048F8F0004A8 +:10014000A503001435E50001AF8500043C088000DC +:1001500035150180A6A9000EA6A9001A8F89000CEA +:1001600030BF8000A6A70010AEA90028A6A60008F0 +:1001700013E0000F3C0F8000350C0100958B00163A +:10018000316AFFFC25440004008818218C6240007D +:100190003046FFFF14C000072416BFFF3C0EFFFFD0 +:1001A00035CD7FFF00AD2824AF8500043C0F8000D3 +:1001B0002416BFFF00B6902435E50180A4B20026C6 +:1001C000ACA7002C3C071000ADE701B80A00137083 +:1001D000000018210E00165D000000003C0A4000DF +:1001E0003C098000AD2A01780A00130400000000D9 +:1001F0008F85002410A00027AF80001090A300007E +:10020000106000742409000310690101000030210E +:1002100090AE0001240D000211CD014230EF0040EC +:1002200090A90001241F0001113F000930E20040A5 +:100230008CA600049785002A00C020210E000FDB49 +:1002400036A60002000040210A00137001001821A8 +:100250005040FFF88CA600043C07080190E7962167 +:1002600010E0FFF4240800010A00137001001821B7 +:10027000939800103C1F080127FF96200018C8C063 +:10028000033F4021AF8800248F85002414A0FFDBAA +:10029000AF9800103C0480008C86400030C50100FF +:1002A00010A0008732AB00043C0C08008D8C0024A9 +:1002B00024160004156000033192000D241600027C +:1002C0003C0480008C8E4000340DFFFF11CD0113E3 +:1002D00032B5FFFB8C984000330F010055E0000160 +:1002E0002415001030E80800110000382409FFFB35 +:1002F0008F9F00282FF903EF53200001024990241B +:1003000030E2010010400014325F00018F87002CA2 +:1003100014E0010E8F8C000C3C0480003486010038 +:1003200090C5001330AA00FF25430004000321C03C +:100330002419FFFE025990241240000202B6302513 +:1003400032A6FFFF0E000FDB9785002A1240FEA3A6 +:1003500000001821325F000113E0000D3247000455 +:10036000240900011249000202B6302532A6FFFF1F +:100370009785002A0E000FDB000020212402FFFEDB +:10038000024290241240FE950000182132470004DA +:1003900050E0FE922403000102B63025241600042A +:1003A0005656000132A6FFFF9785002A0E000FDB8C +:1003B000240401002403FFFB0243A82412A0FE87AB +:1003C000000018210A001370240300010A0014B968 +:1003D0000249902410A0FFAF30E5010010A00017E3 +:1003E0008F8600102403000210C300148F84000CB9 +:1003F0003C0608008CC6003824CAFFFF14C0000267 +:10040000008A1024000010213C0E080025CE003880 +:10041000004E682191AC00048F850028258B0004D4 +:10042000000B21C030A5FFFF36A600020E000FDB37 +:10043000000000000A00137000001821240F0002C1 +:1004400010CF0088241600013C0308008C6300D004 +:100450001076008D8F85002824D9FFFC2F280004FA +:100460001500006300002021241F0002107F005DA2 +:100470002CC9000C24C3FFF82C6200041440FFE9CF +:100480000000202130EA020051400004000621C093 +:1004900054C0000530A5FFFF000621C030A5FFFFB6 +:1004A0000A00150436A600020E000FDB32A600017A +:1004B0008F8600108F8500280A001520000621C0B5 +:1004C0003C0A08008D4A0024315200015240FE438C +:1004D000000018219785002A36A600020E000FDBC7 +:1004E000000020210A001370000018219668000CFB +:1004F000311802005700FE313C0500013C1F800806 +:1005000097F900489789002A36A600023328FFFF92 +:10051000AF8800083C0380008C7501B806A0FFFE80 +:100520003C04800034820180AC400000110000B621 +:1005300024180003252A0012010A182B106000B2AB +:1005400000000000966F00203C0E8000240D001A71 +:1005500031ECFFFF35CA018030EB4000A14D000BAC +:10056000116000B02583FFFE0103902B164000AE02 +:100570002416FFFE34A50001A5430014AF85000436 +:100580002419BFFF00B94024A6E9000EA6E9001A0D +:10059000A6E60008A6E80026A6E700103C07100023 +:1005A000AE8701B80A001370000018213C048000D7 +:1005B0008C8201B80440FFFE349601802415001C93 +:1005C000AEC70000A2D5000B3C071000AC8701B8F5 +:1005D0003C0A40003C098000AD2A01780A0013045F +:1005E000000000005120FFA424C3FFF800002021D8 +:1005F00030A5FFFF0A00150436A600020E00103DCC +:10060000000000008F8700000A001346AF82000C34 +:1006100090A30001241500011075FF0B24080001B0 +:10062000240600021066000430E2004024080001A5 +:100630000A001370010018215040FFFD240800013A +:100640003C0C8000358B0100956A001094A40002D8 +:100650003143FFFF5083FDE1010018210A00158599 +:10066000240800018F8500282CB203EF1240FDDB27 +:10067000240300013C0308008C6300D02416000111 +:100680001476FF7624D9FFFC2CD8000C1300FF72DF +:10069000000621C030A5FFFF0A00150436A600029F +:1006A00010B00037240F000B14AFFE23000731C039 +:1006B000312600FF00065600000A4E0305220047BF +:1006C00030C6007F0006F8C03C16080126D69620EA +:1006D00003F68021A2000001A20000003C0F600090 +:1006E0008DF918202405000100C588040011302769 +:1006F0000326C024000731C000C03821ADF81820FF +:100700000A0013C8A60000028F850020000731C030 +:1007100024A2FFFF0A0013F6AF8200200A0014B2E1 +:100720002415002011E0FECC3C1980003728010080 +:100730009518001094B6000233120FFF16D2FEC6B1 +:10074000000000000A00148290A900013C0B080080 +:100750008D6B0038256DFFFF15600002018D1024A0 +:10076000000010213C080800250800380048C0217E +:10077000930F000425EE00040A0014C5000E21C0EA +:1007800000065202241F00FF115FFDEB000731C07D +:10079000000A20C03C0E080125CE9620008EA8211C +:1007A000009E602100095C02240D00013C076000EE +:1007B000A2AD0000AD860000A2AB00018CF21820B3 +:1007C00024030001014310040242B025ACF61820B6 +:1007D00000C038210A0013C8A6A900020A0015AA01 +:1007E000AF8000200A0012FFAF84002C8F85000428 +:1007F0003C1980002408000337380180A308000B4F +:100800000A00144D3C088000A2F8000B0A00155A9B +:100810002419BFFF8F9600042412FFFE0A00144B18 +:1008200002D228242416FFFE0A00155800B62824F8 +:100830003C038000346401008C85000030A2003E3F +:100840001440000800000000AC6000488C870000E5 +:1008500030E607C010C0000500000000AC60004C8E +:10086000AC60005003E0000824020001AC600054BA +:10087000AC6000408C880000310438001080FFF923 +:10088000000000002402000103E00008AC60004406 +:100890003C0380008C6201B80440FFFE3467018095 +:1008A000ACE4000024080001ACE00004A4E500086A +:1008B00024050002A0E8000A34640140A0E5000B12 +:1008C0009483000A14C00008A4E30010ACE00024E4 +:1008D0003C07800034E901803C041000AD20002872 +:1008E00003E00008ACE401B88C8600043C0410006E +:1008F000ACE600243C07800034E90180AD200028EC +:1009000003E00008ACE401B83C0680008CC201B8EA +:100910000440FFFE34C7018024090002ACE400005B +:10092000ACE40004A4E50008A0E9000A34C50140D5 +:10093000A0E9000B94A8000A3C041000A4E80010F1 +:10094000ACE000248CA30004ACE3002803E0000822 +:10095000ACC401B83C039000346200010082202541 +:100960003C038000AC6400208C65002004A0FFFEE6 +:100970000000000003E00008000000003C028000CE +:10098000344300010083202503E00008AC4400202C +:1009900027BDFFE03C098000AFBF0018AFB10014D5 +:1009A000AFB00010352801408D10000091040009FF +:1009B0009107000891050008308400FF30E600FF31 +:1009C00000061A002C820081008330251040002A86 +:1009D00030A50080000460803C0D080125AD928C9C +:1009E000018D58218D6A00000140000800000000C0 +:1009F0003C038000346201409445000A14A0001EAC +:100A00008F91FCBC9227000530E6000414C0001A48 +:100A1000000000000E00164E02002021922A000560 +:100A200002002021354900040E001658A2290005B5 +:100A30009228000531040004148000020000000028 +:100A40000000000D922D0000240B002031AC00FFAF +:100A5000158B00093C0580008CAE01B805C0FFFE77 +:100A600034B10180AE3000003C0F100024100005AE +:100A7000A230000BACAF01B80000000D8FBF001812 +:100A80008FB100148FB0001003E0000827BD0020D4 +:100A90000200202100C028218FBF00188FB1001450 +:100AA0008FB00010240600010A00161D27BD00208B +:100AB0000000000D0200202100C028218FBF001877 +:100AC0008FB100148FB00010000030210A00161DF5 +:100AD00027BD002014A0FFE8000000000200202134 +:100AE0008FBF00188FB100148FB0001000C02821F4 +:100AF0000A00163B27BD00203C0780008CEE01B8A1 +:100B000005C0FFFE34F00180241F0002A21F000B6D +:100B100034F80140A60600089719000A3C0F10009F +:100B2000A61900108F110004A6110012ACEF01B835 +:100B30000A0016998FBF001827BDFFE8AFBF00104D +:100B40000E000FD4000000003C0280008FBF001098 +:100B500000002021AC4001800A00108F27BD001842 +:100B60003084FFFF30A5FFFF108000070000182130 +:100B7000308200011040000200042042006518216C +:100B80001480FFFB0005284003E0000800601021EE +:100B900010C00007000000008CA2000024C6FFFF68 +:100BA00024A50004AC82000014C0FFFB24840004D0 +:100BB00003E000080000000010A0000824A3FFFFCD +:100BC000AC86000000000000000000002402FFFFCF +:100BD0002463FFFF1462FFFA2484000403E000088A +:100BE000000000003C03800027BDFFF83462018054 +:100BF000AFA20000308C00FF30AD00FF30CE00FF10 +:100C00003C0B80008D6401B80480FFFE00000000F2 +:100C10008FA900008D6801288FAA00008FA700000F +:100C20008FA400002405000124020002A085000A10 +:100C30008FA30000359940003C051000A062000B16 +:100C40008FB800008FAC00008FA600008FAF0000AF +:100C500027BD0008AD280000AD400004AD80002491 +:100C6000ACC00028A4F90008A70D0010A5EE0012E2 +:100C700003E00008AD6501B83C06800827BDFFE829 +:100C800034C50080AFBF001090A7000924020012F5 +:100C900030E300FF1062000B008030218CA8005070 +:100CA00000882023048000088FBF00108CAA003425 +:100CB000240400390000282100CA4823052000052B +:100CC000240600128FBF00102402000103E0000878 +:100CD00027BD00180E0016F2000000008FBF0010A4 +:100CE0002402000103E0000827BD001827BDFFC84B +:100CF000AFB20030AFB00028AFBF0034AFB1002CAE +:100D000000A0802190A5000D30A6001010C000109A +:100D1000008090213C0280088C4400048E0300086F +:100D20001064000C30A7000530A6000510C0009329 +:100D3000240400018FBF00348FB200308FB1002C2B +:100D40008FB000280080102103E0000827BD003884 +:100D500030A7000510E0000F30AB001210C00006F5 +:100D6000240400013C0980088E0800088D25000439 +:100D70005105009C240400388FBF00348FB200302E +:100D80008FB1002C8FB000280080102103E00008F4 +:100D900027BD0038240A0012156AFFE6240400016A +:100DA0000200202127A500100E000CB6AFA00010F5 +:100DB0001440007C3C19800837240080909800087B +:100DC000331100081220000A8FA7001030FF010025 +:100DD00013E000A48FA300148C8600580066102333 +:100DE000044000043C0A8008AC8300588FA7001020 +:100DF0003C0A800835480080910900083124000829 +:100E00001480000224080003000040213C1F8008D9 +:100E100093F1001193F9001237E600808CCC005456 +:100E2000333800FF03087821322D00FF000F708057 +:100E300001AE282100AC582B1160006F00000000AB +:100E400094CA005C8CC900543144FFFF0125102373 +:100E50000082182B14600068000000008CCB005446 +:100E60000165182330EC00041180006C000830800C +:100E70008FA8001C0068102B1040006230ED0004A9 +:100E8000006610232C46008010C00002004088211C +:100E9000241100800E00164E024020213C0D8008D7 +:100EA00035A6008024070001ACC7000C90C80008DC +:100EB0000011484035A70100310C007FA0CC00088C +:100EC0008E05000424AB0001ACCB0030A4D1005C43 +:100ED0008CCA003C9602000E01422021ACC40020C6 +:100EE0008CC3003C0069F821ACDF001C8E190004A3 +:100EF000ACF900008E180008ACF800048FB10010A7 +:100F0000322F000855E0004793A60020A0C0004EF5 +:100F100090D8004E2411FFDFA0F8000890CF000801 +:100F200001F17024A0CE00088E0500083C0B80085B +:100F300035690080AD2500388D6A00148D2200309F +:100F40002419005001422021AD24003491230000D7 +:100F5000307F00FF13F90036264F01000E001658AF +:100F60000240202124040038000028210E0016F23F +:100F70002406000A0A001757240400010E000D2859 +:100F8000000020218FBF00348FB200308FB1002CC1 +:100F90008FB00028004020210080102103E00008CD +:100FA00027BD00388E0E00083C0F800835F0008009 +:100FB000AE0E005402402021AE0000300E00164E4E +:100FC00000000000920D00250240202135AC0020D9 +:100FD0000E001658A20C00250E000CAC0240202179 +:100FE000240400382405008D0E0016F22406001299 +:100FF0000A0017572404000194C5005C0A001792E8 +:1010000030A3FFFF2407021811A0FF9E00E6102363 +:101010008FAE001C0A00179A01C610230A0017970A +:101020002C620218A0E600080A0017C48E0500080A +:101030002406FF8001E6C0243C118000AE38002861 +:101040008E0D000831E7007F3C0E800C00EE602121 +:10105000AD8D00E08E080008AF8C00380A0017D074 +:10106000AD8800E4AC800058908500082403FFF7A9 +:1010700000A33824A08700080A0017758FA7001066 +:101080003C05080024A560A83C04080024846FF4F3 +:101090003C020800244260B0240300063C01080121 +:1010A000AC2596A03C010801AC2496A43C010801A3 +:1010B000AC2296A83C010801A02396AC03E00008EE +:1010C0000000000003E00008240200013C02800050 +:1010D000308800FF344701803C0680008CC301B893 +:1010E0000460FFFE000000008CC501282418FF806A +:1010F0003C0D800A24AF010001F8702431EC007F20 +:10110000ACCE0024018D2021ACE50000948B00EAD8 +:101110003509600024080002316AFFFFACEA0004D0 +:1011200024020001A4E90008A0E8000BACE00024C0 +:101130003C071000ACC701B8AF84003803E00008DA +:10114000AF85006C938800488F8900608F820038DB +:1011500030C600FF0109382330E900FF01221821C1 +:1011600030A500FF2468008810C000020124382147 +:101170000080382130E400031480000330AA00030B +:101180001140000D312B000310A0000900001021B8 +:1011900090ED0000244E000131C200FF0045602B9D +:1011A000A10D000024E700011580FFF925080001CA +:1011B00003E00008000000001560FFF300000000DD +:1011C00010A0FFFB000010218CF80000245900043F +:1011D000332200FF0045782BAD18000024E70004FF +:1011E00015E0FFF92508000403E0000800000000F6 +:1011F00093850048938800588F8700600004320070 +:101200003103007F00E5102B30C47F001040000F39 +:10121000006428258F8400383C0980008C8A00EC0B +:10122000AD2A00A43C03800000A35825AC6B00A0AD +:101230008C6C00A00580FFFE000000008C6D00ACEF +:10124000AC8D00EC03E000088C6200A80A00188254 +:101250008F840038938800593C0280000080502120 +:10126000310300FEA383005930ABFFFF30CC00FFF9 +:1012700030E7FFFF344801803C0980008D2401B82D +:101280000480FFFE8F8D006C24180016AD0D000049 +:101290008D2201248F8D0038AD0200048D5900206D +:1012A000A5070008240201C4A119000AA118000B17 +:1012B000952F01208D4E00088D4700049783005C18 +:1012C0008D59002401CF302100C7282100A32023FD +:1012D0002418FFFFA504000CA50B000EA5020010AA +:1012E000A50C0012AD190018AD18002495AF00E848 +:1012F0003C0B10002407FFF731EEFFFFAD0E002876 +:101300008DAC0084AD0C002CAD2B01B88D460020B7 +:1013100000C7282403E00008AD4500208F8800386E +:101320000080582130E7FFFF910900D63C02800081 +:1013300030A5FFFF312400FF00041A00006750258C +:1013400030C600FF344701803C0980008D2C01B875 +:101350000580FFFE8F82006C240F0017ACE20000B6 +:101360008D390124ACF900048D780020A4EA00082E +:10137000241901C4A0F8000AA0EF000B9523012056 +:101380008D6E00088D6D00049784005C01C35021B0 +:10139000014D602101841023A4E2000CA4E5000E9D +:1013A000A4F90010A4E60012ACE000148D7800242B +:1013B000240DFFFFACF800188D0F007CACEF001C73 +:1013C0008D0E00783C0F1000ACEE0020ACED002438 +:1013D000950A00BE240DFFF73146FFFFACE600285A +:1013E000950C00809504008231837FFF0003CA00C2 +:1013F0003082FFFF0322C021ACF8002CAD2F01B8D2 +:10140000950E00828D6A002000AE3021014D282407 +:10141000A506008203E00008AD6500203C028000C4 +:10142000344501803C0480008C8301B80460FFFED9 +:101430008F8A0044240600199549001C3128FFFFBB +:10144000000839C0ACA70000A0A6000B3C051000A6 +:1014500003E00008AC8501B88F87004C0080402174 +:1014600030C400FF3C0680008CC201B80440FFFE7F +:101470008F89006C9383006834996000ACA90000E8 +:10148000A0A300058CE20010240F00022403FFF744 +:10149000A4A20006A4B900088D180020A0B8000A74 +:1014A000A0AF000B8CEE0000ACAE00108CED000481 +:1014B000ACAD00148CEC001CACAC00248CEB002018 +:1014C000ACAB00288CEA002C3C071000ACAA002C26 +:1014D0008D090024ACA90018ACC701B88D05002007 +:1014E00000A3202403E00008AD0400208F8600380C +:1014F00027BDFFE0AFB10014AFBF0018AFB00010C0 +:1015000090C300D430A500FF3062002010400008D6 +:10151000008088218CCB00D02409FFDF256A0001E0 +:10152000ACCA00D090C800D401093824A0C700D4A8 +:1015300014A000403C0C80008F840038908700D4B9 +:101540002418FFBF2406FFEF30E3007FA08300D400 +:10155000979F005C8F8200608F8D003803E2C82364 +:10156000A799005CA5A000BC91AF00D401F870243D +:10157000A1AE00D48F8C0038A18000D78F8A0038AC +:10158000A5400082AD4000EC914500D400A658244F +:10159000A14B00D48F9000348F8400609786005C4C +:1015A0000204282110C0000FAF850034A38000582A +:1015B0003C0780008E2C000894ED01208E2B000447 +:1015C000018D5021014B8021020620233086FFFF30 +:1015D00030C8000F3909000131310001162000091F +:1015E000A3880058938600488FBF00188FB100145D +:1015F0008FB0001027BD0020AF85006403E0000815 +:10160000AF86006000C870238FBF00189386004823 +:101610008FB100148FB0001034EF0C00010F28219F +:1016200027BD0020ACEE0084AF85006403E0000815 +:10163000AF86006035900180020028210E00190F4E +:10164000240600828F840038908600D430C5004084 +:1016500050A0FFBAA38000688F85004C3C06800034 +:101660008CCD01B805A0FFFE8F89006C2408608234 +:1016700024070002AE090000A6080008A207000B1C +:101680008CA300083C0E1000AE0300108CA2000CCE +:10169000AE0200148CBF0014AE1F00188CB90018E5 +:1016A000AE1900248CB80024AE1800288CAF002896 +:1016B000AE0F002CACCE01B80A001948A380006818 +:1016C0008F8A003827BDFFE0AFB10014AFB0001023 +:1016D0008F880060AFBF00189389003C954200BC22 +:1016E00030D100FF0109182B0080802130AC00FFB1 +:1016F0003047FFFF0000582114600003310600FF4F +:1017000001203021010958239783005C0068202BB9 +:101710001480002700000000106800562419000102 +:101720001199006334E708803165FFFF0E0018C08F +:10173000020020218F83006C3C07800034E601808A +:101740003C0580008CAB01B80560FFFE240A001840 +:101750008F840038ACC30000A0CA000B948900BE7F +:101760003C081000A4C90010ACC00030ACA801B8FF +:101770009482008024430001A4830080949F008011 +:101780003C0608008CC6318833EC7FFF1186005E72 +:101790000000000002002021022028218FBF001835 +:1017A0008FB100148FB000100A00193427BD00203B +:1017B000914400D42403FF8000838825A15100D4E4 +:1017C0009784005C3088FFFF51000023938C003C1D +:1017D0008F8500382402EFFF008B782394AE00BC85 +:1017E0000168502B31E900FF01C26824A4AD00BCA0 +:1017F00051400039010058213C1F800037E60100AC +:101800008CD800043C190001031940245500000144 +:1018100034E740008E0A00202403FFFB241100015E +:1018200001432024AE0400201191002D34E78000F4 +:1018300002002021012030210E0018C03165FFFF79 +:101840009787005C8F890060A780005C0127802358 +:10185000AF900060938C003C8F8B00388FBF0018D6 +:101860008FB100148FB0001027BD002003E00008E6 +:10187000A16C00D73C0D800035AA01008D48000402 +:101880003C0900010109282454A0000134E740006C +:101890008E0F00202418FFFB34E7800001F870242D +:1018A00024190001AE0E00201599FF9F34E708802F +:1018B000020020210E00188E3165FFFF020020215A +:1018C000022028218FBF00188FB100148FB00010A4 +:1018D0000A00193427BD00200A0019F7000048212A +:1018E00002002021012030210E00188E3165FFFFFB +:1018F0009787005C8F890060A780005C01278023A8 +:101900000A001A0EAF900060948C0080241F8000A3 +:10191000019F3024A4860080908B0080908F0080EF +:10192000316700FF0007C9C20019C027001871C045 +:1019300031ED007F01AE2825A08500800A0019DF67 +:1019400002002021938500682403000127BDFFE8E1 +:1019500000A330042CA20020AFB00010AFBF0014D1 +:1019600000C01821104000132410FFFE3C0708009F +:101970008CE7319000E610243C088000350501809A +:1019800014400005240600848F890038240A0004CE +:101990002410FFFFA12A00FC0E00190F0000000018 +:1019A000020010218FBF00148FB0001003E0000868 +:1019B00027BD00183C0608008CC631940A001A574F +:1019C00000C310248F87004427BDFFE0AFB200188A +:1019D000AFB10014AFB00010AFBF001C30D000FF9B +:1019E00090E6000D00A088210080902130C5007F86 +:1019F000A0E5000D8F8500388E2300188CA200D042 +:101A00001062002E240A000E0E001A4AA38A0068F3 +:101A10002409FFFF104900222404FFFF5200002088 +:101A2000000020218E2600003C0C001000CC582421 +:101A3000156000393C0E000800CE682455A0003F18 +:101A4000024020213C18000200D880241200001F10 +:101A50003C0A00048F8700448CE200148CE30010E1 +:101A60008CE500140043F82303E5C82B1320000580 +:101A7000024020218E24002C8CF1001010910031A6 +:101A80000240202124020012A38200680E001A4A9C +:101A90002412FFFF105200022404FFFF0000202147 +:101AA0008FBF001C8FB200188FB100148FB00010D0 +:101AB0000080102103E0000827BD002090A800D47A +:101AC000350400200A001A80A0A400D400CA4824CB +:101AD0001520000B8F8B00448F8D00448DAC0010BF +:101AE0001580000B024020218E2E002C51C0FFECEF +:101AF00000002021024020210A001A9B2402001726 +:101B00008D66001050C0FFE6000020210240202119 +:101B10000A001A9B24020011024020212402001511 +:101B20000E001A4AA3820068240FFFFF104FFFDC4B +:101B30002404FFFF0A001A8A8E2600000A001AC138 +:101B4000240200143C08000400C8382450E0FFD4EC +:101B500000002021024020210A001A9B24020013C9 +:101B60008F85003827BDFFD8AFB3001CAFB2001877 +:101B7000AFB10014AFB00010AFBF002090A700D4E9 +:101B80008F90004C2412FFFF34E2004092060000C8 +:101B9000A0A200D48E0300100080982110720006CD +:101BA00030D1003F2408000D0E001A4AA3880068B7 +:101BB000105200252404FFFF8F8A00388E09001878 +:101BC0008D4400D01124000702602021240C000E57 +:101BD0000E001A4AA38C0068240BFFFF104B001A5A +:101BE0002404FFFF24040020122400048F8D0038F9 +:101BF00091AF00D435EE0020A1AE00D48F85005403 +:101C000010A00019000000001224004A8F9800382C +:101C10008F92FCBC971000809651000A5230004809 +:101C20008F9300403C1F08008FFF318C03E5C82BC9 +:101C30001720001E02602021000028210E0019A993 +:101C400024060001000020218FBF00208FB3001C5C +:101C50008FB200188FB100148FB0001000801021D7 +:101C600003E0000827BD00285224002A8E05001436 +:101C70008F840038948A008025490001A48900805F +:101C8000948800803C0208008C42318831077FFF35 +:101C900010E2000E00000000026020210E00193446 +:101CA000240500010A001B0B000020212402002D46 +:101CB0000E001A4AA38200682403FFFF1443FFE1C9 +:101CC0002404FFFF0A001B0C8FBF002094990080A2 +:101CD000241F800024050001033FC024A498008035 +:101CE00090920080908E0080325100FF001181C2DE +:101CF00000107827000F69C031CC007F018D582576 +:101D0000A08B00800E001934026020210A001B0BFA +:101D1000000020212406FFFF54A6FFD68F84003840 +:101D2000026020210E001934240500010A001B0B5B +:101D300000002021026020210A001B252402000A45 +:101D40002404FFFD0A001B0BAF9300608F8800384E +:101D500027BDFFE8AFB00010AFBF0014910A00D458 +:101D60008F87004C00808021354900408CE60010B0 +:101D7000A10900D43C0208008C4231B030C53FFFBD +:101D800000A2182B106000078F850050240DFF80E3 +:101D900090AE000D01AE6024318B00FF156000088D +:101DA0000006C382020020212403000D8FBF00140F +:101DB0008FB0001027BD00180A001A4AA3830068DC +:101DC00033060003240F000254CFFFF70200202146 +:101DD00094A2001C8F85003824190023A4A200E8D7 +:101DE0008CE8000000081E02307F003F13F9003528 +:101DF0003C0A00838CE800188CA600D0110600086D +:101E0000000000002405000E0E001A4AA385006899 +:101E10002407FFFF104700182404FFFF8F850038B8 +:101E200090A900D435240020A0A400D48F8C0044B5 +:101E3000918E000D31CD007FA18D000D8F83005458 +:101E40001060001C020020218F8400508C9800102C +:101E50000303782B11E0000D241900180200202143 +:101E6000A39900680E001A4A2410FFFF10500002C8 +:101E70002404FFFF000020218FBF00148FB000104A +:101E80000080102103E0000827BD00188C86001098 +:101E90008F9F00440200202100C31023AFE20010F6 +:101EA000240500010E0019A9240600010A001B9751 +:101EB000000020210E001934240500010A001B97A0 +:101EC00000002021010A5824156AFFD98F8C004494 +:101ED000A0A600FC0A001B84A386005A30A500FFC0 +:101EE0002406000124A9000100C9102B1040000C99 +:101EF00000004021240A000100A61823308B0001B5 +:101F000024C60001006A3804000420421160000267 +:101F100000C9182B010740251460FFF800A61823FC +:101F200003E000080100102127BDFFD8AFB0001862 +:101F30008F90004CAFB1001CAFBF00202403FFFF07 +:101F40002411002FAFA30010920600002405000802 +:101F500026100001006620260E001BB0308400FF12 +:101F600000021E003C021EDC34466F410A001BD8F2 +:101F70000000102110A00009008018212445000154 +:101F800030A2FFFF2C4500080461FFFA0003204047 +:101F90000086202614A0FFF9008018210E001BB037 +:101FA000240500208FA300102629FFFF313100FFF8 +:101FB00000034202240700FF1627FFE20102182651 +:101FC00000035027AFAA0014AFAA00100000302170 +:101FD00027A8001027A7001400E6782391ED00033E +:101FE00024CE000100C8602131C600FF2CCB0004C4 +:101FF0001560FFF9A18D00008FA200108FBF002097 +:102000008FB1001C8FB0001803E0000827BD002826 +:1020100027BDFFD0AFB3001CAFB00010AFBF00288A +:10202000AFB50024AFB40020AFB20018AFB10014B8 +:102030003C0C80008D880128240FFF803C06800A1C +:1020400025100100250B0080020F68243205007F57 +:10205000016F7024AD8E009000A62821AD8D002464 +:1020600090A600FC3169007F3C0A8004012A1821F7 +:10207000A386005A9067007C00809821AF830030CF +:1020800030E20002AF88006CAF85003800A0182154 +:10209000144000022404003424040030A3840048C7 +:1020A0008C7200DC30D100FF24040004AF92006089 +:1020B00012240004A38000688E7400041680001EA1 +:1020C0003C0880009386005930C7000150E0000FA3 +:1020D0008F8600608CA400848CA800842413FF8069 +:1020E00000936024000C49403110007F01307825B6 +:1020F0003C19200001F9682530DF00FE3C03800018 +:10210000AC6D0830A39F00598F8600608FBF0028F8 +:102110008FB500248FB400208FB3001C8FB200183D +:102120008FB100148FB000102402000127BD0030D1 +:1021300003E00008ACA600DC8E7F000895020120B9 +:102140008E67001003E2C8213326FFFF30D8000F4E +:1021500033150001AF87003416A00058A39800582B +:1021600035090C000309382100D81823AD03008479 +:10217000AF8700648E6A00043148FFFF1100007EC3 +:10218000A78A005C90AC00D42407FF8000EC3024C8 +:1021900030CB00FF1560004B9786005C938E005A91 +:1021A000240D000230D5FFFF11CD02A20000A021B6 +:1021B0008F85006002A5802B160000BC9388004824 +:1021C0003C11800096240120310400FF1485008812 +:1021D0008F8400648F9800343312000356400085CA +:1021E00030A500FF8F900064310C00FF24060034FE +:1021F00011860095AF90004C9204000414800119E0 +:102200008F8E0038A380003C8E0D00048DC800D84E +:102210003C0600FF34CCFFFF01AC30240106182B34 +:1022200014600121AF8600548F8700609798005C8E +:10223000AF8700400307402310C000C7A788005C99 +:102240008F91003030C3000300035823922A007C92 +:102250003171000302261021000A20823092000111 +:102260000012488000492821311FFFFF03E5C82BD9 +:10227000132001208F8800388F8500348F880064F8 +:102280001105025A3C0E3F018E0600003C0C250051 +:1022900000CE682411AC01638F84004C30E500FF50 +:1022A0000E00184A000030218F8800388F870060A8 +:1022B0008F8500340A001DB78F8600540A001C5613 +:1022C000AF87006490AC00D400EC2024309000FF75 +:1022D000120000169386005990B5008890B400D77C +:1022E00024A8008832A2003F2446FFE02CD1002021 +:1022F000A394003C1220000CAF88004C240E000177 +:1023000000CE2004308A00191540012B3C068000C5 +:1023100034D80002009858241560022E3092002014 +:1023200016400234000000009386005930CE0001B0 +:1023300011C0000F9788005C8CA900848CAF0084CA +:102340002410FF800130C8240019194031ED007FAE +:10235000006D38253C1F200000FF902530CB00FE8B +:102360003C188000AF120830A38B00599788005C9E +:102370001500FF84000000008E630020306C000414 +:102380001180FF51938600592404FFFB0064302420 +:102390003C038000AE660020346601808C7301B877 +:1023A0000660FFFE8F8E006C346A01003C15000150 +:1023B000ACCE00008C62012424076085ACC200040E +:1023C0008D54000402958824522000012407608364 +:1023D000241200023C1810003C0B8000A4C7000827 +:1023E000A0D2000BAD7801B80A001C2B93860059CF +:1023F00030A500FF0E00184A240600018F88006CEB +:102400003C05800034A90900250201889388004812 +:10241000304A0007304B00783C0340802407FF809F +:102420000163C825014980210047F824310C00FFD1 +:1024300024060034ACBF0800AF90004CACB90810C3 +:102440005586FF6E920400048F8400388E11003090 +:10245000908E00D431CD001015A000108F83006045 +:102460002C6F000515E000E400000000909800D4F7 +:102470002465FFFC331200101640000830A400FF52 +:102480008F9F00648F99003413F90004388700018E +:1024900030E20001144001C8000000000E001BC320 +:1024A000000000000A001DF8000000008F84006496 +:1024B00030C500FF0E00184A24060001938E004824 +:1024C000240A003411CA00A08F8500388F8600606E +:1024D0009783005C3062FFFF00C28823AF910060E9 +:1024E000A780005C1280FF90028018212414FFFD59 +:1024F0005474FFA28E6300208E6900042403FFBF82 +:10250000240BFFEF0135C823AE79000490AF00D44F +:1025100031ED007FA0AD00D48E6600208F9800388A +:10252000A780005C34DF0002AE7F0020A70000BC63 +:10253000931200D402434024A30800D48F9500389E +:10254000AEA000EC92AE00D401CB5024A2AA00D4DD +:102550000A001CD78F8500388F910034AF8000604F +:1025600002275821AF8B0034000020212403FFFFF5 +:10257000108301B48F8500388E0C00103C0D0800CC +:102580008DAD31B09208000031843FFF008D802B6B +:1025900012000023310D003F3C1908008F3931A88B +:1025A0008F9F006C000479802408FF80033F202166 +:1025B000008FC821938500590328F8243C06008029 +:1025C0003C0F800034D80001001F91403331007F60 +:1025D0008F8600380251502535EE0940332B0078A4 +:1025E000333000073C0310003C02800C017890253A +:1025F000020E48210143C0250222382134AE0001D9 +:10260000ADFF0804AF890050ADF20814AF87004455 +:10261000ADFF0028ACD90084ADF80830A38E005976 +:102620009383005A240700035067002825A3FFE086 +:10263000240C0001146CFFAB8F850038241100239B +:1026400011B10084000000002402000B0260202170 +:102650000E001A4AA38200680040A0210A001D3221 +:102660008F85003802602021240B000C0E001A4ACE +:10267000A38B0068240AFFFF104AFFBC2404FFFF5D +:102680008F8E0038A380003C8E0D00048DC800D8CA +:102690003C0600FF34CCFFFF01AC30240106182BB0 +:1026A0001060FEE1AF860054026020212412001960 +:1026B0000E001A4AA3920068240FFFFF104FFFABD1 +:1026C0002404FFFF0A001C838F8600542C74002012 +:1026D0001280FFDE2402000B000328803C11080159 +:1026E0002631949000B148218D2D000001A00008F2 +:1026F000000000008F85003400A710219385003C66 +:10270000AF82003402251821A383003C951F00BC32 +:102710000226282137F91000A51900BC5240FF926B +:10272000AF850060246A0004A38A003C950900BCC0 +:1027300024A40004AF84006035322000A51200BC40 +:102740000A001D54000020218F8600602CCB00055C +:102750001560FF609783005C3072FFFF00D240235A +:102760002D18000513000003306400FF24DFFFFC78 +:1027700033E400FF8F8500648F86003410A60004C8 +:10278000388F000131ED000115A001380000000074 +:102790008F840038908C00D435870010A08700D437 +:1027A0008F8500388F8600609783005CACA000ECBA +:1027B0000A001D2F3062FFFF8CAA00848CB50084B4 +:1027C0003C041000014710240002894032B4007F0D +:1027D0000234302500C460253C0880002405000137 +:1027E00002602021240600010E0019A9AD0C08305A +:1027F0000A001CC38F8500388C8200EC1222FE7EFA +:102800000260202124090005A38900680E001A4AED +:102810002411FFFF1451FE782404FFFF0A001D5508 +:102820002403FFFF8F8F004C8F8800388DF8000045 +:10283000AD1800888DE70010AD0700988F87006005 +:102840000A001DB78F8600542407FFFF118700057B +:10285000000000000E001B4C026020210A001D90A9 +:102860000040A0210E001AD1026020210A001D9014 +:102870000040A0218F90004C3C0908008D2931B008 +:102880008E11001032323FFF0249682B11A0000C5C +:10289000240AFF808F85005090AE000D014E102459 +:1028A000304C00FF11800007026020210011C3821C +:1028B00033030003240B0001106B0105000000002E +:1028C000026020212418000D0E001A4AA398006807 +:1028D000004020218F8500380A001D320080A02191 +:1028E0008F90004C3C0A08008D4A31B08F85005013 +:1028F0008E0400100000A0218CB1001430823FFF34 +:10290000004A602B8CB200205180FFEE0260202133 +:1029100090B8000D240BFF800178702431C300FFB4 +:102920005060FFE80260202100044382310600036A +:1029300014C0FFE40260202194BF001C8F9900386E +:102940008E060028A73F00E88CAF0010022F20233E +:1029500014C40139026020218F83005400C3682110 +:10296000022D382B14E00135240200188F8A004410 +:102970008F820030024390218D4B00100163702341 +:10298000AD4E0010AD5200208C4C00740192282BEB +:1029900014A00156026020218F8400508E0800246C +:1029A0008C86002411060007026020212419001CD7 +:1029B0000E001A4AA3990068240FFFFF104FFFC5AD +:1029C0002404FFFF8F8400448C87002424FF00012F +:1029D000AC9F0024125101338F8D00308DB10074F3 +:1029E000123201303C0B00808E0E000001CB5024CF +:1029F00015400075000000008E0300142411FFFF35 +:102A000010710006026020212418001B0E001A4AD3 +:102A1000A39800681051FFAF2404FFFF8E0300004D +:102A20003C0800010068302410C000133C04008002 +:102A30000064A024168000090200282102602021E1 +:102A40002419001A0E001A4AA3990068240FFFFFE8 +:102A5000104FFFA02404FFFF020028210260202164 +:102A60000E001A6A240600012410FFFF1050FF997F +:102A70002404FFFF241400018F9F004402602021E2 +:102A80000280302197F1003424050001262700013F +:102A9000A7E700340E0019A9000000000000202163 +:102AA0008F8500380A001D320080A0218F90004CD5 +:102AB0003C1408008E9431B08E07001030E83FFFC0 +:102AC0000114302B10C000618F860050241FFF803E +:102AD00090C5000D03E52024309200FF5240005CB9 +:102AE000026020218F8D005411A0000700078B8207 +:102AF0008F8500388F89FCBC94AF00809539000A1F +:102B0000132F00F68F870040322C000315800063DE +:102B10000000000092020002104000D700000000F8 +:102B20008E0A0024154000D8026020219204000380 +:102B300024060002308800FF15060005308500FFDE +:102B40008F940054528000F202602021308500FFF3 +:102B500038AD00102DA400012CBF000103E4302586 +:102B6000020028210E001A6A026020212410FFFFB3 +:102B7000105000BE8F8500388F830054106000C451 +:102B8000240500013C1908008F39318C0323782B70 +:102B900015E000B12409002D026020210000282149 +:102BA0000E0019A9240600018F85003800001821A5 +:102BB0000A001D320060A0210E0018750000000000 +:102BC0000A001DF800000000AC8000200A001E78FA +:102BD0008E03001400002821026020210E0019A994 +:102BE000240600010A001CC38F8500380A001DB7A7 +:102BF0008F8800388CB000848CB900843C031000AE +:102C00000207482400096940332F007F01AFF825EF +:102C100003E32825ACC50830910700012405000115 +:102C2000026020210E0019A930E600010A001CC331 +:102C30008F850038938F00482403FFFD0A001D3460 +:102C4000AF8F00600A001D342403FFFF02602021C3 +:102C50002410000D0E001A4AA390006800401821AD +:102C60008F8500380A001D320060A0210E00187503 +:102C7000000000009783005C8F8600603070FFFFCB +:102C800000D048232D3900051320FE128F8500380F +:102C9000ACA200EC0A001D2F3062FFFF90C3000DB4 +:102CA000307800085700FFA2920400030260202140 +:102CB000240200100E001A4AA38200682403FFFFBA +:102CC0005443FF9B920400030A001F128F850038B3 +:102CD00090A8000D3106000810C000958F94005494 +:102CE0001680009E026020218E0F000C8CA4002014 +:102CF00055E40005026020218E1F00088CB90024D5 +:102D000013F9003A02602021240200200E001A4A22 +:102D1000A38200682405FFFF1045FEEE2404FFFF98 +:102D20008F8F0044240CFFF72403FF8091E9000DEE +:102D30003C14800E3C0B8000012CC824A1F9000D2E +:102D40008F8F00303C0708008CE731AC8F8D006C12 +:102D500095E500788F99004400ED902130BF7FFF0A +:102D6000001F20400244302130C8007F00C3C0242F +:102D700001147021AD78002CA5D100008F2A002805 +:102D800025420001AF2200288F29002C8E0C002C38 +:102D9000012C6821AF2D002C8E07002CAF270030AE +:102DA0008E050014AF250034973F003A27E4000158 +:102DB000A724003A95F200783C1008008E1031B03C +:102DC0002643000130717FFF1230005C006030212B +:102DD0008F83003002602021240500010E00193489 +:102DE000A46600780A001EA1000020218E070014AE +:102DF0002412FFFF10F200638F8C00388E09001838 +:102E00008D8D00D0152D005D026020218E0A0024DA +:102E10008CA2002811420053240200210E001A4AFD +:102E2000A38200681452FFBE2404FFFF8F85003880 +:102E30000A001D320080A0212402001F0E001A4A41 +:102E4000A38200682409FFFF1049FEA22404FFFFAB +:102E50000A001E548F830054026020210E001A4A7B +:102E6000A38900681450FF518F8500382403FFFFA9 +:102E70000A001D320060A0218CCE00248E0B00249D +:102E8000116EFF2A026020210A001F262402000F73 +:102E90000E001934026020218F8500380A001EE5DB +:102EA000000018218E0900003C05008001259024B7 +:102EB0001640FF452402001A026020210E001A4A23 +:102EC000A3820068240CFFFF144CFECB2404FFFFF8 +:102ED0008F8500380A001D320080A0212403FFFDE9 +:102EE0000060A0210A001D32AF8700602418001D79 +:102EF0000E001A4AA39800682403FFFF1443FEA69D +:102F00002404FFFF8F8500380A001D320080A021B5 +:102F10002412002C0E001A4AA39200682403FFFF1B +:102F20001043FF508F8500380A001ECC9204000326 +:102F3000026020210A001F3C24020024240B800090 +:102F4000006B702431CAFFFF000A13C2305100FF2A +:102F5000001180270A001F6D001033C00A001F3CBB +:102F6000240200278E0600288CAE002C10CE00080C +:102F7000026020210A001F802402001F0A001F8017 +:102F80002402000E026020210A001F802402002576 +:102F90008E04002C1080000D8F8300308C7800741C +:102FA0000304582B5560000C026020218CA80014EB +:102FB0000086A0210114302B10C0FF5A8F8F0044CF +:102FC000026020210A001F802402002202602021CA +:102FD0000A001F80240200230A001F80240200260A +:102FE00027BDFFD8AFB3001CAFB10014AFBF0020A6 +:102FF000AFB20018AFB000103C0280008C5201400C +:103000008C4B01483C048000000B8C02322300FFF3 +:10301000317300FF8C8501B804A0FFFE349001805D +:10302000AE1200008C8701442464FFF024060002E5 +:103030002C830013AE070004A6110008A206000BA3 +:10304000AE1300241060004F8FBF002000044880A2 +:103050003C0A0801254A9510012A40218D040000F0 +:1030600000800008000000003C0308008C6331A8C9 +:1030700031693FFF0009998000728021021370219D +:103080002405FF80264D0100264C00803C02800074 +:1030900031B1007F3198007F31CA007F3C1F800A28 +:1030A0003C1980043C0F800C01C5202401A530246C +:1030B00001853824014F1821AC460024023F4021ED +:1030C00003194821AC470090AC440028AF8300446A +:1030D000AF880038AF8900300E00190001608021F0 +:1030E0003C0380008C6B01B80560FFFE8F870044B5 +:1030F0008F8600383465018090E8000DACB2000086 +:10310000A4B0000600082600000416030002902761 +:10311000001227C21080008124C20088241F608210 +:10312000A4BF0008A0A0000524020002A0A2000B7A +:103130008F8B0030000424003C0827000088902575 +:10314000ACB20010ACA00014ACA00024ACA00028CD +:10315000ACA0002C8D6900382413FF80ACA90018A6 +:1031600090E3000D02638024320500FF10A00005EB +:103170008FBF002090ED000D31AC007FA0EC000D62 +:103180008FBF00208FB3001C8FB200188FB10014C6 +:103190008FB000103C0A10003C0E800027BD0028B4 +:1031A00003E00008ADCA01B8265F01002405FF80D6 +:1031B00033F8007F3C06800003E578243C19800A40 +:1031C00003192021ACCF0024908E00D400AE6824D7 +:1031D00031AC00FF11800024AF840038248E0088B9 +:1031E00095CD00123C0C08008D8C31A831AB3FFF0F +:1031F00001924821000B5180012A40210105202421 +:10320000ACC400283107007F3C06800C00E620217A +:103210009083000D00A31024304500FF10A0FFD8BC +:10322000AF8400449098000D330F001015E0FFD5D7 +:103230008FBF00200E001900000000003C0380003A +:103240008C7901B80720FFFE00000000AE120000DC +:103250008C7F0144AE1F0004A61100082411000257 +:10326000A211000BAE1300243C130801927396D0F8 +:10327000327000015200FFC38FBF00200E00213DBD +:10328000024020210A00205A8FBF00203C1260001B +:103290008E452C083C03F0033462FFFF00A2F824A3 +:1032A000AE5F2C088E582C083C1901C003199825D4 +:1032B000AE532C080A00205A8FBF0020264D010073 +:1032C00031AF007F3C10800A240EFF8001F02821DE +:1032D00001AE60243C0B8000AD6C00241660FFA89A +:1032E000AF85003824110003A0B100FC0A00205A69 +:1032F0008FBF002026480100310A007F3C0B800A66 +:103300002409FF80014B3021010920243C07800063 +:10331000ACE400240A002059AF860038944E001215 +:10332000320C3FFF31CD3FFF15ACFF7D241F608283 +:1033300090D900D42418FF800319782431EA00FFC3 +:103340001140FF770000000024070004A0C700FC24 +:103350008F870044241160842406000DA4B1000866 +:10336000A0A600050A002044240200023C0400013B +:10337000248496BC24030014240200FE3C010800AF +:10338000AC2431EC3C010800AC2331E83C010801DD +:10339000A42296D83C040801248496D80000182161 +:1033A00000643021A0C30004246300012C6500FFE9 +:1033B00054A0FFFC006430213C07080024E7010012 +:1033C00003E00008AF87007800A058210080482162 +:1033D0000000102114A00012000050210A00213921 +:1033E000000000003C010801A42096D83C0508011B +:1033F00094A596D88F8200783C0C0801258C96D82D +:1034000000E2182100AC2021014B302BA0890004E0 +:1034100000001021A460000810C0003901004821FC +:103420008F8600780009384000E940210008388084 +:1034300000E6282190A8000B90B9000A000820405F +:1034400000881021000218800066C021A319000A1C +:103450008F85007800E5782191EE000A91E6000B57 +:10346000000E684001AE6021000C20800085102114 +:10347000A046000B3C030801906396D21060002226 +:103480002462FFFF8F8300383C010801A02296D2FE +:10349000906C00FF1180000400000000906E00FF9F +:1034A00025CDFFFFA06D00FF3C190801973996D884 +:1034B000272300013078FFFF2F0F00FF11E0FFC925 +:1034C000254A00013C010801A42396D83C050801C7 +:1034D00094A596D88F8200783C0C0801258C96D84C +:1034E00000E2182100AC2021014B302BA089000400 +:1034F00000001021A460000814C0FFC90100482189 +:1035000003E000080000000003E0000824020002BD +:1035100027BDFFE0248501002407FF80AFB0001025 +:10352000AFBF0018AFB1001400A718243C108000F2 +:1035300030A4007F3C06800A008628218E110024DA +:10354000AE03002490A200FF14400008AF850038AD +:10355000A0A000098FBF0018AE1100248FB1001485 +:103560008FB0001003E0000827BD002090A900FDE7 +:1035700090A800FF312400FF0E0020EB310500FF72 +:103580008F8500388FBF0018A0A00009AE1100245D +:103590008FB100148FB0001003E0000827BD002099 +:1035A00027BDFFD0AFB20020AFB1001CAFB00018F4 +:1035B000AFBF002CAFB40028AFB300243C0980009B +:1035C0009533011635320C00952F011A3271FFFF29 +:1035D000023280218E08000431EEFFFF248B0100AF +:1035E000010E6821240CFF8025A5FFFF016C5024EB +:1035F0003166007F3C07800AAD2A002400C73021D5 +:10360000AF850074AF8800703C010801A02096D1FE +:1036100090C300090200D02100809821306300FF90 +:103620002862000510400048AF8600382864000278 +:103630001480008E24140001240D00053C010801B3 +:10364000A02D96B590CC00FD3C010801A02096B6B7 +:103650003C010801A02096B790CB000A240AFF8005 +:10366000318500FF014B4824312700FF10E0000C9A +:10367000000058213C128008365100808E2F003007 +:103680008CD0005C01F0702305C0018E8F87007024 +:1036900090D4000A3284007FA0C4000A8F860038CC +:1036A0003C118008363000808E0F00308F8700700C +:1036B00000EF702319C000EE0000000090D4000954 +:1036C00024120002328400FF109202470000000022 +:1036D0008CC2005800E2F82327F9FFFF1B200130BD +:1036E0000000000090C500092408000430A300FF7A +:1036F00010680057240A00013C010801A02A96B571 +:1037000090C900FF252700013C010801A02796B4BD +:103710003C030801906396B5240600051066006A14 +:103720002C780005130000C4000090210003F880ED +:103730003C0408012484955C03E4C8218F25000023 +:1037400000A0000800000000241800FF1078005CB2 +:103750000000000090CC000A90CA00093C08080153 +:10376000910896D13187008000EA48253C01080184 +:10377000A02996BC90C500FD3C140801929496D2F5 +:10378000311100013C010801A02596BD90DF00FE2B +:103790003C010801A03F96BE90D200FF3C01080109 +:1037A000A03296BF8CD900543C010801AC3996C0B8 +:1037B0008CD000583C010801AC3096C48CC3005C2E +:1037C0003C010801AC3496CC3C010801AC2396C8FE +:1037D000162000088FBF002C8FB400288FB3002460 +:1037E0008FB200208FB1001C8FB0001803E00008DA +:1037F00027BD00303C1180009624010E0E000FD42E +:103800003094FFFF3C0B08018D6B96D40260382189 +:1038100002802821AE2B01803C1308018E7396B4E0 +:1038200001602021240600830E00102FAFB300108A +:103830008FBF002C8FB400288FB300248FB20020DC +:103840008FB1001C8FB0001803E0000827BD0030C6 +:103850003C1808008F1831FC270F00013C010800BC +:10386000AC2F31FC0A0021CE000000001474FFB917 +:1038700000000000A0C000FF3C0508008CA531E45A +:103880003C0308008C6331E03C0208008C423204A7 +:103890008F99003834A80001241F00023C01080160 +:1038A000AC2396D43C010801A02896D03C01080125 +:1038B000A02296D3A33F00090A0021878F860038F3 +:1038C0000E00213D000000000A0021CE8F86003846 +:1038D0003C1F080193FF96B42419000113F9022933 +:1038E0008F8700703C100801921096B83C060801C2 +:1038F00090C696B610C000050200A0213C04080145 +:10390000908496B9109001E48F8700780010884069 +:103910008F9F0078023048210009C880033F702142 +:1039200095D80008270F0001A5CF00083C04080126 +:10393000908496B93C05080190A596B60E0020EB40 +:10394000000000008F8700780230202100043080C2 +:1039500000C720218C8500048F82007400A24023C0 +:1039600005020006AC8200048C8A00008F83007080 +:10397000014310235C400001AC8300008F860038B7 +:1039800090CB00FF2D6C00025580002D2414000107 +:103990000230F821001F40800107282190B9000B58 +:1039A0008CAE00040019C04003197821000F188064 +:1039B000006710218C4D000001AE88232630FFFFE8 +:1039C0005E00001F241400018C4400048CAA000037 +:1039D000008A482319200019240E00043C01080124 +:1039E000A02E96B590AD000B8CAB0004000D884066 +:1039F000022D802100101080004710218C4400040B +:103A000001646023058202009443000890DF00FEF9 +:103A100090B9000B33E500FF54B900040107A02161 +:103A2000A0D400FE8F8700780107A0219284000BAC +:103A30000E0020EB240500018F86003824140001BD +:103A4000125400962E500001160000423C08FFFF61 +:103A5000241900021659FF3F00000000A0C000FF1B +:103A60008F860038A0D200090A0021CE8F86003848 +:103A700090C700092404000230E300FF1064016FC6 +:103A800024090004106901528F8800748CCE005400 +:103A9000010E682325B100010620017524180004D9 +:103AA0003C010801A03896B53C010801A02096B45D +:103AB00090D400FD90D200FF2E4F000215E0FF14BD +:103AC000328400FF000438408F89007890DF00FFC7 +:103AD00000E41021000220800089C8212FE50002A7 +:103AE0009324000B14A0FF0A2407000200041840CE +:103AF0000064802100105880016928218CAC0004EA +:103B0000010C50230540FF02000000003C030801A7 +:103B1000906396B614600005246F00013C01080113 +:103B2000A02496B93C010801A02796B73C010801E2 +:103B3000A02F96B690CE00FF24E7000131CD00FF04 +:103B400001A7882B1220FFE990A4000B0A0021BDD9 +:103B5000000000003C0508018CA596B43C1200044E +:103B600000A8F82413F20006240200053C0908010D +:103B7000912996B5152000022402000324020005B5 +:103B80003C010801A02296D190C700FF14E001205B +:103B900024020002A0C200090A0021CE8F8600384C +:103BA00090CC00FF1180FEDA240A00018F8C007493 +:103BB0008F890078240F0003018068211160001EA6 +:103BC000240E0002000540400105A02100142080C1 +:103BD000008990218E510004019180230600FECCC3 +:103BE000000000003C020801904296B61440000517 +:103BF000245800013C010801A02A96B73C010801A5 +:103C0000A02596B93C010801A03896B690DF00FFC8 +:103C1000010510210002C88033E500FF254A00019C +:103C20000329202100AA402B1500FEB99085000B26 +:103C30001560FFE5000540400005404001051821E2 +:103C4000000310803C010801A02A96B43C01080141 +:103C5000A02596B8004918218C64000400E4F823DC +:103C600027F9FFFF1F20FFE9000000008C63000020 +:103C700000E358230560013A01A3882310E30117EC +:103C80000184C0231B00FEA2000000003C010801CB +:103C9000A02E96B50A0022FC240B0001240E00047D +:103CA000A0CE00093C0D08008DAD31F88F8600389C +:103CB00025A200013C010800AC2231F80A0021CE07 +:103CC000000000008CD9005C00F9C0231F00FE7BBF +:103CD000000000008CDF005C10FFFF658F84007423 +:103CE0008CC3005C00834023250200011C40FF6060 +:103CF000000000008CC9005C2487000100E9282B2B +:103D000010A0FE943C0D80008DAB01043C0C000122 +:103D1000016C50241140FE8F240200103C01080168 +:103D2000A02296D10A0021CE000000008F910074DD +:103D30008F86003826220001ACC2005C0A0022896E +:103D4000241400018F8700382404FF80000088219C +:103D500090E9000A2414000101243025A0E6000A9D +:103D60003C05080190A596B63C040801908496B9DC +:103D70000E0020EB000000008F8600388F85007851 +:103D800090C800FD310700FF000740400107F821FF +:103D9000001FC0800305C8219323000BA0C300FDB2 +:103DA0008F8500788F86003803056021918F000B86 +:103DB000000F704001CF6821000D808002051021A6 +:103DC0008C4B0000ACCB00548D8400048F830074B6 +:103DD0000064502319400002248200012462000183 +:103DE00001074821ACC2005C0009308000C54021B9 +:103DF00000E02021240500010E0020EB9110000BB3 +:103E00008F86003890C500FF10A0FF0C0010704096 +:103E10008F85007801D06821000D10800045582161 +:103E20008D6400008F8C00740184502325470001AD +:103E300004E0FF02263100013C030801906396B6BE +:103E40002E2F0002247800013C010801A03896B60C +:103E50003C010801A03496B711E0FEF802003821B9 +:103E60000A00235C000740408F8400388F83007471 +:103E70008C85005800A340230502FE9AAC830058AD +:103E80000A002232000000003C07080190E796D2A9 +:103E9000240200FF10E200BE8F8600383C110801AA +:103EA000963196DA3C030801246396D82625000152 +:103EB0003230FFFF30ABFFFF020360212D6A00FFAD +:103EC0001540008D918700043C010801A42096DA7A +:103ED0008F8800380007484001272821911800FFEB +:103EE000000530802405000127140001A11400FF03 +:103EF0003C120801925296D28F8800788F8E007003 +:103F0000264F000100C820213C010801A02F96D2B5 +:103F1000AC8E00008F8D0074A4850008AC8D000469 +:103F20003C030801906396B4146000770000902170 +:103F30003C010801A02596B4A087000B8F8C007867 +:103F400000CC5021A147000A8F820038A04700FD15 +:103F50008F840038A08700FE8F8600388F9F007006 +:103F6000ACDF00548F990074ACD900588F8D007865 +:103F70000127C02100185880016DA021928F000AEE +:103F8000000F704001CF182100038880022D80218E +:103F9000A207000B8F86007801666021918A000BD2 +:103FA000000A1040004A20210004288000A6402179 +:103FB000A107000A3C07800834E900808D22003008 +:103FC0008F860038ACC2005C0A00228924140001EC +:103FD00090CA00FF1540FEAD8F880074A0C4000990 +:103FE0000A0021CE8F860038A0C000FD8F980038CF +:103FF00024060001A30000FE3C010801A02696B59E +:104000003C010801A02096B40A0021BD0000000078 +:1040100090CB00FF3C040801908496D3316C00FFE4 +:104020000184502B1540000F2402000324020004D9 +:10403000A0C200090A0021CE8F86003890C3000A72 +:104040002410FF8002035824316C00FF1180FDC151 +:10405000000000003C010801A02096B50A0021BD27 +:1040600000000000A0C200090A0021CE8F8600389F +:1040700090D4000A2412FF8002544824312800FF03 +:104080001500FFF4240200083C010801A02296D18B +:104090000A0021CE00000000001088408F8B0070C5 +:1040A000023018210003688001A72021AC8B00009A +:1040B0008F8A0074240C0001A48C0008AC8A0004D0 +:1040C0003C05080190A596B62402000110A2FE1E30 +:1040D00024A5FFFF0A0022489084000B0184A0233E +:1040E0001A80FD8B000000003C010801A02E96B54F +:1040F0000A0022FC240B00013C010801A42596DAE9 +:104100000A0023AE8F880038240B0001106B0022B8 +:104110008F9800388F85003890BF00FF33F900FF7B +:104120001079002B000000003C1F080193FF96B897 +:10413000001FC840033FC0210018A08002887821DA +:1041400091EE000AA08E000A8F8D00783C030801D2 +:10415000906396B800CD88210A0023D4A223000BD7 +:10416000263000010600003101A490230640002BF8 +:10417000240200033C010801A02F96B50A0022FC8E +:10418000240B00018F8900380A002232AD27005429 +:104190000A00228824120001931400FDA094000B51 +:1041A0008F8800388F8F0078910E00FE00CF682135 +:1041B000A1AE000A8F910038A22700FD8F83007006 +:1041C0008F900038AE0300540A0023D58F8D0078FD +:1041D00090B000FEA090000A8F8B00388F8C007882 +:1041E000916A00FD00CC1021A04A000B8F8400389A +:1041F000A08700FE8F8600748F850038ACA600581B +:104200000A0023D58F8D007894B80008ACA4000470 +:10421000030378210A00227CA4AF00083C010801B6 +:10422000A02296B50A0021BD0000000090CF000931 +:10423000240D000431EE00FF11CDFD8524020001A4 +:104240003C010801A02296B50A0021BD0000000033 +:10425000080033440800334408003420080033F4D5 +:10426000080033D808003328080033280800332812 +:104270000800334C8008010080080080800800009E +:104280005F865437E4AC62CC50103A4536621985EB +:10429000BF14C0E81BC27A1E84F4B556094EA6FEB0 +:1042A0007DDA01E7C04D748108005A7408005AB8DD +:1042B00008005A5C08005A5C08005A5C08005A5C06 +:1042C00008005A7408005A5C08005A5C08005AC07A +:1042D00008005A5C080059D408005A5C08005A5C6F +:1042E00008005AC008005A5C08005A5C08005A5C72 +:1042F00008005A5C08005A5C08005A5C08005A5CC6 +:1043000008005A5C08005A5C08005A5C08005A947D +:1043100008005A5C08005A9408005A5C08005A5C6D +:1043200008005A5C08005A9808005A9408005A5C21 +:1043300008005A5C08005A5C08005A5C08005A5C85 +:1043400008005A5C08005A5C08005A5C08005A5C75 +:1043500008005A5C08005A5C08005A5C08005A5C65 +:1043600008005A5C08005A5C08005A5C08005A5C55 +:1043700008005A5C08005A5C08005A5C08005A9809 +:1043800008005A9808005A5C08005A9808005A5CBD +:1043900008005A5C08005A5C08005A5C08005A5C25 +:1043A00008005A5C08005A5C08005A5C08005A5C15 +:1043B00008005A5C08005A5C08005A5C08005A5C05 +:1043C00008005A5C08005A5C08005A5C08005A5CF5 +:1043D00008005A5C08005A5C08005A5C08005A5CE5 +:1043E00008005A5C08005A5C08005A5C08005A5CD5 +:1043F00008005A5C08005A5C08005A5C08005A5CC5 +:1044000008005A5C08005A5C08005A5C08005A5CB4 +:1044100008005A5C08005A5C08005A5C08005A5CA4 +:1044200008005A5C08005A5C08005A5C08005A5C94 +:1044300008005A5C08005A5C08005A5C08005A5C84 +:1044400008005A5C08005A5C08005A5C08005A5C74 +:1044500008005A5C08005A5C08005A5C08005A5C64 +:1044600008005A5C08005A5C08005A5C08005A5C54 +:1044700008005A5C08005A5C08005A5C08005A5C44 +:1044800008005A5C08005A5C08005A5C08005A5C34 +:1044900008005A5C08005A5C08005A5C08005A5C24 +:1044A00008005A5C08005A5C08005ADC0800782CA6 +:1044B00008007A90080078380800762C08007838D0 +:1044C000080078C4080078380800762C0800762C9C +:1044D0000800762C0800762C0800762C0800762C34 +:1044E0000800762C0800762C0800762C0800762C24 +:1044F00008007858080078480800762C0800762CC8 +:104500000800762C0800762C0800762C0800762C03 +:104510000800762C0800762C0800762C0800762CF3 +:104520000800762C0800762C08007848080082D80D +:1045300008008164080082A008008164080082707D +:104540000800804C080081640800816408008164D0 +:1045500008008164080081640800816408008164A7 +:104560000800816408008164080081640800816497 +:10457000080081640800818C08008D1008008E6C92 +:0C45800008008E4C080088B408008D284C +:04458C000A000124FC +:1045900000000000000000000000000D7470613693 +:1045A0002E322E31610000000602010100000000E1 +:1045B00000000000000000000000000000000000FB +:1045C00000000000000000000000000000000000EB +:1045D00000000000000000000000000000000000DB +:1045E00000000000000000000000000000000000CB +:1045F00000000000000000000000000000000000BB +:1046000000000000000000000000000000000000AA +:10461000000000000000000000000000000000009A +:1046200010000003000000000000000D0000000D5D +:104630003C020800244217203C03080024632A108F +:10464000AC4000000043202B1480FFFD24420004F6 +:104650003C1D080037BD2FFC03A0F0213C100800D2 +:10466000261004903C1C0800279C17200E000262B4 +:10467000000000000000000D2402FF8027BDFFE0C5 +:1046800000821024AFB00010AF420020AFBF00186E +:10469000AFB10014936500043084007F03441821F7 +:1046A0003C0200080062182130A500200360802130 +:1046B0003C080111277B000814A000022466005C5E +:1046C00024660058920200049743010492040004F7 +:1046D0003047000F3063FFFF30840040006728231D +:1046E00010800009000048219202000530420004B9 +:1046F000104000050000000010A0000300000000B2 +:1047000024A5FFFC240900049202000530420004A5 +:10471000104000120000000010A000100000000077 +:104720009602000200A72021010440252442FFFE3A +:10473000A7421016920300042402FF8000431024B5 +:10474000304200FF104000033C0204000A000174E4 +:10475000010240258CC20000AF4210188F42017840 +:104760000440FFFE2402000AA74201409602000214 +:1047700024040009304200070002102330420007E1 +:10478000A7420142960200022442FFFEA7420144D2 +:10479000A740014697420104A74201488F42010801 +:1047A0003042002050400001240400019202000425 +:1047B00030420010144000023483001000801821A1 +:1047C000A743014A000000000000000000000000B4 +:1047D00000000000AF4810000000000000000000D2 +:1047E00000000000000000008F4210000441FFFEA6 +:1047F0003102FFFF10400007000000009202000499 +:104800003042004014400003000000008F421018A6 +:10481000ACC20000960200063042FFFF24420002B4 +:10482000000210430002104003628821962200001B +:104830001120000D3044FFFF00A710218F830038A6 +:104840008F45101C000210820002108000431021CE +:10485000AC45000030A6FFFF0E00058D00052C02C0 +:1048600000402021A6220000920300042402FF80C1 +:1048700000431024304200FF1040001F00000000E1 +:1048800092020005304200021040001B00000000B0 +:104890009742100C2442FFFEA742101600000000B1 +:1048A0003C02040034420030AF421000000000001F +:1048B0000000000000000000000000008F42100017 +:1048C0000441FFFE000000009742100C8F45101CB1 +:1048D0003042FFFF244200300002108200021080AC +:1048E000005B1021AC45000030A6FFFF0E00058DD7 +:1048F00000052C02A6220000960400022484000871 +:104900000E0001E93084FFFF974401040E0001F717 +:104910003084FFFF8FBF00188FB100148FB00010DC +:104920003C02100027BD002003E00008AF420178E0 +:104930003084FFFF308200078F8500241040000282 +:10494000248300073064FFF800A4102130421FFFC9 +:1049500003421821247B4000AF850028AF82002449 +:1049600003E00008AF4200843084FFFF3082000F74 +:104970008F85002C8F860034104000022483000FA6 +:104980003064FFF000A410210046182BAF850030E2 +:104990000046202314600002AF82002CAF84002C5C +:1049A0008F82002C340480000342182100641821F7 +:1049B000AF83003803E00008AF4200808F8200140C +:1049C000104000088F8200048F82FFDC1440000535 +:1049D0008F8200043C02FFBF3442FFFF008220248C +:1049E0008F82000430430006240200021062000F90 +:1049F0003C0201012C620003504000052402000427 +:104A00001060000F3C0200010A00023000000000AC +:104A100010620005240200061462000C3C02011121 +:104A20000A000229008210253C0200110082102594 +:104A3000AF421000240200010A000230AF82000CD5 +:104A400000821025AF421000AF80000C0000000073 +:104A5000000000000000000003E00008000000006B +:104A60008F82000C10400004000000008F421000F4 +:104A70000441FFFE0000000003E000080000000009 +:104A80008F8200102443F800000231C224C2FFF0DC +:104A90002C63030110600003000210420A00025759 +:104AA000AC8200008F85001800C5102B1440000B4D +:104AB0000000182100C51023244700018F82001C2C +:104AC00000A210212442FFFF0046102B5440000496 +:104AD0002402FFFF0A000257AC8700002402FFFFF8 +:104AE0000A000260AC8200008C82000000021940C3 +:104AF000006218210003188000621821000318804A +:104B00003C0208002442175C0062182103E0000800 +:104B10000060102127BDFFD8AFBF0020AFB1001C3F +:104B2000AFB000183C0460088C8250002403FF7F63 +:104B30003C066000004310243442380CAC82500024 +:104B40008CC24C1C3C1A8000000216023042000F3E +:104B500010400007AF82001C8CC34C1C3C02001F9D +:104B60003442FC0000621824000319C2AF8300180D +:104B70008F420008275B400034420001AF4200082A +:104B8000AF8000243C02601CAF400080AF40008436 +:104B90008C4500088CC308083402800003422021A1 +:104BA0002402FFF0006218243C0200803C0108004F +:104BB000AC2204203C025709AF8400381462000480 +:104BC000AF850034240200010A000292AF82001473 +:104BD000AF8000148F4200003842000130420001D3 +:104BE0001440FFFC8F8200141040001600000000EB +:104BF00097420104104000058F83000014600007F5 +:104C00002462FFFF0A0002A72C62000A2C62001037 +:104C1000504000048F83000024620001AF82000036 +:104C20008F8300002C62000A144000032C620007EE +:104C30000A0002AEAF80FFDC104000022402000137 +:104C4000AF82FFDC8F4301088F44010030622000F7 +:104C5000AF83000410400008AF8400103C0208003D +:104C60008C42042C244200013C010800AC22042C9C +:104C70000A00058A3C0240003065020014A00003CF +:104C800024020F001482026024020D0097420104E6 +:104C9000104002C83C02400030624000144000ADA9 +:104CA0008F8200388C4400088F4201780440FFFE58 +:104CB00024020800AF42017824020008A742014004 +:104CC000A7400142974201048F8400043051FFFF46 +:104CD0003082000110400007022080212623FFFEC1 +:104CE000240200023070FFFFA74201460A0002DBE7 +:104CF000A7430148A74001463C0208008C42043CFF +:104D00001440000D8F8300103082002014400002F8 +:104D10002403000924030001006020218F83001078 +:104D2000240209005062000134840004A744014AAF +:104D30000A0002F60000000024020F0014620005C1 +:104D400030820020144000062403000D0A0002F502 +:104D50002403000514400002240300092403000179 +:104D6000A743014A3C0208008C4204203C0400484E +:104D70000E00020C004420250E0002350000000049 +:104D80008F82000C1040003E000000008F42100097 +:104D90003C03002000431024104000398F8200049F +:104DA000304200021040003600000000974210140C +:104DB0001440003300000000974210088F8800382C +:104DC0003042FFFF244200060002188200033880B0 +:104DD00000E83021304300018CC400001060000462 +:104DE000304200030000000D0A00033700E81021E4 +:104DF000544000103084FFFF3C05FFFF0085202455 +:104E0000008518260003182B0004102B00431024E3 +:104E10001040000500000000000000000000000D30 +:104E200000000000240002228CC200000A000336A9 +:104E3000004520253883FFFF0003182B0004102BAA +:104E40000043102410400005000000000000000096 +:104E50000000000D000000002400022B8CC20000A6 +:104E60003444FFFF00E81021AC4400003C0208007D +:104E70008C420430244200013C010800AC22043082 +:104E80008F6200008F840038AF8200088C8300009E +:104E90003402FFFF1462000F000010213C050800DF +:104EA0008CA504543C0408008C84045000B02821D4 +:104EB00000B0302B00822021008620213C01080018 +:104EC000AC2504543C010800AC2404500A000580C1 +:104ED000240400088C820000304201001040000FC2 +:104EE000000010213C0508008CA5044C3C0408007F +:104EF0008C84044800B0282100B0302B008220218F +:104F0000008620213C010800AC25044C3C0108002F +:104F1000AC2404480A000580240400083C0508006D +:104F20008CA504443C0408008C84044000B0282173 +:104F300000B0302B00822021008620213C01080097 +:104F4000AC2504443C010800AC2404400A00058060 +:104F5000240400088F6200088F620000000216021D +:104F6000304300F0240200301062000524020040AB +:104F7000106200E08F8200200A00058824420001B0 +:104F800014A0000500000000000000000000000D5B +:104F900000000000240002568F4201780440FFFE0A +:104FA000000000000E00023D27A400101440000580 +:104FB00000408021000000000000000D0000000003 +:104FC0002400025D8E020000104000050000000079 +:104FD000000000000000000D00000000240002603E +:104FE0008F62000C04430003240200010A00042E17 +:104FF000AE000000AE0200008F8200388C4800082E +:10500000A20000078F65000C8F64000430A3FFFF2F +:105010000004240200852023308200FF0043102179 +:1050200024420005000230832CC20081A605000A3C +:1050300014400005A2040004000000000000000D60 +:1050400000000000240002788F8500380E0005ABB8 +:10505000260400148F6200048F430108A602000892 +:105060003C021000006218241060000800000000DC +:1050700097420104920300072442FFEC34630002CC +:105080003045FFFF0A0003C3A20300079742010453 +:105090002442FFF03045FFFF960600082CC20013A3 +:1050A00054400005920300079202000734420001B9 +:1050B000A20200079203000724020001106200050B +:1050C000240200031062000B8F8200380A0003E004 +:1050D00030C6FFFF8F8200383C04FFFF8C43000C7A +:1050E0000064182400651825AC43000C0A0003E096 +:1050F00030C6FFFF3C04FFFF8C43001000641824FF +:1051000000651825AC43001030C6FFFF24C2000222 +:1051100000021083A20200058F830038304200FF96 +:1051200000021080004328218CA800008CA20000FF +:1051300024030004000217021443001200000000C0 +:10514000974201043C03FFFF010318243042FFFF94 +:10515000004610232442FFFE00624025ACA8000058 +:1051600092030005306200FF000210800050102101 +:10517000904200143042000F004310210A00041531 +:10518000A20200068CA40004974201049603000AC0 +:105190003088FFFF3042FFFF004610232442FFD635 +:1051A0000002140001024025ACA80004920200078E +:1051B000920400052463002800031883006418216A +:1051C00034420004A2030006A20200078F820004FA +:1051D0002403FFFB3442000200431024AF8200048A +:1051E000920300068F87003800031880007010219A +:1051F0008C4400203C02FFF63442FFFF0082402432 +:1052000000671821AE04000CAC68000C9205000683 +:105210003C03FF7F8E02000C0005288000B0202197 +:105220003463FFFF010330249488002600A728215F +:1052300000431024AE02000CAC860020AC88002491 +:10524000ACA8001024020010A74201402402000272 +:10525000A7400142A7400144A742014697420104EA +:105260003C0400082442FFFEA7420148240200013A +:105270000E00020CA742014A9603000A92020004A3 +:105280000043102124420002304200070002102394 +:10529000304200070E000235AE0200108F6200009F +:1052A0003C0308008C63044424040010AF8200080F +:1052B000974201043042FFFF2442FFFE00403821A4 +:1052C000000237C33C0208008C42044000671821EA +:1052D0000067282B00461021004510213C010800E2 +:1052E000AC2304443C010800AC2204400A0005152C +:1052F0000000000014A000050000000000000000F5 +:105300000000000D000000002400030A8F42017815 +:105310000440FFFE000000000E00023D27A4001420 +:105320001440000500408021000000000000000D36 +:1053300000000000240003118E020000544000060B +:1053400092020007000000000000000D00000000B5 +:105350002400031C920200073042000410400005A4 +:105360008F8200042403FFFB344200020043102418 +:10537000AF8200048F620004044300089202000719 +:10538000920200068E03000CAE00000000021080A6 +:1053900000501021AC43002092020007304200046C +:1053A000544000099602000A920200053C030001E5 +:1053B00000021080005010218C46001800C33021DC +:1053C000AC4600189602000A9206000427710008F5 +:1053D0000220202100C2302124C600052605001429 +:1053E0000E0005AB00063082920400068F650004B3 +:1053F0003C027FFF00042080009120218C83000468 +:105400003442FFFF00A2282400651821AC83000469 +:105410009202000792040005920300043042000447 +:105420001040001496070008308400FF000420801C +:10543000009120218C860004974201049605000A01 +:10544000306300FF3042FFFF004310210045102170 +:1054500030E3FFFF004310232442FFD830C6FFFF94 +:105460000002140000C23025AC8600040A0004C902 +:1054700092030007308500FF0005288000B1282135 +:105480008CA4000097420104306300FF3042FFFF0C +:1054900000431021004710233C03FFFF008320241A +:1054A0003042FFFF00822025ACA4000092030007D9 +:1054B0002402000110620006000000002402000324 +:1054C00010620011000000000A0004EC8E030010BE +:1054D00097420104920300049605000A8E24000CF2 +:1054E00000431021004510212442FFF23C03FFFF3E +:1054F000008320243042FFFF00822025AE24000CD0 +:105500000A0004EC8E030010974201049203000489 +:105510009605000A8E24001000431021004510213A +:105520002442FFEE3C03FFFF008320243042FFFFB4 +:1055300000822025AE2400108E0300102402000AF1 +:10554000A7420140A74301429603000A92020004C9 +:105550003C04004000431021A7420144A7400146FB +:1055600097420104A7420148240200010E00020CE8 +:10557000A742014A0E000235000000008F620000C1 +:105580009203000400002021AF820008974201042A +:105590009606000A3042FFFF0062182100602821B1 +:1055A0003C0308008C6304443C0208008C42044025 +:1055B00000651821004410210065382B0047102198 +:1055C0003C010800AC2304443C010800AC22044028 +:1055D00092040004008620212484000A3084FFFF06 +:1055E0000E0001E900000000974401043084FFFF31 +:1055F0000E0001F7000000003C021000AF420178ED +:105600000A0005878F82002014820027306200067E +:1056100097420104104000673C02400030624000A5 +:105620001040000500000000000000000000000D18 +:1056300000000000240004208F4201780440FFFE97 +:1056400024020800AF42017824020008A74201406A +:10565000A74001428F8200049743010430420001B9 +:10566000104000073070FFFF2603FFFE24020002F7 +:10567000A7420146A74301480A00053F2402000D46 +:10568000A74001462402000DA742014A8F62000094 +:1056900024040008AF8200080E0001E900000000A9 +:1056A0000A00051902002021104000423C0240007F +:1056B00093620000304300F02402001010620005E5 +:1056C00024020070106200358F8200200A000588D5 +:1056D000244200018F620000974301043050FFFF15 +:1056E0003071FFFF8F4201780440FFFE3202000755 +:1056F00000021023304200072403000A2604FFFEA4 +:10570000A7430140A7420142A7440144A7400146E4 +:10571000A75101488F420108304200201440000286 +:105720002403000924030001A743014A0E00020CD0 +:105730003C0400400E000235000000003C07080059 +:105740008CE70444021110212442FFFE3C060800AD +:105750008CC604400040182100E3382100001021CD +:105760008F65000000E3402B00C2302126040008B2 +:1057700000C830213084FFFFAF8500083C010800DD +:10578000AC2704443C010800AC2604400E0001E9AB +:10579000000000000A000519022020210E00013B34 +:1057A000000000008F82002024420001AF82002010 +:1057B0003C024000AF4201380A00029200000000A3 +:1057C0003084FFFF30C6FFFF00052C0000A628250F +:1057D0003882FFFF004510210045282B004510218D +:1057E00000021C023042FFFF0043102100021C0295 +:1057F0003042FFFF004310213842FFFF03E0000862 +:105800003042FFFF3084FFFF30A5FFFF000018216A +:1058100010800007000000003082000110400002EC +:1058200000042042006518210A0005A10005284057 +:1058300003E000080060102110C0000624C6FFFF2E +:105840008CA2000024A50004AC8200000A0005AB75 +:105850002484000403E000080000000010A00008F9 +:1058600024A3FFFFAC860000000000000000000041 +:105870002402FFFF2463FFFF1462FFFA2484000464 +:0858800003E000080000000035 +:04588800000000011B +:04588C000A00002AE4 +:1058900000000000000000000000000D7478703669 +:1058A0002E322E31610000000602010000000000CF +:1058B000000001360000EA60000000000000000067 +:1058C00000000000000000000000000000000000D8 +:1058D00000000000000000000000000000000000C8 +:1058E00000000000000000000000000000000016A2 +:1058F00000000000000000000000000000000000A8 +:105900000000000000000000000000000000000097 +:105910000000000000000000000000000000000087 +:10592000000000000000138800000000000005DCFB +:105930000000000000000000100000030000000054 +:105940000000000D0000000D3C02080024423D68EC +:105950003C0308002463401CAC4000000043202BA3 +:105960001480FFFD244200043C1D080037BD7FFC6D +:1059700003A0F0213C100800261000A83C1C0800E1 +:10598000279C3D680E00044E000000000000000D42 +:1059900027BDFFB4AFA10000AFA20004AFA3000871 +:1059A000AFA4000CAFA50010AFA60014AFA700185D +:1059B000AFA8001CAFA90020AFAA0024AFAB0028FD +:1059C000AFAC002CAFAD0030AFAE0034AFAF00389D +:1059D000AFB8003CAFB90040AFBC0044AFBF004817 +:1059E0000E000591000000008FBF00488FBC0044EE +:1059F0008FB900408FB8003C8FAF00388FAE0034B5 +:105A00008FAD00308FAC002C8FAB00288FAA002404 +:105A10008FA900208FA8001C8FA700188FA6001444 +:105A20008FA500108FA4000C8FA300088FA2000484 +:105A30008FA1000027BD004C3C1B60048F7A5030C2 +:105A4000377B502803400008AF7A00008F86003C67 +:105A50003C0390003C0280000086282500A32025FE +:105A6000AC4400203C0380008C67002004E0FFFE73 +:105A70000000000003E00008000000000A000070C1 +:105A8000240400018F85003C3C0480003483000125 +:105A900000A3102503E00008AC82002003E000080A +:105AA000000010213084FFFF30A5FFFF10800007A9 +:105AB0000000182130820001104000020004204242 +:105AC000006518211480FFFB0005284003E0000852 +:105AD0000060102110C00007000000008CA2000030 +:105AE00024C6FFFF24A50004AC82000014C0FFFB05 +:105AF0002484000403E000080000000010A0000857 +:105B000024A3FFFFAC86000000000000000000009E +:105B10002402FFFF2463FFFF1462FFFA24840004C1 +:105B200003E000080000000090AA00318FAB0010D5 +:105B30008CAC00403C0300FF8D680004AD6C00207D +:105B40008CAD004400E060213462FFFFAD6D0024A5 +:105B50008CA700483C09FF000109C024AD6700285C +:105B60008CAE004C0182C82403197825AD6F000467 +:105B7000AD6E002C8CAD0038314A00FFAD6D001CBD +:105B800094A900323128FFFFAD68001090A70030C3 +:105B9000A5600002A1600004A167000090A300328C +:105BA000306200FF00021982106000052405000128 +:105BB0001065000E0000000003E00008A16A00016B +:105BC0008CD80028354A0080AD7800188CCF00149E +:105BD000AD6F00148CCE0030AD6E00088CC4002C6C +:105BE000A16A000103E00008AD64000C8CCD001C2C +:105BF000AD6D00188CC90014AD6900148CC8002468 +:105C0000AD6800088CC70020AD67000C8CC2001482 +:105C10008C8300700043C82B132000070000000095 +:105C20008CC20014144CFFE400000000354A0080D0 +:105C300003E00008A16A00018C8200700A0000E6FF +:105C4000000000009089003027BDFFF88FA8001CDD +:105C5000A3A900008FA300003C0DFF8035A2FFFF29 +:105C60008CAC002C00625824AFAB0000A1000004F3 +:105C700000C05821A7A000028D06000400A0482102 +:105C80000167C8218FA50000008050213C18FF7FCC +:105C9000032C20263C0E00FF2C8C0001370FFFFF49 +:105CA00035CDFFFF3C02FF0000AFC82400EDC0244B +:105CB00000C27824000C1DC00323682501F870255C +:105CC000AD0D0000AD0E00048D240024AFAD00002A +:105CD000AD0400088D2C00202404FFFFAD0C000C47 +:105CE0009547003230E6FFFFAD06001091450048B1 +:105CF00030A200FF000219C2506000018D24003460 +:105D0000AD0400148D4700388FAA001827BD000885 +:105D1000AD0B0028AD0A0024AD07001CAD00002C1F +:105D2000AD00001803E00008AD00002027BDFFE033 +:105D3000AFB20018AFB10014AFB00010AFBF001C7D +:105D40009098003000C088213C0D00FF330F007F89 +:105D5000A0CF0000908E003135ACFFFF3C0AFF0061 +:105D6000A0CE000194A6001EA22000048CAB00145B +:105D70008E29000400A08021016C2824012A4024DF +:105D80000080902101052025A6260002AE240004F3 +:105D900026050020262400080E000092240600029A +:105DA00092470030260500282624001400071E0014 +:105DB0000003160324060004044000032403FFFF2D +:105DC000965900323323FFFF0E000092AE230010DD +:105DD000262400248FBF001C8FB200188FB100143E +:105DE0008FB0001024050003000030210A00009C41 +:105DF00027BD002027BDFFD8AFB1001CAFB00018F1 +:105E0000AFBF002090A900302402000100E0502123 +:105E10003123003F00A040218FB000400080882146 +:105E200000C04821106200148FA70038240B000521 +:105E300000A0202100C02821106B00130200302197 +:105E40000E000128000000009225007C30A4000212 +:105E50001080000326030030AE000030260300341B +:105E60008FBF00208FB1001C8FB000180060102180 +:105E700003E0000827BD00280E0000A7AFB0001007 +:105E80000A00016F000000008FA3003C01002021E8 +:105E90000120282101403021AFA300100E0000EEA8 +:105EA000AFB000140A00016F000000003C06800043 +:105EB00034C20E008C4400108F850044ACA4002036 +:105EC0008C43001803E00008ACA300243C068000CB +:105ED00034C20E008C4400148F850044ACA4002012 +:105EE0008C43001C03E00008ACA300249382000C48 +:105EF0001040001B2483000F2404FFF000643824AA +:105F000010E00019978B00109784000E9389000D04 +:105F10003C0A601C0A0001AC0164402301037021AB +:105F2000006428231126000231C2FFFF30A2FFFFC8 +:105F30000047302B50C0000E00E448218D4D000C6E +:105F400031A3FFFF00036400000C2C0304A1FFF346 +:105F50000000302130637FFF0A0001A42406000105 +:105F600003E00008000000009784000E00E44821D0 +:105F70003123FFFF3168FFFF0068382B54E0FFF842 +:105F8000A783000E938A000D11400005240F000125 +:105F9000006BC023A380000D03E00008A798000E4B +:105FA000006BC023A38F000D03E00008A798000E2C +:105FB00003E000080000000027BDFFE8AFB00010BC +:105FC0003C10800036030140308BFFFF93AA002B6A +:105FD000AFBF0014A46B000436040E0094880016B2 +:105FE00030C600FF8FA90030A4680006AC65000829 +:105FF000A0660012A46A001AAC6700208FA5002CCE +:10600000A4690018012020210E000198AC6500143D +:106010003C021000AE0201788FBF00148FB0001058 +:1060200003E0000827BD00188F85000024840007C6 +:1060300027BDFFF83084FFF83C06800094CB008A2F +:10604000316AFFFFAFAA00008FA90000012540239D +:106050002507FFFF30E31FFF0064102B1440FFF7FC +:1060600000056882000D288034CC400000AC10216F +:1060700003E0000827BD00088F8200002486000787 +:1060800030C5FFF800A2182130641FFF03E00008AC +:10609000AF8400008F87003C8F84004427BDFFB091 +:1060A000AFB70044AFB40038AFB1002CAFBF004869 +:1060B000AFB60040AFB5003CAFB30034AFB2003074 +:1060C000AFB000283C0B80008C860024AD670080B8 +:1060D0008C8A002035670E0035690100ACEA00109B +:1060E0008C8800248D2500040000B821ACE800183D +:1060F0008CE3001000A688230000A021ACE300146C +:106100008CE20018ACE2001C122000FE00E0B0217E +:10611000936C0008118000F400000000976F0010DD +:1061200031EEFFFF022E682B15A000EF00000000EB +:10613000977200103250FFFFAED000003C03800089 +:106140008C740000329300081260FFFD0000000014 +:1061500096D800088EC700043305FFFF30B5000154 +:1061600012A000E4000000000000000D30BFA040BD +:106170002419004013F9011B30B4A000128000DF85 +:106180000000000093730008126000080000000087 +:10619000976D001031ACFFFF00EC202B1080000346 +:1061A00030AE004011C000D500000000A7850040BF +:1061B000AF8700389363000802202821AFB1002088 +:1061C000146000F527B40020AF60000C978F0040EA +:1061D00031F1400016200002240300162403000EB3 +:1061E00024054007A363000AAF650014938A0042A8 +:1061F0008F7000143155000100151240020248252D +:10620000AF690014979F00408F78001433F9001095 +:1062100003194025AF6800149792004032470008E8 +:1062200010E0016E000000008F6700143C121000A7 +:106230003C11800000F27825AF6F001436230E0069 +:10624000946E000A3C0D81002406000E31CCFFFF45 +:10625000018D2025AF640004A36600029373000A39 +:106260003406FFFC266B0004A36B000A97980040DD +:10627000330820001100015F000000003C05800091 +:1062800034A90E00979900409538000C978700407C +:10629000001940423312C0003103000300127B0397 +:1062A00030F11000006F68250011720301AE602507 +:1062B000000C20C0A764001297930040936A000A64 +:1062C000001359823175003C02AA10212450003C71 +:1062D000A3700009953F000C33F93FFFA779001028 +:1062E00097700012936900090130F82127E5000238 +:1062F00030B900070019C02333080007A368000B5A +:106300009371000997720012976F0010322700FFF7 +:106310008F910038978D004000F21821006F702196 +:1063200001C6602131A6004010C000053185FFFF85 +:1063300000B1102B3C128000104000170000982183 +:106340000225A82B56A0013E8FA500203C0480000A +:10635000348A0E008D5300143C068000AD530010AB +:106360008D4B001CAD4B0018AD4500008CCD0000DE +:1063700031AC00081180FFFD34CE0E0095C300083B +:1063800000A0882100009021A78300408DC6000452 +:1063900024130001AF860038976F001031F5FFFF1E +:1063A0008E9F000003F1282310A0011FAE8500007E +:1063B00093620008144000DD000000000E0001E7B9 +:1063C000240400108F900048004028213C02320035 +:1063D000320600FF000654000142F825260900019C +:1063E000AF890048ACBF000093790009977800128C +:1063F000936F000A332800FF3303FFFF01033821A6 +:1064000000076C0031EE00FF01AE6025ACAC00046B +:106410008F840048978B0040316A20001140010AA8 +:10642000ACA4000897640012308BFFFF06400108FF +:10643000ACAB000C978E004031C5000814A00002E0 +:1064400026280006262800023C1F800037E70E00A1 +:1064500094F900148CE5001C8F6700049378000207 +:106460003324FFFF330300FFAFA300108F6F00142E +:10647000AFA800180E0001CBAFAF00142404001029 +:106480000E0001FB000000008E9200001640000587 +:10649000000000008F7800142403FFBF0303A02432 +:1064A000AF7400148F67000C00F5C821AF79000CA1 +:1064B0009375000816A00008000000001260000696 +:1064C000000000008F6800143C0AEFFF3549FFFE12 +:1064D0000109F824AF7F0014A37300088FA50020E2 +:1064E0000A00034F02202021AED100000A00022D35 +:1064F0003C03800014E0FF1E30BFA0400E0001905E +:106500000000A0212E9100010237B02512C0001812 +:106510008FBF00488F87003C24170F0010F700D46E +:106520003C0680008CD901780720FFFE241F0F0055 +:1065300010FF00F634CA0E008D56001434C7014017 +:1065400024080240ACF600048D49001C3C141000E5 +:10655000ACE90008A0E00012A4E0001AACE00020C2 +:10656000A4E00018ACE80014ACD401788FBF004858 +:106570008FB700448FB600408FB5003C8FB4003811 +:106580008FB300348FB200308FB1002C8FB0002851 +:1065900003E0000827BD00508F9100389788004025 +:1065A0003C1280000220A8213107004014E0FF7C4B +:1065B00000009821977900108F9200383338FFFF40 +:1065C000131200A8000020210080A021108000F3F9 +:1065D00000A088211620FECE000000000A00031F44 +:1065E0002E9100013C0380008C6201780440FFFE84 +:1065F000240808008F860000AC6801783C03800006 +:10660000946D008A31ACFFFF01865823256AFFFF95 +:1066100031441FFF2C8900081520FFF900000000FD +:106620008F8F0048347040008F83003C00E0A02131 +:10663000240E0F0025E70001AF87004800D030216D +:10664000023488233C08800031F500FF106E0005FD +:106650002407000193980042331300010013924075 +:1066600036470001001524003C0A0100008A482535 +:10667000ACC900008F82004830BF003630B9000836 +:10668000ACC200041320009900FF982535120E00BB +:106690009650000A8F8700003C0F81003203FFFFF5 +:1066A00024ED000835060140006F60253C0E100007 +:1066B00031AB1FFF269200062405000EACCC002053 +:1066C000026E9825A4C5001AAF8B0000A4D2001852 +:1066D000162000083C1080008F89003C24020F0027 +:1066E0005122000224170001367300400E00018879 +:1066F0003C10800036060E008CCB0014360A014098 +:1067000002402021AD4B00048CC5001CAD450008A3 +:10671000A1550012AD5300140E0001983C15100055 +:10672000AE1501780A00035200000000936F0009C3 +:10673000976E0012936D000B31E500FF00AE202133 +:1067400031AC00FF008C80212602000A3050FFFF90 +:106750000E0001E7020020218F8600483C03410023 +:106760003C05800024CB0001AF8B0048936A0009F0 +:106770009769001230C600FF315F00FF3128FFFF2C +:1067800003E8382124F900020006C4000319782523 +:1067900001E37025AC4E00008F6D000C34A40E0098 +:1067A000948B001401B26025AC4C00048C85001C55 +:1067B0008F670004936A00023164FFFF314900FFD4 +:1067C000AFA900108F680014AFB100180E0001CB04 +:1067D000AFA800140A0002FD02002021AF600004EF +:1067E000A360000297980040330820001500FEA324 +:1067F00000003021A760001297840040936B000ACC +:106800003C10800030931F0000135183014BA821DE +:1068100026A20028A362000936090E00953F000C4D +:106820000A000295A77F00108F70001436090040FF +:106830000E000188AF6900140A0002C900000000C0 +:106840000A00034F000020210641FEFAACA0000C14 +:106850008CAC000C3C0D8000018D90250A0002EAF2 +:10686000ACB2000C000090210A0002C52413000104 +:10687000128000073C028000344B0E009566000831 +:1068800030D3004012600049000000003C06800048 +:106890008CD001780600FFFE34C50E0094B50010C0 +:1068A0003C03050034CC014032B8FFFF03039025C0 +:1068B000AD92000C8CAF0014240D20003C0410009D +:1068C000AD8F00048CAE001CAD8E0008A1800012BC +:1068D000A580001AAD800020A5800018AD8D0014A1 +:1068E000ACC401780A0003263C0680008F9F00009C +:1068F000351801402692000227F9000833281FFFAF +:10690000A71200180A000391AF8800003C02800023 +:1069100034450140ACA0000C1280001B34530E0023 +:1069200034510E008E370010ACB700048E240018CE +:106930003C0B8000ACA400083570014024040040EA +:10694000A20000128FBF0048A600001A8FB70044B3 +:10695000AE0000208FB60040A60000188FB5003CA6 +:10696000AE0400148FB400388FB300348FB20030FF +:106970008FB1002C8FB000283C02100027BD0050C2 +:1069800003E00008AD6201788E660014ACA6000436 +:106990008E64001C0A00042A3C0B80000E0001904B +:1069A0002E9100010A0003200237B02500000000EC +:1069B0000000000D00000000240003690A0004012B +:1069C0003C06800027BDFFD8AFBF00203C098000F7 +:1069D0003C1F20FFAFB200183C07600035320E00AC +:1069E0002402001037F9FFFDACE23008AFB3001C01 +:1069F000AFB10014AFB00010AE59000000000000AD +:106A00000000000000000000000000000000000086 +:106A10003C1800FF3713FFFDAE5300003C0B600431 +:106A20008D7050002411FF7F3C0E0002021178246B +:106A300035EC380C35CD0109ACED4C18240A0009B1 +:106A4000AD6C50008CE80438AD2A0008AD2000146D +:106A50008CE54C1C3106FFFF38C42F7100051E0267 +:106A60003062000F2486C0B310400007AF820008D8 +:106A70008CE54C1C3C09001F3528FC0000A818249C +:106A8000000321C2AF8400048CF108083C0F5709B1 +:106A90002412F0000232702435F0001001D060267C +:106AA00001CF68262DAA00012D8B0001014B38254E +:106AB00050E00009A380000C3C1F601C8FF8000808 +:106AC00024190001A399000C33137C00A793001034 +:106AD000A780000EA380000DAF80004814C0000303 +:106AE000AF8000003C066000ACC0442C0E0005B92D +:106AF0003C1080000E000F1A361101003C120800F5 +:106B000026523DD03C13080026733E508E030000F1 +:106B100038640001308200011440FFFC3C0B800A05 +:106B20008E2600002407FF8024C90240312A007FFE +:106B3000014B402101272824AE060020AF880044E5 +:106B4000AE0500243C048000AF86003C8C8C0178AC +:106B50000580FFFE24180800922F0008AC980178E9 +:106B6000A38F0042938E004231CD000111A0000F8F +:106B700024050D0024DFF8002FF903011320001C69 +:106B8000000629C224A4FFF0000410420002314094 +:106B90000E00020200D2D8213C0240003C068000D8 +:106BA000ACC201380A0004A00000000010C5002398 +:106BB000240D0F0010CD00273C1F800837F90080FE +:106BC00093380000240E0050330F00FF15EEFFF342 +:106BD0003C0240000E000A36000000003C0240006B +:106BE0003C068000ACC201380A0004A0000000008E +:106BF0008F83000400A3402B1500000B8F8B00082F +:106C0000006B50212547FFFF00E5482B15200006AB +:106C100000A36023000C19400E0002020073D8216B +:106C20000A0004C43C0240000000000D0E000202F5 +:106C3000000000000A0004C43C0240003C1B0800A5 +:106C4000277B3F500E000202000000000A0004C42F +:106C50003C0240003C1B0800277B3F700E000202F4 +:106C6000000000000A0004C43C0240003C0660042E +:106C70003C09080025290104ACC9502C8CC85000DF +:106C80003C0580003C02000235070080ACC7500084 +:106C90003C040800248415A43C0308002463155C0C +:106CA000ACA50008ACA2000C3C010800AC243D607F +:106CB0003C010800AC233D6403E00008240200010D +:106CC00000A030213C1C0800279C3D683C0C0400BF +:106CD0003C0B0002008B3826008C40262CE2000181 +:106CE0000007502B2D050001000A48803C030800D6 +:106CF00024633D60004520250123182110800003F6 +:106D000000001021AC6600002402000103E000082E +:106D1000000000003C1C0800279C3D683C0B040060 +:106D20003C0A0002008A3026008B38262CC2000163 +:106D30000006482B2CE50001000940803C030800B8 +:106D400024633D60004520250103182110800005C3 +:106D5000000010213C0C0800258C155CAC6C000078 +:106D60002402000103E00008000000003C090002CA +:106D70003C08040000883026008938262CC3000116 +:106D8000008028212CE40001008310251040000B16 +:106D9000000030213C1C0800279C3D683C0A800014 +:106DA0008D4E00082406000101CA6825AD4D00087B +:106DB0008D4C000C01855825AD4B000C03E00008FC +:106DC00000C010213C1C0800279C3D683C05800049 +:106DD0008CA6000C000420272402000100C4182403 +:106DE00003E00008ACA3000C3C0200021082000B80 +:106DF0003C0560003C070400108700030000000011 +:106E000003E00008000000008CA908D0240AFFFD60 +:106E1000012A402403E00008ACA808D08CA408D0C4 +:106E20002406FFFE0086182403E00008ACA308D067 +:106E30003C05601A34A600108CC3008027BDFFF803 +:106E40008CC50084AFA3000093A4000024020001BD +:106E500010820003AFA5000403E0000827BD00086E +:106E600093A7000114E0001497AC000297B8000249 +:106E70003C0F8000330EFFFC01CF6821ADA5000060 +:106E8000A3A000003C0660008CC708D02408FFFEC9 +:106E90003C04601A00E82824ACC508D08FA3000485 +:106EA0008FA200003499001027BD0008AF22008097 +:106EB00003E00008AF2300843C0B8000318AFFFC14 +:106EC000014B48218D2800000A00057DAFA8000471 +:106ED00027BDFFE8AFBF00103C1C0800279C3D68A1 +:106EE0003C0580008CA4000C8CA200043C03000232 +:106EF0000044282410A0000A00A318243C06040023 +:106F00003C0400021460000900A610241440000F85 +:106F10003C0404000000000D3C1C0800279C3D6858 +:106F20008FBF001003E0000827BD00183C020800D6 +:106F30008C423D600040F809000000003C1C080045 +:106F4000279C3D680A0005A68FBF00103C02080080 +:106F50008C423D640040F809000000000A0005ACC6 +:106F600000000000000411C003E0000824420240B9 +:106F70003C04080024843FB42405001A0A00009C45 +:106F80000000302127BDFFE0AFB000103C108000B2 +:106F9000AFBF0018AFB100143611010092220009F2 +:106FA0000E0005B63044007F8E3F00008F89003C04 +:106FB0003C0F008003E26021258800400049F82151 +:106FC000240DFF80310E00783198007835F90001EA +:106FD00035F100020319382501D14825010D30246F +:106FE00003ED5824018D2824240A00402404008045 +:106FF000240300C0AE0B0024AE000810AE0A081433 +:10700000AE040818AE03081CAE050804AE0708203D +:10701000AE060808AE090824360909009539000CA7 +:107020003605098033ED007F3338FFFF001889C033 +:10703000AE110800AE0F0828952C000C8FBF001869 +:107040008FB10014318BFFFF000B51C0AE0A002C32 +:107050008CA400508FB000108CA3003C8D2700043E +:107060008CA8001C8CA600383C0E800A01AE1021B2 +:1070700027BD0020AF820044AF840050AF8300548E +:10708000AF87004CAF88005C03E00008AF8600606B +:107090003C09080091293FD924A800023C051100B1 +:1070A00000093C0000E8302500C5182524820008AE +:1070B000AC83000003E00008AC8000043C098000C1 +:1070C000352309009128010B906A00112402002841 +:1070D00000804821314700FF00A0702100C06821D6 +:1070E0003108004010E20002340C86DD240C080058 +:1070F0003C0A800035420A9A94470000354B0A9CAE +:1071000035460AA030F9FFFFAD3900008D78000048 +:10711000354B0A8024040001AD3800048CCF0000F8 +:10712000AD2F00089165001930A300031064009092 +:1071300028640002148000AF240500021065009E40 +:10714000240F0003106F00B435450AA4240A080078 +:10715000118A0048000000005100003D3C0B8000F7 +:107160003C048000348309009067001230E200FF85 +:10717000004D7821000FC880272400013C0A8000C0 +:10718000354F090091E50019354C09808D8700289D +:1071900030A300FF00031500004758250004C40079 +:1071A0003C19600001793025370806FFAD26000044 +:1071B000AD2800048DEA002C25280028AD2A0008FF +:1071C0008DEC0030AD2C000C8DE50034AD250010A9 +:1071D0008DE400383C05800034AC093CAD2400143B +:1071E0008DE3001CAD2300188DE70020AD27001CA7 +:1071F0008DE20024AD2200208DF9002834A2010088 +:10720000AD3900248D830000AD0E000434B90900AF +:10721000AD0300008C47000C25020014AD070008E8 +:10722000932B00123C04080090843FD8AD0000105E +:10723000317800FF030D302100064F0000047C0070 +:10724000012F702535CDFFFC03E00008AD0D000CCB +:1072500035780900930600123C05080094A53FC844 +:1072600030C800FF010D5021000A60800A00063C72 +:10727000018520211500005B000000003C0808008B +:1072800095083FCE3C06080094C63FC80106102171 +:107290003C0B80003579090093380011932A0019BE +:1072A00035660A80330800FF94CF002A0008608208 +:1072B000314500FF978A0058000C1E00000524008D +:1072C0003047FFFF006410250047C02501EA302148 +:1072D0003C0B4000030B402500066400AD28000075 +:1072E000AD2C0004932500183C030006252800144B +:1072F00000053E0000E31025AD2200088F24002C7D +:107300003C05800034AC093CAD24000C8F38001CD7 +:1073100034A20100254F0001AD3800108D8300001C +:10732000AD0E000431EB7FFFAD0300008C47000C75 +:1073300034B90900A78B0058AD070008932B001241 +:107340003C04080090843FD825020014317800FFE7 +:10735000030D302100064F0000047C00012F702532 +:1073600035CDFFFCAD00001003E00008AD0D000CB2 +:107370003C02080094423FD23C05080094A53FC857 +:1073800035440AA43C07080094E73FC4948B0000EE +:107390000045C8210327C023000B1C002706FFF26D +:1073A00000665025AD2A000CAD200010AD2C001455 +:1073B0000A00063025290018354F0AA495E500007B +:1073C000956400280005140000043C003459810035 +:1073D00000EC5825AD39000CAD2B00100A0006302A +:1073E000252900143C0C0800958C3FCE0A0006812C +:1073F000258200015460FF56240A080035580AA46B +:107400009706000000061C00006C5025AD2A000CF9 +:107410000A000630252900103C03080094633FD27F +:107420003C07080094E73FC83C0F080095EF3FC4B5 +:1074300094A400009579002800671021004F58237C +:1074400000041C00001934002578FFEE00D87825D0 +:10745000346A8100AD2A000CAD2F0010AD2000145D +:10746000AD2C00180A0006302529001C03E0000896 +:10747000240207D027BDFFE0AFB20018AFB100145F +:10748000AFB00010AFBF001C0E00007C0080882150 +:107490008F8800548F87004C3C05800834B20080F0 +:1074A000011128213C10800024020080240300C028 +:1074B00000A72023AE0208183C068008AE03081C73 +:1074C00018800004AF850054ACC500048CC90004CA +:1074D000AF89004C12200009360409800E0006F81E +:1074E00000000000924C00278E0B007401825004B3 +:1074F000014B3021AE46000C360409808C8E001CF6 +:107500008F8F005C01CF682319A000048FBF001C7F +:107510008C90001CAF90005C8FBF001C8FB20018D5 +:107520008FB100148FB000100A00007E27BD00202C +:107530008F8600508F8300548F82004C3C0580085A +:1075400034A40080AC860050AC83003C03E000080B +:10755000ACA200043C0308008C63005427BDFFF874 +:10756000308400FF2462000130A500FF3C010800C8 +:10757000AC22005430C600FF3C0780008CE8017844 +:107580000500FFFE3C0C7FFFA3A400038FAA0000B0 +:10759000358BFFFF014B4824000627C001244025FE +:1075A000AFA8000034E201009043000AA3A000024B +:1075B0003C1980FFA3A300018FAF000030AE007F15 +:1075C0003738FFFF01F86024000E6E003C0A0020EF +:1075D00034E50140018D5825354920002406FF80FF +:1075E0003C04100027BD0008ACAB000CACA9001493 +:1075F000A4A00018A0A6001203E00008ACE40178E3 +:10760000308800FF30A700FF3C0380008C620178C7 +:107610000440FFFE3C0C8000358A0A008D4B0020A0 +:107620003584014035850980AC8B00048D490024E8 +:107630000007302B00061540AC890008A088001018 +:1076400090A3004CA083002D03E00008A480001844 +:1076500027BDFFE8308400FFAFBF00100E00075DBC +:1076600030A500FF8F8300548FBF00103C068000C0 +:1076700034C50140344700402404FF903C02100010 +:1076800027BD0018ACA3000CA0A40012ACA70014E6 +:1076900003E00008ACC2017827BDFFE03C08800889 +:1076A000AFBF001CAFB20018AFB10014AFB00010F4 +:1076B000351000808E0600183C078000309200FFD5 +:1076C00000C72025AE0400180E00007C30B100FF7A +:1076D00092030005346200080E00007EA20200053D +:1076E000024020210E0007710220282102402021A3 +:1076F0008FBF001C8FB200188FB100148FB0001024 +:1077000024050005240600010A00073227BD0020D9 +:107710003C05800034A309809066000830C2000850 +:107720001040000F3C0A01013549080AAC890000ED +:107730008CA80074AC8800043C07080090E73FD890 +:1077400030E5001050A00008AC8000083C0D800817 +:1077500035AC00808D8B0058AC8B00082484000C65 +:1077600003E00008008010210A0007B52484000C03 +:1077700027BDFFE83C098000AFB00010AFBF001488 +:107780003526098090C800092402000600A058216F +:10779000310300FF35270900008080212405000403 +:1077A0001062007B2408000294CF005C3C0E0204AF +:1077B00031EDFFFF01AE6025AE0C000090CA00085D +:1077C00031440020108000080000000090C2004EEC +:1077D0003C1F010337F90300305800FF031930251F +:1077E00024050008AE06000490F9001190E600128E +:1077F00090E40011333800FF0018708230CF00FF92 +:1078000001CF5021014B6821308900FF31AAFFFFD1 +:1078100039230028000A60801460002C020C4823E1 +:1078200090E400123C198000372F0100308C00FFDB +:10783000018B1821000310800045F821001F8400EF +:10784000360706FFAD270004373F090093EC00110F +:1078500093EE0012372609800005C0828DE4000CEB +:107860008CC5003431CD00FF01AB10210058182128 +:1078700000A4F8230008840000033F0000F0302536 +:1078800033F9FFFF318F00FC00D97025015820210A +:1078900001E9682100045080ADAE000C0E00007CB0 +:1078A000012A80213C088008240B00043505008053 +:1078B0000E00007EA0AB0009020010218FBF001453 +:1078C0008FB0001003E0000827BD001890EC0011F5 +:1078D00090E300193C18080097183FCE318200FF52 +:1078E0000002F882307000FF001FCE0000103C0044 +:1078F0000327302500D870253C0F400001CF6825B4 +:107900003C198000AD2D0000373F090093EC0011B9 +:1079100093EE0012372F0100372609800005C08240 +:107920008DE4000C8CC5003431CD00FF01AB10217B +:107930000058182100A4F8230008840000033F0029 +:1079400000F0302533F9FFFF318F00FC00D970259E +:107950000158202101E9682100045080ADAE000CDF +:107960000E00007C012A80213C088008240B0004C2 +:10797000350500800E00007EA0AB0009020010213A +:107980008FBF00148FB0001003E0000827BD00185F +:107990000A0007C72408001227BDFFD03C0380005F +:1079A000AFB60028AFB50024AFB40020AFB10014CB +:1079B000AFBF002CAFB3001CAFB20018AFB00010C7 +:1079C0003467010090E6000B309400FF30B500FFF3 +:1079D00030C200300000B021104000990000882122 +:1079E000346409809088000800082E0000051E03FA +:1079F000046000C0240400048F8600543C01080089 +:107A0000A0243FD83C0C8000AD8000483C0480009E +:107A1000348E010091CD000B31A5002010A000078D +:107A20003C0780003493098092720008001286009F +:107A300000107E0305E000C43C1F800834EC010008 +:107A4000918A000B34EB09809169000831440040B1 +:107A50000004402B3123000800C898231460000262 +:107A600024120003000090213C10800036180A8088 +:107A700036040900970E002C9083001190890012A3 +:107A800093050018307F00FF312800FF02481021C5 +:107A90000002C880930D0018033F782101F13021C6 +:107AA00030B100FF00D11821A78E00583C0108001A +:107AB000A4263FCE3C010800A4233FD015A000021D +:107AC000000000000000000D920B010B3065FFFF6D +:107AD0003C010800A4233FD2316A00403C01080069 +:107AE000A4203FC83C010800A4203FC4114000026C +:107AF00024A4000A24A4000B3091FFFF0E0001E72C +:107B0000022020219206010B3C0C0800958C3FD2EC +:107B1000004020210006698231A700010E00060105 +:107B20000187282100402021026028210E00060C38 +:107B3000024030210E0007A10040202116C000693C +:107B4000004020219212010B3256004012C0000565 +:107B50003C0500FF8C93000034AEFFFF026E8024D2 +:107B6000AC9000000E0001FB022020213C0F080019 +:107B700091EF3FD831F10003122000163C1380082A +:107B80008F8200543C09800835280080245F000162 +:107B9000AD1F003C3C0580088CB9000403E02021A7 +:107BA000033FC0231B000002AF9F00548CA40004BD +:107BB0000E0006F8ACA400043C0780008CEB0074B7 +:107BC0003C04800834830080004B5021AC6A000CD8 +:107BD0003C138008367000800280202102A02821FA +:107BE000A200006B0E00075D3C1480008F920054D1 +:107BF000368C0140AD92000C8F8600483C15100079 +:107C0000344D000624D60001AF9600488FBF002CEB +:107C1000A18600128FB60028AD8D00148FB3001C12 +:107C2000AE9501788FB200188FB500248FB4002074 +:107C30008FB100148FB0001003E0000827BD0030A2 +:107C400034640980908F0008000F7600000E6E03E8 +:107C500005A00033347F090093F8001B241900109D +:107C60003C010800A0393FD8331300021260FF67BF +:107C70008F8600548F8200601446FF653C048000AC +:107C80000E00007C000000003C0480083485008069 +:107C900090A8000924060016310300FF1066000DAD +:107CA0000000000090AB00093C07080090E73FD8B7 +:107CB00024090008316400FF34EA00013C01080097 +:107CC000A02A3FD81089002F240C000A108C00280D +:107CD0002402000C0E00007E000000000A00086074 +:107CE0008F8600540E0007B9024028210A0008AE12 +:107CF000004020213C0B8008356A00808D460054EE +:107D00008CE9000C1120FF3DAF86005424070014BD +:107D10003C010800A0273FD80A00085F3C0C800007 +:107D200090910008241200023C010800A0323FD8C4 +:107D3000323000201200000B241600018F86005400 +:107D40000A0008602411000837F800808F0200380C +:107D5000AFE200048FF90004AF19003C0A00086C80 +:107D60003C0780008F8600540A000860241100043C +:107D7000A0A200090E00007E000000000A000860BA +:107D80008F860054240200140A00093AA0A20009B8 +:107D900027BDFFE8AFB000103C108000AFBF00145B +:107DA00036020100904400090E00075D2405000121 +:107DB0003C0480089099000E34830080909F000F4F +:107DC000906F00269089000A33F800FF00196E00BA +:107DD0000018740031EC00FF01AE5025000C5A0071 +:107DE000014B3825312800FF36030140344560003F +:107DF00000E830252402FF813C041000AC66000C32 +:107E00008FBF0014AC650014A0620012AE040178AC +:107E10008FB0001003E0000827BD001827BDFFE861 +:107E2000308400FFAFBF00100E00075D30A500FFDB +:107E30003C05800034A40140344700402406FF92F2 +:107E4000AC870014A08600128F8300548FBF0010EF +:107E50003C02100027BD0018AC83000C03E00008B2 +:107E6000ACA2017827BDFFD8AFB00010308400FF6E +:107E700030B000FF3C058000AFB10014AFBF002060 +:107E8000AFB3001CAFB20018000410C234A601004A +:107E900032030002305100011460000790D2000943 +:107EA0003C098008353300809268000531070008DE +:107EB00010E0000C308A0010024020210E000783E1 +:107EC00002202821240200018FBF00208FB3001C54 +:107ED0008FB200188FB100148FB0001003E00008BB +:107EE00027BD00281540003434A50A008CB80024B2 +:107EF0008CAF0008130F004B000038213C0D8008A8 +:107F000035B30080926C006824060002318B00FFBC +:107F1000116600843C06800034C201009263004C6C +:107F200090590009307F00FF53F900043213007CA0 +:107F300010E00069000000003213007C5660005C15 +:107F40000240202116200009320D00013C0C800067 +:107F500035840100358B0A008D6500248C86000471 +:107F600014A6FFD900001021320D000111A0000E4F +:107F7000024020213C188000371001008E0F000CB9 +:107F80008F8E005011EE0008000000000E00084324 +:107F9000022028218E19000C3C1F800837F0008039 +:107FA000AE190050024020210E0007710220282146 +:107FB0000A00098F240200013C0508008CA500641A +:107FC00024A400013C010800AC2400641600000D4C +:107FD00000000000022028210E000771024020212D +:107FE000926E0068240C000231CD00FF11AC00221B +:107FF000024020210E000941000000000A00098F04 +:10800000240200010E00007024040001926B002580 +:10801000020B30250E00007EA26600250A0009D35F +:10802000022028218E6200188CDF00048CB9002405 +:1080300000021E0217F9FFB13065007F9268004C04 +:10804000264400013093007F12650040310300FF99 +:108050001464FFAB3C0D80082647000130F1007F1F +:1080600030E200FF1225000B2407000100409021A0 +:108070000A00099C24110001240500040E000732A7 +:10808000240600010E000941000000000A00098FCB +:10809000240200012405FF8002452024008590264B +:1080A000324200FF004090210A00099C2411000187 +:1080B0000E000843022028213207003010E0FFA103 +:1080C00032100082024020210E0007830220282166 +:1080D0000A00098F240200018E6900180240202145 +:1080E00002202821012640250E000964AE680018F0 +:1080F0009264004C24050003240600010E000732A0 +:10810000308400FF0E0000702404000192710025ED +:10811000021150250E00007EA26A00250A00098F78 +:10812000240200018E6F00183C18800002402021BC +:1081300001F87025022028210E000771AE6E00188C +:108140009264004C0A000A1B24050004324A008095 +:10815000394900801469FF6A3C0D80080A0009F45F +:108160002647000127BDFFC0AFB000183C108000BB +:10817000AFBF0038AFB70034AFB60030AFB5002C9A +:10818000AFB40028AFB30024AFB200200E0005BE8C +:10819000AFB1001C360201009045000B0E000976BD +:1081A00090440008144000E78FBF00383C08800866 +:1081B00035070080A0E0006B3606098090C50000FE +:1081C000240300503C17080026F73F9030A400FF1E +:1081D0003C13080026733FA0108300033C1080006E +:1081E0000000B82100009821241F00103611010062 +:1081F00036120A00361509808E5800248E34000489 +:108200008EAF00208F8C00543C010800A03F3FD867 +:1082100036190A80972B002C8EF60000932A00183E +:108220000298702301EC68233C010800AC2E3FB497 +:108230003C010800AC2D3FB83C010800AC2C3FDCF1 +:10824000A78B005802C0F809315400FF30490002E2 +:10825000152000E930420001504000C49227000977 +:1082600092A9000831280008150000022415000317 +:108270000000A8213C0A80003543090035440A006B +:108280008C8D00249072001190700012907F00116C +:10829000325900FF321100FF02B110210002C080EC +:1082A00033EF00FF0319B021028F702102D4602147 +:1082B00025CB00103C010800A4363FCE3C0108004D +:1082C000AC2D3FE03C010800A42C3FD03C0108004D +:1082D000A42B3FCC355601003554098035510E0092 +:1082E0008F8700548F89005C8E850020240800064B +:1082F000012730233C010800AC283FD400A72823E5 +:1083000004C000B50000902104A000B300C5502BAC +:10831000114000B5000000003C010800AC263FB849 +:108320008E6200000040F8090000000030460002A4 +:1083300014C0007400408021304B000155600011D2 +:108340008E6200043C0D08008DAD3FBC3C0EC000A9 +:108350003C04800001AE6025AE2C00008C9800002B +:10836000330F000811E0FFFD00000000963F0008F9 +:1083700024120001A79F00408E390004AF990038F5 +:108380008E6200040040F80900000000020280250F +:1083900032030002146000B3000000003C09080032 +:1083A00095293FC43C06080094C63FD03C0A08000B +:1083B000954A3FC63C0708008CE73FBC0126702168 +:1083C0003C0308008C633FE03C08080095083FDA56 +:1083D00001CA20218ED9000C00E92821249F000227 +:1083E00000A878210067C02133E4FFFFAF99005057 +:1083F0003C010800AC383FE03C010800A42F3FC816 +:108400003C010800A42E3FD20E0001E7000000004E +:108410008F8D0048004020213C010800A02D3FD94D +:108420008E62000825AC0001AF8C00480040F809BE +:10843000000000008F85005402A030210E00060CC1 +:10844000004020210E0007A1004020218E6B000C6F +:108450000160F809004020213C0A0800954A3FD2FB +:108460003C06080094C63FC6014648212528000264 +:108470000E0001FB3104FFFF3C0508008CA53FB452 +:108480003C0708008CE73FBC00A720233C01080004 +:10849000AC243FB414800006000000003C02080039 +:1084A0008C423FD4344B00403C010800AC2B3FD4FD +:1084B000124000438F8E00448E2D00108F92004496 +:1084C000AE4D00208E2C0018AE4C00243C04080059 +:1084D00094843FC80E0006FA000000008F9F0054ED +:1084E0008E6700103C010800AC3F3FDC00E0F8095B +:1084F000000000003C1908008F393FB41720FF79B5 +:108500008F870054979300583C11800E321601005B +:108510000E000729A633002C16C0004532030010B8 +:108520005460004C8EE50004320800405500001DE8 +:108530008EF000088EE4000C0080F80900000000B6 +:108540008FBF00388FB700348FB600308FB5002C46 +:108550008FB400288FB300248FB200208FB1001C8D +:108560008FB0001803E0000827BD00408F86003C54 +:1085700036110E0000072E0000A62025AE04008054 +:108580008E4300208E500024AFA30010AE230014B1 +:108590008FB20010AE320010AE30001C0A000A7517 +:1085A000AE3000180200F809000000008EE4000C54 +:1085B0000080F809000000000A000B2E8FBF003871 +:1085C00024180001240F0001A5C00020A5D8002216 +:1085D0000A000B10ADCF00243C010800AC203FB8CE +:1085E0000A000AA68E6200003C010800AC253FB8D4 +:1085F0000A000AA68E620000922400090E0007718C +:10860000000028218FBF00388FB700348FB60030AC +:108610008FB5002C8FB400288FB300248FB20020B8 +:108620008FB1001C8FB0001803E0000827BD004088 +:108630003C14800092950109000028210E00084397 +:1086400032A400FF320300105060FFB8320800402F +:108650008EE5000400A0F809000000000A000B28C5 +:10866000320800405240FFA8979300588E340014FF +:108670008F930044AE7400208E35001CAE7500242C +:108680000A000B1F979300588F820014000421806A +:1086900003E00008008210213C07800834E20080DB +:1086A0009043006900804021106000093C040100F3 +:1086B0003C0708008CE73FDC8F83003000E3202379 +:1086C000048000089389001C14E3000301002021AA +:1086D00003E00008008010213C04010003E00008D2 +:1086E000008010211120000B006738233C0D800012 +:1086F00035AC0980918B007C316A0002114000206A +:108700002409003400E9702B15C0FFF1010020217D +:1087100000E938232403FFFC00A3C82400E3C0249D +:1087200000F9782B15E0FFEA0308202130C400038C +:108730000004102314C0001430490003000030214D +:1087400000A9782101E6702100EE682B11A0FFE05E +:108750003C0401002D3800010006C82B010548210A +:108760000319382414E0FFDA2524FFFC2402FFFC5F +:1087700000A218240068202103E0000800801021D6 +:108780000A000B9E240900303C0C800035860980CD +:1087900090CB007C316A00041540FFE924060004F8 +:1087A0000A000BAD000030213C0308008C63005C24 +:1087B0008F82001827BDFFE0AFBF0018AFB10014D3 +:1087C00010620005AFB00010000329C024A402808D +:1087D000AF840014AF8300183C10800036020A00FA +:1087E00094450032361101000E000B7F30A43FFF8C +:1087F0008E240000241FFF803C1100800082C021D5 +:10880000031F60243309007F000CC9400329402561 +:10881000330E0078362F00033C0D1000010D50255B +:1088200001CF5825AE0C002836080980AE0C080C84 +:10883000AE0B082CAE0A0830910300693C06800C90 +:108840000126382110600006AF8700348D09003CF6 +:108850008D03006C0123382318E000820000000023 +:108860003C0B8008356A00803C108000A140006904 +:10887000360609808CC200383C06800034C50A00E8 +:1088800090A8003C310C00201180001AAF8200300B +:10889000240D00013C0E800035D10A00A38D001C80 +:1088A000AF8000248E2400248F850024240D00082E +:1088B000AF800020AF8000283C010800A42D3FC6F7 +:1088C0003C010800A4203FDA0E000B830000302199 +:1088D0009228003C8FBF00188FB100148FB0001099 +:1088E00000086142AF82002C27BD002003E0000891 +:1088F0003182000190B80032240E0001330F00FFD6 +:10890000000F2182108E004124190002109900648A +:1089100034C40AC03C03800034640A008C8F0024F5 +:1089200015E0001E34660900909F003024180005F1 +:1089300033F9003F1338004E240300018F860020D6 +:10894000A383001CAF860028AF8600243C0E800065 +:1089500035D10A008E2400248F850024240D0008C0 +:108960003C010800A42D3FC63C010800A4203FDACA +:108970000E000B83000000009228003C8FBF0018FF +:108980008FB100148FB0001000086142AF82002C3C +:1089900027BD002003E00008318200018C8A000816 +:1089A0008C8B00248CD000643C0E800035D10A00F2 +:1089B000014B2823AF900024A380001CAF85002822 +:1089C0008E2400248F8600208F850024240D00082B +:1089D0003C010800A42D3FC63C010800A4203FDA5A +:1089E0000E000B83000000009228003C8FBF00188F +:1089F0008FB100148FB0001000086142AF82002CCC +:108A000027BD002003E000083182000190A2003061 +:108A10003051003F5224002834C50AC08CB00024D5 +:108A20001600002234CB09008CA600483C0A7FFFC8 +:108A30003545FFFF00C510243C0E8000AF820020AA +:108A400035C509008F8800208CAD0060010D602BBA +:108A500015800002010020218CA400600A000C2275 +:108A6000AF8400208D02006C0A000BFC3C068000E5 +:108A70008C8200488F8600203C097FFF3527FFFF4E +:108A8000004788243C04800824030001AF9100289B +:108A9000AC80006CA383001C0A000C30AF8600245D +:108AA0008C9F00140A000C22AF9F00208D6200688A +:108AB0000A000C6C3C0E800034C409808C89007064 +:108AC0008CA300140123382B10E0000400000000E8 +:108AD0008C8200700A000C6C3C0E80008CA200148A +:108AE0000A000C6C3C0E80008F85002427BDFFE03F +:108AF000AFBF0018AFB1001414A00008AFB0001051 +:108B00003C04800034870A0090E60030240200050F +:108B100030C3003F106200B9348409008F910020F7 +:108B200000A080213C048000348E0A008DCD00041A +:108B30003C0608008CC63FB831A73FFF00E6602B1B +:108B40005580000100E03021938F001C11E0007877 +:108B500000D0282B349F098093F9007C3338000221 +:108B6000130000792403003400C3102B144000D9F3 +:108B70000000000000C3302300D0282B3C01080077 +:108B8000A4233FC414A0006E020018213C04080076 +:108B90008C843FB40064402B55000001006020210C +:108BA0003C05800034A90A00912A003C3C010800E1 +:108BB000AC243FBC31430020146000030000482176 +:108BC00034AB0E008D6900188F88002C0128202BF3 +:108BD0001080005F000000003C0508008CA53FBC31 +:108BE00000A96821010D602B1180005C00B0702B82 +:108BF0000109382300E028213C010800AC273FBCD4 +:108C000012000003240AFFFC10B0008D3224000380 +:108C100000AA18243C010800A4203FDA3C01080007 +:108C2000AC233FBC006028218F840024120400067E +:108C30003C0B80088D6C006C02002021AF9100205D +:108C400025900001AD70006C8F8D00280085882371 +:108C5000AF91002401A52023AF8400281220000238 +:108C600024070018240700103C18800837060080ED +:108C700090CF00683C010800A0273FD824070001DE +:108C800031EE00FF11C700470000000014800018FB +:108C9000000028213C06800034D1098034CD010039 +:108CA00091A600098E2C001824C40001000C860235 +:108CB0003205007F308B007F1165007F2407FF8025 +:108CC0003C19800837290080A124004C3C0808008A +:108CD0008D083FD4241800023C010800A038401938 +:108CE000350F00083C010800AC2F3FD424050010CC +:108CF0003C02800034440A009083003C307F002016 +:108D000013E0000500A02021240A00013C01080016 +:108D1000AC2A3FBC34A400018FBF00188FB10014EF +:108D20008FB000100080102103E0000827BD002054 +:108D30003C010800A4203FC410A0FF9402001821A9 +:108D40000A000CC000C018210A000CB72403003030 +:108D50003C0508008CA53FBC00B0702B11C0FFA8DB +:108D6000000000003C19080097393FC40325C021CA +:108D70000307782B11E000072CAA00043C036000D5 +:108D80008C625404305F003F17E0FFE3240400428C +:108D90002CAA00041140FF9A240400420A000D246A +:108DA0008FBF00181528FFB9000000008CCA0018FA +:108DB0003C1F800024020002015F1825ACC300188C +:108DC00037F90A00A0C200689329003C240400047B +:108DD00000A01021312800203C010800A0244019E7 +:108DE0001100000224050010240200013C010800CB +:108DF000AC223FB40A000D1A3C0280008F88002884 +:108E00008C8900600109282B14A000020100882130 +:108E10008C9100603C048000348B0E008D6400183F +:108E2000240A00010220282102203021A38A001CEC +:108E30000E000B83022080210A000CA6AF82002CBA +:108E40000004582312200007316400033C0E800008 +:108E500035C7098090ED007C31AC00041580001905 +:108E6000248F00043C010800A4243FDA3C1F0800C2 +:108E700097FF3FDA03E5C82100D9C02B1300FF6B31 +:108E80008F8400242CA6000514C0FFA324040042F4 +:108E900030A200031440000200A2182324A3FFFC08 +:108EA0003C010800AC233FBC3C010800A4203FDA91 +:108EB0000A000CE70060282100C770240A000D0D8D +:108EC00001C720263C010800A42F3FDA0A000D78D4 +:108ED000000000003C010800AC203FBC0A000D234C +:108EE000240400428F8300283C05800034AA0A0035 +:108EF0001460000600001021914700302406000590 +:108F000030E400FF108600030000000003E00008CA +:108F100000000000914B0048316900FF000941C288 +:108F20001500FFFA3C0680083C04080094843FC406 +:108F30003C0308008C633FDC3C1908008F393FBCC0 +:108F40003C0F080095EF3FDA0064C0218CCD00048F +:108F50000319702101CF602134AB0E00018D28234D +:108F600018A0001D00000000914F004C8F8C0034B1 +:108F7000956D001031EE00FF8D89000401AE3023A5 +:108F80008D8A000030CEFFFF000E29000125C82188 +:108F900000003821014720210325182B0083C02120 +:108FA000AD990004AD980000918F000A01CF6821AF +:108FB000A18D000A956500128F8A0034A54500082E +:108FC000954B003825690001A54900389148000DEE +:108FD00035070008A147000D03E00008000000006D +:108FE00027BDFFD8AFB000189388001C8FB00014C5 +:108FF0003C0A80003C197FFF8F8700243738FFFF31 +:10900000AFBF0020AFB1001C355F0A000218182462 +:1090100093EB003C00087FC03C02BFFF006F60255F +:109020002CF000013449FFFF3C1F08008FFF3FDC9C +:109030008F9900303C18080097183FD20189782496 +:10904000001047803C07EFFF3C05F0FF01E81825C2 +:109050003C1180003169002034E2FFFF34ADFFFF96 +:10906000362E098027A500102406000203F960238C +:10907000270B0002354A0E00006218240080802170 +:1090800015200002000040218D48001CA7AB0012F3 +:10909000058000392407000030E800FF00083F0089 +:1090A000006758253C028008AFAB0014344F0080A5 +:1090B00091EA00683C08080091083FD93C09DFFFAD +:1090C000352CFFFF000AF82B3C02080094423FCCED +:1090D000A3A80011016CC024001FCF40031918255C +:1090E0008FA70010AFA300143C0C0800918C3FDB4D +:1090F000A7A200168FAB001400ED48243C0F01001E +:109100003C0A0FFF012FC82531980003355FFFFF90 +:10911000016D40243C027000033F382400181E00FB +:1091200000E2482501037825AFAF0014AFA9001075 +:1091300091CC007C0E000092A3AC0015362D0A00E5 +:1091400091A6003C30C400201080000626020008D2 +:109150003C11080096313FC8262EFFFF3C01080055 +:10916000A42E3FC88FBF00208FB1001C8FB0001805 +:1091700003E0000827BD00288F8B002C010B502B2B +:109180005540FFC5240700010A000E0430E800FF27 +:109190009383001C3C02800027BDFFD834480A009E +:1091A00000805021AFBF002034460AC001002821B2 +:1091B0001060000E3444098091070030240B000534 +:1091C0008F89002030EC003F118B000B000038210C +:1091D000AFA900103C0B80088D69006CAFAA001885 +:1091E0000E00015AAFA90014A380001C8FBF0020FD +:1091F00003E0000827BD00288D1F00483C18080028 +:109200008F183FBC8F9900283C027FFF8D080044D7 +:109210003443FFFFAFA900103C0B80088D69006C40 +:1092200003E370240319782101CF682301A83821B2 +:10923000AFAA00180E00015AAFA900140A000E5878 +:10924000A380001C3C05800034A60A0090C7003CA7 +:109250003C06080094C63FDA3C0208008C423FD42A +:1092600030E30020000624001060001E0044382572 +:109270003C0880083505008090A300680000482164 +:109280002408000100002821240400013C0680007D +:109290008CCD017805A0FFFE34CF0140ADE8000879 +:1092A0003C0208008C423FDCA5E50004A5E4000672 +:1092B000ADE2000C3C04080090843FD93C038008D8 +:1092C00034790080A1E40012ADE70014A5E900188C +:1092D0009338004C3C0E1000A1F8002D03E000086C +:1092E000ACCE017834A90E008D28001C3C0C08007F +:1092F0008D8C3FBC952B0016952A001401864821C1 +:109300003164FFFF0A000E803145FFFF3C048000FE +:1093100034830A009065003C30A200201040001900 +:1093200034870E0000004021000038210000202179 +:109330003C0680008CC901780520FFFE34CA01403C +:1093400034CF010091EB0009AD4800083C0E080045 +:109350008DCE3FDC240DFF91240C00403C08100012 +:10936000A5440004A5470006AD4E000CA14D001217 +:10937000AD4C0014A5400018A14B002D03E00008DF +:10938000ACC801788CE8001894E6001294E4001050 +:1093900030C7FFFF0A000EA93084FFFF3C048000A5 +:1093A00034830A009065003C30A200201040002762 +:1093B00027BDFFF82409000100003821240800011E +:1093C0003C0680008CCA01780540FFFE3C0280FF0D +:1093D00034C40100908D00093C0C0800918C4019A8 +:1093E000A3AD00038FAB00003185007F3459FFFF30 +:1093F00001665025AFAA00009083000AA3A00002D6 +:1094000000057E00A3A300018FB8000034CB01400B +:10941000240C30000319702401CF6825AD6D000CB9 +:1094200027BD0008AD6C0014A5600018AD690008E8 +:10943000A56700042409FF80A56800063C08100009 +:10944000A169001203E00008ACC8017834870E005F +:109450008CE9001894E6001294E4001030C8FFFF75 +:109460000A000ECD3087FFFF27BDFFE0AFB100142B +:109470003C118000AFB00010AFBF001836380A00B2 +:10948000970F0032363001000E000B7F31E43FFFB2 +:109490008E0E0000240DFF803C04200001C25821E4 +:1094A000016D6024000C4940316A007F012A40258B +:1094B000010438253C048008AE270830348600803B +:1094C00090C500682403000230A200FF104300048E +:1094D0008F9F00208F990024AC9F0068AC99006496 +:1094E0008FBF00188FB100148FB0001003E0000888 +:1094F00027BD00203C0A0800254A3A803C090800A4 +:1095000025293B103C08080025082F1C3C070800B3 +:1095100024E73BDC3C06080024C639043C0508006F +:1095200024A536583C0408002484325C3C0308001F +:10953000246339B83C020800244237543C01080037 +:10954000AC2A3F983C010800AC293F943C0108003C +:10955000AC283F903C010800AC273F9C3C01080030 +:10956000AC263FAC3C010800AC253FA43C01080000 +:10957000AC243FA03C010800AC233FB03C010800F4 +:0C958000AC223FA803E00008000000003F +:04958C008000094012 +:109590008000090080080100800800808008000029 +:1095A000800E0000800800808008000080000A8093 +:0C95B00080000A00800009808000090093 +:00000001FF +/* + * This file contains firmware data derived from proprietary unpublished + * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. + * + * Permission is hereby granted for the distribution of this firmware data + * in hexadecimal or equivalent format, provided this copyright notice is + * accompanying it. + */ -- cgit v1.2.3 From af1dc13e607c1d1a909e21ee87aafbe7b9d4ae81 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Thu, 10 Mar 2011 06:52:13 +0000 Subject: phylib: SIOCGMIIREG/SIOCSMIIREG: allow access to all mdio addresses phylib would silently ignore the phy_id argument to these ioctls and perform the read/write with the active phydev address, whereas most non-phylib drivers seem to allow access to all mdio addresses (E.G. pcnet_cs). Signed-off-by: Peter Korsgaard Signed-off-by: David S. Miller --- drivers/net/phy/phy.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index a8445c72fc13..f7670330f988 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -319,7 +319,8 @@ int phy_mii_ioctl(struct phy_device *phydev, /* fall through */ case SIOCGMIIREG: - mii_data->val_out = phy_read(phydev, mii_data->reg_num); + mii_data->val_out = mdiobus_read(phydev->bus, mii_data->phy_id, + mii_data->reg_num); break; case SIOCSMIIREG: @@ -350,8 +351,9 @@ int phy_mii_ioctl(struct phy_device *phydev, } } - phy_write(phydev, mii_data->reg_num, val); - + mdiobus_write(phydev->bus, mii_data->phy_id, + mii_data->reg_num, val); + if (mii_data->reg_num == MII_BMCR && val & BMCR_RESET && phydev->drv->config_init) { -- cgit v1.2.3 From 60aeba23101f34a690a0b0a048ffde3d023d4f3b Mon Sep 17 00:00:00 2001 From: Thomas Lange Date: Wed, 9 Mar 2011 04:41:16 +0000 Subject: Davinci: Do not reset EMAC TX overruns counter on read Don't reset tx_fifo_errors when reading out current EMAC stats. (tx_fifo_errors shows up as TX overruns in netdev stats.) Without this correction, the old counter value is lost every time stats are read out. Signed-off-by: Thomas Lange Signed-off-by: David S. Miller --- drivers/net/davinci_emac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 7018bfe408a4..082d6ea69920 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -1730,7 +1730,7 @@ static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev) emac_read(EMAC_TXCARRIERSENSE); emac_write(EMAC_TXCARRIERSENSE, stats_clear_mask); - ndev->stats.tx_fifo_errors = emac_read(EMAC_TXUNDERRUN); + ndev->stats.tx_fifo_errors += emac_read(EMAC_TXUNDERRUN); emac_write(EMAC_TXUNDERRUN, stats_clear_mask); return &ndev->stats; -- cgit v1.2.3 From e9a799ea4a5551d20e458a45b541df0bbf8f1804 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 10 Mar 2011 07:04:18 +0000 Subject: xen: netfront: ethtool stats fields should be unsigned long Fixup the rx_gso_checksum_fixup field added in e0ce4af920eb to be unsigned long as suggested by Ben Hutchings in <1298919198.2569.14.camel@bwh-desktop> Signed-off-by: Ian Campbell Cc: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/xen-netfront.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index da1f12120346..27cf72f26cbb 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -122,7 +122,7 @@ struct netfront_info { struct mmu_update rx_mmu[NET_RX_RING_SIZE]; /* Statistics */ - int rx_gso_checksum_fixup; + unsigned long rx_gso_checksum_fixup; }; struct netfront_rx_info { -- cgit v1.2.3 From d478af0d6bb38c971d1172e99c5046025a9167c9 Mon Sep 17 00:00:00 2001 From: Sony Chacko Date: Thu, 10 Mar 2011 23:50:02 +0000 Subject: netxen: Notify firmware of Flex-10 interface down Notify firmware when a Flex-10 interface is brought down so that virtual connect manager can display the correct link status. Signed-off-by: Sony Chacko Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_main.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 33fac32e0d9f..83348dc4b184 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -1032,6 +1032,9 @@ __netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) netif_carrier_off(netdev); netif_tx_disable(netdev); + if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION) + netxen_linkevent_request(adapter, 0); + if (adapter->stop_port) adapter->stop_port(adapter); -- cgit v1.2.3 From 2e588f84f254cca0fc3b9f01297d06799b8c85d3 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Fri, 11 Mar 2011 02:49:26 +0000 Subject: be2net: changes for BE3 native mode support So far be2net has been using BE3 in legacy mode. It now checks for native mode capability and if available it sets it. In native mode, the RX_COMPL structure is different from that in legacy mode. Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 23 +++- drivers/net/benet/be_cmds.c | 39 +++++++ drivers/net/benet/be_cmds.h | 20 ++++ drivers/net/benet/be_hw.h | 41 ++++++- drivers/net/benet/be_main.c | 279 +++++++++++++++++++++----------------------- 5 files changed, 252 insertions(+), 150 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 4ac0d72660fe..62af70716f8d 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -67,7 +67,7 @@ static inline char *nic_name(struct pci_dev *pdev) } /* Number of bytes of an RX frame that are copied to skb->data */ -#define BE_HDR_LEN 64 +#define BE_HDR_LEN ((u16) 64) #define BE_MAX_JUMBO_FRAME_SIZE 9018 #define BE_MIN_MTU 256 @@ -211,10 +211,30 @@ struct be_rx_stats { u32 rx_fps; /* Rx frags per second */ }; +struct be_rx_compl_info { + u32 rss_hash; + u16 vid; + u16 pkt_size; + u16 rxq_idx; + u16 mac_id; + u8 vlanf; + u8 num_rcvd; + u8 err; + u8 ipf; + u8 tcpf; + u8 udpf; + u8 ip_csum; + u8 l4_csum; + u8 ipv6; + u8 vtm; + u8 pkt_type; +}; + struct be_rx_obj { struct be_adapter *adapter; struct be_queue_info q; struct be_queue_info cq; + struct be_rx_compl_info rxcp; struct be_rx_page_info page_info_tbl[RX_Q_LEN]; struct be_eq_obj rx_eq; struct be_rx_stats stats; @@ -312,6 +332,7 @@ struct be_adapter { u32 flash_status; struct completion flash_compl; + bool be3_native; bool sriov_enabled; struct be_vf_cfg vf_cfg[BE_MAX_VF]; u8 is_virtfn; diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index cc3a235475bc..e1124c89181c 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -2014,3 +2014,42 @@ err: attribs_cmd.dma); return status; } + +/* Uses mbox */ +int be_cmd_check_native_mode(struct be_adapter *adapter) +{ + struct be_mcc_wrb *wrb; + struct be_cmd_req_set_func_cap *req; + int status; + + if (mutex_lock_interruptible(&adapter->mbox_lock)) + return -1; + + wrb = wrb_from_mbox(adapter); + if (!wrb) { + status = -EBUSY; + goto err; + } + + req = embedded_payload(wrb); + + be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, + OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP); + + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, + OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP, sizeof(*req)); + + req->valid_cap_flags = cpu_to_le32(CAPABILITY_SW_TIMESTAMPS | + CAPABILITY_BE3_NATIVE_ERX_API); + req->cap_flags = cpu_to_le32(CAPABILITY_BE3_NATIVE_ERX_API); + + status = be_mbox_notify_wait(adapter); + if (!status) { + struct be_cmd_resp_set_func_cap *resp = embedded_payload(wrb); + adapter->be3_native = le32_to_cpu(resp->cap_flags) & + CAPABILITY_BE3_NATIVE_ERX_API; + } +err: + mutex_unlock(&adapter->mbox_lock); + return status; +} diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index b4ac3938b298..e41fcbaed000 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -190,6 +190,7 @@ struct be_mcc_mailbox { #define OPCODE_COMMON_GET_BEACON_STATE 70 #define OPCODE_COMMON_READ_TRANSRECV_DATA 73 #define OPCODE_COMMON_GET_PHY_DETAILS 102 +#define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103 #define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121 #define OPCODE_ETH_RSS_CONFIG 1 @@ -1042,6 +1043,24 @@ struct be_cmd_resp_cntl_attribs { struct mgmt_controller_attrib attribs; }; +/*********************** Set driver function ***********************/ +#define CAPABILITY_SW_TIMESTAMPS 2 +#define CAPABILITY_BE3_NATIVE_ERX_API 4 + +struct be_cmd_req_set_func_cap { + struct be_cmd_req_hdr hdr; + u32 valid_cap_flags; + u32 cap_flags; + u8 rsvd[212]; +}; + +struct be_cmd_resp_set_func_cap { + struct be_cmd_resp_hdr hdr; + u32 valid_cap_flags; + u32 cap_flags; + u8 rsvd[212]; +}; + extern int be_pci_fnum_get(struct be_adapter *adapter); extern int be_cmd_POST(struct be_adapter *adapter); extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, @@ -1128,4 +1147,5 @@ extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); extern void be_detect_dump_ue(struct be_adapter *adapter); extern int be_cmd_get_die_temperature(struct be_adapter *adapter); extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter); +extern int be_cmd_check_native_mode(struct be_adapter *adapter); diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index dbe67f353e8f..e06aa1567b27 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h @@ -301,10 +301,10 @@ struct be_eth_rx_d { /* RX Compl Queue Descriptor */ -/* Pseudo amap definition for eth_rx_compl in which each bit of the - * actual structure is defined as a byte: used to calculate +/* Pseudo amap definition for BE2 and BE3 legacy mode eth_rx_compl in which + * each bit of the actual structure is defined as a byte: used to calculate * offset/shift/mask of each field */ -struct amap_eth_rx_compl { +struct amap_eth_rx_compl_v0 { u8 vlan_tag[16]; /* dword 0 */ u8 pktsize[14]; /* dword 0 */ u8 port; /* dword 0 */ @@ -335,6 +335,41 @@ struct amap_eth_rx_compl { u8 rsshash[32]; /* dword 3 */ } __packed; +/* Pseudo amap definition for BE3 native mode eth_rx_compl in which + * each bit of the actual structure is defined as a byte: used to calculate + * offset/shift/mask of each field */ +struct amap_eth_rx_compl_v1 { + u8 vlan_tag[16]; /* dword 0 */ + u8 pktsize[14]; /* dword 0 */ + u8 vtp; /* dword 0 */ + u8 ip_opt; /* dword 0 */ + u8 err; /* dword 1 */ + u8 rsshp; /* dword 1 */ + u8 ipf; /* dword 1 */ + u8 tcpf; /* dword 1 */ + u8 udpf; /* dword 1 */ + u8 ipcksm; /* dword 1 */ + u8 l4_cksm; /* dword 1 */ + u8 ip_version; /* dword 1 */ + u8 macdst[7]; /* dword 1 */ + u8 rsvd0; /* dword 1 */ + u8 fragndx[10]; /* dword 1 */ + u8 ct[2]; /* dword 1 */ + u8 sw; /* dword 1 */ + u8 numfrags[3]; /* dword 1 */ + u8 rss_flush; /* dword 2 */ + u8 cast_enc[2]; /* dword 2 */ + u8 vtm; /* dword 2 */ + u8 rss_bank; /* dword 2 */ + u8 port[2]; /* dword 2 */ + u8 vntagp; /* dword 2 */ + u8 header_len[8]; /* dword 2 */ + u8 header_split[2]; /* dword 2 */ + u8 rsvd1[13]; /* dword 2 */ + u8 valid; /* dword 2 */ + u8 rsshash[32]; /* dword 3 */ +} __packed; + struct be_eth_rx_compl { u32 dw[4]; }; diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 68f107817326..3cb5f4e5a06e 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -25,9 +25,9 @@ MODULE_DESCRIPTION(DRV_DESC " " DRV_VER); MODULE_AUTHOR("ServerEngines Corporation"); MODULE_LICENSE("GPL"); -static unsigned int rx_frag_size = 2048; +static ushort rx_frag_size = 2048; static unsigned int num_vfs; -module_param(rx_frag_size, uint, S_IRUGO); +module_param(rx_frag_size, ushort, S_IRUGO); module_param(num_vfs, uint, S_IRUGO); MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data."); MODULE_PARM_DESC(num_vfs, "Number of PCI VFs to initialize"); @@ -851,31 +851,26 @@ static void be_rx_rate_update(struct be_rx_obj *rxo) } static void be_rx_stats_update(struct be_rx_obj *rxo, - u32 pktsize, u16 numfrags, u8 pkt_type) + struct be_rx_compl_info *rxcp) { struct be_rx_stats *stats = &rxo->stats; stats->rx_compl++; - stats->rx_frags += numfrags; - stats->rx_bytes += pktsize; + stats->rx_frags += rxcp->num_rcvd; + stats->rx_bytes += rxcp->pkt_size; stats->rx_pkts++; - if (pkt_type == BE_MULTICAST_PACKET) + if (rxcp->pkt_type == BE_MULTICAST_PACKET) stats->rx_mcast_pkts++; + if (rxcp->err) + stats->rxcp_err++; } -static inline bool csum_passed(struct be_eth_rx_compl *rxcp) +static inline bool csum_passed(struct be_rx_compl_info *rxcp) { - u8 l4_cksm, ipv6, ipcksm, tcpf, udpf; - - l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp); - ipcksm = AMAP_GET_BITS(struct amap_eth_rx_compl, ipcksm, rxcp); - ipv6 = AMAP_GET_BITS(struct amap_eth_rx_compl, ip_version, rxcp); - tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp); - udpf = AMAP_GET_BITS(struct amap_eth_rx_compl, udpf, rxcp); - /* L4 checksum is not reliable for non TCP/UDP packets. * Also ignore ipcksm for ipv6 pkts */ - return (tcpf || udpf) && l4_cksm && (ipcksm || ipv6); + return (rxcp->tcpf || rxcp->udpf) && rxcp->l4_csum && + (rxcp->ip_csum || rxcp->ipv6); } static struct be_rx_page_info * @@ -903,20 +898,17 @@ get_rx_page_info(struct be_adapter *adapter, /* Throwaway the data in the Rx completion */ static void be_rx_compl_discard(struct be_adapter *adapter, struct be_rx_obj *rxo, - struct be_eth_rx_compl *rxcp) + struct be_rx_compl_info *rxcp) { struct be_queue_info *rxq = &rxo->q; struct be_rx_page_info *page_info; - u16 rxq_idx, i, num_rcvd; - - rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); - num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); + u16 i, num_rcvd = rxcp->num_rcvd; for (i = 0; i < num_rcvd; i++) { - page_info = get_rx_page_info(adapter, rxo, rxq_idx); + page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx); put_page(page_info->page); memset(page_info, 0, sizeof(*page_info)); - index_inc(&rxq_idx, rxq->len); + index_inc(&rxcp->rxq_idx, rxq->len); } } @@ -925,30 +917,23 @@ static void be_rx_compl_discard(struct be_adapter *adapter, * indicated by rxcp. */ static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo, - struct sk_buff *skb, struct be_eth_rx_compl *rxcp, - u16 num_rcvd) + struct sk_buff *skb, struct be_rx_compl_info *rxcp) { struct be_queue_info *rxq = &rxo->q; struct be_rx_page_info *page_info; - u16 rxq_idx, i, j; - u32 pktsize, hdr_len, curr_frag_len, size; + u16 i, j; + u16 hdr_len, curr_frag_len, remaining; u8 *start; - u8 pkt_type; - - rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); - pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); - pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl, cast_enc, rxcp); - - page_info = get_rx_page_info(adapter, rxo, rxq_idx); + page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx); start = page_address(page_info->page) + page_info->page_offset; prefetch(start); /* Copy data in the first descriptor of this completion */ - curr_frag_len = min(pktsize, rx_frag_size); + curr_frag_len = min(rxcp->pkt_size, rx_frag_size); /* Copy the header portion into skb_data */ - hdr_len = min((u32)BE_HDR_LEN, curr_frag_len); + hdr_len = min(BE_HDR_LEN, curr_frag_len); memcpy(skb->data, start, hdr_len); skb->len = curr_frag_len; if (curr_frag_len <= BE_HDR_LEN) { /* tiny packet */ @@ -967,19 +952,17 @@ static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo, } page_info->page = NULL; - if (pktsize <= rx_frag_size) { - BUG_ON(num_rcvd != 1); - goto done; + if (rxcp->pkt_size <= rx_frag_size) { + BUG_ON(rxcp->num_rcvd != 1); + return; } /* More frags present for this completion */ - size = pktsize; - for (i = 1, j = 0; i < num_rcvd; i++) { - size -= curr_frag_len; - index_inc(&rxq_idx, rxq->len); - page_info = get_rx_page_info(adapter, rxo, rxq_idx); - - curr_frag_len = min(size, rx_frag_size); + index_inc(&rxcp->rxq_idx, rxq->len); + remaining = rxcp->pkt_size - curr_frag_len; + for (i = 1, j = 0; i < rxcp->num_rcvd; i++) { + page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx); + curr_frag_len = min(remaining, rx_frag_size); /* Coalesce all frags from the same physical page in one slot */ if (page_info->page_offset == 0) { @@ -998,25 +981,19 @@ static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo, skb->len += curr_frag_len; skb->data_len += curr_frag_len; + remaining -= curr_frag_len; + index_inc(&rxcp->rxq_idx, rxq->len); page_info->page = NULL; } BUG_ON(j > MAX_SKB_FRAGS); - -done: - be_rx_stats_update(rxo, pktsize, num_rcvd, pkt_type); } /* Process the RX completion indicated by rxcp when GRO is disabled */ static void be_rx_compl_process(struct be_adapter *adapter, struct be_rx_obj *rxo, - struct be_eth_rx_compl *rxcp) + struct be_rx_compl_info *rxcp) { struct sk_buff *skb; - u32 vlanf, vid; - u16 num_rcvd; - u8 vtm; - - num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); skb = netdev_alloc_skb_ip_align(adapter->netdev, BE_HDR_LEN); if (unlikely(!skb)) { @@ -1026,7 +1003,7 @@ static void be_rx_compl_process(struct be_adapter *adapter, return; } - skb_fill_rx_data(adapter, rxo, skb, rxcp, num_rcvd); + skb_fill_rx_data(adapter, rxo, skb, rxcp); if (likely(adapter->rx_csum && csum_passed(rxcp))) skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -1036,26 +1013,12 @@ static void be_rx_compl_process(struct be_adapter *adapter, skb->truesize = skb->len + sizeof(struct sk_buff); skb->protocol = eth_type_trans(skb, adapter->netdev); - vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); - vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp); - - /* vlanf could be wrongly set in some cards. - * ignore if vtm is not set */ - if ((adapter->function_mode & 0x400) && !vtm) - vlanf = 0; - - if ((adapter->pvid == vlanf) && !adapter->vlan_tag[vlanf]) - vlanf = 0; - - if (unlikely(vlanf)) { + if (unlikely(rxcp->vlanf)) { if (!adapter->vlan_grp || adapter->vlans_added == 0) { kfree_skb(skb); return; } - vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp); - if (!lancer_chip(adapter)) - vid = swab16(vid); - vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, vid); + vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, rxcp->vid); } else { netif_receive_skb(skb); } @@ -1064,31 +1027,14 @@ static void be_rx_compl_process(struct be_adapter *adapter, /* Process the RX completion indicated by rxcp when GRO is enabled */ static void be_rx_compl_process_gro(struct be_adapter *adapter, struct be_rx_obj *rxo, - struct be_eth_rx_compl *rxcp) + struct be_rx_compl_info *rxcp) { struct be_rx_page_info *page_info; struct sk_buff *skb = NULL; struct be_queue_info *rxq = &rxo->q; struct be_eq_obj *eq_obj = &rxo->rx_eq; - u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; - u16 i, rxq_idx = 0, vid, j; - u8 vtm; - u8 pkt_type; - - num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); - pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); - vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); - rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); - vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp); - pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl, cast_enc, rxcp); - - /* vlanf could be wrongly set in some cards. - * ignore if vtm is not set */ - if ((adapter->function_mode & 0x400) && !vtm) - vlanf = 0; - - if ((adapter->pvid == vlanf) && !adapter->vlan_tag[vlanf]) - vlanf = 0; + u16 remaining, curr_frag_len; + u16 i, j; skb = napi_get_frags(&eq_obj->napi); if (!skb) { @@ -1096,9 +1042,9 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, return; } - remaining = pkt_size; - for (i = 0, j = -1; i < num_rcvd; i++) { - page_info = get_rx_page_info(adapter, rxo, rxq_idx); + remaining = rxcp->pkt_size; + for (i = 0, j = -1; i < rxcp->num_rcvd; i++) { + page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx); curr_frag_len = min(remaining, rx_frag_size); @@ -1116,56 +1062,109 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, skb_shinfo(skb)->frags[j].size += curr_frag_len; remaining -= curr_frag_len; - index_inc(&rxq_idx, rxq->len); + index_inc(&rxcp->rxq_idx, rxq->len); memset(page_info, 0, sizeof(*page_info)); } BUG_ON(j > MAX_SKB_FRAGS); skb_shinfo(skb)->nr_frags = j + 1; - skb->len = pkt_size; - skb->data_len = pkt_size; - skb->truesize += pkt_size; + skb->len = rxcp->pkt_size; + skb->data_len = rxcp->pkt_size; + skb->truesize += rxcp->pkt_size; skb->ip_summed = CHECKSUM_UNNECESSARY; - if (likely(!vlanf)) { + if (likely(!rxcp->vlanf)) napi_gro_frags(&eq_obj->napi); - } else { - vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp); - if (!lancer_chip(adapter)) - vid = swab16(vid); + else + vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, rxcp->vid); +} + +static void be_parse_rx_compl_v1(struct be_adapter *adapter, + struct be_eth_rx_compl *compl, + struct be_rx_compl_info *rxcp) +{ + rxcp->pkt_size = + AMAP_GET_BITS(struct amap_eth_rx_compl_v1, pktsize, compl); + rxcp->vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtp, compl); + rxcp->err = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, err, compl); + rxcp->tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, tcpf, compl); + rxcp->ip_csum = + AMAP_GET_BITS(struct amap_eth_rx_compl_v1, ipcksm, compl); + rxcp->l4_csum = + AMAP_GET_BITS(struct amap_eth_rx_compl_v1, l4_cksm, compl); + rxcp->ipv6 = + AMAP_GET_BITS(struct amap_eth_rx_compl_v1, ip_version, compl); + rxcp->rxq_idx = + AMAP_GET_BITS(struct amap_eth_rx_compl_v1, fragndx, compl); + rxcp->num_rcvd = + AMAP_GET_BITS(struct amap_eth_rx_compl_v1, numfrags, compl); + rxcp->pkt_type = + AMAP_GET_BITS(struct amap_eth_rx_compl_v1, cast_enc, compl); + rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtm, compl); + rxcp->vid = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag, compl); +} + +static void be_parse_rx_compl_v0(struct be_adapter *adapter, + struct be_eth_rx_compl *compl, + struct be_rx_compl_info *rxcp) +{ + rxcp->pkt_size = + AMAP_GET_BITS(struct amap_eth_rx_compl_v0, pktsize, compl); + rxcp->vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtp, compl); + rxcp->err = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, err, compl); + rxcp->tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, tcpf, compl); + rxcp->ip_csum = + AMAP_GET_BITS(struct amap_eth_rx_compl_v0, ipcksm, compl); + rxcp->l4_csum = + AMAP_GET_BITS(struct amap_eth_rx_compl_v0, l4_cksm, compl); + rxcp->ipv6 = + AMAP_GET_BITS(struct amap_eth_rx_compl_v0, ip_version, compl); + rxcp->rxq_idx = + AMAP_GET_BITS(struct amap_eth_rx_compl_v0, fragndx, compl); + rxcp->num_rcvd = + AMAP_GET_BITS(struct amap_eth_rx_compl_v0, numfrags, compl); + rxcp->pkt_type = + AMAP_GET_BITS(struct amap_eth_rx_compl_v0, cast_enc, compl); + rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtm, compl); + rxcp->vid = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag, compl); +} + +static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo) +{ + struct be_eth_rx_compl *compl = queue_tail_node(&rxo->cq); + struct be_rx_compl_info *rxcp = &rxo->rxcp; + struct be_adapter *adapter = rxo->adapter; - if (!adapter->vlan_grp || adapter->vlans_added == 0) - return; + /* For checking the valid bit it is Ok to use either definition as the + * valid bit is at the same position in both v0 and v1 Rx compl */ + if (compl->dw[offsetof(struct amap_eth_rx_compl_v1, valid) / 32] == 0) + return NULL; - vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, vid); - } + rmb(); + be_dws_le_to_cpu(compl, sizeof(*compl)); - be_rx_stats_update(rxo, pkt_size, num_rcvd, pkt_type); -} + if (adapter->be3_native) + be_parse_rx_compl_v1(adapter, compl, rxcp); + else + be_parse_rx_compl_v0(adapter, compl, rxcp); -static struct be_eth_rx_compl *be_rx_compl_get(struct be_rx_obj *rxo) -{ - struct be_eth_rx_compl *rxcp = queue_tail_node(&rxo->cq); + /* vlanf could be wrongly set in some cards. ignore if vtm is not set */ + if ((adapter->function_mode & 0x400) && !rxcp->vtm) + rxcp->vlanf = 0; - if (rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] == 0) - return NULL; + if (!lancer_chip(adapter)) + rxcp->vid = swab16(rxcp->vid); - rmb(); - be_dws_le_to_cpu(rxcp, sizeof(*rxcp)); + if ((adapter->pvid == rxcp->vid) && !adapter->vlan_tag[rxcp->vid]) + rxcp->vlanf = 0; + + /* As the compl has been parsed, reset it; we wont touch it again */ + compl->dw[offsetof(struct amap_eth_rx_compl_v1, valid) / 32] = 0; queue_tail_inc(&rxo->cq); return rxcp; } -/* To reset the valid bit, we need to reset the whole word as - * when walking the queue the valid entries are little-endian - * and invalid entries are host endian - */ -static inline void be_rx_compl_reset(struct be_eth_rx_compl *rxcp) -{ - rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] = 0; -} - static inline struct page *be_alloc_pages(u32 size, gfp_t gfp) { u32 order = get_order(size); @@ -1342,13 +1341,12 @@ static void be_rx_q_clean(struct be_adapter *adapter, struct be_rx_obj *rxo) struct be_rx_page_info *page_info; struct be_queue_info *rxq = &rxo->q; struct be_queue_info *rx_cq = &rxo->cq; - struct be_eth_rx_compl *rxcp; + struct be_rx_compl_info *rxcp; u16 tail; /* First cleanup pending rx completions */ while ((rxcp = be_rx_compl_get(rxo)) != NULL) { be_rx_compl_discard(adapter, rxo, rxcp); - be_rx_compl_reset(rxcp); be_cq_notify(adapter, rx_cq->id, false, 1); } @@ -1697,15 +1695,9 @@ static irqreturn_t be_msix_tx_mcc(int irq, void *dev) return IRQ_HANDLED; } -static inline bool do_gro(struct be_rx_obj *rxo, - struct be_eth_rx_compl *rxcp, u8 err) +static inline bool do_gro(struct be_rx_compl_info *rxcp) { - int tcp_frame = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp); - - if (err) - rxo->stats.rxcp_err++; - - return (tcp_frame && !err) ? true : false; + return (rxcp->tcpf && !rxcp->err) ? true : false; } static int be_poll_rx(struct napi_struct *napi, int budget) @@ -1714,10 +1706,8 @@ static int be_poll_rx(struct napi_struct *napi, int budget) struct be_rx_obj *rxo = container_of(rx_eq, struct be_rx_obj, rx_eq); struct be_adapter *adapter = rxo->adapter; struct be_queue_info *rx_cq = &rxo->cq; - struct be_eth_rx_compl *rxcp; + struct be_rx_compl_info *rxcp; u32 work_done; - u16 num_rcvd; - u8 err; rxo->stats.rx_polls++; for (work_done = 0; work_done < budget; work_done++) { @@ -1725,18 +1715,14 @@ static int be_poll_rx(struct napi_struct *napi, int budget) if (!rxcp) break; - err = AMAP_GET_BITS(struct amap_eth_rx_compl, err, rxcp); - num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, - rxcp); /* Ignore flush completions */ - if (num_rcvd) { - if (do_gro(rxo, rxcp, err)) + if (rxcp->num_rcvd) { + if (do_gro(rxcp)) be_rx_compl_process_gro(adapter, rxo, rxcp); else be_rx_compl_process(adapter, rxo, rxcp); } - - be_rx_compl_reset(rxcp); + be_rx_stats_update(rxo, rxcp); } /* Refill the queue */ @@ -2868,6 +2854,7 @@ static int be_get_config(struct be_adapter *adapter) if (status) return status; + be_cmd_check_native_mode(adapter); return 0; } -- cgit v1.2.3 From ac90fa63432b3c03c189c39e62211d3b80418c30 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sun, 13 Mar 2011 06:54:30 +0000 Subject: NET: cdc-phonet, fix stop-queue handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently there is a warning emitted by the cdc-phonet driver: WARNING: at include/linux/netdevice.h:1557 usbpn_probe+0x3bb/0x3f0 [cdc_phonet]() Modules linked in: ... Pid: 5877, comm: insmod Not tainted 2.6.37.3-16-desktop #1 Call Trace: [] dump_trace+0x79/0x340 [] dump_stack+0x69/0x6f [] warn_slowpath_common+0x7b/0xc0 [] usbpn_probe+0x3bb/0x3f0 [cdc_phonet] ... ---[ end trace f5d3e02908603ab4 ]--- netif_stop_queue() cannot be called before register_netdev() So remove netif_stop_queue from the probe funtction to avoid that. Signed-off-by: Jiri Slaby Cc: Rémi Denis-Courmont Cc: David S. Miller Acked-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- drivers/net/usb/cdc-phonet.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c index 109751bad3bb..4cf4e361c121 100644 --- a/drivers/net/usb/cdc-phonet.c +++ b/drivers/net/usb/cdc-phonet.c @@ -392,7 +392,6 @@ int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id) pnd = netdev_priv(dev); SET_NETDEV_DEV(dev, &intf->dev); - netif_stop_queue(dev); pnd->dev = dev; pnd->usb = usb_get_dev(usbdev); -- cgit v1.2.3 From 468c3f924f043cad7a04f4f4d5224a2c9bc886c1 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sun, 13 Mar 2011 06:54:31 +0000 Subject: NET: cdc-phonet, handle empty phonet header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, for N 5800 XM I get: cdc_phonet: probe of 1-6:1.10 failed with error -22 It's because phonet_header is empty. Extra altsetting looks like there: E 05 24 00 01 10 03 24 ab 05 24 06 0a 0b 04 24 fd .$....$..$....$. E 00 . I don't see the header used anywhere so just check if the phonet descriptor is there, not the structure itself. Signed-off-by: Jiri Slaby Cc: Rémi Denis-Courmont Cc: David S. Miller Acked-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- drivers/net/usb/cdc-phonet.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c index 4cf4e361c121..f967913e11bc 100644 --- a/drivers/net/usb/cdc-phonet.c +++ b/drivers/net/usb/cdc-phonet.c @@ -328,13 +328,13 @@ int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id) { static const char ifname[] = "usbpn%d"; const struct usb_cdc_union_desc *union_header = NULL; - const struct usb_cdc_header_desc *phonet_header = NULL; const struct usb_host_interface *data_desc; struct usb_interface *data_intf; struct usb_device *usbdev = interface_to_usbdev(intf); struct net_device *dev; struct usbpn_dev *pnd; u8 *data; + int phonet = 0; int len, err; data = intf->altsetting->extra; @@ -355,10 +355,7 @@ int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id) (struct usb_cdc_union_desc *)data; break; case 0xAB: - if (phonet_header || dlen < 5) - break; - phonet_header = - (struct usb_cdc_header_desc *)data; + phonet = 1; break; } } @@ -366,7 +363,7 @@ int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id) len -= dlen; } - if (!union_header || !phonet_header) + if (!union_header || !phonet) return -EINVAL; data_intf = usb_ifnum_to_if(usbdev, union_header->bSlaveInterface0); -- cgit v1.2.3 From dcf4ae2dba541eed96afb0ba13e562defb8543e6 Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Mon, 14 Mar 2011 15:39:47 -0700 Subject: qeth: change some configurations defaults This patch turns on RX checksum and GRO by default. To improve receiving performance and reduce congestion in case of network bursts we also increase the default number of inbound buffers. Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 3 ++- drivers/s390/net/qeth_core_main.c | 5 ++++- drivers/s390/net/qeth_l3_main.c | 5 +++++ 3 files changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index c5d763ed406e..af3f7b095647 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -225,7 +225,8 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, /*****************************************************************************/ #define QETH_MAX_QUEUES 4 #define QETH_IN_BUF_SIZE_DEFAULT 65536 -#define QETH_IN_BUF_COUNT_DEFAULT 16 +#define QETH_IN_BUF_COUNT_DEFAULT 64 +#define QETH_IN_BUF_COUNT_HSDEFAULT 128 #define QETH_IN_BUF_COUNT_MIN 8 #define QETH_IN_BUF_COUNT_MAX 128 #define QETH_MAX_BUFFER_ELEMENTS(card) ((card)->qdio.in_buf_size >> 12) diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index f3d98ac16e9f..25eef304bd47 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -1026,7 +1026,10 @@ static void qeth_init_qdio_info(struct qeth_card *card) atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED); /* inbound */ card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT; - card->qdio.init_pool.buf_count = QETH_IN_BUF_COUNT_DEFAULT; + if (card->info.type == QETH_CARD_TYPE_IQD) + card->qdio.init_pool.buf_count = QETH_IN_BUF_COUNT_HSDEFAULT; + else + card->qdio.init_pool.buf_count = QETH_IN_BUF_COUNT_DEFAULT; card->qdio.in_buf_pool.buf_count = card->qdio.init_pool.buf_count; INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list); INIT_LIST_HEAD(&card->qdio.init_pool.entry_list); diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 6a9cc58321a0..142e5f6ef4f3 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -3392,6 +3392,8 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD)) card->dev->dev_id = card->info.unique_id & 0xffff; + if (!card->info.guestlan) + card->dev->features |= NETIF_F_GRO; } } else if (card->info.type == QETH_CARD_TYPE_IQD) { card->dev = alloc_netdev(0, "hsi%d", ether_setup); @@ -3430,6 +3432,9 @@ static int qeth_l3_probe_device(struct ccwgroup_device *gdev) card->discipline.output_handler = (qdio_handler_t *) qeth_qdio_output_handler; card->discipline.recover = qeth_l3_recover; + if ((card->info.type == QETH_CARD_TYPE_OSD) || + (card->info.type == QETH_CARD_TYPE_OSX)) + card->options.checksum_type = HW_CHECKSUMMING; return 0; } -- cgit v1.2.3 From c05e7ac99c32d4e5d8be272c0ba95b0fdcab431b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 14 Mar 2011 15:40:39 -0700 Subject: ftmac100: use GFP_ATOMIC allocations where needed When running in softirq context, we should use GFP_ATOMIC allocations instead of GFP_KERNEL ones. Signed-off-by: Eric Dumazet Tested-by: Po-Yu Chuang Acked-by: Po-Yu Chuang Signed-off-by: David S. Miller --- drivers/net/ftmac100.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ftmac100.c b/drivers/net/ftmac100.c index df70368bf317..1d6f4b8d393a 100644 --- a/drivers/net/ftmac100.c +++ b/drivers/net/ftmac100.c @@ -80,7 +80,8 @@ struct ftmac100 { struct mii_if_info mii; }; -static int ftmac100_alloc_rx_page(struct ftmac100 *priv, struct ftmac100_rxdes *rxdes); +static int ftmac100_alloc_rx_page(struct ftmac100 *priv, + struct ftmac100_rxdes *rxdes, gfp_t gfp); /****************************************************************************** * internal functions (hardware register access) @@ -441,7 +442,7 @@ static bool ftmac100_rx_packet(struct ftmac100 *priv, int *processed) skb->truesize += length; __pskb_pull_tail(skb, min(length, 64)); - ftmac100_alloc_rx_page(priv, rxdes); + ftmac100_alloc_rx_page(priv, rxdes, GFP_ATOMIC); ftmac100_rx_pointer_advance(priv); @@ -659,13 +660,14 @@ static int ftmac100_xmit(struct ftmac100 *priv, struct sk_buff *skb, /****************************************************************************** * internal functions (buffer) *****************************************************************************/ -static int ftmac100_alloc_rx_page(struct ftmac100 *priv, struct ftmac100_rxdes *rxdes) +static int ftmac100_alloc_rx_page(struct ftmac100 *priv, + struct ftmac100_rxdes *rxdes, gfp_t gfp) { struct net_device *netdev = priv->netdev; struct page *page; dma_addr_t map; - page = alloc_page(GFP_KERNEL); + page = alloc_page(gfp); if (!page) { if (net_ratelimit()) netdev_err(netdev, "failed to allocate rx page\n"); @@ -736,7 +738,7 @@ static int ftmac100_alloc_buffers(struct ftmac100 *priv) for (i = 0; i < RX_QUEUE_ENTRIES; i++) { struct ftmac100_rxdes *rxdes = &priv->descs->rxdes[i]; - if (ftmac100_alloc_rx_page(priv, rxdes)) + if (ftmac100_alloc_rx_page(priv, rxdes, GFP_KERNEL)) goto err; } -- cgit v1.2.3 From 1a738dcf6dac74a0ce10853a068d822f66f73268 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Wed, 22 Dec 2010 21:04:11 +0900 Subject: pch_phub: add new device ML7213 Add ML7213 device information. ML7213 is companion chip of Intel Atom E6xx series for IVI(In-Vehicle Infotainment). ML7213 is completely compatible for Intel EG20T PCH. Signed-off-by: Tomoya MORINAGA Signed-off-by: Greg Kroah-Hartman --- drivers/misc/Kconfig | 7 ++++- drivers/misc/pch_phub.c | 69 +++++++++++++++++++++++++++++++++---------------- 2 files changed, 53 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index cc8e49db45fe..b7d5ef234ac9 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -441,7 +441,7 @@ config BMP085 module will be called bmp085. config PCH_PHUB - tristate "PCH Packet Hub of Intel Topcliff" + tristate "PCH Packet Hub of Intel Topcliff / OKI SEMICONDUCTOR ML7213" depends on PCI help This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of @@ -449,6 +449,11 @@ config PCH_PHUB processor. The Topcliff has MAC address and Option ROM data in SROM. This driver can access MAC address and Option ROM data in SROM. + This driver also can be used for OKI SEMICONDUCTOR's ML7213 which is + for IVI(In-Vehicle Infotainment) use. + ML7213 is companion chip for Intel Atom E6xx series. + ML7213 is completely compatible for Intel EG20T PCH. + To compile this driver as a module, choose M here: the module will be called pch_phub. diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c index 744b804aca15..98bffc471b17 100644 --- a/drivers/misc/pch_phub.c +++ b/drivers/misc/pch_phub.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,7 +33,12 @@ #define PHUB_TIMEOUT 0x05 /* Time out value for Status Register */ #define PCH_PHUB_ROM_WRITE_ENABLE 0x01 /* Enabling for writing ROM */ #define PCH_PHUB_ROM_WRITE_DISABLE 0x00 /* Disabling for writing ROM */ -#define PCH_PHUB_ROM_START_ADDR 0x14 /* ROM data area start address offset */ +#define PCH_PHUB_MAC_START_ADDR 0x20C /* MAC data area start address offset */ +#define PCH_PHUB_ROM_START_ADDR_EG20T 0x14 /* ROM data area start address offset + (Intel EG20T PCH)*/ +#define PCH_PHUB_ROM_START_ADDR_ML7213 0x400 /* ROM data area start address + offset(OKI SEMICONDUCTOR ML7213) + */ /* MAX number of INT_REDUCE_CONTROL registers */ #define MAX_NUM_INT_REDUCE_CONTROL_REG 128 @@ -42,6 +47,10 @@ #define CLKCFG_CAN_50MHZ 0x12000000 #define CLKCFG_CANCLK_MASK 0xFF000000 +/* Macros for ML7213 */ +#define PCI_VENDOR_ID_ROHM 0x10db +#define PCI_DEVICE_ID_ROHM_ML7213_PHUB 0x801A + /* SROM ACCESS Macro */ #define PCH_WORD_ADDR_MASK (~((1 << 2) - 1)) @@ -298,7 +307,7 @@ static void pch_phub_read_serial_rom_val(struct pch_phub_reg *chip, { unsigned int mem_addr; - mem_addr = PCH_PHUB_ROM_START_ADDR + + mem_addr = PCH_PHUB_ROM_START_ADDR_EG20T + pch_phub_mac_offset[offset_address]; pch_phub_read_serial_rom(chip, mem_addr, data); @@ -315,7 +324,7 @@ static int pch_phub_write_serial_rom_val(struct pch_phub_reg *chip, int retval; unsigned int mem_addr; - mem_addr = PCH_PHUB_ROM_START_ADDR + + mem_addr = PCH_PHUB_ROM_START_ADDR_EG20T + pch_phub_mac_offset[offset_address]; retval = pch_phub_write_serial_rom(chip, mem_addr, data); @@ -594,23 +603,38 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev, "pch_phub_extrom_base_address variable is %p\n", __func__, chip->pch_phub_extrom_base_address); - pci_set_drvdata(pdev, chip); - - retval = sysfs_create_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); - if (retval) - goto err_sysfs_create; - - retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); - if (retval) - goto exit_bin_attr; - - pch_phub_read_modify_write_reg(chip, (unsigned int)CLKCFG_REG_OFFSET, - CLKCFG_CAN_50MHZ, CLKCFG_CANCLK_MASK); + if (id->driver_data == 1) { + retval = sysfs_create_file(&pdev->dev.kobj, + &dev_attr_pch_mac.attr); + if (retval) + goto err_sysfs_create; - /* set the prefech value */ - iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14); - /* set the interrupt delay value */ - iowrite32(0x25, chip->pch_phub_base_address + 0x44); + retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); + if (retval) + goto exit_bin_attr; + + pch_phub_read_modify_write_reg(chip, + (unsigned int)CLKCFG_REG_OFFSET, + CLKCFG_CAN_50MHZ, + CLKCFG_CANCLK_MASK); + + /* set the prefech value */ + iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14); + /* set the interrupt delay value */ + iowrite32(0x25, chip->pch_phub_base_address + 0x44); + } else if (id->driver_data == 2) { + retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); + if (retval) + goto err_sysfs_create; + /* set the prefech value + * Device2(USB OHCI #1/ USB EHCI #1/ USB Device):a + * Device4(SDIO #0,1,2):f + * Device6(SATA 2):f + * Device8(USB OHCI #0/ USB EHCI #0):a + */ + iowrite32(0x000affa0, chip->pch_phub_base_address + 0x14); + } + pci_set_drvdata(pdev, chip); return 0; exit_bin_attr: @@ -687,8 +711,9 @@ static int pch_phub_resume(struct pci_dev *pdev) #endif /* CONFIG_PM */ static struct pci_device_id pch_phub_pcidev_id[] = { - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH1_PHUB)}, - {0,} + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH1_PHUB), 1, }, + { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2, }, + { } }; static struct pci_driver pch_phub_driver = { -- cgit v1.2.3 From 6ae705b23be8da52d3163be9d81e9b767876aaf9 Mon Sep 17 00:00:00 2001 From: Denis Turischev Date: Thu, 10 Mar 2011 15:14:00 +0200 Subject: pch_uart: reference clock on CM-iTC Default clock source for UARTs on Topcliff is external UART_CLK. On CM-iTC USB_48MHz is used instead. After VCO2PLL and DIV manipulations UARTs will receive 192 MHz. Clock manipulations on Topcliff are controlled in pch_phub.c v2: redone against the linux-next tree v3: redone against linux/kernel/git/next/linux-next.git snapshot Signed-off-by: Denis Turischev Signed-off-by: Greg Kroah-Hartman --- drivers/misc/pch_phub.c | 16 ++++++++++++++++ drivers/tty/serial/pch_uart.c | 9 +++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c index 98bffc471b17..5dd0b921bfc6 100644 --- a/drivers/misc/pch_phub.c +++ b/drivers/misc/pch_phub.c @@ -27,6 +27,7 @@ #include #include #include +#include #define PHUB_STATUS 0x00 /* Status Register offset */ #define PHUB_CONTROL 0x04 /* Control Register offset */ @@ -46,6 +47,13 @@ #define PCH_MINOR_NOS 1 #define CLKCFG_CAN_50MHZ 0x12000000 #define CLKCFG_CANCLK_MASK 0xFF000000 +#define CLKCFG_UART_MASK 0xFFFFFF + +/* CM-iTC */ +#define CLKCFG_UART_48MHZ (1 << 16) +#define CLKCFG_BAUDDIV (2 << 20) +#define CLKCFG_PLL2VCO (8 << 9) +#define CLKCFG_UARTCLKSEL (1 << 18) /* Macros for ML7213 */ #define PCI_VENDOR_ID_ROHM 0x10db @@ -618,6 +626,14 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev, CLKCFG_CAN_50MHZ, CLKCFG_CANCLK_MASK); + /* quirk for CM-iTC board */ + if (strstr(dmi_get_system_info(DMI_BOARD_NAME), "CM-iTC")) + pch_phub_read_modify_write_reg(chip, + (unsigned int)CLKCFG_REG_OFFSET, + CLKCFG_UART_48MHZ | CLKCFG_BAUDDIV | + CLKCFG_PLL2VCO | CLKCFG_UARTCLKSEL, + CLKCFG_UART_MASK); + /* set the prefech value */ iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14); /* set the interrupt delay value */ diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index a5ce9a5c018d..a9ad7f33526d 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -1404,14 +1405,18 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, if (!rxbuf) goto init_port_free_txbuf; + base_baud = 1843200; /* 1.8432MHz */ + + /* quirk for CM-iTC board */ + if (strstr(dmi_get_system_info(DMI_BOARD_NAME), "CM-iTC")) + base_baud = 192000000; /* 192.0MHz */ + switch (port_type) { case PORT_UNKNOWN: fifosize = 256; /* EG20T/ML7213: UART0 */ - base_baud = 1843200; /* 1.8432MHz */ break; case PORT_8250: fifosize = 64; /* EG20T:UART1~3 ML7213: UART1~2*/ - base_baud = 1843200; /* 1.8432MHz */ break; default: dev_err(&pdev->dev, "Invalid Port Type(=%d)\n", port_type); -- cgit v1.2.3 From 023d3779145ec6b7a0f38f19672a347b92feb74e Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 31 Jan 2011 11:06:39 +0100 Subject: PM / Wakeup: Combine atomic counters to avoid reordering issues The memory barrier in wakeup_source_deactivate() is supposed to prevent the callers of pm_wakeup_pending() and pm_get_wakeup_count() from seeing the new value of events_in_progress (0, in particular) and the old value of event_count at the same time. However, if wakeup_source_deactivate() is executed by CPU0 and, for instance, pm_wakeup_pending() is executed by CPU1, where both processors can reorder operations, the memory barrier in wakeup_source_deactivate() doesn't affect CPU1 which can reorder reads. In that case CPU1 may very well decide to fetch event_count before it's modified and events_in_progress after it's been updated, so pm_wakeup_pending() may fail to detect a wakeup event. This issue can be addressed by using a single atomic variable to store both events_in_progress and event_count, so that they can be updated together in a single atomic operation. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/wakeup.c | 61 +++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 8ec406d8f548..e5e73b5efc80 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -24,12 +24,26 @@ */ bool events_check_enabled; -/* The counter of registered wakeup events. */ -static atomic_t event_count = ATOMIC_INIT(0); -/* A preserved old value of event_count. */ +/* + * Combined counters of registered wakeup events and wakeup events in progress. + * They need to be modified together atomically, so it's better to use one + * atomic variable to hold them both. + */ +static atomic_t combined_event_count = ATOMIC_INIT(0); + +#define IN_PROGRESS_BITS (sizeof(int) * 4) +#define MAX_IN_PROGRESS ((1 << IN_PROGRESS_BITS) - 1) + +static void split_counters(unsigned int *cnt, unsigned int *inpr) +{ + unsigned int comb = atomic_read(&combined_event_count); + + *cnt = (comb >> IN_PROGRESS_BITS); + *inpr = comb & MAX_IN_PROGRESS; +} + +/* A preserved old value of the events counter. */ static unsigned int saved_count; -/* The counter of wakeup events being processed. */ -static atomic_t events_in_progress = ATOMIC_INIT(0); static DEFINE_SPINLOCK(events_lock); @@ -307,7 +321,8 @@ static void wakeup_source_activate(struct wakeup_source *ws) ws->timer_expires = jiffies; ws->last_time = ktime_get(); - atomic_inc(&events_in_progress); + /* Increment the counter of events in progress. */ + atomic_inc(&combined_event_count); } /** @@ -394,14 +409,10 @@ static void wakeup_source_deactivate(struct wakeup_source *ws) del_timer(&ws->timer); /* - * event_count has to be incremented before events_in_progress is - * modified, so that the callers of pm_check_wakeup_events() and - * pm_save_wakeup_count() don't see the old value of event_count and - * events_in_progress equal to zero at the same time. + * Increment the counter of registered wakeup events and decrement the + * couter of wakeup events in progress simultaneously. */ - atomic_inc(&event_count); - smp_mb__before_atomic_dec(); - atomic_dec(&events_in_progress); + atomic_add(MAX_IN_PROGRESS, &combined_event_count); } /** @@ -556,8 +567,10 @@ bool pm_wakeup_pending(void) spin_lock_irqsave(&events_lock, flags); if (events_check_enabled) { - ret = ((unsigned int)atomic_read(&event_count) != saved_count) - || atomic_read(&events_in_progress); + unsigned int cnt, inpr; + + split_counters(&cnt, &inpr); + ret = (cnt != saved_count || inpr > 0); events_check_enabled = !ret; } spin_unlock_irqrestore(&events_lock, flags); @@ -579,19 +592,22 @@ bool pm_wakeup_pending(void) */ bool pm_get_wakeup_count(unsigned int *count) { - bool ret; + unsigned int cnt, inpr; if (capable(CAP_SYS_ADMIN)) events_check_enabled = false; - while (atomic_read(&events_in_progress) && !signal_pending(current)) { + for (;;) { + split_counters(&cnt, &inpr); + if (inpr == 0 || signal_pending(current)) + break; pm_wakeup_update_hit_counts(); schedule_timeout_interruptible(msecs_to_jiffies(TIMEOUT)); } - ret = !atomic_read(&events_in_progress); - *count = atomic_read(&event_count); - return ret; + split_counters(&cnt, &inpr); + *count = cnt; + return !inpr; } /** @@ -605,11 +621,12 @@ bool pm_get_wakeup_count(unsigned int *count) */ bool pm_save_wakeup_count(unsigned int count) { + unsigned int cnt, inpr; bool ret = false; spin_lock_irq(&events_lock); - if (count == (unsigned int)atomic_read(&event_count) - && !atomic_read(&events_in_progress)) { + split_counters(&cnt, &inpr); + if (cnt == count && inpr == 0) { saved_count = count; events_check_enabled = true; ret = true; -- cgit v1.2.3 From 378eef99ad45700aabfba2bd962516e5608b259a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 31 Jan 2011 11:06:50 +0100 Subject: PM / Wakeup: Make pm_save_wakeup_count() work as documented According to Documentation/ABI/testing/sysfs-power, the /sys/power/wakeup_count interface should only make the kernel react to wakeup events during suspend if the last write to it has been successful. However, if /sys/power/wakeup_count is written to two times in a row, where the first write is successful and the second is not, the kernel will still react to wakeup events during suspend due to a bug in pm_save_wakeup_count(). Fix the bug by making pm_save_wakeup_count() clear events_check_enabled unconditionally before checking if there are any new wakeup events registered since the previous read from /sys/power/wakeup_count. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/wakeup.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index e5e73b5efc80..07e08c3aece4 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -616,25 +616,25 @@ bool pm_get_wakeup_count(unsigned int *count) * * If @count is equal to the current number of registered wakeup events and the * current number of wakeup events being processed is zero, store @count as the - * old number of registered wakeup events to be used by pm_check_wakeup_events() - * and return true. Otherwise return false. + * old number of registered wakeup events for pm_check_wakeup_events(), enable + * wakeup events detection and return 'true'. Otherwise disable wakeup events + * detection and return 'false'. */ bool pm_save_wakeup_count(unsigned int count) { unsigned int cnt, inpr; - bool ret = false; + events_check_enabled = false; spin_lock_irq(&events_lock); split_counters(&cnt, &inpr); if (cnt == count && inpr == 0) { saved_count = count; events_check_enabled = true; - ret = true; } spin_unlock_irq(&events_lock); - if (!ret) + if (!events_check_enabled) pm_wakeup_update_hit_counts(); - return ret; + return events_check_enabled; } static struct dentry *wakeup_sources_stats_dentry; -- cgit v1.2.3 From 790c7885a4b2105e41f7a80b035fdb78e406154f Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 31 Jan 2011 11:07:01 +0100 Subject: PM / Wakeup: Don't update events_check_enabled in pm_get_wakeup_count() Since pm_save_wakeup_count() has just been changed to clear events_check_enabled unconditionally before checking if there are any new wakeup events registered since the last read from /sys/power/wakeup_count, the detection of wakeup events during suspend may be disabled, after it's been enabled, by writing a "wrong" value back to /sys/power/wakeup_count. For this reason, it is not necessary to update events_check_enabled in pm_get_wakeup_count() any more. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/wakeup.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 07e08c3aece4..82836383997f 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -586,17 +586,14 @@ bool pm_wakeup_pending(void) * Store the number of registered wakeup events at the address in @count. Block * if the current number of wakeup events being processed is nonzero. * - * Return false if the wait for the number of wakeup events being processed to + * Return 'false' if the wait for the number of wakeup events being processed to * drop down to zero has been interrupted by a signal (and the current number - * of wakeup events being processed is still nonzero). Otherwise return true. + * of wakeup events being processed is still nonzero). Otherwise return 'true'. */ bool pm_get_wakeup_count(unsigned int *count) { unsigned int cnt, inpr; - if (capable(CAP_SYS_ADMIN)) - events_check_enabled = false; - for (;;) { split_counters(&cnt, &inpr); if (inpr == 0 || signal_pending(current)) -- cgit v1.2.3 From 0295a34d61f14522fddb26856191520d2e1d7e77 Mon Sep 17 00:00:00 2001 From: Mandeep Singh Baines Date: Mon, 31 Jan 2011 11:07:14 +0100 Subject: PM: Use appropriate printk() priority level in trace.c printk()s without a priority level default to KERN_WARNING. To reduce noise at KERN_WARNING, this patch sets the priority level appriopriately for unleveled printks()s. This should be useful to folks that look at dmesg warnings closely. Changed these messages to pr_info(). Signed-off-by: Mandeep Singh Baines Signed-off-by: Rafael J. Wysocki --- drivers/base/power/trace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/trace.c b/drivers/base/power/trace.c index 9f4258df4cfd..c80e138b62fe 100644 --- a/drivers/base/power/trace.c +++ b/drivers/base/power/trace.c @@ -112,7 +112,7 @@ static unsigned int read_magic_time(void) unsigned int val; get_rtc_time(&time); - printk("Time: %2d:%02d:%02d Date: %02d/%02d/%02d\n", + pr_info("Time: %2d:%02d:%02d Date: %02d/%02d/%02d\n", time.tm_hour, time.tm_min, time.tm_sec, time.tm_mon + 1, time.tm_mday, time.tm_year % 100); val = time.tm_year; /* 100 years */ @@ -179,7 +179,7 @@ static int show_file_hash(unsigned int value) unsigned int hash = hash_string(lineno, file, FILEHASH); if (hash != value) continue; - printk(" hash matches %s:%u\n", file, lineno); + pr_info(" hash matches %s:%u\n", file, lineno); match++; } return match; @@ -255,7 +255,7 @@ static int late_resume_init(void) val = val / FILEHASH; dev = val /* % DEVHASH */; - printk(" Magic number: %d:%d:%d\n", user, file, dev); + pr_info(" Magic number: %d:%d:%d\n", user, file, dev); show_file_hash(file); show_dev_hash(dev); return 0; -- cgit v1.2.3 From 4681b17154b3fd81f898802262985f662344e6ed Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 8 Feb 2011 23:25:48 +0100 Subject: USB / Hub: Do not call device_set_wakeup_capable() under spinlock A subsequent patch will modify device_set_wakeup_capable() in such a way that it will call functions which may sleep and therefore it shouldn't be called under spinlocks. In preparation to that, modify usb_set_device_state() to avoid calling device_set_wakeup_capable() under device_state_lock. Tested-by: Minchan Kim Signed-off-by: Rafael J. Wysocki Acked-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 0f299b7aad60..19d3435e6140 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1465,6 +1465,7 @@ void usb_set_device_state(struct usb_device *udev, enum usb_device_state new_state) { unsigned long flags; + int wakeup = -1; spin_lock_irqsave(&device_state_lock, flags); if (udev->state == USB_STATE_NOTATTACHED) @@ -1479,11 +1480,10 @@ void usb_set_device_state(struct usb_device *udev, || new_state == USB_STATE_SUSPENDED) ; /* No change to wakeup settings */ else if (new_state == USB_STATE_CONFIGURED) - device_set_wakeup_capable(&udev->dev, - (udev->actconfig->desc.bmAttributes - & USB_CONFIG_ATT_WAKEUP)); + wakeup = udev->actconfig->desc.bmAttributes + & USB_CONFIG_ATT_WAKEUP; else - device_set_wakeup_capable(&udev->dev, 0); + wakeup = 0; } if (udev->state == USB_STATE_SUSPENDED && new_state != USB_STATE_SUSPENDED) @@ -1495,6 +1495,8 @@ void usb_set_device_state(struct usb_device *udev, } else recursively_mark_NOTATTACHED(udev); spin_unlock_irqrestore(&device_state_lock, flags); + if (wakeup >= 0) + device_set_wakeup_capable(&udev->dev, wakeup); } EXPORT_SYMBOL_GPL(usb_set_device_state); -- cgit v1.2.3 From cb8f51bdadb7969139c2e39c2defd4cde98c1ea8 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 8 Feb 2011 23:26:02 +0100 Subject: PM: Do not create wakeup sysfs files for devices that cannot wake up Currently, wakeup sysfs attributes are created for all devices, regardless of whether or not they are wakeup-capable. This is excessive and complicates wakeup device identification from user space (i.e. to identify wakeup-capable devices user space has to read /sys/devices/.../power/wakeup for all devices and see if they are not empty). Fix this issue by avoiding to create wakeup sysfs files for devices that cannot wake up the system from sleep states (i.e. whose power.can_wakeup flags are unset during registration) and modify device_set_wakeup_capable() so that it adds (or removes) the relevant sysfs attributes if a device's wakeup capability status is changed. Signed-off-by: Rafael J. Wysocki --- Documentation/ABI/testing/sysfs-devices-power | 20 +++---- Documentation/power/devices.txt | 20 +++---- drivers/base/power/power.h | 21 ++++---- drivers/base/power/sysfs.c | 78 +++++++++++++++++---------- drivers/base/power/wakeup.c | 29 ++++++++++ include/linux/pm_runtime.h | 6 +++ include/linux/pm_wakeup.h | 8 +-- 7 files changed, 117 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/Documentation/ABI/testing/sysfs-devices-power b/Documentation/ABI/testing/sysfs-devices-power index 7628cd1bc36a..8ffbc25376a0 100644 --- a/Documentation/ABI/testing/sysfs-devices-power +++ b/Documentation/ABI/testing/sysfs-devices-power @@ -29,9 +29,8 @@ Description: "disabled" to it. For the devices that are not capable of generating system wakeup - events this file contains "\n". In that cases the user space - cannot modify the contents of this file and the device cannot be - enabled to wake up the system. + events this file is not present. In that case the device cannot + be enabled to wake up the system from sleep states. What: /sys/devices/.../power/control Date: January 2009 @@ -85,7 +84,7 @@ Description: The /sys/devices/.../wakeup_count attribute contains the number of signaled wakeup events associated with the device. This attribute is read-only. If the device is not enabled to wake up - the system from sleep states, this attribute is empty. + the system from sleep states, this attribute is not present. What: /sys/devices/.../power/wakeup_active_count Date: September 2010 @@ -95,7 +94,7 @@ Description: number of times the processing of wakeup events associated with the device was completed (at the kernel level). This attribute is read-only. If the device is not enabled to wake up the - system from sleep states, this attribute is empty. + system from sleep states, this attribute is not present. What: /sys/devices/.../power/wakeup_hit_count Date: September 2010 @@ -105,7 +104,8 @@ Description: number of times the processing of a wakeup event associated with the device might prevent the system from entering a sleep state. This attribute is read-only. If the device is not enabled to - wake up the system from sleep states, this attribute is empty. + wake up the system from sleep states, this attribute is not + present. What: /sys/devices/.../power/wakeup_active Date: September 2010 @@ -115,7 +115,7 @@ Description: or 0, depending on whether or not a wakeup event associated with the device is being processed (1). This attribute is read-only. If the device is not enabled to wake up the system from sleep - states, this attribute is empty. + states, this attribute is not present. What: /sys/devices/.../power/wakeup_total_time_ms Date: September 2010 @@ -125,7 +125,7 @@ Description: the total time of processing wakeup events associated with the device, in milliseconds. This attribute is read-only. If the device is not enabled to wake up the system from sleep states, - this attribute is empty. + this attribute is not present. What: /sys/devices/.../power/wakeup_max_time_ms Date: September 2010 @@ -135,7 +135,7 @@ Description: the maximum time of processing a single wakeup event associated with the device, in milliseconds. This attribute is read-only. If the device is not enabled to wake up the system from sleep - states, this attribute is empty. + states, this attribute is not present. What: /sys/devices/.../power/wakeup_last_time_ms Date: September 2010 @@ -146,7 +146,7 @@ Description: signaling the last wakeup event associated with the device, in milliseconds. This attribute is read-only. If the device is not enabled to wake up the system from sleep states, this - attribute is empty. + attribute is not present. What: /sys/devices/.../power/autosuspend_delay_ms Date: September 2010 diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt index 57080cd74575..dd9b49251db3 100644 --- a/Documentation/power/devices.txt +++ b/Documentation/power/devices.txt @@ -159,18 +159,18 @@ matter, and the kernel is responsible for keeping track of it. By contrast, whether or not a wakeup-capable device should issue wakeup events is a policy decision, and it is managed by user space through a sysfs attribute: the power/wakeup file. User space can write the strings "enabled" or "disabled" to -set or clear the should_wakeup flag, respectively. Reads from the file will -return the corresponding string if can_wakeup is true, but if can_wakeup is -false then reads will return an empty string, to indicate that the device -doesn't support wakeup events. (But even though the file appears empty, writes -will still affect the should_wakeup flag.) +set or clear the "should_wakeup" flag, respectively. This file is only present +for wakeup-capable devices (i.e. devices whose "can_wakeup" flags are set) +and is created (or removed) by device_set_wakeup_capable(). Reads from the +file will return the corresponding string. The device_may_wakeup() routine returns true only if both flags are set. -Drivers should check this routine when putting devices in a low-power state -during a system sleep transition, to see whether or not to enable the devices' -wakeup mechanisms. However for runtime power management, wakeup events should -be enabled whenever the device and driver both support them, regardless of the -should_wakeup flag. +This information is used by subsystems, like the PCI bus type code, to see +whether or not to enable the devices' wakeup mechanisms. If device wakeup +mechanisms are enabled or disabled directly by drivers, they also should use +device_may_wakeup() to decide what to do during a system sleep transition. +However for runtime power management, wakeup events should be enabled whenever +the device and driver both support them, regardless of the should_wakeup flag. /sys/devices/.../power/control files diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index 698dde742587..f2a25f18fde7 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h @@ -58,19 +58,18 @@ static inline void device_pm_move_last(struct device *dev) {} * sysfs.c */ -extern int dpm_sysfs_add(struct device *); -extern void dpm_sysfs_remove(struct device *); -extern void rpm_sysfs_remove(struct device *); +extern int dpm_sysfs_add(struct device *dev); +extern void dpm_sysfs_remove(struct device *dev); +extern void rpm_sysfs_remove(struct device *dev); +extern int wakeup_sysfs_add(struct device *dev); +extern void wakeup_sysfs_remove(struct device *dev); #else /* CONFIG_PM */ -static inline int dpm_sysfs_add(struct device *dev) -{ - return 0; -} - -static inline void dpm_sysfs_remove(struct device *dev) -{ -} +static inline int dpm_sysfs_add(struct device *dev) { return 0; } +static inline void dpm_sysfs_remove(struct device *dev) {} +static inline void rpm_sysfs_remove(struct device *dev) {} +static inline int wakeup_sysfs_add(struct device *dev) { return 0; } +static inline void wakeup_sysfs_remove(struct device *dev) {} #endif diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index 0b1e46bf3e56..fff49bee781d 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c @@ -431,26 +431,18 @@ static ssize_t async_store(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(async, 0644, async_show, async_store); #endif /* CONFIG_PM_ADVANCED_DEBUG */ -static struct attribute * power_attrs[] = { - &dev_attr_wakeup.attr, -#ifdef CONFIG_PM_SLEEP - &dev_attr_wakeup_count.attr, - &dev_attr_wakeup_active_count.attr, - &dev_attr_wakeup_hit_count.attr, - &dev_attr_wakeup_active.attr, - &dev_attr_wakeup_total_time_ms.attr, - &dev_attr_wakeup_max_time_ms.attr, - &dev_attr_wakeup_last_time_ms.attr, -#endif +static struct attribute *power_attrs[] = { #ifdef CONFIG_PM_ADVANCED_DEBUG +#ifdef CONFIG_PM_SLEEP &dev_attr_async.attr, +#endif #ifdef CONFIG_PM_RUNTIME &dev_attr_runtime_status.attr, &dev_attr_runtime_usage.attr, &dev_attr_runtime_active_kids.attr, &dev_attr_runtime_enabled.attr, #endif -#endif +#endif /* CONFIG_PM_ADVANCED_DEBUG */ NULL, }; static struct attribute_group pm_attr_group = { @@ -458,9 +450,26 @@ static struct attribute_group pm_attr_group = { .attrs = power_attrs, }; -#ifdef CONFIG_PM_RUNTIME +static struct attribute *wakeup_attrs[] = { +#ifdef CONFIG_PM_SLEEP + &dev_attr_wakeup.attr, + &dev_attr_wakeup_count.attr, + &dev_attr_wakeup_active_count.attr, + &dev_attr_wakeup_hit_count.attr, + &dev_attr_wakeup_active.attr, + &dev_attr_wakeup_total_time_ms.attr, + &dev_attr_wakeup_max_time_ms.attr, + &dev_attr_wakeup_last_time_ms.attr, +#endif + NULL, +}; +static struct attribute_group pm_wakeup_attr_group = { + .name = power_group_name, + .attrs = wakeup_attrs, +}; static struct attribute *runtime_attrs[] = { +#ifdef CONFIG_PM_RUNTIME #ifndef CONFIG_PM_ADVANCED_DEBUG &dev_attr_runtime_status.attr, #endif @@ -468,6 +477,7 @@ static struct attribute *runtime_attrs[] = { &dev_attr_runtime_suspended_time.attr, &dev_attr_runtime_active_time.attr, &dev_attr_autosuspend_delay_ms.attr, +#endif /* CONFIG_PM_RUNTIME */ NULL, }; static struct attribute_group pm_runtime_attr_group = { @@ -480,35 +490,49 @@ int dpm_sysfs_add(struct device *dev) int rc; rc = sysfs_create_group(&dev->kobj, &pm_attr_group); - if (rc == 0 && !dev->power.no_callbacks) { + if (rc) + return rc; + + if (pm_runtime_callbacks_present(dev)) { rc = sysfs_merge_group(&dev->kobj, &pm_runtime_attr_group); if (rc) - sysfs_remove_group(&dev->kobj, &pm_attr_group); + goto err_out; + } + + if (device_can_wakeup(dev)) { + rc = sysfs_merge_group(&dev->kobj, &pm_wakeup_attr_group); + if (rc) { + if (pm_runtime_callbacks_present(dev)) + sysfs_unmerge_group(&dev->kobj, + &pm_runtime_attr_group); + goto err_out; + } } + return 0; + + err_out: + sysfs_remove_group(&dev->kobj, &pm_attr_group); return rc; } -void rpm_sysfs_remove(struct device *dev) +int wakeup_sysfs_add(struct device *dev) { - sysfs_unmerge_group(&dev->kobj, &pm_runtime_attr_group); + return sysfs_merge_group(&dev->kobj, &pm_wakeup_attr_group); } -void dpm_sysfs_remove(struct device *dev) +void wakeup_sysfs_remove(struct device *dev) { - rpm_sysfs_remove(dev); - sysfs_remove_group(&dev->kobj, &pm_attr_group); + sysfs_unmerge_group(&dev->kobj, &pm_wakeup_attr_group); } -#else /* CONFIG_PM_RUNTIME */ - -int dpm_sysfs_add(struct device * dev) +void rpm_sysfs_remove(struct device *dev) { - return sysfs_create_group(&dev->kobj, &pm_attr_group); + sysfs_unmerge_group(&dev->kobj, &pm_runtime_attr_group); } -void dpm_sysfs_remove(struct device * dev) +void dpm_sysfs_remove(struct device *dev) { + rpm_sysfs_remove(dev); + sysfs_unmerge_group(&dev->kobj, &pm_wakeup_attr_group); sysfs_remove_group(&dev->kobj, &pm_attr_group); } - -#endif diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 82836383997f..4573c83df6dd 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -241,6 +241,35 @@ int device_wakeup_disable(struct device *dev) } EXPORT_SYMBOL_GPL(device_wakeup_disable); +/** + * device_set_wakeup_capable - Set/reset device wakeup capability flag. + * @dev: Device to handle. + * @capable: Whether or not @dev is capable of waking up the system from sleep. + * + * If @capable is set, set the @dev's power.can_wakeup flag and add its + * wakeup-related attributes to sysfs. Otherwise, unset the @dev's + * power.can_wakeup flag and remove its wakeup-related attributes from sysfs. + * + * This function may sleep and it can't be called from any context where + * sleeping is not allowed. + */ +void device_set_wakeup_capable(struct device *dev, bool capable) +{ + if (!!dev->power.can_wakeup == !!capable) + return; + + if (device_is_registered(dev)) { + if (capable) { + if (wakeup_sysfs_add(dev)) + return; + } else { + wakeup_sysfs_remove(dev); + } + } + dev->power.can_wakeup = capable; +} +EXPORT_SYMBOL_GPL(device_set_wakeup_capable); + /** * device_init_wakeup - Device wakeup initialization. * @dev: Device to handle. diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index d34f067e2a7f..8de9aa6e7def 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -87,6 +87,11 @@ static inline bool pm_runtime_enabled(struct device *dev) return !dev->power.disable_depth; } +static inline bool pm_runtime_callbacks_present(struct device *dev) +{ + return !dev->power.no_callbacks; +} + static inline void pm_runtime_mark_last_busy(struct device *dev) { ACCESS_ONCE(dev->power.last_busy) = jiffies; @@ -133,6 +138,7 @@ static inline int pm_generic_runtime_resume(struct device *dev) { return 0; } static inline void pm_runtime_no_callbacks(struct device *dev) {} static inline void pm_runtime_irq_safe(struct device *dev) {} +static inline bool pm_runtime_callbacks_present(struct device *dev) { return false; } static inline void pm_runtime_mark_last_busy(struct device *dev) {} static inline void __pm_runtime_use_autosuspend(struct device *dev, bool use) {} diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index 03a67db03d01..a32da962d693 100644 --- a/include/linux/pm_wakeup.h +++ b/include/linux/pm_wakeup.h @@ -62,18 +62,11 @@ struct wakeup_source { * Changes to device_may_wakeup take effect on the next pm state change. */ -static inline void device_set_wakeup_capable(struct device *dev, bool capable) -{ - dev->power.can_wakeup = capable; -} - static inline bool device_can_wakeup(struct device *dev) { return dev->power.can_wakeup; } - - static inline bool device_may_wakeup(struct device *dev) { return dev->power.can_wakeup && !!dev->power.wakeup; @@ -88,6 +81,7 @@ extern struct wakeup_source *wakeup_source_register(const char *name); extern void wakeup_source_unregister(struct wakeup_source *ws); extern int device_wakeup_enable(struct device *dev); extern int device_wakeup_disable(struct device *dev); +extern void device_set_wakeup_capable(struct device *dev, bool capable); extern int device_init_wakeup(struct device *dev, bool val); extern int device_set_wakeup_enable(struct device *dev, bool enable); extern void __pm_stay_awake(struct wakeup_source *ws); -- cgit v1.2.3 From cd51e61cf4e8b220da37dc35e9c2dc2dc258b4de Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 11 Feb 2011 00:04:52 +0100 Subject: PM / ACPI: Remove references to pm_flags from bus.c If direct references to pm_flags are removed from drivers/acpi/bus.c, CONFIG_ACPI will not need to depend on CONFIG_PM any more. Make that happen. Signed-off-by: Rafael J. Wysocki Acked-by: Len Brown --- drivers/acpi/Kconfig | 1 - drivers/acpi/bus.c | 7 ++++--- include/linux/suspend.h | 6 ++++++ kernel/power/main.c | 12 +++++++++++- 4 files changed, 21 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 2aa042a5da6d..3a17ca5fff6f 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -7,7 +7,6 @@ menuconfig ACPI depends on !IA64_HP_SIM depends on IA64 || X86 depends on PCI - depends on PM select PNP default y help diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 7ced61f39492..973b0709972c 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "internal.h" @@ -1025,13 +1026,13 @@ static int __init acpi_init(void) if (!result) { pci_mmcfg_late_init(); - if (!(pm_flags & PM_APM)) - pm_flags |= PM_ACPI; - else { + if (pm_apm_enabled()) { printk(KERN_INFO PREFIX "APM is already active, exiting\n"); disable_acpi(); result = -ENODEV; + } else { + pm_set_acpi_flag(); } } else disable_acpi(); diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 5a89e3612875..5e364db8a56a 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -272,6 +272,9 @@ extern int unregister_pm_notifier(struct notifier_block *nb); register_pm_notifier(&fn##_nb); \ } +extern bool pm_apm_enabled(void); +extern void pm_set_acpi_flag(void); + /* drivers/base/power/wakeup.c */ extern bool events_check_enabled; @@ -292,6 +295,9 @@ static inline int unregister_pm_notifier(struct notifier_block *nb) #define pm_notifier(fn, pri) do { (void)(fn); } while (0) +static inline bool pm_apm_enabled(void) { return false; } +static inline void pm_set_acpi_flag(void) {} + static inline bool pm_wakeup_pending(void) { return false; } #endif /* !CONFIG_PM_SLEEP */ diff --git a/kernel/power/main.c b/kernel/power/main.c index 701853042c28..b5405af48ddb 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -17,10 +17,20 @@ DEFINE_MUTEX(pm_mutex); +#ifdef CONFIG_PM_SLEEP + unsigned int pm_flags; EXPORT_SYMBOL(pm_flags); -#ifdef CONFIG_PM_SLEEP +bool pm_apm_enabled(void) +{ + return !!(pm_flags & PM_APM); +} + +void pm_set_acpi_flag(void) +{ + pm_flags |= PM_ACPI; +} /* Routines for PM-transition notifications */ -- cgit v1.2.3 From aa33860158114d0df3c7997bc1dd41c0168e1c2a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 11 Feb 2011 00:06:54 +0100 Subject: PM: Remove CONFIG_PM_OPS After redefining CONFIG_PM to depend on (CONFIG_PM_SLEEP || CONFIG_PM_RUNTIME) the CONFIG_PM_OPS option is redundant and can be replaced with CONFIG_PM. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sleep.c | 4 ++-- drivers/base/power/Makefile | 3 +-- drivers/net/e1000e/netdev.c | 8 ++++---- drivers/net/pch_gbe/pch_gbe_main.c | 2 +- drivers/pci/pci-driver.c | 4 ++-- drivers/scsi/Makefile | 2 +- drivers/scsi/scsi_priv.h | 2 +- drivers/scsi/scsi_sysfs.c | 2 +- drivers/usb/core/hcd-pci.c | 4 ++-- include/acpi/acpi_bus.h | 2 +- include/linux/pm.h | 2 +- kernel/power/Kconfig | 5 ----- 12 files changed, 17 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index d6a8cd14de2e..8ea092fad3f6 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -585,7 +585,7 @@ int acpi_suspend(u32 acpi_state) return -EINVAL; } -#ifdef CONFIG_PM_OPS +#ifdef CONFIG_PM /** * acpi_pm_device_sleep_state - return preferred power state of ACPI device * in the system sleep state given by %acpi_target_sleep_state @@ -671,7 +671,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) *d_min_p = d_min; return d_max; } -#endif /* CONFIG_PM_OPS */ +#endif /* CONFIG_PM */ #ifdef CONFIG_PM_SLEEP /** diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile index abe46edfe5b4..118c1b92a511 100644 --- a/drivers/base/power/Makefile +++ b/drivers/base/power/Makefile @@ -1,7 +1,6 @@ -obj-$(CONFIG_PM) += sysfs.o +obj-$(CONFIG_PM) += sysfs.o generic_ops.o obj-$(CONFIG_PM_SLEEP) += main.o wakeup.o obj-$(CONFIG_PM_RUNTIME) += runtime.o -obj-$(CONFIG_PM_OPS) += generic_ops.o obj-$(CONFIG_PM_TRACE_RTC) += trace.o obj-$(CONFIG_PM_OPP) += opp.o diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 2e5022849f18..6d513a383340 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -5338,7 +5338,7 @@ void e1000e_disable_aspm(struct pci_dev *pdev, u16 state) __e1000e_disable_aspm(pdev, state); } -#ifdef CONFIG_PM_OPS +#ifdef CONFIG_PM static bool e1000e_pm_ready(struct e1000_adapter *adapter) { return !!adapter->tx_ring->buffer_info; @@ -5489,7 +5489,7 @@ static int e1000_runtime_resume(struct device *dev) return __e1000_resume(pdev); } #endif /* CONFIG_PM_RUNTIME */ -#endif /* CONFIG_PM_OPS */ +#endif /* CONFIG_PM */ static void e1000_shutdown(struct pci_dev *pdev) { @@ -6196,7 +6196,7 @@ static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = { }; MODULE_DEVICE_TABLE(pci, e1000_pci_tbl); -#ifdef CONFIG_PM_OPS +#ifdef CONFIG_PM static const struct dev_pm_ops e1000_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(e1000_suspend, e1000_resume) SET_RUNTIME_PM_OPS(e1000_runtime_suspend, @@ -6210,7 +6210,7 @@ static struct pci_driver e1000_driver = { .id_table = e1000_pci_tbl, .probe = e1000_probe, .remove = __devexit_p(e1000_remove), -#ifdef CONFIG_PM_OPS +#ifdef CONFIG_PM .driver.pm = &e1000_pm_ops, #endif .shutdown = e1000_shutdown, diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index b99e90aca37d..8c66e22c3a0a 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c @@ -2446,7 +2446,7 @@ static struct pci_driver pch_gbe_pcidev = { .id_table = pch_gbe_pcidev_id, .probe = pch_gbe_probe, .remove = pch_gbe_remove, -#ifdef CONFIG_PM_OPS +#ifdef CONFIG_PM .driver.pm = &pch_gbe_pm_ops, #endif .shutdown = pch_gbe_shutdown, diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 88246dd46452..d86ea8b01137 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -431,7 +431,7 @@ static void pci_device_shutdown(struct device *dev) pci_msix_shutdown(pci_dev); } -#ifdef CONFIG_PM_OPS +#ifdef CONFIG_PM /* Auxiliary functions used for system resume and run-time resume. */ @@ -1059,7 +1059,7 @@ static int pci_pm_runtime_idle(struct device *dev) #endif /* !CONFIG_PM_RUNTIME */ -#ifdef CONFIG_PM_OPS +#ifdef CONFIG_PM const struct dev_pm_ops pci_dev_pm_ops = { .prepare = pci_pm_prepare, diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 2e9a87e8e7d8..ef6de669424b 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -165,7 +165,7 @@ scsi_mod-$(CONFIG_SCSI_NETLINK) += scsi_netlink.o scsi_mod-$(CONFIG_SYSCTL) += scsi_sysctl.o scsi_mod-$(CONFIG_SCSI_PROC_FS) += scsi_proc.o scsi_mod-y += scsi_trace.o -scsi_mod-$(CONFIG_PM_OPS) += scsi_pm.o +scsi_mod-$(CONFIG_PM) += scsi_pm.o scsi_tgt-y += scsi_tgt_lib.o scsi_tgt_if.o diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index b4056d14f812..342ee1a9c41d 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -146,7 +146,7 @@ static inline void scsi_netlink_exit(void) {} #endif /* scsi_pm.c */ -#ifdef CONFIG_PM_OPS +#ifdef CONFIG_PM extern const struct dev_pm_ops scsi_bus_pm_ops; #endif #ifdef CONFIG_PM_RUNTIME diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 490ce213204e..e44ff64233fd 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -383,7 +383,7 @@ struct bus_type scsi_bus_type = { .name = "scsi", .match = scsi_bus_match, .uevent = scsi_bus_uevent, -#ifdef CONFIG_PM_OPS +#ifdef CONFIG_PM .pm = &scsi_bus_pm_ops, #endif }; diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index f71e8e307e0f..64a035ba2eab 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -335,7 +335,7 @@ void usb_hcd_pci_shutdown(struct pci_dev *dev) } EXPORT_SYMBOL_GPL(usb_hcd_pci_shutdown); -#ifdef CONFIG_PM_OPS +#ifdef CONFIG_PM #ifdef CONFIG_PPC_PMAC static void powermac_set_asic(struct pci_dev *pci_dev, int enable) @@ -580,4 +580,4 @@ const struct dev_pm_ops usb_hcd_pci_pm_ops = { }; EXPORT_SYMBOL_GPL(usb_hcd_pci_pm_ops); -#endif /* CONFIG_PM_OPS */ +#endif /* CONFIG_PM */ diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 78ca429929f7..ff103ba96b78 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -381,7 +381,7 @@ struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle); int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state); int acpi_disable_wakeup_device_power(struct acpi_device *dev); -#ifdef CONFIG_PM_OPS +#ifdef CONFIG_PM int acpi_pm_device_sleep_state(struct device *, int *); #else static inline int acpi_pm_device_sleep_state(struct device *d, int *p) diff --git a/include/linux/pm.h b/include/linux/pm.h index 21415cc91cbb..9279175a4557 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -267,7 +267,7 @@ const struct dev_pm_ops name = { \ * callbacks provided by device drivers supporting both the system sleep PM and * runtime PM, make the pm member point to generic_subsys_pm_ops. */ -#ifdef CONFIG_PM_OPS +#ifdef CONFIG_PM extern struct dev_pm_ops generic_subsys_pm_ops; #define GENERIC_SUBSYS_PM_OPS (&generic_subsys_pm_ops) #else diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 1e4d9238c5da..0710beead05b 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -220,11 +220,6 @@ config APM_EMULATION anything, try disabling/enabling this option (or disabling/enabling APM in your BIOS). -config PM_OPS - bool - depends on PM_SLEEP || PM_RUNTIME - default y - config ARCH_HAS_OPP bool -- cgit v1.2.3 From e8665002477f0278f84f898145b1f141ba26ee26 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 12 Feb 2011 01:42:41 +0100 Subject: PM: Allow pm_runtime_suspend() to succeed during system suspend The dpm_prepare() function increments the runtime PM reference counters of all devices to prevent pm_runtime_suspend() from executing subsystem-level callbacks. However, this was supposed to guard against a specific race condition that cannot happen, because the power management workqueue is freezable, so pm_runtime_suspend() can only be called synchronously during system suspend and we can rely on subsystems and device drivers to avoid doing that unnecessarily. Make dpm_prepare() drop the runtime PM reference to each device after making sure that runtime resume is not pending for it. Signed-off-by: Rafael J. Wysocki Acked-by: Kevin Hilman --- drivers/base/power/main.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 83404973f97a..f7a755923751 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -669,7 +669,6 @@ static void dpm_complete(pm_message_t state) mutex_unlock(&dpm_list_mtx); device_complete(dev, state); - pm_runtime_put_sync(dev); mutex_lock(&dpm_list_mtx); put_device(dev); @@ -1005,12 +1004,9 @@ static int dpm_prepare(pm_message_t state) if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) pm_wakeup_event(dev, 0); - if (pm_wakeup_pending()) { - pm_runtime_put_sync(dev); - error = -EBUSY; - } else { - error = device_prepare(dev, state); - } + pm_runtime_put_sync(dev); + error = pm_wakeup_pending() ? + -EBUSY : device_prepare(dev, state); mutex_lock(&dpm_list_mtx); if (error) { -- cgit v1.2.3 From 6831c6edc7b272a08dd2a6c71bb183a48fe98ae6 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 15 Feb 2011 21:22:24 +0100 Subject: PM: Drop pm_flags that is not necessary The variable pm_flags is used to prevent APM from being enabled along with ACPI, which would lead to problems. However, acpi_init() is always called before apm_init() and after acpi_init() has returned, it is known whether or not ACPI will be used. Namely, if acpi_disabled is not set after acpi_init() has returned, this means that ACPI is enabled. Thus, it is sufficient to check acpi_disabled in apm_init() to prevent APM from being enabled in parallel with ACPI. Signed-off-by: Rafael J. Wysocki Acked-by: Len Brown --- arch/x86/kernel/apm_32.c | 5 ++--- drivers/acpi/bus.c | 22 +++++----------------- include/linux/pm.h | 9 --------- include/linux/suspend.h | 6 ------ kernel/power/main.c | 13 ------------- 5 files changed, 7 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 0e4f24c2a746..15f47f741983 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c @@ -227,6 +227,7 @@ #include #include #include +#include #include #include @@ -2331,12 +2332,11 @@ static int __init apm_init(void) apm_info.disabled = 1; return -ENODEV; } - if (pm_flags & PM_ACPI) { + if (!acpi_disabled) { printk(KERN_NOTICE "apm: overridden by ACPI.\n"); apm_info.disabled = 1; return -ENODEV; } - pm_flags |= PM_APM; /* * Set up the long jump entry point to the APM BIOS, which is called @@ -2428,7 +2428,6 @@ static void __exit apm_exit(void) kthread_stop(kapmd_task); kapmd_task = NULL; } - pm_flags &= ~PM_APM; } module_init(apm_init); diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 973b0709972c..9749980ca6ca 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1007,8 +1007,7 @@ struct kobject *acpi_kobj; static int __init acpi_init(void) { - int result = 0; - + int result; if (acpi_disabled) { printk(KERN_INFO PREFIX "Interpreter disabled.\n"); @@ -1023,29 +1022,18 @@ static int __init acpi_init(void) init_acpi_device_notify(); result = acpi_bus_init(); - - if (!result) { - pci_mmcfg_late_init(); - if (pm_apm_enabled()) { - printk(KERN_INFO PREFIX - "APM is already active, exiting\n"); - disable_acpi(); - result = -ENODEV; - } else { - pm_set_acpi_flag(); - } - } else + if (result) { disable_acpi(); - - if (acpi_disabled) return result; + } + pci_mmcfg_late_init(); acpi_scan_init(); acpi_ec_init(); acpi_debugfs_init(); acpi_sleep_proc_init(); acpi_wakeup_device_init(); - return result; + return 0; } subsys_initcall(acpi_init); diff --git a/include/linux/pm.h b/include/linux/pm.h index 9279175a4557..1f79c98f1e56 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -565,15 +565,6 @@ enum dpm_order { DPM_ORDER_DEV_LAST, }; -/* - * Global Power Management flags - * Used to keep APM and ACPI from both being active - */ -extern unsigned int pm_flags; - -#define PM_APM 1 -#define PM_ACPI 2 - extern int pm_generic_suspend(struct device *dev); extern int pm_generic_resume(struct device *dev); extern int pm_generic_freeze(struct device *dev); diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 5e364db8a56a..5a89e3612875 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -272,9 +272,6 @@ extern int unregister_pm_notifier(struct notifier_block *nb); register_pm_notifier(&fn##_nb); \ } -extern bool pm_apm_enabled(void); -extern void pm_set_acpi_flag(void); - /* drivers/base/power/wakeup.c */ extern bool events_check_enabled; @@ -295,9 +292,6 @@ static inline int unregister_pm_notifier(struct notifier_block *nb) #define pm_notifier(fn, pri) do { (void)(fn); } while (0) -static inline bool pm_apm_enabled(void) { return false; } -static inline void pm_set_acpi_flag(void) {} - static inline bool pm_wakeup_pending(void) { return false; } #endif /* !CONFIG_PM_SLEEP */ diff --git a/kernel/power/main.c b/kernel/power/main.c index b5405af48ddb..8eaba5f27b10 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -19,19 +19,6 @@ DEFINE_MUTEX(pm_mutex); #ifdef CONFIG_PM_SLEEP -unsigned int pm_flags; -EXPORT_SYMBOL(pm_flags); - -bool pm_apm_enabled(void) -{ - return !!(pm_flags & PM_APM); -} - -void pm_set_acpi_flag(void) -{ - pm_flags |= PM_ACPI; -} - /* Routines for PM-transition notifications */ static BLOCKING_NOTIFIER_HEAD(pm_chain_head); -- cgit v1.2.3 From 7538e3db6e015e890825fbd9f8659952896ddd5b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 16 Feb 2011 21:53:17 +0100 Subject: PM: Add support for device power domains The platform bus type is often used to handle Systems-on-a-Chip (SoC) where all devices are represented by objects of type struct platform_device. In those cases the same "platform" device driver may be used with multiple different system configurations, but the actions needed to put the devices it handles into a low-power state and back into the full-power state may depend on the design of the given SoC. The driver, however, cannot possibly include all the information necessary for the power management of its device on all the systems it is used with. Moreover, the device hierarchy in its current form also is not suitable for representing this kind of information. The patch below attempts to address this problem by introducing objects of type struct dev_power_domain that can be used for representing power domains within a SoC. Every struct dev_power_domain object provides a sets of device power management callbacks that can be used to perform what's needed for device power management in addition to the operations carried out by the device's driver and subsystem. Namely, if a struct dev_power_domain object is pointed to by the pwr_domain field in a struct device, the callbacks provided by its ops member will be executed in addition to the corresponding callbacks provided by the device's subsystem and driver during all power transitions. Signed-off-by: Rafael J. Wysocki Tested-and-acked-by: Kevin Hilman --- Documentation/power/devices.txt | 45 ++++++++++++++++++++++++++++++++++++++++- drivers/base/power/main.c | 37 +++++++++++++++++++++++++++++++++ drivers/base/power/runtime.c | 19 +++++++++++++++-- include/linux/device.h | 1 + include/linux/pm.h | 8 ++++++++ 5 files changed, 107 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt index dd9b49251db3..df1a5cb10c42 100644 --- a/Documentation/power/devices.txt +++ b/Documentation/power/devices.txt @@ -1,6 +1,6 @@ Device Power Management -Copyright (c) 2010 Rafael J. Wysocki , Novell Inc. +Copyright (c) 2010-2011 Rafael J. Wysocki , Novell Inc. Copyright (c) 2010 Alan Stern @@ -507,6 +507,49 @@ routines. Nevertheless, different callback pointers are used in case there is a situation where it actually matters. +Device Power Domains +-------------------- +Sometimes devices share reference clocks or other power resources. In those +cases it generally is not possible to put devices into low-power states +individually. Instead, a set of devices sharing a power resource can be put +into a low-power state together at the same time by turning off the shared +power resource. Of course, they also need to be put into the full-power state +together, by turning the shared power resource on. A set of devices with this +property is often referred to as a power domain. + +Support for power domains is provided through the pwr_domain field of struct +device. This field is a pointer to an object of type struct dev_power_domain, +defined in include/linux/pm.h, providing a set of power management callbacks +analogous to the subsystem-level and device driver callbacks that are executed +for the given device during all power transitions, in addition to the respective +subsystem-level callbacks. Specifically, the power domain "suspend" callbacks +(i.e. ->runtime_suspend(), ->suspend(), ->freeze(), ->poweroff(), etc.) are +executed after the analogous subsystem-level callbacks, while the power domain +"resume" callbacks (i.e. ->runtime_resume(), ->resume(), ->thaw(), ->restore, +etc.) are executed before the analogous subsystem-level callbacks. Error codes +returned by the "suspend" and "resume" power domain callbacks are ignored. + +Power domain ->runtime_idle() callback is executed before the subsystem-level +->runtime_idle() callback and the result returned by it is not ignored. Namely, +if it returns error code, the subsystem-level ->runtime_idle() callback will not +be called and the helper function rpm_idle() executing it will return error +code. This mechanism is intended to help platforms where saving device state +is a time consuming operation and should only be carried out if all devices +in the power domain are idle, before turning off the shared power resource(s). +Namely, the power domain ->runtime_idle() callback may return error code until +the pm_runtime_idle() helper (or its asychronous version) has been called for +all devices in the power domain (it is recommended that the returned error code +be -EBUSY in those cases), preventing the subsystem-level ->runtime_idle() +callback from being run prematurely. + +The support for device power domains is only relevant to platforms needing to +use the same subsystem-level (e.g. platform bus type) and device driver power +management callbacks in many different power domain configurations and wanting +to avoid incorporating the support for power domains into the subsystem-level +callbacks. The other platforms need not implement it or take it into account +in any way. + + System Devices -------------- System devices (sysdevs) follow a slightly different API, which can be found in diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index f7a755923751..05b989139b54 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -423,6 +423,11 @@ static int device_resume_noirq(struct device *dev, pm_message_t state) TRACE_DEVICE(dev); TRACE_RESUME(0); + if (dev->pwr_domain) { + pm_dev_dbg(dev, state, "EARLY power domain "); + pm_noirq_op(dev, &dev->pwr_domain->ops, state); + } + if (dev->bus && dev->bus->pm) { pm_dev_dbg(dev, state, "EARLY "); error = pm_noirq_op(dev, dev->bus->pm, state); @@ -518,6 +523,11 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) dev->power.in_suspend = false; + if (dev->pwr_domain) { + pm_dev_dbg(dev, state, "power domain "); + pm_op(dev, &dev->pwr_domain->ops, state); + } + if (dev->bus) { if (dev->bus->pm) { pm_dev_dbg(dev, state, ""); @@ -629,6 +639,11 @@ static void device_complete(struct device *dev, pm_message_t state) { device_lock(dev); + if (dev->pwr_domain && dev->pwr_domain->ops.complete) { + pm_dev_dbg(dev, state, "completing power domain "); + dev->pwr_domain->ops.complete(dev); + } + if (dev->class && dev->class->pm && dev->class->pm->complete) { pm_dev_dbg(dev, state, "completing class "); dev->class->pm->complete(dev); @@ -745,6 +760,13 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state) if (dev->bus && dev->bus->pm) { pm_dev_dbg(dev, state, "LATE "); error = pm_noirq_op(dev, dev->bus->pm, state); + if (error) + goto End; + } + + if (dev->pwr_domain) { + pm_dev_dbg(dev, state, "LATE power domain "); + pm_noirq_op(dev, &dev->pwr_domain->ops, state); } End: @@ -864,6 +886,13 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) pm_dev_dbg(dev, state, "legacy "); error = legacy_suspend(dev, state, dev->bus->suspend); } + if (error) + goto End; + } + + if (dev->pwr_domain) { + pm_dev_dbg(dev, state, "power domain "); + pm_op(dev, &dev->pwr_domain->ops, state); } End: @@ -976,7 +1005,15 @@ static int device_prepare(struct device *dev, pm_message_t state) pm_dev_dbg(dev, state, "preparing class "); error = dev->class->pm->prepare(dev); suspend_report_result(dev->class->pm->prepare, error); + if (error) + goto End; + } + + if (dev->pwr_domain && dev->pwr_domain->ops.prepare) { + pm_dev_dbg(dev, state, "preparing power domain "); + dev->pwr_domain->ops.prepare(dev); } + End: device_unlock(dev); diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 42615b419dfb..25edc9a3a489 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -168,6 +168,7 @@ static int rpm_check_suspend_allowed(struct device *dev) static int rpm_idle(struct device *dev, int rpmflags) { int (*callback)(struct device *); + int (*domain_callback)(struct device *); int retval; retval = rpm_check_suspend_allowed(dev); @@ -222,10 +223,19 @@ static int rpm_idle(struct device *dev, int rpmflags) else callback = NULL; - if (callback) { + if (dev->pwr_domain) + domain_callback = dev->pwr_domain->ops.runtime_idle; + else + domain_callback = NULL; + + if (callback || domain_callback) { spin_unlock_irq(&dev->power.lock); - callback(dev); + if (domain_callback) + retval = domain_callback(dev); + + if (!retval && callback) + callback(dev); spin_lock_irq(&dev->power.lock); } @@ -390,6 +400,8 @@ static int rpm_suspend(struct device *dev, int rpmflags) else pm_runtime_cancel_pending(dev); } else { + if (dev->pwr_domain) + rpm_callback(dev->pwr_domain->ops.runtime_suspend, dev); no_callback: __update_runtime_status(dev, RPM_SUSPENDED); pm_runtime_deactivate_timer(dev); @@ -569,6 +581,9 @@ static int rpm_resume(struct device *dev, int rpmflags) __update_runtime_status(dev, RPM_RESUMING); + if (dev->pwr_domain) + rpm_callback(dev->pwr_domain->ops.runtime_resume, dev); + if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_resume) callback = dev->bus->pm->runtime_resume; else if (dev->type && dev->type->pm && dev->type->pm->runtime_resume) diff --git a/include/linux/device.h b/include/linux/device.h index 1bf5cf0b4513..22e9a8a7e1bc 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -422,6 +422,7 @@ struct device { void *platform_data; /* Platform specific data, device core doesn't touch it */ struct dev_pm_info power; + struct dev_power_domain *pwr_domain; #ifdef CONFIG_NUMA int numa_node; /* NUMA node this device is close to */ diff --git a/include/linux/pm.h b/include/linux/pm.h index 1f79c98f1e56..6618216bb973 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -465,6 +465,14 @@ struct dev_pm_info { extern void update_pm_runtime_accounting(struct device *dev); +/* + * Power domains provide callbacks that are executed during system suspend, + * hibernation, system resume and during runtime PM transitions along with + * subsystem-level and driver-level callbacks. + */ +struct dev_power_domain { + struct dev_pm_ops ops; +}; /* * The PM_EVENT_ messages are also used by drivers implementing the legacy -- cgit v1.2.3 From 9659cc0678b954f187290c6e8b247a673c5d37e1 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 18 Feb 2011 23:20:21 +0100 Subject: PM: Make system-wide PM and runtime PM treat subsystems consistently The code handling system-wide power transitions (eg. suspend-to-RAM) can in theory execute callbacks provided by the device's bus type, device type and class in each phase of the power transition. In turn, the runtime PM core code only calls one of those callbacks at a time, preferring bus type callbacks to device type or class callbacks and device type callbacks to class callbacks. It seems reasonable to make them both behave in the same way in that respect. Moreover, even though a device may belong to two subsystems (eg. bus type and device class) simultaneously, in practice power management callbacks for system-wide power transitions are always provided by only one of them (ie. if the bus type callbacks are defined, the device class ones are not and vice versa). Thus it is possible to modify the code handling system-wide power transitions so that it follows the core runtime PM code (ie. treats the subsystem callbacks as mutually exclusive). On the other hand, the core runtime PM code will choose to execute, for example, a runtime suspend callback provided by the device type even if the bus type's struct dev_pm_ops object exists, but the runtime_suspend pointer in it happens to be NULL. This is confusing, because it may lead to the execution of callbacks from different subsystems during different operations (eg. the bus type suspend callback may be executed during runtime suspend of the device, while the device type callback will be executed during system suspend). Make all of the power management code treat subsystem callbacks in a consistent way, such that: (1) If the device's type is defined (eg. dev->type is not NULL) and its pm pointer is not NULL, the callbacks from dev->type->pm will be used. (2) If dev->type is NULL or dev->type->pm is NULL, but the device's class is defined (eg. dev->class is not NULL) and its pm pointer is not NULL, the callbacks from dev->class->pm will be used. (3) If dev->type is NULL or dev->type->pm is NULL and dev->class is NULL or dev->class->pm is NULL, the callbacks from dev->bus->pm will be used provided that both dev->bus and dev->bus->pm are not NULL. Signed-off-by: Rafael J. Wysocki Acked-by: Kevin Hilman Reasoning-sounds-sane-to: Grant Likely Acked-by: Greg Kroah-Hartman --- Documentation/power/devices.txt | 29 +++---- Documentation/power/runtime_pm.txt | 13 ++-- drivers/base/power/main.c | 150 ++++++++++++++++--------------------- drivers/base/power/runtime.c | 18 ++--- 4 files changed, 92 insertions(+), 118 deletions(-) (limited to 'drivers') diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt index df1a5cb10c42..f023ba6bba62 100644 --- a/Documentation/power/devices.txt +++ b/Documentation/power/devices.txt @@ -249,23 +249,18 @@ various phases always run after tasks have been frozen and before they are unfrozen. Furthermore, the *_noirq phases run at a time when IRQ handlers have been disabled (except for those marked with the IRQ_WAKEUP flag). -Most phases use bus, type, and class callbacks (that is, methods defined in -dev->bus->pm, dev->type->pm, and dev->class->pm). The prepare and complete -phases are exceptions; they use only bus callbacks. When multiple callbacks -are used in a phase, they are invoked in the order: during -power-down transitions and in the opposite order during power-up transitions. -For example, during the suspend phase the PM core invokes - - dev->class->pm.suspend(dev); - dev->type->pm.suspend(dev); - dev->bus->pm.suspend(dev); - -before moving on to the next device, whereas during the resume phase the core -invokes - - dev->bus->pm.resume(dev); - dev->type->pm.resume(dev); - dev->class->pm.resume(dev); +All phases use bus, type, or class callbacks (that is, methods defined in +dev->bus->pm, dev->type->pm, or dev->class->pm). These callbacks are mutually +exclusive, so if the device type provides a struct dev_pm_ops object pointed to +by its pm field (i.e. both dev->type and dev->type->pm are defined), the +callbacks included in that object (i.e. dev->type->pm) will be used. Otherwise, +if the class provides a struct dev_pm_ops object pointed to by its pm field +(i.e. both dev->class and dev->class->pm are defined), the PM core will use the +callbacks from that object (i.e. dev->class->pm). Finally, if the pm fields of +both the device type and class objects are NULL (or those objects do not exist), +the callbacks provided by the bus (that is, the callbacks from dev->bus->pm) +will be used (this allows device types to override callbacks provided by bus +types or classes if necessary). These callbacks may in turn invoke device- or driver-specific methods stored in dev->driver->pm, but they don't have to. diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index ffe55ffa540a..654097b130b4 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt @@ -1,6 +1,6 @@ Run-time Power Management Framework for I/O Devices -(C) 2009 Rafael J. Wysocki , Novell Inc. +(C) 2009-2011 Rafael J. Wysocki , Novell Inc. (C) 2010 Alan Stern 1. Introduction @@ -44,11 +44,12 @@ struct dev_pm_ops { }; The ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks are -executed by the PM core for either the bus type, or device type (if the bus -type's callback is not defined), or device class (if the bus type's and device -type's callbacks are not defined) of given device. The bus type, device type -and device class callbacks are referred to as subsystem-level callbacks in what -follows. +executed by the PM core for either the device type, or the class (if the device +type's struct dev_pm_ops object does not exist), or the bus type (if the +device type's and class' struct dev_pm_ops objects do not exist) of the given +device (this allows device types to override callbacks provided by bus types or +classes if necessary). The bus type, device type and class callbacks are +referred to as subsystem-level callbacks in what follows. By default, the callbacks are always invoked in process context with interrupts enabled. However, subsystems can use the pm_runtime_irq_safe() helper function diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 05b989139b54..052dc53eef38 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -428,26 +428,17 @@ static int device_resume_noirq(struct device *dev, pm_message_t state) pm_noirq_op(dev, &dev->pwr_domain->ops, state); } - if (dev->bus && dev->bus->pm) { - pm_dev_dbg(dev, state, "EARLY "); - error = pm_noirq_op(dev, dev->bus->pm, state); - if (error) - goto End; - } - if (dev->type && dev->type->pm) { pm_dev_dbg(dev, state, "EARLY type "); error = pm_noirq_op(dev, dev->type->pm, state); - if (error) - goto End; - } - - if (dev->class && dev->class->pm) { + } else if (dev->class && dev->class->pm) { pm_dev_dbg(dev, state, "EARLY class "); error = pm_noirq_op(dev, dev->class->pm, state); + } else if (dev->bus && dev->bus->pm) { + pm_dev_dbg(dev, state, "EARLY "); + error = pm_noirq_op(dev, dev->bus->pm, state); } -End: TRACE_RESUME(error); return error; } @@ -528,36 +519,34 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) pm_op(dev, &dev->pwr_domain->ops, state); } - if (dev->bus) { - if (dev->bus->pm) { - pm_dev_dbg(dev, state, ""); - error = pm_op(dev, dev->bus->pm, state); - } else if (dev->bus->resume) { - pm_dev_dbg(dev, state, "legacy "); - error = legacy_resume(dev, dev->bus->resume); - } - if (error) - goto End; - } - - if (dev->type) { - if (dev->type->pm) { - pm_dev_dbg(dev, state, "type "); - error = pm_op(dev, dev->type->pm, state); - } - if (error) - goto End; + if (dev->type && dev->type->pm) { + pm_dev_dbg(dev, state, "type "); + error = pm_op(dev, dev->type->pm, state); + goto End; } if (dev->class) { if (dev->class->pm) { pm_dev_dbg(dev, state, "class "); error = pm_op(dev, dev->class->pm, state); + goto End; } else if (dev->class->resume) { pm_dev_dbg(dev, state, "legacy class "); error = legacy_resume(dev, dev->class->resume); + goto End; } } + + if (dev->bus) { + if (dev->bus->pm) { + pm_dev_dbg(dev, state, ""); + error = pm_op(dev, dev->bus->pm, state); + } else if (dev->bus->resume) { + pm_dev_dbg(dev, state, "legacy "); + error = legacy_resume(dev, dev->bus->resume); + } + } + End: device_unlock(dev); complete_all(&dev->power.completion); @@ -644,19 +633,18 @@ static void device_complete(struct device *dev, pm_message_t state) dev->pwr_domain->ops.complete(dev); } - if (dev->class && dev->class->pm && dev->class->pm->complete) { - pm_dev_dbg(dev, state, "completing class "); - dev->class->pm->complete(dev); - } - - if (dev->type && dev->type->pm && dev->type->pm->complete) { + if (dev->type && dev->type->pm) { pm_dev_dbg(dev, state, "completing type "); - dev->type->pm->complete(dev); - } - - if (dev->bus && dev->bus->pm && dev->bus->pm->complete) { + if (dev->type->pm->complete) + dev->type->pm->complete(dev); + } else if (dev->class && dev->class->pm) { + pm_dev_dbg(dev, state, "completing class "); + if (dev->class->pm->complete) + dev->class->pm->complete(dev); + } else if (dev->bus && dev->bus->pm) { pm_dev_dbg(dev, state, "completing "); - dev->bus->pm->complete(dev); + if (dev->bus->pm->complete) + dev->bus->pm->complete(dev); } device_unlock(dev); @@ -741,27 +729,23 @@ static pm_message_t resume_event(pm_message_t sleep_state) */ static int device_suspend_noirq(struct device *dev, pm_message_t state) { - int error = 0; - - if (dev->class && dev->class->pm) { - pm_dev_dbg(dev, state, "LATE class "); - error = pm_noirq_op(dev, dev->class->pm, state); - if (error) - goto End; - } + int error; if (dev->type && dev->type->pm) { pm_dev_dbg(dev, state, "LATE type "); error = pm_noirq_op(dev, dev->type->pm, state); if (error) - goto End; - } - - if (dev->bus && dev->bus->pm) { + return error; + } else if (dev->class && dev->class->pm) { + pm_dev_dbg(dev, state, "LATE class "); + error = pm_noirq_op(dev, dev->class->pm, state); + if (error) + return error; + } else if (dev->bus && dev->bus->pm) { pm_dev_dbg(dev, state, "LATE "); error = pm_noirq_op(dev, dev->bus->pm, state); if (error) - goto End; + return error; } if (dev->pwr_domain) { @@ -769,8 +753,7 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state) pm_noirq_op(dev, &dev->pwr_domain->ops, state); } -End: - return error; + return 0; } /** @@ -857,25 +840,22 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) goto End; } + if (dev->type && dev->type->pm) { + pm_dev_dbg(dev, state, "type "); + error = pm_op(dev, dev->type->pm, state); + goto Domain; + } + if (dev->class) { if (dev->class->pm) { pm_dev_dbg(dev, state, "class "); error = pm_op(dev, dev->class->pm, state); + goto Domain; } else if (dev->class->suspend) { pm_dev_dbg(dev, state, "legacy class "); error = legacy_suspend(dev, state, dev->class->suspend); + goto Domain; } - if (error) - goto End; - } - - if (dev->type) { - if (dev->type->pm) { - pm_dev_dbg(dev, state, "type "); - error = pm_op(dev, dev->type->pm, state); - } - if (error) - goto End; } if (dev->bus) { @@ -886,11 +866,10 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) pm_dev_dbg(dev, state, "legacy "); error = legacy_suspend(dev, state, dev->bus->suspend); } - if (error) - goto End; } - if (dev->pwr_domain) { + Domain: + if (!error && dev->pwr_domain) { pm_dev_dbg(dev, state, "power domain "); pm_op(dev, &dev->pwr_domain->ops, state); } @@ -985,28 +964,27 @@ static int device_prepare(struct device *dev, pm_message_t state) device_lock(dev); - if (dev->bus && dev->bus->pm && dev->bus->pm->prepare) { - pm_dev_dbg(dev, state, "preparing "); - error = dev->bus->pm->prepare(dev); - suspend_report_result(dev->bus->pm->prepare, error); - if (error) - goto End; - } - - if (dev->type && dev->type->pm && dev->type->pm->prepare) { + if (dev->type && dev->type->pm) { pm_dev_dbg(dev, state, "preparing type "); - error = dev->type->pm->prepare(dev); + if (dev->type->pm->prepare) + error = dev->type->pm->prepare(dev); suspend_report_result(dev->type->pm->prepare, error); if (error) goto End; - } - - if (dev->class && dev->class->pm && dev->class->pm->prepare) { + } else if (dev->class && dev->class->pm) { pm_dev_dbg(dev, state, "preparing class "); - error = dev->class->pm->prepare(dev); + if (dev->class->pm->prepare) + error = dev->class->pm->prepare(dev); suspend_report_result(dev->class->pm->prepare, error); if (error) goto End; + } else if (dev->bus && dev->bus->pm) { + pm_dev_dbg(dev, state, "preparing "); + if (dev->bus->pm->prepare) + error = dev->bus->pm->prepare(dev); + suspend_report_result(dev->bus->pm->prepare, error); + if (error) + goto End; } if (dev->pwr_domain && dev->pwr_domain->ops.prepare) { diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 25edc9a3a489..54597c859ecb 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -214,12 +214,12 @@ static int rpm_idle(struct device *dev, int rpmflags) dev->power.idle_notification = true; - if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_idle) - callback = dev->bus->pm->runtime_idle; - else if (dev->type && dev->type->pm && dev->type->pm->runtime_idle) + if (dev->type && dev->type->pm) callback = dev->type->pm->runtime_idle; else if (dev->class && dev->class->pm) callback = dev->class->pm->runtime_idle; + else if (dev->bus && dev->bus->pm) + callback = dev->bus->pm->runtime_idle; else callback = NULL; @@ -382,12 +382,12 @@ static int rpm_suspend(struct device *dev, int rpmflags) __update_runtime_status(dev, RPM_SUSPENDING); - if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend) - callback = dev->bus->pm->runtime_suspend; - else if (dev->type && dev->type->pm && dev->type->pm->runtime_suspend) + if (dev->type && dev->type->pm) callback = dev->type->pm->runtime_suspend; else if (dev->class && dev->class->pm) callback = dev->class->pm->runtime_suspend; + else if (dev->bus && dev->bus->pm) + callback = dev->bus->pm->runtime_suspend; else callback = NULL; @@ -584,12 +584,12 @@ static int rpm_resume(struct device *dev, int rpmflags) if (dev->pwr_domain) rpm_callback(dev->pwr_domain->ops.runtime_resume, dev); - if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_resume) - callback = dev->bus->pm->runtime_resume; - else if (dev->type && dev->type->pm && dev->type->pm->runtime_resume) + if (dev->type && dev->type->pm) callback = dev->type->pm->runtime_resume; else if (dev->class && dev->class->pm) callback = dev->class->pm->runtime_resume; + else if (dev->bus && dev->bus->pm) + callback = dev->bus->pm->runtime_resume; else callback = NULL; -- cgit v1.2.3 From 7ae496187876d264c712d7c102c45edb8eb41363 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Fri, 25 Feb 2011 23:46:18 +0100 Subject: PM / OPP: opp_find_freq_exact() documentation fix opp_find_freq_exact() documentation has is_available instead of available. This also fixes warning with the kernel-doc: scripts/kernel-doc drivers/base/power/opp.c >/dev/null Warning(drivers/base/power/opp.c:246): No description found for parameter 'available' Warning(drivers/base/power/opp.c:246): Excess function parameter 'is_available' description in 'opp_find_freq_exact' Signed-off-by: Nishanth Menon Signed-off-by: Rafael J. Wysocki --- drivers/base/power/opp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index 2bb9b4cf59d7..56a6899f5e9e 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c @@ -222,7 +222,7 @@ int opp_get_opp_count(struct device *dev) * opp_find_freq_exact() - search for an exact frequency * @dev: device for which we do this operation * @freq: frequency to search for - * @is_available: true/false - match for available opp + * @available: true/false - match for available opp * * Searches for exact match in the opp list and returns pointer to the matching * opp if found, else returns ERR_PTR in case of error and should be handled -- cgit v1.2.3 From 40dc166cb5dddbd36aa4ad11c03915ea538f5a61 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 15 Mar 2011 00:43:46 +0100 Subject: PM / Core: Introduce struct syscore_ops for core subsystems PM Some subsystems need to carry out suspend/resume and shutdown operations with one CPU on-line and interrupts disabled. The only way to register such operations is to define a sysdev class and a sysdev specifically for this purpose which is cumbersome and inefficient. Moreover, the arguments taken by sysdev suspend, resume and shutdown callbacks are practically never necessary. For this reason, introduce a simpler interface allowing subsystems to register operations to be executed very late during system suspend and shutdown and very early during resume in the form of strcut syscore_ops objects. Signed-off-by: Rafael J. Wysocki Acked-by: Greg Kroah-Hartman --- drivers/base/Makefile | 2 +- drivers/base/syscore.c | 117 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/syscore_ops.h | 29 +++++++++++ kernel/power/hibernate.c | 9 ++++ kernel/power/suspend.c | 4 ++ kernel/sys.c | 4 ++ 6 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 drivers/base/syscore.c create mode 100644 include/linux/syscore_ops.h (limited to 'drivers') diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 5f51c3b4451e..4c5701c15f53 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -1,6 +1,6 @@ # Makefile for the Linux device tree -obj-y := core.o sys.o bus.o dd.o \ +obj-y := core.o sys.o bus.o dd.o syscore.o \ driver.o class.o platform.o \ cpu.o firmware.o init.o map.o devres.o \ attribute_container.o transport_class.o diff --git a/drivers/base/syscore.c b/drivers/base/syscore.c new file mode 100644 index 000000000000..90af2943f9e4 --- /dev/null +++ b/drivers/base/syscore.c @@ -0,0 +1,117 @@ +/* + * syscore.c - Execution of system core operations. + * + * Copyright (C) 2011 Rafael J. Wysocki , Novell Inc. + * + * This file is released under the GPLv2. + */ + +#include +#include +#include + +static LIST_HEAD(syscore_ops_list); +static DEFINE_MUTEX(syscore_ops_lock); + +/** + * register_syscore_ops - Register a set of system core operations. + * @ops: System core operations to register. + */ +void register_syscore_ops(struct syscore_ops *ops) +{ + mutex_lock(&syscore_ops_lock); + list_add_tail(&ops->node, &syscore_ops_list); + mutex_unlock(&syscore_ops_lock); +} +EXPORT_SYMBOL_GPL(register_syscore_ops); + +/** + * unregister_syscore_ops - Unregister a set of system core operations. + * @ops: System core operations to unregister. + */ +void unregister_syscore_ops(struct syscore_ops *ops) +{ + mutex_lock(&syscore_ops_lock); + list_del(&ops->node); + mutex_unlock(&syscore_ops_lock); +} +EXPORT_SYMBOL_GPL(unregister_syscore_ops); + +#ifdef CONFIG_PM_SLEEP +/** + * syscore_suspend - Execute all the registered system core suspend callbacks. + * + * This function is executed with one CPU on-line and disabled interrupts. + */ +int syscore_suspend(void) +{ + struct syscore_ops *ops; + int ret = 0; + + WARN_ONCE(!irqs_disabled(), + "Interrupts enabled before system core suspend.\n"); + + list_for_each_entry_reverse(ops, &syscore_ops_list, node) + if (ops->suspend) { + if (initcall_debug) + pr_info("PM: Calling %pF\n", ops->suspend); + ret = ops->suspend(); + if (ret) + goto err_out; + WARN_ONCE(!irqs_disabled(), + "Interrupts enabled after %pF\n", ops->suspend); + } + + return 0; + + err_out: + pr_err("PM: System core suspend callback %pF failed.\n", ops->suspend); + + list_for_each_entry_continue(ops, &syscore_ops_list, node) + if (ops->resume) + ops->resume(); + + return ret; +} + +/** + * syscore_resume - Execute all the registered system core resume callbacks. + * + * This function is executed with one CPU on-line and disabled interrupts. + */ +void syscore_resume(void) +{ + struct syscore_ops *ops; + + WARN_ONCE(!irqs_disabled(), + "Interrupts enabled before system core resume.\n"); + + list_for_each_entry(ops, &syscore_ops_list, node) + if (ops->resume) { + if (initcall_debug) + pr_info("PM: Calling %pF\n", ops->resume); + ops->resume(); + WARN_ONCE(!irqs_disabled(), + "Interrupts enabled after %pF\n", ops->resume); + } +} +#endif /* CONFIG_PM_SLEEP */ + +/** + * syscore_shutdown - Execute all the registered system core shutdown callbacks. + */ +void syscore_shutdown(void) +{ + struct syscore_ops *ops; + + mutex_lock(&syscore_ops_lock); + + list_for_each_entry_reverse(ops, &syscore_ops_list, node) + if (ops->shutdown) { + if (initcall_debug) + pr_info("PM: Calling %pF\n", ops->shutdown); + ops->shutdown(); + } + + mutex_unlock(&syscore_ops_lock); +} diff --git a/include/linux/syscore_ops.h b/include/linux/syscore_ops.h new file mode 100644 index 000000000000..27b3b0bc41a9 --- /dev/null +++ b/include/linux/syscore_ops.h @@ -0,0 +1,29 @@ +/* + * syscore_ops.h - System core operations. + * + * Copyright (C) 2011 Rafael J. Wysocki , Novell Inc. + * + * This file is released under the GPLv2. + */ + +#ifndef _LINUX_SYSCORE_OPS_H +#define _LINUX_SYSCORE_OPS_H + +#include + +struct syscore_ops { + struct list_head node; + int (*suspend)(void); + void (*resume)(void); + void (*shutdown)(void); +}; + +extern void register_syscore_ops(struct syscore_ops *ops); +extern void unregister_syscore_ops(struct syscore_ops *ops); +#ifdef CONFIG_PM_SLEEP +extern int syscore_suspend(void); +extern void syscore_resume(void); +#endif +extern void syscore_shutdown(void); + +#endif diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 1832bd264219..aeabd26e3342 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -272,6 +273,8 @@ static int create_image(int platform_mode) local_irq_disable(); error = sysdev_suspend(PMSG_FREEZE); + if (!error) + error = syscore_suspend(); if (error) { printk(KERN_ERR "PM: Some system devices failed to power down, " "aborting hibernation\n"); @@ -295,6 +298,7 @@ static int create_image(int platform_mode) } Power_up: + syscore_resume(); sysdev_resume(); /* NOTE: dpm_resume_noirq() is just a resume() for devices * that suspended with irqs off ... no overall powerup. @@ -403,6 +407,8 @@ static int resume_target_kernel(bool platform_mode) local_irq_disable(); error = sysdev_suspend(PMSG_QUIESCE); + if (!error) + error = syscore_suspend(); if (error) goto Enable_irqs; @@ -429,6 +435,7 @@ static int resume_target_kernel(bool platform_mode) restore_processor_state(); touch_softlockup_watchdog(); + syscore_resume(); sysdev_resume(); Enable_irqs: @@ -516,6 +523,7 @@ int hibernation_platform_enter(void) local_irq_disable(); sysdev_suspend(PMSG_HIBERNATE); + syscore_suspend(); if (pm_wakeup_pending()) { error = -EAGAIN; goto Power_up; @@ -526,6 +534,7 @@ int hibernation_platform_enter(void) while (1); Power_up: + syscore_resume(); sysdev_resume(); local_irq_enable(); enable_nonboot_cpus(); diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index de6f86bfa303..2814c32aed51 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "power.h" @@ -163,11 +164,14 @@ static int suspend_enter(suspend_state_t state) BUG_ON(!irqs_disabled()); error = sysdev_suspend(PMSG_SUSPEND); + if (!error) + error = syscore_suspend(); if (!error) { if (!(suspend_test(TEST_CORE) || pm_wakeup_pending())) { error = suspend_ops->enter(state); events_check_enabled = false; } + syscore_resume(); sysdev_resume(); } diff --git a/kernel/sys.c b/kernel/sys.c index 18da702ec813..1ad48b3b9068 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -298,6 +299,7 @@ void kernel_restart_prepare(char *cmd) system_state = SYSTEM_RESTART; device_shutdown(); sysdev_shutdown(); + syscore_shutdown(); } /** @@ -336,6 +338,7 @@ void kernel_halt(void) { kernel_shutdown_prepare(SYSTEM_HALT); sysdev_shutdown(); + syscore_shutdown(); printk(KERN_EMERG "System halted.\n"); kmsg_dump(KMSG_DUMP_HALT); machine_halt(); @@ -355,6 +358,7 @@ void kernel_power_off(void) pm_power_off_prepare(); disable_nonboot_cpus(); sysdev_shutdown(); + syscore_shutdown(); printk(KERN_EMERG "Power down.\n"); kmsg_dump(KMSG_DUMP_POWEROFF); machine_power_off(); -- cgit v1.2.3 From d181a6171ec84a6139dd11d3dd546748c640dcaa Mon Sep 17 00:00:00 2001 From: Domenico Andreoli Date: Mon, 14 Mar 2011 03:46:53 +0000 Subject: CS89x0: Finish transition to CS89x0_NONISA_IRQ CS89x0_NONISA_IRQ is selected by all those non-ISA boards which use CS89x0. This patch only cleans the last bits left after its introduction. Signed-off-by: Domenico Andreoli Signed-off-by: David S. Miller --- drivers/net/cs89x0.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index d325e01a53e0..e6ac755ff5ce 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -943,10 +943,10 @@ skip_this_frame: static void __init reset_chip(struct net_device *dev) { #if !defined(CONFIG_MACH_MX31ADS) -#if !defined(CONFIG_MACH_IXDP2351) && !defined(CONFIG_ARCH_IXDP2X01) +#if !defined(CS89x0_NONISA_IRQ) struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; -#endif +#endif /* CS89x0_NONISA_IRQ */ int reset_start_time; writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET); @@ -954,7 +954,7 @@ static void __init reset_chip(struct net_device *dev) /* wait 30 ms */ msleep(30); -#if !defined(CONFIG_MACH_IXDP2351) && !defined(CONFIG_ARCH_IXDP2X01) +#if !defined(CS89x0_NONISA_IRQ) if (lp->chip_type != CS8900) { /* Hardware problem requires PNP registers to be reconfigured after a reset */ writeword(ioaddr, ADD_PORT, PP_CS8920_ISAINT); @@ -965,7 +965,7 @@ static void __init reset_chip(struct net_device *dev) outb((dev->mem_start >> 16) & 0xff, ioaddr + DATA_PORT); outb((dev->mem_start >> 8) & 0xff, ioaddr + DATA_PORT + 1); } -#endif /* IXDP2x01 */ +#endif /* CS89x0_NONISA_IRQ */ /* Wait until the chip is reset */ reset_start_time = jiffies; -- cgit v1.2.3 From 2ce8c07d63cf860d6869eb4948522a0fef5ccc19 Mon Sep 17 00:00:00 2001 From: Domenico Andreoli Date: Mon, 14 Mar 2011 03:47:07 +0000 Subject: CS89x0: Add networking support for QQ2440 QQ2440 is only another non-ISA board using CS89x0. This patch adds the minimum bits required to make QQ2440 work with CS89x0. Signed-off-by: Domenico Andreoli Signed-off-by: David S. Miller --- drivers/net/Kconfig | 4 ++-- drivers/net/cs89x0.c | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 925c25c295f0..46e1b1a28b80 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1498,7 +1498,7 @@ config FORCEDETH config CS89x0 tristate "CS89x0 support" depends on NET_ETHERNET && (ISA || EISA || MACH_IXDP2351 \ - || ARCH_IXDP2X01 || MACH_MX31ADS) + || ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440) ---help--- Support for CS89x0 chipset based Ethernet cards. If you have a network (Ethernet) card of this type, say Y and read the @@ -1512,7 +1512,7 @@ config CS89x0 config CS89x0_NONISA_IRQ def_bool y depends on CS89x0 != n - depends on MACH_IXDP2351 || ARCH_IXDP2X01 || MACH_MX31ADS + depends on MACH_IXDP2351 || ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440 config TC35815 tristate "TOSHIBA TC35815 Ethernet support" diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index e6ac755ff5ce..537a4b2e2020 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -95,6 +95,9 @@ Dmitry Pervushin : dpervushin@ru.mvista.com : PNX010X platform support + Domenico Andreoli : cavokz@gmail.com + : QQ2440 platform support + */ /* Always include 'config.h' first in case the user wants to turn on @@ -176,6 +179,10 @@ static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0}; #elif defined(CONFIG_ARCH_IXDP2X01) static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0}; static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0}; +#elif defined(CONFIG_MACH_QQ2440) +#include +static unsigned int netcard_portlist[] __used __initdata = { QQ2440_CS8900_VIRT_BASE + 0x300, 0 }; +static unsigned int cs8900_irq_map[] = { QQ2440_CS8900_IRQ, 0, 0, 0 }; #elif defined(CONFIG_MACH_MX31ADS) #include static unsigned int netcard_portlist[] __used __initdata = { @@ -521,6 +528,10 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) #endif lp->force = g_cs89x0_media__force; #endif + +#if defined(CONFIG_MACH_QQ2440) + lp->force |= FORCE_RJ45 | FORCE_FULL; +#endif } /* Grab the region so we can find another board if autoIRQ fails. */ -- cgit v1.2.3 From cc8bdf062318e76277dd76970ed58930d49888b0 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 1 Mar 2011 20:05:35 +0000 Subject: fcoe: correct checking for bonding Check for bonding master and refuse to use that. Signed-off-by: Jiri Pirko Acked-by: Robert Love Acked-by: James Bottomley Signed-off-by: David S. Miller --- drivers/scsi/fcoe/fcoe.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 9f9600b67001..3becc6a20a4f 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -285,9 +285,7 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe, } /* Do not support for bonding device */ - if ((netdev->priv_flags & IFF_MASTER_ALB) || - (netdev->priv_flags & IFF_SLAVE_INACTIVE) || - (netdev->priv_flags & IFF_MASTER_8023AD)) { + if (netdev->priv_flags & IFF_BONDING && netdev->flags & IFF_MASTER) { FCOE_NETDEV_DBG(netdev, "Bonded interfaces not supported\n"); return -EOPNOTSUPP; } -- cgit v1.2.3 From 12a2856b604476c27d85a5f9a57ae1661fc46019 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 14 Mar 2011 06:08:07 +0000 Subject: macvlan : fix checksums error when we are in bridge mode When the lower device has offloading capabilities, the packets checksums are not computed. That leads to have any macvlan port in bridge mode to not work because the packets are dropped due to a bad checksum. If the macvlan is in bridge mode, the packet is forwarded to another macvlan port and reach the network stack where it looks for a checksum but this one was not computed due to the offloading of the lower device. In this case, we have to set the packet with CHECKSUM_UNNECESSARY when it is forwarded to a bridged port and restore the previous value of ip_summed when the packet goes to the lowerdev. Signed-off-by: Daniel Lezcano Cc: Patrick McHardy Cc: Andrian Nord Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/macvlan.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 6ed577b065df..497991bd3b64 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -219,9 +219,11 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) const struct macvlan_dev *vlan = netdev_priv(dev); const struct macvlan_port *port = vlan->port; const struct macvlan_dev *dest; + __u8 ip_summed = skb->ip_summed; if (vlan->mode == MACVLAN_MODE_BRIDGE) { const struct ethhdr *eth = (void *)skb->data; + skb->ip_summed = CHECKSUM_UNNECESSARY; /* send to other bridge ports directly */ if (is_multicast_ether_addr(eth->h_dest)) { @@ -241,6 +243,7 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) } xmit_world: + skb->ip_summed = ip_summed; skb_set_dev(skb, vlan->lowerdev); return dev_queue_xmit(skb); } -- cgit v1.2.3 From 48f26d514ed14f717ebd49439894a9637e0353a9 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 14 Mar 2011 21:05:40 -0700 Subject: xen: netfront: fix xennet_get_ethtool_stats() commit e9a799ea4a5551d2 (xen: netfront: ethtool stats fields should be unsigned long) made rx_gso_checksum_fixup an unsigned long. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/xen-netfront.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 27cf72f26cbb..5b399b54fef7 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1692,7 +1692,7 @@ static void xennet_get_ethtool_stats(struct net_device *dev, int i; for (i = 0; i < ARRAY_SIZE(xennet_stats); i++) - data[i] = *(int *)(np + xennet_stats[i].offset); + data[i] = *(unsigned long *)(np + xennet_stats[i].offset); } static void xennet_get_strings(struct net_device *dev, u32 stringset, u8 * data) -- cgit v1.2.3 From 673b8b70cfae2cd0428a8ab5647571521348549a Mon Sep 17 00:00:00 2001 From: Anders Berggren Date: Fri, 4 Feb 2011 07:32:32 +0000 Subject: igb: fix hw timestamping Hardware timestamping for Intel 82580 didn't work in either 2.6.36 or 2.6.37. Comparing it to Intel's igb-2.4.12 I found that the timecounter_init clock/counter initialization was done too early. Signed-off-by: Anders Berggren Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/igb/igb_main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index b4f92b06f2ac..5366f2ab65f0 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -106,6 +106,7 @@ static void igb_free_all_rx_resources(struct igb_adapter *); static void igb_setup_mrqc(struct igb_adapter *); static int igb_probe(struct pci_dev *, const struct pci_device_id *); static void __devexit igb_remove(struct pci_dev *pdev); +static void igb_init_hw_timer(struct igb_adapter *adapter); static int igb_sw_init(struct igb_adapter *); static int igb_open(struct net_device *); static int igb_close(struct net_device *); @@ -2048,6 +2049,9 @@ static int __devinit igb_probe(struct pci_dev *pdev, } #endif + /* do hw tstamp init after resetting */ + igb_init_hw_timer(adapter); + dev_info(&pdev->dev, "Intel(R) Gigabit Ethernet Network Connection\n"); /* print bus type/speed/width info */ dev_info(&pdev->dev, "%s: (PCIe:%s:%s) %pM\n", @@ -2384,7 +2388,6 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter) return -ENOMEM; } - igb_init_hw_timer(adapter); igb_probe_vfs(adapter); /* Explicitly disable IRQ since the NIC can be in any state. */ -- cgit v1.2.3 From 7ef5ed1ce96c3f9a95b7327279f94b0700c689ef Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Sat, 12 Mar 2011 08:59:47 +0000 Subject: igb: Add messaging for thermal sensor events on i350 devices This feature adds messaging to the link status change to notify the user if the device returned from a downshift or power off event due to the Thermal Sensor feature in i350 parts. Feature is only available on internal copper ports. Signed-off-by: Carolyn Wyborny Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/igb/e1000_defines.h | 5 +++++ drivers/net/igb/e1000_regs.h | 3 +++ drivers/net/igb/igb_main.c | 37 ++++++++++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index 9bb192825893..6b80d40110ca 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h @@ -51,6 +51,7 @@ #define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000 #define E1000_CTRL_EXT_LINK_MODE_1000BASE_KX 0x00400000 #define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000 +#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000 #define E1000_CTRL_EXT_EIAME 0x01000000 #define E1000_CTRL_EXT_IRCA 0x00000001 /* Interrupt delay cancellation */ @@ -788,6 +789,10 @@ #define E1000_MDIC_ERROR 0x40000000 #define E1000_MDIC_DEST 0x80000000 +/* Thermal Sensor */ +#define E1000_THSTAT_PWR_DOWN 0x00000001 /* Power Down Event */ +#define E1000_THSTAT_LINK_THROTTLE 0x00000002 /* Link Speed Throttle Event */ + /* Energy Efficient Ethernet */ #define E1000_IPCNFG_EEE_1G_AN 0x00000008 /* EEE Enable 1G AN */ #define E1000_IPCNFG_EEE_100M_AN 0x00000004 /* EEE Enable 100M AN */ diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h index ad77ed510d7c..958ca3bda482 100644 --- a/drivers/net/igb/e1000_regs.h +++ b/drivers/net/igb/e1000_regs.h @@ -342,6 +342,9 @@ #define E1000_IPCNFG 0x0E38 /* Internal PHY Configuration */ #define E1000_EEER 0x0E30 /* Energy Efficient Ethernet */ +/* Thermal Sensor Register */ +#define E1000_THSTAT 0x08110 /* Thermal Sensor Status */ + /* OS2BMC Registers */ #define E1000_B2OSPC 0x08FE0 /* BMC2OS packets sent by BMC */ #define E1000_B2OGPRC 0x04158 /* BMC2OS packets received by host */ diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 5366f2ab65f0..3d850af0cdda 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -3550,7 +3550,7 @@ static void igb_watchdog_task(struct work_struct *work) watchdog_task); struct e1000_hw *hw = &adapter->hw; struct net_device *netdev = adapter->netdev; - u32 link; + u32 link, ctrl_ext, thstat; int i; link = igb_has_link(adapter); @@ -3574,6 +3574,25 @@ static void igb_watchdog_task(struct work_struct *work) ((ctrl & E1000_CTRL_RFCE) ? "RX" : ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None"))); + /* check for thermal sensor event on i350, + * copper only */ + if (hw->mac.type == e1000_i350) { + thstat = rd32(E1000_THSTAT); + ctrl_ext = rd32(E1000_CTRL_EXT); + if ((hw->phy.media_type == + e1000_media_type_copper) && !(ctrl_ext & + E1000_CTRL_EXT_LINK_MODE_SGMII)) { + if (thstat & + E1000_THSTAT_LINK_THROTTLE) { + printk(KERN_INFO "igb: %s The " + "network adapter link " + "speed was downshifted " + "because it " + "overheated.\n", + netdev->name); + } + } + } /* adjust timeout factor according to speed/duplex */ adapter->tx_timeout_factor = 1; switch (adapter->link_speed) { @@ -3599,6 +3618,22 @@ static void igb_watchdog_task(struct work_struct *work) if (netif_carrier_ok(netdev)) { adapter->link_speed = 0; adapter->link_duplex = 0; + /* check for thermal sensor event on i350 + * copper only*/ + if (hw->mac.type == e1000_i350) { + thstat = rd32(E1000_THSTAT); + ctrl_ext = rd32(E1000_CTRL_EXT); + if ((hw->phy.media_type == + e1000_media_type_copper) && !(ctrl_ext & + E1000_CTRL_EXT_LINK_MODE_SGMII)) { + if (thstat & E1000_THSTAT_PWR_DOWN) { + printk(KERN_ERR "igb: %s The " + "network adapter was stopped " + "because it overheated.\n", + netdev->name); + } + } + } /* Links status message must follow this format */ printk(KERN_INFO "igb: %s NIC Link is Down\n", netdev->name); -- cgit v1.2.3 From 50be5e3657cd2851a297dc0b3fd459f25829d29b Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 29 Nov 2010 15:57:14 +0100 Subject: ahci: add another PCI ID for marvell 1b4b:91a3 seems to be another PCI ID for marvell ahci. Add it. Reported and tested in the following thread. http://thread.gmane.org/gmane.linux.kernel/1068354 Signed-off-by: Tejun Heo Reported-by: Borislav Petkov Reported-by: Alessandro Tagliapietra Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 0c22ebd540d3..e62f693be8ea 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -385,6 +385,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { .driver_data = board_ahci_yes_fbs }, /* 88se9128 */ { PCI_DEVICE(0x1b4b, 0x9125), .driver_data = board_ahci_yes_fbs }, /* 88se9125 */ + { PCI_DEVICE(0x1b4b, 0x91a3), + .driver_data = board_ahci_yes_fbs }, /* Promise */ { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ -- cgit v1.2.3 From 25ae21a10112875763c18b385624df713a288a05 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Wed, 23 Feb 2011 08:11:32 -0800 Subject: RDMA/cma: Fix crash in request handlers Doug Ledford and Red Hat reported a crash when running the rdma_cm on a real-time OS. The crash has the following call trace: cm_process_work cma_req_handler cma_disable_callback rdma_create_id kzalloc init_completion cma_get_net_info cma_save_net_info cma_any_addr cma_zero_addr rdma_translate_ip rdma_copy_addr cma_acquire_dev rdma_addr_get_sgid ib_find_cached_gid cma_attach_to_dev ucma_event_handler kzalloc ib_copy_ah_attr_to_user cma_comp [ preempted ] cma_write copy_from_user ucma_destroy_id copy_from_user _ucma_find_context ucma_put_ctx ucma_free_ctx rdma_destroy_id cma_exch cma_cancel_operation rdma_node_get_transport rt_mutex_slowunlock bad_area_nosemaphore oops_enter They were able to reproduce the crash multiple times with the following details: Crash seems to always happen on the: mutex_unlock(&conn_id->handler_mutex); as conn_id looks to have been freed during this code path. An examination of the code shows that a race exists in the request handlers. When a new connection request is received, the rdma_cm allocates a new connection identifier. This identifier has a single reference count on it. If a user calls rdma_destroy_id() from another thread after receiving a callback, rdma_destroy_id will proceed to destroy the id and free the associated memory. However, the request handlers may still be in the process of running. When control returns to the request handlers, they can attempt to access the newly created identifiers. Fix this by holding a reference on the newly created rdma_cm_id until the request handler is through accessing it. Signed-off-by: Sean Hefty Acked-by: Doug Ledford Cc: Signed-off-by: Roland Dreier --- drivers/infiniband/core/cma.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 6884da24fde1..e450c5a87727 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -1210,6 +1210,11 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) cm_id->context = conn_id; cm_id->cm_handler = cma_ib_handler; + /* + * Protect against the user destroying conn_id from another thread + * until we're done accessing it. + */ + atomic_inc(&conn_id->refcount); ret = conn_id->id.event_handler(&conn_id->id, &event); if (!ret) { /* @@ -1222,8 +1227,10 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0); mutex_unlock(&lock); mutex_unlock(&conn_id->handler_mutex); + cma_deref_id(conn_id); goto out; } + cma_deref_id(conn_id); /* Destroy the CM ID by returning a non-zero value. */ conn_id->cm_id.ib = NULL; @@ -1425,17 +1432,25 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, event.param.conn.private_data_len = iw_event->private_data_len; event.param.conn.initiator_depth = attr.max_qp_init_rd_atom; event.param.conn.responder_resources = attr.max_qp_rd_atom; + + /* + * Protect against the user destroying conn_id from another thread + * until we're done accessing it. + */ + atomic_inc(&conn_id->refcount); ret = conn_id->id.event_handler(&conn_id->id, &event); if (ret) { /* User wants to destroy the CM ID */ conn_id->cm_id.iw = NULL; cma_exch(conn_id, CMA_DESTROYING); mutex_unlock(&conn_id->handler_mutex); + cma_deref_id(conn_id); rdma_destroy_id(&conn_id->id); goto out; } mutex_unlock(&conn_id->handler_mutex); + cma_deref_id(conn_id); out: if (dev) -- cgit v1.2.3 From 29963437a48475036353b95ab142bf199adb909e Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Wed, 23 Feb 2011 08:17:40 -0800 Subject: IB/cm: Bump reference count on cm_id before invoking callback When processing a SIDR REQ, the ib_cm allocates a new cm_id. The refcount of the cm_id is initialized to 1. However, cm_process_work will decrement the refcount after invoking all callbacks. The result is that the cm_id will end up with refcount set to 0 by the end of the sidr req handler. If a user tries to destroy the cm_id, the destruction will proceed, under the incorrect assumption that no other threads are referencing the cm_id. This can lead to a crash when the cm callback thread tries to access the cm_id. This problem was noticed as part of a larger investigation with kernel crashes in the rdma_cm when running on a real time OS. Signed-off-by: Sean Hefty Acked-by: Doug Ledford Cc: Signed-off-by: Roland Dreier --- drivers/infiniband/core/cm.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 64e0903091a8..1d9616be4192 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -2989,6 +2989,7 @@ static int cm_sidr_req_handler(struct cm_work *work) goto out; /* No match. */ } atomic_inc(&cur_cm_id_priv->refcount); + atomic_inc(&cm_id_priv->refcount); spin_unlock_irq(&cm.lock); cm_id_priv->id.cm_handler = cur_cm_id_priv->id.cm_handler; -- cgit v1.2.3 From 8d8ac86564b616bc17054cbb6e727588da64c86b Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Thu, 3 Mar 2011 23:31:06 +0000 Subject: IB/cm: Cancel pending LAP message when exiting IB_CM_ESTABLISH state This problem was reported by Moni Shoua and Amir Vadai : When destroying a cm_id from a context of a work queue and if the lap_state of this cm_id is IB_CM_LAP_SENT, we need to release the reference of this id that was taken upon the send of the LAP message. Otherwise, if the expected APR message gets lost, it is only after a long time that the reference will be released, while during that the work handler thread is not available to process other things. It turns out that we need to cancel any pending LAP messages whenever we transition out of the IB_CM_ESTABLISH state. This occurs when disconnecting - either sending or receiving a DREQ. It can also happen in a corner case where we receive a REJ message after sending an RTU, followed by a LAP. Add checks and cancel any outstanding LAP messages in these three cases. Canceling the LAP when sending a DREQ fixes the destroy problem reported by Moni. When a cm_id is destroyed in the IB_CM_ESTABLISHED state, it sends a DREQ to the remote side to notify the peer that the connection is going away. Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier --- drivers/infiniband/core/cm.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 1d9616be4192..f804e28e1ebb 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -1988,6 +1988,10 @@ int ib_send_cm_dreq(struct ib_cm_id *cm_id, goto out; } + if (cm_id->lap_state == IB_CM_LAP_SENT || + cm_id->lap_state == IB_CM_MRA_LAP_RCVD) + ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); + ret = cm_alloc_msg(cm_id_priv, &msg); if (ret) { cm_enter_timewait(cm_id_priv); @@ -2129,6 +2133,10 @@ static int cm_dreq_handler(struct cm_work *work) ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); break; case IB_CM_ESTABLISHED: + if (cm_id_priv->id.lap_state == IB_CM_LAP_SENT || + cm_id_priv->id.lap_state == IB_CM_MRA_LAP_RCVD) + ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); + break; case IB_CM_MRA_REP_RCVD: break; case IB_CM_TIMEWAIT: @@ -2349,9 +2357,18 @@ static int cm_rej_handler(struct cm_work *work) /* fall through */ case IB_CM_REP_RCVD: case IB_CM_MRA_REP_SENT: - case IB_CM_ESTABLISHED: cm_enter_timewait(cm_id_priv); break; + case IB_CM_ESTABLISHED: + if (cm_id_priv->id.lap_state == IB_CM_LAP_UNINIT || + cm_id_priv->id.lap_state == IB_CM_LAP_SENT) { + if (cm_id_priv->id.lap_state == IB_CM_LAP_SENT) + ib_cancel_mad(cm_id_priv->av.port->mad_agent, + cm_id_priv->msg); + cm_enter_timewait(cm_id_priv); + break; + } + /* fall through */ default: spin_unlock_irq(&cm_id_priv->lock); ret = -EINVAL; -- cgit v1.2.3 From a396d43a35fb91f2d4920a4700d25ecc5ec92404 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Wed, 23 Feb 2011 09:05:39 -0800 Subject: RDMA/cma: Replace global lock in rdma_destroy_id() with id-specific one rdma_destroy_id currently uses the global rdma cm 'lock' to test if an rdma_cm_id has been bound to a device. This prevents an active address resolution callback handler from assigning a device to the rdma_cm_id after rdma_destroy_id checks for one. Instead, we can replace the use of the global lock around the check to the rdma_cm_id device pointer by setting the id state to destroying, then flushing all active callbacks. The latter is accomplished by acquiring and releasing the handler_mutex. Any active handler will complete first, and any newly scheduled handlers will find the rdma_cm_id in an invalid state. In addition to optimizing the current locking scheme, the use of the rdma_cm_id mutex is a more intuitive synchronization mechanism than that of the global lock. These changes are based on feedback from Doug Ledford while he was trying to debug a crash in the rdma cm destroy path. Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier --- drivers/infiniband/core/cma.c | 43 ++++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index e450c5a87727..5ed9d25d021a 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -308,11 +308,13 @@ static inline void release_mc(struct kref *kref) kfree(mc); } -static void cma_detach_from_dev(struct rdma_id_private *id_priv) +static void cma_release_dev(struct rdma_id_private *id_priv) { + mutex_lock(&lock); list_del(&id_priv->list); cma_deref_dev(id_priv->cma_dev); id_priv->cma_dev = NULL; + mutex_unlock(&lock); } static int cma_set_qkey(struct rdma_id_private *id_priv) @@ -373,6 +375,7 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv) enum rdma_link_layer dev_ll = dev_addr->dev_type == ARPHRD_INFINIBAND ? IB_LINK_LAYER_INFINIBAND : IB_LINK_LAYER_ETHERNET; + mutex_lock(&lock); iboe_addr_get_sgid(dev_addr, &iboe_gid); memcpy(&gid, dev_addr->src_dev_addr + rdma_addr_gid_offset(dev_addr), sizeof gid); @@ -398,6 +401,7 @@ out: if (!ret) cma_attach_to_dev(id_priv, cma_dev); + mutex_unlock(&lock); return ret; } @@ -904,9 +908,14 @@ void rdma_destroy_id(struct rdma_cm_id *id) state = cma_exch(id_priv, CMA_DESTROYING); cma_cancel_operation(id_priv, state); - mutex_lock(&lock); + /* + * Wait for any active callback to finish. New callbacks will find + * the id_priv state set to destroying and abort. + */ + mutex_lock(&id_priv->handler_mutex); + mutex_unlock(&id_priv->handler_mutex); + if (id_priv->cma_dev) { - mutex_unlock(&lock); switch (rdma_node_get_transport(id_priv->id.device->node_type)) { case RDMA_TRANSPORT_IB: if (id_priv->cm_id.ib && !IS_ERR(id_priv->cm_id.ib)) @@ -920,10 +929,8 @@ void rdma_destroy_id(struct rdma_cm_id *id) break; } cma_leave_mc_groups(id_priv); - mutex_lock(&lock); - cma_detach_from_dev(id_priv); + cma_release_dev(id_priv); } - mutex_unlock(&lock); cma_release_port(id_priv); cma_deref_id(id_priv); @@ -1200,9 +1207,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) } mutex_lock_nested(&conn_id->handler_mutex, SINGLE_DEPTH_NESTING); - mutex_lock(&lock); ret = cma_acquire_dev(conn_id); - mutex_unlock(&lock); if (ret) goto release_conn_id; @@ -1401,9 +1406,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, goto out; } - mutex_lock(&lock); ret = cma_acquire_dev(conn_id); - mutex_unlock(&lock); if (ret) { mutex_unlock(&conn_id->handler_mutex); rdma_destroy_id(new_cm_id); @@ -1966,20 +1969,11 @@ static void addr_handler(int status, struct sockaddr *src_addr, memset(&event, 0, sizeof event); mutex_lock(&id_priv->handler_mutex); - - /* - * Grab mutex to block rdma_destroy_id() from removing the device while - * we're trying to acquire it. - */ - mutex_lock(&lock); - if (!cma_comp_exch(id_priv, CMA_ADDR_QUERY, CMA_ADDR_RESOLVED)) { - mutex_unlock(&lock); + if (!cma_comp_exch(id_priv, CMA_ADDR_QUERY, CMA_ADDR_RESOLVED)) goto out; - } if (!status && !id_priv->cma_dev) status = cma_acquire_dev(id_priv); - mutex_unlock(&lock); if (status) { if (!cma_comp_exch(id_priv, CMA_ADDR_RESOLVED, CMA_ADDR_BOUND)) @@ -2280,9 +2274,7 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) if (ret) goto err1; - mutex_lock(&lock); ret = cma_acquire_dev(id_priv); - mutex_unlock(&lock); if (ret) goto err1; } @@ -2294,11 +2286,8 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) return 0; err2: - if (id_priv->cma_dev) { - mutex_lock(&lock); - cma_detach_from_dev(id_priv); - mutex_unlock(&lock); - } + if (id_priv->cma_dev) + cma_release_dev(id_priv); err1: cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_IDLE); return ret; -- cgit v1.2.3 From 84c0c6933cb0303fa006992a6659c2b46de4eb17 Mon Sep 17 00:00:00 2001 From: Jeongtae Park Date: Tue, 15 Mar 2011 14:52:48 -0700 Subject: smsc911x: Fix build error when SMSC_TRACE() used This patch fixes build error when SMSC_TRACE() used. Signed-off-by: Jeongtae Park Signed-off-by: David S. Miller --- drivers/net/smsc911x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index d70bde95460b..1566259c1f27 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -791,8 +791,8 @@ static int smsc911x_mii_probe(struct net_device *dev) return -ENODEV; } - SMSC_TRACE(PROBE, "PHY %d: addr %d, phy_id 0x%08X", - phy_addr, phydev->addr, phydev->phy_id); + SMSC_TRACE(PROBE, "PHY: addr %d, phy_id 0x%08X", + phydev->addr, phydev->phy_id); ret = phy_connect_direct(dev, phydev, &smsc911x_phy_adjust_link, 0, -- cgit v1.2.3 From bfd823bd74333615783d8108889814c6d82f2ab0 Mon Sep 17 00:00:00 2001 From: Sony Chacko Date: Tue, 15 Mar 2011 14:54:55 -0700 Subject: netxen: support for GbE port settings o Enable setting speed and auto negotiation parameters for GbE ports. o Hardware do not support half duplex setting currently. David Miller: Amit please update your patch to silently reject link setting attempts that are unsupported by the device. Signed-off-by: Sony Chacko Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 6 +++- drivers/net/netxen/netxen_nic_ctx.c | 15 +++++++++ drivers/net/netxen/netxen_nic_ethtool.c | 58 ++++++++------------------------- 3 files changed, 34 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index a11380544e6c..d7299f1a4940 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -739,7 +739,8 @@ struct netxen_recv_context { #define NX_CDRP_CMD_READ_PEXQ_PARAMETERS 0x0000001c #define NX_CDRP_CMD_GET_LIC_CAPABILITIES 0x0000001d #define NX_CDRP_CMD_READ_MAX_LRO_PER_BOARD 0x0000001e -#define NX_CDRP_CMD_MAX 0x0000001f +#define NX_CDRP_CMD_CONFIG_GBE_PORT 0x0000001f +#define NX_CDRP_CMD_MAX 0x00000020 #define NX_RCODE_SUCCESS 0 #define NX_RCODE_NO_HOST_MEM 1 @@ -1054,6 +1055,7 @@ typedef struct { #define NX_FW_CAPABILITY_BDG (1 << 8) #define NX_FW_CAPABILITY_FVLANTX (1 << 9) #define NX_FW_CAPABILITY_HW_LRO (1 << 10) +#define NX_FW_CAPABILITY_GBE_LINK_CFG (1 << 11) /* module types */ #define LINKEVENT_MODULE_NOT_PRESENT 1 @@ -1349,6 +1351,8 @@ void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup); void netxen_pci_camqm_read_2M(struct netxen_adapter *, u64, u64 *); void netxen_pci_camqm_write_2M(struct netxen_adapter *, u64, u64); +int nx_fw_cmd_set_gbe_port(struct netxen_adapter *adapter, + u32 speed, u32 duplex, u32 autoneg); int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu); int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable); diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index f7d06cbc70ae..f16966afa64e 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c @@ -112,6 +112,21 @@ nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu) return 0; } +int +nx_fw_cmd_set_gbe_port(struct netxen_adapter *adapter, + u32 speed, u32 duplex, u32 autoneg) +{ + + return netxen_issue_cmd(adapter, + adapter->ahw.pci_func, + NXHAL_VERSION, + speed, + duplex, + autoneg, + NX_CDRP_CMD_CONFIG_GBE_PORT); + +} + static int nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter) { diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 587498e140bb..653d308e0f5d 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -214,7 +214,6 @@ skip: check_sfp_module = netif_running(dev) && adapter->has_link_events; } else { - ecmd->autoneg = AUTONEG_ENABLE; ecmd->supported |= (SUPPORTED_TP |SUPPORTED_Autoneg); ecmd->advertising |= (ADVERTISED_TP | ADVERTISED_Autoneg); @@ -252,53 +251,24 @@ static int netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { struct netxen_adapter *adapter = netdev_priv(dev); - __u32 status; + int ret; - /* read which mode */ - if (adapter->ahw.port_type == NETXEN_NIC_GBE) { - /* autonegotiation */ - if (adapter->phy_write && - adapter->phy_write(adapter, - NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, - ecmd->autoneg) != 0) - return -EIO; - else - adapter->link_autoneg = ecmd->autoneg; + if (adapter->ahw.port_type != NETXEN_NIC_GBE) + return -EOPNOTSUPP; - if (adapter->phy_read && - adapter->phy_read(adapter, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, - &status) != 0) - return -EIO; + if (!(adapter->capabilities & NX_FW_CAPABILITY_GBE_LINK_CFG)) + return -EOPNOTSUPP; - /* speed */ - switch (ecmd->speed) { - case SPEED_10: - netxen_set_phy_speed(status, 0); - break; - case SPEED_100: - netxen_set_phy_speed(status, 1); - break; - case SPEED_1000: - netxen_set_phy_speed(status, 2); - break; - } - /* set duplex mode */ - if (ecmd->duplex == DUPLEX_HALF) - netxen_clear_phy_duplex(status); - if (ecmd->duplex == DUPLEX_FULL) - netxen_set_phy_duplex(status); - if (adapter->phy_write && - adapter->phy_write(adapter, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, - *((int *)&status)) != 0) - return -EIO; - else { - adapter->link_speed = ecmd->speed; - adapter->link_duplex = ecmd->duplex; - } - } else + ret = nx_fw_cmd_set_gbe_port(adapter, ecmd->speed, ecmd->duplex, + ecmd->autoneg); + if (ret == NX_RCODE_NOT_SUPPORTED) return -EOPNOTSUPP; + else if (ret) + return -EIO; + + adapter->link_speed = ecmd->speed; + adapter->link_duplex = ecmd->duplex; + adapter->link_autoneg = ecmd->autoneg; if (!netif_running(dev)) return 0; -- cgit v1.2.3 From 9ecb42fda614c4e4f46e95712621510f8d746980 Mon Sep 17 00:00:00 2001 From: Padmanabh Ratnakar Date: Tue, 15 Mar 2011 14:57:09 -0700 Subject: be2net: Fix UDP packet detected status in RX compl Status of UDP packet detection not getting populated in RX completion structure. This is required in csum_passed() routine. Signed-off-by: Padmanabh Ratnakar Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 3cb5f4e5a06e..5e150066a915 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1088,6 +1088,7 @@ static void be_parse_rx_compl_v1(struct be_adapter *adapter, rxcp->vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtp, compl); rxcp->err = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, err, compl); rxcp->tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, tcpf, compl); + rxcp->udpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, udpf, compl); rxcp->ip_csum = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, ipcksm, compl); rxcp->l4_csum = @@ -1113,6 +1114,7 @@ static void be_parse_rx_compl_v0(struct be_adapter *adapter, rxcp->vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtp, compl); rxcp->err = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, err, compl); rxcp->tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, tcpf, compl); + rxcp->udpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, udpf, compl); rxcp->ip_csum = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, ipcksm, compl); rxcp->l4_csum = -- cgit v1.2.3 From fd0e435b0fe85622f167b84432552885a4856ac8 Mon Sep 17 00:00:00 2001 From: Phil Oester Date: Mon, 14 Mar 2011 06:22:04 +0000 Subject: bonding: Incorrect TX queue offset When packets come in from a device with >= 16 receive queues headed out a bonding interface, syslog gets filled with this: kernel: bond0 selects TX queue 16, but real number of TX queues is 16 because queue_mapping is offset by 1. Adjust return value to account for the offset. This is a revision of my earlier patch (which did not use the skb_rx_queue_* helpers - thanks to Ben for the suggestion). Andy submitted a similar patch which emits a pr_warning on invalid queue selection, but I believe the log spew is not useful. We can revisit that question in the future, but in the interim I believe fixing the core problem is worthwhile. Signed-off-by: Phil Oester Signed-off-by: Andy Gospodarek Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 3ad4f501949e..a93d9417dc15 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4341,11 +4341,18 @@ static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb) { /* * This helper function exists to help dev_pick_tx get the correct - * destination queue. Using a helper function skips the a call to + * destination queue. Using a helper function skips a call to * skb_tx_hash and will put the skbs in the queue we expect on their * way down to the bonding driver. */ - return skb->queue_mapping; + u16 txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0; + + if (unlikely(txq >= dev->real_num_tx_queues)) { + do + txq -= dev->real_num_tx_queues; + while (txq >= dev->real_num_tx_queues); + } + return txq; } static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) -- cgit v1.2.3 From e826eafa65c6f1f7c8db5a237556cebac57ebcc5 Mon Sep 17 00:00:00 2001 From: Phil Oester Date: Mon, 14 Mar 2011 06:22:05 +0000 Subject: bonding: Call netif_carrier_off after register_netdevice Bringing up a bond interface with all network cables disconnected does not properly set the interface as DOWN because the call to netif_carrier_off occurs too early in bond_init. The call needs to occur after register_netdevice has set dev->reg_state to NETREG_REGISTERED, so that netif_carrier_off will trigger the call to linkwatch_fire_event. Signed-off-by: Phil Oester Signed-off-by: Andy Gospodarek Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index a93d9417dc15..66c98e61f0b7 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4980,8 +4980,6 @@ static int bond_init(struct net_device *bond_dev) bond_set_lockdep_class(bond_dev); - netif_carrier_off(bond_dev); - bond_create_proc_entry(bond); list_add_tail(&bond->bond_list, &bn->dev_list); @@ -5051,6 +5049,8 @@ int bond_create(struct net *net, const char *name) res = register_netdevice(bond_dev); + netif_carrier_off(bond_dev); + out: rtnl_unlock(); if (res < 0) -- cgit v1.2.3 From 5f86cad1e8224af9e3b9b43dd84b146a9ff0df87 Mon Sep 17 00:00:00 2001 From: Phil Oester Date: Mon, 14 Mar 2011 06:22:06 +0000 Subject: bonding: Improve syslog message at device creation time When the bonding module is loaded, it creates bond0 by default. Then, when attempting to create bond0, the following messages are printed to syslog: kernel: bonding: bond0 is being created... kernel: bonding: Bond creation failed. Which seems to indicate a problem, when in reality there is no problem. Since the actual error code is passed down from bond_create, make use of it to print a bit less ominous message: kernel: bonding: bond0 is being created... kernel: bond0 already exists. Signed-off-by: Phil Oester Signed-off-by: Andy Gospodarek Signed-off-by: David S. Miller --- drivers/net/bonding/bond_sysfs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 72bb0f6cc9bf..e718144c5cfa 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -118,7 +118,10 @@ static ssize_t bonding_store_bonds(struct class *cls, pr_info("%s is being created...\n", ifname); rv = bond_create(net, ifname); if (rv) { - pr_info("Bond creation failed.\n"); + if (rv == -EEXIST) + pr_info("%s already exists.\n", ifname); + else + pr_info("%s creation failed.\n", ifname); res = rv; } } else if (command[0] == '-') { -- cgit v1.2.3 From f942dc2552b8bfdee607be867b12a8971bb9cd85 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 15 Mar 2011 00:06:18 +0000 Subject: xen network backend driver netback is the host side counterpart to the frontend driver in drivers/net/xen-netfront.c. The PV protocol is also implemented by frontend drivers in other OSes too, such as the BSDs and even Windows. The patch is based on the driver from the xen.git pvops kernel tree but has been put through the checkpatch.pl wringer plus several manual cleanup passes and review iterations. The driver has been moved from drivers/xen/netback to drivers/net/xen-netback. One major change from xen.git is that the guest transmit path (i.e. what looks like receive to netback) has been significantly reworked to remove the dependency on the out of tree PageForeign page flag (a core kernel patch which enables a per page destructor callback on the final put_page). This page flag was used in order to implement a grant map based transmit path (where guest pages are mapped directly into SKB frags). Instead this version of netback uses grant copy operations into regular memory belonging to the backend domain. Reinstating the grant map functionality is something which I would like to revisit in the future. Note that this driver depends on 2e820f58f7ad "xen/irq: implement bind_interdomain_evtchn_to_irqhandler for backend drivers" which is in linux next via the "xen-two" tree and is intended for the 2.6.39 merge window: git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen.git stable/backends this branch has only that single commit since 2.6.38-rc2 and is safe for cross merging into the net branch. Signed-off-by: Ian Campbell Reviewed-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/Kconfig | 38 +- drivers/net/Makefile | 1 + drivers/net/xen-netback/Makefile | 3 + drivers/net/xen-netback/common.h | 161 ++++ drivers/net/xen-netback/interface.c | 424 +++++++++ drivers/net/xen-netback/netback.c | 1745 +++++++++++++++++++++++++++++++++++ drivers/net/xen-netback/xenbus.c | 490 ++++++++++ drivers/net/xen-netfront.c | 20 +- include/xen/interface/io/netif.h | 80 +- 9 files changed, 2908 insertions(+), 54 deletions(-) create mode 100644 drivers/net/xen-netback/Makefile create mode 100644 drivers/net/xen-netback/common.h create mode 100644 drivers/net/xen-netback/interface.c create mode 100644 drivers/net/xen-netback/netback.c create mode 100644 drivers/net/xen-netback/xenbus.c (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 46e1b1a28b80..797d68196728 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2953,12 +2953,38 @@ config XEN_NETDEV_FRONTEND select XEN_XENBUS_FRONTEND default y help - The network device frontend driver allows the kernel to - access network devices exported exported by a virtual - machine containing a physical network device driver. The - frontend driver is intended for unprivileged guest domains; - if you are compiling a kernel for a Xen guest, you almost - certainly want to enable this. + This driver provides support for Xen paravirtual network + devices exported by a Xen network driver domain (often + domain 0). + + The corresponding Linux backend driver is enabled by the + CONFIG_XEN_NETDEV_BACKEND option. + + If you are compiling a kernel for use as Xen guest, you + should say Y here. To compile this driver as a module, chose + M here: the module will be called xen-netfront. + +config XEN_NETDEV_BACKEND + tristate "Xen backend network device" + depends on XEN_BACKEND + help + This driver allows the kernel to act as a Xen network driver + domain which exports paravirtual network devices to other + Xen domains. These devices can be accessed by any operating + system that implements a compatible front end. + + The corresponding Linux frontend driver is enabled by the + CONFIG_XEN_NETDEV_FRONTEND configuration option. + + The backend driver presents a standard network device + endpoint for each paravirtual network device to the driver + domain network stack. These can then be bridged or routed + etc in order to provide full network connectivity. + + If you are compiling a kernel to run in a Xen network driver + domain (often this is domain 0) you should say Y here. To + compile this driver as a module, chose M here: the module + will be called xen-netback. config ISERIES_VETH tristate "iSeries Virtual Ethernet driver support" diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 7c2171179f97..01b604ad155e 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -172,6 +172,7 @@ obj-$(CONFIG_SLIP) += slip.o obj-$(CONFIG_SLHC) += slhc.o obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o +obj-$(CONFIG_XEN_NETDEV_BACKEND) += xen-netback/ obj-$(CONFIG_DUMMY) += dummy.o obj-$(CONFIG_IFB) += ifb.o diff --git a/drivers/net/xen-netback/Makefile b/drivers/net/xen-netback/Makefile new file mode 100644 index 000000000000..e346e8125ef5 --- /dev/null +++ b/drivers/net/xen-netback/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_XEN_NETDEV_BACKEND) := xen-netback.o + +xen-netback-y := netback.o xenbus.o interface.o diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h new file mode 100644 index 000000000000..5d7bbf2b2ee7 --- /dev/null +++ b/drivers/net/xen-netback/common.h @@ -0,0 +1,161 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef __XEN_NETBACK__COMMON_H__ +#define __XEN_NETBACK__COMMON_H__ + +#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +struct xen_netbk; + +struct xenvif { + /* Unique identifier for this interface. */ + domid_t domid; + unsigned int handle; + + /* Reference to netback processing backend. */ + struct xen_netbk *netbk; + + u8 fe_dev_addr[6]; + + /* Physical parameters of the comms window. */ + grant_handle_t tx_shmem_handle; + grant_ref_t tx_shmem_ref; + grant_handle_t rx_shmem_handle; + grant_ref_t rx_shmem_ref; + unsigned int irq; + + /* List of frontends to notify after a batch of frames sent. */ + struct list_head notify_list; + + /* The shared rings and indexes. */ + struct xen_netif_tx_back_ring tx; + struct xen_netif_rx_back_ring rx; + struct vm_struct *tx_comms_area; + struct vm_struct *rx_comms_area; + + /* Flags that must not be set in dev->features */ + u32 features_disabled; + + /* Frontend feature information. */ + u8 can_sg:1; + u8 gso:1; + u8 gso_prefix:1; + u8 csum:1; + + /* Internal feature information. */ + u8 can_queue:1; /* can queue packets for receiver? */ + + /* + * Allow xenvif_start_xmit() to peek ahead in the rx request + * ring. This is a prediction of what rx_req_cons will be + * once all queued skbs are put on the ring. + */ + RING_IDX rx_req_cons_peek; + + /* Transmit shaping: allow 'credit_bytes' every 'credit_usec'. */ + unsigned long credit_bytes; + unsigned long credit_usec; + unsigned long remaining_credit; + struct timer_list credit_timeout; + + /* Statistics */ + unsigned long rx_gso_checksum_fixup; + + /* Miscellaneous private stuff. */ + struct list_head schedule_list; + atomic_t refcnt; + struct net_device *dev; + + wait_queue_head_t waiting_to_free; +}; + +#define XEN_NETIF_TX_RING_SIZE __RING_SIZE((struct xen_netif_tx_sring *)0, PAGE_SIZE) +#define XEN_NETIF_RX_RING_SIZE __RING_SIZE((struct xen_netif_rx_sring *)0, PAGE_SIZE) + +struct xenvif *xenvif_alloc(struct device *parent, + domid_t domid, + unsigned int handle); + +int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, + unsigned long rx_ring_ref, unsigned int evtchn); +void xenvif_disconnect(struct xenvif *vif); + +void xenvif_get(struct xenvif *vif); +void xenvif_put(struct xenvif *vif); + +int xenvif_xenbus_init(void); + +int xenvif_schedulable(struct xenvif *vif); + +int xen_netbk_rx_ring_full(struct xenvif *vif); + +int xen_netbk_must_stop_queue(struct xenvif *vif); + +/* (Un)Map communication rings. */ +void xen_netbk_unmap_frontend_rings(struct xenvif *vif); +int xen_netbk_map_frontend_rings(struct xenvif *vif, + grant_ref_t tx_ring_ref, + grant_ref_t rx_ring_ref); + +/* (De)Register a xenvif with the netback backend. */ +void xen_netbk_add_xenvif(struct xenvif *vif); +void xen_netbk_remove_xenvif(struct xenvif *vif); + +/* (De)Schedule backend processing for a xenvif */ +void xen_netbk_schedule_xenvif(struct xenvif *vif); +void xen_netbk_deschedule_xenvif(struct xenvif *vif); + +/* Check for SKBs from frontend and schedule backend processing */ +void xen_netbk_check_rx_xenvif(struct xenvif *vif); +/* Receive an SKB from the frontend */ +void xenvif_receive_skb(struct xenvif *vif, struct sk_buff *skb); + +/* Queue an SKB for transmission to the frontend */ +void xen_netbk_queue_tx_skb(struct xenvif *vif, struct sk_buff *skb); +/* Notify xenvif that ring now has space to send an skb to the frontend */ +void xenvif_notify_tx_completion(struct xenvif *vif); + +/* Returns number of ring slots required to send an skb to the frontend */ +unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb); + +#endif /* __XEN_NETBACK__COMMON_H__ */ diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c new file mode 100644 index 000000000000..de569cc19da4 --- /dev/null +++ b/drivers/net/xen-netback/interface.c @@ -0,0 +1,424 @@ +/* + * Network-device interface management. + * + * Copyright (c) 2004-2005, Keir Fraser + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "common.h" + +#include +#include +#include + +#include +#include + +#define XENVIF_QUEUE_LENGTH 32 + +void xenvif_get(struct xenvif *vif) +{ + atomic_inc(&vif->refcnt); +} + +void xenvif_put(struct xenvif *vif) +{ + if (atomic_dec_and_test(&vif->refcnt)) + wake_up(&vif->waiting_to_free); +} + +int xenvif_schedulable(struct xenvif *vif) +{ + return netif_running(vif->dev) && netif_carrier_ok(vif->dev); +} + +static int xenvif_rx_schedulable(struct xenvif *vif) +{ + return xenvif_schedulable(vif) && !xen_netbk_rx_ring_full(vif); +} + +static irqreturn_t xenvif_interrupt(int irq, void *dev_id) +{ + struct xenvif *vif = dev_id; + + if (vif->netbk == NULL) + return IRQ_NONE; + + xen_netbk_schedule_xenvif(vif); + + if (xenvif_rx_schedulable(vif)) + netif_wake_queue(vif->dev); + + return IRQ_HANDLED; +} + +static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct xenvif *vif = netdev_priv(dev); + + BUG_ON(skb->dev != dev); + + if (vif->netbk == NULL) + goto drop; + + /* Drop the packet if the target domain has no receive buffers. */ + if (!xenvif_rx_schedulable(vif)) + goto drop; + + /* Reserve ring slots for the worst-case number of fragments. */ + vif->rx_req_cons_peek += xen_netbk_count_skb_slots(vif, skb); + xenvif_get(vif); + + if (vif->can_queue && xen_netbk_must_stop_queue(vif)) + netif_stop_queue(dev); + + xen_netbk_queue_tx_skb(vif, skb); + + return NETDEV_TX_OK; + + drop: + vif->dev->stats.tx_dropped++; + dev_kfree_skb(skb); + return NETDEV_TX_OK; +} + +void xenvif_receive_skb(struct xenvif *vif, struct sk_buff *skb) +{ + netif_rx_ni(skb); +} + +void xenvif_notify_tx_completion(struct xenvif *vif) +{ + if (netif_queue_stopped(vif->dev) && xenvif_rx_schedulable(vif)) + netif_wake_queue(vif->dev); +} + +static struct net_device_stats *xenvif_get_stats(struct net_device *dev) +{ + struct xenvif *vif = netdev_priv(dev); + return &vif->dev->stats; +} + +static void xenvif_up(struct xenvif *vif) +{ + xen_netbk_add_xenvif(vif); + enable_irq(vif->irq); + xen_netbk_check_rx_xenvif(vif); +} + +static void xenvif_down(struct xenvif *vif) +{ + disable_irq(vif->irq); + xen_netbk_deschedule_xenvif(vif); + xen_netbk_remove_xenvif(vif); +} + +static int xenvif_open(struct net_device *dev) +{ + struct xenvif *vif = netdev_priv(dev); + if (netif_carrier_ok(dev)) + xenvif_up(vif); + netif_start_queue(dev); + return 0; +} + +static int xenvif_close(struct net_device *dev) +{ + struct xenvif *vif = netdev_priv(dev); + if (netif_carrier_ok(dev)) + xenvif_down(vif); + netif_stop_queue(dev); + return 0; +} + +static int xenvif_change_mtu(struct net_device *dev, int mtu) +{ + struct xenvif *vif = netdev_priv(dev); + int max = vif->can_sg ? 65535 - VLAN_ETH_HLEN : ETH_DATA_LEN; + + if (mtu > max) + return -EINVAL; + dev->mtu = mtu; + return 0; +} + +static void xenvif_set_features(struct xenvif *vif) +{ + struct net_device *dev = vif->dev; + u32 features = dev->features; + + if (vif->can_sg) + features |= NETIF_F_SG; + if (vif->gso || vif->gso_prefix) + features |= NETIF_F_TSO; + if (vif->csum) + features |= NETIF_F_IP_CSUM; + + features &= ~(vif->features_disabled); + + if (!(features & NETIF_F_SG) && dev->mtu > ETH_DATA_LEN) + dev->mtu = ETH_DATA_LEN; + + dev->features = features; +} + +static int xenvif_set_tx_csum(struct net_device *dev, u32 data) +{ + struct xenvif *vif = netdev_priv(dev); + if (data) { + if (!vif->csum) + return -EOPNOTSUPP; + vif->features_disabled &= ~NETIF_F_IP_CSUM; + } else { + vif->features_disabled |= NETIF_F_IP_CSUM; + } + + xenvif_set_features(vif); + return 0; +} + +static int xenvif_set_sg(struct net_device *dev, u32 data) +{ + struct xenvif *vif = netdev_priv(dev); + if (data) { + if (!vif->can_sg) + return -EOPNOTSUPP; + vif->features_disabled &= ~NETIF_F_SG; + } else { + vif->features_disabled |= NETIF_F_SG; + } + + xenvif_set_features(vif); + return 0; +} + +static int xenvif_set_tso(struct net_device *dev, u32 data) +{ + struct xenvif *vif = netdev_priv(dev); + if (data) { + if (!vif->gso && !vif->gso_prefix) + return -EOPNOTSUPP; + vif->features_disabled &= ~NETIF_F_TSO; + } else { + vif->features_disabled |= NETIF_F_TSO; + } + + xenvif_set_features(vif); + return 0; +} + +static const struct xenvif_stat { + char name[ETH_GSTRING_LEN]; + u16 offset; +} xenvif_stats[] = { + { + "rx_gso_checksum_fixup", + offsetof(struct xenvif, rx_gso_checksum_fixup) + }, +}; + +static int xenvif_get_sset_count(struct net_device *dev, int string_set) +{ + switch (string_set) { + case ETH_SS_STATS: + return ARRAY_SIZE(xenvif_stats); + default: + return -EINVAL; + } +} + +static void xenvif_get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, u64 * data) +{ + void *vif = netdev_priv(dev); + int i; + + for (i = 0; i < ARRAY_SIZE(xenvif_stats); i++) + data[i] = *(unsigned long *)(vif + xenvif_stats[i].offset); +} + +static void xenvif_get_strings(struct net_device *dev, u32 stringset, u8 * data) +{ + int i; + + switch (stringset) { + case ETH_SS_STATS: + for (i = 0; i < ARRAY_SIZE(xenvif_stats); i++) + memcpy(data + i * ETH_GSTRING_LEN, + xenvif_stats[i].name, ETH_GSTRING_LEN); + break; + } +} + +static struct ethtool_ops xenvif_ethtool_ops = { + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = xenvif_set_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = xenvif_set_sg, + .get_tso = ethtool_op_get_tso, + .set_tso = xenvif_set_tso, + .get_link = ethtool_op_get_link, + + .get_sset_count = xenvif_get_sset_count, + .get_ethtool_stats = xenvif_get_ethtool_stats, + .get_strings = xenvif_get_strings, +}; + +static struct net_device_ops xenvif_netdev_ops = { + .ndo_start_xmit = xenvif_start_xmit, + .ndo_get_stats = xenvif_get_stats, + .ndo_open = xenvif_open, + .ndo_stop = xenvif_close, + .ndo_change_mtu = xenvif_change_mtu, +}; + +struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, + unsigned int handle) +{ + int err; + struct net_device *dev; + struct xenvif *vif; + char name[IFNAMSIZ] = {}; + + snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle); + dev = alloc_netdev(sizeof(struct xenvif), name, ether_setup); + if (dev == NULL) { + pr_warn("Could not allocate netdev\n"); + return ERR_PTR(-ENOMEM); + } + + SET_NETDEV_DEV(dev, parent); + + vif = netdev_priv(dev); + vif->domid = domid; + vif->handle = handle; + vif->netbk = NULL; + vif->can_sg = 1; + vif->csum = 1; + atomic_set(&vif->refcnt, 1); + init_waitqueue_head(&vif->waiting_to_free); + vif->dev = dev; + INIT_LIST_HEAD(&vif->schedule_list); + INIT_LIST_HEAD(&vif->notify_list); + + vif->credit_bytes = vif->remaining_credit = ~0UL; + vif->credit_usec = 0UL; + init_timer(&vif->credit_timeout); + /* Initialize 'expires' now: it's used to track the credit window. */ + vif->credit_timeout.expires = jiffies; + + dev->netdev_ops = &xenvif_netdev_ops; + xenvif_set_features(vif); + SET_ETHTOOL_OPS(dev, &xenvif_ethtool_ops); + + dev->tx_queue_len = XENVIF_QUEUE_LENGTH; + + /* + * Initialise a dummy MAC address. We choose the numerically + * largest non-broadcast address to prevent the address getting + * stolen by an Ethernet bridge for STP purposes. + * (FE:FF:FF:FF:FF:FF) + */ + memset(dev->dev_addr, 0xFF, ETH_ALEN); + dev->dev_addr[0] &= ~0x01; + + netif_carrier_off(dev); + + err = register_netdev(dev); + if (err) { + netdev_warn(dev, "Could not register device: err=%d\n", err); + free_netdev(dev); + return ERR_PTR(err); + } + + netdev_dbg(dev, "Successfully created xenvif\n"); + return vif; +} + +int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, + unsigned long rx_ring_ref, unsigned int evtchn) +{ + int err = -ENOMEM; + + /* Already connected through? */ + if (vif->irq) + return 0; + + xenvif_set_features(vif); + + err = xen_netbk_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref); + if (err < 0) + goto err; + + err = bind_interdomain_evtchn_to_irqhandler( + vif->domid, evtchn, xenvif_interrupt, 0, + vif->dev->name, vif); + if (err < 0) + goto err_unmap; + vif->irq = err; + disable_irq(vif->irq); + + xenvif_get(vif); + + rtnl_lock(); + netif_carrier_on(vif->dev); + if (netif_running(vif->dev)) + xenvif_up(vif); + rtnl_unlock(); + + return 0; +err_unmap: + xen_netbk_unmap_frontend_rings(vif); +err: + return err; +} + +void xenvif_disconnect(struct xenvif *vif) +{ + struct net_device *dev = vif->dev; + if (netif_carrier_ok(dev)) { + rtnl_lock(); + netif_carrier_off(dev); /* discard queued packets */ + if (netif_running(dev)) + xenvif_down(vif); + rtnl_unlock(); + xenvif_put(vif); + } + + atomic_dec(&vif->refcnt); + wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0); + + del_timer_sync(&vif->credit_timeout); + + if (vif->irq) + unbind_from_irqhandler(vif->irq, vif); + + unregister_netdev(vif->dev); + + xen_netbk_unmap_frontend_rings(vif); + + free_netdev(vif->dev); +} diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c new file mode 100644 index 000000000000..0e4851b8a773 --- /dev/null +++ b/drivers/net/xen-netback/netback.c @@ -0,0 +1,1745 @@ +/* + * Back-end of the driver for virtual network devices. This portion of the + * driver exports a 'unified' network-device interface that can be accessed + * by any operating system that implements a compatible front end. A + * reference front-end implementation can be found in: + * drivers/net/xen-netfront.c + * + * Copyright (c) 2002-2005, K A Fraser + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "common.h" + +#include +#include +#include + +#include + +#include +#include + +#include +#include + +struct pending_tx_info { + struct xen_netif_tx_request req; + struct xenvif *vif; +}; +typedef unsigned int pending_ring_idx_t; + +struct netbk_rx_meta { + int id; + int size; + int gso_size; +}; + +#define MAX_PENDING_REQS 256 + +#define MAX_BUFFER_OFFSET PAGE_SIZE + +/* extra field used in struct page */ +union page_ext { + struct { +#if BITS_PER_LONG < 64 +#define IDX_WIDTH 8 +#define GROUP_WIDTH (BITS_PER_LONG - IDX_WIDTH) + unsigned int group:GROUP_WIDTH; + unsigned int idx:IDX_WIDTH; +#else + unsigned int group, idx; +#endif + } e; + void *mapping; +}; + +struct xen_netbk { + wait_queue_head_t wq; + struct task_struct *task; + + struct sk_buff_head rx_queue; + struct sk_buff_head tx_queue; + + struct timer_list net_timer; + + struct page *mmap_pages[MAX_PENDING_REQS]; + + pending_ring_idx_t pending_prod; + pending_ring_idx_t pending_cons; + struct list_head net_schedule_list; + + /* Protect the net_schedule_list in netif. */ + spinlock_t net_schedule_list_lock; + + atomic_t netfront_count; + + struct pending_tx_info pending_tx_info[MAX_PENDING_REQS]; + struct gnttab_copy tx_copy_ops[MAX_PENDING_REQS]; + + u16 pending_ring[MAX_PENDING_REQS]; + + /* + * Given MAX_BUFFER_OFFSET of 4096 the worst case is that each + * head/fragment page uses 2 copy operations because it + * straddles two buffers in the frontend. + */ + struct gnttab_copy grant_copy_op[2*XEN_NETIF_RX_RING_SIZE]; + struct netbk_rx_meta meta[2*XEN_NETIF_RX_RING_SIZE]; +}; + +static struct xen_netbk *xen_netbk; +static int xen_netbk_group_nr; + +void xen_netbk_add_xenvif(struct xenvif *vif) +{ + int i; + int min_netfront_count; + int min_group = 0; + struct xen_netbk *netbk; + + min_netfront_count = atomic_read(&xen_netbk[0].netfront_count); + for (i = 0; i < xen_netbk_group_nr; i++) { + int netfront_count = atomic_read(&xen_netbk[i].netfront_count); + if (netfront_count < min_netfront_count) { + min_group = i; + min_netfront_count = netfront_count; + } + } + + netbk = &xen_netbk[min_group]; + + vif->netbk = netbk; + atomic_inc(&netbk->netfront_count); +} + +void xen_netbk_remove_xenvif(struct xenvif *vif) +{ + struct xen_netbk *netbk = vif->netbk; + vif->netbk = NULL; + atomic_dec(&netbk->netfront_count); +} + +static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx); +static void make_tx_response(struct xenvif *vif, + struct xen_netif_tx_request *txp, + s8 st); +static struct xen_netif_rx_response *make_rx_response(struct xenvif *vif, + u16 id, + s8 st, + u16 offset, + u16 size, + u16 flags); + +static inline unsigned long idx_to_pfn(struct xen_netbk *netbk, + unsigned int idx) +{ + return page_to_pfn(netbk->mmap_pages[idx]); +} + +static inline unsigned long idx_to_kaddr(struct xen_netbk *netbk, + unsigned int idx) +{ + return (unsigned long)pfn_to_kaddr(idx_to_pfn(netbk, idx)); +} + +/* extra field used in struct page */ +static inline void set_page_ext(struct page *pg, struct xen_netbk *netbk, + unsigned int idx) +{ + unsigned int group = netbk - xen_netbk; + union page_ext ext = { .e = { .group = group + 1, .idx = idx } }; + + BUILD_BUG_ON(sizeof(ext) > sizeof(ext.mapping)); + pg->mapping = ext.mapping; +} + +static int get_page_ext(struct page *pg, + unsigned int *pgroup, unsigned int *pidx) +{ + union page_ext ext = { .mapping = pg->mapping }; + struct xen_netbk *netbk; + unsigned int group, idx; + + group = ext.e.group - 1; + + if (group < 0 || group >= xen_netbk_group_nr) + return 0; + + netbk = &xen_netbk[group]; + + idx = ext.e.idx; + + if ((idx < 0) || (idx >= MAX_PENDING_REQS)) + return 0; + + if (netbk->mmap_pages[idx] != pg) + return 0; + + *pgroup = group; + *pidx = idx; + + return 1; +} + +/* + * This is the amount of packet we copy rather than map, so that the + * guest can't fiddle with the contents of the headers while we do + * packet processing on them (netfilter, routing, etc). + */ +#define PKT_PROT_LEN (ETH_HLEN + \ + VLAN_HLEN + \ + sizeof(struct iphdr) + MAX_IPOPTLEN + \ + sizeof(struct tcphdr) + MAX_TCP_OPTION_SPACE) + +static inline pending_ring_idx_t pending_index(unsigned i) +{ + return i & (MAX_PENDING_REQS-1); +} + +static inline pending_ring_idx_t nr_pending_reqs(struct xen_netbk *netbk) +{ + return MAX_PENDING_REQS - + netbk->pending_prod + netbk->pending_cons; +} + +static void xen_netbk_kick_thread(struct xen_netbk *netbk) +{ + wake_up(&netbk->wq); +} + +static int max_required_rx_slots(struct xenvif *vif) +{ + int max = DIV_ROUND_UP(vif->dev->mtu, PAGE_SIZE); + + if (vif->can_sg || vif->gso || vif->gso_prefix) + max += MAX_SKB_FRAGS + 1; /* extra_info + frags */ + + return max; +} + +int xen_netbk_rx_ring_full(struct xenvif *vif) +{ + RING_IDX peek = vif->rx_req_cons_peek; + RING_IDX needed = max_required_rx_slots(vif); + + return ((vif->rx.sring->req_prod - peek) < needed) || + ((vif->rx.rsp_prod_pvt + XEN_NETIF_RX_RING_SIZE - peek) < needed); +} + +int xen_netbk_must_stop_queue(struct xenvif *vif) +{ + if (!xen_netbk_rx_ring_full(vif)) + return 0; + + vif->rx.sring->req_event = vif->rx_req_cons_peek + + max_required_rx_slots(vif); + mb(); /* request notification /then/ check the queue */ + + return xen_netbk_rx_ring_full(vif); +} + +/* + * Returns true if we should start a new receive buffer instead of + * adding 'size' bytes to a buffer which currently contains 'offset' + * bytes. + */ +static bool start_new_rx_buffer(int offset, unsigned long size, int head) +{ + /* simple case: we have completely filled the current buffer. */ + if (offset == MAX_BUFFER_OFFSET) + return true; + + /* + * complex case: start a fresh buffer if the current frag + * would overflow the current buffer but only if: + * (i) this frag would fit completely in the next buffer + * and (ii) there is already some data in the current buffer + * and (iii) this is not the head buffer. + * + * Where: + * - (i) stops us splitting a frag into two copies + * unless the frag is too large for a single buffer. + * - (ii) stops us from leaving a buffer pointlessly empty. + * - (iii) stops us leaving the first buffer + * empty. Strictly speaking this is already covered + * by (ii) but is explicitly checked because + * netfront relies on the first buffer being + * non-empty and can crash otherwise. + * + * This means we will effectively linearise small + * frags but do not needlessly split large buffers + * into multiple copies tend to give large frags their + * own buffers as before. + */ + if ((offset + size > MAX_BUFFER_OFFSET) && + (size <= MAX_BUFFER_OFFSET) && offset && !head) + return true; + + return false; +} + +/* + * Figure out how many ring slots we're going to need to send @skb to + * the guest. This function is essentially a dry run of + * netbk_gop_frag_copy. + */ +unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb) +{ + unsigned int count; + int i, copy_off; + + count = DIV_ROUND_UP( + offset_in_page(skb->data)+skb_headlen(skb), PAGE_SIZE); + + copy_off = skb_headlen(skb) % PAGE_SIZE; + + if (skb_shinfo(skb)->gso_size) + count++; + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + unsigned long size = skb_shinfo(skb)->frags[i].size; + unsigned long bytes; + while (size > 0) { + BUG_ON(copy_off > MAX_BUFFER_OFFSET); + + if (start_new_rx_buffer(copy_off, size, 0)) { + count++; + copy_off = 0; + } + + bytes = size; + if (copy_off + bytes > MAX_BUFFER_OFFSET) + bytes = MAX_BUFFER_OFFSET - copy_off; + + copy_off += bytes; + size -= bytes; + } + } + return count; +} + +struct netrx_pending_operations { + unsigned copy_prod, copy_cons; + unsigned meta_prod, meta_cons; + struct gnttab_copy *copy; + struct netbk_rx_meta *meta; + int copy_off; + grant_ref_t copy_gref; +}; + +static struct netbk_rx_meta *get_next_rx_buffer(struct xenvif *vif, + struct netrx_pending_operations *npo) +{ + struct netbk_rx_meta *meta; + struct xen_netif_rx_request *req; + + req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++); + + meta = npo->meta + npo->meta_prod++; + meta->gso_size = 0; + meta->size = 0; + meta->id = req->id; + + npo->copy_off = 0; + npo->copy_gref = req->gref; + + return meta; +} + +/* + * Set up the grant operations for this fragment. If it's a flipping + * interface, we also set up the unmap request from here. + */ +static void netbk_gop_frag_copy(struct xenvif *vif, struct sk_buff *skb, + struct netrx_pending_operations *npo, + struct page *page, unsigned long size, + unsigned long offset, int *head) +{ + struct gnttab_copy *copy_gop; + struct netbk_rx_meta *meta; + /* + * These variables a used iff get_page_ext returns true, + * in which case they are guaranteed to be initialized. + */ + unsigned int uninitialized_var(group), uninitialized_var(idx); + int foreign = get_page_ext(page, &group, &idx); + unsigned long bytes; + + /* Data must not cross a page boundary. */ + BUG_ON(size + offset > PAGE_SIZE); + + meta = npo->meta + npo->meta_prod - 1; + + while (size > 0) { + BUG_ON(npo->copy_off > MAX_BUFFER_OFFSET); + + if (start_new_rx_buffer(npo->copy_off, size, *head)) { + /* + * Netfront requires there to be some data in the head + * buffer. + */ + BUG_ON(*head); + + meta = get_next_rx_buffer(vif, npo); + } + + bytes = size; + if (npo->copy_off + bytes > MAX_BUFFER_OFFSET) + bytes = MAX_BUFFER_OFFSET - npo->copy_off; + + copy_gop = npo->copy + npo->copy_prod++; + copy_gop->flags = GNTCOPY_dest_gref; + if (foreign) { + struct xen_netbk *netbk = &xen_netbk[group]; + struct pending_tx_info *src_pend; + + src_pend = &netbk->pending_tx_info[idx]; + + copy_gop->source.domid = src_pend->vif->domid; + copy_gop->source.u.ref = src_pend->req.gref; + copy_gop->flags |= GNTCOPY_source_gref; + } else { + void *vaddr = page_address(page); + copy_gop->source.domid = DOMID_SELF; + copy_gop->source.u.gmfn = virt_to_mfn(vaddr); + } + copy_gop->source.offset = offset; + copy_gop->dest.domid = vif->domid; + + copy_gop->dest.offset = npo->copy_off; + copy_gop->dest.u.ref = npo->copy_gref; + copy_gop->len = bytes; + + npo->copy_off += bytes; + meta->size += bytes; + + offset += bytes; + size -= bytes; + + /* Leave a gap for the GSO descriptor. */ + if (*head && skb_shinfo(skb)->gso_size && !vif->gso_prefix) + vif->rx.req_cons++; + + *head = 0; /* There must be something in this buffer now. */ + + } +} + +/* + * Prepare an SKB to be transmitted to the frontend. + * + * This function is responsible for allocating grant operations, meta + * structures, etc. + * + * It returns the number of meta structures consumed. The number of + * ring slots used is always equal to the number of meta slots used + * plus the number of GSO descriptors used. Currently, we use either + * zero GSO descriptors (for non-GSO packets) or one descriptor (for + * frontend-side LRO). + */ +static int netbk_gop_skb(struct sk_buff *skb, + struct netrx_pending_operations *npo) +{ + struct xenvif *vif = netdev_priv(skb->dev); + int nr_frags = skb_shinfo(skb)->nr_frags; + int i; + struct xen_netif_rx_request *req; + struct netbk_rx_meta *meta; + unsigned char *data; + int head = 1; + int old_meta_prod; + + old_meta_prod = npo->meta_prod; + + /* Set up a GSO prefix descriptor, if necessary */ + if (skb_shinfo(skb)->gso_size && vif->gso_prefix) { + req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++); + meta = npo->meta + npo->meta_prod++; + meta->gso_size = skb_shinfo(skb)->gso_size; + meta->size = 0; + meta->id = req->id; + } + + req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++); + meta = npo->meta + npo->meta_prod++; + + if (!vif->gso_prefix) + meta->gso_size = skb_shinfo(skb)->gso_size; + else + meta->gso_size = 0; + + meta->size = 0; + meta->id = req->id; + npo->copy_off = 0; + npo->copy_gref = req->gref; + + data = skb->data; + while (data < skb_tail_pointer(skb)) { + unsigned int offset = offset_in_page(data); + unsigned int len = PAGE_SIZE - offset; + + if (data + len > skb_tail_pointer(skb)) + len = skb_tail_pointer(skb) - data; + + netbk_gop_frag_copy(vif, skb, npo, + virt_to_page(data), len, offset, &head); + data += len; + } + + for (i = 0; i < nr_frags; i++) { + netbk_gop_frag_copy(vif, skb, npo, + skb_shinfo(skb)->frags[i].page, + skb_shinfo(skb)->frags[i].size, + skb_shinfo(skb)->frags[i].page_offset, + &head); + } + + return npo->meta_prod - old_meta_prod; +} + +/* + * This is a twin to netbk_gop_skb. Assume that netbk_gop_skb was + * used to set up the operations on the top of + * netrx_pending_operations, which have since been done. Check that + * they didn't give any errors and advance over them. + */ +static int netbk_check_gop(struct xenvif *vif, int nr_meta_slots, + struct netrx_pending_operations *npo) +{ + struct gnttab_copy *copy_op; + int status = XEN_NETIF_RSP_OKAY; + int i; + + for (i = 0; i < nr_meta_slots; i++) { + copy_op = npo->copy + npo->copy_cons++; + if (copy_op->status != GNTST_okay) { + netdev_dbg(vif->dev, + "Bad status %d from copy to DOM%d.\n", + copy_op->status, vif->domid); + status = XEN_NETIF_RSP_ERROR; + } + } + + return status; +} + +static void netbk_add_frag_responses(struct xenvif *vif, int status, + struct netbk_rx_meta *meta, + int nr_meta_slots) +{ + int i; + unsigned long offset; + + /* No fragments used */ + if (nr_meta_slots <= 1) + return; + + nr_meta_slots--; + + for (i = 0; i < nr_meta_slots; i++) { + int flags; + if (i == nr_meta_slots - 1) + flags = 0; + else + flags = XEN_NETRXF_more_data; + + offset = 0; + make_rx_response(vif, meta[i].id, status, offset, + meta[i].size, flags); + } +} + +struct skb_cb_overlay { + int meta_slots_used; +}; + +static void xen_netbk_rx_action(struct xen_netbk *netbk) +{ + struct xenvif *vif = NULL, *tmp; + s8 status; + u16 irq, flags; + struct xen_netif_rx_response *resp; + struct sk_buff_head rxq; + struct sk_buff *skb; + LIST_HEAD(notify); + int ret; + int nr_frags; + int count; + unsigned long offset; + struct skb_cb_overlay *sco; + + struct netrx_pending_operations npo = { + .copy = netbk->grant_copy_op, + .meta = netbk->meta, + }; + + skb_queue_head_init(&rxq); + + count = 0; + + while ((skb = skb_dequeue(&netbk->rx_queue)) != NULL) { + vif = netdev_priv(skb->dev); + nr_frags = skb_shinfo(skb)->nr_frags; + + sco = (struct skb_cb_overlay *)skb->cb; + sco->meta_slots_used = netbk_gop_skb(skb, &npo); + + count += nr_frags + 1; + + __skb_queue_tail(&rxq, skb); + + /* Filled the batch queue? */ + if (count + MAX_SKB_FRAGS >= XEN_NETIF_RX_RING_SIZE) + break; + } + + BUG_ON(npo.meta_prod > ARRAY_SIZE(netbk->meta)); + + if (!npo.copy_prod) + return; + + BUG_ON(npo.copy_prod > ARRAY_SIZE(netbk->grant_copy_op)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_copy, &netbk->grant_copy_op, + npo.copy_prod); + BUG_ON(ret != 0); + + while ((skb = __skb_dequeue(&rxq)) != NULL) { + sco = (struct skb_cb_overlay *)skb->cb; + + vif = netdev_priv(skb->dev); + + if (netbk->meta[npo.meta_cons].gso_size && vif->gso_prefix) { + resp = RING_GET_RESPONSE(&vif->rx, + vif->rx.rsp_prod_pvt++); + + resp->flags = XEN_NETRXF_gso_prefix | XEN_NETRXF_more_data; + + resp->offset = netbk->meta[npo.meta_cons].gso_size; + resp->id = netbk->meta[npo.meta_cons].id; + resp->status = sco->meta_slots_used; + + npo.meta_cons++; + sco->meta_slots_used--; + } + + + vif->dev->stats.tx_bytes += skb->len; + vif->dev->stats.tx_packets++; + + status = netbk_check_gop(vif, sco->meta_slots_used, &npo); + + if (sco->meta_slots_used == 1) + flags = 0; + else + flags = XEN_NETRXF_more_data; + + if (skb->ip_summed == CHECKSUM_PARTIAL) /* local packet? */ + flags |= XEN_NETRXF_csum_blank | XEN_NETRXF_data_validated; + else if (skb->ip_summed == CHECKSUM_UNNECESSARY) + /* remote but checksummed. */ + flags |= XEN_NETRXF_data_validated; + + offset = 0; + resp = make_rx_response(vif, netbk->meta[npo.meta_cons].id, + status, offset, + netbk->meta[npo.meta_cons].size, + flags); + + if (netbk->meta[npo.meta_cons].gso_size && !vif->gso_prefix) { + struct xen_netif_extra_info *gso = + (struct xen_netif_extra_info *) + RING_GET_RESPONSE(&vif->rx, + vif->rx.rsp_prod_pvt++); + + resp->flags |= XEN_NETRXF_extra_info; + + gso->u.gso.size = netbk->meta[npo.meta_cons].gso_size; + gso->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4; + gso->u.gso.pad = 0; + gso->u.gso.features = 0; + + gso->type = XEN_NETIF_EXTRA_TYPE_GSO; + gso->flags = 0; + } + + netbk_add_frag_responses(vif, status, + netbk->meta + npo.meta_cons + 1, + sco->meta_slots_used); + + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&vif->rx, ret); + irq = vif->irq; + if (ret && list_empty(&vif->notify_list)) + list_add_tail(&vif->notify_list, ¬ify); + + xenvif_notify_tx_completion(vif); + + xenvif_put(vif); + npo.meta_cons += sco->meta_slots_used; + dev_kfree_skb(skb); + } + + list_for_each_entry_safe(vif, tmp, ¬ify, notify_list) { + notify_remote_via_irq(vif->irq); + list_del_init(&vif->notify_list); + } + + /* More work to do? */ + if (!skb_queue_empty(&netbk->rx_queue) && + !timer_pending(&netbk->net_timer)) + xen_netbk_kick_thread(netbk); +} + +void xen_netbk_queue_tx_skb(struct xenvif *vif, struct sk_buff *skb) +{ + struct xen_netbk *netbk = vif->netbk; + + skb_queue_tail(&netbk->rx_queue, skb); + + xen_netbk_kick_thread(netbk); +} + +static void xen_netbk_alarm(unsigned long data) +{ + struct xen_netbk *netbk = (struct xen_netbk *)data; + xen_netbk_kick_thread(netbk); +} + +static int __on_net_schedule_list(struct xenvif *vif) +{ + return !list_empty(&vif->schedule_list); +} + +/* Must be called with net_schedule_list_lock held */ +static void remove_from_net_schedule_list(struct xenvif *vif) +{ + if (likely(__on_net_schedule_list(vif))) { + list_del_init(&vif->schedule_list); + xenvif_put(vif); + } +} + +static struct xenvif *poll_net_schedule_list(struct xen_netbk *netbk) +{ + struct xenvif *vif = NULL; + + spin_lock_irq(&netbk->net_schedule_list_lock); + if (list_empty(&netbk->net_schedule_list)) + goto out; + + vif = list_first_entry(&netbk->net_schedule_list, + struct xenvif, schedule_list); + if (!vif) + goto out; + + xenvif_get(vif); + + remove_from_net_schedule_list(vif); +out: + spin_unlock_irq(&netbk->net_schedule_list_lock); + return vif; +} + +void xen_netbk_schedule_xenvif(struct xenvif *vif) +{ + unsigned long flags; + struct xen_netbk *netbk = vif->netbk; + + if (__on_net_schedule_list(vif)) + goto kick; + + spin_lock_irqsave(&netbk->net_schedule_list_lock, flags); + if (!__on_net_schedule_list(vif) && + likely(xenvif_schedulable(vif))) { + list_add_tail(&vif->schedule_list, &netbk->net_schedule_list); + xenvif_get(vif); + } + spin_unlock_irqrestore(&netbk->net_schedule_list_lock, flags); + +kick: + smp_mb(); + if ((nr_pending_reqs(netbk) < (MAX_PENDING_REQS/2)) && + !list_empty(&netbk->net_schedule_list)) + xen_netbk_kick_thread(netbk); +} + +void xen_netbk_deschedule_xenvif(struct xenvif *vif) +{ + struct xen_netbk *netbk = vif->netbk; + spin_lock_irq(&netbk->net_schedule_list_lock); + remove_from_net_schedule_list(vif); + spin_unlock_irq(&netbk->net_schedule_list_lock); +} + +void xen_netbk_check_rx_xenvif(struct xenvif *vif) +{ + int more_to_do; + + RING_FINAL_CHECK_FOR_REQUESTS(&vif->tx, more_to_do); + + if (more_to_do) + xen_netbk_schedule_xenvif(vif); +} + +static void tx_add_credit(struct xenvif *vif) +{ + unsigned long max_burst, max_credit; + + /* + * Allow a burst big enough to transmit a jumbo packet of up to 128kB. + * Otherwise the interface can seize up due to insufficient credit. + */ + max_burst = RING_GET_REQUEST(&vif->tx, vif->tx.req_cons)->size; + max_burst = min(max_burst, 131072UL); + max_burst = max(max_burst, vif->credit_bytes); + + /* Take care that adding a new chunk of credit doesn't wrap to zero. */ + max_credit = vif->remaining_credit + vif->credit_bytes; + if (max_credit < vif->remaining_credit) + max_credit = ULONG_MAX; /* wrapped: clamp to ULONG_MAX */ + + vif->remaining_credit = min(max_credit, max_burst); +} + +static void tx_credit_callback(unsigned long data) +{ + struct xenvif *vif = (struct xenvif *)data; + tx_add_credit(vif); + xen_netbk_check_rx_xenvif(vif); +} + +static void netbk_tx_err(struct xenvif *vif, + struct xen_netif_tx_request *txp, RING_IDX end) +{ + RING_IDX cons = vif->tx.req_cons; + + do { + make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR); + if (cons >= end) + break; + txp = RING_GET_REQUEST(&vif->tx, cons++); + } while (1); + vif->tx.req_cons = cons; + xen_netbk_check_rx_xenvif(vif); + xenvif_put(vif); +} + +static int netbk_count_requests(struct xenvif *vif, + struct xen_netif_tx_request *first, + struct xen_netif_tx_request *txp, + int work_to_do) +{ + RING_IDX cons = vif->tx.req_cons; + int frags = 0; + + if (!(first->flags & XEN_NETTXF_more_data)) + return 0; + + do { + if (frags >= work_to_do) { + netdev_dbg(vif->dev, "Need more frags\n"); + return -frags; + } + + if (unlikely(frags >= MAX_SKB_FRAGS)) { + netdev_dbg(vif->dev, "Too many frags\n"); + return -frags; + } + + memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + frags), + sizeof(*txp)); + if (txp->size > first->size) { + netdev_dbg(vif->dev, "Frags galore\n"); + return -frags; + } + + first->size -= txp->size; + frags++; + + if (unlikely((txp->offset + txp->size) > PAGE_SIZE)) { + netdev_dbg(vif->dev, "txp->offset: %x, size: %u\n", + txp->offset, txp->size); + return -frags; + } + } while ((txp++)->flags & XEN_NETTXF_more_data); + return frags; +} + +static struct page *xen_netbk_alloc_page(struct xen_netbk *netbk, + struct sk_buff *skb, + unsigned long pending_idx) +{ + struct page *page; + page = alloc_page(GFP_KERNEL|__GFP_COLD); + if (!page) + return NULL; + set_page_ext(page, netbk, pending_idx); + netbk->mmap_pages[pending_idx] = page; + return page; +} + +static struct gnttab_copy *xen_netbk_get_requests(struct xen_netbk *netbk, + struct xenvif *vif, + struct sk_buff *skb, + struct xen_netif_tx_request *txp, + struct gnttab_copy *gop) +{ + struct skb_shared_info *shinfo = skb_shinfo(skb); + skb_frag_t *frags = shinfo->frags; + unsigned long pending_idx = *((u16 *)skb->data); + int i, start; + + /* Skip first skb fragment if it is on same page as header fragment. */ + start = ((unsigned long)shinfo->frags[0].page == pending_idx); + + for (i = start; i < shinfo->nr_frags; i++, txp++) { + struct page *page; + pending_ring_idx_t index; + struct pending_tx_info *pending_tx_info = + netbk->pending_tx_info; + + index = pending_index(netbk->pending_cons++); + pending_idx = netbk->pending_ring[index]; + page = xen_netbk_alloc_page(netbk, skb, pending_idx); + if (!page) + return NULL; + + netbk->mmap_pages[pending_idx] = page; + + gop->source.u.ref = txp->gref; + gop->source.domid = vif->domid; + gop->source.offset = txp->offset; + + gop->dest.u.gmfn = virt_to_mfn(page_address(page)); + gop->dest.domid = DOMID_SELF; + gop->dest.offset = txp->offset; + + gop->len = txp->size; + gop->flags = GNTCOPY_source_gref; + + gop++; + + memcpy(&pending_tx_info[pending_idx].req, txp, sizeof(*txp)); + xenvif_get(vif); + pending_tx_info[pending_idx].vif = vif; + frags[i].page = (void *)pending_idx; + } + + return gop; +} + +static int xen_netbk_tx_check_gop(struct xen_netbk *netbk, + struct sk_buff *skb, + struct gnttab_copy **gopp) +{ + struct gnttab_copy *gop = *gopp; + int pending_idx = *((u16 *)skb->data); + struct pending_tx_info *pending_tx_info = netbk->pending_tx_info; + struct xenvif *vif = pending_tx_info[pending_idx].vif; + struct xen_netif_tx_request *txp; + struct skb_shared_info *shinfo = skb_shinfo(skb); + int nr_frags = shinfo->nr_frags; + int i, err, start; + + /* Check status of header. */ + err = gop->status; + if (unlikely(err)) { + pending_ring_idx_t index; + index = pending_index(netbk->pending_prod++); + txp = &pending_tx_info[pending_idx].req; + make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR); + netbk->pending_ring[index] = pending_idx; + xenvif_put(vif); + } + + /* Skip first skb fragment if it is on same page as header fragment. */ + start = ((unsigned long)shinfo->frags[0].page == pending_idx); + + for (i = start; i < nr_frags; i++) { + int j, newerr; + pending_ring_idx_t index; + + pending_idx = (unsigned long)shinfo->frags[i].page; + + /* Check error status: if okay then remember grant handle. */ + newerr = (++gop)->status; + if (likely(!newerr)) { + /* Had a previous error? Invalidate this fragment. */ + if (unlikely(err)) + xen_netbk_idx_release(netbk, pending_idx); + continue; + } + + /* Error on this fragment: respond to client with an error. */ + txp = &netbk->pending_tx_info[pending_idx].req; + make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR); + index = pending_index(netbk->pending_prod++); + netbk->pending_ring[index] = pending_idx; + xenvif_put(vif); + + /* Not the first error? Preceding frags already invalidated. */ + if (err) + continue; + + /* First error: invalidate header and preceding fragments. */ + pending_idx = *((u16 *)skb->data); + xen_netbk_idx_release(netbk, pending_idx); + for (j = start; j < i; j++) { + pending_idx = (unsigned long)shinfo->frags[i].page; + xen_netbk_idx_release(netbk, pending_idx); + } + + /* Remember the error: invalidate all subsequent fragments. */ + err = newerr; + } + + *gopp = gop + 1; + return err; +} + +static void xen_netbk_fill_frags(struct xen_netbk *netbk, struct sk_buff *skb) +{ + struct skb_shared_info *shinfo = skb_shinfo(skb); + int nr_frags = shinfo->nr_frags; + int i; + + for (i = 0; i < nr_frags; i++) { + skb_frag_t *frag = shinfo->frags + i; + struct xen_netif_tx_request *txp; + unsigned long pending_idx; + + pending_idx = (unsigned long)frag->page; + + txp = &netbk->pending_tx_info[pending_idx].req; + frag->page = virt_to_page(idx_to_kaddr(netbk, pending_idx)); + frag->size = txp->size; + frag->page_offset = txp->offset; + + skb->len += txp->size; + skb->data_len += txp->size; + skb->truesize += txp->size; + + /* Take an extra reference to offset xen_netbk_idx_release */ + get_page(netbk->mmap_pages[pending_idx]); + xen_netbk_idx_release(netbk, pending_idx); + } +} + +static int xen_netbk_get_extras(struct xenvif *vif, + struct xen_netif_extra_info *extras, + int work_to_do) +{ + struct xen_netif_extra_info extra; + RING_IDX cons = vif->tx.req_cons; + + do { + if (unlikely(work_to_do-- <= 0)) { + netdev_dbg(vif->dev, "Missing extra info\n"); + return -EBADR; + } + + memcpy(&extra, RING_GET_REQUEST(&vif->tx, cons), + sizeof(extra)); + if (unlikely(!extra.type || + extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) { + vif->tx.req_cons = ++cons; + netdev_dbg(vif->dev, + "Invalid extra type: %d\n", extra.type); + return -EINVAL; + } + + memcpy(&extras[extra.type - 1], &extra, sizeof(extra)); + vif->tx.req_cons = ++cons; + } while (extra.flags & XEN_NETIF_EXTRA_FLAG_MORE); + + return work_to_do; +} + +static int netbk_set_skb_gso(struct xenvif *vif, + struct sk_buff *skb, + struct xen_netif_extra_info *gso) +{ + if (!gso->u.gso.size) { + netdev_dbg(vif->dev, "GSO size must not be zero.\n"); + return -EINVAL; + } + + /* Currently only TCPv4 S.O. is supported. */ + if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) { + netdev_dbg(vif->dev, "Bad GSO type %d.\n", gso->u.gso.type); + return -EINVAL; + } + + skb_shinfo(skb)->gso_size = gso->u.gso.size; + skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; + + /* Header must be checked, and gso_segs computed. */ + skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; + skb_shinfo(skb)->gso_segs = 0; + + return 0; +} + +static int checksum_setup(struct xenvif *vif, struct sk_buff *skb) +{ + struct iphdr *iph; + unsigned char *th; + int err = -EPROTO; + int recalculate_partial_csum = 0; + + /* + * A GSO SKB must be CHECKSUM_PARTIAL. However some buggy + * peers can fail to set NETRXF_csum_blank when sending a GSO + * frame. In this case force the SKB to CHECKSUM_PARTIAL and + * recalculate the partial checksum. + */ + if (skb->ip_summed != CHECKSUM_PARTIAL && skb_is_gso(skb)) { + vif->rx_gso_checksum_fixup++; + skb->ip_summed = CHECKSUM_PARTIAL; + recalculate_partial_csum = 1; + } + + /* A non-CHECKSUM_PARTIAL SKB does not require setup. */ + if (skb->ip_summed != CHECKSUM_PARTIAL) + return 0; + + if (skb->protocol != htons(ETH_P_IP)) + goto out; + + iph = (void *)skb->data; + th = skb->data + 4 * iph->ihl; + if (th >= skb_tail_pointer(skb)) + goto out; + + skb->csum_start = th - skb->head; + switch (iph->protocol) { + case IPPROTO_TCP: + skb->csum_offset = offsetof(struct tcphdr, check); + + if (recalculate_partial_csum) { + struct tcphdr *tcph = (struct tcphdr *)th; + tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, + skb->len - iph->ihl*4, + IPPROTO_TCP, 0); + } + break; + case IPPROTO_UDP: + skb->csum_offset = offsetof(struct udphdr, check); + + if (recalculate_partial_csum) { + struct udphdr *udph = (struct udphdr *)th; + udph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, + skb->len - iph->ihl*4, + IPPROTO_UDP, 0); + } + break; + default: + if (net_ratelimit()) + netdev_err(vif->dev, + "Attempting to checksum a non-TCP/UDP packet, dropping a protocol %d packet\n", + iph->protocol); + goto out; + } + + if ((th + skb->csum_offset + 2) > skb_tail_pointer(skb)) + goto out; + + err = 0; + +out: + return err; +} + +static bool tx_credit_exceeded(struct xenvif *vif, unsigned size) +{ + unsigned long now = jiffies; + unsigned long next_credit = + vif->credit_timeout.expires + + msecs_to_jiffies(vif->credit_usec / 1000); + + /* Timer could already be pending in rare cases. */ + if (timer_pending(&vif->credit_timeout)) + return true; + + /* Passed the point where we can replenish credit? */ + if (time_after_eq(now, next_credit)) { + vif->credit_timeout.expires = now; + tx_add_credit(vif); + } + + /* Still too big to send right now? Set a callback. */ + if (size > vif->remaining_credit) { + vif->credit_timeout.data = + (unsigned long)vif; + vif->credit_timeout.function = + tx_credit_callback; + mod_timer(&vif->credit_timeout, + next_credit); + + return true; + } + + return false; +} + +static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk) +{ + struct gnttab_copy *gop = netbk->tx_copy_ops, *request_gop; + struct sk_buff *skb; + int ret; + + while (((nr_pending_reqs(netbk) + MAX_SKB_FRAGS) < MAX_PENDING_REQS) && + !list_empty(&netbk->net_schedule_list)) { + struct xenvif *vif; + struct xen_netif_tx_request txreq; + struct xen_netif_tx_request txfrags[MAX_SKB_FRAGS]; + struct page *page; + struct xen_netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX-1]; + u16 pending_idx; + RING_IDX idx; + int work_to_do; + unsigned int data_len; + pending_ring_idx_t index; + + /* Get a netif from the list with work to do. */ + vif = poll_net_schedule_list(netbk); + if (!vif) + continue; + + RING_FINAL_CHECK_FOR_REQUESTS(&vif->tx, work_to_do); + if (!work_to_do) { + xenvif_put(vif); + continue; + } + + idx = vif->tx.req_cons; + rmb(); /* Ensure that we see the request before we copy it. */ + memcpy(&txreq, RING_GET_REQUEST(&vif->tx, idx), sizeof(txreq)); + + /* Credit-based scheduling. */ + if (txreq.size > vif->remaining_credit && + tx_credit_exceeded(vif, txreq.size)) { + xenvif_put(vif); + continue; + } + + vif->remaining_credit -= txreq.size; + + work_to_do--; + vif->tx.req_cons = ++idx; + + memset(extras, 0, sizeof(extras)); + if (txreq.flags & XEN_NETTXF_extra_info) { + work_to_do = xen_netbk_get_extras(vif, extras, + work_to_do); + idx = vif->tx.req_cons; + if (unlikely(work_to_do < 0)) { + netbk_tx_err(vif, &txreq, idx); + continue; + } + } + + ret = netbk_count_requests(vif, &txreq, txfrags, work_to_do); + if (unlikely(ret < 0)) { + netbk_tx_err(vif, &txreq, idx - ret); + continue; + } + idx += ret; + + if (unlikely(txreq.size < ETH_HLEN)) { + netdev_dbg(vif->dev, + "Bad packet size: %d\n", txreq.size); + netbk_tx_err(vif, &txreq, idx); + continue; + } + + /* No crossing a page as the payload mustn't fragment. */ + if (unlikely((txreq.offset + txreq.size) > PAGE_SIZE)) { + netdev_dbg(vif->dev, + "txreq.offset: %x, size: %u, end: %lu\n", + txreq.offset, txreq.size, + (txreq.offset&~PAGE_MASK) + txreq.size); + netbk_tx_err(vif, &txreq, idx); + continue; + } + + index = pending_index(netbk->pending_cons); + pending_idx = netbk->pending_ring[index]; + + data_len = (txreq.size > PKT_PROT_LEN && + ret < MAX_SKB_FRAGS) ? + PKT_PROT_LEN : txreq.size; + + skb = alloc_skb(data_len + NET_SKB_PAD + NET_IP_ALIGN, + GFP_ATOMIC | __GFP_NOWARN); + if (unlikely(skb == NULL)) { + netdev_dbg(vif->dev, + "Can't allocate a skb in start_xmit.\n"); + netbk_tx_err(vif, &txreq, idx); + break; + } + + /* Packets passed to netif_rx() must have some headroom. */ + skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN); + + if (extras[XEN_NETIF_EXTRA_TYPE_GSO - 1].type) { + struct xen_netif_extra_info *gso; + gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1]; + + if (netbk_set_skb_gso(vif, skb, gso)) { + kfree_skb(skb); + netbk_tx_err(vif, &txreq, idx); + continue; + } + } + + /* XXX could copy straight to head */ + page = xen_netbk_alloc_page(netbk, skb, pending_idx); + if (!page) { + kfree_skb(skb); + netbk_tx_err(vif, &txreq, idx); + continue; + } + + netbk->mmap_pages[pending_idx] = page; + + gop->source.u.ref = txreq.gref; + gop->source.domid = vif->domid; + gop->source.offset = txreq.offset; + + gop->dest.u.gmfn = virt_to_mfn(page_address(page)); + gop->dest.domid = DOMID_SELF; + gop->dest.offset = txreq.offset; + + gop->len = txreq.size; + gop->flags = GNTCOPY_source_gref; + + gop++; + + memcpy(&netbk->pending_tx_info[pending_idx].req, + &txreq, sizeof(txreq)); + netbk->pending_tx_info[pending_idx].vif = vif; + *((u16 *)skb->data) = pending_idx; + + __skb_put(skb, data_len); + + skb_shinfo(skb)->nr_frags = ret; + if (data_len < txreq.size) { + skb_shinfo(skb)->nr_frags++; + skb_shinfo(skb)->frags[0].page = + (void *)(unsigned long)pending_idx; + } else { + /* Discriminate from any valid pending_idx value. */ + skb_shinfo(skb)->frags[0].page = (void *)~0UL; + } + + __skb_queue_tail(&netbk->tx_queue, skb); + + netbk->pending_cons++; + + request_gop = xen_netbk_get_requests(netbk, vif, + skb, txfrags, gop); + if (request_gop == NULL) { + kfree_skb(skb); + netbk_tx_err(vif, &txreq, idx); + continue; + } + gop = request_gop; + + vif->tx.req_cons = idx; + xen_netbk_check_rx_xenvif(vif); + + if ((gop-netbk->tx_copy_ops) >= ARRAY_SIZE(netbk->tx_copy_ops)) + break; + } + + return gop - netbk->tx_copy_ops; +} + +static void xen_netbk_tx_submit(struct xen_netbk *netbk) +{ + struct gnttab_copy *gop = netbk->tx_copy_ops; + struct sk_buff *skb; + + while ((skb = __skb_dequeue(&netbk->tx_queue)) != NULL) { + struct xen_netif_tx_request *txp; + struct xenvif *vif; + u16 pending_idx; + unsigned data_len; + + pending_idx = *((u16 *)skb->data); + vif = netbk->pending_tx_info[pending_idx].vif; + txp = &netbk->pending_tx_info[pending_idx].req; + + /* Check the remap error code. */ + if (unlikely(xen_netbk_tx_check_gop(netbk, skb, &gop))) { + netdev_dbg(vif->dev, "netback grant failed.\n"); + skb_shinfo(skb)->nr_frags = 0; + kfree_skb(skb); + continue; + } + + data_len = skb->len; + memcpy(skb->data, + (void *)(idx_to_kaddr(netbk, pending_idx)|txp->offset), + data_len); + if (data_len < txp->size) { + /* Append the packet payload as a fragment. */ + txp->offset += data_len; + txp->size -= data_len; + } else { + /* Schedule a response immediately. */ + xen_netbk_idx_release(netbk, pending_idx); + } + + if (txp->flags & XEN_NETTXF_csum_blank) + skb->ip_summed = CHECKSUM_PARTIAL; + else if (txp->flags & XEN_NETTXF_data_validated) + skb->ip_summed = CHECKSUM_UNNECESSARY; + + xen_netbk_fill_frags(netbk, skb); + + /* + * If the initial fragment was < PKT_PROT_LEN then + * pull through some bytes from the other fragments to + * increase the linear region to PKT_PROT_LEN bytes. + */ + if (skb_headlen(skb) < PKT_PROT_LEN && skb_is_nonlinear(skb)) { + int target = min_t(int, skb->len, PKT_PROT_LEN); + __pskb_pull_tail(skb, target - skb_headlen(skb)); + } + + skb->dev = vif->dev; + skb->protocol = eth_type_trans(skb, skb->dev); + + if (checksum_setup(vif, skb)) { + netdev_dbg(vif->dev, + "Can't setup checksum in net_tx_action\n"); + kfree_skb(skb); + continue; + } + + vif->dev->stats.rx_bytes += skb->len; + vif->dev->stats.rx_packets++; + + xenvif_receive_skb(vif, skb); + } +} + +/* Called after netfront has transmitted */ +static void xen_netbk_tx_action(struct xen_netbk *netbk) +{ + unsigned nr_gops; + int ret; + + nr_gops = xen_netbk_tx_build_gops(netbk); + + if (nr_gops == 0) + return; + ret = HYPERVISOR_grant_table_op(GNTTABOP_copy, + netbk->tx_copy_ops, nr_gops); + BUG_ON(ret); + + xen_netbk_tx_submit(netbk); + +} + +static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx) +{ + struct xenvif *vif; + struct pending_tx_info *pending_tx_info; + pending_ring_idx_t index; + + /* Already complete? */ + if (netbk->mmap_pages[pending_idx] == NULL) + return; + + pending_tx_info = &netbk->pending_tx_info[pending_idx]; + + vif = pending_tx_info->vif; + + make_tx_response(vif, &pending_tx_info->req, XEN_NETIF_RSP_OKAY); + + index = pending_index(netbk->pending_prod++); + netbk->pending_ring[index] = pending_idx; + + xenvif_put(vif); + + netbk->mmap_pages[pending_idx]->mapping = 0; + put_page(netbk->mmap_pages[pending_idx]); + netbk->mmap_pages[pending_idx] = NULL; +} + +static void make_tx_response(struct xenvif *vif, + struct xen_netif_tx_request *txp, + s8 st) +{ + RING_IDX i = vif->tx.rsp_prod_pvt; + struct xen_netif_tx_response *resp; + int notify; + + resp = RING_GET_RESPONSE(&vif->tx, i); + resp->id = txp->id; + resp->status = st; + + if (txp->flags & XEN_NETTXF_extra_info) + RING_GET_RESPONSE(&vif->tx, ++i)->status = XEN_NETIF_RSP_NULL; + + vif->tx.rsp_prod_pvt = ++i; + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&vif->tx, notify); + if (notify) + notify_remote_via_irq(vif->irq); +} + +static struct xen_netif_rx_response *make_rx_response(struct xenvif *vif, + u16 id, + s8 st, + u16 offset, + u16 size, + u16 flags) +{ + RING_IDX i = vif->rx.rsp_prod_pvt; + struct xen_netif_rx_response *resp; + + resp = RING_GET_RESPONSE(&vif->rx, i); + resp->offset = offset; + resp->flags = flags; + resp->id = id; + resp->status = (s16)size; + if (st < 0) + resp->status = (s16)st; + + vif->rx.rsp_prod_pvt = ++i; + + return resp; +} + +static inline int rx_work_todo(struct xen_netbk *netbk) +{ + return !skb_queue_empty(&netbk->rx_queue); +} + +static inline int tx_work_todo(struct xen_netbk *netbk) +{ + + if (((nr_pending_reqs(netbk) + MAX_SKB_FRAGS) < MAX_PENDING_REQS) && + !list_empty(&netbk->net_schedule_list)) + return 1; + + return 0; +} + +static int xen_netbk_kthread(void *data) +{ + struct xen_netbk *netbk = data; + while (!kthread_should_stop()) { + wait_event_interruptible(netbk->wq, + rx_work_todo(netbk) || + tx_work_todo(netbk) || + kthread_should_stop()); + cond_resched(); + + if (kthread_should_stop()) + break; + + if (rx_work_todo(netbk)) + xen_netbk_rx_action(netbk); + + if (tx_work_todo(netbk)) + xen_netbk_tx_action(netbk); + } + + return 0; +} + +void xen_netbk_unmap_frontend_rings(struct xenvif *vif) +{ + struct gnttab_unmap_grant_ref op; + + if (vif->tx.sring) { + gnttab_set_unmap_op(&op, (unsigned long)vif->tx_comms_area->addr, + GNTMAP_host_map, vif->tx_shmem_handle); + + if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)) + BUG(); + } + + if (vif->rx.sring) { + gnttab_set_unmap_op(&op, (unsigned long)vif->rx_comms_area->addr, + GNTMAP_host_map, vif->rx_shmem_handle); + + if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)) + BUG(); + } + if (vif->rx_comms_area) + free_vm_area(vif->rx_comms_area); + if (vif->tx_comms_area) + free_vm_area(vif->tx_comms_area); +} + +int xen_netbk_map_frontend_rings(struct xenvif *vif, + grant_ref_t tx_ring_ref, + grant_ref_t rx_ring_ref) +{ + struct gnttab_map_grant_ref op; + struct xen_netif_tx_sring *txs; + struct xen_netif_rx_sring *rxs; + + int err = -ENOMEM; + + vif->tx_comms_area = alloc_vm_area(PAGE_SIZE); + if (vif->tx_comms_area == NULL) + goto err; + + vif->rx_comms_area = alloc_vm_area(PAGE_SIZE); + if (vif->rx_comms_area == NULL) + goto err; + + gnttab_set_map_op(&op, (unsigned long)vif->tx_comms_area->addr, + GNTMAP_host_map, tx_ring_ref, vif->domid); + + if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)) + BUG(); + + if (op.status) { + netdev_warn(vif->dev, + "failed to map tx ring. err=%d status=%d\n", + err, op.status); + err = op.status; + goto err; + } + + vif->tx_shmem_ref = tx_ring_ref; + vif->tx_shmem_handle = op.handle; + + txs = (struct xen_netif_tx_sring *)vif->tx_comms_area->addr; + BACK_RING_INIT(&vif->tx, txs, PAGE_SIZE); + + gnttab_set_map_op(&op, (unsigned long)vif->rx_comms_area->addr, + GNTMAP_host_map, rx_ring_ref, vif->domid); + + if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)) + BUG(); + + if (op.status) { + netdev_warn(vif->dev, + "failed to map rx ring. err=%d status=%d\n", + err, op.status); + err = op.status; + goto err; + } + + vif->rx_shmem_ref = rx_ring_ref; + vif->rx_shmem_handle = op.handle; + vif->rx_req_cons_peek = 0; + + rxs = (struct xen_netif_rx_sring *)vif->rx_comms_area->addr; + BACK_RING_INIT(&vif->rx, rxs, PAGE_SIZE); + + return 0; + +err: + xen_netbk_unmap_frontend_rings(vif); + return err; +} + +static int __init netback_init(void) +{ + int i; + int rc = 0; + int group; + + if (!xen_pv_domain()) + return -ENODEV; + + xen_netbk_group_nr = num_online_cpus(); + xen_netbk = vzalloc(sizeof(struct xen_netbk) * xen_netbk_group_nr); + if (!xen_netbk) { + printk(KERN_ALERT "%s: out of memory\n", __func__); + return -ENOMEM; + } + + for (group = 0; group < xen_netbk_group_nr; group++) { + struct xen_netbk *netbk = &xen_netbk[group]; + skb_queue_head_init(&netbk->rx_queue); + skb_queue_head_init(&netbk->tx_queue); + + init_timer(&netbk->net_timer); + netbk->net_timer.data = (unsigned long)netbk; + netbk->net_timer.function = xen_netbk_alarm; + + netbk->pending_cons = 0; + netbk->pending_prod = MAX_PENDING_REQS; + for (i = 0; i < MAX_PENDING_REQS; i++) + netbk->pending_ring[i] = i; + + init_waitqueue_head(&netbk->wq); + netbk->task = kthread_create(xen_netbk_kthread, + (void *)netbk, + "netback/%u", group); + + if (IS_ERR(netbk->task)) { + printk(KERN_ALERT "kthread_run() fails at netback\n"); + del_timer(&netbk->net_timer); + rc = PTR_ERR(netbk->task); + goto failed_init; + } + + kthread_bind(netbk->task, group); + + INIT_LIST_HEAD(&netbk->net_schedule_list); + + spin_lock_init(&netbk->net_schedule_list_lock); + + atomic_set(&netbk->netfront_count, 0); + + wake_up_process(netbk->task); + } + + rc = xenvif_xenbus_init(); + if (rc) + goto failed_init; + + return 0; + +failed_init: + while (--group >= 0) { + struct xen_netbk *netbk = &xen_netbk[group]; + for (i = 0; i < MAX_PENDING_REQS; i++) { + if (netbk->mmap_pages[i]) + __free_page(netbk->mmap_pages[i]); + } + del_timer(&netbk->net_timer); + kthread_stop(netbk->task); + } + vfree(xen_netbk); + return rc; + +} + +module_init(netback_init); + +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c new file mode 100644 index 000000000000..22b8c3505991 --- /dev/null +++ b/drivers/net/xen-netback/xenbus.c @@ -0,0 +1,490 @@ +/* + * Xenbus code for netif backend + * + * Copyright (C) 2005 Rusty Russell + * Copyright (C) 2005 XenSource Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "common.h" + +struct backend_info { + struct xenbus_device *dev; + struct xenvif *vif; + enum xenbus_state frontend_state; + struct xenbus_watch hotplug_status_watch; + int have_hotplug_status_watch:1; +}; + +static int connect_rings(struct backend_info *); +static void connect(struct backend_info *); +static void backend_create_xenvif(struct backend_info *be); +static void unregister_hotplug_status_watch(struct backend_info *be); + +static int netback_remove(struct xenbus_device *dev) +{ + struct backend_info *be = dev_get_drvdata(&dev->dev); + + unregister_hotplug_status_watch(be); + if (be->vif) { + kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE); + xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status"); + xenvif_disconnect(be->vif); + be->vif = NULL; + } + kfree(be); + dev_set_drvdata(&dev->dev, NULL); + return 0; +} + + +/** + * Entry point to this code when a new device is created. Allocate the basic + * structures and switch to InitWait. + */ +static int netback_probe(struct xenbus_device *dev, + const struct xenbus_device_id *id) +{ + const char *message; + struct xenbus_transaction xbt; + int err; + int sg; + struct backend_info *be = kzalloc(sizeof(struct backend_info), + GFP_KERNEL); + if (!be) { + xenbus_dev_fatal(dev, -ENOMEM, + "allocating backend structure"); + return -ENOMEM; + } + + be->dev = dev; + dev_set_drvdata(&dev->dev, be); + + sg = 1; + + do { + err = xenbus_transaction_start(&xbt); + if (err) { + xenbus_dev_fatal(dev, err, "starting transaction"); + goto fail; + } + + err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", sg); + if (err) { + message = "writing feature-sg"; + goto abort_transaction; + } + + err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4", + "%d", sg); + if (err) { + message = "writing feature-gso-tcpv4"; + goto abort_transaction; + } + + /* We support rx-copy path. */ + err = xenbus_printf(xbt, dev->nodename, + "feature-rx-copy", "%d", 1); + if (err) { + message = "writing feature-rx-copy"; + goto abort_transaction; + } + + /* + * We don't support rx-flip path (except old guests who don't + * grok this feature flag). + */ + err = xenbus_printf(xbt, dev->nodename, + "feature-rx-flip", "%d", 0); + if (err) { + message = "writing feature-rx-flip"; + goto abort_transaction; + } + + err = xenbus_transaction_end(xbt, 0); + } while (err == -EAGAIN); + + if (err) { + xenbus_dev_fatal(dev, err, "completing transaction"); + goto fail; + } + + err = xenbus_switch_state(dev, XenbusStateInitWait); + if (err) + goto fail; + + /* This kicks hotplug scripts, so do it immediately. */ + backend_create_xenvif(be); + + return 0; + +abort_transaction: + xenbus_transaction_end(xbt, 1); + xenbus_dev_fatal(dev, err, "%s", message); +fail: + pr_debug("failed"); + netback_remove(dev); + return err; +} + + +/* + * Handle the creation of the hotplug script environment. We add the script + * and vif variables to the environment, for the benefit of the vif-* hotplug + * scripts. + */ +static int netback_uevent(struct xenbus_device *xdev, + struct kobj_uevent_env *env) +{ + struct backend_info *be = dev_get_drvdata(&xdev->dev); + char *val; + + val = xenbus_read(XBT_NIL, xdev->nodename, "script", NULL); + if (IS_ERR(val)) { + int err = PTR_ERR(val); + xenbus_dev_fatal(xdev, err, "reading script"); + return err; + } else { + if (add_uevent_var(env, "script=%s", val)) { + kfree(val); + return -ENOMEM; + } + kfree(val); + } + + if (!be || !be->vif) + return 0; + + return add_uevent_var(env, "vif=%s", be->vif->dev->name); +} + + +static void backend_create_xenvif(struct backend_info *be) +{ + int err; + long handle; + struct xenbus_device *dev = be->dev; + + if (be->vif != NULL) + return; + + err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%li", &handle); + if (err != 1) { + xenbus_dev_fatal(dev, err, "reading handle"); + return; + } + + be->vif = xenvif_alloc(&dev->dev, dev->otherend_id, handle); + if (IS_ERR(be->vif)) { + err = PTR_ERR(be->vif); + be->vif = NULL; + xenbus_dev_fatal(dev, err, "creating interface"); + return; + } + + kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE); +} + + +static void disconnect_backend(struct xenbus_device *dev) +{ + struct backend_info *be = dev_get_drvdata(&dev->dev); + + if (be->vif) { + xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status"); + xenvif_disconnect(be->vif); + be->vif = NULL; + } +} + +/** + * Callback received when the frontend's state changes. + */ +static void frontend_changed(struct xenbus_device *dev, + enum xenbus_state frontend_state) +{ + struct backend_info *be = dev_get_drvdata(&dev->dev); + + pr_debug("frontend state %s", xenbus_strstate(frontend_state)); + + be->frontend_state = frontend_state; + + switch (frontend_state) { + case XenbusStateInitialising: + if (dev->state == XenbusStateClosed) { + printk(KERN_INFO "%s: %s: prepare for reconnect\n", + __func__, dev->nodename); + xenbus_switch_state(dev, XenbusStateInitWait); + } + break; + + case XenbusStateInitialised: + break; + + case XenbusStateConnected: + if (dev->state == XenbusStateConnected) + break; + backend_create_xenvif(be); + if (be->vif) + connect(be); + break; + + case XenbusStateClosing: + if (be->vif) + kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE); + disconnect_backend(dev); + xenbus_switch_state(dev, XenbusStateClosing); + break; + + case XenbusStateClosed: + xenbus_switch_state(dev, XenbusStateClosed); + if (xenbus_dev_is_online(dev)) + break; + /* fall through if not online */ + case XenbusStateUnknown: + device_unregister(&dev->dev); + break; + + default: + xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend", + frontend_state); + break; + } +} + + +static void xen_net_read_rate(struct xenbus_device *dev, + unsigned long *bytes, unsigned long *usec) +{ + char *s, *e; + unsigned long b, u; + char *ratestr; + + /* Default to unlimited bandwidth. */ + *bytes = ~0UL; + *usec = 0; + + ratestr = xenbus_read(XBT_NIL, dev->nodename, "rate", NULL); + if (IS_ERR(ratestr)) + return; + + s = ratestr; + b = simple_strtoul(s, &e, 10); + if ((s == e) || (*e != ',')) + goto fail; + + s = e + 1; + u = simple_strtoul(s, &e, 10); + if ((s == e) || (*e != '\0')) + goto fail; + + *bytes = b; + *usec = u; + + kfree(ratestr); + return; + + fail: + pr_warn("Failed to parse network rate limit. Traffic unlimited.\n"); + kfree(ratestr); +} + +static int xen_net_read_mac(struct xenbus_device *dev, u8 mac[]) +{ + char *s, *e, *macstr; + int i; + + macstr = s = xenbus_read(XBT_NIL, dev->nodename, "mac", NULL); + if (IS_ERR(macstr)) + return PTR_ERR(macstr); + + for (i = 0; i < ETH_ALEN; i++) { + mac[i] = simple_strtoul(s, &e, 16); + if ((s == e) || (*e != ((i == ETH_ALEN-1) ? '\0' : ':'))) { + kfree(macstr); + return -ENOENT; + } + s = e+1; + } + + kfree(macstr); + return 0; +} + +static void unregister_hotplug_status_watch(struct backend_info *be) +{ + if (be->have_hotplug_status_watch) { + unregister_xenbus_watch(&be->hotplug_status_watch); + kfree(be->hotplug_status_watch.node); + } + be->have_hotplug_status_watch = 0; +} + +static void hotplug_status_changed(struct xenbus_watch *watch, + const char **vec, + unsigned int vec_size) +{ + struct backend_info *be = container_of(watch, + struct backend_info, + hotplug_status_watch); + char *str; + unsigned int len; + + str = xenbus_read(XBT_NIL, be->dev->nodename, "hotplug-status", &len); + if (IS_ERR(str)) + return; + if (len == sizeof("connected")-1 && !memcmp(str, "connected", len)) { + xenbus_switch_state(be->dev, XenbusStateConnected); + /* Not interested in this watch anymore. */ + unregister_hotplug_status_watch(be); + } + kfree(str); +} + +static void connect(struct backend_info *be) +{ + int err; + struct xenbus_device *dev = be->dev; + + err = connect_rings(be); + if (err) + return; + + err = xen_net_read_mac(dev, be->vif->fe_dev_addr); + if (err) { + xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename); + return; + } + + xen_net_read_rate(dev, &be->vif->credit_bytes, + &be->vif->credit_usec); + be->vif->remaining_credit = be->vif->credit_bytes; + + unregister_hotplug_status_watch(be); + err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch, + hotplug_status_changed, + "%s/%s", dev->nodename, "hotplug-status"); + if (err) { + /* Switch now, since we can't do a watch. */ + xenbus_switch_state(dev, XenbusStateConnected); + } else { + be->have_hotplug_status_watch = 1; + } + + netif_wake_queue(be->vif->dev); +} + + +static int connect_rings(struct backend_info *be) +{ + struct xenvif *vif = be->vif; + struct xenbus_device *dev = be->dev; + unsigned long tx_ring_ref, rx_ring_ref; + unsigned int evtchn, rx_copy; + int err; + int val; + + err = xenbus_gather(XBT_NIL, dev->otherend, + "tx-ring-ref", "%lu", &tx_ring_ref, + "rx-ring-ref", "%lu", &rx_ring_ref, + "event-channel", "%u", &evtchn, NULL); + if (err) { + xenbus_dev_fatal(dev, err, + "reading %s/ring-ref and event-channel", + dev->otherend); + return err; + } + + err = xenbus_scanf(XBT_NIL, dev->otherend, "request-rx-copy", "%u", + &rx_copy); + if (err == -ENOENT) { + err = 0; + rx_copy = 0; + } + if (err < 0) { + xenbus_dev_fatal(dev, err, "reading %s/request-rx-copy", + dev->otherend); + return err; + } + if (!rx_copy) + return -EOPNOTSUPP; + + if (vif->dev->tx_queue_len != 0) { + if (xenbus_scanf(XBT_NIL, dev->otherend, + "feature-rx-notify", "%d", &val) < 0) + val = 0; + if (val) + vif->can_queue = 1; + else + /* Must be non-zero for pfifo_fast to work. */ + vif->dev->tx_queue_len = 1; + } + + if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg", + "%d", &val) < 0) + val = 0; + vif->can_sg = !!val; + + if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-gso-tcpv4", + "%d", &val) < 0) + val = 0; + vif->gso = !!val; + + if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-gso-tcpv4-prefix", + "%d", &val) < 0) + val = 0; + vif->gso_prefix = !!val; + + if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-no-csum-offload", + "%d", &val) < 0) + val = 0; + vif->csum = !val; + + /* Map the shared frame, irq etc. */ + err = xenvif_connect(vif, tx_ring_ref, rx_ring_ref, evtchn); + if (err) { + xenbus_dev_fatal(dev, err, + "mapping shared-frames %lu/%lu port %u", + tx_ring_ref, rx_ring_ref, evtchn); + return err; + } + return 0; +} + + +/* ** Driver Registration ** */ + + +static const struct xenbus_device_id netback_ids[] = { + { "vif" }, + { "" } +}; + + +static struct xenbus_driver netback = { + .name = "vif", + .owner = THIS_MODULE, + .ids = netback_ids, + .probe = netback_probe, + .remove = netback_remove, + .uevent = netback_uevent, + .otherend_changed = frontend_changed, +}; + +int xenvif_xenbus_init(void) +{ + return xenbus_register_backend(&netback); +} diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 5b399b54fef7..5c8d9c385be0 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -359,7 +359,7 @@ static void xennet_tx_buf_gc(struct net_device *dev) struct xen_netif_tx_response *txrsp; txrsp = RING_GET_RESPONSE(&np->tx, cons); - if (txrsp->status == NETIF_RSP_NULL) + if (txrsp->status == XEN_NETIF_RSP_NULL) continue; id = txrsp->id; @@ -416,7 +416,7 @@ static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev, larger than a page), split it it into page-sized chunks. */ while (len > PAGE_SIZE - offset) { tx->size = PAGE_SIZE - offset; - tx->flags |= NETTXF_more_data; + tx->flags |= XEN_NETTXF_more_data; len -= tx->size; data += tx->size; offset = 0; @@ -442,7 +442,7 @@ static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev, for (i = 0; i < frags; i++) { skb_frag_t *frag = skb_shinfo(skb)->frags + i; - tx->flags |= NETTXF_more_data; + tx->flags |= XEN_NETTXF_more_data; id = get_id_from_freelist(&np->tx_skb_freelist, np->tx_skbs); np->tx_skbs[id].skb = skb_get(skb); @@ -517,10 +517,10 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) tx->flags = 0; if (skb->ip_summed == CHECKSUM_PARTIAL) /* local packet? */ - tx->flags |= NETTXF_csum_blank | NETTXF_data_validated; + tx->flags |= XEN_NETTXF_csum_blank | XEN_NETTXF_data_validated; else if (skb->ip_summed == CHECKSUM_UNNECESSARY) /* remote but checksummed. */ - tx->flags |= NETTXF_data_validated; + tx->flags |= XEN_NETTXF_data_validated; if (skb_shinfo(skb)->gso_size) { struct xen_netif_extra_info *gso; @@ -531,7 +531,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) if (extra) extra->flags |= XEN_NETIF_EXTRA_FLAG_MORE; else - tx->flags |= NETTXF_extra_info; + tx->flags |= XEN_NETTXF_extra_info; gso->u.gso.size = skb_shinfo(skb)->gso_size; gso->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4; @@ -651,7 +651,7 @@ static int xennet_get_responses(struct netfront_info *np, int err = 0; unsigned long ret; - if (rx->flags & NETRXF_extra_info) { + if (rx->flags & XEN_NETRXF_extra_info) { err = xennet_get_extras(np, extras, rp); cons = np->rx.rsp_cons; } @@ -688,7 +688,7 @@ static int xennet_get_responses(struct netfront_info *np, __skb_queue_tail(list, skb); next: - if (!(rx->flags & NETRXF_more_data)) + if (!(rx->flags & XEN_NETRXF_more_data)) break; if (cons + frags == rp) { @@ -983,9 +983,9 @@ err: skb->truesize += skb->data_len - (RX_COPY_THRESHOLD - len); skb->len += skb->data_len; - if (rx->flags & NETRXF_csum_blank) + if (rx->flags & XEN_NETRXF_csum_blank) skb->ip_summed = CHECKSUM_PARTIAL; - else if (rx->flags & NETRXF_data_validated) + else if (rx->flags & XEN_NETRXF_data_validated) skb->ip_summed = CHECKSUM_UNNECESSARY; __skb_queue_tail(&rxq, skb); diff --git a/include/xen/interface/io/netif.h b/include/xen/interface/io/netif.h index 518481c95f18..cb94668f6e9f 100644 --- a/include/xen/interface/io/netif.h +++ b/include/xen/interface/io/netif.h @@ -22,50 +22,50 @@ /* * This is the 'wire' format for packets: - * Request 1: netif_tx_request -- NETTXF_* (any flags) - * [Request 2: netif_tx_extra] (only if request 1 has NETTXF_extra_info) - * [Request 3: netif_tx_extra] (only if request 2 has XEN_NETIF_EXTRA_MORE) - * Request 4: netif_tx_request -- NETTXF_more_data - * Request 5: netif_tx_request -- NETTXF_more_data + * Request 1: xen_netif_tx_request -- XEN_NETTXF_* (any flags) + * [Request 2: xen_netif_extra_info] (only if request 1 has XEN_NETTXF_extra_info) + * [Request 3: xen_netif_extra_info] (only if request 2 has XEN_NETIF_EXTRA_MORE) + * Request 4: xen_netif_tx_request -- XEN_NETTXF_more_data + * Request 5: xen_netif_tx_request -- XEN_NETTXF_more_data * ... - * Request N: netif_tx_request -- 0 + * Request N: xen_netif_tx_request -- 0 */ /* Protocol checksum field is blank in the packet (hardware offload)? */ -#define _NETTXF_csum_blank (0) -#define NETTXF_csum_blank (1U<<_NETTXF_csum_blank) +#define _XEN_NETTXF_csum_blank (0) +#define XEN_NETTXF_csum_blank (1U<<_XEN_NETTXF_csum_blank) /* Packet data has been validated against protocol checksum. */ -#define _NETTXF_data_validated (1) -#define NETTXF_data_validated (1U<<_NETTXF_data_validated) +#define _XEN_NETTXF_data_validated (1) +#define XEN_NETTXF_data_validated (1U<<_XEN_NETTXF_data_validated) /* Packet continues in the next request descriptor. */ -#define _NETTXF_more_data (2) -#define NETTXF_more_data (1U<<_NETTXF_more_data) +#define _XEN_NETTXF_more_data (2) +#define XEN_NETTXF_more_data (1U<<_XEN_NETTXF_more_data) /* Packet to be followed by extra descriptor(s). */ -#define _NETTXF_extra_info (3) -#define NETTXF_extra_info (1U<<_NETTXF_extra_info) +#define _XEN_NETTXF_extra_info (3) +#define XEN_NETTXF_extra_info (1U<<_XEN_NETTXF_extra_info) struct xen_netif_tx_request { grant_ref_t gref; /* Reference to buffer page */ uint16_t offset; /* Offset within buffer page */ - uint16_t flags; /* NETTXF_* */ + uint16_t flags; /* XEN_NETTXF_* */ uint16_t id; /* Echoed in response message. */ uint16_t size; /* Packet size in bytes. */ }; -/* Types of netif_extra_info descriptors. */ -#define XEN_NETIF_EXTRA_TYPE_NONE (0) /* Never used - invalid */ -#define XEN_NETIF_EXTRA_TYPE_GSO (1) /* u.gso */ -#define XEN_NETIF_EXTRA_TYPE_MAX (2) +/* Types of xen_netif_extra_info descriptors. */ +#define XEN_NETIF_EXTRA_TYPE_NONE (0) /* Never used - invalid */ +#define XEN_NETIF_EXTRA_TYPE_GSO (1) /* u.gso */ +#define XEN_NETIF_EXTRA_TYPE_MAX (2) -/* netif_extra_info flags. */ -#define _XEN_NETIF_EXTRA_FLAG_MORE (0) -#define XEN_NETIF_EXTRA_FLAG_MORE (1U<<_XEN_NETIF_EXTRA_FLAG_MORE) +/* xen_netif_extra_info flags. */ +#define _XEN_NETIF_EXTRA_FLAG_MORE (0) +#define XEN_NETIF_EXTRA_FLAG_MORE (1U<<_XEN_NETIF_EXTRA_FLAG_MORE) /* GSO types - only TCPv4 currently supported. */ -#define XEN_NETIF_GSO_TYPE_TCPV4 (1) +#define XEN_NETIF_GSO_TYPE_TCPV4 (1) /* * This structure needs to fit within both netif_tx_request and @@ -107,7 +107,7 @@ struct xen_netif_extra_info { struct xen_netif_tx_response { uint16_t id; - int16_t status; /* NETIF_RSP_* */ + int16_t status; /* XEN_NETIF_RSP_* */ }; struct xen_netif_rx_request { @@ -116,25 +116,29 @@ struct xen_netif_rx_request { }; /* Packet data has been validated against protocol checksum. */ -#define _NETRXF_data_validated (0) -#define NETRXF_data_validated (1U<<_NETRXF_data_validated) +#define _XEN_NETRXF_data_validated (0) +#define XEN_NETRXF_data_validated (1U<<_XEN_NETRXF_data_validated) /* Protocol checksum field is blank in the packet (hardware offload)? */ -#define _NETRXF_csum_blank (1) -#define NETRXF_csum_blank (1U<<_NETRXF_csum_blank) +#define _XEN_NETRXF_csum_blank (1) +#define XEN_NETRXF_csum_blank (1U<<_XEN_NETRXF_csum_blank) /* Packet continues in the next request descriptor. */ -#define _NETRXF_more_data (2) -#define NETRXF_more_data (1U<<_NETRXF_more_data) +#define _XEN_NETRXF_more_data (2) +#define XEN_NETRXF_more_data (1U<<_XEN_NETRXF_more_data) /* Packet to be followed by extra descriptor(s). */ -#define _NETRXF_extra_info (3) -#define NETRXF_extra_info (1U<<_NETRXF_extra_info) +#define _XEN_NETRXF_extra_info (3) +#define XEN_NETRXF_extra_info (1U<<_XEN_NETRXF_extra_info) + +/* GSO Prefix descriptor. */ +#define _XEN_NETRXF_gso_prefix (4) +#define XEN_NETRXF_gso_prefix (1U<<_XEN_NETRXF_gso_prefix) struct xen_netif_rx_response { uint16_t id; uint16_t offset; /* Offset in page of start of received packet */ - uint16_t flags; /* NETRXF_* */ + uint16_t flags; /* XEN_NETRXF_* */ int16_t status; /* -ve: BLKIF_RSP_* ; +ve: Rx'ed pkt size. */ }; @@ -149,10 +153,10 @@ DEFINE_RING_TYPES(xen_netif_rx, struct xen_netif_rx_request, struct xen_netif_rx_response); -#define NETIF_RSP_DROPPED -2 -#define NETIF_RSP_ERROR -1 -#define NETIF_RSP_OKAY 0 -/* No response: used for auxiliary requests (e.g., netif_tx_extra). */ -#define NETIF_RSP_NULL 1 +#define XEN_NETIF_RSP_DROPPED -2 +#define XEN_NETIF_RSP_ERROR -1 +#define XEN_NETIF_RSP_OKAY 0 +/* No response: used for auxiliary requests (e.g., xen_netif_extra_info). */ +#define XEN_NETIF_RSP_NULL 1 #endif -- cgit v1.2.3 From 059718d572e8ad388313b863aff717623bb2552f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 7 Jan 2011 13:24:00 +0100 Subject: m68k/block: amiflop - Remove superfluous amiga_chip_alloc() cast amiga_chip_alloc() returns a void *, so we don't need a cast. Also clean up coding style while we're at it. Signed-off-by: Geert Uytterhoeven --- drivers/block/amiflop.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 7888501ad9ee..363855ca376e 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -1768,8 +1768,8 @@ static int __init amiga_floppy_probe(struct platform_device *pdev) return -EBUSY; ret = -ENOMEM; - if ((raw_buf = (char *)amiga_chip_alloc (RAW_BUF_SIZE, "Floppy")) == - NULL) { + raw_buf = amiga_chip_alloc(RAW_BUF_SIZE, "Floppy"); + if (!raw_buf) { printk("fd: cannot get chip mem buffer\n"); goto out_blkdev; } -- cgit v1.2.3 From 5d03078a6804bf4c7f943c5b68bef80468c0717f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 16 Mar 2011 05:16:57 +0000 Subject: e1000e: fix kconfig for crc32 dependency ERROR: "crc32_le" [drivers/net/e1000e/e1000e.ko] undefined! Reported-by: Frank Peters Signed-off-by: Eric Dumazet Cc: Bruce Allan Cc: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 797d68196728..dc280bc8eba2 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2108,6 +2108,7 @@ config E1000 config E1000E tristate "Intel(R) PRO/1000 PCI-Express Gigabit Ethernet support" + select CRC32 depends on PCI && (!SPARC32 || BROKEN) select CRC32 ---help--- -- cgit v1.2.3 From d2145cde58135dabe7c48a599de4b81c2fe3ea61 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Wed, 16 Mar 2011 08:20:46 +0000 Subject: be2net: Copyright notice change. Update to Emulex instead of ServerEngines Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 10 +++++----- drivers/net/benet/be_cmds.c | 10 +++++----- drivers/net/benet/be_cmds.h | 10 +++++----- drivers/net/benet/be_ethtool.c | 10 +++++----- drivers/net/benet/be_hw.h | 10 +++++----- drivers/net/benet/be_main.c | 10 +++++----- 6 files changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 62af70716f8d..77216996d43b 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2010 ServerEngines + * Copyright (C) 2005 - 2011 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -8,11 +8,11 @@ * Public License is included in this distribution in the file called COPYING. * * Contact Information: - * linux-drivers@serverengines.com + * linux-drivers@emulex.com * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 + * Emulex + * 3333 Susan Street + * Costa Mesa, CA 92626 */ #ifndef BE_H diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index e1124c89181c..5a4a87e7c5ea 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2010 ServerEngines + * Copyright (C) 2005 - 2011 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -8,11 +8,11 @@ * Public License is included in this distribution in the file called COPYING. * * Contact Information: - * linux-drivers@serverengines.com + * linux-drivers@emulex.com * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 + * Emulex + * 3333 Susan Street + * Costa Mesa, CA 92626 */ #include "be.h" diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index e41fcbaed000..4f254cfaabe2 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2010 ServerEngines + * Copyright (C) 2005 - 2011 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -8,11 +8,11 @@ * Public License is included in this distribution in the file called COPYING. * * Contact Information: - * linux-drivers@serverengines.com + * linux-drivers@emulex.com * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 + * Emulex + * 3333 Susan Street + * Costa Mesa, CA 92626 */ /* diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 6e5e43380c2a..aac248fbd18b 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2010 ServerEngines + * Copyright (C) 2005 - 2011 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -8,11 +8,11 @@ * Public License is included in this distribution in the file called COPYING. * * Contact Information: - * linux-drivers@serverengines.com + * linux-drivers@emulex.com * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 + * Emulex + * 3333 Susan Street + * Costa Mesa, CA 92626 */ #include "be.h" diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index e06aa1567b27..d4344a06090b 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2010 ServerEngines + * Copyright (C) 2005 - 2011 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -8,11 +8,11 @@ * Public License is included in this distribution in the file called COPYING. * * Contact Information: - * linux-drivers@serverengines.com + * linux-drivers@emulex.com * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 + * Emulex + * 3333 Susan Street + * Costa Mesa, CA 92626 */ /********* Mailbox door bell *************/ diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 5e150066a915..a71163f1e34b 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 - 2010 ServerEngines + * Copyright (C) 2005 - 2011 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -8,11 +8,11 @@ * Public License is included in this distribution in the file called COPYING. * * Contact Information: - * linux-drivers@serverengines.com + * linux-drivers@emulex.com * - * ServerEngines - * 209 N. Fair Oaks Ave - * Sunnyvale, CA 94085 + * Emulex + * 3333 Susan Street + * Costa Mesa, CA 92626 */ #include "be.h" -- cgit v1.2.3 From c888385a0d61c4c6923ecc3b9dacfe8a1d8cb222 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Wed, 16 Mar 2011 08:21:00 +0000 Subject: be2net: Bump up the version number Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 77216996d43b..f803c58b941d 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -33,7 +33,7 @@ #include "be_hw.h" -#define DRV_VER "2.103.175u" +#define DRV_VER "4.0.100u" #define DRV_NAME "be2net" #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" #define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC" -- cgit v1.2.3 From f1c1775ac7e61950225925c949045406ffcb43de Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Sat, 12 Mar 2011 03:14:35 +0000 Subject: bonding: register slave pointer for rx_handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Register slave pointer as rx_handler data. That would eventually prevent need to loop over slave devices to find the right slave. Use synchronize_net to ensure that bond_handle_frame does not get slave structure freed when working with that. Signed-off-by: Jiri Pirko Reviewed-by: Nicolas de Pesloüan Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 17 +++++++++++------ drivers/net/bonding/bonding.h | 3 +++ 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 66c98e61f0b7..b047d75c28d4 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1482,21 +1482,22 @@ static bool bond_should_deliver_exact_match(struct sk_buff *skb, static struct sk_buff *bond_handle_frame(struct sk_buff *skb) { - struct net_device *slave_dev; + struct slave *slave; struct net_device *bond_dev; skb = skb_share_check(skb, GFP_ATOMIC); if (unlikely(!skb)) return NULL; - slave_dev = skb->dev; - bond_dev = ACCESS_ONCE(slave_dev->master); + + slave = bond_slave_get_rcu(skb->dev); + bond_dev = ACCESS_ONCE(slave->dev->master); if (unlikely(!bond_dev)) return skb; if (bond_dev->priv_flags & IFF_MASTER_ARPMON) - slave_dev->last_rx = jiffies; + slave->dev->last_rx = jiffies; - if (bond_should_deliver_exact_match(skb, slave_dev, bond_dev)) { + if (bond_should_deliver_exact_match(skb, slave->dev, bond_dev)) { skb->deliver_no_wcard = 1; return skb; } @@ -1694,7 +1695,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) pr_debug("Error %d calling netdev_set_bond_master\n", res); goto err_restore_mac; } - res = netdev_rx_handler_register(slave_dev, bond_handle_frame, NULL); + res = netdev_rx_handler_register(slave_dev, bond_handle_frame, + new_slave); if (res) { pr_debug("Error %d calling netdev_rx_handler_register\n", res); goto err_unset_master; @@ -1916,6 +1918,7 @@ err_close: err_unreg_rxhandler: netdev_rx_handler_unregister(slave_dev); + synchronize_net(); err_unset_master: netdev_set_bond_master(slave_dev, NULL); @@ -2099,6 +2102,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) } netdev_rx_handler_unregister(slave_dev); + synchronize_net(); netdev_set_bond_master(slave_dev, NULL); slave_disable_netpoll(slave); @@ -2213,6 +2217,7 @@ static int bond_release_all(struct net_device *bond_dev) } netdev_rx_handler_unregister(slave_dev); + synchronize_net(); netdev_set_bond_master(slave_dev, NULL); slave_disable_netpoll(slave); diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index c4e2343bb0b7..ff9af31e8c5b 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -266,6 +266,9 @@ struct bonding { #endif /* CONFIG_DEBUG_FS */ }; +#define bond_slave_get_rcu(dev) \ + ((struct slave *) rcu_dereference(dev->rx_handler_data)) + /** * Returns NULL if the net_device does not belong to any of the bond's slaves * -- cgit v1.2.3 From 0bd80dad57d82676ee484fb1f9aa4c5e8b5bc469 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 16 Mar 2011 08:45:23 +0000 Subject: net: get rid of multiple bond-related netdevice->priv_flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now when bond-related code is moved from net/core/dev.c into bonding code, multiple priv_flags are not needed anymore. So let them rot. Signed-off-by: Jiri Pirko Reviewed-by: Nicolas de Pesloüan Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 33 ++++++++++++++------------------- drivers/net/bonding/bond_sysfs.c | 8 -------- drivers/net/bonding/bonding.h | 24 +----------------------- 3 files changed, 15 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b047d75c28d4..00e9710caf7f 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1458,20 +1458,20 @@ static void bond_setup_by_slave(struct net_device *bond_dev, * ARP on active-backup slaves with arp_validate enabled. */ static bool bond_should_deliver_exact_match(struct sk_buff *skb, - struct net_device *slave_dev, - struct net_device *bond_dev) + struct slave *slave, + struct bonding *bond) { - if (slave_dev->priv_flags & IFF_SLAVE_INACTIVE) { - if (slave_dev->priv_flags & IFF_SLAVE_NEEDARP && + if (slave->dev->priv_flags & IFF_SLAVE_INACTIVE) { + if (slave_do_arp_validate(bond, slave) && skb->protocol == __cpu_to_be16(ETH_P_ARP)) return false; - if (bond_dev->priv_flags & IFF_MASTER_ALB && + if (bond->params.mode == BOND_MODE_ALB && skb->pkt_type != PACKET_BROADCAST && skb->pkt_type != PACKET_MULTICAST) return false; - if (bond_dev->priv_flags & IFF_MASTER_8023AD && + if (bond->params.mode == BOND_MODE_8023AD && skb->protocol == __cpu_to_be16(ETH_P_SLOW)) return false; @@ -1484,6 +1484,7 @@ static struct sk_buff *bond_handle_frame(struct sk_buff *skb) { struct slave *slave; struct net_device *bond_dev; + struct bonding *bond; skb = skb_share_check(skb, GFP_ATOMIC); if (unlikely(!skb)) @@ -1494,17 +1495,19 @@ static struct sk_buff *bond_handle_frame(struct sk_buff *skb) if (unlikely(!bond_dev)) return skb; - if (bond_dev->priv_flags & IFF_MASTER_ARPMON) + bond = netdev_priv(bond_dev); + + if (bond->params.arp_interval) slave->dev->last_rx = jiffies; - if (bond_should_deliver_exact_match(skb, slave->dev, bond_dev)) { + if (bond_should_deliver_exact_match(skb, slave, bond)) { skb->deliver_no_wcard = 1; return skb; } skb->dev = bond_dev; - if (bond_dev->priv_flags & IFF_MASTER_ALB && + if (bond->params.mode == BOND_MODE_ALB && bond_dev->priv_flags & IFF_BRIDGE_PORT && skb->pkt_type == PACKET_HOST) { @@ -2119,9 +2122,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) dev_set_mtu(slave_dev, slave->original_mtu); - slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | - IFF_SLAVE_INACTIVE | IFF_BONDING | - IFF_SLAVE_NEEDARP); + slave_dev->priv_flags &= ~(IFF_SLAVE_INACTIVE | IFF_BONDING); kfree(slave); @@ -2232,8 +2233,7 @@ static int bond_release_all(struct net_device *bond_dev) dev_set_mac_address(slave_dev, &addr); } - slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | - IFF_SLAVE_INACTIVE); + slave_dev->priv_flags &= ~IFF_SLAVE_INACTIVE; kfree(slave); @@ -4419,11 +4419,9 @@ void bond_set_mode_ops(struct bonding *bond, int mode) case BOND_MODE_BROADCAST: break; case BOND_MODE_8023AD: - bond_set_master_3ad_flags(bond); bond_set_xmit_hash_policy(bond); break; case BOND_MODE_ALB: - bond_set_master_alb_flags(bond); /* FALLTHRU */ case BOND_MODE_TLB: break; @@ -4514,9 +4512,6 @@ static void bond_setup(struct net_device *bond_dev) bond_dev->priv_flags |= IFF_BONDING; bond_dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; - if (bond->params.arp_interval) - bond_dev->priv_flags |= IFF_MASTER_ARPMON; - /* At first, we block adding VLANs. That's the only way to * prevent problems that occur when adding VLANs over an * empty bond. The block will be removed once non-challenged diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index e718144c5cfa..3a530eb9d104 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -325,11 +325,6 @@ static ssize_t bonding_store_mode(struct device *d, ret = -EINVAL; goto out; } - if (bond->params.mode == BOND_MODE_8023AD) - bond_unset_master_3ad_flags(bond); - - if (bond->params.mode == BOND_MODE_ALB) - bond_unset_master_alb_flags(bond); bond->params.mode = new_value; bond_set_mode_ops(bond, bond->params.mode); @@ -530,8 +525,6 @@ static ssize_t bonding_store_arp_interval(struct device *d, pr_info("%s: Setting ARP monitoring interval to %d.\n", bond->dev->name, new_value); bond->params.arp_interval = new_value; - if (bond->params.arp_interval) - bond->dev->priv_flags |= IFF_MASTER_ARPMON; if (bond->params.miimon) { pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", bond->dev->name, bond->dev->name); @@ -1007,7 +1000,6 @@ static ssize_t bonding_store_miimon(struct device *d, pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n", bond->dev->name); bond->params.arp_interval = 0; - bond->dev->priv_flags &= ~IFF_MASTER_ARPMON; if (bond->params.arp_validate) { bond_unregister_arp(bond); bond->params.arp_validate = diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index ff9af31e8c5b..049619f29144 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -356,34 +356,12 @@ static inline void bond_set_slave_inactive_flags(struct slave *slave) slave->state = BOND_STATE_BACKUP; if (!bond->params.all_slaves_active) slave->dev->priv_flags |= IFF_SLAVE_INACTIVE; - if (slave_do_arp_validate(bond, slave)) - slave->dev->priv_flags |= IFF_SLAVE_NEEDARP; } static inline void bond_set_slave_active_flags(struct slave *slave) { slave->state = BOND_STATE_ACTIVE; - slave->dev->priv_flags &= ~(IFF_SLAVE_INACTIVE | IFF_SLAVE_NEEDARP); -} - -static inline void bond_set_master_3ad_flags(struct bonding *bond) -{ - bond->dev->priv_flags |= IFF_MASTER_8023AD; -} - -static inline void bond_unset_master_3ad_flags(struct bonding *bond) -{ - bond->dev->priv_flags &= ~IFF_MASTER_8023AD; -} - -static inline void bond_set_master_alb_flags(struct bonding *bond) -{ - bond->dev->priv_flags |= IFF_MASTER_ALB; -} - -static inline void bond_unset_master_alb_flags(struct bonding *bond) -{ - bond->dev->priv_flags &= ~IFF_MASTER_ALB; + slave->dev->priv_flags &= ~IFF_SLAVE_INACTIVE; } struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); -- cgit v1.2.3 From e30bc066ab67a4c8abcb972227ffe7c576f06a86 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Sat, 12 Mar 2011 03:14:37 +0000 Subject: bonding: wrap slave state work MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit transfers slave->state into slave->backup (that it's going to transfer into bitfield. Introduce wrapper inlines to do the work with it. Signed-off-by: Jiri Pirko Reviewed-by: Nicolas de Pesloüan Signed-off-by: David S. Miller --- drivers/net/bonding/bond_3ad.c | 2 +- drivers/net/bonding/bond_main.c | 36 ++++++++++++++++++------------------ drivers/net/bonding/bond_sysfs.c | 2 +- drivers/net/bonding/bonding.h | 31 ++++++++++++++++++++++++++----- 4 files changed, 46 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index a5d5d0b5b155..494bf960442d 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -246,7 +246,7 @@ static inline void __enable_port(struct port *port) */ static inline int __port_is_enabled(struct port *port) { - return port->slave->state == BOND_STATE_ACTIVE; + return bond_is_active_slave(port->slave); } /** diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 00e9710caf7f..a3ea44997a2a 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1863,7 +1863,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) break; case BOND_MODE_TLB: case BOND_MODE_ALB: - new_slave->state = BOND_STATE_ACTIVE; + bond_set_active_slave(new_slave); bond_set_slave_inactive_flags(new_slave); bond_select_active_slave(bond); break; @@ -1871,7 +1871,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) pr_debug("This slave is always active in trunk mode\n"); /* always active in trunk mode */ - new_slave->state = BOND_STATE_ACTIVE; + bond_set_active_slave(new_slave); /* In trunking mode there is little meaning to curr_active_slave * anyway (it holds no special properties of the bond device), @@ -1909,7 +1909,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) pr_info("%s: enslaving %s as a%s interface with a%s link.\n", bond_dev->name, slave_dev->name, - new_slave->state == BOND_STATE_ACTIVE ? "n active" : " backup", + bond_is_active_slave(new_slave) ? "n active" : " backup", new_slave->link != BOND_LINK_DOWN ? "n up" : " down"); /* enslave is successful */ @@ -2007,7 +2007,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) pr_info("%s: releasing %s interface %s\n", bond_dev->name, - (slave->state == BOND_STATE_ACTIVE) ? "active" : "backup", + bond_is_active_slave(slave) ? "active" : "backup", slave_dev->name); oldcurrent = bond->curr_active_slave; @@ -2348,7 +2348,7 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in res = 0; strcpy(info->slave_name, slave->dev->name); info->link = slave->link; - info->state = slave->state; + info->state = bond_slave_state(slave); info->link_failure_count = slave->link_failure_count; break; } @@ -2387,7 +2387,7 @@ static int bond_miimon_inspect(struct bonding *bond) bond->dev->name, (bond->params.mode == BOND_MODE_ACTIVEBACKUP) ? - ((slave->state == BOND_STATE_ACTIVE) ? + (bond_is_active_slave(slave) ? "active " : "backup ") : "", slave->dev->name, bond->params.downdelay * bond->params.miimon); @@ -2478,13 +2478,13 @@ static void bond_miimon_commit(struct bonding *bond) if (bond->params.mode == BOND_MODE_8023AD) { /* prevent it from being the active one */ - slave->state = BOND_STATE_BACKUP; + bond_set_backup_slave(slave); } else if (bond->params.mode != BOND_MODE_ACTIVEBACKUP) { /* make it immediately active */ - slave->state = BOND_STATE_ACTIVE; + bond_set_active_slave(slave); } else if (slave != bond->primary_slave) { /* prevent it from being the active one */ - slave->state = BOND_STATE_BACKUP; + bond_set_backup_slave(slave); } bond_update_speed_duplex(slave); @@ -2858,7 +2858,7 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack memcpy(&tip, arp_ptr, 4); pr_debug("bond_arp_rcv: %s %s/%d av %d sv %d sip %pI4 tip %pI4\n", - bond->dev->name, slave->dev->name, slave->state, + bond->dev->name, slave->dev->name, bond_slave_state(slave), bond->params.arp_validate, slave_do_arp_validate(bond, slave), &sip, &tip); @@ -2870,7 +2870,7 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack * the active, through one switch, the router, then the other * switch before reaching the backup. */ - if (slave->state == BOND_STATE_ACTIVE) + if (bond_is_active_slave(slave)) bond_validate_arp(bond, slave, sip, tip); else bond_validate_arp(bond, slave, tip, sip); @@ -2932,7 +2932,7 @@ void bond_loadbalance_arp_mon(struct work_struct *work) slave->dev->last_rx + delta_in_ticks)) { slave->link = BOND_LINK_UP; - slave->state = BOND_STATE_ACTIVE; + bond_set_active_slave(slave); /* primary_slave has no meaning in round-robin * mode. the window of a slave being up and @@ -2965,7 +2965,7 @@ void bond_loadbalance_arp_mon(struct work_struct *work) slave->dev->last_rx + 2 * delta_in_ticks)) { slave->link = BOND_LINK_DOWN; - slave->state = BOND_STATE_BACKUP; + bond_set_backup_slave(slave); if (slave->link_failure_count < UINT_MAX) slave->link_failure_count++; @@ -3059,7 +3059,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) * gives each slave a chance to tx/rx traffic * before being taken out */ - if (slave->state == BOND_STATE_BACKUP && + if (!bond_is_active_slave(slave) && !bond->current_arp_slave && !time_in_range(jiffies, slave_last_rx(bond, slave) - delta_in_ticks, @@ -3076,7 +3076,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) * the bond has an IP address) */ trans_start = dev_trans_start(slave->dev); - if ((slave->state == BOND_STATE_ACTIVE) && + if (bond_is_active_slave(slave) && (!time_in_range(jiffies, trans_start - delta_in_ticks, trans_start + 2 * delta_in_ticks) || @@ -4140,7 +4140,7 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev bond_for_each_slave_from(bond, slave, i, start_at) { if (IS_UP(slave->dev) && (slave->link == BOND_LINK_UP) && - (slave->state == BOND_STATE_ACTIVE)) { + bond_is_active_slave(slave)) { res = bond_dev_queue_xmit(bond, skb, slave->dev); break; } @@ -4217,7 +4217,7 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev) bond_for_each_slave_from(bond, slave, i, start_at) { if (IS_UP(slave->dev) && (slave->link == BOND_LINK_UP) && - (slave->state == BOND_STATE_ACTIVE)) { + bond_is_active_slave(slave)) { res = bond_dev_queue_xmit(bond, skb, slave->dev); break; } @@ -4258,7 +4258,7 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev) bond_for_each_slave_from(bond, slave, i, start_at) { if (IS_UP(slave->dev) && (slave->link == BOND_LINK_UP) && - (slave->state == BOND_STATE_ACTIVE)) { + bond_is_active_slave(slave)) { if (tx_dev) { struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); if (!skb2) { diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 3a530eb9d104..c81b97cffaa3 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -1582,7 +1582,7 @@ static ssize_t bonding_store_slaves_active(struct device *d, } bond_for_each_slave(bond, slave, i) { - if (slave->state == BOND_STATE_BACKUP) { + if (!bond_is_active_slave(slave)) { if (new_value) slave->dev->priv_flags &= ~IFF_SLAVE_INACTIVE; else diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 049619f29144..63e9cf779389 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -55,7 +55,7 @@ (((slave)->dev->flags & IFF_UP) && \ netif_running((slave)->dev) && \ ((slave)->link == BOND_LINK_UP) && \ - ((slave)->state == BOND_STATE_ACTIVE)) + bond_is_active_slave(slave)) #define USES_PRIMARY(mode) \ @@ -192,7 +192,8 @@ struct slave { unsigned long last_arp_rx; s8 link; /* one of BOND_LINK_XXXX */ s8 new_link; - s8 state; /* one of BOND_STATE_XXXX */ + u8 backup; /* indicates backup slave. Value corresponds with + BOND_STATE_ACTIVE and BOND_STATE_BACKUP */ u32 original_mtu; u32 link_failure_count; u8 perm_hwaddr[ETH_ALEN]; @@ -304,6 +305,26 @@ static inline bool bond_is_lb(const struct bonding *bond) bond->params.mode == BOND_MODE_ALB); } +static inline void bond_set_active_slave(struct slave *slave) +{ + slave->backup = 0; +} + +static inline void bond_set_backup_slave(struct slave *slave) +{ + slave->backup = 1; +} + +static inline int bond_slave_state(struct slave *slave) +{ + return slave->backup; +} + +static inline bool bond_is_active_slave(struct slave *slave) +{ + return !bond_slave_state(slave); +} + #define BOND_PRI_RESELECT_ALWAYS 0 #define BOND_PRI_RESELECT_BETTER 1 #define BOND_PRI_RESELECT_FAILURE 2 @@ -321,7 +342,7 @@ static inline bool bond_is_lb(const struct bonding *bond) static inline int slave_do_arp_validate(struct bonding *bond, struct slave *slave) { - return bond->params.arp_validate & (1 << slave->state); + return bond->params.arp_validate & (1 << bond_slave_state(slave)); } static inline unsigned long slave_last_rx(struct bonding *bond, @@ -353,14 +374,14 @@ static inline void bond_set_slave_inactive_flags(struct slave *slave) { struct bonding *bond = netdev_priv(slave->dev->master); if (!bond_is_lb(bond)) - slave->state = BOND_STATE_BACKUP; + bond_set_backup_slave(slave); if (!bond->params.all_slaves_active) slave->dev->priv_flags |= IFF_SLAVE_INACTIVE; } static inline void bond_set_slave_active_flags(struct slave *slave) { - slave->state = BOND_STATE_ACTIVE; + bond_set_active_slave(slave); slave->dev->priv_flags &= ~IFF_SLAVE_INACTIVE; } -- cgit v1.2.3 From 2d7011ca79f1a8792e04d131b8ea21db179ab917 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 16 Mar 2011 08:46:43 +0000 Subject: bonding: get rid of IFF_SLAVE_INACTIVE netdev->priv_flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since bond-related code was moved from net/core/dev.c into bonding, IFF_SLAVE_INACTIVE is no longer needed. Replace is with flag "inactive" stored in slave structure Signed-off-by: Jiri Pirko Reviewed-by: Nicolas de Pesloüan Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 6 ++---- drivers/net/bonding/bond_sysfs.c | 4 ++-- drivers/net/bonding/bonding.h | 14 ++++++++++---- 3 files changed, 14 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index a3ea44997a2a..04119b1e7cdb 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1461,7 +1461,7 @@ static bool bond_should_deliver_exact_match(struct sk_buff *skb, struct slave *slave, struct bonding *bond) { - if (slave->dev->priv_flags & IFF_SLAVE_INACTIVE) { + if (bond_is_slave_inactive(slave)) { if (slave_do_arp_validate(bond, slave) && skb->protocol == __cpu_to_be16(ETH_P_ARP)) return false; @@ -2122,7 +2122,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) dev_set_mtu(slave_dev, slave->original_mtu); - slave_dev->priv_flags &= ~(IFF_SLAVE_INACTIVE | IFF_BONDING); + slave_dev->priv_flags &= ~IFF_BONDING; kfree(slave); @@ -2233,8 +2233,6 @@ static int bond_release_all(struct net_device *bond_dev) dev_set_mac_address(slave_dev, &addr); } - slave_dev->priv_flags &= ~IFF_SLAVE_INACTIVE; - kfree(slave); /* re-acquire the lock before getting the next slave */ diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index c81b97cffaa3..de87aea6d01a 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -1584,9 +1584,9 @@ static ssize_t bonding_store_slaves_active(struct device *d, bond_for_each_slave(bond, slave, i) { if (!bond_is_active_slave(slave)) { if (new_value) - slave->dev->priv_flags &= ~IFF_SLAVE_INACTIVE; + slave->inactive = 0; else - slave->dev->priv_flags |= IFF_SLAVE_INACTIVE; + slave->inactive = 1; } } out: diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 63e9cf779389..6b26962fd0ec 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -192,8 +192,9 @@ struct slave { unsigned long last_arp_rx; s8 link; /* one of BOND_LINK_XXXX */ s8 new_link; - u8 backup; /* indicates backup slave. Value corresponds with - BOND_STATE_ACTIVE and BOND_STATE_BACKUP */ + u8 backup:1, /* indicates backup slave. Value corresponds with + BOND_STATE_ACTIVE and BOND_STATE_BACKUP */ + inactive:1; /* indicates inactive slave */ u32 original_mtu; u32 link_failure_count; u8 perm_hwaddr[ETH_ALEN]; @@ -376,13 +377,18 @@ static inline void bond_set_slave_inactive_flags(struct slave *slave) if (!bond_is_lb(bond)) bond_set_backup_slave(slave); if (!bond->params.all_slaves_active) - slave->dev->priv_flags |= IFF_SLAVE_INACTIVE; + slave->inactive = 1; } static inline void bond_set_slave_active_flags(struct slave *slave) { bond_set_active_slave(slave); - slave->dev->priv_flags &= ~IFF_SLAVE_INACTIVE; + slave->inactive = 0; +} + +static inline bool bond_is_slave_inactive(struct slave *slave) +{ + return slave->inactive; } struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); -- cgit v1.2.3 From 8a4eb5734e8d1dc60a8c28576bbbdfdcc643626d Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Sat, 12 Mar 2011 03:14:39 +0000 Subject: net: introduce rx_handler results and logic around that MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch allows rx_handlers to better signalize what to do next to it's caller. That makes skb->deliver_no_wcard no longer needed. kernel-doc for rx_handler_result is taken from Nicolas' patch. Signed-off-by: Jiri Pirko Reviewed-by: Nicolas de Pesloüan Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 22 +++++++++--------- drivers/net/macvlan.c | 11 ++++----- include/linux/netdevice.h | 50 ++++++++++++++++++++++++++++++++++++++++- include/linux/skbuff.h | 5 +---- net/bridge/br_input.c | 25 ++++++++++++--------- net/bridge/br_private.h | 2 +- net/core/dev.c | 21 +++++++++++------ net/core/skbuff.c | 1 - 8 files changed, 98 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 04119b1e7cdb..27c413aa15da 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1480,20 +1480,23 @@ static bool bond_should_deliver_exact_match(struct sk_buff *skb, return false; } -static struct sk_buff *bond_handle_frame(struct sk_buff *skb) +static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) { + struct sk_buff *skb = *pskb; struct slave *slave; struct net_device *bond_dev; struct bonding *bond; - skb = skb_share_check(skb, GFP_ATOMIC); - if (unlikely(!skb)) - return NULL; - slave = bond_slave_get_rcu(skb->dev); bond_dev = ACCESS_ONCE(slave->dev->master); if (unlikely(!bond_dev)) - return skb; + return RX_HANDLER_PASS; + + skb = skb_share_check(skb, GFP_ATOMIC); + if (unlikely(!skb)) + return RX_HANDLER_CONSUMED; + + *pskb = skb; bond = netdev_priv(bond_dev); @@ -1501,8 +1504,7 @@ static struct sk_buff *bond_handle_frame(struct sk_buff *skb) slave->dev->last_rx = jiffies; if (bond_should_deliver_exact_match(skb, slave, bond)) { - skb->deliver_no_wcard = 1; - return skb; + return RX_HANDLER_EXACT; } skb->dev = bond_dev; @@ -1514,12 +1516,12 @@ static struct sk_buff *bond_handle_frame(struct sk_buff *skb) if (unlikely(skb_cow_head(skb, skb->data - skb_mac_header(skb)))) { kfree_skb(skb); - return NULL; + return RX_HANDLER_CONSUMED; } memcpy(eth_hdr(skb)->h_dest, bond_dev->dev_addr, ETH_ALEN); } - return skb; + return RX_HANDLER_ANOTHER; } /* enslave device to bond device */ diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 497991bd3b64..5b37d3c191e4 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -152,9 +152,10 @@ static void macvlan_broadcast(struct sk_buff *skb, } /* called under rcu_read_lock() from netif_receive_skb */ -static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb) +static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb) { struct macvlan_port *port; + struct sk_buff *skb = *pskb; const struct ethhdr *eth = eth_hdr(skb); const struct macvlan_dev *vlan; const struct macvlan_dev *src; @@ -184,7 +185,7 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb) */ macvlan_broadcast(skb, port, src->dev, MACVLAN_MODE_VEPA); - return skb; + return RX_HANDLER_PASS; } if (port->passthru) @@ -192,12 +193,12 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb) else vlan = macvlan_hash_lookup(port, eth->h_dest); if (vlan == NULL) - return skb; + return RX_HANDLER_PASS; dev = vlan->dev; if (unlikely(!(dev->flags & IFF_UP))) { kfree_skb(skb); - return NULL; + return RX_HANDLER_CONSUMED; } len = skb->len + ETH_HLEN; skb = skb_share_check(skb, GFP_ATOMIC); @@ -211,7 +212,7 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb) out: macvlan_count_rx(vlan, len, ret == NET_RX_SUCCESS, 0); - return NULL; + return RX_HANDLER_CONSUMED; } static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 604dbf5051d3..5eeb2cd3631c 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -390,7 +390,55 @@ enum gro_result { }; typedef enum gro_result gro_result_t; -typedef struct sk_buff *rx_handler_func_t(struct sk_buff *skb); +/* + * enum rx_handler_result - Possible return values for rx_handlers. + * @RX_HANDLER_CONSUMED: skb was consumed by rx_handler, do not process it + * further. + * @RX_HANDLER_ANOTHER: Do another round in receive path. This is indicated in + * case skb->dev was changed by rx_handler. + * @RX_HANDLER_EXACT: Force exact delivery, no wildcard. + * @RX_HANDLER_PASS: Do nothing, passe the skb as if no rx_handler was called. + * + * rx_handlers are functions called from inside __netif_receive_skb(), to do + * special processing of the skb, prior to delivery to protocol handlers. + * + * Currently, a net_device can only have a single rx_handler registered. Trying + * to register a second rx_handler will return -EBUSY. + * + * To register a rx_handler on a net_device, use netdev_rx_handler_register(). + * To unregister a rx_handler on a net_device, use + * netdev_rx_handler_unregister(). + * + * Upon return, rx_handler is expected to tell __netif_receive_skb() what to + * do with the skb. + * + * If the rx_handler consumed to skb in some way, it should return + * RX_HANDLER_CONSUMED. This is appropriate when the rx_handler arranged for + * the skb to be delivered in some other ways. + * + * If the rx_handler changed skb->dev, to divert the skb to another + * net_device, it should return RX_HANDLER_ANOTHER. The rx_handler for the + * new device will be called if it exists. + * + * If the rx_handler consider the skb should be ignored, it should return + * RX_HANDLER_EXACT. The skb will only be delivered to protocol handlers that + * are registred on exact device (ptype->dev == skb->dev). + * + * If the rx_handler didn't changed skb->dev, but want the skb to be normally + * delivered, it should return RX_HANDLER_PASS. + * + * A device without a registered rx_handler will behave as if rx_handler + * returned RX_HANDLER_PASS. + */ + +enum rx_handler_result { + RX_HANDLER_CONSUMED, + RX_HANDLER_ANOTHER, + RX_HANDLER_EXACT, + RX_HANDLER_PASS, +}; +typedef enum rx_handler_result rx_handler_result_t; +typedef rx_handler_result_t rx_handler_func_t(struct sk_buff **pskb); extern void __napi_schedule(struct napi_struct *n); diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 31f02d0b46a7..24cfa626931e 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -388,10 +388,7 @@ struct sk_buff { kmemcheck_bitfield_begin(flags2); __u16 queue_mapping:16; #ifdef CONFIG_IPV6_NDISC_NODETYPE - __u8 ndisc_nodetype:2, - deliver_no_wcard:1; -#else - __u8 deliver_no_wcard:1; + __u8 ndisc_nodetype:2; #endif __u8 ooo_okay:1; kmemcheck_bitfield_end(flags2); diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 88e4aa9cb1f9..e2160792e1bc 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -139,21 +139,22 @@ static inline int is_link_local(const unsigned char *dest) * Return NULL if skb is handled * note: already called with rcu_read_lock */ -struct sk_buff *br_handle_frame(struct sk_buff *skb) +rx_handler_result_t br_handle_frame(struct sk_buff **pskb) { struct net_bridge_port *p; + struct sk_buff *skb = *pskb; const unsigned char *dest = eth_hdr(skb)->h_dest; br_should_route_hook_t *rhook; if (unlikely(skb->pkt_type == PACKET_LOOPBACK)) - return skb; + return RX_HANDLER_PASS; if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) goto drop; skb = skb_share_check(skb, GFP_ATOMIC); if (!skb) - return NULL; + return RX_HANDLER_CONSUMED; p = br_port_get_rcu(skb->dev); @@ -167,10 +168,12 @@ struct sk_buff *br_handle_frame(struct sk_buff *skb) goto forward; if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, - NULL, br_handle_local_finish)) - return NULL; /* frame consumed by filter */ - else - return skb; /* continue processing */ + NULL, br_handle_local_finish)) { + return RX_HANDLER_CONSUMED; /* consumed by filter */ + } else { + *pskb = skb; + return RX_HANDLER_PASS; /* continue processing */ + } } forward: @@ -178,8 +181,10 @@ forward: case BR_STATE_FORWARDING: rhook = rcu_dereference(br_should_route_hook); if (rhook) { - if ((*rhook)(skb)) - return skb; + if ((*rhook)(skb)) { + *pskb = skb; + return RX_HANDLER_PASS; + } dest = eth_hdr(skb)->h_dest; } /* fall through */ @@ -194,5 +199,5 @@ forward: drop: kfree_skb(skb); } - return NULL; + return RX_HANDLER_CONSUMED; } diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index f7afc364d777..19e2f46ed086 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -379,7 +379,7 @@ extern void br_features_recompute(struct net_bridge *br); /* br_input.c */ extern int br_handle_frame_finish(struct sk_buff *skb); -extern struct sk_buff *br_handle_frame(struct sk_buff *skb); +extern rx_handler_result_t br_handle_frame(struct sk_buff **pskb); /* br_ioctl.c */ extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); diff --git a/net/core/dev.c b/net/core/dev.c index 0d39032e9621..0b88eba97dab 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3070,6 +3070,8 @@ out: * on a failure. * * The caller must hold the rtnl_mutex. + * + * For a general description of rx_handler, see enum rx_handler_result. */ int netdev_rx_handler_register(struct net_device *dev, rx_handler_func_t *rx_handler, @@ -3129,6 +3131,7 @@ static int __netif_receive_skb(struct sk_buff *skb) rx_handler_func_t *rx_handler; struct net_device *orig_dev; struct net_device *null_or_dev; + bool deliver_exact = false; int ret = NET_RX_DROP; __be16 type; @@ -3181,18 +3184,22 @@ ncls: rx_handler = rcu_dereference(skb->dev->rx_handler); if (rx_handler) { - struct net_device *prev_dev; - if (pt_prev) { ret = deliver_skb(skb, pt_prev, orig_dev); pt_prev = NULL; } - prev_dev = skb->dev; - skb = rx_handler(skb); - if (!skb) + switch (rx_handler(&skb)) { + case RX_HANDLER_CONSUMED: goto out; - if (skb->dev != prev_dev) + case RX_HANDLER_ANOTHER: goto another_round; + case RX_HANDLER_EXACT: + deliver_exact = true; + case RX_HANDLER_PASS: + break; + default: + BUG(); + } } if (vlan_tx_tag_present(skb)) { @@ -3210,7 +3217,7 @@ ncls: vlan_on_bond_hook(skb); /* deliver only exact match when indicated */ - null_or_dev = skb->deliver_no_wcard ? skb->dev : NULL; + null_or_dev = deliver_exact ? skb->dev : NULL; type = skb->protocol; list_for_each_entry_rcu(ptype, diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 1eb526a848ff..801dd08908f9 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -523,7 +523,6 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) new->ip_summed = old->ip_summed; skb_copy_queue_mapping(new, old); new->priority = old->priority; - new->deliver_no_wcard = old->deliver_no_wcard; #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) new->ipvs_property = old->ipvs_property; #endif -- cgit v1.2.3 From ceda86a108671294052cbf51660097b6534672f5 Mon Sep 17 00:00:00 2001 From: Andy Gospodarek Date: Mon, 14 Mar 2011 12:05:21 +0000 Subject: bonding: enable netpoll without checking link status Only slaves that are up should transmit netpoll frames, so there is no need to check to see if a slave is up before enabling netpoll on it. This resolves a reported failure on active-backup bonds where a slave interface is down when netpoll was enabled. Signed-off-by: Andy Gospodarek Tested-by: WANG Cong Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 27c413aa15da..1a6e9eb7af43 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1347,8 +1347,6 @@ static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni) read_lock(&bond->lock); bond_for_each_slave(bond, slave, i) { - if (!IS_UP(slave->dev)) - continue; err = slave_enable_netpoll(slave); if (err) { __bond_netpoll_cleanup(bond); -- cgit v1.2.3